commit 9c6f9f3405260499eee19acdb4c161f0aba9db91 Author: lsv Date: Tue Jul 7 22:19:12 2020 +0500 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f12386e --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +Debug/* +x64/* +Release/* +*.sbr +*.obj +*.cod +*.tlog +*.7z +*.bsc +*.pdb diff --git a/agent/dlgJob.cpp b/agent/dlgJob.cpp new file mode 100644 index 0000000..bf2a697 --- /dev/null +++ b/agent/dlgJob.cpp @@ -0,0 +1,513 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgJob.cpp - PostgreSQL Job Property +// +////////////////////////////////////////////////////////////////////////// + + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "agent/dlgJob.h" +#include "agent/dlgStep.h" +#include "agent/dlgSchedule.h" +#include "agent/pgaJob.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" +#include "frm/frmMain.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define cbJobclass CTRL_COMBOBOX("cbJobclass") +#define txtHostAgent CTRL_TEXT("txtHostAgent") +#define txtCreated CTRL_TEXT("txtCreated") +#define txtChanged CTRL_TEXT("txtChanged") +#define txtNextrun CTRL_TEXT("txtNextrun") +#define txtLastrun CTRL_TEXT("txtLastrun") +#define txtLastresult CTRL_TEXT("txtLastResult") + +#define lstSteps CTRL_LISTVIEW("lstSteps") +#define btnChangeStep CTRL_BUTTON("btnChangeStep") +#define btnAddStep CTRL_BUTTON("btnAddStep") +#define btnRemoveStep CTRL_BUTTON("btnRemoveStep") + +#define lstSchedules CTRL_LISTVIEW("lstSchedules") +#define btnChangeSchedule CTRL_BUTTON("btnChangeSchedule") +#define btnAddSchedule CTRL_BUTTON("btnAddSchedule") +#define btnRemoveSchedule CTRL_BUTTON("btnRemoveSchedule") + + +BEGIN_EVENT_TABLE(dlgJob, dlgAgentProperty) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbJobclass"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtHostAgent"), dlgProperty::OnChange) + + EVT_LIST_ITEM_SELECTED(XRCID("lstSteps"), dlgJob::OnSelChangeStep) + EVT_BUTTON(XRCID("btnChangeStep"), dlgJob::OnChangeStep) + EVT_BUTTON(XRCID("btnAddStep"), dlgJob::OnAddStep) + EVT_BUTTON(XRCID("btnRemoveStep"), dlgJob::OnRemoveStep) + + EVT_LIST_ITEM_SELECTED(XRCID("lstSchedules"), dlgJob::OnSelChangeSchedule) + EVT_BUTTON(XRCID("btnChangeSchedule"), dlgJob::OnChangeSchedule) + EVT_BUTTON(XRCID("btnAddSchedule"), dlgJob::OnAddSchedule) + EVT_BUTTON(XRCID("btnRemoveSchedule"), dlgJob::OnRemoveSchedule) + +#ifdef __WXMAC__ + EVT_SIZE( dlgJob::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgaJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgJob(this, frame, (pgaJob *)node); +} + + +dlgJob::dlgJob(pgaFactory *f, frmMain *frame, pgaJob *node) + : dlgAgentProperty(f, frame, wxT("dlgJob")) +{ + job = node; + + txtID->Disable(); + txtCreated->Disable(); + txtChanged->Disable(); + txtNextrun->Disable(); + txtLastrun->Disable(); + txtLastresult->Disable(); + lstSteps->CreateColumns(0, _("Step"), _("Comment"), 90); + lstSteps->AddColumn(wxT("cmd"), 0); + lstSteps->AddColumn(wxT("id"), 0); + + lstSchedules->CreateColumns(0, _("Schedule"), _("Comment"), 90); + lstSchedules->AddColumn(wxT("cmd"), 0); + lstSchedules->AddColumn(wxT("id"), 0); + btnChangeStep->Disable(); + btnRemoveStep->Disable(); + btnChangeSchedule->Disable(); + btnRemoveSchedule->Disable(); +} + + +pgObject *dlgJob::GetObject() +{ + return job; +} + + +#ifdef __WXMAC__ +void dlgJob::OnChangeSize(wxSizeEvent &ev) +{ + lstSteps->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + lstSchedules->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgJob::Go(bool modal) +{ + int returncode; + + pgSet *jcl = connection->ExecuteSet(wxT("SELECT jclname FROM pgagent.pga_jobclass")); + if (jcl) + { + while (!jcl->Eof()) + { + cbJobclass->Append(jcl->GetVal(0)); + jcl->MoveNext(); + } + delete jcl; + } + + if (job) + { + // edit mode + recId = job->GetRecId(); + txtID->SetValue(NumToStr(recId)); + cbJobclass->SetValue(job->GetJobclass()); + chkEnabled->SetValue(job->GetEnabled()); + txtHostAgent->SetValue(job->GetHostAgent()); + txtCreated->SetValue(DateToStr(job->GetCreated())); + txtChanged->SetValue(DateToStr(job->GetChanged())); + txtNextrun->SetValue(DateToStr(job->GetNextrun())); + txtLastrun->SetValue(DateToStr(job->GetLastrun())); + txtLastresult->SetValue(job->GetLastresult()); + + wxCookieType cookie; + pgObject *data = 0; + + wxTreeItemId item, stepsItem, schedulesItem; + item = mainForm->GetBrowser()->GetFirstChild(job->GetId(), cookie); + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->GetMetaType() == PGM_STEP) + stepsItem = item; + else if (data->GetMetaType() == PGM_SCHEDULE) + schedulesItem = item; + + item = mainForm->GetBrowser()->GetNextChild(job->GetId(), cookie); + } + + if (stepsItem) + { + pgCollection *coll = (pgCollection *)data; + // make sure all columns are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the columns collection + item = mainForm->GetBrowser()->GetFirstChild(stepsItem, cookie); + + // add columns + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(stepFactory)) + { + pgaStep *step = (pgaStep *)data; + int pos = lstSteps->AppendItem(stepFactory.GetIconId(), step->GetName(), step->GetComment()); + lstSteps->SetItem(pos, 3, NumToStr((long)step)); + previousSteps.Add(NumToStr((long)step)); + } + item = mainForm->GetBrowser()->GetNextChild(stepsItem, cookie); + } + } + + if (schedulesItem) + { + pgCollection *coll = (pgCollection *)data; + // make sure all columns are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the columns collection + item = mainForm->GetBrowser()->GetFirstChild(schedulesItem, cookie); + + // add columns + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(scheduleFactory)) + { + pgaSchedule *schedule = (pgaSchedule *)data; + int pos = lstSchedules->AppendItem(scheduleFactory.GetIconId(), schedule->GetName(), schedule->GetComment()); + lstSchedules->SetItem(pos, 3, NumToStr((long)schedule)); + previousSchedules.Add(NumToStr((long)schedule)); + } + item = mainForm->GetBrowser()->GetNextChild(schedulesItem, cookie); + } + } + } + else + { + // create mode + cbJobclass->SetSelection(0); + btnChangeStep->Hide(); + btnChangeSchedule->Hide(); + } + + returncode = dlgProperty::Go(modal); + + SetSqlReadOnly(true); + + // This fixes a UI glitch on MacOS X + // Because of the new layout code, the Columns pane doesn't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + return returncode; +} + + +pgObject *dlgJob::CreateObject(pgCollection *collection) +{ + pgObject *obj = jobFactory.CreateObjects(collection, 0, wxT(" WHERE jobid=") + NumToStr(recId) + wxT("\n")); + return obj; +} + + +void dlgJob::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + if (job) + { + enable = txtComment->GetValue() != job->GetComment() + || name != job->GetName() + || chkEnabled->GetValue() != job->GetEnabled() + || txtHostAgent->GetValue() != job->GetHostAgent(); + if (!enable) + { + enable = !GetUpdateSql().IsEmpty(); + } + } + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + + EnableOK(enable); +} + + +void dlgJob::OnChangeStep(wxCommandEvent &ev) +{ + long pos = lstSteps->GetSelection(); + pgaStep *obj = (pgaStep *) StrToLong(lstSteps->GetText(pos, 3)); + + dlgStep step(&stepFactory, mainForm, obj, job); + step.CenterOnParent(); + step.SetConnection(connection); + + if (step.Go(true) != wxID_CANCEL) + { + lstSteps->SetItem(pos, 0, step.GetName()); + lstSteps->SetItem(pos, 1, step.GetComment()); + + if (lstSteps->GetText(pos, 3).IsEmpty()) + { + wxString *stepSql = new wxString(step.GetInsertSql()); + lstSteps->SetItemData(pos, (long)stepSql); + } + else + { + wxString *stepSql = new wxString(step.GetUpdateSql()); + lstSteps->SetItemData(pos, (long)stepSql); + } + + CheckChange(); + } +} + + +void dlgJob::OnSelChangeStep(wxListEvent &ev) +{ + btnChangeStep->Enable(); + btnRemoveStep->Enable(); +} + + +void dlgJob::OnAddStep(wxCommandEvent &ev) +{ + dlgStep step(&stepFactory, mainForm, NULL, job); + step.CenterOnParent(); + step.SetConnection(connection); + if (step.Go(true) != wxID_CANCEL) + { + int pos = lstSteps->AppendItem(stepFactory.GetIconId(), step.GetName(), step.GetComment()); + wxString *stepSql = new wxString(step.GetInsertSql()); + lstSteps->SetItemData(pos, (long)stepSql); + CheckChange(); + } +} + + +void dlgJob::OnRemoveStep(wxCommandEvent &ev) +{ + delete (wxString *)lstSteps->GetItemData(lstSteps->GetSelection()); + lstSteps->DeleteCurrentItem(); + + btnChangeStep->Disable(); + btnRemoveStep->Disable(); + + CheckChange(); +} + + +void dlgJob::OnSelChangeSchedule(wxListEvent &ev) +{ + btnChangeSchedule->Enable(); + btnRemoveSchedule->Enable(); +} + + +void dlgJob::OnChangeSchedule(wxCommandEvent &ev) +{ + long pos = lstSchedules->GetSelection(); + pgaSchedule *obj = (pgaSchedule *) StrToLong(lstSchedules->GetText(pos, 3)); + + dlgSchedule schedule(&scheduleFactory, mainForm, obj, job); + schedule.CenterOnParent(); + schedule.SetConnection(connection); + + if (schedule.Go(true) != wxID_CANCEL) + { + lstSchedules->SetItem(pos, 0, schedule.GetName()); + lstSchedules->SetItem(pos, 1, schedule.GetComment()); + + if (lstSchedules->GetText(pos, 3).IsEmpty()) + { + wxString *scheduleSql = new wxString(schedule.GetInsertSql()); + lstSchedules->SetItemData(pos, (long)scheduleSql); + } + else + { + wxString *scheduleSql = new wxString(schedule.GetUpdateSql()); + lstSchedules->SetItemData(pos, (long)scheduleSql); + } + + CheckChange(); + } +} + + +void dlgJob::OnAddSchedule(wxCommandEvent &ev) +{ + dlgSchedule schedule(&scheduleFactory, mainForm, NULL, job); + schedule.CenterOnParent(); + schedule.SetConnection(connection); + if (schedule.Go(true) != wxID_CANCEL) + { + int pos = lstSchedules->AppendItem(scheduleFactory.GetIconId(), schedule.GetName(), schedule.GetComment()); + wxString *scheduleSql = new wxString(schedule.GetInsertSql()); + lstSchedules->SetItemData(pos, (long)scheduleSql); + CheckChange(); + } +} + + +void dlgJob::OnRemoveSchedule(wxCommandEvent &ev) +{ + delete (wxString *)lstSchedules->GetItemData(lstSchedules->GetSelection()); + lstSchedules->DeleteCurrentItem(); + + btnChangeSchedule->Disable(); + btnRemoveSchedule->Disable(); + + CheckChange(); +} + + +wxString dlgJob::GetInsertSql() +{ + wxString sql; + + if (!job) + { + sql = wxT("INSERT INTO pgagent.pga_job (jobid, jobjclid, jobname, jobdesc, jobenabled, jobhostagent)\n") + wxT("SELECT , jcl.jclid, ") + qtDbString(GetName()) + + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + BoolToStr(chkEnabled->GetValue()) + + wxT(", ") + qtDbString(txtHostAgent->GetValue()) + wxT("\n") + wxT(" FROM pgagent.pga_jobclass jcl WHERE jclname=") + qtDbString(cbJobclass->GetValue()) + wxT(";\n"); + } + return sql; +} + + +wxString dlgJob::GetUpdateSql() +{ + wxString sql, name; + name = GetName(); + + if (job) + { + // edit mode + wxString vars; + + if (name != job->GetName()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobname = ") + qtDbString(name)); + } + if (cbJobclass->GetValue().Trim() != job->GetJobclass()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobjclid= (SELECT jclid FROM pgagent.pga_jobclass WHERE jclname=") + qtDbString(cbJobclass->GetValue()) + wxT(")")); + } + if (chkEnabled->GetValue() != job->GetEnabled()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobenabled = ") + BoolToStr(chkEnabled->GetValue())); + } + if (txtHostAgent->GetValue() != job->GetHostAgent()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobhostagent = ") + qtDbString(txtHostAgent->GetValue())); + } + if (txtComment->GetValue() != job->GetComment()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jobdesc = ") + qtDbString(txtComment->GetValue())); + } + + if (!vars.IsEmpty()) + sql = wxT("UPDATE pgagent.pga_job SET ") + vars + wxT("\n") + wxT(" WHERE jobid=") + NumToStr(recId) + wxT(";\n"); + + } + else + { + // create mode + // done by GetInsertSql + } + + int pos, index; + + wxArrayString tmpSteps = previousSteps; + for (pos = 0 ; pos < lstSteps->GetItemCount() ; pos++) + { + wxString str = lstSteps->GetText(pos, 3); + if (!str.IsEmpty()) + { + index = tmpSteps.Index(str); + if (index >= 0) + tmpSteps.RemoveAt(index); + } + + if(lstSteps->GetItemData(pos)) + { + str = *(wxString *)lstSteps->GetItemData(pos); + if (!str.IsEmpty()) + sql += str; + } + } + + for (index = 0 ; index < (int)tmpSteps.GetCount() ; index++) + { + sql += wxT("DELETE FROM pgagent.pga_jobstep WHERE jstid=") + + NumToStr(((pgaStep *)StrToLong(tmpSteps.Item(index)))->GetRecId()) + wxT(";\n"); + } + + wxArrayString tmpSchedules = previousSchedules; + for (pos = 0 ; pos < lstSchedules->GetItemCount() ; pos++) + { + wxString str = lstSchedules->GetText(pos, 3); + if (!str.IsEmpty()) + { + index = tmpSchedules.Index(str); + if (index >= 0) + tmpSchedules.RemoveAt(index); + } + if(lstSchedules->GetItemData(pos)) + { + str = *(wxString *)lstSchedules->GetItemData(pos); + if (!str.IsEmpty()) + sql += str; + } + } + + for (index = 0 ; index < (int)tmpSchedules.GetCount() ; index++) + { + sql += wxT("DELETE FROM pgagent.pga_schedule WHERE jscid=") + + NumToStr(((pgaStep *)StrToLong(tmpSchedules.Item(index)))->GetRecId()) + wxT(";\n"); + } + + return sql; + +} diff --git a/agent/dlgSchedule.cpp b/agent/dlgSchedule.cpp new file mode 100644 index 0000000..f50e925 --- /dev/null +++ b/agent/dlgSchedule.cpp @@ -0,0 +1,859 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchedule.cpp - PostgreSQL Schedule Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// App headers +#include "utils/misc.h" +#include "agent/dlgSchedule.h" +#include "agent/pgaSchedule.h" + +// image for de/-select all +#include "images/check.pngc" +#include "images/uncheck.pngc" + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define calStart CTRL_CALENDAR("calStart") +#define timStart CTRL_TIME("timStart") +#define calEnd CTRL_CALENDAR("calEnd") +#define timEnd CTRL_TIME("timEnd") +#define chkWeekdays CTRL_CHECKLISTBOX("chkWeekdays") +#define chkMonthdays CTRL_CHECKLISTBOX("chkMonthdays") +#define chkMonths CTRL_CHECKLISTBOX("chkMonths") +#define chkHours CTRL_CHECKLISTBOX("chkHours") +#define chkMinutes CTRL_CHECKLISTBOX("chkMinutes") +#define lstExceptions CTRL_LISTVIEW("lstExceptions") +#define timException CTRL_TIME("timException") +#define calException CTRL_CALENDAR("calException") +#define btnAddException CTRL_BUTTON("btnAddException") +#define btnChangeException CTRL_BUTTON("btnChangeException") +#define btnRemoveException CTRL_BUTTON("btnRemoveException") +#define btnWeekdays CTRL_BUTTON("btnWeekdays") +#define btnMonthdays CTRL_BUTTON("btnMonthdays") +#define btnMonths CTRL_BUTTON("btnMonths") +#define btnHours CTRL_BUTTON("btnHours") +#define btnMinutes CTRL_BUTTON("btnMinutes") + +BEGIN_EVENT_TABLE(dlgSchedule, dlgAgentProperty) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgSchedule::OnChangeCom) + EVT_CALENDAR_SEL_CHANGED(XRCID("calStart"), dlgSchedule::OnChangeCal) + EVT_TEXT(XRCID("timStart"), dlgSchedule::OnChangeCom) + EVT_CALENDAR_SEL_CHANGED(XRCID("calEnd"), dlgSchedule::OnChangeCal) + EVT_TEXT(XRCID("timEnd"), dlgSchedule::OnChangeCom) + EVT_LIST_ITEM_SELECTED(XRCID("lstExceptions"), dlgSchedule::OnSelChangeException) + EVT_BUTTON(XRCID("btnAddException"), dlgSchedule::OnAddException) + EVT_BUTTON(XRCID("btnChangeException"), dlgSchedule::OnChangeException) + EVT_BUTTON(XRCID("btnRemoveException"), dlgSchedule::OnRemoveException) + EVT_BUTTON(XRCID("btnWeekdays"), dlgSchedule::OnSelectAllWeekdays) + EVT_BUTTON(XRCID("btnMonthdays"), dlgSchedule::OnSelectAllMonthdays) + EVT_BUTTON(XRCID("btnMonths"), dlgSchedule::OnSelectAllMonths) + EVT_BUTTON(XRCID("btnHours"), dlgSchedule::OnSelectAllHours) + EVT_BUTTON(XRCID("btnMinutes"), dlgSchedule::OnSelectAllMinutes) + EVT_CHECKLISTBOX(XRCID("chkWeekdays"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkMonthdays"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkMonths"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkHours"), dlgSchedule::OnChangeCom) + EVT_CHECKLISTBOX(XRCID("chkMinutes"), dlgSchedule::OnChangeCom) +#ifdef __WXMAC__ + EVT_SIZE( dlgSchedule::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgaScheduleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSchedule(this, frame, (pgaSchedule *)node, (pgaJob *)parent); +} + + +dlgSchedule::dlgSchedule(pgaFactory *f, frmMain *frame, pgaSchedule *node, pgaJob *j) + : dlgAgentProperty(f, frame, wxT("dlgSchedule")) +{ + schedule = node; + job = j; + if (job) + jobId = job->GetRecId(); + else + jobId = 0; + + lstExceptions->CreateColumns(0, _("Date"), _("Time"), 90); + lstExceptions->AddColumn(wxT("dirty"), 0); + lstExceptions->AddColumn(wxT("id"), 0); + + txtID->Disable(); + + btnChangeException->Disable(); + btnRemoveException->Disable(); + + int i; + + for (i = 0 ; i < 24 ; i++) + chkHours->Append(wxString::Format(wxT("%02d"), i)); + + for (i = 0 ; i < 60 ; i++) + chkMinutes->Append(wxString::Format(wxT("%02d"), i)); +} + + +pgObject *dlgSchedule::GetObject() +{ + return schedule; +} + + +#ifdef __WXMAC__ +void dlgSchedule::OnChangeSize(wxSizeEvent &ev) +{ + lstExceptions->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgSchedule::Go(bool modal) +{ + int returncode; + + if (schedule) + { + // edit mode + recId = schedule->GetRecId(); + txtID->SetValue(NumToStr(recId)); + chkEnabled->SetValue(schedule->GetEnabled()); + calStart->SetValue(schedule->GetStart().GetDateOnly()); + timStart->SetTime(schedule->GetStart()); + if (schedule->GetEnd().IsValid()) + { + calEnd->SetValue(schedule->GetEnd().GetDateOnly()); + timEnd->SetTime(schedule->GetEnd()); + } + else + { + calEnd->SetValue(wxInvalidDateTime); + timEnd->SetTime(wxInvalidDateTime); + timEnd->Disable(); + } + + unsigned int x; + for (x = 0; x < schedule->GetMonths().Length(); x++ ) + if (schedule->GetMonths()[x] == 't') chkMonths->Check(x, true); + + for (x = 0; x < schedule->GetMonthdays().Length(); x++ ) + if (schedule->GetMonthdays()[x] == 't') chkMonthdays->Check(x, true); + + for (x = 0; x < schedule->GetWeekdays().Length(); x++ ) + if (schedule->GetWeekdays()[x] == 't') chkWeekdays->Check(x, true); + + for (x = 0; x < schedule->GetHours().Length(); x++ ) + if (schedule->GetHours()[x] == 't') chkHours->Check(x, true); + + for (x = 0; x < schedule->GetMinutes().Length(); x++ ) + if (schedule->GetMinutes()[x] == 't') chkMinutes->Check(x, true); + + wxString id, dateToken, timeToken; + wxDateTime val; + long pos = 0; + wxStringTokenizer tkz(schedule->GetExceptions(), wxT("|")); + + while (tkz.HasMoreTokens() ) + { + dateToken.Empty(); + timeToken.Empty(); + + // First is the ID + id = tkz.GetNextToken(); + + // Look for a date + if (tkz.HasMoreTokens()) + dateToken = tkz.GetNextToken(); + + // Look for a time + if (tkz.HasMoreTokens()) + timeToken = tkz.GetNextToken(); + + if (!dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + val.ParseTime(timeToken); + pos = lstExceptions->AppendItem(0, val.FormatDate(), val.FormatTime()); + } + else if (!dateToken.IsEmpty() && timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + pos = lstExceptions->AppendItem(0, val.FormatDate(), _("")); + } + else if (dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseTime(timeToken); + pos = lstExceptions->AppendItem(0, _(""), val.FormatTime()); + } + + lstExceptions->SetItem(pos, 2, BoolToStr(false)); + lstExceptions->SetItem(pos, 3, id); + + } + + wxNotifyEvent ev; + } + else + { + // create mode + } + + // setup de-/select buttons + InitSelectAll(); + + returncode = dlgProperty::Go(modal); + + SetSqlReadOnly(true); + + return returncode; +} + + +pgObject *dlgSchedule::CreateObject(pgCollection *collection) +{ + pgObject *obj = scheduleFactory.CreateObjects(collection, 0, wxT(" AND jscid=") + NumToStr(recId) + wxT("\n")); + return obj; +} + + +void dlgSchedule::OnChangeCal(wxCalendarEvent &ev) +{ + CheckChange(); +} + + +void dlgSchedule::OnChangeCom(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgSchedule::CheckChange() +{ + timEnd->Enable(calEnd->GetValue().IsValid()); + + wxString name = GetName(); + bool enable = true; + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + InitSelectAll(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, calStart->GetValue().IsValid(), _("Please specify start date.")); + + if (enable) + { + EnableOK(!GetSql().IsEmpty()); + } + else + EnableOK(false); +} + + +void dlgSchedule::OnSelChangeException(wxListEvent &ev) +{ + int sel = lstExceptions->GetSelection(); + if (sel >= 0) + { + wxString exDate = lstExceptions->GetText(sel, 0); + wxString exTime = lstExceptions->GetText(sel, 1); + wxDateTime val, null; + + if (exDate == _("")) + calException->SetValue(null); + else + { + val.ParseDate(exDate); + calException->SetValue(val); + } + if (exTime == _("")) + timException->SetTime(null); + else + { + val.ParseTime(exTime); + timException->SetTime(val); + } + + btnChangeException->Enable(); + btnRemoveException->Enable(); + } +} + + +void dlgSchedule::OnAddException(wxCommandEvent &ev) +{ + if (!calException->GetValue().IsValid() && timException->GetValue().IsNull()) + { + wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + wxString exDate, exTime; + + if (calException->GetValue().IsValid()) + exDate = calException->GetValue().FormatDate(); + else + exDate = _(""); + + if (!timException->GetValue().IsNull()) + exTime = timException->GetValue().Format(); + else + exTime = _(""); + + for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++) + { + + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == exTime) + { + wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == _("")) + { + wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 1) == exTime && + lstExceptions->GetText(pos, 0) == _("")) + { + wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + } + + lstExceptions->AppendItem(0, exDate, exTime); + CheckChange(); +} + + +void dlgSchedule::OnChangeException(wxCommandEvent &ev) +{ + if (!calException->GetValue().IsValid() && timException->GetValue().IsNull()) + { + wxMessageBox(_("You must enter a valid date and/or time!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + wxString exDate, exTime; + + if (calException->GetValue().IsValid()) + exDate = calException->GetValue().FormatDate(); + else + exDate = _(""); + + if (!timException->GetValue().IsNull()) + exTime = timException->GetValue().Format(); + else + exTime = _(""); + + long item = lstExceptions->GetFocusedItem(); + + for (int pos = 0; pos < lstExceptions->GetItemCount(); pos++) + { + if (item != pos) + { + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == exTime) + { + wxMessageBox(_("The specified exception already exists!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 0) == exDate && + lstExceptions->GetText(pos, 1) == _("")) + { + wxMessageBox(_("An exception already exists for any time on this date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + + if (lstExceptions->GetText(pos, 1) == exTime && + lstExceptions->GetText(pos, 0) == _("")) + { + wxMessageBox(_("An exception already exists for this time on any date!"), _("Add exception"), wxICON_EXCLAMATION | wxOK, this); + return; + } + } + } + + lstExceptions->SetItem(item, 0, exDate); + lstExceptions->SetItem(item, 1, exTime); + lstExceptions->SetItem(item, 2, BoolToStr(true)); + CheckChange(); +} + + +void dlgSchedule::OnRemoveException(wxCommandEvent &ev) +{ + if (lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3) != wxEmptyString) + { + deleteExceptions.Add(lstExceptions->GetText(lstExceptions->GetFocusedItem(), 3)); + } + lstExceptions->DeleteCurrentItem(); + + btnChangeException->Disable(); + btnRemoveException->Disable(); + + CheckChange(); +} + + +wxString dlgSchedule::GetComment() +{ + return txtComment->GetValue(); +} + + +wxString dlgSchedule::GetInsertSql() +{ + wxString sql; + if (!schedule) + { + wxString name = GetName(); + wxString jscjobid, list = wxT("NULL"); + if (jobId) + jscjobid = NumToStr(jobId); + else + jscjobid = wxT(""); + + // Build the various arrays of values + sql = wxT("INSERT INTO pgagent.pga_schedule (jscid, jscjobid, jscname, jscdesc, jscminutes, jschours, jscweekdays, jscmonthdays, jscmonths, jscenabled, jscstart, jscend)\n") + wxT("VALUES(, ") + jscjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + + wxT("'") + ChkListBox2PgArray(chkMinutes) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkHours) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkWeekdays) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkMonthdays) + wxT("', ") + + wxT("'") + ChkListBox2PgArray(chkMonths) + wxT("', ") + + BoolToStr(chkEnabled->GetValue()) + wxT(", ") + + wxT("'") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'"); + + if (calEnd->GetValue().IsValid()) + sql += wxT(", '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'"); + else + sql += wxT(", NULL"); + + sql += wxT(");\n"); + } + + return sql; +} + + +wxString dlgSchedule::GetUpdateSql() +{ + wxString sql, name; + name = GetName(); + + if (schedule) + { + // edit mode + wxString vars; + + if (name != schedule->GetName()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscname = ") + qtDbString(name)); + } + if (txtComment->GetValue() != schedule->GetComment()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscdesc = ") + qtDbString(txtComment->GetValue())); + } + + if ((!chkEnabled->IsChecked() && schedule->GetEnabled()) || (chkEnabled->IsChecked() && !schedule->GetEnabled())) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscenabled = ") + BoolToStr(chkEnabled->IsChecked())); + } + + if (calStart->GetValue() + timStart->GetValue() != schedule->GetStart()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscstart = '") + DateToAnsiStr(calStart->GetValue() + timStart->GetValue()) + wxT("'")); + } + + if (calEnd->GetValue().IsValid()) + { + if (schedule->GetEnd().IsValid()) + { + if (calEnd->GetValue() + timEnd->GetValue() != schedule->GetEnd()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + timEnd->GetValue()) + wxT("'")); + } + } + else + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscend = '") + DateToAnsiStr(calEnd->GetValue() + wxTimeSpan()) + wxT("'")); + } + } + else + { + if (schedule->GetEnd().IsValid()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscend = NULL")); + } + } + + if (ChkListBox2StrArray(chkMinutes) != schedule->GetMinutes()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscminutes = '") + ChkListBox2PgArray(chkMinutes) + wxT("'")); + } + + if (ChkListBox2StrArray(chkHours) != schedule->GetHours()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jschours = '") + ChkListBox2PgArray(chkHours) + wxT("'")); + } + + if (ChkListBox2StrArray(chkWeekdays) != schedule->GetWeekdays()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscweekdays = '") + ChkListBox2PgArray(chkWeekdays) + wxT("'")); + } + + if (ChkListBox2StrArray(chkMonthdays) != schedule->GetMonthdays()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscmonthdays = '") + ChkListBox2PgArray(chkMonthdays) + wxT("'")); + } + + if (ChkListBox2StrArray(chkMonths) != schedule->GetMonths()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jscmonths = '") + ChkListBox2PgArray(chkMonths) + wxT("'")); + } + + if (!vars.IsEmpty()) + sql = wxT("UPDATE pgagent.pga_schedule SET ") + vars + wxT("\n") + wxT(" WHERE jscid=") + NumToStr(recId) + wxT(";\n"); + } + else + { + // create mode + // Handled by GetInsertSQL + } + + unsigned int x = 0; + int y = 0; + wxDateTime tmpDateTime; + wxString newDate, newTime; + + // Remove old exceptions + for (x = 0; x < deleteExceptions.Count(); x++) + { + sql += wxT("DELETE FROM pgagent.pga_exception\n WHERE jexid = ") + deleteExceptions[x] + wxT(";\n"); + } + + // Update dirty exceptions + for (y = 0; y < lstExceptions->GetItemCount(); y++) + { + if (lstExceptions->GetText(y, 2) == BoolToStr(true) && + lstExceptions->GetText(y, 3) != wxEmptyString) + { + if (lstExceptions->GetText(y, 0) == _("")) + newDate = wxT("null"); + else + { + tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x")); + newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'"); + } + + if (lstExceptions->GetText(y, 1) == _("")) + newTime = wxT("null"); + else + { + tmpDateTime.ParseTime(lstExceptions->GetText(y, 1)); + newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'"); + } + + sql += wxT("UPDATE pgagent.pga_exception SET jexdate = ") + newDate + + wxT(", jextime = ") + newTime + wxT("\n WHERE jexid = ") + + lstExceptions->GetText(y, 3) + wxT(";\n"); + } + } + + // Insert new exceptions + for (y = 0; y < lstExceptions->GetItemCount(); y++) + { + if (lstExceptions->GetText(y, 2) == wxEmptyString && + lstExceptions->GetText(y, 3) == wxEmptyString) + { + if (lstExceptions->GetText(y, 0) == _("")) + newDate = wxT("null"); + else + { + tmpDateTime.ParseFormat(lstExceptions->GetText(y, 0), wxT("%x")); + newDate = wxT("'") + tmpDateTime.FormatISODate() + wxT("'"); + } + + if (lstExceptions->GetText(y, 1) == _("")) + newTime = wxT("null"); + else + { + tmpDateTime.ParseTime(lstExceptions->GetText(y, 1)); + newTime = wxT("'") + tmpDateTime.FormatISOTime() + wxT("'"); + } + + sql += wxT("INSERT INTO pgagent.pga_exception (jexscid, jexdate, jextime)\n VALUES (") + + NumToStr(recId) + wxT(", ") + newDate + wxT(", ") + newTime + wxT(");\n"); + + } + } + + + + return sql; +} + + +const wxString dlgSchedule::ChkListBox2PgArray(wxCheckListBox *lb) +{ + wxString res = wxT("{"); + + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (lb->IsChecked(x)) + res += wxT("t,"); + else + res += wxT("f,"); + } + if (res.Length() > 1) + res.RemoveLast(); + + res += wxT("}"); + + return res; +} + + +const wxString dlgSchedule::ChkListBox2StrArray(wxCheckListBox *lb) +{ + wxString res; + + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (lb->IsChecked(x)) + res += wxT("t"); + else + res += wxT("f"); + } + + return res; +} + + +void dlgSchedule::OnSelectAll(wxCommandEvent &ev, int origin) +{ + bool check = false; + wxBitmapButton *btn; + wxCheckListBox *lb; + wxString tooltip; + + switch (origin) + { + case 1: + btn = ((wxBitmapButton *)btnWeekdays); + lb = chkWeekdays; + break; + case 2: + btn = ((wxBitmapButton *)btnMonthdays); + lb = chkMonthdays; + break; + case 3: + btn = ((wxBitmapButton *)btnMonths); + lb = chkMonths; + break; + case 4: + btn = ((wxBitmapButton *)btnHours); + lb = chkHours; + break; + case 5: + btn = ((wxBitmapButton *)btnMinutes); + lb = chkMinutes; + break; + default: + return; + break; + } + + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + lb->Check(x, check); + } + + CheckChange(); +} + + +void dlgSchedule::InitSelectAll() +{ + bool check = false; + wxBitmapButton *btn; + wxCheckListBox *lb; + wxString tooltip; + + btn = ((wxBitmapButton *)btnWeekdays); + lb = chkWeekdays; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all week days"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all week days"); + } + btn->SetToolTip(tooltip); + + check = false; + btn = ((wxBitmapButton *)btnMonthdays); + lb = chkMonthdays; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all month days"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all month days"); + } + btn->SetToolTip(tooltip); + + check = false; + btn = ((wxBitmapButton *)btnMonths); + lb = chkMonths; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all months"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all months"); + } + btn->SetToolTip(tooltip); + + check = false; + btn = ((wxBitmapButton *)btnHours); + lb = chkHours; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all hours"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all hours"); + } + btn->SetToolTip(tooltip); + + + check = false; + btn = ((wxBitmapButton *)btnMinutes); + lb = chkMinutes; + for (unsigned int x = 0; x < lb->GetCount(); x++) + { + if (!lb->IsChecked(x)) + { + check = true; + break; + } + } + + if (check) + { + btn->SetBitmapLabel(*check_png_bmp); + tooltip = _("Select all minutes"); + } + else + { + btn->SetBitmapLabel(*uncheck_png_bmp); + tooltip = _("Deselect all minutes"); + } + btn->SetToolTip(tooltip); +} diff --git a/agent/dlgStep.cpp b/agent/dlgStep.cpp new file mode 100644 index 0000000..2641d3d --- /dev/null +++ b/agent/dlgStep.cpp @@ -0,0 +1,483 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgStep.cpp - PostgreSQL Step Property +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "agent/dlgStep.h" +#include "agent/pgaStep.h" +#include "dlg/dlgSelectDatabase.h" +#include "schema/pgTable.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define rbxKind CTRL_RADIOBOX("rbxKind") +#define rbxOnError CTRL_RADIOBOX("rbxOnError") +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_TEXT("txtSqlBox") +#define cbDatabase CTRL_COMBOBOX2("cbDatabase") +#define txtConnStr CTRL_TEXT("txtConnStr") +#define btnSelDatabase CTRL_BUTTON("btnSelDatabase") +#define rbRemoteConn CTRL_RADIOBUTTON("rbRemoteConn") +#define rbLocalConn CTRL_RADIOBUTTON("rbLocalConn") + +#define CTL_SQLBOX 188 + +BEGIN_EVENT_TABLE(dlgStep, dlgAgentProperty) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rbxKind"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rbxOnError"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtConnStr"), dlgProperty::OnChange) + EVT_STC_MODIFIED(CTL_SQLBOX, dlgProperty::OnChangeStc) + EVT_BUTTON(XRCID("btnSelDatabase"), dlgStep::OnSelectDatabase) + EVT_RADIOBUTTON(XRCID("rbRemoteConn"), dlgStep::OnSelRemoteConn) + EVT_RADIOBUTTON(XRCID("rbLocalConn"), dlgStep::OnSelLocalConn) +END_EVENT_TABLE(); + + +dlgProperty *pgaStepFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgStep(this, frame, (pgaStep *)node, (pgaJob *)parent); +} + + +dlgStep::dlgStep(pgaFactory *f, frmMain *frame, pgaStep *node, pgaJob *j) + : dlgAgentProperty(f, frame, wxT("dlgStep")) +{ + step = node; + job = j; + if (job) + jobId = job->GetRecId(); + else + jobId = 0; + + sqlBox = new ctlSQLBox(pnlDefinition, CTL_SQLBOX, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + + wxWindow *placeholder = CTRL_TEXT("txtSqlBox"); + wxSizer *sizer = placeholder->GetContainingSizer(); + sizer->Add(sqlBox, 1, wxRIGHT | wxGROW, 5); + sizer->Detach(placeholder); + delete placeholder; + sizer->Layout(); + + + txtID->Disable(); +} + + +pgObject *dlgStep::GetObject() +{ + return step; +} + + +int dlgStep::Go(bool modal) +{ + int returncode; + + hasConnStrSupport = connection->TableHasColumn(wxT("pgagent"), wxT("pga_jobstep"), wxT("jstconnstr")); + cbDatabase->Append(wxT(" ")); + cbDatabase->SetSelection(0); + + pgSet *db = connection->ExecuteSet(wxT("SELECT datname FROM pg_database")); + if (db) + { + while (!db->Eof()) + { + cbDatabase->Append(db->GetVal(0)); + db->MoveNext(); + } + delete db; + } + + if (step) + { + // edit mode + recId = step->GetRecId(); + txtID->SetValue(NumToStr(recId)); + + if (step->HasConnectionString()) + { + rbRemoteConn->SetValue(true); + txtConnStr->Enable(true); + txtConnStr->ChangeValue(step->GetConnStr()); + btnSelDatabase->Enable(true); + cbDatabase->Enable(false); + } + else + { + rbLocalConn->SetValue(true); + if (step->GetDbname().IsEmpty()) + cbDatabase->SetSelection(0); + else + cbDatabase->SetValue(step->GetDbname()); + } + + rbxKind->SetSelection(wxString(wxT("sb")).Find(step->GetKindChar())); + rbxOnError->SetSelection(wxString(wxT("fsi")).Find(step->GetOnErrorChar())); + sqlBox->SetText(step->GetCode()); + + chkEnabled->SetValue(step->GetEnabled()); + } + else + { + // create mode + rbLocalConn->SetValue(true); + cbDatabase->Enable(true); + btnSelDatabase->Enable(false); + txtConnStr->Enable(false); + if (!hasConnStrSupport) + rbLocalConn->Enable(false); + } + + returncode = dlgProperty::Go(modal); + + SetSqlReadOnly(true); + + return returncode; +} + + +pgObject *dlgStep::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = stepFactory.CreateObjects(collection, 0, wxT(" AND jstid=") + NumToStr(recId) + wxT("\n")); + return obj; +} + + +void dlgStep::CheckChange() +{ + wxString name = GetName(); + bool enable; + if (step) + { + enable = name != step->GetName() + || chkEnabled->GetValue() != step->GetEnabled() + || rbxKind->GetSelection() != wxString(wxT("sb")).Find(step->GetKindChar()) + || rbxOnError->GetSelection() != wxString(wxT("fsi")).Find(step->GetOnErrorChar()) + || txtComment->GetValue() != step->GetComment() + || sqlBox->GetText() != step->GetCode(); + + if (!enable && rbxKind->GetSelection() == 0) + { + if (hasConnStrSupport) + { + if (step->HasConnectionString()) + { + if (rbRemoteConn->GetValue()) + enable = txtConnStr->GetValue().Trim() != step->GetConnStr(); + else + enable = true; + } + else + { + if (rbRemoteConn->GetValue()) + enable = true; + else + enable = cbDatabase->GetValue().Trim() != step->GetDbname(); + } + } + else + { + enable = cbDatabase->GetValue().Trim() != step->GetDbname(); + } + } + } + else + { + enable = true; + } + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, sqlBox->GetLength() > 0, _("Please specify code to execute.")); + + // Disable/enable the database combo + if (rbxKind->GetSelection() == 1) + { + rbRemoteConn->Enable(false); + rbLocalConn->Enable(false); + // I don't see any reason to make + // the database combobox selection to 0 + //cbDatabase->SetSelection(0); + txtConnStr->Enable(false); + btnSelDatabase->Enable(false); + cbDatabase->Enable(false); + } + else + { + if (hasConnStrSupport) + { + rbRemoteConn->Enable(true); + rbLocalConn->Enable(true); + if (rbRemoteConn->GetValue()) + { + wxString validConnStr; + + btnSelDatabase->Enable(true); + txtConnStr->Enable(true); + cbDatabase->Enable(false); + CheckValid(enable, !txtConnStr->GetValue().Trim().IsEmpty(), _("Please select a connection string.")); + CheckValid(enable, dlgSelectDatabase::getValidConnectionString(txtConnStr->GetValue().Trim(), validConnStr), _("Please enter a valid connection string")); + } + else + { + cbDatabase->Enable(true); + btnSelDatabase->Enable(false); + txtConnStr->Enable(false); + CheckValid(enable, !cbDatabase->GetValue().Trim().IsEmpty(), _("Please select a database.")); + } + } + else + { + cbDatabase->Enable(true); + // Make sure both radio buttons are disabled + rbRemoteConn->Enable(false); + rbLocalConn->Enable(false); + CheckValid(enable, !cbDatabase->GetValue().Trim().IsEmpty(), _("Please select a database.")); + } + } + + EnableOK(enable); +} + + + +wxString dlgStep::GetComment() +{ + return txtComment->GetValue(); +} + + + +wxString dlgStep::GetInsertSql() +{ + wxString sql; + + if (!step) + { + wxString name = GetName(); + wxString kind = wxT("sb")[rbxKind->GetSelection()]; + wxString onerror = wxT("fsi")[rbxOnError->GetSelection()]; + wxString db, connstr; + wxString jstjobid; + if (jobId) + jstjobid = NumToStr(jobId); + else + jstjobid = wxT(""); + // SQL script expected + if (rbxKind->GetSelection() == 0) + { + if (hasConnStrSupport && rbRemoteConn->GetValue()) + { + connstr = qtDbString(txtConnStr->GetValue().Trim()); + db = wxT("''"); + } + else + { + db = qtDbString(cbDatabase->GetValue().Trim()); + connstr = wxT("''"); + } + } + else + { + db = wxT("''"); + connstr = wxT("''"); + } + + sql = wxT("INSERT INTO pgagent.pga_jobstep (jstid, jstjobid, jstname, jstdesc, jstenabled, jstkind, jstonerror, jstcode, jstdbname"); + if (hasConnStrSupport) + sql += wxT(", jstconnstr"); + sql += wxT(")\n ") \ + wxT("SELECT , ") + jstjobid + wxT(", ") + qtDbString(name) + wxT(", ") + qtDbString(txtComment->GetValue()) + wxT(", ") + + BoolToStr(chkEnabled->GetValue()) + wxT(", ") + qtDbString(kind) + wxT(", ") + + qtDbString(onerror) + wxT(", ") + qtDbString(sqlBox->GetText()) + wxT(", ") + db; + if (hasConnStrSupport) + { + sql += wxT(", ") + connstr; + } + sql += wxT(";\n"); + } + return sql; +} + + +wxString dlgStep::GetUpdateSql() +{ + wxString sql; + + if (step) + { + // edit mode + wxString name = GetName(); + wxString kind = wxT("sb")[rbxKind->GetSelection()]; + + wxString vars; + if (name != step->GetName()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstname=") + qtDbString(name)); + } + if (chkEnabled->GetValue() != step->GetEnabled()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstenabled=") + BoolToStr(chkEnabled->GetValue())); + } + if (hasConnStrSupport && kind == wxT("s")) + { + if (rbRemoteConn->GetValue()) + { + if (step->HasConnectionString()) + { + if (txtConnStr->GetValue().Trim() != step->GetConnStr()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstconnstr=") + qtDbString(txtConnStr->GetValue().Trim())); + } + } + else + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstconnstr=") + qtDbString(txtConnStr->GetValue().Trim()) + wxT(", ")); + vars.Append(wxT("jstdbname=''")); + } + } + else + { + if (step->HasConnectionString()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim()) + wxT(", ")); + vars.Append(wxT("jstconnstr=''")); + } + else + { + if (cbDatabase->GetValue().Trim() != step->GetDbname()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim())); + } + } + } + } + else if (kind == wxT("s")) + { + if (cbDatabase->GetValue().Trim() != step->GetDbname()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=") + qtDbString(cbDatabase->GetValue().Trim())); + } + } + else + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdbname=''")); + if (hasConnStrSupport) + vars.Append(wxT(", jstconnstr=''")); + } + if (rbxKind->GetSelection() != kind) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstkind=") + qtDbString(kind)); + } + if (rbxOnError->GetSelection() != wxString(wxT("fsi")).Find(step->GetOnErrorChar())) + { + wxString onerror = wxT("fsi")[rbxOnError->GetSelection()]; + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstonerror='") + onerror + wxT("'")); + } + if (txtComment->GetValue() != step->GetComment()) + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstdesc=") + qtDbString(txtComment->GetValue())); + } + if (sqlBox->GetText() != step->GetCode()) + { + { + if (!vars.IsEmpty()) + vars.Append(wxT(", ")); + vars.Append(wxT("jstcode=") + qtDbString(sqlBox->GetText())); + } + } + + if (!vars.IsEmpty()) + sql = wxT("UPDATE pgagent.pga_jobstep\n") + wxT(" SET ") + vars + wxT("\n") + wxT(" WHERE jstid=") + NumToStr(step->GetRecId()) + + wxT(";\n"); + } + else + { + // create mode; handled by GetInsertSql() + } + return sql; +} + +bool dlgStep::IsUpToDate() +{ + if (step && !step->IsUpToDate()) + return false; + else + return true; +} + +void dlgStep::OnSelectDatabase(wxCommandEvent &ev) +{ + dlgSelectDatabase dlgSD(this, wxID_ANY); + if (dlgSD.ShowModal() == wxID_OK) + { + wxString strConnStr = dlgSD.getConnInfo(); + if (!strConnStr.IsEmpty()) + txtConnStr->SetValue(strConnStr); + } +} + +void dlgStep::OnSelRemoteConn(wxCommandEvent &ev) +{ + if (rbRemoteConn->GetValue()) + { + cbDatabase->Enable(false); + btnSelDatabase->Enable(true); + txtConnStr->Enable(true); + } + dlgProperty::OnChange(ev); +} + +void dlgStep::OnSelLocalConn(wxCommandEvent &ev) +{ + if (rbLocalConn->GetValue()) + { + cbDatabase->Enable(true); + btnSelDatabase->Enable(false); + txtConnStr->Enable(false); + } + dlgProperty::OnChange(ev); +} + + diff --git a/agent/module.mk b/agent/module.mk new file mode 100644 index 0000000..f0ede73 --- /dev/null +++ b/agent/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/agent/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + agent/dlgJob.cpp \ + agent/dlgSchedule.cpp \ + agent/dlgStep.cpp \ + agent/pgaJob.cpp \ + agent/pgaSchedule.cpp \ + agent/pgaStep.cpp + +EXTRA_DIST += \ + agent/module.mk + + diff --git a/agent/pgaJob.cpp b/agent/pgaJob.cpp new file mode 100644 index 0000000..989c15a --- /dev/null +++ b/agent/pgaJob.cpp @@ -0,0 +1,397 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgDatabase.h" +#include "agent/pgaJob.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" + +pgaJob::pgaJob(const wxString &newName) + : pgServerObject(jobFactory, newName) +{ +} + +wxString pgaJob::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent job"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent job"); + break; + case PROPERTIESREPORT: + message = _("pgAgent job properties report"); + break; + case PROPERTIES: + message = _("pgAgent job properties"); + break; + case DDLREPORT: + message = _("pgAgent job DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pgAgent job dependencies report"); + break; + case DEPENDENCIES: + message = _("pgAgent job dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pgAgent job dependents report"); + break; + case DEPENDENTS: + message = _("pgAgent job dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop job \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop job?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +int pgaJob::GetIconId() +{ + if (GetEnabled()) + return jobFactory.GetIconId(); + else + return jobFactory.GetDisabledId(); +} + + +wxMenu *pgaJob::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (1) // check priv. + { + stepFactory.AppendMenu(menu); + scheduleFactory.AppendMenu(menu); + } + return menu; +} + + +bool pgaJob::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_job WHERE jobid=") + NumToStr(GetRecId())); +} + + +void pgaJob::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child objects to Job.")); + + browser->AppendCollection(this, scheduleFactory); + browser->AppendCollection(this, stepFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + properties->AppendItem(_("Host agent"), GetHostAgent()); + properties->AppendItem(_("Job class"), GetJobclass()); + properties->AppendItem(_("Created"), GetCreated()); + properties->AppendItem(_("Changed"), GetChanged()); + properties->AppendItem(_("Next run"), GetNextrun()); + properties->AppendItem(_("Last run"), GetLastrun()); + properties->AppendItem(_("Last result"), GetLastresult()); + if (!GetCurrentAgent().IsEmpty()) + properties->AppendItem(_("Running at"), GetCurrentAgent()); + else + properties->AppendItem(_("Running at"), _("Not currently running")); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgaJob::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *job = 0; + + pgObject *obj = browser->GetObject(browser->GetItemParent(item)); + if (obj && obj->IsCollection()) + job = jobFactory.CreateObjects((pgCollection *)obj, 0, wxT("\n WHERE j.jobid=") + NumToStr(GetRecId())); + + return job; +} + + + +pgObject *pgaJobFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgaJob *job = 0; + + pgSet *jobs = collection->GetConnection()->ExecuteSet( + wxT("SELECT j.*, cl.*, ag.*, sub.jlgstatus AS joblastresult ") + wxT(" FROM pgagent.pga_job j JOIN") + wxT(" pgagent.pga_jobclass cl ON cl.jclid=jobjclid LEFT OUTER JOIN") + wxT(" pgagent.pga_jobagent ag ON ag.jagpid=jobagentid LEFT OUTER JOIN") + wxT(" (SELECT DISTINCT ON (jlgjobid) jlgstatus, jlgjobid") + wxT(" FROM pgagent.pga_joblog") + wxT(" ORDER BY jlgjobid, jlgid desc) sub ON sub.jlgjobid = j.jobid ") + + restriction + + wxT("ORDER BY jobname;")); + + if (jobs) + { + while (!jobs->Eof()) + { + wxString status; + if (jobs->GetVal(wxT("joblastresult")) == wxT("r")) + status = _("Running"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("s")) + status = _("Successful"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("f")) + status = _("Failed"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("d")) + status = _("Aborted"); + else if (jobs->GetVal(wxT("joblastresult")) == wxT("i")) + status = _("No steps"); + else + status = _("Unknown"); + + job = new pgaJob(jobs->GetVal(wxT("jobname"))); + job->iSetServer(collection->GetServer()); + job->iSetRecId(jobs->GetLong(wxT("jobid"))); + job->iSetComment(jobs->GetVal(wxT("jobdesc"))); + + job->iSetEnabled(jobs->GetBool(wxT("jobenabled"))); + job->iSetJobclass(jobs->GetVal(wxT("jclname"))); + job->iSetHostAgent(jobs->GetVal(wxT("jobhostagent"))); + job->iSetCreated(jobs->GetDateTime(wxT("jobcreated"))); + job->iSetChanged(jobs->GetDateTime(wxT("jobchanged"))); + job->iSetNextrun(jobs->GetDateTime(wxT("jobnextrun"))); + job->iSetLastrun(jobs->GetDateTime(wxT("joblastrun"))); + job->iSetLastresult(status); + job->iSetCurrentAgent(jobs->GetVal(wxT("jagstation"))); + + if (browser) + { + browser->AppendObject(collection, job); + jobs->MoveNext(); + } + else + break; + } + + delete jobs; + } + return job; +} + +void pgaJob::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT jlgid") + wxT(", jlgstatus") + wxT(", jlgstart") + wxT(", jlgduration") + wxT(", (jlgstart + jlgduration) AS endtime") + wxT(" FROM pgagent.pga_joblog\n") + wxT(" WHERE jlgjobid = ") + NumToStr(GetRecId()) + + wxT(" ORDER BY jlgstart DESC") + + wxT(" LIMIT ") + NumToStr(settings->GetMaxRows()); + + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Run"), 50); + statistics->AddColumn(_("Status"), 60); + statistics->AddColumn(_("Start time"), 95); + statistics->AddColumn(_("End time"), 95); + statistics->AddColumn(_("Duration"), 70); + + pgSet *stats = GetConnection()->ExecuteSet(sql); + wxString status; + wxDateTime startTime; + wxDateTime endTime; + + if (stats) + { + while (!stats->Eof()) + { + if (stats->GetVal(1) == wxT("r")) + status = _("Running"); + else if (stats->GetVal(1) == wxT("s")) + status = _("Successful"); + else if (stats->GetVal(1) == wxT("f")) + status = _("Failed"); + else if (stats->GetVal(1) == wxT("d")) + status = _("Aborted"); + else if (stats->GetVal(1) == wxT("i")) + status = _("No steps"); + else + status = _("Unknown"); + + startTime.ParseDateTime(stats->GetVal(2)); + endTime.ParseDateTime(stats->GetVal(4)); + + long pos = statistics->AppendItem(stats->GetVal(0), status, startTime.Format()); + if (stats->GetVal(4).Length() > 0) + statistics->SetItem(pos, 3, endTime.Format()); + statistics->SetItem(pos, 4, stats->GetVal(3)); + + stats->MoveNext(); + } + delete stats; + } + } +} + +bool pgaJob::RunNow() +{ + if (!GetConnection()->ExecuteVoid(wxT("UPDATE pgagent.pga_job SET jobnextrun = now() WHERE jobid=") + NumToStr(GetRecId()))) + return false; + + return true; +} + + +pgaJobCollection::pgaJobCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgaJobCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent jobs"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent jobs"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent jobs list report"); + break; + } + + return message; +} + + +pgaJobObject::pgaJobObject(pgaJob *_job, pgaFactory &factory, const wxString &newName) + : pgServerObject(factory, newName) +{ + job = _job; + server = job->GetServer(); +} + + +pgaJobObjCollection::pgaJobObjCollection(pgaFactory *factory, pgaJob *_job) + : pgServerObjCollection(factory, _job->GetServer()) +{ + job = _job; +} + + +bool pgaJobObjCollection::CanCreate() +{ + return job->CanCreate(); +} + + +pgCollection *pgaJobObjFactory::CreateCollection(pgObject *obj) +{ + return new pgaJobObjCollection(GetCollectionFactory(), (pgaJob *)obj); +} + + +///////////////////////////// + + +#include "images/job.pngc" +#include "images/jobs.pngc" +#include "images/jobdisabled.pngc" + +pgaJobFactory::pgaJobFactory() + : pgServerObjFactory(__("pgAgent Job"), __("New Job"), __("Create a new Job."), job_png_img) +{ + metaType = PGM_JOB; + disabledId = addIcon(jobdisabled_png_img); +} + + +pgCollection *pgaJobFactory::CreateCollection(pgObject *obj) +{ + return new pgaJobCollection(GetCollectionFactory(), (pgServer *)obj); +} + + +pgaJobFactory jobFactory; +static pgaCollectionFactory cf(&jobFactory, __("Jobs"), jobs_png_img); + +runNowFactory::runNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Run now"), _("Reschedule the job to run now.")); +} + + +wxWindow *runNowFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgaJob *)(obj))->RunNow()) + { + wxLogError(_("Failed to reschedule the job.")); + } + + form->Refresh(obj); + + return 0; +} + + +bool runNowFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->GetMetaType() == PGM_JOB && !obj->IsCollection()) + return true; + } + return false; +} diff --git a/agent/pgaSchedule.cpp b/agent/pgaSchedule.cpp new file mode 100644 index 0000000..0022621 --- /dev/null +++ b/agent/pgaSchedule.cpp @@ -0,0 +1,576 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaSchedule.cpp - PostgreSQL Agent Schedule +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "schema/pgCollection.h" +#include "agent/pgaSchedule.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" + + +pgaSchedule::pgaSchedule(pgCollection *_collection, const wxString &newName) + : pgaJobObject(_collection->GetJob(), scheduleFactory, newName) +{ +} + +wxString pgaSchedule::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent schedule"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent schedule"); + break; + case PROPERTIESREPORT: + message = _("pgAgent schedule properties report"); + break; + case PROPERTIES: + message = _("pgAgent schedule properties"); + break; + case DDLREPORT: + message = _("pgAgent schedule DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pgAgent schedule dependencies report"); + break; + case DEPENDENCIES: + message = _("pgAgent schedule dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pgAgent schedule dependents report"); + break; + case DEPENDENTS: + message = _("pgAgent schedule dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop schedule \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop schedule?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +bool pgaSchedule::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_schedule WHERE jscid=") + NumToStr(GetRecId())); +} + + +void pgaSchedule::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + + properties->AppendItem(_("Start date"), GetStart()); + properties->AppendItem(_("End date"), GetEnd()); + properties->AppendItem(_("Minutes"), GetMinutesString()); + properties->AppendItem(_("Hours"), GetHoursString()); + properties->AppendItem(_("Weekdays"), GetWeekdaysString()); + properties->AppendItem(_("Monthdays"), GetMonthdaysString()); + properties->AppendItem(_("Months"), GetMonthsString()); + properties->AppendItem(_("Exceptions"), GetExceptionsString()); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgaSchedule::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *schedule = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + schedule = scheduleFactory.CreateObjects(coll, 0, wxT("\n AND jscid=") + NumToStr(GetRecId())); + + return schedule; +} + + + +pgObject *pgaScheduleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgaSchedule *schedule = 0; + wxString tmp; + + pgSet *schedules = collection->GetConnection()->ExecuteSet( + wxT("SELECT * FROM pgagent.pga_schedule\n") + wxT(" WHERE jscjobid=") + NumToStr(collection->GetJob()->GetRecId()) + wxT("\n") + + restriction + + wxT(" ORDER BY jscname")); + + if (schedules) + { + while (!schedules->Eof()) + { + + schedule = new pgaSchedule(collection, schedules->GetVal(wxT("jscname"))); + schedule->iSetRecId(schedules->GetLong(wxT("jscid"))); + schedule->iSetStart(schedules->GetDateTime(wxT("jscstart"))); + schedule->iSetEnd(schedules->GetDateTime(wxT("jscend"))); + schedule->iSetEnabled(schedules->GetBool(wxT("jscenabled"))); + + tmp = schedules->GetVal(wxT("jscminutes")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetMinutes(tmp); + + tmp = schedules->GetVal(wxT("jschours")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetHours(tmp); + + tmp = schedules->GetVal(wxT("jscweekdays")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetWeekdays(tmp); + + tmp = schedules->GetVal(wxT("jscmonthdays")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetMonthdays(tmp); + + tmp = schedules->GetVal(wxT("jscmonths")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + tmp.Replace(wxT(","), wxT("")); + schedule->iSetMonths(tmp); + + schedule->iSetComment(schedules->GetVal(wxT("jscdesc"))); + + pgSet *exceptions = collection->GetConnection()->ExecuteSet( + wxT("SELECT * FROM pgagent.pga_exception\n") + wxT(" WHERE jexscid=") + NumToStr(schedule->GetRecId()) + wxT("\n")); + + tmp.Empty(); + if (exceptions) + { + while (!exceptions->Eof()) + { + tmp += exceptions->GetVal(wxT("jexid")); + tmp += wxT("|"); + tmp += exceptions->GetVal(wxT("jexdate")); + tmp += wxT("|"); + tmp += exceptions->GetVal(wxT("jextime")); + tmp += wxT("|"); + + exceptions->MoveNext(); + } + } + schedule->iSetExceptions(tmp); + delete exceptions; + + if (browser) + { + browser->AppendObject(collection, schedule); + schedules->MoveNext(); + } + else + break; + } + + delete schedules; + } + return schedule; +} + +wxString pgaSchedule::GetMinutesString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res, tmp; + + for (x = 0; x <= minutes.Length(); x++) + { + if (minutes[x] == 't') + { + tmp.Printf(wxT("%.2d, "), (int)x); + res += tmp; + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every minute"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetHoursString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res, tmp; + + for (x = 0; x <= hours.Length(); x++) + { + if (hours[x] == 't') + { + tmp.Printf(wxT("%.2d, "), (int)x); + res += tmp; + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every hour"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetWeekdaysString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res; + + for (x = 0; x <= weekdays.Length(); x++) + { + if (weekdays[x] == 't') + { + switch (x) + { + case 0: + res += _("Sunday"); + res += wxT(", "); + break; + case 1: + res += _("Monday"); + res += wxT(", "); + break; + case 2: + res += _("Tuesday"); + res += wxT(", "); + break; + case 3: + res += _("Wednesday"); + res += wxT(", "); + break; + case 4: + res += _("Thursday"); + res += wxT(", "); + break; + case 5: + res += _("Friday"); + res += wxT(", "); + break; + case 6: + res += _("Saturday"); + res += wxT(", "); + break; + default: + res += _("The mythical 8th day!"); + res += wxT(", "); + break; + } + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Any day of the week"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetMonthdaysString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res, tmp; + + for (x = 0; x <= monthdays.Length(); x++) + { + if (monthdays[x] == 't') + { + if (x < 31) + { + tmp.Printf(wxT("%.2d, "), (int)(x + 1)); + res += tmp; + } + else + { + res += _("Last day"); + res += wxT(", "); + } + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every day"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetMonthsString() +{ + size_t x = 0; + bool isWildcard = true; + wxString res; + + for (x = 0; x <= months.Length(); x++) + { + if (months[x] == 't') + { + switch (x) + { + case 0: + res += _("January"); + res += wxT(", "); + break; + case 1: + res += _("February"); + res += wxT(", "); + break; + case 2: + res += _("March"); + res += wxT(", "); + break; + case 3: + res += _("April"); + res += wxT(", "); + break; + case 4: + res += _("May"); + res += wxT(", "); + break; + case 5: + res += _("June"); + res += wxT(", "); + break; + case 6: + res += _("July"); + res += wxT(", "); + break; + case 7: + res += _("August"); + res += wxT(", "); + break; + case 8: + res += _("September"); + res += wxT(", "); + break; + case 9: + res += _("October"); + res += wxT(", "); + break; + case 10: + res += _("November"); + res += wxT(", "); + break; + case 11: + res += _("December"); + res += wxT(", "); + break; + default: + res += _("The mythical 13th month!"); + res += wxT(", "); + break; + } + isWildcard = false; + } + } + + if (isWildcard) + { + res = _("Every month"); + } + else + { + if (res.Length() > 2) + { + res.RemoveLast(); + res.RemoveLast(); + } + } + + return res; +} + +wxString pgaSchedule::GetExceptionsString() +{ + wxString tmp, token, dateToken, timeToken; + wxDateTime val; + wxStringTokenizer tkz(exceptions, wxT("|")); + + while (tkz.HasMoreTokens() ) + { + + dateToken.Empty(); + timeToken.Empty(); + + // First is the ID which can be ignored + token = tkz.GetNextToken(); + + // Look for a date + if (tkz.HasMoreTokens()) + dateToken = tkz.GetNextToken(); + + // Look for a time + if (tkz.HasMoreTokens()) + timeToken = tkz.GetNextToken(); + + if (tmp.IsEmpty()) + tmp += wxT("["); + else + tmp += wxT(", ["); + + if (!dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + val.ParseTime(timeToken); + tmp += val.Format(); + } + else if (!dateToken.IsEmpty() && timeToken.IsEmpty()) + { + val.ParseDate(dateToken); + tmp += val.FormatDate(); + } + else if (dateToken.IsEmpty() && !timeToken.IsEmpty()) + { + val.ParseTime(timeToken); + tmp += val.FormatTime(); + } + + tmp += wxT("]"); + + } + + return tmp; +} + + +///////////////////////////// + + +pgaScheduleCollection::pgaScheduleCollection(pgaFactory *factory, pgaJob *job) + : pgaJobObjCollection(factory, job) +{ +} + + +wxString pgaScheduleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent schedules"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent schedules"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent schedules list report"); + break; + } + + return message; +} + +///////////////////////////// + + +#include "images/schedule.pngc" +#include "images/schedules.pngc" + +pgaScheduleFactory::pgaScheduleFactory() + : pgaJobObjFactory(__("Schedule"), __("New Schedule"), __("Create a new Schedule."), schedule_png_img) +{ + metaType = PGM_SCHEDULE; +} + + +pgCollection *pgaScheduleFactory::CreateCollection(pgObject *obj) +{ + return new pgaScheduleCollection(GetCollectionFactory(), (pgaJob *)obj); +} + + +pgaScheduleFactory scheduleFactory; +static pgaCollectionFactory cf(&scheduleFactory, __("Schedules"), schedules_png_img); diff --git a/agent/pgaStep.cpp b/agent/pgaStep.cpp new file mode 100644 index 0000000..eee6fc9 --- /dev/null +++ b/agent/pgaStep.cpp @@ -0,0 +1,327 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaStep.cpp - PostgreSQL Agent Step +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "schema/pgCollection.h" +#include "agent/pgaStep.h" +#include "agent/pgaSchedule.h" + +pgaStep::pgaStep(pgCollection *_collection, const wxString &newName) + : pgaJobObject(_collection->GetJob(), stepFactory, newName) +{ +} + +wxString pgaStep::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent step"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent step"); + break; + case PROPERTIESREPORT: + message = _("pgAgent step properties report"); + break; + case PROPERTIES: + message = _("pgAgent step properties"); + break; + case DDLREPORT: + message = _("pgAgent step DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pgAgent step dependencies report"); + break; + case DEPENDENCIES: + message = _("pgAgent step dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pgAgent step dependents report"); + break; + case DEPENDENTS: + message = _("pgAgent step dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop step \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop step?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +bool pgaStep::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pgagent.pga_jobstep WHERE jstid = ") + NumToStr(GetRecId()); + if (!GetConnection() || GetConnection()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool pgaStep::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DELETE FROM pgagent.pga_jobstep WHERE jstid=") + NumToStr(GetRecId())); +} + + +void pgaStep::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + properties->AppendItem(_("Kind"), GetKind()); + if (GetConnStr().IsEmpty()) + properties->AppendItem(_("Database"), GetDbname()); + else + properties->AppendItem(_("Connection String"), GetConnStr()); + properties->AppendItem(_("Code"), GetCode()); + properties->AppendItem(_("On error"), GetOnError()); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgaStep::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *step = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + step = stepFactory.CreateObjects(coll, 0, wxT("\n AND jstid=") + NumToStr(GetRecId())); + + return step; +} + + + +pgObject *pgaStepFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgaStep *step = 0; + + pgSet *steps = collection->GetConnection()->ExecuteSet( + wxT("SELECT xmin, * FROM pgagent.pga_jobstep\n") + wxT(" WHERE jstjobid=") + NumToStr(collection->GetJob()->GetRecId()) + wxT("\n") + + restriction + + wxT(" ORDER BY jstname")); + + if (steps) + { + while (!steps->Eof()) + { + + step = new pgaStep(collection, steps->GetVal(wxT("jstname"))); + step->iSetRecId(steps->GetLong(wxT("jstid"))); + step->iSetXid(steps->GetOid(wxT("xmin"))); + step->iSetDbname(steps->GetVal(wxT("jstdbname"))); + if (steps->HasColumn(wxT("jstconnstr"))) + step->iSetConnStr(steps->GetVal(wxT("jstconnstr"))); + step->iSetCode(steps->GetVal(wxT("jstcode"))); + step->iSetEnabled(steps->GetBool(wxT("jstenabled"))); + + wxChar kindc = *steps->GetVal(wxT("jstkind")).c_str(); + wxString kinds; + switch (kindc) + { + case 'b': + kinds = _("Batch"); + break; + case 's': + kinds = wxT("SQL"); + break; + } + step->iSetKindChar(kindc); + step->iSetKind(kinds); + + wxChar onerrc = *steps->GetVal(wxT("jstonerror")).c_str(); + wxString onerrs; + switch (onerrc) + { + case 's': + onerrs = _("Succeed"); + break; + case 'f': + onerrs = _("Fail"); + break; + case 'i': + onerrs = _("Ignore"); + break; + + + } + + step->iSetOnErrorChar(onerrc); + step->iSetOnError(onerrs); + step->iSetComment(steps->GetVal(wxT("jstdesc"))); + + + if (browser) + { + browser->AppendObject(collection, step); + steps->MoveNext(); + } + else + break; + } + + delete steps; + } + return step; +} + + +void pgaStep::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT jsljlgid") + wxT(", jslstatus") + wxT(", jslresult") + wxT(", jslstart") + wxT(", jslduration") + wxT(", (jslstart + jslduration) AS endtime") + wxT(", jsloutput") + wxT(" FROM pgagent.pga_jobsteplog\n") + wxT(" WHERE jsljstid = ") + NumToStr(GetRecId()) + + wxT(" ORDER BY jslstart DESC") + wxT(" LIMIT ") + NumToStr(settings->GetMaxRows()); + + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Run"), 50); + statistics->AddColumn(_("Status"), 60); + statistics->AddColumn(_("Result"), 60); + statistics->AddColumn(_("Start time"), 95); + statistics->AddColumn(_("End time"), 95); + statistics->AddColumn(_("Duration"), 70); + statistics->AddColumn(_("Output"), 200); + + pgSet *stats = GetConnection()->ExecuteSet(sql); + wxString status; + wxDateTime startTime; + wxDateTime endTime; + + if (stats) + { + while (!stats->Eof()) + { + if (stats->GetVal(1) == wxT("r")) + status = _("Running"); + else if (stats->GetVal(1) == wxT("s")) + status = _("Successful"); + else if (stats->GetVal(1) == wxT("f")) + status = _("Failed"); + else if (stats->GetVal(1) == wxT("i")) + status = _("Ignored"); + else if (stats->GetVal(1) == wxT("d")) + status = _("Aborted"); + else + status = _("Unknown"); + + startTime.ParseDateTime(stats->GetVal(3)); + endTime.ParseDateTime(stats->GetVal(5)); + + long pos = statistics->AppendItem(stats->GetVal(0), status, stats->GetVal(2)); + statistics->SetItem(pos, 3, startTime.Format()); + if (stats->GetVal(5).Length() > 0) + statistics->SetItem(pos, 4, endTime.Format()); + statistics->SetItem(pos, 5, stats->GetVal(4)); + statistics->SetItem(pos, 6, stats->GetVal(6)); + + stats->MoveNext(); + } + delete stats; + } + } +} + + +///////////////////////////// + + +pgaStepCollection::pgaStepCollection(pgaFactory *factory, pgaJob *job) + : pgaJobObjCollection(factory, job) +{ +} + + +wxString pgaStepCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent steps"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent steps"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent steps list report"); + break; + } + + return message; +} + + +///////////////////////////// + + +#include "images/step.pngc" +#include "images/steps.pngc" + +pgaStepFactory::pgaStepFactory() + : pgaJobObjFactory(__("Step"), __("New Step"), __("Create a new Step."), step_png_img) +{ + metaType = PGM_STEP; +} + + +pgCollection *pgaStepFactory::CreateCollection(pgObject *obj) +{ + return new pgaStepCollection(GetCollectionFactory(), (pgaJob *)obj); +} + + +pgaStepFactory stepFactory; +static pgaCollectionFactory cf(&stepFactory, __("Steps"), steps_png_img); diff --git a/ctl/calbox.cpp b/ctl/calbox.cpp new file mode 100644 index 0000000..0945126 --- /dev/null +++ b/ctl/calbox.cpp @@ -0,0 +1,519 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// calbox.cpp - Date-picker control box +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include + +#include "ctl/calbox.h" + +#if !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL + +#if defined(__WXMSW__) +#define TXTCTRL_FLAGS wxNO_BORDER +#define CALBORDER 0 +#define TXTPOSX 0 +#define TXTPOSY 1 +#elif defined(__WXGTK__) +#define TXTCTRL_FLAGS 0 +#define CALBORDER 4 +#define TXTPOSX 0 +#define TXTPOSY 0 +#else +#define TXTCTRL_FLAGS 0 +#define CALBORDER 4 +#define TXTPOSX 0 +#define TXTPOSY 0 +#endif + + +#define CTRLID_TXT 101 +#define CTRLID_CAL 102 +#define CTRLID_BTN 103 +#define CTRLID_PAN 104 + +BEGIN_EVENT_TABLE(wxCalendarBox, wxControl) + EVT_BUTTON(CTRLID_BTN, wxCalendarBox::OnClick) + EVT_TEXT(CTRLID_TXT, wxCalendarBox::OnText) + EVT_CHILD_FOCUS(wxCalendarBox::OnChildSetFocus) + EVT_SIZE(wxCalendarBox::OnSize) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(wxCalendarBox, wxControl) + + + +wxCalendarBox::wxCalendarBox(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + Init(); + Create(parent, id, date, pos, size, style, name); +} + + +bool wxCalendarBox::Create(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + wxString txt; + if (date.IsValid()) + txt = date.FormatISODate(); + + if ( !wxControl::Create(parent, id, pos, size, + style | wxCLIP_CHILDREN | wxWANTS_CHARS, + wxDefaultValidator, name) ) + + { + return false; + } + + InheritAttributes(); + + wxSize cs = GetClientSize(); + wxSize bs = ConvertDialogToPixels(wxSize(10, 0)); + + wxBitmap bmp(8, 4); + { + wxMemoryDC dc; + + dc.SelectObject(bmp); + dc.SetBrush(wxBrush(GetBackgroundColour())); + dc.SetPen(wxPen(GetBackgroundColour())); + dc.DrawRectangle(0, 0, 8, 4); + + dc.SetBrush(wxBrush(GetForegroundColour())); + dc.SetPen(wxPen(GetForegroundColour())); + wxPoint pt[3] = { wxPoint(0, 0), wxPoint(6, 0), wxPoint(3, 3) }; + dc.DrawPolygon(3, pt); + dc.SelectObject(wxNullBitmap); + } + + m_txt = new wxTextCtrl(this, CTRLID_TXT, txt, wxDefaultPosition, size, TXTCTRL_FLAGS); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxCalendarBox::OnEditKey), 0, this); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(wxCalendarBox::OnKillFocus), 0, this); + SetFormat(wxT("%Y-%m-%d")); + + m_btn = new wxBitmapButton(this, CTRLID_BTN, bmp, wxDefaultPosition, bs); + + m_dlg = new wxDialog(this, CTRLID_CAL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + m_dlg->SetFont(GetFont()); + + wxPanel *panel = new wxPanel(m_dlg, CTRLID_PAN, wxPoint(0, 0), wxDefaultSize, wxSUNKEN_BORDER | wxCLIP_CHILDREN); + m_cal = new pgCompatCalendarCtrl(panel, CTRLID_CAL, wxDefaultDateTime, wxPoint(0, 0), wxDefaultSize, wxSUNKEN_BORDER); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_SEL_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(wxID_ANY, wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxCalendarBox::OnCalKey), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_DOUBLECLICKED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_DAY_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_MONTH_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + m_cal->Connect(CTRLID_CAL, CTRLID_CAL, wxEVT_CALENDAR_YEAR_CHANGED, wxCalendarEventHandler(wxCalendarBox::OnSelChange), 0, this); + + wxWindow *yearControl = m_cal->GetYearControl(); + + Connect(wxID_ANY, wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(wxCalendarBox::OnSetFocus)); + + wxClientDC dc(yearControl); + dc.SetFont(m_font); + wxCoord width, dummy; + dc.GetTextExtent(wxT("2000"), &width, &dummy); + width += ConvertDialogToPixels(wxSize(20, 0)).x; + + wxSize calSize = m_cal->GetBestSize(); + wxSize yearSize = yearControl->GetSize(); + yearSize.x = width; + + wxPoint yearPosition = yearControl->GetPosition(); + + width = yearPosition.x + yearSize.x + 2 + CALBORDER / 2; + if (width < calSize.x - 4) + width = calSize.x - 4; + + int calPos = (width - calSize.x) / 2; + if (calPos == -1) + { + calPos = 0; + width += 2; + } + m_cal->SetSize(calPos, 0, calSize.x, calSize.y); + yearControl->SetSize(width - yearSize.x - CALBORDER / 2, yearPosition.y, yearSize.x, yearSize.y); + m_cal->GetMonthControl()->Move(0, 0); + + SetInitialSize(size); + + panel->SetClientSize(width + CALBORDER / 2, calSize.y - 2 + CALBORDER); + m_dlg->SetClientSize(panel->GetSize()); + + return true; +} + + +void wxCalendarBox::Init() +{ + m_dlg = NULL; + m_txt = NULL; + m_cal = NULL; + m_btn = NULL; + + m_dropped = false; + m_ignoreDrop = false; +} + + +bool wxCalendarBox::Destroy() +{ + if (m_cal) + m_cal->Destroy(); + if (m_dlg) + m_dlg->Destroy(); + if (m_txt) + m_txt->Destroy(); + if (m_btn) + m_btn->Destroy(); + + m_dlg = NULL; + m_txt = NULL; + m_cal = NULL; + m_btn = NULL; + + return wxControl::Destroy(); +} + + +void wxCalendarBox::DoMoveWindow(int x, int y, int w, int h) +{ + wxControl::DoMoveWindow(x, y, w, h); + if (m_dropped) + { + DropDown(); + } +} + + +wxSize wxCalendarBox::DoGetBestSize() const +{ + int bh = m_btn->GetBestSize().y; + int eh = m_txt->GetBestSize().y; + return wxSize(100, bh > eh ? bh : eh); +} + + +void wxCalendarBox::OnSize(wxSizeEvent &event) +{ + if ( m_btn ) + { + wxSize sz = GetClientSize(); + + wxSize bs = m_btn->GetSize(); + int eh = m_txt->GetBestSize().y; + + m_txt->SetSize(TXTPOSX, TXTPOSY, sz.x - bs.x - TXTPOSX, sz.y > eh ? eh - TXTPOSY : sz.y - TXTPOSY); + m_btn->SetSize(sz.x - bs.x, 0, bs.x, sz.y); + } + + event.Skip(); +} + + +bool wxCalendarBox::Show(bool show) +{ + if ( !wxControl::Show(show) ) + { + return false; + } + + if (!show) + { + if (m_dlg) + { + m_dlg->Hide(); + m_dropped = false; + } + } + + return true; +} + + +bool wxCalendarBox::Enable(bool enable) +{ + if ( !wxControl::Enable(enable) ) + { + return false; + } + + if (m_cal) + { + if (enable) + m_cal->Show(); + else + m_cal->Hide(); + } + + if (m_btn) + m_btn->Enable(enable); + return true; +} + + +bool wxCalendarBox::SetFormat(const wxChar *fmt) +{ + wxDateTime dt; + dt.ParseFormat(wxT("2003-10-13"), wxT("%Y-%m-%d")); + wxString str = dt.Format(fmt); + const wxChar *p = (const wxChar *) str; + + m_format = wxEmptyString; + + while (*p) + { + int n = wxAtoi(p); + if (n == dt.GetDay()) + { + m_format.Append(wxT("%d")); + p += 2; + } + else if (n == (int)dt.GetMonth() + 1) + { + m_format.Append(wxT("%m")); + p += 2; + } + else if (n == dt.GetYear()) + { + m_format.Append(wxT("%Y")); + p += 4; + } + else + m_format.Append(*p++); + } + + if (m_txt) + { + wxArrayString valArray; + wxChar c; + for (c = '0'; c <= '9'; c++) + valArray.Add(wxString(c, 1)); + const wxChar *p = (const wxChar *) m_format; + while (*p) + { + if (*p == '%') + p += 2; + else + valArray.Add(wxString(*p++, 1)); + } + wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST); + tv.SetIncludes(valArray); + + m_txt->SetValidator(tv); + } + return true; +} + + +wxDateTime wxCalendarBox::GetValue() +{ + wxDateTime dt; + wxString txt = m_txt->GetValue(); + + if (!txt.IsEmpty()) + dt.ParseFormat(txt, m_format); + + return dt; +} + + +bool wxCalendarBox::SetValue(const wxDateTime &date) +{ + bool retval = false; + + if (m_cal) + { + if (date.IsValid()) + m_txt->SetValue(date.FormatISODate()); + else + m_txt->SetValue(wxEmptyString); + } + return retval; +} + + +void wxCalendarBox::DropDown(bool down) +{ + if (m_dlg) + { + if (down) + { + if (m_txt->GetValue().IsEmpty()) + m_cal->SetDate(wxDateTime::Today()); + else + { + wxDateTime dt; + dt.ParseFormat(m_txt->GetValue(), m_format); + m_cal->SetDate(dt); + } + wxPoint pos = GetParent()->ClientToScreen(GetPosition()); + + m_dlg->Move(pos.x, pos.y + GetSize().y); + m_dlg->Show(); + m_dropped = true; + } + else + { + if (m_dropped) + m_dlg->Hide(); + m_dropped = false; + } + } +} + + +void wxCalendarBox::OnChildSetFocus(wxChildFocusEvent &ev) +{ + ev.Skip(); + m_ignoreDrop = false; + + wxWindow *w = (wxWindow *)ev.GetEventObject(); + while (w) + { + if (w == m_dlg) + return; + w = w->GetParent(); + } + + if (m_dropped) + { + DropDown(false); + if (ev.GetEventObject() == m_btn) + m_ignoreDrop = true; + } +} + + +void wxCalendarBox::OnClick(wxCommandEvent &event) +{ + if (m_ignoreDrop) + { + m_ignoreDrop = false; + m_txt->SetFocus(); + } + else + { + DropDown(); + m_cal->SetFocus(); + } +} + + +void wxCalendarBox::OnSetFocus(wxFocusEvent &ev) +{ + if (m_txt) + { + m_txt->SetFocus(); + m_txt->SetSelection(0, 100); + } +} + + +void wxCalendarBox::OnKillFocus(wxFocusEvent &ev) +{ + wxDateTime dt; + dt.ParseFormat(m_txt->GetValue(), m_format); + if (!dt.IsValid()) + m_txt->SetValue(wxEmptyString); + else + m_txt->SetValue(dt.Format(m_format)); +} + + +void wxCalendarBox::OnSelChange(wxCalendarEvent &ev) +{ + if (m_cal) + { + m_txt->SetValue(m_cal->GetDate().FormatISODate()); + if (ev.GetEventType() == wxEVT_CALENDAR_DOUBLECLICKED) + { + DropDown(false); + m_txt->SetFocus(); + } + } + ev.SetEventObject(this); + ev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + +} + + +void wxCalendarBox::OnText(wxCommandEvent &ev) +{ + ev.SetEventObject(this); + ev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + + // We'll create an additional event if the date is valid. + // If the date isn't valid, the user's probably in the middle of typing + wxString txt = m_txt->GetValue(); + wxDateTime dt; + if (!txt.IsEmpty()) + dt.ParseFormat(txt, m_format); + +#if wxCHECK_VERSION(2, 9, 0) + wxCalendarEvent cev(m_cal, dt, wxEVT_CALENDAR_SEL_CHANGED); +#else + wxCalendarEvent cev(m_cal, wxEVT_CALENDAR_SEL_CHANGED); + cev.SetDate(dt); +#endif + cev.SetEventObject(this); + cev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(cev); +#else + GetParent()->ProcessEvent(cev); +#endif + +} + + +void wxCalendarBox::OnEditKey(wxKeyEvent &ev) +{ + if (ev.GetKeyCode() == WXK_DOWN && !ev.HasModifiers()) + DropDown(); + else + ev.Skip(); +} + + +void wxCalendarBox::OnCalKey(wxKeyEvent &ev) +{ + if (ev.GetKeyCode() == WXK_ESCAPE && !ev.HasModifiers()) + DropDown(false); + else + ev.Skip(); +} + +#endif // !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL diff --git a/ctl/ctlAuiNotebook.cpp b/ctl/ctlAuiNotebook.cpp new file mode 100644 index 0000000..ed3bc20 --- /dev/null +++ b/ctl/ctlAuiNotebook.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlAuiNotebook.cpp - Custom AUI Notebook class +// +////////////////////////////////////////////////////////////////////////// + +// The primary purpose of this class is to pass child focus events from +// the notebook to the parent window. This is the only way we can grab +// focus events from the page controls. + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include + +BEGIN_EVENT_TABLE(ctlAuiNotebook, wxAuiNotebook) + EVT_CHILD_FOCUS(ctlAuiNotebook::OnChildFocus) +END_EVENT_TABLE() + +// Handle, and pass up child focus events +void ctlAuiNotebook::OnChildFocus(wxChildFocusEvent &event) +{ + +#if wxCHECK_VERSION(2, 9, 0) + wxAuiNotebook::OnChildFocusNotebook(event); + GetParent()->GetEventHandler()->AddPendingEvent(event); +#else + wxAuiNotebook::OnChildFocus(event); + GetParent()->AddPendingEvent(event); +#endif + +} diff --git a/ctl/ctlCheckTreeView.cpp b/ctl/ctlCheckTreeView.cpp new file mode 100644 index 0000000..bff9ab1 --- /dev/null +++ b/ctl/ctlCheckTreeView.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlCheckTreeView.cpp - TreeView with Checkboxes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "ctl/ctlCheckTreeView.h" +#include "images/checked.pngc" +#include "images/disabled.pngc" +#include "images/unchecked.pngc" + +BEGIN_EVENT_TABLE(ctlCheckTreeView, wxTreeCtrl) + EVT_LEFT_DOWN( ctlCheckTreeView::OnLeftClick) +END_EVENT_TABLE() + + +ctlCheckTreeView::ctlCheckTreeView(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxTreeCtrl(parent, id, pos, size, style) +{ + wxImageList *treeimages = new wxImageList(16, 16, true, 3); + treeimages->Add(*unchecked_png_img); + treeimages->Add(*checked_png_img); + treeimages->Add(*disabled_png_img); + SetImageList(treeimages); +} + + +void ctlCheckTreeView::OnLeftClick(wxMouseEvent &evt) +{ + int flags; + wxTreeItemId node = HitTest(evt.GetPosition(), flags); + int newimage = 0; + + if ((flags & wxTREE_HITTEST_ONITEMLABEL) || (flags & wxTREE_HITTEST_ONITEMICON)) + { + if (GetItemImage(node) == 0) + newimage = 1; + else if (GetItemImage(node) == 1) + newimage = 0; + + if (newimage == 0 || newimage == 1) + SetParentAndChildImage(node, newimage); + if (newimage == 1) + SetParentImage(node, newimage); + } + + evt.Skip(); +} + +void ctlCheckTreeView::SetParentAndChildImage(wxTreeItemId node, int newimage) +{ + SetItemImage(node, newimage); + wxTreeItemIdValue childData; + wxTreeItemId child = GetFirstChild(node, childData); + while (child.IsOk()) + { + SetParentAndChildImage(child, newimage); + child = GetNextChild(node, childData); + } +} + +void ctlCheckTreeView::SetParentImage(wxTreeItemId node, int newimage) +{ + if (node.IsOk()) + { + SetItemImage(node, newimage); + SetParentImage(GetItemParent(node), newimage); + } +} + +bool ctlCheckTreeView::IsChecked(const wxTreeItemId &node) +{ + return (GetItemImage(node) == 1); +} + diff --git a/ctl/ctlColourPicker.cpp b/ctl/ctlColourPicker.cpp new file mode 100644 index 0000000..ecc07fd --- /dev/null +++ b/ctl/ctlColourPicker.cpp @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// ctlColourPicker.cpp - Colour Picker with a wxBitmapButton +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlColourPicker.h" + + +void ctlColourPicker::Create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) +{ + // Set Default Title + m_title = _("Choose the colour"); + + // Create the wxBitmapButton + ((wxBitmapButton *)this)->Create(parent, id, wxNullBitmap, pos, size); + + // Set the handler for a click + Connect(id, wxEVT_LEFT_DOWN, wxMouseEventHandler(ctlColourPicker::DoProcessLeftClick) ); +} + + +void ctlColourPicker::DoProcessLeftClick(wxMouseEvent &event) +{ + wxColourData clrData; + + // Initialise custom colours + for (int index = 0; index < 16; index++) + clrData.SetCustomColour(index, settings->GetCustomColour(index)); + + // If there is an initial colour, set it for wxColourDialog + if (m_colour_clr.IsOk()) + clrData.SetColour(m_colour_clr); + + // Declare the new dialog + wxColourDialog dialog(this, &clrData); + + // and set its title + dialog.SetTitle(m_title); + + // Now, show it + if (dialog.ShowModal() == wxID_OK) + { + clrData = dialog.GetColourData(); + SetColour(clrData.GetColour()); + + // Store custom colours + for (int index = 0; index < 16; index++) + settings->SetCustomColour(index, clrData.GetCustomColour(index).GetAsString(wxC2S_HTML_SYNTAX)); + } +} + + +void ctlColourPicker::UpdateColour() +{ + if (!m_colour_clr.IsOk()) + { + wxLogError(wxT("ohoh")); + wxBitmap empty(1, 1); + SetBitmapLabel(empty); + return; + } + + wxSize sz = GetSize(); + sz.x -= 2 * GetMarginX(); + sz.y -= 2 * GetMarginY(); + + wxPoint topleft; + if ( sz.x < 1 ) + sz.x = 1; + else if ( sz.y < 1 ) + sz.y = 1; + wxBitmap bmp(sz.x, sz.y); + + wxMemoryDC dc(bmp); + dc.SetBrush(wxBrush(m_colour_clr)); + dc.DrawRectangle(topleft, sz); + + ((wxBitmapButton *)this)->SetBitmapLabel(bmp); +} + +wxColour ctlColourPicker::GetColour() +{ + return m_colour_clr; +} + +wxString ctlColourPicker::GetColourString() +{ + if (!m_colour_clr.IsOk()) + return wxEmptyString; + return m_colour_clr.GetAsString(); +} + +void ctlColourPicker::SetColour(const wxColour &colour) +{ + m_colour_clr = colour; + UpdateColour(); +} + +void ctlColourPicker::SetColour(const wxString &colour) +{ + m_colour_clr = wxColour(colour); + UpdateColour(); +} + +void ctlColourPicker::SetTitle(const wxString &title) +{ + m_title = title; +} diff --git a/ctl/ctlComboBox.cpp b/ctl/ctlComboBox.cpp new file mode 100644 index 0000000..78214a8 --- /dev/null +++ b/ctl/ctlComboBox.cpp @@ -0,0 +1,242 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlComboBox.cpp - enhanced combobox control +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// App headers +#include "ctl/ctlComboBox.h" +#include "db/pgConn.h" +#include "db/pgSet.h" + + +class StringClientData : public wxClientData +{ +public: + StringClientData(const wxChar *c) + { + str = c; + } + wxString str; +}; + + + + +int ctlComboBoxFix::Append(const wxString &item, const wxString &str) +{ + return wxComboBox::Append(item, new StringClientData(str)); +} + + +int ctlComboBoxFix::Append(const wxString &item, long l) +{ + return wxComboBox::Append(item, (void *)l); +} + + +int ctlComboBoxFix::Append(const wxString &item, OID oid) +{ + return wxComboBox::Append(item, (void *)oid); +} + + +int ctlComboBoxFix::FillLongKey(pgConn *conn, const wxChar *qry) +{ + int cnt = 0; + pgSetIterator set(conn->ExecuteSet(qry)); + while (set.RowsLeft()) + { + long l = set.GetLong(0); + wxString txt = set.GetVal(1); + Append(txt, l); + cnt++; + } + return cnt; +} + + +int ctlComboBoxFix::FillOidKey(pgConn *conn, const wxChar *qry) +{ + int cnt = 0; + pgSetIterator set(conn->ExecuteSet(qry)); + Freeze(); + while (set.RowsLeft()) + { + OID oid = set.GetOid(0); + wxString txt = set.GetVal(1); + Append(txt, oid); + cnt++; + } + Thaw(); + return cnt; +} + + +int ctlComboBoxFix::FillStringKey(pgConn *conn, const wxChar *qry) +{ + int cnt = 0; + pgSetIterator set(conn->ExecuteSet(qry)); + while (set.RowsLeft()) + { + wxString str = set.GetVal(0); + wxString txt = set.GetVal(1); + Append(txt, str); + cnt++; + } + return cnt; +} + +long ctlComboBoxFix::GetLongKey(int sel) +{ + if (sel < 0) + sel = GetSelection(); + return (long)wxItemContainer::GetClientData(sel); +} + +OID ctlComboBoxFix::GetOIDKey(int sel) +{ + if (sel < 0) + sel = GetSelection(); + return (OID)wxItemContainer::GetClientData(sel); +} + +wxString ctlComboBoxFix::GetStringKey(int sel) +{ + if (sel < 0) + sel = GetSelection(); + StringClientData *scd = (StringClientData *)wxItemContainer::GetClientObject(sel); + if (scd) + return scd->str; + return wxEmptyString; +} + + +ctlComboBoxFix::ctlComboBoxFix(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr) + : wxComboBox(wnd, id, wxEmptyString, pos, siz, 0, NULL, attr) +{ +} + + +bool ctlComboBoxFix::SetKey(long val) +{ + unsigned int i; + for (i = 0 ; i < GetCount() ; i++) + { + if (GetLongKey(i) == val) + { + SetSelection(i); + return true; + } + } + SetSelection(wxNOT_FOUND); + return false; +} + + +bool ctlComboBoxFix::SetKey(OID val) +{ + unsigned int i; + for (i = 0 ; i < GetCount() ; i++) + { + if (GetOIDKey(i) == val) + { + SetSelection(i); + return true; + } + } + SetSelection(wxNOT_FOUND); + return false; +} + + +bool ctlComboBoxFix::SetKey(const wxString &val) +{ + unsigned int i; + for (i = 0 ; i < GetCount() ; i++) + { + if (GetStringKey(i) == val) + { + SetSelection(i); + return true; + } + } + SetSelection(wxNOT_FOUND); + return false; +} + + +//////////////////////////////////////////// + +ctlComboBox::ctlComboBox(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr) + : ctlComboBoxFix(wnd, id, pos, siz, attr) +{ +#ifdef __WXGTK__ + SetEditable(false); +#endif +} + + +int ctlComboBox::GuessSelection(wxCommandEvent &ev) +{ + if (ev.GetEventType() != wxEVT_COMMAND_TEXT_UPDATED) + return GetGuessedSelection(); + + wxString str = wxComboBox::GetValue(); + if (str.Length()) + { + long pos = GetInsertionPoint(); + + long sel, count = GetCount(); + int len = str.Length(); + for (sel = 0 ; sel < count ; sel++) + { + if (str == GetString(sel).Left(len)) + { + SetSelection(sel); + wxString current = GetString(sel); + SetSelection(pos, current.Length()); + return sel; + } + } + } + return -1; +} + + +int ctlComboBox::GetGuessedSelection() const +{ + int sel = GetCurrentSelection(); + + if (sel < 0) + sel = FindString(GetValue()); + return sel; +} + +int ctlComboBox::GetSelection() const +{ + int sel = 0; +#ifdef __WXMSW__ + sel = GetCurrentSelection(); + + if (sel < 0) +#endif + sel = FindString(GetValue()); + return sel; +} + +wxString ctlComboBox::GetGuessedStringSelection() const +{ + int sel = GetGuessedSelection(); + if (sel < 0) + return wxEmptyString; + else + return GetString(sel); +} diff --git a/ctl/ctlDefaultSecurityPanel.cpp b/ctl/ctlDefaultSecurityPanel.cpp new file mode 100644 index 0000000..c425025 --- /dev/null +++ b/ctl/ctlDefaultSecurityPanel.cpp @@ -0,0 +1,623 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlDefaultSecurityPanel.cpp - Panel with default security information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlDefaultSecurityPanel.h" +#include "db/pgConn.h" +#include "dlg/dlgProperty.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "utils/sysLogger.h" + +#include + +defaultPrivilegesOn g_defPrivTables('r', wxT("Tables"), wxT("arwdDxt")), + g_defPrivSequences('S', wxT("Sequences"), wxT("rwU")), + g_defPrivFunctions('f', wxT("Functions"), wxT("X")), + g_defPrivTypes('T', wxT("Types"), wxT("U")); + +defaultPrivilegesOn::defaultPrivilegesOn(const wxChar privType, const wxString &privOn, const wxString &privileges) + : m_privilegeType(privType), m_privilegesOn(privOn), m_privileges(privileges) {} + +ctlDefaultSecurityPanel::ctlDefaultSecurityPanel(pgConn *conn, wxNotebook *nb, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize), nbNotebook(NULL) +{ + nb->AddPage(this, _("Default Privileges")); + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(1, 1, 1, 1); + mainSizer->AddGrowableCol(0); + mainSizer->AddGrowableRow(0); + + nbNotebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, 0, _("Default ACLs")); + + m_defPrivOnTablesPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivTables, imgList); + m_defPrivOnSeqsPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivSequences, imgList); + m_defPrivOnFuncsPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivFunctions, imgList); + if (conn->BackendMinimumVersion(9, 2)) + m_defPrivOnTypesPanel = new ctlDefaultPrivilegesPanel(this, nbNotebook, g_defPrivTypes, imgList); + else + m_defPrivOnTypesPanel = NULL; + + mainSizer->Add(nbNotebook, 0, wxEXPAND | wxALL, 2); + + this->SetSizer(mainSizer); + mainSizer->Fit(this); +} + +void ctlDefaultSecurityPanel::UpdatePrivilegePages(bool createDefPrivs, const wxString &defPrivsOnTables, + const wxString &defPrivsOnSeqs, const wxString &defPrivsOnFuncs, const wxString &defPrivsOnTypes) +{ + if (!createDefPrivs) + { + nbNotebook->Enable(false); + return; + } + m_defPrivOnTablesPanel->Update(defPrivsOnTables); + m_defPrivOnSeqsPanel->Update(defPrivsOnSeqs); + m_defPrivOnFuncsPanel->Update(defPrivsOnFuncs); + if (m_defPrivOnTypesPanel) + m_defPrivOnTypesPanel->Update(defPrivsOnTypes); +} + + +wxString ctlDefaultSecurityPanel::GetDefaultPrivileges(const wxString &schemaName) +{ + wxString strDefPrivs; + int nPageCount = nbNotebook->GetPageCount(); + for (int index = 0; index < nPageCount; index++) + { + strDefPrivs += (dynamic_cast(nbNotebook->GetPage(index)))->GetDefaultPrivileges(schemaName); + } + return strDefPrivs; +} + + +/////////////////////////////////////////////////////////////////////////////// +// ctlDefaultPrivilegesPanel +/////////////////////////////////////////////////////////////////////////////// + +BEGIN_EVENT_TABLE(ctlDefaultPrivilegesPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_DEFLBPRIV, ctlDefaultPrivilegesPanel::OnPrivSelChange) + EVT_BUTTON(CTL_DEFADDPRIV, ctlDefaultPrivilegesPanel::OnAddPriv) + EVT_BUTTON(CTL_DEFDELPRIV, ctlDefaultPrivilegesPanel::OnDelPriv) + EVT_TEXT(CTL_DEFCBGROUP, ctlDefaultPrivilegesPanel::OnGroupChange) + EVT_COMBOBOX(CTL_DEFCBGROUP, ctlDefaultPrivilegesPanel::OnGroupChange) + EVT_CHECKBOX(CTL_DEFALLPRIV, ctlDefaultPrivilegesPanel::OnPrivCheckAll) + EVT_CHECKBOX(CTL_DEFALLPRIVGRANT, ctlDefaultPrivilegesPanel::OnPrivCheckAllGrant) + EVT_CHECKBOX(CTL_DEFPRIVCB, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 2, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 4, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 6, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 8, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 10, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 12, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 14, ctlDefaultPrivilegesPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_DEFPRIVCB + 16, ctlDefaultPrivilegesPanel::OnPrivCheck) +END_EVENT_TABLE(); + +DEFINE_LOCAL_EVENT_TYPE(EVT_DEFAULTSECURITYPANEL_CHANGE) + +ctlDefaultPrivilegesPanel::ctlDefaultPrivilegesPanel(ctlDefaultSecurityPanel *defSecurityPanel, wxNotebook *nb, + defaultPrivilegesOn &privOn, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize), m_defPrivChanged(false), + m_privilegeType(privOn), m_defSecurityPanel(defSecurityPanel) +{ + + nb->AddPage(this, m_privilegeType.m_privilegesOn); + + allPrivileges = 0; + privCheckboxes = 0; + m_currentSelectedPriv = NULL; + + privilegeCount = m_privilegeType.m_privileges.Length(); + + wxFlexGridSizer *item0 = new wxFlexGridSizer(3, 1, 5, 5); + item0->AddGrowableCol(0); + item0->AddGrowableRow(0); + + privCheckboxes = new wxCheckBox*[privilegeCount * 2]; + + wxFlexGridSizer *itemSizer1 = new wxFlexGridSizer(1, 1, 5, 5); + itemSizer1->AddGrowableCol(0); + itemSizer1->AddGrowableRow(0); + + wxString strGroupLabel = settings->GetShowUsersForPrivileges() ? _("Role/Group") : _("Role"); + + lbPrivileges = new ctlListView(this, CTL_DEFLBPRIV, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT); + lbPrivileges->SetImageList(imgList, wxIMAGE_LIST_SMALL); + lbPrivileges->AddColumn(_("Role/Group"), 60, wxLIST_FORMAT_LEFT); + lbPrivileges->AddColumn(_("Privileges"), 60, wxLIST_FORMAT_LEFT); + itemSizer1->Add(lbPrivileges, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer1, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddPriv = new wxButton(this, CTL_DEFADDPRIV, _("Add/Change")); + itemSizer2->Add(btnAddPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + btnDelPriv = new wxButton(this, CTL_DEFDELPRIV, _("Remove")); + itemSizer2->Add(btnDelPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer2, 0, wxEXPAND | wxALL, 0); + + wxStaticBox *sb = new wxStaticBox(this, -1, _("Privileges")); + wxBoxSizer *itemSizer3 = new wxStaticBoxSizer( sb, wxVERTICAL ); + item0->Add(itemSizer3, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer4a = new wxBoxSizer(wxHORIZONTAL); + stGroup = new wxStaticText(this, CTL_DEFSTATICGROUP, strGroupLabel); + itemSizer4a->Add(stGroup, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + cbGroups = new ctlComboBox(this, CTL_DEFCBGROUP, wxDefaultPosition, wxDefaultSize); + cbGroups->Append(wxT("public")); + cbGroups->SetSelection(0); + itemSizer4a->Add(cbGroups, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + itemSizer3->Add(itemSizer4a, 0, wxEXPAND | wxALL, 0); + + /* border size depends on the plateform */ +#ifdef __WXMSW__ + int bordersize = 4; +#endif +#ifdef __WXMAC__ + int bordersize = 3; +#endif +#ifdef __WXGTK__ + int bordersize = 0; +#endif + + wxBoxSizer *itemSizer5 = new wxBoxSizer(wxHORIZONTAL); + allPrivileges = new wxCheckBox(this, CTL_DEFALLPRIV, wxT("ALL")); + itemSizer5->Add(allPrivileges, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant = new wxCheckBox(this, CTL_DEFALLPRIVGRANT, wxT("WITH GRANT OPTION")); + itemSizer5->Add(allPrivilegesGrant, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant->Disable(); + itemSizer3->Add(itemSizer5, 0, wxALL, bordersize); + + for (int index = 0; index < privilegeCount; index++) + { + int i = index * 2; + wxChar privilege = m_privilegeType.m_privileges.GetChar(index); + wxString priv = pgObject::GetPrivilegeName(privilege); + + wxCheckBox *cb; + wxBoxSizer *itemSizer6 = new wxBoxSizer(wxHORIZONTAL); + cb = new wxCheckBox(this, CTL_DEFPRIVCB + i, priv); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + privCheckboxes[i++] = cb; + cb = new wxCheckBox(this, CTL_DEFPRIVCB + i, wxT("WITH GRANT OPTION")); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + cb->Disable(); + privCheckboxes[i] = cb; + itemSizer3->Add(itemSizer6, 0, wxALL, bordersize); + + } + + this->SetSizer(item0); + item0->Fit(this); +} + + +ctlDefaultPrivilegesPanel::~ctlDefaultPrivilegesPanel() +{ + cbGroups->Clear(); + if (privCheckboxes) + delete[] privCheckboxes; +} + +// Find the privileges for the selected user from the map +// and select the check-boxes accordingly +bool ctlDefaultPrivilegesPanel::PrivCheckBoxUpdate(wxString &strRole) +{ + int index = 0; + wxString strKey = strRole; + defPrivHash::iterator priv = m_privileges.find(strKey); + bool canGrant = CanGrant(); + + if (priv == m_privileges.end()) + { + m_currentSelectedPriv = NULL; + allPrivileges->SetValue(true); + allPrivilegesGrant->Enable(canGrant); + for (; index < privilegeCount; index++) + { + privCheckboxes[index * 2]->Enable(); + privCheckboxes[index * 2]->SetValue(true); + privCheckboxes[index * 2 + 1]->Enable(canGrant); + } + return false; + } + else + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Enable(false); + } + + wxString currentPrivileges = priv->second.m_modified ? priv->second.m_newPriv : priv->second.m_origPriv; + m_currentSelectedPriv = &priv->second; + + for (index = 0; index < privilegeCount; index++) + { + int privAt = currentPrivileges.Find(m_privilegeType.m_privileges.GetChar(index)); + if (privAt != wxNOT_FOUND) + { + privCheckboxes[index * 2]->SetValue(true); + privCheckboxes[index * 2 + 1]->Enable(canGrant); + if (canGrant && (unsigned int)privAt < currentPrivileges.Length() - 1 && currentPrivileges.GetChar(privAt + 1) == wxT('*')) + privCheckboxes[index * 2 + 1]->SetValue(true); + else + privCheckboxes[index * 2 + 1]->SetValue(false); + } + else + { + privCheckboxes[index * 2]->SetValue(false); + privCheckboxes[index * 2 + 1]->SetValue(false); + privCheckboxes[index * 2 + 1]->Disable(); + } + } + return false; +} + + +bool ctlDefaultPrivilegesPanel::CanGrant() +{ + if (cbGroups->GetValue() == wxT("public")) + return false; + return true; +} + + +void ctlDefaultPrivilegesPanel::OnGroupChange(wxCommandEvent &ev) +{ + cbGroups->GuessSelection(ev); + + wxString strRole = cbGroups->GetValue(); + + if (strRole.IsEmpty()) + return; + + btnAddPriv->Enable(!PrivCheckBoxUpdate(strRole)); +} + + +void ctlDefaultPrivilegesPanel::OnPrivCheckAll(wxCommandEvent &ev) +{ + bool all = allPrivileges->GetValue(); + allPrivilegesGrant->Enable(all && CanGrant()); + + for (int i = 0; i < privilegeCount; i++) + { + privCheckboxes[i * 2]->SetValue(all); + CheckGrantOpt(i); + } +} + +void ctlDefaultPrivilegesPanel::OnPrivCheckAllGrant(wxCommandEvent &ev) +{ + bool grant = allPrivilegesGrant->GetValue(); + for (int i = 0 ; i < privilegeCount ; i++) + privCheckboxes[i * 2 + 1]->SetValue(grant); +} + + +void ctlDefaultPrivilegesPanel::OnPrivCheck(wxCommandEvent &ev) +{ + int id = (ev.GetId() - CTL_DEFPRIVCB) / 2; + CheckGrantOpt(id); + btnAddPriv->Enable(); + if (!privCheckboxes[id * 2]->GetValue()) + allPrivileges->SetValue(false); +} + + +void ctlDefaultPrivilegesPanel::CheckGrantOpt(int id) +{ + bool canGrant = (privCheckboxes[id * 2]->GetValue() && CanGrant()); + if (canGrant) + privCheckboxes[id * 2 + 1]->Enable(true); + else + { + privCheckboxes[id * 2 + 1]->SetValue(false); + privCheckboxes[id * 2 + 1]->Disable(); + } + btnAddPriv->Enable(); +} + + +void ctlDefaultPrivilegesPanel::OnDelPriv(wxCommandEvent &ev) +{ + int pos; + wxString strRole; + if ((pos = lbPrivileges->GetFirstSelected()) == -1) + return; + + wxListItem info; + info.m_itemId = pos; + info.m_col = 0; + info.m_mask = wxLIST_MASK_TEXT; + + if (lbPrivileges->GetItem(info)) + strRole = info.m_text; + + wxString strKey = strRole; + defPrivHash::iterator priv = m_privileges.find(strKey); + + if (priv != m_privileges.end()) + { + priv->second.m_modified = true; + priv->second.m_newPriv = wxT(""); + if (m_currentSelectedPriv == &priv->second) + PrivCheckBoxUpdate(strRole); + } + + lbPrivileges->DeleteCurrentItem(); + m_defPrivChanged = true; + + ev.Skip(); +} + + +void ctlDefaultPrivilegesPanel::OnAddPriv(wxCommandEvent &ev) +{ + wxString strRole, strPriv; + bool isPresent = (m_currentSelectedPriv != NULL && + ((m_currentSelectedPriv->m_modified && + !m_currentSelectedPriv->m_newPriv.IsEmpty()) || + (!m_currentSelectedPriv->m_modified))) + || lbPrivileges->FindItem(-1, cbGroups->GetGuessedStringSelection()) >= 0; + + if (allPrivileges && allPrivileges->GetValue()) + { + if (allPrivilegesGrant->GetValue()) + { + for (int index = 0; index < privilegeCount; index++) + { + strPriv += m_privilegeType.m_privileges.GetChar(index); + strPriv += wxT('*'); + } + } + else + strPriv = m_privilegeType.m_privileges; + } + else + { + for (int index = 0; index < privilegeCount; index++) + { + if (privCheckboxes[index * 2]->GetValue()) + { + strPriv += m_privilegeType.m_privileges.GetChar(index); + if(privCheckboxes[index * 2 + 1]->IsEnabled() && privCheckboxes[index * 2 + 1]->GetValue()) + strPriv += wxT('*'); + } + } + } + + if (!m_currentSelectedPriv) + { + strRole = cbGroups->GetGuessedStringSelection(); + + if (strRole.IsEmpty()) + return; + + defPrivilege priv; + priv.m_username = strRole; + priv.m_origPriv = wxT(""); + priv.m_modified = true; + priv.m_newPriv = strPriv; + + wxString strKey = strRole; + m_privileges[strKey] = priv; + + defPrivHash::iterator itr = m_privileges.find(strKey); + m_currentSelectedPriv = &itr->second; + } + else + { + if (m_currentSelectedPriv->m_modified ? + m_currentSelectedPriv->m_newPriv == strPriv : + m_currentSelectedPriv->m_origPriv == strPriv) + { + ev.Skip(); + return; + } + strRole = m_currentSelectedPriv->m_username; + m_currentSelectedPriv->m_modified = true; + m_currentSelectedPriv->m_newPriv = strPriv; + } + + if (!isPresent) + { + int icon; + if (strRole.IsSameAs(wxT("public"), true)) + icon = PGICON_PUBLIC; + else if (strRole.StartsWith(wxT("group "))) + icon = groupFactory.GetIconId(); + else + icon = userFactory.GetIconId(); + long pos = lbPrivileges->GetItemCount(); + + lbPrivileges->InsertItem(pos, strRole, icon); + lbPrivileges->SetItem(pos, 1, strPriv); + } + else + { + long nCount = lbPrivileges->GetItemCount(); + wxListItem info; + + for (int index = 0; index < nCount; index++) + { + wxString strTempRole; + + info.m_itemId = index; + info.m_col = 0; + info.m_mask = wxLIST_MASK_TEXT; + + if (lbPrivileges->GetItem(info)) + strTempRole = info.m_text; + + if (strTempRole == strRole) + { + lbPrivileges->SetItem(index, 1, strPriv); + break; + } + } + } + m_defPrivChanged = true; + + ev.Skip(); +} + + +void ctlDefaultPrivilegesPanel::OnPrivSelChange(wxListEvent &ev) +{ + if (!cbGroups) + return; + if (allPrivileges) + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Disable(); + } + long pos = lbPrivileges->GetSelection(); + if (pos >= 0) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + pos = cbGroups->FindString(name); + if (pos < 0) + { + cbGroups->Append(name); + pos = cbGroups->GetCount() - 1; + } + cbGroups->SetSelection(pos); + + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + privCheckboxes[i * 2]->Enable(); + int index = value.Find(m_privilegeType.m_privileges.GetChar(i)); + if (index >= 0) + { + privCheckboxes[i * 2]->SetValue(true); + privCheckboxes[i * 2 + 1]->SetValue(value.Mid(index + 1, 1) == wxT("*")); + } + else + privCheckboxes[i * 2]->SetValue(false); + } + CheckGrantOpt(i); + } + PrivCheckBoxUpdate(name); + } + btnAddPriv->Enable(); +} + + +void ctlDefaultPrivilegesPanel::Update(wxString strDefPrivs) +{ + unsigned int index = 0; + + lbPrivileges->DeleteAllItems(); + + m_privileges.clear(); + + cbGroups->Clear(); + cbGroups->Append(wxT("public")); + for (; index < m_defSecurityPanel->m_groups.GetCount(); index++) + { + cbGroups->Append(m_defSecurityPanel->m_groups[index]); + } + + if (!strDefPrivs.IsEmpty()) + { + wxString strRole, strPriv; + strDefPrivs.Replace(wxT("\\\""), wxT("\""), true); + strDefPrivs.Replace(wxT("\\\\"), wxT("\\"), true); + + // Removing starting brace '{' and ending brace '}' + strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length() - 1); + + long pos = 0; + + while (pgObject::findUserPrivs(strDefPrivs, strRole, strPriv)) + { + int icon; + if (strRole.IsSameAs(wxT("public"), true)) + icon = PGICON_PUBLIC; + else if (cbGroups->FindString(strRole) != wxNOT_FOUND) + icon = userFactory.GetIconId(); + else if (cbGroups->FindString(wxT("group ") + strRole) != wxNOT_FOUND) + { + icon = groupFactory.GetIconId(); + strRole = wxT("group ") + strRole; + } + else + continue; + + defPrivilege priv; + priv.m_username = strRole; + priv.m_origPriv = strPriv; + priv.m_modified = false; + priv.m_newPriv = wxT(""); + + wxString strKey = strRole; + m_privileges[strKey] = priv; + + pos = lbPrivileges->GetItemCount(); + + lbPrivileges->InsertItem(pos, strRole, icon); + lbPrivileges->SetItem(pos, 1, strPriv); + + strRole = wxT(""); + strPriv = wxT(""); + pos++; + } + } +} + + +wxString ctlDefaultPrivilegesPanel::GetDefaultPrivileges(const wxString &schemaName) +{ + if(!m_defPrivChanged) + return wxT(""); + + wxString strDefPrivs; + defPrivHash::iterator itr = m_privileges.begin(); + + for (; itr != m_privileges.end(); itr++) + { + if(itr->second.m_modified) + { + wxString strRole = itr->second.m_username; + + if (strRole.StartsWith(wxT("group "))) + { + strRole = strRole.Mid(6); + strRole = qtIdent(strRole); + } + else if (strRole != wxT("public")) + strRole = qtIdent(strRole); + + wxString strOrigDefPrivs = itr->second.m_origPriv; + wxString strNewDefPrivs = itr->second.m_newPriv; + + strDefPrivs += pgObject::GetDefaultPrivileges(m_privilegeType.m_privilegesOn.Upper(), m_privilegeType.m_privileges, schemaName, strOrigDefPrivs, strNewDefPrivs, strRole); + } + } + return strDefPrivs; +} + + diff --git a/ctl/ctlListView.cpp b/ctl/ctlListView.cpp new file mode 100644 index 0000000..4f3b76d --- /dev/null +++ b/ctl/ctlListView.cpp @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlListView.cpp - enhanced listview control +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "ctl/ctlListView.h" +#include "utils/misc.h" + + +ctlListView::ctlListView(wxWindow *p, int id, wxPoint pos, wxSize siz, long attr) + : wxListView(p, id, pos, siz, attr | wxLC_REPORT) +{ +} + + +long ctlListView::GetSelection() +{ + return GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); +} + + +wxString ctlListView::GetText(long row, long col) +{ + wxListItem item; + item.SetId(row); + item.SetColumn(col); + item.SetMask(wxLIST_MASK_TEXT); + GetItem(item); + return item.GetText(); +}; + + +void ctlListView::AddColumn(const wxString &text, int size, int format) +{ + if (size == wxLIST_AUTOSIZE || size == wxLIST_AUTOSIZE_USEHEADER) + { + InsertColumn(GetColumnCount(), text, format, size); + } + else + { + InsertColumn(GetColumnCount(), text, format, ConvertDialogToPixels(wxPoint(size, 0)).x); + } +} + + +long ctlListView::AppendItem(int icon, const wxString &val, const wxString &val2, const wxString &val3, const wxString &val4) +{ + long pos = InsertItem(GetItemCount(), val, icon); + if (!val2.IsEmpty()) + SetItem(pos, 1, val2); + if (!val3.IsEmpty()) + SetItem(pos, 2, val3); + if (!val4.IsEmpty()) + SetItem(pos, 3, val4); + + return pos; +} + + +void ctlListView::CreateColumns(wxImageList *images, const wxString &left, const wxString &right, int leftSize) +{ + int rightSize; + if (leftSize < 0) + { +#ifdef __WXMAC__ + leftSize = rightSize = (GetParent()->GetSize().GetWidth() - 20) / 2; +#else + leftSize = rightSize = GetSize().GetWidth() / 2; +#endif + } + else + { + if (leftSize) + leftSize = ConvertDialogToPixels(wxPoint(leftSize, 0)).x; + +#ifdef __WXMAC__ + rightSize = (GetParent()->GetSize().GetWidth() - 20) - leftSize; +#else + rightSize = GetClientSize().GetWidth() - leftSize; +#endif + } + if (!leftSize) + { + InsertColumn(0, left, wxLIST_FORMAT_LEFT, GetClientSize().GetWidth()); + } + else + { + InsertColumn(0, left, wxLIST_FORMAT_LEFT, leftSize); + InsertColumn(1, right, wxLIST_FORMAT_LEFT, rightSize); + } + + if (images) + SetImageList(images, wxIMAGE_LIST_SMALL); +} + + +void ctlListView::CreateColumns(wxImageList *images, const wxString &str1, const wxString &str2, const wxString &str3, int leftSize) +{ + int rightSize; + if (leftSize < 0) + { +#ifdef __WXMAC__ + leftSize = rightSize = (GetParent()->GetSize().GetWidth() - 20) / 2; +#else + leftSize = rightSize = GetSize().GetWidth() / 2; +#endif + } + else + { + if (leftSize) + leftSize = ConvertDialogToPixels(wxPoint(leftSize, 0)).x; + +#ifdef __WXMAC__ + rightSize = (GetParent()->GetSize().GetWidth() - 20) - leftSize; +#else + rightSize = GetClientSize().GetWidth() - leftSize; +#endif + } + if (!leftSize) + { + InsertColumn(0, str1, wxLIST_FORMAT_LEFT, GetClientSize().GetWidth()); + } + else + { + InsertColumn(0, str1, wxLIST_FORMAT_LEFT, leftSize); + InsertColumn(1, str2, wxLIST_FORMAT_LEFT, rightSize / 2); + InsertColumn(2, str3, wxLIST_FORMAT_LEFT, rightSize / 2); + } + + if (images) + SetImageList(images, wxIMAGE_LIST_SMALL); +} diff --git a/ctl/ctlMenuToolbar.cpp b/ctl/ctlMenuToolbar.cpp new file mode 100644 index 0000000..ed35259 --- /dev/null +++ b/ctl/ctlMenuToolbar.cpp @@ -0,0 +1,193 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMenuToolbar.cpp - Menu tool bar +// +// This code is essentially stolen (with the authors permission) from +// Paul Nelson (http://www.pnelsoncomposer.com/) +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlMenuToolbar.h" + +#include +WX_DEFINE_LIST(ctlMenuToolList); + +/* XPM */ +static const char *pulldown_xpm[] = +{ + "16 16 2 1", + ". c Black", + " c None", + /* pixels */ + " ", + " ", + " ", + " ", + " ", + " ", + " ....... ", + " ..... ", + " ... ", + " . ", + " ", + " ", + " ", + " ", + " ", + " " +}; + + +DEFINE_EVENT_TYPE(wxEVT_FILL_MENU) + +////////////////// +// ctlMenuButton +////////////////// + +void ctlMenuButton::Create(wxWindow *window, wxToolBar *toolBar, int ID, wxMenu *menu) +{ + wxBitmap bmpPulldown(pulldown_xpm); + wxSize pulldownSize; + +#ifdef __WXMSW__ + pulldownSize.Set(12, 16); +#else +#ifdef __WXGTK__ + pulldownSize.Set(18, 16); +#else + pulldownSize.Set(10, 16); +#endif +#endif + + m_toolBar = toolBar; + m_menu = menu; + + ((wxBitmapButton *)this)->Create(window, ID, bmpPulldown, wxDefaultPosition, pulldownSize, wxNO_BORDER); + Connect(ID, wxEVT_LEFT_DOWN, wxMouseEventHandler(ctlMenuButton::DoProcessLeftClick) ); +} + + +void ctlMenuButton::DoProcessLeftClick(wxMouseEvent &event) +{ + wxPoint menu_pos; + + if(m_toolBar) + { + wxSize tool_size = m_toolBar->GetToolSize(); + wxSize button_size = GetSize(); + + // ** Assume that pulldown is to the right of a standard toolbar button, + // so, move the x position back one standard toolbar button's width + menu_pos.x = - tool_size.GetWidth(); + menu_pos.y = button_size.GetHeight() / 2 + tool_size.GetHeight() / 2; + +#ifdef __WXMAC__ + wxSize tbar_size = m_toolBar->GetSize(); + wxPoint button_pos = GetPosition(); + int iToolSep = m_toolBar->GetToolSeparation(); + if(iToolSep == 0) iToolSep = 5; + + menu_pos.x += - iToolSep; + menu_pos.y = tbar_size.GetHeight() - button_pos.y / 2; +#endif + } + else + { + wxSize button_size; + button_size = GetSize(); + menu_pos.x = 0; + menu_pos.y = button_size.GetHeight(); + } + + DoPopupMenu(m_menu, menu_pos.x, menu_pos.y); +} + + + +//////////////// +// ctlMenuTool +//////////////// + +ctlMenuTool::ctlMenuTool(wxToolBarToolBase *new_tool, int toolId) +{ + m_tool = new_tool; + m_menu = NULL; + m_toolId = toolId; +} + + +//////////////////// +// ctlMenuToolbar +//////////////////// + +ctlMenuToolbar::ctlMenuToolbar(wxFrame *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name) + : wxToolBar(parent, id, pos, size, style, name) +{ + m_frame = parent; + m_menuTools = NULL; + + Connect(id, wxEVT_LEFT_DOWN, wxMouseEventHandler(ctlMenuToolbar::DoProcessLeftClick) ); +} + + +ctlMenuToolbar::~ctlMenuToolbar() +{ + if(m_menuTools) + delete m_menuTools; +} + +ctlMenuButton *ctlMenuToolbar::AddMenuPulldownTool(int toolId, const wxString &label, const wxString &shortHelpString, wxMenu *popupmenu) +{ + ctlMenuButton *menu_button = new ctlMenuButton(this, toolId, popupmenu); + + AddControl(menu_button); + + return menu_button; +} + + +void ctlMenuToolbar::DoProcessLeftClick(wxMouseEvent &event) +{ + ctlMenuToolList::Node *node = NULL; + ctlMenuTool *menu_tool = NULL; + wxToolBarToolBase *clickTool = FindToolForPosition(event.m_x, event.m_y); + + if(clickTool == NULL || m_menuTools == NULL) + { + event.Skip(); + return; + } + + // search for clickTool in the list of menu tools + node = m_menuTools->GetFirst(); + for( ; node ; node = node->GetNext()) + { + menu_tool = node->GetData(); + if(menu_tool->m_tool == clickTool) + break; + } + + if(node == NULL) + { + event.Skip(); + return; + } + + wxSize tbar_size = GetSize(); + wxPoint menu_pos; + + menu_pos.x = event.m_x - 20; + menu_pos.y = tbar_size.GetHeight() - 2; + + PopupMenu(menu_tool->m_menu, menu_pos); +} diff --git a/ctl/ctlProgressStatusBar.cpp b/ctl/ctlProgressStatusBar.cpp new file mode 100644 index 0000000..24dc4ec --- /dev/null +++ b/ctl/ctlProgressStatusBar.cpp @@ -0,0 +1,202 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlProgressStatusBar.cpp - A status bar with progress indicator +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "ctl/ctlProgressStatusBar.h" + +BEGIN_EVENT_TABLE(ctlProgressStatusBar, wxStatusBar) + EVT_SIZE(ctlProgressStatusBar::OnSize) + EVT_TIMER(wxID_ANY, ctlProgressStatusBar::OnTimer) +END_EVENT_TABLE() + +const unsigned short ctlProgressStatusBar::ms_increment = 100; +const unsigned short ctlProgressStatusBar::ms_progressbar_width = 70; +const unsigned short ctlProgressStatusBar::ms_progressstatus_width = 130; + +ctlProgressStatusBar::ctlProgressStatusBar(wxWindow *parent, bool showProgressInitially, bool autoProgressive, int max) + : wxStatusBar(parent, wxID_ANY), m_progressStopped(!showProgressInitially), + m_autoProgressive(autoProgressive), m_autoValIncrementing(true), + m_hr(0), m_min(0), m_sec(0), m_mil(0), m_val(0) +{ + static int widths[] = { -1, ms_progressbar_width, ms_progressstatus_width}; + int fields = 0; + + if (max <= 0) + max = 100; + + if (m_autoProgressive) + fields = 3; + else + fields = 2; + + m_progress = new wxGauge(this, -1, max); + + wxStatusBar::SetFieldsCount(fields); + wxStatusBar::SetStatusWidths(fields, widths); + + m_timer.SetOwner(this->GetEventHandler()); + + if (!showProgressInitially) + { + m_progressStopped = true; + } + else + { + m_progressStopped = false; + if (m_autoProgressive) + { + m_timer.Start(ms_increment); + + m_hr = 0; + m_min = 0; + m_sec = 0; + m_mil = 0; + } + } + // Dummy event to place the progressbar at right place + wxSizeEvent ev; + this->OnSize(ev); +} + +ctlProgressStatusBar::~ctlProgressStatusBar() +{ + if (m_timer.IsRunning()) + { + m_timer.Stop(); + } +} + + +void ctlProgressStatusBar::OnSize(wxSizeEvent &ev) +{ + // We should have hide the progress bar + if (GetFieldsCount() <= ProgressBar_field) + return; + + wxRect r; + GetFieldRect(ProgressBar_field, r); + + m_progress->SetSize(r.x + 1, r.y + 1, r.width - 2, r.height - 2); + + ev.Skip(); +} + + +void ctlProgressStatusBar::OnTimer(wxTimerEvent &ev) +{ + if (m_progressStopped || !m_autoProgressive) + { + m_timer.Stop(); + return; + } + + m_val = m_progress->GetValue(); + int max = m_progress->GetRange(); + + if (m_val == max) + { + m_val -= 1; + m_autoValIncrementing = false; + } + else if (m_val == 0) + { + m_val = 1; + m_autoValIncrementing = true; + } + else if (m_autoValIncrementing) + { + m_val += 1; + } + else + { + m_val -= 1; + } + + m_progress->SetValue(m_val); + + m_mil += ms_increment; + + if (m_mil >= 1000) + { + m_mil = m_mil - 1000; + m_sec += 1; + + if (m_sec == 60) + { + m_sec = 0; + m_min += 1; + + if (m_min == 60) + { + m_min = 0; + m_hr += 1; + } + } + } + + wxStatusBar::SetStatusText(wxString::Format(_("%d:%02d:%02d.%03d"), m_hr, m_min, m_sec, m_mil), ProgressStatus_field); +} + + +void ctlProgressStatusBar::ShowProgress(bool restart) +{ + if (m_progressStopped) + { + m_progressStopped = false; + + if (!m_timer.IsRunning()) + { + if (restart) + { + m_val = 0; + m_hr = m_min = m_sec = m_mil = 0; + } + + m_progress->SetValue(m_val); + m_timer.Start(ms_increment); + } + } +} + +void ctlProgressStatusBar::StopProgress() +{ + if (m_timer.IsRunning()) + m_timer.Stop(); + + m_progress->SetValue(0); + m_progressStopped = true; +} + +void ctlProgressStatusBar::SetFieldsCount(int number, const int *widths) +{ + m_progress->Show(number > ProgressBar_field); + wxStatusBar::SetFieldsCount( number, widths); + + // Dummy Size event (to reposition the progress bar) + wxSizeEvent ev; + this->OnSize(ev); +} + +void ctlProgressStatusBar::SetStatusWidths(int n, const int widths_field[]) +{ + wxStatusBar::SetStatusWidths( n, widths_field); + + // Dummy Size event (to reposition the progress bar) + wxSizeEvent ev; + this->OnSize(ev); +} \ No newline at end of file diff --git a/ctl/ctlSQLBox.cpp b/ctl/ctlSQLBox.cpp new file mode 100644 index 0000000..8ecebfd --- /dev/null +++ b/ctl/ctlSQLBox.cpp @@ -0,0 +1,1525 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLBox.cpp - SQL syntax highlighting textbox +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "db/pgSet.h" +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgFindReplace.h" +#include "frm/menu.h" +#include "utils/sysProcess.h" +#include +#include + +wxString ctlSQLBox::sqlKeywords; +static const wxString s_leftBrace(_T("([{")); +static const wxString s_rightBrace(_T(")]}")); +static const int s_indicHighlight(20); + +// Additional pl/pgsql keywords we should highlight +wxString plpgsqlKeywords = wxT(" elsif exception exit loop raise record return text while call"); +// +// Additional Text Search keywords we should highlight +wxString ftsKeywords = wxT(" gettoken lextypes headline init lexize"); + +// Additional pgScript keywords we should highlight +wxString pgscriptKeywords = wxT(" assert break columns continue date datetime file go lines ") + wxT(" log print record reference regexrmline string waitfor while"); + +BEGIN_EVENT_TABLE(ctlSQLBox, wxStyledTextCtrl) + EVT_KEY_DOWN(ctlSQLBox::OnKeyDown) + EVT_MENU(MNU_FIND, ctlSQLBox::OnSearchReplace) + EVT_MENU(MNU_AUTOCOMPLETE, ctlSQLBox::OnAutoComplete) + EVT_KILL_FOCUS(ctlSQLBox::OnKillFocus) +// EVT_ERASE_BACKGROUND(ctlSQLBox::OnBackGround) +#ifdef __WXMAC__ + EVT_STC_PAINTED(-1, ctlSQLBox::OnPositionStc) +#else + EVT_STC_UPDATEUI(-1, ctlSQLBox::OnPositionStc) +#endif + EVT_STC_MARGINCLICK(-1, ctlSQLBox::OnMarginClick) + EVT_STC_DOUBLECLICK(-1,ctlSQLBox::OnDoubleClick) + EVT_END_PROCESS(-1, ctlSQLBox::OnEndProcess) +END_EVENT_TABLE() + + +IMPLEMENT_DYNAMIC_CLASS(ctlSQLBox, wxStyledTextCtrl) + + +ctlSQLBox::ctlSQLBox() +{ + m_dlgFindReplace = 0; + m_autoIndent = false; + m_autocompDisabled = false; + process = 0; + processID = 0; +} + + +ctlSQLBox::ctlSQLBox(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) +{ + m_dlgFindReplace = 0; + + m_database = NULL; + + m_autocompDisabled = false; + process = 0; + processID = 0; + + Create(parent, id, pos, size, style); +} +//void ctlSQLBox::OnBackGround(wxEraseEvent &event) { +// wxDC *dc=event.GetDC(); +// dc->SetBackground(wxBrush(GetBackgroundColour(), wxSOLID)); +// dc->Clear(); +// +//} +wxColour ctlSQLBox::SetSQLBoxColourBackground(bool transaction) { + wxColour bgColor = settings->GetSQLBoxColourBackground(); + if (settings->GetSQLBoxUseSystemBackground()) + { + bgColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + } + if (transaction) bgColor = wxColour(241, 241, 186); + StyleSetBackground(wxSTC_STYLE_DEFAULT, bgColor); +// SetBackgroundStyle(wxBG_STYLE_CUSTOM); + return bgColor; +} +void ctlSQLBox::SetQueryBook(ctlAuiNotebook *query_book) +{ + sql_query_book=query_book; +} +void ctlSQLBox::Create(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) +{ + wxStyledTextCtrl::Create(parent, id , pos, size, style); + fix_pos=-1; + sql_query_book =NULL; + // Clear all styles + StyleClearAll(); + m_name=NULL; + // Font + extern sysSettings *settings; + wxFont fntSQLBox = settings->GetSQLFont(); + wxColour bgColor=SetSQLBoxColourBackground(false); + //wxColour bgColor = settings->GetSQLBoxColourBackground(); + //if (settings->GetSQLBoxUseSystemBackground()) + //{ + // bgColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); + //} + + wxColour frColor = settings->GetSQLBoxColourForeground(); + if (settings->GetSQLBoxUseSystemForeground()) + { + frColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + } +// StyleSetBackground(wxSTC_STYLE_DEFAULT, bgColor); + StyleSetForeground(wxSTC_STYLE_DEFAULT, frColor); + StyleSetFont(wxSTC_STYLE_DEFAULT, fntSQLBox); + + SetSelBackground(true, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)); + SetSelForeground(true, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); + + SetCaretForeground(settings->GetSQLColourCaret()); + autoreplace=0; + SetMarginWidth(1, 0); + SetTabWidth(settings->GetIndentSpaces()); + SetUseTabs(!settings->GetSpacesForTabs()); + + // Setup the different highlight colurs + for (int i = 0; i < 34; ++ i ) + { + if (i > 0 && i < 12) + StyleSetForeground(i, settings->GetSQLBoxColour(i)); + else + StyleSetForeground(i, frColor); + StyleSetBackground(i, bgColor); + StyleSetFont(i, fntSQLBox); + } + + // Keywords in uppercase? + + if (settings->GetSQLKeywordsInUppercase()) + StyleSetCase(5, wxSTC_CASE_UPPER); + + // Margin style + StyleSetBackground(wxSTC_STYLE_LINENUMBER, settings->GetSQLMarginBackgroundColour()); + + // Brace maching styles + StyleSetBackground(34, wxColour(0x99, 0xF9, 0xFF)); + StyleSetBackground(35, wxColour(0xFF, 0xCF, 0x27)); + StyleSetFont(34, fntSQLBox); + StyleSetFont(35, fntSQLBox); + + // SQL Lexer and keywords. + if (sqlKeywords.IsEmpty()) + FillKeywords(sqlKeywords); + SetLexer(wxSTC_LEX_SQL); + SetKeyWords(0, sqlKeywords + plpgsqlKeywords + ftsKeywords + pgscriptKeywords); + + // Enable folding + SetMarginSensitive(2, true); + + SetMarginType(2, wxSTC_MARGIN_SYMBOL); // margin 2 for symbols + SetMarginMask(2, wxSTC_MASK_FOLDERS); // set up mask for folding symbols + SetMarginSensitive(2, true); // this one needs to be mouse-aware + SetMarginWidth(2, 16); // set margin 2 16 px wide + + MarkerDefine(wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUSCONNECTED, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUSCONNECTED, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS, *wxWHITE, *wxBLACK); + MarkerDefine(wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS, *wxWHITE, *wxBLACK); + + MarkerDefine(1,wxSTC_MARK_ARROW,*wxBLACK,*wxGREEN); + + SetProperty(wxT("fold"), wxT("1")); + SetFoldFlags(16); + + // Setup accelerators + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_CTRL, (int)'F', MNU_FIND); + entries[1].Set(wxACCEL_CTRL, WXK_SPACE, MNU_AUTOCOMPLETE); + wxAcceleratorTable accel(2, entries); + SetAcceleratorTable(accel); + + // Autocompletion configuration + AutoCompSetSeparator('\t'); + AutoCompSetChooseSingle(true); + AutoCompSetIgnoreCase(true); + AutoCompSetFillUps(wxT(" \t")); + AutoCompSetDropRestOfWord(true); + + SetEOLMode(settings->GetLineEndingType()); +} + +void ctlSQLBox::SetDatabase(pgConn *db) +{ + m_database = db; +} + +void ctlSQLBox::SetChanged(bool b) +{ + if (m_changed != b) + { + m_changed = b; + UpdateTitle(); + } +} + +bool ctlSQLBox::IsChanged() +{ + return m_changed; +} + +void ctlSQLBox::SetOrigin(int origin) +{ + m_origin = origin; +} + +int ctlSQLBox::GetOrigin() +{ + return m_origin; +} + +void ctlSQLBox::SetFilename(wxString &filename) +{ + m_filename = filename; + UpdateTitle(); +} + +wxString ctlSQLBox::GetFilename() +{ + return m_filename; +} + +void ctlSQLBox::SetTitle(wxString &title) +{ + m_title = title; +} + +wxString ctlSQLBox::GetTitle(bool withChangeInd) +{ + wxString title = m_title; + wxString chStr; + if (!withChangeInd) + { + chStr = GetChangeIndicator(); + if (title.EndsWith(chStr)) + title = title.Mid(0, title.Len() - chStr.Len()); + } + return title; +} + +wxString ctlSQLBox::GetChangeIndicator() +{ + if (m_changestr.IsEmpty()) + m_changestr = _("*"); + return m_changestr; +} + +void ctlSQLBox::UpdateTitle() +{ + bool hasCh = false; + wxString chStr = GetChangeIndicator(); + wxString title = GetFilename(); + + if (!title.IsEmpty()) + title = wxFileName::FileName(title).GetFullName(); + else + title = GetTitle(); + + hasCh = title.EndsWith(chStr); + + if (IsChanged() && !hasCh) + title = title + chStr; + else if (!IsChanged() && hasCh) + title = title.Mid(0, title.Len() - chStr.Len()); + + SetTitle(title); +} + +void ctlSQLBox::OnSearchReplace(wxCommandEvent &ev) +{ + if (!m_dlgFindReplace) + { + m_dlgFindReplace = new dlgFindReplace(this); + m_dlgFindReplace->Show(true); + } + else + { + m_dlgFindReplace->Show(true); + m_dlgFindReplace->SetFocus(); + } + + wxString selText = GetSelectedText(); + if (!selText.IsEmpty()) + { + m_dlgFindReplace->SetFindString(selText); + } + + m_dlgFindReplace->FocusSearch(); +} + +bool ctlSQLBox::Find(const wxString &find, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse, bool all) +{ + if (!DoFind(find, wxString(wxEmptyString), false, wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + if (!all) { + wxWindow *w = wxWindow::FindFocus(); + wxMessageBox(_("Reached the end of the document"), _("Find text"), wxICON_EXCLAMATION | wxOK, w); + } + return false; + } + return true; +} + +bool ctlSQLBox::Replace(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse) +{ + if (!DoFind(find, replace, true, wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + wxWindow *w = wxWindow::FindFocus(); + wxMessageBox(_("Reached the end of the document"), _("Replace text"), wxICON_EXCLAMATION | wxOK, w); + return false; + } + return true; +} + +bool ctlSQLBox::ReplaceAll(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps) +{ + // Use DoFind to repeatedly replace text + int count = 0; + int initialPos = GetCurrentPos(); + GotoPos(0); + + while(DoFind(find, replace, true, wholeWord, matchCase, useRegexps, false, false)) + count++; + + GotoPos(initialPos); + + wxString msg; + msg.Printf(wxPLURAL("%d replacement made.", "%d replacements made.", count), count); + wxMessageBox(msg, _("Replace all"), wxOK | wxICON_INFORMATION); + + if (count) + return true; + else + return false; +} + +bool ctlSQLBox::DoFind(const wxString &find, const wxString &replace, bool doReplace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse) +{ + int flags = 0; + int startPos = GetSelectionStart(); + int endPos = GetTextLength(); + + // Setup flags + if (wholeWord) + flags |= wxSTC_FIND_WHOLEWORD; + + if (matchCase) + flags |= wxSTC_FIND_MATCHCASE; + + // Replace the current selection, if there is one and it matches the find param. + wxString current = GetSelectedText(); + if (doReplace) + { + if (useRegexps) + { + CharacterRange cr = RegexFindText(GetSelectionStart(), GetSelectionEnd(), find); + if (GetSelectionStart() == cr.cpMin && GetSelectionEnd() == cr.cpMax) + { + if (cr.cpMin == cr.cpMax) // Must be finding a special char, such as $ (line end) + { + InsertText(cr.cpMax, replace); + SetSelection(cr.cpMax, cr.cpMax + replace.Length()); + SetCurrentPos(cr.cpMax + replace.Length()); + + // Stop if we've got to the end. This is important for the $ + // case where it'll just keep finding the end of the line!! + if ((int)(cr.cpMin + replace.Length()) == GetLength()) + return false; + } + else + { + ReplaceSelection(replace); + SetSelection(startPos, startPos + replace.Length()); + SetCurrentPos(startPos + replace.Length()); + } + } + } + else if ((matchCase && current == find) || (!matchCase && current.Upper() == find.Upper())) + { + ReplaceSelection(replace); + if (!reverse) + { + SetSelection(startPos, startPos + replace.Length()); + SetCurrentPos(startPos + replace.Length()); + } + else + { + SetSelection(startPos + replace.Length(), startPos); + SetCurrentPos(startPos); + } + } + } + + //////////////////////////////////////////////////////////////////////// + // Figure out the starting position for the next search + //////////////////////////////////////////////////////////////////////// + + if (startAtTop) + { + startPos = 0; + endPos = GetTextLength(); + } + else + { + if (reverse) + { + endPos = 0; + startPos = GetCurrentPos(); + } + else + { + endPos = GetTextLength(); + startPos = GetCurrentPos(); + } + } + + size_t selStart = 0, selEnd = 0; + + if (useRegexps) + { + CharacterRange cr = RegexFindText(startPos, endPos, find); + selStart = cr.cpMin; + selEnd = cr.cpMax; + } + else + { + selStart = FindText(startPos, endPos, find, flags); + selEnd = selStart + find.Length(); + } + + if (selStart != (size_t)(-1)) + { + if (reverse) + { + SetCurrentPos(selStart); + SetSelection(selEnd, selStart); + } + else + { + SetCurrentPos(selEnd); + SetSelection(selStart, selEnd); + } + EnsureCaretVisible(); + return true; + } + else + return false; +} +void ctlSQLBox::SetAutoReplaceList(queryMacroList *autorep) { + if (!autorep) { + autoreplace = queryMacroFileProvider::LoadAutoReplace(true); + } else autoreplace=autorep; +} +void ctlSQLBox::SetDefFunction(wxArrayString &name, wxArrayString &def) { + m_name=&name; + m_def=&def; +} + +void ctlSQLBox::OnKeyDown(wxKeyEvent &event) +{ + int pos = GetCurrentPos(); + wxChar ch = GetCharAt(pos - 1); + wxChar nextch = GetCharAt(pos); + int st = GetStyleAt(pos - 1); + if (event.GetKeyCode() == WXK_LEFT) nextch=' '; + if (event.GetKeyCode() == WXK_RIGHT) ch=' '; + + int match; + BraceBadLight(wxSTC_INVALID_POSITION); + // BraceHighlight(-1, -1); + if ((fix_pos!=-1)) { + //GetIndicatorCurrent()==s_indicHighlight + IndicatorClearRange(0,GetTextLength()); + fix_pos=-1; + } + + // Check for braces that aren't in comment styles, + // double quoted styles or single quoted styles + if ((ch == '{' || ch == '}' || + ch == '[' || ch == ']' || + ch == '(' || ch == ')') && + st != 1 && st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos - 1); + if (match != wxSTC_INVALID_POSITION) { + BraceHighlight(pos - 1, match); + } + } + else if ((nextch == '{' || nextch == '}' || + nextch == '[' || nextch == ']' || + nextch == '(' || nextch == ')') && + st != 1 &&st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos); + if (match != wxSTC_INVALID_POSITION) + BraceHighlight(pos, match); + } + while ((pos--) >= 0) + { + ch = GetCharAt(pos); + st = GetStyleAt(pos); + if ((ch == '{' || ch == '}' || + ch == '[' || ch == ']' || + ch == '(' || ch == ')') && + st != 1 &&st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos); + if (match == wxSTC_INVALID_POSITION) + { + BraceBadLight(pos); + } + } + } + + + //wxString autoreplace[]={wxT("se"),wxT("select * from"),wxT("sc"),wxT("select count(*) from"),wxT("si"),wxT("select * from info_oper where"),wxT("sh"),wxT("select * from info_history where")}; +#ifdef __WXGTK__ + event.m_metaDown = false; +#endif + if (m_name) + { + if (((event.GetKeyCode() == '0')&&(event.GetModifiers() == (wxMOD_SHIFT))) + ||event.GetKeyCode() == WXK_UP + ||event.GetKeyCode() == WXK_DOWN) + { + + if (CallTipActive()) CallTipCancel(); + event.Skip(); + return; + + } + + if ((event.GetKeyCode() == '9')&&(event.GetModifiers() == (wxMOD_SHIFT))) + { + int pos = GetCurrentPos() ; + //CallTipSetBackground(*wxYELLOW); + wxString line = GetLine(GetCurrentLine()); + //int max = line.Length() - (GetLineEndPosition(GetCurrentLine()) - GetCurrentPos()) - offset; + int max= PositionFromLine(LineFromPosition(pos)); + int l=0; + wxCharBuffer myStringChars = line.mb_str(); + for (int kk=pos-max-1;kk>=0;kk--) { + //char c=myStringChars.data[kk]; + if ( line[kk].GetValue()<'0') break; + l++; + } + wxString f_name=GetTextRange(pos-l, pos); + int idx=m_name->Index(f_name,false,false); + if (idx!=wxNOT_FOUND) { + calltip=f_name +wxT("(")+m_def->Item(idx)+wxT(")"); + ct_hl=calltip.Find(wxT(",")); + if (ct_hl==wxNOT_FOUND) ct_hl=l; + for (int jj=idx+1;jjCount();jj++) { + if (m_name->Item(jj)== f_name) { + calltip+=wxT("\n")+f_name +wxT("(")+m_def->Item(jj)+wxT(")"); + } else break; + } + + CallTipShow(pos-l,calltip); + CallTipSetHighlight(0,ct_hl); + + + } + //t = GetTextRange(pos-rpl.Length(), pos); + + event.Skip(); + return; + } + } + if (CallTipActive()&&(event.GetKeyCode() == ',' + ||event.GetKeyCode() == WXK_RIGHT + ||event.GetKeyCode() == WXK_LEFT + )) { + //int ptip=CallTipPosAtStart(); + int direction=1; + if (event.GetKeyCode() == WXK_LEFT) + direction=-1; + char c=GetCharAt(GetCurrentPos()); + if (event.GetKeyCode() != ','&&c!=',' ) { + //direction=ct_hl; + } else + { + int pos=ct_hl+direction; + int a=0; + while ( (pos0)) { + c=calltip[pos].GetValue(); + if ((c==',')||(c=='\n')) { + if (direction==1) break; + if (a==1) break; + a++; + ct_hl=pos; + } + pos=pos+direction; + } + //int l=calltip.find(wxT(","),ct_hl+1); + int prev=ct_hl; + if (direction==-1) { + prev=pos; + pos=ct_hl; + } else + { + if (pos==wxNOT_FOUND||(pos==calltip.length())) pos=ct_hl; + } + CallTipSetHighlight(prev,pos); + + ct_hl=pos; + } + } + // Get the line ending type + wxString lineEnd; + switch (GetEOLMode()) + { + case wxSTC_EOL_LF: + lineEnd = wxT("\n"); + break; + case wxSTC_EOL_CRLF: + lineEnd = wxT("\r\n"); + break; + case wxSTC_EOL_CR: + lineEnd = wxT("\r"); + break; + } + // AutoReplace + if (event.GetKeyCode() == ' ') { + //int start = GetSelectionStart(); + //int column = GetColumn(start); + //int curLineNum = GetCurrentLine(); + int pos = GetCurrentPos(); + //wxString line = GetLine(GetCurrentLine()); + wxString t; + wxString wc; + //char c; + bool f; + wxString rpl = wxT(""); + wxString rpl2 = wxT(""); + for (int k=0;autoreplace!=0&&kCount();k=k+1 ) { + f=false; + queryMacroItem *mi=autoreplace->GetItem(k); + rpl = mi->GetName(); + //rpl2 =ss[k+1]; + //rpl=mi->GetName(); + rpl2 =mi->GetQuery(); + if ((pos-rpl.Length())==0) { + t = GetTextRange(pos-rpl.Length(), pos); + f=true; + } else {t = GetTextRange(pos-rpl.Length()-1, pos);} + //wc = GetTextRange(pos-rpl.Length()-1, pos-rpl.Length()-1); + wxChar c = t.GetChar(0); + if (!((c >= '0' && c <= '9')) && + !(c >= 'a' && c <= 'z') && + !(c >= 'A' && c <= 'Z') && + !(c == '_')) + { + f=true; + } + + + if (t.EndsWith(rpl)&&f) + { + //SetTargetStart(pos-2); + //SetTargetEnd(pos); + //ReplaceTarget(rpl2); + + SetSelection(pos-rpl.Length(),pos); + // Lose any selected text. + ReplaceSelection(wxEmptyString); + // Insert a replacement \n (or whatever), and the indent at the insertion point. + InsertText(GetCurrentPos(), rpl2); + // Now, reset the position, and clear the selection + SetCurrentPos(GetCurrentPos() + rpl2.Length()); + SetSelection(GetCurrentPos(), GetCurrentPos()); + + } + } + } + // Block comment/uncomment + if (event.GetKeyCode() == 'K') + { + // Comment (Ctrl+k) + if (event.GetModifiers() == wxMOD_CONTROL) + { + if (BlockComment(false)) + return; + } + // Uncomment (Ctrl+Shift+K) + else if (event.GetModifiers() == (wxMOD_CONTROL | wxMOD_SHIFT)) + { + if (BlockComment(true)) + return; + } + } + + // Autoindent + if (m_autoIndent && event.GetKeyCode() == WXK_RETURN) + { + wxString indent, line; + line = GetLine(GetCurrentLine()); + + // Get the offset for the current line - basically, whether + // or not it ends with a \r\n, \n or \r, and if so, the length + int offset = 0; + if (line.EndsWith(wxT("\r\n"))) + offset = 2; + else if (line.EndsWith(wxT("\n"))) + offset = 1; + else if (line.EndsWith(wxT("\r"))) + offset = 1; + + // Get the indent. This is every leading space or tab on the + // line, up until the current cursor position. + int x = 0; + int max = line.Length() - (GetLineEndPosition(GetCurrentLine()) - GetCurrentPos()) - offset; + if(line != wxEmptyString) + { + while ((x < max) &&(line[x].GetValue() == '\t' || line[x].GetValue() == ' ')) { + wxChar ccc=line[x]; + indent += line[x++]; + } + } + + // Select any indent in front of the cursor to be removed. If + // the cursor is positioned after any non-indent characters, + // we don't remove anything. If there is already some selected, + // don't select anything new at all. + if (indent.Length() != 0 && + (unsigned int)GetCurrentPos() <= ((GetLineEndPosition(GetCurrentLine()) - line.Length()) + indent.Length() + offset) && + GetSelectedText() == wxEmptyString) + SetSelection(GetLineEndPosition(GetCurrentLine()) - line.Length() + offset, GetLineEndPosition(GetCurrentLine()) - line.Length() + indent.Length() + offset); + + // Lose any selected text. + ReplaceSelection(wxEmptyString); + + // Insert a replacement \n (or whatever), and the indent at the insertion point. + InsertText(GetCurrentPos(), lineEnd + indent); + + // Now, reset the position, and clear the selection + SetCurrentPos(GetCurrentPos() + indent.Length() + lineEnd.Length()); + SetSelection(GetCurrentPos(), GetCurrentPos()); + } + else if (m_dlgFindReplace && event.GetKeyCode() == WXK_F3) + { + m_dlgFindReplace->FindNext(); + } + else + event.Skip(); +} + +bool ctlSQLBox::BlockComment(bool uncomment) +{ + wxString lineEnd; + switch (GetEOLMode()) + { + case wxSTC_EOL_LF: + lineEnd = wxT("\n"); + break; + case wxSTC_EOL_CRLF: + lineEnd = wxT("\r\n"); + break; + case wxSTC_EOL_CR: + lineEnd = wxT("\r"); + break; + } + + // Save the start position + const wxString comment = wxT("-- "); + int start = GetSelectionStart(); + + if (!GetSelectedText().IsEmpty()) + { + wxString selection = GetSelectedText(); + if (!uncomment) + { + selection.Replace(lineEnd, lineEnd + comment); + selection.Prepend(comment); + if (selection.EndsWith(comment)) + selection = selection.Left(selection.Length() - comment.Length()); + } + else + { + selection.Replace(lineEnd + comment, lineEnd); + if (selection.StartsWith(comment)) + selection = selection.Right(selection.Length() - comment.Length()); + } + ReplaceSelection(selection); + SetSelection(start, start + selection.Length()); + } + else + { + // No text selection - (un)comment the current line + int column = GetColumn(start); + int curLineNum = GetCurrentLine(); + int pos = PositionFromLine(curLineNum); + + if (!uncomment) + { + InsertText(pos, comment); + } + else + { + wxString t = GetTextRange(pos, pos + comment.Length()); + if (t == comment) + { + // The line starts with a comment, so we remove it + SetTargetStart(pos); + SetTargetEnd(pos + comment.Length()); + ReplaceTarget(wxT("")); + } + else + { + // The line doesn't start with a comment, do nothing + return false; + } + } + + if (GetLineCount() > curLineNum) + { + wxString nextLine = GetLine(curLineNum + 1); + if (nextLine.EndsWith(lineEnd)) + nextLine = nextLine.Left(nextLine.Length() - lineEnd.Length()); + + int nextColumn = (nextLine.Length() < (unsigned int)column ? nextLine.Length() : column); + GotoPos(PositionFromLine(curLineNum + 1) + nextColumn); + } + } + + return true; +} + +void ctlSQLBox::OnKillFocus(wxFocusEvent &event) +{ + AutoCompCancel(); + event.Skip(); +} + +void ctlSQLBox::UpdateLineNumber() +{ + bool showlinenumber; + + settings->Read(wxT("frmQuery/ShowLineNumber"), &showlinenumber, false); + if (showlinenumber) + { + long int width = TextWidth(wxSTC_STYLE_LINENUMBER, + wxT(" ") + NumToStr((long int)GetLineCount()) + wxT(" ")); + if (width != GetMarginWidth(0)) + { + SetMarginWidth(0, width); + Update(); + } + } + else + { + SetMarginWidth(0, 0); + } +} + +void ctlSQLBox::OnEndProcess(wxProcessEvent &ev) +{ + if (process) + { + processErrorOutput = process->ReadErrorStream(); + processOutput += process->ReadInputStream(); + processExitCode = ev.GetExitCode(); + delete process; + process = 0; + processID = 0; + } +} + +wxString ctlSQLBox::ExternalFormat() +{ + wxString msg; + processOutput = wxEmptyString; + + bool isSelected = true; + wxString processInput = GetSelectedText(); + if (processInput.IsEmpty()) + { + processInput = GetText(); + isSelected = false; + } + if (processInput.IsEmpty()) + return _("Nothing to format."); + + wxString formatCmd = settings->GetExtFormatCmd(); + if (formatCmd.IsEmpty()) + { + return _("You need to setup a formatting command"); + } + + if (process) + { + delete process; + process = NULL; + processID = 0; + } + processOutput = wxEmptyString; + processErrorOutput = wxEmptyString; + processExitCode = 0; + + process = new sysProcess(this, wxConvUTF8); + processID = wxExecute(formatCmd, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, process); + if (!processID) + { + delete process; + process = NULL; + processID = 0; + msg = _("Couldn't run formatting command: ") + formatCmd; + return msg; + } + process->WriteOutputStream(processInput); + process->CloseOutput(); + + int timeoutMs = settings->GetExtFormatTimeout(); + int timeoutStepMs = 100; + int i = 0; + while (process && i * timeoutStepMs < timeoutMs) + { + wxSafeYield(); + if (process) + processOutput += process->ReadInputStream(); + wxSafeYield(); + wxMilliSleep(timeoutStepMs); + i++; + } + + if (process) + { + AbortProcess(); + return wxString::Format(_("Formatting command did not respond in %d ms"), timeoutMs); + } + + if (processExitCode != 0) + { + processErrorOutput.Replace(wxT("\n"), wxT(" ")); + msg = wxString::Format(_("Error %d: "), processExitCode) + processErrorOutput; + return msg; + } + else if (processOutput.Trim().IsEmpty()) + { + return _("Formatting command error: Output is empty."); + } + + if (isSelected) + ReplaceSelection(processOutput); + else + SetText(processOutput); + + return _("Formatting complete."); +} + +void ctlSQLBox::AbortProcess() +{ + if (process && processID) + { +#ifdef __WXMSW__ + // SIGTERM is useless for Windows console apps + wxKill(processID, wxSIGKILL, NULL, wxKILL_CHILDREN); +#else + wxKill(processID, wxSIGTERM, NULL, wxKILL_CHILDREN); +#endif + processID = 0; + } +} +long ctlSQLBox::SelectQuery(int startposition) +{ + int pos = GetCurrentPos(); + wxChar ch = GetCharAt(pos - 1); + wxChar nextch = GetCharAt(pos); + int st = GetStyleAt(pos - 1); + int endPos = GetTextLength(); + int match; + int pend=endPos; + int pstart=0; + + if ((ch == ';')) { + pend=pos; + pos=pos-1; + } else + { + while (pos= 0) + { + ch = GetCharAt(pos); + st = GetStyleAt(pos) & 0x1F; + if ((ch == ';') && + st != 2 && st != 6 && st != 7) + { + //pstart=pos+1; + break; + } + if (ch>' ') pstart=pos; + int i=IsDBCSLeadByte(ch)? 2 : 1; + pos=pos-i; + + } + if (startposition<0) SetSelection(pstart,pend); + return (pstart <<16)+pend; + +} +void ctlSQLBox::HighlightBrace(int lb, int rb) { + SetIndicatorCurrent(s_indicHighlight); + { + //SetCaretForeground(wxColour(255, 0, 0)); + //SetCaretWidth(caretWidth + 1); + + IndicatorSetForeground(s_indicHighlight, wxColour(80, 236, 120)); + IndicatorSetStyle(s_indicHighlight, wxSTC_INDIC_ROUNDBOX); +#ifndef wxHAVE_RAW_BITMAP + IndicatorSetUnder(s_indicHighlight, true); +#endif + SetIndicatorCurrent(s_indicHighlight); + IndicatorFillRange(lb, 1); + IndicatorFillRange(rb, 1); + return; + } + +} +void ctlSQLBox::OnDoubleClick(wxStyledTextEvent &event) +{ + fix_pos = GetCurrentPos(); + wxString find = GetSelectedText(); + int flags =0; + flags |= wxSTC_FIND_WHOLEWORD; + flags |= wxSTC_FIND_MATCHCASE; + + size_t selStart = 0, selEnd = 0; + if (!find.IsEmpty()) + { + int startPos = GetSelectionStart(); + int endPos = GetTextLength(); + + IndicatorSetForeground(s_indicHighlight, wxColour(246, 185, 100)); + IndicatorSetAlpha(s_indicHighlight,50); + IndicatorSetStyle(s_indicHighlight, wxSTC_INDIC_ROUNDBOX); +#ifndef wxHAVE_RAW_BITMAP + IndicatorSetUnder(s_indicHighlight, true); +#endif + SetIndicatorCurrent(s_indicHighlight); + startPos=0; + while ((selStart != (size_t)(-1))) { + + selStart = FindText(startPos, endPos, find, flags); + selEnd = selStart + find.Length(); + if ((selStart != (size_t)(-1))) { + IndicatorFillRange(selStart, find.Length()); + //IndicatorFillRange(rb, 1); + startPos=selEnd; + } + + } + } +} +void ctlSQLBox::OnPositionStc(wxStyledTextEvent &event) +{ + int pos = GetCurrentPos(); + wxChar ch = GetCharAt(pos - 1); + wxChar nextch = GetCharAt(pos); + int st = GetStyleAt(pos - 1); + int match; + // Line numbers + // Ensure we don't recurse through any paint handlers on Mac +#ifdef __WXMAC__ + Freeze(); +#endif + UpdateLineNumber(); +#ifdef __WXMAC__ + Thaw(); +#endif + int startsql=0; + // Roll back through the doc and highlight any unmatched braces + int tmp=pos; + list_table.Clear(); + while ((pos--) >= 0) + { + ch = GetCharAt(pos); + st = GetStyleAt(pos); + if (st != 1 &&st != 2 && st != 6 && st != 7 &&(ch==';')&&startsql==0) startsql=pos+1; + if ((ch == '{' || ch == '}' || + ch == '[' || ch == ']' || + ch == '(' || ch == ')') && + st != 1 &&st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos); + if (match == wxSTC_INVALID_POSITION) + { + event.Skip(); + return; + } + } + } + // ïîëó÷åíèå ïîçèöè select + pos=tmp; + wxString keyword; + wxString ident; + while ((pos--) >= 0) + { + ch = GetCharAt(pos); + st = GetStyleAt(pos); + if (st==5) {ident.append(ch);} else + { + if ((!ident.IsEmpty())) { + + if (ident.CmpNoCase(wxT("tceles"))==0) { + startsql=pos+1; + break; + } + ident.Clear(); + } + + } + if (st != 1 &&st != 2 && st != 6 && st != 7 &&(ch==';')&&startsql==0) startsql=pos+1; + if (( ch == '}' || + ch == ']' || + ch == ')') && + st != 1 &&st != 2 && st != 6 && st != 7) + { + match = BraceMatch(pos); + if (match == wxSTC_INVALID_POSITION || (match>=pos)) + { + event.Skip(); + return; + } else + { + pos=match-1; + } + } + } + + + int endtext= GetLength(); + bool isfrom=false; + pos=startsql; + + ident.Clear(); + while (pospos) pos=match; + ident.Clear(); + } + } + if (st != 1 &&st != 2 && st != 6 && st != 7 &&(ch==';')) break; + if ((st==10||st==0)&&(!ident.IsEmpty())) { + if (isfrom) { + list_table.Append(wxT(" ")); + list_table.Append(ident); + if (ch==',') list_table.Append(ch); + //if (!name.IsEmpty()) alias=ident; else name=ident; + } + ident.Clear(); + } + pos++; + + } + if (isfrom&&(!ident.IsEmpty())) {list_table.Append(wxT(" "));list_table.Append(ident);}; + + + event.Skip(); +} + + +void ctlSQLBox::OnMarginClick(wxStyledTextEvent &event) +{ + if (event.GetMargin() == 2) + ToggleFold(LineFromPosition(event.GetPosition())); + + event.Skip(); +} +void ctlSQLBox::Copy() { + wxString selText = GetSelectedText(); + if (!selText.IsEmpty()) + { + wxColor frColor[40]; + wxString str; + wxColour frc = settings->GetSQLBoxColourForeground(); + if (settings->GetSQLBoxUseSystemForeground()) + { + frc = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT); + } + + for (int i = 0; i < 34; ++ i ) + { + frColor[i]=StyleGetForeground(i); + if (i > 0 && i < 12) + //StyleSetForeground(i, settings->GetSQLBoxColour(i)); + frColor[i]=StyleGetForeground(i); + else + frColor[i]=frc; + + //StyleSetBackground(i, bgColor); + //StyleSetFont(i, fntSQLBox); + } + //

+ int endp=GetSelectionEnd(); + int startp=GetSelectionStart(); + wxString prevColor=wxEmptyString; + wxString tColor; + wxFont fntSQLBox = settings->GetSQLFont(); + wxString fontName = fntSQLBox.GetFaceName(); + wxString sz; + sz.Printf("%d",fntSQLBox.GetPixelSize().GetHeight() ); + + str=wxT("
"); + int k=0; + int l=1; + while (startp"); + prevColor=tColor; + } + //str.append(str[k].GetValue()); + l=1; + if (!selText[k].IsAscii()) l++; + int s=0; + if (selText[k].GetValue()==9) s=5; + if (selText[k].GetValue()==32) s=1; + if (s>0) for (int tt=0;tt"); + startp=startp+l; + k++; + } + str=str+wxT("
"); + + + + if (wxTheClipboard->Open()) + { + wxDataObjectComposite* dataobj = new wxDataObjectComposite(); + dataobj->Add(new wxTextDataObject(selText)); + dataobj->Add(new wxHTMLDataObject(str)); + wxTheClipboard->SetData(dataobj); + wxTheClipboard->Close(); + } + + } else wxStyledTextCtrl::Copy(); + + + + + } + +extern "C" char *tab_complete(const char *allstr, const int startptr, const int endptr, void *dbptr); +void ctlSQLBox::OnAutoComplete(wxCommandEvent &rev) +{ + if (GetReadOnly()) + return; + if (m_database == NULL) + return; + if (m_autocompDisabled) + return; + + wxString what = GetCurLine().Left(GetCurrentPos() - PositionFromLine(GetCurrentLine()));; + int spaceidx = what.Find(' ', true); + + char *tab_ret; + if (spaceidx == -1) + tab_ret = tab_complete(what.mb_str(wxConvUTF8), 0, what.Len() + 1, m_database); + else + tab_ret = tab_complete(what.mb_str(wxConvUTF8), spaceidx + 1, what.Len() + 1, m_database); + wxString wxRet; + if (tab_ret == NULL || tab_ret[0] == '\0'){ + int l=0; + for (int kk=what.Len()-2;kk>=0;kk--) { + //char c=myStringChars.data[kk]; + if ( what[kk]<'0') break; + l++; + } + wxString f_name; + if (l>0) { + wxString alias=what.substr(what.Len()-1-l,l); + wxString lst=list_table; + wxString table; + //alias.Replace(wxT("."), wxT("")); + lst.Replace(wxT("\""), wxT("")); + wxStringTokenizer tokenizer(lst, wxT(" ,")); + wxString prev; + bool found=false; + int p=0; + while ( tokenizer.HasMoreTokens() ) + { + wxString token = tokenizer.GetNextToken(); + if (token.IsEmpty()) {p=0; continue;} + token=token.AfterLast('.'); + found=token.CmpNoCase(alias)==0; + if (tokenizer.GetLastDelimiter()==' '&&found) { + if (p==1) table=prev; else table=token; + break; + } + if ((tokenizer.GetLastDelimiter()==',')&&found) { + if (p==1) table=prev; else table=token; + break; + } + if (found) {if (p==1) table=prev; else table=token; break;} + prev=token; + p++; + } + if (found) { + wxString sql=wxT("select string_agg(a.attname,E'\t') from pg_attribute a where a.attrelid = (select oid from pg_class p where relname=") +qtConnString(table) + +wxT(") and a.attisdropped IS FALSE and a.attnum>=0 order by 1"); + //pgSet *res = m_database->ExecuteSet(sql); + prev= m_database->ExecuteScalar(sql); + AutoCompShow(0, prev); + return; + } + //list_table.Find(alias + } + l=0; + for (int kk=what.Len()-1;kk>=0;kk--) { + //char c=myStringChars.data[kk]; + if ( what[kk]<'0') break; + l++; + } + if (l==0) return; + f_name=what.Right(l); + what=f_name; + size_t i, + lo = 0, + hi = m_name->Count(); + int res; + while ( lo < hi ) { + i = (lo + hi)/2; + if (m_name->Item(i).StartsWith(f_name)) break; + res= f_name.CmpNoCase(m_name->Item(i)); + //res = wxStrcmp(sz, m_pItems[i]); + if ( res < 0 ) + hi = i; + else if ( res > 0 ) + lo = i + 1; + else + { break; }// i ok + } + if (lo >= hi) return; + int k=i; + while ( k>=0&&m_name->Item(k).StartsWith(f_name) ) k--; + k++; + wxString prev; + while ( (kGetCount())&&m_name->Item(k).StartsWith(f_name) ) + { + if (prev!=m_name->Item(k)) wxRet+=m_name->Item(k)+wxT("\t"); + prev=m_name->Item(k); + k++; + }; + spaceidx = what.Len()-1; + spaceidx = -1; + //return; /* No autocomplete available for this string */ + } else { + wxRet = wxString(tab_ret, wxConvUTF8); + free(tab_ret); + } + // Switch to the generic list control. Native doesn't play well with + // autocomplete on Mac. +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + + if (spaceidx == -1) + AutoCompShow(what.Len(), wxRet); + else + AutoCompShow(what.Len() - spaceidx - 1, wxRet); + + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif +} + + +ctlSQLBox::~ctlSQLBox() +{ + if (m_dlgFindReplace) + { + m_dlgFindReplace->Destroy(); + m_dlgFindReplace = 0; + } + AbortProcess(); +} + + +/* + * Callback function from tab-complete.c, bridging the gap between C++ and C. + * Execute a query using the C++ APIs, returning it as a tab separated + * "char*-string" + * The query is expected to return only one column, and will have an ORDER BY + * clause for this column added automatically. + */ +extern "C" +char *pg_query_to_single_ordered_string(char *query, void *dbptr) +{ + pgConn *db = (pgConn *)dbptr; + pgSet *res = db->ExecuteSet(wxString(query, wxConvUTF8) + wxT(" ORDER BY 1")); + if (!res) + return NULL; + + wxString ret = wxString(); + wxString tmp; + + while (!res->Eof()) + { + tmp = res->GetVal(0); + if (tmp.Mid(tmp.Length() - 1) == wxT(".")) + ret += tmp + wxT("\t"); + else + ret += tmp + wxT(" \t"); + + res->MoveNext(); + } + + if(res) + { + delete res; + res = NULL; + } + ret.Trim(); + // Trims both space and tab, but we want to keep the space! + if (ret.Length() > 0) + ret += wxT(" "); + + return strdup(ret.mb_str(wxConvUTF8)); +} + + +// Find some text in the document. +CharacterRange ctlSQLBox::RegexFindText(int minPos, int maxPos, const wxString &text) +{ + TextToFind ft; + ft.chrg.cpMin = minPos; + ft.chrg.cpMax = maxPos; + wxWX2MBbuf buf = text.mb_str(wxConvUTF8); + ft.lpstrText = (char *)(const char *)buf; + +//íå êîìïèëèðîâàëàñü ñ wx 2.8.12 + if (SendMsg(2150, wxSTC_FIND_REGEXP, (long)&ft) == -1) + { + ft.chrgText.cpMin = -1; + ft.chrgText.cpMax = -1; + } + + return ft.chrgText; +} diff --git a/ctl/ctlSQLGrid.cpp b/ctl/ctlSQLGrid.cpp new file mode 100644 index 0000000..d2338f1 --- /dev/null +++ b/ctl/ctlSQLGrid.cpp @@ -0,0 +1,772 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLGrid.cpp - SQL Query result window +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include "db/pgConn.h" +#include "ctl/ctlSQLGrid.h" +#include "utils/sysSettings.h" +#include "frm/frmExport.h" +#include +#include "ctl/ctlSQLResult.h" + +#define EXTRAEXTENT_HEIGHT 6 +#define EXTRAEXTENT_WIDTH 6 + +BEGIN_EVENT_TABLE(ctlSQLGrid, wxGrid) + EVT_MOUSEWHEEL(ctlSQLGrid::OnMouseWheel) + EVT_GRID_COL_SIZE(ctlSQLGrid::OnGridColSize) + EVT_GRID_LABEL_LEFT_CLICK(ctlSQLGrid::OnLabelClick) + EVT_GRID_CELL_RIGHT_CLICK( ctlSQLGrid::OnCellRightClick) + EVT_PAINT( ctlSQLGrid::OnPaint ) +END_EVENT_TABLE() + +IMPLEMENT_DYNAMIC_CLASS(ctlSQLGrid, wxGrid) + +ctlSQLGrid::ctlSQLGrid() +{ +} + +ctlSQLGrid::ctlSQLGrid(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) + : wxGrid(parent, id, pos, size, wxWANTS_CHARS | wxVSCROLL | wxHSCROLL) +{ + // Set cells font + wxFont fntCells(settings->GetSQLFont()); + SetDefaultCellFont(fntCells); + // Set labels font + wxFont fntLabel(settings->GetSystemFont()); + fntLabel.SetWeight(wxBOLD); + SetLabelFont(fntLabel); + SetColLabelAlignment(wxALIGN_LEFT, wxALIGN_CENTER); + SetRowLabelSize(50); + SetDefaultRowSize(fntCells.GetPointSize() * 2 + 2); + SetColLabelSize(fntLabel.GetPointSize() * 4); + SetDefaultCellOverflow(false); + //SetDefaultRenderer(new wxGridCellAutoWrapStringRenderer); + SetDefaultRenderer(new CursorCellRenderer); + //SetUseNativeColLabels(true); + //UseNativeColHeader(true); + grp=NULL; + isSort=false; + Connect(wxID_ANY, wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEventHandler(ctlSQLGrid::OnLabelDoubleClick)); +} +#include "wx/renderer.h" +#include "wx/headerctrl.h" + +void ctlSQLGrid::DrawColLabel( wxDC& dc, int col ) { + wxGrid::DrawColLabel(dc,col); + if (!IsSort()) return; + int colLeft = GetColLeft(col); + + wxRect rect(colLeft, 0, GetColWidth(col), m_colLabelHeight); + sqlResultTable *t=(sqlResultTable *)GetTable(); + + wxHeaderSortIconType sortArrow=t->getSortColumn(col)!=0 + ? t->getSortColumn(col)>0 + ? wxHDR_SORT_ICON_UP + : wxHDR_SORT_ICON_DOWN + : wxHDR_SORT_ICON_NONE; + + if (sortArrow != wxHDR_SORT_ICON_NONE ) + { + wxRect ar = rect; + + // make a rect for the arrow + ar.height = 4; + ar.width = 8; + ar.y += (rect.height - ar.height)/2; + ar.x = ar.x + rect.width - 3*ar.width/2; + int arrowSpace = 0; + arrowSpace = 3*ar.width/2; // space to preserve when drawing the label + wxPoint triPt[3]; + if ( sortArrow & wxHDR_SORT_ICON_UP ) + { + triPt[0].x = ar.width / 2; + triPt[0].y = 0; + triPt[1].x = ar.width; + triPt[1].y = ar.height; + triPt[2].x = 0; + triPt[2].y = ar.height; + } + else + { + triPt[0].x = 0; + triPt[0].y = 0; + triPt[1].x = ar.width; + triPt[1].y = 0; + triPt[2].x = ar.width / 2; + triPt[2].y = ar.height; + } + + wxColour c; + + c = wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW); + for (int k=0;kcolsortnumber[k]; + if (cl!=-1) { + if (cl==col) { + if (k==0) c=wxColor(155,17,48); // red + if (k==1) c=wxColor(255,255,0); // yellow + if (k==2) c=wxColor(34,199,76); // green + if (k==3) c=wxColor(12,38,160); // blue + } + } else break; + } + wxDCPenChanger setPen(dc, c); + wxDCBrushChanger setBrush(dc, c); + + wxDCClipper clip(dc, rect); + dc.DrawPolygon( 3, triPt, ar.x, ar.y); + } + + //wxRendererNative::Get().DrawHeaderButton + // (m_colWindow, + // //GetColLabelWindow(), + // dc, + // rect, + // 0, + // IsSortingBy(col) + // ? IsSortOrderAscending() + // ? wxHDR_SORT_ICON_UP + // : wxHDR_SORT_ICON_DOWN + // : wxHDR_SORT_ICON_NONE + // ); + + +} +void ctlSQLGrid::OnGridColSize(wxGridSizeEvent &event) +{ + // Save key="index:label", value=size + int col = event.GetRowOrCol(); + colSizes[GetColKeyValue(col)] = GetColSize(col); +} +void ctlSQLGrid::OnCopy(wxCommandEvent &ev) +{ + Copy(false); +} + +void ctlSQLGrid::OnMouseWheel(wxMouseEvent &event) +{ + if (event.ControlDown() || event.CmdDown()) + { + wxFont fontlabel = GetLabelFont(); + wxFont fontcells = GetDefaultCellFont(); + if (event.GetWheelRotation() > 0) + { + fontlabel.SetPointSize(fontlabel.GetPointSize() - 1); + fontcells.SetPointSize(fontcells.GetPointSize() - 1); + } + else + { + fontlabel.SetPointSize(fontlabel.GetPointSize() + 1); + fontcells.SetPointSize(fontcells.GetPointSize() + 1); + } + SetLabelFont(fontlabel); + SetDefaultCellFont(fontcells); + SetColLabelSize(fontlabel.GetPointSize() * 4); + SetDefaultRowSize(fontcells.GetPointSize() * 2); + for (int index = 0; index < GetNumberCols(); index++) + SetColSize(index, -1); + ForceRefresh(); + } + else + event.Skip(); +} + +wxString ctlSQLGrid::GetExportLine(int row) +{ + return GetExportLine(row, 0, GetNumberCols() - 1); +} + + +wxString ctlSQLGrid::GetExportLine(int row, int col1, int col2) +{ + wxArrayInt cols; + wxString str; + int i; + + if (col2 < col1) + return str; + + cols.Alloc(col2 - col1 + 1); + for (i = col1; i <= col2; i++) + { + cols.Add(i); + } + + return GetExportLine(row, cols); +} + +wxString ctlSQLGrid::GetExportLine(int row, wxArrayInt cols) +{ + wxString str; + unsigned int col; + + if (GetNumberCols() == 0 || GetRowSize(row)==0) + return str; + wxString colsep=settings->GetCopyColSeparator(); + if (generatesql) colsep=wxT(","); + wxString qtsimbol=settings->GetCopyQuoteChar(); + if (generatesql) qtsimbol=wxT("'"); + wxString head=wxT("insert into tbl("); + for (col = 0 ; col < cols.Count() ; col++) + { + if (col > 0) + str.Append(colsep); + if (col > 0) head.Append(colsep); + head=head+GetColumnName(cols[col]); + wxString text = GetCellValue(row, cols[col]); + bool needQuote = false; + if (settings->GetCopyQuoting() == 1) + { + needQuote = IsColText(cols[col]); + } + else if (settings->GetCopyQuoting() == 2) + /* Quote everything */ + needQuote = true; + if (text.Length()==0&&generatesql) {needQuote = false;} else + if (generatesql) needQuote = IsColText(cols[col]); + if (needQuote) + str.Append(qtsimbol); + + if (generatesql) { + if (text.Length()!=0) { + text.Replace(wxT("'"),wxT("''")); + } else text=wxT("null"); + + } + str.Append(text); + if (needQuote) + str.Append(qtsimbol); + } + if (generatesql) str=head+wxT(") values (")+str+");"; + return str; +} + +wxString ctlSQLGrid::GetColumnName(int colNum) +{ + wxString columnName = GetColLabelValue(colNum); + columnName = columnName.Left(columnName.find(wxT("\n"))); + return columnName; +} + +void ctlSQLGrid::AppendColumnHeader(wxString &str, int start, int end) +{ + size_t i, arrsize; + arrsize = (end - start + 1); + wxArrayInt columns; + + for(i = 0; i < arrsize; i++) + { + columns.Add(start + i); + } + + AppendColumnHeader(str, columns); +} + +void ctlSQLGrid::AppendColumnHeader(wxString &str, wxArrayInt columns) +{ + if(settings->GetColumnNames()&&!generatesql) + { + bool CopyQuoting = (settings->GetCopyQuoting() == 1 || settings->GetCopyQuoting() == 2); + size_t i; + + for(i = 0; i < columns.Count() ; i++) + { + long columnPos = columns.Item(i); + if(i > 0) + str.Append(settings->GetCopyColSeparator()); + + if(CopyQuoting) + str.Append(settings->GetCopyQuoteChar()); + str.Append(GetColumnName(columnPos)); + if(CopyQuoting) + str.Append(settings->GetCopyQuoteChar()); + + } + str.Append(END_OF_LINE); + } +} + +int ctlSQLGrid::Copy(bool gensql) +{ + wxString str,tmp; + int copied = 0; + size_t i; + generatesql=gensql; + + + if (GetSelectedRows().GetCount()) + { + AppendColumnHeader(str, 0, (GetNumberCols() - 1)); + + wxArrayInt rows = GetSelectedRows(); + + for (i = 0 ; i < rows.GetCount() ; i++) + { + tmp=GetExportLine(rows.Item(i)); + if (tmp.IsEmpty()) continue; + str.Append(tmp); + if (rows.GetCount() > 1) + str.Append(END_OF_LINE); + } + + copied = rows.GetCount(); + } + else if (GetSelectedCols().GetCount()) + { + wxArrayInt cols = GetSelectedCols(); + size_t numRows = GetNumberRows(); + + AppendColumnHeader(str, cols); + + for (i = 0 ; i < numRows ; i++) + { + str.Append(GetExportLine(i, cols)); + + if (numRows > 1) + str.Append(END_OF_LINE); + } + + copied = numRows; + } + else if (GetSelectionBlockTopLeft().GetCount() > 0 && + GetSelectionBlockBottomRight().GetCount() > 0) + { + unsigned int x1, x2, y1, y2; + + x1 = GetSelectionBlockTopLeft()[0].GetCol(); + x2 = GetSelectionBlockBottomRight()[0].GetCol(); + y1 = GetSelectionBlockTopLeft()[0].GetRow(); + y2 = GetSelectionBlockBottomRight()[0].GetRow(); + + AppendColumnHeader(str, x1, x2); + + for (i = y1; i <= y2; i++) + { + str.Append(GetExportLine(i, x1, x2)); + + if (y2 > y1) + str.Append(END_OF_LINE); + } + + copied = y2 - y1 + 1; + } + else + { + int row, col; + + row = GetGridCursorRow(); + col = GetGridCursorCol(); + + AppendColumnHeader(str, col, col); + + str.Append(GetExportLine(row, col, col)); + copied = 1; + } + + if (copied && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(str)); + wxTheClipboard->Close(); + } + else + { + copied = 0; + } + + return copied; +} + +void ctlSQLGrid::OnLabelDoubleClick(wxGridEvent &event) +{ + int maxHeight, maxWidth; + GetClientSize(&maxWidth, &maxHeight); + int row = event.GetRow(); + int col = event.GetCol(); + + int extent, extentWant = 0; + + if (row >= 0) + { + for (col = 0 ; col < GetNumberCols() ; col++) + { + extent = GetBestSize(row, col).GetHeight(); + if (extent > extentWant) + extentWant = extent; + } + + extentWant += EXTRAEXTENT_HEIGHT; + extentWant = wxMax(extentWant, GetRowMinimalAcceptableHeight()); + extentWant = wxMin(extentWant, maxHeight * 3 / 4); + int currentHeight = GetRowHeight(row); + + if (currentHeight >= maxHeight * 3 / 4 || currentHeight == extentWant) + extentWant = GetRowMinimalAcceptableHeight(); + else if (currentHeight < maxHeight / 4) + extentWant = wxMin(maxHeight / 4, extentWant); + else if (currentHeight < maxHeight / 2) + extentWant = wxMin(maxHeight / 2, extentWant); + else if (currentHeight < maxHeight * 3 / 4) + extentWant = wxMin(maxHeight * 3 / 4, extentWant); + + if (extentWant != currentHeight) + { + BeginBatch(); + if(IsCellEditControlShown()) + { + HideCellEditControl(); + SaveEditControlValue(); + } + + SetRowSize(row, extentWant); + EndBatch(); + } + } + else if (col >= 0) + { + // Holding Ctrl or Meta switches back to automatic column's sizing + if (event.ControlDown() || event.CmdDown()) + { + colSizes.erase(GetColKeyValue(col)); + BeginBatch(); + if(IsCellEditControlShown()) + { + HideCellEditControl(); + SaveEditControlValue(); + } + AutoSizeColumn(col, false); + EndBatch(); + } + else // toggle between some predefined sizes + { + + if (col < (int)colMaxSizes.GetCount() && colMaxSizes[col] >= 0) + extentWant = colMaxSizes[col]; + else + { + for (row = 0 ; row < GetNumberRows() ; row++) + { + if (CheckRowPresent(row)) + { + extent = GetBestSize(row, col).GetWidth(); + if (extent > extentWant) + extentWant = extent; + } + } + } + + extentWant += EXTRAEXTENT_WIDTH; + extentWant = wxMax(extentWant, GetColMinimalAcceptableWidth()); + extentWant = wxMin(extentWant, maxWidth * 3 / 4); + int currentWidth = GetColSize(col); + + if (currentWidth >= maxWidth * 3 / 4 || currentWidth == extentWant) + extentWant = GetColMinimalAcceptableWidth(); + else if (currentWidth < maxWidth / 4) + extentWant = wxMin(maxWidth / 4, extentWant); + else if (currentWidth < maxWidth / 2) + extentWant = wxMin(maxWidth / 2, extentWant); + else if (currentWidth < maxWidth * 3 / 4) + extentWant = wxMin(maxWidth * 3 / 4, extentWant); + + if (extentWant != currentWidth) + { + BeginBatch(); + if(IsCellEditControlShown()) + { + HideCellEditControl(); + SaveEditControlValue(); + } + SetColSize(col, extentWant); + EndBatch(); + colSizes[GetColKeyValue(col)] = extentWant; + } + } + } +} + + void ctlSQLGrid::OnCellRightClick(wxGridEvent &event) +{ + int row = event.GetRow(); + int col = event.GetCol(); + + //SetRowLabelValue(row-1,); + //HideRow(row); +} +void ctlSQLGrid::OnLabelClick(wxGridEvent &event) +{ + int row = event.GetRow(); + int col = event.GetCol(); + if (row >= 0 && grp) { + grp->VisibleGroup(row,GetRowSize(row+1)==0); + return; + } + if ( col >= 0 && (event.AltDown() ) ) + { + // continue for sort event + if (IsSort()) { + sqlResultTable *t=(sqlResultTable *)GetTable(); + t->setSortColumn(col); + return; + } + } + // add support for (de)selecting multiple rows and cols with Control pressed + else if ( row >= 0 && (event.ControlDown() || event.CmdDown()) ) + { + if (GetSelectedRows().Index(row) == wxNOT_FOUND) + SelectRow(row, true); + else + DeselectRow(row); + } + else if ( col >= 0 && (event.ControlDown() || event.CmdDown()) ) + { + if (GetSelectedCols().Index(col) == wxNOT_FOUND) + SelectCol(col, true); + else + DeselectCol(col); + event.Skip(); + } + else + event.Skip(); +} + +void ctlSQLGrid::AutoSizeColumn(int col, bool setAsMin, bool doLimit) +{ + ColKeySizeHashMap::iterator it = colSizes.find(GetColKeyValue(col)); + if (it != colSizes.end()) // Restore user-specified size + SetColSize(col, it->second); + else + wxGrid::AutoSizeColumn(col, setAsMin); + + if (doLimit) + { + int newSize, oldSize; + int maxSize, totalSize = 0, availSize; + + oldSize = GetColSize(col); + availSize = GetClientSize().GetWidth() - GetRowLabelSize(); + maxSize = availSize / 2; + for (int i = 0 ; i < GetNumberCols() ; i++) + totalSize += GetColSize(i); + + if (oldSize > maxSize && totalSize > availSize) + { + totalSize -= oldSize; + /* Shrink wide column to maxSize. + * If the rest of the columns are short, make sure to use all the remaining space, + * but no more than oldSize (which is enough according to AutoSizeColumns()) + */ + newSize = wxMin(oldSize, wxMax(maxSize, availSize - totalSize)); + SetColSize(col, newSize); + } + } +} + +void ctlSQLGrid::AutoSizeColumns(bool setAsMin) +{ + wxCoord newSize, oldSize; + wxCoord maxSize, totalSize = 0, availSize; + int col, nCols = GetNumberCols(); + int row, nRows = GetNumberRows(); + colMaxSizes.Empty(); + + /* We need to check each cell's width to choose best. wxGrid::AutoSizeColumns() + * is good, but looping through long result sets gives a noticeable slowdown. + * Thus we'll check every first 500 cells for each column. + */ + + // First pass: auto-size columns + for (col = 0 ; col < nCols; col++) + { + ColKeySizeHashMap::iterator it = colSizes.find(GetColKeyValue(col)); + if (it != colSizes.end()) // Restore user-specified size + { + newSize = it->second; + colMaxSizes.Add(-1); + } + else + { + wxClientDC dc(GetGridWindow()); + newSize = 0; + // get cells's width + for (row = 0 ; row < wxMin(nRows, 500) ; row++) + { + wxSize size = GetBestSize(row, col); + if ( size.x > newSize ) + newSize = size.x; + } + // get column's label width + wxCoord w, h; + dc.SetFont( GetLabelFont() ); + dc.GetMultiLineTextExtent( GetColLabelValue(col), &w, &h ); + if ( GetColLabelTextOrientation() == wxVERTICAL ) + w = h; + + if ( w > newSize ) + newSize = w; + + if (!newSize) + newSize = GetRowLabelSize(); + else + // leave some space around text + newSize += 6; + + colMaxSizes.Add(newSize); + } + SetColSize(col, newSize); + totalSize += newSize; + } + + availSize = GetClientSize().GetWidth() - GetRowLabelSize(); + + // Second pass: shrink wide columns if exceeded available width + if (totalSize > availSize) + { + // A wide column shouldn't take up more than 50% of the visible space + maxSize = availSize / 2; + for (col = 0 ; col < nCols ; col++) + { + oldSize = GetColSize(col); + // Is too wide and no user-specified size + if (oldSize > maxSize && !(col < (int)colMaxSizes.GetCount() && colMaxSizes[col] == -1)) + { + totalSize -= oldSize; + /* Shrink wide column to maxSize. + * If the rest of the columns are short, make sure to use all the remaining space, + * but no more than oldSize (which is enough according to first pass) + */ + newSize = wxMin(oldSize, wxMax(maxSize, availSize - totalSize)); + SetColSize(col, newSize); + totalSize += newSize; + } + } + } +} + +wxString ctlSQLGrid::GetColKeyValue(int col) +{ + wxString colKey = wxString::Format(wxT("%d:"), col) + GetColLabelValue(col); + return colKey; +} + +wxSize ctlSQLGrid::GetBestSize(int row, int col) +{ + wxSize size; + + wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); + if ( renderer ) + { + wxClientDC dc(GetGridWindow()); + size = renderer->GetBestSize(*this, *attr, dc, row, col); + renderer->DecRef(); + } + + attr->DecRef(); + + return size; +} + + + +int recurse(ctlSQLGrid *g, int pos,int row, double &transfer) { + wxString text; + double leveltime=0; //actual time level + double lastnode=0; + while (rowGetNumberRows()) { + text = g->GetCellValue(row, 0); + int p=0; + while (text.at(p)==' ' ) + { + p++; + } + if (p==pos) { + // + lastnode=0; + if (text.at(p)=='-') { + // ïîñ÷èòàåì âðåìÿ ðàáîòû óçëà + double m=1; + // -> Nested Loop (cost=205.13..273.44 rows=4 width=188) (actual time=13.157..13.157 rows=0 loops=1) + wxRegEx foundstr(wxT("actual time=.*?\\.\\.([0-9.]+).*?loops=([0-9]+)\\)"),wxRE_ADVANCED); + if (foundstr.Matches(text)) { + wxString v=foundstr.GetMatch(text,1); + v.ToCDouble(&lastnode); + v=foundstr.GetMatch(text,2); + v.ToDouble(&m); + lastnode=lastnode*m; + leveltime=leveltime+lastnode; + } + g->grp->ColoriseRow(row,wxColour(248,240,130)); + + } else + { + g->grp->ColoriseRow(row,wxColour(224,255,224)); + g->GetTable()->SetRowLabelValue(row,wxEmptyString); + } + row++; + continue; + } if (ppos) { + // nested level + //g->SetRowGroup(row-1); + wxString s; + int newrow=recurse(g,p,row,transfer); + // + //leveltime=leveltime+transfer; + //GroupRows *u=g->getgroup(); + double tt=lastnode-transfer; + text = g->GetCellValue(row-1, 0); + if ((text.Find("Append")>0) + ||(text.Find("Gather")>0)) + tt=lastnode; + g->grp->AddGroup(row-1,newrow-1,tt); + s << (tt) ; + s=s+wxT("-"); + g->GetTable()->SetRowLabelValue(row-1,s); + + row=newrow; + } + + } + return row; +} +void ctlSQLGrid::SetRowGroup(int row) { }; +bool ctlSQLGrid::FullArrayCollapseRowsPlan(bool clear) +{ + //wxString colKey = wxString::Format(wxT("%d:"), col) + GetColLabelValue(col); + wxString text; + //for(int row = 0; row < GetNumberRows(); ++row) + + if (grp) { delete grp;} + if (clear) { grp=NULL; return true;} + grp = new GroupRows(this); + double transfersum=0; + int r= recurse(this,0,0,transfersum); + grp->CalcTime(); + //for(int row = 0; row < GetNumberRows(); ++row) { + // text = GetCellValue(row, 0); + // //if (row%2==0) SetRowAttr(row,pAttr); + + //} + + return true; +} + + diff --git a/ctl/ctlSQLResult.cpp b/ctl/ctlSQLResult.cpp new file mode 100644 index 0000000..f32aa5c --- /dev/null +++ b/ctl/ctlSQLResult.cpp @@ -0,0 +1,723 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLResult.cpp - SQL Query result window +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "ctl/ctlSQLResult.h" +#include "utils/sysSettings.h" +#include "frm/frmExport.h" + + + +ctlSQLResult::ctlSQLResult(wxWindow *parent, pgConn *_conn, wxWindowID id, const wxPoint &pos, const wxSize &size) + : ctlSQLGrid(parent, id, pos, size) +{ + conn = _conn; + thread = NULL; + + SetTable(new sqlResultTable(), true); + + EnableEditing(false); + SetSizer(new wxBoxSizer(wxVERTICAL)); + cg=GetGridLineColour(); + Connect(wxID_ANY, wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEventHandler(ctlSQLResult::OnGridSelect)); + Connect(wxID_ANY, wxEVT_GRID_COL_SORT, wxGridEventHandler(ctlSQLResult::OnGridColSort)); +} + + + +ctlSQLResult::~ctlSQLResult() +{ + Abort(); + + if (thread) + { + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + + delete thread; + thread = NULL; + } +} + + +void ctlSQLResult::SetConnection(pgConn *_conn) +{ + conn = _conn; +} + + +bool ctlSQLResult::Export() +{ + if (NumRows() > 0) + { + frmExport dlg(this); + if (dlg.ShowModal() == wxID_OK) + return dlg.Export(NULL); + } + return false; +} + +bool ctlSQLResult::ToFile() +{ + if (NumRows() > 0) + { + frmExport dlg(this); + if (dlg.ShowModal() == wxID_OK) + return dlg.Export(thread->DataSet()); + } + return false; +} + +bool ctlSQLResult::ToFile(frmExport *frm) +{ + if (NumRows() > 0) + { + return frm->Export(thread->DataSet()); + } + return false; +} + + + +bool ctlSQLResult::IsColText(int col) +{ + switch (colTypClasses.Item(col)) + { + case PGTYPCLASS_NUMERIC: + case PGTYPCLASS_BOOL: + return false; + } + + return true; +} + + +int ctlSQLResult::Execute(const wxString &query, int resultToRetrieve, wxWindow *caller, long eventId, void *data) +{ + wxGridTableMessage *msg; + sqlResultTable *table = (sqlResultTable *)GetTable(); + + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, GetNumberRows()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_COLS_DELETED, 0, GetNumberCols()); + ProcessTableMessage(*msg); + delete msg; + + Abort(); + + colNames.Empty(); + colTypes.Empty(); + colTypClasses.Empty(); + thread = new pgQueryThread(conn, query, resultToRetrieve, caller, eventId, data); + + if (thread->Create() != wxTHREAD_NO_ERROR) + { + Abort(); + return -1; + } + + ((sqlResultTable *)GetTable())->SetThread(thread); + sqlquerytext= wxString(query); + thread->Run(); + return RunStatus(); +} + + +int ctlSQLResult::Abort() +{ + if (thread) + { + ((sqlResultTable *)GetTable())->SetThread(0); + + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + + delete thread; + thread = NULL; + } + return 0; +} + + + +void ctlSQLResult::DisplayData(bool single) +{ + if (!thread || !thread->DataValid()) + return; + + if (thread->ReturnCode() != PGRES_TUPLES_OK) + return; + + rowcountSuppressed = single; + Freeze(); + + /* + * Resize and repopulate by informing it to delete all the rows and + * columns, then append the correct number of them. Probably is a + * better way to do this. + */ + wxGridTableMessage *msg; + sqlResultTable *table = (sqlResultTable *)GetTable(); + + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_ROWS_DELETED, 0, GetNumberRows()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_COLS_DELETED, 0, GetNumberCols()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, NumRows()); + ProcessTableMessage(*msg); + delete msg; + msg = new wxGridTableMessage(table, wxGRIDTABLE_NOTIFY_COLS_APPENDED, thread->DataSet()->NumCols()); + ProcessTableMessage(*msg); + delete msg; + table->initSort(); + SetSort(true); + if (NumRows()<1000) { + for(int row = 0; row < NumRows(); ++row) { + if (row%2==0) { + wxGridCellAttr* pAttr = new wxGridCellAttr; + pAttr->SetBackgroundColour(wxColour(224,255,224)); + SetRowAttr(row,pAttr); + } + + } + } + table->isplan=false; + wxString c=thread->DataSet()->ColName(0); + if (c==wxT("QUERY PLAN")) { + // + table->isplan=true; + FullArrayCollapseRowsPlan(false); + } else FullArrayCollapseRowsPlan(true); + + if (single) + { + colNames.Add(thread->DataSet()->ColName(0)); + colTypes.Add(wxT("")); + colTypClasses.Add(0L); + + AutoSizeColumn(0, false, false); + } + else + { + long col, nCols = thread->DataSet()->NumCols(); + + AutoSizeColumns(false); + + for (col = 0 ; col < nCols ; col++) + { + colNames.Add(thread->DataSet()->ColName(col)); + colTypes.Add(thread->DataSet()->ColFullType(col)); + colTypClasses.Add(thread->DataSet()->ColTypClass(col)); + if (thread->DataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC) + { + /* + * For numeric columns, set alignment to right. + */ + wxGridCellAttr *attr = new wxGridCellAttr(); + attr->SetAlignment(wxALIGN_RIGHT, wxALIGN_TOP); + SetColAttr(col, attr); + } + } + } + Thaw(); +} + + + +wxString ctlSQLResult::GetMessagesAndClear() +{ + if (thread) + return thread->GetMessagesAndClear(); + return wxEmptyString; +} + + +wxString ctlSQLResult::GetErrorMessage() +{ + return conn->GetLastError(); +} + +pgError ctlSQLResult::GetResultError() +{ + if (thread) + return thread->GetResultError(); + + pgError dummy; + memset(&dummy, 0, sizeof(dummy)); + return dummy; +} + +long ctlSQLResult::NumRows() const +{ + if (thread && thread->DataValid()) + return thread->DataSet()->NumRows(); + return 0; +} + + +long ctlSQLResult::InsertedCount() const +{ + if (thread) + return thread->RowsInserted(); + return -1; +} + + +OID ctlSQLResult::InsertedOid() const +{ + if (thread) + return thread->InsertedOid(); + return (OID) - 1; +} + + +int ctlSQLResult::RunStatus() +{ + if (!thread) + return -1; + + if (thread->IsRunning()) + return CTLSQL_RUNNING; + + return thread->ReturnCode(); +} + + +wxString ctlSQLResult::OnGetItemText(long item, long col) const +{ + if (thread && thread->DataValid()) + { + if (!rowcountSuppressed) + { + if (col) + col--; + else + return NumToStr(item + 1L); + } + if (item >= 0) + { + //thread->DataSet()->Locate(item + 1); + //return thread->DataSet()->GetVal(col); + sqlResultTable *t=(sqlResultTable *)GetTable(); + return t->GetValueFast(item,col); + } + else + return thread->DataSet()->ColName(col); + } + return wxEmptyString; +} + +wxString ctlSQLResult::SummaryColumn() +{ + //ce=cells.Item(0); + double sum=0; + size_t i; + if (GetSelectedRows().GetCount()) + { + //AppendColumnHeader(str, 0, (GetNumberCols() - 1)); + + wxArrayInt rows = GetSelectedRows(); + + for (i = 0 ; i < rows.GetCount() ; i++) + { + //str.Append(GetExportLine(rows.Item(i))); + //if (rows.GetCount() > 1) + // str.Append(END_OF_LINE); + } + + //copied = rows.GetCount(); + } + else if (GetSelectedCols().GetCount()) + { + wxArrayInt cols = GetSelectedCols(); + size_t numRows = GetNumberRows(); + + //AppendColumnHeader(str, cols); + for (i = 0 ; i < numRows ; i++) + { + //str.Append(GetExportLine(i, cols)); + for (size_t col = 0 ; col < cols.Count() ; col++) + { + wxString text = GetCellValue(i, cols[col]); + if (GetRowSize(i)>0) sum=sum+wxAtof(text); + } + + } + + //copied = numRows; + } + else if (GetSelectionBlockTopLeft().GetCount() > 0 && + GetSelectionBlockBottomRight().GetCount() > 0) + { + unsigned int x1, x2, y1, y2; + + x1 = GetSelectionBlockTopLeft()[0].GetCol(); + x2 = GetSelectionBlockBottomRight()[0].GetCol(); + y1 = GetSelectionBlockTopLeft()[0].GetRow(); + y2 = GetSelectionBlockBottomRight()[0].GetRow(); + + //AppendColumnHeader(str, x1, x2); + + for (i = y1; i <= y2; i++) + { +// str.Append(GetExportLine(i, x1, x2)); + wxString text = GetCellValue(i, x1); + if (GetRowSize(i)>0) sum=sum+wxAtof(text); + + //copied = y2 - y1 + 1; + } + } + else + { + int row, col; + + row = GetGridCursorRow(); + col = GetGridCursorCol(); + + //AppendColumnHeader(str, col, col); + +// str.Append(GetExportLine(row, col, col)); + //copied = 1; + } + + + wxString result; + result.Printf(wxT("%f"), sum); + return result; +} +void ctlSQLResult::OnGridColSort(wxGridEvent& event) + { + const int col = event.GetCol(); + //m_table->Sort(col, !(m_grid->IsSortingBy(col) && m_grid->IsSortOrderAscending())); + } + +void ctlSQLResult::OnGridSelect(wxGridRangeSelectEvent &event) +{ + SetFocus(); +} +void ctlSQLResult::ClearFilter() +{ + size_t numRows = GetNumberRows(); + int sizerow=GetDefaultRowSize(); + for (size_t i = 0 ; i < numRows; i++) + { + if (GetRowSize(i)>0) continue; + //SetRowSize(i,sizerow); + ShowRow(i); + + } + SetGridLineColour(cg); +} +wxString ctlSQLResult::SetFilter(int row,int col,bool reverse) +{ + wxString result=wxEmptyString; + sqlResultTable *t=(sqlResultTable *)GetTable(); + if (!(thread && thread->DataValid())) {result.Printf(wxT("Error thread not valid"));return result; } + //wxString fltval=GetCellValue(row,col); + wxString fltval=t->GetValueFast(row,col); + wxString text; + + bool eq; + size_t numRows = GetNumberRows(); + int all=0,show=0,hide=0; + for (size_t i = 0 ; i < numRows; i++) + { + //str.Append(GetExportLine(i, cols)); + //SetRowSize(i,sizerow); + if (GetRowSize(i)==0) continue; + + eq=(fltval==t->GetValueFast(i,col)); + if (reverse) eq=!eq; + if (!eq) { + HideRow(i); + hide++; + } else show++; + all++; + + } + SetGridLineColour(wxColor(0,0,255)); + result.Printf(wxT("Show rows:%d hide:%d all:%d"), show,hide,all); + return result; + +} +#include +int sqlResultTable::sortColumns() +{ + bool no_sort=colsortnumber[0]==-1; + if (!maplines) { + maplines = new int[GetNumberRows()]; + for(int i=0;iDataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC) + { + //sort numeric column + std::multimap mp; + double d; + for (int i=0;iDataSet()->Locate(i+1); + d=thread->DataSet()->GetDouble(col); + mp.insert(std::pair(d, i)); + } + std::multimap::iterator it = mp.begin(); + double prev; + int row; + int minval=0; + cols[k] = new int[GetNumberRows()]; + for (int i = 0; it != mp.end(); it++, i++) { // âûâîäèì èõ + row=it->second; // row + if (i>0) if (prev!=it->first) minval++; + cols[k][row]=minval; + prev=it->first; + } + } else { + //no numeric sort as string + std::multimap mp; + wxString s; + for (int i=0;iDataSet()->Locate(i+1); + s=thread->DataSet()->GetVal(col); + mp.insert(std::pair(s, i)); + } + std::multimap::iterator it = mp.begin(); + wxString prev; + int row; + int minval=0; + cols[k] = new int[GetNumberRows()]; + for (int i = 0; it != mp.end(); it++, i++) { + row=it->second; // row + if (i>0) if (prev!=it->first) minval++; + cols[k][row]=minval; + prev=it->first; + } + } + } else break; + } + + class sorter { + int **cols; + sqlResultTable *m; + public: + sorter(int *_cols[], sqlResultTable *my_obj) { cols=_cols;m=my_obj;} + bool operator() (int i,int j) { + bool rez=true; + int a; + int b; + int col,ord; + for (int k=0;kcolsortnumber[k]; + if (col!=-1) { + ord=m->colorder[col]; + if (ord==0) continue; + a=cols[k][i]; + b=cols[k][j]; + if (a!=b) { + rez=aDataValid()) + { + if (col >= 0) + { + if (use_map) row=maplines[row]; + thread->DataSet()->Locate(row + 1); + wxString s = thread->DataSet()->GetVal(col); + return s; + } + + } + return ""; +} +wxString sqlResultTable::GetValue(int row, int col) +{ + if (thread && thread->DataValid()) + { + if (col >= 0) + { + if (use_map) row=maplines[row]; + thread->DataSet()->Locate(row + 1); + if (settings->GetIndicateNull() && thread->DataSet()->IsNull(col)) + return wxT(""); + else + { + + wxString decimalMark = wxT("."); + wxString s = thread->DataSet()->GetVal(col); + + if(thread->DataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC && + settings->GetDecimalMark().Length() > 0) + { + decimalMark = settings->GetDecimalMark(); + s.Replace(wxT("."), decimalMark); + + } + if (thread->DataSet()->ColTypClass(col) == PGTYPCLASS_NUMERIC && + settings->GetThousandsSeparator().Length() > 0) + { + /* Add thousands separator */ + size_t pos = s.find(decimalMark); + if (pos == wxString::npos) + pos = s.length(); + while (pos > 3) + { + pos -= 3; + if (pos > 1 || !s.StartsWith(wxT("-"))) + s.insert(pos, settings->GetThousandsSeparator()); + } + return s; + } + else + { + wxString data = thread->DataSet()->GetVal(col); + + if (data.Length() > (size_t)settings->GetMaxColSize()) + return thread->DataSet()->GetVal(col).Left(settings->GetMaxColSize()) + wxT(" (...)"); + else + return thread->DataSet()->GetVal(col); + } + } + } + else + return thread->DataSet()->ColName(col); + } + return wxEmptyString; +} + +sqlResultTable::sqlResultTable() +{ + thread = NULL; + colorder=NULL; + maplines=NULL; + use_map=false; +} + +int sqlResultTable::GetNumberRows() +{ + if (thread && thread->DataValid()) + return thread->DataSet()->NumRows(); + return 0; +} + +wxString sqlResultTable::GetRowLabelValue( int row ) +{ + if ( isplan ) + { + // using default label + // + return wxGridStringTable::GetRowLabelValue(row); + } + else + { + wxString s; + s << row + 1; + return s; + } +} + +wxString sqlResultTable::GetColLabelValue(int col) +{ + if (thread && thread->DataValid()) + return thread->DataSet()->ColName(col) + wxT("\n") + + thread->DataSet()->ColFullType(col); + return wxEmptyString; +} + +int sqlResultTable::GetNumberCols() +{ + if (thread && thread->DataValid()) + return thread->DataSet()->NumCols(); + return 0; +} + diff --git a/ctl/ctlSeclabelPanel.cpp b/ctl/ctlSeclabelPanel.cpp new file mode 100644 index 0000000..04ed065 --- /dev/null +++ b/ctl/ctlSeclabelPanel.cpp @@ -0,0 +1,291 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSeclabelPanel.cpp - Panel with security label information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSeclabelPanel.h" +#include "db/pgConn.h" +#include "schema/pgObject.h" +#include "utils/pgDefs.h" + + +BEGIN_EVENT_TABLE(ctlSeclabelPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_LBSECLABEL, ctlSeclabelPanel::OnSeclabelSelChange) + EVT_BUTTON(CTL_ADDSECLABEL, ctlSeclabelPanel::OnAddSeclabel) + EVT_BUTTON(CTL_DELSECLABEL, ctlSeclabelPanel::OnDelSeclabel) + EVT_TEXT(CTL_PROVIDER, ctlSeclabelPanel::OnChange) + EVT_TEXT(CTL_SECLABEL, ctlSeclabelPanel::OnChange) +END_EVENT_TABLE(); + +DEFINE_LOCAL_EVENT_TYPE(EVT_SECLABELPANEL_CHANGE) + + +ctlSeclabelPanel::ctlSeclabelPanel(wxNotebook *nb) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize) +{ + wxStaticText *label; + + nbNotebook = nb; + nbNotebook->AddPage(this, _("Security Labels")); + + connection = NULL; + + // root sizer + wxFlexGridSizer *sizer0 = new wxFlexGridSizer(4, 1, 5, 5); + sizer0->AddGrowableCol(0); + sizer0->AddGrowableRow(0); + + // grid sizer + wxFlexGridSizer *sizer1 = new wxFlexGridSizer(1, 1, 5, 5); + sizer1->AddGrowableCol(0); + sizer1->AddGrowableRow(0); + lbSeclabels = new ctlListView(this, CTL_LBSECLABEL, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT); + lbSeclabels->AddColumn(_("Provider"), 70, wxLIST_FORMAT_LEFT); + lbSeclabels->AddColumn(_("Security label"), 70, wxLIST_FORMAT_LEFT); + sizer1->Add(lbSeclabels, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + sizer0->Add(sizer1, 0, wxEXPAND | wxALL, 5); + + // buttons sizer + wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddSeclabel = new wxButton(this, CTL_ADDSECLABEL, _("Add/Change")); + sizer2->Add(btnAddSeclabel, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + btnDelSeclabel = new wxButton(this, CTL_DELSECLABEL, _("Remove")); + sizer2->Add(btnDelSeclabel, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + sizer0->Add(sizer2, 0, wxEXPAND | wxALL, 0); + + + // textboxes sizer + wxFlexGridSizer *sizer3 = new wxFlexGridSizer(2, 2, 5, 5); + sizer3->AddGrowableCol(1); + label = new wxStaticText(this, 0, _("Provider")); + sizer3->Add(label, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + txtProvider = new wxTextCtrl(this, CTL_PROVIDER); + sizer3->Add(txtProvider, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + label = new wxStaticText(this, 0, _("Security label")); + sizer3->Add(label, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + txtSeclabel = new wxTextCtrl(this, CTL_SECLABEL); + sizer3->Add(txtSeclabel, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + sizer0->Add(sizer3, 0, wxEXPAND | wxALL, 5); + + // compute sizes + this->SetSizer(sizer0); + sizer0->Fit(this); + + btnAddSeclabel->Enable(false); +} + + +ctlSeclabelPanel::~ctlSeclabelPanel() +{ +} + + +void ctlSeclabelPanel::Disable() +{ + lbSeclabels->Disable(); + btnAddSeclabel->Disable(); + btnDelSeclabel->Disable(); + txtProvider->Disable(); + txtSeclabel->Disable(); +} + + +void ctlSeclabelPanel::SetConnection(pgConn *conn) +{ + connection = conn; +} + + +void ctlSeclabelPanel::SetObject(pgObject *obj) +{ + object = obj; + + if (object && !object->GetLabels().IsEmpty()) + { + wxArrayString seclabels = object->GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + lbSeclabels->AppendItem(seclabels.Item(index), + seclabels.Item(index + 1)); + } + } + } +} + + +void ctlSeclabelPanel::OnDelSeclabel(wxCommandEvent &ev) +{ + if (lbSeclabels->GetFirstSelected() == -1) + return; + + lbSeclabels->DeleteCurrentItem(); + + wxCommandEvent event( EVT_SECLABELPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + + +void ctlSeclabelPanel::OnAddSeclabel(wxCommandEvent &ev) +{ + bool found = false; + + for (int indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + if (lbSeclabels->GetText(indexList) == txtProvider->GetValue()) + { + found = true; + lbSeclabels->SetItem(indexList, 1, txtSeclabel->GetValue()); + break; + } + } + + if (!found) + { + int pos = lbSeclabels->GetItemCount(); + lbSeclabels->InsertItem(pos, txtProvider->GetValue()); + lbSeclabels->SetItem(pos, 1, txtSeclabel->GetValue()); + } + + wxCommandEvent event( EVT_SECLABELPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + +void ctlSeclabelPanel::OnChange(wxCommandEvent &event) +{ + wxString provider = txtProvider->GetValue().Trim(true).Trim(false); + wxString label = txtSeclabel->GetValue().Trim(true).Trim(false); + btnAddSeclabel->Enable(!provider.IsEmpty() && !label.IsEmpty()); +} + +void ctlSeclabelPanel::OnSeclabelSelChange(wxListEvent &ev) +{ + if (lbSeclabels->GetFirstSelected() == -1) + return; + + txtProvider->SetValue(lbSeclabels->GetText(lbSeclabels->GetSelection())); + txtSeclabel->SetValue(lbSeclabels->GetText(lbSeclabels->GetSelection(), 1)); +} + +void ctlSeclabelPanel::GetCurrentProviderLabelArray(wxArrayString &secLabels) +{ + for(int indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + secLabels.Add(lbSeclabels->GetText(indexList)); + secLabels.Add(lbSeclabels->GetText(indexList, 1)); + } +} + +wxString ctlSeclabelPanel::GetSqlForSecLabels(wxString objecttype, wxString objectname) +{ + wxASSERT(connection != NULL); + + wxString sql; + wxArrayString seclabels; + int indexList; + unsigned int indexArray; + wxString oldprovider, newprovider, oldlabel, newlabel; + bool found; + + if (object) + { + seclabels = object->GetProviderLabelArray(); + + // find new or changed seclabels + for (indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + found = false; + newprovider = lbSeclabels->GetText(indexList); + newlabel = lbSeclabels->GetText(indexList, 1); + + // try to find the provider in the current providers list + if (object && seclabels.GetCount() > 0) + { + for (indexArray = 0 ; indexArray < seclabels.GetCount() - 1 ; indexArray += 2) + { + oldprovider = seclabels.Item(indexArray); + oldlabel = seclabels.Item(indexArray + 1); + + if (oldprovider == newprovider) + { + found = true; + // provider is available on the old and new list + // we should check is the label has changed + if (oldlabel != newlabel) + sql += wxT("SECURITY LABEL FOR ") + newprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS ") + object->qtDbString(newlabel) + wxT(";\n"); + } + } + } + + if (!found) + sql += wxT("SECURITY LABEL FOR ") + newprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS ") + object->qtDbString(newlabel) + wxT(";\n"); + } + + // find old seclabels + if (seclabels.GetCount() > 0) + { + for (indexArray = 0 ; indexArray < seclabels.GetCount() - 1 ; indexArray += 2) + { + found = false; + oldprovider = seclabels.Item(indexArray); + + for (indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + newprovider = lbSeclabels->GetText(indexList); + + if (oldprovider == newprovider) + { + found = true; + } + } + + if (!found) + sql += wxT("SECURITY LABEL FOR ") + oldprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS NULL;\n"); + } + } + } + else + { + // find new or changed seclabels + for (indexList = 0; indexList < lbSeclabels->GetItemCount(); indexList++) + { + newprovider = lbSeclabels->GetText(indexList); + newlabel = lbSeclabels->GetText(indexList, 1); + + sql += wxT("SECURITY LABEL FOR ") + newprovider + + wxT("\n ON ") + objecttype + wxT(" ") + objectname + + wxT("\n IS ") + connection->qtDbString(newlabel) + wxT(";\n"); + } + } + + return sql; +} diff --git a/ctl/ctlSecurityPanel.cpp b/ctl/ctlSecurityPanel.cpp new file mode 100644 index 0000000..7b3bffe --- /dev/null +++ b/ctl/ctlSecurityPanel.cpp @@ -0,0 +1,445 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSecurityPanel.cpp - Panel with security information +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSecurityPanel.h" +#include "db/pgConn.h" +#include "schema/pgObject.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" + + + +BEGIN_EVENT_TABLE(ctlSecurityPanel, wxPanel) + EVT_LIST_ITEM_SELECTED(CTL_LBPRIV, ctlSecurityPanel::OnPrivSelChange) + EVT_BUTTON(CTL_ADDPRIV, ctlSecurityPanel::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, ctlSecurityPanel::OnDelPriv) + EVT_TEXT(CTL_CBGROUP, ctlSecurityPanel::OnGroupChange) + EVT_COMBOBOX(CTL_CBGROUP, ctlSecurityPanel::OnGroupChange) + EVT_CHECKBOX(CTL_ALLPRIV, ctlSecurityPanel::OnPrivCheckAll) + EVT_CHECKBOX(CTL_ALLPRIVGRANT, ctlSecurityPanel::OnPrivCheckAllGrant) + EVT_CHECKBOX(CTL_PRIVCB, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 2, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 4, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 6, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 8, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 10, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 12, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 14, ctlSecurityPanel::OnPrivCheck) + EVT_CHECKBOX(CTL_PRIVCB + 16, ctlSecurityPanel::OnPrivCheck) +END_EVENT_TABLE(); + +DEFINE_LOCAL_EVENT_TYPE(EVT_SECURITYPANEL_CHANGE) + +ctlSecurityPanel::ctlSecurityPanel(wxNotebook *nb, const wxString &privList, const char *privChars, wxImageList *imgList) + : wxPanel(nb, -1, wxDefaultPosition, wxDefaultSize) +{ + nbNotebook = nb; + nbNotebook->AddPage(this, _("Privileges")); + + connection = 0; + privilegeChars = privChars; + allPrivileges = 0; + + privCheckboxes = 0; + + wxStringTokenizer privileges(privList, wxT(",")); + privilegeCount = privileges.CountTokens(); + + wxFlexGridSizer *item0 = new wxFlexGridSizer(3, 1, 5, 5); + item0->AddGrowableCol(0); + item0->AddGrowableRow(0); + + if (privilegeCount) + { + bool needAll = (privilegeCount > 1); + privCheckboxes = new wxCheckBox*[privilegeCount * 2]; + int i = 0; + + wxFlexGridSizer *itemSizer1 = new wxFlexGridSizer(1, 1, 5, 5); + itemSizer1->AddGrowableCol(0); + itemSizer1->AddGrowableRow(0); + lbPrivileges = new ctlListView(this, CTL_LBPRIV, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxLC_REPORT); + lbPrivileges->SetImageList(imgList, wxIMAGE_LIST_SMALL); + lbPrivileges->AddColumn(_("User/Group"), 70, wxLIST_FORMAT_LEFT); + lbPrivileges->AddColumn(_("Privileges"), 70, wxLIST_FORMAT_LEFT); + itemSizer1->Add(lbPrivileges, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer1, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer2 = new wxBoxSizer(wxHORIZONTAL); + btnAddPriv = new wxButton(this, CTL_ADDPRIV, _("Add/Change")); + itemSizer2->Add(btnAddPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + btnDelPriv = new wxButton(this, CTL_DELPRIV, _("Remove")); + itemSizer2->Add(btnDelPriv, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + item0->Add(itemSizer2, 0, wxEXPAND | wxALL, 0); + + wxStaticBox *sb = new wxStaticBox(this, -1, _("Privileges")); + wxBoxSizer *itemSizer3 = new wxStaticBoxSizer( sb, wxVERTICAL ); + item0->Add(itemSizer3, 0, wxEXPAND | wxALL, 5); + + wxBoxSizer *itemSizer4 = new wxBoxSizer(wxHORIZONTAL); + stGroup = new wxStaticText(this, CTL_STATICGROUP, _("Group")); +#ifdef __WXMSW__ + stGroup->SetMinSize(wxSize(30, 15)); +#endif // __WXMSW__ + itemSizer4->Add(stGroup, 0, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT, 4); + cbGroups = new ctlComboBox(this, CTL_CBGROUP, wxDefaultPosition, wxDefaultSize); + cbGroups->Append(wxT("public")); + cbGroups->SetSelection(0); + itemSizer4->Add(cbGroups, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + itemSizer3->Add(itemSizer4, 0, wxEXPAND | wxALL, 0); + + /* border size depends on the plateform */ +#ifdef __WXMSW__ + int bordersize = 4; +#endif +#ifdef __WXMAC__ + int bordersize = 3; +#endif +#ifdef __WXGTK__ + int bordersize = 0; +#endif + + if (needAll) + { + wxBoxSizer *itemSizer5 = new wxBoxSizer(wxHORIZONTAL); + allPrivileges = new wxCheckBox(this, CTL_ALLPRIV, wxT("ALL")); + itemSizer5->Add(allPrivileges, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant = new wxCheckBox(this, CTL_ALLPRIVGRANT, wxT("WITH GRANT OPTION")); + itemSizer5->Add(allPrivilegesGrant, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + allPrivilegesGrant->Disable(); + itemSizer3->Add(itemSizer5, 0, wxALL, bordersize); + } + + while (privileges.HasMoreTokens()) + { + wxString priv = privileges.GetNextToken(); + wxCheckBox *cb; + wxBoxSizer *itemSizer6 = new wxBoxSizer(wxHORIZONTAL); + cb = new wxCheckBox(this, CTL_PRIVCB + i, priv); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + privCheckboxes[i++] = cb; + cb = new wxCheckBox(this, CTL_PRIVCB + i, wxT("WITH GRANT OPTION")); + itemSizer6->Add(cb, wxEXPAND | wxALIGN_CENTRE_VERTICAL | wxTOP | wxLEFT | wxRIGHT); + cb->Disable(); + privCheckboxes[i++] = cb; + itemSizer3->Add(itemSizer6, 0, wxALL, bordersize); + } + } + + this->SetSizer(item0); + item0->Fit(this); +} + + +ctlSecurityPanel::~ctlSecurityPanel() +{ + if (privCheckboxes) + delete[] privCheckboxes; +} + + +void ctlSecurityPanel::SetConnection(pgConn *conn) +{ + connection = conn; + if (connection && stGroup && connection->BackendMinimumVersion(8, 1)) + stGroup->SetLabel(_("Role")); +} + +wxString ctlSecurityPanel::GetUserPrivileges() +{ + wxString strPrivilages = wxEmptyString; + int cnt = lbPrivileges->GetItemCount(); + int pos; + if(cnt > 0) + { + strPrivilages += wxT("{"); + for (pos = 0 ; pos < cnt ; pos++) + { + if (pos != 0) + strPrivilages += wxT(","); + + strPrivilages += + lbPrivileges->GetText(pos) + wxT("=") + lbPrivileges->GetText(pos, 1) + wxT("/") + connection->GetUser(); + } + strPrivilages += wxT("}"); + } + return strPrivilages; +} + +wxString ctlSecurityPanel::GetGrant(const wxString &allPattern, const wxString &grantObject, wxArrayString *currentAcl, wxString column) +{ + wxArrayString tmpAcl; + if (currentAcl) + tmpAcl = *currentAcl; + + wxString sql; + int cnt = lbPrivileges->GetItemCount(); + int pos; + unsigned int i; + + for (pos = 0 ; pos < cnt ; pos++) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + int nameLen = name.Length(); + + bool privWasAssigned = false; + bool privPartiallyAssigned = false; + for (i = 0 ; i < tmpAcl.GetCount() ; i++) + { + if (tmpAcl.Item(i).Left(nameLen + 1) == name + wxT("=")) + { + privPartiallyAssigned = true; + if (tmpAcl.Item(i).Mid(nameLen + 1) == value) + privWasAssigned = true; + tmpAcl.RemoveAt(i); + break; + } + } + + if (name.Left(6).IsSameAs(wxT("group "), false)) + name = wxT("GROUP ") + qtIdent(name.Mid(6)); + else + name = qtIdent(name); + + if (!privWasAssigned) + { + if (privPartiallyAssigned) + sql += pgObject::GetPrivileges(allPattern, wxT(""), grantObject, name, column); + sql += pgObject::GetPrivileges(allPattern, value, grantObject, name, column); + } + } + + for (i = 0 ; i < tmpAcl.GetCount() ; i++) + { + wxString name = tmpAcl.Item(i).BeforeLast('='); + + if (name.Left(6).IsSameAs(wxT("group "), false)) + name = wxT("GROUP ") + qtIdent(name.Mid(6)); + else + name = qtIdent(name); + sql += pgObject::GetPrivileges(allPattern, wxT(""), grantObject, name, column); + } + return sql; +} + + +void ctlSecurityPanel::OnGroupChange(wxCommandEvent &ev) +{ + cbGroups->GuessSelection(ev); + wxString name = cbGroups->GetGuessedStringSelection(); + + btnAddPriv->Enable(!name.Strip(wxString::both).IsEmpty()); +} + + +void ctlSecurityPanel::OnPrivCheckAll(wxCommandEvent &ev) +{ + bool all = allPrivileges->GetValue(); + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (all) + { + // We use the Name property of the checkboxes as a flag to note if that + // box should remain disabled (eg. CONNECT for a DB on PG < 8.2 + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + privCheckboxes[i * 2]->SetValue(true); + privCheckboxes[i * 2]->Disable(); + privCheckboxes[i * 2 + 1]->Disable(); + allPrivilegesGrant->Enable(GrantAllowed()); + } + } + else + { + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + allPrivilegesGrant->Disable(); + allPrivilegesGrant->SetValue(false); + privCheckboxes[i * 2]->Enable(); + CheckGrantOpt(i); + } + } + } +} + + + +void ctlSecurityPanel::OnPrivCheckAllGrant(wxCommandEvent &ev) +{ + bool grant = allPrivilegesGrant->GetValue(); + int i; + for (i = 0 ; i < privilegeCount ; i++) + privCheckboxes[i * 2 + 1]->SetValue(grant); +} + + +void ctlSecurityPanel::OnPrivCheck(wxCommandEvent &ev) +{ + int id = (ev.GetId() - CTL_PRIVCB) / 2; + CheckGrantOpt(id); +} + + +void ctlSecurityPanel::CheckGrantOpt(int id) +{ + bool canGrant = (GrantAllowed() && privCheckboxes[id * 2]->GetValue()); + if (canGrant) + privCheckboxes[id * 2 + 1]->Enable(); + else + { + privCheckboxes[id * 2 + 1]->SetValue(false); + privCheckboxes[id * 2 + 1]->Disable(); + } +} + + +void ctlSecurityPanel::OnDelPriv(wxCommandEvent &ev) +{ + if (lbPrivileges->GetFirstSelected() == -1) + return; + + lbPrivileges->DeleteCurrentItem(); + + wxCommandEvent event( EVT_SECURITYPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + + +void ctlSecurityPanel::OnAddPriv(wxCommandEvent &ev) +{ + wxString name = cbGroups->GetGuessedStringSelection(); + + long pos = lbPrivileges->FindItem(-1, name); + if (pos < 0) + { + pos = lbPrivileges->GetItemCount(); + int icon = userFactory.GetIconId(); + + if (name.Left(6).IsSameAs(wxT("group "), false)) + icon = groupFactory.GetIconId(); + else if (name.IsSameAs(wxT("public"), false)) + icon = PGICON_PUBLIC; + + lbPrivileges->InsertItem(pos, name, icon); + } + wxString value; + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (privCheckboxes[i * 2]->GetValue()) + { + value += privilegeChars[i]; + if (privCheckboxes[i * 2 + 1]->GetValue()) + value += '*'; + } + } + lbPrivileges->SetItem(pos, 1, value); + + wxCommandEvent event( EVT_SECURITYPANEL_CHANGE, GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + ev.Skip(); +} + + +void ctlSecurityPanel::OnPrivSelChange(wxListEvent &ev) +{ + if (!cbGroups) + return; + if (allPrivileges) + { + allPrivileges->SetValue(false); + allPrivilegesGrant->SetValue(false); + allPrivilegesGrant->Disable(); + } + long pos = lbPrivileges->GetSelection(); + if (pos >= 0) + { + wxString name = lbPrivileges->GetText(pos); + wxString value = lbPrivileges->GetText(pos, 1); + + pos = cbGroups->FindString(name); + if (pos < 0) + { + cbGroups->Append(name); + pos = cbGroups->GetCount() - 1; + } + cbGroups->SetSelection(pos); + + int i; + for (i = 0 ; i < privilegeCount ; i++) + { + if (privCheckboxes[i * 2]->GetName() != wxT("DISABLE")) + { + privCheckboxes[i * 2]->Enable(); + int index = value.Find(privilegeChars[i]); + if (index >= 0) + { + privCheckboxes[i * 2]->SetValue(true); + privCheckboxes[i * 2 + 1]->SetValue(value.Mid(index + 1, 1) == wxT("*")); + } + else + privCheckboxes[i * 2]->SetValue(false); + } + CheckGrantOpt(i); + } + } + btnAddPriv->Enable(); +} + + + +bool ctlSecurityPanel::GrantAllowed() const +{ + if (!connection->BackendMinimumVersion(7, 4)) + return false; + + wxString user = cbGroups->GetValue(); + if (user.IsSameAs(wxT("public"), false)) + return false; + + if (!connection->BackendMinimumVersion(8, 1) && + user.Left(6).IsSameAs(wxT("group "), false)) + return false; + + return true; +} + +bool ctlSecurityPanel::DisablePrivilege(const wxString &priv) +{ + for (int i = 0; i < privilegeCount; i++) + { + if (privCheckboxes[i * 2]->GetLabel() == priv) + { + // Use the Name property as a flag so we don't accidently reenable the control later + privCheckboxes[i * 2]->SetName(wxT("DISABLE")); + privCheckboxes[i * 2]->Disable(); + return true; + } + } + return false; +} diff --git a/ctl/ctlTree.cpp b/ctl/ctlTree.cpp new file mode 100644 index 0000000..98d0714 --- /dev/null +++ b/ctl/ctlTree.cpp @@ -0,0 +1,406 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTree.cpp - wxTreeCtrl containing pgObjects +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlTree.h" + +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgServer.h" + +BEGIN_EVENT_TABLE(ctlTree, wxTreeCtrl) + EVT_CHAR(ctlTree::OnChar) +END_EVENT_TABLE() + + +wxTreeItemId ctlTree::FindItem(const wxTreeItemId &idParent, const wxString &prefixOrig, const bool full ) +{ + // match is case insensitive as this is more convenient to the user: having + // to press Shift-letter to go to the item starting with a capital letter + // would be too bothersome + wxString prefix = prefixOrig.Lower(); + + // determine the starting point: we shouldn't take the current item (this + // allows to switch between two items starting with the same letter just by + // pressing it) but we shouldn't jump to the next one if the user is + // continuing to type as otherwise he might easily skip the item he wanted + wxTreeItemId id = idParent; + int le=prefix.length(); + if ( prefix.length() == 1 ) + { + wxCookieType cookie; + if (HasChildren(id)) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + + // look for the item starting with the given prefix after it + while ( id.IsOk() && + ( ( GetItemText(id) == wxT("Dummy") && !GetItemData(id) ) || + !( (!full&&GetItemText(id).Lower().StartsWith(prefix)) || + (full && //GetItemText(id).Lower().StartsWith(prefix) && GetItemText(id).length()==le) + GetObject(id)!=NULL&&GetObject(id)->GetName()==prefix ) + ) + )) + { + wxCookieType cookie; + if ( HasChildren(id) ) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + + // if we haven't found anything... + if ( !id.IsOk() ) + { + // ... wrap to the beginning + id = GetRootItem(); + if ( HasFlag(wxTR_HIDE_ROOT) ) + { + wxCookieType cookie; + // can't select virtual root + if ( HasChildren(id) ) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + + // and try all the items (stop when we get to the one we started from) + while ( id.IsOk() && id != idParent && + (( GetItemText(id) == wxT("Dummy") && !GetItemData(id) ) || + !((!full&&GetItemText(id).Lower().StartsWith(prefix)) || + (full && //GetItemText(id).Lower().StartsWith(prefix) && GetItemText(id).length()==le) + GetObject(id)!=NULL&&GetObject(id)->GetName()==prefix ) + ) + )) + { + wxCookieType cookie; + if ( HasChildren(id) ) + id = GetFirstChild(id, cookie); + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = GetNextSibling(p); + p = GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + // If we haven't found the item, id.IsOk() will be false, as per + // documentation + } + + return id; +} + +void ctlTree::OnChar(wxKeyEvent &event) +{ + int keyCode = event.GetKeyCode(); + if ( !event.HasModifiers() && + ((keyCode >= '0' && keyCode <= '9') || + (keyCode >= 'a' && keyCode <= 'z') || + (keyCode >= 'A' && keyCode <= 'Z'))) + { + wxTreeItemId currItem = GetSelection(); + + if (!currItem.IsOk()) + return; + + wxTreeItemId matchItem = FindItem(currItem, m_findPrefix + (wxChar)keyCode); + + if ( matchItem.IsOk() ) + { + EnsureVisible(matchItem); + SelectItem(matchItem); + + m_findPrefix += (wxChar)keyCode; + + // also start the timer to reset the current prefix if the user + // doesn't press any more alnum keys soon -- we wouldn't want + // to use this prefix for a new item search + if ( !m_findTimer ) + { + m_findTimer = new ctlTreeFindTimer(this); + } + + m_findTimer->Start(ctlTreeFindTimer::CTLTREE_DELAY, wxTIMER_ONE_SHOT); + return; + } + } + else + { + event.Skip(true); + } +} + +ctlTree::ctlTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxTreeCtrl(parent, id, pos, size, style), m_findTimer(NULL) +{ +} + +ctlTree::~ctlTree() +{ + if ( m_findTimer ) + delete m_findTimer; + m_findTimer = NULL; +} + + +void ctlTree::RemoveDummyChild(pgObject *obj) +{ + wxCookieType cookie; + wxTreeItemId childItem = GetFirstChild(obj->GetId(), cookie); + if (childItem && !GetItemData(childItem)) + { + // The child was a dummy item, which will be replaced by the following ShowTreeDetail by true items + Delete(childItem); + } +} + + +pgObject *ctlTree::GetObject(wxTreeItemId id) +{ + if (id) + return (pgObject *)GetItemData(id); + return 0; +} + + +pgCollection *ctlTree::GetParentCollection(wxTreeItemId id) +{ + pgCollection *coll = (pgCollection *)GetParentObject(id); + if (coll && coll->IsCollection()) + return coll; + return 0; +} + + +void ctlTree::SetItemImage(const wxTreeItemId &item, int image, wxTreeItemIcon which) +{ + wxTreeCtrl::SetItemImage(item, image, which); + + wxTreeItemData *data = GetItemData(item); + + // Set the item colour + if (data) + { + if (((pgObject *)data)->GetMetaType() == PGM_SERVER) + { + if (!((pgServer *)data)->GetColour().IsEmpty()) + SetItemBackgroundColour(item, wxColour(((pgServer *)data)->GetColour())); + } + else if (((pgObject *)data)->GetServer()) + { + if (!((pgObject *)data)->GetServer()->GetColour().IsEmpty()) + SetItemBackgroundColour(item, wxColour(((pgObject *)data)->GetServer()->GetColour())); + } + } +} + +wxTreeItemId ctlTree::AppendItem(const wxTreeItemId &parent, const wxString &text, int image, int selImage, wxTreeItemData *data) +{ + wxTreeItemId itm = wxTreeCtrl::AppendItem(parent, text, image, selImage, data); + + // Set the item colour + if (data) + { + if (((pgObject *)data)->GetMetaType() == PGM_SERVER) + { + if (!((pgServer *)data)->GetColour().IsEmpty()) + SetItemBackgroundColour(itm, wxColour(((pgServer *)data)->GetColour())); + } + else if (((pgObject *)data)->GetServer()) + { + if (!((pgObject *)data)->GetServer()->GetColour().IsEmpty()) + SetItemBackgroundColour(itm, wxColour(((pgObject *)data)->GetServer()->GetColour())); + } + } + + return itm; +} + +wxTreeItemId ctlTree::AppendObject(pgObject *parent, pgObject *object) +{ + wxString label; + wxTreeItemId item; + + if (object->IsCollection()) + label = object->GetTypeName(); + else + label = object->GetDisplayName(); + item = AppendItem(parent->GetId(), label, object->GetIconId(), -1, object); + if (object->IsCollection()) + object->ShowTreeDetail(this); + else if (object->WantDummyChild()) + AppendItem(object->GetId(), wxT("Dummy")); + + return item; +} + + +pgCollection *ctlTree::AppendCollection(pgObject *parent, pgaFactory &factory) +{ + pgCollection *collection = factory.CreateCollection(parent); + AppendObject(parent, collection); + return collection; +} + + +pgObject *ctlTree::FindObject(pgaFactory &factory, wxTreeItemId parent) +{ + wxCookieType cookie; + wxTreeItemId item = GetFirstChild(parent, cookie); + while (item) + { + pgObject *obj = (pgObject *)GetItemData(item); + if (obj && obj->IsCreatedBy(factory)) + return obj; + item = GetNextChild(parent, cookie); + } + return 0; +} + + +pgCollection *ctlTree::FindCollection(pgaFactory &factory, wxTreeItemId parent) +{ + pgaFactory *cf = factory.GetCollectionFactory(); + if (!cf) + return 0; + + pgCollection *collection = (pgCollection *)FindObject(*cf, parent); + + if (!collection || !collection->IsCollection()) + return 0; + return collection; +} + + +void ctlTree::NavigateTree(int keyCode) +{ + switch(keyCode) + { + case WXK_LEFT: + { + //If tree item has children and is expanded, collapse it, otherwise select it's parent if has one + wxTreeItemId currItem = GetSelection(); + + if (ItemHasChildren(currItem) && IsExpanded(currItem)) + { + Collapse(currItem); + } + else + { + wxTreeItemId parent = GetItemParent(currItem); + if (parent.IsOk()) + { + SelectItem(currItem, false); + SelectItem(parent, true); + } + } + } + break; + case WXK_RIGHT: + { + //If tree item do not have any children ignore it, + //otherwise expand it if not expanded, and select first child if already expanded + wxTreeItemId currItem = GetSelection(); + + if(ItemHasChildren(currItem)) + { + if (!IsExpanded(currItem)) + { + Expand(currItem); + } + else + { + wxCookieType cookie; + wxTreeItemId firstChild = GetFirstChild(currItem, cookie); + SelectItem(currItem, false); + SelectItem(firstChild, true); + } + } + } + break; + default: + wxASSERT_MSG(false, _("Currently handles only right and left arrow key, other keys are working")); + break; + } +} + +////////////////////// + +treeObjectIterator::treeObjectIterator(ctlTree *brow, pgObject *obj) +{ + browser = brow; + object = obj; +} + + +pgObject *treeObjectIterator::GetNextObject() +{ + if (!object || !browser) + return 0; + + if (!lastItem) + lastItem = browser->GetFirstChild(object->GetId(), cookie); + else + lastItem = browser->GetNextChild(object->GetId(), cookie); + + if (lastItem) + return browser->GetObject(lastItem); + else + object = 0; + + return 0; +} diff --git a/ctl/explainCanvas.cpp b/ctl/explainCanvas.cpp new file mode 100644 index 0000000..18a7722 --- /dev/null +++ b/ctl/explainCanvas.cpp @@ -0,0 +1,651 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// explainCanvas.cpp - Explain Canvas +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "ctl/explainCanvas.h" + + +BEGIN_EVENT_TABLE(ExplainCanvas, wxShapeCanvas) + EVT_MOTION(ExplainCanvas::OnMouseMotion) +END_EVENT_TABLE() + + +ExplainCanvas::ExplainCanvas(wxWindow *parent) + : wxShapeCanvas(parent), rootShape(NULL) +{ + SetDiagram(new wxDiagram); + GetDiagram()->SetCanvas(this); + SetBackgroundColour(*wxWHITE); + popup = NULL; +} + + +ExplainCanvas::~ExplainCanvas() +{ +} + + +void ExplainCanvas::Clear() +{ + GetDiagram()->DeleteAllShapes(); + rootShape = NULL; +} + + +void ExplainCanvas::SetExplainString(const wxString &str) +{ + // filtred block never executed + wxString rez=wxT(""); + wxString flt=wxT(""); + wxStringTokenizer tmpstr(str, wxT("\n")); + int p=-1; + while (tmpstr.HasMoreTokens()) + { + wxString tmp = tmpstr.GetNextToken(); + if (p>-1) + { + // áëîê never executed + const wxChar *cp = tmp.c_str(); + int pp=0; + while (pp<=p) + { + if (*cp != ' ') + { + break; + } + cp++; + pp++; + } + if (pp<=p) p=-1; + } + if (p==-1) + { + p=tmp.Find(wxT("->")); + if (p>-1) { + int p2=tmp.Find(wxT("(never executed)")); + if (p2==-1) { + p=-1; + } else + { + continue; + + } + } + flt=flt+tmp+wxT("\n"); + + } + } + + Clear(); + + // We can have multiple plans in a single explain string + // Add a empty root shape, which will never get drawn, but it will help us + // to keep track of all these plans + rootShape = ExplainShape::Create(0, NULL, wxEmptyString); + AddShape(rootShape); + + ExplainShape *last = rootShape; + int maxLevel = 0; + + wxStringTokenizer lines(flt, wxT("\n")); + + while (lines.HasMoreTokens()) + { + wxString tmp = lines.GetNextToken(); + wxString line = tmp.Strip(wxString::both); + int braceCount = 0; + do + { + const wxChar *cp = line.c_str(); + while (*cp) + { + if (*cp == '(') + braceCount++; + else if (*cp == ')') + braceCount--; + cp++; + } + if (braceCount > 0) + { + wxString tmp = lines.GetNextToken(); + line += wxT(" ") + tmp.Strip(wxString::both); + braceCount = 0; + } + else + break; + } + while (lines.HasMoreTokens()); + + long level = ((tmp.Length() - line.Length() + 4) / 6) + 1; + + if (last) + { + if (level != 1) + { + if (line.Left(4) == wxT("-> ")) + line = line.Mid(4); + else + { + last->SetCondition(line); + continue; + } + } + + while (last != rootShape && level <= last->GetLevel()) + last = last->GetUpper(); + } + + + ExplainShape *s = ExplainShape::Create(level, last, line); + if (!s) + continue; + s->SetCanvas(this); + InsertShape(s); + s->Show(true); + + if (level > maxLevel) + maxLevel = level; + + last = s; + } + + + int x0 = (int)(rootShape->GetWidth() * 3); + int y0 = (int)(rootShape->GetHeight() * 3 / 2); + int xoffs = (int)(rootShape->GetWidth() * 3); + int yoffs = (int)(rootShape->GetHeight() * 5 / 4); + + wxNode *current = GetDiagram()->GetShapeList()->GetFirst(); + while (current) + { + ExplainShape *s = (ExplainShape *)current->GetData(); + + if (!s->totalShapes) + s->totalShapes = 1; + if (s->GetUpper()) + s->GetUpper()->totalShapes += s->totalShapes; + current = current->GetNext(); + } + + current = GetDiagram()->GetShapeList()->GetLast(); + while (current) + { + ExplainShape *s = (ExplainShape *)current->GetData(); + + s->SetX(y0 + (maxLevel - s->GetLevel()) * xoffs); + ExplainShape *upper = s->GetUpper(); + + if (upper) + { + s->SetY(upper->GetY() + upper->usedShapes * yoffs); + upper->usedShapes += s->totalShapes; + + // We don't require to draw a line from the root shape to its + // childrens + if (upper != rootShape) + { + wxLineShape *l = new ExplainLine(s, upper); + l->Show(true); + AddShape(l); + } + } + else + { + s->SetY(y0); + } + + current = current->GetPrevious(); + } + +#define PIXPERUNIT 20 + int w = (maxLevel * xoffs + x0 * 2 + PIXPERUNIT - 1) / PIXPERUNIT; + int h = (rootShape->totalShapes * yoffs + y0 * 2 + PIXPERUNIT - 1) / PIXPERUNIT; + + SetScrollbars(PIXPERUNIT, PIXPERUNIT, w, h); +} + + +void ExplainCanvas::OnMouseMotion(wxMouseEvent &ev) +{ + ev.Skip(true); + + if (ev.Dragging()) + return; + + wxClientDC dc(this); + PrepareDC(dc); + + wxPoint logPos(ev.GetLogicalPosition(dc)); + + double x, y; + x = (double) logPos.x; + y = (double) logPos.y; + + // Find the nearest object + int attachment = 0; + ExplainShape *nearestObj = dynamic_cast(FindShape(x, y, &attachment)); + + if (nearestObj) + { + ShowPopup(nearestObj); + } +} + + +void ExplainCanvas::ShowPopup(ExplainShape *s) +{ + if (popup || s == NULL) + return; + + popup = new ExplainPopup(this, s, &popup); + +} + + +void ExplainCanvas::SaveAsImage(const wxString &fileName, wxBitmapType imageType) +{ + if (GetDiagram()->GetCount() == 0) + { + wxMessageBox(_("Nothing to be saved!"), _("Save As an image"), wxOK | wxICON_INFORMATION); + return; + } + + int width = 0, height = 0; + GetVirtualSize(&width, &height); + + /* + * Create the bitmap from the Explain window + */ + wxMemoryDC memDC; + wxBitmap tempBitmap(width, height); + + memDC.SelectObject(tempBitmap); + memDC.Clear(); + + // Draw the diagram on the bitmap (Memory Device Context) + GetDiagram()->Redraw(memDC); + + memDC.SelectObject(wxNullBitmap); + + if (!tempBitmap.SaveFile(fileName, imageType)) + { + wxLogError(_("Could not write file \"%s\": error code %d."), fileName.c_str(), wxSysErrorCode()); + } +} + +class ExplainText : public wxWindow +{ +public: + ExplainText(ExplainPopup *parent, ExplainShape *s); + +protected: + void OnMouseMove(wxMouseEvent &ev); +#ifdef wxUSE_POPUPWIN + void OnMouseLost(wxMouseCaptureLostEvent &ev); +#endif + +private: + ExplainPopup *popup; + void OnPaint(wxPaintEvent &ev); + + wxString m_desc, m_detail, m_condition, m_cost, m_actual; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(ExplainText, wxWindow) + EVT_PAINT(ExplainText::OnPaint) + EVT_MOTION(ExplainText::OnMouseMove) +#ifdef wxUSE_POPUPWIN + EVT_MOUSE_CAPTURE_LOST(ExplainText::OnMouseLost) +#endif +END_EVENT_TABLE() + +ExplainText::ExplainText(ExplainPopup *parent, ExplainShape *s) : wxWindow(parent, -1) +{ + SetBackgroundColour(wxColour(255, 255, 224)); + + popup = parent; + + wxWindowDC dc(this); + dc.SetFont(settings->GetSystemFont()); + + m_desc = s->description; + m_detail = s->detail; + m_condition = s->condition; + m_cost = s->cost; + m_actual = s->actual; + + int w1, w2, h; + dc.GetTextExtent(m_desc, &w1, &h); + + dc.GetTextExtent(m_detail, &w2, &h); + if (w1 < w2) w1 = w2; + dc.GetTextExtent(m_condition, &w2, &h); + if (w1 < w2) w1 = w2; + dc.GetTextExtent(m_cost, &w2, &h); + if (w1 < w2) w1 = w2; + dc.GetTextExtent(m_actual, &w2, &h); + if (w1 < w2) w1 = w2; + + int n = 2; + if (!m_detail.IsEmpty()) + n++; + if (!m_condition.IsEmpty()) + n++; + if (!m_cost.IsEmpty()) + n++; + if (!m_actual.IsEmpty()) + n++; + + if (!h) + h = GetCharHeight(); + + SetSize(GetCharHeight() + w1, GetCharHeight() + h * n + h / 3); +} + +void ExplainText::OnMouseMove(wxMouseEvent &ev) +{ + popup->OnMouseMove(ev); +} + +#ifdef wxUSE_POPUPWIN +void ExplainText::OnMouseLost(wxMouseCaptureLostEvent &ev) +{ + /* + * We will not do anything here. + * But - in order to resolve a weird bug on window, when using + * wxPopupTransientWindow, related to loosing the mouse control, + * was not taken care properly, we have to introduce this function + * to avoid the crash. + * + * Please refer: + * http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/82376 + */ +} +#endif + +void ExplainText::OnPaint(wxPaintEvent &ev) +{ + wxPaintDC dc(this); + + wxFont stdFont = settings->GetSystemFont(); + wxFont boldFont = stdFont; + boldFont.SetWeight(wxBOLD); + + int x = GetCharHeight() / 2; + int y = GetCharHeight() / 2; + int w, yoffs; + dc.GetTextExtent(wxT("Dummy"), &w, &yoffs); + + dc.SetFont(boldFont); + dc.DrawText(m_desc, x, y); + + dc.SetFont(stdFont); + + if (!m_detail.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_detail, x, y); + + } + y += yoffs / 3; + + if (!m_condition.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_condition, x, y); + } + if (!m_cost.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_cost, x, y); + } + if (!m_actual.IsEmpty()) + { + y += yoffs; + dc.DrawText(m_actual, x, y); + } + +#if wxUSE_POPUPWIN + + wxPen pen1 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)), + pen2 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW)), + pen3 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DHIGHLIGHT)), + pen4 = wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW)); + + wxRect rect(wxPoint(0, 0), GetSize()); + + // draw the rectangle + dc.SetPen(pen1); + dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), rect.GetRight(), rect.GetTop()); + dc.SetPen(pen2); + dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom()); + + // adjust the rect + rect.Inflate(-1); + + // draw the rectangle + dc.SetPen(pen3); + dc.DrawLine(rect.GetLeft(), rect.GetTop(), rect.GetLeft(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft() + 1, rect.GetTop(), rect.GetRight(), rect.GetTop()); + dc.SetPen(pen4); + dc.DrawLine(rect.GetRight(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); + dc.DrawLine(rect.GetLeft(), rect.GetBottom(), rect.GetRight() + 1, rect.GetBottom()); + + // adjust the rect + rect.Inflate(-1); + + dc.SetPen(pen1); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRectangle(rect); + +#endif + +} + + +BEGIN_EVENT_TABLE(ExplainPopup, pgTipWindowBase) + EVT_MOTION(ExplainPopup::OnMouseMove) + EVT_LEFT_DOWN(ExplainPopup::OnMouseClick) + EVT_RIGHT_DOWN(ExplainPopup::OnMouseClick) + EVT_MIDDLE_DOWN(ExplainPopup::OnMouseClick) +#if wxUSE_POPUPWIN + EVT_MOUSE_CAPTURE_LOST(ExplainPopup::OnMouseLost) +#else + EVT_KILL_FOCUS(ExplainPopup::OnKillFocus) + EVT_ACTIVATE(ExplainPopup::OnActivate) +#endif // !wxUSE_POPUPWIN +END_EVENT_TABLE() + +ExplainPopup::ExplainPopup(ExplainCanvas *parent, ExplainShape *shape, ExplainPopup **popup) +#if wxUSE_POPUPWIN + : wxPopupTransientWindow(parent, wxNO_BORDER) +#else + : wxFrame(parent, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxNO_BORDER | wxFRAME_NO_TASKBAR ) +#endif +{ + wxASSERT(parent != NULL); + wxASSERT(shape != NULL); + + if (popup) + m_ptr = popup; + else + m_ptr = NULL; + + m_explainText = new ExplainText(this, shape); +#if !wxUSE_POPUPWIN + m_creationTime = wxGetLocalTime(); +#endif + double width = 0.0, height = 0.0; + + shape->GetBoundingBoxMin(&width, &height); + if (fabs(width) < 4.0) width = 4.0; + if (fabs(height) < 4.0) height = 4.0; + + width += (double)4.0; + height += (double)4.0; // Allowance for inaccurate mousing + + int x = (int)(shape->GetX() - (width / 2.0)); + int y = (int)(shape->GetY() - (height / 2.0)); + + int sx, sy; + parent->CalcScrolledPosition(x, y, &sx, &sy); + parent->ClientToScreen(&sx, &sy); + + m_rectBound.x = sx; + m_rectBound.y = sy; + m_rectBound.width = WXROUND(width); + m_rectBound.height = WXROUND(height); + + wxSize popupSize; + popupSize = m_explainText->GetSize(); + popupSize.DecTo(wxGetDisplaySize()); + SetSize(popupSize); + + if (sy > GetClientSize().y * 2 / 3) + sy -= GetSize().y; + sx -= GetSize().x / 2; + + if (sx < 5) sx = 5; + + if (sx < 0) x = 0; + +#if wxUSE_POPUPWIN + Position(wxPoint(sx, sy), wxSize(0, 0)); + Popup(m_explainText); + m_explainText->SetFocus(); +#ifdef __WXGTK__ + m_explainText->CaptureMouse(); +#endif +#else + Move(sx, sy); + Show(true); + + m_explainText->SetFocus(); + m_explainText->CaptureMouse(); +#endif +} + + +void ExplainPopup::OnMouseMove(wxMouseEvent &ev) +{ + if ( m_rectBound.width && + !m_rectBound.Contains(ClientToScreen(ev.GetPosition())) ) + { + // mouse left the bounding rect, disappear + Close(); + } + else + { + ev.Skip(); + } +} + + +void ExplainPopup::OnMouseClick(wxMouseEvent &ev) +{ + Close(); +} + + +ExplainPopup::~ExplainPopup() +{ + if (m_ptr) + { + *m_ptr = NULL; + } +#ifdef wxUSE_POPUPWIN +#ifdef __WXGTK__ + if (m_explainText->HasCapture() ) + m_explainText->ReleaseMouse(); +#endif +#endif + if(HasCapture()) + ReleaseMouse(); +} + +void ExplainPopup::Close() +{ + if (m_ptr) + { + *m_ptr = NULL; + m_ptr = NULL; + } + + if (m_explainText->HasCapture()) + m_explainText->ReleaseMouse(); + + if(HasCapture()) + ReleaseMouse(); + +#if wxUSE_POPUPWIN + Show(false); +#ifdef __WXGTK__ +#endif + Destroy(); +#else + wxFrame::Close(); +#endif +} + + +#if wxUSE_POPUPWIN +void ExplainPopup::OnDismiss() +{ + Close(); +} + +void ExplainPopup::OnMouseLost(wxMouseCaptureLostEvent &ev) +{ + /* Do Nothing */ +} +#else +void ExplainPopup::OnKillFocus(wxFocusEvent &event) +{ + // Workaround the kill focus event happening just after creation in wxGTK + if (wxGetLocalTime() > m_creationTime + 1 && + m_rectBound.width && + !m_rectBound.Contains(::wxGetMousePosition())) + { + Close(); + return; + } + m_explainText->SetFocus(); + m_explainText->CaptureMouse(); +} + + +void ExplainPopup::OnActivate(wxActivateEvent &event) +{ + if (!event.GetActive()) + { + if ( m_rectBound.width && + !m_rectBound.Contains(::wxGetMousePosition()) ) + { + Close(); + return; + } + m_explainText->SetFocus(); + m_explainText->CaptureMouse(); + } +} +#endif // !wxUSE_POPUPWIN diff --git a/ctl/explainShape.cpp b/ctl/explainShape.cpp new file mode 100644 index 0000000..48a8068 --- /dev/null +++ b/ctl/explainShape.cpp @@ -0,0 +1,581 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// explainShape.cpp - Explain Shapes +// +////////////////////////////////////////////////////////////////////////// + + + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/explainCanvas.h" + +#include + +#include "images/ex_aggregate.pngc" +#include "images/ex_append.pngc" +#include "images/ex_bmp_and.pngc" +#include "images/ex_bmp_heap.pngc" +#include "images/ex_bmp_index.pngc" +#include "images/ex_bmp_or.pngc" +#include "images/ex_cte_scan.pngc" +#include "images/ex_delete.pngc" +#include "images/ex_foreign_scan.pngc" +#include "images/ex_group.pngc" +#include "images/ex_hash.pngc" +#include "images/ex_hash_anti_join.pngc" +#include "images/ex_hash_semi_join.pngc" +#include "images/ex_hash_setop_except.pngc" +#include "images/ex_hash_setop_except_all.pngc" +#include "images/ex_hash_setop_intersect.pngc" +#include "images/ex_hash_setop_intersect_all.pngc" +#include "images/ex_hash_setop_unknown.pngc" +#include "images/ex_index_only_scan.pngc" +#include "images/ex_index_scan.pngc" +#include "images/ex_insert.pngc" +#include "images/ex_lock_rows.pngc" +#include "images/ex_join.pngc" +#include "images/ex_limit.pngc" +#include "images/ex_materialize.pngc" +#include "images/ex_merge.pngc" +#include "images/ex_merge_anti_join.pngc" +#include "images/ex_merge_append.pngc" +#include "images/ex_merge_semi_join.pngc" +#include "images/ex_gatcher.pngc" +#include "images/ex_nested.pngc" +#include "images/ex_nested_loop_anti_join.pngc" +#include "images/ex_nested_loop_semi_join.pngc" +#include "images/ex_recursive_union.pngc" +#include "images/ex_result.pngc" +#include "images/ex_scan.pngc" +#include "images/ex_pscan.pngc" +#include "images/ex_seek.pngc" +#include "images/ex_setop.pngc" +#include "images/ex_sort.pngc" +#include "images/ex_subplan.pngc" +#include "images/ex_tid_scan.pngc" +#include "images/ex_unique.pngc" +#include "images/ex_unknown.pngc" +#include "images/ex_update.pngc" +#include "images/ex_values_scan.pngc" +#include "images/ex_window_aggregate.pngc" +#include "images/ex_worktable_scan.pngc" + +// Greenplum images +#include "images/ex_broadcast_motion.pngc" +#include "images/ex_redistribute_motion.pngc" +#include "images/ex_gather_motion.pngc" + +#define BMP_BORDER 3 + +ExplainShape::ExplainShape(const wxImage &bmp, const wxString &description, long tokenNo, long detailNo) +{ + SetBitmap(wxBitmap(bmp)); + SetLabel(description, tokenNo, detailNo); + kidCount = 0; + totalShapes = 0; + usedShapes = 0; + m_rootShape = false; +} + + +void ExplainShape::SetLabel(const wxString &str, int tokenNo, int detailNo) +{ + if (tokenNo < 0) + { + description = str; + label = str; + } + else + { + wxStringTokenizer tokens(str, wxT(" ")); + + while (tokenNo-- >= 0) + { + label = tokens.GetNextToken(); + + if (detailNo <= 0) + { + if (!description.IsEmpty()) + description.Append(wxT(" ")); + + description.Append(label); + } + } + if (detailNo > 0) + { + tokens.SetString(str, wxT(" ")); + + while (detailNo--) + { + if (!description.IsEmpty()) + description.Append(wxT(" ")); + + description.Append(tokens.GetNextToken()); + } + detail = tokens.GetString(); + } + } +} + +void ExplainShape::OnDraw(wxDC &dc) +{ + wxBitmap &bmp = GetBitmap(); + if (!bmp.Ok()) + return; + + // We do not draw the root shape + if (m_rootShape) + return; + + int x, y; + x = WXROUND(m_xpos - bmp.GetWidth() / 2.0); + y = WXROUND(m_ypos - GetHeight() / 2.0); + + dc.DrawBitmap(bmp, x, y, true); + + int w, h; + dc.SetFont(GetCanvas()->GetFont()); + dc.GetTextExtent(label, &w, &h); + + x = WXROUND(m_xpos - w / 2.0); + y += bmp.GetHeight() + BMP_BORDER; + + dc.DrawText(label, x, y); +} + + +void ExplainShape::OnLeftClick(double x, double y, int keys, int attachment) +{ + ((ExplainCanvas *)GetCanvas())->ShowPopup(this); +} + + +#define ARROWMARGIN 5 +wxRealPoint ExplainShape::GetStartPoint() +{ + wxRealPoint rp(GetX() + GetBitmap().GetWidth() / 2.0 + ARROWMARGIN, GetY() - (GetHeight() - GetBitmap().GetHeight()) / 2.); + return rp; +} + + +wxRealPoint ExplainShape::GetEndPoint(int kidNo) +{ + wxRealPoint rp(GetX() - GetBitmap().GetWidth() / 2.0 - ARROWMARGIN, GetY() - (GetHeight() - GetBitmap().GetHeight()) / 2. + (kidCount > 1 ? GetBitmap().GetHeight() * 2. / 3. * kidNo / (2 * kidCount - 2) : 0 )); + return rp; +} + + + +ExplainShape *ExplainShape::Create(long level, ExplainShape *last, const wxString &str) +{ + ExplainShape *s = 0; + + int costPos = str.Find(wxT("(cost=")); + int actPos = str.Find(wxT("(actual")); + bool parallel=false; + int inc=0; + wxStringTokenizer tokens(str, wxT(" ")); + wxString token = tokens.GetNextToken(); + if (token == wxT("Parallel")) + { + token = tokens.GetNextToken(); + parallel=true; + inc=1; + } + + wxString token2 = tokens.GetNextToken(); + wxString token3 = tokens.GetNextToken(); + wxString token4; + if (tokens.HasMoreTokens()) + token4 = tokens.GetNextToken(); + wxString descr; + if (costPos > 0) + descr = str.Left(costPos); + else if (actPos > 0) + descr = str.Left(actPos); + else + descr = str; + + // Requested an empty shape, which can be treated as a root shape + if (level == 0) + { + s = new ExplainShape(*ex_unknown_png_img, wxEmptyString); + s->SetDraggable(false); + s->m_rootShape = true; + s->level = level; + int w = 50, h = 20; + + wxBitmap &bmp = s->GetBitmap(); + if (w < bmp.GetWidth()) + w = bmp.GetWidth(); + + s->SetHeight(bmp.GetHeight() + BMP_BORDER + h); + s->SetWidth(w); + + s->upperShape = NULL; + s->kidNo = 0; + + return s; + } + + + // possible keywords can be found in postgresql/src/backend/commands/explain.c + + if (token == wxT("Total")) return 0; + else if (token == wxT("Trigger")) return 0; + else if (token == wxT("Settings:")) return 0; /* Greenplum */ + else if (token == wxT("Slice")) return 0; /* Greenplum */ + else if (token.Mid(0, 6) == wxT("(slice")) return 0; /* Greenplum */ + else if (token == wxT("Result")) s = new ExplainShape(*ex_result_png_img, descr); + else if (token == wxT("Append")) s = new ExplainShape(*ex_append_png_img, descr); + else if (token == wxT("Gather")) s = new ExplainShape(*ex_gatcher_png_img, descr); + else if (token == wxT("Nested")) + { + if (token2 == wxT("Loop") && token4 == wxT("Join")) + { + // Nested Loop Anti Join + if (token3 == wxT("Anti")) + { + s = new ExplainShape(*ex_nested_loop_anti_join_png_img, descr); + } + // Nested Loop Semi Join + else + { + s = new ExplainShape(*ex_nested_loop_semi_join_png_img, descr); + } + } + if (!s) + s = new ExplainShape(*ex_nested_png_img, descr); + } + else if (token == wxT("Merge")) + { + if (token3 == wxT("Join")) + { + // Merge Anti Join + if (token2 == wxT("Anti")) + { + s = new ExplainShape(*ex_merge_anti_join_png_img, descr); + } + // Merge Semi Join + else + { + s = new ExplainShape(*ex_merge_semi_join_png_img, descr); + } + } + // Merge Append + else if (token2 == wxT("Append")) + { + s = new ExplainShape(*ex_merge_append_png_img, descr); + } + else + { + s = new ExplainShape(*ex_merge_png_img, descr); + } + } + else if (token == wxT("Hash")) + { + if (token2 == wxT("Join")) + { + s = new ExplainShape(*ex_join_png_img, descr); + } + else + { + if (token3 == wxT("Join")) + { + // Hash Anti Join + if (token2 == wxT("Anti")) + { + s = new ExplainShape(*ex_hash_anti_join_png_img, descr); + } + // Hash Semi Join + else if (token2 == wxT("Semi")) + { + s = new ExplainShape(*ex_hash_semi_join_png_img, descr); + } + else + { + s = new ExplainShape(*ex_hash_png_img, descr); + } + } + else + { + s = new ExplainShape(*ex_hash_png_img, descr); + } + } + } + else if (token == wxT("HashSetOp")) + { + if (token2 == wxT("Except")) + { + // HashSetOp Except ALL + if (token3 == wxT("ALL")) + { + s = new ExplainShape(*ex_hash_setop_except_all_png_img, descr); + } + // HashSetOp Except + else + { + s = new ExplainShape(*ex_hash_setop_except_png_img, descr); + } + } + else if (token2 == wxT("Intersect")) + { + // HashSetOp Intersect ALL + if (token3 == wxT("ALL")) + { + s = new ExplainShape(*ex_hash_setop_intersect_all_png_img, descr); + } + // HashSetOp Intersect + else + { + s = new ExplainShape(*ex_hash_setop_intersect_png_img, descr); + } + } + else + { + // HashSetOp ??? + s = new ExplainShape(*ex_hash_setop_unknown_png_img, descr); + } + } + else if (token == wxT("Subquery")) s = new ExplainShape(*ex_subplan_png_img, descr, 0, 2); + else if (token == wxT("Function")) s = new ExplainShape(*ex_result_png_img, descr, 0, 2); + else if (token == wxT("Materialize")) s = new ExplainShape(*ex_materialize_png_img, descr); + else if (token == wxT("Sort")) s = new ExplainShape(*ex_sort_png_img, descr); + else if (token == wxT("Group")) s = new ExplainShape(*ex_group_png_img, descr); + else if (token == wxT("Aggregate") || token == wxT("GroupAggregate") || token == wxT("HashAggregate")) + s = new ExplainShape(*ex_aggregate_png_img, descr); + else if (token == wxT("Unique")) s = new ExplainShape(*ex_unique_png_img, descr); + else if (token == wxT("SetOp")) s = new ExplainShape(*ex_setop_png_img, descr); + else if (token == wxT("Limit")) s = new ExplainShape(*ex_limit_png_img, descr); + else if (token == wxT("LockRows")) s = new ExplainShape(*ex_lock_rows_png_img, descr); + else if (token == wxT("Bitmap")) + { + if (token2 == wxT("Index")) s = new ExplainShape(*ex_bmp_index_png_img, descr, 4+inc, 3+inc); + else s = new ExplainShape(*ex_bmp_heap_png_img, descr, 4+inc, 3+inc); + } + else if (token == wxT("BitmapAnd")) s = new ExplainShape(*ex_bmp_and_png_img, descr); + else if (token == wxT("BitmapOr")) s = new ExplainShape(*ex_bmp_or_png_img, descr); + else if (token2 == wxT("Scan")) + { + if (token == wxT("Index")) + // Scan Index Backward + if (token3 == wxT("Backward")) + s = new ExplainShape(*ex_index_scan_png_img, descr, 4+inc, 3+inc); + else + s = new ExplainShape(*ex_index_scan_png_img, descr, 3+inc, 2+inc); + // Tid Scan + else if (token == wxT("Tid")) + s = new ExplainShape(*ex_tid_scan_png_img, descr, 3+inc, 2+inc); + // WorkTable Scan + else if (token == wxT("WorkTable")) + s = new ExplainShape(*ex_worktable_scan_png_img, descr, 3+inc, 2+inc); + // CTE Scan + else if (token == wxT("CTE")) + s = new ExplainShape(*ex_cte_scan_png_img, descr, 3, 2); + // Foreign Scan + else if (token == wxT("Foreign")) + s = new ExplainShape(*ex_foreign_scan_png_img, descr, 3, 2); + // Values Scan + else if (token == wxT("Values")) + s = new ExplainShape(*ex_values_scan_png_img, descr, 3, 2); + else if (parallel) s = new ExplainShape(*ex_pscan_png_img, descr, 4, 3); + else + s = new ExplainShape(*ex_scan_png_img, descr, 3+inc, 2+inc); + } + else if (token == wxT("Index")) + { + // Index Only Scan + if (token2 == wxT("Only") && token3 == wxT("Scan")) + { + s = new ExplainShape(*ex_index_only_scan_png_img, descr, 4+inc, 3+inc); + } + } + else if (token2 == wxT("Seek")) s = new ExplainShape(*ex_seek_png_img, descr, 3, 2); + // Recursive Union + else if (token == wxT("Recursive") && token2 == wxT("Union")) + s = new ExplainShape(*ex_recursive_union_png_img, descr); + else if (token == wxT("WindowAgg")) + s = new ExplainShape(*ex_window_aggregate_png_img, descr); + + // DML + else if (token == wxT("Insert")) + s = new ExplainShape(*ex_insert_png_img, descr, 2, 1); + else if (token == wxT("Update")) + s = new ExplainShape(*ex_update_png_img, descr, 2, 1); + else if (token == wxT("Delete")) + s = new ExplainShape(*ex_delete_png_img, descr, 2, 1); + + // Greenplum additions + else if (token == wxT("Gather") && token2 == wxT("Motion")) + s = new ExplainShape(*ex_gather_motion_png_img, descr); + else if (token == wxT("Broadcast") && token2 == wxT("Motion")) + s = new ExplainShape(*ex_broadcast_motion_png_img, descr); + else if (token == wxT("Redistribute") && token2 == wxT("Motion")) + s = new ExplainShape(*ex_redistribute_motion_png_img, descr); + + if (!s) + s = new ExplainShape(*ex_unknown_png_img, descr); + + s->SetDraggable(false); + + s->level = level; + + if (costPos > 0) + { + if (actPos > 0) + { + s->actual = str.Mid(actPos); + s->cost = str.Mid(costPos, actPos - costPos); + } + else + s->cost = str.Mid(costPos); + } + else if (actPos > 0) + s->actual = str.Mid(actPos); + + int w = 50, h = 20; + + wxBitmap &bmp = s->GetBitmap(); + if (w < bmp.GetWidth()) + w = bmp.GetWidth(); + + s->SetHeight(bmp.GetHeight() + BMP_BORDER + h); + s->SetWidth(w); + + s->upperShape = last; + if (last) + { + s->kidNo = last->kidCount; + last->kidCount++; + } + else + s->kidNo = 0; + + if (costPos > 0) + { + wxChar *cl = const_cast((const wxChar *)str + costPos + 6); + wxChar *ch = wxStrstr(cl, wxT("..")); + if (ch) + { + *ch = 0; + ch += 2; + } + s->costLow = StrToDouble(cl); + if (ch) + { + wxChar *r = wxStrstr(ch, wxT(" rows=")); + if (r) + { + *r = 0; + r += 6; + } + s->costHigh = StrToDouble(ch); + if (r) + { + wxChar *w = wxStrstr(r, wxT(" width=")); + if (w) + { + *w = 0; + w += 7; + } + s->rows = StrToLong(r); + if (w) + s->width = StrToLong(w); + } + } + } + return s; +} + + +ExplainLine::ExplainLine(ExplainShape *from, ExplainShape *to, double weight) +{ + SetCanvas(from->GetCanvas()); + from->AddLine(this, to); + MakeLineControlPoints(4); + + width = (int) log(from->GetAverageCost()); + if (width > 10) + width = 10; + + // If we got an average cost of 0, width is probably negative + // which will look pretty darn ugly as an arrow width! + // This may happen on Greenplum. + if (width < 1) + width = 1; + + wxNode *first = GetLineControlPoints()->GetFirst(); + wxNode *last = GetLineControlPoints()->GetLast(); + *(wxRealPoint *)first->GetData() = from->GetStartPoint(); + *(wxRealPoint *)last->GetData() = to->GetEndPoint(from->GetKidno()); + + wxRealPoint *p1 = (wxRealPoint *)first->GetNext()->GetData(); + wxRealPoint *p2 = (wxRealPoint *)last->GetPrevious()->GetData(); + *p1 = from->GetStartPoint(); + *p2 = to->GetEndPoint(from->GetKidno()); + p1->x -= (p1->x - p2->x) / 3. + 8; + p2->x += (p1->x - p2->x) / 3. - 8; + + Initialise(); +} + + +#define ARROWWIDTH 4 + + +void ExplainLine::OnDraw(wxDC &dc) +{ + if (m_lineControlPoints) + { + dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1, wxSOLID)); + dc.SetBrush(*wxTheBrushList->FindOrCreateBrush(*wxLIGHT_GREY, wxSOLID)); + + wxPoint *points = new wxPoint[11]; + wxRealPoint *point0 = (wxRealPoint *) m_lineControlPoints->Item(0)->GetData(); + wxRealPoint *point1 = (wxRealPoint *) m_lineControlPoints->Item(1)->GetData(); + wxRealPoint *point2 = (wxRealPoint *) m_lineControlPoints->Item(2)->GetData(); + wxRealPoint *point3 = (wxRealPoint *) m_lineControlPoints->Item(3)->GetData(); + + double phi = atan2(point2->y - point1->y, point2->x - point1->x); + double offs = width * tan(phi / 2); + + points[0].x = WXROUND(point0->x); + points[0].y = WXROUND(point0->y) - width; + points[10].x = WXROUND(point0->x); + points[10].y = WXROUND(point0->y) + width; + + points[1].x = WXROUND(point1->x + offs); + points[1].y = WXROUND(point1->y) - width; + points[9].x = WXROUND(point1->x - offs); + points[9].y = WXROUND(point1->y) + width; + + points[2].x = WXROUND(point2->x + offs); + points[2].y = WXROUND(point2->y) - width; + points[8].x = WXROUND(point2->x - offs); + points[8].y = WXROUND(point2->y) + width; + + points[3].x = WXROUND(point3->x) - width - ARROWWIDTH; + points[3].y = WXROUND(point3->y) - width; + points[7].x = WXROUND(point3->x) - width - ARROWWIDTH; + points[7].y = WXROUND(point3->y) + width; + + points[4].x = points[3].x; + points[4].y = points[3].y - ARROWWIDTH; + points[6].x = points[7].x; + points[6].y = points[7].y + ARROWWIDTH; + + points[5].x = WXROUND(point3->x); + points[5].y = WXROUND(point3->y); + + dc.DrawPolygon(11, points, 0, 0); + } +} diff --git a/ctl/module.mk b/ctl/module.mk new file mode 100644 index 0000000..66e9bbe --- /dev/null +++ b/ctl/module.mk @@ -0,0 +1,42 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/ctl/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + ctl/calbox.cpp \ + ctl/ctlAuiNotebook.cpp \ + ctl/ctlCheckTreeView.cpp \ + ctl/ctlColourPicker.cpp \ + ctl/ctlComboBox.cpp \ + ctl/ctlListView.cpp \ + ctl/ctlMenuToolbar.cpp \ + ctl/ctlSQLBox.cpp \ + ctl/ctlSQLGrid.cpp \ + ctl/ctlSQLResult.cpp \ + ctl/ctlDefaultSecurityPanel.cpp \ + ctl/ctlSeclabelPanel.cpp \ + ctl/ctlSecurityPanel.cpp \ + ctl/ctlTree.cpp \ + ctl/ctlProgressStatusBar.cpp \ + ctl/explainCanvas.cpp \ + ctl/explainShape.cpp \ + ctl/timespin.cpp \ + ctl/xh_calb.cpp \ + ctl/xh_ctlcolourpicker.cpp \ + ctl/xh_ctlcombo.cpp \ + ctl/xh_ctlchecktreeview.cpp \ + ctl/xh_ctltree.cpp \ + ctl/xh_sqlbox.cpp \ + ctl/xh_timespin.cpp + +EXTRA_DIST += \ + ctl/module.mk + + diff --git a/ctl/timespin.cpp b/ctl/timespin.cpp new file mode 100644 index 0000000..ac6b025 --- /dev/null +++ b/ctl/timespin.cpp @@ -0,0 +1,461 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// timespin.cpp - timeSpin SpinCtrl +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include "ctl/timespin.h" + + +#define CTRLID_TXT 101 +#define CTRLID_SPN 102 + + +BEGIN_EVENT_TABLE(wxTimeSpinCtrl, wxControl) + EVT_TEXT(CTRLID_TXT, wxTimeSpinCtrl::OnText) + EVT_NAVIGATION_KEY(wxTimeSpinCtrl::OnNavigate) + EVT_SPIN_UP(CTRLID_SPN, wxTimeSpinCtrl::OnSpinUp) + EVT_SPIN_DOWN(CTRLID_SPN, wxTimeSpinCtrl::OnSpinDown) + EVT_SPIN(CTRLID_SPN, wxTimeSpinCtrl::OnSpin) + EVT_SET_FOCUS(wxTimeSpinCtrl::OnSetFocus) + EVT_SIZE(wxTimeSpinCtrl::OnSize) +END_EVENT_TABLE() + + +IMPLEMENT_DYNAMIC_CLASS(wxTimeSpinCtrl, wxControl) + + +wxTimeSpinCtrl::wxTimeSpinCtrl(wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + Init(); + Create(parent, id, pos, size, style, name); +} + + +bool wxTimeSpinCtrl::Create(wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name) +{ + wxControl::Create(parent, id, pos, size, style & ~(wxSP_WRAP | wxSP_ARROW_KEYS), wxDefaultValidator, name); + SetFont(parent->GetFont()); + + m_spn = new wxSpinButton(this, CTRLID_SPN, wxDefaultPosition, wxDefaultSize, wxSP_WRAP | wxSP_VERTICAL | (style & wxSP_ARROW_KEYS)); + + wxSize cs = GetClientSize(); + wxSize ss = m_spn->GetBestSize(); + + m_txt = new wxTextCtrl(this, CTRLID_TXT, wxEmptyString, wxPoint(0, 0), wxSize(cs.x - ss.x, cs.y), wxWANTS_CHARS); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(wxTimeSpinCtrl::OnEditKey), 0, this); + m_txt->Connect(wxID_ANY, wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(wxTimeSpinCtrl::OnKillFocus), 0, this); + + wxArrayString valArray; + wxChar c; + for (c = '0'; c <= '9'; c++) + valArray.Add(wxString(c, 1)); + valArray.Add(wxT(":")); + wxTextValidator tv(wxFILTER_INCLUDE_CHAR_LIST); + tv.SetIncludes(valArray); + m_txt->SetValidator(tv); + + m_spn->SetSize(ss.x, cs.y); + m_spn->SetPosition(wxPoint(cs.x - ss.x, 0)); + + canWrap = (style & wxSP_WRAP) != 0; + SetMax(24 * 60 * 60 - 1); + + SetInitialSize(size); + + return true; +} + +#define TXTPOSX 0 +#define TXTPOSY 0 +void wxTimeSpinCtrl::OnSize(wxSizeEvent &event) +{ + if ( m_spn ) + { + wxSize sz = GetClientSize(); + + wxSize ss = m_spn->GetSize(); + int eh = m_txt->GetBestSize().y; + + m_txt->SetSize(TXTPOSX, TXTPOSY, sz.x - ss.x - TXTPOSX, sz.y > eh ? eh - TXTPOSY : sz.y - TXTPOSY); + m_spn->SetSize(sz.x - ss.x, 0, ss.x, sz.y); + } + + event.Skip(); +} + + +bool wxTimeSpinCtrl::Destroy() +{ + if (m_txt) + { + m_txt->Destroy(); + m_txt = NULL; + } + if (m_spn) + { + m_spn->Destroy(); + m_spn = NULL; + } + return true; +} + + +void wxTimeSpinCtrl::Init() +{ + m_txt = NULL; + m_spn = NULL; + spinValue = 0; +} + + +wxSize wxTimeSpinCtrl::DoGetBestSize() const +{ +#ifdef __WXGTK__ + return wxSize(100, m_spn->GetBestSize().y); +#else + return wxSize(100, m_txt->GetBestSize().y); +#endif +} + + +bool wxTimeSpinCtrl::Enable(bool enable) +{ + m_txt->Enable(enable); + m_spn->Enable(enable); + + return true; +} + +void wxTimeSpinCtrl::SetMax(long seconds, bool useDay) +{ + hasDay = useDay; + if (hasDay) + m_format = wxT("%D:%H:%M:%S"); + else + m_format = wxT("%H:%M:%S"); + maxSpinValue = seconds + 1; + if (maxSpinValue < 2) + maxSpinValue = 2; + m_spn->SetRange(0, 32767); +} + + +bool wxTimeSpinCtrl::SetTime(const wxDateTime &time) +{ + if (time.IsValid()) + { + wxDateTime tt(time); + tt.ResetTime(); + return SetValue(time - tt); + } + else + { + m_txt->SetValue(wxEmptyString); + return false; + } +} + + +bool wxTimeSpinCtrl::SetValue(const wxTimeSpan &span) +{ + m_txt->SetValue(span.Format(m_format)); + spinValue = span.GetSeconds().GetLo(); + return true; +} + + + +wxTimeSpan wxTimeSpinCtrl::GetValue() +{ + return wxTimeSpan(0, 0, spinValue); +} + + +int wxTimeSpinCtrl::GetTimePart() +{ + wxString strAfter = m_txt->GetRange(m_txt->GetInsertionPoint(), 9999); + int cnt = 0; + const wxChar *p = (const wxChar *)strAfter; + while (*p) + { + if (*p++ == ':') + cnt++; + } + return cnt; +} + + +void wxTimeSpinCtrl::Highlight(int tp) +{ + wxString txt = m_txt->GetValue(); + long from = 0, to; + int i; + + for (i = 3 - tp - (hasDay ? 0 : 1) ; i > 0 ; i--) + from += txt.Mid(from).Find(':') + 1; + + to = txt.Mid(from).Find(':') + from; + if (to < from) + to = 999; + + m_txt->SetSelection(from, to); +} + + +void wxTimeSpinCtrl::OnSpinUp(wxSpinEvent &ev) +{ +#ifdef __WXMSW__ + m_txt->SetFocus(); +#endif + DoSpin(1); +} + +void wxTimeSpinCtrl::OnSpinDown(wxSpinEvent &ev) +{ +#ifdef __WXMSW__ + m_txt->SetFocus(); +#endif + DoSpin(-1); +} + + +void wxTimeSpinCtrl::OnSpin(wxSpinEvent &ev) +{ + wxCommandEvent parentSpinEvt(ev.GetEventType(), this->GetId()); + this->GetEventHandler()->AddPendingEvent(parentSpinEvt); +} + +void wxTimeSpinCtrl::DoSpin(int diff) +{ + int tp = GetTimePart(); + long oldValue = 0, maxValue = 0, mult = 0; + + switch (tp) + { + case 0: + oldValue = spinValue; + maxValue = 60; + mult = 1; + break; + case 1: + oldValue = spinValue / 60; + maxValue = 60; + mult = 60; + break; + + case 2: + oldValue = spinValue / 60 / 60; + if (hasDay) + maxValue = 24; + else + maxValue = maxSpinValue / 60 / 60; + mult = 60 * 60; + break; + case 3: + oldValue = spinValue / 60 / 60 / 24; + maxValue = maxSpinValue / 60 / 60 / 24; + mult = 60 * 60 * 24; + break; + default: + // can't happen + break; + } + oldValue %= maxValue; + int newValue = oldValue + diff; + + if (!canWrap) + { + if (newValue < 0) + diff += maxValue; + else if (newValue >= maxValue) + diff -= maxValue; + } + + long newSpinValue = spinValue + diff * mult; + if (newSpinValue < 0) + newSpinValue = maxSpinValue - 1; + else if (newSpinValue > maxSpinValue) + newSpinValue = 0; + + if (spinValue != newSpinValue) + { + spinValue = newSpinValue; + wxTimeSpan span(0, 0, spinValue); + wxString txt = span.Format(m_format); + m_txt->SetValue(txt); + Highlight(tp); + + wxSpinEvent ev; + ev.SetEventObject(this); + ev.SetId(GetId()); + +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + } +} + + +void wxTimeSpinCtrl::OnText(wxCommandEvent &ev) +{ + long time = GetTextTime(); + if (time >= 0) + { + spinValue = time; + ev.SetEventObject(this); + ev.SetId(GetId()); +#if wxCHECK_VERSION(2, 9, 0) + GetParent()->GetEventHandler()->ProcessEvent(ev); +#else + GetParent()->ProcessEvent(ev); +#endif + } +} + + +void wxTimeSpinCtrl::OnNavigate(wxNavigationKeyEvent &ev) +{ + if (wxWindow::FindFocus() == m_txt) + { + int tp = GetTimePart(); + if (ev.GetDirection()) + tp++; + else + tp--; + if ((tp >= 0 && tp < 3) || (hasDay && tp == 3)) + { + Highlight(tp); + return; + } + } + ev.Skip(); +} + + +void wxTimeSpinCtrl::OnEditKey(wxKeyEvent &ev) +{ + if (!ev.HasModifiers()) + { + switch(ev.GetKeyCode()) + { + case WXK_LEFT: + { + if (!ev.ShiftDown()) + { + int tp = GetTimePart() + 1; + if (tp < 3 || (hasDay && tp == 3)) + { + Highlight(tp); + return; + } + } + break; + } + case WXK_RIGHT: + { + if (!ev.ShiftDown()) + { + int tp = GetTimePart() - 1; + if (tp >= 0) + { + Highlight(tp); + return; + } + } + break; + } + case WXK_UP: + DoSpin(1); + return; + break; + case WXK_DOWN: + DoSpin(-1); + return; + break; + default: + break; + } + } + ev.Skip(); +} + + +long wxTimeSpinCtrl::GetTextTime() +{ + int t1, t2, t3, t4; + int scanned = wxSscanf(m_txt->GetValue(), wxT("%d:%d:%d:%d"), &t1, &t2, &t3, &t4); + + switch (scanned) + { + case 1: + if (t1 >= 0) + return t1; + break; + case 2: + if (t1 >= 0 && t2 >= 0 && t2 < 60) + return t1 * 60 + t2; + break; + case 3: + if (t1 >= 0 && t2 >= 0 && t2 < 60 && t3 >= 0 && t3 < 60) + return (t1 * 60 + t2) * 60 + t3; + break; + case 4: + if (t1 >= 0 && t2 >= 0 && t2 < 24 && t3 >= 0 && t3 < 60 && t4 >= 0 && t4 < 60) + return ((t1 * 24 + t2) * 60 + t3) * 60 + t4; + break; + default: + break; + } + return -1; +} + + +void wxTimeSpinCtrl::OnKillFocus(wxFocusEvent &ev) +{ +#ifdef __WXGTK__ + ev.Skip(); +#endif + + long time = GetTextTime(); + + if (time < 0) + { + m_txt->SetValue(wxEmptyString); + spinValue = 0; + m_spn->SetValue(0); + } + else + { + int tp = GetTimePart(); + SetValue(wxTimeSpan(0, 0, time)); + Highlight(tp); + } +} + + +void wxTimeSpinCtrl::OnSetFocus(wxFocusEvent &ev) +{ + m_txt->SetFocus(); + Highlight(hasDay ? 3 : 2); +} diff --git a/ctl/xh_calb.cpp b/ctl/xh_calb.cpp new file mode 100644 index 0000000..271b094 --- /dev/null +++ b/ctl/xh_calb.cpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_calb.cpp - wxCalendarBox handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/xh_calb.h" +#include "ctl/calbox.h" + + +IMPLEMENT_DYNAMIC_CLASS(wxCalendarBoxXmlHandler, wxXmlResourceHandler) + +wxCalendarBoxXmlHandler::wxCalendarBoxXmlHandler() + : wxXmlResourceHandler() +{ + /* + * Only available with the wxDatePickerCtrl + */ + XRC_ADD_STYLE(wxDP_DEFAULT); + XRC_ADD_STYLE(wxDP_SPIN); + XRC_ADD_STYLE(wxDP_DROPDOWN); + XRC_ADD_STYLE(wxDP_ALLOWNONE); + XRC_ADD_STYLE(wxDP_SHOWCENTURY); + + AddWindowStyles(); +} + + +wxObject *wxCalendarBoxXmlHandler::DoCreateResource() +{ + XRC_MAKE_INSTANCE(calendar, wxCalendarBox); + +#if pgUSE_WX_CAL + calendar->Create(m_parentAsWindow, + GetID(), + wxDefaultDateTime, + GetPosition(), GetSize(), + wxDP_DEFAULT | wxDP_SHOWCENTURY | wxDP_ALLOWNONE, + wxDefaultValidator, + GetName()); + +#else // pgUSE_WX_CAL +#if !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL + calendar->Create(m_parentAsWindow, + GetID(), + wxDefaultDateTime, + GetPosition(), GetSize(), + GetStyle(), + GetName()); +#else // !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL + calendar->Create(m_parentAsWindow, + (wxWindowID)GetID(), + wxDefaultDateTime, + GetPosition(), GetSize(), + (long int)GetStyle(), + wxDefaultValidator, + GetName()); +#endif // !defined(wxUSE_DATEPICKCTRL) || !wxUSE_DATEPICKCTRL +#endif // pgUSE_WX_CAL + + SetupWindow(calendar); + + return calendar; +} + +bool wxCalendarBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("wxCalendarBox")); +} diff --git a/ctl/xh_ctlchecktreeview.cpp b/ctl/xh_ctlchecktreeview.cpp new file mode 100644 index 0000000..ef44934 --- /dev/null +++ b/ctl/xh_ctlchecktreeview.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlchecktreeview.cpp - ctlCheckTreeView handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/ctlCheckTreeView.h" +#include "ctl/xh_ctlchecktreeview.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlCheckTreeViewXmlHandler, wxTreeCtrlXmlHandler) + + +wxObject *ctlCheckTreeViewXmlHandler::DoCreateResource() +{ + ctlCheckTreeView *ctl = new ctlCheckTreeView(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlCheckTreeViewXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlCheckTreeView")); +} diff --git a/ctl/xh_ctlcolourpicker.cpp b/ctl/xh_ctlcolourpicker.cpp new file mode 100644 index 0000000..51e8607 --- /dev/null +++ b/ctl/xh_ctlcolourpicker.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// xh_ctlcolourpicker.cpp - ctlColourPicker handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/ctlColourPicker.h" +#include "ctl/xh_ctlcolourpicker.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlColourPickerXmlHandler, wxBitmapButtonXmlHandler) + + +wxObject *ctlColourPickerXmlHandler::DoCreateResource() +{ + ctlColourPicker *ctl = new ctlColourPicker(m_parentAsWindow, GetID(), GetPosition(), GetSize()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlColourPickerXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlColourPicker")); +} diff --git a/ctl/xh_ctlcombo.cpp b/ctl/xh_ctlcombo.cpp new file mode 100644 index 0000000..5fc0025 --- /dev/null +++ b/ctl/xh_ctlcombo.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlcombo.cpp - ctlComboBox handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/ctlComboBox.h" +#include "ctl/xh_ctlcombo.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlComboBoxXmlHandler, wxComboBoxXmlHandler) + + +wxObject *ctlComboBoxXmlHandler::DoCreateResource() +{ + ctlComboBox *ctl = new ctlComboBox(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlComboBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlComboBox")); +} diff --git a/ctl/xh_ctltree.cpp b/ctl/xh_ctltree.cpp new file mode 100644 index 0000000..2efd446 --- /dev/null +++ b/ctl/xh_ctltree.cpp @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctltree.cpp - ctlTree handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" + +#include "utils/misc.h" +#include "ctl/ctlTree.h" +#include "ctl/xh_ctltree.h" + +IMPLEMENT_DYNAMIC_CLASS(ctlTreeXmlHandler, wxTreeCtrlXmlHandler) + + +wxObject *ctlTreeXmlHandler::DoCreateResource() +{ + ctlTree *ctl = new ctlTree(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(ctl); + + return ctl; +} + +bool ctlTreeXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlTree")); +} diff --git a/ctl/xh_sqlbox.cpp b/ctl/xh_sqlbox.cpp new file mode 100644 index 0000000..3d615a9 --- /dev/null +++ b/ctl/xh_sqlbox.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_sqlbox.cpp - ctlSQLBox handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/xh_sqlbox.h" +#include "ctl/ctlSQLBox.h" + + +IMPLEMENT_DYNAMIC_CLASS(ctlSQLBoxXmlHandler, wxXmlResourceHandler) + +ctlSQLBoxXmlHandler::ctlSQLBoxXmlHandler() + : wxXmlResourceHandler() +{ + XRC_ADD_STYLE(wxTE_MULTILINE); + XRC_ADD_STYLE(wxSIMPLE_BORDER); + XRC_ADD_STYLE(wxSUNKEN_BORDER); + XRC_ADD_STYLE(wxTE_RICH2); + + AddWindowStyles(); +} + + +wxObject *ctlSQLBoxXmlHandler::DoCreateResource() +{ + ctlSQLBox *sqlbox = new ctlSQLBox(m_parentAsWindow, GetID(), GetPosition(), GetSize(), GetStyle()); + + SetupWindow(sqlbox); + + return sqlbox; +} + +bool ctlSQLBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("ctlSQLBox")); +} diff --git a/ctl/xh_timespin.cpp b/ctl/xh_timespin.cpp new file mode 100644 index 0000000..6c1cb3d --- /dev/null +++ b/ctl/xh_timespin.cpp @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_timespin.cpp - wxTimeSpinCtrl handler +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "wx/wx.h" +#include "ctl/timespin.h" +#include "ctl/xh_timespin.h" + + +IMPLEMENT_DYNAMIC_CLASS(wxTimeSpinXmlHandler, wxXmlResourceHandler) + +wxTimeSpinXmlHandler::wxTimeSpinXmlHandler() + : wxXmlResourceHandler() +{ + XRC_ADD_STYLE(wxSP_WRAP); + XRC_ADD_STYLE(wxSP_ARROW_KEYS); + + AddWindowStyles(); +} + + +wxObject *wxTimeSpinXmlHandler::DoCreateResource() +{ + XRC_MAKE_INSTANCE(timespin, wxTimeSpinCtrl); + + timespin->Create(m_parentAsWindow, + GetID(), + GetPosition(), GetSize(), + GetStyle(), + GetName()); + + SetupWindow(timespin); + + return timespin; +} + +bool wxTimeSpinXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("wxTimeSpinCtrl")); +} diff --git a/db/keywords.c b/db/keywords.c new file mode 100644 index 0000000..f9adb83 --- /dev/null +++ b/db/keywords.c @@ -0,0 +1,152 @@ +/*------------------------------------------------------------------------- + * + * keywords.c + * lexical token lookup for reserved words in PostgreSQL + * + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.177 2006/10/07 21:51:02 petere Exp $ + * + *------------------------------------------------------------------------- + */ + +/////////////////////////////////////////////////////////////////////////// +// +// pgAdmin note: This file is based on src/backend/parser/keywords.c and +// src/backend/parser/kwlookup.c from PostgreSQL, but extended +// to support EntepriseDB and Greenplum. +// +// This file is under the BSD licence, per PostgreSQL. +/////////////////////////////////////////////////////////////////////////// + +#include "postgres.h" +#include "parser/keywords.h" + +/* + * List of (keyword-name, keyword-token-value) pairs. + */ +#define PG_KEYWORD(a,b,c) {a,c}, +const ScanKeyword ScanKeywords[] = { +#include +}; +const int NumScanKeywords = lengthof(ScanKeywords); + +/* + * Additional pairs here. They need to live in a separate array since + * the ScanKeywords array needs to be sorted! + * + * !!WARNING!!: This list must be sorted, because binary + * search is used to locate entries. + */ +#define PG_KEYWORD2(a,b) {a,b}, +const ScanKeyword ScanKeywordsExtra[] = { + PG_KEYWORD2("connect", RESERVED_KEYWORD) + PG_KEYWORD2("convert", RESERVED_KEYWORD) + PG_KEYWORD2("distributed", UNRESERVED_KEYWORD) + PG_KEYWORD2("exec", RESERVED_KEYWORD) + PG_KEYWORD2("log", UNRESERVED_KEYWORD) + PG_KEYWORD2("long", RESERVED_KEYWORD) + PG_KEYWORD2("minus", RESERVED_KEYWORD) + PG_KEYWORD2("nocache", RESERVED_KEYWORD) + PG_KEYWORD2("number", RESERVED_KEYWORD) + PG_KEYWORD2("package", RESERVED_KEYWORD) + PG_KEYWORD2("pls_integer", RESERVED_KEYWORD) + PG_KEYWORD2("raw", RESERVED_KEYWORD) + PG_KEYWORD2("return", RESERVED_KEYWORD) + PG_KEYWORD2("smalldatetime", RESERVED_KEYWORD) + PG_KEYWORD2("smallfloat", RESERVED_KEYWORD) + PG_KEYWORD2("smallmoney", RESERVED_KEYWORD) + PG_KEYWORD2("sysdate", RESERVED_KEYWORD) + PG_KEYWORD2("systimestap", RESERVED_KEYWORD) + PG_KEYWORD2("tinyint", RESERVED_KEYWORD) + PG_KEYWORD2("tinytext", RESERVED_KEYWORD) + PG_KEYWORD2("varchar2", RESERVED_KEYWORD) +}; +const int NumScanKeywordsExtra = lengthof(ScanKeywordsExtra); + +/* + * ScanKeywordLookup - see if a given word is a keyword + * + * Returns a pointer to the ScanKeyword table entry, or NULL if no match. + * + * The match is done case-insensitively. Note that we deliberately use a + * dumbed-down case conversion that will only translate 'A'-'Z' into 'a'-'z', + * even if we are in a locale where tolower() would produce more or different + * translations. This is to conform to the SQL99 spec, which says that + * keywords are to be matched in this way even though non-keyword identifiers + * receive a different case-normalization mapping. + */ +const ScanKeyword * +ScanKeywordLookup(const char *text) +{ + int len, + i; + char word[NAMEDATALEN]; + const ScanKeyword *low; + const ScanKeyword *high; + + len = strlen(text); + /* We assume all keywords are shorter than NAMEDATALEN. */ + if (len >= NAMEDATALEN) + return NULL; + + /* + * Apply an ASCII-only downcasing. We must not use tolower() since it may + * produce the wrong translation in some locales (eg, Turkish). + */ + for (i = 0; i < len; i++) + { + char ch = text[i]; + + if (ch >= 'A' && ch <= 'Z') + ch += 'a' - 'A'; + word[i] = ch; + } + word[len] = '\0'; + + /* + * Now do a binary search using plain strcmp() comparison. + */ + low = &ScanKeywords[0]; + high = endof(ScanKeywords) - 1; + while (low <= high) + { + const ScanKeyword *middle; + int difference; + + middle = low + (high - low) / 2; + difference = strcmp(middle->name, word); + if (difference == 0) + return middle; + else if (difference < 0) + low = middle + 1; + else + high = middle - 1; + } + + /* + * If not found, also do a binary search in the list of extra + * keywords. + */ + low = &ScanKeywordsExtra[0]; + high = endof(ScanKeywordsExtra) - 1; + while (low <= high) + { + const ScanKeyword *middle; + int difference; + + middle = low + (high - low) / 2; + difference = strcmp(middle->name, word); + if (difference == 0) + return middle; + else if (difference < 0) + low = middle + 1; + else + high = middle - 1; + } + + return NULL; +} diff --git a/db/module.mk b/db/module.mk new file mode 100644 index 0000000..84324ba --- /dev/null +++ b/db/module.mk @@ -0,0 +1,20 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/db/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + db/keywords.c \ + db/pgConn.cpp \ + db/pgSet.cpp \ + db/pgQueryThread.cpp + +EXTRA_DIST += \ + db/module.mk + diff --git a/db/pgConn.cpp b/db/pgConn.cpp new file mode 100644 index 0000000..3a8705a --- /dev/null +++ b/db/pgConn.cpp @@ -0,0 +1,1344 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConn.cpp - PostgreSQL Connection class +// +///////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// PostgreSQL headers +#include +#include "utils/pgfeatures.h" + +// Network headers +#ifdef __WXMSW__ +#include +typedef u_long in_addr_t; + +#else + +#include +#include +#include + +#ifndef INADDR_NONE +#define INADDR_NONE (-1) +#endif + +#endif + +// App headers +#include "utils/misc.h" +#include "utils/sysLogger.h" +#include "db/pgConn.h" +#include "utils/misc.h" +#include "db/pgSet.h" + +double pgConn::libpqVersion = 8.0; + +static void pgNoticeProcessor(void *arg, const char *message) +{ + ((pgConn *)arg)->Notice(message); +} + +pgConn::pgConn(const wxString &server, const wxString &service, const wxString &hostaddr, const wxString &database, const wxString &username, const wxString &password, + int port, const wxString &rolename, int sslmode, OID oid, const wxString &applicationname, + const wxString &sslcert, const wxString &sslkey, const wxString &sslrootcert, const wxString &sslcrl, + const bool sslcompression) : m_cancelConn(NULL) +{ + wxString msg; + + save_server = server; + save_hostaddr = hostaddr; + save_service = service; + save_database = database; + save_username = username; + save_password = password; + save_port = port; + save_rolename = rolename; + save_sslmode = sslmode; + save_oid = oid; + save_applicationname = applicationname; + save_sslcert = sslcert; + save_sslkey = sslkey; + save_sslrootcert = sslrootcert; + save_sslcrl = sslcrl; + save_sslcompression = sslcompression; + + memset(features, 0, sizeof(features)); + majorVersion = 0; + + conv = &wxConvLibc; + needColQuoting = false; + utfConnectString = false; + + // Check the hostname/ipaddress + conn = 0; + noticeArg = 0; + connStatus = PGCONN_BAD; + + // Create the connection string + if (!server.IsEmpty()) + { + connstr.Append(wxT(" host=")); + connstr.Append(qtConnString(server)); + } + if (!hostaddr.IsEmpty()) + { + connstr.Append(wxT(" hostaddr=")); + connstr.Append(qtConnString(hostaddr)); + } + if (!service.IsEmpty()) + { + connstr.Append(wxT(" service=")); + connstr.Append(qtConnString(service)); + } + if (!database.IsEmpty()) + { + connstr.Append(wxT(" dbname=")); + connstr.Append(qtConnString(database)); + } + if (!username.IsEmpty()) + { + connstr.Append(wxT(" user=")); + connstr.Append(qtConnString(username)); + } + if (!password.IsEmpty()) + { + connstr.Append(wxT(" password=")); + connstr.Append(qtConnString(password)); + } + + if (port > 0) + { + connstr.Append(wxT(" port=")); + connstr.Append(NumToStr((long)port)); + } + + if (libpqVersion > 7.3) + { + switch (sslmode) + { + case 1: + connstr.Append(wxT(" sslmode=require")); + break; + case 2: + connstr.Append(wxT(" sslmode=prefer")); + break; + case 3: + connstr.Append(wxT(" sslmode=allow")); + break; + case 4: + connstr.Append(wxT(" sslmode=disable")); + break; + case 5: + connstr.Append(wxT(" sslmode=verify-ca")); + break; + case 6: + connstr.Append(wxT(" sslmode=verify-full")); + break; + } + } + else + { + switch (sslmode) + { + case 1: + connstr.Append(wxT(" requiressl=1")); + break; + case 2: + connstr.Append(wxT(" requiressl=0")); + break; + } + } + + if (libpqVersion > 8.3 && sslmode != 4) + { + if (!sslcert.IsEmpty()) + { + connstr.Append(wxT(" sslcert=")); + connstr.Append(qtConnString(sslcert)); + } + if (!sslkey.IsEmpty()) + { + connstr.Append(wxT(" sslkey=")); + connstr.Append(qtConnString(sslkey)); + } + if (!sslrootcert.IsEmpty()) + { + connstr.Append(wxT(" sslrootcert=")); + connstr.Append(qtConnString(sslrootcert)); + } + if (!sslcrl.IsEmpty()) + { + connstr.Append(wxT(" sslcrl=")); + connstr.Append(qtConnString(sslcrl)); + } + } + + if (libpqVersion > 9.1 && sslmode != 4) + { + if (!sslcompression) + { + connstr.Append(wxT(" sslcompression=0")); + } + } + + connstr.Trim(false); + + dbHost = server; + dbHostName = server; + dbRole = rolename; + +#ifdef HAVE_CONNINFO_PARSE + if (!applicationname.IsEmpty()) + { + // Check connection string with application_name + char *errmsg; + wxString connstr_with_applicationname = connstr + wxT(" application_name='") + applicationname + wxT("'"); + if (PQconninfoParse(connstr_with_applicationname.mb_str(wxConvUTF8), &errmsg)) + { + connstr = connstr_with_applicationname; + } + else if (PQconninfoParse(connstr_with_applicationname.mb_str(wxConvLibc), &errmsg)) + { + connstr = connstr_with_applicationname; + } + } +#endif + + // Open the connection + wxString cleanConnStr = connstr; + cleanConnStr.Replace(qtConnString(password), wxT("'XXXXXX'")); + wxLogInfo(wxT("Opening connection with connection string: %s"), cleanConnStr.c_str()); + + DoConnect(); +} + + +pgConn::~pgConn() +{ + Close(); +} + + +bool pgConn::DoConnect() +{ + wxCharBuffer cstrUTF = connstr.mb_str(wxConvUTF8); + conn = PQconnectdb(cstrUTF); + if (PQstatus(conn) == CONNECTION_OK) + utfConnectString = true; + else + { + wxCharBuffer cstrLibc = connstr.mb_str(wxConvLibc); + if (strcmp(cstrUTF, cstrLibc)) + { + PQfinish(conn); + conn = PQconnectdb(cstrLibc); + } + } + + if (!Initialize()) + return false; + + return true; +} + + +bool pgConn::Initialize() +{ + // Set client encoding to Unicode/Ascii, Datestyle to ISO, and ask for notices. + if (PQstatus(conn) == CONNECTION_OK) + { + connStatus = PGCONN_OK; + PQsetNoticeProcessor(conn, pgNoticeProcessor, this); + + wxString sql = wxT("SET DateStyle=ISO;\nSET client_min_messages=notice;\n"); + if (!save_applicationname.Contains("query")) sql += wxT("SET lock_timeout=15000;\n"); + //if (BackendMinimumVersion(9, 0)) sql += wxT("SET bytea_output=escape;\n"); + + sql += wxT("SELECT oid, pg_encoding_to_char(encoding) AS encoding, datlastsysoid\n") + wxT(" FROM pg_database WHERE "); + + if (save_oid) + sql += wxT("oid = ") + NumToStr(save_oid); + else + { + // Note, can't use qtDbString here as we don't know the server version yet. + wxString db = save_database; + db.Replace(wxT("\\"), wxT("\\\\")); + db.Replace(wxT("'"), wxT("''")); + sql += wxT("datname=") + qtString(db); + } + + pgSet *set = ExecuteSet(sql); + if (set) + { + if (set->ColNumber(wxT("\"datlastsysoid\"")) >= 0) + needColQuoting = true; + + lastSystemOID = set->GetOid(wxT("datlastsysoid")); + dbOid = set->GetOid(wxT("oid")); + wxString encoding = set->GetVal(wxT("encoding")); + + if (encoding != wxT("SQL_ASCII") && encoding != wxT("MULE_INTERNAL")) + { + encoding = wxT("UNICODE"); + conv = &wxConvUTF8; + } + else + conv = &wxConvLibc; + + wxLogInfo(wxT("Setting client_encoding to '%s'"), encoding.c_str()); + if (PQsetClientEncoding(conn, encoding.ToAscii())) + { + wxLogError(wxT("%s"), GetLastError().c_str()); + } + + delete set; + + // Switch to the requested default role if supported by backend + if (dbRole != wxEmptyString && BackendMinimumVersion(8, 1)) + { + sql = wxT("SET ROLE TO "); + sql += qtIdent(dbRole); + + pgSet *set = ExecuteSet(sql); + + if (set) + delete set; + else + return false; + } + return true; + } + } + return false; +} + + +void pgConn::Close() +{ + if (conn) + { + CancelExecution(); + PQfinish(conn); + } + conn = 0; + connStatus = PGCONN_BAD; +} + + +// Reconnect to the server +bool pgConn::Reconnect() +{ + // Close the existing (possibly broken) connection + Close(); + + // Reset any vars that need to be in a defined state before connecting + needColQuoting = false; + + // Attempt the reconnect + if (!DoConnect()) + { + wxLogError(_("Failed to re-establish the connection to the server %s"), GetName().c_str()); + return false; + } + + return true; +} + + +pgConn *pgConn::Duplicate(const wxString &_appName) +{ + pgConn *res = new pgConn(wxString(save_server), wxString(save_service), + wxString(save_hostaddr), wxString(save_database), wxString(save_username), + wxString(save_password), save_port, save_rolename, save_sslmode, save_oid, + _appName.IsEmpty() ? save_applicationname : _appName, save_sslcert, save_sslkey, + save_sslrootcert, save_sslcrl, save_sslcompression); + + // Save the version and features information from the existing connection + res->majorVersion = majorVersion; + res->minorVersion = minorVersion; + res->patchVersion = patchVersion; + res->isEdb = isEdb; + res->isGreenplum = isGreenplum; + res->isHawq = isHawq; + res->reservedNamespaces = reservedNamespaces; + + for (size_t index = FEATURE_INITIALIZED; index < FEATURE_LAST; index++) + res->features[index] = features[index]; + + return res; +} + + +// Return the SSL mode name +wxString pgConn::GetSslModeName() +{ + switch (save_sslmode) + { + case 1: + return wxT("require"); + case 2: + return wxT("prefer"); + case 3: + return wxT("allow"); + case 4: + return wxT("disable"); + case 5: + return wxT("verify-ca"); + case 6: + return wxT("verify-full"); + default: + return wxT("prefer"); + } +} + +bool pgConn::GetIsEdb() +{ + // to retrieve edb flag + BackendMinimumVersion(0, 0); + return isEdb; +} +bool pgConn::GetIsPgProEnt() +{ + // to retrieve edb flag + BackendMinimumVersion(0, 0); + return isPgProEnt; +} + +bool pgConn::GetIsGreenplum() +{ + // to retrieve Greenplum flag + BackendMinimumVersion(0, 0); + return isGreenplum; +} + +bool pgConn::GetIsHawq() +{ + // to retrieve Greenplum HAWQ flag + BackendMinimumVersion(0, 0); + return isHawq; +} + +wxString pgConn::SystemNamespaceRestriction(const wxString &nsp) +{ + if (reservedNamespaces.IsEmpty()) + { + reservedNamespaces = wxT("'information_schema'"); + + if (GetIsEdb()) + reservedNamespaces += wxT(", 'sys'"); + + pgSet *set = ExecuteSet( + wxT("SELECT nspname FROM pg_namespace nsp\n") + wxT(" JOIN pg_proc pr ON pronamespace=nsp.oid\n") + wxT(" WHERE proname IN ('slonyversion')")); + if (set) + { + while (!set->Eof()) + { + reservedNamespaces += wxT(", ") + qtDbString(set->GetVal(wxT("nspname"))); + set->MoveNext(); + } + delete set; + } + } + + if (BackendMinimumVersion(8, 1)) + return wxT("(") + nsp + wxT(" NOT LIKE E'pg\\_%' AND ") + nsp + wxT(" NOT in (") + reservedNamespaces + wxT("))"); + else + return wxT("(") + nsp + wxT(" NOT LIKE 'pg\\_%' AND ") + nsp + wxT(" NOT in (") + reservedNamespaces + wxT("))"); +} + +bool pgConn::HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv) +{ + wxString res = ExecuteScalar( + wxT("SELECT has_") + objTyp.Lower() + + wxT("_privilege(") + qtDbString(objName) + + wxT(", ") + qtDbString(priv) + wxT(")")); + + return StrToBool(res); +} + +bool pgConn::IsSuperuser() +{ + wxString res = ExecuteScalar( + wxT("SELECT rolsuper FROM pg_roles ") + wxT("WHERE rolname='") + qtIdent(GetUser()) + wxT("'")); + + return StrToBool(res); +} + +bool pgConn::BackendMinimumVersion(int major, int minor) +{ + if (GetStatus() != PGCONN_OK) + return false; + if (!majorVersion) + { + wxString version = GetVersionString(); + sscanf(version.ToAscii(), "%*s %d.%d.%d", &majorVersion, &minorVersion, &patchVersion); + isEdb = version.Upper().Matches(wxT("ENTERPRISEDB*")); + if (version.Upper().Matches(wxT("*11BETA*"))) { + majorVersion=11; + minorVersion=0; + } + // EnterpriseDB 8.3 beta 1 & 2 and possibly later actually have PostgreSQL 8.2 style + // catalogs. This is expected to change either before GA, but in the meantime we + // need to check the catalogue version in more detail, and if we don't see what looks + // like a 8.3 catalog, force the version number back to 8.2. Yuck. + if (isEdb && majorVersion == 8 && minorVersion == 3) + { + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_attribute WHERE attname = 'proconfig' AND attrelid = 'pg_proc'::regclass")) == wxT("0")) + minorVersion = 2; + } + isPgProEnt=false; + wxString ed=ExecuteScalar(wxT("select to_regproc('pgpro_edition')::text")); + if (!ed.IsEmpty()) ed=ExecuteScalar(wxT("select pgpro_edition()")); + if (ed==wxT("enterprise")) isPgProEnt=true; + + isGreenplum = version.Upper().Matches(wxT("*GREENPLUM DATABASE*")); + isHawq = version.Upper().Matches(wxT("*GREENPLUM DATABASE*")) && version.Upper().Matches(wxT("*HAWQ*"));; + } + + return majorVersion > major || (majorVersion == major && minorVersion >= minor); + +} + + +// Greenplum sometimes adds features in patch releases, because Greenplum +// releases are not coordinated with PostgreSQL minor releases. +bool pgConn::BackendMinimumVersion(int major, int minor, int patch) +{ + if (!majorVersion) + BackendMinimumVersion(0, 0); + + return majorVersion > major || (majorVersion == major && minorVersion > minor) || (majorVersion == major && minorVersion == minor && patchVersion >= patch); + +} + + +bool pgConn::EdbMinimumVersion(int major, int minor) +{ + return BackendMinimumVersion(major, minor) && GetIsEdb(); +} + + +bool pgConn::HasFeature(int featureNo, bool forceCheck) +{ + if (!features[FEATURE_INITIALIZED] || forceCheck) + { + features[FEATURE_INITIALIZED] = true; + + wxString sql = + wxT("SELECT proname, pronargs, proargtypes[0] AS arg0, proargtypes[1] AS arg1, proargtypes[2] AS arg2\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proname IN ('pg_tablespace_size', 'pg_file_read', 'pg_logfile_rotate',") + wxT( " 'pg_postmaster_starttime', 'pg_terminate_backend', 'pg_reload_conf',") + wxT( " 'pgstattuple', 'pgstatindex')\n") + wxT(" AND nspname IN ('pg_catalog', 'public')"); + + pgSet *set = ExecuteSet(sql); + + if (set) + { + while (!set->Eof()) + { + wxString proname = set->GetVal(wxT("proname")); + long pronargs = set->GetLong(wxT("pronargs")); + + if (proname == wxT("pg_tablespace_size") && pronargs == 1 && set->GetLong(wxT("arg0")) == 26) + features[FEATURE_SIZE] = true; + else if (proname == wxT("pg_file_read") && pronargs == 3 && set->GetLong(wxT("arg0")) == 25 + && set->GetLong(wxT("arg1")) == 20 && set->GetLong(wxT("arg2")) == 20) + features[FEATURE_FILEREAD] = true; + else if (proname == wxT("pg_logfile_rotate") && pronargs == 0) + features[FEATURE_ROTATELOG] = true; + else if (proname == wxT("pg_postmaster_starttime") && pronargs == 0) + features[FEATURE_POSTMASTER_STARTTIME] = true; + else if (proname == wxT("pg_terminate_backend") && pronargs == 1 && set->GetLong(wxT("arg0")) == 23) + features[FEATURE_TERMINATE_BACKEND] = true; + else if (proname == wxT("pg_reload_conf") && pronargs == 0) + features[FEATURE_RELOAD_CONF] = true; + else if (proname == wxT("pgstattuple") && pronargs == 1 && set->GetLong(wxT("arg0")) == 25) + features[FEATURE_PGSTATTUPLE] = true; + else if (proname == wxT("pgstatindex") && pronargs == 1 && set->GetLong(wxT("arg0")) == 25) + features[FEATURE_PGSTATINDEX] = true; + + set->MoveNext(); + } + delete set; + } + + // Check for EDB function parameter default support + wxString defCol = wxT("'proargdefaults'"); + + if (EdbMinimumVersion(8, 3) && !EdbMinimumVersion(8, 4)) + defCol = wxT("'proargdefvals'"); + + wxString hasFuncDefs = ExecuteScalar(wxT("SELECT count(*) FROM pg_attribute WHERE attrelid = 'pg_catalog.pg_proc'::regclass AND attname = ") + defCol); + if (hasFuncDefs == wxT("1")) + features[FEATURE_FUNCTION_DEFAULTS] = true; + else + features[FEATURE_FUNCTION_DEFAULTS] = false; + } + + if (featureNo <= FEATURE_INITIALIZED || featureNo >= FEATURE_LAST) + return false; + return features[featureNo]; +} + + +// Encrypt a password using the appropriate encoding conversion +wxString pgConn::EncryptPassword(const wxString &user, const wxString &password) +{ + char *chrPassword; + wxString strPassword; + + chrPassword = PQencryptPassword(password.mb_str(*conv), user.mb_str(*conv)); + strPassword = wxString::FromAscii(chrPassword); + + PQfreemem(chrPassword); + + return strPassword; +} + +wxString pgConn::qtDbString(const wxString &value) +{ + wxString result = value; + + result.Replace(wxT("\\"), wxT("\\\\")); + result.Replace(wxT("'"), wxT("''")); + result.Append(wxT("'")); + + if (BackendMinimumVersion(8, 1)) + { + if (result.Contains(wxT("\\"))) + result.Prepend(wxT("E'")); + else + result.Prepend(wxT("'")); + } + else + result.Prepend(wxT("'")); + + return result; +} + +void pgConn::ExamineLibpqVersion() +{ + libpqVersion = 7.3; + PQconninfoOption *cio = PQconndefaults(); + + if (cio) + { + PQconninfoOption *co = cio; + while (co->keyword) + { + if (!strcmp(co->keyword, "sslmode")) + { + if (libpqVersion < 7.4) + libpqVersion = 7.4; + } + if (!strcmp(co->keyword, "sslrootcert")) + { + if (libpqVersion < 8.4) + libpqVersion = 8.4; + } + if (!strcmp(co->keyword, "sslcompression")) + { + if (libpqVersion < 9.2) + libpqVersion = 9.2; + } + co++; + } + PQconninfoFree(cio); + } +} + +wxString pgConn::GetName() const +{ + wxString str; + if (save_service.IsEmpty()) + { + if (dbHost.IsEmpty()) + str.Printf(_("%s on local socket"), save_database.c_str()); + else + str.Printf(_("%s on %s@%s:%d"), save_database.c_str(), GetUser().c_str(), dbHost.c_str(), GetPort()); + } + else + str.Printf(_("service %s"), save_service.c_str()); + + + return str; +} + +#ifdef PG_SSL +// we don't define USE_SSL so we don't get ssl.h included +extern "C" +{ + extern void *PQgetssl(PGconn *conn); +} + +bool pgConn::IsSSLconnected() +{ + return (conn && PQstatus(conn) == CONNECTION_OK && PQgetssl(conn) != NULL); +} +#else + +bool pgConn::IsSSLconnected() +{ + return false ; +} +#endif + + +void pgConn::RegisterNoticeProcessor(PQnoticeProcessor proc, void *arg) +{ + noticeArg = arg; + noticeProc = proc; +} + + + + +void pgConn::Notice(const char *msg) +{ + if (noticeArg && noticeProc) + (*noticeProc)(noticeArg, msg); + else + { + wxString str(msg, *conv); + + // Display the notice if required + if (settings->GetShowNotices()) + wxMessageBox(str, _("Notice"), wxICON_INFORMATION | wxOK); + + wxLogNotice(wxT("%s"), str.Trim().c_str()); + } +} + + +pgNotification *pgConn::GetNotification() +{ + pgNotify *notify; + + notify = PQnotifies(conn); + if (!notify) + return NULL; + + pgNotification *ret = new pgNotification; + ret->name = wxString(notify->relname, *conv); + ret->pid = notify->be_pid; + ret->data = wxString(notify->extra, *conv); + + return ret; +} + +int pgConn::GetTxStatus() +{ + return PQtransactionStatus(conn); +} + +////////////////////////////////////////////////////////////////////////// +// Execute SQL +////////////////////////////////////////////////////////////////////////// + +bool pgConn::ExecuteVoid(const wxString &sql, bool reportError) +{ + if (GetStatus() != PGCONN_OK) + return false; + + // Execute the query and get the status. + PGresult *qryRes; + + wxLogSql(wxT("Void query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); + + SetConnCancel(); + qryRes = PQexec(conn, sql.mb_str(*conv)); + ResetConnCancel(); + + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_TUPLES_OK && + lastResultStatus != PGRES_COMMAND_OK) + { + LogError(!reportError); + PQclear(qryRes); + return false; + } + + // Cleanup & exit + PQclear(qryRes); + return true; +} + + + +wxString pgConn::ExecuteScalar(const wxString &sql, bool reportError) +{ + wxString result; + + if (GetStatus() == PGCONN_OK) + { + // Execute the query and get the status. + PGresult *qryRes; + wxLogSql(wxT("Scalar query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); + + SetConnCancel(); + qryRes = PQexec(conn, sql.mb_str(*conv)); + ResetConnCancel(); + + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_TUPLES_OK && lastResultStatus != PGRES_COMMAND_OK) + { + LogError(!reportError); + PQclear(qryRes); + return wxEmptyString; + } + + // Check for a returned row + if (PQntuples(qryRes) < 1) + { + wxLogInfo(wxT("Query returned no tuples")); + PQclear(qryRes); + return wxEmptyString; + } + + // Retrieve the query result and return it. + result = wxString(PQgetvalue(qryRes, 0, 0), *conv); + + wxLogSql(wxT("Query result: %s"), result.c_str()); + + // Cleanup & exit + PQclear(qryRes); + } + + return result; +} + +pgSet *pgConn::ExecuteSet(const wxString &sql, bool reportError) +{ + // Execute the query and get the status. + if (GetStatus() == PGCONN_OK) + { + PGresult *qryRes; + wxLogSql(wxT("Set query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), sql.c_str()); + + SetConnCancel(); + qryRes = PQexec(conn, sql.mb_str(*conv)); + ResetConnCancel(); + + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + if (lastResultStatus == PGRES_TUPLES_OK || lastResultStatus == PGRES_COMMAND_OK) + { + pgSet *set = new pgSet(qryRes, this, *conv, needColQuoting); + if (!set) + { + if (reportError) + wxLogError(_("Couldn't create a pgSet object!")); + else + wxLogQuietError(_("Couldn't create a pgSet object!")); + PQclear(qryRes); + } + return set; + } + else + { + LogError(!reportError); + PQclear(qryRes); + } + } + return new pgSet(); +} + +////////////////////////////////////////////////////////////////////////// +// COPY functions +////////////////////////////////////////////////////////////////////////// + +bool pgConn::StartCopy(const wxString query) +{ + if (GetStatus() != PGCONN_OK) + return false; + + // Execute the query and get the status + PGresult *qryRes; + + wxLogSql(wxT("COPY query (%s:%d): %s"), this->GetHost().c_str(), this->GetPort(), query.c_str()); + qryRes = PQexec(conn, query.mb_str(*conv)); + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_COPY_IN) + { + LogError(false); + PQclear(qryRes); + return false; + } + + // NO cleanup & exit + return true; +} + +bool pgConn::PutCopyData(const char *data, long count) +{ + // Execute the query and get the status + int result = PQputCopyData(conn, data, count); + + return result == 1; +} + +bool pgConn::EndPutCopy(const wxString errormsg) +{ + int result; + + // Execute the query and get the status + if (errormsg.Length() == 0) + result = PQputCopyEnd(conn, NULL); + else + result = PQputCopyEnd(conn, errormsg.mb_str(*conv)); + + return result == 1; +} + +bool pgConn::GetCopyFinalStatus(void) +{ + PGresult *qryRes; + + // Get status + qryRes = PQgetResult(conn); + lastResultStatus = PQresultStatus(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_COMMAND_OK) + { + LogError(false); + PQclear(qryRes); + return false; + } + + // Cleanup & exit + PQclear(qryRes); + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Info +////////////////////////////////////////////////////////////////////////// + +wxString pgConn::GetLastError() const +{ + wxString errmsg; + char *pqErr; + if (conn && (pqErr = PQerrorMessage(conn)) != 0) + { + errmsg = wxString(pqErr, wxConvUTF8); + if (errmsg.IsNull()) + errmsg = wxString(pqErr, wxConvLibc); + } + else + { + if (connStatus == PGCONN_BROKEN) + errmsg = _("Connection to database broken."); + else + errmsg = _("No connection to database."); + } + return errmsg; +} + + + +void pgConn::LogError(const bool quiet) +{ + if (conn) + { + if (quiet) + { + wxLogQuietError(wxT("%s"), GetLastError().Trim().c_str()); + } + else + { + wxLogError(wxT("%s"), GetLastError().Trim().c_str()); + IsAlive(); + } + } +} + + + +bool pgConn::IsAlive() +{ + if (GetStatus() != PGCONN_OK) + { + if (conn) + { + PQfinish(conn); + conn = 0; + connStatus = PGCONN_BROKEN; + } + return false; + } + + PGresult *qryRes = PQexec(conn, "SELECT 1;"); + lastResultStatus = PQresultStatus(qryRes); + if (lastResultStatus != PGRES_TUPLES_OK) + { + PQclear(qryRes); + qryRes = PQexec(conn, "ROLLBACK TRANSACTION; SELECT 1;"); + lastResultStatus = PQresultStatus(qryRes); + SetLastResultError(qryRes); + } + PQclear(qryRes); + + // Check for errors + if (lastResultStatus != PGRES_TUPLES_OK) + { + PQfinish(conn); + conn = 0; + connStatus = PGCONN_BROKEN; + return false; + } + + return true; +} + + +int pgConn::GetStatus() const +{ + if (!this) + return PGCONN_BAD; + + if (conn) + ((pgConn *)this)->connStatus = PQstatus(conn); + + return connStatus; +} + + +void pgConn::Reset() +{ + PQreset(conn); + + // Reset any vars that need to be in a defined state before connecting + needColQuoting = false; + + Initialize(); +} + + +void pgConn::SetConnCancel(void) +{ + wxMutexLocker lock(m_cancelConnMutex); + PGcancel *oldCancelConn = m_cancelConn; + + m_cancelConn = NULL; + + if (oldCancelConn != NULL) + PQfreeCancel(oldCancelConn); + + if (!conn) + return; + + m_cancelConn = PQgetCancel(conn); + +} + + +void pgConn::ResetConnCancel(void) +{ + wxMutexLocker lock(m_cancelConnMutex); + PGcancel *oldCancelConn = m_cancelConn; + + m_cancelConn = NULL; + + if (oldCancelConn != NULL) + PQfreeCancel(oldCancelConn); +} + + +void pgConn::CancelExecution(void) +{ + char errbuf[256]; + wxMutexLocker lock(m_cancelConnMutex); + + if (m_cancelConn) + { + PGcancel *cancelConn = m_cancelConn; + m_cancelConn = NULL; + + if (PQcancel(cancelConn, errbuf, sizeof(errbuf))) + { + SetLastResultError(NULL, wxT("Cancel request sent")); + } + else + { + SetLastResultError(NULL, wxString::Format(wxT("Could not send cancel request:\n%s"), errbuf)); + } + PQfreeCancel(cancelConn); + } +} + + +wxString pgConn::GetVersionString() +{ + return ExecuteScalar(wxT("SELECT version();")); +} + +void pgConn::SetLastResultError(PGresult *res, const wxString &msg) +{ + if (res) + { + lastResultError.severity = wxString(PQresultErrorField(res, PG_DIAG_SEVERITY), *conv); + lastResultError.sql_state = wxString(PQresultErrorField(res, PG_DIAG_SQLSTATE), *conv); + lastResultError.msg_primary = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_PRIMARY), *conv); + lastResultError.msg_detail = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_DETAIL), *conv); + lastResultError.msg_hint = wxString(PQresultErrorField(res, PG_DIAG_MESSAGE_HINT), *conv); + lastResultError.statement_pos = wxString(PQresultErrorField(res, PG_DIAG_STATEMENT_POSITION), *conv); + lastResultError.internal_pos = wxString(PQresultErrorField(res, PG_DIAG_INTERNAL_POSITION), *conv); + lastResultError.internal_query = wxString(PQresultErrorField(res, PG_DIAG_INTERNAL_QUERY), *conv); + lastResultError.context = wxString(PQresultErrorField(res, PG_DIAG_CONTEXT), *conv); + lastResultError.source_file = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_FILE), *conv); + lastResultError.source_line = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_LINE), *conv); + lastResultError.source_function = wxString(PQresultErrorField(res, PG_DIAG_SOURCE_FUNCTION), *conv); + } + else + { + lastResultError.severity = wxEmptyString; + lastResultError.sql_state = wxEmptyString; + if (msg.IsEmpty()) + lastResultError.msg_primary = GetLastError(); + else + lastResultError.msg_primary = msg; + lastResultError.msg_detail = wxEmptyString; + lastResultError.msg_hint = wxEmptyString; + lastResultError.statement_pos = wxEmptyString; + lastResultError.internal_pos = wxEmptyString; + lastResultError.internal_query = wxEmptyString; + lastResultError.context = wxEmptyString; + lastResultError.source_file = wxEmptyString; + lastResultError.source_line = wxEmptyString; + lastResultError.source_function = wxEmptyString; + } + + wxString errMsg; + + if (lastResultError.severity != wxEmptyString && lastResultError.msg_primary != wxEmptyString) + errMsg = lastResultError.severity + wxT(": ") + lastResultError.msg_primary; + else if (lastResultError.msg_primary != wxEmptyString) + errMsg = lastResultError.msg_primary; + + if (!lastResultError.sql_state.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("SQL state: "); + errMsg += lastResultError.sql_state; + } + + if (!lastResultError.msg_detail.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Detail: "); + errMsg += lastResultError.msg_detail; + } + + if (!lastResultError.msg_hint.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Hint: "); + errMsg += lastResultError.msg_hint; + } + + if (!lastResultError.statement_pos.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Character: "); + errMsg += lastResultError.statement_pos; + } + + if (!lastResultError.context.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Context: "); + errMsg += lastResultError.context; + } + lastResultError.formatted_msg = errMsg; +} + +// String quoting - only for use during the connection phase!! +wxString pgConn::qtString(const wxString &value) +{ + wxString result = value; + + result.Replace(wxT("\\"), wxT("\\\\")); + result.Replace(wxT("'"), wxT("\\'")); + result.Append(wxT("'")); + result.Prepend(wxT("'")); + + return result; +} + +// Check if, TABLE (tblname) has column with name colname +bool pgConn::TableHasColumn(wxString schemaname, wxString tblname, const wxString &colname) +{ + // + // SELECT a.attname + // FROM pg_catalog.pg_attribute a + // WHERE a.attrelid = (SELECT c.oid + // FROM pg_catalog.pg_class c + // LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace + // WHERE c.relname ~ '^(TABLENAME)$' AND + // pg_catalog.pg_table_is_visible(c.oid) AND + // n.nspname ~ '^(SCHEMANAME)$') AND + // a.attnum > 0 AND NOT a.attisdropped + // ORDER BY a.attnum + // + + if (tblname.IsEmpty() || colname.IsEmpty()) + return false; + + if (schemaname.IsEmpty()) + schemaname = wxT("public"); + + if (this && GetStatus() == PGCONN_OK) + { + tblname.Replace(wxT("\\"), wxT("\\\\")); + tblname.Replace(wxT("'"), wxT("''")); + schemaname.Replace(wxT("\\"), wxT("\\\\")); + schemaname.Replace(wxT("'"), wxT("''")); + + wxString sql + = wxT("SELECT a.attname AS colname FROM pg_catalog.pg_attribute a ") \ + wxT("WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c ") \ + wxT(" LEFT JOIN pg_catalog.pg_namespace n ON ") \ + wxT(" n.oid = c.relnamespace ") \ + wxT(" WHERE c.relname ~ '^(") + tblname + wxT(")$' AND ") \ + wxT(" n.nspname ~ '^(") + schemaname + wxT(")$') AND ") \ + wxT(" a.attnum > 0 AND NOT a.attisdropped ") \ + wxT("ORDER BY a.attnum"); + + pgSet *set = ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + if (set->GetVal(wxT("colname")) == colname) + { + delete set; + return true; + } + set->MoveNext(); + } + } + delete set; + } + + return false; +} + +void pgError::SetError(PGresult *_res, wxMBConv *_conv) +{ + if (!_conv) + { + _conv = &wxConvLibc; + } + if (_res) + { + msg_primary = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_PRIMARY), *_conv); + severity = wxString(PQresultErrorField(_res, PG_DIAG_SEVERITY), *_conv); + sql_state = wxString(PQresultErrorField(_res, PG_DIAG_SQLSTATE), *_conv); + msg_detail = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_DETAIL), *_conv); + msg_hint = wxString(PQresultErrorField(_res, PG_DIAG_MESSAGE_HINT), *_conv); + statement_pos = wxString(PQresultErrorField(_res, PG_DIAG_STATEMENT_POSITION), *_conv); + internal_pos = wxString(PQresultErrorField(_res, PG_DIAG_INTERNAL_POSITION), *_conv); + internal_query = wxString(PQresultErrorField(_res, PG_DIAG_INTERNAL_QUERY), *_conv); + context = wxString(PQresultErrorField(_res, PG_DIAG_CONTEXT), *_conv); + source_file = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_FILE), *_conv); + source_line = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_LINE), *_conv); + source_function = wxString(PQresultErrorField(_res, PG_DIAG_SOURCE_FUNCTION), *_conv); + } + else + { + msg_primary = wxEmptyString; + severity = wxEmptyString; + sql_state = wxEmptyString; + msg_detail = wxEmptyString; + msg_hint = wxEmptyString; + statement_pos = wxEmptyString; + internal_pos = wxEmptyString; + internal_query = wxEmptyString; + context = wxEmptyString; + source_file = wxEmptyString; + source_line = wxEmptyString; + source_function = wxEmptyString; + } + + wxString errMsg; + + if (severity != wxEmptyString && msg_primary != wxEmptyString) + errMsg = severity + wxT(": ") + msg_primary; + else if (msg_primary != wxEmptyString) + errMsg = msg_primary; + + if (!sql_state.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("SQL state: "); + errMsg += sql_state; + } + + if (!msg_detail.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Detail: "); + errMsg += msg_detail; + } + + if (!msg_hint.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Hint: "); + errMsg += msg_hint; + } + + if (!statement_pos.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Character: "); + errMsg += statement_pos; + } + + if (!context.IsEmpty()) + { + if (!errMsg.EndsWith(wxT("\n"))) + errMsg += wxT("\n"); + errMsg += _("Context: "); + errMsg += context; + } + formatted_msg = errMsg; +} diff --git a/db/pgQueryThread.cpp b/db/pgQueryThread.cpp new file mode 100644 index 0000000..656609c --- /dev/null +++ b/db/pgQueryThread.cpp @@ -0,0 +1,901 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgQueryThread.cpp - PostgreSQL threaded query class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// PostgreSQL headers +#include + +// App headers +#include "db/pgSet.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "utils/pgDefs.h" +#include "utils/sysLogger.h" + +const wxEventType PGQueryResultEvent = wxNewEventType(); + +// default notice processor for the pgQueryThread +// we do assume that the argument passed will be always the +// object of pgQueryThread +void pgNoticeProcessor(void *_arg, const char *_message) +{ + wxString str(_message, wxConvUTF8); + + wxLogNotice(wxT("%s"), str.Trim().c_str()); + if (_arg) + { + ((pgQueryThread *)_arg)->AppendMessage(str); + } +} + + +// support for multiple queries support +pgQueryThread::pgQueryThread(pgConn *_conn, wxEvtHandler *_caller, + PQnoticeProcessor _processor, void *_noticeHandler) : + wxThread(wxTHREAD_JOINABLE), m_currIndex(-1), m_conn(_conn), + m_cancelled(false), m_multiQueries(true), m_useCallable(false), + m_caller(_caller), m_processor(pgNoticeProcessor), m_noticeHandler(NULL), + m_eventOnCancellation(true) +{ + // check if we can really use the enterprisedb callable statement and + // required +#ifdef __WXMSW__ + if (PQiGetOutResult && PQiPrepareOut && PQiSendQueryPreparedOut) + { + // we do not need all of pqi stuff as90 onwards + if (m_conn && m_conn->conn && m_conn->GetIsEdb() + && !m_conn->EdbMinimumVersion(9, 0)) + { + m_useCallable = true; + } + } +#else // __WXMSW__ +#ifdef EDB_LIBPQ + // use callable statement only with enterprisedb advanced servers + // we do not need all of pqi stuff as90 onwards + if (m_conn && m_conn->conn && m_conn->GetIsEdb() + && !m_conn->EdbMinimumVersion(9, 0)) + { + m_useCallable = true; + } +#endif // EDB_LIBPQ +#endif // __WXMSW__ + + if (m_conn && m_conn->conn) + { + PQsetnonblocking(m_conn->conn, 1); + } + + if (_processor != NULL) + { + m_processor = _processor; + if (_noticeHandler) + m_noticeHandler = _noticeHandler; + else + m_noticeHandler = (void *)this; + } + else + { + m_noticeHandler = (void *)this; + } +} + +pgQueryThread::pgQueryThread(pgConn *_conn, const wxString &_qry, + int _resultToRetrieve, wxWindow *_caller, long _eventId, void *_data) + : wxThread(wxTHREAD_JOINABLE), m_currIndex(-1), m_conn(_conn), + m_cancelled(false), m_multiQueries(false), m_useCallable(false), + m_caller(NULL), m_processor(pgNoticeProcessor), m_noticeHandler(NULL), + m_eventOnCancellation(true) +{ + if (m_conn && m_conn->conn) + { + PQsetnonblocking(m_conn->conn, 1); + } + m_queries.Add( + new pgBatchQuery(_qry, (pgParamsArray *)NULL, _eventId, _data, false, + _resultToRetrieve)); + + wxLogInfo(wxT("queueing : %s"), _qry.c_str()); + m_noticeHandler = (void *)this; + + if (_caller) + { + m_caller = _caller->GetEventHandler(); + } +} + +void pgQueryThread::SetEventOnCancellation(bool eventOnCancelled) +{ + m_eventOnCancellation = eventOnCancelled; +} + +void pgQueryThread::AddQuery(const wxString &_qry, pgParamsArray *_params, + long _eventId, void *_data, bool _useCallable, int _resultToRetrieve) +{ + m_queries.Add( + new pgBatchQuery(_qry, _params, _eventId, _data, + // use callable statement only if supported + m_useCallable && _useCallable, _resultToRetrieve)); + + wxLogInfo(wxT("queueing (%ld): %s"), GetId(), _qry.c_str()); +} + + +pgQueryThread::~pgQueryThread() +{ + m_conn->RegisterNoticeProcessor(0, 0); + WX_CLEAR_ARRAY(m_queries); +} + + +wxString pgQueryThread::GetMessagesAndClear(int idx) +{ + wxString msg; + + if (idx == -1) + idx = m_currIndex; + + if (idx >= 0 && idx <= m_currIndex) + { + wxCriticalSectionLocker lock(m_criticalSection); + msg = m_queries[idx]->m_message; + m_queries[idx]->m_message = wxT(""); + } + + return msg; +} + + +void pgQueryThread::AppendMessage(const wxString &str) +{ + if (m_queries[m_currIndex]->m_message.IsEmpty()) + { + wxCriticalSectionLocker lock(m_criticalSection); + if (str != wxT("\n")) + m_queries[m_currIndex]->m_message.Append(str); + } + else + { + wxCriticalSectionLocker lock(m_criticalSection); + m_queries[m_currIndex]->m_message.Append(wxT("\n")).Append(str); + } +} + + +int pgQueryThread::Execute() +{ + wxMutexLocker lock(m_queriesLock); + + PGresult *result = NULL; + wxMBConv &conv = *(m_conn->conv); + + wxString &query = m_queries[m_currIndex]->m_query; + int &resultToRetrieve = m_queries[m_currIndex]->m_resToRetrieve; + long &rowsInserted = m_queries[m_currIndex]->m_rowsInserted; + Oid &insertedOid = m_queries[m_currIndex]->m_insertedOid; + // using the alias for the pointer here, in order to save the result back + // in the pgBatchQuery object + pgSet *&dataSet = m_queries[m_currIndex]->m_resultSet; + int &rc = m_queries[m_currIndex]->m_returnCode; + pgParamsArray *params = m_queries[m_currIndex]->m_params; + bool useCallable = m_queries[m_currIndex]->m_useCallable; + pgError &err = m_queries[m_currIndex]->m_err; + + wxCharBuffer queryBuf = query.mb_str(conv); + + if (PQstatus(m_conn->conn) != CONNECTION_OK) + { + rc = pgQueryResultEvent::PGQ_CONN_LOST; + err.msg_primary = _("Connection to the database server lost"); + + return(RaiseEvent(rc)); + } + + if (!queryBuf && !query.IsEmpty()) + { + rc = pgQueryResultEvent::PGQ_STRING_INVALID; + m_conn->SetLastResultError(NULL, _("the query could not be converted to the required encoding.")); + err.msg_primary = _("Query string is empty"); + + return(RaiseEvent(rc)); + } + + // Honour the parameters (if any) + if (params && params->GetCount() > 0) + { + int pCount = params->GetCount(); + int ret = 0, + idx = 0; + + Oid *pOids = (Oid *)malloc(pCount * sizeof(Oid)); + const char **pParams = (const char **)malloc(pCount * sizeof(const char *)); + int *pLens = (int *)malloc(pCount * sizeof(int)); + int *pFormats = (int *)malloc(pCount * sizeof(int)); + // modes are used only by enterprisedb callable statement +#if defined (__WXMSW__) || (EDB_LIBPQ) + int *pModes = (int *)malloc(pCount * sizeof(int)); +#endif + + for (; idx < pCount; idx++) + { + pgParam *param = (*params)[idx]; + + pOids[idx] = param->m_type; + pParams[idx] = (const char *)param->m_val; + pLens[idx] = param->m_len; + pFormats[idx] = param->GetFormat(); +#if defined (__WXMSW__) || (EDB_LIBPQ) + pModes[idx] = param->m_mode; +#endif + } + + if (useCallable) + { +#if defined (__WXMSW__) || (EDB_LIBPQ) + wxLogInfo(wxString::Format( + _("using an enterprisedb callable statement (queryid:%ld, threadid:%ld)"), + (long)m_currIndex, (long)GetId())); + wxString stmt = wxString::Format(wxT("pgQueryThread-%ld-%ld"), this->GetId(), m_currIndex); + PGresult *res = PQiPrepareOut(m_conn->conn, stmt.mb_str(wxConvUTF8), + queryBuf, pCount, pOids, pModes); + + if( PQresultStatus(res) != PGRES_COMMAND_OK) + { + rc = pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE; + err.SetError(res, &conv); + + PQclear(res); + + goto return_with_error; + } + + ret = PQiSendQueryPreparedOut(m_conn->conn, stmt.mb_str(wxConvUTF8), + pCount, pParams, pLens, pFormats, 1); + + if (ret != 1) + { + rc = pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE; + + m_conn->SetLastResultError(NULL, _("Failed to run PQsendQuery in pgQueryThread")); + err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv); + + PQclear(res); + res = NULL; + + goto return_with_error; + } + + PQclear(res); + res = NULL; +#else + rc = -1; + wxASSERT_MSG(false, + _("the program execution flow must not reach to this point in pgQueryThread")); + + goto return_with_error; +#endif + } + else + { + // assumptions: we will need the results in text format only + ret = PQsendQueryParams(m_conn->conn, queryBuf, pCount, pOids, pParams, pLens, pFormats, 0); + + if (ret != 1) + { + rc = pgQueryResultEvent::PGQ_ERROR_SEND_QUERY; + + m_conn->SetLastResultError(NULL, + _("Failed to run PQsendQueryParams in pgQueryThread")); + + err.msg_primary = _("Failed to run PQsendQueryParams in pgQueryThread.\n") + + wxString(PQerrorMessage(m_conn->conn), conv); + + goto return_with_error; + } + } + goto continue_without_error; + +return_with_error: + { + free(pOids); + free(pParams); + free(pLens); + free(pFormats); +#if defined (__WXMSW__) || (EDB_LIBPQ) + free(pModes); +#endif + return (RaiseEvent(rc)); + } + } + else + { + // use the PQsendQuery api in case, we don't have any parameters to + // pass to the server + if (!PQsendQuery(m_conn->conn, queryBuf)) + { + rc = pgQueryResultEvent::PGQ_ERROR_SEND_QUERY; + + err.msg_primary = _("Failed to run PQsendQueryParams in pgQueryThread.\n") + + wxString(PQerrorMessage(m_conn->conn), conv); + + return(RaiseEvent(rc)); + } + } + +continue_without_error: + int resultsRetrieved = 0; + PGresult *lastResult = 0; + bool connExecutionCancelled = false; + + while (true) + { + // This is a 'joinable' thread, it is not advisable to call 'delete' + // function on this. + // Hence - it does not make sense to use the function 'testdestroy' here. + // We introduced the 'CancelExecution' function for the same purpose. + // + // We will have to call the CancelExecution function of pgConn to + // inform the backend that the user has cancelled the execution. + // + // We will need to consume all the results before quiting from the thread. + // Otherwise - the connection object will become unusable, and throw + // error - because libpq connections expects application to consume all + // the result, before executing another query + // + if (m_cancelled && rc != pgQueryResultEvent::PGQ_EXECUTION_CANCELLED) + { + // We shouldn't be calling cancellation multiple time + if (!connExecutionCancelled) + { + m_conn->CancelExecution(); + connExecutionCancelled = true; + } + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + err.msg_primary = _("Execution Cancelled"); + + if (lastResult) + { + PQclear(lastResult); + lastResult = NULL; + } + } + + if ((rc = PQconsumeInput(m_conn->conn)) != 1) + { + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + err.msg_primary = _("Execution Cancelled"); + + if (lastResult) + { + PQclear(lastResult); + lastResult = NULL; + } + // There is nothing more to consume. + // We can quit the thread now. + // + // Raise the event - if the component asked for it on + // execution cancellation. + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + + if (rc == 0) + { + err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv); + } + if (PQstatus(m_conn->conn) == CONNECTION_BAD) + { + err.msg_primary = _("Connection to the database server lost"); + rc = pgQueryResultEvent::PGQ_CONN_LOST; + } + else + { + rc = pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT; + } + + return(RaiseEvent(rc)); + } + + if (PQisBusy(m_conn->conn)) + { + Yield(); + this->Sleep(10); + + continue; + } + + // if resultToRetrieve is given, the nth result will be returned, + // otherwise the last result set will be returned. + // all others are discarded + PGresult *res = PQgetResult(m_conn->conn); + + if (!res) + break; + + if((PQresultStatus(res) == PGRES_NONFATAL_ERROR) || + (PQresultStatus(res) == PGRES_FATAL_ERROR) || + (PQresultStatus(res) == PGRES_BAD_RESPONSE)) + { + result = res; + err.SetError(res, &conv); + + // Wait for the execution to be finished + // We need to fetch all the results, before sending the error + // message + do + { + if (PQconsumeInput(m_conn->conn) != 1) + { + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + // Release the result as the query execution has been cancelled by the + // user + if (result) + PQclear(result); + + result = NULL; + + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + goto out_of_consume_input_loop; + } + + if ((res = PQgetResult(m_conn->conn)) == NULL) + { + goto out_of_consume_input_loop; + } + + // Release the temporary results + PQclear(res); + res = NULL; + + if (PQisBusy(m_conn->conn)) + { + Yield(); + this->Sleep(10); + } + } + while (true); + + break; + } + +#if defined (__WXMSW__) || (EDB_LIBPQ) + // there should be 2 results in the callable statement - the first is the + // dummy, the second contains our out params. + if (useCallable) + { + PQclear(res); + result = PQiGetOutResult(m_conn->conn); + } +#endif + if (PQresultStatus(res) == PGRES_COPY_IN) + { + rc = PGRES_COPY_IN; + PQputCopyEnd(m_conn->conn, "not supported by pgadmin"); + } + + if (PQresultStatus(res) == PGRES_COPY_OUT) + { + int copyRc; + char *buf; + int copyRows = 0; + int lastCopyRc = 0; + + rc = PGRES_COPY_OUT; + + AppendMessage(_("query returned copy data:\n")); + + while((copyRc = PQgetCopyData(m_conn->conn, &buf, 1)) >= 0) + { + // Ignore processing the query result, when it has already been + // cancelled by the user + if (m_cancelled) + { + if (!connExecutionCancelled) + { + m_conn->CancelExecution(); + connExecutionCancelled = true; + } + continue; + } + + if (buf != NULL) + { + if (copyRows < 100) + { + wxString str(buf, conv); + wxCriticalSectionLocker cs(m_criticalSection); + m_queries[m_currIndex]->m_message.Append(str); + + } + else if (copyRows == 100) + AppendMessage(_("Query returned more than 100 copy rows, discarding the rest...\n")); + + PQfreemem(buf); + } + if (copyRc > 0) + copyRows++; + + if (lastCopyRc == 0 && copyRc == 0) + { + Yield(); + this->Sleep(10); + } + if (copyRc == 0) + { + if (!PQconsumeInput(m_conn->conn)) + { + // It might be the case - it is a result of the + // execution cancellation. + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + // Release the result as the query execution has been cancelled by the + // user + if (result) + PQclear(result); + + result = NULL; + + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + if (PQstatus(m_conn->conn) == CONNECTION_BAD) + { + err.msg_primary = _("Connection to the database server lost"); + rc = pgQueryResultEvent::PGQ_CONN_LOST; + } + else + { + rc = pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT; + + err.msg_primary = wxString(PQerrorMessage(m_conn->conn), conv); + } + return(RaiseEvent(rc)); + } + } + lastCopyRc = copyRc; + } + + res = PQgetResult(m_conn->conn); + + if (!res) + break; + } + + resultsRetrieved++; + + // Save the current result, as asked by the component + // But - only if the execution is not cancelled + if (!m_cancelled && resultsRetrieved == resultToRetrieve) + { + result = res; + insertedOid = PQoidValue(res); + if (insertedOid && insertedOid != (Oid) - 1) + AppendMessage(wxString::Format(_("query inserted one row with oid %d.\n"), insertedOid)); + else + AppendMessage(wxString::Format(wxPLURAL("query result with %d row will be returned.\n", "query result with %d rows will be returned.\n", + PQntuples(result)), PQntuples(result))); + continue; + } + + if (lastResult) + { + if (!m_cancelled && PQntuples(lastResult)) + AppendMessage(wxString::Format(wxPLURAL("query result with %d row discarded.\n", "query result with %d rows discarded.\n", + PQntuples(lastResult)), PQntuples(lastResult))); + PQclear(lastResult); + } + lastResult = res; + } + +out_of_consume_input_loop: + if (m_cancelled) + { + rc = pgQueryResultEvent::PGQ_EXECUTION_CANCELLED; + + // Release the result as the query execution has been cancelled by the + // user + if (result) + PQclear(result); + + result = NULL; + + if (m_eventOnCancellation) + RaiseEvent(rc); + + return rc; + } + + if (!result) + result = lastResult; + + err.SetError(result, &conv); + + AppendMessage(wxT("\n")); + + rc = PQresultStatus(result); + if (rc == PGRES_TUPLES_OK) + { + dataSet = new pgSet(result, m_conn, conv, m_conn->needColQuoting); + dataSet->MoveFirst(); + } + else if (rc == PGRES_COMMAND_OK) + { + char *s = PQcmdTuples(result); + if (*s) + rowsInserted = atol(s); + } + else if (rc == PGRES_FATAL_ERROR || + rc == PGRES_NONFATAL_ERROR || + rc == PGRES_BAD_RESPONSE) + { + if (result) + { + AppendMessage(wxString(PQresultErrorMessage(result), conv)); + PQclear(result); + result = NULL; + } + else + { + AppendMessage(wxString(PQerrorMessage(m_conn->conn), conv)); + } + + return(RaiseEvent(rc)); + } + + insertedOid = PQoidValue(result); + if (insertedOid == (Oid) - 1) + insertedOid = 0; + + return(RaiseEvent(1)); +} + +int pgQueryThread::RaiseEvent(int _retval) +{ +#if !defined(PGSCLI) + if (m_caller) + { + pgQueryResultEvent resultEvent(GetId(), m_queries[m_currIndex], m_queries[m_currIndex]->m_eventID); + + // client data + resultEvent.SetClientData(m_queries[m_currIndex]->m_data); + resultEvent.SetInt(_retval); + + m_caller->AddPendingEvent(resultEvent); + } +#endif + return _retval; +} + + +void *pgQueryThread::Entry() +{ + do + { + if (m_currIndex < (((int)m_queries.GetCount()) - 1)) + { + // Create the PGcancel object to enable cancelling the running + // query + m_conn->SetConnCancel(); + m_currIndex++; + + m_queries[m_currIndex]->m_returnCode = -2; + m_queries[m_currIndex]->m_rowsInserted = -1l; + + wxLogSql(wxT("Thread executing query (%d:%s:%d): %s"), + m_currIndex + 1, m_conn->GetHost().c_str(), m_conn->GetPort(), + m_queries[m_currIndex]->m_query.c_str()); + + // register the notice processor for the current query + m_conn->RegisterNoticeProcessor(m_processor, m_noticeHandler); + + // execute the current query now + Execute(); + + // remove the notice processor now + m_conn->RegisterNoticeProcessor(0, 0); + + // reset the PGcancel object + m_conn->ResetConnCancel(); + } + + if (!m_multiQueries || m_cancelled) + break; + + wxThread::Sleep(10); + } + while (true); + + return(NULL); +} + +int pgQueryThread::DeleteReleasedQueries() +{ + int res = 0, + idx = 0; + + if (m_queriesLock.TryLock() == wxMUTEX_BUSY) + return res; + + for (; idx <= m_currIndex; idx++) + { + if (m_queries[idx]->m_resultSet != NULL) + { + pgSet *set = m_queries[idx]->m_resultSet; + m_queries[idx]->m_resultSet = NULL; + delete set; + set = NULL; + + res++; + } + } + m_queriesLock.Unlock(); + + return res; +} + + +pgError pgQueryThread::GetResultError(int idx) +{ + wxMutexLocker lock(m_queriesLock); + + if (idx == -1) + idx = m_currIndex; + + return m_queries[idx]->m_err; +} + + +const wxString &pgBatchQuery::GetErrorMessage() +{ + return m_err.msg_primary; +} + +pgBatchQuery::~pgBatchQuery() +{ + if (m_resultSet) + { + delete m_resultSet; + m_resultSet = NULL; + } + + if (m_params) + { + WX_CLEAR_ARRAY((*m_params)); + delete m_params; + m_params = NULL; + } +} + +bool pgBatchQuery::Release() +{ + bool res = false; + + if (m_resultSet != NULL) + { + res = true; + + pgSet *set = m_resultSet; + m_resultSet = NULL; + + if (set) + delete set; + set = NULL; + } + + if (m_params) + { + res = true; + + WX_CLEAR_ARRAY((*m_params)); + delete m_params; + m_params = NULL; + } + + return res; +} + +pgQueryResultEvent::pgQueryResultEvent( + unsigned long _thrdId, pgBatchQuery *_qry, int _id) : + wxCommandEvent(PGQueryResultEvent, _id), m_thrdId(_thrdId), + m_query(_qry) { } + +pgQueryResultEvent::pgQueryResultEvent(const pgQueryResultEvent &_ev) + : wxCommandEvent(_ev), m_thrdId(_ev.m_thrdId), m_query(_ev.m_query) { } + + +pgParam::pgParam(Oid _type, void *_val, int _len, short _mode) + : m_type(_type), m_val(_val), m_len(_len), m_mode(_mode) +{ + switch(m_type) + { + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_CSTRING: + m_format = 0; + default: + m_format = 1; + } +} + +// wxString data +pgParam::pgParam(Oid _oid, wxString *_val, wxMBConv *_conv, short _mode) + : m_mode(_mode) +{ + if (m_mode == PG_PARAM_OUT || !_val) + { + m_len = 0; + } + else + { + m_len = _val->Len(); + } + if (_val) + { + char *str = (char *)malloc(m_len + 1); + if (!_val->IsEmpty() && _mode != PG_PARAM_OUT) + { + strncpy(str, + (const char *)_val->mb_str( + *(_conv != NULL ? _conv : &wxConvLocal)), m_len); + str[m_len] = '\0'; + } + else + { + str[0] = '\0'; + } + m_val = (void *)(str); + } + else + { + m_val = NULL; + } + m_type = _oid; + + // text format + m_format = 0; +} + + +pgParam::~pgParam() +{ + if (m_val) + free(m_val); + m_val = NULL; +} + + +int pgParam::GetFormat() +{ + return m_format; +} diff --git a/db/pgSet.cpp b/db/pgSet.cpp new file mode 100644 index 0000000..4ab6cf2 --- /dev/null +++ b/db/pgSet.cpp @@ -0,0 +1,443 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSet.cpp - PostgreSQL ResultSet class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// PostgreSQL headers +#include + +// App headers +#include "db/pgSet.h" +#include "db/pgConn.h" +#include "utils/sysLogger.h" +#include "utils/pgDefs.h" + +pgSet::pgSet() + : conv(wxConvLibc) +{ + conn = 0; + res = 0; + nCols = 0; + nRows = 0; + pos = 0; +} + +pgSet::pgSet(PGresult *newRes, pgConn *newConn, wxMBConv &cnv, bool needColQt) + : conv(cnv) +{ + needColQuoting = needColQt; + + conn = newConn; + res = newRes; + + // Make sure we have tuples + if (PQresultStatus(res) != PGRES_TUPLES_OK) + { + nCols = 0; + nRows = 0; + pos = 0; + } + else + { + nCols = PQnfields(res); + for (int x = 0; x < nCols + 1; x++) + { + colTypes.Add(wxT("")); + colFullTypes.Add(wxT("")); + colClasses.Add(0); + } + + nRows = PQntuples(res); + MoveFirst(); + } +} + + +pgSet::~pgSet() +{ + PQclear(res); +} + + + +OID pgSet::ColTypeOid(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return PQftype(res, col); +} + +long pgSet::ColTypeMod(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return PQfmod(res, col); +} + + +long pgSet::GetInsertedCount() const +{ + char *cnt = PQcmdTuples(res); + if (!*cnt) + return -1; + else + return atol(cnt); +} + + +pgTypClass pgSet::ColTypClass(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + if (colClasses[col] != 0) + return (pgTypClass)colClasses[col]; + + wxString typoid = ExecuteScalar( + wxT("SELECT CASE WHEN typbasetype=0 THEN oid else typbasetype END AS basetype\n") + wxT(" FROM pg_type WHERE oid=") + NumToStr(ColTypeOid(col))); + + switch (StrToLong(typoid)) + { + case PGOID_TYPE_BOOL: + colClasses[col] = PGTYPCLASS_BOOL; + break; + case PGOID_TYPE_INT8: + case PGOID_TYPE_INT2: + case PGOID_TYPE_INT4: + case PGOID_TYPE_OID: + case PGOID_TYPE_XID: + case PGOID_TYPE_TID: + case PGOID_TYPE_CID: + case PGOID_TYPE_FLOAT4: + case PGOID_TYPE_FLOAT8: + case PGOID_TYPE_MONEY: + case PGOID_TYPE_BIT: + case PGOID_TYPE_NUMERIC: + colClasses[col] = PGTYPCLASS_NUMERIC; + break; + case PGOID_TYPE_BYTEA: + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + case PGOID_TYPE_VARCHAR: + colClasses[col] = PGTYPCLASS_STRING; + break; + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIMETZ: + case PGOID_TYPE_INTERVAL: + colClasses[col] = PGTYPCLASS_DATE; + break; + default: + colClasses[col] = PGTYPCLASS_OTHER; + break; + } + + return (pgTypClass)colClasses[col]; +} + + +wxString pgSet::ColType(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + if (!colTypes[col].IsEmpty()) + return colTypes[col]; + + wxString szSQL, szResult; + szSQL.Printf(wxT("SELECT format_type(oid,NULL) as typname FROM pg_type WHERE oid = %d"), (int)ColTypeOid(col)); + szResult = ExecuteScalar(szSQL); + colTypes[col] = szResult; + + return szResult; +} + +wxString pgSet::ColFullType(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + if (!colFullTypes[col].IsEmpty()) + return colFullTypes[col]; + + wxString szSQL, szResult; + szSQL.Printf(wxT("SELECT format_type(oid,%d) as typname FROM pg_type WHERE oid = %d"), (int)ColTypeMod(col), (int)ColTypeOid(col)); + szResult = ExecuteScalar(szSQL); + colFullTypes[col] = szResult; + + return szResult; +} + +int pgSet::ColScale(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + // TODO + return 0; +} +wxString pgSet::ColName(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return wxString(PQfname(res, col), conv); +} + + +int pgSet::ColNumber(const wxString &colname) const +{ + int col; + + if (needColQuoting) + { + wxString quotedColName = colname; + quotedColName.Replace(wxT("\""), wxT("\"\"")); + col = PQfnumber(res, (wxT("\"") + quotedColName + wxT("\"")).mb_str(conv)); + } + else + col = PQfnumber(res, colname.mb_str(conv)); + + if (col < 0) + { + wxLogError(__("Column not found in pgSet: %s"), colname.c_str()); + } + return col; +} + +bool pgSet::HasColumn(const wxString &colname) const +{ + if (needColQuoting) + { + wxString quotedColName = colname; + quotedColName.Replace(wxT("\""), wxT("\"\"")); + return (PQfnumber(res, (wxT("\"") + quotedColName + wxT("\"")).mb_str(conv)) < 0 ? false : true); + } + else + return (PQfnumber(res, colname.mb_str(conv)) < 0 ? false : true); + +} + + + +char *pgSet::GetCharPtr(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return PQgetvalue(res, pos - 1, col); +} + + +char *pgSet::GetCharPtr(const wxString &col) const +{ + return PQgetvalue(res, pos - 1, ColNumber(col)); +} + + +wxString pgSet::GetVal(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return wxString(GetCharPtr(col), conv); +} + + +wxString pgSet::GetVal(const wxString &colname) const +{ + return GetVal(ColNumber(colname)); +} + + +long pgSet::GetLong(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + return atol(c); + else + return 0; +} + + +long pgSet::GetLong(const wxString &col) const +{ + char *c = PQgetvalue(res, pos - 1, ColNumber(col)); + if (c) + return atol(c); + else + return 0; +} + + +bool pgSet::GetBool(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + { + if (*c == 't' || *c == '1' || !strcmp(c, "on")) + return true; + } + return false; +} + + +bool pgSet::GetBool(const wxString &col) const +{ + return GetBool(ColNumber(col)); +} + + +wxDateTime pgSet::GetDateTime(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + wxDateTime dt; + wxString str = GetVal(col); + /* This hasn't just been used. ( Is not infinity ) */ + if (!str.IsEmpty()) + dt.ParseDateTime(str); + return dt; +} + + +wxDateTime pgSet::GetDateTime(const wxString &col) const +{ + return GetDateTime(ColNumber(col)); +} + + +wxDateTime pgSet::GetDate(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + wxDateTime dt; + wxString str = GetVal(col); + /* This hasn't just been used. ( Is not infinity ) */ + if (!str.IsEmpty()) + dt.ParseDate(str); + return dt; +} + + +wxDateTime pgSet::GetDate(const wxString &col) const +{ + return GetDate(ColNumber(col)); +} + + +double pgSet::GetDouble(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + return StrToDouble(GetVal(col)); +} + + +double pgSet::GetDouble(const wxString &col) const +{ + return GetDouble(ColNumber(col)); +} + + +wxULongLong pgSet::GetLongLong(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + return atolonglong(c); + else + return 0; +} + +wxULongLong pgSet::GetLongLong(const wxString &col) const +{ + return GetLongLong(ColNumber(col)); +} + + +OID pgSet::GetOid(const int col) const +{ + wxASSERT(col < nCols && col >= 0); + + char *c = PQgetvalue(res, pos - 1, col); + if (c) + return (OID)strtoul(c, 0, 10); + else + return 0; +} + + +OID pgSet::GetOid(const wxString &col) const +{ + return GetOid(ColNumber(col)); +} + + +wxString pgSet::ExecuteScalar(const wxString &sql) const +{ + return conn->ExecuteScalar(sql); +} + + +////////////////////////////////////////////////////////////////// + +pgSetIterator::pgSetIterator(pgConn *conn, const wxString &qry) +{ + set = conn->ExecuteSet(qry); + first = true; +} + + +pgSetIterator::pgSetIterator(pgSet *s) +{ + set = s; + first = true; +} + + +pgSetIterator::~pgSetIterator() +{ + if (set) + delete set; +} + + +bool pgSetIterator::RowsLeft() +{ + if (!set) + return false; + + if (first) + { + if (!set->NumRows()) + return false; + first = false; + } + else + set->MoveNext(); + + return !set->Eof(); +} + + +bool pgSetIterator::MovePrev() +{ + if (!set) + return false; + + set->MovePrevious(); + return true; +} diff --git a/dd/dditems/figures/ddColumnFigure.cpp b/dd/dditems/figures/ddColumnFigure.cpp new file mode 100644 index 0000000..e2b53fd --- /dev/null +++ b/dd/dditems/figures/ddColumnFigure.cpp @@ -0,0 +1,538 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigure.cpp - Minimal Composite Figure for a column of a table +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/tools/ddColumnFigureTool.h" +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" + +void ddColumnFigure::Init(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk) +{ + setKindId(DDCOLUMNFIGURE); + fkSource = sourceFk; + usedAsFkDestFor = NULL; + setOwnerTable(owner); + deactivateGenFkName(); //initializae by default at not generate auto fk name + columnText = new ddTextTableItemFigure(columnName, dt_null, this); + kindImage = new ddColumnKindIcon(this); + optionImage = new ddColumnOptionIcon(this); + + + //Initialize displaybox and image coords + basicDisplayBox.SetPosition(0, wxPoint(0, 0)); + basicDisplayBox.SetSize( columnText->displayBox().GetSize()); + if(kindImage && optionImage) + { + basicDisplayBox.width += kindImage->displayBox().GetSize().GetWidth() + 3; + basicDisplayBox.width += optionImage->displayBox().GetSize().GetWidth() + 3; + columnText->displayBox().x[0] += kindImage->displayBox().GetSize().GetWidth() + 2; + columnText->displayBox().x[0] += optionImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + basicDisplayBox.width += 22; //default value = 1 + 8 + 3 + 8 + 2 + columnText->displayBox().x[0] += 22; + } + + //Set Value default Attributes + fontAttribute->font().SetPointSize(owner->fontAttribute->font().GetPointSize()); + pgAttNumColNumber = -1; +} + +ddColumnFigure::ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk) +{ + Init(columnName, owner, sourceFk); +} + +//Constructor for creation of existing column from storage +ddColumnFigure::ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddColumnOptionType option, bool isGenFk, bool isPkColumn, wxString colDataType, int p, int s, int ukIdx, ddRelationshipItem *srcFk, ddRelationshipItem *usedAsFk ) +{ + Init(columnName, owner, srcFk); + setColumnOption(option); + generateFkName = isGenFk; + kindImage->setPrimaryKey(isPkColumn); + + int dtype = columnText->dataTypes().Index(colDataType, false); + if(dtype != wxNOT_FOUND) + { + setDataType((ddDataType)dtype); + } + else + { + wxMessageBox(wxString::Format(_("%s column has a non compatible data type (%s).\n%s will now have the default data type."), + columnName.c_str(), colDataType.c_str(), columnName.c_str())); + setDataType((ddDataType)0); + } + + columnText->setPrecision(p); + columnText->setScale(s); + kindImage->setUkIndex(ukIdx); + + usedAsFkDestFor = usedAsFk; + if(ownerTable) + ownerTable->updateTableSize(); + +} + +ddColumnFigure::~ddColumnFigure() +{ + if(columnText) + delete columnText; + if(kindImage) + delete kindImage; + if(optionImage) + delete optionImage; +} + +void ddColumnFigure::AddPosForNewDiagram() +{ + //Add position for new displaybox at new diagram + hdAttributeFigure::AddPosForNewDiagram(); + //Add position to each figure inside this composite figure + if(kindImage) + kindImage->AddPosForNewDiagram(); + if(optionImage) + optionImage->AddPosForNewDiagram(); + if(columnText) + columnText->AddPosForNewDiagram(); +} + +void ddColumnFigure::RemovePosOfDiagram(int posIdx) +{ + //Remove this position at displaybox of this figure + hdAttributeFigure::RemovePosOfDiagram(posIdx); + //Remove this position at each figure inside this composite figure + if(kindImage) + kindImage->RemovePosOfDiagram(posIdx); + if(optionImage) + optionImage->RemovePosOfDiagram(posIdx); + if(columnText) + columnText->RemovePosOfDiagram(posIdx); + +} + +void ddColumnFigure::basicMoveBy(int posIdx, int x, int y) +{ + hdAbstractFigure::basicMoveBy(posIdx, x, y); + if(kindImage) + kindImage->moveBy(posIdx, x, y); + if(optionImage) + optionImage->moveBy(posIdx, x, y); + columnText->moveBy(posIdx, x, y); +} + +void ddColumnFigure::moveTo(int posIdx, int x, int y) +{ + hdAbstractFigure::moveTo(posIdx, x, y); + int distance = 0; + + if(kindImage) + { + kindImage->moveTo(posIdx, x, y); + distance += kindImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + distance += 11; //value = 8 + 3 + } + + if(optionImage) + { + optionImage->moveTo(posIdx, x + distance, y); + distance += optionImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + distance += 11; //value = 8 + 3 + } + + columnText->moveTo(posIdx, x + distance, y); +} + + +bool ddColumnFigure::containsPoint(int posIdx, int x, int y) +{ + bool out = false; + + if(columnText->containsPoint(posIdx, x, y)) + out = true; + else if(kindImage->containsPoint(posIdx, x, y)) + out = true; + else if(optionImage->containsPoint(posIdx, x, y)) + out = true; + + return out; +} + +hdMultiPosRect &ddColumnFigure::getBasicDisplayBox() +{ + return basicDisplayBox; +} + +void ddColumnFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + columnText->draw(context, view); + if(kindImage) + kindImage->draw(context, view); + if(optionImage) + optionImage->draw(context, view); +} + +void ddColumnFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + columnText->drawSelected(context, view); + if(kindImage) + kindImage->drawSelected(context, view); + if(optionImage) + optionImage->drawSelected(context, view); +} + +hdIFigure *ddColumnFigure::findFigure(int posIdx, int x, int y) +{ + hdIFigure *out = NULL; + + if(columnText->containsPoint(posIdx, x, y)) + out = columnText; + + if(kindImage && kindImage->containsPoint(posIdx, x, y)) + out = kindImage; + + if(optionImage && optionImage->containsPoint(posIdx, x, y)) + out = optionImage; + + return out; +} + +hdITool *ddColumnFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new ddColumnFigureTool(view, this, defaultTool); +} + +hdIFigure *ddColumnFigure::getFigureAt(int pos) +{ + if(pos == 0) + return (hdIFigure *) kindImage; + + if(pos == 1) + return (hdIFigure *) optionImage; + + if(pos == 2) + return (hdIFigure *) columnText; + + return NULL; +} + +ddTableFigure *ddColumnFigure::getOwnerTable() +{ + return ownerTable; +} + +void ddColumnFigure::setOwnerTable(ddTableFigure *table) +{ + ownerTable = table; +} + +void ddColumnFigure::displayBoxUpdate() +{ + if(kindImage && optionImage) + { + columnText->displayBoxUpdate(); + basicDisplayBox.width = columnText->displayBox().GetSize().GetWidth(); + basicDisplayBox.width += kindImage->displayBox().GetSize().GetWidth() + 3; + basicDisplayBox.width += optionImage->displayBox().GetSize().GetWidth() + 3; + } + else + { + columnText->displayBoxUpdate(); + basicDisplayBox.width += 22; //default value = 1 + 8 + 3 + 8 +2 + } +} + +bool ddColumnFigure::isNull() +{ + return optionImage->getOption() == null; +} + +bool ddColumnFigure::isNotNull() +{ + return optionImage->getOption() == notnull; +} + +bool ddColumnFigure::isNone() +{ + return kindImage->isNone(); +} + +bool ddColumnFigure::isPrimaryKey() +{ + return kindImage->isPrimaryKey(); +} + +void ddColumnFigure::disablePrimaryKey() +{ + kindImage->disablePrimaryKey(); +} + +void ddColumnFigure::enablePrimaryKey() +{ + kindImage->enablePrimaryKey(); +} + +bool ddColumnFigure::isUniqueKey() +{ + return kindImage->isUniqueKey(); +} + +bool ddColumnFigure::isUniqueKey(int uniqueIndex) +{ + return kindImage->isUniqueKey(uniqueIndex); +} + +bool ddColumnFigure::isPlain() +{ + return kindImage->isNone(); +} + +void ddColumnFigure::setColumnKindToNone() +{ + kindImage->disablePrimaryKey(); + kindImage->disableUniqueKey(); + //Foreign key cannot be changed by set / toggle functions +} + +void ddColumnFigure::setRightIconForColumn() +{ + kindImage->setRightIconForColumn(); +} + +void ddColumnFigure::toggleColumnKind(ddColumnType type, hdDrawingView *view) +{ + kindImage->toggleColumnKind(type, view); +} + +void ddColumnFigure::setColumnOption(ddColumnOptionType type) +{ + optionImage->changeIcon(type); +} + +wxString &ddColumnFigure::getColumnName(bool datatype) +{ + return columnText->getText(datatype); +} + +void ddColumnFigure::setPrecision(int n) +{ + columnText->setPrecision(n); +} + +int ddColumnFigure::getPrecision() +{ + return columnText->getPrecision(); +} + +void ddColumnFigure::setScale(int n) +{ + columnText->setScale(n); +} + +int ddColumnFigure::getScale() +{ + return columnText->getScale(); +} + +int ddColumnFigure::getUniqueConstraintIndex() +{ + return kindImage->getUniqueConstraintIndex(); +} + +void ddColumnFigure::setUniqueConstraintIndex(int i) +{ + kindImage->setUniqueConstraintIndex(i); +} + +ddColumnOptionType ddColumnFigure::getColumnOption() +{ + return optionImage->getOption(); +} + +ddDataType ddColumnFigure::getDataType() +{ + return columnText->getDataType(); +} + +void ddColumnFigure::setDataType(ddDataType type) +{ + columnText->setDataType(type); +} + +void ddColumnFigure::setColumnName(wxString name) +{ + columnText->setText(name); +} + +bool ddColumnFigure::isForeignKeyFromPk() +{ + if(fkSource) + { + return fkSource->isForeignKeyFromPk(); + } + else if(usedAsFkDestFor) + { + return usedAsFkDestFor->isForeignKeyFromPk(); + } + return false; +} + +bool ddColumnFigure::isForeignKey() +{ + bool a = isUserCreatedForeignKey(); + bool b = isGeneratedForeignKey(); + return (a || b); +} + +bool ddColumnFigure::isGeneratedForeignKey() +{ + return fkSource != NULL; +} + +bool ddColumnFigure::isUserCreatedForeignKey() +{ + return usedAsFkDestFor != NULL; +} + +ddRelationshipItem *ddColumnFigure::getRelatedFkItem() +{ + return usedAsFkDestFor; +} + +void ddColumnFigure::setAsUserCreatedFk(ddRelationshipItem *relatedFkItem) +{ + usedAsFkDestFor = relatedFkItem; + //Now fix icons of kind of column + if(relatedFkItem == NULL) + { + kindImage->setRightIconForColumn(); + } +} + +bool ddColumnFigure::isFkNameGenerated() +{ + return generateFkName; +} + +void ddColumnFigure::activateGenFkName() +{ + generateFkName = true; +} + +void ddColumnFigure::deactivateGenFkName() +{ + generateFkName = false; +} + +wxString ddColumnFigure::generateSQL(bool forAlterColumn) +{ + wxString tmp; + tmp = wxT("\"") + getColumnName() + wxT("\" "); + if(forAlterColumn) + tmp += wxT("TYPE "); + tmp += columnText->getType(); + return tmp; +} + +ddRelationshipItem *ddColumnFigure::getFkSource() +{ + return fkSource; +} + +void ddColumnFigure::setTextColour(wxColour colour) +{ + columnText->fontColorAttribute->fontColor = colour; +} + + +//Validate status of column for SQL DDL generation +bool ddColumnFigure::validateColumn(wxString &errors) +{ + bool out = true; + wxString tmp; + + if(usedAsFkDestFor) + { + //Validate if relationship is marked as identifying but column isn't marked as primary key + wxString sourceTableName = usedAsFkDestFor->sourceTableName(); + wxString destTableName = usedAsFkDestFor->destTableName(); + wxString fkColName = usedAsFkDestFor->fkColumn->getColumnName(false); + wxString sourceColName = usedAsFkDestFor->original->getColumnName(false); + + if(usedAsFkDestFor->relationIsIdentifying() && !this->isPrimaryKey()) + { + out = false; + tmp = _("relation between table: ") + sourceTableName + _(" and table: ") + destTableName; + tmp += _(" is marked as identifying but user created foreign key column: ") + fkColName; + tmp += _(" isn't set as primary key \n"); + errors.Append(tmp); + } + //Validate if relationship is marked as optional but column is mandatory + if( !usedAsFkDestFor->relationIsMandatory() && this->isNotNull()) + { + out = false; + tmp = _("relation between table:") + sourceTableName + _(" and table: ") + destTableName; + tmp += _("is marked as optional but user created foreign key column: ") + fkColName; + tmp += _("is set as mandatory \n"); + errors.Append(tmp); + } + //Validate if relationship is marked as mandatory buy column is optional + if( usedAsFkDestFor->relationIsMandatory() && this->isNull()) + { + out = false; + tmp = _("relation between table:") + sourceTableName + _(" and table: ") + destTableName + + tmp += _(" is marked as mandatory but user created foreign key column: ") + fkColName; + tmp += _("is set as optional \n"); + errors.Append(tmp); + } + + //Validate datatype compatibility (right now only exactly same datatype) + if(this->getDataType() != usedAsFkDestFor->original->getDataType()) + { + out = false; + tmp = _("User created foreign key column: ") + fkColName + _("have different datatype from source column of relationship: "); + tmp += sourceColName + _(" \n"); + errors.Append(tmp); + } + } + + return out; +} + +//Used by persistence classes +void ddColumnFigure::setFkSource(ddRelationshipItem *newColumn) +{ + fkSource = newColumn; +} + +//Used by reverse engineering functions +wxString ddColumnFigure::getRawDataType() +{ + return columnText->getType(true); +} diff --git a/dd/dditems/figures/ddColumnKindIcon.cpp b/dd/dditems/figures/ddColumnKindIcon.cpp new file mode 100644 index 0000000..b58d152 --- /dev/null +++ b/dd/dditems/figures/ddColumnKindIcon.cpp @@ -0,0 +1,435 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnKindIcon.cpp - Figure container for kind of Column Images (fk,pk,uk) only used +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" + +//Images +#include "images/ddforeignkey.pngc" +#include "images/ddprimarykey.pngc" +#include "images/ddunique.pngc" +#include "images/ddprimaryforeignkey.pngc" +#include "images/ddprimarykeyuniquekey.pngc" +#include "images/ddforeignkeyfromuk.pngc" +#include "images/ddprimaryforeignkeyfromuk.pngc" +#include "images/ddforeignkeyuniquekey.pngc" +#include "images/ddforeignkeyuniquekeyfromuk.pngc" + +ddColumnKindIcon::ddColumnKindIcon(ddColumnFigure *owner) +{ + setKindId(DDCOLUMNKINDICON); + ownerColumn = owner; + // Initialize with an image to allow initial size calculations + icon = wxBitmap(*ddprimarykey_png_img); + iconToDraw = NULL; + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); + isPk = false; + ukIndex = -1; + + //Set Value default Attributes + fontAttribute->font().SetPointSize(owner->fontAttribute->font().GetPointSize()); +} + +ddColumnKindIcon::~ddColumnKindIcon() +{ +} + +void ddColumnKindIcon::createMenu(wxMenu &mnu) +{ + wxMenuItem *item; + + item = mnu.AppendCheckItem(MNU_DDCTPKEY, _("Primary key")); + item->Check(isPrimaryKey()); + item->Enable(!getOwnerColumn()->isGeneratedForeignKey()); + item = mnu.AppendCheckItem(MNU_DDCTUKEY, _("Unique key")); + item->Check(isUniqueKey()); +} + +void ddColumnKindIcon::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + toggleColumnKind((ddColumnType)event.GetId(), view); +} + +ddColumnFigure *ddColumnKindIcon::getOwnerColumn() +{ + return ownerColumn; +} + +//if columntype attribute (type) is active then disable, is disable then active. +void ddColumnKindIcon::toggleColumnKind(ddColumnType type, hdDrawingView *view, bool interaction) +{ + + switch(type) + { + case pk: + //Set Pk attribute + if(isPrimaryKey()) + { + disablePrimaryKey(); + } + else + { + enablePrimaryKey(); + if(getOwnerColumn()->isNull()) + { + getOwnerColumn()->setColumnOption(notnull); + } + } + break; + case uk: + if(isUniqueKey()) + { + disableUniqueKey(); + } + else + { + uniqueConstraintManager(false, view, interaction); + } + break; + default: + break; + } + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); +} + +void ddColumnKindIcon::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + if(iconToDraw) + { + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + //Adding a yellow circle to increase visibility of uk index + if(isUniqueKey()) + { + context.SetBrush(wxBrush(wxColour(wxT("YELLOW")), wxSOLID)); + context.SetPen(wxPen(wxColour(wxT("YELLOW")))); + context.DrawCircle(copy.x + 6, copy.y + 7, 4); + } + //Draw icon + context.DrawBitmap(*iconToDraw, copy.GetPosition(), true); + //Draw Uk index if needed + if(isUniqueKey() && ukIndex > 0) + { + wxFont font = fontAttribute->font(); + font.SetPointSize(6); + context.SetFont(font); + wxString inumber = wxString::Format(wxT("%d"), (int)ukIndex + 1); + context.DrawText(inumber, copy.x + 4, copy.y + 2); + } + + } +} + +void ddColumnKindIcon::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +int ddColumnKindIcon::getWidth() +{ + if(iconToDraw) + return iconToDraw->GetWidth(); + else + return 8; +} + +int ddColumnKindIcon::getHeight() +{ + if(iconToDraw) + return iconToDraw->GetHeight(); + else + return 10; +} + +/* +ddColumnType ddColumnKindIcon::getKind() +{ + return colType; +} +*/ + +int ddColumnKindIcon::getUniqueConstraintIndex() +{ + return ukIndex; +} + +void ddColumnKindIcon::setUniqueConstraintIndex(int i) +{ + ukIndex = i; +} + +bool ddColumnKindIcon::uniqueConstraintManager(bool ukCol, hdDrawingView *view, bool interaction) +{ + wxString tmpString; + bool isColUk = true; + + if(ukCol) //if already this column kind is Unique Key then convert in a normal column + { + syncUkIndexes(); + setUniqueConstraintIndex(-1); + } + else //colType!=uk + { + if(interaction) + { + if(ownerColumn->getOwnerTable()->getUkConstraintsNames().Count() == 0) + { + tmpString = getOwnerColumn()->getOwnerTable()->getTableName(); + tmpString.append(wxT("_uk")); + tmpString = wxGetTextFromUser(wxT("Name of new Unique Key constraint:"), tmpString, tmpString, view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Add(tmpString); + ukIndex = 0; + } + else + { + setUniqueConstraintIndex(-1); + } + } + else //>0 + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Add(wxString(wxT("Add new Unique Constraint..."))); + int i = wxGetSingleChoiceIndex(wxT("Select Unique Key to add Column"), wxT("Select Unique Key to add Column:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames(), view); + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().RemoveAt(getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Count() - 1); + if(i >= 0) + { + if(i == getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Count()) + { + tmpString = getOwnerColumn()->getOwnerTable()->getTableName(); + tmpString.append(wxT("_uk")); + + int newIndex = i + 1; + wxString inumber = wxString::Format(wxT("%s%d"), tmpString.c_str(), (int)newIndex); + //Validate new name of uk doesn't exists + while(getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Index(inumber, false) != -1) + { + newIndex++; + inumber = wxString::Format(wxT("%s%d"), tmpString.c_str(), (int)newIndex); + } + inumber = wxString::Format(wxT("%d"), (int)newIndex); + tmpString.append(inumber); + tmpString = wxGetTextFromUser(wxT("Name of new Unique Key constraint:"), tmpString, tmpString, view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Add(tmpString); + ukIndex = i; + } + else + { + setUniqueConstraintIndex(-1); + } + } + else + { + ukIndex = i; + } + } + else + { + setUniqueConstraintIndex(-1); + } + } + } + else //without user interaction + { + + } + } + + //synchronize observers if this uk column is used as source of fk + setRightIconForColumn(); + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + + if(!isUniqueKey()) + return false; + else + return true; +} + +//synchronize uk indexes when an uk is change kind from uk to other and other index should be update with that info +void ddColumnKindIcon::syncUkIndexes() +{ + ddColumnFigure *col; + bool lastUk = true; + hdIteratorBase *iterator = getOwnerColumn()->getOwnerTable()->figuresEnumerator(); + iterator->Next(); //First Figure is Main Rect + iterator->Next(); //Second Figure is Table Title + while(iterator->HasNext()) + { + col = (ddColumnFigure *) iterator->Next(); + + if(col != getOwnerColumn() && (col->getUniqueConstraintIndex() == getOwnerColumn()->getUniqueConstraintIndex())) + { + lastUk = false; + break; + } + } + if(lastUk) + { + //here uks indexes are fixed + iterator->ResetIterator(); + iterator->Next(); //First Figure is Main Rect + iterator->Next(); //Second Figure is Table Title + while(iterator->HasNext()) + { + col = (ddColumnFigure *) iterator->Next(); + if( col->getUniqueConstraintIndex() > getOwnerColumn()->getUniqueConstraintIndex() ) + col->setUniqueConstraintIndex(col->getUniqueConstraintIndex() - 1); + } + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().RemoveAt(getOwnerColumn()->getUniqueConstraintIndex()); + getOwnerColumn()->setUniqueConstraintIndex(-1); + } + delete iterator; +} + +void ddColumnKindIcon::setRightIconForColumn() +{ + //for a pk Column + if(isPrimaryKey()) + { + if(isForeignKey()) + { + if(getOwnerColumn()->isForeignKeyFromPk()) + { + icon = wxBitmap(*ddprimaryforeignkey_png_img); + } + else + { + icon = wxBitmap(*ddprimaryforeignkeyfromuk_png_img); + } + } + else if(isUniqueKey()) + { + icon = wxBitmap(*ddprimarykeyuniquekey_png_img); + } + else + { + icon = wxBitmap(*ddprimarykey_png_img); + } + } + else if(isUniqueKey()) + { + if(isForeignKey()) + { + if(getOwnerColumn()->isForeignKeyFromPk()) + { + icon = wxBitmap(*ddforeignkeyuniquekey_png_img); + } + else + { + icon = wxBitmap(*ddforeignkeyuniquekeyfromuk_png_img); + } + + } + else if(isPrimaryKey()) + { + icon = wxBitmap(*ddprimarykeyuniquekey_png_img); + } + else + { + icon = wxBitmap(*ddunique_png_img); + } + + } + else if(isForeignKey() && !isPrimaryKey() && !isUniqueKey() ) + { + + if(getOwnerColumn()->isForeignKeyFromPk()) + { + icon = wxBitmap(*ddforeignkey_png_img); + } + else + { + icon = wxBitmap(*ddforeignkeyfromuk_png_img); + } + } + + + if(isNone()) + { + iconToDraw = NULL; + } + else + { + iconToDraw = &icon; + } +} + +bool ddColumnKindIcon::isPrimaryKey() +{ + return isPk; +} + +bool ddColumnKindIcon::isUniqueKey() +{ + return ukIndex >= 0; +} + +bool ddColumnKindIcon::isUniqueKey(int uniqueIndex) +{ + return (ukIndex == uniqueIndex); +} + +bool ddColumnKindIcon::isNone() +{ + return !isUniqueKey() && !isPrimaryKey() && !isForeignKey(); +} +bool ddColumnKindIcon::isForeignKey() +{ + return getOwnerColumn()->isForeignKey(); +} + +void ddColumnKindIcon::disableUniqueKey() +{ + syncUkIndexes(); //prepare to remove uk attribute to this column + ukIndex = -1; + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + setRightIconForColumn(); +} + +void ddColumnKindIcon::disablePrimaryKey() +{ + getOwnerColumn()->getOwnerTable()->prepareForDeleteFkColumn(getOwnerColumn()); + isPk = false; + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + setRightIconForColumn(); +} + +void ddColumnKindIcon::enablePrimaryKey() +{ + isPk = true; + getOwnerColumn()->getOwnerTable()->updateFkObservers(); + setRightIconForColumn(); +} + +//Only used for figures created from storage +void ddColumnKindIcon::setPrimaryKey(bool value) +{ + isPk = value; + setRightIconForColumn(); +} + +//Only used for figures created from storage +void ddColumnKindIcon::setUkIndex(int ukIdx) +{ + ukIndex = ukIdx; +} diff --git a/dd/dditems/figures/ddColumnOptionIcon.cpp b/dd/dditems/figures/ddColumnOptionIcon.cpp new file mode 100644 index 0000000..d79f61e --- /dev/null +++ b/dd/dditems/figures/ddColumnOptionIcon.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnOptionIcon.cpp - Part of composite column figure, allow to choose between: not null and null +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/dditems/figures/ddColumnFigure.h" + +//Images +#include "images/ddnull.pngc" +#include "images/ddnotnull.pngc" + +ddColumnOptionIcon::ddColumnOptionIcon(ddColumnFigure *owner) +{ + setKindId(DDCOLUMNOPTIONICON); + ownerColumn = owner; + colOption = null; + icon = wxBitmap(*ddnull_png_img); + iconToDraw = &icon; + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); + + //Set Value default Attributes + fontAttribute->font().SetPointSize(owner->fontAttribute->font().GetPointSize()); +} + +ddColumnOptionIcon::~ddColumnOptionIcon() +{ +} + +void ddColumnOptionIcon::createMenu(wxMenu &mnu) +{ + wxMenuItem *item; + + item = mnu.AppendCheckItem(MNU_COLNULL, _("NULL")); + item->Check(colOption == null); + item->Enable(!getOwnerColumn()->isGeneratedForeignKey()); + item = mnu.AppendCheckItem(MNU_COLNOTNULL, _("Not NULL")); + item->Check(colOption == notnull); + item->Enable(!getOwnerColumn()->isGeneratedForeignKey()); +} + +void ddColumnOptionIcon::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + changeIcon((ddColumnOptionType)event.GetId()); +} + +void ddColumnOptionIcon::changeIcon(ddColumnOptionType type) +{ + colOption = type; + switch(type) + { + case MNU_COLNULL: + icon = wxBitmap(*ddnull_png_img); + if(getOwnerColumn()->isPrimaryKey()) + { + if(getOwnerColumn()->isForeignKey() || getOwnerColumn()->isUniqueKey()) + { + getOwnerColumn()->toggleColumnKind(pk); //remove pk attribute because column now is null + getOwnerColumn()->setRightIconForColumn(); + } + else + { + getOwnerColumn()->disablePrimaryKey(); + } + } + break; + case MNU_COLNOTNULL: + icon = wxBitmap(*ddnotnull_png_img); + break; + } + getBasicDisplayBox().SetSize(wxSize(getWidth(), getHeight())); +} + +void ddColumnOptionIcon::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + if(iconToDraw) + { + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawBitmap(*iconToDraw, copy.GetPosition(), true); + } +} + +void ddColumnOptionIcon::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +int ddColumnOptionIcon::getWidth() +{ + if(iconToDraw) + return iconToDraw->GetWidth(); + else + return 8; +} + +int ddColumnOptionIcon::getHeight() +{ + if(iconToDraw) + return iconToDraw->GetHeight(); + else + return 10; +} + +ddColumnOptionType ddColumnOptionIcon::getOption() +{ + return colOption; +} + +ddColumnFigure *ddColumnOptionIcon::getOwnerColumn() +{ + return ownerColumn; +} diff --git a/dd/dditems/figures/ddRelationshipFigure.cpp b/dd/dditems/figures/ddRelationshipFigure.cpp new file mode 100644 index 0000000..008d18d --- /dev/null +++ b/dd/dditems/figures/ddRelationshipFigure.cpp @@ -0,0 +1,930 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipFigure.cpp - Figure to draw foreign keys between tables. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/utilities/ddSelectKindFksDialog.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" + + +ddRelationshipFigure::ddRelationshipFigure(): + hdLineConnection() +{ + constraintName = wxEmptyString; + setKindId(DDRELATIONSHIPFIGURE); + fkFromPk = true; + fkMandatory = true; + fkOneToMany = true; + fkIdentifying = false; + matchSimple = false; + ukIndex = -1; + disconnectedEndTable = NULL; + paintingFkColumns = false; + //DEFERRABLE, NOT DEFERRABLE, INITIALLY IMMEDIATE, INITIALLY DEFERRED can be added in a future + onUpdateAction = FK_ACTION_NO; + onDeleteAction = FK_ACTION_NO; + enablePopUp(); +} + +ddRelationshipFigure::ddRelationshipFigure(int posIdx, hdIFigure *figure1, hdIFigure *figure2): + hdLineConnection(posIdx, figure1, figure2) +{ + enablePopUp(); +} + +ddRelationshipFigure::~ddRelationshipFigure() +{ + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + delete item; + } + chm.clear(); +} + +wxString ddRelationshipFigure::getConstraintName() +{ + return constraintName; +} + +//This function avoid a bug with recursive indentifying relationships when +//a column is removed from pk or delete. +void ddRelationshipFigure::prepareFkForDelete(ddColumnFigure *column) +{ + ddTableFigure *endTable = (ddTableFigure *) getEndFigure(); + ddRelationshipItem *fkColumnRelItem; + + columnsHashMap::iterator it; + for (it = chm.begin(); it != chm.end(); ++it) + { + fkColumnRelItem = it->second; + if(fkColumnRelItem->original == column) + fkColumnRelItem->original = NULL; + } + //go recursive to next table + if(endTable) + endTable->prepareForDeleteFkColumn(column); +} + +void ddRelationshipFigure::updateForeignKey() +{ + if(getEndFigure() && getStartFigure() && getStartFigure()->ms_classInfo.IsKindOf(&ddTableFigure::ms_classInfo) && getEndFigure()->ms_classInfo.IsKindOf(&ddTableFigure::ms_classInfo)) + { + ddTableFigure *startTable = (ddTableFigure *) getStartFigure(); + ddTableFigure *endTable = (ddTableFigure *) getEndFigure(); + ddColumnFigure *col; + ddRelationshipItem *fkColumnRelItem; + + //STEP 0: Look for changes on source columns names and short table names. + + //Before iterate over all columns of source table look if any column used at relationship + //and changed their name and updated it when needed + columnsHashMap::iterator it; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if(fkColumnRelItem->original != NULL) //original column wasn't mark for delete. + { + //if autonaming is set on this item and column name at original source column of fk have been changed + if(!fkColumnRelItem->original->getColumnName(false).IsSameAs(fkColumnRelItem->originalStartColName, false)) + { + chm[fkColumnRelItem->original->getColumnName(false)] = fkColumnRelItem; + chm[fkColumnRelItem->originalStartColName] = NULL; + chm.erase(it); + fkColumnRelItem->syncAutoFkName(); + break; + } + } + } + + //STEP 1: Look at all source table columns add and delete fk + hdIteratorBase *iterator = startTable->figuresEnumerator(); + iterator->Next(); //first figure is main rect + iterator->Next(); //second figure is table title + while(iterator->HasNext()) + { + col = (ddColumnFigure *) iterator->Next(); + if(fkFromPk) //fk is generated from a pk column: add new fk/pk(s) column(s) from source fk table to destination + { + //STEP 1.1a: Add fk columns from table source pk if not exists using same name + it = chm.find(col->getColumnName()); + bool NotFound = it == chm.end(); + + if( col->isPrimaryKey() && NotFound ) + { + fkColumnRelItem = new ddRelationshipItem(this, col, endTable, (fkMandatory ? notnull : null), (fkIdentifying ? pk : none) ); + chm[col->getColumnName()] = fkColumnRelItem; //hashmap key will be original table name always + endTable->addColumn(0, fkColumnRelItem->fkColumn); + updateConnection(0); + } + + //STEP 1.2a: Delete old Fk columns not pk now or deleted from source fk table. + //This part of code (repeat) is a hack cause every time a column is delete hashmap is modified inside and becomes invalid iterator at that loop + bool repeat; + do + { + repeat = false; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if( fkColumnRelItem->original == NULL || !fkColumnRelItem->original->isPrimaryKey() || !startTable->includes(fkColumnRelItem->original) ) //order matters fkColumnRelItem->original==NULL short circuit evaluation should be first + { + if(fkColumnRelItem->isAutomaticallyGenerated()) //don't remove from fk_dest table fk column created from existing column, just mark now as not foreign key + { + fkColumnRelItem->getDestinationTable()->removeColumn(0, fkColumnRelItem->fkColumn); + } + else + { + fkColumnRelItem->fkColumn->setAsUserCreatedFk(NULL); + } + chm.erase(it); + delete fkColumnRelItem; + repeat = true; + updateConnection(0); + } + if (repeat) + break; + } + } + while(repeat); + } + else //fk is generated from a uk column: add new fk/pk(s) column(s) from source fk table to destination + { + //STEP 1.1b: Add fk columns from table source uk if not exists + columnsHashMap::iterator it = chm.find(col->getColumnName()); + bool NotFound = it == chm.end(); + + if( col->isUniqueKey(ukIndex) && NotFound ) + { + fkColumnRelItem = new ddRelationshipItem(this, col, endTable, (fkMandatory ? notnull : null), (fkIdentifying ? pk : none) ); + chm[col->getColumnName()] = fkColumnRelItem; //hashmap key will be original table name always + endTable->addColumn(0, fkColumnRelItem->fkColumn); + updateConnection(0); + } + + //STEP 1.2b: Delete old Fk columns not pk now or deleted from source fk table. + //This part of code (repeat) is a hack cause every time a column is delete hashmap is modified inside and becomes invalid iterator at that loop + bool repeat; + do + { + repeat = false; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if( fkColumnRelItem->original == NULL || !fkColumnRelItem->original->isUniqueKey(ukIndex) || !startTable->includes(fkColumnRelItem->original) ) //order matters fkColumnRelItem->original==NULL short circuit evaluation should be first + { + if(fkColumnRelItem->isAutomaticallyGenerated()) //don't remove from fk_dest table fk column created from existing column, just mark now as not foreign key + { + fkColumnRelItem->getDestinationTable()->removeColumn(0, fkColumnRelItem->fkColumn); + } + else + { + fkColumnRelItem->fkColumn->setAsUserCreatedFk(NULL); + } + chm.erase(it); + delete fkColumnRelItem; + repeat = true; + updateConnection(0); + } + if (repeat) + break; + } + } + while(repeat); + + } + } + delete iterator; + //Now if relationship is an identifying one, I should alert all observers of my observer to update it. + if(fkIdentifying) + { + if(endTable) + endTable->updateFkObservers(); + } + } + else + { + wxMessageBox(wxT("Error invalid kind of start figure at relationship"), wxT("Error invalid kind of start figure at relationship"), wxICON_ERROR | wxOK); + } +} + +void ddRelationshipFigure::createMenu(wxMenu &mnu) +{ + wxMenu *submenu; + wxMenuItem *item; + wxString tmp; + + submenu = new wxMenu(_("Select one")); + + tmp = _("Foreign Key From"); + mnu.AppendSubMenu(submenu, tmp); + item = submenu->AppendCheckItem(MNU_FKEYFROMPKEY, _("Primary Key")); + item->Check(fkFromPk); + + if(getStartFigure()) + { + ddTableFigure *startTable = (ddTableFigure *) getStartFigure(); + int i, last = startTable->getUkConstraintsNames().Count(); + int eventID; //Hack to allow multiple submenu items for select uk as fk origin + for(i = 0; i < last; i++) + { + eventID = MNU_FKEYFROMUKEYBASE + i; + tmp = _("Unique Key: "); + tmp += startTable->getUkConstraintsNames()[i]; + item = submenu->AppendCheckItem(eventID, tmp ); + item->Check(!fkFromPk && ukIndex == i); + } + } + mnu.AppendSeparator(); + //disable right now item = mnu.AppendCheckItem(MNU_FKEYCUSTOMMAPPING, _("Foreign Key Columns Custom Mapping")); + item = mnu.AppendCheckItem(MNU_MANDATORYRELATIONSHIP, _("Mandatory relationship kind")); + item->Check(fkMandatory); + item = mnu.AppendCheckItem(MNU_IDENTIFYINGRELATIONSHIP, _("Identifying relationship")); + item->Check(fkIdentifying); + mnu.AppendSeparator(); + item = mnu.AppendCheckItem(MNU_1MRELATIONSHIP, _("1:M")); + item->Check(fkOneToMany); + mnu.AppendSeparator(); + mnu.Append(MNU_FKCONSTRAINTNAME, _("Foreign Key Constraint Name")); + + submenu = new wxMenu(_("Select one")); + item = submenu->AppendCheckItem(MNU_FKMATCHTYPESIMPLE, _("Type Simple")); + item->Check(matchSimple); + item = submenu->AppendCheckItem(MNU_FKMATCHTYPEFULL, _("Type Full")); + item->Check(!matchSimple); + tmp = _("Match Type "); + if(matchSimple) + tmp += _("[ Simple ]"); + else + tmp += _("[ Full ]"); + mnu.AppendSubMenu(submenu, tmp); + + tmp = _("On Delete "); + submenu = new wxMenu(_("Select one")); + item = submenu->AppendCheckItem(MNU_FKONDELETENOACTION, _("No Action")); + item->Check(onDeleteAction == FK_ACTION_NO); + if(onDeleteAction == FK_ACTION_NO) + tmp += _("[ No Action ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETERESTRICT, _("Restrict")); + item->Check(onDeleteAction == FK_RESTRICT); + if(onDeleteAction == FK_RESTRICT) + tmp += _("[ Restrict ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETECASCADE, _("Cascade")); + item->Check(onDeleteAction == FK_CASCADE); + if(onDeleteAction == FK_CASCADE) + tmp += _("[ Cascade ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETESETNULL, _("Set Null")); + item->Check(onDeleteAction == FK_SETNULL); + if(onDeleteAction == FK_SETNULL) + tmp += _("[ Set Null ]"); + item = submenu->AppendCheckItem(MNU_FKONDELETESETDEFAULT, _("Set Default")); + item->Check(onDeleteAction == FK_SETDEFAULT); + if(onDeleteAction == FK_SETDEFAULT) + tmp += _("[ Set Default ]"); + mnu.AppendSubMenu(submenu, tmp); + + tmp = _("On Update "); + submenu = new wxMenu(_("Select one")); + item = submenu->AppendCheckItem(MNU_FKONUPDATENOACTION, _("No Action")); + item->Check(onUpdateAction == FK_ACTION_NO); + if(onUpdateAction == FK_ACTION_NO) + tmp += _("[ No Action ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATERESTRICT, _("Restrict")); + item->Check(onUpdateAction == FK_RESTRICT); + if(onUpdateAction == FK_RESTRICT) + tmp += _("[ Restrict ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATECASCADE, _("Cascade")); + item->Check(onUpdateAction == FK_CASCADE); + if(onUpdateAction == FK_CASCADE) + tmp += _("[ Cascade ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATESETNULL, _("Set Null")); + item->Check(onUpdateAction == FK_SETNULL); + if(onUpdateAction == FK_SETNULL) + tmp += _("[ Set Null ]"); + item = submenu->AppendCheckItem(MNU_FKONUPDATESETDEFAULT, _("Set Default")); + item->Check(onUpdateAction == FK_SETDEFAULT); + if(onUpdateAction == FK_SETDEFAULT) + tmp += _("[ Set Default ]"); + mnu.AppendSubMenu(submenu, tmp); + + mnu.AppendSeparator(); + mnu.Append(MNU_DELETERELATIONSHIP, _("Delete Relationship...")); +}; + +void ddRelationshipFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + int answer; + ddTableFigure *startTable = NULL; + ddTableFigure *endTable = NULL; + wxTextEntryDialog *nameDialog = NULL; + hdRemoveDeleteDialog *delremDialog = NULL; + ddSelectKindFksDialog *mappingDialog = NULL; + wxString tmpString; + + switch(event.GetId()) + { + case MNU_MANDATORYRELATIONSHIP: + fkMandatory = !fkMandatory; + if(fkMandatory) + { + setLinePen(wxPen(*wxBLACK_PEN)); + setOptionAtForeignKeys(notnull); + } + else + { + fkIdentifying = false; + setLinePen(wxPen(*wxBLACK, 1, wxSHORT_DASH)); + setOptionAtForeignKeys(null); + } + view->notifyChanged(); + break; + case MNU_IDENTIFYINGRELATIONSHIP: + fkMandatory = true; + setLinePen(wxPen(*wxBLACK_PEN)); + fkIdentifying = !fkIdentifying; + fkOneToMany = true; + updatePkAtFkCols(); + view->notifyChanged(); + break; + case MNU_FKCONSTRAINTNAME: + startTable = (ddTableFigure *) getStartFigure(); + endTable = (ddTableFigure *) getEndFigure(); + if(constraintName.IsEmpty() && startTable && endTable ) + { + constraintName = endTable->getTableName(); + constraintName += _("_"); + constraintName += startTable->getTableName(); + } + nameDialog = new wxTextEntryDialog(view, wxT("Change Constraint Name"), wxT("Constraint Name"), constraintName ); + answer = nameDialog->ShowModal(); + if (answer == wxID_OK) + { + tmpString = nameDialog->GetValue(); + constraintName = tmpString; + view->notifyChanged(); + } + delete nameDialog; + break; + case MNU_FKMATCHTYPEFULL: + matchSimple = false; + view->notifyChanged(); + break; + case MNU_FKMATCHTYPESIMPLE: + matchSimple = true; + view->notifyChanged(); + break; + case MNU_FKONDELETENOACTION: + onDeleteAction = FK_ACTION_NO; + view->notifyChanged(); + break; + case MNU_FKONDELETERESTRICT: + onDeleteAction = FK_RESTRICT; + view->notifyChanged(); + break; + case MNU_FKONDELETECASCADE: + onDeleteAction = FK_CASCADE; + view->notifyChanged(); + break; + case MNU_FKONDELETESETNULL: + onDeleteAction = FK_SETNULL; + view->notifyChanged(); + break; + case MNU_FKONDELETESETDEFAULT: + onDeleteAction = FK_SETDEFAULT; + view->notifyChanged(); + break; + + case MNU_FKONUPDATENOACTION: + onUpdateAction = FK_ACTION_NO; + view->notifyChanged(); + break; + case MNU_FKONUPDATERESTRICT: + onUpdateAction = FK_RESTRICT; + view->notifyChanged(); + break; + case MNU_FKONUPDATECASCADE: + onUpdateAction = FK_CASCADE; + view->notifyChanged(); + break; + case MNU_FKONUPDATESETNULL: + onUpdateAction = FK_SETNULL; + view->notifyChanged(); + break; + case MNU_FKONUPDATESETDEFAULT: + onUpdateAction = FK_SETDEFAULT; + view->notifyChanged(); + break; + case MNU_1MRELATIONSHIP: + fkOneToMany = !fkOneToMany; + view->notifyChanged(); + break; + case MNU_DELETERELATIONSHIP: + if(getStartFigure() && getEndFigure()) + { + ddTableFigure *t1 = (ddTableFigure *)getStartFigure(); + ddTableFigure *t2 = (ddTableFigure *)getEndFigure(); + //Relationship can be delete only NOT REMOVED + delremDialog = new hdRemoveDeleteDialog( + wxString::Format(_("Are you sure you wish to delete relationship between tables %s and %s?"), + t1->getTableName().c_str(), t2->getTableName().c_str()), + _("Delete relationship?"), + (wxScrolledWindow *)view, + false); + answer = delremDialog->ShowModal(); + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + if (answer == DD_DELETE) + { + editor->removeFromAllSelections(this); + removeForeignKeys(); + disconnectStart(); + disconnectEnd(); + //Hack to autodelete relationship + ddRelationshipFigure *r = this; + if(r) + editor->deleteModelFigure(r); + editor->getDesign()->refreshBrowser(); + view->notifyChanged(); + } + else if(answer == DD_REMOVE) + { + editor->getExistingDiagram(view->getIdx())->removeFromSelection(this); + editor->getExistingDiagram(view->getIdx())->remove(this); + view->notifyChanged(); + } + delete delremDialog; + } + break; + case MNU_FKEYFROMPKEY: + fkFromPk = true; + updateForeignKey(); + view->notifyChanged(); + break; + case MNU_FKEYCUSTOMMAPPING: + //disable right now + /* + mappingDialog = new ddSelectKindFksDialog(view,this); + mappingDialog->ShowModal(); + delete mappingDialog; + */ + break; + default: + //Hack to allow multiple selection of Uk in submenu + answer = event.GetId(); + if( answer >= MNU_FKEYFROMUKEYBASE) + { + fkFromPk = false; + ukIndex = answer - MNU_FKEYFROMUKEYBASE; + updateForeignKey(); + view->notifyChanged(); + } + break; + } +} + +bool ddRelationshipFigure::getIdentifying() +{ + return fkIdentifying; +} + +bool ddRelationshipFigure::getOneToMany() +{ + return fkOneToMany; +} + +bool ddRelationshipFigure::getMandatory() +{ + return fkMandatory; +} + + +// relationship is observed by several tables at same time, one is the +// owner (start connector table) others are just observers of that +// relationship (end connectors table) +void ddRelationshipFigure::connectEnd(hdIConnector *end, hdDrawingView *view) +{ + ddSelectKindFksDialog *mappingDialog = NULL; + hdLineConnection::connectEnd(end); + if(view) + view->Refresh(); + + //Hack to allow abort of mapping of Fk + int answer = -1; //By default + + //If connecte destination and start figure + if(getEndFigure() && getStartFigure()) + { + mappingDialog = new ddSelectKindFksDialog(view, this); + answer = mappingDialog->ShowModal(); + delete mappingDialog; + if(answer == wxID_OK) + { + if(view) + { + view->AcceptsFocus(); + view->SetFocus(); + } + updateForeignKey(); + } + } + + //Is Start is connected Tell to check consistency + if(getStartFigure()) + { + getStartTable()->setSelectFkDestMode(false); + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + editor->checkAllDigramsRelConsistency(); + } + + //Hack to Abort Connection because user press cancel button at fk mapping dialog + if (answer == wxID_CANCEL) + { + //By disconnecting both sides I force to delete relationship at ConnectionCreationTool + getStartTable()->setSelectFkDestMode(false); + this->disconnectStart(); + this->disconnectEnd(); + } +} + +bool ddRelationshipFigure::isForeignKeyFromPk() +{ + return fkFromPk; +} + +void ddRelationshipFigure::setFkFrom(bool primaryKey, int useUkIndex, bool issueUpdateFk) +{ + if(useUkIndex >= 0) + { + fkFromPk = false; + ukIndex = useUkIndex; + } + else + { + fkFromPk = true; + ukIndex = -1; + } + + if(issueUpdateFk) + updateForeignKey(); +} + +void ddRelationshipFigure::connectStart(hdIConnector *start, hdDrawingView *view) +{ + hdLineConnection::connectStart(start); + if(getEndFigure() && getStartFigure()) + updateForeignKey(); +} + +void ddRelationshipFigure::disconnectStart(hdDrawingView *view) +{ + paintingFkColumns = false; + changeFkOSTextColor( *wxBLACK, *wxBLACK, true ); + disconnectedEndTable = (ddTableFigure *) getEndFigure(); + removeForeignKeys(); + hdLineConnection::disconnectStart(); +} + +void ddRelationshipFigure::disconnectEnd(hdDrawingView *view) +{ + paintingFkColumns = false; + changeFkOSTextColor( *wxBLACK, *wxBLACK, true ); + disconnectedEndTable = (ddTableFigure *) getEndFigure(); + hdLineConnection::disconnectEnd(); + removeForeignKeys(); +} + +void ddRelationshipFigure::addExistingColumnFk(ddColumnFigure *startTablesourceCol, wxString destColumn) +{ + ddTableFigure *endTable = (ddTableFigure *) getEndFigure(); + ddRelationshipItem *fkColumnRelItem; + ddColumnFigure *endTablesourceCol = endTable->getColumnByName(destColumn); + //Create a new relationship item but with an existing column for fk at destination table + if(endTablesourceCol) + { + fkColumnRelItem = new ddRelationshipItem(this, startTablesourceCol, endTable, (fkMandatory ? notnull : null), (fkIdentifying ? pk : noaction), endTablesourceCol); + //Mark it as Custom Fk (fk from existing column not an automatic generated) + endTablesourceCol->setAsUserCreatedFk(fkColumnRelItem); + chm[startTablesourceCol->getColumnName()] = fkColumnRelItem; //hashmap key will be original table name always + updateConnection(0); + } +} + +void ddRelationshipFigure::removeForeignKeys() +{ + if(disconnectedEndTable) + { + columnsHashMap::iterator it; + ddRelationshipItem *fkColumnRelItem; + + //This part of code (repeat) is a hack cause every time a column is delete hashmap is modified inside and becomes invalid iterator at that loop + bool repeat; + do + { + repeat = false; + for( it = chm.begin(); it != chm.end(); ++it ) + { + wxString key = it->first; + fkColumnRelItem = it->second; + if(fkColumnRelItem->getDestinationTable()->includes(fkColumnRelItem->fkColumn)) + { + //Remove fk column only if that column is automatically generated + if(fkColumnRelItem->isAutomaticallyGenerated()) + { + fkColumnRelItem->getDestinationTable()->removeColumn(0, fkColumnRelItem->fkColumn); + } //is an existing column use as fk + else + { + //Mark as existing column not used as foreign key destination + fkColumnRelItem->fkColumn->setAsUserCreatedFk(NULL); + } + chm.erase(it); + delete fkColumnRelItem; + repeat = true; + break; + } + } + } + while(repeat); + chm.clear(); + disconnectedEndTable = NULL; + } +} + +void ddRelationshipFigure::setOptionAtForeignKeys(ddColumnOptionType type) +{ + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + if(item->isAutomaticallyGenerated()) + item->fkColumn->setColumnOption(type); + } +} + +void ddRelationshipFigure::updatePkAtFkCols() +{ + bool changed = false; + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + if(item->isAutomaticallyGenerated()) //only update fk status at fk NOT created from an existing column + { + if(fkIdentifying) + { + item->fkColumn->enablePrimaryKey(); + } + else + { + item->fkColumn->disablePrimaryKey(); + } + changed = true; + } + } + + if(changed) //set as identifying relationship (hierarchy) + { + ddTableFigure *table = (ddTableFigure *) getEndFigure(); + table->updateFkObservers(); + } +} +wxString ddRelationshipFigure::generateSQL(wxString schemaName) +{ + wxString tmp; + if(chm.size() > 0) + { + tmp = wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + tmp += wxT("\"") + schemaName + wxT("\"."); + tmp += wxT("\"") + ((ddTableFigure *)getEndFigure())->getTableName() + wxT("\"") ; + + tmp += wxT(" ADD "); + if(!constraintName.IsEmpty()) + { + tmp += wxT("CONSTRAINT \"") + constraintName + wxT("\" "); + } + tmp += wxT("FOREIGN KEY ( "); + columnsHashMap::iterator it, end; + ddRelationshipItem *item; + for( it = chm.begin(); it != chm.end(); ++it ) + { + wxString key = it->first; + item = it->second; + tmp += wxT("\"") + item->fkColumn->getColumnName() + wxT("\""); + end = it; + end++; + if(end != chm.end()) + { + tmp += wxT(" , "); + } + else + { + tmp += wxT(" )"); + } + } + + tmp += wxT(" REFERENCES "); + if(!schemaName.IsEmpty()) + tmp += wxT("\"") + schemaName + _("\"."); + tmp += wxT("\"") + ((ddTableFigure *)getStartFigure())->getTableName() + wxT("\"") ; + + tmp += wxT(" ( "); + for( it = chm.begin(); it != chm.end(); ++it ) + { + wxString key = it->first; + item = it->second; + tmp += wxT("\"") + item->original->getColumnName() + wxT("\""); + end = it; + end++; + if(end != chm.end()) + { + tmp += wxT(" , "); + } + else + { + tmp += wxT(" )"); + } + } + + if(matchSimple) + tmp += wxT(" MATCH SIMPLE "); + else + tmp += wxT(" MATCH FULL "); + + tmp += wxT(" ON DELETE "); + switch(onDeleteAction) + { + case FK_ACTION_NO: + tmp += wxT(" NO ACTION "); + break; + case FK_RESTRICT: + tmp += wxT(" RESTRICT "); + break; + case FK_CASCADE: + tmp += wxT(" CASCADE "); + break; + case FK_SETNULL: + tmp += wxT(" SET NULL "); + break; + case FK_SETDEFAULT: + tmp += wxT(" SET DEFAULT "); + break; + } + + tmp += wxT(" ON UPDATE "); + switch(onUpdateAction) + { + case FK_ACTION_NO: + tmp += wxT(" NO ACTION "); + break; + case FK_RESTRICT: + tmp += wxT(" RESTRICT "); + break; + case FK_CASCADE: + tmp += wxT(" CASCADE "); + break; + case FK_SETNULL: + tmp += wxT(" SET NULL "); + break; + case FK_SETDEFAULT: + tmp += wxT(" SET DEFAULT "); + break; + } + + tmp += _(";\n"); + } + return tmp; +} + +ddTableFigure *ddRelationshipFigure::getStartTable() +{ + return (ddTableFigure *) getStartFigure(); +} + +ddTableFigure *ddRelationshipFigure::getEndTable() +{ + return (ddTableFigure *) getEndFigure(); +} + +void ddRelationshipFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdLineConnection::basicDrawSelected(context, view); + if(getEndFigure() && getStartFigure()) + { + paintingFkColumns = true; + changeFkOSTextColor(wxColour(255, 0, 0), wxColour(255, 0, 0)); + } +} + +void ddRelationshipFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdLineConnection::basicDraw(context, view); + if(getEndFigure() && getStartFigure() && paintingFkColumns) + { + paintingFkColumns = false; + changeFkOSTextColor( *wxBLACK, *wxBLACK, true ); + } +} + +void ddRelationshipFigure::changeFkOSTextColor(wxColour originalColour, wxColour fkColour, bool reset) +{ + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = chm.begin(); it != chm.end(); ++it) + { + wxString key = it->first; + item = it->second; + if(item->original) + { + if(!reset) + item->original->setTextColour(originalColour); + else + item->original->setTextColour(item->original->getOwnerTable()->fontColorAttribute->fontColor); + + } + if(item->fkColumn) + { + if(!reset) + item->fkColumn->setTextColour(fkColour); + else + item->fkColumn->setTextColour(item->fkColumn->getOwnerTable()->fontColorAttribute->fontColor); + } + } + +} + +//Used by persistence classes +int ddRelationshipFigure::getUkIndex() +{ + return ukIndex; +} + +//Used by persistence classes +actionKind ddRelationshipFigure::getOnUpdateAction() +{ + return onUpdateAction; +} + +//Used by persistence classes +actionKind ddRelationshipFigure::getOnDeleteAction() +{ + return onDeleteAction; +} + +//Used by persistence classes +bool ddRelationshipFigure::getMatchSimple() +{ + return matchSimple; +} + +//Used by persistence classes +void ddRelationshipFigure::initRelationValues( ddTableFigure *source, ddTableFigure *destination, int ukIdx, wxString constraint, actionKind onUpdate, actionKind onDelete, bool simpleMatch, bool identifying, bool oneToMany, bool mandatory, bool fromPk ) +{ + ukIndex = ukIdx; + fkFromPk = fromPk; + fkMandatory = mandatory; + fkOneToMany = oneToMany; + fkIdentifying = identifying; + matchSimple = simpleMatch; + onUpdateAction = onUpdate; + onDeleteAction = onDelete; + constraintName = constraint; + + //I need to add two points to relationship if there aren't any points for it a first position + int i, start = pointCount(0); + for(i = start; i < 2 ; i++) + { + addPoint(0, -100, -100); + } + + //reestablish connections between figures + hdLineConnection::connectStart(source->connectorAt(0, getStartPoint(0).x, getStartPoint(0).y)); + hdLineConnection::connectEnd(destination->connectorAt(0, getEndPoint(0).x, getEndPoint(0).y)); +} diff --git a/dd/dditems/figures/ddRelationshipItem.cpp b/dd/dditems/figures/ddRelationshipItem.cpp new file mode 100644 index 0000000..f820704 --- /dev/null +++ b/dd/dditems/figures/ddRelationshipItem.cpp @@ -0,0 +1,132 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipItem.cpp - Items (fk columns) inside a relationship figure hashmap +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/dditems/utilities/ddDataType.h" + +ddRelationshipItem::ddRelationshipItem() +{ + ownerRel = NULL; + original = NULL; + destinationTable = NULL; +} + +ddRelationshipItem::ddRelationshipItem(ddRelationshipFigure *owner, ddColumnFigure *originalColumn, ddTableFigure *destination, ddColumnOptionType type, ddColumnType colType, ddColumnFigure *existingColumn) +{ + ownerRel = owner; + original = originalColumn; + originalStartColName = original->getColumnName(false); + destinationTable = destination; + + if(existingColumn == NULL) //Fk destination column will be automatically generated + { + generatedName = autoGenerateNameForFk(); + fkColumn = new ddColumnFigure( generatedName, destinationTable, this); + fkColumn->setColumnOption(type); + fkColumn->toggleColumnKind(colType); + fkColumn->activateGenFkName(); //By default fk name is generate by using ( alias | tableName) . ColumnName combination + fkIsAutoGenerated = true; + } + else //using existing column as fk destination (Validation Required at user choices compatibility of types, precision and scale) + { + generatedName = wxEmptyString; + fkColumn = existingColumn; + fkColumn->setAsUserCreatedFk(this); + fkColumn->deactivateGenFkName(); + fkIsAutoGenerated = false; + } + + fkColumn->setRightIconForColumn(); +} + +ddRelationshipItem::~ddRelationshipItem() +{ +} + +void ddRelationshipItem::initRelationshipItemValues(ddRelationshipFigure *owner, ddTableFigure *destination, bool fromExistingColumn, ddColumnFigure *fkCol, ddColumnFigure *sourceCol, wxString initialColName) +{ + ownerRel = owner; + destinationTable = destination; + fkIsAutoGenerated = fromExistingColumn; + original = sourceCol; + fkColumn = fkCol; + originalStartColName = initialColName; + if(fkIsAutoGenerated) + fkColumn->setFkSource(this); + else + fkColumn->setAsUserCreatedFk(this); + + fkColumn->setRightIconForColumn(); +} + + +bool ddRelationshipItem::isAutomaticallyGenerated() +{ + return fkIsAutoGenerated; +} + +wxString ddRelationshipItem::autoGenerateNameForFk() +{ + wxString newName; + newName = original->getOwnerTable()->getTableName(); + newName.append(wxT("_")); + newName.append(originalStartColName); + return newName; +} + +void ddRelationshipItem::syncAutoFkName() +{ + originalStartColName = original->getColumnName(false); //Because original name was probably changed, now I should update it. + if(fkColumn->isGeneratedForeignKey() && fkColumn->isFkNameGenerated() ) + { + fkColumn->setColumnName(autoGenerateNameForFk()); + //Update all connections, but need to be notified to all views only doing it right now for first view + ownerRel->updateConnection(0); + } +} + +bool ddRelationshipItem::relationIsIdentifying() +{ + return ownerRel->getIdentifying(); +} + +bool ddRelationshipItem::relationIsMandatory() +{ + return ownerRel->getMandatory(); +} + +wxString ddRelationshipItem::sourceTableName() +{ + return original->getOwnerTable()->getTableName(); +} + +wxString ddRelationshipItem::destTableName() +{ + return destinationTable->getTableName(); +} + +bool ddRelationshipItem::isForeignKeyFromPk() +{ + if(ownerRel) + { + return ownerRel->isForeignKeyFromPk(); + } + return false; +} diff --git a/dd/dditems/figures/ddRelationshipTerminal.cpp b/dd/dditems/figures/ddRelationshipTerminal.cpp new file mode 100644 index 0000000..7d43d77 --- /dev/null +++ b/dd/dditems/figures/ddRelationshipTerminal.cpp @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipTerminal.cpp - Draw inverse arrows at fk terminal based on kind of relationship. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/figures/ddRelationshipTerminal.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdGeometry.h" + +ddRelationshipTerminal::ddRelationshipTerminal(ddRelationshipFigure *owner, bool endFigureTerminal) +{ + ownerFigure = owner; + endTerminal = endFigureTerminal; +} + +ddRelationshipTerminal::~ddRelationshipTerminal() +{ +} + +hdPoint &ddRelationshipTerminal::draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view) +{ + hdGeometry g; + hdPoint points[3]; + + context.SetPen(terminalLinePen); + + hdPoint aCopy = a, bCopy = b; + view->CalcScrolledPosition(aCopy.x, aCopy.y, &aCopy.x, &aCopy.y); + view->CalcScrolledPosition(bCopy.x, bCopy.y, &bCopy.x, &bCopy.y); + + if(endTerminal) + { + //Calc a point very far away of center of table to intersect one of the sides lines of the table rectangle figure + double X = aCopy.x + (bCopy.x - aCopy.x) * 0.9; + double Y = aCopy.y + (bCopy.y - aCopy.y) * 0.9; + + if(ownerFigure->getEndFigure() && ownerFigure->getOneToMany()) + { + hdRect r = ownerFigure->getEndFigure()->displayBox().gethdRect(view->getIdx()); + + view->CalcScrolledPosition(r.x, r.y, &r.x, &r.y); + + int centerX = r.x + r.width / 2; + int centerY = r.y + r.height / 2; + + context.SetPen(*wxBLACK_PEN); + context.SetBrush(*wxBLACK_BRUSH); + + double XX, YY, distance; + + //Calculate a new point to a given distance from the end of the relationship to draw many ( ----<| ) connector + //first calculate vector from point1 & point2 + double vectorx = aCopy.x - bCopy.x; + double vectory = aCopy.y - bCopy.y; + //calculate the length + double length = sqrt(vectorx * vectorx + vectory * vectory); + //normalize the vector to unit length + double normalizevx = vectorx / length; + double normalizevy = vectory / length; + distance = -15; + //calculate point a given distance + XX = bCopy.x + normalizevx * (length + distance); + YY = bCopy.y + normalizevy * (length + distance); + + wxPoint intersectionLine1(centerX, centerY); + wxPoint intersectionLine2(X, Y); + + //TOP + if(g.intersection(intersectionLine1, intersectionLine2, r.GetTopLeft(), r.GetTopRight())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x - 7, aCopy.y); + points[2] = wxPoint(aCopy.x + 7, aCopy.y); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX - 7, YY), wxPoint(XX + 7, YY)); + context.SetPen(*wxBLACK_PEN); + } + + } //RIGHT + else if(g.intersection(intersectionLine1, intersectionLine2, r.GetTopRight(), r.GetBottomRight())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x, aCopy.y - 7); + points[2] = wxPoint(aCopy.x, aCopy.y + 7); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX, YY - 7), wxPoint(XX, YY + 7)); + context.SetPen(*wxBLACK_PEN); + } + } //BOTTOM + else if(g.intersection(intersectionLine1, intersectionLine2, r.GetBottomLeft(), r.GetBottomRight())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x - 7, aCopy.y); + points[2] = wxPoint(aCopy.x + 7, aCopy.y); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX - 7, YY), wxPoint(XX + 7, YY)); + context.SetPen(*wxBLACK_PEN); + } + } //LEFT + else if(g.intersection(intersectionLine1, intersectionLine2, r.GetTopLeft(), r.GetBottomLeft())) + { + points[0] = wxPoint(XX, YY); + points[1] = wxPoint(aCopy.x, aCopy.y - 7); + points[2] = wxPoint(aCopy.x, aCopy.y + 7); + context.DrawPolygon(3, points); + + if(ownerFigure->getIdentifying()) + { + context.SetPen(wxPen(*wxBLACK, 2)); + context.DrawLine(wxPoint(XX, YY - 7), wxPoint(XX, YY + 7)); + context.SetPen(*wxBLACK_PEN); + } + } + else + { + //CENTER of star figure or invalid place, do nothing + } + + value = hdPoint(XX, YY); + return value; + } + value = hdPoint(0, 0); + return value; + } + value = hdPoint(0, 0); + return value; +} diff --git a/dd/dditems/figures/ddTableFigure.cpp b/dd/dditems/figures/ddTableFigure.cpp new file mode 100644 index 0000000..1290a55 --- /dev/null +++ b/dd/dditems/figures/ddTableFigure.cpp @@ -0,0 +1,1798 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableFigure.cpp - Draw table figure of a model +// +//////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/handles/ddAddColButtonHandle.h" +#include "dd/dditems/locators/ddAddColLocator.h" +#include "dd/dditems/handles/ddAddFkButtonHandle.h" +#include "dd/dditems/locators/ddAddFkLocator.h" +#include "dd/dditems/handles/ddRemoveTableButtonHandle.h" +#include "dd/dditems/locators/ddRemoveTableLocator.h" +#include "dd/dditems/handles/ddMinMaxTableButtonHandle.h" +#include "dd/dditems/locators/ddMinMaxTableLocator.h" +#include "dd/dditems/handles/ddScrollBarHandle.h" +#include "dd/dditems/locators/ddScrollBarTableLocator.h" +#include "dd/dditems/handles/ddSouthTableSizeHandle.h" +#include "dd/dditems/locators/ddTableBottomLocator.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "hotdraw/connectors/hdLocatorConnector.h" +#include "hotdraw/main/hdDrawing.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +//Images +#include "images/ddAddColumn.pngc" +#include "images/ddRemoveColumn.pngc" +#include "images/ddAddForeignKey.pngc" +#include "images/ddMaximizeTable.pngc" +#include "images/ddMinimizeTable.pngc" +#include "images/ddRemoveTable.pngc" + +/* +All figures title, colums, indexes are store at same array to improve performance in the following order: + [0] = table border rect + [1] = table title + [2] = first column index + [maxColIndex] = last column index + [minIdxIndex] = first index index + [maxIdxIndex] = last index index +*/ + +void ddTableFigure::Init(wxString tableName, int x, int y) +{ + setKindId(DDTABLEFIGURE); + internalPadding = 2; + externalPadding = 4; + selectingFkDestination = false; + + //Set Value default Attributes + fontColorAttribute->fontColor = wxColour(49, 79, 79); + //Set Value default selected Attributes + lineSelAttribute->pen().SetColour(wxColour(204, 0, 0)); + lineSelAttribute->pen().SetStyle(wxSOLID); + lineSelAttribute->pen().SetWidth(1); + fillSelAttribute->brush().SetColour(wxColour(255, 250, 205)); + fillAttribute->brush().SetColour(wxColour(248, 248, 255)); + fontSelColorAttribute->fontColor = wxColour(49, 79, 79); + + //Set table size, width and position + rectangleFigure = new hdRectangleFigure(); + rectangleFigure->moveTo(0, x, y); + add(rectangleFigure); + + tableTitle = new ddTextTableItemFigure(tableName, dt_null, NULL); + tableTitle->setOwnerTable(this); + tableTitle->setEditable(true); + tableTitle->moveTo(0, x, y); + tableTitle->disablePopUp(); + tableTitle->setShowDataType(false); + add(tableTitle); + tableTitle->moveTo(0, rectangleFigure->getBasicDisplayBox().x[0] + internalPadding * 2, rectangleFigure->getBasicDisplayBox().y[0] + internalPadding / 2); + + //Intialize handles + wxBitmap image = wxBitmap(*ddAddColumn_png_img); + wxSize valueSize = wxSize(8, 8); + figureHandles->addItem(new ddAddColButtonHandle((hdIFigure *)this, (hdILocator *)new ddAddColLocator(), image, valueSize)); + image = wxBitmap(*ddAddForeignKey_png_img); + figureHandles->addItem(new ddAddFkButtonHandle((hdIFigure *)this, (hdILocator *)new ddAddFkLocator(), image, valueSize)); + image = wxBitmap(*ddRemoveTable_png_img); + figureHandles->addItem(new ddRemoveTableButtonHandle((hdIFigure *)this, (hdILocator *)new ddRemoveTableLocator(), image, valueSize)); + image = wxBitmap(*ddMinimizeTable_png_img); + wxBitmap image2 = wxBitmap(*ddMaximizeTable_png_img); + figureHandles->addItem(new ddMinMaxTableButtonHandle((hdIFigure *)this, (hdILocator *)new ddMinMaxTableLocator(), image, image2, valueSize)); + figureHandles->addItem(new ddSouthTableSizeHandle(this, (hdILocator *)new ddTableBottomLocator())); + + //Intialize special handle + valueSize = wxSize(10, colsRect.GetSize().GetHeight()); + scrollbar = new ddScrollBarHandle(this, (hdILocator *)new ddScrollBarTableLocator(), valueSize); + + //Intialize columns window (min is always 1 in both, with or without cols & indxs) + colsRowsSize = 0; + colsWindow = 0; + idxsRowsSize = 0; + idxsWindow = 0; + + //Initialize indexes (pointers to array segments) + maxColIndex = 2; + minIdxIndex = 2; + maxIdxIndex = 2; + + //Initialize position where start to draw columns & indexes, this is the value to allow scrollbars + beginDrawCols = 2; + beginDrawIdxs = 2; + + //Initialize + pkName = wxEmptyString; + ukNames.clear(); + + updateTableSize(); + + basicDisplayBox.x[0] = x; + basicDisplayBox.y[0] = y; + belongsToSchema = false; +} + +ddTableFigure::ddTableFigure(wxString tableName, int x, int y): + hdCompositeFigure() +{ + Init(tableName, x, y); +} + +ddTableFigure::ddTableFigure(wxString tableName, int posIdx, int x, int y): + hdCompositeFigure() +{ + Init(tableName, 0, 0); + //Check figure available positions for diagrams, add at least needed to allow initialization of the class + int i, start; + start = basicDisplayBox.CountPositions(); + for(i = start; i < (posIdx + 1); i++) + { + AddPosForNewDiagram(); + } + syncInternalsPosAt(posIdx, x, y); +} + +//Used by persistence classes +void ddTableFigure::InitTableValues(wxArrayString UniqueKeysName, wxString primaryKeyName, int bdc, int bdi, int maxcolsi, int minidxsi, int maxidxsi, int colsrs, int colsw, int idxsrs, int idxsw) +{ + ukNames = UniqueKeysName; + pkName = primaryKeyName; + beginDrawCols = bdc; + beginDrawIdxs = bdi; + maxColIndex = maxcolsi; + minIdxIndex = minidxsi; + maxIdxIndex = maxidxsi; + colsRowsSize = colsrs; + colsWindow = colsw; + idxsRowsSize = idxsrs; + idxsWindow = idxsw; + updateTableSize(); +} + +ddTableFigure::~ddTableFigure() +{ + if(scrollbar) + { + if(figureHandles->existsObject(scrollbar)) + figureHandles->removeItem(scrollbar); + delete scrollbar; + } +} + +void ddTableFigure::AddPosForNewDiagram() +{ + //Add new position to internal calculations figure + fullSizeRect.addNewXYPosition(); + titleRect.addNewXYPosition(); + titleColsRect.addNewXYPosition(); + colsRect.addNewXYPosition(); + titleIndxsRect.addNewXYPosition(); + indxsRect.addNewXYPosition(); + unScrolledColsRect.addNewXYPosition(); + unScrolledFullSizeRect.addNewXYPosition(); + unScrolledTitleRect.addNewXYPosition(); + //Add to all figure figures + hdCompositeFigure::AddPosForNewDiagram(); +} + +void ddTableFigure::RemovePosOfDiagram(int posIdx) +{ + //Remove position for internal calculations figure + fullSizeRect.removeXYPosition(posIdx); + titleRect.removeXYPosition(posIdx); + titleColsRect.removeXYPosition(posIdx); + colsRect.removeXYPosition(posIdx); + titleIndxsRect.removeXYPosition(posIdx); + indxsRect.removeXYPosition(posIdx); + unScrolledColsRect.removeXYPosition(posIdx); + unScrolledFullSizeRect.removeXYPosition(posIdx); + unScrolledTitleRect.removeXYPosition(posIdx); + //remove position at all figure figures + hdCompositeFigure::RemovePosOfDiagram(posIdx); +} + +ddColumnFigure *ddTableFigure::getColByName(wxString name) +{ + ddColumnFigure *out = NULL; + ddColumnFigure *f; + + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(f->getColumnName(false).IsSameAs(name)) + { + out = f; + break; + } + } + delete iterator; + + return out; +} + +//WARNING: Columns SHOULD BE ADDED only using this function to avoid strange behaviors +void ddTableFigure::addColumn(int posIdx, ddColumnFigure *column) +{ + column->setOwnerTable(this); + add(column); + //Update Indexes + if(maxColIndex == minIdxIndex) //maxColIndex == minIdxIndex means not indexes at this table, then update too + { + minIdxIndex++; + maxIdxIndex++; + } + maxColIndex++; + colsWindow++; //by default add a column increase initial window + colsRowsSize++; + + updateTableSize(true); + + //Fix column position at all available positions (Diagrams) + int i; + for(i = 0; i < basicDisplayBox.CountPositions(); i++) + { + syncInternalsPosAt(i, basicDisplayBox.x[i], basicDisplayBox.y[i]); + } +} + +//WARNING: Function should be called on a table generated from a storage or to sync values after a big change at model (not derived from hotdraw events) +void ddTableFigure::syncInternalsPosAt(int posIdx, int x, int y) +{ + basicDisplayBox.x[posIdx] = x; + basicDisplayBox.y[posIdx] = y; + rectangleFigure->moveTo(posIdx, x, y); + tableTitle->moveTo(posIdx, rectangleFigure->getBasicDisplayBox().x[posIdx] + internalPadding * 2, rectangleFigure->getBasicDisplayBox().y[posIdx] + internalPadding / 2); + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); +} + +//WARNING: Function should be called on a table generated from a storage or to sync values after a big change at model (not derived from hotdraw events) +void ddTableFigure::syncInternalsPosAt(wxArrayInt &x, wxArrayInt &y) +{ + unsigned int posIdx, pointsCount = tableTitle->getBasicDisplayBox().CountPositions(), finalValue = x.Count(); + //I need to check that figures inside figure have all points too + while(pointsCount < finalValue) + { + AddPosForNewDiagram(); + pointsCount = tableTitle->getBasicDisplayBox().CountPositions(); + } + + //optimize this, because this is hack right now to avoid some weird problem when recreating figure status + basicDisplayBox.x = x; + basicDisplayBox.y = y; + + for(posIdx = 0; posIdx < finalValue; posIdx++) + { + rectangleFigure->moveTo(posIdx, x[posIdx], y[posIdx]); + tableTitle->moveTo(posIdx, rectangleFigure->getBasicDisplayBox().x[posIdx] + internalPadding * 2, rectangleFigure->getBasicDisplayBox().y[posIdx] + internalPadding / 2); + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } +} + +//WARNING: Columns SHOULD BE ADDED only using this columns if was created as an image from storage one +void ddTableFigure::addColumnFromStorage(ddColumnFigure *column) +{ + add(column); +} + +void ddTableFigure::removeColumn(int posIdx, ddColumnFigure *column) +{ + //Hack to allow to remove Fk before delete it. + if(column->isPrimaryKey() || column->isUniqueKey()) + { + column->setColumnKindToNone(); + } + + column->setOwnerTable(NULL); + remove(column); + + if(column) + delete column; + //Update Indexes + if(maxColIndex == minIdxIndex) //means not indexes at this table, then update too + { + minIdxIndex--; + maxIdxIndex--; + } + maxColIndex--; + if(colsRowsSize == colsWindow) //only decrease if size of window and columns is the same + colsWindow--; + colsRowsSize--; + if(beginDrawCols > 2) + beginDrawCols--; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + if(colsWindow == colsRowsSize) //if handle need to be removed, remove it + { + if(figureHandles->existsObject(scrollbar)) + figureHandles->removeItem(scrollbar); + } + //hack to update relationship position when table size change + manuallyNotifyChange(posIdx); + column = NULL; +} + +void ddTableFigure::recalculateColsPos(int posIdx) +{ + wxFont font = fontAttribute->font(); + int defaultHeight = getColDefaultHeight(font); + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); //first figure is always Rect + int horizontalPos = f->displayBox().x[posIdx] + 2; + int verticalPos = 0; + + for(int i = 2; i < maxColIndex ; i++) + { + f = (hdIFigure *) figureFigures->getItemAt(i); //table title + if( (i >= beginDrawCols) && (i <= (colsWindow + beginDrawCols)) ) //Visible to draw + { + verticalPos = colsRect.y[posIdx] + (defaultHeight * (i - beginDrawCols) + ((i - beginDrawCols) * internalPadding)); + f->moveTo(posIdx, horizontalPos, verticalPos); + } + else + f->moveTo(posIdx, -65000, -65000); //any figure outside canvas (x<0 || y<0) is not draw & not used to calculate displaybox + } +} + + + +void ddTableFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + int idx = view->getIdx(); + calcInternalSubAreas(idx); + + if(calcScrolled) //Hack to avoid pass view as parameter to calcInternalSubAreas() because is sometimes called outside a paint event + { + view->CalcScrolledPosition(fullSizeRect.x[idx], fullSizeRect.y[idx], &fullSizeRect.x[idx], &fullSizeRect.y[idx]); + view->CalcScrolledPosition(titleRect.x[idx], titleRect.y[idx], &titleRect.x[idx], &titleRect.y[idx]); + view->CalcScrolledPosition(titleColsRect.x[idx], titleColsRect.y[idx], &titleColsRect.x[idx], &titleColsRect.y[idx]); + view->CalcScrolledPosition(colsRect.x[idx], colsRect.y[idx], &colsRect.x[idx], &colsRect.y[idx]); + view->CalcScrolledPosition(titleIndxsRect.x[idx], titleIndxsRect.y[idx], &titleIndxsRect.x[idx], &titleIndxsRect.y[idx]); + view->CalcScrolledPosition(indxsRect.x[idx], indxsRect.y[idx], &indxsRect.x[idx], &indxsRect.y[idx]); + calcScrolled = false; + } + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); //table rectangle + f->draw(context, view); + f = (hdIFigure *) figureFigures->getItemAt(1); //table title + f->draw(context, view); + + for(int i = beginDrawCols; i < (colsWindow + beginDrawCols); i++) + { + f = (hdIFigure *) figureFigures->getItemAt(i); //table title + if(f->displayBox().GetPosition(view->getIdx()).x > 0 && f->displayBox().GetPosition(view->getIdx()).y > 0) + { + f->draw(context, view); + } + } + + reapplyAttributes(context, view); //reset attributes to default of figure because can be modified at Draw functions. + + //Set Font for title "Columns" + wxFont font = fontAttribute->font(); + int newSize = font.GetPointSize() * 0.7; + font.SetPointSize(newSize); + context.SetFont(font); + + //Draw Columns Title Line 1 + context.DrawLine(titleColsRect.GetTopLeft(idx), titleColsRect.GetTopRight(idx)); + //Draw Columns Title + context.DrawText(wxT("Columns"), titleColsRect.x[idx] + 3, titleColsRect.y[idx]); + //Draw Columns Title Line 2 + context.DrawLine(titleColsRect.GetBottomLeft(idx), titleColsRect.GetBottomRight(idx)); + //DrawVertical Lines + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 11, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 11, titleIndxsRect.GetTopLeft(idx).y); + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 22, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 22, titleIndxsRect.GetTopLeft(idx).y); + //Draw Indexes Title Line 1 + context.DrawLine(titleIndxsRect.GetTopLeft(idx), titleIndxsRect.GetTopRight(idx)); + //Draw Indexes Title + //disable until implemented in a future: context.DrawText(wxT("Indexes"),titleIndxsRect.x+3,titleIndxsRect.y); + //Draw Indexes Title Line 2 + context.DrawLine(titleIndxsRect.GetBottomLeft(idx), titleIndxsRect.GetBottomRight(idx)); + + context.SetFont(fontAttribute->font()); //after change font return always to initial one + + //Draw scrollbar is needed + if(scrollbar && figureHandles->existsObject(scrollbar)) + scrollbar->draw(context, view); + + //Use this in a future + //Hack to show message to select fk destination table + if(selectingFkDestination) + { + context.SetTextForeground(*wxWHITE); + wxBrush old = context.GetBrush(); + context.SetBrush(*wxBLACK_BRUSH); + + int w, h, x, y; + context.GetTextExtent(wxString(wxT("Select Destination table of foreign key")), &w, &h); + x = fullSizeRect.GetTopLeft(idx).x + (((fullSizeRect.GetTopRight(idx).x - fullSizeRect.GetTopLeft(idx).x) - w) / 2); + y = fullSizeRect.GetTopLeft(idx).y - h - 2; + context.DrawRectangle(wxRect(x, y, w, h)); + context.DrawText(wxString(wxT("Select Destination table of foreign key")), x, y); + + context.SetBrush(old); + context.SetTextForeground(*wxBLACK); + context.SetBackground(*wxWHITE); + + //don't draw anything else then don't reapply default attributes + } +} + +void ddTableFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + int idx = view->getIdx(); + calcInternalSubAreas(idx); + + if(calcScrolled) //Hack to avoid pass view as parameter to calcInternalSubAreas() because is sometimes called outside a paint event + { + view->CalcScrolledPosition(fullSizeRect.x[idx], fullSizeRect.y[idx], &fullSizeRect.x[idx], &fullSizeRect.y[idx]); + view->CalcScrolledPosition(titleRect.x[idx], titleRect.y[idx], &titleRect.x[idx], &titleRect.y[idx]); + view->CalcScrolledPosition(titleColsRect.x[idx], titleColsRect.y[idx], &titleColsRect.x[idx], &titleColsRect.y[idx]); + view->CalcScrolledPosition(colsRect.x[idx], colsRect.y[idx], &colsRect.x[idx], &colsRect.y[idx]); + view->CalcScrolledPosition(titleIndxsRect.x[idx], titleIndxsRect.y[idx], &titleIndxsRect.x[idx], &titleIndxsRect.y[idx]); + view->CalcScrolledPosition(indxsRect.x[idx], indxsRect.y[idx], &indxsRect.x[idx], &indxsRect.y[idx]); + calcScrolled = false; + } + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); //table rectangle + f->drawSelected(context, view); + f = (hdIFigure *) figureFigures->getItemAt(1); //table title + f->drawSelected(context, view); + + for(int i = beginDrawCols; i < (colsWindow + beginDrawCols); i++) + { + f = (hdIFigure *) figureFigures->getItemAt(i); //table title + if(f->displayBox().GetPosition(view->getIdx()).x > 0 && f->displayBox().GetPosition(view->getIdx()).y > 0) + { + f->drawSelected(context, view); + } + } + + reapplySelAttributes(context, view); //reset attributes to default of figure because can be modified at Draw functions. + wxFont font = fontAttribute->font(); + float t = font.GetPointSize(); + int newSize = font.GetPointSize() * 0.7; + font.SetPointSize(newSize); + context.SetFont(font); + + //Draw Columns Title Line 1 + context.DrawLine(titleColsRect.GetTopLeft(idx), titleColsRect.GetTopRight(idx)); + //Draw Columns Title + context.DrawText(wxT("Columns"), titleColsRect.x[idx] + 3, titleColsRect.y[idx]); + //Draw Columns Title Line 2 + context.DrawLine(titleColsRect.GetBottomLeft(idx), titleColsRect.GetBottomRight(idx)); + //DrawVertical Lines + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 11, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 11, titleIndxsRect.GetTopLeft(idx).y); + context.DrawLine(titleColsRect.GetBottomLeft(idx).x + 22, titleColsRect.GetBottomLeft(idx).y, titleColsRect.GetBottomLeft(idx).x + 22, titleIndxsRect.GetTopLeft(idx).y); + //Draw Indexes Title Line 1 + context.DrawLine(titleIndxsRect.GetTopLeft(idx), titleIndxsRect.GetTopRight(idx)); + //Draw Indexes Title + //disable until implemented in a future: context.DrawText(wxT("Indexes"),titleIndxsRect.x+3,titleIndxsRect.y); + //Draw Indexes Title Line 2 + context.DrawLine(titleIndxsRect.GetBottomLeft(idx), titleIndxsRect.GetBottomRight(idx)); +} + +hdMultiPosRect &ddTableFigure::getBasicDisplayBox() +{ + return basicDisplayBox; +} + +void ddTableFigure::setColsRowsWindow(int num) +{ + if(num > 0) + { + colsWindow = num; + wxFont font = fontAttribute->font(); + colsRect.height = getColDefaultHeight(font) * colsWindow; + colsRect.width = getFiguresMaxWidth(); + } +} + +int ddTableFigure::getHeightFontMetric(wxString text, wxFont font) +{ + int width, height; + wxBitmap emptyBitmap(*ddAddColumn_png_img); + wxMemoryDC temp_dc; + temp_dc.SelectObject(emptyBitmap); + temp_dc.SetFont(font); + temp_dc.GetTextExtent(text, &width, &height); + return height; +} + +int ddTableFigure::getColDefaultHeight(wxFont font) +{ + if(figureFigures->count() <= 0) + { + int width, height; + wxBitmap emptyBitmap(*ddAddColumn_png_img); + wxMemoryDC temp_dc; + temp_dc.SelectObject(emptyBitmap); + temp_dc.SetFont(font); + temp_dc.GetTextExtent(wxT("NewColumn"), &width, &height); + return height; + } + else + { + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(1); //table title + return f->displayBox().height; + } +} + +//Show select fk destination Message Hack +void ddTableFigure::setSelectFkDestMode(bool value) +{ + selectingFkDestination = value; +} + +int ddTableFigure::getFiguresMaxWidth() +{ + ddColumnFigure *cf; + hdGeometry g; + + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + int maxWidth = 0; + cf = (ddColumnFigure *) iterator->Next(); //Second figure is main title + maxWidth = g.max(maxWidth, cf->displayBox().width + 20); + while(iterator->HasNext()) + { + cf = (ddColumnFigure *) iterator->Next(); + maxWidth = g.max(maxWidth, cf->displayBox().width); + } + delete iterator; + if(figureHandles->existsObject(scrollbar)) + return maxWidth + 11; //as defined at locator + else + return maxWidth; +} + +void ddTableFigure::calcInternalSubAreas(int posIdx) +{ + calcScrolled = true; + + int maxWidth = getFiguresMaxWidth() + externalPadding; + if(maxWidth < 100) + maxWidth = 100; + wxFont font = fontAttribute->font(); + int defaultHeight = getColDefaultHeight(font); + + hdRect db = basicDisplayBox.gethdRect(posIdx); + + //*** titleRect + float t = font.GetPointSize(); + int newSize = font.GetPointSize() * 0.7; + font.SetPointSize(newSize); + int colsTitleHeight = getHeightFontMetric(wxT("Columns"), font); + + titleRect.x[posIdx] = db.x; + titleRect.y[posIdx] = db.y; + titleRect.width = maxWidth; + titleRect.height = defaultHeight; + + titleColsRect.x[posIdx] = db.x; + titleColsRect.y[posIdx] = titleRect.y[posIdx] + titleRect.height; + titleColsRect.width = maxWidth; + titleColsRect.height = colsTitleHeight; + unScrolledTitleRect = titleColsRect; + + //*** colsRect + colsRect.width = maxWidth; + if(colsWindow > 0) + colsRect.height = defaultHeight * colsWindow + (colsWindow * internalPadding); + else + colsRect.height = defaultHeight; + colsRect.x[posIdx] = db.x; + colsRect.y[posIdx] = titleRect.y[posIdx] + titleRect.height + titleColsRect.height; + unScrolledColsRect = colsRect; + + //*** idxTitleRect + titleIndxsRect.width = maxWidth; + titleIndxsRect.height = colsTitleHeight; + titleIndxsRect.x[posIdx] = db.x; + titleIndxsRect.y[posIdx] = colsRect.y[posIdx] + colsRect.height; + + //*** indexesRect + indxsRect.width = maxWidth; + indxsRect.height = defaultHeight * idxsWindow + (idxsWindow * internalPadding); + indxsRect.x[posIdx] = db.x; + indxsRect.y[posIdx] = titleIndxsRect.y[posIdx] + titleIndxsRect.height; + + //*** FullTable Size + fullSizeRect.width = maxWidth; + fullSizeRect.height = titleRect.height + titleColsRect.height + colsRect.height + titleIndxsRect.height + indxsRect.height; + fullSizeRect.x[posIdx] = db.x; + fullSizeRect.y[posIdx] = titleRect.y[posIdx]; + unScrolledFullSizeRect = fullSizeRect; + + //Update size + wxSize sizeValue = fullSizeRect.GetSize(); + rectangleFigure->setSize(sizeValue); +} + +void ddTableFigure::updateTableSize(bool notifyChange) +{ + //Step 0: Recalculate displaybox size, in case of an external modification as change of datatype in a fk from a source (data is stored in original table) + ddColumnFigure *cf; + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + cf = (ddColumnFigure *) iterator->Next(); //Second figure is main title + while(iterator->HasNext()) + { + cf = (ddColumnFigure *) iterator->Next(); + cf->displayBoxUpdate(); + } + delete iterator; + + //Step 1: Update table size + calcInternalSubAreas(0); + basicDisplayBox.SetSize(fullSizeRect.GetSize()); + if(notifyChange) + { + //hack to update relationship position when table size change, but need to be notified to all views only doing it right now for first view + manuallyNotifyChange(0); + } +} + +hdMultiPosRect &ddTableFigure::getColsSpace() +{ + return unScrolledColsRect; +} + +hdMultiPosRect &ddTableFigure::getFullSpace() +{ + return unScrolledFullSizeRect; +} + +hdMultiPosRect &ddTableFigure::getTitleRect() +{ + return unScrolledTitleRect; +} + + +int ddTableFigure::getTotalColumns() +{ + return colsRowsSize; +} + +int ddTableFigure::getColumnsWindow() +{ + return colsWindow; +} + +void ddTableFigure::setColumnsWindow(int posIdx, int value, bool maximize) +{ + + if(!maximize) + { + + //if value >0 && <= max size table && table+offset < maxColIndex with window + if( (value > 0) && (value <= colsRowsSize) && (maxColIndex >= ( beginDrawCols + value ) ) ) + { + colsWindow = value; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } + + //if special case of needing to modify beginDrawCols then do it + if( (value > 0) && (value <= colsRowsSize) && (maxColIndex < ( beginDrawCols + value ) ) ) + { + if( (beginDrawCols + colsWindow) == maxColIndex) //if index is at max + { + int diff = value - colsWindow; // value should be always higher tan colsWindows + if(diff > 0 && (beginDrawCols - diff) >= 0 ) + { + beginDrawCols -= diff; + colsWindow = value; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + + } + } + } + } + else + { + beginDrawCols = 2; + colsWindow = value; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } + + + //Hide Scrollbar if needed + if(colsWindow == colsRowsSize) + { + if(figureHandles->existsObject(scrollbar)) + figureHandles->removeItem(scrollbar); + } + else + { + if (!figureHandles->existsObject(scrollbar)) + figureHandles->addItem(scrollbar); + } + +} + +void ddTableFigure::columnsWindowUp(int posIdx) //move window from number to zero +{ + if( beginDrawCols > 2 ) + { + beginDrawCols--; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } +} + +void ddTableFigure::columnsWindowDown(int posIdx) //move window from number to maxcolumns +{ + if( (beginDrawCols + colsWindow) < maxColIndex) + { + beginDrawCols++; + calcInternalSubAreas(posIdx); + recalculateColsPos(posIdx); + } +} + +int ddTableFigure::getTopColWindowIndex() +{ + return (beginDrawCols - 2); +} + +void ddTableFigure::setPkConstraintName(wxString name) +{ + pkName = name; +} + +wxString ddTableFigure::getPkConstraintName() +{ + return pkName; +} + +wxArrayString ddTableFigure::getAllColumnsNames() +{ + wxArrayString tmp; + ddColumnFigure *f; + tmp.Clear(); + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + tmp.Add(f->getColumnName(false)); + } + delete iterator; + return tmp; +} + +wxArrayString ddTableFigure::getAllFkSourceColsNames(bool pk, int ukIndex) +{ + wxArrayString tmp; + ddColumnFigure *f; + tmp.Clear(); + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(pk) + { + if(f->isPrimaryKey()) + tmp.Add(f->getColumnName(false)); + } + else + { + if(f->isUniqueKey(ukIndex)) + tmp.Add(f->getColumnName(false)); + } + } + delete iterator; + return tmp; +} + +ddColumnFigure *ddTableFigure::getColumnByName(wxString name) +{ + ddColumnFigure *f; + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(f->getColumnName().IsSameAs(name)) + { + return f; + } + } + delete iterator; + return NULL; +} + +wxArrayString &ddTableFigure::getUkConstraintsNames() +{ + return ukNames; +} + +wxString ddTableFigure::getTableName() +{ + ddTextTableItemFigure *c = (ddTextTableItemFigure *) figureFigures->getItemAt(1); + c->setOneTimeNoAlias(); + return c->getText(false); +} + +//set Null on all relationship items with a fk column to be delete or a pk to be removed (pk attribute) +void ddTableFigure::prepareForDeleteFkColumn(ddColumnFigure *column) +{ + hdIteratorBase *iterator = observersEnumerator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iterator->Next(); + if(r->getStartFigure() == this) //Only update FK of connection with this table as source. source ---<| destination + r->prepareFkForDelete(column); + } + delete iterator; + +} + +// Note about observers: +// A table is observed by several relationships at same time, where that observers +// are just looking for changes that will affect relationship behavior. +// Ex: if I delete a pk on observed table (source) all observers (destination) +// should modify their columns to remove that fk created from that pk column. +// Warning: when a relationship is created an observer is added to both sides of relationship +// because this behavior (needed for update connection) to identify if is an observer +// of source table or destination table, should be check end figure, start!=end and end=this is end figure +// If start = and is recursive +void ddTableFigure::updateFkObservers() +{ + hdIteratorBase *iterator = observersEnumerator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iterator->Next(); + if(r->getStartFigure() == this) //Only update FK of connection with this table as source. source ---<| destination + { + r->updateForeignKey(); + } + } + delete iterator; +} + +//If a column change datatype, should alert all others table to adjust their size with new values +void ddTableFigure::updateSizeOfObservers() +{ + //For all tables that are observing this table, update their size + hdIteratorBase *iterator = observersEnumerator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iterator->Next(); + ddTableFigure *destFkTable = (ddTableFigure *) r->getEndFigure(); + destFkTable->updateTableSize(); + } + delete iterator; +} + +//drop foreign keys with this table as origin or destination because table is going to be deleted +void ddTableFigure::processDeleteAlert(hdDrawing *drawing) +{ + hdIteratorBase *iterator = observersEnumerator(); + bool repeatFlag; + do + { + repeatFlag = false; + iterator->ResetIterator(); + while(iterator->HasNext()) + { + ddRelationshipFigure *rel = (ddRelationshipFigure *) iterator->Next(); + rel->disconnectStart(); + rel->disconnectEnd(); + + drawing->getOwnerEditor()->removeFromAllSelections(rel); + drawing->getOwnerEditor()->deleteModelFigure(rel); + repeatFlag = true; + break; + } + } + while(repeatFlag); + + delete iterator; +} + +void ddTableFigure::basicMoveBy(int posIdx, int x, int y) +{ + + hdIFigure *f = (hdIFigure *) figureFigures->getItemAt(0); +//Hack to avoid bug in if clause + int width = spaceForMovement.GetWidth(); + int height = spaceForMovement.GetHeight(); + int bottom = f->displayBox().y[posIdx] + f->displayBox().height + y; + int right = f->displayBox().x[posIdx] + f->displayBox().width + x; + int left = f->displayBox().x[posIdx] + x; + int top = f->displayBox().y[posIdx] + y; + +//limit movemnt of table figures to canvas space + if( (left > 0) && (top > 0) && (right < width) && (bottom < height) ) + hdCompositeFigure::basicMoveBy(posIdx, x, y); +} + +//Validate status of table for SQL DDL generation +bool ddTableFigure::validateTable(wxString &errors) +{ + bool out = true; + wxString tmp = wxEmptyString; + ddColumnFigure *f; + + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //First figure is main rect + iterator->Next(); //Second figure is main title + + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + if(!f->validateColumn(tmp)) + { + out = false; + } + } + + if(!out) + { + errors.Append(wxT("\n")); + errors.Append(wxT("Errors detected at table") + this->getTableName() + wxT(" \n")); + errors.Append(tmp); + errors.Append(wxT("\n")); + } + + delete iterator; + + return out; +} + +//Using some options from http://www.postgresql.org/docs/8.1/static/sql-createtable.html, but new options can be added in a future. +wxString ddTableFigure::generateSQLCreate(wxString schemaName) +{ + //Columns and table + wxString tmp(wxT("CREATE TABLE ")); + if(!schemaName.IsEmpty()) + { + tmp += wxT("\"") + schemaName + wxT("\".\"") + getTableName() + wxT("\" (\n"); + } + else + { + tmp += wxT("\"") + getTableName() + wxT("\" (\n"); + } + hdIteratorBase *iterator = figuresEnumerator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + tmp += column->generateSQL(); + if(column->isNotNull()) + { + tmp += wxT(" NOT NULL"); + } + if(iterator->HasNext()) + { + tmp += wxT(" , \n"); + } + } + tmp += wxT("\n ); "); + + return tmp; +} + +wxString ddTableFigure::generateSQLAlterPks(wxString schemaName) +{ + wxString tmp; + hdIteratorBase *iterator = figuresEnumerator(); + //Pk, Uk Constraints + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + int contPk = 0; + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isPrimaryKey()) + contPk++; + } + if(contPk > 0) + { + tmp += wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + { + tmp += wxT("\"") + schemaName + wxT("\".\"") + getTableName() + wxT("\""); + } + else + { + tmp += wxT("\"") + getTableName() + wxT("\"") ; + } + + tmp += wxT(" ADD "); + + if(!pkName.IsEmpty()) + { + tmp += wxT("CONSTRAINT \"") + pkName + wxT("\" "); + } + tmp += wxT("PRIMARY KEY ( "); + iterator->ResetIterator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isPrimaryKey()) + { + tmp += wxT("\"") + column->getColumnName() + wxT("\""); + contPk--; + if(contPk > 0) + { + tmp += wxT(" , "); + } + else + { + tmp += wxT(" ); "); + } + } + } + } + delete iterator; + + return tmp; +} + +wxString ddTableFigure::generateSQLAlterFks(wxString schemaName) +{ + wxString tmp; + hdIteratorBase *iterator = figuresEnumerator(); + //Fk Constraint + iterator = observersEnumerator(); + if(!iterator->HasNext()) + { + tmp = wxEmptyString; + } + else + { + while(iterator->HasNext()) + { + ddRelationshipFigure *rel = (ddRelationshipFigure *) iterator->Next(); + if(rel->getStartFigure() != this) + { + tmp += rel->generateSQL(schemaName); + } + } + } + delete iterator; + return tmp; +} + +wxString ddTableFigure::generateSQLAlterUks(wxString schemaName) +{ + hdIteratorBase *iterator = figuresEnumerator(); + + //Pk, Uk Constraints + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + int MaxUk = -1; + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() > MaxUk) + MaxUk = column->getUniqueConstraintIndex(); + } + + wxString tmp = wxEmptyString; + if(MaxUk >= 0) + { + int i; + for(i = 0; i <= MaxUk; i++) + { + tmp += wxT("\nALTER TABLE "); + + if(!schemaName.IsEmpty()) + tmp += wxT("\"") + schemaName + wxT("\"."); + tmp += wxT("\"") + getTableName() + wxT("\"") ; + + tmp += wxT(" ADD "); + + if(!getUkConstraintsNames()[i].IsEmpty()) + { + tmp += wxT("CONSTRAINT \"") + getUkConstraintsNames()[i] + wxT("\" ") ; + } + tmp += wxT("UNIQUE ( "); + + int countUk = 0; + iterator->ResetIterator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->getUniqueConstraintIndex() == i) + countUk++; + } + + iterator->ResetIterator(); + iterator->Next(); //Fixed Position for table rectangle + iterator->Next(); //Fixed Position for table name + while(iterator->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iterator->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() == i) + { + tmp += wxT("\"") + column->getColumnName() + wxT("\""); + countUk--; + if(countUk > 0) + { + tmp += wxT(", "); + } + } + } + tmp += wxT(" ); "); + } + } + delete iterator; + return tmp; +} + +wxString ddTableFigure::generateAltersTable(pgConn *connection, wxString schemaName, ddDatabaseDesign *design) +{ + wxString out; + + OID oidTable = ddImportDBUtils::getTableOID(connection, schemaName, getTableName()); + if(oidTable == -1) + { + wxMessageBox(wxString::Format(_("Cannot build an ALTER TABLE statement for a non existing table (%s.%s)."), + schemaName.c_str(), getTableName().c_str()), _("Error when trying to get table OID"), wxICON_ERROR); + return wxEmptyString; + } + + ddStubTable *dbTable = ddImportDBUtils::getTable(connection, getTableName(), oidTable); + if(!dbTable) + { + wxMessageBox(wxString::Format(_("Cannot reverse engineering table %s.%s."), + schemaName.c_str(), getTableName().c_str()), _("Error when trying to get stub table"), wxICON_ERROR); + return wxEmptyString; + } + + //--------------- DETECT TABLE LEVEL CHANGES + + // Check if TABLE was renamed + // **Not supported yet** + + // Check if PRIMARY KEY constraint was renamed + // Some models don't set a name for the primary key, so we ignore those models + if(this->getPkConstraintName().Len() > 0 && !dbTable->PrimaryKeyName.IsSameAs(this->getPkConstraintName())) + { + out += wxT("\n"); + out += wxT("ALTER INDEX \"") + dbTable->PrimaryKeyName + wxT("\" RENAME TO \"") + this->getPkConstraintName() + wxT("\";"); + out += wxT("\n"); + } + + // Check if a UNIQUE KEY constraint was renamed + // **Not supported yet** (is it possible?) + + //--------------- DETECT COLUMN LEVEL CHANGES + + // Check if A COLUMN was renamed + // **Not supported yet** + + // Look for columns that exist in the database but not in the model + bool pkRemovedflag = false; + bool ukRemoved = false; + stubColsHashMap::iterator it; + ddStubColumn *item; + + for (it = dbTable->cols.begin(); it != dbTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + ddColumnFigure *column = getColumnByName(key); + + // Check for changes at the column + if(column) + { + // Generate ALTER COLUMN statement if needed + // Datatype change, length, and precision are checked + + // Temporary conversion fix to datatype of designer should be improved in a future + wxString dataType = item->typeColumn->Name(); + bool sameDatatype = true, sameScale = true, samePrecision = true; + int s = -1, p = -1; + bool useScale = true, needps = false; + + s = item->typeColumn->Length(); + p = item->typeColumn->Precision(); + + if(dataType.IsSameAs(wxT("character varying"), false)) + { + needps = true; + dataType = wxT("varchar(n)"); + } + + else if(dataType.IsSameAs(wxT("numeric"), false)) + { + needps = true; + useScale = false; + dataType = wxT("numeric(p,s)"); + } + else if(dataType.IsSameAs(wxT("interval"), false)) + { + needps = true; + dataType = wxT("interval(n)"); + } + else if(dataType.IsSameAs(wxT("bit"), false)) + { + needps = true; + dataType = wxT("bit(n)"); + } + else if(dataType.IsSameAs(wxT("char"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + else if(dataType.IsSameAs(wxT("varbit"), false)) + { + needps = true; + dataType = wxT("varbit(n)"); + } + else if(dataType.IsSameAs(wxT("character"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + + if(needps) + { + if(useScale) + { + samePrecision = column->getPrecision() == s; + } + else + { + samePrecision = column->getPrecision() == s; + sameScale = column->getScale() == p; + } + } + + + sameDatatype = column->getRawDataType().IsSameAs(dataType, false); + + if(!samePrecision || !sameScale || !sameDatatype) + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + + out += wxT(" ALTER COLUMN ") + column->generateSQL(true) + wxT(";"); + out += wxT("\n"); + } + } + else // DROP COLUMN because it doesn't exist in the model anymore + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + + out += wxT(" DROP COLUMN \"") + key + wxT("\";"); + out += wxT("\n"); + if(item->isPrimaryKey) + { + pkRemovedflag = true; + } + } + } + + // Look for columns that exist in the model but not in the database + hdIteratorBase *iteratorPK = figuresEnumerator(); + iteratorPK->Next(); //Fixed Position for table rectangle + iteratorPK->Next(); //Fixed Position for table name + + bool pkAddedflag = false; + while(iteratorPK->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorPK->Next(); + if(dbTable->cols.find(column->getColumnName()) == dbTable->cols.end()) //Exist in model but not in db + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ADD COLUMN ") + column->generateSQL() + wxT(";"); + out += wxT("\n"); + if(column->isPrimaryKey()) + { + pkAddedflag = true; + } + } + } + + // Look for all PRIMARY columns in the database's tables + bool pkChanged = false; + iteratorPK->ResetIterator(); + iteratorPK->Next(); //Fixed Position for table rectangle + iteratorPK->Next(); //Fixed Position for table name + while(iteratorPK->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorPK->Next(); + if(column->isPrimaryKey()) + { + if(dbTable->cols.find(column->getColumnName()) == dbTable->cols.end()) + { + pkChanged = true; + } + else + { + if(!dbTable->cols[column->getColumnName()]->isPrimaryKey) + { + pkChanged = true; + } + } + } + } + delete iteratorPK; + + // Look for all PRIMARY columns in the model + stubColsHashMap::iterator itCol; + ddStubColumn *itemCol; + for (itCol = dbTable->cols.begin(); itCol != dbTable->cols.end(); ++itCol) + { + wxString colStubName = itCol->first; + itemCol = itCol->second; + if(itemCol->isPrimaryKey) + { + ddColumnFigure *col = getColumnByName(colStubName); + if(col != NULL) + { + if(!col->isPrimaryKey()) + { + pkChanged = true; + } + } + else + { + pkChanged = true; + } + } + } + + + // Handle the addition of a new column to the primary key + if(pkAddedflag || pkRemovedflag || pkChanged) + { + // Drop existing primary key + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" DROP CONSTRAINT \"") + this->getPkConstraintName() + wxT("\";"); + // Create the new one + out += generateSQLAlterPks(schemaName); + } + + // Handle changes from NOT NULL to NULL (always after dropping PK) + for (it = dbTable->cols.begin(); it != dbTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + ddColumnFigure *column = getColumnByName(key); + + // Check for changes at the column level + if(column) + { + // Generate ALTER COLUMN statement if needed + // Datatype change, length and precision are handled. + + // Temporary conversion fix to datatype of designer should be improved in a future + wxString dataType = item->typeColumn->Name(); + bool sameDatatype = true, sameScale = true, samePrecision = true; + int s = -1, p = -1; + + // Model has now NULL constraint, so drop the NOT NULL constraint + if(column->isNotNull()) + { + if(!item->isNotNull) + { + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ALTER COLUMN \"") + column->getColumnName() + _("\" SET NOT NULL;"); + out += wxT("\n"); + } + } + else if(!column->isNotNull()) + { + if(item->isNotNull) + { + out += wxT("\n"); + out += wxT("ALTER TABLE \""); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT("\" ALTER COLUMN \"") + column->getColumnName() + wxT("\" DROP NOT NULL;"); + out += wxT("\n"); + } + } + } + } + + // Check UK conditions + int i, maxUkn = this->getUkConstraintsNames().Count(); + for(i = 0; i < maxUkn; i++) + { + if(this->getUkConstraintsNames()[i].Len() == 0) + { + wxMessageBox(wxString::Format(_("Some UNIQUE keys on table %s have no name.\nYou should set a name for them, so that pgAdmin can check consistency with the already available database constraints."), + getTableName().c_str()), _("Trying to build ALTER sentences"), wxICON_ERROR); + return wxEmptyString; + } + } + + // Search for UNIQUE key deleted from model, but available in the database + // Two steps process: first drop then delete from wxarraystring + int maxUkStub = dbTable->UniqueKeysNames.Count(); + for(i = 0; i < maxUkStub; i++) + { + // Drop UK [in db but not in model] + if(this->getUkConstraintsNames().Index(dbTable->UniqueKeysNames[i]) == wxNOT_FOUND) + { + // Drop it + out += wxT("\n"); + out += wxT("DROP INDEX \"") + dbTable->UniqueKeysNames[i] + wxT("\";"); + out += wxT("\n"); + + // This index metadata is not useful anymore, so erase it at temporary stub table. + stubColsHashMap::iterator itDelUkIdx; + ddStubColumn *itemDelUkIdx; + for (itDelUkIdx = dbTable->cols.begin(); itDelUkIdx != dbTable->cols.end(); ++itDelUkIdx) + { + wxString keyDelUkIdx = itDelUkIdx->first; + itemDelUkIdx = itDelUkIdx->second; + if(itemDelUkIdx->uniqueKeyIndex == i) + { + itemDelUkIdx->uniqueKeyIndex = -1; + } + } + } + } + + maxUkStub = dbTable->UniqueKeysNames.Count(); + for(i = 0; i < maxUkStub; i++) + { + // Drop UK [in db but not in model] + if(this->getUkConstraintsNames().Index(dbTable->UniqueKeysNames[i]) == wxNOT_FOUND) + { + dbTable->UniqueKeysNames.RemoveAt(i); + maxUkStub = dbTable->UniqueKeysNames.Count(); + } + } + + // Search for new UK in model to add ADD CONSTRAINT clause + int maxUkModel = this->getUkConstraintsNames().Count(); + for(i = 0; i < maxUkModel; i++) + { + // Add UK [in model but not in db] + if(dbTable->UniqueKeysNames.Index(this->getUkConstraintsNames()[i]) == wxNOT_FOUND) + { + // Create it + out += wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ADD "); + if(!getUkConstraintsNames()[i].IsEmpty()) + { + out += wxT(" CONSTRAINT \"") + getUkConstraintsNames()[i] + wxT("\" "); + } + out += wxT(" UNIQUE ( "); + + int countUk = 0; + hdIteratorBase *iteratorUk = figuresEnumerator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->getUniqueConstraintIndex() == i) + countUk++; + } + + iteratorUk->ResetIterator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() == i) + { + out += wxT("\"") + column->getColumnName() + wxT("\""); + countUk--; + if(countUk > 0) + { + out += wxT(", "); + } + else + { + out += wxT(");"); + } + } + } + delete iteratorUk; + } + } + + // After delete/create UK, look for changes at existing UK + // Unified UK indexes at both dbtable and ddTableFigure [same index at dbtable that in tablefigure] + // BUT in table figure exists indexes without an equivalent in dbtable + maxUkStub = this->getUkConstraintsNames().Count(); + for(i = 0; i < maxUkStub; i++) + { + int oldIndex = dbTable->UniqueKeysNames.Index(this->getUkConstraintsNames()[i]); + int newIndex = i; + + if(oldIndex != wxNOT_FOUND) + { + stubColsHashMap::iterator itDelUkIdx; + ddStubColumn *itemDelUkIdx; + for (itDelUkIdx = dbTable->cols.begin(); itDelUkIdx != dbTable->cols.end(); ++itDelUkIdx) + { + wxString keyDelUkIdx = itDelUkIdx->first; + itemDelUkIdx = itDelUkIdx->second; + if(item->uniqueKeyIndex == oldIndex) + { + item->uniqueKeyIndex = newIndex; + } + } + } + } + + // Generate again those UK that fill one of these conditions: + // 1. UK at tablefigure have more columns that at stub + // 2. Uk at stub have more column that at tablefigure + // Right now, UK constraints have unified indexes (same index at tablefigure and stub) + maxUkStub = this->getUkConstraintsNames().Count(); + + // for each UK + for(i = 0; i < maxUkStub; i++) + { + // Only for UKs with number unified that exists at both sides [db and tablefigure] [with boundaries check] + int boundarie1 = getUkConstraintsNames().Count(); + int boundarie2 = dbTable->UniqueKeysNames.Count(); + if( (i < boundarie1) && (i < boundarie2) && getUkConstraintsNames().Index( dbTable->UniqueKeysNames[i]) != wxNOT_FOUND ) + { + // Assumption + bool createUkAgain = false; + + // CHECK FIRST CONDITION ---> 1. UK at tablefigure have more columns that at stub? + hdIteratorBase *iteratorUk = figuresEnumerator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + // For each UK column of the constraint with same index (position i, constraint at getUkConstraintsNames()[] ) + if(column->getUniqueConstraintIndex() == i) + { + if(dbTable->cols.find(column->getColumnName()) == dbTable->cols.end()) //found at dbtable that uk column + { + createUkAgain = true; + } + else + { + ddStubColumn *stubCol = dbTable->cols[column->getColumnName()]; + if(!stubCol->isUniqueKey()) + { + createUkAgain = true; + } + } + } + } + delete iteratorUk; + + // CHECK SECOND CONDITION ---> UK at stub have more uk column of same index that at tablefigure? + stubColsHashMap::iterator itCol; + ddStubColumn *itemCol; + for (itCol = dbTable->cols.begin(); itCol != dbTable->cols.end(); ++itCol) + { + bool isAtFigure = false; + wxString colStubName = itCol->first; + itemCol = itCol->second; + if(itemCol->uniqueKeyIndex == i) + { + ddColumnFigure *colUk = getColumnByName(colStubName); + if(colUk == NULL) + { + createUkAgain = true; + } + else + { + if(!colUk->isUniqueKey()) + { + createUkAgain = true; + } + } + } + } + + if(createUkAgain) + { + // Drop it + out += wxT("\n"); + out += wxT("DROP INDEX \"") + dbTable->UniqueKeysNames[i] + wxT("\";"); + out += wxT("\n"); + + // Create it + out += wxT("\nALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + getTableName() + wxT("\"") ; + out += wxT(" ADD "); + if(!getUkConstraintsNames()[i].IsEmpty()) + { + out += wxT(" CONSTRAINT \"") + getUkConstraintsNames()[i] + wxT("\" "); + } + out += wxT(" UNIQUE ( "); + + int countUk = 0; + hdIteratorBase *iteratorUk = figuresEnumerator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->getUniqueConstraintIndex() == i) + countUk++; + } + + iteratorUk->ResetIterator(); + iteratorUk->Next(); //Fixed Position for table rectangle + iteratorUk->Next(); //Fixed Position for table name + while(iteratorUk->HasNext()) + { + ddColumnFigure *column = (ddColumnFigure *) iteratorUk->Next(); + if(column->isUniqueKey() && column->getUniqueConstraintIndex() == i) + { + out += wxT("\"") + column->getColumnName() + wxT("\""); + countUk--; + if(countUk > 0) + { + out += wxT(", "); + } + else + { + out += wxT(" );"); + } + } + } + delete iteratorUk; + } + } + } + + // Validate all FKs have a name defined at model + hdIteratorBase *iteratorRelations = observersEnumerator(); + while(iteratorRelations->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iteratorRelations->Next(); + if(r->getConstraintName().Len() == 0) // Add to list, FKs with this table as destination. source ---<| destination + { + wxMessageBox(wxString::Format(_("Some foreign keys keys on table %s have no name.\nYou should set a name for them, so that pgAdmin can check consistency with the already available database constraints."), + getTableName().c_str()), _("Trying to build ALTER sentences"), wxICON_ERROR); + return wxEmptyString; + } + } + + //Check Foreign Keys + // FK at model are same (including attributes and columns) at db + iteratorRelations->ResetIterator(); + while(iteratorRelations->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iteratorRelations->Next(); + if(r->getEndFigure() == this) // Only check FK this table as destination. source ---<| destination + { + // Check relationship from model exists a db? + if(ddImportDBUtils::existsFk(connection, dbTable->OIDTable, schemaName, r->getConstraintName(), r->getStartTable()->getTableName())) + { + // Columns and other properties are exactly the same? if not, then drop and create again + if(!ddImportDBUtils::isModelSameDbFk(connection, dbTable->OIDTable, schemaName, r->getConstraintName(), r->getStartTable()->getTableName(), r->getEndTable()->getTableName(), dbTable, r)) + { + // Drop it first + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + this->getTableName() + wxT("\"") ; + out += wxT(" DROP CONSTRAINT \"") + r->getConstraintName() + wxT("\";"); + out += wxT("\n"); + + // Then Add it again with changes + out += r->generateSQL(schemaName); + + } + } + else //relationship only exists at model and not in db + { + //Create because it doesn't exists + out += r->generateSQL(schemaName); + } + } + } + + // Check foreign keys available in the database but not in the model + // because we need to drop them + // First, create a list of FKs at destination table in the model + wxArrayString validFks; + iteratorRelations->ResetIterator(); + while(iteratorRelations->HasNext()) + { + ddRelationshipFigure *r = (ddRelationshipFigure *) iteratorRelations->Next(); + if(r->getEndFigure() == this) // Add to list, FKs with this table as destination. source ---<| destination + { + validFks.Add(r->getConstraintName()); + } + } + delete iteratorRelations; + + wxArrayString fksToDelete = ddImportDBUtils::getFkAtDbNotInModel(connection, dbTable->OIDTable, schemaName, validFks , design); + + int max = fksToDelete.Count(); + for(i = 0; i < max; i++) + { + // Drop it + out += wxT("\n"); + out += wxT("ALTER TABLE "); + if(!schemaName.IsEmpty()) + out += wxT("\"") + schemaName + wxT("\"."); + out += wxT("\"") + this->getTableName() + wxT("\"") ; + out += wxT(" DROP CONSTRAINT \"") + fksToDelete[i] + wxT("\";"); + out += wxT("\n"); + } + + if(dbTable) + delete dbTable; + return out; +} diff --git a/dd/dditems/figures/ddTextTableItemFigure.cpp b/dd/dditems/figures/ddTextTableItemFigure.cpp new file mode 100644 index 0000000..6bfbb0b --- /dev/null +++ b/dd/dditems/figures/ddTextTableItemFigure.cpp @@ -0,0 +1,582 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTextTableItemFigure.cpp - Draw a column inside a table +// +//////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/tools/ddColumnTextTool.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddPrecisionScaleDialog.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" + +ddTextTableItemFigure::ddTextTableItemFigure(wxString &columnName, ddDataType dataType, ddColumnFigure *owner): + hdSimpleTextFigure(columnName) +{ + setKindId(DDTEXTTABLEITEMFIGURE); + ownerTable = NULL; //table name item is the only one case of use of this variable + oneTimeNoAlias = false; + columnType = dataType; + this->setEditable(true); + enablePopUp(); + ownerColumn = owner; + showDataType = true; + showAlias = false; + recalculateDisplayBox(); + precision = -1; + scale = -1; + + if(owner) //is Column Object + { + fontColorAttribute->fontColor = owner->getOwnerTable()->fontColorAttribute->fontColor; + fontSelColorAttribute->fontColor = owner->getOwnerTable()->fontSelColorAttribute->fontColor; + } +} + +ddTextTableItemFigure::~ddTextTableItemFigure() +{ +} + +void ddTextTableItemFigure::recalculateDisplayBox() +{ + if (ownerColumn && ownerColumn->getOwnerTable()) + { + hdSimpleTextFigure::recalculateDisplayBox(); + displayBox().width = ownerColumn->getOwnerTable()->getFiguresMaxWidth(); + } +} + +void ddTextTableItemFigure::displayBoxUpdate() +{ + recalculateDisplayBox(); +} + +void ddTextTableItemFigure::setOwnerTable(ddTableFigure *table) +{ + ownerTable = table; + if(table)//is Table Name object + { + fontColorAttribute->fontColor = ownerTable->fontColorAttribute->fontColor; + fontSelColorAttribute->fontColor = ownerTable->fontSelColorAttribute->fontColor; + } +} + +wxString &ddTextTableItemFigure::getText(bool extended) +{ + if(showDataType && extended && getOwnerColumn()) + { + wxString ddType = dataTypes()[getDataType()]; //Should use getDataType() & getPrecision(), because when column is fk, type is not taken from this column, instead from original column (source of fk) + bool havePrecision = columnType == dt_numeric || columnType == dt_bit || columnType == dt_char || columnType == dt_interval || columnType == dt_varbit || columnType == dt_varchar; + if( havePrecision && getPrecision() >= 0) + { + ddType.Truncate(ddType.Find(wxT("("))); + if(getScale() == -1) + ddType += wxString::Format(wxT("(%d)"), getPrecision()); + else + ddType += wxString::Format(wxT("(%d,%d)"), getPrecision(), getScale()); + } + //Fix to serial is integer at automatically generated foreign key + if(getDataType() == dt_serial && getOwnerColumn()->isGeneratedForeignKey()) + ddType = dataTypes()[dt_integer]; + + out = wxString( hdSimpleTextFigure::getText() + wxString(wxT(" : ")) + ddType ); + return out; + } + else if( showAlias && getOwnerColumn() == NULL ) + { + if(!oneTimeNoAlias) + out = wxString( hdSimpleTextFigure::getText() + wxString(wxT(" ( ")) + colAlias + wxString(wxT(" ) ")) ); + else + { + out = wxString( hdSimpleTextFigure::getText() ); + oneTimeNoAlias = false; + } + return out; + } + else + { + return hdSimpleTextFigure::getText(); + } +} + +wxString ddTextTableItemFigure::getType(bool raw) +{ + wxString ddType = dataTypes()[columnType]; + if(raw) + return ddType; + + bool havePrecision = columnType == dt_numeric || columnType == dt_bit || columnType == dt_char || columnType == dt_interval || columnType == dt_varbit || columnType == dt_varchar; + if( havePrecision && getPrecision() >= 0) + { + ddType.Truncate(ddType.Find(wxT("("))); + if(getScale() == -1) + ddType += wxString::Format(wxT("(%d)"), getPrecision()); + else + ddType += wxString::Format(wxT("(%d,%d)"), getPrecision(), getScale()); + } + + //Fix to serial is integer at automatically generated foreign key + if(columnType == dt_serial && getOwnerColumn()->isGeneratedForeignKey()) + ddType = dataTypes()[dt_integer]; + + return ddType; +} + +//WARNING: event ID must match enum ddDataType!!! this event was created on view +void ddTextTableItemFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + wxTextEntryDialog *nameDialog = NULL; + ddPrecisionScaleDialog *numericDialog = NULL; + wxString tmpString; + int answer; + int tmpprecision; + long tmpvalue; + hdRemoveDeleteDialog *delremDialog = NULL; + + switch(event.GetId()) + { + case MNU_DDADDCOLUMN: + nameDialog = new wxTextEntryDialog(view, wxT("New column name"), wxT("Add a column")); + answer = nameDialog->ShowModal(); + if (answer == wxID_OK) + { + tmpString = nameDialog->GetValue(); + getOwnerColumn()->getOwnerTable()->addColumn(view->getIdx(), new ddColumnFigure(tmpString, getOwnerColumn()->getOwnerTable())); + view->notifyChanged(); + } + delete nameDialog; + break; + case MNU_DELCOLUMN: + answer = wxMessageBox(wxT("Are you sure you wish to delete column ") + getText(true) + wxT("?"), wxT("Delete column?"), wxYES_NO | wxNO_DEFAULT, view); + if (answer == wxYES) + { + getOwnerColumn()->getOwnerTable()->removeColumn(view->getIdx(), getOwnerColumn()); + view->notifyChanged(); + } + break; + case MNU_AUTONAMCOLUMN: + getOwnerColumn()->activateGenFkName(); + getOwnerColumn()->getFkSource()->syncAutoFkName(); + view->notifyChanged(); + break; + case MNU_RENAMECOLUMN: + nameDialog = new wxTextEntryDialog(view, wxT("New column name"), wxT("Rename Column"), getText()); + nameDialog->ShowModal(); + if(getOwnerColumn()->isGeneratedForeignKey()) //after a manual user column rename, deactivated automatic generation of fk name. + getOwnerColumn()->deactivateGenFkName(); + setText(nameDialog->GetValue()); + delete nameDialog; + view->notifyChanged(); + break; + case MNU_NOTNULL: + if(getOwnerColumn()->isNotNull()) + getOwnerColumn()->setColumnOption(null); + else + getOwnerColumn()->setColumnOption(notnull); + view->notifyChanged(); + break; + case MNU_PKEY: + if(getOwnerColumn()->isPrimaryKey()) + { + getOwnerColumn()->disablePrimaryKey(); + } + else + { + getOwnerColumn()->enablePrimaryKey(); + getOwnerColumn()->setColumnOption(notnull); + } + view->notifyChanged(); + break; + case MNU_UKEY: + getOwnerColumn()->toggleColumnKind(uk, view); + view->notifyChanged(); + break; + case MNU_TYPESERIAL: + setDataType(dt_serial); //Should use setDataType always to set this value to allow fk to work flawlessly + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEBOOLEAN: + setDataType(dt_boolean); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEINTEGER: + setDataType(dt_integer); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEMONEY: + setDataType(dt_money); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEVARCHAR: + setDataType(dt_varchar); + tmpprecision = wxGetNumberFromUser(_("Varchar size"), + _("Size for varchar datatype"), + _("Varchar size"), + getPrecision(), 0, 255, view); + if (tmpprecision >= 0) + { + setPrecision(tmpprecision); + setScale(-1); + } + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + view->notifyChanged(); + break; + case MNU_TYPEOTHER: + answer = wxGetSingleChoiceIndex(wxT("New column datatype"), wxT("Column Datatypes"), dataTypes(), view); + if(answer >= 0) + { + view->notifyChanged(); + if(answer == dt_varchar || answer == dt_bit || answer == dt_char || answer == dt_interval || answer == dt_varbit) + { + tmpprecision = wxGetNumberFromUser(_("datatype size"), + _("Size for datatype"), + _("size"), + getPrecision(), 0, 255, view); + if (tmpprecision >= 0) + { + setPrecision(tmpprecision); + setScale(-1); + } + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + } + if(answer == dt_numeric) + { + numericDialog = new ddPrecisionScaleDialog( view, + NumToStr((long)getPrecision()), + NumToStr((long)getScale())); + numericDialog->ShowModal(); + numericDialog->GetValue1().ToLong(&tmpvalue); + setPrecision(tmpvalue); + numericDialog->GetValue2().ToLong(&tmpvalue); + setScale(tmpvalue); + delete numericDialog; + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + } + + + setDataType( (ddDataType) answer ); + recalculateDisplayBox(); + getOwnerColumn()->displayBoxUpdate(); + getOwnerColumn()->getOwnerTable()->updateTableSize(); + } + break; + case MNU_TYPEPKEY_CONSTRAINTNAME: + tmpString = wxGetTextFromUser(wxT("New name of primary key:"), getOwnerColumn()->getOwnerTable()->getPkConstraintName(), getOwnerColumn()->getOwnerTable()->getPkConstraintName(), view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->setPkConstraintName(tmpString); + view->notifyChanged(); + } + break; + case MNU_TYPEUKEY_CONSTRAINTNAME: + answer = wxGetSingleChoiceIndex(wxT("Select Unique Key constraint to edit name"), wxT("Select Unique Constraint to edit name:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames(), view); + if(answer >= 0) + { + tmpString = wxGetTextFromUser(wxT("Change name of Unique Key constraint:"), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer), getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer), view); + if(tmpString.length() > 0) + { + getOwnerColumn()->getOwnerTable()->getUkConstraintsNames().Item(answer) = tmpString; + view->notifyChanged(); + } + } + break; + case MNU_DELTABLE: + + delremDialog = new hdRemoveDeleteDialog(wxT("Are you sure you wish to delete table ") + getOwnerColumn()->getOwnerTable()->getTableName() + wxT("?"), wxT("Delete table?"), view); + answer = delremDialog->ShowModal(); + ddTableFigure *table = getOwnerColumn()->getOwnerTable(); + if (answer == DD_DELETE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + //Unselect table at all diagrams + editor->removeFromAllSelections(table); + //Drop foreign keys with this table as origin or destination + table->processDeleteAlert(view->getDrawing()); + //Drop table + editor->deleteModelFigure(table); + editor->getDesign()->refreshBrowser(); + view->notifyChanged(); + } + else if(answer == DD_REMOVE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + editor->getExistingDiagram(view->getIdx())->removeFromSelection(table); + editor->getExistingDiagram(view->getIdx())->remove(table); + view->notifyChanged(); + } + delete delremDialog; + break; + } +} + +void ddTextTableItemFigure::createMenu(wxMenu &mnu) +{ + wxMenu *submenu; + wxMenuItem *item; + + mnu.Append(MNU_DDADDCOLUMN, _("Add a column...")); + item = mnu.Append(MNU_DELCOLUMN, _("Delete the selected column...")); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + mnu.Append(MNU_RENAMECOLUMN, _("Rename the selected column...")); + if(getOwnerColumn()->isGeneratedForeignKey() && !getOwnerColumn()->isFkNameGenerated()) + mnu.Append(MNU_AUTONAMCOLUMN, _("Activate fk auto-naming...")); + mnu.AppendSeparator(); + item = mnu.AppendCheckItem(MNU_NOTNULL, _("Not NULL constraint")); + if(getOwnerColumn()->isNotNull()) + item->Check(true); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + mnu.AppendSeparator(); + item = mnu.AppendCheckItem(MNU_PKEY, _("Primary Key")); + if(getOwnerColumn()->isPrimaryKey()) + item->Check(true); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + item = mnu.AppendCheckItem(MNU_UKEY, _("Unique Key")); + if(getOwnerColumn()->isUniqueKey()) + item->Check(true); + mnu.AppendSeparator(); + submenu = new wxMenu(); + item = mnu.AppendSubMenu(submenu, _("Column datatype")); + if(getOwnerColumn()->isGeneratedForeignKey()) + item->Enable(false); + item = submenu->AppendCheckItem(MNU_TYPESERIAL, _("serial")); + item->Check(columnType == dt_bigint); + item = submenu->AppendCheckItem(MNU_TYPEBOOLEAN, _("boolean")); + item->Check(columnType == dt_boolean); + item = submenu->AppendCheckItem(MNU_TYPEINTEGER, _("integer")); + item->Check(columnType == dt_integer); + item = submenu->AppendCheckItem(MNU_TYPEMONEY, _("money")); + item->Check(columnType == dt_money); + item = submenu->AppendCheckItem(MNU_TYPEVARCHAR, _("varchar(n)")); + item->Check(columnType == dt_varchar); + item = submenu->Append(MNU_TYPEOTHER, _("Choose another datatype...")); + mnu.AppendSeparator(); + mnu.Append(MNU_TYPEPKEY_CONSTRAINTNAME, _("Primary Key Constraint name...")); + mnu.Append(MNU_TYPEUKEY_CONSTRAINTNAME, _("Unique Key Constraint name...")); + mnu.AppendSeparator(); + mnu.Append(MNU_DELTABLE, _("Delete table...")); +}; + + +const wxArrayString ddTextTableItemFigure::dataTypes() +{ + if(ddDatatypes.IsEmpty()) + { + //Fast access ddDatatypes + ddDatatypes.Add(wxT("ANY")); + ddDatatypes.Add(wxT("serial")); + ddDatatypes.Add(wxT("boolean")); + ddDatatypes.Add(wxT("integer")); + ddDatatypes.Add(wxT("money")); + ddDatatypes.Add(wxT("varchar(n)")); + //Normal access ddDatatypes + ddDatatypes.Add(wxT("bigint")); + ddDatatypes.Add(wxT("bit(n)")); + ddDatatypes.Add(wxT("bytea")); + ddDatatypes.Add(wxT("char(n)")); + ddDatatypes.Add(wxT("cidr")); + ddDatatypes.Add(wxT("circle")); + ddDatatypes.Add(wxT("date")); + ddDatatypes.Add(wxT("double precision")); + ddDatatypes.Add(wxT("inet")); + ddDatatypes.Add(wxT("interval(n)")); + ddDatatypes.Add(wxT("line")); + ddDatatypes.Add(wxT("lseg")); + ddDatatypes.Add(wxT("macaddr")); + ddDatatypes.Add(wxT("numeric(p,s)")); + ddDatatypes.Add(wxT("path")); + ddDatatypes.Add(wxT("point")); + ddDatatypes.Add(wxT("polygon")); + ddDatatypes.Add(wxT("real")); + ddDatatypes.Add(wxT("smallint")); + ddDatatypes.Add(wxT("text")); + ddDatatypes.Add(wxT("time")); + ddDatatypes.Add(wxT("timestamp")); + ddDatatypes.Add(wxT("varbit(n)")); + } + return ddDatatypes; +} + +void ddTextTableItemFigure::setText(wxString textString) +{ + hdSimpleTextFigure::setText(textString); + + //Hack to allow column text to submit new size of text signal to tablefigure + //and then recalculate displaybox. Helps with fk autorenaming too. + if(ownerColumn) + { + ownerColumn->displayBoxUpdate(); + ownerColumn->getOwnerTable()->updateTableSize(); + ownerColumn->getOwnerTable()->updateFkObservers(); + } +} + +wxString ddTextTableItemFigure::getAlias() +{ + return colAlias; +} + +//Activate use of alias or short names at ddtextTableItems like TableNames [Columns don' use it] +void ddTextTableItemFigure::setAlias(wxString alias) +{ + if(alias.length() <= 0 || alias.length() > 3 ) + { + showAlias = false; + colAlias = wxEmptyString; + } + else + { + showAlias = true; + colAlias = alias; + } + recalculateDisplayBox(); + ownerTable->updateFkObservers(); //Only triggered by a tableName item [Not a column] + ownerTable->updateTableSize(); +} + +void ddTextTableItemFigure::setOneTimeNoAlias() +{ + oneTimeNoAlias = true; +} + +ddColumnFigure *ddTextTableItemFigure::getOwnerColumn() +{ + return ownerColumn; +} + +void ddTextTableItemFigure::setOwnerColumn(ddColumnFigure *column) +{ + ownerColumn = column; +} + +void ddTextTableItemFigure::setShowDataType(bool value) +{ + showDataType = value; +} + +hdITool *ddTextTableItemFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + if(getOwnerColumn()) + { + return textEditable ? new ddColumnTextTool(view, this, defaultTool, false, wxT("New Column Name"), wxT("Rename Column")) : defaultTool; + } + else + { + setOneTimeNoAlias(); + return textEditable ? new ddColumnTextTool(view, this, defaultTool, false, wxT("New Table Name"), wxT("Rename Table")) : defaultTool; + } +} + +int ddTextTableItemFigure::getTextWidth() +{ + int w, h; + getFontMetrics(w, h); + return w; +} + +int ddTextTableItemFigure::getTextHeight() +{ + int w, h; + getFontMetrics(w, h); + return h; +} + +ddDataType ddTextTableItemFigure::getDataType() +{ + if(!getOwnerColumn()->isGeneratedForeignKey()) + return columnType; + else + { + columnType = getOwnerColumn()->getFkSource()->original->getDataType(); + return columnType; + } +} + +void ddTextTableItemFigure::setDataType(ddDataType type) +{ + columnType = type; + ownerColumn->getOwnerTable()->updateSizeOfObservers(); +} + +int ddTextTableItemFigure::getPrecision() +{ + if(getOwnerColumn()->isGeneratedForeignKey()) + { + precision = getOwnerColumn()->getFkSource()->original->getPrecision(); + return precision; + } + else + { + return precision; + } +} + +void ddTextTableItemFigure::setPrecision(int value) +{ + if(!getOwnerColumn()->isGeneratedForeignKey()) + { + precision = value; + ownerColumn->getOwnerTable()->updateSizeOfObservers(); + } +} + +void ddTextTableItemFigure::setScale(int value) +{ + if(!getOwnerColumn()->isGeneratedForeignKey()) + { + scale = value; + ownerColumn->getOwnerTable()->updateSizeOfObservers(); + } +} + +int ddTextTableItemFigure::getScale() +{ + if(getOwnerColumn()->isGeneratedForeignKey()) + { + scale = getOwnerColumn()->getFkSource()->original->getScale(); + return scale; + } + else + { + return scale; + } +} diff --git a/dd/dditems/figures/module.mk b/dd/dditems/figures/module.mk new file mode 100644 index 0000000..14e0f4c --- /dev/null +++ b/dd/dditems/figures/module.mk @@ -0,0 +1,25 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/figures/ddColumnFigure.cpp \ + dd/dditems/figures/ddColumnKindIcon.cpp \ + dd/dditems/figures/ddColumnOptionIcon.cpp \ + dd/dditems/figures/ddRelationshipFigure.cpp \ + dd/dditems/figures/ddRelationshipItem.cpp \ + dd/dditems/figures/ddRelationshipTerminal.cpp \ + dd/dditems/figures/ddTableFigure.cpp \ + dd/dditems/figures/ddTextTableItemFigure.cpp + +EXTRA_DIST += \ + dd/dditems/figures/module.mk + +include dd/dditems/figures/xml/module.mk diff --git a/dd/dditems/figures/xml/ddXmlStorage.cpp b/dd/dditems/figures/xml/ddXmlStorage.cpp new file mode 100644 index 0000000..ddf3bfd --- /dev/null +++ b/dd/dditems/figures/xml/ddXmlStorage.cpp @@ -0,0 +1,1828 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddXmlStorage.cpp - Database designer class for storing / loading objects +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include +#include +#include + +// App headers +#include "dd/dditems/figures/xml/ddXmlStorage.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/figures/hdIFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/figures/ddRelationshipTerminal.h" +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +ddDatabaseDesign *ddXmlStorage::design = NULL; +ctlAuiNotebook *ddXmlStorage::tabs = NULL; + +ddXmlStorage::ddXmlStorage(): + hdStorage() +{ + design = NULL; + tabs = NULL; +} + +#define XML_FROM_WXSTRING(s) ((xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) + +void ddXmlStorage::setModel(ddDatabaseDesign *sourceDesign) +{ + design = sourceDesign; +} + +void ddXmlStorage::setNotebook(ctlAuiNotebook *notebook) +{ + tabs = notebook; +} + +void ddXmlStorage::StartModel(xmlTextWriterPtr writer, ddDatabaseDesign *sourceDesign) +{ + int tmp; + design = sourceDesign; + // but add all dtd to doc instead url + wxString name = _("MODEL"); + wxString pubid = _("pgrm"); + wxString uri = _("pgrm"); + + xmlTextWriterWriteDTD(writer, XML_FROM_WXSTRING(name), NULL, NULL, XML_FROM_WXSTRING(getModelDTD())); + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "MODEL"); + processResult(tmp); + + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "VERSION"); + processResult(tmp); + // + wxString version = sourceDesign->getVersionXML(); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "VERIXLU", XML_FROM_WXSTRING(version) ); + processResult(tmp); + //Close VERSION Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::EndModel( xmlTextWriterPtr writer) +{ + //Close MODEL Element + xmlTextWriterEndElement(writer); + design = NULL; +} + +bool ddXmlStorage::Write(xmlTextWriterPtr writer, hdIFigure *figure) +{ + if(design == NULL) + { + wxMessageBox(_("Error saving model: not source model have been set")); + return false; + } + + switch(figure->getKindId()) + { + case DDCOLUMNOPTIONICON: + WriteLocal(writer, (ddColumnOptionIcon *)figure); + break; + case DDCOLUMNKINDICON: + WriteLocal(writer, (ddColumnKindIcon *)figure); + break; + case DDTEXTTABLEITEMFIGURE: + WriteLocal(writer, (ddTextTableItemFigure *)figure); + break; + case DDCOLUMNFIGURE: + WriteLocal(writer, (ddColumnFigure *)figure); + break; + case DDTABLEFIGURE: + WriteLocal(writer, (ddTableFigure *)figure); + break; + case DDRELATIONSHIPFIGURE: + WriteLocal(writer, (ddRelationshipFigure *)figure); + break; + } + return true; +} + +bool ddXmlStorage::processResult(int value) +{ + if (value < 0) + { + wxMessageBox(_("Fatal Error at libxml for figure persistency")); + return false; + } + return true; +} + +void ddXmlStorage::WriteLocal(xmlTextWriterPtr writer, ddColumnOptionIcon *figure) +{ + int tmp; + + //At COLUMN Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "OPTION", "%d", figure->getOption() ); + processResult(tmp); +} + +void ddXmlStorage::WriteLocal(xmlTextWriterPtr writer, ddColumnKindIcon *figure) +{ + int tmp; + + //At COLUMN Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UKINDEX", "%d", figure->getUniqueConstraintIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ISPK", "%c", figure->isPrimaryKey() ? 'T' : 'F' ); + processResult(tmp); +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddTextTableItemFigure *figure) +{ + int tmp; + + // + wxString ddType = figure->dataTypes()[figure->getDataType()]; + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLUMNTYPE", "%s", XML_FROM_WXSTRING(ddType)); + processResult(tmp); + + if(figure->getPrecision() != -1) + { + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PRECISION", "%d", figure->getPrecision()); + processResult(tmp); + } + + if(figure->getScale() != -1) + { + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SCALE", "%d", figure->getScale()); + processResult(tmp); + } + +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddColumnFigure *figure) +{ + int tmp; + + //At TABLE Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "COLUMN"); + + // + wxString columnName = figure->getColumnName(false); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(columnName)); + processResult(tmp); + + //At Column Element + Write(writer, figure->getOptionImage()); + Write(writer, figure->getKindImage()); + Write(writer, figure->getColumnText()); + + //At Column Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "GENERATEFKNAME", "%c", figure->isFkNameGenerated() ? 'T' : 'F' ); + processResult(tmp); + + //Close COLUMN Element + xmlTextWriterEndElement(writer); + processResult(tmp); +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddTableFigure *figure) +{ + int tmp; + + //At TABLES ELEMENT + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "TABLE"); + processResult(tmp); + + // --> ddTableFigure ID + wxString TableId = design->getTableId(figure->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "TableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + //Start POINTS + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINTS"); + processResult(tmp); + int posIdx, positionsCount = figure->getBasicDisplayBox().CountPositions(); + for(posIdx = 0; posIdx < positionsCount; posIdx++) + { + //Start POINT + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINT"); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X", "%d", figure->getBasicDisplayBox().x[posIdx]); + processResult(tmp); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Y", "%d", figure->getBasicDisplayBox().y[posIdx]); + processResult(tmp); + //Close POINT Element + xmlTextWriterEndElement(writer); + } + xmlTextWriterEndElement(writer); + //Close POINTS Element + + //Add Table Title + ddColumnFigure *f; + hdIteratorBase *iterator = figure->figuresEnumerator(); + iterator->Next(); //First figure is main rect + + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "TITLE"); + processResult(tmp); + f = (ddColumnFigure *) iterator->Next(); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(figure->getTableName())); + processResult(tmp); + + //Close TITLE Element + xmlTextWriterEndElement(writer); + + if(figure->getUkConstraintsNames().Count() > 0) + { + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "UKNAMES"); + processResult(tmp); + + // one for each name + int i, last = figure->getUkConstraintsNames().Count(); + wxString ukName; + for(i = 0; i < last; i++) + { + ukName = figure->getUkConstraintsNames()[i]; + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UKNAME", "%s", XML_FROM_WXSTRING(ukName)); + processResult(tmp); + } + + //Close UKNAMES Element + xmlTextWriterEndElement(writer); + } + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "PKNAME", "%s", XML_FROM_WXSTRING(figure->getPkConstraintName())); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BEGINDRAWCOLS", "%d", figure->getBeginDrawCols()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "BEGINDRAWIDXS", "%d", figure->getBeginDrawIdxs()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MAXCOLINDEX", "%d", figure->getMaxColIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MINIDXINDEX", "%d", figure->getMinIdxIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MAXIDXINDEX", "%d", figure->getMaxIdxIndex()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLSROWSSIZE", "%d", figure->getColsRowsSize()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "COLSWINDOW", "%d", figure->getColsWindow()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IDXSROWSSIZE", "%d", figure->getIdxsRowsSize()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IDXSWINDOW", "%d", figure->getIdxsWindow()); + processResult(tmp); + + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "COLUMNS"); + processResult(tmp); + + //ALL COLUMN ELEMENT + while(iterator->HasNext()) + { + f = (ddColumnFigure *) iterator->Next(); + Write(writer, f); + } + delete iterator; + + //Close COLUMNS Element + xmlTextWriterEndElement(writer); + + //Close TABLE Element + xmlTextWriterEndElement(writer); + +} + + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddRelationshipFigure *figure) +{ + int tmp; + + //At RELATIONSHIPS Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "RELATIONSHIP"); + + // --> ddTableFigure ID + wxString TableId = design->getTableId(figure->getStartTable()->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "SourceTableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + // + TableId = design->getTableId(figure->getEndTable()->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "DestTableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + //At RELATIONSHIP Element + + //Start POINTSRELATION + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINTSRELATION"); + hdPoint point; + + for(int posIdx = 0 ; posIdx < figure->pointLinesCount(); posIdx++) + { + //At POINTSRELATION Element + //Start POINTS + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINTS"); + for(int i = 0; i < figure->pointCount(posIdx); i++) + { + //At POINTS Element + //Start POINT + tmp = xmlTextWriterStartElement(writer, BAD_CAST "POINT"); + point = figure->pointAt(posIdx, i); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "X", "%d", point.x); + processResult(tmp); + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "Y", "%d", point.y); + processResult(tmp); + //Close POINT Element + xmlTextWriterEndElement(writer); + } + //Close POINTS Element + xmlTextWriterEndElement(writer); + } + //Close POINTSRELATION Element + xmlTextWriterEndElement(writer); + + //At RELATIONSHIP Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "UKINDEX", "%d", figure->getUkIndex()); + processResult(tmp); + + if(figure->getConstraintName().Length() > 0) + { + // + wxString name = figure->getConstraintName(); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(name)); + processResult(tmp); + } + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ONUPDATE", "%d", figure->getOnUpdateAction()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ONDELETE", "%d", figure->getOnDeleteAction()); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MATCHSIMPLE", "%c", figure->getMatchSimple() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "IDENTIFYING", "%c", figure->getIdentifying() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "ONETOMANY", "%c", figure->getOneToMany() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "MANDATORY", "%c", figure->getMandatory() ? 'T' : 'F' ); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "FKFROMPK", "%c", figure->isForeignKeyFromPk() ? 'T' : 'F' ); + processResult(tmp); + + //At RELATIONSHIP Element + //Start RELATIONITEMS + tmp = xmlTextWriterStartElement(writer, BAD_CAST "RELATIONITEMS"); + + ddRelationshipItem *item; + wxString key; + columnsHashMap::iterator it; + for( it = figure->getItemsHashMap().begin(); it != figure->getItemsHashMap().end(); ++it ) + { + key = it->first; + item = it->second; + ddXmlStorage::WriteLocal(writer, item); + } + + //Close RELATIONITEMS + xmlTextWriterEndElement(writer); + + //Close RELATIONSHIP Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::WriteLocal( xmlTextWriterPtr writer, ddRelationshipItem *item) +{ + int tmp; + + //At RELATIONITEMS Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "RELATIONITEM"); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "AUTOGENFK", "%c", item->isAutomaticallyGenerated() ? 'T' : 'F' ); + processResult(tmp); + + // + wxString fkColName = item->fkColumn->getColumnName(); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "FKCOLNAME", "%s", XML_FROM_WXSTRING(fkColName)); + processResult(tmp); + + // + wxString sourceColName = item->original->getColumnName(); + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "SOURCECOLNAME", "%s", XML_FROM_WXSTRING(sourceColName)); + processResult(tmp); + + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "INITIALCOLNAME", "%s", XML_FROM_WXSTRING(item->originalStartColName)); + processResult(tmp); + + //Close RELATIONITEM Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::StarDiagrams( xmlTextWriterPtr writer) +{ + //At MODEL Element + // + xmlTextWriterStartElement(writer, BAD_CAST "DIAGRAMS"); +} + +void ddXmlStorage::EndDiagrams( xmlTextWriterPtr writer) +{ + + //Close DIAGRAMS Element + xmlTextWriterEndElement(writer); +} + +void ddXmlStorage::WriteLocal(xmlTextWriterPtr writer, hdDrawing *diagram) +{ + int tmp; + + //At DIAGRAMS Element + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "DIAGRAM"); + + //At DIAGRAM Element + // + tmp = xmlTextWriterWriteFormatElement(writer, BAD_CAST "NAME", "%s", XML_FROM_WXSTRING(diagram->getName()) ); + processResult(tmp); + + hdIteratorBase *iterator = diagram->figuresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + // + tmp = xmlTextWriterStartElement(writer, BAD_CAST "TABLEREF"); + + // --> ddTableFigure ID + wxString TableId = design->getTableId(table->getTableName()); + tmp = xmlTextWriterWriteAttribute(writer, BAD_CAST "TableID", XML_FROM_WXSTRING(TableId) ); + processResult(tmp); + + //Close TABLEREF Element + xmlTextWriterEndElement(writer); + } + } + delete iterator; + + //Close DIAGRAM Element + xmlTextWriterEndElement(writer); +} + +//This is needed because table doesn't have any explicit order when stored then I created all first +void ddXmlStorage::initialModelParse(xmlTextReaderPtr reader) +{ + int ret, tmp; + xmlChar *value; + + if(reader != NULL) + { + wxString tableName = wxEmptyString, tableAlias = wxEmptyString, TableID; + xmlTextReaderSetParserProp( reader, XML_PARSER_VALIDATE, 1 ); + ret = xmlTextReaderRead(reader); + while (ret == 1) + { + if(getNodeType(reader) == 1 && getNodeName(reader).IsSameAs(_("TABLE"), false)) //libxml 1 for start element + { + //Look for table ID + tmp = xmlTextReaderHasAttributes(reader); + TableID = _("TableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(TableID)); + } + + if(value) + { + TableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + // + wxString tmpInt; + tmp = xmlTextReaderRead(reader); //go to POINTS + wxArrayInt x, y; + if(getNodeName(reader).IsSameAs(_("POINTS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + tmp = xmlTextReaderRead(reader); //go POINT + do + { + // --> POINT + // + tmp = xmlTextReaderRead(reader); //go X + tmp = xmlTextReaderRead(reader); //go X Value + tmp = xmlTextReaderRead(reader); //go to /X + + tmp = xmlTextReaderRead(reader); //go Y + tmp = xmlTextReaderRead(reader); //go Y Value + tmp = xmlTextReaderRead(reader); //go to /Y + + tmp = xmlTextReaderRead(reader); //go /POINT + tmp = xmlTextReaderRead(reader); //go POINT or /POINTS ? + } + while(getNodeName(reader).IsSameAs(_("POINT"), false)); + } + + tmp = xmlTextReaderRead(reader); //go to TITLE + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + tableName = WXSTRING_FROM_XML(value); + design->addTableToMapping(TableID, tableName); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + + tmp = xmlTextReaderRead(reader); //go to ALIAS or /TITLE + if(getNodeName(reader).IsSameAs(_("ALIAS"), false)) + { + tmp = xmlTextReaderRead(reader); //go to ALIAS Value + value = xmlTextReaderValue(reader); //Value of ALIAS + if(value) + { + tableAlias = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ALIAS + tmp = xmlTextReaderRead(reader); //go to /TITLE + } + ddTableFigure *t = new ddTableFigure(tableName, -1, -1); + + design->addTableToModel(t); + } + ret = xmlTextReaderRead(reader); + } + + //Once the document has been fully parsed check the validation results + if (xmlTextReaderIsValid(reader) != 1) + { + wxMessageBox(_("Model is not following embedded DTD definition, check it.\n")); + return; + } + } + //reset reader to begining of stream +} + + + +bool ddXmlStorage::Read(xmlTextReaderPtr reader) +{ + int ret; + + if(reader != NULL) + { + xmlTextReaderSetParserProp( reader, XML_PARSER_VALIDATE, 1 ); + ret = xmlTextReaderRead(reader); + while (ret == 1) + { + selectReader(reader); + ret = xmlTextReaderRead(reader); + } + + //Once the document has been fully parsed check the validation results + if (xmlTextReaderIsValid(reader) != 1) + { + wxMessageBox(_("Model is not following embedded DTD definition, check it.\n")); + return false; + } + + if (ret != 0) + { + wxMessageBox(_("Failed to load document from disk")); + return false; + } + else + { + return true; + } + } + return false; +} + +wxString ddXmlStorage::getNodeName(xmlTextReaderPtr reader) +{ + xmlChar *name; + wxString out = wxEmptyString; + name = xmlTextReaderName(reader); + if (name == NULL) + name = xmlStrdup(BAD_CAST "--"); + out = WXSTRING_FROM_XML(name); + xmlFree(name); + return out; +} +int ddXmlStorage::getNodeType(xmlTextReaderPtr reader) +{ + return xmlTextReaderNodeType(reader); +} + +wxString ddXmlStorage::getNodeValue(xmlTextReaderPtr reader) +{ + wxString out = wxEmptyString; + xmlChar *value; + value = xmlTextReaderValue(reader); + if (value != NULL) + { + out = WXSTRING_FROM_XML(value); + xmlFree(value); + } + return out; +} + + +void ddXmlStorage::selectReader(xmlTextReaderPtr reader) +{ + if(getNodeType(reader) == 1) //libxml 1 for start element + { + if(getNodeName(reader).IsSameAs(_("VERSION"), false)) + { + checkVersion(reader); + } + if(getNodeName(reader).IsSameAs(_("MODEL"), false)) + { + // + } + + if(getNodeName(reader).IsSameAs(_("TABLE"), false)) + { + getTable(reader); + } + + if(getNodeName(reader).IsSameAs(_("RELATIONSHIP"), false)) + { + ddRelationshipFigure *r = getRelationship(reader); + design->addTableToModel(r); + } + + if(getNodeName(reader).IsSameAs(_("DIAGRAMS"), false)) + { + initDiagrams(reader); + } + } +} + +//Check if version of modeler with xml input is compatible +void ddXmlStorage::checkVersion(xmlTextReaderPtr reader) +{ + /* + + + + */ + int tmp; + wxString Number; + xmlChar *value; + // + tmp = xmlTextReaderHasAttributes(reader); + Number = _("VERIXLU"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(Number)); + } + + if(value) + { + Number = WXSTRING_FROM_XML(value); + xmlFree(value); + } + if(!Number.IsSameAs(_("1.0"))) + { + wxMessageBox(_("Invalid version of XML file for pgAdmin database designer found"), _("Invalid XML"), wxOK | wxICON_ERROR); + } +} + +//Table isn't create here because fk needs all tables created before assign it +ddTableFigure *ddXmlStorage::getTable(xmlTextReaderPtr reader) +{ + /* + + + + + + + + + + + + + + + + + + + + + + + + + */ + + int tmp; + wxString TableID, node, tmpInt; + xmlChar *value; + + // + tmp = xmlTextReaderHasAttributes(reader); + TableID = _("TableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(TableID)); + } + + if(value) + { + TableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + // --> ATTRIBUTE* + //Element(s) Attribute* + // NEED TO IMPLEMENT THIS + + + // -->POINTS + // + tmp = xmlTextReaderRead(reader); //go to POINTS + wxArrayInt x, y; + if(getNodeName(reader).IsSameAs(_("POINTS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + tmp = xmlTextReaderRead(reader); //go POINT + do + { + // --> POINT + // + tmp = xmlTextReaderRead(reader); //go X + tmp = xmlTextReaderRead(reader); //go X Value + value = xmlTextReaderValue(reader); //Value of X + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + x.Add(wxAtoi(tmpInt)); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /X + + tmp = xmlTextReaderRead(reader); //go Y + tmp = xmlTextReaderRead(reader); //go Y Value + value = xmlTextReaderValue(reader); //Value of Y + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + y.Add(wxAtoi(tmpInt)); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /Y + tmp = xmlTextReaderRead(reader); //go /POINT + tmp = xmlTextReaderRead(reader); //go POINT or /POINTS ? + } + while(getNodeName(reader).IsSameAs(_("POINT"), false)); + } + + if(!getNodeName(reader).IsSameAs(_("POINTS"), false)) + processResult(-1); + + // --> TITLE + // + // + // + wxString tableName = wxEmptyString; + wxString tableAlias = wxEmptyString; + + tmp = xmlTextReaderRead(reader); //go to TITLE + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + + if(value) + { + tableName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + tmp = xmlTextReaderRead(reader); //go to ALIAS or /TITLE + if(getNodeName(reader).IsSameAs(_("ALIAS"), false)) + { + tmp = xmlTextReaderRead(reader); //go to ALIAS Value + value = xmlTextReaderValue(reader); //Value of ALIAS + if(value) + { + tableAlias = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ALIAS + tmp = xmlTextReaderRead(reader); //go to /TITLE + } + + // --> UKNAMES? + // + // + tmp = xmlTextReaderRead(reader); //go to UKNAMES or PKNAMES? + wxArrayString ukNames; + if(getNodeName(reader).IsSameAs(_("UKNAMES"), false)) + { + tmp = xmlTextReaderRead(reader); //go UKNAME + do + { + tmp = xmlTextReaderRead(reader); //go UKNAME Value + value = xmlTextReaderValue(reader); //Value of UKNAME + if(value) + { + ukNames.Add(WXSTRING_FROM_XML(value)); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /UKNAME + tmp = xmlTextReaderRead(reader); //go to UKNAME or /UKNAMES ? + } + while(getNodeName(reader).IsSameAs(_("UKNAME"), false)); + tmp = xmlTextReaderRead(reader); //go to PKNAME + } + + // --> PKNAME + // + wxString pkName; + if(getNodeName(reader).IsSameAs(_("PKNAME"))) + { + tmp = xmlTextReaderRead(reader); //go to PKNAME Value or PKNAME node? + if(!getNodeName(reader).IsSameAs(_("PKNAME"))) + { + value = xmlTextReaderValue(reader); //Value of PKNAME + if(value) + { + pkName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /PKNAME + } + } + + int beginDrawCols, beginDrawIdxs, maxColIndex, minIdxIndex, maxIdxIndex, colsRowsSize, colsWindow, idxsRowsSize, idxsWindow; + // --> BEGINDRAWCOLS + // + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWCOLS + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWCOLS Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + beginDrawCols = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /BEGINDRAWCOLS + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWIDXS + + // --> BEGINDRAWIDXS + // + tmp = xmlTextReaderRead(reader); //go to BEGINDRAWIDXS Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + beginDrawIdxs = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /BEGINDRAWIDXS + tmp = xmlTextReaderRead(reader); //go to MAXCOLINDEX + + // --> MAXCOLINDEX + // + tmp = xmlTextReaderRead(reader); //go to MAXCOLINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + maxColIndex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MAXCOLINDEX + tmp = xmlTextReaderRead(reader); //go to MINIDXINDEX + + // --> MINIDXINDEX + // + tmp = xmlTextReaderRead(reader); //go to MINIDXINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + minIdxIndex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MINIDXINDEX + tmp = xmlTextReaderRead(reader); //go to MAXIDXINDEX + + // --> MAXIDXINDEX + // + tmp = xmlTextReaderRead(reader); //go to MAXIDXINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + maxIdxIndex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MAXIDXINDEX + tmp = xmlTextReaderRead(reader); //go to COLSROWSSIZE + + // --> COLSROWSSIZE + // + tmp = xmlTextReaderRead(reader); //go to COLSROWSSIZE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + colsRowsSize = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /COLSROWSSIZE + tmp = xmlTextReaderRead(reader); //go to COLSWINDOW + + // --> COLSWINDOW + // + tmp = xmlTextReaderRead(reader); //go to COLSWINDOW Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + colsWindow = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /COLSWINDOW + tmp = xmlTextReaderRead(reader); //go to IDXSROWSSIZE + + // --> IDXSROWSSIZE + // + tmp = xmlTextReaderRead(reader); //go to IDXSROWSSIZE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + idxsRowsSize = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /IDXSROWSSIZE + tmp = xmlTextReaderRead(reader); //go to IDXSWINDOW + + // --> IDXSWINDOW + //*/ + tmp = xmlTextReaderRead(reader); //go to IDXSWINDOW Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + idxsWindow = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /IDXSWINDOW + // --> COLUMNS + // + + tmp = xmlTextReaderRead(reader); //go to COLUMNS + + //Use empty table without columns created at preparsing to fill it with metadata + + ddTableFigure *t = design->getTable(tableName); + if(t != NULL) + t->InitTableValues(ukNames, pkName, beginDrawCols, beginDrawIdxs, maxColIndex, minIdxIndex, maxIdxIndex, colsRowsSize, colsWindow, idxsRowsSize, idxsWindow); + else + wxMessageBox(_("Table initial metadata info not found")); + + + //CHANGE 300,300 for right value when displaybox metadata will be added + + + //COLUMNS node have COLUMN children? + if(getNodeName(reader).IsSameAs(_("COLUMNS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + ddColumnFigure *c; + do + { + c = getColumn(reader, t); + if(c) + { + t->addColumnFromStorage(c); + c->setRightIconForColumn(); + } + } + while(c != NULL); + //now at + } + + tmp = xmlTextReaderRead(reader); //go to + t->syncInternalsPosAt(x, y); //synchronize positions + t->updateTableSize(); + return t; +} + +ddColumnFigure *ddXmlStorage::getColumn(xmlTextReaderPtr reader, ddTableFigure *colOwner) +{ + /* + + + + + + + + + + */ + + xmlChar *value; + int tmp; + tmp = xmlTextReaderRead(reader); //go to COLUMN + if(getNodeName(reader).IsSameAs(_("COLUMN")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + // --> ATTRIBUTE* + //Element(s) Attribute* + // NEED TO IMPLEMENT THIS + + // --> NAME + // + wxString columnName; + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + columnName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + tmp = xmlTextReaderRead(reader); //go to OPTION + + // --> OPTION + // + int option; + wxString tmpInt; + tmp = xmlTextReaderRead(reader); //go to OPTION Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + option = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /OPTION + tmp = xmlTextReaderRead(reader); //go to UKINDEX + + // --> UKINDEX + // + int ukindex; + tmp = xmlTextReaderRead(reader); //go to UKINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + ukindex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /UKINDEX + tmp = xmlTextReaderRead(reader); //go to ISPK + + // --> ISPK + // + bool isPk = false; + tmp = xmlTextReaderRead(reader); //go to ISPK Value + value = xmlTextReaderValue(reader); //Value of ISPK + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + isPk = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ISPK + + // --> COLUMNTYPE + // + wxString columnType; + tmp = xmlTextReaderRead(reader); //go to COLUMNTYPE + tmp = xmlTextReaderRead(reader); //go to COLUMNTYPE Value + value = xmlTextReaderValue(reader); //Value of COLUMNTYPE + if(value) + { + columnType = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /COLUMNTYPE + + // --> PRECISION? + // + tmp = xmlTextReaderRead(reader); //go to PRECISION? or SCALE? or ALIAS? or GENERATEFKNAME + int precision = -1; + if(getNodeName(reader).IsSameAs(_("PRECISION"))) + { + tmp = xmlTextReaderRead(reader); //go to PRECISION Value + value = xmlTextReaderValue(reader); //Value of PRECISION + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + precision = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /PRECISION + tmp = xmlTextReaderRead(reader); //go to SCALE? or ALIAS? or GENERATEFKNAME + } + + // --> SCALE? + // + + int scale = -1; + if(getNodeName(reader).IsSameAs(_("SCALE"))) + { + tmp = xmlTextReaderRead(reader); //go to SCALE Value + value = xmlTextReaderValue(reader); //Value of SCALE + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + scale = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /SCALE + tmp = xmlTextReaderRead(reader); //go to ALIAS? or GENERATEFKNAME + } + + // --> GENERATEFKNAME + // + bool generateFkName = false; + tmp = xmlTextReaderRead(reader); //go to GENERATEFKNAME Value + value = xmlTextReaderValue(reader); //Value of GENERATEFKNAME + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + generateFkName = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /GENERATEFKNAME + tmp = xmlTextReaderRead(reader); //go to /COLUMN + + return new ddColumnFigure(columnName, colOwner, (ddColumnOptionType)option, generateFkName, isPk, columnType, precision, scale, ukindex, NULL, NULL); + } + return NULL; //found /COLUMNS node +} + +ddRelationshipFigure *ddXmlStorage::getRelationship(xmlTextReaderPtr reader) +{ + /* + + + + + + + + + + + + + + + + + + + + + + + + */ + + xmlChar *value; + wxString tmpInt; + int tmp; + + // + tmp = xmlTextReaderHasAttributes(reader); + wxString SourceTableID = _("SourceTableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(SourceTableID)); + } + + if(value) + { + SourceTableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + // + tmp = xmlTextReaderHasAttributes(reader); + wxString DestTableID = _("DestTableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(DestTableID)); + } + + if(value) + { + DestTableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + ddTableFigure *source = design->getTable(design->getTableName(SourceTableID)); + ddTableFigure *destination = design->getTable(design->getTableName(DestTableID)); + + ddRelationshipFigure *relation = new ddRelationshipFigure(); + relation->setStartTerminal(new ddRelationshipTerminal(relation, false)); + relation->setEndTerminal(new ddRelationshipTerminal(relation, true)); + relation->clearPoints(0); + bool firstPoint = true; + // --> ATTRIBUTE* + //Element(s) Attribute* + // NEED TO IMPLEMENT THIS + + // --> POINTSRELATION + // + int x, y, posIdx = 0; + + tmp = xmlTextReaderRead(reader); //go to POINTSRELATION + if(getNodeName(reader).IsSameAs(_("POINTSRELATION"), false)) + { + //only first time inside POINTSRELATION this is needed + tmp = xmlTextReaderRead(reader); //go POINTS + do + { + + if(!firstPoint) //because at first time position for diagram exists at relationship yet + { + relation->AddPosForNewDiagram(); + } + else + { + firstPoint = false; + } + + if(getNodeName(reader).IsSameAs(_("POINTS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + //only first time inside POINTS this is needed + tmp = xmlTextReaderRead(reader); //go POINT + do + { + tmp = xmlTextReaderRead(reader); //go X + tmp = xmlTextReaderRead(reader); //go X Value + value = xmlTextReaderValue(reader); //Value of X + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + x = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /X + + tmp = xmlTextReaderRead(reader); //go Y + tmp = xmlTextReaderRead(reader); //go Y Value + value = xmlTextReaderValue(reader); //Value of Y + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + y = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /Y + tmp = xmlTextReaderRead(reader); //go /POINT + relation->addPoint(posIdx, x, y); + + tmp = xmlTextReaderRead(reader); //go POINT or /POINTS? + } + while(getNodeName(reader).IsSameAs(_("POINT"), false) && getNodeType(reader) == 1); + } + else + { + if(! (getNodeName(reader).IsSameAs(_("POINTS")) && xmlTextReaderIsEmptyElement(reader)) ) + { + processResult(-1); + } + } + posIdx++; //change of points array then change view position index + tmp = xmlTextReaderRead(reader); //go POINTS or /POINTSRELATION? + } + while(getNodeName(reader).IsSameAs(_("POINTS"), false) && getNodeType(reader) == 1); + } + + if(!getNodeName(reader).IsSameAs(_("POINTSRELATION"), false)) + { + processResult(-1); + } + + // --> UKINDEX + // + int ukindex; + tmp = xmlTextReaderRead(reader); //go to UKINDEX + tmp = xmlTextReaderRead(reader); //go to UKINDEX Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + ukindex = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /UKINDEX + + // --> NAME + // + tmp = xmlTextReaderRead(reader); //go to NAME or ONUPDATE + wxString RelationshipName = wxEmptyString; + if(getNodeName(reader).IsSameAs(_("NAME"), false)) + { + + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + RelationshipName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + tmp = xmlTextReaderRead(reader); //go to ONUPDATE + } + + // --> ONUPDATE + // + int onUpdate; + + tmp = xmlTextReaderRead(reader); //go to ONUPDATE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + onUpdate = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ONUPDATE + tmp = xmlTextReaderRead(reader); //go to ONDELETE + + // --> ONDELETE + // + int onDelete; + tmp = xmlTextReaderRead(reader); //go to ONDELETE Value + value = xmlTextReaderValue(reader); //Value + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + onDelete = wxAtoi(tmpInt); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ONDELETE + tmp = xmlTextReaderRead(reader); //go to MATCHSIMPLE + + // --> MATCHSIMPLE + // + bool matchSimple = false; + tmp = xmlTextReaderRead(reader); //go to MATCHSIMPLE Value + value = xmlTextReaderValue(reader); //Value of MATCHSIMPLE + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + matchSimple = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MATCHSIMPLE + tmp = xmlTextReaderRead(reader); //go to IDENTIFYING + + // --> IDENTIFYING + // + bool identifying = false; + tmp = xmlTextReaderRead(reader); //go to IDENTIFYING Value + value = xmlTextReaderValue(reader); //Value of IDENTIFYING + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + identifying = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /IDENTIFYING + tmp = xmlTextReaderRead(reader); //go to ONETOMANY + + // --> ONETOMANY + // + bool oneToMany = false; + tmp = xmlTextReaderRead(reader); //go to ONETOMANY Value + value = xmlTextReaderValue(reader); //Value of ONETOMANY + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + oneToMany = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /ONETOMANY + tmp = xmlTextReaderRead(reader); //go to MANDATORY + + // --> MANDATORY + // + bool mandatory = false; + tmp = xmlTextReaderRead(reader); //go to MANDATORY Value + value = xmlTextReaderValue(reader); //Value of MANDATORY + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + mandatory = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /MANDATORY + tmp = xmlTextReaderRead(reader); //go to FKFROMPK + + // --> FKFROMPK + // + bool fkFromPk = false; + tmp = xmlTextReaderRead(reader); //go to FKFROMPK Value + value = xmlTextReaderValue(reader); //Value of FKFROMPK + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + fkFromPk = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /FKFROMPK + + + //refresh relationship after all values were setted + relation->initRelationValues(source, destination, ukindex, RelationshipName, (actionKind) onUpdate, (actionKind) onDelete, matchSimple, identifying, oneToMany, mandatory, fkFromPk); + + + // --> RELATIONITEMS + // + tmp = xmlTextReaderRead(reader); //go to RELATIONITEMS + if(getNodeName(reader).IsSameAs(_("RELATIONITEMS")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + tmp = xmlTextReaderRead(reader); //go RELATIONITEM + do + { + //Now only add item to relationship + ddRelationshipItem *item = getRelationshipItem(reader, relation, source, destination); + relation->getItemsHashMap()[item->original->getColumnName()] = item; + + tmp = xmlTextReaderRead(reader); //go to RELATIONITEM or /RELATIONITEMS + } + while(getNodeName(reader).IsSameAs(_("RELATIONITEM"), false)); + } + + tmp = xmlTextReaderRead(reader); //go to /RELATIONSHIP + + relation->updateConnection(0); + return relation; +} + +ddRelationshipItem *ddXmlStorage::getRelationshipItem(xmlTextReaderPtr reader, ddRelationshipFigure *itemOwner, ddTableFigure *source, ddTableFigure *destination) +{ + /* + + + + + + + */ + xmlChar *value; + wxString tmpInt; + int tmp; + + // --> AUTOGENFK + // + bool autoGenFk = false; + tmp = xmlTextReaderRead(reader); //go to AUTOGENFK + tmp = xmlTextReaderRead(reader); //go to AUTOGENFK Value + value = xmlTextReaderValue(reader); //Value of AUTOGENFK + if(value) + { + tmpInt = WXSTRING_FROM_XML(value); + autoGenFk = tmpInt.IsSameAs(_("T")); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /AUTOGENFK + + // + wxString fkColName; + tmp = xmlTextReaderRead(reader); //go to FKCOLNAME + tmp = xmlTextReaderRead(reader); //go to FKCOLNAME Value + value = xmlTextReaderValue(reader); //Value of FKCOLNAME + if(value) + { + fkColName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /FKCOLNAME + + // + wxString sourceColName; + tmp = xmlTextReaderRead(reader); //go to SOURCECOLNAME + tmp = xmlTextReaderRead(reader); //go to SOURCECOLNAME Value + value = xmlTextReaderValue(reader); //Value of SOURCECOLNAME + if(value) + { + sourceColName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /SOURCECOLNAME + + // + wxString initialColName; + tmp = xmlTextReaderRead(reader); //go to INITIALCOLNAME + tmp = xmlTextReaderRead(reader); //go to INITIALCOLNAME Value + value = xmlTextReaderValue(reader); //Value of INITIALCOLNAME + if(value) + { + initialColName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /INITIALCOLNAME + + // + tmp = xmlTextReaderRead(reader); //go to INITIALALIASNAME + wxString initialAliasName = wxEmptyString; + if(getNodeName(reader).IsSameAs(_("INITIALALIASNAME"), false)) + { + tmp = xmlTextReaderRead(reader); //go to INITIALALIASNAME Value + value = xmlTextReaderValue(reader); //Value of INITIALALIASNAME + if(value) + { + initialAliasName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /INITIALALIASNAME + tmp = xmlTextReaderRead(reader); //go to /RELATIONITEM + } + + ddRelationshipItem *item = new ddRelationshipItem(); + ddColumnFigure *sourceCol = source->getColByName(sourceColName); + ddColumnFigure *destinationCol = destination->getColByName(fkColName); + item->initRelationshipItemValues(itemOwner, destination, autoGenFk, destinationCol, sourceCol, initialColName); + + return item; + +} + +void ddXmlStorage::initDiagrams(xmlTextReaderPtr reader) +{ + /* + + + + + + + + */ + + //At DIAGRAMS Element + xmlChar *value = NULL; + wxString diagramName; + hdDrawing *newDiagram; + int tmp; + + // + tmp = xmlTextReaderRead(reader); //go to DIAGRAM + if(getNodeName(reader).IsSameAs(_("DIAGRAM")) && getNodeType(reader) == 1 && !xmlTextReaderIsEmptyElement(reader) ) + { + do + { + // + tmp = xmlTextReaderRead(reader); //go to NAME + tmp = xmlTextReaderRead(reader); //go to NAME Value + value = xmlTextReaderValue(reader); //Value of NAME + if(value) + { + diagramName = WXSTRING_FROM_XML(value); + xmlFree(value); + } + tmp = xmlTextReaderRead(reader); //go to /NAME + + if(tabs && design) + { + newDiagram = design->createDiagram(tabs, diagramName, true); + tabs->AddPage(newDiagram->getView(), diagramName); + } + else + { + processResult(-1); + } + // + // + tmp = xmlTextReaderRead(reader); //go to TABLEREF + bool firstTime = true; + if(getNodeName(reader).IsSameAs(_("TABLEREF")) && xmlTextReaderIsEmptyElement(reader)) + { + wxString TableID, tableName; + if(firstTime) + { + firstTime = false; + } + else + { + tmp = xmlTextReaderRead(reader); //go to TABLEREF + } + do + { + // + tmp = xmlTextReaderHasAttributes(reader); + TableID = _("TableID"); + if(tmp) + { + value = xmlTextReaderGetAttribute(reader, XML_FROM_WXSTRING(TableID)); + } + + if(value) + { + TableID = WXSTRING_FROM_XML(value); + xmlFree(value); + } + + tableName = design->getTableName(TableID); + //Add table to diagram + newDiagram->add(design->getTable(tableName)); + tmp = xmlTextReaderRead(reader); //go to TABLEREF or /DIAGRAM? + } + while(getNodeName(reader).IsSameAs(_("TABLEREF"), false)); + } + //After adding a new diagram check for all needed relationships at diagram and add it. + if(design) + { + design->getEditor()->checkRelationshipsConsistency(newDiagram->getView()->getIdx()); + newDiagram->getView()->Refresh(); + } + else + { + processResult(-1); + } + tmp = xmlTextReaderRead(reader); //go to DIAGRAM or /DIAGRAMS? + } + while(getNodeName(reader).IsSameAs(_("DIAGRAM"), false)); + } + + + +} + +//Temporary DTD will change later +wxString ddXmlStorage::getModelDTD() +{ + wxString dtd = wxEmptyString; + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(" "); + dtd += _(" "); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + dtd += _(""); + + return dtd; +} diff --git a/dd/dditems/figures/xml/module.mk b/dd/dditems/figures/xml/module.mk new file mode 100644 index 0000000..d68fdc9 --- /dev/null +++ b/dd/dditems/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/figures/xml/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/figures/xml/ddXmlStorage.cpp + +EXTRA_DIST += \ + dd/dditems/figures/xml/module.mk diff --git a/dd/dditems/handles/ddAddColButtonHandle.cpp b/dd/dditems/handles/ddAddColButtonHandle.cpp new file mode 100644 index 0000000..ece6568 --- /dev/null +++ b/dd/dditems/handles/ddAddColButtonHandle.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColButtonHandle.cpp - A handle for a table figure that allow to graphically add columns +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddAddColButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/main/hdDrawingView.h" + +//Images +#include "images/ddAddColumnCursor.pngc" + +ddAddColButtonHandle::ddAddColButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ +} + +ddAddColButtonHandle::~ddAddColButtonHandle() +{ +} + +void ddAddColButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + ddTableFigure *table = (ddTableFigure *) getOwner(); + wxTextEntryDialog nameDialog(view, wxT("New column name"), wxT("Add a column")); + bool again; + do + { + again = false; + int answer = nameDialog.ShowModal(); + if (answer == wxID_OK) + { + wxString name = nameDialog.GetValue(); + if(table->getColByName(name) == NULL) + { + table->addColumn(view->getIdx(), new ddColumnFigure(name, table)); + view->notifyChanged(); + } + else + { + wxString msg(wxT("Error trying to add new column '")); + msg.Append(name); + msg.Append(wxT("' column name already in use")); + wxMessageDialog info( view, msg , + wxT("Column name already in use"), + wxNO_DEFAULT | wxOK | wxICON_EXCLAMATION); + again = true; + info.ShowModal(); + } + } + + } + while(again); + view->Refresh(); +} + +void ddAddColButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddAddColButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} diff --git a/dd/dditems/handles/ddAddFkButtonHandle.cpp b/dd/dditems/handles/ddAddFkButtonHandle.cpp new file mode 100644 index 0000000..ffb0d57 --- /dev/null +++ b/dd/dditems/handles/ddAddFkButtonHandle.cpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkButtonHandle.cpp - A handle for a table figure that allow to graphically add relationships (fk) +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddAddFkButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/tools/hdConnectionCreationTool.h" +#include "hotdraw/utilities/hdMouseEvent.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipTerminal.h" + +//Images +#include "images/ddRelationshipCursor.pngc" + +ddAddFkButtonHandle::ddAddFkButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ +} + +ddAddFkButtonHandle::~ddAddFkButtonHandle() +{ +} + +void ddAddFkButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + if(getOwner()->ms_classInfo.IsKindOf(&ddTableFigure::ms_classInfo)) + { + ddRelationshipFigure *fkConnection = new ddRelationshipFigure(); + //Check figure available positions for diagrams, add at least needed to allow initialization of the class + int i, start; + start = fkConnection->displayBox().CountPositions(); + for(i = start; i < (view->getIdx() + 1); i++) + { + fkConnection->AddPosForNewDiagram(); + } + fkConnection->setStartTerminal(new ddRelationshipTerminal(fkConnection, false)); + fkConnection->setEndTerminal(new ddRelationshipTerminal(fkConnection, true)); + hdConnectionCreationTool *conn = new hdConnectionCreationTool(view, fkConnection); + view->setTool(conn); + // Simulate button down to start connection of foreign key + wxMouseEvent e(wxEVT_LEFT_DOWN); + e.m_x = event.GetPosition().x; + e.m_y = event.GetPosition().y; + e.SetEventObject(view); + hdMouseEvent evento(e, view); + conn->mouseDown(evento); + ddTableFigure *table = (ddTableFigure *) getOwner(); + table->setSelectFkDestMode(true); + view->notifyChanged(); + } +} + +void ddAddFkButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddAddFkButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} diff --git a/dd/dditems/handles/ddMinMaxTableButtonHandle.cpp b/dd/dditems/handles/ddMinMaxTableButtonHandle.cpp new file mode 100644 index 0000000..153e686 --- /dev/null +++ b/dd/dditems/handles/ddMinMaxTableButtonHandle.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableButtonHandle.cpp - A handle for a table figure that allow to graphically minimize or maximize table window size +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddMinMaxTableButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/main/hdDrawingView.h" + +//Images +#include "images/ddMinMaxCursor.pngc" + +ddMinMaxTableButtonHandle::ddMinMaxTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxBitmap &buttonSecondImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ + buttonMaximizeImage = buttonSecondImage; + tmpImage = buttonImage; + showFirst = true; +} + +ddMinMaxTableButtonHandle::~ddMinMaxTableButtonHandle() +{ +} + +void ddMinMaxTableButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddMinMaxTableButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddMinMaxTableButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + ddTableFigure *table = (ddTableFigure *) getOwner(); + + if(showFirst) + { + buttonIcon = buttonMaximizeImage; + table->setColumnsWindow(view->getIdx(), 1); + } + else + { + buttonIcon = tmpImage; + table->setColumnsWindow(table->getTotalColumns(), true); + } + showFirst = !showFirst; + view->notifyChanged(); +} diff --git a/dd/dditems/handles/ddRemoveTableButtonHandle.cpp b/dd/dditems/handles/ddRemoveTableButtonHandle.cpp new file mode 100644 index 0000000..0c8852c --- /dev/null +++ b/dd/dditems/handles/ddRemoveTableButtonHandle.cpp @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveTableButtonHandle.cpp - A handle for a table figure that allow to delete it +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddRemoveTableButtonHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +//Images +#include "images/ddDeleteTableCursor.pngc" + +ddRemoveTableButtonHandle::ddRemoveTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdButtonHandle(owner, buttonLocator, buttonImage, size) +{ +} + +ddRemoveTableButtonHandle::~ddRemoveTableButtonHandle() +{ +} + +void ddRemoveTableButtonHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddRemoveTableButtonHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void ddRemoveTableButtonHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + if(view && getOwner()) + { + ddTableFigure *table = (ddTableFigure *) getOwner(); + hdRemoveDeleteDialog dialog(_("Are you sure you wish to delete table ") + table->getTableName() + wxT("?"), _("Delete table?"), view); + int answer = dialog.ShowModal(); + if (answer == DD_DELETE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + //Unselect table at all diagrams + editor->removeFromAllSelections(table); + //Drop foreign keys with this table as origin or destination + table->processDeleteAlert(view->getDrawing()); + //Drop table + editor->deleteModelFigure(table); + editor->getDesign()->refreshBrowser(); + editor->checkRelationshipsConsistency(view->getIdx()); + view->notifyChanged(); + } + else if(answer == DD_REMOVE) + { + ddDrawingEditor *editor = (ddDrawingEditor *) view->editor(); + editor->getExistingDiagram(view->getIdx())->removeFromSelection(table); + editor->getExistingDiagram(view->getIdx())->remove(table); + editor->checkRelationshipsConsistency(view->getIdx()); + view->notifyChanged(); + } + + } +} diff --git a/dd/dditems/handles/ddScrollBarHandle.cpp b/dd/dditems/handles/ddScrollBarHandle.cpp new file mode 100644 index 0000000..9542e88 --- /dev/null +++ b/dd/dditems/handles/ddScrollBarHandle.cpp @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarHandle.cpp - A handle for a table figure that allow to scroll it when table is not in full size +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddScrollBarHandle.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdGeometry.h" + +//Images +#include "images/ddUp.pngc" +#include "images/ddDown.pngc" + +ddScrollBarHandle::ddScrollBarHandle(ddTableFigure *owner, hdILocator *scrollBarLocator , wxSize &size): + hdLocatorHandle(owner, scrollBarLocator) +{ + table = owner; + scrollLocator = scrollBarLocator; + displayBox.SetSize(size); + upBitmap = wxBitmap(*ddUp_png_img); + downBitmap = wxBitmap(*ddDown_png_img); +} + +ddScrollBarHandle::~ddScrollBarHandle() +{ +} + + +wxCursor ddScrollBarHandle::createCursor() +{ + return wxCursor(wxCURSOR_HAND); +} + +//avoid to use inflate on this handle +hdRect &ddScrollBarHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + displayBox.width = 11; //as defined at locator + displayBox.height = table->getColsSpace().height; + displayBox.SetPosition(p); + return displayBox; +} + +void ddScrollBarHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + int idx = view->getIdx(); + context.SetBrush(*wxWHITE_BRUSH); + wxPoint copy = getDisplayBox(idx).GetPosition(); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawRectangle(copy.x, copy.y, getDisplayBox(idx).width, getDisplayBox(idx).height); + context.DrawBitmap(upBitmap, copy.x + 1, copy.y + 2, true); + context.DrawBitmap(downBitmap, copy.x + 1, copy.y + getDisplayBox(idx).height - 2 - downBitmap.GetHeight(), true); + + barSize.SetHeight((getDisplayBox(idx).height - 12) * 0.45); + barSize.SetWidth(getDisplayBox(idx).width - 4); + + int divBy = (table->getTotalColumns() - table->getColumnsWindow()); + if(divBy <= 0) + divBy = table->getColumnsWindow(); + int colOffset = barSize.GetHeight() / divBy; + int verticalPosBar = 3 + copy.y + downBitmap.GetHeight() + colOffset * table->getTopColWindowIndex(); + if(table->getColumnsWindow() > 1) + context.DrawRectangle(wxPoint(copy.x + 2, verticalPosBar), barSize); + +} + +void ddScrollBarHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + int idx = view->getIdx(); + int y = event.GetPosition().y; + anchorY = y; + if( (y > (getDisplayBox(idx).GetPosition().y + 2)) && (y < (getDisplayBox(idx).GetPosition().y + 2 + 6)) ) //6 image height + table->columnsWindowUp(idx); + + if( (y > (getDisplayBox(idx).GetPosition().y + getDisplayBox(idx).height - 2 - downBitmap.GetHeight()) ) && (y < (getDisplayBox(idx).GetPosition().y + getDisplayBox(idx).height - 2) ) ) + table->columnsWindowDown(idx); + view->notifyChanged(); +} + +void ddScrollBarHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int y = event.GetPosition().y; + int divBy = (table->getTotalColumns() - table->getColumnsWindow()); + if(divBy <= 0) + divBy = table->getColumnsWindow(); + int colOffset = barSize.GetHeight() / divBy; + + hdGeometry g; + if ( g.ddabs(anchorY - y) > colOffset) + { + if((anchorY - y) > 0) + { + table->columnsWindowUp(view->getIdx()); + } + else + { + table->columnsWindowDown(view->getIdx()); + } + anchorY = y; + } + view->notifyChanged(); +} + +void ddScrollBarHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} + +hdPoint &ddScrollBarHandle::locate(int posIdx) +{ + if(scrollLocator) + { + pointLocate = scrollLocator->locate(posIdx, getOwner()); + return pointLocate; + } + else + pointLocate = hdPoint(0, 0); + return pointLocate; +} diff --git a/dd/dditems/handles/ddSouthTableSizeHandle.cpp b/dd/dditems/handles/ddSouthTableSizeHandle.cpp new file mode 100644 index 0000000..77c182c --- /dev/null +++ b/dd/dditems/handles/ddSouthTableSizeHandle.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddSouthTableSizeHandle.cpp - Allow to change table size by using drag and drop from south side of table rectangle +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/handles/ddSouthTableSizeHandle.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/main/hdDrawingView.h" + +ddSouthTableSizeHandle::ddSouthTableSizeHandle(ddTableFigure *owner, hdILocator *locator): + hdLocatorHandle(owner, locator) +{ +} + +hdRect &ddSouthTableSizeHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + ddTableFigure *table = (ddTableFigure *) getOwner(); + displayBox.width = table->getFullSpace().width * 0.5; //as defined at locator + displayBox.height = 3; + displayBox.SetPosition(p); + return displayBox; +} + + +wxCursor ddSouthTableSizeHandle::createCursor() +{ + return wxCursor(wxCURSOR_SIZENS); +} + +void ddSouthTableSizeHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ +} + +ddSouthTableSizeHandle::~ddSouthTableSizeHandle() +{ +} + +void ddSouthTableSizeHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + anchorY = event.GetPosition().y; +} + +void ddSouthTableSizeHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int y = event.GetPosition().y; + ddTableFigure *table = (ddTableFigure *) getOwner(); + wxFont font = *hdFontAttribute::defaultFont; + int colOffset = table->getColDefaultHeight(font); + + int divBy = (table->getTotalColumns() - table->getColumnsWindow()); + if(divBy <= 0) + divBy = table->getColumnsWindow(); + + hdGeometry g; + if ( g.ddabs(anchorY - y) > colOffset) + { + if((anchorY - y) > 0) + { + table->setColumnsWindow(view->getIdx(), table->getColumnsWindow() - 1); + } + else + { + table->setColumnsWindow(view->getIdx(), table->getColumnsWindow() + 1); + } + anchorY = y; + } + + //hack to update relationship position when table size change + table->manuallyNotifyChange(view->getIdx()); + view->notifyChanged(); +} + +void ddSouthTableSizeHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + //hack to update relationship position when table size change + ddTableFigure *table = (ddTableFigure *) getOwner(); + table->manuallyNotifyChange(view->getIdx()); + view->notifyChanged(); +} diff --git a/dd/dditems/handles/module.mk b/dd/dditems/handles/module.mk new file mode 100644 index 0000000..19fab2d --- /dev/null +++ b/dd/dditems/handles/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/handles/ddAddColButtonHandle.cpp \ + dd/dditems/handles/ddAddFkButtonHandle.cpp \ + dd/dditems/handles/ddMinMaxTableButtonHandle.cpp \ + dd/dditems/handles/ddRemoveTableButtonHandle.cpp \ + dd/dditems/handles/ddScrollBarHandle.cpp \ + dd/dditems/handles/ddSouthTableSizeHandle.cpp + +EXTRA_DIST += \ + dd/dditems/handles/module.mk diff --git a/dd/dditems/locators/ddAddColLocator.cpp b/dd/dditems/locators/ddAddColLocator.cpp new file mode 100644 index 0000000..e847e94 --- /dev/null +++ b/dd/dditems/locators/ddAddColLocator.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColLocator.cpp - Locate table add column button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddAddColLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddAddColLocator::ddAddColLocator() +{ +} + +ddAddColLocator::~ddAddColLocator() +{ +} + +hdPoint &ddAddColLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + locatePoint.x = table->getTitleRect().GetBottomRight(posIdx).x - 20; + locatePoint.y = table->getTitleRect().GetBottomRight(posIdx).y - 9; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddAddFkLocator.cpp b/dd/dditems/locators/ddAddFkLocator.cpp new file mode 100644 index 0000000..f320f0f --- /dev/null +++ b/dd/dditems/locators/ddAddFkLocator.cpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkLocator.cpp - Locate table add fk relationship button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddAddFkLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddAddFkLocator::ddAddFkLocator() +{ +} + +ddAddFkLocator::~ddAddFkLocator() +{ +} + +hdPoint &ddAddFkLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + locatePoint.x = table->getTitleRect().GetBottomRight(posIdx).x - 10; + locatePoint.y = table->getTitleRect().GetBottomRight(posIdx).y - 9; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddMinMaxTableLocator.cpp b/dd/dditems/locators/ddMinMaxTableLocator.cpp new file mode 100644 index 0000000..98209c4 --- /dev/null +++ b/dd/dditems/locators/ddMinMaxTableLocator.cpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableLocator.cpp - Locate table minimize/maximize button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddMinMaxTableLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddMinMaxTableLocator::ddMinMaxTableLocator() +{ +} + +ddMinMaxTableLocator::~ddMinMaxTableLocator() +{ +} + +hdPoint &ddMinMaxTableLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + int x = table->displayBox().x[posIdx] + table->displayBox().width - 20; //(8+2) + int y = table->displayBox().y[posIdx] + 6; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddRemoveTableLocator.cpp b/dd/dditems/locators/ddRemoveTableLocator.cpp new file mode 100644 index 0000000..07dc79b --- /dev/null +++ b/dd/dditems/locators/ddRemoveTableLocator.cpp @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveColLocator.cpp - Locate table delete button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddRemoveTableLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddRemoveTableLocator::ddRemoveTableLocator() +{ +} + +ddRemoveTableLocator::~ddRemoveTableLocator() +{ +} + +hdPoint &ddRemoveTableLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + int x = table->displayBox().x[posIdx] + table->displayBox().width - 10; //(8+2) + int y = table->displayBox().y[posIdx] + 6; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddScrollBarTableLocator.cpp b/dd/dditems/locators/ddScrollBarTableLocator.cpp new file mode 100644 index 0000000..3a78340 --- /dev/null +++ b/dd/dditems/locators/ddScrollBarTableLocator.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarTableLocator.cpp - Locate table scrollbar inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddScrollBarTableLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddScrollBarTableLocator::ddScrollBarTableLocator() +{ +} + +ddScrollBarTableLocator::~ddScrollBarTableLocator() +{ +} + +hdPoint &ddScrollBarTableLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + ; + int x = table->getColsSpace().GetTopRight(posIdx).x - 11; //scrollwidth + int y = table->getColsSpace().y[posIdx]; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/ddTableBottomLocator.cpp b/dd/dditems/locators/ddTableBottomLocator.cpp new file mode 100644 index 0000000..37ba2ab --- /dev/null +++ b/dd/dditems/locators/ddTableBottomLocator.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableBottomLocator.cpp - Locate bottom (south) of table for use of south table size handle. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/locators/ddTableBottomLocator.h" +#include "dd/dditems/figures/ddTableFigure.h" + +ddTableBottomLocator::ddTableBottomLocator() +{ +} + +ddTableBottomLocator::~ddTableBottomLocator() +{ +} + +hdPoint &ddTableBottomLocator::locate(int posIdx, hdIFigure *owner) +{ + if(owner) + { + ddTableFigure *table = (ddTableFigure *) owner; + + int x = table->getFullSpace().GetLeftBottom(posIdx).x + table->getFullSpace().width * 0.25; + int y = table->getFullSpace().GetLeftBottom(posIdx).y - 2; + + locatePoint.x = x; + locatePoint.y = y; + return locatePoint; + } + locatePoint.x = 0; + locatePoint.y = 0; + return locatePoint; +} diff --git a/dd/dditems/locators/module.mk b/dd/dditems/locators/module.mk new file mode 100644 index 0000000..ab06b22 --- /dev/null +++ b/dd/dditems/locators/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/locators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/locators/ddAddColLocator.cpp \ + dd/dditems/locators/ddAddFkLocator.cpp \ + dd/dditems/locators/ddMinMaxTableLocator.cpp \ + dd/dditems/locators/ddRemoveTableLocator.cpp \ + dd/dditems/locators/ddScrollBarTableLocator.cpp \ + dd/dditems/locators/ddTableBottomLocator.cpp + +EXTRA_DIST += \ + dd/dditems/locators/module.mk diff --git a/dd/dditems/module.mk b/dd/dditems/module.mk new file mode 100644 index 0000000..acb36fa --- /dev/null +++ b/dd/dditems/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/ Makefile fragment +# +####################################################################### + +include dd/dditems/figures/module.mk +include dd/dditems/handles/module.mk +include dd/dditems/locators/module.mk +include dd/dditems/tools/module.mk +include dd/dditems/utilities/module.mk + +EXTRA_DIST += \ + dd/dditems/module.mk diff --git a/dd/dditems/tools/ddColumnFigureTool.cpp b/dd/dditems/tools/ddColumnFigureTool.cpp new file mode 100644 index 0000000..037d787 --- /dev/null +++ b/dd/dditems/tools/ddColumnFigureTool.cpp @@ -0,0 +1,130 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigureTool.cpp - Improvement to hdFigureTool to work with composite table figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/dditems/tools/ddColumnFigureTool.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "hotdraw/tools/hdDragTrackerTool.h" + + +ddColumnFigureTool::ddColumnFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ + delegateTool = NULL; +} + +ddColumnFigureTool::~ddColumnFigureTool() +{ + //This tool destructor is at compositeTool, because this is only a selection tool and neither tool belongs to it. + hdITool *tmpDefault = hdFigureTool::getDefaultTool(); + hdFigureTool *tmpDelegateDefault; + + if(delegateTool->ms_classInfo.IsKindOf(&hdFigureTool::ms_classInfo)) + tmpDelegateDefault = (hdFigureTool *)delegateTool; + else + tmpDelegateDefault = NULL; + + if(delegateTool && delegateTool != tmpDefault) + { + //Hack to avoid delete defaultTool (Delegate->defaultTool) of delegate tool + // if this is the same as defaultTool (this->defaultTool) of this Object. + if(tmpDelegateDefault && tmpDelegateDefault->getDefaultTool() == tmpDefault) + tmpDelegateDefault->setDefaultTool(NULL); + + //Hack to avoid delete hdDragTrackerTool Default twice because this figure is only used inside + //a table, and then create a compositeTool and default in both tools is hdDragTrackerTool + //but I can't hard code this is Composite because that class should remain generic + if(tmpDelegateDefault->getDefaultTool()->ms_classInfo.IsKindOf(&hdDragTrackerTool::ms_classInfo)) + tmpDelegateDefault->setDefaultTool(NULL); + delete delegateTool; + } + +} + +void ddColumnFigureTool::setDefaultTool(hdITool *dt) +{ + hdFigureTool::setDefaultTool(dt); +} + +hdITool *ddColumnFigureTool::getDefaultTool() +{ + if(delegateTool) + { + return delegateTool; + } + else + { + return hdFigureTool::getDefaultTool(); + } +} + +void ddColumnFigureTool::mouseDown(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + ddColumnFigure *cfigure = (ddColumnFigure *) getFigure(); + hdIFigure *figure = cfigure->findFigure(event.getView()->getIdx(), x, y); + + if(figure) + { + setDelegateTool(event.getView(), figure->CreateFigureTool(event.getView(), getDefaultTool())); + } + else + { + setDelegateTool(event.getView(), getDefaultTool()); + } + + if(delegateTool) + { + delegateTool->mouseDown(event); + } +} + +void ddColumnFigureTool::activate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->activate(view); + } +} + +void ddColumnFigureTool::deactivate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + } +} + +void ddColumnFigureTool::setDelegateTool(hdDrawingView *view, hdITool *tool) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + delete delegateTool; + delegateTool = NULL; + } + + delegateTool = tool; + if(delegateTool) + { + delegateTool->activate(view); + } +} + +hdITool *ddColumnFigureTool::getDelegateTool() +{ + return delegateTool; +} diff --git a/dd/dditems/tools/ddColumnTextTool.cpp b/dd/dditems/tools/ddColumnTextTool.cpp new file mode 100644 index 0000000..4aef3ff --- /dev/null +++ b/dd/dditems/tools/ddColumnTextTool.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnTextTool.cpp - Modification of simple text tool for editing composite figure columns +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/tools/ddColumnTextTool.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" + +class hdDrawingEditor; + + +ddColumnTextTool::ddColumnTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit , wxString dialogCaption, wxString dialogMessage): + hdSimpleTextTool(view, fig, dt, fastEdit, dialogCaption, dialogMessage) +{ + if(colTextFigure->ms_classInfo.IsKindOf(&ddTextTableItemFigure::ms_classInfo)) + colTextFigure = (ddTextTableItemFigure *) fig; + else + colTextFigure = NULL; +} + +ddColumnTextTool::~ddColumnTextTool() +{ +} + +void ddColumnTextTool::mouseDown(hdMouseEvent &event) +{ + hdSimpleTextTool::mouseDown(event); +} + +bool ddColumnTextTool::callDialog(hdDrawingView *view) +{ + if(colTextFigure->getOwnerColumn() == NULL) + { + wxString colName = colTextFigure->getText(); + wxString colShortName = colTextFigure->getAlias(); + ddTableNameDialog *nameAliasDialog = new ddTableNameDialog( + view, + colName, + colShortName, + colTextFigure + ); + + int answer = nameAliasDialog->ShowModal(); + bool change = false; + + if(answer == wxOK) + { + //check if names changed + change = ! (colShortName.IsSameAs(nameAliasDialog->GetValue1()) && colShortName.IsSameAs(nameAliasDialog->GetValue2())); + if(change) + { + colTextFigure->setText(nameAliasDialog->GetValue1()); + colTextFigure->setAlias(nameAliasDialog->GetValue2()); + view->notifyChanged(); + } + } + delete nameAliasDialog; + return change; + } + else + { + bool change = hdSimpleTextTool::callDialog(view); + if( change && colTextFigure->getOwnerColumn()->isGeneratedForeignKey()) //after a manual user column rename, deactivated automatic generation of fk name. + colTextFigure->getOwnerColumn()->deactivateGenFkName(); + return change; + } +} diff --git a/dd/dditems/tools/module.mk b/dd/dditems/tools/module.mk new file mode 100644 index 0000000..294b639 --- /dev/null +++ b/dd/dditems/tools/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/tools/ddColumnFigureTool.cpp \ + dd/dditems/tools/ddColumnTextTool.cpp + +EXTRA_DIST += \ + dd/dditems/tools/module.mk diff --git a/dd/dditems/utilities/ddPrecisionScaleDialog.cpp b/dd/dditems/utilities/ddPrecisionScaleDialog.cpp new file mode 100644 index 0000000..064c499 --- /dev/null +++ b/dd/dditems/utilities/ddPrecisionScaleDialog.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddPrecisionScaleDialog.cpp - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/dditems/utilities/ddPrecisionScaleDialog.h" +#include "dd/dditems/figures/ddTableFigure.h" + +#define txtPrecision CTRL_TEXT("txtPrecision") +#define txtScale CTRL_TEXT("txtScale") + + +BEGIN_EVENT_TABLE(ddPrecisionScaleDialog, pgDialog) +END_EVENT_TABLE() + +ddPrecisionScaleDialog::ddPrecisionScaleDialog( wxWindow *parent, + const wxString &defaultValue1, + const wxString &defaultValue2 + ) +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("ddPrecisionScaleDialog")); + RestorePosition(); + Init(); + SetValue1(defaultValue1); + SetValue2(defaultValue2); + + txtPrecision->SetFocus(); +} + +ddPrecisionScaleDialog::~ddPrecisionScaleDialog() +{ +} + +ddPrecisionScaleDialog::ddPrecisionScaleDialog() +{ + Init(); +} + +void ddPrecisionScaleDialog::Init( ) +{ + m_value1 = wxT("0"); + m_value2 = wxT("0"); +} + +//Transfer data to the window +bool ddPrecisionScaleDialog::TransferDataToWindow() +{ + txtPrecision->SetValue(m_value1); + txtScale->SetValue(m_value2); + + return true; +} + +//Transfer data from the window +bool ddPrecisionScaleDialog::TransferDataFromWindow() +{ + m_value1 = txtPrecision->GetValue(); + m_value2 = txtScale->GetValue(); + + return true; +} diff --git a/dd/dditems/utilities/ddSelectKindFksDialog.cpp b/dd/dditems/utilities/ddSelectKindFksDialog.cpp new file mode 100644 index 0000000..5e30c7d --- /dev/null +++ b/dd/dditems/utilities/ddSelectKindFksDialog.cpp @@ -0,0 +1,316 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddSelectKindFksDialog.cpp - Utility dialog class to allow user select destination of fk: automatically generated or existing column +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include "wx/stattext.h" + + +// App headers +#include "dd/dditems/utilities/ddSelectKindFksDialog.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" + + +IMPLEMENT_CLASS( ddSelectKindFksDialog, wxDialog ) + +BEGIN_EVENT_TABLE( ddSelectKindFksDialog, wxDialog ) + EVT_BUTTON(wxID_OK, ddSelectKindFksDialog::OnOkButtonClicked) + EVT_BUTTON(wxID_CANCEL, ddSelectKindFksDialog::OnCancelButtonClicked) + EVT_CHOICE(DDSELECTKINDFK, ddSelectKindFksDialog::OnChoiceFkKind) +END_EVENT_TABLE() + +ddSelectKindFksDialog::ddSelectKindFksDialog( wxWindow *parent, + ddRelationshipFigure *relation, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style + ) +{ + tablesRelation = relation; + Init(); + Create(parent, id, pos, size, style); +} + +ddSelectKindFksDialog::~ddSelectKindFksDialog() +{ + //before delete all items inside to free memory + deleteColsControls(); + delete ok; + delete line; +} + +ddSelectKindFksDialog::ddSelectKindFksDialog() +{ + Init(); +} + +void ddSelectKindFksDialog::Init( ) +{ + // choices.clear(); and delete all items inside hash map + +} + +bool ddSelectKindFksDialog::Create( wxWindow *parent, + wxWindowID id, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxCAPTION ) +{ + if (!wxDialog::Create( parent, id, wxT("Select Foreign Key Mapping for each Column"), pos, size, style )) + return false; + + CreateControls(); + + // This fits the dialog to the minimum size dictated by + // the sizers + GetSizer()->Fit(this); + + // This ensures that the dialog cannot be sized smaller + // than the minimum size + + GetSizer()->SetSizeHints(this); + + // Centre the dialog on the parent or (if none) screen + + Centre(); + + return true; +} + +void ddSelectKindFksDialog::CreateControls() +{ + // A top-level sizer + + topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + // A wxChoice to choice kind of foreign key: from Uk or from pk + wxArrayString kindFks; + kindFks.Add(_("From Primary")); + + int i, last = tablesRelation->getStartTable()->getUkConstraintsNames().Count(); + wxString tmp; + + for(i = 0; i < last; i++) + { + tmp = _("Unique Key: "); + tmp += tablesRelation->getStartTable()->getUkConstraintsNames()[i]; + kindFks.Add(tmp); + } + + kindFkCtrl = new wxChoice(this, DDSELECTKINDFK, wxDefaultPosition, wxDefaultSize, kindFks); + kindFkCtrl->SetStringSelection(_("From Primary")); + topSizer->Add(kindFkCtrl, 0, wxALIGN_CENTER, 5); + + // A dividing line before the mapping items and kind of mapping + line = new wxStaticLine ( this, wxID_STATIC, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + topSizer->Add(line, 0, wxGROW | wxALL, 5); + + + //Hack to allow multiple pairs of wxStaticText wxchoice at dialog + colsTopSizer = new wxBoxSizer(wxVERTICAL ); + topSizer->Add(colsTopSizer); + populateColumnsControls(true, -1); + + // A dividing line before the OK and Cancel buttons + + line = new wxStaticLine ( this, wxID_STATIC, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + topSizer->Add(line, 0, wxGROW | wxALL, 5); + + // A horizontal box sizer to contain Reset, OK, Cancel and Help + + okCancelBox = new wxBoxSizer(wxHORIZONTAL); + topSizer->Add(okCancelBox, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + + // The OK button + + ok = new wxButton ( this, wxID_OK, wxT("&OK"), + wxDefaultPosition, wxDefaultSize, 0 ); + okCancelBox->Add(ok, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + // The Cancel button + + cancel = new wxButton ( this, wxID_CANCEL, wxT("&Cancel"), + wxDefaultPosition, wxDefaultSize, 0 ); + okCancelBox->Add(cancel, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); +} + +void ddSelectKindFksDialog::OnChoiceFkKind(wxCommandEvent &event) +{ + int selectedUk = kindFkCtrl->GetSelection() == 0 ? -1 : kindFkCtrl->GetSelection() - 1; + bool frompk = kindFkCtrl->GetSelection() == 0; + + populateColumnsControls(frompk, selectedUk); +} + +void ddSelectKindFksDialog::deleteColsControls() +{ + choicesControlsHashMap::iterator it; + bool repeat; + ddSelectFkKindLine *columnLine; + do + { + repeat = false; + for (it = choices.begin(); it != choices.end(); ++it) + { + wxString key = it->first; + columnLine = it->second; + choices.erase(it); + delete columnLine; + repeat = true; + if (repeat) + break; + } + } + while(repeat); + colsTopSizer->Clear(); + choices.clear(); +} +void ddSelectKindFksDialog::populateColumnsControls(bool primaryKey, int useUkIndex) +{ + // Adding all columns mapping items + ddTableFigure *source = (ddTableFigure *) tablesRelation->getStartFigure(); + ddTableFigure *destination = (ddTableFigure *) tablesRelation->getEndFigure(); + + //Delete existing controllers + deleteColsControls(); + + //Populate controllers + if(primaryKey) + { + wxArrayString sourceCols = source->getAllFkSourceColsNames(true); + wxArrayString destCols = destination->getAllColumnsNames(); + destCols.Insert(_("Automatically Generated"), 0); + int i, last = sourceCols.Count(); + int eventID; + for(i = 0; i < last; i++) + { + // A sizer to allow lines of controls + linesSizer = new wxBoxSizer(wxHORIZONTAL ); + colsTopSizer->Add(linesSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + //Create controls and put inside linesizer + eventID = DDCHOICESELECTBASE + i; + ddSelectFkKindLine *newLineControls = new ddSelectFkKindLine(this, sourceCols[i], destCols, eventID); + choices[ sourceCols[i] ] = newLineControls; + linesSizer->Add(newLineControls->sourceCtrl, 0, wxALIGN_LEFT | wxALL, 5); + linesSizer->Add(newLineControls->destinationCtrl, 0, wxGROW | wxALL, 5); + } + } + else + { + wxArrayString sourceCols = source->getAllFkSourceColsNames(false, useUkIndex); + wxArrayString destCols = destination->getAllColumnsNames(); + destCols.Insert(_("Automatically Generated"), 0); + int i, last = sourceCols.Count(); + int eventID; + for(i = 0; i < last; i++) + { + // A sizer to allow lines of controls + linesSizer = new wxBoxSizer(wxHORIZONTAL ); + colsTopSizer->Add(linesSizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5); + //Create controls and put inside linesizer + eventID = DDCHOICESELECTBASE + i; + ddSelectFkKindLine *newLineControls = new ddSelectFkKindLine(this, sourceCols[i], destCols, eventID); + choices[ sourceCols[i] ] = newLineControls; + linesSizer->Add(newLineControls->sourceCtrl, 0, wxALIGN_LEFT | wxALL, 5); + linesSizer->Add(newLineControls->destinationCtrl, 0, wxGROW | wxALL, 5); + } + } + this->Layout(); + this->InvalidateBestSize(); + this->Fit(); + topSizer->RecalcSizes(); +} + +//Transfer data to the window +bool ddSelectKindFksDialog::TransferDataToWindow() +{ + return true; +} + +//Transfer data from the window +bool ddSelectKindFksDialog::TransferDataFromWindow() +{ + return true; +} + +void ddSelectKindFksDialog::OnEnterPressed( wxCommandEvent &event ) +{ + if (event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER) + { + if ( Validate() && TransferDataFromWindow() ) + { + if ( IsModal() ) + EndModal(wxID_OK); // If modal + else + { + SetReturnCode(wxID_OK); + this->Show(false); // If modeless + } + } + + } +} + +void ddSelectKindFksDialog::OnCancelButtonClicked( wxCommandEvent &event ) +{ + //Do nothing, just return wxID_CANCEL to don't allow connection + event.Skip(); +} + +void ddSelectKindFksDialog::OnOkButtonClicked( wxCommandEvent &event ) +{ + choicesControlsHashMap::iterator it; + ddSelectFkKindLine *lineOfCtrls; + + int selectedUk = kindFkCtrl->GetSelection() == 0 ? -1 : kindFkCtrl->GetSelection() - 1; + bool fromPk = kindFkCtrl->GetSelection() == 0; + tablesRelation->setFkFrom(fromPk, selectedUk); //true or bigger from zero both are mutually exclusive + + for( it = choices.begin(); it != choices.end(); ++it ) + { + wxString key = it->first; + lineOfCtrls = it->second; + if(lineOfCtrls->destinationCtrl->GetSelection() != 0) //No automatic Generated + { + ddColumnFigure *col = tablesRelation->getStartTable()->getColumnByName(lineOfCtrls->sourceCtrl->GetLabel()); + tablesRelation->addExistingColumnFk(col, lineOfCtrls->destinationCtrl->GetString(lineOfCtrls->destinationCtrl->GetSelection())); + } + } + event.Skip(); +} + +ddSelectFkKindLine::ddSelectFkKindLine(wxWindow *parent, wxString sourceColumn, wxArrayString possibleTargets, wxWindowID eventId) +{ + sourceCtrl = new wxStaticText(parent, wxID_STATIC, sourceColumn, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + destinationCtrl = new wxChoice(parent, eventId, wxDefaultPosition, wxDefaultSize, possibleTargets); + destinationCtrl->SetStringSelection(_("Automatically Generated")); +} + +ddSelectFkKindLine::ddSelectFkKindLine() +{ + sourceCtrl = NULL; + destinationCtrl = NULL; +} + +ddSelectFkKindLine::~ddSelectFkKindLine() +{ + delete sourceCtrl; + delete destinationCtrl; +} diff --git a/dd/dditems/utilities/ddTableNameDialog.cpp b/dd/dditems/utilities/ddTableNameDialog.cpp new file mode 100644 index 0000000..6b7a749 --- /dev/null +++ b/dd/dditems/utilities/ddTableNameDialog.cpp @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableNameDialog.cpp - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/dditems/utilities/ddTableNameDialog.h" +#include "dd/dditems/figures/ddTableFigure.h" + +#define txtUsualTableName CTRL_TEXT("txtUsualTableName") + + +BEGIN_EVENT_TABLE(ddTableNameDialog, pgDialog) +END_EVENT_TABLE() + + +ddTableNameDialog::ddTableNameDialog( wxWindow *parent, + const wxString &defaultValue1, + const wxString &defaultValue2, + ddTextTableItemFigure *tableItem + ) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("ddTableNameDialog")); + RestorePosition(); + Init(); + tabItem = tableItem; + checkGenerate = false; + + SetValue1(defaultValue1); + SetValue2(defaultValue2); + + txtUsualTableName->SetFocus(); +} + +ddTableNameDialog::~ddTableNameDialog() +{ +} + +ddTableNameDialog::ddTableNameDialog() : + pgDialog() +{ + Init(); +} + +void ddTableNameDialog::Init( ) +{ + m_value1 = wxEmptyString; + m_value2 = wxEmptyString; +} + +//Transfer data to the window +bool ddTableNameDialog::TransferDataToWindow() +{ + txtUsualTableName->SetValue(m_value1); + return true; +} + +//Transfer data from the window +bool ddTableNameDialog::TransferDataFromWindow() +{ + m_value1 = txtUsualTableName->GetValue(); + return true; +} + diff --git a/dd/dditems/utilities/module.mk b/dd/dditems/utilities/module.mk new file mode 100644 index 0000000..a31ff0f --- /dev/null +++ b/dd/dditems/utilities/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/dditems/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/dditems/utilities/ddPrecisionScaleDialog.cpp \ + dd/dditems/utilities/ddSelectKindFksDialog.cpp \ + dd/dditems/utilities/ddTableNameDialog.cpp +EXTRA_DIST += \ + dd/dditems/utilities/module.mk diff --git a/dd/ddmodel/ddBrowserDataContainer.cpp b/dd/ddmodel/ddBrowserDataContainer.cpp new file mode 100644 index 0000000..5521e8b --- /dev/null +++ b/dd/ddmodel/ddBrowserDataContainer.cpp @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddBrowserDataContainer.cpp - Item to contain data for each treview child. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dd/ddmodel/ddBrowserDataContainer.h" +#include "hotdraw/figures/hdIFigure.h" + + +ddBrowserDataContainer::ddBrowserDataContainer(hdIFigure *data) +{ + figure = data; +} + + +// Destructor +ddBrowserDataContainer::~ddBrowserDataContainer() +{ + +} + +int ddBrowserDataContainer::getFigureKindId() +{ + return figure->getKindId(); +} + +hdIFigure *ddBrowserDataContainer::getFigure() +{ + return figure; +} diff --git a/dd/ddmodel/ddDBReverseEnginering.cpp b/dd/ddmodel/ddDBReverseEnginering.cpp new file mode 100644 index 0000000..473041b --- /dev/null +++ b/dd/ddmodel/ddDBReverseEnginering.cpp @@ -0,0 +1,2087 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDBReverseEnginering.cpp - Reverse engineering database functions for database designer. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "schema/pgSchema.h" +#include "schema/pgDatatype.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/figures/ddRelationshipItem.h" +#include "dd/dditems/figures/ddRelationshipTerminal.h" +#include "images/namespaces.pngc" +#include "images/namespace-sm.pngc" +#include "images/gqbOrderAddAll.pngc" +#include "images/gqbOrderRemoveAll.pngc" +#include "images/gqbOrderRemove.pngc" +#include "images/gqbOrderAdd.pngc" + + +BEGIN_EVENT_TABLE(ddDBReverseEngineering, wxWizard) + EVT_WIZARD_FINISHED(wxID_ANY, ddDBReverseEngineering::OnFinishPressed) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelSchemaPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelSchemaPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelTablesPage, wxWizardPage) + EVT_BUTTON(DDREMOVE, SelTablesPage::OnButtonRemove) + EVT_BUTTON(DDREMOVEALL, SelTablesPage::OnButtonRemoveAll) + EVT_BUTTON(DDADD, SelTablesPage::OnButtonAdd) + EVT_BUTTON(DDADDALL, SelTablesPage::OnButtonAddAll) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelTablesPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(ReportPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, ReportPage::OnWizardPageChanging) +END_EVENT_TABLE() + +// +// +// +// ----- Stub & reverse engineering classes Implementation +// +// +// + +wxArrayString ddImportDBUtils::getTablesNames(pgConn *connection, wxString schemaName) +{ + + wxArrayString out; + wxString query; + + OID schemaOID = ddImportDBUtils::getSchemaOID(connection, schemaName); + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r') AND relnamespace = ") + NumToStr(schemaOID) + wxT(";"); + + pgSet *tables = connection->ExecuteSet(query); + + if (tables) + { + while (!tables->Eof()) + { + wxString tmpname = tables->GetVal(wxT("relname")); + wxString relkind = tables->GetVal(wxT("relkind")); + + if (relkind == wxT("r")) // Table + { + out.Add(tables->GetVal(wxT("relname"))); + } + + tables->MoveNext(); + } + + delete tables; + } + + return out; +} + +OID ddImportDBUtils::getSchemaOID(pgConn *connection, wxString schemaName) +{ + // Search Schemas and insert it + wxString restr = wxT(" WHERE "); + + restr += wxT("NOT "); + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (connection->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (connection->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + wxT(" AND nspname = '") + schemaName + wxT("' ") + + wxT(" ORDER BY 1, nspname"); + + pgSet *schemas = connection->ExecuteSet(sql); + + int times = 0; + OID schemaOID = -1; + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + schemaOID = schemas->GetOid(wxT("oid")); + times++; + schemas->MoveNext(); + } + + delete schemas; + } + + if(times > 1 || schemaOID == -1) + { + wxMessageBox(_("Schema not found"), _("getting table OID"), wxICON_ERROR | wxOK); + return -1; + } + return schemaOID; +} + +OID ddImportDBUtils::getTableOID(pgConn *connection, wxString schemaName, wxString tableName) +{ + + OID schemaOID = ddImportDBUtils::getSchemaOID(connection, schemaName); + wxString query; + OID tableOID = -1; + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r') AND relnamespace = ") + NumToStr(schemaOID) + + wxT(" AND relname = '") + tableName + wxT("';"); + + pgSet *tables = connection->ExecuteSet(query); + int times; + if (tables) + { + times = 0; + while (!tables->Eof()) + { + wxString relkind = tables->GetVal(wxT("relkind")); + if (relkind == wxT("r")) // Table + { + tableOID = tables->GetOid(wxT("oid")); + times++; + } + + tables->MoveNext(); + } + + delete tables; + } + + if(times > 1 || tableOID == -1) + { + wxMessageBox(_("Table not found"), _("getting table OID"), wxICON_ERROR | wxOK); + return -1; + } + return tableOID; +} + +// Don't support inherited tables right now, or tables where a column is part of more than one Unique Key. +ddStubTable *ddImportDBUtils::getTable(pgConn *connection, wxString tableName, OID tableOid) +{ + wxString sql; + int currentcol; + ddStubTable *table = NULL; + ddStubColumn *column = NULL; + + + // grab inherited tables [if found don't allow table import because this feature isn't supported right now] + sql = wxT("SELECT inhparent::regclass AS inhrelname,\n") + wxT(" (SELECT count(*) FROM pg_attribute WHERE attrelid=inhparent AND attnum>0) AS colscount\n") + wxT(" FROM pg_inherits\n") + wxT(" WHERE inhrelid = ") + NumToStr(tableOid) + wxT("::oid\n") + wxT(" ORDER BY inhseqno"); + pgSet *inhtables = connection->ExecuteSet(sql); + + if(inhtables && inhtables->Eof()) + { + wxString systemRestriction; + systemRestriction = wxT("\n AND att.attnum > 0"); + + sql = + wxT("SELECT att.*, def.*, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval, CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray, format_type(ty.oid,NULL) AS typname, format_type(ty.oid,att.atttypmod) AS displaytypname, tn.nspname as typnspname, et.typname as elemtypname,\n") + wxT(" ty.typstorage AS defaultstorage, cl.relname, na.nspname, att.attstattarget, description, cs.relname AS sername, ns.nspname AS serschema,\n") + wxT(" (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup, indkey"); + + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(",\n coll.collname, nspc.nspname as collnspname"); + if (connection->BackendMinimumVersion(8, 5)) + sql += wxT(",\n attoptions"); + if (connection->BackendMinimumVersion(7, 4)) + sql += + wxT(",\n") + wxT(" EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f'") + wxT(" AND att.attnum=ANY(conkey)) As isfk"); + if (connection->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=att.attrelid AND sl2.objsubid=att.attnum) AS providers"); + } + + sql += wxT("\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" JOIN pg_class cl ON cl.oid=att.attrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=att.attrelid AND des.objsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary\n"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + sql += wxT(" WHERE att.attrelid = ") + NumToStr(tableOid) + + systemRestriction + wxT("\n") + wxT(" AND att.attisdropped IS FALSE\n") + wxT(" ORDER BY att.attnum"); + + table = new ddStubTable(tableName, tableOid); + + pgSet *columns = connection->ExecuteSet(sql); + if (columns) + { + currentcol = 0; + while (!columns->Eof()) + { + currentcol++; + column = new ddStubColumn(columns->GetVal(wxT("attname")), tableOid); + column->pgColNumber = columns->GetLong(wxT("attnum")); + wxString pkCols = columns->GetVal(wxT("indkey")); + bool isPK = false; + wxStringTokenizer indkey(pkCols); + while (indkey.HasMoreTokens()) + { + wxString str = indkey.GetNextToken(); + if (StrToLong(str) == column->pgColNumber) + { + isPK = true; + break; + } + } + column->isPrimaryKey = isPK; + + long typmod = columns->GetLong(wxT("atttypmod")); + pgDatatype *dt = new pgDatatype(columns->GetVal(wxT("typnspname")), columns->GetVal(wxT("typname")), + columns->GetBool(wxT("isdup")), + columns->GetLong(wxT("attndims")), typmod); + + column->typeColumn = dt; + column->isNotNull = columns->GetBool(wxT("attnotnull")); + wxString colName = column->columnName; + table->cols[colName] = column; + columns->MoveNext(); + } + + delete columns; + } + setUniqueConstraints(connection, table); + setPkName(connection, table); + if(inhtables) + { + delete inhtables; + inhtables = NULL; + } + return table; + } + + return table; +} + +//true on everything fine, false when some error is found +bool ddImportDBUtils::setUniqueConstraints(pgConn *connection, ddStubTable *table) +{ + bool out = true; + //temporary fix, this should be adapted to pgadmin way of working + // check for extended ruleutils with pretty-print option + wxString prettyOption; + wxString exprname = connection->ExecuteScalar(wxT("SELECT proname FROM pg_proc WHERE proname='pg_get_viewdef' AND proargtypes[1]=16")); + if (!exprname.IsEmpty()) + prettyOption = wxT(", true"); + + wxString query; + + wxString proname, projoin; + if (connection->BackendMinimumVersion(7, 4)) + { + proname = wxT("indnatts, "); + if (connection->BackendMinimumVersion(7, 5)) + { + proname += wxT("cls.reltablespace AS spcoid, spcname, "); + projoin = wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace\n"); + } + } + else + { + proname = wxT("proname, pn.nspname as pronspname, proargtypes, "); + projoin = wxT(" LEFT OUTER JOIN pg_proc pr ON pr.oid=indproc\n") + wxT(" LEFT OUTER JOIN pg_namespace pn ON pn.oid=pr.pronamespace\n"); + } + query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisunique, indisprimary, n.nspname,\n") + wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n") + wxT(" pg_get_expr(indpred, indrelid") + prettyOption + wxT(") as indconstraint, contype, condeferrable, condeferred, amname\n"); + if (connection->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(" FROM pg_index idx\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" JOIN pg_class tab ON tab.oid=indrelid\n") + + projoin + + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace\n") + wxT(" JOIN pg_am am ON am.oid=cls.relam\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid\n") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)\n") + wxT(" WHERE indrelid = ") + NumToStr(table->OIDTable) + wxT("::oid") + + wxT(" AND contype='u' ") + + wxT("\n") + wxT(" ORDER BY cls.relname"); + pgSet *indexes = connection->ExecuteSet(query); + int ukIndex = -1; + wxArrayString UniqueKeysNames; + + if (indexes) + { + while (!indexes->Eof()) + { + ukIndex++; + wxString uniqueKeys = indexes->GetVal(wxT("indkey")); + + UniqueKeysNames.Add(indexes->GetVal(wxT("idxname"))); + + wxStringTokenizer indkey(uniqueKeys); + while (indkey.HasMoreTokens()) + { + //Get column number in unique key + wxString str = indkey.GetNextToken(); + //look at all columns [change for hashmap in a future if that option is more optimized] + stubColsHashMap::iterator it; + ddStubColumn *item; + for (it = table->cols.begin(); it != table->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //If column belong to unique constraint mark it + if (StrToLong(str) == item->pgColNumber) + { + item->uniqueKeyIndex = ukIndex; + } + } + } + indexes->MoveNext(); + } + table->UniqueKeysNames = UniqueKeysNames; + delete indexes; + } + return out; //false in a future when detect a column in more than one unique key because this is not supported by database designer right now +} + +//true on everything fine, false when some error is found +bool ddImportDBUtils::setPkName(pgConn *connection, ddStubTable *table) +{ + bool out = true; + wxString pkName = wxEmptyString; + + //temporary fix, this should be adapted to pgadmin way of working + // check for extended ruleutils with pretty-print option + wxString prettyOption; + wxString exprname = connection->ExecuteScalar(wxT("SELECT proname FROM pg_proc WHERE proname='pg_get_viewdef' AND proargtypes[1]=16")); + if (!exprname.IsEmpty()) + prettyOption = wxT(", true"); + + wxString query; + + wxString proname, projoin; + if (connection->BackendMinimumVersion(7, 4)) + { + proname = wxT("indnatts, "); + if (connection->BackendMinimumVersion(7, 5)) + { + proname += wxT("cls.reltablespace AS spcoid, spcname, "); + projoin = wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace\n"); + } + } + else + { + proname = wxT("proname, pn.nspname as pronspname, proargtypes, "); + projoin = wxT(" LEFT OUTER JOIN pg_proc pr ON pr.oid=indproc\n") + wxT(" LEFT OUTER JOIN pg_namespace pn ON pn.oid=pr.pronamespace\n"); + } + query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisunique, indisprimary, n.nspname,\n") + wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n") + wxT(" pg_get_expr(indpred, indrelid") + prettyOption + wxT(") as indconstraint, contype, condeferrable, condeferred, amname\n"); + if (connection->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(" FROM pg_index idx\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" JOIN pg_class tab ON tab.oid=indrelid\n") + + projoin + + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace\n") + wxT(" JOIN pg_am am ON am.oid=cls.relam\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid\n") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)\n") + wxT(" WHERE indrelid = ") + NumToStr(table->OIDTable) + wxT("::oid") + + wxT(" AND contype='p' ") + + wxT("\n") + wxT(" ORDER BY cls.relname"); + pgSet *indexes = connection->ExecuteSet(query); + if (indexes) + { + while (!indexes->Eof()) + { + pkName = indexes->GetVal(wxT("idxname")); + indexes->MoveNext(); + } + delete indexes; + } + + table->PrimaryKeyName = pkName; + return out; //false in a future when detect a column in more than one unique key because this is not supported by database designer right now +} + +void ddImportDBUtils::getAllRelationships(pgConn *connection, stubTablesHashMap &tables, ddDatabaseDesign *design) +{ + wxString sql; + ddRelationshipFigure *relation = NULL; + ddTableFigure *sourceTabFigure = NULL; + ddTableFigure *destTabFigure = NULL; + //Add Tables to the Model + stubTablesHashMap::iterator mainIt; + ddStubTable *destStubTable = NULL; + for (mainIt = tables.begin(); mainIt != tables.end(); ++mainIt) + { + wxString key = mainIt->first; + destStubTable = mainIt->second; + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destStubTable->OIDTable) + wxT("::oid") + //+ restriction + + + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + if (foreignKeys && foreignKeys->NumRows() > 0) + { + while (!foreignKeys->Eof()) + { + wxString sourceSchema, destSchema; + sourceSchema = foreignKeys->GetVal(wxT("refnsp")); + destSchema = foreignKeys->GetVal(wxT("fknsp")); + + // Source Table ----------------------<| Destination Table + + if(sourceSchema.IsSameAs(destSchema, false)) + { + wxString sourceTableName = foreignKeys->GetVal(wxT("reftab")); + wxString destTableName = foreignKeys->GetVal(wxT("fktab")); + + destTabFigure = design->getTable(destTableName); + sourceTabFigure = design->getTable(sourceTableName); + + //Only if both tables were imported at same time + if(destTabFigure != NULL && sourceTabFigure != NULL) + { + + int ukindex = -1; //Only Supporting foreign keys from PK right now when importing model + wxString RelationshipName = foreignKeys->GetVal(wxT("conname")); + + wxString onUpd = foreignKeys->GetVal(wxT("confupdtype")); + actionKind onUpdate = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + + wxString onDel = foreignKeys->GetVal(wxT("confdeltype")); + actionKind onDelete = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + wxString match = foreignKeys->GetVal(wxT("confmatchtype")); + bool matchSimple = match.IsSameAs('f') ? false : + match.IsSameAs('u') ? true : false; + + + //------ Preparing metada to allow discovery of some relationship attributes + //Source table columns + wxString fkColsSourceTable = foreignKeys->GetVal(wxT("confkey")); + //remove {} of string + fkColsSourceTable.Remove(0, 1); + fkColsSourceTable.RemoveLast(); + wxString fkColsDestTable = foreignKeys->GetVal(wxT("conkey")); + //remove {} of string + fkColsDestTable.Remove(0, 1); + fkColsDestTable.RemoveLast(); + + wxSortedArrayInt sourceFkCols(sortFunc); + wxSortedArrayInt destFkCols(sortFunc); + wxSortedArrayInt sourcePKs(sortFunc); + wxSortedArrayInt destPKs(sortFunc); + + //Split columns from sourceFk + wxStringTokenizer confkey(fkColsSourceTable); + while (confkey.HasMoreTokens()) + { + wxString str = confkey.GetNextToken(); + sourceFkCols.Add(StrToLong(str)); + } + + //Split columns from destFk + wxStringTokenizer conkey(fkColsDestTable); + while (conkey.HasMoreTokens()) + { + wxString str = conkey.GetNextToken(); + destFkCols.Add(StrToLong(str)); + } + + //Get Stub of source table + ddStubTable *sourceStubTable = tables[sourceTableName]; + + //Get PK columns of source + stubColsHashMap::iterator it; + ddStubColumn *column; + for (it = sourceStubTable->cols.begin(); it != sourceStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + sourcePKs.Add(column->pgColNumber); + } + + //Get PK columns of dest + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + destPKs.Add(column->pgColNumber); + } + + // Source Table ----------------------<| Destination Table + //Default assumption is the source of this fk is a Primary Key. + bool fkFromPk = true; + + //first check: number of columns used as fk at Source is the same of the pk at Source + if(sourceFkCols.Count() == sourcePKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int srcFkCount = sourceFkCols.Count(); + for(i = 0; i < srcFkCount; i++) + { + if( sourceFkCols[i] != sourcePKs[i] ) + { + fkFromPk = false; + break; + } + } + } + else + { + fkFromPk = true; + } + + //------ Finding fk from uk or pk? + int ukIndex = -1; + //if fkFromPk = false then is fkfromUK?, check that + //all source fk columns should belong to one Uk at source table. + if( fkFromPk == false ) + { + bool error = false; + int baseColNumber = sourceFkCols[sourceFkCols.Count() - 1]; + int baseUkIdxSourceCol = sourceStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + int nextColNumber, nextUkIdxSourceCol; + int countSrcFkCols = sourceFkCols.Count() - 2; + while(countSrcFkCols >= 0) + { + nextColNumber = sourceFkCols[countSrcFkCols]; + nextUkIdxSourceCol = sourceStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countSrcFkCols--; + if(baseUkIdxSourceCol != nextUkIdxSourceCol) + { + error = true; + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return; + } + } + if(!error) + { + ukIndex = baseUkIdxSourceCol; + } + } + + //Last check of consistency + if(fkFromPk == false && ukIndex < 0) + { + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return; + } + + + //------ identifying relationship or not -----|-<|? + //Default assumption is relationship is identifying + bool identifying = true; + + //first check: number of columns used as fk at Source is the same of the pk at Source + if(destFkCols.Count() == destPKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int destFkCount = destFkCols.Count(); + for(i = 0; i < destFkCount; i++) + { + if( destFkCols[i] != destPKs[i] ) + { + identifying = false; + break; + } + } + } + else + { + identifying = false; + } + + //------ 1:1 or 1:M ? as a fact 1:1 have a fk,uk at destination table. + // A foreign key have an one to many relationship when there is an UK for same column(s) + // inside the foreign key. Assumption, a column on belong to one Uk (no more than one). + bool oneToMany = true; + int baseColNumber = destFkCols[destFkCols.Count() - 1]; + int baseUkIdxDestCol = destStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + if(baseUkIdxDestCol != -1) + { + oneToMany = false; + int nextUkIdxDestCol, nextColNumber; + int countDestFkCols = destFkCols.Count() - 2; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countDestFkCols--; + //if a dest fk column is not in the same Uk index of first one + if(nextUkIdxDestCol != baseUkIdxDestCol) + { + oneToMany = true; + break; + } + } + } + + //Step two check all column of fk are inside a unique key (all and not more) + if(oneToMany == false) //assumption is 1:1 relationship until now + { + int numberColsInUk = 0, nextUkIdxDestCol, nextColNumber; + ddStubColumn *item; + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //at each column with same uk index that base comparison column, count it + nextColNumber = item->pgColNumber; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + if( nextUkIdxDestCol == baseUkIdxDestCol) + { + numberColsInUk++; + } + } + + //number of columns in uk used by relationship is bigger or lesser than number of columns + //in destination table used by relationship as fk dest(dest fk columnn), then is not 1:1 + if(numberColsInUk != destFkCols.Count()) + oneToMany = true; + } + + //Optional or Mandatory consistency + bool mandatoryRelationship; + + int countDestFkCols = destFkCols.Count() - 1; + bool isNotNull; + int nnCols = 0, nullCols = 0, nextColNumber; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + isNotNull = destStubTable->getColumnByNumber(nextColNumber)->isNotNull; + countDestFkCols--; + if(isNotNull) + nnCols++; + else + nullCols++; + } + + if(nnCols == 0 && nullCols > 0) + { + mandatoryRelationship = false; + } + else if(nnCols > 0 && nullCols == 0) + { + mandatoryRelationship = true; + } + else + { + wxMessageBox(_("Error detecting kind of foreign key: null or not null"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return; + } + + relation = new ddRelationshipFigure(); + relation->setStartTerminal(new ddRelationshipTerminal(relation, false)); + relation->setEndTerminal(new ddRelationshipTerminal(relation, true)); + relation->clearPoints(0); + relation->initRelationValues(sourceTabFigure, destTabFigure, ukIndex, RelationshipName, onUpdate, onDelete, matchSimple, identifying, oneToMany, mandatoryRelationship, fkFromPk); + relation->updateConnection(0); + design->addTableToModel(relation); + + //Add items to relationship + wxString srcColName, destColName; + ddColumnFigure *sourceCol = NULL, *destinationCol = NULL; + bool autoGenFk = false; + wxString initialColName; + ddRelationshipItem *item = NULL; + int i, srcFkCount = sourceFkCols.Count(); + for(i = 0; i < srcFkCount ; i++) + { + srcColName = sourceStubTable->getColumnByNumber(sourceFkCols[i])->columnName; + destColName = destStubTable->getColumnByNumber(destFkCols[i])->columnName; + sourceCol = sourceTabFigure->getColByName(srcColName); + destinationCol = destTabFigure->getColByName(destColName); + initialColName = srcColName; + item = new ddRelationshipItem(); + item->initRelationshipItemValues(relation, destTabFigure, autoGenFk, destinationCol, sourceCol, initialColName); + relation->getItemsHashMap()[item->original->getColumnName()] = item; + } + } + } + foreignKeys->MoveNext(); + } + delete foreignKeys; + } + } +} + +bool ddImportDBUtils::existsFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName) +{ + wxString sql; + OID sourceOID = getTableOID(connection, schemaName, sourceTableName); + if(sourceOID == -1 ) + { + return false; + } + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destTableOid) + wxT("::oid") + wxT(" AND conname ='") + fkName + wxT("' ") + wxT(" AND confrelid = ") + NumToStr(sourceOID) + wxT("::oid") + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + //relation don't exists then + if(foreignKeys->NumRows() == 0) + { + return false; + } + delete foreignKeys; + + return true; +} + +int ddImportDBUtils::getPgColumnNum(pgConn *connection, wxString schemaName, wxString tableName, wxString columnName) +{ + int out = -1; + wxString sql; + OID tableOid = getTableOID(connection, schemaName, tableName); + wxString systemRestriction; + systemRestriction = wxT("\n AND att.attnum > 0"); + + sql = wxT("SELECT att.attrelid,att.attname, att.attnum ") + wxT("\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" JOIN pg_class cl ON cl.oid=att.attrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=att.attrelid AND des.objsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary\n"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + sql += wxT(" WHERE att.attrelid = ") + NumToStr(tableOid) + + systemRestriction + wxT("\n") + wxT(" AND att.attisdropped IS FALSE\n") + wxT(" ORDER BY att.attnum"); + + pgSet *columns = connection->ExecuteSet(sql); + if (columns) + { + while (!columns->Eof()) + { + wxString colName = columns->GetVal(wxT("attname")); + if(colName.IsSameAs(columnName, false)) + { + out = columns->GetLong(wxT("attnum")); + break; + } + columns->MoveNext(); + } + delete columns; + } + return out; +} + +wxArrayString ddImportDBUtils::getFkAtDbNotInModel(pgConn *connection, OID destTableOid, wxString schemaName, wxArrayString existingFkList, ddDatabaseDesign *design) +{ + wxArrayString out; + wxString sql; + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destTableOid) + wxT("::oid"); + //Add Fk names in model + int i, max = existingFkList.Count(); + if(max > 0) + { + sql += wxT(" AND conname NOT IN( "); + for(i = 0; i < max - 1; i++) + { + sql += wxT("'") + existingFkList[i] + wxT("',"); + } + if(max >= 1) + { + sql += wxT("'") + existingFkList[max - 1] + wxT("'"); + } + sql += wxT(" ) "); + } + + //Add valid tables sources names to search (others outside a model shouldn't be modified) + sql += wxT("\n ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + if (foreignKeys && foreignKeys->NumRows() > 0) + { + while (!foreignKeys->Eof()) + { + //Create a list will all relationships in db but not in model [but only for tables IN MODEL because tables not in model SHOULDN'T BE modified] + wxString sourceTableName = foreignKeys->GetVal(wxT("reftab")); + if(design->getTable(sourceTableName)) + { + wxString RelationshipName = foreignKeys->GetVal(wxT("conname")); + out.Add(RelationshipName); + } + foreignKeys->MoveNext(); + } + delete foreignKeys; + } + //return a list with Fks to delete from db because don't exists at model. + return out; +} + +//Assumption Fk exists, and this should be checked before with existsFk function +bool ddImportDBUtils::isModelSameDbFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName, wxString destTableName, ddStubTable *destStubTable, ddRelationshipFigure *relation) +{ + bool equalFk = true; + + wxString sql; + OID sourceOID = getTableOID(connection, schemaName, sourceTableName); + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (connection->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=ct.oid\n") + wxT(" WHERE contype='f' AND conrelid = ") + NumToStr(destTableOid) + wxT("::oid") + wxT(" AND conname ='") + fkName + wxT("' ") + wxT(" AND confrelid = ") + NumToStr(sourceOID) + wxT("::oid") + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = connection->ExecuteSet(sql); + + + //First Step create array with columns from pgCol numbers from destTable (MODEL) in relationship; + //Second Step create array with columns from pgCol numbers from srcTable (MODEL) in relationship; + wxSortedArrayInt destPgs(sortFunc); + wxSortedArrayInt srcPgs(sortFunc); + columnsHashMap::iterator it; + ddRelationshipItem *item; + for (it = relation->getItemsHashMap().begin(); it != relation->getItemsHashMap().end(); ++it) + { + wxString key = it->first; + item = it->second; + int pgColDest = getPgColumnNum(connection, schemaName, destTableName, item->fkColumn->getColumnName()); + destPgs.Add(pgColDest); + int pgColSrc = getPgColumnNum(connection, schemaName, sourceTableName, item->original->getColumnName()); + srcPgs.Add(pgColSrc); + } + + //Extracting relationship metadata information from DB relationship + int ukindex = -1; //Only Supporting foreign keys from PK right now when importing model + wxString RelationshipName; + actionKind onUpdate; + actionKind onDelete; + bool matchSimple; + bool identifying = true; //Default assumption is relationship is identifying + bool oneToMany = true; + bool mandatoryRelationship; + bool fkFromPk = true; //Default assumption is the source of this fk is a Primary Key. + wxSortedArrayInt sourceFkCols(sortFunc); + wxSortedArrayInt destFkCols(sortFunc); + + + if (foreignKeys && foreignKeys->NumRows() == 1) + { + while (!foreignKeys->Eof()) + { + + //------ Preparing metada to allow discovery of some relationship attributes + RelationshipName = foreignKeys->GetVal(wxT("conname")); + + wxString onUpd = foreignKeys->GetVal(wxT("confupdtype")); + onUpdate = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + + wxString onDel = foreignKeys->GetVal(wxT("confdeltype")); + onDelete = onUpd.IsSameAs('a') ? FK_ACTION_NO : + onUpd.IsSameAs('r') ? FK_RESTRICT : + onUpd.IsSameAs('c') ? FK_CASCADE : + onUpd.IsSameAs('d') ? FK_SETDEFAULT : + onUpd.IsSameAs('n') ? FK_SETNULL : FK_ACTION_NO; + + wxString match = foreignKeys->GetVal(wxT("confmatchtype")); + matchSimple = match.IsSameAs('f') ? false : + match.IsSameAs('u') ? true : false; + + + //------ Preparing metada to allow discovery of some relationship attributes + //Source table columns + wxString fkColsSourceTable = foreignKeys->GetVal(wxT("confkey")); + wxSortedArrayInt sourcePKs(sortFunc); + wxSortedArrayInt destPKs(sortFunc); + //remove {} of string + fkColsSourceTable.Remove(0, 1); + fkColsSourceTable.RemoveLast(); + wxString fkColsDestTable = foreignKeys->GetVal(wxT("conkey")); + //remove {} of string + fkColsDestTable.Remove(0, 1); + fkColsDestTable.RemoveLast(); + + //Separe columns from sourceFk + wxStringTokenizer confkey(fkColsSourceTable); + while (confkey.HasMoreTokens()) + { + wxString str = confkey.GetNextToken(); + sourceFkCols.Add(StrToLong(str)); + } + + //Separe columns from destFk + wxStringTokenizer conkey(fkColsDestTable); + while (conkey.HasMoreTokens()) + { + wxString str = conkey.GetNextToken(); + destFkCols.Add(StrToLong(str)); + } + + //Get Stub of source table + ddStubTable *sourceStubTable = ddImportDBUtils::getTable(connection, sourceTableName, sourceOID); + + //Get PK columns of source + stubColsHashMap::iterator it; + ddStubColumn *column; + for (it = sourceStubTable->cols.begin(); it != sourceStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + sourcePKs.Add(column->pgColNumber); + } + + //Get PK columns of dest + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + column = it->second; + if(column->isPrimaryKey) + destPKs.Add(column->pgColNumber); + } + + // Source Table ----------------------<| Destination Table + + //first check: number of columns used as fk at Source is the same of the pk at Source + if(sourceFkCols.Count() == sourcePKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int srcFkCount = sourceFkCols.Count(); + for(i = 0; i < srcFkCount; i++) + { + if( sourceFkCols[i] != sourcePKs[i] ) + { + fkFromPk = false; + break; + } + } + } + else + { + fkFromPk = true; + } + + //------ Finding fk from uk or pk? + int ukIndex = -1; + //if fkFromPk = false then is fkfromUK?, check that + //all source fk columns should belong to one Uk at source table. + if( fkFromPk == false ) + { + bool error = false; + int baseColNumber = sourceFkCols[sourceFkCols.Count() - 1]; + int baseUkIdxSourceCol = sourceStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + int nextColNumber, nextUkIdxSourceCol; + int countSrcFkCols = sourceFkCols.Count() - 2; + while(countSrcFkCols >= 0) + { + nextColNumber = sourceFkCols[countSrcFkCols]; + nextUkIdxSourceCol = sourceStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countSrcFkCols--; + if(baseUkIdxSourceCol != nextUkIdxSourceCol) + { + error = true; + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return false; + } + } + if(!error) + { + ukIndex = baseUkIdxSourceCol; + } + } + + //Last check of consistency + if(fkFromPk == false && ukIndex < 0) + { + wxMessageBox(_("Error detecting kind of foreign key source: from Pk or from Uk"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return false; + } + + + //------ identifying relationship or not -----|-<|? + //first check: number of columns used as fk at Source is the same of the pk at Source + if(destFkCols.Count() == destPKs.Count()) + { + int i; + //Because postgres columns numbers are stored in an ordered array, + //their index should be the same at all positions + int destFkCount = destFkCols.Count(); + for(i = 0; i < destFkCount; i++) + { + if( destFkCols[i] != destPKs[i] ) + { + identifying = false; + break; + } + } + } + else + { + identifying = false; + } + + //------ 1:1 or 1:M ? as a fact 1:1 have a fk,uk at destination table. + // A foreign key have an one to many relationship when there is an UK for same column(s) + // inside the foreign key. Assumption, a column on belong to one Uk (no more than one). + int baseColNumber = destFkCols[destFkCols.Count() - 1]; + int baseUkIdxDestCol = destStubTable->getColumnByNumber(baseColNumber)->uniqueKeyIndex; + if(baseUkIdxDestCol != -1) + { + oneToMany = false; + int nextUkIdxDestCol, nextColNumber; + int countDestFkCols = destFkCols.Count() - 2; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + countDestFkCols--; + //if a dest fk column is not in the same Uk index of first one + if(nextUkIdxDestCol != baseUkIdxDestCol) + { + oneToMany = true; + break; + } + } + } + + //Step two check all column of fk are inside a unique key (all and not more) + if(oneToMany == false) //assumption is 1:1 relationship until now + { + int numberColsInUk = 0, nextUkIdxDestCol, nextColNumber; + ddStubColumn *item; + for (it = destStubTable->cols.begin(); it != destStubTable->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //at each column with same uk index that base comparison column, count it + nextColNumber = item->pgColNumber; + nextUkIdxDestCol = destStubTable->getColumnByNumber(nextColNumber)->uniqueKeyIndex; + if( nextUkIdxDestCol == baseUkIdxDestCol) + { + numberColsInUk++; + } + } + + //number of columns in uk used by relationship is bigger or lesser than number of columns + //in destination table used by relationship as fk dest(dest fk columnn), then is not 1:1 + if(numberColsInUk != destFkCols.Count()) + oneToMany = true; + } + + //Optional or Mandatory consistency + int countDestFkCols = destFkCols.Count() - 1; + bool isNotNull; + int nnCols = 0, nullCols = 0, nextColNumber; + while(countDestFkCols >= 0) + { + nextColNumber = destFkCols[countDestFkCols]; + isNotNull = destStubTable->getColumnByNumber(nextColNumber)->isNotNull; + countDestFkCols--; + if(isNotNull) + nnCols++; + else + nullCols++; + } + + if(nnCols == 0 && nullCols > 0) + { + mandatoryRelationship = false; + } + else if(nnCols > 0 && nullCols == 0) + { + mandatoryRelationship = true; + } + else + { + wxMessageBox(_("Error detecting kind of foreign key: null or not null"), _("Error importing relationship"), wxICON_ERROR | wxOK); + delete foreignKeys; + return false; + } + delete sourceStubTable; + foreignKeys->MoveNext(); + } + //After collection db info compare with model info + + //Is safe to check if this UKindex is the same Ukindex of relationship because both aren't equal. + //Before should by unified by same uk index like in comparing uk at table figure class + //Todo in a future + + //relation is fromPk in model and db? + if(fkFromPk && !relation->isForeignKeyFromPk()) + equalFk = false; + + //OnUpdateAction is the same kind? + if(onUpdate != relation->getOnUpdateAction()) + equalFk = false; + + //OnDeleteAction is the same kind? + if(onDelete != relation->getOnDeleteAction()) + equalFk = false; + + //Are same match kind + if(matchSimple != relation->getMatchSimple()) + equalFk = false; + + //are both identifying? + if(identifying != relation->getIdentifying()) + equalFk = false; + + //are both 1:1 or 1:M + if(oneToMany != relation->getOneToMany()) + equalFk = false; + + //Mandatory value is the same? + if(mandatoryRelationship != relation->getMandatory()) + equalFk = false; + + //Columns at both arrays: created from model and created from db are supposed to have same number of item + //if not fk has changed. + + //Number of source fk columns at DB is the same number of source fk columns at model + if(sourceFkCols.Count() != srcPgs.Count()) + equalFk = false; + + //Number of destination fk columns at DB is the same number of destination fk columns at model + if(destFkCols.Count() != destPgs.Count()) + equalFk = false; + + //Now because arrays are sorted they numbers should match exactly (same pg column number) + int i, max = sourceFkCols.Count(); + for(i = 0; i < max; i++) + { + if(sourceFkCols[i] != srcPgs[i]) + equalFk = false; + } + + max = destFkCols.Count(); + for(i = 0; i < max; i++) + { + if(destFkCols[i] != destPgs[i]) + equalFk = false; + } + + return equalFk; + } + else + { + wxMessageBox(_("Error fk is repeated"), _("Error comparing relationships"), wxICON_ERROR | wxOK); + } + delete foreignKeys; + + return equalFk; +} + +ddTableFigure *ddImportDBUtils::getTableFigure(ddStubTable *table) +{ + wxString name = table->tableName; + ddTableFigure *tableFigure = new ddTableFigure(name, -1, -1); + if(tableFigure != NULL) + { + //Default Values + int colsRowsSize = 0; + int colsWindow = 0; + int idxsRowsSize = 0; + int idxsWindow = 0; + int maxColIndex = 2; + int minIdxIndex = 2; + int maxIdxIndex = 2; + int beginDrawCols = 2; + int beginDrawIdxs = 2; + + tableFigure->InitTableValues(table->UniqueKeysNames, table->PrimaryKeyName, beginDrawCols, beginDrawIdxs, maxColIndex, minIdxIndex, maxIdxIndex, colsRowsSize, colsWindow, idxsRowsSize, idxsWindow); + + //Add Columns to Table + stubColsHashMap::iterator it; + ddStubColumn *item; + for (it = table->cols.begin(); it != table->cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + + ddColumnOptionType option = item->isNotNull ? notnull : null; + bool generateFkName = false; //Not automatic names will be used by default at user imported tables. + + wxString dataType = item->typeColumn->Name(); + + //temporary conversion fix to datatype of designer should be improved in a future + int s = -1, p = -1; + bool useScale = true, needps = false; + s = item->typeColumn->Length(); + p = item->typeColumn->Precision(); + + if(dataType.IsSameAs(wxT("character varying"), false)) + { + needps = true; + dataType = wxT("varchar(n)"); + } + + else if(dataType.IsSameAs(wxT("numeric"), false)) + { + needps = true; + useScale = false; + dataType = wxT("numeric(p,s)"); + } + else if(dataType.IsSameAs(wxT("interval"), false)) + { + needps = true; + dataType = wxT("interval(n)"); + } + else if(dataType.IsSameAs(wxT("bit"), false)) + { + needps = true; + dataType = wxT("bit(n)"); + } + else if(dataType.IsSameAs(wxT("char"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + else if(dataType.IsSameAs(wxT("varbit"), false)) + { + needps = true; + dataType = wxT("varbit(n)"); + } + else if(dataType.IsSameAs(wxT("character"), false)) + { + needps = true; + dataType = wxT("char(n)"); + } + + int precision = -1; + int scale = -1; + wxString colName = item->columnName; + + int ukindex = -1; //By default no ukindex is set + + ddColumnFigure *columnFigure = new ddColumnFigure(colName, tableFigure, option, generateFkName, item->isPrimaryKey, dataType, precision, scale, ukindex, NULL, NULL); + //a conversion problem I called precision to length of types, pgadmin called scale. + //this should be fixed, at the same time the datatype subsystem of the database designer will be redesigned. + + /* + Disable right now, it can be useful at the future when db designer will be improved again + columnFigure->setPgAttNumCol(item->pgColNumber); + */ + if(needps) + { + if(useScale) + { + columnFigure->setPrecision(s); + columnFigure->setScale(-1); + } + else + { + columnFigure->setPrecision(p); + columnFigure->setScale(s); + } + } + + if(item->isUniqueKey()) + { + columnFigure->setUniqueConstraintIndex(item->uniqueKeyIndex); + } + + tableFigure->addColumn(-1, columnFigure); + columnFigure->setRightIconForColumn(); + } + return tableFigure; + } + else + { + return NULL; + } +} + +ddStubTable::ddStubTable() +{ + tableName = wxEmptyString; +} + +ddStubTable::ddStubTable(wxString name, OID tableOID) +{ + tableName = name; + OIDTable = tableOID; +} + +ddStubTable::~ddStubTable() +{ +} + +ddStubColumn *ddStubTable::getColumnByNumber(int pgColNumber) +{ + stubColsHashMap::iterator it; + ddStubColumn *item, *out = NULL; + for (it = cols.begin(); it != cols.end(); ++it) + { + wxString key = it->first; + item = it->second; + //If found pgColNumber at table columns + if (item->pgColNumber == pgColNumber) + { + out = item; + break; + } + } + return out; +} + +ddStubColumn::ddStubColumn(wxString name, OID oidSource, bool notNull, bool pk, pgDatatype *type, int ukIndex) +{ + columnName = name; + OIDTable = oidSource; + isNotNull = notNull; + isPrimaryKey = pk; + typeColumn = type; + uniqueKeyIndex = ukIndex; +} + +ddStubColumn::ddStubColumn(const ddStubColumn ©) +{ + columnName = copy.columnName; + OIDTable = copy.OIDTable; + isNotNull = copy.isNotNull; + isPrimaryKey = copy.isPrimaryKey; + typeColumn = copy.typeColumn; + uniqueKeyIndex = copy.uniqueKeyIndex; +} + +ddStubColumn::ddStubColumn(wxString name, OID oidSource) +{ + columnName = name; + OIDTable = oidSource; + uniqueKeyIndex = -1; + OIDTable = -1; + typeColumn = NULL; +} + +ddStubColumn::ddStubColumn() +{ + uniqueKeyIndex = -1; + OIDTable = -1; + typeColumn = NULL; +} + +ddStubColumn::~ddStubColumn() +{ + if(typeColumn) + delete typeColumn; +} + +bool ddStubColumn::isUniqueKey() +{ + return uniqueKeyIndex > -1; +}; + +// +// +// +// ----- ddDBReverseEngineering Implementation +// +// +// + +ddDBReverseEngineering::ddDBReverseEngineering(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer) + : wxWizard(frame, wxID_ANY, wxT("Import tables from schema wizard"), + wxBitmap(*namespaces_png_bmp), wxDefaultPosition, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + conn = connection; + OIDSelectedSchema = 0; + figuresDesign = design; + + // a wizard page may be either an object of predefined class + initialPage = new wxWizardPageSimple(this); + + frontText = new wxStaticText(initialPage, wxID_ANY, + wxT("Import database tables to model tables wizard.\n") + wxT("\n") + wxT("The next pages will allow you to import database tables inside a database model.") + wxT("\n\n") + wxT("\nSome restrictions apply:\n\n") + wxT("1. Columns that belong to more than one unique constraint aren't supported.\n\n") + wxT("2. Relationships are imported only if both tables (source and destination) are imported.\n\n") + wxT("3. User defined datatypes aren't supported.\n\n") + wxT("4. No indexes, views, sequences and others objects different from tables/relationships can be imported.\n\n") + wxT("5. Tables with same name cannot be imported.\n\n") + wxT("6. Inherited tables cannot be imported.\n\n") + , wxPoint(5, 5) + ); + + page2 = new SelSchemaPage(this, initialPage); + initialPage->SetNext(page2); + page3 = new SelTablesPage(this, page2); + page2->SetNext(page3); + page4 = new ReportPage(this, page3); + page3->SetNext(page4); + page4->SetNext(NULL); + + if ( useSizer ) + { + // allow the wizard to size itself around the pages + GetPageAreaSizer()->Add(initialPage); + } +} + +// Destructor +ddDBReverseEngineering::~ddDBReverseEngineering() +{ + if(frontText) + delete frontText; +} + + + +wxArrayString ddDBReverseEngineering::getTables() +{ + + wxArrayString out; + wxString query; + + tablesOIDHM.clear(); + + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r') AND relnamespace = ") + NumToStr(OIDSelectedSchema) + wxT(";"); + + pgSet *tables = conn->ExecuteSet(query); + + if (tables) + { + while (!tables->Eof()) + { + wxString tmpname = tables->GetVal(wxT("relname")); + wxString relkind = tables->GetVal(wxT("relkind")); + + if (relkind == wxT("r")) // Table + { + out.Add(tables->GetVal(wxT("relname"))); + tablesOIDHM[tables->GetVal(wxT("relname"))] = tables->GetOid(wxT("oid")); + } + + tables->MoveNext(); + } + + delete tables; + } + + return out; +} + +void ddDBReverseEngineering::OnFinishPressed(wxWizardEvent &event) +{ + //Add Tables to the Model + stubTablesHashMap::iterator it; + ddStubTable *item; + for (it = stubsHM.begin(); it != stubsHM.end(); ++it) + { + wxString key = it->first; + item = it->second; + figuresDesign->addTableToModel(ddImportDBUtils::getTableFigure(item)); + } + //Add All relationships to the Model + ddImportDBUtils::getAllRelationships(getConnection(), stubsHM, getDesign()); +} + + +// +// +// +// ----- SelSchemaPage Implementation +// +// +// + +SelSchemaPage::SelSchemaPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddDBReverseEngineering *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + //Add a message + message = new wxStaticText(this, wxID_STATIC, _("Please, select a schema to use at import tables process:"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + topSizer->Add(message); + topSizer->AddSpacer(10); + + //Get Schemas info + if(wparent && wparent->getConnection()) + refreshSchemas(wparent->getConnection()); + + //Add a listbox with schemas + m_allSchemas = new wxListBox(this, DDALLSCHEMAS, wxDefaultPosition, wxDefaultSize, schemasNames, wxLB_SORT | wxLB_ALWAYS_SB | wxLB_SINGLE); + topSizer->Add(m_allSchemas, 1, wxEXPAND); +} + +SelSchemaPage::~SelSchemaPage() +{ + if(m_allSchemas) + delete m_allSchemas; + if(message) + delete message; +} + +void SelSchemaPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_allSchemas->GetSelection() == wxNOT_FOUND) + { + wxMessageBox(_("Please, select a Schema to continue to next step."), _("Select a Schema..."), wxICON_WARNING | wxOK, this); + event.Veto(); + } + else if(event.GetDirection()) + { + wparent->OIDSelectedSchema = schemasHM[schemasNames[m_allSchemas->GetSelection()]]; + wparent->schemaName = schemasNames[m_allSchemas->GetSelection()]; + wparent->page3->RefreshTablesList(); + } +} + +void SelSchemaPage::refreshSchemas(pgConn *connection) +{ + + schemasHM.clear(); + schemasNames.Clear(); + // Search Schemas and insert it + wxString restr = wxT(" WHERE "); + + restr += wxT("NOT "); + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (connection->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (connection->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + + pgSet *schemas = connection->ExecuteSet(sql); + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + //Build Schema Tree item + //this->AppendItem(rootNode, name , DD_IMG_FIG_SCHEMA, DD_IMG_FIG_SCHEMA, NULL); + schemasNames.Add(name); + schemasHM[name] = schemas->GetOid(wxT("oid")); + schemas->MoveNext(); + } + + delete schemas; + } + +} + +// +// +// +// ----- SelTablesPage Implementation +// +// +// + +SelTablesPage::SelTablesPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddDBReverseEngineering *) parent; + m_prev = prev; + m_next = NULL; + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(2, 3, 0, 0); + this->SetSizer(mainSizer); + + leftText = new wxStaticText(this, wxID_STATIC, _("Table(s) from selected schema"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(leftText); + centerText = new wxStaticText(this, wxID_STATIC, wxT(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(centerText); + + rightText = new wxStaticText(this, wxID_STATIC, _("Tables(s) to be imported"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(rightText, wxALIGN_LEFT); + + //left listbox with all tables from selected schema + m_allTables = new wxListBox( this, DDALLTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableRow(1); + mainSizer->AddGrowableCol(0); + mainSizer->Add(m_allTables , 1, wxEXPAND); + + addBitmap = *gqbOrderAdd_png_bmp; + addAllBitmap = *gqbOrderAddAll_png_bmp; + removeBitmap = *gqbOrderRemove_png_bmp; + removeAllBitmap = *gqbOrderRemoveAll_png_bmp; + + buttonAdd = new wxBitmapButton( this, DDADD, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") ); + buttonAdd->SetToolTip(_("Add the selected table(s)")); + buttonAddAll = new wxBitmapButton( this, DDADDALL, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") ); + buttonAddAll->SetToolTip(_("Add all tables")); + buttonRemove = new wxBitmapButton( this, DDREMOVE, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") ); + buttonRemove->SetToolTip(_("Remove the selected table(s)")); + buttonRemoveAll = new wxBitmapButton( this, DDREMOVEALL, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") ); + buttonRemoveAll->SetToolTip(_("Remove all tables")); + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonAddAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemove, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemoveAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + mainSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + //right listbox with selected tables from schema to be imported. + m_selTables = new wxListBox( this, DDSELTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableCol(2); + mainSizer->Add(m_selTables , 1, wxEXPAND); + mainSizer->Fit(this); +} + +SelTablesPage::~SelTablesPage() +{ + if(rightText) + delete rightText; + if(centerText) + delete centerText; + if(leftText) + delete leftText; + if(m_allTables) + delete m_allTables; + if(m_selTables) + delete m_selTables; + if(buttonAdd) + delete buttonAdd; + if(buttonAddAll) + delete buttonAddAll; + if(buttonRemove) + delete buttonRemove; + if(buttonRemoveAll) + delete buttonRemoveAll; +} + +void SelTablesPage::RefreshTablesList() +{ + m_allTables->Set(wparent->getTables(), (void **)NULL); +} + +void SelTablesPage::OnButtonAdd(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_allTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); + for(i = 0; i < size; i++) + { + m_selTables->Append(m_allTables->GetString(positions[i])); + m_allTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_allTables->Delete(positions[i]); + } + + if(m_allTables->GetCount() > 0) + m_allTables->Select(0); + } +} + +void SelTablesPage::OnButtonAddAll(wxCommandEvent &) +{ + int itemsCount = m_allTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_allTables->Deselect(0); + m_selTables->Append(m_allTables->GetString(0)); + m_allTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + +void SelTablesPage::OnButtonRemove(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_selTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); //warning about conversion should be ignored + for(i = 0; i < size; i++) + { + m_allTables->Append(m_selTables->GetString(positions[i])); + m_selTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_selTables->Delete(positions[i]); + } + + if(m_selTables->GetCount() > 0) + m_selTables->Select(0); + } +} + +void SelTablesPage::OnButtonRemoveAll(wxCommandEvent &) +{ + int itemsCount = m_selTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_selTables->Deselect(0); + m_allTables->Append(m_selTables->GetString(0)); + m_selTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + +void SelTablesPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_selTables->GetCount() <= 0) + { + wxMessageBox(_("Please, select at least a table to continue to next step."), _("Select some Tables..."), wxICON_WARNING | wxOK, this); + event.Veto(); + } + else if(event.GetDirection()) + { + + int itemsCount = m_selTables->GetCount(); + if( itemsCount > 0) + { + int item = 0; + do + { + ddStubTable *table = ddImportDBUtils::getTable(wparent->getConnection(), m_selTables->GetString(item), wparent->tablesOIDHM[m_selTables->GetString(item)]); + if(table == NULL) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Error when preparing to import table: ") + m_selTables->GetString(item) + _(", this table have inherited columns and this feature is not supported at this moment.\n\n")); + } + else if(wparent->getDesign()->getTable(m_selTables->GetString(item)) != NULL) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Error when preparing to import table: ") + m_selTables->GetString(item) + _(", this table already exists in the model and updating table at a model is not supported at this moment.\n\n")); + } + else if(table->tableName.Length() > 0) + { + if(m_next) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Prepared to import table: ") + table->tableName + _("\n")); + wparent->stubsHM[table->tableName] = table; + } + } + else + { + if(m_next) + { + ReportPage *tmp = (ReportPage *) m_next; + tmp->results->AppendText(_("Error when preparing to import table: ") + m_selTables->GetString(item) + _("\n")); + } + } + item++; + } + while(item < itemsCount); + } + } + else if(!event.GetDirection()) + { + //Reset tables after a warning + int answer = wxMessageBox(_("Returning to previous dialog will remove all selected tables, do you like to continue?"), _("Confirm"), wxYES_NO | wxCANCEL, this); + if (answer == wxYES) + { + m_selTables->Clear(); + m_allTables->Clear(); + wparent->tablesOIDHM.clear(); + } + else + event.Veto(); + } +} + +// +// +// +// ----- ReportPage Implementation +// +// +// + +ReportPage::ReportPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddDBReverseEngineering *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + //Add a message + results = new wxTextCtrl(this, wxID_ANY , wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_LEFT + ); + topSizer->Add(results, 1, wxEXPAND); + topSizer->Fit(this); +} + +ReportPage::~ReportPage() +{ + if(results) + delete results; +} + +void ReportPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(!event.GetDirection()) + { + int answer = wxMessageBox(_("Returning to previous dialog will delete imported tables before adding it to the model?"), _("Confirm"), wxYES_NO | wxCANCEL, this); + if (answer == wxYES) + { + results->Clear(); + wparent->stubsHM.clear(); + } + else + event.Veto(); + } +} + diff --git a/dd/ddmodel/ddDatabaseDesign.cpp b/dd/ddmodel/ddDatabaseDesign.cpp new file mode 100644 index 0000000..68e52d2 --- /dev/null +++ b/dd/ddmodel/ddDatabaseDesign.cpp @@ -0,0 +1,710 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDatabaseDesign.cpp - Manages all design related info and contains all model(s) and tables. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// libxml2 headers +#include +#include + +// App headers +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "hotdraw/tools/hdSelectionTool.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/dditems/figures/xml/ddXmlStorage.h" +#include "dd/ddmodel/ddModelBrowser.h" + + +ddDatabaseDesign::ddDatabaseDesign(wxWindow *parent, wxWindow *frmOwner) +{ + editor = new ddDrawingEditor(parent, frmOwner, this); + attachedBrowser = NULL; +} + +ddDatabaseDesign::~ddDatabaseDesign() +{ + if(editor) + delete editor; +} + +ddDrawingEditor *ddDatabaseDesign::getEditor() +{ + return editor; +} + +hdDrawingView *ddDatabaseDesign::getView(int diagramIndex) +{ + return editor->getExistingView(diagramIndex); +} + +void ddDatabaseDesign::registerBrowser(ddModelBrowser *browser) +{ + attachedBrowser = browser; +} + +void ddDatabaseDesign::addTableToModel(hdIFigure *figure) +{ + editor->addModelFigure(figure); + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +void ddDatabaseDesign::addTableToView(int diagramIndex, hdIFigure *figure) +{ + editor->addDiagramFigure(diagramIndex, figure); + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +void ddDatabaseDesign::refreshBrowser() +{ + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +void ddDatabaseDesign::removeTable(int diagramIndex, hdIFigure *figure) +{ + editor->removeDiagramFigure(diagramIndex, figure); +} + +void ddDatabaseDesign::refreshDraw(int diagramIndex) +{ + editor->getExistingView(diagramIndex)->Refresh(); +} + +void ddDatabaseDesign::eraseDiagram(int diagramIndex) +{ + editor->getExistingDiagram(diagramIndex)->removeAllFigures(); +} + +void ddDatabaseDesign::emptyModel() +{ + editor->deleteAllModelFigures(); + if(attachedBrowser) + { + attachedBrowser->refreshFromModel(); + } +} + +bool ddDatabaseDesign::validateModel(wxString &errors) +{ + bool out = true; + + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + if(!table->validateTable(errors)) + { + out = false; + } + } + } + delete iterator; + + return out; +} + +wxString ddDatabaseDesign::generateList(wxArrayString tables, wxArrayInt options, pgConn *connection, wxString schemaName) +{ + int i; + + // Validate + if(tables.Count() != options.Count()) + { + // shouldn't it be a WXASSERT? + wxMessageBox(_("Invalid number of arguments in call of function generate tables of list"), _("Error at generation process"), wxICON_ERROR | wxOK); + return wxEmptyString; + } + + int tablesCount = tables.Count(); + for(i = 0; i < tablesCount; i++) + { + ddTableFigure *table = getTable(tables[i]); + if(table == NULL) + { + // shouldn't it be a WXASSERT? + wxMessageBox(_("Metadata of table to be generated not found at database designer model"), _("Error at generation process"), wxICON_ERROR | wxOK); + return wxEmptyString; + } + } + + // Start building of CREATE + ALTER PK(s) + ALTER UK(s) + ALTER FK(s) + wxString out; + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Create sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + if(options[i] == DDGENDROPCRE) + { + out += wxT(" \n"); + out += wxT("DROP TABLE \"") + table->getTableName() + wxT("\";"); + out += wxT(" \n"); + } + out += wxT(" \n"); + out += table->generateSQLCreate(schemaName); + out += wxT(" \n"); + } + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Pk sentence for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateSQLAlterPks(schemaName); + } + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Uk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateSQLAlterUks(schemaName); + } + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Fk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENCREATE || options[i] == DDGENDROPCRE) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateSQLAlterFks(schemaName); + } + } + + //Start generation of alter table instead of create + //Check there is some + int countAlter = 0; + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENALTER) + { + countAlter++; + } + } + + if(countAlter > 0 && connection == NULL) + { + wxMessageBox(_("No connection found when building ALTER objects DDL."), _("Error at generation process"), wxICON_ERROR | wxOK); + return out; + } + else if(countAlter > 0 && connection != NULL) + { + if(schemaName.IsEmpty()) + { + wxMessageBox(_("Schema defined when building ALTER TABLE DDL"), _("Error at generation process"), wxICON_ERROR | wxOK); + return out; + } + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Alter table sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + for(i = 0; i < tablesCount; i++) + { + if(options[i] == DDGENALTER) + { + ddTableFigure *table = getTable(tables[i]); + out += table->generateAltersTable(connection, schemaName, this); + out += wxT(" \n"); + } + } + } + + return out; +} + +wxArrayString ddDatabaseDesign::getModelTables() +{ + wxArrayString out; + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out.Add(table->getTableName()); + } + } + return out; +} + +wxString ddDatabaseDesign::generateModel(wxString schemaName) +{ + wxString out; + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Create sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + out += wxT(" \n"); + table = (ddTableFigure *)tmp; + out += table->generateSQLCreate(schemaName); + out += wxT(" \n"); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Pk sentence for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterPks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Uk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterUks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Fk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterFks(schemaName); + } + } + + delete iterator; + return out; +} + +wxArrayString ddDatabaseDesign::getDiagramTables(int diagramIndex) +{ + wxArrayString out; + hdIteratorBase *iterator = editor->getExistingDiagram(diagramIndex)->figuresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out.Add(table->getTableName()); + } + } + + return out; +} + +wxString ddDatabaseDesign::generateDiagram(int diagramIndex, wxString schemaName) +{ + wxString out; + hdIteratorBase *iterator = editor->getExistingDiagram(diagramIndex)->figuresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Create sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + out += wxT(" \n"); + table = (ddTableFigure *)tmp; + out += table->generateSQLCreate(schemaName); + out += wxT(" \n"); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Pk sentence for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterPks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Uk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterUks(schemaName); + } + } + + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT(" \n"); + out += wxT("--\n-- "); + out += _("Generating Fk sentence(s) for table(s) "); + out += wxT(" \n--\n"); + out += wxT(" \n"); + out += wxT(" \n"); + iterator->ResetIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + out += table->generateSQLAlterFks(schemaName); + } + } + + delete iterator; + return out; +} + +ddTableFigure *ddDatabaseDesign::getSelectedTable(int diagramIndex) +{ + hdIteratorBase *iterator = editor->getExistingDiagram(diagramIndex)->figuresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table = NULL; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if (tmp->isSelected(diagramIndex) && tmp->getKindId() == DDTABLEFIGURE) + table = (ddTableFigure *)tmp; + } + delete iterator; + return table; +} + +ddTableFigure *ddDatabaseDesign::getTable(wxString tableName) +{ + ddTableFigure *out = NULL; + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + if(table->getTableName().IsSameAs(tableName, false)) + { + out = table; + } + } + } + delete iterator; + return out; +} + +#define XML_FROM_WXSTRING(s) ((xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) + +bool ddDatabaseDesign::writeXmlModel(wxString file) +{ + int rc; + + xmlWriter = xmlNewTextWriterFilename(file.mb_str(wxConvUTF8), 0); + if (xmlWriter == NULL) + { + wxMessageBox(_("Failed to write the model file!"), _("Error"), wxICON_ERROR | wxOK); + return false; + } + rc = xmlTextWriterStartDocument(xmlWriter, NULL, "UTF-8" , NULL); + if(rc < 0) + { + wxMessageBox(_("Failed to write the model file!"), _("Error"), wxICON_ERROR | wxOK); + return false; + } + else + { + ddXmlStorage::StartModel(xmlWriter, this); + //initialize IDs of tables + mappingNameToId.clear(); + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmp; + ddTableFigure *table; + int nextID = 10; + + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + mappingNameToId[table->getTableName()] = wxString::Format(wxT("TID%d"), nextID); + nextID += 10; + } + } + delete iterator; + + + //Create table xml info + iterator = editor->modelFiguresEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + ddXmlStorage::Write(xmlWriter, table); + } + } + delete iterator; + + + //Create relationships xml info + ddRelationshipFigure *relationship; + iterator = editor->modelFiguresEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relationship = (ddRelationshipFigure *)tmp; + ddXmlStorage::Write(xmlWriter, relationship); + } + } + delete iterator; + + //Create Diagrams xml info + + ddXmlStorage::StarDiagrams(xmlWriter); + + iterator = editor->diagramsEnumerator(); + hdDrawing *tmpDiagram; + + while(iterator->HasNext()) + { + tmpDiagram = (hdDrawing *)iterator->Next(); + ddXmlStorage::WriteLocal(xmlWriter, tmpDiagram); + } + delete iterator; + + ddXmlStorage::EndDiagrams(xmlWriter); + + //End model xml info + ddXmlStorage::EndModel(xmlWriter); + xmlTextWriterEndDocument(xmlWriter); + xmlFreeTextWriter(xmlWriter); + return true; + } + return false; +} + +bool ddDatabaseDesign::readXmlModel(wxString file, ctlAuiNotebook *notebook) +{ + emptyModel(); + + mappingIdToName.clear(); + //Initial Parse Model + xmlTextReaderPtr reader = xmlReaderForFile(file.mb_str(wxConvUTF8), NULL, 0); + ddXmlStorage::setModel(this); + ddXmlStorage::setModel(this); + ddXmlStorage::initialModelParse(reader); + + //Parse Model + xmlReaderNewFile(reader, file.mb_str(wxConvUTF8), NULL, 0); + ddXmlStorage::setModel(this); + ddXmlStorage::setNotebook(notebook); + + if(!ddXmlStorage::Read(reader)) + { + return false; + } + xmlFreeTextReader(reader); + return true; +} + +wxString ddDatabaseDesign::getTableId(wxString tableName) +{ + return mappingNameToId[tableName]; +} + +void ddDatabaseDesign::addTableToMapping(wxString IdKey, wxString tableName) +{ + mappingIdToName[IdKey] = tableName; +} + +wxString ddDatabaseDesign::getTableName(wxString Id) +{ + wxString tableName = wxEmptyString; + + tablesMappingHashMap::iterator it; + for (it = mappingIdToName.begin(); it != mappingIdToName.end(); ++it) + { + wxString key = it->first; + if(key.IsSameAs(Id, false)) + { + tableName = it->second; + break; + } + } + return tableName; +} + +hdDrawing *ddDatabaseDesign::createDiagram(wxWindow *owner, wxString name, bool fromXml) +{ + hdDrawing *drawing = editor->createDiagram(owner, fromXml); + drawing->setName(name); + return drawing; +} + +void ddDatabaseDesign::deleteDiagram(int diagramIndex, bool deleteView) +{ + editor->deleteDiagram(diagramIndex, deleteView); +} + +wxString ddDatabaseDesign::getVersionXML() +{ + return wxString(_("1.0")); +} + +void ddDatabaseDesign::markSchemaOn(wxArrayString tables) +{ + + int i, tablesCount = tables.Count(); + for(i = 0; i < tablesCount; i++) + { + ddTableFigure *table = getTable(tables[i]); + if(table != NULL) //mark on if table exists in other case do nothing + { + table->setBelongsToSchema(true); + } + } +} + +void ddDatabaseDesign::unMarkSchemaOnAll() +{ + hdIteratorBase *iterator = editor->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + table->setBelongsToSchema(false); + } + } + delete iterator; +} diff --git a/dd/ddmodel/ddDrawingEditor.cpp b/dd/ddmodel/ddDrawingEditor.cpp new file mode 100644 index 0000000..ddf593c --- /dev/null +++ b/dd/ddmodel/ddDrawingEditor.cpp @@ -0,0 +1,300 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.cpp - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddDrawingView.h" +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "frm/frmDatabaseDesigner.h" + + +ddDrawingEditor::ddDrawingEditor(wxWindow *owner, wxWindow *frmOwner, ddDatabaseDesign *design) + : hdDrawingEditor(owner, true) +{ + databaseDesign = design; + frm = (frmDatabaseDesigner *) frmOwner; +} + +hdDrawing *ddDrawingEditor::createDiagram(wxWindow *owner, bool fromXml) +{ + + hdDrawing *_tmpModel = new hdDrawing(this); + + ddDrawingView *_viewTmp = new ddDrawingView(_diagrams->count(), owner, this, wxSize(1200, 1200), _tmpModel); + + // Set Scroll Bar & split + _viewTmp->SetScrollbars( 10, 10, 127, 80 ); + _viewTmp->EnableScrolling(true, true); + _viewTmp->AdjustScrollbars(); + + _tmpModel->registerView(_viewTmp); + + _viewTmp->SetDropTarget(new ddDropTarget(databaseDesign, _tmpModel)); + + if(!fromXml) + { + //Add a new position inside each figure to allow use of this new diagram existing figures. + int i; + hdIFigure *tmp; + for(i = 0; i < _model->count(); i++) + { + tmp = (hdIFigure *) _model->getItemAt(i); + tmp->AddPosForNewDiagram(); + } + } + //Add Diagram + _diagrams->addItem((hdObject *) _tmpModel); + modelChanged = true; + return _tmpModel; +} + + +void ddDrawingEditor::remOrDelSelFigures(int diagramIndex) +{ + hdIFigure *tmp; + ddTableFigure *table; + ddRelationshipFigure *relation; + hdIteratorBase *iterator; + hdCollection *tmpSelection; + int answer; + int numbTables = 0; + int numbRelationships = 0; + + if (getExistingDiagram(diagramIndex)->countSelectedFigures() == 1) + { + tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0); + if(tmp->getKindId() == DDTABLEFIGURE) + { + numbTables = 1; + table = (ddTableFigure *)tmp; + hdRemoveDeleteDialog dialog(_("Are you sure you wish to delete table ") + table->getTableName() + wxT("?"), _("Delete table?"), getExistingView(diagramIndex)); + answer = dialog.ShowModal(); + } + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + numbRelationships = 1; + relation = (ddRelationshipFigure *)tmp; + //Relationship can be delete only NOT REMOVED + hdRemoveDeleteDialog dialog2(_("Are you sure you wish to delete relationship ") + relation->getConstraintName() + wxT("?"), _("Delete relationship?"), getExistingView(diagramIndex), false); + answer = dialog2.ShowModal(); + } + } + else if (getExistingDiagram(diagramIndex)->countSelectedFigures() > 1) + { + numbTables = 0; + iterator = getExistingDiagram(diagramIndex)->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDTABLEFIGURE) + numbTables++; + } + delete iterator; + + + //Improve messages to display about relationships and tables and only relationship + hdRemoveDeleteDialog dialog3( + wxString::Format(_("Are you sure you wish to delete %d tables, removing from model related relationships?"), numbTables), + _("Delete tables?"), getExistingView(diagramIndex)); + answer = dialog3.ShowModal(); + } + + if (answer == DD_DELETE || answer == DD_REMOVE) + { + modelChanged = true; + tmpSelection = new hdCollection(new hdArrayCollection()); + + //Preprocess relationships counting and storing at temporary collection + numbRelationships = 0; + iterator = getExistingDiagram(diagramIndex)->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + numbRelationships++; + tmpSelection->addItem(tmp); + } + } + delete iterator; + + while(numbTables > 0) + { + tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0); + if(tmp->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmp; + if(table && answer == DD_REMOVE) + { + getExistingDiagram(diagramIndex)->removeFromSelection(table); + getExistingDiagram(diagramIndex)->remove(table); + } + //if table is going to be delete all others diagrams should be alerted about it + if(table && answer == DD_DELETE) + { + removeFromAllSelections(table); + table->processDeleteAlert(getExistingDiagram(diagramIndex)); + deleteModelFigure(table); + databaseDesign->refreshBrowser(); + } + numbTables--; + } + else if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + getExistingDiagram(diagramIndex)->removeFromSelection(tmp); //isn't a tables is probably a relationship + } + else + { + wxMessageBox(_("Invalid figure kind found"), _("Error while deleting tables"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex)); + } + } + + if( numbRelationships > 0 ) + { + + //check again: Are there relationships selected that wasn't delete (only selected relationship not source/destination table) + numbRelationships = 0; + iterator = tmpSelection->createIterator(); //getExistingDiagram(diagramIndex)->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + //only way a relationship don't exists at diagram is + //it had been deleted before by deleting source/destination table that owns it + if(getExistingDiagram(diagramIndex)->includes(tmp)) + { + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + numbRelationships++; + } + else + { + wxMessageBox(_("Invalid figure kind found"), _("Error while deleting table"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex)); + } + } + else + { + tmpSelection->removeItem(tmp); + } + } + delete iterator; + + while(numbRelationships > 0 && tmpSelection->count() == numbRelationships) + { + tmp = (hdIFigure *) tmpSelection->getItemAt(0); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relation = (ddRelationshipFigure *)tmp; + if(relation && answer == DD_REMOVE) + { + getExistingDiagram(diagramIndex)->removeFromSelection(relation); + getExistingDiagram(diagramIndex)->remove(relation); + } + //if relation is going to be delete all others diagrams should be alerted about it + if(relation && answer == DD_DELETE) + { + removeFromAllSelections(relation); + relation->removeForeignKeys(); + relation->disconnectEnd(); + relation->disconnectStart(); + deleteModelFigure(relation); + databaseDesign->refreshBrowser(); + } + numbRelationships--; + } + else + { + wxMessageBox(_("Invalid figure kind found"), _("Error while deleting realtionships"), wxCENTRE | wxICON_ERROR, getExistingView(diagramIndex)); + // getExistingDiagram(diagramIndex)->removeFromSelection(tmp); //isn't neither a table or relationship + } + } + } + getExistingDiagram(diagramIndex)->clearSelection(); //after delete all items all relationships remains at selection and should be removed + tmpSelection->removeAll(); + delete tmpSelection; + } +} + +void ddDrawingEditor::checkRelationshipsConsistency(int diagramIndex) +{ + hdIFigure *tmp; + ddRelationshipFigure *relation; + hdDrawing *diagram = getExistingDiagram(diagramIndex); + + // First Step Removel all orphan [relations without source or destination] relationships + // from DIAGRAM but NOT from MODEL + hdIteratorBase *iterator = diagram->figuresEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relation = (ddRelationshipFigure *)tmp; + //test if all tables of a relationship are included if this is not the case then remove relationship from this diagram + bool sourceExists = diagram->getFiguresCollection()->existsObject(relation->getStartTable()); + bool destinationExists = diagram->getFiguresCollection()->existsObject(relation->getEndTable()); + if(!sourceExists || !destinationExists) + { + diagram->remove(relation); + } + + } + } + delete iterator; + + // Now add all existing relationships in MODEL to DIAGRAM if both source and destination + // tables exists at DIAGRAM + iterator = _model->createIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->getKindId() == DDRELATIONSHIPFIGURE) + { + relation = (ddRelationshipFigure *)tmp; + + //test if all tables of a relationship are included if this is the case then include relationship at this diagram + bool sourceExists = diagram->getFiguresCollection()->existsObject(relation->getStartTable()); + bool destinationExists = diagram->getFiguresCollection()->existsObject(relation->getEndTable()); + bool relationExists = diagram->getFiguresCollection()->existsObject(relation); + if(sourceExists && destinationExists && !relationExists) + { + diagram->add(relation); + relation->updateConnection(diagramIndex); + } + } + } + delete iterator; +} + +void ddDrawingEditor::checkAllDigramsRelConsistency() +{ + int i, size = modelCount(); + + for(i = 0; i < size ; i++) + { + checkRelationshipsConsistency(i); + } +} + +void ddDrawingEditor::notifyChanged() +{ + if(frm) + frm->setModelChanged(true); + modelChanged = true; +} diff --git a/dd/ddmodel/ddDrawingView.cpp b/dd/ddmodel/ddDrawingView.cpp new file mode 100644 index 0000000..0683eac --- /dev/null +++ b/dd/ddmodel/ddDrawingView.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDrawingView.cpp - Main canvas where all tables and relationships are drawn +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "dd/ddmodel/ddDrawingView.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" + +ddDrawingView::ddDrawingView(int diagram, wxWindow *ddParent, ddDrawingEditor *editor , wxSize size, hdDrawing *drawing) + : hdDrawingView(diagram, ddParent, editor, size, drawing) +{ +} + +void ddDrawingView::createViewMenu(wxMenu &mnu) +{ + mnu.Append(MNU_NEWTABLE, _("Add new Table")); +} + +void ddDrawingView::OnGenericViewPopupClick(wxCommandEvent &event) +{ + ddDrawingEditor *ed = (ddDrawingEditor *) editor(); + switch(event.GetId()) + { + case MNU_NEWTABLE: + ddTableNameDialog *newTableDialog = new ddTableNameDialog( + this, + wxEmptyString, + wxEmptyString, + NULL + ); + int answer = newTableDialog->ShowModal(); + if (answer == wxID_OK && !newTableDialog->GetValue1().IsEmpty()) + { + ddTableFigure *newTable = new ddTableFigure(newTableDialog->GetValue1(), + rand() % 90 + 200, + rand() % 90 + 140); + ed->getDesign()->addTableToView(this->getIdx(), newTable); + ed->getDesign()->refreshDraw(this->getIdx()); + } + delete newTableDialog; + break; + } +} + +ddDropTarget::ddDropTarget(ddDatabaseDesign *sourceDesign, hdDrawing *targetDrawing) +{ + target = targetDrawing; + source = sourceDesign; + +} + +bool ddDropTarget::OnDropText(wxCoord x, wxCoord y, const wxString &text) +{ + ddTableFigure *t = source->getTable(text); + if(t != NULL && !target->includes(t)) + { + target->add(t); + t->syncInternalsPosAt(target->getView()->getIdx(), x, y); + source->getEditor()->checkRelationshipsConsistency(target->getView()->getIdx()); + target->getView()->Refresh(); + return true; + } + else + { + if(target->includes(t)) + { + wxMessageBox(_("Table exists already at this diagram"), _("Drag and drop warning"), wxICON_EXCLAMATION | wxOK); + return true; + } + else + return false; + } +} diff --git a/dd/ddmodel/ddGenerationWizard.cpp b/dd/ddmodel/ddGenerationWizard.cpp new file mode 100644 index 0000000..89f7424 --- /dev/null +++ b/dd/ddmodel/ddGenerationWizard.cpp @@ -0,0 +1,740 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddGenerationWizard.cpp - Wizard to allow generation of tables. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "schema/pgSchema.h" +#include "dd/ddmodel/ddGenerationWizard.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "gqb/gqbGridRestTable.h" +#include "images/gqbOrderAddAll.pngc" +#include "images/gqbOrderRemoveAll.pngc" +#include "images/gqbOrderRemove.pngc" +#include "images/gqbOrderAdd.pngc" + + +#include "images/continue.pngc" + +const wxColour LIGHT_YELLOW(0xff, 0xff, 0x80); + +BEGIN_EVENT_TABLE(ddGenerationWizard, wxWizard) + EVT_WIZARD_FINISHED(wxID_ANY, ddGenerationWizard::OnFinishPressed) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, ddGenerationWizard::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelGenTablesPage, wxWizardPage) + EVT_BUTTON(DDREMOVE, SelGenTablesPage::OnButtonRemove) + EVT_BUTTON(DDREMOVEALL, SelGenTablesPage::OnButtonRemoveAll) + EVT_BUTTON(DDADD, SelGenTablesPage::OnButtonAdd) + EVT_BUTTON(DDADDALL, SelGenTablesPage::OnButtonAddAll) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelGenTablesPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(SelGenSchemaPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, SelGenSchemaPage::OnWizardPageChanging) +END_EVENT_TABLE() + +BEGIN_EVENT_TABLE(ReportGridPage, wxWizardPage) + EVT_WIZARD_PAGE_CHANGING(wxID_ANY, ReportGridPage::OnWizardPageChanging) +END_EVENT_TABLE() + +ddGenerationWizard::ddGenerationWizard(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer) + : wxWizard(frame, wxID_ANY, wxT("Generate DDL from model"), + wxBitmap(*continue_png_bmp), wxDefaultPosition, + wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + conn = connection; + figuresDesign = design; + + // a wizard page may be either an object of predefined class + initialPage = new wxWizardPageSimple(this); + + frontText = new wxStaticText(initialPage, wxID_ANY, + wxT("Build DDL from model tables.\n") + wxT("\n") + wxT("The next pages will allow the built of DDL of the current database designer model.") + wxT("\n\n") + wxT("Restrictions apply when using experimental function ALTER TABLE instead of DROP/CREATE:\n\n") + wxT("1. Database connection is required to check differences with existing tables.\n\n") + wxT("2. Only changes done in the design will be applied to the db, not otherwise.\n\n") + wxT("3. Rename of columns or tables is not (yet) supported.\n\n") + wxT("4. Rename of constraints generate a drop and create, except for primary key constraints.\n\n") + wxT("5. All constraints should have a defined name.\n\n") + , wxPoint(5, 5) + ); + + page2 = new SelGenTablesPage(this, initialPage); + initialPage->SetNext(page2); + page3 = new SelGenSchemaPage(this, page2); + page2->SetNext(page3); + page4 = new ReportGridPage(this, page3); + page3->SetNext(page4); + + if (useSizer) + { + // allow the wizard to size itself around the pages + GetPageAreaSizer()->Add(initialPage); + } +} + +ddGenerationWizard::~ddGenerationWizard() +{ +} + +void ddGenerationWizard::OnFinishPressed(wxWizardEvent &event) +{ + wxString strChoicesSimple[1] = {_("Create table")}; + wxString strChoicesAlter[4] = {_("Alter table"), _("Drop, then create"), _("Create table [conflict]"), wxT("No action")}; + wxArrayString tables; + wxArrayInt options; + //if(page4->getGrid()->GetRows() > 0) + if(page4->getGrid()->GetNumberRows() > 0) + { + int i; + for(i = page4->getGrid()->GetNumberRows() - 1; i >= 0; i--) + { + tables.Add(page4->getGrid()->GetCellValue(i, 0)); + wxString value = page4->getGrid()->GetCellValue(i, 1); + if(value.IsSameAs(strChoicesAlter[0])) + { + options.Add(DDGENALTER); + } + else if(value.IsSameAs(strChoicesAlter[1])) + { + options.Add(DDGENDROPCRE); + } + else if(value.IsSameAs(strChoicesAlter[2]) || value.IsSameAs(strChoicesSimple[0])) + { + options.Add(DDGENCREATE); + } + else if(value.IsSameAs(strChoicesAlter[3])) + { + options.Add(DDGENNOTHING); + } + } + } + DDL = getDesign()->generateList(tables, options, conn, schemaName); +} + +void ddGenerationWizard::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection()) + { + page2->RefreshTablesList(); + } +} + +// ----- SelGenTablesPage Implementation + +SelGenTablesPage::SelGenTablesPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddGenerationWizard *) parent; + m_prev = prev; + m_next = NULL; + + wxFlexGridSizer *mainSizer = new wxFlexGridSizer(2, 3, 0, 0); + this->SetSizer(mainSizer); + + leftText = new wxStaticText(this, wxID_STATIC, _("Table(s) from selected schema"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(leftText); + centerText = new wxStaticText(this, wxID_STATIC, _(" "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(centerText); + + rightText = new wxStaticText(this, wxID_STATIC, _("Tables(s) to be generated"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + mainSizer->Add(rightText, wxALIGN_LEFT); + + // Left listbox with all tables + m_allTables = new wxListBox( this, DDALLTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableRow(1); + mainSizer->AddGrowableCol(0); + mainSizer->Add(m_allTables , 1, wxEXPAND); + + addBitmap = *gqbOrderAdd_png_bmp; + addAllBitmap = *gqbOrderAddAll_png_bmp; + removeBitmap = *gqbOrderRemove_png_bmp; + removeAllBitmap = *gqbOrderRemoveAll_png_bmp; + + buttonAdd = new wxBitmapButton( this, DDADD, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") ); + buttonAdd->SetToolTip(_("Add the selected table(s)")); + buttonAddAll = new wxBitmapButton( this, DDADDALL, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") ); + buttonAddAll->SetToolTip(_("Add all tables")); + buttonRemove = new wxBitmapButton( this, DDREMOVE, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") ); + buttonRemove->SetToolTip(_("Remove the selected table(s)")); + buttonRemoveAll = new wxBitmapButton( this, DDREMOVEALL, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") ); + buttonRemoveAll->SetToolTip(_("Remove all tables")); + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonAddAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemove, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + buttonsSizer->Add( + this->buttonRemoveAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 3 + + mainSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + //right listbox with selected tables from schema to be imported. + m_selTables = new wxListBox( this, DDSELTABS, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED | wxLB_ALWAYS_SB | wxLB_SORT); + mainSizer->AddGrowableCol(2); + mainSizer->Add(m_selTables , 1, wxEXPAND); + mainSizer->Fit(this); +} + +SelGenTablesPage::~SelGenTablesPage() +{ + if(rightText) + delete rightText; + if(centerText) + delete centerText; + if(leftText) + delete leftText; + if(m_allTables) + delete m_allTables; + if(m_selTables) + delete m_selTables; + if(buttonAdd) + delete buttonAdd; + if(buttonAddAll) + delete buttonAddAll; + if(buttonRemove) + delete buttonRemove; + if(buttonRemoveAll) + delete buttonRemoveAll; +} + +void SelGenTablesPage::OnButtonAdd(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_allTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); + for(i = 0; i < size; i++) + { + m_selTables->Append(m_allTables->GetString(positions[i])); + m_allTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_allTables->Delete(positions[i]); + } + + if(m_allTables->GetCount() > 0) + m_allTables->Select(0); + } +} + +void SelGenTablesPage::OnButtonAddAll(wxCommandEvent &) +{ + int itemsCount = m_allTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_allTables->Deselect(0); + m_selTables->Append(m_allTables->GetString(0)); + m_allTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + +void SelGenTablesPage::OnButtonRemove(wxCommandEvent &) +{ + wxArrayInt positions; + if(m_selTables->GetSelections(positions) > 0) + { + int i; + int size = positions.Count(); // Warning about conversion should be ignored + for(i = 0; i < size; i++) + { + m_allTables->Append(m_selTables->GetString(positions[i])); + m_selTables->Deselect(positions[i]); + } + + for(i = (size - 1); i >= 0 ; i--) + { + m_selTables->Delete(positions[i]); + } + + if(m_selTables->GetCount() > 0) + m_selTables->Select(0); + } +} + +void SelGenTablesPage::OnButtonRemoveAll(wxCommandEvent &) +{ + int itemsCount = m_selTables->GetCount(); + if( itemsCount > 0) + { + do + { + m_selTables->Deselect(0); + m_allTables->Append(m_selTables->GetString(0)); + m_selTables->Delete(0); + itemsCount--; + } + while(itemsCount > 0); + } +} + + +void SelGenTablesPage::moveToSelectList(wxString tableName) +{ + int position = m_allTables->FindString(tableName); + if(position != wxNOT_FOUND) + { + m_selTables->Append(m_allTables->GetString(position)); + m_allTables->Delete(position); + } +} + + +void SelGenTablesPage::RefreshTablesList() +{ + wxArrayString tablesList; + m_allTables->Clear(); + m_selTables->Clear(); + + hdIteratorBase *iterator = wparent->getDesign()->getEditor()->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + tablesList.Add(table->getTableName()); + } + } + delete iterator; + m_allTables->Set(tablesList, (void **)NULL); + + int max = wparent->preSelTables.Count(); + if(max > 0) + { + int i; + for(i = 0; i < max; i++) + { + moveToSelectList(wparent->preSelTables[i]); + } + } + +} + + +void SelGenTablesPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_selTables->GetCount() <= 0) + { + wxMessageBox(_("Please select at least one table to move to next step."), _("No tables selected"), wxICON_WARNING | wxOK, this); + event.Veto(); + } +} + +// ----- SelGenSchemaPage Implementation + +SelGenSchemaPage::SelGenSchemaPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddGenerationWizard *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + //Add a message + message = new wxStaticText(this, wxID_STATIC, _("Please select a schema to use as check target.\n\nThis affects the choice between CREATE/ALTER table(s) matching for the DDL generated depending on whether or not the table exists in that schema."), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(message); + topSizer->AddSpacer(10); + + //Get Schemas info + if(wparent && wparent->getConnection()) + refreshSchemas(wparent->getConnection()); + else + schemasNames.Add(_("No schema")); + + //Add a listbox with schemas + m_allSchemas = new wxListBox(this, DDALLSCHEMAS, wxDefaultPosition, wxDefaultSize, schemasNames, wxLB_SORT | wxLB_ALWAYS_SB | wxLB_SINGLE); + topSizer->Add(m_allSchemas, 1, wxEXPAND); +} + +SelGenSchemaPage::~SelGenSchemaPage() +{ + if(m_allSchemas) + delete m_allSchemas; + if(message) + delete message; +} + +void SelGenSchemaPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(event.GetDirection() && m_allSchemas->GetSelection() == wxNOT_FOUND) + { + wxMessageBox(_("Please select an item to move to next step."), _("No choice made"), wxICON_WARNING | wxOK, this); + event.Veto(); + } + else if(event.GetDirection()) + { + if(m_allSchemas->GetSelection() > 0) + { + wparent->OIDSelectedSchema = schemasHM[schemasNames[m_allSchemas->GetSelection()]]; + wparent->schemaName = schemasNames[m_allSchemas->GetSelection()]; + wxArrayString tables = ddImportDBUtils::getTablesNames(wparent->getConnection(), wparent->schemaName); + wparent->getDesign()->unMarkSchemaOnAll(); + wparent->getDesign()->markSchemaOn(tables); + } + else + { + wparent->OIDSelectedSchema = -1; + wparent->schemaName = _(""); + } + wparent->page4->populateGrid(); + } +} + +void SelGenSchemaPage::refreshSchemas(pgConn *connection) +{ + + schemasHM.clear(); + schemasNames.Clear(); + schemasNames.Add(wxT("Not schema selected")); + + // Search schemas and insert them + wxString restr = wxT(" WHERE ") + wxT("NOT ") + wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n") + wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (connection->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (connection->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + + pgSet *schemas = connection->ExecuteSet(sql); + wxTreeItemId parent; + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + schemasNames.Add(name); + schemasHM[name] = schemas->GetOid(wxT("oid")); + schemas->MoveNext(); + } + + delete schemas; + } +} + +// ----- SelGenSchemaPage Implementation + +ReportGridPage::ReportGridPage(wxWizard *parent, wxWizardPage *prev) + : wxWizardPage(parent) +{ + wparent = (ddGenerationWizard *) parent; + m_prev = prev; + m_next = NULL; + + // A top-level sizer + wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + + // Add a message + message = new wxStaticText(this, wxID_STATIC, _("Please check the choice for each table:"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(message); + topSizer->AddSpacer(10); + + reportGrid = new wxDDGrid(this, DDTABSGRID); + reportGrid->SetRowLabelSize(25); + reportGrid->CreateGrid(wparent->page2->countSelTables(), 2); + populateGrid(); + topSizer->Add(reportGrid, 1, wxEXPAND); + + // Add Event + this->Connect(DDTABSGRID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &ReportGridPage::OnCellLeftClick); +} + +ReportGridPage::~ReportGridPage() +{ + +} + +void ReportGridPage::populateGrid() +{ + reportGrid->ClearGrid(); + if(reportGrid->GetNumberRows() > 0) + reportGrid->DeleteRows(0, reportGrid->GetNumberRows()); + int row , max = wparent->page2->countSelTables(); + reportGrid->InsertRows(0, max); + reportGrid->SetColLabelValue(0, _("Tables")); + reportGrid->SetColLabelValue(1, _("Select an action")); + wxString strChoicesSimple[1] = {_("Create table")}; + wxString strChoicesAlter[4] = {_("Alter table"), _("Drop, then create"), _("Create table [conflict]"), wxT("No action")}; + + //Two Steps process first for tables that belongs to a schema (need alter table) + //Later for normal tables (just create table) + int useRow = 0; + for(row = 0; row < max; row++) + { + ddTableFigure *table = wparent->getDesign()->getTable(wparent->page2->getSelTableName(row)); + if(table != NULL && table->getBelongsToSchema()) + { + wxString labelString = wxString::Format(wxT("%i"), (row + 1)); + reportGrid->SetRowLabelValue(row, labelString); + reportGrid->SetReadOnly( row, 0, true); + reportGrid->SetCellValue( row, 0, wparent->page2->getSelTableName(row)); + reportGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + reportGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoicesAlter), strChoicesAlter)); + reportGrid->SetCellValue( row, 1, _("Alter table")); + reportGrid->SetCellBackgroundColour(row, 0, LIGHT_YELLOW); + reportGrid->SetCellBackgroundColour(row, 1, LIGHT_YELLOW); + useRow++; + } + else if(table == NULL) + { + wxMessageBox(_("Metadata of table to be generated not found at database designer model"), _("Error at generation process"), wxICON_ERROR | wxOK); + return; + } + } + + // Normal tables (just create table) + for(row = 0; row < max; row++) + { + ddTableFigure *table = wparent->getDesign()->getTable(wparent->page2->getSelTableName(row)); + if(table != NULL && !table->getBelongsToSchema()) + { + reportGrid->SetCellValue( row, 0, wparent->page2->getSelTableName(row)); + reportGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + reportGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoicesSimple), strChoicesSimple)); + reportGrid->SetCellValue( row, 1, _("Create table")); + useRow++; + } + else if(table == NULL) + { + wxMessageBox(_("Metadata of table to be generated not found at database designer model"), _("Error importing at generation process"), wxICON_ERROR | wxOK); + return; + } + + } + + reportGrid->AutoSizeColumns(); + reportGrid->Fit(); + +} + +void ReportGridPage::OnWizardPageChanging(wxWizardEvent &event) +{ + if(!event.GetDirection()) + { + //Reset tables after a warning + int answer = wxMessageBox(_("Going back to \"Select schema\" page will reinitialize all selections.\nDo you want to continue?"), _("Going back?"), wxYES_NO | wxCANCEL, this); + if (answer != wxYES) + { + event.Veto(); + } + } +} + +void ReportGridPage::OnCellLeftClick(wxGridEvent &event) +{ + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + reportGrid->ComboBoxEvent(event); + } + + event.Skip(); +} + + +// +// -- Special version of wxGrid to allow use of fast comboboxes and grid columns auto fit +// +wxDDGrid::wxDDGrid(wxWindow *parent, wxWindowID id): + wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_BESTWRAP, wxT("")), + m_selTemp(NULL), keepFit(1) +{ + // Initially all columns have s-factor=1 + for( unsigned i = 0; i < 10; ++i ) sf[i] = 1; + + Connect( wxEVT_SIZE, wxSizeEventHandler( wxDDGrid::OnSizeEvt) ); + // Adjust the default row height to be more compact + wxFont font = GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + SetColLabelSize(nHeight + 6); + SetRowLabelSize(35); +#ifdef __WXGTK__ + SetDefaultRowSize(nHeight + 8, TRUE); +#else + SetDefaultRowSize(nHeight + 4, TRUE); +#endif +} + +void wxDDGrid::ComboBoxEvent(wxGridEvent &event) +{ + + // This forces the cell to go into edit mode directly + this->m_waitForSlowClick = TRUE; + int row = event.GetRow(); + int col = event.GetCol(); + + this->SetGridCursor(row, col); + + // Store the click co-ordinates in the editor if possible + // if an editor has created a ClientData area, we presume it's + // a wxPoint and we store the click co-ordinates + wxGridCellEditor *pEditor = this->GetCellEditor(event.GetRow(), event.GetCol()); + wxPoint *pClickPoint = (wxPoint *)pEditor->GetClientData(); + if (pClickPoint) + { + *pClickPoint = this->ClientToScreen(event.GetPosition()); +#ifndef __WINDOWS__ + EnableCellEditControl(true); +#endif + } + + // hack to prevent selection from being lost when click combobox + if (this->IsInSelection(event.GetRow(), event.GetCol())) + { + this->m_selTemp = this->m_selection; + this->m_selection = NULL; + } + pEditor->DecRef(); +} + +void wxDDGrid::RevertSel() +{ + if (m_selTemp) + { + wxASSERT(m_selection == NULL); + m_selection = m_selTemp; + m_selTemp = NULL; + } +} + +void wxDDGrid::OnSizeEvt( wxSizeEvent &ev ) +{ + if( !StretchIt() ) ev.Skip(); +} + +int wxDDGrid::StretchIt() +{ + int new_width = GetClientSize().GetWidth() - GetRowLabelSize() - 10; + int fixedWidth = 0, numStretches = 0, numStretched = 0; + + for( int i = 0; i < GetNumberCols(); ++i ) + { + if( sf[i] == 0 ) fixedWidth += GetColSize(i); + else if( sf[i] < 0 ) + { + AutoSizeColumn(i, false); + fixedWidth += GetColSize(i); + } + else + { + numStretches += sf[i]; + numStretched += 1; + } + } + + // Now either we have space for normal layout or resort to wxGrid default behaviour + if( numStretched && ((fixedWidth + numStretched * 10) < new_width) ) + { + int stretchSpace = (new_width - fixedWidth) / numStretches; + //BeginBatch(); + int i, max = GetNumberCols(); + for(i = 0; i < max; ++i ) + if( sf[i] > 0 ) + SetColSize(i, stretchSpace * sf[i]); + //EndBatch(); + return 1; + } + return 0; +} diff --git a/dd/ddmodel/ddModelBrowser.cpp b/dd/ddmodel/ddModelBrowser.cpp new file mode 100644 index 0000000..f2d838e --- /dev/null +++ b/dd/ddmodel/ddModelBrowser.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddModelBrowser.cpp - Tables Tree of Database Designer. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "dd/ddmodel/ddModelBrowser.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddBrowserDataContainer.h" + +// Images +#include "images/table-sm.pngc" +#include "images/database-sm.pngc" + + +BEGIN_EVENT_TABLE(ddModelBrowser, wxTreeCtrl) + EVT_TREE_ITEM_ACTIVATED(DD_BROWSER, ddModelBrowser::OnItemActivated) + EVT_TREE_BEGIN_DRAG(DD_BROWSER, ddModelBrowser::OnBeginDrag) +END_EVENT_TABLE() + +ddModelBrowser::ddModelBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, ddDatabaseDesign *design) + : wxTreeCtrl(parent, id, pos, size, style) +{ + ownerDesign = design; + rootNode = (wxTreeItemId *)NULL; + createRoot(_("Database Design")); + + // Create normal images list of browser + // Remember to update enum gqbImages in ddModelBrowser.h if changing the images!! + imageList = new wxImageList(16, 16); + imageList->Add(*database_sm_png_ico); + imageList->Add(*table_sm_png_ico); + this->AssignImageList(imageList); +} + + +// Destructor +ddModelBrowser::~ddModelBrowser() +{ + this->DeleteAllItems(); // This remove and delete data inside tree's node +} + + +// Create root node +wxTreeItemId &ddModelBrowser::createRoot(wxString Name) +{ + rootNode = this->AddRoot(Name, DD_IMG_FIG_DATABASE, DD_IMG_FIG_DATABASE); + return rootNode; +} + + +void ddModelBrowser::refreshFromModel() +{ + + this->DeleteAllItems(); + createRoot(_("Database Design")); + + hdIteratorBase *iterator = ownerDesign->getEditor()->modelFiguresEnumerator(); + hdIFigure *tmpFigure; + ddTableFigure *table; + + while(iterator->HasNext()) + { + tmpFigure = (hdIFigure *)iterator->Next(); + if(tmpFigure->getKindId() == DDTABLEFIGURE) + { + table = (ddTableFigure *)tmpFigure; + this->AppendItem(rootNode, table->getTableName(), DD_IMG_FIG_TABLE, DD_IMG_FIG_TABLE, new ddBrowserDataContainer(table)); + } + } + delete iterator; + + this->Expand(rootNode); + this->SortChildren(rootNode); +} + +void ddModelBrowser::OnItemActivated(wxTreeEvent &event) +{ +} + +void ddModelBrowser::OnBeginDrag(wxTreeEvent &event) +{ + wxTreeItemId itemId = event.GetItem(); + + // Simplest solution, simulate DnD but actually don't do it + ddBrowserDataContainer *object = (ddBrowserDataContainer *) GetItemData(itemId); + + if(object != NULL && (object->getFigureKindId() == DDTABLEFIGURE)) + { + ddTableFigure *item = (ddTableFigure *) object->getFigure(); + wxString tableName = item->getTableName(); + wxTextDataObject textData(tableName); + wxDropSource dragSource(this); + dragSource.SetData(textData); + wxDragResult result = dragSource.DoDragDrop(wxDrag_CopyOnly); + if(result != wxDragCopy) + { + wxMessageBox(wxT("Invalid kind of data during drag and drop operation"), wxT("Drag and drop error"), wxICON_ERROR | wxOK); + } + } +} diff --git a/dd/ddmodel/module.mk b/dd/ddmodel/module.mk new file mode 100644 index 0000000..2438c46 --- /dev/null +++ b/dd/ddmodel/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/ddmodel/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dd/ddmodel/ddDatabaseDesign.cpp \ + dd/ddmodel/ddDrawingEditor.cpp \ + dd/ddmodel/ddDBReverseEnginering.cpp \ + dd/ddmodel/ddModelBrowser.cpp \ + dd/ddmodel/ddGenerationWizard.cpp \ + dd/ddmodel/ddDrawingView.cpp \ + dd/ddmodel/ddBrowserDataContainer.cpp + +EXTRA_DIST += \ + dd/ddmodel/module.mk diff --git a/dd/module.mk b/dd/module.mk new file mode 100644 index 0000000..d4387ae --- /dev/null +++ b/dd/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dd/ Makefile fragment +# +####################################################################### + +include dd/dditems/module.mk +include dd/ddmodel/module.mk + + +EXTRA_DIST += \ + dd/module.mk diff --git a/debugger/ctlMessageWindow.cpp b/debugger/ctlMessageWindow.cpp new file mode 100644 index 0000000..5e9482b --- /dev/null +++ b/debugger/ctlMessageWindow.cpp @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMessageWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "debugger/ctlMessageWindow.h" + +IMPLEMENT_CLASS(ctlMessageWindow, wxTextCtrl) + +BEGIN_EVENT_TABLE(ctlMessageWindow, wxTextCtrl) + EVT_TIMER(wxID_ANY, ctlMessageWindow::OnTimer) +END_EVENT_TABLE() + +//////////////////////////////////////////////////////////////////////////////// +// ctlMessageWindow constructor +// +// Initialize the grid control and clear it out.... +// + +ctlMessageWindow::ctlMessageWindow(wxWindow *parent, wxWindowID id) + : wxTextCtrl(parent, wxID_ANY, wxT(""), wxPoint(0, 0), wxSize(0, 0), + wxTE_MULTILINE | wxTE_READONLY) +{ + SetFont(settings->GetSQLFont()); + m_timer.SetOwner(this); +} + +//////////////////////////////////////////////////////////////////////////////// +// AddMessage() +// +// Adds the message in the 'DBMS Messages' window. +// + +void ctlMessageWindow::AddMessage(wxString message) +{ + m_mutex.Lock(); + m_currMsg += message + wxT("\n"); + m_mutex.Unlock(); + + if (!m_timer.IsRunning()) + m_timer.Start(100, true); +} + +void ctlMessageWindow::OnTimer(wxTimerEvent &ev) +{ + m_mutex.Lock(); + AppendText(m_currMsg); + m_currMsg = wxEmptyString; + m_mutex.Unlock(); +} + +//////////////////////////////////////////////////////////////////////////////// +// delMessage() +// +// Removes the given message from the 'DBMS Messages' window. +// + +void ctlMessageWindow::DelMessage(const char *name) +{ + SetValue(wxT("")); +} + + +wxString ctlMessageWindow::GetMessage(int row) +{ + return(GetValue()); +} diff --git a/debugger/ctlResultGrid.cpp b/debugger/ctlResultGrid.cpp new file mode 100644 index 0000000..7f12677 --- /dev/null +++ b/debugger/ctlResultGrid.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlResultGrid.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "debugger/ctlResultGrid.h" + +IMPLEMENT_CLASS( ctlResultGrid, wxGrid ) + +//////////////////////////////////////////////////////////////////////////////// +// ctlResultGrid constructor +// +// We use a ctlResultGrid to display the result set from a query. This class +// is a minor extension of the wxGrid class. + +ctlResultGrid::ctlResultGrid( wxWindow *parent, wxWindowID id ) + : wxGrid( parent, id ) +{ + SetFont(settings->GetSystemFont()); + + CreateGrid( 0, 0 ); +} + +//////////////////////////////////////////////////////////////////////////////// +// fillGrid() +// +// Given a result set handle, this function copies the values in that result +// set into the grid. + +void ctlResultGrid::FillResult(pgSet *set) +{ + // Clear out the old results (if any) and resize + // grid to match the result set + if( GetNumberRows()) + DeleteRows( 0, GetNumberRows()); + if( GetNumberCols()) + DeleteCols( 0, GetNumberCols()); + + if (!set) + return; + + int rowCount = set->NumRows(); + int colCount = set->NumCols(); + + // If this PGresult represents a non-query command + // (like an INSERT), there won't be any columns in + // the result set - just return + if( colCount == 0 ) + return; + + // Disable repaints to we don't flicker too much + + BeginBatch(); + + AppendRows(rowCount); + AppendCols(colCount); + + EnableEditing(false); + + // Copy the column names from the result set into the column headers + int row = 0, + col; + for(col = 0; col < colCount; ++col) + SetColLabelValue(col, set->ColName(col)); + wxGridCellAttr* pAttr = new wxGridCellAttr; + pAttr->SetBackgroundColour(wxColour(128,128,128)); + //SetDefaultCellBackgroundColour(wxColour(128,128,128)); + + // Now copy each value from the result set into the grid + while(!set->Eof()) + { + for(col = 0; col < colCount; ++col) + { + if(set->IsNull(col)) + SetCellValue(row, col, wxT("")); + else + SetCellValue(row, col, set->GetVal(col)); + } + row++; + set->MoveNext(); + } + + // Resize each column to fit its content + AutoSizeColumns(false); + + // Enable repaints + EndBatch(); +} diff --git a/debugger/ctlStackWindow.cpp b/debugger/ctlStackWindow.cpp new file mode 100644 index 0000000..423ef36 --- /dev/null +++ b/debugger/ctlStackWindow.cpp @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlStackWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "debugger/ctlStackWindow.h" + +WX_DEFINE_LIST(dbgStackFrameList); + +IMPLEMENT_CLASS(ctlStackWindow, wxListBox) + +//////////////////////////////////////////////////////////////////////////////// +// ctlStackWindow constructor +// +// Initialize the grid control and clear it out.... +// + +ctlStackWindow::ctlStackWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ) + : wxListBox(parent , id, pos, size, 0, NULL, style | wxLB_HSCROLL | wxLB_NEEDED_SB ) +{ + SetFont(settings->GetSystemFont()); +} + +//////////////////////////////////////////////////////////////////////////////// +// ClearStack() +// +// Remove all stack frames from the display +// +void ctlStackWindow::ClearStack() +{ + Set(0, NULL); +} + +//////////////////////////////////////////////////////////////////////////////// +// SetStack() +// +// Add an array of stack frames to the display +// +void ctlStackWindow::SetStack(const dbgStackFrameList &stacks, int selected) +{ + Set(0, NULL); + + for (dbgStackFrameList::Node *node = stacks.GetFirst(); node; + node = node->GetNext()) + { + dbgStackFrame *frame = node->GetData(); + Append(frame->GetDescription(), (wxClientData *)frame); + } + if (selected != -1) + { + SetSelection(selected); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// SelectFrame() +// +// Select the frame based on the input function and package +// +void ctlStackWindow::SelectFrame(const wxString &pkg, const wxString &func) +{ + int cnt = GetCount(); + + for (int idx = 0; idx < cnt; idx++) + { + dbgStackFrame *frame = (dbgStackFrame *)GetClientObject(idx); + + if (frame && frame->GetFunction() == func && frame->GetPackage() == pkg) + { + SetSelection(idx); + + return; + } + } +} diff --git a/debugger/ctlTabWindow.cpp b/debugger/ctlTabWindow.cpp new file mode 100644 index 0000000..19f3967 --- /dev/null +++ b/debugger/ctlTabWindow.cpp @@ -0,0 +1,175 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTabWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "ctl/ctlAuiNotebook.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/dbgConst.h" + + +IMPLEMENT_CLASS(ctlTabWindow, wxWindow) + +//////////////////////////////////////////////////////////////////////////////// +// ctlTabWindow constructor +// +// This constructor creates a new notebook (a tab control) and clears out the +// rest of the data members. +// +ctlTabWindow::ctlTabWindow(wxWindow *parent, wxWindowID id, const wxPoint &pos, + const wxSize &size, long style, const wxString &name) + : ctlAuiNotebook(parent, id, pos, size, style), + m_resultWindow(NULL), + m_varWindow(NULL), + m_pkgVarWindow(NULL), + m_stackWindow(NULL), + m_paramWindow(NULL), + m_messageWindow(NULL) +{ + SetFont(settings->GetSystemFont()); + m_tabMap = new wsTabHash(); +} + +void ctlTabWindow::SelectTab(wxWindowID id) +{ + wsTabHash::iterator result = m_tabMap->find(id); + + if (result != m_tabMap->end()) + { + SetSelection(result->second); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// GetResultWindow() +// +// This function returns a pointer to our child result window (m_resultWindow) +// and creates that window when we first need it. +// +ctlResultGrid *ctlTabWindow::GetResultWindow() +{ + if (m_resultWindow == 0) + { + // We don't have a result window yet - go ahead and create one + + m_resultWindow = new ctlResultGrid(this, -1); + AddPage(m_resultWindow, _("Results"), true); + } + + return m_resultWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetVarWindow() +// +// This function returns a pointer to our child 'local-variables' window +// (m_varWindow) and creates that window when we first need it. +// +ctlVarWindow *ctlTabWindow::GetVarWindow(bool _create) +{ + if ((m_varWindow == NULL) && _create) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_VARGRID] = GetPageCount(); + + m_varWindow = new ctlVarWindow(this, ID_VARGRID); + AddPage(m_varWindow, _("Local Variables"), true); + } + + return m_varWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetPkgVarWindow() +// +// This function returns a pointer to our child 'package-variables' window +// (m_varWindow) and creates that window when we first need it. +// +ctlVarWindow *ctlTabWindow::GetPkgVarWindow(bool create) +{ + if ((m_pkgVarWindow == NULL) && create) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_PKGVARGRID] = GetPageCount(); + + m_pkgVarWindow = new ctlVarWindow(this, ID_PKGVARGRID); + AddPage(m_pkgVarWindow, _("Package Variables"), true); + } + + return m_pkgVarWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetParamWindow() +// +// This function returns a pointer to our child 'parameters' window +// (m_paramWindow) and creates that window when we first need it. +// +ctlVarWindow *ctlTabWindow::GetParamWindow(bool create) +{ + if ((m_paramWindow == NULL) && create) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_PARAMGRID] = GetPageCount(); + + m_paramWindow = new ctlVarWindow(this, ID_PARAMGRID); + AddPage(m_paramWindow, _("Parameters"), true); + } + + return m_paramWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetMessageWindow() +// +// This function returns a pointer to our child 'messages' window +// (m_messageWindow) and creates that window when we first need it. +// +ctlMessageWindow *ctlTabWindow::GetMessageWindow() +{ + if (m_messageWindow == 0) + { + // We don't have a variable window yet - go ahead and create one + + (*m_tabMap)[ID_MSG_PAGE] = GetPageCount(); + + m_messageWindow = new ctlMessageWindow(this, ID_MSG_PAGE); + AddPage(m_messageWindow, _("DBMS Messages"), true); + } + return m_messageWindow; +} + +//////////////////////////////////////////////////////////////////////////////// +// GetStackWindow() +// +// This function returns a pointer to our child stack-trace window +// (m_stackWindow) and creates that window when we first need it. +// +ctlStackWindow *ctlTabWindow::GetStackWindow() +{ + if (m_stackWindow == 0) + { + // We don't have a stack-trace window yet - go ahead and create one + m_stackWindow = new ctlStackWindow(this, -1); + AddPage(m_stackWindow, _("Stack"), true); + } + + return m_stackWindow; +} + diff --git a/debugger/ctlVarWindow.cpp b/debugger/ctlVarWindow.cpp new file mode 100644 index 0000000..1865b78 --- /dev/null +++ b/debugger/ctlVarWindow.cpp @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlVarWindow.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "debugger/ctlVarWindow.h" + +IMPLEMENT_CLASS(ctlVarWindow, wxGrid) + +//////////////////////////////////////////////////////////////////////////////// +// ctlVarWindow constructor +// +// Initialize the grid control and clear it out.... +// +ctlVarWindow::ctlVarWindow(wxWindow *parent, wxWindowID id) + : wxGrid(parent, id), + m_cells(NULL), + m_nameFont(GetDefaultCellFont()) +{ + SetFont(settings->GetSystemFont()); + + // Create the grid control + CreateGrid(0, 0); + SetRowLabelSize(0); // Turn off the row labels + + // Set up three columns: name, value, and data type + AppendCols(3); + SetColLabelValue(COL_NAME, _("Name")); + SetColLabelValue(COL_TYPE, _("Type")); + SetColLabelValue(COL_VALUE, _("Value")); + + EnableDragGridSize(true); + + // EDB wants to hide certain PL variables. To do that, we + // keep a hash of hidden names and a hash of hidden types... + m_hiddenNames.insert(wxT("found")); + m_hiddenNames.insert(wxT("rowcount")); + m_hiddenNames.insert(wxT("sqlcode")); + m_hiddenNames.insert(wxT("sqlerrm")); + m_hiddenNames.insert(wxT("_found")); + m_hiddenNames.insert(wxT("_rowcount")); + m_hiddenNames.insert(wxT("sqlstate")); + + m_hiddenTypes.insert(wxT("refcursor")); + +} + +//////////////////////////////////////////////////////////////////////////////// +// AddVar() +// +// Adds (or updates) the given variable in the 'local variables' window. If +// we find a variabled named 'name' in the window, we simply update the value, +// otherwise, we create a new entry in the grid +// +void ctlVarWindow::AddVar(wxString name, wxString value, wxString type, bool readOnly) +{ + // If this is a 'hidden' variable, just ignore it + + if (m_hiddenNames.find(name) != m_hiddenNames.end()) + return; + + if (m_hiddenTypes.find(type) != m_hiddenTypes.end()) + return; + + if (m_cells == NULL) + { + // This is the first variable we're adding to this grid, + // layout the grid and set the column headers. + + m_cells = new wsCellHash; + } + + // Try to find an existing grid cell for this variable... + wxString key(name); + + wsCellHash::iterator cell = m_cells->find(key); + + if (cell == m_cells->end()) + { + // Can't find this variable in the grid, go ahead and add it + + gridCell newCell; + + newCell.m_row = m_cells->size(); + newCell.m_type = type; + newCell.m_value = value; + + AppendRows(1); + + SetRowLabelValue(newCell.m_row, key); + + SetCellValue(newCell.m_row, COL_NAME, key); + SetCellValue(newCell.m_row, COL_TYPE, type); + SetCellValue(newCell.m_row, COL_VALUE, value); + + SetCellFont(newCell.m_row, COL_NAME, m_nameFont); + + SetReadOnly(newCell.m_row, COL_NAME, true); + SetReadOnly(newCell.m_row, COL_TYPE, true); + SetReadOnly(newCell.m_row, COL_VALUE, readOnly); + + (*m_cells)[key] = newCell; + } + else + { + // This variable is already in the grid, update the value + // and hilite it so the user knows that it has changed. + + cell->second.m_value = value; + + if (GetCellValue(cell->second.m_row, COL_VALUE).IsSameAs(value)) + SetCellTextColour(cell->second.m_row, COL_VALUE, *wxBLACK); + else + SetCellTextColour(cell->second.m_row, COL_VALUE, *wxRED); + + SetCellValue(cell->second.m_row, COL_VALUE, value); + + // FIXME: why is this part conditional? + // FIXME: why do we need this code? can the type ever change? + + if (GetCellValue(cell->second.m_row, COL_TYPE) == wxT("")) + { + SetCellValue(cell->second.m_row, COL_TYPE, type); + } + } + + // AutoSizeColumns(false); +} + +//////////////////////////////////////////////////////////////////////////////// +// delVar() +// +// Removes the given variable from the 'local variables' window. +// + +void ctlVarWindow::DelVar(wxString name) +{ + if (name.IsEmpty()) + { + delete m_cells; + m_cells = NULL; + + if (GetNumberRows()) + DeleteRows(0, GetNumberRows()); + } + else + { + for (int row = 0; row < GetNumberRows(); row++) + { + if (GetCellValue(row, COL_NAME) == name) + { + DeleteRows(row, 1); + break; + } + } + } +} + + +wxString ctlVarWindow::GetVarName(int row) +{ + return(GetCellValue(row, COL_NAME)); + +} + +wxString ctlVarWindow::GetVarValue(int row) +{ + return(GetCellValue(row, COL_VALUE)); +} diff --git a/debugger/dbgBreakPoint.cpp b/debugger/dbgBreakPoint.cpp new file mode 100644 index 0000000..a611350 --- /dev/null +++ b/debugger/dbgBreakPoint.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgBreakPoint.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "debugger/dbgBreakPoint.h" + +WX_DEFINE_LIST( dbgBreakPointList ); + + diff --git a/debugger/dbgController.cpp b/debugger/dbgController.cpp new file mode 100644 index 0000000..d9f6d37 --- /dev/null +++ b/debugger/dbgController.cpp @@ -0,0 +1,913 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgController.cpp - debugger controller +// - Flow and data controller for the debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +#include "ctl/ctlAuiNotebook.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "schema/pgObject.h" +#include "schema/pgTrigger.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "debugger/dlgDirectDbg.h" + +#include "utils/pgDefs.h" + +#include + +#define LOG_DBG_MUTEX_LOCKING 0 + +#if LOG_DBG_MUTEX_LOCKING + +#define LOCKMUTEX(m) \ + wxPrintf(wxT("Mutex locking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Lock(); \ + wxPrintf(wxT("Mutex locked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#define UNLOCKMUTEX(m) \ + wxPrintf(wxT("Mutex unlocking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Unlock(); \ + wxPrintf(wxT("Mutex unlocked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#else + +#define LOCKMUTEX(m) \ + m.Lock(); + +#define UNLOCKMUTEX(m) \ + m.Unlock(); + +#endif + +const wxString dbgController::ms_cmdDebugSPLV1( + wxT("SELECT edb_oid_debug(%lu, %lu)")); +const wxString dbgController::ms_cmdDebugSPLV2( + wxT("SELECT edb_oid_debug(%lu)")); + +const wxString dbgController::ms_cmdDebugPLPGSQLV1( + wxT("SELECT plpgsql_oid_debug(%lu, %lu)")); +const wxString dbgController::ms_cmdDebugPLPGSQLV2( + wxT("SELECT plpgsql_oid_debug(%lu)")); + +const wxString dbgController::ms_cmdAttachToPort( + wxT("SELECT * FROM pldbg_attach_to_port(%s)")); +const wxString dbgController::ms_cmdWaitForBreakpointV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_wait_for_breakpoint($1::INTEGER) p")); +const wxString dbgController::ms_cmdWaitForBreakpointV2( + wxT("SELECT\n") + wxT(" p.func AS func, p.targetName AS targetName, \n") + wxT(" p.linenumber AS linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_wait_for_breakpoint($1::INTEGER) p")); + +const wxString dbgController::ms_cmdGetVars( + wxT("SELECT\n") + wxT(" name, varClass, value,\n") + wxT(" pg_catalog.format_type(dtype, NULL) as dtype, isconst\n") + wxT("FROM pldbg_get_variables(%s) ORDER BY varClass")); +const wxString dbgController::ms_cmdGetStack( + wxT("SELECT * FROM pldbg_get_stack(%s) ORDER BY level")); +const wxString dbgController::ms_cmdGetBreakpoints( + wxT("SELECT * FROM pldbg_get_breakpoints(%s)")); + +const wxString dbgController::ms_cmdStepOverV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_step_over($1::INTEGER) p")); +const wxString dbgController::ms_cmdStepOverV2( + wxT("SELECT\n") + wxT(" p.func, p.targetName, p.linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_step_over($1::INTEGER) p")); +const wxString dbgController::ms_cmdStepIntoV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_step_into($1::INTEGER) p")); +const wxString dbgController::ms_cmdStepIntoV2( + wxT("SELECT\n") + wxT(" p.func, p.targetName, p.linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_step_into($1::INTEGER) p")); +const wxString dbgController::ms_cmdContinueV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber, pldbg_get_source($1::INTEGER, p.pkg, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_continue($1::INTEGER) p")); +const wxString dbgController::ms_cmdContinueV2( + wxT("SELECT\n") + wxT(" p.func, p.targetName, p.linenumber,\n") + wxT(" pldbg_get_source($1::INTEGER, p.func) AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_continue($1::INTEGER) p")); + +const wxString dbgController::ms_cmdSetBreakpointV1( + wxT("SELECT * FROM pldbg_set_breakpoint(%s,%s,%s,%d)")); +const wxString dbgController::ms_cmdSetBreakpointV2( + wxT("SELECT * FROM pldbg_set_breakpoint(%s,%s,%d)")); + +const wxString dbgController::ms_cmdClearBreakpointV1( + wxT("SELECT * FROM pldbg_drop_breakpoint(%s,%s,%s,%d)")); +const wxString dbgController::ms_cmdClearBreakpointV2( + wxT("SELECT * FROM pldbg_drop_breakpoint(%s,%s,%d)")); + +const wxString dbgController::ms_cmdSelectFrameV1( + wxT("SELECT\n") + wxT(" p.pkg AS pkg, p.func AS func, p.targetName AS targetName,\n") + wxT(" p.linenumber AS linenumber,\n") + wxT(" CASE WHEN p.func <> 0 THEN pldbg_get_source($1::INTEGER, p.func, p.pkg) ELSE '' END AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func AND s.pkg = p.pkg) AS args\n") + wxT("FROM pldbg_select_frame($1::INTEGER, $2::INTEGER) p")); +const wxString dbgController::ms_cmdSelectFrameV2( + wxT("SELECT\n") + wxT(" p.func AS func, p.targetName AS targetName, p.linenumber AS linenumber,\n") + wxT(" CASE WHEN p.func <> 0 THEN pldbg_get_source($1::INTEGER, p.func) ELSE '' END AS src,\n") + wxT(" (SELECT\n") + wxT(" s.args\n") + wxT(" FROM pldbg_get_stack($1::INTEGER) s\n") + wxT(" WHERE s.func = p.func) AS args\n") + wxT("FROM pldbg_select_frame($1::INTEGER, $2::INTEGER) p")); + +const wxString dbgController::ms_cmdDepositValue( + wxT("SELECT * FROM pldbg_deposit_value(%s,%s,%d,%s)")); +const wxString dbgController::ms_cmdAbortTarget( + wxT("SELECT * FROM pldbg_abort_target(%s)")); + +const wxString dbgController::ms_cmdAddBreakpointEDB( + wxT("SELECT * FROM pldbg_set_global_breakpoint(%s, %s, %s, -1, %s)")); +const wxString dbgController::ms_cmdAddBreakpointPG( + wxT("SELECT * FROM pldbg_set_global_breakpoint(%s, %s, -1, %s)")); + +const wxString dbgController::ms_cmdCreateListener( + wxT("SELECT * from pldbg_create_listener()")); +const wxString dbgController::ms_cmdWaitForTarget( + wxT("SELECT * FROM pldbg_wait_for_target(%s)")); + +const wxString dbgController::ms_cmdIsBackendRunning( + wxT("SELECT COUNT(*) FROM (SELECT pg_catalog.pg_stat_get_backend_idset() AS bid) AS s WHERE pg_catalog.pg_stat_get_backend_pid(s.bid) = '%d'::integer;")); + +dbgController::dbgController(frmMain *main, pgObject *_obj, bool _directDebugging) + : m_ver(DEBUGGER_UNKNOWN_API), m_sessionType(DBG_SESSION_TYPE_UNKNOWN), + m_lineOffset(1), m_terminated(false), m_frm(NULL), m_dbgConn(NULL), + m_dbgThread(NULL), m_execConnThread(NULL), m_model(NULL), + m_isStopping(false) +{ + // Create the connection for listening the debugger port and doing the + // debugging operations. + // i.e. + // - step in, step over, continue, fetch stack-frames, fetch variables, etc. + m_dbgConn = _obj->GetConnection()->Duplicate( + wxT("pgAdmin Debugger - Global Listener")); + + if (!m_dbgConn->IsAlive()) + { + wxLogError(_("Couldn't create a connection for the debugger")); + + delete m_dbgConn; + m_dbgConn = NULL; + + throw (std::runtime_error("Couldn't create a connection for the debugger")); + } + + m_dbgConn->ExecuteVoid(wxT("SET client_min_messages TO error")); + + if (!m_dbgConn->BackendMinimumVersion(9, 1)) + m_lineOffset = 0; + + OID target; + if (_obj->GetMetaType() == PGM_TRIGGER) + { + target = ((pgTrigger *)_obj)->GetFunctionOid(); + } + else + { + target = _obj->GetOid(); + } + + // Fetch the target information + try + { + m_model = new dbgModel((Oid)target, m_dbgConn); + } + catch (const std::runtime_error &error) + { + // Catching the runtime error thrown by dbgTargetInfo, so that we can + // delete the created connection object and then rethrow it + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + // Rethrow the error + throw error; + } + + if (m_model->GetTarget()->HasVariadic() && + m_model->GetTarget()->GetLanguage() == wxT("edbspl")) + { + wxLogError( + _("An 'edbspl' target with a variadic argument is not supported by this version of pgAdmin debugger!")); + + throw (std::runtime_error( + "Unsupported target specified!")); + } + + // Fetch the debugger version + wxString strCntProxyInfo = m_dbgConn->ExecuteScalar( + wxT("SELECT COUNT(*) FROM pg_catalog.pg_proc p\n") + wxT(" LEFT JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid\n") + wxT("WHERE n.nspname = ANY(current_schemas(false))\n") + wxT(" AND p.proname = 'pldbg_get_proxy_info'"), false); + + if(!strCntProxyInfo.IsEmpty() && m_dbgConn->GetLastResultStatus() == PGRES_TUPLES_OK) + { + if (strCntProxyInfo == wxT("0")) + { + m_ver = DEBUGGER_V1_API; + } + wxString strVer = m_dbgConn->ExecuteScalar( + wxT("SELECT proxyapiver FROM pldbg_get_proxy_info()"), false); + + if (!strVer.IsEmpty() && m_dbgConn->GetLastResultStatus() == PGRES_TUPLES_OK) + { + long ver; + strVer.ToLong(&ver); + + switch (ver) + { + case DEBUGGER_V3_API: + case DEBUGGER_V2_API: + m_ver = (DebuggerApiVersion)ver; + break; + default: + wxLogError( + wxString::Format( + _("pgAdmin does not support this version of the debugger plugin (v:%ld)"), + ver)); + + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + delete m_model; + m_model = NULL; + + throw (std::runtime_error( + "Unsupported version of debugger plugin installed")); + break; + } + } + else + { + wxLogError( + wxString::Format( + _("Couldn't determine the debugger plugin version.\n%s"), + m_dbgConn->GetLastError().c_str())); + + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + delete m_model; + m_model = NULL; + + throw (std::runtime_error( + "Couldn't determine the debugger version (function execution error).")); + } + } + else + { + wxLogError( + wxString::Format( + _("Couldn't determine the debugger plugin version.\n%s"), + m_dbgConn->GetLastError().c_str())); + + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + + delete m_model; + m_model = NULL; + + throw (std::runtime_error( + "Couldn't determine the debugger version (function check)")); + } + + // Store debugging type + if (_directDebugging) + { + m_sessionType = DBG_SESSION_TYPE_DIRECT; + m_frm = new frmDebugger( + main, this, wxString::Format( + _("Debugger - %s"), + m_model->GetTarget()->GetQualifiedName().c_str())); + } + else + { + m_sessionType = DBG_SESSION_TYPE_INCONTEXT; + m_frm = new frmDebugger( + main, this, _("Global Debugger")); + } + + if (!Start()) + m_frm->EnableToolsAndMenus(false); +} + + +dbgController::~dbgController() +{ + if (m_dbgConn) + { + m_dbgConn->Close(); + delete m_dbgConn; + m_dbgConn = NULL; + } + + if (m_model) + { + delete m_model; + m_model = NULL; + } +} + + +bool dbgController::Start() +{ + m_frm->EnableToolsAndMenus(false); + m_frm->Show(true); + + if(m_frm->GetTabWindow()->GetPageCount()) // Clearing message window, result grid, and re-setting the status message during the module re-exeuction. + { + m_frm->GetMessageWindow()->Clear(); + m_frm->GetResultWindow()->ClearGrid(); + m_frm->LaunchWaitingDialog(_("Initializing...")); + } + + if (!m_dbgConn->IsAlive()) + { + if (!m_dbgConn->Reconnect()) + { + // Unable to re-establish the connection for debugger + return false; + } + } + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread = new pgQueryThread( + m_dbgConn, this, &(dbgController::NoticeHandler), this); + m_dbgThread->SetEventOnCancellation(false); + + if (m_dbgThread->Create() != wxTHREAD_NO_ERROR) + { + delete m_dbgThread; + m_dbgThread = NULL; + UNLOCKMUTEX(m_dbgThreadLock); + + return false; + } + + m_dbgThread->Run(); + UNLOCKMUTEX(m_dbgThreadLock); + + wxTheApp->Yield(true); + + m_terminated = false; + m_isStopping = false; + + if (m_sessionType == DBG_SESSION_TYPE_DIRECT) + { + pgConn *conn = m_dbgConn->Duplicate( + wxT("pgAdmin Debugger - Target Invoker")); + + if (m_model->GetTarget()->RequireUserInput()) + { + dlgDirectDbg dlg(m_frm, this, conn); + + if (dlg.ShowModal() != wxID_OK) + { + // Close the connection for the debugging listener + m_dbgConn->Close(); + + // Close the connection for the debugging executor + conn->Close(); + delete conn; + conn = NULL; + + // Declare that execution has been cancelled + m_terminated = true; + m_frm->EnableToolsAndMenus(false); + m_frm->CloseProgressBar(); + + return false; + } + } + + m_execConnThread = new pgQueryThread( + conn, this, &(dbgController::NoticeHandler), this); + m_execConnThread->SetEventOnCancellation(false); + + if (m_execConnThread->Create() != wxTHREAD_NO_ERROR) + { + delete m_execConnThread; + m_execConnThread = NULL; + + conn->Close(); + delete conn; + conn = NULL; + + Stop(); + + return false; + } + return ExecuteTarget(); + } + else if (m_sessionType == DBG_SESSION_TYPE_INCONTEXT) + { + // TODO:: Ask for the target session and different targets + dbgBreakPointList &breakpoints = m_model->GetBreakPoints(); + + WX_CLEAR_ARRAY(breakpoints); + + dbgTargetInfo *target = m_model->GetTarget(); + breakpoints.Append(new dbgBreakPoint( + wxString::Format(wxT("%lu"), target->GetOid()), + wxString::Format(wxT("%lu"), target->GetPkgOid()))); + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdCreateListener, NULL, (long)RESULT_ID_LISTENER_CREATED); + UNLOCKMUTEX(m_dbgThreadLock); + } + + return true; +} + + +bool dbgController::ExecuteTarget() +{ + dbgTargetInfo *target = m_model->GetTarget(); + wxString strDebugCmdPkgInitializer, strDebugCmdTarget; + + if (m_ver <= DEBUGGER_V2_API) + { + if (target->GetLanguage() == wxT("edbspl")) + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugSPLV1, target->GetPkgOid(), target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format( + ms_cmdDebugSPLV1, target->GetPkgOid(), target->GetOid()); + } + else + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugPLPGSQLV1, target->GetPkgOid(), target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format( + ms_cmdDebugPLPGSQLV1, target->GetPkgOid(), target->GetOid()); + } + } + else + { + if (target->GetLanguage() == wxT("edbspl")) + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugSPLV2, target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format(ms_cmdDebugSPLV2, target->GetOid()); + } + else + { + strDebugCmdPkgInitializer = wxString::Format( + ms_cmdDebugPLPGSQLV2, target->GetPkgInitOid()); + strDebugCmdTarget = wxString::Format(ms_cmdDebugPLPGSQLV2, target->GetOid()); + } + } + if (target->DebugPackageConstructor()) + { + m_execConnThread->AddQuery(strDebugCmdPkgInitializer); + } + m_execConnThread->AddQuery(strDebugCmdTarget); + + if (target->AddForExecution(m_execConnThread)) + { + // Start the execution thread + m_execConnThread->Run(); + } + else + { + wxLogError(_("Couldn't determine how to execute the selected target.")); + + Stop(); + + return false; + } + return true; +} + + +void dbgController::NoticeHandler(void *_arg, const char *_msg) +{ + dbgController *controller = (dbgController *)_arg; + + if (controller->m_terminated) + return; + + wxMBConv *conv = controller->m_dbgConn->GetConv(); + + wxString strMsg(_msg, *conv); + + if (strMsg.EndsWith(wxT("\n"))) + { + strMsg.RemoveLast(); + } + + if (strMsg.Find(wxT("PLDBGBREAK")) != wxNOT_FOUND) + { + // NOTICE: PLDBGBREAK 1 + wxStringTokenizer tokens(strMsg, wxT(":\n")); + + tokens.GetNextToken(); // NOTICE: + tokens.GetNextToken(); // PLDBGBREAK + + controller->m_model->GetPort() = tokens.GetNextToken(); // + + wxCommandEvent btnEvt(wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_START_DEBUGGING); + controller->AddPendingEvent(btnEvt); + } + else + { + wxCommandEvent btnEvt(wxEVT_COMMAND_BUTTON_CLICKED, MENU_ID_NOTICE_RECEIVED); + + btnEvt.SetString(strMsg); + controller->AddPendingEvent(btnEvt); + } +} + + +// Debugging actions (called from the frmDebugger) +void dbgController::ClearBreakpoint(int _lineNo) +{ + if (m_terminated || m_isStopping) + return; + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdClearBreakpointV1, m_model->GetSession().c_str(), + m_model->GetDisplayedPackage().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, (long) RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdClearBreakpointV2, m_model->GetSession().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } +} + + +void dbgController::SetBreakpoint(int _lineNo) +{ + if (m_terminated || m_isStopping) + return; + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV1, m_model->GetSession().c_str(), + m_model->GetDisplayedPackage().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV2, m_model->GetSession().c_str(), + m_model->GetDisplayedFunction().c_str(), _lineNo + 1), + NULL, RESULT_ID_NEW_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } +} + + +void dbgController::Countinue() +{ + if (m_terminated || m_isStopping) + return; + + pgParamsArray *params = new pgParamsArray; + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdContinueV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdContinueV2, params, RESULT_ID_BREAKPOINT); + } + + // Do not allow any action at this time + m_frm->EnableToolsAndMenus(false); +} + + +void dbgController::StepOver() +{ + if (m_terminated || m_isStopping) + return; + + pgParamsArray *params = new pgParamsArray; + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepOverV1, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepOverV2, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + + // Do not allow any action at this time + m_frm->EnableToolsAndMenus(false); +} + + +void dbgController::StepInto() +{ + if (m_terminated || m_isStopping) + return; + + pgParamsArray *params = new pgParamsArray; + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + + if (m_ver <= DEBUGGER_V2_API) + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepIntoV1, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery(ms_cmdStepIntoV2, params, RESULT_ID_BREAKPOINT); + UNLOCKMUTEX(m_dbgThreadLock); + } + + // Do not allow any action at this time + m_frm->EnableToolsAndMenus(false); +} + + +bool dbgController::Stop() +{ + if (m_terminated) + return true; + + if (m_isStopping) + return false; + + LOCKMUTEX(m_dbgThreadLock); + + m_frm->EnableToolsAndMenus(false); + m_frm->LaunchWaitingDialog(_("Waiting for target stop execution...")); + m_isStopping = true; + + switch(m_sessionType) + { + case DBG_SESSION_TYPE_DIRECT: + { + // We must send the abort target command to the executor + // session + if (m_execConnThread) + { + if (m_execConnThread->IsRunning()) + { + // Ask the direct debugging executor to not to handle any of the error or + // result any more. + m_execConnThread->CancelExecution(); + if (m_dbgConn->GetStatus() != CONNECTION_BAD && m_model->GetSession() != wxEmptyString) + { + // And then, we will ask the backend to abort the target, so that the + // target backend will wait for any commands from debugging proxy. + pgConn *conn = m_dbgThread->GetConn(); + pgSet *set = conn->ExecuteSet( + wxString::Format(ms_cmdAbortTarget, m_model->GetSession().c_str())); + + if (set) + delete set; + + } + while (m_execConnThread && m_execConnThread->IsRunning()) + { + wxTheApp->Yield(true); + wxMilliSleep(3); + } + if (m_execConnThread) + m_execConnThread->Wait(); + } + if (m_execConnThread) + { + // We also need to deallocate the momory for the connection + pgConn *conn = m_execConnThread->GetConn(); + + delete m_execConnThread; + m_execConnThread = NULL; + + conn->Close(); + delete conn; + conn = NULL; + } + } + } + break; + default: + break; + } + + if (m_dbgThread) + { + if (m_dbgThread->IsRunning()) + { + m_dbgThread->CancelExecution(); + m_dbgThread->Wait(); + } + + delete m_dbgThread; + m_dbgThread = NULL; + } + + // Disconnect the debugger connection + m_dbgConn->Close(); + m_frm->CloseProgressBar(); + m_terminated = true; + m_isStopping = false; + + UNLOCKMUTEX(m_dbgThreadLock); + + return true; +} + + +void dbgController::DepositValue(const wxString &_name, const wxString &_val) +{ + if (m_terminated || m_isStopping) + return; + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdDepositValue, m_model->GetSession().c_str(), + m_dbgConn->qtDbString(_name).c_str(), -1, + m_dbgConn->qtDbString(_val).c_str()), + NULL, RESULT_ID_DEPOSIT_VALUE); + UNLOCKMUTEX(m_dbgThreadLock); +} + + +bool dbgController::SelectFrame(int _frameNo) +{ + LOCKMUTEX(m_dbgThreadLock); + if (m_terminated || m_isStopping) + { + UNLOCKMUTEX(m_dbgThreadLock); + return true; + } + + ctlStackWindow *stackWin = m_frm->GetStackWindow(); + dbgStackFrame *frame = (dbgStackFrame *)stackWin->GetClientObject(_frameNo); + + if (!frame || frame->GetFunction() == wxT("0")) + { + UNLOCKMUTEX(m_dbgThreadLock); + wxMessageBox( + _("Cannot fetch information about the anonymous block!"), + _("Invalid Stack"), wxICON_ERROR | wxOK); + return false; + } + + wxString strLevel = frame->GetLevel(); + pgParamsArray *params = new pgParamsArray; + + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + params->Add(new pgParam(PGOID_TYPE_INT4, &strLevel)); + + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdSelectFrameV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdSelectFrameV2, params, RESULT_ID_BREAKPOINT); + } + UNLOCKMUTEX(m_dbgThreadLock); + + return true; +} + +void dbgController::UpdateBreakpoints() +{ + if (m_terminated || m_isStopping) + return; + + LOCKMUTEX(m_dbgThreadLock); + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetBreakpoints, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_BREAKPOINTS); + UNLOCKMUTEX(m_dbgThreadLock); +} + + +// Closing Debugger +bool dbgController::CloseDebugger() +{ + if (Stop()) + { + if (m_dbgConn) + { + delete m_dbgConn; + + m_dbgConn = NULL; + } + + return true; + } + return false; +} + +dbgTargetInfo *dbgController::GetTargetInfo() +{ + return m_model->GetTarget(); +} diff --git a/debugger/dbgEvents.cpp b/debugger/dbgEvents.cpp new file mode 100644 index 0000000..ed62c4d --- /dev/null +++ b/debugger/dbgEvents.cpp @@ -0,0 +1,974 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgEvents.cpp - debugger controller events +// - This files contains the functions related to the event handling of the +// debugger controller. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include "ctl/ctlAuiNotebook.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "schema/pgObject.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "debugger/dlgDirectDbg.h" +#include "utils/pgDefs.h" + +#define LOG_DBG_MUTEX_LOCKING 0 + +#if LOG_DBG_MUTEX_LOCKING + +#define LOCKMUTEX(m) \ + wxPrintf(wxT("Mutex locking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Lock(); \ + wxPrintf(wxT("Mutex locked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#define UNLOCKMUTEX(m) \ + wxPrintf(wxT("Mutex unlocking @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); \ + m.Unlock(); \ + wxPrintf(wxT("Mutex unlocked @ %s:%d\n"), wxString::FromAscii(__WXFUNCTION__).c_str(), __LINE__); + +#else + +#define LOCKMUTEX(m) \ + m.Lock(); + +#define UNLOCKMUTEX(m) \ + m.Unlock(); + +#endif + +BEGIN_EVENT_TABLE(dbgController, wxEvtHandler) + EVT_BUTTON(MENU_ID_NOTICE_RECEIVED, dbgController::OnNoticeReceived) + EVT_BUTTON(MENU_ID_START_DEBUGGING, dbgController::OnStartDebugging) + + EVT_PGQUERYRESULT(RESULT_ID_DIRECT_TARGET_COMPLETE, dbgController::ResultTargetComplete) + EVT_PGQUERYRESULT(RESULT_ID_ATTACH_TO_PORT, dbgController::ResultPortAttach) + EVT_PGQUERYRESULT(RESULT_ID_LISTENER_CREATED, dbgController::ResultListenerCreated) + + EVT_PGQUERYRESULT(RESULT_ID_TARGET_READY, dbgController::ResultTargetReady) + + EVT_PGQUERYRESULT(RESULT_ID_DEL_BREAKPOINT, dbgController::ResultDeletedBreakpoint) + + EVT_PGQUERYRESULT(RESULT_ID_BREAKPOINT, dbgController::ResultBreakpoint) + EVT_PGQUERYRESULT(RESULT_ID_NEW_BREAKPOINT, dbgController::ResultNewBreakpoint) + EVT_PGQUERYRESULT(RESULT_ID_NEW_BREAKPOINT_WAIT, dbgController::ResultNewBreakpointWait) + + EVT_PGQUERYRESULT(RESULT_ID_GET_VARS, dbgController::ResultVarList) + EVT_PGQUERYRESULT(RESULT_ID_GET_STACK, dbgController::ResultStack) + EVT_PGQUERYRESULT(RESULT_ID_GET_BREAKPOINTS, dbgController::ResultBreakpoints) + + EVT_PGQUERYRESULT(RESULT_ID_DEPOSIT_VALUE, dbgController::ResultDepositValue) +END_EVENT_TABLE() + + +// Event functions +void dbgController::OnNoticeReceived(wxCommandEvent &_ev) +{ + m_frm->GetMessageWindow()->AddMessage(_ev.GetString()); + m_frm->GetTabWindow()->SelectTab(ID_MSG_PAGE); +} + + +void dbgController::OnStartDebugging(wxCommandEvent &_ev) +{ + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + m_dbgThread->AddQuery( + wxString::Format(ms_cmdAttachToPort, m_model->GetPort().c_str()), + NULL, RESULT_ID_ATTACH_TO_PORT); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultTargetComplete(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + m_frm->EnableToolsAndMenus(false); + m_terminated = true; + m_frm->SetStatusText(_("Debugging Completed")); + m_frm->CloseProgressBar(); + + wxTheApp->Yield(true); + + if (m_execConnThread) + { + switch(qry->ReturnCode()) + { + case pgQueryResultEvent::PGQ_CONN_LOST: + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target terminated due to connection loss.\n"), + m_execConnThread->GetId())); + break; + // This is very unlikely, unless we made mistake creating the query + case pgQueryResultEvent::PGQ_STRING_INVALID: + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target terminated due to empty query string.\n"), + m_execConnThread->GetId())); + break; + case pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_SEND_QUERY: + case pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT: + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target terminated due to execution error (%d).\n"), + m_execConnThread->GetId(), qry->ReturnCode())); + break; + case pgQueryResultEvent::PGQ_EXECUTION_CANCELLED: + m_frm->SetStatusText(_("Debugging Cancelled")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging target cancelled.\n"), + m_execConnThread->GetId())); + break; + case pgQueryResultEvent::PGQ_RESULT_ERROR: + { + wxString strErr = qry->GetErrorMessage(); + + m_frm->SetStatusText(_("Execution completed with an error.")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Function/Procedure terminated with an error.\n%s"), + m_execConnThread->GetId(), strErr.c_str())); + + m_frm->GetMessageWindow()->AddMessage(qry->GetMessage()); + m_frm->GetMessageWindow()->SetFocus(); + } + + break; + case PGRES_FATAL_ERROR: + case PGRES_NONFATAL_ERROR: + case PGRES_BAD_RESPONSE: + { + wxString strErr = qry->GetErrorMessage(); + m_frm->SetStatusText(_("Execution completed with an error.")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Function/Procedure terminated with an error.\n%s"), + m_execConnThread->GetId(), strErr.c_str())); + + m_frm->GetMessageWindow()->AddMessage(qry->GetMessage()); + m_frm->GetMessageWindow()->SetFocus(); + } + + break; + case PGRES_TUPLES_OK: + { + m_frm->SetStatusText(_("Execution completed.")); + pgSet *set = qry->ResultSet(); + m_frm->GetMessageWindow()->AddMessage(set->GetCommandStatus()); + + m_frm->GetResultWindow()->FillResult(set); + } + + break; + default: + m_frm->SetStatusText(_("Execution completed.")); + wxLogInfo( + wxString::Format( + _("Debugger(%ld): Execution of the debugging function/procedure completed\n"), + m_execConnThread->GetId())); + + m_frm->GetMessageWindow()->AddMessage(qry->GetMessage()); + m_frm->GetMessageWindow()->SetFocus(); + + break; + } + + if (m_execConnThread->IsRunning()) + { + m_execConnThread->CancelExecution(); + m_execConnThread->Wait(); + } + + pgConn *execConn = m_execConnThread->GetConn(); + delete m_execConnThread; + + m_execConnThread = NULL; + execConn->Close(); + delete execConn; + } + + LOCKMUTEX(m_dbgThreadLock); + pgQueryThread *oldDebugThread = m_dbgThread; + m_dbgThread = NULL; + UNLOCKMUTEX(m_dbgThreadLock); + + if (oldDebugThread) + { + oldDebugThread->CancelExecution(); + oldDebugThread->Wait(); + + delete oldDebugThread; + } + + // We won't keep the connection open, we will open it only when required + if (m_dbgConn) + m_dbgConn->Close(); + + if (m_frm) + m_frm->EnableToolsAndMenus(false); +} + + +void dbgController::ResultPortAttach(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error attaching the proxy session."))) + { + return; + } + + if (qry->ReturnCode() != PGRES_TUPLES_OK) + { + Stop(); + + return; + } + + m_frm->EnableToolsAndMenus(false); + + wxString strSession = qry->ResultSet()->GetVal(0); + m_model->GetSession() = strSession; + + pgParamsArray *params = new pgParamsArray; + + params->Add(new pgParam(PGOID_TYPE_INT4, &strSession)); + + LOCKMUTEX(m_dbgThreadLock); + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV2, params, RESULT_ID_BREAKPOINT); + } + qry->Release(); + + // Now create any breakpoints that the user created in last execution. We + // start by asking the server to resolve the breakpoint name into an OID (or, + // a pair of OID's if the target is defined in a package). As each + // (targetInof) result arrives, we add a break-point at the resulting OID. + dbgBreakPointList breakpoints = m_model->GetBreakPoints(); + + for (dbgBreakPointList::Node *node = breakpoints.GetFirst(); node; + node = node->GetNext()) + { + dbgBreakPoint *breakpoint = node->GetData(); + /* + * In EnterpriseDB versions <= 9.1 the + * pldbg_set_global_breakpoint function took five arguments, + * the 2nd argument being the package's OID, if any. Starting + * with 9.2, the package OID argument is gone, and the function + * takes four arguments like the community version has always + * done. + */ + if (m_dbgConn->GetIsEdb() && !m_dbgConn->BackendMinimumVersion(9, 2)) + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV1, m_model->GetSession().c_str(), + breakpoint->GetPackageOid().c_str(), + breakpoint->GetFunctionOid().c_str(), + breakpoint->GetLineNo()), + NULL, RESULT_ID_NEW_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdSetBreakpointV2, m_model->GetSession().c_str(), + breakpoint->GetFunctionOid().c_str(), + breakpoint->GetLineNo()), + NULL, RESULT_ID_NEW_BREAKPOINT); + } + } + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +bool dbgController::HandleQuery(pgBatchQuery *_qry, const wxString &_err) +{ + if (!_qry) + return false; + + LOCKMUTEX(m_dbgThreadLock); + + // It is possible that we found one error, while running the previous query + // and, called Stop function from it, because of an error found. + // That may have released the debugger thread + // + // In this case, we should exit this flow gracefully instead showing any + // error + if (!m_dbgThread || !m_dbgThread->IsRunning()) + { + UNLOCKMUTEX(m_dbgThreadLock); + return false; + } + + switch(_qry->ReturnCode()) + { + case pgQueryResultEvent::PGQ_CONN_LOST: + // This is very unlikely, unless we made mistake creating the query + case pgQueryResultEvent::PGQ_STRING_INVALID: + case PGRES_EMPTY_QUERY: + case pgQueryResultEvent::PGQ_ERROR_PREPARE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_EXECUTE_CALLABLE: + case pgQueryResultEvent::PGQ_ERROR_SEND_QUERY: + case pgQueryResultEvent::PGQ_ERROR_CONSUME_INPUT: + case pgQueryResultEvent::PGQ_RESULT_ERROR: + case PGRES_BAD_RESPONSE: + case PGRES_NONFATAL_ERROR: + case PGRES_FATAL_ERROR: + break; + + // This is unlikely, we do not generate an event, when execution is + // cancelled + case pgQueryResultEvent::PGQ_EXECUTION_CANCELLED: + break; + case PGRES_COMMAND_OK: + case PGRES_TUPLES_OK: + UNLOCKMUTEX(m_dbgThreadLock); + return true; + // Hmm - where did it come from? + // We never call a function, which results into these results + // Anyway - we will return true as we have the result + case PGRES_COPY_IN: + case PGRES_COPY_OUT: + UNLOCKMUTEX(m_dbgThreadLock); + return true; + } + + m_frm->EnableToolsAndMenus(false); + wxTheApp->Yield(true); + + if (!m_dbgConn->IsAlive()) + { + UNLOCKMUTEX(m_dbgThreadLock); + wxMessageBox( + _("Connection to the database server lost, debugging cannot continue!"), + _("Connection Lost"), wxICON_ERROR | wxOK); + } + else + { + wxString strErr; + if (!_err.IsEmpty()) + strErr = _err + wxT("\n\n"); + strErr += _qry->GetErrorMessage(); + UNLOCKMUTEX(m_dbgThreadLock); + + if (_qry->ReturnCode() == PGRES_FATAL_ERROR) + { + // We will start start listening for new in-context session, if the + // current session is closed. On which, the query/target was + // running. + // + // This allows us to have the same behaviour as the old one. + // + if (m_sessionType == DBG_SESSION_TYPE_INCONTEXT && m_currTargetPid != wxT("")) + { + // Let's check if the target pid has stopped or exited after + // successful debugging, let's move on and wait for the next + // target to hit. + wxString isTargetRunning = m_dbgConn->ExecuteScalar(wxString::Format(ms_cmdIsBackendRunning, m_currTargetPid.c_str())); + + if (isTargetRunning == wxT("0")) + { + // Reset the current backend-pid of the target + m_currTargetPid = wxT(""); + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdWaitForTarget, m_model->GetSession().c_str()), + NULL, RESULT_ID_TARGET_READY); + + m_frm->LaunchWaitingDialog(); + + return false; + } + } + else + { + wxMessageBox(_("The calling connection was closed or lost."), _("Connection Lost"), wxICON_ERROR | wxOK); + } + } + else + { + wxMessageBox(strErr, _("Execution Error"), wxICON_ERROR | wxOK); + } + + wxLogQuietError(strErr); + } + + Stop(); + m_terminated = true; + + m_frm->SetStatusText(_("Debugging aborting...")); + + return false; +} + + +void dbgController::ResultBreakpoint(pgQueryResultEvent &_ev) +{ + if (m_frm) + m_frm->CloseProgressBar(); + + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, wxEmptyString)) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + wxString func, + pkg = wxT("0"); + + pgSet *set = qry->ResultSet(); + + if (set->HasColumn(wxT("pkg"))) + { + pkg = set->GetVal(wxT("pkg")); + } + func = set->GetVal(wxT("func")); + + m_model->GetFocusedPackage() = pkg; + m_model->GetFocusedFunction() = func; + + int lineNo = (int)(set->GetLong(wxT("linenumber")) - 1); + + if (lineNo < 0) + lineNo = -1; + else + lineNo -= m_lineOffset; + m_model->GetCurrLineNo() = lineNo; + + wxString strSource = set->GetVal(wxT("src")); + + if (strSource.IsEmpty()) + strSource = _(""); + + dbgCachedStack src(pkg, func, set->GetVal(wxT("targetname")), + set->GetVal(wxT("args")), strSource); + + m_model->AddSource(func, src); + m_frm->DisplaySource(src); + + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetStack, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_STACK); + + m_frm->EnableToolsAndMenus(true); + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultVarList(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error fetching variables."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + ctlVarWindow *paramWin = NULL, *pkgVarWin = NULL, *varWin = NULL; + pgSet *set = qry->ResultSet(); + + while (!set->Eof()) + { + switch((char)(set->GetVal(wxT("varclass"))[0])) + { + case 'A': + { + if (paramWin == NULL) + paramWin = m_frm->GetParamWindow(true); + + paramWin->AddVar( + set->GetVal(wxT("name")), + set->GetVal(wxT("value")), + set->GetVal(wxT("dtype")), + set->GetBool(wxT("isconst"))); + + break; + } + case 'P': + { + if (pkgVarWin == NULL) + pkgVarWin = m_frm->GetPkgVarWindow(true); + + pkgVarWin->AddVar( + set->GetVal(wxT("name")), + set->GetVal(wxT("value")), + set->GetVal(wxT("dtype")), + set->GetBool(wxT("isconst"))); + + break; + } + default: + { + if (varWin == NULL) + varWin = m_frm->GetVarWindow(true); + + varWin->AddVar( + set->GetVal(wxT("name")), + set->GetVal(wxT("value")), + set->GetVal(wxT("dtype")), + set->GetBool(wxT("isconst"))); + + break; + } + } + set->MoveNext(); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultStack(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error fetching the call stack."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + dbgStackFrameList stacks; + ctlStackWindow *stackWin = m_frm->GetStackWindow(); + + // Fetched the stack, now fetch the break-points + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetBreakpoints, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_BREAKPOINTS); + + stackWin->ClearStack(); + + int selected = 0, + levelCol = set->ColNumber(wxT("level")), + pkgCol = set->HasColumn(wxT("pkg")) ? set->ColNumber(wxT("level")) : -1, + funCol = set->ColNumber(wxT("func")), + targetCol = set->ColNumber(wxT("targetname")), + argsCol = set->ColNumber(wxT("args")), + lineCol = set->ColNumber(wxT("linenumber")); + + while (!set->Eof()) + { + // The result set contains one tuple per frame: + // package, function, linenumber, args + dbgStackFrame *frame = new dbgStackFrame( + set->GetVal(levelCol), + pkgCol != -1 ? set->GetVal(wxT("pkg")) : wxT("0"), + set->GetVal(funCol), + wxString::Format( + wxT("%s(%s)@%s"), + set->GetVal(targetCol).c_str(), + set->GetVal(argsCol).c_str(), + set->GetVal(lineCol).c_str())); + + // Select this one in the stack window + if (frame->GetFunction() == m_model->GetDisplayedFunction() && + frame->GetPackage() == m_model->GetDisplayedPackage()) + { + selected = set->CurrentPos() - 1; + } + + stacks.Append(frame); + set->MoveNext(); + } + stackWin->SetStack(stacks, selected); + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultBreakpoints(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Error fetching breakpoints."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + int pkgCol = -1, funcCol = set->ColNumber(wxT("func")), + lineCol = set->ColNumber(wxT("linenumber")); + + if (set->HasColumn(wxT("pkg"))) + { + pkgCol = set->ColNumber(wxT("pkg")); + } + + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetVars, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_VARS); + + m_frm->ClearBreakpointMarkers(); + dbgBreakPointList &breakpoints = m_model->GetBreakPoints(); + WX_CLEAR_ARRAY(breakpoints); + + while (!set->Eof()) + { + // The result set contains one tuple per breakpoint: + // pkg, func, linenumber, target + // or, + // func, linenumber, target + wxString pkg = (pkgCol == -1) ? wxT("0") : set->GetVal(pkgCol); + wxString func = set->GetVal(funcCol); + int lineNumber = (int)set->GetLong(lineCol); + + // Save this break-points in break-point list + breakpoints.Append(new dbgBreakPoint(func, pkg, lineNumber)); + + // Mark the break-point in the viewer + if (pkg == m_model->GetDisplayedPackage() && + func == m_model->GetDisplayedFunction()) + { + m_frm->MarkBreakpoint(lineNumber - 1); + } + set->MoveNext(); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultNewBreakpoint(pgQueryResultEvent &_ev) +{ + // We will wait for the last new break-point, which will be handled in + // dbgController::ResultNewBreakpointWait function + if (!HandleQuery(_ev.GetQuery(), _("Could not create the breakpoint."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + // Release the result-set + _ev.GetQuery()->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultNewBreakpointWait(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Could not create the breakpoint."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = _ev.GetQuery()->ResultSet(); + m_frm->EnableToolsAndMenus(false); + + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdWaitForTarget, m_model->GetSession().c_str()), + NULL, RESULT_ID_TARGET_READY); + + m_frm->LaunchWaitingDialog(); + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultDeletedBreakpoint(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Could not drop the breakpoint."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + if (set->GetBool(0)) + { + m_frm->SetStatusText(_("Breakpoint dropped")); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +//////////////////////////////////////////////////////////////////////////////// +// ResultDepositValue() +// +// This event handler is called when the proxy completes a 'deposit' operation +// (in response to an earlier call to pldbg_deposit_value()). +// +// We schedule a refresh of our variable window(s) for the next idle period. +// +void dbgController::ResultDepositValue(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, _("Could not deposit the new value."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + if (set->GetBool(0)) + { + m_frm->SetStatusText(_("Value changed")); + + m_dbgThread->AddQuery( + wxString::Format(ms_cmdGetVars, m_model->GetSession().c_str()), + NULL, RESULT_ID_GET_VARS); + } + else + { + wxLogError(_("Could not deposit the new value.")); + } + } + + // Release the result-set + qry->Release(); + } + UNLOCKMUTEX(m_dbgThreadLock); +} + + +void dbgController::ResultListenerCreated(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (!HandleQuery(qry, + _("Could not create the proxy listener for in-process debugging."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + if (qry->ReturnCode() == PGRES_TUPLES_OK) + { + pgSet *set = qry->ResultSet(); + + // We now have a global listener and a session handle. Grab the session + // handle (we'll need it for just about everything else). + m_model->GetSession() = set->GetVal(0); + + // Release the result-set + qry->Release(); + + // Now create any global breakpoints that the user requested. We start + // by asking the server to resolve the breakpoint name into an OID (or, + // a pair of OID's if the target is defined in a package). As each + // (targetInof) result arrives, we add a break-point at the resulting + // OID. + unsigned int idx = 1; + long resultId; + + dbgBreakPointList breakpoints = m_model->GetBreakPoints(); + for (dbgBreakPointList::Node *node = breakpoints.GetFirst(); node; + node = node->GetNext(), ++idx) + { + dbgBreakPoint *breakpoint = node->GetData(); + + if(idx < breakpoints.GetCount()) + { + resultId = RESULT_ID_NEW_BREAKPOINT; + } + else + { + resultId = RESULT_ID_NEW_BREAKPOINT_WAIT; + } + + /* + * In EnterpriseDB versions <= 9.1 the + * pldbg_set_global_breakpoint function took five arguments, + * the 2nd argument being the package's OID, if any. Starting + * with 9.2, the package OID argument is gone, and the function + * takes four arguments like the community version has always + * done. + */ + if (m_dbgConn->GetIsEdb() && !m_dbgConn->BackendMinimumVersion(9, 2)) + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdAddBreakpointEDB, m_model->GetSession().c_str(), + breakpoint->GetPackageOid().c_str(), + breakpoint->GetFunctionOid().c_str(), + m_model->GetTargetPid().c_str()), + NULL, resultId); + } + else + { + m_dbgThread->AddQuery( + wxString::Format( + ms_cmdAddBreakpointPG, m_model->GetSession().c_str(), + breakpoint->GetFunctionOid().c_str(), + m_model->GetTargetPid().c_str()), + NULL, resultId); + } + } + UNLOCKMUTEX(m_dbgThreadLock); + } + else + { + // Release the result-set + qry->Release(); + UNLOCKMUTEX(m_dbgThreadLock); + } + } + else + { + UNLOCKMUTEX(m_dbgThreadLock); + } +} + + +void dbgController::ResultTargetReady(pgQueryResultEvent &_ev) +{ + pgBatchQuery *qry = _ev.GetQuery(); + + if (m_frm) + { + m_frm->CloseProgressBar(); + m_frm->EnableToolsAndMenus(false); + } + + if (!HandleQuery(qry, + _("Error fetching target information."))) + return; + + LOCKMUTEX(m_dbgThreadLock); + // Do not bother to process the result, if the debugger thread is not + // running or not exists + if (m_dbgThread && m_dbgThread->IsRunning()) + { + bool goAhead = false; + goAhead = (qry->ReturnCode() == PGRES_TUPLES_OK); + pgSet *set = qry->ResultSet(); + + // Save the current running target pid + m_currTargetPid = set->GetVal(0); + + // Next line release the actual result-set + set = NULL; + + // Release the result-set + qry->Release(); + UNLOCKMUTEX(m_dbgThreadLock); + + pgParamsArray *params = new pgParamsArray; + + params->Add(new pgParam(PGOID_TYPE_INT4, &(m_model->GetSession()))); + if (m_ver <= DEBUGGER_V2_API) + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV1, params, RESULT_ID_BREAKPOINT); + } + else + { + m_dbgThread->AddQuery(ms_cmdWaitForBreakpointV2, params, RESULT_ID_BREAKPOINT); + } + } + else + { + UNLOCKMUTEX(m_dbgThreadLock); + } +} diff --git a/debugger/dbgModel.cpp b/debugger/dbgModel.cpp new file mode 100644 index 0000000..a1d97ae --- /dev/null +++ b/debugger/dbgModel.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgModel.cpp - debugger model +// - It contains the data and information related the debugging session +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "debugger/dbgModel.h" + + +dbgModel::dbgModel(Oid _target, pgConn *_conn) + : m_target(NULL), m_currLineNo(-1), m_targetPid(wxT("NULL")) +{ + m_target = new dbgTargetInfo(_target, _conn); +} + + +bool dbgModel::GetSource(const wxString &_funcOid, dbgCachedStack *_cached) +{ + dbgSourceHash::iterator match = m_sourceMap.find(_funcOid); + + if (match == m_sourceMap.end()) + return false; + else + { + if (_cached) + { + *_cached = match->second; + } + + return true; + } +} + + +void dbgModel::ClearCachedSource() +{ + m_sourceMap.clear(); + + // Put a dummy entry for invalid function OID to the cache. This is + // displayed at least for inline code blocks, as we currently have no way + // to fetch the source for those + m_sourceMap[wxT("0")] = dbgCachedStack(wxT("0"), wxT("0"), wxT(""), wxT(""), _("")); +} + + +void dbgModel::AddSource(const wxString &_funcOid, const dbgCachedStack &_source) +{ + m_sourceMap[_funcOid] = _source; +} diff --git a/debugger/dbgTargetInfo.cpp b/debugger/dbgTargetInfo.cpp new file mode 100644 index 0000000..3b33cf0 --- /dev/null +++ b/debugger/dbgTargetInfo.cpp @@ -0,0 +1,647 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgTargetInfo.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" +#include "utils/pgDefs.h" + +// wxWindows headers +#include + +// App headers +#include "debugger/dbgTargetInfo.h" +#include "debugger/dbgConst.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" + +#include + +//////////////////////////////////////////////////////////////////////////////// +// dbgTargetInfo constructor +// +// This class implements a container that holds information necessary to invoke +// a debugger target (a function or procedure). +// +// When the constructor is called, it sends a query to the server to retreive: +// the OID of the target, +// the name of the target, +// the name of the schema in which the target is defined +// the name of the language in which the target is defined +// the number of arguments expected by the target +// the argument names +// the argument types +// the argument modes (IN, OUT, or INOUT) +// the target type (function or procedure) +// +// This class offers a number of (inline) member functions that you can call +// to extract the above information after it's been queried from the server. + +dbgTargetInfo::dbgTargetInfo(Oid _target, pgConn *_conn) + : m_args(NULL), m_inputParamCnt(0), m_hasVariadic(false) +{ + wxMBConv *conv = _conn->GetConv(); + wxString targetQuery = + wxT("SELECT\n") + wxT(" p.proname AS name, l.lanname, p.proretset, p.prorettype, y.typname AS rettype,\n") + wxT(" CASE WHEN proallargtypes IS NOT NULL THEN\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(\n") + wxT(" p.proallargtypes, 1)) AS s(i)), ',')\n") + wxT(" ELSE\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" pg_catalog.format_type(p.proargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(\n") + wxT(" p.proargtypes, 1)) AS s(i)), ',')\n") + wxT(" END AS proargtypenames,\n") + wxT(" CASE WHEN proallargtypes IS NOT NULL THEN\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT proallargtypes[s.i] FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(proallargtypes, 1)) s(i)), ',')\n") + wxT(" ELSE\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT proargtypes[s.i] FROM\n") + wxT(" pg_catalog.generate_series(0, pg_catalog.array_upper(proargtypes, 1)) s(i)), ',')\n") + wxT(" END AS proargtypes,\n") + wxT(" pg_catalog.array_to_string(p.proargnames, ',') AS proargnames,\n") + wxT(" pg_catalog.array_to_string(proargmodes, ',') AS proargmodes,\n"); + + if (_conn->GetIsEdb()) + { + targetQuery += + wxT(" CASE WHEN n.nspparent <> 0 THEN n.oid ELSE 0 END AS pkg,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN n.nspname ELSE '' END AS pkgname,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN (SELECT oid FROM pg_proc WHERE pronamespace=n.oid AND proname='cons') ELSE 0 END AS pkgconsoid,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN g.oid ELSE n.oid END AS schema,\n") + wxT(" CASE WHEN n.nspparent <> 0 THEN g.nspname ELSE n.nspname END AS schemaname,\n") + wxT(" NOT (l.lanname = 'edbspl' AND protype = '1') AS isfunc,\n"); + } + else + { + targetQuery += + wxT(" 0 AS pkg,\n") + wxT(" '' AS pkgname,\n") + wxT(" 0 AS pkgconsoid,\n") + wxT(" n.oid AS schema,\n") + wxT(" n.nspname AS schemaname,\n") + wxT(" true AS isfunc,\n"); + } + if (_conn->BackendMinimumVersion(8, 4)) + { + targetQuery += wxT(" pg_catalog.pg_get_function_identity_arguments(p.oid) AS signature,"); + } + else if (_conn->BackendMinimumVersion(8, 1)) + { + targetQuery += + wxT(" CASE\n") + wxT(" WHEN proallargtypes IS NOT NULL THEN pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" CASE\n") + wxT(" WHEN p.proargmodes[s.i] = 'i' THEN ''\n") + wxT(" WHEN p.proargmodes[s.i] = 'o' THEN 'OUT '\n") + wxT(" WHEN p.proargmodes[s.i] = 'b' THEN 'INOUT '\n") + wxT(" WHEN p.proargmodes[s.i] = 'v' THEN 'VARIADIC '\n") + wxT(" END ||\n") + wxT(" CASE WHEN COALESCE(p.proargnames[s.i], '') = '' THEN ''\n") + wxT(" ELSE p.proargnames[s.i] || ' '\n") + wxT(" END ||\n") + wxT(" pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proallargtypes, 1)) AS s(i)\n") + wxT(" WHERE p.proargmodes[s.i] != 't'\n") + wxT(" ), ', ')\n") + wxT(" ELSE\n") + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" CASE\n") + wxT(" WHEN COALESCE(p.proargnames[s.i+1], '') = '' THEN ''\n") + wxT(" ELSE p.proargnames[s.i+1] || ' '\n") + wxT(" END ||\n") + wxT(" pg_catalog.format_type(p.proargtypes[s.i], NULL)\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n") + wxT(" ), ', ')\n") + wxT(" END AS signature,\n"); + } + else + { + targetQuery += wxT(" '' AS signature,"); + } + + if (_conn->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + // EnterpriseDB 8.3R2 + if(!_conn->BackendMinimumVersion(8, 4)) + { + targetQuery += + wxT(" pg_catalog.array_to_string(ARRAY(\n") + wxT(" SELECT\n") + wxT(" CASE WHEN p.proargdefvals[x.j] != '-' THEN\n") + wxT(" pg_catalog.pg_get_expr(p.proargdefvals[x.j], 'pg_catalog.pg_class'::regclass, true)\n") + wxT(" ELSE '-' END\n") + wxT(" FROM\n") + wxT(" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proargdefvals, 1)) AS x(j)\n") + wxT(" ), ',') AS proargdefaults,\n") + wxT(" CASE WHEN p.proargdefvals IS NULL THEN '0'\n") + wxT(" ELSE pg_catalog.array_upper(p.proargdefvals, 1)::text END AS pronargdefaults\n"); + } + else + { + targetQuery += + wxT(" pg_catalog.pg_get_expr(p.proargdefaults, 'pg_catalog.pg_class'::regclass, false) AS proargdefaults,\n") + wxT(" p.pronargdefaults\n"); + } + } + else + { + targetQuery += + wxT(" '' AS proargdefaults, 0 AS pronargdefaults\n"); + } + targetQuery += + wxT("FROM\n") + wxT(" pg_catalog.pg_proc p\n") + wxT(" LEFT JOIN pg_catalog.pg_namespace n ON p.pronamespace = n.oid\n") + wxT(" LEFT JOIN pg_catalog.pg_language l ON p.prolang = l.oid\n") + wxT(" LEFT JOIN pg_catalog.pg_type y ON p.prorettype = y.oid\n"); + if(_conn->GetIsEdb()) + { + targetQuery += + wxT(" LEFT JOIN pg_catalog.pg_namespace g ON n.nspparent = g.oid\n"); + } + targetQuery += + wxString::Format(wxT("WHERE p.oid = %ld"), (long)_target); + + pgSet *set = _conn->ExecuteSet(targetQuery); + + if (conv == NULL) + { + conv = &wxConvLibc; + } + + if (!set || _conn->GetLastResultStatus() != PGRES_TUPLES_OK) + { + if (set) + delete set; + wxLogError(_("Could not fetch information about the debugger target.\n") + + _conn->GetLastError()); + + throw (std::runtime_error( + (const char *)(_conn->GetLastError().c_str()))); + } + + if (set->NumRows() == 0) + { + delete set; + + wxLogError(_("Can't find the debugging target")); + throw (std::runtime_error("Can't find target!")); + } + + m_oid = _target; + m_name = set->GetVal(wxT("name")); + m_schema = set->GetVal(wxT("schemaname")); + m_package = set->GetVal(wxT("pkgname")); + m_language = set->GetVal(wxT("lanname")); + m_returnType = set->GetVal(wxT("rettype")); + m_funcSignature = set->GetVal(wxT("signature")); + m_isFunction = set->GetBool(wxT("isfunc")); + m_returnsSet = set->GetBool(wxT("proretset")); + m_pkgOid = set->GetOid(wxT("pkg")); + m_pkgInitOid = set->GetOid(wxT("pkgconsoid")); + m_schemaOid = set->GetOid(wxT("schema")); + m_fqName = qtIdent(m_schema) + wxT(".") + + (m_pkgOid == 0 ? wxT("") : (qtIdent(m_package) + wxT("."))) + qtIdent(m_name); + + wxArrayString argModes, argNames, argTypes, argTypeOids, argDefVals, + argBaseTypes; + + // Fetch Argument Modes (if available) + if (!set->IsNull(set->ColNumber(wxT("proargmodes")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargmodes")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argModes); + } + // Fetch Argument Names (if available) + if (!set->IsNull(set->ColNumber(wxT("proargnames")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargnames")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argNames); + } + // Fetch Argument Type-Names (if available) + if (!set->IsNull(set->ColNumber(wxT("proargtypenames")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargtypenames")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argTypes); + } + // Fetch Argument Type-Names (if available) + if (!set->IsNull(set->ColNumber(wxT("proargtypes")))) + { + wxString tmp; + tmp = set->GetVal(wxT("proargtypes")); + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argTypeOids); + } + + size_t nArgDefs = (size_t)set->GetLong(wxT("pronargdefaults")); + // Fetch Argument Default Values (if available) + if (!set->IsNull(set->ColNumber(wxT("proargdefaults"))) && nArgDefs != 0) + { + wxString tmp; + tmp = set->GetVal(wxT("proargdefaults")); + + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp, argDefVals); + } + + wxString argName, argDefVal; + short argMode; + Oid argTypeOid; + size_t argCnt = argTypes.Count(); + + // This function/procedure does not take any arguments + if (argCnt == 0) + { + return; + } + + size_t idx = 0; + m_args = new pgDbgArgs(); + + for (; idx < argCnt; idx++) + { + argTypeOid = (Oid)strtoul(argTypeOids[idx].mb_str(wxConvUTF8), 0, 10); + argDefVal = wxEmptyString; + + argName = wxEmptyString; + if (idx < argNames.Count()) + argName = argNames[idx]; + + if (argName.IsEmpty()) + argName.Printf( wxT( "dbgParam%d" ), (idx + 1)); + + if (idx < argModes.Count()) + { + wxString tmp = argModes[idx]; + switch ((char)(tmp.c_str())[0]) + { + case 'i': + argMode = pgParam::PG_PARAM_IN; + m_inputParamCnt++; + break; + case 'b': + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_INOUT; + break; + case 'o': + argMode = pgParam::PG_PARAM_OUT; + break; + case 'v': + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_VARIADIC; + m_hasVariadic = true; + break; + case 't': + continue; + default: + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_IN; + break; + } + } + else + { + m_inputParamCnt++; + argMode = pgParam::PG_PARAM_IN; + } + + // In EDBAS 90, if an SPL-function has both an OUT-parameter + // and a return value (which is not possible on PostgreSQL otherwise), + // the return value is transformed into an extra OUT-parameter + // named "_retval_" + if (argName == wxT("_retval_") && _conn->EdbMinimumVersion(9, 0)) + { + // this will be the return type for this object + m_returnType = argTypes[idx]; + + continue; + } + + m_args->Add(new dbgArgInfo(argName, argTypes[idx], argTypeOid, argMode)); + } + + if (m_args->GetCount() == 0) + { + delete m_args; + m_args = NULL; + + return; + } + + if (nArgDefs != 0) + { + argCnt = m_args->GetCount(); + + // Set the default as the value for the argument + for (idx = argCnt - 1;; idx--) + { + dbgArgInfo *arg = (dbgArgInfo *)((*m_args)[idx]); + + if (arg->GetMode() == pgParam::PG_PARAM_INOUT || + arg->GetMode() == pgParam::PG_PARAM_IN) + { + nArgDefs--; + + if (argDefVals[nArgDefs] != wxT("-")) + { + arg->SetDefault(argDefVals[nArgDefs]); + } + + if (nArgDefs == 0) + { + break; + } + } + if (idx == 0) + break; + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// operator[] +// +// This operator function makes it easy to index into the m_args array +// using concise syntax. +dbgArgInfo *dbgTargetInfo::operator[](int index) +{ + if (m_args == NULL) + return (dbgArgInfo *)NULL; + + if (index < 0 || index >= (int)m_args->GetCount()) + return (dbgArgInfo *)NULL; + + return (dbgArgInfo *)((*m_args)[index]); +} + +dbgArgInfo::dbgArgInfo(const wxString &_name, const wxString &_type, Oid _typeOid, + short _mode) + : m_name(_name), m_type(_type), m_typeOid(_typeOid), m_mode(_mode), + m_hasDefault(false), m_useDefault(false), m_null(false) +{ + if (!_type.EndsWith(wxT("[]"), &m_baseType)) + { + m_baseType = wxEmptyString; + } +} + + +pgParam *dbgArgInfo::GetParam(wxMBConv *_conv) +{ + return new pgParam(m_typeOid, + (m_null ? (wxString *)NULL : &m_val), + _conv, m_mode); +} + +bool dbgTargetInfo::AddForExecution(pgQueryThread *_thread) +{ + wxASSERT(_thread != NULL); + + if (_thread == NULL) + return false; + + pgConn *conn = _thread->GetConn(); + + pgParamsArray *params = NULL; + wxString strQuery; + bool useCallable = false; + + // Basically - we can call the function/target three ways: + // 1. If it is a edbspl procedure, we can use callable statement + // 2. If the database server is of type EnterpriseDB, and + // function/procedure is type 'edbspl', we should use the anonymous + // function block for: + // a. Version < 9.0 + // b. Package function/procedure + // 3. Otherwise, we should use the simple function call (except using EXEC + // for the procedure in 'edbspl' instead of using SELECT) + if (_thread->SupportCallableStatement() && + m_language == wxT("edbspl") && + !m_isFunction) + { + useCallable = true; + strQuery = wxT("CALL ") + m_fqName + wxT("("); + + if (m_args) + { + params = new pgParamsArray(); + wxMBConv *conv = conn->GetConv(); + + for(int idx = 0; idx < (int)m_args->GetCount(); idx++) + { + params->Add(((*m_args)[idx])->GetParam(conv)); + + if (idx != 0) + strQuery += wxT(", "); + strQuery += wxString::Format(wxT("$%d::"), idx + 1) + + ((*m_args)[idx])->GetTypeName(); + } + } + strQuery += wxT(")"); + } + else if (conn->GetIsEdb() && !conn->BackendMinimumVersion(9, 3)) + { + wxString strDeclare, strStatement, strResult; + bool useAnonymousBlock = false; + + if (m_language == wxT("edbspl")) + { + useAnonymousBlock = true; + if (!m_isFunction) + { + strStatement = wxT("\tEXEC ") + m_fqName; + } + else if (m_returnType == wxT("void") || m_returnsSet || + !conn->BackendMinimumVersion(8, 4)) + { + strStatement = wxT("\tPERFORM ") + m_fqName; + } + else + { + wxString resultVar = wxT("v_retVal"); + strStatement = wxT("\t") + resultVar + wxT(" := ") + m_fqName; + strDeclare.Append(wxT("\t")) + .Append(resultVar) + .Append(wxT(" ")) + .Append(m_returnType) + .Append(wxT(";\n")); + strResult = wxT("\tDBMS_OUTPUT.PUT_LINE(E'\\n\\nResult:\\n--------\\n' || ") + + resultVar + + wxT("::text || E'\\n\\nNOTE: This is the result generated during the function execution by the debugger.\\n');\n"); + } + } + else + { + if (m_returnType == wxT("record")) + { + strStatement = wxT("\tSELECT ") + m_fqName; + } + else + { + strStatement = wxT("\tSELECT * FROM ") + m_fqName; + } + } + + if (m_args && m_args->GetCount() > 0) + { + strStatement.Append(wxT("(")); + + for(int idx = 0, firstProcessed = false; idx < (int)m_args->GetCount(); idx++) + { + dbgArgInfo *arg = (*m_args)[idx]; + + if (!conn->EdbMinimumVersion(8, 4) && + arg->GetMode() == pgParam::PG_PARAM_OUT && + (!m_isFunction || m_language == wxT("edbspl"))) + { + if (firstProcessed) + strStatement.Append(wxT(", ")); + firstProcessed = true; + + strStatement.Append(wxT("NULL::")).Append(arg->GetTypeName()); + } + else if (conn->EdbMinimumVersion(8, 4) && useAnonymousBlock && + (arg->GetMode() == pgParam::PG_PARAM_OUT || + arg->GetMode() == pgParam::PG_PARAM_INOUT)) + { + wxString strParam = wxString::Format(wxT("p_param%d"), idx); + + strDeclare.Append(wxT("\t")) + .Append(strParam) + .Append(wxT(" ")) + .Append(arg->GetTypeName()); + + if (arg->GetMode() == pgParam::PG_PARAM_INOUT) + { + strDeclare.Append(wxT(" := ")) + .Append(arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value())) + .Append(wxT("::")) + .Append(arg->GetTypeName()); + } + strDeclare.Append(wxT(";\n")); + + if (firstProcessed) + strStatement.Append(wxT(", ")); + firstProcessed = true; + + strStatement.Append(strParam); + } + else if (arg->GetMode() != pgParam::PG_PARAM_OUT) + { + if (firstProcessed) + strStatement.Append(wxT(", ")); + firstProcessed = true; + + if (arg->GetMode() == pgParam::PG_PARAM_VARIADIC) + strStatement += wxT("VARIADIC "); + + strStatement + .Append(arg->Null() ? wxT("NULL") : conn->qtDbString(arg->Value())) + .Append(wxT("::")) + .Append(arg->GetTypeName()); + } + } + strStatement.Append(wxT(")")); + strQuery = strStatement; + } + else if (!m_isFunction && m_language == wxT("edbspl")) + { + strQuery = strStatement; + } + else + { + strQuery = strStatement.Append(wxT("()")); + } + if (useAnonymousBlock) + { + strQuery = wxT("DECLARE\n") + + strDeclare + wxT("BEGIN\n") + strStatement + wxT(";\n") + strResult + wxT("END;"); + } + } + else + { + if (!m_isFunction) + { + strQuery = wxT("EXEC ") + m_fqName + wxT("("); + } + else if (m_returnType == wxT("record")) + { + strQuery = wxT("SELECT ") + m_fqName + wxT("("); + } + else + { + strQuery = wxT("SELECT * FROM ") + m_fqName + wxT("("); + } + + if (m_args) + { + params = new pgParamsArray(); + wxMBConv *conv = conn->GetConv(); + unsigned int noInParams = 0; + + for(int idx = 0; idx < (int)m_args->GetCount(); idx++) + { + dbgArgInfo *arg = (*m_args)[idx]; + + if (arg->GetMode() != pgParam::PG_PARAM_OUT) + { + params->Add(arg->GetParam(conv)); + + if (noInParams != 0) + strQuery += wxT(", "); + + if (arg->GetMode() == pgParam::PG_PARAM_VARIADIC) + strQuery += wxT("VARIADIC "); + + noInParams++; + strQuery += wxString::Format(wxT("$%d::"), noInParams) + + ((*m_args)[idx])->GetTypeName(); + } + } + + /* + * The function may not have IN/IN OUT/VARIADIC arguments, but only + * OUT one(s). + */ + if (params->GetCount() == 0) + { + delete params; + params = NULL; + } + } + strQuery += wxT(")"); + } + + _thread->AddQuery(strQuery, params, RESULT_ID_DIRECT_TARGET_COMPLETE, NULL, useCallable); + + return true; +} diff --git a/debugger/debugger.cpp b/debugger/debugger.cpp new file mode 100644 index 0000000..e5c5e7c --- /dev/null +++ b/debugger/debugger.cpp @@ -0,0 +1,273 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// debugger.cpp - Debugger factories +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "debugger/debugger.h" +#include "debugger/dbgController.h" +#include "schema/pgFunction.h" +#include "schema/pgTrigger.h" +#include "schema/edbPackageFunction.h" + +#include + +/////////////////////////////////////////////////// +// Debugger factory +/////////////////////////////////////////////////// +debuggerFactory::debuggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Debug"), _("Debug the selected object")); +} + +wxWindow *debuggerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + // Check here to make sure the function still exists before proceeding. + // There is still a very small window in which it might be dropped, but + // that will be handled by a cache lookup failure error in the database + // We also make sure the function name doesn't contain a : as that will + // sent the debugger API nuts. + pgSet *res = obj->GetConnection()->ExecuteSet(wxT("SELECT proname FROM pg_proc WHERE oid = ") + NumToStr((long)obj->GetOid())); + + if (res->NumRows() != 1) + { + wxLogError(_("The selected function could not be found.")); + ctlTree *browser = form->GetBrowser(); + wxTreeItemId item = browser->GetSelection(); + if (obj == browser->GetObject(item)) + { + form->Refresh(obj); + } + delete res; + return (wxWindow *)NULL; + } + + if (res->GetVal(wxT("proname")).Contains(wxT(":"))) + { + wxLogError(_("Functions with a colon in the name cannot be debugged.")); + delete res; + return (wxWindow *)NULL; + } + try + { + new dbgController(form, obj, true); + } + catch (const std::runtime_error &) + { + // just ignore this errors, we already logged them in native messages to + // the end-user + } + delete res; + return (wxWindow *)NULL; +} + +bool debuggerFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + // Can't debug catalog objects. + if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG) + return false; + + // Must be a super user or object owner to create breakpoints of any kind. + if (!obj->GetServer() || !(obj->GetServer()->GetSuperUser() || obj->GetServer()->GetUsername() == obj->GetOwner())) + return false; + + // EnterpriseDB 8.3 or earlier does not support debugging by the non-superuser + if (!obj->GetServer()->GetSuperUser() && !obj->GetConnection()->EdbMinimumVersion(8, 4) && obj->GetConnection()->GetIsEdb()) + return false; + + if (!obj->IsCollection()) + { + switch (obj->GetMetaType()) + { + case PGM_FUNCTION: + { + pgFunction *func = (pgFunction *)obj; + + // If this is an EDB wrapped function, no debugging allowed + if (obj->GetConnection()->GetIsEdb() && func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + return false; + + if (func->GetReturnType() != wxT("trigger") && + func->GetReturnType() != wxT("\"trigger\"")) + { + if (func->GetLanguage() == wxT("plpgsql") && + obj->GetDatabase()->CanDebugPlpgsql()) + return true; + else if (func->GetLanguage() == wxT("edbspl") && + obj->GetDatabase()->CanDebugEdbspl()) + return true; + else + return false; + } + else + return false; + } + break; + + case EDB_PACKAGEFUNCTION: + if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) && + obj->GetDatabase()->CanDebugEdbspl() && + obj->GetName() != wxT("cons") && + ((edbPackageFunction *)obj)->GetSource() != wxEmptyString && + (!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))) + return true; + break; + + default: + break; + } + } + return false; +} + +/////////////////////////////////////////////////// +// Breakpoint factory +/////////////////////////////////////////////////// +breakpointFactory::breakpointFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Set breakpoint"), _("Set a breakpoint on the selected object")); +} + +wxWindow *breakpointFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString dbgOid; + if (obj->GetMetaType() == PGM_TRIGGER) + dbgOid = NumToStr((long)((pgTrigger *)obj)->GetFunctionOid()); + else + dbgOid = NumToStr((long)obj->GetOid()); + + // Check here to make sure the function still exists before proceeding. + // There is still a very small window in which it might be dropped, but + // we should be able to handle most cases here without having to do this + // deep down in query threads. + // We also make sure the function name doesn't contain a : as that will + // sent the debugger API nuts. + pgSet *res = obj->GetConnection()->ExecuteSet( + wxT("SELECT count(*) AS count, proname FROM pg_proc WHERE oid = ") + dbgOid + wxT(" GROUP BY proname")); + if (res->GetVal(wxT("proname")).Contains(wxT(":"))) + { + wxLogError(_("Functions with a colon in the name cannot be debugged.")); + delete res; + return (wxWindow *)NULL; + } + + if (res->GetLong(wxT("count")) != 1) + { + wxLogError(_("The selected function could not be found.")); + + ctlTree *browser = form->GetBrowser(); + wxTreeItemId item = browser->GetSelection(); + if (obj == browser->GetObject(item)) + { + pgCollection *coll = browser->GetParentCollection(obj->GetId()); + browser->DeleteChildren(coll->GetId()); + coll->ShowTreeDetail(browser); + } + delete res; + return (wxWindow *)NULL; + } + + try + { + new dbgController(form, obj, false); + } + catch (const std::runtime_error &) + { + // just ignore this errors, we already logged them in native messages to + // the end-user + } + + delete res; + return (wxWindow *)NULL; +} + +bool breakpointFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + // Can't debug catalog objects. + if (obj->GetSchema() && obj->GetSchema()->GetMetaType() == PGM_CATALOG) + return false; + + // Must be a super user to create breakpoints of any kind. + if (!obj->GetServer() || !obj->GetServer()->GetSuperUser()) + return false; + + if (!obj->IsCollection()) + { + switch (obj->GetMetaType()) + { + case PGM_FUNCTION: + { + pgFunction *func = (pgFunction *)obj; + + // If this is an EDB wrapped function, no debugging allowed + if (obj->GetConnection()->GetIsEdb() && + func->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + return false; + + if (func->GetLanguage() == wxT("plpgsql") && + obj->GetDatabase()->CanDebugPlpgsql()) + return true; + else if (func->GetLanguage() == wxT("edbspl") && + obj->GetDatabase()->CanDebugEdbspl()) + return true; + else + return false; + } + break; + + case EDB_PACKAGEFUNCTION: + if (obj->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2) && + obj->GetDatabase()->CanDebugEdbspl() && + obj->GetName() != wxT("cons") && + ((edbPackageFunction *)obj)->GetSource() != wxEmptyString && + (!((edbPackageFunction *)obj)->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$")))) + return true; + break; + + case PGM_TRIGGER: + { + pgTrigger *trig = (pgTrigger *)obj; + + // If this is an EDB wrapped function, no debugging allowed + if (obj->GetConnection()->GetIsEdb() && + trig->GetSource().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + return false; + + if (trig->GetLanguage() == wxT("plpgsql") && + obj->GetDatabase()->CanDebugPlpgsql()) + return true; + else if (trig->GetLanguage() == wxT("edbspl") && + obj->GetDatabase()->CanDebugEdbspl()) + return true; + else + return false; + } + break; + + default: + break; + } + } + return false; +} + + + + diff --git a/debugger/dlgDirectDbg.cpp b/debugger/dlgDirectDbg.cpp new file mode 100644 index 0000000..d9ab706 --- /dev/null +++ b/debugger/dlgDirectDbg.cpp @@ -0,0 +1,1073 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDirectDbg.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "ctl/ctlAuiNotebook.h" +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "schema/pgObject.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "debugger/dlgDirectDbg.h" + +#include "images/debugger.pngc" + +#define lblMessage CTRL_STATIC("lblMessage") +#define grdParams CTRL("grdParams", wxGrid) +#define chkPkgInit CTRL_CHECKBOX("chkPkgInit") +#define btnDebug CTRL_BUTTON("wxID_OK") + +IMPLEMENT_CLASS(dlgDirectDbg, pgDialog) + +BEGIN_EVENT_TABLE(dlgDirectDbg, pgDialog) + EVT_BUTTON(wxID_OK, dlgDirectDbg::OnOk) + EVT_BUTTON(wxID_CANCEL, dlgDirectDbg::OnCancel) + EVT_GRID_CMD_LABEL_LEFT_CLICK(XRCID("grdParams"), dlgDirectDbg::OnClickGridLabel) + EVT_MENU(RESULT_ID_ARGS_UPDATED, dlgDirectDbg::ResultArgsUpdated) + EVT_MENU(RESULT_ID_ARGS_UPDATE_ERROR, dlgDirectDbg::ResultArgsUpdateError) +END_EVENT_TABLE() + + +//////////////////////////////////////////////////////////////////////////////// +// dlgDirectDbg constructor +// +// This class implements 'direct-debugging'. In direct-debugging, the user +// provides a function signature, procedure signature, or OID on the command +// line (this identifies the debug target). We query the server for the +// names, types, and in/out modes for each target parameter and then prompt +// the user to enter a value for each of the IN (and IN/OUT) parameters. +// +// When the user fills in the parameter values and clicks OK, we set a +// breakpoint at the target and then execute a SELECT statement or an +// EXEC statement that invokes the target (with the parameter values +// provided by the user). + +dlgDirectDbg::dlgDirectDbg(frmDebugger *_parent, dbgController *_controller, + pgConn *_conn) + : m_controller(_controller), m_thread(NULL), m_conn(_conn) +{ + int width, height, totalWidth = 0; + + SetFont(settings->GetSystemFont()); + LoadResource(_parent, wxT("dlgDirectDbg")); + + // Icon + SetIcon(*debugger_png_ico); + RestorePosition(); + + grdParams->SetRowLabelSize(wxGRID_AUTOSIZE); + grdParams->SetColLabelSize(20); + grdParams->AutoSizeColumns(true); + + chkPkgInit->SetValue(false); + + PopulateParamGrid(); + + LoadSettings(); + + for(int i = 0; i < grdParams->GetNumberCols(); i++) + grdParams->AutoSizeColumn(i, true); + + if (grdParams->GetNumberCols() > 1) + { + // Extend grid to it's parent width + grdParams->GetClientSize(&width, &height); + for (int i = 0; i < grdParams->GetNumberCols(); i++) + { + totalWidth += grdParams->GetColSize(i); + } + // Total client width - total six column widths - the first (an empty) column + // width + grdParams->SetColSize(COL_DEF_VAL, width - totalWidth - 100); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// PopulateParamGrid() +// +// This function reads parameter descriptions from m_targetInfo and adds a +// new row to the grid control for each IN (or IN/OUT, VARAIADIC) parameter. +// Each row displays the parameter name, the data type, and an entry box +// where the user can type in a value for that parameter +// +void dlgDirectDbg::PopulateParamGrid() +{ + pgDbgArgs *args = m_controller->GetTargetInfo()->GetArgs(); + + // If the target is defined within package, offer the user + // a chance to debug the initializer (there may or may not + // be an initializer, we don't really know at this point) + if(m_controller->GetTargetInfo()->GetPkgOid() == 0) + chkPkgInit->Disable(); + else + chkPkgInit->Enable(); + + if (!args) + { + grdParams->CreateGrid(0, 1); + grdParams->SetColLabelValue(COL_NAME, _("No arguments required")); + grdParams->SetColSize(0, 350); + + return; + } + + // Add seven columns to the grid control: + // - Name, Type, NULL?, EXPR?, Value, Default?, And Default Value + grdParams->CreateGrid(0, 7); + + grdParams->SetColLabelValue(COL_NAME, _("Name")); + grdParams->SetColLabelValue(COL_TYPE, _("Type")); + grdParams->SetColLabelValue(COL_NULL, _("Null?")); + grdParams->SetColLabelValue(COL_EXPR, _("Expression?")); + grdParams->SetColLabelValue(COL_VALUE, _("Value")); + grdParams->SetColLabelValue(COL_USE_DEF, _("Use default?")); + grdParams->SetColLabelValue(COL_DEF_VAL, _("Default Value")); + + size_t idx = 0; + + for(size_t pIdx = 0; pIdx < args->Count(); pIdx++) + { + dbgArgInfo *arg = (*args)[pIdx]; + + // If this is an IN parameter (or an IN/OUT parameter), add + // a new row to the grid + if(arg->GetMode() != pgParam::PG_PARAM_OUT) + { + grdParams->AppendRows(1); + grdParams->SetCellValue(idx, COL_NAME, arg->GetName()); + + // Make it obvious which are variadics + if (arg->GetMode() != pgParam::PG_PARAM_VARIADIC) + { + grdParams->SetRowLabelValue(idx, wxEmptyString); + grdParams->SetCellValue(idx, COL_TYPE, arg->GetTypeName()); + + if (!arg->IsArray()) + { + // Is the value an expression? + grdParams->SetCellEditor(idx, COL_EXPR, new ctlGridCellBoolEditor()); + grdParams->SetCellRenderer(idx, COL_EXPR, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(idx, COL_EXPR, wxT("")); + } + else + { + grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90)); + } + + // Use the default value? + grdParams->SetCellRenderer(idx, COL_USE_DEF, new wxGridCellBoolRenderer()); + grdParams->SetCellEditor(idx, COL_USE_DEF, new ctlGridCellBoolEditor()); + } + else + { + grdParams->SetCellValue(idx, COL_TYPE, wxT("VARIADIC ") + arg->GetTypeName()); + grdParams->SetRowLabelValue(idx, wxEmptyString); + + grdParams->AppendRows(1); + grdParams->SetRowLabelValue(idx + 1, wxT("+")); + grdParams->SetCellValue(idx + 1, COL_NAME, _("Click '+/-' to add/remove value to variadic")); + + grdParams->SetCellBackgroundColour(idx + 1, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx + 1, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx + 1, COL_USE_DEF, wxColour(235, 235, 235, 90)); + } + + // Set value to NULL? + grdParams->SetCellEditor(idx, COL_NULL, new ctlGridCellBoolEditor(arg)); + grdParams->SetCellRenderer(idx, COL_NULL, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(idx, COL_NULL, wxT("")); + + if (arg->HasDefault()) + { + // Whenever the default value is available, use that by default + grdParams->SetCellValue(idx, COL_USE_DEF, wxT("1")); + grdParams->SetCellValue(idx, COL_DEF_VAL, arg->Default()); + + // When "Use Defalut?" is enabled, disable VALUE, NULL? and + // EXPR? columns + grdParams->SetReadOnly(idx, COL_USE_DEF, false); + grdParams->SetReadOnly(idx, COL_VALUE, false); + grdParams->SetReadOnly(idx, COL_EXPR, false); + } + else + { + grdParams->SetCellValue(idx, COL_USE_DEF, wxT("")); + grdParams->SetCellValue(idx, COL_DEF_VAL, _("")); + + // When default value is not available, we should ask the user + // to enter them + grdParams->SetReadOnly(idx, COL_USE_DEF, true); + grdParams->SetReadOnly(idx, COL_VALUE, arg->IsArray()); + grdParams->SetReadOnly(idx, COL_EXPR, arg->IsArray()); + + grdParams->SetCellBackgroundColour(idx, COL_USE_DEF, wxColour(235, 235, 235, 90)); + if (arg->IsArray()) + { + grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90)); + } + } + + grdParams->SetReadOnly(idx, COL_NULL, false); + grdParams->SetReadOnly(idx, COL_NAME, true); + grdParams->SetReadOnly(idx, COL_TYPE, true); + grdParams->SetReadOnly(idx, COL_DEF_VAL, true); + grdParams->SetCellBackgroundColour(idx, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + idx++; + + if (arg->GetMode() != pgParam::PG_PARAM_VARIADIC && + arg->IsArray()) + { + grdParams->AppendRows(1); + + grdParams->SetRowLabelValue(idx, wxT("+")); + grdParams->SetCellValue(idx, COL_NAME, _("Click '+/-' to add/remove value to the array")); + + grdParams->SetReadOnly(idx, COL_NAME, true); + grdParams->SetReadOnly(idx, COL_TYPE, true); + grdParams->SetReadOnly(idx, COL_NULL, true); + grdParams->SetReadOnly(idx, COL_EXPR, true); + grdParams->SetReadOnly(idx, COL_VALUE, true); + grdParams->SetReadOnly(idx, COL_USE_DEF, true); + grdParams->SetReadOnly(idx, COL_DEF_VAL, true); + + grdParams->SetCellBackgroundColour(idx, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_NULL, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_USE_DEF, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(idx, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + idx++; + } + } + } + + // Move the cursor to the first value (so that the user + // can just start typing) + + grdParams->SetGridCursor(0, COL_VALUE); + grdParams->SetFocus(); +} + +void dlgDirectDbg::LoadLastCellSetting(int row_number, int parameter_index, + int index_array_bound, bool isArray) +{ + wxString lastValue, valKey; + dbgTargetInfo *target = m_controller->GetTargetInfo(); + long num; + + settings->Read(wxT("Debugger/Proc/OID"), &num, -1L); + if(num != target->GetOid()) + { + return; + } + else + { + if(!isArray) + { + // Non array elements cell index is 0 + valKey = wxString::Format(wxT("Debugger/Proc/%d/0/"), parameter_index); + settings->Read(valKey + wxT("VAL"), &lastValue, wxEmptyString); + grdParams->SetCellValue(row_number, COL_VALUE, lastValue); + } + else + { + long arrCnt; + + settings->Read( + wxString::Format( + wxT("Debugger/Proc/%d/"), parameter_index) + + wxT("ArrCnt"), &arrCnt, 0L); + + // Refresh an entire array element + for( int i = 0; i <= index_array_bound && i <= arrCnt - 1; i++ ) + { + valKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), parameter_index, i); + settings->Read(valKey + wxT("VAL"), &lastValue, wxEmptyString); + grdParams->SetCellValue(row_number - index_array_bound + i, COL_VALUE, + lastValue); + } + } + } + +} + +//////////////////////////////////////////////////////////////////////////////// +// LoadSettings() +// +// Loads default values from our .ini file. We save the OID of the most +// recent direct-debugging target when close a session. If we're direct- +// debugging the same target this time around, we load the argument values +// from the .ini file. +void dlgDirectDbg::LoadSettings() +{ + long num, arrCnt; + wxString tmp, key; + bool initPkgCon = false; + + settings->Read(wxT("Debugger/Proc/OID"), &num, -1L); + + dbgTargetInfo *target = m_controller->GetTargetInfo(); + pgDbgArgs *args = m_controller->GetTargetInfo()->GetArgs(); + + if (num != target->GetOid()) + { + chkPkgInit->SetValue(target->GetPkgInitOid() != 0L); + chkPkgInit->Enable(target->GetPkgInitOid() != 0L); + + return; + } + else + { + settings->Read(wxT("Debugger/Proc/initialize_package_constructor"), &initPkgCon, true); + + chkPkgInit->SetValue(&initPkgCon && target->GetPkgInitOid() != 0L); + chkPkgInit->Enable(target->GetPkgInitOid() != 0L); + } + + settings->Read(wxT("Debugger/Proc/args"), &num, 0L); + + if (num <= 0L) + return; + + if (!args) + return; + + for (int cnt = 0, row = 0; cnt < num && cnt < (int)args->Count();) + { + ctlGridCellBoolEditor *editor = + dynamic_cast( + grdParams->GetCellEditor(row, COL_NULL)); + dbgArgInfo *arg + = editor != NULL ? editor->GetArg() : NULL; + + if (arg == NULL) + { + row++; + + continue; + } + + key = wxString::Format(wxT("Debugger/Proc/%d/"), cnt); + + // Use NULL? + settings->Read(key + wxT("NULL"), &tmp, wxEmptyString); + grdParams->SetCellValue(row, COL_NULL, tmp); + + // Use Default (if available) + settings->Read(key + wxT("USE_DEF"), &tmp, wxEmptyString); + grdParams->SetCellValue(row, COL_USE_DEF, tmp); + + // Is Array/VARIADIC? + settings->Read(key + wxT("ArrCnt"), &arrCnt, 0L); + + if (arrCnt > 0L) + { + // An individual variable can be an expression or can be the 'NULL' value + wxString valKey, strVal, strExpr, strNull; + + for (int idx = 0; idx < arrCnt; idx++, row++) + { + valKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), cnt, idx); + + // Use 'NULL'? + settings->Read(valKey + wxT("NULL"), &strNull, wxEmptyString); + + // Use EXPR? + settings->Read(valKey + wxT("EXPR"), &strExpr, wxEmptyString); + + // Value + settings->Read(valKey + wxT("VAL"), &strVal, wxEmptyString); + + if (arg->IsArray()) + { + int arrRow = row + 1; + + if (idx == 0) + { + grdParams->SetReadOnly(row, COL_EXPR, true); + grdParams->SetReadOnly(row, COL_VALUE, true); + + grdParams->SetCellBackgroundColour(row, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_VALUE, wxColour(235, 235, 235, 90)); + + grdParams->SetRowLabelValue( + row, wxString::Format(wxT("%d"), cnt + 1)); + } + grdParams->InsertRows(arrRow, 1, false); + grdParams->SetRowLabelValue(arrRow, wxT("-")); + + grdParams->SetCellValue(arrRow, COL_TYPE, arg->GetBaseType()); + + // Is the value an expression? + grdParams->SetCellEditor(arrRow, COL_EXPR, new ctlGridCellBoolEditor()); + grdParams->SetCellRenderer(arrRow, COL_EXPR, + new wxGridCellBoolRenderer()); + grdParams->SetCellValue(arrRow, COL_EXPR, strExpr); + + // Set value to NULL? + grdParams->SetCellEditor(arrRow, COL_NULL, + new ctlGridCellBoolEditor(arg)); + grdParams->SetCellRenderer(arrRow, COL_NULL, + new wxGridCellBoolRenderer()); + grdParams->SetCellValue(arrRow, COL_NULL, strNull); + + // Set value + grdParams->SetCellValue(arrRow, COL_VALUE, strVal); + + grdParams->SetReadOnly(arrRow, COL_NULL, false); + grdParams->SetReadOnly(arrRow, COL_EXPR, false); + grdParams->SetReadOnly(arrRow, COL_VALUE, false); + + grdParams->SetCellBackgroundColour(arrRow, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow, COL_USE_DEF, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + grdParams->SetReadOnly(arrRow + 1, COL_NAME, true); + grdParams->SetReadOnly(arrRow + 1, COL_TYPE, true); + grdParams->SetReadOnly(arrRow + 1, COL_NULL, true); + grdParams->SetReadOnly(arrRow + 1, COL_EXPR, true); + grdParams->SetReadOnly(arrRow + 1, COL_VALUE, true); + grdParams->SetReadOnly(arrRow + 1, COL_USE_DEF, true); + grdParams->SetReadOnly(arrRow + 1, COL_DEF_VAL, true); + + grdParams->SetCellBackgroundColour(arrRow + 1, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_NULL, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_EXPR, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_VALUE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_USE_DEF, + wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(arrRow + 1, COL_DEF_VAL, + wxColour(235, 235, 235, 90)); + + grdParams->SetRowLabelValue(arrRow + 1, wxT("+")); + } + else + { + grdParams->SetCellValue(row, COL_VALUE, strVal); + grdParams->SetCellValue(row, COL_EXPR, strExpr); + grdParams->SetCellValue(row, COL_NULL, strNull); + + grdParams->SetReadOnly(row, COL_NULL, false); + grdParams->SetReadOnly(row, COL_EXPR, false); + grdParams->SetReadOnly(row, COL_VALUE, false); + + grdParams->SetRowLabelValue( + row, wxString::Format(wxT("%d"), cnt + 1)); + } + } + if (arg->IsArray()) + row++; + } + cnt++; + } +} + + +void dlgDirectDbg::OnOk(wxCommandEvent &_ev) +{ + if (m_thread) + return; + + grdParams->Enable(false); + btnDebug->Enable(false); + + m_thread = new dbgArgValueEvaluator(m_conn, this); + + if (m_thread->Create() != wxTHREAD_NO_ERROR) + { + delete m_thread; + m_thread = NULL; + + wxLogError(_("Failed to create a debugging thread.")); + EndModal(wxID_CANCEL); + + return; + } + + m_thread->Run(); +} + + +void dlgDirectDbg::OnCancel(wxCommandEvent &_ev) +{ + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + _ev.Skip(); +} + +void dlgDirectDbg::OnClickGridLabel(wxGridEvent &_ev) +{ + if (_ev.AltDown() || _ev.ControlDown() || _ev.ShiftDown()) + { + _ev.Skip(); + + return; + } + + int row = _ev.GetRow(); + int col = _ev.GetCol(); + + if (row < 0 || col > 0) + { + _ev.Skip(); + + return; + } + + wxString strLabel = grdParams->GetRowLabelValue(row); + + if (strLabel == wxT("+")) + { + wxASSERT(row != 0); + + ctlGridCellBoolEditor *editor = + dynamic_cast( + grdParams->GetCellEditor(row - 1, COL_NULL)); + dbgArgInfo *arg + = editor != NULL ? editor->GetArg() : NULL; + + grdParams->InsertRows(row, 1, false); + grdParams->SetRowLabelValue(row, wxT("-")); + + grdParams->SetCellValue(row, COL_TYPE, arg->GetBaseType()); + grdParams->SetCellBackgroundColour(row, COL_TYPE, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_NAME, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_USE_DEF, wxColour(235, 235, 235, 90)); + grdParams->SetCellBackgroundColour(row, COL_DEF_VAL, wxColour(235, 235, 235, 90)); + + // Is the value an expression? + grdParams->SetCellEditor(row, COL_EXPR, new ctlGridCellBoolEditor()); + grdParams->SetCellRenderer(row, COL_EXPR, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(row, COL_EXPR, wxT("")); + + // Set value to NULL? + grdParams->SetCellEditor(row, COL_NULL, new ctlGridCellBoolEditor(arg)); + grdParams->SetCellRenderer(row, COL_NULL, new wxGridCellBoolRenderer()); + grdParams->SetCellValue(row, COL_NULL, wxT("1")); + + row++; + grdParams->SetRowLabelValue(row, wxT("+")); + } + else if (strLabel == wxT("-")) + { + dbgArgInfo *arg = NULL; + grdParams->DeleteRows(row, 1, false); + } + else + return; + + // Update the row labels + ctlGridCellBoolEditor *editor = NULL; + dbgArgInfo *arg = NULL, + *prev = NULL; + wxString strName; + + int totalRows = grdParams->GetNumberRows(), + idx = 0; + row = 0; + + while (row < totalRows) + { + editor = + dynamic_cast( + grdParams->GetCellEditor(row, COL_NULL)); + arg = editor != NULL ? editor->GetArg() : NULL; + strName = grdParams->GetCellValue(row, COL_NAME); + + if (strName.IsEmpty() && arg) + grdParams->SetRowLabelValue(row, wxT("-")); + else if (!strName.IsEmpty() && !arg) + grdParams->SetRowLabelValue(row, wxT("+")); + else + { + idx++; + grdParams->SetRowLabelValue(row, wxString::Format(wxT("%d"), idx)); + } + + row++; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// SaveSettings() +// +// Save default values to our .ini file. We save the OID of the most +// recent direct-debugging target when close a session. We also save the +// value of each argument - if you debug the same target again next time, +// loadSettings() will initialize the parameter-values window with the +// same parameter values that you entered in this session. +// +void dlgDirectDbg::SaveSettings() +{ + wxString strName, strExpr, strVal, strNull, strDef, strKey, strValExpr; + dbgArgInfo *prev = NULL, + *arg = NULL; + int row = 0, + idx = -1, + arrCnt = 1; + + // Save the current function/procedure/trigger OID + settings->WriteLong(wxT("Debugger/Proc/OID"), + m_controller->GetTargetInfo()->GetOid()); + + // Save - whether we need to debug the package constructor + settings->WriteBool(wxT("Debugger/Proc/initialize_package_constructor"), + (chkPkgInit->IsEnabled() && chkPkgInit->GetValue())); + + for (; row < grdParams->GetNumberRows(); row++) + { + ctlGridCellBoolEditor *editor = + dynamic_cast( + grdParams->GetCellEditor(row, COL_NULL)); + arg = editor != NULL ? editor->GetArg() : NULL; + + // This should be the information for add/remove values for an array + if (arg == NULL) + { + continue; + } + else if (prev != arg) + { + idx++; + prev = arg; + + if (arg->IsArray()) + { + arrCnt = 0; + } + else + { + arrCnt = 1; + } + } + else + { + arrCnt++; + } + + settings->WriteInt(wxString::Format(wxT("Debugger/Proc/%d/ArrCnt"), idx), arrCnt); + + if ((arrCnt == 0 && arg->IsArray()) || + (arrCnt == 1 && !arg->IsArray())) + { + // Use Default (if available) + settings->Write(wxString::Format(wxT("Debugger/Proc/%d/USE_DEF"), idx), + grdParams->GetCellValue(row, COL_USE_DEF)); + + // Use NULL? + settings->Write(wxString::Format(wxT("Debugger/Proc/%d/NULL"), idx), + grdParams->GetCellValue(row, COL_NULL)); + + if (arrCnt == 0 && arg->IsArray()) + continue; + } + + strKey = wxString::Format(wxT("Debugger/Proc/%d/%d/"), idx, arrCnt - 1); + + // Use NULL? + settings->Write(strKey + wxT("NULL"), + grdParams->GetCellValue(row, COL_NULL)); + + // Is value EXPR? + settings->Write(strKey + wxT("EXPR"), + grdParams->GetCellValue(row, COL_EXPR)); + + // Value + settings->Write(strKey + wxT("VAL"), + grdParams->GetCellValue(row, COL_VALUE)); + } + + // Save the number of arguments + settings->WriteLong(wxT("Debugger/Proc/args"), (long)(idx + 1)); +} + + +ctlGridCellBoolEditor::ctlGridCellBoolEditor(dbgArgInfo *_arg) + : m_arg(_arg) +{} + + +void ctlGridCellBoolEditor::BeginEdit(int _row, int _col, wxGrid *_grid) +{ + wxGridCellBoolEditor::BeginEdit(_row, _col, _grid); + + wxFocusEvent event (wxEVT_KILL_FOCUS); + if (m_control) + { + m_control->GetEventHandler()->AddPendingEvent(event); + } +} + + +wxGrid *dlgDirectDbg::GetParamsGrid() +{ + return grdParams; +} + +bool dlgDirectDbg::DebugPkgConstructor() +{ + return chkPkgInit->IsEnabled() && chkPkgInit->GetValue(); +} + + +wxGridCellEditor *ctlGridCellBoolEditor::Clone() const +{ + return new ctlGridCellBoolEditor(m_arg); +} + + +void dlgDirectDbg::ResultArgsUpdated(wxCommandEvent &_ev) +{ + SaveSettings(); + SavePosition(); + + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + + if (IsModal()) + EndModal(wxID_OK); + else + Destroy(); +} + + +void dlgDirectDbg::ResultArgsUpdateError(wxCommandEvent &_ev) +{ + if (_ev.GetInt() == pgQueryResultEvent::PGQ_CONN_LOST) + { + if(wxMessageBox( + _("Connection to the database server lost!\nDo you want to try to reconnect to the server?"), + _("Connection Lost"), wxICON_ERROR | wxICON_QUESTION | wxYES_NO) == wxID_YES) + { + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + m_conn->Reconnect(); + + return; + } + EndModal(wxID_CANCEL); + + return; + } + + if (m_thread) + { + if (m_thread->IsRunning()) + { + m_thread->CancelEval(); + m_thread->Wait(); + } + + delete m_thread; + m_thread = NULL; + } + + wxLogError(_ev.GetString()); + + grdParams->Enable(true); + btnDebug->Enable(true); +} + + +void dbgArgValueEvaluator::NoticeHandler(void *, const char *) +{ + // Ignore the notices +} + + +void *dbgArgValueEvaluator::Entry() +{ + bool argNull, nullVal, useDef; + wxString strVal, strValExpr; + dbgArgInfo *prev = NULL, + *arg = NULL; + + wxGrid *grd = m_dlg->GetParamsGrid(); + + m_dlg->m_controller->GetTargetInfo()->DebugPackageConstructor() + = m_dlg->DebugPkgConstructor(); + + m_conn->RegisterNoticeProcessor(dbgArgValueEvaluator::NoticeHandler, NULL); + + for (int row = 0, idx = 0, arrCnt = 1, arr_idx_bound = 0; + row < grd->GetNumberRows() && !m_cancelled; row++) + { + ctlGridCellBoolEditor *editor = + dynamic_cast( + grd->GetCellEditor(row, dlgDirectDbg::COL_NULL)); + arg = editor != NULL ? editor->GetArg() : NULL; + + // This should be the information for add/remove values for an array + if (arg == NULL) + { + // prev was an array, can we fetch value for the same + if (prev && !prev->Null()) + { + wxString res = + m_conn->ExecuteScalar( + wxT("SELECT ARRAY[") + strValExpr + wxT("]::") + prev->GetTypeName(), + false); + + if (m_cancelled) + { + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + } + if (m_conn->GetStatus() == PGCONN_BAD) + { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + + ev.SetInt(pgQueryResultEvent::PGQ_CONN_LOST); + + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + } + if (m_conn->GetLastResultStatus() == PGRES_TUPLES_OK) + { + prev->Value() = res; + } + else + { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + wxString strName = prev->GetName(); + wxString strMsg; + + if (strName.IsEmpty()) + { + ev.SetString( + wxString::Format( + _("The specified value for argument #%d is not valid.\nPlease re-enter the value for it."), + idx)); + } + else + { + ev.SetString( + wxString::Format( + _("Specified value for argument '%s' is not valid.\nPlease re-enter the value for it."), + strName.c_str())); + } + ev.SetInt(pgQueryResultEvent::PGQ_RESULT_ERROR); + m_dlg->LoadLastCellSetting(row - 1, idx - 1, arr_idx_bound - 1, true); + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + + } + prev = NULL; + arr_idx_bound = 0; + } + + continue; + } + else if (prev != arg) + { + idx++; + argNull = false; + nullVal = false; + useDef = false; + + strValExpr = wxEmptyString; + } + + if (prev != arg) + { + prev = arg; + + // Use Default (if available) + arg->UseDefault() = wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_USE_DEF)); + // NULL? + arg->Null() = wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_NULL)); + + if (arg->UseDefault()) + strValExpr = arg->Default(); + + if (arg->IsArray()) + continue; + } + + // Use NULL? + // + // Keep this just before 'Use Default' column as - we may have non-empty + // value in the 'VAL' column + + if (!arg->UseDefault() || !arg->Null()) + { + if (!strValExpr.IsEmpty()) + { + strValExpr += wxT(", "); + } + + if (wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_NULL))) + { + strValExpr += wxT("NULL"); + } + else if (wxGridCellBoolEditor::IsTrueValue( + grd->GetCellValue(row, dlgDirectDbg::COL_EXPR))) + { + strValExpr += wxT("(") + grd->GetCellValue(row, dlgDirectDbg::COL_VALUE) + wxT(")"); + } + else + { + strValExpr += m_conn->qtDbString( + grd->GetCellValue(row, dlgDirectDbg::COL_VALUE)); + } + strValExpr.Append(wxT("::")) + .Append(arg->IsArray() ? + arg->GetBaseType() : arg->GetTypeName()); + + if(arg->IsArray()) + { + arr_idx_bound ++; + } + } + + if (!arg->IsArray() && !arg->Null()) + { + pgSet *set = + m_conn->ExecuteSet(wxT("SELECT ") + strValExpr, false); + + if (m_cancelled) + { + return (void *)NULL; + } + if (m_conn->GetStatus() == PGCONN_BAD) + { + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + + ev.SetString(_("Connection to the database server lost!")); + ev.SetInt(pgQueryResultEvent::PGQ_CONN_LOST); + + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + if (set) + delete set; + + return (void *)NULL; + } + if (m_conn->GetLastResultStatus() == PGRES_TUPLES_OK && + set && set->NumRows() > 0L) + { + if (set->IsNull(0)) + { + arg->Null() = true; + } + else + { + arg->Null() = false; + arg->Value() = set->GetVal(0); + } + } + else + { + wxString strName = arg->GetName(); + + if (strName.IsEmpty()) + strName = wxString::Format(_("Param#%d"), idx); + + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATE_ERROR); + + ev.SetString( + wxString::Format(_("Please re-enter the value for argument '%s'."), + strName.c_str())); + ev.SetInt(pgQueryResultEvent::PGQ_RESULT_ERROR); + + m_dlg->GetEventHandler()->AddPendingEvent(ev); + m_dlg->LoadSettings(); + // For scalar variable, always index of array bound is 0. + m_dlg->LoadLastCellSetting(row, idx - 1, 0, false); + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; + } + } + } + + wxCommandEvent ev(wxEVT_COMMAND_MENU_SELECTED, RESULT_ID_ARGS_UPDATED); + m_dlg->GetEventHandler()->AddPendingEvent(ev); + + m_conn->RegisterNoticeProcessor(NULL, NULL); + + return (void *)NULL; +} + + +void dbgArgValueEvaluator::CancelEval() +{ + m_cancelled = true; + + if (m_conn->GetTxStatus() == PGCONN_TXSTATUS_ACTIVE) + m_conn->CancelExecution(); +} + +dbgArgValueEvaluator::dbgArgValueEvaluator(pgConn *_conn, dlgDirectDbg *_dlg) + : wxThread(wxTHREAD_JOINABLE), m_conn(_conn), m_dlg(_dlg), m_cancelled(false) +{} diff --git a/debugger/frmDebugger.cpp b/debugger/frmDebugger.cpp new file mode 100644 index 0000000..22c5d13 --- /dev/null +++ b/debugger/frmDebugger.cpp @@ -0,0 +1,1024 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDebugger.cpp - debugger +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +#include + +// App headers +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlAuiNotebook.h" +#include "ctl/ctlProgressStatusBar.h" +#include "debugger/dbgController.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/frmDebugger.h" +#include "frm/frmMain.h" +#include "debugger/dbgConst.h" + +#include "images/debugger.pngc" +#include "images/clearAll.pngc" +#include "images/continue.pngc" +#include "images/setBreak.pngc" +#include "images/stepOver.pngc" +#include "images/stepInto.pngc" +#include "images/stop.pngc" + +IMPLEMENT_CLASS(frmDebugger, pgFrame) + +BEGIN_EVENT_TABLE(frmDebugger, pgFrame) + EVT_CLOSE(frmDebugger::OnClose) + EVT_SIZE(frmDebugger::OnSize) + EVT_ERASE_BACKGROUND(frmDebugger::OnEraseBackground) + EVT_AUI_PANE_CLOSE(frmDebugger::OnAuiUpdate) + + EVT_MENU_RANGE(MENU_ID_TOGGLE_BREAK, MENU_ID_STOP, frmDebugger::OnDebugCommand) + + EVT_STC_MARGINCLICK(wxID_ANY, frmDebugger::OnMarginClick) + EVT_STC_UPDATEUI(wxID_ANY, frmDebugger::OnPositionStc) + EVT_LISTBOX(wxID_ANY, frmDebugger::OnSelectFrame) + EVT_GRID_CELL_CHANGED( frmDebugger::OnVarChange) + EVT_MENU(MNU_EXIT, frmDebugger ::OnExit) + EVT_MENU(MENU_ID_VIEW_TOOLBAR, frmDebugger::OnToggleToolBar) + EVT_MENU(MENU_ID_VIEW_STACKPANE, frmDebugger::OnToggleStackPane) + EVT_MENU(MENU_ID_VIEW_OUTPUTPANE, frmDebugger::OnToggleOutputPane) + EVT_MENU(MENU_ID_VIEW_DEFAULTVIEW, frmDebugger::OnDefaultView) + + EVT_MENU(MNU_CONTENTS, frmDebugger::OnContents) + EVT_MENU(MNU_HELP, frmDebugger::OnHelp) +END_EVENT_TABLE() + +//////////////////////////////////////////////////////////////////////////////// +// frmDebugger constructor +// +// frmDebugger manages the user interface for the workstation. This class +// manages the toolbar, menu, status bar, and top-level windows. + +frmDebugger::frmDebugger(frmMain *_parent, dbgController *_controller, + const wxString &_title) : pgFrame(_parent, _title), m_menuBar(NULL), + m_toolBar(NULL), m_viewMenu(NULL), m_debugMenu(NULL), m_statusBar(NULL), + m_parent(_parent), m_controller(_controller), m_stackWindow(NULL), + m_tabWindow(NULL), m_codeViewer(NULL) +{ + dlgName = wxT("frmDebugger"); + RestorePosition(100, 100, 600, 500, 450, 300); + + SetFont(settings->GetSystemFont()); + + m_manager.SetManagedWindow(this); + m_manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + // Define the icon for this window + SetIcon(*debugger_png_ico); + + // Create (and configure) the menu bar, toolbar, and status bar + m_menuBar = SetupMenuBar(); + m_toolBar = SetupToolBar(); + m_statusBar = SetupStatusBar(); + + m_manager.AddPane( + m_toolBar, + wxAuiPaneInfo().Name(wxT("toolBar")).Caption(wxT("Toolbar")) + .ToolbarPane().Top().Row(1).Position(1).LeftDockable(false) + .RightDockable(false)); + + // Now load the layout + wxString perspective; + settings->Read( + wxT("Debugger/frmDebugger/Perspective-") + + wxString(FRMDEBUGGER_PERSPECTIVE_VER), + &perspective, FRMDEBUGGER_DEFAULT_PERSPECTIVE); + + m_manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + m_manager.GetPane(wxT("toolBar")).Caption(_("Toolbar")); + + // Sync the View menu options + m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, m_manager.GetPane(wxT("toolBar")).IsShown()); + + SetupDebugger(); + + m_manager.Update(); +} + + +frmDebugger::~frmDebugger() +{ + // Only save the settings if the window was completely setup + // This may not be the case if the params dialog was displayed, + // and the user hit cancel before the main form opened. + wxAuiPaneInfo &pane = m_manager.GetPane(wxT("sourcePane")); + if (pane.IsOk()) + settings->Write(wxT("Debugger/frmDebugger/Perspective-") + wxString(FRMDEBUGGER_PERSPECTIVE_VER), m_manager.SavePerspective()); + + m_manager.UnInit(); + + if (m_parent) + m_parent->RemoveFrame(this); + + if (m_controller) + { + PopEventHandler(); + delete m_controller; + m_controller = NULL; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnContents() +// OnHelp() +// +// Help menu options +void frmDebugger::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("debugger"), HELP_PGADMIN); +} + + +void frmDebugger::OnHelp(wxCommandEvent &event) +{ + DisplayHelp(wxT("plpgsql"), HELP_POSTGRESQL); +} + + +//////////////////////////////////////////////////////////////////////////////// +// SetupDebugger() +// +// This function creates the debugger views... +// +void frmDebugger::SetupDebugger() +{ + SetFont(settings->GetSystemFont()); + + // Initializing Stack Frame Window + if (m_stackWindow == NULL) + { + m_stackWindow = new ctlStackWindow(this, WINDOW_ID_STACK, wxDefaultPosition, + wxDefaultSize, 0); + + m_manager.AddPane(m_stackWindow, + wxAuiPaneInfo().Name(wxT("stackPane")).Caption(_("Stack pane")).Right() + .MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200))); + } + // Initializing Tab Window + if (m_tabWindow == NULL) + { + m_tabWindow = new ctlTabWindow(this, WINDOW_ID_TABS, wxDefaultPosition, + wxDefaultSize, wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + + m_manager.AddPane(m_tabWindow, + wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom() + .MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300))); + } + // Initialing Code viewer Window + if (m_codeViewer == NULL) + { + m_codeViewer = new ctlSQLBox(this, -1); + + // Set up the markers that we use to indicate the current line and + // the break-point + m_codeViewer->MarkerDefine(MARKER_CURRENT, wxSTC_MARK_ARROW, *wxGREEN, + *wxGREEN); + m_codeViewer->MarkerDefine(MARKER_CURRENT_BG, wxSTC_MARK_BACKGROUND, *wxGREEN, + *wxGREEN); + m_codeViewer->MarkerDefine(MARKER_BREAKPOINT, wxSTC_MARK_CIRCLEPLUS, *wxRED, + *wxRED); + + m_codeViewer->SetMarginWidth(1, 16); + m_codeViewer->SetMarginType(1, wxSTC_MARGIN_SYMBOL); + + // Make sure that the text control tells us when the user clicks in the + // left margin + m_codeViewer->SetMarginSensitive(0, true); + m_codeViewer->SetMarginSensitive(1, true); + m_codeViewer->SetMarginSensitive(2, true); + + m_manager.AddPane(m_codeViewer, + wxAuiPaneInfo().Name(wxT("sourcePane")).Caption(_("Source pane")).Center() + .CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)) + .BestSize(wxSize(350, 200))); + } + + // Make sure the user can't edit the source code for this function + m_codeViewer->SetReadOnly(true); + + // Now (re)load the layout + wxString perspective; + settings->Read( + wxT("Debugger/frmDebugger/Perspective-") + + wxString(FRMDEBUGGER_PERSPECTIVE_VER), &perspective, + FRMDEBUGGER_DEFAULT_PERSPECTIVE); + m_manager.LoadPerspective(perspective, true); + + // And reset the captions + m_manager.GetPane(wxT("sourcePane")).Caption(_("Source pane")); + m_manager.GetPane(wxT("stackPane")).Caption(_("Stack pane")); + m_manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + + // Sync the View menu options + m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, + m_manager.GetPane(wxT("stackPane")).IsShown()); + m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, + m_manager.GetPane(wxT("outputPane")).IsShown()); + + // Enable the options for these controls + m_viewMenu->Enable(MENU_ID_VIEW_OUTPUTPANE, true); + m_viewMenu->Enable(MENU_ID_VIEW_STACKPANE, true); + + m_manager.Update(); + + // force + EnableToolsAndMenus(false); + + PushEventHandler(m_controller); +} + + +//////////////////////////////////////////////////////////////////////////////// +// EnableToolsAndMenus +// +// Enable or disable the debugging tools and menus +// +// Parameters: +// - enable/disable (boolean) +// +void frmDebugger::EnableToolsAndMenus(bool enable) +{ + if (m_toolBar) + { + m_toolBar->EnableTool(MENU_ID_STEP_INTO, enable); + m_toolBar->EnableTool(MENU_ID_STEP_OVER, enable); + m_toolBar->EnableTool(MENU_ID_CONTINUE, + (enable || + (m_controller && m_controller->CanRestart()))); + m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK, enable); + m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK, enable); + m_toolBar->EnableTool(MENU_ID_STOP, enable); + } + + if (m_debugMenu) + { + m_debugMenu->Enable(MENU_ID_STEP_INTO, enable); + m_debugMenu->Enable(MENU_ID_STEP_OVER, enable); + m_debugMenu->Enable(MENU_ID_CONTINUE, + (enable || + (m_controller && m_controller->CanRestart()))); + m_debugMenu->Enable(MENU_ID_TOGGLE_BREAK, enable); + m_debugMenu->Enable(MENU_ID_CLEAR_ALL_BREAK, enable); + m_debugMenu->Enable(MENU_ID_STOP, enable); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// GetLineNo +// +// This function returns the current line-number, where the execution flow +// has been stopped +// +// Returns: +// Current line-number +// +int frmDebugger::GetLineNo() +{ + if (m_codeViewer) + { + return (m_codeViewer->LineFromPosition(m_codeViewer->GetCurrentPos())); + } + else + { + return -1; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// IsBreakpoint(int) +// +// This function helps checking if break-point is set on the particular line +// +// Parameters: +// - line-number +// +// Returns: +// - True if a break-point is set on the line-no, otherwise false +// +bool frmDebugger::IsBreakpoint(int _lineNo) +{ + if (m_codeViewer) + return (m_codeViewer->MarkerGet(_lineNo) & + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT) ? true : false); + else + return false; +} + + +//////////////////////////////////////////////////////////////////////////////// +// ClearAllBreakpoints +// +// This function clears all the break-points +// +void frmDebugger::ClearAllBreakpoints() +{ + int lineNo = -1; + bool updateBreakpoints = false; + + if (m_codeViewer) + { + while((lineNo = m_codeViewer->MarkerNext(lineNo + 1, + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))) != -1) + { + // Clear the break-point at particular location + m_controller->ClearBreakpoint(lineNo); + updateBreakpoints = true; + } + + // Update break-points only if required + if (updateBreakpoints) + m_controller->UpdateBreakpoints(); + } +} + + +void frmDebugger::ClearBreakpointMarkers() +{ + int lineNo = 0; + if (m_codeViewer) + { + while((lineNo = m_codeViewer->MarkerNext(lineNo, + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT))) != -1) + { + m_codeViewer->MarkerDelete(lineNo++, MARKER_BREAKPOINT); + } + } +} + + +void frmDebugger::MarkBreakpoint(int _line) +{ + if (m_codeViewer) + { + m_codeViewer->MarkerAdd(_line, MARKER_BREAKPOINT); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// UnhilightCurrentLine +// +// This function removes the hilight from the current line +// +void frmDebugger::UnhilightCurrentLine() +{ + if (m_codeViewer) + { + int lineNo + = m_codeViewer->MarkerNext(0, MARKERINDEX_TO_MARKERMASK(MARKER_CURRENT)); + + if(lineNo != -1) + { + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT); + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT_BG); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnDebugCommand(wxCommandEvent) +// +// This function handles the user clicks one of the debugger tools and menus +// and take care of actions requires. These events are toggle break-point, +// clear all break-points, debugging continue, step-in, step-over and stop +// debugging. +// +// Parameters +// - event object +// +void frmDebugger::OnDebugCommand(wxCommandEvent &_event) +{ + switch(_event.GetId()) + { + case MENU_ID_TOGGLE_BREAK: + { + int lineNo = GetLineNo(); + + // This event should have not been called + if (lineNo == -1) + return; + + // The user wants to set or clear a breakpoint at the line that + // contains the insertion point (the caret) + if (IsBreakpoint(lineNo)) + { + m_controller->ClearBreakpoint(lineNo); + } + else + { + m_controller->SetBreakpoint(lineNo); + } + m_controller->UpdateBreakpoints(); + } + break; + + case MENU_ID_CLEAR_ALL_BREAK: + // The user wants to clear all the breakpoint + ClearAllBreakpoints(); + + break; + + case MENU_ID_CONTINUE: + // The user wants to continue execution (as opposed to + // single-stepping through the code). Unhilite all + // variables and tell the debugger server to continue. + if (m_controller) + { + if (m_controller->CanRestart()) + { + m_controller->Start(); + } + else + { + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target (continue)...")); + m_controller->Countinue(); + UnhilightCurrentLine(); + } + } + break; + + case MENU_ID_STEP_OVER: + // The user wants to step-over a function invocation (or + // just single-step). Unhilite all variables and tell the + // debugger server to step-over + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target (step over)...")); + m_controller->StepOver(); + UnhilightCurrentLine(); + + break; + + case MENU_ID_STEP_INTO: + // The user wants to step-into a function invocation (or + // just single-step). Unhilite all variables and tell the + // debugger server to step-into + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target (step into)...")); + m_controller->StepInto(); + UnhilightCurrentLine(); + + break; + + case MENU_ID_STOP: + EnableToolsAndMenus(false); + LaunchWaitingDialog(_("Waiting for target to stop execution...")); + m_controller->Stop(); + UnhilightCurrentLine(); + + break; + + default: + break; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnSelectFrame() +// +// This function handles the user click on one of the stack-frames, and +// asks the debugger server to switch to that frame, update the breakpoint +// markers, and send a list of variables that are in-scope in the selected +// frame +// +// Parametes: +// Selection Event Object +// +void frmDebugger::OnSelectFrame(wxCommandEvent &_ev) +{ + if(_ev.GetSelection() != -1) + { + if (!m_controller->SelectFrame(_ev.GetSelection())) + { + // Reset to previous selection + dbgModel *model = m_controller->GetModel(); + m_stackWindow->SelectFrame(model->GetDisplayedPackage(), + model->GetDisplayedFunction()); + } + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnMarginClick() +// +// This function handles the user clicks in the margin to the left of a +// line of source code. We use the margin to display breakpoint indicators +// so it makes sense that if you click on an breakpoint indicator, we will +// clear that breakpoint. If you click on a spot that does not contain a +// breakpoint indicator (but it's still in the margin), we create a new +// breakpoint at that line +// +// Parametes: +// Selection Event Object +// +void frmDebugger::OnMarginClick(wxStyledTextEvent &event) +{ + int lineNo; + + // Check that the user clicked on the line number or breakpoint margin + // We don't want to set a breakpoint when the user folds/unfolds code + if (!(event.GetMargin() == 0 || event.GetMargin() == 1)) + return; + + lineNo = m_codeViewer->LineFromPosition(event.GetPosition()); + + if (lineNo <= 0) + return; + + // If we already have a breakpoint at the clickpoint, disable it, otherwise + // create a new breakpoint + if(m_codeViewer->MarkerGet(lineNo) & + MARKERINDEX_TO_MARKERMASK(MARKER_BREAKPOINT)) + { + m_controller->ClearBreakpoint(lineNo); + } + else + { + m_controller->SetBreakpoint(lineNo); + } + m_controller->UpdateBreakpoints(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnPositionStc() +// +// This function handles the event called when the user positions the cursor +// in the code viewer. We will update the current line number etc in the +// status bar. +// +// Parametes: +// wxStyledTextEvent Object +// +void frmDebugger::OnPositionStc(wxStyledTextEvent &event) +{ + if (m_codeViewer) + { + wxString strPos; + + int pos = m_codeViewer->GetCurrentPos(); + + strPos.Printf(_("Ln %d Col %d Ch %d"), m_codeViewer->LineFromPosition(pos) + 1, + m_codeViewer->GetColumn(pos) + 1, pos + 1); + + GetStatusBar()->SetStatusText(strPos, 3); + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnVarChange() +// +// This functions handles the event occurred when the user edits a variable +// value. Submit the changed value to the debugger server +// +void frmDebugger::OnVarChange(wxGridEvent &_ev) +{ + ctlVarWindow *varWin = NULL; + wxString varName, varValue; + + if(_ev.GetId() == ID_PARAMGRID) + { + varWin = GetParamWindow(false); + varName = varWin->GetVarName(_ev.GetRow()); + varValue = varWin->GetVarValue(_ev.GetRow()); + } + else if (_ev.GetId() == ID_VARGRID) + { + varWin = GetVarWindow(false); + varName = varWin->GetVarName(_ev.GetRow()); + varValue = varWin->GetVarValue(_ev.GetRow()); + } + else if (_ev.GetId() == ID_PKGVARGRID) + { + varWin = GetPkgVarWindow(false); + varName = wxT("@") + varWin->GetVarName(_ev.GetRow()); + varValue = varWin->GetVarValue(_ev.GetRow()); + } + else + { + // Theorically - the execution flow must not reach at this point. + return; + } + + m_controller->DepositValue(varName, varValue); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnSize() +// +// This event handler is called when a resize event occurs (that is, when +// wxWidgets needs to size the application window) +// +void frmDebugger::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + + +void frmDebugger::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// setupToolBar() +// +// This function creates the standard toolbar +// +ctlMenuToolbar *frmDebugger::SetupToolBar(void) +{ + m_toolBar = new ctlMenuToolbar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + + m_toolBar->SetToolBitmapSize(wxSize(16, 16)); + + m_toolBar->AddTool(MENU_ID_STEP_INTO, wxEmptyString, *stepInto_png_bmp, + _("Step into")); + m_toolBar->AddTool(MENU_ID_STEP_OVER, wxEmptyString, *stepOver_png_bmp, + _("Step over")); + m_toolBar->AddTool(MENU_ID_CONTINUE, wxEmptyString, *continue_png_bmp, + _("Continue/Start")); + m_toolBar->AddSeparator(); + m_toolBar->AddTool(MENU_ID_TOGGLE_BREAK, wxEmptyString, *setBreak_png_bmp, + _("Toggle breakpoint")); + m_toolBar->AddTool(MENU_ID_CLEAR_ALL_BREAK, wxEmptyString, *clearAll_png_bmp, + _("Clear all breakpoints")); + m_toolBar->AddSeparator(); + m_toolBar->AddTool(MENU_ID_STOP, wxEmptyString, *stop_png_bmp, + _("Stop debugging")); + + m_toolBar->EnableTool(MENU_ID_STEP_INTO, false); + m_toolBar->EnableTool(MENU_ID_STEP_OVER, false); + m_toolBar->EnableTool(MENU_ID_CONTINUE, false); + m_toolBar->EnableTool(MENU_ID_TOGGLE_BREAK, false); + m_toolBar->EnableTool(MENU_ID_CLEAR_ALL_BREAK, false); + m_toolBar->EnableTool(MENU_ID_STOP, false); + + m_toolBar->Realize(); + + return(m_toolBar); +} + + +//////////////////////////////////////////////////////////////////////////////// +// SetupStatusBar() +// +// This function initializes the status bar (we don't have one at the moment +// so this function simply returns) +// +ctlProgressStatusBar *frmDebugger::SetupStatusBar(void) +{ + ctlProgressStatusBar *bar = new ctlProgressStatusBar(this, false); + int widths[] = { -1, ctlProgressStatusBar::ms_progressbar_width, ctlProgressStatusBar::ms_progressstatus_width, 190}; + + bar->SetFieldsCount(4); + bar->SetStatusWidths(4, widths); + this->SetStatusBar(bar); + + return(bar); +} + + +//////////////////////////////////////////////////////////////////////////////// +// SetupMenuBar() +// +// This function creates the standard menu bar +// +wxMenuBar *frmDebugger::SetupMenuBar(void) +{ + m_menuBar = new wxMenuBar; + + // Don't append the File menu on Mac, as the Exit option + // will be moved to the application menu, leaving File empty. +#ifndef __WXMAC__ + wxMenu *fileMenu = new wxMenu; + fileMenu->Append(MNU_EXIT, _("E&xit\tAlt-F4"), _("Exit debugger window")); + + m_menuBar->Append(fileMenu, _("&File")); +#endif + + m_debugMenu = new wxMenu; +#ifdef __WXGTK__ + // + // F10 is treated as a System menu under GTK. Hence, we will use Ctrl+F10 for + // "step over" operation under GTK, instead of F10. + // + // To make the behavior consitent, we will also use Ctrl+ for all the operations + // under GTK. (i.e. Step into, Step over, Continue, Toggle breakpoint, Stop + // debugging) + // + // Please follow this link for more details: + // http://trac.wxwidgets.org/ticket/2404 + // + m_debugMenu->Append(MENU_ID_STEP_INTO, _("Step into\tCtrl+F11")); + m_debugMenu->Append(MENU_ID_STEP_OVER, _("Step over\tCtrl+F10")); + m_debugMenu->Append(MENU_ID_CONTINUE, _("Continue/Start\tCtrl+F5")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_TOGGLE_BREAK, _("Toggle breakpoint\tCtrl+F9")); + m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK, _("Clear all breakpoints\tCtrl+Shift+F9")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_STOP, _("Stop debugging\tCtrl+F8")); +#else + m_debugMenu->Append(MENU_ID_STEP_INTO, _("Step into\tF11")); + m_debugMenu->Append(MENU_ID_STEP_OVER, _("Step over\tF10")); + m_debugMenu->Append(MENU_ID_CONTINUE, _("Continue/Start\tF5")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_TOGGLE_BREAK, _("Toggle breakpoint\tF9")); + m_debugMenu->Append(MENU_ID_CLEAR_ALL_BREAK, _("Clear all breakpoints\tCtrl+Shift+F9")); + m_debugMenu->AppendSeparator(); + m_debugMenu->Append(MENU_ID_STOP, _("Stop debugging\tF8")); +#endif //__WXGTK__ + m_debugMenu->Enable(MENU_ID_STEP_INTO, false); + m_debugMenu->Enable(MENU_ID_STEP_OVER, false); + m_debugMenu->Enable(MENU_ID_CONTINUE, false); + m_debugMenu->Enable(MENU_ID_TOGGLE_BREAK, false); + m_debugMenu->Enable(MENU_ID_CLEAR_ALL_BREAK, false); + m_debugMenu->Enable(MENU_ID_STOP, false); + m_menuBar->Append(m_debugMenu, _("&Debug")); + + m_viewMenu = new wxMenu; + m_viewMenu->Append(MENU_ID_VIEW_OUTPUTPANE, _("&Output pane\tCtrl-Alt-O"), _("Show or hide the output pane."), wxITEM_CHECK); + m_viewMenu->Append(MENU_ID_VIEW_STACKPANE, _("&Stack pane\tCtrl-Alt-S"), _("Show or hide the stack pane."), wxITEM_CHECK); + m_viewMenu->Append(MENU_ID_VIEW_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + m_viewMenu->AppendSeparator(); + m_viewMenu->Append(MENU_ID_VIEW_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + m_viewMenu->Enable(MENU_ID_VIEW_OUTPUTPANE, false); + m_viewMenu->Enable(MENU_ID_VIEW_STACKPANE, false); + m_menuBar->Append(m_viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); + m_menuBar->Append(helpMenu, _("&Help")); + + SetMenuBar(m_menuBar); + + return(m_menuBar); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnClose() +// +// wxWidgets invokes this event handler when the user closes the main window + +void frmDebugger::OnClose(wxCloseEvent &_ev) +{ + if (!m_controller->CanRestart() && _ev.CanVeto()) + { + if (wxMessageBox( + _("Are you sure you wish to abort the debugging session?\nThis will abort the function currently being debugged."), + _("Close debugger"), wxICON_QUESTION | wxYES_NO) != wxYES) + { + _ev.Veto(); + + return; + } + } + + if (!m_controller->CloseDebugger() && _ev.CanVeto()) + { + _ev.Veto(); + + return; + } + + _ev.Skip(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnExit() +// +// Close the debugger + +void frmDebugger::OnExit(wxCommandEvent &event) +{ + Close(); +} + + +//////////////////////////////////////////////////////////////////////////////// +// OnToggleToolBar() +// +// Turn the tool bar on or off +void frmDebugger::OnToggleToolBar(wxCommandEvent &event) +{ + if (m_viewMenu->IsChecked(MENU_ID_VIEW_TOOLBAR)) + m_manager.GetPane(wxT("toolBar")).Show(true); + else + m_manager.GetPane(wxT("toolBar")).Show(false); + + m_manager.Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnToggleStackPane() +// +// Turn the tool bar on or off +void frmDebugger::OnToggleStackPane(wxCommandEvent &event) +{ + if (m_viewMenu->IsChecked(MENU_ID_VIEW_STACKPANE)) + m_manager.GetPane(wxT("stackPane")).Show(true); + else + m_manager.GetPane(wxT("stackPane")).Show(false); + + m_manager.Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnToggleOutputPane() +// +// Turn the tool bar on or off +void frmDebugger::OnToggleOutputPane(wxCommandEvent &event) +{ + if (m_viewMenu->IsChecked(MENU_ID_VIEW_OUTPUTPANE)) + m_manager.GetPane(wxT("outputPane")).Show(true); + else + m_manager.GetPane(wxT("outputPane")).Show(false); + + m_manager.Update(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnAuiUpdate() +// +// Update the view menu to reflect AUI changes +void frmDebugger::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("toolBar")) + { + m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, false); + } + else if(event.pane->name == wxT("stackPane")) + { + m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, false); + } + else if(event.pane->name == wxT("outputPane")) + { + m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, false); + } + event.Skip(); +} + +//////////////////////////////////////////////////////////////////////////////// +// OnDefaultView() +// +// Reset the AUI view to the default +void frmDebugger::OnDefaultView(wxCommandEvent &event) +{ + m_manager.LoadPerspective(FRMDEBUGGER_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + m_manager.GetPane(wxT("toolBar")).Caption(_("Toolbar")); + m_manager.GetPane(wxT("stackPane")).Caption(_("Stack pane")); + m_manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + + // tell the m_manager to "commit" all the changes just made + m_manager.Update(); + + // Sync the View menu options + m_viewMenu->Check(MENU_ID_VIEW_TOOLBAR, m_manager.GetPane(wxT("toolBar")).IsShown()); + m_viewMenu->Check(MENU_ID_VIEW_STACKPANE, m_manager.GetPane(wxT("stackPane")).IsShown()); + m_viewMenu->Check(MENU_ID_VIEW_OUTPUTPANE, m_manager.GetPane(wxT("outputPane")).IsShown()); +} + + +void frmDebugger::HighlightLine(int _lineNo) +{ + int lineNo = m_codeViewer->MarkerNext( + 0, MARKERINDEX_TO_MARKERMASK( MARKER_CURRENT)); + + if (lineNo != -1) + { + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT); + m_codeViewer->MarkerDelete(lineNo, MARKER_CURRENT_BG); + } + + // Add the current-line indicator to the current line of code + m_codeViewer->MarkerAdd(_lineNo, MARKER_CURRENT); + m_codeViewer->MarkerAdd(_lineNo, MARKER_CURRENT_BG); + + // Scroll the source code listing (if required) to make sure + // that this line of code is visible + // + // (NOTE: we set the anchor and the caret to the same position to avoid + // creating a selection region) + int pos = m_codeViewer->PositionFromLine(_lineNo); + + m_codeViewer->SetAnchor(pos); + m_codeViewer->SetCurrentPos(pos); + + m_codeViewer->EnsureCaretVisible(); +} + +void frmDebugger::DisplaySource(dbgCachedStack &_cached) +{ + dbgModel *model = m_controller->GetModel(); + + m_codeViewer->SetFocus(); + + if (model->RequireDisplayUpdate()) + { + ctlVarWindow *varWin = NULL; + if ((varWin = GetVarWindow(false)) != NULL) + { + varWin->DelVar(); + } + if ((varWin = GetParamWindow(false)) != NULL) + { + varWin->DelVar(); + } + if ((varWin = GetPkgVarWindow(false)) != NULL) + { + varWin->DelVar(); + } + + model->GetDisplayedFunction() = _cached.m_func; + model->GetDisplayedPackage() = _cached.m_pkg; + + // Now erase any old code and write out the new listing + m_codeViewer->SetReadOnly(false); + + m_codeViewer->SetText(_cached.m_source); + m_codeViewer->Colourise(0, _cached.m_source.Length()); + + m_codeViewer->SetReadOnly(true); + } + HighlightLine(model->GetCurrLineNo()); +} + + +void frmDebugger::SetStatusText(const wxString &_status) +{ + m_statusBar->SetStatusText(_status, 0); +} + + +void frmDebugger::LaunchWaitingDialog(const wxString &msg) +{ + dbgModel *model = m_controller->GetModel(); + wxString strStatus, + strTargetPid = model->GetTargetPid(), + strTarget = model->GetTarget()->GetQualifiedName(); + + if (msg.IsEmpty()) + { + if (strTargetPid != wxT("NULL")) + { + strStatus = + wxString::Format( + _("Waiting for the session (pid:%s) to invoke the specified targets."), + strTargetPid.c_str()); + } + else + { + strStatus = + wxString::Format( + _("Waiting for another session to invoke the target - \"%s\""), strTarget.c_str()); + } + } + else + { + strStatus = msg; + } + m_statusTxt = strStatus; + + SetStatusText(strStatus); + m_statusBar->ShowProgress(); +} + + +void frmDebugger::CloseProgressBar() +{ + if (!m_statusTxt.IsEmpty()) + { + SetStatusText(m_statusTxt + wxT(" Done")); + m_statusTxt = wxT(""); + } + m_statusBar->StopProgress(); +} diff --git a/debugger/module.mk b/debugger/module.mk new file mode 100644 index 0000000..afb13ec --- /dev/null +++ b/debugger/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/debugger/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + debugger/ctlMessageWindow.cpp \ + debugger/ctlResultGrid.cpp \ + debugger/ctlStackWindow.cpp \ + debugger/ctlTabWindow.cpp \ + debugger/ctlVarWindow.cpp \ + debugger/dbgBreakPoint.cpp \ + debugger/dbgController.cpp \ + debugger/dbgEvents.cpp \ + debugger/dbgModel.cpp \ + debugger/dbgTargetInfo.cpp \ + debugger/debugger.cpp \ + debugger/dlgDirectDbg.cpp \ + debugger/frmDebugger.cpp + +EXTRA_DIST += \ + debugger/module.mk + + diff --git a/dlg/dlgAddFavourite.cpp b/dlg/dlgAddFavourite.cpp new file mode 100644 index 0000000..061083c --- /dev/null +++ b/dlg/dlgAddFavourite.cpp @@ -0,0 +1,185 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAddFavourite.cpp - Add a favourite +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgAddFavourite.h" +#include "db/pgConn.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" +#include "ctl/ctlTree.h" + +#include "images/folder.pngc" + +#include "utils/favourites.h" + +#include + +BEGIN_EVENT_TABLE(dlgAddFavourite, pgDialog) + EVT_TEXT(XRCID("txtTitle"), dlgAddFavourite::OnChange) + EVT_TREE_SEL_CHANGED(XRCID("trLocation"), dlgAddFavourite::OnTreeChange) + EVT_BUTTON (wxID_OK, dlgAddFavourite::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgAddFavourite::OnCancel) + EVT_BUTTON (XRCID("btnNewFolder"), dlgAddFavourite::OnNewFolder) +END_EVENT_TABLE() + + +#define btnOK CTRL_BUTTON("wxID_OK") +#define txtTitle CTRL_TEXT("txtTitle") +#define trLocation CTRL_TREE("trLocation") +#define btnNewFolder CTRL_BUTTON("btnNewFolder") + + +dlgAddFavourite::dlgAddFavourite(wxWindow *parent, queryFavouriteFolder *favourites) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgAddFavourite")); + RestorePosition(); + + anythingChanged = false; + + this->favourites = favourites; + + wxImageList *imgList = new wxImageList(16, 16, true, 2); + imgList->Add(*folder_png_ico); + trLocation->AssignImageList(imgList); + + trLocation->AddRoot(_("Favourites"), 0); + trLocation->SelectItem(trLocation->GetRootItem()); + favourites->AppendAllToTree(trLocation, trLocation->GetRootItem(), true); + trLocation->Expand(trLocation->GetRootItem()); +} + +int dlgAddFavourite::AddFavourite(wxString newtext) +{ + int ret = 1; + int r = ShowModal(); + if (r != wxID_OK) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + wxString title = txtTitle->GetValue().Trim(); + if (title.IsEmpty()) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + if (!trLocation->GetSelection().IsOk()) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + queryFavouriteFolder *fld = (queryFavouriteFolder *)favourites->FindTreeItem(trLocation->GetSelection()); + + if (!fld) + { + if (anythingChanged) + // Need rollback! + ret = -1; + else + ret = 0; + } + + if (r == wxID_OK) + fld->AddNewFavourite(title, newtext); + return ret; +} + +dlgAddFavourite::~dlgAddFavourite() +{ + SavePosition(); +} + + +void dlgAddFavourite::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + EndModal(wxID_OK); +} + + +void dlgAddFavourite::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgAddFavourite::OnChange(wxCommandEvent &ev) +{ + bool ok = true; + + if (txtTitle->GetValue().Trim().IsEmpty()) + ok = false; + else if (!trLocation->GetSelection().IsOk()) + ok = false; + else if (favourites->FindTreeItem(trLocation->GetSelection()) == NULL) + ok = false; + + btnOK->Enable(ok); +} + +void dlgAddFavourite::OnTreeChange(wxTreeEvent &ev) +{ + wxCommandEvent evt; + OnChange(evt); +} + +void dlgAddFavourite::OnNewFolder(wxCommandEvent &ev) +{ + if (!trLocation->GetSelection().IsOk()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + if (item->GetId() != -2) + return; + + wxTextEntryDialog dlg(this, _("Enter name of new folder"), _("Create new favourites folder")); + if (dlg.ShowModal() != wxID_OK) + return; + + wxString title = dlg.GetValue().Trim(); + if (title.IsEmpty()) + return; + + queryFavouriteFolder *fld = (queryFavouriteFolder *)item; + if (fld->ContainsFolder(title)) + { + wxMessageBox(_("A folder with the specified name already exists.")); + return; + } + + + queryFavouriteFolder *newfld = fld->AddNewFolder(dlg.GetValue()); + newfld->SetTreeId(trLocation->AppendItem(trLocation->GetSelection(), title, 0)); + trLocation->Expand(fld->GetTreeId()); + anythingChanged = true; +} diff --git a/dlg/dlgAggregate.cpp b/dlg/dlgAggregate.cpp new file mode 100644 index 0000000..1c62f55 --- /dev/null +++ b/dlg/dlgAggregate.cpp @@ -0,0 +1,594 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAggregate.cpp - Aggregate properties dialog +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgAggregate.h" +#include "schema/pgSchema.h" +#include "schema/pgAggregate.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" +#include "frm/frmMain.h" +#include "schema/pgUser.h" +#include "schema/pgGroup.h" + +#include "images/aggregate.pngc" + +// pointer to controls +#define cbInputType CTRL_COMBOBOX2("cbInputType") +#define lstInputTypes CTRL_LISTCTRL("lstInputTypes") +#define cbStateType CTRL_COMBOBOX2("cbStateType") +#define cbStateFunc CTRL_COMBOBOX("cbStateFunc") +#define cbFinalFunc CTRL_COMBOBOX("cbFinalFunc") +#define cbSortOp CTRL_COMBOBOX("cbSortOp") +#define txtInitial CTRL_TEXT("txtInitial") +#define btnAddType CTRL_BUTTON("btnAddType") +#define btnRemoveType CTRL_BUTTON("btnRemoveType") + +dlgProperty *pgAggregateFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgAggregate(this, frame, (pgAggregate *)node, (pgSchema *)parent); +} + +BEGIN_EVENT_TABLE(dlgAggregate, dlgTypeProperty) + EVT_TEXT(XRCID("cbInputType"), dlgAggregate::OnChangeTypeBase) + EVT_TEXT(XRCID("cbStateType"), dlgAggregate::OnChangeTypeState) + EVT_COMBOBOX(XRCID("cbStateType"), dlgAggregate::OnChangeType) + EVT_COMBOBOX(XRCID("cbStateFunc"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbSortOp"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbStateFunc"), dlgProperty::OnChange) + EVT_BUTTON(XRCID("btnAddType"), dlgAggregate::OnAddInputType) + EVT_BUTTON(XRCID("btnRemoveType"), dlgAggregate::OnRemoveInputType) + EVT_LIST_ITEM_SELECTED(XRCID("lstInputTypes"), dlgAggregate::OnSelectInputType) + EVT_BUTTON(CTL_ADDPRIV, dlgAggregate::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgAggregate::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgAggregate::OnChangeSize) +#endif +END_EVENT_TABLE(); + +dlgAggregate::dlgAggregate(pgaFactory *f, frmMain *frame, pgAggregate *agg, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgAggregate")) +{ + schema = sch; + aggregate = agg; + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + /* Aggregate Privileges */ + securityChanged = false; + if (agg) + connection = agg->GetConnection(); + securityPage = new ctlSecurityPanel(nbNotebook, wxT("EXECUTE"), "X", frame->GetImageList()); + if (connection && (!agg || agg->CanCreate())) + { + // Fetch Groups Information + pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + if (agg) + { + wxString strAcl = agg->GetAcl(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } + } + else + securityPage->Disable(); +} + +pgObject *dlgAggregate::GetObject() +{ + return aggregate; +} + +int dlgAggregate::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + + if (!connection->BackendMinimumVersion(8, 1)) + cbSortOp->Disable(); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(aggregate); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgAggregate::OnChange)); + } + else + seclabelPage->Disable(); + + lstInputTypes->InsertColumn(0, _("Input types"), wxLIST_FORMAT_LEFT, lstInputTypes->GetSize().x - 10); + + if (aggregate) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(7, 4)); + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + + for (unsigned int x = 0; x < aggregate->GetInputTypesArray().Count(); x++ ) + { + lstInputTypes->InsertItem(x, aggregate->GetInputTypesArray().Item(x)); + AddType(wxT(" "), 0, aggregate->GetInputTypesArray().Item(x)); + } + + cbStateType->Append(aggregate->GetStateType()); + cbStateType->SetSelection(0); + + cbStateFunc->Append(aggregate->GetStateFunction()); + cbStateFunc->SetSelection(0); + cbFinalFunc->Append(aggregate->GetFinalFunction()); + cbFinalFunc->SetSelection(0); + + cbSortOp->Append(aggregate->GetSortOp()); + cbSortOp->SetSelection(0); + + txtInitial->SetValue(aggregate->GetInitialCondition()); + + cbInputType->Disable(); + btnAddType->Disable(); + btnRemoveType->Disable(); + cbStateFunc->Disable(); + cbStateType->Disable(); + cbFinalFunc->Disable(); + cbSortOp->Disable(); + txtInitial->Disable(); + } + else + { + // create mode + AddType(wxT(" "), PGOID_TYPE_ANY, wxT("\"any\"")); + cbInputType->Append(wxT("ANY")); + + FillDatatype(cbInputType, cbStateType, false); + btnRemoveType->Disable(); + } + + securityPage->SetConnection(connection); + + if (securityPage->cbGroups) + { + // Fetch Groups Information + for ( unsigned int index = 0; index < groups.Count();) + securityPage->cbGroups->Append(wxT("group ") + groups[index++]); + + // Fetch Users Information + if (settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups); + } + } + securityPage->lbPrivileges->GetParent()->Layout(); + + return dlgProperty::Go(modal); +} + +pgObject *dlgAggregate::CreateObject(pgCollection *collection) +{ + pgObject *obj = aggregateFactory.CreateObjects(collection, 0, + wxT("\n AND proname=") + qtDbString(GetName()) + + wxT("\n AND pronamespace=") + schema->GetOidStr()); + + return obj; +} + +#ifdef __WXMAC__ +void dlgAggregate::OnChangeSize(wxSizeEvent &ev) +{ + lstInputTypes->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +void dlgAggregate::CheckChange() +{ + bool enable = true; + if (aggregate) + { + enable = GetName() != aggregate->GetName() + || cbSchema->GetValue() != aggregate->GetSchema()->GetName() + || txtComment->GetValue() != aggregate->GetComment() + || cbOwner->GetValue() != aggregate->GetOwner(); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + // For pre 8.2 servers, we can only have one input type. + if (!connection->BackendMinimumVersion(8, 2)) + { + if (lstInputTypes->GetItemCount() >= 1) + btnAddType->Disable(); + else + btnAddType->Enable(); + } + + // Multi parameter aggregates cannot have sort ops. + if (connection->BackendMinimumVersion(8, 2)) + { + if (lstInputTypes->GetItemCount() > 1) + { + cbSortOp->SetValue(wxEmptyString); + cbSortOp->Disable(); + } + else + cbSortOp->Enable(); + } + + wxString name = GetName(); + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbStateType->GetGuessedSelection() >= 0, _("Please select state datatype.")); + CheckValid(enable, cbStateFunc->GetCurrentSelection() >= 0, _("Please specify state function.")); + } + EnableOK(enable || securityChanged); +} + +void dlgAggregate::OnChangeTypeBase(wxCommandEvent &ev) +{ + cbInputType->GuessSelection(ev); + OnChangeType(ev); +} + +void dlgAggregate::OnChangeTypeState(wxCommandEvent &ev) +{ + cbStateType->GuessSelection(ev); + OnChangeType(ev); +} + +void dlgAggregate::OnChangeType(wxCommandEvent &ev) +{ + cbStateFunc->Clear(); + cbFinalFunc->Clear(); + cbSortOp->Clear(); + + pgSet *set; + wxString qry; + + // Get the possible state functions. They must return the state type, and take + // input_types + 1 parameters, the first of which is of the state type. + // If there are no input_types specified, assume "ANY" for a count(*) style aggregate. + if (lstInputTypes->GetItemCount() > 0 && cbStateType->GetGuessedSelection() >= 0) + { + set = connection->ExecuteSet( + wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_type t ON t.oid=p.prorettype\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype = ") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + + wxT("\n AND prokind <> 'a'") + wxT("\n AND proargtypes = '") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + wxT(" ") + GetInputTypesOidList() + wxT("'")); + + if (set) + { + while (!set->Eof()) + { + cbStateFunc->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")), + database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + + set->MoveNext(); + } + delete set; + } + + // Get the possible final_func options. This may be nothing, or a + // function taking an argument of state_type + cbFinalFunc->Append(wxT(" ")); + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_type t ON t.oid=p.prorettype\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proisagg = FALSE") + wxT("\n AND proargtypes = '") + GetTypeOid(cbStateType->GetGuessedSelection() + 1) + wxT("'")); + + if (set) + { + while (!set->Eof()) + { + cbFinalFunc->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")), + database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + + set->MoveNext(); + } + delete set; + } + + // Get the sort operators. This is only valid for a single arguement operator. + cbSortOp->Append(wxT(" "), wxEmptyString); + + set = connection->ExecuteSet( + wxT("SELECT oprname, nspname\n") + wxT(" FROM pg_operator op\n") + wxT(" JOIN pg_namespace nsp on nsp.oid=oprnamespace\n") + wxT(" WHERE oprleft = ") + NumToStr(GetInputTypeOid(0)) + wxT("\n") + wxT(" AND oprright = ") + NumToStr(GetInputTypeOid(0)) + wxT("\n")); + + if (set) + { + while (!set->Eof()) + { + wxString key = database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("oprname"))); + wxString txt = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("oprname")); + cbSortOp->Append(txt, key); + set->MoveNext(); + } + delete set; + } + } + + CheckChange(); +} + +wxString dlgAggregate::GetSql() +{ + wxString sql, name; + + if (aggregate) + { + // edit mode + name = schema->GetQuotedPrefix() + qtIdent(GetName()) + wxT("(") + GetInputTypesList() + wxT(")"); + + AppendNameChange(sql, wxT("AGGREGATE ") + aggregate->GetQuotedFullName()); + AppendOwnerChange(sql, wxT("AGGREGATE ") + name); + AppendSchemaChange(sql, wxT("AGGREGATE ") + name); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + if (connection->BackendMinimumVersion(8, 2)) + { + sql = wxT("CREATE AGGREGATE ") + name + + wxT("(") + GetInputTypesList() + wxT(") (\n"); + } + else + { + sql = wxT("CREATE AGGREGATE ") + name + + wxT("(\n BASETYPE=") + GetInputTypesList() + wxT(",\n"); + } + + sql += wxT(" SFUNC=") + cbStateFunc->GetStringKey() + + wxT(",\n STYPE=") + GetQuotedTypename(cbStateType->GetGuessedSelection() + 1); // skip "any" type + + if (cbFinalFunc->GetCurrentSelection() > 0) + { + sql += wxT(",\n FINALFUNC=") + + cbFinalFunc->GetStringKey(); + } + wxString initial = txtInitial->GetValue().Strip(wxString::both); + if (!initial.IsEmpty()) + { + if (initial == wxT("''")) // Empty string + sql += wxT(",\n INITCOND=''"); + else if (initial == wxT("\\'\\'")) // Pair of quotes + sql += wxT(",\n INITCOND=''''''"); + else + sql += wxT(",\n INITCOND=") + qtDbString(initial); + } + + if (!cbSortOp->GetValue().IsEmpty()) + { + wxString opr = cbSortOp->GetStringKey(); + if (!opr.IsEmpty()) + sql += wxT(",\n SORTOP=") + opr; + } + + sql += wxT("\n);\n"); + + AppendOwnerNew(sql, wxT("AGGREGATE ") + name + wxT("(") + GetInputTypesList() + wxT(")")); + } + + AppendComment(sql, wxT("AGGREGATE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + + wxT("(") + GetInputTypesList() + wxT(")"), aggregate); + + sql += securityPage->GetGrant(wxT("X"), + wxT("FUNCTION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + wxT("(") + GetInputTypesList() + wxT(")"), + ¤tAcl); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("AGGREGATE"), + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + + wxT("(") + GetInputTypesList() + wxT(")")); + + return sql; +} + +// Return the list of input types +wxString dlgAggregate::GetInputTypesList() +{ + wxString types; + + for (int i = 0; i < lstInputTypes->GetItemCount(); i++) + { + if (i > 0) + types += wxT(", "); + + if (lstInputTypes->GetItemText(i) == wxT("ANY") || lstInputTypes->GetItemText(i) == wxT("*")) + return wxT("*"); + else + types += qtTypeIdent(lstInputTypes->GetItemText(i)); + } + return types; +} + +void dlgAggregate::OnAddInputType(wxCommandEvent &ev) +{ + if (cbInputType->GetValue() != wxEmptyString) + { + if (cbInputType->GetValue() == wxT("ANY") && lstInputTypes->GetItemCount() > 0) + { + wxLogError(_("The ANY pseudo-datatype cannot be used in multi parameter aggregates.")); + return; + } + + wxListItem itm; + itm.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT); + + itm.SetData(StrToLong(GetTypeOid(cbInputType->GetGuessedSelection()))); + itm.SetText(cbInputType->GetValue()); + + lstInputTypes->InsertItem(itm); + + if (cbInputType->GetValue() == wxT("ANY")) + btnAddType->Disable(); + + OnChangeType(ev); + } +} + +void dlgAggregate::OnRemoveInputType(wxCommandEvent &ev) +{ + long pos = lstInputTypes->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);; + if (pos >= 0) + { + lstInputTypes->DeleteItem(pos); + + OnChangeType(ev); + btnRemoveType->Disable(); + + // Re-enable the Add button, in case it was disabled because + // ANY was specified. + btnAddType->Enable(); + } +} + +void dlgAggregate::OnSelectInputType(wxListEvent &ev) +{ + if (!aggregate) + btnRemoveType->Enable(); +} + +// Returnt the datatype OID for the given parameter number +long dlgAggregate::GetInputTypeOid(int param) +{ + wxListItem itm; + itm.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_TEXT); + itm.SetId(param); + + lstInputTypes->GetItem(itm); + + return itm.GetData(); +} + +// Return the list of datatype OIDs +wxString dlgAggregate::GetInputTypesOidList() +{ + wxString types; + + for (int i = 0; i < lstInputTypes->GetItemCount(); i++) + { + if (i > 0) + types += wxT(" "); + + types += NumToStr(GetInputTypeOid(i)); + } + return types; +} + +void dlgAggregate::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgAggregate::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + +void dlgAggregate::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} diff --git a/dlg/dlgCast.cpp b/dlg/dlgCast.cpp new file mode 100644 index 0000000..7b67215 --- /dev/null +++ b/dlg/dlgCast.cpp @@ -0,0 +1,216 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCast.cpp - PostgreSQL Operator Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgCast.h" +#include "schema/pgCast.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtCastname CTRL_TEXT("txtCastname") +#define cbSourceType CTRL_COMBOBOX2("cbSourceType") +#define cbTargetType CTRL_COMBOBOX2("cbTargetType") +#define cbFunction CTRL_COMBOBOX("cbFunction") +#define chkImplicit CTRL_CHECKBOX("chkImplicit") +#define stComment CTRL_STATIC("stComment") + +dlgProperty *pgCastFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgCast(this, frame, (pgCast *)node); +} + + +BEGIN_EVENT_TABLE(dlgCast, dlgTypeProperty) + EVT_TEXT(XRCID("cbSourceType"), dlgCast::OnChangeTypeSrc) + EVT_COMBOBOX(XRCID("cbSourceType"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTargetType"), dlgCast::OnChangeTypeTrg) + EVT_COMBOBOX(XRCID("cbTargetType"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgCast::dlgCast(pgaFactory *f, frmMain *frame, pgCast *node) + : dlgTypeProperty(f, frame, wxT("dlgCast")) +{ + cast = node; + + txtCastname->Disable(); +} + + +pgObject *dlgCast::GetObject() +{ + return cast; +} + + +int dlgCast::Go(bool modal) +{ + + if (!connection->BackendMinimumVersion(7, 5)) + txtComment->Disable(); + + if (cast) + { + // edit mode + cbSourceType->Append(cast->GetSourceType()); + cbSourceType->SetSelection(0); + cbSourceType->Disable(); + + cbTargetType->Append(wxEmptyString); + cbTargetType->Append(cast->GetTargetType()); + cbTargetType->SetSelection(1); + cbTargetType->Disable(); + + AddType(wxT(" "), cast->GetSourceTypeOid()); + AddType(wxT(" "), cast->GetTargetTypeOid()); + + cbFunction->Append(cast->GetCastFunction()); + cbFunction->SetSelection(0); + + cbFunction->Disable(); + chkImplicit->Disable(); + } + else + { + // create mode + FillDatatype(cbSourceType, cbTargetType, false); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgCast::CreateObject(pgCollection *collection) +{ + pgObject *obj = castFactory.CreateObjects(collection, 0, + wxT(" WHERE castsource = ") + GetTypeOid(cbSourceType->GetGuessedSelection()) + + wxT("\n AND casttarget = ") + GetTypeOid(cbTargetType->GetGuessedSelection())); + + return obj; +} + + +void dlgCast::CheckChange() +{ + if (cast) + { + EnableOK(txtComment->GetValue() != cast->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, cbSourceType->GetGuessedSelection() > 0, _("Please specify source datatype.")); + CheckValid(enable, cbTargetType->GetGuessedSelection() > 0, _("Please select target datatype.")); + + if (enable) + txtCastname->SetValue(cbSourceType->GetValue() + wxT(" -> ") + cbTargetType->GetValue()); + else + txtCastname->SetValue(wxEmptyString); + + EnableOK(enable); + } +} + + +void dlgCast::OnChangeTypeSrc(wxCommandEvent &ev) +{ + cbSourceType->GuessSelection(ev); + OnChangeType(ev); +} + +void dlgCast::OnChangeTypeTrg(wxCommandEvent &ev) +{ + cbTargetType->GuessSelection(ev); + OnChangeType(ev); +} + + +void dlgCast::OnChangeType(wxCommandEvent &ev) +{ + functions.Clear(); + cbFunction->Clear(); + + if (cbSourceType->GetGuessedSelection() > 0 && cbTargetType->GetGuessedSelection() > 0) + { + functions.Add(wxEmptyString); + cbFunction->Append(wxT(" ")); + + wxString qry = + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes[0] = ") + + GetTypeOid(cbSourceType->GetGuessedSelection()) + + wxT("\n AND CASE ") + + wxT("\n WHEN array_length(proargtypes, 1) = 2 THEN") + + wxT("\n proargtypes[1] = 23") + + wxT("\n WHEN array_length(proargtypes, 1) >= 3 THEN") + + wxT("\n proargtypes[1] = 23 AND proargtypes[2] = 16") + + wxT("\n ELSE true END") + + wxT("\n AND prorettype = ") + + GetTypeOid(cbTargetType->GetGuessedSelection()); + pgSet *set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + functions.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + cbFunction->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"))); + + set->MoveNext(); + } + delete set; + } + } + + CheckChange(); +} + + +wxString dlgCast::GetSql() +{ + wxString sql; + + if (cast) + { + // edit mode + } + else + { + // create mode + sql = wxT("CREATE CAST (") + cbSourceType->GetValue() + + wxT(" AS ") + cbTargetType->GetValue() + + wxT(")\n "); + if (cbFunction->GetCurrentSelection() > 0) + sql += wxT("WITH FUNCTION ") + functions.Item(cbFunction->GetCurrentSelection()) + + wxT("(") + cbSourceType->GetValue() + wxT(")"); + else + sql += wxT("WITHOUT FUNCTION"); + + if (chkImplicit->GetValue()) + sql += wxT("\n AS IMPLICIT"); + + sql += wxT(";\n"); + + } + AppendComment(sql, wxT("CAST (") + cbSourceType->GetValue() + + wxT(" AS ") + cbTargetType->GetValue() + wxT(")"), cast); + + return sql; +} diff --git a/dlg/dlgCheck.cpp b/dlg/dlgCheck.cpp new file mode 100644 index 0000000..44ddd2f --- /dev/null +++ b/dlg/dlgCheck.cpp @@ -0,0 +1,185 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCheck.cpp - PostgreSQL Check Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "schema/pgCheck.h" +#include "dlg/dlgCheck.h" + +#define txtWhere CTRL_TEXT("txtWhere") +#define chkNoInherit CTRL_CHECKBOX("chkNoInherit") +#define chkDontValidate CTRL_CHECKBOX("chkDontValidate") + + +BEGIN_EVENT_TABLE(dlgCheck, dlgProperty) + EVT_TEXT(XRCID("txtWhere"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDontValidate"), dlgCheck::OnChangeValidate) +END_EVENT_TABLE(); + + +dlgProperty *pgCheckFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgCheck(this, frame, (pgCheck *)node, parent); +} + + +dlgCheck::dlgCheck(pgaFactory *f, frmMain *frame, pgCheck *node, pgObject *parentNode) + : dlgProperty(f, frame, wxT("dlgCheck")) +{ + check = node; + object = parentNode; +} + +void dlgCheck::CheckChange() +{ + bool enable = true; + if (check) + { + enable = txtName->GetValue() != check->GetName() || txtComment->GetValue() != check->GetComment(); + if (connection->BackendMinimumVersion(9, 2) && !check->GetValid() && !chkDontValidate->GetValue()) + enable = true; + EnableOK(enable); + } + else + { + // We don't allow changing the comment if the dialog is launched from dlgTable or dlgDomain + // so we check IsModal() + txtComment->Enable(!GetName().IsEmpty() && !IsModal() && object->GetTypeName().Upper() == wxT("TABLE")); + CheckValid(enable, !txtWhere->GetValue().IsEmpty(), _("Please specify condition.")); + EnableOK(enable); + } +} + + +pgObject *dlgCheck::GetObject() +{ + return check; +} + + +pgObject *dlgCheck::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + if (name.IsEmpty()) + return 0; + + pgObject *obj = checkFactory.CreateObjects(collection, 0, wxT( + "\n AND conname=") + qtDbString(name) + wxT( + "\n AND relnamespace=") + object->GetSchema()->GetOidStr()); + return obj; +} + + +int dlgCheck::Go(bool modal) +{ + if (check) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + txtComment->Enable(object->GetTypeName().Upper() == wxT("TABLE")); + + txtWhere->SetValue(check->GetDefinition()); + txtWhere->Disable(); + + if (connection->BackendMinimumVersion(9, 2)) + { + chkNoInherit->SetValue(check->GetNoInherit()); + chkDontValidate->SetValue(!check->GetValid()); + } + else + chkDontValidate->SetValue(true); + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2) && !check->GetDefinition().IsEmpty() && !check->GetValid()); + } + else + { + // create mode + txtComment->Disable(); + if (!object) + { + cbClusterSet->Disable(); + cbClusterSet = 0; + } + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 2)); + } + + chkNoInherit->Enable(connection->BackendMinimumVersion(9, 2) && !check); + + return dlgProperty::Go(modal); +} + + +void dlgCheck::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgCheck::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (!check) + { + sql = wxT("ALTER ") + object->GetTypeName().Upper() + wxT(" ") + object->GetQuotedFullIdentifier() + + wxT("\n ADD"); + if (name.Length() > 0) + { + sql += wxT(" CONSTRAINT ") + qtIdent(name) + wxT("\n "); + } + sql += wxT(" CHECK "); + sql += GetDefinition(); + if (connection->BackendMinimumVersion(9, 2) && chkNoInherit->GetValue()) + { + sql += wxT(" NO INHERIT"); + } + sql += wxT(";\n"); + } + else + { + if (check->GetName() != name) + { + sql = wxT("ALTER ") + object->GetTypeName().Upper() + wxT(" ") + object->GetQuotedFullIdentifier() + + wxT("\n RENAME CONSTRAINT ") + qtIdent(check->GetName()) + + wxT(" TO ") + qtIdent(name) + wxT(";\n"); + } + if (connection->BackendMinimumVersion(9, 2) && !check->GetValid() && !chkDontValidate->GetValue()) + { + sql += wxT("ALTER ") + object->GetTypeName().Upper() + wxT(" ") + object->GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + qtIdent(name) + wxT(";\n"); + } + } + + if (!name.IsEmpty()) + AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + + wxT(" ON ") + object->GetQuotedFullIdentifier(), check); + return sql; +} + + +wxString dlgCheck::GetDefinition() +{ + wxString sql; + + sql = wxT("(") + txtWhere->GetValue() + wxT(")"); + + if (chkDontValidate->GetValue()) + sql += wxT(" NOT VALID"); + + return sql; +} diff --git a/dlg/dlgClasses.cpp b/dlg/dlgClasses.cpp new file mode 100644 index 0000000..7e5cdfc --- /dev/null +++ b/dlg/dlgClasses.cpp @@ -0,0 +1,778 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgClasses.cpp - Some dialogue base classes +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "db/pgConn.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "utils/sysProcess.h" +#include "frm/menu.h" +#include "db/pgQueryThread.h" + +#include +WX_DEFINE_LIST(windowList); + +#define STATUSBAR_XRCNAME wxT("unkStatusBar") +#define STATUSBAR_CONTAINER STATUSBAR_XRCNAME wxT("_container") + + +BEGIN_EVENT_TABLE(pgDialog, wxDialog) + EVT_BUTTON (wxID_CANCEL, pgDialog::OnCancel) + EVT_CLOSE( pgDialog::OnClose) +END_EVENT_TABLE() + + + +void pgDialog::AddStatusBar() +{ + if (!statusBar) + { + long flags = 0; + if (GetWindowStyle() & wxRESIZE_BORDER) + flags = wxST_SIZEGRIP; + statusBar = new wxStatusBar(this, -1, flags); + + wxWindow *statusBarContainer = FindWindow(STATUSBAR_CONTAINER); + + if (statusBarContainer) + { + wxXmlResource::Get()->AttachUnknownControl(STATUSBAR_XRCNAME, statusBar); + } + else + { + int sbHeight = statusBar->GetSize().y; + wxSize size = GetSize(); + size.y += sbHeight; + SetSize(size); + + size = GetClientSize(); + statusBar->Move(0, size.y - sbHeight); + } + } +} + + +void pgDialog::PostCreation() +{ + if (!statusBar && FindWindow(STATUSBAR_CONTAINER)) + AddStatusBar(); + + if (GetWindowStyle() & wxRESIZE_BORDER) // is designed with sizers; don't change + return; + + if (!btnCancel) + return; + + wxSize size = btnCancel->GetSize(); + wxPoint pos = btnCancel->GetPosition(); + int height = pos.y + size.GetHeight() + ConvertDialogToPixels(wxSize(0, 3)).y; + if (statusBar) + height += statusBar->GetSize().GetHeight(); + + int right = pos.x + ConvertDialogToPixels(wxSize(50, 0)).x - size.GetWidth(); + btnCancel->Move(right, pos.y); + + if (btnOK) + { + size = btnOK->GetSize(); + right -= size.GetWidth() + ConvertDialogToPixels(wxSize(3, 0)).x; + btnOK->Move(right, pos.y); + } + +// On OS X, reverse the buttons for UI consistency +#ifdef __WXMAC__ + wxPoint pos2; + pos = btnCancel->GetPosition(); + + if (btnOK) + { + pos2 = btnOK->GetPosition(); + btnOK->Move(pos.x, pos.y); + } + + btnCancel->Move(pos2.x, pos2.y); +#endif + + int w, h; + size = GetSize(); + GetClientSize(&w, &h); + + SetSize(size.GetWidth(), size.GetHeight() + height - h); +} + + +void pgDialog::RestorePosition(int defaultX, int defaultY, int defaultW, int defaultH, int minW, int minH) +{ + if (minW == -1) + minW = GetSize().GetX(); + + if (minH == -1) + minH = GetSize().GetY(); + + wxPoint pos(settings->Read(dlgName, wxPoint(defaultX, defaultY))); + wxSize size; + + if ((this->GetWindowStyle() & wxRESIZE_BORDER) == wxRESIZE_BORDER) + { + if (defaultW < 0) + size = settings->Read(dlgName, GetSize()); + else + size = settings->Read(dlgName, wxSize(defaultW, defaultH)); + } + else + { + size = GetSize(); + } + + bool posDefault = (pos.x == -1 && pos.y == -1); + + CheckOnScreen(this, pos, size, minW, minH); + SetSize(pos.x, pos.y, size.x, size.y); + if (posDefault) + CenterOnParent(); +} + +void pgDialog::SavePosition() +{ +#ifndef __WXGTK__ + if (!IsIconized()) + { +#endif + wxPoint pos = GetPosition(); + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + settings->WriteSizePoint(dlgName, GetSize(), pos); +#ifndef __WXGTK__ + } +#endif +} + +void pgDialog::LoadResource(wxWindow *parent, const wxChar *name) +{ + if (name) + dlgName = name; + wxXmlResource::Get()->LoadDialog(this, parent, dlgName); + PostCreation(); +} + + + +void pgDialog::OnClose(wxCloseEvent &event) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + + +void pgDialog::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + + +/////////////////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(pgFrame, wxFrame) + EVT_MENU(MNU_EXIT, pgFrame::OnExit) + EVT_MENU(MNU_RECENT + 1, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 2, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 3, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 4, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 5, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 6, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 7, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 8, pgFrame::OnRecent) + EVT_MENU(MNU_RECENT + 9, pgFrame::OnRecent) +#ifdef __WXGTK__ + EVT_KEY_DOWN( pgFrame::OnKeyDown) +#endif +END_EVENT_TABLE() + + +pgFrame::pgFrame(wxFrame *parent, const wxString &title, const wxPoint &pos, const wxSize &size, long flags) + : wxFrame(parent, -1, title, pos, size, flags) +{ + changed = false; + recentFileMenu = 0; + menuFactories = 0; +} + + +pgFrame::~pgFrame() +{ + if (!dlgName.IsEmpty()) + SavePosition(); + if (menuFactories) + delete menuFactories; + +} + + +void pgFrame::RemoveFrame(wxWindow *frame) +{ + frames.DeleteObject(frame); +} + + +void pgFrame::OnAction(wxCommandEvent &ev) +{ + actionFactory *af = menuFactories->GetFactory(ev.GetId()); + if (af) + { + wxWindow *wnd = af->StartDialog((frmMain *)this, 0); + if (wnd) + AddFrame(wnd); + } +} + + +// Event handlers +void pgFrame::OnKeyDown(wxKeyEvent &event) +{ + event.m_metaDown = false; + event.Skip(); +} + + +void pgFrame::OnExit(wxCommandEvent &event) +{ + Close(); +} + + +void pgFrame::OnHelp(wxCommandEvent &WXUNUSED(event)) +{ + wxString page = GetHelpPage(); + DisplayHelp(page, HELP_PGADMIN); +} + + +void pgFrame::OnRecent(wxCommandEvent &event) +{ + int fileNo = event.GetId() - MNU_RECENT; + wxString newPath = settings->Read(recentKey + wxString::Format(wxT("/%d"), fileNo), wxT("")); + + if (!newPath.IsNull()) + { + if (CheckChanged(true)) + return; + + lastPath = newPath; + int dirsep; + dirsep = lastPath.Find(wxFILE_SEP_PATH, true); + lastDir = lastPath.Mid(0, dirsep); + lastFilename = lastPath.Mid(dirsep + 1); + OpenLastFile(); + } +} + + + +void pgFrame::UpdateRecentFiles(bool updatefile) +{ + if (!recentFileMenu) + return; + + if (recentKey.IsEmpty()) + recentKey = dlgName + wxT("/RecentFiles"); + + wxString lastFiles[10]; // 0 will be unused for convenience + int i, maxFiles = 9; + int recentIndex = maxFiles; + + for (i = 1 ; i <= maxFiles ; i++) + { + lastFiles[i] = settings->Read(recentKey + wxString::Format(wxT("/%d"), i), wxT("")); + if (!lastPath.IsNull() && lastPath.IsSameAs(lastFiles[i], wxARE_FILENAMES_CASE_SENSITIVE)) + recentIndex = i; + } + while (i <= maxFiles) + lastFiles[i++] = wxT(""); + + if (recentIndex > 1 && !lastPath.IsNull() && updatefile) + { + for (i = recentIndex ; i > 1 ; i--) + lastFiles[i] = lastFiles[i - 1]; + lastFiles[1] = lastPath; + } + + i = recentFileMenu->GetMenuItemCount(); + while (i) + { + wxMenuItem *item = recentFileMenu->Remove(MNU_RECENT + i); + if (item) + delete item; + i--; + } + + for (i = 1 ; i <= maxFiles ; i++) + { + if (updatefile) + settings->Write(recentKey + wxString::Format(wxT("/%d"), i), lastFiles[i]); + + if (!lastFiles[i].IsNull()) + recentFileMenu->Append(MNU_RECENT + i, wxT("&") + wxString::Format(wxT("%d"), i) + wxT(" ") + lastFiles[i]); + } +} + + +void pgFrame::RestorePosition(int defaultX, int defaultY, int defaultW, int defaultH, int minW, int minH) +{ + bool maximized = false; + wxPoint pos(settings->Read(dlgName, wxPoint(defaultX, defaultY))); + wxSize size; + if (defaultW < 0) + size = GetSize(); + else + size = settings->Read(dlgName, wxSize(defaultW, defaultH)); + + bool posDefault = (pos.x == -1 && pos.y == -1); + + CheckOnScreen(this, pos, size, minW, minH); + SetSize(pos.x, pos.y, size.x, size.y); + if (posDefault) + CenterOnParent(); + + settings->Read(dlgName + wxT("/Maximized"), &maximized, false); + if (maximized) + Maximize(); +} + + +void pgFrame::SavePosition() +{ +#ifndef __WXGTK__ + if (!IsIconized()) + { +#endif + wxPoint pos = GetPosition(); + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + settings->WriteSizePoint(dlgName, GetSize(), pos); + settings->WriteBool(dlgName + wxT("/Maximized"), IsMaximized()); +#ifndef __WXGTK__ + } +#endif +} + + + +////////////////////////////////////////////////////// + +BEGIN_EVENT_TABLE(DialogWithHelp, pgDialog) + EVT_MENU(MNU_HELP, DialogWithHelp::OnHelp) + EVT_BUTTON(wxID_HELP, DialogWithHelp::OnHelp) +END_EVENT_TABLE(); + + +DialogWithHelp::DialogWithHelp(frmMain *frame) : pgDialog() +{ + mainForm = frame; + + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); +// this is for GTK because Meta (usually Numlock) is interpreted like Alt +// there are too many controls to reset m_Meta in all of them + entries[1].Set(wxACCEL_ALT, WXK_F1, MNU_HELP); + wxAcceleratorTable accel(2, entries); + + SetAcceleratorTable(accel); +} + + +void DialogWithHelp::OnHelp(wxCommandEvent &ev) +{ + wxString page = GetHelpPage(); + + if (!page.IsEmpty()) + { + if (page.StartsWith(wxT("pg/"))) + DisplayHelp(page.Mid(3), HELP_POSTGRESQL); + else if (page.StartsWith(wxT("slony/"))) + DisplayHelp(page.Mid(6), HELP_SLONY); + else + DisplayHelp(page, HELP_PGADMIN); + } +} + + + +////////////////////////////////////////////////////////////////77 + + +BEGIN_EVENT_TABLE(ExecutionDialog, DialogWithHelp) + EVT_BUTTON (wxID_OK, ExecutionDialog::OnOK) + EVT_BUTTON (wxID_CANCEL, ExecutionDialog::OnCancel) + EVT_CLOSE( ExecutionDialog::OnClose) +END_EVENT_TABLE() + + +ExecutionDialog::ExecutionDialog(frmMain *frame, pgObject *_object) : DialogWithHelp(frame) +{ + thread = 0; + object = _object; + txtMessages = 0; + bIsAborted = false; + bIsExecutionStarted = false; + bIsExecutionCompleted = false; + + pgDatabase *db = object->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Execution Tool"); + conn = db->CreateConn(applicationname); +} + +void ExecutionDialog::EnableOK(const bool enable) +{ + btnOK->Enable(enable); +} + + +void ExecutionDialog::OnClose(wxCloseEvent &event) +{ + Abort(); + // If execution is started and not yet complete it means thread is still + // running, so we should not delete the connection object and destroy the dialog. + if(bIsExecutionStarted && !bIsExecutionCompleted) + return; + + delete conn; + if (IsModal()) + EndModal(-1); + else + Destroy(); +} + + +void ExecutionDialog::OnCancel(wxCommandEvent &ev) +{ + if (thread) + { + btnCancel->Disable(); + Abort(); + btnCancel->Enable(); + btnOK->Enable(); + } + else + { + delete conn; + if (IsModal()) + EndModal(-1); + else + Destroy(); + } +} + + +void ExecutionDialog::Abort() +{ + // If bIsAborted is true it means abort is still in progress + if (thread && !bIsAborted) + { + bIsAborted = true; + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + + delete thread; + thread = 0; + } +} + + +void ExecutionDialog::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!thread) + { + wxString sql = GetSql(); + if (sql.IsEmpty()) + return; + + btnOK->Disable(); + // Reset the variables + bIsAborted = false; + bIsExecutionStarted = false; + bIsExecutionCompleted = false; + + thread = new pgQueryThread(conn, sql); + if (thread->Create() != wxTHREAD_NO_ERROR) + { + Abort(); + return; + } + + wxLongLong startTime = wxGetLocalTimeMillis(); + thread->Run(); + // When execution is started then set the variable + bIsExecutionStarted = true; + wxNotebook *nb = CTRL_NOTEBOOK("nbNotebook"); + if (nb) + nb->SetSelection(nb->GetPageCount() - 1); + + while (thread && thread->IsRunning()) + { + wxMilliSleep(10); + // here could be the animation + if (txtMessages) + { + wxString msg = thread->GetMessagesAndClear(); + if (!msg.IsEmpty()) + txtMessages->AppendText(msg + wxT("\n")); + } + + wxTheApp->Yield(true); + } + + if (thread) + { + bool isOk = (thread->ReturnCode() == PGRES_COMMAND_OK || thread->ReturnCode() == PGRES_TUPLES_OK); + + if (txtMessages) + { + txtMessages->AppendText(thread->GetMessagesAndClear()); + } + + if (thread->DataSet() != NULL) + { + wxLogInfo(wxString::Format(wxT("%d rows."), thread->DataSet()->NumRows())); + } + + if (isOk) + { + if (txtMessages) + txtMessages->AppendText( + _("Total query runtime: ") + + ElapsedTimeToStr( + wxGetLocalTimeMillis() - startTime + ) + ); + + btnOK->SetLabel(_("Done")); + btnCancel->Disable(); + } + else + { + if (txtMessages) + txtMessages->AppendText(conn->GetLastError()); + Abort(); + } + } + else if (txtMessages) + txtMessages->AppendText(_("\nCancelled.\n")); + + btnOK->Enable(); + bIsExecutionCompleted = true; + } + else + { + Abort(); + delete conn; + Destroy(); + } +} + + + +#define TIMER_ID 4442 + +BEGIN_EVENT_TABLE(ExternProcessDialog, DialogWithHelp) + EVT_BUTTON(wxID_OK, ExternProcessDialog::OnOK) + EVT_BUTTON(wxID_CANCEL, ExternProcessDialog::OnCancel) + EVT_CLOSE( ExternProcessDialog::OnClose) + EVT_END_PROCESS(-1, ExternProcessDialog::OnEndProcess) + EVT_TIMER(TIMER_ID, ExternProcessDialog::OnPollProcess) +END_EVENT_TABLE() + + + +ExternProcessDialog::ExternProcessDialog(frmMain *frame) : DialogWithHelp(frame) +{ + txtMessages = 0; + process = 0; + done = false; + processID = 0; + + timer = new wxTimer(this, TIMER_ID); +} + + + +ExternProcessDialog::~ExternProcessDialog() +{ + Abort(); + delete timer; +} + + +void ExternProcessDialog::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!done) + Execute(0); + else + { + Abort(); + pgDialog::OnCancel(ev); + } +} + + +bool ExternProcessDialog::Execute(int step, bool finalStep) +{ + btnOK->Disable(); + final = finalStep; + + if (txtMessages) + txtMessages->AppendText(GetDisplayCmd(step) + END_OF_LINE); + + if (process) + { + delete process; + process = NULL; + processID = 0; + } + + process = new sysProcess(this); + process->SetEnvironment(environment); + + processID = wxExecute(GetCmd(step), wxEXEC_ASYNC, process); + + if (processID) + { + wxNotebook *nb = CTRL_NOTEBOOK("nbNotebook"); + if (nb) + nb->SetSelection(nb->GetPageCount() - 1); + if (txtMessages) + { + checkStreams(); + timer->Start(100L); + } + return true; + } + else + { + delete process; + process = NULL; + processID = 0; + return false; + } +} + + +void ExternProcessDialog::OnCancel(wxCommandEvent &ev) +{ + if (process) + { + btnCancel->Disable(); + Abort(); + wxMilliSleep(100); + if (txtMessages) + txtMessages->AppendText(END_OF_LINE + wxString(_("Cancelled on user request.")) + END_OF_LINE + END_OF_LINE); + } + else + pgDialog::OnCancel(ev); +} + + +void ExternProcessDialog::OnClose(wxCloseEvent &ev) +{ + btnCancel->Disable(); + Abort(); + pgDialog::OnClose(ev); +} + + +void ExternProcessDialog::OnPollProcess(wxTimerEvent &event) +{ + checkStreams(); +} + + +void ExternProcessDialog::checkStreams() +{ + if (txtMessages && process) + { + txtMessages->AppendText(process->ReadErrorStream()); + txtMessages->AppendText(process->ReadInputStream()); + } +} + + +void ExternProcessDialog::OnEndProcess(wxProcessEvent &ev) +{ + if (process) + { + if (!ev.GetExitCode()) + { + if (final) + btnOK->SetLabel(_("Done")); + done = true; + } + } + timer->Stop(); + + if (txtMessages) + { + checkStreams(); + txtMessages->AppendText(END_OF_LINE + + wxString::Format(_("Process returned exit code %d."), ev.GetExitCode()) + + END_OF_LINE); + } + + if (process) + { + delete process; + processID = 0; + process = 0; + } + btnOK->Enable(); + btnCancel->Enable(); +} + + +void ExternProcessDialog::Abort() +{ + timer->Stop(); + if (process) + { + done = false; + // Kill the child process started with wxExecute in Execute method + wxKill(processID); + processID = 0; + } +} + diff --git a/dlg/dlgCollation.cpp b/dlg/dlgCollation.cpp new file mode 100644 index 0000000..47ad3c7 --- /dev/null +++ b/dlg/dlgCollation.cpp @@ -0,0 +1,187 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCollation.cpp - PostgreSQL Collation Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgCollation.h" +#include "schema/pgSchema.h" +#include "schema/pgCollation.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtLocale CTRL_TEXT("txtLocale") +#define txtLcCollate CTRL_TEXT("txtLcCollate") +#define txtLcCtype CTRL_TEXT("txtLcCtype") +#define cbCollation CTRL_COMBOBOX2("cbCollation") + + +BEGIN_EVENT_TABLE(dlgCollation, dlgTypeProperty) + EVT_TEXT(XRCID("txtLocale"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtLcCollate"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtLcCtype"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbCollation"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbCollation"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *pgCollationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgCollation(this, frame, (pgCollation *)node, (pgSchema *)parent); +} + + +dlgCollation::dlgCollation(pgaFactory *f, frmMain *frame, pgCollation *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgCollation")) +{ + schema = sch; + collation = node; +} + + +pgObject *dlgCollation::GetObject() +{ + return collation; +} + + +int dlgCollation::Go(bool modal) +{ + if (collation) + { + // edit mode + txtLcCollate->SetValue(collation->GetLcCollate()); + txtLcCtype->SetValue(collation->GetLcCtype()); + + txtLocale->Disable(); + txtLcCollate->Disable(); + txtLcCtype->Disable(); + cbCollation->Disable(); + } + else + { + // create mode + // fill collation combobox + cbCollation->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgCollation::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = collationFactory.CreateObjects(collection, 0, + wxT(" AND c.collname=") + qtDbString(name) + + wxT("\n AND c.collnamespace=") + schema->GetOidStr() + + wxT("\n")); + return obj; +} + + +void dlgCollation::CheckChange() +{ + if (collation) + { + EnableOK(txtName->GetValue() != collation->GetName() + || cbSchema->GetValue() != collation->GetSchema()->GetName() + || cbOwner->GetValue() != collation->GetOwner() + || txtComment->GetValue() != collation->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, + !txtLocale->GetValue().IsEmpty() || + !(txtLcCollate->GetValue().IsEmpty() && txtLcCtype->GetValue().IsEmpty()) || + !cbCollation->GetValue().IsEmpty(), + _("Please specify a locale, or LC_COLLATE and LC_CTYPE, or a collation")); + + txtLocale->Enable(cbCollation->GetValue().IsEmpty() && txtLcCollate->GetValue().IsEmpty() && txtLcCtype->GetValue().IsEmpty()); + txtLcCollate->Enable(cbCollation->GetValue().IsEmpty() && txtLocale->GetValue().IsEmpty()); + txtLcCtype->Enable(cbCollation->GetValue().IsEmpty() && txtLocale->GetValue().IsEmpty()); + cbCollation->Enable(txtLocale->GetValue().IsEmpty() && txtLcCollate->GetValue().IsEmpty() && txtLcCtype->GetValue().IsEmpty()); + + EnableOK(enable); + } +} + + +wxString dlgCollation::GetSql() +{ + wxString sql; + wxString name; + + if (collation) + { + // edit mode + name = schema->GetQuotedPrefix() + qtIdent(GetName());; + AppendNameChange(sql, wxT("COLLATION ") + collation->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("COLLATION ") + name); + AppendSchemaChange(sql, wxT("COLLATION ") + name); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + sql = wxT("CREATE COLLATION ") + name; + if (cbCollation->GetValue().IsEmpty()) + { + if (txtLocale->GetValue().IsEmpty()) + { + sql += wxT("(LC_COLLATE=") + qtDbString(txtLcCollate->GetValue()) + + wxT(", LC_CTYPE=") + qtDbString(txtLcCtype->GetValue()) + + wxT(")"); + } + else + { + sql += wxT("(LOCALE=") + qtDbString(txtLocale->GetValue()) + wxT(")"); + } + } + else + { + sql += wxT(" FROM ") + cbCollation->GetValue(); + } + sql += wxT(";\n"); + + AppendOwnerNew(sql, wxT("COLLATION ") + schema->GetQuotedPrefix() + qtIdent(name)); + } + AppendComment(sql, wxT("COLLATION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), collation); + + return sql; +} + diff --git a/dlg/dlgColumn.cpp b/dlg/dlgColumn.cpp new file mode 100644 index 0000000..a2ec0a6 --- /dev/null +++ b/dlg/dlgColumn.cpp @@ -0,0 +1,917 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgColumns.cpp - PostgreSQL Columns Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgColumn.h" +#include "schema/pgSchema.h" +#include "schema/pgColumn.h" +#include "schema/pgTable.h" +#include "schema/pgDatatype.h" +#include "frm/frmMain.h" +#include "schema/pgUser.h" +#include "schema/pgGroup.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define txtDefault CTRL_TEXT("txtDefault") +#define chkNotNull CTRL_CHECKBOX("chkNotNull") +#define txtAttstattarget CTRL_TEXT("txtAttstattarget") +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbStorage CTRL_COMBOBOX1("cbStorage") +#define cbCollation CTRL_COMBOBOX("cbCollation") + + +BEGIN_EVENT_TABLE(dlgColumn, dlgTypeProperty) + EVT_TEXT(XRCID("txtLength"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtPrecision"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDefault"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkNotNull"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtAttstattarget"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbDatatype"), dlgColumn::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgColumn::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbCollation"), dlgColumn::OnSelChangeTyp) + EVT_BUTTON(CTL_ADDPRIV, dlgColumn::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgColumn::OnDelPriv) + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgColumn::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgColumn::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgColumn::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgColumn::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgColumn::OnVarnameSelChange) + EVT_TEXT(XRCID("cbStorage"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbStorage"), dlgProperty::OnChange) + +#ifdef __WXMAC__ + EVT_SIZE( dlgColumn::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgColumnFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgColumn(this, frame, (pgColumn *)node, (pgTable *)parent); +} + + +dlgColumn::dlgColumn(pgaFactory *f, frmMain *frame, pgColumn *node, pgTable *parentNode) + : dlgTypeProperty(f, frame, wxT("dlgColumn")) +{ + column = node; + table = parentNode; + wxASSERT(!table || (table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW || table->GetMetaType() == GP_EXTTABLE || table->GetMetaType() == GP_PARTITION)); + + changedColumn = NULL; + + dirtyVars = false; + + txtAttstattarget->SetValidator(numericValidator); + + lstVariables->CreateColumns(0, _("Variable"), _("Value")); + + cbStorage->Append(wxT("PLAIN")); + cbStorage->Append(wxT("MAIN")); + cbStorage->Append(wxT("EXTERNAL")); + cbStorage->Append(wxT("EXTENDED")); + + /* Column Level Privileges */ + securityChanged = false; + if (node) + connection = node->GetConnection(); + securityPage = new ctlSecurityPanel(nbNotebook, wxT("INSERT,SELECT,UPDATE,REFERENCES"), "arwx", frame->GetImageList()); + if (connection && connection->BackendMinimumVersion(8, 4) && (!node || node->CanCreate())) + { + // Fetch Groups Information + pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + SetSecurityPage(node); + } + else + securityPage->Disable(); + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +#ifdef __WXMAC__ +void dlgColumn::OnChangeSize(wxSizeEvent &ev) +{ + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +pgObject *dlgColumn::GetObject() +{ + return column; +} + +void dlgColumn::SetSecurityPage(const pgColumn *node) +{ + if (node) + { + wxString strAcl = node->GetAcl(); + securityPage->lbPrivileges->DeleteAllItems(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + + if(changedColumn == NULL) + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } +} + +int dlgColumn::Go(bool modal) +{ + if (connection->BackendMinimumVersion(8, 4)) + { + securityPage->SetConnection(connection); + + if (securityPage->cbGroups) + { + // Fetch Groups Information + for ( unsigned int index = 0; index < groups.Count();) + securityPage->cbGroups->Append(wxT("group ") + groups[index++]); + + // Fetch Users Information + if (settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups); + Layout(); + } + } + securityPage->lbPrivileges->GetParent()->Layout(); + } + + if (connection->BackendMinimumVersion(8, 5)) + { + cbVarname->Append(wxT("n_distinct")); + cbVarname->Append(wxT("n_distinct_inherited")); + cbVarname->SetSelection(0); + } + else + { + lstVariables->Enable(false); + btnAdd->Enable(false); + btnRemove->Enable(false); + cbVarname->Enable(false); + txtValue->Enable(false); + } + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(column); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgColumn::OnChange)); + } + else + seclabelPage->Disable(); + + cbStorage->Enable(true); + + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + cbCollation->Freeze(); + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + cbCollation->Thaw(); + delete set; + } + cbCollation->SetSelection(0); + } + else + cbCollation->Disable(); + + if (column) + { + // edit mode + if (column->GetLength() > 0) + txtLength->SetValue(NumToStr(column->GetLength())); + if (column->GetPrecision() >= 0) + txtPrecision->SetValue(NumToStr(column->GetPrecision())); + txtDefault->SetValue(column->GetDefault()); + chkNotNull->SetValue(column->GetNotNull()); + txtAttstattarget->SetValue(NumToStr(column->GetAttstattarget())); + + wxString fullType = column->GetRawTypename(); + if (column->GetIsArray()) + fullType += wxT("[]"); + cbDatatype->Append(fullType); + AddType(wxT("?"), column->GetAttTypId(), fullType); + + if (!column->IsReferenced()) + { + wxString typeSql = + wxT("SELECT tt.oid, format_type(tt.oid,NULL) AS typname\n") + wxT(" FROM pg_cast\n") + wxT(" JOIN pg_type tt ON tt.oid=casttarget\n") + wxT(" WHERE castsource=") + NumToStr(column->GetAttTypId()) + wxT("\n"); + + if (connection->BackendMinimumVersion(8, 0)) + typeSql += wxT(" AND castcontext IN ('i', 'a')"); + else + typeSql += wxT(" AND castfunc=0"); + + pgSetIterator set(connection, typeSql); + + while (set.RowsLeft()) + { + if (set.GetVal(wxT("typname")) != column->GetRawTypename()) + { + cbDatatype->Append(set.GetVal(wxT("typname"))); + AddType(wxT("?"), set.GetOid(wxT("oid")), set.GetVal(wxT("typname"))); + } + } + } + if (cbDatatype->GetCount() <= 1) + cbDatatype->Disable(); + + cbDatatype->SetSelection(0); + wxNotifyEvent ev; + OnSelChangeTyp(ev); + + previousDefinition = GetDefinition(); + if (column->GetColNumber() < 0) // Disable controls not valid for system columns + { + txtName->Disable(); + txtDefault->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + cbStorage->Disable(); + cbCollation->Disable(); + } + else if (column->GetTable()->GetMetaType() == PGM_VIEW) // Disable controls not valid for view columns + { + txtName->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + cbStorage->Disable(); + cbCollation->Disable(); + } + else if (column->GetTable()->GetMetaType() == GP_EXTTABLE) // Disable controls not valid for external table columns + { + txtName->Disable(); + chkNotNull->Disable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Disable(); + txtDefault->Disable(); + cbStorage->Disable(); + cbCollation->Disable(); + } + else if (table->GetOfTypeOid() > 0) + { + txtName->Disable(); + chkNotNull->Enable(); + txtLength->Disable(); + cbDatatype->Disable(); + txtAttstattarget->Enable(); + txtDefault->Enable(); + cbStorage->Enable(); + cbCollation->Disable(); + } + + cbStorage->SetValue(column->GetStorage()); + cbCollation->SetValue(column->GetCollation()); + + size_t i; + for (i = 0 ; i < column->GetVariables().GetCount() ; i++) + { + wxString item = column->GetVariables().Item(i); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + } + else + { + // create mode + FillDatatype(cbDatatype, true, true); + + if (!table) + { + cbClusterSet->Disable(); + cbClusterSet = 0; + } + + txtAttstattarget->Disable(); + cbStorage->Disable(); + } + + if (changedColumn) + ApplyChangesToDlg(); + + return dlgTypeProperty::Go(modal); +} + + +wxString dlgColumn::GetSql() +{ + wxString sql; + wxString name = GetName(); + + bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial") || cbDatatype->GetValue() == wxT("smallserial")); + + if (table) + { + if (column) + { + if (name != column->GetName()) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT(" RENAME ") + qtIdent(column->GetName()) + + wxT(" TO ") + qtIdent(name) + + wxT(";\n"); + + wxString len; + if (txtLength->IsEnabled()) + len = txtLength->GetValue(); + + wxString prec; + if (txtPrecision->IsEnabled()) + prec = txtPrecision->GetValue(); + + if (connection->BackendMinimumVersion(7, 5)) + { + if ((cbDatatype->GetValue() != column->GetRawTypename() && !column->GetIsArray()) || + (cbDatatype->GetValue() != column->GetRawTypename() + wxT("[]") && column->GetIsArray()) || + (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) || + (isVarLen && txtLength->IsEnabled() && StrToLong(len) != column->GetLength()) || + (isVarPrec && txtPrecision->IsEnabled() && StrToLong(prec) != column->GetPrecision())) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + wxT(" TYPE ") + + GetQuotedTypename(cbDatatype->GetGuessedSelection()); + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) + sql += wxT(" COLLATE ") + cbCollation->GetValue(); + sql += wxT(";\n"); + } + } + else + { + wxString sqlPart; + if (cbDatatype->GetCount() > 1 && cbDatatype->GetValue() != column->GetRawTypename()) + sqlPart = wxT("atttypid=") + dlgTypeProperty::GetTypeOid(cbDatatype->GetGuessedSelection()); + + + if (!sqlPart.IsEmpty() || + (isVarLen && txtLength->IsEnabled() && StrToLong(prec) != column->GetLength()) || + (isVarPrec && txtPrecision->IsEnabled() && StrToLong(prec) != column->GetPrecision())) + { + long typmod = pgDatatype::GetTypmod(column->GetRawTypename(), len, prec); + + if (!sqlPart.IsEmpty()) + sqlPart += wxT(", "); + sqlPart += wxT("atttypmod=") + NumToStr(typmod); + } + if (!sqlPart.IsEmpty()) + { + sql += wxT("UPDATE pg_attribute\n") + wxT(" SET ") + sqlPart + wxT("\n") + wxT(" WHERE attrelid=") + table->GetOidStr() + + wxT(" AND attnum=") + NumToStr(column->GetColNumber()) + wxT(";\n"); + } + } + + if (txtDefault->GetValue() != column->GetDefault()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name); + if (txtDefault->GetValue().IsEmpty()) + sql += wxT(" DROP DEFAULT"); + else + sql += wxT(" SET DEFAULT ") + txtDefault->GetValue(); + + sql += wxT(";\n"); + } + if (chkNotNull->GetValue() != column->GetNotNull()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name); + if (chkNotNull->GetValue()) + sql += wxT(" SET"); + else + sql += wxT(" DROP"); + + sql += wxT(" NOT NULL;\n"); + } + if (txtAttstattarget->GetValue() != NumToStr(column->GetAttstattarget())) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name); + if (txtAttstattarget->GetValue().IsEmpty()) + sql += wxT(" SET STATISTICS -1"); + else + sql += wxT(" SET STATISTICS ") + txtAttstattarget->GetValue(); + sql += wxT(";\n"); + } + + wxArrayString vars; + size_t index; + + for (index = 0 ; index < column->GetVariables().GetCount() ; index++) + vars.Add(column->GetVariables().Item(index)); + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT("\n SET (") + newVar + wxT("=") + newVal + wxT(");\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT("\n RESET (") + vars.Item(pos).BeforeFirst('=') + wxT(");\n"); + } + + if (cbStorage->GetValue() != column->GetStorage()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT(" SET STORAGE ") + cbStorage->GetValue() + + wxT(";\n"); + } + } + else + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD COLUMN ") + qtIdent(name) + + wxT(" ") + GetQuotedTypename(cbDatatype->GetGuessedSelection()); + + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + cbCollation->GetValue(); + + if (chkNotNull->GetValue()) + sql += wxT(" NOT NULL"); + + if (!isSerial && !txtDefault->GetValue().IsEmpty()) + sql += wxT(" DEFAULT ") + txtDefault->GetValue(); + + sql += wxT(";\n"); + + if (!txtAttstattarget->GetValue().IsEmpty()) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT(" SET STATISTICS ") + txtAttstattarget->GetValue() + + wxT(";\n"); + + // check for added vars + for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ALTER COLUMN ") + qtIdent(name) + + wxT("\n SET (") + lstVariables->GetText(pos) + wxT("=") + + lstVariables->GetText(pos, 1) + wxT(");\n"); + } + } + + AppendComment(sql, wxT("COLUMN ") + table->GetQuotedFullIdentifier() + + wxT(".") + qtIdent(name), column); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("COLUMN"), table->GetQuotedFullIdentifier() + + wxT(".") + qtIdent(name)); + + // securityPage will exists only for PG 8.4 and later + if (connection->BackendMinimumVersion(8, 4)) + sql += securityPage->GetGrant(wxT("arwx"), table->GetQuotedFullIdentifier(), ¤tAcl, qtIdent(name)); + } + return sql; +} + + +void dlgColumn::SetChangedCol(pgColumn *changedCol) +{ + changedColumn = changedCol; +} + + +void dlgColumn::ApplyChangesToObj(pgColumn *changedCol) +{ + changedCol->iSetName(txtName->GetValue()); + changedCol->iSetComment(txtComment->GetValue()); + + changedCol->iSetRawTypename(cbDatatype->GetValue()); + + if (!txtLength->GetValue().IsEmpty()) + changedCol->iSetLength(StrToLong(txtLength->GetValue())); + if (!txtPrecision->GetValue().IsEmpty()) + changedCol->iSetPrecision(StrToLong(txtPrecision->GetValue())); + changedCol->iSetCollation(cbCollation->GetValue()); + + changedCol->iSetStorage(cbStorage->GetValue()); + changedCol->iSetAttstattarget(StrToLong(txtAttstattarget->GetValue())); + changedCol->iSetNotNull(chkNotNull->GetValue()); + changedCol->iSetDefault(txtDefault->GetValue()); + + changedCol->GetVariables().Clear(); + for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + changedCol->GetVariables().Add(lstVariables->GetText(pos) + wxT("=") + lstVariables->GetText(pos, 1)); + } + + if(securityPage && connection->BackendMinimumVersion(8, 4)) + { + changedCol->iSetAcl(securityPage->GetUserPrivileges()); + } + + if(seclabelPage && connection->BackendMinimumVersion(9, 1)) + { + wxArrayString secLabels; + wxString providers; + wxString labels; + seclabelPage->GetCurrentProviderLabelArray(secLabels); + + if(!secLabels.IsEmpty()) + { + for(size_t pos = 0; pos < secLabels.Count(); pos += 2) + { + if(pos == 0) + { + providers += wxT("{") + secLabels.Item(pos); + labels += wxT("{") + secLabels.Item(pos + 1); + } + else + { + providers += wxT(",") + secLabels.Item(pos); + labels += wxT(",") + secLabels.Item(pos + 1); + } + } + providers += wxT("}"); + labels += wxT("}"); + } + changedCol->iSetProviders(providers); + changedCol->iSetLabels(labels); + } +} + + +void dlgColumn::ApplyChangesToDlg() +{ + txtName->SetValue(changedColumn->GetName()); + txtComment->SetValue(changedColumn->GetComment()); + + cbDatatype->SetValue(changedColumn->GetRawTypename()); + + txtLength->SetValue(NumToStr(changedColumn->GetLength())); + txtPrecision->SetValue(NumToStr(changedColumn->GetPrecision())); + cbCollation->SetValue(changedColumn->GetCollation()); + + cbStorage->SetValue(changedColumn->GetStorage()); + txtAttstattarget->SetValue(NumToStr(changedColumn->GetAttstattarget())); + chkNotNull->SetValue(changedColumn->GetNotNull()); + txtDefault->SetValue(changedColumn->GetDefault()); + + lstVariables->DeleteAllItems(); + for (size_t i = 0 ; i < changedColumn->GetVariables().GetCount() ; i++) + { + wxString item = changedColumn->GetVariables().Item(i); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + //setting privileges to changed values + SetSecurityPage(changedColumn); + + if (connection->BackendMinimumVersion(9, 1)) + { + wxArrayString seclabels = changedColumn->GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + seclabelPage->lbSeclabels->AppendItem(seclabels.Item(index), + seclabels.Item(index + 1)); + } + } + } + else if (seclabelPage != NULL) + { + seclabelPage->Disable(); + } +} + +void dlgColumn::GetVariableList(wxArrayString &variableList) +{ + wxString name; + wxString value; + for(int pos = 0; pos < lstVariables->GetItemCount(); pos++) + { + name = lstVariables->GetText(pos); + value = lstVariables->GetText(pos, 1); + variableList.Add(name + wxT("=") + value); + } +} + +void dlgColumn::GetSecLabelList(wxArrayString &secLabelList) +{ + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + seclabelPage->GetCurrentProviderLabelArray(secLabelList); +} + +wxString dlgColumn::GetDefinition() +{ + wxString sql; + sql = GetQuotedTypename(cbDatatype->GetGuessedSelection()); + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + cbCollation->GetValue(); + if (chkNotNull->GetValue()) + sql += wxT(" NOT NULL"); + + AppendIfFilled(sql, wxT(" DEFAULT "), txtDefault->GetValue()); + + return sql; +} + + +wxString dlgColumn::GetTypeOid() +{ + return dlgTypeProperty::GetTypeOid(cbDatatype->GetGuessedSelection()); +} + + +pgObject *dlgColumn::CreateObject(pgCollection *collection) +{ + pgObject *obj; + obj = columnFactory.CreateObjects(collection, 0, + wxT("\n AND attname=") + qtDbString(GetName()) + + wxT("\n AND cl.relname=") + qtDbString(table->GetName()) + + wxT("\n AND cl.relnamespace=") + table->GetSchema()->GetOidStr() + + wxT("\n")); + return obj; +} + + +void dlgColumn::OnSelChangeTyp(wxCommandEvent &ev) +{ + cbDatatype->GuessSelection(ev); + + CheckLenEnable(); + txtLength->Enable(isVarLen); + + bool isSerial = (cbDatatype->GetValue() == wxT("serial") || cbDatatype->GetValue() == wxT("bigserial") || cbDatatype->GetValue() == wxT("smallserial")); + txtDefault->Enable(!isSerial); + + CheckChange(); +} + + +void dlgColumn::CheckChange() +{ + bool enable = true; + long varlen = StrToLong(txtLength->GetValue()), + varprec = StrToLong(txtPrecision->GetValue()); + + if (column) + { + txtPrecision->Enable(column->GetTable()->GetMetaType() != PGM_VIEW && isVarPrec && varlen > 0); + + CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); + if (!connection->BackendMinimumVersion(7, 5)) + { + CheckValid(enable, !isVarLen || !txtLength->GetValue().IsEmpty() || varlen >= column->GetLength(), + _("New length must not be less than old length.")); + CheckValid(enable, !txtPrecision->IsEnabled() || varprec >= column->GetPrecision(), + _("New precision must not be less than old precision.")); + CheckValid(enable, !txtPrecision->IsEnabled() || varlen - varprec >= column->GetLength() - column->GetPrecision(), + _("New total digits must not be less than old total digits.")); + } + + if (enable) + enable = GetName() != column->GetName() + || txtDefault->GetValue() != column->GetDefault() + || txtComment->GetValue() != column->GetComment() + || chkNotNull->GetValue() != column->GetNotNull() + || (cbDatatype->GetCount() > 1 && cbDatatype->GetGuessedStringSelection() != column->GetRawTypename() && !column->GetIsArray()) + || (cbDatatype->GetCount() > 1 && cbDatatype->GetGuessedStringSelection() != column->GetRawTypename() + wxT("[]") && column->GetIsArray()) + || (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != column->GetCollation()) + || (isVarLen && varlen != column->GetLength()) + || (isVarPrec && varprec != column->GetPrecision()) + || txtAttstattarget->GetValue() != NumToStr(column->GetAttstattarget()) + || cbStorage->GetValue() != column->GetStorage() + || dirtyVars; + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + + EnableOK(enable || securityChanged); + } + else + { + txtPrecision->Enable(isVarPrec && varlen > 0); + + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); + CheckValid(enable, !isVarLen || txtLength->GetValue().IsEmpty() + || (varlen >= minVarLen && varlen <= maxVarLen && NumToStr(varlen) == txtLength->GetValue()), + _("Please specify valid length.")); + CheckValid(enable, !txtPrecision->IsEnabled() + || (varprec >= 0 && varprec <= varlen && NumToStr(varprec) == txtPrecision->GetValue()), + _("Please specify valid numeric precision (0..") + NumToStr(varlen) + wxT(").")); + + EnableOK(enable); + } +} + + +void dlgColumn::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + + +void dlgColumn::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + +void dlgColumn::OnVarnameSelChange(wxCommandEvent &ev) +{ + cbVarname->GuessSelection(ev); +} + +void dlgColumn::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + cbVarname->FindString(lstVariables->GetText(pos)); + txtValue->SetValue(value); + } +} + + +void dlgColumn::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + + dirtyVars = true; + CheckChange(); +} + + +void dlgColumn::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() >= 0) + { + lstVariables->DeleteCurrentItem(); + dirtyVars = true; + CheckChange(); + } +} + + +void dlgColumn::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgConnect.cpp b/dlg/dlgConnect.cpp new file mode 100644 index 0000000..c006660 --- /dev/null +++ b/dlg/dlgConnect.cpp @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConnect.cpp - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgConnect.h" +#include "db/pgConn.h" +#include "frm/frmHint.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" + +#include "images/connect.pngc" + + + +BEGIN_EVENT_TABLE(dlgConnect, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgConnect::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgConnect::OnCancel) +END_EVENT_TABLE() + + +#define stDescription CTRL_STATIC("stDescription") +#define chkStorePwd CTRL_CHECKBOX("chkStorePwd") +#define txtPassword CTRL_TEXT("txtPassword") + + + +dlgConnect::dlgConnect(frmMain *form, const wxString &description, bool storePwd) : + DialogWithHelp(form) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)form, wxT("dlgConnect")); + + SetIcon(*connect_png_ico); + RestorePosition(); + + // Setup the default values + stDescription->SetLabel(description); + chkStorePwd->SetValue(storePwd); + txtPassword->Enable(true); + + if (form == NULL) + chkStorePwd->Hide(); +} + +dlgConnect::~dlgConnect() +{ + SavePosition(); +} + + +wxString dlgConnect::GetHelpPage() const +{ + return wxT("connect"); +} + + +void dlgConnect::OnOK(wxCommandEvent &ev) +{ + // Display the 'save password' hint if required + if(chkStorePwd->GetValue()) + { + if (frmHint::ShowHint(this, HINT_SAVING_PASSWORDS) == wxID_CANCEL) + return; + } + + EndModal(wxID_OK); +} + + +void dlgConnect::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +int dlgConnect::Go() +{ + // Set focus on the Password textbox and show modal + txtPassword->SetFocus(); + return ShowModal(); +} + +wxString dlgConnect::GetPassword() +{ + return txtPassword->GetValue(); +} + +bool dlgConnect::GetStorePwd() +{ + return chkStorePwd->GetValue(); +} diff --git a/dlg/dlgConversion.cpp b/dlg/dlgConversion.cpp new file mode 100644 index 0000000..eea5056 --- /dev/null +++ b/dlg/dlgConversion.cpp @@ -0,0 +1,208 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConversion.cpp - PostgreSQL Conversion Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgConversion.h" +#include "schema/pgConversion.h" +#include "schema/pgSchema.h" + + +// pointer to controls +#define cbSourceEncoding CTRL_COMBOBOX("cbSourceEncoding") +#define cbTargetEncoding CTRL_COMBOBOX("cbTargetEncoding") +#define cbFunction CTRL_COMBOBOX("cbFunction") +#define chkDefault CTRL_CHECKBOX("chkDefault") + + + +BEGIN_EVENT_TABLE(dlgConversion, dlgProperty) + EVT_TEXT(XRCID("cbSourceEncoding"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbSourceEncoding"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTargetEncoding"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTargetEncoding"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbFunction"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbFunction"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *pgConversionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgConversion(this, frame, (pgConversion *)node, (pgSchema *)parent); +} + + + +dlgConversion::dlgConversion(pgaFactory *f, frmMain *frame, pgConversion *node, pgSchema *sch) + : dlgProperty(f, frame, wxT("dlgConversion")) +{ + conversion = node; + schema = sch; +} + + +pgObject *dlgConversion::GetObject() +{ + return conversion; +} + + +int dlgConversion::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(7, 4)) + txtComment->Disable(); + + if (!connection->BackendMinimumVersion(7, 5)) + cbOwner->Disable(); + + if (conversion) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbSourceEncoding->Append(conversion->GetForEncoding()); + cbSourceEncoding->SetSelection(0); + cbTargetEncoding->Append(conversion->GetToEncoding()); + cbTargetEncoding->SetSelection(0); + + cbFunction->Append(database->GetSchemaPrefix(conversion->GetProcNamespace()) + conversion->GetProc()); + cbFunction->SetSelection(0); + + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + chkDefault->SetValue(conversion->GetDefaultConversion()); + cbSourceEncoding->Disable(); + cbTargetEncoding->Disable(); + cbFunction->Disable(); + chkDefault->Disable(); + } + else + { + // create mode + + wxString qry = + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace") + wxT("\n WHERE prorettype = ") + NumToStr(PGOID_TYPE_VOID) + + wxT("\n AND pronargs = 5"); + + pgSet *set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + functions.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + cbFunction->Append(database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname"))); + + set->MoveNext(); + } + delete set; + } + + long encNo = 0; + wxString encStr; + do + { + encStr = connection->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (!encStr.IsEmpty()) + { + cbSourceEncoding->Append(encStr); + cbTargetEncoding->Append(encStr); + } + encNo++; + } + while (!encStr.IsEmpty()); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgConversion::CreateObject(pgCollection *collection) +{ + pgObject *obj = conversionFactory.CreateObjects(collection, 0, + wxT("\n AND conname = ") + qtDbString(GetName())); + + return obj; +} + + +void dlgConversion::CheckChange() +{ + if (conversion) + { + EnableOK(txtName->GetValue() != conversion->GetName() + || cbSchema->GetValue() != conversion->GetSchema()->GetName() + || txtComment->GetValue() != conversion->GetComment() + || cbOwner->GetValue() != conversion->GetOwner()); + } + else + { + bool enable = true; + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !cbSourceEncoding->GetValue().IsEmpty(), _("Please specify source encoding.")); + CheckValid(enable, !cbTargetEncoding->GetValue().IsEmpty(), _("Please specify target encoding.")); + CheckValid(enable, cbFunction->GetCurrentSelection() >= 0, _("Please specify conversion function.")); + + EnableOK(enable); + } +} + + + + +wxString dlgConversion::GetSql() +{ + wxString sql; + wxString name; + + if (conversion) + { + // edit mode + name = GetName(); + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("CONVERSION ") + schema->GetQuotedPrefix() + qtIdent(name)); + + if (cbSchema->GetValue() != conversion->GetSchema()->GetName()) + { + sql += wxT("ALTER CONVERSION ") + qtIdent(conversion->GetSchema()->GetName()) + wxT(".") + qtIdent(name) + + wxT("\n SET SCHEMA ") + qtIdent(cbSchema->GetValue()) + + wxT(";\n"); + } + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // create mode + sql = wxT("CREATE "); + if (chkDefault->GetValue()) + sql += wxT("DEFAULT "); + sql += wxT("CONVERSION ") + name + + wxT("\n FOR ") + qtDbString(cbSourceEncoding->GetValue()) + + wxT(" TO ") + qtDbString(cbTargetEncoding->GetValue()) + + wxT("\n FROM ") + functions.Item(cbFunction->GetCurrentSelection()) + + wxT(";\n"); + + AppendOwnerNew(sql, wxT("CONVERSION ") + schema->GetQuotedPrefix() + qtIdent(name)); + } + AppendComment(sql, wxT("CONVERSION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), conversion); + + return sql; +} diff --git a/dlg/dlgDatabase.cpp b/dlg/dlgDatabase.cpp new file mode 100644 index 0000000..2309bae --- /dev/null +++ b/dlg/dlgDatabase.cpp @@ -0,0 +1,900 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDatabase.cpp - PostgreSQL Database Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "dlg/dlgDatabase.h" +#include "schema/pgDatabase.h" +#include "ctl/ctlDefaultSecurityPanel.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define cbEncoding CTRL_COMBOBOX("cbEncoding") +#define cbTemplate CTRL_COMBOBOX("cbTemplate") +#define stPath CTRL_STATIC("stPath") +#define txtPath CTRL_TEXT("txtPath") +#define stTablespace CTRL_STATIC("stTablespace") +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define txtSchemaRestr CTRL_TEXT("txtSchemaRestr") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define cbVarUsername CTRL_COMBOBOX2("cbVarUsername") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbCollate CTRL_COMBOBOX2("cbCollate") +#define cbCType CTRL_COMBOBOX2("cbCType") +#define txtConnLimit CTRL_TEXT("txtConnLimit") + +dlgProperty *pgDatabaseFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + dlgDatabase *dlg = new dlgDatabase(this, frame, (pgDatabase *)node); + if (dlg && !node) + { + // use the server's connection to avoid "template1 in use" + dlg->SetConnection(parent->GetConnection()); + } + return dlg; +} + + +BEGIN_EVENT_TABLE(dlgDatabase, dlgDefaultSecurityProperty) + EVT_TEXT(XRCID("txtPath"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbEncoding"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbEncoding"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtSchemaRestr"), dlgDatabase::OnChangeRestr) + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgDatabase::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgDatabase::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgDatabase::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgDatabase::OnVarnameSelChange) + EVT_TEXT(XRCID("cbVarUsername"), dlgDatabase::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgDatabase::OnVarnameSelChange) + EVT_BUTTON(wxID_OK, dlgDatabase::OnOK) + EVT_TEXT(XRCID("cbCollate"), dlgDatabase::OnCollateSelChange) + EVT_TEXT(XRCID("cbCType"), dlgDatabase::OnCTypeSelChange) + EVT_TEXT(XRCID("txtConnLimit"), dlgDatabase::OnConnLimitChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgDatabase::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgDatabase::dlgDatabase(pgaFactory *f, frmMain *frame, pgDatabase *node) + : dlgDefaultSecurityProperty(f, frame, node, wxT("dlgDatabase"), wxT("CREATE,TEMP,CONNECT"), "CTc", node != NULL ? true : false) +{ + database = node; + schemaRestrictionOk = true; + lstVariables->CreateColumns(0, _("Username"), _("Variable"), _("Value")); + + chkValue->Hide(); + + dirtyVars = false; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + if (!node) + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value = wxT("Tc"); + securityPage->lbPrivileges->AppendItem(icon, name, value); + AppendCurrentAcl(name, value); + } +} + +pgObject *dlgDatabase::GetObject() +{ + return database; +} + + +wxString dlgDatabase::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 1) + return wxT("pg/runtime-config"); + return dlgDefaultSecurityProperty::GetHelpPage(); +} + + +int dlgDatabase::Go(bool modal) +{ + bool createDefPriv = false; + wxString strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes; + + if (connection->BackendMinimumVersion(9, 2)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(database); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgDatabase::OnChange)); + } + else + seclabelPage->Disable(); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarUsername->Append(wxT("")); + // AddUsers function of dlgDefaultSecurity has already been called. + // Hence, calling dlgProperty::AddUsers instead of that. + dlgProperty::AddUsers(cbVarUsername); + } + else + cbVarUsername->Enable(false); + + if (connection->BackendMinimumVersion(8, 0)) + { + stPath->Hide(); + txtPath->Hide(); + } + else + { + stTablespace->Hide(); + cbTablespace->Hide(); + } + + if (!connection->BackendMinimumVersion(8, 1)) + { + txtConnLimit->Disable(); + } + else + txtConnLimit->SetValidator(numericValidator); + + if (!connection->BackendMinimumVersion(8, 4)) + { + cbCollate->Disable(); + cbCType->Disable(); + } + + pgSet *set; + if (connection->BackendMinimumVersion(7, 4)) + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + else + set = connection->ExecuteSet(wxT("SELECT name, 'string' as vartype, '' as min_val, '' as max_val FROM pg_settings")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarUsername->SetSelection(0); + } + SetupVarEditor(0); + } + + if (database) + { + // edit mode + + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + + readOnly = !database->GetServer()->GetCreatePrivilege(); + + + if (connection->BackendMinimumVersion(9, 0)) + { + createDefPriv = true; + strDefPrivsOnTables = database->GetDefPrivsOnTables(); + strDefPrivsOnSeqs = database->GetDefPrivsOnSequences(); + strDefPrivsOnFuncs = database->GetDefPrivsOnFunctions(); + } + if (connection->BackendMinimumVersion(9, 2)) + strDefPrivsOnTypes = database->GetDefPrivsOnTypes(); + + if (readOnly) + { + cbVarname->Disable(); + cbVarUsername->Disable(); + txtValue->Disable(); + btnAdd->Disable(); + btnRemove->Disable(); + } + + size_t i; + wxString username; + wxString varname; + wxString varvalue; + for (i = 0 ; i < database->GetVariables().GetCount() ; i += 3) + { + username = database->GetVariables().Item(i); + varname = database->GetVariables().Item(i + 1); + varvalue = database->GetVariables().Item(i + 2); + + lstVariables->AppendItem(0, username, varname, varvalue); + } + + PrepareTablespace(cbTablespace, database->GetTablespaceOid()); + if (connection->BackendMinimumVersion(8, 4)) + cbTablespace->Enable(); + else + cbTablespace->Disable(); + txtPath->SetValue(database->GetPath()); + txtPath->Disable(); + + cbEncoding->Append(database->GetEncoding()); + cbEncoding->SetSelection(0); + + if (connection->BackendMinimumVersion(8, 1)) + { + wxString strConnLimit; + strConnLimit.Printf(wxT("%ld"), database->GetConnectionLimit()); + txtConnLimit->SetValue(strConnLimit); + } + + if (connection->BackendMinimumVersion(8, 4)) + { + cbCollate->Append(database->GetCollate()); + cbCollate->SetSelection(0); + cbCType->Append(database->GetCType()); + cbCType->SetSelection(0); + } + + cbTemplate->Disable(); + cbEncoding->Disable(); + cbCollate->Disable(); + cbCType->Disable(); + + txtSchemaRestr->SetValue(database->GetSchemaRestriction()); + } + else + { + // create mode + if (!connection->BackendMinimumVersion(8, 2)) + txtComment->Disable(); + + PrepareTablespace(cbTablespace); + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + + cbTemplate->Append(wxEmptyString); + FillCombobox(wxT("SELECT datname FROM pg_database ORDER BY datname"), cbTemplate); + cbTemplate->SetSelection(0); + + if (connection->BackendMinimumVersion(8, 4)) + { + FillCombobox(wxT("select DISTINCT(datctype) from pg_database UNION SELECT DISTINCT(datcollate) from pg_database"), cbCollate, cbCType); + if (cbCollate->FindString(wxT("C")) < 0) + { + cbCollate->AppendString(wxT("C")); + cbCType->AppendString(wxT("C")); + } + if (cbCollate->FindString(wxT("POSIX")) < 0) + { + cbCollate->AppendString(wxT("POSIX")); + cbCType->AppendString(wxT("POSIX")); + } + } + if (connection->BackendMinimumVersion(8, 1)) + { + txtConnLimit->SetValue(wxT("-1")); + } + + + long encNo = 0; + wxString encStr; + do + { + encStr = connection->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (pgConn::IsValidServerEncoding(encNo) && !encStr.IsEmpty()) + cbEncoding->Append(encStr); + + encNo++; + } + while (!encStr.IsEmpty()); + + encStr = connection->ExecuteScalar(wxT("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = 'template0'")); + encNo = cbEncoding->FindString(encStr); + + if (encNo < 0) + { + encNo = cbEncoding->FindString(wxT("UNICODE")); + if (encNo < 0) + encNo = cbEncoding->FindString(wxT("UTF8")); + } + + if (encNo >= 0) + cbEncoding->SetSelection(encNo); + + } + + // Find, and disable the CONNECT ACL option if we're on pre 8.2 + if (!connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("CONNECT"))) + { + wxLogError(_("Failed to disable the CONNECT privilege checkbox!")); + } + } + + return dlgDefaultSecurityProperty::Go(modal, createDefPriv, strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes); +} + + +pgObject *dlgDatabase::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = databaseFactory.CreateObjects(collection, 0, wxT(" WHERE datname=") + qtDbString(name) + wxT("\n")); + return obj; +} + + +#ifdef __WXMAC__ +void dlgDatabase::OnChangeSize(wxSizeEvent &ev) +{ + lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgDatabase::OnChangeRestr(wxCommandEvent &ev) +{ + if (txtSchemaRestr->GetValue().IsEmpty()) + schemaRestrictionOk = true; + else + { + wxString sql = wxT("EXPLAIN SELECT 1 FROM pg_namespace\n") + wxT("WHERE nspname IN (") + txtSchemaRestr->GetValue() + wxT(")"); + + wxLogNull nix; + wxString result = connection->ExecuteScalar(sql); + + schemaRestrictionOk = !result.IsEmpty(); + } + OnChange(ev); +} + + +void dlgDatabase::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (database) + { + database->iSetSchemaRestriction(txtSchemaRestr->GetValue().Trim()); + settings->Write(wxString::Format(wxT("Servers/%ld/Databases/%s/SchemaRestriction"), database->GetServer()->GetServerIndex(), database->GetName().c_str()), txtSchemaRestr->GetValue().Trim()); + + /* + * The connection from the database will get disconnected before execution of any + * sql statements for the database. + * + * Hence, we need to hack the execution of the default privileges statements(sqls) + * before getting disconnected from this database. So that, these statements will + * run against the current database connection, and not against the server connection. + */ + // defaultSecurityChanged will be true only for PostgreSQL 9.0 or later + if (defaultSecurityChanged) + { + wxString strDefPrivs = GetDefaultPrivileges(); + if (!executeDDLSql(strDefPrivs)) + { + EnableOK(true); + return; + } + defaultSecurityChanged = false; + } + } + dlgDefaultSecurityProperty::OnOK(ev); +} + +/* + * Execute default privileges statement + * + * - Hacked to execute the default privileges statement (sql) for dlgDatabse against this database, + * because connection for this database object is getting disconnected, and replaced by the server + * connection, before execution of any statements (sqls) in dlgPropery::apply function called + * from dlgPropery::OnOK event handler. + * + * NOTE: This will work only if the database object exists. + */ +bool dlgDatabase::executeDDLSql(const wxString &strSql) +{ + pgConn *myConn = connection; + + if (!strSql.IsEmpty()) + { + wxString tmp; + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data = (replClientData *)cbClusterSet->wxItemContainer::GetClientData(cbClusterSet->GetSelection()); + + if (data->majorVer > 1 || (data->majorVer == 1 && data->minorVer >= 2)) + { + // From slony version 2.2.0 onwards ddlscript_prepare() method is removed and + // ddlscript_complete() method arguments got changed so we have to use ddlcapture() method + // instead of ddlscript_prepare() and changed the argument of ddlscript_complete() method + if ((data->majorVer == 2 && data->minorVer >= 2) || (data->majorVer > 2)) + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlcapture(") + qtDbString(strSql) + wxT(", ") + wxT("NULL::text") + wxT(");\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + wxT("NULL::text") + wxT(");\n"); + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_prepare(") + NumToStr(data->setId) + wxT(", -1);\n") + + strSql + wxT(";\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(strSql) + wxT(", -1);\n"); + } + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(strSql) + wxT(", 0);\n"); + } + } + else + tmp = strSql; + + if (!myConn->ExecuteVoid(tmp)) + // error message is displayed inside ExecuteVoid + return false; + } + return true; +} + + +void dlgDatabase::CheckChange() +{ + bool enable = true; + + if (database) + { + long connLimit; + if (!txtConnLimit->GetValue().ToLong(&connLimit)) + connLimit = database->GetConnectionLimit(); + + enable = txtSchemaRestr->GetValue() != database->GetSchemaRestriction() + || txtComment->GetValue() != database->GetComment() + || txtName->GetValue() != database->GetName() + || cbOwner->GetValue() != database->GetOwner() + || cbTablespace->GetValue() != database->GetTablespace() + || connLimit != database->GetConnectionLimit() + || dirtyVars; + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, schemaRestrictionOk, _("Restriction not valid.")); + + // If there's a schema restriction, we need to ignore the SQL + // for the dialogue when enabling the OK button. + if (schemaRestrictionOk) + EnableOK(enable, true); + else + EnableOK(enable); +} + + +void dlgDatabase::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgDatabase::OnCollateSelChange(wxCommandEvent &ev) +{ + cbCollate->GuessSelection(ev); +} + +void dlgDatabase::OnCTypeSelChange(wxCommandEvent &ev) +{ + cbCType->GuessSelection(ev); +} + +void dlgDatabase::OnConnLimitChange(wxCommandEvent &ev) +{ + if (ev.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED) + { + wxString strConnLimit = txtConnLimit->GetValue(); + long val = 0; + if (strConnLimit.ToLong(&val)) + { + CheckChange(); + } + else if (strConnLimit.Contains(wxT("."))) + { + double val; + + // Stop Propagation of the event to the parents + ev.StopPropagation(); + if (strConnLimit.ToDouble(&val)) + { + strConnLimit.Printf(wxT("%ld"), (long)val); + txtConnLimit->SetValue(strConnLimit); + txtConnLimit->SetInsertionPointEnd(); + return; + } + } + else if (strConnLimit.length() > 9) + { + // Maximum value support is 2147483647 + wxString newVal = strConnLimit.substr(0, 10); + if (!newVal.ToLong(&val)) + { + newVal = strConnLimit.substr(0, 9); + } + ev.StopPropagation(); + txtConnLimit->SetValue(newVal); + txtConnLimit->SetInsertionPointEnd(); + return; + } + } +} + +void dlgDatabase::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->SetMinSize(wxSize(cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight())); + chkValue->GetParent()->Layout(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + txtValue->SetMinSize(wxSize(cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight())); + txtValue->GetParent()->Layout(); + } + } +} + +void dlgDatabase::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + cbVarUsername->SetValue(lstVariables->GetText(pos)); + cbVarname->SetValue(lstVariables->GetText(pos, 1)); + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + wxString value = lstVariables->GetText(pos, 2); + int sel = cbVarname->FindString(lstVariables->GetText(pos, 1)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + +void dlgDatabase::OnVarAdd(wxCommandEvent &ev) +{ + wxString username = cbVarUsername->GetValue(); + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + bool found = false; + long prevpos = -1; + for (long item = 0; item < lstVariables->GetItemCount(); item++) + { + if (name == lstVariables->GetText(item, 1)) + { + if (username == lstVariables->GetText(item)) + { + found = true; + lstVariables->SetItem(item, 2, value); + } + else + { + prevpos = item; + } + } + } + if (!found) + { + if (prevpos != -1) + { + lstVariables->InsertItem(prevpos, username, 1); + lstVariables->SetItem(prevpos, 1, name); + lstVariables->SetItem(prevpos, 2, value); + } + else + { + long pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, username, 1); + lstVariables->SetItem(pos, 1, name); + lstVariables->SetItem(pos, 2, value); + } + } + } + dirtyVars = true; + CheckChange(); +} + + +void dlgDatabase::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + dirtyVars = true; + CheckChange(); +} + + +// Note: CREATE DATABASE cannot be part of a multi-statement query as of +// PG83, and never actually would have been transaction-safe prior +// to then. Therefore, when creating a new database, only the CREATE +// statement comes from GetSql(), subsequent ALTERs come from GetSql2() +wxString dlgDatabase::GetSql() +{ + wxString sql, name; + name = GetName(); + + if (database) + { + // edit mode + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("DATABASE ") + qtIdent(name)); + + AppendComment(sql, wxT("DATABASE"), 0, database); + + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("DATABASE"), qtIdent(name)); + + if (connection->BackendMinimumVersion(8, 4)) + { + if (cbTablespace->GetCurrentSelection() > 0 && cbTablespace->GetOIDKey() > 0 + && cbTablespace->GetOIDKey() != database->GetTablespaceOid()) + sql += wxT("ALTER DATABASE ") + qtIdent(name) + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + } + if (connection->BackendMinimumVersion(8, 1)) + { + long connLimit; + + if (txtConnLimit->GetValue().IsEmpty()) + connLimit = -1; + else if (!txtConnLimit->GetValue().ToLong(&connLimit)) + connLimit = database->GetConnectionLimit(); + + if (connLimit != database->GetConnectionLimit()) + { + wxString strConnLimit; + strConnLimit << connLimit; + sql += wxT("ALTER DATABASE ") + qtIdent(name) + + wxT("\n WITH CONNECTION LIMIT = ") + + strConnLimit + + wxT(";\n"); + } + } + + if (!connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("CT"), wxT("DATABASE ") + qtIdent(name)); + else + sql += GetGrant(wxT("CTc"), wxT("DATABASE ") + qtIdent(name)); + + wxArrayString vars; + wxString username; + wxString varname; + wxString varvalue; + size_t index; + int pos; + + // copy database->GetVariables() into vars + for (index = 0 ; index < database->GetVariables().GetCount() ; index++) + vars.Add(database->GetVariables().Item(index)); + + // check for changed or added vars + for (pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + wxString newUsr = lstVariables->GetText(pos); + wxString newVar = lstVariables->GetText(pos, 1); + wxString newVal = lstVariables->GetText(pos, 2); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index += 3) + { + username = vars.Item(index); + varname = vars.Item(index + 1); + varvalue = vars.Item(index + 2); + + if (newUsr == username && newVar == varname) + { + oldVal = varvalue; + vars.RemoveAt(index); + vars.RemoveAt(index); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (newUsr.Length() == 0) + sql += wxT("ALTER DATABASE ") + qtIdent(name); + else + sql += wxT("ALTER ROLE ") + newUsr + wxT(" IN DATABASE ") + qtIdent(name); + + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); + } + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos += 3) + { + username = vars.Item(pos); + varname = vars.Item(pos + 1); + varvalue = vars.Item(pos + 2); + + if (username.Length() == 0) + { + sql += wxT("ALTER DATABASE ") + qtIdent(name) + + wxT("\n RESET ") + varname + + wxT(";\n"); + } + else + { + sql += wxT("ALTER ROLE ") + username + wxT(" IN DATABASE ") + qtIdent(name) + + wxT("\n RESET ") + varname + wxT(";\n"); + } + } + + if (defaultSecurityChanged) + sql += wxT("\n") + GetDefaultPrivileges(); + } + else + { + // create mode + sql = wxT("CREATE DATABASE ") + qtIdent(name) + + wxT("\n WITH ENCODING=") + qtDbString(cbEncoding->GetValue()); + + AppendIfFilled(sql, wxT("\n OWNER="), qtIdent(cbOwner->GetValue())); + AppendIfFilled(sql, wxT("\n TEMPLATE="), qtIdent(cbTemplate->GetValue())); + AppendIfFilled(sql, wxT("\n LOCATION="), txtPath->GetValue()); + if (connection->BackendMinimumVersion(8, 4)) + { + wxString strCollate = cbCollate->GetValue(); + if (!strCollate.IsEmpty()) + AppendIfFilled(sql, wxT("\n LC_COLLATE="), qtDbString(strCollate)); + wxString strCType = cbCType->GetValue(); + if (!strCType.IsEmpty()) + AppendIfFilled(sql, wxT("\n LC_CTYPE="), qtDbString(strCType)); + } + if (connection->BackendMinimumVersion(8, 1)) + { + AppendIfFilled(sql, wxT("\n CONNECTION LIMIT="), (txtConnLimit->GetValue() == wxT("-") ? wxT("-1") : txtConnLimit->GetValue())); + } + if (cbTablespace->GetCurrentSelection() > 0 && cbTablespace->GetOIDKey() > 0) + sql += wxT("\n TABLESPACE=") + qtIdent(cbTablespace->GetValue()); + + sql += wxT(";\n"); + } + + return sql.Trim(false); +} + +wxString dlgDatabase::GetSql2() +{ + wxString sql, name; + name = GetName(); + + // We only use GetSql2() in the CREATE case + if (!database) + { + if (connection->BackendMinimumVersion(8, 2)) + AppendComment(sql, wxT("DATABASE"), 0, database); + + if (!connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("CT"), wxT("DATABASE ") + qtIdent(name)); + else + sql += GetGrant(wxT("CTc"), wxT("DATABASE ") + qtIdent(name)); + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newUsr = lstVariables->GetText(pos); + wxString newVar = lstVariables->GetText(pos, 1); + wxString newVal = lstVariables->GetText(pos, 2); + + if (newUsr.Length() == 0) + sql += wxT("ALTER DATABASE ") + qtIdent(name); + else + sql += wxT("ALTER ROLE ") + newUsr + wxT(" IN DATABASE ") + qtIdent(name); + + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); + } + } + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("DATABASE"), qtIdent(name)); + } + + return sql; +} + +bool dlgDatabase::GetDisconnectFirst() +{ + if (database) + return true; + return false; +} + +void dlgDatabase::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgDomain.cpp b/dlg/dlgDomain.cpp new file mode 100644 index 0000000..a3992f2 --- /dev/null +++ b/dlg/dlgDomain.cpp @@ -0,0 +1,443 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDomain.cpp - PostgreSQL Domain Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgDomain.h" +#include "dlg/dlgCheck.h" +#include "schema/pgSchema.h" +#include "schema/pgCheck.h" +#include "schema/pgDomain.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define chkNotNull CTRL_CHECKBOX("chkNotNull") +#define txtDefault CTRL_TEXT("txtDefault") +#define cbCollation CTRL_COMBOBOX("cbCollation") +#define lstConstraints CTRL_LISTVIEW("lstConstraints") +#define btnAddConstr CTRL_BUTTON("btnAddConstr") +#define cbConstrType CTRL_COMBOBOX("cbConstrType") +#define btnRemoveConstr CTRL_BUTTON("btnRemoveConstr") + +BEGIN_EVENT_TABLE(dlgDomain, dlgTypeProperty) + EVT_TEXT(XRCID("txtLength"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtPrecision"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbDatatype"), dlgDomain::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgDomain::OnSelChangeTyp) + EVT_TEXT(XRCID("txLength"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDefault"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkNotNull"), dlgProperty::OnChange) + EVT_BUTTON(XRCID("btnAddConstr"), dlgDomain::OnAddConstr) + EVT_BUTTON(XRCID("btnRemoveConstr"), dlgDomain::OnRemoveConstr) + EVT_LIST_ITEM_SELECTED(XRCID("lstConstraints"), dlgDomain::OnSelChangeConstr) +END_EVENT_TABLE(); + + +dlgProperty *pgDomainFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgDomain(this, frame, (pgDomain *)node, (pgSchema *)parent); +} + + +dlgDomain::dlgDomain(pgaFactory *f, frmMain *frame, pgDomain *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgDomain")) +{ + schema = sch; + domain = node; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + txtLength->Disable(); + txtPrecision->Disable(); + + lstConstraints->CreateColumns(0, _("Constraint name"), _("Definition"), 90); +} + + +pgObject *dlgDomain::GetObject() +{ + return domain; +} + + +int dlgDomain::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(domain); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgDomain::OnChange)); + } + else + seclabelPage->Disable(); + + if (domain) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + cbDatatype->Append(domain->GetBasetype()); + AddType(wxT(" "), 0, domain->GetBasetype()); + cbDatatype->SetSelection(0); + if (domain->GetLength() >= 0) + { + txtLength->SetValue(NumToStr(domain->GetLength())); + if (domain->GetPrecision() >= 0) + txtPrecision->SetValue(NumToStr(domain->GetPrecision())); + } + chkNotNull->SetValue(domain->GetNotNull()); + txtDefault->SetValue(domain->GetDefault()); + + wxCookieType cookie; + pgObject *data = 0; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(domain->GetId(), cookie); + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + pgaFactory *factory = data->GetFactory(); + if (factory == checkFactory.GetCollectionFactory()) + constraintsItem = item; + else if (data->GetMetaType() == PGM_CONSTRAINT) + constraintsItem = item; + + if (constraintsItem) + break; + + item = mainForm->GetBrowser()->GetNextChild(domain->GetId(), cookie); + } + + if (constraintsItem) + { + pgCollection *coll = (pgCollection *)mainForm->GetBrowser()->GetObject(constraintsItem); + // make sure all constraints are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the constraints collection + item = mainForm->GetBrowser()->GetFirstChild(constraintsItem, cookie); + + // add constraints + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + switch (data->GetMetaType()) + { + case PGM_CHECK: + { + pgCheck *obj = (pgCheck *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + } + + item = mainForm->GetBrowser()->GetNextChild(constraintsItem, cookie); + } + } + + cbDatatype->Disable(); + + cbCollation->SetValue(domain->GetQuotedCollation()); + cbCollation->Disable(); + + if (!connection->BackendMinimumVersion(7, 4)) + { + cbOwner->Disable(); + txtDefault->Disable(); + chkNotNull->Disable(); + } + } + else + { + // create mode + FillDatatype(cbDatatype, false); + + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + } + + cbConstrType->Clear(); + cbConstrType->Append(_("Check")); + cbConstrType->SetSelection(0); + btnRemoveConstr->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgDomain::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = domainFactory.CreateObjects(collection, 0, + wxT(" AND d.typname=") + qtDbString(name) + + wxT("\n AND d.typnamespace=") + schema->GetOidStr() + + wxT("\n")); + return obj; +} + + +void dlgDomain::CheckChange() +{ + bool enable = true; + + if (domain) + { + enable = false; + if (connection->BackendMinimumVersion(7, 4) || lstColumns->GetItemCount() > 0) + { + enable = !GetSql().IsEmpty(); + } + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + long varlen = StrToLong(txtLength->GetValue()), + varprec = StrToLong(txtPrecision->GetValue()); + + txtPrecision->Enable(isVarPrec && varlen > 0); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbDatatype->GetGuessedSelection() >= 0, _("Please select a datatype.")); + CheckValid(enable, !isVarLen || txtLength->GetValue().IsEmpty() + || (varlen >= minVarLen && varlen <= maxVarLen && NumToStr(varlen) == txtLength->GetValue()), + _("Please specify valid length.")); + CheckValid(enable, !txtPrecision->IsEnabled() + || (varprec >= 0 && varprec <= varlen && NumToStr(varprec) == txtPrecision->GetValue()), + _("Please specify valid numeric precision (0..") + NumToStr(varlen) + wxT(").")); + } + EnableOK(enable); +} + + + +void dlgDomain::OnSelChangeTyp(wxCommandEvent &ev) +{ + if (!domain) + { + cbDatatype->GuessSelection(ev); + CheckLenEnable(); + txtLength->Enable(isVarLen); + CheckChange(); + } +} + + +void dlgDomain::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgDomain::GetSql() +{ + wxString sql, name; + int pos; + wxString definition; + int index = -1; + wxArrayString tmpDef = previousConstraints; + wxString tmpsql = wxEmptyString; + + if (domain) + { + // edit mode + name = GetName(); + + if (txtName->GetValue() != domain->GetName()) + { + + if (connection->BackendMinimumVersion(9, 2)) + AppendNameChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); + else + AppendNameChange(sql, wxT("TYPE ") + domain->GetQuotedFullIdentifier()); + } + if (chkNotNull->GetValue() != domain->GetNotNull()) + { + sql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier(); + if (chkNotNull->GetValue()) + sql += wxT("\n SET NOT NULL;\n"); + else + sql += wxT("\n DROP NOT NULL;\n"); + } + if (txtDefault->GetValue() != domain->GetDefault()) + { + sql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier(); + if (txtDefault->GetValue().IsEmpty()) + sql += wxT("\n DROP DEFAULT;\n"); + else + sql += wxT("\n SET DEFAULT ") + txtDefault->GetValue() + wxT(";\n"); + } + + // Build a temporary list of ADD CONSTRAINTs, and fixup the list to remove + for (pos = 0; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString conname = qtIdent(lstConstraints->GetItemText(pos)); + definition = conname; + definition += wxT(" CHECK ") + constraintsDefinition.Item(pos); + index = tmpDef.Index(definition); + if (index >= 0) + tmpDef.RemoveAt(index); + else + { + tmpsql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier() + + wxT("\n ADD"); + if (!conname.IsEmpty()) + tmpsql += wxT(" CONSTRAINT "); + + tmpsql += definition + wxT(";\n"); + } + } + + // Add the DROP CONSTRAINTs... + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + if (definition[0U] == '"') + definition = definition.Mid(1).BeforeFirst('"'); + else + definition = definition.BeforeFirst(' '); + sql += wxT("ALTER DOMAIN ") + domain->GetQuotedFullIdentifier() + + wxT("\n DROP CONSTRAINT ") + qtIdent(definition) + wxT(";\n"); + + } + + // Add the ADD CONSTRAINTs... + sql += tmpsql; + + AppendOwnerChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); + AppendSchemaChange(sql, wxT("DOMAIN ") + domain->GetQuotedFullIdentifier()); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE DOMAIN ") + name + + wxT("\n AS ") + GetQuotedTypename(cbDatatype->GetGuessedSelection()); + + if (!cbCollation->GetValue().IsEmpty() && cbCollation->GetValue() != wxT("pg_catalog.\"default\"")) + sql += wxT("\n COLLATE ") + cbCollation->GetValue(); + + AppendIfFilled(sql, wxT("\n DEFAULT "), txtDefault->GetValue()); + + if (chkNotNull->GetValue()) + sql += wxT("\n NOT NULL"); + + for (pos = 0 ; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString name = lstConstraints->GetItemText(pos); + wxString definition = constraintsDefinition.Item(pos); + if (!name.IsEmpty()) + sql += wxT("\n CONSTRAINT ") + qtIdent(name) + wxT(" CHECK ") + definition; + else + sql += wxT("\n CHECK ") + definition; + } + + sql += wxT(";\n"); + + AppendOwnerNew(sql, wxT("DOMAIN ") + name); + } + + AppendComment(sql, wxT("DOMAIN ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), domain); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("DOMAIN"), name); + + return sql; +} + +void dlgDomain::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgDomain::OnAddConstr(wxCommandEvent &ev) +{ + int sel = cbConstrType->GetCurrentSelection(); + + switch (sel) + { + case 0: // Check + { + dlgCheck chk(&checkFactory, mainForm); + chk.CenterOnParent(); + chk.SetDatabase(database); + if (chk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = chk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(checkFactory.GetIconId(), chk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + } + CheckChange(); +} + + +void dlgDomain::OnRemoveConstr(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected constraint?"), _("Remove constraint?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + int pos = lstConstraints->GetSelection(); + if (pos < 0) + return; + + lstConstraints->DeleteItem(pos); + constraintsDefinition.RemoveAt(pos); + btnRemoveConstr->Disable(); + + CheckChange(); +} + + +void dlgDomain::OnSelChangeConstr(wxListEvent &ev) +{ + btnRemoveConstr->Enable(); +} + + diff --git a/dlg/dlgEditGridOptions.cpp b/dlg/dlgEditGridOptions.cpp new file mode 100644 index 0000000..349ac03 --- /dev/null +++ b/dlg/dlgEditGridOptions.cpp @@ -0,0 +1,391 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEditGridOptions.cpp - Edit Grid Box Options +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" + +#include "frm/frmEditGrid.h" +#include "dlg/dlgEditGridOptions.h" +#include "schema/pgTable.h" +#include "schema/pgView.h" + +// Icons +#include "images/sortfilter.pngc" + +#define nbOptions CTRL_NOTEBOOK("nbOptions") +#define btnAsc CTRL_BUTTON("btnAsc") +#define btnDesc CTRL_BUTTON("btnDesc") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define btnValidate CTRL_BUTTON("btnValidate") +#define cboColumns CTRL_COMBOBOX("cboColumns") +#define lstSortCols CTRL_LISTVIEW("lstSortCols") +#define pnlSort CTRL_PANEL("pnlSort") +#define pnlFilter CTRL_PANEL("pnlFilter") +#define filter CTRL_SQLBOX("sqlFilter") + +BEGIN_EVENT_TABLE(dlgEditGridOptions, pgDialog) + EVT_CLOSE( dlgEditGridOptions::OnClose) + EVT_BUTTON (wxID_OK, dlgEditGridOptions::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgEditGridOptions::OnCancel) + EVT_BUTTON (wxID_REMOVE, dlgEditGridOptions::OnRemove) + EVT_BUTTON (XRCID("btnAsc"), dlgEditGridOptions::OnAsc) + EVT_BUTTON (XRCID("btnDesc"), dlgEditGridOptions::OnDesc) + EVT_BUTTON (XRCID("btnValidate"), dlgEditGridOptions::OnValidate) + EVT_COMBOBOX (XRCID("cboColumns"), dlgEditGridOptions::OnCboColumnsChange) + EVT_LIST_ITEM_SELECTED (XRCID("lstSortCols"), dlgEditGridOptions::OnLstSortColsChange) + EVT_LIST_ITEM_DESELECTED (XRCID("lstSortCols"), dlgEditGridOptions::OnLstSortColsChange) + EVT_STC_MODIFIED (XRCID("sqlFilter"), dlgEditGridOptions::OnFilterChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgEditGridOptions::OnChangeSize) +#endif +END_EVENT_TABLE() + +dlgEditGridOptions::dlgEditGridOptions(frmEditGrid *win, pgConn *conn, const wxString &rel, ctlSQLEditGrid *grid) +{ + editGrid = grid; + connection = conn; + relation = rel; + parent = win; + SetFont(settings->GetSystemFont()); + LoadResource(win, wxT("dlgEditGridOptions")); + conv = conn->GetConv(); + + // Icon + SetIcon(*sortfilter_png_ico); + RestorePosition(); + + int cols = grid->GetNumberCols(); + long x; + + for (x = 0; x < cols; x++) + cboColumns->Append(grid->GetColLabelValue(x).BeforeFirst('\n')); + + // Setup the buttons + wxCommandEvent nullEvent; + OnCboColumnsChange(nullEvent); + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); + + // Setup the list box + int leftSize = 140, rightSize; + leftSize = ConvertDialogToPixels(wxPoint(leftSize, 0)).x; + rightSize = lstSortCols->GetClientSize().GetWidth() - leftSize; + // This check is to work around a bug in wxGTK that doesn't set + // appropriately the GetClientSize(). + // Without this workaround, we have an invisible second column. + if (rightSize < leftSize) + rightSize = leftSize + 1; + lstSortCols->InsertColumn(0, _("Column name"), wxLIST_FORMAT_LEFT, leftSize); + lstSortCols->InsertColumn(1, _("Sort order"), wxLIST_FORMAT_LEFT, rightSize); + + // Setup the filter SQL box. This is an XRC 'unknown' control so must + // be manually created and attache to the XRC global resource. + filter->SetText(parent->GetFilter()); + + // Get the current sort columns, and populate the listbox. + // The current columns will be parsed char by char to allow us + // to cope with quoted column names with commas in them (let's hope + // no one ever does that, but sod's law etc....) + bool inColumn = true, inQuote = false; + wxString sortCols = parent->GetSortCols(); + wxString col, dir; + size_t pos, len = sortCols.Length(); + int itm = 0; + + for (pos = 0; pos < len; pos++) + { + if (inColumn) + { + if (sortCols.GetChar(pos) == '"') inQuote = !inQuote; + if (!inQuote && (sortCols.GetChar(pos) == ' ' || sortCols.GetChar(pos) == ',')) + inColumn = false; + else if (sortCols.GetChar(pos) != '"') col += sortCols.GetChar(pos); + } + else + { + if (sortCols.GetChar(pos - 1) == ',') + { + inColumn = true; + lstSortCols->InsertItem(itm, col); + if (dir.GetChar(0) == 'D') + { + lstSortCols->SetItem(itm, 1, _("Descending")); + lstSortCols->SetItemData(itm, 0); + } + else + { + lstSortCols->SetItem(itm, 1, _("Ascending")); + lstSortCols->SetItemData(itm, 1); + } + col = wxT(""); + dir = wxT(""); + ++itm; + } + else + { + dir += sortCols.GetChar(pos); + } + } + } + + // Insert the last column + if (col.Length() > 0) + { + lstSortCols->InsertItem(itm, col); + if (dir.GetChar(0) == 'D') + { + lstSortCols->SetItem(itm, 1, _("Descending")); + lstSortCols->SetItemData(itm, 0); + } + else + { + lstSortCols->SetItem(itm, 1, _("Ascending")); + lstSortCols->SetItemData(itm, 1); + } + } + + // Finally (phew!) remove all columns we're already sorting on from the list. + long count = lstSortCols->GetItemCount(); + + for (x = 0; x < count; x++) + { + int idx = cboColumns->FindString(lstSortCols->GetItemText(x)); + if (idx >= 0) + cboColumns->Delete(idx); + } + + // Display the appropriate tab. If the EditGrid is not shown, we must be + // doing a View Filtered Data. + if (!parent->IsShown()) + nbOptions->DeletePage(0); + + btnValidate->Disable(); + filter->SetFocus(); +} + +dlgEditGridOptions::~dlgEditGridOptions() +{ + SavePosition(); +} + +// Enable/disable the validation button +void dlgEditGridOptions::OnFilterChange(wxStyledTextEvent &ev) +{ + btnValidate->Enable(!filter->GetText().Trim().IsEmpty()); +} + +void dlgEditGridOptions::OnRemove(wxCommandEvent &ev) +{ + long itm = -1; + itm = lstSortCols->GetNextItem(itm, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + cboColumns->Append(lstSortCols->GetItemText(itm)); + lstSortCols->DeleteItem(itm); + if (lstSortCols->GetItemCount() > 0) + { + if (lstSortCols->GetItemCount() < itm + 1) + lstSortCols->SetItemState(lstSortCols->GetItemCount() - 1, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + else + lstSortCols->SetItemState(itm, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); + } + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); +} + + +void dlgEditGridOptions::OnAsc(wxCommandEvent &ev) +{ + long itm = lstSortCols->GetItemCount(); + lstSortCols->InsertItem(itm, cboColumns->GetValue()); + lstSortCols->SetItem(itm, 1, _("Ascending")); + lstSortCols->SetItemData(itm, 1); + cboColumns->Delete(cboColumns->GetCurrentSelection()); + + // Setup the buttons + OnCboColumnsChange(ev); + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); +} + +void dlgEditGridOptions::OnDesc(wxCommandEvent &ev) +{ + long itm = lstSortCols->GetItemCount(); + lstSortCols->InsertItem(itm, cboColumns->GetValue()); + lstSortCols->SetItem(itm, 1, _("Descending")); + lstSortCols->SetItemData(itm, 0); + cboColumns->Delete(cboColumns->GetCurrentSelection()); + + // Setup the buttons + OnCboColumnsChange(ev); + wxListEvent nullLstEvent; + OnLstSortColsChange(nullLstEvent); +} + +#ifdef __WXMAC__ +void dlgEditGridOptions::OnChangeSize(wxSizeEvent &ev) +{ + if (lstSortCols) + lstSortCols->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +void dlgEditGridOptions::OnValidate(wxCommandEvent &ev) +{ + if (Validate()) + wxMessageBox(_("Filter string syntax validates OK!"), _("Syntax Validation"), wxICON_INFORMATION | wxOK); +} + +void dlgEditGridOptions::OnCboColumnsChange(wxCommandEvent &ev) +{ + // Set the command buttons appropriately + if (cboColumns->GetCurrentSelection() == wxNOT_FOUND) + { + btnAsc->Enable(false); + btnDesc->Enable(false); + } + else + { + btnAsc->Enable(true); + btnDesc->Enable(true); + } +} + +void dlgEditGridOptions::OnLstSortColsChange(wxListEvent &ev) +{ + // Set the command buttons appropriately + if (lstSortCols->GetSelectedItemCount() == 0) + btnRemove->Enable(false); + else + btnRemove->Enable(true); +} + +void dlgEditGridOptions::OnCancel(wxCommandEvent &ev) +{ + EndModal(false); +} + + +void dlgEditGridOptions::OnClose(wxCloseEvent &ev) +{ + EndModal(false); +} + +void dlgEditGridOptions::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + // Check the filter syntax + if (!Validate()) return; + + if (nbOptions->GetPageCount() > 1) + { + wxString sortCols; + long x, count = lstSortCols->GetItemCount(); + + for (x = 0; x < count; x++) + { + sortCols += qtIdent(lstSortCols->GetItemText(x)); + if (lstSortCols->GetItemData(x) == 0) + sortCols += wxT(" DESC"); + else + sortCols += wxT(" ASC"); + sortCols += wxT(", "); + } + + if (sortCols.Length() > 2) + { + sortCols.RemoveLast(); + sortCols.RemoveLast(); + } + + parent->SetSortCols(sortCols); + } + + parent->SetFilter(filter->GetText().Trim()); + EndModal(true); +} + +bool dlgEditGridOptions::Validate() +{ + winMain->StartMsg(_("Validating filter string")); + filter->MarkerDeleteAll(0); + if (!filter->GetText().Trim().Length()) + { + winMain->EndMsg(); + return true; + } + + wxString sql = wxT("EXPLAIN SELECT * FROM ") + relation + wxT(" WHERE "); + int queryOffset = sql.Length(); + sql += filter->GetText(); + + PGresult *qryRes; + qryRes = PQexec(connection->connection(), sql.mb_str(*conv)); + int res = PQresultStatus(qryRes); + + // Check for errors + if (res == PGRES_TUPLES_OK || + res == PGRES_COMMAND_OK) + { + // No errors, all OK! + winMain->EndMsg(); + return true; + } + + // Figure out where the error is + wxString errMsg = connection->GetLastError(); + + wxString atChar = wxT(" at character "); + int chp = errMsg.Find(atChar); + + if (chp > 0) + { + int selStart = filter->GetSelectionStart(), selEnd = filter->GetSelectionEnd(); + if (selStart == selEnd) + selStart = 0; + + long errPos = 0; + errMsg.Mid(chp + atChar.Length()).ToLong(&errPos); + errPos -= queryOffset; // do not count EXPLAIN or similar + wxLogError(wxT("%s"), _("ERROR: Syntax error at character %d!"), errPos); + + int line = 0, maxLine = filter->GetLineCount(); + while (line < maxLine && filter->GetLineEndPosition(line) < errPos + selStart + 1) + line++; + if (line < maxLine) + { + filter->MarkerAdd(line, 0); + filter->EnsureVisible(line); + } + } + else + wxLogError(wxT("%s"), errMsg.BeforeFirst('\n').c_str()); + + // Cleanup + PQclear(qryRes); + winMain->EndMsg(); + return false; +} diff --git a/dlg/dlgEventTrigger.cpp b/dlg/dlgEventTrigger.cpp new file mode 100644 index 0000000..b04cbec --- /dev/null +++ b/dlg/dlgEventTrigger.cpp @@ -0,0 +1,247 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEventTrigger.cpp - PostgreSQL Trigger Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgEventTrigger.h" +#include "schema/pgEventTrigger.h" +#include "ctl/ctlSeclabelPanel.h" + +// pointer to controls +#define chkEnable CTRL_CHECKBOX("chkEnable") +#define rdbEnableStatus CTRL_RADIOBOX("rdbEnableStatus") +#define cbFunction CTRL_COMBOBOX2("cbFunction") +#define rdbEvents CTRL_RADIOBOX("rdbEvents") +#define txtWhen CTRL_TEXT("txtWhen") +#define cbOwner CTRL_COMBOBOX2("cbOwner") + +BEGIN_EVENT_TABLE(dlgEventTrigger, dlgProperty) + EVT_CHECKBOX(XRCID("chkEnable"), dlgEventTrigger::OnChangeEnable) + EVT_RADIOBOX(XRCID("rdbEnableStatus"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbFunction"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rdbEvents"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtWhen"), dlgProperty::OnChange) +END_EVENT_TABLE(); + +dlgEventTrigger::dlgEventTrigger(pgaFactory *factory, frmMain *frame, pgEventTrigger *node, pgObject *parent) + : dlgProperty(factory, frame, wxT("dlgEventTrigger")) +{ + seclabelPage = new ctlSeclabelPanel(nbNotebook); + eventTrigger = node; +} + +dlgProperty *pgEventTriggerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgEventTrigger(this, frame, (pgEventTrigger *)node, parent); +} + +wxString dlgEventTrigger::GetSql() +{ + wxString sql = wxEmptyString; + wxString name = GetName(); + + if (eventTrigger) + { + if (!GetName().IsEmpty() && GetName() != eventTrigger->GetName()) + sql = wxT("ALTER EVENT TRIGGER ") + eventTrigger->GetQuotedFullIdentifier() + wxT("\nRENAME TO ") + qtIdent(GetName()) + wxT(";\n\n"); + + if (!cbOwner->GetValue().IsEmpty() && cbOwner->GetValue() != eventTrigger->GetOwner()) + sql += wxT("ALTER EVENT TRIGGER ") + eventTrigger->GetQuotedFullIdentifier() + wxT("\nOWNER TO ") + cbOwner->GetValue() + wxT(";\n\n"); + + if (rdbEnableStatus->GetSelection() != 0 && chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + ((rdbEnableStatus->GetSelection() == 1) ? wxT(" ENABLE REPLICA ;\n\n") : wxT(" ENABLE ALWAYS ;\n\n")); + else if (!chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + wxT(" DISABLE ;\n\n"); + } + + if (!eventTrigger || + ( + cbFunction->GetValue() != (eventTrigger->GetFunction()) || + rdbEvents->GetStringSelection().Lower() != (eventTrigger->GetEventName().Lower()) || + txtWhen->GetValue() != (eventTrigger->GetWhen()) + ) + ) + { + if (eventTrigger) + sql = wxT("DROP EVENT TRIGGER IF EXISTS ") + ((eventTrigger) ? qtIdent(eventTrigger->GetName()) : qtIdent(GetName())) + wxT(";\n\n"); + + sql += wxT("CREATE EVENT TRIGGER ") + qtIdent(name) + wxT(" ON "); + + if (rdbEvents->GetSelection() == 0) + sql += wxT(" DDL_COMMAND_START "); + else if (rdbEvents->GetSelection() == 1) + sql += wxT(" DDL_COMMAND_END "); + else + sql += wxT(" SQL_DROP "); + + if (!txtWhen->IsEmpty()) + sql += wxT("\nWHEN TAG IN (") + txtWhen->GetValue() + wxT(")"); + + if (!cbFunction->GetValue().IsEmpty()) + sql += wxT("\nEXECUTE PROCEDURE ") + (cbFunction->GetValue()) + wxT("();\n\n"); + + if (rdbEnableStatus->GetSelection() != 0 && chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + ((rdbEnableStatus->GetSelection() == 1) ? wxT(" ENABLE REPLICA ;\n\n") : wxT(" ENABLE ALWAYS ;\n\n")); + else if (!chkEnable->GetValue()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(name) + wxT(" DISABLE ;\n\n"); + + if (!eventTrigger && !cbOwner->GetValue().IsEmpty()) + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) + wxT("\nOWNER TO ") + cbOwner->GetValue() + wxT(";\n\n"); + } + + AppendComment(sql, wxT("EVENT TRIGGER ") + qtIdent(GetName()), eventTrigger); + + if (seclabelPage) + sql += seclabelPage->GetSqlForSecLabels(wxT("EVENT TRIGGER"), qtIdent(name)); + + return sql; +} + +pgObject *dlgEventTrigger::CreateObject(pgCollection *pgcol) +{ + pgObject *obj = eventTriggerFactory.CreateObjects(pgcol, 0, + wxT(" \n AND e.evtname = ") + qtDbString(GetName())); + return obj; +} + +pgObject *dlgEventTrigger::GetObject() +{ + return eventTrigger; +} + +int dlgEventTrigger::Go(bool modal) +{ + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(eventTrigger); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgEventTrigger::OnChange)); + + if (eventTrigger) + { + // Edit mode + chkEnable->SetValue(eventTrigger->GetEnabled()); + + if (eventTrigger->GetEnableStatus() == wxT("enabled")) + rdbEnableStatus->SetSelection(0); + else if(eventTrigger->GetEnableStatus() == wxT("replica")) + rdbEnableStatus->SetSelection(1); + else if(eventTrigger->GetEnableStatus() == wxT("always")) + rdbEnableStatus->SetSelection(2); + else + rdbEnableStatus->Disable(); + + if(eventTrigger->GetEventName().Lower() == wxT("ddl command start")) + rdbEvents->SetSelection(0); + else if(eventTrigger->GetEventName().Lower() == wxT("ddl command end")) + rdbEvents->SetSelection(1); + else + rdbEvents->SetSelection(2); + + cbFunction->SetValue(eventTrigger->GetFunction()); + cbOwner->SetValue(eventTrigger->GetOwner()); + (!eventTrigger->GetWhen().IsEmpty()) ? txtWhen->SetValue(eventTrigger->GetWhen()) : txtWhen->SetValue(wxEmptyString); + } + else + { + // Create mode + chkEnable->SetValue(true); + rdbEnableStatus->Disable(); + } + + pgSet *funcSet = connection->ExecuteSet( + wxT("SELECT quote_ident(nspname) || '.' || quote_ident(proname)\n") + wxT(" FROM pg_proc p, pg_namespace n, pg_language l\n") + wxT(" WHERE p.pronamespace = n.oid AND p.prolang = l.oid AND p.pronargs = 0 AND l.lanname != 'sql' AND prorettype::regtype::text = 'event_trigger'\n") + wxT(" ORDER BY nspname ASC, proname ASC ")); + if (funcSet) + { + while (!funcSet->Eof()) + { + cbFunction->Append(funcSet->GetVal(0)); + funcSet->MoveNext(); + } + delete funcSet; + } + + pgSet *userSet = connection->ExecuteSet( + wxT("SELECT usename ") + wxT("FROM pg_user ") + wxT("WHERE usesuper IS TRUE")); + if (userSet) + { + while (!userSet->Eof()) + { + cbOwner->Append(userSet->GetVal(0)); + userSet->MoveNext(); + } + delete userSet; + } + + return dlgProperty::Go(modal); +} + +void dlgEventTrigger::CheckChange() +{ + bool enable = true; + + wxString function = cbFunction->GetValue(); + wxString name = GetName(); + wxString owner = cbOwner->GetValue(); + + (chkEnable->GetValue()) ? rdbEnableStatus->Enable() : rdbEnableStatus->Disable(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify event trigger name.")); + CheckValid(enable, !owner.IsEmpty(), _("Please specify owner of event trigger.")); + CheckValid(enable, !function.IsEmpty(), _("Please specify event trigger function.")); + + if (eventTrigger) + { + EnableOK(enable && + (txtComment->GetValue() != eventTrigger->GetComment() || + txtName->GetValue() != eventTrigger->GetName() || + txtWhen->GetValue() != eventTrigger->GetWhen() || + chkEnable->GetValue() != eventTrigger->GetEnabled() || + rdbEvents->GetStringSelection().Lower() != eventTrigger->GetEventName().Lower() || + rdbEnableStatus->GetStringSelection().Lower() != eventTrigger->GetEnableStatus().Lower() || + !function.IsEmpty() || + !owner.IsEmpty() + ) + ); + } + else + { + EnableOK(enable); + } +} + +bool dlgEventTrigger::IsUpToDate() +{ + if (eventTrigger && !eventTrigger->IsUpToDate()) + return false; + else + return true; +} + +void dlgEventTrigger::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + +void dlgEventTrigger::OnChangeEnable(wxCommandEvent &ev) +{ + CheckChange(); +} diff --git a/dlg/dlgExtTable.cpp b/dlg/dlgExtTable.cpp new file mode 100644 index 0000000..d6f47a8 --- /dev/null +++ b/dlg/dlgExtTable.cpp @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtTable.cpp - Greenplum Externtal Table Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgExtTable.h" +#include "schema/gpExtTable.h" +#include "schema/pgSchema.h" + + + +// pointer to controls +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") + + + +BEGIN_EVENT_TABLE(dlgExtTable, dlgSecurityProperty) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) +END_EVENT_TABLE(); + + +dlgProperty *gpExtTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgExtTable(this, frame, (gpExtTable *)node, (pgSchema *)parent); +} + +dlgExtTable::dlgExtTable(pgaFactory *f, frmMain *frame, gpExtTable *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgExtTable"), wxT("SELECT"), "r") +{ + schema = sch; + extTable = node; + +} + + +pgObject *dlgExtTable::GetObject() +{ + return extTable; +} + + +int dlgExtTable::Go(bool modal) +{ + int returncode; + + if (extTable) + { + // edit mode + + // TODO: Make this more like dlgTable, so that it is easier to use. + // Right now, this is just dummy code until that code is written. + txtSqlBox->SetText(wxT("(") + extTable->GetSql(NULL).AfterFirst('(')); + oldDefinition = txtSqlBox->GetText(); + txtSqlBox->Enable(false); + } + else + { + // create mode + } + + returncode = dlgSecurityProperty::Go(modal); + + // This fixes a UI glitch on MacOS X and Windows + // Because of the new layout code, the Privileges pane don't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + return returncode; +} + + +pgObject *dlgExtTable::CreateObject(pgCollection *collection) +{ + pgObject *obj = extTableFactory.CreateObjects(collection, 0, + wxT("\n AND c.relname=") + qtDbString(txtName->GetValue()) + + wxT("\n AND c.relnamespace=") + schema->GetOidStr()); + return obj; +} + + +void dlgExtTable::CheckChange() +{ + wxString name = GetName(); + if(!name.IsEmpty()) + { + if (extTable) + EnableOK(txtComment->GetValue() != extTable->GetComment() + || txtSqlBox->GetText() != oldDefinition + || cbOwner->GetValue() != extTable->GetOwner() + || name != extTable->GetName()); + else + EnableOK(!txtComment->GetValue().IsEmpty() + || !txtSqlBox->GetText().IsEmpty() + || !cbOwner->GetValue().IsEmpty()); + } + else + { + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, txtSqlBox->GetText().Length() > 0 , _("Please enter external table definition.")); + + EnableOK(enable); + } +} + + +wxString dlgExtTable::GetSql() +{ + wxString sql, name = GetName(); + + + if (extTable) + { + // edit mode + + if (name != extTable->GetName()) + { + sql += wxT("ALTER TABLE ") + extTable->GetQuotedFullIdentifier() + + wxT(" RENAME TO ") + qtIdent(name) + wxT(";\n"); + } + } + + if (!extTable || txtSqlBox->GetText() != oldDefinition) + { + sql += wxT("CREATE EXTERNAL TABLE ") + schema->GetQuotedPrefix() + qtIdent(name) + wxT("\n") + + txtSqlBox->GetText() + + wxT(";\n"); + } + + if (extTable) + AppendOwnerChange(sql, wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + else + AppendOwnerNew(sql, wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + + + sql += GetGrant(wxT("r"), wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + + AppendComment(sql, wxT("TABLE"), schema, extTable); + return sql; +} + +bool dlgExtTable::IsUpToDate() +{ + if (extTable && !extTable->IsUpToDate()) + return false; + else + return true; +} + diff --git a/dlg/dlgExtension.cpp b/dlg/dlgExtension.cpp new file mode 100644 index 0000000..cfa62a3 --- /dev/null +++ b/dlg/dlgExtension.cpp @@ -0,0 +1,198 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtension.cpp - PostgreSQL Extension Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgExtension.h" +#include "schema/pgExtension.h" + + +// pointer to controls +#define cbName CTRL_COMBOBOX("cbName") +#define cbObjectsSchema CTRL_COMBOBOX("cbObjectsSchema") +#define cbVersion CTRL_COMBOBOX("cbVersion") + + +dlgProperty *pgExtensionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgExtension(this, frame, (pgExtension *)node); +} + + +BEGIN_EVENT_TABLE(dlgExtension, dlgProperty) + EVT_TEXT(XRCID("cbName"), dlgExtension::OnChangeName) + EVT_COMBOBOX(XRCID("cbName"), dlgExtension::OnChangeName) + EVT_TEXT(XRCID("cbObjectsSchema"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbObjectsSchema"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbVersion"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbVersion"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgExtension::dlgExtension(pgaFactory *f, frmMain *frame, pgExtension *node) + : dlgProperty(f, frame, wxT("dlgExtension")) +{ + extension = node; +} + + +pgObject *dlgExtension::GetObject() +{ + return extension; +} + + +int dlgExtension::Go(bool modal) +{ + txtComment->Disable(); + + // add all schemas + cbObjectsSchema->Append(wxEmptyString); + pgSetIterator schemas(connection, + wxT("SELECT nspname FROM pg_namespace\n") + wxT(" ORDER BY nspname")); + + while (schemas.RowsLeft()) + cbObjectsSchema->Append(schemas.GetVal(wxT("nspname"))); + cbObjectsSchema->SetSelection(0); + + if (extension) + { + // edit mode + cbName->Append(extension->GetName()); + cbName->SetSelection(0); + cbName->Disable(); + + cbObjectsSchema->SetValue(extension->GetSchemaStr()); + cbObjectsSchema->Enable(extension->GetIsRelocatable()); + + // add all versions + cbVersion->Clear(); + cbVersion->Append(wxEmptyString); + pgSetIterator versions(connection, + wxT("SELECT version, relocatable FROM pg_available_extension_versions\n") + wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ") + wxT(" ORDER BY version")); + + while (versions.RowsLeft()) + cbVersion->Append(versions.GetVal(wxT("version"))); + cbVersion->SetValue(extension->GetVersion()); + } + else + { + // create mode + + // add available extensions (but not the installed ones) + cbName->Append(wxEmptyString); + pgSetIterator extensions(connection, + wxT("SELECT name FROM pg_available_extensions\n") + wxT(" WHERE installed_version IS NULL\n") + wxT(" ORDER BY name")); + + while (extensions.RowsLeft()) + cbName->Append(extensions.GetVal(wxT("name"))); + cbName->SetSelection(0); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgExtension::CreateObject(pgCollection *collection) +{ + wxString name = cbName->wxComboBox::GetValue(); + + pgObject *obj = extensionFactory.CreateObjects(collection, 0, wxT("\n AND extname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgExtension::OnChangeName(wxCommandEvent &ev) +{ + bool relocatable; + + // add all versions + cbVersion->Clear(); + cbVersion->Append(wxEmptyString); + pgSetIterator versions(connection, + wxT("SELECT version, relocatable FROM pg_available_extension_versions\n") + wxT(" WHERE name=") + qtDbString(cbName->GetValue()) + wxT(" ") + wxT(" ORDER BY version")); + + while (versions.RowsLeft()) + { + relocatable = versions.GetBool(wxT("relocatable")); + cbVersion->Append(versions.GetVal(wxT("version"))); + } + cbVersion->SetSelection(0); + + if (relocatable) + { + cbObjectsSchema->Enable(); + } + else + { + cbObjectsSchema->SetSelection(0); + cbObjectsSchema->Disable(); + } + + OnChange(ev); +} + + +void dlgExtension::CheckChange() +{ + bool didChange = true; + if (extension) + { + didChange = cbObjectsSchema->GetValue() != extension->GetSchemaStr() + || cbVersion->GetValue() != extension->GetVersion(); + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !cbName->GetValue().IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + +wxString dlgExtension::GetSql() +{ + wxString sql; + + if (extension) + { + // edit mode + if (cbObjectsSchema->GetValue() != extension->GetSchemaStr()) + sql += wxT("ALTER EXTENSION ") + qtIdent(extension->GetName()) + + wxT("\n SET SCHEMA ") + qtIdent(cbObjectsSchema->GetValue()) + wxT(";\n"); + if (cbVersion->GetValue() != extension->GetVersion()) + sql += wxT("ALTER EXTENSION ") + qtIdent(extension->GetName()) + + wxT("\n UPDATE TO ") + qtIdent(cbVersion->GetValue()) + wxT(";\n"); + } + else + { + sql = wxT("CREATE EXTENSION ") + qtIdent(cbName->GetValue()); + AppendIfFilled(sql, wxT("\n SCHEMA "), qtIdent(cbObjectsSchema->GetValue())); + AppendIfFilled(sql, wxT("\n VERSION "), qtIdent(cbVersion->GetValue())); + } + + return sql; +} diff --git a/dlg/dlgFindReplace.cpp b/dlg/dlgFindReplace.cpp new file mode 100644 index 0000000..1942be4 --- /dev/null +++ b/dlg/dlgFindReplace.cpp @@ -0,0 +1,367 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFindReplace.cpp - Search and replace +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgFindReplace.h" +#include "ctl/ctlSQLBox.h" + +BEGIN_EVENT_TABLE(dlgFindReplace, pgDialog) + EVT_BUTTON (wxID_FIND, dlgFindReplace::OnFind) + EVT_BUTTON (wxID_REPLACE, dlgFindReplace::OnReplace) + EVT_BUTTON (XRCID("wxID_REPLACEALL"), dlgFindReplace::OnReplaceAll) + EVT_BUTTON (wxID_CANCEL, dlgFindReplace::OnCancel) + EVT_RADIOBUTTON(XRCID("rdOriginCursor"), dlgFindReplace::OnChange) + EVT_RADIOBUTTON(XRCID("rdOriginTop"), dlgFindReplace::OnChange) + EVT_CHECKBOX(XRCID("chkOptionsUseRegexps"), dlgFindReplace::OnChange) + EVT_CLOSE( dlgFindReplace::OnClose) +END_EVENT_TABLE() + + +#define btnFind CTRL_BUTTON("wxID_FIND") +#define btnReplace CTRL_BUTTON("wxID_REPLACE") +#define btnReplaceAll CTRL_BUTTON("wxID_REPLACEALL") +#define btnCancel CTRL_BUTTON("wxID_CANCEL") +#define txtFind CTRL_TEXT("txtFind") +#define txtReplace CTRL_TEXT("txtReplace") +#define rdOriginTop CTRL_RADIOBUTTON("rdOriginTop") +#define rdOriginCursor CTRL_RADIOBUTTON("rdOriginCursor") +#define rdDirectionForward CTRL_RADIOBUTTON("rdDirectionForward") +#define rdDirectionBackward CTRL_RADIOBUTTON("rdDirectionBackward") +#define chkOptionsWholeWord CTRL_CHECKBOX("chkOptionsWholeWord") +#define chkOptionsAllFind CTRL_CHECKBOX("chkOptionsAllFind") +#define chkOptionsMatchCase CTRL_CHECKBOX("chkOptionsMatchCase") +#define chkOptionsUseRegexps CTRL_CHECKBOX("chkOptionsUseRegexps") + +dlgFindReplace::dlgFindReplace(ctlSQLBox *parent) : + pgDialog() +{ + sqlbox = parent; + startsqlbox = parent; + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgFindReplace")); + RestorePosition(); + + // Icon + appearanceFactory->SetIcons(this); + + // Accelerator table + wxAcceleratorEntry entries[2]; + entries[0].Set(wxACCEL_NORMAL, WXK_F3, wxID_FIND); + entries[1].Set(wxACCEL_SHIFT, WXK_F3, wxID_FIND); + wxAcceleratorTable accel(2, entries); + SetAcceleratorTable(accel); + + if (startsqlbox->GetQueryBook()==NULL) chkOptionsAllFind->Disable(); + // Load up the defaults + wxString val; + bool bVal; + + // Find/Replace values + settings->Read(wxT("FindReplace/Find"), &val, wxT("")); + txtFind->SetValue(val); + + settings->Read(wxT("FindReplace/Replace"), &val, wxT("")); + txtReplace->SetValue(val); + + // Origin + settings->Read(wxT("FindReplace/Origin"), &val, wxT("c")); + if (val == wxT("t")) + { + rdOriginCursor->SetValue(false); + rdOriginTop->SetValue(true); + } + else + { + rdOriginCursor->SetValue(true); + rdOriginTop->SetValue(false); + } + + // Direction + settings->Read(wxT("FindReplace/Direction"), &val, wxT("f")); + if (val == wxT("b")) + { + rdDirectionForward->SetValue(false); + rdDirectionBackward->SetValue(true); + } + else + { + rdDirectionForward->SetValue(true); + rdDirectionBackward->SetValue(false); + } + + // WholeWord + settings->Read(wxT("FindReplace/WholeWord"), &bVal, false); + chkOptionsWholeWord->SetValue(bVal); + + // MatchCase + settings->Read(wxT("FindReplace/MatchCase"), &bVal, false); + chkOptionsMatchCase->SetValue(bVal); + + // UseRegexps + settings->Read(wxT("FindReplace/UseRegexps"), &bVal, false); + chkOptionsUseRegexps->SetValue(bVal); + + wxCommandEvent ev; + OnChange(ev); + ResetTabOrder(); +} + +dlgFindReplace::~dlgFindReplace() +{ + SavePosition(); +} + +void dlgFindReplace::FocusSearch() +{ + txtFind->SetFocus(); + txtFind->SetSelection(-1, -1); +} + +void dlgFindReplace::SaveSettings() +{ + settings->Write(wxT("FindReplace/Find"), txtFind->GetValue()); + settings->Write(wxT("FindReplace/Replace"), txtReplace->GetValue()); + + if (rdOriginTop->GetValue()) + settings->Write(wxT("FindReplace/Origin"), wxT("t")); + else + settings->Write(wxT("FindReplace/Origin"), wxT("c")); + + if (rdDirectionBackward->GetValue()) + settings->Write(wxT("FindReplace/Direction"), wxT("b")); + else + settings->Write(wxT("FindReplace/Direction"), wxT("f")); + + settings->WriteBool(wxT("FindReplace/WholeWord"), chkOptionsWholeWord->GetValue()); + settings->WriteBool(wxT("FindReplace/MatchCase"), chkOptionsMatchCase->GetValue()); + settings->WriteBool(wxT("FindReplace/UseRegexps"), chkOptionsUseRegexps->GetValue()); +} + +void dlgFindReplace::OnClose(wxCloseEvent &ev) +{ + SaveSettings(); + this->Hide(); + if (ev.CanVeto()) + ev.Veto(); +} + +void dlgFindReplace::OnCancel(wxCommandEvent &ev) +{ + SaveSettings(); + this->Hide(); +} + +void dlgFindReplace::OnChange(wxCommandEvent &ev) +{ + if (chkOptionsUseRegexps->GetValue() == true || rdOriginTop->GetValue() == true) + { + rdDirectionForward->SetValue(true); + rdDirectionBackward->SetValue(false); + rdDirectionBackward->Enable(false); + } + else + { + rdDirectionBackward->Enable(true); + } + + if (chkOptionsUseRegexps->GetValue() == true) + { + chkOptionsWholeWord->Enable(false); + chkOptionsMatchCase->Enable(false); + } + else + { + chkOptionsWholeWord->Enable(true); + chkOptionsMatchCase->Enable(true); + } +} + +void dlgFindReplace::OnFind(wxCommandEvent &ev) +{ + if (txtFind->GetValue().IsEmpty()) + return; + + bool wholeWord = false, + matchCase = false, + useRegexps = false, + startAtTop = false, + all = false, + reverse = false; + + if (rdOriginTop->GetValue() == true) + startAtTop = true; + + if (rdDirectionBackward->GetValue() == true) + reverse = true; + + if (wxGetKeyState(WXK_SHIFT)) + reverse = !reverse; + + if (chkOptionsWholeWord->GetValue() == true) + wholeWord = true; + + if (chkOptionsMatchCase->GetValue() == true) + matchCase = true; + + if (chkOptionsUseRegexps->GetValue() == true) + useRegexps = true; + if (chkOptionsAllFind->GetValue() == true) + all = true; + + if (sqlbox->Find(txtFind->GetValue(), wholeWord, matchCase, useRegexps, startAtTop, reverse,all)) + { + if (startAtTop) + { + rdOriginTop->SetValue(false); + rdOriginCursor->SetValue(true); + wxCommandEvent nullEvent; + OnChange(nullEvent); + return; + + } + } else + { + rdOriginTop->SetValue(true); + rdOriginCursor->SetValue(false); + wxCommandEvent nullEvent; + OnChange(nullEvent); + startAtTop=true; + reverse=false; + // not find in current tabs + if (all) { + ctlAuiNotebook *note=startsqlbox->GetQueryBook(); + if (note!=NULL) { + size_t count_pages=note->GetPageCount(); + ctlSQLBox *sqlQuery; + for(int i=0;iGetPage(i), ctlSQLBox); + if (sqlQuery==sqlbox) { + while (true) { + i++; + if (i>=count_pages) i=0; + // next tabs + sqlQuery = wxDynamicCast(note->GetPage(i), ctlSQLBox); + if (sqlQuery==startsqlbox) { + note->SetSelection(i); + sqlbox=sqlQuery; + wxWindow *w = wxWindow::FindFocus(); + wxMessageBox(_("Reached the end of the document"), _("Replace text"), wxICON_EXCLAMATION | wxOK, w); + return ; + } + note->SetSelection(i); + sqlbox=sqlQuery; + if (sqlbox->Find(txtFind->GetValue(), wholeWord, matchCase, useRegexps, startAtTop, reverse,all)) + { + if (startAtTop) + { + rdOriginTop->SetValue(false); + rdOriginCursor->SetValue(true); + wxCommandEvent nullEvent; + OnChange(nullEvent); + return; + } + } + } + return; + } + } + } + + wxWindow *w = wxWindow::FindFocus(); + wxMessageBox(_("Reached the end of the document"), _("Replace text"), wxICON_EXCLAMATION | wxOK, w); + } + } +} + +void dlgFindReplace::OnReplace(wxCommandEvent &ev) +{ + if (txtFind->GetValue().IsEmpty()) + return; + + bool wholeWord = false, + matchCase = false, + useRegexps = false, + startAtTop = false, + reverse = false; + + if (rdOriginTop->GetValue() == true) + startAtTop = true; + + if (rdDirectionBackward->GetValue() == true) + reverse = true; + + if (chkOptionsWholeWord->GetValue() == true) + wholeWord = true; + + if (chkOptionsMatchCase->GetValue() == true) + matchCase = true; + + if (chkOptionsUseRegexps->GetValue() == true) + useRegexps = true; + + if (startsqlbox->Replace(txtFind->GetValue(), txtReplace->GetValue(), wholeWord, matchCase, useRegexps, startAtTop, reverse)) + { + if (startAtTop) + { + rdOriginTop->SetValue(false); + rdOriginCursor->SetValue(true); + wxCommandEvent nullEvent; + OnChange(nullEvent); + } + } +} +void dlgFindReplace::OnReplaceAll(wxCommandEvent &ev) +{ + if (txtFind->GetValue().IsEmpty()) + return; + + bool wholeWord = false, + matchCase = false, + useRegexps = false; + + if (chkOptionsWholeWord->GetValue() == true) + wholeWord = true; + + if (chkOptionsMatchCase->GetValue() == true) + matchCase = true; + + if (chkOptionsUseRegexps->GetValue() == true) + useRegexps = true; + + startsqlbox->ReplaceAll(txtFind->GetValue(), txtReplace->GetValue(), wholeWord, matchCase, useRegexps); +} + +void dlgFindReplace::FindNext() +{ + if (btnFind->IsEnabled() && !txtFind->IsEmpty()) + { + wxCommandEvent ev; + OnFind(ev); + } +} + +void dlgFindReplace::SetFindString(const wxString &val) +{ + txtFind->SetValue(val); +} + +void dlgFindReplace::ResetTabOrder() +{ + btnFind->MoveAfterInTabOrder(chkOptionsUseRegexps); + btnReplace->MoveAfterInTabOrder(btnFind); + btnReplaceAll->MoveAfterInTabOrder(btnReplace); + btnCancel->MoveAfterInTabOrder(btnReplaceAll); +} + diff --git a/dlg/dlgForeignDataWrapper.cpp b/dlg/dlgForeignDataWrapper.cpp new file mode 100644 index 0000000..65595d8 --- /dev/null +++ b/dlg/dlgForeignDataWrapper.cpp @@ -0,0 +1,400 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignDataWrapper.cpp - PostgreSQL ForeignDataWrapper Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgForeignDataWrapper.h" +#include "schema/pgForeignDataWrapper.h" + + +// pointer to controls +#define cbHandler CTRL_COMBOBOX("cbHandler") +#define cbValidator CTRL_COMBOBOX("cbValidator") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgForeignDataWrapperFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignDataWrapper(this, frame, (pgForeignDataWrapper *)node); +} + + +BEGIN_EVENT_TABLE(dlgForeignDataWrapper, dlgSecurityProperty) + EVT_TEXT(XRCID("cbHandler"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbHandler"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbValidator"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbValidator"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignDataWrapper::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignDataWrapper::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignDataWrapper::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignDataWrapper::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgForeignDataWrapper::dlgForeignDataWrapper(pgaFactory *f, frmMain *frame, pgForeignDataWrapper *node) + : dlgSecurityProperty(f, frame, node, wxT("dlgForeignDataWrapper"), wxT("USAGE"), "U") +{ + fdw = node; +} + + +pgObject *dlgForeignDataWrapper::GetObject() +{ + return fdw; +} + + +int dlgForeignDataWrapper::Go(bool modal) +{ + wxString val; + + if(!connection->BackendMinimumVersion(9, 1)) + cbHandler->Disable(); + + // Fill handler combobox + cbHandler->Append(wxT("")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, proname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE pronargs=0") + wxT(" AND prorettype=") + NumToStr(PGOID_TYPE_HANDLER)); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbHandler->Append(procname); + set->MoveNext(); + } + delete set; + } + cbHandler->SetSelection(0); + + // Fill validator combobox + cbValidator->Append(wxT("")); + set = connection->ExecuteSet( + wxT("SELECT nspname, proname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE proargtypes[0]=") + NumToStr(PGOID_TYPE_TEXT_ARRAY) + + wxT(" AND proargtypes[1]=") + NumToStr(PGOID_TYPE_OID)); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbValidator->Append(procname); + set->MoveNext(); + } + delete set; + } + cbValidator->SetSelection(0); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (fdw) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + + val = fdw->GetHandlerProc(); + if (!val.IsEmpty()) + { + for (unsigned int i = 0 ; i < cbHandler->GetCount() ; i++) + { + if (cbHandler->GetString(i) == val) + cbHandler->SetSelection(i); + } + } + + val = fdw->GetValidatorProc(); + if (!val.IsEmpty()) + { + for (unsigned int i = 0 ; i < cbValidator->GetCount() ; i++) + { + if (cbValidator->GetString(i) == val) + cbValidator->SetSelection(i); + } + } + + wxString options = fdw->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgForeignDataWrapper::CreateObject(pgCollection *collection) +{ + wxString name = txtName->GetValue(); + + pgObject *obj = foreignDataWrapperFactory.CreateObjects(collection, 0, wxT("\n AND fdwname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgForeignDataWrapper::CheckChange() +{ + bool didChange = true; + wxString name = txtName->GetValue(); + if (fdw) + { + didChange = name != fdw->GetName() + || cbOwner->GetValue() != fdw->GetOwner() + || txtComment->GetValue() != fdw->GetComment() + || cbHandler->GetValue() != fdw->GetHandlerProc() + || cbValidator->GetValue() != fdw->GetValidatorProc() + || GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + + +void dlgForeignDataWrapper::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignDataWrapper::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignDataWrapper::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignDataWrapper::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignDataWrapper::GetOptionsSql() +{ + wxString options = fdw->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = fdw->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignDataWrapper::GetSql() +{ + wxString sql, name; + name = txtName->GetValue(); + + if (fdw) + { + // edit mode + sql = wxEmptyString; + + AppendNameChange(sql); + + if (cbHandler->GetValue() != fdw->GetHandlerProc()) + { + if (cbHandler->GetValue().IsEmpty()) + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n NO HANDLER;\n"); + else + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n HANDLER ") + qtIdent(cbHandler->GetValue()) + + wxT(";\n"); + } + + if (cbValidator->GetValue() != fdw->GetValidatorProc()) + { + if (cbValidator->GetValue().IsEmpty()) + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n NO VALIDATOR;\n"); + else + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + qtIdent(name) + + wxT("\n VALIDATOR ") + qtIdent(cbValidator->GetValue()) + + wxT(";\n"); + } + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER FOREIGN DATA WRAPPER ") + name + + wxT(" OPTIONS (") + sqloptions + wxT(");"); + } + + AppendOwnerChange(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + } + else + { + // create mode + sql = wxT("CREATE FOREIGN DATA WRAPPER ") + qtIdent(name); + AppendIfFilled(sql, wxT("\n HANDLER "), qtIdent(cbHandler->GetValue())); + AppendIfFilled(sql, wxT("\n VALIDATOR "), qtIdent(cbValidator->GetValue())); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + AppendOwnerNew(sql, wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + qtIdent(name)); + AppendComment(sql, wxT("FOREIGN DATA WRAPPER"), 0, fdw); + + return sql; +} + + diff --git a/dlg/dlgForeignKey.cpp b/dlg/dlgForeignKey.cpp new file mode 100644 index 0000000..9fa9dbd --- /dev/null +++ b/dlg/dlgForeignKey.cpp @@ -0,0 +1,569 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignKey.cpp - PostgreSQL Foreign Key Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "schema/pgTable.h" +#include "schema/pgForeignKey.h" +#include "dlg/dlgForeignKey.h" +#include "schema/pgColumn.h" + + +#define chkDeferrable CTRL_CHECKBOX("chkDeferrable") +#define chkDeferred CTRL_CHECKBOX("chkDeferred") +#define cbReferences CTRL_COMBOBOX("cbReferences") +#define chkMatchFull CTRL_CHECKBOX("chkMatchFull") +#define chkDontValidate CTRL_CHECKBOX("chkDontValidate") + +#define chkAutoIndex CTRL_CHECKBOX("chkAutoIndex") +#define txtIndexName CTRL_TEXT("txtIndexName") + +#define cbRefColumns CTRL_COMBOBOX("cbRefColumns") +#define btnAddRef CTRL_BUTTON("btnAddRef") +#define btnRemoveRef CTRL_BUTTON("btnRemoveRef") + +#define rbOnUpdate CTRL_RADIOBOX("rbOnUpdate") +#define rbOnDelete CTRL_RADIOBOX("rbOnDelete") + + +BEGIN_EVENT_TABLE(dlgForeignKey, dlgProperty) + EVT_CHECKBOX(XRCID("chkDeferrable"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkAutoIndex") , dlgProperty::OnChange) + EVT_TEXT(XRCID("txtIndexName"), dlgProperty::OnChange) + + EVT_CHECKBOX(XRCID("chkDontValidate"), dlgForeignKey::OnChangeValidate) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgForeignKey::OnSelChangeCol) + EVT_TEXT(XRCID("cbReferences"), dlgForeignKey::OnSelChangeRef) + EVT_COMBOBOX(XRCID("cbReferences"), dlgForeignKey::OnSelChangeRef) + EVT_TEXT(XRCID("cbColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_COMBOBOX(XRCID("cbColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_TEXT(XRCID("cbRefColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_COMBOBOX(XRCID("cbRefColumns"), dlgForeignKey::OnSelChangeRefCol) + EVT_BUTTON(XRCID("btnAddRef"), dlgForeignKey::OnAddRef) + EVT_BUTTON(XRCID("btnRemoveRef"), dlgForeignKey::OnRemoveRef) + EVT_BUTTON(wxID_OK, dlgForeignKey::OnOK) +#ifdef __WXMAC__ + EVT_SIZE( dlgForeignKey::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgForeignKeyFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignKey(this, frame, (pgForeignKey *)node, (pgTable *)parent); +} + + +dlgForeignKey::dlgForeignKey(pgaFactory *f, frmMain *frame, pgForeignKey *node, pgTable *parentNode) + : dlgCollistProperty(f, frame, wxT("dlgForeignKey"), parentNode) +{ + foreignKey = node; +} + + +dlgForeignKey::dlgForeignKey(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgCollistProperty(f, frame, wxT("dlgForeignKey"), colList) +{ + foreignKey = 0; +} + + +wxString dlgForeignKey::DefaultIndexName(const wxString &name) +{ + if (name.IsEmpty()) + return wxEmptyString; + + if (name.Left(3) == wxT("fk_")) + return wxT("fki_") + name.Mid(3); + else if (name.Left(3) == wxT("FK_")) + return wxT("FKI_") + name.Mid(3); + else + return wxT("fki_") + name; +} + + +void dlgForeignKey::OnOK(wxCommandEvent &ev) +{ + if (chkAutoIndex->IsEnabled() && !chkAutoIndex->GetValue() + && frmHint::ShowHint(this, HINT_FKINDEX) == wxID_CANCEL) + return; + + dlgProperty::OnOK(ev); +} + + +#ifdef __WXMAC__ +void dlgForeignKey::OnChangeSize(wxSizeEvent &ev) +{ + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 450); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgForeignKey::CheckChange() +{ + if (processing) + return; + + processing = true; + + wxString name = GetName(); + + wxString cols; + int pos; + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + cols += wxT(", "); + cols += qtIdent(lstColumns->GetText(pos)); + } + + bool canDef = chkDeferrable->GetValue(); + if (!canDef) + chkDeferred->SetValue(false); + chkDeferred->Enable(canDef); + + txtIndexName->Enable(table && chkAutoIndex->GetValue()); + + wxString coveringIndex; + if (table) + { + coveringIndex = table->GetCoveringIndex(mainForm->GetBrowser(), cols); + + if (coveringIndex.IsEmpty()) + { + if (!chkAutoIndex->IsEnabled()) + { + chkAutoIndex->Enable(); + chkAutoIndex->SetValue(true); + txtIndexName->Enable(); + txtIndexName->SetValue(savedIndexName); + } + + wxString idxName = txtIndexName->GetValue().Strip(wxString::both); + + if (name != savedFKName || idxName == savedIndexName) + { + if (idxName.IsEmpty() || idxName == DefaultIndexName(savedFKName)) + { + idxName = DefaultIndexName(name); + txtIndexName->SetValue(idxName); + } + } + savedIndexName = idxName; + } + else + { + if (chkAutoIndex->IsEnabled()) + savedIndexName = txtIndexName->GetValue(); + + txtIndexName->SetValue(coveringIndex); + chkAutoIndex->SetValue(false); + + txtIndexName->Disable(); + chkAutoIndex->Disable(); + } + } + + savedFKName = name; + processing = false; + + if (foreignKey) + { + bool enable = true; + if (chkAutoIndex->GetValue()) + { + CheckValid(enable, !txtIndexName->GetValue().IsEmpty(), + _("Please specify covering index name.")); + } + else + enable = txtName->GetValue() != foreignKey->GetName() || txtComment->GetValue() != foreignKey->GetComment(); + + if (connection->BackendMinimumVersion(9, 1) && !foreignKey->GetValid() && !chkDontValidate->GetValue()) + enable = true; + + EnableOK(enable); + } + else + { + bool enable = true; + txtComment->Enable(!name.IsEmpty()); + CheckValid(enable, lstColumns->GetItemCount() > 0, _("Please specify columns.")); + CheckValid(enable, !chkAutoIndex->GetValue() || !txtIndexName->GetValue().IsEmpty(), + _("Please specify covering index name.")); + EnableOK(enable); + } + +} + + +void dlgForeignKey::OnChangeValidate(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgForeignKey::OnSelChangeCol(wxListEvent &ev) +{ + btnRemoveRef->Enable(); +} + + +void dlgForeignKey::OnSelChangeRefCol(wxCommandEvent &ev) +{ + btnAddRef->Enable(cbColumns->GetCurrentSelection() >= 0 && cbRefColumns->GetCurrentSelection() >= 0); +} + + +void dlgForeignKey::OnSelChangeRef(wxCommandEvent &ev) +{ + cbRefColumns->Clear(); + + wxString tab = cbReferences->GetValue(); + wxString nsp; + if (tab.Find('.') >= 0) + { + nsp = tab.BeforeFirst('.'); + tab = tab.AfterFirst('.'); + } + else + nsp = database->GetDefaultSchema(); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute att, pg_class cl, pg_namespace nsp\n") + wxT(" WHERE attrelid=cl.oid AND relnamespace=nsp.oid\n") + wxT(" AND nspname=") + qtDbString(nsp) + + wxT("\n AND relname=") + qtDbString(tab) + + wxT("\n AND attnum > 0\n") + wxT("\n AND NOT attisdropped\n") + wxT("\n ORDER BY attnum")); + if (set) + { + while (!set->Eof()) + { + cbRefColumns->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + + if (cbRefColumns->GetCount()) + cbRefColumns->SetSelection(0); + } + + OnSelChangeRefCol(ev); +} + + +void dlgForeignKey::OnAddRef(wxCommandEvent &ev) +{ + wxString col = cbColumns->GetValue(); + wxString ref = cbRefColumns->GetValue(); + if (!col.IsEmpty() && !ref.IsEmpty()) + { + lstColumns->AppendItem(columnFactory.GetIconId(), col, ref); + cbColumns->Delete(cbColumns->GetCurrentSelection()); + cbRefColumns->Delete(cbRefColumns->GetCurrentSelection()); + cbReferences->Disable(); + + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + if (cbRefColumns->GetCount()) + cbRefColumns->SetSelection(0); + + OnSelChangeRefCol(ev); + CheckChange(); + } +} + + +void dlgForeignKey::OnRemoveRef(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + + if (pos >= 0) + { + wxString col = lstColumns->GetText(pos); + wxString ref = lstColumns->GetText(pos, 1); + cbColumns->Append(col); + cbRefColumns->Append(ref); + + lstColumns->DeleteItem(pos); + cbReferences->Enable(lstColumns->GetItemCount() == 0); + btnRemoveRef->Disable(); + } +} + + +pgObject *dlgForeignKey::GetObject() +{ + return foreignKey; +} + + +pgObject *dlgForeignKey::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + if (name.IsEmpty()) + return 0; + + pgObject *obj = foreignKeyFactory.CreateObjects(collection, 0, wxT( + "\n AND conname=") + qtDbString(name) + wxT( + "\n AND cl.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + + +int dlgForeignKey::Go(bool modal) +{ + lstColumns->CreateColumns(0, _("Local"), _("Referenced"), -1); + + processing = true; // protect from OnChange execution + + btnAddRef->Disable(); + btnRemoveRef->Disable(); + + if (readOnly) + { + chkAutoIndex->Disable(); + txtIndexName->Disable(); + } + + + if (foreignKey) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + cbReferences->Append(foreignKey->GetReferences()); + cbReferences->SetValue(foreignKey->GetReferences()); + cbReferences->Disable(); + + chkDeferrable->SetValue(foreignKey->GetDeferrable()); + chkDeferred->SetValue(foreignKey->GetDeferred()); + chkMatchFull->SetValue(foreignKey->GetMatch() == wxT("FULL")); + if (connection->BackendMinimumVersion(9, 1)) + chkDontValidate->SetValue(!foreignKey->GetValid()); + chkDeferrable->Disable(); + chkDeferred->Disable(); + chkMatchFull->Disable(); + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 1)); + if(!connection->BackendMinimumVersion(9, 1)) + { + chkDontValidate->SetValue(true); + } + rbOnUpdate->SetStringSelection(foreignKey->GetOnUpdate()); + rbOnDelete->SetStringSelection(foreignKey->GetOnDelete()); + rbOnUpdate->Disable(); + rbOnDelete->Disable(); + + chkAutoIndex->SetValue(false); + txtIndexName->SetValue(foreignKey->GetCoveringIndex()); + if (!txtIndexName->GetValue().IsEmpty()) + { + chkAutoIndex->Disable(); + txtIndexName->Disable(); + } + + btnAddRef->Disable(); + btnRemoveRef->Disable(); + cbColumns->Disable(); + cbRefColumns->Disable(); + + int pos = 0; + wxStringTokenizer cols(foreignKey->GetFkColumns(), wxT(",")); + wxStringTokenizer refs(foreignKey->GetRefColumns(), wxT(",")); + while (cols.HasMoreTokens()) + { + wxString col = cols.GetNextToken().Trim(false).Trim(true); + wxString ref = refs.GetNextToken().Trim(false).Trim(true); + if (pos++) + { + if (col.Last() == ',') + col.RemoveLast(); + if (ref.Last() == ',') + ref.RemoveLast(); + } + lstColumns->AppendItem(columnFactory.GetIconId(), col, ref); + } + } + else + { + // create mode + txtComment->Disable(); + + chkDontValidate->Enable(connection->BackendMinimumVersion(9, 1)); + + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("nsp.nspname")); + + wxString sql = wxT("SELECT nspname, relname FROM pg_namespace nsp, pg_class cl\n") + wxT(" WHERE relnamespace=nsp.oid AND relkind='r'\n"); + + if (connection->BackendMinimumVersion(8, 1)) + sql += wxT(" AND nsp.nspname NOT LIKE E'pg\\_temp\\_%'\n"); + else + sql += wxT(" AND nsp.nspname NOT LIKE 'pg\\_temp\\_%'\n"); + + sql += systemRestriction + + wxT(" ORDER BY nspname, relname"); + + pgSet *set = connection->ExecuteSet(sql); + + if (set) + { + while (!set->Eof()) + { + cbReferences->Append(database->GetSchemaPrefix(set->GetVal(0)) + set->GetVal(1)); + set->MoveNext(); + } + delete set; + cbReferences->SetSelection(0); + } + if (!table) + { + chkAutoIndex->Disable(); + chkAutoIndex->SetValue(false); + txtIndexName->Disable(); + cbClusterSet->Disable(); + cbClusterSet = 0; + } + } + + processing = false; + + // Reset the labels as the XRC defined values will have been localised :-( + + rbOnUpdate->SetString(0, wxT("NO ACTION")); + rbOnUpdate->SetString(1, wxT("RESTRICT")); + rbOnUpdate->SetString(2, wxT("CASCADE")); + rbOnUpdate->SetString(3, wxT("SET NULL")); + rbOnUpdate->SetString(4, wxT("SET DEFAULT")); + + rbOnDelete->SetString(0, wxT("NO ACTION")); + rbOnDelete->SetString(1, wxT("RESTRICT")); + rbOnDelete->SetString(2, wxT("CASCADE")); + rbOnDelete->SetString(3, wxT("SET NULL")); + rbOnDelete->SetString(4, wxT("SET DEFAULT")); + + wxCommandEvent nullEvent; + OnSelChangeRef(nullEvent); + + return dlgCollistProperty::Go(modal); +} + + +wxString dlgForeignKey::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (!foreignKey) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD"); + AppendIfFilled(sql, wxT(" CONSTRAINT "), qtIdent(name)); + sql += wxT(" FOREIGN KEY ") + GetDefinition() + + wxT(";\n"); + } + else + { + if (foreignKey->GetName() != name) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n RENAME CONSTRAINT ") + qtIdent(foreignKey->GetName()) + + wxT(" TO ") + qtIdent(name) + wxT(";\n"); + } + if (connection->BackendMinimumVersion(9, 1) && !foreignKey->GetValid() && !chkDontValidate->GetValue()) + { + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + qtIdent(name) + wxT(";\n"); + } + } + + if (!name.IsEmpty()) + AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), foreignKey); + + if (chkAutoIndex->GetValue()) + { + sql += wxT("CREATE INDEX ") + qtIdent(txtIndexName->GetValue()) + + wxT("\n ON ") + table->GetQuotedFullIdentifier() + + wxT("("); + + int pos; + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetText(pos)); + } + + sql += wxT(");\n"); + } + return sql; +} + + +wxString dlgForeignKey::GetDefinition() +{ + wxString sql; + wxString cols, refs; + + int pos; + + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + { + cols += wxT(", "); + refs += wxT(", "); + } + cols += qtIdent(lstColumns->GetText(pos)); + refs += qtIdent(lstColumns->GetText(pos, 1)); + } + + sql = wxT("(") + cols + + wxT(") REFERENCES "); + AppendQuoted(sql, cbReferences->GetValue()); + sql += wxT(" (") + refs + + wxT(")"); + + if (chkMatchFull->GetValue()) + sql += wxT(" MATCH FULL"); + + sql += wxT("\n ") + wxT(" ON UPDATE ") + rbOnUpdate->GetStringSelection() + + wxT(" ON DELETE ") + rbOnDelete->GetStringSelection(); + + if (chkDeferrable->GetValue()) + sql += wxT("\n DEFERRABLE"); + if (chkDeferred->GetValue()) + sql += wxT(" INITIALLY DEFERRED"); + + if (chkDontValidate->GetValue()) + sql += wxT("\n NOT VALID"); + + return sql; +} diff --git a/dlg/dlgForeignServer.cpp b/dlg/dlgForeignServer.cpp new file mode 100644 index 0000000..457e6db --- /dev/null +++ b/dlg/dlgForeignServer.cpp @@ -0,0 +1,329 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignServer.cpp - PostgreSQL Foreign Server Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgForeignServer.h" +#include "schema/pgForeignServer.h" + + +// pointer to controls +#define cbForeignDataWrapper CTRL_COMBOBOX("cbForeignDataWrapper") +#define txtType CTRL_TEXT("txtType") +#define txtVersion CTRL_TEXT("txtVersion") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgForeignServerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignServer(this, frame, (pgForeignServer *)node, (pgForeignDataWrapper *)parent); +} + + +BEGIN_EVENT_TABLE(dlgForeignServer, dlgSecurityProperty) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignServer::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignServer::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignServer::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignServer::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgForeignServer::dlgForeignServer(pgaFactory *f, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent) + : dlgSecurityProperty(f, frame, node, wxT("dlgForeignServer"), wxT("USAGE"), "U") +{ + foreigndatawrapper = parent; + foreignserver = node; +} + + +pgObject *dlgForeignServer::GetObject() +{ + return foreignserver; +} + + +int dlgForeignServer::Go(bool modal) +{ + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (foreignserver) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + txtType->Disable(); + + txtType->SetValue(foreignserver->GetType()); + txtVersion->SetValue(foreignserver->GetVersion()); + + wxString options = foreignserver->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgForeignServer::CreateObject(pgCollection *collection) +{ + wxString name = txtName->GetValue(); + + pgObject *obj = foreignServerFactory.CreateObjects(collection, 0, wxT("\n AND srvname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgForeignServer::CheckChange() +{ + bool didChange = true; + wxString name = txtName->GetValue(); + if (foreignserver) + { + didChange = name != foreignserver->GetName() + || txtComment->GetValue() != foreignserver->GetComment() + || cbOwner->GetValue() != foreignserver->GetOwner() + || txtType->GetValue() != foreignserver->GetType() + || txtVersion->GetValue() != foreignserver->GetVersion() + || GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } +} + + + +void dlgForeignServer::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgForeignServer::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignServer::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignServer::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignServer::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignServer::GetOptionsSql() +{ + wxString options = foreignserver->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = foreignserver->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignServer::GetSql() +{ + wxString sql, name; + name = txtName->GetValue(); + + if (foreignserver) + { + // edit mode + AppendNameChange(sql, wxT("SERVER ") + qtIdent(foreignserver->GetName())); + + if (txtVersion->GetValue() != foreignserver->GetVersion()) + { + sql = wxT("ALTER SERVER ") + qtIdent(name) + + wxT("\n VERSION ") + qtDbString(txtVersion->GetValue()) + wxT(";\n"); + } + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER SERVER ") + name + + wxT("\n OPTIONS (") + sqloptions + wxT(");\n"); + } + + AppendOwnerChange(sql, wxT("SERVER ") + qtIdent(name)); + } + else + { + // create mode + sql = wxT("CREATE SERVER ") + qtIdent(name); + if (!(txtType->GetValue()).IsEmpty()) + sql += wxT("\n TYPE ") + qtDbString(txtType->GetValue()); + if (!(txtVersion->GetValue()).IsEmpty()) + sql += wxT("\n VERSION ") + qtDbString(txtVersion->GetValue()); + sql += wxT("\n FOREIGN DATA WRAPPER ") + qtIdent(foreigndatawrapper->GetName()); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + AppendOwnerNew(sql, wxT("SERVER ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("SERVER ") + qtIdent(name)); + AppendComment(sql, wxT("SERVER"), 0, foreignserver); + + return sql; +} + + + diff --git a/dlg/dlgForeignTable.cpp b/dlg/dlgForeignTable.cpp new file mode 100644 index 0000000..c65746f --- /dev/null +++ b/dlg/dlgForeignTable.cpp @@ -0,0 +1,644 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignTable.cpp - PostgreSQL Foreign Table Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + + +// App headers +#include "utils/misc.h" +#include "dlg/dlgForeignTable.h" +#include "schema/pgSchema.h" +#include "schema/pgForeignTable.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define cbForeignServer CTRL_COMBOBOX("cbForeignServer") +#define lstMembers CTRL_LISTVIEW("lstMembers") +#define txtMembername CTRL_TEXT("txtMembername") +#define btnAddMember CTRL_BUTTON("btnAddMember") +#define btnChangeMember CTRL_BUTTON("btnChangeMember") +#define btnRemoveMember CTRL_BUTTON("btnRemoveMember") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define chkNotNull CTRL_CHECKBOX("chkNotNull") + + +BEGIN_EVENT_TABLE(dlgForeignTable, dlgTypeProperty) + EVT_BUTTON(XRCID("btnAddMember"), dlgForeignTable::OnMemberAdd) + EVT_BUTTON(XRCID("btnChangeMember"), dlgForeignTable::OnMemberChange) + EVT_BUTTON(XRCID("btnRemoveMember"), dlgForeignTable::OnMemberRemove) + EVT_LIST_ITEM_SELECTED(XRCID("lstMembers"), dlgForeignTable::OnMemberSelChange) + EVT_TEXT(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_TEXT(XRCID("txtMembername"), dlgForeignTable::OnChangeMember) + EVT_TEXT(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgForeignTable::OnSelChangeTyp) + EVT_TEXT(XRCID("txtLength"), dlgForeignTable::OnSelChangeTypOrLen) + EVT_TEXT(XRCID("txtPrecision"), dlgForeignTable::OnSelChangeTypOrLen) + EVT_CHECKBOX(XRCID("chkNotNull"), dlgForeignTable::OnChangeMember) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgForeignTable::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgForeignTable::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgForeignTable::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgForeignTable::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgProperty *pgForeignTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgForeignTable(this, frame, (pgForeignTable *)node, (pgSchema *)parent); +} + + +dlgForeignTable::dlgForeignTable(pgaFactory *f, frmMain *frame, pgForeignTable *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgForeignTable")) +{ + foreigntable = node; + schema = sch; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + lstMembers->CreateColumns(0, _("Member"), _("Data type"), _("Constraint"), -1); + + queriesToBeSplitted = false; +} + + +void dlgForeignTable::OnChangeMember(wxCommandEvent &ev) +{ + btnAddMember->Enable( + !txtMembername->GetValue().Strip(wxString::both).IsEmpty() + && cbDatatype->GetGuessedSelection() >= 0); + btnChangeMember->Enable(true); +} + + +pgObject *dlgForeignTable::GetObject() +{ + return foreigntable; +} + + +int dlgForeignTable::Go(bool modal) +{ + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(foreigntable); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgForeignTable::OnChange)); + + // Fill owner combobox + if (!foreigntable) + cbOwner->Append(wxT("")); + AddGroups(); + AddUsers(cbOwner); + + // Fill datatype combobox + FillDatatype(cbDatatype); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (foreigntable) + { + // Edit Mode + cbForeignServer->SetValue(foreigntable->GetForeignServer()); + cbForeignServer->Disable(); + + txtMembername->Enable(true); + btnAddMember->Enable(true); + btnChangeMember->Enable(false); + btnRemoveMember->Enable(false); + + wxArrayString elements = foreigntable->GetTypesArray(); + wxString fullType, typeName, typeLength, typePrecision; + size_t pos; + size_t i; + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + lstMembers->AppendItem(0, elements.Item(i), elements.Item(i + 1), elements.Item(i + 2)); + + fullType = elements.Item(i + 1); + typeName = fullType; + typeLength = wxEmptyString; + typePrecision = wxEmptyString; + + if (fullType.Find(wxT("(")) > 0) + { + // there is at least a length + typeName = fullType.BeforeFirst('('); + if (fullType.Find(wxT(",")) > 0) + { + // there is also a precision + typeLength = fullType.AfterFirst('(').BeforeFirst(','); + typePrecision = fullType.AfterFirst(',').BeforeFirst(')'); + } + else + typeLength = fullType.AfterFirst('(').BeforeFirst(')'); + if (!fullType.AfterFirst(')').IsEmpty()) typeName += fullType.AfterFirst(')'); + } + int fnd=-1; + for (pos = 0; pos < cbDatatype->GetCount() - 1; pos++) + { + if (cbDatatype->GetString(pos) == typeName) + { + memberTypes.Add(GetTypeInfo(pos)); + fnd=pos; + break; + } + } + if (fnd==-1) { + wxLogWarning(_("Type %s not found in cbDatatype(%d)\n"), + typeName.c_str(), + cbDatatype->GetCount() + ); + + } + memberLengths.Add(typeLength); + memberPrecisions.Add(typePrecision); + memberNotNulls.Add(elements.Item(i + 2)); + } + + cbDatatype->Enable(); + txtLength->Enable(); + + wxArrayString options = foreigntable->GetOptionsArray(); + wxString optionname, optionvalue; + for (unsigned int index = 0; index < options.Count(); index += 2) + { + optionname = options.Item(index); + optionvalue = options.Item(index + 1); + lstOptions->AppendItem(optionname, optionvalue); + } + } + else + { + // Create mode + cbOwner->Append(wxEmptyString); + cbOwner->Disable(); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT srvname\n") + wxT(" FROM pg_foreign_server\n") + wxT(" ORDER BY srvname")); + if (set) + { + while (!set->Eof()) + { + wxString srvname = set->GetVal(wxT("srvname")); + cbForeignServer->Append(srvname); + set->MoveNext(); + } + delete set; + } + cbForeignServer->SetSelection(0); + } + + txtLength->SetValidator(numericValidator); + + return dlgTypeProperty::Go(modal); +} + + +void dlgForeignTable::OnSelChangeTyp(wxCommandEvent &ev) +{ + txtLength->SetValue(wxEmptyString); + txtPrecision->SetValue(wxEmptyString); + cbDatatype->GuessSelection(ev); + chkNotNull->SetValue(false); + OnSelChangeTypOrLen(ev); +} + + +void dlgForeignTable::OnSelChangeTypOrLen(wxCommandEvent &ev) +{ + CheckLenEnable(); + txtLength->Enable(isVarLen); + txtPrecision->Enable(isVarPrec); + CheckChange(); + OnChangeMember(ev); +} + + +void dlgForeignTable::CheckChange() +{ + bool enable = true; + if (foreigntable) + { + enable = txtComment->GetValue() != foreigntable->GetComment() + || cbSchema->GetValue() != foreigntable->GetSchema()->GetName() + || cbOwner->GetValue() != foreigntable->GetOwner() + || GetSqlForTypes() != wxEmptyString + || GetSql().Length() > 0; + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbForeignServer->GetCurrentSelection() >= 0, _("Please specify a foreign server.")); + } + EnableOK(enable); +} + + +void dlgForeignTable::OnMemberSelChange(wxListEvent &ev) +{ + long pos = lstMembers->GetSelection(); + if (pos >= 0) + { + txtMembername->SetValue(lstMembers->GetText(pos)); + cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':')); + txtLength->SetValue(memberLengths.Item(pos)); + txtLength->Enable(!txtLength->GetValue().IsEmpty()); + txtPrecision->SetValue(memberPrecisions.Item(pos)); + txtPrecision->Enable(!txtPrecision->GetValue().IsEmpty()); + chkNotNull->SetValue(memberNotNulls.Item(pos) == wxT("NOT NULL")); + chkNotNull->Enable(); + btnChangeMember->Enable(); + btnRemoveMember->Enable(); + } +} + + +void dlgForeignTable::OnMemberAdd(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString notnull = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + notnull = chkNotNull->GetValue() ? wxT("NOT NULL") : wxEmptyString; + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + size_t pos = lstMembers->GetItemCount(); + lstMembers->InsertItem(pos, name, 0); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, notnull); + memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection())); + memberLengths.Add(length); + memberPrecisions.Add(precision); + memberNotNulls.Add(notnull); + } + + txtMembername->SetValue(wxEmptyString); + cbDatatype->SetValue(wxEmptyString); + txtLength->SetValue(wxEmptyString); + txtPrecision->SetValue(wxEmptyString); + chkNotNull->SetValue(false); + + CheckChange(); +} + + +void dlgForeignTable::OnMemberChange(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString notnull = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + notnull = chkNotNull->GetValue() ? wxT("NOT NULL") : wxEmptyString; + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + long pos = lstMembers->GetFirstSelected(); + if (pos >= 0) + { + lstMembers->SetItem(pos, 0, name); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, notnull); + memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos); + memberLengths.Insert(length, pos); + memberPrecisions.Insert(precision, pos); + memberNotNulls.Insert(notnull, pos); + memberTypes.RemoveAt(pos + 1); + memberLengths.RemoveAt(pos + 1); + memberPrecisions.RemoveAt(pos + 1); + memberNotNulls.RemoveAt(pos + 1); + } + } + + CheckChange(); +} + + +void dlgForeignTable::OnMemberRemove(wxCommandEvent &ev) +{ + long pos = lstMembers->GetSelection(); + + if (pos >= 0) + { + lstMembers->DeleteItem(pos); + memberTypes.RemoveAt(pos); + memberLengths.RemoveAt(pos); + memberPrecisions.RemoveAt(pos); + memberNotNulls.RemoveAt(pos); + } + CheckChange(); +} + + +pgObject *dlgForeignTable::CreateObject(pgCollection *collection) +{ + pgObject *obj = 0; + return obj; +} + + +void dlgForeignTable::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgForeignTable::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgForeignTable::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgForeignTable::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgForeignTable::GetOptionsSql() +{ + wxArrayString options = foreigntable->GetOptionsArray(); + wxString optionname, optionvalue, sqloptions; + bool found; + int pos; + + for (unsigned int index = 0; index < options.Count(); index += 2) + { + optionname = options.Item(index); + optionvalue = options.Item(index + 1); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = foreigntable->GetOptionsArray(); + found = false; + + for (unsigned int index = 0; index < options.Count() && !found; index += 2) + { + optionname = options.Item(index); + optionvalue = options.Item(index + 1); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + } + + if (!found) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgForeignTable::GetSql() +{ + wxString sql; + wxString name; + + if (foreigntable) + { + // Edit Mode + name = qtIdent(foreigntable->GetSchema()->GetName()) + wxT(".") + qtIdent(GetName()); + + AppendNameChange(sql, wxT("FOREIGN TABLE ") + foreigntable->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("FOREIGN TABLE ") + name); + + sql += GetSqlForTypes(); + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER FOREIGN TABLE ") + name + + wxT("\n OPTIONS (") + sqloptions + wxT(");\n"); + } + AppendSchemaChange(sql, wxT("FOREIGN TABLE ") + name); + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // Create Mode + sql = wxT("CREATE FOREIGN TABLE " + name); + sql += wxT(" ("); + + int i; + for (i = 0 ; i < lstMembers->GetItemCount() ; i++) + { + if (i) + sql += wxT(",\n "); + sql += qtIdent(lstMembers->GetItemText(i)) + wxT(" ") + + GetFullTypeName(i); + } + + sql += wxT(") SERVER ") + cbForeignServer->GetValue(); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + } + AppendComment(sql, wxT("FOREIGN TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), foreigntable); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("FOREIGN TABLE "), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + return sql; +} + +wxString dlgForeignTable::GetFullTypeName(int type) +{ + wxString typname = memberTypes.Item(type).AfterFirst(':'); + + if (!memberLengths.Item(type).IsEmpty()) + { + typname += wxT("(") + memberLengths.Item(type); + if (!memberPrecisions.Item(type).IsEmpty()) + typname += wxT(",") + memberPrecisions.Item(type); + typname += wxT(")"); + } + + typname += wxT(" ") + memberNotNulls.Item(type); + + return typname; +} + +wxString dlgForeignTable::GetSqlForTypes() +{ + wxString sql = wxEmptyString; + wxString old_name, old_type, new_name, new_type; + wxArrayString elements = foreigntable->GetTypesArray(); + bool modified = lstMembers->GetItemCount() * 3 != (int)elements.GetCount(); + size_t i; + + // Check if there is a change + for (int i = 0 ; i < lstMembers->GetItemCount() && !modified; i++) + { + old_name = elements.Item(i * 3); + old_type = elements.Item(i * 3 + 1) + wxT(" ") + elements.Item(i * 3 + 2); + new_name = lstMembers->GetItemText(i); + new_type = GetFullTypeName(i); + modified = modified || old_name != new_name || old_type != new_type; + } + + if (modified) + { + // Drop all old attributes + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + old_name = elements.Item(i); + sql += wxT("ALTER FOREIGN TABLE ") + foreigntable->GetQuotedFullIdentifier() + + wxT("\n DROP COLUMN ") + old_name + wxT(";\n"); + } + + // Add all new attributes + for (int i = 0 ; i < lstMembers->GetItemCount() ; i++) + { + new_name = lstMembers->GetItemText(i); + new_type = GetFullTypeName(i); + sql += wxT("ALTER FOREIGN TABLE ") + foreigntable->GetQuotedFullIdentifier() + + wxT("\n ADD COLUMN ") + new_name + wxT(" ") + new_type + wxT(";\n"); + } + } + + return sql; +} + +void dlgForeignTable::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgFunction.cpp b/dlg/dlgFunction.cpp new file mode 100644 index 0000000..ae359e7 --- /dev/null +++ b/dlg/dlgFunction.cpp @@ -0,0 +1,1135 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFunction.cpp - PostgreSQL Function Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgFunction.h" +#include "schema/pgFunction.h" +#include "schema/pgSchema.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + + +// pointer to controls +#define txtArguments CTRL_TEXT("txtArguments") +#define cbReturntype CTRL_COMBOBOX2("cbReturntype") +#define cbLanguage CTRL_COMBOBOX2("cbLanguage") +#define chkSetof CTRL_CHECKBOX("chkSetof") +#define cbVolatility CTRL_COMBOBOX("cbVolatility") +#define cbParallel CTRL_COMBOBOX("cbParallel") +#define chkStrict CTRL_CHECKBOX("chkStrict") +#define chkWindow CTRL_CHECKBOX("chkWindow") +#define chkSecureDefiner CTRL_CHECKBOX("chkSecureDefiner") +#define txtCost CTRL_TEXT("txtCost") +#define txtRows CTRL_TEXT("txtRows") +#define chkLeakProof CTRL_CHECKBOX("chkLeakProof") + +#define lstArguments CTRL_LISTVIEW("lstArguments") +#define rdbIn CTRL_RADIOBUTTON("rdbIn") +#define rdbOut CTRL_RADIOBUTTON("rdbOut") +#define rdbInOut CTRL_RADIOBUTTON("rdbInOut") +#define rdbVariadic CTRL_RADIOBUTTON("rdbVariadic") + +#define txtArgName CTRL_TEXT("txtArgName") +#define txtArgDefVal CTRL_TEXT("txtArgDefVal") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnChange CTRL_BUTTON("wxID_CHANGE") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + +#define pnlParameters CTRL_PANEL("pnlParameters") +#define sbxDefinition CTRL_STATICBOX("sbxDefinition") +#define stObjectFile CTRL_STATIC("stObjectFile") +#define txtObjectFile CTRL_TEXT("txtObjectFile") +#define stLinkSymbol CTRL_STATIC("stLinkSymbol") +#define txtLinkSymbol CTRL_TEXT("txtLinkSymbol") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define btnAddVar CTRL_BUTTON("btnAddVar") +#define btnRemoveVar CTRL_BUTTON("btnRemoveVar") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") + +#define TXTOBJ_LIB wxT("$libdir/") + +BEGIN_EVENT_TABLE(dlgFunction, dlgSecurityProperty) + EVT_TEXT(XRCID("cbVolatility"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbParallel"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkStrict"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSecureDefiner"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtObjectFile"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtLinkSymbol"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtCost"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtRows"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkLeakProof"), dlgProperty::OnChange) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) + + EVT_CHECKBOX(XRCID("chkSetof"), dlgFunction::OnChangeSetof) + EVT_TEXT(XRCID("cbReturntype"), dlgFunction::OnChangeReturn) + EVT_COMBOBOX(XRCID("cbReturntype"), dlgFunction::OnChangeReturn) + EVT_TEXT(XRCID("cbDatatype"), dlgFunction::OnSelChangeType) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgFunction::OnSelChangeType) + EVT_TEXT(XRCID("cbLanguage"), dlgFunction::OnSelChangeLanguage) + EVT_COMBOBOX(XRCID("cbLanguage"), dlgFunction::OnSelChangeLanguage) + + EVT_LIST_ITEM_SELECTED(XRCID("lstArguments"), dlgFunction::OnSelChangeArg) + EVT_TEXT(XRCID("txtArgName"), dlgFunction::OnChangeArgName) + EVT_BUTTON(wxID_ADD, dlgFunction::OnAddArg) + EVT_BUTTON(XRCID("wxID_CHANGE"), dlgFunction::OnChangeArg) + EVT_BUTTON(wxID_REMOVE, dlgFunction::OnRemoveArg) + + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgFunction::OnVarSelChange) + EVT_BUTTON(XRCID("btnAddVar"), dlgFunction::OnVarAdd) + EVT_BUTTON(XRCID("btnRemoveVar"), dlgFunction::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgFunction::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgFunction::OnVarnameSelChange) + EVT_RADIOBUTTON(XRCID("rdbIn"), dlgFunction::OnChangeArgMode) + EVT_RADIOBUTTON(XRCID("rdbOut"), dlgFunction::OnChangeArgMode) + EVT_RADIOBUTTON(XRCID("rdbInOut"), dlgFunction::OnChangeArgMode) + EVT_RADIOBUTTON(XRCID("rdbVariadic"), dlgFunction::OnChangeArgMode) + EVT_CHECKBOX(XRCID("chkWindow"), dlgFunction::OnChangeWindow) +#ifdef __WXMAC__ + EVT_SIZE( dlgFunction::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgFunctionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + pgSchema *sch; + + if (parent->GetMetaType() == PGM_TRIGGER) + sch = parent->GetSchema(); + // Event triggers are at database level. So, we do not have a schema for an event trigger. + else if(parent->GetMetaType() == PGM_EVENTTRIGGER) + sch = 0; + else + sch = (pgSchema *)parent; + + return new dlgFunction(this, frame, (pgFunction *)node, sch); +} + + +dlgFunction::dlgFunction(pgaFactory *f, frmMain *frame, pgFunction *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgFunction"), wxT("EXECUTE"), "X"), + isEdbWrapped( false ) +{ + schema = sch; + function = node; + isProcedure = false; + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + txtArguments->Disable(); + + if (!node) + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value = wxT("X"); + securityPage->lbPrivileges->AppendItem(icon, name, value); + AppendCurrentAcl(name, value); + } + + bool bVal; + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + if (!bVal) + { + txtSqlBox->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtSqlBox->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + } + btnAdd->Disable(); + btnRemove->Disable(); + btnChange->Disable(); + + lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1); + chkValue->Hide(); +} + + + +dlgProperty *pgProcedureFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + dlgProcedure *p= new dlgProcedure(this, frame, (pgFunction *)node, (pgSchema *)parent); + //p->isProcedure=true; + return p; +} + +dlgProcedure::dlgProcedure(pgaFactory *f, frmMain *frame, pgFunction *node, pgSchema *sch) + : dlgFunction(f, frame, node, sch) +{ + isProcedure = true; +} + +pgObject *dlgFunction::GetObject() +{ + return function; +} + + +int dlgFunction::Go(bool modal) +{ + isBackendMinVer84 = connection->BackendMinimumVersion(8, 4); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(function); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgFunction::OnChange)); + } + else + seclabelPage->Disable(); + + if (function) + { + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + rdbVariadic->Disable(); + isProcedure = function->GetIsProcedure(); + } + + if (!isBackendMinVer84) + txtArgDefVal->Disable(); + chkLeakProof->Enable(connection->BackendMinimumVersion(9, 2)); + + lstArguments->AddColumn(_("Type"), 60); + lstArguments->AddColumn(_("Mode"), 40); + lstArguments->AddColumn(_("Name"), 60); + lstArguments->AddColumn(_("Default Value"), 60); + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + + if (!connection->BackendMinimumVersion(8, 3)) + txtCost->Disable(); + + txtRows->Disable(); + + if (!connection->BackendMinimumVersion(8, 0)) + txtArgName->Disable(); + + // Window function can not be modified + // Disable it for editing + if (function || !isBackendMinVer84) + chkWindow->Disable(); + + if (isProcedure) + { + if (function && !connection->EdbMinimumVersion(8, 2)) + // txtName->Disable(); + //cbOwner->Disable(); + //cbLanguage->Disable(); + chkStrict->Disable(); + chkWindow->Disable(); + //chkSecureDefiner->Disable(); + chkSetof->Disable(); + cbVolatility->Disable(); + cbParallel->Disable(); + cbReturntype->Disable(); + txtCost->Disable(); + txtRows->Disable(); + chkLeakProof->Disable(); + } + else + { + if (!connection->BackendMinimumVersion(8, 1)) + { + rdbIn->SetValue(true); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + } + + if (!isBackendMinVer84) + { + rdbVariadic->Disable(); + } + } + + pgSet *lang = connection->ExecuteSet(wxT("SELECT lanname FROM pg_language")); + if (lang) + { + while (!lang->Eof()) + { + wxString language = lang->GetVal(0); + if (factory == &triggerFunctionFactory) + { + if (language.IsSameAs(wxT("SQL"), false) || + language.IsSameAs(wxT("edbspl"), false)) + { + lang->MoveNext(); + continue; + } + } + cbLanguage->Append(language); + lang->MoveNext(); + } + delete lang; + } + + if (connection->BackendMinimumVersion(8, 3)) + { + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + SetupVarEditor(0); + } + + } + else + { + btnAddVar->Disable(); + btnRemoveVar->Disable(); + cbVarname->Disable(); + txtValue->Disable(); + chkValue->Disable(); + } + + if (function) + { + // edit mode + + if (factory != &triggerFunctionFactory) + { + wxArrayString argTypes = function->GetArgTypesArray(); + wxArrayString argNames = function->GetArgNamesArray(); + wxArrayString argModes = function->GetArgModesArray(); + wxArrayString argDefs = function->GetArgDefsArray(); + + for (unsigned int i = 0; i < argTypes.Count(); i++) + { + if (argModes[i] != wxT("TABLE")) + { + if (isBackendMinVer84) + lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i], (argDefs.Count() > i ? argDefs[i] : wxString(wxEmptyString))); + else + lstArguments->AppendItem(-1, argTypes.Item(i), argModes[i], argNames[i]); + } + } + } + + txtArguments->SetValue(function->GetArgListWithNames()); + if (!isProcedure) + { + cbReturntype->Append(function->GetReturnType()); + cbReturntype->SetSelection(0); + //cbReturntype->SetValue(function->GetReturnType()); + } + + cbLanguage->SetValue(function->GetLanguage()); + cbVolatility->SetValue(function->GetVolatility()); + cbParallel->SetValue(function->GetParallel()); + + chkSetof->SetValue(function->GetReturnAsSet()); + chkStrict->SetValue(function->GetIsStrict()); + if (connection->BackendMinimumVersion(8, 4)) + chkWindow->SetValue(function->GetIsWindow()); + chkSecureDefiner->SetValue(function->GetSecureDefiner()); + chkLeakProof->SetValue(function->GetIsLeakProof()); + + if (function->GetLanguage().IsSameAs(wxT("C"), false)) + { + txtObjectFile->SetValue(function->GetBin()); + txtLinkSymbol->SetValue(function->GetSource()); + } + else + txtSqlBox->SetText(function->GetSource()); + + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + + if (connection->BackendMinimumVersion(8, 3)) + { + txtCost->SetValue(NumToStr(function->GetCost())); + if (function->GetReturnAsSet()) + { + txtRows->SetValue(NumToStr(function->GetRows())); + txtRows->Enable(); + } + else + txtRows->Disable(); + } + + size_t index; + for (index = 0 ; index < function->GetConfigList().GetCount() ; index++) + { + wxString item = function->GetConfigList().Item(index); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + cbReturntype->Disable(); + chkSetof->Disable(); + cbDatatype->Disable(); + // Editing parameter for wrapped functions is not allowed + // It will anyway throw an error, if we try to edit the parameter list + if ( connection->GetIsEdb() && + function->GetSource().Trim(false).StartsWith( wxT( "$__EDBwrapped__$" ))) + { + isEdbWrapped = true; + cbDatatype->Disable(); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + rdbVariadic->Disable(); + txtArgName->Disable(); + txtArgDefVal->Disable(); + btnAdd->Disable(); + btnChange->Disable(); + btnRemove->Disable(); + } + } + else + { + wxString restrict; + // create mode + restrict = wxT("(typtype IN ('b', 'c', 'd', 'e', 'p', 'r') AND typname NOT IN ('any', 'trigger', 'language_handler', 'event_trigger'))"); + if (!settings->GetShowSystemObjects()) + restrict += wxT(" AND nspname NOT LIKE E'pg\\\\_toast%' AND nspname NOT LIKE E'pg\\\\_temp%'"); + + DatatypeReader tr(database, restrict); + cbDatatype->Freeze(); + cbReturntype->Freeze(); + while (tr.HasMore()) + { + pgDatatype dt = tr.GetDatatype(); + + typOids.Add(tr.GetOidStr()); + types.Add(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + + cbDatatype->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + if (factory != &triggerFunctionFactory) + cbReturntype->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + tr.MoveNext(); + } + cbDatatype->Thaw(); + cbReturntype->Thaw(); + long sel; + if (factory == &triggerFunctionFactory) + { + cbReturntype->Append(wxT("trigger")); + + if (connection->BackendMinimumVersion(9, 3)) + cbReturntype->Append(wxT("event_trigger")); + + cbReturntype->SetSelection(0); + lstArguments->Disable(); + cbDatatype->Disable(); + txtArgName->Disable(); + txtArgDefVal->Disable(); + rdbIn->Disable(); + rdbOut->Disable(); + rdbInOut->Disable(); + rdbVariadic->Disable(); + sel = cbLanguage->FindString(wxT("c")); + } + else if (isProcedure) + sel = cbLanguage->FindString(wxT("plpgsql")); + else + sel = cbLanguage->FindString(wxT("sql")); + + if (sel >= 0) + cbLanguage->SetSelection(sel); + txtObjectFile->SetValue(TXTOBJ_LIB); + } + + wxNotifyEvent event; + OnSelChangeLanguage(event); + + return dlgSecurityProperty::Go(modal); +} + +#ifdef __WXMAC__ +void dlgFunction::OnChangeSize(wxSizeEvent &ev) +{ + lstArguments->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgFunction::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgFunction::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->GetParent()->Layout(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + txtValue->GetParent()->Layout(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + } + } +} + +void dlgFunction::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + int sel = cbVarname->FindString(lstVariables->GetText(pos)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + + +void dlgFunction::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + CheckChange(); +} + + +void dlgFunction::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + CheckChange(); +} + + +pgObject *dlgFunction::CreateObject(pgCollection *collection) +{ + wxString sql = wxT(" WHERE proname=") + qtDbString(GetName()) + + wxT("\n AND pronamespace=") + schema->GetOidStr(); + + long argCount; + for (argCount = 0 ; argCount < (int)argOids.GetCount() ; argCount++) + sql += wxT("\n AND proargtypes[") + NumToStr(argCount) + wxT("] = ") + argOids.Item(argCount); + + sql += wxT("\n AND proargtypes[") + NumToStr(argCount) + wxT("] = 0\n"); + + pgObject *obj = functionFactory.AppendFunctions(collection, collection->GetSchema(), 0, sql); + return obj; +} + + +void dlgFunction::CheckChange() +{ + wxString name = GetName(); + bool isC = cbLanguage->GetValue().IsSameAs(wxT("C"), false); + bool enable = true, didChange = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + if (!isProcedure) + CheckValid(enable, cbReturntype->GetValue().Trim() != wxEmptyString, _("Please select return type.")); + + CheckValid(enable, cbLanguage->GetGuessedSelection() >= 0, _("Please select language.")); + + if (isC) + { + wxString objfile = txtObjectFile->GetValue(); + CheckValid(enable, !objfile.IsEmpty() && objfile != TXTOBJ_LIB, _("Please specify object library.")); + } + else + { + CheckValid(enable, !txtSqlBox->GetText().IsEmpty(), _("Please enter function source code.")); + } + + if (function && enable) + { + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + wxString s=GetSql(); + bool noempty=true; + if (s.IsEmpty()) { + noempty=false; + } + EnableOK(enable && noempty); + } + else + { + EnableOK(enable && didChange); + } +} + +bool dlgFunction::IsUpToDate() +{ + if (function && !function->IsUpToDate()) + return false; + else + return true; +} + +void dlgFunction::OnSelChangeLanguage(wxCommandEvent &ev) +{ + bool isC = (cbLanguage->GetValue().IsSameAs(wxT("C"), false)); + + stObjectFile->Show(isC); + txtObjectFile->Show(isC); + stLinkSymbol->Show(isC); + txtLinkSymbol->Show(isC); + txtSqlBox->Show(!isC); + + txtSqlBox->GetContainingSizer()->Layout(); + + CheckChange(); +} + + +void dlgFunction::OnSelChangeArg(wxListEvent &ev) +{ + int row = lstArguments->GetSelection(); + if (row >= 0) + { + cbDatatype->SetValue(lstArguments->GetText(row, 0)); + wxString mode = lstArguments->GetText(row, 1); + if (mode == wxT("IN")) + rdbIn->SetValue(true); + else if (mode == wxT("OUT")) + rdbOut->SetValue(true); + else if (mode == wxT("IN OUT") || mode == wxT("INOUT")) + rdbInOut->SetValue(true); + else if (mode == wxT("VARIADIC")) + rdbVariadic->SetValue(true); + txtArgName->SetValue(lstArguments->GetText(row, 2)); + if (isBackendMinVer84) + { + txtArgDefVal->SetValue(lstArguments->GetText(row, 3)); + txtArgDefVal->Enable(mode == wxT("IN") || mode.IsEmpty()); + } + + wxCommandEvent ev; + OnChangeArgName(ev); + } +} + + +void dlgFunction::OnChangeReturn(wxCommandEvent &ev) +{ + cbReturntype->GuessSelection(ev); + CheckChange(); +} + + +void dlgFunction::OnChangeSetof(wxCommandEvent &ev) +{ + if (chkSetof->GetValue() && connection->BackendMinimumVersion(8, 3) && !isProcedure) + txtRows->Enable(); + else + txtRows->Disable(); + + CheckChange(); +} + + +void dlgFunction::OnSelChangeType(wxCommandEvent &ev) +{ + cbDatatype->GuessSelection(ev); + OnChangeArgName(ev); +} + + +void dlgFunction::OnChangeArgName(wxCommandEvent &ev) +{ + int argNameRow = -1; + if (!txtArgName->GetValue().IsEmpty()) + argNameRow = lstArguments->FindItem(-1, txtArgName->GetValue()); + + int pos = lstArguments->GetSelection(); + + bool typeValid = (function != 0 || cbDatatype->GetGuessedSelection() >= 0); + + // EDBWrapped function does not allow modification in parameter list + btnChange->Enable(pos >= 0 && typeValid && !isEdbWrapped); + if (!function) + { + // EDBWrapped function does not allow modification in parameter list + btnAdd->Enable(argNameRow < 0 && typeValid && !isEdbWrapped); + btnRemove->Enable(pos >= 0 && !isEdbWrapped); + } +} + +void dlgFunction::OnChangeArgMode(wxCommandEvent &ev) +{ + // Do nothing, if Default value for function parameter not supported + if (!isBackendMinVer84) + return; + + // Only IN parameter supports default value + if (!rdbIn->GetValue()) + { + txtArgDefVal->SetValue(wxEmptyString); + txtArgDefVal->Enable(false); + } + else + { + // EDBWrapped function does not allow modification in parameter list + txtArgDefVal->Enable(true && !isEdbWrapped); + } +} + +void dlgFunction::OnChangeArg(wxCommandEvent &ev) +{ + if (GetSelectedDirection() == wxT("VARIADIC") && + !cbDatatype->GetValue().EndsWith(wxT("[]"))) + { + wxLogError(_("Only array types can be VARIADIC.")); + return; + } + + int row = lstArguments->GetSelection(); + + if (row >= 0) + { + lstArguments->SetItem(row, 0, cbDatatype->GetValue()); + lstArguments->SetItem(row, 1, GetSelectedDirection()); + lstArguments->SetItem(row, 2, txtArgName->GetValue()); + if (isBackendMinVer84) + lstArguments->SetItem(row, 3, txtArgDefVal->GetValue()); + + if (!function) + argOids.Item(row) = typOids.Item(cbDatatype->GetGuessedSelection()); + txtArguments->SetValue(GetArgs()); + } + OnChangeArgName(ev); + CheckChange(); +} + + +void dlgFunction::OnAddArg(wxCommandEvent &ev) +{ + if (GetSelectedDirection() == wxT("VARIADIC") && + !cbDatatype->GetValue().EndsWith(wxT("[]"))) + { + wxLogError(_("Only array types can be VARIADIC.")); + return; + } + + lstArguments->AppendItem(-1, cbDatatype->GetValue(), GetSelectedDirection(), txtArgName->GetValue(), txtArgDefVal->GetValue().Trim()); + + if (!function) + argOids.Add(typOids.Item(cbDatatype->GetGuessedSelection())); + + txtArguments->SetValue(GetArgs()); + OnChangeArgName(ev); +} + + +void dlgFunction::OnRemoveArg(wxCommandEvent &ev) +{ + unsigned int sel = lstArguments->GetSelection(); + argOids.RemoveAt(sel); + lstArguments->DeleteItem(sel); + btnRemove->Disable(); + txtArguments->SetValue(GetArgs()); + OnChangeArgName(ev); +} + +wxString dlgFunction::GetSelectedDirection() +{ + if (rdbIn->GetValue()) + return wxT("IN"); + else if (rdbOut->GetValue()) + return wxT("OUT"); + else if (rdbInOut->GetValue()) + { + if (isProcedure) + return wxT("INOUT"); + else + return wxT("INOUT"); + } + else if (rdbVariadic->GetValue()) + return wxT("VARIADIC"); + else + return wxEmptyString; +} + + +wxString dlgFunction::GetArgs(const bool withNames, const bool inOnly) +{ + wxString args; + bool isEdbspl = cbLanguage->GetValue() == wxT("edbspl"); + + for (int i = 0; i < lstArguments->GetItemCount(); i++) + { + if (!isEdbspl && inOnly && lstArguments->GetText(i, 1) == wxT("OUT")) + continue; + + if (i && !args.IsEmpty() && !args.EndsWith(wxT(", "))) + args += wxT(", "); + + if (isProcedure) + { + if (withNames && lstArguments->GetText(i, 2) != wxEmptyString) + args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" "); + + // edbspl functions should list OUT params, but only by type. + // although this is not true for EDB AS90 onwards.. + if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT") || + connection->EdbMinimumVersion(9, 0)) + { + if (lstArguments->GetText(i, 1) != wxEmptyString) + args += lstArguments->GetText(i, 1) + wxT(" "); + } + + args += lstArguments->GetText(i, 0); + } + else + { + // edbspl functions should list OUT params, but only by type. + // although this is not true for EDB AS90 onwards.. + if (!inOnly || !isEdbspl || lstArguments->GetText(i, 1) != wxT("OUT") || + connection->EdbMinimumVersion(9, 0)) + { + if (connection->BackendMinimumVersion(8, 1) && lstArguments->GetText(i, 1) != wxEmptyString) + args += lstArguments->GetText(i, 1) + wxT(" "); + } + + if (connection->BackendMinimumVersion(8, 0) && withNames && lstArguments->GetText(i, 2) != wxEmptyString) + args += qtIdent(lstArguments->GetText(i, 2)) + wxT(" "); + + args += lstArguments->GetText(i, 0); + } + if (withNames && isBackendMinVer84 && !lstArguments->GetText(i, 3).IsEmpty()) + args += wxT(" DEFAULT ") + lstArguments->GetText(i, 3); + } + + return args; +} + + +wxString dlgFunction::GetSql() +{ + wxString sql; + wxString name; + wxString objType; + if (isProcedure) + objType = wxT("PROCEDURE "); + else + objType = wxT("FUNCTION "); + + bool isC = cbLanguage->GetValue().IsSameAs(wxT("C"), false); + bool didChange = !function + || cbLanguage->GetValue() != function->GetLanguage() && !isProcedure + || cbVolatility->GetValue() != function->GetVolatility() && !isProcedure + || cbParallel->GetValue() != function->GetParallel() && !isProcedure + || chkSecureDefiner->GetValue() != function->GetSecureDefiner() + || chkStrict->GetValue() != function->GetIsStrict() && !isProcedure + || GetArgs() != function->GetArgListWithNames() && !isProcedure + || chkLeakProof->GetValue() != function->GetIsLeakProof() && !isProcedure + || (isC && (txtObjectFile->GetValue() != function->GetBin()&& !isProcedure || txtLinkSymbol->GetValue() != function->GetSource())) + || (!isC && txtSqlBox->GetText() != function->GetSource()); + + if (connection->BackendMinimumVersion(8, 3)) + { + didChange = (didChange || + txtCost->GetValue() != NumToStr(function->GetCost())&& !isProcedure || + (chkSetof->GetValue()&& !isProcedure && txtRows->GetValue() != NumToStr(function->GetRows()))); + } + + if (function) + { + name = GetName(); + // edit mode + if (name != function->GetName()) + { + if (!isProcedure) + AppendNameChange(sql, wxT("FUNCTION ") + function->GetQuotedFullIdentifier() + + wxT("(") + function->GetArgSigList() + wxT(")")); + else + AppendNameChange(sql, wxT("PROCEDURE ") + function->GetQuotedFullIdentifier()); + } + if (didChange) + sql += wxT("CREATE OR REPLACE ") + objType; + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // create mode + sql = wxT("CREATE " ) + objType; + } + + if (didChange) + { + if (isProcedure && GetArgs().IsEmpty()) + { + sql += schema->GetQuotedPrefix() + qtIdent(GetName()) + wxT("()"); + } + else + { + // While creating trigger functions from the Event trigger, we may get the schema as null. + // Since, Event triggers are at database level. + + if (schema) + sql += schema->GetQuotedPrefix() + qtIdent(GetName()) + + wxT("(") + GetArgs() + wxT(")"); + else if(!function) + sql += qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()) + + wxT("(") + GetArgs() + wxT(")"); + else + sql += function->GetSchema()->GetQuotedPrefix() + qtIdent(GetName()) + + wxT("(") + GetArgs() + wxT(")"); + } + //sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" "); + if (!isProcedure) + { + sql += wxT(" RETURNS "); + sql += cbReturntype->GetValue(); + } + + sql += wxT(" AS\n"); + + if (isProcedure) + { + sql += qtDbStringDollar(txtSqlBox->GetText()); + sql = sql.Trim(true); + sql += wxT("\nLANGUAGE ") + cbLanguage->GetValue(); + if (!sql.EndsWith(wxT(";"))) + sql += wxT(";\n"); + else + sql += wxT("\n"); + + + } + else + { + if (cbLanguage->GetValue().IsSameAs(wxT("C"), false)) + { + sql += qtDbString(txtObjectFile->GetValue()); + if (!txtLinkSymbol->GetValue().IsEmpty()) + sql += wxT(", ") + qtDbString(txtLinkSymbol->GetValue()); + } + else + { + if (connection->BackendMinimumVersion(7, 5)) + sql += qtDbStringDollar(txtSqlBox->GetText()); + else + sql += qtDbString(txtSqlBox->GetText()); + } + + sql += wxT("\nLANGUAGE ") + cbLanguage->GetValue(); + if (chkWindow->GetValue()) + sql += wxT(" WINDOW "); + else + sql += wxT(" "); + sql += cbVolatility->GetValue(); + if (connection->BackendMinimumVersion(9, 2)) + { + if (!chkLeakProof->GetValue()) + sql += wxT(" NOT"); + sql += wxT(" LEAKPROOF"); + } + if (chkStrict->GetValue()) + sql += wxT(" STRICT"); + if (chkSecureDefiner->GetValue()) + sql += wxT(" SECURITY DEFINER"); + if (connection->BackendMinimumVersion(10, 0)) + { + sql += wxT(" PARALLEL "); + sql += cbParallel->GetValue(); + } + // PostgreSQL 8.3+ cost/row estimations + if (connection->BackendMinimumVersion(8, 3)) + { + if (txtCost->GetValue().Length() > 0) + sql += wxT("\nCOST ") + txtCost->GetValue(); + + if (chkSetof->GetValue() && txtRows->GetValue().Length() > 0) + sql += wxT("\nROWS ") + txtRows->GetValue(); + } + + sql += wxT(";\n"); + } + } + + + if (function ) + { + if (schema) + name = schema->GetQuotedPrefix() + qtIdent(name) + wxT("(") + GetArgs(false, true) + wxT(")"); + // Event triggers do not have it's schema definition. Hence, getting the schema from the trigger function. + else + name = function->GetSchema()->GetQuotedPrefix() + qtIdent(name) + + wxT("(") + GetArgs(false, true) + wxT(")"); + + AppendOwnerChange(sql, objType + name); + AppendSchemaChange(sql, objType + name); + } + //else if (function && isProcedure) + //{ + // name = schema->GetQuotedPrefix() + qtIdent(name); + // AppendOwnerChange(sql, wxT("PROCEDURE ") + name); + // AppendSchemaChange(sql, wxT("PROCEDURE ") + name); + //} + + else + { + name = name + wxT("(") + GetArgs(false, true) + wxT(")"); + + if (cbOwner->GetCurrentSelection() > 0) + if (!isProcedure) AppendOwnerNew(sql, wxT("FUNCTION ") + name); + else AppendOwnerNew(sql, wxT("PROCEDURE ") + name); + } + + if (false) + sql += GetGrant(wxT("X"), wxT("PROCEDURE ") + name); + else + { + wxArrayString vars; + size_t index; + if (isProcedure) sql += GetGrant(wxT("X"), objType + name); + + if (function) + { + for (index = 0 ; index < function->GetConfigList().GetCount() ; index++) + vars.Add(function->GetConfigList().Item(index)); + } + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + + // Reset the vars if they've changed, or the function definition has + // changed, which will remove them all :-( + if ((oldVal != newVal) || didChange) + { + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + sql += wxT("ALTER ")+ objType + name + + wxT("\n SET ") + newVar + + wxT("='") + newVal + + wxT("';\n"); + else + sql += wxT("ALTER ")+ objType + name + + wxT("\n SET ") + newVar + + wxT("=") + newVal + + wxT(";\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER ")+ objType + name + + wxT("\n RESET ") + vars.Item(pos).BeforeFirst('=') + + wxT(";\n"); + } + + sql += GetGrant(wxT("X"), objType + name); + } + + if (isProcedure) + AppendComment(sql, wxT("PROCEDURE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), function); + else + { + AppendComment(sql, wxT("FUNCTION ") + name, function); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("FUNCTION"), name); + } + + return sql; +} + + +void dlgFunction::OnChangeWindow(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgFunction::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgGroup.cpp b/dlg/dlgGroup.cpp new file mode 100644 index 0000000..75021c2 --- /dev/null +++ b/dlg/dlgGroup.cpp @@ -0,0 +1,221 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgGroup.cpp - PostgreSQL Group Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "utils/misc.h" +#include "dlg/dlgGroup.h" +#include "schema/pgGroup.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") + +#define lbUsersNotIn CTRL_LISTBOX("lbUsersNotIn") +#define lbUsersIn CTRL_LISTBOX("lbUsersIn") +#define btnAddUser CTRL_BUTTON("btnAddUser") +#define btnDelUser CTRL_BUTTON("btnDelUser") + + +dlgProperty *pgGroupFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgGroup(this, frame, (pgGroup *)node); +} + + + +BEGIN_EVENT_TABLE(dlgGroup, dlgProperty) + EVT_LISTBOX_DCLICK(XRCID("lbUsersNotIn"), dlgGroup::OnUserAdd) + EVT_LISTBOX_DCLICK(XRCID("lbUsersIn"), dlgGroup::OnUserRemove) + EVT_BUTTON(XRCID("btnAddUser"), dlgGroup::OnUserAdd) + EVT_BUTTON(XRCID("btnDelUser"), dlgGroup::OnUserRemove) +END_EVENT_TABLE(); + + + +dlgGroup::dlgGroup(pgaFactory *f, frmMain *frame, pgGroup *node) + : dlgProperty(f, frame, wxT("dlgGroup")) +{ + group = node; +} + + +pgObject *dlgGroup::GetObject() +{ + return group; +} + + +int dlgGroup::Go(bool modal) +{ + pgSet *set = connection->ExecuteSet(wxT("SELECT usename FROM pg_user")); + if (set) + { + while (!set->Eof()) + { + wxString userName = set->GetVal(wxT("usename")); + + if (group && group->GetUsersIn().Index(userName) >= 0) + lbUsersIn->Append(userName); + else + lbUsersNotIn->Append(userName); + + set->MoveNext(); + } + delete set; + } + + if (group) + { + // Edit Mode + readOnly = !group->GetServer()->GetSuperUser(); + + txtID->SetValue(NumToStr(group->GetGroupId())); + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + txtID->Disable(); + if (readOnly) + { + btnAddUser->Disable(); + btnDelUser->Disable(); + } + } + else + { + txtID->SetValidator(numericValidator); + } + + return dlgProperty::Go(modal); +} + + +void dlgGroup::CheckChange() +{ + if (group) + { + EnableOK(!GetSql().IsEmpty()); + } + else + { + wxString name = GetName(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + + EnableOK(enable); + } +} + + +void dlgGroup::OnUserAdd(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbUsersNotIn->GetSelection(); + if (pos >= 0) + { + lbUsersIn->Append(lbUsersNotIn->GetString(pos)); + lbUsersNotIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgGroup::OnUserRemove(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbUsersIn->GetSelection(); + if (pos >= 0) + { + lbUsersNotIn->Append(lbUsersIn->GetString(pos)); + lbUsersIn->Delete(pos); + } + CheckChange(); + } +} + + +pgObject *dlgGroup::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = groupFactory.CreateObjects(collection, 0, wxT("\n WHERE groname=") + qtDbString(name)); + return obj; +} + + +wxString dlgGroup::GetSql() +{ + wxString sql; + wxString name = GetName(); + int cnt, pos; + + if (group) + { + // Edit Mode + + AppendNameChange(sql); + + cnt = lbUsersIn->GetCount(); + wxArrayString tmpUsers = group->GetUsersIn(); + + // check for added users + for (pos = 0 ; pos < cnt ; pos++) + { + wxString userName = lbUsersIn->GetString(pos); + + int index = tmpUsers.Index(userName); + if (index >= 0) + tmpUsers.RemoveAt(index); + else + sql += wxT("ALTER GROUP ") + qtIdent(name) + + wxT("\n ADD USER ") + qtIdent(userName) + wxT(";\n"); + } + + // check for removed users + for (pos = 0 ; pos < (int)tmpUsers.GetCount() ; pos++) + { + sql += wxT("ALTER GROUP ") + qtIdent(name) + + wxT("\n DROP USER ") + qtIdent(tmpUsers.Item(pos)) + wxT(";\n"); + } + } + else + { + // Create Mode + wxString name = GetName(); + + long id = StrToLong(txtID->GetValue()); + + sql = wxT( + "CREATE GROUP ") + qtIdent(name); + if (id) + sql += wxT("\n WITH SYSID ") + NumToStr(id); + cnt = lbUsersIn->GetCount(); + if (cnt) + sql += wxT("\n USER "); + for (pos = 0 ; pos < cnt ; pos++) + { + if (pos) + sql += wxT(", "); + sql += qtIdent(lbUsersIn->GetString(pos)); + } + sql += wxT(";\n"); + + } + return sql; +} + diff --git a/dlg/dlgHbaConfig.cpp b/dlg/dlgHbaConfig.cpp new file mode 100644 index 0000000..47365da --- /dev/null +++ b/dlg/dlgHbaConfig.cpp @@ -0,0 +1,436 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgHbaConfig.cpp - Configure setting +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgHbaConfig.h" +#include "db/pgConn.h" +#include "db/pgSet.h" + +// Icons +#include "images/property.pngc" + + + + + +BEGIN_EVENT_TABLE(dlgHbaConfig, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgHbaConfig::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgHbaConfig::OnCancel) + EVT_BUTTON(wxID_REFRESH, dlgHbaConfig::OnAddValue) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgHbaConfig::OnChange) + EVT_COMBOBOX(XRCID("cbType"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("cbDatabase"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("cbUser"), dlgHbaConfig::OnChange) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgHbaConfig::OnAddDatabase) + EVT_COMBOBOX(XRCID("cbUser"), dlgHbaConfig::OnAddUser) + EVT_COMBOBOX(XRCID("cbMethod"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("txtIPaddress"), dlgHbaConfig::OnChange) + EVT_TEXT(XRCID("txtOption"), dlgHbaConfig::OnChange) +END_EVENT_TABLE() + + +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define cbType CTRL_COMBOBOX("cbType") +#define cbDatabase CTRL_COMBOBOX("cbDatabase") +#define cbUser CTRL_COMBOBOX("cbUser") +#define cbMethod CTRL_COMBOBOX("cbMethod") +#define txtIPaddress CTRL_TEXT("txtIPaddress") +#define txtOption CTRL_TEXT("txtOption") +#define stIPaddress CTRL_STATIC("stIPaddress") +#define stOption CTRL_STATIC("stOption") + + +dlgHbaConfig::dlgHbaConfig(pgFrame *parent, pgHbaConfigLine *_line, pgConn *_conn) : + DialogWithHelp((frmMain *)parent) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)parent, wxT("dlgHbaConfig")); + + conn = _conn; + + userAdding = databaseAdding = false; + + // Icon + SetIcon(*property_png_ico); + RestorePosition(); + + line = _line; + + cbType->Append(wxT("local")); + cbType->Append(wxT("host")); + cbType->Append(wxT("hostssl")); + cbType->Append(wxT("hostnossl")); + + cbDatabase->Append(wxT("all")); + cbDatabase->Append(wxT("sameuser")); + cbDatabase->Append(wxT("@")); + if (conn) + { + // role is supported from 8.1 + if (conn->BackendMinimumVersion(8, 1)) + cbDatabase->Append(wxT("samerole")); + else + cbDatabase->Append(wxT("samegroup")); + + // replication is supported from 9.0 + if (conn->BackendMinimumVersion(9, 0)) + cbDatabase->Append(wxT("replication")); + } + else + { + cbDatabase->Append(wxT("samegroup")); + cbDatabase->Append(wxT("samerole")); + cbDatabase->Append(wxT("replication")); + } + + cbUser->Append(wxT("all")); + + cbMethod->Append(wxT("trust")); + cbMethod->Append(wxT("reject")); + cbMethod->Append(wxT("md5")); + cbMethod->Append(wxT("password")); + cbMethod->Append(wxT("krb4")); + cbMethod->Append(wxT("krb5")); + cbMethod->Append(wxT("ident")); + cbMethod->Append(wxT("pam")); + + if (conn) + { + // LDAP is supported from 8.2 + if (conn->BackendMinimumVersion(8, 2)) + cbMethod->Append(wxT("ldap")); + + // GSS/SSPI are supported from 8.3 + if (conn->BackendMinimumVersion(8, 3)) + { + cbMethod->Append(wxT("gss")); + cbMethod->Append(wxT("sspi")); + } + + // CERT is supported from 8.4 + // but crypt is no longer supported in 8.4 + if (conn->BackendMinimumVersion(8, 4)) + { + cbMethod->Append(wxT("cert")); + } + else + { + cbMethod->Append(wxT("crypt")); + } + + // Radius is supported from 9.0 + if (conn->BackendMinimumVersion(9, 0)) + { + cbMethod->Append(wxT("radius")); + } + + // Peer is supported from 9.1 + if (conn->BackendMinimumVersion(9, 1)) + { + cbMethod->Append(wxT("peer")); + } + } + else + { + // Add all version-dependent methods if we don't know what version we have. + cbMethod->Append(wxT("ldap")); + cbMethod->Append(wxT("gss")); + cbMethod->Append(wxT("sspi")); + cbMethod->Append(wxT("cert")); + cbMethod->Append(wxT("crypt")); + cbMethod->Append(wxT("radius")); + cbMethod->Append(wxT("peer")); + } + + if (conn) + { + pgSet *set = conn->ExecuteSet(wxT("SELECT datname FROM pg_database")); + if (set) + { + while (!set->Eof()) + { + cbDatabase->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + wxString sql = wxT("SELECT usename FROM pg_user\n") + wxT("UNION\n") + wxT("SELECT 'group ' || groname FROM pg_group"); + set = conn->ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + cbUser->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + + // Setup the default values + + chkEnabled->SetValue(!line->isComment); + if(line->connectType != pgHbaConfigLine::PGC_INVALIDCONF) + { + database = line->database; + user = line->user; + + cbType->SetSelection(line->connectType); + cbMethod->SetSelection(line->method); + cbDatabase->SetValue(database); + cbUser->SetValue(user); + txtIPaddress->SetValue(line->ipaddress); + txtOption->SetValue(line->option); + } + wxCommandEvent noEvent; + OnChange(noEvent); +} + + +dlgHbaConfig::~dlgHbaConfig() +{ + SavePosition(); +} + + +wxString dlgHbaConfig::GetHelpPage() const +{ + return wxT("pg/client-authentication"); + // auth-methods#auth-trust #auth-password #kerberos-auth #auth-ident #auth-pam +} + + +void dlgHbaConfig::OnAddDatabase(wxCommandEvent &ev) +{ + int sel = cbDatabase->GetCurrentSelection(); + if (sel < 3) + return; + + wxString newDatabase; + if (database == wxT("all") || database == wxT("sameuser") || database == wxT("samegroup") + || database == wxT("samerole") || database == wxT("replication") || database.Left(1) == wxT("@")) + database = wxEmptyString; + + if (sel == 3) // file + newDatabase = wxT("@"); + else + { + wxString str = cbDatabase->GetString(sel); + if (str.Find(' ') >= 0) + str = wxT("\"") + str + wxT("\""); + + int pos = database.Find(str); + if (pos >= 0) + { + if (pos > 0 && database.Mid(pos - 1, 1) != wxT(",")) + pos = -1; + if (database.Length() > str.Length() + pos && database.Mid(pos + str.Length(), 1) != wxT(",")) + pos = -1; + } + if (pos < 0) + { + if (!database.IsEmpty()) + database += wxT(","); + + newDatabase = database + str; + } + else + newDatabase = database; + } + + wxTheApp->Yield(true); + + database = newDatabase; + databaseAdding = true; + wxCommandEvent buttonEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_REFRESH); + AddPendingEvent(buttonEvent); +} + + +void dlgHbaConfig::OnAddUser(wxCommandEvent &ev) +{ + int sel = cbUser->GetCurrentSelection(); + if (sel < 1) + return; + + wxString newUser; + + wxString str = cbUser->GetString(sel); + if (str.Left(6) == wxT("group ")) + { + if (str.Find(' ', true) > 5) + str = wxT("+\"") + str.Mid(6) + wxT("\""); + else + str = wxT("+") + str.Mid(6); + } + else + { + if (str.Find(' ') >= 0) + str = wxT("\"") + str + wxT("\""); + } + + if (user == wxT("all")) + newUser = str; + else + { + int pos = user.Find(str); + if (pos >= 0) + { + if (pos > 0 && user.Mid(pos - 1, 1) != wxT(",")) + pos = -1; + if (user.Length() > str.Length() + pos && user.Mid(pos + str.Length(), 1) != wxT(",")) + pos = -1; + } + + if (pos < 0) + { + if (!user.IsEmpty()) + user += wxT(","); + newUser = user + str; + } + else + newUser = user; + } + + wxTheApp->Yield(true); + + user = newUser; + userAdding = true; + wxCommandEvent buttonEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_REFRESH); + AddPendingEvent(buttonEvent); +} + + + +void dlgHbaConfig::OnAddValue(wxCommandEvent &ev) +{ + if (databaseAdding) + { + cbDatabase->SetSelection(-1); + cbDatabase->SetValue(database); + cbDatabase->SetInsertionPointEnd(); + databaseAdding = false; + } + + if (userAdding) + { + cbUser->SetSelection(-1); + cbUser->SetValue(user); + cbUser->SetInsertionPointEnd(); + userAdding = false; + } + OnChange(ev); +} + + +void dlgHbaConfig::OnChange(wxCommandEvent &ev) +{ + if (databaseAdding || userAdding) + return; + + database = cbDatabase->GetValue(); + user = cbUser->GetValue(); + + bool needIp = (cbType->GetCurrentSelection() != 0); + + stIPaddress->Enable(needIp); + txtIPaddress->Enable(needIp); + + bool needOption = false; + // IDENT and LDAP always take an option + if (cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_IDENT || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_LDAP) + { + needOption = true; + } + else if (cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_GSS || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_SSPI || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_KRB5 || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_PAM || + cbMethod->GetCurrentSelection() == pgHbaConfigLine::PGC_CERT) + { + // GSS/SSPI/KRB5/PAM/CERT take options from 8.4 onwards. If we don't know the version + // then allow the option to be specified. + if (conn) + { + if (conn->BackendMinimumVersion(8, 4)) + needOption = true; + } + else + needOption = true; + } + + // On 8.4 and above, any hostssl lines can take an option + if (cbType->GetCurrentSelection() == pgHbaConfigLine::PGC_HOSTSSL) + { + if (conn) + { + if (conn->BackendMinimumVersion(8, 4)) + needOption = true; + } + else + needOption = true; + } + + stOption->Enable(needOption); + txtOption->Enable(needOption); + + bool ipValid = !chkEnabled->GetValue() || !needIp; + if (!ipValid) + { + // we should check for validity of txtIPaddress->GetValue() here + ipValid = true; + } + btnOK->Enable(cbType->GetCurrentSelection() >= 0 && !database.IsEmpty() && !user.IsEmpty() && + cbMethod->GetCurrentSelection() >= 0 && ipValid); +} + + +void dlgHbaConfig::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + line->isComment = !chkEnabled->GetValue(); + line->connectType = (pgHbaConfigLine::pgHbaConnectType)cbType->GetCurrentSelection(); + line->database = database; + line->user = user; + line->ipaddress = txtIPaddress->GetValue(); + line->method = (pgHbaConfigLine::pgHbaMethod)cbMethod->GetCurrentSelection(); + if (txtOption->IsEnabled()) + line->option = txtOption->GetValue(); + else + line->option = wxEmptyString; + line->changed = true; + + EndModal(wxID_OK); +} + + +void dlgHbaConfig::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + + +int dlgHbaConfig::Go() +{ + // Set focus on the Password textbox and show modal + return ShowModal(); +} diff --git a/dlg/dlgIndex.cpp b/dlg/dlgIndex.cpp new file mode 100644 index 0000000..48cce98 --- /dev/null +++ b/dlg/dlgIndex.cpp @@ -0,0 +1,663 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndex.cpp - PostgreSQL Index Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "dlg/dlgIndex.h" +#include "schema/pgIndex.h" +#include "schema/pgColumn.h" +#include "schema/pgTable.h" + + +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define cbType CTRL_COMBOBOX("cbType") +#define chkUnique CTRL_CHECKBOX("chkUnique") +#define chkClustered CTRL_CHECKBOX("chkClustered") +#define chkConcurrent CTRL_CHECKBOX("chkConcurrent") +#define txtWhere CTRL_TEXT("txtWhere") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define cbOpClass CTRL_COMBOBOX("cbOpClass") +#define chkDesc CTRL_CHECKBOX("chkDesc") +#define rdbNullsFirst CTRL_RADIOBUTTON("rdbNullsFirst") +#define rdbNullsLast CTRL_RADIOBUTTON("rdbNullsLast") +#define cbCollation CTRL_COMBOBOX("cbCollation") + + +BEGIN_EVENT_TABLE(dlgIndexBase, dlgCollistProperty) + EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtFillFactor"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgIndexBase::OnSelectListCol) + EVT_COMBOBOX(XRCID("cbColumns"), dlgIndexBase::OnSelectComboCol) +END_EVENT_TABLE(); + + +dlgProperty *pgIndexFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgIndex(this, frame, (pgIndex *)node, (pgTable *)parent); +} + + +dlgIndexBase::dlgIndexBase(pgaFactory *f, frmMain *frame, const wxString &resName, pgIndexBase *node, pgTable *parentNode) + : dlgCollistProperty(f, frame, resName, parentNode) +{ + index = node; + wxASSERT(!table || table->GetMetaType() == PGM_TABLE || table->GetMetaType() == GP_PARTITION); +} + + +dlgIndexBase::dlgIndexBase(pgaFactory *f, frmMain *frame, const wxString &resName, ctlListView *colList) + : dlgCollistProperty(f, frame, resName, colList) +{ + index = 0; +} + + +pgObject *dlgIndexBase::GetObject() +{ + return index; +} + + +int dlgIndexBase::Go(bool modal) +{ + + if (index) + { + // edit mode + txtName->Enable(connection->BackendMinimumVersion(9, 2)); + cbColumns->Disable(); + + if (txtFillFactor) + { + txtFillFactor->SetValue(index->GetFillFactor()); + } + } + else + { + // create mode + } + + if (txtFillFactor) + { + txtFillFactor->SetValidator(numericValidator); + if (connection->BackendMinimumVersion(8, 2)) + txtFillFactor->Enable(); + else + txtFillFactor->Disable(); + } + + btnAddCol->Disable(); + btnRemoveCol->Disable(); + + return dlgCollistProperty::Go(modal); +} + +void dlgIndexBase::OnSelectListCol(wxListEvent &ev) +{ + OnSelectCol(); +} + +void dlgIndexBase::OnSelectComboCol(wxCommandEvent &ev) +{ + if (cbType) + { + wxString method = wxEmptyString; + + if (cbType->GetValue().Length() == 0) + { + method = cbType->GetStringKey(1); + } + else + { + method = cbType->GetStringKey(cbType->GetCurrentSelection()); + } + + cbOpClass->Clear(); + + wxString sql = wxT("SELECT opcname FROM pg_opclass ") + wxT("WHERE opcmethod=") + method + + wxT(" AND NOT opcdefault") + wxT(" ORDER BY 1"); + pgSet *set = connection->ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + cbOpClass->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + + OnSelectCol(); +} + +void dlgIndexBase::OnSelectCol() +{ + // Can't change the columns on an existing index. + if (index) + return; + + if (lstColumns->GetSelection() != wxNOT_FOUND) + btnRemoveCol->Enable(true); + else + btnRemoveCol->Enable(false); + + if (cbColumns->GetSelection() != wxNOT_FOUND && !cbColumns->GetValue().IsEmpty()) + btnAddCol->Enable(true); + else + btnAddCol->Enable(false); +} + + +void dlgIndexBase::CheckChange() +{ + if (index) + { + EnableOK(txtName->GetValue() != index->GetName() || + txtComment->GetValue() != index->GetComment() || + cbTablespace->GetOIDKey() != index->GetTablespaceOid() || + txtFillFactor->GetValue() != index->GetFillFactor()); + } + else + { + bool enable = true; + txtComment->Enable(!GetName().IsEmpty()); + CheckValid(enable, lstColumns->GetItemCount() > 0, _("Please specify columns.")); + EnableOK(enable); + } +} + + +BEGIN_EVENT_TABLE(dlgIndex, dlgIndexBase) + EVT_BUTTON(XRCID("btnAddCol"), dlgIndex::OnAddCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgIndex::OnRemoveCol) + EVT_CHECKBOX(XRCID("chkClustered"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDesc"), dlgIndex::OnDescChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgIndex::OnChangeSize) +#endif + EVT_COMBOBOX(XRCID("cbType"), dlgIndex::OnSelectType) +END_EVENT_TABLE(); + + +dlgIndex::dlgIndex(pgaFactory *f, frmMain *frame, pgIndex *index, pgTable *parentNode) + : dlgIndexBase(f, frame, wxT("dlgIndex"), index, parentNode) +{ + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Order"), 40); + lstColumns->AddColumn(_("NULLs order"), 50); + lstColumns->AddColumn(_("Op. class"), 40); + lstColumns->AddColumn(_("Collation"), 40); +} + + +void dlgIndex::CheckChange() +{ + bool fill = false; + + txtComment->Enable(!txtName->GetValue().IsEmpty()); + chkClustered->Enable(!txtName->GetValue().IsEmpty()); + + if (index) + { + if (txtFillFactor) + { + fill = txtFillFactor->GetValue() != index->GetFillFactor() && !txtFillFactor->GetValue().IsEmpty(); + } + + EnableOK(fill || + txtComment->GetValue() != index->GetComment() || + chkClustered->GetValue() != index->GetIsClustered() || + cbTablespace->GetOIDKey() != index->GetTablespaceOid() || + (txtName->GetValue() != index->GetName() && + txtName->GetValue().Length() != 0)); + } + else + { + wxString name = GetName(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty() || (name.IsEmpty() && this->database->BackendMinimumVersion(9, 0)), _("Please specify name.")); + CheckValid(enable, lstColumns->GetItemCount() > 0, _("Please specify columns.")); + EnableOK(enable); + } +} + +void dlgIndex::OnSelectType(wxCommandEvent &ev) +{ + // The column options available change depending on the + // index type. We need to clear the column list, and + // setup some of the other controls accordingly. + + wxString newType = cbType->GetValue(); + bool changingDefault = false; + + // Detect if we're changing between default and btree (which are the same) to + // avoid annoying the user needlessly. + if ((m_previousType == wxEmptyString && cbType->GetValue() == wxT("btree")) || + (m_previousType == wxT("btree") && cbType->GetValue() == wxEmptyString)) + changingDefault = true; + + if (lstColumns->GetItemCount() > 0 && !changingDefault) + { + if (wxMessageBox(_("Changing the index type will cause the column list to be cleared. Do you wish to continue?"), _("Change index type?"), wxYES_NO) != wxYES) + { + cbType->SetValue(m_previousType); + return; + } + + // Move all the columns back to the combo + for (int pos = lstColumns->GetItemCount(); pos > 0; pos--) + { + wxString colName = lstColumns->GetItemText(pos - 1); + + lstColumns->DeleteItem(pos - 1); + cbColumns->Append(colName); + } + } + + if (newType == wxT("btree") || newType == wxEmptyString) + { + cbOpClass->Enable(true); + chkDesc->Enable(true); + rdbNullsFirst->Enable(true); + rdbNullsLast->Enable(true); + } + else + { + cbOpClass->Enable(false); + chkDesc->Enable(false); + rdbNullsFirst->Enable(false); + rdbNullsLast->Enable(false); + } + + // Make a note of the type so we can compare if it changes again. + m_previousType = cbType->GetValue(); +} + + +wxString dlgIndex::GetColumns() +{ + wxString sql; + + int pos; + // iterate cols + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetItemText(pos)); + + if (this->database->BackendMinimumVersion(9, 1)) + { + wxString collation = lstColumns->GetText(pos, 4); + if (!collation.IsEmpty() && collation != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + collation; + } + + wxString opclass = lstColumns->GetText(pos, 3); + if (!opclass.IsEmpty()) + sql += wxT(" ") + opclass; + + if (this->database->BackendMinimumVersion(8, 3)) + { + wxString order = lstColumns->GetText(pos, 1); + if (!order.IsEmpty()) + sql += wxT(" ") + order; + + wxString nullsOrder = lstColumns->GetText(pos, 2); + if (!nullsOrder.IsEmpty()) + sql += wxT(" NULLS ") + nullsOrder; + } + } + return sql; +} + + +int dlgIndex::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(7, 4)) + chkClustered->Disable(); + + if (index) + { + // edit mode: view only + + // We only display the column options (ASC/DESC, NULLS FIRST/LAST) + // on PostgreSQL 8.3+, for btree indexes. + wxArrayString colsArr = index->GetColumnList(); + wxArrayString collationsArray = index->GetCollationsArray(); + wxString colDef, descDef, nullsDef, opclassDef; + if (this->database->BackendMinimumVersion(8, 3) && index->GetIndexType() == wxT("btree")) + { + for (unsigned int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + colDef = colsArr.Item(colIdx); + descDef = index->GetOrdersArray().Item(colIdx); + nullsDef = index->GetNullsArray().Item(colIdx); + opclassDef = index->GetOpClassesArray().Item(colIdx); + + lstColumns->InsertItem(colIdx, colDef, columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 1, descDef); + lstColumns->SetItem(colIdx, 2, nullsDef); + lstColumns->SetItem(colIdx, 3, opclassDef); + if (colIdx < collationsArray.Count()) + lstColumns->SetItem(colIdx, 4, collationsArray.Item(colIdx)); + } + } + else + { + for (unsigned int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + int pos = colDef.First(wxT(" ")); + if (pos > 0) + { + opclassDef = colDef.Mid(pos + 1); + colDef = colDef.Mid(0, pos); + } + else + opclassDef = wxEmptyString; + + lstColumns->InsertItem(colIdx, colsArr.Item(colIdx), columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 3, cbOpClass->GetValue()); + if (colIdx < collationsArray.Count()) + lstColumns->SetItem(colIdx, 4, collationsArray.Item(colIdx)); + } + } + + cbType->Append(index->GetIndexType()); + chkUnique->SetValue(index->GetIsUnique()); + chkClustered->SetValue(index->GetIsClustered()); + txtWhere->SetValue(index->GetConstraint()); + cbType->SetSelection(0); + cbType->Disable(); + txtWhere->Disable(); + chkUnique->Disable(); + chkConcurrent->Disable(); + PrepareTablespace(cbTablespace, index->GetTablespaceOid()); + cbOpClass->Disable(); + chkDesc->Disable(); + rdbNullsFirst->Disable(); + rdbNullsLast->Disable(); + cbCollation->Disable(); + lstColumns->Disable(); + } + else + { + // create mode + PrepareTablespace(cbTablespace); + cbType->Append(wxT("")); + pgSet *set = connection->ExecuteSet(wxT( + "SELECT oid, amname FROM pg_am")); + if (set) + { + while (!set->Eof()) + { + cbType->Append(set->GetVal(1), set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + } + else + cbCollation->Disable(); + + if (!this->database->BackendMinimumVersion(8, 2)) + chkConcurrent->Disable(); + + if (!this->database->BackendMinimumVersion(8, 3)) + { + chkDesc->Disable(); + rdbNullsFirst->Disable(); + rdbNullsLast->Disable(); + } + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + } + + // Reset the labels as the XRC defined values will have been localised :-( + rdbNullsFirst->SetLabel(wxT("FIRST")); + rdbNullsLast->SetLabel(wxT("LAST")); + + int returnCode = dlgIndexBase::Go(modal); + + if (index && connection->BackendMinimumVersion(8, 0)) + txtName->Enable(true); + + // This fixes a UI glitch on MacOS X + // Because of the new layout code, the Columns pane doesn't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + return returnCode; +} + + +void dlgIndex::OnAddCol(wxCommandEvent &ev) +{ + wxString colName = cbColumns->GetValue(); + + if (!colName.IsEmpty()) + { + long colIndex = lstColumns->InsertItem(lstColumns->GetItemCount(), colName, columnFactory.GetIconId()); + + + if (this->database->BackendMinimumVersion(8, 3)) + { + if (chkDesc->GetValue()) + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("DESC")); + + + if (rdbNullsLast->GetValue()) + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + } + else + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("ASC")); + + if (rdbNullsFirst->GetValue()) + { + if (rdbNullsFirst->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + } + + lstColumns->SetItem(colIndex, 3, cbOpClass->GetValue()); + lstColumns->SetItem(colIndex, 4, cbCollation->GetValue()); + } + + cbColumns->Delete(cbColumns->GetCurrentSelection()); + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + CheckChange(); + if (!cbColumns->GetCount()) + btnAddCol->Disable(); + } +} + + +void dlgIndex::OnRemoveCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + if (pos >= 0) + { + wxString colName = lstColumns->GetItemText(pos); + + lstColumns->DeleteItem(pos); + cbColumns->Append(colName); + + CheckChange(); + btnRemoveCol->Disable(); + } +} + +#ifdef __WXMAC__ +void dlgIndex::OnChangeSize(wxSizeEvent &ev) +{ + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 700); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + +wxString dlgIndex::GetSql() +{ + wxString sql; + + if (table) + { + wxString name = GetName(); + if (!index) + { + sql = wxT("CREATE "); + if (chkUnique->GetValue()) + sql += wxT("UNIQUE "); + + sql += wxT("INDEX "); + + if (chkConcurrent->GetValue()) + sql += wxT("CONCURRENTLY "); + + sql += qtIdent(name); + + sql += wxT("\n ON ") + table->GetQuotedFullIdentifier(); + + if (cbType->GetCurrentSelection() > 0) + AppendIfFilled(sql, wxT(" USING "), cbType->GetValue()); + + sql += wxT(" (") + GetColumns() + + wxT(")"); + + if (txtFillFactor) + { + if (connection->BackendMinimumVersion(8, 2) && txtFillFactor->GetValue().Length() > 0) + sql += wxT("\n WITH (FILLFACTOR=") + txtFillFactor->GetValue() + wxT(")"); + } + + if (cbTablespace->GetOIDKey() > 0) + AppendIfFilled(sql, wxT("\n TABLESPACE "), qtIdent(cbTablespace->GetValue())); + + AppendIfFilled(sql, wxT(" WHERE "), txtWhere->GetValue()); + sql += wxT(";\n"); + } + else + { + if (connection->BackendMinimumVersion(8, 2) && txtFillFactor->GetValue().Length() > 0) + sql += wxT("ALTER INDEX ") + qtIdent(index->GetSchema()->GetName()) + wxT(".") + + qtIdent(index->GetName()) + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + + if(connection->BackendMinimumVersion(8, 0)) + { + if (index->GetName() != txtName->GetValue() && + !txtName->GetValue().IsEmpty()) + sql += wxT("ALTER INDEX ") + qtIdent(index->GetSchema()->GetName()) + wxT(".") + + qtIdent(index->GetName()) + wxT("\n RENAME TO ") + + qtIdent(txtName->GetValue()) + wxT(";\n"); + + if (cbTablespace->GetOIDKey() != index->GetTablespaceOid()) + sql += wxT("ALTER INDEX ") + qtIdent(index->GetSchema()->GetName()) + wxT(".") + qtIdent(name) + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + } + } + if (connection->BackendMinimumVersion(7, 4) && chkClustered->IsEnabled()) + { + if (index && index->GetIsClustered() && !chkClustered->GetValue()) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n SET WITHOUT CLUSTER;\n"); + else if (chkClustered->GetValue() && (!index || !index->GetIsClustered())) + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n CLUSTER ON ") + qtIdent(name) + wxT(";\n"); + } + + if (txtComment->IsEnabled()) + { + AppendComment(sql, wxT("INDEX"), table->GetSchema(), index); + } + } + return sql; +} + + +pgObject *dlgIndex::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = indexFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + +void dlgIndex::OnDescChange(wxCommandEvent &ev) +{ + if (chkDesc->GetValue()) + { + rdbNullsFirst->SetValue(true); + } + else + { + rdbNullsLast->SetValue(true); + } +} diff --git a/dlg/dlgIndexConstraint.cpp b/dlg/dlgIndexConstraint.cpp new file mode 100644 index 0000000..27c19d7 --- /dev/null +++ b/dlg/dlgIndexConstraint.cpp @@ -0,0 +1,688 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndexConstraint.cpp - PostgreSQL IndexConstraint Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "dlg/dlgIndexConstraint.h" +#include "schema/pgIndex.h" +#include "schema/pgColumn.h" +#include "schema/pgTable.h" +#include "schema/pgIndexConstraint.h" + + +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define cbIndex CTRL_COMBOBOX("cbIndex") +#define cbType CTRL_COMBOBOX("cbType") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define txtWhere CTRL_TEXT("txtWhere") +#define chkDeferrable CTRL_CHECKBOX("chkDeferrable") +#define chkDeferred CTRL_CHECKBOX("chkDeferred") +#define cbOpClass CTRL_COMBOBOX("cbOpClass") +#define chkDesc CTRL_CHECKBOX("chkDesc") +#define rdbNullsFirst CTRL_RADIOBUTTON("rdbNullsFirst") +#define rdbNullsLast CTRL_RADIOBUTTON("rdbNullsLast") +#define cbOperator CTRL_COMBOBOX("cbOperator") + +BEGIN_EVENT_TABLE(dlgIndexConstraint, dlgIndexBase) + EVT_CHECKBOX(XRCID("chkDeferrable"), dlgProperty::OnChange) + EVT_BUTTON(XRCID("btnAddCol"), dlgIndexConstraint::OnAddCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgIndexConstraint::OnRemoveCol) +#ifdef __WXMAC__ + EVT_SIZE( dlgIndexConstraint::OnChangeSize) +#endif + EVT_COMBOBOX(XRCID("cbIndex"), dlgIndexConstraint::OnChangeIndex) + EVT_COMBOBOX(XRCID("cbType"), dlgIndexConstraint::OnSelectType) + EVT_COMBOBOX(XRCID("cbColumns"), dlgIndexConstraint::OnSelectComboCol) +END_EVENT_TABLE(); + + +dlgIndexConstraint::dlgIndexConstraint(pgaFactory *f, frmMain *frame, const wxString &resName, pgIndexBase *index, pgTable *parentNode) + : dlgIndexBase(f, frame, resName, index, parentNode) +{ + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Order"), 40); + lstColumns->AddColumn(_("NULLs order"), 50); + lstColumns->AddColumn(_("Op. class"), 40); + lstColumns->AddColumn(_("Operator"), 40); +} + + +dlgIndexConstraint::dlgIndexConstraint(pgaFactory *f, frmMain *frame, const wxString &resName, ctlListView *colList) + : dlgIndexBase(f, frame, resName, colList) +{ + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Order"), 40); + lstColumns->AddColumn(_("NULLs order"), 50); + lstColumns->AddColumn(_("Op. class"), 40); + lstColumns->AddColumn(_("Operator"), 40); +} + + +wxString dlgIndexConstraint::GetColumns() +{ + wxString sql; + + int pos; + // iterate cols + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetItemText(pos)); + + wxString opclass = lstColumns->GetText(pos, 3); + if (!opclass.IsEmpty()) + sql += wxT(" ") + opclass; + + wxString order = lstColumns->GetText(pos, 1); + if (!order.IsEmpty()) + sql += wxT(" ") + order; + + wxString nullsOrder = lstColumns->GetText(pos, 2); + if (!nullsOrder.IsEmpty()) + sql += wxT(" NULLS ") + nullsOrder; + + wxString oper = lstColumns->GetText(pos, 4); + if (!oper.IsEmpty()) + sql += wxT(" WITH ") + oper; + } + return sql; +} + + +int dlgIndexConstraint::Go(bool modal) +{ + pgSet *set; + + PrepareTablespace(cbTablespace); + + if (wxString(factory->GetTypeName()).Upper() == wxT("EXCLUDE")) + { + cbIndex->Disable(); + } + else + { + cbIndex->Enable(connection->BackendMinimumVersion(9, 1)); + cbType->Disable(); + txtWhere->Disable(); + cbOpClass->Disable(); + chkDesc->Disable(); + rdbNullsFirst->Disable(); + rdbNullsLast->Disable(); + cbOperator->Disable(); + } + + if (index) + { + pgIndexConstraint *idc = (pgIndexConstraint *)index; + + // We only display the column options (ASC/DESC, NULLS FIRST/LAST) + // on exclude constraints with btree + wxArrayString colsArr = index->GetColumnList(); + wxString colDef, colRest, descDef, nullsDef, opclassDef, withDef; + const wxString firstOrder = wxT(" NULLS FIRST"), lastOrder = wxT(" NULLS LAST"); + const wxString descOrder = wxT(" DESC"); + if (wxString(factory->GetTypeName()).Upper() == wxT("EXCLUDE") && index->GetIndexType() == wxT("btree")) + { + for (int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + colDef = colsArr.Item(colIdx); + + int withStartPoint = colDef.Find(wxT(" WITH ")); + if (withStartPoint > 0) + { + withDef = colDef.Mid(withStartPoint + 6, colDef.Length() - withStartPoint - 6); + colDef = colDef.Mid(0, withStartPoint); + } + else + withDef = wxT(""); + + if (colDef.EndsWith(firstOrder.GetData(), &colRest)) + { + colDef = colRest; + nullsDef = wxT("FIRST"); + } + else if (colDef.EndsWith(lastOrder.GetData(), &colRest)) + { + colDef = colRest; + nullsDef = wxT("LAST"); + } + else + nullsDef = wxT(""); + + if (colDef.EndsWith(descOrder.GetData(), &colRest)) + { + colDef = colRest; + descDef = wxT("DESC"); + if (nullsDef.IsEmpty()) + nullsDef = wxT("FIRST"); + } + else + { + descDef = wxT("ASC"); + if (nullsDef.IsEmpty()) + nullsDef = wxT("LAST"); + } + + int pos = colDef.First(wxT(" ")); + if (pos > 0) + { + opclassDef = colDef.Mid(pos + 1); + colDef = colDef.Mid(0, pos); + } + else + opclassDef = wxEmptyString; + + lstColumns->InsertItem(colIdx, colDef, columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 1, descDef); + lstColumns->SetItem(colIdx, 2, nullsDef); + lstColumns->SetItem(colIdx, 3, opclassDef); + lstColumns->SetItem(colIdx, 4, withDef); + } + } + else + { + for (int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + colDef = colsArr.Item(colIdx); + + int withStartPoint = colDef.Find(wxT(" WITH ")); + if (withStartPoint > 0) + { + withDef = colDef.Mid(withStartPoint + 6, colDef.Length() - withStartPoint - 6); + colDef = colDef.Mid(0, withStartPoint); + } + else + withDef = wxT(""); + + int pos = colDef.First(wxT(" ")); + if (pos > 0) + { + opclassDef = colDef.Mid(pos + 1); + colDef = colDef.Mid(0, pos); + } + else + opclassDef = wxEmptyString; + + lstColumns->InsertItem(colIdx, colDef, columnFactory.GetIconId()); + lstColumns->SetItem(colIdx, 3, cbOpClass->GetValue()); + lstColumns->SetItem(colIdx, 4, withDef); + } + } + + if (idc->GetTablespaceOid() != 0) + cbTablespace->SetKey(idc->GetTablespaceOid()); + cbTablespace->Enable(connection->BackendMinimumVersion(8, 0)); + + if (txtFillFactor) + { + txtFillFactor->SetValue(idc->GetFillFactor()); + } + + if (index->GetIndexType().Length() > 0) + { + cbType->Append(index->GetIndexType()); + cbType->SetSelection(0); + cbType->Disable(); + } + + chkDeferrable->SetValue(index->GetDeferrable()); + chkDeferred->SetValue(index->GetDeferred()); + chkDeferrable->Enable(false); + chkDeferred->Enable(false); + } + else + { + txtComment->Disable(); + if (!table) + { + cbClusterSet->Disable(); + cbClusterSet = 0; + } + + // Add the indexes + if (table) + { + cbIndex->Append(wxT("")); + set = connection->ExecuteSet( + wxT("SELECT relname FROM pg_class, pg_index WHERE pg_class.oid=indexrelid AND indrelid=") + table->GetOidStr()); + if (set) + { + while (!set->Eof()) + { + cbIndex->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + else + { + cbIndex->Disable(); + } + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + wxString can_exclude = wxT("WHERE EXISTS (SELECT 1 FROM pg_proc WHERE oid=amgettuple) "); + if (connection->BackendMinimumVersion(9, 6)) + can_exclude = wxT("WHERE pg_indexam_has_property(oid,'can_exclude') "); + + cbType->Append(wxT("")); + + set = connection->ExecuteSet( + wxT("SELECT oid, amname FROM pg_am ") + + can_exclude+ + wxT("ORDER BY amname")); + if (set) + { + while (!set->Eof()) + { + cbType->Append(set->GetVal(1), set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + chkDeferrable->Enable(connection->BackendMinimumVersion(9, 0)); + chkDeferred->Enable(connection->BackendMinimumVersion(9, 0)); + } + + txtFillFactor->SetValidator(numericValidator); + if (connection->BackendMinimumVersion(8, 2)) + txtFillFactor->Enable(); + else + txtFillFactor->Disable(); + + return dlgIndexBase::Go(modal); +} + + +void dlgIndexConstraint::OnAddCol(wxCommandEvent &ev) +{ + wxString colName = cbColumns->GetValue(); + + if (!colName.IsEmpty()) + { + long colIndex = lstColumns->InsertItem(lstColumns->GetItemCount(), colName, columnFactory.GetIconId()); + + if (chkDesc->GetValue()) + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("DESC")); + + + if (rdbNullsLast->GetValue()) + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + } + else + { + if (chkDesc->IsEnabled()) + lstColumns->SetItem(colIndex, 1, wxT("ASC")); + + if (rdbNullsFirst->GetValue()) + { + if (rdbNullsFirst->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("FIRST")); + } + else + { + if (rdbNullsLast->IsEnabled()) + lstColumns->SetItem(colIndex, 2, wxT("LAST")); + } + } + + lstColumns->SetItem(colIndex, 3, cbOpClass->GetValue()); + lstColumns->SetItem(colIndex, 4, cbOperator->GetValue()); + + cbColumns->Delete(cbColumns->GetCurrentSelection()); + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + CheckChange(); + if (!cbColumns->GetCount()) + btnAddCol->Disable(); + } +} + + +void dlgIndexConstraint::OnRemoveCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + if (pos >= 0) + { + wxString colName = lstColumns->GetItemText(pos); + + lstColumns->DeleteItem(pos); + cbColumns->Append(colName); + + CheckChange(); + btnRemoveCol->Disable(); + } +} + +#ifdef __WXMAC__ +void dlgIndexConstraint::OnChangeSize(wxSizeEvent &ev) +{ + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgIndexConstraint::OnSelectComboCol(wxCommandEvent &ev) +{ + cbOperator->Clear(); + cbOperator->Append(wxT("")); + + if (cbColumns->GetValue().Length() > 0) + { + pgSet *set = connection->ExecuteSet( + wxT("SELECT DISTINCT oprname FROM pg_operator \n") + wxT("WHERE (") + wxT(" oprleft=") + NumToStr(cbColumns->GetOIDKey(cbColumns->GetCurrentSelection())) + + wxT(" OR oprright=") + NumToStr(cbColumns->GetOIDKey(cbColumns->GetCurrentSelection())) + + wxT(") AND oprcom > 0 \n") + wxT("ORDER BY oprname")); + if (set) + { + while (!set->Eof()) + { + cbOperator->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + } + + dlgIndexBase::OnSelectComboCol(ev); +} + + +void dlgIndexConstraint::OnChangeIndex(wxCommandEvent &ev) +{ + bool indexselected = cbIndex->GetCurrentSelection() > 0; + bool btreeindex = cbType->GetValue() == wxT("btree") || cbType->GetValue() == wxEmptyString; + bool excludeconstraint = wxString(factory->GetTypeName()).Upper() == wxT("EXCLUDE"); + + cbTablespace->Enable(!indexselected && connection->BackendMinimumVersion(8, 0)); + cbType->Enable(!indexselected && excludeconstraint); + txtFillFactor->Enable(!indexselected && connection->BackendMinimumVersion(8, 2)); + txtWhere->Enable(!indexselected && excludeconstraint); + chkDeferrable->Enable(!indexselected && connection->BackendMinimumVersion(9, 0)); + chkDeferred->Enable(!indexselected && connection->BackendMinimumVersion(9, 0)); + cbOpClass->Enable(!indexselected && excludeconstraint && btreeindex); + chkDesc->Enable(!indexselected && excludeconstraint && btreeindex); + rdbNullsFirst->Enable(!indexselected && excludeconstraint && btreeindex); + rdbNullsLast->Enable(!indexselected && excludeconstraint && btreeindex); + cbOperator->Enable(!indexselected && excludeconstraint); + cbColumns->Enable(!indexselected); + btnAddCol->Enable(!indexselected); + btnRemoveCol->Enable(!indexselected); +} + + +void dlgIndexConstraint::OnSelectType(wxCommandEvent &ev) +{ + // The column options available change depending on the + // index type. We need to clear the column list, and + // setup some of the other controls accordingly. + + wxString newType = cbType->GetValue(); + bool changingDefault = false; + + // Detect if we're changing between default and btree (which are the same) to + // avoid annoying the user needlessly. + if ((m_previousType == wxEmptyString && cbType->GetValue() == wxT("btree")) || + (m_previousType == wxT("btree") && cbType->GetValue() == wxEmptyString)) + changingDefault = true; + + if (lstColumns->GetItemCount() > 0 && !changingDefault) + { + if (wxMessageBox(_("Changing the index type will cause the column list to be cleared. Do you wish to continue?"), _("Change index type?"), wxYES_NO) != wxYES) + { + cbType->SetValue(m_previousType); + return; + } + + // Move all the columns back to the combo + for (int pos = lstColumns->GetItemCount(); pos > 0; pos--) + { + wxString colName = lstColumns->GetItemText(pos - 1); + + lstColumns->DeleteItem(pos - 1); + cbColumns->Append(colName); + } + } + + if (newType == wxT("btree") || newType == wxEmptyString) + { + cbOpClass->Enable(true); + chkDesc->Enable(true); + rdbNullsFirst->Enable(true); + rdbNullsLast->Enable(true); + } + else + { + cbOpClass->Enable(false); + chkDesc->Enable(false); + rdbNullsFirst->Enable(false); + rdbNullsLast->Enable(false); + } + + // Make a note of the type so we can compare if it changes again. + m_previousType = cbType->GetValue(); +} + + +void dlgIndexConstraint::CheckChange() +{ + if (cbIndex->GetCurrentSelection() > 0) + EnableOK(true); + else + dlgIndexBase::CheckChange(); +} + + +wxString dlgIndexConstraint::GetDefinition() +{ + wxString sql = wxEmptyString; + + if (cbIndex->GetCurrentSelection() > 0) + { + sql += wxT(" USING INDEX ") + qtIdent(cbIndex->GetValue()); + } + else + { + if (cbType->GetCurrentSelection() > 0) + AppendIfFilled(sql, wxT(" USING "), cbType->GetValue()); + + sql += wxT("(") + GetColumns() + wxT(")"); + + if (txtFillFactor) + { + if (connection->BackendMinimumVersion(8, 2) && txtFillFactor->GetValue().Length() > 0) + sql += wxT("\n WITH (FILLFACTOR=") + txtFillFactor->GetValue() + wxT(")"); + } + + if (cbTablespace->GetOIDKey() > 0) + sql += wxT(" USING INDEX TABLESPACE ") + qtIdent(cbTablespace->GetValue()); + + if (chkDeferrable->GetValue()) + { + sql += wxT(" DEFERRABLE"); + if (chkDeferred->GetValue()) + sql += wxT(" INITIALLY DEFERRED"); + } + + if (txtWhere->GetValue().Length() > 0) + sql += wxT(" WHERE (") + txtWhere->GetValue() + wxT(")"); + } + + return sql; +} + + +wxString dlgIndexConstraint::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (!index) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD"); + AppendIfFilled(sql, wxT(" CONSTRAINT "), qtIdent(name)); + + sql += wxT(" ") + wxString(factory->GetTypeName()).Upper() + wxT(" ") + GetDefinition() + + wxT(";\n"); + } + else + { + if (index->GetName() != name) + { + sql = wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n RENAME CONSTRAINT ") + qtIdent(index->GetName()) + + wxT(" TO ") + qtIdent(name) + wxT(";\n"); + } + if (connection->BackendMinimumVersion(8, 0) && cbTablespace->GetOIDKey() != index->GetTablespaceOid()) + { + sql += wxT("ALTER INDEX ") + index->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(name) + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + } + + if (txtFillFactor->GetValue().Trim().Length() > 0 && txtFillFactor->GetValue() != index->GetFillFactor()) + { + sql += wxT("ALTER INDEX ") + index->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(name) + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + } + + if (!name.IsEmpty()) + AppendComment(sql, wxT("CONSTRAINT ") + qtIdent(name) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), index); + + return sql; +} + + + +dlgProperty *pgPrimaryKeyFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgPrimaryKey(this, frame, (pgPrimaryKey *)node, (pgTable *)parent); +} + + + + +dlgPrimaryKey::dlgPrimaryKey(pgaFactory *f, frmMain *frame, pgPrimaryKey *index, pgTable *parentNode) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), index, parentNode) +{ +} + + +dlgPrimaryKey::dlgPrimaryKey(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), colList) +{ +} + + +pgObject *dlgPrimaryKey::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + if (name.IsEmpty()) + return 0; + + pgObject *obj = primaryKeyFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + + return obj; +} + + + +dlgProperty *pgUniqueFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgUnique(this, frame, (pgUnique *)node, (pgTable *)parent); +} + + +dlgUnique::dlgUnique(pgaFactory *f, frmMain *frame, pgUnique *index, pgTable *parentNode) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), index, parentNode) +{ +} + + +dlgUnique::dlgUnique(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), colList) +{ +} + + +pgObject *dlgUnique::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = uniqueFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + + +dlgProperty *pgExcludeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgExclude(this, frame, (pgExclude *)node, (pgTable *)parent); +} + + +dlgExclude::dlgExclude(pgaFactory *f, frmMain *frame, pgExclude *index, pgTable *parentNode) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), index, parentNode) +{ +} + + +dlgExclude::dlgExclude(pgaFactory *f, frmMain *frame, ctlListView *colList) + : dlgIndexConstraint(f, frame, wxT("dlgIndexConstraint"), colList) +{ +} + + +pgObject *dlgExclude::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = excludeFactory.CreateObjects(collection, 0, wxT( + "\n AND cls.relname=") + qtDbString(name) + wxT( + "\n AND cls.relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} diff --git a/dlg/dlgLanguage.cpp b/dlg/dlgLanguage.cpp new file mode 100644 index 0000000..7c8c5bc --- /dev/null +++ b/dlg/dlgLanguage.cpp @@ -0,0 +1,263 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgLanguage.cpp - Language properties dialog +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgLanguage.h" +#include "schema/pgLanguage.h" +#include "ctl/ctlSeclabelPanel.h" + +// pointer to controls +#define cbName CTRL_COMBOBOX("cbName") +#define chkTrusted CTRL_CHECKBOX("chkTrusted") +#define cbHandler CTRL_COMBOBOX("cbHandler") +#define cbInline CTRL_COMBOBOX("cbInline") +#define cbValidator CTRL_COMBOBOX("cbValidator") + +dlgProperty *pgLanguageFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgLanguage(this, frame, (pgLanguage *)node, parent); +} + +BEGIN_EVENT_TABLE(dlgLanguage, dlgSecurityProperty) + EVT_TEXT(XRCID("cbName"), dlgLanguage::OnChangeName) + EVT_COMBOBOX(XRCID("cbName"), dlgLanguage::OnChangeName) + EVT_TEXT(XRCID("cbHandler"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbHandler"), dlgProperty::OnChange) +END_EVENT_TABLE(); + +dlgLanguage::dlgLanguage(pgaFactory *f, frmMain *frame, pgLanguage *node, pgObject *parent) + : dlgSecurityProperty(f, frame, node, wxT("dlgLanguage"), wxT("USAGE"), "U") +{ + language = node; + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + if (!node) + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value = wxT("U"); + securityPage->lbPrivileges->AppendItem(icon, name, value); + AppendCurrentAcl(name, value); + } +} + +pgObject *dlgLanguage::GetObject() +{ + return language; +} + +int dlgLanguage::Go(bool modal) +{ + if (!connection->BackendMinimumVersion(8, 3)) + cbOwner->Disable(); + + if (!connection->BackendMinimumVersion(7, 5)) + txtComment->Disable(); + + if (!connection->BackendMinimumVersion(9, 0)) + cbInline->Disable(); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(language); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgLanguage::OnChange)); + } + else + seclabelPage->Disable(); + + if (language) + { + // edit mode + chkTrusted->SetValue(language->GetTrusted()); + + cbHandler->Append(language->GetHandlerProc()); + cbHandler->SetSelection(0); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbInline->Append(language->GetInlineProc()); + cbInline->SetSelection(0); + } + + wxString val = language->GetValidatorProc(); + if (!val.IsEmpty()) + { + cbValidator->Append(val); + cbValidator->SetSelection(0); + } + + cbName->SetValue(language->GetName()); + if (!connection->BackendMinimumVersion(7, 4)) + cbName->Disable(); + + chkTrusted->Disable(); + cbHandler->Disable(); + cbInline->Disable(); + cbValidator->Disable(); + } + else + { + // create mode + if (connection->BackendMinimumVersion(8, 1)) + { + pgSetIterator languages(connection, + wxT("SELECT tmplname FROM pg_pltemplate\n") + wxT(" LEFT JOIN pg_language ON tmplname=lanname\n") + wxT(" WHERE lanname IS NULL\n") + wxT(" ORDER BY tmplname")); + + while (languages.RowsLeft()) + cbName->Append(languages.GetVal(wxT("tmplname"))); + } + else + { + // to clear drop down list + cbName->Append(wxT(" ")); + cbName->Delete(0); + } + + cbValidator->Append(wxT("")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT nspname, proname, prorettype, proargtypes[0] AS argtype\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" WHERE prorettype=") + NumToStr(PGOID_TYPE_LANGUAGE_HANDLER) + wxT("\n") + wxT(" OR (prorettype=") + NumToStr(PGOID_TYPE_VOID) + + wxT(" AND proargtypes[0]=") + NumToStr(PGOID_TYPE_LANGUAGE_HANDLER) + wxT(")") + wxT(" OR (prorettype=") + NumToStr(PGOID_TYPE_VOID) + + wxT(" AND proargtypes[0]=") + NumToStr(PGOID_TYPE_INTERNAL) + wxT(")")); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + if (set->GetOid(wxT("prorettype")) == PGOID_TYPE_LANGUAGE_HANDLER) + cbHandler->Append(procname); + else + { + if (set->GetOid(wxT("argtype")) == PGOID_TYPE_LANGUAGE_HANDLER) + cbValidator->Append(procname); + else + cbInline->Append(procname); + } + set->MoveNext(); + } + delete set; + } + cbHandler->SetSelection(0); + cbInline->SetSelection(0); + cbValidator->SetSelection(0); + } + + return dlgSecurityProperty::Go(modal); +} + +pgObject *dlgLanguage::CreateObject(pgCollection *collection) +{ + wxString name = cbName->wxComboBox::GetValue(); + + pgObject *obj = languageFactory.CreateObjects(collection, 0, wxT("\n AND lanname ILIKE ") + qtDbString(name)); + return obj; +} + +void dlgLanguage::OnChangeName(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(8, 1) && !language) + { + bool useTemplate = (cbName->FindString(cbName->wxComboBox::GetValue()) >= 0); + chkTrusted->Enable(!useTemplate); + cbHandler->Enable(!useTemplate); + cbInline->Enable(!useTemplate && connection->BackendMinimumVersion(9, 0)); + cbValidator->Enable(!useTemplate); + } + OnChange(ev); +} + +void dlgLanguage::CheckChange() +{ + bool enable = true; + wxString name = cbName->GetValue(); + if (language) + { + enable = name != language->GetName() + || txtComment->GetValue() != language->GetComment() + || (connection->BackendMinimumVersion(8, 3) && cbOwner->GetValue() != language->GetOwner()); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + bool useTemplate = (cbName->FindString(name) >= 0); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, useTemplate || !cbHandler->GetValue().IsEmpty(), _("Please specify language handler.")); + } + EnableOK(enable); +} + +wxString dlgLanguage::GetSql() +{ + wxString sql, name; + name = cbName->GetValue(); + + if (language) + { + // edit mode + if (name != language->GetName()) + sql += wxT("ALTER LANGUAGE ") + qtIdent(language->GetName()) + + wxT("\n RENAME TO ") + qtIdent(name) + wxT(";\n"); + if (connection->BackendMinimumVersion(8, 3)) + AppendOwnerChange(sql, wxT("LANGUAGE ") + qtIdent(name)); + } + else + { + // create mode + if (connection->BackendMinimumVersion(8, 1) && cbName->FindString(name) >= 0) + { + sql = wxT("CREATE LANGUAGE ") + qtIdent(name) + wxT(";\n"); + } + else + { + sql = wxT("CREATE "); + if (chkTrusted->GetValue()) + sql += wxT("TRUSTED "); + sql += wxT("LANGUAGE ") + qtIdent(name) + wxT("\n HANDLER ") + qtIdent(cbHandler->GetValue()); + if (connection->BackendMinimumVersion(9, 0)) + AppendIfFilled(sql, wxT("\n INLINE "), qtIdent(cbInline->GetValue())); + AppendIfFilled(sql, wxT("\n VALIDATOR "), qtIdent(cbValidator->GetValue())); + sql += wxT(";\n"); + } + if (connection->BackendMinimumVersion(8, 3)) + AppendOwnerNew(sql, wxT("LANGUAGE ") + qtIdent(name)); + } + + sql += GetGrant(wxT("U"), wxT("LANGUAGE ") + qtIdent(name)); + AppendComment(sql, wxT("LANGUAGE ") + qtIdent(name), 0, language); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("LANGUAGE"), qtIdent(name)); + + return sql; +} + +void dlgLanguage::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgMainConfig.cpp b/dlg/dlgMainConfig.cpp new file mode 100644 index 0000000..b59301a --- /dev/null +++ b/dlg/dlgMainConfig.cpp @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMainConfig.cpp - Configure setting +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgMainConfig.h" + + +// Icons +#include "images/property.pngc" + + + + + +BEGIN_EVENT_TABLE(dlgMainConfig, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgMainConfig::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgMainConfig::OnCancel) + EVT_TEXT(XRCID("txtValue"), dlgMainConfig::OnChange) + EVT_TEXT(XRCID("cbValue"), dlgMainConfig::OnChange) + EVT_CHECKBOX(XRCID("chkValue"), dlgMainConfig::OnChange) +END_EVENT_TABLE() + + +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define cbValue CTRL_COMBOBOX("cbValue") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") +#define txtComment CTRL_TEXT("txtComment") +#define stName CTRL_STATIC("stName") +#define stDescription CTRL_STATIC("stDescription") + + +static const wxChar *contextStrings[] = +{ + __("Internal - not externally settable"), + __("Postmaster - set on server start"), + __("SIGHUP - reloaded on SIGHUP signal"), + __("Backend - overridable in individual backend"), + __("Suset - may be overridden by superuser"), + __("Userlimit - may be set by user"), + __("Userset - may be set by user"), + __("Unknown") +}; + + +static const wxChar *sourceStrings[] = +{ + __("Variable has still its initial default value"), + __("Set via environment variable"), + __("Set in configuration file"), + __("Set on command line"), + __("Set by unprivileged command"), + __("Set in database variables"), + __("Set in user variables"), + __("Set in client parameters"), + __("set by Override"), + __("Set interactively"), + __("Set by test"), + __("Set by session parameters") +}; + + +dlgMainConfig::dlgMainConfig(pgFrame *parent, pgSettingItem *_item) : + DialogWithHelp((frmMain *)parent) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)parent, wxT("dlgMainConfig")); + + // Icon + SetIcon(*property_png_ico); + RestorePosition(); + + item = _item; + + SetTitle(wxString::Format(_("Configuration setting \"%s\""), item->name.c_str())); + + // Setup the default values + + cbValue->Hide(); + chkValue->Hide(); + + if (!item->newLine) + { + if (item->orgLine) + item->newLine = new pgConfigLine(item->orgLine); + else + { + item->newLine = new pgConfigLine(); + item->newLine->item = item; + } + } + + chkEnabled->SetValue(!item->newLine->isComment); + txtValue->SetValue(item->newLine->value); + txtComment->SetValue(item->newLine->comment); + + wxFont fntLabel = stName->GetFont(); + fntLabel.SetWeight(wxBOLD); + stName->SetFont(fntLabel); + stName->SetLabel(item->name); + + wxString str; + str += _("Category") + wxString(wxT(": ")) + item->category + END_OF_LINE; + str += _("Context") + wxString(wxT(": ")); + str += wxGetTranslation(contextStrings[item->context]); + str += END_OF_LINE; + + if (item->source != pgSettingItem::PGC_UNKNOWNSOURCE) + { + str += _("Current value") + wxString(wxT(": ")); + + if (item->value == wxT("unset") && item->source == pgSettingItem::PGC_DEFAULT) + str += _("unset"); + else + str += item->value + END_OF_LINE wxT(" ") + wxGetTranslation(sourceStrings[item->source]); + + str += END_OF_LINE; + } + + stDescription->SetLabel(str + END_OF_LINE + item->short_desc + END_OF_LINE + item->extra_desc); + btnOK->Enable(); +} + + +dlgMainConfig::~dlgMainConfig() +{ + SavePosition(); +} + + +wxString dlgMainConfig::GetValue() +{ + return txtValue->GetValue(); +} + + +wxString dlgMainConfig::GetHelpPage() const +{ + return wxT("pg/runtime-config"); +} + + +void dlgMainConfig::OnChange(wxCommandEvent &ev) +{ +} + + +void dlgMainConfig::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + item->newLine->value = GetValue(); + item->newLine->comment = txtComment->GetValue(); + item->newLine->isComment = !chkEnabled->GetValue(); + + EndModal(wxID_OK); +} + + +void dlgMainConfig::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +int dlgMainConfig::Go() +{ + // Set focus on the Password textbox and show modal + return ShowModal(); +} diff --git a/dlg/dlgManageFavourites.cpp b/dlg/dlgManageFavourites.cpp new file mode 100644 index 0000000..a04fc06 --- /dev/null +++ b/dlg/dlgManageFavourites.cpp @@ -0,0 +1,207 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageFavourites.cpp - Manage favourites +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgManageFavourites.h" +#include "db/pgConn.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" + +#include "images/folder.pngc" +#include "images/favourite.pngc" + +#include "utils/favourites.h" + +#include + +BEGIN_EVENT_TABLE(dlgManageFavourites, pgDialog) + EVT_TREE_SEL_CHANGED(XRCID("trLocation"), dlgManageFavourites::OnTreeChange) + EVT_BUTTON (wxID_OK, dlgManageFavourites::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgManageFavourites::OnCancel) + EVT_BUTTON (XRCID("btnRename"), dlgManageFavourites::OnRename) + EVT_BUTTON (XRCID("btnDelete"), dlgManageFavourites::OnDelete) + EVT_BUTTON (XRCID("btnNewFolder"), dlgManageFavourites::OnNewFolder) +END_EVENT_TABLE() + + +#define btnRename CTRL_BUTTON("btnRename") +#define btnDelete CTRL_BUTTON("btnDelete") +#define btnNewFolder CTRL_BUTTON("btnNewFolder") +// #define txtTitle CTRL_TEXT("txtTitle") +#define trLocation CTRL_TREE("trLocation") + + +dlgManageFavourites::dlgManageFavourites(wxWindow *parent, queryFavouriteFolder *favourites) : + pgDialog() +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgManageFavourites")); + RestorePosition(); + + anythingChanged = false; + + this->favourites = favourites; + + wxImageList *imgList = new wxImageList(16, 16, true, 2); + imgList->Add(*favourite_png_ico); + imgList->Add(*folder_png_ico); + + trLocation->AssignImageList(imgList); + + // Setup the default values + trLocation->AddRoot(_("Favourites"), 1); + trLocation->SetItemImage(trLocation->GetRootItem(), 1, wxTreeItemIcon_Normal); + trLocation->SelectItem(trLocation->GetRootItem()); + favourites->AppendAllToTree(trLocation, trLocation->GetRootItem(), false); + trLocation->Expand(trLocation->GetRootItem()); +} + +int dlgManageFavourites::ManageFavourites() +{ + int r = ShowModal(); + if (r == wxID_OK) + return 1; + else + { + if (anythingChanged) + // Need rollback! + return -1; + else + return 0; + } +} + +dlgManageFavourites::~dlgManageFavourites() +{ + SavePosition(); +} + + +void dlgManageFavourites::OnOK(wxCommandEvent &ev) +{ + EndModal(wxID_OK); +} + + +void dlgManageFavourites::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgManageFavourites::OnTreeChange(wxTreeEvent &ev) +{ + if (!trLocation->GetSelection().IsOk()) + { + btnRename->Enable(false); + btnDelete->Enable(false); + btnNewFolder->Enable(false); + return; + } + if (trLocation->GetSelection() == trLocation->GetRootItem()) + { + // On root item + btnRename->Enable(false); + btnDelete->Enable(false); + btnNewFolder->Enable(true); + } + else + { + btnRename->Enable(true); + btnDelete->Enable(true); + btnNewFolder->Enable(trLocation->GetItemImage(trLocation->GetSelection()) == 1); + } +} + + +void dlgManageFavourites::OnRename(wxCommandEvent &ev) +{ + if (!trLocation->GetSelection().IsOk() || + trLocation->GetSelection() == trLocation->GetRootItem()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + + wxTextEntryDialog dlg(this, _("Enter new name"), (item->GetId() != -2) ? _("Rename favourite") : _("Rename favourites folder"), item->GetTitle()); + if (dlg.ShowModal() != wxID_OK) + return; + + if (dlg.GetValue() != item->GetTitle()) + { + item->SetTitle(dlg.GetValue()); + trLocation->SetItemText(trLocation->GetSelection(), dlg.GetValue()); + anythingChanged = true; + } +} + +void dlgManageFavourites::OnDelete(wxCommandEvent &ev) +{ + wxString msg; + + if (!trLocation->GetSelection().IsOk() || + trLocation->GetSelection() == trLocation->GetRootItem()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + + if (item->GetId() != -2) + msg = wxString::Format(_("Are you sure you want to delete the favourite '%s'?"), item->GetTitle().c_str()); + else + msg = wxString::Format(_("Are you sure you want to delete the folder '%s'?"), item->GetTitle().c_str()); + if (wxMessageDialog(this, msg, _("Confirm delete"), wxYES_NO | wxICON_QUESTION).ShowModal() != wxID_YES) + return; + + if (favourites->DeleteTreeItem(trLocation->GetSelection())) + { + trLocation->Delete(trLocation->GetSelection()); + anythingChanged = true; + } +} + +void dlgManageFavourites::OnNewFolder(wxCommandEvent &ev) +{ + if (!trLocation->GetSelection().IsOk()) + return; + + queryFavouriteItem *item = favourites->FindTreeItem(trLocation->GetSelection()); + if (!item) + return; + if (item->GetId() != -2) + return; + + wxTextEntryDialog dlg(this, _("Enter name of new folder"), _("Create new favourites folder")); + if (dlg.ShowModal() != wxID_OK) + return; + + wxString title = dlg.GetValue().Trim(); + if (title.IsEmpty()) + return; + + queryFavouriteFolder *fld = (queryFavouriteFolder *)item; + if (fld->ContainsFolder(title)) + { + wxMessageBox(_("A folder with the specified name already exists.")); + return; + } + + + queryFavouriteFolder *newfld = fld->AddNewFolder(dlg.GetValue()); + newfld->SetTreeId(trLocation->AppendItem(trLocation->GetSelection(), title, 1)); + trLocation->Expand(fld->GetTreeId()); + anythingChanged = true; +} diff --git a/dlg/dlgManageMacros.cpp b/dlg/dlgManageMacros.cpp new file mode 100644 index 0000000..98b2194 --- /dev/null +++ b/dlg/dlgManageMacros.cpp @@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageMacros.cpp - Manage macros +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgManageMacros.h" +#include "db/pgConn.h" +#include "schema/pgServer.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSQLBox.h" +#include "utils/macros.h" + +#include + +//pointer to controls +#define lstKeys CTRL_LISTVIEW("lstKeys") +#define txtName CTRL_TEXT("txtName") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") +#define btnClear CTRL_BUTTON("btnClear") +#define btnSave CTRL_BUTTON("btnSave") + +BEGIN_EVENT_TABLE(dlgManageMacros, DialogWithHelp) + EVT_LIST_ITEM_SELECTED (XRCID("lstKeys"), dlgManageMacros::OnKeySelect) + EVT_BUTTON (wxID_OK, dlgManageMacros::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgManageMacros::OnCancel) + EVT_BUTTON (XRCID("btnClear"), dlgManageMacros::OnClear) + EVT_BUTTON (XRCID("btnSave"), dlgManageMacros::OnSave) + EVT_TEXT (XRCID("txtName"), dlgManageMacros::OnNameChange) + EVT_STC_CHANGE (XRCID("txtSqlBox"), dlgManageMacros::OnQueryChange) +END_EVENT_TABLE() + +dlgManageMacros::dlgManageMacros(wxWindow *parent, frmMain *form, queryMacroList *macros) : + DialogWithHelp(form) +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgManageMacros")); + RestorePosition(); + + this->macros = macros; + + // Setup list of keys + lstKeys->CreateColumns(NULL, _("Key"), _("Name"), 40); + + lstKeys->Hide(); + size_t i; + int num = 0; + for (i = 1; i < 13; i++) + { + wxString key; + key.Printf(wxT("Alt-F%d"), (int)i); + AddKeyToList(num++, key); + } + for (i = 1; i < 11; i++) + { + wxString key; + key.Printf(wxT("Ctrl-%d"), (int)i % 10); // in order of keys 1,2,...,8,9,0 + AddKeyToList(num++, key); + } + lstKeys->Show(); + + // Initialy no key is selected, so disable editor keys + btnClear->Disable(); + btnSave->Disable(); + + // Clear Markers + anythingChanged = false; + thisMacroChanged = false; + + txtSqlBox->SetModEventMask(wxSTC_MOD_INSERTTEXT | wxSTC_MOD_DELETETEXT); +} + +void dlgManageMacros::AddKeyToList(int position, const wxString &key) +{ + long tmp = lstKeys->InsertItem(position, key); + queryMacroItem *item = macros->FindMacro(key); + if (item != NULL) + lstKeys->SetItem(tmp, 1, item->GetName()); +} + +int dlgManageMacros::ManageMacros() +{ + int r = ShowModal(); + if (r == wxID_OK) + { + return 1; + } + else + { + if (anythingChanged) + return -1; + else + return 0; + } +} + +dlgManageMacros::~dlgManageMacros() +{ + SavePosition(); +} + +void dlgManageMacros::OnOK(wxCommandEvent &ev) +{ + if (thisMacroChanged) + SetMacro(true); + EndModal(wxID_OK); +} + +void dlgManageMacros::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgManageMacros::DeleteMacro(int listItem) +{ + wxString key; + key = lstKeys->GetItemText(listItem); + + if (macros->DelMacro(key)) + { + anythingChanged = true; + lstKeys->SetItem(listItem, 1, wxT("")); + txtName->ChangeValue(wxT("")); + txtSqlBox->SetText(wxT("")); + thisMacroChanged = false; + btnSave->Disable(); + btnClear->Disable(); + } +} + +void dlgManageMacros::OnClear(wxCommandEvent &ev) +{ + int item; + item = lstKeys->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + + if (item == -1) + return; + + DeleteMacro(item); +} + +void dlgManageMacros::OnSave(wxCommandEvent &ev) +{ + if (!thisMacroChanged) + return; + SetMacro(false); +} + +void dlgManageMacros::SetMacro(bool silent) +{ + int item; + wxString key, Name, query; + + item = lstKeys->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item == -1) + return; + + key = lstKeys->GetItemText(item); + Name = txtName->GetValue().Trim(); + query = txtSqlBox->GetText().Trim(); + + if (Name.IsEmpty() && query.IsEmpty()) + { + DeleteMacro(item); + } + else if (Name.IsEmpty() || query.IsEmpty()) + { + if (!silent) + wxMessageBox(_("You must specify a query and a name for the macro"), _("Save macro"), wxICON_EXCLAMATION | wxOK); + return; + } + else + { + macros->AddOrUpdateMacro(key, Name, query); + anythingChanged = true; + thisMacroChanged = false; + lstKeys->SetItem(item, 1, Name); + btnClear->Enable(); + btnSave->Disable(); + } +} + +void dlgManageMacros::OnKeySelect(wxListEvent &ev) +{ + wxString key; + key = ev.GetText(); + + queryMacroItem *item = macros->FindMacro(key); + if (item != NULL) + { + txtName->ChangeValue(item->GetName()); + txtSqlBox->SetText(item->GetQuery()); + btnClear->Enable(); + btnSave->Disable(); + } + else + { + txtName->ChangeValue(wxT("")); + txtSqlBox->SetText(wxT("")); + btnClear->Disable(); + btnSave->Disable(); + } + thisMacroChanged = false; +} + +void dlgManageMacros::OnNameChange(wxCommandEvent &ev) +{ + thisMacroChanged = true; + btnSave->Enable(); +} + +void dlgManageMacros::OnQueryChange(wxStyledTextEvent &ev) +{ + thisMacroChanged = true; + btnSave->Enable(); +} + +wxString dlgManageMacros::GetHelpPage() const +{ + return wxT("macros"); +} diff --git a/dlg/dlgMoveTablespace.cpp b/dlg/dlgMoveTablespace.cpp new file mode 100644 index 0000000..111d245 --- /dev/null +++ b/dlg/dlgMoveTablespace.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMoveTablespace.cpp - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" +#include "dlg/dlgMoveTablespace.h" +#include "utils/misc.h" +#include "schema/pgTablespace.h" + + +// pointer to controls +#define cbMoveTo CTRL_COMBOBOX("cbMoveTo") +#define cbKind CTRL_COMBOBOX("cbKind") +#define cbOwner CTRL_COMBOBOX("cbOwner") +#define btnOK CTRL_BUTTON("wxID_OK") + + +BEGIN_EVENT_TABLE(dlgMoveTablespace, pgDialog) + EVT_BUTTON(wxID_OK, dlgMoveTablespace::OnOK) +END_EVENT_TABLE() + + +dlgMoveTablespace::dlgMoveTablespace(frmMain *win, pgConn *conn, pgTablespace *tblspc) +{ + wxString query; + + connection = conn; + parent = win; + + SetFont(settings->GetSystemFont()); + LoadResource(win, wxT("dlgMoveTablespace")); + RestorePosition(); + + cbKind->Clear(); + cbKind->Append(_("All")); + cbKind->Append(_("Tables")); + cbKind->Append(_("Indexes")); + cbKind->Append(_("Materialized views")); + cbKind->SetSelection(0); + + cbMoveTo->Clear(); + query = wxT("SELECT spcname FROM pg_tablespace WHERE spcname<>") + conn->qtDbString(tblspc->GetName()) + wxT(" ORDER BY spcname"); + pgSetIterator tblspcs(connection, query); + while (tblspcs.RowsLeft()) + { + cbMoveTo->Append(tblspcs.GetVal(wxT("spcname"))); + } + cbMoveTo->SetSelection(0); + + cbOwner->Clear(); + cbOwner->Append(wxEmptyString); + query = wxT("SELECT rolname FROM pg_roles ORDER BY rolname"); + pgSetIterator roles(connection, query); + while (roles.RowsLeft()) + { + cbOwner->Append(roles.GetVal(wxT("rolname"))); + } + cbOwner->SetSelection(0); + cbOwner->Enable(cbOwner->GetStrings().Count() > 0); + + SetSize(330, 160); +} + +dlgMoveTablespace::~dlgMoveTablespace() +{ + SavePosition(); +} + + +void dlgMoveTablespace::OnOK(wxCommandEvent &ev) +{ + EndModal(wxID_OK); +} + + +void dlgMoveTablespace::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +wxString dlgMoveTablespace::GetTablespace() +{ + return cbMoveTo->GetValue(); +} + +wxArrayString dlgMoveTablespace::GetKind() +{ + wxArrayString kinds; + if (cbKind->GetValue().Cmp(_("Tables")) == 0) + kinds.Add(wxT("TABLE")); + else if (cbKind->GetValue().Cmp(_("Indexes")) == 0) + kinds.Add(wxT("INDEX")); + else if (cbKind->GetValue().Cmp(_("Materialized views")) == 0) + kinds.Add(wxT("MATERIALIZED VIEW")); + else + { + kinds.Add(wxT("TABLE")); + kinds.Add(wxT("INDEX")); + kinds.Add(wxT("MATERIALIZED VIEW")); + } + return kinds; +} + +wxString dlgMoveTablespace::GetOwner() +{ + return cbOwner->GetValue(); +} + diff --git a/dlg/dlgOperator.cpp b/dlg/dlgOperator.cpp new file mode 100644 index 0000000..986c47f --- /dev/null +++ b/dlg/dlgOperator.cpp @@ -0,0 +1,469 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgOperator.cpp - PostgreSQL Operator Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgOperator.h" +#include "schema/pgSchema.h" +#include "schema/pgOperator.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbLeftType CTRL_COMBOBOX2("cbLeftType") +#define cbRightType CTRL_COMBOBOX2("cbRightType") +#define cbProcedure CTRL_COMBOBOX2("cbProcedure") +#define cbRestrict CTRL_COMBOBOX("cbRestrict") +#define cbJoin CTRL_COMBOBOX("cbJoin") +#define cbCommutator CTRL_COMBOBOX("cbCommutator") +#define cbNegator CTRL_COMBOBOX("cbNegator") +#define cbLeftSort CTRL_COMBOBOX("cbLeftSort") +#define cbRightSort CTRL_COMBOBOX("cbRightSort") +#define cbLess CTRL_COMBOBOX("cbLess") +#define cbGreater CTRL_COMBOBOX("cbGreater") +#define chkCanHash CTRL_CHECKBOX("chkCanHash") +#define chkCanMerge CTRL_CHECKBOX("chkCanMerge") + + +BEGIN_EVENT_TABLE(dlgOperator, dlgTypeProperty) + EVT_TEXT(XRCID("cbLeftType"), dlgOperator::OnChangeTypeLeft) + EVT_COMBOBOX(XRCID("cbLeftType"), dlgOperator::OnChangeTypeLeft) + EVT_TEXT(XRCID("cbRightType"), dlgOperator::OnChangeTypeRight) + EVT_COMBOBOX(XRCID("cbRightType"), dlgOperator::OnChangeTypeRight) + EVT_TEXT(XRCID("cbProcedure"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbProcedure"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbLeftSort") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbLeftSort") , dlgOperator::OnChangeJoin) + EVT_TEXT(XRCID("cbRightSort") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbRightSort") , dlgOperator::OnChangeJoin) + EVT_TEXT(XRCID("cbLess") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbLess") , dlgOperator::OnChangeJoin) + EVT_TEXT(XRCID("cbGreater") , dlgOperator::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbGreater") , dlgOperator::OnChangeJoin) +END_EVENT_TABLE(); + + + +dlgProperty *pgOperatorFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgOperator(this, frame, (pgOperator *)node, (pgSchema *)parent); +} + +dlgOperator::dlgOperator(pgaFactory *f, frmMain *frame, pgOperator *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgOperator")) +{ + schema = sch; + oper = node; + + cbRestrict->Disable(); + cbJoin->Disable(); + cbCommutator->Disable(); + cbNegator->Disable(); + cbLeftSort->Disable(); + cbRightSort->Disable(); + cbLess->Disable(); + cbGreater->Disable(); + chkCanHash->Disable(); + chkCanMerge->Disable(); +} + + +pgObject *dlgOperator::GetObject() +{ + return oper; +} + + +int dlgOperator::Go(bool modal) +{ + if (oper) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + + cbLeftType->Append(oper->GetLeftType()); + cbLeftType->SetSelection(0); + + cbRightType->Append(oper->GetRightType()); + cbRightType->SetSelection(0); + + cbProcedure->Append(oper->GetOperatorFunction()); + cbProcedure->SetSelection(0); + + AddType(wxT(" "), oper->GetLeftTypeOid()); + AddType(wxT(" "), oper->GetRightTypeOid()); + + cbRestrict->Append(oper->GetRestrictFunction()); + cbRestrict->SetSelection(0); + + cbJoin->Append(oper->GetJoinFunction()); + cbJoin->SetSelection(0); + + cbCommutator->Append(oper->GetCommutator()); + cbCommutator->SetSelection(0); + + cbNegator->Append(oper->GetNegator()); + cbNegator->SetSelection(0); + + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Append(oper->GetLeftSortOperator()); + cbLeftSort->SetSelection(0); + + cbRightSort->Append(oper->GetRightSortOperator()); + cbRightSort->SetSelection(0); + + cbLess->Append(oper->GetLessOperator()); + cbLess->SetSelection(0); + + cbGreater->Append(oper->GetGreaterOperator()); + cbGreater->SetSelection(0); + } + + chkCanHash->SetValue(oper->GetHashJoins()); + chkCanMerge->SetValue(oper->GetMergeJoins()); + + + txtName->Disable(); + cbProcedure->Disable(); + cbLeftType->Disable(); + cbRightType->Disable(); + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + } + else + { + // create mode + wxArrayString incl; + incl.Add(wxT("+")); + incl.Add(wxT("-")); + incl.Add(wxT("*")); + incl.Add(wxT("/")); + incl.Add(wxT("<")); + incl.Add(wxT(">")); + incl.Add(wxT("=")); + incl.Add(wxT("~")); + incl.Add(wxT("!")); + incl.Add(wxT("@")); + incl.Add(wxT("#")); + incl.Add(wxT("%")); + incl.Add(wxT("^")); + incl.Add(wxT("&")); + incl.Add(wxT("|")); + incl.Add(wxT("`")); + incl.Add(wxT("?")); + incl.Add(wxT("$")); + + wxTextValidator validator(wxFILTER_INCLUDE_CHAR_LIST); + validator.SetIncludes(incl); + txtName->SetValidator(validator); + + AddType(wxT(" "), 0); + cbLeftType->Append(wxT(" ")); + cbRightType->Append(wxT(" ")); + FillDatatype(cbLeftType, cbRightType, false); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgOperator::CreateObject(pgCollection *collection) +{ + pgObject *obj = operatorFactory.CreateObjects(collection, 0, + wxT("\n AND op.oprname=") + qtDbString(GetName()) + + wxT("\n AND op.oprnamespace=") + schema->GetOidStr() + + wxT("\n AND op.oprleft = ") + GetTypeOid(cbLeftType->GetGuessedSelection()) + + wxT("\n AND op.oprright = ") + GetTypeOid(cbRightType->GetGuessedSelection())); + + return obj; +} + + +void dlgOperator::CheckChange() +{ + if (oper) + { + EnableOK(txtComment->GetValue() != oper->GetComment() + || cbSchema->GetValue() != oper->GetSchema()->GetName() + || cbOwner->GetValue() != oper->GetOwner()); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbLeftType->GetGuessedSelection() > 0 || cbRightType->GetGuessedSelection() > 0 , _("Please select left or right datatype.")); + CheckValid(enable, cbProcedure->GetGuessedSelection() >= 0, _("Please specify a procedure.")); + + EnableOK(enable); + } +} + + +void dlgOperator::OnChangeTypeLeft(wxCommandEvent &ev) +{ + cbLeftType->GuessSelection(ev); + CheckChangeType(); +} + +void dlgOperator::OnChangeTypeRight(wxCommandEvent &ev) +{ + cbRightType->GuessSelection(ev); + CheckChangeType(); +} + +void dlgOperator::CheckChangeType() +{ + bool binaryOp = cbLeftType->GetGuessedSelection() > 0 && cbRightType->GetGuessedSelection() > 0; + + cbRestrict->Enable(binaryOp); + cbJoin->Enable(binaryOp); + + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Enable(binaryOp); + cbRightSort->Enable(binaryOp); + cbLess->Enable(binaryOp); + cbGreater->Enable(binaryOp); + } + + chkCanHash->Enable(binaryOp); + chkCanMerge->Enable(binaryOp); + + procedures.Clear(); + + cbProcedure->Clear(); + cbJoin->Clear(); + cbRestrict->Clear(); + cbCommutator->Clear(); + cbNegator->Clear(); + + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Clear(); + cbRightSort->Clear(); + cbLess->Clear(); + cbGreater->Clear(); + } + + cbRestrict->Append(wxEmptyString); + cbJoin->Append(wxEmptyString); + if (cbRestrict->GetCurrentSelection() < 0) + cbRestrict->SetSelection(0); + if (cbJoin->GetCurrentSelection() < 0) + cbJoin->SetSelection(0); + + + if (cbLeftType->GetGuessedSelection() > 0 || cbRightType->GetGuessedSelection() > 0) + { + wxString qry = + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE pronargs = "); + + if (binaryOp) + qry += wxT("2"); + else + qry += wxT("1"); + + qry += wxT("\n AND proargtypes[0] = "); + + if (cbLeftType->GetGuessedSelection() > 0) + qry += GetTypeOid(cbLeftType->GetGuessedSelection()); + + if (binaryOp) + qry += wxT("\n AND proargtypes[1] = "); + + if (cbRightType->GetGuessedSelection() > 0) + qry += GetTypeOid(cbRightType->GetGuessedSelection()); + + + pgSet *set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + procedures.Add(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + qtIdent(set->GetVal(wxT("proname")))); + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbProcedure->Append(procname); + if (binaryOp) + { + cbJoin->Append(procname); + cbRestrict->Append(procname); + } + + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT oprname, nspname\n") + wxT(" FROM pg_operator o\n") + wxT(" JOIN pg_namespace n ON n.oid=oprnamespace\n"); + + if (cbLeftType->GetGuessedSelection() > 0) + qry += wxT(" WHERE oprleft = ") + GetTypeOid(cbLeftType->GetGuessedSelection()); + + + if (cbRightType->GetGuessedSelection() > 0) + { + if (binaryOp) + qry += wxT("\n AND oprright = "); + else + qry += wxT(" WHERE oprright = "); + qry += GetTypeOid(cbRightType->GetGuessedSelection()); + } + + cbCommutator->Append(wxT(" ")); + cbNegator->Append(wxT(" ")); + if (!connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Append(wxT(" ")); + cbRightSort->Append(wxT(" ")); + cbLess->Append(wxT(" ")); + cbGreater->Append(wxT(" ")); + } + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString opname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("oprname")); + + cbCommutator->Append(opname); + cbNegator->Append(opname); + if (binaryOp && !connection->BackendMinimumVersion(8, 3)) + { + cbLeftSort->Append(opname); + cbRightSort->Append(opname); + cbLess->Append(opname); + cbGreater->Append(opname); + } + set->MoveNext(); + } + delete set; + } + } + + CheckChange(); +} + + +void dlgOperator::OnChangeJoin(wxCommandEvent &ev) +{ + bool implicitMerges = (cbLeftSort->GetCurrentSelection() > 0 || cbRightSort->GetCurrentSelection() > 0 + || cbLess->GetCurrentSelection() > 0 || cbGreater->GetCurrentSelection() > 0); + + if (implicitMerges) + chkCanMerge->SetValue(true); + chkCanMerge->Enable(!implicitMerges); +} + + + +void dlgOperator::AppendFilledOperator(wxString &sql, const wxChar *txt, ctlComboBoxFix *cb) +{ + wxString op = cb->GetValue().Trim(); + if (!op.IsNull()) + { + sql += txt; + if (op.Find('.') > 0) + sql += wxT("OPERATOR(") + op + wxT(")"); + else + sql += op; + } +} + + +wxString dlgOperator::GetSql() +{ + wxString sql, name; + + if (oper) + { + // edit mode + name = oper->GetQuotedFullIdentifier() + + wxT("(") + oper->GetOperands() + wxT(")"); + + AppendOwnerChange(sql, wxT("OPERATOR ") + name); + AppendSchemaChange(sql, wxT("OPERATOR ") + name); + name = qtIdent(cbSchema->GetValue()) + wxT(".") + GetName() + + wxT("(") + oper->GetOperands() + wxT(")"); + } + else + { + // create mode + name = qtIdent(cbSchema->GetValue()) + wxT(".") + GetName() + wxT("("); + if (cbLeftType->GetGuessedSelection() > 0) + name += GetQuotedTypename(cbLeftType->GetGuessedSelection()); + else + name += wxT("NONE"); + name += wxT(", "); + if (cbRightType->GetGuessedSelection() > 0) + name += GetQuotedTypename(cbRightType->GetGuessedSelection()); + else + name += wxT("NONE"); + name += wxT(")"); + + + sql = wxT("CREATE OPERATOR ") + qtIdent(cbSchema->GetValue()) + wxT(".") + GetName() + + wxT("(\n PROCEDURE=") + procedures.Item(cbProcedure->GetGuessedSelection()); + + AppendIfFilled(sql, wxT(",\n LEFTARG="), GetQuotedTypename(cbLeftType->GetGuessedSelection())); + AppendIfFilled(sql, wxT(",\n RIGHTARG="), GetQuotedTypename(cbRightType->GetGuessedSelection())); + AppendIfFilled(sql, wxT(",\n COMMUTATOR="), cbCommutator->GetValue().Trim()); + AppendIfFilled(sql, wxT(",\n NEGATOR="), cbNegator->GetValue().Trim()); + + if (cbLeftType->GetGuessedSelection() > 0 && cbRightType->GetGuessedSelection() > 0) + { + if (cbRestrict->GetCurrentSelection() > 0) + sql += wxT(",\n RESTRICT=") + procedures.Item(cbRestrict->GetCurrentSelection() - 1); + if (cbJoin->GetCurrentSelection() > 0) + sql += wxT(",\n JOIN=") + procedures.Item(cbJoin->GetCurrentSelection() - 1); + + if (!connection->BackendMinimumVersion(8, 3)) + { + AppendFilledOperator(sql, wxT(",\n SORT1="), cbLeftSort); + AppendFilledOperator(sql, wxT(",\n SORT2="), cbRightSort); + AppendFilledOperator(sql, wxT(",\n LTCMP="), cbLess); + AppendFilledOperator(sql, wxT(",\n GTCMP="), cbGreater); + } + + if (chkCanMerge->GetValue() || chkCanHash->GetValue()) + { + sql += wxT(",\n "); + if (chkCanHash->GetValue()) + { + if (chkCanMerge->GetValue()) + sql += wxT("HASHES, MERGES"); + else + sql += wxT("HASHES"); + } + else if (chkCanMerge->GetValue()) + sql += wxT("MERGES"); + } + } + sql += wxT(");\n"); + AppendOwnerChange(sql, wxT("OPERATOR ") + name); + } + AppendComment(sql, wxT("OPERATOR ") + name, oper); + + return sql; +} diff --git a/dlg/dlgPackage.cpp b/dlg/dlgPackage.cpp new file mode 100644 index 0000000..dd3d4fd --- /dev/null +++ b/dlg/dlgPackage.cpp @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPackage.cpp - EnterpriseDB package Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" + +#include "dlg/dlgPackage.h" +#include "schema/edbPackage.h" + +// pointer to controls +#define txtName CTRL_TEXT("txtName") +#define txtComment CTRL_TEXT("txtComment") +#define txtHeader CTRL_SQLBOX("txtHeader") +#define txtBody CTRL_SQLBOX("txtBody") + +dlgProperty *edbPackageFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgPackage(this, frame, (edbPackage *)node, (pgSchema *)parent); +} + + +BEGIN_EVENT_TABLE(dlgPackage, dlgSecurityProperty) + EVT_STC_MODIFIED(XRCID("txtHeader"), dlgProperty::OnChangeStc) + EVT_STC_MODIFIED(XRCID("txtBody"), dlgProperty::OnChangeStc) +END_EVENT_TABLE(); + + +dlgPackage::dlgPackage(pgaFactory *f, frmMain *frame, edbPackage *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgPackage"), wxT("EXECUTE"), "X") +{ + schema = sch; + package = node; + + bool bVal; + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + if (!bVal) + { + txtHeader->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtHeader->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + + txtBody->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtBody->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + } +} + + + +pgObject *dlgPackage::GetObject() +{ + return package; +} + + +int dlgPackage::Go(bool modal) +{ + if (!connection->EdbMinimumVersion(8, 2)) + txtComment->Disable(); + + cbOwner->Disable(); + + if (package) + { + // edit mode + txtName->Disable(); + + txtHeader->SetText(package->GetHeaderInner()); + txtBody->SetText(package->GetBodyInner()); + } + else + { + // create mode + + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgPackage::CreateObject(pgCollection *collection) +{ + pgObject *obj; + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + obj = packageFactory.CreateObjects(collection, 0, + wxT(" AND nspname = ") + qtDbString(GetName())); + else + obj = packageFactory.CreateObjects(collection, 0, + wxT(" AND pkgname = ") + qtDbString(GetName())); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgPackage::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgPackage::CheckChange() +{ + bool enable = true; + + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !txtHeader->GetText().IsEmpty(), _("Please specify package header.")); + + if (package) + { + if (!(txtBody->GetText() != package->GetBodyInner() || + txtHeader->GetText() != package->GetHeaderInner())) + enable = false; + + if (txtComment->GetValue() != package->GetComment()) + enable = true; + } + + EnableOK(enable); +} + +bool dlgPackage::IsUpToDate() +{ + if (package && !package->IsUpToDate()) + return false; + else + return true; +} + + +wxString dlgPackage::GetSql() +{ + wxString sql; + wxString qtName = schema->GetQuotedSchemaPrefix(schema->GetName()) + qtIdent(txtName->GetValue()); + + if (!package || (package && txtHeader->GetText() != package->GetHeaderInner())) + { + if (package) + sql = wxT("DROP PACKAGE BODY ") + qtName + wxT(";\n\n"); + + sql += wxT("CREATE OR REPLACE PACKAGE ") + qtName + wxT("\nIS\n"); + sql += txtHeader->GetText(); + sql += wxT("\nEND ") + qtIdent(txtName->GetValue()) + wxT(";\n\n"); + } + + if (!package || (package && txtBody->GetText() != package->GetBodyInner()) + || (package && txtHeader->GetText() != package->GetHeaderInner())) + { + if (!txtBody->GetText().Trim().IsEmpty()) + { + sql += wxT("CREATE OR REPLACE PACKAGE BODY ") + qtName + wxT("\nIS\n"); + sql += txtBody->GetText().Trim().Trim(false); + sql += wxT("\nEND ") + qtIdent(txtName->GetValue()) + wxT(";\n\n"); + } + else + { + if (package && !package->GetBodyInner().Trim().IsEmpty()) + sql = wxT("DROP PACKAGE BODY ") + qtName + wxT(";\n\n"); + } + } + + sql += GetGrant(wxT("X"), wxT("PACKAGE ") + qtName); + + AppendComment(sql, wxT("PACKAGE"), schema, package); + + return sql; +} diff --git a/dlg/dlgPgpassConfig.cpp b/dlg/dlgPgpassConfig.cpp new file mode 100644 index 0000000..bbf6b91 --- /dev/null +++ b/dlg/dlgPgpassConfig.cpp @@ -0,0 +1,124 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPgpassConfig.cpp - Configure setting +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" + +#include "dlg/dlgPgpassConfig.h" +#include "db/pgConn.h" +#include "db/pgSet.h" + +// Icons +#include "images/property.pngc" + + + + + +BEGIN_EVENT_TABLE(dlgPgpassConfig, DialogWithHelp) + EVT_BUTTON (wxID_OK, dlgPgpassConfig::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgPgpassConfig::OnCancel) + EVT_CHECKBOX(XRCID("chkEnabled"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtHostname"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtPort"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtDatabase"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtUsername"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtPassword"), dlgPgpassConfig::OnChange) + EVT_TEXT(XRCID("txtRePassword"), dlgPgpassConfig::OnChange) +END_EVENT_TABLE() + + +#define chkEnabled CTRL_CHECKBOX("chkEnabled") +#define txtHostname CTRL_TEXT("txtHostname") +#define txtPort CTRL_TEXT("txtPort") +#define txtDatabase CTRL_TEXT("txtDatabase") +#define txtUsername CTRL_TEXT("txtUsername") +#define txtPassword CTRL_TEXT("txtPassword") +#define txtRePassword CTRL_TEXT("txtRePassword") + +dlgPgpassConfig::dlgPgpassConfig(pgFrame *parent, pgPassConfigLine *_line) : + DialogWithHelp((frmMain *)parent) +{ + SetFont(settings->GetSystemFont()); + LoadResource((wxWindow *)parent, wxT("dlgPgpassConfig")); + + userAdding = databaseAdding = false; + + // Icon + SetIcon(*property_png_ico); + RestorePosition(); + line = _line; + + chkEnabled->SetValue(!line->isComment); + txtHostname->SetValue(line->hostname); + txtPort->SetValue(line->port); + txtDatabase->SetValue(line->database); + txtUsername->SetValue(line->username); + txtPassword->SetValue(line->password); + txtRePassword->SetValue(line->password); + btnOK->Disable(); + +} + + +dlgPgpassConfig::~dlgPgpassConfig() +{ + SavePosition(); +} + + +wxString dlgPgpassConfig::GetHelpPage() const +{ + return wxT("pg/libpq-pgpass"); +} + + +void dlgPgpassConfig::OnChange(wxCommandEvent &ev) +{ + /* Add any required validation rules here */ + wxString passwd = txtPassword->GetValue(); + wxString repasswd = txtRePassword->GetValue(); + if (passwd.IsEmpty() || (passwd.Length() > 1)) + { + if (!passwd.compare(repasswd)) + btnOK->Enable(); + } +} + + +void dlgPgpassConfig::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + line->isComment = !chkEnabled->GetValue(); + line->hostname = txtHostname->GetValue(); + line->port = txtPort->GetValue(); + line->database = txtDatabase->GetValue(); + line->username = txtUsername->GetValue(); + line->password = txtPassword->GetValue(); + EndModal(wxID_OK); +} + + +void dlgPgpassConfig::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + + +int dlgPgpassConfig::Go() +{ + return ShowModal(); +} diff --git a/dlg/dlgProperty.cpp b/dlg/dlgProperty.cpp new file mode 100644 index 0000000..480eabe --- /dev/null +++ b/dlg/dlgProperty.cpp @@ -0,0 +1,2377 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgQuery.cpp - Property Dialog +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLBox.h" +#include "schema/pgCollection.h" +#include "schema/pgDatatype.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "ctl/ctlSecurityPanel.h" +#include "ctl/ctlDefaultSecurityPanel.h" + +// Images +#include "images/properties.pngc" + +#include "frm/frmMain.h" +#include "frm/frmHint.h" + +// Property dialogs +#include "dlg/dlgProperty.h" +#include "dlg/dlgServer.h" +#include "dlg/dlgAggregate.h" +#include "dlg/dlgColumn.h" +#include "dlg/dlgIndex.h" +#include "dlg/dlgIndexConstraint.h" +#include "dlg/dlgForeignKey.h" +#include "dlg/dlgCheck.h" +#include "dlg/dlgRule.h" +#include "dlg/dlgTrigger.h" +#include "dlg/dlgEventTrigger.h" +#include "agent/dlgJob.h" +#include "agent/dlgStep.h" +#include "agent/dlgSchedule.h" + +#include "slony/dlgRepCluster.h" +#include "slony/dlgRepNode.h" +#include "slony/dlgRepPath.h" +#include "slony/dlgRepListen.h" +#include "slony/dlgRepSet.h" +#include "slony/dlgRepSequence.h" +#include "slony/dlgRepTable.h" +#include "slony/dlgRepSubscription.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgTrigger.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "schema/pgEventTrigger.h" + +void dataType::SetOid(OID id) +{ + oid = id; +} + +void dataType::SetTypename(wxString name) +{ + typeName = name; +} + +OID dataType::GetOid() +{ + return oid; +} + +wxString dataType::GetTypename() +{ + return typeName; +} + +#define CTRLID_CHKSQLTEXTFIELD 1000 + + +BEGIN_EVENT_TABLE(dlgProperty, DialogWithHelp) + EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), dlgProperty::OnPageSelect) + + EVT_TEXT(XRCID("txtName"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbOwner"), dlgProperty::OnChangeOwner) + EVT_COMBOBOX(XRCID("cbOwner"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbSchema"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbSchema"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtComment"), dlgProperty::OnChange) + + EVT_CHECKBOX(CTRLID_CHKSQLTEXTFIELD, dlgProperty::OnChangeReadOnly) + + EVT_BUTTON(wxID_HELP, dlgProperty::OnHelp) + EVT_BUTTON(wxID_OK, dlgProperty::OnOK) +END_EVENT_TABLE(); + + +dlgProperty::dlgProperty(pgaFactory *f, frmMain *frame, const wxString &resName) : DialogWithHelp(frame) +{ + readOnly = false; + sqlPane = 0; + sqlTextField1 = 0; + sqlTextField2 = 0; + processing = false; + mainForm = frame; + database = 0; + connection = 0; + factory = f; + item = (void *)NULL; + owneritem = (void *)NULL; + chkReadOnly = (wxCheckBox *)NULL; + SetFont(settings->GetSystemFont()); + LoadResource(frame, resName); + +#ifdef __WXMSW__ + SetWindowStyleFlag(GetWindowStyleFlag() & ~wxMAXIMIZE_BOX); +#endif + + nbNotebook = CTRL_NOTEBOOK("nbNotebook"); + if (!nbNotebook) + { + wxMessageBox(wxString::Format(_("Problem with resource %s: Notebook not found.\nPrepare to crash!"), resName.c_str())); + return; + } + + // Set the icon + wxBitmap bm(factory->GetImage()); + wxIcon ico; + ico.CopyFromBitmap(bm); + SetIcon(ico); + + txtName = CTRL_TEXT("txtName"); + txtOid = CTRL_TEXT("txtOID"); + txtComment = CTRL_TEXT("txtComment"); + cbOwner = CTRL_COMBOBOX2("cbOwner"); + cbSchema = CTRL_COMBOBOX2("cbSchema"); + cbClusterSet = CTRL_COMBOBOX1("cbClusterSet"); + + wxString db = wxT("Database"); + wxString ts = wxT("Tablespace"); + wxString rg = wxT("Resource Group"); + enableSQL2 = db.Cmp(factory->GetTypeName()) == 0 + || ts.Cmp(factory->GetTypeName()) == 0 + || rg.Cmp(factory->GetTypeName()) == 0; + + wxNotebookPage *page = nbNotebook->GetPage(0); + wxASSERT(page != NULL); + page->GetClientSize(&width, &height); + + numericValidator.SetStyle(wxFILTER_NUMERIC); + btnOK->Disable(); + + statusBar = XRCCTRL(*this, "unkStatusBar", wxStatusBar); +} + + +dlgProperty::~dlgProperty() +{ + wxString prop = wxT("Properties/") + wxString(factory->GetTypeName()); + settings->WritePoint(prop, GetPosition()); + + if (GetWindowStyle() & wxRESIZE_BORDER) + settings->WriteSize(prop, GetSize()); + + if (obj) + obj->SetWindowPtr(NULL); +} + + +wxString dlgProperty::GetHelpPage() const +{ + wxString page; + + pgObject *obj = ((dlgProperty *)this)->GetObject(); + if (obj) + page = obj->GetHelpPage(false); + else + { + // Attempt to get he page from the dialogue, otherwise, take a shot at it! + page = this->GetHelpPage(true); + if (page.Length() == 0) + { + page = wxT("pg/sql-create"); + page += wxString(factory->GetTypeName()).Lower(); + } + } + + return page; +} + + +void dlgProperty::CheckValid(bool &enable, const bool condition, const wxString &msg) +{ + if (enable) + { + if (!condition) + { + if (statusBar) + statusBar->SetStatusText(msg); + enable = false; + } + } +} + + +void dlgProperty::SetDatabase(pgDatabase *db) +{ + database = db; + if (db) + connection = db->GetConnection(); +} + +void dlgProperty::SetDatatypeCache(dataTypeCache cache) +{ + dtCache = cache; +} + +void dlgProperty::EnableOK(bool enable) +{ + btnOK->Enable(enable); + if (enable) + { + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + } +} + + +void dlgProperty::SetSqlReadOnly(bool readonly) +{ + if (chkReadOnly) + chkReadOnly->Enable(!readonly); +} + + +int dlgProperty::Go(bool modal) +{ + wxASSERT(factory != 0); + + if(GetObject()) + obj = GetObject(); + else + obj = mainForm->GetBrowser()->GetObject(mainForm->GetBrowser()->GetSelection()); + + // restore previous position and size, if applicable + wxString prop = wxT("Properties/") + wxString(factory->GetTypeName()); + + wxSize origSize = GetSize(); + + if (GetWindowStyle() & wxRESIZE_BORDER) + SetSize(settings->Read(prop, GetSize())); + + wxPoint pos = settings->Read(prop, GetPosition()); + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + Move(pos); + + wxSize size = GetSize(); + CheckOnScreen(this, pos, size, origSize.GetWidth(), origSize.GetHeight()); + Move(pos); + + ctlComboBoxFix *cbowner = (ctlComboBoxFix *)cbOwner; + ctlComboBoxFix *cbschema = (ctlComboBoxFix *)cbSchema; + + if (cbClusterSet) + { + cbClusterSet->Append(wxEmptyString); + cbClusterSet->SetSelection(0); + + if (mainForm && database) + { + wxArrayString clusters = database->GetSlonyClusters(mainForm->GetBrowser()); + + size_t i; + for (i = 0 ; i < clusters.GetCount() ; i++) + { + wxString cluster = wxT("_") + clusters.Item(i); + pgSetIterator sets(connection, + wxT("SELECT set_id, ") + qtIdent(cluster) + wxT(".slonyversionmajor(), ") + qtIdent(cluster) + wxT(".slonyversionminor()\n") + wxT(" FROM ") + qtIdent(cluster) + wxT(".sl_set\n") + wxT(" WHERE set_origin = ") + qtIdent(cluster) + + wxT(".getlocalnodeid(") + qtDbString(cluster) + wxT(");")); + + while (sets.RowsLeft()) + { + wxString str; + long setId = sets.GetLong(wxT("set_id")); + long majorVer = sets.GetLong(wxT("slonyversionmajor")); + long minorVer = sets.GetLong(wxT("slonyversionminor")); + str.Printf(_("Cluster \"%s\", set %ld"), clusters.Item(i).c_str(), setId); + cbClusterSet->Append(str, static_cast(new replClientData(cluster, setId, majorVer, minorVer))); + } + } + } + if (cbClusterSet->GetCount() < 2) + cbClusterSet->Disable(); + } + + if (cbowner && !cbowner->GetCount()) + { + if (!GetObject()) + cbOwner->Append(wxEmptyString); + AddGroups(cbowner); + AddUsers(cbowner); + } + if (txtOid) + txtOid->Disable(); + + if (cbschema && !cbschema->GetCount()) + AddSchemas(cbschema); + + if (GetObject()) + { + if (txtName) + txtName->SetValue(GetObject()->GetName()); + if (txtOid) + txtOid->SetValue(NumToStr((unsigned long)GetObject()->GetOid())); + if (cbOwner) + cbOwner->SetValue(GetObject()->GetOwner()); + if (cbSchema) + cbSchema->SetValue(GetObject()->GetSchema()->GetName()); + if (txtComment) + txtComment->SetValue(GetObject()->GetComment()); + + + if (!readOnly && !GetObject()->CanCreate()) + { + // users who can't create will usually not be allowed to change either. + readOnly = false; + } + + wxString typeName = factory->GetTypeName(); + SetTitle(wxString(wxGetTranslation(typeName)) + wxT(" ") + GetObject()->GetFullIdentifier()); + if (typeName==wxT("Function")||typeName==wxT("Procedure")) { + if (nbNotebook) + nbNotebook->SetSelection(4); + } + + } + else + { + if (factory) + SetTitle(wxGetTranslation(factory->GetNewString())); + if (cbSchema) + { + if (obj->GetMetaType() == PGM_SCHEMA) + cbSchema->SetValue(obj->GetName()); + else + cbSchema->SetValue(obj->GetSchema()->GetName()); + } + } + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + if (nbNotebook) + { + wxNotebookPage *pg = nbNotebook->GetPage(0); + if (pg) + pg->SetFocus(); + } + + // This fixes a UI glitch on MacOS X and Windows + // Because of the new layout code, the Privileges pane don't size itself properly + SetSize(GetSize().GetWidth() + 1, GetSize().GetHeight()); + SetSize(GetSize().GetWidth() - 1, GetSize().GetHeight()); + + if (modal) + return ShowModal(); + else + Show(true); + + return 0; +} + + +void dlgProperty::CreateAdditionalPages() +{ + if (wxString(factory->GetTypeName()).Cmp(wxT("Server"))) + { + // create a panel + sqlPane = new wxPanel(nbNotebook); + + // add panel to the notebook + nbNotebook->AddPage(sqlPane, wxT("SQL")); + + // create a flex grid sizer + wxFlexGridSizer *fgsizer = new wxFlexGridSizer(1, 5, 5); + + // add checkbox to the panel + chkReadOnly = new wxCheckBox(sqlPane, CTRLID_CHKSQLTEXTFIELD, _("Read only")); + chkReadOnly->SetValue(true); + fgsizer->Add(chkReadOnly, 1, wxALL | wxALIGN_LEFT, 5); + + // text entry box + sqlTextField1 = new ctlSQLBox(sqlPane, CTL_PROPSQL, + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + fgsizer->Add(sqlTextField1, 1, wxALL | wxEXPAND, 5); + + // text entry box + if (enableSQL2) + { + sqlTextField2 = new ctlSQLBox(sqlPane, CTL_PROPSQL, + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_RICH2); + fgsizer->Add(sqlTextField2, 1, wxALL | wxEXPAND, 5); + } + + fgsizer->AddGrowableCol(0); + fgsizer->AddGrowableRow(1); + if (fgsizer->GetRows() > 1) + { + fgsizer->AddGrowableRow(2); + } + + sqlPane->SetAutoLayout(true); + sqlPane->SetSizer(fgsizer); + } +} + + +wxString dlgProperty::GetName() +{ + if (txtName) + { + if (GetObject()) + { + // If there is an existing object name with a leading or trailing + // space, don't try to remove it. + if (GetObject()->GetName() == txtName->GetValue()) + return txtName->GetValue(); + else + return txtName->GetValue().Strip(wxString::both); + } + else + return txtName->GetValue().Strip(wxString::both); + } + return wxEmptyString; +} + + +void dlgProperty::AppendNameChange(wxString &sql, const wxString &objName) +{ + if (GetObject()->GetName() != GetName()) + { + if (objName.Length() > 0) + { + sql += wxT("ALTER ") + objName + + wxT("\n RENAME TO ") + qtIdent(GetName()) + + wxT(";\n"); + } + else + { + sql += wxT("ALTER ") + GetObject()->GetTypeName().MakeUpper() + + wxT(" ") + GetObject()->GetQuotedFullIdentifier() + + wxT("\n RENAME TO ") + qtIdent(GetName()) + + wxT(";\n"); + } + } +} + + +void dlgProperty::AppendOwnerChange(wxString &sql, const wxString &objName) +{ + if (!GetObject() || GetObject()->GetOwner() != cbOwner->GetValue()) + { + sql += wxT("ALTER ") + objName + + wxT("\n OWNER TO ") + qtIdent(cbOwner->GetValue()) + + wxT(";\n"); + } +} + + +void dlgProperty::AppendOwnerNew(wxString &sql, const wxString &objName) +{ + if (cbOwner->GetGuessedSelection() > 0) + sql += wxT("ALTER ") + objName + + wxT("\n OWNER TO ") + qtIdent(cbOwner->GetValue()) + + wxT(";\n"); +} + + +void dlgProperty::AppendSchemaChange(wxString &sql, const wxString &objName) +{ + wxString currentschema; + + if (GetObject()->GetMetaType() == PGM_SCHEMA) + { + currentschema = GetObject()->GetName(); + } + else + { + currentschema = GetObject()->GetSchema()->GetName(); + } + + if (currentschema != cbSchema->GetValue()) + { + sql += wxT("ALTER ") + objName + + wxT("\n SET SCHEMA ") + qtIdent(cbSchema->GetValue()) + + wxT(";\n"); + } +} + + +void dlgProperty::AppendComment(wxString &sql, const wxString &objName, pgObject *obj) +{ + wxString comment = txtComment->GetValue(); + if ((!obj && !comment.IsEmpty()) || (obj && obj->GetComment() != comment)) + { + sql += wxT("COMMENT ON ") + objName + + wxT("\n IS ") + qtDbString(comment) + wxT(";\n"); + } +} + + +void dlgProperty::AppendComment(wxString &sql, const wxString &objType, pgSchema *schema, pgObject *obj) +{ + wxString comment = txtComment->GetValue(); + if ((!obj && !comment.IsEmpty()) || (obj && obj->GetComment() != comment)) + { + sql += wxT("COMMENT ON ") + objType + wxT(" "); + if (schema) + sql += schema->GetQuotedPrefix(); + sql += qtIdent(GetName()) + wxT("\n IS ") + qtDbString(comment) + wxT(";\n"); + } +} + + +void dlgProperty::AppendQuoted(wxString &sql, const wxString &name) +{ + // quick and quite dirty: + // !!! this is unsafe if the name itself contains a dot which isn't meant as separator between schema and object + if (name.First('.') >= 0) + { + sql += qtIdent(name.BeforeFirst('.')) + wxT(".") + qtIdent(name.AfterFirst('.')); + } + else + sql += qtIdent(name); +} + +void dlgProperty::AppendQuotedType(wxString &sql, const wxString &name) +{ + // see AppendQuoted() + if (name.First('.') >= 0) + { + sql += qtIdent(name.BeforeFirst('.')) + wxT(".") + qtTypeIdent(name.AfterFirst('.')); + } + else + sql += qtTypeIdent(name); +} + + +void dlgProperty::FillCombobox(const wxString &query, ctlComboBoxFix *cb1, ctlComboBoxFix *cb2) +{ + if (!cb1 && !cb2) + return; + + pgSet *set = connection->ExecuteSet(query); + if (set) + { + while (!set->Eof()) + { + if (cb1) + cb1->Append(set->GetVal(0)); + if (cb2) + cb2->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + +} + + +void dlgProperty::AddDatabases(ctlComboBoxFix *cb) +{ + FillCombobox(wxT("SELECT datname FROM pg_database ORDER BY 1"), cb); +} + + +void dlgProperty::AddUsers(ctlComboBoxFix *cb1, ctlComboBoxFix *cb2) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + FillCombobox(wxT("SELECT rolname FROM pg_roles WHERE rolcanlogin ORDER BY 1"), cb1, cb2); + } + else + { + FillCombobox(wxT("SELECT usename FROM pg_user ORDER BY 1"), cb1, cb2); + } +} + + +void dlgProperty::AddGroups(ctlComboBoxFix *combo) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + FillCombobox(wxT("SELECT rolname FROM pg_roles WHERE NOT rolcanlogin ORDER BY 1"), combo); + } + else + { + FillCombobox(wxT("SELECT groname FROM pg_group ORDER BY 1"), combo); + } +} + + +void dlgProperty::AddSchemas(ctlComboBoxFix *combo) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + FillCombobox(wxT("SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE E'pg\\\\_%' AND nspname != 'information_schema' ORDER BY nspname"), + combo); + } +} + + +void dlgProperty::PrepareTablespace(ctlComboBoxFix *cb, const OID current) +{ + wxASSERT(cb != 0); + + if (connection->BackendMinimumVersion(8, 0)) + { + // Populate the combo + cb->FillOidKey(connection, wxT("SELECT oid, spcname FROM pg_tablespace WHERE spcname <> 'pg_global' ORDER BY spcname")); + + if (current) + cb->SetKey(current); + else + { + if (database) + cb->SetValue(database->GetDefaultTablespace()); + else + { + wxString def = connection->ExecuteScalar(wxT("SELECT current_setting('default_tablespace');")); + if (def == wxEmptyString || def == wxT("unset")) + def = wxT("pg_default"); + cb->SetValue(def); + } + } + } + else + cb->Disable(); +} + + +void dlgProperty::OnChangeStc(wxStyledTextEvent &ev) +{ + CheckChange(); +} + + +void dlgProperty::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgProperty::OnChangeOwner(wxCommandEvent &ev) +{ + ctlComboBox *cb = cbOwner; + if (cb) + cb->GuessSelection(ev); + CheckChange(); +} + + +void dlgProperty::OnChangeReadOnly(wxCommandEvent &ev) +{ + size_t pos; + bool showmessage; + + showmessage = chkReadOnly->GetValue() + && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- nothing to change")) == 0) + && ! (!enableSQL2 && GetSql().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0) + && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- nothing to change")) == 0 && sqlTextField2->GetText().Length() == 0) + && ! (enableSQL2 && GetSql().Length() == 0 && GetSql2().Length() == 0 && sqlTextField1->GetText().Cmp(_("-- definition incomplete")) == 0 && sqlTextField2->GetText().Length() == 0) + && (sqlTextField1->GetText().Cmp(GetSql()) != 0 || (enableSQL2 && sqlTextField2->GetText().Cmp(GetSql2()) != 0)); + + if (showmessage) + { + if (wxMessageBox(_("Are you sure you wish to cancel your edit?"), _("SQL editor"), wxYES_NO | wxNO_DEFAULT) != wxYES) + { + chkReadOnly->SetValue(false); + return; + } + } + + sqlTextField1->SetReadOnly(chkReadOnly->GetValue()); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(chkReadOnly->GetValue()); + } + for (pos = 0; pos < nbNotebook->GetPageCount() - 1; pos++) + { + nbNotebook->GetPage(pos)->Enable(chkReadOnly->GetValue()); + } + + if (chkReadOnly->GetValue()) + { + FillSQLTextfield(); + } +} + + +void dlgProperty::FillSQLTextfield() +{ + // create a function because this is a duplicated code + sqlTextField1->SetReadOnly(false); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(false); + } + if (btnOK->IsEnabled()) + { + wxString tmp; + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data = (replClientData *)cbClusterSet->wxItemContainer::GetClientData(cbClusterSet->GetSelection()); + if(data) + tmp.Printf(_("-- Execute replicated using cluster \"%s\", set %ld\n"), data->cluster.c_str(), data->setId); + } + sqlTextField1->SetText(tmp + GetSql()); + if (enableSQL2) + { + sqlTextField2->SetText(GetSql2()); + } + } + else + { + if (GetObject()) + sqlTextField1->SetText(_("-- nothing to change")); + else + sqlTextField1->SetText(_("-- definition incomplete")); + if (enableSQL2) + { + sqlTextField2->SetText(wxT("")); + } + } + sqlTextField1->SetReadOnly(true); + if (enableSQL2) + { + sqlTextField2->SetReadOnly(true); + } +} + + +bool dlgProperty::tryUpdate(wxTreeItemId collectionItem) +{ + ctlTree *browser = mainForm->GetBrowser(); + pgCollection *collection = (pgCollection *)browser->GetObject(collectionItem); + if (collection && collection->IsCollection() && factory->GetCollectionFactory() == collection->GetFactory()) + { + pgObject *data = CreateObject(collection); + if (data) + { + + wxString nodeName = this->GetDisplayName(); + if (nodeName.IsEmpty()) + nodeName = data->GetDisplayName(); + + size_t pos = 0; + wxTreeItemId newItem; + + if (!data->IsCreatedBy(columnFactory)) + { + // columns should be appended, not inserted alphabetically + + wxCookieType cookie; + newItem = browser->GetFirstChild(collectionItem, cookie); + while (newItem) + { + if (browser->GetItemText(newItem) > nodeName) + break; + pos++; + newItem = browser->GetNextChild(collectionItem, cookie); + } + } + + if (newItem) + browser->InsertItem(collectionItem, pos, nodeName, data->GetIconId(), -1, data); + else + browser->AppendItem(collectionItem, nodeName, data->GetIconId(), -1, data); + + if (data->WantDummyChild()) + browser->AppendItem(data->GetId(), wxT("Dummy")); + + if (browser->GetSelection() == item) + collection->ShowTreeDetail(browser, 0, mainForm->GetProperties()); + else + collection->UpdateChildCount(browser); + } + else + { + // CreateObject didn't return a new pgObject; refresh the complete collection + mainForm->Refresh(collection); + } + return true; + } + return false; +} + + + +void dlgProperty::ShowObject() +{ + mainForm->ObjectBrowserRefreshing(true); + pgObject *data = GetObject(); + + // We might have a parent to refresh. If so, the children will + // inherently get refreshed as well. Yay :-) + if (owneritem) + { + // Get the object node in case we need it later + wxTreeItemId objectnode = mainForm->GetBrowser()->GetItemParent(owneritem); + + // Stash the selected items path + wxString currentPath = mainForm->GetCurrentNodePath(); + + pgObject *tblobj = mainForm->GetBrowser()->GetObject(owneritem); + + if (tblobj) + { + dlgProperty *ownDialog = NULL; + if (data) + { + ownDialog = data->GetWindowPtr(); + data->SetWindowPtr(NULL); + } + mainForm->Refresh(tblobj); + if (data) + { + data->SetWindowPtr(ownDialog); + } + } + + // Restore the previous selection... + mainForm->SetCurrentNode(mainForm->GetBrowser()->GetRootItem(), currentPath); + } + else if (data) + { + pgObject *newData = data->Refresh(mainForm->GetBrowser(), item); + if (newData && newData != data) + { + mainForm->SetCurrentObject(newData); + mainForm->GetBrowser()->SetItemData(item, newData); + + newData->SetId(item); + delete data; + SetObject(newData); + + newData->UpdateIcon(mainForm->GetBrowser()); + } + if (newData) + { + mainForm->GetBrowser()->DeleteChildren(newData->GetId()); + + if (item == mainForm->GetBrowser()->GetSelection()) + newData->ShowTree(mainForm, mainForm->GetBrowser(), mainForm->GetProperties(), 0); + mainForm->GetBrowser()->SetItemText(item, newData->GetFullName()); + mainForm->GetSqlPane()->SetReadOnly(false); + mainForm->GetSqlPane()->SetText(newData->GetSql(mainForm->GetBrowser())); + mainForm->GetSqlPane()->SetReadOnly(true); + } + } + else if (item && chkReadOnly->GetValue()) + { + wxTreeItemId collectionItem = item; + + while (collectionItem) + { + // search up the tree for our collection + if (tryUpdate(collectionItem)) + break; + collectionItem = mainForm->GetBrowser()->GetItemParent(collectionItem); + } + } + else // Brute force update the current item + { + pgObject *currobj = mainForm->GetBrowser()->GetObject(mainForm->GetBrowser()->GetSelection()); + + if (currobj) + mainForm->Refresh(currobj); + } + mainForm->ObjectBrowserRefreshing(false); +} + + +bool dlgProperty::apply(const wxString &sql, const wxString &sql2) +{ + wxString tmp; + pgConn *myConn = connection; + + if (GetDisconnectFirst()) + { + myConn = database->GetServer()->GetConnection(); + database->Disconnect(); + } + + if (!sql.IsEmpty()) + { + wxArrayString queries; + + if (WannaSplitQueries()) + queries = SplitQueries(BuildSql(sql)); + else + queries.Add(BuildSql(sql)); + + for (size_t index = 0; index < queries.GetCount(); index++) + { + tmp = queries.Item(index); + if (!myConn->ExecuteVoid(tmp)) + { + // error message is displayed inside ExecuteVoid + return false; + } + + if (database) + database->AppendSchemaChange(tmp); + } + } + + // Process the second SQL statement. This is primarily only used by + // CREATE DATABASE which cannot be run in a multi-statement query in + // PostgreSQL 8.3+ + if (!sql2.IsEmpty()) + { + tmp = BuildSql(sql2); + + if (!myConn->ExecuteVoid(tmp)) + { + // error message is displayed inside ExecuteVoid + // Warn the user about partially applied changes, but don't bail out. + // Carry on as if everything was successful (because the most important + // change was!! + wxMessageBox(_("An error occurred executing the second stage SQL statement.\n\nChanges may have been partially applied."), _("Warning"), wxICON_EXCLAMATION | wxOK, this); + } + else // Only apend schema changes if there was no error. + { + if (database) + database->AppendSchemaChange(tmp); + } + } + + ShowObject(); + + return true; +} + + +wxString dlgProperty::BuildSql(const wxString &sql) +{ + wxString tmp; + + if (cbClusterSet && cbClusterSet->GetSelection() > 0) + { + replClientData *data = (replClientData *)cbClusterSet->wxItemContainer::GetClientData(cbClusterSet->GetSelection()); + if (data) + { + if (data->majorVer > 1 || (data->majorVer == 1 && data->minorVer >= 2)) + { + // From slony version 2.2.0 onwards ddlscript_prepare() method is removed and + // ddlscript_complete() method arguments got changed so we have to use ddlcapture() method + // instead of ddlscript_prepare() and changed the argument of ddlscript_complete() method + if ((data->majorVer == 2 && data->minorVer >= 2) || (data->majorVer > 2)) + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlcapture(") + qtDbString(sql) + wxT(", ") + wxT("NULL::text") + wxT(" );\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + wxT("NULL::text") + wxT(" );\n"); + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_prepare(") + NumToStr(data->setId) + wxT(", -1);\n") + + sql + wxT(";\n") + + wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript_complete(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(sql) + wxT(", -1);\n"); + } + } + else + { + tmp = wxT("SELECT ") + qtIdent(data->cluster) + + wxT(".ddlscript(") + NumToStr(data->setId) + wxT(", ") + + qtDbString(sql) + wxT(", 0);\n"); + } + } + } + else + tmp = sql; + + return tmp; +} + + +wxArrayString dlgProperty::SplitQueries(const wxString &sql) +{ + wxArrayString queries; + wxString query; + wxString c; + + bool antislash = false; + bool quote_string = false; + bool doublequote_string = false; + + for (size_t item = 0; item < sql.Length(); item++) + { + c = sql.GetChar(item); + + if (c == wxT("\\")) + antislash = true; + + if (c == wxT("'")) + { + if (antislash) + antislash = false; + else if (quote_string) + quote_string = false; + else if (!doublequote_string) + quote_string = true; + } + + if (c == wxT("\"")) + { + if (antislash) + antislash = false; + else if (doublequote_string) + doublequote_string = false; + else if (!quote_string) + doublequote_string = true; + } + + query = query + c; + + if (c == wxT(";") && !antislash && !quote_string && !doublequote_string) + { + queries.Add(query); + query = wxEmptyString; + } + } + + return queries; +} + + +void dlgProperty::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) != wxYES) + return; + } + + EnableOK(false); + + if (IsModal()) + { + EndModal(0); + return; + } + + wxString sql; + wxString sql2; + if (chkReadOnly->GetValue()) + { + sql = GetSql(); + sql2 = GetSql2(); + } + else + { + sql = sqlTextField1->GetText(); + if (enableSQL2) + { + sql2 = sqlTextField2->GetText(); + } + else + { + sql2 = wxT(""); + } + } + + if (!apply(sql, sql2)) + { + EnableOK(true); + return; + } + + Destroy(); +} + + +void dlgProperty::OnPageSelect(wxNotebookEvent &event) +{ + if (sqlTextField1 && chkReadOnly->GetValue() && + event.GetSelection() == (int)nbNotebook->GetPageCount() - 1) + { + FillSQLTextfield(); + } +} + + + +void dlgProperty::InitDialog(frmMain *frame, pgObject *node) +{ + CenterOnParent(); + if (!connection) + connection = node->GetConnection(); + database = node->GetDatabase(); + + if (factory != node->GetFactory() && !node->IsCollection()) + { + wxCookieType cookie; + wxTreeItemId collectionItem = frame->GetBrowser()->GetFirstChild(node->GetId(), cookie); + while (collectionItem) + { + pgCollection *collection = (pgCollection *)frame->GetBrowser()->GetObject(collectionItem); + if (collection && collection->IsCollection() && collection->IsCollectionFor(node)) + break; + + collectionItem = frame->GetBrowser()->GetNextChild(node->GetId(), cookie); + } + item = collectionItem; + } + else + item = node->GetId(); + + // Additional hacks to get the table to refresh when modifying sub-objects + if (!item && (node->GetMetaType() == PGM_TABLE || node->GetMetaType() == PGM_VIEW + || node->GetMetaType() == GP_PARTITION || node->GetMetaType() == PGM_DOMAIN)) + owneritem = node->GetId(); + + int metatype = node->GetMetaType(); + + switch (metatype) + { + case PGM_COLUMN: + owneritem = node->GetTable()->GetId(); + break; + + case PGM_CHECK: + case PGM_FOREIGNKEY: + case PGM_CONSTRAINT: + case PGM_EXCLUDE: + case PGM_INDEX: + case PGM_PRIMARYKEY: + case PGM_UNIQUE: + case PGM_TRIGGER: + case PGM_RULE: // Rules are technically table objects! Yeuch + case EDB_PACKAGEFUNCTION: + case EDB_PACKAGEVARIABLE: + case PGM_SCHEDULE: + case PGM_STEP: + if (node->IsCollection()) + owneritem = frame->GetBrowser()->GetParentObject(node->GetId())->GetId(); + else + owneritem = frame->GetBrowser()->GetParentObject(frame->GetBrowser()->GetParentObject(node->GetId())->GetId())->GetId(); + break; + + default: + // we want to do this as objects can change schema + owneritem = node->GetId(); + break; + } +} + + +dlgProperty *dlgProperty::CreateDlg(frmMain *frame, pgObject *node, bool asNew, pgaFactory *factory) +{ + if (!factory) + { + factory = node->GetFactory(); + if (node->IsCollection()) + factory = ((pgaCollectionFactory *)factory)->GetItemFactory(); + } + + pgObject *currentNode, *parentNode; + if (asNew) + currentNode = 0; + else + currentNode = node; + + if (factory != node->GetFactory()) + parentNode = node; + else + parentNode = frame->GetBrowser()->GetObject( + frame->GetBrowser()->GetItemParent(node->GetId())); + + if (parentNode && parentNode->IsCollection() && parentNode->GetMetaType() != PGM_SERVER) + parentNode = frame->GetBrowser()->GetObject( + frame->GetBrowser()->GetItemParent(parentNode->GetId())); + + dlgProperty *dlg = 0; + + if (factory) + { + dlg = factory->CreateDialog(frame, currentNode, parentNode); + if (dlg) + { + if (factory->IsCollection()) + factory = ((pgaCollectionFactory *)factory)->GetItemFactory(); + wxASSERT(factory); + + dlg->InitDialog(frame, node); + + if (currentNode) + currentNode->SetWindowPtr(dlg); + } + } + return dlg; +} + + +bool dlgProperty::CreateObjectDialog(frmMain *frame, pgObject *node, pgaFactory *factory) +{ + if (node->GetMetaType() != PGM_SERVER) + { + pgConn *conn = node->GetConnection(); + if (!conn || conn->GetStatus() != PGCONN_OK || !conn->IsAlive()) + return false; + } + + dlgProperty *dlg = NULL; + + if (node) + dlg = node->GetWindowPtr(); + + if (dlg) + dlg->Raise(); + else + { + dlg = CreateDlg(frame, node, true, factory); + + if (dlg) + { + dlg->SetTitle(wxGetTranslation(dlg->factory->GetNewString())); + + dlg->CreateAdditionalPages(); + dlg->Go(); + dlg->CheckChange(); + } + else + wxMessageBox(_("Not implemented.")); + } + + return true; +} + + +bool dlgProperty::EditObjectDialog(frmMain *frame, ctlSQLBox *sqlbox, pgObject *node) +{ + if (node->GetMetaType() != PGM_SERVER) + { + pgConn *conn = node->GetConnection(); + if (!conn || conn->GetStatus() != PGCONN_OK || !conn->IsAlive()) + return false; + } + + // If this is a function or view, hint that the user might want to edit the object in + // the query tool. + if (node->GetMetaType() == PGM_FUNCTION || node->GetMetaType() == PGM_VIEW) + { + if (frmHint::ShowHint(frame, HINT_OBJECT_EDITING) == wxID_CANCEL) + return false; + } + + dlgProperty *dlg = NULL; + + if (node) + dlg = node->GetWindowPtr(); + + if (dlg) + dlg->Raise(); + else + { + dlg = CreateDlg(frame, node, false); + + if (dlg) + { + wxString typeName = dlg->factory->GetTypeName(); + dlg->SetTitle(wxString(wxGetTranslation(typeName)) + wxT(" ") + node->GetFullIdentifier()); + + dlg->CreateAdditionalPages(); + dlg->Go(); + + dlg->CheckChange(); + } + else + wxMessageBox(_("Not implemented.")); + } + + return true; +} + +wxString dlgProperty::qtDbString(const wxString &str) +{ + // Use the server aware version if possible + if (connection) + return connection->qtDbString(str); + else if (database) + return database->GetConnection()->qtDbString(str); + else + { + wxString ret = str; + ret.Replace(wxT("\\"), wxT("\\\\")); + ret.Replace(wxT("'"), wxT("''")); + ret.Append(wxT("'")); + ret.Prepend(wxT("'")); + return ret; + } +} + +void dlgProperty::OnHelp(wxCommandEvent &ev) +{ + wxString page = GetHelpPage(); + + if (!page.IsEmpty()) + { + if (page.StartsWith(wxT("pg/"))) + { + if (connection) + { + if (connection->GetIsEdb()) + DisplayHelp(page.Mid(3), HELP_ENTERPRISEDB); + else if (connection->GetIsGreenplum()) + DisplayHelp(page.Mid(3), HELP_GREENPLUM); + else + DisplayHelp(page.Mid(3), HELP_POSTGRESQL); + } + else + DisplayHelp(page.Mid(3), HELP_POSTGRESQL); + } + else if (page.StartsWith(wxT("slony/"))) + DisplayHelp(page.Mid(6), HELP_SLONY); + else + DisplayHelp(page, HELP_PGADMIN); + } +} + +///////////////////////////////////////////////////////////////////////////// + + +dlgTypeProperty::dlgTypeProperty(pgaFactory *f, frmMain *frame, const wxString &resName) + : dlgProperty(f, frame, resName) +{ + isVarLen = false; + isVarPrec = false; + if (wxWindow::FindWindow(XRCID("txtLength"))) + { + txtLength = CTRL_TEXT("txtLength"); + txtLength->SetValidator(numericValidator); + txtLength->Disable(); + } + else + txtLength = 0; + if (wxWindow::FindWindow(XRCID("txtPrecision"))) + { + txtPrecision = CTRL_TEXT("txtPrecision"); + txtPrecision->SetValidator(numericValidator); + txtPrecision->Disable(); + } + else + txtPrecision = 0; +} + + +void dlgTypeProperty::FillDatatype(ctlComboBox *cb, bool withDomains, bool addSerials) +{ + FillDatatype(cb, 0, withDomains, addSerials); +} + +void dlgTypeProperty::FillDatatype(ctlComboBox *cb, ctlComboBox *cb2, bool withDomains, bool addSerials) +{ + + if (dtCache.IsEmpty()) + { + // A column dialog is directly called, no datatype caching is done. + // Fetching datatypes from server. + DatatypeReader tr(database, withDomains, addSerials); + while (tr.HasMore()) + { + pgDatatype dt = tr.GetDatatype(); + + AddType(wxT("?"), tr.GetOid(), dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + cb->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + if (cb2) + cb2->Append(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + tr.MoveNext(); + } + } + else + { + // A column dialog is called from a table dialog where we have already cached the datatypes. + // Using cached datatypes. + size_t i; + for (i = 0; i < dtCache.GetCount(); i++) + { + AddType(wxT("?"), dtCache.Item(i)->GetOid(), dtCache.Item(i)->GetTypename()); + cb->Append(dtCache.Item(i)->GetTypename()); + if (cb2) + cb2->Append(dtCache.Item(i)->GetTypename()); + } + } + +} + + +int dlgTypeProperty::Go(bool modal) +{ + if (GetObject()) + { + if (txtLength) + txtLength->SetValidator(numericValidator); + if (txtPrecision) + txtPrecision->SetValidator(numericValidator); + } + return dlgProperty::Go(modal); +} + + + +void dlgTypeProperty::AddType(const wxString &typ, const OID oid, const wxString quotedName) +{ + wxString vartyp; + if (typ == wxT("?")) + { + switch ((long)oid) + { + case PGOID_TYPE_BIT: + case PGOID_TYPE_BIT_ARRAY: + case PGOID_TYPE_VARBIT: + case PGOID_TYPE_VARBIT_ARRAY: + case PGOID_TYPE_BPCHAR: + case PGOID_TYPE_BPCHAR_ARRAY: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_VARCHAR_ARRAY: + vartyp = wxT("L"); + break; + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIME_ARRAY: + case PGOID_TYPE_TIMETZ: + case PGOID_TYPE_TIMETZ_ARRAY: + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIMESTAMP_ARRAY: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_TIMESTAMPTZ_ARRAY: + case PGOID_TYPE_INTERVAL: + case PGOID_TYPE_INTERVAL_ARRAY: + vartyp = wxT("D"); + break; + case PGOID_TYPE_NUMERIC: + case PGOID_TYPE_NUMERIC_ARRAY: + vartyp = wxT("P"); + break; + default: + vartyp = wxT(" "); + break; + } + } + else + vartyp = typ; + + types.Add(vartyp + NumToStr(oid) + wxT(":") + quotedName); +} + + +wxString dlgTypeProperty::GetTypeInfo(int sel) +{ + wxString str; + if (sel >= 0) + str = types.Item(sel); + + return str; +} + + +wxString dlgTypeProperty::GetTypeOid(int sel) +{ + wxString str; + if (sel >= 0) + str = types.Item(sel).Mid(1).BeforeFirst(':'); + + return str; +} + + +wxString dlgTypeProperty::GetQuotedTypename(int sel) +{ + wxString sql, suffix; + bool isArray = false; + + if (sel >= 0) + { + sql = types.Item(sel).AfterFirst(':'); + + // Deal with time/timestamp first as they're special cases + if (sql.Left(19) == wxT("time with time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("time"); + suffix = wxT("with time zone"); + } + else if (sql.Left(21) == wxT("time without time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("time"); + suffix = wxT("without time zone"); + } + else if (sql.Left(24) == wxT("timestamp with time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("timestamp"); + suffix = wxT("with time zone"); + } + else if (sql.Left(27) == wxT("timestamp without time zone")) + { + if (sql.Right(2) == wxT("[]")) + isArray = true; + sql = wxT("timestamp"); + suffix = wxT("without time zone"); + } + else if (sql.Right(2) == wxT("[]")) + { + sql = sql.SubString(0, sql.Len() - 3); + isArray = true; + } + else if (sql.Right(3) == wxT("[]\"")) + { + sql = sql.SubString(1, sql.Len() - 4); + isArray = true; + } + + // Stick the length on + if (isVarLen && txtLength) + { + wxString varlen = txtLength->GetValue(); + if (!varlen.IsEmpty() && NumToStr(StrToLong(varlen)) == varlen && StrToLong(varlen) >= minVarLen) + { + sql += wxT("(") + varlen; + if (isVarPrec && txtPrecision) + { + wxString varprec = txtPrecision->GetValue(); + if (!varprec.IsEmpty()) + sql += wxT(",") + varprec; + } + sql += wxT(")"); + } + } + } + + // Append any post-length suffix + if (suffix.length()) + sql += wxT(" ") + suffix; + + // Append any array decoration + if (isArray) + sql += wxT("[]"); + + return sql; +} + + +void dlgTypeProperty::CheckLenEnable() +{ + int sel = cbDatatype->GetGuessedSelection(); + if (sel >= 0) + { + wxString info = types.Item(sel); + isVarPrec = info.StartsWith(wxT("P")); + isVarLen = isVarPrec || info.StartsWith(wxT("L")) || info.StartsWith(wxT("D")); + minVarLen = (info.StartsWith(wxT("D")) ? 0 : 1); + maxVarLen = isVarPrec ? 1000 : + minVarLen ? 0x7fffffff : 10; + } +} + + +///////////////////////////////////////////////////////////////////////////// + + +dlgCollistProperty::dlgCollistProperty(pgaFactory *f, frmMain *frame, const wxString &resName, pgTable *parentNode) + : dlgProperty(f, frame, resName) +{ + columns = 0; + table = parentNode; +} + + +dlgCollistProperty::dlgCollistProperty(pgaFactory *f, frmMain *frame, const wxString &resName, ctlListView *colList) + : dlgProperty(f, frame, resName) +{ + columns = colList; + table = 0; +} + + +int dlgCollistProperty::Go(bool modal) +{ + if (columns) + { + int pos; + // iterate cols + for (pos = 0 ; pos < columns->GetItemCount() ; pos++) + { + wxString col = columns->GetItemText(pos); + if (cbColumns->FindString(col) < 0) + { + cbColumns->Append(col, StrToOid(columns->GetText(pos, 7))); + } + } + } + if (table) + { + wxCookieType cookie; + pgObject *data; + wxTreeItemId columnsItem = mainForm->GetBrowser()->GetFirstChild(table->GetId(), cookie); + while (columnsItem) + { + data = mainForm->GetBrowser()->GetObject(columnsItem); + if (data->GetMetaType() == PGM_COLUMN && data->IsCollection()) + break; + columnsItem = mainForm->GetBrowser()->GetNextChild(table->GetId(), cookie); + } + + if (columnsItem) + { + wxCookieType cookie; + pgColumn *column; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(columnsItem, cookie); + + // check columns + while (item) + { + column = (pgColumn *)mainForm->GetBrowser()->GetObject(item); + if (column->IsCreatedBy(columnFactory)) + { + if (column->GetColNumber() > 0) + { + cbColumns->Append(column->GetName(), column->GetAttTypId()); + } + } + + item = mainForm->GetBrowser()->GetNextChild(columnsItem, cookie); + } + } + } + + return dlgProperty::Go(modal); +} + + + +///////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(dlgSecurityProperty, dlgProperty) + EVT_BUTTON(CTL_ADDPRIV, dlgSecurityProperty::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgSecurityProperty::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgSecurityProperty::OnChangeSize) +#endif +END_EVENT_TABLE(); + +void dlgSecurityProperty::SetPrivilegesLayout() +{ + securityPage->lbPrivileges->GetParent()->Layout(); +} + +dlgSecurityProperty::dlgSecurityProperty(pgaFactory *f, frmMain *frame, pgObject *obj, const wxString &resName, const wxString &privList, const char *privChar) + : dlgProperty(f, frame, resName) +{ + securityChanged = false; + + + if (!privList.IsEmpty() && (!obj || obj->CanCreate())) + { + securityPage = new ctlSecurityPanel(nbNotebook, privList, privChar, frame->GetImageList()); + + if (obj) + { + + wxArrayString groups; + // Fetch Groups Information + pgSet *setGrp = obj->GetConnection()->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + wxString str = obj->GetAcl(); + if (!str.IsEmpty()) + { + str = str.Mid(1, str.Length() - 2); + wxStringTokenizer tokens(str, wxT(",")); + + while (tokens.HasMoreTokens()) + { + wxString str = tokens.GetNextToken(); + if (str[0U] == '"') + str = str.Mid(1, str.Length() - 2); + + wxString name = str.BeforeLast('='); + wxString value; + + connection = obj->GetConnection(); + if (connection->BackendMinimumVersion(7, 4)) + value = str.Mid(name.Length() + 1).BeforeLast('/'); + else + value = str.Mid(name.Length() + 1); + + int icon = userFactory.GetIconId(); + + if (name.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + name = wxT("group ") + qtStrip(name.Mid(6)); + } + else if (name.IsEmpty()) + { + icon = PGICON_PUBLIC; + name = wxT("public"); + } + else + { + name = qtStrip(name); + for (unsigned int index = 0; index < groups.Count(); index++) + if (name == groups[index]) + { + name = wxT("group ") + name; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, name, value); + currentAcl.Add(name + wxT("=") + value); + } + } + else + { + int icon = PGICON_PUBLIC; + wxString name = wxT("public"); + wxString value; + if (obj->GetMetaType() == PGM_DATABASE) + value = wxT("Tc"); + else if (obj->GetMetaType() == PGM_FUNCTION) + value = wxT("X"); + else if (obj->GetMetaType() == PGM_LANGUAGE) + value = wxT("U"); + + if (value != wxEmptyString) + { + securityPage->lbPrivileges->AppendItem(icon, name, value); + currentAcl.Add(name + wxT("=") + value); + } + } + } + } + else + securityPage = NULL; +} + + +dlgSecurityProperty::~dlgSecurityProperty() +{ +} + + + +#ifdef __WXMAC__ +void dlgSecurityProperty::OnChangeSize(wxSizeEvent &ev) +{ + if (securityPage) + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgSecurityProperty::Go(bool modal) +{ + if (securityPage) + { + if (cbOwner && !cbOwner->GetCount()) + { + if (!GetObject()) + cbOwner->Append(wxEmptyString); + AddGroups(cbOwner); + AddUsers(cbOwner); + } + + securityPage->SetConnection(connection); + //securityPage->Layout(); + } + + return dlgProperty::Go(modal); +} + + +void dlgSecurityProperty::AddGroups(ctlComboBox *comboBox) +{ + if (!((securityPage && securityPage->cbGroups) || comboBox)) + return; + + pgSet *set = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + if (comboBox) + comboBox->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } +} + + +void dlgSecurityProperty::AddUsers(ctlComboBox *combobox) +{ + if (securityPage && securityPage->cbGroups && settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups, combobox); + Layout(); + } + else + dlgProperty::AddUsers(combobox); +} + + +void dlgSecurityProperty::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + + +void dlgSecurityProperty::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + + +wxString dlgSecurityProperty::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == (int)nbNotebook->GetPageCount() - 2) + return wxT("pg/sql-grant"); + else + return dlgProperty::GetHelpPage(); +} + + +void dlgSecurityProperty::EnableOK(bool enable, bool ignoreSql) +{ + // Don't enable the OK button if the object isn't yet created, + // leave that to the object dialog. + if (securityChanged && GetObject() && !ignoreSql) + { + wxString sql = GetSql(); + if (sql.IsEmpty()) + { + enable = false; + securityChanged = false; + } + else + enable = true; + } + dlgProperty::EnableOK(enable); +} + + +wxString dlgSecurityProperty::GetGrant(const wxString &allPattern, const wxString &grantObject) +{ + if (securityPage) + return securityPage->GetGrant(allPattern, grantObject, ¤tAcl); + else + return wxString(); +} + +bool dlgSecurityProperty::DisablePrivilege(const wxString &priv) +{ + if (securityPage) + return securityPage->DisablePrivilege(priv); + else + return true; +} + +void dlgSecurityProperty::AppendCurrentAcl(const wxString &name, const wxString &value) +{ + if (!(name.IsEmpty() && value.IsEmpty())) + currentAcl.Add(name + wxT("=") + value); +} + + +///////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(dlgDefaultSecurityProperty, dlgSecurityProperty) + EVT_BUTTON(CTL_DEFADDPRIV, dlgDefaultSecurityProperty::OnAddPriv) + EVT_BUTTON(CTL_DEFDELPRIV, dlgDefaultSecurityProperty::OnDelPriv) +#ifdef __WXMAC__ + EVT_SIZE( dlgDefaultSecurityProperty::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgDefaultSecurityProperty::dlgDefaultSecurityProperty(pgaFactory *f, frmMain *frame, pgObject *obj, const wxString &resName, const wxString &privList, const char *privChar, bool createDefPrivPanel) + : dlgSecurityProperty(f, frame, obj, resName, privList, privChar), defaultSecurityChanged(false) +{ + pgConn *l_conn = obj ? obj->GetConnection() : connection; + if ((!obj || obj->CanCreate()) && createDefPrivPanel) + defaultSecurityPage = new ctlDefaultSecurityPanel(l_conn, nbNotebook, frame->GetImageList()); + else + defaultSecurityPage = NULL; +} + + +void dlgDefaultSecurityProperty::AddGroups(ctlComboBox *comboBox) +{ + if (!((securityPage && securityPage->cbGroups) || comboBox || defaultSecurityPage)) + return; + + pgSet *set = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + + if (comboBox) + comboBox->Append(set->GetVal(0)); + + if (defaultSecurityPage) + defaultSecurityPage->m_groups.Add(wxT("group ") + set->GetVal(0)); + + set->MoveNext(); + } + delete set; + } +} + + +void dlgDefaultSecurityProperty::AddUsers(ctlComboBox *combobox) +{ + if ((securityPage && securityPage->cbGroups) || defaultSecurityPage || combobox) + { + wxString strFetchUserQuery = + connection->BackendMinimumVersion(8, 1) ? + wxT("SELECT rolname FROM pg_roles WHERE rolcanlogin ORDER BY 1") : + wxT("SELECT usename FROM pg_user ORDER BY 1"); + + pgSet *set = connection->ExecuteSet(strFetchUserQuery); + if (set) + { + while (!set->Eof()) + { + if (settings->GetShowUsersForPrivileges()) + { + if (securityPage && securityPage->cbGroups) + securityPage->cbGroups->Append(set->GetVal(0)); + + if (defaultSecurityPage) + defaultSecurityPage->m_groups.Add(set->GetVal(0)); + } + + if (combobox) + combobox->Append(set->GetVal(0)); + + set->MoveNext(); + } + delete set; + } + } +} + +#ifdef __WXMAC__ +void dlgDefaultSecurityProperty::OnChangeSize(wxSizeEvent &ev) +{ + wxSize l_size = ev.GetSize(); + if (defaultSecurityPage && l_size.GetWidth() > 10 && l_size.GetHeight() > 25) + defaultSecurityPage->SetSize(l_size.GetWidth() - 10, l_size.GetHeight() - 25); + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgDefaultSecurityProperty::EnableOK(bool enable, bool ignoreSql) +{ + // Don't enable the OK button if the object isn't yet created, + // leave that to the object dialog. + if (GetObject() && !ignoreSql) + { + wxString sql = GetSql(); + if (sql.IsEmpty()) + { + enable = false; + } + else + enable = true; + } + dlgSecurityProperty::EnableOK(enable, ignoreSql); +} + + +void dlgDefaultSecurityProperty::OnAddPriv(wxCommandEvent &ev) +{ + defaultSecurityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + + +void dlgDefaultSecurityProperty::OnDelPriv(wxCommandEvent &ev) +{ + defaultSecurityChanged = true; + EnableOK(btnOK->IsEnabled()); +} + +wxString dlgDefaultSecurityProperty::GetDefaultPrivileges(const wxString &schemaName) +{ + if (defaultSecurityChanged) + return defaultSecurityPage->GetDefaultPrivileges(schemaName); + return wxT(""); +} + +int dlgDefaultSecurityProperty::Go(bool modal, bool createDefPrivs, const wxString &defPrivsOnTables, + const wxString &defPrivsOnSeqs, const wxString &defPrivsOnFuncs, + const wxString &defPrivsOnTypes) +{ + if (securityPage) + { + if (cbOwner && !cbOwner->GetCount()) + { + if (!GetObject()) + cbOwner->Append(wxEmptyString); + AddGroups(cbOwner); + AddUsers(cbOwner); + } + + securityPage->SetConnection(connection); + //securityPage->Layout(); + } + + int res = dlgSecurityProperty::Go(modal); + + if (defaultSecurityPage) + { + if (createDefPrivs && connection->BackendMinimumVersion(9, 0)) + defaultSecurityPage->UpdatePrivilegePages(createDefPrivs, defPrivsOnTables, + defPrivsOnSeqs, defPrivsOnFuncs, defPrivsOnTypes); + else + defaultSecurityPage->Enable(false); + } + + return res; +} + +wxString dlgDefaultSecurityProperty::GetHelpPage() const +{ + int nDiff = nbNotebook->GetPageCount() - nbNotebook->GetSelection(); + + switch (nDiff) + { + case 3: + return wxT("pg/sql-grant"); + case 2: + return wxT("pg/sql-alterdefaultprivileges"); + default: + return dlgProperty::GetHelpPage(); + } +} + +///////////////////////////////////////////////////////////////////////////// + + +BEGIN_EVENT_TABLE(dlgAgentProperty, dlgProperty) + EVT_BUTTON (wxID_OK, dlgAgentProperty::OnOK) +END_EVENT_TABLE(); + +dlgAgentProperty::dlgAgentProperty(pgaFactory *f, frmMain *frame, const wxString &resName) + : dlgProperty(f, frame, resName) +{ + recId = 0; +} + + +wxString dlgAgentProperty::GetSql() +{ + wxString str = GetInsertSql(); + if (!str.IsEmpty()) + str += wxT("\n\n"); + return str + GetUpdateSql(); +} + + + +bool dlgAgentProperty::executeSql() +{ + wxString sql; + bool dataChanged = false; + + sql = GetInsertSql(); + if (!sql.IsEmpty()) + { + int pos; + long jobId = 0, schId = 0, stpId = 0; + if (sql.Contains(wxT(""))) + { + recId = jobId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_job_jobid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + sql = sql.Left(pos) + NumToStr(jobId) + sql.Mid(pos + 7); + } + + if (sql.Contains(wxT(""))) + { + // Each schedule ID should be unique. This'll need work if a schedule hits more than + // one table or anything. + recId = schId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(schId) + sql.Mid(pos + 7); + recId = schId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + } + } + + if (sql.Contains(wxT(""))) + { + // Each step ID should be unique. This'll need work if a step hits more than + // one table or anything. + recId = stpId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(stpId) + sql.Mid(pos + 7); + recId = stpId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + } + } + + pgSet *set = connection->ExecuteSet(sql); + if (set) + { + delete set; + } + if (!set) + { + return false; + } + dataChanged = true; + } + + sql = GetUpdateSql(); + if (!sql.IsEmpty()) + { + int pos; + while ((pos = sql.Find(wxT(""))) >= 0) + sql = sql.Left(pos) + NumToStr(recId) + sql.Mid(pos + 7); + + long newId; + if (sql.Contains(wxT(""))) + { + // Each schedule ID should be unique. This'll need work if a schedule hits more than + // one table or anything. + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(newId) + sql.Mid(pos + 7); + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_schedule_jscid_seq');"))); + } + } + + if (sql.Contains(wxT(""))) + { + // Each step ID should be unique. This'll need work if a step hits more than + // one table or anything. + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + while ((pos = sql.Find(wxT(""))) >= 0) + { + sql = sql.Left(pos) + NumToStr(newId) + sql.Mid(pos + 7); + newId = StrToLong(connection->ExecuteScalar(wxT("SELECT nextval('pgagent.pga_jobstep_jstid_seq');"))); + } + } + + if (!connection->ExecuteVoid(sql)) + { + // error message is displayed inside ExecuteVoid + return false; + } + dataChanged = true; + } + + return dataChanged; +} + + +void dlgAgentProperty::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (!IsUpToDate()) + { + if (wxMessageBox(wxT("The object has been changed by another user. Do you wish to continue to try to update it?"), wxT("Overwrite changes?"), wxYES_NO) != wxYES) + return; + } + + if (IsModal()) + { + EndModal(0); + return; + } + + connection->ExecuteVoid(wxT("BEGIN TRANSACTION")); + + if (executeSql()) + { + connection->ExecuteVoid(wxT("COMMIT TRANSACTION")); + ShowObject(); + } + else + { + connection->ExecuteVoid(wxT("ROLLBACK TRANSACTION")); + } + + Destroy(); +} + + +propertyFactory::propertyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + if (mnu) + mnu->Append(id, _("&Properties...\tCtrl-Alt-Enter"), _("Display/edit the properties of the selected object.")); + else + context = false; + if (toolbar) + toolbar->AddTool(id, wxEmptyString, *properties_png_bmp, _("Display/edit the properties of the selected object."), wxITEM_NORMAL); +} + + +wxWindow *propertyFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!dlgProperty::EditObjectDialog(form, form->GetSqlPane(), obj)) + form->CheckAlive(); + + return 0; +} + + +bool propertyFactory::CheckEnable(pgObject *obj) +{ + return obj && ((obj->GetMetaType() == PGM_DATABASE) ? (obj->GetConnection() != NULL) : true) && obj->CanEdit(); +} + + +#include "images/create.pngc" +createFactory::createFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Create..."), _("Create a new object of the same type as the selected object.")); + toolbar->AddTool(id, wxEmptyString, *create_png_bmp, _("Create a new object of the same type as the selected object."), wxITEM_NORMAL); +} + + +wxWindow *createFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!dlgProperty::CreateObjectDialog(form, obj, 0)) + form->CheckAlive(); + + return 0; +} + + +bool createFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanCreate(); +} + + +#include "images/drop.pngc" +dropFactory::dropFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Delete/Drop...\tDel"), _("Delete/Drop the selected object.")); + toolbar->AddTool(id, wxEmptyString, *drop_png_bmp, _("Drop the currently selected object."), wxITEM_NORMAL); +} + + +wxWindow *dropFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->ExecDrop(false); + return 0; +} + + +bool dropFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanDrop(); +} + + +dropCascadedFactory::dropCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Drop cascaded..."), _("Drop the selected object and all objects dependent on it.")); +} + + +wxWindow *dropCascadedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->ExecDrop(true); + return 0; +} + + +bool dropCascadedFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanDrop() && obj->CanDropCascaded(); +} + + +#include "images/refresh.pngc" +refreshFactory::refreshFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + if (mnu) + mnu->Append(id, _("Re&fresh\tF5"), _("Refresh the selected object.")); + else + context = false; + if (toolbar) + toolbar->AddTool(id, wxEmptyString, *refresh_png_bmp, _("Refresh the selected object."), wxITEM_NORMAL); +} + + +wxWindow *refreshFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (form) + obj = form->GetBrowser()->GetObject(form->GetBrowser()->GetSelection()); + + if (obj) + if (CheckEnable(obj)) + form->Refresh(obj); + return 0; +} + + +bool refreshFactory::CheckEnable(pgObject *obj) +{ + // This isn't really clean... But we don't have a pgObject::CanRefresh() so far, + // so it's Good Enough (tm) for now. + return obj != 0 && !obj->IsCreatedBy(serverFactory.GetCollectionFactory()); +} + diff --git a/dlg/dlgReassignDropOwned.cpp b/dlg/dlgReassignDropOwned.cpp new file mode 100644 index 0000000..95b3d97 --- /dev/null +++ b/dlg/dlgReassignDropOwned.cpp @@ -0,0 +1,122 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgReassignDropOwned.cpp - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgRole.h" +#include "dlg/dlgReassignDropOwned.h" + + +// pointer to controls +#define rbReassignTo CTRL_RADIOBUTTON("rbReassignTo") +#define rbDrop CTRL_RADIOBUTTON("rbDrop") +#define cbRoles CTRL_COMBOBOX("cbRoles") +#define cbDatabases CTRL_COMBOBOX("cbDatabases") +#define btnOK CTRL_BUTTON("wxID_OK") + +BEGIN_EVENT_TABLE(dlgReassignDropOwned, pgDialog) + EVT_RADIOBUTTON(XRCID("rbReassignTo"), dlgReassignDropOwned::OnChange) + EVT_RADIOBUTTON(XRCID("rbDrop"), dlgReassignDropOwned::OnChange) + EVT_BUTTON(wxID_OK, dlgReassignDropOwned::OnOK) +END_EVENT_TABLE() + + +dlgReassignDropOwned::dlgReassignDropOwned(frmMain *win, pgConn *conn, + pgRole *role, wxString dbrestriction) +{ + wxString query; + + connection = conn; + parent = win; + + SetFont(settings->GetSystemFont()); + LoadResource(win, wxT("dlgReassignDropOwned")); + RestorePosition(); + + cbRoles->Clear(); + query = wxT("SELECT rolname FROM pg_roles WHERE rolname<>") + conn->qtDbString(role->GetName()) + wxT(" ORDER BY rolname"); + pgSetIterator roles(connection, query); + while (roles.RowsLeft()) + { + cbRoles->Append(roles.GetVal(wxT("rolname"))); + } + cbRoles->SetSelection(0); + cbRoles->Enable(cbRoles->GetStrings().Count() > 0); + + cbDatabases->Clear(); + query = wxT("SELECT DISTINCT datname FROM pg_database WHERE datallowconn"); + if (!dbrestriction.IsEmpty()) + { + query += wxT(" AND datname NOT IN (") + dbrestriction + wxT(")"); + } + query += wxT(" ORDER BY datname"); + + pgSetIterator databases(connection, query); + while (databases.RowsLeft()) + { + cbDatabases->Append(databases.GetVal(wxT("datname"))); + } + cbDatabases->SetSelection(0); + + if(rbReassignTo->GetValue() && cbRoles->GetStrings().Count() <= 0) + btnOK->Disable(); + + SetSize(330, 160); +} + +dlgReassignDropOwned::~dlgReassignDropOwned() +{ + SavePosition(); +} + + +void dlgReassignDropOwned::OnOK(wxCommandEvent &ev) +{ + EndModal(wxID_OK); +} + + +void dlgReassignDropOwned::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +void dlgReassignDropOwned::OnChange(wxCommandEvent &ev) +{ + cbRoles->Enable(rbReassignTo->GetValue() && cbRoles->GetStrings().Count() > 0); + if(rbReassignTo->GetValue() && cbRoles->GetStrings().Count() <= 0) + btnOK->Disable(); + else + btnOK->Enable(); +} + +wxString dlgReassignDropOwned::GetDatabase() +{ + return cbDatabases->GetValue(); +} + +wxString dlgReassignDropOwned::GetRole() +{ + return cbRoles->GetValue(); +} + +bool dlgReassignDropOwned::IsReassign() +{ + return rbReassignTo->GetValue(); +} diff --git a/dlg/dlgResourceGroup.cpp b/dlg/dlgResourceGroup.cpp new file mode 100644 index 0000000..c7088fd --- /dev/null +++ b/dlg/dlgResourceGroup.cpp @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgResourceGroup.cpp - Resource Group Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "dlg/dlgResourceGroup.h" +#include "schema/edbResourceGroup.h" + + +// pointer to controls +#define txtResGrpName CTRL_TEXT("txtResGrpName") +#define txtCPURate CTRL_TEXT("txtCPURate") +#define txtDirtyRate CTRL_TEXT("txtDirtyRate") + +dlgProperty *edbResourceGroupFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgResourceGroup(this, frame, (edbResourceGroup *)node); +} + + +BEGIN_EVENT_TABLE(dlgResourceGroup, dlgProperty) + EVT_TEXT(XRCID("txtCPURate"), dlgResourceGroup::OnChange) + EVT_TEXT(XRCID("txtDirtyRate"), dlgResourceGroup::OnChange) + EVT_BUTTON(wxID_OK, dlgResourceGroup::OnOK) +END_EVENT_TABLE(); + +dlgResourceGroup::dlgResourceGroup(pgaFactory *f, frmMain *frame, edbResourceGroup *node) + : dlgProperty(f, frame, wxT("dlgResourceGroup")) +{ + resourceGroup = node; + m_cpuRate = wxEmptyString; + m_dirtyRate = wxEmptyString; + m_isNameChange = false; +} + +pgObject *dlgResourceGroup::GetObject() +{ + return resourceGroup; +} + +int dlgResourceGroup::Go(bool modal) +{ + txtCPURate->SetValidator(numericValidator); + txtDirtyRate->SetValidator(numericValidator); + + if (resourceGroup) + { + wxString sql = wxT("SELECT rgrpcpuratelimit, rgrpdirtyratelimit from edb_resource_group WHERE rgrpname = '") + + resourceGroup->GetName() + wxT("'"); + + pgSet *set = connection->ExecuteSet(sql); + if (set && set->NumRows() > 0) + { + txtCPURate->SetValue(set->GetVal(0)); + txtDirtyRate->SetValue(set->GetVal(1)); + delete set; + } + } + else + { + txtCPURate->SetValue(wxT("0")); + txtDirtyRate->SetValue(wxT("0")); + } + + m_cpuRate = txtCPURate->GetValue(); + m_dirtyRate = txtDirtyRate->GetValue(); + + return dlgProperty::Go(modal); +} + +void dlgResourceGroup::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgResourceGroup::CheckChange() +{ + if (resourceGroup) + { + EnableOK(!GetSql().IsEmpty()); + } + else + { + wxString name = GetName(); + wxString cpuRate = txtCPURate->GetValue(); + wxString dirtyRate = txtDirtyRate->GetValue(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, !cpuRate.IsEmpty(), _("Please specify CPU rate limit.")); + CheckValid(enable, !dirtyRate.IsEmpty(), _("Please specify Dirty rate limit.")); + + EnableOK(enable); + } +} + +pgObject *dlgResourceGroup::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = resourceGroupFactory.CreateObjects(collection, 0, wxT("\n WHERE rgrpname= ") + qtDbString(name)); + return obj; +} + +wxString dlgResourceGroup::GetSql() +{ + wxString sql = wxEmptyString; + wxString name = GetName(); + wxString cpuRate = txtCPURate->GetValue(); + wxString dirtyRate = txtDirtyRate->GetValue(); + + if (resourceGroup) + { + AppendNameChange(sql, wxT("RESOURCE GROUP ") + resourceGroup->GetQuotedFullIdentifier()); + + // Update the flag if resource group name is changed so that next + // ALTER command will be displayed in the second SQL text box. + m_isNameChange = !sql.IsEmpty(); + + // Check the "cpu rate/dirty rate" limit is changed or not + if (!m_isNameChange && (m_cpuRate.compare(cpuRate) != 0 || m_dirtyRate.compare(dirtyRate) != 0)) + { + sql += wxT("ALTER RESOURCE GROUP ") + qtIdent(name) + wxT(" SET cpu_rate_limit = ") + + cpuRate + wxT(", dirty_rate_limit = ") + dirtyRate + wxT(";\n"); + } + } + else + { + sql = wxT("CREATE RESOURCE GROUP ") + qtIdent(name) + wxT(";\n"); + } + + return sql; +} + +wxString dlgResourceGroup::GetSql2() +{ + wxString sql = wxEmptyString; + wxString name = GetName(); + wxString cpuRate = txtCPURate->GetValue(); + wxString dirtyRate = txtDirtyRate->GetValue(); + + if (!resourceGroup || m_isNameChange) + { + // Check the "cpu rate/dirty rate" limit is changed or not + if (m_cpuRate.compare(cpuRate) != 0 || m_dirtyRate.compare(dirtyRate) != 0) + { + sql = wxT("ALTER RESOURCE GROUP ") + qtIdent(name) + wxT(" SET cpu_rate_limit = ") + + cpuRate + wxT(", dirty_rate_limit = ") + dirtyRate + wxT(";\n"); + } + } + + return sql; +} + +void dlgResourceGroup::OnOK(wxCommandEvent &ev) +{ + dlgProperty::OnOK(ev); +} diff --git a/dlg/dlgRole.cpp b/dlg/dlgRole.cpp new file mode 100644 index 0000000..00f6b83 --- /dev/null +++ b/dlg/dlgRole.cpp @@ -0,0 +1,930 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRole.cpp - PostgreSQL Role Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "utils/misc.h" +#include "dlg/dlgRole.h" +#include "schema/pgRole.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define txtPasswd CTRL_TEXT("txtPasswd") +#define txtRePasswd CTRL_TEXT("txtRePasswd") +#define datValidUntil CTRL_CALENDAR("datValidUntil") +#define timValidUntil CTRL_TIME("timValidUntil") +#define chkCanLogin CTRL_CHECKBOX("chkCanLogin") +#define chkSuperuser CTRL_CHECKBOX("chkSuperuser") +#define chkInherits CTRL_CHECKBOX("chkInherits") +#define chkCreateDB CTRL_CHECKBOX("chkCreateDB") +#define chkCreateRole CTRL_CHECKBOX("chkCreateRole") +#define chkUpdateCat CTRL_CHECKBOX("chkUpdateCat") +#define chkReplication CTRL_CHECKBOX("chkReplication") +#define txtConnectionLimit CTRL_TEXT("txtConnectionLimit") + +#define lbRolesNotIn CTRL_LISTBOX("lbRolesNotIn") +#define lbRolesIn CTRL_LISTBOX("lbRolesIn") +#define btnAddRole CTRL_BUTTON("btnAddRole") +#define btnDelRole CTRL_BUTTON("btnDelRole") +#define chkAdminOption CTRL_CHECKBOX("chkAdminOption") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define cbVarDbname CTRL_COMBOBOX2("cbVarDbname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") + + + +dlgProperty *pgLoginRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRole(this, frame, (pgRole *)node, true); +} + +dlgProperty *pgGroupRoleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRole(this, frame, (pgRole *)node, false); +} + +BEGIN_EVENT_TABLE(dlgRole, dlgProperty) + EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeCal) + EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgRole::OnChangeDate) + EVT_SPIN(XRCID("timValidUntil"), dlgRole::OnChangeSpin) + EVT_TEXT(XRCID("timValidUntil"), dlgRole::OnChange) + + EVT_LISTBOX_DCLICK(XRCID("lbRolesNotIn"), dlgRole::OnRoleAdd) + EVT_LISTBOX_DCLICK(XRCID("lbRolesIn"), dlgRole::OnRoleRemove) + EVT_TEXT(XRCID("txtPasswd"), dlgRole::OnChangePasswd) + EVT_TEXT(XRCID("txtRePasswd"), dlgRole::OnChangePasswd) + EVT_CHECKBOX(XRCID("chkCanLogin"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkInherits"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkCreateDB"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkUpdateCat"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkSuperuser"), dlgRole::OnChangeSuperuser) + EVT_CHECKBOX(XRCID("chkCreateRole"), dlgRole::OnChange) + EVT_CHECKBOX(XRCID("chkReplication"), dlgRole::OnChange) + EVT_TEXT(XRCID("txtConnectionLimit"), dlgRole::OnChange) + + EVT_BUTTON(XRCID("btnAddRole"), dlgRole::OnRoleAdd) + EVT_BUTTON(XRCID("btnDelRole"), dlgRole::OnRoleRemove) + + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgRole::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgRole::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgRole::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgRole::OnVarnameSelChange) + EVT_TEXT(XRCID("cbVarDbname"), dlgRole::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgRole::OnVarnameSelChange) + + EVT_BUTTON(wxID_OK, dlgRole::OnOK) + +#ifdef __WXMAC__ + EVT_SIZE( dlgRole::OnChangeSize) +#endif +END_EVENT_TABLE(); + + + +dlgRole::dlgRole(pgaFactory *f, frmMain *frame, pgRole *node, bool chkLogin) + : dlgProperty(f, frame, wxT("dlgRole")) +{ + role = node; + lstVariables->CreateColumns(0, _("Database"), _("Variable"), _("Value"), -1); + btnOK->Disable(); + chkValue->Hide(); + if (chkLogin) + chkCanLogin->SetValue(true); + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgRole::GetObject() +{ + return role; +} + + +#ifdef __WXMAC__ +void dlgRole::OnChangeSize(wxSizeEvent &ev) +{ + lstVariables->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +int dlgRole::Go(bool modal) +{ + +// In wxMac, the text deletion of "calenderBox" is not raising the EVT_CALENDAR_SEL_CHANGED, EVT_DATE_CHANGED events properly. +// Hence, raising these events with wxEVT_CHILD_FOCUS events. +// +#ifdef __WXMAC__ + + datValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this); + timValidUntil->Connect(wxEVT_CHILD_FOCUS, wxCommandEventHandler(dlgRole::OnChange), NULL, this); + +#endif + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarDbname->Append(wxT("")); + AddDatabases(cbVarDbname); + } + else + { + cbVarDbname->Enable(false); + } + + if (connection->BackendMinimumVersion(9, 2)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(role); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgRole::OnChange)); + } + else + seclabelPage->Disable(); + + wxString roleSql = + wxT("SELECT rolname\n") + wxT(" FROM pg_roles r\n"); + + varInfo.Add(wxT("role")); + cbVarname->Append(wxT("role")); + + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + + if (connection->BackendMinimumVersion(9, 0)) + { + cbVarDbname->SetSelection(0); + } + + SetupVarEditor(0); + } + + if (role) + { + wxArrayString roles = role->GetRolesIn(); + size_t i; + for (i = 0 ; i < roles.GetCount() ; i++) + lbRolesIn->Append(roles.Item(i)); + + roleSql += + wxT(" LEFT JOIN pg_auth_members ON r.oid=roleid AND member = ") + role->GetOidStr() + wxT("\n") + wxT(" WHERE r.oid <> ") + role->GetOidStr() + wxT("\n") + wxT(" AND roleid IS NULL"); + + // Edit Mode + if (role->GetServer()->GetSuperUser() || role->GetServer()->GetCreateRole()) + readOnly = false; + else + readOnly = true; + + chkCreateDB->SetValue(role->GetCreateDatabase()); + chkCreateRole->SetValue(role->GetCreateRole()); + chkSuperuser->SetValue(role->GetSuperuser()); + chkInherits->SetValue(role->GetInherits()); + if (!connection->BackendMinimumVersion(9, 5)) + chkUpdateCat->SetValue(role->GetUpdateCatalog()); + else + chkUpdateCat->Disable(); + chkCanLogin->SetValue(role->GetCanLogin()); + chkReplication->SetValue(role->GetReplication()); + if (role->GetAccountExpires().IsValid() && role->GetAccountExpires().GetValue() != -1) + { + datValidUntil->SetValue(role->GetAccountExpires().GetDateOnly()); + timValidUntil->SetTime(role->GetAccountExpires()); + } + else + { + wxDateTime empty; + datValidUntil->SetValue(empty); + } + txtConnectionLimit->SetValue(NumToStr(role->GetConnectionLimit())); + txtComment->SetValue(role->GetComment()); + + size_t index; + wxString dbname; + wxString parameter; + wxString value; + for (index = 0 ; index < role->GetVariables().GetCount() ; index += 3) + { + dbname = role->GetVariables().Item(index); + parameter = role->GetVariables().Item(index + 1); + value = role->GetVariables().Item(index + 2); + + lstVariables->AppendItem(0, dbname, parameter, value); + } + + timValidUntil->Enable(!readOnly && role->GetAccountExpires().IsValid()); + + if (readOnly) + { + chkCanLogin->Disable(); + chkCreateDB->Disable(); + chkCreateRole->Disable(); + chkSuperuser->Disable(); + chkInherits->Disable(); + chkUpdateCat->Disable(); + chkReplication->Disable(); + datValidUntil->Disable(); + timValidUntil->Disable(); + btnAddRole->Disable(); + btnDelRole->Disable(); + cbVarname->Disable(); + cbVarDbname->Disable(); + txtValue->Disable(); + txtConnectionLimit->Disable(); + btnRemove->Disable(); + /* Its own password can be changed. */ + if (connection->GetUser() != role->GetName()) + { + txtPasswd->Disable(); + txtRePasswd->Disable(); + btnAdd->Disable(); + } + else + { + txtPasswd->Enable(); + txtRePasswd->Enable(); + btnAdd->Enable(); + } + } + } + else + { + chkCanLogin->Disable(); + wxDateTime empty; + datValidUntil->SetValue(empty); + timValidUntil->Disable(); + } + + // Role comments are only appropriate in 8.2+ + if (!connection->BackendMinimumVersion(8, 2)) + txtComment->Disable(); + + // Replication roles added in 9.1 + if (!connection->BackendMinimumVersion(9, 1)) + { + chkReplication->Disable(); + } + + + if (!settings->GetShowUsersForPrivileges()) + { + if (role) + roleSql += wxT("\n AND NOT rolcanlogin"); + else + roleSql += wxT("\n WHERE NOT rolcanlogin"); + } + roleSql += wxT("\n ORDER BY rolname"); + + pgSetIterator roles(connection, roleSql); + + while (roles.RowsLeft()) + lbRolesNotIn->Append(roles.GetVal(wxT("rolname"))); + + return dlgProperty::Go(modal); +} + + +wxString dlgRole::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 2) + return wxT("pg/runtime-config"); + else + return wxT("pg/sql-createrole"); +} + + +void dlgRole::OnOK(wxCommandEvent &ev) +{ + dlgProperty::OnOK(ev); + + if (role && ((role->GetCanLogin() != chkCanLogin->GetValue()) == !btnOK->IsEnabled())) + { + // LOGIN attribute changed successfully; need to put object under different collection + } +} + + +void dlgRole::OnChangeCal(wxCalendarEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + + +void dlgRole::OnChangeDate(wxDateEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + +void dlgRole::OnChangeSpin(wxSpinEvent &ev) +{ + CheckChange(); +} + + +void dlgRole::OnChangeSuperuser(wxCommandEvent &ev) +{ + if (role && role->GetSuperuser() && !chkSuperuser->GetValue()) + { + wxMessageDialog dlg(this, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + { + chkSuperuser->SetValue(true); + return; + } + } + chkUpdateCat->SetValue(chkSuperuser->GetValue() && + !connection->BackendMinimumVersion(9, 5)); + CheckChange(); +} + +void dlgRole::OnChangePasswd(wxCommandEvent &ev) +{ + CheckChange(); +} + +void dlgRole::CheckChange() +{ + bool enable = true; + bool timEn = datValidUntil->GetValue().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + + if (!readOnly) + chkUpdateCat->Enable(chkSuperuser->GetValue() && + !connection->BackendMinimumVersion(9, 5)); + + // Check the passwords match + if (txtPasswd->GetValue() != txtRePasswd->GetValue()) + { + bool enable = true; + CheckValid(enable, false, _("The passwords entered do not match!")); + EnableOK(enable); + return; + } + + if (!role) + { + wxString name = GetName(); + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + } + else + { + enable = !GetSql().IsEmpty(); + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + EnableOK(enable); +} + + +void dlgRole::OnRoleAdd(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbRolesNotIn->GetSelection(); + if (pos >= 0) + { + wxString roleName = lbRolesNotIn->GetString(pos); + if (chkAdminOption->GetValue()) + roleName += PGROLE_ADMINOPTION; + lbRolesIn->Append(roleName); + lbRolesNotIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgRole::OnRoleRemove(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbRolesIn->GetSelection(); + if (pos >= 0) + { + wxString role = lbRolesIn->GetString(pos); + if (role.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + role = role.Left(role.Length() - PGROLE_ADMINOPTION_LEN); + + lbRolesNotIn->Append(role); + lbRolesIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgRole::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgRole::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->GetParent()->Layout(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + txtValue->GetParent()->Layout(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + } + + } +} + +void dlgRole::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + cbVarDbname->SetValue(lstVariables->GetText(pos)); + cbVarname->SetValue(lstVariables->GetText(pos, 1)); + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + wxString value = lstVariables->GetText(pos, 2); + int sel = cbVarname->FindString(lstVariables->GetText(pos, 1)); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + +void dlgRole::OnVarAdd(wxCommandEvent &ev) +{ + wxString dbname = cbVarDbname->GetValue(); + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + bool found = false; + long prevpos = -1; + for (long item = 0; item < lstVariables->GetItemCount(); item++) + { + if (name == lstVariables->GetText(item, 1)) + { + if (dbname == lstVariables->GetText(item)) + { + found = true; + lstVariables->SetItem(item, 2, value); + } + else + { + prevpos = item; + } + } + } + if (!found) + { + if (prevpos != -1) + { + lstVariables->InsertItem(prevpos, dbname, 1); + lstVariables->SetItem(prevpos, 1, name); + lstVariables->SetItem(prevpos, 2, value); + } + else + { + long pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, dbname, 1); + lstVariables->SetItem(pos, 1, name); + lstVariables->SetItem(pos, 2, value); + } + } + } + CheckChange(); +} + + +void dlgRole::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + CheckChange(); +} + + +pgObject *dlgRole::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = loginRoleFactory.CreateObjects(collection, 0, wxT("\n WHERE rolname=") + qtDbString(name)); + return obj; +} + + +wxString dlgRole::GetSql() +{ + int pos; + wxString sql; + wxString name = GetName(); + + wxString passwd = txtPasswd->GetValue(); + bool createDB = chkCreateDB->GetValue(), + createRole = chkCreateRole->GetValue(), + superuser = chkSuperuser->GetValue(), + inherits = chkInherits->GetValue(), + canLogin = chkCanLogin->GetValue(), + replication = chkReplication->GetValue(); + + if (role) + { + // Edit Mode + + AppendNameChange(sql, wxT("ROLE ") + role->GetQuotedFullIdentifier()); + + + wxString options; + if (canLogin != role->GetCanLogin()) + { + if (canLogin) + options = wxT(" LOGIN"); + else + options = wxT(" NOLOGIN"); + } + if (canLogin && !passwd.IsEmpty()) + options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + + if (createDB != role->GetCreateDatabase() || createRole != role->GetCreateRole() + || superuser != role->GetSuperuser() || inherits != role->GetInherits() + || replication != role->GetReplication()) + { + options += wxT("\n "); + + if (superuser != role->GetSuperuser()) + { + if (superuser) + options += wxT(" SUPERUSER"); + else + options += wxT(" NOSUPERUSER"); + } + if (inherits != role->GetInherits()) + { + if (inherits) + options += wxT(" INHERIT"); + else + options += wxT(" NOINHERIT"); + } + if (createDB != role->GetCreateDatabase()) + { + if (createDB) + options += wxT(" CREATEDB"); + else + options += wxT(" NOCREATEDB"); + } + if (createRole != role->GetCreateRole()) + { + if (createRole) + options += wxT(" CREATEROLE"); + else + options += wxT(" NOCREATEROLE"); + } + if (connection->BackendMinimumVersion(9, 1)) + { + if (replication != role->GetReplication()) + { + if (replication) + options += wxT(" REPLICATION"); + else + options += wxT(" NOREPLICATION"); + } + } + } + if (!datValidUntil->GetValue().IsValid() || DateToStr(datValidUntil->GetValue() + timValidUntil->GetValue()) != DateToStr(role->GetAccountExpires())) + { + if (datValidUntil->GetValue().IsValid()) + options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else if (!role->GetIsValidInfinity() && role->GetAccountExpires().GetValue() != -1) + options += wxT("\n VALID UNTIL 'infinity'"); + } + + if (txtConnectionLimit->GetValue().Length() == 0) + { + if (role->GetConnectionLimit() != -1) + { + options += wxT(" CONNECTION LIMIT -1"); + } + } + else + { + if (txtConnectionLimit->GetValue() != NumToStr(role->GetConnectionLimit())) + { + options += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue(); + } + } + + if (!options.IsNull()) + sql += wxT("ALTER ROLE ") + qtIdent(name) + options + wxT(";\n"); + + if (!connection->BackendMinimumVersion(9, 5) && + chkUpdateCat->GetValue() != role->GetUpdateCatalog()) + { + if (!connection->HasPrivilege(wxT("Table"), wxT("pg_authid"), wxT("update"))) + sql += wxT(" -- Can't update 'UpdateCatalog privilege: can't write to pg_authid.\n") + wxT("-- "); + + sql += wxT("UPDATE pg_authid SET rolcatupdate=") + BoolToStr(chkUpdateCat->GetValue()) + + wxT(" WHERE OID=") + role->GetOidStr() + wxT(";\n"); + } + int cnt = lbRolesIn->GetCount(); + wxArrayString tmpRoles = role->GetRolesIn(); + + // check for added roles + for (pos = 0 ; pos < cnt ; pos++) + { + wxString roleName = lbRolesIn->GetString(pos); + + int index = tmpRoles.Index(roleName); + if (index >= 0) + { + // role membership unchanged + tmpRoles.RemoveAt(index); + } + else + { + bool admin = false; + if (roleName.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + { + admin = true; + roleName = roleName.Left(roleName.Length() - PGROLE_ADMINOPTION_LEN); + } + else + { + // new role membership without admin option + index = tmpRoles.Index(roleName + PGROLE_ADMINOPTION); + if (index >= 0) + { + // old membership with admin option + tmpRoles.RemoveAt(index); + sql += wxT("REVOKE ADMIN OPTION FOR ") + qtIdent(roleName) + + wxT(" FROM ") + qtIdent(name) + wxT(";\n"); + continue; + } + } + + index = tmpRoles.Index(roleName); + if (index >= 0) + { + // admin option added to existing membership + tmpRoles.RemoveAt(index); + } + + sql += wxT("GRANT ") + qtIdent(roleName) + + wxT(" TO ") + qtIdent(name); + + if (admin) + sql += wxT(" WITH ADMIN OPTION"); + + sql += wxT(";\n"); + } + } + + // check for removed roles + for (pos = 0 ; pos < (int)tmpRoles.GetCount() ; pos++) + { + sql += wxT("REVOKE ") + qtIdent(tmpRoles.Item(pos)) + + wxT(" FROM ") + qtIdent(name) + wxT(";\n"); + } + } + else + { + // Create Mode + sql = wxT( + "CREATE ROLE ") + qtIdent(name); + if (canLogin) + { + sql += wxT(" LOGIN"); + if (!passwd.IsEmpty()) + sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + } + + if (createDB || createRole || !inherits || superuser) + sql += wxT("\n "); + if (superuser) + sql += wxT(" SUPERUSER"); + if (!inherits) + sql += wxT(" NOINHERIT"); + if (createDB) + sql += wxT(" CREATEDB"); + if (createRole) + sql += wxT(" CREATEROLE"); + if (connection->BackendMinimumVersion(9, 1)) + { + if (replication) + sql += wxT(" REPLICATION"); + } + if (datValidUntil->GetValue().IsValid()) + sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else + sql += wxT("\n VALID UNTIL 'infinity'"); + + if (txtConnectionLimit->GetValue().Length() > 0) + { + sql += wxT(" CONNECTION LIMIT ") + txtConnectionLimit->GetValue(); + } + + int cnt = lbRolesIn->GetCount(); + wxString grants; + + if (cnt) + { + wxString roleName; + + for (pos = 0 ; pos < cnt ; pos++) + { + bool admin = false; + roleName = lbRolesIn->GetString(pos); + if (roleName.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + { + roleName = roleName.Left(roleName.Length() - PGROLE_ADMINOPTION_LEN); + admin = true; + + } + grants += wxT("GRANT ") + qtIdent(roleName) + + wxT(" TO ") + qtIdent(name); + + if (admin) + grants += wxT(" WITH ADMIN OPTION;\n"); + else + grants += wxT(";\n"); + } + } + sql += wxT(";\n") + grants; + + if (superuser && !chkUpdateCat->GetValue() && + !connection->BackendMinimumVersion(9, 5)) + sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(name) + wxT(";\n"); + } + + wxArrayString vars; + wxString dbname; + wxString parameter; + wxString value; + + size_t index; + + if (role) + { + for (index = 0 ; index < role->GetVariables().GetCount() ; index++) + vars.Add(role->GetVariables().Item(index)); + } + + int cnt = lstVariables->GetItemCount(); + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newDb = lstVariables->GetText(pos); + wxString newVar = lstVariables->GetText(pos, 1); + wxString newVal = lstVariables->GetText(pos, 2); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index += 3) + { + dbname = vars.Item(index); + parameter = vars.Item(index + 1); + value = vars.Item(index + 2); + + if (newDb == dbname && newVar == parameter) + { + oldVal = value; + vars.RemoveAt(index); + vars.RemoveAt(index); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (newDb.Length() == 0) + sql += wxT("ALTER ROLE ") + qtIdent(name); + else + sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + newDb; + + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + newVar + wxT(" = '") + newVal + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + newVar + wxT(" = ") + newVal + wxT(";\n"); + } + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos += 3) + { + dbname = vars.Item(pos); + parameter = vars.Item(pos + 1); + value = vars.Item(pos + 2); + + if (dbname.Length() == 0) + { + sql += wxT("ALTER ROLE ") + qtIdent(name) + + wxT(" RESET ") + parameter + + wxT(";\n"); + } + else + { + sql += wxT("ALTER ROLE ") + qtIdent(name) + wxT(" IN DATABASE ") + dbname + + wxT(" RESET ") + parameter + wxT(";\n"); + } + } + + AppendComment(sql, wxT("ROLE"), 0, role); + + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("ROLE"), qtIdent(name)); + + return sql; +} + + +void dlgRole::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgRule.cpp b/dlg/dlgRule.cpp new file mode 100644 index 0000000..32ced00 --- /dev/null +++ b/dlg/dlgRule.cpp @@ -0,0 +1,196 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRule.cpp - PostgreSQL View Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgRule.h" +#include "schema/pgRule.h" +#include "schema/pgTable.h" +#include "schema/pgCollection.h" + + + +// pointer to controls +#define rbxEvent CTRL_RADIOBOX("rbxEvent") +#define chkDoInstead CTRL_CHECKBOX("chkDoInstead") +#define txtCondition CTRL_TEXT("txtCondition") + +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") + + +BEGIN_EVENT_TABLE(dlgRule, dlgProperty) + EVT_TEXT(XRCID("txtCondition"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSelect"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkInsert"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkUpdate"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDelete"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkDoInstead"), dlgProperty::OnChange) + EVT_RADIOBOX(XRCID("rbxEvent"), dlgProperty::OnChange) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) +END_EVENT_TABLE(); + + +dlgProperty *pgRuleFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRule(this, frame, (pgRule *)node, (pgTable *)parent); +} + + + +dlgRule::dlgRule(pgaFactory *f, frmMain *frame, pgRule *node, pgTable *tab) + : dlgProperty(f, frame, wxT("dlgRule")) +{ + table = tab; + rule = node; +} + + +pgObject *dlgRule::GetObject() +{ + return rule; +} + + +int dlgRule::Go(bool modal) +{ + if (rule) + { + // edit mode + + oldDefinition = rule->GetFormattedDefinition(); + if (!oldDefinition.IsEmpty()) + { + int doPos = oldDefinition.Find(wxT(" DO INSTEAD ")); + if (doPos > 0) + oldDefinition = oldDefinition.Mid(doPos + 12).Strip(wxString::both); + else + { + doPos = oldDefinition.Find(wxT(" DO ")); + if (doPos > 0) + oldDefinition = oldDefinition.Mid(doPos + 4).Strip(wxString::both); + } + } + chkDoInstead->SetValue(rule->GetDoInstead()); + rbxEvent->SetStringSelection(rule->GetEvent()); + txtCondition->SetValue(rule->GetCondition()); + txtSqlBox->SetText(oldDefinition); + + txtName->Disable(); + } + else + { + // create mode + } + + // Reset the labels as they XRC values will have been localised :-( + rbxEvent->SetString(0, wxT("SELECT")); + rbxEvent->SetString(1, wxT("INSERT")); + rbxEvent->SetString(2, wxT("UPDATE")); + rbxEvent->SetString(3, wxT("DELETE")); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRule::CreateObject(pgCollection *collection) +{ + pgObject *obj = ruleFactory.CreateObjects(collection, 0, + wxT("\n AND rulename=") + qtDbString(GetName()) + + wxT("\n AND rw.ev_class=") + table->GetOidStr()); + return obj; +} + + +bool dlgRule::didChange() +{ + if (!rule) + return true; + + if (GetName() != rule->GetName()) + return true; + if (txtSqlBox->GetText().Strip(wxString::both) != oldDefinition) + return true; + if (chkDoInstead->GetValue() != rule->GetDoInstead()) + return true; + if (rbxEvent->GetStringSelection() != rule->GetEvent()) + return true; + if (txtCondition->GetValue() != rule->GetCondition()) + return true; + if (txtSqlBox->GetText() != oldDefinition) + return true; + + return false; +} + + +void dlgRule::CheckChange() +{ + if (rule) + { + EnableOK(didChange() || txtSqlBox->GetText() != oldDefinition || txtComment->GetValue() != rule->GetComment()); + } + else + { + wxString name = GetName(); + + bool enable = true; + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, rbxEvent->GetSelection() >= 0, + _("Please select at an event.")); + CheckValid(enable, !txtSqlBox->GetTextLength() || txtSqlBox->GetTextLength() > 6 , _("Please enter function definition.")); + + EnableOK(enable); + } +} + + +wxString dlgRule::GetSql() +{ + wxString sql, name = GetName(); + + + if (!rule || didChange()) + { + sql += wxT("CREATE OR REPLACE RULE ") + qtIdent(name) + + wxT(" AS\n ON ") + rbxEvent->GetStringSelection() + + wxT(" TO ") + table->GetQuotedFullIdentifier(); + AppendIfFilled(sql, wxT("\n WHERE ") , txtCondition->GetValue()); + + sql += wxT("\n DO "); + + if (chkDoInstead->GetValue()) + sql += wxT("INSTEAD "); + + if (txtSqlBox->GetTextLength()) + { + sql += wxT("\n") + txtSqlBox->GetText().Strip(wxString::both); + if (sql.Right(1) != wxT(";")) + sql += wxT(";"); + } + else + sql += wxT("NOTHING;"); + + sql += wxT("\n"); + } + AppendComment(sql, wxT("RULE ") + qtIdent(name) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), rule); + return sql; +} + diff --git a/dlg/dlgSchema.cpp b/dlg/dlgSchema.cpp new file mode 100644 index 0000000..168340b --- /dev/null +++ b/dlg/dlgSchema.cpp @@ -0,0 +1,170 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchema.cpp - PostgreSQL Schema Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "dlg/dlgSchema.h" +#include "schema/pgSchema.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls + +BEGIN_EVENT_TABLE(dlgSchema, dlgDefaultSecurityProperty) +END_EVENT_TABLE(); + +dlgProperty *pgSchemaBaseFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSchema(this, frame, (pgSchema *)node, parent); +} + +dlgSchema::dlgSchema(pgaFactory *f, frmMain *frame, pgSchema *node, pgObject *parent) + : dlgDefaultSecurityProperty(f, frame, node, wxT("dlgSchema"), wxT("USAGE,CREATE"), "UC", node != NULL ? true : false) +{ + schema = node; + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgSchema::GetObject() +{ + return schema; +} + + +int dlgSchema::Go(bool modal) +{ + wxString strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes; + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(schema); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgSchema::OnChange)); + } + else + seclabelPage->Disable(); + + if (schema) + { + if (connection->BackendMinimumVersion(9, 0)) + { + strDefPrivsOnTables = schema->GetDefPrivsOnTables(); + strDefPrivsOnSeqs = schema->GetDefPrivsOnSequences(); + strDefPrivsOnFuncs = schema->GetDefPrivsOnFunctions(); + } + if (connection->BackendMinimumVersion(9, 2)) + strDefPrivsOnTypes = schema->GetDefPrivsOnTypes(); + + // edit mode + if (!connection->BackendMinimumVersion(7, 5)) + cbOwner->Disable(); + + if (schema->GetMetaType() == PGM_CATALOG) + { + cbOwner->Disable(); + txtName->Disable(); + } + } + else + { + // create mode + } + + return dlgDefaultSecurityProperty::Go(modal, true, strDefPrivsOnTables, strDefPrivsOnSeqs, strDefPrivsOnFuncs, strDefPrivsOnTypes); +} + + +pgObject *dlgSchema::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = schemaFactory.CreateObjects(collection, 0, wxT(" WHERE nspname=") + qtDbString(name) + wxT("\n")); + return obj; +} + + +#ifdef __WXMAC__ +void dlgSchema::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgSchema::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + + if (schema) + { + enable = name != schema->GetName() + || txtComment->GetValue() != schema->GetComment() + || cbOwner->GetValue() != schema->GetOwner(); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + } + + EnableOK(enable); +} + + + +wxString dlgSchema::GetSql() +{ + wxString sql, name; + name = qtIdent(GetName()); + + if (schema) + { + // edit mode + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("SCHEMA ") + name); + } + else + { + // create mode + sql = wxT("CREATE SCHEMA ") + name; + AppendIfFilled(sql, wxT("\n AUTHORIZATION "), qtIdent(cbOwner->GetValue())); + sql += wxT(";\n"); + + } + AppendComment(sql, wxT("SCHEMA"), 0, schema); + + sql += GetGrant(wxT("UC"), wxT("SCHEMA ") + name); + + if (connection->BackendMinimumVersion(9, 0) && defaultSecurityChanged) + sql += GetDefaultPrivileges(name); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("SCHEMA"), name); + + return sql; +} + + +void dlgSchema::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgSearchObject.cpp b/dlg/dlgSearchObject.cpp new file mode 100644 index 0000000..59d5de2 --- /dev/null +++ b/dlg/dlgSearchObject.cpp @@ -0,0 +1,976 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSearchObject.h - Search dialogue +// +////////////////////////////////////////////////////////////////////////// + + +//AVANT DE LE COMMITER, IL FAUT AJOUTER LA MODIF DU PROJET VS2008 + +// App headers +#include "pgAdmin3.h" + +#include "frm/frmMain.h" +#include "dlg/dlgSearchObject.h" +#include "utils/sysSettings.h" +#include "utils/misc.h" +#include "ctl/ctlListView.h" + +#define txtPattern CTRL_TEXT("txtPattern") +#define cbType CTRL_COMBOBOX("cbType") +#define cbSchema CTRL_COMBOBOX("cbSchema") +#define lcResults CTRL_LISTCTRL("lcResults") +#define btnSearch CTRL_BUTTON("btnSearch") +#define chkNames CTRL_CHECKBOX("chkNames") +#define chkDefinitions CTRL_CHECKBOX("chkDefinitions") +#define chkComments CTRL_CHECKBOX("chkComments") + +BEGIN_EVENT_TABLE(dlgSearchObject, pgDialog) + EVT_BUTTON(wxID_HELP, dlgSearchObject::OnHelp) + EVT_BUTTON(XRCID("btnSearch"), dlgSearchObject::OnSearch) + EVT_BUTTON(wxID_CANCEL, dlgSearchObject::OnCancel) + EVT_TEXT(XRCID("txtPattern"), dlgSearchObject::OnChange) + EVT_COMBOBOX(XRCID("cbType"), dlgSearchObject::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lcResults"), dlgSearchObject::OnSelSearchResult) + EVT_CHECKBOX(XRCID("chkNames"), dlgSearchObject::OnChange) + EVT_CHECKBOX(XRCID("chkDefinitions"), dlgSearchObject::OnChange) + EVT_CHECKBOX(XRCID("chkComments"), dlgSearchObject::OnChange) +END_EVENT_TABLE() + +dlgSearchObject::dlgSearchObject(frmMain *p, pgDatabase *db, pgObject *obj) +{ + parent = p; + header = wxT(""); + currentdb = db; + + SetFont(settings->GetSystemFont()); + LoadResource(p, wxT("dlgSearchObject")); + statusBar = XRCCTRL(*this, "unkStatusBar", wxStatusBar); + + // Icon + appearanceFactory->SetIcons(this); + RestorePosition(); + + ToggleBtnSearch(false); + + lcResults->InsertColumn(0, _("Type")); + lcResults->InsertColumn(1, _("Name")); + lcResults->InsertColumn(2, _("Path")); + + // Mapping table between local language and english, + // because in SQL we're using only english and translate it later + // to the local language. + + aMap[_("All types")] = wxT("All types"); + aMap[_("Schemas")] = wxT("Schemas"); + aMap[_("Tables")] = wxT("Tables"); + aMap[_("Columns")] = wxT("Columns"); + aMap[_("Triggers")] = wxT("Triggers"); + aMap[_("Views")] = wxT("Views"); + aMap[_("Rules")] = wxT("Rules"); + aMap[_("Indexes")] = wxT("Indexes"); + aMap[_("Functions")] = wxT("Functions"); + aMap[_("Procedures")] = wxT("Procedures"); + aMap[_("Aggregates")] = wxT("Aggregates"); + aMap[_("Trigger Functions")] = wxT("Trigger Functions"); + aMap[_("Constraints")] = wxT("Constraints"); + aMap[_("Sequences")] = wxT("Sequences"); + aMap[_("Types")] = wxT("Types"); + aMap[_("Domains")] = wxT("Domains"); + aMap[_("Languages")] = wxT("Languages"); + aMap[_("Conversions")] = wxT("Conversions"); + aMap[_("Casts")] = wxT("Casts"); + aMap[_("Login Roles")] = wxT("Login Roles"); + aMap[_("Group Roles")] = wxT("Group Roles"); + aMap[_("FTS Configurations")] = wxT("FTS Configurations"); + aMap[_("FTS Dictionaries")] = wxT("FTS Dictionaries"); + aMap[_("FTS Parsers")] = wxT("FTS Parsers"); + aMap[_("FTS Templates")] = wxT("FTS Templates"); + aMap[_("Foreign Data Wrappers")] = wxT("Foreign Data Wrappers"); + aMap[_("Foreign Servers")] = wxT("Foreign Servers"); + aMap[_("Foreign Tables")] = wxT("Foreign Tables"); + aMap[_("User Mappings")] = wxT("User Mappings"); + aMap[_("Operators")] = wxT("Operators"); + aMap[_("Operator Classes")] = wxT("Operator Classes"); + aMap[_("Operator Families")] = wxT("Operator Families"); + aMap[_("Extensions")] = wxT("Extensions"); + aMap[_("Collations")] = wxT("Collations"); + + cbType->Clear(); + cbType->Append(_("All types")); + cbType->Append(_("Schemas")); + cbType->Append(_("Tables")); + cbType->Append(_("Columns")); + cbType->Append(_("Triggers")); + cbType->Append(_("Views")); + cbType->Append(_("Rules")); + cbType->Append(_("Indexes")); + cbType->Append(_("Functions")); + cbType->Append(_("Aggregates")); + cbType->Append(_("Trigger Functions")); + cbType->Append(_("Constraints")); + cbType->Append(_("Sequences")); + cbType->Append(_("Types")); + cbType->Append(_("Languages")); + cbType->Append(_("Domains")); + cbType->Append(_("Conversions")); + cbType->Append(_("Casts")); + cbType->Append(_("Login Roles")); + cbType->Append(_("Group Roles")); + cbType->Append(_("FTS Configurations")); + cbType->Append(_("FTS Dictionaries")); + cbType->Append(_("FTS Parsers")); + cbType->Append(_("FTS Templates")); + if(currentdb->BackendMinimumVersion(8, 4)) + { + cbType->Append(_("Foreign Data Wrappers")); + cbType->Append(_("Foreign Servers")); + cbType->Append(_("User Mappings")); + } + if(currentdb->BackendMinimumVersion(9, 1)) + { + cbType->Append(_("Foreign Tables")); + } + cbType->Append(_("Operators")); + cbType->Append(_("Operator Classes")); + cbType->Append(_("Operator Families")); + + if(currentdb->BackendMinimumVersion(9, 1)) + { + cbType->Append(_("Extensions")); + cbType->Append(_("Collations")); + } + if(currentdb->BackendMinimumVersion(10, 0)) + { + cbType->Append(_("Procedures")); + } + + cbSchema->Clear(); + cbSchema->Append(_("All schemas")); + cbSchema->Append(_("My schemas")); + + if (obj->GetSchema()) + { + if (obj->GetSchema()->GetSchema()) + currentSchema = obj->GetSchema()->GetSchema()->GetName(); + else + currentSchema = obj->GetSchema()->GetName(); + } + else if (obj->GetMetaType() == PGM_SCHEMA && !obj->IsCollection()) + currentSchema = obj->GetName(); + else + currentSchema = wxEmptyString; + + if (!currentSchema.IsEmpty()) + cbSchemaIdxCurrent = cbSchema->Append(wxString::Format(_("Current schema (%s)"), currentSchema.c_str())); + + wxString sql; + + sql = wxT("SELECT nsp.nspname") + wxT(" FROM pg_namespace nsp\n"); + if (!settings->GetShowSystemObjects()) + { + if (currentdb->BackendMinimumVersion(8, 1)) + sql += wxT(" WHERE nspname NOT LIKE E'pg\\\\_temp\\\\_%' AND nspname NOT LIKE E'pg\\\\_toast%'"); + else + sql += wxT(" WHERE nspname NOT LIKE 'pg\\\\_temp\\\\_%' AND nspname NOT LIKE 'pg\\\\_toast%'"); + } + sql += wxT(" ORDER BY nspname"); + + pgSet *set = currentdb->GetConnection()->ExecuteSet(sql); + if(set) + { + while(!set->Eof()) + { + cbSchema->Append(set->GetVal(wxT("nspname"))); + set->MoveNext(); + } + delete set; + } + + RestoreSettings(); + txtPattern->SetFocus(); +} + + +dlgSearchObject::~dlgSearchObject() +{ + SaveSettings(); + SavePosition(); +} + +void dlgSearchObject::SaveSettings() +{ + settings->Write(wxT("SearchObject/Pattern"), txtPattern->GetValue()); + settings->Write(wxT("SearchObject/Type"), aMap[cbType->GetValue()]); + settings->Write(wxT("SearchObject/Schema"), cbSchema->GetValue()); + settings->WriteBool(wxT("SearchObject/Names"), chkNames->GetValue()); + settings->WriteBool(wxT("SearchObject/Definitions"), chkDefinitions->GetValue()); + settings->WriteBool(wxT("SearchObject/Comments"), chkComments->GetValue()); +} + +wxString dlgSearchObject::getMapKeyByValue(wxString search_value) +{ + wxString key = wxEmptyString; + LngMapping::iterator it; + + for (it = aMap.begin(); it != aMap.end(); ++it) + { + if (search_value.IsSameAs(it->second)) + { + key = it->first; + break; + } + } + return key; +} + +void dlgSearchObject::RestoreSettings() +{ + wxString val, mapkey; + bool bVal; + + // Pattern + settings->Read(wxT("SearchObject/Pattern"), &val, wxEmptyString); + txtPattern->SetValue(val); + + // Type + settings->Read(wxT("SearchObject/Type"), &val, wxT("All types")); + mapkey = getMapKeyByValue(val); + if (cbType->FindString(mapkey, true) == wxNOT_FOUND) + cbType->SetValue(getMapKeyByValue(wxT("All types"))); + else + cbType->SetValue(mapkey); + + // Schema + settings->Read(wxT("SearchObject/Schema"), &val, wxT("All schemas")); + if (cbSchema->FindString(val, true) == wxNOT_FOUND) + cbSchema->SetValue(wxT("All schemas")); + else + cbSchema->SetValue(val); + + // names + settings->Read(wxT("SearchObject/Names"), &bVal, true); + chkNames->SetValue(bVal); + + // definitions + settings->Read(wxT("SearchObject/Definitions"), &bVal, false); + chkDefinitions->SetValue(bVal); + + // comments + settings->Read(wxT("SearchObject/Comments"), &bVal, false); + chkComments->SetValue(bVal); +} + +void dlgSearchObject::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("search_object"), HELP_PGADMIN); +} + +void dlgSearchObject::OnSelSearchResult(wxListEvent &ev) +{ + + long row_number = ev.GetIndex(); + + if(lcResults->GetItemTextColour(row_number) == wxColour(128, 128, 128)) + { + /* Result type is not enabled in settings, so we don't search for it in the tree */ + return; + } + + //Taken from: http://wiki.wxwidgets.org/WxListCtrl#Get_the_String_Contents_of_a_.22cell.22_in_a_LC_REPORT_wxListCtrl + wxListItem row_info; + wxString path; + + // Set what row it is (m_itemId is a member of the regular wxListCtrl class) + row_info.m_itemId = row_number; + // Set what column of that row we want to query for information. + row_info.m_col = 2; + // Set text mask + row_info.m_mask = wxLIST_MASK_TEXT; + + // Get the info and store it in row_info variable. + lcResults->GetItem(row_info); + + // Extract the text out that cell + path = row_info.m_text; + + + if(!parent->SetCurrentNode(parent->GetBrowser()->GetRootItem(), path)) + { + wxMessageBox(_("The specified object couldn't be found in the tree.")); + } + +} + +void dlgSearchObject::OnChange(wxCommandEvent &ev) +{ + ToggleBtnSearch(true); +} + +void dlgSearchObject::ToggleBtnSearch(bool enable) +{ + if(enable && + /* When someone searches for operators, the limit of 3 characters is ignored */ + (aMap[cbType->GetValue()] == wxT("Operators") || txtPattern->GetValue().Length() >= 3) && + // At least one search mode enabled + (chkNames->GetValue() || chkDefinitions->GetValue() || chkComments->GetValue())) + { + btnSearch->Enable(); + } + else + btnSearch->Disable(); +} + +void dlgSearchObject::OnSearch(wxCommandEvent &ev) +{ + if (!(chkNames->GetValue() || chkDefinitions->GetValue() || chkComments->GetValue())) + return; // should not happen + + wxBusyCursor wait; + ToggleBtnSearch(false); + if (statusBar) + statusBar->SetStatusText(_("Searching...")); + + wxString txtPatternStr; + if (txtPattern->GetValue().Contains(wxT("%"))) + txtPatternStr = currentdb->GetConnection()->qtDbString(txtPattern->GetValue().Lower()); + else + txtPatternStr = currentdb->GetConnection()->qtDbString(wxT("%") + txtPattern->GetValue().Lower() + wxT("%")); + + /* + Adding objects: + + Create a sql statement which lists all objects of the specified type and add it to the inner statement with an union. + We need four columns: type, objectname, path and nspname (schema name). If object is schemaless, set nspname to NULL. + Parts of the path which has to be translated to the local langauge (because of tree path) must begin with a colon. + Append the type to the combobox and the mapping table in the constructor. */ + + wxString databasePath = parent->GetNodePath(currentdb->GetDatabase()->GetId()); + wxString searchSQL = wxT("SELECT * FROM ( "); + + bool nextMode = false; + // search names + if (chkNames->GetValue()) + { + if (nextMode) + searchSQL += wxT("UNION \n"); + nextMode = true; + searchSQL += wxT("SELECT * FROM ( ") + wxT(" SELECT ") + wxT(" CASE ") + wxT(" WHEN c.relkind = 'r' THEN 'Tables' ") + wxT(" WHEN c.relkind = 'S' THEN 'Sequences' ") + wxT(" WHEN c.relkind IN ('v','m') THEN 'Views' ") + wxT(" ELSE 'should not happen' ") + wxT(" END AS type, c.relname AS objectname, ") + wxT(" ':Schemas/' || n.nspname || '/' || ") + wxT(" CASE ") + wxT(" WHEN c.relkind = 'r' THEN ':Tables' ") + wxT(" WHEN c.relkind = 'S' THEN ':Sequences' ") + wxT(" WHEN c.relkind IN ('v','m') THEN ':Views' ") + wxT(" ELSE 'should not happen' ") + wxT(" END || '/' || c.relname AS path, n.nspname ") + wxT(" FROM pg_class c ") + wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace ") + wxT(" WHERE c.relkind in ('r','S','v','m') ") + wxT(" UNION ") + wxT(" SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname, n.nspname ") + wxT(" FROM pg_index idx ") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid ") + wxT(" JOIN pg_class tab ON tab.oid=indrelid ") + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace ") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i') ") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid) ") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid ") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0) ") + wxT(" WHERE contype IS NULL ") + wxT(" UNION ") + wxT(" SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE case when p.prokind='p' then 'Procedures' else 'Functions' end END AS type, p.proname, ") + wxT(" ':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else case when p.prokind='p' then ':Procedures' else ':Functions' end end || '/' || p.proname, n.nspname ") + wxT(" from pg_proc p ") + wxT(" left join pg_namespace n on p.pronamespace = n.oid ") + wxT(" left join pg_type t on p.prorettype = t.oid ") + wxT(" union ") + wxT(" select 'Schemas', nspname, ':Schemas/' || nspname, nspname from pg_namespace ") + wxT(" union ") + wxT(" select 'Columns', a.attname, ") + wxT(" ':Schemas/' || n.nspname || '/' || ") + wxT(" case ") + wxT(" when t.relkind = 'r' then ':Tables' ") + wxT(" when t.relkind = 'S' then ':Sequences' ") + wxT(" when t.relkind in ('v','m') then ':Views' ") + wxT(" else 'should not happen' ") + wxT(" end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname ") + wxT(" from pg_attribute a ") + wxT(" inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0 ") + wxT(" union ") + wxT(" select 'Constraints', case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, n.nspname from pg_constraint c ") + wxT(" left join pg_class t on c.conrelid = t.oid ") + wxT(" left join pg_class tf on c.confrelid = tf.oid ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid ") + wxT(" union ") + wxT(" select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename, n.nspname from pg_rewrite r ") + wxT(" left join pg_class t on r.ev_class = t.oid ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid ") + wxT(" union ") + wxT(" select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname, n.nspname from pg_trigger tr ") + wxT(" left join pg_class t on tr.tgrelid = t.oid ") + wxT(" left join pg_namespace n on t.relnamespace = n.oid ") + wxT(" where "); + if(currentdb->BackendMinimumVersion(9, 0)) + searchSQL += wxT(" tr.tgisinternal = false "); + else + searchSQL += wxT(" tr.tgisconstraint = false "); + searchSQL += wxT(" union ") + wxT(" SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types/' || t.typname, n.nspname ") + wxT(" FROM pg_type t ") + wxT(" LEFT OUTER JOIN pg_type e ON e.oid=t.typelem ") + wxT(" LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c' ") + wxT(" LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid ") + wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%' "); + if (!settings->GetShowSystemObjects()) + searchSQL += wxT(" AND ct.oid IS NULL\n"); + searchSQL += wxT(" union ") + wxT(" SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname, n.nspname ") + wxT(" FROM pg_conversion co ") + wxT(" JOIN pg_namespace n ON n.oid=co.connamespace ") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0 ") + wxT(" union ") + wxT(" SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), NULL as nspname ") + wxT(" FROM pg_cast ca ") + wxT(" JOIN pg_type st ON st.oid=castsource ") + wxT(" JOIN pg_type tt ON tt.oid=casttarget ") + wxT(" union ") + wxT(" SELECT 'Languages', lanname, ':Languages/' || lanname, NULL as nspname ") + wxT(" FROM pg_language lan ") + wxT(" WHERE lanispl IS TRUE ") + wxT(" union ") + wxT(" SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname, n.nspname ") + wxT(" FROM pg_ts_config cfg ") + wxT(" left join pg_namespace n on cfg.cfgnamespace = n.oid ") + wxT(" union ") + wxT(" SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname, ns.nspname ") + wxT(" FROM pg_ts_dict dict ") + wxT(" left join pg_namespace ns on dict.dictnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname, ns.nspname ") + wxT(" FROM pg_ts_parser prs ") + wxT(" left join pg_namespace ns on prs.prsnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname, ns.nspname ") + wxT(" FROM pg_ts_template tmpl ") + wxT(" left join pg_namespace ns on tmpl.tmplnamespace = ns.oid ") + wxT(" union ") + wxT(" select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname, n.nspname from pg_type t ") + wxT(" inner join pg_namespace n on t.typnamespace = n.oid ") + wxT(" where t.typtype = 'd' ") + wxT(" union ") + wxT(" select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname , ns.nspname from pg_catalog.pg_aggregate ag ") + wxT(" inner join pg_proc pr on ag.aggfnoid = pr.oid ") + wxT(" left join pg_namespace ns on pr.pronamespace = ns.oid ") + wxT(" union ") + wxT(" select case when rolcanlogin = true then 'Login Roles' else 'Group Roles' end, rolname, case when rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname, NULL as nspname ") + wxT(" from pg_roles ") + wxT(" union ") + wxT(" select 'Tablespaces', spcname, ':Tablespaces/'||spcname, NULL as nspname from pg_tablespace ") + wxT(" union ") + wxT(" SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname, ns.nspname ") + wxT(" FROM pg_operator op ") + wxT(" left join pg_namespace ns on op.oprnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname, ns.nspname ") + wxT(" FROM pg_opclass op ") + wxT(" left join pg_namespace ns on op.opcnamespace = ns.oid ") + wxT(" union ") + wxT(" SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname, ns.nspname ") + wxT(" FROM pg_opfamily opf ") + wxT(" left join pg_namespace ns on opf.opfnamespace = ns.oid "); + + if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser()) + { + searchSQL += wxT(" union ") + wxT(" select 'Foreign Data Wrappers', fdwname, ':Foreign Data Wrappers/' || fdwname, NULL as nspname from pg_foreign_data_wrapper ") + wxT(" union ") + wxT(" select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname, NULL as nspname from pg_foreign_server sr ") + wxT(" inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid ") + wxT(" union ") + wxT(" select 'User Mappings', ro.rolname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname || '/:User Mappings/' || ro.rolname, NULL as nspname from pg_user_mapping um ") + wxT(" inner join pg_roles ro on um.umuser = ro.oid ") + wxT(" inner join pg_foreign_server sr on um.umserver = sr.oid ") + wxT(" inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid "); + } + + if(currentdb->BackendMinimumVersion(9, 1)) + { + searchSQL += wxT(" union ") + wxT(" select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname, ns.nspname from pg_foreign_table ft ") + wxT(" inner join pg_class c on ft.ftrelid = c.oid ") + wxT(" inner join pg_namespace ns on c.relnamespace = ns.oid ") + wxT(" union ") + wxT(" select 'Extensions', x.extname, ':Extensions/' || x.extname, NULL as nspname ") + wxT(" FROM pg_extension x ") + wxT(" JOIN pg_namespace n on x.extnamespace=n.oid ") + wxT(" join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name ") + wxT(" union ") + wxT(" SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname, n.nspname ") + wxT(" FROM pg_collation c ") + wxT(" JOIN pg_namespace n ON n.oid=c.collnamespace "); + } + + searchSQL += wxT(") sn \n") + wxT("where lower(sn.objectname) like ") + txtPatternStr + wxT(" \n"); + } // search names + + // search definitions + if (chkDefinitions->GetValue()) + { + if (nextMode) + searchSQL += wxT("UNION \n"); + nextMode = true; + searchSQL += wxT("SELECT * FROM ( ") // Function's source code + wxT(" SELECT CASE WHEN t.typname = 'trigger' THEN 'Trigger Functions' ELSE case when p.prokind='p' then 'Procedures' else 'Functions' end END AS type, p.proname as objectname, ") + wxT(" ':Schemas/' || n.nspname || '/' || case when t.typname = 'trigger' then ':Trigger Functions' else case when p.prokind='p' then ':Procedures' else ':Functions' end end || '/' || p.proname as path, n.nspname ") + wxT(" from pg_proc p ") + wxT(" left join pg_namespace n on p.pronamespace = n.oid ") + wxT(" left join pg_type t on p.prorettype = t.oid ") + wxT("WHERE p.prosrc ILIKE ") + txtPatternStr + wxT(" ") + wxT("UNION ") // Column's type name and default value + wxT("select 'Columns', a.attname, ") + wxT("':Schemas/' || n.nspname || '/' || ") + wxT("case ") + wxT(" when t.relkind = 'r' then ':Tables' ") + wxT(" when t.relkind = 'S' then ':Sequences' ") + wxT(" when t.relkind in ('v','m') then ':Views' ") + wxT(" else 'should not happen' ") + wxT("end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname ") + wxT("from pg_attribute a ") + wxT("inner join pg_type ty on a.atttypid = ty.oid ") + wxT("left join pg_attrdef ad on a.attrelid = ad.adrelid and a.attnum = ad.adnum ") + wxT("inner join pg_class t on a.attrelid = t.oid and t.relkind in ('r','v','m') ") + wxT("left join pg_namespace n on t.relnamespace = n.oid ") + wxT("where a.attnum > 0 ") + wxT(" and (ty.typname ilike ") + txtPatternStr + wxT(" or pg_get_expr(ad.adbin,0) ilike ") + txtPatternStr + wxT(") ") + wxT("UNION ") // View's definition + wxT("SELECT 'Views', c.relname, ") + wxT("':Schemas/' || n.nspname || '/:Views/' || c.relname, n.nspname ") + wxT(" FROM pg_class c ") + wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace ") + wxT(" WHERE c.relkind IN ('v','m') ") + wxT(" and pg_get_viewdef(c.oid) ilike ") + txtPatternStr + wxT(" ") + wxT("UNION ") // Relation's column names except for Views (searched earlier) + wxT("SELECT CASE ") + wxT(" WHEN c.relkind = 'c' THEN 'Types' ") + wxT(" WHEN c.relkind = 'r' THEN 'Tables' ") + wxT(" WHEN c.relkind = 'f' THEN 'Foreign Tables' ") + wxT(" ELSE 'should not happen' ") + wxT(" END AS type, c.relname AS objectname, ") + wxT(" ':Schemas/' || n.nspname || '/' || ") + wxT(" CASE ") + wxT(" WHEN c.relkind = 'c' THEN ':Types' ") + wxT(" WHEN c.relkind = 'r' THEN ':Tables' ") + wxT(" WHEN c.relkind = 'f' THEN ':Foreign Tables' ") + wxT(" ELSE 'should not happen' ") + wxT(" END || '/' || c.relname AS path, n.nspname ") + wxT(" from pg_attribute a ") + wxT(" inner join pg_class c on a.attrelid = c.oid and c.relkind in ('c','r','f') ") + wxT(" left join pg_namespace n on c.relnamespace = n.oid ") + wxT(" where a.attname ilike ") + txtPatternStr + wxT(" "); + // TODO: search for other object's definitions (indexes, constraints and so on) + searchSQL += wxT(") sd \n"); + } // search definitions + + // search comments + if (chkComments->GetValue()) + { + if (nextMode) + searchSQL += wxT("UNION \n"); + nextMode = true; + + wxString pd = wxT("(select pd.objoid, pd.classoid, pd.objsubid, c.relname") + wxT(" from pg_description pd") + wxT(" join pg_class c on pd.classoid = c.oid") + wxT(" where pd.description ilike ") + txtPatternStr + wxT(" UNION ") + wxT("select psd.objoid, psd.classoid, NULL as objsubid, c.relname") + wxT(" from pg_shdescription psd") + wxT(" join pg_class c on psd.classoid = c.oid") + wxT(" where psd.description ilike ") + txtPatternStr + wxT(") "); + + searchSQL += wxT("SELECT * FROM ( "); + if(currentdb->BackendMinimumVersion(8, 4)) // Common Table Expressions are available + { + searchSQL += wxT("with pd as ") + pd; + pd = wxT("pd "); + } + else // use pd as a subquery + pd += wxT(" pd "); + + searchSQL += wxT("SELECT CASE") + wxT(" WHEN c.relkind = 'r' THEN 'Tables'") + wxT(" WHEN c.relkind = 'S' THEN 'Sequences'") + wxT(" WHEN c.relkind IN ('v','m') THEN 'Views'") + wxT(" ELSE 'should not happen'") + wxT(" END AS type, c.relname AS objectname,") + wxT(" ':Schemas/' || n.nspname || '/' ||") + wxT(" CASE") + wxT(" WHEN c.relkind = 'r' THEN ':Tables'") + wxT(" WHEN c.relkind = 'S' THEN ':Sequences'") + wxT(" WHEN c.relkind IN ('v','m') THEN ':Views'") + wxT(" ELSE 'should not happen'") + wxT(" END || '/' || c.relname AS path, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_class c on pd.relname = 'pg_class' and pd.objoid = c.oid") + wxT(" LEFT JOIN pg_namespace n ON n.oid = c.relnamespace") + wxT(" WHERE c.relkind in ('r','S','v','m')") + wxT(" UNION") + wxT(" SELECT 'Indexes', cls.relname, ':Schemas/' || n.nspname || '/:Tables/' || tab.relname || '/:Indexes/' || cls.relname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_class cls ON pd.relname = 'pg_class' and pd.objoid = cls.oid") + wxT(" JOIN pg_index idx ON cls.oid=indexrelid") + wxT(" JOIN pg_class tab ON tab.oid=indrelid") + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=cls.oid") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0)") + wxT(" WHERE contype IS NULL") + wxT(" UNION") + wxT(" select CASE WHEN p_t.typname = 'trigger' THEN 'Trigger Functions' ELSE case when p_.prokind='p' then 'Procedures' else 'Functions' end END AS type,") + wxT(" p_.proname AS objectname,") + wxT(" ':Schemas/' || n.nspname || '/' ||") + wxT(" case when p_t.typname = 'trigger' then ':Trigger Functions/' else case when p_.prokind='p' then ':Procedures/' else ':Functions/' end end || p_.proname AS path, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_proc p_ on pd.relname = 'pg_proc' and pd.objoid = p_.oid and p_.prokind <> 'a'") + wxT(" left join pg_type p_t on p_.prorettype = p_t.oid") + wxT(" left join pg_namespace n on p_.pronamespace = n.oid") + wxT(" union") + wxT(" select 'Schemas', n_.nspname, ':Schemas/' || n_.nspname, n_.nspname") + wxT(" from ") + pd + + wxT(" join pg_namespace n_ on pd.relname = 'pg_namespace' and pd.objoid = n_.oid") + wxT(" union") + wxT(" select 'Columns', a.attname,") + wxT(" ':Schemas/' || n.nspname || '/' ||") + wxT(" case") + wxT(" when t.relkind = 'r' then ':Tables'") + wxT(" when t.relkind = 'S' then ':Sequences'") + wxT(" when t.relkind in ('v','m') then ':Views'") + wxT(" else 'should not happen'") + wxT(" end || '/' || t.relname || '/:Columns/' || a.attname AS path, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_class t on pd.relname = 'pg_class' and pd.objoid = t.oid and t.relkind in ('r','v','m')") + wxT(" join pg_attribute a on a.attrelid = t.oid and pd.objsubid = a.attnum") + wxT(" left join pg_namespace n on t.relnamespace = n.oid where a.attnum > 0") + wxT(" union") + wxT(" select 'Constraints',") + wxT(" case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end,") + wxT(" ':Schemas/' || n.nspname||'/:Tables/'||t.relname||'/:Constraints/'") + wxT(" ||case when tf.relname is null then c.conname else c.conname || ' -> ' || tf.relname end, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_constraint c on pd.relname = 'pg_constraint' and pd.objoid = c.oid") + wxT(" left join pg_class t on c.conrelid = t.oid") + wxT(" left join pg_class tf on c.confrelid = tf.oid") + wxT(" left join pg_namespace n on t.relnamespace = n.oid") + wxT(" union") + wxT(" select 'Rules', r.rulename, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname||'/:Rules/'|| r.rulename, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_rewrite r on pd.relname = 'pg_rewrite' and pd.objoid = r.oid") + wxT(" left join pg_class t on r.ev_class = t.oid") + wxT(" left join pg_namespace n on t.relnamespace = n.oid") + wxT(" union") + wxT(" select 'Triggers', tr.tgname, ':Schemas/' || n.nspname||case when t.relkind in ('v','m') then '/:Views/' else '/:Tables/' end||t.relname || '/:Triggers/' || tr.tgname, n.nspname") + wxT(" from ") + pd + + wxT(" join pg_trigger tr on pd.relname = 'pg_trigger' and pd.objoid = tr.oid") + wxT(" left join pg_class t on tr.tgrelid = t.oid") + wxT(" left join pg_namespace n on t.relnamespace = n.oid WHERE "); + if(currentdb->BackendMinimumVersion(9, 0)) + searchSQL += wxT(" tr.tgisinternal = false "); + else + searchSQL += wxT(" tr.tgisconstraint = false "); + searchSQL += wxT(" union") + wxT(" SELECT 'Types', t.typname, ':Schemas/' || n.nspname || '/:Types/' || t.typname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_type t on pd.relname = 'pg_type' and pd.objoid = t.oid") + wxT(" LEFT OUTER JOIN pg_type e ON e.oid=t.typelem") + wxT(" LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'") + wxT(" LEFT OUTER JOIN pg_namespace n on t.typnamespace = n.oid") + wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%'") + wxT(" union") + wxT(" SELECT 'Conversions', co.conname, ':Schemas/' || n.nspname || '/:Conversions/' || co.conname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_conversion co on pd.relname = 'pg_conversion' and pd.objoid = co.oid") + wxT(" JOIN pg_namespace n ON n.oid=co.connamespace") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=co.oid AND des.objsubid=0") + wxT(" union") + wxT(" SELECT 'Casts', format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), ':Casts/' || format_type(st.oid,NULL) ||'->'|| format_type(tt.oid,tt.typtypmod), NULL as nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_cast ca on pd.relname = 'pg_cast' and pd.objoid = ca.oid") + wxT(" JOIN pg_type st ON st.oid=castsource") + wxT(" JOIN pg_type tt ON tt.oid=casttarget") + wxT(" union") + wxT(" SELECT 'Languages', lanname, ':Languages/' || lanname, NULL as nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_language lan on pd.relname = 'pg_language' and pd.objoid = lan.oid") + wxT(" WHERE lanispl IS TRUE") + wxT(" union") + wxT(" SELECT 'FTS Configurations', cfg.cfgname, ':Schemas/' || n.nspname || '/:FTS Configurations/' || cfg.cfgname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_config cfg on pd.relname = 'pg_ts_config' and pd.objoid = cfg.oid") + wxT(" left join pg_namespace n on cfg.cfgnamespace = n.oid") + wxT(" union") + wxT(" SELECT 'FTS Dictionaries', dict.dictname, ':Schemas/' || ns.nspname || '/:FTS Dictionaries/' || dict.dictname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_dict dict on pd.relname = 'pg_ts_dict' and pd.objoid = dict.oid") + wxT(" left join pg_namespace ns on dict.dictnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'FTS Parsers', prs.prsname, ':Schemas/' || ns.nspname || '/:FTS Parsers/' || prs.prsname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_parser prs on pd.relname = 'pg_ts_parser' and pd.objoid = prs.oid") + wxT(" left join pg_namespace ns on prs.prsnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'FTS Templates', tmpl.tmplname, ':Schemas/' || ns.nspname || '/:FTS Templates/' || tmpl.tmplname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_ts_template tmpl on pd.relname = 'pg_ts_template' and pd.objoid = tmpl.oid") + wxT(" left join pg_namespace ns on tmpl.tmplnamespace = ns.oid") + wxT(" union") + wxT(" select 'Domains', t.typname, ':Schemas/' || n.nspname || '/:Domains/' || t.typname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_type t on pd.relname = 'pg_type' and pd.objoid = t.oid") + wxT(" inner join pg_namespace n on t.typnamespace = n.oid") + wxT(" where t.typtype = 'd'") + wxT(" union") + wxT(" select 'Aggregates', pr.proname, ':Schemas/' || ns.nspname || '/:Aggregates/' || pr.proname, ns.nspname") + wxT(" from ") + pd + + wxT(" join pg_proc pr on pd.relname = 'pg_proc' and pd.objoid = pr.oid") + wxT(" JOIN pg_catalog.pg_aggregate ag on ag.aggfnoid = pr.oid") + wxT(" left join pg_namespace ns on pr.pronamespace = ns.oid") + wxT(" union") + wxT(" select case when r_.rolcanlogin = true then 'Login Roles' else 'Group Roles' end, r_.rolname,") + wxT(" case when r_.rolcanlogin = true then ':Login Roles' else ':Group Roles' end || '/' || rolname, NULL as nspname") + wxT(" from ") + pd + + wxT(" join pg_roles r_ on pd.relname = 'pg_authid' and pd.objoid = r_.oid") + wxT(" union") + wxT(" select 'Tablespaces', ts_.spcname, ':Tablespaces/'||ts_.spcname, NULL as nspname") + wxT(" from ") + pd + + wxT(" JOIN pg_tablespace ts_ on pd.relname = 'pg_tablespace' and pd.objoid = ts_.oid") + wxT(" union") + wxT(" SELECT 'Operators', op.oprname, ':Schemas/' || ns.nspname || '/:Operators/' || op.oprname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_operator op ON pd.relname = 'pg_operator' and pd.objoid = op.oid") + wxT(" left join pg_namespace ns on op.oprnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'Operator Classes', op.opcname, ':Schemas/' || ns.nspname || '/:Operator Classes/' || op.opcname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_opclass op ON pd.relname = 'pg_opclass' and pd.objoid = op.oid") + wxT(" left join pg_namespace ns on op.opcnamespace = ns.oid") + wxT(" union") + wxT(" SELECT 'Operator Families', opf.opfname, ':Schemas/' || ns.nspname || '/:Operator Families/' || opf.opfname, ns.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_opfamily opf ON pd.relname = 'pg_opfamily' and pd.objoid = opf.oid") + wxT(" left join pg_namespace ns on opf.opfnamespace = ns.oid"); + + if(currentdb->BackendMinimumVersion(8, 4) && currentdb->GetConnection()->IsSuperuser()) + { + searchSQL += wxT(" union") + wxT(" select 'Foreign Data Wrappers', fdw.fdwname, ':Foreign Data Wrappers/' || fdw.fdwname, NULL as nspname ") + wxT(" from ") + pd + + wxT(" JOIN pg_foreign_data_wrapper fdw ON pd.relname = 'pg_foreign_data_wrapper' and pd.objoid = fdw.oid") + wxT(" union ") + wxT(" select 'Foreign Server', sr.srvname, ':Foreign Data Wrappers/' || fdw.fdwname || '/:Foreign Servers/' || sr.srvname, NULL as nspname") + wxT(" from ") + pd + + wxT(" JOIN pg_foreign_server sr ON pd.relname = 'pg_foreign_server' and pd.objoid = sr.oid") + wxT(" inner join pg_foreign_data_wrapper fdw on sr.srvfdw = fdw.oid "); + } + + if(currentdb->BackendMinimumVersion(9, 1)) + { + searchSQL += wxT(" union") + wxT(" select 'Foreign Tables', c.relname, ':Schemas/' || ns.nspname || '/:Foreign Tables/' || c.relname, ns.nspname") + wxT(" from ") + pd + + wxT(" JOIN pg_class c ON pd.relname = 'pg_class' and pd.objoid = c.oid") + wxT(" join pg_foreign_table ft on ft.ftrelid = c.oid") + wxT(" inner join pg_namespace ns on c.relnamespace = ns.oid") + wxT(" union") + wxT(" select 'Extensions', x.extname, ':Extensions/' || x.extname, NULL AS nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_extension x ON pd.relname = 'pg_extension' and pd.objoid = x.oid") + wxT(" JOIN pg_namespace n on x.extnamespace=n.oid") + wxT(" join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name") + wxT(" union") + wxT(" SELECT 'Collations', c.collname, ':Schemas/' || n.nspname || '/:Collations/' || c.collname, n.nspname") + wxT(" FROM ") + pd + + wxT(" JOIN pg_collation c ON pd.relname = 'pg_collation' and pd.objoid = c.oid") + wxT(" JOIN pg_namespace n ON n.oid=c.collnamespace"); + } + searchSQL += wxT(") sc \n"); + } // search comments + + searchSQL += wxT(") ii \n"); + + bool nextPredicate = false; + if (cbType->GetValue() != _("All types")) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.type = ") + currentdb->GetConnection()->qtDbString(aMap[cbType->GetValue()]) + wxT(" "); + } + + if (cbSchema->GetSelection() == cbSchemaIdxCurrent && !currentSchema.IsEmpty()) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.nspname = ") + currentdb->GetConnection()->qtDbString(currentSchema) + wxT(" "); + } + else if (cbSchema->GetValue() == _("My schemas")) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.nspname IN (SELECT n.nspname FROM pg_namespace n WHERE n.nspowner = (SELECT u.usesysid FROM pg_user u WHERE u.usename = ") + + currentdb->GetConnection()->qtDbString(currentdb->GetConnection()->GetUser()) + wxT(")) "); + } + else if (cbSchema->GetValue() != _("All schemas")) + { + searchSQL += (nextPredicate) ? wxT("AND ") : wxT("WHERE "); + nextPredicate = true; + searchSQL += wxT("ii.nspname = ") + currentdb->GetConnection()->qtDbString(cbSchema->GetValue()) + wxT(" "); + } + + searchSQL += wxT("ORDER BY 1, 2, 3"); + + pgSet *set = currentdb->GetConnection()->ExecuteSet(searchSQL); + int i = 0; + if(set) + { + lcResults->DeleteAllItems(); + + while(!set->Eof()) + { + wxString objectType = set->GetVal(wxT("type")); + wxString objectName = set->GetVal(wxT("objectname")); + wxString ItemPath; + + + /* Login Roles, Group Roles and Tablespaces are "outside" the database, so we have to adjust the path */ + if(objectType == wxT("Login Roles") || objectType == wxT("Group Roles") || objectType == wxT("Tablespaces")) + { + wxStringTokenizer tkz(databasePath, wxT("/")); + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + if(token == _("Databases")) + break; + ItemPath += token + wxT("/"); + } + ItemPath += set->GetVal(wxT("path")); + } + else + { + ItemPath = databasePath + wxT("/") + set->GetVal(wxT("path")); + } + + if(ItemPath.Contains(wxT("Schemas/information_schema"))) + { + /* In information Schema only views and columns are displayed, nothing else */ + if(objectType == wxT("Views") || objectType == wxT("Columns")) + { + ItemPath.Replace(wxT(":Schemas/information_schema"), wxT(":Catalogs/ANSI/:Catalog Objects")); + ItemPath.Replace(wxT(":Views/"), wxT("")); + } + else + { + set->MoveNext(); + continue; + } + } + + if(ItemPath.Contains(wxT("Schemas/pg_catalog"))) + { + ItemPath.Replace(wxT(":Schemas/pg_catalog"), wxT(":Catalogs/PostgreSQL")); + } + + wxListItem item; + item.SetId(i); + lcResults->InsertItem(item); + + wxString locTypeStr = wxGetTranslation(set->GetVal(wxT("type"))); + + /* Check if viewing of the specified object is enabled in settings */ + if(!settings->GetDisplayOption(locTypeStr)) + { + lcResults->SetItemTextColour(i, wxColour(128, 128, 128)); + } + + lcResults->SetItem(i, 0, locTypeStr); + lcResults->SetItem(i, 1, objectName); + lcResults->SetItem(i, 2, TranslatePath(ItemPath)); + set->MoveNext(); + i++; + } + delete set; + } + + if(lcResults->GetItemCount() > 0) + { + lcResults->SetColumnWidth(0, wxLIST_AUTOSIZE); + lcResults->SetColumnWidth(1, wxLIST_AUTOSIZE); + lcResults->SetColumnWidth(2, wxLIST_AUTOSIZE); + } + + if (statusBar) + { + if (i > 0) + statusBar->SetStatusText(wxString::Format(wxPLURAL("Found %d item", "Found %d items", i), i)); + else + statusBar->SetStatusText(_("Nothing was found")); + } + + ToggleBtnSearch(true); +} + +wxString dlgSearchObject::TranslatePath(wxString &path) +{ + /* Translate a path, but only word that start's with a colon (:) */ + wxStringTokenizer tkz(path, wxT("/")); + wxString newPath; + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + if(token.StartsWith(wxT(":"))) + { + token = wxGetTranslation(token.AfterFirst(':')); + } + newPath = newPath + token.Trim() + wxT("/"); + } + return newPath.BeforeLast('/'); + +} + +void dlgSearchObject::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + +searchObjectFactory::searchObjectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Search objects...\tCtrl-G"), _("Search database for specific objects")); +} + +wxWindow *searchObjectFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgSearchObject *so = new dlgSearchObject(form, obj->GetDatabase(), obj); + so->Show(); + return 0; +} + +bool searchObjectFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); +} diff --git a/dlg/dlgSelectConnection.cpp b/dlg/dlgSelectConnection.cpp new file mode 100644 index 0000000..11b8ef8 --- /dev/null +++ b/dlg/dlgSelectConnection.cpp @@ -0,0 +1,382 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectConnection.cpp - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "frm/frmMain.h" +#include "dlg/dlgSelectConnection.h" +#include "dlg/dlgConnect.h" +#include "schema/pgServer.h" +#include "images/connect.pngc" + +#define CTRLID_CBSERVER 4242 +#define CTRLID_CBDATABASE 4243 +#define CTRLID_CBUSERNAME 4244 +#define CTRLID_CBROLENAME 4245 + +BEGIN_EVENT_TABLE(dlgSelectConnection, DialogWithHelp) + EVT_COMBOBOX(CTRLID_CBSERVER, dlgSelectConnection::OnChangeServer) + EVT_COMBOBOX(CTRLID_CBDATABASE, dlgSelectConnection::OnChangeDatabase) + EVT_TEXT(CTRLID_CBSERVER, dlgSelectConnection::OnTextChange) + EVT_TEXT(CTRLID_CBDATABASE, dlgSelectConnection::OnTextChange) + EVT_TEXT(CTRLID_CBUSERNAME, dlgSelectConnection::OnTextChange) + EVT_BUTTON (wxID_OK, dlgSelectConnection::OnOK) + EVT_BUTTON (wxID_CANCEL, dlgSelectConnection::OnCancel) +END_EVENT_TABLE() + +#define stUsername CTRL_STATIC("stUsername") + + +dlgSelectConnection::dlgSelectConnection(wxWindow *parent, frmMain *form) : + DialogWithHelp(form) +{ + long style = wxCB_DROPDOWN; + remoteServer = NULL; + + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("dlgSelectConnection")); + + SetIcon(*connect_png_ico); + RestorePosition(); + + if (form != NULL) + style |= wxCB_READONLY; + + cbServer = new ctlComboBoxFix(this, CTRLID_CBSERVER, ConvertDialogToPixels(wxPoint(65, 5)), ConvertDialogToPixels(wxSize(135, 12)), style); + cbDatabase = new wxComboBox(this, CTRLID_CBDATABASE, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 20)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); + cbUsername = new wxComboBox(this, CTRLID_CBUSERNAME, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 35)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); + cbRolename = new wxComboBox(this, CTRLID_CBROLENAME, wxEmptyString, ConvertDialogToPixels(wxPoint(65, 50)), ConvertDialogToPixels(wxSize(135, 12)), wxArrayString(), style); + + if (form == NULL) + { + cbServer->SetValue(settings->Read(wxT("QuickConnect/server"), wxEmptyString)); + cbDatabase->SetValue(settings->Read(wxT("QuickConnect/database"), wxEmptyString)); + cbUsername->SetValue(settings->Read(wxT("QuickConnect/username"), wxEmptyString)); + cbRolename->SetValue(settings->Read(wxT("QuickConnect/rolename"), wxEmptyString)); + } + + btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); +} + + +dlgSelectConnection::~dlgSelectConnection() +{ + SavePosition(); +} + + +wxString dlgSelectConnection::GetHelpPage() const +{ + return wxT("connect"); +} + + +void dlgSelectConnection::OnChangeServer(wxCommandEvent &ev) +{ + int item; + wxString olddatabase, oldusername; + + if (!GetServer()) + return; + + // Keep old value for these comboboxes so that we can restore them if needed + olddatabase = cbDatabase->GetValue(); + oldusername = cbUsername->GetValue(); + + // Clear the comboboxes + cbDatabase->Clear(); + cbUsername->Clear(); + cbRolename->Clear(); + + int sel = cbServer->GetCurrentSelection(); + if (sel >= 0) + { + remoteServer = (pgServer *)cbServer->wxItemContainer::GetClientData(sel); + + if (!remoteServer->GetConnected()) + { + remoteServer->Connect(mainForm, remoteServer->GetStorePwd()); + if (!remoteServer->GetConnected()) + { + wxLogError(wxT("%s"), remoteServer->GetLastError().c_str()); + return; + } + } + if (remoteServer->GetConnected()) + { + pgSetIterator set1(remoteServer->GetConnection(), + wxT("SELECT DISTINCT datname\n") + wxT(" FROM pg_database db\n") + wxT(" WHERE datallowconn ORDER BY datname")); + + item = 0; + while(set1.RowsLeft()) + { + cbDatabase->Append(set1.GetVal(wxT("datname"))); + if (set1.GetVal(wxT("datname")) == olddatabase) + item = cbDatabase->GetCount() - 1; + } + + if (cbDatabase->GetCount()) + cbDatabase->SetSelection(item); + + pgSetIterator set2(remoteServer->GetConnection(), + wxT("SELECT DISTINCT usename\n") + wxT("FROM pg_user db\n") + wxT("ORDER BY usename")); + + item = 0; + while(set2.RowsLeft()) + { + cbUsername->Append(set2.GetVal(wxT("usename"))); + if (set2.GetVal(wxT("usename")) == oldusername) + item = cbDatabase->GetCount() - 1; + } + + if (cbUsername->GetCount()) + cbUsername->SetSelection(item); + + if (remoteServer->GetConnection()->BackendMinimumVersion(8, 1)) + { + pgSetIterator set3(remoteServer->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set3.RowsLeft()) + cbRolename->Append(set3.GetVal(wxT("rolname"))); + + cbRolename->Enable(true); + } + else + cbRolename->Disable(); + + cbRolename->SetValue(wxEmptyString); + } + + } + OnChangeDatabase(ev); +} + + +wxString dlgSelectConnection::GetDatabase() +{ + return cbDatabase->GetValue(); +} + +wxString dlgSelectConnection::GetServerName() +{ + return cbServer->GetValue(); +} + +void dlgSelectConnection::OnChangeDatabase(wxCommandEvent &ev) +{ + btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); +} + +void dlgSelectConnection::OnTextChange(wxCommandEvent &ev) +{ + btnOK->Enable(cbServer->GetValue().Length() > 0 && cbDatabase->GetValue().Length() > 0 && cbUsername->GetValue().Length() > 0); +} + +void dlgSelectConnection::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + + if (cbDatabase->GetCurrentSelection() == wxNOT_FOUND || + cbServer->GetCurrentSelection() == wxNOT_FOUND) + remoteServer = NULL; + + EndModal(wxID_OK); +} + + +void dlgSelectConnection::OnCancel(wxCommandEvent &ev) +{ + EndModal(wxID_CANCEL); +} + +pgConn *dlgSelectConnection::CreateConn(wxString &applicationname, bool &createdNew) +{ + /* gcc requires that we store this in temporary variables for some reason... */ + wxString serv = cbServer->GetValue(); + wxString db = cbDatabase->GetValue(); + + createdNew = true; + + long port = 0; + if (serv.Find(':') > 0) + { + if (!serv.Mid(serv.Find(':') + 1).ToLong(&port)) + { + wxMessageBox(_("Invalid port number specified.")); + return NULL; + } + serv = serv.Mid(0, serv.Find(':')); + } + + wxString user = cbUsername->GetValue(); + wxString role = cbRolename->GetValue(); + + if (cbConnection) + { + /* Check if selected combination already exists */ + for (unsigned int index = 0; index < cbConnection->GetCount() - 1; index++) + { + pgConn *conn = (pgConn *)cbConnection->GetClientData(index); + if (conn && + conn->GetHost() == serv && + conn->GetPort() == port && + conn->GetUser() == user && + conn->GetRole() == role && + conn->GetDbname() == db) + { + createdNew = false; + return conn; + } + } + } + + + int sslmode = remoteServer ? remoteServer->GetSSL() : 0; + + return CreateConn(serv, db, user, port, role, sslmode, applicationname, true); +} + +pgConn *dlgSelectConnection::CreateConn(wxString &server, wxString &dbname, wxString &username, int port, wxString &rolename, int sslmode, wxString &applicationname, bool writeMRU) +{ + pgConn *newconn; + newconn = new pgConn(server, wxEmptyString, wxEmptyString, dbname, username, wxT(""), port, rolename, sslmode, 0, applicationname); + if (newconn->GetStatus() != PGCONN_OK && + newconn->GetLastError().Cmp(wxString(PQnoPasswordSupplied, wxConvUTF8)) == 0) + { + /* Needs password */ + delete newconn; + newconn = NULL; + + wxString txt; + txt.Printf(_("Please enter password for user %s\non server %s"), username.c_str(), server.c_str()); + dlgConnect dlg(NULL, txt, false); + if (dlg.Go() != wxID_OK) + return NULL; + + newconn = new pgConn(server, wxEmptyString, wxEmptyString, dbname, username, dlg.GetPassword(), port, rolename, sslmode, 0, applicationname); + } + + if (newconn) + { + if (newconn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + newconn->GetLastError()); + return NULL; + } + + if (writeMRU) + { + settings->Write(wxT("QuickConnect/server"), cbServer->GetValue()); + settings->Write(wxT("QuickConnect/database"), cbDatabase->GetValue()); + settings->Write(wxT("QuickConnect/username"), cbUsername->GetValue()); + settings->Write(wxT("QuickConnect/rolename"), cbRolename->GetValue()); + } + } + return newconn; +} + +int dlgSelectConnection::Go(pgConn *conn, wxBitmapComboBox *cb) +{ + bool foundServer = false; + cbConnection = cb; + if (mainForm != NULL) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + cbServer->Append(server->GetIdentifier(), (void *)server); + if (server->GetConnected() && + server->GetConnection()->GetHost() == conn->GetHost() && + server->GetConnection()->GetPort() == conn->GetPort()) + { + cbServer->SetSelection(cbServer->GetCount() - 1); + remoteServer = server; + foundServer = true; + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + + cbServer->SetFocus(); + + wxCommandEvent ev; + OnChangeServer(ev); + + if (foundServer) + { + + unsigned int index = 0; + for (; index < cbDatabase->GetCount(); index++) + { + if (cbDatabase->GetString(index) == conn->GetDbname()) + { + cbDatabase->SetSelection(index); + break; + } + } + for (index = 0; index < cbUsername->GetCount(); index++) + { + if (cbUsername->GetString(index) == conn->GetUser()) + { + cbUsername->SetSelection(index); + break; + } + } + for (index = 0; index < cbRolename->GetCount(); index++) + { + if (cbRolename->GetString(index) == conn->GetRole()) + { + cbRolename->SetSelection(index); + break; + } + } + } + + return ShowModal(); +} + diff --git a/dlg/dlgSelectDatabase.cpp b/dlg/dlgSelectDatabase.cpp new file mode 100644 index 0000000..f4a4d08 --- /dev/null +++ b/dlg/dlgSelectDatabase.cpp @@ -0,0 +1,325 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectDatabase.cpp - Database Selection for connection string +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +#include + +#include "utils/misc.h" +#include "dlg/dlgSelectDatabase.h" +#include "schema/pgServer.h" +#include "schema/pgDatabase.h" +#include "frm/frmMain.h" + +extern frmMain *winMain; +wxWindowID TCSERVER_ID = ::wxNewId(); + +BEGIN_EVENT_TABLE(dlgSelectDatabase, wxDialog) + EVT_TREE_ITEM_ACTIVATED (TCSERVER_ID, dlgSelectDatabase::OnSelActivate) + EVT_TREE_SEL_CHANGED (TCSERVER_ID, dlgSelectDatabase::OnSelect) +END_EVENT_TABLE() + + +dlgSelectDatabase::dlgSelectDatabase(wxWindow *parent, int id, const wxPoint &pos, const wxSize &size, long style): + wxDialog(parent, id, wxT("Select Database"), pos, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) +{ + +#ifdef __WXMSW__ + SetWindowStyleFlag(GetWindowStyleFlag() & ~wxMAXIMIZE_BOX); +#endif + + wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL); + + tcServers = new wxTreeCtrl(this, TCSERVER_ID); + mainSizer->Add(tcServers, 1, wxEXPAND, 0); + + wxBoxSizer *bottomSizer = new wxBoxSizer(wxHORIZONTAL); + + bottomSizer->AddStretchSpacer(); + + wxButton *btnOk = new wxButton(this, wxID_OK, wxT("&OK")); + bottomSizer->Add(btnOk); + + wxButton *btnCANCEL = new wxButton(this, wxID_CANCEL, wxT("&Cancel")); + bottomSizer->Add(btnCANCEL, 0, wxLEFT, 10); + + mainSizer->Add(bottomSizer, 0, wxALL | wxALIGN_RIGHT, 5); + SetSizer(mainSizer); + + SetSize(wxSize(200, 240)); + + Layout(); + Centre(); + + Initialize(); +} + +void dlgSelectDatabase::Initialize() +{ + // Add the root node + pgServerCollection *serversObj = new pgServerCollection(serverFactory.GetCollectionFactory()); + wxTreeItemId rootItemID = tcServers->AddRoot(wxGetTranslation(serverFactory.GetCollectionFactory()->GetTypeName()), + serversObj->GetIconId(), -1, serversObj); + tcServers->SetImageList(imageList); + + ctlTree *browser = winMain->GetBrowser(); + + wxTreeItemId servers = tcServers->GetRootItem(); + + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxCookieType cookie; + wxTreeItemId serverItem = browser->GetFirstChild(folderitem, cookie); + + wxTreeItemId tcGroupsItem = tcServers->AppendItem(rootItemID, browser->GetItemText(folderitem), serversObj->GetIconId()); + while (serverItem) + { + pgServer *server = (pgServer *)browser->GetObject(serverItem); + + if (server && server->IsCreatedBy(serverFactory)) + { + dlgSelDBNode *cnInfo = new dlgSelDBNode(server); + wxTreeItemId itm = tcServers->AppendItem(tcGroupsItem, server->GetFullName(), server->GetIconId(), -1, cnInfo); + + pgConn *conn = server->connection(); + + if (conn && conn->IsAlive()) + { + pgSet *res = conn->ExecuteSet(wxT("SELECT datname, datallowconn FROM pg_catalog.pg_database")); + if (res) + { + while (!res->Eof()) + { + if (res->GetBool(wxT("datallowconn"))) + { + dlgSelDBNode *cnInfo = new dlgSelDBNode(server, res->GetVal(wxT("datname"))); + tcServers->AppendItem(itm, cnInfo->getDatabase(), databaseFactory.GetIconId(), -1, cnInfo); + } + + res->MoveNext(); + } + delete res; + } + } + } + + serverItem = browser->GetNextChild(folderitem, cookie); + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + + tcServers->Expand(servers); + selectedConn = NULL; +} + +void dlgSelectDatabase::OnSelect(wxTreeEvent &ev) +{ + wxTreeItemId sel = tcServers->GetSelection(); + + if (sel.IsOk() && sel != tcServers->GetRootItem() && tcServers->GetItemParent(sel) != tcServers->GetRootItem()) + { + selectedConn = (dlgSelDBNode *)tcServers->GetItemData(sel); + } + else + { + selectedConn = NULL; + } +} + +void dlgSelectDatabase::OnSelActivate(wxTreeEvent &ev) +{ + wxTreeItemId selID = tcServers->GetSelection(); + + if (selID.IsOk() && selID != tcServers->GetRootItem()) + { + selectedConn = (dlgSelDBNode *)tcServers->GetItemData(selID); + + if (selectedConn->dbname.IsEmpty() && tcServers->GetChildrenCount(selID, false) == 0) + { + winMain->ReconnectServer(selectedConn->server, true); + + pgConn *conn = selectedConn->server->connection(); + if (conn && conn->GetStatus() == PGCONN_OK) + { + pgSet *res = conn->ExecuteSet(wxT("SELECT datname, datallowconn FROM pg_catalog.pg_database")); + if (res) + { + while (!res->Eof()) + { + if (res->GetBool(wxT("datallowconn"))) + { + dlgSelDBNode *cnInfo = new dlgSelDBNode(selectedConn->server, res->GetVal(wxT("datname"))); + tcServers->AppendItem(selID, cnInfo->getDatabase(), databaseFactory.GetIconId(), -1, cnInfo); + } + + res->MoveNext(); + } + } + delete res; + } + tcServers->Expand(selID); + } + } + else + { + selectedConn = NULL; + } +} + + +wxString dlgSelectDatabase::getConnInfo() +{ + if (selectedConn) + { + return selectedConn->getConnectionString(); + } + + return wxEmptyString; +} + +bool dlgSelectDatabase::getValidConnectionString(wxString connStr, wxString &resultStr) +{ + wxString user; + wxString dbname; + wxString host; + unsigned long port = 0; + wxString password; + unsigned long connection_timeout = 0; + + wxRegEx propertyExp; + + // Remove white-spaces ahead the '=" + bool res = propertyExp.Compile(wxT("(([ ]*[\t]*)+)=")); + propertyExp.ReplaceAll(&connStr, wxT("=")); + + // Remove white-spaces after the '=" + res = propertyExp.Compile(wxT("=(([ ]*[\t]*)+)")); + propertyExp.ReplaceAll(&connStr, wxT("=")); + wxArrayString tokens = wxStringTokenize(connStr, wxT("\t \n\r")); + + unsigned int index = 0; + while (index < tokens.Count()) + { + wxString prop, value; + + // Find pairs + // i.e. user=xxx + // password=xxx + wxArrayString pairs = wxStringTokenize(tokens[index++], wxT("=")); + + // pair must exist in pair=value format + if (pairs.GetCount() != 2) + return false; + + prop = pairs[0]; + value = pairs[1]; + + if (prop.CmpNoCase(wxT("user")) == 0) + user = value; + else if (prop.CmpNoCase(wxT("host")) == 0 || prop.CmpNoCase(wxT("hostAddr")) == 0) + host = value; + else if (prop.CmpNoCase(wxT("port")) == 0) + { + if (!value.ToULong(&port)) + // port must be an unsigned integer + return false; + } + else if (prop.CmpNoCase(wxT("password")) == 0) + password = value; + else if (prop.CmpNoCase(wxT("connection_timeout")) == 0) + { + if (!value.ToULong(&connection_timeout)) + // connection timeout must be an unsigned interger + return false; + } + else if (prop.CmpNoCase(wxT("dbname")) == 0) + dbname = value; + else + // Not valid property found + return false; + } + + if (dbname.IsEmpty()) + return false; + + if (!user.IsEmpty()) + resultStr = wxT("user=") + user + wxT(" "); + + if (!host.IsEmpty()) + { + resultStr += wxT("host=") + host + wxT(" "); + } + + + if (!resultStr.IsEmpty()) + resultStr += wxT(" "); + resultStr += wxT("dbname=") + dbname + wxT(" "); + + if (port != 0) + { + wxString portStr; + portStr.Printf(wxT("port=%ld"), port); + resultStr += portStr + wxT(" "); + } + + + if (connection_timeout != 0) + { + wxString strConnTimeOut; + strConnTimeOut.Printf(wxT("connection_timeout=%ld"), connection_timeout); + resultStr += strConnTimeOut + wxT(" "); + } + + if (!password.IsEmpty()) + { + resultStr += wxT("password=") + password + wxT(" "); + } + + resultStr = resultStr.Trim(); + + return true; +} + +dlgSelDBNode::dlgSelDBNode (pgServer *_server, const wxString &_dbname) +{ + server = _server; + dbname = _dbname; +} + +wxString dlgSelDBNode::getConnectionString() +{ + if (dbname.IsEmpty()) + return wxEmptyString; + + pgConn *conn = server->connection(); + wxString connStr; + + if (conn && conn->GetStatus() == PGCONN_OK) + { + connStr += wxT("user=") + conn->GetUser() + wxT(" "); + connStr += wxT("host=") + conn->GetHostName() + wxT(" "); + + wxString port; + port.Printf(wxT("port=%d "), conn->GetPort()); + connStr += port; + + connStr += wxT("dbname=") + dbname; + } + + return connStr; +} + diff --git a/dlg/dlgSequence.cpp b/dlg/dlgSequence.cpp new file mode 100644 index 0000000..e58e9dc --- /dev/null +++ b/dlg/dlgSequence.cpp @@ -0,0 +1,386 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSequence.cpp - PostgreSQL Sequence Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "dlg/dlgSequence.h" + +#include "schema/pgSchema.h" +#include "schema/pgSequence.h" +#include "ctl/ctlSeclabelPanel.h" + + +#define txtIncrement CTRL_TEXT("txtIncrement") +#define cbOwner CTRL_COMBOBOX2("cbOwner") +#define txtMin CTRL_TEXT("txtMin") +#define txtMax CTRL_TEXT("txtMax") +#define txtStart CTRL_TEXT("txtStart") +#define txtCache CTRL_TEXT("txtCache") +#define chkCycled CTRL_CHECKBOX("chkCycled") +#define stStart CTRL_STATIC("stStart") + +// pointer to controls + +BEGIN_EVENT_TABLE(dlgSequence, dlgSecurityProperty) + EVT_TEXT(XRCID("txtStart"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtMin"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtMax"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtCache"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtIncrement"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkCycled"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *pgSequenceFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSequence(this, frame, (pgSequence *)node, (pgSchema *)parent); +} + + +dlgSequence::dlgSequence(pgaFactory *f, frmMain *frame, pgSequence *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgSequence"), wxT("INSERT,SELECT,UPDATE,DELETE,RULE,REFERENCES,TRIGGER,USAGE"), "arwdRxtU") +{ + schema = sch; + sequence = node; + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgSequence::GetObject() +{ + return sequence; +} + + +int dlgSequence::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(sequence); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgSequence::OnChange)); + } + else + seclabelPage->Disable(); + + if (sequence) + { + // edit mode + txtIncrement->SetValue(sequence->GetIncrement().ToString()); + txtStart->SetValue(sequence->GetLastValue().ToString()); + txtMin->SetValue(sequence->GetMinValue().ToString()); + txtMax->SetValue(sequence->GetMaxValue().ToString()); + txtCache->SetValue(sequence->GetCacheValue().ToString()); + chkCycled->SetValue(sequence->GetCycled()); + + stStart->SetLabel(_("Current value")); + + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + + if (!connection->BackendMinimumVersion(7, 4)) + { + txtIncrement->Disable(); + txtMin->Disable(); + txtMax->Disable(); + txtCache->Disable(); + chkCycled->Disable(); + } + } + else + { + // create mode + txtIncrement->SetValidator(numericValidator); + txtMin->SetValidator(numericValidator); + txtMax->SetValidator(numericValidator); + txtCache->SetValidator(numericValidator); + } + + txtStart->SetValidator(numericValidator); + + // Find, and disable the USAGE ACL option if we're on pre 8.2 + // 8.2+ only supports SELECT, UPDATE and USAGE + if (!connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("USAGE"))) + { + wxLogError(_("Failed to disable the USAGE privilege checkbox!")); + } + } + else + { + if (!DisablePrivilege(wxT("INSERT"))) + { + wxLogError(_("Failed to disable the INSERT privilege checkbox!")); + } + if (!DisablePrivilege(wxT("DELETE"))) + { + wxLogError(_("Failed to disable the DELETE privilege checkbox!")); + } + if (!DisablePrivilege(wxT("RULE"))) + { + wxLogError(_("Failed to disable the RULE privilege checkbox!")); + } + if (!DisablePrivilege(wxT("REFERENCES"))) + { + wxLogError(_("Failed to disable the REFERENCES privilege checkbox!")); + } + if (!DisablePrivilege(wxT("TRIGGER"))) + { + wxLogError(_("Failed to disable the TRIGGER privilege checkbox!")); + } + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgSequence::CreateObject(pgCollection *collection) +{ + pgObject *obj = sequenceFactory.CreateObjects(collection, 0, + wxT(" AND relname=") + qtDbString(GetName()) + + wxT("\n AND relnamespace=") + schema->GetOidStr()); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgSequence::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgSequence::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + bool maxOk = true; + + if (statusBar) + statusBar->SetStatusText(wxEmptyString); + + // Check we don't overflow INT64_MAX + if (doesOverflowBigInt(txtCache->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid cache value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtMax->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid maximum value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtMin->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid minimum value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtStart->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid current value")); + maxOk = false; + } + + if (doesOverflowBigInt(txtIncrement->GetValue(), !sequence)) + { + if (statusBar) + statusBar->SetStatusText(_("Invalid increment value")); + maxOk = false; + } + + if (sequence) + { + enable = maxOk && (name != sequence->GetName() + || cbSchema->GetValue() != sequence->GetSchema()->GetName() + || txtComment->GetValue() != sequence->GetComment() + || cbOwner->GetValue() != sequence->GetOwner() + || txtStart->GetValue() != sequence->GetLastValue().ToString() + || txtMin->GetValue() != sequence->GetMinValue().ToString() + || txtMax->GetValue() != sequence->GetMaxValue().ToString() + || txtCache->GetValue() != sequence->GetCacheValue().ToString() + || txtIncrement->GetValue() != sequence->GetIncrement().ToString() + || chkCycled->GetValue() != sequence->GetCycled()); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + EnableOK(enable); + } + else + { + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable && maxOk); + } +} + +bool dlgSequence::doesOverflowBigInt(const wxString &str, bool emptyAllowed) +{ + if (emptyAllowed && str.IsEmpty()) + return false; + + if (NumToStr(StrToLongLong(str)) != str) + return true; + + return false; +} + +wxString dlgSequence::GetSql() +{ + wxString sql, name; + + if (sequence) + { + // edit mode + name = GetName(); + + if (connection->BackendMinimumVersion(8, 3)) + AppendNameChange(sql, wxT("SEQUENCE ") + sequence->GetQuotedFullIdentifier()); + else + AppendNameChange(sql, wxT("TABLE ") + sequence->GetQuotedFullIdentifier()); + + if (connection->BackendMinimumVersion(8, 4)) + AppendOwnerChange(sql, wxT("SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name)); + else + AppendOwnerChange(sql, wxT("TABLE ") + schema->GetQuotedPrefix() + qtIdent(name)); + + // This is where things get hairy. Per some thought by Horvath Gabor, + // we need to adjust the min/max sequence values, and the current + // value per the rules: + // + // 1 Any ALTER SEQUENCE MIN/MAXVALUE statements that widen the range + // 2 SETVAL + // 3 Any ALTER SEQUENCE MIN/MAXVALUE statements that narrow the range. + // + // We'll change any other options at the end. + wxString tmp; + + // MIN/MAX changes that widen the range. + if (connection->BackendMinimumVersion(7, 4)) + { + tmp = wxEmptyString; + if (txtMin->GetValue().IsEmpty()) + tmp += wxT("\n NO MINVALUE"); + else if (StrToLongLong(txtMin->GetValue()) < sequence->GetMinValue()) + tmp += wxT("\n MINVALUE ") + txtMin->GetValue(); + + if (txtMax->GetValue().IsEmpty()) + tmp += wxT("\n NO MAXVALUE"); + else if (StrToLongLong(txtMax->GetValue()) > sequence->GetMaxValue()) + tmp += wxT("\n MAXVALUE ") + txtMax->GetValue(); + + if (!tmp.IsEmpty()) + { + sql += wxT("ALTER SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name) + + tmp + wxT(";\n"); + } + } + + // The new sequence value + if (txtStart->GetValue() != sequence->GetLastValue().ToString()) + sql += wxT("SELECT setval('") + qtIdent(schema->GetName()) + wxT(".") + qtIdent(name) + + wxT("', ") + txtStart->GetValue() + + wxT(", true);\n"); + + // Min/Max changes that narrow the ranges, as well as other changes. + if (connection->BackendMinimumVersion(7, 4)) + { + tmp = wxEmptyString; + if (txtIncrement->GetValue() != sequence->GetIncrement().ToString()) + tmp += wxT("\n INCREMENT ") + txtIncrement->GetValue(); + + if ((!txtMin->GetValue().IsEmpty()) && StrToLongLong(txtMin->GetValue()) > sequence->GetMinValue()) + tmp += wxT("\n MINVALUE ") + txtMin->GetValue(); + + if ((!txtMax->GetValue().IsEmpty()) && StrToLongLong(txtMax->GetValue()) < sequence->GetMaxValue()) + tmp += wxT("\n MAXVALUE ") + txtMax->GetValue(); + + if (txtCache->GetValue() != sequence->GetCacheValue().ToString()) + tmp += wxT("\n CACHE ") + txtCache->GetValue(); + + if (chkCycled->GetValue() != sequence->GetCycled()) + { + if (chkCycled->GetValue()) + tmp += wxT("\n CYCLE"); + else + tmp += wxT("\n NO CYCLE"); + } + + if (!tmp.IsEmpty()) + { + sql += wxT("ALTER SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name) + + tmp + wxT(";\n"); + } + + if (connection->BackendMinimumVersion(8, 1)) + AppendSchemaChange(sql, wxT("SEQUENCE ") + schema->GetQuotedPrefix() + qtIdent(name)); + } + } + else + { + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + // create mode + sql = wxT("CREATE SEQUENCE ") + name; + if (chkCycled->GetValue()) + sql += wxT(" CYCLE"); + AppendIfFilled(sql, wxT("\n INCREMENT "), txtIncrement->GetValue()); + AppendIfFilled(sql, wxT("\n START "), txtStart->GetValue()); + AppendIfFilled(sql, wxT("\n MINVALUE "), txtMin->GetValue()); + AppendIfFilled(sql, wxT("\n MAXVALUE "), txtMax->GetValue()); + AppendIfFilled(sql, wxT("\n CACHE "), txtCache->GetValue()); + sql += wxT(";\n"); + + if (cbOwner->GetGuessedSelection() > 0) + { + if (connection->BackendMinimumVersion(8, 4)) + { + AppendOwnerChange(sql, wxT("SEQUENCE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + } + else + { + AppendOwnerChange(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + } + } + } + + if (!connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + else + sql += GetGrant(wxT("rwU"), wxT("SEQUENCE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + AppendComment(sql, wxT("SEQUENCE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), sequence); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("SEQUENCE"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + return sql; +} + +void dlgSequence::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgServer.cpp b/dlg/dlgServer.cpp new file mode 100644 index 0000000..4576c3e --- /dev/null +++ b/dlg/dlgServer.cpp @@ -0,0 +1,745 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgServer.cpp - PostgreSQL Database Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +// Must be after pgAdmin3.h or MSVC++ complains +#include +#include +#include + +// Other app headers +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "dlg/dlgServer.h" +#include "schema/pgDatabase.h" + +// pointer to controls +#define txtHostAddr CTRL_TEXT("txtHostAddr") +#define txtDescription CTRL_TEXT("txtDescription") +#define txtService CTRL_TEXT("txtService") +#define txtServiceID CTRL_TEXT("txtServiceID") +#define cbDatabase CTRL_COMBOBOX("cbDatabase") +#define txtPort CTRL_TEXT("txtPort") +#define cbSSL CTRL_COMBOBOX("cbSSL") +#define txtUsername CTRL_TEXT("txtUsername") +#define stTryConnect CTRL_STATIC("stTryConnect") +#define chkTryConnect CTRL_CHECKBOX("chkTryConnect") +#define stStorePwd CTRL_STATIC("stStorePwd") +#define chkStorePwd CTRL_CHECKBOX("chkStorePwd") +#define txtRolename CTRL_TEXT("txtRolename") +#define stRestore CTRL_STATIC("stRestore") +#define chkRestore CTRL_CHECKBOX("chkRestore") +#define stPassword CTRL_STATIC("stPassword") +#define txtPassword CTRL_TEXT("txtPassword") +#define txtDbRestriction CTRL_TEXT("txtDbRestriction") +#define colourPicker CTRL_COLOURPICKER("colourPicker") +#define cbGroup CTRL_COMBOBOX("cbGroup") +#define pickerSSLCert CTRL_FILEPICKER("pickerSSLCert") +#define pickerSSLKey CTRL_FILEPICKER("pickerSSLKey") +#define pickerSSLRootCert CTRL_FILEPICKER("pickerSSLRootCert") +#define pickerSSLCrl CTRL_FILEPICKER("pickerSSLCrl") +#define chkSSLCompression CTRL_CHECKBOX("chkSSLCompression") +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") + +// SSH Tunnel Tab +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#define chkSSHTunnel CTRL_CHECKBOX("chkSSHTunnel") +#define txtTunnelHost CTRL_TEXT("txtTunnelHost") +#define txtTunnelUsername CTRL_TEXT("txtTunnelUsername") +#define radioBtnPassword CTRL_RADIOBUTTON("radioBtnPassword") +#define radioBtnKeyfile CTRL_RADIOBUTTON("radioBtnKeyfile") +#define txtTunnelPassword CTRL_TEXT("txtTunnelPassword") +#define pickerPublicKeyFile CTRL_FILEPICKER("pickerPublicKeyFile") +#define pickerIdentityFile CTRL_FILEPICKER("pickerIdentityFile") +#define stPublicKeyFile CTRL_STATIC("stPublicKeyFile") +#define txtTunnelPort CTRL_TEXT("txtTunnelPort") +#endif + +BEGIN_EVENT_TABLE(dlgServer, dlgProperty) + EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), dlgServer::OnPageSelect) + EVT_TEXT(XRCID("txtHostAddr"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDescription"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtService"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtServiceID"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbDatabase"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtPort") , dlgProperty::OnChange) + EVT_TEXT(XRCID("txtUsername"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtRolename"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtDbRestriction"), dlgServer::OnChangeRestr) + EVT_COMBOBOX(XRCID("cbSSL"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkStorePwd"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkRestore"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkTryConnect"), dlgServer::OnChangeTryConnect) + EVT_COLOURPICKER_CHANGED(XRCID("colourPicker"), dlgServer::OnChangeColour) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLCert"), dlgServer::OnChangeFile) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLKey"), dlgServer::OnChangeFile) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLRootCert"), dlgServer::OnChangeFile) + EVT_FILEPICKER_CHANGED(XRCID("pickerSSLCrl"), dlgServer::OnChangeFile) + EVT_TEXT(XRCID("cbGroup"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbGroup"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSSLCompression"), dlgProperty::OnChange) + EVT_BUTTON(wxID_OK, dlgServer::OnOK) +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + EVT_TEXT(XRCID("txtTunnelHost"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtTunnelUsername"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkSSHTunnel"), dlgServer::OnCheckSSHTunnel) + EVT_RADIOBUTTON(XRCID("radioBtnPassword"), dlgServer::OnChangeAuthOption) + EVT_RADIOBUTTON(XRCID("radioBtnKeyfile"), dlgServer::OnChangeAuthOption) + EVT_TEXT(XRCID("txtTunnelPort"), dlgProperty::OnChange) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgServerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgServer(this, frame, (pgServer *)node); +} + + +dlgServer::dlgServer(pgaFactory *f, frmMain *frame, pgServer *node) + : dlgProperty(f, frame, wxT("dlgServer")) +{ + server = node; + dbRestrictionOk = true; + + cbDatabase->Append(wxT("postgres")); + cbDatabase->Append(wxT("edb")); + cbDatabase->Append(wxT("template1")); + wxString lastDB = settings->GetLastDatabase(); + if (lastDB != wxT("postgres") && lastDB != wxT("edb") && lastDB != wxT("template1")) + cbDatabase->Append(lastDB); + cbDatabase->SetSelection(0); + + txtPort->SetValue(NumToStr((long)settings->GetLastPort())); + if (!cbSSL->GetValue().IsEmpty()) + cbSSL->SetSelection(settings->GetLastSSL()); + txtUsername->SetValue(settings->GetLastUsername()); + + chkTryConnect->SetValue(true); + chkStorePwd->SetValue(true); + chkRestore->SetValue(true); + if (node) + { + chkTryConnect->SetValue(false); + chkTryConnect->Disable(); + } + + // Fill the group combobox + cbGroup->Append(_("Servers")); + ctlTree *browser = frame->GetBrowser(); + wxTreeItemId groupitem; + wxTreeItemIdValue groupcookie, servercookie; + pgServer *firstserver; + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (groupitem) + { + firstserver = (pgServer *)browser->GetObject(browser->GetFirstChild(groupitem, servercookie)); + if (firstserver && !firstserver->GetGroup().IsEmpty() && firstserver->GetGroup() != _("Servers")) + cbGroup->Append(firstserver->GetGroup()); + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + EnableSSHTunnelControls(false); + radioBtnPassword->SetValue(true); + radioBtnKeyfile->SetValue(false); + txtTunnelPassword->SetMaxLength(SSH_MAX_PASSWORD_LEN); + txtTunnelPort->SetValue(NumToStr((long)DEFAULT_SSH_PORT)); +#ifdef HAVE_OPENSSL_CRYPTO + stPublicKeyFile->Show(false); + pickerPublicKeyFile->Show(false); +#endif +#else + for(size_t i = 0; i < nbNotebook->GetPageCount(); i++) + { + if(nbNotebook->GetPageText(i).compare(wxT("SSH Tunnel")) == 0) + { + nbNotebook->RemovePage(i); + } + } +#endif +} + + +dlgServer::~dlgServer() +{ + if (!server) + { + settings->SetLastDatabase(cbDatabase->GetValue()); + settings->SetLastPort(StrToLong(txtPort->GetValue())); + settings->SetLastSSL(cbSSL->GetCurrentSelection()); + settings->SetLastUsername(txtUsername->GetValue()); + } +} + + +pgObject *dlgServer::GetObject() +{ + return server; +} + + +void dlgServer::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + + // Display the 'save password' hint if required + if(chkStorePwd->GetValue()) + { + if (frmHint::ShowHint(this, HINT_SAVING_PASSWORDS) == wxID_CANCEL) + return; + } + + // notice: changes active after reconnect + EnableOK(false); + + if (server) + { + server->iSetName(GetName()); + server->iSetHostAddr(txtHostAddr->GetValue()); + server->iSetDescription(txtDescription->GetValue()); + server->iSetService(txtService->GetValue()); + if (txtServiceID->GetValue() != server->GetServiceID()) + { + mainForm->StartMsg(_("Checking server status")); + server->iSetServiceID(txtServiceID->GetValue()); + mainForm->EndMsg(); + } + server->iSetPort(StrToLong(txtPort->GetValue())); + server->iSetSSL(cbSSL->GetCurrentSelection()); + server->iSetDatabase(cbDatabase->GetValue()); + server->iSetUsername(txtUsername->GetValue()); + server->iSetRolename(txtRolename->GetValue()); + server->iSetStorePwd(chkStorePwd->GetValue()); + server->iSetRestore(chkRestore->GetValue()); + server->iSetDbRestriction(txtDbRestriction->GetValue().Trim()); + server->SetSSLCert(pickerSSLCert->GetPath()); + server->SetSSLKey(pickerSSLKey->GetPath()); + server->SetSSLRootCert(pickerSSLRootCert->GetPath()); + server->SetSSLCrl(pickerSSLCrl->GetPath()); + server->iSetSSLCompression(chkSSLCompression->GetValue()); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + server->iSetSSHTunnel(chkSSHTunnel->GetValue()); + server->iSetTunnelPort(StrToLong(txtTunnelPort->GetValue())); + server->SetTunnelHost(txtTunnelHost->GetValue()); + server->SetTunnelUserName(txtTunnelUsername->GetValue()); + server->iSetAuthModePwd(radioBtnPassword->GetValue()); + server->SetTunnelPassword(txtTunnelPassword->GetValue()); + server->SetPublicKeyFile(pickerPublicKeyFile->GetPath()); + server->SetIdentityFile(pickerIdentityFile->GetPath()); +#endif + wxColour colour = colourPicker->GetColour(); + wxString sColour = colour.GetAsString(wxC2S_HTML_SYNTAX); + server->iSetColour(sColour); + if (cbGroup->GetValue().IsEmpty()) + cbGroup->SetValue(_("Servers")); + if (server->GetGroup() != cbGroup->GetValue()) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemId oldgroupitem, groupitem, serveritem; + wxTreeItemIdValue groupcookie; + bool found; + int total; + wxString label, oldgroupname; + + // Duplicate server object + pgServer *newserver = new pgServer( + server->GetName(), + server->GetHostAddr(), + server->GetDescription(), + server->GetService(), + server->GetDatabaseName(), + server->GetUsername(), + server->GetPort(), + server->GetStorePwd(), + server->GetRolename(), + server->GetRestore(), + server->GetSSL(), + server->GetColour(), +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + server->GetGroup(), + server->GetSSHTunnel(), + server->GetTunnelHost(), + server->GetTunnelUserName(), + server->GetAuthModePwd(), + server->GetTunnelPassword(), + server->GetPublicKeyFile(), + server->GetIdentityFile(), + server->GetTunnelPort()); +#else + server->GetGroup()); +#endif + newserver->iSetDbRestriction(server->GetDbRestriction().Trim()); + newserver->iSetServiceID(server->GetServiceID().Trim()); + newserver->iSetDiscoveryID(server->GetDiscoveryID().Trim()); + newserver->SetSSLCert(server->GetSSLCert()); + newserver->SetSSLKey(server->GetSSLKey()); + newserver->SetSSLRootCert(server->GetSSLRootCert()); + newserver->SetSSLCrl(server->GetSSLCrl()); + newserver->iSetSSLCompression(server->GetSSLCompression()); + + // Drop the old item + // (will also take care of dropping the pgServer item) + oldgroupitem = browser->GetItemParent(item); + oldgroupname = server->GetGroup(); + if (oldgroupname.IsEmpty()) + oldgroupname = _("Servers"); + browser->Delete(item); + + // Move the item + found = false; + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(cbGroup->GetValue())) + found = true; + else + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(browser->GetRootItem(), cbGroup->GetValue(), browser->GetItemImage(browser->GetRootItem())); + browser->SortChildren(browser->GetRootItem()); + } + + serveritem = browser->AppendItem(groupitem, newserver->GetFullName(), newserver->GetIconId(), -1, newserver); + browser->SortChildren(groupitem); + browser->Expand(groupitem); + browser->SelectItem(serveritem); + + // Count the number of items in the old group item + total = browser->GetChildrenCount(oldgroupitem, false); + if (total == 0) + browser->Delete(oldgroupitem); + else + { + label = oldgroupname + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(oldgroupitem, label); + } + + // Count the number of items in the new group item + total = browser->GetChildrenCount(groupitem, false); + label = cbGroup->GetValue() + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(groupitem, label); + + // Re-initialize old variables to have their new meanings + server = newserver; + item = serveritem; + } + server->iSetGroup(cbGroup->GetValue()); + + mainForm->execSelChange(server->GetId(), true); + mainForm->GetBrowser()->SetItemText(item, server->GetFullName()); + mainForm->SetItemBackgroundColour(item, wxColour(server->GetColour())); + mainForm->StoreServers(); + } + + if (IsModal()) + { + EndModal(wxID_OK); + return; + } + else + Destroy(); +} + + +void dlgServer::OnChangeColour(wxColourPickerEvent &ev) +{ + dlgProperty::OnChange(ev); +} + + +void dlgServer::OnChangeFile(wxFileDirPickerEvent &ev) +{ + dlgProperty::OnChange(ev); +} + + +void dlgServer::OnChangeRestr(wxCommandEvent &ev) +{ + if (!connection || txtDbRestriction->GetValue().IsEmpty()) + dbRestrictionOk = true; + else + { + wxString sql = wxT("EXPLAIN SELECT 1 FROM pg_database\n") + wxT("WHERE datname IN (") + txtDbRestriction->GetValue() + wxT(")"); + + wxLogNull nix; + wxString result = connection->ExecuteScalar(sql); + + dbRestrictionOk = !result.IsEmpty(); + } + dlgProperty::OnChange(ev); +} + + +void dlgServer::OnPageSelect(wxNotebookEvent &event) +{ + // to prevent dlgProperty from catching it +} + + +wxString dlgServer::GetHelpPage() const +{ + return wxT("connect"); +} + + +int dlgServer::GoNew() +{ + if (cbSSL->GetValue().IsEmpty()) + return Go(true); + else + { + CheckChange(); + return ShowModal(); + } +} + + +int dlgServer::Go(bool modal) +{ + chkSSLCompression->Disable(); + + cbSSL->Clear(); + cbSSL->Append(wxT(" ")); + +#ifdef PG_SSL + cbSSL->Append(_("require")); + cbSSL->Append(_("prefer")); + + if (pgConn::GetLibpqVersion() > 7.3) + { + cbSSL->Append(_("allow")); + cbSSL->Append(_("disable")); + } + + if (pgConn::GetLibpqVersion() >= 8.4) + { + cbSSL->Append(_("verify-ca")); + cbSSL->Append(_("verify-full")); + } + + if (pgConn::GetLibpqVersion() >= 9.2) + { + chkSSLCompression->Enable(); + } +#endif + + if (server) + { + if (cbDatabase->FindString(server->GetDatabaseName()) < 0) + cbDatabase->Append(server->GetDatabaseName()); + txtHostAddr->SetValue(server->GetHostAddr()); + txtDescription->SetValue(server->GetDescription()); + txtService->SetValue(server->GetService()); + txtServiceID->SetValue(server->GetServiceID()); + txtPort->SetValue(NumToStr((long)server->GetPort())); + cbSSL->SetSelection(server->GetSSL()); + cbDatabase->SetValue(server->GetDatabaseName()); + txtUsername->SetValue(server->GetUsername()); + chkStorePwd->SetValue(server->GetStorePwd()); + txtRolename->SetValue(server->GetRolename()); + chkRestore->SetValue(server->GetRestore()); + txtDbRestriction->SetValue(server->GetDbRestriction()); + colourPicker->SetColour(server->GetColour()); + cbGroup->SetValue(server->GetGroup()); + + pickerSSLCert->SetPath(server->GetSSLCert()); + pickerSSLKey->SetPath(server->GetSSLKey()); + pickerSSLRootCert->SetPath(server->GetSSLRootCert()); + pickerSSLCrl->SetPath(server->GetSSLCrl()); + + chkSSLCompression->SetValue(server->GetSSLCompression()); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + chkSSHTunnel->SetValue(server->GetSSHTunnel()); + if(server->GetSSHTunnel()) + { + chkStorePwd->SetValue(false); + chkStorePwd->Enable(false); + } + txtTunnelPort->SetValue(NumToStr((long)server->GetTunnelPort())); + txtTunnelHost->SetValue(server->GetTunnelHost()); + txtTunnelUsername->SetValue(server->GetTunnelUserName()); + if (server->GetAuthModePwd()) + { + radioBtnPassword->SetValue(true); + radioBtnKeyfile->SetValue(false); + } + else + { + radioBtnPassword->SetValue(false); + radioBtnKeyfile->SetValue(true); + } + txtTunnelPassword->SetValue(server->GetTunnelPassword()); + pickerPublicKeyFile->SetPath(server->GetPublicKeyFile()); + pickerIdentityFile->SetPath(server->GetIdentityFile()); +#endif + stPassword->Disable(); + txtPassword->Disable(); + if (connection) + { + txtHostAddr->Disable(); + txtDescription->Disable(); + txtService->Disable(); + txtServiceID->Disable(); + txtName->Disable(); + cbDatabase->Disable(); + txtPort->Disable(); + cbSSL->Disable(); + txtUsername->Disable(); + chkStorePwd->Disable(); + txtRolename->Disable(); + chkRestore->Disable(); + txtDbRestriction->Disable(); + colourPicker->Disable(); + cbGroup->Disable(); + pickerSSLCert->Disable(); + pickerSSLKey->Disable(); + pickerSSLRootCert->Disable(); + pickerSSLCrl->Disable(); + chkSSLCompression->Disable(); + EnableOK(false); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + chkSSHTunnel->Enable(false); + EnableSSHTunnelControls(false); + } + else + { + if (server->GetSSHTunnel()) + { + chkSSHTunnel->Enable(true); + EnableSSHTunnelControls(true); + EnableAuthenticationOptions(); + } +#endif + } + } + else + { + SetTitle(_("Add server")); + cbGroup->SetValue(_("Servers")); + wxString colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX); + colourPicker->SetColour(colour); + } + + // Call CheckRange to set state on OK button + CheckChange(); + return dlgProperty::Go(modal); +} + + +bool dlgServer::GetTryConnect() +{ + return chkTryConnect->GetValue(); +} + + +wxString dlgServer::GetPassword() +{ + return txtPassword->GetValue(); +} + + +pgObject *dlgServer::CreateObject(pgCollection *collection) +{ + pgServer *obj = NULL; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if (chkSSHTunnel->GetValue()) + { + obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), + txtService->GetValue(), cbDatabase->GetValue(), + txtUsername->GetValue(), StrToLong(txtPort->GetValue()), + chkTryConnect->GetValue() && chkStorePwd->GetValue(), + txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), + colourPicker->GetColourString(), cbGroup->GetValue(), + chkSSHTunnel->GetValue(), txtTunnelHost->GetValue(), txtTunnelUsername->GetValue(), + radioBtnPassword->GetValue(), + txtTunnelPassword->GetValue(), pickerPublicKeyFile->GetPath(), + pickerIdentityFile->GetPath(), StrToLong(txtTunnelPort->GetValue())); + } + else +#endif + { + obj = new pgServer(GetName(), txtHostAddr->GetValue(), txtDescription->GetValue(), + txtService->GetValue(), cbDatabase->GetValue(), + txtUsername->GetValue(), StrToLong(txtPort->GetValue()), + chkTryConnect->GetValue() && chkStorePwd->GetValue(), + txtRolename->GetValue(), chkRestore->GetValue(), cbSSL->GetCurrentSelection(), + colourPicker->GetColourString(), cbGroup->GetValue()); + } + + obj->iSetDbRestriction(txtDbRestriction->GetValue().Trim()); + obj->iSetServiceID(txtServiceID->GetValue()); + obj->SetSSLCert(pickerSSLCert->GetTextCtrlValue()); + obj->SetSSLKey(pickerSSLKey->GetTextCtrlValue()); + obj->SetSSLRootCert(pickerSSLRootCert->GetTextCtrlValue()); + obj->SetSSLCrl(pickerSSLCrl->GetTextCtrlValue()); + obj->iSetSSLCompression(chkSSLCompression->GetValue()); + + return obj; +} + + +void dlgServer::OnChangeTryConnect(wxCommandEvent &ev) +{ + chkStorePwd->Enable(chkTryConnect->GetValue() && !connection); + txtPassword->Enable(chkTryConnect->GetValue() && !connection); + OnChange(ev); +} + + +void dlgServer::CheckChange() +{ + wxString name = GetName(); + bool enable = true; + + if (server) + { + // Get old value + wxColour colour; + wxString sColour = wxEmptyString; + + if (colour.Set(server->GetColour())) + sColour = colour.GetAsString(wxC2S_HTML_SYNTAX); + + // Get new value + wxString sColour2 = colourPicker->GetColourString(); + + enable = name != server->GetName() + || txtHostAddr->GetValue() != server->GetHostAddr() + || txtDescription->GetValue() != server->GetDescription() + || txtService->GetValue() != server->GetService() + || txtServiceID->GetValue() != server->GetServiceID() + || StrToLong(txtPort->GetValue()) != server->GetPort() + || cbDatabase->GetValue() != server->GetDatabaseName() + || txtUsername->GetValue() != server->GetUsername() + || cbSSL->GetCurrentSelection() != server->GetSSL() + || chkStorePwd->GetValue() != server->GetStorePwd() + || txtRolename->GetValue() != server->GetRolename() + || chkRestore->GetValue() != server->GetRestore() + || txtDbRestriction->GetValue() != server->GetDbRestriction() + || sColour != sColour2 + || cbGroup->GetValue() != server->GetGroup() + || pickerSSLCert->GetPath() != server->GetSSLCert() + || pickerSSLKey->GetPath() != server->GetSSLKey() + || pickerSSLRootCert->GetPath() != server->GetSSLRootCert() + || pickerSSLCrl->GetPath() != server->GetSSLCrl() + || chkSSLCompression->GetValue() != server->GetSSLCompression(); + } + +#ifdef __WXMSW__ + CheckValid(enable, !name.IsEmpty(), _("Please specify address.")); +#else + bool isPipe = (name.IsEmpty() || name.StartsWith(wxT("/"))); + cbSSL->Enable(!isPipe && !connection); +#endif + CheckValid(enable, !txtDescription->GetValue().IsEmpty(), _("Please specify description.")); + if (txtService->GetValue().IsEmpty()) + { + CheckValid(enable, StrToLong(txtPort->GetValue()) > 0, _("Please specify port.")); + CheckValid(enable, !txtUsername->GetValue().IsEmpty(), _("Please specify user name")); + } + CheckValid(enable, dbRestrictionOk, _("Restriction not valid.")); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(chkSSHTunnel->GetValue()) + { + CheckValid(enable, !txtTunnelHost->GetValue().IsEmpty(), _("Please specify ssh tunnel host.")); + CheckValid(enable, !txtTunnelPort->GetValue().IsEmpty(), _("Please specify ssh tunnel port.")); + CheckValid(enable, !txtTunnelUsername->GetValue().IsEmpty(), _("Please specify ssh tunnel user name.")); + } +#endif + + EnableOK(enable && !connection); +} + + +wxString dlgServer::GetSql() +{ + return wxEmptyString; +} + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + +void dlgServer::OnCheckSSHTunnel(wxCommandEvent &ev) +{ + if (chkSSHTunnel->IsChecked()) + { + if(chkStorePwd->GetValue()) + { + wxMessageBox(_("Database passwords cannot be stored when using SSH tunnelling. The 'Store password' option has been turned off."), _("Stored Password"), wxICON_EXCLAMATION | wxOK, this); + } + chkStorePwd->SetValue(false); + chkStorePwd->Enable(false); + EnableSSHTunnelControls(true); + EnableAuthenticationOptions(); + } + else + { + chkStorePwd->Enable(); + EnableSSHTunnelControls(false); + } + + CheckChange(); +} + +void dlgServer::OnChangeAuthOption(wxCommandEvent &ev) +{ + EnableAuthenticationOptions(); +} + +void dlgServer::EnableSSHTunnelControls(const bool &bEnable) +{ + txtTunnelHost->Enable(bEnable); + txtTunnelUsername->Enable(bEnable); + pickerPublicKeyFile->Enable(bEnable); + pickerIdentityFile->Enable(bEnable); + radioBtnPassword->Enable(bEnable); + radioBtnKeyfile->Enable(bEnable); + txtTunnelPassword->Enable(bEnable); + txtTunnelPort->Enable(bEnable); +} + +void dlgServer::EnableAuthenticationOptions() +{ + if (radioBtnPassword->GetValue()) + { + pickerIdentityFile->Enable(false); + pickerPublicKeyFile->Enable(false); + } + else + { + pickerIdentityFile->Enable(true); + pickerPublicKeyFile->Enable(true); + } +} +#endif diff --git a/dlg/dlgSynonym.cpp b/dlg/dlgSynonym.cpp new file mode 100644 index 0000000..a3bd189 --- /dev/null +++ b/dlg/dlgSynonym.cpp @@ -0,0 +1,316 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSynonym.cpp - EnterpriseDB Synonym Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgSynonym.h" +#include "schema/edbSynonym.h" +#include "schema/edbPrivateSynonym.h" + +// pointer to controls +#define txtName CTRL_TEXT("txtName") +#define cbTargetType CTRL_COMBOBOX2("cbTargetType") +#define cbTargetSchema CTRL_COMBOBOX2("cbTargetSchema") +#define cbTargetObject CTRL_COMBOBOX("cbTargetObject") +#define stComment CTRL_STATIC("stComment") + +dlgProperty *edbSynonymFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSynonym(this, frame, (edbSynonym *)node); +} + +dlgProperty *edbPrivateSynonymFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgSynonym(this, frame, (edbPrivateSynonym *)node, (pgSchema *)parent); +} + + +BEGIN_EVENT_TABLE(dlgSynonym, dlgProperty) + EVT_TEXT(XRCID("cbTargetType"), dlgSynonym::OnChangeTargetType) + EVT_COMBOBOX(XRCID("cbTargetType"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTargetSchema"), dlgSynonym::OnChangeTargetSchema) + EVT_COMBOBOX(XRCID("cbTargetSchema"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTargetObject"), dlgProperty::OnChange) +END_EVENT_TABLE(); + + +dlgSynonym::dlgSynonym(pgaFactory *f, frmMain *frame, edbSynonym *node) + : dlgProperty(f, frame, wxT("dlgSynonym")) +{ + synonym = node; + privSynonym = NULL; + synonymSchema = NULL; + cbOwner->Disable(); +} + +dlgSynonym::dlgSynonym(edbPrivateSynonymFactory *factory, frmMain *frame, edbPrivateSynonym *syn, pgSchema *schema) + : dlgProperty((pgaFactory *)factory, frame, wxT("dlgSynonym")) +{ + synonym = NULL; + privSynonym = syn; + synonymSchema = schema; + cbOwner->Disable(); +} + + +pgObject *dlgSynonym::GetObject() +{ + if (!synonymSchema) + return synonym; + return (pgObject *)privSynonym; +} + + +int dlgSynonym::Go(bool modal) +{ + if (synonym) + { + // edit mode + txtName->Disable(); + + cbTargetType->SetSelection(cbTargetType->FindString(synonym->GetTargetType())); + ProcessTypeChange(); + + if (cbTargetType->GetValue() != _("Public synonym")) + { + cbTargetSchema->SetSelection(cbTargetSchema->FindString(synonym->GetTargetSchema())); + ProcessSchemaChange(); + } + cbTargetObject->SetSelection(cbTargetObject->FindString(synonym->GetTargetObject())); + } + else if (privSynonym) + { + // edit mode + txtName->Disable(); + + cbTargetType->SetSelection(cbTargetType->FindString(privSynonym->GetTargetType())); + ProcessTypeChange(); + + cbTargetSchema->SetSelection(cbTargetSchema->FindString(privSynonym->GetTargetSchema())); + ProcessSchemaChange(); + + cbTargetObject->SetSelection(cbTargetObject->FindString(privSynonym->GetTargetObject())); + } + else + { + // create mode + cbTargetType->Enable(); + cbTargetSchema->Disable(); + cbTargetObject->Disable(); + } + + txtComment->Disable(); + + // Functions and Procedures are available 8.4 onwards. So check for the + // same. Unfortunately we need a connection object for that and so we + // re-use an existing one.. + if (connection && connection->BackendMinimumVersion(8, 4)) + { + cbTargetType->Append(_("Function")); + cbTargetType->Append(_("Procedure")); + } + cbTargetType->Append(_("Sequence")); + cbTargetType->Append(_("Public synonym")); + cbTargetType->Append(_("Table")); + cbTargetType->Append(_("View")); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgSynonym::CreateObject(pgCollection *collection) +{ + pgObject *obj = NULL; + if (!synonymSchema) + obj = synonymFactory.CreateObjects(collection, 0, + wxT(" WHERE synname = ") + qtDbString(GetName())); + else + obj = edbPrivFactory.CreateObjects(collection, 0, + wxT(" WHERE s.synname=") + qtDbString(GetName()) + + wxT(" AND s.synnamespace=") + collection->GetSchema()->GetOidStr() + wxT(" \n")); + + return obj; +} + + +void dlgSynonym::CheckChange() +{ + bool enable = true; + CheckValid(enable, !txtName->GetValue().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !cbTargetType->GetValue().IsEmpty(), _("Please select target type.")); + // Public Synonyms does supported in public only + if (!synonymSchema && cbTargetType->GetValue() != _("Public synonym")) + CheckValid(enable, !cbTargetSchema->GetValue().IsEmpty(), _("Please select target schema.")); + CheckValid(enable, !cbTargetObject->GetValue().IsEmpty(), _("Please select target object.")); + + if (!enable) + { + EnableOK(enable); + return; + } + + if (synonym) + EnableOK(synonym->GetTargetObject() != cbTargetObject->GetValue()); + else if (privSynonym) + EnableOK(privSynonym->GetTargetObject() != cbTargetObject->GetValue()); + else + EnableOK(txtName->GetValue() != wxEmptyString && cbTargetObject->GetValue() != wxEmptyString); +} + +void dlgSynonym::ProcessTypeChange() +{ + cbTargetSchema->Clear(); + cbTargetObject->Clear(); + if (cbTargetType->GetValue() != _("Public synonym")) + { + pgSet *schemas; + if (connection->BackendMinimumVersion(8, 2)) + schemas = connection->ExecuteSet(wxT("SELECT nspname FROM pg_namespace WHERE nspparent = 0 AND nspname NOT LIKE E'pg\\_%' AND nspname NOT IN ('pg_catalog', 'sys', 'dbo', 'pgagent', 'information_schema', 'dbms_job_procedure') ORDER BY nspname;")); + else if (connection->BackendMinimumVersion(8, 1)) + schemas = connection->ExecuteSet(wxT("SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE E'pg\\_%' ORDER BY nspname;")); + else + schemas = connection->ExecuteSet(wxT("SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg\\_%' ORDER BY nspname;")); + + for (int x = 0; x < schemas->NumRows(); x++) + { + cbTargetSchema->Append(schemas->GetVal(0)); + schemas->MoveNext(); + } + delete schemas; + + cbTargetSchema->Enable(); + cbTargetSchema->SetValue(wxT("public")); + ProcessSchemaChange(); + } + else + { + pgSet *synonyms = connection->ExecuteSet(wxT("SELECT synname FROM pg_synonym ORDER BY synname;")); + for (int x = 0; x < synonyms->NumRows(); x++) + { + cbTargetObject->Append(synonyms->GetVal(0)); + synonyms->MoveNext(); + } + delete synonyms; + + cbTargetSchema->Disable(); + cbTargetObject->Enable(); + } +} + +void dlgSynonym::ProcessSchemaChange() +{ + cbTargetObject->Clear(); + + wxString restriction; + if (cbTargetType->GetValue() == _("Sequence")) + restriction = wxT("S"); + else if (cbTargetType->GetValue() == _("Table")) + restriction = wxT("r"); + else if (cbTargetType->GetValue() == _("View")) + restriction = wxT("v"); + else if (cbTargetType->GetValue() == _("Function")) + restriction = wxT("0"); + else if (cbTargetType->GetValue() == _("Procedure")) + restriction = wxT("1"); + + wxString sql; + if (cbTargetType->GetValue() == _("Synonym")) + { + sql = wxT("SELECT synname FROM pg_synonym s JOIN pg_namespace n\n") + wxT(" ON s.synnamespace = n.oid AND \n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + + wxT(" ORDER BY synname;"); + } + else if (cbTargetType->GetValue() == _("Function") || + cbTargetType->GetValue() == _("Procedure")) + { + // "protype" is available, no need to check for version again here.. + sql = wxT("SELECT DISTINCT proname from pg_proc p, pg_namespace n\n") + wxT(" WHERE p.pronamespace = n.oid AND\n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + wxT(" AND\n") + wxT(" p.protype = '") + restriction + wxT("' ORDER BY proname;"); + } + else if (cbTargetType->GetValue() == _("View")) + { + wxString mviewRestriction = wxT("m"); + sql = wxT("SELECT relname FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid AND\n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + wxT(" AND\n") + wxT(" (c.relkind = '") + restriction + wxT("' OR c.relkind = '") + mviewRestriction + wxT("') ORDER BY relname;"); + } + else + { + sql = wxT("SELECT relname FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid AND\n") + wxT(" n.nspname = ") + qtDbString(cbTargetSchema->GetValue()) + wxT(" AND\n") + wxT(" c.relkind = '") + restriction + wxT("' ORDER BY relname;"); + } + + pgSet *objects = connection->ExecuteSet(sql); + for (int x = 0; x < objects->NumRows(); x++) + { + cbTargetObject->Append(objects->GetVal(0)); + objects->MoveNext(); + } + delete objects; + + cbTargetObject->Enable(); +} + + +wxString dlgSynonym::GetSql() +{ + wxString sql; + + if (!synonymSchema) + { + + sql = wxT("CREATE OR REPLACE PUBLIC SYNONYM ") + qtIdent(txtName->GetValue()) + wxT("\n FOR "); + + if (cbTargetSchema->GetValue() != wxEmptyString) + sql += qtIdent(cbTargetSchema->GetValue()) + wxT("."); + + sql += qtIdent(cbTargetObject->GetValue()) + wxT(";\n"); + + AppendComment(sql, wxT("PUBLIC SYNONYM ") + qtIdent(txtName->GetValue()), synonym); + } + else + { + wxString createSql, commentSql; + if (synonymSchema->GetName() == wxT("public")) + { + createSql = wxT("CREATE OR REPLACE PUBLIC SYNONYM "); + commentSql = wxT("PUBLIC SYNONYM "); + } + else + { + createSql = wxT("CREATE OR REPLACE SYNONYM ") + qtIdent(synonymSchema->GetName()) + wxT("."); + commentSql = wxT("PRIVATE SYNONYM "); + } + + sql = createSql + qtIdent(txtName->GetValue()) + wxT("\n FOR "); + + if (cbTargetSchema->GetValue() != wxEmptyString) + sql += qtIdent(cbTargetSchema->GetValue()) + wxT("."); + + sql += qtIdent(cbTargetObject->GetValue()) + wxT(";\n"); + + AppendComment(sql, commentSql + qtIdent(txtName->GetValue()), synonym); + } + + return sql; +} diff --git a/dlg/dlgTable.cpp b/dlg/dlgTable.cpp new file mode 100644 index 0000000..c02e9c9 --- /dev/null +++ b/dlg/dlgTable.cpp @@ -0,0 +1,2135 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTable.cpp - PostgreSQL Table Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" + +#include "dlg/dlgTable.h" +#include "dlg/dlgColumn.h" +#include "dlg/dlgIndexConstraint.h" +#include "dlg/dlgForeignKey.h" +#include "dlg/dlgCheck.h" + +#include "schema/gpPartition.h" +#include "schema/pgPartition.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgCheck.h" +#include "schema/pgForeignKey.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" + + +#define stUnlogged CTRL_STATIC("stUnlogged") +#define chkUnlogged CTRL_CHECKBOX("chkUnlogged") +#define stHasOids CTRL_STATIC("stHasOids") +#define chkHasOids CTRL_CHECKBOX("chkHasOids") +#define lbTables CTRL_LISTBOX("lbTables") +#define btnAddTable CTRL_BUTTON("btnAddTable") +#define btnRemoveTable CTRL_BUTTON("btnRemoveTable") +#define cbTables CTRL_COMBOBOX2("cbTables") +#define cbTablespace CTRL_COMBOBOX("cbTablespace") +#define cbOfType CTRL_COMBOBOX("cbOfType") +#define txtFillFactor CTRL_TEXT("txtFillFactor") + +#define btnAddCol CTRL_BUTTON("btnAddCol") +#define btnChangeCol CTRL_BUTTON("btnChangeCol") +#define btnRemoveCol CTRL_BUTTON("btnRemoveCol") + +#define lstConstraints CTRL_LISTVIEW("lstConstraints") +#define btnAddConstr CTRL_BUTTON("btnAddConstr") +#define cbConstrType CTRL_COMBOBOX("cbConstrType") +#define btnRemoveConstr CTRL_BUTTON("btnRemoveConstr") + +#define cbLikeRelation CTRL_COMBOBOX("cbLikeRelation") +#define chkIncludingDefaults CTRL_CHECKBOX("chkIncludingDefaults") +#define chkIncludingConstraints CTRL_CHECKBOX("chkIncludingConstraints") +#define chkIncludingIndexes CTRL_CHECKBOX("chkIncludingIndexes") +#define chkIncludingStorage CTRL_CHECKBOX("chkIncludingStorage") +#define chkIncludingComments CTRL_CHECKBOX("chkIncludingComments") + +/* AutoVacuum Settings */ +#define nbVaccum CTRL_NOTEBOOK("nbVacuum") +#define chkCustomVac CTRL_CHECKBOX("chkCustomVac") +#define chkVacEnabled CTRL_CHECKBOX("chkVacEnabled") +#define txtBaseVac CTRL_TEXT("txtBaseVac") +#define stBaseVacCurr CTRL_STATIC("stBaseVacCurr") +#define txtBaseAn CTRL_TEXT("txtBaseAn") +#define stBaseAnCurr CTRL_STATIC("stBaseAnCurr") +#define txtFactorVac CTRL_TEXT("txtFactorVac") +#define stFactorVacCurr CTRL_STATIC("stFactorVacCurr") +#define txtFactorAn CTRL_TEXT("txtFactorAn") +#define stFactorAnCurr CTRL_STATIC("stFactorAnCurr") +#define txtVacDelay CTRL_TEXT("txtVacDelay") +#define stVacDelayCurr CTRL_STATIC("stVacDelayCurr") +#define txtVacLimit CTRL_TEXT("txtVacLimit") +#define stVacLimitCurr CTRL_STATIC("stVacLimitCurr") +#define txtFreezeMinAge CTRL_TEXT("txtFreezeMinAge") +#define stFreezeMinAgeCurr CTRL_STATIC("stFreezeMinAgeCurr") +#define txtFreezeMaxAge CTRL_TEXT("txtFreezeMaxAge") +#define stFreezeMaxAgeCurr CTRL_STATIC("stFreezeMaxAgeCurr") +#define txtFreezeTableAge CTRL_TEXT("txtFreezeTableAge") +#define stFreezeTableAgeCurr CTRL_STATIC("stFreezeTableAgeCurr") + +/* TOAST TABLE AutoVacuum Settings */ +#define chkCustomToastVac CTRL_CHECKBOX("chkCustomToastVac") +#define chkToastVacEnabled CTRL_CHECKBOX("chkToastVacEnabled") +#define txtBaseToastVac CTRL_TEXT("txtBaseToastVac") +#define stBaseToastVacCurr CTRL_STATIC("stBaseToastVacCurr") +#define txtFactorToastVac CTRL_TEXT("txtFactorToastVac") +#define stFactorToastVacCurr CTRL_STATIC("stFactorToastVacCurr") +#define txtToastVacDelay CTRL_TEXT("txtToastVacDelay") +#define stToastVacDelayCurr CTRL_STATIC("stToastVacDelayCurr") +#define txtToastVacLimit CTRL_TEXT("txtToastVacLimit") +#define stToastVacLimitCurr CTRL_STATIC("stToastVacLimitCurr") +#define txtToastFreezeMinAge CTRL_TEXT("txtToastFreezeMinAge") +#define stToastFreezeMinAgeCurr CTRL_STATIC("stToastFreezeMinAgeCurr") +#define txtToastFreezeMaxAge CTRL_TEXT("txtToastFreezeMaxAge") +#define stToastFreezeMaxAgeCurr CTRL_STATIC("stToastFreezeMaxAgeCurr") +#define txtToastFreezeTableAge CTRL_TEXT("txtToastFreezeTableAge") +#define stToastFreezeTableAgeCurr CTRL_STATIC("stToastFreezeTableAgeCurr") + + +BEGIN_EVENT_TABLE(dlgTable, dlgSecurityProperty) + EVT_CHECKBOX(XRCID("chkUnlogged"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbTablespace"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtFillFactor"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbOfType"), dlgTable::OnChangeOfType) + EVT_CHECKBOX(XRCID("chkHasOids"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbTables"), dlgTable::OnChangeTable) + EVT_BUTTON(XRCID("btnAddTable"), dlgTable::OnAddTable) + EVT_BUTTON(XRCID("btnRemoveTable"), dlgTable::OnRemoveTable) + EVT_LISTBOX(XRCID("lbTables"), dlgTable::OnSelChangeTable) + + EVT_BUTTON(XRCID("btnAddCol"), dlgTable::OnAddCol) + EVT_BUTTON(XRCID("btnChangeCol"), dlgTable::OnChangeCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgTable::OnRemoveCol) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgTable::OnSelChangeCol) + + EVT_BUTTON(XRCID("btnAddConstr"), dlgTable::OnAddConstr) + EVT_BUTTON(XRCID("btnRemoveConstr"), dlgTable::OnRemoveConstr) + EVT_LIST_ITEM_SELECTED(XRCID("lstConstraints"), dlgTable::OnSelChangeConstr) + + /* AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomVac"), dlgTable::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkVacEnabled"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseAn"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorAn"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacDelay"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacLimit"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMinAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMaxAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeTableAge"), dlgTable::OnChangeVacuum) + + /* TOAST TABLE AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomToastVac"), dlgTable::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkToastVacEnabled"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseToastVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorToastVac"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacDelay"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacLimit"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMinAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMaxAge"), dlgTable::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeTableAge"), dlgTable::OnChangeVacuum) + + EVT_BUTTON(wxID_OK, dlgTable::OnOK) + +#ifdef __WXMAC__ + EVT_SIZE( dlgTable::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTable(this, frame, (pgTable *)node, (pgSchema *)parent); +} + +dlgProperty *gpPartitionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTable(this, frame, (gpPartition *)node, (pgSchema *)parent); +} +dlgProperty *pgPartitionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + pgObject *parentNode; + parentNode = parent; + // found schema node + while (parentNode->GetMetaType() != PGM_SCHEMA) { + if (parentNode && /*parentNode->IsCollection() && */parentNode->GetMetaType() != PGM_SERVER) + parentNode = frame->GetBrowser()->GetObject( + frame->GetBrowser()->GetItemParent(parentNode->GetId())); + else + break; + } + parent=parentNode; + pgPartition *n=(pgPartition *)node; + pgSchema *p=(pgSchema *)parent; + if (n->GetSchema()->GetName()!=p->GetName()) parent=n->GetSchema(); + return new dlgTable(this, frame, (pgPartition *)node, (pgSchema *)parent); +} + +dlgTable::dlgTable(pgaFactory *f, frmMain *frame, pgTable *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgTable"), wxT("INSERT,SELECT,UPDATE,DELETE,TRUNCATE,RULE,REFERENCES,TRIGGER"), "arwdDRxt") +{ + schema = sch; + table = node; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + btnAddTable->Disable(); + btnRemoveTable->Disable(); + + // Visible columns + lstColumns->AddColumn(_("Column name"), 90); + lstColumns->AddColumn(_("Definition"), 135); +#ifndef __WXMAC__ + lstColumns->AddColumn(_("Inherited from table"), 40); +#else + lstColumns->AddColumn(_("Inherited from table"), 80); +#endif + // Invisible columns + // ... sql definition + lstColumns->AddColumn(_("Column definition"), 0); + // ... new comment + lstColumns->AddColumn(_("Column comment"), 0); + // ... new statistics + lstColumns->AddColumn(_("Column statistics"), 0); + // ... pgColumn* handle (used for new columns) + lstColumns->AddColumn(_("Column"), 0); + // ... new type OID + lstColumns->AddColumn(_("Column type oid"), 0); + // ... pgColumn* handle (used for changed columns) + lstColumns->AddColumn(_("Changed column"), 0); + // ... pgColumn* handle (used for variable list) + lstColumns->AddColumn(_("Variable List"), 0); + // ... pgColumn* handle (used for security label list) + lstColumns->AddColumn(_("Security Label List"), 0); + lstConstraints->CreateColumns(0, _("Constraint name"), _("Definition"), 90); +} + +dlgTable::~dlgTable() +{ + //Clear the cached datatypes + size_t i; + for (i = 0; i < dtCache.GetCount(); i++) + delete dtCache.Item(i); +} + +bool dlgTable::Destroy() +{ + for(int pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + pgColumn *column2 = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_CHANGEDCOL)); + if(column2) delete column2; + } + return dlgProperty::Destroy(); +} + +pgObject *dlgTable::GetObject() +{ + return table; +} + + +int dlgTable::Go(bool modal) +{ + PrepareTablespace(cbTablespace); + PopulateDatatypeCache(); + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(table); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgTable::OnChange)); + } + else + seclabelPage->Disable(); + + // new "of type" combobox + wxString typeQuery = wxT("SELECT t.oid, t.typname ") + wxT("FROM pg_type t, pg_namespace n ") + wxT("WHERE t.typtype='c' AND t.typnamespace=n.oid ") + wxT("AND NOT (n.nspname like 'pg_%' OR n.nspname='information_schema') ") + wxT("ORDER BY typname"); + cbOfType->Insert(wxEmptyString, 0, (void *)0); + cbOfType->FillOidKey(connection, typeQuery); + cbOfType->SetSelection(0); + + // "like relation" tab + nbNotebook->GetPage(TAB_LIKE)->Enable(!table); + + hasPK = false; + + if (table) + { + // edit mode + chkUnlogged->SetValue(table->GetUnlogged()); + chkHasOids->SetValue(table->GetHasOids()); + + if (table->GetTablespaceOid() != 0) + cbTablespace->SetKey(table->GetTablespaceOid()); + + if (table->GetOfTypeOid() != 0) + cbOfType->SetKey(table->GetOfTypeOid()); + + inheritedTableOids = table->GetInheritedTablesOidList(); + + wxArrayString qitl = table->GetQuotedInheritedTablesList(); + size_t i; + for (i = 0 ; i < qitl.GetCount() ; i++) + { + previousTables.Add(qitl.Item(i)); + lbTables->Append(qitl.Item(i)); + } + + btnAddTable->Enable(connection->BackendMinimumVersion(8, 2) && cbTables->GetGuessedSelection() >= 0); + lbTables->Enable(connection->BackendMinimumVersion(8, 2)); + chkHasOids->Enable((connection->BackendMinimumVersion(8, 0) && table->GetHasOids()) + || connection->BackendMinimumVersion(8, 4)); + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + cbTablespace->Enable(connection->BackendMinimumVersion(7, 5)); + + wxCookieType cookie; + pgObject *data = 0; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(table->GetId(), cookie); + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + pgaFactory *factory = data->GetFactory(); + if (factory == columnFactory.GetCollectionFactory()) + columnsItem = item; + else if (factory == checkFactory.GetCollectionFactory()) + constraintsItem = item; + if (data->GetMetaType() == PGM_COLUMN && data->IsCollection()) + columnsItem = item; + else if (data->GetMetaType() == PGM_CONSTRAINT) + constraintsItem = item; + + if (columnsItem && constraintsItem) + break; + + item = mainForm->GetBrowser()->GetNextChild(table->GetId(), cookie); + } + + if (columnsItem) + { + pgCollection *coll = (pgCollection *)data; + // make sure all columns are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the columns collection + item = mainForm->GetBrowser()->GetFirstChild(columnsItem, cookie); + + // add columns + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(columnFactory)) + { + pgColumn *column = (pgColumn *)data; + // make sure column details are read + column->ShowTreeDetail(mainForm->GetBrowser()); + + if (column->GetColNumber() > 0) + { + bool inherited = (column->GetInheritedCount() != 0); + int pos = lstColumns->AppendItem((inherited ? tableFactory.GetIconId() : column->GetIconId()), + column->GetName(), column->GetDefinition()); + previousColumns.Add(column->GetQuotedIdentifier() + + wxT(" ") + column->GetDefinition()); + lstColumns->SetItem(pos, COL_PGCOLUMN, NumToStr((long)column)); + if (inherited) + lstColumns->SetItem(pos, COL_INHERIT, column->GetInheritedTableName()); + } + } + + item = mainForm->GetBrowser()->GetNextChild(columnsItem, cookie); + } + } + if (constraintsItem) + { + pgCollection *coll = (pgCollection *)mainForm->GetBrowser()->GetObject(constraintsItem); + // make sure all constraints are appended + coll->ShowTreeDetail(mainForm->GetBrowser()); + // this is the constraints collection + item = mainForm->GetBrowser()->GetFirstChild(constraintsItem, cookie); + + // add constraints + while (item) + { + data = mainForm->GetBrowser()->GetObject(item); + switch (data->GetMetaType()) + { + case PGM_PRIMARYKEY: + hasPK = true; + case PGM_UNIQUE: + { + pgIndexConstraint *obj = (pgIndexConstraint *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + case PGM_EXCLUDE: + { + pgIndexConstraint *obj = (pgIndexConstraint *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + case PGM_FOREIGNKEY: + { + pgForeignKey *obj = (pgForeignKey *)data; + wxString def = obj->GetDefinition(); + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), def); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + def); + break; + } + case PGM_CHECK: + { + pgCheck *obj = (pgCheck *)data; + + lstConstraints->AppendItem(data->GetIconId(), obj->GetName(), obj->GetDefinition()); + constraintsDefinition.Add(obj->GetDefinition()); + previousConstraints.Add(obj->GetQuotedIdentifier() + + wxT(" ") + obj->GetTypeName().Upper() + wxT(" ") + obj->GetDefinition()); + break; + } + } + + item = mainForm->GetBrowser()->GetNextChild(constraintsItem, cookie); + } + } + } + else + { + // create mode + btnChangeCol->Hide(); + + // Add the default tablespace + cbTablespace->Insert(_(""), 0, (void *)0); + cbTablespace->SetSelection(0); + + // new "like relation" combobox + wxString likeRelationQuery = wxT("SELECT c.oid, quote_ident(n.nspname)||'.'||quote_ident(c.relname) ") + wxT("FROM pg_class c, pg_namespace n ") + wxT("WHERE c.relnamespace=n.oid AND c.relkind IN "); + if (connection->BackendMinimumVersion(9, 2)) + { + likeRelationQuery += wxT("('r', 'v', 'f')"); + } + else + { + likeRelationQuery += wxT("('r')"); + } + if (!settings->GetShowSystemObjects()) + likeRelationQuery += wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("n.nspname")); + likeRelationQuery += wxT(" ORDER BY 1"); + cbLikeRelation->Insert(wxEmptyString, 0, (void *)0); + cbLikeRelation->FillOidKey(connection, likeRelationQuery); + cbLikeRelation->SetSelection(0); + + // Enable the "like relation" comboboxes + chkIncludingDefaults->Enable(); + chkIncludingConstraints->Enable(connection->BackendMinimumVersion(8, 2)); + chkIncludingIndexes->Enable(connection->BackendMinimumVersion(8, 3)); + chkIncludingStorage->Enable(connection->BackendMinimumVersion(9, 0)); + chkIncludingComments->Enable(connection->BackendMinimumVersion(9, 0)); + } + + chkUnlogged->Enable(connection->BackendMinimumVersion(9, 1) && !table); + cbOfType->Enable(connection->BackendMinimumVersion(9, 0) && !table); + cbTables->Enable(connection->BackendMinimumVersion(8, 2) && cbOfType->GetCurrentSelection() == 0); + + if (connection->BackendMinimumVersion(8, 2) || !table) + { + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = + wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("n.nspname")); + + if (table) + { + wxString oids = table->GetOidStr(); + int i; + for (i = 0 ; i < (int)inheritedTableOids.GetCount() ; i++) + { + oids += wxT(", ") + inheritedTableOids.Item(i); + } + if (oids.Length() > 0) + systemRestriction += wxT(" AND c.oid NOT IN (") + oids + wxT(")"); + } + + pgSet *set = connection->ExecuteSet( + wxT("SELECT c.oid, c.relname , nspname\n") + wxT(" FROM pg_class c\n") + wxT(" JOIN pg_namespace n ON n.oid=c.relnamespace\n") + wxT(" WHERE relkind='r'\n") + + systemRestriction + + wxT(" ORDER BY relnamespace, c.relname")); + if (set) + { + cbTables->Freeze(); + while (!set->Eof()) + { + cbTables->Append(database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))) + + qtIdent(set->GetVal(wxT("relname")))); + + tableOids.Add(set->GetVal(wxT("oid"))); + set->MoveNext(); + } + cbTables->Thaw(); + delete set; + } + } + + FillConstraint(); + + btnChangeCol->Disable(); + btnRemoveCol->Disable(); + btnRemoveConstr->Disable(); + btnOK->Disable(); + + if ((connection->BackendMinimumVersion(8, 1) && table) || connection->BackendMinimumVersion(8, 4)) + { + if (!connection->BackendMinimumVersion(8, 4)) + { + txtFreezeTableAge->Disable(); + /* Remove Toast Table AutoVacuume setting page */ + nbVaccum->DeletePage(1); + } + + settingAutoVacuum = false; + + pgSetIterator avSet(connection, + wxT("SELECT name, setting FROM pg_settings WHERE name like '%vacuum%' ORDER BY name")); + while (avSet.RowsLeft()) + { + wxString name = avSet.GetVal(wxT("name")); + wxString setting = avSet.GetVal(wxT("setting")); + + if (name == wxT("autovacuum_vacuum_cost_delay")) + settingCostDelay = setting; + else if (name == wxT("vacuum_cost_delay")) + { + if (StrToLong(settingCostDelay) < 0) + settingCostDelay = setting; + } + else if (name == wxT("autovacuum_vacuum_cost_limit")) + settingCostLimit = setting; + else if (name == wxT("vacuum_cost_limit")) + { + if (StrToLong(settingCostLimit) < 0) + settingCostLimit = setting; + } + else if (name == wxT("autovacuum_vacuum_scale_factor")) + settingVacFactor = setting; + else if (name == wxT("autovacuum_analyze_scale_factor")) + settingAnlFactor = setting; + else if (name == wxT("autovacuum_vacuum_threshold")) + settingVacBaseThr = setting; + else if (name == wxT("autovacuum_analyze_threshold")) + settingAnlBaseThr = setting; + else if (name == wxT("vacuum_freeze_min_age")) + settingFreezeMinAge = setting; + else if (name == wxT("autovacuum_freeze_max_age")) + settingFreezeMaxAge = setting; + else if (name == wxT("vacuum_freeze_table_age")) + settingFreezeTableAge = setting; + else + settingAutoVacuum = avSet.GetBool(wxT("setting")); + } + + tableVacBaseThr = wxT("-1"); + tableAnlBaseThr = wxT("-1"); + tableCostDelay = wxT("-1"); + tableCostLimit = wxT("-1"); + tableFreezeMinAge = wxT("-1"); + tableFreezeMaxAge = wxT("-1"); + tableVacFactor = wxT("-1"); + tableAnlFactor = wxT("-1"); + tableFreezeTableAge = wxT("-1"); + + toastTableVacBaseThr = wxT("-1"); + toastTableCostDelay = wxT("-1"); + toastTableCostLimit = wxT("-1"); + toastTableFreezeMinAge = wxT("-1"); + toastTableFreezeMaxAge = wxT("-1"); + toastTableVacFactor = wxT("-1"); + toastTableFreezeTableAge = wxT("-1"); + + toastTableHasVacuum = false; + toastTableVacEnabled = false; + + if (!connection->BackendMinimumVersion(8, 4)) + { + pgSetIterator set(connection, wxT("SELECT * FROM pg_autovacuum WHERE vacrelid=") + table->GetOidStr()); + if (set.RowsLeft()) + { + hasVacuum = true; + + tableVacEnabled = set.GetBool(wxT("enabled")); + chkVacEnabled->SetValue(tableVacEnabled); + + tableVacBaseThr = set.GetVal(wxT("vac_base_thresh")); + tableAnlBaseThr = set.GetVal(wxT("anl_base_thresh")); + tableCostDelay = set.GetVal(wxT("vac_cost_delay")); + tableCostLimit = set.GetVal(wxT("vac_cost_limit")); + tableVacFactor = set.GetVal(wxT("vac_scale_factor")); + tableAnlFactor = set.GetVal(wxT("anl_scale_factor")); + + if (connection->BackendMinimumVersion(8, 2)) + { + tableFreezeMinAge = set.GetVal(wxT("freeze_min_age")); + tableFreezeMaxAge = set.GetVal(wxT("freeze_max_age")); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(true); + } + } + else if (table) + { + if (table->GetAutoVacuumEnabled() == 2) + tableVacEnabled = settingAutoVacuum; + else + tableVacEnabled = table->GetAutoVacuumEnabled() == 1; + if (!table->GetAutoVacuumVacuumThreshold().IsEmpty()) + tableVacBaseThr = table->GetAutoVacuumVacuumThreshold(); + if (!table->GetAutoVacuumAnalyzeThreshold().IsEmpty()) + tableAnlBaseThr = table->GetAutoVacuumAnalyzeThreshold(); + if (!table->GetAutoVacuumVacuumScaleFactor().IsEmpty()) + tableVacFactor = table->GetAutoVacuumVacuumScaleFactor(); + if (!table->GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + tableAnlFactor = table->GetAutoVacuumAnalyzeScaleFactor(); + if (!table->GetAutoVacuumVacuumCostDelay().IsEmpty()) + tableCostDelay = table->GetAutoVacuumVacuumCostDelay(); + if (!table->GetAutoVacuumVacuumCostLimit().IsEmpty()) + tableCostLimit = table->GetAutoVacuumVacuumCostLimit(); + if (!table->GetAutoVacuumFreezeMinAge().IsEmpty()) + tableFreezeMinAge = table->GetAutoVacuumFreezeMinAge(); + if (!table->GetAutoVacuumFreezeMaxAge().IsEmpty()) + tableFreezeMaxAge = table->GetAutoVacuumFreezeMaxAge(); + if (!table->GetAutoVacuumFreezeTableAge().IsEmpty()) + tableFreezeTableAge = table->GetAutoVacuumFreezeTableAge(); + + hasVacuum = table->GetCustomAutoVacuumEnabled(); + chkVacEnabled->SetValue(hasVacuum ? tableVacEnabled : settingAutoVacuum); + + toastTableVacEnabled = false; + + if (!table->GetHasToastTable()) + { + nbVaccum->GetPage(1)->Enable(false); + } + else + { + toastTableHasVacuum = table->GetToastCustomAutoVacuumEnabled(); + if (toastTableHasVacuum) + { + if (table->GetToastAutoVacuumEnabled() == 2) + toastTableVacEnabled = settingAutoVacuum; + else + toastTableVacEnabled = table->GetToastAutoVacuumEnabled() == 1; + if (!table->GetToastAutoVacuumVacuumThreshold().IsEmpty()) + toastTableVacBaseThr = table->GetToastAutoVacuumVacuumThreshold(); + if (!table->GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + toastTableVacFactor = table->GetToastAutoVacuumVacuumScaleFactor(); + if (!table->GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + toastTableCostDelay = table->GetToastAutoVacuumVacuumCostDelay(); + if (!table->GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + toastTableCostLimit = table->GetToastAutoVacuumVacuumCostLimit(); + if (!table->GetToastAutoVacuumFreezeMinAge().IsEmpty()) + toastTableFreezeMinAge = table->GetToastAutoVacuumFreezeMinAge(); + if (!table->GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + toastTableFreezeMaxAge = table->GetToastAutoVacuumFreezeMaxAge(); + if (!table->GetToastAutoVacuumFreezeTableAge().IsEmpty()) + toastTableFreezeTableAge = table->GetToastAutoVacuumFreezeTableAge(); + } + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(settingAutoVacuum); + } + + //txtBaseVac->SetValue(tableVacBaseThr); + txtBaseAn->SetValue(tableAnlBaseThr); + txtFactorVac->SetValue(tableVacFactor); + txtFactorAn->SetValue(tableAnlFactor); + txtVacDelay->SetValue(tableCostDelay); + txtVacLimit->SetValue(tableCostLimit); + + if (connection->BackendMinimumVersion(8, 2)) + { + txtFreezeMinAge->SetValue(tableFreezeMinAge); + txtFreezeMaxAge->SetValue(tableFreezeMaxAge); + } + if (connection->BackendMinimumVersion(8, 4)) + { + txtFreezeTableAge->SetValue(tableFreezeTableAge); + txtBaseToastVac->SetValue(toastTableVacBaseThr); + txtFactorToastVac->SetValue(toastTableVacFactor); + txtToastVacDelay->SetValue(toastTableCostDelay); + txtToastVacLimit->SetValue(toastTableCostLimit); + txtToastFreezeMinAge->SetValue(toastTableFreezeMinAge); + txtToastFreezeMaxAge->SetValue(toastTableFreezeMaxAge); + txtToastFreezeTableAge->SetValue(toastTableFreezeTableAge); + + chkCustomToastVac->SetValue(toastTableHasVacuum); + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + chkCustomVac->SetValue(hasVacuum); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + else + { + /* Remove 'Vacuum Settings' Page */ + nbNotebook->DeletePage(TAB_AUTOVACUUM); + } + + // Find, and disable the RULE ACL option if we're 8.2 + if (connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("RULE"))) + { + wxLogError(_("Failed to disable the RULE privilege checkbox!")); + } + + if (table) + { + txtFillFactor->SetValue(table->GetFillFactor()); + } + + txtFillFactor->SetValidator(numericValidator); + txtFillFactor->Enable(); + } + else + { + txtFillFactor->Disable(); + } + + return dlgSecurityProperty::Go(modal); +} + + + +wxString dlgTable::GetItemConstraintType(ctlListView *list, long pos) +{ + wxString con; + wxListItem item; + item.SetId(pos); + item.SetColumn(0); + item.SetMask(wxLIST_MASK_IMAGE); + list->GetItem(item); + if (item.GetImage() == primaryKeyFactory.GetIconId()) + con = wxT("PRIMARY KEY"); + if (item.GetImage() == foreignKeyFactory.GetIconId()) + con = wxT("FOREIGN KEY"); + if (item.GetImage() == excludeFactory.GetIconId()) + con = wxT("EXCLUDE"); + if (item.GetImage() == uniqueFactory.GetIconId()) + con = wxT("UNIQUE"); + if (item.GetImage() == checkFactory.GetIconId()) + con = wxT("CHECK"); + return con; +} + + +wxString dlgTable::GetSql() +{ + int pos; + wxString sql; + wxString tabname; + + if (table) + { + int pos; + int index = -1; + + wxString definition; + + wxArrayString tmpDef = previousColumns; + wxString tmpsql; + + tabname = schema->GetQuotedPrefix() + qtIdent(GetName()); + + // Build a temporary list of ADD COLUMNs, and fixup the list to remove + for (pos = 0; pos < lstColumns->GetItemCount() ; pos++) + { + index = -1; + + if (lstColumns->GetText(pos, COL_INHERIT).IsEmpty()) + { + definition = lstColumns->GetText(pos, COL_SQLCHANGE); + if (definition.IsEmpty()) + { + definition = qtIdent(lstColumns->GetText(pos)) + wxT(" ") + lstColumns->GetText(pos, COL_DEFINITION); + index = tmpDef.Index(definition); + if (index < 0) + { + tmpsql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n ADD COLUMN ") + definition + wxT(";\n"); + } + } + else + { + tmpsql += definition; + + pgColumn *column = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_PGCOLUMN)); + if (column) + { + index = tmpDef.Index(column->GetQuotedIdentifier() + + wxT(" ") + column->GetDefinition()); + } + } + } + else + { + if (! lstColumns->GetText(pos, COL_INHERIT).IsEmpty()) + { + definition = qtIdent(lstColumns->GetText(pos)) + wxT(" ") + lstColumns->GetText(pos, COL_DEFINITION); + index = tmpDef.Index(definition); + } + } + if (index >= 0 && index < (int)tmpDef.GetCount()) + tmpDef.RemoveAt(index); + } + + + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + if (definition[0U] == '"') + definition = definition.Mid(1).BeforeFirst('"'); + else + definition = definition.BeforeFirst(' '); + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n DROP COLUMN ") + qtIdent(definition) + wxT(";\n"); + } + // Add the ADD COLUMNs... + sql += tmpsql; + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("TABLE ") + tabname); + + tmpDef = previousTables; + tmpsql.Empty(); + + // Build a temporary list of INHERIT tables, and fixup the list to remove + for (pos = 0 ; pos < (int)lbTables->GetCount() ; pos++) + { + definition = lbTables->GetString(pos); + index = tmpDef.Index(definition); + if (index < 0) + tmpsql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n INHERIT ") + definition + wxT(";\n"); + else + tmpDef.RemoveAt(index); + } + + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + // We don't need to quote the table because it's already quoted + sql += wxT("ALTER TABLE ") + table->GetQuotedFullIdentifier() + + wxT("\n NO INHERIT ") + definition + wxT(";\n"); + } + // Add the INHERIT COLUMNs... + sql += tmpsql; + + tmpDef = previousConstraints; + tmpsql.Empty(); + + // Build a temporary list of ADD CONSTRAINTs, and fixup the list to remove + for (pos = 0; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString conname = qtIdent(lstConstraints->GetItemText(pos)); + definition = conname; + definition += wxT(" ") + GetItemConstraintType(lstConstraints, pos) + + wxT(" ") + constraintsDefinition.Item(pos); + index = tmpDef.Index(definition); + if (index >= 0) + tmpDef.RemoveAt(index); + else + { + tmpsql += wxT("ALTER TABLE ") + tabname + + wxT("\n ADD"); + if (!conname.IsEmpty()) + tmpsql += wxT(" CONSTRAINT "); + + tmpsql += definition + wxT(";\n"); + } + } + + for (index = 0 ; index < (int)tmpDef.GetCount() ; index++) + { + definition = tmpDef.Item(index); + if (definition[0U] == '"') + definition = definition.Mid(1).BeforeFirst('"'); + else + definition = definition.BeforeFirst(' '); + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n DROP CONSTRAINT ") + qtIdent(definition) + wxT(";\n"); + + } + // Add the ADD CONSTRAINTs... + sql += tmpsql; + + if (!chkHasOids->GetValue() && table->GetHasOids()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET WITHOUT OIDS;\n"); + } + if (chkHasOids->GetValue() && !table->GetHasOids()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET WITH OIDS;\n"); + } + if (connection->BackendMinimumVersion(8, 0) && cbTablespace->GetOIDKey() != table->GetTablespaceOid()) + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET TABLESPACE ") + qtIdent(cbTablespace->GetValue()) + + wxT(";\n"); + + if (txtFillFactor->GetValue().Trim().Length() > 0 && txtFillFactor->GetValue() != table->GetFillFactor()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + + if (connection->BackendMinimumVersion(8, 1)) + { + if (!chkCustomVac->GetValue()) + { + if (hasVacuum) + { + if (connection->BackendMinimumVersion(8, 4)) + sql += wxT("ALTER TABLE ") + tabname + + wxT(" RESET(\n") + wxT(" autovacuum_enabled,\n") + wxT(" autovacuum_vacuum_threshold,\n") + wxT(" autovacuum_analyze_threshold,\n") + wxT(" autovacuum_vacuum_scale_factor,\n") + wxT(" autovacuum_analyze_scale_factor,\n") + wxT(" autovacuum_vacuum_cost_delay,\n") + wxT(" autovacuum_vacuum_cost_limit,\n") + wxT(" autovacuum_freeze_min_age,\n") + wxT(" autovacuum_freeze_max_age,\n") + wxT(" autovacuum_freeze_table_age\n") + wxT(");\n"); + else + sql += wxT("DELETE FROM pg_autovacuum WHERE vacrelid=") + table->GetOidStr() + wxT(";\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkVacEnabled->GetValue() != tableVacEnabled); + if (connection->BackendMinimumVersion(8, 4)) + { + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER TABLE ") + tabname + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER TABLE ") + tabname + resetStr + wxT("\n);\n");; + changed = true; + } + } + else if (!hasVacuum) + { + if (connection->BackendMinimumVersion(8, 2)) + { + vacStr = wxT("INSERT INTO pg_autovacuum(vacrelid, enabled, vac_base_thresh, anl_base_thresh, vac_scale_factor, anl_scale_factor, vac_cost_delay, vac_cost_limit, freeze_min_age, freeze_max_age)") + wxT("\n VALUES(") + + table->GetOidStr() + wxT(", ") + + BoolToStr(chkVacEnabled->GetValue()) + wxT(", ") + + AppendNum(changed, txtBaseVac, tableVacBaseThr) + wxT(", ") + + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + wxT(", ") + + AppendNum(changed, txtFactorVac, tableVacFactor) + wxT(", ") + + AppendNum(changed, txtFactorAn, tableAnlFactor) + wxT(", ") + + AppendNum(changed, txtVacDelay, tableCostDelay) + wxT(", ") + + AppendNum(changed, txtVacLimit, tableCostLimit) + wxT(", ") + + AppendNum(changed, txtFreezeMinAge, tableFreezeMinAge) + wxT(", ") + + AppendNum(changed, txtFreezeMaxAge, tableFreezeMaxAge) + wxT(");\n"); + } + else + { + vacStr = wxT("INSERT INTO pg_autovacuum(vacrelid, enabled, vac_base_thresh, anl_base_thresh, vac_scale_factor, anl_scale_factor, vac_cost_delay, vac_cost_limit)") + wxT("\n VALUES(") + + table->GetOidStr() + wxT(", ") + + BoolToStr(chkVacEnabled->GetValue()) + wxT(", ") + + AppendNum(changed, txtBaseVac, tableVacBaseThr) + wxT(", ") + + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + wxT(", ") + + AppendNum(changed, txtFactorVac, tableVacFactor) + wxT(", ") + + AppendNum(changed, txtFactorAn, tableAnlFactor) + wxT(", ") + + AppendNum(changed, txtVacDelay, tableCostDelay) + wxT(", ") + + AppendNum(changed, txtVacLimit, tableCostLimit) + wxT(");\n"); + } + } + else + { + if (connection->BackendMinimumVersion(8, 2)) + { + vacStr = wxT("UPDATE pg_autovacuum\n") + wxT(" SET enabled=") + + BoolToStr(chkVacEnabled->GetValue()) + + wxT(", vac_base_thresh = ") + AppendNum(changed, txtBaseVac, tableVacBaseThr) + + wxT(", anl_base_thresh = ") + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + + wxT(", vac_scale_factor = ") + AppendNum(changed, txtFactorVac, tableVacFactor) + + wxT(", anl_scale_factor = ") + AppendNum(changed, txtFactorAn, tableAnlFactor) + + wxT(", vac_cost_delay = ") + AppendNum(changed, txtVacDelay, tableCostDelay) + + wxT(", vac_cost_limit = ") + AppendNum(changed, txtVacLimit, tableCostLimit) + + wxT(", freeze_min_age = ") + AppendNum(changed, txtFreezeMinAge, tableFreezeMinAge) + + wxT(", freeze_max_age = ") + AppendNum(changed, txtFreezeMaxAge, tableFreezeMaxAge) + + wxT("\n WHERE vacrelid=") + table->GetOidStr() + wxT(";\n"); + } + else + { + vacStr = wxT("UPDATE pg_autovacuum\n") + wxT(" SET enabled=") + + BoolToStr(chkVacEnabled->GetValue()) + + wxT(", vac_base_thresh = ") + AppendNum(changed, txtBaseVac, tableVacBaseThr) + + wxT(", anl_base_thresh = ") + AppendNum(changed, txtBaseAn, tableAnlBaseThr) + + wxT(", vac_scale_factor = ") + AppendNum(changed, txtFactorVac, tableVacFactor) + + wxT(", anl_scale_factor = ") + AppendNum(changed, txtFactorAn, tableAnlFactor) + + wxT(", vac_cost_delay = ") + AppendNum(changed, txtVacDelay, tableCostDelay) + + wxT(", vac_cost_limit = ") + AppendNum(changed, txtVacLimit, tableCostLimit) + + wxT("\n WHERE vacrelid=") + table->GetOidStr() + wxT(";\n"); + } + + } + if (changed) + sql += vacStr; + } + } + if (connection->BackendMinimumVersion(8, 4)) + { + if (!chkCustomToastVac->GetValue()) + { + if (toastTableHasVacuum) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT(" RESET(\n") + wxT(" toast.autovacuum_enabled,\n") + wxT(" toast.autovacuum_vacuum_threshold,\n") + wxT(" toast.autovacuum_analyze_threshold,\n") + wxT(" toast.autovacuum_vacuum_scale_factor,\n") + wxT(" toast.autovacuum_analyze_scale_factor,\n") + wxT(" toast.autovacuum_vacuum_cost_delay,\n") + wxT(" toast.autovacuum_vacuum_cost_limit,\n") + wxT(" toast.autovacuum_freeze_min_age,\n") + wxT(" toast.autovacuum_freeze_max_age,\n") + wxT(" toast.autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkToastVacEnabled->GetValue() != toastTableVacEnabled); + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER TABLE ") + tabname + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER TABLE ") + tabname + resetStr + wxT("\n);\n");; + changed = true; + } + if (changed) + sql += vacStr; + } + } + // This needs to always be last so that other statements use correct schema + if (connection->BackendMinimumVersion(8, 1) && cbSchema->GetValue() != table->GetSchema()->GetName()) + { + AppendSchemaChange(sql, wxT("TABLE ") + tabname); + } + } + else + { + bool needComma = false; + bool typedTable = cbOfType->GetCurrentSelection() > 0 && cbOfType->GetOIDKey() > 0; + + tabname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + + sql = wxT("CREATE "); + if (chkUnlogged->GetValue()) + sql += wxT("UNLOGGED "); + sql += wxT("TABLE ") + tabname; + if (typedTable) + sql += wxT("\nOF ") + qtIdent(cbOfType->GetValue()); + + if (!typedTable || (typedTable && lstConstraints->GetItemCount() > 0)) + sql += wxT("\n("); + + if (!cbLikeRelation->GetValue().IsEmpty()) + { + sql += wxT("\n LIKE ") + cbLikeRelation->GetValue(); + if (chkIncludingDefaults->GetValue()) + sql += wxT(" INCLUDING DEFAULTS"); + if (chkIncludingConstraints->GetValue()) + sql += wxT(" INCLUDING CONSTRAINTS"); + if (chkIncludingIndexes->GetValue()) + sql += wxT(" INCLUDING INDEXES"); + if (chkIncludingStorage->GetValue()) + sql += wxT(" INCLUDING STORAGE"); + if (chkIncludingComments->GetValue()) + sql += wxT(" INCLUDING COMMENTS"); + needComma = true; + } + + if (!typedTable) + { + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (lstColumns->GetText(pos, COL_INHERIT).IsEmpty()) + { + // standard definition, not inherited + if (needComma) + sql += wxT(", "); + else + needComma = true; + + wxString name = lstColumns->GetText(pos); + wxString definition = lstColumns->GetText(pos, COL_DEFINITION); + + sql += wxT("\n ") + qtIdent(name) + + wxT(" ") + definition; + } + } + } + + for (pos = 0 ; pos < lstConstraints->GetItemCount() ; pos++) + { + wxString name = lstConstraints->GetItemText(pos); + wxString definition = constraintsDefinition.Item(pos); + + if (needComma) + sql += wxT(", "); + else + needComma = true; + + sql += wxT("\n "); + if (!name.IsEmpty()) + sql += wxT("CONSTRAINT ") + qtIdent(name) + wxT(" "); + sql += GetItemConstraintType(lstConstraints, pos) + wxT(" ") + definition; + } + + if (!typedTable || (typedTable && lstConstraints->GetItemCount() > 0)) + sql += wxT("\n) "); + + + if (lbTables->GetCount() > 0) + { + sql += wxT("\nINHERITS ("); + + unsigned int i; + for (i = 0 ; i < lbTables->GetCount() ; i++) + { + if (i) + sql += wxT(", "); + sql += lbTables->GetString(i); + } + sql += wxT(")"); + } + + if (connection->BackendMinimumVersion(8, 2)) + { + sql += wxT("\nWITH ("); + if (txtFillFactor->GetValue().Trim().Length() > 0) + sql += wxT("\n FILLFACTOR = ") + txtFillFactor->GetValue() + wxT(", "); + if (chkHasOids->GetValue()) + sql += wxT("\n OIDS = TRUE"); + else + sql += wxT("\n OIDS = FALSE"); + if (connection->BackendMinimumVersion(8, 4) && chkCustomVac->GetValue()) + { + bool valChanged = false; + wxString newVal; + wxString resetStr; + + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + } + if (connection->BackendMinimumVersion(8, 4) && chkCustomToastVac->GetValue()) + { + bool valChanged = false; + wxString newVal; + wxString resetStr; + + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + } + + sql += wxT("\n)\n"); + } + else + { + sql += (chkHasOids->GetValue() ? wxT("\nWITH OIDS") : wxT("\nWITHOUT OIDS")); + } + + if (cbTablespace->GetCurrentSelection() > 0 && cbTablespace->GetOIDKey() > 0) + sql += wxT("\nTABLESPACE ") + qtIdent(cbTablespace->GetValue()); + + sql += wxT(";\n"); + + AppendOwnerNew(sql, wxT("TABLE ") + tabname); + + // Extra column info + // Statistics + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (!lstColumns->GetText(pos, COL_STATISTICS).IsEmpty()) + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n ALTER COLUMN ") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT("\n SET STATISTICS ") + lstColumns->GetText(pos, COL_STATISTICS) + + wxT(";\n"); + } + } + + //variables + for (pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + wxStringTokenizer varToken(lstColumns->GetText(pos, COL_VARIABLE_LIST), wxT(",")); + while (varToken.HasMoreTokens()) + { + sql += wxT("ALTER TABLE ") + tabname + + wxT("\n ALTER COLUMN ") + + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT(" \nSET ("); + sql += varToken.GetNextToken() + wxT(");\n"); + } + } + + //security labels + for (pos = 0; pos < lstColumns->GetItemCount(); pos++) + { + wxStringTokenizer varToken(lstColumns->GetText(pos, COL_SECLABEL_LIST), wxT(",")); + wxString providerLabel = wxEmptyString; + wxString provider = wxEmptyString; + while (varToken.HasMoreTokens()) + { + provider = varToken.GetNextToken(); + if(varToken.HasMoreTokens()) + providerLabel = varToken.GetNextToken(); + + sql += wxT("SECURITY LABEL FOR ") + provider + + wxT("\n ON COLUMN ") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT("\n IS ") + connection->qtDbString(providerLabel) + wxT(";\n"); + } + } + + // Comments + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (!lstColumns->GetText(pos, COL_COMMENTS).IsEmpty()) + sql += wxT("COMMENT ON COLUMN ") + tabname + + wxT(".") + qtIdent(lstColumns->GetText(pos, COL_NAME)) + + wxT(" IS ") + qtDbString(lstColumns->GetText(pos, COL_COMMENTS)) + + wxT(";\n"); + } + + AppendComment(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), table); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("TABLE"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + if (connection->BackendMinimumVersion(8, 4)) + sql += GetGrant(wxT("arwdDxt"), wxT("TABLE ") + tabname); + else if (connection->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdxt"), wxT("TABLE ") + tabname); + else + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + tabname); + + return sql; +} + + +void dlgTable::FillConstraint() +{ + cbConstrType->Clear(); + if (!hasPK) + cbConstrType->Append(_("Primary Key")); + +// chkHasOids->Enable(!table || (table && table->GetHasOids() && hasPK && connection->BackendMinimumVersion(7, 4))); + cbConstrType->Append(_("Foreign Key")); + cbConstrType->Append(_("Exclude Constraint")); + cbConstrType->Append(_("Unique")); + cbConstrType->Append(_("Check")); + cbConstrType->SetSelection(0); +} + + +pgObject *dlgTable::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = tableFactory.CreateObjects(collection, 0, wxT( + "\n AND rel.relname=") + qtDbString(name) + wxT( + "\n AND rel.relnamespace=") + schema->GetOidStr()); + + return obj; +} + + +wxString dlgTable::GetNumString(wxTextCtrl *ctl, bool enabled, const wxString &val) +{ + if (!enabled) + return val; + wxString str = ctl->GetValue(); + if (str.IsEmpty() || StrToLong(val) < 0) + return val; + else + return str; +} + + +wxString dlgTable::AppendNum(bool &changed, wxTextCtrl *ctl, wxString val) +{ + wxString str = ctl->GetValue(); + if (str.IsEmpty() || str.StartsWith(wxT("-"))) + str = wxT("-1"); + + changed |= (str != val); + return str; +} + + +#ifdef __WXMAC__ +void dlgTable::OnChangeSize(wxSizeEvent &ev) +{ + if (lstConstraints) + { + lstConstraints->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 150); + } + + lstColumns->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 150); + + dlgSecurityProperty::OnChangeSize(ev); +} +#endif + + +void dlgTable::OnChangeVacuum(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(8, 1)) + { + bool vacEn = chkCustomVac->GetValue() && chkVacEnabled->GetValue(); + chkVacEnabled->Enable(chkCustomVac->GetValue()); + + txtBaseVac->Enable(vacEn); + txtBaseAn->Enable(vacEn); + txtFactorVac->Enable(vacEn); + txtFactorAn->Enable(vacEn); + txtVacDelay->Enable(vacEn); + txtVacLimit->Enable(vacEn); + + if (connection->BackendMinimumVersion(8, 2)) + { + txtFreezeMinAge->Enable(vacEn); + txtFreezeMaxAge->Enable(vacEn); + } + else + { + txtFreezeMinAge->Enable(false); + txtFreezeMaxAge->Enable(false); + } + + stBaseVacCurr->SetLabel(tableVacBaseThr == wxT("-1") ? settingVacBaseThr : tableVacBaseThr); + stBaseAnCurr->SetLabel(tableAnlBaseThr == wxT("-1") ? settingAnlBaseThr : tableAnlBaseThr); + stFactorVacCurr->SetLabel(tableVacFactor == wxT("-1") ? settingVacFactor : tableVacFactor); + stFactorAnCurr->SetLabel(tableAnlFactor == wxT("-1") ? settingAnlFactor : tableAnlFactor); + stVacDelayCurr->SetLabel(tableCostDelay == wxT("-1") ? settingCostDelay : tableCostDelay); + stVacLimitCurr->SetLabel(tableCostLimit == wxT("-1") ? settingCostLimit : tableCostLimit); + + if (connection->BackendMinimumVersion(8, 2)) + { + stFreezeMinAgeCurr->SetLabel(tableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : tableFreezeMinAge); + stFreezeMaxAgeCurr->SetLabel(tableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : tableFreezeMaxAge); + } + if (connection->BackendMinimumVersion(8, 4)) + { + txtFreezeTableAge->Enable(vacEn); + stFreezeTableAgeCurr->SetLabel(tableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : tableFreezeTableAge); + /* Toast Table Vacuum Settings */ + bool toastVacEn = chkCustomToastVac->GetValue() && chkToastVacEnabled->GetValue(); + chkToastVacEnabled->Enable(chkCustomToastVac->GetValue()); + + txtBaseToastVac->Enable(toastVacEn); + txtFactorToastVac->Enable(toastVacEn); + txtToastVacDelay->Enable(toastVacEn); + txtToastVacLimit->Enable(toastVacEn); + txtToastFreezeMinAge->Enable(toastVacEn); + txtToastFreezeMaxAge->Enable(toastVacEn); + txtToastFreezeTableAge->Enable(toastVacEn); + + stBaseToastVacCurr->SetLabel(toastTableVacBaseThr == wxT("-1") ? settingVacBaseThr : toastTableVacBaseThr); + stFactorToastVacCurr->SetLabel(toastTableVacFactor == wxT("-1") ? settingVacFactor : toastTableVacFactor); + stToastVacDelayCurr->SetLabel(toastTableCostDelay == wxT("-1") ? settingCostDelay : toastTableCostDelay); + stToastVacLimitCurr->SetLabel(toastTableCostLimit == wxT("-1") ? settingCostLimit : toastTableCostLimit); + stToastFreezeMinAgeCurr->SetLabel(toastTableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : toastTableFreezeMinAge); + stToastFreezeMaxAgeCurr->SetLabel(toastTableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : toastTableFreezeMaxAge); + txtToastFreezeTableAge->Enable(toastVacEn); + stToastFreezeTableAgeCurr->SetLabel(toastTableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : toastTableFreezeTableAge); + } + else + { + stFreezeTableAgeCurr->SetLabel(wxEmptyString); + txtFreezeTableAge->Enable(false); + } + } + OnChange(ev); +} + + +void dlgTable::OnChangeTable(wxCommandEvent &ev) +{ + cbTables->GuessSelection(ev); + btnAddTable->Enable((table || connection->BackendMinimumVersion(8, 2)) && cbTables->GetGuessedSelection() >= 0); +} + + +void dlgTable::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + if (lstColumns->GetItemCount() > 0 && !hasPK + && frmHint::ShowHint(this, HINT_PRIMARYKEY) == wxID_CANCEL) + return; + + dlgProperty::OnOK(ev); +} + + +void dlgTable::CheckChange() +{ + bool enable = true; + if (table) + { + enable = false; + if (connection->BackendMinimumVersion(7, 4) || lstColumns->GetItemCount() > 0) + { + enable = !GetSql().IsEmpty(); + } + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, connection->BackendMinimumVersion(7, 4) || lstColumns->GetItemCount() > 0, + _("Please specify columns.")); + } + EnableOK(enable); +} + + +void dlgTable::OnAddTable(wxCommandEvent &ev) +{ + int sel = cbTables->GetGuessedSelection(); + if (sel >= 0) + { + wxString tabname = cbTables->GetValue(); + wxString taboid = tableOids.Item(sel); + inheritedTableOids.Add(taboid); + tableOids.RemoveAt(sel); + + lbTables->Append(tabname); + cbTables->Delete(sel); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT attname, format_type(atttypid, NULL) AS atttype FROM pg_attribute\n") + wxT (" WHERE NOT attisdropped AND attnum>0 AND attrelid=") + taboid); + if (set) + { + bool found; + while (!set->Eof()) + { + found = false; + + size_t row = lstColumns->GetItemCount(); + while (row--) + { + if (set->GetVal(wxT("attname")).Cmp(lstColumns->GetText(row, COL_NAME)) == 0) + { + found = true; + break; + } + } + + if (found) + { + lstColumns->SetItem(row, COL_INHERIT, tabname); + } + else + { + lstColumns->AppendItem(tableFactory.GetIconId(), + set->GetVal(wxT("attname")), + set->GetVal(wxT("atttype")), + tabname); + } + set->MoveNext(); + } + delete set; + } + CheckChange(); + } +} + + +void dlgTable::OnRemoveTable(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected table?"), _("Remove table?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + int sel = lbTables->GetSelection(); + if (sel >= 0) + { + wxString tabname = lbTables->GetStringSelection(); + tableOids.Add(inheritedTableOids.Item(sel)); + inheritedTableOids.RemoveAt(sel); + + lbTables->Delete(sel); + cbTables->Append(tabname); + + size_t row = lstColumns->GetItemCount(); + while (row--) + { + if (tabname == lstColumns->GetText(row, COL_INHERIT)) + { + lstColumns->SetItem(row, COL_INHERIT, wxT("")); + } + } + CheckChange(); + } + btnRemoveTable->Disable(); +} + + +void dlgTable::OnSelChangeTable(wxCommandEvent &ev) +{ + btnRemoveTable->Enable(); +} + + +void dlgTable::OnChangeOfType(wxCommandEvent &ev) +{ + if (cbOfType->GetCurrentSelection() > 0) + { + if (settings->GetConfirmDelete() && lstColumns->GetItemCount() > 0) + { + if (wxMessageBox(_("A typed table only has the type's columns. All other columns will be dropped. Are you sure you want to do this?"), _("Remove all columns?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + { + lstColumns->DeleteAllItems(); + lstConstraints->DeleteAllItems(); + constraintsDefinition.Clear(); + hasPK = false; + FillConstraint(); + } + else + { + cbOfType->SetSelection(0); + return; + } + } + + pgSet *set = connection->ExecuteSet( + wxT("SELECT a.attname, format_type(atttypid, NULL) AS atttypname ") + wxT("FROM pg_attribute a, pg_class c\n") + wxT("WHERE NOT a.attisdropped AND a.attnum>0 ") + wxT("AND a.attrelid=c.oid AND c.relname='") + qtIdent(cbOfType->GetValue()) + wxT("'")); + if (set) + { + while (!set->Eof()) + { + lstColumns->AppendItem(tableFactory.GetIconId(), + set->GetVal(wxT("attname")), + set->GetVal(wxT("atttypname")), + wxT("")); + set->MoveNext(); + } + delete set; + } + } + else + { + if (settings->GetConfirmDelete() && lstColumns->GetItemCount() > 0) + { + if (wxMessageBox(_("All type's columns will be dropped. Are you sure you want to do this?"), _("Remove all columns?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + { + lstColumns->DeleteAllItems(); + lstConstraints->DeleteAllItems(); + constraintsDefinition.Clear(); + hasPK = false; + FillConstraint(); + } + } + } + + btnAddCol->Enable(cbOfType->GetCurrentSelection() == 0); + cbTables->Enable(connection->BackendMinimumVersion(8, 2) && cbOfType->GetCurrentSelection() == 0); + btnRemoveCol->Enable(false); + CheckChange(); +} + +void dlgTable::OnChangeCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + pgColumn *column = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_PGCOLUMN)); + pgColumn *column2 = (pgColumn *) StrToLong(lstColumns->GetText(pos, COL_CHANGEDCOL)); + + dlgColumn col(&columnFactory, mainForm, column, table); + col.CenterOnParent(); + col.SetDatabase(database); + col.SetChangedCol(column2); + if (col.Go(true) != wxID_CANCEL) + { + if(column2 == NULL) + column2 = new pgColumn(*column); + + col.ApplyChangesToObj(column2); + lstColumns->SetItem(pos, COL_NAME, col.GetName()); + lstColumns->SetItem(pos, COL_DEFINITION, col.GetDefinition()); + lstColumns->SetItem(pos, COL_SQLCHANGE, col.GetSql()); + lstColumns->SetItem(pos, COL_STATISTICS, col.GetStatistics()); + lstColumns->SetItem(pos, COL_COMMENTS, col.GetComment()); + lstColumns->SetItem(pos, COL_CHANGEDCOL, NumToStr((long)column2)); + } + CheckChange(); +} + +// Cache datatypes to avoid multiple calls to server when adding multiple columns to a table. +void dlgTable::PopulateDatatypeCache() +{ + DatatypeReader tr(database, true, true); + while (tr.HasMore()) + { + pgDatatype dt = tr.GetDatatype(); + + dataType *dType = new dataType(); + dType->SetOid(tr.GetOid()); + dType->SetTypename(dt.GetQuotedSchemaPrefix(database) + dt.QuotedFullName()); + dtCache.Add(dType); + + tr.MoveNext(); + } +} + + +void dlgTable::OnAddCol(wxCommandEvent &ev) +{ + dlgColumn col(&columnFactory, mainForm, NULL, table); + col.CenterOnParent(); + col.SetDatabase(database); + col.SetDatatypeCache(dtCache); + if (col.Go(true) != wxID_CANCEL) + { + long pos = lstColumns->AppendItem(columnFactory.GetIconId(), col.GetName(), col.GetDefinition()); + if (table && !connection->BackendMinimumVersion(8, 0)) + lstColumns->SetItem(pos, COL_SQLCHANGE, col.GetSql()); + lstColumns->SetItem(pos, COL_STATISTICS, col.GetStatistics()); + lstColumns->SetItem(pos, COL_COMMENTS, col.GetComment()); + lstColumns->SetItem(pos, COL_TYPEOID, col.GetTypeOid()); + + wxString perColumnListString = wxEmptyString; + + //getting the variable list for each column + wxArrayString perColumnList; + col.GetVariableList(perColumnList); + for(size_t index = 0; index < perColumnList.GetCount(); index++) + { + if (index == 0) + perColumnListString = perColumnList.Item(index); + else + perColumnListString += wxT(",") + perColumnList.Item(index); + } + lstColumns->SetItem(pos, COL_VARIABLE_LIST, perColumnListString); + + //getting the security labels list for each column + if(connection->BackendMinimumVersion(9, 1)) + { + wxString secLabelListString = wxEmptyString; + wxArrayString secLabelList; + col.GetSecLabelList(secLabelList); + for(size_t index = 0; index < secLabelList.GetCount(); index++) + { + if (index == 0) + secLabelListString = secLabelList.Item(index); + else + secLabelListString += wxT(",") + secLabelList.Item(index); + } + lstColumns->SetItem(pos, COL_SECLABEL_LIST, secLabelListString); + } + } + + CheckChange(); +} + + +void dlgTable::OnRemoveCol(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected column?"), _("Remove column?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + lstColumns->DeleteCurrentItem(); + + btnChangeCol->Disable(); + btnRemoveCol->Disable(); + + CheckChange(); +} + + +void dlgTable::OnSelChangeCol(wxListEvent &ev) +{ + long pos = lstColumns->GetSelection(); + wxString inheritedFromTable = lstColumns->GetText(pos, COL_INHERIT); + + btnAddCol->Enable(!(cbOfType->GetCurrentSelection() > 0 && cbOfType->GetOIDKey() > 0)); + btnRemoveCol->Enable(inheritedFromTable.IsEmpty() && !(cbOfType->GetCurrentSelection() > 0 && cbOfType->GetOIDKey() > 0)); + btnChangeCol->Enable(table != 0 && !lstColumns->GetText(pos, COL_PGCOLUMN).IsEmpty() && inheritedFromTable.IsEmpty()); +} + + +void dlgTable::OnAddConstr(wxCommandEvent &ev) +{ + int sel = cbConstrType->GetCurrentSelection(); + if (hasPK) + sel++; + + switch (sel) + { + case 0: // Primary Key + { + dlgPrimaryKey pk(&primaryKeyFactory, mainForm, lstColumns); + pk.CenterOnParent(); + pk.SetDatabase(database); + if (pk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = pk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(primaryKeyFactory.GetIconId(), pk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + hasPK = true; + FillConstraint(); + } + break; + } + case 1: // Foreign Key + { + dlgForeignKey fk(&foreignKeyFactory, mainForm, lstColumns); + fk.CenterOnParent(); + fk.SetDatabase(database); + if (fk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = fk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + while (tmpDef.Contains(wxT(" "))) + tmpDef.Replace(wxT(" "), wxT(" ")); + + lstConstraints->AppendItem(foreignKeyFactory.GetIconId(), fk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + case 2: // Exclusion Constraint + { + dlgExclude ec(&excludeFactory, mainForm, lstColumns); + ec.CenterOnParent(); + ec.SetDatabase(database); + if (ec.Go(true) != wxID_CANCEL) + { + wxString tmpDef = ec.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + while (tmpDef.Contains(wxT(" "))) + tmpDef.Replace(wxT(" "), wxT(" ")); + + lstConstraints->AppendItem(excludeFactory.GetIconId(), ec.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + case 3: // Unique + { + dlgUnique unq(&uniqueFactory, mainForm, lstColumns); + unq.CenterOnParent(); + unq.SetDatabase(database); + if (unq.Go(true) != wxID_CANCEL) + { + wxString tmpDef = unq.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(uniqueFactory.GetIconId(), unq.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + case 4: // Check + { + dlgCheck chk(&checkFactory, mainForm); + chk.CenterOnParent(); + chk.SetDatabase(database); + if (chk.Go(true) != wxID_CANCEL) + { + wxString tmpDef = chk.GetDefinition(); + tmpDef.Replace(wxT("\n"), wxT(" ")); + + lstConstraints->AppendItem(checkFactory.GetIconId(), chk.GetName(), tmpDef); + constraintsDefinition.Add(tmpDef); + } + break; + } + } + CheckChange(); +} + + +void dlgTable::OnRemoveConstr(wxCommandEvent &ev) +{ + if (settings->GetConfirmDelete()) + { + if (wxMessageBox(_("Are you sure you wish to remove the selected constraint?"), _("Remove constraint?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + } + + int pos = lstConstraints->GetSelection(); + if (pos < 0) + return; + + wxListItem item; + item.SetId(pos); + item.SetColumn(0); + item.SetMask(wxLIST_MASK_IMAGE); + lstConstraints->GetItem(item); + if (item.GetImage() == primaryKeyFactory.GetIconId()) + { + hasPK = false; + FillConstraint(); + } + + lstConstraints->DeleteItem(pos); + constraintsDefinition.RemoveAt(pos); + btnRemoveConstr->Disable(); + + CheckChange(); +} + + +void dlgTable::OnSelChangeConstr(wxListEvent &ev) +{ + btnRemoveConstr->Enable(); +} + + +void dlgTable::FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, + const wxString ¶meter, const wxString &val) +{ + if (val == wxT("-1")) + { + if (resetStr.IsEmpty()) + resetStr = wxT(" RESET ("); + else + resetStr += wxT(","); + resetStr += wxT("\n ") + parameter; + } + else + { + if (setStr.IsEmpty()) + setStr = wxT(" SET ("); + else + setStr += wxT(","); + setStr += wxT("\n ") + parameter + wxT(" = ") + val; + } +} + + +void dlgTable::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgTablespace.cpp b/dlg/dlgTablespace.cpp new file mode 100644 index 0000000..81cc85e --- /dev/null +++ b/dlg/dlgTablespace.cpp @@ -0,0 +1,384 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTablespace.cpp - Tablespace property +// +////////////////////////////////////////////////////////////////////////// + + + +#include "pgAdmin3.h" + +// wxWindows headers +#include + + +// App headers +#include "utils/misc.h" +#include "dlg/dlgTablespace.h" +#include "schema/pgTablespace.h" +#include "ctl/ctlSeclabelPanel.h" + +// pointer to controls +#define txtLocation CTRL_TEXT("txtLocation") +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + +dlgProperty *pgTablespaceFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTablespace(this, frame, (pgTablespace *)node); +} + + +BEGIN_EVENT_TABLE(dlgTablespace, dlgSecurityProperty) + EVT_TEXT(XRCID("txtLocation"), dlgProperty::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgTablespace::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgTablespace::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgTablespace::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgTablespace::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgTablespace::OnVarnameSelChange) +END_EVENT_TABLE(); + + + +dlgTablespace::dlgTablespace(pgaFactory *f, frmMain *frame, pgTablespace *node) + : dlgSecurityProperty(f, frame, node, wxT("dlgTablespace"), wxT("CREATE"), "C") +{ + tablespace = node; + lstVariables->CreateColumns(0, _("Variable"), _("Value")); + chkValue->Hide(); + btnOK->Disable(); + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgTablespace::GetObject() +{ + return tablespace; +} + + +wxString dlgTablespace::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 1) + return wxT("pg/runtime-config"); + return dlgSecurityProperty::GetHelpPage(); +} + + +int dlgTablespace::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 2)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(tablespace); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgTablespace::OnChange)); + } + else + seclabelPage->Disable(); + + pgSet *set; + if (connection->BackendMinimumVersion(8, 5)) + { + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE name IN ('seq_page_cost', 'random_page_cost')")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + SetupVarEditor(0); + } + } + else + { + lstVariables->Enable(false); + btnAdd->Enable(false); + btnRemove->Enable(false); + cbVarname->Enable(false); + txtValue->Enable(false); + chkValue->Enable(false); + } + + if (tablespace) + { + // Edit Mode + txtName->SetValue(tablespace->GetIdentifier()); + txtLocation->SetValue(tablespace->GetLocation()); + txtComment->SetValue(tablespace->GetComment()); + + txtLocation->Disable(); + + size_t i; + for (i = 0 ; i < tablespace->GetVariables().GetCount() ; i++) + { + wxString item = tablespace->GetVariables().Item(i); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + } + else + { + } + + // Tablespace comments are only appropriate in 8.2+ + if (!connection->BackendMinimumVersion(8, 2)) + txtComment->Disable(); + + return dlgSecurityProperty::Go(modal); +} + + +#ifdef __WXMAC__ +void dlgTablespace::OnChangeSize(wxSizeEvent &ev) +{ + SetPrivilegesLayout(); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgTablespace::CheckChange() +{ + bool enable = true; + if (tablespace) + { + enable = txtComment->GetValue() != tablespace->GetComment() + || GetName() != tablespace->GetName() + || cbOwner->GetValue() != tablespace->GetOwner() + || dirtyVars; + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + CheckValid(enable, !GetName().IsEmpty(), _("Please specify name.")); + CheckValid(enable, !txtLocation->GetValue().IsEmpty(), _("Please specify location.")); + } + EnableOK(enable); +} + + +pgObject *dlgTablespace::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = tablespaceFactory.CreateObjects(collection, 0, wxT("\n WHERE spcname=") + qtDbString(name)); + return obj; +} + + +wxString dlgTablespace::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (tablespace) + { + // Edit Mode + + AppendNameChange(sql); + AppendOwnerChange(sql, wxT("TABLESPACE ") + qtIdent(name)); + + sql += GetGrant(wxT("C"), wxT("TABLESPACE ") + qtIdent(name)); + AppendComment(sql, wxT("TABLESPACE"), 0, tablespace); + + wxArrayString vars; + + size_t index; + + for (index = 0 ; index < tablespace->GetVariables().GetCount() ; index++) + vars.Add(tablespace->GetVariables().Item(index)); + + int cnt = lstVariables->GetItemCount(); + int pos; + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + sql += wxT("ALTER TABLESPACE ") + qtIdent(name) + + wxT("\n SET (") + newVar + + wxT("=") + newVal + + wxT(");\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER TABLESPACE ") + qtIdent(name) + + wxT("\n RESET (") + vars.Item(pos).BeforeFirst('=') + + wxT(");\n"); + } + } + else + { + // Create Mode + sql = wxT("CREATE TABLESPACE ") + qtIdent(name); + AppendIfFilled(sql, wxT("\n OWNER "), qtIdent(cbOwner->GetValue())); + sql += wxT("\n LOCATION ") + qtDbString(txtLocation->GetValue()) + + wxT(";\n"); + } + + if (seclabelPage && connection->BackendMinimumVersion(9, 2)) + sql += seclabelPage->GetSqlForSecLabels(wxT("TABLESPACE"), qtIdent(name)); + + + return sql; +} + +wxString dlgTablespace::GetSql2() +{ + wxString sql; + wxString name = GetName(); + + if (!tablespace) + { + sql += GetGrant(wxT("C"), wxT("TABLESPACE ") + qtIdent(name)); + AppendComment(sql, wxT("TABLESPACE"), 0, tablespace); + + // check for changed or added vars + for (int pos = 0 ; pos < lstVariables->GetItemCount() ; pos++) + { + sql += wxT("ALTER TABLESPACE ") + qtIdent(name) + + wxT("\n SET (") + lstVariables->GetText(pos) + + wxT("=") + lstVariables->GetText(pos, 1) + + wxT(");\n"); + } + } + + return sql; +} + +void dlgTablespace::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgTablespace::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + chkValue->SetSize(wxDefaultCoord, wxDefaultCoord, + cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight()); + } + else + { + chkValue->Hide(); + txtValue->Show(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + txtValue->SetSize(wxDefaultCoord, wxDefaultCoord, + cbVarname->GetSize().GetWidth(), cbVarname->GetSize().GetHeight()); + } + } +} + +void dlgTablespace::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + int sel = cbVarname->FindString(lstVariables->GetText(pos)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + +void dlgTablespace::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + dirtyVars = true; + CheckChange(); +} + + +void dlgTablespace::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() >= 0) + { + lstVariables->DeleteCurrentItem(); + dirtyVars = true; + CheckChange(); + } +} + + +void dlgTablespace::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} diff --git a/dlg/dlgTextSearchConfiguration.cpp b/dlg/dlgTextSearchConfiguration.cpp new file mode 100644 index 0000000..2d7c001 --- /dev/null +++ b/dlg/dlgTextSearchConfiguration.cpp @@ -0,0 +1,444 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchConfiguration.cpp - PostgreSQL Text Search Configuration Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchConfiguration.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbParser CTRL_COMBOBOX2("cbParser") +#define cbCopy CTRL_COMBOBOX2("cbCopy") +#define lstTokens CTRL_LISTVIEW("lstTokens") +#define cbToken CTRL_COMBOBOX2("cbToken") +#define txtDictionary CTRL_TEXT("txtDictionary") +#define cbDictionary CTRL_CHOICE("cbDictionary") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +BEGIN_EVENT_TABLE(dlgTextSearchConfiguration, dlgTypeProperty) + EVT_TEXT(XRCID("cbParser"), dlgTextSearchConfiguration::OnChange) + EVT_COMBOBOX(XRCID("cbParser"), dlgTextSearchConfiguration::OnChange) + EVT_TEXT(XRCID("cbCopy"), dlgTextSearchConfiguration::OnChange) + EVT_COMBOBOX(XRCID("cbCopy"), dlgTextSearchConfiguration::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstTokens"), dlgTextSearchConfiguration::OnSelChangeToken) + EVT_TEXT(XRCID("cbToken"), dlgTextSearchConfiguration::OnChangeCbToken) + EVT_COMBOBOX(XRCID("cbToken"), dlgTextSearchConfiguration::OnChangeCbToken) + EVT_TEXT(XRCID("txtDictionary"), dlgTextSearchConfiguration::OnChangeTxtDictionary) + EVT_CHOICE(XRCID("cbDictionary"), dlgTextSearchConfiguration::OnChangeCbDictionary) + EVT_BUTTON(wxID_ADD, dlgTextSearchConfiguration::OnAddToken) + EVT_BUTTON(wxID_REMOVE, dlgTextSearchConfiguration::OnRemoveToken) +#ifdef __WXMAC__ + EVT_SIZE( dlgTextSearchConfiguration::OnChangeSize) +#endif +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchConfigurationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchConfiguration(this, frame, (pgTextSearchConfiguration *)node, (pgSchema *)parent); +} + +dlgTextSearchConfiguration::dlgTextSearchConfiguration(pgaFactory *f, frmMain *frame, pgTextSearchConfiguration *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchConfiguration")) +{ + schema = sch; + config = node; + dirtyTokens = false; + + lstTokens->CreateColumns(0, _("Token"), _("Dictionaries")); + + cbCopy->Disable(); +} + + +pgObject *dlgTextSearchConfiguration::GetObject() +{ + return config; +} + + +int dlgTextSearchConfiguration::Go(bool modal) +{ + wxString qry; + pgSet *set; + + cbParser->Append(wxT("")); + + qry = wxT("SELECT prsname, nspname\n") + wxT(" FROM pg_ts_parser\n") + wxT(" JOIN pg_namespace n ON n.oid=prsnamespace\n") + wxT(" ORDER BY prsname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("prsname")); + cbParser->Append(procname); + set->MoveNext(); + } + delete set; + } + + cbCopy->Append(wxT("")); + + qry = wxT("SELECT cfgname, nspname\n") + wxT(" FROM pg_ts_config\n") + wxT(" JOIN pg_namespace n ON n.oid=cfgnamespace\n") + wxT(" ORDER BY nspname, cfgname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + cbCopy->Enable(); + while (!set->Eof()) + { + wxString configname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("cfgname")); + cbCopy->Append(configname); + set->MoveNext(); + } + delete set; + } + + if (config) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbParser->SetValue(config->GetParser()); + cbCopy->Disable(); + + // second tab handling + size_t i; + for (i = 0 ; i < config->GetTokens().GetCount() ; i++) + { + wxString token = config->GetTokens().Item(i); + lstTokens->AppendItem(token.BeforeFirst('/'), token.AfterFirst('/')); + } + + pgSet *tokens; + tokens = connection->ExecuteSet( + wxT("SELECT alias FROM ts_token_type(") + + config->GetParserOidStr() + + wxT(") ORDER BY alias")); + + if (tokens) + { + while (!tokens->Eof()) + { + cbToken->Append(tokens->GetVal(wxT("alias"))); + tokens->MoveNext(); + } + delete tokens; + } + + pgSet *dictionaries; + dictionaries = connection->ExecuteSet( + wxT("SELECT dictname FROM pg_ts_dict ORDER BY dictname")); + + if (dictionaries) + { + while (!dictionaries->Eof()) + { + cbDictionary->Append(dictionaries->GetVal(wxT("dictname"))); + dictionaries->MoveNext(); + } + delete dictionaries; + } + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + } + else + { + // create mode + } + + btnAdd->Disable(); + btnRemove->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchConfiguration::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchConfigurationFactory.CreateObjects(collection, 0, + wxT("\n AND cfg.cfgname=") + qtDbString(GetName()) + + wxT("\n AND cfg.cfgnamespace=") + schema->GetOidStr()); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgTextSearchConfiguration::OnChangeSize(wxSizeEvent &ev) +{ + lstTokens->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgTextSearchConfiguration::CheckChange() +{ + if (config) + { + EnableOK(txtName->GetValue() != config->GetName() + || cbSchema->GetValue() != config->GetSchema()->GetName() + || txtComment->GetValue() != config->GetComment() + || cbOwner->GetValue() != config->GetOwner() + || dirtyTokens); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbParser->GetGuessedSelection() > 0 || cbCopy->GetGuessedSelection() > 0 , _("Please select a parser or a configuration to copy.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchConfiguration::OnChange(wxCommandEvent &ev) +{ + cbParser->Enable(cbCopy->GetValue().Length() == 0); + cbCopy->Enable(cbParser->GetValue().Length() == 0); + + CheckChange(); +} + +void dlgTextSearchConfiguration::OnChangeCbToken(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++) + { + if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false)) + { + lstTokens->Select(pos); + found = true; + break; + } + } + + btnAdd->Enable(cbToken->GetValue().Length() > 0); +} + + +void dlgTextSearchConfiguration::OnChangeCbDictionary(wxCommandEvent &ev) +{ + if (!txtDictionary->GetValue().Matches(wxT("*") + cbDictionary->GetStringSelection() + wxT("*"))) + { + wxString dicts = txtDictionary->GetValue(); + if (dicts.Length() > 0) + dicts += wxT(","); + dicts += cbDictionary->GetStringSelection(); + + txtDictionary->SetValue(dicts); + } + btnAdd->Enable(cbToken->GetValue().Length() > 0); +} + + +void dlgTextSearchConfiguration::OnChangeTxtDictionary(wxCommandEvent &ev) +{ + btnAdd->Enable(cbToken->GetValue().Length() > 0); +} + + +void dlgTextSearchConfiguration::OnSelChangeToken(wxListEvent &ev) +{ + int row = lstTokens->GetSelection(); + if (row >= 0) + { + cbToken->SetValue(lstTokens->GetText(row, 0)); + txtDictionary->SetValue(lstTokens->GetText(row, 1)); + } + + btnAdd->Enable(cbToken->GetValue().Length() > 0); + btnRemove->Enable(row >= 0); +} + + +void dlgTextSearchConfiguration::OnAddToken(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++) + { + if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false)) + { + lstTokens->SetItem(pos, 1, txtDictionary->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstTokens->AppendItem(cbToken->GetValue(), txtDictionary->GetValue()); + } + + btnAdd->Disable(); + + dirtyTokens = true; + + CheckChange(); +} + + +void dlgTextSearchConfiguration::OnRemoveToken(wxCommandEvent &ev) +{ + for (int pos = 0 ; pos < lstTokens->GetItemCount() ; pos++) + { + if (lstTokens->GetText(pos).IsSameAs(cbToken->GetValue(), false)) + { + lstTokens->DeleteItem(pos); + break; + } + } + + cbToken->SetValue(wxT("")); + txtDictionary->SetValue(wxT("")); + + btnRemove->Disable(); + + dirtyTokens = true; + + CheckChange(); +} + + +wxString dlgTextSearchConfiguration::GetSql() +{ + wxString sql; + wxString objname; + + if (config) + { + objname = schema->GetQuotedPrefix() + qtIdent(config->GetName()); + } + else + { + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + } + + if (cbParser->GetValue().Length() > 0) + { + wxArrayString toks; + size_t index; + + if (config) + { + for (index = 0 ; index < config->GetTokens().GetCount() ; index++) + toks.Add(config->GetTokens().Item(index)); + } + + int cnt = lstTokens->GetItemCount(); + int pos; + + // check for changed or added tokens + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newTok = lstTokens->GetText(pos); + wxString newVal = lstTokens->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < toks.GetCount() ; index++) + { + wxString tok = toks.Item(index); + if (tok.BeforeFirst('/').IsSameAs(newTok, false)) + { + oldVal = tok.Mid(newTok.Length() + 1); + toks.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (oldVal.Length() == 0) + { + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname + + wxT("\n ADD MAPPING FOR ") + newTok + + wxT("\n WITH ") + newVal + + wxT(";\n"); + } + else + { + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname + + wxT("\n ALTER MAPPING FOR ") + newTok + + wxT("\n WITH ") + newVal + + wxT(";\n"); + } + } + } + + // check for removed tokens + wxString oldTok; + for (pos = 0 ; pos < (int)toks.GetCount() ; pos++) + { + if (!toks.Item(pos).BeforeFirst('/').IsSameAs(oldTok, false)) + { + oldTok = toks.Item(pos).BeforeFirst('/'); + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + objname + + wxT(" DROP MAPPING FOR ") + oldTok + + wxT(";\n"); + } + } + } + + if (config) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + config->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + objname); + AppendSchemaChange(sql, wxT("TEXT SEARCH CONFIGURATION ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH CONFIGURATION ") + + objname + + wxT(" ("); + + AppendIfFilled(sql, wxT("\n PARSER="), cbParser->GetValue()); + AppendIfFilled(sql, wxT("\n COPY="), cbCopy->GetValue()); + + sql += wxT("\n);\n"); + + } + + AppendComment(sql, wxT("TEXT SEARCH CONFIGURATION ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), config); + + return sql; +} diff --git a/dlg/dlgTextSearchDictionary.cpp b/dlg/dlgTextSearchDictionary.cpp new file mode 100644 index 0000000..83cffbd --- /dev/null +++ b/dlg/dlgTextSearchDictionary.cpp @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchDictionary.cpp - PostgreSQL Text Search Dictionary Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchDictionary.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbTemplate CTRL_COMBOBOX2("cbTemplate") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +BEGIN_EVENT_TABLE(dlgTextSearchDictionary, dlgTypeProperty) + EVT_TEXT(XRCID("cbTemplate"), dlgTextSearchDictionary::OnChange) + EVT_COMBOBOX(XRCID("cbTemplate"), dlgTextSearchDictionary::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgTextSearchDictionary::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgTextSearchDictionary::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgTextSearchDictionary::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgTextSearchDictionary::OnRemoveOption) +#ifdef __WXMAC__ + EVT_SIZE( dlgTextSearchDictionary::OnChangeSize) +#endif +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchDictionaryFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchDictionary(this, frame, (pgTextSearchDictionary *)node, (pgSchema *)parent); +} + +dlgTextSearchDictionary::dlgTextSearchDictionary(pgaFactory *f, frmMain *frame, pgTextSearchDictionary *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchDictionary")) +{ + schema = sch; + dict = node; +} + + +pgObject *dlgTextSearchDictionary::GetObject() +{ + return dict; +} + + +int dlgTextSearchDictionary::Go(bool modal) +{ + wxString qry; + pgSet *set; + + qry = wxT("SELECT tmplname, nspname\n") + wxT(" FROM pg_ts_template\n") + wxT(" JOIN pg_namespace n ON n.oid=tmplnamespace\n") + wxT(" ORDER BY tmplname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("tmplname")); + cbTemplate->Append(procname); + set->MoveNext(); + } + delete set; + } + + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + + if (dict) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbTemplate->SetValue(dict->GetTemplate()); + cbTemplate->Disable(); + + wxString options = dict->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + + if (!connection->BackendMinimumVersion(8, 0)) + cbOwner->Disable(); + } + else + { + // create mode + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchDictionary::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchDictionaryFactory.CreateObjects(collection, 0, + wxT("\n AND dict.dictname=") + qtDbString(GetName()) + + wxT("\n AND dict.dictnamespace=") + schema->GetOidStr()); + + return obj; +} + + +#ifdef __WXMAC__ +void dlgTextSearchDictionary::OnChangeSize(wxSizeEvent &ev) +{ + lstOptions->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 350); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgTextSearchDictionary::CheckChange() +{ + if (dict) + { + EnableOK(txtName->GetValue() != dict->GetName() + || cbSchema->GetValue() != dict->GetSchema()->GetName() + || txtComment->GetValue() != dict->GetComment() + || cbOwner->GetValue() != dict->GetOwner() + || GetOptionsSql().Length() > 0); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbTemplate->GetValue().Length() > 0 , _("Please select a template.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchDictionary::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgTextSearchDictionary::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgTextSearchDictionary::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgTextSearchDictionary::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgTextSearchDictionary::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgTextSearchDictionary::GetOptionsSql() +{ + wxString options = dict->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += optionname + wxT("=") + lstOptions->GetText(pos, 1); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = dict->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += lstOptions->GetText(pos, 0) + wxT("=") + lstOptions->GetText(pos, 1); + } + } + + return sqloptions; +} + + +wxString dlgTextSearchDictionary::GetSql() +{ + wxString sql; + wxString objname; + + if (dict) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH DICTIONARY ") + dict->GetQuotedFullIdentifier()); + + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER TEXT SEARCH DICTIONARY ") + objname + + wxT("\n (") + sqloptions + wxT(");\n"); + } + AppendOwnerChange(sql, wxT("TEXT SEARCH DICTIONARY ") + objname); + + AppendSchemaChange(sql, wxT("TEXT SEARCH DICTIONARY ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH DICTIONARY ") + + objname + + wxT("\n (") + + wxT("\n TEMPLATE = ") + cbTemplate->GetValue(); + + // check for options + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + sql += wxT(", ") + lstOptions->GetText(pos, 0) + + wxT("=") + lstOptions->GetText(pos, 1); + } + + sql += wxT("\n);\n"); + + AppendOwnerNew(sql, wxT("TEXT SEARCH DICTIONARY ") + objname); + } + + AppendComment(sql, wxT("TEXT SEARCH DICTIONARY ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), dict); + + return sql; +} diff --git a/dlg/dlgTextSearchParser.cpp b/dlg/dlgTextSearchParser.cpp new file mode 100644 index 0000000..ecb667f --- /dev/null +++ b/dlg/dlgTextSearchParser.cpp @@ -0,0 +1,262 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchParser.cpp - PostgreSQL Text Search Parser Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchParser.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbStart CTRL_COMBOBOX2("cbStart") +#define cbGetToken CTRL_COMBOBOX2("cbGetToken") +#define cbEnd CTRL_COMBOBOX2("cbEnd") +#define cbLextypes CTRL_COMBOBOX2("cbLextypes") +#define cbHeadline CTRL_COMBOBOX2("cbHeadline") + + +BEGIN_EVENT_TABLE(dlgTextSearchParser, dlgTypeProperty) + EVT_TEXT(XRCID("cbStart"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbStart"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbGetToken"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbGetToken"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbEnd"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbEnd"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbLextypes"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbLextypes"), dlgTextSearchParser::OnChange) + EVT_TEXT(XRCID("cbHeadline"), dlgTextSearchParser::OnChange) + EVT_COMBOBOX(XRCID("cbHeadline"), dlgTextSearchParser::OnChange) +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchParserFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchParser(this, frame, (pgTextSearchParser *)node, (pgSchema *)parent); +} + +dlgTextSearchParser::dlgTextSearchParser(pgaFactory *f, frmMain *frame, pgTextSearchParser *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchParser")) +{ + schema = sch; + parser = node; +} + + +pgObject *dlgTextSearchParser::GetObject() +{ + return parser; +} + + +int dlgTextSearchParser::Go(bool modal) +{ + wxString qry; + pgSet *set; + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes='2281 23'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbStart->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes='2281 2281 2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbGetToken->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2278 AND proargtypes='2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbEnd->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname, prorettype\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2281 AND proargtypes='2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbLextypes->Append(procname); + set->MoveNext(); + } + delete set; + } + + cbHeadline->Append(wxT("")); + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE proargtypes='2281 2281 3615'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbHeadline->Append(procname); + set->MoveNext(); + } + delete set; + } + + if (parser) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbStart->SetValue(parser->GetStart()); + cbStart->Disable(); + cbGetToken->SetValue(parser->GetGettoken()); + cbGetToken->Disable(); + cbEnd->SetValue(parser->GetEnd()); + cbEnd->Disable(); + cbLextypes->SetValue(parser->GetLextypes()); + cbLextypes->Disable(); + cbHeadline->SetValue(parser->GetHeadline()); + cbHeadline->Disable(); + } + else + { + // create mode + } + + cbOwner->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchParser::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchParserFactory.CreateObjects(collection, 0, + wxT("\n AND prs.prsname=") + qtDbString(GetName()) + + wxT("\n AND prs.prsnamespace=") + schema->GetOidStr()); + + return obj; +} + + +void dlgTextSearchParser::CheckChange() +{ + if (parser) + { + EnableOK(txtName->GetValue() != parser->GetName() + || cbSchema->GetValue() != parser->GetSchema()->GetName() + || txtComment->GetValue() != parser->GetComment()); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbStart->GetValue().Length() > 0 , _("Please select a start function.")); + CheckValid(enable, cbGetToken->GetValue().Length() > 0 , _("Please select a gettoken function.")); + CheckValid(enable, cbEnd->GetValue().Length() > 0 , _("Please select an end function.")); + CheckValid(enable, cbLextypes->GetValue().Length() > 0 , _("Please select a lextypes function.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchParser::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgTextSearchParser::GetSql() +{ + wxString sql; + wxString objname; + + if (parser) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH PARSER ") + parser->GetQuotedFullIdentifier()); + AppendSchemaChange(sql, wxT("TEXT SEARCH PARSER ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH PARSER ") + + objname + + wxT(" (") + + wxT("\n START = ") + cbStart->GetValue() + + wxT(",\n GETTOKEN = ") + cbGetToken->GetValue() + + wxT(",\n END = ") + cbEnd->GetValue() + + wxT(",\n LEXTYPES = ") + cbLextypes->GetValue(); + + AppendIfFilled(sql, wxT(",\n HEADLINE="), cbHeadline->GetValue()); + + sql += wxT("\n);\n"); + + } + AppendComment(sql, wxT("TEXT SEARCH PARSER ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), parser); + + return sql; +} diff --git a/dlg/dlgTextSearchTemplate.cpp b/dlg/dlgTextSearchTemplate.cpp new file mode 100644 index 0000000..3c5f6c7 --- /dev/null +++ b/dlg/dlgTextSearchTemplate.cpp @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchTemplate.cpp - PostgreSQL Text Search Template Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTextSearchTemplate.h" +#include "schema/pgSchema.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbInit CTRL_COMBOBOX2("cbInit") +#define cbLexize CTRL_COMBOBOX2("cbLexize") + + +BEGIN_EVENT_TABLE(dlgTextSearchTemplate, dlgTypeProperty) + EVT_TEXT(XRCID("cbInit"), dlgTextSearchTemplate::OnChange) + EVT_COMBOBOX(XRCID("cbInit"), dlgTextSearchTemplate::OnChange) + EVT_TEXT(XRCID("cbLexize"), dlgTextSearchTemplate::OnChange) + EVT_COMBOBOX(XRCID("cbLexize"), dlgTextSearchTemplate::OnChange) +END_EVENT_TABLE(); + + + +dlgProperty *pgTextSearchTemplateFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTextSearchTemplate(this, frame, (pgTextSearchTemplate *)node, (pgSchema *)parent); +} + +dlgTextSearchTemplate::dlgTextSearchTemplate(pgaFactory *f, frmMain *frame, pgTextSearchTemplate *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgTextSearchTemplate")) +{ + schema = sch; + tmpl = node; +} + + +pgObject *dlgTextSearchTemplate::GetObject() +{ + return tmpl; +} + + +int dlgTextSearchTemplate::Go(bool modal) +{ + wxString qry; + pgSet *set; + + cbInit->Append(wxT("")); + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2281 and proargtypes='2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbInit->Append(procname); + set->MoveNext(); + } + delete set; + } + + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=2281 and proargtypes='2281 2281 2281 2281'\n") + wxT(" ORDER BY proname\n"); + + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbLexize->Append(procname); + set->MoveNext(); + } + delete set; + } + + if (tmpl) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(9, 1)); + cbInit->SetValue(tmpl->GetInit()); + cbInit->Disable(); + cbLexize->SetValue(tmpl->GetLexize()); + cbLexize->Disable(); + } + else + { + // create mode + } + + cbOwner->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgTextSearchTemplate::CreateObject(pgCollection *collection) +{ + pgObject *obj = textSearchTemplateFactory.CreateObjects(collection, 0, + wxT("\n AND tmpl.tmplname=") + qtDbString(GetName()) + + wxT("\n AND tmpl.tmplnamespace=") + schema->GetOidStr()); + + return obj; +} + + +void dlgTextSearchTemplate::CheckChange() +{ + if (tmpl) + { + EnableOK(txtName->GetValue() != tmpl->GetName() + || cbSchema->GetValue() != tmpl->GetSchema()->GetName() + || txtComment->GetValue() != tmpl->GetComment()); + } + else + { + wxString name = GetName(); + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, cbLexize->GetGuessedSelection() > 0 , _("Please select a lexize function.")); + + EnableOK(enable); + } +} + + +void dlgTextSearchTemplate::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +wxString dlgTextSearchTemplate::GetSql() +{ + wxString sql; + wxString objname; + + if (tmpl) + { + // edit mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TEXT SEARCH TEMPLATE ") + tmpl->GetQuotedFullIdentifier()); + AppendSchemaChange(sql, wxT("TEXT SEARCH TEMPLATE ") + objname); + } + else + { + // create mode + objname = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + sql = wxT("CREATE TEXT SEARCH TEMPLATE ") + + objname + + wxT(" ("); + + AppendIfFilled(sql, wxT("\n INIT="), cbInit->GetValue()); + if (cbInit->GetValue().Length() > 0) + sql += wxT(","); + AppendIfFilled(sql, wxT("\n LEXIZE="), cbLexize->GetValue()); + + sql += wxT("\n);\n"); + + } + + AppendComment(sql, wxT("TEXT SEARCH TEMPLATE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), tmpl); + + return sql; +} diff --git a/dlg/dlgTrigger.cpp b/dlg/dlgTrigger.cpp new file mode 100644 index 0000000..c6dbc74 --- /dev/null +++ b/dlg/dlgTrigger.cpp @@ -0,0 +1,551 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTrigger.cpp - PostgreSQL Trigger Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgTrigger.h" +#include "schema/pgTrigger.h" +#include "schema/pgTable.h" +#include "schema/pgSchema.h" + + +// pointer to controls +#define chkRow CTRL_CHECKBOX("chkRow") +#define chkConstraint CTRL_CHECKBOX("chkConstraint") +#define chkDeferrable CTRL_CHECKBOX("chkDeferrable") +#define chkDeferred CTRL_CHECKBOX("chkDeferred") +#define cbFunction CTRL_COMBOBOX2("cbFunction") +#define txtArguments CTRL_TEXT("txtArguments") +#define rdbFires CTRL_RADIOBOX("rdbFires") +#define chkInsert CTRL_CHECKBOX("chkInsert") +#define chkUpdate CTRL_CHECKBOX("chkUpdate") +#define chkDelete CTRL_CHECKBOX("chkDelete") +#define chkTruncate CTRL_CHECKBOX("chkTruncate") +#define txtWhen CTRL_TEXT("txtWhen") +#define txtBody CTRL_SQLBOX("txtBody") +#define btnAddCol CTRL_BUTTON("btnAddCol") +#define btnRemoveCol CTRL_BUTTON("btnRemoveCol") +#define lstColumns CTRL_LISTVIEW("lstColumns") + + +BEGIN_EVENT_TABLE(dlgTrigger, dlgCollistProperty) + EVT_RADIOBOX(XRCID("rdbFires"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkConstraint"), dlgTrigger::OnChangeConstraint) + EVT_CHECKBOX(XRCID("chkDeferrable"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkRow"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkInsert"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkUpdate"), dlgTrigger::OnChange) + EVT_CHECKBOX(XRCID("chkDelete"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkTruncate"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbFunction"), dlgTrigger::OnChangeFunc) + EVT_COMBOBOX(XRCID("cbFunction"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtArguments"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtWhen"), dlgProperty::OnChange) + EVT_STC_MODIFIED(XRCID("txtBody"), dlgProperty::OnChangeStc) + EVT_LIST_ITEM_SELECTED(XRCID("lstColumns"), dlgTrigger::OnSelectListCol) + EVT_COMBOBOX(XRCID("cbColumns"), dlgTrigger::OnSelectComboCol) + EVT_BUTTON(XRCID("btnAddCol"), dlgTrigger::OnAddCol) + EVT_BUTTON(XRCID("btnRemoveCol"), dlgTrigger::OnRemoveCol) +END_EVENT_TABLE(); + + +dlgProperty *pgTriggerFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgTrigger(this, frame, (pgTrigger *)node, (pgTable *)parent); +} + + +dlgTrigger::dlgTrigger(pgaFactory *f, frmMain *frame, pgTrigger *node, pgTable *parentNode) + : dlgCollistProperty(f, frame, wxT("dlgTrigger"), parentNode) +{ + trigger = node; + table = parentNode; + wxASSERT(!table || table->GetMetaType() == PGM_TABLE || table->GetMetaType() == PGM_VIEW + || table->GetMetaType() == GP_PARTITION); + + bool bVal; + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + if (!bVal) + { + txtBody->SetMarginType(1, wxSTC_MARGIN_NUMBER); + txtBody->SetMarginWidth(1, ConvertDialogToPixels(wxPoint(16, 0)).x); + } + + lstColumns->AddColumn(_("Column name")); +} + + +pgObject *dlgTrigger::GetObject() +{ + return trigger; +} + + +wxString dlgTrigger::GetColumns() +{ + wxString sql; + + int pos; + // iterate cols + for (pos = 0 ; pos < lstColumns->GetItemCount() ; pos++) + { + if (pos) + sql += wxT(", "); + + sql += qtIdent(lstColumns->GetItemText(pos)); + } + return sql; +} + + +int dlgTrigger::Go(bool modal) +{ + if (trigger) + { + // edit mode + chkRow->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_ROW) != 0); + chkInsert->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_INSERT) != 0); + chkUpdate->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE) != 0); + chkDelete->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_DELETE) != 0); + chkTruncate->SetValue((trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE) != 0); + if (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE) + rdbFires->SetSelection(0); + else if (trigger->GetTriggerType() & TRIGGER_TYPE_INSTEAD) + rdbFires->SetSelection(2); + else + rdbFires->SetSelection(1); + txtArguments->SetValue(trigger->GetArguments()); + txtWhen->SetValue(trigger->GetWhen()); + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + + if (trigger->GetLanguage() == wxT("edbspl")) + { + cbFunction->Append(wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))); + txtBody->SetText(trigger->GetSource()); + } + else + { + cbFunction->Append(trigger->GetFunction()); + txtBody->Disable(); + } + + cbFunction->SetSelection(0); + txtArguments->Disable(); + cbFunction->Disable(); + + if (!connection->EdbMinimumVersion(8, 0)) + { + chkRow->Disable(); + rdbFires->Disable(); + chkInsert->Disable(); + chkUpdate->Disable(); + chkDelete->Disable(); + chkTruncate->Disable(); + } + else if (!connection->BackendMinimumVersion(8, 4)) + chkTruncate->Disable(); + else if (!connection->BackendMinimumVersion(8, 5)) + txtWhen->Disable(); + + wxArrayString colsArr = trigger->GetColumnList(); + for (int colIdx = 0, colsCount = colsArr.Count(); colIdx < colsCount; colIdx++) + { + lstColumns->InsertItem(colIdx, colsArr.Item(colIdx)); + } + + if (connection->BackendMinimumVersion(8, 2)) + { + chkConstraint->SetValue(trigger->GetIsConstraint()); + chkDeferrable->SetValue(trigger->GetDeferrable()); + chkDeferred->SetValue(trigger->GetDeferred()); + } + chkConstraint->Enable(false); + chkDeferrable->Enable(false); + chkDeferred->Enable(false); + } + else + { + // create mode + if (connection->EdbMinimumVersion(8, 0)) + cbFunction->Append(wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))); + + wxString sysRestr; + if (!settings->GetShowSystemObjects()) + sysRestr = wxT(" AND ") + connection->SystemNamespaceRestriction(wxT("nspname")); + + pgSet *set = connection->ExecuteSet( + wxT("SELECT quote_ident(nspname) || '.' || quote_ident(proname)\n") + wxT(" FROM pg_proc p, pg_namespace n, pg_language l\n") + wxT(" WHERE p.pronamespace = n.oid AND p.prolang = l.oid AND l.lanname != 'edbspl' AND prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + sysRestr + + wxT(" ORDER BY nspname ASC, proname ASC ")); + if (set) + { + while (!set->Eof()) + { + cbFunction->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + if (!connection->BackendMinimumVersion(7, 4)) + { + chkRow->SetValue(true); + chkRow->Disable(); + } + + txtBody->Disable(); + + if (!connection->BackendMinimumVersion(8, 4)) + chkTruncate->Disable(); + + if (!connection->BackendMinimumVersion(9, 1) || table->GetMetaType() != PGM_VIEW) + rdbFires->Enable(2, false); + + chkConstraint->Enable(connection->BackendMinimumVersion(8, 2)); + chkDeferrable->Disable(); + chkDeferred->Disable(); + } + + cbColumns->Disable(); + btnAddCol->Disable(); + btnRemoveCol->Disable(); + + // Reset the radio box rbxEvent item values with the keywords to resolve the locale issues. + rdbFires->SetString(0, wxT("BEFORE")); + rdbFires->SetString(1, wxT("AFTER")); + rdbFires->SetString(2, wxT("INSTEAD OF")); + + chkTruncate->SetLabel(wxT("TRUNCATE")); + chkDelete->SetLabel(wxT("DELETE")); + chkInsert->SetLabel(wxT("INSERT")); + chkUpdate->SetLabel(wxT("UPDATE")); + + return dlgCollistProperty::Go(modal); +} + + +void dlgTrigger::OnAddCol(wxCommandEvent &ev) +{ + wxString colName = cbColumns->GetValue(); + + if (!colName.IsEmpty()) + { + lstColumns->InsertItem(lstColumns->GetItemCount(), colName); + + cbColumns->Delete(cbColumns->GetCurrentSelection()); + if (cbColumns->GetCount()) + cbColumns->SetSelection(0); + + CheckChange(); + if (!cbColumns->GetCount()) + btnAddCol->Disable(); + } +} + + +void dlgTrigger::OnRemoveCol(wxCommandEvent &ev) +{ + long pos = lstColumns->GetSelection(); + if (pos >= 0) + { + wxString colName = lstColumns->GetItemText(pos); + + lstColumns->DeleteItem(pos); + cbColumns->Append(colName); + + CheckChange(); + btnRemoveCol->Disable(); + } +} + +wxString dlgTrigger::GetSql() +{ + wxString sql; + wxString name = GetName(); + + if (trigger) + { + if (name != trigger->GetName()) + sql = wxT("ALTER TRIGGER ") + trigger->GetQuotedIdentifier() + wxT(" ON ") + table->GetQuotedFullIdentifier() + + wxT("\n RENAME TO ") + qtIdent(name) + wxT(";\n\n"); + } + + if (!trigger || + (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL")) + && ( + txtBody->GetText() != trigger->GetSource() || + chkRow->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_ROW) || + chkInsert->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_INSERT ? true : false) || + chkUpdate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE ? true : false) || + chkDelete->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_DELETE ? true : false) || + chkTruncate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE ? true : false) || + rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : TRIGGER_TYPE_INSTEAD ? 2 : 1) + ) + ) + ) + { + if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + sql += wxT("CREATE OR REPLACE TRIGGER "); + else if (chkConstraint->GetValue()) + sql += wxT("CREATE CONSTRAINT TRIGGER "); + else + sql += wxT("CREATE TRIGGER "); + sql += qtIdent(name); + + if (rdbFires->GetSelection() == 1) + sql += wxT(" AFTER"); + else if (rdbFires->GetSelection() == 2) + sql += wxT(" INSTEAD OF"); + else + sql += wxT(" BEFORE"); + int actionCount = 0; + if (chkInsert->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" INSERT"); + } + if (chkUpdate->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" UPDATE"); + if (lstColumns->GetItemCount() > 0) + sql += wxT(" OF ") + GetColumns(); + } + if (chkDelete->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" DELETE"); + } + if (chkTruncate->GetValue()) + { + if (actionCount++) + sql += wxT(" OR"); + sql += wxT(" TRUNCATE"); + } + sql += wxT("\n ON ") + table->GetQuotedFullIdentifier(); + if (chkDeferrable->GetValue()) + { + sql += wxT(" DEFERRABLE"); + if (chkDeferred->GetValue()) + sql += wxT(" INITIALLY DEFERRED"); + } + sql += wxT(" FOR EACH "); + if (chkRow->GetValue()) + sql += wxT("ROW"); + else + sql += wxT("STATEMENT"); + + if (connection->BackendMinimumVersion(8, 5) && !txtWhen->GetValue().IsEmpty()) + sql += wxT("\n WHEN (") + txtWhen->GetValue() + wxT(")"); + + if (cbFunction->GetValue() != wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + { + sql += wxT("\n EXECUTE PROCEDURE ") + cbFunction->GetValue() + + wxT("(") + txtArguments->GetValue() + + wxT(");\n"); + } + else + { + sql += wxT("\n") + txtBody->GetText(); + if (!sql.Trim().EndsWith(wxT(";"))) + sql = sql.Trim() + wxT(";"); + sql += wxT("\n"); + } + } + AppendComment(sql, wxT("TRIGGER ") + qtIdent(GetName()) + + wxT(" ON ") + table->GetQuotedFullIdentifier(), trigger); + + return sql; +} + + +pgObject *dlgTrigger::CreateObject(pgCollection *collection) +{ + pgObject *obj = triggerFactory.CreateObjects(collection, 0, + wxT("\n AND tgname=") + qtDbString(GetName()) + + wxT("\n AND tgrelid=") + table->GetOidStr() + + wxT("\n AND relnamespace=") + table->GetSchema()->GetOidStr()); + return obj; +} + + +void dlgTrigger::OnChange(wxCommandEvent &ev) +{ + if (chkUpdate->GetValue()) + { + cbColumns->Enable(); + } + else + { + if (lstColumns->GetItemCount() > 0) + { + if (wxMessageBox(_("Removing the UPDATE event will cause the column list to be cleared. Do you wish to continue?"), _("Remove UPDATE event?"), wxYES_NO) != wxYES) + { + chkUpdate->SetValue(true); + return; + } + + // Move all the columns back to the combo + for (int pos = lstColumns->GetItemCount(); pos > 0; pos--) + { + wxString colName = lstColumns->GetItemText(pos - 1); + + lstColumns->DeleteItem(pos - 1); + cbColumns->Append(colName); + } + } + + cbColumns->Disable(); + btnAddCol->Disable(); + btnRemoveCol->Disable(); + } + + CheckChange(); +} + + +void dlgTrigger::OnChangeFunc(wxCommandEvent &ev) +{ + cbFunction->GuessSelection(ev); + + if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + { + txtArguments->Disable(); + txtBody->Enable(); + } + else + { + txtArguments->Enable(); + txtBody->Disable(); + } + + CheckChange(); +} + + +void dlgTrigger::OnChangeConstraint(wxCommandEvent &ev) +{ + if (chkConstraint->GetValue()) + { + rdbFires->SetSelection(1); + rdbFires->Disable(); + chkRow->SetValue(true); + chkRow->Disable(); + chkDeferrable->Enable(); + chkDeferred->Enable(); + } + else + { + rdbFires->Enable(); + chkRow->Enable(); + chkDeferrable->Disable(); + chkDeferred->Disable(); + } + + CheckChange(); +} + + +void dlgTrigger::CheckChange() +{ + bool enable = true; + + wxString function = cbFunction->GetValue(); + wxString name = GetName(); + + // We can only have per-statement TRUNCATE triggers + if (trigger || connection->BackendMinimumVersion(8, 4)) + { + if (chkRow->GetValue()) + { + chkTruncate->Disable(); + chkTruncate->SetValue(false); + } + else if (connection->EdbMinimumVersion(8, 0)) + chkTruncate->Enable(); + } + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, !function.IsEmpty(), _("Please specify trigger function.")); + + CheckValid(enable, chkInsert->GetValue() || chkUpdate->GetValue() || chkDelete->GetValue() || chkTruncate->GetValue(), + _("Please specify at least one action.")); + + if (cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) + CheckValid(enable, !txtBody->GetText().IsEmpty(), _("Please specify trigger body.")); + + if (trigger) + { + EnableOK(enable && + (txtComment->GetValue() != trigger->GetComment() || + txtName->GetValue() != trigger->GetName() || + (txtBody->GetText() != trigger->GetSource() && cbFunction->GetValue() == wxString::Format(wxT("<%s>"), _("Inline EDB-SPL"))) || + txtWhen->GetValue() != trigger->GetWhen() || + chkRow->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_ROW ? true : false) || + chkInsert->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_INSERT ? true : false) || + chkUpdate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_UPDATE ? true : false) || + chkDelete->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_DELETE ? true : false) || + chkTruncate->GetValue() != (trigger->GetTriggerType() & TRIGGER_TYPE_TRUNCATE ? true : false) || + rdbFires->GetSelection() != (trigger->GetTriggerType() & TRIGGER_TYPE_BEFORE ? 0 : (trigger->GetTriggerType() & TRIGGER_TYPE_INSTEAD ? 2 : 1)))); + } + else + { + EnableOK(enable); + } +} + +bool dlgTrigger::IsUpToDate() +{ + if (trigger && !trigger->IsUpToDate()) + return false; + else + return true; +} + +void dlgTrigger::OnSelectListCol(wxListEvent &ev) +{ + OnSelectCol(); +} + +void dlgTrigger::OnSelectComboCol(wxCommandEvent &ev) +{ + OnSelectCol(); +} + +void dlgTrigger::OnSelectCol() +{ + // Can't change the columns on an existing index. + if (trigger) + return; + + if (lstColumns->GetSelection() != wxNOT_FOUND) + btnRemoveCol->Enable(true); + else + btnRemoveCol->Enable(false); + + if (cbColumns->GetSelection() != wxNOT_FOUND && !cbColumns->GetValue().IsEmpty()) + btnAddCol->Enable(true); + else + btnAddCol->Enable(false); +} + + diff --git a/dlg/dlgType.cpp b/dlg/dlgType.cpp new file mode 100644 index 0000000..e9f72f8 --- /dev/null +++ b/dlg/dlgType.cpp @@ -0,0 +1,1432 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgType.cpp - PostgreSQL TYPE Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + + +// App headers +#include "utils/misc.h" +#include "dlg/dlgType.h" +#include "schema/pgSchema.h" +#include "schema/pgType.h" +#include "schema/pgDatatype.h" +#include "ctl/ctlSeclabelPanel.h" +#include "frm/frmMain.h" +#include "schema/pgUser.h" +#include "schema/pgGroup.h" + + +// pointer to controls +#define rdbType CTRL_RADIOBOX("rdbType") + +#define cbInput CTRL_COMBOBOX("cbInput") +#define cbOutput CTRL_COMBOBOX("cbOutput") +#define cbReceive CTRL_COMBOBOX("cbReceive") +#define cbSend CTRL_COMBOBOX("cbSend") +#define cbTypmodin CTRL_COMBOBOX("cbTypmodin") +#define cbTypmodout CTRL_COMBOBOX("cbTypmodout") +#define cbAnalyze CTRL_COMBOBOX("cbAnalyze") +#define cbCategory CTRL_COMBOBOX("cbCategory") +#define chkPrefered CTRL_CHECKBOX("chkPrefered") +#define chkVariable CTRL_CHECKBOX("chkVariable") +#define txtIntLength CTRL_TEXT("txtIntLength") +#define txtDefault CTRL_TEXT("txtDefault") +#define cbElement CTRL_COMBOBOX2("cbElement") +#define txtDelimiter CTRL_TEXT("txtDelimiter") +#define chkByValue CTRL_CHECKBOX("chkByValue") +#define cbAlignment CTRL_COMBOBOX("cbAlignment") +#define cbStorage CTRL_COMBOBOX("cbStorage") +#define lstMembers CTRL_LISTVIEW("lstMembers") +#define txtMembername CTRL_TEXT("txtMembername") +#define lstLabels CTRL_LISTVIEW("lstLabels") +#define txtLabel CTRL_TEXT("txtLabel") +#define btnAddMember CTRL_BUTTON("btnAddMember") +#define btnChangeMember CTRL_BUTTON("btnChangeMember") +#define btnRemoveMember CTRL_BUTTON("btnRemoveMember") +#define btnAddAfterLabel CTRL_BUTTON("btnAddAfterLabel") +#define btnAddBeforeLabel CTRL_BUTTON("btnAddBeforeLabel") +#define btnRemoveLabel CTRL_BUTTON("btnRemoveLabel") +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define pnlDefinitionExtern CTRL_PANEL("pnlDefinitionExtern") +#define pnlDefinitionComposite CTRL_PANEL("pnlDefinitionComposite") +#define pnlDefinitionEnum CTRL_PANEL("pnlDefinitionEnum") +#define pnlDefinitionRange CTRL_PANEL("pnlDefinitionRange") +#define chkCollatable CTRL_CHECKBOX("chkCollatable") +#define cbCollation CTRL_COMBOBOX("cbCollation") +#define cbSubtype CTRL_COMBOBOX("cbSubtype") +#define cbSubtypeOpclass CTRL_COMBOBOX("cbSubtypeOpclass") +#define cbRngCollation CTRL_COMBOBOX("cbRngCollation") +#define cbCanonical CTRL_COMBOBOX("cbCanonical") +#define cbSubtypeDiff CTRL_COMBOBOX("cbSubtypeDiff") + + +BEGIN_EVENT_TABLE(dlgType, dlgTypeProperty) + EVT_RADIOBOX(XRCID("rdbType"), dlgType::OnTypeChange) + + EVT_TEXT(XRCID("cbInput"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbInput"), dlgProperty::OnChange) + EVT_TEXT(XRCID("cbOutput"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbOutput"), dlgProperty::OnChange) + EVT_TEXT(XRCID("txtIntLength"), dlgProperty::OnChange) + EVT_CHECKBOX(XRCID("chkVariable"), dlgProperty::OnChange) + + EVT_BUTTON(XRCID("btnAddMember"), dlgType::OnMemberAdd) + EVT_BUTTON(XRCID("btnChangeMember"), dlgType::OnMemberChange) + EVT_BUTTON(XRCID("btnRemoveMember"), dlgType::OnMemberRemove) + EVT_BUTTON(XRCID("btnAddBeforeLabel"), dlgType::OnLabelAddBefore) + EVT_BUTTON(XRCID("btnAddAfterLabel"), dlgType::OnLabelAddAfter) + EVT_BUTTON(XRCID("btnRemoveLabel"), dlgType::OnLabelRemove) + EVT_LIST_ITEM_SELECTED(XRCID("lstMembers"), dlgType::OnMemberSelChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstLabels"), dlgType::OnLabelSelChange) + EVT_TEXT(XRCID("cbDatatype"), dlgType::OnSelChangeTyp) + EVT_COMBOBOX(XRCID("cbDatatype"), dlgType::OnSelChangeTyp) + EVT_TEXT(XRCID("txtMembername"), dlgType::OnChangeMember) + EVT_TEXT(XRCID("txtLength"), dlgType::OnSelChangeTypOrLen) + EVT_TEXT(XRCID("txtPrecision"), dlgType::OnSelChangeTypOrLen) + EVT_BUTTON(CTL_ADDPRIV, dlgType::OnAddPriv) + EVT_BUTTON(CTL_DELPRIV, dlgType::OnDelPriv) + EVT_TEXT(XRCID("cbSubtype"), dlgType::OnSubtypeChange) + EVT_COMBOBOX(XRCID("cbSubtype"), dlgType::OnSubtypeChange) + EVT_TEXT(XRCID("txtName"), dlgType::OnNameChange) +#ifdef __WXMAC__ + EVT_SIZE( dlgType::OnChangeSize) +#endif +END_EVENT_TABLE(); + + +dlgProperty *pgTypeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgType(this, frame, (pgType *)node, (pgSchema *)parent); +} + + +dlgType::dlgType(pgaFactory *f, frmMain *frame, pgType *node, pgSchema *sch) + : dlgTypeProperty(f, frame, wxT("dlgType")) +{ + type = node; + schema = sch; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); + + lstMembers->CreateColumns(0, _("Member"), _("Data type"), _("Collation"), -1); + lstLabels->InsertColumn(0, _("Label"), wxLIST_FORMAT_LEFT, GetClientSize().GetWidth()); + + cbStorage->Append(wxT("PLAIN")); + cbStorage->Append(wxT("MAIN")); + cbStorage->Append(wxT("EXTERNAL")); + cbStorage->Append(wxT("EXTENDED")); + + queriesToBeSplitted = false; + + /* Type Privileges */ + securityChanged = false; + if (node) + connection = node->GetConnection(); + securityPage = new ctlSecurityPanel(nbNotebook, wxT("USAGE"), "U", frame->GetImageList()); + if (connection && connection->BackendMinimumVersion(9, 2) && (!node || node->CanCreate())) + { + // Fetch Groups Information + pgSet *setGrp = connection->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (setGrp) + { + while (!setGrp->Eof()) + { + groups.Add(setGrp->GetVal(0)); + setGrp->MoveNext(); + } + delete setGrp; + } + + if (node) + { + wxString strAcl = node->GetAcl(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString roleName; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + roleName = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = roleName + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + roleName = strCurrAcl.BeforeLast('='); + + wxString value = strCurrAcl.Mid(roleName.Length() + 1).BeforeLast('/'); + + int icon = userFactory.GetIconId(); + + if (roleName.Left(6).IsSameAs(wxT("group "), false)) + { + icon = groupFactory.GetIconId(); + roleName = wxT("group ") + qtStrip(roleName.Mid(6)); + } + else if (roleName.IsEmpty()) + { + icon = PGICON_PUBLIC; + roleName = wxT("public"); + } + else + { + roleName = qtStrip(roleName); + for (unsigned int index = 0; index < groups.Count(); index++) + if (roleName == groups[index]) + { + roleName = wxT("group ") + roleName; + icon = groupFactory.GetIconId(); + break; + } + } + + securityPage->lbPrivileges->AppendItem(icon, roleName, value); + currentAcl.Add(roleName + wxT("=") + value); + + // Reset roleName + roleName.Empty(); + } + } + } + } + else + securityPage->Disable(); + +} + + +#ifdef __WXMAC__ +void dlgType::OnChangeSize(wxSizeEvent &ev) +{ + securityPage->lbPrivileges->SetSize(wxDefaultCoord, wxDefaultCoord, + ev.GetSize().GetWidth(), ev.GetSize().GetHeight() - 550); + if (GetAutoLayout()) + { + Layout(); + } +} +#endif + + +void dlgType::OnChangeMember(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + + btnAddMember->Enable( + ((type && connection->BackendMinimumVersion(9, 1)) || !type) + && !name.IsEmpty() + && lstMembers->FindItem(-1, name, false) == -1 + && cbDatatype->GetGuessedSelection() >= 0); + btnChangeMember->Enable( + lstMembers->FindItem(-1, name, false) == lstMembers->GetFirstSelected() + || lstMembers->FindItem(-1, name, false) == -1); +} + +void dlgType::showDefinition(int panel) +{ + pnlDefinitionExtern->Show(false); + pnlDefinitionComposite->Show(false); + pnlDefinitionEnum->Show(false); + pnlDefinitionRange->Show(false); + + switch (panel) + { + case 0: + pnlDefinitionComposite->Show(true); + break; + case 1: + pnlDefinitionEnum->Show(true); + break; + case 2: + pnlDefinitionExtern->Show(true); + break; + case 3: + pnlDefinitionRange->Show(true); + break; + } + + pnlDefinitionComposite->GetParent()->Layout(); + // we don't need to call GetParent()->Layout() for all four panels + // because they all share the same parent +} + + +void dlgType::OnTypeChange(wxCommandEvent &ev) +{ + showDefinition(rdbType->GetSelection()); + + CheckChange(); +} + + +pgObject *dlgType::GetObject() +{ + return type; +} + + +int dlgType::Go(bool modal) +{ + pgSet *set; + + cbRngCollation->Enable(false); + if (connection->BackendMinimumVersion(9, 2)) + { + securityPage->SetConnection(connection); + + if (securityPage->cbGroups) + { + // Fetch Groups Information + for ( unsigned int index = 0; index < groups.Count();) + securityPage->cbGroups->Append(wxT("group ") + groups[index++]); + + // Fetch Users Information + if (settings->GetShowUsersForPrivileges()) + { + securityPage->stGroup->SetLabel(_("Group/User")); + dlgProperty::AddUsers(securityPage->cbGroups); + } + } + securityPage->lbPrivileges->GetParent()->Layout(); + + // Load the range combox (the 403 opcmethod is btree) + set = connection->ExecuteSet( + wxT("SELECT DISTINCT typ.typname\n") + wxT(" FROM pg_opclass opc\n") + wxT(" JOIN pg_type typ ON opc.opcintype=typ.oid\n") + wxT(" WHERE opc.opcmethod=403\n") + wxT(" ORDER BY typname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtTypeIdent(set->GetVal(wxT("typname"))); + cbSubtype->Append(name); + set->MoveNext(); + } + delete set; + } + cbSubtype->SetSelection(0); + } + else + { + rdbType->Enable(3, false); + } + + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(type); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgType::OnChange)); + } + else + seclabelPage->Disable(); + + FillDatatype(cbDatatype, cbElement); + + if (connection->BackendMinimumVersion(9, 1)) + { + // fill collation combobox + cbCollation->Append(wxEmptyString); + cbRngCollation->Append(wxEmptyString); + set = connection->ExecuteSet( + wxT("SELECT nspname, collname\n") + wxT(" FROM pg_collation c, pg_namespace n\n") + wxT(" WHERE c.collnamespace=n.oid\n") + wxT(" ORDER BY nspname, collname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("nspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + cbCollation->Append(name); + cbRngCollation->Append(name); + set->MoveNext(); + } + delete set; + } + cbCollation->SetSelection(0); + cbRngCollation->SetSelection(0); + } + + if (type) + { + // Edit Mode + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + txtName->Enable(connection->BackendMinimumVersion(8, 4)); + rdbType->SetSelection(type->GetTypeClass()); + rdbType->Disable(); + + showDefinition(type->GetTypeClass()); + + cbInput->Append(type->GetInputFunction()); + cbInput->SetSelection(0); + cbInput->Disable(); + cbOutput->Append(type->GetOutputFunction()); + cbOutput->SetSelection(0); + cbOutput->Disable(); + cbReceive->Append(type->GetReceiveFunction()); + cbReceive->SetSelection(0); + cbReceive->Disable(); + cbSend->Append(type->GetSendFunction()); + cbSend->SetSelection(0); + cbSend->Disable(); + cbTypmodin->Append(type->GetTypmodinFunction()); + cbTypmodin->SetSelection(0); + cbTypmodin->Disable(); + cbTypmodout->Append(type->GetTypmodoutFunction()); + cbTypmodout->SetSelection(0); + cbTypmodout->Disable(); + cbAnalyze->Append(type->GetAnalyzeFunction()); + cbAnalyze->SetSelection(0); + cbAnalyze->Disable(); + cbCategory->Append(catGetText(type->GetCategory())); + cbCategory->SetSelection(0); + cbCategory->Disable(); + chkPrefered->SetValue(type->GetPrefered()); + chkPrefered->Disable(); + + chkVariable->SetValue(type->GetInternalLength() < 0); + chkVariable->Disable(); + if (type->GetInternalLength() > 0) + txtIntLength->SetValue(NumToStr(type->GetInternalLength())); + txtIntLength->Disable(); + txtDefault->SetValue(type->GetDefault()); + txtDefault->Disable(); + cbElement->Append(type->GetElement()); + cbElement->SetSelection(0); + cbElement->Disable(); + txtDelimiter->SetValue(type->GetDelimiter()); + txtDelimiter->Disable(); + chkByValue->SetValue(type->GetPassedByValue()); + chkByValue->Disable(); + cbAlignment->SetValue(type->GetAlignment()); + cbAlignment->Disable(); + cbStorage->SetValue(type->GetStorage()); + cbStorage->Disable(); + chkCollatable->SetValue(type->GetCollatable()); + chkCollatable->Disable(); + + bool changeok = connection->BackendMinimumVersion(9, 1); + txtMembername->Enable(changeok); + cbCollation->Enable(changeok); + btnAddMember->Enable(false); + btnChangeMember->Enable(false); + btnRemoveMember->Enable(false); + + txtLabel->Enable(connection->BackendMinimumVersion(9, 1)); + btnAddBeforeLabel->Enable(connection->BackendMinimumVersion(9, 1)); + btnAddAfterLabel->Enable(connection->BackendMinimumVersion(9, 1)); + btnRemoveLabel->Disable(); + + wxArrayString elements = type->GetTypesArray(); + wxString fullType, typeName, typeLength, typePrecision; + size_t pos; + size_t i; + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + lstMembers->AppendItem(0, elements.Item(i), elements.Item(i + 1), elements.Item(i + 2)); + + fullType = elements.Item(i + 1); + typeName = fullType; + typeLength = wxEmptyString; + typePrecision = wxEmptyString; + + if (fullType.Find(wxT("(")) > 0) + { + // there is at least a length + typeName = fullType.BeforeFirst('('); + if (fullType.Find(wxT(",")) > 0) + { + // there is also a precision + typeLength = fullType.AfterFirst('(').BeforeFirst(','); + typePrecision = fullType.AfterFirst(',').BeforeFirst(')'); + } + else + typeLength = fullType.AfterFirst('(').BeforeFirst(')'); + } + + for (pos = 0; pos < cbDatatype->GetCount() - 1; pos++) + { + if (cbDatatype->GetString(pos) == typeName) + { + memberTypes.Add(GetTypeInfo(pos)); + break; + } + } + memberLengths.Add(typeLength); + memberPrecisions.Add(typePrecision); + memberCollations.Add(elements.Item(i + 2)); + memberOriginalNames.Add(elements.Item(i)); + } + + cbDatatype->Enable(changeok); + txtLength->Enable(changeok); + + // Load the enum labels + elements = type->GetLabelArray(); + for (i = 0 ; i < elements.GetCount() ; i++) + lstLabels->AppendItem(0, elements.Item(i)); + + // Load the RANGE informations + cbSubtype->SetValue(type->GetSubtypeFunctionStr()); + cbSubtype->Disable(); + cbSubtypeOpclass->Append(type->GetSubtypeOpClassFunctionStr()); + cbSubtypeOpclass->SetSelection(0); + cbSubtypeOpclass->Disable(); + cbRngCollation->Append(type->GetCollationFunctionStr()); + cbRngCollation->SetSelection(0); + cbRngCollation->Disable(); + cbCanonical->Append(type->GetCanonical()); + cbCanonical->SetSelection(0); + cbCanonical->Disable(); + cbSubtypeDiff->Append(type->GetSubtypeDiff()); + cbSubtypeDiff->SetSelection(0); + cbSubtypeDiff->Disable(); + + if (!connection->BackendMinimumVersion(7, 5)) + cbOwner->Disable(); + } + else + { + // Create mode + cbOwner->Disable(); + + bool hasSendRcv = connection->BackendMinimumVersion(7, 4); + bool hasTypmod = connection->BackendMinimumVersion(8, 3); + + cbCategory->Enable(connection->BackendMinimumVersion(8, 4)); + chkPrefered->Enable(connection->BackendMinimumVersion(8, 4)); + + if (hasSendRcv) + { + cbReceive->Append(wxEmptyString); + cbSend->Append(wxEmptyString); + cbAnalyze->Append(wxEmptyString); + } + else + { + cbReceive->Disable(); + cbSend->Disable(); + cbAnalyze->Disable(); + } + + if (hasTypmod) + { + cbTypmodin->Append(wxEmptyString); + cbTypmodout->Append(wxEmptyString); + } + else + { + cbTypmodin->Disable(); + cbTypmodout->Disable(); + } + + if (!connection->BackendMinimumVersion(8, 3)) + rdbType->Enable(TYPE_ENUM, false); + + chkCollatable->Enable(connection->BackendMinimumVersion(9, 1)); + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM (\n") + wxT(" SELECT proname, nspname, max(proargtypes[0]) AS arg0, max(proargtypes[1]) AS arg1\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" GROUP BY proname, nspname\n") + wxT(" HAVING count(proname) = 1 ) AS uniquefunc\n") + wxT(" WHERE arg0 <> 0 AND arg1 = 0")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbInput->Append(pn); + cbOutput->Append(pn); + if (hasSendRcv) + { + cbReceive->Append(pn); + cbSend->Append(pn); + cbAnalyze->Append(pn); + } + if (hasTypmod) + { + cbTypmodin->Append(pn); + cbTypmodout->Append(pn); + } + set->MoveNext(); + } + delete set; + } + + if (hasTypmod) + { + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='int4')") + wxT(" AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='_cstring')") + wxT(" AND proargtypes[1] IS NULL") + wxT(" ORDER BY nspname, proname")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbTypmodin->Append(pn); + set->MoveNext(); + } + delete set; + } + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc p\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=(SELECT oid FROM pg_type WHERE typname='cstring')") + wxT(" AND proargtypes[0]=(SELECT oid FROM pg_type WHERE typname='int4')") + wxT(" AND proargtypes[1] IS NULL") + wxT(" ORDER BY nspname, proname")); + + if (set) + { + while (!set->Eof()) + { + wxString pn = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + + cbTypmodout->Append(pn); + set->MoveNext(); + } + delete set; + } + } + } + + txtLength->SetValidator(numericValidator); + + return dlgTypeProperty::Go(modal); +} + + +void dlgType::OnSelChangeTyp(wxCommandEvent &ev) +{ + txtLength->SetValue(wxEmptyString); + txtPrecision->SetValue(wxEmptyString); + cbDatatype->GuessSelection(ev); + cbCollation->SetValue(wxEmptyString); + OnSelChangeTypOrLen(ev); +} + + + +void dlgType::OnNameChange(wxCommandEvent &ev) +{ + wxString qry; + wxString shelltype; + pgSet *set; + + cbCanonical->Clear(); + if (!txtName->GetValue().IsEmpty()) + { + // Grab the shelltype + qry = wxT("SELECT oid FROM pg_type WHERE typname='") + qtIdent(txtName->GetValue()) + wxT("'"); + set = connection->ExecuteSet(qry); + if (set) + { + if (!set->Eof()) + { + shelltype = set->GetVal(wxT("oid")); + } + delete set; + } + + if (!shelltype.IsEmpty()) + { + // Load the canonical functions + qry = wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=") + shelltype + + wxT(" AND proargtypes='") + shelltype + wxT("'\n") + wxT(" ORDER BY proname\n"); + + cbCanonical->Append(wxEmptyString); + set = connection->ExecuteSet(qry); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbCanonical->Append(procname); + set->MoveNext(); + } + delete set; + } + cbCanonical->SetSelection(0); + } + } + CheckChange(); +} + + +void dlgType::OnSubtypeChange(wxCommandEvent &ev) +{ + wxString subtypeoid; + cbSubtypeOpclass->Clear(); + cbSubtypeDiff->Clear(); + + if (!cbSubtype->GetValue().IsEmpty()) + { + cbSubtypeOpclass->Append(wxEmptyString); + pgSet *set = connection->ExecuteSet( + wxT("SELECT opc.opcname, opc.opcintype\n") + wxT(" FROM pg_opclass opc\n") + wxT(" JOIN pg_type typ ON opc.opcintype=typ.oid ") + wxT(" AND typ.typname='") + cbSubtype->GetValue() + wxT("'\n") + wxT(" WHERE opc.opcmethod=403\n") + wxT(" ORDER BY opcname")); + if (set) + { + while (!set->Eof()) + { + wxString name = qtIdent(set->GetVal(wxT("opcname"))); + subtypeoid = set->GetVal(wxT("opcintype")); + cbSubtypeOpclass->Append(name); + set->MoveNext(); + } + delete set; + } + cbSubtypeOpclass->SetSelection(0); + + set = connection->ExecuteSet( + wxT("SELECT typcollation FROM pg_type WHERE typname='") + cbSubtype->GetValue() + wxT("'\n")); + if (set) + { + if (!set->Eof()) + { + cbRngCollation->Enable(set->GetLong(wxT("typcollation")) > 0); + } + delete set; + } + else + { + cbRngCollation->Enable(false); + } + + // Load the subtypediff functions (701 is double precision type) + + set = connection->ExecuteSet( + wxT("SELECT proname, nspname\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace n ON n.oid=pronamespace\n") + wxT(" WHERE prorettype=701 ") + wxT(" AND proargtypes='") + subtypeoid + wxT(" ") + subtypeoid + wxT("'\n") + wxT(" ORDER BY proname\n")); + if (set) + { + while (!set->Eof()) + { + wxString procname = database->GetSchemaPrefix(set->GetVal(wxT("nspname"))) + set->GetVal(wxT("proname")); + cbSubtypeDiff->Append(procname); + set->MoveNext(); + } + delete set; + } + } +} + + +void dlgType::OnSelChangeTypOrLen(wxCommandEvent &ev) +{ + if ((type && connection->BackendMinimumVersion(9, 1)) || !type) + { + CheckLenEnable(); + txtLength->Enable(isVarLen); + txtPrecision->Enable(isVarPrec); + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + CheckChange(); + OnChangeMember(ev); + } +} + + +void dlgType::CheckChange() +{ + bool enable = true; + + if (rdbType->GetSelection() == TYPE_COMPOSITE) + { + CheckValid(enable, lstMembers->GetItemCount() > 1, _("Please specify at least two members.")); + } + else if (rdbType->GetSelection() == TYPE_ENUM) + { + CheckValid(enable, lstLabels->GetItemCount() >= 1, _("Please specify at least one label.")); + } + else if (rdbType->GetSelection() == TYPE_EXTERNAL) + { + txtLength->Enable(!chkVariable->GetValue()); + CheckValid(enable, cbInput->GetCurrentSelection() >= 0, _("Please specify input conversion function.")); + CheckValid(enable, cbOutput->GetCurrentSelection() >= 0, _("Please specify output conversion function.")); + CheckValid(enable, chkVariable->GetValue() || StrToLong(txtLength->GetValue()) > 0, _("Please specify internal storage length.")); + } + else + { + CheckValid(enable, cbSubtype->GetCurrentSelection() >= 0, _("Please specify subtype function.")); + } + + if (type) + { + enable = enable && (GetName() != type->GetName() + || txtComment->GetValue() != type->GetComment() + || cbSchema->GetValue() != type->GetSchema()->GetName() + || cbOwner->GetValue() != type->GetOwner() + || (rdbType->GetSelection() == TYPE_COMPOSITE && GetSqlForTypes() != wxEmptyString) + || (GetSql().Length() > 0 && connection->BackendMinimumVersion(9, 1))); + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + } + else + { + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, !name.StartsWith(wxT("_")), _("Name may not start with '_'.")); + } + + EnableOK(enable || securityChanged); +} + + +void dlgType::OnMemberSelChange(wxListEvent &ev) +{ + long pos = lstMembers->GetSelection(); + if (pos >= 0) + { + txtMembername->SetValue(lstMembers->GetText(pos)); + cbDatatype->SetValue(memberTypes.Item(pos).AfterFirst(':')); + txtLength->SetValue(memberLengths.Item(pos)); + txtLength->Enable(((type && connection->BackendMinimumVersion(9, 1)) || !type) && !txtLength->GetValue().IsEmpty()); + txtPrecision->SetValue(memberPrecisions.Item(pos)); + txtPrecision->Enable(((type && connection->BackendMinimumVersion(9, 1)) || !type) && !txtPrecision->GetValue().IsEmpty()); + cbCollation->SetValue(memberCollations.Item(pos)); + cbCollation->Enable(connection->BackendMinimumVersion(9, 1)); + btnChangeMember->Enable((type && connection->BackendMinimumVersion(9, 1)) || !type); + btnRemoveMember->Enable((type && connection->BackendMinimumVersion(9, 1)) || !type); + } +} + + +void dlgType::OnMemberAdd(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString collation = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + if (cbCollation->GetValue() != wxT("") && cbCollation->IsEnabled()) + collation = cbCollation->GetValue(); + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + size_t pos = lstMembers->GetItemCount(); + lstMembers->InsertItem(pos, name, 0); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, collation); + memberTypes.Add(GetTypeInfo(cbDatatype->GetGuessedSelection())); + memberLengths.Add(length); + memberPrecisions.Add(precision); + memberCollations.Add(collation); + memberOriginalNames.Add(wxEmptyString); + } + + CheckChange(); +} + + +void dlgType::OnMemberChange(wxCommandEvent &ev) +{ + wxString name = txtMembername->GetValue().Strip(wxString::both); + wxString type = cbDatatype->GetValue(); + wxString length = wxEmptyString; + wxString precision = wxEmptyString; + wxString collation = wxEmptyString; + + if (txtLength->GetValue() != wxT("") && txtLength->IsEnabled()) + length = txtLength->GetValue(); + if (txtPrecision->GetValue() != wxT("") && txtPrecision->IsEnabled()) + precision = txtPrecision->GetValue(); + if (cbCollation->GetValue() != wxT("") && cbCollation->IsEnabled()) + collation = cbCollation->GetValue(); + + if (!length.IsEmpty()) + { + type += wxT("(") + length; + if (!precision.IsEmpty()) + type += wxT(",") + precision; + type += wxT(")"); + } + + if (!name.IsEmpty()) + { + long pos = lstMembers->GetFirstSelected(); + if (pos >= 0) + { + lstMembers->SetItem(pos, 0, name); + lstMembers->SetItem(pos, 1, type); + lstMembers->SetItem(pos, 2, collation); + memberTypes.Insert(GetTypeInfo(cbDatatype->GetGuessedSelection()), pos); + memberLengths.Insert(length, pos); + memberPrecisions.Insert(precision, pos); + memberCollations.Insert(collation, pos); + memberTypes.RemoveAt(pos + 1); + memberLengths.RemoveAt(pos + 1); + memberPrecisions.RemoveAt(pos + 1); + memberCollations.RemoveAt(pos + 1); + } + } + + CheckChange(); +} + + +void dlgType::OnMemberRemove(wxCommandEvent &ev) +{ + long pos = lstMembers->GetSelection(); + + if (pos >= 0) + { + lstMembers->DeleteItem(pos); + memberTypes.RemoveAt(pos); + memberLengths.RemoveAt(pos); + memberPrecisions.RemoveAt(pos); + memberCollations.RemoveAt(pos); + memberOriginalNames.RemoveAt(pos); + } + CheckChange(); +} + + +void dlgType::OnLabelSelChange(wxListEvent &ev) +{ + long pos = lstLabels->GetSelection(); + if (pos >= 0) + { + txtLabel->SetValue(lstLabels->GetText(pos)); + } +} + + +void dlgType::OnLabelAddBefore(wxCommandEvent &ev) +{ + wxString label = txtLabel->GetValue().Strip(wxString::both); + + if (!label.IsEmpty()) + { + long pos = lstLabels->FindItem(-1, label); + if (pos < 0) + { + if (lstLabels->GetFirstSelected() >= 0) + pos = lstLabels->GetFirstSelected(); + else + pos = 0; + lstLabels->InsertItem(pos, label, 0); + } + } + txtLabel->SetValue(wxEmptyString); + CheckChange(); +} + + +void dlgType::OnLabelAddAfter(wxCommandEvent &ev) +{ + wxString label = txtLabel->GetValue().Strip(wxString::both); + + if (!label.IsEmpty()) + { + long pos = lstLabels->FindItem(-1, label); + if (pos < 0) + { + if (lstLabels->GetFirstSelected() >= 0) + pos = lstLabels->GetFirstSelected() + 1; + else + pos = lstLabels->GetItemCount(); + lstLabels->InsertItem(pos, label, 0); + } + } + txtLabel->SetValue(wxEmptyString); + CheckChange(); +} + + +void dlgType::OnLabelRemove(wxCommandEvent &ev) +{ + long pos = lstLabels->GetSelection(); + + if (pos >= 0) + lstLabels->DeleteItem(pos); + + CheckChange(); +} + + +pgObject *dlgType::CreateObject(pgCollection *collection) +{ + pgObject *obj = 0; //pgType::ReadObjects(collection, 0, wxT("\n WHERE usename=") + qtDbString(name)); + return obj; +} + + +wxString dlgType::GetSql() +{ + wxString sql, direction, objname; + size_t existingitems_index, listitems_index, offset; + + if (type) + { + // Edit Mode + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + AppendNameChange(sql, wxT("TYPE ") + type->GetQuotedFullIdentifier()); + AppendOwnerChange(sql, wxT("TYPE ") + objname); + + sql += GetSqlForTypes(); + if (rdbType->GetSelection() == TYPE_ENUM && connection->BackendMinimumVersion(9, 1)) + { + wxArrayString elements = type->GetLabelArray(); + existingitems_index = 0; + for (listitems_index = 0 ; listitems_index < (size_t)lstLabels->GetItemCount() ; listitems_index++) + { + if (existingitems_index >= elements.GetCount() || lstLabels->GetItemText(listitems_index) != elements.Item(existingitems_index)) + { + queriesToBeSplitted = true; + if (listitems_index == 0) + { + direction = wxT("BEFORE"); + offset = 0; + } + else + { + direction = wxT("AFTER"); + offset = -1; + } + + sql += wxT("ALTER TYPE ") + objname + + wxT("\n ADD VALUE ") + connection->qtDbString(lstLabels->GetItemText(listitems_index)) + + wxT(" ") + direction + wxT(" ") + + connection->qtDbString(elements.Item(existingitems_index + offset)) + + wxT(";\n"); + } + else + existingitems_index++; + } + } + AppendSchemaChange(sql, wxT("TYPE ") + objname); + } + else + { + // Create Mode + sql = wxT("CREATE TYPE ") + schema->GetQuotedPrefix() + qtIdent(GetName()); + + if (rdbType->GetSelection() == TYPE_COMPOSITE) + { + sql += wxT(" AS\n ("); + + int i; + for (i = 0 ; i < lstMembers->GetItemCount() ; i++) + { + if (i) + sql += wxT(",\n "); + sql += qtIdent(lstMembers->GetItemText(i)) + wxT(" ") + + GetFullTypeName(i); + } + } + else if (rdbType->GetSelection() == TYPE_ENUM) + { + sql += wxT(" AS ENUM\n ("); + + int i; + for (i = 0 ; i < lstLabels->GetItemCount() ; i++) + { + if (i) + sql += wxT(",\n "); + sql += connection->qtDbString(lstLabels->GetItemText(i)); + } + } + else if (rdbType->GetSelection() == TYPE_EXTERNAL) + { + sql += wxT("\n (INPUT="); + AppendQuoted(sql, cbInput->GetValue()); + sql += wxT(", OUTPUT="); + AppendQuoted(sql, cbOutput->GetValue()); + + if (connection->BackendMinimumVersion(7, 4)) + { + if (cbReceive->GetCurrentSelection() > 0 || cbSend->GetCurrentSelection() > 0) + { + if (cbReceive->GetCurrentSelection() > 0) + { + sql += wxT(",\n RECEIVE="); + AppendQuoted(sql, cbReceive->GetValue()); + if (cbSend->GetCurrentSelection() > 0) + { + sql += wxT(", SEND="); + AppendQuoted(sql, cbSend->GetValue()); + } + } + else + { + sql += wxT(",\n SEND="); + AppendQuoted(sql, cbSend->GetValue()); + } + } + if (cbAnalyze->GetCurrentSelection() > 0) + { + sql += wxT(",\n ANALYZE="); + AppendQuoted(sql, cbAnalyze->GetValue()); + } + + } + if (connection->BackendMinimumVersion(8, 3)) + { + if (cbTypmodin->GetCurrentSelection() > 0 || cbTypmodout->GetCurrentSelection() > 0) + { + if (cbTypmodin->GetCurrentSelection() > 0) + { + sql += wxT(",\n TYPMOD_IN="); + AppendQuoted(sql, cbTypmodin->GetValue()); + if (cbTypmodout->GetCurrentSelection() > 0) + { + sql += wxT(", TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + else + { + sql += wxT(",\n TYPMOD_OUT="); + AppendQuoted(sql, cbTypmodout->GetValue()); + } + } + + } + if (connection->BackendMinimumVersion(8, 4)) + { + sql += wxT(",\n CATEGORY=") + qtDbString(cbCategory->GetValue()); + if (chkPrefered->GetValue()) + sql += wxT(",\n PREFERRED=true"); + } + sql += wxT(",\n INTERNALLENGTH="); + if (chkVariable->GetValue()) + sql += wxT("VARIABLE"); + else + sql += txtLength->GetValue(); + AppendIfFilled(sql, wxT(",\n DEFAULT="), txtDefault->GetValue()); + if (!cbElement->GetValue().IsEmpty()) + { + sql += wxT(",\n ELEMENT="); + AppendQuoted(sql, cbElement->GetValue()); + AppendIfFilled(sql, wxT(", DELIMITER="), qtDbString(txtDelimiter->GetValue().Strip(wxString::both))); + } + if (chkByValue->GetValue()) + sql += wxT(",\n PASSEDBYVALUE"); + AppendIfFilled(sql, wxT(",\n ALIGNMENT="), cbAlignment->GetValue()); + AppendIfFilled(sql, wxT(",\n STORAGE="), cbStorage->GetValue()); + if (connection->BackendMinimumVersion(9, 1) && chkCollatable->GetValue()) + sql += wxT(",\n COLLATABLE=true"); + } + else + { + sql += wxT(" AS RANGE\n (SUBTYPE="); + AppendQuoted(sql, cbSubtype->GetValue()); + if (!cbSubtypeOpclass->GetValue().IsEmpty()) + { + sql += wxT(", SUBTYPE_OPCLASS="); + AppendQuoted(sql, cbSubtypeOpclass->GetValue()); + } + if (!cbRngCollation->GetValue().IsEmpty()) + { + sql += wxT(", COLLATION=") + cbRngCollation->GetValue(); + } + if (!cbCanonical->GetValue().IsEmpty()) + { + sql += wxT(", CANONICAL="); + AppendQuoted(sql, cbCanonical->GetValue()); + } + if (!cbSubtypeDiff->GetValue().IsEmpty()) + { + sql += wxT(", SUBTYPE_DIFF="); + AppendQuoted(sql, cbSubtypeDiff->GetValue()); + } + } + + sql += wxT(");\n"); + } + AppendComment(sql, wxT("TYPE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), type); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("TYPE"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + // securityPage will exists only for PG 9.2 and later + if (connection->BackendMinimumVersion(9, 2)) + sql += securityPage->GetGrant(wxT("U"), wxT("TYPE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), ¤tAcl); + return sql; +} + +wxString dlgType::GetFullTypeName(int type) +{ + wxString typname = memberTypes.Item(type).AfterFirst(':'); + + if (!memberLengths.Item(type).IsEmpty()) + { + typname += wxT("(") + memberLengths.Item(type); + if (!memberPrecisions.Item(type).IsEmpty()) + typname += wxT(",") + memberPrecisions.Item(type); + typname += wxT(")"); + } + if (!memberCollations.Item(type).IsEmpty() && memberCollations.Item(type) != wxT("pg_catalog.\"default\"")) + typname += wxT(" COLLATE ") + memberCollations.Item(type); + + return typname; +} + +wxString dlgType::GetSqlForTypes() +{ + wxString sql = wxEmptyString; + wxString objname, old_name, old_type, old_collation, new_name, new_type, new_full_type, new_collation, original_name; + wxArrayString elements = type->GetTypesArray(); + int newindex; + unsigned int oldindex = 0; + int hold = 0; + objname = schema->GetQuotedPrefix() + qtIdent(GetName()); + + for (newindex = 0 ; newindex < lstMembers->GetItemCount() ; newindex = newindex + 1 - hold) + { + // this will decide whether we progress to the next new item, + // or whether we need to continue checking the old list first + hold = 0; + + // these are a copy of the list before any changes + if (elements.GetCount() >= (oldindex * 3) + 3) + { + old_name = elements.Item(oldindex * 3); + old_type = elements.Item(oldindex * 3 + 1); + old_collation = elements.Item(oldindex * 3 + 2); + } + else + { + // we've now used up all the old attributes + old_name = wxEmptyString; + old_type = wxEmptyString; + old_collation = wxEmptyString; + } + + // this is the original name of the type before editing + original_name = memberOriginalNames.Item(newindex); + + new_name = lstMembers->GetItemText(newindex); + new_type = memberTypes.Item(newindex).AfterFirst(':'); + new_full_type = GetFullTypeName(newindex); + new_collation = memberCollations.Item(newindex); + + if (!original_name.IsEmpty() && original_name == old_name && (new_name != old_name + || new_type != old_type || new_collation != old_collation)) + { + // if this was originally in the list and the name has changed then rename it + + if (new_name != old_name) + { + sql += wxT("ALTER TYPE ") + objname + wxT("\n RENAME ATTRIBUTE ") + + qtIdent(original_name) + wxT(" TO ") + qtIdent(new_name) + wxT(";\n"); + } + + if (new_type != old_type || new_collation != old_collation) + { + sql += wxT("ALTER TYPE ") + objname + wxT("\n ALTER ATTRIBUTE ") + + qtIdent(new_name); + + // the syntax for alter attribute requires that we always specify the type + sql += wxT(" SET DATA TYPE ") + new_type; + + if (new_collation != old_collation) + sql += wxT(" COLLATE ") + new_collation; + + sql += wxT(";\n"); + } + } + else if (!original_name.IsEmpty() && original_name != old_name) + { + // the old attribute isn't in the new list so drop it + + // don't move through new list yet + hold = 1; + + sql += wxT("ALTER TYPE ") + objname + wxT("\n DROP ATTRIBUTE ") + + qtIdent(old_name) + wxT(";\n"); + } + else if (original_name.IsEmpty()) + { + if (!old_name.IsEmpty()) + { + sql += wxT("ALTER TYPE ") + objname + wxT("\n DROP ATTRIBUTE ") + + qtIdent(old_name) + wxT(";\n"); + } + + sql += wxT("ALTER TYPE ") + objname + wxT("\n ADD ATTRIBUTE ") + + qtIdent(new_name) + wxT(" ") + new_full_type + wxT(";\n"); + } + else + { + // do nothing + } + + oldindex++; + + if (newindex + 1 - hold == lstMembers->GetItemCount() && elements.GetCount() >= (oldindex * 3) + 3) + { + // remove remaining old attributes + for (; elements.GetCount() >= (oldindex * 3) + 3; oldindex++) + { + old_name = elements.Item(oldindex * 3); + old_type = elements.Item(oldindex * 3 + 1); + old_collation = elements.Item(oldindex * 3 + 2); + + sql += wxT("ALTER TYPE ") + objname + wxT("\n DROP ATTRIBUTE ") + + qtIdent(old_name) + wxT(";\n"); + } + break; + } + } + + return sql; +} + + +void dlgType::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + + +void dlgType::OnAddPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + + +void dlgType::OnDelPriv(wxCommandEvent &ev) +{ + securityChanged = true; + CheckChange(); +} + + +wxString dlgType::catGetText(wxString c) +{ + if (c == wxT("A")) + return wxT("Array types"); + if (c == wxT("B")) + return wxT("Boolean types"); + if (c == wxT("C")) + return wxT("Composite types"); + if (c == wxT("D")) + return wxT("Date/time types"); + if (c == wxT("E")) + return wxT("Enum types"); + if (c == wxT("G")) + return wxT("Geometric types"); + if (c == wxT("I")) + return wxT("Network address types"); + if (c == wxT("N")) + return wxT("Numeric types"); + if (c == wxT("P")) + return wxT("Pseudo-types"); + if (c == wxT("S")) + return wxT("String types"); + if (c == wxT("T")) + return wxT("Timespan types"); + if (c == wxT("U")) + return wxT("User-defined types"); + if (c == wxT("V")) + return wxT("Bit-string types"); + if (c == wxT("X")) + return wxT("unknown type"); + return wxEmptyString; +} + + +wxString dlgType::catGetChar(wxString t) +{ + if (t == wxT("Array types")) + return wxT("A"); + if (t == wxT("Boolean types")) + return wxT("B"); + if (t == wxT("Composite types")) + return wxT("C"); + if (t == wxT("Date/time types")) + return wxT("D"); + if (t == wxT("Enum types")) + return wxT("E"); + if (t == wxT("Geometric types")) + return wxT("G"); + if (t == wxT("Network address types")) + return wxT("I"); + if (t == wxT("Numeric types")) + return wxT("N"); + if (t == wxT("Pseudo-types")) + return wxT("P"); + if (t == wxT("String types")) + return wxT("S"); + if (t == wxT("Timespan types")) + return wxT("T"); + if (t == wxT("User-defined types")) + return wxT("U"); + if (t == wxT("Bit-string types")) + return wxT("V"); + if (t == wxT("unknown type")) + return wxT("X"); + return wxEmptyString; +} diff --git a/dlg/dlgUser.cpp b/dlg/dlgUser.cpp new file mode 100644 index 0000000..d70922d --- /dev/null +++ b/dlg/dlgUser.cpp @@ -0,0 +1,571 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUser.cpp - PostgreSQL User Property +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "utils/misc.h" +#include "dlg/dlgUser.h" +#include "schema/pgUser.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define txtPasswd CTRL_TEXT("txtPasswd") +#define txtRePasswd CTRL_TEXT("txtRePasswd") +#define datValidUntil CTRL_CALENDAR("datValidUntil") +#define timValidUntil CTRL_TIME("timValidUntil") +#define chkCreateDB CTRL_CHECKBOX("chkCreateDB") +#define chkCreateUser CTRL_CHECKBOX("chkCreateUser") + +#define lbGroupsNotIn CTRL_LISTBOX("lbGroupsNotIn") +#define lbGroupsIn CTRL_LISTBOX("lbGroupsIn") +#define btnAddGroup CTRL_BUTTON("btnAddGroup") +#define btnDelGroup CTRL_BUTTON("btnDelGroup") + +#define lstVariables CTRL_LISTVIEW("lstVariables") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") +#define cbVarname CTRL_COMBOBOX2("cbVarname") +#define txtValue CTRL_TEXT("txtValue") +#define chkValue CTRL_CHECKBOX("chkValue") + + + +dlgProperty *pgUserFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgUser(this, frame, (pgUser *)node); +} + + +BEGIN_EVENT_TABLE(dlgUser, dlgProperty) + EVT_CALENDAR_SEL_CHANGED(XRCID("datValidUntil"), dlgUser::OnChangeCal) + EVT_DATE_CHANGED(XRCID("datValidUntil"), dlgUser::OnChangeDate) + EVT_SPIN(XRCID("timValidUntil"), dlgUser::OnChangeSpin) + + EVT_LISTBOX_DCLICK(XRCID("lbGroupsNotIn"), dlgUser::OnGroupAdd) + EVT_LISTBOX_DCLICK(XRCID("lbGroupsIn"), dlgUser::OnGroupRemove) + EVT_TEXT(XRCID("txtPasswd"), dlgUser::OnChangePasswd) + EVT_TEXT(XRCID("txtRePasswd"), dlgUser::OnChangePasswd) + EVT_CHECKBOX(XRCID("chkCreateDB"), dlgUser::OnChange) + EVT_CHECKBOX(XRCID("chkCreateUser"), dlgUser::OnChangeSuperuser) + + EVT_BUTTON(XRCID("btnAddGroup"), dlgUser::OnGroupAdd) + EVT_BUTTON(XRCID("btnDelGroup"), dlgUser::OnGroupRemove) + + EVT_LIST_ITEM_SELECTED(XRCID("lstVariables"), dlgUser::OnVarSelChange) + EVT_BUTTON(wxID_ADD, dlgUser::OnVarAdd) + EVT_BUTTON(wxID_REMOVE, dlgUser::OnVarRemove) + EVT_TEXT(XRCID("cbVarname"), dlgUser::OnVarnameSelChange) + EVT_COMBOBOX(XRCID("cbVarname"), dlgUser::OnVarnameSelChange) +END_EVENT_TABLE(); + + + +dlgUser::dlgUser(pgaFactory *f, frmMain *frame, pgUser *node) + : dlgProperty(f, frame, wxT("dlgUser")) +{ + user = node; + lstVariables->CreateColumns(0, _("Variable"), _("Value"), -1); + btnOK->Disable(); + chkValue->Hide(); +} + + +pgObject *dlgUser::GetObject() +{ + return user; +} + + +int dlgUser::Go(bool modal) +{ + pgSet *set = connection->ExecuteSet(wxT("SELECT groname FROM pg_group")); + if (set) + { + while (!set->Eof()) + { + wxString groupName = set->GetVal(wxT("groname")); + if (user && user->GetGroupsIn().Index(groupName) >= 0) + lbGroupsIn->Append(groupName); + else + lbGroupsNotIn->Append(groupName); + + set->MoveNext(); + } + delete set; + } + + if (connection->BackendMinimumVersion(7, 4)) + set = connection->ExecuteSet(wxT("SELECT name, vartype, min_val, max_val\n") + wxT(" FROM pg_settings WHERE context in ('user', 'superuser')")); + else + set = connection->ExecuteSet(wxT("SELECT name, 'string' as vartype, '' as min_val, '' as max_val FROM pg_settings")); + if (set) + { + while (!set->Eof()) + { + cbVarname->Append(set->GetVal(0)); + varInfo.Add(set->GetVal(wxT("vartype")) + wxT(" ") + + set->GetVal(wxT("min_val")) + wxT(" ") + + set->GetVal(wxT("max_val"))); + set->MoveNext(); + } + delete set; + + cbVarname->SetSelection(0); + SetupVarEditor(0); + } + + if (user) + { + // Edit Mode + readOnly = !user->GetServer()->GetSuperUser(); + + txtID->SetValue(NumToStr(user->GetUserId())); + chkCreateDB->SetValue(user->GetCreateDatabase()); + chkCreateUser->SetValue(user->GetSuperuser()); + if (user->GetAccountExpires().IsValid()) + { + datValidUntil->SetValue(user->GetAccountExpires().GetDateOnly()); + timValidUntil->SetTime(user->GetAccountExpires()); + } + if (!connection->BackendMinimumVersion(7, 4)) + txtName->Disable(); + txtID->Disable(); + + size_t index; + for (index = 0 ; index < user->GetConfigList().GetCount() ; index++) + { + wxString item = user->GetConfigList().Item(index); + lstVariables->AppendItem(0, item.BeforeFirst('='), item.AfterFirst('=')); + } + + timValidUntil->Enable(!readOnly && user->GetAccountExpires().IsValid()); + + if (readOnly) + { + chkCreateDB->Disable(); + chkCreateUser->Disable(); + datValidUntil->Disable(); + timValidUntil->Disable(); + btnAddGroup->Disable(); + btnDelGroup->Disable(); + cbVarname->Disable(); + txtValue->Disable(); + btnRemove->Disable(); + if (connection->GetUser() != user->GetName()) + { + txtPasswd->Disable(); + txtRePasswd->Disable(); + btnAdd->Disable(); + } + else + { + txtPasswd->Enable(); + txtRePasswd->Enable(); + btnAdd->Enable(); + } + } + } + else + { + wxDateTime empty; + datValidUntil->SetValue(empty); + txtID->SetValidator(numericValidator); + timValidUntil->Disable(); + } + + return dlgProperty::Go(modal); +} + + +wxString dlgUser::GetHelpPage() const +{ + if (nbNotebook->GetSelection() == 2) + return wxT("pg/runtime-config"); + return dlgProperty::GetHelpPage(); +} + + +void dlgUser::OnChangeCal(wxCalendarEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + + +void dlgUser::OnChangeDate(wxDateEvent &ev) +{ + bool timEn = ev.GetDate().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + else + timValidUntil->SetTime(wxDateTime::Today()); + + CheckChange(); +} + +void dlgUser::OnChangeSpin(wxSpinEvent &ev) +{ + CheckChange(); +} + + +void dlgUser::OnChangeSuperuser(wxCommandEvent &ev) +{ + if (user && user->GetSuperuser() && !chkCreateUser->GetValue()) + { + wxMessageDialog dlg(this, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + { + chkCreateUser->SetValue(true); + return; + } + } + CheckChange(); +} + +void dlgUser::OnChangePasswd(wxCommandEvent &ev) +{ + CheckChange(); +} + +void dlgUser::CheckChange() +{ + bool timEn = datValidUntil->GetValue().IsValid(); + timValidUntil->Enable(timEn); + if (!timEn) + timValidUntil->SetTime(wxDefaultDateTime); + + // Check the passwords match + if (txtPasswd->GetValue() != txtRePasswd->GetValue()) + { + bool enable = true; + CheckValid(enable, false, _("The passwords entered do not match!")); + EnableOK(enable); + return; + } + + if (!user) + { + wxString name = GetName(); + + bool enable = true; + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + EnableOK(enable); + } + else + { + EnableOK(!GetSql().IsEmpty()); + } +} + + +void dlgUser::OnGroupAdd(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbGroupsNotIn->GetSelection(); + if (pos >= 0) + { + lbGroupsIn->Append(lbGroupsNotIn->GetString(pos)); + lbGroupsNotIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgUser::OnGroupRemove(wxCommandEvent &ev) +{ + if (!readOnly) + { + int pos = lbGroupsIn->GetSelection(); + if (pos >= 0) + { + lbGroupsNotIn->Append(lbGroupsIn->GetString(pos)); + lbGroupsIn->Delete(pos); + } + CheckChange(); + } +} + + +void dlgUser::OnVarnameSelChange(wxCommandEvent &ev) +{ + int sel = cbVarname->GuessSelection(ev); + + SetupVarEditor(sel); +} + +void dlgUser::SetupVarEditor(int var) +{ + if (var >= 0 && varInfo.Count() > 0) + { + wxStringTokenizer vals(varInfo.Item(var)); + wxString typ = vals.GetNextToken(); + + if (typ == wxT("bool")) + { + txtValue->Hide(); + chkValue->Show(); + } + else + { + chkValue->Hide(); + txtValue->Show(); + if (typ == wxT("string") || typ == wxT("enum")) + txtValue->SetValidator(wxTextValidator()); + else + txtValue->SetValidator(numericValidator); + } + } +} + +void dlgUser::OnVarSelChange(wxListEvent &ev) +{ + long pos = lstVariables->GetSelection(); + if (pos >= 0) + { + wxString value = lstVariables->GetText(pos, 1); + cbVarname->SetValue(lstVariables->GetText(pos)); + + + // We used to raise an OnVarnameSelChange() event here, but + // at this point the combo box hasn't necessarily updated. + int sel = cbVarname->FindString(lstVariables->GetText(pos)); + SetupVarEditor(sel); + + txtValue->SetValue(value); + chkValue->SetValue(value == wxT("on")); + } +} + + + +void dlgUser::OnVarAdd(wxCommandEvent &ev) +{ + wxString name = cbVarname->GetValue(); + wxString value; + if (chkValue->IsShown()) + value = chkValue->GetValue() ? wxT("on") : wxT("off"); + else + value = txtValue->GetValue().Strip(wxString::both); + + if (value.IsEmpty()) + value = wxT("DEFAULT"); + + if (!name.IsEmpty()) + { + long pos = lstVariables->FindItem(-1, name); + if (pos < 0) + { + pos = lstVariables->GetItemCount(); + lstVariables->InsertItem(pos, name, 0); + } + lstVariables->SetItem(pos, 1, value); + } + CheckChange(); +} + + +void dlgUser::OnVarRemove(wxCommandEvent &ev) +{ + if (lstVariables->GetSelection() == wxNOT_FOUND) + return; + lstVariables->DeleteCurrentItem(); + CheckChange(); +} + + +pgObject *dlgUser::CreateObject(pgCollection *collection) +{ + wxString name = GetName(); + + pgObject *obj = userFactory.CreateObjects(collection, 0, wxT("\n WHERE usename=") + qtDbString(name)); + return obj; +} + + +wxString dlgUser::GetSql() +{ + int pos; + wxString sql; + wxString name = GetName(); + + wxString passwd = txtPasswd->GetValue(); + bool createDB = chkCreateDB->GetValue(), + createUser = chkCreateUser->GetValue(); + + if (user) + { + // Edit Mode + + AppendNameChange(sql); + + + wxString options; + if (!passwd.IsEmpty()) + options += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + + if (createDB != user->GetCreateDatabase() || createUser != user->GetSuperuser()) + options += wxT("\n "); + + if (createDB != user->GetCreateDatabase()) + { + if (createDB) + options += wxT(" CREATEDB"); + else + options += wxT(" NOCREATEDB"); + } + if (createUser != user->GetSuperuser()) + { + if (createUser) + options += wxT(" CREATEUSER"); + else + options += wxT(" NOCREATEUSER"); + } + + if (!datValidUntil->GetValue().IsValid() || DateToStr(datValidUntil->GetValue()) != DateToStr(user->GetAccountExpires())) + { + if (datValidUntil->GetValue().IsValid()) + options += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else + options += wxT("\n VALID UNTIL 'infinity'"); + } + + if (!options.IsNull()) + sql += wxT("ALTER USER ") + qtIdent(name) + options + wxT(";\n"); + + int cnt = lbGroupsIn->GetCount(); + wxArrayString tmpGroups = user->GetGroupsIn(); + + // check for added groups + for (pos = 0 ; pos < cnt ; pos++) + { + wxString groupName = lbGroupsIn->GetString(pos); + + int index = tmpGroups.Index(groupName); + if (index >= 0) + tmpGroups.RemoveAt(index); + else + sql += wxT("ALTER GROUP ") + qtIdent(groupName) + + wxT("\n ADD USER ") + qtIdent(name) + wxT(";\n"); + } + + // check for removed groups + for (pos = 0 ; pos < (int)tmpGroups.GetCount() ; pos++) + { + sql += wxT("ALTER GROUP ") + qtIdent(tmpGroups.Item(pos)) + + wxT("\n DROP USER ") + qtIdent(name) + wxT(";\n"); + } + } + else + { + // Create Mode + + long id = StrToLong(txtID->GetValue()); + + sql = wxT( + "CREATE USER ") + qtIdent(name); + if (id) + sql += wxT("\n WITH SYSID ") + NumToStr(id); + if (!passwd.IsEmpty()) + sql += wxT(" ENCRYPTED PASSWORD ") + qtDbString(connection->EncryptPassword(name, passwd)); + + if (createDB || createUser) + sql += wxT("\n "); + if (createDB) + sql += wxT(" CREATEDB"); + if (createUser) + sql += wxT(" CREATEUSER"); + if (datValidUntil->GetValue().IsValid()) + sql += wxT("\n VALID UNTIL ") + qtDbString(DateToAnsiStr(datValidUntil->GetValue() + timValidUntil->GetValue())); + else + sql += wxT("\n VALID UNTIL 'infinity'"); + sql += wxT(";\n"); + + int cnt = lbGroupsIn->GetCount(); + for (pos = 0 ; pos < cnt ; pos++) + sql += wxT("ALTER GROUP ") + qtIdent(lbGroupsIn->GetString(pos)) + + wxT("\n ADD USER ") + qtIdent(name) + wxT(";\n"); + } + + wxArrayString vars; + size_t index; + + if (user) + { + for (index = 0 ; index < user->GetConfigList().GetCount() ; index++) + vars.Add(user->GetConfigList().Item(index)); + } + + int cnt = lstVariables->GetItemCount(); + + // check for changed or added vars + for (pos = 0 ; pos < cnt ; pos++) + { + wxString newVar = lstVariables->GetText(pos); + wxString newVal = lstVariables->GetText(pos, 1); + + wxString oldVal; + + for (index = 0 ; index < vars.GetCount() ; index++) + { + wxString var = vars.Item(index); + if (var.BeforeFirst('=').IsSameAs(newVar, false)) + { + oldVal = var.Mid(newVar.Length() + 1); + vars.RemoveAt(index); + break; + } + } + if (oldVal != newVal) + { + if (newVar != wxT("search_path") && newVar != wxT("temp_tablespaces")) + sql += wxT("ALTER USER ") + qtIdent(name) + + wxT("\n SET ") + newVar + + wxT("='") + newVal + + wxT("';\n"); + else + sql += wxT("ALTER USER ") + qtIdent(name) + + wxT("\n SET ") + newVar + + wxT("=") + newVal + + wxT(";\n"); + } + } + + // check for removed vars + for (pos = 0 ; pos < (int)vars.GetCount() ; pos++) + { + sql += wxT("ALTER USER ") + qtIdent(name) + + wxT("\n RESET ") + vars.Item(pos).BeforeFirst('=') + + wxT(";\n"); + } + + return sql; +} + + diff --git a/dlg/dlgUserMapping.cpp b/dlg/dlgUserMapping.cpp new file mode 100644 index 0000000..ccd90e9 --- /dev/null +++ b/dlg/dlgUserMapping.cpp @@ -0,0 +1,319 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUserMapping.cpp - PostgreSQL User Mapping Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "dlg/dlgUserMapping.h" +#include "schema/pgUserMapping.h" + + +// pointer to controls +#define cbUser CTRL_COMBOBOX("cbUser") +#define lstOptions CTRL_LISTVIEW("lstOptions") +#define txtOption CTRL_TEXT("txtOption") +#define txtValue CTRL_TEXT("txtValue") +#define btnAdd CTRL_BUTTON("wxID_ADD") +#define btnRemove CTRL_BUTTON("wxID_REMOVE") + + +dlgProperty *pgUserMappingFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgUserMapping(this, frame, (pgUserMapping *)node, (pgForeignServer *)parent); +} + + +BEGIN_EVENT_TABLE(dlgUserMapping, dlgProperty) + EVT_TEXT(XRCID("cbUser"), dlgUserMapping::OnChange) + EVT_COMBOBOX(XRCID("cbUser"), dlgUserMapping::OnChange) + EVT_LIST_ITEM_SELECTED(XRCID("lstOptions"), dlgUserMapping::OnSelChangeOption) + EVT_TEXT(XRCID("txtOption"), dlgUserMapping::OnChangeOptionName) + EVT_BUTTON(wxID_ADD, dlgUserMapping::OnAddOption) + EVT_BUTTON(wxID_REMOVE, dlgUserMapping::OnRemoveOption) +END_EVENT_TABLE(); + + +dlgUserMapping::dlgUserMapping(pgaFactory *f, frmMain *frame, pgUserMapping *node, pgForeignServer *parent) + : dlgProperty(f, frame, wxT("dlgUserMapping")) +{ + foreignserver = parent; + usermapping = node; +} + + +pgObject *dlgUserMapping::GetObject() +{ + return usermapping; +} + + +int dlgUserMapping::Go(bool modal) +{ + // Fill user combobox + cbUser->Append(wxT("CURRENT_USER")); + cbUser->Append(wxT("PUBLIC")); + pgSet *set = connection->ExecuteSet( + wxT("SELECT rolname\n") + wxT(" FROM pg_roles\n") + wxT(" ORDER BY rolname")); + if (set) + { + while (!set->Eof()) + { + wxString rolname = set->GetVal(wxT("rolname")); + cbUser->Append(rolname); + set->MoveNext(); + } + delete set; + } + cbUser->SetSelection(0); + + // Initialize options listview and buttons + lstOptions->AddColumn(_("Option"), 80); + lstOptions->AddColumn(_("Value"), 40); + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + btnRemove->Disable(); + + if (usermapping) + { + // edit mode + cbUser->SetValue(usermapping->GetUsr()); + cbUser->Disable(); + + wxString options = usermapping->GetOptions(); + wxString option, optionname, optionvalue; + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + lstOptions->AppendItem(optionname, optionvalue); + options = options.AfterFirst(','); + } + } + else + { + // create mode + } + + txtComment->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgUserMapping::CreateObject(pgCollection *collection) +{ + pgObject *obj = userMappingFactory.CreateObjects(collection, 0, wxT("\n AND true")); //srvname ILIKE ") + qtDbString(name)); + return obj; +} + + +void dlgUserMapping::CheckChange() +{ + bool didChange = true; + if (usermapping) + { + didChange = GetOptionsSql().Length() > 0; + EnableOK(didChange); + } + else + { + bool enable = true; + + CheckValid(enable, !cbUser->GetValue().IsEmpty(), _("Please specify user.")); + EnableOK(enable); + } +} + + + +void dlgUserMapping::OnChange(wxCommandEvent &ev) +{ + CheckChange(); +} + + +void dlgUserMapping::OnChangeOptionName(wxCommandEvent &ev) +{ + btnAdd->Enable(txtOption->GetValue().Length() > 0); +} + + +void dlgUserMapping::OnSelChangeOption(wxListEvent &ev) +{ + int row = lstOptions->GetSelection(); + if (row >= 0) + { + txtOption->SetValue(lstOptions->GetText(row, 0)); + txtValue->SetValue(lstOptions->GetText(row, 1)); + } + + btnRemove->Enable(row >= 0); +} + + +void dlgUserMapping::OnAddOption(wxCommandEvent &ev) +{ + bool found = false; + + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (lstOptions->GetText(pos).IsSameAs(txtOption->GetValue(), false)) + { + lstOptions->SetItem(pos, 1, txtValue->GetValue()); + found = true; + break; + } + } + + if (!found) + { + lstOptions->AppendItem(txtOption->GetValue(), txtValue->GetValue()); + } + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnAdd->Disable(); + + CheckChange(); +} + + +void dlgUserMapping::OnRemoveOption(wxCommandEvent &ev) +{ + int sel = lstOptions->GetSelection(); + lstOptions->DeleteItem(sel); + + txtOption->SetValue(wxT("")); + txtValue->SetValue(wxT("")); + btnRemove->Disable(); + + CheckChange(); +} + + +wxString dlgUserMapping::GetOptionsSql() +{ + wxString options = usermapping->GetOptions(); + wxString option, optionname, optionvalue, sqloptions; + bool found; + int pos; + + while (options.Length() > 0) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + // check for options + found = false; + for (pos = 0 ; pos < lstOptions->GetItemCount() && !found; pos++) + { + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + if (found) break; + } + + if (found) + { + if (lstOptions->GetText(pos, 1).Cmp(optionvalue) != 0) + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("SET ") + optionname + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + else + { + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("DROP ") + optionname; + } + + options = options.AfterFirst(','); + } + + for (pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + options = usermapping->GetOptions(); + found = false; + + while (options.Length() > 0 && !found) + { + option = options.BeforeFirst(','); + optionname = option.BeforeFirst(wxT('=')).Trim(false).Trim(); + found = lstOptions->GetText(pos, 0).Cmp(optionname) == 0; + options = options.AfterFirst(','); + } + + if (!found) + { + optionvalue = option.AfterFirst(wxT('=')).Trim(false).Trim(); + + if (sqloptions.Length() > 0) + sqloptions += wxT(", "); + sqloptions += wxT("ADD ") + lstOptions->GetText(pos, 0) + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("'"); + } + } + + return sqloptions; +} + + +wxString dlgUserMapping::GetSql() +{ + wxString sql; + + if (usermapping) + { + // edit mode + wxString sqloptions = GetOptionsSql(); + if (sqloptions.Length() > 0) + { + sql += wxT("ALTER USER MAPPING FOR ") + usermapping->GetUsr() + wxT(" SERVER ") + qtIdent(foreignserver->GetName()) + + wxT("\n OPTIONS (") + sqloptions + wxT(");\n"); + } + } + else + { + // create mode + sql = wxT("CREATE USER MAPPING FOR ") + cbUser->GetValue() + wxT(" SERVER ") + qtIdent(foreignserver->GetName()); + + // check for options + if (lstOptions->GetItemCount() > 0) + { + wxString options = wxEmptyString; + for (int pos = 0 ; pos < lstOptions->GetItemCount() ; pos++) + { + if (options.Length() > 0) + options += wxT(", "); + + options += lstOptions->GetText(pos, 0) + + wxT(" '") + lstOptions->GetText(pos, 1) + wxT("' "); + } + sql += wxT("\n OPTIONS (") + options + wxT(")"); + } + + sql += wxT(";\n"); + } + + return sql; +} + + + diff --git a/dlg/dlgView.cpp b/dlg/dlgView.cpp new file mode 100644 index 0000000..6d1664a --- /dev/null +++ b/dlg/dlgView.cpp @@ -0,0 +1,1233 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgView.cpp - PostgreSQL View Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" + +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgView.h" +#include "schema/pgView.h" +#include "schema/pgSchema.h" +#include "ctl/ctlSeclabelPanel.h" + + +// pointer to controls +#define pnlDefinition CTRL_PANEL("pnlDefinition") +#define txtSqlBox CTRL_SQLBOX("txtSqlBox") +#define chkSecurityBarrier CTRL_CHECKBOX("chkSecurityBarrier") + +/* AutoVacuum Settings */ +#define nbVaccum CTRL_NOTEBOOK("nbVacuum") +#define chkCustomVac CTRL_CHECKBOX("chkCustomVac") +#define chkVacEnabled CTRL_CHECKBOX("chkVacEnabled") +#define txtBaseVac CTRL_TEXT("txtBaseVac") +#define stBaseVacCurr CTRL_STATIC("stBaseVacCurr") +#define txtBaseAn CTRL_TEXT("txtBaseAn") +#define stBaseAnCurr CTRL_STATIC("stBaseAnCurr") +#define txtFactorVac CTRL_TEXT("txtFactorVac") +#define stFactorVacCurr CTRL_STATIC("stFactorVacCurr") +#define txtFactorAn CTRL_TEXT("txtFactorAn") +#define stFactorAnCurr CTRL_STATIC("stFactorAnCurr") +#define txtVacDelay CTRL_TEXT("txtVacDelay") +#define stVacDelayCurr CTRL_STATIC("stVacDelayCurr") +#define txtVacLimit CTRL_TEXT("txtVacLimit") +#define stVacLimitCurr CTRL_STATIC("stVacLimitCurr") +#define txtFreezeMinAge CTRL_TEXT("txtFreezeMinAge") +#define stFreezeMinAgeCurr CTRL_STATIC("stFreezeMinAgeCurr") +#define txtFreezeMaxAge CTRL_TEXT("txtFreezeMaxAge") +#define stFreezeMaxAgeCurr CTRL_STATIC("stFreezeMaxAgeCurr") +#define txtFreezeTableAge CTRL_TEXT("txtFreezeTableAge") +#define stFreezeTableAgeCurr CTRL_STATIC("stFreezeTableAgeCurr") + +/* TOAST TABLE AutoVacuum Settings */ +#define chkCustomToastVac CTRL_CHECKBOX("chkCustomToastVac") +#define chkToastVacEnabled CTRL_CHECKBOX("chkToastVacEnabled") +#define txtBaseToastVac CTRL_TEXT("txtBaseToastVac") +#define stBaseToastVacCurr CTRL_STATIC("stBaseToastVacCurr") +#define txtFactorToastVac CTRL_TEXT("txtFactorToastVac") +#define stFactorToastVacCurr CTRL_STATIC("stFactorToastVacCurr") +#define txtToastVacDelay CTRL_TEXT("txtToastVacDelay") +#define stToastVacDelayCurr CTRL_STATIC("stToastVacDelayCurr") +#define txtToastVacLimit CTRL_TEXT("txtToastVacLimit") +#define stToastVacLimitCurr CTRL_STATIC("stToastVacLimitCurr") +#define txtToastFreezeMinAge CTRL_TEXT("txtToastFreezeMinAge") +#define stToastFreezeMinAgeCurr CTRL_STATIC("stToastFreezeMinAgeCurr") +#define txtToastFreezeMaxAge CTRL_TEXT("txtToastFreezeMaxAge") +#define stToastFreezeMaxAgeCurr CTRL_STATIC("stToastFreezeMaxAgeCurr") +#define txtToastFreezeTableAge CTRL_TEXT("txtToastFreezeTableAge") +#define stToastFreezeTableAgeCurr CTRL_STATIC("stToastFreezeTableAgeCurr") + +/* Materialized view Settings */ +#define stMaterializedView CTRL_STATIC("stMaterializedView") +#define chkMaterializedView CTRL_CHECKBOX("chkMaterializedView") +#define stTableSpace CTRL_STATIC("stTableSpace") +#define cboTablespace CTRL_COMBOBOX("cboTablespace") +#define stFillFactor CTRL_STATIC("stFillFactor") +#define txtFillFactor CTRL_TEXT("txtFillFactor") +#define stMatViewWithData CTRL_STATIC("stMatViewWithData") +#define chkMatViewWithData CTRL_CHECKBOX("chkMatViewWithData") +#define stCheckOption CTRL_STATIC("stCheckOption") +#define cbCheckOption CTRL_COMBOBOX("cbCheckOption") + +BEGIN_EVENT_TABLE(dlgView, dlgSecurityProperty) + EVT_STC_MODIFIED(XRCID("txtSqlBox"), dlgProperty::OnChangeStc) + EVT_CHECKBOX(XRCID("chkSecurityBarrier"), dlgProperty::OnChange) + EVT_COMBOBOX(XRCID("cbCheckOption"), dlgProperty::OnChange) + + /* Materialized view setting */ + EVT_CHECKBOX(XRCID("chkMaterializedView"), dlgView::OnCheckMaterializedView) + EVT_TEXT(XRCID("txtFillFactor"), dlgView::OnChangeVacuum) + + EVT_COMBOBOX(XRCID("cboTablespace"), dlgView::OnChangeVacuum) + + EVT_CHECKBOX(XRCID("chkMatViewWithData"), dlgProperty::OnChange) + + /* AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomVac"), dlgView::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkVacEnabled"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseAn"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorAn"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacDelay"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtVacLimit"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMinAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeMaxAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFreezeTableAge"), dlgView::OnChangeVacuum) + + /* TOAST TABLE AutoVacuum Settings */ + EVT_CHECKBOX(XRCID("chkCustomToastVac"), dlgView::OnChangeVacuum) + EVT_CHECKBOX(XRCID("chkToastVacEnabled"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtBaseToastVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtFactorToastVac"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacDelay"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastVacLimit"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMinAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeMaxAge"), dlgView::OnChangeVacuum) + EVT_TEXT(XRCID("txtToastFreezeTableAge"), dlgView::OnChangeVacuum) + +END_EVENT_TABLE(); + + +dlgProperty *pgViewFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgView(this, frame, (pgView *)node, (pgSchema *)parent); +} + +dlgView::dlgView(pgaFactory *f, frmMain *frame, pgView *node, pgSchema *sch) + : dlgSecurityProperty(f, frame, node, wxT("dlgView"), wxT("INSERT,SELECT,UPDATE,DELETE,RULE,REFERENCE,TRIGGER"), "arwdRxt") +{ + schema = sch; + view = node; + forceSecurityBarrierChanged = false; + + seclabelPage = new ctlSeclabelPanel(nbNotebook); +} + + +pgObject *dlgView::GetObject() +{ + return view; +} + + +int dlgView::Go(bool modal) +{ + if (connection->BackendMinimumVersion(9, 1)) + { + seclabelPage->SetConnection(connection); + seclabelPage->SetObject(view); + this->Connect(EVT_SECLABELPANEL_CHANGE, wxCommandEventHandler(dlgView::OnChange)); + } + else + seclabelPage->Disable(); + + chkSecurityBarrier->Enable(connection->BackendMinimumVersion(9, 2)); + cbCheckOption->Enable(connection->BackendMinimumVersion(9, 4)); + + if (connection->BackendMinimumVersion(9, 3)) + { + PrepareTablespace(cboTablespace); + } + + if (view) + { + // edit mode + cbSchema->Enable(connection->BackendMinimumVersion(8, 1)); + oldDefinition = view->GetFormattedDefinition(); + txtSqlBox->SetText(oldDefinition); + chkSecurityBarrier->SetValue(view->GetSecurityBarrier() == wxT("true")); + + if ((connection->BackendMinimumVersion(9, 3) && view)) + { + // If it is materialized view than edit it + if (view->GetMaterializedView()) + { + // Checked the view as user is in edit materialized view mode + chkMaterializedView->SetValue(true); + + // Disable the security barrier as user is editing the materailized view + chkSecurityBarrier->Disable(); + + // Disable the check-option as user is editing the materailized view + cbCheckOption->Disable(); + + // Disable the materialized view as user is editing it and not allowed to switch to other view + chkMaterializedView->Disable(); + + if (view->GetTablespaceOid() != 0) + cboTablespace->SetKey(view->GetTablespaceOid()); + + txtFillFactor->SetValue(view->GetFillFactor()); + + if (view->GetIsPopulated().Cmp(wxT("t")) == 0) + chkMatViewWithData->SetValue(true); + else + chkMatViewWithData->SetValue(false); + + settingAutoVacuum = false; + + pgSetIterator avSet(connection, + wxT("SELECT name, setting FROM pg_settings WHERE name like '%vacuum%' ORDER BY name")); + while (avSet.RowsLeft()) + { + wxString name = avSet.GetVal(wxT("name")); + wxString setting = avSet.GetVal(wxT("setting")); + + if (name == wxT("autovacuum_vacuum_cost_delay")) + settingCostDelay = setting; + else if (name == wxT("vacuum_cost_delay")) + { + if (StrToLong(settingCostDelay) < 0) + settingCostDelay = setting; + } + else if (name == wxT("autovacuum_vacuum_cost_limit")) + settingCostLimit = setting; + else if (name == wxT("vacuum_cost_limit")) + { + if (StrToLong(settingCostLimit) < 0) + settingCostLimit = setting; + } + else if (name == wxT("autovacuum_vacuum_scale_factor")) + settingVacFactor = setting; + else if (name == wxT("autovacuum_analyze_scale_factor")) + settingAnlFactor = setting; + else if (name == wxT("autovacuum_vacuum_threshold")) + settingVacBaseThr = setting; + else if (name == wxT("autovacuum_analyze_threshold")) + settingAnlBaseThr = setting; + else if (name == wxT("vacuum_freeze_min_age")) + settingFreezeMinAge = setting; + else if (name == wxT("autovacuum_freeze_max_age")) + settingFreezeMaxAge = setting; + else if (name == wxT("vacuum_freeze_table_age")) + settingFreezeTableAge = setting; + else + settingAutoVacuum = avSet.GetBool(wxT("setting")); + } + + tableVacBaseThr = wxT("-1"); + tableAnlBaseThr = wxT("-1"); + tableCostDelay = wxT("-1"); + tableCostLimit = wxT("-1"); + tableFreezeMinAge = wxT("-1"); + tableFreezeMaxAge = wxT("-1"); + tableVacFactor = wxT("-1"); + tableAnlFactor = wxT("-1"); + tableFreezeTableAge = wxT("-1"); + + toastTableVacBaseThr = wxT("-1"); + toastTableCostDelay = wxT("-1"); + toastTableCostLimit = wxT("-1"); + toastTableFreezeMinAge = wxT("-1"); + toastTableFreezeMaxAge = wxT("-1"); + toastTableVacFactor = wxT("-1"); + toastTableFreezeTableAge = wxT("-1"); + + toastTableHasVacuum = false; + toastTableVacEnabled = false; + + if (view) + { + if (view->GetAutoVacuumEnabled() == 2) + tableVacEnabled = settingAutoVacuum; + else + tableVacEnabled = view->GetAutoVacuumEnabled() == 1; + if (!view->GetAutoVacuumVacuumThreshold().IsEmpty()) + tableVacBaseThr = view->GetAutoVacuumVacuumThreshold(); + if (!view->GetAutoVacuumAnalyzeThreshold().IsEmpty()) + tableAnlBaseThr = view->GetAutoVacuumAnalyzeThreshold(); + if (!view->GetAutoVacuumVacuumScaleFactor().IsEmpty()) + tableVacFactor = view->GetAutoVacuumVacuumScaleFactor(); + if (!view->GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + tableAnlFactor = view->GetAutoVacuumAnalyzeScaleFactor(); + if (!view->GetAutoVacuumVacuumCostDelay().IsEmpty()) + tableCostDelay = view->GetAutoVacuumVacuumCostDelay(); + if (!view->GetAutoVacuumVacuumCostLimit().IsEmpty()) + tableCostLimit = view->GetAutoVacuumVacuumCostLimit(); + if (!view->GetAutoVacuumFreezeMinAge().IsEmpty()) + tableFreezeMinAge = view->GetAutoVacuumFreezeMinAge(); + if (!view->GetAutoVacuumFreezeMaxAge().IsEmpty()) + tableFreezeMaxAge = view->GetAutoVacuumFreezeMaxAge(); + if (!view->GetAutoVacuumFreezeTableAge().IsEmpty()) + tableFreezeTableAge = view->GetAutoVacuumFreezeTableAge(); + + hasVacuum = view->GetCustomAutoVacuumEnabled(); + chkVacEnabled->SetValue(hasVacuum ? tableVacEnabled : settingAutoVacuum); + + toastTableVacEnabled = false; + + if (!view->GetHasToastTable()) + { + nbVaccum->GetPage(2)->Enable(false); + } + else + { + toastTableHasVacuum = view->GetToastCustomAutoVacuumEnabled(); + if (toastTableHasVacuum) + { + if (view->GetToastAutoVacuumEnabled() == 2) + toastTableVacEnabled = settingAutoVacuum; + else + toastTableVacEnabled = view->GetToastAutoVacuumEnabled() == 1; + if (!view->GetToastAutoVacuumVacuumThreshold().IsEmpty()) + toastTableVacBaseThr = view->GetToastAutoVacuumVacuumThreshold(); + if (!view->GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + toastTableVacFactor = view->GetToastAutoVacuumVacuumScaleFactor(); + if (!view->GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + toastTableCostDelay = view->GetToastAutoVacuumVacuumCostDelay(); + if (!view->GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + toastTableCostLimit = view->GetToastAutoVacuumVacuumCostLimit(); + if (!view->GetToastAutoVacuumFreezeMinAge().IsEmpty()) + toastTableFreezeMinAge = view->GetToastAutoVacuumFreezeMinAge(); + if (!view->GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + toastTableFreezeMaxAge = view->GetToastAutoVacuumFreezeMaxAge(); + if (!view->GetToastAutoVacuumFreezeTableAge().IsEmpty()) + toastTableFreezeTableAge = view->GetToastAutoVacuumFreezeTableAge(); + } + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + } + } + else + { + hasVacuum = false; + chkVacEnabled->SetValue(settingAutoVacuum); + } + + txtBaseVac->SetValue(tableVacBaseThr); + txtBaseAn->SetValue(tableAnlBaseThr); + txtFactorVac->SetValue(tableVacFactor); + txtFactorAn->SetValue(tableAnlFactor); + txtVacDelay->SetValue(tableCostDelay); + txtVacLimit->SetValue(tableCostLimit); + txtFreezeMinAge->SetValue(tableFreezeMinAge); + txtFreezeMaxAge->SetValue(tableFreezeMaxAge); + + txtFreezeTableAge->SetValue(tableFreezeTableAge); + txtBaseToastVac->SetValue(toastTableVacBaseThr); + txtFactorToastVac->SetValue(toastTableVacFactor); + txtToastVacDelay->SetValue(toastTableCostDelay); + txtToastVacLimit->SetValue(toastTableCostLimit); + txtToastFreezeMinAge->SetValue(toastTableFreezeMinAge); + txtToastFreezeMaxAge->SetValue(toastTableFreezeMaxAge); + txtToastFreezeTableAge->SetValue(toastTableFreezeTableAge); + + chkCustomToastVac->SetValue(toastTableHasVacuum); + chkToastVacEnabled->SetValue(toastTableHasVacuum ? toastTableVacEnabled : settingAutoVacuum); + + chkCustomVac->SetValue(hasVacuum); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + else + { + // It is not materialized view so disabling all the controls + DisableMaterializedView(); + } + + cbCheckOption->SetSelection(GetIndexCheckOption(view->GetCheckOption())); + } + } + else + { + // create mode + cboTablespace->Insert(_(""), 0, (void *)0); + cboTablespace->SetSelection(0); + cbCheckOption->SetSelection(0); + wxCommandEvent ev; + OnChangeVacuum(ev); + } + + // Find, and disable the RULE ACL option if we're 8.2 + if (connection->BackendMinimumVersion(8, 2)) + { + // Disable the checkbox + if (!DisablePrivilege(wxT("RULE"))) + { + wxLogError(_("Failed to disable the RULE privilege checkbox!")); + } + } + + return dlgSecurityProperty::Go(modal); +} + + +pgObject *dlgView::CreateObject(pgCollection *collection) +{ + pgObject *obj = viewFactory.CreateObjects(collection, 0, + wxT("\n AND c.relname=") + qtDbString(txtName->GetValue()) + + wxT("\n AND c.relnamespace=") + schema->GetOidStr()); + return obj; +} + + +void dlgView::CheckChange() +{ + bool enable = true; + wxString name = GetName(); + + CheckValid(enable, !name.IsEmpty(), _("Please specify name.")); + CheckValid(enable, txtSqlBox->GetText().Trim(true).Trim(false).Length() > 0 , _("Please enter function definition.")); + + if (!connection->BackendMinimumVersion(9, 3)) + { + DisableMaterializedView(); + } + + if(enable) + { + if (view) + enable = txtComment->GetValue() != view->GetComment() + || txtSqlBox->GetText().Trim(true).Trim(false) != oldDefinition.Trim(true).Trim(false) + || cbOwner->GetValue() != view->GetOwner() + || cbSchema->GetValue() != view->GetSchema()->GetName() + || name != view->GetName(); + + if (connection->BackendMinimumVersion(9, 3)) + { + enable = !GetSql().IsEmpty(); + } + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + enable = enable || !(seclabelPage->GetSqlForSecLabels().IsEmpty()); + + if (connection->BackendMinimumVersion(9, 2)) + { + if (view) + { + if (chkSecurityBarrier->GetValue()) + enable = enable || !(view->GetSecurityBarrier() == wxT("true")); + else + enable = enable || (view->GetSecurityBarrier() == wxT("true")); + } + else + { + enable = enable || (chkSecurityBarrier->GetValue()); + } + } + + if (connection->BackendMinimumVersion(9, 4) && view) + { + enable = enable || (cbCheckOption->GetSelection() != GetIndexCheckOption(view->GetCheckOption())); + } + } + + EnableOK(enable); +} + + +wxString dlgView::GetSql() +{ + wxString sql; + wxString name; + wxString withoptions = wxEmptyString; + bool editQuery = false; + + if (view) + { + // edit mode + name = GetName(); + + if (name != view->GetName()) + { + if (connection->BackendMinimumVersion(8, 3)) + { + if (connection->BackendMinimumVersion(9, 3)) + { + if (view->GetMaterializedView()) + { + AppendNameChange(sql, wxT("MATERIALIZED VIEW ") + view->GetQuotedFullIdentifier()); + editQuery = true; + } + else + AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + } + else + AppendNameChange(sql, wxT("VIEW ") + view->GetQuotedFullIdentifier()); + } + else + AppendNameChange(sql, wxT("TABLE ") + view->GetQuotedFullIdentifier()); + } + + if (connection->BackendMinimumVersion(8, 4) && cbSchema->GetName() != view->GetSchema()->GetName()) + { + if (connection->BackendMinimumVersion(9, 3)) + { + if (view->GetMaterializedView()) + { + AppendSchemaChange(sql, wxT("MATERIALIZED VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + editQuery = true; + } + else + AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + else + AppendSchemaChange(sql, wxT("VIEW " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + else + AppendSchemaChange(sql, wxT("TABLE " + qtIdent(view->GetSchema()->GetName()) + wxT(".") + qtIdent(name))); + } + + name = qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()); + if (!view || txtSqlBox->GetText().Trim(true).Trim(false) != oldDefinition.Trim(true).Trim(false)) + { + if (editQuery) + { + // Delete the materialized view query + sql += wxT("DROP MATERIALIZED VIEW ") + name + wxT(";"); + } + + // Check if user creates the materialized view + if (!chkMaterializedView->GetValue()) + { + sql += wxT("CREATE OR REPLACE VIEW ") + name; + + if (connection->BackendMinimumVersion(9, 2) && chkSecurityBarrier->GetValue()) + withoptions += wxT("security_barrier=true"); + if (connection->BackendMinimumVersion(9, 4) && cbCheckOption->GetSelection() > 0) + { + if (withoptions.Length() > 0) + withoptions += wxT(", "); + if (cbCheckOption->GetSelection() == 1) + withoptions += wxT("check_option=local"); + if (cbCheckOption->GetSelection() == 2) + withoptions += wxT("check_option=cascaded"); + } + + if (withoptions.Length() > 0) + sql += wxT(" WITH (") + withoptions + wxT(")"); + + sql += wxT(" AS\n") + + txtSqlBox->GetText().Trim(true).Trim(false) + + wxT(";\n"); + } + else if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + sql += wxT("CREATE MATERIALIZED VIEW ") + name; + + // Add the parameter of tablespace and storage parameter to create the materilized view + if (txtFillFactor->GetValue().Trim().Length() > 0 || chkVacEnabled->GetValue() == true || chkToastVacEnabled->GetValue() == true) + { + bool fillFactorFlag, toastTableFlag; + fillFactorFlag = false; + toastTableFlag = false; + + sql += wxT("\nWITH ("); + + if (txtFillFactor->GetValue().Trim().Length() > 0) + { + sql += wxT("\n FILLFACTOR = ") + txtFillFactor->GetValue(); + fillFactorFlag = true; + } + + bool valChanged = false; + wxString newVal; + wxString resetStr; + + if (connection->BackendMinimumVersion(9, 3) && chkCustomVac->GetValue()) + { + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + + if (!fillFactorFlag) + { + int position = sql.Find(',', true); + if (position != wxNOT_FOUND) + sql.Remove(position, 1); + toastTableFlag = true; + } + + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + } + + if (connection->BackendMinimumVersion(9, 3) && chkCustomToastVac->GetValue()) + { + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + + if (!fillFactorFlag && !toastTableFlag) + { + int position = sql.Find(',', true); + if (position != wxNOT_FOUND) + sql.Remove(position, 1); + } + + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(sql, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + } + + sql += wxT("\n)\n"); + } + + if (cboTablespace->GetCurrentSelection() > 0 && cboTablespace->GetOIDKey() > 0) + sql += wxT("\nTABLESPACE ") + qtIdent(cboTablespace->GetValue()); + + wxString sqlDefinition; + bool tmpLoopFlag = true; + sqlDefinition = txtSqlBox->GetText().Trim(true).Trim(false); + + // Remove semicolon from the end of the string + while(tmpLoopFlag) + { + int length = sqlDefinition.Len(); + int position = sqlDefinition.Find(';', true); + if ((position != wxNOT_FOUND) && (position = (length - 1))) + sqlDefinition.Remove(position, 1); + else + tmpLoopFlag = false; + } + + sql += wxT(" AS\n") + + sqlDefinition; + + if (chkMatViewWithData->GetValue()) + sql += wxT("\n WITH DATA;\n"); + else + sql += wxT("\n WITH NO DATA;\n"); + } + } + else if (view) + { + if (!chkMaterializedView->GetValue()) + { + if (connection->BackendMinimumVersion(9, 2)) + { + if (chkSecurityBarrier->GetValue() && view->GetSecurityBarrier() != wxT("true")) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (security_barrier=true);\n"); + else if (!chkSecurityBarrier->GetValue() && view->GetSecurityBarrier() == wxT("true")) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (security_barrier=false);\n"); + } + + if (connection->BackendMinimumVersion(9, 4) + && cbCheckOption->GetSelection() != GetIndexCheckOption(view->GetCheckOption()) ) + { + if ((cbCheckOption->GetSelection()) == 0) + sql += wxT("ALTER VIEW ") + name + wxT(" RESET (check_option);\n"); + else + { + if (cbCheckOption->GetSelection() == 1) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (check_option=local") + wxT(");\n"); + if (cbCheckOption->GetSelection() == 2) + sql += wxT("ALTER VIEW ") + name + wxT("\n SET (check_option=cascaded") + wxT(");\n"); + } + } + + if (withoptions.Length() > 0) + sql += wxT(" WITH (") + withoptions + wxT(")"); + } + else if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + { + if (txtFillFactor->GetValue() != view->GetFillFactor()) + { + // If fill factor value get changed then set the new value + if (txtFillFactor->GetValue().Trim().Length() > 0) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT("\n SET (FILLFACTOR=") + + txtFillFactor->GetValue() + wxT(");\n"); + } + else + { + // If fill factor value get changed and value is not blank then do the reset + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" FILLFACTOR\n") + wxT(");\n"); + } + } + + bool isPopulatedFlag = false; + + if (view->GetIsPopulated().Cmp(wxT("t")) == 0) + isPopulatedFlag = true; + + if (chkMatViewWithData->GetValue() != isPopulatedFlag) + { + // If checkbox is checked then set WITH NO DATA + if (isPopulatedFlag) + { + sql += wxT("REFRESH MATERIALIZED VIEW ") + name + + wxT(" WITH NO DATA;\n"); + } + else + { + sql += wxT("REFRESH MATERIALIZED VIEW ") + name + + wxT(" WITH DATA;\n"); + } + } + + // Altered the storage parameters for the materialized view? + if (!chkCustomVac->GetValue()) + { + if (hasVacuum) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" autovacuum_enabled,\n") + wxT(" autovacuum_vacuum_threshold,\n") + wxT(" autovacuum_analyze_threshold,\n") + wxT(" autovacuum_vacuum_scale_factor,\n") + wxT(" autovacuum_analyze_scale_factor,\n") + wxT(" autovacuum_vacuum_cost_delay,\n") + wxT(" autovacuum_vacuum_cost_limit,\n") + wxT(" autovacuum_freeze_min_age,\n") + wxT(" autovacuum_freeze_max_age,\n") + wxT(" autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkVacEnabled->GetValue() != tableVacEnabled); + + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_enabled"), BoolToStr(chkVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseVac, tableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtBaseAn, tableAnlBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorVac, tableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorAn, tableAnlFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_analyze_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtVacDelay, tableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtVacLimit, tableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMinAge, tableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeMaxAge, tableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtFreezeTableAge, tableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER MATERIALIZED VIEW ") + name + setStr + wxT("\n);\n");; + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER MATERIALIZED VIEW ") + name + resetStr + wxT("\n);\n");; + changed = true; + } + if (changed) + sql += vacStr; + } + + if (!chkCustomToastVac->GetValue()) + { + if (toastTableHasVacuum) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT(" RESET(\n") + wxT(" toast.autovacuum_enabled,\n") + wxT(" toast.autovacuum_vacuum_threshold,\n") + wxT(" toast.autovacuum_analyze_threshold,\n") + wxT(" toast.autovacuum_vacuum_scale_factor,\n") + wxT(" toast.autovacuum_analyze_scale_factor,\n") + wxT(" toast.autovacuum_vacuum_cost_delay,\n") + wxT(" toast.autovacuum_vacuum_cost_limit,\n") + wxT(" toast.autovacuum_freeze_min_age,\n") + wxT(" toast.autovacuum_freeze_max_age,\n") + wxT(" toast.autovacuum_freeze_table_age\n") + wxT(");\n"); + } + } + else + { + wxString vacStr; + bool changed = (chkToastVacEnabled->GetValue() != toastTableVacEnabled); + bool valChanged = false; + wxString newVal; + wxString setStr; + wxString resetStr; + if (changed) + { + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_enabled"), BoolToStr(chkToastVacEnabled->GetValue())); + } + newVal = AppendNum(valChanged, txtBaseToastVac, toastTableVacBaseThr); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_threshold"), newVal); + } + + newVal = AppendNum(valChanged, txtFactorToastVac, toastTableVacFactor); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_scale_factor"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacDelay, toastTableCostDelay); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_delay"), newVal); + } + + newVal = AppendNum(valChanged, txtToastVacLimit, toastTableCostLimit); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_vacuum_cost_limit"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMinAge, toastTableFreezeMinAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_min_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeMaxAge, toastTableFreezeMaxAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_max_age"), newVal); + } + + newVal = AppendNum(valChanged, txtToastFreezeTableAge, toastTableFreezeTableAge); + if (valChanged) + { + valChanged = false; + FillAutoVacuumParameters(setStr, resetStr, wxT("toast.autovacuum_freeze_table_age"), newVal); + } + + if (!setStr.IsEmpty()) + { + vacStr = wxT("ALTER MATERIALIZED VIEW ") + name + setStr + wxT("\n);\n"); + changed = true; + } + if (!resetStr.IsEmpty()) + { + vacStr += wxT("ALTER MATERIALIZED VIEW ") + name + resetStr + wxT("\n);\n"); + changed = true; + } + if (changed) + sql += vacStr; + } + + if (cboTablespace->GetOIDKey() != view->GetTablespaceOid()) + { + sql += wxT("ALTER MATERIALIZED VIEW ") + name + + wxT("\n SET TABLESPACE ") + qtIdent(cboTablespace->GetValue()) + + wxT(";\n"); + } + } + } + + if (view) + AppendOwnerChange(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + else + AppendOwnerNew(sql, wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + if (connection->BackendMinimumVersion(9, 3) && chkMaterializedView->GetValue()) + AppendComment(sql, wxT("MATERIALIZED VIEW ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), view); + else + AppendComment(sql, wxT("VIEW ") + qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName()), view); + + if (seclabelPage && connection->BackendMinimumVersion(9, 1)) + sql += seclabelPage->GetSqlForSecLabels(wxT("VIEW"), qtIdent(cbSchema->GetValue()) + wxT(".") + qtIdent(GetName())); + + return sql; +} + +bool dlgView::IsUpToDate() +{ + if (view && !view->IsUpToDate()) + return false; + else + return true; +} + +void dlgView::OnChange(wxCommandEvent &event) +{ + CheckChange(); +} + +void dlgView::OnCheckMaterializedView(wxCommandEvent &ev) +{ + if (chkMaterializedView->GetValue()) + { + // Security barrier and Check-option, are not applicable to the materialized view + cbCheckOption->Disable(); + if (chkSecurityBarrier->GetValue()) + { + wxMessageBox(_("The security barrier option is not applicable to materialized views and has been turned off."), _("View"), wxICON_EXCLAMATION | wxOK, this); + chkSecurityBarrier->SetValue(false); + chkSecurityBarrier->Disable(); + forceSecurityBarrierChanged = true; + } + else + { + chkSecurityBarrier->Disable(); + } + + cboTablespace->Enable(); + txtFillFactor->Enable(); + chkMatViewWithData->Enable(); + chkCustomVac->Enable(); + chkCustomToastVac->Enable(); + } + else + { + chkSecurityBarrier->Enable(); + cbCheckOption->Enable(); + chkSecurityBarrier->SetValue(forceSecurityBarrierChanged); + forceSecurityBarrierChanged = false; + + DisableStorageParameters(); + } +} + +void dlgView::FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, + const wxString ¶meter, const wxString &val) +{ + if (val == wxT("-1")) + { + if (resetStr.IsEmpty()) + resetStr = wxT(" RESET ("); + else + resetStr += wxT(","); + resetStr += wxT("\n ") + parameter; + } + else + { + if (setStr.IsEmpty()) + setStr = wxT(" SET ("); + else + setStr += wxT(","); + setStr += wxT("\n ") + parameter + wxT(" = ") + val; + } +} + +wxString dlgView::AppendNum(bool &changed, wxTextCtrl *ctl, wxString val) +{ + wxString str = ctl->GetValue(); + if (str.IsEmpty() || str.StartsWith(wxT("-"))) + str = wxT("-1"); + + changed |= (str != val); + return str; +} + +void dlgView::OnChangeVacuum(wxCommandEvent &ev) +{ + if (connection->BackendMinimumVersion(9, 3)) + { + bool vacEn = chkCustomVac->GetValue() && chkVacEnabled->GetValue(); + chkCustomVac->Enable(chkMaterializedView->GetValue()); + chkVacEnabled->Enable(chkCustomVac->GetValue()); + cboTablespace->Enable(chkMaterializedView->GetValue()); + txtFillFactor->Enable(chkMaterializedView->GetValue()); + chkMatViewWithData->Enable(chkMaterializedView->GetValue()); + + txtBaseVac->Enable(vacEn); + txtBaseAn->Enable(vacEn); + txtFactorVac->Enable(vacEn); + txtFactorAn->Enable(vacEn); + txtVacDelay->Enable(vacEn); + txtVacLimit->Enable(vacEn); + txtFreezeMinAge->Enable(vacEn); + txtFreezeMaxAge->Enable(vacEn); + + stBaseVacCurr->SetLabel(tableVacBaseThr == wxT("-1") ? settingVacBaseThr : tableVacBaseThr); + stBaseAnCurr->SetLabel(tableAnlBaseThr == wxT("-1") ? settingAnlBaseThr : tableAnlBaseThr); + stFactorVacCurr->SetLabel(tableVacFactor == wxT("-1") ? settingVacFactor : tableVacFactor); + stFactorAnCurr->SetLabel(tableAnlFactor == wxT("-1") ? settingAnlFactor : tableAnlFactor); + stVacDelayCurr->SetLabel(tableCostDelay == wxT("-1") ? settingCostDelay : tableCostDelay); + stVacLimitCurr->SetLabel(tableCostLimit == wxT("-1") ? settingCostLimit : tableCostLimit); + + stFreezeMinAgeCurr->SetLabel(tableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : tableFreezeMinAge); + stFreezeMaxAgeCurr->SetLabel(tableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : tableFreezeMaxAge); + + txtFreezeTableAge->Enable(vacEn); + stFreezeTableAgeCurr->SetLabel(tableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : tableFreezeTableAge); + /* Toast Table Vacuum Settings */ + bool toastVacEn = chkCustomToastVac->GetValue() && chkToastVacEnabled->GetValue(); + chkCustomToastVac->Enable(chkMaterializedView->GetValue()); + chkToastVacEnabled->Enable(chkCustomToastVac->GetValue()); + + txtBaseToastVac->Enable(toastVacEn); + txtFactorToastVac->Enable(toastVacEn); + txtToastVacDelay->Enable(toastVacEn); + txtToastVacLimit->Enable(toastVacEn); + txtToastFreezeMinAge->Enable(toastVacEn); + txtToastFreezeMaxAge->Enable(toastVacEn); + txtToastFreezeTableAge->Enable(toastVacEn); + + stBaseToastVacCurr->SetLabel(toastTableVacBaseThr == wxT("-1") ? settingVacBaseThr : toastTableVacBaseThr); + stFactorToastVacCurr->SetLabel(toastTableVacFactor == wxT("-1") ? settingVacFactor : toastTableVacFactor); + stToastVacDelayCurr->SetLabel(toastTableCostDelay == wxT("-1") ? settingCostDelay : toastTableCostDelay); + stToastVacLimitCurr->SetLabel(toastTableCostLimit == wxT("-1") ? settingCostLimit : toastTableCostLimit); + stToastFreezeMinAgeCurr->SetLabel(toastTableFreezeMinAge == wxT("-1") ? settingFreezeMinAge : toastTableFreezeMinAge); + stToastFreezeMaxAgeCurr->SetLabel(toastTableFreezeMaxAge == wxT("-1") ? settingFreezeMaxAge : toastTableFreezeMaxAge); + txtToastFreezeTableAge->Enable(toastVacEn); + stToastFreezeTableAgeCurr->SetLabel(toastTableFreezeTableAge == wxT("-1") ? settingFreezeTableAge : toastTableFreezeTableAge); + } + OnChange(ev); +} + +void dlgView::DisableMaterializedView() +{ + chkMaterializedView->Disable(); + cboTablespace->Disable(); + txtFillFactor->Disable(); + chkMatViewWithData->Disable(); + + chkCustomVac->Disable(); + chkVacEnabled->Disable(); + txtBaseVac->Disable(); + txtBaseAn->Disable(); + txtFactorVac->Disable(); + txtFactorAn->Disable(); + txtVacDelay->Disable(); + txtVacLimit->Disable(); + txtFreezeMinAge->Disable(); + txtFreezeMaxAge->Disable(); + txtFreezeTableAge->Disable(); + + chkToastVacEnabled->Disable(); + chkCustomToastVac->Disable(); + txtBaseToastVac->Disable(); + txtFactorToastVac->Disable(); + txtToastVacDelay->Disable(); + txtToastVacLimit->Disable(); + txtToastFreezeMinAge->Disable(); + txtToastFreezeMaxAge->Disable(); + txtToastFreezeTableAge->Disable(); +} + +void dlgView::DisableStorageParameters() +{ + cboTablespace->Disable(); + txtFillFactor->Disable(); + chkMatViewWithData->Disable(); + + chkCustomVac->Disable(); + chkVacEnabled->Disable(); + txtBaseVac->Disable(); + txtBaseAn->Disable(); + txtFactorVac->Disable(); + txtFactorAn->Disable(); + txtVacDelay->Disable(); + txtVacLimit->Disable(); + txtFreezeMinAge->Disable(); + txtFreezeMaxAge->Disable(); + txtFreezeTableAge->Disable(); + + chkToastVacEnabled->Disable(); + chkCustomToastVac->Disable(); + txtBaseToastVac->Disable(); + txtFactorToastVac->Disable(); + txtToastVacDelay->Disable(); + txtToastVacLimit->Disable(); + txtToastFreezeMinAge->Disable(); + txtToastFreezeMaxAge->Disable(); + txtToastFreezeTableAge->Disable(); +} + +int dlgView::GetIndexCheckOption(const wxString &str) const +{ + if (str.Cmp(wxT("local")) == 0) + return 1; + if (str.Cmp(wxT("cascaded")) == 0) + return 2; + + return 0; +} diff --git a/dlg/module.mk b/dlg/module.mk new file mode 100644 index 0000000..c1a4e33 --- /dev/null +++ b/dlg/module.mk @@ -0,0 +1,72 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/dlg/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + dlg/dlgAddFavourite.cpp \ + dlg/dlgAggregate.cpp \ + dlg/dlgCast.cpp \ + dlg/dlgClasses.cpp \ + dlg/dlgCheck.cpp \ + dlg/dlgCollation.cpp \ + dlg/dlgColumn.cpp \ + dlg/dlgConnect.cpp \ + dlg/dlgConversion.cpp \ + dlg/dlgDatabase.cpp \ + dlg/dlgDomain.cpp \ + dlg/dlgEventTrigger.cpp \ + dlg/dlgExtension.cpp \ + dlg/dlgEditGridOptions.cpp \ + dlg/dlgFindReplace.cpp \ + dlg/dlgForeignDataWrapper.cpp \ + dlg/dlgForeignKey.cpp \ + dlg/dlgForeignServer.cpp \ + dlg/dlgForeignTable.cpp \ + dlg/dlgFunction.cpp \ + dlg/dlgGroup.cpp \ + dlg/dlgHbaConfig.cpp \ + dlg/dlgIndex.cpp \ + dlg/dlgIndexConstraint.cpp \ + dlg/dlgLanguage.cpp \ + dlg/dlgMainConfig.cpp \ + dlg/dlgManageFavourites.cpp \ + dlg/dlgMoveTablespace.cpp \ + dlg/dlgOperator.cpp \ + dlg/dlgPackage.cpp \ + dlg/dlgPgpassConfig.cpp \ + dlg/dlgProperty.cpp \ + dlg/dlgReassignDropOwned.cpp \ + dlg/dlgRole.cpp \ + dlg/dlgRule.cpp \ + dlg/dlgSchema.cpp \ + dlg/dlgSearchObject.cpp \ + dlg/dlgSelectConnection.cpp \ + dlg/dlgSequence.cpp \ + dlg/dlgServer.cpp \ + dlg/dlgSynonym.cpp \ + dlg/dlgTable.cpp \ + dlg/dlgTablespace.cpp \ + dlg/dlgTextSearchConfiguration.cpp \ + dlg/dlgTextSearchDictionary.cpp \ + dlg/dlgTextSearchParser.cpp \ + dlg/dlgTextSearchTemplate.cpp \ + dlg/dlgTrigger.cpp \ + dlg/dlgType.cpp \ + dlg/dlgUser.cpp \ + dlg/dlgUserMapping.cpp \ + dlg/dlgView.cpp \ + dlg/dlgManageMacros.cpp \ + dlg/dlgExtTable.cpp \ + dlg/dlgSelectDatabase.cpp \ + dlg/dlgResourceGroup.cpp + +EXTRA_DIST += \ + dlg/module.mk + diff --git a/ex_pscan.png b/ex_pscan.png new file mode 100644 index 0000000..381d00d Binary files /dev/null and b/ex_pscan.png differ diff --git a/ex_pscan.pngc b/ex_pscan.pngc new file mode 100644 index 0000000..db3b531 --- /dev/null +++ b/ex_pscan.pngc @@ -0,0 +1,1264 @@ +#ifndef EX_PSCAN_PNG_H +#define EX_PSCAN_PNG_H + +static const unsigned char ex_pscan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, +0x08, 0x06, 0x00, 0x00, 0x00, 0x9a, 0x76, 0x82, +0x70, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0e, 0xc2, 0x00, 0x00, 0x0e, +0xc2, 0x01, 0x15, 0x28, 0x4a, 0x80, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x50, +0x61, 0x69, 0x6e, 0x74, 0x2e, 0x4e, 0x45, 0x54, +0x20, 0x76, 0x33, 0x2e, 0x35, 0x2e, 0x38, 0x37, +0x3b, 0x80, 0x5d, 0x00, 0x00, 0x25, 0x9a, 0x49, +0x44, 0x41, 0x54, 0x78, 0x5e, 0xed, 0xd7, 0x31, +0x0d, 0x00, 0x00, 0x0c, 0xc3, 0xb0, 0xf1, 0x27, +0xdd, 0xb1, 0xc8, 0xe5, 0x11, 0xa8, 0x64, 0xed, +0xc9, 0xcd, 0x11, 0x20, 0x40, 0x80, 0x00, 0x01, +0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x12, +0xb8, 0x68, 0xc7, 0x0c, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, +0x26, 0x40, 0x3c, 0x01, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0xf0, 0x0e, 0x37, 0x69, 0xd1, 0xd1, 0xd7, 0x23, +0x17, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_pscan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_pscan_png = new wxImage(); + if (!img_ex_pscan_png || !img_ex_pscan_png->IsOk()) + { + wxMemoryInputStream img_ex_pscan_pngIS(ex_pscan_png_data, sizeof(ex_pscan_png_data)); + img_ex_pscan_png->LoadFile(img_ex_pscan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_pscan_png; +} +#define ex_pscan_png_img ex_pscan_png_img() + +static wxBitmap *ex_pscan_png_bmp() +{ + static wxBitmap *bmp_ex_pscan_png; + if (!bmp_ex_pscan_png || !bmp_ex_pscan_png->IsOk()) + bmp_ex_pscan_png = new wxBitmap(*ex_pscan_png_img); + return bmp_ex_pscan_png; +} +#define ex_pscan_png_bmp ex_pscan_png_bmp() + +static wxIcon *ex_pscan_png_ico() +{ + static wxIcon *ico_ex_pscan_png; + if (!ico_ex_pscan_png || !ico_ex_pscan_png->IsOk()) + { + ico_ex_pscan_png = new wxIcon(); + ico_ex_pscan_png->CopyFromBitmap(*ex_pscan_png_bmp); + } + return ico_ex_pscan_png; +} +#define ex_pscan_png_ico ex_pscan_png_ico() + +#endif // EX_PSCAN_PNG_H diff --git a/frm/events.cpp b/frm/events.cpp new file mode 100644 index 0000000..3c6973a --- /dev/null +++ b/frm/events.cpp @@ -0,0 +1,1179 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// events.cpp - Event handlers for frmMain +// +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include + +// App headers +#include "utils/misc.h" +#include "frm/menu.h" +#include "frm/frmMain.h" +#include "frm/frmOptions.h" +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlMenuToolbar.h" +#include "db/pgConn.h" +#include "schema/pgDatabase.h" +#include "db/pgSet.h" +#include "schema/pgServer.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgTable.h" +#include "schema/edbPrivateSynonym.h" +#include "dlg/dlgProperty.h" + +// Mutex to protect the "currentObject" from race conditions. +// +static wxMutex s_currentObjectMutex; + +// Event table +BEGIN_EVENT_TABLE(frmMain, pgFrame) + EVT_CHILD_FOCUS( frmMain::OnChildFocus) + EVT_ERASE_BACKGROUND( frmMain::OnEraseBackground) + EVT_SIZE( frmMain::OnSize) + EVT_MENU(MNU_ACTION, frmMain::OnAction) + + EVT_MENU(MNU_COPY, frmMain::OnCopy) + EVT_MENU(MNU_DELETE, frmMain::OnDelete) + EVT_MENU(MNU_SAVEDEFINITION, frmMain::OnSaveDefinition) + EVT_MENU(MNU_SQLPANE, frmMain::OnToggleSqlPane) + EVT_MENU(MNU_OBJECTBROWSER, frmMain::OnToggleObjectBrowser) + EVT_MENU(MNU_TOOLBAR, frmMain::OnToggleToolBar) + EVT_MENU(MNU_DEFAULTVIEW, frmMain::OnDefaultView) + EVT_MENU(MNU_CHECKALIVE, frmMain::OnCheckAlive) + EVT_MENU(MNU_CONTEXTMENU, frmMain::OnContextMenu) + + EVT_AUINOTEBOOK_PAGE_CHANGED(wxID_ANY, frmMain::OnPageChange) + EVT_LIST_ITEM_SELECTED(CTL_PROPVIEW, frmMain::OnPropSelChanged) + EVT_LIST_ITEM_ACTIVATED(CTL_PROPVIEW, frmMain::OnPropSelActivated) + EVT_LIST_ITEM_RIGHT_CLICK(CTL_PROPVIEW, frmMain::OnPropRightClick) + EVT_LIST_ITEM_SELECTED(CTL_STATVIEW, frmMain::OnSelectItem) + EVT_LIST_ITEM_SELECTED(CTL_DEPVIEW, frmMain::OnSelectItem) + EVT_LIST_ITEM_SELECTED(CTL_REFVIEW, frmMain::OnSelectItem) + EVT_TREE_SEL_CHANGED(CTL_BROWSER, frmMain::OnTreeSelChanged) + EVT_TREE_ITEM_EXPANDING(CTL_BROWSER, frmMain::OnExpand) + EVT_TREE_ITEM_COLLAPSING(CTL_BROWSER, frmMain::OnCollapse) + EVT_TREE_ITEM_ACTIVATED(CTL_BROWSER, frmMain::OnSelActivated) + EVT_TREE_ITEM_RIGHT_CLICK(CTL_BROWSER, frmMain::OnSelRightClick) + EVT_STC_UPDATEUI(CTL_SQLPANE, frmMain::OnPositionStc) + EVT_CLOSE( frmMain::OnClose) + + EVT_AUI_PANE_CLOSE( frmMain::OnAuiUpdate) + EVT_AUINOTEBOOK_PAGE_CLOSE(wxID_ANY, frmMain::OnAuiNotebookPageClose) + +#ifdef __WXGTK__ + EVT_TREE_KEY_DOWN(CTL_BROWSER, frmMain::OnTreeKeyDown) +#endif + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + EVT_COMMAND (wxID_ANY, SSH_TUNNEL_ERROR_EVENT, frmMain::OnSSHTunnelEvent) +#endif + +END_EVENT_TABLE() + +void frmMain::OnChildFocus(wxChildFocusEvent &event) +{ + // Grab the focussed control and stash it away for later use + currentControl = dynamic_cast(event.GetEventObject()); + + // Setup the menu controls according to the control that's selected + // and it's status. + + // Defaults. + editMenu->Enable(MNU_COPY, false); + + // ctlSQLBox? + ctlSQLBox *sb = dynamic_cast(event.GetEventObject()); + if (sb) + { + // Copy + editMenu->Enable(MNU_COPY, !sb->GetSelectedText().IsEmpty()); + } + + // Listview? + ctlListView *lv = dynamic_cast(event.GetEventObject()); + if (lv) + { + // Copy + editMenu->Enable(MNU_COPY, lv->GetSelectedItemCount() > 0); + } +} + +void frmMain::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + +void frmMain::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + +// unfortunately, under GTK we won't get the original wxKeyEvent +// to reset m_metaDown +void frmMain::OnTreeKeyDown(wxTreeEvent &event) +{ + int keyCode = event.GetKeyCode(); + switch (keyCode) + { + case WXK_F1: + OnHelp(event); + break; + case WXK_F5: + Refresh(currentObject); + break; + case WXK_DELETE: + OnDelete(event); + break; + // Is tempting to write all cases(this handler) in tree control itself + case WXK_LEFT: + case WXK_RIGHT: + browser->NavigateTree(keyCode); + break; + default: + event.Skip(); + break; + } +} + +void frmMain::OnExit(wxCommandEvent &event) +{ + Close(false); // Allow sub windows to stop us + event.Skip(); +} + + + +void frmMain::OnClose(wxCloseEvent &event) +{ + wxWindow *fr; + windowList::Node *node; + while ((node = frames.GetFirst()) != NULL) + { + fr = node->GetData(); + + // if crashes occur here when closing the app, + // some actionFactory::StartDialog returned a wxWindow* (which is registered in frames) + // without code to handle OnClose (esp. removing itself with RemoveFrame) + + if (!fr->Close(!event.CanVeto())) + { + if (event.CanVeto()) + { + event.Veto(); + return; + } + } + delete node; + fr->Destroy(); + } + Destroy(); +} + + +void frmMain::UpdateAllRecentFiles() +{ + wxWindow *fr; + windowList::Node *node; + node = frames.GetFirst(); + while (node) + { + fr = node->GetData(); + ((frmQuery *)fr)->UpdateRecentFiles(false); + node = node->GetNext(); + } +} + + +void frmMain::UpdateAllFavouritesList() +{ + wxWindow *fr; + windowList::Node *node; + node = frames.GetFirst(); + while (node) + { + fr = node->GetData(); + ((frmQuery *)fr)->UpdateFavouritesList(); + node = node->GetNext(); + } +} + +void frmMain::UpdateAllMacrosList() +{ + wxWindow *fr; + windowList::Node *node; + node = frames.GetFirst(); + while (node) + { + fr = node->GetData(); + ((frmQuery *)fr)->UpdateMacrosList(); + node = node->GetNext(); + } +} + + +void frmMain::OnAction(wxCommandEvent &ev) +{ + if (currentObject) { + actionFactory *af = menuFactories->GetFactory(ev.GetId()); + if (af) + { + wxWindow *wnd = af->StartDialog(this, currentObject); + if (wnd) + AddFrame(wnd); + } + } +} + +wxString frmMain::GetHelpPage() const +{ + wxString page; + + if (currentObject) + page = currentObject->GetHelpPage(true); + + if (page.IsEmpty()) + page = wxT("pg/sql-commands"); + + return page; +} + +void frmMain::OnCollapse(wxTreeEvent &event) +{ +#ifdef WIN32 + // This is weird stuff, but somewhere comes a collapse after we have done + // connecting the server and expanding the tree. + // Possibly not necessary + if (event.GetItem() == denyCollapseItem) + event.Veto(); +#endif + denyCollapseItem = wxTreeItemId(); +} + + +void frmMain::OnExpand(wxTreeEvent &event) +{ + wxCookieType cookie; + wxTreeItemId item = browser->GetFirstChild(event.GetItem(), cookie); + if (item && !browser->GetItemData(item)) + { + // the expanding node has a dummy item. + // delete dummy item, and expand kids. + execSelChange(event.GetItem(), browser->GetSelection() == item); + + // we don't have any kids, so don't expand + if (!browser->GetChildrenCount(event.GetItem())) + event.Veto(); + } +} + + +void frmMain::OnCheckAlive(wxCommandEvent &event) +{ + CheckAlive(); +} + + + +void frmMain::OnPropSelChanged(wxListEvent &event) +{ + if (properties->GetSelectedItemCount() == 1) + { + wxTreeItemId item = browser->GetSelection(); + if (item) + { + pgObject *data = browser->GetObject(item); + if (data && data->IsCollection()) + { + currentObject = ((pgCollection *)data)->FindChild(browser, event.GetIndex()); + if (currentObject) + { + setDisplay(currentObject); + sqlPane->SetReadOnly(false); + sqlPane->SetText(currentObject->GetSql(browser)); + sqlPane->SetReadOnly(true); + } + } + } + } + + editMenu->Enable(MNU_COPY, properties->GetSelectedItemCount() > 0); + +// The generic list view control on the Mac doesn't fire focus events +// as it should, so we set currentControl here instead of relying on +// the ChildFocusEvent. The native list view does fire the events, but +// does weird things with multi-select items so we currently disable +// it (see the creation of the listviews in frmMain.cpp). +#ifdef __WXMAC__ + currentControl = properties; +#endif +} + + +void frmMain::OnSelectItem(wxListEvent &event) +{ + ctlListView *list; + + switch(listViews->GetSelection()) + { + case NBP_STATISTICS: + list = statistics; + break; + case NBP_DEPENDENCIES: + list = dependencies; + break; + case NBP_DEPENDENTS: + list = dependents; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + + editMenu->Enable(MNU_COPY, list->GetSelectedItemCount() > 0); + +// The generic list view control on the Mac doesn't fire focus events +// as it should, so we set currentControl here instead of relying on +// the ChildFocusEvent. The native list view does fire the events, but +// does weird things with multi-select items so we currently disable +// it (see the creation of the listviews in frmMain.cpp). +#ifdef __WXMAC__ + currentControl = list; +#endif +} + +void frmMain::OnPropSelActivated(wxListEvent &event) +{ + if (propFactory->CheckEnable(currentObject)) + propFactory->StartDialog(this, currentObject); +} + + +void frmMain::OnPropRightClick(wxListEvent &event) +{ + OnPropSelChanged(event); + + if (currentObject) + doPopup(properties, event.GetPoint(), currentObject); +} + + +void frmMain::OnTreeSelChanged(wxTreeEvent &event) +{ + /* + * Do not honour the tree selection change, while a property dialog is + * closed and refresh is in progress + */ + if (m_refreshing) + return; + + denyCollapseItem = wxTreeItemId(); + // Reset the listviews/SQL pane + if (event.GetItem()) + execSelChange(event.GetItem(), true); +} + + +// Reset the list controls +void frmMain::ResetLists() +{ + properties->ClearAll(); + properties->AddColumn(_("Properties"), properties->GetSize().GetWidth() - 10); + properties->InsertItem(0, _("No properties are available for the current selection"), PGICON_PROPERTY); + statistics->ClearAll(); + statistics->AddColumn(_("Statistics"), properties->GetSize().GetWidth() - 10); + statistics->InsertItem(0, _("No statistics are available for the current selection"), PGICON_PROPERTY); + dependencies->ClearAll(); + dependencies->AddColumn(_("Dependencies"), properties->GetSize().GetWidth() - 10); + dependencies->InsertItem(0, _("No dependency information is available for the current selection"), PGICON_PROPERTY); + dependents->ClearAll(); + dependents->AddColumn(_("Dependents"), properties->GetSize().GetWidth() - 10); + dependents->InsertItem(0, _("No dependent information is available for the current selection"), PGICON_PROPERTY); +} + + +void frmMain::execSelChange(wxTreeItemId item, bool currentNode) +{ + static bool refresh = true; + + if (currentNode) + { + ResetLists(); + sqlPane->Clear(); + } + + // Get the item data, and feed it to the relevant handler, + // cast as required. + // + // Lock the assignment to prevent the race conditions between onSelRightClick and execSelChange. + // + s_currentObjectMutex.Lock(); + currentObject = browser->GetObject(item); + s_currentObjectMutex.Unlock(); + + // If we didn't get an object, then we may have a right click, or + // invalid click, so ignore. + if (!currentObject) + { + menuFactories->CheckMenu(currentObject, menuBar, toolBar); + } + else + { + int settingRefreshOnClick = settings->GetRefreshOnClick(); + + if (settingRefreshOnClick != REFRESH_OBJECT_NONE + && refresh + && currentObject->GetTypeName() != wxT("Server") + && currentObject->GetTypeName() != wxT("Servers") + && currentObject->GetTypeName() != wxT("Database") + && !currentObject->IsCollection()) + { + refresh = false; + + if (settingRefreshOnClick == REFRESH_OBJECT_ONLY ) + { + // We can not update the schema, because it would cause an update to the entire tree. + if (currentObject->GetTypeName() != wxT("Schema")) + { + wxTreeItemId currentItem = currentObject->GetId(); + + // Do not refresh and instead bail out if dialog of the currently selected + // node or it's child node is open, as refresh would delete this node's object + // and could cause a crash + pgObject *obj = NULL; + if (currentItem) + obj = browser->GetObject(currentItem); + + if (obj && obj->CheckOpenDialogs(browser, currentItem)) + { + properties->Freeze(); + setDisplay(currentObject, properties, sqlPane); + properties->Thaw(); + refresh = true; + return; + } + + pgObject *newData = currentObject->Refresh(browser, currentItem); + + if (newData != 0) + { + wxLogInfo(wxT("Replacing with new node %s %s for refresh"), newData->GetTypeName().c_str(), newData->GetQuotedFullIdentifier().c_str()); + + browser->DeleteChildren(currentItem); + newData->SetId(currentItem); // not done automatically + browser->SetItemData(currentItem, newData); + + // Update the node text if this is an object, as it may have been renamed + if (!newData->IsCollection()) + browser->SetItemText(currentItem, newData->GetDisplayName()); + + delete currentObject; + currentObject = newData; + } + else + { + // OK, we failed to refresh, so select the parent and delete the child. + browser->SelectItem(browser->GetItemParent(currentItem)); + browser->Delete(currentItem); + } + } + } + else + Refresh(currentObject); + + refresh = true; + } + + + if (currentNode) + { + properties->Freeze(); + setDisplay(currentObject, properties, sqlPane); + properties->Thaw(); + } + else + setDisplay(currentObject, 0, 0); + } +} + + +void frmMain::setDisplay(pgObject *data, ctlListView *props, ctlSQLBox *sqlbox) +{ + pgServer *server = 0; + + + bool showTree = false; + + pgaFactory *factory = data->GetFactory(); + if (factory) + { + if (factory == &serverFactory) + { + server = (pgServer *)data; + + data->ShowTree(this, browser, props, sqlbox); + showTree = false; + } + else + showTree = true; + } + else + showTree = false; + + if (showTree) + data->ShowTree(this, browser, props, sqlbox); + + if (sqlbox) + { + sqlbox->SetReadOnly(false); + sqlbox->SetText(data->GetSql(browser)); + sqlbox->SetReadOnly(true); + } + + pgConn *conn = data->GetConnection(); + if (conn && (conn->GetStatus() == PGCONN_BROKEN || conn->GetStatus() == PGCONN_BAD)) + { + CheckAlive(); + return; + } + + unsigned int i; + wxMenuItem *menuItem; + i = newMenu->GetMenuItemCount(); + while (i--) + { + menuItem = newMenu->GetMenuItems().Item(i)->GetData(); + if (menuItem) + delete newMenu->Remove(menuItem); + } + + i = newContextMenu->GetMenuItemCount(); + while (i--) + { + menuItem = newContextMenu->GetMenuItems().Item(i)->GetData(); + if (menuItem) + delete newContextMenu->Remove(menuItem); + } + + editMenu->Enable(newMenuFactory->GetId(), false); + + wxMenu *indivMenu = data->GetNewMenu(); + if (indivMenu) + { + if (indivMenu->GetMenuItemCount()) + { + editMenu->Enable(newMenuFactory->GetId(), true); + + for (i = 0 ; i < indivMenu->GetMenuItemCount() ; i++) + { + menuItem = indivMenu->GetMenuItems().Item(i)->GetData(); +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + + newMenu->Append(menuItem->GetId(), lab, menuItem->GetHelp()); + newContextMenu->Append(menuItem->GetId(), lab, menuItem->GetHelp()); + } + } + delete indivMenu; + } + + menuFactories->CheckMenu(data, menuBar, toolBar); + + menuFactories->EnableSubmenu(menuBar, MNU_CONFIGSUBMENU); + menuFactories->EnableSubmenu(menuBar, MNU_SLONY_SUBMENU); +} + + +void frmMain::OnSelActivated(wxTreeEvent &event) +{ + // This handler will primarily deal with displaying item + // properties in seperate windows and 'Add xxx...' clicks + + // Get the item data, and feed it to the relevant handler, + // cast as required. + + wxTreeItemId item = event.GetItem(); + pgObject *data = browser->GetObject(item); + if (!data) + return; + pgServer *server; + wxCommandEvent nullEvent; + + if (data->IsCreatedBy(serverFactory)) + { + server = (pgServer *)data; + if (!server->GetConnected()) + { + if (ReconnectServer(server) == PGCONN_OK) + { + // prevent from being collapsed immediately + + denyCollapseItem = item; + } + } + } + else + { + if (settings->GetDoubleClickProperties() && propFactory->CheckEnable(data)) + { + propFactory->StartDialog(this, data); + event.Skip(); + return; + } + } + + browser->Expand(item); +} + +void frmMain::doPopup(wxWindow *win, wxPoint point, pgObject *object) +{ + if (treeContextMenu) + delete treeContextMenu; + + treeContextMenu = new wxMenu(); + + menuFactories->AppendEnabledMenus(menuBar, treeContextMenu); + + wxMenuItem *newItem = treeContextMenu->FindItem(newMenuFactory->GetId()); + + if (newItem) + { + size_t newItemPos; + + wxMenuItemList mil = treeContextMenu->GetMenuItems(); + for (newItemPos = 0 ; newItemPos < mil.GetCount() ; newItemPos++) + { + if (mil.Item(newItemPos)->GetData()->GetId() == newItem->GetId()) + break; + } + + if (object) + { + wxMenu *indivMenu = object->GetNewMenu(); + if (indivMenu) + { + + if (indivMenu->GetMenuItemCount() > 1) + { + wxMenuItem *menuItem = menuBar->FindItem(newMenuFactory->GetId()); +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + + treeContextMenu->Insert(newItemPos, newMenuFactory->GetId(), lab, indivMenu, menuItem->GetHelp()); + } + else + { + if (indivMenu->GetMenuItemCount() == 1) + { + wxMenuItem *menuItem = indivMenu->GetMenuItems().Item(0)->GetData(); +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + treeContextMenu->Insert(newItemPos, menuItem->GetId(), lab, menuItem->GetHelp()); + } + delete indivMenu; + } + } + } + treeContextMenu->Remove(newItem); + delete newItem; + } + + if (treeContextMenu->GetMenuItemCount()) + win->PopupMenu(treeContextMenu, point); +} + +//////////////////////////////////////////////////////////////////////////////// +// This handler will display a popup menu for the currently selected item +//////////////////////////////////////////////////////////////////////////////// +void frmMain::OnContextMenu(wxCommandEvent &event) +{ + wxPoint point; + + if (FindFocus() == browser) + { + wxRect rect; + wxTreeItemId item = browser->GetSelection(); + + browser->GetBoundingRect(item, rect); + point = rect.GetPosition(); + wxPoint origin = GetClientAreaOrigin(); + + // Because this Tree is inside a vertical splitter, we + // must compensate for the size of the other elements + point.x += origin.x; + point.y += origin.y; + + doPopup(this, point, browser->GetObject(item)); + } + +} + + +//////////////////////////////////////////////////////////////////////////////// +// This handler will display a popup menu for the item at the mouse position +//////////////////////////////////////////////////////////////////////////////// +void frmMain::OnSelRightClick(wxTreeEvent &event) +{ + wxTreeItemId item = event.GetItem(); + if (item != browser->GetSelection()) + { + browser->SelectItem(item); + + // Prevent changes to "currentObject" by "execSelchange" function by another + // thread. Will hold the lock until we have the actual object in hand. + s_currentObjectMutex.Lock(); + currentObject = browser->GetObject(item); + s_currentObjectMutex.Unlock(); + } + + if (currentObject) + doPopup(browser, event.GetPoint(), currentObject); +} + + +void frmMain::OnDelete(wxCommandEvent &ev) +{ + if (currentObject->CanDrop()) + ExecDrop(false); +} + + +void frmMain::ExecDrop(bool cascaded) +{ + wxTreeItemId item = browser->GetSelection(); + pgCollection *collection = (pgCollection *)browser->GetObject(item); + + // Get any table object for later update + wxTreeItemId owneritem; + pgObject *node = (pgObject *)browser->GetObject(item); + + int metatype = node->GetMetaType(); + + switch (metatype) + { + case PGM_COLUMN: + owneritem = node->GetTable()->GetId(); + break; + + case PGM_CHECK: + case PGM_CONSTRAINT: + case PGM_EXCLUDE: + case PGM_FOREIGNKEY: + case PGM_INDEX: + case PGM_PRIMARYKEY: + case PGM_UNIQUE: + case PGM_TRIGGER: + case PGM_RULE: // Rules are technically table objects! Yeuch + case EDB_PACKAGEFUNCTION: + case EDB_PACKAGEVARIABLE: + case PGM_SCHEDULE: + case PGM_STEP: + if (node->IsCollection()) + owneritem = browser->GetParentObject(node->GetId())->GetId(); + else + owneritem = browser->GetParentObject(browser->GetParentObject(node->GetId())->GetId())->GetId(); + break; + + default: + break; + } + + // Grab the parent item to re-focus on. + wxString parent = GetNodePath(item).BeforeLast('/'); + + bool success = false; + if (collection == currentObject) + success = dropSingleObject(currentObject, true, cascaded); + else + { + if (collection && collection->IsCollection()) + { + long index = properties->GetFirstSelected(); + + if (index >= 0) + { + pgObject *data = collection->FindChild(browser, index); + + if (!data || !data->CanDrop()) + return; + + if (properties->GetSelectedItemCount() == 1) + { + success = dropSingleObject(data, true, cascaded); + } + else + { + if (cascaded || data->RequireDropConfirm() || settings->GetConfirmDelete()) + { + wxString text, caption; + if (cascaded) + { + text = _("Are you sure you wish to drop multiple objects including all objects that depend on them?"); + caption = _("Drop multiple objects cascaded?"); + } + else + { + text = _("Are you sure you wish to drop multiple objects?"); + caption = _("Drop multiple objects?"); + } + wxMessageDialog msg(this, text, caption, wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT); + if (msg.ShowModal() != wxID_YES) + { + return; + } + } + + bool done = true; + long count = 0; + while (done && data && index >= 0) + { + if (data->GetSystemObject()) + { + wxMessageDialog msg(this, + data->GetTranslatedMessage(CANNOTDROPSYSTEM), + _("Trying to drop system object"), wxICON_EXCLAMATION); + msg.ShowModal(); + return; + } + + done = dropSingleObject(data, false, cascaded); + + if (done) + { + properties->DeleteItem(index); + count++; + index = properties->GetFirstSelected(); + + if (index >= 0) + data = collection->FindChild(browser, index); + + success = true; + } + } + } + } + } + } + + if (success) + { + // If the collection has a table, refresh that as well. + if (owneritem) + { + ObjectBrowserRefreshing(true); + Refresh(browser->GetObject(owneritem)); + ObjectBrowserRefreshing(false); + } + + // Now re-focus on the parent of the deleted node + if (!parent.IsEmpty()) + SetCurrentNode(browser->GetRootItem(), parent); + } +} + + +bool frmMain::dropSingleObject(pgObject *data, bool updateFinal, bool cascaded) +{ + if (updateFinal) + { + // accelerator can bypass disabled menu, so we need to check + if (!data || !data->CanDrop()) + return false; + + if (data->CheckOpenDialogs(browser, browser->GetSelection())) + { + wxString msg = _("There are properties dialogues open for one or more objects that would be dropped. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot drop object"), wxICON_WARNING | wxOK); + return false; + } + + if (data->GetSystemObject()) + { + wxMessageDialog msg(this, data->GetTranslatedMessage(CANNOTDROPSYSTEM), + _("Trying to drop system object"), wxICON_EXCLAMATION); + msg.ShowModal(); + return false; + } + + if (cascaded || data->RequireDropConfirm() || settings->GetConfirmDelete()) + { + wxString text, caption; + if (cascaded) + { + text = data->GetTranslatedMessage(DROPINCLUDINGDEPS); + caption = data->GetTranslatedMessage(DROPCASCADETITLE); + } + else + { + /* + * currentObject is set using the following command. + * i.e. currentObject = browser->GetObject(item); + * While fetching this object using this code, somehow it looses its virtual table pointer. + * Hence, it is not able to call the GetFullIdentifier - virtual function from the + * particular class, but it will always call this functions from pgObject class always. + * To rectify this problem, we need to explicitly check the meta data type and call the + * function from the particular class. + */ + if (data->GetMetaType() == PGM_SERVER) + text = wxString::Format(_("Are you sure you wish to drop server \"%s\"?"), + ((pgServer *)data)->GetFullIdentifier().c_str()); + else if (data->GetMetaType() == EDB_SYNONYM) + text = ((edbPrivateSynonym *)data)->GetTranslatedMessage(DROPEXCLUDINGDEPS); + else + text = data->GetTranslatedMessage(DROPEXCLUDINGDEPS); + caption = data->GetTranslatedMessage(DROPTITLE); + } + wxMessageDialog msg(this, text, caption, wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT); + if (msg.ShowModal() != wxID_YES) + { + return false; + } + } + } + bool done = data->DropObject(this, browser, cascaded); + + if (done) + { + wxLogInfo(wxT("Dropping %s %s"), data->GetTypeName().c_str(), data->GetIdentifier().c_str()); + + wxTreeItemId parentItem = browser->GetItemParent(data->GetId()); + + if (updateFinal) + { + wxTreeItemId nextItem; + if (browser->IsVisible(data->GetId())) + nextItem = browser->GetNextVisible(data->GetId()); + + if (nextItem) + { + pgObject *nextData = browser->GetObject(nextItem); + if (!nextData || nextData->GetType() != data->GetType()) + nextItem = browser->GetPrevSibling(data->GetId()); + } + else + nextItem = browser->GetPrevSibling(data->GetId()); + + if (nextItem) + browser->SelectItem(nextItem); + } + pgaFactory *droppedCollFactory = data->GetFactory()->GetCollectionFactory(); + + wxTreeItemId oldgroupitem; + wxString oldgroupname; + if (data->IsCreatedBy(serverFactory)) + { + oldgroupname = ((pgServer *)data)->GetGroup(); + oldgroupitem = browser->GetItemParent(data->GetId()); + } + + browser->Delete(data->GetId()); + // data is invalid now + + if (updateFinal) + { + if (!oldgroupname.IsEmpty()) + { + int total = browser->GetChildrenCount(oldgroupitem, false); + if (total == 0) + browser->Delete(oldgroupitem); + else + { + wxString label = oldgroupname + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(oldgroupitem, label); + } + } + else + { + pgCollection *collection = 0; + + while (parentItem) + { + collection = (pgCollection *)browser->GetObject(parentItem); + if (collection && collection->IsCollection() && collection->GetFactory() == droppedCollFactory) + { + collection->UpdateChildCount(browser); + break; + } + parentItem = browser->GetItemParent(parentItem); + } + } + } + + // Update the server list, if we dropped a server + StoreServers(); + } + return done; +} + + +void frmMain::OnNew(wxCommandEvent &ev) +{ + pgaFactory *factory = pgaFactory::GetFactory(ev.GetId() - MNU_NEW); + + if (factory == &serverFactory) + { + if (currentObject && currentObject->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)currentObject; + if (!server->GetConnected()) + ReconnectServer(server); + } + return; + } + + if (currentObject) + { + if (!dlgProperty::CreateObjectDialog(this, currentObject, factory)) + CheckAlive(); + } +} + + +void frmMain::OnSaveDefinition(wxCommandEvent &event) +{ + + wxLogInfo(wxT("Saving object definition")); + + if (sqlPane->GetText().IsNull()) + { + wxLogError(__("There is nothing in the SQL pane to save!")); + return; + } + + wxString file; + settings->Read(wxT("frmMain/LastFile"), &file, wxEmptyString); + +#ifdef __WXMSW__ + wxFileDialog filename(this, _("Select output file"), ::wxPathOnly(file), file, _("SQL Scripts (*.sql)|*.sql|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog filename(this, _("Select output file"), ::wxPathOnly(file), file, _("SQL Scripts (*.sql)|*.sql|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + // Show the dialogue + if (filename.ShowModal() == wxID_OK) + { + // Write the file + if (!FileWrite(filename.GetPath(), sqlPane->GetText())) + { + wxLogError(__("Could not write the file %s: Errcode=%d."), filename.GetPath().c_str(), wxSysErrorCode()); + } + } + else + { + wxLogInfo(wxT("User cancelled")); + } + + settings->Write(wxT("frmMain/LastFile"), filename.GetPath()); +} + +void frmMain::OnToggleSqlPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_SQLPANE)) + manager.GetPane(wxT("sqlPane")).Show(true); + else + manager.GetPane(wxT("sqlPane")).Show(false); + manager.Update(); +} + +void frmMain::OnToggleObjectBrowser(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_OBJECTBROWSER)) + manager.GetPane(wxT("objectBrowser")).Show(true); + else + manager.GetPane(wxT("objectBrowser")).Show(false); + manager.Update(); +} + +void frmMain::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + manager.GetPane(wxT("toolBar")).Show(true); + else + manager.GetPane(wxT("toolBar")).Show(false); + manager.Update(); +} + +void frmMain::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("objectBrowser")) + { + viewMenu->Check(MNU_OBJECTBROWSER, false); + } + else if(event.pane->name == wxT("sqlPane")) + { + viewMenu->Check(MNU_SQLPANE, false); + } + else if(event.pane->name == wxT("toolBar")) + { + viewMenu->Check(MNU_TOOLBAR, false); + } + event.Skip(); +} + +void frmMain::OnAuiNotebookPageClose(wxAuiNotebookEvent &event) +{ + // Prevent the user closing the four main tabs. + if (event.GetSelection() < 4) + { + wxMessageBox(_("This tab cannot be closed."), _("Close tab"), wxICON_INFORMATION | wxOK); + event.Veto(); + return; + } + + event.Skip(); +} + +void frmMain::OnDefaultView(wxCommandEvent &event) +{ + manager.LoadPerspective(FRMMAIN_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("objectBrowser")).Caption(_("Object browser")); + manager.GetPane(wxT("listViews")).Caption(_("Info pane")); + manager.GetPane(wxT("sqlPane")).Caption(_("SQL pane")); + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_SQLPANE, manager.GetPane(wxT("sqlPane")).IsShown()); + viewMenu->Check(MNU_OBJECTBROWSER, manager.GetPane(wxT("objectBrowser")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); +} + +void frmMain::OnPositionStc(wxStyledTextEvent &event) +{ + if (sqlPane->GetSelectedText().IsNull()) + editMenu->Enable(MNU_COPY, false); + else + editMenu->Enable(MNU_COPY, true); +} diff --git a/frm/frmAbout.cpp b/frm/frmAbout.cpp new file mode 100644 index 0000000..0e88b6a --- /dev/null +++ b/frm/frmAbout.cpp @@ -0,0 +1,108 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmAbout.cpp - About Box +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmAbout.h" + +// Copyright text +#include "copyright.h" +#include "version.h" +#include "svnversion.h" + +#define VERSION_WITH_DATE_AND_SVN wxT("Version ") VERSION_STR wxT(" (") __TDATE__ wxT(", rev: ") wxT(VERSION_SVN) wxT(")") + + +BEGIN_EVENT_TABLE(frmAbout, wxFrame) + EVT_PAINT(frmAbout::OnPaint) + + EVT_KEY_UP(frmAbout::OnKeyUp) + EVT_LEFT_DOWN(frmAbout::OnLeftDown) +#ifdef __WXGTK__ + EVT_WINDOW_CREATE(frmAbout::OnWindowCreate) +#endif +END_EVENT_TABLE() + +frmAbout::frmAbout(wxFrame *parent) + : wxFrame(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(100, 100), 0 | wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP) +{ + appearanceFactory->SetIcons(this); + about = appearanceFactory->GetSplashImage(); + + SetClientSize(about.GetWidth(), about.GetHeight()); + +#ifndef __WXGTK__ + SetWindowShape(); +#endif + + CenterOnParent(); +} + +void frmAbout::OnLeftDown(wxMouseEvent &WXUNUSED(evt)) +{ + this->Close(); +} + +void frmAbout::OnKeyUp(wxKeyEvent &evt) +{ + if (evt.GetKeyCode() == WXK_ESCAPE) + this->Close(); +} + + +void frmAbout::SetWindowShape() +{ + wxRegion region(about); + SetShape(region); +} + +void frmAbout::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ + wxPoint pos = appearanceFactory->GetSplashTextPos(); + + wxPaintDC dc(this); + dc.DrawBitmap(about, 0, 0, true); + dc.SetTextForeground(appearanceFactory->GetSplashTextColour()); + dc.SetFont(appearanceFactory->GetSplashTextFont()); + + if (appearanceFactory->IsBranded()) + { + dc.DrawText(_("This program is based on pgAdmin III"), pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + } + dc.DrawText(VERSION_WITH_DATE_AND_SVN, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(COPYRIGHT, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(LICENSE, pos); +} + +void frmAbout::OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)) +{ + SetWindowShape(); +} + +aboutFactory::aboutFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&About"), _("Show about dialog.")); +} + + +wxWindow *aboutFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmAbout *frm = new frmAbout((wxFrame *)form); + frm->Show(); + return 0; +} diff --git a/frm/frmBackup.cpp b/frm/frmBackup.cpp new file mode 100644 index 0000000..ca946f3 --- /dev/null +++ b/frm/frmBackup.cpp @@ -0,0 +1,636 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackup.cpp - Backup database dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "frm/frmBackup.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "ctl/ctlCheckTreeView.h" + +// Icons +#include "images/backup.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define txtCompressRatio CTRL_TEXT("txtCompressRatio") +#define cbEncoding CTRL_COMBOBOX("cbEncoding") +#define cbFormat CTRL_COMBOBOX("cbFormat") +#define txtNumberOfJobs CTRL_TEXT("txtNumberOfJobs") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkBlobs CTRL_CHECKBOX("chkBlobs") +#define chkOid CTRL_CHECKBOX("chkOid") +#define chkInsert CTRL_CHECKBOX("chkInsert") +#define chkDisableDollar CTRL_CHECKBOX("chkDisableDollar") +#define chkOnlyData CTRL_CHECKBOX("chkOnlyData") +#define chkOnlySchema CTRL_CHECKBOX("chkOnlySchema") +#define chkNoOwner CTRL_CHECKBOX("chkNoOwner") +#define chkCreateDb CTRL_CHECKBOX("chkCreateDb") +#define chkDropDb CTRL_CHECKBOX("chkDropDb") +#define chkDisableTrigger CTRL_CHECKBOX("chkDisableTrigger") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkColumnInserts CTRL_CHECKBOX("chkColumnInserts") +#define chkNoPrivileges CTRL_CHECKBOX("chkNoPrivileges") +#define chkNoTablespaces CTRL_CHECKBOX("chkNoTablespaces") +#define chkUseSetSession CTRL_CHECKBOX("chkUseSetSession") +#define chkForceQuoteForIdent CTRL_CHECKBOX("chkForceQuoteForIdent") +#define ctvObjects CTRL_CHECKTREEVIEW("ctvObjects") +#define chkNoUnloggedTableData CTRL_CHECKBOX("chkNoUnloggedTableData") +#define chkSectionPreData CTRL_CHECKBOX("chkSectionPreData") +#define chkSectionData CTRL_CHECKBOX("chkSectionData") +#define chkSectionPostData CTRL_CHECKBOX("chkSectionPostData") + + +BEGIN_EVENT_TABLE(frmBackup, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmBackup::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmBackup::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmBackup::OnOK) + EVT_COMBOBOX(XRCID("cbFormat"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkOnlyData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkOnlySchema"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkNoUnloggedTableData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkSectionPreData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkSectionData"), frmBackup::OnChangePlain) + EVT_CHECKBOX(XRCID("chkSectionPostData"), frmBackup::OnChangePlain) + EVT_CLOSE( ExternProcessDialog::OnClose) +END_EVENT_TABLE() + + + +frmBackup::frmBackup(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmBackup")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(BACKUPTITLE)); + + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupExecutable; + else + backupExecutable = pgBackupExecutable; + + canBlob = (obj->GetMetaType() == PGM_DATABASE); + chkBlobs->SetValue(canBlob); + chkDisableDollar->Enable(obj->GetConnection()->BackendMinimumVersion(7, 5)); + + wxString val; + settings->Read(wxT("frmBackup/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + pgServer *server = object->GetServer(); + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + object->GetServer()->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + if (server->GetSSLRootCert() != wxEmptyString) + environment.Add(wxT("PGSSLROOTCERT=") + server->GetSSLRootCert()); + + if (server->GetSSLCert() != wxEmptyString) + environment.Add(wxT("PGSSLCERT=") + server->GetSSLCert()); + + if (server->GetSSLKey() != wxEmptyString) + environment.Add(wxT("PGSSLKEY=") + server->GetSSLKey()); + + if (server->GetSSLCrl() != wxEmptyString) + environment.Add(wxT("PGSSLCRL=") + server->GetSSLCrl()); + + // Icon + SetIcon(*backup_png_ico); + + // fix translation problem + wxString dollarLabel = wxGetTranslation(_("$$ quoting")); + dollarLabel.Replace(wxT("$$"), wxT("$")); + chkDisableDollar->SetLabel(dollarLabel); + chkDisableDollar->SetSize(chkDisableDollar->GetBestSize()); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + + long encNo = 0; + wxString encStr; + cbEncoding->Append(wxT("")); + do + { + encStr = object->GetConnection()->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (pgConn::IsValidServerEncoding(encNo) && !encStr.IsEmpty()) + cbEncoding->Append(encStr); + + encNo++; + } + while (!encStr.IsEmpty()); + + cbEncoding->SetSelection(0); + + wxString i18ndb = _("Database"); + wxTreeItemId db = ctvObjects->AddRoot(i18ndb + wxT(" ") + object->GetDatabase()->GetName(), 1); + bool checked; + + wxString query = wxT("SELECT nspname, relname ") + wxT("FROM pg_namespace n ") + wxT("LEFT JOIN pg_class c ON n.oid=c.relnamespace AND relkind='r' ") + wxT("WHERE nspname NOT LIKE E'pg\\\\_%' AND nspname <> 'information_schema' "); + if (!object->GetDatabase()->GetSchemaRestriction().IsEmpty()) + query += wxT("AND nspname IN (") + object->GetDatabase()->GetSchemaRestriction() + wxT(")"); + query += wxT("ORDER BY nspname, relname"); + + pgSet *objects = object->GetDatabase()->ExecuteSet(query); + + if (objects) + { + wxString currentSchema = wxT(""); + wxTreeItemId currentSchemaNode; + while (!objects->Eof()) + { + if (currentSchema != objects->GetVal(wxT("nspname"))) + { + currentSchema = objects->GetVal(wxT("nspname")); + if (object->GetMetaType() == PGM_SCHEMA) + { + checked = ((pgSchema *)object)->GetIdentifier() == currentSchema; + } + else + { + if (object->GetMetaType() == PGM_TABLE || object->GetMetaType() == GP_PARTITION) + { + checked = ((pgTable *)object)->GetSchema()->GetIdentifier() == currentSchema + || (object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION); + } + else + { + checked = object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION; + } + } + currentSchemaNode = ctvObjects->AppendItem(db, currentSchema, checked ? 1 : 0); + } + if (!objects->GetVal(wxT("relname")).IsNull()) + { + if (object->GetMetaType() == PGM_TABLE || object->GetMetaType() == GP_PARTITION) + { + checked = ((pgTable *)object)->GetSchema()->GetIdentifier() == currentSchema + && ((pgTable *)object)->GetIdentifier() == objects->GetVal(wxT("relname")); + } + else + { + if (object->GetMetaType() == PGM_SCHEMA) + { + checked = ((pgSchema *)object)->GetIdentifier() == currentSchema; + } + else + { + if (object->GetMetaType() == PGM_TABLE || object->GetMetaType() == GP_PARTITION) + { + checked = ((pgTable *)object)->GetSchema()->GetIdentifier() == currentSchema + || (object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION); + } + else + { + checked = object->GetMetaType() != PGM_TABLE && object->GetMetaType() != GP_PARTITION; + } + } + } + ctvObjects->AppendItem(currentSchemaNode, objects->GetVal(wxT("relname")), checked ? 1 : 0); + } + objects->MoveNext(); + } + ctvObjects->ExpandAll(); + + delete objects; + } + + if (!pgAppMinimumVersion(backupExecutable, 9, 3)) + { + txtNumberOfJobs->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 9, 2)) + { + chkSectionPreData->Disable(); + chkSectionData->Disable(); + chkSectionPostData->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 9, 1)) + { + chkForceQuoteForIdent->Disable(); + chkNoUnloggedTableData->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 8, 4)) + { + chkNoTablespaces->Disable(); + cbRolename->Disable(); + } + else + { + // Available rolenames + if (object->GetServer()->GetConnection()->BackendMinimumVersion(8, 1)) + { + pgSetIterator set(object->GetServer()->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(object->GetServer()->GetRolename()); + cbRolename->Enable(true); + } + else + cbRolename->Disable(); + } + if (!pgAppMinimumVersion(backupExecutable, 8, 1)) + { + cbEncoding->Disable(); + } + + cbFormat->Append(_("Custom")); + cbFormat->Append(_("Tar")); + cbFormat->Append(_("Plain")); + cbFormat->SetSelection(0); + + if (pgAppMinimumVersion(backupExecutable, 9, 1)) + cbFormat->Append(_("Directory")); + + wxCommandEvent ev; + OnChangePlain(ev); +} + + +frmBackup::~frmBackup() +{ + SavePosition(); +} + + +wxString frmBackup::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pgdump"); + return page; +} + + +void frmBackup::OnSelectFilename(wxCommandEvent &ev) +{ + wxString title, prompt, FilenameOnly; + + if (cbFormat->GetSelection() == 2) // plain + { + title = _("Select output file"); +#ifdef __WXMSW__ + prompt = _("Query files (*.sql)|*.sql|All files (*.*)|*.*"); +#else + prompt = _("Query files (*.sql)|*.sql|All files (*)|*"); +#endif + } + else + { + title = _("Select backup filename"); +#ifdef __WXMSW__ + prompt = _("Backup files (*.backup)|*.backup|All files (*.*)|*.*"); +#else + prompt = _("Backup files (*.backup)|*.backup|All files (*)|*"); +#endif + } + + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + wxFileDialog file(this, title, ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, prompt, wxFD_SAVE); + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} + + +void frmBackup::OnChange(wxCommandEvent &ev) +{ + if (!process && !done) + btnOK->Enable(!txtFilename->GetValue().IsEmpty()); +} + + +void frmBackup::OnChangePlain(wxCommandEvent &ev) +{ + bool isDirectory = (cbFormat->GetSelection() == 3); + bool isSection = chkSectionPreData->GetValue() || chkSectionData->GetValue() || chkSectionPostData->GetValue(); + + chkOnlyData->Enable(!chkOnlySchema->GetValue() && !isSection); + chkOnlySchema->Enable(!chkOnlyData->GetValue() && !isSection); + + chkSectionPreData->Enable(!chkOnlyData->GetValue() && !chkOnlySchema->GetValue()); + chkSectionData->Enable(!chkOnlyData->GetValue() && !chkOnlySchema->GetValue()); + chkSectionPostData->Enable(!chkOnlyData->GetValue() && !chkOnlySchema->GetValue()); + + chkDisableTrigger->Enable(chkOnlyData->GetValue()); + + btnFilename->Enable(!isDirectory); + + txtNumberOfJobs->Enable(isDirectory && pgAppMinimumVersion(backupExecutable, 9, 3)); + if (!txtNumberOfJobs->IsEnabled()) + txtNumberOfJobs->SetValue(wxEmptyString); + + wxCommandEvent nullEvent; + OnChange(nullEvent); +} + + +wxString frmBackup::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackup::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackup::getCmdPart1() +{ + pgServer *server = object->GetDatabase()->GetServer(); + + wxString cmd = backupExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(backupExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + if (object->GetConnection()->GetIsGreenplum()) + cmd += wxT(" --gp-syntax "); + return cmd; +} + + +wxString frmBackup::getCmdPart2() +{ + wxString cmd; + + switch (cbFormat->GetSelection()) + { + case 0: // compressed + { + cmd.Append(wxT(" --format custom")); + if (chkBlobs->GetValue()) + cmd.Append(wxT(" --blobs")); + if (!txtCompressRatio->GetValue().IsEmpty()) + cmd.Append(wxT(" --compress ") + txtCompressRatio->GetValue()); + break; + } + case 1: // tar + { + cmd.Append(wxT(" --format tar")); + if (chkBlobs->GetValue()) + cmd.Append(wxT(" --blobs")); + break; + } + case 2: // plain + { + cmd.Append(wxT(" --format plain")); + if (chkOnlyData->GetValue()) + { + cmd.Append(wxT(" --data-only")); + if (chkDisableTrigger->GetValue()) + cmd.Append(wxT(" --disable-triggers")); + } + else + { + if (chkOnlySchema->GetValue()) + cmd.Append(wxT(" --schema-only")); + if (chkNoOwner->GetValue()) + cmd.Append(wxT(" --no-owner")); + if (chkCreateDb->GetValue()) + cmd.Append(wxT(" --create")); + if (chkDropDb->GetValue()) + cmd.Append(wxT(" --clean")); + } + break; + } + case 3: // directory + { + cmd.Append(wxT(" --format directory")); + break; + } + } + + // Section + if (pgAppMinimumVersion(backupExecutable, 9, 2)) + { + if (chkSectionPreData->GetValue()) + cmd.Append(wxT(" --section pre-data")); + if (chkSectionData->GetValue()) + cmd.Append(wxT(" --section data")); + if (chkSectionPostData->GetValue()) + cmd.Append(wxT(" --section post-data")); + } + + if (!cbEncoding->GetValue().IsEmpty()) + cmd.Append(wxT(" --encoding ") + cbEncoding->GetValue()); + if (chkOid->GetValue()) + cmd.Append(wxT(" --oids")); + if (chkInsert->GetValue()) + cmd.Append(wxT(" --inserts")); + if (chkColumnInserts->GetValue()) + cmd.Append(wxT(" --column-inserts")); + if (chkNoPrivileges->GetValue()) + cmd.Append(wxT(" --no-privileges")); + if (chkNoTablespaces->GetValue()) + cmd.Append(wxT(" --no-tablespaces")); + if (chkUseSetSession->GetValue()) + cmd.Append(wxT(" --use-set-session-authorization")); + if (chkDisableDollar->GetValue()) + cmd.Append(wxT(" --disable-dollar-quoting")); + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + if (chkForceQuoteForIdent->GetValue()) + cmd.Append(wxT(" --quote-all-identifiers")); + if (chkNoUnloggedTableData->GetValue()) + cmd.Append(wxT(" --no-unlogged-table-data")); + + cmd.Append(wxT(" --file \"") + txtFilename->GetValue() + wxT("\"")); + + if (!txtNumberOfJobs->GetValue().IsEmpty()) + cmd.Append(wxT(" --jobs ") + txtNumberOfJobs->GetValue()); + + // Process selected items + wxTreeItemId root, schema, table; + wxTreeItemIdValue schemaData, tableData; + wxString cmdSchemas, cmdTables, tmpTables; + bool partialDump; + bool partialSchema; + + root = ctvObjects->GetRootItem(); + schema = ctvObjects->GetFirstChild(root, schemaData); + cmdSchemas = wxT(""); + cmdTables = wxT(""); + partialDump = false; + while (schema.IsOk()) + { + if (ctvObjects->IsChecked(schema)) + { + partialSchema = false; + tmpTables = wxT(""); + table = ctvObjects->GetFirstChild(schema, tableData); + while (table.IsOk()) + { + if (ctvObjects->IsChecked(table)) + { + // The syntax changed in 8.2 :-( + if (pgAppMinimumVersion(backupExecutable, 8, 2)) + { + tmpTables.Append(wxT(" --table \"") + + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(schema)), true) + + wxT(".") + + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(table)), true) + + wxT("\"")); + } + else + { + tmpTables.Append(wxT(" --table \"") + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(table)), true) + wxT("\"")); + tmpTables.Append(wxT(" --schema \"") + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(schema)), true) + wxT("\"")); + } + } + else + { + partialDump = true; + partialSchema = true; + } + table = ctvObjects->GetNextChild(schema, tableData); + } + + if (partialSchema) + { + cmdTables += tmpTables; + } + else + { + cmdSchemas.Append(wxT(" --schema \"") + commandLineCleanOption(qtIdent(ctvObjects->GetItemText(schema)), true) + wxT("\"")); + } + } + else + { + partialDump = true; + } + + schema = ctvObjects->GetNextChild(root, schemaData); + } + + if (partialDump) + { + if (!cmdTables.IsEmpty()) + cmd.Append(cmdTables); + if (!cmdSchemas.IsEmpty()) + cmd.Append(cmdSchemas); + } + + cmd.Append(wxT(" ") + commandLineCleanOption(object->GetDatabase()->GetQuotedIdentifier())); + + return cmd; +} + + +void frmBackup::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + +void frmBackup::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a backup to this file again?"), _("Repeat backup?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + else if (wxFile::Exists(txtFilename->GetValue())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), txtFilename->GetValue().c_str()); + if (wxMessageBox(msg, _("Overwrite file?"), wxICON_WARNING | wxYES_NO) != wxYES) + return; + } + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmBackup/LastFile"), txtFilename->GetValue()); + ExternProcessDialog::OnOK(ev); +} + +backupFactory::backupFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Backup..."), _("Creates a backup of the current database to a local file")); +} + + +wxWindow *backupFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmBackup *frm = new frmBackup(form, obj); + frm->Go(); + return 0; +} + + +bool backupFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) + return obj->CanBackup() && !edbBackupExecutable.IsEmpty(); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanBackup() && !gpBackupExecutable.IsEmpty(); + else + return obj->CanBackup() && !pgBackupExecutable.IsEmpty(); + +} + + diff --git a/frm/frmBackupGlobals.cpp b/frm/frmBackupGlobals.cpp new file mode 100644 index 0000000..38e9a33 --- /dev/null +++ b/frm/frmBackupGlobals.cpp @@ -0,0 +1,295 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupGlobals.cpp - Backup globals dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "frm/frmBackupGlobals.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" + +// Icons +#include "images/backup.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkForceQuoteForIdent CTRL_CHECKBOX("chkForceQuoteForIdent") + + +BEGIN_EVENT_TABLE(frmBackupGlobals, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmBackupGlobals::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmBackupGlobals::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmBackupGlobals::OnOK) + EVT_CLOSE( ExternProcessDialog::OnClose) +END_EVENT_TABLE() + + + +frmBackupGlobals::frmBackupGlobals(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmBackupGlobals")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(BACKUPGLOBALS)); + + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupAllExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupAllExecutable; + else + backupExecutable = pgBackupAllExecutable; + + wxString val; + settings->Read(wxT("frmBackupGlobals/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + pgServer *server; + if (object->GetMetaType() == PGM_SERVER) + server = (pgServer *)object; + else + server = object->GetDatabase()->GetServer(); + + bool roles_supported = pgAppMinimumVersion(backupExecutable, 8, 4) && server->GetConnection()->BackendMinimumVersion(8, 1); + cbRolename->Enable(roles_supported); + + if (roles_supported) + { + // Collect the available rolenames + pgSetIterator set(server->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(server->GetRolename()); + } + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + server->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + if (server->GetSSLRootCert() != wxEmptyString) + environment.Add(wxT("PGSSLROOTCERT=") + server->GetSSLRootCert()); + + if (server->GetSSLCert() != wxEmptyString) + environment.Add(wxT("PGSSLCERT=") + server->GetSSLCert()); + + if (server->GetSSLKey() != wxEmptyString) + environment.Add(wxT("PGSSLKEY=") + server->GetSSLKey()); + + if (server->GetSSLCrl() != wxEmptyString) + environment.Add(wxT("PGSSLCRL=") + server->GetSSLCrl()); + + // Icon + SetIcon(*backup_png_ico); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + + if (!pgAppMinimumVersion(backupExecutable, 9, 1)) + { + chkForceQuoteForIdent->Disable(); + } + + wxCommandEvent ev; + OnChange(ev); +} + + +frmBackupGlobals::~frmBackupGlobals() +{ + SavePosition(); +} + + +wxString frmBackupGlobals::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pg-dumpall"); + return page; +} + + +void frmBackupGlobals::OnSelectFilename(wxCommandEvent &ev) +{ + wxString title, prompt, FilenameOnly; + + title = _("Select output file"); +#ifdef __WXMSW__ + prompt = _("Query files (*.sql)|*.sql|All files (*.*)|*.*"); +#else + prompt = _("Query files (*.sql)|*.sql|All files (*)|*"); +#endif + + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + wxFileDialog file(this, title, ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, prompt, wxFD_SAVE); + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} + + +void frmBackupGlobals::OnChange(wxCommandEvent &ev) +{ + if (!process && !done) + btnOK->Enable(!txtFilename->GetValue().IsEmpty()); +} + +wxString frmBackupGlobals::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupGlobals::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupGlobals::getCmdPart1() +{ + pgServer *server; + if (object->GetMetaType() == PGM_SERVER) + server = (pgServer *)object; + else + server = object->GetDatabase()->GetServer(); + + wxString cmd = backupExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())) + + wxT(" --database ") + commandLineCleanOption(qtIdent(server->GetDatabaseName())); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(backupExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + return cmd; +} + + +wxString frmBackupGlobals::getCmdPart2() +{ + wxString cmd; + + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + if (chkForceQuoteForIdent->GetValue()) + cmd.Append(wxT(" --quote-all-identifiers")); + + cmd.Append(wxT(" --file \"") + txtFilename->GetValue() + wxT("\"")); + + cmd.Append(wxT(" --globals-only")); + + return cmd; +} + + +void frmBackupGlobals::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + +void frmBackupGlobals::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a backup to this file again?"), _("Repeat backup?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + else if (wxFile::Exists(txtFilename->GetValue())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), txtFilename->GetValue().c_str()); + if (wxMessageBox(msg, _("Overwrite file?"), wxICON_WARNING | wxYES_NO) != wxYES) + return; + } + + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmBackupGlobals/LastFile"), txtFilename->GetValue()); + ExternProcessDialog::OnOK(ev); +} + +backupGlobalsFactory::backupGlobalsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Backup globals..."), _("Creates a backup of the global database objects")); +} + + +wxWindow *backupGlobalsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmBackupGlobals *frm = new frmBackupGlobals(form, obj); + frm->Go(); + return 0; +} + + +bool backupGlobalsFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetMetaType() == PGM_SERVER) + if (!((pgServer *)obj)->GetConnected()) + return false; + + if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) + return obj->CanBackupGlobals() && !edbBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(edbBackupAllExecutable, 8, 3); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanBackupGlobals() && !gpBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(gpBackupAllExecutable, 8, 3); + else + return obj->CanBackupGlobals() && !pgBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(pgBackupAllExecutable, 8, 3); +} + diff --git a/frm/frmBackupServer.cpp b/frm/frmBackupServer.cpp new file mode 100644 index 0000000..b4cf110 --- /dev/null +++ b/frm/frmBackupServer.cpp @@ -0,0 +1,270 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupServer.cpp - Backup server dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "frm/frmBackupServer.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" + +// Icons +#include "images/backup.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkForceQuoteForIdent CTRL_CHECKBOX("chkForceQuoteForIdent") + + +BEGIN_EVENT_TABLE(frmBackupServer, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmBackupServer::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmBackupServer::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmBackupServer::OnOK) + EVT_CLOSE( ExternProcessDialog::OnClose) +END_EVENT_TABLE() + + + +frmBackupServer::frmBackupServer(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmBackupServer")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(BACKUPSERVERTITLE)); + + pgServer *server = (pgServer *)object; + if (server->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupAllExecutable; + else if (server->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupAllExecutable; + else + backupExecutable = pgBackupAllExecutable; + + wxString val; + settings->Read(wxT("frmBackupServer/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + bool roles_supported = pgAppMinimumVersion(backupExecutable, 8, 4) && server->GetConnection()->BackendMinimumVersion(8, 1); + cbRolename->Enable(roles_supported); + + if (roles_supported) + { + // Collect the available rolenames + pgSetIterator set(server->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(server->GetRolename()); + } + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + server->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + // Icon + SetIcon(*backup_png_ico); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + + if (!pgAppMinimumVersion(backupExecutable, 9, 1)) + { + chkForceQuoteForIdent->Disable(); + } + + wxCommandEvent ev; + OnChange(ev); +} + + +frmBackupServer::~frmBackupServer() +{ + SavePosition(); +} + + +wxString frmBackupServer::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pg-dumpall"); + return page; +} + + +void frmBackupServer::OnSelectFilename(wxCommandEvent &ev) +{ + wxString title, prompt, FilenameOnly; + + title = _("Select output file"); +#ifdef __WXMSW__ + prompt = _("Query files (*.sql)|*.sql|All files (*.*)|*.*"); +#else + prompt = _("Query files (*.sql)|*.sql|All files (*)|*"); +#endif + + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + wxFileDialog file(this, title, ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, prompt, wxFD_SAVE); + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} + + +void frmBackupServer::OnChange(wxCommandEvent &ev) +{ + if (!process && !done) + btnOK->Enable(!txtFilename->GetValue().IsEmpty()); +} + +wxString frmBackupServer::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupServer::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(); +} + + +wxString frmBackupServer::getCmdPart1() +{ + pgServer *server = (pgServer *)object; + + wxString cmd = backupExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(backupExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + return cmd; +} + + +wxString frmBackupServer::getCmdPart2() +{ + wxString cmd; + + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + if (chkForceQuoteForIdent->GetValue()) + cmd.Append(wxT(" --quote-all-identifiers")); + + cmd.Append(wxT(" --file \"") + txtFilename->GetValue() + wxT("\"")); + + return cmd; +} + + +void frmBackupServer::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + +void frmBackupServer::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a backup to this file again?"), _("Repeat backup?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + else if (wxFile::Exists(txtFilename->GetValue())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), txtFilename->GetValue().c_str()); + if (wxMessageBox(msg, _("Overwrite file?"), wxICON_WARNING | wxYES_NO) != wxYES) + return; + } + + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmBackupServer/LastFile"), txtFilename->GetValue()); + ExternProcessDialog::OnOK(ev); +} + +backupServerFactory::backupServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Backup server..."), _("Creates a backup of the entire server")); +} + + +wxWindow *backupServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmBackupServer *frm = new frmBackupServer(form, obj); + frm->Go(); + return 0; +} + + +bool backupServerFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (!((pgServer *)obj)->GetConnected() || obj->GetMetaType() != PGM_SERVER) + return false; + + if (obj->GetConnection()->EdbMinimumVersion(8, 0)) + return !edbBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(edbBackupAllExecutable, 8, 3); + else if (obj->GetConnection()->GetIsGreenplum()) + return !gpBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(gpBackupAllExecutable, 8, 3); + else + return !pgBackupAllExecutable.IsEmpty() && pgAppMinimumVersion(pgBackupAllExecutable, 8, 3); +} + diff --git a/frm/frmConfig.cpp b/frm/frmConfig.cpp new file mode 100644 index 0000000..d14dfe3 --- /dev/null +++ b/frm/frmConfig.cpp @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmConfig.cpp - Configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmConfig.h" +#include "frm/frmHint.h" +#include "frm/frmMainConfig.h" +#include "frm/frmHbaConfig.h" +#include "frm/frmPgpassConfig.h" +#include "frm/frmMain.h" +#include "frm/frmAbout.h" +#include "utils/utffile.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#include "images/file_open.pngc" +#include "images/file_save.pngc" +#include "images/edit_undo.pngc" +#include "images/delete.pngc" +#include "images/help.pngc" +#include "images/hint2.pngc" +#include "images/checked.pngc" +#include "images/unchecked.pngc" +#include "images/query_execute.pngc" + + +BEGIN_EVENT_TABLE(frmConfig, pgFrame) + EVT_CLOSE( frmConfig::OnClose) + EVT_MENU(MNU_OPEN, frmConfig::OnOpen) + EVT_MENU(MNU_SAVE, frmConfig::OnSave) + EVT_MENU(MNU_SAVEAS, frmConfig::OnSaveAs) + EVT_MENU(MNU_EXECUTE, frmConfig::OnExecute) + EVT_MENU(MNU_HELP, frmConfig::OnHelp) + EVT_MENU(MNU_HINT, frmConfig::OnHint) +END_EVENT_TABLE() + + +wxImageList *configImageList = 0; + +frmConfig::frmConfig(frmMain *parent, const wxString &title, pgConn *_conn) + : pgFrame(parent, title) +{ + mainForm = parent; + conn = _conn; + SetStatusBarPane(-1); +} + + +frmConfig::frmConfig(const wxString &title, const wxString &configFile) + : pgFrame(NULL, title) +{ + mainForm = 0; + conn = 0; + + lastPath = configFile; + SetStatusBarPane(-1); +} + + +frmConfig::~frmConfig() +{ + if (conn) + delete conn; + if (mainForm) + mainForm->RemoveFrame(this); +} + + +void frmConfig::InitFrame(const wxChar *frameName) +{ + dlgName = frameName; + + if (!configImageList) + { + configImageList = new wxImageList(16, 16, true, 2); + configImageList->Add(*unchecked_png_ico); + configImageList->Add(*checked_png_ico); + } + + menuFactories = new menuFactoryList(); + + SetFont(settings->GetSystemFont()); + + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + + fileMenu = new wxMenu(); + editMenu = new wxMenu(); + helpMenu = new wxMenu(); + recentFileMenu = new wxMenu(); + + fileMenu->Append(MNU_OPEN, _("&Open...\tCtrl-O"), _("Open a query file")); + toolBar->AddTool(MNU_OPEN, wxEmptyString, *file_open_png_bmp, _("Open file"), wxITEM_NORMAL); + + fileMenu->Append(MNU_SAVE, _("&Save\tCtrl-S"), _("Save current file")); + toolBar->AddTool(MNU_SAVE, wxEmptyString, *file_save_png_bmp, _("Save file"), wxITEM_NORMAL); + + fileMenu->Append(MNU_SAVEAS, _("Save &as..."), _("Save file under new name")); + + fileMenu->AppendSeparator(); + toolBar->AddSeparator(); + + // File Menu + + fileMenu->Append(MNU_EXECUTE, _("Reload server"), _("Reload Server to apply configuration changes.")); + toolBar->AddTool(MNU_EXECUTE, wxEmptyString, *query_execute_png_bmp, _("Reload Server to apply configuration changes."), wxITEM_NORMAL); + + fileMenu->AppendSeparator(); + toolBar->AddSeparator(); + + fileMenu->Append(MNU_RECENT, _("&Recent files"), recentFileMenu); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit configuration tool")); + + editMenu->Append(MNU_UNDO, _("&Undo\tCtrl-Z"), _("Undo last action"), wxITEM_NORMAL); + toolBar->AddTool(MNU_UNDO, wxEmptyString, *edit_undo_png_bmp, _("Undo last action"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_DELETE, _("&Delete\tDEL"), _("Delete current row"), wxITEM_NORMAL); + toolBar->AddTool(MNU_DELETE, wxEmptyString, *delete_png_bmp, _("Delete current row"), wxITEM_NORMAL); + + toolBar->AddSeparator(); + + + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + + helpMenu->Append(MNU_HINT, _("Hints"), _("Display helpful hints on current object.")); + toolBar->AddTool(MNU_HINT, wxEmptyString, *hint2_png_bmp, _("Display helpful hints on current object.")); + helpMenu->Append(MNU_HELP, _("&Configuration Help\tF1"), _("Display help on configuration options.")); + helpMenu->AppendSeparator(); + + new bugReportFactory(menuFactories, helpMenu, 0); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + +#ifdef __WXMAC__ + wxApp::s_macAboutMenuItemId = af->GetId(); +#else + (void)af; +#endif + + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); + menuFactories->CheckMenu(0, menuBar, toolBar); + + wxAcceleratorEntry entries[3]; + + entries[0].Set(wxACCEL_CTRL, (int)'O', MNU_OPEN); + entries[1].Set(wxACCEL_CTRL, (int)'S', MNU_SAVE); + entries[2].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + + wxAcceleratorTable accel(3, entries); + SetAcceleratorTable(accel); + + toolBar->AddTool(MNU_HELP, wxEmptyString, *help_png_bmp, _("Display help on configuration options."), wxITEM_NORMAL); + toolBar->Realize(); + + UpdateRecentFiles(); + + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + if (conn) + { + toolBar->EnableTool(MNU_OPEN, false); + if (!conn->HasFeature(FEATURE_RELOAD_CONF)) + { + fileMenu->Enable(MNU_EXECUTE, false); + toolBar->EnableTool(MNU_EXECUTE, false); + } + } + else + { + fileMenu->Enable(MNU_EXECUTE, false); + toolBar->EnableTool(MNU_EXECUTE, false); + } + + SetToolBar(toolBar); + statusBar = CreateStatusBar(); +} + + +void frmConfig::Go() +{ + Show(); +} + +void frmConfig::DoOpen(const wxString &fn) +{ + wxCommandEvent ev; + OnOpen(ev); +} + + +void frmConfig::OnClose(wxCloseEvent &event) +{ + if (CheckChanged(event.CanVeto()) && event.CanVeto()) + { + event.Veto(); + return; + } + Destroy(); +} + +void frmConfig::OnHelp(wxCommandEvent &event) +{ + DisplayHelp(GetHelpPage(), HELP_POSTGRESQL); +} + +void frmConfig::OnHint(wxCommandEvent &event) +{ + DisplayHint(true); +} + + +void frmConfig::OnBugreport(wxCommandEvent &event) +{ + DisplayHelp(wxT("bugreport"), HELP_PGADMIN); +} + + +void frmConfig::OnExecute(wxCommandEvent &event) +{ + wxMessageDialog dlg(this, _("Are you sure you want trigger the server to reload its configuration?"), + _("Reload server configuration"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() == wxID_YES) + { + if (conn->ExecuteVoid(wxT("SELECT pg_reload_conf()"))) + { + } + } +} + + +void frmConfig::OnOpen(wxCommandEvent &event) +{ + if (CheckChanged(true)) + return; + +#ifdef __WXMSW__ + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*)|*"), wxFD_OPEN); +#endif + + if (dlg.ShowModal() == wxID_OK) + { + lastFilename = dlg.GetFilename(); + lastDir = dlg.GetDirectory(); + lastPath = dlg.GetPath(); + OpenLastFile(); + UpdateRecentFiles(); + } +} + + + +void frmConfig::OnSave(wxCommandEvent &event) +{ + if (!fileMenu->IsEnabled(MNU_SAVE)) + return; + + if (conn) + { + wxMessageDialog msg(this, _("If a malformed configuration is written to the server, it might show problems when restarting or reloading.\nAre you sure the configuration is correct?"), + _("Writing configuration file to server"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + + if (msg.ShowModal() != wxID_YES) + return; + } + WriteFile(conn); +} + + +void frmConfig::OnSaveAs(wxCommandEvent &event) +{ +#ifdef __WXMSW__ + wxFileDialog *dlg = new wxFileDialog(this, _("Save configuration file as"), lastDir, lastFilename, + _("Configuration files (*.conf)|*.conf|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog *dlg = new wxFileDialog(this, _("Save configuration file as"), lastDir, lastFilename, + _("Configuration files (*.conf)|*.conf|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + if (dlg->ShowModal() == wxID_OK) + { + lastFilename = dlg->GetFilename(); + lastDir = dlg->GetDirectory(); + lastPath = dlg->GetPath(); + + WriteFile(); + if (!changed) + UpdateRecentFiles(); + } + delete dlg; +} + + +void frmConfig::OpenLastFile() +{ + wxUtfFile file(lastPath, wxFile::read, wxFONTENCODING_SYSTEM); + if (file.IsOpened()) + { + wxString buffer; + file.Read(buffer); + file.Close(); + + DisplayFile(buffer); + + statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), lastPath.c_str())); + + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + } +} + + +bool frmConfig::CheckChanged(bool canVeto) +{ + if (changed && settings->GetAskSaveConfirmation()) + { + wxMessageDialog msg(this, _("The configuration is modified.\nDo you want to save changes?"), + GetTitle(), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION | + (canVeto ? wxCANCEL : 0)); + + switch (msg.ShowModal()) + { + case wxID_YES: + WriteFile(conn); + return changed; + + case wxID_CANCEL: + return true; + } + } + return false; +} + + +bool frmConfig::DoWriteFile(const wxChar *str, pgConn *conn) +{ + bool done = false; + + wxString buffer; + if (filetype != wxTextFileType_Unix) + { + buffer = wxTextBuffer::Translate(str, filetype); + str = buffer; + } + if (conn) + { + done = conn->ExecuteVoid( + wxT("SELECT pg_file_unlink('") + serverFileName + wxT(".bak');\n") + wxT("SELECT pg_file_write('") + serverFileName + wxT(".tmp', ") + + conn->qtDbString(str) + wxT(", false);\n") + wxT("SELECT pg_file_rename('") + serverFileName + wxT(".tmp', '") + + serverFileName + wxT("', '") + + serverFileName + wxT(".bak');")); + if (!done) + conn->ExecuteVoid( + wxT("SELECT pg_file_unlink('") + serverFileName + wxT(".tmp')")); + } + else + { + wxUtfFile file(lastPath, wxFile::write, wxFONTENCODING_SYSTEM); + if (file.IsOpened()) + { +#ifdef __WXMSW__ + _setmode(file.fd(), _O_BINARY); +#endif + file.Write(str); + file.Close(); + done = true; + } + } + + if (done) + { + if (conn) + statusBar->SetStatusText(wxString::Format(_(" Configuration written to %s"), conn->GetHost().c_str())); + else + statusBar->SetStatusText(wxString::Format(_(" Configuration written to %s"), lastPath.c_str())); + } + return done; +} + + +void frmConfig::DisplayHint(bool force) +{ + wxString str = GetHintString(); + if (str.IsEmpty()) + { + if (!force) + return; + str = _("No configuration setting detected that appears doubtful."); + } + + wxMessageBox(str, _("Backend Configuration Hints"), wxICON_EXCLAMATION | wxOK); +} + + +frmConfig *frmConfig ::Create(const wxString &title, const wxString &configFile, tryMode mode) +{ + frmConfig *frm = 0; + if (wxFile::Exists(configFile)) + { + if (mode == HBAFILE || configFile.Right(11) == wxT("pg_hba.conf")) + frm = new frmHbaConfig(title, configFile); + else if (mode == MAINFILE || configFile.Right(15) == wxT("postgresql.conf")) + frm = new frmMainConfig(title, configFile); + else if (mode == PGPASSFILE || configFile.Right(11) == wxT("pgpass.conf") || configFile.Right(7) == wxT(".pgpass")) + frm = new frmPgpassConfig(title, configFile); + + // unknown config file! + } + + if (frm) + frm->Go(); + + return frm; +} diff --git a/frm/frmDatabaseDesigner.cpp b/frm/frmDatabaseDesigner.cpp new file mode 100644 index 0000000..06cd55b --- /dev/null +++ b/frm/frmDatabaseDesigner.cpp @@ -0,0 +1,929 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDatabaseDesigner.cpp - The database designer form +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "frm/frmMain.h" +#include "frm/frmDatabaseDesigner.h" +#include "ctl/ctlMenuToolbar.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "ctl/ctlSQLBox.h" +#include "dlg/dlgSelectConnection.h" +#include "utils/sysSettings.h" + +// Designer headers +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "hotdraw/figures/hdRectangleFigure.h" +#include "hotdraw/figures/hdBitmapFigure.h" +#include "hotdraw/tools/hdConnectionCreationTool.h" +#include "dd/ddmodel/ddModelBrowser.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include "dd/ddmodel/ddGenerationWizard.h" + +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddDrawingView.h" + +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/utilities/ddTableNameDialog.h" + +#include "dd/dditems/figures/xml/ddXmlStorage.h" + +// Icons +#include "images/ddmodel-32.pngc" +#include "images/file_new.pngc" +#include "images/table.pngc" +#include "images/ddRemoveTable2.pngc" +#include "images/continue.pngc" +#include "images/ddnewdiagram.pngc" +#include "images/ddgendiagram.pngc" +#include "images/help.pngc" +#include "images/file_save.pngc" +#include "images/file_open.pngc" +#include "images/conversion.pngc" + +BEGIN_EVENT_TABLE(frmDatabaseDesigner, pgFrame) + EVT_COMBOBOX(CTL_DDCONNECTION, frmDatabaseDesigner::OnChangeConnection) + EVT_MENU(MNU_NEW, frmDatabaseDesigner::OnNewModel) + EVT_MENU(MNU_ADDTABLE, frmDatabaseDesigner::OnAddTable) + EVT_MENU(MNU_DELETETABLE, frmDatabaseDesigner::OnDeleteTable) + EVT_MENU(MNU_ADDCOLUMN, frmDatabaseDesigner::OnAddColumn) + EVT_MENU(MNU_GENERATEDIAGRAM, frmDatabaseDesigner::OnDiagramGeneration) + EVT_MENU(MNU_GENERATEMODEL, frmDatabaseDesigner::OnModelGeneration) + EVT_MENU(MNU_SAVEMODEL, frmDatabaseDesigner::OnModelSave) + EVT_MENU(MNU_SAVEMODELAS, frmDatabaseDesigner::OnModelSaveAs) + EVT_MENU(MNU_LOADMODEL, frmDatabaseDesigner::OnModelLoad) + EVT_MENU(MNU_NEWDIAGRAM, frmDatabaseDesigner::OnAddDiagram) + EVT_MENU(MNU_DELDIAGRAM, frmDatabaseDesigner::OnDeleteDiagram) + EVT_MENU(MNU_RENDIAGRAM, frmDatabaseDesigner::OnRenameDiagram) + EVT_MENU(MNU_TOGGLEDDSQL, frmDatabaseDesigner::OnToggleSQLWindow) + EVT_MENU(MNU_TOGGLEMBROWSER, frmDatabaseDesigner::OnToggleModelBrowser) + EVT_MENU(CTL_IMPSCHEMA, frmDatabaseDesigner::OnImportSchema) + EVT_AUINOTEBOOK_PAGE_CLOSE(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnDeleteDiagramTab) + EVT_AUINOTEBOOK_PAGE_CLOSED(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnDeletedDiagramTab) + EVT_AUINOTEBOOK_BUTTON(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnClickDiagramTab) + EVT_AUINOTEBOOK_BG_DCLICK(CTL_DDNOTEBOOK, frmDatabaseDesigner::OnAddDiagram2) + EVT_CLOSE( frmDatabaseDesigner::OnClose) +END_EVENT_TABLE() + +frmDatabaseDesigner::frmDatabaseDesigner(frmMain *form, const wxString &_title, pgConn *conn) + : pgFrame(NULL, _title) +{ + mainForm = form; + SetTitle(wxT("Database Designer")); + SetIcon(wxIcon(*ddmodel_32_png_ico)); + loading = true; + closing = false; + + RestorePosition(100, 100, 600, 500, 450, 300); + SetMinSize(wxSize(450, 300)); + + // connection + connection = conn; + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + SetFont(settings->GetSystemFont()); + + // Set File menu + fileMenu = new wxMenu(); + fileMenu->Append(MNU_NEW, _("&New database design\tCtrl-N"), _("Create a new database design")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_LOADMODEL, _("&Open Model..."), _("Open an existing database design from a file")); + fileMenu->Append(MNU_SAVEMODEL, _("&Save Model"), _("Save changes at database design")); + fileMenu->Append(MNU_SAVEMODELAS, _("&Save Model As..."), _("Save database design at new file")); + fileMenu->AppendSeparator(); + fileMenu->Append(CTL_IMPSCHEMA, _("&Import Tables..."), _("Import tables from database schema to database designer model")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit database designer window")); + + // Set Diagram menu + diagramMenu = new wxMenu(); + diagramMenu->Append(MNU_NEWDIAGRAM, _("&New model diagram"), _("Create a new diagram")); + diagramMenu->Append(MNU_DELDIAGRAM, _("&Delete selected model diagram..."), _("Delete selected diagram")); + diagramMenu->Append(MNU_RENDIAGRAM, _("&Rename selected model diagram..."), _("Rename selected diagram")); + + // Set View menu + viewMenu = new wxMenu(); + viewMenu->AppendCheckItem(MNU_TOGGLEMBROWSER, _("&Model Browser"), _("Show / Hide Model Browser Window")); + viewMenu->AppendCheckItem(MNU_TOGGLEDDSQL, _("&SQL Window"), _("Show / Hide SQL Window")); + viewMenu->Check(MNU_TOGGLEDDSQL, true); + viewMenu->Check(MNU_TOGGLEMBROWSER, true); + + // Set Help menu + helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); + + // Set menu bar + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(diagramMenu, _("&Diagram")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + + // Set status bar + int iWidths[6] = {0, -1, 40, 150, 80, 80}; + CreateStatusBar(6); + SetStatusBarPane(-1); + SetStatusWidths(6, iWidths); + + // Set toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + toolBar->AddTool(MNU_NEW, _("New Model"), *file_new_png_bmp, _("Create new model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_NEWDIAGRAM, _("New Diagram"), *ddnewdiagram_png_bmp, _("Add new diagram"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_LOADMODEL, _("Open Model"), *file_open_png_bmp, _("Open existing model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_SAVEMODEL, _("Save Model"), *file_save_png_bmp, _("Save current model"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_ADDTABLE, _("Add Table"), *table_png_bmp, _("Add empty table to the current model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_DELETETABLE, _("Delete Table"), wxBitmap(*ddRemoveTable2_png_img), _("Delete selected table"), wxITEM_NORMAL); + toolBar->AddTool(MNU_ADDCOLUMN, _("Add Column"), *table_png_bmp, _("Add new column to the selected table"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_GENERATEMODEL, _("Generate Model"), *continue_png_bmp, _("Generate SQL for the current model"), wxITEM_NORMAL); + toolBar->AddTool(MNU_GENERATEDIAGRAM, _("Generate Diagram"), *ddgendiagram_png_bmp, _("Generate SQL for the current diagram"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(CTL_IMPSCHEMA, _("Import Tables from database..."), *conversion_png_ico, _("Import tables from database schema to database designer model"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_HELP, _("Help"), *help_png_bmp, _("Display help"), wxITEM_NORMAL); + toolBar->Realize(); + + // Create notebook for diagrams + diagrams = new ctlAuiNotebook(this, CTL_DDNOTEBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON | wxAUI_NB_CLOSE_ON_ALL_TABS); + + // Now, the scratchpad + sqltext = new ctlSQLBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2); + + //Now, the Objects Browser + wxSizer *browserSizer = new wxBoxSizer(wxHORIZONTAL); + browserPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + + // Add the database designer + design = new ddDatabaseDesign(diagrams, this); + + // Create database model browser + modelBrowser = new ddModelBrowser(browserPanel, DD_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER, design); + design->registerBrowser(modelBrowser); + + // Set browser Sizers + browserSizer->Add(modelBrowser, 1, wxEXPAND); + browserPanel->SetSizer(browserSizer); + browserSizer->SetSizeHints(browserPanel); + + // Add view to notebook + diagrams->AddPage(design->createDiagram(diagrams, _("unnamed"), false)->getView(), _("unnamed")); + + + // Add the database selection bar and schema selector + wxSizer *connectionSizer = new wxBoxSizer(wxHORIZONTAL); + connectionPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1)); + cbConnection = new wxBitmapComboBox(connectionPanel, CTL_DDCONNECTION, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + if(conn) + cbConnection->Append(conn->GetName(), CreateBitmap(GetServerColour(conn)), (void *)conn); + cbConnection->Append(_(""), wxNullBitmap, (void *) NULL); + + connectionSizer->Add(cbConnection, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 1); + connectionSizer->AddSpacer(5); + connectionPanel->SetSizer(connectionSizer); + connectionSizer->SetSizeHints(connectionPanel); + + + // Add the panes + manager.AddPane(diagrams, + wxAuiPaneInfo().Center(). + Name(wxT("sqlQuery")).Caption(_("Database Designer")). + CaptionVisible(true).CloseButton(false).MaximizeButton(true). + Dockable(true).Movable(true)); + manager.AddPane(browserPanel, + wxAuiPaneInfo().Left(). + Name(wxT("ModelBrowser")).Caption(_("Model Browser")). + CaptionVisible(true).CloseButton(true).MinimizeButton(true). + MinSize(wxSize(140, 100)).BestSize(wxSize(200, 200))); + manager.AddPane(sqltext, + wxAuiPaneInfo().Bottom(). + Name(wxT("sqlText")).Caption(_("SQL query")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true).MinimizeButton(true). + MinSize(wxSize(200, 100)).BestSize(wxSize(350, 150))); + manager.AddPane(toolBar, + wxAuiPaneInfo().Top(). + Name(wxT("toolBar")).Caption(_("Tool bar")). + ToolbarPane(). + LeftDockable(false).RightDockable(false)); + manager.AddPane(connectionPanel, wxAuiPaneInfo().Name(wxT("databaseBar")) + .Caption(_("Connection bar")).ToolbarPane().Top(). + LeftDockable(false).RightDockable(false)); + + // Update the AUI manager + manager.Update(); + + //Update browser info + modelBrowser->SetSize(browserPanel->GetSize()); + + previousChanged = true; + setModelChanged(false); + SetStatusText(wxString(wxT("Ready")), 1); +} + + +frmDatabaseDesigner::~frmDatabaseDesigner() +{ + closing = true; + + // Save form's position + SavePosition(); + + // Uninitialize wxAUIManager + manager.UnInit(); + + if (mainForm) + mainForm->RemoveFrame(this); + + if(modelBrowser) + delete modelBrowser; + + if(browserPanel) + delete browserPanel; + + if(diagrams) + delete diagrams; + + if(design) + delete design; + + if (connection) + { + if (connection->IsAlive()) + delete connection; + } +} + + +void frmDatabaseDesigner::Go() +{ + cbConnection->SetSelection(0L); + + if (connection) + { + wxCommandEvent event; + OnChangeConnection(event); + } + + loading = false; + Show(true); +} + +void frmDatabaseDesigner::setModelChanged(bool value) +{ + previousChanged = changed; + changed = value; + + // optimization to avoid unneeded operations + // false changed for false don't trigger it, but false changed to true trigger it. + if (previousChanged != changed) + { + wxMenuItem *itemMenu = fileMenu->FindItem(MNU_SAVEMODEL); + + if (value) + { + itemMenu->Enable(true); + toolBar->EnableTool(MNU_SAVEMODEL, true); + setExtendedTitle(); + } + else + { + itemMenu->Enable(false); + toolBar->EnableTool(MNU_SAVEMODEL, false); + setExtendedTitle(); + } + } +} + + +void frmDatabaseDesigner::OnClose(wxCloseEvent &event) +{ + closing = true; + + // Ask what to do with old model + if (changed) + { + int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); + + if (answer == wxYES) + { + if (lastFile.IsEmpty()) + { + wxFileDialog openFileDialog( this, _("Save model"), wxT(""), wxT(""), wxT("*.pgd"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); + + if (openFileDialog.ShowModal() == wxID_OK) + { + wxString path; + path.append(openFileDialog.GetDirectory()); + path.append(wxFileName::GetPathSeparator()); + path.append(openFileDialog.GetFilename()); + if(!path.Lower().Matches(wxT("*.pgd"))) + path.append(wxT(".pgd")); + lastFile = path; + } + } + + if (!lastFile.IsEmpty()) + { + design->writeXmlModel(lastFile); + setModelChanged(false); + setExtendedTitle(); + } + } + else if (answer == wxCANCEL) + { + event.Veto(); + return; + } + } + + Hide(); + Destroy(); +} + +void frmDatabaseDesigner::setExtendedTitle() +{ + wxString title = wxT("Database Design"); + wxString chgStr; + if (changed) + chgStr = wxT(" *"); + + if (lastFile.IsEmpty()) + SetTitle(title + chgStr); + else + SetTitle(title + wxT(" - [") + lastFile + wxT("]") + chgStr); +} + +void frmDatabaseDesigner::OnAddTable(wxCommandEvent &event) +{ + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + + ddTableNameDialog *newTableDialog = new ddTableNameDialog( + this, + wxEmptyString, + wxEmptyString, + NULL + ); + + bool done = false, existsTable; + int answer; + + do + { + answer = newTableDialog->ShowModal(); + existsTable = design->getTable(newTableDialog->GetValue1()) != NULL; + + if (answer == wxID_OK && !newTableDialog->GetValue1().IsEmpty() && !existsTable) + { + ddTableFigure *newTable = new ddTableFigure(newTableDialog->GetValue1(), + view->getIdx(), + rand() % 90 + 200, + rand() % 90 + 140); + design->addTableToView(view->getIdx(), newTable); + design->refreshDraw(view->getIdx()); + setModelChanged(true); + setExtendedTitle(); + done = true; + } + else if(existsTable && answer == wxID_OK) + { + wxMessageBox(_("You have to change the table name because there is already a table with that name in this model."), _("Table already existing"), wxICON_EXCLAMATION | wxOK); + } + } + while (answer != wxID_CANCEL && !done); + + delete newTableDialog; + } +} + +void frmDatabaseDesigner::OnDeleteTable(wxCommandEvent &event) +{ + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + view->getDrawing()->deleteSelectedFigures(); + setModelChanged(true); + setExtendedTitle(); + } +} + +void frmDatabaseDesigner::OnAddColumn(wxCommandEvent &event) +{ + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + ddTableFigure *table = design->getSelectedTable(view->getIdx()); + wxTextEntryDialog nameDialog (this, wxT("New column name"), wxT("Add a column"), wxT("NewColumn")); + int answer; + wxString tmpString; + + if (table) + { + bool again; + do + { + again = false; + answer = nameDialog.ShowModal(); + if (answer == wxID_OK) + { + tmpString = nameDialog.GetValue(); + if(table->getColByName(tmpString) == NULL) + { + table->addColumn(view->getIdx(), new ddColumnFigure(tmpString, table)); + setModelChanged(true); + setExtendedTitle(); + } + else + { + wxString msg(wxT("Error trying to add new column '")); + msg.Append(tmpString); + msg.Append(wxT("' column name already in use")); + wxMessageDialog info( this, msg , + wxT("Column name already in use"), + wxNO_DEFAULT | wxOK | wxICON_EXCLAMATION); + again = true; + info.ShowModal(); + } + + } + } + while(again); + } + view->Refresh(); + } + else + { + wxMessageBox(_("Warning about adding a column to a table without a diagram"), _("Please create a model diagram first"), wxICON_EXCLAMATION | wxOK); + } +} + + +void frmDatabaseDesigner::OnNewModel(wxCommandEvent &event) +{ + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + + if (changed) + { + // Ask what to do with old model + int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); + + if (answer == wxYES) + { + if (!lastFile.IsEmpty()) + OnModelSave(event); + else + OnModelSaveAs(event); + } + else if (answer == wxCANCEL) + return; + } + + // Clean treeview, notebook, and sql pane + design->emptyModel(); + while (diagrams->GetPageCount() > 0) + { + diagrams->RemovePage(0); + design->deleteDiagram(0); + } + sqltext->SetText(wxEmptyString); + + // Add new diagram + diagrams->AddPage(design->createDiagram(diagrams, _("unnamed"), false)->getView(), _("unnamed")); + + // Misc + lastFile = wxEmptyString; + setModelChanged(false); + setExtendedTitle(); + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnDiagramGeneration(wxCommandEvent &event) +{ + wxString errors; + if(!design->validateModel(errors)) + { + wxMessageDialog dialog(this, errors , wxT("Errors detected in the database model"), wxOK | wxICON_EXCLAMATION | wxSTAY_ON_TOP); + dialog.ShowModal(); + } + else + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + ddGenerationWizard *generationWizard = new ddGenerationWizard(this, design, connection); + //Set pre-select tables [diagram] + generationWizard->preSelTables = design->getDiagramTables(view->getIdx()); + //Call generation wizard + generationWizard->RunWizard(generationWizard->GetFirstPage()); + sqltext->SetText(generationWizard->DDL); + delete generationWizard; + } +} + +void frmDatabaseDesigner::OnModelGeneration(wxCommandEvent &event) +{ + wxString errors; + if(!design->validateModel(errors)) + { + wxMessageDialog dialog(this, errors , wxT("Errors detected in the database model"), wxOK | wxICON_EXCLAMATION | wxSTAY_ON_TOP); + dialog.ShowModal(); + } + else + { + ddGenerationWizard *generationWizard = new ddGenerationWizard(this, design, connection); + //Set pre-select tables [model] disable + //generationWizard->preSelTables = design->getModelTables(); + //Call generation wizard + generationWizard->RunWizard(generationWizard->GetFirstPage()); + sqltext->SetText(generationWizard->DDL); + delete generationWizard; + } +} + +void frmDatabaseDesigner::OnModelSaveAs(wxCommandEvent &event) +{ + wxFileDialog openFileDialog( this, _("Save model"), wxT(""), wxT(""), wxT("*.pgd"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT, wxDefaultPosition); + + if (openFileDialog.ShowModal() == wxID_OK) + { + wxString path; + path.append( openFileDialog.GetDirectory() ); + path.append( wxFileName::GetPathSeparator() ); + path.append( openFileDialog.GetFilename() ); + if(!path.Lower().Matches(wxT("*.pgd"))) + path.append(wxT(".pgd")); + lastFile = path; + setModelChanged(false); + setExtendedTitle(); + design->writeXmlModel(path); + } +} + +void frmDatabaseDesigner::OnModelSave(wxCommandEvent &event) +{ + if (lastFile != wxEmptyString) + { + design->writeXmlModel(lastFile); + setModelChanged(false); + setExtendedTitle(); + } + else + { + OnModelSaveAs(event); + } +} + +void frmDatabaseDesigner::OnModelLoad(wxCommandEvent &event) +{ + if(changed) + { + // Ask what to do with old model + int answer = wxMessageBox(_("Save model changes?"), _("Confirm"), wxYES_NO | wxCANCEL); + if (answer == wxYES) + { + if (lastFile != wxEmptyString) + OnModelSave(event); + else + OnModelSaveAs(event); + } + + if(answer == wxCANCEL) + return; + } + + //Open Model + wxFileDialog openFileDialog(this, _("Open model"), wxT(""), wxT(""), wxT("*.pgd"), + wxFD_OPEN | wxFD_FILE_MUST_EXIST, wxDefaultPosition); + + if (openFileDialog.ShowModal() == wxID_OK) + { + wxString path; + path.append(openFileDialog.GetDirectory()); + path.append(wxFileName::GetPathSeparator()); + path.append(openFileDialog.GetFilename()); + if(!path.Lower().Matches(wxT("*.pgd"))) + path.append(wxT(".pgd")); + lastFile = path; + + // Clean treeview, notebook, and sql pane + design->emptyModel(); + while(diagrams->GetPageCount() > 0) + { + diagrams->RemovePage(0); + design->deleteDiagram(0); + } + sqltext->SetText(wxEmptyString); + + // Read model from xml file + design->readXmlModel(path, diagrams); + setModelChanged(false); + setExtendedTitle(); + } +} + +void frmDatabaseDesigner::OnAddDiagram(wxCommandEvent &event) +{ + wxString newName = wxGetTextFromUser(_("New Diagram Name"), _("Diagram Name"), _("unnamed"), this); + + if (!newName.IsEmpty()) + { + diagrams->AddPage(design->createDiagram(diagrams, newName, false)->getView(), newName); + setModelChanged(true); + } + + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnAddDiagram2(wxAuiNotebookEvent &event) +{ + wxCommandEvent evt; + OnAddDiagram(evt); +} + +void frmDatabaseDesigner::OnDeleteDiagram(wxCommandEvent &event) +{ + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + int diagramIndex = view->getIdx(); + diagrams->RemovePage(diagrams->GetSelection()); + design->deleteDiagram(diagramIndex); + setModelChanged(true); + + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnRenameDiagram(wxCommandEvent &event) +{ + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + int diagramIndex = view->getIdx(); + wxString msg; + msg.Printf(_("Rename diagram %s to:"), diagrams->GetPageText(diagramIndex).c_str()); + wxString name = wxGetTextFromUser(msg, _("Rename diagram..."), diagrams->GetPageText(diagramIndex), this); + if(!name.IsEmpty() && !name.IsSameAs(diagrams->GetPageText(diagramIndex), false)) + { + view->getDrawing()->setName(name); + diagrams->SetPageText(diagramIndex, name); + setModelChanged(true); + } +} + +void frmDatabaseDesigner::OnDeleteDiagramTab(wxAuiNotebookEvent &event) +{ + deletedTab = event.GetSelection(); + wxAuiNotebook *ctrl = (wxAuiNotebook *)event.GetEventObject(); + hdDrawingView *view = (hdDrawingView *) ctrl->GetPage(event.GetSelection()); + + wxString msg; + msg.Printf(_("Are you sure you want to delete diagram \"%s\" from model?"), view->getDrawing()->getName().c_str()); + int res = wxMessageBox(msg, + wxT("Delete diagram?"), + wxYES_NO | wxNO_DEFAULT, + this); + if (res != wxYES) + { + event.Veto(); + } + else + { + setModelChanged(true); + } + + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnDeletedDiagramTab(wxAuiNotebookEvent &event) +{ + //don't delete view when deleting diagram because it was deleted before by EVT_AUINOTEBOOK_PAGE_CLOSE event + //option possible will be wxAuiPaneInfo().DestroyOnClose(false) but should be tried in a future + design->deleteDiagram(deletedTab, false); + UpdateToolbar(); +} + +void frmDatabaseDesigner::OnClickDiagramTab(wxAuiNotebookEvent &event) +{ +//This event is not working by unknown reason right now. + wxLogError(wxT("WTF?")); +} + +void frmDatabaseDesigner::UpdateToolbar() +{ + toolBar->EnableTool(MNU_ADDTABLE, diagrams->GetPageCount() > 0); + toolBar->EnableTool(MNU_DELETETABLE, diagrams->GetPageCount() > 0); + + if (diagrams->GetPageCount() > 0) + { + hdDrawingView *view = (hdDrawingView *) diagrams->GetPage(diagrams->GetSelection()); + ddTableFigure *table = design->getSelectedTable(view->getIdx()); + toolBar->EnableTool(MNU_ADDCOLUMN, table != NULL); + } + + toolBar->EnableTool(MNU_GENERATEMODEL, diagrams->GetPageCount() > 0); + toolBar->EnableTool(MNU_GENERATEDIAGRAM, diagrams->GetPageCount() > 0); +} + + +wxColour frmDatabaseDesigner::GetServerColour(pgConn *connection) +{ + wxColour tmp = wxNullColour; + if (mainForm != NULL) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server->GetConnected() && + server->GetConnection()->GetHost() == connection->GetHost() && + server->GetConnection()->GetPort() == connection->GetPort()) + { + tmp = wxColour(server->GetColour()); + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + return tmp; +} + +wxBitmap frmDatabaseDesigner::CreateBitmap(const wxColour &colour) +{ + const int w = 10, h = 10; + + wxMemoryDC dc; + wxBitmap bmp(w, h); + dc.SelectObject(bmp); + if (colour == wxNullColour) + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); + else + dc.SetBrush(wxBrush(colour)); + dc.DrawRectangle(0, 0, w, h); + + return bmp; +} + +void frmDatabaseDesigner::OnChangeConnection(wxCommandEvent &event) +{ + // On Solaris, this event seems to get fired when the form closes(!!) + if(!IsVisible() && !loading) + return; + + unsigned int sel = cbConnection->GetSelection(); + if (sel == cbConnection->GetCount() - 1) + { + // new Connection + dlgSelectConnection dlg(this, mainForm); + int rc = dlg.Go(connection, cbConnection); + if (rc == wxID_OK) + { + bool createdNewConn; + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Database Designer"); + pgConn *newconn = dlg.CreateConn(applicationname, createdNewConn); + if (newconn && createdNewConn) + { + cbConnection->Insert(newconn->GetName(), CreateBitmap(GetServerColour(newconn)), sel); + cbConnection->SetClientData(sel, (void *)newconn); + cbConnection->SetSelection(sel); + OnChangeConnection(event); + } + else + rc = wxID_CANCEL; + } + if (rc != wxID_OK) + { + unsigned int i; + for (i = 0 ; i < sel ; i++) + { + if (cbConnection->GetClientData(i) == connection) + { + cbConnection->SetSelection(i); + break; + } + } + } + } + else + { + connection = (pgConn *)cbConnection->GetClientData(sel); + setExtendedTitle(); + } +} + +void frmDatabaseDesigner::OnImportSchema(wxCommandEvent &WXUNUSED(event)) +{ + ddDBReverseEngineering *importTableWizard = new ddDBReverseEngineering(this, design, connection); + importTableWizard->RunWizard(importTableWizard->GetFirstPage()); + delete importTableWizard; +} + +void frmDatabaseDesigner::OnToggleModelBrowser(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOGGLEMBROWSER)) + manager.GetPane(wxT("ModelBrowser")).Show(true); + else + manager.GetPane(wxT("ModelBrowser")).Show(false); + manager.Update(); +} + +void frmDatabaseDesigner::OnToggleSQLWindow(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOGGLEDDSQL)) + manager.GetPane(wxT("sqlText")).Show(true); + else + manager.GetPane(wxT("sqlText")).Show(false); + manager.Update(); +} + +/////////////////////////////////////////////////////// + + +bool databaseDesignerBaseFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); +} + + +wxWindow *databaseDesignerBaseFactory::StartDialogDesigner(frmMain *form, pgObject *obj, const wxString &sql) +{ + if(obj) + { + pgDatabase *db = obj->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Database designer"); + pgConn *conn = NULL; + if(db) + { + conn = db->CreateConn(applicationname); + if (conn) + { + frmDatabaseDesigner *fd = new frmDatabaseDesigner(form, wxEmptyString, conn); + fd->Go(); + return fd; + } + } + + } + + frmDatabaseDesigner *fd = new frmDatabaseDesigner(form, wxEmptyString, NULL); + fd->Go(); + return fd; +} + + +databaseDesignerFactory::databaseDesignerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : databaseDesignerBaseFactory(list) +{ + mnu->Append(id, _("&Database Designer\tCtrl-F"), _("Create database designs")); + toolbar->AddTool(id, _("Database Designer\tCtrl-F"), wxBitmap(*ddmodel_32_png_img), _("Create database designs."), wxITEM_NORMAL); +} + + +wxWindow *databaseDesignerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString qry; + if (settings->GetStickySql()) + qry = obj->GetSql(form->GetBrowser()); + return StartDialogDesigner(form, obj, qry); +} diff --git a/frm/frmEditGrid.cpp b/frm/frmEditGrid.cpp new file mode 100644 index 0000000..0c54b31 --- /dev/null +++ b/frm/frmEditGrid.cpp @@ -0,0 +1,3385 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmEditGrid.cpp - Edit Grid Box +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include "frm/frmMain.h" +#include "frm/menu.h" +#include "db/pgQueryThread.h" + +#include +#include + +#include "frm/frmAbout.h" +#include "frm/frmEditGrid.h" +#include "ctl/ctlMenuToolbar.h" +#include "dlg/dlgEditGridOptions.h" +#include "frm/frmHint.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgTable.h" +#include "schema/pgForeignTable.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" +#include "schema/pgPartition.h" + +// wxAUI +#include + +// Icons +#include "images/viewdata.pngc" +#include "images/storedata.pngc" +#include "images/readdata.pngc" +#include "images/delete.pngc" +#include "images/edit_undo.pngc" +#include "images/sortfilter.pngc" +#include "images/help.pngc" +#include "images/clip_copy.pngc" +#include "images/clip_paste.pngc" + +#define CTRLID_LIMITCOMBO 4226 + + +BEGIN_EVENT_TABLE(frmEditGrid, pgFrame) + EVT_ERASE_BACKGROUND( frmEditGrid::OnEraseBackground) + EVT_SIZE( frmEditGrid::OnSize) + EVT_MENU(MNU_REFRESH, frmEditGrid::OnRefresh) + EVT_MENU(MNU_DELETE, frmEditGrid::OnDelete) + EVT_MENU(MNU_SAVE, frmEditGrid::OnSave) + EVT_MENU(MNU_INCLUDEFILTER, frmEditGrid::OnIncludeFilter) + EVT_MENU(MNU_EXCLUDEFILTER, frmEditGrid::OnExcludeFilter) + EVT_MENU(MNU_REMOVEFILTERS, frmEditGrid::OnRemoveFilters) + EVT_MENU(MNU_ASCSORT, frmEditGrid::OnAscSort) + EVT_MENU(MNU_DESCSORT, frmEditGrid::OnDescSort) + EVT_MENU(MNU_REMOVESORT, frmEditGrid::OnRemoveSort) + EVT_MENU(MNU_UNDO, frmEditGrid::OnUndo) + EVT_MENU(MNU_OPTIONS, frmEditGrid::OnOptions) + EVT_MENU(MNU_HELP, frmEditGrid::OnHelp) + EVT_MENU(MNU_CONTENTS, frmEditGrid::OnContents) + EVT_MENU(MNU_COPY, frmEditGrid::OnCopy) + EVT_MENU(MNU_PASTE, frmEditGrid::OnPaste) + EVT_MENU(MNU_LIMITBAR, frmEditGrid::OnToggleLimitBar) + EVT_MENU(MNU_TOOLBAR, frmEditGrid::OnToggleToolBar) + EVT_MENU(MNU_SCRATCHPAD, frmEditGrid::OnToggleScratchPad) + EVT_MENU(MNU_DEFAULTVIEW, frmEditGrid::OnDefaultView) + EVT_MENU(MNU_CLOSE, frmEditGrid::OnClose) + EVT_CLOSE( frmEditGrid::OnCloseWindow) + EVT_KEY_DOWN( frmEditGrid::OnKey) + EVT_GRID_RANGE_SELECT( frmEditGrid::OnGridSelectCells) + EVT_GRID_SELECT_CELL( frmEditGrid::OnCellChange) + EVT_GRID_EDITOR_SHOWN( frmEditGrid::OnEditorShown) + EVT_GRID_EDITOR_HIDDEN( frmEditGrid::OnEditorHidden) + EVT_GRID_CELL_RIGHT_CLICK( frmEditGrid::OnCellRightClick) + EVT_GRID_LABEL_RIGHT_CLICK( frmEditGrid::OnLabelRightClick) + EVT_AUI_PANE_BUTTON( frmEditGrid::OnAuiUpdate) +END_EVENT_TABLE() + + +frmEditGrid::frmEditGrid(frmMain *form, const wxString &_title, pgConn *_conn, pgSchemaObject *obj, bool pkAscending) + : pgFrame(NULL, _title) +{ + closing = false; + + SetIcon(*viewdata_png_ico); + SetFont(settings->GetSystemFont()); + dlgName = wxT("frmEditGrid"); + RestorePosition(-1, -1, 600, 500, 300, 350); + connection = _conn; + mainForm = form; + thread = 0; + relkind = 0; + limit = 0; + relid = (Oid)obj->GetOid(); + editorCell = new sqlCell(); + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + SetMinSize(wxSize(300, 350)); + + CreateStatusBar(); + SetStatusBarPane(-1); + + sqlGrid = new ctlSQLEditGrid(this, CTL_EDITGRID, wxDefaultPosition, wxDefaultSize); + sqlGrid->SetTable(0); +#ifdef __WXMSW__ + sqlGrid->SetDefaultRowSize(sqlGrid->GetDefaultRowSize() + 2, true); +#endif + + // Set up toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + + toolBar->AddTool(MNU_SAVE, wxEmptyString, *storedata_png_bmp, _("Save the changed row."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_REFRESH, wxEmptyString, *readdata_png_bmp, _("Refresh."), wxITEM_NORMAL); + toolBar->AddTool(MNU_UNDO, wxEmptyString, *edit_undo_png_bmp, _("Undo change of data."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_COPY, wxEmptyString, *clip_copy_png_bmp, _("Copy selected lines to clipboard."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_PASTE, wxEmptyString, *clip_paste_png_bmp, _("Paste data from the clipboard."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_DELETE, wxEmptyString, *delete_png_bmp, _("Delete selected rows."), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_OPTIONS, wxEmptyString, *sortfilter_png_bmp, _("Sort/filter options."), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_HELP, wxEmptyString, *help_png_bmp, _("Display help on this window.")); + + toolBar->Realize(); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + toolBar->EnableTool(MNU_DELETE, false); + + // Setup the limit bar +#ifndef __WXMAC__ + cbLimit = new wxComboBox(this, CTRLID_LIMITCOMBO, wxEmptyString, wxPoint(0, 0), wxSize(GetCharWidth() * 12, -1), wxArrayString(), wxCB_DROPDOWN); +#else + cbLimit = new wxComboBox(this, CTRLID_LIMITCOMBO, wxEmptyString, wxPoint(0, 0), wxSize(GetCharWidth() * 24, -1), wxArrayString(), wxCB_DROPDOWN); +#endif + cbLimit->Append(_("No limit")); + cbLimit->Append(_("1000 rows")); + cbLimit->Append(_("500 rows")); + cbLimit->Append(_("100 rows")); + cbLimit->SetValue(_("No limit")); + + // Finally, the scratchpad + scratchPad = new wxTextCtrl(this, -1, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxHSCROLL); + + // Menus + + // File menu + fileMenu = new wxMenu(); + fileMenu->Append(MNU_SAVE, _("&Save\tCtrl-S"), _("Save the changed row.")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_CLOSE, _("&Close\tCtrl-W"), _("Close this window.")); + fileMenu->Enable(MNU_SAVE, false); + + // Edit menu + editMenu = new wxMenu(); + editMenu->Append(MNU_UNDO, _("&Undo\tCtrl-Z"), _("Undo change of data.")); + editMenu->AppendSeparator(); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected cells to clipboard.")); + editMenu->Append(MNU_PASTE, _("&Paste\tCtrl-V"), _("Paste data from the clipboard.")); + editMenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows.")); + editMenu->Enable(MNU_UNDO, false); + editMenu->Enable(MNU_DELETE, false); + + + // View menu + viewMenu = new wxMenu(); + viewMenu->Append(MNU_REFRESH, _("&Refresh\tF5"), _("Refresh.")); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_LIMITBAR, _("&Limit bar\tCtrl-Alt-L"), _("Show or hide the row limit options bar."), wxITEM_CHECK); + viewMenu->Append(MNU_SCRATCHPAD, _("S&cratch pad\tCtrl-Alt-S"), _("Show or hide the scratch pad."), wxITEM_CHECK); + viewMenu->Append(MNU_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + + // Tools menu + toolsMenu = new wxMenu(); + toolsMenu->Append(MNU_OPTIONS, _("&Sort / Filter ..."), _("Sort / Filter options.")); + toolsMenu->AppendSeparator(); + toolsMenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"), _("Display only those rows that have this value in this column.")); + toolsMenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"), _("Display only those rows that do not have this value in this column.")); + toolsMenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"), _("Remove all filters on this table")); + toolsMenu->AppendSeparator(); + toolsMenu->Append(MNU_ASCSORT, _("Sort &Ascending"), _("Append an ASCENDING sort condition based on this column")); + toolsMenu->Append(MNU_DESCSORT, _("Sort &Descending"), _("Append a DESCENDING sort condition based on this column")); + toolsMenu->Append(MNU_REMOVESORT, _("&Remove Sort"), _("Remove all sort conditions")); + + // Help menu + helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help contents"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&Edit grid help"), _("Display help on this window.")); + +#ifdef __WXMAC__ + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); +#endif + + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(toolsMenu, _("&Tools")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + + // Accelerators + wxAcceleratorEntry entries[8]; + + entries[0].Set(wxACCEL_CTRL, (int)'S', MNU_SAVE); + entries[1].Set(wxACCEL_NORMAL, WXK_F5, MNU_REFRESH); + entries[2].Set(wxACCEL_CTRL, (int)'Z', MNU_UNDO); + entries[3].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + entries[4].Set(wxACCEL_CTRL, (int)'C', MNU_COPY); + entries[5].Set(wxACCEL_CTRL, (int)'V', MNU_PASTE); + entries[6].Set(wxACCEL_NORMAL, WXK_DELETE, MNU_DELETE); + entries[7].Set(wxACCEL_CTRL, (int)'W', MNU_CLOSE); + + wxAcceleratorTable accel(8, entries); + SetAcceleratorTable(accel); + sqlGrid->SetAcceleratorTable(accel); + + // Kickstart wxAUI + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(cbLimit, wxAuiPaneInfo().Name(wxT("limitBar")).Caption(_("Limit bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(sqlGrid, wxAuiPaneInfo().Name(wxT("sqlGrid")).Caption(_("Data grid")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(300, 200))); + manager.AddPane(scratchPad, wxAuiPaneInfo().Name(wxT("scratchPad")).Caption(_("Scratch pad")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(300, 150))); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmEditGrid/Perspective-") + wxString(FRMEDITGRID_PERSPECTIVE_VER), &perspective, FRMEDITGRID_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("limitBar")).Caption(_("Limit bar")); + manager.GetPane(wxT("sqlGrid")).Caption(_("Data grid")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + // Sync the View menu options + viewMenu->Check(MNU_LIMITBAR, manager.GetPane(wxT("limitBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + autoOrderBy = false; + if (obj->GetMetaType() == PGM_TABLE || obj->GetMetaType() == GP_PARTITION) + { + pgTable *table = (pgTable *)obj; + + relkind = 'r'; + hasOids = table->GetHasOids(); + tableName = table->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + table->GetQuotedIdentifier(); + primaryKeyColNumbers = table->GetPrimaryKeyColNumbers(); + autoOrderBy = true; // default order by PK/OID will be discarded when a user defines his order + orderBy = table->GetQuotedPrimaryKey(); + if (orderBy.IsEmpty() && hasOids) + orderBy = wxT("oid"); + if (!orderBy.IsEmpty()) + { + if (pkAscending) + { + orderBy.Replace(wxT(","), wxT(" ASC,")); + orderBy += wxT(" ASC"); + } + else + { + orderBy.Replace(wxT(","), wxT(" DESC,")); + orderBy += wxT(" DESC"); + } + } + } + else if (obj->GetMetaType() == PGM_VIEW) + { + pgView *view = (pgView *)obj; + + relkind = 'v'; + hasOids = false; + tableName = view->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + view->GetQuotedIdentifier(); + } + else if (obj->GetMetaType() == PGM_FOREIGNTABLE) + { + pgForeignTable *foreigntable = (pgForeignTable *)obj; + + relkind = 'f'; + hasOids = false; + tableName = foreigntable->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + foreigntable->GetQuotedIdentifier(); + } + else if (obj->GetMetaType() == GP_EXTTABLE) + { + gpExtTable *exttable = (gpExtTable *)obj; + + relkind = 'x'; + hasOids = false; + tableName = exttable->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + exttable->GetQuotedIdentifier(); + } + else if (obj->GetMetaType() == PGM_CATALOGOBJECT) + { + pgCatalogObject *catobj = (pgCatalogObject *)obj; + + relkind = 'v'; + hasOids = false; + tableName = catobj->GetSchema()->GetQuotedFullIdentifier() + wxT(".") + catobj->GetQuotedIdentifier(); + } +} + +void frmEditGrid::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + +void frmEditGrid::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + +void frmEditGrid::OnToggleLimitBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_LIMITBAR)) + manager.GetPane(wxT("limitBar")).Show(true); + else + manager.GetPane(wxT("limitBar")).Show(false); + manager.Update(); +} + +void frmEditGrid::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + manager.GetPane(wxT("toolBar")).Show(true); + else + manager.GetPane(wxT("toolBar")).Show(false); + manager.Update(); +} + +void frmEditGrid::OnToggleScratchPad(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + else + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); +} + +void frmEditGrid::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("limitBar")) + { + viewMenu->Check(MNU_LIMITBAR, false); + } + else if(event.pane->name == wxT("toolBar")) + { + viewMenu->Check(MNU_TOOLBAR, false); + } + else if(event.pane->name == wxT("scratchPad")) + { + viewMenu->Check(MNU_SCRATCHPAD, false); + } + event.Skip(); +} + +void frmEditGrid::OnDefaultView(wxCommandEvent &event) +{ + manager.LoadPerspective(FRMEDITGRID_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("limitBar")).Caption(_("Limit bar")); + manager.GetPane(wxT("sqlGrid")).Caption(_("Data grid")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_LIMITBAR, manager.GetPane(wxT("limitBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); +} + +void frmEditGrid::SetSortCols(const wxString &cols) +{ + if (orderBy != cols) + { + orderBy = cols; + } +} + +void frmEditGrid::SetFilter(const wxString &filter) +{ + if (rowFilter != filter) + { + rowFilter = filter; + } +} + +void frmEditGrid::SetLimit(const int rowlimit) +{ + if (rowlimit != limit) + { + limit = rowlimit; + + if (limit <= 0) + cbLimit->SetValue(_("No limit")); + else + cbLimit->SetValue(wxString::Format(wxPLURAL("%i row", "%i rows", limit), limit)); + } +} + +void frmEditGrid::OnLabelRightClick(wxGridEvent &event) +{ + wxMenu *xmenu = new wxMenu(); + wxArrayInt rows = sqlGrid->GetSelectedRows(); + xmenu->Append(MNU_COPY, _("&Copy"), _("Copy selected cells to clipboard.")); + xmenu->Append(MNU_PASTE, _("&Paste"), _("Paste data from the clipboard.")); + xmenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows.")); + + if ((rows.GetCount()) && (!sqlGrid->IsCurrentCellReadOnly())) + { + xmenu->Enable(MNU_COPY, true); + xmenu->Enable(MNU_DELETE, true); + xmenu->Enable(MNU_PASTE, true); + } + else + { + xmenu->Enable(MNU_COPY, false); + xmenu->Enable(MNU_DELETE, false); + xmenu->Enable(MNU_PASTE, false); + } + sqlGrid->PopupMenu(xmenu); +} + + +void frmEditGrid::OnCellRightClick(wxGridEvent &event) +{ + wxMenu *xmenu = new wxMenu(); + + // If we cannot refresh, assume there is a data thread running. We cannot + // check thread->IsRunning() as it can crash if the thread is in some + // states :-( + if (!toolBar->GetToolEnabled(MNU_REFRESH)) + return; + + sqlGrid->SetGridCursor(event.GetRow(), event.GetCol()); + + xmenu->Append(MNU_INCLUDEFILTER, _("Filter By &Selection"), _("Display only those rows that have this value in this column.")); + xmenu->Append(MNU_EXCLUDEFILTER, _("Filter E&xcluding Selection"), _("Display only those rows that do not have this value in this column.")); + xmenu->Append(MNU_REMOVEFILTERS, _("&Remove Filter"), _("Remove all filters on this table")); + xmenu->InsertSeparator(3); + xmenu->Append(MNU_ASCSORT, _("Sort &Ascending"), _("Append an ASCENDING sort condition based on this column")); + xmenu->Append(MNU_DESCSORT, _("Sort &Descending"), _("Append a DESCENDING sort condition based on this column")); + xmenu->Append(MNU_REMOVESORT, _("&Remove Sort"), _("Remove all sort conditions")); + + xmenu->Enable(MNU_INCLUDEFILTER, true); + xmenu->Enable(MNU_EXCLUDEFILTER, true); + xmenu->Enable(MNU_REMOVEFILTERS, true); + xmenu->Enable(MNU_ASCSORT, true); + xmenu->Enable(MNU_DESCSORT, true); + xmenu->Enable(MNU_REMOVESORT, true); + + sqlGrid->PopupMenu(xmenu); +} + + +void frmEditGrid::OnCellChange(wxGridEvent &event) +{ + sqlTable *table = sqlGrid->GetTable(); + bool doSkip = true; + + if (table) + { + if (table->LastRow() >= 0) + { + if (table->LastRow() != event.GetRow()) + { + doSkip = DoSave(); + } + } + else if (sqlGrid->GetGridCursorRow() != event.GetRow()) + { + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + } + } + + if (doSkip) + event.Skip(); +} + + +void frmEditGrid::OnIncludeFilter(wxCommandEvent &event) +{ + int curcol = sqlGrid->GetGridCursorCol(); + int currow = sqlGrid->GetGridCursorRow(); + + if (curcol == -1 || currow == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString new_filter_string; + + size_t old_filter_string_length = GetFilter().Trim().Len(); + + if (old_filter_string_length > 0) + { + new_filter_string = GetFilter().Trim() + wxT(" \n AND "); + } + + if (table->IsColText(curcol)) + { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NULL "); + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) + { + new_filter_string += column_label + wxT(" = ''"); + } + else + { + new_filter_string += column_label + wxT(" = ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); + } + } + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NULL "); + } + else + { + new_filter_string += column_label + wxT(" = ") + sqlGrid->GetCellValue(currow, curcol); + } + } + + SetFilter(new_filter_string); + + Go(); +} + + +void frmEditGrid::OnExcludeFilter(wxCommandEvent &event) +{ + int curcol = sqlGrid->GetGridCursorCol(); + int currow = sqlGrid->GetGridCursorRow(); + + if (curcol == -1 || currow == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString new_filter_string; + + size_t old_filter_string_length = GetFilter().Trim().Len(); + + if (old_filter_string_length > 0) + { + new_filter_string = GetFilter().Trim() + wxT(" \n AND "); + } + + if (table->IsColText(curcol)) + { + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NOT NULL "); + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol) == wxT("\'\'")) + { + new_filter_string += column_label + wxString::Format(wxT(" IS DISTINCT FROM '' ")) ; + } + else + { + new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + connection->qtDbString(sqlGrid->GetCellValue(currow, curcol)) + wxT(" "); + } + } + } + else + { + + if (sqlGrid->GetCellValue(currow, curcol).IsNull()) + { + new_filter_string += column_label + wxT(" IS NOT NULL ") ; + } + else + { + new_filter_string += column_label + wxT(" IS DISTINCT FROM ") + sqlGrid->GetCellValue(currow, curcol); + } + } + + SetFilter(new_filter_string); + + Go(); +} + + +void frmEditGrid::OnRemoveFilters(wxCommandEvent &event) +{ + SetFilter(wxT("")); + + Go(); +} + + +void frmEditGrid::OnAscSort(wxCommandEvent &ev) +{ + int curcol = sqlGrid->GetGridCursorCol(); + + if (curcol == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString old_sort_string, new_sort_string; + + if (autoOrderBy) + { + autoOrderBy = false; + old_sort_string = wxT(""); + } + else + old_sort_string = GetSortCols().Trim(); + + if (old_sort_string.Find(column_label) == wxNOT_FOUND) + { + if (old_sort_string.Len() > 0) + new_sort_string = old_sort_string + wxT(" , "); + + new_sort_string += column_label + wxT(" ASC "); + } + else + { + if (old_sort_string.Find(column_label + wxT(" ASC")) == wxNOT_FOUND) + { + // Previous occurrence was for DESCENDING sort + new_sort_string = old_sort_string; + new_sort_string.Replace(column_label + wxT(" DESC"), column_label + wxT(" ASC")); + } + else + { + // Previous occurrence was for ASCENDING sort. Nothing to do + new_sort_string = old_sort_string; + } + } + + SetSortCols(new_sort_string); + + Go(); +} + + +void frmEditGrid::OnDescSort(wxCommandEvent &ev) +{ + int curcol = sqlGrid->GetGridCursorCol(); + + if (curcol == -1) + return; + + sqlTable *table = sqlGrid->GetTable(); + wxString column_label = qtIdent(table->GetColLabelValueUnformatted(curcol)); + wxString old_sort_string, new_sort_string; + + if (autoOrderBy) + { + autoOrderBy = false; + old_sort_string = wxT(""); + } + else + old_sort_string = GetSortCols().Trim(); + + if (old_sort_string.Find(column_label) == wxNOT_FOUND) + { + if (old_sort_string.Len() > 0) + new_sort_string = old_sort_string + wxT(" , "); + + new_sort_string += column_label + wxT(" DESC "); + } + else + { + if (old_sort_string.Find(column_label + wxT(" DESC")) == wxNOT_FOUND) + { + // Previous occurrence was for ASCENDING sort + new_sort_string = old_sort_string; + new_sort_string.Replace(column_label + wxT(" ASC"), column_label + wxT(" DESC")); + } + else + { + // Previous occurrence was for DESCENDING sort. Nothing to do + new_sort_string = old_sort_string; + } + } + + SetSortCols(new_sort_string); + + Go(); +} + + +void frmEditGrid::OnRemoveSort(wxCommandEvent &ev) +{ + SetSortCols(wxT("")); + + Go(); +} + + +void frmEditGrid::OnCopy(wxCommandEvent &ev) +{ + wxWindow *wnd = FindFocus(); + if (wnd == scratchPad) + { + scratchPad->Copy(); + } + else + { + if (editorCell->IsSet()) + { + if (wxTheClipboard->Open()) + { + if (sqlGrid->GetTable()->IsColText(sqlGrid->GetGridCursorCol())) + { + wxStyledTextCtrl *text = (wxStyledTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text && !text->GetSelectedText().IsEmpty()) + { + wxTheClipboard->SetData(new wxTextDataObject(text->GetSelectedText())); + SetStatusText(_("Data from one cell copied to clipboard.")); + } + } + else + { + wxTextCtrl *text = (wxTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text && !text->GetStringSelection().IsEmpty()) + { + wxTheClipboard->SetData(new wxTextDataObject(text->GetStringSelection())); + SetStatusText(_("Data from one cell copied to clipboard.")); + } + } + + wxTheClipboard->Close(); + } + } + else if(sqlGrid->GetNumberRows() > 0) + { + int copied; + copied = sqlGrid->Copy(false); + SetStatusText(wxString::Format( + wxPLURAL("Data from %d row copied to clipboard.", "Data from %d rows copied to clipboard.", copied), + copied)); + } + } +} + + +void frmEditGrid::OnPaste(wxCommandEvent &ev) +{ + wxWindow *wnd = FindFocus(); + if (wnd == scratchPad) + { + scratchPad->Paste(); + } + else if (editorCell->IsSet()) + { + if (wxTheClipboard->Open()) + { + if (wxTheClipboard->IsSupported(wxDF_TEXT)) + { + wxTextDataObject data; + wxTheClipboard->GetData(data); + wxControl *ed = sqlGrid->GetCellEditor(editorCell->GetRow(), editorCell->GetCol())->GetControl(); + if (ed->IsKindOf(CLASSINFO(wxStyledTextCtrl))) + { + wxStyledTextCtrl *txtEd = (wxStyledTextCtrl *)ed; + txtEd->ReplaceSelection(data.GetText()); + } + else if (ed->IsKindOf(CLASSINFO(wxCheckBox))) + { + wxCheckBox *boolEd = (wxCheckBox *)ed; + + if (data.GetText().Lower() == wxT("true")) + boolEd->Set3StateValue(wxCHK_CHECKED); + else if (data.GetText().Lower() == wxT("false")) + boolEd->Set3StateValue(wxCHK_UNCHECKED); + else + boolEd->Set3StateValue(wxCHK_UNDETERMINED); + } + else if (ed->IsKindOf(CLASSINFO(wxTextCtrl))) + { + wxTextCtrl *txtEd = (wxTextCtrl *)ed; + long x, y; + txtEd->GetSelection(&x, &y); + txtEd->Replace(x, y, data.GetText()); + //txtEd->SetValue(data.GetText()); + } + } + wxTheClipboard->Close(); + } + } + else if(sqlGrid->GetNumberRows() > 0) + { + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + wxYES_NO | wxICON_QUESTION | wxCANCEL); + switch (msg.ShowModal()) + { + case wxID_YES: + if (!DoSave()) + return; + break; + + case wxID_CANCEL: + return; + break; + + case wxID_NO: + CancelChange(); + break; + } + } + + if (sqlGrid->GetTable()->Paste()) + { + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + } + } +} + +void frmEditGrid::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("editgrid"), HELP_PGADMIN); +} + +void frmEditGrid::OnContents(wxCommandEvent &ev) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + +void frmEditGrid::OnKey(wxKeyEvent &event) +{ + int curcol = sqlGrid->GetGridCursorCol(); + int currow = sqlGrid->GetGridCursorRow(); + + if (curcol == -1 || currow == -1) + return; + + int keycode = event.GetKeyCode(); + wxCommandEvent ev; + + switch (keycode) + { + case WXK_DELETE: + { + if (editorCell->IsSet() || !toolBar->GetToolEnabled(MNU_DELETE)) + { + if (!sqlGrid->IsCurrentCellReadOnly()) + { + sqlGrid->EnableCellEditControl(); + sqlGrid->ShowCellEditControl(); + + wxGridCellEditor *edit = sqlGrid->GetCellEditor(currow, curcol); + if (edit) + { + wxControl *ctl = edit->GetControl(); + if (ctl) + { + wxStyledTextCtrl *txt = wxDynamicCast(ctl, wxStyledTextCtrl); + if (txt) + txt->SetText(wxEmptyString); + } + edit->DecRef(); + } + } + } + else + { + OnDelete(ev); + } + return; + } + case WXK_RETURN: + case WXK_NUMPAD_ENTER: + // check for shift etc. + if (event.ControlDown() || event.ShiftDown()) + { + // Inject a RETURN into the control + wxGridCellEditor *edit = sqlGrid->GetCellEditor(currow, curcol); + if (edit) + { + wxControl *ctl = edit->GetControl(); + if (ctl) + { + wxStyledTextCtrl *txt = wxDynamicCast(ctl, wxStyledTextCtrl); + if (txt) + txt->ReplaceSelection(END_OF_LINE); + } + edit->DecRef(); + } + return; + } + else + { + if( keycode != WXK_NUMPAD_ENTER ) + { + // if we are at the end of the row + if (curcol == sqlGrid->GetNumberCols() - 1) + { + // we first get to the first column of the next row + curcol = 0; + currow++; + + // * if the displayed object is a table, + // we first need to make sure that the new selected + // cell is read/write, otherwise we need to select + // the next one + // * if the displayed object is not a table (for + // example, a view), all cells are readonly, so + // we skip that part + if (relkind == 'r') + { + // locate first editable column + while (curcol < sqlGrid->GetNumberCols() && sqlGrid->IsReadOnly(currow, curcol)) + curcol++; + // next line is completely read-only + if (curcol == sqlGrid->GetNumberCols()) + return; + } + } + else + curcol++; + } + else // ( keycode==WXK_NUMPAD_ENTER ) + { + currow++; + } + + OnSave(ev); + sqlGrid->SetGridCursor(currow, curcol); + + return; + } + + case WXK_TAB: + if (event.ControlDown()) + { + wxStyledTextCtrl *text = (wxStyledTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text) + text->SetText(wxT("\t")); + return; + } + + break; + + case WXK_ESCAPE: + CancelChange(); + break; + + default: + if (sqlGrid->IsEditable() && keycode >= WXK_SPACE && keycode < WXK_START) + { + if (sqlGrid->IsCurrentCellReadOnly()) + return; + + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + } + break; + } + event.Skip(); +} + +void frmEditGrid::OnClose(wxCommandEvent &event) +{ + this->Close(); +} + +void frmEditGrid::OnCloseWindow(wxCloseEvent &event) +{ + // We need to call OnCellChange to check if some cells for the row have been changed + wxGridEvent evt; + OnCellChange(evt); + + // If MNU_SAVE item is still enabled, we need to ask about the unsaved data + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + int flag = wxYES_NO | wxICON_QUESTION; + if (event.CanVeto()) + flag |= wxCANCEL; + + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + flag); + switch (msg.ShowModal()) + { + case wxID_YES: + { + if (!DoSave()) + { + event.Veto(); + return; + } + break; + } + case wxID_CANCEL: + event.Veto(); + return; + } + } + Abort(); + Destroy(); +} + + +void frmEditGrid::OnUndo(wxCommandEvent &event) +{ + sqlGrid->DisableCellEditControl(); + sqlGrid->GetTable()->UndoLine(sqlGrid->GetGridCursorRow()); + sqlGrid->ForceRefresh(); + + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); +} + + +void frmEditGrid::OnRefresh(wxCommandEvent &event) +{ + if (!toolBar->GetToolEnabled(MNU_REFRESH)) + return; + + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + wxYES_NO | wxICON_QUESTION | wxCANCEL); + switch (msg.ShowModal()) + { + case wxID_YES: + { + if (!DoSave()) + return; + break; + } + case wxID_CANCEL: + return; + } + } + + sqlGrid->DisableCellEditControl(); + Go(); +} + + +void frmEditGrid::OnSave(wxCommandEvent &event) +{ + if (sqlGrid->GetBatchCount() == 0) + DoSave(); +} + +bool frmEditGrid::DoSave() +{ + sqlGrid->HideCellEditControl(); + sqlGrid->SaveEditControlValue(); + sqlGrid->DisableCellEditControl(); + + if (!sqlGrid->GetTable()->StoreLine()) + return false; + + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + + return true; +} + +void frmEditGrid::CancelChange() +{ + sqlGrid->HideCellEditControl(); + sqlGrid->SaveEditControlValue(); + sqlGrid->DisableCellEditControl(); + + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + + sqlGrid->GetTable()->UndoLine(sqlGrid->GetGridCursorRow()); + sqlGrid->ForceRefresh(); +} + + +void frmEditGrid::OnOptions(wxCommandEvent &event) +{ + if (toolBar->GetToolEnabled(MNU_SAVE)) + { + wxMessageDialog msg(this, _("There is unsaved data in a row.\nDo you want to store to the database?"), _("Unsaved data"), + wxYES_NO | wxICON_QUESTION | wxCANCEL); + switch (msg.ShowModal()) + { + case wxID_YES: + { + if (!DoSave()) + return; + break; + } + case wxID_CANCEL: + return; + case wxID_NO: + CancelChange(); + } + } + + dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); + if (winOptions->ShowModal()) + Go(); +} + + +template < class T > +int ArrayCmp(T *a, T *b) +{ + if (*a == *b) + return 0; + + if (*a > *b) + return 1; + else + return -1; +} + +void frmEditGrid::OnDelete(wxCommandEvent &event) +{ + // Don't bugger about with keypresses to the scratch pad. + if (FindFocus() == scratchPad) + { + event.Skip(); + return; + } + + if (editorCell->IsSet()) + { + if (sqlGrid->GetTable()->IsColBoolean(sqlGrid->GetGridCursorCol())) + return; + + if (sqlGrid->GetTable()->IsColText(sqlGrid->GetGridCursorCol())) + { + wxStyledTextCtrl *text = (wxStyledTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text && text->GetCurrentPos() <= text->GetTextLength()) + { + if (text->GetSelectionStart() == text->GetSelectionEnd()) + text->SetSelection(text->GetSelectionStart(), text->GetSelectionStart() + 1); + text->Clear(); + } + } + else + { + wxTextCtrl *text = (wxTextCtrl *)sqlGrid->GetCellEditor(sqlGrid->GetGridCursorRow(), sqlGrid->GetGridCursorCol())->GetControl(); + if (text) + { + long x, y; + text->GetSelection(&x, &y); + if (x != y) + text->Remove(x, x + y + 1); + else + text->Remove(x, x + 1); + } + } + return; + } + + // If the delete button is disabled, don't try to delete anything + if (!toolBar->GetToolEnabled(MNU_DELETE)) + return; + + wxArrayInt delrows = sqlGrid->GetSelectedRows(); + int i = delrows.GetCount(); + + if (i == 0) + return; + + wxString prompt; + if (i == 1) + prompt = _("Are you sure you wish to delete the selected row?"); + else + prompt.Printf(_("Are you sure you wish to delete the %d selected rows?"), i); + + wxMessageDialog msg(this, prompt, _("Delete rows?"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + return; + + sqlGrid->BeginBatch(); + + // Sort the grid so we always delete last->first, otherwise we + // could end up deleting anything because the array returned by + // GetSelectedRows is in the order that rows were selected by + // the user. + delrows.Sort(ArrayCmp); + + // don't care a lot about optimizing here; doing it line by line + // just as sqlTable::DeleteRows does + bool show_continue_message = true; + while (i--) + { + if (!sqlGrid->DeleteRows(delrows.Item(i), 1) && + i > 0 && + show_continue_message) + { + wxMessageDialog msg(this, wxString::Format(wxPLURAL( + "There was an error deleting the previous record.\nAre you sure you wish to delete the remaining %d row?", + "There was an error deleting the previous record.\nAre you sure you wish to delete the remaining %d rows?", + i), i), _("Delete more records ?"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + break; + else + show_continue_message = false; + } + } + + + sqlGrid->EndBatch(); + + SetStatusText(wxString::Format(wxPLURAL("%d row.", "%d rows.", sqlGrid->GetTable()->GetNumberStoredRows()), sqlGrid->GetTable()->GetNumberStoredRows()), 0); +} + + +void frmEditGrid::OnEditorShown(wxGridEvent &event) +{ + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + editorCell->SetCell(event.GetRow(), event.GetCol()); + + event.Skip(); +} + + +void frmEditGrid::OnEditorHidden(wxGridEvent &event) +{ + editorCell->ClearCell(); +} + + +void frmEditGrid::OnGridSelectCells(wxGridRangeSelectEvent &event) +{ + if (sqlGrid->IsEditable()) + { + wxArrayInt rows = sqlGrid->GetSelectedRows(); + + bool enable = rows.GetCount() > 0; + if (enable) + { + wxCommandEvent nullEvent; + OnSave(event); + + // check if a readonly line is selected + int row, col; + size_t i; + + for (i = 0 ; i < rows.GetCount() ; i++) + { + row = rows.Item(i); + bool lineEnabled = false; + + if (row == sqlGrid->GetNumberRows() - 1) + { + // the (*) line may not be deleted/copied + enable = false; + break; + } + for (col = 0 ; col < sqlGrid->GetNumberCols() ; col++) + { + if (!sqlGrid->IsReadOnly(row, col)) + { + lineEnabled = true; + break; + } + } + + if (!lineEnabled) + { + enable = false; + break; + } + } + } + toolBar->EnableTool(MNU_DELETE, enable); + editMenu->Enable(MNU_DELETE, enable); + } + event.Skip(); +} + + +void frmEditGrid::ShowForm(bool filter) +{ + bool abort = false; + + if (relkind == 'r' || relkind == 'v' || relkind == 'x' || relkind == 'f') + { + if (filter) + { + dlgEditGridOptions *winOptions = new dlgEditGridOptions(this, connection, tableName, sqlGrid); + abort = !(winOptions->ShowModal()); + } + if (abort) + { + // Hack to ensure there's a table for ~wxGrid() to delete + sqlGrid->CreateGrid(0, 0); + sqlGrid->SetTable(0); + Close(); + Destroy(); + } + else + { + Show(true); + Go(); + } + } + else + { + wxLogError(__("No Table or view.")); + // Hack to ensure there's a table for ~wxGrid() to delete + sqlGrid->CreateGrid(0, 0); + Close(); + Destroy(); + } +} + +void frmEditGrid::Go() +{ + long templong; + + if (cbLimit->GetValue() != wxT("") && + cbLimit->GetValue() != _("No limit") && + !cbLimit->GetValue().BeforeFirst(' ').ToLong(&templong)) + { + wxLogError(_("The row limit must be an integer number or 'No limit'")); + return; + } + + if (cbLimit->GetValue() == _("No limit")) + SetLimit(0); + else + { + cbLimit->GetValue().BeforeFirst(' ').ToLong(&templong); + SetLimit(templong); + } + + // Check we have access + if (connection->ExecuteScalar(wxT("SELECT count(*) FROM ") + tableName + wxT(" WHERE false")) == wxT("")) + return; + + SetStatusText(_("Refreshing data, please wait."), 0); + + toolBar->EnableTool(MNU_REFRESH, false); + viewMenu->Enable(MNU_REFRESH, false); + toolBar->EnableTool(MNU_OPTIONS, false); + toolsMenu->Enable(MNU_OPTIONS, false); + toolsMenu->Enable(MNU_INCLUDEFILTER, false); + toolsMenu->Enable(MNU_EXCLUDEFILTER, false); + toolsMenu->Enable(MNU_REMOVEFILTERS, false); + toolsMenu->Enable(MNU_ASCSORT, false); + toolsMenu->Enable(MNU_DESCSORT, false); + toolsMenu->Enable(MNU_REMOVESORT, false); + + wxString qry = wxT("SELECT "); + if (hasOids) + qry += wxT("oid, "); + qry += wxT("* FROM ") + tableName; + if (!rowFilter.IsEmpty()) + { + qry += wxT(" WHERE ") + rowFilter; + } + if (!orderBy.IsEmpty()) + { + qry += wxT("\n ORDER BY ") + orderBy; + } + if (limit > 0) + qry += wxT(" LIMIT ") + wxString::Format(wxT("%i"), limit); + + thread = new pgQueryThread(connection, qry); + if (thread->Create() != wxTHREAD_NO_ERROR) + { + Abort(); + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + + return; + } + + thread->Run(); + + while (thread && thread->IsRunning()) + { + wxTheApp->Yield(true); + wxMilliSleep(10); + } + + // Brute force check to ensure the user didn't get bored and close the window + if (closing) + return; + + if (!thread) + { + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + return; + } + + if (!thread->DataValid()) + { + Abort(); + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + return; + } + + SetStatusText(wxString::Format(wxPLURAL("%d row.", "%d rows.", (int)thread->DataSet()->NumRows()), (int)thread->DataSet()->NumRows()), 0); + + sqlGrid->BeginBatch(); + + // to force the grid to create scrollbars, we make sure the size so small that scrollbars are needed + // later, we will resize the grid's parent to force the correct size (now including scrollbars, even if + // they are suppressed initially. Win32 won't need this. + // !!! This hack breaks columns auto-sizing ( GetClientSize().GetWidth() is used in ctlSQLGrid::AutoSizeColumns() ) + // !!! Is it still required? + //sqlGrid->SetSize(10, 10); + + sqlGrid->SetTable(new sqlTable(connection, thread, tableName, relid, hasOids, primaryKeyColNumbers, relkind), true); + sqlGrid->AutoSizeColumns(false); + + sqlGrid->EndBatch(); + + toolBar->EnableTool(MNU_REFRESH, true); + viewMenu->Enable(MNU_REFRESH, true); + toolBar->EnableTool(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_OPTIONS, true); + toolsMenu->Enable(MNU_INCLUDEFILTER, true); + toolsMenu->Enable(MNU_EXCLUDEFILTER, true); + toolsMenu->Enable(MNU_REMOVEFILTERS, true); + toolsMenu->Enable(MNU_ASCSORT, true); + toolsMenu->Enable(MNU_DESCSORT, true); + toolsMenu->Enable(MNU_REMOVESORT, true); + + manager.Update(); + + if (!hasOids && primaryKeyColNumbers.IsEmpty() && relkind == 'r') + frmHint::ShowHint(this, HINT_READONLY_NOPK, tableName); + + // Set the thread variable to zero so we don't try to + // abort it if the user cancels now. + thread = 0; +} + + +frmEditGrid::~frmEditGrid() +{ + closing = true; + + mainForm->RemoveFrame(this); + + settings->Write(wxT("frmEditGrid/Perspective-") + wxString(FRMEDITGRID_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + + if (connection) + delete connection; +} + + +void frmEditGrid::Abort() +{ + if (sqlGrid->GetTable()) + { + sqlGrid->HideCellEditControl(); + sqlGrid->SetTable(0); + } + + if (thread) + { + SetStatusText(_("aborting."), 0); + if (thread->IsRunning()) + { + thread->CancelExecution(); + thread->Wait(); + } + delete thread; + thread = 0; + } +} + + +ctlSQLEditGrid::ctlSQLEditGrid(wxFrame *parent, wxWindowID id, const wxPoint &pos, const wxSize &size) + : ctlSQLGrid(parent, id, pos, size) +{ +} + +bool ctlSQLEditGrid::CheckRowPresent(int row) +{ + return GetTable()->CheckInCache(row); +} + +void ctlSQLEditGrid::ResizeEditor(int row, int col) +{ + + if (GetTable()->needsResizing(col)) + { + wxGridCellAttr *attr = GetCellAttr(row, col); + wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); + if ( renderer ) + { + wxClientDC dc(GetGridWindow()); + wxSize size = renderer->GetBestSize(*this, *attr, dc, row, col); + renderer->DecRef(); + + int w = wxMax(size.GetWidth(), 15) + 20; + int h = wxMax(size.GetHeight(), 15) + 20; + + + wxGridCellEditor *editor = attr->GetEditor(this, row, col); + if (editor) + { + wxRect cellRect = CellToRect(m_currentCellCoords); + wxRect rect = cellRect; + rect.SetWidth(w); + rect.SetHeight(h); + + // we might have scrolled + CalcUnscrolledPosition(0, 0, &w, &h); + rect.SetLeft(rect.GetLeft() - w); + rect.SetTop(rect.GetTop() - h); + + // Clip rect to client size + GetClientSize(&w, &h); + rect.SetRight(wxMin(rect.GetRight(), w)); + rect.SetBottom(wxMin(rect.GetBottom(), h)); + + // but not smaller than original cell + rect.SetWidth(wxMax(cellRect.GetWidth(), rect.GetWidth())); + rect.SetHeight(wxMax(cellRect.GetHeight(), rect.GetHeight())); + + editor->SetSize(rect); + editor->DecRef(); + } + } + + attr->DecRef(); + } +} + +wxArrayInt ctlSQLEditGrid::GetSelectedRows() const +{ + wxArrayInt rows, rows2; + + wxGridCellCoordsArray tl = GetSelectionBlockTopLeft(), br = GetSelectionBlockBottomRight(); + + int maxCol = ((ctlSQLEditGrid *)this)->GetNumberCols() - 1; + size_t i; + for (i = 0 ; i < tl.GetCount() ; i++) + { + wxGridCellCoords c1 = tl.Item(i), c2 = br.Item(i); + if (c1.GetCol() != 0 || c2.GetCol() != maxCol) + return rows2; + + int j; + for (j = c1.GetRow() ; j <= c2.GetRow() ; j++) + rows.Add(j); + } + + rows2 = wxGrid::GetSelectedRows(); + + rows.Sort(ArrayCmp); + rows2.Sort(ArrayCmp); + + size_t i2 = 0, cellRowMax = rows.GetCount(); + + for (i = 0 ; i < rows2.GetCount() ; i++) + { + int row = rows2.Item(i); + while (i2 < cellRowMax && rows.Item(i2) < row) + i2++; + if (i2 == cellRowMax || row != rows.Item(i2)) + rows.Add(row); + } + + return rows; +} + + +class sqlGridTextEditor : public wxGridCellTextEditor +{ +public: + virtual wxGridCellEditor *Clone() const + { + return new sqlGridTextEditor(); + } + void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler); + void BeginEdit(int row, int col, wxGrid *grid); + + +#if wxCHECK_VERSION(2, 9, 0) + void ApplyEdit(int row, int col, wxGrid *grid); + bool EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *); +#else + bool EndEdit(int row, int col, wxGrid *grid); +#endif + wxString GetValue() const; + virtual void Reset() + { + DoReset(m_startValue); + } + void StartingKey(wxKeyEvent &event); + +protected: + void DoBeginEdit(const wxString &startValue); + wxStyledTextCtrl *Text() const + { + return (wxStyledTextCtrl *)m_control; + } + void DoReset(const wxString &startValue); + + wxString m_startValue; +}; + + + + +void sqlGridTextEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + int flags = wxSTC_WRAP_NONE; + + m_control = new wxStyledTextCtrl(parent, id, + wxDefaultPosition, wxDefaultSize, flags + ); + + wxGridCellEditor::Create(parent, id, evtHandler); +} + + +void sqlGridTextEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + m_startValue = grid->GetTable()->GetValue(row, col); + DoBeginEdit(m_startValue); + ((ctlSQLEditGrid *)grid)->ResizeEditor(row, col); +} + +void sqlGridTextEditor::DoBeginEdit(const wxString &startValue) +{ + Text()->SetMarginWidth(1, 0); + Text()->SetText(startValue); + Text()->SetCurrentPos(Text()->GetTextLength()); + Text()->SetUseHorizontalScrollBar(false); + Text()->SetUseVerticalScrollBar(false); + Text()->SetSelection(0, -1); + Text()->SetFocus(); +} + +#if wxCHECK_VERSION(2, 9, 0) +void sqlGridTextEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + wxString value = Text()->GetText(); + grid->GetTable()->SetValue(row, col, value); +} +#endif + +#if wxCHECK_VERSION(2, 9, 0) +bool sqlGridTextEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *) +#else +bool sqlGridTextEditor::EndEdit(int row, int col, wxGrid *grid) +#endif +{ + bool changed = false; + wxString value = Text()->GetText(); + + if (value != m_startValue) + changed = true; + +#if !wxCHECK_VERSION(2, 9, 0) + if (changed) + grid->GetTable()->SetValue(row, col, value); +#endif + + return changed; +} + +wxString sqlGridTextEditor::GetValue() const +{ + return Text()->GetText(); +} + +void sqlGridTextEditor::DoReset(const wxString &startValue) +{ + Text()->SetText(startValue); + Text()->SetSelection(-1, -1); +} + +void sqlGridTextEditor::StartingKey(wxKeyEvent &event) +{ + wxChar ch; + +#if wxUSE_UNICODE + ch = event.GetUnicodeKey(); + if (ch <= 127) + ch = (wxChar)event.GetKeyCode(); +#else + ch = (wxChar)event.GetKeyCode(); +#endif + + if (ch != (wxChar)WXK_BACK) + { + Text()->SetText(ch); + Text()->GotoPos(Text()->GetLength()); + } +} + +class sqlGridNumericEditor : public wxGridCellTextEditor +{ +public: + sqlGridNumericEditor(int len = -1, int prec = -1) + { + numlen = len; + numprec = prec; + } + virtual wxGridCellEditor *Clone() const + { + return new sqlGridNumericEditor(numlen, numprec); + } + virtual void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler); + + virtual bool IsAcceptedKey(wxKeyEvent &event); + virtual void BeginEdit(int row, int col, wxGrid *grid); +#if wxCHECK_VERSION(2, 9, 0) + void ApplyEdit(int row, int col, wxGrid *grid); + bool EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *); +#else + bool EndEdit(int row, int col, wxGrid *grid); +#endif + + virtual void Reset() + { + DoReset(m_startValue); + } + virtual void StartingKey(wxKeyEvent &event); + virtual void SetParameters(const wxString ¶ms); + +protected: + int numlen, numprec; + wxString m_startValue; + +}; + + + +void sqlGridNumericEditor::StartingKey(wxKeyEvent &event) +{ + int keycode = event.GetKeyCode(); + bool allowed = false; + + switch (keycode) + { + case WXK_DECIMAL: + case WXK_NUMPAD_DECIMAL: + case '.': + if (numprec) + allowed = true; + break; + case '+': + case WXK_ADD: + case WXK_NUMPAD_ADD: + case '-': + case WXK_SUBTRACT: + case WXK_NUMPAD_SUBTRACT: + + case WXK_NUMPAD0: + case WXK_NUMPAD1: + case WXK_NUMPAD2: + case WXK_NUMPAD3: + case WXK_NUMPAD4: + case WXK_NUMPAD5: + case WXK_NUMPAD6: + case WXK_NUMPAD7: + case WXK_NUMPAD8: + case WXK_NUMPAD9: + allowed = true; + break; + default: + if (wxIsdigit(keycode)) + allowed = true; + break; + + } + if (allowed) + wxGridCellTextEditor::StartingKey(event); + else + event.Skip(); +} + + + +bool sqlGridNumericEditor::IsAcceptedKey(wxKeyEvent &event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + int keycode = event.GetKeyCode(); + switch ( keycode ) + { + case WXK_DECIMAL: + case WXK_NUMPAD_DECIMAL: + return (numprec != 0); + + case '+': + case WXK_ADD: + case WXK_NUMPAD_ADD: + case '-': + case WXK_SUBTRACT: + case WXK_NUMPAD_SUBTRACT: + + case WXK_NUMPAD0: + case WXK_NUMPAD1: + case WXK_NUMPAD2: + case WXK_NUMPAD3: + case WXK_NUMPAD4: + case WXK_NUMPAD5: + case WXK_NUMPAD6: + case WXK_NUMPAD7: + case WXK_NUMPAD8: + case WXK_NUMPAD9: + return true; + default: + return wxIsdigit(keycode) != 0; + } + } + + return false; +} + + + +void sqlGridNumericEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + m_startValue = grid->GetTable()->GetValue(row, col); + + + wxString value = m_startValue; + // localize value here + + DoBeginEdit(value); +} + +#if wxCHECK_VERSION(2, 9, 0) +void sqlGridNumericEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + wxString value = Text()->GetValue(); + grid->GetTable()->SetValue(row, col, value); + m_startValue = wxEmptyString; + Text()->SetValue(m_startValue); +} +#endif + +#if wxCHECK_VERSION(2, 9, 0) +bool sqlGridNumericEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *) +#else +bool sqlGridNumericEditor::EndEdit(int row, int col, wxGrid *grid) +#endif +{ + wxASSERT_MSG(m_control, + wxT("The sqlGridNumericEditor must be Created first!")); + + bool changed = false; + wxString value = Text()->GetValue(); + + // de-localize value here + + if (value != m_startValue) + changed = true; + +#if !wxCHECK_VERSION(2, 9, 0) + if (changed) + grid->GetTable()->SetValue(row, col, value); + + m_startValue = wxEmptyString; + Text()->SetValue(m_startValue); +#endif + return changed; +} + + +void sqlGridNumericEditor::SetParameters(const wxString ¶ms) +{ + if ( !params ) + { + // reset to default + numlen = -1; + numprec = -1; + } + else + { + long tmp; + if ( params.BeforeFirst(wxT(',')).ToLong(&tmp) ) + { + numlen = (int)tmp; + + if ( params.AfterFirst(wxT(',')).ToLong(&tmp) ) + { + numprec = (int)tmp; + + // skip the error message below + return; + } + } + } +} + + +void sqlGridNumericEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + m_control = new wxTextCtrl(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize); + + wxGridCellEditor::Create(parent, id, evtHandler); + Text()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); +} + + +////////////////////////////////////////////////////////////////////// +// Bool editor +////////////////////////////////////////////////////////////////////// + +class sqlGridBoolEditor : public wxGridCellEditor +{ +public: + sqlGridBoolEditor() { } + + virtual void Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler); + + virtual void SetSize(const wxRect &rect); + virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL); + + virtual bool IsAcceptedKey(wxKeyEvent &event); + virtual void BeginEdit(int row, int col, wxGrid *grid); + +#if wxCHECK_VERSION(2, 9, 0) + virtual void ApplyEdit(int row, int col, wxGrid *grid); // pure virtual in wx 2.9+, doesn't exist in prior versions + virtual bool EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *); +#else + virtual bool EndEdit(int row, int col, wxGrid *grid); +#endif + + virtual void Reset(); + virtual void StartingClick(); + virtual void StartingKey(wxKeyEvent &event); + + virtual wxGridCellEditor *Clone() const + { + return new sqlGridBoolEditor; + } + + virtual wxString GetValue() const; + +protected: + wxCheckBox *CBox() const + { + return (wxCheckBox *)m_control; + } + +private: + wxCheckBoxState m_startValue; + + DECLARE_NO_COPY_CLASS(sqlGridBoolEditor) +}; + + +void sqlGridBoolEditor::Create(wxWindow *parent, wxWindowID id, wxEvtHandler *evtHandler) +{ + m_control = new wxCheckBox(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxNO_BORDER | wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER); + + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void sqlGridBoolEditor::SetSize(const wxRect &r) +{ + bool resize = false; + wxSize size = m_control->GetSize(); + wxCoord minSize = wxMin(r.width, r.height); + + // check if the checkbox is not too big/small for this cell + wxSize sizeBest = m_control->GetBestSize(); + if ( !(size == sizeBest) ) + { + // reset to default size if it had been made smaller + size = sizeBest; + + resize = true; + } + + if ( size.x >= minSize || size.y >= minSize ) + { + // leave 1 pixel margin + size.x = size.y = minSize - 2; + + resize = true; + } + + if ( resize ) + { + m_control->SetSize(size); + } + + // position it in the centre of the rectangle (TODO: support alignment?) + +#if defined(__WXGTK__) + // the checkbox without label still has some space to the right in wxGTK, + // so shift it to the right + size.x -= 8; +#elif defined(__WXMSW__) + // here too, but in other way + size.x += 1; + size.y -= 2; +#endif + + int hAlign = wxALIGN_CENTRE; + int vAlign = wxALIGN_CENTRE; + if (GetCellAttr()) + GetCellAttr()->GetAlignment(& hAlign, & vAlign); + + int x = 0, y = 0; + if (hAlign == wxALIGN_LEFT) + { + x = r.x + 2; +#ifdef __WXMSW__ + x += 2; +#endif + y = r.y + r.height / 2 - size.y / 2; + } + else if (hAlign == wxALIGN_RIGHT) + { + x = r.x + r.width - size.x - 2; + y = r.y + r.height / 2 - size.y / 2; + } + else if (hAlign == wxALIGN_CENTRE) + { + x = r.x + r.width / 2 - size.x / 2; + y = r.y + r.height / 2 - size.y / 2; + } + + m_control->Move(x, y); +} + +void sqlGridBoolEditor::Show(bool show, wxGridCellAttr *attr) +{ + m_control->Show(show); + + if ( show ) + { + wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY; + CBox()->SetBackgroundColour(colBg); + } +} + +void sqlGridBoolEditor::BeginEdit(int row, int col, wxGrid *grid) +{ + wxASSERT_MSG(m_control, wxT("The sqlGridBoolEditor must be Created first!")); + + wxString value = grid->GetTable()->GetValue(row, col); + if (value == wxT("TRUE")) + m_startValue = wxCHK_CHECKED; + else if (value == wxT("FALSE")) + m_startValue = wxCHK_UNCHECKED; + else + m_startValue = wxCHK_UNDETERMINED; + + CBox()->Set3StateValue(m_startValue); + CBox()->SetFocus(); +} + +#define BOOL_EDIT_SWITCH switch (value) \ +{ \ + case wxCHK_UNCHECKED:\ + grid->GetTable()->SetValue(row, col, wxT("FALSE"));\ + break;\ + case wxCHK_CHECKED:\ + grid->GetTable()->SetValue(row, col, wxT("TRUE"));\ + break;\ + case wxCHK_UNDETERMINED:\ + grid->GetTable()->SetValue(row, col, wxEmptyString);\ + break;\ +}\ + +#if wxCHECK_VERSION(2, 9, 0) +// pure virtual in 2.9+, doesn't exist in prior versions +void sqlGridBoolEditor::ApplyEdit(int row, int col, wxGrid *grid) +{ + wxCheckBoxState value = CBox()->Get3StateValue(); + BOOL_EDIT_SWITCH +} +#endif + +#if wxCHECK_VERSION(2, 9, 0) +bool sqlGridBoolEditor::EndEdit(int row, int col, const wxGrid *grid, const wxString &, wxString *) +#else +bool sqlGridBoolEditor::EndEdit(int row, int col, wxGrid *grid) +#endif +{ + wxASSERT_MSG(m_control, wxT("The sqlGridBoolEditor must be Created first!")); + + bool changed = false; + wxCheckBoxState value = CBox()->Get3StateValue(); + if ( value != m_startValue ) + changed = true; + +#if !wxCHECK_VERSION(2, 9, 0) + if ( changed ) + { + BOOL_EDIT_SWITCH + } +#endif + + return changed; +} + +void sqlGridBoolEditor::Reset() +{ + wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be Created first!")); + + CBox()->Set3StateValue(m_startValue); +} + +void sqlGridBoolEditor::StartingClick() +{ + // We used to cycle the value on click here but + // that can lead to odd behaviour of the cell. + // Without cycling here, the checkbox is displayed + // but the user must toggle the box itself - she + // cannot just keep clicking the cell. +} + +bool sqlGridBoolEditor::IsAcceptedKey(wxKeyEvent &event) +{ + if ( wxGridCellEditor::IsAcceptedKey(event) ) + { + int keycode = event.GetKeyCode(); + switch ( keycode ) + { + case WXK_SPACE: + case '+': + case '-': + case 'n': + case 'N': + return true; + } + } + + return false; +} + +void sqlGridBoolEditor::StartingKey(wxKeyEvent &event) +{ + int keycode = event.GetKeyCode(); + wxCheckBoxState value = CBox()->Get3StateValue(); + + switch ( keycode ) + { + case WXK_SPACE: + switch (value) + { + case wxCHK_UNCHECKED: + case wxCHK_UNDETERMINED: + CBox()->Set3StateValue(wxCHK_CHECKED); + break; + case wxCHK_CHECKED: + CBox()->Set3StateValue(wxCHK_UNCHECKED); + break; + } + break; + + case '+': + CBox()->Set3StateValue(wxCHK_CHECKED); + break; + + case '-': + CBox()->Set3StateValue(wxCHK_UNCHECKED); + break; + + case 'n': + case 'N': + CBox()->Set3StateValue(wxCHK_UNDETERMINED); + break; + } +} + + +// return the value as "1" for true and the empty string for false +wxString sqlGridBoolEditor::GetValue() const +{ + + wxCheckBoxState value = CBox()->Get3StateValue(); + + switch (value) + { + case wxCHK_UNCHECKED: + return wxT("FALSE"); + break; + case wxCHK_CHECKED: + return wxT("TRUE"); + break; + case wxCHK_UNDETERMINED: + return wxEmptyString; + break; + } + return wxEmptyString; +} + +////////////////////////////////////////////////////////////////////// +// End Bool editor +////////////////////////////////////////////////////////////////////// + + +sqlTable::sqlTable(pgConn *conn, pgQueryThread *_thread, const wxString &tabName, const OID _relid, bool _hasOid, const wxString &_pkCols, char _relkind) +{ + connection = conn; + primaryKeyColNumbers = _pkCols; + relid = _relid; + relkind = _relkind; + tableName = tabName; + hasOids = _hasOid; + thread = _thread; + + rowsCached = 0; + rowsAdded = 0; + rowsStored = 0; + rowsDeleted = 0; + + + dataPool = 0; + addPool = new cacheLinePool(500); // arbitrary initial size + lastRow = -1; + int i; + lineIndex = 0; + + nRows = thread->DataSet()->NumRows(); + nCols = thread->DataSet()->NumCols(); + + columns = new sqlCellAttr[nCols]; + savedLine.cols = new wxString[nCols]; + + // Get the "real" column list, including any dropped columns, as + // key positions etc do not ignore these. + pgSet *allColsSet = connection->ExecuteSet( + wxT("SELECT attisdropped FROM pg_attribute") + wxT(" WHERE attnum > 0 AND attrelid=") + NumToStr(relid) + wxT("::oid\n") + wxT(" ORDER BY attnum")); + + int x = 1; + if (allColsSet) + { + for (i = 0; i < allColsSet->NumRows(); i++) + { + if (allColsSet->GetVal(wxT("attisdropped")) == wxT("t")) + { + colMap.Add(0); + } + else + { + colMap.Add(x); + x++; + } + allColsSet->MoveNext(); + } + delete allColsSet; + } + + pgSet *colSet = connection->ExecuteSet( + wxT("SELECT n.nspname AS nspname, relname, format_type(t.oid,NULL) AS typname, format_type(t.oid, att.atttypmod) AS displaytypname, ") + wxT("nt.nspname AS typnspname, attname, attnum, COALESCE(b.oid, t.oid) AS basetype, atthasdef, pg_get_expr(def.adbin,0) AS adsrc,\n") + wxT(" CASE WHEN t.typbasetype::oid=0 THEN att.atttypmod else t.typtypmod END AS typmod,\n") + wxT(" CASE WHEN t.typbasetype::oid=0 THEN att.attlen else t.typlen END AS typlen\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type t ON t.oid=att.atttypid\n") + wxT(" JOIN pg_namespace nt ON nt.oid=t.typnamespace\n") + wxT(" JOIN pg_class c ON c.oid=attrelid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type b ON b.oid=t.typbasetype\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=attrelid AND adnum=attnum\n") + wxT(" WHERE attnum > 0 AND NOT attisdropped AND attrelid=") + NumToStr(relid) + wxT("::oid\n") + wxT(" ORDER BY attnum")); + + + + bool canInsert = false; + if (colSet) + { + if (hasOids) + { + columns[0].name = wxT("oid"); + columns[0].numeric = true; + columns[0].attr->SetReadOnly(true); + columns[0].type = PGTYPCLASS_NUMERIC; + } + + for (i = (hasOids ? 1 : 0) ; i < nCols ; i++) + { + wxGridCellEditor *editor = 0; + + columns[i].name = colSet->GetVal(wxT("attname")); + columns[i].typeName = colSet->GetVal(wxT("typname")); + columns[i].displayTypeName = colSet->GetVal(wxT("displaytypname")); + + // Special case for character datatypes. We always cast them to text to avoid + // truncation issues with casts like ::character(3) + if (columns[i].typeName == wxT("character") || columns[i].typeName == wxT("character varying") || columns[i].typeName == wxT("\"char\"")) + columns[i].typeName = wxT("text"); + + columns[i].type = (Oid)colSet->GetOid(wxT("basetype")); + if ((columns[i].type == PGOID_TYPE_INT4 || columns[i].type == PGOID_TYPE_INT8 || columns[i].type == PGOID_TYPE_INT2) + && colSet->GetBool(wxT("atthasdef"))) + { + wxString adsrc = colSet->GetVal(wxT("adsrc")); + if (adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::text)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)") || + adsrc == wxT("nextval('") + colSet->GetVal(wxT("nspname")) + wxT(".") + colSet->GetVal(wxT("relname")) + wxT("_") + columns[i].name + wxT("_seq'::regclass)")) + { + if (columns[i].type == PGOID_TYPE_INT4) + columns[i].type = (Oid)PGOID_TYPE_SERIAL; + else if (columns[i].type == PGOID_TYPE_INT8) + columns[i].type = (Oid)PGOID_TYPE_SERIAL8; + else + columns[i].type = (Oid)PGOID_TYPE_SERIAL2; + } + } + columns[i].typlen = colSet->GetLong(wxT("typlen")); + columns[i].typmod = colSet->GetLong(wxT("typmod")); + + switch (columns[i].type) + { + case PGOID_TYPE_BOOL: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + editor = new sqlGridBoolEditor(); + break; + case PGOID_TYPE_INT8: + case PGOID_TYPE_SERIAL8: + SetNumberEditor(i, 20); + break; + case PGOID_TYPE_INT2: + case PGOID_TYPE_SERIAL2: + SetNumberEditor(i, 5); + break; + case PGOID_TYPE_INT4: + case PGOID_TYPE_SERIAL: + SetNumberEditor(i, 10); + break; + case PGOID_TYPE_OID: + case PGOID_TYPE_TID: + case PGOID_TYPE_XID: + case PGOID_TYPE_CID: + SetNumberEditor(i, 10); + break; + case PGOID_TYPE_FLOAT4: + case PGOID_TYPE_FLOAT8: + columns[i].numeric = true; + columns[i].attr->SetReadOnly(false); + editor = new sqlGridNumericEditor(); + break; + case PGOID_TYPE_MONEY: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + editor = new wxGridCellTextEditor(); + break; + case PGOID_TYPE_NUMERIC: + { + columns[i].numeric = true; + columns[i].attr->SetReadOnly(false); + int len = columns[i].size(); + int prec = columns[i].precision(); + if (prec > 0) + len -= (prec); + editor = new sqlGridNumericEditor(len, prec); + break; + } + case PGOID_TYPE_BYTEA: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(true); + break; + case PGOID_TYPE_DATE: + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIMETZ: + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_INTERVAL: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + editor = new sqlGridTextEditor(); + break; + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + default: + columns[i].numeric = false; + columns[i].attr->SetReadOnly(false); + columns[i].needResize = true; + editor = new sqlGridTextEditor(); + break; + } + if (editor) + columns[i].attr->SetEditor(editor); + + if (relkind != 'r' || (!hasOids && primaryKeyColNumbers.IsNull())) + { + // for security reasons, we need oid or pk to enable updates. If none is available, + // the table definition can be considered faulty. + columns[i].attr->SetReadOnly(true); + } + if (!columns[i].attr->IsReadOnly()) + canInsert = true; + + wxStringTokenizer collist(primaryKeyColNumbers, wxT(",")); + long cn = 0; + long attnum = colSet->GetLong(wxT("attnum")); + + while (cn < attnum && collist.HasMoreTokens()) + { + cn = StrToLong(collist.GetNextToken()); + if (cn == attnum) + columns[i].isPrimaryKey = true; + } + + colSet->MoveNext(); + } + delete colSet; + } + else + { + // um, we never should reach here because this would mean + // that datatypes are unreadable. + // *if* we reach here, namespace info is missing. + for (i = 0 ; i < nCols ; i++) + { + columns[i].typeName = thread->DataSet()->ColType(i); + columns[i].name = thread->DataSet()->ColName(i); + } + } + + if (nRows) + { + dataPool = new cacheLinePool(nRows); + lineIndex = new int[nRows]; + for (i = 0 ; i < nRows ; i++) + lineIndex[i] = i; + } + + if (canInsert) + { + // an empty line waiting for inserts + rowsAdded = 1; + } +} + + +sqlTable::~sqlTable() +{ + if (thread) + delete thread; + if (dataPool) + delete dataPool; + + delete addPool; + + delete[] columns; + + if (lineIndex) + delete[] lineIndex; +} + + +int sqlTable::GetNumberCols() +{ + return nCols; +} + + +int sqlTable::GetNumberRows() +{ + return nRows + rowsAdded - rowsDeleted; +} + + +int sqlTable::GetNumberStoredRows() +{ + return nRows + rowsStored - rowsDeleted; +} + + +bool ctlSQLEditGrid::IsColText(int col) +{ + return GetTable()->IsColText(col); +} + +bool sqlTable::IsColText(int col) +{ + return !columns[col].numeric && !(columns[col].type == PGOID_TYPE_BOOL); +} + +bool sqlTable::IsColBoolean(int col) +{ + return (columns[col].type == PGOID_TYPE_BOOL); +} + +wxString sqlTable::GetColLabelValue(int col) +{ + wxString label = columns[col].name + wxT("\n"); + if (columns[col].isPrimaryKey) + label += wxT("[PK] "); + + switch (columns[col].type) + { + case (Oid)PGOID_TYPE_SERIAL: + label += wxT("serial"); + break; + case (Oid)PGOID_TYPE_SERIAL8: + label += wxT("bigserial"); + break; + case (Oid)PGOID_TYPE_SERIAL2: + label += wxT("smallserial"); + break; + default: + label += columns[col].displayTypeName; + break; + } + return label; +} + + +wxString sqlTable::GetColLabelValueUnformatted(int col) +{ + return columns[col].name; +} + + +wxString sqlTable::GetRowLabelValue(int row) +{ + wxString label; + if (row < nRows - rowsDeleted || GetLine(row)->stored) + label.Printf(wxT("%d"), row + 1); + else + label = wxT("*"); + return label; +} + + + +void sqlTable::SetNumberEditor(int col, int len) +{ + columns[col].numeric = true; + columns[col].attr->SetReadOnly(false); + columns[col].attr->SetEditor(new sqlGridNumericEditor(len, 0)); +} + + +bool sqlTable::CheckInCache(int row) +{ + if (row > nRows - rowsDeleted + rowsAdded) + return false; + if (row >= nRows - rowsDeleted) + return true; + + return dataPool->IsFilled(row); +} + + +cacheLine *sqlTable::GetLine(int row) +{ + cacheLine *line; + if (row < nRows - rowsDeleted) + line = dataPool->Get(lineIndex[row]); + else + line = addPool->Get(row - (nRows - rowsDeleted)); + + return line; +} + + + +wxString sqlTable::MakeKey(cacheLine *line) +{ + wxString whereClause; + if (!primaryKeyColNumbers.IsEmpty()) + { + wxStringTokenizer collist(primaryKeyColNumbers, wxT(",")); + long cn; + int offset; + + if (hasOids) + offset = 0; + else + offset = 1; + + while (collist.HasMoreTokens()) + { + cn = StrToLong(collist.GetNextToken()); + + // Translate the column location to the real location in the actual columns still present + cn = colMap[cn - 1]; + + wxString colval = line->cols[cn - offset]; + if (colval.IsEmpty()) + return wxEmptyString; + + if (colval == wxT("''") && columns[cn - offset].typeName == wxT("text")) + colval = wxEmptyString; + + if (!whereClause.IsEmpty()) + whereClause += wxT(" AND "); + whereClause += qtIdent(columns[cn - offset].name) + wxT(" = ") + connection->qtDbString(colval); + + if (columns[cn - offset].typeName != wxT("")) + { + whereClause += wxT("::"); + whereClause += columns[cn - offset].displayTypeName; + } + } + } + else if (hasOids) + whereClause = wxT("oid = ") + line->cols[0]; + + return whereClause; +} + + + +void sqlTable::UndoLine(int row) +{ + if (lastRow >= 0 && row >= 0) + { + cacheLine *line = GetLine(row); + if (line) + { + int i; + for (i = 0 ; i < nCols ; i++) + line->cols[i] = savedLine.cols[i]; + ctlMenuToolbar *tb = (ctlMenuToolbar *)((wxFrame *)GetView()->GetParent())->GetToolBar(); + if (tb) + { + tb->EnableTool(MNU_SAVE, false); + tb->EnableTool(MNU_UNDO, false); + } + wxMenu *fm = ((frmEditGrid *)GetView()->GetParent())->GetFileMenu(); + if (fm) + fm->Enable(MNU_SAVE, false); + wxMenu *em = ((frmEditGrid *)GetView()->GetParent())->GetEditMenu(); + if (em) + em->Enable(MNU_UNDO, false); + } + } + lastRow = -1; +} + + +bool sqlTable::StoreLine() +{ + bool done = false; + + GetView()->BeginBatch(); + if (lastRow >= 0) + { + cacheLine *line = GetLine(lastRow); + + int i; + wxString colList, valList; + + if (line->stored) + { + // UPDATE + + for (i = (hasOids ? 1 : 0) ; i < nCols ; i++) + { + if (savedLine.cols[i] != line->cols[i]) + { + if (!valList.IsNull()) + valList += wxT(", "); + valList += qtIdent(columns[i].name) + wxT("=") + columns[i].Quote(connection, line->cols[i]); + } + } + + if (valList.IsEmpty()) + done = true; + else + { + wxString key = MakeKey(&savedLine); + wxASSERT(!key.IsEmpty()); + done = connection->ExecuteVoid(wxT( + "UPDATE ") + tableName + wxT( + " SET ") + valList + wxT( + " WHERE ") + key); + } + } + else + { + // INSERT + + for (i = 0 ; i < nCols ; i++) + { + if (!columns[i].attr->IsReadOnly() && !line->cols[i].IsEmpty()) + { + if (!colList.IsNull()) + { + valList += wxT(", "); + colList += wxT(", "); + } + colList += qtIdent(columns[i].name); + + valList += columns[i].Quote(connection, line->cols[i]); + } + } + + if (!valList.IsEmpty()) + { + pgSet *set = connection->ExecuteSet( + wxT("INSERT INTO ") + tableName + + wxT("(") + colList + + wxT(") VALUES (") + valList + + wxT(")")); + if (set) + { + if (set->GetInsertedCount() > 0) + { + if (hasOids) + line->cols[0] = NumToStr((long)set->GetInsertedOid()); + delete set; + + done = true; + rowsStored++; + ((wxFrame *)GetView()->GetParent())->SetStatusText(wxString::Format(wxT("%d rows."), GetNumberStoredRows())); + if (rowsAdded == rowsStored) + GetView()->AppendRows(); + + // Read back what we inserted to get default vals + wxString key = MakeKey(line); + + if (key.IsEmpty()) + { + // That's a problem: obviously, the key generated isn't present + // because it's serial or default or otherwise generated in the backend + // we don't get. + // That's why the whole line is declared readonly. + + line->readOnly = true; + } + else + { + set = connection->ExecuteSet( + wxT("SELECT * FROM ") + tableName + + wxT(" WHERE ") + key); + if (set) + { + for (i = (hasOids ? 1 : 0) ; i < nCols ; i++) + { + line->cols[i] = set->GetVal(columns[i].name); + } + delete set; + } + } + } + } + } + } + if (done) + { + line->stored = true; + lastRow = -1; + } + else + GetView()->SelectRow(lastRow); + } + + GetView()->EndBatch(); + + return done; +} + + +void sqlTable::SetValue(int row, int col, const wxString &value) +{ + cacheLine *line = GetLine(row); + + if (!line) + { + // Bad problem, no line! + return; + } + + + if (row != lastRow) + { + if (lastRow >= 0) + StoreLine(); + + if (!line->cols) + line->cols = new wxString[nCols]; + + // remember line contents for later reference in update ... where + int i; + for (i = 0 ; i < nCols ; i++) + savedLine.cols[i] = line->cols[i]; + lastRow = row; + } + ctlMenuToolbar *tb = (ctlMenuToolbar *)((wxFrame *)GetView()->GetParent())->GetToolBar(); + if (tb) + { + tb->EnableTool(MNU_SAVE, true); + tb->EnableTool(MNU_UNDO, true); + } + wxMenu *fm = ((frmEditGrid *)GetView()->GetParent())->GetFileMenu(); + if (fm) + fm->Enable(MNU_SAVE, true); + wxMenu *em = ((frmEditGrid *)GetView()->GetParent())->GetEditMenu(); + if (em) + em->Enable(MNU_UNDO, true); + line->cols[col] = value; +} + + + +wxString sqlTable::GetValue(int row, int col) +{ + wxString val; + cacheLine *line; + if (row < nRows - rowsDeleted) + line = dataPool->Get(lineIndex[row]); + else + line = addPool->Get(row - (nRows - rowsDeleted)); + + if (!line) + { + // Bad problem, no line! + return val; + } + + if (!line->cols) + { + line->cols = new wxString[nCols]; + if (row < nRows - rowsDeleted) + { + if (!thread) + { + wxLogError(__("Unexpected empty cache line: dataSet already closed.")); + return val; + } + + line->stored = true; + if (lineIndex[row] != thread->DataSet()->CurrentPos() - 1) + thread->DataSet()->Locate(lineIndex[row] + 1); + + int i; + for (i = 0 ; i < nCols ; i++) + { + wxString val; + if (thread->DataSet()->ColType(i) == wxT("bytea")) + val = _(""); + else + { + val = thread->DataSet()->GetVal(i); + if (val.IsEmpty()) + { + if (!thread->DataSet()->IsNull(i)) + val = wxT("''"); + } + else if (val == wxT("''")) + val = wxT("\\'\\'"); + } + line->cols[i] = val; + } + rowsCached++; + + if (rowsCached == nRows) + { + delete thread; + thread = 0; + } + } + } + if (columns[col].type == PGOID_TYPE_BOOL) + { + if (line->cols[col] != wxEmptyString) + line->cols[col] = (StrToBool(line->cols[col]) ? wxT("TRUE") : wxT("FALSE")); + } + + val = line->cols[col]; + return val; +} + +bool sqlTable::AppendRows(size_t rows) +{ + rowsAdded += rows; + GetLine(nRows + rowsAdded - rowsDeleted - 1); + + wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, rows); + GetView()->ProcessTableMessage(msg); + + return true; +} + + +bool sqlTable::DeleteRows(size_t pos, size_t rows) +{ + size_t i = pos; + size_t rowsDone = 0; + + while (i < pos + rows) + { + cacheLine *line = GetLine(pos); + if (!line) + break; + + // If line->cols is null, it probably means we need to force the cacheline to be populated. + if (!line->cols) + { + GetValue(pos, 0); + line = GetLine(pos); + } + + if (line->stored) + { + wxString key = MakeKey(line); + wxASSERT(!key.IsEmpty()); + bool done = connection->ExecuteVoid(wxT( + "DELETE FROM ") + tableName + wxT(" WHERE ") + key); + if (!done) + break; + + if ((int)pos < nRows - rowsDeleted) + { + rowsDeleted++; + if ((int)pos < nRows - rowsDeleted) + memmove(lineIndex + pos, lineIndex + pos + 1, sizeof(*lineIndex) * (nRows - rowsDeleted - pos)); + } + else + { + rowsAdded--; + if (GetLine(pos)->stored) + rowsStored--; + addPool->Delete(pos - (nRows - rowsDeleted)); + } + rowsDone++; + } + else + { + // last empty line won't be deleted, just cleared + int j; + for (j = 0 ; j < nCols ; j++) + line->cols[j] = wxT(""); + } + i++; + } + + if (rowsDone > 0 && GetView()) + { + wxGridTableMessage msg(this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, pos, rowsDone); + GetView()->ProcessTableMessage(msg); + } + return (rowsDone != 0); +} + + +bool sqlTable::Paste() +{ + int row, col; + int start, pos, len; + wxArrayString data; + wxString text, quoteChar, colSep; + bool inQuotes, inData, skipSerial; + + if (!this) + return false; + + if (wxTheClipboard->Open()) + { + if (wxTheClipboard->IsSupported(wxDF_TEXT)) + { + wxTextDataObject textData; + wxTheClipboard->GetData(textData); + text = textData.GetText(); + } + else + { + wxTheClipboard->Close(); + return false; + } + wxTheClipboard->Close(); + } + else + { + return false; + } + + start = pos = 0; + len = text.Len(); + quoteChar = settings->GetCopyQuoteChar(); + colSep = settings->GetCopyColSeparator(); + inQuotes = inData = false; + + while (pos < len && !(text[pos] == '\n' && !inQuotes)) + { + if (!inData) + { + if (text[pos] == quoteChar) + { + inQuotes = inData = true; + pos++; + start++; + continue; + } + else + { + inQuotes = false; + } + inData = true; + } + + if (inQuotes && text[pos] == quoteChar && + (text[pos + 1] == colSep || text[pos + 1] == '\r' || text[pos + 1] == '\n')) + { + data.Add(text.Mid(start, pos - start)); + start = (pos += 2); + inData = false; + } + else if (!inQuotes && text[pos] == colSep) + { + data.Add(text.Mid(start, pos - start)); + start = ++pos; + inData = false; + } + else + { + pos++; + } + } + if (start < pos) + { + if (inQuotes && text[pos - 1] == quoteChar) + data.Add(text.Mid(start, pos - start - 1)); + else + data.Add(text.Mid(start, pos - start)); + } + + row = GetNumberRows() - 1; + skipSerial = false; + + for (col = 0; col < nCols; col++) + { + if (columns[col].type == (unsigned int)PGOID_TYPE_SERIAL || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL8 || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL2) + { + wxMessageDialog msg(GetView()->GetParent(), + _("This table contains serial columns. Do you want to use the values in the clipboard for these columns?"), + _("Paste Data"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() != wxID_YES) + { + skipSerial = true; + } + break; + } + } + + bool pasted = false; + for (col = (hasOids ? 1 : 0); col < nCols && col < (int)data.GetCount(); col++) + { + if (!(skipSerial && (columns[col].type == (unsigned int)PGOID_TYPE_SERIAL || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL8 || + columns[col].type == (unsigned int)PGOID_TYPE_SERIAL2))) + { + SetValue(row, col, data.Item(col)); + GetView()->SetGridCursor(row, col); + GetView()->MakeCellVisible(row, col); + pasted = true; + } + } + GetView()->ForceRefresh(); + + return pasted; +} + + + + +wxGridCellAttr *sqlTable::GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) +{ + cacheLine *line = GetLine(row); + if (line && line->readOnly) + { + wxGridCellAttr *attr = new wxGridCellAttr(columns[col].attr); + attr->SetReadOnly(); + return attr; + } + else + { + columns[col].attr->IncRef(); + return columns[col].attr; + } +} + + + +wxString sqlCellAttr::Quote(pgConn *conn, const wxString &value) +{ + wxString str; + if (value.IsEmpty()) + str = wxT("NULL"); + else if (numeric) + str = conn->qtDbString(value); + else if (value == wxT("\\'\\'")) + str = conn->qtDbString(wxT("''")); + else if (value == wxT("''")) + str = wxT("''"); + else if (type == PGOID_TYPE_BOOL) + str = value; + else if (type == PGOID_TYPE_BIT) + // Don't cast this one + return wxT("B'") + value + wxT("'"); + else + str = conn->qtDbString(value); + + return str + wxT("::") + displayTypeName; +} + + + + +int sqlCellAttr::size() +{ + if (typlen == -1 && typmod > 0) + { + return (typmod - 4) >> 16; + } + else + return typlen; +} + + +int sqlCellAttr::precision() +{ + if (typlen == -1 && typmod > 0) + { + return (typmod - 4) & 0x7fff; + } + else + return -1; +} + + +cacheLinePool::cacheLinePool(int initialLines) +{ + ptr = new cacheLine*[initialLines]; + if (ptr) + { + anzLines = initialLines; + memset(ptr, 0, sizeof(cacheLine *)*anzLines); + } + else + { + anzLines = 0; + wxLogError(__("Out of Memory for cacheLinePool")); + } +} + + + +cacheLinePool::~cacheLinePool() +{ + if (ptr) + { + while (anzLines--) + { + if (ptr[anzLines]) + delete ptr[anzLines]; + } + delete[] ptr; + } +} + + + +void cacheLinePool::Delete(int lineNo) +{ + if (ptr && lineNo >= 0 && lineNo < anzLines) + { +#if 1 + if (ptr[lineNo]) + delete ptr[lineNo]; + + if (lineNo < anzLines - 1) + { + // beware: overlapping copy + memmove(ptr + lineNo, ptr + lineNo + 1, sizeof(cacheLine *) * (anzLines - lineNo - 1)); + } +#else + cacheLine *c; + c = ptr[0]; + ptr[0] = ptr[1]; + ptr[1] = c; +#endif + ptr[anzLines - 1] = 0; + } +} + + +cacheLine *cacheLinePool::Get(int lineNo) +{ + if (lineNo < 0) return 0; + + if (lineNo >= anzLines) + { + cacheLine **old = ptr; + int oldAnz = anzLines; + anzLines = lineNo + 100; + ptr = new cacheLine*[anzLines]; + if (!ptr) + { + anzLines = 0; + wxLogError(__("Out of Memory for cacheLinePool")); + } + else + { + if (oldAnz) + { + memcpy(ptr, old, sizeof(cacheLine *)*oldAnz); + delete[] old; + } + memset(ptr + oldAnz, 0, anzLines - oldAnz); + } + } + + if (lineNo < anzLines) + { + if (!ptr[lineNo]) + ptr[lineNo] = new cacheLine(); + return ptr[lineNo]; + } + return 0; +} + + +bool cacheLinePool::IsFilled(int lineNo) +{ + return (lineNo < anzLines && ptr[lineNo]); +} + + +bool editGridFactoryBase::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgaFactory *factory = obj->GetFactory(); + return factory == &pg_partitionFactory || factory == &tableFactory || factory == &foreignTableFactory || factory == &viewFactory || factory == &extTableFactory || factory == &catalogObjectFactory; + } + return false; +} + + +wxWindow *editGridFactoryBase::ViewData(frmMain *form, pgObject *obj, bool filter) +{ + pgDatabase *db = ((pgSchemaObject *)obj)->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Edit Grid"); + + pgServer *server = db->GetServer(); + pgConn *conn = db->CreateConn(applicationname); + if (conn) + { + wxString txt = _("Edit Data - ") + + server->GetDescription() + + wxT(" (") + server->GetName() + + wxT(":") + NumToStr((long)server->GetPort()) + + wxT(") - ") + db->GetName() + + wxT(" - ") + obj->GetFullIdentifier(); + + frmEditGrid *eg = new frmEditGrid(form, txt, conn, (pgSchemaObject *)obj, pkAscending); + eg->SetLimit(rowlimit); + eg->ShowForm(filter); + return eg; + } + return 0; +} + + +editGridFactory::editGridFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : editGridFactoryBase(list) +{ + mnu->Append(id, _("View &All Rows\tCtrl-D"), _("View the data in the selected object.")); + toolbar->AddTool(id, _("View All Rows\tCtrl-D"), *viewdata_png_bmp, _("View the data in the selected object."), wxITEM_NORMAL); + context = false; +} + + +wxWindow *editGridFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return ViewData(form, obj, false); +} + + +#include "images/viewfiltereddata.pngc" +editGridFilteredFactory::editGridFilteredFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : editGridFactoryBase(list) +{ + mnu->Append(id, _("View F&iltered Rows...\tCtrl-G"), _("Apply a filter and view the data in the selected object.")); + toolbar->AddTool(id, _("View Filtered Rows\tCtrl-G"), *viewfiltereddata_png_bmp, _("Apply a filter and view the data in the selected object."), wxITEM_NORMAL); + context = false; +} + + +wxWindow *editGridFilteredFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return ViewData(form, obj, true); +} + +editGridLimitedFactory::editGridLimitedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, int limit, bool ascending) : editGridFactoryBase(list) +{ + if (ascending) + mnu->Append(id, wxString::Format(wxPLURAL("View Top %i Row", "View Top %i Rows", limit), limit), _("View a limited number of rows in the selected object.")); + else + mnu->Append(id, wxString::Format(wxPLURAL("View Last %i Row", "View Last %i Rows", limit), limit), _("View a limited number of rows in the selected object.")); + + pkAscending = ascending; + rowlimit = limit; + context = false; +} + +wxWindow *editGridLimitedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return ViewData(form, obj, false); +} diff --git a/frm/frmExport.cpp b/frm/frmExport.cpp new file mode 100644 index 0000000..16097ee --- /dev/null +++ b/frm/frmExport.cpp @@ -0,0 +1,601 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmExport.cpp - The export file dialogue +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" +#include +#include "frm/frmExport.h" +#include "utils/sysSettings.h" +#include "utils/misc.h" +#include "ctl/ctlSQLResult.h" +#include +#include +#include + +#define txtFilename CTRL_TEXT("txtFilename") +#define btnOK CTRL_BUTTON("wxID_OK") +#define rbUnicode CTRL_RADIOBUTTON("rbUnicode") +#define rbLocal CTRL_RADIOBUTTON("rbLocal") +#define rbCRLF CTRL_RADIOBUTTON("rbCRLF") +#define rbLF CTRL_RADIOBUTTON("rbLF") +#define rbQuoteStrings CTRL_RADIOBUTTON("rbQuoteStrings") +#define rbQuoteAll CTRL_RADIOBUTTON("rbQuoteAll") +#define rbQuoteNone CTRL_RADIOBUTTON("rbQuoteNone") +#define chkColnames CTRL_CHECKBOX("chkColnames") +#define chkXlsCopy CTRL_CHECKBOX("chkXlsCopy") +#define cbColSeparator CTRL_COMBOBOX("cbColSeparator") +#define cbQuoteChar CTRL_COMBOBOX("cbQuoteChar") + + +BEGIN_EVENT_TABLE(frmExport, pgDialog) + EVT_TEXT(XRCID("txtFilename"), frmExport::OnChange) + EVT_RADIOBUTTON(XRCID("rbQuoteNone"), frmExport::OnChange) + EVT_RADIOBUTTON(XRCID("rbQuoteStrings"), frmExport::OnChange) + EVT_RADIOBUTTON(XRCID("rbQuoteAll"), frmExport::OnChange) + EVT_BUTTON(XRCID("btnFilename"), frmExport::OnBrowseFile) + EVT_BUTTON(wxID_HELP, frmExport::OnHelp) + EVT_BUTTON(wxID_OK, frmExport::OnOK) + EVT_BUTTON(wxID_CANCEL, frmExport::OnCancel) +END_EVENT_TABLE() + +class XMLDataFormat : public wxDataFormat +{ +public: + XMLDataFormat() : wxDataFormat(wxT("XML Spreadsheet")) {} +}; +class XMLDataObject : public wxDataObjectSimple +{ + +public: + XMLDataObject(const wxString& xmlstring = wxEmptyString) : wxDataObjectSimple(), m_XMLString(xmlstring) + { + SetFormat(XMLDataFormat()); + } + + + size_t GetLength() const { return m_XMLString.Len()*2 + 1; } + wxString GetXML() const { return m_XMLString; } + void SetXML(const wxString& xml) { m_XMLString = xml; } + + size_t GetDataSize() const + { + return GetLength(); + } + + bool GetDataHere(void *buf) const + { + //char* c = _strdup(m_XMLString.c_str()); not needed as per suggestion + + //memcpy(buf, m_XMLString.c_str(), m_XMLString.Len()*2+1); + + memcpy(buf,m_XMLString.mb_str(wxConvUTF8),m_XMLString.Len()*2+1); + return true; + } + + bool SetData(size_t len, const void* buf) + { + //char* c = new char[len + 1]; not needed as per suggestion + //memcpy(c, buf, len); not needed as per suggestion + m_XMLString = wxString::FromUTF8((const char*)buf); //changed as per suggestion + + //delete c; + + return true; + } + + virtual size_t GetDataSize(const wxDataFormat&) const + { + return GetDataSize(); + } + virtual bool GetDataHere(const wxDataFormat&, void *buf) const + { + return GetDataHere(buf); + } + virtual bool SetData(const wxDataFormat&, size_t len, const void *buf) + { + return SetData(len, buf); + } + + +private: + wxString m_XMLString; +}; + + +frmExport::frmExport(wxWindow *p) +{ + parent = p; + + SetFont(settings->GetSystemFont()); + LoadResource(p, wxT("frmExport")); + RestorePosition(); + + // Icon + appearanceFactory->SetIcons(this); + cbQuoteChar->Disable(); + btnOK->Disable(); + + + bool uc = settings->GetExportUnicode(); + rbUnicode->SetValue(uc); + rbLocal->SetValue(!uc); + + bool isCrLf = settings->GetExportRowSeparator() == wxT("\r\n"); + rbCRLF->SetValue(isCrLf); + rbLF->SetValue(!isCrLf); + + int qt = settings->GetExportQuoting(); + + rbQuoteNone->SetValue(qt == 0); + rbQuoteStrings->SetValue(qt == 1); + rbQuoteAll->SetValue(qt == 2); + + cbColSeparator->SetValue(settings->GetExportColSeparator()); + + + cbQuoteChar->SetValue(settings->GetExportQuoteChar()); + + wxString val; + settings->Read(wxT("Export/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + wxCommandEvent ev; + OnChange(ev); +} + + +frmExport::~frmExport() +{ + SavePosition(); +} + + +void frmExport::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("export"), HELP_PGADMIN); +} + + +void frmExport::OnChange(wxCommandEvent &ev) +{ + cbQuoteChar->Enable(rbQuoteStrings->GetValue() || rbQuoteAll->GetValue()); + btnOK->Enable(!txtFilename->GetValue().IsEmpty() && !cbColSeparator->GetValue().IsEmpty()); +} + + +void frmExport::OnOK(wxCommandEvent &ev) +{ + settings->SetExportUnicode(rbUnicode->GetValue()); + settings->SetExportRowSeparator(rbCRLF->GetValue() ? wxT("\r\n") : wxT("\n")); + settings->SetExportColSeparator(cbColSeparator->GetValue()); + + if (rbQuoteAll->GetValue()) + settings->SetExportQuoting(2); + else if (rbQuoteStrings->GetValue()) + settings->SetExportQuoting(1); + else + settings->SetExportQuoting(0); + + settings->SetExportQuoteChar(cbQuoteChar->GetValue()); + + settings->Write(wxT("Export/LastFile"), txtFilename->GetValue()); + + + if (IsModal()) + EndModal(wxID_OK); + else + Destroy(); +} + +wxString frmExport::InitXml(int cols, int rows) +{ + wxString strc; + wxString strr; + + strc.Printf(wxT("%d"),cols); + strr.Printf(wxT("%d"),rows); + + wxString s= wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + ; + for (int c = 0 ; c < cols ; c++) + { + s+=wxT("\n"); + } + return s; +} +wxString textEscapeXml(wxString &text) +{ + wxString::const_iterator i; + wxString xmltext=wxEmptyString; + for ( i = text.begin(); i != text.end(); ++i ) + { +#if wxCHECK_VERSION(3, 0, 0) + char c=*i; + switch (c) +#else + switch (*i) +#endif + { + case '&': xmltext+= wxT("&"); break; + case '\'': xmltext+= wxT("'"); break; + case '"': xmltext+= wxT("""); break; + case '<': xmltext+= wxT("<"); break; + case '>': xmltext+= wxT(">"); break; + case 13: break; + case 10: xmltext+= wxT(" "); break; + default: xmltext+= *i; break; + } + } +return xmltext; +} +bool frmExport::ExportXls(ctlSQLResult *grid) +{ + int colCount, rowCount; + int col; + wxString line; + long skipped = 0; + wxWX2MBbuf buf; + colCount = grid->GetNumberCols(); + rowCount = grid->NumRows(); + line=InitXml(colCount,rowCount+1); + wxAutomationObject excelObject; + line += wxT("\n"); + for (col = 0 ; col < colCount ; col++) + { + line += wxT("")+grid->OnGetItemText(-1, col + 1).BeforeFirst('\n')+wxT(""); + //wxString adr(wxT("")); + //adr.Printf(wxT("%s%d"), name,1); + //rng[0] = wxVariant(adr); + //excelObject.GetObject(range, wxT("Range"), 1,rng); + //range.CallMethod(wxT("Activate")); + //excelObject.PutProperty(wxT("ActiveCell.Font.Bold"), true); + //excelObject.PutProperty(wxT("ActiveCell.Value"), grid->OnGetItemText(-1, col + 1).BeforeFirst('\n')); + //name[0]++; + } + line += wxT("\n"); + int row; + wxString text; + wxString type; + OID typOid; + wxString fn=txtFilename->GetValue().BeforeLast('.'); + if (fn.IsEmpty()) fn=txtFilename->GetValue()+wxT(".xml"); + else fn+=wxT(".xml"); + + wxFile file(fn, wxFile::write); + if (!file.IsOpened()) + { + wxLogError(__("Failed to open file %s."), fn.c_str()); + return false; + } + file.Write(line, wxConvUTF8); + wxString xmltext=wxEmptyString; + for (row = 0 ; row < rowCount ; row++) + { + if (grid->GetRowSize(row)==0) continue; + line = wxT("\n"); + for (col = 0 ; col < colCount ; col++) + { + wxString style(wxT("null")); + //adr.Printf(wxT("%s%d"), name,row+2); + //rng[0] = wxVariant(adr); + //excelObject.GetObject(range, wxT("Range"), 1,rng); + //range.CallMethod(wxT("Activate")); + text=grid->OnGetItemText(row, col + 1); + xmltext=wxEmptyString; + typOid = grid->colTypClasses[col]; + if (!text.IsEmpty()) { + style=wxT("def"); + xmltext=textEscapeXml(text); + // find out if string + switch (typOid) + { + case PGTYPCLASS_NUMERIC: + //type=wxT("0.00"); + if (xmltext.IsNumber()) + xmltext=wxT("")+xmltext+wxT(""); + else + xmltext=wxT("")+xmltext+wxT(""); + break; + case PGTYPCLASS_DATE: + //type=wxT("ÃÃÃÃ-ÌÌ-ÄÄ ÷÷:ìì:ññ"); + xmltext=xmltext.BeforeFirst('+'); + if (xmltext.Replace(wxT(" "),wxT("T"))==0) { + xmltext=wxT("")+xmltext+wxT(""); + } else + { + style=wxT("dt"); + xmltext=wxT("")+xmltext+wxT(""); + } + break; + case PGTYPCLASS_BOOL: + default: + //type=wxT("@"); + xmltext=wxT("")+xmltext+wxT(""); + break; + } + + } else xmltext=wxT(""); + // excelObject.PutProperty(wxT("ActiveCell.Borders.LineStyle"), 1); + // excelObject.PutProperty(wxT("ActiveCell.NumberFormat"),type); + // excelObject.PutProperty(wxT("ActiveCell.Value"), text); + // name[0]++; + line += xmltext+wxT("\n"); + } + line += wxT("\n"); + file.Write(line, wxConvUTF8); + } + line = wxT("
"); + file.Write(line, wxConvUTF8); + text=textEscapeXml(grid->sqlquerytext); + line= wxT("\n") + wxT("\n") + wxT("\n") + wxT("")+text+ + wxT("\n
") + wxT("
\n") + ; + file.Write(line, wxConvUTF8); + file.Close(); + if (excelObject.CreateInstance(wxT("Excel.Application"))) { + //excelObject.GetObject(xlbook,wxT("Workbooks.Add")); + excelObject.CallMethod(wxT("Workbooks.Open"), fn); + excelObject.PutProperty(_T("VISIBLE"), true); + return true; + } + return false; + +} + +bool frmExport::Export(pgSet *set) +{ + ctlSQLResult *grid = 0; + if (!set) + { + wxLogInfo(wxT("Exporting data from the grid")); + grid = (ctlSQLResult *)parent; + if (chkXlsCopy->GetValue()) { + return ExportXls(grid); + } + + } + else + wxLogInfo(wxT("Exporting data from a resultset")); + + wxFile file(txtFilename->GetValue(), wxFile::write); + if (!file.IsOpened()) + { + wxLogError(__("Failed to open file %s."), txtFilename->GetValue().c_str()); + return false; + } + + wxString line; + long skipped = 0; + wxWX2MBbuf buf; + + int colCount, rowCount; + + if (set) + { + colCount = set->NumCols(); + rowCount = set->NumRows(); + } + else + { + colCount = grid->GetNumberCols(); + rowCount = grid->NumRows(); + } + + int col; + if (chkColnames->GetValue()) + { + for (col = 0 ; col < colCount ; col++) + { + if (!col) + line = wxEmptyString; + else + line += cbColSeparator->GetValue(); + + if (rbQuoteStrings->GetValue() || rbQuoteAll->GetValue()) + { + wxString qc = cbQuoteChar->GetValue(); + + wxString hdr; + if (set) + hdr = set->ColName(col); + else + hdr = grid->OnGetItemText(-1, col + 1).BeforeFirst('\n'); + + hdr.Replace(qc, qc + qc); + line += qc + hdr + qc; + } + else + { + if (set) + line += set->ColName(col); + else + line += grid->OnGetItemText(-1, col + 1).BeforeFirst('\n'); + } + } + if (rbCRLF->GetValue()) + line += wxT("\r\n"); + else + line += wxT("\n"); + + if (rbUnicode->GetValue()) + file.Write(line, wxConvUTF8); + else + { + buf = line.mb_str(wxConvLibc); + if (!buf) + skipped++; + else + file.Write(line, wxConvLibc); + } + } + + + wxString text; + OID typOid; + + int row; + for (row = 0 ; row < rowCount ; row++) + { + for (col = 0 ; col < colCount ; col++) + { + if (!col) + line = wxEmptyString; + else + line += cbColSeparator->GetValue(); + + bool needQuote = rbQuoteAll->GetValue(); + + if (set) + { + text = set->GetVal(col); + typOid = set->ColTypClass(col); + } + else + { + text = grid->OnGetItemText(row, col + 1); + typOid = grid->colTypClasses[col]; + } + + if (!needQuote && rbQuoteStrings->GetValue()) + { + // find out if string + switch (typOid) + { + case PGTYPCLASS_NUMERIC: + case PGTYPCLASS_BOOL: + break; + default: + needQuote = true; + break; + } + } + if (needQuote) + { + wxString qc = cbQuoteChar->GetValue(); + text.Replace(qc, qc + qc); + line += qc + text + qc; + } + else + line += text; + } + if (rbCRLF->GetValue()) + line += wxT("\r\n"); + else + line += wxT("\n"); + + if (rbUnicode->GetValue()) + file.Write(line, wxConvUTF8); + else + { + buf = line.mb_str(wxConvLibc); + if (!buf) + skipped++; + else + file.Write(line, wxConvLibc); + } + + if (set) + set->MoveNext(); + } + file.Close(); + + if (skipped) + wxLogError(wxPLURAL( + "Data export incomplete.\n\n%d row contained characters that could not be converted to the local charset.\n\nPlease correct the data or try using UTF8 instead.", + "Data export incomplete.\n\n%d rows contained characters that could not be converted to the local charset.\n\nPlease correct the data or try using UTF8 instead.", + skipped), skipped); + else + wxMessageBox(_("Data export completed successfully."), _("Export data"), wxICON_INFORMATION | wxOK); + + return true; +} + + +void frmExport::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + +void frmExport::OnBrowseFile(wxCommandEvent &ev) +{ + wxString directory; + wxString filename; + + if (txtFilename->GetValue().IsEmpty()) + directory = wxGetHomeDir(); + else + { + directory = wxFileName(txtFilename->GetValue()).GetPath(); + filename = wxFileName(txtFilename->GetValue()).GetFullName(); + } + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select export filename"), directory, filename, + _("CSV files (*.csv)|*.csv|Data files (*.dat)|*.dat|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog file(this, _("Select export filename"), directory, filename, + _("CSV files (*.csv)|*.csv|Data files (*.dat)|*.dat|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } +} diff --git a/frm/frmGrantWizard.cpp b/frm/frmGrantWizard.cpp new file mode 100644 index 0000000..f4d70fa --- /dev/null +++ b/frm/frmGrantWizard.cpp @@ -0,0 +1,340 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmGrantWizard.cpp - Grant Wizard dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmGrantWizard.h" +#include "frm/frmMain.h" +#include "utils/sysLogger.h" +#include "ctl/ctlSecurityPanel.h" +#include "schema/pgFunction.h" +#include "schema/pgSequence.h" +#include "schema/pgTable.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" + +// Icons +#include "images/index.pngc" + + +#define chkList CTRL_CHECKLISTBOX("chkList") + + + +BEGIN_EVENT_TABLE(frmGrantWizard, ExecutionDialog) + EVT_NOTEBOOK_PAGE_CHANGED(XRCID("nbNotebook"), frmGrantWizard::OnPageSelect) + EVT_BUTTON(XRCID("btnChkAll"), frmGrantWizard::OnCheckAll) + EVT_BUTTON(XRCID("btnUnchkAll"), frmGrantWizard::OnUncheckAll) + EVT_CHECKLISTBOX(XRCID("chkList"), frmGrantWizard::OnChange) +END_EVENT_TABLE() + + +frmGrantWizard::frmGrantWizard(frmMain *form, pgObject *obj) : ExecutionDialog(form, obj) +{ + nbNotebook = 0; + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmGrantWizard")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(GRANTWIZARDTITLE)); + + // Icon + SetIcon(*index_png_ico); + nbNotebook = CTRL_NOTEBOOK("nbNotebook"); + sqlPane = 0; + + Restore(); + EnableOK(false); +} + + +frmGrantWizard::~frmGrantWizard() +{ + SavePosition(); + Abort(); +} + + +wxString frmGrantWizard::GetHelpPage() const +{ + wxString page = wxT("pg/sql-grant"); + + return page; +} + +void frmGrantWizard::OnChange(wxCommandEvent &event) +{ + sqlPane->SetReadOnly(false); + sqlPane->SetText(GetSql()); + sqlPane->SetReadOnly(true); + + if (sqlPane->GetText().IsEmpty()) + EnableOK(false); + else + EnableOK(true); +} + + +void frmGrantWizard::OnUncheckAll(wxCommandEvent &event) +{ + unsigned int i; + for (i = 0 ; i < chkList->GetCount() ; i++) + chkList->Check(i, false); + + OnChange(event); +} + + + +void frmGrantWizard::OnCheckAll(wxCommandEvent &event) +{ + unsigned int i; + for (i = 0 ; i < chkList->GetCount() ; i++) + chkList->Check(i, true); + + OnChange(event); +} + +void frmGrantWizard::OnPageSelect(wxNotebookEvent &event) +{ + if (nbNotebook && sqlPane && event.GetSelection() == (int)nbNotebook->GetPageCount() - 2) + { + sqlPane->SetReadOnly(false); + sqlPane->SetText(GetSql()); + sqlPane->SetReadOnly(true); + } +} + + +void frmGrantWizard::AddObjects(pgCollection *collection) +{ + bool traverseKids = (!collection->IsCollection() || collection->GetMetaType() == PGM_SCHEMA); + + if (!traverseKids) + { + pgaFactory *factory = collection->GetFactory(); + if (!factory->IsCollectionFor(tableFactory) && + !factory->IsCollectionFor(functionFactory) && + !factory->IsCollectionFor(triggerFunctionFactory) && + !factory->IsCollectionFor(procedureFactory) && + !factory->IsCollectionFor(viewFactory) && + !factory->IsCollectionFor(extTableFactory) && + !factory->IsCollectionFor(sequenceFactory)) + return; + } + + wxCookieType cookie; + wxTreeItemId item = mainForm->GetBrowser()->GetFirstChild(collection->GetId(), cookie); + + while (item) + { + pgObject *obj = mainForm->GetBrowser()->GetObject(item); + if (obj) + { + if (traverseKids) + AddObjects((pgCollection *)obj); + else + { + if (obj->CanEdit()) + { + objectArray.Add(obj); + chkList->Append((wxString)wxGetTranslation(obj->GetTypeName()) + wxT(" ") + obj->GetFullIdentifier()); + } + } + } + item = mainForm->GetBrowser()->GetNextChild(collection->GetId(), cookie); + } +} + +void frmGrantWizard::Go() +{ + chkList->SetFocus(); + + wxString privList = wxT("INSERT,SELECT,UPDATE,DELETE,TRUNCATE,REFERENCES,TRIGGER"); + const char *privChar = "arwdDxt"; + + switch (object->GetMetaType()) + { + case PGM_DATABASE: + case PGM_SCHEMA: + privList.Append(wxT(",EXECUTE,USAGE")); + privChar = "arwdDxtXU"; + break; + case PGM_FUNCTION: + privList = wxT("EXECUTE"); + privChar = "X"; + break; + case PGM_SEQUENCE: + privList = wxT("SELECT,UPDATE,USAGE"); + privChar = "rwU"; + break; + case GP_EXTTABLE: + privList = wxT("SELECT"); + privChar = "r"; + default: + break; + } + + securityPage = new ctlSecurityPanel(nbNotebook, privList, privChar, mainForm->GetImageList()); + securityPage->SetConnection(object->GetConnection()); + this->Connect(EVT_SECURITYPANEL_CHANGE, wxCommandEventHandler(frmGrantWizard::OnChange)); + + sqlPane = new ctlSQLBox(nbNotebook, CTL_PROPSQL, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSUNKEN_BORDER | wxTE_READONLY | wxTE_RICH2); + nbNotebook->AddPage(sqlPane, wxT("SQL")); + + txtMessages = new wxTextCtrl(nbNotebook, CTL_MSG, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxHSCROLL); + nbNotebook->AddPage(txtMessages, _("Messages")); + + AddObjects((pgCollection *)object); + + + if (securityPage->cbGroups) + { + pgSet *set = object->GetConnection()->ExecuteSet(wxT("SELECT groname FROM pg_group ORDER BY groname")); + + if (set) + { + while (!set->Eof()) + { + securityPage->cbGroups->Append(wxT("group ") + set->GetVal(0)); + set->MoveNext(); + } + delete set; + } + + if (settings->GetShowUsersForPrivileges()) + { + set = object->GetConnection()->ExecuteSet(wxT("SELECT usename FROM pg_user ORDER BY usename")); + + if (set) + { + securityPage->stGroup->SetLabel(_("Group/User")); + + while (!set->Eof()) + { + securityPage->cbGroups->Append(set->GetVal(0)); + set->MoveNext(); + } + delete set; + Layout(); + } + } + } + + Layout(); + Show(true); + + // Work around a weird display bug in wx2.7 + this->Refresh(); +} + + +wxString frmGrantWizard::GetSql() +{ + wxString sql; + + unsigned int i; + for (i = 0 ; i < chkList->GetCount() ; i++) + { + if (chkList->IsChecked(i)) + { + wxString tmp; + + pgObject *obj = (pgObject *)objectArray.Item(i); + + switch (obj->GetMetaType()) + { + case PGM_FUNCTION: + { + if (((pgFunction *)obj)->GetIsProcedure()) + { + tmp = securityPage->GetGrant(wxT("X"), wxT("PROCEDURE ") + + obj->GetQuotedFullIdentifier() + wxT("(") + + ((pgProcedure *)obj)->GetArgSigList() + wxT(")")); + } + else + { + tmp = securityPage->GetGrant(wxT("X"), wxT("FUNCTION ") + + obj->GetQuotedFullIdentifier() + wxT("(") + + ((pgFunction *)obj)->GetArgSigList() + wxT(")")); + } + break; + } + case PGM_VIEW: + tmp = securityPage->GetGrant(wxT("arwdxt"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + break; + case PGM_SEQUENCE: + tmp = securityPage->GetGrant(wxT("rwU"), wxT("SEQUENCE ") + obj->GetQuotedFullIdentifier()); + break; + case GP_EXTTABLE: + tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + default: + if (obj->GetTypeName().Upper() == wxT("EXTERNAL TABLE")) // somewhat of a hack + { + tmp = securityPage->GetGrant(wxT("r"), wxT("TABLE ") + obj->GetQuotedFullIdentifier()); + } + else + tmp = securityPage->GetGrant(wxT("arwdDxt"), obj->GetTypeName().Upper() + wxT(" ") + obj->GetQuotedFullIdentifier()); + break; + } + + if (!tmp.IsEmpty()) + sql.Append(tmp); + } + } + return sql; +} + + +grantWizardFactory::grantWizardFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Grant Wizard..."), _("Grants rights to multiple objects")); +} + + +wxWindow *grantWizardFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmGrantWizard *frm = new frmGrantWizard(form, obj); + frm->Go(); + return 0; +} + + +bool grantWizardFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + switch (obj->GetMetaType()) + { + case PGM_TABLE: + case PGM_FUNCTION: + case PGM_SEQUENCE: + case PGM_VIEW: + case GP_EXTTABLE: + if (obj->IsCollection() && obj->GetSchema()->GetMetaType() != PGM_CATALOG) + return obj->GetSchema()->CanEdit(); + break; + + case PGM_SCHEMA: + return obj->CanEdit(); + default: + break; + } + } + return false; +} diff --git a/frm/frmHbaConfig.cpp b/frm/frmHbaConfig.cpp new file mode 100644 index 0000000..044a7d8 --- /dev/null +++ b/frm/frmHbaConfig.cpp @@ -0,0 +1,394 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHbaConfig.cpp - Backend access configuration tool +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmHbaConfig.h" +#include "dlg/dlgHbaConfig.h" +#include "frm/frmMain.h" +#include "utils/utffile.h" +#include "schema/pgServer.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#define CTL_CFGVIEW 345 + +#include +WX_DEFINE_OBJARRAY(pgHbaConfigLineArray); + + +BEGIN_EVENT_TABLE(frmHbaConfig, frmConfig) + EVT_MENU(MNU_UNDO, frmHbaConfig::OnUndo) + EVT_MENU(MNU_DELETE, frmHbaConfig::OnDelete) + EVT_MENU(MNU_CONTENTS, frmHbaConfig::OnContents) + EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmHbaConfig::OnEditSetting) + EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmHbaConfig::OnSelectSetting) +END_EVENT_TABLE() + +#define BACE_TITLE _("Backend Access Configuration Editor") + + +frmHbaConfig::frmHbaConfig(frmMain *parent, pgServer *server) + : frmConfig(parent, BACE_TITLE, 0) +{ + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Configuration Editor"); + if (server) + conn = server->CreateConn(wxEmptyString, 0, applicationname); + Init(); + + if (conn) + { + serverFileName = conn->ExecuteScalar(wxT("SHOW hba_file")); + if (serverFileName == wxT("unset") || serverFileName.IsEmpty()) + serverFileName = wxT("pg_hba.conf"); + + wxString txt; + txt.Printf(_(" - %s on %s (%s:%d)"), + serverFileName.c_str(), server->GetDescription().c_str(), + server->GetName().c_str(), server->GetPort()); + SetTitle(BACE_TITLE + txt); + + wxString str; + str = conn->ExecuteScalar(wxT("SELECT pg_file_read('") + serverFileName + wxT("', 0, ") + wxT("pg_file_length('") + serverFileName + wxT("'))")); + + DisplayFile(str); + + statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), conn->GetHost().c_str())); + } +} + + +frmHbaConfig::frmHbaConfig(const wxString &title, const wxString &configFile) + : frmConfig(title + wxT(" - ") + _("Backend Access Configuration Editor"), configFile) +{ + + Init(); + + OpenLastFile(); +} + + +frmHbaConfig::~frmHbaConfig() +{ +} + + +void frmHbaConfig::Init() +{ + appearanceFactory->SetIcons(this); + + InitFrame(wxT("frmHbaConfig")); + RestorePosition(150, 150, 650, 300, 300, 200); + + + listEdit = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + listEdit->SetImageList(configImageList, wxIMAGE_LIST_SMALL); + + listEdit->AddColumn(_("Type"), 40); + listEdit->AddColumn(_("Database"), 80); + listEdit->AddColumn(_("User"), 80); + listEdit->AddColumn(_("IP-Address"), 100); + listEdit->AddColumn(_("Method"), 40); + listEdit->AddColumn(_("Option"), 100); + + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); + + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); +} + + +void frmHbaConfig::OnSelectSetting(wxListEvent &event) +{ + // Enable delete because an item has been selected + if (event.GetIndex() != listEdit->GetItemCount() - 1) + { + editMenu->Enable(MNU_DELETE, true); + toolBar->EnableTool(MNU_DELETE, true); + } + else + { + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); + } + + // Disable undo because we don't want to undo the wrong line. + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_UNDO, false); +} + + +void frmHbaConfig::DisplayFile(const wxString &str) +{ + lines.Empty(); + + filetype = wxTextFileType_Unix; + wxStringTokenizer strtok; + + if (str.Find('\r') >= 0) + { + if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n"))) + filetype = wxTextFileType_Dos; + else + filetype = wxTextFileType_Mac; + + strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY); + } + else + strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY); + + while (strtok.HasMoreTokens()) + { + pgHbaConfigLine *line = new pgHbaConfigLine(strtok.GetNextToken()); + lines.Add(line); + } + + listEdit->DeleteAllItems(); + + size_t i = lines.GetCount(); + + // make sure the last line is empty + + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgHbaConfigLine &line = lines.Item(i); + const wxChar *connTypeStr = line.GetConnectType(); + if ((line.isValid || (!line.isValid && !line.isComment)) && !line.GetText().IsEmpty()) + { + int imgIndex = 0; + if (!line.isComment) + imgIndex = 1; + long pos = listEdit->AppendItem(imgIndex, connTypeStr, line.database, line.user); + listEdit->SetItem(pos, 3, line.ipaddress); + listEdit->SetItem(pos, 4, line.GetMethod()); + listEdit->SetItem(pos, 5, line.option); + + line.item = pos; + } + } + if (!i || !lines.Item(i - 1).text.IsEmpty()) + { + pgHbaConfigLine *line = new pgHbaConfigLine(); + lines.Add(line); + line->item = listEdit->AppendItem(0, wxString(wxEmptyString)); + } +} + + +void frmHbaConfig::WriteFile(pgConn *conn) +{ + wxString str; + size_t i; + for (i = 0 ; i < lines.GetCount() - 1 ; i++) + str.Append(lines.Item(i).GetText() + wxT("\n")); + + if (DoWriteFile(str, conn)) + { + changed = false; + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + // make intermediate change current + for (i = 0 ; i < lines.GetCount() ; i++) + lines.Item(i).Init(lines.Item(i).GetText()); + } +} + + +wxString frmHbaConfig::GetHintString() +{ + wxString hint; + return hint; +} + + +wxString frmHbaConfig::GetHelpPage() const +{ + wxString page = wxT("client-authentication"); + return page; +} + + +void frmHbaConfig::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + + +void frmHbaConfig::OnUndo(wxCommandEvent &ev) +{ + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + size_t i; + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgHbaConfigLine &line = lines.Item(i); + + if (line.item == pos) + { + line.Init(line.text); + UpdateDisplay(line); + break; + } + } + } +} + +void frmHbaConfig::OnDelete(wxCommandEvent &event) +{ + bool found = false; + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + listEdit->DeleteCurrentItem(); + size_t i; + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item == pos) + { + lines.RemoveAt(i); + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, false); + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, false); + toolBar->EnableTool(MNU_DELETE, false); + found = true; + break; + } + } + if (found) + { + /* Renumber all positions */ + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item > pos) + lines.Item(i).item--; + } + } + } +} + + +void frmHbaConfig::UpdateDisplay(pgHbaConfigLine &line) +{ + long pos = line.item; + listEdit->SetItemImage(pos, (line.isComment ? 0 : 1)); + listEdit->SetItem(pos, 0, line.GetConnectType()); + listEdit->SetItem(pos, 1, line.database); + listEdit->SetItem(pos, 2, line.user); + listEdit->SetItem(pos, 3, line.ipaddress); + listEdit->SetItem(pos, 4, line.GetMethod()); + listEdit->SetItem(pos, 5, line.option); +} + + +void frmHbaConfig::OnEditSetting(wxListEvent &event) +{ + long pos = event.GetIndex(); + if (pos < 0) + return; + + size_t i; + + for (i = 0 ; i < lines.GetCount() ; i++) + { + if (lines.Item(i).item == pos) + { + pgHbaConfigLine &line = lines.Item(i); + bool isLastLine = (i == lines.GetCount() - 1 && line.isComment && !line.GetConnectType()); + + dlgHbaConfig dlg(this, &line, conn); + if (dlg.Go() == wxID_OK) + { + UpdateDisplay(line); + + if (isLastLine) + { + long pos = listEdit->AppendItem(0, wxString(wxEmptyString)); + pgHbaConfigLine *line = new pgHbaConfigLine(); + line->item = pos; + lines.Add(line); + } + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + } + break; + } + } +} + + +hbaConfigFactory::hbaConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, wxT("pg_hba.conf"), _("Edit server access configuration file.")); +} + + +wxWindow *hbaConfigFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = obj->GetServer(); + if (server) + { + frmHbaConfig *frm = new frmHbaConfig(form, server); + frm->Go(); + return frm; + } + return 0; +} + + +bool hbaConfigFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgServer *server = obj->GetServer(); + if (server) + { + pgConn *conn = server->GetConnection(); + return conn && server->GetSuperUser() && conn->HasFeature(FEATURE_FILEREAD); + } + } + return false; +} + + +hbaConfigFileFactory::hbaConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("Open pg_hba.conf..."), _("Open configuration editor with pg_hba.conf.")); +} + + +wxWindow *hbaConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmConfig *dlg = new frmHbaConfig(form); + dlg->Go(); + dlg->DoOpen(); + return dlg; +} diff --git a/frm/frmHint.cpp b/frm/frmHint.cpp new file mode 100644 index 0000000..e8d3a74 --- /dev/null +++ b/frm/frmHint.cpp @@ -0,0 +1,510 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHint.cpp - PostgreSQL Guru hints +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include "wx/wxhtml.h" +#include + +// App headers +#include "copyright.h" +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "utils/misc.h" +#include "utils/utffile.h" + +// Icons +#include "images/hint.pngc" +#include "images/hint2.pngc" + + + +#define HINT_CANSUPPRESS 1 +#define HINT_CANABORT 2 +#define HINT_CANFIX 4 +#define HINT_YESNO 8 + + +struct make_dumb_compilers_happy // unnamed structs don't make all compilers happy... +{ + const wxChar *hintPage; + const wxChar *hintCaption; + const wxChar *fixText; + const wxChar *helpItem; + int flags; +} +hintArray[] = +{ + { + HINT_CONNECTSERVER, + __("Server not listening"), + 0, + wxT("pg/runtime-config#runtime-config-connection"), + HINT_CANSUPPRESS + }, + { + HINT_MISSINGHBA, + __("Server denies access"), + 0, + wxT("pg/client-authentication#auth-pg-hba-conf"), + HINT_CANSUPPRESS + }, + { + HINT_MISSINGIDENT, + __("Ident authentication failed"), + 0, + wxT("pg/auth-methods#auth-ident"), + HINT_CANSUPPRESS + }, + { + HINT_PRIMARYKEY, + __("Creation of primary key suggested"), + 0, + wxT("pg/ddl-constraints"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_FKINDEX, + __("Creation of index in referencing table suggested"), + 0, + wxT("pg/ddl-constraints#ddl-constraints-fk"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_VACUUM, + __("Running VACUUM recommended"), + __("VACUUM"), + wxT("pg/maintenance#routine-vacuuming"), + HINT_CANSUPPRESS | HINT_CANFIX + }, + { + HINT_VACUUM_FULL, + __("Running VACUUM FULL not recommended"), + __("VACUUM FULL"), + wxT("pg/sql-vacuum"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_QUERYRUNTIME, + __("Query took a long time to complete"), + 0, + wxT("query"), + HINT_CANSUPPRESS | HINT_CANABORT | HINT_YESNO + }, + { + HINT_INSTRUMENTATION, + __("Server instrumentation not installed"), + 0, + wxEmptyString, + HINT_CANSUPPRESS + }, + { + HINT_INSTRUMENTATION_91_WITH, + __("Server instrumentation not installed"), + 0, + wxEmptyString, + HINT_CANSUPPRESS | HINT_CANFIX + }, + { + HINT_INSTRUMENTATION_91_WITHOUT, + __("Server instrumentation not installed"), + 0, + wxEmptyString, + HINT_CANSUPPRESS + }, + { + HINT_ENCODING_UNICODE, + __("Database encoding is Unicode"), + 0, + wxT("pg/multibyte"), + HINT_CANSUPPRESS + }, + { + HINT_ENCODING_ASCII, + __("Database encoding is SQL_ASCII"), + 0, + wxT("pg/multibyte"), + HINT_CANSUPPRESS + }, + { + HINT_READONLY_NOPK, + __("Can't edit tables without primary key"), + 0, + wxT("editgrid"), + HINT_CANSUPPRESS + }, + { + HINT_AUTOVACUUM, + _("Enabling autovacuum recommended"), + 0, + wxT("pg/maintenance#autovacuum"), + HINT_CANSUPPRESS + }, + { + HINT_OBJECT_EDITING, + _("Editing views, stored procedures or functions"), + 0, + wxT("query"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { + HINT_SAVING_PASSWORDS, + _("Saving passwords"), + 0, + wxT("pg/libpq-pgpass"), + HINT_CANSUPPRESS | HINT_CANABORT + }, + { 0, 0, 0, 0 } +}; + + +BEGIN_EVENT_TABLE(frmHint, DialogWithHelp) + EVT_BUTTON(XRCID("btnFix"), frmHint::OnFix) +END_EVENT_TABLE(); + + +#define chkSuppress CTRL_CHECKBOX("chkSuppress") +#define htmlHint (XRCCTRL(*this, "htmlHint", wxHtmlWindow)) +#define btnFix CTRL_BUTTON("btnFix") +#define btnYes CTRL_BUTTON("wxID_YES") +#define btnNo CTRL_BUTTON("wxID_NO") +#define btnHelp CTRL_BUTTON("wxID_HELP") + +frmHint::frmHint(wxWindow *fr, bool _force) : DialogWithHelp(0) +{ + force = _force; + SetFont(settings->GetSystemFont()); + LoadResource(fr, wxT("frmHint")); + RestorePosition(); + + if (force) + btnCancel->Disable(); + + SetIcon(*hint_png_ico); +} + + + +wxString frmHint::GetPage(const wxChar *hintPage) +{ + wxString page; + + wxString cn = settings->GetCanonicalLanguageName(); + if (cn.IsEmpty()) + cn = wxT("en_US"); + + wxString filename = docPath + wxT("/") + cn + wxT("/hints/") + hintPage + wxT(".html"); + + if (!wxFile::Exists(filename)) + filename = docPath + wxT("/en_US/hints/") + hintPage + wxT(".html"); + if (wxFile::Exists(filename)) + { + wxUtfFile file(filename, wxFile::read, wxFONTENCODING_UTF8); + file.Read(page); + } + + return page; +} + + +void frmHint::SetHint(int hintno, const wxString &info) +{ + hintnos.Add(hintno); + SetHint(info); +}; + + +void frmHint::SetHint(const wxArrayInt &_hintnos, const wxString &info) +{ + hintnos = _hintnos; + SetHint(info); +} + + +void frmHint::SetHint(const wxString &info) +{ + currentHint = hintnos.Item(0); + + bool canSuppress = false; + if (hintnos.GetCount() == 1) + { + if (hintArray[currentHint].flags & HINT_CANSUPPRESS) + canSuppress = true; + SetTitle(_("Guru Hint") + wxString(wxT(" - ")) + wxGetTranslation(hintArray[currentHint].hintCaption)); + + wxString page = GetPage(hintArray[currentHint].hintPage); + page.Replace(wxT(""), HtmlEntities(info)); + + htmlHint->SetPage(page); + } + else + { + SetTitle(_("Guru Hints")); + + wxString header = GetPage(wxT("multiple")); + wxString pages; + + if (header.IsEmpty()) + { + header = + wxT("\n") + wxT("\n") + wxT("\n") + wxT("Guru Hints\n") + wxT("

\n"); + } + else + { + int o = header.Find(wxT("")); + if (o > 0) + header = header.Left(o) + wxT("

"); + } + + size_t i; + for (i = 0 ; i < hintnos.GetCount() ; i++) + { + int hintno = hintnos.Item(i); + if (hintArray[hintno].flags & HINT_CANSUPPRESS) + canSuppress = true; + wxString page = GetPage(hintArray[hintno].hintPage); + int a = page.Find(wxT("")); + int o = page.Find(wxT("")); + if (a < 0) + a = 0; + if (o < 0) + o = wxString::npos; + + + int ha = page.Find(wxT("

")); + int ho = page.Find(wxT("

")); + if (ha < 0) + ha = page.Find(wxT("

")); + if (ho < 0) + ho = page.Find(wxT("

")); + + if (ha > a && ho > ha) + { + wxString hintTitle = page.Mid(ha + 4, ho - ha - 4); + + pages += page.Mid(a, ha - a) + + wxT("

") + + hintTitle + wxT("") + + page.Mid(ho, o - ho); + header += wxString(wxT("") + + hintTitle + wxT("
"); + } + else + pages += page.Mid(a, o - a); + } + + pages.Replace(wxT(""), info); + pages.Replace(wxT(""), info); + + htmlHint->SetPage(header + wxT("

") + pages + wxT("\n")); + } + + chkSuppress->SetValue(false); + chkSuppress->Enable(!force && canSuppress); + + if (force || !(hintArray[currentHint].flags & HINT_CANABORT)) + btnCancel->Disable(); + if (!(hintArray[currentHint].flags & HINT_CANFIX)) + btnFix->Hide(); + + if (!(hintArray[currentHint].flags & HINT_CANFIX)) + btnFix->Hide(); + else if (hintArray[currentHint].fixText) + btnFix->SetLabel(wxGetTranslation(hintArray[currentHint].fixText)); + + if (hintArray[currentHint].flags & HINT_YESNO) + btnOK->Hide(); + else + { + btnYes->Hide(); + btnNo->Hide(); + } + + if (hintArray[currentHint].helpItem == wxEmptyString) + btnHelp->Disable(); + else + btnHelp->Enable(); +}; + + +frmHint::~frmHint() +{ + if (!force && chkSuppress->GetValue()) + { + size_t i; + for (i = 0 ; i < hintnos.GetCount() ; i++) + { + int hintno = hintnos.Item(i); + if (hintArray[hintno].flags & HINT_CANSUPPRESS) + settings->Write(wxString(wxT("Hints/")) + hintArray[hintno].hintPage, wxT("Suppress")); + } + } + SavePosition(); +} + + +wxString frmHint::GetHelpPage() const +{ + const wxChar *helpItem = hintArray[currentHint].helpItem; + if (helpItem) + return helpItem; + + return wxT("guruhints"); +} + + +void frmHint::ResetHints() +{ + int hintno = 0; + while (hintArray[hintno].hintPage) + { + settings->Write(wxString(wxT("Hints/")) + hintArray[hintno].hintPage, wxString(wxEmptyString)); + hintno++; + } +} + + +int frmHint::GetHintNo(const wxString &hint) +{ + int hintno = 0; + while (hintArray[hintno].hintPage) + { + if (hintArray[hintno].hintPage == hint) + return hintno; + hintno++; + } + return -1; +} + + +bool frmHint::WantHint(const wxString &hint) +{ + int hintno = GetHintNo(hint); + if (hintno < 0) + return false; + + return WantHint(hintno); +} + + +bool frmHint::WantHint(int hintno) +{ + if (hintno < 0) + return false; + + if ((hintArray[hintno].flags & HINT_CANSUPPRESS) && settings->GetSuppressGuruHints()) + return false; + + if (settings->Read(wxString(wxT("Hints/")) + hintArray[hintno].hintPage, wxEmptyString) != wxT("Suppress")) + return true; + + return false; +} + + + +int frmHint::ShowHint(wxWindow *fr, const wxArrayString &hints, const wxString &info, bool force) +{ + wxArrayInt hintnos; + size_t i; + + if(!hints.GetCount()) + return wxID_OK; + for (i = 0 ; i < hints.GetCount() ; i++) + { + int hintNo = GetHintNo(hints.Item(i)); + if (hintNo >= 0 && (force || WantHint(hintNo))) + hintnos.Add(hintNo); + } + + if (!hintnos.GetCount()) + return wxID_OK; + + frmHint *frm = new frmHint(fr, force); + frm->SetHint(hintnos, info); + + frm->CenterOnParent(); + int rc = frm->ShowModal(); + delete frm; + + if ((rc == wxID_CANCEL || rc == -1)) + rc = wxID_OK; + + return rc; +} + + +int frmHint::ShowHint(wxWindow *fr, const wxString &hint, const wxString &info, bool force) +{ + int rc = wxID_OK; + int hintno = GetHintNo(hint); + + if (WantHint(hintno)) + { + frmHint *frm = new frmHint(fr, force); + frm->SetHint(hintno, info); + + frm->CenterOnParent(); + rc = frm->ShowModal(); + delete frm; + + if ((rc == wxID_CANCEL || rc == -1) && !(hintArray[hintno].flags & HINT_CANABORT)) + rc = wxID_OK; + } + return rc; +} + + +void frmHint::OnFix(wxCommandEvent &ev) +{ + EndModal(HINT_RC_FIX); +} + + + +hintFactory::hintFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool) : actionFactory(list) +{ + mnu->Append(id, _("Hints"), _("Display helpful hints on current object.")); + if (toolbar) + { + const wxBitmap &bmp = (bigTool ? *hint_png_bmp : *hint2_png_bmp); + toolbar->AddTool(id, wxEmptyString, bmp, _("Display helpful hints on current object.")); + } +} + + +wxWindow *hintFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj) + obj->ShowHint(form, true); + else + wxLogMessage(_("There are no hints available for the current object.")); + + return 0; +} + + +bool hintFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetCanHint(); +} + diff --git a/frm/frmImport.cpp b/frm/frmImport.cpp new file mode 100644 index 0000000..ddaf88f --- /dev/null +++ b/frm/frmImport.cpp @@ -0,0 +1,379 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmImport.cpp - Import database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "db/pgConn.h" +#include "frm/frmMain.h" +#include "frm/frmImport.h" +#include "utils/sysLogger.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgPartition.h" + +// Icons +#include "images/reload.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define pickerImportfile CTRL_FILEPICKER("pickerImportfile") +#define cbFormat CTRL_COMBOBOX("cbFormat") +#define cbEncoding CTRL_COMBOBOX("cbEncoding") +#define chkOids CTRL_CHECKBOX("chkOids") +#define chkHeader CTRL_CHECKBOX("chkHeader") +#define cbDelimiter CTRL_COMBOBOX("cbDelimiter") +#define cbQuote CTRL_COMBOBOX("cbQuote") +#define cbEscape CTRL_COMBOBOX("cbEscape") +#define txtNull CTRL_TEXT("txtNull") +#define gauge CTRL_GAUGE("gauge") +#define lstColumnsToImport CTRL_CHECKLISTBOX("lstColumnsToImport") +#define lstIgnoreForColumns CTRL_CHECKLISTBOX("lstIgnoreForColumns") + + +BEGIN_EVENT_TABLE(frmImport, pgDialog) + EVT_COMBOBOX(XRCID("cbFormat"), frmImport::OnChangeFormat) + EVT_BUTTON(wxID_OK, frmImport::OnOK) + EVT_BUTTON (wxID_HELP, frmImport::OnHelp) +END_EVENT_TABLE() + + +frmImport::frmImport(frmMain *form, pgObject *_object, pgConn *_conn) +{ + // Initialize variables + connection = _conn; + object = _object; + done = false; + + // Set-up window + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmImport")); + RestorePosition(); + SetTitle(wxT("Import data from file into ") + object->GetName()); + SetIcon(*reload_png_ico); + + // Fill the encoding combobox + long encNo = 0; + wxString encStr; + cbEncoding->Append(wxT("")); + do + { + encStr = object->GetConnection()->ExecuteScalar( + wxT("SELECT pg_encoding_to_char(") + NumToStr(encNo) + wxT(")")); + if (pgConn::IsValidServerEncoding(encNo) && !encStr.IsEmpty()) + cbEncoding->Append(encStr); + + encNo++; + } + while (!encStr.IsEmpty()); + cbEncoding->SetSelection(0); + + // Fill the columns checklistboxes + wxCookieType cookie; + pgObject *data = 0; + wxTreeItemId columnsItem; + wxTreeItemId item = form->GetBrowser()->GetFirstChild(object->GetId(), cookie); + while (item) + { + data = form->GetBrowser()->GetObject(item); + pgaFactory *factory = data->GetFactory(); + if (factory == columnFactory.GetCollectionFactory()) + columnsItem = item; + if (data->GetMetaType() == PGM_COLUMN && data->IsCollection()) + columnsItem = item; + if (columnsItem) + break; + + item = form->GetBrowser()->GetNextChild(object->GetId(), cookie); + } + + if (columnsItem) + { + pgCollection *coll = (pgCollection *)data; + coll->ShowTreeDetail(form->GetBrowser()); + item = form->GetBrowser()->GetFirstChild(columnsItem, cookie); + + while (item) + { + data = form->GetBrowser()->GetObject(item); + if (data->IsCreatedBy(columnFactory)) + { + pgColumn *column = (pgColumn *)data; + column->ShowTreeDetail(form->GetBrowser()); + if (column->GetColNumber() > 0) + { + lstColumnsToImport->Append(column->GetName()); + lstIgnoreForColumns->Append(column->GetName()); + } + } + item = form->GetBrowser()->GetNextChild(columnsItem, cookie); + } + + for (unsigned int x = 0; x < lstColumnsToImport->GetCount(); x++) + lstColumnsToImport->Check(x, true); + } + + // Fix some widgets + wxCommandEvent ev; + OnChangeFormat(ev); +} + + +frmImport::~frmImport() +{ + SavePosition(); +} + + +void frmImport::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("sql-copy"), HELP_POSTGRESQL); +} + +void frmImport::OnChangeFormat(wxCommandEvent &ev) +{ + bool enabled = cbFormat->GetValue() == wxT("csv"); + chkHeader->Enable(enabled); + cbQuote->Enable(enabled); + cbEscape->Enable(enabled); + lstIgnoreForColumns->Enable(enabled); +} + + +void frmImport::OnOK(wxCommandEvent &ev) +{ + wxString query = wxEmptyString; + wxString columnsToImport = wxEmptyString; + wxString columnsToIgnoreForNulls = wxEmptyString; + bool allColumnsToImport = true; + bool someColumnsToIgnoreForNulls = false; + wxFileName fn; + wxFile *file; + bool copydone = false; + bool goterror = false; + int nCount = 8192; + + if (!done) + { + // Check checklistboxes + for (unsigned int x = 0; x < lstColumnsToImport->GetCount(); x++) + { + if (lstColumnsToImport->IsChecked(x)) + { + if (!columnsToImport.IsEmpty()) + { + columnsToImport.Append(wxT(",")); + } + columnsToImport.Append(qtIdent(lstColumnsToImport->GetString(x))); + } + else + { + allColumnsToImport = false; + } + } + for (unsigned int x = 0; x < lstIgnoreForColumns->GetCount(); x++) + { + if (lstIgnoreForColumns->IsChecked(x)) + { + if (!columnsToIgnoreForNulls.IsEmpty()) + { + columnsToIgnoreForNulls.Append(wxT(",")); + } + columnsToIgnoreForNulls.Append(qtIdent(lstIgnoreForColumns->GetString(x))); + someColumnsToIgnoreForNulls = true; + } + } + + // Check at least one column is selected else raise a warning + if (!allColumnsToImport && columnsToImport.Length() <= 0) + { + wxMessageBox(_("Please select at least one column to import."), _("Import"), wxICON_WARNING | wxOK, this); + return; + } + + // Build COPY query + query = wxT("COPY ") + object->GetSchema()->GetQuotedIdentifier() + wxT(".") + object->GetQuotedIdentifier(); + if (!allColumnsToImport) + { + query += wxT("(") + columnsToImport + wxT(")"); + } + query += wxT(" FROM STDIN "); + if (connection->BackendMinimumVersion(9, 0)) + { + query += wxT("("); + query += wxT("FORMAT '") + cbFormat->GetValue() + wxT("'"); + if (chkOids->GetValue()) + query += wxT(", OIDS"); + if (cbDelimiter->GetValue() == wxT("[tab]")) + query += wxT(", DELIMITER E'\\t'"); + else if (!cbDelimiter->GetValue().IsEmpty()) + query += wxT(", DELIMITER ") + connection->qtDbString(cbDelimiter->GetValue()); + if (!txtNull->GetValue().IsEmpty()) + query += wxT(", NULL ") + connection->qtDbString(txtNull->GetValue()); + if (cbFormat->GetValue() == wxT("csv")) + { + if (chkHeader->GetValue()) + query += wxT(", HEADER"); + if (!cbQuote->GetValue().IsEmpty()) + query += wxT(", QUOTE ") + connection->qtDbString(cbQuote->GetValue()); + if (!cbEscape->GetValue().IsEmpty()) + query += wxT(", ESCAPE ") + connection->qtDbString(cbEscape->GetValue()); + } + if (connection->BackendMinimumVersion(9, 1) && !cbEncoding->GetValue().IsEmpty()) + query += wxT(", ENCODING ") + connection->qtDbString(cbEncoding->GetValue()); + if (cbFormat->GetValue() == wxT("csv")) + { + if (someColumnsToIgnoreForNulls) + query += wxT(", FORCE_NOT_NULL (") + columnsToIgnoreForNulls + wxT(")"); + } + query += wxT(")"); + } + else + { + query += wxT("WITH "); + if (cbFormat->GetValue() == wxT("binary")) + query += wxT("BINARY "); + if (chkOids->GetValue()) + query += wxT("OIDS "); + if (!cbDelimiter->GetValue().IsEmpty()) + query += wxT("DELIMITER ") + connection->qtDbString(cbDelimiter->GetValue()); + if (!txtNull->GetValue().IsEmpty()) + query += wxT("NULL ") + connection->qtDbString(txtNull->GetValue()); + if (cbFormat->GetValue() == wxT("csv")) + { + query += wxT("CSV "); + if (connection->BackendMinimumVersion(8, 0) && chkHeader->GetValue()) + query += wxT("HEADER "); + if (connection->BackendMinimumVersion(8, 0) && !cbQuote->GetValue().IsEmpty()) + query += wxT("QUOTE ") + connection->qtDbString(cbQuote->GetValue()); + if (connection->BackendMinimumVersion(8, 0) && !cbEscape->GetValue().IsEmpty()) + query += wxT("ESCAPE ") + connection->qtDbString(cbEscape->GetValue()); + if (someColumnsToIgnoreForNulls) + query += wxT("FORCE NOT NULL ") + columnsToIgnoreForNulls + wxT(" "); + } + } + + // Check CSV file + if (!wxFileName::FileExists(pickerImportfile->GetPath())) + { + wxString msg; + msg.Printf(_("The file %s doesn't exist.\nPlease select a valid file."), pickerImportfile->GetPath().c_str()); + wxLogError(msg); + return; + } + + // Open CSV file + fn = wxFileName(pickerImportfile->GetPath()); + file = new wxFile(fn.GetFullPath(), wxFile::read); + + // Set range for gauge + gauge->SetRange(file->Length()); + + // Start COPY + if (!connection->StartCopy(query)) + { + goterror = true; + } + + // Send COPY data + while (!copydone && !goterror) + { + // Read a buffer + char *buffer = new char[nCount + 4]; + memset(buffer, 0, nCount + 4); + off_t len = file->Read(buffer, nCount); + + // If we read something, send it to the server + if (len > 0) + { + if (!connection->PutCopyData(buffer, len)) + { + goterror = true; + } + else + { + gauge->SetValue(gauge->GetValue() + len); + Update(); + } + } + + // If we read nothing, we're done + copydone = len == 0; + + // Clean the buffer + delete[] buffer; + } + + // Close CSV file + file->Close(); + + // End COPY + if (goterror) + { + connection->EndPutCopy(_("Copy failed!")); + } + else + { + goterror = !connection->EndPutCopy(wxT("")); + } + + // Get final status of the COPY command + if (!connection->GetCopyFinalStatus()) + { + goterror = true; + } + + if (goterror) + { + wxLogError(_("Copy failed!\n") + connection->GetLastError()); + } + else + { + btnOK->SetLabel(wxT("Done")); + done = true; + } + } + else + { + Close(); + } +} + +importFactory::importFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Import..."), _("Import CSV file into a relation")); +} + + +wxWindow *importFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgDatabase *db = obj->GetDatabase(); + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Import Tool"); + pgConn *conn = db->CreateConn(applicationname); + if (conn) + { + frmImport *frm = new frmImport(form, obj, conn); + frm->Show(); + } + return 0; +} + +bool importFactory::CheckEnable(pgObject *obj) +{ + return obj && (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)); +} diff --git a/frm/frmMain.cpp b/frm/frmMain.cpp new file mode 100644 index 0000000..c9cb432 --- /dev/null +++ b/frm/frmMain.cpp @@ -0,0 +1,1510 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMain.cpp - The main form +// +// Note: Due to the size of frmMain, event handler, browser and statistics +// functions are in events.cpp. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifndef WIN32 +#include +#endif + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// wxAUI +#include + +// App headers +#include "utils/misc.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" +#include "debugger/debugger.h" +#include "frm/frmMain.h" +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLBox.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "agent/pgaJob.h" +#include "schema/pgDatabase.h" +#include "schema/pgServer.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "frm/frmOptions.h" +#include "frm/frmAbout.h" +#include "frm/frmHint.h" +#include "frm/frmGrantWizard.h" +#include "frm/frmMainConfig.h" +#include "frm/frmHbaConfig.h" +#include "frm/frmPgpassConfig.h" +#include "frm/frmBackup.h" +#include "frm/frmBackupGlobals.h" +#include "frm/frmBackupServer.h" +#include "frm/frmRestore.h" +#include "frm/frmReport.h" +#include "frm/frmMaintenance.h" +#include "frm/frmStatus.h" +#include "frm/frmPassword.h" +#ifdef DATABASEDESIGNER +#include "frm/frmDatabaseDesigner.h" +#endif +#include "frm/frmQuery.h" +#include "frm/frmEditGrid.h" +#include "frm/frmImport.h" +#include "dlg/dlgServer.h" +#include "dlg/dlgDatabase.h" +#include "dlg/dlgSearchObject.h" +#include "schema/pgTable.h" +#include "schema/pgView.h" +#include "schema/pgFunction.h" +#include "schema/pgIndex.h" +#include "schema/pgTrigger.h" +#include "pro_scheduler/pgproJob.h" +#include "schema/pgRole.h" +#include "schema/pgRule.h" +#include "schema/pgServer.h" +#include "schema/pgTablespace.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "schema/pgDomain.h" +#include "schema/pgEventTrigger.h" + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#include "utils/sshTunnel.h" +#endif + +#if wxDIALOG_UNIT_COMPATIBILITY +#error wxWindows must be compiled with wxDIALOG_UNIT_COMPATIBILITY=0! +#endif + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +DEFINE_EVENT_TYPE(SSH_TUNNEL_ERROR_EVENT); +#endif + +frmMain::frmMain(const wxString &title) + : pgFrame((wxFrame *)NULL, title) +{ + msgLevel = 0; + lastPluginUtility = NULL; + pluginUtilityCount = 0; + m_refreshing = false; + + dlgName = wxT("frmMain"); + SetMinSize(wxSize(600, 450)); + RestorePosition(50, 50, 750, 550, 600, 450); + + SetFont(settings->GetSystemFont()); + + { + wxLogInfo(wxT("Using fontmetrics %d/%d, %d Point"), GetCharWidth(), GetCharHeight(), GetFont().GetPointSize()); + wxLogInfo(wxT("Native Description '%s'"), GetFont().GetNativeFontInfoDesc().c_str()); + wxWindowDC dc(this); + dc.SetFont(GetFont()); + + wxCoord w, h, d, e; + + dc.GetTextExtent(wxT("M"), &w, &h, &d, &e); + wxLogInfo(wxT("Draw size of 'M': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e); + + dc.GetTextExtent(wxT("g"), &w, &h, &d, &e); + wxLogInfo(wxT("Draw size of 'g': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e); + + dc.GetTextExtent(wxT("Mg"), &w, &h, &d, &e); + wxLogInfo(wxT("Draw size of 'Mg': w=%d, h=%d, descent %d, external lead %d."), w, h, d, e); + } + + // Current database + denyCollapseItem = wxTreeItemId(); + currentObject = 0; + + appearanceFactory->SetIcons(this); + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE); + + // wxGTK needs this deferred + pgaFactory::RealizeImages(); + + CreateMenus(); + + // Setup the object browser + browser = new ctlTree(this, CTL_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER); + browser->SetImageList(imageList); + + // Setup the listview + listViews = new ctlAuiNotebook(this, CTL_NOTEBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_TAB_EXTERNAL_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + + // Switch to the generic list control. Native doesn't play well with + // multi-row select on Mac. +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + + properties = new ctlListView(listViews, CTL_PROPVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + statistics = new ctlListView(listViews, CTL_STATVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + dependencies = new ctlListView(listViews, CTL_DEPVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + dependents = new ctlListView(listViews, CTL_REFVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + + + + // Switch back to the native list control. +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + + listViews->AddPage(properties, _("Properties")); // NBP_PROPERTIES + listViews->AddPage(statistics, _("Statistics")); // NBP_STATISTICS + listViews->AddPage(dependencies, _("Dependencies")); // NBP_DEPENDENCIES + listViews->AddPage(dependents, _("Dependents")); // NBP_DEPENDENTS + + properties->SetImageList(imageList, wxIMAGE_LIST_SMALL); + statistics->SetImageList(imageList, wxIMAGE_LIST_SMALL); + dependencies->SetImageList(imageList, wxIMAGE_LIST_SMALL); + dependents->SetImageList(imageList, wxIMAGE_LIST_SMALL); + + wxColour background; + background = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + statistics->SetBackgroundColour(background); + dependencies->SetBackgroundColour(background); + dependents->SetBackgroundColour(background); + + // Setup the SQL pane + sqlPane = new ctlSQLBox(this, CTL_SQLPANE, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_READONLY | wxTE_RICH2); + sqlPane->SetBackgroundColour(background); + + // Setup menus + pgaFactory::RegisterMenu(this, wxCommandEventHandler(frmMain::OnNew)); + menuFactories->RegisterMenu(this, wxCommandEventHandler(frmMain::OnAction)); + menuFactories->CheckMenu(0, menuBar, toolBar); + + // Kickstart wxAUI + manager.AddPane(browser, wxAuiPaneInfo().Name(wxT("objectBrowser")).Caption(_("Object browser")).Left().MinSize(wxSize(100, 200)).BestSize(wxSize(200, 450))); + manager.AddPane(listViews, wxAuiPaneInfo().Name(wxT("listViews")).Caption(_("Info pane")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(400, 200))); + manager.AddPane(sqlPane, wxAuiPaneInfo().Name(wxT("sqlPane")).Caption(_("SQL pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(400, 200))); + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmMain/Perspective-") + wxString(FRMMAIN_PERSPECTIVE_VER), &perspective, FRMMAIN_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + manager.GetPane(wxT("objectBrowser")).Caption(_("Object browser")); + manager.GetPane(wxT("listViews")).Caption(_("Info pane")); + manager.GetPane(wxT("sqlPane")).Caption(_("SQL pane")); + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + + // Sync the View menu options + viewMenu->Check(MNU_SQLPANE, manager.GetPane(wxT("sqlPane")).IsShown()); + viewMenu->Check(MNU_OBJECTBROWSER, manager.GetPane(wxT("objectBrowser")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + + ResetLists(); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Add the root node + serversObj = new pgServerCollection(serverFactory.GetCollectionFactory()); + wxTreeItemId root = browser->AddRoot(_("Server Groups"), serversObj->GetIconId(), -1, serversObj); + + // Work around a bug in the generic tree control in wxWidgets, + // Per http://trac.wxwidgets.org/ticket/10085 + browser->SetItemText(root, _("Server Groups")); + + // Load servers + RetrieveServers(); + + browser->Expand(root); + browser->SortChildren(root); + browser->SetFocus(); +} + + +frmMain::~frmMain() +{ + // Store the servers, to ensure we store the last database/schema etc + StoreServers(); + + settings->Write(wxT("frmMain/Perspective-") + wxString(FRMMAIN_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + + // Clear the treeview + browser->DeleteAllItems(); + + if (treeContextMenu) + delete treeContextMenu; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(pgadminTunnelThread && pgadminTunnelThread->IsAlive()) + { + pgadminTunnelThread->Cleanup(); + pgadminTunnelThread = NULL; + } +#endif +} + + + +void frmMain::CreateMenus() +{ + // to add a new menu or context menu to the main window, i.e. define a possible + // action on a pgObject, everything has to go into this method. Doing menu related + // stuff elsewhere is plain wrong! + // Create a proper actionFactory (or contextActionFactory) for each of your new actions + // in the new frmXXX.cpp and register it here. + + fileMenu = new wxMenu(); + pluginsMenu = new wxMenu(); + viewMenu = new wxMenu(); + editMenu = new wxMenu(); + newMenu = new wxMenu(); + toolsMenu = new wxMenu(); + slonyMenu = new wxMenu(); + scriptingMenu = new wxMenu(); + viewDataMenu = new wxMenu(); + debuggingMenu = new wxMenu(); + reportMenu = new wxMenu(); + wxMenu *cfgMenu = new wxMenu(); + helpMenu = new wxMenu(); + newContextMenu = new wxMenu(); + + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER ); + toolBar->SetToolBitmapSize(wxSize(32, 32)); + menuFactories = new menuFactoryList(); + + // Load plugins - must do this after creating the menus and the factories + LoadPluginUtilities(); + + //-------------------------- + fileMenu->Append(MNU_SAVEDEFINITION, _("&Save Definition..."), _("Save the SQL definition of the selected object.")); + fileMenu->AppendSeparator(); + new addServerFactory(menuFactories, fileMenu, toolBar); + + viewMenu->Append(MNU_OBJECTBROWSER, _("&Object browser\tCtrl-Alt-O"), _("Show or hide the object browser."), wxITEM_CHECK); + viewMenu->Append(MNU_SQLPANE, _("&SQL pane\tCtrl-Alt-S"), _("Show or hide the SQL pane."), wxITEM_CHECK); + viewMenu->Append(MNU_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + viewMenu->AppendSeparator(); + actionFactory *refFact = new refreshFactory(menuFactories, viewMenu, toolBar); + new countRowsFactory(menuFactories, viewMenu, 0); + new refreshMatViewFactory(menuFactories, viewMenu, 0); + new refreshConcurrentlyMatViewFactory(menuFactories, viewMenu, 0); + new executePgstattupleFactory(menuFactories, viewMenu, 0); + new executePgstatindexFactory(menuFactories, viewMenu, 0); + new enabledisableRuleFactory(menuFactories, toolsMenu, 0); + new enabledisableTriggerFactory(menuFactories, toolsMenu, 0); + new enabledisableEventTriggerFactory(menuFactories, toolsMenu, 0); + new enabledisableJobFactory(menuFactories, toolsMenu, 0); + new disableAllTriggersFactory(menuFactories, toolsMenu, 0); + new enableAllTriggersFactory(menuFactories, toolsMenu, 0); + new validateForeignKeyFactory(menuFactories, toolsMenu, 0); + new validateCheckFactory(menuFactories, toolsMenu, 0); + new validateDomainCheckFactory(menuFactories, toolsMenu, 0); + toolsMenu->AppendSeparator(); + + //-------------------------- + new separatorFactory(menuFactories); + + toolBar->AddSeparator(); + + new passwordFactory(menuFactories, fileMenu, 0); + fileMenu->AppendSeparator(); + optionsFactory *optFact = new optionsFactory(menuFactories, fileMenu, 0); + fileMenu->AppendSeparator(); + new mainConfigFileFactory(menuFactories, fileMenu, 0); + new hbaConfigFileFactory(menuFactories, fileMenu, 0); + new pgpassConfigFileFactory(menuFactories, fileMenu, 0); + + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-Q"), _("Quit this program.")); + + new slonyRestartFactory(menuFactories, slonyMenu, 0); + new slonyUpgradeFactory(menuFactories, slonyMenu, 0); + new slonyFailoverFactory(menuFactories, slonyMenu, 0); + new slonyLockSetFactory(menuFactories, slonyMenu, 0); + new slonyUnlockSetFactory(menuFactories, slonyMenu, 0); + new slonyMergeSetFactory(menuFactories, slonyMenu, 0); + new slonyMoveSetFactory(menuFactories, slonyMenu, 0); + toolsMenu->Append(MNU_SLONY_SUBMENU, _("Slony Replication"), slonyMenu); + + propFactory = new propertyFactory(menuFactories, 0, toolBar); + new separatorFactory(menuFactories); + + + // ------------------------- + + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard")); + editMenu->AppendSeparator(); + + // ------------------------- + + //-------------------------- + + newMenuFactory = new submenuFactory(menuFactories); // placeholder where "New objects" submenu will be inserted + editMenu->Append(newMenuFactory->GetId(), _("New &Object"), newMenu, _("Create a new object.")); + editMenu->AppendSeparator(); + + + //-------------------------- + + new connectServerFactory(menuFactories, toolsMenu, 0); + new disconnectServerFactory(menuFactories, toolsMenu, 0); + new disconnectDatabaseFactory(menuFactories, toolsMenu, 0); + + new startServiceFactory(menuFactories, toolsMenu, 0); + new stopServiceFactory(menuFactories, toolsMenu, 0); + new reloadconfServiceFactory(menuFactories, toolsMenu, 0); + new pausereplayServiceFactory(menuFactories, toolsMenu, 0); + new resumereplayServiceFactory(menuFactories, toolsMenu, 0); + new addnamedrestorepointServiceFactory(menuFactories, toolsMenu, 0); + + new createFactory(menuFactories, editMenu, toolBar); + new dropFactory(menuFactories, editMenu, toolBar); + new dropCascadedFactory(menuFactories, editMenu, 0); + new truncateFactory(menuFactories, editMenu, 0); + new truncateCascadedFactory(menuFactories, editMenu, 0); + new resetTableStatsFactory(menuFactories, editMenu, 0); + new resetFunctionStatsFactory(menuFactories, editMenu, 0); + new reassignDropOwnedFactory(menuFactories, editMenu, 0); + new moveTablespaceFactory(menuFactories, editMenu, 0); + new searchObjectFactory(menuFactories, editMenu, 0); + editMenu->AppendSeparator(); + + new separatorFactory(menuFactories); + + toolBar->AddSeparator(); + toolsMenu->AppendSeparator(); + + debuggingMenuFactory = new submenuFactory(menuFactories); // placeholder where "Debugging" submenu will be inserted + toolsMenu->Append(debuggingMenuFactory->GetId(), _("&Debugging"), debuggingMenu, _("Debugging options for the selected item.")); + new debuggerFactory(menuFactories, debuggingMenu, 0); + new breakpointFactory(menuFactories, debuggingMenu, 0); + + new queryToolFactory(menuFactories, toolsMenu, toolBar); + scriptingMenuFactory = new submenuFactory(menuFactories); // placeholder where "Query Template" submenu will be inserted + toolsMenu->Append(scriptingMenuFactory->GetId(), _("Scripts"), scriptingMenu, _("Start Query Tool with scripted query.")); + new queryToolSqlFactory(menuFactories, scriptingMenu, 0); + new queryToolCreateCascadeFactory(menuFactories, scriptingMenu, 0); + new queryToolSelectFactory(menuFactories, scriptingMenu, 0); + new queryToolExecFactory(menuFactories, scriptingMenu, 0); + new queryToolInsertFactory(menuFactories, scriptingMenu, 0); + new queryToolUpdateFactory(menuFactories, scriptingMenu, 0); + new queryToolDeleteFactory(menuFactories, scriptingMenu, 0); + +#ifdef DATABASEDESIGNER + new databaseDesignerFactory(menuFactories, toolsMenu, toolBar); +#endif + + viewdataMenuFactory = new submenuFactory(menuFactories); // placeholder where "View data" submenu will be inserted + toolsMenu->Append(viewdataMenuFactory->GetId(), _("View &Data"), viewDataMenu, _("View data.")); + + reportMenuFactory = new submenuFactory(menuFactories); // placeholder where "Reports" submenu will be inserted + toolsMenu->Append(reportMenuFactory->GetId(), _("&Reports"), reportMenu, _("Create reports about the selected item.")); + new reportObjectPropertiesFactory(menuFactories, reportMenu, 0); + new reportObjectDdlFactory(menuFactories, reportMenu, 0); + new reportObjectDataDictionaryFactory(menuFactories, reportMenu, 0); + new reportObjectStatisticsFactory(menuFactories, reportMenu, 0); + new reportObjectDependenciesFactory(menuFactories, reportMenu, 0); + new reportObjectDependentsFactory(menuFactories, reportMenu, 0); + new reportObjectListFactory(menuFactories, reportMenu, 0); + new reportCompareFactory(menuFactories, reportMenu, 0); + + + toolsMenu->AppendSeparator(); + + new editGridLimitedFactory(menuFactories, viewDataMenu, toolBar, 100, true); + new editGridLimitedFactory(menuFactories, viewDataMenu, toolBar, 100, false); + new editGridFactory(menuFactories, viewDataMenu, toolBar); + new editGridFilteredFactory(menuFactories, viewDataMenu, toolBar); + + new maintenanceFactory(menuFactories, toolsMenu, toolBar); + + new backupFactory(menuFactories, toolsMenu, 0); + new backupGlobalsFactory(menuFactories, toolsMenu, 0); + new backupServerFactory(menuFactories, toolsMenu, 0); + new restoreFactory(menuFactories, toolsMenu, 0); + new importFactory(menuFactories, toolsMenu, 0); + + new grantWizardFactory(menuFactories, toolsMenu, 0); + new mainConfigFactory(menuFactories, cfgMenu, 0); + new hbaConfigFactory(menuFactories, cfgMenu, 0); + toolsMenu->Append(MNU_CONFIGSUBMENU, _("Server Configuration"), cfgMenu); + toolsMenu->AppendSeparator(); + + new runNowFactory(menuFactories, toolsMenu, 0); + toolsMenu->AppendSeparator(); + + new separatorFactory(menuFactories); + + new propertyFactory(menuFactories, editMenu, 0); + new serverStatusFactory(menuFactories, toolsMenu, 0); + + // Add the plugin toolbar button/menu + new pluginButtonMenuFactory(menuFactories, pluginsMenu, toolBar, pluginUtilityCount); + + //-------------------------- + toolBar->AddSeparator(); + + actionFactory *helpFact = new contentsFactory(menuFactories, helpMenu, 0); + new hintFactory(menuFactories, helpMenu, toolBar, true); + new faqFactory(menuFactories, helpMenu, 0); + new bugReportFactory(menuFactories, helpMenu, 0); + + helpMenu->AppendSeparator(); + + new pgsqlHelpFactory(menuFactories, helpMenu, toolBar, true); + if (!appearanceFactory->GetHideEnterprisedbHelp()) + new edbHelpFactory(menuFactories, helpMenu, toolBar, true); + if (!appearanceFactory->GetHideGreenplumHelp()) + new greenplumHelpFactory(menuFactories, helpMenu, toolBar, true); + new slonyHelpFactory(menuFactories, helpMenu, toolBar, true); + + // Don't include this seperator on Mac, because the only option + // under it will be moved to the application menu. +#ifndef __WXMAC__ + helpMenu->AppendSeparator(); +#endif + + actionFactory *abFact = new aboutFactory(menuFactories, helpMenu, 0); + +#ifdef __WXMAC__ + wxApp::s_macPreferencesMenuItemId = optFact->GetId(); + wxApp::s_macExitMenuItemId = MNU_EXIT; + wxApp::s_macAboutMenuItemId = abFact->GetId(); +#else + (void)optFact; + (void)abFact; +#endif + + + menuBar = new wxMenuBar(); + menuBar->Append(fileMenu, _("&File")); + menuBar->Append(editMenu, _("&Edit")); + // Changing the caption of the plugins menu also needs a similar change below + menuBar->Append(pluginsMenu, _("&Plugins")); + menuBar->Append(viewMenu, _("&View")); + menuBar->Append(toolsMenu, _("&Tools")); + menuBar->Append(helpMenu, _("&Help")); + SetMenuBar(menuBar); + + // Disable the plugins menu if there aren't any. + if (!pluginUtilityCount) + { + pluginsMenu->Append(MNU_DUMMY, _("No plugins installed")); + pluginsMenu->Enable(MNU_DUMMY, false); + } + + treeContextMenu = 0; + + // Status bar + statusBar = CreateStatusBar(4); + int iWidths[4] = {0, -1, 400, 100}; + SetStatusWidths(4, iWidths); + SetStatusBarPane(-1); + statusBar->SetStatusText(wxT(""), 0); + statusBar->SetStatusText(_("Ready."), 1); + statusBar->SetStatusText(_("0 Secs"), 3); + + wxAcceleratorEntry entries[4]; + entries[0].Set(wxACCEL_NORMAL, WXK_F5, refFact->GetId()); + entries[1].Set(wxACCEL_NORMAL, WXK_DELETE, MNU_DELETE); + entries[2].Set(wxACCEL_NORMAL, WXK_F1, helpFact->GetId()); + entries[3].Set(wxACCEL_SHIFT, WXK_F10, MNU_CONTEXTMENU); + wxAcceleratorTable accel(4, entries); + + SetAcceleratorTable(accel); + + // Display the bar and configure buttons. + toolBar->Realize(); +} + + +void frmMain::Refresh(pgObject *data) +{ + bool done = false; + pgObject *obj = NULL; + + StartMsg(data->GetTranslatedMessage(REFRESHINGDETAILS)); + browser->Freeze(); + + wxTreeItemId currentItem = data->GetId(); + if (currentItem) + obj = browser->GetObject(currentItem); + + if (obj && obj->CheckOpenDialogs(browser, currentItem)) + { + wxString msg = _("There are properties dialogues open for one or more objects that would be refreshed. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot refresh browser"), wxICON_WARNING | wxOK); + } + else + { + if (data->GetMetaType() == PGM_SCHEMA && !data->IsCollection() && data->GetConnection()->BackendMinimumVersion(9, 3)) + { + // Event triggers backend functions are at schema level. + // Hence, we can consider that Event Triggers at schema level and partly at database. + // So, if any schema is refreshed, we need to the event trigger collection as well. + // It's a special case, which effects the schema operations on the event triggers as well. + // To solve this, we are navigating to the parent node (database node), and then locating event trigger collections. + // Once we've found the event triggers collection, we refresh it. + // + wxTreeItemId dbItem = browser->GetItemParent(browser->GetItemParent(browser->GetSelection())); + pgCollection *eventTrgCol = browser->FindCollection(eventTriggerFactory, dbItem); + + if(eventTrgCol) + Refresh(eventTrgCol); + } + + // Scan the child nodes and make a list of those that are expanded + // This is not an exact science as node names may change etc. + wxArrayString expandedNodes; + GetExpandedChildNodes(currentItem, expandedNodes); + + browser->DeleteChildren(currentItem); + + // refresh information about the object + data->SetDirty(); + + pgObject *newData = data->Refresh(browser, currentItem); + done = !data->GetConnection() || data->GetConnection()->GetStatus() == PGCONN_OK; + + if (newData != data) + { + wxLogInfo(wxT("Deleting %s %s for refresh"), data->GetTypeName().c_str(), data->GetQuotedFullIdentifier().c_str()); + + if (data == currentObject) + currentObject = newData; + + if (newData) + { + wxLogInfo(wxT("Replacing with new node %s %s for refresh"), newData->GetTypeName().c_str(), newData->GetQuotedFullIdentifier().c_str()); + + newData->SetId(currentItem); // not done automatically + browser->SetItemData(currentItem, newData); + + // Update the node text if this is an object, as it may have been renamed + if (!newData->IsCollection()) + browser->SetItemText(currentItem, newData->GetDisplayName()); + + delete data; + data = NULL; + } + else + { + wxLogInfo(wxT("No object to replace: vanished after refresh.")); + + // If the connection is dead, just return here + if (data->GetConnection()->GetStatus() != PGCONN_OK) + { + CheckAlive(); + browser->Thaw(); + return; + } + + wxTreeItemId delItem = currentItem; + currentItem = browser->GetItemParent(currentItem); + browser->SelectItem(currentItem); + browser->Delete(delItem); + } + } + + if (currentItem) + { + // Select the current node + execSelChange(currentItem, currentItem == browser->GetSelection()); + + // Attempt to expand any child nodes that were previously expanded + ExpandChildNodes(currentItem, expandedNodes); + } + } + + browser->Thaw(); + EndMsg(done); +} + +void frmMain::OnCopy(wxCommandEvent &ev) +{ + wxString text; + + // Attempt to copy from the current object + + // Listview + ctlListView *lv = dynamic_cast(currentControl); + if (lv) + { + int row = lv->GetFirstSelected(); + + while (row >= 0) + { + for (int col = 0; col < lv->GetColumnCount(); col++) + { + text.Append(lv->GetText(row, col) + wxT("\t")); + } + text.Append(wxT("\n")); + row = lv->GetNextSelected(row); + } + text = text.Trim(); + } + + // ctlSQLBox + ctlSQLBox *sb = dynamic_cast(currentControl); + if (sb) + { + text = sb->GetSelectedText(); + } + + // Set the clipboard text + if (text.Length() > 0 && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(wxTextBuffer::Translate(text))); + wxTheClipboard->Close(); + } +} + +void frmMain::GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + while (child.IsOk()) + { + if (browser->IsExpanded(child)) + { + GetExpandedChildNodes(child, expandedNodes); + expandedNodes.Add(GetNodePath(child)); + } + + child = browser->GetNextChild(node, cookie); + } +} + +void frmMain::ExpandChildNodes(wxTreeItemId node, wxArrayString &expandedNodes) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + while (child.IsOk()) + { + if (expandedNodes.Index(GetNodePath(child)) != wxNOT_FOUND) + { + browser->Expand(child); + ExpandChildNodes(child, expandedNodes); + } + + child = browser->GetNextChild(node, cookie); + } +} + +wxString frmMain::GetNodePath(wxTreeItemId node) +{ + wxString path; + path = browser->GetItemText(node).BeforeFirst('(').Trim(); + + wxTreeItemId parent = browser->GetItemParent(node); + while (parent.IsOk()) + { + path = browser->GetItemText(parent).BeforeFirst('(').Trim() + wxT("/") + path; + parent = browser->GetItemParent(parent); + } + + return path; +} + +// Return the path for the current node +wxString frmMain::GetCurrentNodePath() +{ + return GetNodePath(currentObject->GetId()); +} + +// Attempt to reselect the node with the given path +bool frmMain::SetCurrentNode(wxTreeItemId node, const wxString &origPath) +{ + wxString path = origPath.Lower(); + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + + while (child.IsOk()) + { + wxString actNodePath = GetNodePath(child).Lower(); + + if(path.StartsWith(actNodePath)) + { + if(!browser->IsExpanded(child)) + { + browser->SelectItem(child, true); + browser->Expand(child); + } + + if (actNodePath == path) + { + browser->SelectItem(child, true); + return true; + } + else if (SetCurrentNode(child, path)) + return true; + } + child = browser->GetNextChild(node, cookie); + + } + + return false; +} + +void frmMain::ShowObjStatistics(pgObject *data, wxWindow *ctrl) +{ + + // Refresh panes if they're currently shown on screen, unless + // they've been specifically requested (eg. a notebook + // event is telling us they're about to become visible). + + if ((!ctrl && statistics->IsShownOnScreen()) || ctrl == statistics) + { + statistics->Freeze(); + data->ShowStatistics(this, statistics); + statistics->Thaw(); + } + + if ((!ctrl && dependencies->IsShownOnScreen()) || ctrl == dependencies) + { + dependencies->Freeze(); + data->ShowDependencies(this, dependencies); + dependencies->Thaw(); + } + + if ((!ctrl && dependents->IsShownOnScreen()) || ctrl == dependents) + { + dependents->Freeze(); + data->ShowDependents(this, dependents); + dependents->Thaw(); + } +} + + +// Ensure we show the data in any tabs that become visible +void frmMain::OnPageChange(wxAuiNotebookEvent &event) +{ + pgObject *data = browser->GetObject(browser->GetSelection()); + + if (!data) + return; + + ShowObjStatistics(data, ((wxAuiNotebook *)event.GetEventObject())->GetPage(event.GetSelection())); +} + + +ctlListView *frmMain::GetStatistics() +{ + return statistics; +} + +ctlListView *frmMain::GetDependencies() +{ + return dependencies; +} + +ctlListView *frmMain::GetReferencedBy() +{ + return dependents; +} + +bool frmMain::CheckAlive() +{ + bool userInformed = false; + bool closeIt = false; + + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxCookieType cookie; + wxTreeItemId serverItem = browser->GetFirstChild(folderitem, cookie); + while (serverItem) + { + pgServer *server = (pgServer *)browser->GetObject(serverItem); + + if (server && server->IsCreatedBy(serverFactory) && server->connection()) + { + if (server->connection()->IsAlive()) + { + wxCookieType cookie2; + wxTreeItemId item = browser->GetFirstChild(serverItem, cookie2); + while (item) + { + pgObject *obj = browser->GetObject(item); + if (obj && obj->IsCreatedBy(databaseFactory.GetCollectionFactory())) + { + wxCookieType cookie3; + item = browser->GetFirstChild(obj->GetId(), cookie3); + while (item) + { + pgDatabase *db = (pgDatabase *)browser->GetObject(item); + if (db && db->IsCreatedBy(databaseFactory)) + { + pgConn *conn = db->GetConnection(); + if (conn) + { + if (!conn->IsAlive() && (conn->GetStatus() == PGCONN_BROKEN || conn->GetStatus() == PGCONN_BAD)) + { + conn->Close(); + if (!userInformed) + { + wxMessageDialog dlg(this, _("Do you want to attempt to reconnect to the database?"), + wxString::Format(_("Connection to database %s lost."), db->GetName().c_str()), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + + closeIt = (dlg.ShowModal() != wxID_YES); + userInformed = true; + } + if (closeIt) + { + db->Disconnect(); + + browser->DeleteChildren(db->GetId()); + db->UpdateIcon(browser); + } + else + { + // Create a server object and connect it. + wxBusyInfo waiting(wxString::Format(_("Reconnecting to database %s"), + db->GetName().c_str()), this); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + if (!conn->Reconnect()) + { + db->Disconnect(); + + browser->DeleteChildren(db->GetId()); + db->UpdateIcon(browser); + } + else + // Indicate things are back to normal + userInformed = false; + } + + } + } + } + item = browser->GetNextChild(obj->GetId(), cookie3); + } + } + item = browser->GetNextChild(serverItem, cookie2); + } + } + else + { + if (server->connection()->GetStatus() == PGCONN_BROKEN || server->connection()->GetStatus() == PGCONN_BAD) + { + server->connection()->Close(); + if (!userInformed) + { + wxMessageDialog dlg(this, _("Do you want to attempt to reconnect to the server?"), + wxString::Format(_("Connection to server %s lost."), server->GetName().c_str()), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + + closeIt = (dlg.ShowModal() != wxID_YES); + userInformed = true; + } + if (closeIt) + { + server->Disconnect(this); + browser->SelectItem(serverItem); + execSelChange(serverItem, true); + browser->DeleteChildren(serverItem); + } + else + { + // Create a server object and connect it. + wxBusyInfo waiting(wxString::Format(_("Reconnecting to server %s (%s:%d)"), + server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + if (!server->connection()->Reconnect()) + { + server->Disconnect(this); + browser->SelectItem(serverItem); + execSelChange(serverItem, true); + browser->DeleteChildren(serverItem); + } + else + // Indicate things are back to normal + userInformed = false; + } + } + } + } + + serverItem = browser->GetNextChild(folderitem, cookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + return userInformed; +} + + +wxTreeItemId frmMain::RestoreEnvironment(pgServer *server) +{ + wxTreeItemId item, lastItem; + wxString lastDatabase = server->GetLastDatabase(); + if (lastDatabase.IsNull()) + return item; + + wxCookieType cookie; + pgObject *data = 0; + item = browser->GetFirstChild(server->GetId(), cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->IsCreatedBy(databaseFactory.GetCollectionFactory())) + break; + // Get the next item + item = browser->GetNextChild(server->GetId(), cookie); + } + if (!item) + return item; + + // found DATABASES item + listViews->SetSelection(NBP_PROPERTIES); + data->ShowTree(this, browser, 0, 0); + lastItem = item; + + item = browser->GetFirstChild(lastItem, cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->IsCreatedBy(databaseFactory) && data->GetName() == lastDatabase) + break; + // Get the next item + item = browser->GetNextChild(lastItem, cookie); + } + if (!item) + return lastItem; + + // found last DATABASE + data->ShowTree(this, browser, 0, 0); + lastItem = item; + + wxString lastSchema = server->GetLastSchema(); + if (lastSchema.IsNull()) + return lastItem; + + item = browser->GetFirstChild(lastItem, cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->GetMetaType() == PGM_SCHEMA) + break; + // Get the next item + item = browser->GetNextChild(lastItem, cookie); + } + if (!item) + return lastItem; + + // found SCHEMAS item + data->ShowTree(this, browser, 0, 0); + lastItem = item; + + item = browser->GetFirstChild(lastItem, cookie); + while (item) + { + data = browser->GetObject(item); + if (data && data->GetMetaType() == PGM_SCHEMA && data->GetName() == lastSchema) + break; + // Get the next item + item = browser->GetNextChild(lastItem, cookie); + } + + return (item ? item : lastItem); +} + + +int frmMain::ReconnectServer(pgServer *server, bool restore) +{ + // Create a server object and connect it. + wxBusyInfo waiting(wxString::Format(_("Connecting to server %s (%s:%d)"), + server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), this); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + int res = server->Connect(this, true, wxEmptyString, false, true); + + // Check the result, and handle it as appropriate + wxTreeItemId item; + switch (res) + { + case PGCONN_OK: + { + if (restore && server->GetRestore()) + StartMsg(_("Restoring previous environment")); + else + StartMsg(_("Establishing connection")); + + wxLogInfo(wxT("pgServer object initialised as required.")); + + server->ShowTreeDetail(browser); + + browser->Freeze(); + if (restore && server->GetRestore()) + item = RestoreEnvironment(server); + else + item = server->GetId(); + browser->Thaw(); + + if (item) + { + browser->SelectItem(item); + + wxSafeYield(); + browser->Expand(item); + browser->EnsureVisible(item); + } + + if (item) + EndMsg(true); + else + { + if (restore && server->GetRestore()) + EndMsg(false); + else + EndMsg(true); + } + if (item) + GetMenuFactories()->CheckMenu((pgObject *)browser->GetItemData(item), GetMenuBar(), (ctlMenuToolbar *)GetToolBar()); + else + GetMenuFactories()->CheckMenu(server, GetMenuBar(), (ctlMenuToolbar *)GetToolBar()); + browser->SetFocus(); + return res; + } + case PGCONN_DNSERR: + /* + // looks strange to me. Shouldn_t server be removed from the tree as well? + delete server; + OnAddServer(wxCommandEvent()); + break; + */ + case PGCONN_BAD: + ReportConnError(server); + break; + + default: + wxLogInfo(wxT("pgServer object didn't initialise because the user aborted.")); + break; + } + + server->Disconnect(this); + return res; +} + + +bool frmMain::reportError(const wxString &error, const wxString &msgToIdentify, const wxString &hint) +{ + bool identified = false; + + wxString translated = wxGetTranslation(msgToIdentify); + if (translated != msgToIdentify) + { + identified = (error.Find(translated) >= 0); + } + + if (!identified) + { + if (msgToIdentify.Left(20) == wxT("Translator attention")) + identified = (error.Find(msgToIdentify.Mid(msgToIdentify.Find('!') + 1)) >= 0); + else + identified = (error.Find(msgToIdentify) >= 0); + } + + if (identified) + { + if (frmHint::WantHint(hint)) + frmHint::ShowHint(this, hint, error); + } + return identified; +} + + +void frmMain::ReportConnError(pgServer *server) +{ + wxString error = server->GetLastError(); + bool wantHint = false; + + wantHint = reportError(error, __("Translator attention: must match libpq translation!Is the server running on host"), HINT_CONNECTSERVER); + if (!wantHint) + { + wantHint = reportError(error, __("Translator attention: must match backend translation!no pg_hba.conf entry for"), HINT_MISSINGHBA); + } + if (!wantHint) + { + wantHint = reportError(error, __("Translator attention: must match backend translation!Ident authentication failed"), HINT_MISSINGIDENT); + } + if (!wantHint) + { + wxLogError(__("Error connecting to the server: %s"), error.c_str()); + } +} + + +void frmMain::StoreServers() +{ + wxLogInfo(wxT("Storing listed servers for later...")); + + // Store the currently listed servers for later retrieval. + pgServer *server; + int numServers = 0; + + // Get the hostname for later... + char buf[255]; + gethostname(buf, 255); + wxString hostname = wxString(buf, wxConvUTF8); + + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxTreeItemIdValue servercookie; + wxTreeItemId serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + server = (pgServer *)browser->GetItemData(serveritem); + if (server != NULL && server->IsCreatedBy(serverFactory)) + { + wxString key; + ++numServers; + + key.Printf(wxT("Servers/%d/"), numServers); + settings->Write(key + wxT("Server"), server->GetName()); + settings->Write(key + wxT("HostAddr"), server->GetHostAddr()); + settings->Write(key + wxT("Description"), server->GetDescription()); + settings->Write(key + wxT("Service"), server->GetService()); + settings->Write(key + wxT("ServiceID"), server->GetServiceID()); + settings->Write(key + wxT("DiscoveryID"), server->GetDiscoveryID()); + settings->WriteInt(key + wxT("Port"), server->GetPort()); + settings->WriteBool(key + wxT("StorePwd"), server->GetStorePwd()); + settings->Write(key + wxT("Rolename"), server->GetRolename()); + settings->WriteBool(key + wxT("Restore"), server->GetRestore()); + settings->Write(key + wxT("Database"), server->GetDatabaseName()); + settings->Write(key + wxT("Username"), server->GetUsername()); + settings->Write(key + wxT("LastDatabase"), server->GetLastDatabase()); + settings->Write(key + wxT("LastSchema"), server->GetLastSchema()); + settings->Write(key + wxT("DbRestriction"), server->GetDbRestriction()); + settings->Write(key + wxT("Colour"), server->GetColour()); + settings->WriteInt(key + wxT("SSL"), server->GetSSL()); + settings->Write(key + wxT("Group"), server->GetGroup()); + settings->Write(key + wxT("SSLCert"), server->GetSSLCert()); + settings->Write(key + wxT("SSLKey"), server->GetSSLKey()); + settings->Write(key + wxT("SSLRootCert"), server->GetSSLRootCert()); + settings->Write(key + wxT("SSLCrl"), server->GetSSLCrl()); + settings->WriteBool(key + wxT("SSLCompression"), server->GetSSLCompression()); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + settings->WriteBool(key + wxT("SSHTunnel"), server->GetSSHTunnel()); + settings->Write(key + wxT("TunnelHost"), server->GetTunnelHost()); + settings->Write(key + wxT("TunnelUserName"), server->GetTunnelUserName()); + settings->WriteBool(key + wxT("TunnelModePwd"), server->GetAuthModePwd()); + settings->Write(key + wxT("PublicKeyFile"), server->GetPublicKeyFile()); + settings->Write(key + wxT("IdentityFile"), server->GetIdentityFile()); + settings->WriteInt(key + wxT("TunnelPort"), server->GetTunnelPort()); +#endif + pgCollection *coll = browser->FindCollection(databaseFactory, server->GetId()); + if (coll) + { + treeObjectIterator dbs(browser, coll); + pgDatabase *db; + + while ((db = (pgDatabase *)dbs.GetNextObject()) != 0) + settings->Write(key + wxT("Databases/") + db->GetName() + wxT("/SchemaRestriction"), db->GetSchemaRestriction()); + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + // Write the server count + settings->WriteInt(wxT("Servers/Count"), numServers); + settings->FlushChanges(); + wxLogInfo(wxT("Stored %d servers."), numServers); +} + + +void frmMain::RetrieveServers() +{ + wxString label; + int total = 0; + wxTreeItemIdValue groupcookie; + wxTreeItemId groupitem; + + // Retrieve previously stored servers + wxLogInfo(wxT("Reloading servers...")); + + // Create all servers' nodes + serverFactory.CreateObjects(serversObj, browser); + + // Count number of servers and groups + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (groupitem) + { + total = browser->GetChildrenCount(groupitem, false); + label = browser->GetItemText(groupitem) + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(groupitem, label); + browser->SortChildren(groupitem); + browser->Expand(groupitem); + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } +} + +pgServer *frmMain::ConnectToServer(const wxString &servername, bool restore) +{ + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server->GetDescription() == servername) + { + ReconnectServer(server, restore); + return server; + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + return 0; +} + +void frmMain::StartMsg(const wxString &msg) +{ + if (msgLevel++) + return; + + timermsg.Printf(wxT("%s..."), msg.c_str()); + wxBeginBusyCursor(); + stopwatch.Start(0); + + // Create a copy of the message, with %'s escaped for wxLogStatus + wxString logmsg = timermsg; + logmsg.Replace(wxT("%"), wxT("%%")); + wxLogStatus(logmsg); + + statusBar->SetStatusText(timermsg, 1); + statusBar->SetStatusText(wxT(""), 2); +} + + +void frmMain::EndMsg(bool done) +{ + msgLevel--; + + if (!msgLevel) + { + // Get the execution time & display it + float timeval = stopwatch.Time(); + statusBar->SetStatusText(ElapsedTimeToStr(timeval), 3); + + // Display the name of the connection for currently selected object + wxString connection; + if (currentObject) + { + pgConn *conn = currentObject->GetConnection(); + + if (conn) + connection = conn->GetName(); + } + statusBar->SetStatusText(connection, 2); + + // Display the 'Done' message + if (done) + statusBar->SetStatusText(timermsg + _(" Done."), 1); + else + statusBar->SetStatusText(timermsg + _(" Failed."), 1); + + wxLogStatus( + wxT("%s (%s)"), timermsg.c_str(), + ElapsedTimeToStr(timeval).c_str() + ); + wxEndBusyCursor(); + } +} + + +void frmMain::SetStatusText(const wxString &msg) +{ + statusBar->SetStatusText(msg, 1); + statusBar->SetStatusText(wxEmptyString, 2); +} + +void frmMain::SetItemBackgroundColour(wxTreeItemId item, wxColour colour) +{ + wxTreeItemIdValue cookie; + + browser->SetItemBackgroundColour(item, wxColour(colour)); + if (browser->ItemHasChildren(item)) + { + wxTreeItemId childitem = browser->GetFirstChild(item, cookie); + while (childitem) + { + SetItemBackgroundColour(childitem, colour); + childitem = browser->GetNextChild(item, cookie); + } + } +} + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +void frmMain::OnSSHTunnelEvent(wxCommandEvent &event) +{ + wxLogError(event.GetString()); +} +#endif + +///////////////////////////////////////// + + +contentsFactory::contentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Help contents"), _("Open the helpfile.")); +} + + +wxWindow *contentsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); + return 0; +} + + +faqFactory::faqFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&FAQ"), _("Frequently asked questions.")); +} + + +wxWindow *faqFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxLaunchDefaultBrowser(wxT("http://www.pgadmin.org/support/faq.php")); + + return 0; +} + +#include "images/help.pngc" +#include "images/help2.pngc" +pgsqlHelpFactory::pgsqlHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&PostgreSQL Help"), _("Display help on the PostgreSQL database system.")); + if (toolbar) + { + if (bigIcon) + toolbar->AddTool(id, wxEmptyString, *help2_png_bmp, _("Display help on SQL commands.")); + else + toolbar->AddTool(id, wxEmptyString, *help_png_bmp, _("Display help on SQL commands.")); + } +} + + +wxWindow *pgsqlHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_POSTGRESQL); + return 0; +} + +edbHelpFactory::edbHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&EnterpriseDB Help"), _("Display help on the EnterpriseDB database system.")); +} + + +wxWindow *edbHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_ENTERPRISEDB); + return 0; +} + +greenplumHelpFactory::greenplumHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&Greenplum Database Help"), _("Display help on the Greenplum Database system.")); +} + + +wxWindow *greenplumHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_GREENPLUM); + return 0; +} + + +slonyHelpFactory::slonyHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigIcon) : actionFactory(list) +{ + mnu->Append(id, _("&Slony Help"), _("Display help on the Slony replication system.")); +} + + +wxWindow *slonyHelpFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("index"), HELP_SLONY); + return 0; +} + +bugReportFactory::bugReportFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Bug Report"), _("How to send a bugreport to the pgAdmin Development Team.")); +} + + +wxWindow *bugReportFactory::StartDialog(frmMain *form, pgObject *obj) +{ + DisplayHelp(wxT("bugreport"), HELP_PGADMIN); + return 0; +} diff --git a/frm/frmMainConfig.cpp b/frm/frmMainConfig.cpp new file mode 100644 index 0000000..c5e4773 --- /dev/null +++ b/frm/frmMainConfig.cpp @@ -0,0 +1,717 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMainConfig.cpp - Backend configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmMainConfig.h" +#include "frm/frmMain.h" +#include "dlg/dlgMainConfig.h" +#include "utils/utffile.h" +#include "schema/pgServer.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#include +WX_DEFINE_OBJARRAY(pgConfigOrgLineArray); + +#define CTL_CFGVIEW 345 + + +BEGIN_EVENT_TABLE(frmMainConfig, frmConfig) + EVT_MENU(MNU_UNDO, frmMainConfig::OnUndo) + EVT_MENU(MNU_CONTENTS, frmMainConfig::OnContents) + EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmMainConfig::OnEditSetting) + EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmMainConfig::OnSelectSetting) +END_EVENT_TABLE() + + +#define BCE_TITLE _("Backend Configuration Editor") + + +frmMainConfig::frmMainConfig(frmMain *parent, pgServer *server) + : frmConfig(parent, BCE_TITLE, 0) +{ + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Configuration Editor"); + if (server) + { + conn = server->CreateConn(wxEmptyString, 0, applicationname); + serverVersionNumber = server->GetVersionNumber(); + } + else + serverVersionNumber = wxEmptyString; + + InitForm(); + Init(); + + if (conn) + { + if (serverFileName.IsEmpty()) + serverFileName = wxT("postgresql.conf"); + + + wxString txt; + txt.Printf(_(" - %s on %s (%s:%d)"), + serverFileName.c_str(), server->GetDescription().c_str(), + server->GetName().c_str(), server->GetPort()); + SetTitle(BCE_TITLE + txt); + + wxString str; + str = conn->ExecuteScalar(wxT("SELECT pg_file_read('") + serverFileName + wxT("', 0, ") + wxT("pg_file_length('") + serverFileName + wxT("'))")); + + DisplayFile(str); + + statusBar->SetStatusText(wxString::Format(_(" Configuration read from %s"), conn->GetHost().c_str())); + } +} + + +frmMainConfig::frmMainConfig(const wxString &title, const wxString &configFile) + : frmConfig(title + wxT(" - ") + _("Backend Configuration Editor"), configFile) +{ + InitForm(); + Init(); + OpenLastFile(); +} + + +frmMainConfig::~frmMainConfig() +{ + options.clear(); + categories.clear(); + lines.Clear(); +} + + +void frmMainConfig::Init(pgSettingReader *reader) +{ + pgSettingItem *item; + do + { + item = reader->GetNextItem(); + if (item) + { + if (item->context == pgSettingItem::PGC_INTERNAL) + delete item; + else + { + if (options[item->name]) + delete item; + else + { + options[item->name] = item; + + wxArrayString *category = categories[item->category]; + if (!category) + { + category = new wxArrayString; + categories[item->category] = category; + } + category->Add(item->name); + } + } + } + } + while (item); + + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); +} + + +void frmMainConfig::Init() +{ + // Cleanup first, in case we're re-initing + options.clear(); + categories.clear(); + lines.Clear(); + + pgSettingReader *reader; + if (conn) + { + // read settings from server + reader = new pgSettingDbReader(conn); + } + else + { + // read settings from file. First, use localized file... + reader = new pgSettingFileReader(true); + + if (reader->IsValid()) + Init(reader); + delete reader; + + // ... then add default file + reader = new pgSettingFileReader(false); + } + + if (reader->IsValid()) + Init(reader); + + delete reader; +} + +void frmMainConfig::InitForm() +{ + appearanceFactory->SetIcons(this); + + InitFrame(wxT("frmMainConfig")); + RestorePosition(50, 50, 600, 600, 300, 200); + + cfgList = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + + cfgList->SetImageList(configImageList, wxIMAGE_LIST_SMALL); + + cfgList->AddColumn(_("Setting name"), 120); + cfgList->AddColumn(_("Value"), 80); + if (conn) + cfgList->AddColumn(_("Current value"), 80); + cfgList->AddColumn(_("Comment"), 400); +} + +void frmMainConfig::OnSelectSetting(wxListEvent &event) +{ + + // Disable undo because we don't want to undo the wrong line. + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_UNDO, false); +} + +void frmMainConfig::OnEditSetting(wxListEvent &event) +{ + wxString name = cfgList->GetText(event.GetIndex()); + if (!name.IsEmpty()) + { + pgSettingItem *item = options[name]; + wxASSERT(item); + dlgMainConfig dlg(this, item); + dlg.Go(); + + if (item->orgLine && !item->newLine->Differs(item->orgLine)) + { + delete item->newLine; + item->newLine = 0; + } + else + { + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + + + } + UpdateLine(event.GetIndex()); + } +} + + +void frmMainConfig::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + + +wxString frmMainConfig::GetHelpPage() const +{ + wxString page; + if (page.IsEmpty()) + page = wxT("runtime-config"); + + return page; +} + + +void frmMainConfig::OnUndo(wxCommandEvent &ev) +{ + wxString name = cfgList->GetText(cfgList->GetSelection()); + if (!name.IsEmpty()) + { + pgSettingItem *item = options[name]; + if (item->newLine) + { + delete item->newLine; + item->newLine = 0; + UpdateLine(cfgList->GetSelection()); + } + } +} + + + +void frmMainConfig::UpdateLine(int pos) +{ + wxString name = cfgList->GetText(pos); + if (!name.IsEmpty()) + { + pgSettingItem *item = options[name]; + + pgConfigLine *line = item->newLine; + if (!line) + line = item->orgLine; + + wxString value, comment; + int imgIndex = 0; + if (line) + { + value = line->value; + comment = line->comment; + if (!line->isComment) + imgIndex = 1; + } + cfgList->SetItem(pos, 1, value); + + if (conn) + cfgList->SetItem(pos, 3, comment); + else + cfgList->SetItem(pos, 2, comment); + + cfgList->SetItemImage(pos, imgIndex, imgIndex); + } +} + + +void frmMainConfig::WriteFile(pgConn *conn) +{ + + size_t i; + + wxString str; + for (i = 0 ; i < lines.GetCount() ; i++) + str.Append(lines.Item(i).GetNewText() + wxT("\n")); + + for (i = 0 ; i < (size_t)cfgList->GetItemCount() ; i++) + { + pgSettingItem *item = options[cfgList->GetText(i)]; + + if (item && item->newLine && item->newLine->item && !item->orgLine) + str.Append(item->newLine->GetNewText() + wxT("\n")); + } + + + if (DoWriteFile(str, conn)) + { + changed = false; + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + size_t i; + for (i = 0 ; i < (size_t)cfgList->GetItemCount() ; i++) + { + pgSettingItem *item = options[cfgList->GetText(i)]; + + if (item && item->newLine) + { + if (!item->orgLine) + { + item->orgLine = new pgConfigOrgLine(item->newLine); + lines.Add(item->orgLine); + item->orgLine->item = item; + } + else + { + item->orgLine->comment = item->newLine->comment; + item->orgLine->isComment = item->newLine->isComment; + item->orgLine->value = item->newLine->value; + item->orgLine->text = item->orgLine->GetNewText(); + } + } + } + + + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgConfigOrgLine &line = lines.Item(i); + if (line.item && line.item->newLine) + { + line.text = line.GetNewText(); + delete line.item->newLine; + line.item->newLine = 0; + } + } + } +} + + + +void frmMainConfig::DisplayFile(const wxString &str) +{ + Init(); + + filetype = wxTextFileType_Unix; + wxStringTokenizer strtok; + wxArrayString *unknownCategory = 0; + + if (str.Find('\r') >= 0) + { + if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n"))) + filetype = wxTextFileType_Dos; + else + filetype = wxTextFileType_Mac; + + strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY); + } + else + strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY); + + while (strtok.HasMoreTokens()) + { + pgConfigOrgLine *line = new pgConfigOrgLine(strtok.GetNextToken()); + lines.Add(line); + + // identify option + bool isComment = false; + const wxChar *p = line->text.c_str(); + + // identify keywords + while (*p && wxStrchr(wxT("# \n"), *p)) + { + if (*p == '#') + isComment = true; + p++; + } + + if (!*p) + isComment = true; + + line->isComment = isComment; + + const wxChar *p2 = p; + while (*p2 && *p2 != '#' && *p2 != ' ' && *p2 != '\t' && *p2 != '=') + p2++; + + if (p2 != p) + { + wxString keyword = line->text.Mid(p - line->text.c_str(), p2 - p); + + pgSettingItemHashmap::iterator it = options.find(keyword); + + pgSettingItem *item; + if (it == options.end()) + { + if (isComment) + continue; + + item = new pgSettingItem; + item->name = keyword; + item->category = _("Unknown"); + item->short_desc = _("Unknown option"); + item->extra_desc = _("This option is present in the configuration file, but not known to the configuration tool."); + item->SetType(wxT("string")); + + options[item->name] = item; + + if (!unknownCategory) + { + unknownCategory = new wxArrayString; + categories[item->category] = unknownCategory; + } + unknownCategory->Add(item->name); + } + else + item = it->second; + + + if (!isComment || !item->orgLine || item->orgLine->isComment) + { + line->item = item; + if (item->orgLine) + item->orgLine->item = 0; + item->orgLine = line; + } + while (*p2 && *p2 != '=') + p2++; + + p2++; // skip = + while (*p2 && wxStrchr(wxT(" \t"), *p2)) + p2++; + + wxChar quoteChar = 0; + if (wxStrchr(wxT("'\""), *p2)) + quoteChar = *p2++; + + const wxChar *p3 = p2; + while (*p3) + { + if (*p3 == quoteChar || (!quoteChar && wxStrchr(wxT(" \t#"), *p3))) + break; + p3++; + } + if (p2 != p3) + { + line->value = line->text.Mid(p2 - line->text.c_str(), p3 - p2); + if (quoteChar) + p3++; + + const wxChar *p4 = p3; + while (*p4 && wxStrchr(wxT(" \t#"), *p4)) + p4++; + + line->commentIndent = line->text.Mid(p3 - line->text.c_str(), p4 - p3); + line->comment = p4; + } + } + } + + cfgList->DeleteAllItems(); + + double versionNum; + bool versionRetVal = serverVersionNumber.ToDouble(&versionNum); + + // we want to show options ordered by category/name + // category might be localized, and we want a distinct category ordering + + FillList(wxT("listen_addresses")); // Connections and Authentication / Connection Settings + FillList(wxT("authentication_timeout")); // Connections and Authentication / Security and Authentication + FillList(wxT("check_function_bodies")); // Client Connection Defaults / Statement Behaviour + FillList(wxT("lc_messages")); // Client Connection Defaults / Locale and Formatting + if (versionRetVal && versionNum < 8.4) + FillList(wxT("explain_pretty_print")); // Client Connection Defaults / Other Defaults + FillList(wxT("enable_hashjoin")); // Query Tuning / Planner Method Configuration + FillList(wxT("cpu_operator_cost")); // Query Tuning / Planner Cost Constants + if (!conn || !conn->GetIsGreenplum()) // Greenplum doesn't have the Genetic Query Optimizer + FillList(wxT("geqo")); // Query Tuning / Genetic Query Optimizer + FillList(wxT("default_statistics_target")); // Query Tuning / Other Planner Options + FillList(wxT("deadlock_timeout")); // Lock Management + FillList(wxT("shared_buffers")); // Resource Usage / Memory + if (versionRetVal && versionNum < 8.4) + FillList(wxT("max_fsm_pages")); // Resource Usage / Free Space Map + FillList(wxT("bgwriter_delay")); // Resource Usage + FillList(wxT("max_files_per_process")); // Resource Usage / Kernel Resources + FillList(wxT("log_connections")); // Reporting and Logging / What to Log + FillList(wxT("client_min_messages")); // Reporting and Logging / When to Log + FillList(wxT("log_destination")); // Reporting and Logging / Where to Log + FillList(wxT("stats_command_string"), wxT("track_activities")); // Statistics / Query and Index Statistics Collector + FillList(wxT("log_executor_stats")); // Statistics / Monitoring + FillList(wxT("fsync")); // Write-Ahead Log / Settings + FillList(wxT("checkpoint_segments")); // Write-Ahead Log / Checkpoints + if (versionRetVal && versionNum <= 8.4) + FillList(wxT("add_missing_from")); // Version and Platform Compatibility / Previous PostgreSQL Version + FillList(wxT("transform_null_equals")); // Version and Platform Compatibility / Other Platforms and Clients + if (!conn || !conn->GetIsGreenplum()) // Greenplum doesn't have trace_notify visible + FillList(wxT("trace_notify")); // Developer Options + FillList(wxT("hba_file")); // Ungrouped + + + // for all we didn't get + while (!categories.empty()) + { + pgCategoryHashmap::iterator it = categories.begin(); + wxString missed = it->first; + FillList(it->second); + categories.erase(it); + } +} + + +void frmMainConfig::FillList(const wxString &categoryMember, const wxString &altCategoryMember) +{ + pgSettingItem *categoryItem = options[categoryMember]; + + if (!categoryItem && !altCategoryMember.IsEmpty()) + categoryItem = options[altCategoryMember]; + + wxASSERT_MSG(categoryItem, wxString::Format(wxT("%s/%s"), categoryMember.c_str(), altCategoryMember.c_str())); + + if (categoryItem) + { + FillList(categories[categoryItem->category]); + categories.erase(categoryItem->category); + } +} + + +void frmMainConfig::FillList(wxArrayString *category) +{ + if (category) + { + size_t i; + for (i = 0 ; i < category->GetCount() ; i++) + { + pgSettingItem *item = options[category->Item(i)]; + wxASSERT(item); + + wxString value; + wxString comment; + int imgIndex = 0; + if (item->orgLine) + { + if (!item->orgLine->isComment) + imgIndex = 1; + value = item->orgLine->value; + comment = item->orgLine->comment; + comment.Replace(wxT("\t"), wxT(" ")); + } + long pos = cfgList->AppendItem(imgIndex, item->name, value); + if (conn) + { + cfgList->SetItem(pos, 2, item->value); + cfgList->SetItem(pos, 3, comment); + } + else + cfgList->SetItem(pos, 2, comment); + } + delete category; + } +} + + + +enum +{ + HINT_LISTEN_ADDRESSES, + HINT_AUTOVACUUM_CFG +}; + + +const wxChar *hintString[] = +{ + _("The PostgreSQL server engine is currently configured to listen for local connections only.\nYou might want to check \"listen_addresses\" to enable accessing the server over the network too."), + _("The autovacuum backend process is not running.\nIt is recommended to enable it by setting 'track_counts' and 'autovacuum' to 'on' in PostgreSQL 8.3 and above or 'stats_start_collector', 'stats_row_level' and 'autovacuum' to 'on' in earlier versions.") +}; + + +wxString frmMainConfig::GetHintString() +{ + wxArrayInt hints; + size_t i; + int autovacuum = 0; + bool autovacuumPresent = false; + + for (i = 0 ; i < (size_t)cfgList->GetItemCount() ; i++) + { + pgSettingItem *item = options[cfgList->GetText(i)]; + + if (item) + { + wxString name = item->name; + wxString value = item->GetActiveValue(); + if (name == wxT("listen_addresses")) + { + if (value.IsEmpty() || value == wxT("localhost")) + hints.Add(HINT_LISTEN_ADDRESSES); + } + else if (name == wxT("autovacuum")) + { + autovacuumPresent = true; + if (StrToBool(value)) + autovacuum++; + } + else if (name == wxT("stats_start_collector") || name == wxT("stats_row_level")) + { + if (StrToBool(value)) + autovacuum++; + } + else if (name == wxT("track_counts")) + { + // Double increment, because track_counts in 8.3 is worth both previous options. + if (StrToBool(value)) + autovacuum = autovacuum + 2; + } + } + } + + if (autovacuumPresent && autovacuum < 3) + hints.Add(HINT_AUTOVACUUM_CFG); + + wxString str; + for (i = 0 ; i < hints.GetCount() ; i++) + { + if (i) + str.Append(wxT("\n\n")); + str.Append(hintString[hints.Item(i)]); + } + + return str; +} + +void frmMainConfig::OnOpen(wxCommandEvent &event) +{ + if (CheckChanged(true)) + return; + +#ifdef __WXMSW__ + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog dlg(this, _("Open configuration file"), lastDir, wxT(""), + _("Configuration files (*.conf)|*.conf|All files (*)|*"), wxFD_OPEN); +#endif + if (dlg.ShowModal() == wxID_OK) + { + Init(); + + lastFilename = dlg.GetFilename(); + lastDir = dlg.GetDirectory(); + lastPath = dlg.GetPath(); + OpenLastFile(); + UpdateRecentFiles(); + } +} + +mainConfigFactory::mainConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, wxT("postgresql.conf"), _("Edit general server configuration file.")); +} + + +wxWindow *mainConfigFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = obj->GetServer(); + if (server) + { + frmConfig *frm = new frmMainConfig(form, server); + frm->Go(); + return frm; + } + return 0; +} + + +bool mainConfigFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgServer *server = obj->GetServer(); + if (server) + { + pgConn *conn = server->GetConnection(); + return conn && server->GetSuperUser() && conn->HasFeature(FEATURE_FILEREAD); + } + } + return false; +} + + +mainConfigFileFactory::mainConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("Open postgresql.conf..."), _("Open configuration editor with postgresql.conf.")); +} + + +wxWindow *mainConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmConfig *dlg = new frmMainConfig(form); + dlg->Go(); + dlg->DoOpen(); + return dlg; +} diff --git a/frm/frmMaintenance.cpp b/frm/frmMaintenance.cpp new file mode 100644 index 0000000..ca3df29 --- /dev/null +++ b/frm/frmMaintenance.cpp @@ -0,0 +1,254 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMaintenance.cpp - Maintenance options selection dialogue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmHint.h" +#include "frm/frmMaintenance.h" +#include "frm/frmMain.h" +#include "utils/sysLogger.h" +#include "schema/pgIndex.h" + +// Icons +#include "images/vacuum.pngc" + + +BEGIN_EVENT_TABLE(frmMaintenance, ExecutionDialog) + EVT_RADIOBOX(XRCID("rbxAction"), frmMaintenance::OnAction) +END_EVENT_TABLE() + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define rbxAction CTRL_RADIOBOX("rbxAction") +#define chkFull CTRL_CHECKBOX("chkFull") +#define chkFreeze CTRL_CHECKBOX("chkFreeze") +#define chkAnalyze CTRL_CHECKBOX("chkAnalyze") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define chkDISABLE_PAGE_SKIPPING CTRL_CHECKBOX("chkDISABLE_PAGE_SKIPPING") +#define chkCONCURRENTLY CTRL_CHECKBOX("chkCONCURRENTLY") + + +#define stBitmap CTRL("stBitmap", wxStaticBitmap) + + + +frmMaintenance::frmMaintenance(frmMain *form, pgObject *obj) : ExecutionDialog(form, obj) +{ + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmMaintenance")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(MAINTENANCEDIALOGTITLE)); + + txtMessages = CTRL_TEXT("txtMessages"); + + // Icon + SetIcon(*vacuum_png_ico); + + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + + if (object->GetMetaType() == PGM_INDEX || object->GetMetaType() == PGM_PRIMARYKEY || object->GetMetaType() == PGM_UNIQUE) + { + rbxAction->SetSelection(2); + rbxAction->Enable(0, false); + rbxAction->Enable(1, false); + } + wxCommandEvent ev; + OnAction(ev); +} + + +frmMaintenance::~frmMaintenance() +{ + SavePosition(); + Abort(); +} + + +wxString frmMaintenance::GetHelpPage() const +{ + wxString page; + switch ((XRCCTRL(*(frmMaintenance *)this, "rbxAction", wxRadioBox))->GetSelection()) + { + case 0: + page = wxT("pg/sql-vacuum"); + break; + case 1: + page = wxT("pg/sql-analyze"); + break; + case 2: + page = wxT("pg/sql-reindex"); + break; + case 3: + page = wxT("pg/sql-cluster"); + break; + } + return page; +} + + + +void frmMaintenance::OnAction(wxCommandEvent &ev) +{ + bool isVacuum = (rbxAction->GetSelection() == 0); + chkFull->Enable(isVacuum); + chkFreeze->Enable(isVacuum); + chkAnalyze->Enable(isVacuum); + chkDISABLE_PAGE_SKIPPING->Enable(isVacuum && conn->BackendMinimumVersion(10, 0)); + + bool isReindex = (rbxAction->GetSelection() == 2); + chkCONCURRENTLY->Enable(isReindex && conn->BackendMinimumVersion(12, 0)); + + bool isCluster = (rbxAction->GetSelection() == 3); + if ((isCluster && !conn->BackendMinimumVersion(8, 4))) + { + chkVerbose->SetValue(false); + chkVerbose->Enable(false); + } + else + { + chkVerbose->SetValue(true); + chkVerbose->Enable(true); + } +} + + + +wxString frmMaintenance::GetSql() +{ + wxString sql; + + switch (rbxAction->GetSelection()) + { + case 0: + { + /* Warn about VACUUM FULL on < 9.0 */ + if (chkFull->GetValue() && + !conn->BackendMinimumVersion(9, 0)) + { + if (frmHint::ShowHint(this, HINT_VACUUM_FULL) == wxID_CANCEL) + return wxEmptyString; + } + sql = wxT("VACUUM "); + wxString opt = ""; + if (chkFull->GetValue()) + AppendIfFilled(opt,",",wxT("FULL")); + if (chkFreeze->GetValue()) + AppendIfFilled(opt,",",wxT("FREEZE")); + if (chkVerbose->GetValue()) + AppendIfFilled(opt,",",wxT("VERBOSE")); + if (chkAnalyze->GetValue()) + AppendIfFilled(opt,",",wxT("ANALYZE")); + if (chkDISABLE_PAGE_SKIPPING->GetValue()) + AppendIfFilled(opt,",",wxT("DISABLE_PAGE_SKIPPING")); + sql += opt.IsNull() ? "" : "("+opt.Mid(1)+")"; + if (object->GetMetaType() != PGM_DATABASE) + sql += object->GetQuotedFullIdentifier(); + + break; + } + case 1: + { + sql = wxT("ANALYZE "); + if (chkVerbose->GetValue()) + sql += wxT("VERBOSE "); + + if (object->GetMetaType() != PGM_DATABASE) + sql += object->GetQuotedFullIdentifier(); + + break; + } + case 2: + { + sql = wxT("REINDEX "); + if (chkVerbose->GetValue()) + sql += wxT("(VERBOSE) "); + + if (object->GetMetaType() == PGM_UNIQUE || object->GetMetaType() == PGM_PRIMARYKEY) + { + sql += wxT("INDEX "); + sql += chkCONCURRENTLY->GetValue() ? "CONCURRENTLY ": ""; + sql += object->GetQuotedFullIdentifier(); + } + else // Database, Tables, and Index (but not Constraintes ones) + { + sql += object->GetTypeName().Upper(); + sql += chkCONCURRENTLY->GetValue() ? " CONCURRENTLY ": " "; + sql += object->GetQuotedFullIdentifier(); + } + break; + } + case 3: + { + sql = wxT("CLUSTER "); + + if (chkVerbose->GetValue()) + sql += wxT("VERBOSE "); + if (object->GetMetaType() == PGM_TABLE) + sql += object->GetQuotedFullIdentifier(); + if (object->GetMetaType() == PGM_INDEX || object->GetMetaType() == PGM_UNIQUE + || object->GetMetaType() == PGM_PRIMARYKEY) + { + sql += object->GetSchema()->GetQuotedFullIdentifier(); + if (conn->BackendMinimumVersion(8, 4)) + { + sql += wxT(" USING ") + object->GetQuotedIdentifier(); + } + else + { + sql += wxT(" ON ") + object->GetQuotedIdentifier(); + } + } + } + } + + return sql; +} + + + +void frmMaintenance::Go() +{ + chkFull->SetFocus(); + Show(true); +} + + + +maintenanceFactory::maintenanceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Maintenance..."), _("Maintain the current database or table.")); + toolbar->AddTool(id, wxEmptyString, *vacuum_png_bmp, _("Maintain the current database or table."), wxITEM_NORMAL); +} + + +wxWindow *maintenanceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmMaintenance *frm = new frmMaintenance(form, obj); + frm->Go(); + return 0; +} + + +bool maintenanceFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->CanMaintenance(); +} diff --git a/frm/frmOptions.cpp b/frm/frmOptions.cpp new file mode 100644 index 0000000..974304b --- /dev/null +++ b/frm/frmOptions.cpp @@ -0,0 +1,1065 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmOptions.cpp - The main options dialogue +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// App headers +#include "frm/frmOptions.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "utils/sysSettings.h" +#include "utils/sysLogger.h" +#include "utils/misc.h" +#include "frm/menu.h" +#include "ctl/ctlColourPicker.h" + +// Must be after pgAdmin3.h or MSVC++ complains +#include + +#include "images/properties.pngc" + +#define BROWSER_ITEM _("Browser") +#define BROWSER_DISPLAY_ITEM _("Display") +#define BROWSER_PROPERTIES_ITEM _("Properties") +#define BROWSER_BINPATH_ITEM _("Binary paths") +#define BROWSER_MISC_ITEM _("UI Miscellaneous") +#define QUERYTOOL_ITEM _("Query tool") +#define QUERYTOOL_EDITOR_ITEM _("Query editor") +#define QUERYTOOL_COLOURS_ITEM _("Colours") +#define QUERYTOOL_RESULTS_ITEM _("Results grid") +#define QUERYTOOL_FILES_ITEM _("Query file") +#define QUERYTOOL_FAVOURITES_ITEM _("Favourites") +#define QUERYTOOL_MACROS_ITEM _("Macros") +#define QUERYTOOL_HISTORYFILE_ITEM _("History file") +#define DATABASEDESIGNER_ITEM _("Database Designer") +#define SERVERSTATUS_ITEM _("Server status") +#define MISC_ITEM _("Miscellaneous") +#define MISC_UI_ITEM _("User Interface") +#define MISC_HELPPATH_ITEM _("Help paths") +#define MISC_GURUHINTS_ITEM _("Guru hints") +#define MISC_LOGGING_ITEM _("Logging") + +#define txtPgHelpPath CTRL_TEXT("txtPgHelpPath") +#define txtEdbHelpPath CTRL_TEXT("txtEdbHelpPath") +#define txtGpHelpPath CTRL_TEXT("txtGpHelpPath") +#define txtSlonyHelpPath CTRL_TEXT("txtSlonyHelpPath") +#define pickerSlonyPath CTRL_DIRPICKER("pickerSlonyPath") +#define pickerPostgresqlPath CTRL_DIRPICKER("pickerPostgresqlPath") +#define pickerEnterprisedbPath CTRL_DIRPICKER("pickerEnterprisedbPath") +#define pickerGPDBPath CTRL_DIRPICKER("pickerGPDBPath") +#define txtSystemSchemas CTRL_TEXT("txtSystemSchemas") +#define pickerLogfile CTRL_FILEPICKER("pickerLogfile") +#define radLoglevel CTRL_RADIOBOX("radLoglevel") +#define txtMaxRows CTRL_TEXT("txtMaxRows") +#define txtMaxColSize CTRL_TEXT("txtMaxColSize") +#define pickerFont CTRL_FONTPICKER("pickerFont") +#define chkUnicodeFile CTRL_CHECKBOX("chkUnicodeFile") +#define chkWriteBOM CTRL_CHECKBOX("chkWriteBOM") +#define chkAskSaveConfirm CTRL_CHECKBOX("chkAskSaveConfirm") +#define chkAskDelete CTRL_CHECKBOX("chkAskDelete") +#define chkShowUsersForPrivileges CTRL_CHECKBOX("chkShowUsersForPrivileges") +#define txtAutoRowCount CTRL_TEXT("txtAutoRowCount") +#define txtIndent CTRL_TEXT("txtIndent") +#define chkSpacesForTabs CTRL_CHECKBOX("chkSpacesForTabs") +#define cbCopyQuote CTRL_COMBOBOX("cbCopyQuote") +#define cbCopyQuoteChar CTRL_COMBOBOX("cbCopyQuoteChar") +#define cbCopySeparator CTRL_COMBOBOX("cbCopySeparator") +#define chkStickySql CTRL_CHECKBOX("chkStickySql") +#define chkIndicateNull CTRL_CHECKBOX("chkIndicateNull") +#define txtDecimalMark CTRL_TEXT("txtDecimalMark") +#define chkColumnNames CTRL_CHECKBOX("chkColumnNames") +#define txtThousandsSeparator CTRL_TEXT("txtThousandsSeparator") +#define chkAutoRollback CTRL_CHECKBOX("chkAutoRollback") +#define chkAutoCommit CTRL_CHECKBOX("chkAutoCommit") +#define chkDoubleClickProperties CTRL_CHECKBOX("chkDoubleClickProperties") +#define chkShowNotices CTRL_CHECKBOX("chkShowNotices") +#define cbLanguage CTRL_COMBOBOX("cbLanguage") +#define pickerSqlFont CTRL_FONTPICKER("pickerSqlFont") +#define chkSuppressHints CTRL_CHECKBOX("chkSuppressHints") +#define chkResetHints CTRL_CHECKBOX("chkResetHints") +#define lstDisplay CTRL_CHECKLISTBOX("lstDisplay") +#define chkSystemObjects CTRL_CHECKBOX("chkSystemObjects") +#define chkIgnoreVersion CTRL_CHECKBOX("chkIgnoreVersion") +#define pickerIdleProcessColour CTRL_COLOURPICKER("pickerIdleProcessColour") +#define pickerActiveProcessColour CTRL_COLOURPICKER("pickerActiveProcessColour") +#define pickerSlowProcessColour CTRL_COLOURPICKER("pickerSlowProcessColour") +#define pickerBlockedProcessColour CTRL_COLOURPICKER("pickerBlockedProcessColour") +#define pickerBlockedbyProcessColour CTRL_COLOURPICKER("pickerBlockedbyProcessColour") +#define pickerFavouritesFile CTRL_FILEPICKER("pickerFavouritesFile") +#define pickerMacrosFile CTRL_FILEPICKER("pickerMacrosFile") +#define pickerHistoryFile CTRL_FILEPICKER("pickerHistoryFile") +#define pickerExtFormatCmd CTRL_FILEPICKER("pickerExtFormatCmd") +#define txtHistoryMaxQueries CTRL_TEXT("txtHistoryMaxQueries") +#define txtHistoryMaxQuerySize CTRL_TEXT("txtHistoryMaxQuerySize") +#define chkSQLUseSystemBackgroundColour CTRL_CHECKBOX("chkSQLUseSystemBackgroundColour") +#define chkSQLUseSystemForegroundColour CTRL_CHECKBOX("chkSQLUseSystemForegroundColour") +#define pickerSQLBackgroundColour CTRL_COLOURPICKER("pickerSQLBackgroundColour") +#define pickerSQLForegroundColour CTRL_COLOURPICKER("pickerSQLForegroundColour") +#define stSQLCustomBackgroundColour CTRL_STATIC("stSQLCustomBackgroundColour") +#define stSQLCustomForegroundColour CTRL_STATIC("stSQLCustomForegroundColour") +#define pickerSQLMarginBackgroundColour CTRL_COLOURPICKER("pickerSQLMarginBackgroundColour") +#define pickerSQLColour1 CTRL_COLOURPICKER("pickerSQLColour1") +#define pickerSQLColour2 CTRL_COLOURPICKER("pickerSQLColour2") +#define pickerSQLColour3 CTRL_COLOURPICKER("pickerSQLColour3") +#define pickerSQLColour4 CTRL_COLOURPICKER("pickerSQLColour4") +#define pickerSQLColour5 CTRL_COLOURPICKER("pickerSQLColour5") +#define pickerSQLColour6 CTRL_COLOURPICKER("pickerSQLColour6") +#define pickerSQLColour7 CTRL_COLOURPICKER("pickerSQLColour7") +#define pickerSQLColour10 CTRL_COLOURPICKER("pickerSQLColour10") +#define pickerSQLColour11 CTRL_COLOURPICKER("pickerSQLColour11") +#define pickerSQLCaretColour CTRL_COLOURPICKER("pickerSQLCaretColour") +#define chkKeywordsInUppercase CTRL_CHECKBOX("chkKeywordsInUppercase") +#define chkASUTPstyle CTRL_CHECKBOX("chkASUTPstyle") +#define menus CTRL_TREE("menus") +#define pnlBrowserDisplay CTRL_PANEL("pnlBrowserDisplay") +#define pnlBrowserProperties CTRL_PANEL("pnlBrowserProperties") +#define pnlBrowserBinPath CTRL_PANEL("pnlBrowserBinPath") +#define pnlBrowserMisc CTRL_PANEL("pnlBrowserMisc") +#define pnlQueryToolEditor CTRL_PANEL("pnlQueryToolEditor") +#define pnlQueryToolColours CTRL_PANEL("pnlQueryToolColours") +#define pnlQueryToolResults CTRL_PANEL("pnlQueryToolResults") +#define pnlQueryToolFiles CTRL_PANEL("pnlQueryToolFiles") +#define pnlQueryToolFavourites CTRL_PANEL("pnlQueryToolFavourites") +#define pnlQueryToolMacros CTRL_PANEL("pnlQueryToolMacros") +#define pnlQueryToolHistoryFile CTRL_PANEL("pnlQueryToolHistoryFile") +#define pnlDatabaseDesigner CTRL_PANEL("pnlDatabaseDesigner") +#define pnlServerStatus CTRL_PANEL("pnlServerStatus") +#define pnlMiscUI CTRL_PANEL("pnlMiscUI") +#define pnlMiscHelpPath CTRL_PANEL("pnlMiscHelpPath") +#define pnlMiscGuruHints CTRL_PANEL("pnlMiscGuruHints") +#define pnlMiscLogging CTRL_PANEL("pnlMiscLogging") +#define cbRefreshOnClick CTRL_COMBOBOX("cbRefreshOnClick") +#define pickerFontDD CTRL_FONTPICKER("pickerFontDD") + + +BEGIN_EVENT_TABLE(frmOptions, pgDialog) + EVT_MENU(MNU_HELP, frmOptions::OnHelp) + EVT_BUTTON (XRCID("btnDefault"), frmOptions::OnDefault) + EVT_CHECKBOX(XRCID("chkSuppressHints"), frmOptions::OnSuppressHints) + EVT_CHECKBOX(XRCID("chkResetHints"), frmOptions::OnResetHints) + EVT_CHECKBOX(XRCID("chkSQLUseSystemBackgroundColour"), frmOptions::OnChangeSQLUseCustomColour) + EVT_CHECKBOX(XRCID("chkSQLUseSystemForegroundColour"), frmOptions::OnChangeSQLUseCustomColour) + EVT_BUTTON (wxID_OK, frmOptions::OnOK) + EVT_BUTTON (wxID_HELP, frmOptions::OnHelp) + EVT_BUTTON (wxID_CANCEL, frmOptions::OnCancel) + EVT_COMBOBOX(XRCID("cbCopyQuote"), frmOptions::OnChangeCopyQuote) + EVT_TREE_SEL_CHANGED(XRCID("menus"), frmOptions::OnTreeSelChanged) +END_EVENT_TABLE() + + +//---------------------------------------------------------------------------- +// wxRichTextFontDialog: a substitute for wxFontDialog, which is broken on +// Mac OS X Snow Leopard +//---------------------------------------------------------------------------- + +#ifdef __WXMAC__ +#if !wxCHECK_VERSION(2, 9, 0) + +#include +#include +#include + +class wxRichTextFontDialog: public wxFontDialogBase +{ +public: + wxRichTextFontDialog() : wxFontDialogBase() + { + Init(); /* must be + Create()d later */ + } + wxRichTextFontDialog(wxWindow *parent) + : wxFontDialogBase(parent) + { + Init(); + Create(parent); + } + wxRichTextFontDialog(wxWindow *parent, const wxFontData &data) + : wxFontDialogBase(parent, data) + { + Init(); + Create(parent, data); + } + + void Init() + { + m_title = _("Font"); + } + + virtual int ShowModal(); + + virtual void SetTitle( const wxString &title) + { + m_title = title; + } + virtual wxString GetTitle() const + { + return m_title; + } + +protected: + wxString m_title; + + DECLARE_DYNAMIC_CLASS_NO_COPY(wxRichTextFontDialog) + +}; + +IMPLEMENT_DYNAMIC_CLASS(wxRichTextFontDialog, wxDialog) + +int wxRichTextFontDialog::ShowModal() +{ + wxTextAttrEx attr; + if (m_fontData.GetInitialFont().Ok()) + attr.SetFont(m_fontData.GetInitialFont()); + + if (m_fontData.GetColour().Ok()) + attr.SetTextColour(m_fontData.GetColour()); + + wxRichTextFormattingDialog formatDlg(wxRICHTEXT_FORMAT_FONT, + GetParent(), GetTitle()); + formatDlg.SetAttributes(attr); + + if (formatDlg.ShowModal() == wxID_OK) + { + wxTextAttrEx attr(formatDlg.GetAttributes()); + + m_fontData.SetChosenFont(attr.GetFont()); + m_fontData.SetColour(attr.GetTextColour()); + + return wxID_OK; + } + else + return wxID_CANCEL; + +} + +#endif +#endif + +//---------------------------------------------------------------------------- + +frmOptions::frmOptions(frmMain *parent) +{ + wxTreeItemId root, node; + wxTreeItemIdValue cookie; + + mainForm = parent; + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("frmOptions")); + + // Icon + SetIcon(*properties_png_ico); + RestorePosition(); + + wxAcceleratorEntry entries[1]; + + entries[0].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + + wxAcceleratorTable accel(1, entries); + SetAcceleratorTable(accel); + + wxTextValidator numval(wxFILTER_NUMERIC); + txtMaxRows->SetValidator(numval); + txtMaxColSize->SetValidator(numval); + txtAutoRowCount->SetValidator(numval); + txtIndent->SetValidator(numval); + txtHistoryMaxQueries->SetValidator(numval); + txtHistoryMaxQuerySize->SetValidator(numval); + + pickerLogfile->SetPath(settings->GetLogFile()); + radLoglevel->SetSelection(settings->GetLogLevel()); + txtMaxRows->SetValue(NumToStr(settings->GetMaxRows())); + txtMaxColSize->SetValue(NumToStr(settings->GetMaxColSize())); + chkAskSaveConfirm->SetValue(!settings->GetAskSaveConfirmation()); + chkAskDelete->SetValue(settings->GetConfirmDelete()); + chkShowUsersForPrivileges->SetValue(settings->GetShowUsersForPrivileges()); + txtAutoRowCount->SetValue(NumToStr(settings->GetAutoRowCountThreshold())); + txtIndent->SetValue(NumToStr(settings->GetIndentSpaces())); + chkSpacesForTabs->SetValue(settings->GetSpacesForTabs()); + cbCopyQuote->SetSelection(settings->GetCopyQuoting()); + cbCopyQuoteChar->SetValue(settings->GetCopyQuoteChar()); + cbRefreshOnClick->SetSelection(settings->GetRefreshOnClick()); + + wxString copySeparator = settings->GetCopyColSeparator(); + if (copySeparator == wxT("\t")) + copySeparator = _("Tab"); + cbCopySeparator->SetValue(copySeparator); + + chkStickySql->SetValue(settings->GetStickySql()); + chkIndicateNull->SetValue(settings->GetIndicateNull()); + txtThousandsSeparator->SetValue(settings->GetThousandsSeparator()); + chkAutoRollback->SetValue(settings->GetAutoRollback()); + chkAutoCommit->SetValue(settings->GetAutoCommit()); + chkDoubleClickProperties->SetValue(settings->GetDoubleClickProperties()); + txtDecimalMark->SetValue(settings->GetDecimalMark()); + chkColumnNames->SetValue(settings->GetColumnNames()); + chkShowNotices->SetValue(settings->GetShowNotices()); + + txtPgHelpPath->SetValue(settings->GetPgHelpPath()); + txtEdbHelpPath->SetValue(settings->GetEdbHelpPath()); + txtGpHelpPath->SetValue(settings->GetGpHelpPath()); + txtSlonyHelpPath->SetValue(settings->GetSlonyHelpPath()); + + txtSystemSchemas->SetValue(settings->GetSystemSchemas()); + chkUnicodeFile->SetValue(settings->GetUnicodeFile()); + chkWriteBOM->SetValue(settings->GetWriteBOM()); + chkSuppressHints->SetValue(settings->GetSuppressGuruHints()); + pickerSlonyPath->SetPath(settings->GetSlonyPath()); + pickerPostgresqlPath->SetPath(settings->GetPostgresqlPath()); + pickerEnterprisedbPath->SetPath(settings->GetEnterprisedbPath()); + pickerGPDBPath->SetPath(settings->GetGPDBPath()); + chkIgnoreVersion->SetValue(settings->GetIgnoreVersion()); + + // Get back the colours + pickerIdleProcessColour->SetColour(settings->GetIdleProcessColour()); + pickerActiveProcessColour->SetColour(settings->GetActiveProcessColour()); + pickerSlowProcessColour->SetColour(settings->GetSlowProcessColour()); + pickerBlockedProcessColour->SetColour(settings->GetBlockedProcessColour()); + pickerBlockedbyProcessColour->SetColour(settings->GetBlockedbyProcessColour()); + + pickerFavouritesFile->SetPath(settings->GetFavouritesFile()); + pickerMacrosFile->SetPath(settings->GetMacrosFile()); + pickerHistoryFile->SetPath(settings->GetHistoryFile()); + pickerExtFormatCmd->SetPath(settings->GetExtFormatCmd()); + + txtHistoryMaxQueries->SetValue(NumToStr(settings->GetHistoryMaxQueries())); + txtHistoryMaxQuerySize->SetValue(NumToStr(settings->GetHistoryMaxQuerySize())); + + chkSQLUseSystemBackgroundColour->SetValue(settings->GetSQLBoxUseSystemBackground()); + chkSQLUseSystemForegroundColour->SetValue(settings->GetSQLBoxUseSystemForeground()); + UpdateColourControls(); + + pickerSQLColour1->SetColour(settings->GetSQLBoxColour(1)); + pickerSQLColour2->SetColour(settings->GetSQLBoxColour(2)); + pickerSQLColour3->SetColour(settings->GetSQLBoxColour(3)); + pickerSQLColour4->SetColour(settings->GetSQLBoxColour(4)); + pickerSQLColour5->SetColour(settings->GetSQLBoxColour(5)); + pickerSQLColour6->SetColour(settings->GetSQLBoxColour(6)); + pickerSQLColour7->SetColour(settings->GetSQLBoxColour(7)); + pickerSQLColour10->SetColour(settings->GetSQLBoxColour(10)); + pickerSQLColour11->SetColour(settings->GetSQLBoxColour(11)); + + chkKeywordsInUppercase->SetValue(settings->GetSQLKeywordsInUppercase()); + chkASUTPstyle->SetValue(settings->GetASUTPstyle()); + cbLanguage->Append(_("Default")); + int sel = 0; + wxLanguage langId = settings->GetCanonicalLanguage(); + + int langCount = existingLangs.GetCount(); + if (langCount) + { + int langNo; + const wxLanguageInfo *langInfo; + for (langNo = 0; langNo < langCount ; langNo++) + { + langInfo = wxLocale::GetLanguageInfo(existingLangs.Item(langNo)); + cbLanguage->Append(wxT("(") + langInfo->CanonicalName + wxT(") ") + + existingLangNames.Item(langNo)); + if (langId == langInfo->Language) + sel = langNo + 1; + } + } + cbLanguage->SetSelection(sel); + + pickerFont->SetSelectedFont(settings->GetSystemFont()); + pickerSqlFont->SetSelectedFont(settings->GetSQLFont()); + pickerFontDD->SetSelectedFont(settings->GetDDFont()); + + // Load the display options + lstDisplay->Append(_("Databases")); + lstDisplay->Append(_("Tablespaces")); + lstDisplay->Append(_("pgAgent Jobs")); + lstDisplay->Append(_("pgpro_scheduler")); + lstDisplay->Append(_("Groups/group Roles")); + lstDisplay->Append(_("Users/login Roles")); + lstDisplay->Append(_("Resource Queues")); + lstDisplay->Append(_("Resource Groups")); + lstDisplay->Append(_("Catalogs")); + lstDisplay->Append(_("Casts")); + lstDisplay->Append(_("Event Triggers")); + lstDisplay->Append(_("Extensions")); + lstDisplay->Append(_("Publications")); + lstDisplay->Append(_("Subscriptions")); + lstDisplay->Append(_("Foreign Data Wrappers")); + lstDisplay->Append(_("Foreign Servers")); + lstDisplay->Append(_("User Mappings")); + lstDisplay->Append(_("Languages")); + lstDisplay->Append(_("Schemas")); + lstDisplay->Append(_("Synonyms")); + lstDisplay->Append(_("Slony-I Clusters")); + lstDisplay->Append(_("Aggregates")); + lstDisplay->Append(_("Collations")); + lstDisplay->Append(_("Conversions")); + lstDisplay->Append(_("Domains")); + lstDisplay->Append(_("External Tables")); + lstDisplay->Append(_("Foreign Tables")); + lstDisplay->Append(_("FTS Configurations")); + lstDisplay->Append(_("FTS Dictionaries")); + lstDisplay->Append(_("FTS Parsers")); + lstDisplay->Append(_("FTS Templates")); + lstDisplay->Append(_("Functions")); + lstDisplay->Append(_("Operators")); + lstDisplay->Append(_("Operator Classes")); + lstDisplay->Append(_("Operator Families")); + lstDisplay->Append(_("Packages")); + lstDisplay->Append(_("Procedures")); + lstDisplay->Append(_("Sequences")); + lstDisplay->Append(_("Tables")); + lstDisplay->Append(_("Trigger Functions")); + lstDisplay->Append(_("Types")); + lstDisplay->Append(_("Views")); + + for (unsigned int x = 0; x < lstDisplay->GetCount(); x++) + lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x))); + + chkSystemObjects->SetValue(settings->GetShowSystemObjects()); + + wxCommandEvent e; + OnChangeCopyQuote(e); + + // Fill the treeview + root = menus->AddRoot(_("Options")); + + node = menus->AppendItem(root, BROWSER_ITEM); + menus->AppendItem(node, BROWSER_DISPLAY_ITEM); + menus->AppendItem(node, BROWSER_PROPERTIES_ITEM); + menus->AppendItem(node, BROWSER_BINPATH_ITEM); + menus->AppendItem(node, BROWSER_MISC_ITEM); + + node = menus->AppendItem(root, QUERYTOOL_ITEM); + menus->AppendItem(node, QUERYTOOL_EDITOR_ITEM); + menus->AppendItem(node, QUERYTOOL_COLOURS_ITEM); + menus->AppendItem(node, QUERYTOOL_RESULTS_ITEM); + menus->AppendItem(node, QUERYTOOL_FILES_ITEM); + menus->AppendItem(node, QUERYTOOL_FAVOURITES_ITEM); + menus->AppendItem(node, QUERYTOOL_MACROS_ITEM); + menus->AppendItem(node, QUERYTOOL_HISTORYFILE_ITEM); + + node = menus->AppendItem(root, DATABASEDESIGNER_ITEM); + + node = menus->AppendItem(root, SERVERSTATUS_ITEM); + + node = menus->AppendItem(root, MISC_ITEM); + menus->AppendItem(node, MISC_UI_ITEM); + menus->AppendItem(node, MISC_HELPPATH_ITEM); + menus->AppendItem(node, MISC_GURUHINTS_ITEM); + menus->AppendItem(node, MISC_LOGGING_ITEM); + + menus->ExpandAllChildren(root); + + menuSelection = settings->GetOptionsLastTreeItem(); + wxTreeItemId menuItem = GetTreeItemByLabel(root, menuSelection); + if (!menuItem.IsOk()) + menuItem = menus->GetFirstChild(root, cookie); + + menus->SelectItem(menuItem); + ShowPanel(menuItem); +} + + +frmOptions::~frmOptions() +{ + SavePosition(); +} + +void frmOptions::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("options"), HELP_PGADMIN); +} + +void frmOptions::OnDefault(wxCommandEvent &ev) +{ + // Reset the display options to the defaults. + // Clear them all first + for (unsigned int x = 0; x < lstDisplay->GetCount(); x++) + lstDisplay->Check(x, settings->GetDisplayOption(lstDisplay->GetString(x), true)); +} + +void frmOptions::OnSuppressHints(wxCommandEvent &ev) +{ + if (chkSuppressHints->GetValue()) + chkResetHints->SetValue(false); +} + + +void frmOptions::OnResetHints(wxCommandEvent &ev) +{ + if (chkResetHints->GetValue()) + chkSuppressHints->SetValue(false); +} + +void frmOptions::UpdateColourControls() +{ + if (chkSQLUseSystemBackgroundColour->GetValue()) + { + pickerSQLBackgroundColour->Enable(false); + pickerSQLBackgroundColour->SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + stSQLCustomBackgroundColour->Enable(false); + } + else + { + pickerSQLBackgroundColour->Enable(true); + pickerSQLBackgroundColour->SetColour(settings->GetSQLBoxColourBackground()); + stSQLCustomBackgroundColour->Enable(true); + } + + if (chkSQLUseSystemForegroundColour->GetValue()) + { + pickerSQLForegroundColour->Enable(false); + pickerSQLForegroundColour->SetColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT)); + stSQLCustomForegroundColour->Enable(false); + } + else + { + pickerSQLForegroundColour->Enable(true); + pickerSQLForegroundColour->SetColour(settings->GetSQLBoxColourForeground()); + stSQLCustomForegroundColour->Enable(true); + } + + pickerSQLCaretColour->SetColour(settings->GetSQLColourCaret()); + + pickerSQLMarginBackgroundColour->SetColour(settings->GetSQLMarginBackgroundColour()); +} + +void frmOptions::OnChangeSQLUseCustomColour(wxCommandEvent &ev) +{ + UpdateColourControls(); +} + +void frmOptions::OnOK(wxCommandEvent &ev) +{ + // Check the PostgreSQL and EnterpriseDB paths +#ifdef __WXMSW__ + if (!pickerPostgresqlPath->GetPath().IsEmpty() && !isPgApp(pickerPostgresqlPath->GetPath() + wxT("\\pg_dump.exe"))) +#else + if (!pickerPostgresqlPath->GetPath().IsEmpty() && !isPgApp(pickerPostgresqlPath->GetPath() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The PostgreSQL bin path specified is not valid or does not contain a PostgreSQL pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + return; + } + +#ifdef __WXMSW__ + if (!pickerEnterprisedbPath->GetPath().IsEmpty() && !isEdbApp(pickerEnterprisedbPath->GetPath() + wxT("\\pg_dump.exe"))) +#else + if (!pickerEnterprisedbPath->GetPath().IsEmpty() && !isEdbApp(pickerEnterprisedbPath->GetPath() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The EnterpriseDB bin path specified is not valid or does not contain an EnterpriseDB pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + return; + } + +#ifdef __WXMSW__ + if (!pickerGPDBPath->GetPath().IsEmpty() && !isGpApp(pickerGPDBPath->GetPath() + wxT("\\pg_dump.exe"))) +#else + if (!pickerGPDBPath->GetPath().IsEmpty() && !isGpApp(pickerGPDBPath->GetPath() + wxT("/pg_dump"))) +#endif + { + wxMessageBox(_("The Greenplum bin path specified is not valid or does not contain a Greenplum pg_dump executable.\n\nPlease select another directory, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + return; + } + + + if (txtDecimalMark->GetValue() != wxEmptyString) + { + // Check decimal mark <> thousands separator + if (txtDecimalMark->GetValue() == txtThousandsSeparator->GetValue()) + { + wxMessageBox(_("The decimal mark and thousands separator must not be equal."), _("Error"), wxICON_ERROR | wxOK); + return; + } + } + + // Clean and check the help paths + txtPgHelpPath->SetValue(CleanHelpPath(txtPgHelpPath->GetValue())); + if (!HelpPathValid(txtPgHelpPath->GetValue())) + { + wxMessageBox(_("An invalid PostgreSQL help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtPgHelpPath->SetFocus(); + return; + } + + txtEdbHelpPath->SetValue(CleanHelpPath(txtEdbHelpPath->GetValue())); + if (!HelpPathValid(txtEdbHelpPath->GetValue())) + { + wxMessageBox(_("An invalid EnterpriseDB help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtEdbHelpPath->SetFocus(); + return; + } + + txtGpHelpPath->SetValue(CleanHelpPath(txtGpHelpPath->GetValue())); + if (!HelpPathValid(txtGpHelpPath->GetValue())) + { + wxMessageBox(_("An invalid GreenplumDB help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtGpHelpPath->SetFocus(); + return; + } + + txtSlonyHelpPath->SetValue(CleanHelpPath(txtSlonyHelpPath->GetValue())); + if (!HelpPathValid(txtSlonyHelpPath->GetValue())) + { + wxMessageBox(_("An invalid Slony help path was specified.\n\nPlease enter another filename, directory or URL, or leave the path blank."), _("Error"), wxICON_ERROR | wxOK); + txtSlonyHelpPath->SetFocus(); + return; + } + + // Logfile + wxString logFile = pickerLogfile->GetPath(); + wxLogInfo(wxT("Setting logfile to: %s"), logFile.c_str()); + settings->SetLogFile(logFile); + + // Loglevel + wxString logInfo = radLoglevel->GetStringSelection(); + wxLogInfo(wxT("Setting loglevel to: %s"), logInfo.c_str()); + int sel = radLoglevel->GetSelection(); + + switch(sel) + { + case(0): + settings->SetLogLevel(LOG_NONE); + break; + case(1): + settings->SetLogLevel(LOG_ERRORS); + break; + case(2): + settings->SetLogLevel(LOG_NOTICE); + break; + case(3): + settings->SetLogLevel(LOG_SQL); + break; + case(4): + settings->SetLogLevel(LOG_DEBUG); + break; + default: + settings->SetLogLevel(LOG_ERRORS); + break; + } + + // Query parameter + settings->SetMaxRows(StrToLong(txtMaxRows->GetValue())); + settings->SetMaxColSize(StrToLong(txtMaxColSize->GetValue())); + + settings->SetAskSaveConfirmation(!chkAskSaveConfirm->GetValue()); + settings->SetConfirmDelete(chkAskDelete->GetValue()); + settings->SetShowUsersForPrivileges(chkShowUsersForPrivileges->GetValue()); + settings->SetAutoRowCountThreshold(StrToLong(txtAutoRowCount->GetValue())); + settings->SetIndentSpaces(StrToLong(txtIndent->GetValue())); + settings->SetSpacesForTabs(chkSpacesForTabs->GetValue()); + settings->SetCopyQuoting(cbCopyQuote->GetCurrentSelection()); + settings->SetCopyQuoteChar(cbCopyQuoteChar->GetValue()); + settings->SetHistoryMaxQueries(StrToLong(txtHistoryMaxQueries->GetValue())); + settings->SetHistoryMaxQuerySize(StrToLong(txtHistoryMaxQuerySize->GetValue())); + settings->SetRefreshOnClick(cbRefreshOnClick->GetSelection()); + + wxString copySeparator = cbCopySeparator->GetValue(); + if (copySeparator == _("Tab")) + copySeparator = wxT("\t"); + settings->SetCopyColSeparator(copySeparator); + + settings->SetStickySql(chkStickySql->GetValue()); + settings->SetIndicateNull(chkIndicateNull->GetValue()); + settings->SetDecimalMark(txtDecimalMark->GetValue()); + settings->SetColumnNames(chkColumnNames->GetValue()); + settings->SetThousandsSeparator(txtThousandsSeparator->GetValue()); + settings->SetAutoRollback(chkAutoRollback->GetValue()); + settings->SetAutoCommit(chkAutoCommit->GetValue()); + settings->SetDoubleClickProperties(chkDoubleClickProperties->GetValue()); + settings->SetShowNotices(chkShowNotices->GetValue()); + + settings->SetUnicodeFile(chkUnicodeFile->GetValue()); + settings->SetWriteBOM(chkWriteBOM->GetValue()); + settings->SetSystemFont(pickerFont->GetSelectedFont()); + settings->SetSQLFont(pickerSqlFont->GetSelectedFont()); + settings->SetDDFont(pickerFontDD->GetSelectedFont()); + settings->SetSuppressGuruHints(chkSuppressHints->GetValue()); + settings->SetSlonyPath(pickerSlonyPath->GetPath()); + settings->SetPostgresqlPath(pickerPostgresqlPath->GetPath()); + settings->SetEnterprisedbPath(pickerEnterprisedbPath->GetPath()); + settings->SetGPDBPath(pickerGPDBPath->GetPath()); + + // Setup PostgreSQL/EnterpriseDB working paths +#if defined(__WXMSW__) + pgBackupExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dump.exe"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dumpall.exe"); + pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("\\pg_restore.exe"); + + edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dumpall.exe"); + edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_restore.exe"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("\\pg_dump.exe"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("\\pg_dumpall.exe"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("\\pg_restore.exe"); +#else + pgBackupExecutable = settings->GetPostgresqlPath() + wxT("/pg_dump"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall"); + pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("/pg_restore"); + + edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dump"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall"); + edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("/pg_restore"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("/pg_dump"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("/pg_dumpall"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("/pg_restore"); +#endif + + if (!wxFile::Exists(pgBackupExecutable)) + pgBackupExecutable = wxEmptyString; + if (!wxFile::Exists(pgBackupAllExecutable)) + pgBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(pgRestoreExecutable)) + pgRestoreExecutable = wxEmptyString; + + if (!wxFile::Exists(edbBackupExecutable)) + edbBackupExecutable = wxEmptyString; + if (!wxFile::Exists(edbBackupAllExecutable)) + edbBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(edbRestoreExecutable)) + edbRestoreExecutable = wxEmptyString; + + if (!wxFile::Exists(gpBackupExecutable)) + gpBackupExecutable = wxEmptyString; + if (!wxFile::Exists(gpBackupAllExecutable)) + gpBackupAllExecutable = wxEmptyString; + if (!wxFile::Exists(gpRestoreExecutable)) + gpRestoreExecutable = wxEmptyString; + + + settings->SetIgnoreVersion(chkIgnoreVersion->GetValue()); + + if (chkResetHints->GetValue()) + frmHint::ResetHints(); + + // Set the help paths + settings->SetPgHelpPath(txtPgHelpPath->GetValue()); + settings->SetEdbHelpPath(txtEdbHelpPath->GetValue()); + settings->SetGpHelpPath(txtGpHelpPath->GetValue()); + settings->SetSlonyHelpPath(txtSlonyHelpPath->GetValue()); + + settings->SetSystemSchemas(txtSystemSchemas->GetValue()); + + // Save the display options + bool changed = false; + for (unsigned int x = 0; x < lstDisplay->GetCount(); x++) + { + if (lstDisplay->IsChecked(x) != settings->GetDisplayOption(lstDisplay->GetString(x))) + { + changed = true; + settings->SetDisplayOption(lstDisplay->GetString(x), lstDisplay->IsChecked(x)); + } + } + + if (chkSystemObjects->GetValue() != settings->GetShowSystemObjects()) + { + changed = true; + settings->SetShowSystemObjects(chkSystemObjects->GetValue()); + } + + // Change the status colours + if (pickerIdleProcessColour->GetColourString() != settings->GetIdleProcessColour()) + changed = true; + settings->SetIdleProcessColour(pickerIdleProcessColour->GetColourString()); + + if (pickerActiveProcessColour->GetColourString() != settings->GetActiveProcessColour()) + changed = true; + settings->SetActiveProcessColour(pickerActiveProcessColour->GetColourString()); + + if (pickerSlowProcessColour->GetColourString() != settings->GetSlowProcessColour()) + changed = true; + settings->SetSlowProcessColour(pickerSlowProcessColour->GetColourString()); + + if (pickerBlockedProcessColour->GetColourString() != settings->GetBlockedProcessColour()) + changed = true; + settings->SetBlockedbyProcessColour(pickerBlockedProcessColour->GetColourString()); + if (pickerBlockedbyProcessColour->GetColourString() != settings->GetBlockedbyProcessColour()) + changed = true; + settings->SetBlockedbyProcessColour(pickerBlockedbyProcessColour->GetColourString()); + + // Change files' location + settings->SetFavouritesFile(pickerFavouritesFile->GetPath()); + settings->SetMacrosFile(pickerMacrosFile->GetPath()); + settings->SetHistoryFile(pickerHistoryFile->GetPath()); + settings->SetExtFormatCmd(pickerExtFormatCmd->GetPath()); + + // Change SQL Syntax colours + if (settings->GetSQLBoxUseSystemBackground() != chkSQLUseSystemBackgroundColour->GetValue()) + { + changed = true; + settings->SetSQLBoxUseSystemBackground(chkSQLUseSystemBackgroundColour->GetValue()); + } + + if (settings->GetSQLBoxUseSystemForeground() != chkSQLUseSystemForegroundColour->GetValue()) + { + changed = true; + settings->SetSQLBoxUseSystemForeground(chkSQLUseSystemForegroundColour->GetValue()); + } + + if (!settings->GetSQLBoxUseSystemBackground()) + { + if (pickerSQLBackgroundColour->GetColourString() != settings->GetSQLBoxColourBackground()) + changed = true; + settings->SetSQLBoxColourBackground(pickerSQLBackgroundColour->GetColourString()); + } + + if (!settings->GetSQLBoxUseSystemForeground()) + { + if (pickerSQLForegroundColour->GetColourString() != settings->GetSQLBoxColourForeground()) + changed = true; + settings->SetSQLBoxColourForeground(pickerSQLForegroundColour->GetColourString()); + } + + if (pickerSQLMarginBackgroundColour->GetColourString() != settings->GetSQLMarginBackgroundColour()) + changed = true; + settings->SetSQLMarginBackgroundColour(pickerSQLMarginBackgroundColour->GetColourString()); + + if (pickerSQLCaretColour->GetColourString() != settings->GetSQLColourCaret()) + changed = true; + settings->SetSQLColourCaret(pickerSQLCaretColour->GetColourString()); + + if (pickerSQLColour1->GetColourString() != settings->GetSQLBoxColour(1)) + changed = true; + settings->SetSQLBoxColour(1, pickerSQLColour1->GetColourString()); + if (pickerSQLColour2->GetColourString() != settings->GetSQLBoxColour(2)) + changed = true; + settings->SetSQLBoxColour(2, pickerSQLColour2->GetColourString()); + if (pickerSQLColour3->GetColourString() != settings->GetSQLBoxColour(3)) + changed = true; + settings->SetSQLBoxColour(3, pickerSQLColour3->GetColourString()); + if (pickerSQLColour4->GetColourString() != settings->GetSQLBoxColour(4)) + changed = true; + settings->SetSQLBoxColour(4, pickerSQLColour4->GetColourString()); + if (pickerSQLColour5->GetColourString() != settings->GetSQLBoxColour(5)) + changed = true; + settings->SetSQLBoxColour(5, pickerSQLColour5->GetColourString()); + if (pickerSQLColour6->GetColourString() != settings->GetSQLBoxColour(6)) + changed = true; + settings->SetSQLBoxColour(6, pickerSQLColour6->GetColourString()); + if (pickerSQLColour7->GetColourString() != settings->GetSQLBoxColour(7)) + changed = true; + settings->SetSQLBoxColour(7, pickerSQLColour7->GetColourString()); + if (pickerSQLColour10->GetColourString() != settings->GetSQLBoxColour(10)) + changed = true; + settings->SetSQLBoxColour(10, pickerSQLColour10->GetColourString()); + if (pickerSQLColour11->GetColourString() != settings->GetSQLBoxColour(11)) + changed = true; + settings->SetSQLBoxColour(11, pickerSQLColour11->GetColourString()); + + if (settings->GetASUTPstyle() != chkASUTPstyle->GetValue()) + { + changed = true; + settings->SetASUTPstyle(chkASUTPstyle->GetValue()); + } + + // Change the language last, as it will affect our tests for changes + // in the display object types. + int langNo = cbLanguage->GetCurrentSelection(); + if (langNo >= 0) + { + wxLanguage langId; + if (langNo == 0) + langId = wxLANGUAGE_DEFAULT; + else + { + const wxLanguageInfo *langInfo = wxLocale::GetLanguageInfo(existingLangs.Item(langNo - 1)); + langId = (wxLanguage) langInfo->Language; + } + + settings->SetCanonicalLanguage(langId); + } + + settings->SetOptionsLastTreeItem(menuSelection); + + // Did any display options change? Display this message last, so it's + // in the selected language. + if (changed) + wxMessageBox(_("Changes to the display options may not be visible until the browser tree is refreshed."), _("Display options"), wxICON_INFORMATION | wxOK); + + Destroy(); +} + + +void frmOptions::OnCancel(wxCommandEvent &ev) +{ + Destroy(); +} + + +optionsFactory::optionsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Options..."), _("Show options dialog.")); +} + + +wxWindow *optionsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmOptions *frm = new frmOptions(form); + frm->Show(); + return 0; +} + +// Enable/disable the copy quote option as required. +void frmOptions::OnChangeCopyQuote(wxCommandEvent &WXUNUSED(ev)) +{ + if (cbCopyQuote->GetValue() == _("None")) + cbCopyQuoteChar->Disable(); + else + cbCopyQuoteChar->Enable(); +} + + +wxString frmOptions::CheckColour(wxString oldColour) +{ + wxString newColour = wxEmptyString; + + if (oldColour != wxEmptyString) + { + wxColour colour; + + if (colour.Set(oldColour)) + newColour = colour.GetAsString(wxC2S_HTML_SYNTAX); + else + wxLogError(_("The colour specified is not valid.")); + } + + return newColour; +} + +void frmOptions::OnTreeSelChanged(wxTreeEvent &event) +{ + wxTreeItemId sel = event.GetItem(); + + if (sel) + ShowPanel(sel); +} + +void frmOptions::ShowPanel(const wxTreeItemId &menuItem) +{ + // Hide everything + pnlBrowserDisplay->Show(false); + pnlBrowserProperties->Show(false); + pnlBrowserBinPath->Show(false); + pnlBrowserMisc->Show(false); + pnlQueryToolEditor->Show(false); + pnlQueryToolColours->Show(false); + pnlQueryToolResults->Show(false); + pnlQueryToolFiles->Show(false); + pnlQueryToolFavourites->Show(false); + pnlQueryToolMacros->Show(false); + pnlQueryToolHistoryFile->Show(false); + pnlDatabaseDesigner->Show(false); + pnlServerStatus->Show(false); + pnlMiscUI->Show(false); + pnlMiscHelpPath->Show(false); + pnlMiscGuruHints->Show(false); + pnlMiscLogging->Show(false); + + // Find the one to show + menuSelection = menus->GetItemText(menuItem); + if (menuSelection == BROWSER_ITEM || menuSelection == BROWSER_DISPLAY_ITEM) + pnlBrowserDisplay->Show(true); + else if (menuSelection == BROWSER_PROPERTIES_ITEM) + pnlBrowserProperties->Show(true); + else if (menuSelection == BROWSER_BINPATH_ITEM) + pnlBrowserBinPath->Show(true); + else if (menuSelection == BROWSER_MISC_ITEM) + pnlBrowserMisc->Show(true); + + else if (menuSelection == QUERYTOOL_ITEM || menuSelection == QUERYTOOL_EDITOR_ITEM) + pnlQueryToolEditor->Show(true); + else if (menuSelection == QUERYTOOL_COLOURS_ITEM) + { + pnlQueryToolColours->Show(true); + pickerSQLBackgroundColour->UpdateColour(); + pickerSQLForegroundColour->UpdateColour(); + pickerSQLMarginBackgroundColour->UpdateColour(); + pickerSQLColour1->UpdateColour(); + pickerSQLColour2->UpdateColour(); + pickerSQLColour3->UpdateColour(); + pickerSQLColour4->UpdateColour(); + pickerSQLColour5->UpdateColour(); + pickerSQLColour6->UpdateColour(); + pickerSQLColour7->UpdateColour(); + pickerSQLColour10->UpdateColour(); + pickerSQLColour11->UpdateColour(); + pickerSQLCaretColour->UpdateColour(); + } + else if (menuSelection == QUERYTOOL_RESULTS_ITEM) + pnlQueryToolResults->Show(true); + else if (menuSelection == QUERYTOOL_FILES_ITEM) + pnlQueryToolFiles->Show(true); + else if (menuSelection == QUERYTOOL_FAVOURITES_ITEM) + pnlQueryToolFavourites->Show(true); + else if (menuSelection == QUERYTOOL_MACROS_ITEM) + pnlQueryToolMacros->Show(true); + else if (menuSelection == QUERYTOOL_HISTORYFILE_ITEM) + pnlQueryToolHistoryFile->Show(true); + + else if (menuSelection == DATABASEDESIGNER_ITEM) + pnlDatabaseDesigner->Show(true); + + else if (menuSelection == SERVERSTATUS_ITEM) + { + pnlServerStatus->Show(true); + pickerIdleProcessColour->UpdateColour(); + pickerActiveProcessColour->UpdateColour(); + pickerSlowProcessColour->UpdateColour(); + pickerBlockedProcessColour->UpdateColour(); + } + + else if (menuSelection == MISC_ITEM || menuSelection == MISC_UI_ITEM) + pnlMiscUI->Show(true); + else if (menuSelection == MISC_HELPPATH_ITEM) + pnlMiscHelpPath->Show(true); + else if (menuSelection == MISC_GURUHINTS_ITEM) + pnlMiscGuruHints->Show(true); + else if (menuSelection == MISC_LOGGING_ITEM) + pnlMiscLogging->Show(true); + + pnlBrowserDisplay->GetParent()->Layout(); + // we don't need to call GetParent()->Layout() for all panels + // because they all share the same parent +} + +wxTreeItemId frmOptions::GetTreeItemByLabel(const wxTreeItemId &root, const wxString &label) +{ + wxTreeItemIdValue cookie; + wxTreeItemId child; + wxTreeItemId notfound; + + if (!root.IsOk()) + return notfound; + if (label.CompareTo(menus->GetItemText(root)) == 0) + return root; + if (!menus->ItemHasChildren(root)) + return notfound; + + child = menus->GetFirstChild(root, cookie); + while (child.IsOk()) + { + child = GetTreeItemByLabel(child, label); + if (child.IsOk()) + return child; + child = menus->GetNextChild(root, cookie); + } + return child; +} + diff --git a/frm/frmPassword.cpp b/frm/frmPassword.cpp new file mode 100644 index 0000000..6c7e561 --- /dev/null +++ b/frm/frmPassword.cpp @@ -0,0 +1,117 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPassword.cpp - Change password +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + + +// App headers +#include "pgAdmin3.h" +#include "frm/frmPassword.h" +#include "schema/pgServer.h" + +#include "images/connect.pngc" + +#define txtCurrent CTRL_TEXT("txtCurrent") +#define txtNew CTRL_TEXT("txtNew") +#define txtConfirm CTRL_TEXT("txtConfirm") + + +BEGIN_EVENT_TABLE(frmPassword, pgDialog) + EVT_BUTTON (wxID_HELP, frmPassword::OnHelp) + EVT_BUTTON (wxID_OK, frmPassword::OnOK) + EVT_BUTTON (wxID_CANCEL, frmPassword::OnCancel) +END_EVENT_TABLE() + + +frmPassword::frmPassword(wxFrame *parent, pgObject *obj) +{ + SetFont(settings->GetSystemFont()); + LoadResource(parent, wxT("frmPassword")); + RestorePosition(); + + server = obj->GetServer(); + // Icon + SetIcon(*connect_png_ico); +} + +frmPassword::~frmPassword() +{ + SavePosition(); +} + + +void frmPassword::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("password"), HELP_PGADMIN); +} + + +void frmPassword::OnOK(wxCommandEvent &event) +{ + + // Is the old password right? + if (txtCurrent->GetValue() != server->GetPassword()) + { + wxLogError(__("Incorrect password!")); + return; + } + + // Did we confirm the password OK? + if (txtNew->GetValue() != txtConfirm->GetValue()) + { + wxLogError(__("Passwords do not match!")); + return; + } + + // Set the new password + if (!server->SetPassword(txtNew->GetValue())) + { + wxLogError(__("The password could not be changed!")); + return; + } + + // All must have gone well! + wxLogMessage(__("Password successfully changed!")); + this->Destroy(); +} + + +void frmPassword::OnCancel(wxCommandEvent &event) +{ + Destroy(); +} + + +passwordFactory::passwordFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("C&hange Password..."), _("Change your password.")); +} + + +wxWindow *passwordFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmPassword *frm = new frmPassword((pgFrame *)form, obj); + frm->Show(); + return 0; +} + + +bool passwordFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + pgServer *server = obj->GetServer(); + return server && server->GetConnected(); + } + return false; +} diff --git a/frm/frmPgpassConfig.cpp b/frm/frmPgpassConfig.cpp new file mode 100644 index 0000000..b940bfd --- /dev/null +++ b/frm/frmPgpassConfig.cpp @@ -0,0 +1,353 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPgpassConfig.cpp - Client access configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#ifdef __WXMSW__ +#include +#include +#endif + +#include + +#include "ctl/ctlMenuToolbar.h" +#include "frm/frmPgpassConfig.h" +#include "dlg/dlgPgpassConfig.h" +#include "frm/frmMain.h" +#include "utils/utffile.h" +#include "schema/pgServer.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" + +#define CTL_CFGVIEW 345 + +#include +WX_DEFINE_OBJARRAY(pgPassConfigLineArray); + + +BEGIN_EVENT_TABLE(frmPgpassConfig, frmConfig) + EVT_MENU(MNU_UNDO, frmPgpassConfig::OnUndo) + EVT_MENU(MNU_DELETE, frmPgpassConfig::OnDelete) + EVT_MENU(MNU_CONTENTS, frmPgpassConfig::OnContents) + EVT_LIST_ITEM_ACTIVATED(CTL_CFGVIEW, frmPgpassConfig::OnEditSetting) + EVT_LIST_ITEM_SELECTED(CTL_CFGVIEW, frmPgpassConfig::OnSelectSetting) +END_EVENT_TABLE() + +#define CACE_TITLE _("Client Access Configuration Editor") + +frmPgpassConfig::frmPgpassConfig(const wxString &title, const wxString &configFile) + : frmConfig(title + wxT(" - ") + _("Client Access Configuration Editor"), configFile) +{ + Init(); + + OpenLastFile(); + + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); +} + +frmPgpassConfig::frmPgpassConfig(frmMain *parent) + : frmConfig(parent, CACE_TITLE, 0) +{ + Init(); + + lastPath = sysSettings::GetConfigFile(sysSettings::PGPASS); + wxFile f; + if (f.Exists(lastPath)) + { + OpenLastFile(); + } + + helpMenu->Enable(MNU_HINT, false); + toolBar->EnableTool(MNU_HINT, false); +} + +frmPgpassConfig::~frmPgpassConfig() +{ +} + + +void frmPgpassConfig::Init() +{ + appearanceFactory->SetIcons(this); + + InitFrame(wxT("frmPgpassConfig")); + RestorePosition(150, 150, 650, 300, 300, 200); + + + listEdit = new ctlListView(this, CTL_CFGVIEW, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER); + listEdit->SetImageList(configImageList, wxIMAGE_LIST_SMALL); + + listEdit->AddColumn(_("Host"), 50); + listEdit->AddColumn(_("Port"), 30); + listEdit->AddColumn(_("Database"), 80); + listEdit->AddColumn(_("Username"), 80); + listEdit->AddColumn(_("Password"), 80); + + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); +} + +void frmPgpassConfig::OnSelectSetting(wxListEvent &event) +{ + // Enable delete because an item has been selected + if (event.GetIndex() != listEdit->GetItemCount() - 1) + { + editMenu->Enable(MNU_DELETE, true); + toolBar->EnableTool(MNU_DELETE, true); + } + else + { + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_DELETE, false); + } + + // Disable undo because we don't want to undo the wrong line. + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_UNDO, false); +} + +void frmPgpassConfig::DisplayFile(const wxString &str) +{ + lines.Empty(); + + filetype = wxTextFileType_Unix; + wxStringTokenizer strtok; + + if (str.Find('\r') >= 0) + { + if (str.Find(wxT("\n\r")) >= 0 || str.Find(wxT("\r\n"))) + filetype = wxTextFileType_Dos; + else + filetype = wxTextFileType_Mac; + + strtok.SetString(wxTextBuffer::Translate(str, wxTextFileType_Unix), wxT("\n"), wxTOKEN_RET_EMPTY); + } + else + strtok.SetString(str, wxT("\n"), wxTOKEN_RET_EMPTY); + + while (strtok.HasMoreTokens()) + { + pgPassConfigLine *line = new pgPassConfigLine(strtok.GetNextToken()); + lines.Add(line); + } + + listEdit->DeleteAllItems(); + + size_t i; + + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgPassConfigLine &line = lines.Item(i); + int imgIndex = 0; + if (!line.isComment) + imgIndex = 1; + long pos = listEdit->AppendItem(imgIndex, line.hostname); + + listEdit->SetItem(pos, 1, line.port); + listEdit->SetItem(pos, 2, line.database); + listEdit->SetItem(pos, 3, line.username); + listEdit->SetItem(pos, 4, line.password.IsEmpty() ? wxT("") : wxT("*********")); + line.item = pos; + } + if (!i || !lines.Item(i - 1).text.IsEmpty()) + { + pgPassConfigLine *line = new pgPassConfigLine(); + lines.Add(line); + line->item = listEdit->AppendItem(0, wxString(wxEmptyString)); + } +} + + +void frmPgpassConfig::WriteFile(pgConn *conn) +{ + wxString str; + size_t i; + for (i = 0 ; i < lines.GetCount() - 1 ; i++) + { + // Before writing it into the file we need to escape "\" and ":" + pgPassConfigLine line = lines.Item(i); + line.hostname.Replace(wxT("\\"), wxT("\\\\")); + line.hostname.Replace(wxT(":") , wxT("\\:")); + line.port.Replace(wxT("\\"), wxT("\\\\")); + line.port.Replace(wxT(":") , wxT("\\:")); + line.database.Replace(wxT("\\"), wxT("\\\\")); + line.database.Replace(wxT(":") , wxT("\\:")); + line.username.Replace(wxT("\\"), wxT("\\\\")); + line.username.Replace(wxT(":") , wxT("\\:")); + line.password.Replace(wxT("\\"), wxT("\\\\")); + line.password.Replace(wxT(":") , wxT("\\:")); + + wxString strLine = line.hostname + wxT(":") + line.port + wxT(":") + + line.database + wxT(":") + line.username + wxT(":") + line.password + wxT("\n"); + + str.Append(strLine); + } + + if (DoWriteFile(str, NULL)) + { + changed = false; + fileMenu->Enable(MNU_SAVE, false); + editMenu->Enable(MNU_UNDO, false); + toolBar->EnableTool(MNU_SAVE, false); + toolBar->EnableTool(MNU_UNDO, false); + + // make intermediate change current + for (i = 0 ; i < lines.GetCount() ; i++) + lines.Item(i).Init(lines.Item(i).GetText()); + } +} + + +wxString frmPgpassConfig::GetHintString() +{ + wxString hint; + return hint; +} + + +wxString frmPgpassConfig::GetHelpPage() const +{ + wxString page = wxT("libpq-pgpass"); + ; + return page; +} + + +void frmPgpassConfig::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + + +void frmPgpassConfig::OnUndo(wxCommandEvent &ev) +{ + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + size_t i; + for (i = 0 ; i < lines.GetCount() ; i++) + { + pgPassConfigLine &line = lines.Item(i); + + if (line.item == pos) + { + line.Init(line.text); + UpdateDisplay(line); + break; + } + } + } +} + +void frmPgpassConfig::OnDelete(wxCommandEvent &event) +{ + bool found = false; + int pos = listEdit->GetSelection(); + if (pos >= 0) + { + listEdit->DeleteCurrentItem(); + size_t i; + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item == pos) + { + lines.RemoveAt(i); + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, false); + editMenu->Enable(MNU_DELETE, false); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, false); + toolBar->EnableTool(MNU_DELETE, false); + found = true; + break; + } + } + if (found) + { + /* Renumber all positions */ + for (i = 0; i < lines.GetCount(); i++) + { + if (lines.Item(i).item > pos) + lines.Item(i).item--; + } + } + } +} + +void frmPgpassConfig::UpdateDisplay(pgPassConfigLine &line) +{ + long pos = line.item; + listEdit->SetItemImage(pos, (line.isComment ? 0 : 1)); + listEdit->SetItem(pos, 0, line.hostname); + listEdit->SetItem(pos, 1, line.port); + listEdit->SetItem(pos, 2, line.database); + listEdit->SetItem(pos, 3, line.username); + listEdit->SetItem(pos, 4, line.password.IsEmpty() ? wxT("") : wxT("*********")); +} + + +void frmPgpassConfig::OnEditSetting(wxListEvent &event) +{ + long pos = event.GetIndex(); + if (pos < 0) + return; + + size_t i; + + for (i = 0 ; i < lines.GetCount() ; i++) + { + if (lines.Item(i).item == pos) + { + pgPassConfigLine &line = lines.Item(i); + bool isLastLine = (i == lines.GetCount() - 1 && line.isComment && line.text.IsEmpty()); + + dlgPgpassConfig dlg(this, &line); + if (dlg.Go() == wxID_OK) + { + UpdateDisplay(line); + + if (isLastLine) + { + long pos = listEdit->AppendItem(0, wxString(wxEmptyString)); + pgPassConfigLine *line = new pgPassConfigLine(); + line->item = pos; + lines.Add(line); + } + changed = true; + fileMenu->Enable(MNU_SAVE, true); + editMenu->Enable(MNU_UNDO, true); + toolBar->EnableTool(MNU_SAVE, true); + toolBar->EnableTool(MNU_UNDO, true); + } + break; + } + } +} + + +pgpassConfigFileFactory::pgpassConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ +#ifdef WIN32 + mnu->Append(id, _("Open pgpass.conf"), _("Open configuration editor with pgpass.conf.")); +#else + mnu->Append(id, _("Open .pgpass"), _("Open configuration editor with .pgpass")); +#endif +} + + +wxWindow *pgpassConfigFileFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmConfig *dlg = new frmPgpassConfig(form); + dlg->Go(); + return dlg; +} diff --git a/frm/frmQuery.cpp b/frm/frmQuery.cpp new file mode 100644 index 0000000..72aa405 --- /dev/null +++ b/frm/frmQuery.cpp @@ -0,0 +1,4782 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmQuery.cpp - SQL Query Box +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// App headers +#include "frm/frmAbout.h" +#include "frm/frmMain.h" +#include "frm/frmQuery.h" +#include "frm/menu.h" +#include "ctl/explainCanvas.h" +#include "db/pgConn.h" + +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlSQLResult.h" +#include "dlg/dlgSelectConnection.h" +#include "dlg/dlgAddFavourite.h" +#include "dlg/dlgManageFavourites.h" +#include "dlg/dlgManageMacros.h" +#include "dlg/dlgFunction.h" +#include "frm/frmReport.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbViewPanels.h" +#include "gqb/gqbEvents.h" +#include "schema/pgDatabase.h" +#include "schema/pgFunction.h" +#include "schema/pgTable.h" +#include "schema/pgForeignTable.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" +#include "schema/pgServer.h" +#include "utils/favourites.h" +#include "utils/sysLogger.h" +#include "utils/sysSettings.h" +#include "utils/utffile.h" +#include "utils/misc.h" +#include "pgscript/pgsApplication.h" +#include "schema/pgPartition.h" + +// Icons +#include "images/sql-32.pngc" + +// Bitmaps +#include "images/file_new.pngc" +#include "images/file_open.pngc" +#include "images/file_save.pngc" +#include "images/clip_cut.pngc" +#include "images/clip_copy.pngc" +#include "images/clip_paste.pngc" +#include "images/edit_clear.pngc" +#include "images/edit_find.pngc" +#include "images/edit_undo.pngc" +#include "images/edit_redo.pngc" +#include "images/query_execute.pngc" +#include "images/query_pgscript.pngc" +#include "images/query_execfile.pngc" +#include "images/query_explain.pngc" +#include "images/query_cancel.pngc" +#include "images/query_commit.pngc" +#include "images/query_rollback.pngc" +#include "images/help.pngc" +#include "images/gqbJoin.pngc" + +#define CTRLID_CONNECTION 4200 +#define CTRLID_DATABASELABEL 4201 +#define CTL_SQLQUERYBOOK 4202 +#define CTL_BUTTONTRANSACTION 4203 + +#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) +#define XML_STR(s) ((const xmlChar *)s) + +// Initialize execution 'mutex'. As this will always run in the +// main thread, there aren't any real concurrency issues, so +// a simple flag will suffice. +// Required because the pgScript parser isn't currently thread-safe :-( +bool frmQuery::ms_pgScriptRunning = false; + +BEGIN_EVENT_TABLE(frmQuery, pgFrame) + EVT_ERASE_BACKGROUND( frmQuery::OnEraseBackground) + EVT_SIZE( frmQuery::OnSize) + EVT_COMBOBOX(CTRLID_CONNECTION, frmQuery::OnChangeConnection) + EVT_COMBOBOX(CTL_SQLQUERYCBOX, frmQuery::OnChangeQuery) + EVT_CLOSE( frmQuery::OnClose) + EVT_SET_FOCUS( frmQuery::OnSetFocus) + EVT_MENU(MNU_NEW, frmQuery::OnNew) + EVT_MENU(MNU_OPEN, frmQuery::OnOpen) + EVT_MENU(MNU_SAVE, frmQuery::OnSave) + EVT_MENU(MNU_SAVEAS, frmQuery::OnSaveAs) + EVT_MENU(MNU_NEWSQLTAB, frmQuery::OnSqlBookAddPage) + EVT_MENU(MNU_EXPORT, frmQuery::OnExport) + EVT_MENU(MNU_SAVEAS_IMAGE_GQB, frmQuery::SaveExplainAsImage) + EVT_MENU(MNU_SAVEAS_IMAGE_EXPLAIN, frmQuery::SaveExplainAsImage) + EVT_MENU(MNU_EXIT, frmQuery::OnExit) + EVT_MENU(MNU_CUT, frmQuery::OnCut) + EVT_MENU(MNU_COPY, frmQuery::OnCopy) + EVT_MENU(MNU_PASTE, frmQuery::OnPaste) + EVT_MENU(MNU_CLEAR, frmQuery::OnClear) + EVT_MENU(MNU_SUMMARY_COL, frmQuery::OnSummary_Column) + EVT_MENU(MNU_COPY_INSERT, frmQuery::OnCopy_Insert) + EVT_MENU(MNU_CLEAR_FILTER, frmQuery::OnClear_Filter) + EVT_MENU(MNU_FIND, frmQuery::OnSearchReplace) + EVT_MENU(MNU_UNDO, frmQuery::OnUndo) + EVT_MENU(MNU_REDO, frmQuery::OnRedo) + EVT_MENU(MNU_EXECUTE, frmQuery::OnExecute) + EVT_MENU(MNU_EXECUTE_2, frmQuery::OnExecuteShift) + EVT_MENU(MNU_EXECPGS, frmQuery::OnExecScript) + EVT_MENU(MNU_EXECFILE, frmQuery::OnExecFile) + EVT_MENU(MNU_EXPLAIN, frmQuery::OnExplain) + EVT_MENU(MNU_EXPLAINANALYZE, frmQuery::OnExplain) + EVT_MENU(MNU_DOCOMMIT, frmQuery::OnCommit) + EVT_MENU(MNU_DOROLLBACK, frmQuery::OnRollback) + EVT_MENU(MNU_CANCEL, frmQuery::OnCancel) + EVT_MENU(MNU_AUTOSELECTQUERY, frmQuery::OnAutoSelectQuery) + EVT_MENU(MNU_AUTOROLLBACK, frmQuery::OnAutoRollback) + EVT_MENU(MNU_AUTOCOMMIT, frmQuery::OnAutoCommit) + EVT_MENU(MNU_CONTENTS, frmQuery::OnContents) + EVT_MENU(MNU_HELP, frmQuery::OnHelp) + EVT_MENU(MNU_CLEARHISTORY, frmQuery::OnClearHistory) + EVT_MENU(MNU_SAVEHISTORY, frmQuery::OnSaveHistory) + EVT_MENU(MNU_SELECTALL, frmQuery::OnSelectAll) + EVT_MENU(MNU_QUICKREPORT, frmQuery::OnQuickReport) + EVT_MENU(MNU_AUTOINDENT, frmQuery::OnAutoIndent) + EVT_MENU(MNU_WORDWRAP, frmQuery::OnWordWrap) + EVT_MENU(MNU_SHOWINDENTGUIDES, frmQuery::OnShowIndentGuides) + EVT_MENU(MNU_SHOWWHITESPACE, frmQuery::OnShowWhitespace) + EVT_MENU(MNU_SHOWLINEENDS, frmQuery::OnShowLineEnds) + EVT_MENU(MNU_SHOWLINENUMBER, frmQuery::OnShowLineNumber) + EVT_MENU(MNU_FAVOURITES_ADD, frmQuery::OnAddFavourite) + EVT_MENU(MNU_FAVOURITES_INJECT, frmQuery::OnInjectFavourite) + EVT_MENU(MNU_FAVOURITES_MANAGE, frmQuery::OnManageFavourites) + EVT_MENU(MNU_MACROS_MANAGE, frmQuery::OnMacroManage) + EVT_MENU(MNU_AUTOREPLACE_MANAGE,frmQuery::OnAutoReplaceManage) + EVT_MENU(MNU_DATABASEBAR, frmQuery::OnToggleDatabaseBar) + EVT_MENU(MNU_TOOLBAR, frmQuery::OnToggleToolBar) + EVT_MENU(MNU_SCRATCHPAD, frmQuery::OnToggleScratchPad) + EVT_MENU(MNU_OUTPUTPANE, frmQuery::OnToggleOutputPane) + EVT_MENU(MNU_DEFAULTVIEW, frmQuery::OnDefaultView) + EVT_MENU(MNU_BLOCK_INDENT, frmQuery::OnBlockIndent) + EVT_MENU(MNU_BLOCK_OUTDENT, frmQuery::OnBlockOutDent) + EVT_MENU(MNU_UPPER_CASE, frmQuery::OnChangeToUpperCase) + EVT_MENU(MNU_LOWER_CASE, frmQuery::OnChangeToLowerCase) + EVT_MENU(MNU_COMMENT_TEXT, frmQuery::OnCommentText) + EVT_MENU(MNU_UNCOMMENT_TEXT, frmQuery::OnUncommentText) + EVT_MENU(MNU_EXTERNALFORMAT, frmQuery::OnExternalFormat) + EVT_MENU(MNU_LF, frmQuery::OnSetEOLMode) + EVT_MENU(MNU_CRLF, frmQuery::OnSetEOLMode) + EVT_MENU(MNU_CR, frmQuery::OnSetEOLMode) + EVT_MENU(MNU_AUTOEDITOBJECT, frmQuery::OnAutoEditObject) + EVT_MENU_RANGE(MNU_FAVOURITES_MANAGE + 1, MNU_FAVOURITES_MANAGE + 999, frmQuery::OnSelectFavourite) + EVT_MENU_RANGE(MNU_MACROS_MANAGE + 1, MNU_MACROS_MANAGE + 99, frmQuery::OnMacroInvoke) + EVT_ACTIVATE( frmQuery::OnActivate) + EVT_STC_MODIFIED(CTL_SQLQUERY, frmQuery::OnChangeStc) + EVT_STC_UPDATEUI(CTL_SQLQUERY, frmQuery::OnPositionStc) + EVT_GRID_LABEL_RIGHT_CLICK( frmQuery::OnLabelRightClick) + EVT_GRID_CELL_LEFT_DCLICK( frmQuery::OnCellLeftDClick) + EVT_AUI_PANE_CLOSE( frmQuery::OnAuiUpdate) + EVT_TIMER(CTL_TIMERSIZES, frmQuery::OnAdjustSizesTimer) + EVT_TIMER(CTL_TIMERFRM, frmQuery::OnTimer) +// These fire when the queries complete + EVT_PGQUERYRESULT(QUERY_COMPLETE, frmQuery::OnQueryComplete) + EVT_MENU(PGSCRIPT_COMPLETE, frmQuery::OnScriptComplete) + EVT_AUINOTEBOOK_PAGE_CHANGED(CTL_NTBKCENTER, frmQuery::OnChangeNotebook) + EVT_AUINOTEBOOK_PAGE_CHANGED(CTL_NTBKGQB, frmQuery::OnChangeNotebookOutpane) + EVT_AUINOTEBOOK_TAB_RIGHT_DOWN(CTL_NTBKGQB, frmQuery::OnNotebookOutpaneTabRDown) + EVT_AUINOTEBOOK_PAGE_CHANGED(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageChanged) + EVT_AUINOTEBOOK_PAGE_CHANGING(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageChanging) + EVT_AUINOTEBOOK_PAGE_CLOSE(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageClose) + EVT_AUINOTEBOOK_TAB_RIGHT_DOWN(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookTabRDown) + EVT_AUINOTEBOOK_PAGE_CLOSED(CTL_SQLQUERYBOOK, frmQuery::OnSqlBookPageClosed) + EVT_SPLITTER_SASH_POS_CHANGED(GQB_HORZ_SASH, frmQuery::OnResizeHorizontally) + EVT_BUTTON(CTL_DELETECURRENTBTN, frmQuery::OnDeleteCurrent) + EVT_BUTTON(CTL_DELETEALLBTN, frmQuery::OnDeleteAll) + EVT_BUTTON(CTL_BUTTONTRANSACTION,frmQuery::OnModeTransaction) +END_EVENT_TABLE() + +class DnDFile : public wxFileDropTarget +{ +public: + DnDFile(frmQuery *fquery) + { + m_fquery = fquery; + } + + virtual bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) + { + size_t nFiles = filenames.GetCount(); + if ((int) nFiles > 1) + wxLogError(_("Drag one file at a time")); + else if ((int) nFiles == 1) + { + wxString str; + bool modeUnicode = settings->GetUnicodeFile(); + wxUtfFile file(filenames[0], wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + + if (file.IsOpened()) + file.Read(str); + + if (!str.IsEmpty() && !m_fquery->CheckChanged(true)) + { + m_fquery->SetLastPath(filenames[0]); + m_fquery->SetQueryText(str); + m_fquery->ColouriseQuery(0, str.Length()); + wxSafeYield(); // needed to process sqlQuery modify event + m_fquery->SetChanged(false); + m_fquery->SetOrigin(ORIGIN_FILE); + m_fquery->setExtendedTitle(); + m_fquery->SetLineEndingStyle(); + m_fquery->UpdateRecentFiles(true); + m_fquery->UpdateAllRecentFiles(); + } + } + return true; + } + +private: + frmQuery *m_fquery; +}; + + +frmQuery::frmQuery(frmMain *form, const wxString &_title, pgConn *_conn, const wxString &query, const wxString &file) + : pgFrame(NULL, _title), + timer(this, CTL_TIMERFRM), + pgScript(new pgsApplication(_conn)), + pgsStringOutput(&pgsOutputString), + pgsOutput(pgsStringOutput, wxEOL_UNIX), + pgsTimer(new pgScriptTimer(this)), + m_loadingfile(false) +{ + pgScript->SetCaller(this, PGSCRIPT_COMPLETE); + + mainForm = form; + conn = _conn; + + loading = true; + closing = false; + + dlgName = wxT("frmQuery"); + recentKey = wxT("RecentFiles"); + RestorePosition(100, 100, 600, 500, 450, 300); + + explainCanvas = NULL; + + // notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG); + + SetMinSize(wxSize(450, 300)); + + SetIcon(*sql_32_png_ico); + SetFont(settings->GetSystemFont()); + menuBar = new wxMenuBar(); + + fileMenu = new wxMenu(); + recentFileMenu = new wxMenu(); + fileMenu->Append(MNU_NEW, _("&New window\tCtrl-N"), _("Open a new query window")); + fileMenu->Append(MNU_OPEN, _("&Open...\tCtrl-O"), _("Open a query file")); + fileMenu->Append(MNU_SAVE, _("&Save\tCtrl-S"), _("Save current file")); + saveasImageMenu = new wxMenu(); + saveasImageMenu->Append(MNU_SAVEAS, _("Query (text)"), _("Save file under new name")); + saveasImageMenu->Append(MNU_SAVEAS_IMAGE_GQB, _("Graphical Query (image)"), _("Save Graphical Query as an image")); + saveasImageMenu->Append(MNU_SAVEAS_IMAGE_EXPLAIN, _("Explain (image)"), _("Save output of Explain as an image")); + fileMenu->Append(wxID_ANY, _("Save as"), saveasImageMenu); + + // SQL tabs related menu items + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_NEWSQLTAB, _("New SQL &tab\tCtrl-T"), _("Open a new query tab")); + + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_EXPORT, _("&Export..."), _("Export data to file")); + fileMenu->Append(MNU_QUICKREPORT, _("&Quick report..."), _("Run a quick report...")); + fileMenu->AppendSeparator(); + fileMenu->Append(MNU_RECENT, _("&Recent files"), recentFileMenu); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit query window")); + + menuBar->Append(fileMenu, _("&File")); + + lineEndMenu = new wxMenu(); + lineEndMenu->AppendRadioItem(MNU_LF, _("Unix (LF)"), _("Use Unix style line endings")); + lineEndMenu->AppendRadioItem(MNU_CRLF, _("DOS (CRLF)"), _("Use DOS style line endings")); + lineEndMenu->AppendRadioItem(MNU_CR, _("Mac (CR)"), _("Use Mac style line endings")); + + editMenu = new wxMenu(); + editMenu->Append(MNU_UNDO, _("&Undo\tCtrl-Z"), _("Undo last action"), wxITEM_NORMAL); + editMenu->Append(MNU_REDO, _("&Redo\tCtrl-Y"), _("Redo last action"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_CUT, _("Cu&t\tCtrl-X"), _("Cut selected text to clipboard"), wxITEM_NORMAL); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL); + editMenu->Append(MNU_PASTE, _("&Paste\tCtrl-V"), _("Paste selected text from clipboard"), wxITEM_NORMAL); + editMenu->Append(MNU_CLEAR, _("C&lear window"), _("Clear edit window"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_FIND, _("&Find and Replace\tCtrl-F"), _("Find and replace text"), wxITEM_NORMAL); + editMenu->AppendSeparator(); + editMenu->Append(MNU_AUTOINDENT, _("&Auto indent"), _("Automatically indent text to the same level as the preceding line"), wxITEM_CHECK); + + // editMenu->AppendSeparator(); + formatMenu = new wxMenu(); + formatMenu->Append(MNU_UPPER_CASE, _("&Upper case\tCtrl-U"), _("Change the selected text to upper case")); + formatMenu->Append(MNU_LOWER_CASE, _("&Lower case\tCtrl-Shift-U"), _("Change the selected text to lower case")); + formatMenu->AppendSeparator(); + formatMenu->Append(MNU_BLOCK_INDENT, _("Block &Indent\tTab"), _("Indent the selected block")); + formatMenu->Append(MNU_BLOCK_OUTDENT, _("Block &Outdent\tShift-Tab"), _("Outdent the selected block")); + formatMenu->Append(MNU_COMMENT_TEXT, _("Co&mment Text\tCtrl-K"), _("Comment out the selected text")); + formatMenu->Append(MNU_UNCOMMENT_TEXT, _("Uncomme&nt Text\tCtrl-Shift-K"), _("Uncomment the selected text")); + formatMenu->AppendSeparator(); + formatMenu->Append(MNU_EXTERNALFORMAT, _("External Format\tCtrl-Shift-F"), _("Call external formatting command")); + editMenu->AppendSubMenu(formatMenu, _("F&ormat")); + editMenu->Append(MNU_LINEENDS, _("&Line ends"), lineEndMenu); + editMenu->Append(MNU_AUTOREPLACE_MANAGE, _("Manage autoreplace..."), _("Edit and delete autoreplace strings")); + editMenu->Append(MNU_AUTOEDITOBJECT, _("Open object\tF4"), _("Open object in brouser tree")); + + autoreplace = queryMacroFileProvider::LoadAutoReplace(true); + + menuBar->Append(editMenu, _("&Edit")); + + queryMenu = new wxMenu(); + queryMenu->Append(MNU_EXECUTE, _("&Execute\tF8"), _("Execute query")); + queryMenu->Append(MNU_EXECUTE_2, _("&Execute new output\tShift-F8"), _("Execute query in new output")); + queryMenu->Append(MNU_EXECPGS, _("Execute &pgScript\tF6"), _("Execute pgScript")); + queryMenu->Append(MNU_EXECFILE, _("Execute to file\tF5"), _("Execute query, write result to file")); + queryMenu->Append(MNU_EXPLAIN, _("E&xplain\tF7"), _("Explain query")); + queryMenu->Append(MNU_EXPLAINANALYZE, _("Explain analyze\tShift-F7"), _("Explain and analyze query")); + + + wxMenu *eo = new wxMenu(); + eo->Append(MNU_VERBOSE, _("Verbose"), _("Explain verbose query"), wxITEM_CHECK); + eo->Append(MNU_COSTS, _("Costs"), _("Explain analyze query with (or without) costs"), wxITEM_CHECK); + eo->Append(MNU_BUFFERS, _("Buffers"), _("Explain analyze query with (or without) buffers"), wxITEM_CHECK); + eo->Append(MNU_TIMING, _("Timing"), _("Explain analyze query with (or without) timing"), wxITEM_CHECK); + queryMenu->Append(MNU_EXPLAINOPTIONS, _("Explain &options"), eo, _("Options modifying Explain output")); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_SAVEHISTORY, _("Save history"), _("Save history of executed commands.")); + queryMenu->Append(MNU_CLEARHISTORY, _("Clear history"), _("Clear history window.")); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_AUTOSELECTQUERY, _("&Auto-Select"), _("Auto select query"), wxITEM_CHECK); + queryMenu->Append(MNU_AUTOROLLBACK, _("&Auto-Rollback"), _("Rollback the current transaction if an error is detected"), wxITEM_CHECK); + queryMenu->Append(MNU_AUTOCOMMIT, _("&Auto-Commit"), _("Auto commit the cuurent transaction"), wxITEM_CHECK); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_CANCEL, _("&Cancel\tAlt-Break"), _("Cancel query")); + queryMenu->AppendSeparator(); + queryMenu->Append(MNU_DOCOMMIT, _("Commit\tF10"), _("Commit")); + queryMenu->Append(MNU_DOROLLBACK, _("Rollback\tShift-F10"), _("Rollback")); + menuBar->Append(queryMenu, _("&Query")); + + favouritesMenu = new wxMenu(); + favouritesMenu->Append(MNU_FAVOURITES_ADD, _("Add favourite..."), _("Add current query to favourites")); + favouritesMenu->Append(MNU_FAVOURITES_INJECT, _("Inject\tF2"), _("Replace a word under cursor with a favourite with same name")); + favouritesMenu->Append(MNU_FAVOURITES_MANAGE, _("Manage favourites..."), _("Edit and delete favourites")); + favouritesMenu->AppendSeparator(); + favourites = 0L; + UpdateFavouritesList(); + menuBar->Append(favouritesMenu, _("Fav&ourites")); + + macrosMenu = new wxMenu(); + macrosMenu->Append(MNU_MACROS_MANAGE, _("Manage macros..."), _("Edit and delete macros")); + macrosMenu->AppendSeparator(); + macros = 0L; + UpdateMacrosList(); + menuBar->Append(macrosMenu, _("&Macros")); + + // View menu + viewMenu = new wxMenu(); + viewMenu->Append(MNU_DATABASEBAR, _("&Connection bar\tCtrl-Alt-B"), _("Show or hide the database selection bar."), wxITEM_CHECK); + viewMenu->Append(MNU_OUTPUTPANE, _("&Output pane\tCtrl-Alt-O"), _("Show or hide the output pane."), wxITEM_CHECK); + viewMenu->Append(MNU_SCRATCHPAD, _("S&cratch pad\tCtrl-Alt-S"), _("Show or hide the scratch pad."), wxITEM_CHECK); + viewMenu->Append(MNU_TOOLBAR, _("&Tool bar\tCtrl-Alt-T"), _("Show or hide the tool bar."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_SHOWINDENTGUIDES, _("&Indent guides"), _("Enable or disable display of indent guides"), wxITEM_CHECK); + viewMenu->Append(MNU_SHOWLINEENDS, _("&Line ends"), _("Enable or disable display of line ends"), wxITEM_CHECK); + viewMenu->Append(MNU_SHOWWHITESPACE, _("&Whitespace"), _("Enable or disable display of whitespaces"), wxITEM_CHECK); + viewMenu->Append(MNU_WORDWRAP, _("&Word wrap"), _("Enable or disable word wrapping"), wxITEM_CHECK); + viewMenu->Append(MNU_SHOWLINENUMBER, _("&Line number"), _("Enable or disable display of line number"), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + menuBar->Append(viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&SQL Help\tF1"), _("Display help on SQL commands.")); + +#ifdef __WXMAC__ + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); +#endif + + menuBar->Append(helpMenu, _("&Help")); + + SetMenuBar(menuBar); + + queryMenu->Check(MNU_VERBOSE, settings->GetExplainVerbose()); + queryMenu->Check(MNU_COSTS, settings->GetExplainCosts()); + queryMenu->Check(MNU_BUFFERS, settings->GetExplainBuffers()); + queryMenu->Check(MNU_TIMING, settings->GetExplainTiming()); + + UpdateRecentFiles(); + + wxAcceleratorEntry entries[16]; + + entries[0].Set(wxACCEL_CTRL, (int)'E', MNU_EXECUTE); + entries[1].Set(wxACCEL_CTRL, (int)'O', MNU_OPEN); + entries[2].Set(wxACCEL_CTRL, (int)'S', MNU_SAVE); + entries[3].Set(wxACCEL_CMD, (int)'S', MNU_SAVE); + entries[4].Set(wxACCEL_CTRL, (int)'F', MNU_FIND); + entries[5].Set(wxACCEL_CTRL, (int)'R', MNU_REPLACE); + entries[6].Set(wxACCEL_NORMAL, WXK_F8, MNU_EXECUTE); + entries[7].Set(wxACCEL_NORMAL, WXK_F7, MNU_EXPLAIN); + entries[8].Set(wxACCEL_ALT, WXK_PAUSE, MNU_CANCEL); + entries[9].Set(wxACCEL_CTRL, (int)'A', MNU_SELECTALL); + entries[10].Set(wxACCEL_CMD, (int)'A', MNU_SELECTALL); + entries[11].Set(wxACCEL_NORMAL, WXK_F1, MNU_HELP); + entries[12].Set(wxACCEL_CTRL, (int)'N', MNU_NEW); + entries[13].Set(wxACCEL_NORMAL, WXK_F6, MNU_EXECPGS); + entries[14].Set(wxACCEL_NORMAL, WXK_F5, MNU_EXECFILE); + entries[15].Set(wxACCEL_CTRL, (int)'T', MNU_NEWSQLTAB); + + wxAcceleratorTable accel(16, entries); + SetAcceleratorTable(accel); + + queryMenu->Enable(MNU_CANCEL, false); + + int iWidths[7] = {0, -1, 40, 200, 80, 80, 80}; + statusBar = CreateStatusBar(7); + SetStatusBarPane(-1); + SetStatusWidths(7, iWidths); + SetStatusText(_("ready"), STATUSPOS_MSGS); + + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + + toolBar->SetToolBitmapSize(wxSize(16, 16)); + + toolBar->AddTool(MNU_NEWSQLTAB, wxEmptyString, *file_new_png_bmp, _("New SQL tab"), wxITEM_NORMAL); + toolBar->AddTool(MNU_OPEN, wxEmptyString, *file_open_png_bmp, _("Open file"), wxITEM_NORMAL); + toolBar->AddTool(MNU_SAVE, wxEmptyString, *file_save_png_bmp, _("Save file"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_CUT, wxEmptyString, *clip_cut_png_bmp, _("Cut selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COPY, wxEmptyString, *clip_copy_png_bmp, _("Copy selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_PASTE, wxEmptyString, *clip_paste_png_bmp, _("Paste selected text from clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_CLEAR, wxEmptyString, *edit_clear_png_bmp, _("Clear edit window"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_UNDO, wxEmptyString, *edit_undo_png_bmp, _("Undo last action"), wxITEM_NORMAL); + toolBar->AddTool(MNU_REDO, wxEmptyString, *edit_redo_png_bmp, _("Redo last action"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_FIND, wxEmptyString, *edit_find_png_bmp, _("Find and replace text"), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_EXECUTE, wxEmptyString, *query_execute_png_bmp, _("Execute query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_EXECPGS, wxEmptyString, *query_pgscript_png_bmp, _("Execute pgScript"), wxITEM_NORMAL); + toolBar->AddTool(MNU_EXECFILE, wxEmptyString, *query_execfile_png_bmp, _("Execute query, write result to file"), wxITEM_NORMAL); + toolBar->AddTool(MNU_EXPLAIN, wxEmptyString, *query_explain_png_bmp, _("Explain query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_CANCEL, wxEmptyString, *query_cancel_png_bmp, _("Cancel query"), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_DOCOMMIT, wxEmptyString, *query_commit_png_bmp, _("Commit"), wxITEM_NORMAL); + toolBar->AddTool(MNU_DOROLLBACK, wxEmptyString, *query_rollback_png_bmp, _("Rollback"), wxITEM_NORMAL); + toolBar->AddSeparator(); + + toolBar->AddTool(MNU_HELP, wxEmptyString, *help_png_bmp, _("Display help on SQL commands."), wxITEM_NORMAL); + toolBar->Realize(); + + // Add the database selection bar + cbConnection = new wxBitmapComboBox(this, CTRLID_CONNECTION, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + cbConnection->Append(conn->GetName(), CreateBitmap(GetServerColour(conn)), (void *)conn); + cbConnection->Append(_(""), wxNullBitmap, (void *) NULL); + //CTL_BUTTONTRANSACTION + btnModeTransaction = new wxButton(this, CTL_BUTTONTRANSACTION, "A",wxDefaultPosition,wxSize(-1, -1),wxMINIMIZE_BOX); + btnModeTransaction->SetMaxSize(wxSize(22,22)); +// btnModeTransaction->Enable(true); + wxFont stdFont = settings->GetSystemFont(); + wxFont boldFont = stdFont; + boldFont.SetWeight(wxBOLD); + btnModeTransaction->SetFont(boldFont); + if (settings->GetAutoCommit()) + btnModeTransaction->SetLabel("A"); + else + btnModeTransaction->SetLabel("T"); + + +// btnModeTransaction->Fit(); + + + + + //Create SQL editor notebook + sqlNotebook = new ctlAuiNotebook(this, CTL_NTBKCENTER, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + + // Create panel for query + wxPanel *pnlQuery = new wxPanel(sqlNotebook); + + // Create the outer box sizer + wxBoxSizer *boxQuery = new wxBoxSizer(wxVERTICAL); + + // Create the inner box sizer + // This one will contain the label, the combobox, and the two buttons + wxBoxSizer *boxHistory = new wxBoxSizer(wxHORIZONTAL); + + // Label + wxStaticText *label = new wxStaticText(pnlQuery, 0, _("Previous queries")); + boxHistory->Add(label, 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // Query combobox + sqlQueries = new wxComboBox(pnlQuery, CTL_SQLQUERYCBOX, wxT(""), wxDefaultPosition, wxDefaultSize, wxArrayString(), wxCB_DROPDOWN | wxCB_READONLY); + sqlQueries->SetToolTip(_("Previous queries")); + LoadQueries(); + boxHistory->Add(sqlQueries, 1, wxEXPAND | wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // Delete Current button + btnDeleteCurrent = new wxButton(pnlQuery, CTL_DELETECURRENTBTN, _("Delete")); + btnDeleteCurrent->Enable(false); + boxHistory->Add(btnDeleteCurrent, 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + // Delete All button + btnDeleteAll = new wxButton(pnlQuery, CTL_DELETEALLBTN, _("Delete All")); + btnDeleteAll->Enable(sqlQueries->GetCount() > 0); + boxHistory->Add(btnDeleteAll, 0, wxALL | wxALIGN_CENTER_VERTICAL, 1); + + boxQuery->Add(boxHistory, 0, wxEXPAND | wxALL, 1); + + // Create the other inner box sizer + // This one will contain the SQL box + wxBoxSizer *boxSQL = new wxBoxSizer(wxHORIZONTAL); + + // Use sqlQueryBook instead of sqlQuery and put the book inside boxSQL sizer. + // We don't add any SQL tabs until all menu items are initialized from settings. + sqlQueryBook = new ctlAuiNotebook(pnlQuery, CTL_SQLQUERYBOOK, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_WINDOWLIST_BUTTON); + sqlQueryCounter = 0; + sqlQueryExec = NULL; + sqlQueryExecLast = NULL; + + boxSQL->Add(sqlQueryBook, 1, wxEXPAND | wxRIGHT | wxLEFT | wxBOTTOM, 1); + + boxQuery->Add(boxSQL, 1, wxEXPAND | wxRIGHT | wxLEFT | wxBOTTOM, 1); + + // Auto-sizing + pnlQuery->SetSizer(boxQuery); + boxQuery->Fit(pnlQuery); + + // Results pane + outputPane = new ctlAuiNotebook(this, CTL_NTBKGQB, wxDefaultPosition, wxSize(500, 300), wxAUI_NB_TOP | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_WINDOWLIST_BUTTON); + sqlResult = new ctlSQLResult(outputPane, conn, CTL_SQLRESULT, wxDefaultPosition, wxDefaultSize); + + int len = sizeof(ctlSQL) / sizeof(ctlSQL[0]); + for (int i=0;iSetFont(settings->GetSQLFont()); + msgHistory = new wxTextCtrl(outputPane, CTL_MSGHISTORY, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_DONTWRAP); + msgHistory->SetFont(settings->GetSQLFont()); + // Graphical Canvas + // initialize values + model = new gqbModel(); + controller = new gqbController(model, sqlNotebook, outputPane, wxSize(GQB_MIN_WIDTH, GQB_MIN_HEIGHT)); + firstTime = true; // Inform to GQB that the tree of table haven't filled. + gqbUpdateRunning = false; // Are we already updating the SQL query - event recursion protection. + adjustSizesTimer = NULL; // Timer used to avoid a bug when close outputPane + + // Setup SQL editor notebook NBP_SQLEDTR + sqlNotebook->AddPage(pnlQuery, _("SQL Editor")); + sqlNotebook->AddPage(controller->getViewContainer(), _("Graphical Query Builder")); + sqlNotebook->SetSelection(0); + + outputPane->AddPage(sqlResult, _("Data Output")); + outputPane->AddPage(explainCanvas, _("Explain")); + outputPane->AddPage(msgResult, _("Messages")); + outputPane->AddPage(msgHistory, _("History")); + + sqlResult->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgResult->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgHistory->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + + // Now, the scratchpad + scratchPad = new wxTextCtrl(this, CTL_SCRATCHPAD, wxT(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxHSCROLL); + + // Kickstart wxAUI + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(cbConnection, wxAuiPaneInfo().Name(wxT("databaseBar")).Caption(_("Connection bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + manager.AddPane(btnModeTransaction, wxAuiPaneInfo().Name(wxT("ModeTransaction")).Caption(_("Mode transaction")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + + manager.AddPane(outputPane, wxAuiPaneInfo().Name(wxT("outputPane")).Caption(_("Output pane")).Bottom().MinSize(wxSize(200, 100)).BestSize(wxSize(550, 300))); + manager.AddPane(scratchPad, wxAuiPaneInfo().Name(wxT("scratchPad")).Caption(_("Scratch pad")).Right().MinSize(wxSize(100, 100)).BestSize(wxSize(250, 200))); + manager.AddPane(sqlNotebook, wxAuiPaneInfo().Name(wxT("sqlQuery")).Caption(_("SQL query")).Center().CaptionVisible(false).CloseButton(false).MinSize(wxSize(200, 100)).BestSize(wxSize(350, 200))); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmQuery/Perspective-") + wxString(FRMQUERY_PERSPECTIVE_VER), &perspective, FRMQUERY_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // and reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("databaseBar")).Caption(_("Connection bar")); + //manager.GetPane(wxT("ModeTransaction")).Caption(_("Mode transaction")); + if (!manager.GetPane(wxT("ModeTransaction")).IsShown()) { + manager.GetPane(wxT("ModeTransaction")).MaxSize(wxSize(22, 22)); + manager.GetPane(wxT("ModeTransaction")).BestSize(wxSize(22, 22)); + manager.GetPane(wxT("ModeTransaction")).Show(true); + + } + manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query")); + manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + + // Sync the View menu options + viewMenu->Check(MNU_DATABASEBAR, manager.GetPane(wxT("databaseBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + bool bVal; + + + // Auto-Select + bVal = settings->GetAutoSelectQuery(); + queryMenu->Check(MNU_AUTOSELECTQUERY, bVal); + + // Auto-rollback + bVal = settings->GetAutoRollback(); + queryMenu->Check(MNU_AUTOROLLBACK, bVal); + + // Auto-commit + bVal = settings->GetAutoCommit(); + queryMenu->Check(MNU_AUTOCOMMIT, bVal); + + // Auto indent + settings->Read(wxT("frmQuery/AutoIndent"), &bVal, true); + editMenu->Check(MNU_AUTOINDENT, bVal); + + // Word wrap + settings->Read(wxT("frmQuery/WordWrap"), &bVal, false); + viewMenu->Check(MNU_WORDWRAP, bVal); + + // Indent Guides + settings->Read(wxT("frmQuery/ShowIndentGuides"), &bVal, false); + viewMenu->Check(MNU_SHOWINDENTGUIDES, bVal); + + // Whitespace + settings->Read(wxT("frmQuery/ShowWhitespace"), &bVal, false); + viewMenu->Check(MNU_SHOWWHITESPACE, bVal); + + // Line ends + settings->Read(wxT("frmQuery/ShowLineEnds"), &bVal, false); + viewMenu->Check(MNU_SHOWLINEENDS, bVal); + + // Line number + settings->Read(wxT("frmQuery/ShowLineNumber"), &bVal, false); + viewMenu->Check(MNU_SHOWLINENUMBER, bVal); + + // Create the SQL box. After this, sqlQuery variable can be used. + SqlBookAddPage(); + + if (!file.IsEmpty() && wxFileName::FileExists(file)) + { + wxFileName fn = file; + lastFilename = fn.GetFullName(); + lastDir = fn.GetPath(); + lastPath = fn.GetFullPath(); + OpenLastFile(); + sqlQuery->Colourise(0, query.Length()); + } + else if (!query.IsNull()) + { + sqlQuery->SetText(query); + SetLineEndingStyle(); + sqlQuery->Colourise(0, query.Length()); + wxSafeYield(); // needed to process sqlQuery modify event + sqlQuery->SetChanged(false); + sqlQuery->SetOrigin(ORIGIN_INITIAL); + /* _title if not empty should contain displayName of base object for the query. + It's pretty good for a proposed filename if the user chooses to Save As. */ + lastFilename = _title; + setExtendedTitle(); + SqlBookUpdatePageTitle(); + } else + { + // load temp file + wxString str; + wxString filename; + + wxString tempDir=wxStandardPaths::Get().GetUserConfigDir()+wxT("\\postgresql\\recovery\\"); + + if (!wxDirExists(tempDir)) { + wxFileName dn = tempDir; + dn.Mkdir(); + } + wxString pref=_conn->GetDbname(); + + bool modeUnicode = settings->GetUnicodeFile(); + + wxString f = wxFindFirstFile(tempDir+wxT("*.a")); + while ( !f.empty() ) + { + filename=f.AfterLast('\\').BeforeLast('.'); + if ((f.AfterLast('\\').StartsWith(pref+wxT("."))||(filename.BeforeLast('.').IsEmpty()))) { + wxUtfFile file(f, wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { file.Read(str); file.Close(); } + if (!str.IsEmpty()) + { + wxString fline=str.BeforeFirst('@'); + int l=fline.Length(); + if (fline.Find('\n')>=0) l=0; + long nl=0; + if (l>0) fline.ToLong(&nl); + if (l>0) { + fline=str.Mid(l+1); + str=fline; + } + sqlQuery->SetText(str); + sqlQuery->Colourise(0, str.Length()); + sqlQuery->EmptyUndoBuffer(); + + sqlQuery->GotoPos(nl); + wxSafeYield(); // needed to process sqlQuery modify event + //sqlQuery->SetFilename(lastPath); + sqlQuery->SetChanged(true); + //sqlQuery->SetOrigin(ORIGIN_INITIAL); + //filename=f.AfterLast('\\').BeforeLast('.'); + sqlQuery->SetTitle(filename); + setExtendedTitle(); + SqlBookUpdatePageTitle(); + //SetLineEndingStyle(); + SaveTempFile(); + SqlBookAddPage(); + + } + + } + f = wxFindNextFile(); + } + //for (int i=1;i<15;i++) + //{ + //filename=wxString::Format(_("Query %i"), i); + + //if (!wxFileName::FileExists(tempDir+filename)) continue; + //wxUtfFile file(tempDir+filename, wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + + //if (file.IsOpened()) + //{ file.Read(str); file.Close(); } + ////QFile::remove(tempDir+wxT("\\")+filename); + //wxRemoveFile(tempDir+filename); + //if (!str.IsEmpty()) + //{ + // sqlQuery->SetText(str); + // sqlQuery->Colourise(0, str.Length()); + // sqlQuery->EmptyUndoBuffer(); + // wxSafeYield(); // needed to process sqlQuery modify event + // //sqlQuery->SetFilename(lastPath); + // sqlQuery->SetChanged(true); + // //sqlQuery->SetOrigin(ORIGIN_INITIAL); + // setExtendedTitle(); + // SqlBookUpdatePageTitle(); + // //SetLineEndingStyle(); + // SaveTempFile(); + // SqlBookAddPage(); + + //} + //// for end + //} + + } + //sqlQuery->SetAutoReplaceList(autoreplace); + updateMenu(); + queryMenu->Enable(MNU_SAVEHISTORY, false); + queryMenu->Enable(MNU_CLEARHISTORY, false); + setTools(false); + lastFileFormat = settings->GetUnicodeFile(); + // Load function name + pgSet *functions; + wxString def_f; + wxString def_name; + functions = conn->ExecuteSet(wxT("select pg_get_function_arguments(oid) def,proname,pronargs nargs from pg_proc where pronargs>=0 order by proname,pronargs")); + if (functions) + { + //name_func.Init(true); + while (!functions->Eof()) + { + def_f = functions->GetVal(wxT("def")); + def_name = functions->GetVal(wxT("proname")); + def_func.Add(def_f); + name_func.Add(def_name); + functions->MoveNext(); + } + name_func.Sort(); + delete functions; + } + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + msgResult->SetMaxLength(0L); + msgHistory->SetMaxLength(0L); +#endif +} + + +frmQuery::~frmQuery() +{ + closing = true; + if (!name_func.IsEmpty()) name_func.Clear(); + if (!def_func.IsEmpty()) def_func.Clear(); + // Save frmQuery Perspective + settings->Write(wxT("frmQuery/Perspective-") + wxString(FRMQUERY_PERSPECTIVE_VER), manager.SavePerspective()); + + // Uninitialize wxAUIManager + manager.UnInit(); + + if(sqlNotebook) + { + delete sqlNotebook; + sqlNotebook = NULL; + } + if(controller) + { + delete controller; + controller = NULL; + } + if(model) + { + delete model; + model = NULL; + } + if(adjustSizesTimer) + { + delete adjustSizesTimer; + adjustSizesTimer = NULL; + } + + while (cbConnection->GetCount() > 1) + { + delete (pgConn *)cbConnection->GetClientData(0); + cbConnection->Delete(0); + } + + if (favourites) + { + delete favourites; + favourites = NULL; + } + + if (pgsTimer) + { + delete pgsTimer; + pgsTimer = NULL; + } + + if (pgScript) + { + delete pgScript; + pgScript = NULL; + } + + if (mainForm) + mainForm->RemoveFrame(this); + + if (macros) + delete macros; + if (autoreplace) + delete autoreplace; +} + + +void frmQuery::OnExit(wxCommandEvent &event) +{ + closing = true; + Close(); +} + + +void frmQuery::OnEraseBackground(wxEraseEvent &event) +{ + event.Skip(); +} + + +void frmQuery::OnSize(wxSizeEvent &event) +{ + event.Skip(); +} + + +void frmQuery::OnToggleScratchPad(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + else + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); +} + + +void frmQuery::OnToggleDatabaseBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_DATABASEBAR)) + manager.GetPane(wxT("databaseBar")).Show(true); + else + manager.GetPane(wxT("databaseBar")).Show(false); + manager.Update(); +} + + +void frmQuery::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + manager.GetPane(wxT("toolBar")).Show(true); + else + manager.GetPane(wxT("toolBar")).Show(false); + manager.Update(); +} + + +void frmQuery::OnToggleOutputPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_OUTPUTPANE)) + { + manager.GetPane(wxT("outputPane")).Show(true); + } + else + { + manager.GetPane(wxT("outputPane")).Show(false); + } + manager.Update(); + adjustGQBSizes(); +} + + +void frmQuery::OnAuiUpdate(wxAuiManagerEvent &event) +{ + if(event.pane->name == wxT("databaseBar")) + { + viewMenu->Check(MNU_DATABASEBAR, false); + } + else if(event.pane->name == wxT("toolBar")) + { + viewMenu->Check(MNU_TOOLBAR, false); + } + else if(event.pane->name == wxT("outputPane")) + { + viewMenu->Check(MNU_OUTPUTPANE, false); + if(!adjustSizesTimer) + adjustSizesTimer = new wxTimer(this, CTL_TIMERSIZES); + adjustSizesTimer->Start(500); + } + else if(event.pane->name == wxT("scratchPad")) + { + viewMenu->Check(MNU_SCRATCHPAD, false); + } + event.Skip(); +} + + +void frmQuery::OnDefaultView(wxCommandEvent &event) +{ + // Reset captions to whatever AuiManager expects in perspective + BeginPerspectiveChange(); + + manager.LoadPerspective(FRMQUERY_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("databaseBar")).Caption(_("Connection bar")); + manager.GetPane(wxT("sqlQuery")).Caption(_("SQL query")); + manager.GetPane(wxT("outputPane")).Caption(_("Output pane")); + manager.GetPane(wxT("scratchPad")).Caption(_("Scratch pad")); + + EndPerspectiveChange(false); + + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_DATABASEBAR, manager.GetPane(wxT("databaseBar")).IsShown()); + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_OUTPUTPANE, manager.GetPane(wxT("outputPane")).IsShown()); + viewMenu->Check(MNU_SCRATCHPAD, manager.GetPane(wxT("scratchPad")).IsShown()); +} + +void frmQuery::OnAutoSelectQuery(wxCommandEvent &event) +{ + queryMenu->Check(MNU_AUTOSELECTQUERY, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/AutoSelectQuery"), queryMenu->IsChecked(MNU_AUTOSELECTQUERY)); +} + +void frmQuery::OnAutoRollback(wxCommandEvent &event) +{ + queryMenu->Check(MNU_AUTOROLLBACK, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/AutoRollback"), queryMenu->IsChecked(MNU_AUTOROLLBACK)); +} + +void frmQuery::OnAutoCommit(wxCommandEvent &event) +{ + bool chk=queryMenu->IsChecked(MNU_AUTOCOMMIT); + queryMenu->Check(MNU_AUTOCOMMIT, chk); + if (chk) + btnModeTransaction->SetLabel("A"); + else + btnModeTransaction->SetLabel("T"); + + if(chk && conn->GetTxStatus() != PQTRANS_IDLE) + wxMessageBox( + _("The current transaction is still in progess.\n\nIn order to take the effect of AUTOCOMMIT mode, please complete the transaction by executing COMMIT, or ROLLBACK statement."), + _("Warning - Transaction in progress"), wxICON_INFORMATION | wxOK, this); + settings->WriteBool(wxT("frmQuery/AutoCommit"), queryMenu->IsChecked(MNU_AUTOCOMMIT)); +} + +void frmQuery::OnAutoIndent(wxCommandEvent &event) +{ + editMenu->Check(MNU_AUTOINDENT, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/AutoIndent"), editMenu->IsChecked(MNU_AUTOINDENT)); + + SqlBookSetAutoIndent(event.IsChecked()); +} + + +void frmQuery::OnWordWrap(wxCommandEvent &event) +{ + viewMenu->Check(MNU_WORDWRAP, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/WordWrap"), viewMenu->IsChecked(MNU_WORDWRAP)); + + SqlBookSetWrapMode(event.IsChecked()); +} + + +void frmQuery::OnShowIndentGuides(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWINDENTGUIDES, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowIndentGuides"), viewMenu->IsChecked(MNU_SHOWINDENTGUIDES)); + + SqlBookSetIndentGuides(event.IsChecked()); +} + + +void frmQuery::OnShowWhitespace(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWWHITESPACE, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowWhitespace"), viewMenu->IsChecked(MNU_SHOWWHITESPACE)); + + SqlBookSetViewWhiteSpace(event.IsChecked()); +} + + +void frmQuery::OnShowLineEnds(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWLINEENDS, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowLineEnds"), viewMenu->IsChecked(MNU_SHOWLINEENDS)); + + SqlBookSetViewEOL(event.IsChecked()); +} + + +void frmQuery::OnShowLineNumber(wxCommandEvent &event) +{ + viewMenu->Check(MNU_SHOWLINENUMBER, event.IsChecked()); + + settings->WriteBool(wxT("frmQuery/ShowLineNumber"), viewMenu->IsChecked(MNU_SHOWLINENUMBER)); + + SqlBookSetViewLineNumbers(event.IsChecked()); +} + +void frmQuery::OnActivate(wxActivateEvent &event) +{ + if (event.GetActive()) + updateMenu(); + event.Skip(); +} + + +void frmQuery::OnExport(wxCommandEvent &ev) +{ + sqlResult->Export(); +} + + +void frmQuery::Go() +{ + cbConnection->SetSelection(0L); + wxCommandEvent ev; + OnChangeConnection(ev); + + Show(true); + sqlQuery->SetFocus(); + loading = false; +} + + +typedef struct __sqltokenhelp +{ + const wxChar *token; + const wxChar *page; + int type; +} SqlTokenHelp; + +SqlTokenHelp sqlTokenHelp[] = +{ + { wxT("ABORT"), 0, 0}, + { wxT("ALTER"), 0, 2}, + { wxT("ANALYZE"), 0, 0}, + { wxT("BEGIN"), 0, 0}, + { wxT("CHECKPOINT"), 0, 0}, + { wxT("CLOSE"), 0, 0}, + { wxT("CLUSTER"), 0, 0}, + { wxT("COMMENT"), 0, 0}, + { wxT("COMMIT"), 0, 0}, + { wxT("COPY"), 0, 0}, + { wxT("CREATE"), 0, 1}, + { wxT("DEALLOCATE"), 0, 0}, + { wxT("DECLARE"), 0, 0}, + { wxT("DELETE"), 0, 0}, + { wxT("DROP"), 0, 1}, + { wxT("END"), 0, 0}, + { wxT("EXECUTE"), 0, 0}, + { wxT("EXPLAIN"), 0, 0}, + { wxT("FETCH"), 0, 0}, + { wxT("GRANT"), 0, 0}, + { wxT("INSERT"), 0, 0}, + { wxT("LISTEN"), 0, 0}, + { wxT("LOAD"), 0, 0}, + { wxT("LOCK"), 0, 0}, + { wxT("MOVE"), 0, 0}, + { wxT("NOTIFY"), 0, 0}, + { wxT("END"), 0, 0}, + // { wxT("PREPARE"), 0, 0}, handled individually + { wxT("REINDEX"), 0, 0}, + { wxT("RELEASE"), wxT("pg/sql-release-savepoint"), 0}, + { wxT("RESET"), 0, 0}, + { wxT("REVOKE"), 0, 0}, + // { wxT("ROLLBACK"), 0, 0}, handled individually + { wxT("SAVEPOINT"), 0, 0}, + { wxT("SELECT"), 0, 0}, + { wxT("SET"), 0, 0}, + { wxT("SHOW"), 0, 0}, + { wxT("START"), wxT("pg/sql-start-transaction"), 0}, + { wxT("TRUNCATE"), 0, 0}, + { wxT("UNLISTEN"), 0, 0}, + { wxT("UPDATE"), 0, 0}, + { wxT("VACUUM"), 0, 0}, + + { wxT("AGGREGATE"), 0, 11}, + { wxT("CAST"), 0, 11}, + { wxT("CONSTRAINT"), 0, 11}, + { wxT("CONVERSION"), 0, 11}, + { wxT("DATABASE"), 0, 12}, + { wxT("DOMAIN"), 0, 11}, + { wxT("FUNCTION"), 0, 11}, + { wxT("GROUP"), 0, 12}, + { wxT("INDEX"), 0, 11}, + { wxT("LANGUAGE"), 0, 11}, + { wxT("OPERATOR"), 0, 11}, + { wxT("ROLE"), 0, 11}, + { wxT("RULE"), 0, 11}, + { wxT("SCHEMA"), 0, 11}, + { wxT("SEQUENCE"), 0, 11}, + { wxT("TABLE"), 0, 12}, + { wxT("TABLESPACE"), 0, 12}, + { wxT("TRIGGER"), 0, 12}, + { wxT("TYPE"), 0, 11}, + { wxT("USER"), 0, 12}, + { wxT("VIEW"), 0, 11}, + { wxT("EXTTABLE"), 0, 12}, + { 0, 0 } +}; + +void frmQuery::OnContents(wxCommandEvent &event) +{ + DisplayHelp(wxT("query"), HELP_PGADMIN); +} + + +void frmQuery::OnChangeConnection(wxCommandEvent &ev) +{ + // On Solaris, this event seems to get fired when the form closes(!!) + if(!IsVisible() && !loading) + return; + + unsigned int sel = cbConnection->GetSelection(); + if (sel == cbConnection->GetCount() - 1) + { + // new Connection + dlgSelectConnection dlg(this, mainForm); + int rc = dlg.Go(conn, cbConnection); + if (rc == wxID_OK) + { + bool createdNewConn; + wxString usr=wxEmptyString; + wxGetEnv(wxT("USERNAME"),&usr); + + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - query ")+usr; + pgConn *newconn = dlg.CreateConn(applicationname, createdNewConn); + if (newconn && createdNewConn) + { + cbConnection->Insert(newconn->GetName(), CreateBitmap(GetServerColour(newconn)), sel); + cbConnection->SetClientData(sel, (void *)newconn); + cbConnection->SetSelection(sel); + OnChangeConnection(ev); + } + else + rc = wxID_CANCEL; + } + if (rc != wxID_OK) + { + unsigned int i; + for (i = 0 ; i < sel ; i++) + { + if (cbConnection->GetClientData(i) == conn) + { + cbConnection->SetSelection(i); + break; + } + } + } + } + else + { + conn = (pgConn *)cbConnection->GetClientData(sel); + SqlBookSetDatabase(conn); + int len = sizeof(ctlSQL) / sizeof(ctlSQL[0]); + for (int i=0;iSetConnection(conn); + //sqlResult->SetConnection(conn); + pgScript->SetConnection(conn); + title = wxT("Query - ") + cbConnection->GetValue(); + setExtendedTitle(); + + //Refresh GQB Tree if used + if(conn && !firstTime) + { + controller->getTablesBrowser()->refreshTables(conn); + controller->getView()->Refresh(); + } + } +} + + +void frmQuery::OnHelp(wxCommandEvent &event) +{ + wxString page; + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + + query.Trim(false); + + if (!query.IsEmpty()) + { + wxStringTokenizer tokens(query); + query = tokens.GetNextToken(); + + if (query.IsSameAs(wxT("PREPARE"), false)) + { + if (tokens.GetNextToken().IsSameAs(wxT("TRANSACTION"), false)) + page = wxT("sql-prepare-transaction"); + else + page = wxT("sql-prepare"); + } + else if (query.IsSameAs(wxT("ROLLBACK"), false)) + { + if (tokens.GetNextToken().IsSameAs(wxT("PREPARED"), false)) + page = wxT("sql-rollback-prepared"); + else + page = wxT("sql-rollback"); + } + else + { + SqlTokenHelp *sth = sqlTokenHelp; + while (sth->token) + { + if (sth->type < 10 && query.IsSameAs(sth->token, false)) + { + if (sth->page) + page = sth->page; + else + page = wxT("sql-") + query.Lower(); + + if (sth->type) + { + int type = sth->type + 10; + + query = tokens.GetNextToken(); + sth = sqlTokenHelp; + while (sth->token) + { + if (sth->type >= type && query.IsSameAs(sth->token, false)) + { + if (sth->page) + page += sth->page; + else + page += query.Lower(); + break; + } + sth++; + } + if (!sth->token) + page = wxT("sql-commands"); + } + break; + } + sth++; + } + } + } + if (page.IsEmpty()) + page = wxT("sql-commands"); + + if (conn->GetIsEdb()) + DisplayHelp(page, HELP_ENTERPRISEDB); + else if (conn->GetIsGreenplum()) + DisplayHelp(page, HELP_GREENPLUM); + else + DisplayHelp(page, HELP_POSTGRESQL); +} + + +void frmQuery::OnSaveHistory(wxCommandEvent &event) +{ +#ifdef __WXMSW__ + wxFileDialog *dlg = new wxFileDialog(this, _("Save history"), lastDir, wxEmptyString, + _("Log files (*.log)|*.log|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog *dlg = new wxFileDialog(this, _("Save history"), lastDir, wxEmptyString, + _("Log files (*.log)|*.log|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + if (dlg->ShowModal() == wxID_OK) + { + if (!FileWrite(dlg->GetPath(), msgHistory->GetValue(), false)) + { + wxLogError(__("Could not write the file %s: Errcode=%d."), dlg->GetPath().c_str(), wxSysErrorCode()); + } + } + delete dlg; + +} +void frmQuery::OnChangeNotebookOutpane(wxAuiNotebookEvent &event) +{ + if (outputPane->GetPageCount() > 0) + { + size_t curpage = outputPane->GetSelection(); + if (wxDynamicCast(outputPane->GetPage(curpage), wxTextCtrl)) + { + + wxTextCtrl *hist = wxDynamicCast(outputPane->GetPage(curpage), wxTextCtrl); + //hist->SetInsertionPointEnd(); + //outputPane->Get + if (outputPane->GetPageText(curpage)==_("History")) { + ///showMessage(hist->GetName()); + hist->ShowPosition(99999999); + } + //showMessage(); + } + if (wxDynamicCast(outputPane->GetPage(curpage), ctlSQLResult)) + { + ctlSQLResult *c=wxDynamicCast(outputPane->GetPage(curpage), ctlSQLResult); + int len = sizeof(ctlSQL) / sizeof(ctlSQL[0]); + for (int i=0;iCmdKeyExecute(wxSTC_CMD_TAB); + } + +} +void frmQuery::OnChangeNotebook(wxAuiNotebookEvent &event) +{ + // A bug in wxGTK prevents us to show a modal dialog within a + // EVT_AUINOTEBOOK_PAGE_CHANGED event + // So, we need these three lines of code to work-around it + wxWindow *win = wxWindow::GetCapture(); + if (win) + win->ReleaseMouse(); + + if(sqlNotebook && sqlNotebook->GetPageCount() >= 2) + { + + if (event.GetSelection() == 0) + { + queryMenu->SetHelpString(MNU_EXECUTE, _("Execute query")); + queryMenu->SetHelpString(MNU_EXECFILE, _("Execute query, write result to file")); + toolBar->SetToolShortHelp(MNU_EXECUTE, _("Execute query")); + toolBar->SetToolShortHelp(MNU_EXECFILE, _("Execute query, write result to file")); + viewMenu->Enable(MNU_OUTPUTPANE, true); + viewMenu->Enable(MNU_SCRATCHPAD, true); + + // Reset the panes + if (viewMenu->IsChecked(MNU_OUTPUTPANE)) + manager.GetPane(wxT("outputPane")).Show(true); + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + manager.Update(); + + updateFromGqb(false); + } + else + { + manager.GetPane(wxT("outputPane")).Show(false); + manager.GetPane(wxT("scratchPad")).Show(false); + manager.Update(); + viewMenu->Enable(MNU_OUTPUTPANE, false); + viewMenu->Enable(MNU_SCRATCHPAD, false); + + if(firstTime) //Things that should be done on first click on GQB + { + // Menu + queryMenu->Append(MNU_EXECUTE, _("Generate SQL from Graphical Query Builder Model")); + queryMenu->SetHelpString(MNU_EXECFILE, _("Generate SQL from Graphical Query Builder Model")); + toolBar->SetToolShortHelp(MNU_EXECUTE, _("Generate SQL from Graphical Query Builder Model")); + toolBar->SetToolShortHelp(MNU_EXECFILE, _("Generate SQL from Graphical Query Builder Model")); + + // Size, and pause to allow the window to draw + adjustGQBSizes(); + wxTheApp->Yield(true); + + // Database related Stuffs. + // Create a server object and connect it. + controller->getTablesBrowser()->refreshTables(conn); + firstTime = false; + } + } + } +} + + +void frmQuery::OnSetFocus(wxFocusEvent &event) +{ + sqlQuery->SetFocus(); + event.Skip(); +} + + +void frmQuery::OnClearHistory(wxCommandEvent &event) +{ + queryMenu->Enable(MNU_SAVEHISTORY, false); + queryMenu->Enable(MNU_CLEARHISTORY, false); + msgHistory->Clear(); + msgHistory->SetFont(settings->GetSQLFont()); +} + + +void frmQuery::OnFocus(wxFocusEvent &ev) +{ + if (wxDynamicCast(this, wxFrame)) + updateMenu(); + else + { + frmQuery *wnd = (frmQuery *)GetParent(); + + if (wnd) + wnd->OnFocus(ev); + } + ev.Skip(); +} + + +void frmQuery::OnCut(wxCommandEvent &ev) +{ + if (currentControl() == sqlQuery) + { + sqlQuery->Cut(); + updateMenu(); + } +} + + +wxWindow *frmQuery::currentControl() +{ + wxWindow *wnd = FindFocus(); + if (wnd == outputPane) + { + wnd = sqlResult; + switch (outputPane->GetSelection()) + { + case 0: + wnd = sqlResult; + break; + case 1: + wnd = explainCanvas; + break; + case 2: + wnd = msgResult; + break; + case 3: + wnd = msgHistory; + break; + } + } + return wnd; + +} + + +void frmQuery::OnCopy(wxCommandEvent &ev) +{ + wxWindow *wnd = currentControl(); + + if (wnd == sqlQuery) + sqlQuery->Copy(); + else if (wnd == msgResult) + msgResult->Copy(); + else if (wnd == msgHistory) + msgHistory->Copy(); + else if (wnd == scratchPad) + scratchPad->Copy(); + else + { + wxWindow *obj = wnd; + + while (obj != NULL) + { + if (obj == sqlResult) + { + sqlResult->Copy(false); + break; + } + obj = obj->GetParent(); + } + } + updateMenu(); +} + + +void frmQuery::OnPaste(wxCommandEvent &ev) +{ + if (currentControl() == sqlQuery) + sqlQuery->Paste(); + else if (currentControl() == scratchPad) + scratchPad->Paste(); +} + + +void frmQuery::OnClear(wxCommandEvent &ev) +{ + wxWindow *wnd = currentControl(); + + if (wnd == sqlQuery) + sqlQuery->ClearAll(); + else if (wnd == msgResult) + { + msgResult->Clear(); + msgResult->SetFont(settings->GetSQLFont()); + } + else if (wnd == msgHistory) + { + msgHistory->Clear(); + msgHistory->SetFont(settings->GetSQLFont()); + } + else if (wnd == scratchPad) + scratchPad->Clear(); +} + + +void frmQuery::OnSelectAll(wxCommandEvent &ev) +{ + wxWindow *wnd = currentControl(); + + if (wnd == sqlQuery) + sqlQuery->SelectAll(); + else if (wnd == msgResult) + msgResult->SelectAll(); + else if (wnd == msgHistory) + msgHistory->SelectAll(); + else if (wnd == sqlResult) + sqlResult->SelectAll(); + else if (wnd == scratchPad) + scratchPad->SelectAll(); + else if (wnd->GetParent() == sqlResult) + sqlResult->SelectAll(); +} + + +void frmQuery::OnSearchReplace(wxCommandEvent &ev) +{ + sqlQuery->OnSearchReplace(ev); +} + + +void frmQuery::OnUndo(wxCommandEvent &ev) +{ + sqlQuery->Undo(); +} + + +void frmQuery::OnRedo(wxCommandEvent &ev) +{ + sqlQuery->Redo(); +} + + +void frmQuery::setExtendedTitle() +{ + wxString chgStr; + if (sqlQuery->IsChanged()) + chgStr = wxT(" *"); + + wxString filename = sqlQuery->GetFilename(); + if (filename.IsNull()) + SetTitle(title + chgStr); + else + { + SetTitle(title + wxT(" - [") + filename + wxT("]") + chgStr); + } + // Allow to save initial queries though they are not changed + bool enableSave = sqlQuery->IsChanged() || (sqlQuery->GetOrigin() == ORIGIN_INITIAL); + toolBar->EnableTool(MNU_SAVE, enableSave); + fileMenu->Enable(MNU_SAVE, enableSave); +} + +bool frmQuery::relatesToWindow(wxWindow *which, wxWindow *related) +{ + while (which != NULL) + { + if (which == related) + return true; + else + which = which->GetParent(); + } + return false; +} + +void frmQuery::updateMenu(bool allowUpdateModelSize) +{ + bool canCut = false; + bool canCopy = false; + bool canPaste = false; + bool canUndo = false; + bool canRedo = false; + bool canClear = false; + bool canFind = false; + bool canAddFavourite = false; + bool canManageFavourite = false; + bool canSaveExplain = false; + bool canSaveGQB = false; + + wxAuiFloatingFrame *fp = wxDynamicCastThis(wxAuiFloatingFrame); + if (fp) + return; + + if (closing) + return; + + canSaveExplain = explainCanvas->GetDiagram()->GetCount() > 0; + + if (allowUpdateModelSize) + { + canSaveGQB = controller->getView() != NULL && controller->getView()->canSaveAsImage(); + } + + saveasImageMenu->Enable(MNU_SAVEAS_IMAGE_GQB, canSaveGQB); + saveasImageMenu->Enable(MNU_SAVEAS_IMAGE_EXPLAIN, canSaveExplain); + + wxWindow *wnd = currentControl(); + if (wnd == NULL) + return; + + if (relatesToWindow(wnd, sqlQuery) + || relatesToWindow(wnd, sqlResult) + || relatesToWindow(wnd, msgResult) + || relatesToWindow(wnd, msgHistory) + || relatesToWindow(wnd, scratchPad)) + { + if (relatesToWindow(wnd, sqlQuery)) + { + canUndo = sqlQuery->CanUndo(); + canRedo = sqlQuery->CanRedo(); + canPaste = sqlQuery->CanPaste(); + canFind = true; + canAddFavourite = (sqlQuery->GetLength() > 0) && (settings->GetFavouritesFile().Length() > 0); + canManageFavourite = (settings->GetFavouritesFile().Length() > 0); + } + else if (relatesToWindow(wnd, scratchPad)) + { + canPaste = true; + } + canCopy = true; + canCut = true; + canClear = true; + } + + toolBar->EnableTool(MNU_UNDO, canUndo); + editMenu->Enable(MNU_UNDO, canUndo); + + toolBar->EnableTool(MNU_REDO, canRedo); + editMenu->Enable(MNU_REDO, canRedo); + + toolBar->EnableTool(MNU_COPY, canCopy); + editMenu->Enable(MNU_COPY, canCopy); + + toolBar->EnableTool(MNU_PASTE, canPaste); + editMenu->Enable(MNU_PASTE, canPaste); + + toolBar->EnableTool(MNU_CUT, canCut); + editMenu->Enable(MNU_CUT, canCut); + + toolBar->EnableTool(MNU_CLEAR, canClear); + editMenu->Enable(MNU_CLEAR, canClear); + + toolBar->EnableTool(MNU_FIND, canFind); + editMenu->Enable(MNU_FIND, canFind); + + favouritesMenu->Enable(MNU_FAVOURITES_ADD, canAddFavourite); + favouritesMenu->Enable(MNU_FAVOURITES_INJECT, canAddFavourite); // these two use the same criteria + favouritesMenu->Enable(MNU_FAVOURITES_MANAGE, canManageFavourite); +} + + +void frmQuery::UpdateFavouritesList() +{ + if (IsVisible() && menuBar->FindMenu(_("Fav&ourites")) == wxNOT_FOUND) + return; + + if (favourites) + delete favourites; + + favourites = queryFavouriteFileProvider::LoadFavourites(true); + + while (favouritesMenu->GetMenuItemCount() > 4) // there are 3 static items + separator above + { + favouritesMenu->Destroy(favouritesMenu->GetMenuItems()[4]); + } + + favourites->AppendAllToMenu(favouritesMenu, MNU_FAVOURITES_MANAGE + 1); +} + + +void frmQuery::UpdateMacrosList() +{ + if (IsVisible() && menuBar->FindMenu(_("&Macros")) == wxNOT_FOUND) + return; + + if (macros) + delete macros; + + macros = queryMacroFileProvider::LoadMacros(true); + + while (macrosMenu->GetMenuItemCount() > 2) + { + macrosMenu->Destroy(macrosMenu->GetMenuItems()[2]); + } + + macros->AppendAllToMenu(macrosMenu, MNU_MACROS_MANAGE + 1); +} + + +void frmQuery::OnAddFavourite(wxCommandEvent &event) +{ + if (sqlQuery->GetText().Trim().IsEmpty()) + return; + int r = dlgAddFavourite(this, favourites).AddFavourite(sqlQuery->GetText()); + if (r == 1) + { + // Added a favourite, so save + queryFavouriteFileProvider::SaveFavourites(favourites); + } + if (r == 1 || r == -1) + { + // Changed something requiring rollback + mainForm->UpdateAllFavouritesList(); + } +} + + +void frmQuery::OnInjectFavourite(wxCommandEvent &event) +{ + queryFavouriteItem *fav; + bool selected = true; + int startPos, endPos; + wxString name = sqlQuery->GetSelectedText(); + + if (name.IsEmpty()) + { + // get the word under cursor: + int curPos = sqlQuery->GetCurrentPos(); + startPos = sqlQuery->WordStartPosition(curPos, true); + endPos = sqlQuery->WordEndPosition(curPos, true); + name = sqlQuery->GetTextRange(startPos, endPos); + selected = false; + } + name.Trim(false).Trim(true); + if (name.IsEmpty()) + return; + + // search for favourite with this name + fav = favourites->FindFavourite(name); + if (!fav) + return; + + // replace selection (or current word) with it's contents + //wxLogInfo(wxT("frmQuery::OnReplaceFavourite(): name=[%s] contents=[%s]"), name, fav->GetContents()); + sqlQuery->BeginUndoAction(); + if (!selected) + sqlQuery->SetSelection(startPos, endPos); + sqlQuery->ReplaceSelection(fav->GetContents()); + sqlQuery->EndUndoAction(); +} + + +void frmQuery::OnManageFavourites(wxCommandEvent &event) +{ + int r = dlgManageFavourites(this, favourites).ManageFavourites(); + if (r == 1) + { + // Changed something, so save + queryFavouriteFileProvider::SaveFavourites(favourites); + } + if (r == 1 || r == -1) + { + // Changed something requiring rollback + mainForm->UpdateAllFavouritesList(); + } +} + + +void frmQuery::OnSelectFavourite(wxCommandEvent &event) +{ + queryFavouriteItem *fav; + + fav = favourites->FindFavourite(event.GetId()); + if (!fav) + return; + + if (!sqlQuery->GetText().Trim().IsEmpty()) + { + int r = wxMessageDialog(this, _("Replace current query?"), _("Confirm replace"), wxYES_NO | wxCANCEL | wxICON_QUESTION).ShowModal(); + if (r == wxID_CANCEL) + return; + else if (r == wxID_YES) + sqlQuery->ClearAll(); + else + { + if (sqlQuery->GetText().Last() != '\n') + sqlQuery->AddText(wxT("\n")); // Add a newline after the last query + } + } + sqlQuery->AddText(fav->GetContents()); +} + + +bool frmQuery::CheckChanged(bool canVeto) +{ + if (sqlQuery->IsChanged() && settings->GetAskSaveConfirmation()) + { + wxString fn, filename; + filename = sqlQuery->GetFilename(); + if (!filename.IsNull()) + fn = wxString::Format(_("The text in file %s has changed.\nDo you want to save changes?"), filename.c_str()); + else + fn = _("The text has changed.\nDo you want to save changes?"); + wxMessageDialog msg(this, fn, _("Query"), + wxYES_NO | wxICON_EXCLAMATION | + (canVeto ? wxCANCEL : 0)); + + wxCommandEvent noEvent; + switch (msg.ShowModal()) + { + case wxID_YES: + if (filename.IsNull()) + OnSaveAs(noEvent); + else + OnSave(noEvent); + + return sqlQuery->IsChanged(); + + case wxID_CANCEL: + return true; + } + + } + return false; +} + + +void frmQuery::OnClose(wxCloseEvent &event) +{ + if (queryMenu->IsEnabled(MNU_CANCEL)) + { + if (event.CanVeto()) + { + wxMessageDialog msg(this, _("A query is running. Do you wish to cancel it?"), _("Query"), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION); + + if (msg.ShowModal() != wxID_YES) + { + event.Veto(); + return; + } + } + + wxCommandEvent ev; + OnCancel(ev); + } + + while (sqlResult->RunStatus() == CTLSQL_RUNNING) + { + wxLogInfo(wxT("SQL Query box: Waiting for query to abort")); + wxSleep(1); + } + + if (m_loadingfile && event.CanVeto()) + { + wxMessageBox(_("The query tool cannot be closed whilst a file is loading."), _("Warning"), wxICON_INFORMATION | wxOK); + event.Veto(); + + return; + } + + if (SqlBookClose(event.CanVeto()) && event.CanVeto()) + { + event.Veto(); + return; + } + + closing = true; + + // Reset the panes + if (viewMenu->IsChecked(MNU_OUTPUTPANE)) + manager.GetPane(wxT("outputPane")).Show(true); + if (viewMenu->IsChecked(MNU_SCRATCHPAD)) + manager.GetPane(wxT("scratchPad")).Show(true); + manager.Update(); + + Hide(); + int len = sizeof(ctlSQL) / sizeof(ctlSQL[0]); + for (int i=0;iDisconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + +// sqlResult->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgResult->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + msgHistory->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + + controller->nullView(); //to avoid bug on *nix when deleting controller + + settings->SetExplainVerbose(queryMenu->IsChecked(MNU_VERBOSE)); + settings->SetExplainCosts(queryMenu->IsChecked(MNU_COSTS)); + settings->SetExplainBuffers(queryMenu->IsChecked(MNU_BUFFERS)); + settings->SetExplainTiming(queryMenu->IsChecked(MNU_TIMING)); + + for (int i=0;iAbort(); + +// sqlResult->Abort(); // to make sure conn is unused + + Destroy(); + +} + + +void frmQuery::OnChangeStc(wxStyledTextEvent &event) +{ + // The STC seems to fire this event even if it loses focus. Fortunately, + // that seems to be m_modificationType == 512. + // 0x4010 - SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER + if ((event.m_modificationType != 512 && event.m_modificationType != 0x4010)&& + // Sometimes there come events 20 and 520 AFTER the initial query was set by constructor. + // Their occurrence is related to query's size and possibly international characters in it (??) + // Filter them out to keep "initial" origin of query text. + (sqlQuery->GetOrigin() != ORIGIN_INITIAL || (event.m_modificationType != 20 && event.m_modificationType != 520))) + { + // This is the default change origin. + // In other cases the changer function will reset it after this event. + sqlQuery->SetOrigin(ORIGIN_MANUAL); + if (!sqlQuery->IsChanged()) + { + sqlQuery->SetChanged(true); + setExtendedTitle(); + SqlBookUpdatePageTitle(); + } + } + // do not allow update of model size of GQB on input (key press) of each + // character of the query in Query Tool + updateMenu(false); +} +void frmQuery::OnLabelRightClick(wxGridEvent &event) +{ + wxMenu *xmenu = new wxMenu(); + wxArrayInt rows = sqlResult->GetSelectedRows(); + xmenu->Append(MNU_COPY, _("&Copy"), _("Copy selected cells to clipboard.")); + xmenu->Append(MNU_PASTE, _("&Paste"), _("Paste data from the clipboard.")); + xmenu->Append(MNU_DELETE, _("&Delete"), _("Delete selected rows.")); + xmenu->Append(MNU_SUMMARY_COL, _("Summary"), _("Summary selected cells.")); + xmenu->Append(MNU_COPY_INSERT, _("Copy Insert format"), _("Copy Insert format.")); + xmenu->Append(MNU_CLEAR_FILTER, _("Clear filter"), _("Clear filter")); + + if ((rows.GetCount())) + { + xmenu->Enable(MNU_COPY, true); + xmenu->Enable(MNU_DELETE, true); + xmenu->Enable(MNU_PASTE, true); + } + else + { + xmenu->Enable(MNU_COPY, false); + xmenu->Enable(MNU_DELETE, false); + xmenu->Enable(MNU_PASTE, false); + } + xmenu->Enable(MNU_CLEAR_FILTER, isfilterresult); + sqlResult->PopupMenu(xmenu); +} +void frmQuery::OnCopy_Insert(wxCommandEvent &ev) +{ +// if (currentControl() == sqlResult) + { + wxString s=wxT("Insert into format copy buffer."); + sqlResult->Copy(true); + SetStatusText(s, STATUSPOS_POS); + } +} +void frmQuery::OnCellLeftDClick(wxGridEvent &event) +{ + int row=event.GetRow(); + int col=event.GetCol(); + bool reverse=event.AltDown(); + wxString s=wxEmptyString; + s.Printf("wait ...",row,col); + SetStatusText(s, STATUSPOS_MSGS); + s=sqlResult->SetFilter(row,col,reverse); + isfilterresult=true; + SetStatusText(s, STATUSPOS_MSGS); +} +void frmQuery::OnClear_Filter(wxCommandEvent &ev) +{ +// if (currentControl() == sqlResult) + { + wxString s=wxT("Clear filter"); + sqlResult->ClearFilter(); + SetStatusText(s, STATUSPOS_MSGS); + isfilterresult=false; + } +} + +void frmQuery::OnSummary_Column(wxCommandEvent &ev) +{ +// if (currentControl() == sqlResult) + { + wxString s=sqlResult->SummaryColumn(); + SetStatusText(s, STATUSPOS_POS); + } +} + +void frmQuery::OnPositionStc(wxStyledTextEvent &event) +{ + int selFrom, selTo, selCount; + sqlQuery->GetSelection(&selFrom, &selTo); + selCount = selTo - selFrom; + editMenu->Enable(MNU_AUTOEDITOBJECT, selCount > 0); + wxString pos; + pos.Printf(_("Ln %d, Col %d, Ch %d"), sqlQuery->LineFromPosition(sqlQuery->GetCurrentPos()) + 1, sqlQuery->GetColumn(sqlQuery->GetCurrentPos()) + 1, sqlQuery->GetCurrentPos() + 1); + //pos.Printf(_("Ln %d, Col %d, Ch %d, st %d"), sqlQuery->LineFromPosition(sqlQuery->GetCurrentPos()) + 1, sqlQuery->GetColumn(sqlQuery->GetCurrentPos()) + 1, sqlQuery->GetCurrentPos() + 1,sqlQuery->GetStyleAt(sqlQuery->GetCurrentPos() - 1)); + + SetStatusText(pos, STATUSPOS_POS); + if (selCount < 1) + pos = wxEmptyString; + else + pos.Printf(wxPLURAL("%d char", "%d chars", selCount), selCount); + SetStatusText(pos, STATUSPOS_SEL); +} + + +void frmQuery::OpenLastFile() +{ + wxString str; + bool modeUnicode = settings->GetUnicodeFile(); + wxUtfFile file(lastPath, wxFile::read, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + + m_loadingfile = true; + if (file.IsOpened()) + file.Read(str); + + if (!str.IsEmpty()) + { + sqlQuery->SetText(str); + sqlQuery->Colourise(0, str.Length()); + sqlQuery->EmptyUndoBuffer(); + wxSafeYield(); // needed to process sqlQuery modify event + sqlQuery->SetFilename(lastPath); + sqlQuery->SetChanged(false); + sqlQuery->SetOrigin(ORIGIN_FILE); + setExtendedTitle(); + SqlBookUpdatePageTitle(); + SetLineEndingStyle(); + UpdateRecentFiles(true); + if(mainForm != NULL) + { + mainForm->UpdateAllRecentFiles(); + } + } + sqlQuery->SetFocus(); + m_loadingfile = false; +} + + +void frmQuery::UpdateAllRecentFiles() +{ + mainForm->UpdateAllRecentFiles(); +} + +void frmQuery::OnNew(wxCommandEvent &event) +{ + frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn->Duplicate(), wxEmptyString); + if (mainForm) + mainForm->AddFrame(fq); + fq->Go(); +} + + +void frmQuery::OnOpen(wxCommandEvent &event) +{ + if (CheckChanged(true)) + return; + +#ifdef __WXMSW__ + wxFileDialog dlg(this, _("Open query file"), lastDir, wxT(""), + _("Query files (*.sql)|*.sql|pgScript files (*.pgs)|*.pgs|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog dlg(this, _("Open query file"), lastDir, wxT(""), + _("Query files (*.sql)|*.sql|pgScript files (*.pgs)|*.pgs|All files (*)|*"), wxFD_OPEN); +#endif + + if (dlg.ShowModal() == wxID_OK) + { + lastFilename = dlg.GetFilename(); + lastDir = dlg.GetDirectory(); + lastPath = dlg.GetPath(); + OpenLastFile(); + } +} + +void frmQuery::SaveTempFile() +{ + bool modeUnicode = settings->GetUnicodeFile(); + wxString filename = sqlQuery->GetFilename(); + if (!filename.IsNull()) + { + return; + } + filename=sqlQuery->GetTitle(false); + wxString pref=conn->GetDbname(); + //if (filename.StartsWith(pref)) + filename+=wxT(".a"); + wxString tempDir=wxStandardPaths::Get().GetUserConfigDir()+wxT("\\postgresql\\recovery"); + wxUtfFile file(tempDir+wxT("\\")+filename, wxFile::write, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { + int nl=sqlQuery->GetCurrentPos(); + wxString strnl; + strnl=wxString::Format(_("%i@"), nl); + file.Write(strnl); + if ((file.Write(sqlQuery->GetText()) == 0) && (!modeUnicode)) + wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead.")); + file.Close(); + sqlQuery->SetChanged(false); + SqlBookUpdatePageTitle(); + } + else + { + wxLogError(__("Could not write the file %s: Errcode=%d."), filename.c_str(), wxSysErrorCode()); + } + + +} + +void frmQuery::OnSave(wxCommandEvent &event) +{ + bool modeUnicode = settings->GetUnicodeFile(); + wxString filename = sqlQuery->GetFilename(); + + if (filename.IsNull()) + { + OnSaveAs(event); + return; + } + + wxUtfFile file(filename, wxFile::write, modeUnicode ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { + if ((file.Write(sqlQuery->GetText()) == 0) && (!modeUnicode)) + wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead.")); + file.Close(); + sqlQuery->SetChanged(false); + setExtendedTitle(); + UpdateRecentFiles(); + SqlBookUpdatePageTitle(); + } + else + { + wxLogError(__("Could not write the file %s: Errcode=%d."), filename.c_str(), wxSysErrorCode()); + } +} + + +// Set the line ending style based on the current document. +void frmQuery::SetLineEndingStyle() +{ + // Detect the file mode + wxRegEx *reLF = new wxRegEx(wxT("[^\r]\n"), wxRE_NEWLINE); + wxRegEx *reCRLF = new wxRegEx(wxT("\r\n"), wxRE_NEWLINE); + wxRegEx *reCR = new wxRegEx(wxT("\r[^\n]"), wxRE_NEWLINE); + + bool haveLF = reLF->Matches(sqlQuery->GetText()); + bool haveCRLF = reCRLF->Matches(sqlQuery->GetText()); + bool haveCR = reCR->Matches(sqlQuery->GetText()); + int mode = GetLineEndingStyle(); + + if ((haveLF && haveCR) || + (haveLF && haveCRLF) || + (haveCR && haveCRLF)) + { + wxMessageBox(_("This file contains mixed line endings. They will be converted to the current setting."), _("Warning"), wxICON_INFORMATION | wxOK); + sqlQuery->ConvertEOLs(mode); + sqlQuery->SetChanged(true); + setExtendedTitle(); + updateMenu(); + } + else + { + if (haveLF) + mode = wxSTC_EOL_LF; + else if (haveCRLF) + mode = wxSTC_EOL_CRLF; + else if (haveCR) + mode = wxSTC_EOL_CR; + } + + // Now set the status text, menu options, and the mode + sqlQuery->SetEOLMode(mode); + SetEOLModeDisplay(mode); + + delete reCRLF; + delete reCR; + delete reLF; +} + + +// Get the line ending style +int frmQuery::GetLineEndingStyle() +{ + if (lineEndMenu->IsChecked(MNU_LF)) + return wxSTC_EOL_LF; + else if (lineEndMenu->IsChecked(MNU_CRLF)) + return wxSTC_EOL_CRLF; + else if (lineEndMenu->IsChecked(MNU_CR)) + return wxSTC_EOL_CR; + else + return sqlQuery->GetEOLMode(); +} + +void frmQuery::OnAutoEditObject(wxCommandEvent &event) +{ + //parent->SetCurrentNode(parent->GetBrowser()->GetRootItem(), path); + pgObject *obj = mainForm->GetBrowser()->GetObject(mainForm->GetBrowser()->GetSelection()); + pgFunction *fun=(pgFunction *)obj;//obj->Show + //mainForm.propFactory->StartDialog(mainForm, obj); + //showMessage(obj->GetTypeName()); + //return; + if (obj->GetTypeName()==wxT("Servers")||obj->GetTypeName()==wxT("Server")||obj->GetTypeName()==wxT("Databases") + ||obj->GetTypeName()==wxT("Tablespaces")||obj->GetTypeName()==wxT("Group Roles") + ||obj->GetTypeName()==wxT("Login Roles") + ) return; + wxString databasePath = mainForm->GetNodePath(obj->GetDatabase()->GetId()); + //showMessage(databasePath); + wxString selText = sqlQuery->GetSelectedText(); + if (!selText.IsNull()) { + databasePath =databasePath +wxT("/")+ _("Schemas"); + if(!mainForm->SetCurrentNode(mainForm->GetBrowser()->GetRootItem(), databasePath)) + { + wxMessageBox(_("The specified object couldn't be found in the tree.") + databasePath); + } + //int n=mainForm->GetBrowser()->GetChildrenCount(mainForm->GetBrowser()->GetSelection(),false); + wxTreeItemId matchItem = mainForm->GetBrowser()->FindItem(obj->GetId(),selText,true); + + if (matchItem.IsOk()) { + wxString findtext= mainForm->GetBrowser()->GetItemText(matchItem); + pgObject *o=mainForm->GetBrowser()->GetObject(matchItem); + //mainForm->GetBrowser()->SelectItem(o->GetId()); + //showMessage(o->GetName().Lower()); + if (o->GetName().Lower()==selText.Lower()) { + + //obj = mainForm->GetBrowser()->GetObject(mainForm->GetBrowser()->GetSelection()); + mainForm->execSelChange(matchItem,false); + obj=o; + if (!dlgProperty::EditObjectDialog(mainForm, 0, obj)) + mainForm->CheckAlive(); + + } + } + } + +} +// User-set the current EOL mode for the form +void frmQuery::OnSetEOLMode(wxCommandEvent &event) +{ + int mode = GetLineEndingStyle(); + sqlQuery->ConvertEOLs(mode); + sqlQuery->SetEOLMode(mode); + settings->SetLineEndingType(mode); + + SetEOLModeDisplay(mode); + + if (!sqlQuery->IsChanged()) + { + sqlQuery->SetChanged(true); + setExtendedTitle(); + } + setExtendedTitle(); + + // TODO: Figure out why this is here? + pgScript->SetConnection(conn); +} + + +// Display the EOL mode settings on the form +void frmQuery::SetEOLModeDisplay(int mode) +{ + switch(mode) + { + + case wxSTC_EOL_LF: + lineEndMenu->Check(MNU_LF, true); + SetStatusText(_("Unix"), STATUSPOS_FORMAT); + break; + + case wxSTC_EOL_CRLF: + lineEndMenu->Check(MNU_CRLF, true); + SetStatusText(_("DOS"), STATUSPOS_FORMAT); + break; + + case wxSTC_EOL_CR: + lineEndMenu->Check(MNU_CR, true); + SetStatusText(_("Mac"), STATUSPOS_FORMAT); + break; + + default: + wxLogError(wxT("Someone created a new line ending style! Run, run for your lives!!")); + } +} + + +void frmQuery::OnSaveAs(wxCommandEvent &event) +{ + wxString filename; + filename = sqlQuery->GetFilename(); + if (filename.IsNull()) + filename = lastFilename; + +#ifdef __WXMSW__ + wxFileDialog *dlg = new wxFileDialog(this, _("Save query file as"), lastDir, filename, /*lastFilename,*/ + _("Query files (*.sql)|*.sql|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog *dlg = new wxFileDialog(this, _("Save query file as"), lastDir, filename, /*lastFilename,*/ + _("Query files (*.sql)|*.sql|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + if (dlg->ShowModal() == wxID_OK) + { + lastFilename = dlg->GetFilename(); + lastDir = dlg->GetDirectory(); + lastPath = dlg->GetPath(); + switch (dlg->GetFilterIndex()) + { + case 0: +#ifdef __WXMAC__ + if (!lastPath.Contains(wxT("."))) + lastPath += wxT(".sql"); +#endif + break; + case 1: +#ifdef __WXMAC__ + if (!lastPath.Contains(wxT("."))) + lastPath += wxT(".sql"); +#endif + break; + default: + break; + } + + lastFileFormat = settings->GetUnicodeFile(); + + wxUtfFile file(lastPath, wxFile::write, lastFileFormat ? wxFONTENCODING_UTF8 : wxFONTENCODING_DEFAULT); + if (file.IsOpened()) + { + if ((file.Write(sqlQuery->GetText()) == 0) && (!lastFileFormat)) + wxMessageBox(_("Query text incomplete.\nQuery contained characters that could not be converted to the local charset.\nPlease correct the data or try using UTF8 instead.")); + file.Close(); + sqlQuery->SetChanged(false); + sqlQuery->SetFilename(lastPath); + + // Forget about Initial origin thus making "Save" button behave as usual + // (be enabled/disabled according to dirty flag only). + if (sqlQuery->GetOrigin() == ORIGIN_INITIAL) + sqlQuery->SetOrigin(ORIGIN_FILE); + + setExtendedTitle(); + SqlBookUpdatePageTitle(); + SetOutputPaneCaption(true); + UpdateRecentFiles(); + fileMenu->Enable(MNU_RECENT, (recentFileMenu->GetMenuItemCount() > 0)); + } + else + { + wxLogError(__("Could not write the file %s: Errcode=%d."), lastPath.c_str(), wxSysErrorCode()); + } + } + delete dlg; +} + + +void frmQuery::OnQuickReport(wxCommandEvent &event) +{ + wxDateTime now = wxDateTime::Now(); + + frmReport *rep = new frmReport(this); + + rep->XmlAddHeaderValue(wxT("generated"), now.Format(wxT("%c"))); + rep->XmlAddHeaderValue(wxT("database"), conn->GetName()); + + rep->SetReportTitle(_("Quick report")); + + int section = rep->XmlCreateSection(_("Query results")); + + rep->XmlAddSectionTableFromGrid(section, sqlResult); + + wxString stats; + stats.Printf(wxT("%ld rows with %d columns retrieved."), sqlResult->NumRows(), sqlResult->GetNumberCols()); + + rep->XmlSetSectionTableInfo(section, stats); + + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + + rep->XmlSetSectionSql(section, query); + + rep->ShowModal(); +} + + +void frmQuery::OnCancel(wxCommandEvent &event) +{ + toolBar->EnableTool(MNU_CANCEL, false); + queryMenu->Enable(MNU_CANCEL, false); + SetStatusText(_("Cancelling."), STATUSPOS_MSGS); + + if (sqlResult->RunStatus() == CTLSQL_RUNNING) + sqlResult->Abort(); + else if (pgScript->IsRunning()) + pgScript->Terminate(); + + QueryExecInfo *qi = (QueryExecInfo *)event.GetClientData(); + if (qi) + delete qi; + + aborted = true; +} + + +void frmQuery::OnExplain(wxCommandEvent &event) +{ + if(sqlNotebook->GetSelection() == 1) + { + if (!updateFromGqb(true)) + return; + } + + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + if (queryMenu->IsChecked(MNU_AUTOSELECTQUERY)) { + // Auto-select + SelectQuery(); + query = sqlQuery->GetSelectedText(); + } else query = sqlQuery->GetText(); + + if (query.IsNull()) + return; + wxString sql; + int resultToRetrieve = 1; + bool verbose = queryMenu->IsChecked(MNU_VERBOSE); + bool analyze = event.GetId() == MNU_EXPLAINANALYZE; + + if (analyze) + { + sql += wxT("\nBEGIN;\n"); + resultToRetrieve++; + } + sql += wxT("EXPLAIN "); + if (conn->BackendMinimumVersion(9, 0)) + { + bool costs = queryMenu->IsChecked(MNU_COSTS); + bool buffers = queryMenu->IsChecked(MNU_BUFFERS) && analyze; + bool timing = queryMenu->IsChecked(MNU_TIMING) && analyze; + + sql += wxT("("); + if (analyze) + sql += wxT("ANALYZE on, "); + else + sql += wxT("ANALYZE off, "); + if (verbose) + sql += wxT("VERBOSE on, "); + else + sql += wxT("VERBOSE off, "); + if (costs) + sql += wxT("COSTS on, "); + else + sql += wxT("COSTS off, "); + if (buffers) + sql += wxT("BUFFERS on"); + else + sql += wxT("BUFFERS off"); + if (conn->BackendMinimumVersion(9, 2)) + { + if (timing) + sql += wxT(", TIMING on "); + else + sql += wxT(", TIMING off "); + } + sql += wxT(")"); + } + else + { + if (analyze) + sql += wxT("ANALYZE "); + if (verbose) + sql += wxT("VERBOSE "); + } + + int offset = sql.Length(); + + sql += query; + + if (analyze) + { + // Bizarre bug fix - if we append a rollback directly after -- it'll crash!! + // Add a \n first. + sql += wxT("\n;\nROLLBACK;"); + } + sqlQuery->MarkerDeleteAll(1); + execQuery(sql, resultToRetrieve, true, offset, false, true, verbose); +} + +void frmQuery::OnCommit(wxCommandEvent &event) +{ + execQuery(wxT("COMMIT;")); +} + +void frmQuery::OnRollback(wxCommandEvent &event) +{ + execQuery(wxT("ROLLBACK;")); +} + +// Update the main SQL query from the GQB if desired +bool frmQuery::updateFromGqb(bool executing) +{ + if (closing) + return false; + + // Make sure this doesn't get call recursively through an event + if (gqbUpdateRunning) + return false; + updateMenu(); + + gqbUpdateRunning = true; + + // Execute Generation of SQL sentence from GQB + bool canGenerate = false; + wxString newQuery = controller->generateSQL(); + + // If the new query is empty, don't do anything + if (newQuery.IsEmpty()) + { + if (controller->getTableCount() > 0) + { + wxMessageBox(_("No SQL query was generated."), _("Graphical Query Builder"), wxICON_INFORMATION | wxOK); + } + gqbUpdateRunning = false; + return false; + } + + // Only prompt the user if the dirty flag is set, and last modification wasn't from GQB, + // and the textbox is not empty, and the new query is different. + if (sqlQuery->IsChanged() && sqlQuery->GetOrigin() != ORIGIN_GQB && + !sqlQuery->GetText().Trim().IsEmpty() && sqlQuery->GetText() != newQuery + wxT("\n")) + { + wxString fn; + if (executing) + fn = _("The generated SQL query has changed.\nDo you want to update it and execute the query?"); + else + fn = _("The generated SQL query has changed.\nDo you want to update it?"); + + wxMessageDialog msg(this, fn, _("Query"), wxYES_NO | wxICON_EXCLAMATION); + if(msg.ShowModal() == wxID_YES && sqlQuery->IsChanged()) + { + canGenerate = true; + } + else + { + gqbUpdateRunning = false; + } + } + else + { + canGenerate = true; + } + + if(canGenerate) + { + sqlQuery->SetText(newQuery + wxT("\n")); + sqlQuery->Colourise(0, sqlQuery->GetText().Length()); + wxSafeYield(); // needed to process sqlQuery modify event + sqlNotebook->SetSelection(0); + sqlQuery->SetChanged(true); + sqlQuery->SetOrigin(ORIGIN_GQB); + setExtendedTitle(); + + gqbUpdateRunning = false; + return true; + } + + return false; +} +void frmQuery::SelectQuery() { + long p; + bool selected = false; + //sqlQuery->GetSelection(); + wxString name = sqlQuery->GetSelectedText(); + wxString *q=new wxString[30]; + int s,e,i=0; + if (!name.IsEmpty()) + { + // get the word under cursor: + int endDoc = sqlQuery->GetLength(); + int endPos = sqlQuery->GetSelectionEnd(); + int startPos = sqlQuery->GetSelectionStart(); + while(endPosSelectQuery(startPos); + s=p>>16; + e=p & 65535; + q[i++]=sqlQuery->GetTextRange(s, e); + startPos=e+1; + } + querys=new wxString[i]; + for (int j = 0; j < i; j++) { + querys[j]=q[j]; + } + //name = sqlQuery->GetTextRange(startPos, endPos); + //selected = false; + } else { + int curPos = sqlQuery->GetCurrentPos(); + p=sqlQuery->SelectQuery(curPos); + s=p>>16; + e=p & 65535; + querys=new wxString[1]; + querys[0]=sqlQuery->GetTextRange(s, e); + // âûäåëèì çàïðîñ êîòîðûé áóäåì âûïîëíÿòü + sqlQuery->SetSelection(s,e); + } + delete [] q; + +} +void frmQuery::OnExecuteShift(wxCommandEvent &event) +{ + //add new page outpane + int len = sizeof(ctlSQL) / sizeof(ctlSQL[0]); + wxString titlename; + for (int i=0;iAddPage(sqlResult, titlename); + sqlResult->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + indexResult=i; + ctlSQL[i]=sqlResult; + ctlSBox[i]=sqlQuery; + break; + }; + OnExecute(event); +} +void frmQuery::OnExecute(wxCommandEvent &event) +{ + if(sqlNotebook->GetSelection() == 1) + { + if (!updateFromGqb(true)) + return; + } + SaveTempFile(); + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + if (queryMenu->IsChecked(MNU_AUTOSELECTQUERY)) { + // Auto-select + SelectQuery(); + //query = sqlQuery->GetSelectedText(); + query = querys[0]; + } else query = sqlQuery->GetText(); + + if (query.IsNull()) + return; + // set marker sqlQueryExec->MarkerAdd(line, 0); // wxSTC_MARK_CIRCLE + int en=sqlQuery->GetSelectionEnd(); + int st=-1; + if (sqlQueryExecLast==sqlQuery) sqlQuery->MarkerDeleteAll(1); + + if (en>=0) { + st=sqlQuery->GetSelectionStart(); + int hline=sqlQuery->LineFromPosition(st); + int eline=sqlQuery->LineFromPosition(en); + for (int i=hline;i<=eline;i++) { + sqlQuery->MarkerAdd(i,1); + } + //sqlResult->SetRangeLineExecuteSQL(hline,eline); + } + execQuery(query); + sqlQuery->SetFocus(); +} + + +void frmQuery::OnExecScript(wxCommandEvent &event) +{ + // Get the script + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + if (query.IsNull()) + return; + + // Make sure pgScript is not already running + // Required because the pgScript parser isn't currently thread-safe :-( + if (frmQuery::ms_pgScriptRunning == true) + { + wxMessageBox(_("pgScript already running."), _("Concurrent execution of pgScripts is not supported at this time."), wxICON_WARNING | wxOK); + return; + } + frmQuery::ms_pgScriptRunning = true; + + // Clear markers and indicators + sqlQuery->MarkerDeleteAll(0); + sqlQuery->StartStyling(0, wxSTC_INDICS_MASK); + sqlQuery->SetStyling(sqlQuery->GetText().Length(), 0); + + // Menu stuff to initialize + setTools(true); + queryMenu->Enable(MNU_SAVEHISTORY, true); + queryMenu->Enable(MNU_CLEARHISTORY, true); + + // Window stuff + explainCanvas->Clear(); + msgResult->Clear(); + msgResult->SetFont(settings->GetSQLFont()); + outputPane->SetSelection(2); + + // Status text + SetStatusText(wxT(""), STATUSPOS_SECS); + SetStatusText(_("pgScript is running."), STATUSPOS_MSGS); + SetStatusText(wxT(""), STATUSPOS_ROWS); + + // History + msgHistory->AppendText(_("-- Executing pgScript\n")); + Update(); + wxTheApp->Yield(true); + + // Timer + startTimeQuery = wxGetLocalTimeMillis(); + timer.Start(10); + + // Delete previous variables + pgScript->ClearSymbols(); + + // Parse script. Note that we add \n so the parse can correctly identify + // a comment on the last line of the query. + pgScript->ParseString(query + wxT("\n"), pgsOutput); + pgsTimer->Start(20); + aborted = false; +} + + + +void frmQuery::OnExecFile(wxCommandEvent &event) +{ + if(sqlNotebook->GetSelection() == 1) + { + if (!updateFromGqb(true)) + return; + } + + wxString query = sqlQuery->GetSelectedText(); + if (query.IsNull()) + query = sqlQuery->GetText(); + + if (query.IsNull()) + return; + + execQuery(query, 0, false, 0, true); + sqlQuery->SetFocus(); +} +void frmQuery::OnAutoReplaceManage(wxCommandEvent &event) +{ + //if (autoreplace) delete + //macros = queryMacroFileProvider::LoadMacros(true); + int r = dlgManageMacros(this, mainForm, autoreplace).ManageMacros(); + if (r == 1) + { + // Changed something, so save + queryMacroFileProvider::SaveAutoReplace(autoreplace); + } + +} + +void frmQuery::OnMacroManage(wxCommandEvent &event) +{ + int r = dlgManageMacros(this, mainForm, macros).ManageMacros(); + if (r == 1) + { + // Changed something, so save + queryMacroFileProvider::SaveMacros(macros); + } + if (r == -1 || r == 1) + { + // Changed something requiring rollback + mainForm->UpdateAllMacrosList(); + } + +} + + +void frmQuery::OnMacroInvoke(wxCommandEvent &event) +{ + queryMacroItem *mac; + + mac = macros->FindMacro(event.GetId()); + if (!mac) + return; + + wxString query = mac->GetQuery(); + if (query.IsEmpty()) + return; // do not execute empty query + + if (query.Find(wxT("$SELECTION$")) != wxNOT_FOUND) + { + wxString selection = sqlQuery->GetSelectedText(); + if (selection.IsEmpty()) + { + wxMessageBox(_("This macro includes a text substitution. Please select some text in the SQL pane and re-run the macro."), _("Execute macro"), wxICON_EXCLAMATION | wxOK); + return; + } + query.Replace(wxT("$SELECTION$"), selection); + } + + execQuery(query); + sqlQuery->SetFocus(); +} + + +void frmQuery::setTools(const bool running) +{ + bool canEndTransaction = (!running && conn->GetTxStatus() != PQTRANS_IDLE); + + toolBar->EnableTool(MNU_EXECUTE, !running); + toolBar->EnableTool(MNU_EXECUTE_2, !running); + toolBar->EnableTool(MNU_EXECPGS, !running); + toolBar->EnableTool(MNU_EXECFILE, !running); + toolBar->EnableTool(MNU_EXPLAIN, !running); + toolBar->EnableTool(MNU_CANCEL, running); + toolBar->EnableTool(MNU_DOCOMMIT, canEndTransaction); + toolBar->EnableTool(MNU_DOROLLBACK, canEndTransaction); + queryMenu->Enable(MNU_EXECUTE, !running); + queryMenu->Enable(MNU_EXECUTE_2, !running); + queryMenu->Enable(MNU_EXECPGS, !running); + queryMenu->Enable(MNU_EXECFILE, !running); + queryMenu->Enable(MNU_EXPLAIN, !running); + queryMenu->Enable(MNU_EXPLAINANALYZE, !running); + queryMenu->Enable(MNU_CANCEL, running); + queryMenu->Enable(MNU_DOCOMMIT, canEndTransaction); + queryMenu->Enable(MNU_DOROLLBACK, canEndTransaction); + fileMenu->Enable(MNU_EXPORT, sqlResult->CanExport()); + fileMenu->Enable(MNU_QUICKREPORT, sqlResult->CanExport()); + fileMenu->Enable(MNU_RECENT, (recentFileMenu->GetMenuItemCount() > 0)); + sqlQuery->EnableAutoComp(running); + sqlQuery->SetSQLBoxColourBackground(canEndTransaction); +} + + +void frmQuery::showMessage(const wxString &msg, const wxString &msgShort) +{ + msgResult->AppendText(msg + wxT("\n")); + msgHistory->AppendText(msg + wxT("\n")); + wxString str; + if (msgShort.IsNull()) + str = msg; + else + str = msgShort; + str.Replace(wxT("\n"), wxT(" ")); + SetStatusText(str, STATUSPOS_MSGS); +} + + +void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singleResult, const int queryOffset, bool toFile, bool explain, bool verbose) +{ + setTools(true); + queryMenu->Enable(MNU_SAVEHISTORY, true); + queryMenu->Enable(MNU_CLEARHISTORY, true); + + explainCanvas->Clear(); + + // Clear markers and indicators + sqlQuery->MarkerDeleteAll(0); + sqlQuery->StartStyling(0, wxSTC_INDICS_MASK); + sqlQuery->SetStyling(sqlQuery->GetText().Length(), 0); + + int i=sqlQueryBook->GetSelection(); + sqlQueryBook->SetPageBitmap(i,CreateBitmap(wxColour(255,0,0))); + + if (!sqlQuery->IsChanged()) + setExtendedTitle(); + + aborted = false; + isfilterresult=false; + + sqlResult=ctlSQL[indexResult]; + sqlResult->ClearFilter(); + ctlSBox[indexResult]=sqlQuery; + // + int idx=outputPane->GetPageIndex(sqlResult); + outputPane->SetPageBitmap(idx,CreateBitmap(wxNullColour)); + + QueryExecInfo *qi = new QueryExecInfo(); + qi->queryOffset = queryOffset; + qi->toFileExportForm = NULL; + qi->singleResult = singleResult; + qi->explain = explain; + qi->verbose = verbose; + + if (toFile) + { + qi->toFileExportForm = new frmExport(this); + if (qi->toFileExportForm->ShowModal() != wxID_OK) + { + delete qi; + setTools(false); + aborted = true; + return; + } + } + + // Remember the tab from which execute was called. By the time query completes, SQL tab selection may change. + sqlQueryExec = sqlQuery; + // Because the output pane is clear during query execution, we clear the result source title on Output Pane. + sqlQueryExecLast = NULL; + SetOutputPaneCaption(true); + + // We must do this lot before the query starts, otherwise + // it might not happen once the main thread gets busy with + // other stuff. + SetStatusText(wxT(""), STATUSPOS_SECS); + SetStatusText(_("Query is running."), STATUSPOS_MSGS); + SetStatusText(wxT(""), STATUSPOS_ROWS); + msgResult->Clear(); + msgResult->SetFont(settings->GetSQLFont()); + + msgHistory->AppendText(wxString::Format(_("-- Executing query [%s]:\n"), sqlQueryExec->GetTitle(false).c_str())); + msgHistory->AppendText(query); + msgHistory->AppendText(wxT("\n")); + Update(); + wxTheApp->Yield(true); + + startTimeQuery = wxGetLocalTimeMillis(); + timer.Start(10); + + if (!queryMenu->IsChecked(MNU_AUTOCOMMIT) && conn->GetTxStatus() == PQTRANS_IDLE && !isBeginNotRequired(query)) + conn->ExecuteVoid(wxT("BEGIN;")); + + if (sqlResult->Execute(query, resultToRetrieve, this, QUERY_COMPLETE, qi) >= 0) + { + // Return and wait for the result + return; + } + + completeQuery(false, false, false); +} + +bool frmQuery::isBeginNotRequired(wxString query) +{ + int wordlen = 0; + + query = query.Trim(false); + size_t queryLen = query.Len(); + + /* + * Check word length (since "beginx" is not "begin"). + */ + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + + /* + * Transaction control commands. These should include every keyword that + * gives rise to a TransactionStmt in the backend grammar, except for the + * savepoint-related commands. + * + * (We assume that START must be START TRANSACTION, since there is + * presently no other "START foo" command.) + */ + wxString keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 5 && keyword.CmpNoCase(wxT("abort")) == 0) + return true; + if (wordlen == 5 && keyword.CmpNoCase(wxT("begin")) == 0) + return true; + if (wordlen == 5 && keyword.CmpNoCase(wxT("start")) == 0) + return true; + if (wordlen == 6 && keyword.CmpNoCase(wxT("commit")) == 0) + return true; + if (wordlen == 3 && keyword.CmpNoCase(wxT("end")) == 0) + return true; + if (wordlen == 8 && keyword.CmpNoCase(wxT("rollback")) == 0) + return true; + if (wordlen == 7 && keyword.CmpNoCase(wxT("prepare")) == 0) + { + /* PREPARE TRANSACTION is a TC command, PREPARE foo is not */ + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 11 && keyword.CmpNoCase(wxT("transaction")) == 0) + return true; + return false; + } + + /* + * Commands not allowed within transactions. The statements checked for + * here should be exactly those that call PreventTransactionChain() in the + * backend. + */ + if (wordlen == 6 && keyword.CmpNoCase(wxT("vacuum")) == 0) + return true; + if (wordlen == 7 && keyword.CmpNoCase(wxT("cluster")) == 0) + { + /* CLUSTER with any arguments is allowed in transactions */ + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + + if(wxIsalpha(((wxChar)query.at(0)))) + return false; /* has additional words */ + return true; /* it's CLUSTER without arguments */ + } + + if (wordlen == 6 && keyword.CmpNoCase(wxT("create")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 8 && keyword.CmpNoCase(wxT("database")) == 0) + return true; + if (wordlen == 10 && keyword.CmpNoCase(wxT("tablespace")) == 0) + return true; + + /* CREATE [UNIQUE] INDEX CONCURRENTLY isn't allowed in xacts */ + if (wordlen == 6 && keyword.CmpNoCase(wxT("cluster")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + } + + if (wordlen == 5 && keyword.CmpNoCase(wxT("index")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 12 && keyword.CmpNoCase(wxT("concurrently")) == 0) + return true; + } + + return false; + } + + if (wordlen == 5 && keyword.CmpNoCase(wxT("alter")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + /* ALTER SYSTEM isn't allowed in xacts */ + if (wordlen == 6 && keyword.CmpNoCase(wxT("system")) == 0) + return true; + + return false; + } + + /* + * Note: these tests will match DROP SYSTEM and REINDEX TABLESPACE, which + * aren't really valid commands so we don't care much. The other four + * possible matches are correct. + */ + if ((wordlen == 4 && keyword.CmpNoCase(wxT("drop")) == 0) || + (wordlen == 7 && keyword.CmpNoCase(wxT("reindex")) == 0)) + { + query = query.SubString(wordlen , queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 8 && keyword.CmpNoCase(wxT("database")) == 0) + return true; + if (wordlen == 6 && keyword.CmpNoCase(wxT("system")) == 0) + return true; + if (wordlen == 10 && keyword.CmpNoCase(wxT("tablespace")) == 0) + return true; + return false; + } + + /* DISCARD ALL isn't allowed in xacts, but other variants are allowed. */ + if (wordlen == 7 && keyword.CmpNoCase(wxT("discard")) == 0) + { + query = query.SubString(wordlen, queryLen - 1); + query = query.Trim(false); + queryLen = query.Len(); + wordlen = 0; + + while((size_t)wordlen < queryLen && wxIsalpha(query.GetChar(wordlen))) + wordlen++; + keyword = query.SubString(0, wordlen - 1); + + if (wordlen == 3 && keyword.CmpNoCase(wxT("all")) == 0) + return true; + return false; + } + + return false; +} + +// When the query completes, it raises an event which we process here. +void frmQuery::OnQueryComplete(pgQueryResultEvent &ev) +{ + QueryExecInfo *qi = (QueryExecInfo *)ev.GetClientData(); + + bool done = false; + + while (sqlResult->RunStatus() == CTLSQL_RUNNING) + { + wxTheApp->Yield(true); + } + + while (pgScript->IsRunning()) + { + wxLogInfo(wxT("SQL Query box: Waiting for script to abort")); + wxSleep(1); + } + + timer.Stop(); + + wxString str; + str = sqlResult->GetMessagesAndClear(); + //if (!str.IsEmpty()) + //{ + // wxString msg; + // msgHistory->AppendText(str + wxT("\n")); + // wxRegEx multilf(wxT("(CONTEXT:.*$)")); + // multilf.ReplaceAll(&str, wxT("")); + // + //} + + msgResult->AppendText(str); + msgHistory->AppendText(str); + + elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery; + SetStatusText(ElapsedTimeToStr(elapsedQuery), STATUSPOS_SECS); + + if (sqlResult->RunStatus() != PGRES_TUPLES_OK) + { + outputPane->SetSelection(2); + if (sqlResult->RunStatus() == PGRES_COMMAND_OK) + { + done = true; + + int insertedCount = sqlResult->InsertedCount(); + OID insertedOid = sqlResult->InsertedOid(); + if (insertedCount < 0) + { + showMessage( + wxString::Format( + _("Query returned successfully with no result in %s."), + ElapsedTimeToStr(elapsedQuery).c_str() + ), + _("OK.") + ); + } + else if (insertedCount == 1) + { + if (insertedOid) + { + showMessage( + wxString::Format( + _("Query returned successfully: one row with OID %ld inserted, %s execution time."), + (long)insertedOid, + ElapsedTimeToStr(elapsedQuery).c_str()), + wxString::Format( + _("One row with OID %ld inserted."), + (long)insertedOid + ) + ); + } + else + { + showMessage( + wxString::Format( + _("Query returned successfully: one row affected, %s execution time."), + ElapsedTimeToStr(elapsedQuery).c_str()), + wxString::Format(_("One row affected.")) + ); + } + } + else + { + showMessage( + wxString::Format( + _("Query returned successfully: %d rows affected, %s execution time."), + insertedCount, + ElapsedTimeToStr(elapsedQuery).c_str() + ), + wxString::Format( + _("%d rows affected."), insertedCount + ) + ); + } + } + else if (sqlResult->RunStatus() == PGRES_EMPTY_QUERY) + { + showMessage(_("Empty query, no results.")); + } + else if (ev.GetInt() == pgQueryResultEvent::PGQ_EXECUTION_CANCELLED) + { + showMessage(_("Execution Cancelled!")); + } + else + { + wxString errMsg, errMsg2; + long errPos; + + pgError err = sqlResult->GetResultError(); + errMsg = err.formatted_msg; + wxLogQuietError(wxT("%s"), conn->GetLastError().Trim().c_str()); + err.statement_pos.ToLong(&errPos); + + if (err.sql_state.IsEmpty()) + { + if (wxMessageBox(_("Do you want to attempt to reconnect to the database?"), + wxString::Format(_("Connection to database %s lost."), conn->GetDbname().c_str()), + wxICON_EXCLAMATION | wxYES_NO) == wxYES) + { + conn->Reset(); + errMsg2 = _("Connection reset."); + } + } + + showMessage(wxString::Format(wxT("********** %s **********\n"), _("Error"))); + showMessage(errMsg); + if (!errMsg2.IsEmpty()) + showMessage(errMsg2); + + if (errPos > 0 && sqlQueryExec != NULL) + { + int selStart = sqlQueryExec->GetSelectionStart(), selEnd = sqlQueryExec->GetSelectionEnd(); + if (selStart == selEnd) + selStart = 0; + + errPos -= qi->queryOffset; // do not count EXPLAIN or similar + + // Set an indicator on the error word (break on any kind of bracket, a space or full stop) + int sPos = errPos + selStart - 1, wEnd = 1; + sqlQueryExec->StartStyling(sPos, wxSTC_INDICS_MASK); + int c = sqlQueryExec->GetCharAt(sPos + wEnd); + size_t len = sqlQueryExec->GetText().Length(); + while(c != ' ' && c != '(' && c != '{' && c != '[' && c != '.' && + (unsigned int)(sPos + wEnd) < len) + { + wEnd++; + c = sqlQueryExec->GetCharAt(sPos + wEnd); + } + sqlQueryExec->SetStyling(wEnd, wxSTC_INDIC0_MASK); + + int line = 0, maxLine = sqlQueryExec->GetLineCount(); + while (line < maxLine && sqlQueryExec->GetLineEndPosition(line) < errPos + selStart + 1) + line++; + if (line < maxLine) + { + sqlQueryExec->GotoPos(sPos); + // wxSTC_MARK_ARROW = 2 + sqlQueryExec->MarkerAdd(line, 0); // wxSTC_MARK_CIRCLE + + if (!sqlQueryExec->IsChanged()) + setExtendedTitle(); + + sqlQueryExec->EnsureVisible(line); + } + } + } + } + else + { + done = true; + for(int i=0;iGetPageCount();i++) + { + if (wxDynamicCast(outputPane->GetPage(i), ctlSQLResult)==sqlResult) { + outputPane->SetSelection(i); + } + } + + long rowsTotal = sqlResult->NumRows(); + + if (qi->toFileExportForm) + { + SetStatusText(wxString::Format(wxPLURAL("%d row.", "%d rows.", rowsTotal), rowsTotal), STATUSPOS_ROWS); + + if (rowsTotal) + { + SetStatusText(_("Writing data."), STATUSPOS_MSGS); + + toolBar->EnableTool(MNU_CANCEL, false); + queryMenu->Enable(MNU_CANCEL, false); + SetCursor(*wxHOURGLASS_CURSOR); + + if (sqlResult->ToFile(qi->toFileExportForm)) + SetStatusText(_("Data written to file."), STATUSPOS_MSGS); + else + SetStatusText(_("Data export aborted."), STATUSPOS_MSGS); + SetCursor(wxNullCursor); + } + else + SetStatusText(_("No data to export."), STATUSPOS_MSGS); + } + else + { + if (qi->singleResult) + { + sqlResult->DisplayData(true); + + showMessage(wxString::Format( + wxPLURAL("%ld row retrieved.", "%ld rows retrieved.", + sqlResult->NumRows()), sqlResult->NumRows()), + _("OK.")); + } + else + { + SetStatusText( + wxString::Format( + wxPLURAL( + "Retrieving data: %d row.", + "Retrieving data: %d rows.", + (int)rowsTotal), (int)rowsTotal), + STATUSPOS_MSGS); + wxTheApp->Yield(true); + + sqlResult->DisplayData(); + + SetStatusText( + ElapsedTimeToStr(elapsedQuery), + STATUSPOS_SECS + ); + + str = wxString::Format( + _("Total query runtime: %s\n"), + ElapsedTimeToStr(elapsedQuery).c_str() + ); + msgResult->AppendText(str); + msgHistory->AppendText(str); + + showMessage( + wxString::Format( + wxPLURAL( + "%d row retrieved.", + "%d rows retrieved.", + (int)sqlResult->NumRows() + ), + (int)sqlResult->NumRows() + ), + _("OK.") + ); + } + SetStatusText( + wxString::Format( + wxPLURAL( + "%ld row.", + "%ld rows.", + rowsTotal + ), + rowsTotal + ), + STATUSPOS_ROWS + ); + } + } + + if (sqlResult->RunStatus() == PGRES_TUPLES_OK || sqlResult->RunStatus() == PGRES_COMMAND_OK) + { + // Get the executed query + wxString executedQuery = sqlQueryExec->GetSelectedText(); + if (executedQuery.IsNull()) + executedQuery = sqlQueryExec->GetText(); + + // Same query, but without return feeds and carriage returns + wxString executedQueryWithoutReturns = executedQuery; + executedQueryWithoutReturns.Replace(wxT("\n"), wxT(" ")); + executedQueryWithoutReturns.Replace(wxT("\r"), wxT(" ")); + executedQueryWithoutReturns = executedQueryWithoutReturns.Trim(); + + if (executedQuery.Len() < (unsigned int)settings->GetHistoryMaxQuerySize()) + { + // We put in the combo box the query without returns... + sqlQueries->Append(executedQueryWithoutReturns); + + // .. but we save the query with returns in the array + // (so that we have the real query in the file) + histoQueries.Add(executedQuery); + + // Finally, we save the queries + SaveQueries(); + } + + // Search a matching old query + unsigned int index = 0; + bool found = false; + while (!found && index < sqlQueries->GetCount()) + { + found = sqlQueries->GetString(index) == executedQueryWithoutReturns; + if (!found) + index++; + } + + // If we found one, delete it from the combobox and the array + if (found && index < (unsigned int)sqlQueries->GetCount() - 1) + { + histoQueries.RemoveAt(index); + sqlQueries->Delete(index); + } + } + + // Make sure only the maximum query number is enforced + while (sqlQueries->GetCount() > (unsigned int)settings->GetHistoryMaxQueries()) + { + histoQueries.RemoveAt(0); + sqlQueries->Delete(0); + } + + SaveQueries(); + + completeQuery(done, qi->explain, qi->verbose); + delete qi; +} + + +void frmQuery::OnScriptComplete(wxCommandEvent &ev) +{ + // Stop timers + timer.Stop(); + pgsTimer->Stop(); + + // Write output + writeScriptOutput(); + + // Reset tools + setTools(false); + + // Unlock our pseudo-mutex thingy + frmQuery::ms_pgScriptRunning = false; + + // Manage timer + elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery; + wxString fmtExecTime = ElapsedTimeToStr(elapsedQuery); + SetStatusText(fmtExecTime, STATUSPOS_SECS); + SetStatusText(_("pgScript completed."), STATUSPOS_MSGS); + msgHistory->AppendText( + wxString::Format( + _("Total pgScript runtime: %s\n\n"), + fmtExecTime.c_str() + ) + ); + // Check whether there was an error/exception + if (pgScript->errorOccurred() && pgScript->errorLine() >= 1) + { + // Find out what the line number is + int selStart = sqlQuery->GetSelectionStart(), selEnd = sqlQuery->GetSelectionEnd(); + if (selStart == selEnd) + selStart = 0; + int line = 0, maxLine = sqlQuery->GetLineCount(); + while (line < maxLine && sqlQuery->GetLineEndPosition(line) < selStart) + line++; + line += pgScript->errorLine() - 1; + + // Mark the line where the error occurred + sqlQuery->MarkerAdd(line, 0); + + // Go to that line + sqlQuery->GotoPos(sqlQuery->GetLineEndPosition(line)); + } +} + +void frmQuery::writeScriptOutput() +{ + pgScript->LockOutput(); + + wxString output(pgsOutputString); + pgsOutputString.Clear(); + msgResult->AppendText(output); + + pgScript->UnlockOutput(); +} + +// Complete the processing of a query +void frmQuery::completeQuery(bool done, bool explain, bool verbose) +{ + // Display async notifications + pgNotification *notify; + int notifies = 0; + notify = conn->GetNotification(); + while (notify) + { + wxString notifyStr; + notifies++; + + if (notify->data.IsEmpty()) + notifyStr.Printf(_("\nAsynchronous notification of '%s' received from backend pid %d"), notify->name.c_str(), notify->pid); + else + notifyStr.Printf(_("\nAsynchronous notification of '%s' received from backend pid %d\n Data: %s"), notify->name.c_str(), notify->pid, notify->data.c_str()); + + msgResult->AppendText(notifyStr); + msgHistory->AppendText(notifyStr); + + notify = conn->GetNotification(); + } + + if (notifies) + { + wxString statusMsg = statusBar->GetStatusText(STATUSPOS_MSGS); + if (statusMsg.Last() == '.') + statusMsg = statusMsg.Left(statusMsg.Length() - 1); + + SetStatusText(wxString::Format( + wxPLURAL("%s (%d asynchronous notification received).", "%s (%d asynchronous notifications received).", notifies), + statusMsg.c_str(), notifies), STATUSPOS_MSGS); + } + + msgResult->AppendText(wxT("\n")); + msgResult->ShowPosition(0); + msgHistory->AppendText(wxT("\n")); + msgHistory->ShowPosition(0); + + // If the transaction aborted for some reason, issue a rollback to cleanup. + if (queryMenu->IsChecked(MNU_AUTOROLLBACK) && conn->GetTxStatus() == PGCONN_TXSTATUS_INERROR) + conn->ExecuteVoid(wxT("ROLLBACK;")); + + setTools(false); + fileMenu->Enable(MNU_EXPORT, sqlResult->CanExport()); + + if ((!IsActive() || IsIconized())|| (elapsedQuery>120*1000)) + RequestUserAttention(); + + if (!viewMenu->IsChecked(MNU_OUTPUTPANE)) + { + viewMenu->Check(MNU_OUTPUTPANE, true); + manager.GetPane(wxT("outputPane")).Show(true); + manager.Update(); + } + + // If this was an EXPLAIN query, process the results + if (done && explain) + { + if (!verbose || conn->BackendMinimumVersion(8, 4)) + { + int i; + wxString str; + if (sqlResult->NumRows() == 1) + { + // Avoid shared storage issues with strings + str.Append(sqlResult->OnGetItemText(0, 0).c_str()); + } + else + { + for (i = 0 ; i < sqlResult->NumRows() ; i++) + { + if (i) + str.Append(wxT("\n")); + str.Append(sqlResult->OnGetItemText(i, 0)); + } + } + explainCanvas->SetExplainString(str); + outputPane->SetSelection(1); + } + updateMenu(); + } + + // Change the output pane caption so the user knows which tab the result came from + sqlQueryExecLast = sqlQueryExec; + SetOutputPaneCaption(true); + for (int i=0;iGetPageCount();i++) + if ((sqlQueryBook->GetPageBitmap(i)).IsOk()) sqlQueryBook->SetPageBitmap(i,wxNullBitmap); + //int i=sqlQueryBook->GetPageCount()-1; + //sqlQueryBook->SetPageBitmap(i,CreateBitmap(wxNullColour)); + + //int i=sqlQueryBook->GetSelection() if (); + + + sqlQueryExec = NULL; + sqlQuery->SetFocus(); + +} + + +void frmQuery::OnTimer(wxTimerEvent &event) +{ + elapsedQuery = wxGetLocalTimeMillis() - startTimeQuery; + SetStatusText(ElapsedTimeToStr(elapsedQuery), STATUSPOS_SECS); + + wxString str = sqlResult->GetMessagesAndClear(); + if (!str.IsEmpty()) + { + // wxString msg; + // msgHistory->AppendText(str + wxT("\n")); + // wxRegEx multilf(wxT("(CONTEXT:.*$)")); + // multilf.ReplaceAll(&str, wxT("")); + // msgResult->AppendText(str + wxT("\n")); + // + msgHistory->AppendText(str + wxT("\n")); + msgResult->AppendText(str + wxT("\n")); + } + + // Increase the granularity for longer running queries + if (timer.IsRunning()) + { + // Set timer to fire every 100 ms if >200 ms elapsed + if (elapsedQuery > 200 && timer.GetInterval() < 100) + { + timer.Stop(); + timer.Start(100); + } + // Set timer to fire every 1000 ms if >60 seconds elapsed + else if (elapsedQuery > 60 * 1000 && timer.GetInterval() < 1000) + { + timer.Stop(); + timer.Start(1000); + } + } +} + + +// Adjust sizes of GQB components, Located here because need to +// avoid some issues when implementing inside controller/view Classes +void frmQuery::adjustGQBSizes() +{ + // Get Size (only height) from main Tab with GQB and SQL Editor and adjust the width + // to desiree, then set [Sash of tablesBrowser | GQB_Canvas] + manager.Update(); + sqlNotebook->Refresh(); + wxSize s = sqlNotebook->GetSize(); + s.SetWidth(200); + s.SetHeight(s.GetHeight() - 180); //re-adjust weight eliminating Horz Sash Position + controller->getTablesBrowser()->SetSize(s); + controller->setSashVertPosition(controller->getTablesBrowser()->GetSize().GetWidth()); + + // Now Adjust Sash Horizontal + s = sqlNotebook->GetSize(); + controller->setSashHorizPosition(s.GetHeight() - 150); + + // Adjust GQB grids internal columns sizes + controller->calcGridColsSizes(); +} + + +// Adjust sizes of GQB components after vertical sash adjustment, +// Located here because need to avoid some issues when implementing +// inside controller/view Classes +void frmQuery::OnResizeHorizontally(wxSplitterEvent &event) +{ + int y = event.GetSashPosition(); + wxSize s = controller->getTablesBrowser()->GetSize(); + s.SetHeight(y); // re-adjust weight eliminating Horz Sash Position + controller->getTablesBrowser()->SetSize(s); +} + + + +// This function adjust the GQB Components after an event on the wxAui +// event, it's a workaround because need event finish to work properly +void frmQuery::OnAdjustSizesTimer(wxTimerEvent &event) +{ + adjustGQBSizes(); + adjustSizesTimer->Stop(); +} + +void frmQuery::OnBlockIndent(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->CmdKeyExecute(wxSTC_CMD_TAB); + else if (FindFocus()->GetId() == CTL_SCRATCHPAD) + scratchPad->WriteText(wxT("\t")); +} + +void frmQuery::OnBlockOutDent(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->CmdKeyExecute(wxSTC_CMD_BACKTAB); +} + +void frmQuery::OnChangeToUpperCase(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->UpperCase(); +} + +void frmQuery::OnChangeToLowerCase(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->LowerCase(); +} + +void frmQuery::OnCommentText(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->BlockComment(false); +} + +void frmQuery::OnUncommentText(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + sqlQuery->BlockComment(true); +} + +void frmQuery::OnExternalFormat(wxCommandEvent &event) +{ + if (FindFocus()->GetId() == CTL_SQLQUERY) + { + wxBusyCursor wait; + SetStatusText(_("Running formatting command..."), STATUSPOS_MSGS); + SetStatusText(sqlQuery->ExternalFormat(), STATUSPOS_MSGS); + sqlQuery->SetFocus(); // could loose focus after running formatting process + } +} + +wxBitmap frmQuery::CreateBitmap(const wxColour &colour) +{ + const int w = 10, h = 10; + + wxMemoryDC dc; + wxBitmap bmp(w, h); + dc.SelectObject(bmp); + if (colour == wxNullColour) + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW))); + else + dc.SetBrush(wxBrush(colour)); + dc.DrawRectangle(0, 0, w, h); + + return bmp; +} + +wxColour frmQuery::GetServerColour(pgConn *connection) +{ + wxColour tmp = wxNullColour; + if (mainForm != NULL) + { + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server->GetConnected() && + server->GetConnection()->GetHost() == connection->GetHost() && + server->GetConnection()->GetPort() == connection->GetPort()) + { + tmp = wxColour(server->GetColour()); + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + } + return tmp; +} + +void frmQuery::LoadQueries() +{ + xmlDocPtr doc; + xmlNodePtr cur; + xmlChar *key; + + if (!wxFile::Access(settings->GetHistoryFile(), wxFile::read)) + return; + + doc = xmlParseFile((const char *)settings->GetHistoryFile().mb_str(wxConvUTF8)); + if (doc == NULL) + { + wxMessageBox(_("Failed to load the history file!")); + ::wxRemoveFile(settings->GetHistoryFile()); + return; + } + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) + { + xmlFreeDoc(doc); + return; + } + + if (xmlStrcmp(cur->name, (const xmlChar *) "histoqueries")) + { + wxMessageBox(_("Failed to load the history file!")); + xmlFreeDoc(doc); + ::wxRemoveFile(settings->GetHistoryFile()); + return; + } + + cur = cur->xmlChildrenNode; + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"histoquery"))) + { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + + if (key) + { + if (WXSTRING_FROM_XML(key) != wxT("")) + { + wxString query = WXSTRING_FROM_XML(key); + wxString tmp = query; + tmp.Replace(wxT("\n"), wxT(" ")); + tmp.Replace(wxT("\r"), wxT(" ")); + sqlQueries->Append(tmp); + histoQueries.Add(query); + } + xmlFree(key); + } + } + + cur = cur->next; + } + + xmlFreeDoc(doc); + + // Make sure only the maximum query number is enforced + if (sqlQueries->GetCount() > (unsigned int)settings->GetHistoryMaxQueries()) + { + while (sqlQueries->GetCount() > (unsigned int)settings->GetHistoryMaxQueries()) + { + histoQueries.RemoveAt(0); + sqlQueries->Delete(0); + } + SaveQueries(); + } + + return; +} + + +void frmQuery::SaveQueries() +{ + size_t i; + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetHistoryFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to write to history file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("histoqueries")) < 0)) + { + wxMessageBox(_("Failed to write to history file!")); + xmlFreeTextWriter(writer); + return; + } + + for (i = 0; i < histoQueries.GetCount(); i++) + { + xmlTextWriterStartElement(writer, XML_STR("histoquery")); + xmlTextWriterWriteString(writer, XML_FROM_WXSTRING(histoQueries.Item(i))); + xmlTextWriterEndElement(writer); + } + + if (xmlTextWriterEndDocument(writer) < 0) + { + wxMessageBox(_("Failed to write to history file!")); + } + + xmlFreeTextWriter(writer); +} + + +void frmQuery::OnChangeQuery(wxCommandEvent &event) +{ + wxString query = histoQueries.Item(sqlQueries->GetSelection()); + if (query.Length() > 0) + { + sqlQuery->SetText(query); + sqlQuery->Colourise(0, query.Length()); + wxSafeYield(); // needed to process sqlQuery modify event + sqlQuery->SetChanged(true); + sqlQuery->SetOrigin(ORIGIN_HISTORY); + setExtendedTitle(); + SetLineEndingStyle(); + btnDeleteCurrent->Enable(true); + } + btnDeleteAll->Enable(sqlQueries->GetCount() > 0); +} + + +void frmQuery::OnDeleteCurrent(wxCommandEvent &event) +{ + + if ( wxMessageDialog(this, + _("Delete current query from history?"), + _("Confirm deletion"), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION).ShowModal() == wxID_YES ) + { + histoQueries.RemoveAt(sqlQueries->GetSelection()); + sqlQueries->Delete(sqlQueries->GetSelection()); + sqlQueries->SetValue(wxT("")); + btnDeleteCurrent->Enable(false); + btnDeleteAll->Enable(sqlQueries->GetCount() > 0); + SaveQueries(); + } +} +void frmQuery::OnModeTransaction(wxCommandEvent &event) +{ + queryMenu->Check(MNU_AUTOCOMMIT, !queryMenu->IsChecked(MNU_AUTOCOMMIT)); + OnAutoCommit(event); +} +void frmQuery::OnDeleteAll(wxCommandEvent &event) +{ + + if ( wxMessageDialog(this, + _("Delete all queries from history?"), + _("Confirm deletion"), + wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION).ShowModal() == wxID_YES ) + { + histoQueries.Clear(); + sqlQueries->Clear(); + sqlQueries->SetValue(wxT("")); + btnDeleteCurrent->Enable(false); + btnDeleteAll->Enable(false); + SaveQueries(); + } +} + +void frmQuery::BeginPerspectiveChange() +{ + manager.GetPane(_("outputPane")).Caption(_("Output pane")); +} + +void frmQuery::EndPerspectiveChange(bool update) +{ + SetOutputPaneCaption(update); +} + +void frmQuery::SetOutputPaneCaption(bool update) +{ + wxString caption; + wxString title; + + if (sqlQueryExecLast == NULL) + caption = _("Output pane"); + else + { + // We don't want to make it look like Output Pane has been changed, + // so request the title without the change indicator + title = sqlQueryExecLast->GetTitle(false); + caption = wxString::Format(_("Output pane [%s]"), title.c_str()); + } + + manager.GetPane(wxT("outputPane")).Caption(caption); + + if (update) + manager.Update(); +} + +// Methods related to SQL tabs // + +void frmQuery::OnSqlBookPageChanged(wxAuiNotebookEvent &event) +{ + // Try to always keep sqlQuery variable pointing to the currently selected SQLBox. + // When closing and removing all tabs, page count may be zero. + if (sqlQueryBook->GetPageCount() > 0) + { + size_t curpage = sqlQueryBook->GetSelection(); + sqlQuery = wxDynamicCast(sqlQueryBook->GetPage(curpage), ctlSQLBox); + if (sqlQuery != NULL) + { + // Update UI with chosen query's info + SetEOLModeDisplay(sqlQuery->GetEOLMode()); + setExtendedTitle(); + curpage = outputPane->GetSelection(); + ctlSQLResult *r; + r=NULL; + if (wxDynamicCast(outputPane->GetPage(curpage), ctlSQLResult)) { + ctlSQLResult *r = wxDynamicCast(outputPane->GetPage(curpage), ctlSQLResult); + } + int pos=-1; + //if (r!=NULL) for (int i=0;iGetPageIndex(ctlSQL[i]); + + if (ctlSBox[i]==sqlQuery) { + outputPane->SetPageBitmap(idx,CreateBitmap(wxNullColour)); + pos=i; + } else + { + outputPane->SetPageBitmap(idx,wxNullBitmap); + } + } + } + + sqlQuery->SetFocus(); + //wxMessageBox(wxT("OnSqlBookPageChanged ")); + wxTheApp->Yield(true); + } + } + else + { + // This should help us find bugs (such as using sqlQuery after closing all tabs) much faster. + sqlQuery = NULL; + } +} + +void frmQuery::OnSqlBookPageChanging(wxAuiNotebookEvent &event) +{ + // Veto event while page change is prohibited. + if (!SqlBookCanChangePage()) + { + event.Veto(); + wxMessageBox(_("Cannot change to selected SQL tab now. Try again a bit later.")); + } +} + +void frmQuery::OnSqlBookAddPage(wxCommandEvent &event) +{ + if (SqlBookCanChangePage()) + SqlBookAddPage(); + else + wxMessageBox(_("Cannot add a new SQL tab now. Try again a bit later.")); +} +void frmQuery::OnSqlBookPageClosed(wxAuiNotebookEvent &event) +{ + //OnSqlBookPageChanged(event); + + //wxSleep(5); +// wxMessageBox(wxT("OnSqlBookPageClosed end")); +} + +void frmQuery::OnNotebookOutpaneTabRDown(wxAuiNotebookEvent &event) { +//ctlSQL + size_t curpage = outputPane->GetSelection(); + if ( event.GetSelection()!=curpage) return; + wxBitmap b=outputPane->GetPageBitmap(curpage); + if (b.IsOk()) { + if (sqlQuery!=NULL) { + wxString sql=sqlResult->sqlquerytext; + if (sql.StartsWith("EXPLAIN")) sql=sql.AfterFirst(')'); + if (sql.StartsWith("\nBEGIN;\nEXPLAIN")) { + sql=sql.AfterFirst(')'); + //"\n;\nROLLBACK;" + sql=sql.Mid(0,sql.Length()-12); + } + if (!sqlQuery->Find(sql,false,false,false,true,false,true)) { + wxString t=sqlQuery->GetText(); + if (t.Find(sql)>-1) { + SetStatusText("Found",1); + } + } + + } + } +} +void frmQuery::OnSqlBookTabRDown (wxAuiNotebookEvent &event) { + size_t curpage = sqlQueryBook->GetSelection(); + ctlSQLBox *sqlQuery = wxDynamicCast(sqlQueryBook->GetPage(curpage), ctlSQLBox); + wxString pref=conn->GetDbname()+wxT(".nametab"); + + wxTextEntryDialog dialog(this, + wxT("Please enter name string with prefix dbname\n") + , + wxT("Name autosave tab window."), + pref, + wxOK | wxCANCEL); //setName( dlg.GetValue().wc_str() ); + if (dialog.ShowModal() == wxID_OK) { + wxString tempDir=wxStandardPaths::Get().GetUserConfigDir()+wxT("\\postgresql\\recovery\\"); + wxString filename=sqlQuery->GetTitle(false); + wxRemoveFile(tempDir+filename+wxT(".a")); + wxString nt=dialog.GetValue(); + sqlQuery->SetTitle(nt); + SqlBookUpdatePageTitle(); + //sqlQueryBook->GetPage(curpage)-> + SaveTempFile(); + } + +} +void frmQuery::OnSqlBookPageClose(wxAuiNotebookEvent &event) +{ + // Don't allow removal of the last SQL box via user generated event + size_t pagecnt = sqlQueryBook->GetPageCount(); + if (pagecnt == 1) + { + event.Veto(); + wxMessageBox(_("Cannot remove the last SQL tab")); + return; + } + + // Prevent removing the page that is currently being executed + if (sqlQueryExec != NULL && sqlQueryExec == sqlQuery) + { + event.Veto(); + wxMessageBox(_("The query on this SQL tab is still running.\nWait for it to finish or cancel it before closing the tab.")); + return; + } + + if (CheckChanged(true)) + { + event.Veto(); + return; + } + + // If removing the tab for which results are displayed, reset the output pane's caption + if (sqlQuery == sqlQueryExecLast) + { + sqlQueryExecLast = NULL; + SetOutputPaneCaption(true); + } + + SqlBookDisconnectPage(); + //drop temp file + wxString tempDir=wxStandardPaths::Get().GetUserConfigDir()+wxT("\\postgresql\\recovery\\"); + wxString filename=sqlQuery->GetTitle(false)+wxT(".a"); + if (wxFileName::FileExists(tempDir+filename)) wxRemoveFile(tempDir+filename); + +} + +bool frmQuery::SqlBookCanChangePage() +{ + return !(m_loadingfile || ms_pgScriptRunning); +} + +void frmQuery::SqlBookAddPage() +{ + ctlSQLBox *box; + wxString caption; + bool bVal; + + // All SQL boxes use the same wxID, CTL_SQLQUERY. + // This should probably be changed, but it works for now and has minimal impact on existing code. + box = new ctlSQLBox(sqlQueryBook, CTL_SQLQUERY, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxSIMPLE_BORDER | wxTE_RICH2); + box->SetDatabase(conn); + box->SetMarginWidth(1, 16); + box->SetDropTarget(new DnDFile(this)); + box->SetChanged(false); + box->SetOrigin(ORIGIN_MANUAL); + box->SetQueryBook(sqlQueryBook); + bVal = editMenu->IsChecked(MNU_AUTOINDENT); + box->SetAutoIndent(bVal); + + bVal = viewMenu->IsChecked(MNU_WORDWRAP); + box->SetWrapMode(bVal ? wxSTC_WRAP_WORD : wxSTC_WRAP_NONE); + + bVal = viewMenu->IsChecked(MNU_SHOWINDENTGUIDES); + box->SetIndentationGuides(bVal); + + bVal = viewMenu->IsChecked(MNU_SHOWWHITESPACE); + box->SetViewWhiteSpace(bVal ? wxSTC_WS_VISIBLEALWAYS : wxSTC_WS_INVISIBLE); + + bVal = viewMenu->IsChecked(MNU_SHOWLINEENDS); + box->SetViewEOL(bVal ? 1 : 0); + + box->Connect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + box->Connect(wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + + sqlQueryCounter ++; + caption = wxString::Format(_("Query %i"), sqlQueryCounter); + box->SetTitle(caption); + sqlQueryBook->AddPage(box, caption, true); + + // Probably not needed, as the line above should trigger the PageChange event + sqlQuery = box; + sqlQuery->SetAutoReplaceList(autoreplace); + sqlQuery->SetDefFunction(name_func, def_func); +} + +void frmQuery::SqlBookDisconnectPage(ctlSQLBox *box) +{ + if (box == NULL) + box = sqlQuery; + + if (box != NULL) + { + box->Disconnect(wxID_ANY, wxEVT_SET_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + box->Disconnect(wxID_ANY, wxEVT_KILL_FOCUS, wxFocusEventHandler(frmQuery::OnFocus)); + for (int k=0;kGetPageCount() > 0) + { + // If removing the tab for which results are displayed, reset the output pane's caption + if (sqlQuery == sqlQueryExecLast) + { + sqlQueryExecLast = NULL; + SetOutputPaneCaption(true); + } + + SqlBookDisconnectPage(); + pageidx = sqlQueryBook->GetSelection(); + wxString tempDir=wxStandardPaths::Get().GetUserConfigDir()+wxT("\\postgresql\\recovery\\"); + ctlSQLBox *box; + box = wxDynamicCast(sqlQueryBook->GetPage(pageidx), ctlSQLBox); + wxString filename=box->GetTitle(false); + wxRemoveFile(tempDir+filename+wxT(".a")); + return sqlQueryBook->DeletePage(pageidx); + } + return false; +} + +void frmQuery::SqlBookSetAutoIndent(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetAutoIndent(b); + } +} + +void frmQuery::SqlBookSetWrapMode(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetWrapMode(b ? wxSTC_WRAP_WORD : wxSTC_WRAP_NONE); + } +} + +void frmQuery::SqlBookSetIndentGuides(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetIndentationGuides(b); + } +} + +void frmQuery::SqlBookSetViewWhiteSpace(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetViewWhiteSpace(b ? wxSTC_WS_VISIBLEALWAYS : wxSTC_WS_INVISIBLE); + } +} + +void frmQuery::SqlBookSetViewEOL(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetViewEOL(b ? 1 : 0); + } +} + +void frmQuery::SqlBookSetViewLineNumbers(bool b) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->UpdateLineNumber(); + } +} + +void frmQuery::SqlBookSetDatabase(pgConn *con) +{ + size_t i, cnt; + ctlSQLBox *box; + + for (i = 0, cnt = sqlQueryBook->GetPageCount(); i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + box->SetDatabase(con); + } +} + +void frmQuery::SqlBookUpdatePageTitle() +{ + size_t index; + wxString title; + + if (sqlQueryBook->GetPageCount() > 0 && sqlQuery != NULL) + { + index = sqlQueryBook->GetPageIndex(sqlQuery); + if (index == wxNOT_FOUND) + return; + + title = sqlQuery->GetTitle(); + if (sqlQueryBook->GetPageText(index) != title) + sqlQueryBook->SetPageText(index, title); + } +} + +// Returns true if any SQL tab attempts to veto the closing, false otherwise. +bool frmQuery::SqlBookClose(bool canVeto) +{ + size_t i = 0; + size_t cnt = sqlQueryBook->GetPageCount(); + ctlSQLBox *box; + + // See if we have any unsaved changes and prompt to save them + for (i = 0; i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL && box->IsChanged()) + { + sqlQueryBook->SetSelection(i); + if (CheckChanged(canVeto)) + return true; + } + } + + // If we got here, the window will be closed + for (i = 0; i < cnt; ++i) + { + box = wxDynamicCast(sqlQueryBook->GetPage(i), ctlSQLBox); + if (box != NULL) + SqlBookDisconnectPage(box); + } + + return false; +} + + +/////////////////////////////////////////////////////// + +wxWindow *queryToolBaseFactory::StartDialogSql(frmMain *form, pgObject *obj, const wxString &sql) +{ + pgDatabase *db = obj->GetDatabase(); + wxString usr=wxEmptyString; + wxGetEnv(wxT("USERNAME"),&usr); + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - query ")+usr; + pgConn *conn = db->CreateConn(applicationname); + if (conn) + { + frmQuery *fq = new frmQuery(form, obj->GetDisplayName(), conn, sql); + fq->Go(); + return fq; + } + return 0; +} + + +bool queryToolBaseFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected(); +} + + +bool queryToolDataFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() && + (obj->IsCreatedBy(tableFactory) || obj->IsCreatedBy(pg_partitionFactory) || obj->IsCreatedBy(viewFactory)); +} + + +queryToolFactory::queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolBaseFactory(list) +{ + mnu->Append(id, _("&Query tool\tCtrl-E"), _("Execute arbitrary SQL queries.")); + toolbar->AddTool(id, wxEmptyString, *sql_32_png_bmp, _("Execute arbitrary SQL queries."), wxITEM_NORMAL); +} + + +wxWindow *queryToolFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString qry; + if (settings->GetStickySql()) + qry = obj->GetSql(form->GetBrowser()); + return StartDialogSql(form, obj, qry); +} + + +queryToolSqlFactory::queryToolSqlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolBaseFactory(list) +{ + mnu->Append(id, _("CREATE Script"), _("Start Query tool with CREATE script.")); + if (toolbar) + toolbar->AddTool(id, wxEmptyString, *sql_32_png_bmp, _("Start query tool with CREATE script."), wxITEM_NORMAL); +} + + +wxWindow *queryToolSqlFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return StartDialogSql(form, obj, obj->GetSql(form->GetBrowser())); +} + + +bool queryToolSqlFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && obj->CanCreate() && !obj->IsCollection(); +} + + +queryToolSelectFactory::queryToolSelectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("SELECT Script"), _("Start query tool with SELECT script.")); +} + +bool queryToolSelectFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() && + (obj->IsCreatedBy(tableFactory) || obj->IsCreatedBy(foreignTableFactory) || obj->IsCreatedBy(viewFactory) || obj->IsCreatedBy(functionFactory) || obj->IsCreatedBy(pg_partitionFactory)); +} + +wxWindow *queryToolSelectFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)||(obj->IsCreatedBy(pg_partitionFactory))) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(extTableFactory)) + { + gpExtTable *exttable = (gpExtTable *)obj; + return StartDialogSql(form, obj, exttable->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(functionFactory)) + { + pgFunction *function = (pgFunction *)obj; + return StartDialogSql(form, obj, function->GetSelectSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(foreignTableFactory)) + { + pgForeignTable *foreigntable = (pgForeignTable *)obj; + return StartDialogSql(form, obj, foreigntable->GetSelectSql(form->GetBrowser())); + } + return 0; +} + +queryToolExecFactory::queryToolExecFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("EXEC Script"), _("Start query tool with EXEC script.")); +} + +bool queryToolExecFactory::CheckEnable(pgObject *obj) +{ + return queryToolBaseFactory::CheckEnable(obj) && !obj->IsCollection() && obj->IsCreatedBy(procedureFactory); +} + +wxWindow *queryToolExecFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(procedureFactory)) + { + pgProcedure *procedure = (pgProcedure *)obj; + return StartDialogSql(form, obj, procedure->GetExecSql(form->GetBrowser())); + } + return 0; +} + +queryToolDeleteFactory::queryToolDeleteFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("DELETE Script"), _("Start query tool with DELETE script.")); +} + + +bool queryToolDeleteFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + return false; +} + + +wxWindow *queryToolDeleteFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetDeleteSql(form->GetBrowser())); + } + return 0; +} + + +queryToolCreateCascadeFactory::queryToolCreateCascadeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("Script Recreate Cascade"), _("Start query tool with recreate cascade script.")); +} + +//wxArrayString queryToolCreateCascadeFactory::GetArrayList(wxString *strobj) +//{ +// wxString *databasePath=new wxString(strobj); +// pgSet *set; +// set = connection->ExecuteSet( +// wxT("SELECT relname FROM pg_class, pg_index WHERE pg_class.oid=indexrelid AND indrelid=") + table->GetOidStr()); +// if (set) +// { +// while (!set->Eof()) +// { +// cbIndex->Append(set->GetVal(0)); +// set->MoveNext(); +// } +// delete set; +// } +// +// wxStringTokenizer tkz(databasePath, wxT("/")); +// while(tkz.HasMoreTokens()) +// { +// wxString token = tkz.GetNextToken(); +// if(token == _("Databases")) +// break; +// //ItemPath += token + wxT("/"); +// } +// +// return 0; +//} +wxWindow *queryToolCreateCascadeFactory::StartDialog(frmMain *form, pgObject *obj) +{ + + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetSqlReCreate(form,obj)); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetSqlReCreate(form,obj)); + } + + return 0; +} + + +bool queryToolCreateCascadeFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + pgView *view = (pgView *)obj; + + return true; +} + +queryToolUpdateFactory::queryToolUpdateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("UPDATE Script"), _("Start query tool with UPDATE script.")); +} + + +wxWindow *queryToolUpdateFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetUpdateSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetUpdateSql(form->GetBrowser())); + } + + return 0; +} + + +bool queryToolUpdateFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + pgView *view = (pgView *)obj; + + return view->HasUpdateRule(); +} + + +queryToolInsertFactory::queryToolInsertFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : queryToolDataFactory(list) +{ + mnu->Append(id, _("INSERT Script"), _("Start query tool with INSERT script.")); +} + + +wxWindow *queryToolInsertFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + { + pgTable *table = (pgTable *)obj; + return StartDialogSql(form, obj, table->GetInsertSql(form->GetBrowser())); + } + else if (obj->IsCreatedBy(viewFactory)) + { + pgView *view = (pgView *)obj; + return StartDialogSql(form, obj, view->GetInsertSql(form->GetBrowser())); + } + return 0; +} + +bool queryToolInsertFactory::CheckEnable(pgObject *obj) +{ + if (!queryToolDataFactory::CheckEnable(obj)) + return false; + if (obj->IsCreatedBy(tableFactory)||obj->IsCreatedBy(pg_partitionFactory)) + return true; + pgView *view = (pgView *)obj; + + return view->HasInsertRule(); +} + +void frmQuery::SaveExplainAsImage(wxCommandEvent &ev) +{ + wxFileDialog *dlg = new wxFileDialog(this, _("Save Explain As image file"), lastDir, lastFilename, + wxT("Bitmap files (*.bmp)|*.bmp|JPEG files (*.jpeg)|*.jpeg|PNG files (*.png)|*.png"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); + if (dlg->ShowModal() == wxID_OK) + { + lastFilename = dlg->GetFilename(); + lastDir = dlg->GetDirectory(); + lastPath = dlg->GetPath(); + int index = dlg->GetFilterIndex(); + + wxString strType; + wxBitmapType imgType; + switch (index) + { + // bmp + case 0: + strType = wxT(".bmp"); + imgType = wxBITMAP_TYPE_BMP; + break; + // jpeg + case 1: + strType = wxT(".jpeg"); + imgType = wxBITMAP_TYPE_JPEG; + break; + // default (png) + default: + // png + case 2: + strType = wxT(".png"); + imgType = wxBITMAP_TYPE_PNG; + break; + } + + if (!lastPath.Contains(wxT("."))) + lastPath += strType; + + if (ev.GetId() == MNU_SAVEAS_IMAGE_GQB) + controller->getView()->SaveAsImage(lastPath, imgType); + else if (ev.GetId() == MNU_SAVEAS_IMAGE_EXPLAIN) + explainCanvas->SaveAsImage(lastPath, imgType); + } +} + +/////////////////////////////////////////////////////// + +pgScriptTimer::pgScriptTimer(frmQuery *parent) : + m_parent(parent) +{ + +} + +void pgScriptTimer::Notify() +{ + // Write script output + m_parent->writeScriptOutput(); +} + diff --git a/frm/frmReport.cpp b/frm/frmReport.cpp new file mode 100644 index 0000000..01a97b4 --- /dev/null +++ b/frm/frmReport.cpp @@ -0,0 +1,2290 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmReport.cpp - The report file dialogue +// +////////////////////////////////////////////////////////////////////////// + + + +// App headers +#include "pgAdmin3.h" +#include + +#include "frm/frmMain.h" +#include "frm/frmReport.h" +#include "utils/sysSettings.h" +#include "utils/misc.h" +#include "ctl/ctlListView.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgServer.h" +#include "schema/pgDatabase.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgConstraints.h" +#include "agent/pgaJob.h" +#include "schema/pgForeignKey.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgCheck.h" +#include "utils/utffile.h" +#include + +// XML2/XSLT headers +#include +#include + +#define txtTitle CTRL_TEXT("txtTitle") +#define txtNotes CTRL_TEXT("txtNotes") +#define txtHtmlFile CTRL_TEXT("txtHtmlFile") +#define txtXmlFile CTRL_TEXT("txtXmlFile") +#define txtHtmlStylesheet CTRL_TEXT("txtHtmlStylesheet") +#define txtXmlStylesheet CTRL_TEXT("txtXmlStylesheet") +#define btnOK CTRL_BUTTON("wxID_OK") +#define btnFile CTRL_BUTTON("btnFile") +#define btnStylesheet CTRL_BUTTON("btnStylesheet") +#define rbHtml CTRL_RADIOBUTTON("rbHtml") +#define rbXml CTRL_RADIOBUTTON("rbXml") +#define rbHtmlBuiltin CTRL_RADIOBUTTON("rbHtmlBuiltin") +#define rbHtmlEmbed CTRL_RADIOBUTTON("rbHtmlEmbed") +#define rbHtmlLink CTRL_RADIOBUTTON("rbHtmlLink") +#define rbXmlPlain CTRL_RADIOBUTTON("rbXmlPlain") +#define rbXmlLink CTRL_RADIOBUTTON("rbXmlLink") +#define rbXmlProcess CTRL_RADIOBUTTON("rbXmlProcess") +#define chkSql CTRL_CHECKBOX("chkSql") +#define chkBrowser CTRL_CHECKBOX("chkBrowser") + +BEGIN_EVENT_TABLE(frmReport, pgDialog) + EVT_RADIOBUTTON(XRCID("rbHtml"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXml"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbHtmlBuiltin"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbHtmlEmbed"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbHtmlLink"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXmlPlain"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXmlLink"), frmReport::OnChange) + EVT_RADIOBUTTON(XRCID("rbXmlProcess"), frmReport::OnChange) + EVT_TEXT(XRCID("txtHtmlFile"), frmReport::OnChange) + EVT_TEXT(XRCID("txtXmlFile"), frmReport::OnChange) + EVT_TEXT(XRCID("txtHtmlStylesheet"), frmReport::OnChange) + EVT_TEXT(XRCID("txtXmlStylesheet"), frmReport::OnChange) + EVT_BUTTON(XRCID("btnFile"), frmReport::OnBrowseFile) + EVT_BUTTON(XRCID("btnStylesheet"), frmReport::OnBrowseStylesheet) + EVT_BUTTON(wxID_HELP, frmReport::OnHelp) + EVT_BUTTON(wxID_OK, frmReport::OnOK) + EVT_BUTTON(wxID_CANCEL, frmReport::OnCancel) +END_EVENT_TABLE() + +frmReport::frmReport(wxWindow *p) +{ + parent = p; + header = wxT(""); + + SetFont(settings->GetSystemFont()); + LoadResource(p, wxT("frmReport")); + + // Icon + appearanceFactory->SetIcons(this); + RestorePosition(); + btnOK->Disable(); + + wxString val; + bool bVal; + + // Output format + settings->Read(wxT("Reports/ReportFormat"), &val, wxT("h")); + if (val == wxT("x")) + { + rbHtml->SetValue(false); + rbXml->SetValue(true); + } + else + { + rbHtml->SetValue(true); + rbXml->SetValue(false); + } + + // HTML Stylesheet + settings->Read(wxT("Reports/HtmlStylesheetMode"), &val, wxT("b")); + if (val == wxT("e")) + { + rbHtmlBuiltin->SetValue(false); + rbHtmlEmbed->SetValue(true); + rbHtmlLink->SetValue(false); + } + else if (val == wxT("l")) + { + rbHtmlBuiltin->SetValue(false); + rbHtmlEmbed->SetValue(false); + rbHtmlLink->SetValue(true); + } + else + { + rbHtmlBuiltin->SetValue(true); + rbHtmlEmbed->SetValue(false); + rbHtmlLink->SetValue(false); + } + + // XML Stylesheet + settings->Read(wxT("Reports/XmlStylesheetMode"), &val, wxT("p")); + if (val == wxT("l")) + { + rbXmlPlain->SetValue(false); + rbXmlLink->SetValue(true); + rbXmlProcess->SetValue(false); + } + else if (val == wxT("r")) + { + rbXmlPlain->SetValue(false); + rbXmlLink->SetValue(false); + rbXmlProcess->SetValue(true); + } + else + { + rbXmlPlain->SetValue(true); + rbXmlLink->SetValue(false); + rbXmlProcess->SetValue(false); + } + + // Default values + settings->Read(wxT("Reports/LastNotes"), &val, wxT("")); + txtNotes->SetValue(val); + + settings->Read(wxT("Reports/LastHtmlStylesheet"), &val, wxEmptyString); + txtHtmlStylesheet->SetValue(val); + + settings->Read(wxT("Reports/LastXmlStylesheet"), &val, wxEmptyString); + txtXmlStylesheet->SetValue(val); + + settings->Read(wxT("Reports/LastHtmlFile"), &val, wxEmptyString); + txtHtmlFile->SetValue(val); + + settings->Read(wxT("Reports/LastXmlFile"), &val, wxEmptyString); + txtXmlFile->SetValue(val); + + settings->Read(wxT("Reports/IncludeSQL"), &bVal, true); + chkSql->SetValue(bVal); + chkSql->Disable(); + + settings->Read(wxT("Reports/OpenInBrowser"), &bVal, true); + chkBrowser->SetValue(bVal); + + wxCommandEvent ev; + OnChange(ev); + + txtTitle->SetFocus(); +} + + +frmReport::~frmReport() +{ + SavePosition(); +} + + +void frmReport::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("reports"), HELP_PGADMIN); +} + + +void frmReport::OnChange(wxCommandEvent &ev) +{ + bool enable = true; + + if (rbHtml->GetValue()) + { + // Show/hide the appropriate controls + rbHtmlBuiltin->Show(true); + rbHtmlEmbed->Show(true); + rbHtmlLink->Show(true); + txtHtmlStylesheet->Show(true); + txtHtmlFile->Show(true); + + rbXmlPlain->Show(false); + rbXmlLink->Show(false); + rbXmlProcess->Show(false); + txtXmlStylesheet->Show(false); + txtXmlFile->Show(false); + + // Enable/disable as appropriate + if (txtHtmlFile->GetValue().IsEmpty()) + enable = false; + + if (rbHtmlBuiltin->GetValue()) + { + txtHtmlStylesheet->Disable(); + btnStylesheet->Disable(); + } + else + { + txtHtmlStylesheet->Enable(); + btnStylesheet->Enable(); + } + + if (rbHtmlEmbed->GetValue()) + { + if (!wxFile::Exists(txtHtmlStylesheet->GetValue())) + enable = false; + } + } + else + { + // Show/hide the appropriate controls + rbHtmlBuiltin->Show(false); + rbHtmlEmbed->Show(false); + rbHtmlLink->Show(false); + txtHtmlStylesheet->Show(false); + txtHtmlFile->Show(false); + + rbXmlPlain->Show(true); + rbXmlLink->Show(true); + rbXmlProcess->Show(true); + txtXmlStylesheet->Show(true); + txtXmlFile->Show(true); + + // Enable/disable as appropriate + if (txtXmlFile->GetValue().IsEmpty()) + enable = false; + + if (rbXmlPlain->GetValue()) + { + txtXmlStylesheet->Disable(); + btnStylesheet->Disable(); + } + else + { + txtXmlStylesheet->Enable(); + btnStylesheet->Enable(); + } + + if (rbXmlProcess->GetValue()) + { + if (!wxFile::Exists(txtXmlStylesheet->GetValue())) + enable = false; + } + } + + btnOK->Enable(enable); +} + + +void frmReport::OnOK(wxCommandEvent &ev) +{ + wxString filename; + if (rbHtml->GetValue()) + filename = txtHtmlFile->GetValue(); + else + filename = txtXmlFile->GetValue(); + + wxFileName fn(filename); + fn.MakeAbsolute(); + + // Check if the file exsits, and if so, whether to overwrite it + if (wxFileExists(fn.GetFullPath())) + { + wxString msg; + msg.Printf(_("The file: \n\n%s\n\nalready exists. Do you want to overwrite it?"), fn.GetFullPath().c_str()); + + if (wxMessageBox(msg, _("Overwrite file?"), wxYES_NO | wxICON_QUESTION) != wxYES) + { + if (rbHtml->GetValue()) + txtHtmlFile->SetFocus(); + else + txtXmlFile->SetFocus(); + return; + } + } + + // Yield, to allow the messagebox to go + wxTheApp->Yield(true); + + // Add the title, notes and SQL + if (txtTitle->GetValue() != wxT("")) + XmlAddHeaderValue(wxT("title"), txtTitle->GetValue()); + + if (txtNotes->GetValue() != wxT("")) + XmlAddHeaderValue(wxT("notes"), txtNotes->GetValue()); + + // Generate the report data + wxString report; + + if (rbHtml->GetValue()) + { + if (rbHtmlBuiltin->GetValue()) + { + wxString xml = GetXmlReport(wxEmptyString); + wxString xsl = GetDefaultXsl(GetEmbeddedCss(GetDefaultCss())); + report = XslProcessReport(xml, xsl); + } + else if (rbHtmlEmbed->GetValue()) + { + wxString xml = GetXmlReport(wxEmptyString); + wxString css = FileRead(txtHtmlStylesheet->GetValue()); + if (css.IsEmpty()) + { + wxLogError(_("No stylesheet data could be read from the file %s: Errcode=%d."), txtHtmlStylesheet->GetValue().c_str(), wxSysErrorCode()); + return; + } + wxString xsl = GetDefaultXsl(GetEmbeddedCss(css)); + report = XslProcessReport(xml, xsl); + } + else + { + wxString xml = GetXmlReport(wxEmptyString); + wxString xsl = GetDefaultXsl(GetCssLink(txtHtmlStylesheet->GetValue())); + report = XslProcessReport(xml, xsl); + } + } + else + { + if (rbXmlPlain->GetValue()) + { + report = GetXmlReport(wxEmptyString); + } + else if (rbXmlLink->GetValue()) + { + report = GetXmlReport(txtXmlStylesheet->GetValue()); + } + else + { + wxString xml = GetXmlReport(wxEmptyString); + wxString xsl = FileRead(txtXmlStylesheet->GetValue()); + if (xsl.IsEmpty()) + { + wxLogError(_("No stylesheet data could be read from the file %s: Errcode=%d."), txtXmlStylesheet->GetValue().c_str(), wxSysErrorCode()); + return; + } + report = XslProcessReport(xml, xsl); + } + } + + // If report is empty, an error must have occurred + if (report.IsEmpty()) + return; + + // Save it to disk + wxFile file(fn.GetFullPath(), wxFile::write); + if (!file.IsOpened()) + { + wxLogError(_("Failed to open file %s."), fn.GetFullPath().c_str()); + return; + } + file.Write(report, wxConvUTF8); + file.Close(); + + // Open the file in the default browser if required + if (chkBrowser->GetValue()) +#ifdef __WXMSW__ + wxLaunchDefaultBrowser(fn.GetFullPath()); +#else + wxLaunchDefaultBrowser(wxT("file://") + fn.GetFullPath()); +#endif + + // Save the settings for next time round + settings->Write(wxT("Reports/LastNotes"), txtNotes->GetValue()); + + if (rbHtml->GetValue()) + settings->Write(wxT("Reports/ReportFormat"), wxT("h")); + else + settings->Write(wxT("Reports/ReportFormat"), wxT("x")); + + if (rbHtmlBuiltin->GetValue()) + settings->Write(wxT("Reports/HtmlStylesheetMode"), wxT("b")); + else if (rbHtmlEmbed->GetValue()) + settings->Write(wxT("Reports/HtmlStylesheetMode"), wxT("e")); + else + settings->Write(wxT("Reports/HtmlStylesheetMode"), wxT("l")); + + if (rbXmlPlain->GetValue()) + settings->Write(wxT("Reports/XmlStylesheetMode"), wxT("p")); + else if (rbXmlLink->GetValue()) + settings->Write(wxT("Reports/XmlStylesheetMode"), wxT("l")); + else + settings->Write(wxT("Reports/XmlStylesheetMode"), wxT("r")); + + settings->Write(wxT("Reports/LastHtmlStylesheet"), txtHtmlStylesheet->GetValue()); + settings->Write(wxT("Reports/LastXmlStylesheet"), txtXmlStylesheet->GetValue()); + + + settings->Write(wxT("Reports/LastHtmlFile"), txtHtmlFile->GetValue()); + settings->Write(wxT("Reports/LastXmlFile"), txtXmlFile->GetValue()); + + settings->WriteBool(wxT("Reports/IncludeSQL"), chkSql->GetValue()); + + settings->WriteBool(wxT("Reports/OpenInBrowser"), chkBrowser->GetValue()); + + // Now go away + if (IsModal()) + EndModal(wxID_OK); + else + Destroy(); +} + +void frmReport::OnCancel(wxCommandEvent &ev) +{ + if (IsModal()) + EndModal(wxID_CANCEL); + else + Destroy(); +} + +void frmReport::OnBrowseStylesheet(wxCommandEvent &ev) +{ + if (rbHtml->GetValue()) + { + wxString def = txtHtmlStylesheet->GetValue(); + + if (!wxFile::Exists(def)) + def.Empty(); + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("HTML Stylesheet files (*.css)|*.css|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("HTML Stylesheet files (*.css)|*.css|All files (*)|*"), wxFD_OPEN); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtHtmlStylesheet->SetValue(file.GetPath()); + OnChange(ev); + } + } + else + { + wxString def = txtXmlStylesheet->GetValue(); + + if (!wxFile::Exists(def)) + def.Empty(); + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("XML Stylesheet files (*.xsl)|*.xsl|All files (*.*)|*.*"), wxFD_OPEN); +#else + wxFileDialog file(this, _("Select stylesheet filename"), wxGetHomeDir(), def, _("XML Stylesheet files (*.xsl)|*.xsl|All files (*)|*"), wxFD_OPEN); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtXmlStylesheet->SetValue(file.GetPath()); + OnChange(ev); + } + } +} + +void frmReport::OnBrowseFile(wxCommandEvent &ev) +{ + if (rbHtml->GetValue()) + { +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtHtmlFile->GetValue(), + _("HTML files (*.html)|*.html|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtHtmlFile->GetValue(), + _("HTML files (*.html)|*.html|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtHtmlFile->SetValue(file.GetPath()); + OnChange(ev); + } + } + else + { +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtXmlFile->GetValue(), + _("XML files (*.xml)|*.xml|All files (*.*)|*.*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#else + wxFileDialog file(this, _("Select output filename"), wxGetHomeDir(), txtXmlFile->GetValue(), + _("XML files (*.xml)|*.xml|All files (*)|*"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtXmlFile->SetValue(file.GetPath()); + OnChange(ev); + } + } +} + +void frmReport::SetReportTitle(const wxString &t) +{ + txtTitle->SetValue(t); +} + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// START STYLESHEET FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +wxString frmReport::GetCssLink(const wxString &file) +{ + wxString data; + + data = wxT(" \n"); + + return data; +} + +wxString frmReport::GetEmbeddedCss(const wxString &css) +{ + wxString data; + + data = wxT(" \n"); + + return data; +} + +const wxString frmReport::GetDefaultCss() +{ + wxString data; + + data = wxT(" body { font-family: verdana, helvetica, sans-serif; margin: 0px; padding: 0; }\n") + wxT(" h1 { font-weight: bold; font-size: 150%; border-bottom-style: solid; border-bottom-width: 2px; margin-top: 0px; padding-bottom: 0.5ex; color: #eeeeee; overflow: hidden; text-overflow: ellipsis; }\n") + wxT(" h2 { font-size: 130%; padding-bottom: 0.5ex; color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; border-bottom-style: solid; border-bottom-width: 2px; }\n") + wxT(" h3 { font-size: 110%; padding-bottom: 0.5ex; color: #000000; }\n") + wxT(" th { text-align: left; background-color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; color: #eeeeee; }\n") + wxT(" #ReportHeader { padding: 10px; background-color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; color: #eeeeee; border-bottom-style: solid; border-bottom-width: 2px; border-color: #999999; }\n") + wxT(" #ReportHeader th { width: 25%; white-space: nowrap; vertical-align: top; }\n") + wxT(" #ReportHeader td { vertical-align: top; color: #eeeeee; }\n") + wxT(" #ReportNotes { padding: 10px; background-color: #eeeeee; font-size: 80%; border-bottom-style: solid; border-bottom-width: 2px; border-color: #999999; }\n") + wxT(" .ReportSQL { margin-bottom: 10px; padding: 10px; display: block; background-color: #eeeeee; font-family: monospace; }\n") + wxT(" #ReportDetails { margin-left: 10px; margin-right: 10px; margin-bottom: 10px; }\n") + wxT(" #ReportDetails td, th { font-size: 80%; margin-left: 2px; margin-right: 2px; }\n") + wxT(" #ReportDetails th { border-bottom-color: #777777; border-bottom-style: solid; border-bottom-width: 2px; }\n") + wxT(" .ReportDetailsOddDataRow { background-color: #dddddd; }\n") + wxT(" .ReportDetailsEvenDataRow { background-color: #eeeeee; }\n") + wxT(" .ReportTableHeaderCell { background-color: #dddddd; color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; vertical-align: top; font-size: 80%; white-space: nowrap; }\n") + wxT(" .ReportTableValueCell { vertical-align: top; font-size: 80%; white-space: nowrap; }\n") + wxT(" .ReportTableInfo { font-size: 80%; font-style: italic; }\n") + wxT(" #ReportFooter { font-weight: bold; font-size: 80%; text-align: right; background-color: ") + appearanceFactory->GetReportKeyColour().GetAsString(wxC2S_HTML_SYNTAX) + wxT("; color: #eeeeee; margin-top: 10px; padding: 2px; border-bottom-style: solid; border-bottom-width: 2px; border-top-style: solid; border-top-width: 2px; border-color: #999999; }\n") + wxT(" #ReportFooter a { color: #ffffff; text-decoration: none; }\n"); + + return data; +} + +wxString frmReport::GetDefaultXsl(const wxString &css) +{ + wxString data; + + data = wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" <xsl:value-of select=\"header/title\" />\n") + wxT(" \n") + wxT(" \n"); + data += css; + data += wxT(" \n") + wxT("\n") + wxT(" \n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT("

\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Generated"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Server"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Database"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Catalog"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Schema"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Table"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT(" "); + data += _("Job"); + data += wxT(":
\n") + wxT("
\n") + wxT("\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT("
\n") + wxT(" "); + data += _("Notes"); + data += wxT(":

\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
\n") + wxT("
\n") + wxT("\n") + wxT("
\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT("\n") + wxT("
\n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("
\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT("

\n") + wxT("
\n") + wxT("\n") + wxT(" 0\">\n") + wxT("
\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
\n") + wxT("
\n") + wxT("
\n") + wxT(" \n") + wxT("

\n") + wxT("
\n") + wxT("
\n") + wxT("\n") + wxT(" \n") + wxT("
\n")
+	        wxT("      \n")
+	        wxT("         \n")
+	        wxT("      \n")
+	        wxT("    
\n") + wxT("
\n") + wxT("
\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" %\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" ReportDetailsOddDataRow\n") + wxT(" \n") + wxT(" \n") + wxT(" ReportDetailsEvenDataRow\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("\n") + wxT("\n") + wxT("\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
\n") + wxT("
\n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT(" \n") + wxT("
\n") + wxT("\n") + wxT("
\n"); + + return data; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// END STYLESHEET FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// START XML FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void frmReport::XmlAddHeaderValue(const wxString &name, const wxString &value) +{ + header += wxT(" <") + HtmlEntities(name) + wxT(">") + HtmlEntities(value) + wxT("\n"); +} + +int frmReport::XmlCreateSection(const wxString &name) +{ + int ind = sectionName.Add(HtmlEntities(name)); + sectionData.Add(wxT("")); + sectionTableHeader.Add(wxT("")); + sectionTableRows.Add(wxT("")); + sectionTableInfo.Add(wxT("")); + sectionSql.Add(wxT("")); + return ind + 1; +} + +void frmReport::XmlSetSectionTableHeader(const int section, int columns, const wxChar *name, ...) +{ + va_list ap; + const wxChar *p = name; + wxString data; + + va_start(ap, name); + + for (int x = 0; x < columns; x++) + { + data += wxT(" \n"); + p = va_arg(ap, wxChar *); + } + + va_end(ap); + + sectionTableHeader[section - 1] = data; +} + +void frmReport::XmlAddSectionTableRow(const int section, int number, int columns, const wxChar *value, ...) +{ + va_list ap; + const wxChar *p = value; + wxString data; + + va_start(ap, value); + + data = wxT(" \n"); + + va_end(ap); + + sectionTableRows[section - 1] += data; +} + +void frmReport::XmlAddSectionTableFromListView(const int section, ctlListView *list) +{ + // Get the column headers + int cols = list->GetColumnCount(); + + wxString data; + wxListItem itm; + + // Build the columns + for (int x = 0; x < cols; x++) + { + itm.SetMask(wxLIST_MASK_TEXT); + list->GetColumn(x, itm); + wxString label = itm.GetText(); + data += wxT(" \n"); + } + sectionTableHeader[section - 1] = data; + + // Build the rows + int rows = list->GetItemCount(); + + for (int y = 0; y < rows; y++) + { + data = wxT(" GetText(y, x)); + data += wxT("\""); + } + data += wxT(" />\n"); + sectionTableRows[section - 1] += data; + } +} + +void frmReport::XmlAddSectionTableFromGrid(const int section, ctlSQLResult *grid) +{ + // Get the column headers + int cols = grid->GetNumberCols(); + int shift = 0; + + wxString data; + wxListItem itm; + + if (grid->GetRowCountSuppressed()) + shift = 1; + + for (int x = 1; x <= cols; x++) + { + wxString label = grid->OnGetItemText(-1, x - shift); + data += wxT(" \n"); + } + sectionTableHeader[section - 1] = data; + + // Build the rows + int rows = grid->NumRows(); + + for (int y = 0; y < rows; y++) + { + data = wxT(" OnGetItemText(y, x - shift)); + data += wxT("\""); + } + data += wxT(" />\n"); + sectionTableRows[section - 1] += data; + } +} + +void frmReport::XmlSetSectionSql(int section, const wxString &sql) +{ + sectionSql[section - 1] = HtmlEntities(sql); + + if (!sectionSql[section - 1].IsEmpty()) + chkSql->Enable(); + else + chkSql->Disable(); +} + +void frmReport::XmlAddSectionValue(const int section, const wxString &name, const wxString &value) +{ + sectionData[section - 1] += wxT(" <") + HtmlEntities(name) + wxT(">") + HtmlEntities(value) + wxT("\n"); +} + +wxString frmReport::GetSectionTableColumns(const int section) +{ + wxString data; + + data = wxT(" \n"); + data += sectionTableHeader[section - 1]; + data += wxT(" \n"); + + return data; +} + +wxString frmReport::GetSectionTableRows(const int section) +{ + wxString data; + + data = wxT(" \n"); + data += sectionTableRows[section - 1]; + data += wxT(" \n"); + + return data; +} + +wxString frmReport::GetSectionTable(const int section) +{ + wxString data; + + data = wxT(" \n"); + data += GetSectionTableColumns(section); + data += GetSectionTableRows(section); + + if (!sectionTableInfo[section - 1].IsEmpty()) + { + data += wxT(" "); + data += sectionTableInfo[section - 1]; + data += wxT("\n"); + } + + data += wxT("
\n"); + + return data; +} + +wxString frmReport::GetSection(const int section) +{ + wxString data; + + data = wxT("
\n"); + data += GetSectionTable(section); + + + if (chkSql->GetValue() && !sectionSql[section - 1].IsEmpty()) + { + data += wxT(" "); + data += sectionSql[section - 1]; + data += wxT("\n"); + } + + data += sectionData[section - 1]; + data += wxT("
\n"); + + return data; +} + +wxString frmReport::GetXmlReport(const wxString &stylesheet = wxT("")) +{ + wxString data; + + data = wxT("\n"); + + if (!stylesheet.IsEmpty()) + { + data += wxT("\n"); + } + + data += wxT("\n"); + data += wxT("\n\n"); + + data += wxT("
\n"); + data += header; + data += wxT("
\n\n"); + + for (unsigned int x = 1; x <= sectionName.GetCount(); x++ ) + { + data += GetSection(x); + data += wxT("\n"); + } + + data += wxT("
\n"); + + return data; +} + +// +// libxml convenience macros +// +#define XML_FROM_WXSTRING(s) ((xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) + +wxString frmReport::XslProcessReport(const wxString &xml, const wxString &xsl) +{ + xmlChar *output = 0; + xmlDocPtr ssDoc = 0, xmlDoc = 0, resDoc = 0; + xsltStylesheetPtr ssPtr = 0; + int length; + + wxBeginBusyCursor(); + + // Apply the stylesheet + xmlSubstituteEntitiesDefault (1); // Substitute entities + xmlLoadExtDtdDefaultValue = 1; // Load external entities + + // Parse the stylesheet + ssDoc = xmlParseDoc(XML_FROM_WXSTRING(xsl)); + if (!ssDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to parse the XML stylesheet!")); + goto cleanup; + } + + ssPtr = xsltParseStylesheetDoc(ssDoc); + if (!ssPtr) + { + wxEndBusyCursor(); + wxLogError(_("Failed to parse the XSL stylesheet!")); + goto cleanup; + } + + // Parse the data + xmlDoc = xmlParseDoc(XML_FROM_WXSTRING(xml)); + if (!xmlDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to parse the XML document!")); + goto cleanup; + } + + // Apply the stylesheet + resDoc = xsltApplyStylesheet(ssPtr, xmlDoc, NULL); + if (!resDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to apply the XSL stylesheet to the XML document!")); + goto cleanup; + } + + // Get the result + xsltSaveResultToString (&output, &length, resDoc, ssPtr); + if (!resDoc) + { + wxEndBusyCursor(); + wxLogError(_("Failed to read the processed document!")); + goto cleanup; + } + +cleanup: + + // Cleanup + if (resDoc) + xmlFreeDoc(resDoc); + + if (xmlDoc) + xmlFreeDoc(xmlDoc); + + if (ssPtr) + xsltFreeStylesheet(ssPtr); + + // This crashes - dunno why :-( + // if (ssDoc) + // xmlFreeDoc(ssDoc); + + xsltCleanupGlobals(); + + wxEndBusyCursor(); + + if (output) + return WXSTRING_FROM_XML(output); + else + return wxEmptyString; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// END XML FUNCTIONS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +SQL::SQL(const wxString &_sql, const wxString &_pathtree) { + // Construct a SQL with the specified operation and text. + sql=wxString(_sql); + pathtree=wxString(_pathtree) ; + countchild=0; + mode=0; +} + +SQL::SQL() { +} + +/** + * Display a human-readable version of this SQL. + * @return text version + */ +wxString SQL::toString() const { + wxString prettyText = sql; + // Replace linebreaks with Pilcrow signs. + //prettyText.replace('\n', L'\u00b6'); + wxString c=wxEmptyString; + wxString cmp=wxEmptyString; + if (countchild>0) c.Printf(wxT("(%d)"), countchild); + bool r=false; + if (sql.Cmp(sql2)!=0) { + cmp="ne EQ "; + cmp.Printf(wxT("(ne EQ (%d, %d))"), sql.Len(),sql2.Len()); + } + if (mode==__Remove) cmp=cmp+" - "; + if (mode==__Insert) cmp=cmp+" + "; + if (mode==__Equal) cmp=cmp+" = "; + return wxString(pathtree+c+"\n"+cmp+"SQL(" + wxString("\"")) + + prettyText + wxString("\")"); +} + +/** + * Is this SQL equivalent to another SQL? + * @param d Another SQL to compare against + * @return true or false + */ +bool SQL::operator==(const SQL &d) const { + return (d.sql == this->sql); +} + +bool SQL::operator!=(const SQL &d) const { + return !(operator == (d)); +} + #include + WX_DEFINE_LIST(MyListSql); +#include "wx/arrimpl.cpp" +WX_DEFINE_OBJARRAY(ArraySQL) +wxString reportCompareFactory::GetNodePath(wxTreeItemId node) { + wxString path; + path = parent->GetBrowser()->GetItemText(node).Trim(); + + wxTreeItemId parent_id = parent->GetBrowser()->GetItemParent(node); + while (parent_id.IsOk()) + { + path = parent->GetBrowser()->GetItemText(parent_id).BeforeFirst('(').Trim() + wxT("/") + path; + parent_id = parent->GetBrowser()->GetItemParent(parent_id); + } + + return path; + +} +void reportCompareFactory::GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes, ArraySQL &list, time_t *t, wxBusyInfo *w, MyHashSQL &h_path,int lvl) +{ + wxTreeItemIdValue cookie; + ctlTree *browser=parent->GetBrowser(); + wxTreeItemId child; + if (lvl==0) child = node; + else child = browser->GetFirstChild(node, cookie); + pgObject *obj; + wxString path; + time_t tmp; + int size=expandedNodes.Count(); + while (child.IsOk()) + { + obj=browser->GetObject(child); + if (obj && obj->GetMetaType()==PGM_FUNCTION && !browser->HasChildren(child)) + path=GetNodePath(child); + else + path=parent->GetNodePath(child); + + // tmp=wxDateTime::GetTimeNow(); + // if (difftime(tmp,*t)>2.0) { + //w->~wxBusyInfo(); + //wxSafeYield(); + //wxMilliSleep(50); + //wxSafeYield(); + //w = new wxBusyInfo(wxString::Format("Path = %s ,GetName() = %s, isCollection = %d", + // path.c_str(), obj->GetName().c_str(), obj->IsCollection()),parent); + //wxSafeYield(); + //wxMilliSleep(50); + //wxSafeYield(); + // *t=tmp; + // } + if (obj) { +// OutputDebugString(wxString::Format("Path = %s ,GetName() = %s, isCollection = %d\n", +// path.c_str(), obj->GetTypeName().c_str(), obj->IsCollection())); + if (obj->GetMetaType()==PGM_CATALOG + ||obj->GetMetaType()==PGM_COLUMN + ||obj->GetMetaType()==PGM_RULE + ||obj->GetMetaType()==PGM_CATALOG + ) { + child = browser->GetNextChild(node, cookie); + continue; + } + //obj->ShowTreeDetail(browser); + //obj->ShowTree(parent,browser); + // åñëè íàäî îáúåêòî ñëîæíûé è ñàñ ñîñòîèò èç êîëëåêöèé + if ((obj->GetMetaType()==PGM_SCHEMA + ||obj->GetMetaType()==PGM_DATABASE + ||obj->GetMetaType()==PGM_TABLE + ||obj->GetMetaType()==PGM_FOREIGNTABLE + )&&!obj->IsCollection()) { + obj->ShowTreeDetail(browser); + //obj->ShowTree(parent,browser); + } else + { + if (obj->GetMetaType()==PGM_VIEW) obj->ShowTreeDetail(browser); // òîëüêî äëÿ òîãî ÷òîáû ïîëó÷èòü èíôó î òðèããåðàõ + if (obj->GetMetaType()==PGM_EVENTTRIGGER) // ïîëó÷àåì èíôó î òðèãåððàõ ïî ñîáûòèÿì + obj->ShowTreeDetail(browser); + } + } + + //if (browser->IsExpanded(child)) + if (browser->HasChildren(child)) + { + bool rec=true; + if (obj && (obj->GetMetaType()==PGM_TABLE + //||obj->GetMetaType()==PGM_VIEW + )) { + wxTreeItemId Item = browser->GetItemParent(child); + obj=browser->GetObject(Item); // Tables + wxTreeItemId Item2 = browser->GetItemParent(obj->GetId()); + obj=browser->GetObject(Item2); // Schemes + if (obj && obj->GetMetaType()==PGM_SCHEMA&& !obj->IsCollection()) { + rec=false; // íå ñîáèðàåì èíôó ïî ñåê. òàáëèöàì è ñåêöèÿì, è âî âíóòðü íå çàõîäèì + obj=browser->GetObject(child); + obj->ShowTreeDetail(browser); + } else obj=browser->GetObject(child); + } + if (obj && (obj->GetMetaType()==PGM_VIEW && !obj->IsCollection())) rec=false; + if (rec) { + GetExpandedChildNodes(child, expandedNodes,list,t,w,h_path,lvl+1); + //expandedNodes.Add(parent->GetNodePath(child)); + obj=browser->GetObject(child); + } + + } + if (obj ) { + wxString s=obj->GetSql(browser); + if (obj->GetMetaType()==PGM_SEQUENCE) s=""; + int c=browser->GetChildrenCount(child,false); + if (size>0) { + wxString srcpath(path); + SQL *sq; + srcpath.Replace(expandedNodes[0],expandedNodes[2],false); + srcpath.Replace(expandedNodes[1],expandedNodes[3],false); + MyHashSQL::iterator it=h_path.find(srcpath); + if (h_path.end()==it) { + // íå íàéäåíî â ïåðâîé ÁÄ + + if (s!=wxEmptyString) { + sq =new SQL(wxEmptyString,srcpath); + sq->sql2=s; + sq->mode=__Remove; + list.Add(sq); + + } else + { + sq =new SQL(wxEmptyString,srcpath); + sq->sql2=wxEmptyString; + sq->countchild=c; + sq->mode=__Remove; + list.Add(sq); + + } + + h_path[srcpath]=list.GetCount()-1; + } + else { + int i=it->second; + SQL& sql=list.Item(i); + sql.mode=__Equal; + sql.sql2=s; + } + } else { + if (s!=wxEmptyString) { + SQL *sq =new SQL(s,path); + sq->mode=__Insert; + list.Add(sq); + } else + { + SQL *sq =new SQL(s,path); + sq->countchild=c; + sq->mode=__Insert; + list.Add(sq); + } + h_path[path]=list.GetCount()-1; + } + } + + child = browser->GetNextChild(node, cookie); + } + +} + +wxWindow *reportCompareFactory::StartDialog(frmMain *form, pgObject *obj) +{ + parent = form; +// std::wstring r; +// std::wstring str1=L""; +// std::wstring str2=L"line#\nline2\nADD line 3\nline4\n"; +// r=printdiff(str1,str2); +// return 0; + +// wxBeginBusyCursor(); + //frmReport *report = new frmReport(GetFrmMain()); + //wxBusyInfo *waiting; + wxString msg; + // Generate the report header + wxDateTime now = wxDateTime::Now(); + + ctlTree *browser=form->GetBrowser(); + wxTreeItemIdValue foldercookie; + wxTreeItemId folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + wxString path(form->GetNodePath(obj->GetId())); + // ãðóïïû ñåðâåðîâ/Ñåðâåðû/serverN/Datebases/dbname + // p1 p2 p3 + wxString p_db; + int p1=path.Find('/'); + if (p1<0) return 0; + int p2=path.find('/',p1+1); + if (p2<0) return 0; + startpathpos=p2; + int p3=path.find('/',p2+1); + wxString p_pref=path.substr(0,p2); + wxString p_server_obj; + if (!obj->GetConnection()) return 0; + if (obj && obj->GetDatabase() && obj->GetDatabase()->GetConnected()) + p_db=obj->GetDatabase()->GetName(); + else + p_db=obj->GetServer()->GetDatabaseName(); + + if (p3<0) { + // âûáðàí ñåðâåð + //if (wxMessageBox(wxString::Format("Path = %s ,GetName() = %s, isCollection = %d", + // path.c_str(), obj->GetTypeName().c_str(), obj->IsCollection()), _("Close"), wxYES_NO | wxICON_QUESTION) != wxYES) + //{ + // return 0; + //} +//Ãðóïïû ñåðâåðîâ/Ñåðâåðû/PostgreSQL 9.6 +// èñïîëüçóåì ïåðâóþ ïîïàâøóþñÿ îòêðûòóþ ÁÄ + p_server_obj=path.substr(p2); // ñ /ñåðâåðN/ + + } else + { +// Ãðóïïû ñåðâåðîâ/Ñåðâåðû/PostgreSQL 9.6/Áàçû äàííûõ/postgres + p_server_obj=path.substr(p2,p3-p2); // ñ /ñåðâåðN/ + } + wxString p_db_replace=_("Databases")+"/"+p_db+"/"; + wxString p_server_replace=_("Servers")+p_server_obj; + pgServer *server; + pgDatabase *db=NULL,*lastdb=NULL; +wxString trg_db_replace; +wxString trg_server_replace; + + wxTreeItemId srvitem = obj->GetServer()->GetId(); + + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + wxTreeItemIdValue servercookie; + wxTreeItemId serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + server = (pgServer *)browser->GetItemData(serveritem); + if (server != NULL && server->IsCreatedBy(serverFactory)) + { + trg_server_replace=browser->GetItemText(server->GetId()).BeforeFirst('(').Trim(); + if (srvitem!=server->GetId() && server->GetConnected()) { + // íàøå ñîåäèíåíèå íå íóæíî íóæíî äðóãîå è àêòèâíîå + pgCollection *coll = browser->FindCollection(databaseFactory, server->GetId()); + if (coll) + { + treeObjectIterator dbs(browser, coll); + while ((db = (pgDatabase *)dbs.GetNextObject()) != 0) + { + // åñòü îòêðûòàÿ ÁÄ + lastdb=db; + if (db->GetConnected()) { + + //if (db->GetName()!=wxT("postgres")) goto ex_out; + goto ex_out; + } + } + + } + } + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } +ex_out: +pgObject *trgobj; +wxString newpath; +if (lastdb!=NULL) { + p_db=browser->GetItemText(lastdb->GetId()).BeforeFirst('(').Trim(); + trg_db_replace=_("Databases")+"/"+p_db+"/"; + trg_server_replace=_("Servers")+"/"+trg_server_replace; + + newpath=path; + + //if (newpath.Replace(p_server_replace,trg_server_replace,false)==0) + newpath.Replace(p_server_replace,trg_server_replace,false); + newpath.Replace(p_db_replace,trg_db_replace,false); + if (!parent->SetCurrentNode(parent->GetBrowser()->GetRootItem(),newpath)) { + msg.Printf("Íå óäàëîñü íàéòè îáúåêò %s â äðóãîé ÁÄ.",newpath); + wxMessageBox(msg, _("Error"), wxOK | wxICON_INFORMATION); + return 0; + } + trgobj=browser->GetObject(browser->GetSelection()); +} else +{ + msg="Íåò äðóãèõ óñòàíîâëåííûõ ñîåäèíåíèè , ñðàâíåíèå íå âîçìîæíî."; +// msg.Printf(" óñòàíîâëåííîì ñîåäèíåíèè %s, íåò ïîäõîäÿùèõ ÁÄ.",browser->GetItemText(lastdb->GetServer()->GetId()).BeforeFirst('(').Trim()); + wxMessageBox(msg, _("Error"), wxOK | wxICON_INFORMATION); + return 0; +} +time_t timer=wxDateTime::GetTimeNow(); + wxArrayString expandedNodes; + ArraySQL list; + MyHashSQL h_path; + +wxWindowDisabler disableAll; +{ + wxBusyInfo waiting(wxString::Format(" Îáõîä èñõîäíîé ÁÄ Path = %s ,Ñòàðòîâûé îáúåêò = %s", + browser->GetItemText(obj->GetServer()->GetId()).c_str(), obj->GetName().c_str(),parent)); + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(50); + wxSafeYield(); +// waiting->~wxBusyInfo(); + GetExpandedChildNodes(obj->GetId(),expandedNodes,list,&timer, NULL,h_path,0); +} +//waiting->~wxBusyInfo(); + + wxFileName fn(""); + fn.MakeAbsolute(); +wxSafeYield(); +wxMilliSleep(50); +wxSafeYield(); +// return 0; + +{ + wxBusyInfo waiting(wxString::Format(" Îáõîä äðóãîé ÁÄ Path = %s\nÑòàðòîâûé îáúåêò = %s", + browser->GetItemText(trgobj->GetId()).c_str(), trgobj->GetName().c_str(),parent)); + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(50); + wxSafeYield(); +timer=wxDateTime::GetTimeNow(); + wxArrayString expandedNodes2; + expandedNodes2.Add(trg_server_replace); + expandedNodes2.Add(trg_db_replace); + expandedNodes2.Add(p_server_replace); + expandedNodes2.Add(p_db_replace); + GetExpandedChildNodes(trgobj->GetId(),expandedNodes2,list,&timer, NULL,h_path,0); +} +//waiting->~wxBusyInfo(); + +int e_count=list.GetCount(); +int linecount=0; +int nstart=0,lastpos=0; +int c,minlen=100000,root=0; +wxArrayInt* child; +wxArrayPtrVoid level(15); +wxHashTable htab(wxKEY_STRING); +wxString key; +int npos=p2; + for (int i = 0; i < e_count; ++i) + { + SQL& sq = list.Item(i); + c=0; + nstart=0; + if ((nstart=sq.pathtree.rfind('/'))!=wxNOT_FOUND ) { + key=sq.pathtree.SubString(npos,nstart-1); + if (minlen>key.Len()) {minlen=key.Len(); root=i;} + } + child=(wxArrayInt *)htab.Get(key); + if (child==NULL) { + child=new wxArrayInt; + htab.Put(key,(wxObject *)child); + } + child->Add(i); + + linecount++; + } + +MyListSql::iterator iter2; +//e_count=list.GetCount(); +//for (int i = 0; i < e_count; ++i) +//{ +// SQL& sq = list.Item(i); +//} +// file2.Write(report, wxConvUTF8); +// file2.Close(); + + + //return 0; + titleline=wxEmptyString; + list_head=wxEmptyString; + rowlist=wxEmptyString; + list_end=wxEmptyString; + tableheader=wxEmptyString; + head=wxEmptyString; + tableheader2=wxEmptyString; + tableshtml=wxEmptyString; + +// Çàãðóçêà øàáëîíà +#ifndef _DEBUG + wxString fDir=wxStandardPaths::Get().GetExecutablePath().BeforeLast('\\')+wxT("\\"); +#else + wxString fDir=wxStandardPaths::Get().GetExecutablePath().BeforeLast('\\')+wxT("\\"); +#endif + wxString f=fDir+"textcompare_report.template"; + wxString buffer; + + wxUtfFile file3(f, wxFile::read, wxFONTENCODING_UTF8); + if (file3.IsOpened()) + { + file3.Read(buffer); + file3.Close(); + } else + { + wxLogError(_("Failed to open file %s."), f.c_str()); + return 0; + } + buffer.Replace('\r',wxEmptyString,true); + wxStringTokenizer lines(buffer, wxT("\n")); + Diff_EditCost=4; + Match_Threshold=0.5; + Match_Distance=1000; + + bool mline=false; + while (lines.HasMoreTokens()) + { + wxString tmp = lines.GetNextToken(); + + //if (tmp.length()>0 && tmp[tmp.length()-1]=='\r') tmp.RemoveLast(); + wxString line = tmp.Strip(wxString::both); + if (tmp.StartsWith("@end@")) break; + int l=wxString("@titleline").Len(); + if (tmp.StartsWith("@titleline")) {titleline=tmp.Mid(l)+"\n"; continue;} + l=wxString("@[list").Len(); + if (tmp.StartsWith("@[list")) {list_head=tmp.Mid(l)+"\n"; continue;} + l=wxString("@]list").Len(); + if (tmp.StartsWith("@]list")) {list_end=tmp.Mid(l)+"\n"; continue;} + l=wxString("@rowlist").Len(); + if (tmp.StartsWith("@rowlist")) {rowlist=tmp.Mid(l)+"\n"; continue;} + l=wxString("@tableheader2").Len(); + if (tmp.StartsWith("@tableheader2")) {tableheader2=tmp.Mid(l)+"\n"; continue;} + + if (tmp==wxString("@tableheader@")) {mline=!mline; continue;} + if (mline) { tableheader+=tmp+"\n";continue;} + // diff config + if (tmp.StartsWith("@Match_Distance=")) {Match_Distance=(int)StrToDouble(tmp.After('=')); continue;} + if (tmp.StartsWith("@Diff_EditCost=")) {Diff_EditCost=StrToDouble(tmp.After('=')); continue;} + if (tmp.StartsWith("@Match_Threshold=")) {Match_Threshold=(float)StrToDouble(tmp.After('=')); continue;} + + head+=tmp+"\n"; + } + // +{ + wxBusyInfo waiting(wxString::Format(" Ïîèñê ðàçëè÷èé ...",0)); + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(50); + wxSafeYield(); + + wxString content=printlvl(root,0,list,htab); + wxString tmp(titleline); + tmp.Replace("$titleline$","Left : "+path); + wxString tmp2(titleline); + tmp2.Replace("$titleline$","Right: "+newpath); + head.Replace("$titleline$",tmp+tmp2); + + head.Replace("$list$",content); + head.Replace("$tables$",tableshtml); + tableshtml=wxEmptyString; + content=wxEmptyString; +} + + //head+=""; + fDir=wxStandardPaths::Get().GetTempDir()+wxT("\\cmp.html"); + //fn="D:\\PostgreSQL\\cmp.html"; + fn=fDir; + fn.MakeAbsolute(); + + wxString html(head); + wxFile file4(fn.GetFullPath(), wxFile::write); + if (!file4.IsOpened()) + { + wxLogError(_("Failed to open file %s."), fn.GetFullPath().c_str()); + return 0; + } + file4.Write(html, wxConvUTF8); + file4.Close(); + head=wxEmptyString; + +list.RemoveAt(0,list.GetCount()); +e_count=list.GetCount(); +for (int i = 0; i < e_count; ++i) +{ + //SQL *p=&sq; + //list.RemoveAt(0,list.GetCount()); +// SQL *p = list.Detach(i); +// delete p; +} +//htab.DeleteContents(true); +h_path.clear(); +//MyHashSQL::iterator it, en; +//for( it = h_path.begin(), en = h_path.end(); it != en; ++it ) +//{ +// h_path.erase(it); +//} +//htab.Clear(); +//list.Empty(); + +#ifdef __WXMSW__ + wxLaunchDefaultBrowser(fn.GetFullPath()); +#else + wxLaunchDefaultBrowser(wxT("file://") + fn.GetFullPath()); +#endif + + return 0; +} +#if defined(DELETE) +#undef DELETE +#endif // DUMMYSTRUCTNAME + +std::wstring reportCompareFactory::printdiff(std::wstring str1, std::wstring str2 ) +{ + diff_match_patch dmp(Diff_EditCost,Match_Threshold,Match_Distance); + std::list diffs; + if (str1==str2) { + return L""; + } + diffs=dmp.diff_main(str1,str2); + int nstart=0; + int pos=0; + countdiffline=0; + std::wstring cur_l; + std::wstring ncur_l; std::wstring p_ncur_l;std::wstring p_ncur_r; + std::wstring cur_r; + std::wstring ncur_r; + std::wstring tex; + std::wstring t; + std::wstring tableline; + int rline=1,lline=1; + std::list::const_iterator it; // îáúÿâëÿåì èòåðàòîð + it = diffs.begin(); // ïðèñâàèâàåì åìó íà÷àëî ñïèñêà + Diff aDiff; + bool modify=false; + bool oneline=false; + nstart=0; + while (it != diffs.end()) // ïîêà èòåðàòîð íå äîñòèãíåò êîíöà + { + aDiff=*it; + tex=aDiff.text; + nstart=0; + while (nstart0) { + // ýòî âñ¸ åù¸ îäíà ñòðîêà + if (aDiff.operation==Operation::INSERT) cur_r+=L""+t+L""; + if (aDiff.operation==Operation::DELETE) cur_l+=L""+t+L""; + if (aDiff.operation==Operation::EQUAL) { + cur_r+=t; + cur_l+=t; + } else modify=true; + // ïîêà íå âñòðåòèì ïåðåâîä ñòðîêè ñ÷èòàåì ÷òî ýòî âñ¸ îäíà ñòðîêà + oneline=true; + } else + { + // äîøëè äî ïåðåâîäà \n + nstart=pos+1; + ncur_l=std::to_wstring(lline); + ncur_l=L""; ncur_r=L""; +// if (p_ncur_r==ncur_r) { ncur_r=L""; modify=true;} +// if (p_ncur_l==ncur_l) { ncur_l=L""; modify=true;} + + std::wstring t_cur_l=cur_l; + std::wstring t_cur_r=cur_r; + if (aDiff.operation==Operation::DELETE) { + t_cur_r=L""; + ncur_l=std::to_wstring(lline); + modify=true; + lline++; + } else if (aDiff.operation==Operation::INSERT) { + t_cur_l=L""; + ncur_r=std::to_wstring(rline); + modify=true; + rline++; + } else if (aDiff.operation==Operation::EQUAL) { + ncur_r=std::to_wstring(rline); + ncur_l=std::to_wstring(lline); + rline++; lline++; + } + if (modify) countdiffline++; +// if (( (ncur_r.empty()&&(!ncur_l.empty())) +// ||(ncur_l.empty()&&(!ncur_r.empty())) +// )&&(!modify)) modify=true; + // ôîðìèðóåì êîëîíêè + //left + tableline+=L""; + tableline+= modify ? L""+ncur_l+"" : L""+ncur_l+""; + tableline+=L"
"+t_cur_l+"
"; + // right + tableline+=L""; + tableline+= modify ? L""+ncur_r+"" : L""+ncur_r+""; + tableline+=L"
"+t_cur_r+"
"; + tableline+=L""; + + + + if (ncur_r.length()>0) p_ncur_r=ncur_r; + if (ncur_l.length()>0) p_ncur_l=ncur_l; + + if (aDiff.operation==Operation::DELETE) { + cur_l=L""; + } else if (aDiff.operation==Operation::INSERT) { + cur_r=L""; + } else if (aDiff.operation==Operation::EQUAL) { + cur_r=L"";cur_l=L""; + } + + // + modify=false; + oneline=false; + } + } // öèêë ïî ñòðîêàì âíóòðè îäíîãî Diff + ++it; + } +#ifdef _DEBUG + wxFileName fn("D:\\PostgreSQL\\cmp.txt"); + fn.MakeAbsolute(); + + wxFile file(fn.GetFullPath(), wxFile::write); + if (!file.IsOpened()) + { + wxLogError(_("Failed to open file %s."), fn.GetFullPath().c_str()); + } + +wxString report; + report.Append(wxString::Format(" Òàáëèöà\n%s\n",tableline)); + file.Write(report, wxConvUTF8); + file.Close(); + +#endif + +return tableline; +} +wxString reportCompareFactory::printlvl(int element,int lvl,ArraySQL &list, wxHashTable &htab) +{ + wxString l(list_head); + + wxString r=wxEmptyString; + wxArrayInt* child; + wxString key,name; + int e=element; + int nstart; + SQL& sq=list.Item(e); + if ((nstart=sq.pathtree.rfind('/'))!=wxNOT_FOUND ) { + name=sq.pathtree.AfterLast('/'); + key=sq.pathtree.Mid(startpathpos); + + } + wxString tid=wxString::Format("id%d",e); + wxString rlist=HtmlEntities(name); + wxString cdiff=wxEmptyString; + // òàáëèöà ðàçëè÷èé + countdiffline=0; + if (sq.sql.length()+sq.sql2.length()>0) { + // äëÿ îäèíàêîâûõ íåáóäêì òàáëèöó ôîðìèðîâàòü + std::wstring t1=sq.sql.wc_str(); + std::wstring t2(sq.sql2.wc_str()); + t1.erase(std::remove(t1.begin(), t1.end(), '\r'), t1.end()); + t2.erase(std::remove(t2.begin(), t2.end(), '\r'), t2.end()); + std::wstring rez=printdiff(t1,t2); + if (rez.length()>0) { + //L"" + //tableshtml + wxString tmp(tableheader); + tmp.Replace("@idtablecmp@",tid); + tmp.Replace("$rowlist$",rlist); + tableshtml+=tmp+"\n"; + tmp=tableheader2; + tmp.Replace("@idtablecmp@",tid); + tmp.Replace("$rowlist$",rlist); + tableshtml+=tmp; + tableshtml+=rez; + tableshtml+="\n"; + cdiff=wxString::Format(" ( %d )",countdiffline); + } + } + + // ñïèñîê îáúåêòîâ + child=(wxArrayInt *)htab.Get(key); + r=rowlist; + r.Replace("$rowlist$",rlist+cdiff); + if (sq.mode==__Insert) r.Replace("@color@","insert"); + else if (sq.mode==__Remove) r.Replace("@color@","remove"); + else if (countdiffline>0) r.Replace("@color@","ne"); else { + if (child!=NULL) r.Replace("@color@","eq"); else r.Replace("@color@","eqhidden"); + } + r.Replace("@idtablecmp@",tid); + l+=r; + if (child!=NULL) { + for (int j=0;jGetCount();j++) { + l+=printlvl(child->Item(j),lvl+1,list,htab); + } + } + l+=list_end; + return l; +} + +/////////////////////////////////////////////////////// +// Report base +/////////////////////////////////////////////////////// +wxWindow *reportBaseFactory::StartDialog(frmMain *form, pgObject *obj) +{ + parent = form; + + wxBeginBusyCursor(); + frmReport *report = new frmReport(GetFrmMain()); + + // Generate the report header + wxDateTime now = wxDateTime::Now(); + report->XmlAddHeaderValue(wxT("generated"), now.Format(wxT("%c"))); + if (obj->GetServer()) + report->XmlAddHeaderValue(wxT("server"), obj->GetServer()->GetFullIdentifier()); + if (obj->GetDatabase()) + report->XmlAddHeaderValue(wxT("database"), obj->GetDatabase()->GetName()); + if (obj->GetSchema()) + { + if (obj->GetSchema()->GetMetaType() == PGM_CATALOG) + report->XmlAddHeaderValue(wxT("catalog"), obj->GetSchema()->GetDisplayName()); + else + report->XmlAddHeaderValue(wxT("schema"), obj->GetSchema()->GetName()); + } + if (obj->GetJob()) + report->XmlAddHeaderValue(wxT("job"), obj->GetJob()->GetName()); + if (obj->GetTable()) + report->XmlAddHeaderValue(wxT("table"), obj->GetTable()->GetName()); + + GenerateReport(report, obj); + wxEndBusyCursor(); + + report->ShowModal(); + return 0; +} + +/////////////////////////////////////////////////////// +// Properties report +/////////////////////////////////////////////////////// +reportObjectPropertiesFactory::reportObjectPropertiesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Properties Report"), _("Generate a Properties report for this object.")); +} + +bool reportObjectPropertiesFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->IsCollection()) + return false; + else + return true; + } + return false; +} + +void reportObjectPropertiesFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(PROPERTIESREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(PROPERTIES)); + + ctlListView *list = GetFrmMain()->GetProperties(); + object->ShowProperties(); + + report->XmlAddSectionTableFromListView(section, list); + + report->XmlSetSectionSql(section, object->GetSql(NULL)); +} + +/////////////////////////////////////////////////////// +// DDL report +/////////////////////////////////////////////////////// +reportObjectDdlFactory::reportObjectDdlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&DDL Report"), _("Generate a DDL report for this object.")); +} + +bool reportObjectDdlFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->GetMetaType() == PGM_SERVER || obj->GetMetaType() == PGM_CATALOGOBJECT || obj->IsCollection()) + return false; + else + return true; + } + return false; +} + +void reportObjectDdlFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(DDLREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(DDL)); + + report->XmlSetSectionSql(section, object->GetSql(NULL)); +} + +/////////////////////////////////////////////////////// +// Data dictionary report +/////////////////////////////////////////////////////// +reportObjectDataDictionaryFactory::reportObjectDataDictionaryFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Data Dictionary Report"), _("Generate a Data Dictionary report for this object.")); +} + +bool reportObjectDataDictionaryFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if ((obj->GetMetaType() == PGM_TABLE || obj->GetMetaType() == GP_PARTITION) && !obj->IsCollection()) + return true; + else + return false; + } + return false; +} + +void reportObjectDataDictionaryFactory::GenerateReport(frmReport *report, pgObject *object) +{ + + pgTable *table = (pgTable *)object; + + report->SetReportTitle(object->GetTranslatedMessage(DATADICTIONNARYREPORT)); + + // Columns + int section = report->XmlCreateSection(_("Columns")); + + report->XmlSetSectionTableHeader(section, 6, (const wxChar *) _("Name"), (const wxChar *) _("Data type"), (const wxChar *) _("Not Null?"), (const wxChar *) _("Primary key?"), (const wxChar *) _("Default"), (const wxChar *) _("Comment")); + + ctlTree *browser = GetFrmMain()->GetBrowser(); + pgCollection *columns = table->GetColumnCollection(browser); + + treeObjectIterator colIt(browser, columns); + + pgColumn *column; + bool haveInherit = false; + wxString colName; + while ((column = (pgColumn *)colIt.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + colName = column->GetName(); + if (column->GetInheritedCount() > 0) + { + colName += _("*"); + haveInherit = true; + } + + report->XmlAddSectionTableRow(section, + column->GetColNumber(), + 6, + (const wxChar *) colName, + (const wxChar *) column->GetVarTypename(), + (const wxChar *) BoolToYesNo(column->GetNotNull()), + (const wxChar *) BoolToYesNo(column->GetIsPK()), + (const wxChar *) column->GetDefault(), + (const wxChar *) column->GetComment()); + } + } + if (haveInherit) + { + wxString info; + info.Printf(_("* Inherited columns from %s."), table->GetInheritedTables().c_str()); + report->XmlSetSectionTableInfo(section, info); + } + + // Constraints + pgCollection *constraints = table->GetConstraintCollection(browser); + + treeObjectIterator conIt(browser, constraints); + + pgObject *constraint; + long x = 1; + wxString definition, type; + while ((constraint = (pgObject *)conIt.GetNextObject()) != 0) + { + if (x == 1) + { + section = report->XmlCreateSection(_("Constraints")); + report->XmlSetSectionTableHeader(section, 4, (const wxChar *) _("Name"), (const wxChar *) _("Type"), (const wxChar *) _("Definition"), (const wxChar *) _("Comment")); + } + + constraint->ShowTreeDetail(browser); + + switch (constraint->GetMetaType()) + { + case PGM_PRIMARYKEY: + type = _("Primary key"); + definition = ((pgIndexConstraint *)constraint)->GetDefinition(); + break; + case PGM_UNIQUE: + type = _("Unique"); + definition = ((pgIndexConstraint *)constraint)->GetDefinition(); + break; + case PGM_FOREIGNKEY: + type = _("Foreign key"); + definition = ((pgForeignKey *)constraint)->GetDefinition(); + break; + case PGM_EXCLUDE: + type = _("Exclude"); + definition = ((pgIndexConstraint *)constraint)->GetDefinition(); + break; + case PGM_CHECK: + type = _("Check"); + definition = wxT("(") + ((pgCheck *)constraint)->GetDefinition() + wxT(")"); + break; + } + + report->XmlAddSectionTableRow(section, + x, + 4, + (const wxChar *) constraint->GetName(), + (const wxChar *) type, + (const wxChar *) definition, + (const wxChar *) constraint->GetComment()); + x++; + } +} + +/////////////////////////////////////////////////////// +// Statistics report +/////////////////////////////////////////////////////// +reportObjectStatisticsFactory::reportObjectStatisticsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Statistics Report"), _("Generate a Statistics report for this object.")); +} + +bool reportObjectStatisticsFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->HasStats()) + { + if (obj->IsCollection()) + { + pgaFactory *f = obj->GetFactory(); + + if (f) + { + if (f->GetMetaType() == PGM_TABLE || + f->GetMetaType() == GP_PARTITION || + f->GetMetaType() == PGM_TABLESPACE || + f->GetMetaType() == PGM_DATABASE) + return true; + } + else + { + return false; + } + } + else + { + return false; + } + + } + else + { + return true; + } + } + + return false; +} + +void reportObjectStatisticsFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(STATISTICSREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(OBJSTATISTICS)); + + ctlListView *list = GetFrmMain()->GetStatistics(); + object->ShowStatistics(GetFrmMain(), list); + + report->XmlAddSectionTableFromListView(section, list); +} + +/////////////////////////////////////////////////////// +// Dependencies report +/////////////////////////////////////////////////////// +reportObjectDependenciesFactory::reportObjectDependenciesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Dependencies Report"), _("Generate a Dependencies report for this object.")); +} + +bool reportObjectDependenciesFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->HasDepends()) + return false; + else + return true; + } + return false; +} + +void reportObjectDependenciesFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(DEPENDENCIESREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(DEPENDENCIES)); + + ctlListView *list = GetFrmMain()->GetDependencies(); + object->ShowDependencies(parent, list); + + report->XmlAddSectionTableFromListView(section, list); +} + +/////////////////////////////////////////////////////// +// Dependents report +/////////////////////////////////////////////////////// +reportObjectDependentsFactory::reportObjectDependentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Dependents Report"), _("Generate a Dependents report for this object.")); +} + +bool reportObjectDependentsFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->HasReferences()) + return false; + else + return true; + } + return false; +} + +void reportObjectDependentsFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(DEPENDENTSREPORT)); + + int section = report->XmlCreateSection(object->GetTranslatedMessage(DEPENDENTS)); + + ctlListView *list = GetFrmMain()->GetReferencedBy(); + object->ShowDependents(parent, list); + + report->XmlAddSectionTableFromListView(section, list); +} + +/////////////////////////////////////////////////////// +// Object list report +/////////////////////////////////////////////////////// +reportObjectListFactory::reportObjectListFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) + : reportBaseFactory(list) +{ + mnu->Append(id, _("&Object List Report"), _("Generate an Object List report for this collection.")); +} + +bool reportObjectListFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (!obj->IsCollection()) + { + return false; + } + else + { + pgaFactory *f = obj->GetFactory(); + if (obj) + { + if (f->GetMetaType() == PGM_SERVER) + return false; + } + else + return false; + + return true; + } + } + return false; +} + +void reportObjectListFactory::GenerateReport(frmReport *report, pgObject *object) +{ + report->SetReportTitle(object->GetTranslatedMessage(OBJECTSLISTREPORT)); + + int section = report->XmlCreateSection(object->GetFullIdentifier()); + + ctlListView *list = GetFrmMain()->GetProperties(); + object->ShowProperties(); + + report->XmlAddSectionTableFromListView(section, list); +} + + diff --git a/frm/frmRestore.cpp b/frm/frmRestore.cpp new file mode 100644 index 0000000..769c273 --- /dev/null +++ b/frm/frmRestore.cpp @@ -0,0 +1,896 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmRestore.cpp - Restore database dialogue +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include + + +// App headers +#include "frm/frmRestore.h" +#include "frm/frmMain.h" +#include "utils/sysLogger.h" +#include "schema/pgTable.h" +#include "schema/pgFunction.h" +#include "schema/pgLanguage.h" +#include "schema/pgConstraints.h" +#include "schema/pgForeignKey.h" +#include "ctl/ctlCheckTreeView.h" + +// Icons +#include "images/restore.pngc" + + +#define nbNotebook CTRL_NOTEBOOK("nbNotebook") +#define txtFilename CTRL_TEXT("txtFilename") +#define btnFilename CTRL_BUTTON("btnFilename") +#define cbFormat CTRL_COMBOBOX("cbFormat") +#define cbRolename CTRL_COMBOBOX("cbRolename") +#define chkOnlyData CTRL_CHECKBOX("chkOnlyData") +#define chkOnlySchema CTRL_CHECKBOX("chkOnlySchema") +#define chkNoOwner CTRL_CHECKBOX("chkNoOwner") +#define chkNoPrivileges CTRL_CHECKBOX("chkNoPrivileges") +#define chkNoTablespaces CTRL_CHECKBOX("chkNoTablespaces") +#define chkCreateDb CTRL_CHECKBOX("chkCreateDb") +#define chkClean CTRL_CHECKBOX("chkClean") +#define chkSingleXact CTRL_CHECKBOX("chkSingleXact") +#define chkDisableTrigger CTRL_CHECKBOX("chkDisableTrigger") +#define chkNoDataForFailedTables CTRL_CHECKBOX("chkNoDataForFailedTables") +#define chkUseSetSession CTRL_CHECKBOX("chkUseSetSession") +#define chkExitOnError CTRL_CHECKBOX("chkExitOnError") +#define txtNumberOfJobs CTRL_TEXT("txtNumberOfJobs") +#define chkVerbose CTRL_CHECKBOX("chkVerbose") +#define stSingleObject CTRL_STATIC("stSingleObject") +#define chkSectionPreData CTRL_CHECKBOX("chkSectionPreData") +#define chkSectionData CTRL_CHECKBOX("chkSectionData") +#define chkSectionPostData CTRL_CHECKBOX("chkSectionPostData") +#define ctvObjects CTRL_CHECKTREEVIEW("ctvObjects") +#define btnView CTRL_BUTTON("btnView") + + +BEGIN_EVENT_TABLE(frmRestore, ExternProcessDialog) + EVT_TEXT(XRCID("txtFilename"), frmRestore::OnChangeName) + EVT_COMBOBOX(XRCID("cbFormat"), frmRestore::OnChangeFormat) + EVT_CHECKBOX(XRCID("chkOnlyData"), frmRestore::OnChangeData) + EVT_CHECKBOX(XRCID("chkOnlySchema"), frmRestore::OnChangeSchema) + EVT_BUTTON(XRCID("btnFilename"), frmRestore::OnSelectFilename) + EVT_BUTTON(wxID_OK, frmRestore::OnOK) + EVT_BUTTON(XRCID("btnView"), frmRestore::OnView) + EVT_END_PROCESS(-1, frmRestore::OnEndProcess) + EVT_CLOSE( ExternProcessDialog::OnClose) + EVT_CHECKBOX(XRCID("chkSectionPreData"), frmRestore::OnChangeSection) + EVT_CHECKBOX(XRCID("chkSectionData"), frmRestore::OnChangeSection) + EVT_CHECKBOX(XRCID("chkSectionPostData"), frmRestore::OnChangeSection) +END_EVENT_TABLE() + + + +frmRestore::frmRestore(frmMain *form, pgObject *obj) : ExternProcessDialog(form) +{ + object = obj; + + if (object->GetMetaType() == PGM_SERVER) + server = (pgServer *)object; + else + server = object->GetDatabase()->GetServer(); + + SetFont(settings->GetSystemFont()); + LoadResource(form, wxT("frmRestore")); + RestorePosition(); + + SetTitle(object->GetTranslatedMessage(RESTORETITLE)); + + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + restoreExecutable = edbRestoreExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + restoreExecutable = gpRestoreExecutable; + else + restoreExecutable = pgRestoreExecutable; + + if (object->GetMetaType() != PGM_DATABASE) + { + chkOnlySchema->SetValue(object->GetMetaType() == PGM_FUNCTION + || object->GetMetaType() == PGM_INDEX + || object->GetMetaType() == PGM_TRIGGER); + chkOnlyData->SetValue(object->GetMetaType() == PGM_TABLE + || object->GetMetaType() == GP_PARTITION); + if (object->GetMetaType() != PGM_SCHEMA) + { + chkOnlyData->Disable(); + chkOnlySchema->Disable(); + } + if (object->GetMetaType() == PGM_FUNCTION) + { + chkClean->SetValue(true); + chkClean->Disable(); + } + btnView->Disable(); + } + + wxString val; + settings->Read(wxT("frmRestore/LastFile"), &val, wxEmptyString); + txtFilename->SetValue(val); + + // Icon + SetIcon(*restore_png_ico); + + txtMessages = CTRL_TEXT("txtMessages"); + // Note that under GTK+, SetMaxLength() function may only be used with single line text controls. + // (see http://docs.wxwidgets.org/2.8/wx_wxtextctrl.html#wxtextctrlsetmaxlength) +#ifndef __WXGTK__ + txtMessages->SetMaxLength(0L); +#endif + btnOK->Disable(); + filenameValid = false; + + if (!server->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + server->GetPassword()); + + // Pass the SSL mode via the environment + environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName()); + + if (server->GetSSLRootCert() != wxEmptyString) + environment.Add(wxT("PGSSLROOTCERT=") + server->GetSSLRootCert()); + + if (server->GetSSLCert() != wxEmptyString) + environment.Add(wxT("PGSSLCERT=") + server->GetSSLCert()); + + if (server->GetSSLKey() != wxEmptyString) + environment.Add(wxT("PGSSLKEY=") + server->GetSSLKey()); + + if (server->GetSSLCrl() != wxEmptyString) + environment.Add(wxT("PGSSLCRL=") + server->GetSSLCrl()); + + if (!pgAppMinimumVersion(restoreExecutable, 8, 4)) + { + chkNoTablespaces->Disable(); + chkSingleXact->Disable(); + txtNumberOfJobs->Disable(); + cbRolename->Disable(); + } + else + { + // Available rolenames + if (server->GetConnection()->BackendMinimumVersion(8, 1)) + { + pgSetIterator set(server->GetConnection(), + wxT("SELECT DISTINCT rolname\n") + wxT("FROM pg_roles db\n") + wxT("ORDER BY rolname")); + + cbRolename->Append(wxEmptyString); + + while(set.RowsLeft()) + cbRolename->Append(set.GetVal(wxT("rolname"))); + + cbRolename->SetValue(server->GetRolename()); + cbRolename->Enable(true); + } + else + cbRolename->Disable(); + } + if (!pgAppMinimumVersion(restoreExecutable, 8, 2)) + { + chkNoDataForFailedTables->Disable(); + } + if (!pgAppMinimumVersion(restoreExecutable, 8, 0)) + { + chkExitOnError->Disable(); + } + + cbFormat->Append(_("Custom or tar")); + if (pgAppMinimumVersion(restoreExecutable, 9, 1)) + cbFormat->Append(_("Directory")); + cbFormat->SetSelection(0); + + if (!pgAppMinimumVersion(restoreExecutable, 9, 2)) + { + chkSectionPreData->Disable(); + chkSectionData->Disable(); + chkSectionPostData->Disable(); + } + + wxCommandEvent ev; + OnChangeName(ev); +} + + +frmRestore::~frmRestore() +{ + SavePosition(); +} + + +wxString frmRestore::GetHelpPage() const +{ + wxString page; + page = wxT("pg/app-pgrestore"); + return page; +} + + +void frmRestore::OnSelectFilename(wxCommandEvent &ev) +{ + if (cbFormat->GetSelection() == 0) // custom or tar + { + wxString FilenameOnly; + wxFileName::SplitPath(txtFilename->GetValue(), NULL, NULL, &FilenameOnly, NULL); + +#ifdef __WXMSW__ + wxFileDialog file(this, _("Select backup filename"), ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, + _("Backup files (*.backup)|*.backup|All files (*.*)|*.*")); +#else + wxFileDialog file(this, _("Select backup filename"), ::wxPathOnly(txtFilename->GetValue()), FilenameOnly, + _("Backup files (*.backup)|*.backup|All files (*)|*")); +#endif + + if (file.ShowModal() == wxID_OK) + { + txtFilename->SetValue(file.GetPath()); + OnChange(ev); + } + } + else + { + wxDirDialog dir(this, _("Select the backup directory"), txtFilename->GetValue()); + if (dir.ShowModal() == wxID_OK) + { + txtFilename->SetValue(dir.GetPath()); + OnChange(ev); + } + } +} + + +void frmRestore::OnChangeFormat(wxCommandEvent &ev) +{ + btnView->Enable(cbFormat->GetSelection() == 0); +} + + +void frmRestore::OnChangeData(wxCommandEvent &ev) +{ + chkOnlySchema->Enable(!chkOnlyData->GetValue()); + chkSectionPreData->Enable(!chkOnlyData->GetValue()); + chkSectionData->Enable(!chkOnlyData->GetValue()); + chkSectionPostData->Enable(!chkOnlyData->GetValue()); + + OnChange(ev); +} + + +void frmRestore::OnChangeSchema(wxCommandEvent &ev) +{ + chkOnlyData->Enable(!chkOnlySchema->GetValue()); + chkSectionPreData->Enable(!chkOnlySchema->GetValue()); + chkSectionData->Enable(!chkOnlySchema->GetValue()); + chkSectionPostData->Enable(!chkOnlySchema->GetValue()); + + OnChange(ev); +} + + +void frmRestore::OnChangeSection(wxCommandEvent &ev) +{ + bool isSection = chkSectionPreData->GetValue() || chkSectionData->GetValue() || chkSectionPostData->GetValue(); + + chkOnlySchema->Enable(!isSection); + chkOnlyData->Enable(!isSection); + + OnChange(ev); +} + + +void frmRestore::OnChangeName(wxCommandEvent &ev) +{ + wxString name = txtFilename->GetValue(); + if (cbFormat->GetSelection() == 0) + { + if (name.IsEmpty() || !wxFile::Exists(name)) + filenameValid = false; + else + { + wxFile file(name, wxFile::read); + if (file.IsOpened()) + { + char buffer[8]; + off_t size = file.Read(buffer, 8); + if (size == 8) + { + if (memcmp(buffer, "PGDMP", 5) && !memcmp(buffer, "toc.dat", 8)) + { + // tar format? + file.Seek(512); + size = file.Read(buffer, 8); + } + if (size == 8 && !memcmp(buffer, "PGDMP", 5)) + { + // check version here? + filenameValid = true; + } + } + } + } + } + else + { + filenameValid = wxDir::Exists(name); + } + OnChange(ev); +} + + +void frmRestore::OnChange(wxCommandEvent &ev) +{ + btnOK->Enable(filenameValid); + btnView->Enable(filenameValid && object->GetMetaType() == PGM_DATABASE); +} + + +wxString frmRestore::GetCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(step); +} + + +wxString frmRestore::GetDisplayCmd(int step) +{ + wxString cmd = getCmdPart1(); + + return cmd + getCmdPart2(step); +} + + +wxString frmRestore::getCmdPart1() +{ + wxString cmd; + + cmd = restoreExecutable; + + if (!server->GetName().IsEmpty()) + cmd += wxT(" --host ") + server->GetName(); + + cmd += wxT(" --port ") + NumToStr((long)server->GetPort()) + + wxT(" --username ") + commandLineCleanOption(qtIdent(server->GetUsername())) + + wxT(" --dbname ") + commandLineCleanOption(object->GetDatabase()->GetQuotedIdentifier()); + + if (!cbRolename->GetValue().IsEmpty()) + cmd += wxT(" --role ") + commandLineCleanOption(qtIdent(cbRolename->GetValue())); + + if (pgAppMinimumVersion(restoreExecutable, 8, 4)) + cmd += wxT(" --no-password "); + + return cmd; +} + + +wxString frmRestore::getCmdPart2(int step) +{ + wxString cmd; + + wxString restoreExecutable; + if (object->GetConnection()->EdbMinimumVersion(8, 0)) + restoreExecutable = edbBackupExecutable; + else if (object->GetConnection()->GetIsGreenplum()) + restoreExecutable = gpBackupExecutable; + else + restoreExecutable = pgBackupExecutable; + + if (step) + { + cmd.Append(wxT(" --list")); + } + else + { + if (cbFormat->GetSelection() == 1) // directory + { + cmd.Append(wxT(" --format directory")); + } + + // Section + if (pgAppMinimumVersion(restoreExecutable, 9, 2)) + { + if (chkSectionPreData->GetValue()) + cmd.Append(wxT(" --section pre-data")); + if (chkSectionData->GetValue()) + cmd.Append(wxT(" --section data")); + if (chkSectionPostData->GetValue()) + cmd.Append(wxT(" --section post-data")); + } + + if (chkOnlyData->GetValue()) + { + cmd.Append(wxT(" --data-only")); + } + else + { + if (chkNoOwner->GetValue()) + cmd.Append(wxT(" --no-owner")); + if (chkNoPrivileges->GetValue()) + cmd.Append(wxT(" --no-privileges")); + if (chkNoTablespaces->GetValue()) + cmd.Append(wxT(" --no-tablespaces")); + } + + if (chkOnlySchema->GetValue()) + { + cmd.Append(wxT(" --schema-only")); + } + else + { + if (chkDisableTrigger->GetValue()) + cmd.Append(wxT(" --disable-triggers")); + } + if (chkCreateDb->GetValue()) + cmd.Append(wxT(" --create")); + if (chkClean->GetValue()) + cmd.Append(wxT(" --clean")); + if (chkSingleXact->GetValue()) + cmd.Append(wxT(" --single-transaction")); + if (chkNoDataForFailedTables->GetValue()) + cmd.Append(wxT(" --no-data-for-failed-tables")); + if (chkUseSetSession->GetValue()) + cmd.Append(wxT(" --use-set-session-authorization")); + if (chkExitOnError->GetValue()) + cmd.Append(wxT(" --exit-on-error")); + + if (!txtNumberOfJobs->GetValue().IsEmpty()) + cmd.Append(wxT(" --jobs ") + txtNumberOfJobs->GetValue()); + + // Process selected items + wxTreeItemId root, firstLevelObject, secondLevelObject; + wxTreeItemIdValue firstLevelObjectData, secondLevelObjectData; + bool partialDump = false; + + // Get root object + root = ctvObjects->GetRootItem(); + + if (root && object->GetMetaType() == PGM_DATABASE) + { + // Prepare the array + wxArrayString restoreStrings; + restoreStrings.Add(wxEmptyString, numberOfTOCItems); + restoreTreeItemData *data; + + // Loop through first level objects + firstLevelObject = ctvObjects->GetFirstChild(root, firstLevelObjectData); + while (firstLevelObject.IsOk()) + { + if (ctvObjects->IsChecked(firstLevelObject)) + { + // Write the file + data = (restoreTreeItemData *)ctvObjects->GetItemData(firstLevelObject); + restoreStrings[data->GetId()] = data->GetDesc(); + + // Loop through second level objects + secondLevelObject = ctvObjects->GetFirstChild(firstLevelObject, secondLevelObjectData); + while (secondLevelObject.IsOk()) + { + if (ctvObjects->IsChecked(secondLevelObject)) + { + // Write the file + data = (restoreTreeItemData *)ctvObjects->GetItemData(secondLevelObject); + restoreStrings[data->GetId()] = data->GetDesc(); + } + else + partialDump = true; + secondLevelObject = ctvObjects->GetNextChild(firstLevelObject, secondLevelObjectData); + } + } + else + partialDump = true; + firstLevelObject = ctvObjects->GetNextChild(root, firstLevelObjectData); + } + + // Open a temporary file to store the TOC + restoreTOCFilename = wxFileName::CreateTempFileName(wxT("restore")); + wxFile tocFile; + tocFile.Open(restoreTOCFilename.c_str(), wxFile::write); + + // Write all selected items in it + for (int i = 0; i < numberOfTOCItems; i++) + { + if (restoreStrings[i] != wxEmptyString) + { + if (!tocFile.Write(restoreStrings[i] + wxT("\n"))) + { + wxLogError(_("Error writing to the temporary file ") + restoreTOCFilename); + } + } + } + + // If some items were not checked and if the file still contains something, we have to use the list + if (partialDump && tocFile.Length() > 0) + cmd.Append(wxT(" --use-list \"") + restoreTOCFilename + wxT("\"")); + tocFile.Close(); + } + else if (object->GetMetaType() != PGM_DATABASE) + { + switch (object->GetMetaType()) + { + case PGM_FUNCTION: + cmd.Append(wxT(" --function ") + commandLineCleanOption(qtIdent(object->GetFullName()), true)); + break; + case PGM_INDEX: + cmd.Append(wxT(" --index ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + break; + case PGM_TABLE: + cmd.Append(wxT(" --table ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + break; + case PGM_TRIGGER: + cmd.Append(wxT(" --trigger ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + break; + default: + break; + } + if (object->GetMetaType() == PGM_SCHEMA) + cmd.Append(wxT(" --schema ") + commandLineCleanOption(object->GetQuotedIdentifier(), true)); + else if (pgAppMinimumVersion(restoreExecutable, 8, 2)) + cmd.Append(wxT(" --schema ") + commandLineCleanOption(object->GetSchema()->GetQuotedIdentifier(), true)); + } + + if (settings->GetIgnoreVersion()) + cmd.Append(wxT(" --ignore-version")); + if (chkVerbose->GetValue()) + cmd.Append(wxT(" --verbose")); + } + + + cmd.Append(wxT(" \"") + txtFilename->GetValue() + wxT("\"")); + + return cmd; +} + + +void frmRestore::OnView(wxCommandEvent &ev) +{ + btnView->Disable(); + btnOK->Disable(); + viewRunning = true; + Execute(1, false); + btnOK->SetLabel(_("OK")); + done = 0; +} + + +void frmRestore::OnOK(wxCommandEvent &ev) +{ + if (!done) + { + if (processedFile == txtFilename->GetValue()) + { + if (wxMessageBox(_("Are you sure you wish to run a restore from this file again?"), _("Repeat restore?"), wxICON_QUESTION | wxYES_NO) != wxYES) + return; + } + + processedFile = txtFilename->GetValue(); + } + + settings->Write(wxT("frmRestore/LastFile"), txtFilename->GetValue()); + viewRunning = false; + btnView->Disable(); + + ExternProcessDialog::OnOK(ev); + +} + + +void frmRestore::OnEndProcess(wxProcessEvent &ev) +{ + ExternProcessDialog::OnEndProcess(ev); + + if (done && viewRunning && !ev.GetExitCode()) + { + done = false; + + wxString str = wxTextBuffer::Translate(txtMessages->GetValue(), wxTextFileType_Unix); + + wxStringTokenizer line(str, wxT("\n")); + line.GetNextToken(); + + wxBeginBusyCursor(); + + wxString i18nbackup = _("Backup"); + wxTreeItemId root = ctvObjects->AddRoot(i18nbackup + wxT(" ") + txtFilename->GetValue()); + wxString currentSchema = wxT(""); + wxTreeItemId currentSchemaNode; + wxTreeItemId schemaNode, lastItem, extensionNode; + wxTreeItemIdValue schemaNodeData, extensionNodeData; + numberOfTOCItems = 0; + + while (line.HasMoreTokens()) + { + // Read the next line + str = line.GetNextToken(); + + // If this is the last line, it contains process information - skip it! + if (!line.HasMoreTokens()) + continue; + + // Skip the few lines of comments + if (str.Left(1) == wxT(";") || str.Left(1) == wxT("P")) + continue; + + // Split the line according to spaces + wxStringTokenizer col(str, wxT(" ")); + + // Column 1 (dumpId) + col.GetNextToken(); + + // Column 2 (tableOid) + col.GetNextToken(); + + // Column 3 (oid) + col.GetNextToken(); + + // Column 4 (desc) + // First interesting information: object's type + wxString type = col.GetNextToken(); + + if (type == wxT("DATABASE")) + { + // We are restoring a database, not creating one. So ignore + // this line as there is no valid schema info and move on + // to the next object + continue; + } + else if (type == wxT("PROCEDURAL")) + { + // type for a PL is PROCEDURAL LANGUAGE + // we'll keep the next column for the object's type + type = col.GetNextToken(); + } + else if (type == wxT("SHELL")) + { + // type for a SHELL is SHELL TYPE + // we'll keep both columns for the object's type + type += col.GetNextToken(); + } + else if (type == wxT("OPERATOR")) + { + // type for an operator class is OPERATOR CLASS + // we'll keep the two columns for the object's type + wxString tmp = str.Mid(str.Find(type) + type.Length() + 1, 5); + if (tmp == wxT("CLASS")) + type += wxT(" ") + col.GetNextToken(); + } + else if (type == wxT("SEQUENCE")) + { + // type for a sequence can be SEQUENCE, SEQUENCE OWNED BY or SEQUENCE SET + // we'll keep all these columns for the object's type + wxString tmp = str.Mid(str.Find(type) + type.Length() + 1, 3); + if (tmp == wxT("OWN") || tmp == wxT("SET")) + { + type += wxT(" ") + col.GetNextToken(); + if (type == wxT("SEQUENCE OWNED")) + type += wxT(" ") + col.GetNextToken(); + } + } + else if (type == wxT("FK")) + { + // type for a FK is FK CONSTRAINT + // we'll keep the next column for the object's type + type = col.GetNextToken(); + } + else if (type == wxT("TABLE")) + { + if (col.CountTokens() == 4) + { + // TABLE DATA detected + type += wxT(" ") + col.GetNextToken(); + } + } + // In case of statements like DEFAULT ACL DEFAULT PRIVILEGES FOR TABLES + else if (type == wxT("DEFAULT")) + { + // We do not expect the 'DEFAULT ' pattern here. + if (col.CountTokens() != 3) + { + type += wxT(" ") + col.GetNextToken(); + if (type != wxT("DEFAULT ACL")) + { + wxLogError(wxString::Format(_("Unexpected DEFAULT statement found: '%s'!"), str.c_str())); + continue; + } + } + } + + // Column 5 (namespace) + // Second interesting information: object's schema + wxString schema = col.GetNextToken(); + + // Column 6 (tag) + // Third interesting information: object's qualified name + //wxString name=col.GetNextToken(); + wxString name = str.Mid(str.Find(schema) + schema.Length() + 1).BeforeLast(' '); + + // Column 7 (owner) + // Fourth interesting information: object's owner + wxString owner = str.Mid(str.Find(name) + name.Length() + 1); + + // New method + if (type == wxT("LANGUAGE")) + { + lastItem = ctvObjects->AppendItem(root, wxT("Language ") + name + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + else if (type == wxT("ACL") && schema == wxT("-")) + { + lastItem = ctvObjects->AppendItem(root, type + wxT(" ") + name, 1); + } + else if (type == wxT("CAST")) + { + lastItem = ctvObjects->AppendItem(root, name, 1); + } + else if (type == wxT("SCHEMA")) + { + currentSchema = name; + lastItem = currentSchemaNode = ctvObjects->AppendItem(root, wxT("Schema ") + name, 1); + } + else if (type == wxT("EXTENSION") && (schema == wxT("-") || schema.IsEmpty())) + { + lastItem = ctvObjects->AppendItem(root, + owner.IsEmpty() ? wxT("Extension ") + name : + wxT("Extension ") + name + wxT("[") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + else if (type == wxT("COMMENT") && name.StartsWith(wxT("EXTENSION "))) + { + wxString extension = name.SubString(10, name.Length()); + + if (ctvObjects->GetItemText(lastItem) == wxT("Extension ") + extension) + { + extensionNode = lastItem; + } + else + { + wxTreeItemId searchStartNode = root; + + if (schema != wxT("-")) + { + searchStartNode = currentSchemaNode; + if (schema != currentSchema) + { + searchStartNode = ctvObjects->GetFirstChild(root, schemaNodeData); + bool found = false; + while (searchStartNode.IsOk() && !found) + { + if (ctvObjects->GetItemText(searchStartNode) == wxT("Schema ") + schema) + found = true; + else + searchStartNode = ctvObjects->GetNextChild(root, schemaNodeData); + } + + // Found it? + if (!searchStartNode.IsOk()) + { + searchStartNode = schemaNode; + } + else + { + searchStartNode = root; + } + } + } + + extensionNode = ctvObjects->GetFirstChild(searchStartNode, extensionNodeData); + bool found = false; + + while (extensionNode.IsOk() && !found) + { + if (ctvObjects->GetItemText(extensionNode) == wxT("Extension ") + extension) + found = true; + else + extensionNode = ctvObjects->GetNextChild(searchStartNode, schemaNodeData); + } + } + + if (extensionNode.IsOk()) + { + lastItem = ctvObjects->AppendItem(extensionNode, + owner.IsEmpty() ? type + wxT(" Extension ") + extension : + type + wxT(" Extension ") + extension + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + } + else + { + if (schema != currentSchema) + { + // Loop through the nodes to find the schema + schemaNode = ctvObjects->GetFirstChild(root, schemaNodeData); + bool found = false; + while (schemaNode.IsOk() && !found) + { + if (ctvObjects->GetItemText(schemaNode) == wxT("Schema ") + schema) + found = true; + else + schemaNode = ctvObjects->GetNextChild(root, schemaNodeData); + } + + // Found it? + if (schemaNode.IsOk()) + { + currentSchema = schema; + currentSchemaNode = schemaNode; + } + // if we are treating a comment, we use the schema of its + // object (ie, the previous line) + else if (type != wxT("COMMENT")) + { + wxLogError(_("Schema node not found for object ") + type + wxT(" ") + name + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]")); + } + } + lastItem = ctvObjects->AppendItem(currentSchemaNode, + owner.IsEmpty() ? type + wxT(" ") + name : + type + wxT(" ") + name + wxT(" [") + _("owner") + wxT(": ") + owner + wxT("]"), 1); + } + ctvObjects->SetItemData(lastItem, new restoreTreeItemData(numberOfTOCItems, str)); + numberOfTOCItems++; + } + + wxEndBusyCursor(); + nbNotebook->SetSelection(3); + } + else + { + wxRemoveFile(restoreTOCFilename); + } +} + + +void frmRestore::Go() +{ + txtFilename->SetFocus(); + Show(true); +} + + + +restoreFactory::restoreFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Restore..."), _("Restores a backup from a local file")); +} + + +wxWindow *restoreFactory::StartDialog(frmMain *form, pgObject *obj) +{ + frmRestore *frm = new frmRestore(form, obj); + frm->Go(); + return 0; +} + + +bool restoreFactory::CheckEnable(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetConnection() && obj->GetConnection()->EdbMinimumVersion(8, 0)) + return obj->CanCreate() && obj->CanRestore() && !edbRestoreExecutable.IsEmpty(); + else if (obj->GetConnection() && obj->GetConnection()->GetIsGreenplum()) + return obj->CanCreate() && obj->CanRestore() && !gpRestoreExecutable.IsEmpty(); + else + return obj->CanCreate() && obj->CanRestore() && !pgRestoreExecutable.IsEmpty(); +} + + +restoreTreeItemData::restoreTreeItemData(int id, const wxString &desc) +{ + restoreId = id; + restoreDesc = desc; +} diff --git a/frm/frmSplash.cpp b/frm/frmSplash.cpp new file mode 100644 index 0000000..5bf7998 --- /dev/null +++ b/frm/frmSplash.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmSplash.cpp - Splash Screen +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmSplash.h" + + +// Copyright text +#include "copyright.h" +#include "version.h" + +BEGIN_EVENT_TABLE(frmSplash, wxFrame) + EVT_PAINT(frmSplash::OnPaint) + +#ifdef __WXGTK__ + EVT_WINDOW_CREATE(frmSplash::OnWindowCreate) +#endif +END_EVENT_TABLE() + +frmSplash::frmSplash(wxFrame *parent) +#ifndef __WXDEBUG__ + : wxFrame((wxFrame *)NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(100, 100), 0 | wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP) +#else + : wxFrame((wxFrame *)NULL, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(100, 100), 0 | wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR) +#endif +{ + appearanceFactory->SetIcons(this); + splash = appearanceFactory->GetSplashImage(); + + SetClientSize(splash.GetWidth(), splash.GetHeight()); + +#ifndef __WXGTK__ + SetWindowShape(); +#endif + + CenterOnScreen(); +} + +void frmSplash::SetWindowShape() +{ + wxRegion region(splash); + SetShape(region); +} + +void frmSplash::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ + wxPoint pos = appearanceFactory->GetSplashTextPos(); + + wxPaintDC dc(this); + dc.DrawBitmap(splash, 0, 0, true); + + dc.SetTextForeground(appearanceFactory->GetSplashTextColour()); + dc.SetFont(appearanceFactory->GetSplashTextFont()); + + if (appearanceFactory->IsBranded()) + { + dc.DrawText(_("This program is based on pgAdmin III"), pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + } + dc.DrawText(VERSION_WITHOUT_DATE, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(COPYRIGHT, pos); + pos.y += appearanceFactory->GetSplashTextOffset(); + dc.DrawText(LICENSE, pos); +} + +void frmSplash::OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)) +{ + SetWindowShape(); +} diff --git a/frm/frmStatus.cpp b/frm/frmStatus.cpp new file mode 100644 index 0000000..97bf1b7 --- /dev/null +++ b/frm/frmStatus.cpp @@ -0,0 +1,3708 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmStatus.cpp - Status Screen +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include + +// wxAUI +#include + +// App headers +#include "frm/frmAbout.h" +#include "frm/frmStatus.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "db/pgConn.h" +#include "frm/frmQuery.h" +#include "utils/pgfeatures.h" +#include "schema/pgServer.h" +#include "schema/pgUser.h" +#include "ctl/ctlMenuToolbar.h" +#include "ctl/ctlAuiNotebook.h" +#include "utils/csvfiles.h" + +// Icons +#include "images/clip_copy.pngc" +#include "images/readdata.pngc" +#include "images/query_cancel.pngc" +#include "images/terminate_backend.pngc" +#include "images/delete.pngc" +#include "images/storedata.pngc" +#include "images/down.pngc" +#include "images/up.pngc" + + +#include "db/pgConn.h" + + +#define CTRLID_DATABASE 4200 + + +BEGIN_EVENT_TABLE(frmStatus, pgFrame) + EVT_MENU(MNU_EXIT, frmStatus::OnExit) + + EVT_MENU(MNU_COPY, frmStatus::OnCopy) + EVT_MENU(MNU_COPY_QUERY, frmStatus::OnCopyQuery) + EVT_MENU(MNU_HELP, frmStatus::OnHelp) + EVT_MENU(MNU_CONTENTS, frmStatus::OnContents) + EVT_MENU(MNU_STATUSPAGE, frmStatus::OnToggleStatusPane) + EVT_MENU(MNU_LOCKPAGE, frmStatus::OnToggleLockPane) + EVT_MENU(MNU_XACTPAGE, frmStatus::OnToggleXactPane) + EVT_MENU(MNU_LOGPAGE, frmStatus::OnToggleLogPane) + EVT_MENU(MNU_QUERYSTATEPAGE, frmStatus::OnToggleQuerystatePane) + EVT_MENU(MNU_QUERYSTATEVERBOSE, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATETIME, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATEBUFFER, frmStatus::OnEmptyAction) + EVT_MENU(MNU_QUERYSTATETRIGGER, frmStatus::OnEmptyAction) + + EVT_MENU(MNU_TOOLBAR, frmStatus::OnToggleToolBar) + EVT_MENU(MNU_DEFAULTVIEW, frmStatus::OnDefaultView) + EVT_MENU(MNU_HIGHLIGHTSTATUS, frmStatus::OnHighlightStatus) + + EVT_AUI_PANE_CLOSE( frmStatus::OnPaneClose) + + EVT_COMBOBOX(CTL_RATECBO, frmStatus::OnRateChange) + EVT_MENU(MNU_REFRESH, frmStatus::OnRefresh) + EVT_MENU(MNU_CANCEL, frmStatus::OnCancelBtn) + EVT_MENU(MNU_TERMINATE, frmStatus::OnTerminateBtn) + EVT_MENU(MNU_COMMIT, frmStatus::OnCommit) + EVT_MENU(MNU_ROLLBACK, frmStatus::OnRollback) + EVT_COMBOBOX(CTL_LOGCBO, frmStatus::OnLoadLogfile) + EVT_BUTTON(CTL_ROTATEBTN, frmStatus::OnRotateLogfile) + + EVT_TIMER(TIMER_REFRESHUI_ID, frmStatus::OnRefreshUITimer) + + EVT_TIMER(TIMER_STATUS_ID, frmStatus::OnRefreshStatusTimer) + EVT_LIST_ITEM_SELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) + EVT_LIST_ITEM_DESELECTED(CTL_STATUSLIST, frmStatus::OnSelStatusItem) + EVT_LIST_COL_CLICK(CTL_STATUSLIST, frmStatus::OnSortStatusGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_STATUSLIST, frmStatus::OnRightClickStatusGrid) + EVT_LIST_COL_END_DRAG(CTL_STATUSLIST, frmStatus::OnChgColSizeStatusGrid) + + EVT_TIMER(TIMER_LOCKS_ID, frmStatus::OnRefreshLocksTimer) + EVT_LIST_ITEM_SELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) + EVT_LIST_ITEM_DESELECTED(CTL_LOCKLIST, frmStatus::OnSelLockItem) + EVT_LIST_COL_CLICK(CTL_LOCKLIST, frmStatus::OnSortLockGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_LOCKLIST, frmStatus::OnRightClickLockGrid) + EVT_LIST_COL_END_DRAG(CTL_LOCKLIST, frmStatus::OnChgColSizeLockGrid) + + EVT_TIMER(TIMER_XACT_ID, frmStatus::OnRefreshXactTimer) + EVT_LIST_ITEM_SELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) + EVT_LIST_ITEM_DESELECTED(CTL_XACTLIST, frmStatus::OnSelXactItem) + EVT_LIST_COL_CLICK(CTL_XACTLIST, frmStatus::OnSortXactGrid) + EVT_LIST_COL_RIGHT_CLICK(CTL_XACTLIST, frmStatus::OnRightClickXactGrid) + EVT_LIST_COL_END_DRAG(CTL_XACTLIST, frmStatus::OnChgColSizeXactGrid) + + + + + EVT_TIMER(TIMER_LOG_ID, frmStatus::OnRefreshLogTimer) + EVT_LIST_ITEM_SELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) + EVT_LIST_ITEM_DESELECTED(CTL_LOGLIST, frmStatus::OnSelLogItem) + + EVT_TIMER(TIMER_QUERYSTATE_ID, frmStatus::OnRefreshQuerystateTimer) + EVT_LIST_COL_RIGHT_CLICK(CTL_QUERYSTATELIST, frmStatus::OnRightClickQuerystateGrid) + EVT_LIST_ITEM_SELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) + EVT_LIST_ITEM_DESELECTED(CTL_QUERYSTATELIST, frmStatus::OnSelQuerystateItem) + EVT_LIST_COL_END_DRAG(CTL_QUERYSTATELIST, frmStatus::OnChgColSizeQuerystateGrid) + EVT_COMBOBOX(CTRLID_DATABASE, frmStatus::OnChangeDatabase) + + EVT_CLOSE( frmStatus::OnClose) +END_EVENT_TABLE(); + + +int frmStatus::cboToRate() +{ + int rate = 0; + + if (cbRate->GetValue() == _("Don't refresh")) + rate = 0; + if (cbRate->GetValue() == _("1 second")) + rate = 1; + if (cbRate->GetValue() == _("5 seconds")) + rate = 5; + if (cbRate->GetValue() == _("10 seconds")) + rate = 10; + if (cbRate->GetValue() == _("30 seconds")) + rate = 30; + if (cbRate->GetValue() == _("1 minute")) + rate = 60; + if (cbRate->GetValue() == _("5 minutes")) + rate = 300; + if (cbRate->GetValue() == _("10 minutes")) + rate = 600; + if (cbRate->GetValue() == _("30 minutes")) + rate = 1800; + if (cbRate->GetValue() == _("1 hour")) + rate = 3600; + + return rate; +} + + +wxString frmStatus::rateToCboString(int rate) +{ + wxString rateStr; + + if (rate == 0) + rateStr = _("Don't refresh"); + if (rate == 1) + rateStr = _("1 second"); + if (rate == 5) + rateStr = _("5 seconds"); + if (rate == 10) + rateStr = _("10 seconds"); + if (rate == 30) + rateStr = _("30 seconds"); + if (rate == 60) + rateStr = _("1 minute"); + if (rate == 300) + rateStr = _("5 minutes"); + if (rate == 600) + rateStr = _("10 minutes"); + if (rate == 1800) + rateStr = _("30 minutes"); + if (rate == 3600) + rateStr = _("1 hour"); + + return rateStr; +} + + +frmStatus::frmStatus(frmMain *form, const wxString &_title, pgConn *conn) : pgFrame(NULL, _title) +{ + wxString initquery; + bool highlight = false; + + dlgName = wxT("frmStatus"); + + loaded = false; + + mainForm = form; + connection = conn; + locks_connection = conn; + + statusTimer = 0; + locksTimer = 0; + xactTimer = 0; + logTimer = 0; + + logHasTimestamp = false; + logFormatKnown = false; + + // Only superusers can set these parameters... + pgUser *user = new pgUser(connection->GetUser()); + if (user) + { + if (user->GetSuperuser()) + { + // Make the connection quiet on the logs + if (connection->BackendMinimumVersion(8, 0)) + initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;"); + else + initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); + connection->ExecuteVoid(initquery, false); + } + delete user; + } + + // Notify wxAUI which frame to use + manager.SetManagedWindow(this); + manager.SetFlags(wxAUI_MGR_DEFAULT | wxAUI_MGR_TRANSPARENT_DRAG | wxAUI_MGR_ALLOW_ACTIVE_PANE); + + // Set different window's attributes + SetTitle(_title); + appearanceFactory->SetIcons(this); + RestorePosition(-1, -1, 700, 500, 700, 500); + SetMinSize(wxSize(700, 500)); + SetFont(settings->GetSystemFont()); + + // Build menu bar + menuBar = new wxMenuBar(); + + fileMenu = new wxMenu(); + fileMenu->Append(MNU_EXIT, _("E&xit\tCtrl-W"), _("Exit query window")); + + menuBar->Append(fileMenu, _("&File")); + + editMenu = new wxMenu(); + editMenu->Append(MNU_COPY, _("&Copy\tCtrl-C"), _("Copy selected text to clipboard"), wxITEM_NORMAL); + + menuBar->Append(editMenu, _("&Edit")); + + actionMenu = new wxMenu(); + actionMenu->Append(MNU_REFRESH, _("Refresh\tCtrl-R"), _("Refresh the selected panel"), wxITEM_NORMAL); + actionMenu->AppendSeparator(); + actionMenu->Append(MNU_COPY_QUERY, _("Copy to query tool\tCtrl-Shift-C"), _("Open the query tool with the selected query"), wxITEM_NORMAL); + actionMenu->Append(MNU_CANCEL, _("Cancel query\tDel"), _("Cancel the selected query"), wxITEM_NORMAL); + actionMenu->Append(MNU_TERMINATE, _("Terminate backend\tShift-Del"), _("Terminate the selected backend"), wxITEM_NORMAL); + actionMenu->AppendSeparator(); + actionMenu->Append(MNU_COMMIT, _("Commit prepared transaction"), _("Commit the selected prepared transaction"), wxITEM_NORMAL); + actionMenu->Append(MNU_ROLLBACK, _("Rollback prepared transaction"), _("Rollback the selected prepared transaction"), wxITEM_NORMAL); + + menuBar->Append(actionMenu, _("&Action")); + + viewMenu = new wxMenu(); + viewMenu->Append(MNU_STATUSPAGE, _("&Activity\tCtrl-Alt-A"), _("Show or hide the activity tab."), wxITEM_CHECK); + viewMenu->Append(MNU_LOCKPAGE, _("&Locks\tCtrl-Alt-L"), _("Show or hide the locks tab."), wxITEM_CHECK); + viewMenu->Append(MNU_XACTPAGE, _("Prepared &Transactions\tCtrl-Alt-T"), _("Show or hide the prepared transactions tab."), wxITEM_CHECK); + viewMenu->Append(MNU_LOGPAGE, _("Log&file\tCtrl-Alt-F"), _("Show or hide the logfile tab."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_QUERYSTATEPAGE, _("&Query state\tCtrl-Alt-Q"), _("Show or hide the query state tab."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATEVERBOSE, _("Append verbose"), _("Append verbose."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATEBUFFER, _("Append use buffers"), _("Append use buffers."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATETIME, _("Append real timing"), _("Append real timing."), wxITEM_CHECK); + viewMenu->Append(MNU_QUERYSTATETRIGGER, _("Append triggers"), _("Append triggers."), wxITEM_CHECK); + + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_TOOLBAR, _("Tool&bar\tCtrl-Alt-B"), _("Show or hide the toolbar."), wxITEM_CHECK); + viewMenu->Append(MNU_HIGHLIGHTSTATUS, _("Highlight items of the activity list"), _("Highlight or not the items of the activity list."), wxITEM_CHECK); + viewMenu->AppendSeparator(); + viewMenu->Append(MNU_DEFAULTVIEW, _("&Default view\tCtrl-Alt-V"), _("Restore the default view.")); + + menuBar->Append(viewMenu, _("&View")); + + wxMenu *helpMenu = new wxMenu(); + helpMenu->Append(MNU_CONTENTS, _("&Help contents"), _("Open the helpfile.")); + helpMenu->Append(MNU_HELP, _("&Server status help"), _("Display help on this window.")); + +#ifdef __WXMAC__ + menuFactories = new menuFactoryList(); + aboutFactory *af = new aboutFactory(menuFactories, helpMenu, 0); + wxApp::s_macAboutMenuItemId = af->GetId(); + menuFactories->RegisterMenu(this, wxCommandEventHandler(pgFrame::OnAction)); +#endif + + menuBar->Append(helpMenu, _("&Help")); + + // Setup edit menu + editMenu->Enable(MNU_COPY, false); + + // Finish menu bar + SetMenuBar(menuBar); + + // Set statusBar + statusBar = CreateStatusBar(1); + SetStatusBarPane(-1); + + // Set up toolbar + toolBar = new ctlMenuToolbar(this, -1, wxDefaultPosition, wxDefaultSize, wxTB_FLAT | wxTB_NODIVIDER); + toolBar->SetToolBitmapSize(wxSize(16, 16)); + toolBar->AddTool(MNU_REFRESH, wxEmptyString, *readdata_png_bmp, _("Refresh"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_COPY, wxEmptyString, *clip_copy_png_bmp, _("Copy selected text to clipboard"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COPY_QUERY, wxEmptyString, *clip_copy_png_bmp, _("Open the query tool with the selected query"), wxITEM_NORMAL); + toolBar->AddSeparator(); + toolBar->AddTool(MNU_CANCEL, wxEmptyString, *query_cancel_png_bmp, _("Cancel query"), wxITEM_NORMAL); + toolBar->AddTool(MNU_TERMINATE, wxEmptyString, *terminate_backend_png_bmp, _("Terminate backend"), wxITEM_NORMAL); + toolBar->AddTool(MNU_COMMIT, wxEmptyString, *storedata_png_bmp, _("Commit transaction"), wxITEM_NORMAL); + toolBar->AddTool(MNU_ROLLBACK, wxEmptyString, *delete_png_bmp, _("Rollback transaction"), wxITEM_NORMAL); + toolBar->AddSeparator(); + cbLogfiles = new wxComboBox(toolBar, CTL_LOGCBO, wxT(""), wxDefaultPosition, wxDefaultSize, 0, NULL, + wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbLogfiles); + btnRotateLog = new wxButton(toolBar, CTL_ROTATEBTN, _("Rotate")); + toolBar->AddControl(btnRotateLog); + toolBar->AddSeparator(); + cbRate = new wxComboBox(toolBar, CTL_RATECBO, wxEmptyString, wxDefaultPosition, wxSize(-1, -1), wxArrayString(), wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbRate); + toolBar->AddSeparator(); + cbDatabase = new ctlComboBoxFix(toolBar, CTRLID_DATABASE, wxDefaultPosition, wxSize(-1, -1), wxCB_READONLY | wxCB_DROPDOWN); + toolBar->AddControl(cbDatabase); + toolBar->Realize(); + + // Append items to cbo + cbRate->Append(_("Don't refresh")); + cbRate->Append(_("1 second")); + cbRate->Append(_("5 seconds")); + cbRate->Append(_("10 seconds")); + cbRate->Append(_("30 seconds")); + cbRate->Append(_("1 minute")); + cbRate->Append(_("5 minutes")); + cbRate->Append(_("10 minutes")); + cbRate->Append(_("30 minutes")); + cbRate->Append(_("1 hour")); + + // Disable toolbar's items + toolBar->EnableTool(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + toolBar->EnableTool(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_CANCEL, false); + actionMenu->Enable(MNU_TERMINATE, false); + actionMenu->Enable(MNU_COMMIT, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + // Add the database combobox + pgSet *dataSet1 = connection->ExecuteSet(wxT("SELECT datname FROM pg_database WHERE datallowconn ORDER BY datname")); + while (!dataSet1->Eof()) + { + cbDatabase->Append(dataSet1->GetVal(wxT("datname"))); + dataSet1->MoveNext(); + } + delete dataSet1; + + // Image list for all listviews + listimages = new wxImageList(13, 8, true, 2); + listimages->Add(*down_png_ico); + listimages->Add(*up_png_ico); + + // Create panel + AddStatusPane(); + AddLockPane(); + AddXactPane(); + AddQuerystatePane(); + AddLogPane(); + + manager.AddPane(toolBar, wxAuiPaneInfo().Name(wxT("toolBar")).Caption(_("Tool bar")).ToolbarPane().Top().LeftDockable(false).RightDockable(false)); + + // Now load the layout + wxString perspective; + settings->Read(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), &perspective, FRMSTATUS_DEFAULT_PERSPECTIVE); + manager.LoadPerspective(perspective, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("Activity")).Caption(_("Activity")); + manager.GetPane(wxT("Locks")).Caption(_("Locks")); + manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); + manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); + manager.GetPane(wxT("Querystate")).Caption(_("QueryState")); + + // Tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); + viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); + viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); + viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE installed_version is not null and name='pg_query_state'")); + viewMenu->Enable(MNU_QUERYSTATEPAGE,set->NumRows() == 1); + //viewMenu->Check(MNU_QUERYSTATEPAGE,set->NumRows() == 1); + delete set; + + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + // + if (!viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) { + manager.GetPane(wxT("Querystate")).Hide(); + } else manager.GetPane(wxT("Querystate")).Show(); + viewMenu->Check(MNU_QUERYSTATEPAGE,manager.GetPane(wxT("Querystate")).IsShown()); + // Read the highlight status checkbox + settings->Read(wxT("frmStatus/HighlightStatus"), &highlight, true); + viewMenu->Check(MNU_HIGHLIGHTSTATUS, highlight); + bool qu_status; + settings->Read(wxT("frmStatus/QuerystateVerboseStatus"), &qu_status, false); + viewMenu->Check(MNU_QUERYSTATEVERBOSE, qu_status); + settings->Read(wxT("frmStatus/QuerystateTimeStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATETIME, qu_status); + settings->Read(wxT("frmStatus/QuerystateBufferStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATEBUFFER, qu_status); + settings->Read(wxT("frmStatus/QuerystateTriggerStatus"), &qu_status, true); + viewMenu->Check(MNU_QUERYSTATETRIGGER, qu_status); + + + // Get our PID + backend_pid = connection->GetBackendPID(); + + // Create the refresh timer (quarter of a second) + // This is a horrible hack to get around the lack of a + // PANE_ACTIVATED event in wxAUI. + refreshUITimer = new wxTimer(this, TIMER_REFRESHUI_ID); + refreshUITimer->Start(250); + + // The selected pane is the log pane by default + // so enable/disable the widgets according to this + wxListEvent nullevent; + OnSelLogItem(nullevent); + + // We're good now + loaded = true; +} + + +frmStatus::~frmStatus() +{ + // Delete the refresh timer + delete refreshUITimer; + + // If the status window wasn't launched in standalone mode... + if (mainForm) + mainForm->RemoveFrame(this); + + // Save the window's position + settings->Write(wxT("frmStatus/Perspective-") + wxString(FRMSTATUS_PERSPECTIVE_VER), manager.SavePerspective()); + manager.UnInit(); + SavePosition(); + + // Save the highlight status checkbox + settings->WriteBool(wxT("frmStatus/HighlightStatus"), viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)); + settings->WriteBool(wxT("frmStatus/QuerystateVerboseStatus"), viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)); + settings->WriteBool(wxT("frmStatus/QuerystateTimeStatus"), viewMenu->IsChecked(MNU_QUERYSTATETIME)); + settings->WriteBool(wxT("frmStatus/QuerystateBufferStatus"), viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)); + settings->WriteBool(wxT("frmStatus/QuerystateTriggerStatus"), viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)); + + + + // For each current page, save the slider's position and delete the timer + settings->WriteInt(wxT("frmStatus/RefreshStatusRate"), statusRate); + delete statusTimer; + settings->WriteInt(wxT("frmStatus/RefreshLockRate"), locksRate); + delete locksTimer; + if (viewMenu->IsEnabled(MNU_XACTPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshXactRate"), xactRate); + if (xactTimer) + { + delete xactTimer; + xactTimer = NULL; + } + } + if (viewMenu->IsEnabled(MNU_LOGPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshLogRate"), logRate); + emptyLogfileCombo(); + if (logTimer) + { + delete logTimer; + logTimer = NULL; + } + } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE)) + { + settings->WriteInt(wxT("frmStatus/RefreshQuerystateRate"), querystateRate); + if (querystateTimer) + { + delete querystateTimer; + querystateTimer = NULL; + } + } + + // If connection is still available, delete it + if (locks_connection && locks_connection != connection) + { + if (locks_connection->IsAlive()) + delete locks_connection; + } + if (connection) + { + if (connection->IsAlive()) + delete connection; + } +} + + +void frmStatus::Go() +{ + // Show the window + Show(true); + + // Send RateChange event to launch each timer + wxScrollEvent nullScrollEvent; + if (viewMenu->IsChecked(MNU_STATUSPAGE)) + { + currentPane = PANE_STATUS; + cbRate->SetValue(rateToCboString(statusRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsChecked(MNU_LOCKPAGE)) + { + currentPane = PANE_LOCKS; + cbRate->SetValue(rateToCboString(locksRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) + { + currentPane = PANE_XACT; + cbRate->SetValue(rateToCboString(xactRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) + { + currentPane = PANE_LOG; + cbRate->SetValue(rateToCboString(logRate)); + OnRateChange(nullScrollEvent); + } + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) + { + currentPane = PANE_QUERYSTATE; + cbRate->SetValue(rateToCboString(querystateRate)); + OnRateChange(nullScrollEvent); + } + + // Refresh all pages + wxCommandEvent nullEvent; + OnRefresh(nullEvent); +} + + +void frmStatus::OnClose(wxCloseEvent &event) +{ + Destroy(); +} + + +void frmStatus::OnExit(wxCommandEvent &event) +{ + Destroy(); +} + + +void frmStatus::OnChangeDatabase(wxCommandEvent &ev) +{ + wxString initquery; + + if (locks_connection != connection) + { + delete locks_connection; + } + + locks_connection = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), cbDatabase->GetValue(), + connection->GetUser(), connection->GetPassword(), connection->GetPort(), connection->GetRole(), connection->GetSslMode(), + 0, connection->GetApplicationName(), connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); + + pgUser *user = new pgUser(locks_connection->GetUser()); + if (user) + { + if (user->GetSuperuser()) + { + if (locks_connection->BackendMinimumVersion(8, 0)) + initquery = wxT("SET log_statement='none';SET log_duration='off';SET log_min_duration_statement=-1;"); + else + initquery = wxT("SET log_statement='off';SET log_duration='off';SET log_min_duration_statement=-1;"); + locks_connection->ExecuteVoid(initquery, false); + } + delete user; + } +} + + +void frmStatus::AddStatusPane() +{ + // Create panel + wxPanel *pnlActivity = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdActivity = new wxFlexGridSizer(1, 1, 5, 5); + grdActivity->AddGrowableCol(0); + grdActivity->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstStatus = new wxListCtrl(pnlActivity, CTL_STATUSLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdActivity->Add(lstStatus, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlActivity, + wxAuiPaneInfo(). + Name(wxT("Activity")).Caption(_("Activity")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlActivity->SetSizer(grdActivity); + grdActivity->Fit(pnlActivity); + + // Add each column to the list control + statusList = (ctlListView *)lstStatus; + statusList->AddColumn(_("PID"), 35); + if (connection->BackendMinimumVersion(8, 5)) + statusList->AddColumn(_("Application name"), 70); + statusList->AddColumn(_("Database"), 70); + statusList->AddColumn(_("User"), 70); + if (connection->BackendMinimumVersion(8, 1)) + { + statusList->AddColumn(_("Client"), 70); + statusList->AddColumn(_("Client start"), 80); + } + if (connection->BackendMinimumVersion(7, 4)) + statusList->AddColumn(_("Query start"), 50); + if (connection->BackendMinimumVersion(8, 3)) + statusList->AddColumn(_("TX start"), 50); + if (connection->BackendMinimumVersion(9, 2)) + { + statusList->AddColumn(_("State"), 35); + statusList->AddColumn(_("State change"), 35); + } + if (connection->BackendMinimumVersion(9, 4)) + { + statusList->AddColumn(_("Backend XID"), 35); + statusList->AddColumn(_("Backend XMin"), 35); + } + if (connection->BackendMinimumVersion(9, 6)) + { + statusList->AddColumn(_("W_Event_T"), 35); + statusList->AddColumn(_("W_Event"), 35); + } + statusList->AddColumn(_("Blocked by"), 35); + statusList->AddColumn(_("Query"), 500); + + // Get through the list of columns to build the popup menu + // and reinitialize column's width if we find a saved width + statusPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < statusList->GetColumnCount(); col++) + { + // Get column + statusList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/StatusPane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + statusList->SetColumnWidth(col, savedwidth); + else + statusList->SetColumnWidth(col, 0); + statusColWidth[col] = savedwidth; + + // Add new check item on the popup menu + statusPopupMenu->AppendCheckItem(1000 + col, item.GetText()); + statusPopupMenu->Check(1000 + col, statusList->GetColumnWidth(col) > 0); + this->Connect(1000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnStatusMenu)); + } + + // Build image list + statusList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read statusRate configuration + settings->Read(wxT("frmStatus/RefreshStatusRate"), &statusRate, 10); + + // Initialize sort order + statusSortColumn = 1; + statusSortOrder = wxT("ASC"); + + // Create the timer + statusTimer = new wxTimer(this, TIMER_STATUS_ID); +} + + +void frmStatus::AddLockPane() +{ + // Create panel + wxPanel *pnlLock = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdLock = new wxFlexGridSizer(1, 1, 5, 5); + grdLock->AddGrowableCol(0); + grdLock->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstLocks = new wxListCtrl(pnlLock, CTL_LOCKLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdLock->Add(lstLocks, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlLock, + wxAuiPaneInfo(). + Name(wxT("Locks")).Caption(_("Locks")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlLock->SetSizer(grdLock); + grdLock->Fit(pnlLock); + + // Add each column to the list control + lockList = (ctlListView *)lstLocks; + lockList->AddColumn(wxT("PID"), 35); + lockList->AddColumn(_("Database"), 50); + lockList->AddColumn(_("Relation"), 50); + lockList->AddColumn(_("User"), 50); + if (locks_connection->BackendMinimumVersion(8, 3)) + lockList->AddColumn(_("XID"), 50); + lockList->AddColumn(_("TX"), 50); + lockList->AddColumn(_("Mode"), 50); + lockList->AddColumn(_("Granted"), 50); + if (locks_connection->BackendMinimumVersion(7, 4)) + lockList->AddColumn(_("Start"), 50); + lockList->AddColumn(_("Query"), 500); + + // Get through the list of columns to build the popup menu + lockPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < lockList->GetColumnCount(); col++) + { + // Get column + lockList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/LockPane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + lockList->SetColumnWidth(col, savedwidth); + else + lockList->SetColumnWidth(col, 0); + lockColWidth[col] = savedwidth; + + // Add new check item on the popup menu + lockPopupMenu->AppendCheckItem(2000 + col, item.GetText()); + lockPopupMenu->Check(2000 + col, lockList->GetColumnWidth(col) > 0); + this->Connect(2000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnLockMenu)); + } + + // Build image list + lockList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read locksRate configuration + settings->Read(wxT("frmStatus/RefreshLockRate"), &locksRate, 10); + + // Initialize sort order + lockSortColumn = 1; + lockSortOrder = wxT("ASC"); + + // Create the timer + locksTimer = new wxTimer(this, TIMER_LOCKS_ID); +} + + +void frmStatus::AddXactPane() +{ + // Create panel + wxPanel *pnlXacts = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdXacts = new wxFlexGridSizer(1, 1, 5, 5); + grdXacts->AddGrowableCol(0); + grdXacts->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstXacts = new wxListCtrl(pnlXacts, CTL_XACTLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdXacts->Add(lstXacts, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlXacts, + wxAuiPaneInfo(). + Name(wxT("Transactions")).Caption(_("Transactions")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlXacts->SetSizer(grdXacts); + grdXacts->Fit(pnlXacts); + + // Add the xact list + xactList = (ctlListView *)lstXacts; + + // We don't need this report if server release is less than 8.1 + // GPDB doesn't have external global transactions. + // Perhaps we should use this display to show our + // global xid to local xid mappings? + if (!connection->BackendMinimumVersion(8, 1) || connection->GetIsGreenplum()) + { + // manager.GetPane(wxT("Transactions")).Show(false); + lstXacts->InsertColumn(lstXacts->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800); + lstXacts->InsertItem(lstXacts->GetItemCount(), _("Prepared transactions not available on this server."), -1); + lstXacts->Enable(false); + xactTimer = NULL; + + // We're done + return; + } + + // Add each column to the list control + xactList->AddColumn(wxT("XID"), 50); + xactList->AddColumn(_("Global ID"), 200); + xactList->AddColumn(_("Time"), 100); + xactList->AddColumn(_("Owner"), 50); + xactList->AddColumn(_("Database"), 50); + + // Get through the list of columns to build the popup menu + xactPopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < xactList->GetColumnCount(); col++) + { + // Get column + xactList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/XactPane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + xactList->SetColumnWidth(col, savedwidth); + else + xactList->SetColumnWidth(col, 0); + xactColWidth[col] = savedwidth; + + // Add new check item on the popup menu + xactPopupMenu->AppendCheckItem(3000 + col, item.GetText()); + xactPopupMenu->Check(3000 + col, xactList->GetColumnWidth(col) > 0); + this->Connect(3000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnXactMenu)); + } + + // Build image list + xactList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read xactRate configuration + settings->Read(wxT("frmStatus/RefreshXactRate"), &xactRate, 10); + + // Initialize sort order + xactSortColumn = 2; + xactSortOrder = wxT("ASC"); + + // Create the timer + xactTimer = new wxTimer(this, TIMER_XACT_ID); +} +void frmStatus::AddQuerystatePane() +{ + // Create panel + wxPanel *pnlQuerystate = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdQuerystate = new wxFlexGridSizer(1, 1, 5, 5); + grdQuerystate->AddGrowableCol(0); + grdQuerystate->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstQuerystate = new wxListCtrl(pnlQuerystate, CTL_QUERYSTATELIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdQuerystate->Add(lstQuerystate, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlQuerystate, + wxAuiPaneInfo().Center(). + Name(wxT("Querystate")).Caption(_("Query State")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlQuerystate->SetSizer(grdQuerystate); + grdQuerystate->Fit(pnlQuerystate); + + // Add the xact list + querystateList = (ctlListView *)lstQuerystate; + + // Add each column to the list control + querystateList->AddColumn(wxT("Pid"), 20); + querystateList->AddColumn(wxT("Fn"), 20); + querystateList->AddColumn(_("Query Text"), 200); + querystateList->AddColumn(_("Plan"), 300); + querystateList->AddColumn(wxT("Leader_pid"), 20); + + + // Get through the list of columns to build the popup menu + querystatePopupMenu = new wxMenu(); + wxListItem item; + item.SetMask(wxLIST_MASK_TEXT); + int savedwidth; + for (int col = 0; col < querystateList->GetColumnCount(); col++) + { + // Get column + querystateList->GetColumn(col, item); + + // Reinitialize column's width + settings->Read(wxT("frmStatus/QuerystatePane_") + item.GetText() + wxT("_Width"), &savedwidth, item.GetWidth()); + if (savedwidth > 0) + querystateList->SetColumnWidth(col, savedwidth); + else + querystateList->SetColumnWidth(col, 0); + querystateColWidth[col] = savedwidth; + + // Add new check item on the popup menu + querystatePopupMenu->AppendCheckItem(4000 + col, item.GetText()); + querystatePopupMenu->Check(4000 + col, querystateList->GetColumnWidth(col) > 0); + this->Connect(4000 + col, wxEVT_COMMAND_MENU_SELECTED, + wxCommandEventHandler(frmStatus::OnQuerystateMenu)); + } + + // Build image list + querystateList->SetImageList(listimages, wxIMAGE_LIST_SMALL); + + // Read querystateRate configuration + settings->Read(wxT("frmStatus/RefreshQuerystateRate"), &querystateRate, 10); + + // Initialize sort order + //QuerystateortColumn = 2; + //QuerystateortOrder = wxT("ASC"); + + // Create the timer + querystateTimer = new wxTimer(this, TIMER_QUERYSTATE_ID); + + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE installed_version is not null and name='pg_query_state'")); + if (set->NumRows() == 1) + viewMenu->Check(MNU_QUERYSTATEPAGE,true); + else + viewMenu->Check(MNU_QUERYSTATEPAGE,false); + delete set; + +} + + +void frmStatus::AddLogPane() +{ + int rc = -1; + wxString hint = HINT_INSTRUMENTATION; + + // Create panel + wxPanel *pnlLog = new wxPanel(this); + + // Create flex grid + wxFlexGridSizer *grdLog = new wxFlexGridSizer(1, 1, 5, 5); + grdLog->AddGrowableCol(0); + grdLog->AddGrowableRow(0); + + // Add the list control +#ifdef __WXMAC__ + // Switch to the generic list control. + // Disable sort on Mac. + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), true); +#endif + wxListCtrl *lstLog = new wxListCtrl(pnlLog, CTL_LOGLIST, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSUNKEN_BORDER); + // Now switch back +#ifdef __WXMAC__ + wxSystemOptions::SetOption(wxT("mac.listctrl.always_use_generic"), false); +#endif + grdLog->Add(lstLog, 0, wxGROW, 3); + + // Add the panel to the notebook + manager.AddPane(pnlLog, + wxAuiPaneInfo().Center(). + Name(wxT("Logfile")).Caption(_("Logfile")). + CaptionVisible(true).CloseButton(true).MaximizeButton(true). + Dockable(true).Movable(true)); + + // Auto-sizing + pnlLog->SetSizer(grdLog); + grdLog->Fit(pnlLog); + + // Add the log list + logList = (ctlListView *)lstLog; + + // We don't need this report (but we need the pane) + // if server release is less than 8.0 or if server has no adminpack + if (!(connection->BackendMinimumVersion(8, 0) && + connection->HasFeature(FEATURE_FILEREAD))) + { + // if the server release is 9.1 or more and the server has no adminpack + if (connection->BackendMinimumVersion(9, 1)) + { + // Search the adminpack extension + pgSet *set = connection->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='adminpack'")); + if (set->NumRows() == 1) + hint = HINT_INSTRUMENTATION_91_WITH; + else + hint = HINT_INSTRUMENTATION_91_WITHOUT; + delete set; + } + + if (connection->BackendMinimumVersion(8, 0)) + rc = frmHint::ShowHint(this, hint); + + if (rc == HINT_RC_FIX) + connection->ExecuteVoid(wxT("CREATE EXTENSION adminpack"), true); + + if (!connection->HasFeature(FEATURE_FILEREAD, true)) + { + logList->InsertColumn(logList->GetColumnCount(), _("Message"), wxLIST_FORMAT_LEFT, 800); + logList->InsertItem(logList->GetItemCount(), _("Logs are not available for this server."), -1); + logList->Enable(false); + logTimer = NULL; + // We're done + return; + } + } + + // Add each column to the list control + logFormat = connection->ExecuteScalar(wxT("SHOW log_line_prefix")); + if (logFormat == wxT("unset")) + logFormat = wxEmptyString; + logFmtPos = logFormat.Find('%', true); + + if (logFmtPos < 0) + logFormatKnown = true; // log_line_prefix not specified. + else if (!logFmtPos && logFormat.Mid(logFmtPos, 2) == wxT("%t") && logFormat.Length() > 2) // Timestamp at end of log_line_prefix? + { + logFormatKnown = true; + logHasTimestamp = true; + } + else if (connection->GetIsGreenplum()) + { + // Always %m|%u|%d|%p|%I|%X|:- (timestamp w/ millisec) for 3.2.x + // Usually CSV formatted for 3.3 + logFormatKnown = true; + logHasTimestamp = true; + } + + + if (connection->GetIsGreenplum() && connection->BackendMinimumVersion(8, 2, 13)) + { + // Be ready for GPDB CSV format log file + logList->AddColumn(_("Timestamp"), 120); // Room for millisecs + logList->AddColumn(_("Level"), 35); + logList->AddColumn(_("Log entry"), 400); + logList->AddColumn(_("Connection"), 45); + logList->AddColumn(_("Cmd number"), 48); + logList->AddColumn(_("Dbname"), 48); + logList->AddColumn(_("Segment"), 45); + } + else // Non-GPDB or non-CSV format log + { + if (logHasTimestamp) + logList->AddColumn(_("Timestamp"), 100); + + if (logFormatKnown) + logList->AddColumn(_("Level"), 35); + + logList->AddColumn(_("Log entry"), 800); + } + + if (!connection->HasFeature(FEATURE_ROTATELOG)) + btnRotateLog->Disable(); + + // Re-initialize variables + logfileLength = 0; + + // Read logRate configuration + settings->Read(wxT("frmStatus/RefreshLogRate"), &logRate, 10); + + // Create the timer + logTimer = new wxTimer(this, TIMER_LOG_ID); +} + + +void frmStatus::OnCopy(wxCommandEvent &ev) +{ + ctlListView *list; + int row, col; + wxString text; + + switch(currentPane) + { + case PANE_STATUS: + list = statusList; + break; + case PANE_LOCKS: + list = lockList; + break; + case PANE_XACT: + list = xactList; + break; + case PANE_LOG: + list = logList; + break; + case PANE_QUERYSTATE: + list = querystateList; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + if (currentPane==PANE_QUERYSTATE) { + wxString s; + for (row = 0; row < list->GetItemCount(); row++) + { + s=list->GetText(row, 2); + if (s.Length()>0) { + text.Append(wxT("SQL QUERY: ")).Append(s); + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + } + text.Append(list->GetText(row, 3)); + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + } +// list->GetText(row,3); + } else + { + row = list->GetFirstSelected(); + + while (row >= 0) + { + for (col = 0; col < list->GetColumnCount(); col++) + { + text.Append(list->GetText(row, col) + wxT("\t")); + } + #ifdef __WXMSW__ + text.Append(wxT("\r\n")); + #else + text.Append(wxT("\n")); + #endif + row = list->GetNextSelected(row); + } + } + if (text.Length() > 0 && wxTheClipboard->Open()) + { + wxTheClipboard->SetData(new wxTextDataObject(text)); + wxTheClipboard->Close(); + } +} + + +void frmStatus::OnCopyQuery(wxCommandEvent &ev) +{ + ctlListView *list; + int row, col; + wxString text = wxT(""); + wxString dbname = wxT(""); + unsigned int maxlength; + + // Only the status list shows the query + list = statusList; + + // Get the database + row = list->GetFirstSelected(); + col = connection->BackendMinimumVersion(9, 0) ? 2 : 1; + dbname.Append(list->GetText(row, col)); + + // Get the actual query + row = list->GetFirstSelected(); + text.Append(queries.Item(row)); + + // Check if we have a query whose length is maximum + maxlength = 1024; + if (connection->BackendMinimumVersion(8, 4)) + { + pgSet *set; + set = connection->ExecuteSet(wxT("SELECT setting FROM pg_settings\n") + wxT(" WHERE name='track_activity_query_size'")); + if (set) + { + maxlength = set->GetLong(0); + delete set; + } + } + + if (text.Length() == maxlength) + { + wxLogError(_("The query you copied is at the maximum length.\nIt may have been truncated.")); + } + + // If we have some real query, launch the query tool + if (text.Length() > 0 && dbname.Length() > 0 + && text.Trim() != wxT("") && text.Trim() != wxT("")) + { + pgConn *conn = new pgConn(connection->GetHostName(), connection->GetService(), connection->GetHostAddr(), dbname, + connection->GetUser(), connection->GetPassword(), + connection->GetPort(), connection->GetRole(), connection->GetSslMode(), connection->GetDbOid(), + connection->GetApplicationName(), + connection->GetSSLCert(), connection->GetSSLKey(), connection->GetSSLRootCert(), connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (conn) + { + frmQuery *fq = new frmQuery(mainForm, wxEmptyString, conn, text); + fq->Go(); + mainForm->AddFrame(fq); + } + } +} + + +void frmStatus::OnPaneClose(wxAuiManagerEvent &evt) +{ + if (evt.pane->name == wxT("Activity")) + { + viewMenu->Check(MNU_STATUSPAGE, false); + statusTimer->Stop(); + } + if (evt.pane->name == wxT("Locks")) + { + viewMenu->Check(MNU_LOCKPAGE, false); + locksTimer->Stop(); + } + if (evt.pane->name == wxT("Transactions")) + { + viewMenu->Check(MNU_XACTPAGE, false); + if (xactTimer) + xactTimer->Stop(); + } + if (evt.pane->name == wxT("Logfile")) + { + viewMenu->Check(MNU_LOGPAGE, false); + if (logTimer) + logTimer->Stop(); + } + if (evt.pane->name == wxT("Querystate")) + { + viewMenu->Check(MNU_QUERYSTATEPAGE, false); + if (querystateTimer) + querystateTimer->Stop(); + } +} + + +void frmStatus::OnToggleStatusPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_STATUSPAGE)) + { + manager.GetPane(wxT("Activity")).Show(true); + cbRate->SetValue(rateToCboString(statusRate)); + if (statusRate > 0) + statusTimer->Start(statusRate * 1000L); + } + else + { + manager.GetPane(wxT("Activity")).Show(false); + statusTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleLockPane(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_LOCKPAGE)) + { + manager.GetPane(wxT("Locks")).Show(true); + cbRate->SetValue(rateToCboString(locksRate)); + if (locksRate > 0) + locksTimer->Start(locksRate * 1000L); + } + else + { + manager.GetPane(wxT("Locks")).Show(false); + locksTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleXactPane(wxCommandEvent &event) +{ + if (viewMenu->IsEnabled(MNU_XACTPAGE) && viewMenu->IsChecked(MNU_XACTPAGE)) + { + manager.GetPane(wxT("Transactions")).Show(true); + cbRate->SetValue(rateToCboString(xactRate)); + if (xactRate > 0 && xactTimer) + xactTimer->Start(xactRate * 1000L); + } + else + { + manager.GetPane(wxT("Transactions")).Show(false); + if (xactTimer) + xactTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleLogPane(wxCommandEvent &event) +{ + if (viewMenu->IsEnabled(MNU_LOGPAGE) && viewMenu->IsChecked(MNU_LOGPAGE)) + { + manager.GetPane(wxT("Logfile")).Show(true); + cbRate->SetValue(rateToCboString(logRate)); + if (logRate > 0 && logTimer) + logTimer->Start(logRate * 1000L); + } + else + { + manager.GetPane(wxT("Logfile")).Show(false); + if (logTimer) + logTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} +void frmStatus::OnToggleQuerystatePane(wxCommandEvent &event) +{ + if (viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) && viewMenu->IsChecked(MNU_QUERYSTATEPAGE)) + { + manager.GetPane(wxT("Querystate")).Show(true); + cbRate->SetValue(rateToCboString(querystateRate)); + if (querystateRate > 0 && querystateTimer) + querystateTimer->Start(querystateRate * 1000L); + } + else + { + manager.GetPane(wxT("Querystate")).Show(false); + if (querystateTimer) + querystateTimer->Stop(); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnToggleToolBar(wxCommandEvent &event) +{ + if (viewMenu->IsChecked(MNU_TOOLBAR)) + { + manager.GetPane(wxT("toolBar")).Show(true); + } + else + { + manager.GetPane(wxT("toolBar")).Show(false); + } + + // Tell the manager to "commit" all the changes just made + manager.Update(); +} + + +void frmStatus::OnDefaultView(wxCommandEvent &event) +{ + manager.LoadPerspective(FRMSTATUS_DEFAULT_PERSPECTIVE, true); + + // Reset the captions for the current language + manager.GetPane(wxT("toolBar")).Caption(_("Tool bar")); + manager.GetPane(wxT("Activity")).Caption(_("Activity")); + manager.GetPane(wxT("Locks")).Caption(_("Locks")); + manager.GetPane(wxT("Transactions")).Caption(_("Prepared Transactions")); + manager.GetPane(wxT("Logfile")).Caption(_("Logfile")); + manager.GetPane(wxT("Querystate")).Caption(_("Query State")); + + // tell the manager to "commit" all the changes just made + manager.Update(); + + // Sync the View menu options + viewMenu->Check(MNU_TOOLBAR, manager.GetPane(wxT("toolBar")).IsShown()); + viewMenu->Check(MNU_STATUSPAGE, manager.GetPane(wxT("Activity")).IsShown()); + viewMenu->Check(MNU_LOCKPAGE, manager.GetPane(wxT("Locks")).IsShown()); + viewMenu->Check(MNU_XACTPAGE, manager.GetPane(wxT("Transactions")).IsShown()); + viewMenu->Check(MNU_LOGPAGE, manager.GetPane(wxT("Logfile")).IsShown()); + viewMenu->Check(MNU_QUERYSTATEPAGE, manager.GetPane(wxT("Querystate")).IsShown()); +} + + +void frmStatus::OnHighlightStatus(wxCommandEvent &event) +{ + wxTimerEvent evt; + + OnRefreshStatusTimer(evt); +} +void frmStatus::OnEmptyAction(wxCommandEvent &event) +{ +} + + +void frmStatus::OnHelp(wxCommandEvent &ev) +{ + DisplayHelp(wxT("status"), HELP_PGADMIN); +} + + +void frmStatus::OnContents(wxCommandEvent &ev) +{ + DisplayHelp(wxT("index"), HELP_PGADMIN); +} + +void frmStatus::OnRateChange(wxCommandEvent &event) +{ + wxTimer *timer; + int rate; + + switch(currentPane) + { + case PANE_STATUS: + timer = statusTimer; + rate = cboToRate(); + statusRate = rate; + break; + case PANE_LOCKS: + timer = locksTimer; + rate = cboToRate(); + locksRate = rate; + break; + case PANE_XACT: + timer = xactTimer; + rate = cboToRate(); + xactRate = rate; + break; + case PANE_LOG: + timer = logTimer; + rate = cboToRate(); + logRate = rate; + break; + case PANE_QUERYSTATE: + timer = querystateTimer; + rate = cboToRate(); + querystateRate = rate; + break; + default: + // This shouldn't happen. + // If it does, it's no big deal, we just need to get out. + return; + break; + } + + if (timer) + { + timer->Stop(); + if (rate > 0) + timer->Start(rate * 1000L); + } + OnRefresh(event); +} + + +void frmStatus::OnRefreshUITimer(wxTimerEvent &event) +{ + wxListEvent evt; + + refreshUITimer->Stop(); + + for (unsigned int i = 0; i < manager.GetAllPanes().GetCount(); i++) + { + wxAuiPaneInfo &pane = manager.GetAllPanes()[i]; + + if (pane.HasFlag(wxAuiPaneInfo::optionActive)) + { + if (pane.name == wxT("Activity") && currentPane != PANE_STATUS) + { + OnSelStatusItem(evt); + } + if (pane.name == wxT("Locks") && currentPane != PANE_LOCKS) + { + OnSelLockItem(evt); + } + if (pane.name == wxT("Transactions") && currentPane != PANE_XACT) + { + OnSelXactItem(evt); + } + if (pane.name == wxT("Logfile") && currentPane != PANE_LOG) + { + OnSelLogItem(evt); + } + if (pane.name == wxT("Querystate") && currentPane != PANE_QUERYSTATE) + { + OnSelQuerystateItem(evt); + } + } + } + + refreshUITimer->Start(250); +} + + +void frmStatus::OnRefreshStatusTimer(wxTimerEvent &event) +{ + long pid = 0; + wxString pidcol = connection->BackendMinimumVersion(9, 2) ? wxT("p.pid") : wxT("p.procpid"); + wxString querycol = connection->BackendMinimumVersion(9, 2) ? wxT("query") : wxT("current_query"); + + if (! viewMenu->IsChecked(MNU_STATUSPAGE)) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + long row = 0; + wxString q = wxT("SELECT "); + + // PID + q += pidcol + wxT(" AS pid, "); + + // Application name (when available) + if (connection->BackendMinimumVersion(8, 5)) + q += wxT("application_name, "); + + // Database, and user name + q += wxT("p.datname, usename,\n"); + + // Client connection method + if (connection->BackendMinimumVersion(8, 1)) + { + q += wxT("CASE WHEN client_port=-1 THEN 'local pipe' "); + if (connection->BackendMinimumVersion(9, 1)) + q += wxT("WHEN length(client_hostname)>0 THEN client_hostname||':'||client_port "); + q += wxT("ELSE textin(inet_out(client_addr))||':'||client_port END AS client,\n"); + } + + // Backend start timestamp + if (connection->BackendMinimumVersion(8, 1)) + q += wxT("date_trunc('second', backend_start) AS backend_start, "); + + // Query start timestamp (when available) + if (connection->BackendMinimumVersion(9, 2)) + { + q += wxT("CASE WHEN state='active' THEN date_trunc('second', query_start)::text ELSE '' END "); + } + else if (connection->BackendMinimumVersion(7, 4)) + { + q += wxT("CASE WHEN ") + querycol + wxT("='' OR ") + querycol + wxT("='' THEN '' ") + wxT(" ELSE date_trunc('second', query_start)::text END "); + } + else + { + q += wxT("'' "); + } + q += wxT("AS query_start,\n"); + + // Transaction start timestamp + if (connection->BackendMinimumVersion(8, 3)) + q += wxT("date_trunc('second', xact_start) AS xact_start, "); + + // State + if (connection->BackendMinimumVersion(9, 2)) + q += wxT("state, date_trunc('second', state_change) AS state_change, "); + + // Xmin and XID + if (connection->BackendMinimumVersion(9, 4)) + q += wxT("backend_xid::text, backend_xmin::text, "); + + // Blocked by... + q += wxT("(SELECT min(l1.pid) FROM pg_locks l1 WHERE GRANTED AND (") + wxT("relation IN (SELECT relation FROM pg_locks l2 WHERE l2.pid=") + pidcol + wxT(" AND NOT granted)") + wxT(" OR ") + wxT("transactionid IN (SELECT transactionid FROM pg_locks l3 WHERE l3.pid=") + pidcol + wxT(" AND NOT granted)") + wxT(")) AS blockedby,\n"); + + // Query + q += querycol + wxT(" AS query,\n"); + + // Slow query? + if (connection->BackendMinimumVersion(9, 2)) + { + q += wxT("CASE WHEN query_start IS NULL OR state<>'active' THEN false ELSE query_start < now() - '10 seconds'::interval END "); + } + else if (connection->BackendMinimumVersion(7, 4)) + { + q += wxT("CASE WHEN query_start IS NULL OR ") + querycol + wxT(" LIKE '%' THEN false ELSE query_start < now() - '10 seconds'::interval END "); + } + else + { + q += wxT("false"); + } + q += wxT("AS slowquery\n"); + if (connection->BackendMinimumVersion(9, 6)) + { + q += wxT(",wait_event_type,wait_event,v.heap_blks_total,v.heap_blks_vacuumed,v.heap_blks_scanned,v.phase\n"); + q += wxT("FROM pg_stat_activity p LEFT JOIN pg_stat_progress_vacuum v ON p.pid=v.pid "); + } else + { + q += wxT("FROM pg_stat_activity p "); + } + + // And the rest of the query... + + q += wxT("ORDER BY ") + NumToStr((long)statusSortColumn) + wxT(" ") + statusSortOrder; + + pgSet *dataSet1 = connection->ExecuteSet(q); + if (dataSet1) + { + statusBar->SetStatusText(_("Refreshing status list.")); + statusList->Freeze(); + + // Clear the queries array content + queries.Clear(); + wxString blocked=wxT(""); + wxArrayLong pids; + while (!dataSet1->Eof()) + { + pid = dataSet1->GetLong(wxT("pid")); + // Update the UI + if (pid != backend_pid) + { + pids.Add(pid); + // Add the query content to the queries array + queries.Add(dataSet1->GetVal(wxT("query"))); + + if (row >= statusList->GetItemCount()) + { + statusList->InsertItem(row, NumToStr(pid), -1); + row = statusList->GetItemCount() - 1; + } + else + { + statusList->SetItem(row, 0, NumToStr(pid)); + } + + wxString qry = dataSet1->GetVal(wxT("query")); + wxString app_name = dataSet1->GetVal(wxT("application_name")); + if (connection->BackendMinimumVersion(9, 6)) + { + wxString heap_blks_total = dataSet1->GetVal(wxT("heap_blks_total")); + if (!heap_blks_total.IsEmpty()) { + wxString heap_blks_vacuumed = dataSet1->GetVal(wxT("heap_blks_vacuumed")); + wxString heap_blks_scanned = dataSet1->GetVal(wxT("heap_blks_scanned")); + wxString phase = dataSet1->GetVal(wxT("phase")); + double total; + double vac=0; + double proc; + heap_blks_vacuumed.ToDouble(&vac); + if (!phase.CmpNoCase(wxT("scanning heap"))) { + heap_blks_scanned.ToDouble(&vac); + } + heap_blks_total.ToDouble(&total); + proc=vac*100/total; + wxString str; + str.Printf(wxT("%s %5.2f%%"), phase, proc); + app_name=str; + } + + } + int colpos = 1; + if (connection->BackendMinimumVersion(8, 5)) + statusList->SetItem(row, colpos++, app_name); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("datname"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("usename"))); + + if (connection->BackendMinimumVersion(8, 1)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("client"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_start"))); + } + if (connection->BackendMinimumVersion(7, 4)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("query_start"))); + } + + if (connection->BackendMinimumVersion(8, 3)) + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("xact_start"))); + + if (connection->BackendMinimumVersion(9, 2)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("state_change"))); + } + + if (connection->BackendMinimumVersion(9, 4)) + { + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xid"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("backend_xmin"))); + } + if (connection->BackendMinimumVersion(9, 6)) + { + wait_event_type_col=colpos; + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event_type"))); + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("wait_event"))); + } + + statusList->SetItem(row, colpos++, dataSet1->GetVal(wxT("blockedby"))); + statusList->SetItem(row, colpos, qry); + + // Colorize the new line + if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) + { + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetActiveProcessColour())); + if (qry == wxT("") || qry == wxT(" in transaction0")) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetIdleProcessColour())); + if (connection->BackendMinimumVersion(9, 2)) + { + if (dataSet1->GetVal(wxT("state")) != wxT("active")) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetIdleProcessColour())); + } + + if (dataSet1->GetBool(wxT("slowquery"))) + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetSlowProcessColour())); + if (dataSet1->GetVal(wxT("blockedby")).Length() > 0) { + statusList->SetItemBackgroundColour(row, + wxColour(settings->GetBlockedProcessColour())); + blocked += dataSet1->GetVal(wxT("blockedby")); + blocked += wxT(","); + } + } + else + statusList->SetItemBackgroundColour(row, *wxWHITE); + + row++; + } + dataSet1->MoveNext(); + } + delete dataSet1; + if (viewMenu->IsChecked(MNU_HIGHLIGHTSTATUS)) + { + wxString numstr; + wxString str; + numstr=blocked.BeforeFirst(',',&str); + while (!numstr.IsEmpty()) { + int number = wxAtoi(numstr); + for(long i = 0; i < pids.size(); i++) + { + if (pids[i]==number) { + statusList->SetItemBackgroundColour(i, + wxColour(settings->GetBlockedbyProcessColour())); + + } + } + blocked=str.Clone(); + numstr=blocked.BeforeFirst(',',&str); + } + } + bool selverify=true; + while (row < statusList->GetItemCount()) { + statusList->Select(row,false); + long item = -1; + item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED); + if (item>=row) statusList->Focus(row-1); + statusList->DeleteItem(row); + } + statusList->Thaw(); + wxListEvent ev; + //OnSelStatusItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} + + +void frmStatus::OnRefreshLocksTimer(wxTimerEvent &event) +{ + long pid = 0; + + if (! viewMenu->IsChecked(MNU_LOCKPAGE)) + return; + + checkConnection(); + if (!locks_connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + lockSortColumn = 1; + } + + long row = 0; + wxString sql; + if (locks_connection->BackendMinimumVersion(8, 3)) + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.virtualxid::text, pgl.virtualtransaction::text AS transaction, pgl.mode, pgl.granted, ") + wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + else if (locks_connection->BackendMinimumVersion(7, 4)) + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.transaction, pgl.mode, pgl.granted, ") + wxT("date_trunc('second', pg_stat_get_backend_activity_start(svrid)) AS query_start, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + else + { + sql = wxT("SELECT pg_stat_get_backend_pid(svrid) AS pid, ") + wxT("(SELECT datname FROM pg_database WHERE oid = pgl.database) AS dbname, ") + wxT("coalesce(pgc.relname, pgl.relation::text) AS class, ") + wxT("pg_get_userbyid(pg_stat_get_backend_userid(svrid)) as user, ") + wxT("pgl.transaction, pgl.mode, pgl.granted, ") + wxT("pg_stat_get_backend_activity(svrid) AS query ") + wxT("FROM pg_stat_get_backend_idset() svrid, pg_locks pgl ") + wxT("LEFT JOIN pg_class pgc ON pgl.relation=pgc.oid ") + wxT("WHERE pgl.pid = pg_stat_get_backend_pid(svrid) ") + wxT("ORDER BY ") + NumToStr((long)lockSortColumn) + wxT(" ") + lockSortOrder; + } + + pgSet *dataSet2 = locks_connection->ExecuteSet(sql); + if (dataSet2) + { + statusBar->SetStatusText(_("Refreshing locks list.")); + lockList->Freeze(); + + while (!dataSet2->Eof()) + { + pid = dataSet2->GetLong(wxT("pid")); + + if (pid != backend_pid) + { + if (row >= lockList->GetItemCount()) + { + lockList->InsertItem(row, NumToStr(pid), -1); + row = lockList->GetItemCount() - 1; + } + else + { + lockList->SetItem(row, 0, NumToStr(pid)); + } + + int colpos = 1; + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("dbname"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("class"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("user"))); + if (locks_connection->BackendMinimumVersion(8, 3)) + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("virtualxid"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("transaction"))); + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("mode"))); + + if (dataSet2->GetVal(wxT("granted")) == wxT("t")) + { + lockList->SetItem(row, colpos++, _("Yes")); + lockList->SetItemBackgroundColour(row,lockList->GetBackgroundColour()); + } + else { + lockList->SetItem(row, colpos++, _("No")); + lockList->SetItemBackgroundColour(row, wxColour(settings->GetBlockedProcessColour())); + + } + + wxString qry = dataSet2->GetVal(wxT("query")); + + if (locks_connection->BackendMinimumVersion(7, 4)) + { + if (qry.IsEmpty() || qry == wxT("")) + lockList->SetItem(row, colpos++, wxEmptyString); + else + lockList->SetItem(row, colpos++, dataSet2->GetVal(wxT("query_start"))); + } + lockList->SetItem(row, colpos++, qry.Left(250)); + + row++; + } + dataSet2->MoveNext(); + } + + delete dataSet2; + + while (row < lockList->GetItemCount()) + lockList->DeleteItem(row); + + lockList->Thaw(); + wxListEvent ev; + //OnSelLockItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} + + +void frmStatus::OnRefreshXactTimer(wxTimerEvent &event) +{ + if (! viewMenu->IsEnabled(MNU_XACTPAGE) || ! viewMenu->IsChecked(MNU_XACTPAGE) || !xactTimer) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + xactTimer->Stop(); + querystateTimer->Stop(); + if (logTimer) + logTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + xactSortColumn = 2; + } + + long row = 0; + wxString sql; + if (connection->BackendMinimumVersion(8, 3)) + sql = wxT("SELECT transaction::text, gid, prepared, owner, database ") + wxT("FROM pg_prepared_xacts ") + wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; + else + sql = wxT("SELECT transaction, gid, prepared, owner, database ") + wxT("FROM pg_prepared_xacts ") + wxT("ORDER BY ") + NumToStr((long)xactSortColumn) + wxT(" ") + xactSortOrder; + + pgSet *dataSet3 = connection->ExecuteSet(sql); + if (dataSet3) + { + statusBar->SetStatusText(_("Refreshing transactions list.")); + xactList->Freeze(); + + while (!dataSet3->Eof()) + { + long xid = dataSet3->GetLong(wxT("transaction")); + + if (row >= xactList->GetItemCount()) + { + xactList->InsertItem(row, NumToStr(xid), -1); + row = xactList->GetItemCount() - 1; + } + else + { + xactList->SetItem(row, 0, NumToStr(xid)); + } + + int colpos = 1; + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("gid"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("prepared"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("owner"))); + xactList->SetItem(row, colpos++, dataSet3->GetVal(wxT("database"))); + + row++; + dataSet3->MoveNext(); + } + delete dataSet3; + + while (row < xactList->GetItemCount()) + xactList->DeleteItem(row); + + xactList->Thaw(); + wxListEvent ev; + //OnSelXactItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} +long frmStatus::getlongvalue(wxString source,wxString match_str) { + long aa=0; + wxRegEx foundstr(match_str); + if (foundstr.Matches(source)) { + wxString v=foundstr.GetMatch(source,1); + v.ToLong(&aa); + } + return aa; +} + + +void frmStatus::OnRefreshQuerystateTimer(wxTimerEvent &event) +{ + if (! viewMenu->IsEnabled(MNU_QUERYSTATEPAGE) || ! viewMenu->IsChecked(MNU_QUERYSTATEPAGE) || !querystateTimer) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + xactTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + if (logTimer) + logTimer->Stop(); + return; + } + int row = statusList->GetFirstSelected(); + if (row<0) + return; + wxString pid=statusList->GetText(row, 0); + wxString dbname=statusList->GetText(row, 2); // dbname + wxString wait_event_type= statusList->GetText(row, wait_event_type_col); + if (dbname.IsEmpty()||wait_event_type==wxT("Extension")) return; + + wxString flags=wxT(""); + if (viewMenu->IsChecked(MNU_QUERYSTATEVERBOSE)) + flags += wxT(",true,false"); + else + flags += wxT(",false,false"); + if (viewMenu->IsChecked(MNU_QUERYSTATETIME)) + flags += wxT(",true"); + else + flags += wxT(",false"); + if (viewMenu->IsChecked(MNU_QUERYSTATEBUFFER)) + flags += wxT(",true"); + else + flags += wxT(",false"); + if (viewMenu->IsChecked(MNU_QUERYSTATETRIGGER)) + flags += wxT(",true"); + else + flags += wxT(",false"); + + flags += wxT(",'text'::text"); + wxCriticalSectionLocker lock(gs_critsect); + + row = 0; + wxString sql; + sql = wxT("select pid,frame_number,query_text,unnest(string_to_array(plan, E'\n')) pln,leader_pid from pg_query_state(") + +pid+flags+wxT(") s"); + + pgSet *dataSet3 = connection->ExecuteSet(sql,false); + if (dataSet3) + { + statusBar->SetStatusText(_("Refreshing query state list.")); + querystateList->Freeze(); + long prev_fn=100000000; + while (!dataSet3->Eof()&&dataSet3->NumCols()>0) + { + long pid = dataSet3->GetLong(wxT("pid")); + + if (row >= querystateList->GetItemCount()) + { + querystateList->InsertItem(row, NumToStr(pid), -1); + row = querystateList->GetItemCount() - 1; + } + else + { + querystateList->SetItem(row, 0, NumToStr(pid)); + } + + int colpos = 1; + long fn=dataSet3->GetLong(wxT("frame_number")); + querystateList->SetItem(row, colpos++, NumToStr(fn)); + querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("query_text"))); + wxString p=dataSet3->GetVal(wxT("pln")); + querystateList->SetItem(row, colpos++, p); + querystateList->SetItem(row, colpos++, dataSet3->GetVal(wxT("leader_pid"))); + if (prev_fn==fn) { + querystateList->SetItem(row, 1, wxT("")); + querystateList->SetItem(row, 2, wxT("")); + } + wxColour wc; + if (p.Find(wxT("->"))<0) { + wc=*wxWHITE; + if (getlongvalue(p,wxT("Rows Removed by Join Filter: ([0-9]+)"))>1000000) { + wc=wxColour(201,83,2); + //querystateList->SetItemBackgroundColour(row, wxColour(201,83,2)); + } + + querystateList->SetItemBackgroundColour(row, wc); + //querystateList->SetItemBackgroundColour(row, ); + } else + { + if (getlongvalue(p,wxT("actual rows=([0-9]+)"))>1000000) { + querystateList->SetItemBackgroundColour(row, wxColour(255,174,200)); // red + } else + querystateList->SetItemBackgroundColour(row, wxColour(224,255,224)); // gren + } + + row++; + prev_fn=fn; + dataSet3->MoveNext(); + } + delete dataSet3; + + while (row < querystateList->GetItemCount()) + querystateList->DeleteItem(row); + + querystateList->Thaw(); + wxListEvent ev; + //OnSelQuerystateItem(ev); + statusBar->SetStatusText(_("Done.")); + } + else + checkConnection(); +} + + +void frmStatus::OnRefreshLogTimer(wxTimerEvent &event) +{ + if (! viewMenu->IsEnabled(MNU_LOGPAGE) || ! viewMenu->IsChecked(MNU_LOGPAGE) || !logTimer) + return; + + checkConnection(); + if (!connection) + { + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + logTimer->Stop(); + return; + } + + wxCriticalSectionLocker lock(gs_critsect); + + if (connection->GetLastResultError().sql_state == wxT("42501")) + { + // Don't have superuser privileges, so can't do anything with the log display + logTimer->Stop(); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + manager.GetPane(wxT("Logfile")).Show(false); + manager.Update(); + return; + } + + long newlen = 0; + + if (logDirectory.IsEmpty()) + { + // freshly started + logDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); + if (connection->GetLastResultError().sql_state == wxT("42501")) + { + // Don't have superuser privileges, so can't do anything with the log display + logTimer->Stop(); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + manager.GetPane(wxT("Logfile")).Show(false); + manager.Update(); + return; + } + if (fillLogfileCombo()) + { + savedPartialLine.Clear(); + cbLogfiles->SetSelection(0); + wxCommandEvent ev; + OnLoadLogfile(ev); + return; + } + else + { + logDirectory = wxT("-"); + if (connection->BackendMinimumVersion(8, 3)) + logList->AppendItem(-1, wxString(_("logging_collector not enabled or log_filename misconfigured"))); + else + logList->AppendItem(-1, wxString(_("redirect_stderr not enabled or log_filename misconfigured"))); + cbLogfiles->Disable(); + btnRotateLog->Disable(); + } + } + + if (logDirectory == wxT("-")) + return; + + if (isCurrent) + { + // check if the current logfile changed + pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_length(") + connection->qtDbString(logfileName) + wxT(") AS len")); + if (set) + { + newlen = set->GetLong(wxT("len")); + delete set; + } + else + { + checkConnection(); + return; + } + if (newlen > logfileLength) + { + statusBar->SetStatusText(_("Refreshing log list.")); + addLogFile(logfileName, logfileTimestamp, newlen, logfileLength, false); + statusBar->SetStatusText(_("Done.")); + + // as long as there was new data, the logfile is probably the current + // one so we don't need to check for rotation + return; + } + } + + // + wxString newDirectory = connection->ExecuteScalar(wxT("SHOW log_directory")); + + int newfiles = 0; + if (newDirectory != logDirectory) + cbLogfiles->Clear(); + + newfiles = fillLogfileCombo(); + + if (newfiles) + { + if (!showCurrent) + isCurrent = false; + + if (isCurrent) + { + int pos = cbLogfiles->GetCount() - newfiles; + bool skipFirst = true; + + while (newfiles--) + { + addLogLine(_("pgadmin:Logfile rotated."), false); + wxDateTime *ts = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(pos++); + wxASSERT(ts != 0); + + addLogFile(ts, skipFirst); + skipFirst = false; + + pos++; + } + } + } +} + + +void frmStatus::OnRefresh(wxCommandEvent &event) +{ + wxTimerEvent evt; + + OnRefreshStatusTimer(evt); + OnRefreshLocksTimer(evt); + OnRefreshXactTimer(evt); + OnRefreshLogTimer(evt); + OnRefreshQuerystateTimer(evt); +} + + +void frmStatus::checkConnection() +{ + if (connection) { + if (!locks_connection->IsAlive()) + { + locks_connection = connection; + } + if (!connection->IsAlive()) + { + if (locks_connection==connection) locks_connection = 0; + delete connection; + connection = 0; + statusTimer->Stop(); + locksTimer->Stop(); + if (xactTimer) + xactTimer->Stop(); + if (logTimer) + logTimer->Stop(); + if (querystateTimer) + querystateTimer->Stop(); + actionMenu->Enable(MNU_REFRESH, false); + toolBar->EnableTool(MNU_REFRESH, false); + statusBar->SetStatusText(_("Connection broken.")); + } + } +} + + +void frmStatus::addLogFile(wxDateTime *dt, bool skipFirst) +{ + pgSet *set = connection->ExecuteSet( + wxT("SELECT filetime, filename, pg_file_length(filename) AS len ") + wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text) ") + wxT(" WHERE filetime = '") + DateToAnsiStr(*dt) + wxT("'::timestamp")); + if (set) + { + logfileName = set->GetVal(wxT("filename")); + logfileTimestamp = set->GetDateTime(wxT("filetime")); + long len = set->GetLong(wxT("len")); + + logfileLength = 0; + addLogFile(logfileName, logfileTimestamp, len, logfileLength, skipFirst); + + delete set; + } +} + + +void frmStatus::addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst) +{ + wxString line; + + if (skipFirst) + { + long maxServerLogSize = settings->GetMaxServerLogSize(); + + if (!logfileLength && maxServerLogSize && logfileLength > maxServerLogSize) + { + long maxServerLogSize = settings->GetMaxServerLogSize(); + len = read - maxServerLogSize; + } + else + skipFirst = false; + } + + // If GPDB 3.3 and later, log is normally in CSV format. Let's get a whole log line before calling addLogLine, + // so we can do things smarter. + + // PostgreSQL can log in CSV format, as well as regular format. Normally, we'd only see + // the regular format logs here, because pg_logdir_ls only returns those. But if pg_logdir_ls is + // changed to return the csv format log files, we should handle it. + + bool csv_log_format = filename.Right(4) == wxT(".csv"); + + if (csv_log_format && savedPartialLine.length() > 0) + { + if (read == 0) // Starting at beginning of log file + savedPartialLine.clear(); + else + line = savedPartialLine; + } + + while (len > read) + { + statusBar->SetStatusText(_("Reading log from server...")); + pgSet *set = connection->ExecuteSet(wxT("SELECT pg_file_read(") + + connection->qtDbString(filename) + wxT(", ") + NumToStr(read) + wxT(", 50000)")); + if (!set) + { + connection->IsAlive(); + return; + } + char *raw = set->GetCharPtr(0); + + if (!raw || !*raw) + { + delete set; + break; + } + + read += strlen(raw); + + wxString str; + if (wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8).Len() > 0) + str = line + wxString(wxString(raw, wxConvLibc).wx_str(), wxConvUTF8); + else + str = line + wxTextBuffer::Translate(wxString(raw, set->GetConversion()), wxTextFileType_Unix); + + delete set; + + if (str.Len() == 0) + { + wxString msgstr = _("The server log contains entries in multiple encodings and cannot be displayed by pgAdmin."); + wxMessageBox(msgstr); + return; + } + + if (csv_log_format) + { + // This will work for any DB using CSV format logs + + if (logHasTimestamp) + { + // Right now, csv format logs from GPDB and PostgreSQL always start with a timestamp, so we count on that. + + // And the only reason we need to do that is to make sure we are in sync. + + // Bad things happen if we start in the middle of a + // double-quoted string, as we would never find a correct line terminator! + + // In CSV logs, the first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). + if (str.length() > 4 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) + { + wxLogNotice(wxT("Log line does not start with timestamp: %s \n"), str.Mid(0, 100).c_str()); + // Something isn't right, as we are not at the beginning of a csv log record. + // We should never get here, but if we do, try to handle it in a smart way. + str = str.Mid(str.Find(wxT("\n20")) + 1); // Try to re-sync. + } + } + + CSVLineTokenizer tk(str); + + logList->Freeze(); + + while (tk.HasMoreLines()) + { + line.Clear(); + + bool partial; + str = tk.GetNextLine(partial); + if (partial) + { + line = str; // Start of a log line, but not complete. Loop back, Read more data. + break; + } + + // Some extra debug checking, assuming csv logs line start with timestamps. + // Not really necessary, but it is good for debugging if something isn't right. + if (logHasTimestamp) + { + // The first field must be a Timestamp, so must start with "2009" or "201" or "202" (at least for the next 20 years). + // This is just an extra check to make sure we haven't gotten out of sync with the log. + if (str.length() > 5 && str.Left(4) != wxT("2009") && str.Left(3) != wxT("201") && str.Left(3) != wxT("202")) + { + // BUG: We are out of sync on the log + wxLogNotice(wxT("Log line does not start with timestamp: %s\n"), str.c_str()); + } + else if (str.length() < 20) + { + // BUG: We are out of sync on the log, or the log is garbled + wxLogNotice(wxT("Log line too short: %s\n"), str.c_str()); + } + } + + // Looks like we have a good complete CSV log record. + addLogLine(str.Trim(), true, true); + } + + logList->Thaw(); + } + else + { + // Non-csv format log file + + bool hasCr = (str.Right(1) == wxT("\n")); + + wxStringTokenizer tk(str, wxT("\n")); + + logList->Freeze(); + + while (tk.HasMoreTokens()) + { + str = tk.GetNextToken(); + if (skipFirst) + { + // could be truncated + skipFirst = false; + continue; + } + + if (tk.HasMoreTokens() || hasCr) + addLogLine(str.Trim()); + else + line = str; + } + + logList->Thaw(); + } + } + + savedPartialLine.clear(); + + if (!line.IsEmpty()) + { + // We finished reading to the end of the log file, but still have some data left + if (csv_log_format) + { + savedPartialLine = line; // Save partial log line for next read of the data file. + line.Clear(); + } + else + addLogLine(line.Trim()); + } + +} + + +void frmStatus::addLogLine(const wxString &str, bool formatted, bool csv_log_format) +{ + int row = logList->GetItemCount(); + + int idxTimeStampCol = -1, idxLevelCol = -1; + int idxLogEntryCol = 0; + + if (logFormatKnown) + { + // Known Format first will be level, then Log entry + // idxLevelCol : 0, idxLogEntryCol : 1, idxTimeStampCol : -1 + idxLevelCol++; + idxLogEntryCol++; + if (logHasTimestamp) + { + // idxLevelCol : 1, idxLogEntryCol : 2, idxTimeStampCol : 0 + idxTimeStampCol++; + idxLevelCol++; + idxLogEntryCol++; + } + } + + if (!logFormatKnown) + logList->AppendItem(-1, str); + else if ((!csv_log_format) && str.Find(':') < 0) + { + // Must be a continuation of a previous line. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLogEntryCol, str); + } + else if (!formatted) + { + // Not from a log, from pgAdmin itself. + if (logHasTimestamp) + { + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); + } + else + { + logList->InsertItem(row, str.BeforeFirst(':'), -1); + } + logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':')); + } + else // formatted log + { + if (csv_log_format) + { + // Log is in CSV format (GPDB 3.3 and later, or Postgres if only csv log enabled) + // In this case, we are always supposed to have a complete log line in csv format in str when called. + + if (logHasTimestamp && (str.Length() < 20 || (logHasTimestamp && (str[0] != wxT('2') || str[1] != wxT('0'))))) + { + // Log line too short or does not start with an expected timestamp... + // Must be a continuation of the previous line or garbage, + // or we are out of sync in our CSV handling. + // We shouldn't ever get here. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, str); + } + else + { + CSVTokenizer tk(str); + + bool gpdb = connection->GetIsGreenplum(); + + // Get the fields from the CSV log. + wxString logTime = tk.GetNextToken(); + wxString logUser = tk.GetNextToken(); + wxString logDatabase = tk.GetNextToken(); + wxString logPid = tk.GetNextToken(); + + wxString logSession; + wxString logCmdcount; + wxString logSegment; + + if (gpdb) + { + wxString logThread = tk.GetNextToken(); // GPDB specific + wxString logHost = tk.GetNextToken(); + wxString logPort = tk.GetNextToken(); // GPDB (Postgres puts port with Host) + wxString logSessiontime = tk.GetNextToken(); + wxString logTransaction = tk.GetNextToken(); + logSession = tk.GetNextToken(); + logCmdcount = tk.GetNextToken(); + logSegment = tk.GetNextToken(); + wxString logSlice = tk.GetNextToken(); + wxString logDistxact = tk.GetNextToken(); + wxString logLocalxact = tk.GetNextToken(); + wxString logSubxact = tk.GetNextToken(); + } + else + { + wxString logHost = tk.GetNextToken(); // Postgres puts port with Hostname + logSession = tk.GetNextToken(); + wxString logLineNumber = tk.GetNextToken(); + wxString logPsDisplay = tk.GetNextToken(); + wxString logSessiontime = tk.GetNextToken(); + wxString logVXid = tk.GetNextToken(); + wxString logTransaction = tk.GetNextToken(); + } + + wxString logSeverity = tk.GetNextToken(); + wxString logState = tk.GetNextToken(); + wxString logMessage = tk.GetNextToken(); + wxString logDetail = tk.GetNextToken(); + wxString logHint = tk.GetNextToken(); + wxString logQuery = tk.GetNextToken(); + wxString logQuerypos = tk.GetNextToken(); + wxString logContext = tk.GetNextToken(); + wxString logDebug = tk.GetNextToken(); + wxString logCursorpos = tk.GetNextToken(); + + wxString logStack; + if (gpdb) + { + wxString logFunction = tk.GetNextToken(); // GPDB. Postgres puts func, file, and line together + wxString logFile = tk.GetNextToken(); + wxString logLine = tk.GetNextToken(); + logStack = tk.GetNextToken(); // GPDB only. + } + else + wxString logFuncFileLine = tk.GetNextToken(); + + logList->InsertItem(row, logTime, -1); // Insert timestamp (with time zone) + + logList->SetItem(row, 1, logSeverity); + + // Display the logMessage, breaking it into lines + wxStringTokenizer lm(logMessage, wxT("\n")); + logList->SetItem(row, 2, lm.GetNextToken()); + + logList->SetItem(row, 3, logSession); + logList->SetItem(row, 4, logCmdcount); + logList->SetItem(row, 5, logDatabase); + if ((!gpdb) || (logSegment.length() > 0 && logSegment != wxT("seg-1"))) + { + logList->SetItem(row, 6, logSegment); + } + else + { + // If we are reading the masterDB log only, the logSegment won't + // have anything useful in it. Look in the logMessage, and see if the + // segment info exists in there. It will always be at the end. + if (logMessage.length() > 0 && logMessage[logMessage.length() - 1] == wxT(')')) + { + int segpos = -1; + segpos = logMessage.Find(wxT("(seg")); + if (segpos <= 0) + segpos = logMessage.Find(wxT("(mir")); + if (segpos > 0) + { + logSegment = logMessage.Mid(segpos + 1); + if (logSegment.Find(wxT(' ')) > 0) + logSegment = logSegment.Mid(0, logSegment.Find(wxT(' '))); + logList->SetItem(row, 6, logSegment); + } + } + } + + // The rest of the lines from the logMessage + while (lm.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lm.GetNextToken()); + } + + // Add the detail + wxStringTokenizer ld(logDetail, wxT("\n")); + while (ld.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, ld.GetNextToken()); + } + + // And the hint + wxStringTokenizer lh(logHint, wxT("\n")); + while (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lh.GetNextToken()); + } + + if (logDebug.length() > 0) + { + wxString logState3 = logState.Mid(0, 3); + if (logState3 == wxT("426") || logState3 == wxT("22P") || logState3 == wxT("427") + || logState3 == wxT("42P") || logState3 == wxT("458") + || logMessage.Mid(0, 9) == wxT("duration:") || logSeverity == wxT("FATAL") || logSeverity == wxT("PANIC")) + { + // If not redundant, add the statement from the debug_string + wxStringTokenizer lh(logDebug, wxT("\n")); + if (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, wxT("statement: ") + lh.GetNextToken()); + } + while (lh.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, lh.GetNextToken()); + } + } + } + + if (gpdb) + if (logSeverity == wxT("PANIC") || + (logSeverity == wxT("FATAL") && logState != wxT("57P03") && logState != wxT("53300"))) + { + // If this is a severe error, add the stack trace. + wxStringTokenizer ls(logStack, wxT("\n")); + if (ls.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 1, wxT("STACK")); + logList->SetItem(controw, 2, ls.GetNextToken()); + } + while (ls.HasMoreTokens()) + { + int controw = logList->GetItemCount(); + logList->InsertItem(controw, wxEmptyString, -1); + logList->SetItem(controw, 2, ls.GetNextToken()); + } + } + } + } + else if (connection->GetIsGreenplum()) + { + // Greenplum 3.2 and before. log_line_prefix = "%m|%u|%d|%p|%I|%X|:-" + + wxString logSeverity; + // Skip prefix, get message. In GPDB, always follows ":-". + wxString rest = str.Mid(str.Find(wxT(":-")) + 1) ; + if (rest.Length() > 0 && rest[0] == wxT('-')) + rest = rest.Mid(1); + + // Separate loglevel from message + + if (rest.Length() > 1 && rest[0] != wxT(' ') && rest.Find(':') > 0) + { + logSeverity = rest.BeforeFirst(':'); + rest = rest.AfterFirst(':').Mid(2); + } + + wxString ts = str.BeforeFirst(logFormat.c_str()[logFmtPos + 2]); + if (ts.Length() < 20 || (logHasTimestamp && (ts.Left(2) != wxT("20") || str.Find(':') < 0))) + { + // No Timestamp? Must be a continuation of a previous line? + // Not sure if it is possible to get here. + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, rest); + } + else if (logSeverity.Length() > 1) + { + // Normal case: Start of a new log record. + logList->InsertItem(row, ts, -1); + logList->SetItem(row, 1, logSeverity); + logList->SetItem(row, 2, rest); + } + else + { + // Continuation of previous line + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, 2, rest); + } + } + else + { + // All Non-csv-format non-GPDB PostgreSQL systems. + + wxString rest; + + if (logHasTimestamp) + { + if (formatted) + { + rest = str.Mid(logFmtPos + 22).AfterFirst(':'); + wxString ts = str.Mid(logFmtPos, str.Length() - rest.Length() - logFmtPos - 1); + + int pos = ts.Find(logFormat.c_str()[logFmtPos + 2], true); + logList->InsertItem(row, ts.Left(pos), -1); + logList->SetItem(row, idxLevelCol, ts.Mid(pos + logFormat.Length() - logFmtPos - 2)); + logList->SetItem(row, idxLogEntryCol, rest.Mid(2)); + } + else + { + logList->InsertItem(row, wxEmptyString, -1); + logList->SetItem(row, idxLevelCol, str.BeforeFirst(':')); + logList->SetItem(row, idxLogEntryCol, str.AfterFirst(':').Mid(2)); + } + } + else + { + if (formatted) + rest = str.Mid(logFormat.Length()); + else + rest = str; + + int pos = rest.Find(':'); + + if (pos < 0) + logList->InsertItem(row, rest, -1); + else + { + logList->InsertItem(row, rest.BeforeFirst(':'), -1); + logList->SetItem(row, idxLogEntryCol, rest.AfterFirst(':').Mid(2)); + } + } + } + } +} + + +void frmStatus::emptyLogfileCombo() +{ + if (cbLogfiles->GetCount()) // first entry has no client data + cbLogfiles->Delete(0); + + while (cbLogfiles->GetCount()) + { + wxDateTime *dt = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(0); + if (dt) + delete dt; + cbLogfiles->Delete(0); + } +} + + +int frmStatus::fillLogfileCombo() +{ + int count = cbLogfiles->GetCount(); + if (!count) + cbLogfiles->Append(_("Current log")); + else + count--; + + pgSet *set = connection->ExecuteSet( + wxT("SELECT filename, filetime\n") + wxT(" FROM pg_logdir_ls() AS A(filetime timestamp, filename text)\n") + wxT(" ORDER BY filetime DESC")); + if (set) + { + if (set->NumRows() <= count) + { + delete set; + return 0; + } + + set->Locate(count + 1); + count = 0; + + while (!set->Eof()) + { + count++; + wxString fn = set->GetVal(wxT("filename")); + wxDateTime ts = set->GetDateTime(wxT("filetime")); + + cbLogfiles->Append(DateToAnsiStr(ts), (void *)new wxDateTime(ts)); + + set->MoveNext(); + } + + delete set; + } + + return count; +} + + +void frmStatus::OnLoadLogfile(wxCommandEvent &event) +{ + int pos = cbLogfiles->GetCurrentSelection(); + if (pos >= 0) + { + showCurrent = (pos == 0); + isCurrent = showCurrent || (pos == 1); + + wxDateTime *ts = (wxDateTime *)cbLogfiles->wxItemContainer::GetClientData(showCurrent ? 1 : pos); + wxASSERT(ts != 0); + + if (ts != NULL && (!logfileTimestamp.IsValid() || *ts != logfileTimestamp)) + { + logList->DeleteAllItems(); + addLogFile(ts, true); + } + } +} + + +void frmStatus::OnRotateLogfile(wxCommandEvent &event) +{ + if (wxMessageBox(_("Are you sure the logfile should be rotated?"), _("Logfile rotation"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) == wxYES) + connection->ExecuteVoid(wxT("select pg_logfile_rotate()")); +} + + +void frmStatus::OnCancelBtn(wxCommandEvent &event) +{ + switch(currentPane) + { + case PANE_STATUS: + OnStatusCancelBtn(event); + break; + case PANE_LOCKS: + OnLocksCancelBtn(event); + break; + default: + // This shouldn't happen. If it does, it's no big deal + break; + } +} + + +void frmStatus::OnStatusCancelBtn(wxCommandEvent &event) +{ + long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = statusList->GetItemText(item); + wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelStatusItem(ev); +} + + +void frmStatus::OnLocksCancelBtn(wxCommandEvent &event) +{ + long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to cancel the selected query(s)?"), _("Cancel query?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = lockList->GetItemText(item); + wxString sql = wxT("SELECT pg_cancel_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A cancel signal was sent to the selected server process(es)."), _("Cancel query"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelLockItem(ev); +} + + +void frmStatus::OnTerminateBtn(wxCommandEvent &event) +{ + switch(currentPane) + { + case PANE_STATUS: + OnStatusTerminateBtn(event); + break; + case PANE_LOCKS: + OnLocksTerminateBtn(event); + break; + default: + // This shouldn't happen. If it does, it's no big deal + break; + } +} + + +void frmStatus::OnStatusTerminateBtn(wxCommandEvent &event) +{ + long item = statusList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = statusList->GetItemText(item); + wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = statusList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelStatusItem(ev); +} + + +void frmStatus::OnLocksTerminateBtn(wxCommandEvent &event) +{ + long item = lockList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to terminate the selected server process(es)?"), _("Terminate process?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString pid = lockList->GetItemText(item); + wxString sql = wxT("SELECT pg_terminate_backend(") + pid + wxT(");"); + connection->ExecuteScalar(sql); + + item = lockList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + wxMessageBox(_("A terminate signal was sent to the selected server process(es)."), _("Terminate process"), wxOK | wxICON_INFORMATION); + OnRefresh(event); + wxListEvent ev; + OnSelLockItem(ev); +} + + +void frmStatus::OnStatusMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < statusPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (statusList->GetColumnWidth(i) > 0) + statusColWidth[i] = statusList->GetColumnWidth(i); + + wxMenuItem *menu = statusPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + statusList->SetColumnWidth(i, statusColWidth[i]); + else if (statusList->GetColumnWidth(i) > 0) + statusList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + statusList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), + statusColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/StatusPane_") + column.GetText() + wxT("_Width"), + -statusColWidth[i]); + } +} + + +void frmStatus::OnLockMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < lockPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (lockList->GetColumnWidth(i) > 0) + lockColWidth[i] = lockList->GetColumnWidth(i); + + wxMenuItem *menu = lockPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + lockList->SetColumnWidth(i, lockColWidth[i]); + else if (lockList->GetColumnWidth(i) > 0) + lockList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + lockList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), + lockColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/LockPane_") + column.GetText() + wxT("_Width"), + -lockColWidth[i]); + } +} + + +void frmStatus::OnXactMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < xactPopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (xactList->GetColumnWidth(i) > 0) + xactColWidth[i] = xactList->GetColumnWidth(i); + + wxMenuItem *menu = xactPopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + xactList->SetColumnWidth(i, xactColWidth[i]); + else if (xactList->GetColumnWidth(i) > 0) + xactList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + xactList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), + xactColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/XactPane_") + column.GetText() + wxT("_Width"), + -xactColWidth[i]); + } +} +void frmStatus::OnQuerystateMenu(wxCommandEvent &event) +{ + wxListItem column; + column.SetMask(wxLIST_MASK_TEXT); + + for (unsigned int i = 0; i < querystatePopupMenu->GetMenuItemCount(); i++) + { + // Save column's width in a variable so that we can restore the old width + // if we make this column "invisible" + if (querystateList->GetColumnWidth(i) > 0) + querystateColWidth[i] = querystateList->GetColumnWidth(i); + + wxMenuItem *menu = querystatePopupMenu->FindItemByPosition(i); + if (menu && menu->IsChecked()) + querystateList->SetColumnWidth(i, querystateColWidth[i]); + else if (querystateList->GetColumnWidth(i) > 0) + querystateList->SetColumnWidth(i, 0); + + // Save current width to restore it at next launch + querystateList->GetColumn(i, column); + if (column.GetWidth() > 0) + settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), + querystateColWidth[i]); + else + settings->WriteInt(wxT("frmStatus/QuerystatePane_") + column.GetText() + wxT("_Width"), + -querystateColWidth[i]); + } +} + + +void frmStatus::OnCommit(wxCommandEvent &event) +{ + long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to commit the selected prepared transactions?"), _("Commit transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString xid = xactList->GetText(item, 1); + wxString sql = wxT("COMMIT PREPARED ") + connection->qtDbString(xid); + + // We must execute this in the database in which the prepared transaction originated. + if (connection->GetDbname() != xactList->GetText(item, 4)) + { + pgConn *tmpConn = new pgConn(connection->GetHost(), + connection->GetService(), + connection->GetHostAddr(), + xactList->GetText(item, 4), + connection->GetUser(), + connection->GetPassword(), + connection->GetPort(), + connection->GetRole(), + connection->GetSslMode(), + 0, + connection->GetApplicationName(), + connection->GetSSLCert(), + connection->GetSSLKey(), + connection->GetSSLRootCert(), + connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (tmpConn) + { + if (tmpConn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); + return ; + } + tmpConn->ExecuteScalar(sql); + + tmpConn->Close(); + delete tmpConn; + } + } + else + connection->ExecuteScalar(sql); + + item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + OnRefresh(event); + wxListEvent ev; + OnSelXactItem(ev); +} + + +void frmStatus::OnRollback(wxCommandEvent &event) +{ + long item = xactList->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (item < 0) + return; + + if (wxMessageBox(_("Are you sure you wish to rollback the selected prepared transactions?"), _("Rollback transaction?"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION) != wxYES) + return; + + while (item >= 0) + { + wxString xid = xactList->GetText(item, 1); + wxString sql = wxT("ROLLBACK PREPARED ") + connection->qtDbString(xid); + + // We must execute this in the database in which the prepared transaction originated. + if (connection->GetDbname() != xactList->GetText(item, 4)) + { + pgConn *tmpConn = new pgConn(connection->GetHost(), + connection->GetService(), + connection->GetHostAddr(), + xactList->GetText(item, 4), + connection->GetUser(), + connection->GetPassword(), + connection->GetPort(), + connection->GetRole(), + connection->GetSslMode(), + 0, + connection->GetApplicationName(), + connection->GetSSLCert(), + connection->GetSSLKey(), + connection->GetSSLRootCert(), + connection->GetSSLCrl(), + connection->GetSSLCompression()); + if (tmpConn) + { + if (tmpConn->GetStatus() != PGCONN_OK) + { + wxMessageBox(wxT("Connection failed: ") + tmpConn->GetLastError()); + return ; + } + tmpConn->ExecuteScalar(sql); + + tmpConn->Close(); + delete tmpConn; + } + } + else + connection->ExecuteScalar(sql); + + item = xactList->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + } + + OnRefresh(event); + wxListEvent ev; + OnSelXactItem(ev); +} + + +void frmStatus::OnSelStatusItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_STATUS; + cbRate->SetValue(rateToCboString(statusRate)); + if (connection && connection->BackendMinimumVersion(8, 0)) + { + if(statusList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_CANCEL, true); + actionMenu->Enable(MNU_CANCEL, true); + if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) + { + toolBar->EnableTool(MNU_TERMINATE, true); + actionMenu->Enable(MNU_TERMINATE, true); + } + } + else + { + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + } + } + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, statusList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); + toolBar->EnableTool(MNU_COPY_QUERY, statusList->GetFirstSelected() >= 0); + OnRefresh(event); +} + + +void frmStatus::OnSelLockItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_LOCKS; + cbRate->SetValue(rateToCboString(locksRate)); + if (connection && connection->BackendMinimumVersion(8, 0)) + { + if(lockList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_CANCEL, true); + actionMenu->Enable(MNU_CANCEL, true); + if (connection->HasFeature(FEATURE_TERMINATE_BACKEND)) + { + toolBar->EnableTool(MNU_TERMINATE, true); + actionMenu->Enable(MNU_TERMINATE, true); + } + } + else + { + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + } + } + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, lockList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + + +void frmStatus::OnSelXactItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_XACT; + cbRate->SetValue(rateToCboString(xactRate)); + if(xactList->GetSelectedItemCount() > 0) + { + toolBar->EnableTool(MNU_COMMIT, true); + actionMenu->Enable(MNU_COMMIT, true); + toolBar->EnableTool(MNU_ROLLBACK, true); + actionMenu->Enable(MNU_ROLLBACK, true); + } + else + { + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, xactList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + +void frmStatus::OnSelQuerystateItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.Update(); +#endif + currentPane = PANE_QUERYSTATE; + cbRate->SetValue(rateToCboString(querystateRate)); + { + toolBar->EnableTool(MNU_COMMIT, false); + actionMenu->Enable(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + toolBar->EnableTool(MNU_CANCEL, false); + actionMenu->Enable(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + actionMenu->Enable(MNU_TERMINATE, false); + cbLogfiles->Enable(false); + btnRotateLog->Enable(false); + + editMenu->Enable(MNU_COPY, querystateList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + + +void frmStatus::OnSelLogItem(wxListEvent &event) +{ +#ifdef __WXGTK__ + manager.GetPane(wxT("Activity")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Locks")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Transactions")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.GetPane(wxT("Logfile")).SetFlag(wxAuiPaneInfo::optionActive, true); + manager.GetPane(wxT("Querystate")).SetFlag(wxAuiPaneInfo::optionActive, false); + manager.Update(); +#endif + currentPane = PANE_LOG; + cbRate->SetValue(rateToCboString(logRate)); + + // if there's no log, don't enable items + if (logDirectory != wxT("-")) + { + cbLogfiles->Enable(true); + btnRotateLog->Enable(true); + toolBar->EnableTool(MNU_CANCEL, false); + toolBar->EnableTool(MNU_TERMINATE, false); + toolBar->EnableTool(MNU_COMMIT, false); + toolBar->EnableTool(MNU_ROLLBACK, false); + actionMenu->Enable(MNU_CANCEL, false); + actionMenu->Enable(MNU_TERMINATE, false); + actionMenu->Enable(MNU_COMMIT, false); + actionMenu->Enable(MNU_ROLLBACK, false); + } + + editMenu->Enable(MNU_COPY, logList->GetFirstSelected() >= 0); + actionMenu->Enable(MNU_COPY_QUERY, false); + toolBar->EnableTool(MNU_COPY_QUERY, false); +} + + +void frmStatus::SetColumnImage(ctlListView *list, int col, int image) +{ + wxListItem item; + item.SetMask(wxLIST_MASK_IMAGE); + item.SetImage(image); + list->SetColumn(col, item); +} + + +void frmStatus::OnSortStatusGrid(wxListEvent &event) +{ + // Get the information for the SQL ORDER BY + if (statusSortColumn == event.GetColumn() + 1) + { + if (statusSortOrder == wxT("ASC")) + statusSortOrder = wxT("DESC"); + else + statusSortOrder = wxT("ASC"); + } + else + { + statusSortColumn = event.GetColumn() + 1; + statusSortOrder = wxT("ASC"); + } + + + // Re-initialize all columns' image + for (int i = 0; i < statusList->GetColumnCount(); i++) + { + SetColumnImage(statusList, i, -1); + } + + // Set the up/down image + if (statusSortOrder == wxT("ASC")) + SetColumnImage(statusList, statusSortColumn - 1, 0); + else + SetColumnImage(statusList, statusSortColumn - 1, 1); + + // Refresh grid + wxTimerEvent evt; + OnRefreshStatusTimer(evt); +} + + +void frmStatus::OnSortLockGrid(wxListEvent &event) +{ + // Get the information for the SQL ORDER BY + if (lockSortColumn == event.GetColumn() + 1) + { + if (lockSortOrder == wxT("ASC")) + lockSortOrder = wxT("DESC"); + else + lockSortOrder = wxT("ASC"); + } + else + { + lockSortColumn = event.GetColumn() + 1; + lockSortOrder = wxT("ASC"); + } + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && lockSortColumn == 5) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + lockSortColumn = 1; + } + + // Re-initialize all columns' image + for (int i = 0; i < lockList->GetColumnCount(); i++) + { + SetColumnImage(lockList, i, -1); + } + + // Set the up/down image + if (lockSortOrder == wxT("ASC")) + SetColumnImage(lockList, lockSortColumn - 1, 0); + else + SetColumnImage(lockList, lockSortColumn - 1, 1); + + // Refresh grid + wxTimerEvent evt; + OnRefreshLocksTimer(evt); +} + + +void frmStatus::OnSortXactGrid(wxListEvent &event) +{ + // Get the information for the SQL ORDER BY + if (xactSortColumn == event.GetColumn() + 1) + { + if (xactSortOrder == wxT("ASC")) + xactSortOrder = wxT("DESC"); + else + xactSortOrder = wxT("ASC"); + } + else + { + xactSortColumn = event.GetColumn() + 1; + xactSortOrder = wxT("ASC"); + } + + // There are no sort operator for xid before 8.3 + if (!connection->BackendMinimumVersion(8, 3) && xactSortColumn == 1) + { + wxLogError(_("You cannot sort by transaction id on your PostgreSQL release. You need at least 8.3.")); + xactSortColumn = 2; + } + + // Re-initialize all columns' image + for (int i = 0; i < xactList->GetColumnCount(); i++) + { + SetColumnImage(xactList, i, -1); + } + + // Set the up/down image + if (xactSortOrder == wxT("ASC")) + SetColumnImage(xactList, xactSortColumn - 1, 0); + else + SetColumnImage(xactList, xactSortColumn - 1, 1); + + // Refresh grid + wxTimerEvent evt; + OnRefreshXactTimer(evt); +} + + +void frmStatus::OnRightClickStatusGrid(wxListEvent &event) +{ + statusList->PopupMenu(statusPopupMenu, event.GetPoint()); +} + +void frmStatus::OnRightClickLockGrid(wxListEvent &event) +{ + lockList->PopupMenu(lockPopupMenu, event.GetPoint()); +} + +void frmStatus::OnRightClickXactGrid(wxListEvent &event) +{ + xactList->PopupMenu(xactPopupMenu, event.GetPoint()); +} +void frmStatus::OnRightClickQuerystateGrid(wxListEvent &event) +{ + querystateList->PopupMenu(querystatePopupMenu, event.GetPoint()); +} + + +void frmStatus::OnChgColSizeStatusGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnStatusMenu(ev); +} + +void frmStatus::OnChgColSizeLockGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnLockMenu(ev); +} + +void frmStatus::OnChgColSizeXactGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnXactMenu(ev); +} + +void frmStatus::OnChgColSizeQuerystateGrid(wxListEvent &event) +{ + wxCommandEvent ev; + OnQuerystateMenu(ev); +} + + +serverStatusFactory::serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Server Status"), _("Displays the current database status.")); +} + + +wxWindow *serverStatusFactory::StartDialog(frmMain *form, pgObject *obj) +{ + + pgServer *server = obj->GetServer(); + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Server Status"); + + pgConn *conn = server->CreateConn(wxEmptyString, 0, applicationname); + if (conn) + { + wxString txt = _("Server Status - ") + server->GetDescription() + + wxT(" (") + server->GetName() + wxT(":") + NumToStr((long)server->GetPort()) + wxT(")"); + + frmStatus *status = new frmStatus(form, txt, conn); + status->Go(); + return status; + } + return 0; +} + + +bool serverStatusFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->GetServer() != 0; +} diff --git a/frm/module.mk b/frm/module.mk new file mode 100644 index 0000000..58e2402 --- /dev/null +++ b/frm/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/frm/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + frm/events.cpp \ + frm/frmAbout.cpp \ + frm/frmBackup.cpp \ + frm/frmBackupGlobals.cpp \ + frm/frmBackupServer.cpp \ + frm/frmConfig.cpp \ + frm/frmDatabaseDesigner.cpp \ + frm/frmEditGrid.cpp \ + frm/frmExport.cpp \ + frm/frmGrantWizard.cpp \ + frm/frmHbaConfig.cpp \ + frm/frmHint.cpp \ + frm/frmImport.cpp \ + frm/frmMain.cpp \ + frm/frmMainConfig.cpp \ + frm/frmMaintenance.cpp \ + frm/frmOptions.cpp \ + frm/frmPassword.cpp \ + frm/frmPgpassConfig.cpp \ + frm/frmQuery.cpp \ + frm/frmReport.cpp \ + frm/frmRestore.cpp \ + frm/frmSplash.cpp \ + frm/frmStatus.cpp \ + frm/plugins.cpp + +EXTRA_DIST += \ + frm/module.mk diff --git a/frm/plugins.cpp b/frm/plugins.cpp new file mode 100644 index 0000000..d7016eb --- /dev/null +++ b/frm/plugins.cpp @@ -0,0 +1,464 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// plugins.cpp - Plugin management for frmMain +// +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// Application headers +#include "frm/frmMain.h" +#include "db/pgConn.h" +#include "ctl/ctlMenuToolbar.h" +#include "schema/pgObject.h" +#include "schema/pgDatabase.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "utils/sysSettings.h" + +void frmMain::LoadPluginUtilities() +{ + if (pluginsDir.IsEmpty()) + return; + + PluginUtility *util = new PluginUtility; + ClearPluginUtility(util); + + // Loop through all the ini files we find in the directory. + wxString iniFile; + wxDir iniDir(pluginsDir); + + if (!iniDir.IsOpened()) + return; + + wxLogInfo(wxT("Loading plugin ini files from %s"), pluginsDir.c_str()); + + bool cont = iniDir.GetFirst(&iniFile, wxT("*.ini"), wxDIR_FILES); + + while(cont) + { + // Load the config file + wxFileName utilIni(pluginsDir + wxT("/") + iniFile); + if (!utilIni.FileExists()) + { + cont = iniDir.GetNext(&iniFile); + continue; + } + + wxLogInfo(wxT("Loading plugin utilities from %s"), utilIni.GetFullPath().c_str()); + wxString brCfg = FileRead(utilIni.GetFullPath()); + + wxStringTokenizer tkz(brCfg, wxT("\r\n")); + + // Loop round the lines in the file. Everytime we find a new 'Title' value + // we create the current plugin and start a new one + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + + if (token.Trim() == wxEmptyString || token.StartsWith(wxT(";"))) + continue; + + // Separator + if (token.Lower().StartsWith(wxT("[separator]"))) + { + // Add the previous app if required. + AddPluginUtility(util); + pluginsMenu->AppendSeparator(); + } + + // Title + if (token.Lower().StartsWith(wxT("title="))) + { + // Add the previous app if required. + AddPluginUtility(util); + util->title = token.AfterFirst('=').Trim(); + } + + // Command + if (token.Lower().StartsWith(wxT("command="))) + util->command = token.AfterFirst('=').Trim(); + + // Description + if (token.Lower().StartsWith(wxT("description="))) + util->description = token.AfterFirst('=').Trim(); + + // KeyFile + if (token.Lower().StartsWith(wxT("keyfile="))) + { + wxString keyfile = token.AfterFirst('=').Trim(); + + // Substitute path placeholders + keyfile.Replace(wxT("$$BINDIR"), loadPath); + keyfile.Replace(wxT("$$WORKINGDIR"), wxGetCwd()); + keyfile.Replace(wxT("$$PGBINDIR"), settings->GetPostgresqlPath()); + keyfile.Replace(wxT("$$EDBBINDIR"), settings->GetEnterprisedbPath()); + keyfile.Replace(wxT("$$SLONYBINDIR"), settings->GetSlonyPath()); + + util->keyfile = keyfile; + } + + // Platform + if (token.Lower().StartsWith(wxT("platform="))) + util->platform = token.AfterFirst('=').Trim(); + + // Server types + if (token.Lower().StartsWith(wxT("servertype="))) + { + util->server_types.Clear(); + + // This is a comma delimited list of values going into an array. + wxStringTokenizer valueTkz(token.AfterFirst('='), wxT(",")); + + while(valueTkz.HasMoreTokens()) + util->server_types.Add(valueTkz.GetNextToken()); + } + + // Database + if (token.Lower().StartsWith(wxT("database="))) + { + if (token.AfterFirst('=').Trim().Lower() == wxT("yes")) + util->database = true; + else + util->database = false; + } + + // Applies to + if (token.Lower().StartsWith(wxT("appliesto="))) + { + util->applies_to.Clear(); + + // This is a comma delimited list of values going into an array. + wxStringTokenizer valueTkz(token.AfterFirst('='), wxT(",")); + + while(valueTkz.HasMoreTokens()) + util->applies_to.Add(valueTkz.GetNextToken()); + } + + // Set password + if (token.Lower().StartsWith(wxT("setpassword="))) + { + if (token.AfterFirst('=').Trim().Lower() == wxT("yes")) + util->set_password = true; + else + util->set_password = false; + } + // Environment + if (token.Lower().StartsWith(wxT("environment="))) + { + util->set_env.Clear(); + + // This is a comma delimited list of values going into an array. + wxStringTokenizer valueTkz(token.AfterFirst('='), wxT(",")); + + while(valueTkz.HasMoreTokens()) + util->set_env.Add(valueTkz.GetNextToken()); + } + } + + // Add the last app if required. + AddPluginUtility(util); + + // Get the next file + cont = iniDir.GetNext(&iniFile); + } + + if (util) + delete util; +} + +// Add a new plugin to the collection. +void frmMain::AddPluginUtility(PluginUtility *util) +{ + // Platform name +#ifdef __WXMSW__ + wxString thisPlatform = wxT("windows"); +#else +#ifdef __WXGTK__ + wxString thisPlatform = wxT("unix"); +#else + wxString thisPlatform = wxT("osx"); +#endif +#endif + + // Only add apps targeted to this, or any platform + if (util->platform.Lower() == thisPlatform || util->platform == wxEmptyString) + { + // Only add an app with a title and command + if (!util->title.IsEmpty() && !util->command.IsEmpty()) + { + // We're only going to add this if the keyfile exists or isn't specified + if (util->keyfile.IsEmpty() || wxFileExists(util->keyfile)) + { + CreatePluginUtility(util); + ClearPluginUtility(util); + pluginUtilityCount++; + } + } + } +} + +// Create a new Plugin utility factory +void frmMain::CreatePluginUtility(PluginUtility *util) +{ + wxLogInfo(wxT("Adding plugin utility: %s"), util->title.c_str()); + wxLogInfo(wxT(" Command: %s"), util->command.c_str()); + wxLogInfo(wxT(" Description: %s"), util->description.c_str()); + wxLogInfo(wxT(" Database?: %s"), util->database ? wxT("Yes") : wxT("No")); + wxLogInfo(wxT(" Set Password?: %s"), util->set_password ? wxT("Yes") : wxT("No")); + + new pluginUtilityFactory(menuFactories, pluginsMenu, util); +} + +// Clear a PluginUtility struct +void frmMain::ClearPluginUtility(PluginUtility *util) +{ + util->title = wxEmptyString; + util->command = wxEmptyString; + util->description = wxEmptyString; + util->keyfile = wxEmptyString; + util->platform = wxEmptyString; + util->server_types.Clear(); + util->database = false; + util->applies_to.Clear(); + util->set_password = false; + util->set_env.Clear(); +} + +// The actionFactory for the plugin utilities +pluginUtilityFactory::pluginUtilityFactory(menuFactoryList *list, wxMenu *menu, PluginUtility *util) : actionFactory(list) +{ + title = util->title; + command = util->command; + description = util->description; + server_types = util->server_types; + database = util->database; + applies_to = util->applies_to; + set_password = util->set_password; + set_env = util->set_env; + + menu->Append(id, title, description); +} + + +wxWindow *pluginUtilityFactory::StartDialog(frmMain *form, pgObject *obj) +{ + wxString execCmd = command; + wxArrayString environment = set_env; + + // Remember this as the last plugin used + form->SetLastPluginUtility(this); + + // Replace all the place holders with appropriate values + if (HaveDatabase(obj)) + { + execCmd.Replace(wxT("$$HOSTNAME"), obj->GetConnection()->GetHostName()); + execCmd.Replace(wxT("$$HOSTADDR"), obj->GetConnection()->GetHostName()); + execCmd.Replace(wxT("$$PORT"), NumToStr((long)obj->GetConnection()->GetPort())); + execCmd.Replace(wxT("$$SSLMODE"), obj->GetConnection()->GetSslModeName()); + execCmd.Replace(wxT("$$DATABASE"), obj->GetConnection()->GetDbname()); + execCmd.Replace(wxT("$$USERNAME"), obj->GetConnection()->GetUser()); + execCmd.Replace(wxT("$$PASSWORD"), obj->GetConnection()->GetPassword()); + + // Set the PGPASSWORD variable if required. + if (set_password && !obj->GetConnection()->GetPassword().IsEmpty()) + wxSetEnv(wxT("PGPASSWORD"), obj->GetConnection()->GetPassword()); + + // Pass the SSL settings via the environment + switch (obj->GetConnection()->GetSslMode()) + { + case 1: + wxSetEnv(wxT("PGREQUIRESSL"), wxT("1")); + break; + case 2: + wxSetEnv(wxT("PGREQUIRESSL"), wxT("0")); + break; + } + + wxSetEnv(wxT("PGSSLMODE"), obj->GetConnection()->GetSslModeName()); + wxSetEnv(wxT("PGSSLCERT"), obj->GetConnection()->GetSSLCert()); + wxSetEnv(wxT("PGSSLKEY"), obj->GetConnection()->GetSSLKey()); + wxSetEnv(wxT("PGSSLROOTCERT"), obj->GetConnection()->GetSSLRootCert()); + wxSetEnv(wxT("PGSSLCRL"), obj->GetConnection()->GetSSLCrl()); + } + else + { + // Blank the rest + execCmd.Replace(wxT("$$HOSTNAME"), wxEmptyString); + execCmd.Replace(wxT("$$HOSTADDR"), wxEmptyString); + execCmd.Replace(wxT("$$PORT"), wxEmptyString); + execCmd.Replace(wxT("$$SSLMODE"), wxEmptyString); + execCmd.Replace(wxT("$$DATABASE"), wxEmptyString); + execCmd.Replace(wxT("$$USERNAME"), wxEmptyString); + execCmd.Replace(wxT("$$PASSWORD"), wxEmptyString); + } + + // Name + if (obj && obj->IsCollection()) + execCmd.Replace(wxT("$$OBJECTNAME"), wxT("*")); + else if (obj) + execCmd.Replace(wxT("$$OBJECTNAME"), obj->GetName()); + else + execCmd.Replace(wxT("$$OBJECTNAME"), wxEmptyString); + + // Object type + if (obj && obj->GetFactory()) + execCmd.Replace(wxT("$$OBJECTTYPE"), wxString(obj->GetFactory()->GetTypeName()).Upper()); + else + execCmd.Replace(wxT("$$OBJECTTYPE"), wxEmptyString); + + // Schema + if (obj) + { + if (obj->GetMetaType() == PGM_SCHEMA) + execCmd.Replace(wxT("$$SCHEMA"), obj->GetName()); + else if (obj->GetSchema()) + execCmd.Replace(wxT("$$SCHEMA"), obj->GetSchema()->GetName()); + } + else + execCmd.Replace(wxT("$$SCHEMA"), wxEmptyString); + + // Table + if (obj) + { + if (obj->GetMetaType() == PGM_TABLE || obj->GetMetaType() == GP_PARTITION) + execCmd.Replace(wxT("$$TABLE"), obj->GetName()); + else if (obj->GetTable()) + execCmd.Replace(wxT("$$TABLE"), obj->GetTable()->GetName()); + } + else + execCmd.Replace(wxT("$$TABLE"), wxEmptyString); + + // Directory substitutions + execCmd.Replace(wxT("$$BINDIR"), loadPath); + execCmd.Replace(wxT("$$WORKINGDIR"), wxGetCwd()); + execCmd.Replace(wxT("$$PGBINDIR"), settings->GetPostgresqlPath()); + execCmd.Replace(wxT("$$EDBBINDIR"), settings->GetEnterprisedbPath()); + execCmd.Replace(wxT("$$SLONYBINDIR"), settings->GetSlonyPath()); + + // set Environment variable. + for (size_t i = 0 ; i < environment.GetCount() ; i++) + { + wxString str = environment.Item(i); + wxSetEnv(str.BeforeFirst('='), str.AfterFirst('=')); + } + + // Let's go!! + if (wxExecute(execCmd) == 0) + { + wxLogError(_("Failed to execute plugin %s (%s)"), title.c_str(), command.c_str()); + } + + // Reset the environment variables set by us + wxUnsetEnv(wxT("PGPASSWORD")); + wxUnsetEnv(wxT("PGSSLMODE")); + wxUnsetEnv(wxT("PGREQUIRESSL")); + wxUnsetEnv(wxT("PGSSLCERT")); + wxUnsetEnv(wxT("PGSSLKEY")); + wxUnsetEnv(wxT("PGSSLROOTCERT")); + wxUnsetEnv(wxT("PGSSLCRL")); + + return 0; +} + +bool pluginUtilityFactory::CheckEnable(pgObject *obj) +{ + // First check that this is one of the supported server types + // for this plugin. If none are specified, then anything goes + if (database && server_types.Count() > 0) + { + // If we need a specific server type, we can't enable unless + // we have a connection. + if (!obj || !(obj->GetConnection()->GetStatus() == PGCONN_OK)) + return false; + + // Get the server type. + wxString serverType = wxT("postgresql"); + if (obj->GetConnection()->GetIsEdb()) + serverType = wxT("enterprisedb"); + + // Check if it's in the list. + if (server_types.Index(serverType) == wxNOT_FOUND) + return false; + } + + // Now check that this is one of the supported object types + // for this plugin. If none are specified, then anything goes + if (obj && applies_to.Count() > 0) + { + if (applies_to.Index(wxString(obj->GetFactory()->GetTypeName()).Lower()) == wxNOT_FOUND) + return false; + } + + // If we don't need a database, we're always OK. + if (!database) + return true; + + return HaveDatabase(obj); +} + +bool pluginUtilityFactory::HaveDatabase(pgObject *obj) +{ + // We need a good connection and database. + if (!obj) + return false; + + if (!obj->GetDatabase()) + return false; + + if (!obj->GetDatabase()->GetConnection()) + return false; + + if (!(obj->GetDatabase()->GetConnection()->GetStatus() == PGCONN_OK)) + return false; + + return true; +} + +// The pluginButtonMenuFactory class manages the toolbar menu button +// for the plugins. + +#include "images/plugins.pngc" +pluginButtonMenuFactory::pluginButtonMenuFactory(menuFactoryList *list, wxMenu *popupmenu, ctlMenuToolbar *toolbar, int pluginCount) : actionFactory(list) +{ + if (pluginCount) + enableButton = true; + else + enableButton = false; + + if (toolbar) + { + toolbar->AddTool(id, wxEmptyString, *plugins_png_bmp, _("Execute the last used plugin.")); + pulldownButton = toolbar->AddMenuPulldownTool(MNU_PLUGINBUTTONLIST, wxT("Execute Plugin"), wxT("Select a plugin."), popupmenu); + } +} + +// Call the last plugin used, or popup the menu if this is the first time +wxWindow *pluginButtonMenuFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (form->GetLastPluginUtility() && form->GetLastPluginUtility()->CheckEnable(obj)) + return form->GetLastPluginUtility()->StartDialog(form, obj); + else + { + wxMouseEvent evt; + pulldownButton->DoProcessLeftClick(evt); + } + + return 0; +} + +bool pluginButtonMenuFactory::CheckEnable(pgObject *obj) +{ + return enableButton; +} diff --git a/gqb/gqbArrayCollection.cpp b/gqb/gqbArrayCollection.cpp new file mode 100644 index 0000000..9936147 --- /dev/null +++ b/gqb/gqbArrayCollection.cpp @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbArrayCollection.cpp - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbObject.h" + +// Destructor +gqbArrayCollection::~gqbArrayCollection() +{ + WX_CLEAR_ARRAY(gqbArray); +} + + +// Add item to array +void gqbArrayCollection::addItem(gqbObject *item) +{ + gqbArray.Add(item); +} + + +// Remove item from array but don't delete it. +void gqbArrayCollection::removeItem(gqbObject *item) +{ + gqbArray.Remove(item); +} + + +// Create an iterator for the objects inside the array +gqbIteratorBase *gqbArrayCollection::createIterator() +{ + return (new gqbArrayIterator(&gqbArray)); +} + +// Create a Down to iterator for the objects inside the array +gqbIteratorBase *gqbArrayCollection::createDownIterator() +{ + return (new gqbArrayDownIterator(&gqbArray)); +} + +// Return the number of elements inside the array +int gqbArrayCollection::count() +{ + return gqbArray.Count(); +} + + +// Return true if an element pointer is found inside array +bool gqbArrayCollection::existsObject(gqbObject *item) +{ + gqbObject *found = NULL; + int size = gqbArray.GetCount(); + for(int i = 0; i < size; i++) + { + if (gqbArray.Item(i) == item) + { + found = gqbArray.Item(i); + break; + } + } + if(found) + return true; + else + return false; +} + + +// Delete all elements inside array +void gqbArrayCollection::deleteAll() +{ + WX_CLEAR_ARRAY(gqbArray); +} + + +// Removes all elements inside array without deleting +void gqbArrayCollection::removeAll() +{ + gqbArray.Empty(); +} + +// Get Item at certain position at Collection +gqbObject *gqbArrayCollection::getItemAt(int index) +{ + if(!gqbArray.IsEmpty()) + return gqbArray.Item(index); + else + return NULL; +} + + +int gqbArrayCollection::getIndex(gqbObject *item) +{ + return gqbArray.Index(item); +} + + +// Insert item into the array before the index +void gqbArrayCollection:: insertAtIndex(gqbObject *item, int index) +{ + gqbArray.Insert(item, index); +} + + +// +// gqbArrayIterator - Manages iterator for the array collection concrete class, from first to last element +// + +// Constructor +gqbArrayIterator::gqbArrayIterator(gqbObjsArray *gqbPtrsArray) +{ + position = 0; + internalArray = gqbPtrsArray; +} + + +// Get next item in the array for the iterator +gqbObject *gqbArrayIterator::Next() +{ + gqbObject *obj = internalArray->Item(position); + position++; + return obj; +} + + +// Return true if the array has more elements to return +bool gqbArrayIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1)) ) + return true; + else + return false; +} + + +void gqbArrayIterator::ResetIterator() +{ + position = 0; +} + + +// +// gqbArrayDownIterator - Manages iterator for the array collection concrete class from last to first element +// + +// Constructor +gqbArrayDownIterator::gqbArrayDownIterator(gqbObjsArray *gqbPtrsArray) +{ + internalArray = gqbPtrsArray; + position = internalArray->GetCount() - 1; +} + + +// Get next item in the array for the iterator +gqbObject *gqbArrayDownIterator::Next() +{ + gqbObject *obj = internalArray->Item(position); + position--; + return obj; +} + + +// Return true if the array has more elements to return +bool gqbArrayDownIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1) && position >= 0) ) + return true; + else + return false; +} + + +void gqbArrayDownIterator::ResetIterator() +{ + position = internalArray->GetCount() - 1; +} diff --git a/gqb/gqbBrowser.cpp b/gqb/gqbBrowser.cpp new file mode 100644 index 0000000..dfc60fb --- /dev/null +++ b/gqb/gqbBrowser.cpp @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbBrowser.cpp - Tables Tree of GQB. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "gqb/gqbBrowser.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbDatabase.h" +#include "gqb/gqbViewController.h" + +// Images +#include "images/table-sm.pngc" +#include "images/view-sm.pngc" +#include "images/namespace-sm.pngc" +#include "images/namespaces.pngc" +#include "images/database-sm.pngc" +#include "images/catalog-sm.pngc" +#include "images/catalogs.pngc" +#include "images/catalogobject-sm.pngc" +#include "images/exttable-sm.pngc" // Greenplum external tables + +BEGIN_EVENT_TABLE(gqbBrowser, wxTreeCtrl) + EVT_TREE_ITEM_ACTIVATED(GQB_BROWSER, gqbBrowser::OnItemActivated) + EVT_TREE_BEGIN_DRAG(GQB_BROWSER, gqbBrowser::OnBeginDrag) +END_EVENT_TABLE() + +gqbBrowser::gqbBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, gqbController *_controller) + : wxTreeCtrl(parent, id, pos, size, style) +{ + controller = _controller; + rootNode = (wxTreeItemId *)NULL; + + // Create normal images list of browser + // Remember to update enum gqbImages in gqbBrowser.h if changing the images!! + imageList = new wxImageList(16, 16); + imageList->Add(*database_sm_png_ico); + imageList->Add(*namespace_sm_png_ico); + imageList->Add(*table_sm_png_ico); + imageList->Add(*namespaces_png_ico); + imageList->Add(*catalogs_png_ico); + imageList->Add(*catalog_sm_png_ico); + imageList->Add(*catalogobject_sm_png_ico); + imageList->Add(*view_sm_png_ico); + imageList->Add(*exttable_sm_png_ico); + this->AssignImageList(imageList); +} + + +// Destructor +gqbBrowser::~gqbBrowser() +{ + this->DeleteAllItems(); // This remove and delete data inside tree's node +} + + +// Create root node +wxTreeItemId &gqbBrowser::createRoot(wxString &Name) +{ + rootNode = this->AddRoot(Name, 0, 0); + catalogsNode = this->AppendItem(rootNode, _("Catalogs"), GQB_IMG_CATALOGS, GQB_IMG_CATALOGS, NULL); + schemasNode = this->AppendItem(rootNode, _("Schemas"), GQB_IMG_NAMESPACES, GQB_IMG_NAMESPACES, NULL); + return rootNode; +} + + +// Event activated when user double click on a item of tree +void gqbBrowser::OnItemActivated(wxTreeEvent &event) +{ + wxTreeItemId itemId = event.GetItem(); + gqbObject *object = (gqbObject *) GetItemData(itemId); + if(object) + { + if (object->getType() == GQB_TABLE || object->getType() == GQB_VIEW) + { + gqbTable *item = (gqbTable *) object; + controller->addTableToModel(item, wxPoint(10, 10)); + controller->getView()->Refresh(); + } + else if (GetChildrenCount(itemId) == 0 && object->getType() == GQB_SCHEMA) + { + gqbSchema *schema = (gqbSchema *)object; + schema->createObjects(this, schema->getOid(), itemId, GQB_IMG_TABLE, GQB_IMG_VIEW, GQB_IMG_EXTTABLE); + } + } + +} + +void gqbBrowser::refreshTables(pgConn *connection) +{ + controller->emptyModel(); + this->DeleteAllItems(); + gqbDatabase *Data = new gqbDatabase(wxEmptyString, connection); + Data->createObjects(this); + this->Expand(rootNode); +} + + +void gqbBrowser::OnBeginDrag(wxTreeEvent &event) +{ + wxTreeItemId itemId = event.GetItem(); + + // Simplest solution, simulate DnD but actually don't do it + gqbObject *object = (gqbObject *) GetItemData(itemId); + if(object != NULL && (object->getType() == GQB_TABLE || object->getType() == GQB_VIEW)) + { + gqbTable *item = (gqbTable *) object; + wxString tableName = item->getName(); + wxTextDataObject textData(tableName); + wxDropSource dragSource(this); + dragSource.SetData(textData); + wxDragResult result = dragSource.DoDragDrop(wxDrag_CopyOnly); + if(result == wxDragCopy) + { + controller->getView()->CalcUnscrolledPosition(xx, yy, &xx, &yy); + gqbQueryObject *queryObj = controller->addTableToModel(item, wxPoint(xx, yy)); + controller->getView()->Refresh(); + if (queryObj) + { + controller->getView()->Update(); + controller->getView()->updateModelSize(queryObj, false); + } + } + } +} diff --git a/gqb/gqbCollection.cpp b/gqb/gqbCollection.cpp new file mode 100644 index 0000000..a743663 --- /dev/null +++ b/gqb/gqbCollection.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbCollection.cpp - Generic implementation of a Collection used by GQB. +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbCollection.h" +#include "gqb/gqbObject.h" + +gqbCollection::gqbCollection(gqbCollectionBase *collectionBase) +{ + collection = collectionBase; +} + + +gqbCollection::~gqbCollection() +{ + if(collection) + delete collection; +} + + +void gqbCollection::addItem(gqbObject *item) +{ + collection->addItem(item); +} + + +void gqbCollection::removeItem(gqbObject *item) +{ + collection->removeItem(item); +} + + +gqbIteratorBase *gqbCollection::createIterator() +{ + return collection->createIterator(); +} + +gqbIteratorBase *gqbCollection::createDownIterator() +{ + return collection->createDownIterator(); +} + + +int gqbCollection::count() +{ + return collection->count(); +} + + +bool gqbCollection::existsObject(gqbObject *item) +{ + return collection->existsObject(item); +} + + +gqbObject *gqbCollection::getItemAt(int index) +{ + return collection->getItemAt(index); +} + + +// Remove all items from collection without deleting each one. +void gqbCollection::removeAll() +{ + collection->removeAll(); +} + + +void gqbCollection::deleteAll() +{ + collection->deleteAll(); +} + + +int gqbCollection::getIndex(gqbObject *item) +{ + return collection->getIndex(item); +} + + +void gqbCollection::insertAtIndex(gqbObject *item, int index) +{ + collection->insertAtIndex(item, index); +} diff --git a/gqb/gqbColumn.cpp b/gqb/gqbColumn.cpp new file mode 100644 index 0000000..2c2e847 --- /dev/null +++ b/gqb/gqbColumn.cpp @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbColumn.cpp - Column Object for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbColumn.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbArrayCollection.h" + +gqbColumn::gqbColumn(gqbObject *parent, wxString name, pgConn *connection): + gqbObject(name, parent, connection) +{ + setType(GQB_COLUMN); +} diff --git a/gqb/gqbController.cpp b/gqb/gqbController.cpp new file mode 100644 index 0000000..de4927c --- /dev/null +++ b/gqb/gqbController.cpp @@ -0,0 +1,606 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbController.cpp - Controller part of MVC Software Pattern used by GQB +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "frm/frmQuery.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbBrowser.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbViewPanels.h" + +wxWindowID CTL_NTBKPANELS = ::wxNewId(); + +gqbController::gqbController(gqbModel *_model, wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size = wxSize(GQB_MIN_WIDTH, GQB_MIN_HEIGHT)) + : wxObject() +{ + pparent = gqbParent; + model = _model; + wxSize tablesBrowserSize = wxSize(200, 800); //Initial Size + + // Initialize Main Splitter + gqbMainContainer = new wxSplitterWindow(gqbParent, GQB_HORZ_SASH, wxDefaultPosition, wxDefaultSize, wxSP_3D); + tabs = new wxNotebook(gqbMainContainer, CTL_NTBKPANELS, wxDefaultPosition, wxDefaultSize); + + // Initialize view container with tables browser + // GQB-TODO: change 976 with a enum value of events.h + gqbContainer = new gqbSplitter(gqbMainContainer, 976, wxDefaultPosition, wxDefaultSize, wxSP_3D); + + // Initialize view canvas and tables tree + browserPanel = new wxPanel(gqbContainer, wxID_ANY, wxDefaultPosition, tablesBrowserSize); + tablesBrowser = new gqbBrowser(browserPanel, GQB_BROWSER, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxSIMPLE_BORDER, this); + view = new gqbView(gqbContainer, gridParent, size, this, model); + + // Set Drag Target + view->SetDropTarget(new DnDText(tablesBrowser)); + + // Set Scroll Bar & split + view->SetScrollbars( 10, 10, 127, 80 ); + gqbContainer->SplitVertically(browserPanel, view); + + tabs->InsertPage(ti_colsGridPanel, view->getColsGridPanel(), _("Columns")); + tabs->InsertPage(ti_criteriaPanel, view->getCriteriaPanel(), _("Criteria")); + tabs->InsertPage(ti_orderPanel, view->getOrderPanel(), _("Ordering")); + tabs->InsertPage(ti_joinsPanel, view->getJoinsPanel(), _("Joins")); + gqbMainContainer->SplitHorizontally(gqbContainer, tabs); + + // Fix Sash resize bug + gqbContainer->setTablesBrowser(tablesBrowser); + gqbContainer->setBrowserPanel(browserPanel); +} + + +// Destructor +gqbController::~gqbController() +{ + if(view) + { + delete view; + view = NULL; + } +} + + +// Add a table to the model +gqbQueryObject *gqbController::addTableToModel(gqbTable *table, wxPoint p) +{ + gqbQueryObject *added = model->addTable(table, p); + view->newTableAdded(added); + return added; +} + + +// Remove a table from the model +void gqbController::removeTableFromModel(gqbQueryObject *mtable, gqbGridProjTable *gridTable = NULL, gqbGridOrderTable *orderLTable = NULL, gqbGridOrderTable *orderRTable = NULL) +{ + model->deleteTable(mtable); + gridTable->removeAllRows(mtable); // GQB-TODO: move this functions to model?? + orderLTable->emptyTableData(mtable); + orderRTable->emptyTableData(mtable); +} + + +// Add (Select to be use in projection) a column for table in a model +void gqbController::processColumnInModel(gqbQueryObject *table, gqbColumn *column, gqbGridProjTable *gridTable = NULL) +{ + if(!table->existsColumn(column)) + { + table->addColumn(column); + if(gridTable) + { + gridTable->AppendItem(0, table); + gridTable->AppendItem(1, column); + gridTable->AppendItem(2, NULL); + } + } + else + { + // Removes but don't delete because we needed the column at table [this is just a pointer to it] + table->removeColumn(column); + if(gridTable) + { + gridTable->removeRow(table, column); + } + } +} + + +// Get selected item at position pt, marks item as selected and if there is a previous selected then unselect it +gqbObject *gqbController::getModelSelected(wxPoint &pt, gqbQueryObject *lastSelected, gqbQueryJoin *lastJoinSelected, bool mark) +{ + gqbQueryObject *sel = NULL; + gqbQueryJoin *jSel = NULL; + gqbIteratorBase *iterator = model->createDownQueryIterator(); + bool found = false; + + while(!found && iterator->HasNext()) + { + // Try to find if click over a table + sel = (gqbQueryObject *)iterator->Next(); + if( ((pt.x - sel->position.x > 0 ) && (sel->position.x + sel->getWidth() > pt.x)) && ((pt.y - sel->position.y > 0) && (sel->position.y + sel->getHeight() > pt.y)) ) + { + // GQB-TODO: this function should be move to the view to allow to + // recalculate it if the graphBehavior changes + if(mark) + sel->setSelected(true); + + jSel = NULL; + found = true; + break; + } + + // Try to find if user click over a Join + if(sel->getHaveJoins()) + { + gqbIteratorBase *joinsIterator = sel->createJoinsIterator(); + while(joinsIterator->HasNext()) + { + // GQB-TODO: don't pass anchor because join it's passed as parameter yet. + jSel = (gqbQueryJoin *) joinsIterator->Next(); + wxPoint o = jSel->getSourceAnchor(); + wxPoint d = jSel->getDestAnchor(); + + if(view->clickOnJoin(jSel, pt, o, d)) + { + if(mark) + jSel->setSelected(true); + found = true; + sel = NULL; + break; + } + + } + delete joinsIterator; + } + } + + delete iterator; + + if(found) + { + if(mark) + { + if(lastSelected && lastSelected != sel) // Unselect previous table selected if exists + lastSelected->setSelected(false); + // Unselect previous join selected if exists + if(lastJoinSelected && lastJoinSelected != jSel) + lastJoinSelected->setSelected(false); + } + if(sel) + return sel; + else if(jSel) + return jSel; + } + + return NULL; +} + + +// Unselect any previously selected item in the model +void gqbController::unsetModelSelected(bool queryTable = true) +{ + gqbQueryObject *sel = NULL; + gqbQueryJoin *jSel = NULL; + + if(queryTable) // QueryTable + { + gqbIteratorBase *iterator = model->createQueryIterator(); + while(iterator->HasNext()) + { + sel = (gqbQueryObject *)iterator->Next(); + if(sel->getSelected()) + { + sel->setSelected(false); + } + } + delete iterator; + } + + if(!queryTable) // QueryJoin + { + gqbIteratorBase *iterator = model->createQueryIterator(); + gqbQueryObject *sel = NULL; + while(iterator->HasNext()) + { + sel = (gqbQueryObject *)iterator->Next(); + if(sel->getHaveJoins()) + { + gqbIteratorBase *joinsIterator = sel->createJoinsIterator(); + while(joinsIterator->HasNext()) + { + // GQB-TODO: don't pass anchor because join it's passed as parameter yet. + jSel = (gqbQueryJoin *) joinsIterator->Next(); + if(jSel->getSelected()) + { + jSel->setSelected(false); + } + } + + delete joinsIterator; + } + } + delete iterator; + } +} + + +// GQB-TODO: Create a less complex & simpler generation function +// Generate the SQL Sentence from the model +wxString gqbController::generateSQL() +{ + wxString sentence = wxT(""); + if(model->tablesCount() > 0) + { + sentence += wxT("SELECT \n"); + + // Add selected columns for Query + gqbQueryObject *sel = NULL; + gqbIteratorBase *iteratorRestrictions = NULL; + gqbIteratorBase *iteratorModel = NULL; + gqbIteratorBase *iteratorJoins = NULL; + + // Projection Part [Select x,x,x...] + gqbObjsArray *cols = model->getOrderedColumns(); + gqbObjsArray *tables = model->getColumnsParents(); + wxArrayString *alias = model->getColumnsAlias(); + + int i, size = cols->GetCount(); + + for(i = 0; i < size; i++) + { + if(alias->Item(i).length() > 0) + { + if(((gqbQueryObject *)tables->Item(i))->getAlias().length() > 0) + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getAlias()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(" AS ") + + qtIdent(alias->Item(i)) + + wxT(", \n"); + } + else + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getName()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(" AS ") + + qtIdent(alias->Item(i)) + + wxT(", \n"); + } + } + else + { + if(((gqbQueryObject *)tables->Item(i))->getAlias().length() > 0) + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getAlias()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(", \n"); + } + else + { + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)tables->Item(i))->getName()) + + wxT(".") + + qtIdent(((gqbColumn *)cols->Item(i))->getName()) + + wxT(", \n"); + } + } + } + + if(!size) + sentence += wxT(" * \n"); + else + { + // remove last ", " + sentence.Truncate(sentence.Length() - 3); + sentence += wxT("\n"); + } + + sentence += wxT("FROM \n"); + + iteratorModel = model->createQueryIterator(); + while(iteratorModel->HasNext()) + { + sel = (gqbQueryObject *)iteratorModel->Next(); + gqbSchema *schema = (gqbSchema *)sel->parent->getOwner(); + if(sel->getAlias().length() > 0) + { + sentence += wxT(" ") + + qtIdent(schema->getName()) + + wxT(".") + + qtIdent(sel->getName()) + + wxT(" ") + + qtIdent(sel->getAlias()) + + wxT(", \n"); + } + else + { + sentence += wxT(" ") + + qtIdent(schema->getName()) + + wxT(".") + + qtIdent(sel->getName()) + + wxT(", \n"); + } + + } + sentence.Truncate(sentence.Length() - 3); // remove last ", " + + // WHERE PART + // [Joins] + bool first = true, truncAnd = false; + gqbQueryJoin *tmp; + iteratorModel->ResetIterator(); + while(iteratorModel->HasNext()) + { + sel = (gqbQueryObject *)iteratorModel->Next(); + if(sel->getHaveJoins()) + { + truncAnd = true; + iteratorJoins = sel->createJoinsIterator(); + while(iteratorJoins->HasNext()) + { + if(first) + { + first = false; + sentence += wxT("\nWHERE \n"); + } + tmp = (gqbQueryJoin *)iteratorJoins->Next(); + + if(tmp->getSourceQTable()->getAlias().length() > 0) + sentence += wxT(" ") + + qtIdent(tmp->getSourceQTable()->getAlias()) + + wxT(".") + + qtIdent(tmp->getSourceCol()); + else + sentence += wxT(" ") + + qtIdent(tmp->getSourceQTable()->getName()) + + wxT(".") + + qtIdent(tmp->getSourceCol()); + + switch(tmp->getKindofJoin()) + { + case _equally: + sentence += wxT(" = "); + break; + case _greater: + sentence += wxT(" > "); + break; + case _lesser: + sentence += wxT(" < "); + break; + case _equgreater: + sentence += wxT(" >= "); + break; + case _equlesser: + sentence += wxT(" <= "); + break; + + } + + if(tmp->getDestQTable()->getAlias().length() > 0) + sentence += qtIdent(tmp->getDestQTable()->getAlias()) + + wxT(".") + + qtIdent(tmp->getDestCol()) + + wxT(" AND\n"); + else + sentence += qtIdent(tmp->getDestQTable()->getName()) + + wxT(".") + + qtIdent(tmp->getDestCol()) + + wxT(" AND\n"); + } + delete iteratorJoins; + } + } + delete iteratorModel; + + gqbRestrictions *restrictions = model->getRestrictions(); + + // Remove last " AND " from joins if there isn't restrictions, only left white space + if(truncAnd && (restrictions->restrictionsCount() <= 0)) + sentence.Truncate(sentence.Length() - 5); + + // Never found a join + if (!truncAnd && (restrictions->restrictionsCount() > 0)) + sentence += wxT("\nWHERE \n"); + + //GQB-TODO: VALIDATE RESTRICTIONS + iteratorRestrictions = restrictions->createRestrictionsIterator(); + gqbQueryRestriction *r = NULL; + + while(iteratorRestrictions->HasNext()) + { + r = (gqbQueryRestriction *)iteratorRestrictions->Next(); + sentence += wxT(" ") + + r->getLeft() + + wxT(" ") + + r->getRestriction() + + wxT(" ") + + r->getValue_s() + + wxT(" ") + + r->getConnector() + + wxT(" \n"); + } + delete iteratorRestrictions; + + if(restrictions->restrictionsCount() > 0) + { + if(r->getConnector().Contains(wxT("AND"))) + { + sentence.Truncate(sentence.Length() - 6); + } + else + { + sentence.Truncate(sentence.Length() - 5); + } + } + // ORDER BY PART + gqbObjsArray *orderByColumns = model->getOrdByColumns(); + gqbObjsArray *orderByParents = model->getOrdByParents(); + charArray *typeOfOrder = model->getOrdByKind(); + + size = orderByColumns->GetCount(); + if(size > 0) + { + sentence += wxT("\nORDER BY\n"); + } + wxString typeOrder = wxT(""); + for(i = 0; i < size; i++) + { + switch(typeOfOrder->Item(i)) + { + case 'A': + typeOrder = wxT(" ASC"); + break; + case 'D': + typeOrder = wxT(" DESC"); + break; + }; + if(((gqbQueryObject *)orderByParents->Item(i))->getAlias().length() > 0) + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)orderByParents->Item(i))->getAlias()) + + wxT(".") + + qtIdent(((gqbColumn *)orderByColumns->Item(i))->getName()) + + typeOrder + + wxT(", \n"); + else + sentence += wxT(" ") + + qtIdent(((gqbQueryObject *)orderByParents->Item(i))->getName()) + + wxT(".") + + qtIdent(((gqbColumn *)orderByColumns->Item(i))->getName()) + + typeOrder + + wxT(", \n"); + } + + if(size > 0) + sentence.Truncate(sentence.Length() - 3); + + sentence += wxT(";"); + } // Close Tables Count > 0 on model + return sentence; +} + + +gqbQueryRestriction *gqbController::addRestriction() +{ + return model->addRestriction(); +} + + +gqbQueryJoin *gqbController::addJoin(gqbQueryObject *sTable, gqbColumn *sColumn, gqbQueryObject *dTable, gqbColumn *dColumn, type_Join kind) +{ + return sTable->addJoin(sTable, dTable, sColumn, dColumn, kind); +} + + +void gqbController::removeJoin(gqbQueryJoin *join) +{ + join->getSourceQTable()->removeJoin(join, true); +} + + +void gqbController::setPointerMode(pointerMode pm) +{ + view->setPointerMode(pm); +} + + +void gqbController::emptyModel() +{ + view->emptyPanelsData(); + model->emptyAll(); +} + + +void gqbController::calcGridColsSizes() +{ + // Recalculate best internals sizes for all columns inside grids. + ((gqbGridPanel *)view->getColsGridPanel())->SetGridColsSize(); + ((gqbCriteriaPanel *)view->getCriteriaPanel())->SetGridColsSize(); + ((gqbOrderPanel *)view->getOrderPanel())->SetGridColsSize(); + ((gqbJoinsPanel *)view->getJoinsPanel())->SetGridColsSize(); +} + + +void gqbController::setSashVertPosition(int pos) +{ + gqbContainer->UpdateSize(); + gqbContainer->SetSashPosition(pos, true); + gqbContainer->SetMinimumPaneSize(pos); + gqbContainer->UpdateSize(); +} + +int gqbController::getSashHorizPosition() +{ + return gqbMainContainer->GetSashPosition(); +} + + +void gqbController::setSashHorizPosition(int pos) +{ + gqbMainContainer->UpdateSize(); + gqbMainContainer->SetSashPosition(pos, true); + + if(pos >= 150 && pos <= 200) + { + gqbMainContainer->SetMinimumPaneSize(pos); + } + else + { + gqbMainContainer->SetMinimumPaneSize(150); + } + gqbMainContainer->UpdateSize(); +} + + +// +// Utility Class to avoid a bug when the event sash resize is called [onVerticalSashResize] +// + +// GQB-TODO: fix 976 for real one value here and above + +BEGIN_EVENT_TABLE(gqbSplitter, wxSplitterWindow) + EVT_SPLITTER_SASH_POS_CHANGED(976, gqbSplitter::onVerticalSashResize) +END_EVENT_TABLE() + +gqbSplitter::gqbSplitter(wxWindow *parent, wxWindowID id, const wxPoint &point, const wxSize &size, long style) + : wxSplitterWindow(parent, id, point, size, style), + tablesBrowser(NULL), + browserPanel(NULL) +{ +} + + +void gqbSplitter::onVerticalSashResize(wxSplitterEvent &event) +{ + if(tablesBrowser != NULL && browserPanel != NULL) + { + wxSize s = tablesBrowser->GetSize(); + s.SetWidth(event.GetSashPosition()); + browserPanel->SetSize(s); + tablesBrowser->SetSize(s); + // GQB-TODO: Set a minimun value + } +} diff --git a/gqb/gqbDatabase.cpp b/gqb/gqbDatabase.cpp new file mode 100644 index 0000000..50fbded --- /dev/null +++ b/gqb/gqbDatabase.cpp @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbDatabase.cpp - Database object for GQB. +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "gqb/gqbDatabase.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbSchema.h" +#include "schema/pgSchema.h" + +gqbDatabase::gqbDatabase(wxString name, pgConn *connection) + : gqbObject(name, NULL, connection) +{ + setType(GQB_DATABASE); +} + + +void gqbDatabase::createObjects(gqbBrowser *_tablesBrowser) +{ + + wxString rootNodeString = wxString(conn->GetDbname()); + // Create Root Node + _tablesBrowser->createRoot(rootNodeString); + + // FillBrowser + createSchemas(_tablesBrowser, _tablesBrowser->getCatalogRootNode(), GQB_CATALOG, GQB_IMG_CATALOG); + createSchemas(_tablesBrowser, _tablesBrowser->getTablesRootNode(), GQB_OTHER, GQB_IMG_NAMESPACE); +} + + +// Use database connection to create all objects inside tree +void gqbDatabase::createSchemas(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, typeSchema MetaType, int indexImage) +{ + + // Search Schemas and insert it + wxString restr = wxT(" WHERE "); + + if (MetaType != GQB_CATALOG) + { + restr += wxT("NOT "); + } + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'dbo' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'systables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'sys' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'all_tables' AND relnamespace = nsp.oid LIMIT 1)))\n"); + + if (conn->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + wxString sql; + + if (MetaType == GQB_CATALOG) + { + sql = wxT("SELECT 2 AS nsptyp, nspname, nsp.oid") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + else + { + if (conn->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp, nspname, nsp.oid\n") + wxT(" FROM pg_namespace nsp\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + + pgSet *schemas = conn->ExecuteSet(sql); + wxTreeItemId parent; + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && MetaType != GQB_CATALOG && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + int tableImage = GQB_IMG_TABLE, viewImage = GQB_IMG_VIEW; + gqbSchema *schema; + + if (MetaType == GQB_CATALOG) + { + + // Create Schema Object + schema = new gqbSchema(this, name, conn, schemas->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, name, indexImage, indexImage, schema); + schema->createObjects(tablesBrowser, schema->getOid(), parent, GQB_IMG_TABLE, GQB_IMG_VIEW, GQB_IMG_EXTTABLE); + + if(name != wxT("pg_catalog") && name != wxT("pgagent")) + { + tableImage = GQB_IMG_CATALOG_OBJ; + viewImage = GQB_IMG_CATALOG_OBJ; + } + } + else + { + + // Create Schema Object + // Note that the schema will be populated when the node is expanded. + schema = new gqbSchema(this, name, conn, schemas->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, name , indexImage, indexImage, schema); + schema->createObjects(tablesBrowser, schema->getOid(), parent, GQB_IMG_TABLE, GQB_IMG_VIEW, GQB_IMG_EXTTABLE); + } + + schemas->MoveNext(); + } + + delete schemas; + } +} diff --git a/gqb/gqbGraphSimple.cpp b/gqb/gqbGraphSimple.cpp new file mode 100644 index 0000000..979486a --- /dev/null +++ b/gqb/gqbGraphSimple.cpp @@ -0,0 +1,494 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGraphsimple.cpp - A simple Implementation of the Graphic Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "utils/sysSettings.h" +#include "gqb/gqbGraphSimple.h" +#include "gqb/gqbQueryObjs.h" +// GQB Images +#include "images/gqbColNotSel.pngc" +#include "images/gqbColSel.pngc" + +gqbGraphSimple::gqbGraphSimple() +{ + normalFont = settings->GetSystemFont(); + TableTitleFont = settings->GetSystemFont(); + TableTitleFont.SetWeight(wxFONTWEIGHT_BOLD); + BackgroundLayer1 = wxBrush(wxColour(112, 112, 112), wxSOLID); + BackgroundLayer2 = wxBrush (wxColour(208, 208, 208), wxSOLID); + BackgroundTitle = wxBrush (wxColour(245, 245, 245), wxSOLID); + minTableWidth = 80; + minTableHeight = 54; + rowHeight = 0; //By default but this it's replaced by font metrics value + rowLeftMargin = 14; + rowRightMargin = 5; + rowTopMargin = 1; + lineClickThreshold = 7; + selectedPen = wxPen(wxColour(0, 146, 195), 2, wxSOLID); + selectedBrush = wxBrush(wxColour(0, 146, 195), wxSOLID); + imgSelBoxEmpty = *gqbColNotSel_png_bmp; + imgSelBoxSelected = *gqbColSel_png_bmp; + +} + + +// NOTES:(1) store values of width & height at queryTable. +// (2)Need to set a font for the device context before get font metrics with GetTextExtent +void gqbGraphSimple::drawTable(wxMemoryDC &bdc, wxPoint *origin, gqbQueryObject *queryTable) +{ + +#if wxCHECK_VERSION(2, 9, 0) + wxCoord w = 0, h = 0, height = 0, width = 0, margin = 5; +#else + long w = 0, h = 0, height = 0, width = 0, margin = 5; +#endif + + // Get Value for row Height + if(!rowHeight) + { + bdc.SetFont(TableTitleFont); + bdc.GetTextExtent(wxT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxtz"), &w, &h); + rowHeight = h; + } + + // Get Title Metrics + bdc.SetFont(TableTitleFont); + height += rowHeight + rowTopMargin; + + // Calculate font metrics for table title with/without alias + if(queryTable->getAlias().length() > 0) + bdc.GetTextExtent(queryTable->getName() + wxT(" (") + queryTable->getAlias() + wxT(")"), &w, &h); + else + bdc.GetTextExtent(queryTable->getName(), &w, &h); + width = rowLeftMargin + w + rowRightMargin; + + // Get Columns Metrics + bdc.SetFont(normalFont); + + // Don't use h value from font metrics to get consistency between columns vertical separation (height) + height += rowHeight * queryTable->parent->countCols() + rowTopMargin * queryTable->parent->countCols(); + gqbIteratorBase *iterator = queryTable->parent->createColumnsIterator(); + while(iterator->HasNext()) + { + gqbColumn *tmp = (gqbColumn *)iterator->Next(); + bdc.GetTextExtent(tmp->getName(), &w, &h); + if((rowLeftMargin + w + rowRightMargin) > width) + width = rowLeftMargin + w + rowRightMargin; + } + + //Don't delete iterator because will be use below; + + // Set table Size in ObjectModel (Temporary Values for object representation, + // and for this reason the view can modified model without using the controller + // because this values are used by controller when use object's size in internal operations) + if( (height + 2) < minTableHeight) // +2 from BackgroundLayers addition + { + queryTable->setHeight(minTableHeight); + height = minTableHeight; + } + else + queryTable->setHeight(height + 2); + + if( (width + 2) < minTableWidth) + { + queryTable->setWidth(minTableWidth); + width = minTableWidth; + } + else + queryTable->setWidth(width + 2); + + //Decorate Table + bdc.SetPen(*wxTRANSPARENT_PEN); + + //draw second Layer + bdc.SetBrush(BackgroundLayer2); + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width + 2, height + 2))); + + //draw third Layer + bdc.SetBrush(BackgroundLayer1); + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width + 1, height + 1))); + + //draw real frame layer + bdc.SetBrush(*wxWHITE_BRUSH); + if(queryTable->getSelected()) + { + bdc.SetPen(selectedPen); + } + else + { + bdc.SetPen(*wxBLACK_PEN); + } + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width, height))); + + //draw title layer + bdc.SetBrush(BackgroundTitle); + bdc.DrawRectangle(wxRect(wxPoint(origin->x, origin->y), wxSize(width, rowHeight + rowTopMargin))); + bdc.SetFont(TableTitleFont); + if(queryTable->getAlias().length() > 0) + bdc.DrawText(queryTable->getName() + wxT(" (") + queryTable->getAlias() + wxT(")"), origin->x + margin, origin->y + rowTopMargin); + else + bdc.DrawText(queryTable->getName(), origin->x + margin, origin->y + rowTopMargin); + bdc.SetFont(normalFont); + + // GQB-TODO: in a future reuse a little more the iterator creating it inside the Query or Table Object + // and only delete it when delete the query object. + + // Draw Columns + height = rowHeight + rowTopMargin; + iterator->ResetIterator(); + while(iterator->HasNext()) + { + gqbColumn *tmp = (gqbColumn *)iterator->Next(); + if(queryTable->existsColumn(tmp)) + { + bdc.SetTextForeground(* wxRED); + bdc.SetFont(normalFont); + bdc.DrawBitmap(imgSelBoxSelected, origin->x + 3, origin->y + height, true); + } + else + { + bdc.SetFont(normalFont); + bdc.DrawBitmap(imgSelBoxEmpty, origin->x + 3, origin->y + height, true); + } + bdc.DrawText(tmp->getName(), origin->x + rowLeftMargin, origin->y + height); + bdc.SetTextForeground( *wxBLACK); + height += rowHeight + rowTopMargin; + } + delete iterator; //now if delete because it's not needed anymore + +} + + +// return a column when a user click on a checkbox [0->16] x point +gqbColumn *gqbGraphSimple::getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility) +{ + int countCols = queryTable->parent->countCols(), colPos = -1; + if(countCols > 0) //exists any column + { + colPos = (clickPoint->y - queryTable->position.y) / (rowHeight + rowTopMargin); + } + + int x = clickPoint->x - queryTable->position.x; + if( (x > 0 && x < sensibility) && colPos > 0) + + // Because 0 is title + return queryTable->parent->getColumnAtIndex(colPos - 1); + else + return NULL; +} + + +void gqbGraphSimple::drawTempJoinLine(wxMemoryDC &bdc, wxPoint &origin, wxPoint &end) +{ + wxPoint anchorsUsed = wxPoint(0, 0); + + if(origin.x < end.x) + { + anchorsUsed.x = 1; + anchorsUsed.y = -1; + } + else + { + anchorsUsed.x = -1; + anchorsUsed.y = 1; + } + + drawJoin(bdc, origin, end, anchorsUsed, true, _equally); +} + + +void gqbGraphSimple::drawJoin(wxMemoryDC &bdc, wxPoint &origin, wxPoint &dest, wxPoint &anchorUsed, bool selected = false, type_Join joinKind = _equally) +{ + wxPoint origin2 = origin; + wxPoint dest2 = dest; + + if(selected) + { + bdc.SetPen(selectedPen); + bdc.SetBrush(selectedBrush); + } + else + { + bdc.SetPen(*wxBLACK_PEN); + bdc.SetBrush(*wxBLACK_BRUSH); + } + + // GQB-TODO: optimize this if possible, I know one other can be the same? + + // getAnchorsUsed() [-1==left] [1==right] x->origin y->destination + if(anchorUsed.x == 1) + { + bdc.DrawRectangle(origin.x, origin.y - 4, 8, 8); + origin2.x += 20; + } + else + { + bdc.DrawRectangle(origin.x - 8, origin.y - 4, 8, 8); + origin2.x -= 20; + } + + if(anchorUsed.y == 1) + { + bdc.DrawRectangle(dest.x, dest.y - 4, 8, 8); + dest2.x += 20; + } + else + { + bdc.DrawRectangle(dest.x - 8, dest.y - 4, 8, 8); + dest2.x -= 20; + } + + bdc.DrawLine(origin, origin2); + bdc.DrawLine(dest, dest2); + bdc.DrawLine(origin2, dest2); + + // Draw type of join + switch(joinKind) + { + case _equally: + bdc.DrawText(wxT("="), findLineMiddle(origin2, dest2)); + break; + case _lesser: + bdc.DrawText(wxT("<"), findLineMiddle(origin2, dest2)); + break; + case _greater: + bdc.DrawText(wxT(">"), findLineMiddle(origin2, dest2)); + break; + case _equlesser: + bdc.DrawText(wxT("<="), findLineMiddle(origin2, dest2)); + break; + case _equgreater: + bdc.DrawText(wxT(">="), findLineMiddle(origin2, dest2)); + break; + }; +} + + +// Return true if pt click over a threshold of the join, false if not +bool gqbGraphSimple::clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest) +{ + + wxPoint origin2 = origin; + wxPoint dest2 = dest; + + if(join->getAnchorsUsed().x == 1) + { + origin2.x += 20; + } + else + { + origin2.x -= 20; + } + + if(join->getAnchorsUsed().y == 1) + { + dest2.x += 20; + } + else + { + dest2.x -= 20; + } + + // Check origin anchor + bool value1 = insideLine(pt, origin, origin2, lineClickThreshold); + + // Check dest anchor + bool value2 = insideLine(pt, dest, dest2, lineClickThreshold); + + // Check line between both tables + bool value3 = insideLine(pt, origin2, dest2, lineClickThreshold); + + if(value1 || value2 || value3) + return true; + else + return false; +} + + +bool gqbGraphSimple::insideLine(wxPoint &pt, wxPoint &p1, wxPoint &p2, int threshold = 7) +{ + bool value = false; + if(distanceToLine(pt, p1, p2) < threshold) + { + value = true; + } + return value; +} + + +wxPoint gqbGraphSimple::findLineMiddle(wxPoint p1, wxPoint p2) +{ + int middleX = -1, middleY = -1; + + int dx = p2.x - p1.x; + if(dx > 0) // p1 at left + { + middleX = dx / 2 + p1.x; + } // p1 at right + else + { + middleX = p1.x + dx / 2; + } + + int dy = p2.y - p1.y; + if(dy > 0) // p1 is above + { + middleY = dy / 2 + p1.y; + } // p1 is below + else + { + middleY = p1.y + dy / 2; + } + + if(dy == 0) + middleY = p1.y; + if(dx == 0) + middleX = p1.x; + + return wxPoint(middleX, middleY); +} + + +double gqbGraphSimple::distanceToLine(wxPoint pt, wxPoint p1, wxPoint p2) +{ + p2.x -= p1.x; + p2.y -= p1.y; + + pt.x -= p1.x; + pt.y -= p1.y; + + double dprod = pt.x * p2.x + pt.y * p2.y; + double pLenSq; + + if(dprod <= 0.0) + { + pLenSq = 0.0; + } + else + { + pt.x = p2.x - pt.x; + pt.y = p2.y - pt.y; + dprod = pt.x * p2.x + pt.y * p2.y; + if(dprod <= 0.0) + { + pLenSq = 0.0; + } + else + { + pLenSq = dprod * dprod / (p2.x * p2.x + p2.y * p2.y); + } + } + + double lengthSq = pt.x * pt.x + pt.y * pt.y - pLenSq; + + if(lengthSq < 0) + { + lengthSq = 0; + } + + double length = sqrt(lengthSq); + + return length; +} + + +// Set the anchors points [source, destination] for a join +void gqbGraphSimple::calcAnchorPoint(gqbQueryJoin *join) +{ + int index, x, y; + wxPoint use; // [-1==left] [1==right] x->origin y->destination + int sx = join->getSourceQTable()->position.x; + int sy = join->getSourceQTable()->position.y; + int dx = join->getDestQTable()->position.x; + int dy = join->getDestQTable()->position.y; + + // Source + index = join->getSourceQTable()->getColumnIndex(join->getSCol()) + 1; + if(sx < dx) + { + x = sx + join->getSourceQTable()->getWidth(); + use.x = 1; + } + else + { + x = sx; + use.x = -1; + } + y = sy + index * (rowHeight + rowTopMargin) + ((rowHeight + rowTopMargin) / 2); + join->setSourceAnchor(wxPoint(x, y)); + + // Destination + index = join->getDestQTable()->getColumnIndex(join->getDCol()) + 1; + if(dx < sx) + { + x = dx + join->getDestQTable()->getWidth(); + use.y = 1; + } + else + { + x = dx; + use.y = -1; + } + y = dy + index * (rowHeight + rowTopMargin) + ((rowHeight + rowTopMargin) / 2); + join->setDestAnchor(wxPoint(x, y)); + + join->setAnchorsUsed(use); +} + + +// Update position of Object in the query if move table & adjust all other items like joins (own & registered) +void gqbGraphSimple::UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment) +{ + x -= cursorAdjustment; // Move Pointer to a better Position; + y -= rowHeight / 2; + + // Update position of table + // Do not allow table/view moved/repositioned less than (0, 0) cordinates + queryTable->position.x = x > 0 ? x : 0; + queryTable->position.y = y > 0 ? y : 0; + + // Update position of anchor points of Joins that origin from this table + if(queryTable->getHaveJoins()) + { + gqbIteratorBase *j = queryTable->createJoinsIterator(); + while(j->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)j->Next(); + calcAnchorPoint(tmp); + } + delete j; + } + + // Update position of anchor points of Joins that come from others tables + if(queryTable->getHaveRegJoins()) + { + gqbIteratorBase *r = queryTable->createRegJoinsIterator(); + while(r->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)r->Next(); + calcAnchorPoint(tmp); + } + delete r; + } +} + + +int gqbGraphSimple::getTitleRowHeight() +{ + return rowHeight; +} diff --git a/gqb/gqbGridJoinTable.cpp b/gqb/gqbGridJoinTable.cpp new file mode 100644 index 0000000..6318566 --- /dev/null +++ b/gqb/gqbGridJoinTable.cpp @@ -0,0 +1,287 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridJoinTable.cpp - Table implementation for Joins Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbGridJoinTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbViewController.h" + +gqbGridJoinTable::gqbGridJoinTable(gqbController *_controller): + wxGridTableBase() +{ + controller = _controller; +} + + +gqbGridJoinTable::~gqbGridJoinTable() +{ + emptyTableData(); +} + + +int gqbGridJoinTable::GetNumberRows() +{ + return joins.count(); +} + + +int gqbGridJoinTable::GetNumberCols() +{ + return 3; +} + + +bool gqbGridJoinTable::IsEmptyCell( int row, int col ) +{ + if (joins.count() == 0) + return true; + return false; +} + + +wxString gqbGridJoinTable::GetValue( int row, int col ) +{ + if (row >= joins.count()) + return wxEmptyString; + gqbQueryJoin *obj = (gqbQueryJoin *)joins.getItemAt(row); + + switch(col) + { + case 0: + { + gqbQueryObject *srcTbl = obj->getSourceQTable(); + wxString sStr = srcTbl ? (srcTbl->getAlias().IsEmpty() ? qtIdent(srcTbl->getName()) : qtIdent(srcTbl->getAlias())) : wxString(wxEmptyString); + if ( !sStr.IsEmpty() ) + sStr += wxT(".") + qtIdent(obj->getSourceCol()); + return sStr; + } + case 1: + switch(obj->getKindofJoin()) + { + case _equally: + return wxT("="); + case _lesser: + return wxT("<"); + case _greater: + return wxT(">"); + case _equlesser: + return wxT("<="); + case _equgreater: + return wxT(">="); + } + return wxEmptyString; + case 2: + { + gqbQueryObject *destTbl = obj->getDestQTable(); + wxString dStr = destTbl ? (destTbl->getAlias().IsEmpty() ? qtIdent(destTbl->getName()) : qtIdent(destTbl->getAlias())) : wxString(wxEmptyString); + if ( !dStr.IsEmpty() ) + dStr += wxT(".") + obj->getDestCol(); + return dStr; + } + break; + }; + return wxT(""); +} + + +void gqbGridJoinTable::SetValue( int row, int col, const wxString &value ) +{ + if (col == 1) + { + gqbQueryJoin *join = (gqbQueryJoin *)joins.getItemAt(row); + if (value == wxT("=")) + join->setKindofJoin(_equally); + else if (value == wxT("<")) + join->setKindofJoin(_lesser); + else if (value == wxT(">")) + join->setKindofJoin(_greater); + else if (value == wxT("<=")) + join->setKindofJoin(_equlesser); + else if (value == wxT(">=")) + join->setKindofJoin(_equgreater); + controller->getView()->Refresh(); + } +} + +bool gqbGridJoinTable::ReplaceJoin( gqbQueryJoin *orig, gqbQueryJoin *newVal ) +{ + int rowCount = joins.count(); + for ( int index = 0; index < rowCount; index++ ) + { + if ( joins[ index ] == orig ) + { + joins[ index ] = newVal; + return true; + } + } + return false; +} + +gqbQueryJoin *gqbGridJoinTable::GetJoin( int row ) +{ + if (row >= joins.count()) + return NULL; + return (gqbQueryJoin *)joins.getItemAt(row); +} + + +void gqbGridJoinTable::removeJoin(gqbQueryJoin *item) +{ + if (item == NULL || this->joins.count() == 0) + return; + int index = joins.getIndex( item ); + if (index == -1) + return; + joins.removeItem( item ); + if (GetView()) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + index + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } +} + +void gqbGridJoinTable::removeJoins(gqbQueryObject *obj) +{ + if (!obj) + return; + + if (obj->getHaveJoins()) + { + gqbIteratorBase *itrJoins = obj->createJoinsIterator(); + if (itrJoins) + { + while (itrJoins->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)itrJoins->Next(); + removeJoin(tmp); + } + } + } + + if (obj->getHaveRegJoins()) + { + gqbIteratorBase *itrRegJoins = obj->createRegJoinsIterator(); + if (itrRegJoins) + { + while (itrRegJoins->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)itrRegJoins->Next(); + removeJoin(tmp); + } + } + } +} + +void gqbGridJoinTable::AppendJoin(gqbQueryJoin *item) +{ + bool notify = true; + if ( item == NULL ) + { + item = new gqbQueryJoin(NULL, NULL, NULL, NULL, _equally); + } + joins.addItem( item ); + if (notify && GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + joins.count(), + 1 ); + GetView()->ProcessTableMessage( msg ); + + int row = GetView()->GetNumberRows() - 1; + + wxString strChoices[] = {wxT("="), wxT("<"), wxT("<="), wxT(">"), wxT(">=")}; + + GetView()->SetCellRenderer(row, 0, new wxGridCellButtonRenderer); + GetView()->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + GetView()->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoices), strChoices)); + GetView()->SetCellRenderer(row, 2, new wxGridCellButtonRenderer); + + GetView()->SetReadOnly( row, 0 ); + GetView()->SetReadOnly( row, 2 ); + } +} + + +// Removes all items from gqbGridJoinTable +void gqbGridJoinTable::emptyTableData() +{ + for (int index = joins.count() - 1; index >= 0; index--) + { + gqbQueryJoin *join = (gqbQueryJoin *)joins[index]; + joins.removeItem(join); + + // Join with either source or destination not present needs to be removed here + if (!(join->getSourceQTable() && join->getDestQTable())) + { + delete join; + join = NULL; + } + } +} + +gqbQueryObject *gqbGridJoinTable::DeleteRow(size_t pos) +{ + gqbQueryJoin *join = (gqbQueryJoin *)joins.getItemAt(pos); + gqbQueryObject *srcTbl = NULL; + if (join) + { + this->removeJoin(join); + if (join->getSourceQTable() && join->getDestQTable()) + { + srcTbl = join->getSourceQTable(); + srcTbl->removeJoin(join, true); + } + } + + return srcTbl; +} + +wxString gqbGridJoinTable::GetColLabelValue(int col) +{ + switch(col) + { + case 0: + return _("Source Column"); + case 1: + return _("Join Type"); + case 2: + return _("Destination Column"); + } + return wxEmptyString; +} + + +void gqbGridJoinTable::selectJoin(gqbQueryJoin *join) +{ + int indexRow = joins.getIndex(join); + if (indexRow != -1 && GetView()) + { + GetView()->ClearSelection(); + GetView()->SelectRow(indexRow); + } +} + diff --git a/gqb/gqbGridOrderTable.cpp b/gqb/gqbGridOrderTable.cpp new file mode 100644 index 0000000..1252cec --- /dev/null +++ b/gqb/gqbGridOrderTable.cpp @@ -0,0 +1,293 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridOrderTable.cpp - Table implementation for Order By Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbModel.h" + +gqbGridOrderTable::gqbGridOrderTable(int numColumns, gqbObjsArray *cols, gqbObjsArray *parent, charArray *orderBy) +{ + numberColumns = numColumns; + columns = cols; + colsParents = parent; + kindOfOrder = orderBy; +} + + +gqbGridOrderTable::~gqbGridOrderTable() +{ +} + + +int gqbGridOrderTable::GetNumberRows() +{ + return (columns->GetCount()); +} + + +int gqbGridOrderTable::GetNumberCols() +{ + return numberColumns; +} + + +bool gqbGridOrderTable::IsEmptyCell( int row, int col ) +{ + int count = columns->GetCount(); + if(row + 1 <= count) + return false; + else + return true; +} + + +wxString gqbGridOrderTable::GetValue( int row, int col ) +{ + if(col == 0) + { + wxString col = wxT(""); + if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length() > 0) + { + col += ((gqbQueryObject *)colsParents->Item(row))->getAlias() + wxT("."); + } + else + { + col += ((gqbQueryObject *)colsParents->Item(row))->getName() + wxT("."); + } + col += ((gqbColumn *)columns->Item(row))->getName(); + return col; + } + + if(numberColumns == 2) + { + if(col == 1) + { + wxString ord = wxT(""); + if(kindOfOrder->Item(row) == 'A') + ord += wxT("ASC"); + else + ord += wxT("DESC"); + + return ord; + } + } + return wxT(""); +} + + +wxString gqbGridOrderTable::GetColLabelValue(int col) +{ + switch(col) + { + case 0: + if(numberColumns == 2) + { + return _("Column"); + } + else + { + return _("Available Columns"); + } + break; + case 1: + return _("Order"); + break; + }; + return wxT(""); +} + + +void gqbGridOrderTable::SetValue( int row, int col, const wxString &value ) +{ + if(col == 1 && numberColumns == 2) + { + if(value.Contains(wxT("ASC"))) + { + kindOfOrder->Item(row) = 'A'; + } + else + { + kindOfOrder->Item(row) = 'D'; + } + } +} + + +void gqbGridOrderTable::AppendItem(gqbColumn *column, gqbQueryObject *parent, char kindOrder) +{ + columns->Add(column); + colsParents->Add(parent); + if(numberColumns == 2) + { + kindOfOrder->Add(kindOrder); + } + + if (GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + (columns->GetCount() - 1), + 1 ); + GetView()->ProcessTableMessage( msg ); + } +} + + +bool gqbGridOrderTable::removeFirstRow(gqbObject *itemTable) +{ + bool found = false; + int i, size = colsParents->GetCount(); + + for(i = 0; i < size; i++) + { + if (colsParents->Item(i) == itemTable) + { + found = true; + break; + } + } + + if(found) + { + columns->RemoveAt(i); + colsParents->RemoveAt(i); + if(numberColumns == 2) + { + kindOfOrder->RemoveAt(i); + } + if ( GetView() ) // Notify Grid about the change + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + } + + return found; +} + + +void gqbGridOrderTable::emptyTableData(gqbQueryObject *object) +{ + // Because items positions on array changes when I delete one, I have to do the remove in this way + while(removeFirstRow(object)); +} + + +void gqbGridOrderTable::removeRowAt(int i) +{ + columns->RemoveAt(i); + colsParents->RemoveAt(i); + if(numberColumns == 2) + { + kindOfOrder->RemoveAt(i); + } + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } +} + + +gqbObject *gqbGridOrderTable::getObjectAt(int pos, int col) +{ + gqbObject *value = NULL; + switch(col) + { + case 0: + value = columns->Item(pos); + break; + case 1: + value = colsParents->Item(pos); + break; + }; + return value; +} + + +void gqbGridOrderTable::changesPositions(int sPos, int dPos) +{ + + int size = columns->GetCount(); + gqbObject *tmpTable = NULL, *tmpColumn = NULL; + char tmpKind = 'N'; + + if( (sPos >= 0 && sPos < size) && (dPos >= 0 && dPos < size) ) + { + tmpTable = colsParents->Item(sPos); + tmpColumn = columns->Item(sPos); + tmpKind = kindOfOrder->Item(sPos); + + colsParents->Item(sPos) = colsParents->Item(dPos); + columns->Item(sPos) = columns->Item(dPos); + kindOfOrder->Item(sPos) = kindOfOrder->Item(dPos); + colsParents->Item(dPos) = tmpTable; + columns->Item(dPos) = tmpColumn; + kindOfOrder->Item(dPos) = tmpKind; + } + + wxGridTableMessage msg( this, + wxGRIDTABLE_REQUEST_VIEW_GET_VALUES, + sPos, + 1 ); + GetView()->ProcessTableMessage( msg ); + +} + + +// GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess. +// Change a single row or a range to one pos up or down (but no more than one position) +void gqbGridOrderTable::changesRangeOnePos(int topPos, int bottomPos, int newTop) +{ + // Eliminate side effect of zero base array on calculations, but careful newTop still it's zero based + topPos++; + bottomPos++; + int sizeRange = bottomPos - (topPos - 1), size = GetNumberRows(); + if(topPos > newTop) // Go Down + { + // Only if the movement don't create an overflow + if( (topPos > 1) && ((newTop + sizeRange) < size) ) + { + for(int i = newTop ; i < (newTop + sizeRange) ; i++) + { + changesPositions(i, i + 1); + } + } + + } // Go Up + else + { + // Only if the movement don't create an overflow + if( (bottomPos < size) && ((newTop + sizeRange) <= size) ) + { + // Go Up Down + for(int i = (newTop + sizeRange - 1) ; i >= newTop ; i--) + { + changesPositions(i - 1, i); + } + } + } +} diff --git a/gqb/gqbGridProjTable.cpp b/gqb/gqbGridProjTable.cpp new file mode 100644 index 0000000..46e332b --- /dev/null +++ b/gqb/gqbGridProjTable.cpp @@ -0,0 +1,327 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridProjTable.cpp - Table implementation for Projection Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" + +gqbGridProjTable::gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias): + wxGridTableBase() +{ + colsPosition = position; + colsParents = parent; + columnsAlias = alias; + // GQB-TODO: replace above pointers array with local variable if possible or research what it's causing bug in destructor??? +} + + +gqbGridProjTable::~gqbGridProjTable() +{ +} + + +int gqbGridProjTable::GetNumberRows() +{ + return (colsPosition->GetCount()); +} + + +int gqbGridProjTable::GetNumberCols() +{ + + return 3; +} + + +bool gqbGridProjTable::IsEmptyCell( int row, int col ) +{ + + int count = colsParents->GetCount(); + if(row + 1 <= count) + return false; + else + return true; +} + + +wxString gqbGridProjTable::GetValue( int row, int col ) +{ + switch(col) + { + case 0: + if(((gqbQueryObject *)colsParents->Item(row))->getAlias().length() > 0) + { + return ((gqbQueryObject *)colsParents->Item(row))->getAlias(); + } + else + { + return ((gqbQueryObject *)colsParents->Item(row))->getName(); + } + break; + case 1: + return ((gqbColumn *)colsPosition->Item(row))->getName(); + break; + case 2: + return columnsAlias->Item(row); + break; + }; + return wxT(""); +} + + +wxString gqbGridProjTable::GetColLabelValue( int col) +{ + switch(col) + { + case 0: + return _("Relation"); + break; + case 1: + return _("Column"); + break; + case 2: + return _("Alias"); + break; + }; + return wxT(""); +} + + +void gqbGridProjTable::SetValue( int row, int col, const wxString &value ) +{ + // Do nothing on values that cannot be edited on this model [Column & Relation Name] + switch(col) + { + case 2: + columnsAlias->Item(row) = value; + break; + }; +} + +void *gqbGridProjTable::GetValueAsCustom( int row, int col, const wxString &typeName ) +{ + switch(col) + { + case 0: + return (void *)&colsParents->Item(row); + break; + case 1: + return (void *)&colsPosition->Item(row); + break; + case 2: + break; + }; + return NULL; +} + + +void gqbGridProjTable::SetValueAsCustom( int row, int col, const wxString &typeName, void *value ) +{ + switch(col) + { + case 0: + colsParents->Add(((gqbQueryObject *)value)); + break; + case 1: + colsPosition->Add(((gqbColumn *)value)); + }; +} + + +void gqbGridProjTable::AppendItem(int col, gqbObject *item) +{ + bool notify = false; + switch(col) + { + case 0: + colsParents->Add(item); + break; + case 1: + colsPosition->Add(item); + notify = true; + break; + case 2: + columnsAlias->Add(wxT("")); + break; + }; + + if (notify && GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + (colsParents->GetCount() - 1), + 1 ); + GetView()->ProcessTableMessage( msg ); + + // Set the cells read-only + GetView()->SetReadOnly(GetView()->GetNumberRows() - 1, 0); + GetView()->SetReadOnly(GetView()->GetNumberRows() - 1, 1); + } + +} + +// Remove a column at the grid +bool gqbGridProjTable::removeRow(gqbObject *itemTable, gqbObject *itemColumn) +{ + bool found = false; + int i, size = colsPosition->GetCount(); + + for(i = 0; i < size; i++) + { + if (colsParents->Item(i) == itemTable && colsPosition->Item(i) == itemColumn) + { + found = true; + break; + } + } + + if(found) + { + colsParents->RemoveAt(i); + colsPosition->RemoveAt(i); + columnsAlias->RemoveAt(i); + + if ( GetView() ) // Notify Grid about the change + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + } + + return found; +} + + +void gqbGridProjTable::removeAllRows(gqbObject *itemTable) +{ + + int size = colsParents->GetCount(); + for(int i = (size - 1); i >= 0; i--) + { + if (colsParents->Item(i) == itemTable) + { + colsParents->RemoveAt(i); + colsPosition->RemoveAt(i); + columnsAlias->RemoveAt(i); + + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + i + 1, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + } + } +} + + +void gqbGridProjTable::changesPositions(int sPos, int dPos) +{ + + int size = colsPosition->GetCount(); + gqbObject *tmpTable = NULL, *tmpColumn = NULL; + wxString tmpAlias = wxT(""); + + if( (sPos >= 0 && sPos < size) && (dPos >= 0 && dPos < size) ) + { + tmpTable = colsParents->Item(sPos); + tmpColumn = colsPosition->Item(sPos); + tmpAlias = columnsAlias->Item(sPos); + + colsParents->Item(sPos) = colsParents->Item(dPos); + colsPosition->Item(sPos) = colsPosition->Item(dPos); + columnsAlias->Item(sPos) = columnsAlias->Item(dPos); + colsParents->Item(dPos) = tmpTable; + colsPosition->Item(dPos) = tmpColumn; + columnsAlias->Item(dPos) = tmpAlias; + } + + wxGridTableMessage msg( this, + wxGRIDTABLE_REQUEST_VIEW_GET_VALUES, + sPos, + 1 ); + GetView()->ProcessTableMessage( msg ); + +} + + +// GQB-TODO: optimize this functions & related buttons events at gqbView because works but are a mess. +// Change a single row or a range to one pos up or down (but no more than one position) +void gqbGridProjTable::changesRangeOnePos(int topPos, int bottomPos, int newTop) +{ + // Eliminate side effect of zero base array on calculations, but careful newTop still it's zero based + topPos++; + bottomPos++; + int sizeRange = bottomPos - (topPos - 1), size = GetNumberRows(); + if(topPos > newTop) // Go Down + { + // Only if the movement don't create an overflow + if( (topPos > 1) && ((newTop + sizeRange) < size) ) + { + for(int i = newTop ; i < (newTop + sizeRange) ; i++) + { + changesPositions(i, i + 1); + } + } + + } // Go Up + else + { + // Only if the movement don't create an overflow + if( (bottomPos < size) && ((newTop + sizeRange) <= size) ) + { + // Go Up Down + for(int i = (newTop + sizeRange - 1) ; i >= newTop ; i--) + { + changesPositions(i - 1, i); + } + } + } +} + + +// Removes all items from gqbGridProjTable +void gqbGridProjTable::emptyTableData() +{ + + int count = colsPosition->GetCount(); + colsPosition->Empty(); + colsParents->Empty(); + columnsAlias->Empty(); + + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + 1, + count); + GetView()->ProcessTableMessage( msg ); + } +} + diff --git a/gqb/gqbGridRestTable.cpp b/gqb/gqbGridRestTable.cpp new file mode 100644 index 0000000..f086a55 --- /dev/null +++ b/gqb/gqbGridRestTable.cpp @@ -0,0 +1,372 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridRestTable.cpp - Table implementation for Restrictions Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbViewPanels.h" + +gqbGridRestTable::gqbGridRestTable(gqbRestrictions *_restrictions): + wxGridTableBase() +{ + restrictions = _restrictions; +} + + +gqbGridRestTable::~gqbGridRestTable() +{ +} + + +int gqbGridRestTable::GetNumberRows() +{ + return (restrictions->restrictionsCount()); +} + + +int gqbGridRestTable::GetNumberCols() +{ + return 4; +} + + +bool gqbGridRestTable::IsEmptyCell( int row, int col ) +{ + + int count = restrictions->restrictionsCount(); + if(row + 1 <= count) + return false; + else + return true; +} + + +wxString gqbGridRestTable::GetValue( int row, int col ) +{ + switch(col) + { + case 0: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getLeft(); + break; + case 1: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getRestriction(); + break; + case 2: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getValue_s(); + break; + case 3: + return ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->getConnector(); + break; + }; + + return wxT(""); +} + + +wxString gqbGridRestTable::GetColLabelValue( int col) +{ + switch(col) + { + case 0: + return _("Restricted Value"); + break; + case 1: + return _("Operator"); + break; + case 2: + return _("Value"); + break; + case 3: + return _("Connector"); + break; + }; + return wxT(""); +} + + +void gqbGridRestTable::SetValue( int row, int col, const wxString &value ) +{ + switch(col) + { + case 0: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setLeft(value); + break; + case 1: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setRestriction(value); + break; + case 2: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setValue_s(value); + break; + case 3: + ((gqbQueryRestriction *)restrictions->getRestrictionAt(row))->setConnector(value); + break; + } +} + + +void gqbGridRestTable::AppendItem(gqbQueryRestriction *item) +{ + bool notify = true; + + restrictions->addRestriction(item); + + if (notify && GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + (restrictions->restrictionsCount() - 1), + 1 ); + GetView()->ProcessTableMessage( msg ); + } + +} + + +bool gqbGridRestTable::DeleteRows(size_t pos = 0, size_t numRows = 1) +{ + if((pos < (size_t)GetNumberRows()) && numRows == 1) + { + gqbQueryRestriction *r = restrictions->getRestrictionAt(pos); + restrictions->removeRestriction(r); + + // Notify Grid about the change + if ( GetView() ) + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + pos, + 1 ); + GetView()->ProcessTableMessage( msg ); + } + + delete r; + return true; + } + else + return false; +} + + +// Removes all items from gqbGridTable +void gqbGridRestTable::emptyTableData() +{ + + int count = restrictions->restrictionsCount(); + restrictions->deleteAllRestrictions(); + + if ( GetView() ) //Notify Grid about the change + { + wxGridTableMessage msg( this, + wxGRIDTABLE_NOTIFY_ROWS_DELETED, + 1, + count); + GetView()->ProcessTableMessage( msg ); + } +} + + +// +// Cell rendering utilities classes +// + +void wxGridCellComboBoxRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, + const wxRect &rectCell, int row, int col, bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + // first calculate button size + // don't draw outside the cell + int nButtonWidth = 17; + if (rectCell.height < 2) return; + wxRect rectButton; + rectButton.x = rectCell.x + rectCell.width - nButtonWidth; + rectButton.y = rectCell.y + 1; + int cell_rows, cell_cols; + attr.GetSize(&cell_rows, &cell_cols); + rectButton.width = nButtonWidth; + if (cell_rows == 1) + rectButton.height = rectCell.height - 2; + else + rectButton.height = nButtonWidth; + + SetTextColoursAndFont(grid, attr, dc, isSelected); + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + + // Leave room for button + wxRect rect = rectCell; + rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth() - 2); + rect.Inflate(-1); + grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign); + + // Don't bother drawing if the cell is too small + if (rectButton.height < 4 || rectButton.width < 4) + return; + + // Draw 3-d button + wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + dc.SetBrush(wxBrush(colourBackGround, wxSOLID)); + dc.SetPen(wxPen(colourBackGround, 1, wxSOLID)); + dc.DrawRectangle(rectButton); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetBottom()); + dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetTop() - 1); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetBottom() - 1); + dc.DrawLine(rectButton.GetRight() - 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetTop()); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetRight() - 2, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetTop() + 1); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetBottom() - 1); + + // Draw little triangle + int nTriWidth = 7; + int nTriHeight = 4; + wxPoint point[3]; + point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth() - nTriWidth) / 2, + rectButton.GetTop() + (rectButton.GetHeight() - nTriHeight) / 2); + point[1] = wxPoint(point[0].x + nTriWidth - 1, point[0].y); + point[2] = wxPoint(point[0].x + 3, point[0].y + nTriHeight - 1); + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID)); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + dc.DrawPolygon(3, point); + if (m_border == wxLAYOUT_TOP) + { + dc.SetPen(wxPen(*wxBLACK, 1, wxDOT)); + dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(), + rectCell.GetLeft(), rectCell.GetTop()); + } +} + + +void wxGridCellButtonRenderer::Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, + const wxRect &rectCell, int row, int col, bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + // First calculate button size + // don't draw outside the cell + int nButtonWidth = 17; + if (rectCell.height < 2) return; + wxRect rectButton; + rectButton.x = rectCell.x + rectCell.width - nButtonWidth; + rectButton.y = rectCell.y + 1; + int cell_rows, cell_cols; + attr.GetSize(&cell_rows, &cell_cols); + rectButton.width = nButtonWidth; + if (cell_rows == 1) + rectButton.height = rectCell.height - 2; + else + rectButton.height = nButtonWidth; + + SetTextColoursAndFont(grid, attr, dc, isSelected); + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + + // Leave room for button + wxRect rect = rectCell; + rect.SetWidth(rectCell.GetWidth() - rectButton.GetWidth() - 2); + rect.Inflate(-1); + grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign); + + + // Don't bother drawing if the cell is too small draw 3-d button + if (rectButton.height < 4 || rectButton.width < 4) + return; + + wxColour colourBackGround = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + dc.SetBrush(wxBrush(colourBackGround, wxSOLID)); + dc.SetPen(wxPen(colourBackGround, 1, wxSOLID)); + dc.DrawRectangle(rectButton); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetBottom()); + dc.DrawLine(rectButton.GetRight(), rectButton.GetBottom(), + rectButton.GetRight(), rectButton.GetTop() - 1); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetBottom() - 1); + dc.DrawLine(rectButton.GetRight() - 1, rectButton.GetBottom() - 1, + rectButton.GetRight() - 1, rectButton.GetTop()); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT), + 1, wxSOLID)); + dc.DrawLine(rectButton.GetRight() - 2, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetTop() + 1); + dc.DrawLine(rectButton.GetLeft() + 1, rectButton.GetTop() + 1, + rectButton.GetLeft() + 1, rectButton.GetBottom() - 1); + + // Draw little plus symbol + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), wxSOLID)); + dc.SetPen(wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNTEXT), 1, wxSOLID)); + int nPlusWidth = 7; + int nPlusHeight = 7; + wxPoint point[4]; + point[0] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth() - nPlusWidth) / 2, rectButton.GetTop() + (rectButton.GetHeight() / 2) - 1); + point[1] = wxPoint(point[0].x + nPlusWidth, point[0].y); + point[2] = wxPoint(rectButton.GetLeft() + (rectButton.GetWidth()) / 2, rectButton.GetTop() + (rectButton.GetHeight() - nPlusHeight) / 2); + point[3] = wxPoint(point[2].x, point[2].y + nPlusHeight); + dc.DrawLine(point[0], point[1]); + dc.DrawLine(point[2], point[3]); + + if (m_border == wxLAYOUT_TOP) + { + dc.SetPen(wxPen(*wxBLACK, 1, wxDOT)); + dc.DrawLine(rectCell.GetRight(), rectCell.GetTop(), + rectCell.GetLeft(), rectCell.GetTop()); + } +} + + +// +// Cell editing utilities classes +// +dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(const wxArrayString &choices, bool allowOthers) + : wxGridCellChoiceEditor(choices, allowOthers) +{ +} + + +dxGridCellSizedChoiceEditor::dxGridCellSizedChoiceEditor(size_t count, const wxString choices[], bool allowOthers) + : wxGridCellChoiceEditor(count, choices, allowOthers) +{ +} + + +wxGridCellEditor *dxGridCellSizedChoiceEditor::Clone() const +{ + dxGridCellSizedChoiceEditor *editor = new + dxGridCellSizedChoiceEditor(); + return editor; +} + + +void dxGridCellSizedChoiceEditor::Show(bool show, wxGridCellAttr *attr) +{ + wxGridCellEditor::Show(show, attr); +} diff --git a/gqb/gqbModel.cpp b/gqb/gqbModel.cpp new file mode 100644 index 0000000..fa4d13d --- /dev/null +++ b/gqb/gqbModel.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbModel.cpp - Model of MVC Pattern for GQB +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbQueryObjs.h" + +gqbModel::gqbModel(): + wxObject() +{ +// here store all queryObjects +// GQB-TODO: allow different names for each model + queryCollection = new gqbQueryObjs(); + restrictions = new gqbRestrictions(); + columnsAlias = new wxArrayString(); +} + + +// GQB-TODO: check this destructor is not complete +gqbModel::~gqbModel() +{ + if(queryCollection) + delete queryCollection; + + // Don't owns objects only remove then in both + colsPosition.Empty(); + colsParents.Empty(); + if(columnsAlias) + delete columnsAlias; + + //GQB-TODO: delete restrictions + if(restrictions) + delete restrictions; +} + + +gqbQueryObject *gqbModel::addTable(gqbTable *table, wxPoint p) +{ + // Get a table but introduce a QueryObject + gqbQueryObject *tmp = new gqbQueryObject(table); + tmp->position = p; + + // Now use insert the new object in the collection of the model + queryCollection->addTable(tmp); + + // Columns of added table should be possible to use on Order By Clause + gqbIteratorBase *iterator = tmp->parent->createColumnsIterator(); + while(iterator->HasNext()) + { + gqbColumn *col = (gqbColumn *)iterator->Next(); + AvailableColumns.Add(col); + ColumnAvailParent.Add(tmp); + } + delete iterator; + + return tmp; +} + + +gqbIteratorBase *gqbModel::createQueryIterator() +{ + return queryCollection->createQueryIterator(); +} + +gqbIteratorBase *gqbModel::createDownQueryIterator() +{ + return queryCollection->createDownQueryIterator(); +} + +void gqbModel::deleteTable(gqbQueryObject *modelTable) +{ + if(modelTable) + { + queryCollection->removeTable(modelTable); + delete modelTable; + modelTable = NULL; + } +} + + +int gqbModel::tablesCount() +{ + return queryCollection->tablesCount(); +} + + +void gqbModel::emptyAll() +{ + colsPosition.Empty(); + colsParents.Empty(); + queryCollection->removeAllQueryObjs(); + +} + + +gqbQueryRestriction *gqbModel::addRestriction() +{ + gqbQueryRestriction *r = new gqbQueryRestriction(); + restrictions->addRestriction(r); + return r; +} diff --git a/gqb/gqbObject.cpp b/gqb/gqbObject.cpp new file mode 100644 index 0000000..e5180dc --- /dev/null +++ b/gqb/gqbObject.cpp @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObject.cpp - Main basic object used by GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbObject.h" + +gqbObject::gqbObject(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid) +{ + Name = name; + Owner = owner; + conn = connection; + Oid = oid; +} + + +gqbObject::~gqbObject() +{ +} diff --git a/gqb/gqbObjectCollection.cpp b/gqb/gqbObjectCollection.cpp new file mode 100644 index 0000000..492cefb --- /dev/null +++ b/gqb/gqbObjectCollection.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObjectCollection.cpp - A Collection of simple GQB objects +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbObjectCollection.h" +#include "gqb/gqbCollection.h" +#include "gqb/gqbArrayCollection.h" + +gqbObjectCollection::gqbObjectCollection(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid) + : gqbObject(name, owner, connection, oid) +{ + // Create the concrete implementation of the Collection, right now only one implementation not need parameter + implementation = new gqbArrayCollection(); + + // Create the collection using the concrete implementation + // use the array implementation of the collection + objectsCollection = new gqbCollection(implementation); +} + + +gqbObjectCollection::~gqbObjectCollection() +{ + if(objectsCollection) // Implementation is deleted when delete the collection & shouldn't be deleted again + delete objectsCollection; +} + + +void gqbObjectCollection::addObject(gqbObject *object) +{ + objectsCollection->addItem(object); +} + + +void gqbObjectCollection::removeObject(gqbObject *object) +{ + objectsCollection->removeItem(object); +} + + +gqbIteratorBase *gqbObjectCollection::createIterator() +{ + return objectsCollection->createIterator(); +} + +gqbIteratorBase *gqbObjectCollection::createDownIterator() +{ + return objectsCollection->createDownIterator(); +} + +int gqbObjectCollection::countObjects() +{ + return objectsCollection->count(); +} + + +gqbObject *gqbObjectCollection::getObjectAtIndex(int index) +{ + return objectsCollection->getItemAt(index); +} + + +bool gqbObjectCollection::existsObject(gqbObject *object) +{ + return objectsCollection->existsObject(object); +} + + +// Remove all objects from collection without deleting each one. +void gqbObjectCollection::removeAll() +{ + objectsCollection->removeAll(); +} + + +int gqbObjectCollection::indexObject(gqbObject *object) +{ + return objectsCollection->getIndex(object); +} + + +void gqbObjectCollection::insertObjectAt(gqbObject *object, int index) +{ + objectsCollection->insertAtIndex(object, index); +} + + +int gqbObjectCollection::getCount() +{ + return objectsCollection->count(); +} + + +// Remove & delete all objects +void gqbObjectCollection::deleteAll() +{ + objectsCollection->deleteAll(); +} diff --git a/gqb/gqbQueryObjs.cpp b/gqb/gqbQueryObjs.cpp new file mode 100644 index 0000000..34076a5 --- /dev/null +++ b/gqb/gqbQueryObjs.cpp @@ -0,0 +1,513 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbQueryObjs.cpp - All objects used by a model of a query in the MVC Pattern model. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "gqb/gqbTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbObjectCollection.h" +#include "gqb/gqbViewPanels.h" + +// +// Collections of Tables inside a Query, data structured used for query storage & later generation of SQL sentence +// + +gqbQueryObjs::gqbQueryObjs() + : gqbObjectCollection(wxT(""), NULL, NULL) +{ + setType(GQB_QUERY); +} + + +void gqbQueryObjs::addTable(gqbQueryObject *mtable) +{ + this->addObject(mtable); +} + + +void gqbQueryObjs::removeTable(gqbQueryObject *mtable) +{ + this->removeObject(mtable); +} + + +gqbIteratorBase *gqbQueryObjs::createQueryIterator() +{ + return this->createIterator(); +} + +gqbIteratorBase *gqbQueryObjs::createDownQueryIterator() +{ + return this->createDownIterator(); +} + + +int gqbQueryObjs::tablesCount() +{ + return this->countObjects(); +} + + +void gqbQueryObjs::removeAllQueryObjs() +{ + this->removeAll(); +} + + +// +// An Object inside a query (A table object in the query), not equal to gqbTable +// Reason: Sometimes a table can be used twice or more times in a query with different columns selected +// Because this we can not use directly the base table object + +gqbQueryObject::gqbQueryObject(gqbTable *table) + : gqbObjectCollection(table->getName(), table, table->getConnection()) +{ + selected = false; + parent = table; + + //GQB-TODO: Calculate a good initial position + position.x = 20; + position.y = 20; + haveJoins = false; + haveRegisteredJoins = false; + registeredCollection = NULL; + joinsCollection = NULL; + setType(GQB_QUERYOBJ); +} + + +// Destructor must empty collection to don't allow deleting of column items from tree +// because this collection doesn't owns it, and then shouldn't destroy it. +gqbQueryObject::~gqbQueryObject() +{ + this->removeAll(); + + // Remove item registered at this Query Object + gqbQueryJoin *tmp; + if(registeredCollection) + { + gqbIteratorBase *r = createRegJoinsIterator(); + while(r->HasNext()) + { + tmp = (gqbQueryJoin *)r->Next(); + this->unregisterJoin(tmp, true); // remove and unregister every join in every query object + // which have registered at this query object + + // On each iteration the structure of iterator change because + // modified his own collection & should be reset + r->ResetIterator(); + } + delete r; + } + + if(joinsCollection) + { + gqbIteratorBase *j = createJoinsIterator(); + while(j->HasNext()) + { + tmp = (gqbQueryJoin *)j->Next(); + this->removeJoin(tmp, true); // removes & unregister Join which have like origin this + // query object + // On each iteration the structure of iterator change because + // modified his own collection & should be reset + j->ResetIterator(); + } + delete j; + + } + + // removeJoin & unregisterJoin delete the collections where there aren't any items inside. +} + + +void gqbQueryObject::setSelected(bool value) +{ + this->selected = value; +} + + +bool gqbQueryObject::getSelected() +{ + return this->selected; +} + + +void gqbQueryObject::setWidth(int value) +{ + width = value; +} + + +int gqbQueryObject::getWidth() +{ + return width; +} + + +void gqbQueryObject::setHeight(int value) +{ + height = value; +} + + +int gqbQueryObject::getHeight() +{ + return height; +} + + +void gqbQueryObject::addColumn(gqbColumn *column) +{ + this->addObject(column); +} + + +void gqbQueryObject::removeColumn(gqbColumn *column) +{ + this->removeObject(column); +} + + +bool gqbQueryObject::existsColumn(gqbColumn *column) +{ + return this->existsObject(column); +} + + +gqbIteratorBase *gqbQueryObject::createQueryTableIterator() +{ + return this->createIterator(); +} + + +gqbIteratorBase *gqbQueryObject::createJoinsIterator() +{ + return joinsCollection->createIterator(); +} + + +gqbIteratorBase *gqbQueryObject::createRegJoinsIterator() +{ + return registeredCollection->createIterator(); +} + + +// Create a Join from this table [owner] column to other table [observable] column +gqbQueryJoin *gqbQueryObject::addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind) +{ + if(!haveJoins) + { + implementationj = new gqbArrayCollection(); + joinsCollection = new gqbCollection(implementationj); + haveJoins = true; + } + + gqbQueryJoin *join = new gqbQueryJoin(owner, observable, source, destination, kind); + joinsCollection->addItem(join); + observable->registerJoin(join); + return join; +} + + +// Remove the join from this query object [source table] +void gqbQueryObject::removeJoin(gqbQueryJoin *join, bool unRegister = false) +{ + // Notify to observable that the join this object owns will be removed & then remove the join + if(unRegister) + join->getDestQTable()->unregisterJoin(join, false); + joinsCollection->removeItem(join); + if(join) + delete join; // Join can be only delete Here by his owner + + if(joinsCollection->count() <= 0) + { + delete joinsCollection; // implementation it's delete too inside collection. + haveJoins = false; + joinsCollection = NULL; + } +} + + +// Register a Join created from other table [source] to this table [destination] +void gqbQueryObject::registerJoin(gqbQueryJoin *join) +{ + if(!haveRegisteredJoins) + { + implementationr = new gqbArrayCollection(); + registeredCollection = new gqbCollection(implementationr); + haveRegisteredJoins = true; + } + registeredCollection->addItem(join); +} + + +// Unregister a Join create from other table [source] to this table [destination] delete the join if need it.. +void gqbQueryObject::unregisterJoin(gqbQueryJoin *join, bool removeIt = false) +{ + // Notify to source/owner object of join about join removing & then remove + registeredCollection->removeItem(join); + if(removeIt) + join->getSourceQTable()->removeJoin(join, false); + if(registeredCollection->count() <= 0) + { + delete registeredCollection; //implementation it's delete too inside collection. + haveRegisteredJoins = false; + registeredCollection = NULL; + } +} + + +int gqbQueryObject::getColumnIndex(gqbColumn *column) +{ + return parent->indexColumn(column); +} + + +bool gqbQueryObject::getHaveJoins() +{ + return haveJoins; +} + + +bool gqbQueryObject::getHaveRegJoins() +{ + return haveRegisteredJoins; +} + +// GQB-TODO if last join it's delete I MUST delete implementation & collection & put haveJoins in false; +// Same for registered joins + +// +// A Join inside a query Object like Table or view [Stored at source, registered at destination] +// I need to store the owner, destination because columns it's share between multiple joins +gqbQueryJoin::gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind) + : gqbObject(wxT(""), _owner, NULL) +{ + kindofJoin = joinKind; + sCol = sourceCol; + dCol = destCol; + owner = _owner; + selected = false; + destination = _destination; + setType(GQB_JOIN); +} + + +void gqbQueryJoin::setKindofJoin(type_Join kind) +{ + kindofJoin = kind; +} + + +type_Join gqbQueryJoin::getKindofJoin() +{ + return kindofJoin; +} + + +// Return the object where the join is stored +gqbQueryObject *gqbQueryJoin::getSourceQTable() +{ + return owner; +} + + +// Return the object where the join point to. +gqbQueryObject *gqbQueryJoin::getDestQTable() +{ + return destination; +} + + +// Return the gqbObject of Destination Column +gqbColumn *gqbQueryJoin::getDCol() +{ + return dCol; +} + + +// Return the gqbObject of Source Column +gqbColumn *gqbQueryJoin::getSCol() +{ + return sCol; +} + + +wxString gqbQueryJoin::getSourceTable() +{ + if (!owner) + return wxEmptyString; + + gqbTable *s = (gqbTable *)sCol->getOwner(); + return s->getName(); +} + + +wxString gqbQueryJoin::getDestTable() +{ + if (!destination) + return wxEmptyString; + + gqbTable *d = (gqbTable *)dCol->getOwner(); + return d->getName(); +} + + +wxString gqbQueryJoin::getSourceCol() +{ + if (!sCol) + return wxEmptyString; + + return sCol->getName(); +} + + +wxString gqbQueryJoin::getDestCol() +{ + if (!dCol) + return wxEmptyString; + + return dCol->getName(); +} + + +void gqbQueryJoin::setSourceAnchor(wxPoint pt) +{ + sAnchor = pt; +} + + +void gqbQueryJoin::setDestAnchor(wxPoint pt) +{ + dAnchor = pt; +} + + +wxPoint &gqbQueryJoin::getSourceAnchor() +{ + return sAnchor; +} + + +wxPoint &gqbQueryJoin::getDestAnchor() +{ + return dAnchor; +} + + +void gqbQueryJoin::setSelected(bool value) +{ + this->selected = value; +} + + +bool gqbQueryJoin::getSelected() +{ + return this->selected; +} + + +void gqbQueryJoin::setAnchorsUsed(wxPoint pt) +{ + anchorsUsed = pt; +} + + +wxPoint &gqbQueryJoin::getAnchorsUsed() +{ + return anchorsUsed; +} + + +// +// A query restriction +// + +enum +{ + QRButton = 9000, + QRValue, + QRConnector, + QRtype +}; + +gqbQueryRestriction::gqbQueryRestriction() + : gqbObject(wxT(""), NULL, NULL) +{ + leftPart = wxT(""); + value_s = wxT(""); + connector = wxT("AND"); + restriction = wxT("="); + setType(GQB_RESTRICTION); +} + + +gqbRestrictions::gqbRestrictions() + : gqbObjectCollection(wxT(""), NULL, NULL) +{ + setType(GQB_RESTRICTION); +} + + +gqbRestrictions::~gqbRestrictions() +{ + this->removeAll(); +} + + +void gqbRestrictions::addRestriction(gqbQueryRestriction *r) +{ + this->addObject(r); +} + + +void gqbRestrictions::addRestrictionAt(gqbQueryRestriction *r, int index) +{ + this->insertObjectAt(r, index); +} + + +// Remove but don't delete restriction +void gqbRestrictions::removeRestriction(gqbQueryRestriction *r) +{ + this->removeObject(r); +} + + +void gqbRestrictions::deleteAllRestrictions() +{ + this->deleteAll(); +} + + +gqbIteratorBase *gqbRestrictions::createRestrictionsIterator() +{ + return this->createIterator(); +} + + +int gqbRestrictions::restrictionsCount() +{ + return this->getCount(); +} + + +gqbQueryRestriction *gqbRestrictions::getRestrictionAt(int index) +{ + return (gqbQueryRestriction *)this->getObjectAtIndex(index); +} diff --git a/gqb/gqbSchema.cpp b/gqb/gqbSchema.cpp new file mode 100644 index 0000000..aa73397 --- /dev/null +++ b/gqb/gqbSchema.cpp @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbSchema.cpp - Schema object for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbSchema.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbBrowser.h" + +gqbSchema::gqbSchema(gqbObject *parent, wxString name, pgConn *connection, OID oid) + : gqbObject(name, parent, connection, oid) +{ + setType(GQB_SCHEMA); +} + + +// GQB-TODO: don't declare OID inside gqbBrowsear instead use the pgadmin one +void gqbSchema::createObjects(gqbBrowser *tablesBrowser, OID oidVal, wxTreeItemId parentNode, int tableImage, int viewImage, int xTableImage) +{ + createTables(tablesBrowser, parentNode, oidVal, tableImage, viewImage, xTableImage); +} + +void gqbSchema::createTables(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int tableImage, int viewImage, int xTableImage) +{ + wxString query; + + // Get the child objects. + query = wxT("SELECT oid, relname, relkind\n") + wxT(" FROM pg_class\n") + wxT(" WHERE relkind IN ('r','v','x','m') AND relnamespace = ") + NumToStr(oidVal) + wxT(";"); + + pgSet *tables = conn->ExecuteSet(query); + wxTreeItemId parent; + + if (tables) + { + while (!tables->Eof()) + { + gqbTable *table = 0; + wxString tmpname = tables->GetVal(wxT("relname")); + wxString relkind = tables->GetVal(wxT("relkind")); + + if (relkind == wxT("r")) // Table + { + table = new gqbTable(this, tmpname, conn, GQB_TABLE, tables->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")) , tableImage, tableImage, table); + } + else if (relkind == wxT("v") || relkind == wxT("m")) + { + table = new gqbTable(this, tmpname, conn, GQB_VIEW, tables->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")) , viewImage, viewImage, table); + } + else if (relkind == wxT("x")) // Greenplum external table + { + table = new gqbTable(this, tmpname, conn, GQB_TABLE, tables->GetOid(wxT("oid"))); + parent = tablesBrowser->AppendItem(parentNode, tables->GetVal(wxT("relname")), xTableImage, xTableImage, table); + } + + // Create columns inside this table. + if (table) + table->createObjects(tablesBrowser, conn, tables->GetOid(wxT("oid")), parent); + + tables->MoveNext(); + } + + delete tables; + } + + tablesBrowser->SortChildren(parentNode); +} diff --git a/gqb/gqbTable.cpp b/gqb/gqbTable.cpp new file mode 100644 index 0000000..8b8f957 --- /dev/null +++ b/gqb/gqbTable.cpp @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbTable.cpp - Table object for GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbArrayCollection.h" + +gqbTable::gqbTable(gqbObject *parent, wxString name, pgConn *connection, type_gqbObject type, OID oid) + : gqbObjectCollection(name, parent, connection, oid) +{ + setType(type); +} + + +gqbIteratorBase *gqbTable::createColumnsIterator() +{ + return createIterator(); +} + + +void gqbTable::addColumn(gqbColumn *column) +{ + this->addObject(column); +} + + +void gqbTable::createObjects(gqbBrowser *_tablesBrowser, pgConn *_conn, OID oidVal, wxTreeItemId parentNode) +{ + createColumns(_conn, _tablesBrowser, parentNode, oidVal); +} + +void gqbTable::createColumns(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal) +{ + + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT("\n AND attnum > 0"); + + wxString sql = + wxT("SELECT attname FROM pg_attribute att\n") + wxT(" WHERE attrelid = ") + + NumToStr(oidVal) + + systemRestriction + wxT("\n") + wxT(" AND attisdropped IS FALSE\n") + wxT(" ORDER BY attnum"); + + pgSet *columns = conn->ExecuteSet(sql); + if (columns) + { + while (!columns->Eof()) + { + if (tablesBrowser) + { + //Disable, Column SHOULDN'T be added to tree only use for debug purposes tablesBrowser->AppendItem(parentNode, columns->GetVal(wxT("attname")) , -1, -1); + wxString tmpname = wxString(columns->GetVal(wxT("attname"))); + gqbColumn *column = new gqbColumn(this, tmpname, conn); + this->addColumn(column); + columns->MoveNext(); + } + else + break; + } + + delete columns; + } +} + + +//work as a synonym for function +int gqbTable::countCols() +{ + return this->countObjects(); +} + + +//work as a synonym for function & return correct type +gqbColumn *gqbTable::getColumnAtIndex(int index) +{ + return (gqbColumn *)this->getObjectAtIndex(index); +} + + +int gqbTable::indexColumn(gqbColumn *col) +{ + return this->indexObject(col); +} diff --git a/gqb/gqbView.cpp b/gqb/gqbView.cpp new file mode 100644 index 0000000..ac06089 --- /dev/null +++ b/gqb/gqbView.cpp @@ -0,0 +1,844 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbView.cpp - View implementation for MVC Pattern of GQB +// +////////////////////////////////////////////////////////////////////////// + + +// 1. READ MODEL STATE FROM gqbModel TO CREATE THE GRAPHIC REPRESENTATION OF THE QUERY +// 2. USE THE CONTROLLER TO CHANGE THE MODEL WITH THE USER INPUT + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbGraphSimple.h" +#include "gqb/gqbViewPanels.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbObjectCollection.h" + +// Image +#include "images/gqbJoinCursor.pngc" + +BEGIN_EVENT_TABLE(gqbView, wxScrolledWindow) + EVT_SIZE(gqbView::OnSize) + EVT_PAINT(gqbView::onPaint) + EVT_MOTION(gqbView::onMotion) + EVT_LEFT_DOWN(gqbView::onMotion) + EVT_RIGHT_DOWN(gqbView::onRightClick) + EVT_LEFT_UP(gqbView::onMotion) + EVT_LEFT_DCLICK(gqbView::onDoubleClick) + EVT_ERASE_BACKGROUND(gqbView::onEraseBackGround) //This erase flicker create by wxStaticText when erasing background but this is not needed + EVT_KEY_DOWN(gqbView::OnKeyDown) + EVT_MENU(GQB_RMJ_DELETE, gqbView::OnMenuJoinDelete) + EVT_MENU(GQB_RMT_DELETE, gqbView::OnMenuTableDelete) + EVT_MENU(GQB_RMT_SETALIAS, gqbView::OnMenuTableSetAlias) + EVT_MENU(GQB_REFRESH, gqbView::OnRefresh) +END_EVENT_TABLE() + +gqbView::gqbView(wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model) + : wxScrolledWindow(gqbParent, wxID_ANY, wxPoint(201, 0), size, + wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED) +{ + this->controller = controller; + this->model = model; + pressed = -1; + selected = -1; + changeTOpressed = false; + canvasSize = size; + collectionSelected = NULL; + joinSelected = NULL; + joinSource = NULL; + joinDest = NULL; + joinSCol = NULL; + joinDCol = NULL; + refreshRate = 3; + iterator = NULL; + mode = pt_normal; + joinCursorImage = *gqbJoinCursor_png_img; + joinCursor = wxCursor(joinCursorImage); + m_rightJoins = NULL; + m_rightTables = NULL; + m_gqbPopup = NULL; + jTempSelected = NULL; + cTempSelected = NULL; + + // Assing kind of join Options + joinTypeChoices.Add(wxString(wxT(" = "))); + joinTypeChoices.Add(wxString(wxT(" > "))); + joinTypeChoices.Add(wxString(wxT(" < "))); + joinTypeChoices.Add(wxString(wxT(" >= "))); + joinTypeChoices.Add(wxString(wxT(" <= "))); + + // Assign default graphic behavior [skin of forms inside model] + this->graphBehavior = new gqbGraphSimple(); + + // Create Projection Panel + // GQB-TODO: move model to grid panel constructor + this->gridTable = new gqbGridProjTable(this->model->getOrderedColumns(), this->model->getColumnsParents(), this->model->getColumnsAlias()); + this->projectionPanel = new gqbGridPanel(controller->getTabs(), -1, gridTable); + + // Create Restrictions Panel + this->restrictionsGridTable = new gqbGridRestTable(model->getRestrictions()); + this->criteriaPanel = new gqbCriteriaPanel(controller->getTabs(), model, restrictionsGridTable); + + // Create Joins Panel + this->joinsGridTable = new gqbGridJoinTable(this->controller); + this->joinsPanel = new gqbJoinsPanel(controller->getTabs(), model, joinsGridTable, controller); + + // Create Order by Panel + this->orderByLGridTable = new gqbGridOrderTable(1, model->getOrdByAvailColumns(), model->getOrdByAvailParents(), NULL); + this->orderByRGridTable = new gqbGridOrderTable(2, model->getOrdByColumns(), model->getOrdByParents(), model->getOrdByKind()); + this->orderPanel = new gqbOrderPanel(controller->getTabs(), orderByLGridTable, orderByRGridTable); + +#if !wxCHECK_VERSION(2, 9, 0) + // does nothing in 2.9+ + SetVirtualSizeHints(size); +#endif + +} + + +gqbView::~gqbView() +{ + if(graphBehavior) + delete graphBehavior; + if(iterator) + delete iterator; + + if(m_rightTables) + delete m_rightTables; + + if(m_rightJoins) + delete m_rightJoins; + + if (m_gqbPopup) + delete m_gqbPopup; + + if(orderByRGridTable) + delete orderByRGridTable; + + if(orderByLGridTable) + delete orderByLGridTable; +} + + +// Overwrite and disable onEraseBackground Event to avoid Flicker +void gqbView::onEraseBackGround(wxEraseEvent &event) +{ +} + + +// Detect when should be drawn the canvas with the model information +void gqbView::onPaint(wxPaintEvent &event) +{ + wxPaintDC dcc(this); // Prepare Context for Buffered Draw + wxBufferedDC dc(&dcc, canvasSize); + drawAll(dc, true); // Call Function to draw all +} + + +// GQB-TODO: remove all possible modification to model from here to controller. +void gqbView::onRightClick(wxMouseEvent &event) +{ + // GQB-TODO: Validate Alias + gqbObject *anySelected = NULL; + wxPoint pdc = event.GetPosition(); + pdc.x = event.GetPosition().x; + pdc.y = event.GetPosition().y; + this->CalcUnscrolledPosition(pdc.x, pdc.y, &pdc.x, &pdc.y); + anySelected = controller->getModelSelected(pdc, cTempSelected, jTempSelected, false); + if(anySelected) + { + if(anySelected->getType() == GQB_QUERYOBJ) + { + if(!m_rightTables) + { + m_rightTables = new wxMenu; + m_rightTables->Append(GQB_RMT_SETALIAS, _("&Set Alias for table")); + m_rightTables->Append(GQB_RMT_DELETE, _("&Delete Table")); + m_rightTables->AppendSeparator(); + m_rightTables->Append(GQB_REFRESH, _("&Refresh")); + + } + cTempSelected = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + jTempSelected = NULL; + PopupMenu(m_rightTables, event.GetPosition()); + } + + if(anySelected->getType() == GQB_JOIN) + { + if(!m_rightJoins) + { + m_rightJoins = new wxMenu; + m_rightJoins->Append(GQB_RMJ_DELETE, _("&Delete Join")); + m_rightJoins->AppendSeparator(); + m_rightJoins->Append(GQB_REFRESH, _("&Refresh")); + } + cTempSelected = NULL; + jTempSelected = (gqbQueryJoin *) anySelected;; + PopupMenu(m_rightJoins, event.GetPosition()); + } + } + else + { + if(!m_gqbPopup) + { + m_gqbPopup = new wxMenu; + m_gqbPopup->Append(GQB_REFRESH, _("&Refresh")); + } + PopupMenu(m_gqbPopup, event.GetPosition()); + } +} + + +void gqbView::OnMenuJoinDelete(wxCommandEvent &WXUNUSED(event)) +{ + if(jTempSelected) + { + this->joinsGridTable->removeJoin(jTempSelected); + controller->removeJoin(jTempSelected); + jTempSelected = NULL; + this->Refresh(); + } +} + + +void gqbView::OnMenuTableDelete(wxCommandEvent &WXUNUSED(event)) +{ + if(cTempSelected) + { + joinsGridTable->removeJoins(cTempSelected); + controller->removeTableFromModel(cTempSelected, gridTable, orderByLGridTable, orderByRGridTable); + cTempSelected = NULL; + this->Refresh(); + } +} + + +void gqbView::OnMenuTableSetAlias(wxCommandEvent &event) +{ + if(cTempSelected) + { + // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign + // as his parent the main container of the view, and void the bug + wxTextEntryDialog dialog(controller->getDialogParent(), + wxString::Format(_("Enter an alias for table %s"), cTempSelected->getName().c_str()), + _("Please enter an alias for the table."), + wxT(""), + wxOK | wxCANCEL | wxCENTRE); + dialog.SetValue(cTempSelected->getAlias()); + if (dialog.ShowModal() == wxID_OK) + { + cTempSelected->setAlias(dialog.GetValue()); + joinsPanel->Refresh(); + } + cTempSelected = NULL; + this->Refresh(); + } +} + + +void gqbView::onDoubleClick(wxMouseEvent &event) +{ + // GQB-TODO: Validate Alias + gqbObject *anySelected = NULL; + wxPoint pdc = event.GetPosition(); + pdc.x = event.GetPosition().x; + pdc.y = event.GetPosition().y; + this->CalcUnscrolledPosition(pdc.x, pdc.y, &pdc.x, &pdc.y); + + anySelected = controller->getModelSelected(pdc, cTempSelected, jTempSelected, false); + if(anySelected) + { + if(anySelected->getType() == GQB_QUERYOBJ) + { + gqbQueryObject *t = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + + // Because a bug that scrolled automatically the panel of the view if this dialog is called, then assign + // as his parent the main container of the view, and void the bug + wxTextEntryDialog dialog(controller->getDialogParent(), + wxString::Format(_("Enter an alias for table %s"), t->getName().c_str()), + _("Please enter an alias for the table."), + wxT(""), + wxOK | wxCANCEL | wxCENTRE); + dialog.SetValue(t->getAlias()); + if (dialog.ShowModal() == wxID_OK) + { + t->setAlias(dialog.GetValue()); + joinsPanel->Refresh(); + + // hack to avoid misplaced joins anchors after insert an alias that trigger a table graph resize (bigger) + this->Refresh(); + this->Update(); //force refresh + graphBehavior->UpdatePosObject(t, t->position.x, t->position.y, 0); + } + } + else if(anySelected->getType() == GQB_JOIN) + { + gqbQueryJoin *j = (gqbQueryJoin *) anySelected; + + controller->getTabs()->ChangeSelection(ti_joinsPanel); + gqbJoinsPanel *jPanel = wxDynamicCast( joinsPanel, gqbJoinsPanel ); + jPanel->selectJoin(j); + } + } + this->Refresh(); +} + + +// Manages user input [Mouse click, drag & drop] over the Canvas +void gqbView::onMotion(wxMouseEvent &event) +{ + static int refresh = 1; // refresh counter, everytime this values reaches + // "refreshRate" value then Refresh while dragging + // Discover area where event ocurrs + pos.x = event.GetPosition().x; + pos.y = event.GetPosition().y; + this->CalcUnscrolledPosition(pos.x, pos.y, &pos.x, &pos.y); + gqbObject *anySelected = NULL; + + // Button Down Event is triggered + if(event.ButtonDown() && !changeTOpressed) + { + this->SetFocus(); + + // Which kind of button down was? join creation [click on any column at the + // right of checkbox and drag & drop] or table moving [click on title and drag & drop] + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + if(anySelected) + { + // Anything before just forget about it + changeTOpressed = false; + joinSource = NULL; + joinSCol = NULL; + joinDCol = NULL; + joinDest = NULL; + jpos.x = 0; + jpos.y = 0; + + if(anySelected->getType() == GQB_QUERYOBJ) + { + gqbQueryObject *t = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + + // If click on the title area AND don't click on the columns selection checkbox + if( (pos.y - t->position.y <= graphBehavior->getTitleRowHeight())) + controller->setPointerMode(pt_normal); + else if(pos.x - t->position.x <= 17) + controller->setPointerMode(pt_normal); + else + controller->setPointerMode(pt_join); + } + } + else + { + anySelected = NULL; + mode = pt_normal; + } + + if(mode == pt_normal) // pointer is used to move tables & select/unselect columns + { + // getSelected Item [Mark it as selected if possible] + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, true); + changeTOpressed = true; + + // Do conversion of type object if any found + if(anySelected) + { + if(anySelected->getType() == GQB_QUERYOBJ) + { + collectionSelected = (gqbQueryObject *) (gqbObjectCollection *) anySelected; + joinSelected = NULL; + } + else if(anySelected->getType() == GQB_JOIN) + { + joinSelected = (gqbQueryJoin *) anySelected; + collectionSelected = NULL; + } + } + else + { + collectionSelected = NULL; + joinSelected = NULL; + } + + if(!collectionSelected) + { + // none selected temp unselect all items + controller->unsetModelSelected(true); + } + else + { + gqbColumn *col = graphBehavior->getColumnAtPosition(&pos, collectionSelected); + if(col) + { + // Add or remove column from model & observers (ex: Grid) (projection part of SQL sentence) + controller->processColumnInModel(collectionSelected, col, gridTable); + } + } + + if(!joinSelected) + { + controller->unsetModelSelected(false); + } + + } + // Pointer is used to add joins + else if(mode == pt_join) + { + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + + // Even if I get an object check that it isn't a join + if( (anySelected) && anySelected->getType() == GQB_QUERYOBJ) + joinSource = (gqbQueryObject *)(gqbObjectCollection *) anySelected; + else + joinSource = NULL; + + if(!joinSource) + { + // creation of join starts + joinSCol = NULL; + joinDCol = NULL; + jpos.x = 0; + jpos.y = 0; + } + else + { + joinSCol = graphBehavior->getColumnAtPosition(&pos, joinSource, joinSource->getWidth()); + jpos = pos; + + // GQB-TODO then draw line between column & pointer + } + } + + this->Refresh(); + } + + // Button Up Event is triggered + if(event.ButtonUp()) + { + // Pointer is used to move tables & select/unselect columns + if(mode == pt_normal) + { + changeTOpressed = false; + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + if (anySelected && anySelected->getType() == GQB_JOIN) + { + gqbJoinsPanel *jPanel = wxDynamicCast( joinsPanel, gqbJoinsPanel ); + jPanel->selectJoin((gqbQueryJoin *)anySelected); + } + } + // Pointer is used to add joins + else if(mode == pt_join) + { + anySelected = controller->getModelSelected(pos, collectionSelected, joinSelected, false); + + // Even if I get an object check that it isn't a join + if( (anySelected) && anySelected->getType() == GQB_QUERYOBJ) + { + joinDest = (gqbQueryObject *)(gqbObjectCollection *) anySelected; + // Validate not self joins [in this version tables can be duplicated to create same effect] + if(joinDest == joinSource) + { + joinDest = NULL; + } + } + else + joinDest = NULL; + + // Creation of join starts + if(!joinDest) + { + joinSource = NULL; + joinSCol = NULL; + joinDCol = NULL; + joinDest = NULL; + jpos.x = 0; + jpos.y = 0; + } + else + { + joinDCol = graphBehavior->getColumnAtPosition(&pos, joinDest, joinDest->getWidth()); + if(joinDCol) + { + // GQB-TODO: Allow other type of joins + gqbQueryJoin *qj = controller->addJoin(joinSource, joinSCol, joinDest, joinDCol, _equally); + graphBehavior->calcAnchorPoint(qj); + this->joinsGridTable->AppendJoin(qj); + } + // Let the temporary join line to be draw again [Don't destroy anything because all object where own by other objects this are just pointers] + joinSource = NULL; + joinSCol = NULL; + joinDest = NULL; + joinDCol = NULL; + jpos.x = 0; + jpos.y = 0; + } + } + + controller->setPointerMode(pt_normal); //when button is up, pointer mode should be only normal + this->Refresh(); + } + + // Mouse is Dragged while mouse button is down + if (event.Dragging() && pressed) + { + if(mode == pt_normal) + { + if(collectionSelected) + { + // GQB-TODO: same as gqbGraphBehavior.h [find a way to not hard code the 17 default value] + if((pos.x > collectionSelected->position.x + 17) || (pos.x < collectionSelected->position.x) ) + { + graphBehavior->UpdatePosObject(collectionSelected, pos.x, pos.y, 40); + } + + // Don't draw too much when dragging table around canvas [lower cpu use] + if(refresh % refreshRate == 0) + { + this->Refresh(); + refresh = 1; + } + else + refresh++; + + } + } + else if(mode == pt_join) + { + if(joinSource && !joinDest) + { + this->Refresh(); + } + + } + } +} + + +void gqbView::OnKeyDown(wxKeyEvent &event) +{ + if(event.GetKeyCode() == WXK_DELETE) + { + if(collectionSelected) + { + this->joinsGridTable->removeJoins(collectionSelected); + controller->removeTableFromModel(collectionSelected, gridTable, orderByLGridTable, orderByRGridTable); + collectionSelected = NULL; + this->Refresh(); + } + + if(joinSelected) + { + this->joinsGridTable->removeJoin(joinSelected); + controller->removeJoin(joinSelected); + joinSelected = NULL; + this->Refresh(); + } + } +} + + +void gqbView::drawAll(wxMemoryDC &bdc, bool adjustScrolling) +{ + bdc.Clear(); + if(!iterator) + // Get an iterator for the objects (tables/views) in the model. + iterator = this->model->createQueryIterator(); + else + iterator->ResetIterator(); + + // First Draw Tables + while(iterator->HasNext()) + { + gqbQueryObject *tmp = (gqbQueryObject *)iterator->Next(); + wxPoint pt = wxPoint(tmp->position); // Use a copy because I don't want to store the modified + // version of point after CalcScrolledPosition was called + + if (adjustScrolling) + { + // adjust coordinates + this->CalcScrolledPosition(pt.x, pt.y, &pt.x, &pt.y); + } + graphBehavior->drawTable(bdc, &pt, tmp); // graph table + } + + // Later Draw Joins over Tables + iterator->ResetIterator(); + while(iterator->HasNext()) + { + gqbQueryObject *tmp = (gqbQueryObject *)iterator->Next(); + + if(tmp->getHaveJoins()) + { + gqbIteratorBase *joinsIterator = tmp->createJoinsIterator(); + while(joinsIterator->HasNext()) + { + gqbQueryJoin *join = (gqbQueryJoin *) joinsIterator->Next(); + wxPoint o = join->getSourceAnchor(); + wxPoint d = join->getDestAnchor(); + + if (adjustScrolling) + { + // adjust coordinates origin + this->CalcScrolledPosition(o.x, o.y, &o.x, &o.y); + + // adjust coordinates destination + this->CalcScrolledPosition(d.x, d.y, &d.x, &d.y); + } + graphBehavior->drawJoin(bdc, o, d, join->getAnchorsUsed(), join->getSelected(), join->getKindofJoin()); + } + delete joinsIterator; + } + + } + + // This iterator is delete at destroyer for reuse purposes + if(joinSource) + { + // Draw temporary line while creating a join + wxPoint source = jpos; + wxPoint destination = pos; + if(adjustScrolling) + { + this->CalcScrolledPosition(source.x, source.y, &source.x, &source.y); + this->CalcScrolledPosition(destination.x, destination.y, &destination.x, &destination.y); + } + graphBehavior->drawTempJoinLine(bdc, source, destination); + } +} + + +void gqbView::setPointerMode(pointerMode pm) +{ + mode = pm; + if(mode == pt_join) + this->SetCursor(joinCursor); + else + this->SetCursor(wxNullCursor); +} + + +bool gqbView::clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest) +{ + return graphBehavior->clickOnJoin(join, pt, origin, dest); +} + + +void gqbView::emptyPanelsData() +{ + gridTable->emptyTableData(); + this->joinsGridTable->emptyTableData(); +} + + +void gqbView::newTableAdded(gqbQueryObject *item) +{ + // Refresh Order By Panel's Left Grid + if (orderByLGridTable->GetView() ) + { + wxGridTableMessage msg( orderByLGridTable, + wxGRIDTABLE_NOTIFY_ROWS_INSERTED, + orderByLGridTable->GetNumberRows() - 1, + item->parent->countCols() ); + orderByLGridTable->GetView()->ProcessTableMessage( msg ); + } +} + +void gqbView::updateTable(gqbQueryObject *queryTable) +{ + if (queryTable->getHaveJoins()) + { + gqbIteratorBase *j = queryTable->createJoinsIterator(); + while (j->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)j->Next(); + graphBehavior->calcAnchorPoint(tmp); + } + delete j; + } + + // Update position of anchor points of Joins that come from others tables + if (queryTable->getHaveRegJoins()) + { + gqbIteratorBase *r = queryTable->createRegJoinsIterator(); + while (r->HasNext()) + { + gqbQueryJoin *tmp = (gqbQueryJoin *)r->Next(); + graphBehavior->calcAnchorPoint(tmp); + } + delete r; + } + this->Refresh(); +} + + +void gqbView::OnRefresh(wxCommandEvent &ev) +{ + updateModelSize(NULL, true); + this->Update(); +} + + +/* +* updateModelSize +* - Update the model size. +* - Calculate the maximum width and maximum height of the model +* * When removed a table/view from model, the obj parameter must be null, +* and update parameter should be true, otherwise update parameter should +* be false (Dragging event) +*/ +void gqbView::updateModelSize(gqbQueryObject *obj, bool updateAnyWay) +{ + static int callCount = 0; + callCount++; + if (!obj) + { + // Do not update model size, everytime it gets called + // Update the size once in 10 times + // Update the size only if update flag is true + if (callCount < 10 && !updateAnyWay) + return; + callCount = 0; + // Figure out the actual model size. + // Remove table + int w = 0, h = 0, maxW = 0, maxH = 0; + if(!iterator) + // Get an iterator for the objects (tables/views) in the model. + iterator = this->model->createQueryIterator(); + else + iterator->ResetIterator(); + + while (iterator->HasNext()) + { + gqbQueryObject *tmp = (gqbQueryObject *)iterator->Next();; + w = tmp->position.x + tmp->getWidth(); + h = tmp->position.y + tmp->getHeight(); + + if (maxW < w) + maxW = w; + if (maxH < h) + maxH = h; + } + + // Reset Model size + modelSize.Set(maxW, maxH); + } + else + { + int w = 0, h = 0; + w = obj->position.x + obj->getWidth(); + h = obj->position.y + obj->getHeight(); + + if (w > modelSize.GetWidth()) + modelSize.SetWidth(w); + if (h > modelSize.GetHeight()) + modelSize.SetHeight(h); + } + bool updateView = false; + int viewW, viewH; + GetSize(&viewW, &viewH); + + if (viewW < GQB_MIN_WIDTH) + viewW = GQB_MIN_WIDTH; + + if (viewH < GQB_MIN_HEIGHT) + viewH = GQB_MIN_HEIGHT; + + if ((modelSize.GetWidth() > viewW || canvasSize.GetWidth() > viewW) && + modelSize.GetWidth() != canvasSize.GetWidth()) + { + canvasSize.SetWidth((modelSize.GetWidth() > viewW ? modelSize.GetWidth() : viewW)); + updateView = true; + } + if ((modelSize.GetHeight() > viewH || canvasSize.GetHeight() > viewH ) && + modelSize.GetHeight() != canvasSize.GetHeight()) + { + canvasSize.SetHeight((modelSize.GetHeight() > viewH ? modelSize.GetHeight() : viewH)); + updateView = true; + } + + if (canvasSize.GetWidth() < viewW) + { + canvasSize.SetWidth(viewW); + updateView = true; + } + + if (canvasSize.GetHeight() < viewH) + { + canvasSize.SetHeight(viewH); + updateView = true; + } + + if (updateView) + { + SetVirtualSize(canvasSize); + } + + FitInside(); + Refresh(); +} + +void gqbView::OnSize(wxSizeEvent &event) +{ + updateModelSize(NULL, true); +} + + +bool gqbView::canSaveAsImage() +{ + updateModelSize(NULL, true); + return !(modelSize.GetWidth() == 0 || modelSize.GetHeight() == 0); +} + +void gqbView::SaveAsImage(const wxString &fileName, wxBitmapType imgType) +{ + + updateModelSize(NULL, true); + + if (modelSize.GetWidth() == 0 || modelSize.GetHeight() == 0) + { + wxMessageBox(_("Nothing to be saved!"), _("Save As an image"), wxOK | wxICON_INFORMATION); + return; + } + + int width = 0, height = 0; + GetVirtualSize(&width, &height); + + /* + * Create the bitmap from the Explain window + */ + wxMemoryDC memDC; + wxBitmap tempBitmap(width, height); + + memDC.SelectObject(tempBitmap); + memDC.Clear(); + + // Draw the diagram on the bitmap (Memory Device Context) + drawAll(memDC, false); + + memDC.SelectObject(wxNullBitmap); + + if (!tempBitmap.SaveFile(fileName, imgType)) + { + wxLogError(_("Could not write the file %s: Errcode=%d."), fileName.c_str(), wxSysErrorCode()); + } +} + + + diff --git a/gqb/gqbViewPanels.cpp b/gqb/gqbViewPanels.cpp new file mode 100644 index 0000000..ec35f1a --- /dev/null +++ b/gqb/gqbViewPanels.cpp @@ -0,0 +1,1648 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbViewPanels.cpp - All panels used by GQB +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include + +// App headers +#include "gqb/gqbViewPanels.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridJoinTable.h" + +// Images +#include "images/gqbUp.pngc" +#include "images/gqbUpTop.pngc" +#include "images/gqbDown.pngc" +#include "images/gqbDownBottom.pngc" +#include "images/gqbOrderAddAll.pngc" +#include "images/gqbOrderRemoveAll.pngc" +#include "images/gqbOrderRemove.pngc" +#include "images/gqbOrderAdd.pngc" +#include "images/gqbAddRest.pngc" +#include "images/gqbRemoveRest.pngc" +#include "images/tables.pngc" +#include "images/table-sm.pngc" +#include "images/column-sm.pngc" +#include "images/view-sm.pngc" +#include "images/gqbAdd.pngc" +#include "images/gqbRemove.pngc" + +// Get available ID for Criteria & Joins Panel +long CRITERIA_PANEL_RESTRICTION_GRID_ID = ::wxNewId(); +long JOINS_PANEL_GRID_ID = ::wxNewId(); + +// +// View Columns Grid Panel Class. +// + +BEGIN_EVENT_TABLE(gqbGridPanel, wxPanel) + EVT_GRID_SELECT_CELL(gqbGridPanel::OnGridSelectCell) + EVT_GRID_RANGE_SELECT(gqbGridPanel::OnGridRangeSelected) + EVT_BUTTON(GQB_COLS_UP_BUTTON_ID, gqbGridPanel::OnButtonUp) + EVT_BUTTON(GQB_COLS_UP_TOP_BUTTON_ID, gqbGridPanel::OnButtonUpTop) + EVT_BUTTON(GQB_COLS_DOWN_BUTTON_ID, gqbGridPanel::OnButtonDown) + EVT_BUTTON(GQB_COLS_DOWN_BOTTOM_BUTTON_ID, gqbGridPanel::OnButtonDownBottom) +END_EVENT_TABLE() + +gqbGridPanel::gqbGridPanel(wxWindow *parent, wxWindowID id = wxID_ANY, gqbGridProjTable *gridModel = NULL): + wxPanel(parent, -1) +{ + gModel = gridModel; + allowSelCells = true; + selTop = -1; + selBottom = -1; + upBitmap = *gqbUp_png_bmp; + upTopBitmap = *gqbUpTop_png_bmp; + downBitmap = *gqbDown_png_bmp; + downBottomBitmap = *gqbDownBottom_png_bmp; + + buttonUp = new wxBitmapButton( this, GQB_COLS_UP_BUTTON_ID, upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Up") ); + buttonUp->SetToolTip(_("Move the selected column up")); + buttonUpTop = new wxBitmapButton( this, GQB_COLS_UP_TOP_BUTTON_ID, upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Top") ); + buttonUpTop->SetToolTip(_("Move the selected column to the top")); + buttonDown = new wxBitmapButton( this, GQB_COLS_DOWN_BUTTON_ID, downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Down") ); + buttonDown->SetToolTip(_("Move the selected column down")); + buttonDownBottom = new wxBitmapButton( this, GQB_COLS_DOWN_BOTTOM_BUTTON_ID, downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Bottom") ); + buttonDownBottom->SetToolTip(_("Move the selected column to the bottom")); + + this->colsGrid = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("")); + colsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells); + + // Adjust the default row height to be more compact + wxFont font = colsGrid->GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + colsGrid->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + colsGrid->SetColLabelSize(nHeight + 6); + colsGrid->SetRowLabelSize(35); +#ifdef __WXGTK__ + colsGrid->SetDefaultRowSize(nHeight + 8, TRUE); +#else + colsGrid->SetDefaultRowSize(nHeight + 4, TRUE); +#endif + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + horizontalSizer->Add(colsGrid, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonUpTop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonUp, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDown, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDownBottom, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +gqbGridPanel::~gqbGridPanel() +{ + if (buttonUp) + delete buttonUp; + if(buttonDown) + delete buttonDown; + if(buttonUpTop) + delete buttonUpTop; + if(buttonDownBottom) + delete buttonDownBottom; +} + + +void gqbGridPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column about 33% each one + int size = (int)((colsGrid->GetSize().GetWidth() - colsGrid->GetRowLabelSize()) * 0.30); + colsGrid->SetColSize(0, size); + colsGrid->SetColSize(1, size); + colsGrid->SetColSize(2, size); +} + + +void gqbGridPanel::OnGridSelectCell( wxGridEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + selTop = ev.GetRow(); + selBottom = -1; + } + else + { + selTop = -1; + selBottom = -1; + } + } + ev.Skip(); +} + + +void gqbGridPanel::OnGridRangeSelected( wxGridRangeSelectEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + selTop = ev.GetTopRow(); + selBottom = ev.GetBottomRow(); + } + else + { + selTop = -1; + selBottom = -1; + } + } + ev.Skip(); +} + + +void gqbGridPanel::OnButtonUp(wxCommandEvent &) +{ + // A single row is selected + allowSelCells = false; + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + --selTop; + gModel->changesPositions(selTop, selTop + 1); + if(selTop < 0) + { + selTop = 0; + } + colsGrid->SelectBlock(selTop, 0, selTop, 1, false); + colsGrid->SetGridCursor(selTop, 0); + selBottom = -1; + } + else + { + // A range of rows is selected + if (selTop >= 0 && selBottom >= 0) + { + int newTop = selTop - 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + if(selTop > 0) // recalculate new selection area & avoid bad selection area + { + selTop--; + selBottom--; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + allowSelCells = true; +} + + +void gqbGridPanel::OnButtonUpTop(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + selBottom = selTop - 1; + selTop = 0; + gModel->changesRangeOnePos(selTop, selBottom, 1); + colsGrid->SelectBlock(0, 0, 0, 1, false); + colsGrid->SetGridCursor(0, 0); + + // Put variables in correct values now. + selTop = 0; + selBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0; + if (selTop >= 0 && selBottom >= 0) + { + // Move all range only one pos the require times to get the top + for(int i = selTop; i > 0; i--) + { + newTop = selTop - 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selTop > 0) + { + selTop--; + selBottom--; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + } + allowSelCells = true; +} + + +void gqbGridPanel::OnButtonDown(wxCommandEvent &) +{ + + allowSelCells = false; + + // A single row is selected + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + ++selTop; + gModel->changesPositions(selTop, selTop - 1); + + // Adjust selection when selected item it's last item. + if(selTop == gModel->GetNumberRows()) + { + selTop--; + } + colsGrid->SelectBlock(selTop, 0, selTop, 1, false); + colsGrid->SetGridCursor(selTop, 0); + selBottom = -1; + } + // A range of rows is selected + else + { + if (selTop >= 0 && selBottom >= 0) + { + int newTop = selTop + 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selBottom < gModel->GetNumberRows() - 1) + { + selTop++; + selBottom++; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + allowSelCells = true; +} + + +void gqbGridPanel::OnButtonDownBottom(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selTop >= 0 && selBottom == -1) || (selTop == selBottom)) + { + selBottom = gModel->GetNumberRows() - 1; + selTop = selTop + 1; + int newBottom = gModel->GetNumberRows() - 1; + gModel->changesRangeOnePos(selTop, selBottom, selTop - 1); + colsGrid->SelectBlock(newBottom, 0, newBottom, 1, false); + colsGrid->SetGridCursor(newBottom, 0); + + // Put variables in correct values now. + selTop = newBottom; + selBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0, size = gModel->GetNumberRows(); + + if (selTop >= 0 && selBottom >= 0) + { + for(int i = selBottom; i < size; i++) + { + newTop = selTop + 1; + gModel->changesRangeOnePos(selTop, selBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selBottom < gModel->GetNumberRows() - 1) + { + selTop++; + selBottom++; + } + colsGrid->SelectBlock(selTop, 0, selBottom, 1, false); + colsGrid->SetGridCursor(selTop, 0); + } + } + } + allowSelCells = true; +} + + +// +// Tree with Columns & tables inside a query model +// + +gqbColsTree::gqbColsTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style) + : wxTreeCtrl(parent, id, pos, size, style) +{ + wxImageList *imageList = new wxImageList(16, 16); + imageList->Add(*tables_png_ico); + imageList->Add(*table_sm_png_ico); + imageList->Add(*column_sm_png_ico); + imageList->Add(*view_sm_png_ico); + this->AssignImageList(imageList); + wxString a = _("Select column"); + createRoot(a); + this->Expand(rootNode); +} + + +// Create root node +wxTreeItemId &gqbColsTree::createRoot(wxString &Name) +{ + rootNode = this->AddRoot(Name, 0, 0); + return rootNode; +} + + +// Override the DeleteAllItems virtual function +// Needs to set null as item-data, otherwise they will delete +// the gqbQueryObject(s) and gqbColumn(s), while deleting these +// items +void gqbColsTree::DeleteAllItems() +{ + wxTreeItemId tableId; + wxTreeItemIdValue tableCookie; + wxTreeItemId rootId = this->GetRootItem(); + + if ( this->GetChildrenCount(rootId, false) != 0 ) + { + wxTreeItemId lastTableId = this->GetLastChild(rootId); + tableId = this->GetFirstChild(rootId, tableCookie); + while ( true ) + { + this->SetItemData(tableId, NULL); + wxTreeItemIdValue colCookie; + wxTreeItemId colId = this->GetFirstChild(tableId, colCookie); + wxTreeItemId lastColId = this->GetLastChild(tableId); + if ( this->GetChildrenCount(tableId, false) != 0 ) + { + while ( true ) + { + this->SetItemData(colId, NULL); + if ( colId != lastColId ) + colId = this->GetNextSibling(colId); + else + break; + } + } + if ( lastTableId != tableId ) + tableId = this->GetNextSibling(tableId); + else + break; + } + } + wxTreeCtrl::DeleteAllItems(); +} + +void gqbColsTree::refreshTree(gqbModel *model, gqbQueryObject *doNotInclude) +{ + // This remove and delete data inside tree's node + this->DeleteAllItems(); + wxString a = _("Select column"); + createRoot(a); + this->Expand(rootNode); + + wxTreeItemId parent; + gqbIteratorBase *iterator = model->createQueryIterator(); + while(iterator->HasNext()) + { + gqbQueryObject *tmpTable = (gqbQueryObject *)iterator->Next(); + + if (doNotInclude && tmpTable == doNotInclude) + continue; + + int iconIndex; + if (tmpTable->parent->getType() == GQB_TABLE) + iconIndex = 1; + else // Must be a view + iconIndex = 3; + + if(tmpTable->getAlias().length() > 0) + { + parent = this->AppendItem(rootNode, tmpTable->getAlias() , iconIndex, iconIndex, tmpTable); + } + else + { + parent = this->AppendItem(rootNode, tmpTable->getName() , iconIndex, iconIndex, tmpTable); + } + gqbIteratorBase *colsIterator = tmpTable->parent->createColumnsIterator(); + while(colsIterator->HasNext()) + { + gqbColumn *tmpColumn = (gqbColumn *)colsIterator->Next(); + this->AppendItem(parent, tmpColumn->getName() , 2, 2, tmpColumn); + } + delete colsIterator; + } + delete iterator; + + if (rootNode) + { + this->SortChildren(rootNode); + this->Expand(rootNode); + } +} + + +// +// Popup Window for gqbColsTree +// + +gqbColsPopUp::gqbColsPopUp(wxWindow *parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size): + wxDialog(parent, id, title, pos, size, wxRESIZE_BORDER | wxCAPTION) +{ + this->SetSize(wxSize(243, 165)); + wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL); + + editTree = new wxTextCtrl(this, QR_TREE, wxT(""), wxPoint(5, 5), wxSize(193, 22)); + editTree->AcceptsFocus(); + editTree->SetFocus(); + editTree->SetEditable(true); + + hSizer->Add(editTree, 1, wxEXPAND | wxRIGHT, 3); + + buttonTree = new wxButton(this, QR_TREE_OK, _("OK") , wxPoint(199, 5), wxDefaultSize, wxBU_EXACTFIT); + this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbColsPopUp::OnPopUpOKClick); + + hSizer->Add(buttonTree); + vSizer->Add(hSizer, 0, wxEXPAND | wxALL, 3); + + colsTree = new gqbColsTree(this, QR_TREE, wxPoint(5, 31), wxSize(224, 104), wxTR_HAS_BUTTONS | wxSIMPLE_BORDER | wxTR_SINGLE); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeDoubleClick); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbColsPopUp::OnPopUpTreeClick); + + vSizer->Add(colsTree, 1, wxEXPAND | wxALL, 3); + SetSizer(vSizer); +} + + +void gqbColsPopUp::refreshTree(gqbModel *_model) +{ + model = _model; + if(colsTree && _model) + { + colsTree->refreshTree(model); + } + +} + + +void gqbColsPopUp::OnPopUpOKClick(wxCommandEvent &event) +{ + this->usedGrid->SetCellValue(_row, _col, this->getEditText()); + //this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); +} + + +void gqbColsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent &event) +{ + if(colsTree) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + this->usedGrid->SetCellValue(_row, _col, this->getEditText()); + if(this->usedGrid->GetCellValue(_row, _col).length() <= 0) + { + this->usedGrid->SetCellValue(_row, _col, _("Set value")); + } + //this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); + } + } +} + +void gqbColsPopUp::OnPopUpTreeClick(wxTreeEvent &event) +{ + if(colsTree) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId))); + } + } +} + + +void gqbColsPopUp::setEditText(wxString text) +{ + this->editTree->SetValue(text); +} + + +void gqbColsPopUp::focus() +{ + this->editTree->SetFocus(); + this->editTree->SetSelection(-1, -1); +} + + +// +// View Selection Criteria Panel Class. +// + +BEGIN_EVENT_TABLE(gqbCriteriaPanel, wxPanel) + EVT_BUTTON(GQB_COLS_ADD_BUTTON_ID, gqbCriteriaPanel::OnButtonAdd) + EVT_BUTTON(GQB_COLS_DROP_BUTTON_ID, gqbCriteriaPanel::OnButtonDrop) +END_EVENT_TABLE() + +gqbCriteriaPanel::gqbCriteriaPanel(wxWindow *parent, gqbModel *_model, gqbGridRestTable *gridModel): + wxPanel(parent, -1) +{ + model = _model; + gModel = gridModel; + colsPopUp = NULL; + + this->restrictionsGrid = new gqbCustomGrid(this, CRITERIA_PANEL_RESTRICTION_GRID_ID); + restrictionsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells); + this->restrictionsGrid->SetSelectionMode(wxGrid::wxGridSelectRows); + + this->Connect(CRITERIA_PANEL_RESTRICTION_GRID_ID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbCriteriaPanel::OnCellLeftClick); + // GQB-TODO: in a future implement OnMouseWheel + + addBitmap = *gqbAddRest_png_bmp; + dropBitmap = *gqbRemoveRest_png_bmp; + buttonAdd = new wxBitmapButton( this, GQB_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add")); + buttonAdd->SetToolTip(_("Add a new criteria line")); + buttonDrop = new wxBitmapButton( this, GQB_COLS_DROP_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove")); + buttonDrop->SetToolTip(_("Remove the selected criteria line")); + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + horizontalSizer->Add(restrictionsGrid, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDrop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +void gqbCriteriaPanel::showColsPopUp(int row, int col, wxPoint pos) +{ + if(!colsPopUp) + { + colsPopUp = new gqbColsPopUp(this, -1, wxT("Set Value"), wxDefaultPosition, wxDefaultSize); + } + + refreshTree(model); + + // Set initial Value + colsPopUp->setEditText(restrictionsGrid->GetCellValue(row, col)); + + // Set Position for Pop Up Tree + // Position of wxNotebook + wxPoint p = this->GetParent()->GetPosition(); + p.x += pos.x; + p.y += pos.y; + wxPoint p2 = this->GetPosition(); + + // Position of panel inside wxNotebook + p.x += p2.x; + p.y += p2.y + 40; + colsPopUp->SetPosition(p); + //colsPopUp->Show(); + //colsPopUp->MakeModal(true); + colsPopUp->ShowModal(); + colsPopUp->focus(); + colsPopUp->setUsedCell(restrictionsGrid, row, col); +} + + +void gqbCriteriaPanel::refreshTree(gqbModel *_model) +{ + // GQB-TODO: Do this through controller... + model = _model; + if(colsPopUp && model) + colsPopUp->refreshTree(model); + +} + + +void gqbCriteriaPanel::OnCellLeftClick(wxGridEvent &event) +{ + wxObject *object = event.GetEventObject(); + gqbCustomGrid *grid = wxDynamicCast( object, gqbCustomGrid ); + + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + grid->ComboBoxEvent(event); + } + else if(event.GetCol() == 0 || event.GetCol() == 2) + { + // Allow mini browser frame to be visible to user + wxRect cellSize = grid->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + restrictionsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((grid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + showColsPopUp(event.GetRow(), event.GetCol(), p); + } + } //GQB-TODO 1,2 can be integrate with 3 + else if(event.GetCol() == 3) + { + // Change connector of the Restriction between AND/OR + wxRect cellSize = restrictionsGrid->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + restrictionsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((restrictionsGrid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + if( gModel->GetValue(event.GetRow(), 3).Contains(wxT("AND")) ) + { + gModel->SetValue(event.GetRow(), 3, wxT("OR")); + } + else + { + gModel->SetValue(event.GetRow(), 3, wxT("AND")); + } + restrictionsGrid->Refresh(); + } + } + event.Skip(); +} + + +void gqbCriteriaPanel::OnButtonAdd(wxCommandEvent &) +{ + // GQB-TODO: use controller one + gqbQueryRestriction *r = new gqbQueryRestriction(); + gModel->AppendItem(r); + int row = model->getRestrictions()->restrictionsCount() - 1; + + wxString strChoices[16] = {wxT("="), wxT("!="), wxT("<"), wxT("<="), wxT(">"), wxT(">="), wxT("BETWEEN"), wxT("LIKE"), wxT("NOT LIKE"), wxT("ILIKE"), wxT("NOT ILIKE"), wxT("IN"), wxT("NOT IN"), wxT("NOT BETWEEN"), wxT("IS NULL"), wxT("IS NOT NULL")}; + restrictionsGrid->SetCellRenderer(row, 1, new wxGridCellComboBoxRenderer); + restrictionsGrid->SetCellRenderer(row, 0, new wxGridCellButtonRenderer); + restrictionsGrid->SetCellEditor(row, 1, new dxGridCellSizedChoiceEditor(WXSIZEOF(strChoices), strChoices)); + restrictionsGrid->SetCellRenderer(row, 2, new wxGridCellButtonRenderer); + restrictionsGrid->SetCellRenderer(row, 3, new wxGridCellButtonRenderer); + restrictionsGrid->SetReadOnly(row, 3, true); +} + + +void gqbCriteriaPanel::OnButtonDrop(wxCommandEvent &) +{ + if(restrictionsGrid->GetGridCursorRow() >= 0) + gModel->DeleteRows(restrictionsGrid->GetGridCursorRow(), 1); + restrictionsGrid->Refresh(); +} + + +void gqbCriteriaPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column about 33% each one + int size = (int)((restrictionsGrid->GetSize().GetWidth() - restrictionsGrid->GetRowLabelSize()) * 0.225); + restrictionsGrid->SetColSize(0, size); + restrictionsGrid->SetColSize(1, size); + restrictionsGrid->SetColSize(2, size); + restrictionsGrid->SetColSize(3, size); +} + + +// +// View Selection Criteria Panel Class's Grid. +// +gqbCustomGrid::gqbCustomGrid(wxWindow *parent, wxWindowID id): + wxGrid(parent, id, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP, wxT("")), + m_selTemp(NULL) +{ + // Adjust the default row height to be more compact + wxFont font = GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + SetColLabelSize(nHeight + 6); + SetRowLabelSize(35); +#ifdef __WXGTK__ + SetDefaultRowSize(nHeight + 8, TRUE); +#else + SetDefaultRowSize(nHeight + 4, TRUE); +#endif +} + + +void gqbCustomGrid::RevertSel() +{ + if (m_selTemp) + { + wxASSERT(m_selection == NULL); + m_selection = m_selTemp; + m_selTemp = NULL; + } +} + + +void gqbCustomGrid::ComboBoxEvent(wxGridEvent &event) +{ + + // This forces the cell to go into edit mode directly + this->m_waitForSlowClick = TRUE; + int row = event.GetRow(); + int col = event.GetCol(); + + this->SetGridCursor(row, col); + + // Store the click co-ordinates in the editor if possible + // if an editor has created a ClientData area, we presume it's + // a wxPoint and we store the click co-ordinates + wxGridCellEditor *pEditor = this->GetCellEditor(event.GetRow(), event.GetCol()); + wxPoint *pClickPoint = (wxPoint *)pEditor->GetClientData(); + if (pClickPoint) + { + *pClickPoint = this->ClientToScreen(event.GetPosition()); +#ifndef __WINDOWS__ + EnableCellEditControl(true); +#endif + } + + // hack to prevent selection from being lost when click combobox + if (this->IsInSelection(event.GetRow(), event.GetCol())) + { + this->m_selTemp = this->m_selection; + this->m_selection = NULL; + } + pEditor->DecRef(); +} + + +// +// +// Order by Panel +// +// + +BEGIN_EVENT_TABLE(gqbOrderPanel, wxPanel) + EVT_BUTTON(GQB_ORDER_DROP_BUTTON_ID, gqbOrderPanel::OnButtonRemove) + EVT_BUTTON(GQB_ORDER_DROP_ALL_BUTTON_ID, gqbOrderPanel::OnButtonRemoveAll) + EVT_BUTTON(GQB_ORDER_ADD_BUTTON_ID, gqbOrderPanel::OnButtonAdd) + EVT_BUTTON(GQB_ORDER_ADD_ALL_BUTTON_ID, gqbOrderPanel::OnButtonAddAll) + EVT_GRID_SELECT_CELL(gqbOrderPanel::OnGridSelectCell) + EVT_GRID_RANGE_SELECT(gqbOrderPanel::OnGridRangeSelected) + EVT_BUTTON(GQB_ORDER_UP_BUTTON_ID, gqbOrderPanel::OnButtonUp) + EVT_BUTTON(GQB_ORDER_UP_TOP_BUTTON_ID, gqbOrderPanel::OnButtonUpTop) + EVT_BUTTON(GQB_ORDER_DOWN_BUTTON_ID, gqbOrderPanel::OnButtonDown) + EVT_BUTTON(GQB_ORDER_DOWN_BOTTOM_BUTTON_ID, gqbOrderPanel::OnButtonDownBottom) +END_EVENT_TABLE() + +gqbOrderPanel::gqbOrderPanel(wxWindow *parent, gqbGridOrderTable *gridTableLeft, gqbGridOrderTable *gridTableRight): + wxPanel(parent, -1) +{ + + // GQB-TODO: change bitmap buttons + selLeft = -1; + selRightTop = -1; + selRightBottom = -1; + tableLeft = gridTableLeft; + tableRight = gridTableRight; + allowSelCells = true; + + addBitmap = *gqbOrderAdd_png_bmp; + addAllBitmap = *gqbOrderAddAll_png_bmp; + removeBitmap = *gqbOrderRemove_png_bmp; + removeAllBitmap = *gqbOrderRemoveAll_png_bmp; + + buttonAdd = new wxBitmapButton( this, GQB_ORDER_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add Column") ); + buttonAdd->SetToolTip(_("Add the selected column")); + buttonAddAll = new wxBitmapButton( this, GQB_ORDER_ADD_ALL_BUTTON_ID, addAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add All Columns") ); + buttonAddAll->SetToolTip(_("Add all columns")); + buttonRemove = new wxBitmapButton( this, GQB_ORDER_DROP_BUTTON_ID, removeBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove Column") ); + buttonRemove->SetToolTip(_("Remove the selected column")); + buttonRemoveAll = new wxBitmapButton( this, GQB_ORDER_DROP_ALL_BUTTON_ID, removeAllBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove All Columns") ); + buttonRemoveAll->SetToolTip(_("Remove all columns")); + + upBitmap = *gqbUp_png_bmp; + upTopBitmap = *gqbUpTop_png_bmp; + downBitmap = *gqbDown_png_bmp; + downBottomBitmap = *gqbDownBottom_png_bmp; + + buttonUp = new wxBitmapButton( this, GQB_ORDER_UP_BUTTON_ID, upBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Up") ); + buttonUp->SetToolTip(_("Move the selected column up")); + buttonDown = new wxBitmapButton( this, GQB_ORDER_DOWN_BUTTON_ID, downBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Down") ); + buttonDown->SetToolTip(_("Move the selected column down")); + buttonUpTop = new wxBitmapButton( this, GQB_ORDER_UP_TOP_BUTTON_ID, upTopBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Top") ); + buttonUpTop->SetToolTip(_("Move the selected column to the top")); + buttonDownBottom = new wxBitmapButton( this, GQB_ORDER_DOWN_BOTTOM_BUTTON_ID, downBottomBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Bottom") ); + buttonDownBottom->SetToolTip(_("Move the selected column to the bottom")); + + availableColumns = new wxGrid(this, -1, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("Available Columns")); + availableColumns->SetTable(gridTableLeft); + availableColumns->EnableEditing(false); + + // Adjust the default row height to be more compact + wxFont font = availableColumns->GetLabelFont(); + int nWidth = 0; + int nHeight = 18; + availableColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + availableColumns->SetColLabelSize(nHeight + 6); + availableColumns->SetRowLabelSize(35); +#ifdef __WXGTK__ + availableColumns->SetDefaultRowSize(nHeight + 8, TRUE); +#else + availableColumns->SetDefaultRowSize(nHeight + 4, TRUE); +#endif + + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + + horizontalSizer->Add(availableColumns, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer1 = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer1->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer1->Add( + this->buttonAddAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer1->Add( + this->buttonRemove, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer1->Add( + this->buttonRemoveAll, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer1, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + // GQB-TODO: change 333 for a new and better one. + usedColumns = new wxGrid(this, 333, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY | wxTE_BESTWRAP , wxT("Columns Order")); + usedColumns->SetTable(gridTableRight); + usedColumns->EnableEditing(false); + + // Adjust the default row height to be more compact + font = usedColumns->GetLabelFont(); + nWidth = 0; + nHeight = 18; + usedColumns->GetTextExtent(wxT("W"), &nWidth, &nHeight, NULL, NULL, &font); + usedColumns->SetColLabelSize(nHeight + 6); + usedColumns->SetRowLabelSize(35); +#ifdef __WXGTK__ + usedColumns->SetDefaultRowSize(nHeight + 8, TRUE); +#else + usedColumns->SetDefaultRowSize(nHeight + 4, TRUE); +#endif + + this->Connect(333, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbOrderPanel::OnCellLeftClick); + + horizontalSizer->Add(usedColumns, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer2 = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer2->Add( + this->buttonUpTop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer2->Add( + this->buttonUp, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer2->Add( + this->buttonDown, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + buttonsSizer2->Add( + this->buttonDownBottom, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 3 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer2, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +void gqbOrderPanel::OnButtonRemove(wxCommandEvent &) +{ + if(usedColumns->GetNumberRows() > 0) + { + if(selRightTop != -1) + { + gqbColumn *col = (gqbColumn *) tableRight->getObjectAt(selRightTop, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(selRightTop, 1); + tableLeft->AppendItem(col, colParent, 'N'); + tableRight->removeRowAt(selRightTop); + } + } +} + + +void gqbOrderPanel::OnButtonRemoveAll(wxCommandEvent &) +{ + if(usedColumns->GetNumberRows() > 0) + { + for(int i = usedColumns->GetNumberRows() - 1; i >= 0; i--) + { + gqbColumn *col = (gqbColumn *) tableRight->getObjectAt(i, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableRight->getObjectAt(i, 1); + tableLeft->AppendItem(col, colParent, 'N'); + tableRight->removeRowAt(i); + } + } +} + + +void gqbOrderPanel::OnButtonAdd(wxCommandEvent &) +{ + if(availableColumns->GetNumberRows() > 0) + { + if(selLeft != -1) + { + gqbColumn *col = (gqbColumn *) tableLeft->getObjectAt(selLeft, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(selLeft, 1); + tableRight->AppendItem(col, colParent, 'A'); + usedColumns->SetCellRenderer((usedColumns->GetNumberRows() - 1), 1, new wxGridCellButtonRenderer); + tableLeft->removeRowAt(selLeft); + } + } +} + + +void gqbOrderPanel::OnButtonAddAll(wxCommandEvent &) +{ + if(availableColumns->GetNumberRows() > 0) + { + for(int i = availableColumns->GetNumberRows() - 1; i >= 0; i--) + { + gqbColumn *col = (gqbColumn *) tableLeft->getObjectAt(i, 0); + gqbQueryObject *colParent = (gqbQueryObject *) tableLeft->getObjectAt(i, 1); + tableRight->AppendItem(col, colParent, 'A'); + usedColumns->SetCellRenderer((usedColumns->GetNumberRows() - 1), 1, new wxGridCellButtonRenderer); + tableLeft->removeRowAt(i); + } + } +} + + +void gqbOrderPanel::OnGridSelectCell( wxGridEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + wxObject *object = ev.GetEventObject(); + wxGrid *grid = wxDynamicCast( object, wxGrid ); + if(grid->GetNumberCols() == 1) // Left Grid + { + selLeft = ev.GetRow(); + } + else + { + // Right Grid + selRightTop = ev.GetRow(); + selRightBottom = -1; + } + } + else + { + selRightTop = -1; // GQB-TODO: this is correct?? + selRightBottom = -1; + selLeft = -1; + } + } + ev.Skip(); +} + + +void gqbOrderPanel::OnGridRangeSelected( wxGridRangeSelectEvent &ev ) +{ + if(allowSelCells) + { + if ( ev.Selecting() ) + { + selRightTop = ev.GetTopRow(); + selRightBottom = ev.GetBottomRow(); + } + else + { + selRightTop = -1; + selRightBottom = -1; + } + } + ev.Skip(); +} + + +void gqbOrderPanel::OnButtonUp(wxCommandEvent &) +{ + // A single row is selected + allowSelCells = false; + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + --selRightTop; + tableRight->changesPositions(selRightTop, selRightTop + 1); + if(selRightTop < 0) + { + selRightTop = 0; + } + usedColumns->SelectBlock(selRightTop, 0, selRightTop, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + selRightBottom = -1; + } + else + { + // A range of rows is selected + if (selRightTop >= 0 && selRightBottom >= 0) + { + int newTop = selRightTop - 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + if(selRightTop > 0) // Recalculate new selection area & avoid bad selection area + { + selRightTop--; + selRightBottom--; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::OnButtonUpTop(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + selRightBottom = selRightTop - 1; + selRightTop = 0; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, 1); + usedColumns->SelectBlock(0, 0, 0, 1, false); + usedColumns->SetGridCursor(0, 0); + + // Put variables in correct values now. + selRightTop = 0; + selRightBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0; + if (selRightTop >= 0 && selRightBottom >= 0) + { + // Move all range only one pos the require times to get the top + for(int i = selRightTop; i > 0; i--) + { + newTop = selRightTop - 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selRightTop > 0) + { + selRightTop--; + selRightBottom--; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::OnButtonDown(wxCommandEvent &) +{ + + allowSelCells = false; + + // A single row is selected + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + ++selRightTop; + tableRight->changesPositions(selRightTop, selRightTop - 1); + + // Adjust selection when selected item it's last item. + if(selRightTop == tableRight->GetNumberRows()) + { + selRightTop--; + } + usedColumns->SelectBlock(selRightTop, 0, selRightTop, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + selRightBottom = -1; + } + // A range of rows is selected + else + { + if (selRightTop >= 0 && selRightBottom >= 0) + { + int newTop = selRightTop + 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selRightBottom < tableRight->GetNumberRows() - 1) + { + selRightTop++; + selRightBottom++; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::OnButtonDownBottom(wxCommandEvent &) +{ + allowSelCells = false; + + // A Single Row is selected + if((selRightTop >= 0 && selRightBottom == -1) || (selRightTop == selRightBottom)) + { + selRightBottom = tableRight->GetNumberRows() - 1; + selRightTop = selRightTop + 1; + int newBottom = tableRight->GetNumberRows() - 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, selRightTop - 1); + usedColumns->SelectBlock(newBottom, 0, newBottom, 1, false); + usedColumns->SetGridCursor(newBottom, 0); + + // Put variables in correct values now. + selRightTop = newBottom; + selRightBottom = -1; + } + // A range of rows is selected + else + { + int newTop = 0, size = tableRight->GetNumberRows(); + + if (selRightTop >= 0 && selRightBottom >= 0) + { + for(int i = selRightBottom; i < size; i++) + { + newTop = selRightTop + 1; + tableRight->changesRangeOnePos(selRightTop, selRightBottom, newTop); + + // Recalculate new selection area & avoid bad selection area + if(selRightBottom < tableRight->GetNumberRows() - 1) + { + selRightTop++; + selRightBottom++; + } + usedColumns->SelectBlock(selRightTop, 0, selRightBottom, 1, false); + usedColumns->SetGridCursor(selRightTop, 0); + } + } + } + allowSelCells = true; +} + + +void gqbOrderPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column + int size = (int)((availableColumns->GetSize().GetWidth() - availableColumns->GetRowLabelSize()) * 0.90); + availableColumns->SetColSize(0, size); + + size = (int)((usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize()) * 0.65); + int size2 = (int)((usedColumns->GetSize().GetWidth() - usedColumns->GetRowLabelSize()) * 0.25); + usedColumns->SetColSize(0, size); + usedColumns->SetColSize(1, size2); +} + + +void gqbOrderPanel::OnCellLeftClick(wxGridEvent &event) +{ + + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + // Change kind of order of the columns between ASC and DESC + wxRect cellSize = usedColumns->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + usedColumns->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((usedColumns->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + if( tableRight->GetValue(event.GetRow(), 1).Contains(wxT("ASC")) ) + { + tableRight->SetValue(event.GetRow(), 1, wxT("DESC")); + } + else + { + tableRight->SetValue(event.GetRow(), 1, wxT("ASC")); + } + usedColumns->Refresh(); + } + } + event.Skip(); +} + +// Popup window for gqbJoinsPanel +// +gqbJoinsPopUp::gqbJoinsPopUp( + gqbJoinsPanel *parent, wxWindowID id, wxString title, + wxPoint pos, const wxSize size, gqbQueryJoin *_join, + bool isSource, gqbGridJoinTable *_gmodel) + : gqbColsPopUp(parent, id, title, pos, size) +{ + this->editTree->SetEditable(false); + + // Handles different events for Ok button, single mouse click, double mouse click + this->Connect(QR_TREE_OK, wxEVT_COMMAND_BUTTON_CLICKED, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &gqbJoinsPopUp::OnPopUpOKClick); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_ITEM_ACTIVATED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbJoinsPopUp::OnPopUpTreeDoubleClick); + this->Connect(QR_TREE, wxEVT_COMMAND_TREE_SEL_CHANGED, (wxObjectEventFunction) (wxEventFunction) (wxTreeEventFunction) &gqbJoinsPopUp::OnPopUpTreeClick); + + this->selectedTbl = NULL; + this->selectedCol = NULL; + this->join = _join; + this->isSource = isSource; + this->gModel = _gmodel; +} + +void gqbJoinsPopUp::refreshTree(gqbModel *_model) +{ + model = _model; + if(colsTree && _model) + { + // Do not include already included Table + // For self join, other entity for the same table should be used with alias + if ( join ) + colsTree->refreshTree(model, isSource ? join->getDestQTable() : join->getSourceQTable()); + else + colsTree->refreshTree(model); + } +} + +// single mouse click on tree +void gqbJoinsPopUp::OnPopUpTreeClick(wxTreeEvent &event) +{ + if( colsTree ) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + selectedCol = (gqbColumn *)colsTree->GetItemData(itemId); + selectedTbl = (gqbQueryObject *)colsTree->GetItemData(itemIdParent); + this->editTree->SetValue(qtIdent(colsTree->GetItemText(itemIdParent)) + wxT(".") + qtIdent(colsTree->GetItemText(itemId))); + } + else + { + selectedCol = NULL; + selectedTbl = NULL; + } + } +} + + +void gqbJoinsPopUp::OnPopUpOKClick(wxCommandEvent &event) +{ + if( colsTree && selectedCol && selectedTbl ) + { + // This should update the selected Join with the new values. + updateJoin(); + } + + //this->MakeModal(false); + + this->Hide(); + this->GetParent()->Refresh(); + this->join = NULL; + this->selectedCol = NULL; + this->selectedTbl = NULL; +} + + +// Update the view fo this query table, involved in +// the whole operation +void gqbJoinsPanel::updateView(gqbQueryObject *table) +{ + if (table) + controller->getView()->updateTable(table); +} + +void gqbJoinsPopUp::updateJoin() +{ + if ((isSource ? join->getSCol() : join->getDCol()) != selectedCol) + { + // Create a new join with the existing data + // Replace it in the gqbJoinTable with the existing one + // Unregister the join, if exists + gqbQueryObject *srcTbl = ( isSource ? selectedTbl : join->getSourceQTable() ); + gqbQueryObject *destTbl = ( isSource ? join->getDestQTable() : selectedTbl ); + gqbColumn *srcCol = ( isSource ? selectedCol : join->getSCol() ); + gqbColumn *destCol = ( isSource ? join->getDCol() : selectedCol ); + type_Join joinType = join->getKindofJoin(); + + gqbQueryJoin *newJoin = NULL; + if( srcTbl && destTbl ) + { + newJoin = srcTbl->addJoin(srcTbl, destTbl, srcCol, destCol, joinType); + ((gqbJoinsPanel *)GetParent())->updateView(newJoin->getSourceQTable()); + } + else + newJoin = new gqbQueryJoin(srcTbl, destTbl, srcCol, destCol, joinType); + + gModel->ReplaceJoin(join, newJoin); + + if (join->getSourceQTable() && join->getDestQTable()) + { + // This will remove the join object too + gqbQueryObject *srcObj = join->getSourceQTable(); + srcObj->removeJoin(join, true); + } + else + { + delete join; + } + join = newJoin; + } +} + + +void gqbJoinsPopUp::OnPopUpTreeDoubleClick(wxTreeEvent &event) +{ + if(colsTree) + { + wxTreeItemId itemId = event.GetItem(); + wxTreeItemId itemIdParent = colsTree->GetItemParent(itemId); + if(!colsTree->ItemHasChildren(itemId) && (colsTree->GetRootItem() != itemId)) + { + selectedCol = (gqbColumn *)colsTree->GetItemData(itemId); + selectedTbl = (gqbQueryObject *)colsTree->GetItemData(itemIdParent); + + updateJoin(); + + //this->MakeModal(false); + this->Hide(); + this->GetParent()->Refresh(); + this->join = NULL; + this->selectedCol = NULL; + this->selectedTbl = NULL; + } + } +} + +// +// View Selection Joins Panel Class. +// + +BEGIN_EVENT_TABLE(gqbJoinsPanel, wxPanel) + EVT_BUTTON(GQB_JOIN_COLS_ADD_BUTTON_ID, gqbJoinsPanel::OnButtonAdd) + EVT_BUTTON(GQB_JOIN_COLS_DELETE_BUTTON_ID, gqbJoinsPanel::OnButtonDrop) +END_EVENT_TABLE() + +gqbJoinsPanel::gqbJoinsPanel(wxWindow *parent, gqbModel *_model, gqbGridJoinTable *_gmodel, gqbController *_controller): + wxPanel(parent, wxID_ANY) +{ + model = _model; + gModel = _gmodel; + controller = _controller; + joinsPopUp = NULL; + + this->joinsGrid = new gqbCustomGrid(this, JOINS_PANEL_GRID_ID); + joinsGrid->CreateGrid(0, 5, wxGrid::wxGridSelectRows); + joinsGrid->SetTable(gModel, true, wxGrid::wxGridSelectCells); + this->joinsGrid->SetSelectionMode(wxGrid::wxGridSelectRows); + + this->Connect(JOINS_PANEL_GRID_ID, wxEVT_GRID_CELL_LEFT_CLICK, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &gqbJoinsPanel::OnCellLeftClick); + // GQB-TODO: in a future implement OnMouseWheel + + addBitmap = *gqbAdd_png_bmp; + dropBitmap = *gqbRemove_png_bmp; + buttonAdd = new wxBitmapButton( this, GQB_JOIN_COLS_ADD_BUTTON_ID, addBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Add")); + buttonAdd->SetToolTip(_("Add a new join")); + buttonDrop = new wxBitmapButton( this, GQB_JOIN_COLS_DELETE_BUTTON_ID, dropBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW, wxDefaultValidator, wxT("Remove")); + buttonDrop->SetToolTip(_("Remove the selected join")); + + wxBoxSizer *horizontalSizer = new wxBoxSizer( wxHORIZONTAL ); + horizontalSizer->Add(joinsGrid, + 1, // make vertically stretchable + wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + 3 ); // set border width to 10 + + wxBoxSizer *buttonsSizer = new wxBoxSizer( wxVERTICAL ); + + buttonsSizer->Add( + this->buttonAdd, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + buttonsSizer->Add( + this->buttonDrop, + 0, // make horizontally unstretchable + wxALL, // make border all around (implicit top alignment) + 10 ); // set border width to 10 + + horizontalSizer->Add( + buttonsSizer, + 0, // make vertically unstretchable + wxALIGN_CENTER ); // no border and centre horizontally + + this->SetSizer(horizontalSizer); +} + + +void gqbJoinsPanel::showColsPopUp(int row, int col, wxPoint pos) +{ + if( joinsPopUp ) + { + joinsPopUp->Destroy(); + joinsPopUp = NULL; + } + joinsPopUp = new gqbJoinsPopUp(this, -1, wxT("Select Column"), wxDefaultPosition, wxDefaultSize, this->gModel->GetJoin(row), ( col == 0 ? true : false ), this->gModel); + + refreshTree(model); + + // Set initial Value + joinsPopUp->setEditText(joinsGrid->GetCellValue(row, col)); + + // Set Position for Pop Up Tree + // Position of wxNotebook + wxPoint p = this->GetParent()->GetPosition(); + p.x += pos.x; + p.y += pos.y; + wxPoint p2 = this->GetPosition(); + + // Position of panel inside wxNotebook + p.x += p2.x; + p.y += p2.y + 40; + joinsPopUp->SetPosition(p); + //joinsPopUp->Show(); + joinsPopUp->ShowModal(); + joinsPopUp->focus(); + joinsPopUp->setUsedCell(joinsGrid, row, col); +} + + +void gqbJoinsPanel::refreshTree(gqbModel *_model) +{ + model = _model; + if(joinsPopUp && model) + joinsPopUp->refreshTree(model); +} + + +void gqbJoinsPanel::OnCellLeftClick(wxGridEvent &event) +{ + wxObject *object = event.GetEventObject(); + gqbCustomGrid *grid = wxDynamicCast( object, gqbCustomGrid ); + + // Only show editor y case of column 1 + if(event.GetCol() == 1) + { + grid->ComboBoxEvent(event); + } + else if(event.GetCol() == 0 || event.GetCol() == 2) + { + // Allow mini browser frame to be visible to user + wxRect cellSize = grid->CellToRect(event.GetRow(), event.GetCol()); + wxPoint p = event.GetPosition(); + joinsGrid->CalcUnscrolledPosition(p.x, p.y, &p.x, &p.y); + + // Number 17 is button's width at cellRender function [nButtonWidth] + if((grid->GetRowLabelSize() + cellSize.GetRight()) - (p.x) <= 17 ) + { + p = event.GetPosition(); + showColsPopUp(event.GetRow(), event.GetCol(), p); + } + } + event.Skip(); +} + + +void gqbJoinsPanel::OnButtonAdd(wxCommandEvent &) +{ + this->gModel->AppendJoin( NULL ); +} + + +void gqbJoinsPanel::OnButtonDrop(wxCommandEvent &) +{ + if(joinsGrid->GetGridCursorRow() >= 0) + { + gqbQueryObject *updateTbl = gModel->DeleteRow(joinsGrid->GetGridCursorRow()); + if (updateTbl) + controller->getView()->updateTable(updateTbl); + } + joinsGrid->Refresh(); +} + + +void gqbJoinsPanel::SetGridColsSize() +{ + // After sizers determine the width of Grid then calculate the % space for each column about 33% each one + int size = (int)((joinsGrid->GetSize().GetWidth() - joinsGrid->GetRowLabelSize()) * 0.3); + joinsGrid->SetColSize(0, size); + joinsGrid->SetColSize(1, size); + joinsGrid->SetColSize(2, size); +} + +void gqbJoinsPanel::selectJoin(gqbQueryJoin *join) +{ + joinsGrid->RevertSel(); + gModel->selectJoin(join); +} + diff --git a/gqb/module.mk b/gqb/module.mk new file mode 100644 index 0000000..674daa0 --- /dev/null +++ b/gqb/module.mk @@ -0,0 +1,36 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/gqb/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + gqb/gqbArrayCollection.cpp \ + gqb/gqbBrowser.cpp \ + gqb/gqbCollection.cpp \ + gqb/gqbColumn.cpp \ + gqb/gqbController.cpp \ + gqb/gqbDatabase.cpp \ + gqb/gqbGraphSimple.cpp \ + gqb/gqbGridOrderTable.cpp \ + gqb/gqbGridProjTable.cpp \ + gqb/gqbGridRestTable.cpp \ + gqb/gqbGridJoinTable.cpp \ + gqb/gqbModel.cpp \ + gqb/gqbObject.cpp \ + gqb/gqbObjectCollection.cpp \ + gqb/gqbQueryObjs.cpp \ + gqb/gqbSchema.cpp \ + gqb/gqbTable.cpp \ + gqb/gqbViewPanels.cpp \ + gqb/gqbView.cpp + +EXTRA_DIST += \ + gqb/module.mk + + diff --git a/hotdraw/connectors/hdChopBoxConnector.cpp b/hotdraw/connectors/hdChopBoxConnector.cpp new file mode 100644 index 0000000..0611216 --- /dev/null +++ b/hotdraw/connectors/hdChopBoxConnector.cpp @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChopBoxConnector.cpp - Connector for center of figure to line crossing one limit line of rect +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdChopBoxConnector.h" +#include "hotdraw/utilities/hdGeometry.h" + +hdChopBoxConnector::hdChopBoxConnector(hdIFigure *owner): + hdIConnector(owner) +{ +} + +hdChopBoxConnector::~hdChopBoxConnector() +{ +} + + +hdPoint hdChopBoxConnector::chop(int posIdx, hdIFigure *target, hdPoint point) +{ + if(target && target->containsPoint(posIdx, point.x, point.y)) + { + point = target->displayBox().center(posIdx); + return point; + } + else if(!target) + { + point = hdPoint(0, 0); + return point; + } + + hdGeometry g; + + rect = getDisplayBox().gethdRect(posIdx); //hack to avoid linux bug + double angle = g.angleFromPoint(rect, point); + point = g.edgePointFromAngle(rect, angle); + return point; +} + +hdPoint hdChopBoxConnector::findStart(int posIdx, hdLineConnection *connFigure) +{ + if(!connFigure) + { + point = getDisplayBox().center(posIdx); + return point; + } + + if(connFigure->pointCount(posIdx) < 2) + { + point = getDisplayBox().center(posIdx); + return point; + } + + hdIFigure *start = connFigure->getStartConnector()->getOwner(); + point = connFigure->pointAt(posIdx, 1); + point = chop(posIdx, start, point); + return point; +} + +hdPoint hdChopBoxConnector::findEnd(int posIdx, hdLineConnection *connFigure) +{ + if(!connFigure) + { + return getDisplayBox().center(posIdx); + } + hdIFigure *end = connFigure->getEndConnector()->getOwner(); + point = connFigure->pointAt(posIdx, connFigure->pointCount(posIdx) - 2); + point = chop(posIdx, end, point); + return point; +} diff --git a/hotdraw/connectors/hdIConnector.cpp b/hotdraw/connectors/hdIConnector.cpp new file mode 100644 index 0000000..e6cc29a --- /dev/null +++ b/hotdraw/connectors/hdIConnector.cpp @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnector.cpp - Base class for all connectors +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdIConnector.h" + +class hdLineConnection; +class hdIFigure; + +hdIConnector::hdIConnector(hdIFigure *owner): + hdObject() +{ + figureOwner = owner; +} + +hdIConnector::~hdIConnector() +{ +} + +hdIFigure *hdIConnector::getOwner() +{ + return figureOwner; + +} + +void hdIConnector::setOwner(hdIFigure *owner) +{ + figureOwner = owner; +} + +void hdIConnector::draw(wxBufferedDC &context) +{ +} + +hdMultiPosRect &hdIConnector::getDisplayBox() +{ + return figureOwner->displayBox(); +} + +bool hdIConnector::containsPoint(int posIdx, int x, int y) +{ + return figureOwner->containsPoint(posIdx, x, y); +} + +hdPoint hdIConnector::findStart(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox().center(posIdx); +} + +hdPoint hdIConnector::findEnd(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox().center(posIdx); +} diff --git a/hotdraw/connectors/hdLocatorConnector.cpp b/hotdraw/connectors/hdLocatorConnector.cpp new file mode 100644 index 0000000..9a2325f --- /dev/null +++ b/hotdraw/connectors/hdLocatorConnector.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorConnector.cpp - class that puts connects at locator position +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdLocatorConnector.h" +hdLocatorConnector::hdLocatorConnector(hdIFigure *owner, hdILocator *locator): + hdIConnector(owner) +{ + figureOwner = owner; + figureLocator = locator; + size = 8; +} + +hdLocatorConnector::~hdLocatorConnector() +{ +} + +hdPoint hdLocatorConnector::locate(int posIdx) +{ + return figureLocator->locate(posIdx, getOwner()); +} + +void hdLocatorConnector::draw(wxBufferedDC &context) +{ +} + +hdRect &hdLocatorConnector::getDisplayBox(int posIdx) +{ + hdPoint p = figureLocator->locate(posIdx, getOwner()); + displayBox = hdRect(p.x - (size / 2), p.y - (size / 2), size, size); + return displayBox; +} + +bool hdLocatorConnector::containsPoint(int posIdx, int x, int y) +{ + return getDisplayBox(posIdx).Contains(x, y); +} + +hdPoint hdLocatorConnector::findStart(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox(posIdx).center(); +} + +hdPoint hdLocatorConnector::findEnd(int posIdx, hdLineConnection *connection) +{ + return getDisplayBox(posIdx).center(); +} diff --git a/hotdraw/connectors/hdStickyRectangleConnector.cpp b/hotdraw/connectors/hdStickyRectangleConnector.cpp new file mode 100644 index 0000000..ab7072c --- /dev/null +++ b/hotdraw/connectors/hdStickyRectangleConnector.cpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdStickyRectangleConnector.cpp - A StickyRectangleConnector locates connection points by choping +// the connection between the centers of the two figures at the display box. The location +// of the connection point is computed once, when the user connects the figure. +// Moving the figure around will not change the location. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/connectors/hdStickyRectangleConnector.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/connectors/hdChopBoxConnector.h" +#include "hotdraw/utilities/hdGeometry.h" + +class hdLineConnection; +class hdIFigure; + +hdStickyRectangleConnector::hdStickyRectangleConnector(hdIFigure *owner, hdPoint p): + hdChopBoxConnector(owner) +{ + hdGeometry g; + updateAnchor(0, p); +} + +hdStickyRectangleConnector::~hdStickyRectangleConnector() +{ +} + +void hdStickyRectangleConnector::setAngle(float newAngle) +{ + angle = newAngle; +} + +void hdStickyRectangleConnector::updateAnchor(int posIdx, hdPoint p) +{ + hdGeometry g; + + hdRect rect = getDisplayBox().gethdRect(posIdx); //hack to avoid linux bug + angle = g.angleFromPoint(rect, p); +} + +hdPoint hdStickyRectangleConnector::getAnchor(int posIdx) +{ + hdGeometry g; + + hdRect rect = getDisplayBox().gethdRect(posIdx); //hack to avoid linux bug + return g.edgePointFromAngle(rect, angle); +} + +hdPoint hdStickyRectangleConnector::chop(int posIdx, hdIFigure *target, hdPoint point) +{ + + hdGeometry g; + + hdRect rect = target->displayBox().gethdRect(posIdx); //hack to avoid linux bug + point = g.edgePointFromAngle(rect, angle); + return point; +} + +void hdStickyRectangleConnector::draw(wxBufferedDC &context) +{ +} diff --git a/hotdraw/connectors/module.mk b/hotdraw/connectors/module.mk new file mode 100644 index 0000000..245f019 --- /dev/null +++ b/hotdraw/connectors/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/connectors/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/connectors/hdChopBoxConnector.cpp \ + hotdraw/connectors/hdIConnector.cpp \ + hotdraw/connectors/hdLocatorConnector.cpp \ + hotdraw/connectors/hdStickyRectangleConnector.cpp + +EXTRA_DIST += \ + hotdraw/connectors/module.mk diff --git a/hotdraw/figures/defaultAttributes/hdFillAttribute.cpp b/hotdraw/figures/defaultAttributes/hdFillAttribute.cpp new file mode 100644 index 0000000..1990cee --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdFillAttribute.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFillAttribute.cpp - Default attribute for fill color of figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFillAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +hdFillAttribute::hdFillAttribute(): + hdAttribute() +{ + fillAttributes = wxBrush(*wxWHITE); +} + +void hdFillAttribute::apply(wxBufferedDC &context) +{ + context.SetBrush(fillAttributes); +} + +void hdFillAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + //create brush dialog + wxColour color = wxGetColourFromUser(owner, fillAttributes.GetColour(), wxT("Select a color for fill color...")); + fillAttributes = wxBrush(color); +} + +wxBrush &hdFillAttribute::brush() +{ + return fillAttributes; +} diff --git a/hotdraw/figures/defaultAttributes/hdFontAttribute.cpp b/hotdraw/figures/defaultAttributes/hdFontAttribute.cpp new file mode 100644 index 0000000..d8395df --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdFontAttribute.cpp @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.cpp - Default attribute for attributes of fonts +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +wxFont *hdFontAttribute::defaultFont = NULL; + +hdFontAttribute::hdFontAttribute(): + hdAttribute() +{ + fontAttributes = *defaultFont; +} + +void hdFontAttribute::apply(wxBufferedDC &context) +{ + context.SetFont(fontAttributes); +} + +void hdFontAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + fontAttributes = wxGetFontFromUser(owner, fontAttributes, wxT("Select a font...")); +} + +wxFont &hdFontAttribute::font() +{ + return fontAttributes; +} + +void hdFontAttribute::InitFont() +{ + defaultFont = new wxFont(10, wxSWISS, wxNORMAL, wxNORMAL); +} diff --git a/hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp b/hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp new file mode 100644 index 0000000..2a5be91 --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.cpp - Default attribute for color of fonts +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFontColorAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +hdFontColorAttribute::hdFontColorAttribute(): + hdAttribute() +{ + fontColor = wxColour(*wxBLACK); +} + +void hdFontColorAttribute::apply(wxBufferedDC &context) +{ + context.SetTextForeground(fontColor); +} + +void hdFontColorAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + fontColor = wxGetColourFromUser(owner, fontColor, wxT("Select a color for font...")); +} diff --git a/hotdraw/figures/defaultAttributes/hdLineAttribute.cpp b/hotdraw/figures/defaultAttributes/hdLineAttribute.cpp new file mode 100644 index 0000000..62e014d --- /dev/null +++ b/hotdraw/figures/defaultAttributes/hdLineAttribute.cpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineAttribute.cpp - Default Attribute for lines style, color an others at figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdLineAttribute.h" +#include "hotdraw/figures/hdAttribute.h" + +hdLineAttribute::hdLineAttribute(): + hdAttribute() +{ + penAttributes = *wxBLACK_PEN; +} + +void hdLineAttribute::apply(wxBufferedDC &context) +{ + context.SetPen(penAttributes); +} + +void hdLineAttribute::callDefaultChangeDialog(wxWindow *owner) +{ + //create line dialog +} + +wxPen &hdLineAttribute::pen() +{ + return penAttributes; +} diff --git a/hotdraw/figures/defaultAttributes/module.mk b/hotdraw/figures/defaultAttributes/module.mk new file mode 100644 index 0000000..23b81f6 --- /dev/null +++ b/hotdraw/figures/defaultAttributes/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/figures/defaultAttributes/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/figures/defaultAttributes/hdFillAttribute.cpp \ + hotdraw/figures/defaultAttributes/hdFontAttribute.cpp \ + hotdraw/figures/defaultAttributes/hdFontColorAttribute.cpp \ + hotdraw/figures/defaultAttributes/hdLineAttribute.cpp + +EXTRA_DIST += \ + hotdraw/figures/defaultAttributes/module.mk diff --git a/hotdraw/figures/hdAbstractFigure.cpp b/hotdraw/figures/hdAbstractFigure.cpp new file mode 100644 index 0000000..6d35066 --- /dev/null +++ b/hotdraw/figures/hdAbstractFigure.cpp @@ -0,0 +1,130 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.cpp - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAbstractFigure.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdDrawingView.h" + +hdAbstractFigure::hdAbstractFigure() +{ + spaceForMovement.SetHeight(0); + spaceForMovement.SetWidth(0); +} + +hdAbstractFigure::~hdAbstractFigure() +{ +} + +bool hdAbstractFigure::canConnect () +{ + return true; +} + +bool hdAbstractFigure::includes(hdIFigure *figure) +{ + return (this == figure); +} + +void hdAbstractFigure::draw(wxBufferedDC &context, hdDrawingView *view) +{ + //Hack to Allow creations of limits for figures movements, but what to do should be defined at derivated classes + spaceForMovement = view->canvasSize; + hdIFigure::draw(context, view); + basicDraw(context, view); +} + +void hdAbstractFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + context.SetPen(*wxGREEN_PEN); + context.SetBrush(wxBrush (wxColour(208, 208, 208), wxSOLID)); + context.DrawRectangle(copy); +} + +void hdAbstractFigure::drawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdIFigure::drawSelected(context, view); + basicDrawSelected(context, view); +} + +void hdAbstractFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + context.SetPen(*wxRED_PEN); + context.SetBrush(wxBrush (wxColour(133, 133, 133), wxSOLID)); + context.DrawRectangle(copy); +} + + +hdITool *hdAbstractFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return defaultTool; +} + +void hdAbstractFigure::moveBy(int posIdx, int x, int y) +{ + willChange(); + basicMoveBy(posIdx, x, y); + changed(posIdx); +} + +void hdAbstractFigure::basicMoveBy(int posIdx, int x, int y) +{ + basicDisplayBox.x[posIdx] += x; + basicDisplayBox.y[posIdx] += y; +} + + +void hdAbstractFigure::moveTo(int posIdx, int x, int y) +{ + basicDisplayBox.x[posIdx] = x; + basicDisplayBox.y[posIdx] = y; +} + +void hdAbstractFigure::willChange() +{ + invalidate(); +} + +void hdAbstractFigure::changed(int posIdx) +{ + invalidate(); + onFigureChanged(posIdx, this); +} + +void hdAbstractFigure::invalidate() +{ + +} + +bool hdAbstractFigure::containsPoint(int posIdx, int x, int y) +{ + return basicDisplayBox.Contains(posIdx, x, y); +} + +void hdAbstractFigure::onFigureChanged(int posIdx, hdIFigure *figure) +{ + //go to figure procedure to alert observers of changes on this figure + hdIFigure::onFigureChanged(posIdx, figure); +} diff --git a/hotdraw/figures/hdAbstractMenuFigure.cpp b/hotdraw/figures/hdAbstractMenuFigure.cpp new file mode 100644 index 0000000..5964d63 --- /dev/null +++ b/hotdraw/figures/hdAbstractMenuFigure.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractMenuFigure.cpp - Base class for figures that show a menu with right click +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAbstractMenuFigure.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/tools/hdMenuTool.h" + +hdAbstractMenuFigure::hdAbstractMenuFigure() +{ +} + +hdAbstractMenuFigure::~hdAbstractMenuFigure() +{ +} + + +hdITool *hdAbstractMenuFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new hdMenuTool(view, this, defaultTool); +} + +void hdAbstractMenuFigure::enablePopUp() +{ + showMenu = true; +} + +void hdAbstractMenuFigure::disablePopUp() +{ + showMenu = false; +} + +bool hdAbstractMenuFigure::menuEnabled() +{ + return showMenu; +} + +void hdAbstractMenuFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + //Action on popup goes here + //strings[event.GetId()] +} diff --git a/hotdraw/figures/hdAttribute.cpp b/hotdraw/figures/hdAttribute.cpp new file mode 100644 index 0000000..e2334eb --- /dev/null +++ b/hotdraw/figures/hdAttribute.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAttributeFigure.cpp - Base class for all figure attributes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAttribute.h" + +hdAttribute::hdAttribute(): + hdObject() +{ +} + +void hdAttribute::apply(wxBufferedDC &context) +{ +} + +void hdAttribute::callDefaultChangeDialog(wxWindow *owner) +{ +} + diff --git a/hotdraw/figures/hdAttributeFigure.cpp b/hotdraw/figures/hdAttributeFigure.cpp new file mode 100644 index 0000000..ea8e448 --- /dev/null +++ b/hotdraw/figures/hdAttributeFigure.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAttributeFigure.cpp - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdAttributeFigure.h" +#include "hotdraw/figures/hdAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFillAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontColorAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdLineAttribute.h" + +hdAttributeFigure::hdAttributeFigure() +{ + initializeDefaultAttributes(); +} + +hdAttributeFigure::~hdAttributeFigure() +{ + delete fillAttribute; + delete lineAttribute; + delete fontAttribute; + delete fontColorAttribute; + delete fillSelAttribute; + delete lineSelAttribute; + delete fontSelAttribute; + delete fontSelColorAttribute; +} + +void hdAttributeFigure::draw(wxBufferedDC &context, hdDrawingView *view) +{ + //find a way to allow user to use custom attributes without affecting performance + fillAttribute->apply(context); + lineAttribute->apply(context); + fontAttribute->apply(context); + fontColorAttribute->apply(context); + + hdAbstractFigure::draw(context, view); +} + +void hdAttributeFigure::drawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + //find a way to allow user to use custom attributes without affecting performance + fillSelAttribute->apply(context); + lineSelAttribute->apply(context); + fontSelAttribute->apply(context); + fontSelColorAttribute->apply(context); + + hdAbstractFigure::drawSelected(context, view); +} + +void hdAttributeFigure::initializeDefaultAttributes() +{ + + fontAttribute = new hdFontAttribute(); + fontColorAttribute = new hdFontColorAttribute(); + fillAttribute = new hdFillAttribute(); + lineAttribute = new hdLineAttribute(); + + fontSelAttribute = new hdFontAttribute(); + fontSelColorAttribute = new hdFontColorAttribute(); + fillSelAttribute = new hdFillAttribute(); + lineSelAttribute = new hdLineAttribute(); + +} + +void hdAttributeFigure::reapplyAttributes(wxBufferedDC &context, hdDrawingView *view) +{ + fillAttribute->apply(context); + lineAttribute->apply(context); + fontAttribute->apply(context); + fontColorAttribute->apply(context); +} + +void hdAttributeFigure::reapplySelAttributes(wxBufferedDC &context, hdDrawingView *view) +{ + fillSelAttribute->apply(context); + lineSelAttribute->apply(context); + fontSelAttribute->apply(context); + fontSelColorAttribute->apply(context); +} diff --git a/hotdraw/figures/hdBitmapFigure.cpp b/hotdraw/figures/hdBitmapFigure.cpp new file mode 100644 index 0000000..6d6b550 --- /dev/null +++ b/hotdraw/figures/hdBitmapFigure.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.cpp - Figure that draw a bitmap +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdBitmapFigure.h" +#include "hotdraw/main/hdDrawingView.h" + + +hdBitmapFigure::hdBitmapFigure(wxBitmap image) +{ + imageToDraw = image; + this->getBasicDisplayBox().width = imageToDraw.GetWidth(); + this->getBasicDisplayBox().height = imageToDraw.GetHeight(); +} + +hdBitmapFigure::~hdBitmapFigure() +{ +} + +void hdBitmapFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawBitmap(imageToDraw, copy.GetPosition(), true); +} + +void hdBitmapFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +void hdBitmapFigure::changeBitmap(wxBitmap image) +{ + imageToDraw = image; + //Index doesn't care because width and height are shared in a MultiPosRect + this->getBasicDisplayBox().width = imageToDraw.GetWidth(); + this->getBasicDisplayBox().height = imageToDraw.GetHeight(); +} + +int hdBitmapFigure::getWidth() +{ + return imageToDraw.GetWidth(); +} + +int hdBitmapFigure::getHeight() +{ + return imageToDraw.GetHeight(); +} diff --git a/hotdraw/figures/hdCompositeFigure.cpp b/hotdraw/figures/hdCompositeFigure.cpp new file mode 100644 index 0000000..5e95cf2 --- /dev/null +++ b/hotdraw/figures/hdCompositeFigure.cpp @@ -0,0 +1,271 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.cpp - Base class for all figures composite with figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdCompositeFigure.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/tools/hdCompositeFigureTool.h" + +hdCompositeFigure::hdCompositeFigure() +{ + figureFigures = new hdCollection(new hdArrayCollection()); + figureHandles = new hdCollection(new hdArrayCollection()); +} + +void hdCompositeFigure::AddPosForNewDiagram() +{ + //Add position for new displaybox at new diagram + hdAttributeFigure::AddPosForNewDiagram(); + //Add position to each figure inside this composite figure + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + f->AddPosForNewDiagram(); + } + delete iterator; +} + +void hdCompositeFigure::RemovePosOfDiagram(int posIdx) +{ + hdAttributeFigure::RemovePosOfDiagram(posIdx); + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + f->RemovePosOfDiagram(posIdx); + } + delete iterator; +} + +hdCompositeFigure::~hdCompositeFigure() +{ + hdIHandle *tmpH; + //Handles should be delete by their owner (figure) + while(figureHandles->count() > 0) + { + tmpH = (hdIHandle *) figureHandles->getItemAt(0); + figureHandles->removeItemAt(0); + delete tmpH; + } + if(figureHandles) + delete figureHandles; + + hdIFigure *tmp; + while(figureFigures->count() > 0) + { + tmp = (hdIFigure *) figureFigures->getItemAt(0); + figureFigures->removeItemAt(0); + delete tmp; + } + if(figureFigures) + delete figureFigures; +} + +void hdCompositeFigure::basicMoveBy(int posIdx, int x, int y) +{ + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + f->moveBy(posIdx, x, y); + } + + basicDisplayBox.x[posIdx] += x; + basicDisplayBox.y[posIdx] += y; + delete iterator; +} + +bool hdCompositeFigure::containsPoint(int posIdx, int x, int y) +{ + bool out = false; + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + if(f->containsPoint(posIdx, x, y)) + { + out = true; //avoid memory leak + } + } + delete iterator; + return out; +} + +hdIteratorBase *hdCompositeFigure::figuresEnumerator() +{ + return figureFigures->createIterator(); +} + +hdIteratorBase *hdCompositeFigure::figuresInverseEnumerator() +{ + return figureFigures->createDownIterator(); +} + +//Ignore figures at negative positions +hdMultiPosRect &hdCompositeFigure::getBasicDisplayBox() +{ + basicDisplayBox.SetSize(wxSize(0, 0)); + + int posIdx; + hdIteratorBase *iterator = figuresEnumerator(); + for(posIdx = 0; posIdx < basicDisplayBox.CountPositions(); posIdx++) + { + basicDisplayBox.SetPosition(posIdx, wxPoint(0, 0)); + bool firstFigure = true; + + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + if(firstFigure) + { + basicDisplayBox.SetPosition(posIdx, f->displayBox().GetPosition(posIdx)); + basicDisplayBox.SetSize( f->displayBox().GetSize()); + if(f->displayBox().GetPosition(posIdx).x > 0 && f->displayBox().GetPosition(posIdx).y > 0) + firstFigure = false; + } + else + { + if(f->displayBox().GetPosition(posIdx).x > 0 && f->displayBox().GetPosition(posIdx).y > 0) + basicDisplayBox.add(posIdx, f->displayBox().gethdRect(posIdx) ); + } + } + iterator->ResetIterator(); + } + delete iterator; + return basicDisplayBox; + +} + +hdCollection *hdCompositeFigure::handlesEnumerator() +{ + return figureHandles; +} + +void hdCompositeFigure::add(hdIFigure *figure) +{ + if(includes(figure)) + return; + + //Add figure + figureFigures->addItem(figure); + //Check figure available positions for diagrams. + int i, start; + start = figure->displayBox().CountPositions(); + for(i = start; i < basicDisplayBox.CountPositions(); i++) + { + figure->AddPosForNewDiagram(); + } + //Add figure handles + hdIteratorBase *handlesIterator = figure->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + hdIHandle *h = (hdIHandle *) handlesIterator->Next(); + figureHandles->addItem(h); + } + delete handlesIterator; +} + +void hdCompositeFigure::remove(hdIFigure *figure) +{ + if(!includes(figure)) + return; + + //Remove figure handles + hdIteratorBase *handlesIterator = figure->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + hdIHandle *h = (hdIHandle *) handlesIterator->Next(); + figureHandles->removeItem(h); + } + delete handlesIterator; + //Remove figure + figureFigures->removeItem(figure); +} + +bool hdCompositeFigure::includes(hdIFigure *figure) +{ + if(hdAbstractFigure::includes(figure)) + return true; + + bool out = false; + + hdIteratorBase *iterator = figuresEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *f = (hdIFigure *) iterator->Next(); + if(f->includes(figure)) + out = true; + } + delete iterator; + return out; +} + +void hdCompositeFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdIteratorBase *iterator = figuresEnumerator(); + hdIFigure *f = NULL; + while(iterator->HasNext()) + { + f = (hdIFigure *) iterator->Next(); + f->draw(context, view); + } + delete iterator; +} + +void hdCompositeFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdIteratorBase *iterator = figuresEnumerator(); + hdIFigure *f = NULL; + while(iterator->HasNext()) + { + f = (hdIFigure *) iterator->Next(); + f->drawSelected(context, view); + } + delete iterator; +} + +hdIFigure *hdCompositeFigure::findFigure(int posIdx, int x, int y) +{ + hdIFigure *tmp = NULL, *out = NULL; + hdIteratorBase *iterator = figuresInverseEnumerator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->containsPoint(posIdx, x, y)) + { + out = tmp; + break; + } + } + + delete iterator; + + return out; +} + +hdITool *hdCompositeFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new hdCompositeFigureTool(view, this, defaultTool); +} + +hdIFigure *hdCompositeFigure::getFigureAt(int indexOfCollection) +{ + return (hdIFigure *) figureFigures->getItemAt(indexOfCollection); +} diff --git a/hotdraw/figures/hdIConnectionFigure.cpp b/hotdraw/figures/hdIConnectionFigure.cpp new file mode 100644 index 0000000..eaa0bf5 --- /dev/null +++ b/hotdraw/figures/hdIConnectionFigure.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnectionFigure.cpp - Base class for all connection figures +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdIConnectionFigure.h" + +// All functions abstract prototypes inside hdIConnectionFigure.h +// this is just a base class diff --git a/hotdraw/figures/hdIFigure.cpp b/hotdraw/figures/hdIFigure.cpp new file mode 100644 index 0000000..6b98dbc --- /dev/null +++ b/hotdraw/figures/hdIFigure.cpp @@ -0,0 +1,175 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIFigure.cpp - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/connectors/hdChopBoxConnector.h" + +hdIFigure::hdIFigure() +{ + handles = new hdCollection(new hdArrayCollection()); + observers = new hdCollection(new hdArrayCollection()); + unsigned int i; + for(i = 0; i < MAXPOS; i++) + { + selected.Add(false); + } + connector = NULL; + basicDisplayBox.SetSize(wxSize(0, 0)); +} + +hdIFigure::~hdIFigure() +{ + if(connector) + delete connector; + if(handles) + delete handles; + if(observers) + { + observers->removeAll(); + delete observers; + } +} + +void hdIFigure::AddPosForNewDiagram() +{ + basicDisplayBox.addNewXYPosition(); + selected.Add(false); +} + +void hdIFigure::RemovePosOfDiagram(int posIdx) +{ + basicDisplayBox.removeXYPosition(posIdx); +} + +hdMultiPosRect &hdIFigure::displayBox() +{ + return getBasicDisplayBox(); +} + +hdMultiPosRect &hdIFigure::getBasicDisplayBox() +{ + return basicDisplayBox; +} + +void hdIFigure::draw (wxBufferedDC &context, hdDrawingView *view) +{ + +} + +void hdIFigure::drawSelected (wxBufferedDC &context, hdDrawingView *view) +{ + +} + +hdCollection *hdIFigure::handlesEnumerator() +{ + return handles; +} + +void hdIFigure::addHandle (hdIHandle *handle) +{ + if(!handles) + { + handles = new hdCollection(new hdArrayCollection()); + } + handles->addItem(handle); +} + +void hdIFigure::removeHandle (hdIHandle *handle) +{ + if(handles) + { + handles->removeItem(handle); + } +} + +hdITool *hdIFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return defaultTool; +} + +bool hdIFigure::isSelected(int posIdx) +{ + return selected[posIdx]; +} + +void hdIFigure::setSelected(int posIdx, bool value) +{ + selected[posIdx] = value; +} + +hdIConnector *hdIFigure::connectorAt (int posIdx, int x, int y) +{ + if(!connector) + connector = new hdChopBoxConnector(this); + return connector; +} + +bool hdIFigure::includes(hdIFigure *figure) +{ + return (this == figure); +} + +void hdIFigure::onFigureChanged(int posIdx, hdIFigure *figure) +{ + + hdIteratorBase *iterator = observers->createIterator(); + while(iterator->HasNext()) + { + hdIFigure *o = (hdIFigure *) iterator->Next(); + o->onFigureChanged(posIdx, this); + } + delete iterator; +} + +void hdIFigure::addObserver(hdIFigure *observer) +{ + if(!observers) + { + observers = new hdCollection(new hdArrayCollection()); + } + observers->addItem(observer); +} + +void hdIFigure::removeObserver(hdIFigure *observer) +{ + if(observers) + { + observers->removeItem(observer); + } +} + +hdIteratorBase *hdIFigure::observersEnumerator() +{ + return observers->createIterator(); +} + +void hdIFigure::setKindId(int hiddenId) +{ + kindHiddenId = hiddenId; +} + +//Hack because is kindof in not powerful as it should be +int hdIFigure::getKindId() +{ + return kindHiddenId; +} diff --git a/hotdraw/figures/hdLineConnection.cpp b/hotdraw/figures/hdLineConnection.cpp new file mode 100644 index 0000000..4197f82 --- /dev/null +++ b/hotdraw/figures/hdLineConnection.cpp @@ -0,0 +1,293 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnection.cpp - Base class for line connection figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/handles/hdChangeConnectionStartHandle.h" +#include "hotdraw/handles/hdChangeConnectionEndHandle.h" +#include "hotdraw/handles/hdLineConnectionHandle.h" +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/utilities/hdArrayCollection.h" + +hdLineConnection::hdLineConnection(): + hdPolyLineFigure() +{ + startConnector = NULL; + endConnector = NULL; + changeConnStartHandle = NULL; + changeConnEndHandle = NULL; +} + +hdLineConnection::hdLineConnection(int posIdx, hdIFigure *figure1, hdIFigure *figure2): + hdPolyLineFigure() +{ + //Check figure available positions for diagrams, add at least needed to allow initialization of the class + int i, start; + start = basicDisplayBox.CountPositions(); + for(i = start; i < (posIdx + 1); i++) + { + AddPosForNewDiagram(); + } + + startConnector = NULL; + endConnector = NULL; + + if(figure1) + { + connectStart(figure1->connectorAt(posIdx, 0, 0)); + } + + if(figure2) + { + connectEnd(figure2->connectorAt(posIdx, 0, 0)); + } +} + +hdLineConnection::~hdLineConnection() +{ +} + +hdIConnector *hdLineConnection::getStartConnector() +{ + return startConnector; +} + +hdIConnector *hdLineConnection::getEndConnector() +{ + return endConnector; +} + +void hdLineConnection::setStartConnector(hdIConnector *connector) +{ + startConnector = connector; +} + +void hdLineConnection::setEndConnector(hdIConnector *connector) +{ + endConnector = connector; +} + +void hdLineConnection::connectStart(hdIConnector *start, hdDrawingView *view) +{ + if(startConnector == start) + { + return; + } + + disconnectStart(); + startConnector = start; + connectFigure(startConnector); +} + +void hdLineConnection::connectEnd(hdIConnector *end, hdDrawingView *view) +{ + if(endConnector == end) + { + return; + } + + disconnectEnd(); + endConnector = end; + connectFigure(endConnector); +} + +void hdLineConnection::disconnectStart(hdDrawingView *view) +{ + disconnectFigure (startConnector); + startConnector = NULL; +} + +void hdLineConnection::disconnectEnd(hdDrawingView *view) +{ + disconnectFigure (endConnector); + endConnector = NULL; +} + +bool hdLineConnection::canConnectStart(hdIFigure *figure) +{ + return true; +} + +bool hdLineConnection::canConnectEnd(hdIFigure *figure) +{ + return true; +} + +hdIFigure *hdLineConnection::getStartFigure() +{ + if(startConnector) + { + return startConnector->getOwner(); + } + + return NULL; +} + +hdIFigure *hdLineConnection::getEndFigure() +{ + if(endConnector) + { + return endConnector->getOwner(); + } + + return NULL; +} + +void hdLineConnection::updateConnection(int posIdx) +{ + if(startConnector) + { + setStartPoint(posIdx, startConnector->findStart(posIdx, this)); + } + if(endConnector) + { + setEndPoint(posIdx, endConnector->findEnd(posIdx, this)); + } +} + +hdIHandle *hdLineConnection::getStartHandle() +{ + if(!changeConnStartHandle) + { + changeConnStartHandle = new hdChangeConnectionStartHandle(this); + } + return changeConnStartHandle; +} + +hdIHandle *hdLineConnection::getEndHandle() +{ + if(!changeConnEndHandle) + { + changeConnEndHandle = new hdChangeConnectionEndHandle(this); + } + return changeConnEndHandle; +} + +void hdLineConnection::basicMoveBy(int posIdx, int x, int y) +{ + hdPolyLineFigure::basicMoveBy(posIdx, x, y); + updateConnection(posIdx); +} + +bool hdLineConnection::canConnect() +{ + return false; +} + +void hdLineConnection::setPointAt (int posIdx, int index, int x, int y) +{ + hdPolyLineFigure::setPointAt(posIdx, index, x, y); + updateConnection(posIdx); +} + +hdCollection *hdLineConnection::handlesEnumerator() +{ + return handles; +} + + +void hdLineConnection::connectFigure (hdIConnector *connector) +{ + if(connector) + { + connector->getOwner()->addObserver(this); + } +} + +void hdLineConnection::disconnectFigure (hdIConnector *connector) +{ + if(connector) + { + connector->getOwner()->removeObserver(this); + } +} + +void hdLineConnection::onFigureChanged(int posIdx, hdIFigure *figure) +{ + updateConnection(posIdx); +} + +void hdLineConnection::addPoint (int posIdx, int x, int y) +{ + willChange(); + points[posIdx]->addItem((hdObject *) new hdPoint(x, y) ); + //Update handles + if(points[posIdx]->count() == 1) + { + //first point add start handle + if(handles->count() == 0) + handles->addItem(getStartHandle()); + } + else if(points[posIdx]->count() == 2) + { + //second point add end handle + if(handles->count() == 1) + handles->addItem(getEndHandle()); + } + else if(points[posIdx]->count() > 2) + { + //Locate maximum index if there is need for one new handle then added it + if( getMaximunIndex() > handles->count() ) + { + //third and above point, add a polylinehandle before end handle + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(0), 0), handles->count() - 1); + } + } + updateHandlesIndexes(); + changed(posIdx); +} + +void hdLineConnection::insertPointAt (int posIdx, int index, int x, int y) +{ + willChange(); + points[posIdx]->insertAtIndex((hdObject *) new hdPoint(x, y), index); + //Update handles + //Is there need of a new handle if is first point + if(index == 0 && handles->count() == 0 ) + { + //add a new handle "normal" for a point in next position 0,1 in 1... in 0 startHandle is not moved + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), 1); + } + else if(index == (points[posIdx]->count() - 1) && handles->count() < getMaximunIndex() ) //last point + { + //add a new handle "normal" for a point in before last item position + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), (points[posIdx]->count() - 1)); + } + else if(handles->count() < getMaximunIndex()) + { + //add handle at index + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), index); + } + updateHandlesIndexes(); + changed(posIdx); +} + +//Update points between start and end, because start and end don't have index (is other kind of handle) +void hdLineConnection::updateHandlesIndexes() +{ + hdPolyLineHandle *h = NULL; + + //Get maximun point position in a collection of points + int maxPosition = getMaximunIndex(); + + //Update Handles indexes + for(int i = 1; i < maxPosition - 1; i++) + { + h = (hdPolyLineHandle *) handles->getItemAt(i); + h->setIndex(i); + } +} diff --git a/hotdraw/figures/hdLineTerminal.cpp b/hotdraw/figures/hdLineTerminal.cpp new file mode 100644 index 0000000..689892a --- /dev/null +++ b/hotdraw/figures/hdLineTerminal.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineTerminal.cpp - Base class for line terminal figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/main/hdDrawingView.h" + +hdLineTerminal::hdLineTerminal() +{ + middle = hdPoint(0, 0); + terminalLinePen = wxPen(wxString(wxT("BLACK")), 1, wxSOLID); +} + +hdLineTerminal::~hdLineTerminal() +{ +} + +void hdLineTerminal::setLinePen(wxPen pen) +{ + terminalLinePen = pen; +} + +hdPoint &hdLineTerminal::draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view) +{ + hdGeometry g; + context.SetPen(terminalLinePen); + + hdPoint copyA = hdPoint (a); + view->CalcScrolledPosition(copyA.x, copyA.y, ©A.x, ©A.y); + hdPoint copyB = hdPoint (b); + view->CalcScrolledPosition(copyB.x, copyB.y, ©B.x, ©B.y); + context.DrawLine(copyA, copyB); + + context.SetPen(wxPen(wxString(wxT("BLACK")), 1, wxSOLID)); + int x = copyA.x + g.ddabs(copyA.x - copyB.x); + int y = copyA.y + g.ddabs(copyA.y - copyB.y); + middle = hdPoint(x, y); + + context.DrawRectangle(wxRect(copyA.x, copyA.y, 5, 5)); + context.DrawCircle(copyA, 10); + return middle; +} diff --git a/hotdraw/figures/hdPolyLineFigure.cpp b/hotdraw/figures/hdPolyLineFigure.cpp new file mode 100644 index 0000000..079644d --- /dev/null +++ b/hotdraw/figures/hdPolyLineFigure.cpp @@ -0,0 +1,446 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigure.cpp - A simple line figure that can be split on several lines joined by flexibility points +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/handles/hdPolyLineHandle.h" +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/tools/hdPolyLineFigureTool.h" +#include "hotdraw/tools/hdMenuTool.h" + +hdPolyLineFigure::hdPolyLineFigure() +{ + unsigned int i; + + for(i = 0; i < MAXPOS ; i++) + { + points.Add(new hdArrayCollection()); + } + + startTerminal = NULL; + endTerminal = NULL; + handlesChanged = false; + startPoint = hdPoint(0, 0); + endPoint = hdPoint(0, 0); + pointAtPos = hdPoint(0, 0); + linePen = wxPen(wxString(wxT("BLACK")), 1, wxSOLID); +} + +hdPolyLineFigure::~hdPolyLineFigure() +{ + hdPoint *tmp; //Hack: If just delete points collection an error is raised. + hdArrayCollection *tmpCollection; + + unsigned int i; + for(i = 0; i < points.Count(); i++) + { + while(points[i]->count() > 0) + { + tmp = (hdPoint *) points[i]->getItemAt(0); + points[i]->removeItemAt(0); + delete tmp; + } + if(points[i]) + { + tmpCollection = points[i]; + points.RemoveAt(i); + delete tmpCollection; + } + } + if(startTerminal) + delete startTerminal; + if(endTerminal) + delete endTerminal; +} + +void hdPolyLineFigure::AddPosForNewDiagram() +{ + //Add position for new displaybox at new diagram + hdIFigure::AddPosForNewDiagram(); + //Add new array of point for polylinefigure + points.Add(new hdArrayCollection()); +} + +void hdPolyLineFigure::RemovePosOfDiagram(int posIdx) +{ + hdIFigure::RemovePosOfDiagram(posIdx); + + //Hack: If just delete points collection an error is raised. + hdPoint *tmp; + hdArrayCollection *tmpCollection; + while(points[posIdx]->count() > 0) + { + tmp = (hdPoint *) points[posIdx]->getItemAt(0); + points[posIdx]->removeItemAt(0); + delete tmp; + } + + if(points[posIdx]) + { + tmpCollection = points[posIdx]; + points.RemoveAt(posIdx); + delete tmpCollection; + } +} + +int hdPolyLineFigure::getMaximunIndex() +{ + unsigned int i; + int max = points[0]->count(); + + for(i = 1; i < points.Count(); i++) + { + if(points[i]->count() > max) + { + max = points[i]->count(); + } + + } + return max; +} + + +hdMultiPosRect &hdPolyLineFigure::getBasicDisplayBox() +{ + basicDisplayBox.height = 0; + basicDisplayBox.width = 0; + + int posIdx; + //optimize this if needed in a future, because right now calculate displaybox for all posIdx + hdIteratorBase *iterator; + for(posIdx = 0; posIdx < basicDisplayBox.CountPositions(); posIdx++) + { + if(points[posIdx]->count() >= 1) + { + basicDisplayBox.SetPosition(posIdx, pointAt(posIdx, 0)); + } + else + { + basicDisplayBox.SetPosition(posIdx, wxPoint(0, 0)); + } + + iterator = points[posIdx]->createIterator(); + while(iterator->HasNext()) + { + hdPoint *p = (hdPoint *) iterator->Next(); + hdRect r = hdRect(p->x, p->y, 0, 0); + basicDisplayBox.add(posIdx, r); + } + + delete iterator; + } + return basicDisplayBox; +} + +int hdPolyLineFigure::pointLinesCount() +{ + return points.Count(); +} +int hdPolyLineFigure::pointCount(int posIdx) +{ + return points[posIdx]->count(); +} + +hdPoint &hdPolyLineFigure::getStartPoint(int posIdx) +{ + startPoint.x = ((hdPoint *)points[posIdx]->getItemAt(0))->x; + startPoint.y = ((hdPoint *)points[posIdx]->getItemAt(0))->y; + return startPoint; +} + +void hdPolyLineFigure::setStartPoint(int posIdx, hdPoint point) +{ + willChange(); + if(points[posIdx]->count() == 0) + addPoint(posIdx, point.x, point.y); + else + { + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(0); + p->x = point.x; + p->y = point.y; + } + changed(posIdx); +} + +hdPoint &hdPolyLineFigure::getEndPoint(int posIdx) +{ + endPoint.x = ((hdPoint *)points[posIdx]->getItemAt(points[posIdx]->count() - 1))->x; + endPoint.y = ((hdPoint *)points[posIdx]->getItemAt(points[posIdx]->count() - 1))->y; + return endPoint; +} + +void hdPolyLineFigure::setEndPoint(int posIdx, hdPoint point) +{ + willChange(); + if(points[posIdx]->count() < 2) + addPoint(posIdx, point.x, point.y); + else + { + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(points[posIdx]->count() - 1); + p->x = point.x; + p->y = point.y; + } + changed(posIdx); +} + +void hdPolyLineFigure::setStartTerminal(hdLineTerminal *terminal) +{ + startTerminal = terminal; +} + +hdLineTerminal *hdPolyLineFigure::getStartTerminal() +{ + return startTerminal; +} + +void hdPolyLineFigure::setEndTerminal(hdLineTerminal *terminal) +{ + endTerminal = terminal; +} + +hdLineTerminal *hdPolyLineFigure::getEndTerminal() +{ + return endTerminal; +} + +hdCollection *hdPolyLineFigure::handlesEnumerator() +{ + return handles; +} + +void hdPolyLineFigure::addPoint (int posIdx, int x, int y) +{ + willChange(); + points[posIdx]->addItem((hdObject *) new hdPoint(x, y) ); + + if( handles->count() < getMaximunIndex() ) + { + //Update handles + handles->addItem(new hdPolyLineHandle(this, new hdPolyLineLocator(0), 0)); + updateHandlesIndexes(); + } + changed(posIdx); +} + +void hdPolyLineFigure::changed(int posIdx) +{ + handlesChanged = true; +} + +void hdPolyLineFigure::removePointAt (int posIdx, int index) +{ + willChange(); + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(index); + points[posIdx]->removeItemAt(index); + delete p; + //Update handles [If there are more handles than maximum points of a line in a view] + if( handles->count() > getMaximunIndex() ) + { + handles->removeItemAt(index); + updateHandlesIndexes(); + } + changed(posIdx); +} + +void hdPolyLineFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + basicDraw(context, view); +} + +void hdPolyLineFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + int posIdx = view->getIdx(); + if(points[posIdx]->count() < 2) + { + return; + } + hdPoint start, end; + + if(startTerminal) + { + startTerminal->setLinePen(linePen); + start = startTerminal->draw(context, getStartPoint(posIdx), pointAt(posIdx, 1), view); + } + else + { + start = getStartPoint(posIdx); + } + + if(endTerminal) + { + endTerminal->setLinePen(linePen); + end = endTerminal->draw(context, getEndPoint(posIdx), pointAt(posIdx, pointCount(posIdx) - 2), view); + } + else + { + end = getEndPoint(posIdx); + } + + context.SetPen(linePen); + for(int i = 0; i < points[posIdx]->count() - 1; i++) + { + hdPoint *p1 = (hdPoint *) points[posIdx]->getItemAt(i); + hdPoint *p2 = (hdPoint *) points[posIdx]->getItemAt(i + 1); + + hdPoint copyP1 = hdPoint (*p1); + view->CalcScrolledPosition(copyP1.x, copyP1.y, ©P1.x, ©P1.y); + hdPoint copyP2 = hdPoint (*p2); + view->CalcScrolledPosition(copyP2.x, copyP2.y, ©P2.x, ©P2.y); + + context.DrawLine(copyP1, copyP2); + } +} + +void hdPolyLineFigure::basicMoveBy(int posIdx, int x, int y) +{ + hdPoint *movPoint; + for(int i = 0 ; i < points[posIdx]->count() ; i++) + { + movPoint = (hdPoint *) points[posIdx]->getItemAt(i); + movPoint->x += x; + movPoint->y += y; + } +} + +hdITool *hdPolyLineFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return new hdPolyLineFigureTool(view, this, new hdMenuTool(view, this, defaultTool)); +} + + +int hdPolyLineFigure::findSegment (int posIdx, int x, int y) +{ + for(int i = 0 ; i < points[posIdx]->count() - 1 ; i++) + { + hdPoint p1 = pointAt(posIdx, i); + hdPoint p2 = pointAt(posIdx, i + 1); + hdGeometry g; + if(g.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y)) + { + return i + 1; + } + } + return -1; +} + +hdPoint &hdPolyLineFigure::pointAt(int posIdx, int index) +{ + //hack to avoid error with bad indexes calls + if(index < 0) + { + pointAtPos.x = 0; + pointAtPos.y = 0; + } + else + { + pointAtPos.x = ((hdPoint *)points[posIdx]->getItemAt(index))->x; + pointAtPos.y = ((hdPoint *)points[posIdx]->getItemAt(index))->y; + } + return pointAtPos; +} + +bool hdPolyLineFigure::containsPoint (int posIdx, int x, int y) +{ + hdRect rect = this->displayBox().gethdRect(posIdx); + rect.Inflate(4, 4); + if(!rect.Contains(x, y)) + { + return false; + } + + for(int i = 0 ; i < points[posIdx]->count() - 1 ; i++) + { + hdPoint p1 = pointAt(posIdx, i); + hdPoint p2 = pointAt(posIdx, i + 1); + hdGeometry g; + if(g.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y)) + { + return true; + } + } + return false; +} + +void hdPolyLineFigure::clearPoints(int posIdx) +{ + points[posIdx]->deleteAll(); +} + +void hdPolyLineFigure::insertPointAt (int posIdx, int index, int x, int y) +{ + willChange(); + points[posIdx]->insertAtIndex((hdObject *) new hdPoint(x, y), index); + + if( handles->count() < getMaximunIndex() ) + { + //Update handles + handles->insertAtIndex(new hdPolyLineHandle(this, new hdPolyLineLocator(index), index), index); + updateHandlesIndexes(); + } + + changed(posIdx); +} + +void hdPolyLineFigure::setPointAt (int posIdx, int index, int x, int y) +{ + willChange(); + hdPoint *p = (hdPoint *) points[posIdx]->getItemAt(index); + p->x = x; + p->y = y; + changed(posIdx); +} + +void hdPolyLineFigure::splitSegment(int posIdx, int x, int y) +{ + int index = findSegment(posIdx, x, y); + + if(index != -1) + { + insertPointAt(posIdx, index, x, y); + } +} + +void hdPolyLineFigure::updateHandlesIndexes() +{ + hdPolyLineHandle *h = NULL; + + //Get maximun point position in a collection of points + int i, maxPosition = getMaximunIndex(); + + //Update Handles indexes + for(i = 0; i < maxPosition; i++) + { + h = (hdPolyLineHandle *) handles->getItemAt(i); + h->setIndex(i); + } + +} + +void hdPolyLineFigure::setLinePen(wxPen pen) +{ + linePen = pen; +} + +int hdPolyLineFigure::countPointsAt(int posIdx) +{ + return points[posIdx]->count(); +} diff --git a/hotdraw/figures/hdRectangleFigure.cpp b/hotdraw/figures/hdRectangleFigure.cpp new file mode 100644 index 0000000..8d730eb --- /dev/null +++ b/hotdraw/figures/hdRectangleFigure.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRectangleFigure.cpp - A simple rectangle figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdRectangleFigure.h" +#include "hotdraw/main/hdDrawingView.h" + +hdRectangleFigure::hdRectangleFigure() +{ +} + +hdRectangleFigure::~hdRectangleFigure() +{ +} + +void hdRectangleFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawRectangle(copy); +} + +void hdRectangleFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawRectangle(copy); +} + +void hdRectangleFigure::setRectangle(hdMultiPosRect &rect) +{ + basicDisplayBox = rect; +} + +void hdRectangleFigure::setSize(wxSize &size) +{ + basicDisplayBox.SetSize(size); +} diff --git a/hotdraw/figures/hdSimpleTextFigure.cpp b/hotdraw/figures/hdSimpleTextFigure.cpp new file mode 100644 index 0000000..394178b --- /dev/null +++ b/hotdraw/figures/hdSimpleTextFigure.cpp @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextFigure.cpp - A simple rectangle figure with text inside it +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "hotdraw/tools/hdSimpleTextTool.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" + +// dummy image +#include "images/ddnull.pngc" + +hdSimpleTextFigure::hdSimpleTextFigure(wxString textString) +{ + textEditable = false; + font = *hdFontAttribute::defaultFont; + padding = 2; + setText(textString); + showMenu = false; +} + +hdSimpleTextFigure::~hdSimpleTextFigure() +{ +} + +void hdSimpleTextFigure::setText(wxString textString) +{ + text = textString; + recalculateDisplayBox(); +} + +//extended is flag that inform about returning an extended version of text stored at figure +wxString &hdSimpleTextFigure::getText(bool extended) +{ + return text; +} + +void hdSimpleTextFigure::setFont(wxFont textFont) +{ + font = textFont; + recalculateDisplayBox(); +} + +void hdSimpleTextFigure::getFontMetrics(int &width, int &height) +{ + wxBitmap emptyBitmap(*ddnull_png_img); + wxMemoryDC temp_dc; + temp_dc.SelectObject(emptyBitmap); + temp_dc.SetFont(font); + if(getText(true).length() > 5) + temp_dc.GetTextExtent(getText(true), &width, &height); + else + temp_dc.GetTextExtent(wxT("EMPTY"), &width, &height); +} + +void hdSimpleTextFigure::recalculateDisplayBox() +{ + int w, h; + + getFontMetrics(w, h); + + hdGeometry g; + displayBox().width = g.max(w, 10) + padding; + displayBox().height = g.max(h, 10) + padding; +} + +void hdSimpleTextFigure::basicDraw(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawText(getText(true), copy.GetPosition()); +} + +void hdSimpleTextFigure::basicDrawSelected(wxBufferedDC &context, hdDrawingView *view) +{ + hdRect copy = displayBox().gethdRect(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + context.DrawText(getText(true), copy.GetPosition()); +} + +void hdSimpleTextFigure::basicMoveBy(int posIdx, int x, int y) +{ + displayBox().x[posIdx] += x; + displayBox().y[posIdx] += y; +} + +hdITool *hdSimpleTextFigure::CreateFigureTool(hdDrawingView *view, hdITool *defaultTool) +{ + return textEditable ? new hdSimpleTextTool(view, this, defaultTool) : defaultTool; +} + +void hdSimpleTextFigure::setEditable(bool value) +{ + textEditable = value; +} + +bool hdSimpleTextFigure::getEditable() +{ + return textEditable; +} + +int hdSimpleTextFigure::getPadding() +{ + return padding; +} + +void hdSimpleTextFigure::enablePopUp() +{ + showMenu = true; +} + +void hdSimpleTextFigure::disablePopUp() +{ + showMenu = false; +} + +bool hdSimpleTextFigure::menuEnabled() +{ + return showMenu; +} + +void hdSimpleTextFigure::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + setText(strings[event.GetId()]); +} diff --git a/hotdraw/figures/module.mk b/hotdraw/figures/module.mk new file mode 100644 index 0000000..ed01f04 --- /dev/null +++ b/hotdraw/figures/module.mk @@ -0,0 +1,31 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/figures/hdAbstractFigure.cpp \ + hotdraw/figures/hdAbstractMenuFigure.cpp \ + hotdraw/figures/hdAttribute.cpp \ + hotdraw/figures/hdAttributeFigure.cpp \ + hotdraw/figures/hdBitmapFigure.cpp \ + hotdraw/figures/hdCompositeFigure.cpp \ + hotdraw/figures/hdIConnectionFigure.cpp \ + hotdraw/figures/hdIFigure.cpp \ + hotdraw/figures/hdLineConnection.cpp \ + hotdraw/figures/hdLineTerminal.cpp \ + hotdraw/figures/hdPolyLineFigure.cpp \ + hotdraw/figures/hdRectangleFigure.cpp \ + hotdraw/figures/hdSimpleTextFigure.cpp + +EXTRA_DIST += \ + hotdraw/figures/module.mk + +include hotdraw/figures/defaultAttributes/module.mk +include hotdraw/figures/xml/module.mk diff --git a/hotdraw/figures/xml/hdStorage.cpp b/hotdraw/figures/xml/hdStorage.cpp new file mode 100644 index 0000000..4050d4c --- /dev/null +++ b/hotdraw/figures/xml/hdStorage.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdStorage.cpp - Base class for managing all figures persistence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// libxml2 headers +#include +#include + +// App headers +#include "hotdraw/figures/xml/hdStorage.h" + +hdStorage::hdStorage(): + hdObject() +{ +} + +bool hdStorage::Read(xmlTextReaderPtr reader) +{ + return false; +} + +bool hdStorage::Write(xmlTextWriterPtr writer, hdIFigure *figure) +{ + return false; +} diff --git a/hotdraw/figures/xml/module.mk b/hotdraw/figures/xml/module.mk new file mode 100644 index 0000000..3f6dad7 --- /dev/null +++ b/hotdraw/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/figures/xml/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/figures/xml/hdStorage.cpp + +EXTRA_DIST += \ + hotdraw/figures/xml/module.mk diff --git a/hotdraw/handles/hdButtonHandle.cpp b/hotdraw/handles/hdButtonHandle.cpp new file mode 100644 index 0000000..1467b13 --- /dev/null +++ b/hotdraw/handles/hdButtonHandle.cpp @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdButtonHandle.cpp - Handle to allow creation of buttons at figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdButtonHandle.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdDrawingView.h" + + + +hdButtonHandle::hdButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size): + hdIHandle(owner) +{ + buttonIcon = buttonImage; + clicked = false; + bLocator = buttonLocator; + displayBox.SetSize(size); +} + +hdButtonHandle::~hdButtonHandle() +{ + if(bLocator) + delete bLocator; +} + +wxCursor hdButtonHandle::createCursor() +{ + return wxCursor(wxCURSOR_ARROW); +} + +hdRect &hdButtonHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + displayBox.SetPosition(p); + return displayBox; +} + +void hdButtonHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + wxPoint copy = getDisplayBox(view->getIdx()).GetPosition(); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + if(buttonIcon.IsOk()) + context.DrawBitmap(buttonIcon, copy.x, copy.y, true); +} + + +hdPoint &hdButtonHandle::locate(int posIdx) +{ + if(bLocator) + { + pointLocate = bLocator->locate(posIdx, getOwner()); + return pointLocate; + } + else + { + pointLocate = hdPoint(0, 0); + return pointLocate; + } +} diff --git a/hotdraw/handles/hdChangeConnectionEndHandle.cpp b/hotdraw/handles/hdChangeConnectionEndHandle.cpp new file mode 100644 index 0000000..ade1d14 --- /dev/null +++ b/hotdraw/handles/hdChangeConnectionEndHandle.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionEndHandle.cpp - Handle to allow change connected figure at end of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdChangeConnectionEndHandle.h" +#include "hotdraw/utilities/hdPoint.h" + +hdChangeConnectionEndHandle::hdChangeConnectionEndHandle(hdLineConnection *owner): + hdChangeConnectionHandle(owner) +{ +} + +hdChangeConnectionEndHandle::~hdChangeConnectionEndHandle() +{ +} + +hdPoint &hdChangeConnectionEndHandle::locate(int posIdx) +{ + return connection->getEndPoint(posIdx); +} + +hdIConnector *hdChangeConnectionEndHandle::target() +{ + return connection->getEndConnector(); +} + +void hdChangeConnectionEndHandle::connect(hdIConnector *connector, hdDrawingView *view) +{ + connection->connectEnd(connector, view); +} + +void hdChangeConnectionEndHandle::disconnect(hdDrawingView *view) +{ + connection->disconnectEnd(view); +} + +bool hdChangeConnectionEndHandle::isConnectionPossible(hdIFigure *figure) +{ + if(!figure->includes(connection) && figure->canConnect() && connection->canConnectEnd(figure)) + { + return true; + } + else + { + return false; + } +} + +void hdChangeConnectionEndHandle::setPoint(int posIdx, hdPoint p) +{ + connection->setEndPoint(posIdx, p); +} diff --git a/hotdraw/handles/hdChangeConnectionHandle.cpp b/hotdraw/handles/hdChangeConnectionHandle.cpp new file mode 100644 index 0000000..54e3fff --- /dev/null +++ b/hotdraw/handles/hdChangeConnectionHandle.cpp @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionHandle.cpp - Base Handle to allow change connected figures at connection figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/handles/hdChangeConnectionHandle.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdDrawingView.h" + + +hdChangeConnectionHandle::hdChangeConnectionHandle(hdLineConnection *owner): + hdIHandle(owner) +{ + connection = owner; + targetFigure = NULL; + originalTarget = NULL; +} + +hdChangeConnectionHandle::~hdChangeConnectionHandle() +{ + +} + +void hdChangeConnectionHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + + hdRect copy = getDisplayBox(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + copy.Deflate(2, 2); + context.SetPen(*wxGREEN_PEN); + context.SetBrush(*wxGREEN_BRUSH); + context.DrawRectangle(copy); +} + +wxCursor hdChangeConnectionHandle::createCursor() +{ + return wxCursor(wxCURSOR_CROSS); +} + +void hdChangeConnectionHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + originalTarget = target(); + disconnect(view); +} + +void hdChangeConnectionHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdPoint p = hdPoint(x, y); + hdIFigure *figure = findConnectableFigure(view->getIdx(), x, y, view->getDrawing()); + targetFigure = figure; + hdIConnector *target = findConnectionTarget(view->getIdx(), x, y, view->getDrawing()); + if(target) + { + p = target->getDisplayBox().center(view->getIdx()); + } + setPoint(view->getIdx(), p); + connection->updateConnection(view->getIdx()); + if(view) + view->Refresh(); +} + +void hdChangeConnectionHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdIConnector *target = findConnectionTarget(view->getIdx(), x, y, view->getDrawing()); + if(!target) + { + target = originalTarget; + } + connect(target, view); + connection->updateConnection(view->getIdx()); + if(view) + view->Refresh(); +} + + +hdIFigure *hdChangeConnectionHandle::findConnectableFigure (int posIdx, int x, int y, hdDrawing *drawing) +{ + hdIFigure *out = NULL; + hdIteratorBase *iterator = drawing->figuresInverseEnumerator(); + while(iterator->HasNext()) + { + hdIFigure *figure = (hdIFigure *) iterator->Next(); + if(figure->containsPoint(posIdx, x, y) && isConnectionPossible(figure)) + { + out = figure; + break; + } + } + delete iterator; + return out; +} +hdIConnector *hdChangeConnectionHandle::findConnectionTarget(int posIdx, int x, int y, hdDrawing *drawing) +{ + hdIFigure *target = findConnectableFigure(posIdx, x, y, drawing); + if(target) + return target->connectorAt(posIdx, x, y); + else + return NULL; +} diff --git a/hotdraw/handles/hdChangeConnectionStartHandle.cpp b/hotdraw/handles/hdChangeConnectionStartHandle.cpp new file mode 100644 index 0000000..2d09a3f --- /dev/null +++ b/hotdraw/handles/hdChangeConnectionStartHandle.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionStartHandle.cpp - Handle to allow change connected figure at start of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdChangeConnectionStartHandle.h" +#include "hotdraw/utilities/hdPoint.h" + +hdChangeConnectionStartHandle::hdChangeConnectionStartHandle(hdLineConnection *owner): + hdChangeConnectionHandle(owner) +{ +} + +hdChangeConnectionStartHandle::~hdChangeConnectionStartHandle() +{ +} + +hdPoint &hdChangeConnectionStartHandle::locate(int posIdx) +{ + return connection->getStartPoint(posIdx); +} + +hdIConnector *hdChangeConnectionStartHandle::target() +{ + return connection->getStartConnector(); +} + +void hdChangeConnectionStartHandle::connect(hdIConnector *connector, hdDrawingView *view) +{ + connection->connectStart(connector, view); +} + +void hdChangeConnectionStartHandle::disconnect(hdDrawingView *view) +{ + connection->disconnectStart(view); +} + +bool hdChangeConnectionStartHandle::isConnectionPossible(hdIFigure *figure) +{ + if(!figure->includes(connection) && figure->canConnect() && connection->canConnectStart(figure)) + { + return true; + } + else + { + return false; + } +} + +void hdChangeConnectionStartHandle::setPoint(int posIdx, hdPoint p) +{ + connection->setStartPoint(posIdx, p); +} diff --git a/hotdraw/handles/hdIHandle.cpp b/hotdraw/handles/hdIHandle.cpp new file mode 100644 index 0000000..337b0bc --- /dev/null +++ b/hotdraw/handles/hdIHandle.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIHandle.cpp - Base class for all Handles +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdPoint.h" + +hdIHandle::hdIHandle(hdIFigure *owner) +{ + figureOwner = owner; +} +hdIHandle::~hdIHandle() +{ +} + +hdIFigure *hdIHandle::getOwner() +{ + return figureOwner; +} + +hdRect &hdIHandle::getDisplayBox(int posIdx) +{ + hdPoint p = locate(posIdx); + displayBox.width = 0; + displayBox.height = 0; + displayBox.SetPosition(p); + displayBox.Inflate(size, size); + return displayBox; +} + +bool hdIHandle::containsPoint(int posIdx, int x, int y) +{ + return getDisplayBox(posIdx).Contains(x, y); +} diff --git a/hotdraw/handles/hdLineConnectionHandle.cpp b/hotdraw/handles/hdLineConnectionHandle.cpp new file mode 100644 index 0000000..cae86ea --- /dev/null +++ b/hotdraw/handles/hdLineConnectionHandle.cpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnectionHandle.cpp - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/handles/hdLineConnectionHandle.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/main/hdDrawingView.h" + +hdLineConnectionHandle::hdLineConnectionHandle(hdPolyLineFigure *figure, hdILocator *loc, int index): + hdPolyLineHandle(figure, loc, index) +{ +} + +void hdLineConnectionHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdPolyLineFigure *figure = (hdPolyLineFigure *) getOwner(); + //eliminate all handles in the middle of a straight line + + if( figure->pointCount(view->getIdx()) > 2 && getIndex() != 0 && getIndex() != (figure->pointCount(view->getIdx()) - 1) ) + { + hdPoint p1 = figure->pointAt(view->getIdx(), getIndex() - 1); + hdPoint p2 = figure->pointAt(view->getIdx(), getIndex() + 1); + hdGeometry g; + if(g.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y)) + { + figure->removePointAt(view->getIdx(), getIndex()); + } + } +} diff --git a/hotdraw/handles/hdLocatorHandle.cpp b/hotdraw/handles/hdLocatorHandle.cpp new file mode 100644 index 0000000..40f1362 --- /dev/null +++ b/hotdraw/handles/hdLocatorHandle.cpp @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorHandle.cpp - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/handles/hdLocatorHandle.h" + +hdLocatorHandle::hdLocatorHandle(hdIFigure *owner, hdILocator *locator): + hdIHandle(owner) +{ + loc = locator; +} + +hdLocatorHandle::~hdLocatorHandle() +{ + if(loc) + delete loc; +} + +hdPoint &hdLocatorHandle::locate(int posIdx) +{ + p = hdPoint(0, 0); + return loc == NULL ? p : loc->locate(posIdx, getOwner()); +} + +hdILocator *hdLocatorHandle::locator() +{ + return loc; +} + +void hdLocatorHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void hdLocatorHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ +} + +void hdLocatorHandle::invokeEnd(hdMouseEvent &event, hdDrawingView *view) +{ +} diff --git a/hotdraw/handles/hdPolyLineHandle.cpp b/hotdraw/handles/hdPolyLineHandle.cpp new file mode 100644 index 0000000..bba2f15 --- /dev/null +++ b/hotdraw/handles/hdPolyLineHandle.cpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineHandle.cpp - Handle for manipulation of multiple flexibility points lines. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/handles/hdPolyLineHandle.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/main/hdDrawingView.h" + + +hdPolyLineHandle::hdPolyLineHandle(hdPolyLineFigure *figure, hdILocator *loc, int index): + hdLocatorHandle((hdIFigure *)figure, loc) +{ + indx = index; +} + +hdPolyLineHandle::~hdPolyLineHandle() +{ +} + +void hdPolyLineHandle::draw(wxBufferedDC &context, hdDrawingView *view) +{ + //A Handle at polyline figure without a respetive flexibility point at line + //Hack to allow handles of polylines reuse between different versions of same line. + if(getOwner() && indx < (((hdPolyLineFigure *) getOwner())->countPointsAt(view->getIdx()) - 1) ) //indx 0 is first, count first is 1 + { + hdRect copy = getDisplayBox(view->getIdx()); + view->CalcScrolledPosition(copy.x, copy.y, ©.x, ©.y); + + /* Uncomment this for testing purposes of handles in a polyline figure + wxString pos = wxString::Format(_("%d"),indx); + double middle2 = copy.width / 2; + context.DrawText(pos,copy.x + middle2+3, copy.y + middle2); + */ + + double middle = copy.width / 2; + context.DrawCircle( + wxPoint(copy.x + middle, copy.y + middle), + wxCoord(middle) + ); + } +} + +void hdPolyLineHandle::invokeStep(hdMouseEvent &event, hdDrawingView *view) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + ((hdPolyLineFigure *) getOwner())->setPointAt(view->getIdx(), indx, x, y); + view->notifyChanged(); + +} + +void hdPolyLineHandle::invokeStart(hdMouseEvent &event, hdDrawingView *view) +{ + if(event.RightDown()) + { + ((hdPolyLineFigure *) getOwner())->removePointAt(view->getIdx(), indx); + view->notifyChanged(); + } +} +wxCursor hdPolyLineHandle::createCursor() +{ + return wxCursor(wxCURSOR_CROSS); + +} + +int hdPolyLineHandle::getIndex() +{ + return indx; +} + +void hdPolyLineHandle::setIndex(int index) +{ + indx = index; + hdPolyLineLocator *l = (hdPolyLineLocator *) locator(); + l->setIndex(index); +} diff --git a/hotdraw/handles/module.mk b/hotdraw/handles/module.mk new file mode 100644 index 0000000..7f0d240 --- /dev/null +++ b/hotdraw/handles/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/handles/hdButtonHandle.cpp \ + hotdraw/handles/hdChangeConnectionEndHandle.cpp \ + hotdraw/handles/hdChangeConnectionHandle.cpp \ + hotdraw/handles/hdChangeConnectionStartHandle.cpp \ + hotdraw/handles/hdIHandle.cpp \ + hotdraw/handles/hdLineConnectionHandle.cpp \ + hotdraw/handles/hdLocatorHandle.cpp \ + hotdraw/handles/hdPolyLineHandle.cpp + +EXTRA_DIST += \ + hotdraw/handles/module.mk diff --git a/hotdraw/locators/hdILocator.cpp b/hotdraw/locators/hdILocator.cpp new file mode 100644 index 0000000..c89b578 --- /dev/null +++ b/hotdraw/locators/hdILocator.cpp @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdILocator.cpp - Base class for creation of a location for a ddHandle +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/locators/hdILocator.h" + +hdILocator::hdILocator() +{ + locatePoint = hdPoint(0, 0); +} + +hdILocator::~hdILocator() +{ +} diff --git a/hotdraw/locators/hdPolyLineLocator.cpp b/hotdraw/locators/hdPolyLineLocator.cpp new file mode 100644 index 0000000..53daeb7 --- /dev/null +++ b/hotdraw/locators/hdPolyLineLocator.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineLocator.cpp - Return multiple location at same time for a PolyLine +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/locators/hdPolyLineLocator.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdPolyLineFigure.h" + +hdPolyLineLocator::~hdPolyLineLocator() +{ +} + +//This index refers to point index inside collection not the diagram index +hdPolyLineLocator::hdPolyLineLocator(int index) +{ + indx = index; +} + +hdPoint &hdPolyLineLocator::locate(int posIdx, hdIFigure *owner) +{ + hdPolyLineFigure *figure = (hdPolyLineFigure *) owner; + + //A Handle at polyline figure without a respetive flexibility point at line + //Hack to allow handles of polylines reuse between different versions of same line. + if(figure && indx >= (figure->countPointsAt(posIdx) - 1) ) //indx 0 is first, count first is 1 + { + locatePoint.x = -100; //Any negative number that don't allow to the mouse to reach this locator + locatePoint.y = -100; + return locatePoint; + } + else if(figure) + { + locatePoint = figure->pointAt(posIdx, indx); + return locatePoint; + } + else + { + return locatePoint; + } +} + +void hdPolyLineLocator::setIndex(int index) +{ + indx = index; +} diff --git a/hotdraw/locators/module.mk b/hotdraw/locators/module.mk new file mode 100644 index 0000000..1defbd3 --- /dev/null +++ b/hotdraw/locators/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/locator/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/locators/hdILocator.cpp \ + hotdraw/locators/hdPolyLineLocator.cpp + +EXTRA_DIST += \ + hotdraw/locators/module.mk diff --git a/hotdraw/main/hdDrawing.cpp b/hotdraw/main/hdDrawing.cpp new file mode 100644 index 0000000..ba0f947 --- /dev/null +++ b/hotdraw/main/hdDrawing.cpp @@ -0,0 +1,245 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawing.cpp - Main storage class for all objects of the diagram, +// their functions are used by model and shouldn't be called directly +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/main/hdDrawing.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdIFigure.h" + + +hdDrawing::hdDrawing(hdDrawingEditor *owner) +{ + figures = new hdCollection(new hdArrayCollection()); + selection = new hdCollection(new hdArrayCollection()); + usedView = NULL; + ownerEditor = owner; + drawingName = wxEmptyString; +} + +hdDrawing::~hdDrawing() +{ + //clear selection + if(selection) + { + selection->removeAll(); + delete selection; + } + + //Cannot delete figures, because they belong to model not to diagram + hdIFigure *tmp; + while(figures->count() > 0) + { + tmp = (hdIFigure *) figures->getItemAt(0); + figures->removeItemAt(0); + } + + if(figures) + delete figures; +} + +void hdDrawing::add(hdIFigure *figure) +{ + if(figures) + figures->addItem(figure); +} + +void hdDrawing::remove(hdIFigure *figure) +{ + if(figures) + { + figures->removeItem(figure); + if(usedView) + figure->moveTo(usedView->getIdx(), -1, -1); + } +} + +bool hdDrawing::includes(hdIFigure *figure) +{ + if(figures) + return figures->existsObject(figure); + return false; +} + +hdIFigure *hdDrawing::findFigure(int posIdx, int x, int y) +{ + hdIFigure *tmp = NULL, *out = NULL; + hdIteratorBase *iterator = figures->createIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + if(tmp->containsPoint(posIdx, x, y)) + { + out = tmp; + break; + } + } + + delete iterator;; + + return out; +} + +void hdDrawing::recalculateDisplayBox(int posIdx) +{ + bool first = true; + hdIFigure *figure = NULL; + + hdIteratorBase *iterator = figures->createIterator(); + while(iterator->HasNext()) + { + figure = (hdIFigure *)iterator->Next(); + if(first) + { + displayBox = figure->displayBox().gethdRect(posIdx); + first = false; + } + else + { + displayBox.add(figure->displayBox().gethdRect(posIdx)); + } + } + + delete iterator; +} + +void hdDrawing::bringToFront(hdIFigure *figure) +{ + //To bring to front this figure need to be at last position when is draw + //because this reason sendToBack (last position) is used. + figures->sendToBack(figure); +} + +void hdDrawing::sendToBack(hdIFigure *figure) +{ + //To send to back this figure need to be at first position when is draw + //because this reason bringToFront (1st position) is used. + figures->bringToFront(figure); +} + +hdRect &hdDrawing::DisplayBox() +{ + return displayBox; +} + +hdIteratorBase *hdDrawing::figuresEnumerator() +{ + return figures->createIterator(); +} + +hdIteratorBase *hdDrawing::figuresInverseEnumerator() +{ + return figures->createDownIterator(); +} + +void hdDrawing::deleteAllFigures() +{ + selection->removeAll(); + + hdIFigure *tmp; + while(figures->count() > 0) + { + tmp = (hdIFigure *) figures->getItemAt(0); + figures->removeItemAt(0); + delete tmp; + } + //handles delete it together with figures +} + +void hdDrawing::removeAllFigures() +{ + selection->removeAll(); + + hdIFigure *tmp; + while(figures->count() > 0) + { + tmp = (hdIFigure *) figures->getItemAt(0); + figures->removeItemAt(0); + if(usedView) + tmp->moveTo(usedView->getIdx(), -1, -1); + } +} + +void hdDrawing::deleteSelectedFigures() +{ + //Allow to customize delete dialog at Editor + ownerEditor->remOrDelSelFigures(usedView->getIdx()); +} + +void hdDrawing::addToSelection(hdIFigure *figure) +{ + if(!selection) + { + selection = new hdCollection(new hdArrayCollection()); + } + if(figure) + { + figure->setSelected(usedView->getIdx(), true); + selection->addItem(figure); + } +} + +void hdDrawing::addToSelection(hdCollection *figures) +{ +} + +void hdDrawing::removeFromSelection(hdIFigure *figure) +{ + figure->setSelected(usedView->getIdx(), false); + if(selection) + selection->removeItem(figure); +} + + +void hdDrawing::toggleSelection(hdIFigure *figure) +{ + if(figure->isSelected(usedView->getIdx()) && selection->existsObject(figure)) + selection->removeItem(figure); + else if(!figure->isSelected(usedView->getIdx()) && this->includes(figure)) + selection->addItem(figure); + + figure->setSelected(usedView->getIdx(), !figure->isSelected(usedView->getIdx())); +} + +void hdDrawing::clearSelection() +{ + hdIFigure *tmp = NULL; + hdIteratorBase *iterator = selection->createIterator(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + tmp->setSelected(usedView->getIdx(), false); + } + selection->removeAll(); + delete iterator; +} + +bool hdDrawing::isFigureSelected(hdIFigure *figure) +{ + return selection->existsObject(figure); +} + +hdIteratorBase *hdDrawing::selectionFigures() +{ + return selection->createIterator(); +} + +int hdDrawing::countSelectedFigures() +{ + return selection->count(); +} diff --git a/hotdraw/main/hdDrawingEditor.cpp b/hotdraw/main/hdDrawingEditor.cpp new file mode 100644 index 0000000..e1b7ef3 --- /dev/null +++ b/hotdraw/main/hdDrawingEditor.cpp @@ -0,0 +1,303 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.cpp - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" + +hdDrawingEditor::hdDrawingEditor(wxWindow *owner, bool defaultView) +{ + _diagrams = new hdArrayCollection(); + _model = new hdArrayCollection(); + editorOwner = owner; + modelChanged = false; + + changeDefaultFiguresFont(); +} + +hdDrawingEditor::~hdDrawingEditor() +{ + //Hack: If just delete _diagrams collection an error is raised. + hdDrawing *diagram; + while(_diagrams->count() > 0) + { + diagram = (hdDrawing *) _diagrams->getItemAt(0); + _diagrams->removeItemAt(0); + delete diagram; + } + + //Hack: If just delete _model collection an error is raised. + hdIFigure *tmp; + while(_model->count() > 0) + { + tmp = (hdIFigure *) _model->getItemAt(0); + _model->removeItemAt(0); + delete tmp; + } + + if(_model) + delete _model; + + if(_diagrams) + delete _diagrams; +} + +//Hack to allow create different kind of custom _views inside custom editor +hdDrawing *hdDrawingEditor::createDiagram(wxWindow *owner, bool fromXml) +{ + hdDrawing *_tmpModel = new hdDrawing(this); + + hdDrawingView *_viewTmp = new hdDrawingView(_diagrams->count(), owner, this, wxSize(1200, 1200), _tmpModel); + + // Set Scroll Bar & split + _viewTmp->SetScrollbars( 10, 10, 127, 80 ); + _viewTmp->EnableScrolling(true, true); + _viewTmp->AdjustScrollbars(); + + _tmpModel->registerView(_viewTmp); + + //Add a new position inside each figure to allow use of this new diagram existing figures. + int i; + hdIFigure *tmp; + if(!fromXml) + { + for(i = 0; i < _model->count(); i++) + { + tmp = (hdIFigure *) _model->getItemAt(i); + tmp->AddPosForNewDiagram(); + } + } + + //Add Diagram + _diagrams->addItem((hdObject *) _tmpModel); + modelChanged = true; + return _tmpModel; +} + +void hdDrawingEditor::deleteDiagram(int diagramIndex, bool deleteView) +{ + hdDrawing *_tmpModel = (hdDrawing *) _diagrams->getItemAt(diagramIndex); + _diagrams->removeItemAt(diagramIndex); + hdDrawingView *_viewTmp = _tmpModel->getView(); + _tmpModel->registerView(NULL); + if(_tmpModel) + delete _tmpModel; + if(_viewTmp && deleteView) + delete _viewTmp; + + // Fix other diagrams positions + int i; + for(i = diagramIndex; i < _diagrams->count(); i++) + { + getExistingDiagram(i)->getView()->syncIdx(i); + } + + //Remove this position inside each figure to allow delete that diagram related info from figures. + hdIFigure *tmp; + for(i = 0; i < _model->count(); i++) + { + tmp = (hdIFigure *) _model->getItemAt(i); + tmp->RemovePosOfDiagram(diagramIndex); + } + modelChanged = true; +} + +hdDrawingView *hdDrawingEditor::getExistingView(int diagramIndex) +{ + if(diagramIndex >= _diagrams->count() || diagramIndex < 0) + { + return NULL; + } + + hdDrawing *diagram = (hdDrawing *) _diagrams->getItemAt(diagramIndex); + return diagram->getView(); +} + +hdDrawing *hdDrawingEditor::getExistingDiagram(int diagramIndex) +{ + if(diagramIndex >= _diagrams->count() || diagramIndex < 0) + { + return NULL; + } + + return (hdDrawing *) _diagrams->getItemAt(diagramIndex); +} + +void hdDrawingEditor::addModelFigure(hdIFigure *figure) +{ + if(_model) + _model->addItem(figure); + modelChanged = true; +} + +void hdDrawingEditor::removeFromAllSelections(hdIFigure *figure) +{ + if(_model) + { + if(_diagrams) + { + int i; + for(i = 0; i < _diagrams->count(); i++) + { + if(getExistingDiagram(i)->isFigureSelected(figure)) + getExistingDiagram(i)->removeFromSelection(figure); + } + } + } +} + +void hdDrawingEditor::deleteModelFigure(hdIFigure *figure) +{ + if(_model) + { + if(_diagrams) + { + int i; + for(i = 0; i < _diagrams->count(); i++) + { + if(getExistingDiagram(i)->includes(figure)) + getExistingDiagram(i)->remove(figure); + } + } + _model->removeItem(figure); + delete figure; + figure = NULL; + } + modelChanged = true; +} + +void hdDrawingEditor::addDiagramFigure(int diagramIndex, hdIFigure *figure) +{ + //first time figure is used at a diagram then add to it + if(!modelIncludes(figure)) + { + //Add figure to model + addModelFigure(figure); + //Add needed position(s) to figure to allow their use at new diagram(s). + int i, start; + start = figure->displayBox().CountPositions(); + for(i = start; i < _diagrams->count(); i++) + { + figure->AddPosForNewDiagram(); + } + } + getExistingDiagram(diagramIndex)->add(figure); + modelChanged = true; +} + +void hdDrawingEditor::removeDiagramFigure(int diagramIndex, hdIFigure *figure) +{ + getExistingDiagram(diagramIndex)->remove(figure); + modelChanged = true; +} + +bool hdDrawingEditor::modelIncludes(hdIFigure *figure) +{ + if(_model) + return _model->existsObject(figure); + return false; +} + +int hdDrawingEditor::modelCount() +{ + if(_model) + return _diagrams->count(); + return 0; +} + +hdIteratorBase *hdDrawingEditor::modelFiguresEnumerator() +{ + return _model->createIterator(); +} + +hdIteratorBase *hdDrawingEditor::diagramsEnumerator() +{ + return _diagrams->createIterator(); +} + +void hdDrawingEditor::removeAllDiagramsFigures() +{ + int i, size = modelCount(); + + for(i = 0; i < size ; i++) + { + getExistingDiagram(i)->removeAllFigures(); + } + modelChanged = true; +} + +void hdDrawingEditor::deleteAllModelFigures() +{ + removeAllDiagramsFigures(); + hdIFigure *tmp; + while(_model->count() > 0) + { + tmp = (hdIFigure *) _model->getItemAt(0); + _model->removeItemAt(0); + delete tmp; + } + modelChanged = true; +} + +void hdDrawingEditor::remOrDelSelFigures(int diagramIndex) +{ + int answer; + hdIFigure *tmp; + + if (getExistingDiagram(diagramIndex)->countSelectedFigures() == 1) + { + tmp = (hdIFigure *) getExistingDiagram(diagramIndex)->selectedFigures()->getItemAt(0); + answer = wxMessageBox(_("Are you sure you wish to delete figure ?"), _("Delete figures?"), wxYES_NO | wxNO_DEFAULT); + } + else if (getExistingDiagram(diagramIndex)->countSelectedFigures() > 1) + { + answer = wxMessageBox( + wxString::Format(_("Are you sure you wish to delete %d figures?"), getExistingDiagram(diagramIndex)->countSelectedFigures()), + _("Delete figures?"), wxYES_NO | wxNO_DEFAULT); + } + + if (answer == wxYES) + { + while(getExistingDiagram(diagramIndex)->countSelectedFigures() > 0) + { + getExistingDiagram(diagramIndex)->removeFromSelection(tmp); + getExistingDiagram(diagramIndex)->remove(tmp); + if(tmp) + delete tmp; + } + getExistingDiagram(diagramIndex)->clearSelection(); //reset selection to zero items + modelChanged = true; + } +} + +void hdDrawingEditor::changeDefaultFiguresFont() +{ + *hdFontAttribute::defaultFont = settings->GetDDFont(); +} + +bool hdDrawingEditor::modelHasChanged() +{ + return modelChanged; +} + +void hdDrawingEditor::notifyChanged() +{ + modelChanged = true; +} diff --git a/hotdraw/main/hdDrawingView.cpp b/hotdraw/main/hdDrawingView.cpp new file mode 100644 index 0000000..921fd6a --- /dev/null +++ b/hotdraw/main/hdDrawingView.cpp @@ -0,0 +1,473 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingView.cpp - Main canvas where all figures are drawn +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/utilities/hdMouseEvent.h" +#include "hotdraw/tools/hdCanvasMenuTool.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/tools/hdSelectionTool.h" + +// Images +#include "images/check.pngc" +#include "images/ddcancel.pngc" + +BEGIN_EVENT_TABLE(hdDrawingView, wxScrolledWindow) + EVT_PAINT( hdDrawingView::onPaint) + EVT_MOTION( hdDrawingView::onMotion) + EVT_RIGHT_DOWN( hdDrawingView::onMouseDown) + EVT_RIGHT_UP( hdDrawingView::onMouseUp) + EVT_LEFT_DOWN( hdDrawingView::onMouseDown) + EVT_LEFT_DCLICK( hdDrawingView::onMouseDown) + EVT_LEFT_UP( hdDrawingView::onMouseUp) + EVT_ERASE_BACKGROUND( hdDrawingView::onEraseBackGround) //This erase flicker + EVT_TEXT(CTL_TEXTTOOLID, hdDrawingView::simpleTextToolChangeHandler) + EVT_BUTTON(CTL_OKBUTTONID, hdDrawingView::OnOkTxtButton) + EVT_BUTTON(CTL_CANCELBUTTONID, hdDrawingView::OnCancelTxtButton) + EVT_KEY_DOWN( hdDrawingView::onKeyDown) + EVT_KEY_UP( hdDrawingView::onKeyUp) +END_EVENT_TABLE() + + +hdDrawingView::hdDrawingView(int diagram, wxWindow *ddParent, hdDrawingEditor *editor, wxSize size, hdDrawing *initialDrawing)// gqbController *controller, gqbModel *model) + : wxScrolledWindow(ddParent, wxID_ANY, wxPoint(0, 0), size, + wxHSCROLL | wxVSCROLL | wxBORDER | wxRETAINED) +{ + diagramIndex = diagram; + drawing = initialDrawing; + drawingEditor = editor; + canvasSize = size; + +#if wxCHECK_VERSION(2, 9, 0) + FitInside(); +#else + SetVirtualSizeHints(canvasSize); +#endif + + // Hack to avoid selection rectangle drawing bug + drawSelRect = false; + // Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event + simpleTextToolEdit = new wxTextCtrl(this, CTL_TEXTTOOLID, wxT(""), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + simpleTextToolEdit->Hide(); + simpleTextFigure = NULL; + menuFigure = NULL; + okTxtButton = new wxBitmapButton(this, CTL_OKBUTTONID, *check_png_bmp, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + okTxtButton->Hide(); + cancelTxtButton = new wxBitmapButton(this, 1981, wxBitmap(*ddcancel_png_img), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + cancelTxtButton->Hide(); + canvasMenu = NULL; + _tool = NULL; + _tool = new hdSelectionTool(this); +} + +hdDrawingView::~hdDrawingView() +{ + if(simpleTextToolEdit) + delete simpleTextToolEdit; + if(okTxtButton) + delete okTxtButton; + if(cancelTxtButton) + delete cancelTxtButton; + if(_tool) + delete _tool; +} + +void hdDrawingView::onPaint(wxPaintEvent &event) +{ + // Prepare Context for Buffered Draw + wxPaintDC dcc(this); + wxBufferedDC dc(&dcc, canvasSize); + dc.Clear(); + hdIFigure *toDraw = NULL; + hdIteratorBase *iterator = drawing->figuresEnumerator(); + + while(iterator->HasNext()) + { + toDraw = (hdIFigure *)iterator->Next(); + if(toDraw->isSelected(diagramIndex)) + toDraw->drawSelected(dc, this); + else + toDraw->draw(dc, this); + } + + delete iterator; + + hdIHandle *tmpHandle = NULL; + hdIteratorBase *selectionIterator = drawing->selectionFigures();//selection->createIterator(); + while(selectionIterator->HasNext()) + { + toDraw = (hdIFigure *)selectionIterator->Next(); + hdIteratorBase *handlesIterator = toDraw->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + tmpHandle = (hdIHandle *)handlesIterator->Next(); + tmpHandle->draw(dc, this); + } + delete handlesIterator; + } + + delete selectionIterator; + + //Hack to avoid selection rectangle drawing bug + if (drawSelRect) + { + wxPen *pen = wxThePenList->FindOrCreatePen(*wxRED, 1, wxDOT); + dc.SetPen(*pen); + wxBrush *brush = wxTheBrushList->FindOrCreateBrush(*wxRED, wxTRANSPARENT); + dc.SetBackground(*brush); + dc.SetBackgroundMode(wxTRANSPARENT); + //Adjust points before drawing + wxPoint selAjustedPoints[5]; + CalcScrolledPosition(selPoints[0].x, selPoints[0].y, &selAjustedPoints[0].x, &selAjustedPoints[0].y); + CalcScrolledPosition(selPoints[1].x, selPoints[1].y, &selAjustedPoints[1].x, &selAjustedPoints[1].y); + CalcScrolledPosition(selPoints[2].x, selPoints[2].y, &selAjustedPoints[2].x, &selAjustedPoints[2].y); + CalcScrolledPosition(selPoints[3].x, selPoints[3].y, &selAjustedPoints[3].x, &selAjustedPoints[3].y); + CalcScrolledPosition(selPoints[4].x, selPoints[4].y, &selAjustedPoints[4].x, &selAjustedPoints[4].y); + //Draw + dc.DrawLines(5, selAjustedPoints, 0, 0); + drawSelRect = false; + } +} + +//Hack to avoid selection rectangle drawing bug +void hdDrawingView::disableSelRectDraw() +{ + drawSelRect = false; +} + +//Hack to avoid selection rectangle drawing bug +void hdDrawingView::setSelRect(hdRect &selectionRect) +{ + //Create rectangle lines to avoid non transparent brush for filling bug in wxwidgets + selPoints[0].x = selectionRect.x; + selPoints[0].y = selectionRect.y; + selPoints[1].x = selectionRect.x + selectionRect.width; + selPoints[1].y = selectionRect.y; + selPoints[2].x = selectionRect.x + selectionRect.width; + selPoints[2].y = selectionRect.y + selectionRect.height; + selPoints[3].x = selectionRect.x; + selPoints[3].y = selectionRect.y + selectionRect.height; + selPoints[4].x = selectionRect.x; + selPoints[4].y = selectionRect.y; + drawSelRect = true; +} + +// Overwrite and disable onEraseBackground Event to avoid Flicker +void hdDrawingView::onEraseBackGround(wxEraseEvent &event) +{ +} + +hdMultiPosRect hdDrawingView::getVisibleArea() +{ + int x, y, w, h; + GetViewStart(&x, &y); + GetClientSize(&w, &h); + hdMultiPosRect visibleArea(x, y, w, h); + return visibleArea; +} + +hdMultiPosRect hdDrawingView::getVirtualSize() +{ + int w, h; + GetVirtualSize(&w, &h); + hdMultiPosRect virtualSize(0, 0, w, h); + return virtualSize; +} + +void hdDrawingView::ScrollToMakeVisible(hdPoint p) +{ + //implement this function +} + +void hdDrawingView::ScrollToMakeVisible (hdRect r) +{ + //implement this function +} + +hdIHandle *hdDrawingView::findHandle(int posIdx, double x, double y) +{ + hdIFigure *tmpFigure = NULL; + hdIHandle *tmpHandle = NULL, *out = NULL; + + + //Look for handles at each figure in SelectionEnumerator + hdIteratorBase *selectionIterator = drawing->selectionFigures(); //selection->createIterator(); + while(selectionIterator->HasNext()) + { + tmpFigure = (hdIFigure *)selectionIterator->Next(); + hdIteratorBase *handlesIterator = tmpFigure->handlesEnumerator()->createIterator(); + while(handlesIterator->HasNext()) + { + tmpHandle = (hdIHandle *)handlesIterator->Next(); + if(tmpHandle->containsPoint(posIdx, x, y)) + { + out = tmpHandle; + break; + } + } + delete handlesIterator; + } + delete selectionIterator; + return out; +} + +hdDrawing *hdDrawingView::getDrawing() +{ + return drawing; +} + +void hdDrawingView::onMotion(wxMouseEvent &event) +{ +// simple hack to don't update so frequently the canvas and mouse events +// Should be changed for a better one using time intervals not a simple counter + static int simpleOptimization = 0; + simpleOptimization++; + if(simpleOptimization > 0) + { + simpleOptimization = 0; + + hdMouseEvent ddEvent = hdMouseEvent(event, this); + if(event.Dragging()) + { + _tool->mouseDrag(ddEvent); + this->Refresh(); //only a dragging event on montion will change model + } + else + { + _tool->mouseMove(ddEvent); + } + } +} + +void hdDrawingView::onMouseDown(wxMouseEvent &event) +{ + this->AcceptsFocus(); + this->SetFocus(); + startDrag = event.GetPosition(); + hdMouseEvent ddEvent = hdMouseEvent(event, this); + _tool->mouseDown(ddEvent); + this->Refresh(); +} + +void hdDrawingView::onMouseUp(wxMouseEvent &event) +{ + this->AcceptsFocus(); + this->SetFocus(); + hdMouseEvent ddEvent = hdMouseEvent(event, this); + _tool->mouseUp(ddEvent); + this->Refresh(); +} + +void hdDrawingView::onKeyDown(wxKeyEvent &event) +{ + hdKeyEvent ddEvent = hdKeyEvent(event, this); + _tool->keyDown(ddEvent); + this->Refresh(); +} + +void hdDrawingView::onKeyUp(wxKeyEvent &event) +{ + hdKeyEvent ddEvent = hdKeyEvent(event, this); + _tool->keyUp(ddEvent); + this->Refresh(); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +void hdDrawingView::setSimpleTextToolFigure(hdSimpleTextFigure *figure, bool onlySetFigure) +{ + simpleTextFigure = figure; + menuFigure = NULL; + if(simpleTextFigure && !onlySetFigure) + { + oldText = simpleTextFigure->getText(); + simpleTextToolEdit->SetValue(simpleTextFigure->getText()); + simpleTextToolEdit->SelectAll(); + } +} + +//Hack to allow use (events) of wxmenu inside a tool Generic Way +void hdDrawingView::setMenuToolFigure(hdAbstractMenuFigure *figure) +{ + menuFigure = figure; + simpleTextFigure = NULL; +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +void hdDrawingView::OnOkTxtButton(wxCommandEvent &event) +{ + _tool->deactivate(this); + simpleTextToolEdit->Hide(); + okTxtButton->Hide(); + cancelTxtButton->Hide(); + setSimpleTextToolFigure(NULL); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +void hdDrawingView::OnCancelTxtButton(wxCommandEvent &event) +{ + simpleTextToolEdit->SetValue(oldText); + _tool->deactivate(this); + simpleTextToolEdit->Hide(); + okTxtButton->Hide(); + cancelTxtButton->Hide(); + setSimpleTextToolFigure(NULL); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event (when text is set at edit it generate this event not sure ????) +void hdDrawingView::simpleTextToolChangeHandler(wxCommandEvent &event) +{ + if(!simpleTextToolEdit->IsModified() && simpleTextFigure) + { + simpleTextFigure->setText(simpleTextToolEdit->GetValue()); + //getFontMetrics + int width, height; + wxWindowDC dc(this); + dc.SetFont(*hdFontAttribute::defaultFont); + if(simpleTextFigure->getText(true).length() > 5) + dc.GetTextExtent(simpleTextFigure->getText(true), &width, &height); + else + dc.GetTextExtent(wxT("EMPTY"), &width, &height); + //recalculateDisplayBox + hdGeometry g; + simpleTextFigure->displayBox().width = g.max(width, 10) + simpleTextFigure->getPadding(); + simpleTextFigure->displayBox().height = g.max(height, 10) + simpleTextFigure->getPadding(); + //calculateSizeEntry + hdPoint p = simpleTextFigure->displayBox().GetPosition(this->diagramIndex); + CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + simpleTextToolEdit->SetPosition(p); + simpleTextToolEdit->SetSize(simpleTextFigure->displayBox().GetSize()); + okTxtButton->SetPosition(wxPoint(p.x + simpleTextToolEdit->GetSize().GetWidth() + 4, p.y)); + cancelTxtButton->SetPosition(wxPoint(okTxtButton->GetPosition().x + okTxtButton->GetSize().GetWidth() + 4, p.y)); + } + else if(!simpleTextFigure) + { + wxMessageDialog *error = new wxMessageDialog(NULL, wxT("Error locating hdSimpleTextTool figure"), wxT("Error!"), wxOK | wxICON_ERROR); + error->ShowModal(); + delete error; + } + event.Skip(); +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +wxTextCtrl *hdDrawingView::getSimpleTextToolEdit() +{ + return simpleTextToolEdit; +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +wxBitmapButton *hdDrawingView::getOkTxt() +{ + return okTxtButton; +} + +//Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event +wxBitmapButton *hdDrawingView::getCancelTxt() +{ + return cancelTxtButton; +} + +//Hack to allow use (events) of wxmenu inside a tool like simpletexttool +void hdDrawingView::OnGenericPopupClick(wxCommandEvent &event) +{ + + if(canvasMenu) + canvasMenu->OnGenericPopupClick(event, this); + else if(menuFigure) + menuFigure->OnGenericPopupClick(event, this); + else if(simpleTextFigure) + simpleTextFigure->OnGenericPopupClick(event, this); + + simpleTextFigure = NULL; + menuFigure = NULL; + canvasMenu = NULL; + + event.Skip(); +} + +//Hack to allow use (events) of wxmenu inside a tool like simpletexttool +void hdDrawingView::connectPopUpMenu(wxMenu &mnu) +{ + // Connect the main menu + mnu.Connect(wxEVT_COMMAND_MENU_SELECTED, + (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &hdDrawingView::OnGenericPopupClick, + NULL, + this); + + // Connect all submenus + wxMenuItem *item; + wxMenuItemList list = mnu.GetMenuItems(); + for (unsigned int index = 0; index < list.GetCount(); index++) + { + wxMenuItemList::compatibility_iterator node = list.Item(index); + item = (wxMenuItem *) node->GetData(); + if (item->IsSubMenu()) + { + wxMenu *submenu = item->GetSubMenu(); + submenu->Connect(wxEVT_COMMAND_MENU_SELECTED, + (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &hdDrawingView::OnGenericPopupClick, + NULL, + this); + } + } +} + +//Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way +void hdDrawingView::setCanvasMenuTool(hdCanvasMenuTool *menuTool) +{ + canvasMenu = menuTool; +} + +hdDrawingEditor *hdDrawingView::editor() +{ + return drawingEditor; +} + +bool hdDrawingView::AcceptsFocus() const +{ + return true; +} + +void hdDrawingView::setTool(hdITool *tool) +{ + if(_tool) + delete _tool; + _tool = tool; +} + +void hdDrawingView::createViewMenu(wxMenu &mnu) +{ + wxMenuItem *item; + item = mnu.AppendCheckItem(1000, _("Sample Item")); + item->Check(true); +} + +void hdDrawingView::OnGenericViewPopupClick(wxCommandEvent &event) +{ + switch(event.GetId()) + { + case 1000: + wxMessageBox(_("Sample menu item"), _("Sample"), wxOK, this); + } +} + +void hdDrawingView::notifyChanged() +{ + drawingEditor->notifyChanged(); +} diff --git a/hotdraw/main/module.mk b/hotdraw/main/module.mk new file mode 100644 index 0000000..40de330 --- /dev/null +++ b/hotdraw/main/module.mk @@ -0,0 +1,18 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/main/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/main/hdDrawing.cpp \ + hotdraw/main/hdDrawingEditor.cpp \ + hotdraw/main/hdDrawingView.cpp + +EXTRA_DIST += \ + hotdraw/main/module.mk diff --git a/hotdraw/module.mk b/hotdraw/module.mk new file mode 100644 index 0000000..bcf99f6 --- /dev/null +++ b/hotdraw/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/ Makefile fragment +# +####################################################################### + +include hotdraw/connectors/module.mk +include hotdraw/figures/module.mk +include hotdraw/handles/module.mk +include hotdraw/locators/module.mk +include hotdraw/main/module.mk +include hotdraw/tools/module.mk +include hotdraw/utilities/module.mk + +EXTRA_DIST += \ + hotdraw/module.mk diff --git a/hotdraw/tools/hdAbstractTool.cpp b/hotdraw/tools/hdAbstractTool.cpp new file mode 100644 index 0000000..c6a89e0 --- /dev/null +++ b/hotdraw/tools/hdAbstractTool.cpp @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractTool.cpp - An abstract tool to allow creation of all tools +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdAbstractTool.h" + +hdAbstractTool::hdAbstractTool(hdDrawingView *view) +{ + anchorX = 0; + anchorY = 0; + ownerView = view; +} + +hdAbstractTool::~hdAbstractTool() +{ +} + +void hdAbstractTool::mouseDown(hdMouseEvent &event) +{ + setAnchorCoords(event.GetPosition().x, event.GetPosition().y); +} + +void hdAbstractTool::mouseUp(hdMouseEvent &event) +{ +} + +void hdAbstractTool::mouseMove(hdMouseEvent &event) +{ +} + +void hdAbstractTool::mouseDrag(hdMouseEvent &event) +{ +} + +void hdAbstractTool::keyDown(hdKeyEvent &event) +{ +// setAnchorCoords(event.GetPosition().x,event.GetPosition().y); +} + +void hdAbstractTool::keyUp(hdKeyEvent &event) +{ +} + +void hdAbstractTool::setAnchorCoords(int x, int y) +{ + anchorX = x; + anchorY = y; +} + +hdDrawingView *hdAbstractTool::getDrawingView() +{ + return ownerView; +} + diff --git a/hotdraw/tools/hdCanvasMenuTool.cpp b/hotdraw/tools/hdCanvasMenuTool.cpp new file mode 100644 index 0000000..826ef8b --- /dev/null +++ b/hotdraw/tools/hdCanvasMenuTool.cpp @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCanvasMenuTool.cpp - Allow to set up a menu at main canvas in case of not finding a tool or handle that manages an event +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdCanvasMenuTool.h" + +class hdDrawingEditor; + +hdCanvasMenuTool::hdCanvasMenuTool(hdDrawingView *view, hdITool *dt): + hdAbstractTool(view) +{ + defaultTool = dt; + ownerView->setCanvasMenuTool(NULL); +} + +hdCanvasMenuTool::~hdCanvasMenuTool() +{ + ownerView->setCanvasMenuTool(NULL); + if(defaultTool) + delete defaultTool; +} + +void hdCanvasMenuTool::mouseDown(hdMouseEvent &event) +{ + //Linux hack for bug + int x = event.GetPosition().x, y = event.GetPosition().y; + setAnchorCoords(x, y); + + if(event.RightDown()) + { + wxMenu menu; + event.getView()->setCanvasMenuTool(this); + createViewMenu(event.getView(), menu); + event.getView()->connectPopUpMenu(menu); + hdPoint p = event.GetPosition(); + event.getView()->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + event.getView()->PopupMenu(&menu, p); + return; + } + + defaultTool->mouseDown(event); +} + +void hdCanvasMenuTool::mouseDrag(hdMouseEvent &event) +{ + defaultTool->mouseDrag(event); +} + +void hdCanvasMenuTool::mouseUp(hdMouseEvent &event) +{ + defaultTool->mouseUp(event); +} + +void hdCanvasMenuTool::mouseMove(hdMouseEvent &event) +{ + defaultTool->mouseMove(event); +} + +void hdCanvasMenuTool::createViewMenu(hdDrawingView *view, wxMenu &mnu) +{ + view->createViewMenu(mnu); +} + +void hdCanvasMenuTool::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + view->OnGenericViewPopupClick(event); +} diff --git a/hotdraw/tools/hdCompositeFigureTool.cpp b/hotdraw/tools/hdCompositeFigureTool.cpp new file mode 100644 index 0000000..3c39b59 --- /dev/null +++ b/hotdraw/tools/hdCompositeFigureTool.cpp @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigureTool.cpp - A Tool that allow to change between all tools in a composite figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdCompositeFigureTool.h" +#include "hotdraw/figures/hdCompositeFigure.h" + + +hdCompositeFigureTool::hdCompositeFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ + delegateTool = NULL; +} + +hdCompositeFigureTool::~hdCompositeFigureTool() +{ + hdITool *tmpDefault = hdFigureTool::getDefaultTool(); + hdFigureTool *tmpDelegateDefault; + + if(delegateTool->ms_classInfo.IsKindOf(&hdFigureTool::ms_classInfo)) + tmpDelegateDefault = (hdFigureTool *)delegateTool; + else + tmpDelegateDefault = NULL; + + if(delegateTool && delegateTool != tmpDefault) + { + // Hack to avoid delete defaultTool (Delegate->defaultTool) of delegate tool + // if this is the same as defaultTool (this->defaultTool) of this Object. + if(tmpDelegateDefault && tmpDelegateDefault->getDefaultTool() == tmpDefault) + tmpDelegateDefault->setDefaultTool(NULL); + delete delegateTool; + } +} + +void hdCompositeFigureTool::setDefaultTool(hdITool *dt) +{ + hdFigureTool::setDefaultTool(dt); +} + +hdITool *hdCompositeFigureTool::getDefaultTool() +{ + if(delegateTool) + { + return delegateTool; + } + else + { + return hdFigureTool::getDefaultTool(); + } +} + +void hdCompositeFigureTool::mouseDown(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdCompositeFigure *cfigure = (hdCompositeFigure *) getFigure(); + hdIFigure *figure = cfigure->findFigure(event.getView()->getIdx(), x, y); + + if(figure) + { + setDelegateTool(event.getView(), figure->CreateFigureTool(event.getView(), getDefaultTool())); + } + else + { + setDelegateTool(event.getView(), getDefaultTool()); + } + + if(delegateTool) + { + delegateTool->mouseDown(event); + } +} + +void hdCompositeFigureTool::activate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->activate(view); + } +} + +void hdCompositeFigureTool::deactivate(hdDrawingView *view) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + } +} + +void hdCompositeFigureTool::setDelegateTool(hdDrawingView *view, hdITool *tool) +{ + if(delegateTool) + { + delegateTool->deactivate(view); + delete delegateTool; + delegateTool = NULL; + } + + delegateTool = tool; + if(delegateTool) + { + delegateTool->activate(view); + } +} + +hdITool *hdCompositeFigureTool::getDelegateTool() +{ + return delegateTool; +} diff --git a/hotdraw/tools/hdConnectionCreationTool.cpp b/hotdraw/tools/hdConnectionCreationTool.cpp new file mode 100644 index 0000000..ceb749f --- /dev/null +++ b/hotdraw/tools/hdConnectionCreationTool.cpp @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdConnectionCreationTool.cpp - A Tool that allow to create a connection figure between two figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdConnectionCreationTool.h" +#include "hotdraw/tools/hdSelectionTool.h" +#include "hotdraw/main/hdDrawingView.h" + +hdConnectionCreationTool::hdConnectionCreationTool(hdDrawingView *view, hdLineConnection *figure): + hdAbstractTool(view) +{ + toolConnection = figure; + toolConnection->disconnectStart(); + toolConnection->disconnectEnd(); + handle = NULL; + numClicks = 0; + dragged = false; +} + +hdConnectionCreationTool::~hdConnectionCreationTool() +{ +} + +void hdConnectionCreationTool::mouseDrag(hdMouseEvent &event) +{ + if(handle && event.LeftIsDown()) + { + dragged = true; + handle->invokeStep(event, event.getView()); + } +} + +void hdConnectionCreationTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + if(event.LeftDown()) + { + numClicks++; + int x = event.getScrolledPosX(), y = event.getScrolledPosY(); + hdDrawingView *view = event.getView(); + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + + if(figure) + { + if(numClicks == 1) //first mouse click to select start/end figure + { + toolConnection->setEndPoint(view->getIdx(), hdPoint(x, y)); + toolConnection->setStartPoint(view->getIdx(), hdPoint(x, y)); + toolConnection->connectStart(figure->connectorAt(view->getIdx(), x, y)); + toolConnection->updateConnection(view->getIdx()); + view->editor()->addDiagramFigure(view->getIdx(), toolConnection); + view->getDrawing()->clearSelection(); + view->getDrawing()->addToSelection(toolConnection); + handle = toolConnection->getEndHandle(); + } + else if(numClicks > 1) //second mouse click to select end figure only + { + toolConnection->setEndPoint(view->getIdx(), hdPoint(x, y)); + toolConnection->updateConnection(event.getView()->getIdx()); + } + } + else + { + event.getView()->setTool(new hdSelectionTool(event.getView())); + } + } +} + +void hdConnectionCreationTool::mouseUp(hdMouseEvent &event) +{ + if(event.LeftUp()) + { + //Hack to allow one click and drag creation of connections + if(handle) + { + if(!dragged && numClicks == 1) //mouse haven't be dragged and is first click of mouse at this tool + { + toolConnection->setEndPoint(event.getView()->getIdx(), event.GetPosition()); + toolConnection->updateConnection(event.getView()->getIdx()); + } + else + { + handle->invokeEnd(event, event.getView()); + } + } + + if((toolConnection->getEndConnector() == NULL && numClicks > 1) || (toolConnection->getEndConnector() == NULL && dragged)) //Delete connection only if a second click a connection figures isn't found + { + //check if exists at drawing because automatically integrity check + if(event.getView()->getDrawing()->includes(toolConnection)) + event.getView()->getDrawing()->remove(toolConnection); + event.getView()->getDrawing()->clearSelection(); + toolConnection->disconnectStart(); + toolConnection->disconnectEnd(); + event.getView()->editor()->deleteModelFigure(toolConnection); + } + } + if(dragged || numClicks > 1) //if drag to select a figure or is second or higher click (to select end figure) then this tool ends. + { + event.getView()->setTool(new hdSelectionTool(event.getView())); + } + else if(!dragged && numClicks == 1) //if not dragged before and is first click then allow to select end, disconnecting it + { + toolConnection->disconnectEnd(); + } + +} + +void hdConnectionCreationTool::mouseMove(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + hdDrawingView *view = event.getView(); + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + if(figure) + { + view->SetCursor(wxCursor(wxCURSOR_PENCIL)); + } + else + { + view->SetCursor(wxCursor(wxCURSOR_CROSS)); + } + + if(toolConnection && handle && numClicks > 0) + { + handle->invokeStep(event, view); + } +} diff --git a/hotdraw/tools/hdCreationTool.cpp b/hotdraw/tools/hdCreationTool.cpp new file mode 100644 index 0000000..31f5020 --- /dev/null +++ b/hotdraw/tools/hdCreationTool.cpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCreationTool.cpp - A Tool that create a figure by just click on view +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdCreationTool.h" +#include "hotdraw/tools/hdSelectionTool.h" + +hdCreationTool::hdCreationTool(hdDrawingView *view, hdIFigure *prototype): + hdAbstractTool(view) +{ + figurePrototype = prototype; +} + +hdCreationTool::~hdCreationTool() +{ +} + +void hdCreationTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + if(event.LeftDown()) + { + event.getView()->getDrawing()->add(figurePrototype); + int x = event.GetPosition().x, y = event.GetPosition().y; + figurePrototype->moveTo(event.getView()->getIdx(), x, y); + event.getView()->getDrawing()->clearSelection(); + event.getView()->getDrawing()->addToSelection(figurePrototype); + } +} + +void hdCreationTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); + event.getView()->setTool(new hdSelectionTool(event.getView())); +} + +void hdCreationTool::activate(hdDrawingView *view) +{ + hdAbstractTool::activate(view); + view->SetCursor(wxCursor(wxCURSOR_CROSS)); +} + +void hdCreationTool::deactivate(hdDrawingView *view) +{ + hdAbstractTool::deactivate(view); + view->SetCursor(wxCursor(wxCURSOR_ARROW)); +} + +void hdCreationTool::setPrototype(hdIFigure *prototype) +{ + figurePrototype = prototype; +} + +hdIFigure *hdCreationTool::getPrototype() +{ + return figurePrototype; +} diff --git a/hotdraw/tools/hdDragCreationTool.cpp b/hotdraw/tools/hdDragCreationTool.cpp new file mode 100644 index 0000000..c15afe3 --- /dev/null +++ b/hotdraw/tools/hdDragCreationTool.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragCreationTool.cpp - A Tool that allow to move figure around view +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdDragCreationTool.h" + +hdDragCreationTool::hdDragCreationTool(hdDrawingView *view, hdIFigure *prototype): + hdCreationTool(view, prototype) +{ +} + +hdDragCreationTool::~hdDragCreationTool() +{ +} + + +void hdDragCreationTool::mouseDrag(hdMouseEvent &event) +{ + if(event.LeftIsDown()) + { + figurePrototype->displayBox().SetPosition(event.getView()->getIdx(), event.GetPosition()); + } +} diff --git a/hotdraw/tools/hdDragTrackerTool.cpp b/hotdraw/tools/hdDragTrackerTool.cpp new file mode 100644 index 0000000..b8c3722 --- /dev/null +++ b/hotdraw/tools/hdDragTrackerTool.cpp @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragTrackerTool.cpp - A Tool that allow to drag and drop figures at the view +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdDragTrackerTool.h" +#include "hotdraw/tools/hdAbstractTool.h" + +hdDragTrackerTool::hdDragTrackerTool(hdDrawingView *view, hdIFigure *anchor) + : hdAbstractTool(view) +{ + hasMovedValue = false; + anchorFigure = anchor; +} + +hdDragTrackerTool::~hdDragTrackerTool() +{ +} + +void hdDragTrackerTool::setLastCoords(int x, int y) +{ + lastX = x; + lastY = y; +} + +void hdDragTrackerTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + + if(event.LeftDown()) + { + int x = event.GetPosition().x, y = event.GetPosition().y; + + setLastCoords(x, y); + + if(event.m_shiftDown) + { + event.getView()->getDrawing()->toggleSelection(anchorFigure); + } + else if(!event.getView()->getDrawing()->isFigureSelected(anchorFigure)) + { + event.getView()->getDrawing()->clearSelection(); + event.getView()->getDrawing()->addToSelection(anchorFigure); + } + } +} + +void hdDragTrackerTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); +} + +void hdDragTrackerTool::mouseDrag(hdMouseEvent &event) +{ + hdAbstractTool::mouseDrag(event); + + if(event.LeftIsDown()) + { + int x = event.GetPosition().x, y = event.GetPosition().y; + + //Hack to avoid a weird bug that ocurrs when use double click very fast over figure and drag a same time, lastX + //and lastY values becomes big negatives numbers, if this happens, then reset it to click point + if(lastX < 0) + lastX = x; + if(lastY < 0) + lastY = y; + + hasMovedValue = (abs (x - anchorX) > 4 || abs (y - anchorX) > 4); + + if (hasMoved()) + { + hdIFigure *tmp = NULL; + hdIteratorBase *iterator = event.getView()->getDrawing()->selectionFigures(); + while(iterator->HasNext()) + { + tmp = (hdIFigure *)iterator->Next(); + tmp->moveBy(event.getView()->getIdx(), x - lastX, y - lastY); + event.getView()->notifyChanged(); + } + delete iterator; + } + setLastCoords (x, y); + } +} + +bool hdDragTrackerTool::hasMoved() +{ + return hasMovedValue; +} diff --git a/hotdraw/tools/hdFigureTool.cpp b/hotdraw/tools/hdFigureTool.cpp new file mode 100644 index 0000000..73c0adf --- /dev/null +++ b/hotdraw/tools/hdFigureTool.cpp @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFigureTool.cpp - Base class for all figure tools +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdFigureTool.h" + +hdFigureTool::hdFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdAbstractTool(view) +{ + defaultTool = dt; + figure = fig; +} + +hdFigureTool::~hdFigureTool() +{ + if(defaultTool) + { + delete defaultTool; + } +} + +void hdFigureTool::setDefaultTool(hdITool *dt) +{ + defaultTool = dt; +} + +hdITool *hdFigureTool::getDefaultTool() +{ + return defaultTool; +} + +void hdFigureTool::setFigure(hdIFigure *fig) +{ + figure = fig; +} + +hdIFigure *hdFigureTool::getFigure() +{ + return figure; +} + +void hdFigureTool::mouseDown(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseDown(event); + } +} + +void hdFigureTool::mouseUp(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseUp(event); + } +} + +void hdFigureTool::mouseMove(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseMove(event); + } +} + +void hdFigureTool::mouseDrag(hdMouseEvent &event) +{ + if(defaultTool) + { + defaultTool->mouseDrag(event); + } +} + +void hdFigureTool::keyDown(hdKeyEvent &event) +{ + if(defaultTool) + { + defaultTool->keyDown(event); + } +} + +void hdFigureTool::keyUp(hdKeyEvent &event) +{ + if(defaultTool) + { + defaultTool->keyUp(event); + } +} diff --git a/hotdraw/tools/hdHandleTrackerTool.cpp b/hotdraw/tools/hdHandleTrackerTool.cpp new file mode 100644 index 0000000..62d46d3 --- /dev/null +++ b/hotdraw/tools/hdHandleTrackerTool.cpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdHandleTrackerTool.cpp - A Tool that allow to use multiple handles +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdHandleTrackerTool.h" +#include "hotdraw/tools/hdAbstractTool.h" + +hdHandleTrackerTool::hdHandleTrackerTool(hdDrawingView *view, hdIHandle *anchor) + : hdAbstractTool(view) +{ + anchorHandle = anchor; +} + +hdHandleTrackerTool::~hdHandleTrackerTool() +{ +} + +void hdHandleTrackerTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + anchorHandle->invokeStart(event, event.getView()); +} + +void hdHandleTrackerTool::mouseUp(hdMouseEvent &event) +{ + anchorHandle->invokeEnd(event, event.getView()); +} + +void hdHandleTrackerTool::mouseDrag(hdMouseEvent &event) +{ + anchorHandle->invokeStep(event, event.getView()); +} diff --git a/hotdraw/tools/hdITool.cpp b/hotdraw/tools/hdITool.cpp new file mode 100644 index 0000000..75fff6c --- /dev/null +++ b/hotdraw/tools/hdITool.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdITool.cpp - Base class for all tools +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/utilities/hdMouseEvent.h" + +hdITool::hdITool() +{ + activatedValue = false; + undoableValue = false; +} + +hdITool::~hdITool() +{ +} + +void hdITool::mouseDown(hdMouseEvent &event) +{ + /* + EVT_LEFT_DOWN(func) + EVT_MIDDLE_DOWN(func) + EVT_RIGHT_DOWN(func) + EVT_LEFT_DCLICK(func) + */ +} + +void hdITool::mouseUp(hdMouseEvent &event) +{ + /* + EVT_LEFT_UP(func) + EVT_MIDDLE_UP(func) + EVT_RIGHT_UP(func) + EVT_RIGHT_DCLICK(func) + */ +} + +void hdITool::mouseMove(hdMouseEvent &event) +{ + /* + EVT_MOTION(func) + */ +} + +void hdITool::mouseDrag(hdMouseEvent &event) +{ + /* + When a mouse is dragged this returns true: event.Dragging() + */ +} + +void hdITool::keyDown(hdKeyEvent &event) +{ + /* + setAnchorCoords(event.GetPosition().x,event.GetPosition().y); + */ +} + +void hdITool::keyUp(hdKeyEvent &event) +{ +} + +void hdITool::activate(hdDrawingView *view) +{ + activatedValue = true; +} + +void hdITool::deactivate(hdDrawingView *view) +{ + activatedValue = false; +} + +bool hdITool::activated() +{ + return activatedValue; +} + +bool hdITool::undoable() +{ + return undoableValue; +} diff --git a/hotdraw/tools/hdMenuTool.cpp b/hotdraw/tools/hdMenuTool.cpp new file mode 100644 index 0000000..b139d38 --- /dev/null +++ b/hotdraw/tools/hdMenuTool.cpp @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMenuTool.cpp - Allow Edition of textTool (double click) or show a menu to modifiy in someway text (right click) a figure. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdMenuTool.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdDrawingEditor; + +hdMenuTool::hdMenuTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ + menuFigure = (hdAbstractMenuFigure *) this->getFigure(); + ownerView->setMenuToolFigure(NULL); +} + +hdMenuTool::~hdMenuTool() +{ +} + +void hdMenuTool::mouseDown(hdMouseEvent &event) +{ + //Linux hack for bug + int x = event.GetPosition().x, y = event.GetPosition().y; + setAnchorCoords(x, y); + + if(menuFigure->menuEnabled() && event.RightDown()) + { + wxMenu menu; + event.getView()->setMenuToolFigure(menuFigure); + menuFigure->createMenu(menu); + event.getView()->connectPopUpMenu(menu); + hdPoint p = event.GetPosition(); + event.getView()->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + event.getView()->PopupMenu(&menu, p); + return; + } + + getDefaultTool()->mouseDown(event); +} + +void hdMenuTool::activate(hdDrawingView *view) +{ + hdFigureTool::activate(view); +} + +void hdMenuTool::deactivate(hdDrawingView *view) +{ + hdFigureTool::deactivate(view); +} + +void hdMenuTool::mouseDrag(hdMouseEvent &event) +{ + getDefaultTool()->mouseDrag(event); +} + +void hdMenuTool::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + menuFigure->OnGenericPopupClick(event, view); +} diff --git a/hotdraw/tools/hdPolyLineFigureTool.cpp b/hotdraw/tools/hdPolyLineFigureTool.cpp new file mode 100644 index 0000000..5f698e9 --- /dev/null +++ b/hotdraw/tools/hdPolyLineFigureTool.cpp @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigureTool.cpp - Tool to allow creation of flexibility points at polylines figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdPolyLineFigureTool.h" +#include "hotdraw/tools/hdFigureTool.h" +#include "hotdraw/tools/hdHandleTrackerTool.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/tools/hdMenuTool.h" + +hdPolyLineFigureTool::hdPolyLineFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt): + hdFigureTool(view, fig, dt) +{ +} + +hdPolyLineFigureTool::~hdPolyLineFigureTool() +{ +} + +void hdPolyLineFigureTool::mouseDown(hdMouseEvent &event) +{ + int x = event.GetPosition().x, y = event.GetPosition().y; + setAnchorCoords(x, y); + //Other events like other mouse button click (no left double click) should be done at handle + //because this tool only add flexibility points to polylines. + if(event.LeftDClick()) + { + hdPolyLineFigure *connection = (hdPolyLineFigure *) figure; + connection->splitSegment(event.getView()->getIdx(), x, y); + event.getView()->getDrawing()->clearSelection(); + event.getView()->getDrawing()->addToSelection(figure); + hdIHandle *handle = event.getView()->findHandle(event.getView()->getIdx(), x, y); + event.getView()->SetCursor(handle->createCursor()); + if(defaultTool) + delete defaultTool; + defaultTool = new hdHandleTrackerTool(event.getView(), handle); + event.getView()->notifyChanged(); + } + defaultTool->mouseDown(event); +} diff --git a/hotdraw/tools/hdSelectAreaTool.cpp b/hotdraw/tools/hdSelectAreaTool.cpp new file mode 100644 index 0000000..c3263cd --- /dev/null +++ b/hotdraw/tools/hdSelectAreaTool.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectAreaTool.cpp - Tool to allow selection of figures inside a rectangle +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdSelectAreaTool.h" +#include "hotdraw/tools/hdAbstractTool.h" +#include "hotdraw/utilities/hdGeometry.h" + + +hdSelectAreaTool::hdSelectAreaTool(hdDrawingView *view) + : hdAbstractTool(view) +{ +} + +hdSelectAreaTool::~hdSelectAreaTool() +{ +} + +void hdSelectAreaTool::mouseDown(hdMouseEvent &event) +{ + hdAbstractTool::mouseDown(event); + if(!event.ShiftDown()) + { + event.getView()->getDrawing()->clearSelection(); + } + if(event.LeftDown()) + { + int x = event.GetPosition().x, y = event.GetPosition().y; + selectionRect.x = x; + selectionRect.y = y; + selectionRect.width = 0; + selectionRect.height = 0; + drawSelectionRect(event.getView()); + } +} + +void hdSelectAreaTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); + hdGeometry g; + //hack-fix for bug when selecting figures from right to left + if(event.LeftUp()) + { + if( selectionRect.width < 0 ) + { + int tmp; + tmp = selectionRect.width; + selectionRect.x += tmp; + selectionRect.width = g.ddabs(tmp); + + } + if( selectionRect.height < 0 ) + { + int tmp; + tmp = selectionRect.height; + selectionRect.y += tmp; + selectionRect.height = g.ddabs(tmp); + } + //end hack-fix + drawSelectionRect(event.getView()); + selectFiguresOnRect(event.ShiftDown(), event.getView()); + event.getView()->disableSelRectDraw(); + } +} + +void hdSelectAreaTool::mouseDrag(hdMouseEvent &event) +{ + hdAbstractTool::mouseDrag(event); + if(event.LeftIsDown()) + { + drawSelectionRect(event.getView()); + int x = event.GetPosition().x, y = event.GetPosition().y; + selectionRect.x = anchorX; + selectionRect.y = anchorY; + selectionRect.SetBottomRight(wxPoint(x, y)); + drawSelectionRect(event.getView()); + event.getView()->ScrollToMakeVisible(event.GetPosition()); + } +} + +void hdSelectAreaTool::selectFiguresOnRect(bool shiftPressed, hdDrawingView *view) +{ + hdIFigure *figure; + hdIteratorBase *iterator = view->getDrawing()->figuresInverseEnumerator(); + while(iterator->HasNext()) + { + figure = (hdIFigure *)iterator->Next(); + if(selectionRect.Contains(figure->displayBox().gethdRect(view->getIdx()))) + { + if(shiftPressed) + { + view->getDrawing()->toggleSelection(figure); + } + else + { + view->getDrawing()->addToSelection(figure); + } + } + } + delete iterator; +} + +void hdSelectAreaTool::drawSelectionRect(hdDrawingView *view) +{ + view->setSelRect(selectionRect); +} + diff --git a/hotdraw/tools/hdSelectionTool.cpp b/hotdraw/tools/hdSelectionTool.cpp new file mode 100644 index 0000000..862e164 --- /dev/null +++ b/hotdraw/tools/hdSelectionTool.cpp @@ -0,0 +1,161 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectionTool.cpp - Tool to allow selection of figures +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/tools/hdSelectionTool.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdHandleTrackerTool.h" +#include "hotdraw/tools/hdDragTrackerTool.h" +#include "hotdraw/tools/hdSelectAreaTool.h" +#include "hotdraw/tools/hdCanvasMenuTool.h" + + +class hdDrawingView; +class hdDrawingEditor; + +hdSelectionTool::hdSelectionTool(hdDrawingView *owner): + hdAbstractTool(owner) +{ + _delegateTool = NULL; +} + +hdSelectionTool::~hdSelectionTool() +{ + if(_delegateTool) + delete _delegateTool; +} + +void hdSelectionTool::mouseDown(hdMouseEvent &event) +{ + hdITool::mouseDown(event); + + hdDrawingView *view = event.getView(); + int x = event.GetPosition().x, y = event.GetPosition().y; + + hdIHandle *handle = view->findHandle(view->getIdx(), x, y); + if(handle) + { + setDelegateTool(view, new hdHandleTrackerTool(view, handle)); + } + else + { + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + if(figure) + { + view->getDrawing()->bringToFront(figure); + setDelegateTool(event.getView(), figure->CreateFigureTool(view, new hdDragTrackerTool(view, figure))); + } + else + { + setDelegateTool(event.getView(), new hdCanvasMenuTool(view, new hdSelectAreaTool(view)) ); + } + } + + hdITool *delegateTool = getDelegateTool(); + if (delegateTool) + delegateTool->mouseDown(event); +} + +void hdSelectionTool::mouseUp(hdMouseEvent &event) +{ + hdAbstractTool::mouseUp(event); + hdITool *delegateTool = getDelegateTool(); + if (delegateTool) + delegateTool->mouseUp(event); +} + +void hdSelectionTool::mouseMove(hdMouseEvent &event) +{ + hdAbstractTool::mouseMove(event); + hdDrawingView *view = event.getView(); + int x = event.GetPosition().x, y = event.GetPosition().y; + hdIHandle *handle = view->findHandle(view->getIdx(), x, y); + + if(handle) + { + view->SetCursor(handle->createCursor()); + } + else + { + hdIFigure *figure = view->getDrawing()->findFigure(view->getIdx(), x, y); + if(figure) + { + view->SetCursor(wxCursor(wxCURSOR_HAND)); + } + else + { + view->SetCursor(wxCursor(wxCURSOR_ARROW)); + } + } +} + +void hdSelectionTool::mouseDrag(hdMouseEvent &event) +{ + hdAbstractTool::mouseDrag(event); + hdITool *delegateTool = getDelegateTool(); + if (delegateTool) + delegateTool->mouseDrag(event); +} + +void hdSelectionTool::keyDown(hdKeyEvent &event) +{ + if(getDelegateTool()) + { + getDelegateTool()->keyDown(event); + } + if(event.GetKeyCode() == WXK_DELETE) + { + event.getView()->getDrawing()->deleteSelectedFigures(); + } +} + +void hdSelectionTool::keyUp(hdKeyEvent &event) +{ + if(getDelegateTool()) + { + getDelegateTool()->keyUp(event); + } +} + +void hdSelectionTool::setDelegateTool(hdDrawingView *view, hdITool *tool) +{ + if(_delegateTool) + { + _delegateTool->deactivate(view); + delete _delegateTool; + } + + _delegateTool = tool; + + if(_delegateTool) + { + _delegateTool->activate(view); + } +} + +hdITool *hdSelectionTool::getDelegateTool() +{ + return _delegateTool; +} + +void hdSelectionTool::deleteAllFigures(hdDrawingView *view) +{ + view->getDrawing()->clearSelection(); + view->getDrawing()->deleteAllFigures(); +} + diff --git a/hotdraw/tools/hdSimpleTextTool.cpp b/hotdraw/tools/hdSimpleTextTool.cpp new file mode 100644 index 0000000..51256c7 --- /dev/null +++ b/hotdraw/tools/hdSimpleTextTool.cpp @@ -0,0 +1,139 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextTool.cpp - Tool to allow edition of textTool with a double click or show a menu with a right click. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include + +// App headers +#include "hotdraw/tools/hdSimpleTextTool.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" + +class hdDrawingEditor; + +hdSimpleTextTool::hdSimpleTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit , wxString dialogCaption, wxString dialogMessage): + hdFigureTool(view, fig, dt) +{ + dlgMessage = dialogMessage; + dlgCaption = dialogCaption; + withoutDialog = fastEdit; + showEdit = false; + txtFigure = ((hdSimpleTextFigure *)this->getFigure()); + ownerView->setSimpleTextToolFigure(NULL); + + calculateSizeEntry(ownerView); +} + +hdSimpleTextTool::~hdSimpleTextTool() +{ +} + +void hdSimpleTextTool::calculateSizeEntry(hdDrawingView *view) +{ + if(view->getSimpleTextToolEdit()) + { + hdPoint p = txtFigure->displayBox().GetPosition(view->getIdx()); + view->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + view->getSimpleTextToolEdit()->SetPosition(p); + view->getSimpleTextToolEdit()->SetSize(txtFigure->displayBox().GetSize()); + view->getOkTxt()->SetPosition(wxPoint(p.x + view->getSimpleTextToolEdit()->GetSize().GetWidth() + 4, p.y)); + view->getCancelTxt()->SetPosition(wxPoint(view->getOkTxt()->GetPosition().x + view->getOkTxt()->GetSize().GetWidth() + 4, p.y)); + //Right now implemented with a hack (function at main view), but source of bug, probably can be tracked. + } +} + +void hdSimpleTextTool::mouseDown(hdMouseEvent &event) +{ + setAnchorCoords(event.GetPosition().x, event.GetPosition().y); + + // Right click to get the contextual menu + if(txtFigure->menuEnabled() && event.RightDown()) + { + wxMenu menu; + event.getView()->setSimpleTextToolFigure(txtFigure, true); + txtFigure->createMenu(menu); + event.getView()->connectPopUpMenu(menu); + hdPoint p = event.GetPosition(); + event.getView()->CalcScrolledPosition(p.x, p.y, &p.x, &p.y); + event.getView()->PopupMenu(&menu, p); + return; + } + + // Double click to rename an object + if(event.LeftDClick()) + { + if(withoutDialog) + { + event.getView()->setSimpleTextToolFigure(txtFigure); + showEdit = true; + event.getView()->getSimpleTextToolEdit()->ChangeValue(txtFigure->getText()); //Same as SetValue but don't generated wxEVT_COMMAND_TEXT_UPDATED event + calculateSizeEntry(event.getView()); + event.getView()->getSimpleTextToolEdit()->SetFocus(); + event.getView()->getSimpleTextToolEdit()->Show(); + event.getView()->getOkTxt()->Show(); + event.getView()->getCancelTxt()->Show(); + } + else + { + callDialog(event.getView()); + } + return; + } + getDefaultTool()->mouseDown(event); +} + +void hdSimpleTextTool::activate(hdDrawingView *view) +{ + showEdit = false; + hdFigureTool::activate(view); +} + +void hdSimpleTextTool::deactivate(hdDrawingView *view) +{ + if(view->getSimpleTextToolEdit()) + { + // Can't delete this objects because view is the owner of this objects + view->getSimpleTextToolEdit()->Hide(); + view->getOkTxt()->Hide(); + view->getCancelTxt()->Hide(); + view->setSimpleTextToolFigure(NULL); + } + hdFigureTool::deactivate(view); +} + +void hdSimpleTextTool::mouseDrag(hdMouseEvent &event) +{ + if(!showEdit) + { + getDefaultTool()->mouseDrag(event); + } +} + +void hdSimpleTextTool::OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view) +{ + txtFigure->OnGenericPopupClick(event, view); +} + +bool hdSimpleTextTool::callDialog(hdDrawingView *view) +{ + wxString sNewValue = wxGetTextFromUser(dlgMessage, dlgCaption, txtFigure->getText(), view); + if (!sNewValue.IsEmpty()) + { + txtFigure->setText(sNewValue); + view->notifyChanged(); + return true; + } + else + return false; +} diff --git a/hotdraw/tools/module.mk b/hotdraw/tools/module.mk new file mode 100644 index 0000000..a17914d --- /dev/null +++ b/hotdraw/tools/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/tools/hdAbstractTool.cpp \ + hotdraw/tools/hdCanvasMenuTool.cpp \ + hotdraw/tools/hdCompositeFigureTool.cpp \ + hotdraw/tools/hdConnectionCreationTool.cpp \ + hotdraw/tools/hdCreationTool.cpp \ + hotdraw/tools/hdDragCreationTool.cpp \ + hotdraw/tools/hdDragTrackerTool.cpp \ + hotdraw/tools/hdFigureTool.cpp \ + hotdraw/tools/hdHandleTrackerTool.cpp \ + hotdraw/tools/hdITool.cpp \ + hotdraw/tools/hdMenuTool.cpp \ + hotdraw/tools/hdPolyLineFigureTool.cpp \ + hotdraw/tools/hdSelectAreaTool.cpp \ + hotdraw/tools/hdSelectionTool.cpp \ + hotdraw/tools/hdSimpleTextTool.cpp + +EXTRA_DIST += \ + hotdraw/tools/module.mk diff --git a/hotdraw/utilities/hdArrayCollection.cpp b/hotdraw/utilities/hdArrayCollection.cpp new file mode 100644 index 0000000..0156a9c --- /dev/null +++ b/hotdraw/utilities/hdArrayCollection.cpp @@ -0,0 +1,221 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdArrayCollection.cpp - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/main/hdObject.h" + +// Destructor +hdArrayCollection::~hdArrayCollection() +{ + WX_CLEAR_ARRAY(ddArray); +} + +// Add item to array +void hdArrayCollection::addItem(hdObject *item) +{ + ddArray.Add(item); +} + +// Remove item from array but don't delete it. +void hdArrayCollection::removeItem(hdObject *item) +{ + ddArray.Remove(item); +} + +void hdArrayCollection::removeItemAt(int index) +{ + ddArray.RemoveAt(index); +} + +// Create an iterator for the objects inside the array +hdIteratorBase *hdArrayCollection::createIterator() +{ + return (new hdArrayIterator(&ddArray)); +} + +// Create a Down to iterator for the objects inside the array +hdIteratorBase *hdArrayCollection::createDownIterator() +{ + return (new hdArrayDownIterator(&ddArray)); +} + +// Return the number of elements inside the array +int hdArrayCollection::count() +{ + return ddArray.Count(); +} + +// Return true if an element pointer is found inside array +bool hdArrayCollection::existsObject(hdObject *item) +{ + hdObject *found = NULL; + int size = ddArray.GetCount(); + for(int i = 0; i < size; i++) + { + if (ddArray.Item(i) == item) + { + found = ddArray.Item(i); + break; + } + } + return (found != NULL); +} + +// Delete all elements inside array +void hdArrayCollection::deleteAll() +{ + WX_CLEAR_ARRAY(ddArray); +} + +// Removes all elements inside array without deleting +void hdArrayCollection::removeAll() +{ + ddArray.Empty(); +} + +// Get Item at certain position at Collection +hdObject *hdArrayCollection::getItemAt(int index) +{ + if(!ddArray.IsEmpty()) + return ddArray[index]; + else + return NULL; +} + +//Bring item to start of array +void hdArrayCollection::bringToFront(hdObject *item) +{ + hdObject *tmp = ddArray[0]; + int index = getIndex(item); + ddArray[0] = ddArray[index]; + ddArray[index] = tmp; +} + +//Bring item to end of array +void hdArrayCollection::sendToBack(hdObject *item) +{ + int end = count() - 1; + hdObject *tmp = ddArray[end]; + int index = getIndex(item); + ddArray[end] = ddArray[index]; + ddArray[index] = tmp; +} + + +int hdArrayCollection::getIndex(hdObject *item) +{ + return ddArray.Index(item); +} + +// Insert item into the array before the index +void hdArrayCollection::insertAtIndex(hdObject *item, int index) +{ + ddArray.Insert(item, index); +} + +// Replace item into the array at index (if overwrite user should delete manually previous object at index) +void hdArrayCollection::replaceAtIndex(hdObject *item, int index) +{ + ddArray.RemoveAt(index); + ddArray.Insert(item, index); +} + + +// +// hdArrayIterator - Manages iterator for the array collection concrete class, from first to last element +// + + +// Constructor +hdArrayIterator::hdArrayIterator(ddObjsArray *ddPtrsArray) +{ + position = 0; + internalArray = ddPtrsArray; +} + +// Get current item in the array for the iterator +hdObject *hdArrayIterator::Current() +{ + hdObject *obj = internalArray->Item(position); + return obj; +} + +// Get next item in the array for the iterator +hdObject *hdArrayIterator::Next() +{ + hdObject *obj = internalArray->Item(position); + position++; + return obj; +} + +// Return true if the array has more elements to return +bool hdArrayIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1)) ) + return true; + else + return false; +} + +void hdArrayIterator::ResetIterator() +{ + position = 0; +} + + +// +// hdArrayDownIterator - Manages iterator for the array collection concrete class from last to first element +// + + +// Constructor +hdArrayDownIterator::hdArrayDownIterator(ddObjsArray *ddPtrsArray) +{ + internalArray = ddPtrsArray; + position = internalArray->GetCount() - 1; +} + +// Get current item in the array for the iterator +hdObject *hdArrayDownIterator::Current() +{ + hdObject *obj = internalArray->Item(position); + return obj; +} + +// Get next item in the array for the iterator +hdObject *hdArrayDownIterator::Next() +{ + hdObject *obj = internalArray->Item(position); + position--; + return obj; +} + +// Return true if the array has more elements to return +bool hdArrayDownIterator::HasNext() +{ + int size = internalArray->GetCount(); + if( (size > 0) && (position <= (size - 1) && position >= 0) ) + return true; + else + return false; +} + +void hdArrayDownIterator::ResetIterator() +{ + position = internalArray->GetCount() - 1; +} diff --git a/hotdraw/utilities/hdCollection.cpp b/hotdraw/utilities/hdCollection.cpp new file mode 100644 index 0000000..c6b5bed --- /dev/null +++ b/hotdraw/utilities/hdCollection.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCollection.cpp - Generic implementation of a Collection used by dd +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdCollection.h" +#include "hotdraw/main/hdObject.h" + +hdCollection::hdCollection(hdCollectionBase *collectionBase) +{ + collection = collectionBase; +} + +hdCollection::~hdCollection() +{ + if(collection) + delete collection; +} + +void hdCollection::addItem(hdObject *item) +{ + collection->addItem(item); +} + +void hdCollection::removeItem(hdObject *item) +{ + collection->removeItem(item); +} + + +hdIteratorBase *hdCollection::createIterator() +{ + if(collection) + return collection->createIterator(); + return NULL; +} + +hdIteratorBase *hdCollection::createDownIterator() +{ + if(collection) + return collection->createDownIterator(); + return NULL; +} + +int hdCollection::count() +{ + return collection->count(); +} + +bool hdCollection::existsObject(hdObject *item) +{ + return collection->existsObject(item); +} + +hdObject *hdCollection::getItemAt(int index) +{ + return collection->getItemAt(index); +} + +void hdCollection::removeItemAt(int index) +{ + collection->removeItemAt(index); +} + +// Remove all items from collection without deleting each one. +void hdCollection::removeAll() +{ + collection->removeAll(); +} + +void hdCollection::deleteAll() +{ + collection->deleteAll(); +} + +int hdCollection::getIndex(hdObject *item) +{ + return collection->getIndex(item); +} + +void hdCollection::insertAtIndex(hdObject *item, int index) +{ + collection->insertAtIndex(item, index); +} + +void hdCollection::replaceAtIndex(hdObject *item, int index) +{ + collection->replaceAtIndex(item, index); +} + +void hdCollection::bringToFront(hdObject *item) +{ + collection->bringToFront(item); +} + +void hdCollection::sendToBack(hdObject *item) +{ + collection->sendToBack(item); +} diff --git a/hotdraw/utilities/hdGeometry.cpp b/hotdraw/utilities/hdGeometry.cpp new file mode 100644 index 0000000..663b36b --- /dev/null +++ b/hotdraw/utilities/hdGeometry.cpp @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdGeometry.cpp - Utility Geometric Functions Shared between classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdGeometry.h" +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/utilities/hdPoint.h" + +// +// Warning when using it: typecasting to avoid miscalculations functions need double values not int +// + +bool hdGeometry::lineContainsPoint(double x1, double y1, double x2, double y2, double px, double py) +{ + hdPoint p = hdPoint(x1, y1); + hdRect r = hdRect(p); + r.add(x2, y2); + r.Inflate(2, 2); + if(!r.Contains(px, py)) + { + return false; + } + + double a, b, x, y; + double val1, val2; + + val1 = px - x1; + if( x1 == x2 ) + { + return (ddabs(val1) < 3); + } + + val2 = py - y1; + if( y1 == y2 ) + { + return (ddabs(val2) < 3); + } + + a = (y1 - y2) / (x1 - x2); + b = y1 - a * x1; + x = (py - b) / a; + y = a * px + b; + + val1 = x - px; + val2 = y - py; + bool out = (min( ddabs(val1), ddabs(val2)) < 4); + return out; +} + +int hdGeometry::min(double a, double b) +{ + return(a <= b) ? a : b; +} + +int hdGeometry::max(double a, double b) +{ + return(a >= b) ? a : b; +} + + +int hdGeometry::min(int a, int b) +{ + return(a <= b) ? a : b; +} + +int hdGeometry::max(int a, int b) +{ + return(a >= b) ? a : b; +} + +//Gets the angle of a point relative to a rectangle. +double hdGeometry::angleFromPoint(int posIdx, hdMultiPosRect r, hdPoint point) +{ + return angleFromPoint(r.gethdRect(posIdx), point); +} + +double hdGeometry::angleFromPoint(hdRect r, hdPoint point) +{ + double rx = point.x - r.center().x; + double ry = point.y - r.center().y; + return atan2 (ry * r.width, rx * r.height); +} + +hdPoint hdGeometry::edgePointFromAngle(int posIdx, hdMultiPosRect r, double angle) +{ + return edgePointFromAngle(r.gethdRect(posIdx), angle); +} + +//Gets the point on a rectangle that corresponds to the given angle. +hdPoint hdGeometry::edgePointFromAngle(hdRect r, double angle) +{ + static hdPoint locationPoint; //Hack to allow bug in linux & ddabs + double sinv = sin(angle); + double cosv = cos(angle); + double e = 0.0001; + double x = 0.0; + double y = 0.0; + double width = r.width; + double height = r.height; + + + if( ddabs(sinv) > e ) + { + x = (1.0 + cosv / ddabs (sinv)) / 2.0 * width; + x = range(0.0, width, x); + } + else if ( cosv >= 0.0 ) + { + x = width; + } + + if ( ddabs(cosv) > e ) + { + y = (1.0 + sinv / ddabs (cosv)) / 2.0 * height; + y = range (0.0, height, y); + } + else if ( sinv >= 0.0 ) + { + y = height; + } + int xx = r.x + x; + int yy = r.y + y; + locationPoint = hdPoint(xx, yy); + return locationPoint; +} + +double hdGeometry::range(double min, double max, double num) +{ + return num < min ? min : (num > max ? max : num); +} + +double hdGeometry::ddabs(double value) +{ + return value < 0 ? (value * -1) : value; +} + +int hdGeometry::ddabs(int value) +{ + return value < 0 ? (value * -1) : value; +} + +double hdGeometry::lineSize (hdPoint p1, hdPoint p2) +{ + int w = p1.x - p2.x; + int h = p1.y - p2.y; + + double perimeter = w * w + h * h; + return sqrt (perimeter); +} + +// source: http://vision.dai.ed.ac.uk/andrewfg/c-g-a-faq.html +// Standard line intersection algorithm, Return true intersection if it exists, else false. +bool hdGeometry::intersection(hdPoint p1, hdPoint p2, hdPoint p3, hdPoint p4) +{ + // Store the values for fast access and easy + // equations-to-code conversion + float x1 = p1.x, x2 = p2.x, x3 = p3.x, x4 = p4.x; + float y1 = p1.y, y2 = p2.y, y3 = p3.y, y4 = p4.y; + + float d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); + // If d is zero, there is no intersection + if (d == 0) return false; + + // Get the x and y + float pre = (x1 * y2 - y1 * x2), post = (x3 * y4 - y3 * x4); + // point of intersection + float x = ( pre * (x3 - x4) - (x1 - x2) * post ) / d; + float y = ( pre * (y3 - y4) - (y1 - y2) * post ) / d; + + // Check if the x and y coordinates are within both lines + if ( x < min(x1, x2) || x > max(x1, x2) || x < min(x3, x4) || x > max(x3, x4) ) + return false; + if ( y < min(y1, y2) || y > max(y1, y2) || y < min(y3, y4) || y > max(y3, y4) ) + return false; + + return true; +} diff --git a/hotdraw/utilities/hdKeyEvent.cpp b/hotdraw/utilities/hdKeyEvent.cpp new file mode 100644 index 0000000..bd63d0a --- /dev/null +++ b/hotdraw/utilities/hdKeyEvent.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdKeyEvent.h - Wrapper Class to integrate wxKeyEvent inside library. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdKeyEvent.h" +#include "hotdraw/main/hdDrawingView.h" + +hdKeyEvent::hdKeyEvent(wxKeyEvent &event, hdDrawingView *owner): + keyEvent(event) +{ + view = owner; + keyCode = event.GetKeyCode(); +} + +int hdKeyEvent::GetKeyCode() +{ + return keyCode; +} + +hdDrawingView *hdKeyEvent::getView() +{ + return view; +} diff --git a/hotdraw/utilities/hdMouseEvent.cpp b/hotdraw/utilities/hdMouseEvent.cpp new file mode 100644 index 0000000..1552b5d --- /dev/null +++ b/hotdraw/utilities/hdMouseEvent.cpp @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMouseEvent.cpp - Wrapper Class to integrate conversion CalcUnscrolledPosition in a mouse event. +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdMouseEvent.h" +#include "hotdraw/main/hdDrawingView.h" + +hdMouseEvent::hdMouseEvent(wxMouseEvent &event, hdDrawingView *owner): + mouseEvent(event) +{ + view = owner; + m_shiftDown = event.m_shiftDown; +} + +hdPoint &hdMouseEvent::GetPosition() +{ + return getUnScrolledPosition(); +} + +hdPoint &hdMouseEvent::getUnScrolledPosition() +{ + unScrolled = mouseEvent.GetPosition(); + view->CalcUnscrolledPosition(unScrolled.x, unScrolled.y, &unScrolled.x, &unScrolled.y); + return unScrolled; +} + +hdPoint &hdMouseEvent::getScrolledPosition() +{ + scrolled = mouseEvent.GetPosition(); + return scrolled; +} + +int hdMouseEvent::getScrolledPosX() +{ + return getScrolledPosition().x; +} + +int hdMouseEvent::getScrolledPosY() +{ + return getScrolledPosition().y; +} + +int hdMouseEvent::getUnScrolledPosX() +{ + return getUnScrolledPosition().x; +} + +int hdMouseEvent::getUnScrolledPosY() +{ + return getUnScrolledPosition().y; +} + +bool hdMouseEvent::LeftDClick() +{ + return mouseEvent.LeftDClick(); +} + +bool hdMouseEvent::ShiftDown() +{ + return mouseEvent.ShiftDown(); +} + +bool hdMouseEvent::RightDown() +{ + return mouseEvent.RightDown(); +} + +bool hdMouseEvent::LeftDown() +{ + return mouseEvent.LeftDown(); +} + +bool hdMouseEvent::LeftUp() +{ + return mouseEvent.LeftUp(); +} + +bool hdMouseEvent::LeftIsDown() +{ + return mouseEvent.LeftIsDown(); +} + +hdDrawingView *hdMouseEvent::getView() +{ + return view; +} diff --git a/hotdraw/utilities/hdMultiPosRect.cpp b/hotdraw/utilities/hdMultiPosRect.cpp new file mode 100644 index 0000000..0178e80 --- /dev/null +++ b/hotdraw/utilities/hdMultiPosRect.cpp @@ -0,0 +1,215 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMultiRect.cpp - hdMultiPosRect improved class with new needed functionalities for allowing multiple displaybox for same figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/utilities/hdGeometry.h" + +void hdMultiPosRect::init(int valX, int valY) +{ + int i; + for(i = 0; i < MAXPOS; i++) + { + x.Add(valX); + y.Add(valY); + } +} + +hdMultiPosRect::hdMultiPosRect(int posIdx, const wxPoint &topLeft, const wxPoint &bottomRight) +{ + x[posIdx] = topLeft.x; + y[posIdx] = topLeft.y; + width = bottomRight.x - topLeft.x; + height = bottomRight.y - topLeft.y; + + if (width < 0) + { + width = -width; + x[posIdx] = bottomRight.x; + } + width++; + + if (height < 0) + { + height = -height; + y[posIdx] = bottomRight.y; + } + height++; +} + +//simplify this function with SetCount() in a future +void hdMultiPosRect::addNewXYPosition() +{ + x.Add(-1); + y.Add(-1); +} + +void hdMultiPosRect::removeXYPosition(int posIdx) +{ + x.RemoveAt(posIdx); + y.RemoveAt(posIdx); +} + +hdMultiPosRect &hdMultiPosRect::Union(int posIdx, const hdMultiPosRect &rect) +{ + // ignore empty rectangles: union with an empty rectangle shouldn't extend + // this one to (0, 0) + if ( !width || !height ) + { + *this = rect; + } + else if ( rect.width && rect.height ) + { + int x1 = wxMin(x[posIdx], rect.x[posIdx]); + int y1 = wxMin(y[posIdx], rect.y[posIdx]); + int y2 = wxMax(y[posIdx] + height, rect.height + rect.y[posIdx]); + int x2 = wxMax(x[posIdx] + width, rect.width + rect.x[posIdx]); + + x[posIdx] = x1; + y[posIdx] = y1; + width = x2 - x1; + height = y2 - y1; + } + //else: we're not empty and rect is empty + + return *this; +} + +hdMultiPosRect &hdMultiPosRect::Inflate(int posIdx, wxCoord dx, wxCoord dy) +{ + if (-2 * dx > width) + { + // Don't allow deflate to eat more width than we have, + // a well-defined rectangle cannot have negative width. + x[posIdx] += width / 2; + width = 0; + } + else + { + // The inflate is valid. + x[posIdx] -= dx; + width += 2 * dx; + } + + if (-2 * dy > height) + { + // Don't allow deflate to eat more height than we have, + // a well-defined rectangle cannot have negative height. + y[posIdx] += height / 2; + height = 0; + } + else + { + // The inflate is valid. + y[posIdx] -= dy; + height += 2 * dy; + } + + return *this; +} + +bool hdMultiPosRect::Contains(int posIdx, int cx, int cy) const +{ + return ( (cx >= x[posIdx]) && (cy >= y[posIdx]) + && ((cy - y[posIdx]) < height) + && ((cx - x[posIdx]) < width) + ); +} + +bool hdMultiPosRect::Contains(int posIdx, const hdRect &rect) const +{ + return Contains(posIdx, rect.GetTopLeft()) && Contains(posIdx, rect.GetBottomRight()); +} + +hdMultiPosRect &hdMultiPosRect::Intersect(int posIdx, const hdMultiPosRect &rect) +{ + int x2 = GetRight(posIdx), + y2 = GetBottom(posIdx); + + if ( x[posIdx] < rect.x[posIdx] ) + x[posIdx] = rect.x[posIdx]; + if ( y[posIdx] < rect.y[posIdx] ) + y[posIdx] = rect.y[posIdx]; + if ( x2 > rect.GetRight(posIdx) ) + x2 = rect.GetRight(posIdx); + if ( y2 > rect.GetBottom(posIdx) ) + y2 = rect.GetBottom(posIdx); + + width = x2 - x[posIdx] + 1; + height = y2 - y[posIdx] + 1; + + if ( width <= 0 || height <= 0 ) + { + width = + height = 0; + } + + return *this; +} + +bool hdMultiPosRect::Intersects(int posIdx, const hdMultiPosRect &rect) const +{ + hdMultiPosRect r = Intersect(posIdx, rect); + + // if there is no intersection, both width and height are 0 + return r.width != 0; +} + +void hdMultiPosRect::add (int posIdx, int newX, int newY) +{ + int x1 = hdGeometry::min(x[posIdx] , newX); + int x2 = hdGeometry::max(x[posIdx] + width , newX); + int y1 = hdGeometry::min(y[posIdx] , newY); + int y2 = hdGeometry::max(y[posIdx] + height , newY); + + SetX(posIdx, x1); + SetWidth(x2 - x1); + SetY(posIdx, y1); + SetHeight(y2 - y1); +} + + +void hdMultiPosRect::add (int posIdx, hdRect *newRect) +{ + add(posIdx, newRect->GetTopLeft().x , newRect->GetTopLeft().y); + add(posIdx, newRect->GetBottomRight().x , newRect->GetBottomRight().y); +} + +void hdMultiPosRect::add (int posIdx, hdRect newRect) +{ + add(posIdx, newRect.GetTopLeft().x , newRect.GetTopLeft().y); + add(posIdx, newRect.GetBottomRight().x , newRect.GetBottomRight().y); +} + +void hdMultiPosRect::add(int posIdx, hdPoint *p) +{ + add(posIdx, p->x, p->y); +} + + + +hdPoint hdMultiPosRect::center(int posIdx) +{ + point = hdPoint(x[posIdx] + (width / 2) , y[posIdx] + (height / 2)); + return point; +} + +int hdMultiPosRect::CountPositions() +{ + return x.Count(); +} diff --git a/hotdraw/utilities/hdPoint.cpp b/hotdraw/utilities/hdPoint.cpp new file mode 100644 index 0000000..dcfaa4e --- /dev/null +++ b/hotdraw/utilities/hdPoint.cpp @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPoint.cpp - wxPoint class to be used as wrapper and allow independence of point class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdPoint.h" + +hdPoint::hdPoint(): + wxPoint() +{ +} + +hdPoint::hdPoint(int x, int y): + wxPoint(x, y) +{ +} + +hdPoint::hdPoint(const hdPoint &p): + wxPoint(p.x, p.y) +{ +} + +hdPoint::hdPoint(const wxPoint &p): + wxPoint(p.x, p.y) +{ +} diff --git a/hotdraw/utilities/hdRect.cpp b/hotdraw/utilities/hdRect.cpp new file mode 100644 index 0000000..c469bab --- /dev/null +++ b/hotdraw/utilities/hdRect.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRect.cpp - wxRect improved class with new needed functionalities +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include + +// App headers +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdGeometry.h" + +hdRect::hdRect() +{ +} + +hdRect::hdRect(int xx, int yy, int ww, int hh): + wxRect(xx, yy, ww, hh) +{ +} + +hdRect::hdRect(hdPoint *topLeft, hdPoint *bottomRight): + wxRect(*topLeft, *bottomRight) +{ +} + +hdRect::hdRect(hdPoint *point): + wxRect(point->x, point->y, 0, 0) +{ +} + +hdRect::hdRect(hdPoint &point): + wxRect(point.x, point.y, 0, 0) +{ +} + +void hdRect::add (int newX, int newY) +{ + int x1 = hdGeometry::min(x , newX); + int x2 = hdGeometry::max(x + width , newX); + int y1 = hdGeometry::min(y , newY); + int y2 = hdGeometry::max(y + height , newY); + + SetX(x1); + SetWidth(x2 - x1); + SetY(y1); + SetHeight(y2 - y1); +} + + +void hdRect::add (hdRect *newRect) +{ + add(newRect->GetTopLeft().x , newRect->GetTopLeft().y); + add(newRect->GetBottomRight().x , newRect->GetBottomRight().y); +} + +void hdRect::add (hdRect newRect) +{ + add(newRect.GetTopLeft().x , newRect.GetTopLeft().y); + add(newRect.GetBottomRight().x , newRect.GetBottomRight().y); +} + +void hdRect::add(hdPoint *p) +{ + add(p->x, p->y); +} + + + +hdPoint hdRect::center() +{ + point = hdPoint(x + (width / 2) , y + (height / 2)); + return point; +} + diff --git a/hotdraw/utilities/hdRemoveDeleteDialog.cpp b/hotdraw/utilities/hdRemoveDeleteDialog.cpp new file mode 100644 index 0000000..9bf3c22 --- /dev/null +++ b/hotdraw/utilities/hdRemoveDeleteDialog.cpp @@ -0,0 +1,169 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRemoveDeleteDialog.cpp - Utility dialog class to allow user to select between delete / remove a figure +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include + +// App headers +#include "hotdraw/utilities/hdRemoveDeleteDialog.h" + +IMPLEMENT_CLASS( hdRemoveDeleteDialog, wxDialog ) + +BEGIN_EVENT_TABLE(hdRemoveDeleteDialog, wxDialog) + EVT_BUTTON(DD_REMOVE, hdRemoveDeleteDialog::OnRemove) + EVT_BUTTON(DD_DELETE, hdRemoveDeleteDialog::OnDelete) + EVT_BUTTON(wxID_CANCEL, hdRemoveDeleteDialog::OnCancel) +END_EVENT_TABLE() + +hdRemoveDeleteDialog::hdRemoveDeleteDialog( const wxString &message, + const wxString &caption, + wxWindow *parent, bool allowRemove + ) +{ + allowRemoveButton = allowRemove; + SetFont(settings->GetSystemFont()); + Init(); + Create(parent, wxID_ANY, message, caption); + cancelButton->SetFocus(); +} + +hdRemoveDeleteDialog::~hdRemoveDeleteDialog() +{ + if(staticText) + delete staticText; + if(staticText2) + delete staticText2; + if(staticText3) + delete staticText3; + if(line) + delete line; + if(removeButton) + delete removeButton; + if(deleteButton) + delete deleteButton; + if(cancelButton) + delete cancelButton; +} + +hdRemoveDeleteDialog::hdRemoveDeleteDialog() +{ + Init(); +} + + +void hdRemoveDeleteDialog::Init( ) +{ +} + +// Creation +bool hdRemoveDeleteDialog::Create( wxWindow *parent, + wxWindowID id, + const wxString &caption, + const wxString &message + ) +{ + SetFont(settings->GetSystemFont()); + + if (!wxDialog::Create( parent, id, message, wxDefaultPosition, wxDefaultSize, wxCAPTION)) + return false; + + CreateControls(caption); + + // This fits the dialog to the minimum size dictated by + // the sizers + GetSizer()->Fit(this); + + // This ensures that the dialog cannot be sized smaller + // than the minimum size + GetSizer()->SetSizeHints(this); + + // Centre the dialog on the parent or (if none) screen + + Centre(); + + return true; +} + + +// Creates the controls and sizers +void hdRemoveDeleteDialog::CreateControls(const wxString &message) +{ + // A top-level sizer + topSizer = new wxBoxSizer(wxVERTICAL ); + this->SetSizer(topSizer); + topSizer->AddSpacer(10); + //Message Sizer + messageSizer = new wxBoxSizer(wxHORIZONTAL ); + topSizer->Add(messageSizer); + messageSizer->AddSpacer(25); + + staticText = new wxStaticText(this, wxID_STATIC, message, wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER); + messageSizer->Add(staticText, 0, wxALIGN_CENTER, 5); + + messageSizer->AddSpacer(45); + + // Add important user info + wxString info = _(" Choose Remove from Diagram to remove only from current diagram. "); + wxString info2 = _(" Choose Remove from Model to delete permanently. "); + + this->SetForegroundColour(wxColour(wxT("GREY"))); + staticText2 = new wxStaticText(this, wxID_STATIC, info, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(staticText2, 0, wxALIGN_LEFT, 5); + + staticText3 = new wxStaticText(this, wxID_STATIC, info2, wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT); + topSizer->Add(staticText3, 0, wxALIGN_LEFT, 5); + + // A space and a dividing line before the Remove Delete and Cancel buttons + topSizer->AddSpacer(10); + line = new wxStaticLine ( this, wxID_STATIC, + wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + topSizer->Add(line, 0, wxGROW | wxALL, 5); + + //Buttons Sizer + buttonsSizer = new wxBoxSizer(wxHORIZONTAL ); + + topSizer->Add(buttonsSizer, 0, wxALIGN_CENTER, 5); + + removeButton = new wxButton ( this, DD_REMOVE, wxT("&Remove from Diagram"), + wxDefaultPosition, wxDefaultSize, 0 ); + + if(!allowRemoveButton) + removeButton->Enable(false); + + buttonsSizer->Add(removeButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + deleteButton = new wxButton ( this, DD_DELETE, wxT("&Remove from Model"), + wxDefaultPosition, wxDefaultSize, 0 ); + buttonsSizer->Add(deleteButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + + cancelButton = new wxButton ( this, wxID_CANCEL, wxT("&Cancel"), + wxDefaultPosition, wxDefaultSize, 0 ); + buttonsSizer->Add(cancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5); + topSizer->AddSpacer(10); +} + +void hdRemoveDeleteDialog::OnRemove(wxCommandEvent &WXUNUSED(event)) +{ + EndModal( DD_REMOVE ); +} + +void hdRemoveDeleteDialog::OnDelete(wxCommandEvent &WXUNUSED(event)) +{ + EndModal( DD_DELETE ); +} + +void hdRemoveDeleteDialog::OnCancel(wxCommandEvent &WXUNUSED(event)) +{ + EndModal( wxID_CANCEL ); +} diff --git a/hotdraw/utilities/module.mk b/hotdraw/utilities/module.mk new file mode 100644 index 0000000..04244bc --- /dev/null +++ b/hotdraw/utilities/module.mk @@ -0,0 +1,24 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/hotdraw/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + hotdraw/utilities/hdArrayCollection.cpp \ + hotdraw/utilities/hdCollection.cpp \ + hotdraw/utilities/hdGeometry.cpp \ + hotdraw/utilities/hdKeyEvent.cpp \ + hotdraw/utilities/hdMouseEvent.cpp \ + hotdraw/utilities/hdMultiPosRect.cpp \ + hotdraw/utilities/hdPoint.cpp \ + hotdraw/utilities/hdRect.cpp \ + hotdraw/utilities/hdRemoveDeleteDialog.cpp + +EXTRA_DIST += \ + hotdraw/utilities/module.mk diff --git a/include/.gitignore b/include/.gitignore new file mode 100644 index 0000000..0db0f54 --- /dev/null +++ b/include/.gitignore @@ -0,0 +1,2 @@ +# Global excludes across all subdirectories +svnversion.h diff --git a/include/agent/dlgJob.h b/include/agent/dlgJob.h new file mode 100644 index 0000000..4a9c974 --- /dev/null +++ b/include/agent/dlgJob.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgJob.h - Job property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_JOBPROP +#define __DLG_JOBPROP + +#include "dlg/dlgProperty.h" + +class pgaJob; + +class dlgJob : public dlgAgentProperty +{ +public: + dlgJob(pgaFactory *factory, frmMain *frame, pgaJob *j); + + void CheckChange(); + int Go(bool modal); + + wxString GetUpdateSql(); + wxString GetInsertSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-jobs"); + } + +private: + pgaJob *job; + + wxArrayString previousSteps, previousSchedules; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeStep(wxListEvent &ev); + void OnChangeStep(wxCommandEvent &ev); + void OnAddStep(wxCommandEvent &ev); + void OnRemoveStep(wxCommandEvent &ev); + + void OnSelChangeSchedule(wxListEvent &ev); + void OnChangeSchedule(wxCommandEvent &ev); + void OnAddSchedule(wxCommandEvent &ev); + void OnRemoveSchedule(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/agent/dlgSchedule.h b/include/agent/dlgSchedule.h new file mode 100644 index 0000000..23b2c98 --- /dev/null +++ b/include/agent/dlgSchedule.h @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchedule.h - Job property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SCHEDULEPROP +#define __DLG_SCHEDULEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/timespin.h" +#include "ctl/calbox.h" + +class pgaSchedule; +class pgaJob; + +class dlgSchedule : public dlgAgentProperty +{ +public: + dlgSchedule(pgaFactory *factory, frmMain *frame, pgaSchedule *s, pgaJob *j); + + void CheckChange(); + int Go(bool modal); + + wxString GetComment(); + wxString GetUpdateSql(); + wxString GetInsertSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetJobId(long id) + { + jobId = id; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-schedules"); + } + +private: + long jobId; + pgaSchedule *schedule; + pgaJob *job; + + wxArrayString deleteExceptions; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChangeCom(wxCommandEvent &ev); + void OnChangeCal(wxCalendarEvent &ev); + void OnSelChangeException(wxListEvent &ev); + void OnAddException(wxCommandEvent &ev); + void OnChangeException(wxCommandEvent &ev); + void OnRemoveException(wxCommandEvent &ev); + const wxString ChkListBox2PgArray(wxCheckListBox *lb); + const wxString ChkListBox2StrArray(wxCheckListBox *lb); + void OnSelectAll(wxCommandEvent &ev, int origin); + void OnSelectAllWeekdays(wxCommandEvent &ev) + { + OnSelectAll(ev, 1); + }; + void OnSelectAllMonthdays(wxCommandEvent &ev) + { + OnSelectAll(ev, 2); + }; + void OnSelectAllMonths(wxCommandEvent &ev) + { + OnSelectAll(ev, 3); + }; + void OnSelectAllHours(wxCommandEvent &ev) + { + OnSelectAll(ev, 4); + }; + void OnSelectAllMinutes(wxCommandEvent &ev) + { + OnSelectAll(ev, 5); + }; + void InitSelectAll(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/agent/dlgStep.h b/include/agent/dlgStep.h new file mode 100644 index 0000000..7f0f000 --- /dev/null +++ b/include/agent/dlgStep.h @@ -0,0 +1,67 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgStep.h - Job property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_STEPPROP +#define __DLG_STEPPROP + +#include "dlg/dlgProperty.h" + +class pgaStep; +class pgaJob; + +class dlgStep : public dlgAgentProperty +{ +public: + dlgStep(pgaFactory *factory, frmMain *frame, pgaStep *s, pgaJob *j); + + void CheckChange(); + int Go(bool modal); + + wxString GetUpdateSql(); + wxString GetInsertSql(); + wxString GetComment(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void SetObject(pgObject *obj) + { + step = (pgaStep *)obj; + } + + void SetJobId(long id) + { + jobId = id; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-steps"); + } + +private: + void OnSelRemoteConn(wxCommandEvent &ev); + void OnSelLocalConn(wxCommandEvent &ev); + void OnSelectDatabase(wxCommandEvent &ev); + + virtual bool IsUpToDate(); + + long jobId; + ctlSQLBox *sqlBox; + pgaStep *step; + pgaJob *job; + bool hasConnStrSupport; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/agent/module.mk b/include/agent/module.mk new file mode 100644 index 0000000..4742e46 --- /dev/null +++ b/include/agent/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/agent Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/agent/dlgJob.h \ + include/agent/dlgSchedule.h \ + include/agent/dlgStep.h \ + include/agent/pgaJob.h \ + include/agent/pgaSchedule.h \ + include/agent/pgaStep.h + +EXTRA_DIST += \ + include/agent/module.mk + diff --git a/include/agent/pgaJob.h b/include/agent/pgaJob.h new file mode 100644 index 0000000..e561d0b --- /dev/null +++ b/include/agent/pgaJob.h @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGAJOB_H +#define PGAJOB_H + +#include "schema/pgServer.h" + + +class pgaJobFactory : public pgServerObjFactory +{ +public: + pgaJobFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetDisabledId() + { + return disabledId; + } + +protected: + int disabledId; +}; +extern pgaJobFactory jobFactory; + +class pgaJob : public pgServerObject +{ +public: + pgaJob(const wxString &newName = wxT("")); + + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + wxString GetTranslatedMessage(int kindOfMessage) const; + wxString GetJobclass() const + { + return jobclass; + } + void iSetJobclass(const wxString &s) + { + jobclass = s; + } + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxDateTime GetCreated() const + { + return created; + } + void iSetCreated(const wxDateTime &d) + { + created = d; + } + wxDateTime GetChanged() const + { + return changed; + } + void iSetChanged(const wxDateTime &d) + { + changed = d; + } + wxDateTime GetNextrun() const + { + return nextrun; + } + void iSetNextrun(const wxDateTime &d) + { + nextrun = d; + } + wxDateTime GetLastrun() const + { + return lastrun; + } + void iSetLastrun(const wxDateTime &d) + { + lastrun = d; + } + wxString GetLastresult() const + { + return lastresult; + } + void iSetLastresult(const wxString &s) + { + lastresult = s; + } + wxString GetCurrentAgent() const + { + return currentAgent; + } + void iSetCurrentAgent(const wxString &s) + { + currentAgent = s; + } + wxString GetHostAgent() const + { + return hostAgent; + } + void iSetHostAgent(const wxString &s) + { + hostAgent = s; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + bool RunNow(); + + wxMenu *GetNewMenu(); + bool CanCreate() + { + return true; + } + bool CanView() + { + return false; + } + bool CanEdit() + { + return true; + } + bool CanDrop() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-jobs"); + } + +private: + bool enabled; + wxDateTime created, changed, nextrun, lastrun; + wxString lastresult, jobclass, currentAgent, hostAgent; + long recId; +}; + + +class pgaJobObject : public pgServerObject +{ +public: + pgaJobObject(pgaJob *job, pgaFactory &factory, const wxString &newName); + virtual pgaJob *GetJob() + { + return job; + } + + bool CanCreate() + { + return job->CanCreate(); + } + bool CanView() + { + return false; + } + bool CanEdit() + { + return job->CanEdit(); + } + bool CanDrop() + { + return job->CanDrop(); + } + +protected: + pgaJob *job; +}; + + +class pgaJobCollection : public pgServerObjCollection +{ +public: + pgaJobCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgaJobObjCollection : public pgServerObjCollection +{ +public: + pgaJobObjCollection(pgaFactory *factory, pgaJob *job); + bool CanCreate(); +}; + +class pgaJobObjFactory : public pgServerObjFactory +{ +public: + pgaJobObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgServerObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class runNowFactory : public contextActionFactory +{ +public: + runNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/agent/pgaSchedule.h b/include/agent/pgaSchedule.h new file mode 100644 index 0000000..20df7b1 --- /dev/null +++ b/include/agent/pgaSchedule.h @@ -0,0 +1,151 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaSchedule.h - PostgreSQL Agent Job Schedule +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGASCHEDULE_H +#define PGASCHEDULE_H + +#include "agent/pgaJob.h" + + +class pgaScheduleFactory : public pgaJobObjFactory +{ +public: + pgaScheduleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgaScheduleFactory scheduleFactory; + + +class pgaSchedule : public pgaJobObject +{ +public: + pgaSchedule(pgCollection *collection, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxDateTime GetStart() const + { + return start; + } + void iSetStart(const wxDateTime &d) + { + start = d; + } + wxDateTime GetEnd() const + { + return end; + } + void iSetEnd(const wxDateTime &d) + { + end = d; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + + wxString GetMinutes() const + { + return minutes; + } + wxString GetMinutesString(); + void iSetMinutes(const wxString &s) + { + minutes = s; + } + + wxString GetHours() const + { + return hours; + } + wxString GetHoursString(); + void iSetHours(const wxString &s) + { + hours = s; + } + + wxString GetWeekdays() const + { + return weekdays; + } + wxString GetWeekdaysString(); + void iSetWeekdays(const wxString &s) + { + weekdays = s; + } + + wxString GetMonthdays() const + { + return monthdays; + } + wxString GetMonthdaysString(); + void iSetMonthdays(const wxString &s) + { + monthdays = s; + } + + wxString GetMonths() const + { + return months; + } + wxString GetMonthsString(); + void iSetMonths(const wxString &s) + { + months = s; + } + + wxString GetExceptions() const + { + return exceptions; + } + wxString GetExceptionsString(); + void iSetExceptions(const wxString &s) + { + exceptions = s; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-schedules"); + } + +private: + bool enabled; + wxDateTime start, end; + long recId; + wxString minutes, hours, weekdays, monthdays, months, exceptions; +}; + +class pgaScheduleCollection : public pgaJobObjCollection +{ +public: + pgaScheduleCollection(pgaFactory *factory, pgaJob *job); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/agent/pgaStep.h b/include/agent/pgaStep.h new file mode 100644 index 0000000..1369f58 --- /dev/null +++ b/include/agent/pgaStep.h @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaStep.h - PostgreSQL Agent Job Step +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGASTEP_H +#define PGASTEP_H + +#include "agent/pgaJob.h" + + + +class pgaStepFactory : public pgaJobObjFactory +{ +public: + pgaStepFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgaStepFactory stepFactory; + + +class pgaStep : public pgaJobObject +{ +public: + pgaStep(pgCollection *collection, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxChar GetKindChar() const + { + return kindChar; + } + void iSetKindChar(const wxChar c) + { + kindChar = c; + } + wxString GetKind() const + { + return kind; + } + void iSetKind(const wxString &s) + { + kind = s; + } + wxString GetCode() const + { + return code; + } + void iSetCode(const wxString &s) + { + code = s; + } + wxString GetDbname() const + { + return dbname; + } + void iSetDbname(const wxString &s) + { + dbname = s; + } + wxString GetConnStr() const + { + return connstr; + } + void iSetConnStr(const wxString &s) + { + connstr = s; + } + wxString GetOnError() const + { + return onError; + } + void iSetOnError(const wxString &s) + { + onError = s; + } + wxChar GetOnErrorChar() const + { + return onErrorChar; + } + void iSetOnErrorChar(const wxChar c) + { + onErrorChar = c; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + + bool HasConnectionString() const + { + return !connstr.IsEmpty(); + } + + bool IsUpToDate(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-steps"); + } + +private: + bool enabled; + wxString kind, code, dbname, connstr, onError; + wxChar kindChar, onErrorChar; + long recId; +}; + +class pgaStepCollection : public pgaJobObjCollection +{ +public: + pgaStepCollection(pgaFactory *factory, pgaJob *job); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/copyright.h b/include/copyright.h new file mode 100644 index 0000000..1e9cdc5 --- /dev/null +++ b/include/copyright.h @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// copyright.h - pgAdmin copyright messages +// +////////////////////////////////////////////////////////////////////////// + +#ifndef COPYRIGHT_H +#define COPYRIGHT_H + +#define COPYRIGHT wxT("Copyright 2002 - 2016, The pgAdmin Development Team") +#define COPYRIGHT_WIN32 "\251 2002 - 2016, The pgAdmin Development Team" +#define LICENSE _("This software is released under the PostgreSQL Licence.") + +#endif diff --git a/include/ctl/calbox.h b/include/ctl/calbox.h new file mode 100644 index 0000000..c5785d0 --- /dev/null +++ b/include/ctl/calbox.h @@ -0,0 +1,136 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// calbox.h - Date-picker control box +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_CALBOX_H_ +#define _WX_CALBOX_H_ + +#include "wx/calctrl.h" + +#if defined(wxUSE_DATEPICKCTRL) && wxUSE_DATEPICKCTRL +#include "wx/datectrl.h" +#if wxUSE_DATEPICKCTRL_GENERIC +#include "wx/generic/datectrl.h" +#endif // wxUSE_DATEPICKCTRL_GENERIC +typedef wxDatePickerCtrl wxCalendarBox; +#else + +// pgCompatCalendarCtrl is a typedef for either wxGenericCalendarCtrl or wxCalendarCtrl +#if wxCHECK_VERSION(2, 9, 0) +#include "wx/generic/calctrlg.h" +typedef wxGenericCalendarCtrl pgCompatCalendarCtrl; +#else +typedef wxCalendarCtrl pgCompatCalendarCtrl; +#endif + +class wxCalendarBox : public wxControl +{ +public: + wxCalendarBox() + { + Init(); + } + wxCalendarBox(wxWindow *parent, + wxWindowID id, + const wxDateTime &date = wxDefaultDateTime, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxCAL_SHOW_HOLIDAYS | wxWANTS_CHARS, const wxString &name = wxCalendarNameStr); + + bool Destroy(); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name); + + bool SetValue(const wxDateTime &date); + wxDateTime GetValue(); + + bool SetLowerDateLimit(const wxDateTime &date = wxDefaultDateTime) + { + return m_cal->SetLowerDateLimit(date); + } + const wxDateTime &GetLowerDateLimit() const + { + return m_cal->GetLowerDateLimit(); + } + bool SetUpperDateLimit(const wxDateTime &date = wxDefaultDateTime) + { + return m_cal->SetUpperDateLimit(date); + } + const wxDateTime &GetUpperDateLimit() const + { + return m_cal->GetUpperDateLimit(); + } + + bool SetDateRange(const wxDateTime &lowerdate = wxDefaultDateTime, const wxDateTime &upperdate = wxDefaultDateTime) + { + return m_cal->SetDateRange(lowerdate, upperdate); + } + + wxCalendarDateAttr *GetAttr(size_t day) const + { + return m_cal->GetAttr(day); + } + void SetAttr(size_t day, wxCalendarDateAttr *attr) + { + m_cal->SetAttr(day, attr); + } + void SetHoliday(size_t day) + { + m_cal->SetHoliday(day); + } + void ResetAttr(size_t day) + { + m_cal->ResetAttr(day); + } + bool SetFormat(const wxChar *fmt); + + virtual bool Enable(bool enable = true); + virtual bool Show(bool show = true); + virtual void DoMoveWindow(int x, int y, int width, int height); + +private: + wxDialog *m_dlg; + wxTextCtrl *m_txt; + pgCompatCalendarCtrl *m_cal; + wxButton *m_btn; + wxString m_format; + + bool m_dropped, m_ignoreDrop; + + void Init(); + void DropDown(bool down = true); + + wxSize DoGetBestSize() const; + void OnSize(wxSizeEvent &event); + + void OnText(wxCommandEvent &ev); + void OnEditKey(wxKeyEvent &event); + void OnCalKey(wxKeyEvent &event); + void OnClick(wxCommandEvent &ev); + void OnSelChange(wxCalendarEvent &ev); + void OnSetFocus(wxFocusEvent &ev); + void OnKillFocus(wxFocusEvent &ev); + void OnChildSetFocus(wxChildFocusEvent &ev); + + DECLARE_DYNAMIC_CLASS(wxCalendarBox) + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxCalendarBox) +}; + +#endif // wxUSE_DATEPICKCTRL + +#endif // _WX_CALBOX_H_ + diff --git a/include/ctl/ctlAuiNotebook.h b/include/ctl/ctlAuiNotebook.h new file mode 100644 index 0000000..9f2684d --- /dev/null +++ b/include/ctl/ctlAuiNotebook.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlAuiNotebook.cpp - Custom AUI Notebook class +// +////////////////////////////////////////////////////////////////////////// + +// The primary purpose of this class is to pass child focus events from +// the notebook to the parent window. This is the only way we can grab +// focus events from the page controls. + +#ifndef CTLAUINOTEBOOK_H +#define CTLAUINOTEBOOK_H + +// wxWindows headers +#include +#include + +class ctlAuiNotebook : public wxAuiNotebook +{ +public: + ctlAuiNotebook(wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxAUI_NB_DEFAULT_STYLE) : + wxAuiNotebook(parent, id, pos, size, style) { } + +protected: + void OnChildFocus(wxChildFocusEvent &evt); + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/ctl/ctlCheckTreeView.h b/include/ctl/ctlCheckTreeView.h new file mode 100644 index 0000000..117f592 --- /dev/null +++ b/include/ctl/ctlCheckTreeView.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlCheckTreeView.cpp - TreeView with Checkboxes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _CTLCHECKTREEVIEW_H +#define _CTLCHECKTREEVIEW_H + + +// wxWindows headers +#include +#include +#include +#include + +class ctlCheckTreeView : public wxTreeCtrl +{ +public: + ctlCheckTreeView(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTR_HAS_BUTTONS); + bool IsChecked(const wxTreeItemId &node); + +private: + void OnLeftClick(wxMouseEvent &evt); + void SetParentAndChildImage(wxTreeItemId node, int newimage); + void SetParentImage(wxTreeItemId node, int newimage); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/ctl/ctlColourPicker.h b/include/ctl/ctlColourPicker.h new file mode 100644 index 0000000..ba3d644 --- /dev/null +++ b/include/ctl/ctlColourPicker.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// ctlColourPicker.cpp - TreeView with Checkboxes +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _CTLCOLOURPICKER_H +#define _CTLCOLOURPICKER_H + +// wxWindows headers +#include +#include "utils/misc.h" + + + +class ctlColourPicker : public wxBitmapButton +{ +public: + ctlColourPicker(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize) + { + Create(parent, id, pos, size); + } + + void DoProcessLeftClick(wxMouseEvent &event); + + wxColour GetColour(); + wxString GetColourString(); + + void SetColour(const wxColour &colour); + void SetColour(const wxString &colour); + + void SetTitle(const wxString &title); + void UpdateColour(); + +private: + wxString m_title; + wxColour m_colour_clr; + + void Create(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); +}; + +#endif diff --git a/include/ctl/ctlComboBox.h b/include/ctl/ctlComboBox.h new file mode 100644 index 0000000..75749f1 --- /dev/null +++ b/include/ctl/ctlComboBox.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlComboBox.h - enhanced combobox control +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __COMBOBOX_H +#define __COMBOBOX_H + +// wxWindows headers +#include +#include "utils/misc.h" + + + +class pgConn; +class ctlComboBoxFix : public wxComboBox +{ +public: + ctlComboBoxFix(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr); + + int FillLongKey(pgConn *conn, const wxChar *qry); + int FillOidKey(pgConn *conn, const wxChar *qry); + int FillStringKey(pgConn *conn, const wxChar *qry); + long GetLongKey(int sel = -1); + OID GetOIDKey(int sel = -1); + wxString GetStringKey(int sel = -1); + bool SetKey(long val); + bool SetKey(OID val); + bool SetKey(const wxString &val); + + int Append(const wxString &item) + { + return wxComboBox::Append(item); + } + int Append(const wxString &item, void *data) + { + return wxComboBox::Append(item, data); + } + int Append(const wxString &item, const wxString &str); + int Append(const wxString &item, long l); + int Append(const wxString &item, OID oid); +}; + +class ctlComboBox : public ctlComboBoxFix +{ +public: + ctlComboBox(wxWindow *wnd, int id, wxPoint pos, wxSize siz, long attr = 0); + int GuessSelection(wxCommandEvent &ev); + int GetGuessedSelection() const; + wxString GetGuessedStringSelection() const; + int GetSelection() const; +}; + +#endif diff --git a/include/ctl/ctlDefaultSecurityPanel.h b/include/ctl/ctlDefaultSecurityPanel.h new file mode 100644 index 0000000..6571588 --- /dev/null +++ b/include/ctl/ctlDefaultSecurityPanel.h @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlDefaultSecurityPanel.h - Panel with default security information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_DEFDEFSECPANEL_H +#define CTL_DEFDEFSECPANEL_H + +#include +#include +#include + +enum +{ + CTL_DEFPROPSQL = 500, + CTL_DEFMSG, + CTL_DEFLBPRIV, + CTL_DEFSTATICGROUP, + CTL_DEFCBGROUP, + CTL_DEFADDPRIV, + CTL_DEFDELPRIV, + CTL_DEFALLPRIV, + CTL_DEFALLPRIVGRANT, + CTL_DEFPRIVCB // base for all privilege checkboxes, must be last +}; + +class defaultPrivilegesOn +{ +public: + defaultPrivilegesOn(const wxChar, const wxString &, const wxString &); + + wxChar m_privilegeType; + wxString m_privilegesOn; + wxString m_privileges; + wxArrayString m_privilegesList; +}; + + +DECLARE_LOCAL_EVENT_TYPE(EVT_DEFAULTSECURITYPANEL_CHANGE, -1) + +class pgConn; +class ctlDefaultPrivilegesPanel; +class dlgDefaultSecurityProperty; + +class ctlDefaultSecurityPanel : public wxPanel +{ + +public: + ctlDefaultSecurityPanel(pgConn *, wxNotebook *, wxImageList *); + + wxString GetDefaultPrivileges(const wxString &schemaName); + void UpdatePrivilegePages(bool createDefPrivs, const wxString &defPrivsOnTables, + const wxString &defPrivsOnSeqs, const wxString &defPrivsOnFuncs, + const wxString &defPrivsOnTypes); + +protected: + wxNotebook *nbNotebook; + wxArrayString m_groups; + wxArrayString m_namespaces; + + ctlDefaultPrivilegesPanel *m_defPrivOnTablesPanel, *m_defPrivOnSeqsPanel, *m_defPrivOnFuncsPanel, *m_defPrivOnTypesPanel; + + friend class ctlDefaultPrivilegesPanel; + friend class dlgDefaultSecurityProperty; + +}; + +class ctlDefaultPrivilegesPanel : public wxPanel +{ + +public: + + ctlDefaultPrivilegesPanel(ctlDefaultSecurityPanel *, wxNotebook *, defaultPrivilegesOn &, wxImageList *); + ~ctlDefaultPrivilegesPanel(); + + void Update(wxString privs); + wxString GetDefaultPrivileges(const wxString &schemaName); + +protected: + + typedef struct + { + wxString m_username; + wxString m_origPriv; + wxString m_newPriv; + bool m_modified; + } defPrivilege; + +public: + WX_DECLARE_STRING_HASH_MAP(defPrivilege, defPrivHash); + +protected: + + bool m_defPrivChanged; + int privilegeCount; + defaultPrivilegesOn m_privilegeType; + defPrivHash m_privileges; + defPrivilege *m_currentSelectedPriv; + + ctlDefaultSecurityPanel *m_defSecurityPanel; + wxButton *btnAddPriv, *btnDelPriv; + wxCheckBox **privCheckboxes; + wxCheckBox *allPrivileges, *allPrivilegesGrant; + ctlListView *lbPrivileges; + ctlComboBox *cbGroups; + wxStaticText *stGroup; + + void OnPrivSelChange(wxListEvent &ev); + void OnAddPriv(wxCommandEvent &ev); + void OnGroupChange(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + void OnPrivCheck(wxCommandEvent &ev); + void OnPrivCheckAll(wxCommandEvent &ev); + void OnPrivCheckAllGrant(wxCommandEvent &ev); + + bool PrivCheckBoxUpdate(wxString &strUser); + void CheckGrantOpt(int index); + bool CanGrant(); + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/ctl/ctlListView.h b/include/ctl/ctlListView.h new file mode 100644 index 0000000..d2a9e4e --- /dev/null +++ b/include/ctl/ctlListView.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlListView.h - enhanced listview control +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLLISTVIEW_H +#define CTLLISTVIEW_H + +// wxWindows headers +#include +#include +#include "utils/misc.h" + +class frmMain; + +class ctlListView : public wxListView +{ +public: + ctlListView(wxWindow *p, int id, wxPoint pos, wxSize siz, long attr = 0); + long GetSelection(); + wxString GetText(long row, long col = 0); + + void CreateColumns(wxImageList *images, const wxString &left, const wxString &right, int leftSize = 60); + void CreateColumns(wxImageList *images, const wxString &str1, const wxString &str2, const wxString &str3, int leftSize = 60); + + void AddColumn(const wxString &text, int size = wxLIST_AUTOSIZE_USEHEADER, int format = wxLIST_FORMAT_LEFT); + + long AppendItem(int icon, const wxString &val, const wxString &val2 = wxString(), const wxString &val3 = wxString(), const wxString &val4 = wxString()); + long AppendItem(const wxString &val, const wxString &val2 = wxString(), const wxString &val3 = wxString()) + { + return AppendItem(PGICON_PROPERTY, val, val2, val3); + } + void AppendItem(const wxString &str, long l) + { + AppendItem(str, NumToStr(l)); + } + void AppendItem(const wxString &str, double d) + { + AppendItem(str, NumToStr(d)); + } + void AppendItem(const wxString &str, OID o) + { + AppendItem(str, NumToStr(o)); + } + void AppendItem(const wxString &str, const wxDateTime &d) + { + AppendItem(str, DateToStr(d)); + } + void AppendItem(const wxString &str, const wxLongLong &l) + { + AppendItem(str, l.ToString()); + } + void AppendItem(const wxString &str, const wxULongLong &l) + { + AppendItem(str, l.ToString()); + } + void AppendYesNoItem(const wxString &str, bool b) + { + AppendItem(str, BoolToYesNo(b)); + } + + void DeleteCurrentItem() + { + DeleteItem(GetSelection()); + } +}; + + +#endif diff --git a/include/ctl/ctlMenuToolbar.h b/include/ctl/ctlMenuToolbar.h new file mode 100644 index 0000000..786f4c2 --- /dev/null +++ b/include/ctl/ctlMenuToolbar.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMenuToolbar.h - Menu tool bar +// +// This code is essentially stolen (with the authors permission) from +// Paul Nelson (http://www.pnelsoncomposer.com/) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLMENUTOOLBAR_H +#define CTLMENUTOOLBAR_H + +#include "wx/frame.h" + +// ctlMenuButton - Can be used wherever you can use a standard wxBitmapButton +// +// Implements a small pull-down triangle (v), which, when clicked, will display +// a pop-up menu. + +class ctlMenuButton : public wxBitmapButton +{ +public: + ctlMenuButton(wxToolBar *toolBar, int ID, wxMenu *menu) + { + Create(toolBar, toolBar, ID, menu); + } + void DoProcessLeftClick(wxMouseEvent &event); + + wxMenu *m_menu; + + void FillMenu(); + +private: + void Create(wxWindow *window, wxToolBar *toolBar, int ID, wxMenu *menu); + wxToolBar *m_toolBar; +}; + + +// ctlMenuTool - is only used internal to the implementation of ctlMenuToolbar. +// +// You should never have to use it yourself + +class ctlMenuTool +{ +public: + ctlMenuTool(wxToolBarToolBase *new_tool, int toolId); + wxToolBarToolBase *m_tool; + wxMenu *m_menu; + +private: + int m_toolId; + ctlMenuButton *m_button; +}; + +WX_DECLARE_LIST(ctlMenuTool, ctlMenuToolList); + + +// *** ctlMenuToolbar - A replacement for wxToolBar which implements menu buttons +// and pull-down buttons +// +// A menu button is a standard looking toolbar tool which, when clicked, pops up a +// menu which can be selected. +// +// A pull-down button presents a small black triangle which, when clicked, pops up +// a menu which can be selected. These buttons are typically used for a list of previous +// actions (for example, previous web pages visited). + +class ctlMenuToolbar : public wxToolBar +{ +public: + ctlMenuToolbar(); + ctlMenuToolbar(wxFrame *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTB_HORIZONTAL | wxNO_BORDER, const wxString &name = wxPanelNameStr); + ~ctlMenuToolbar(); + + // NOTE: label, shortHelpString, are not implemented on all platforms and are only + // included for possible future upgrades + ctlMenuButton *AddMenuPulldownTool(int toolId, const wxString &label, const wxString &shortHelpString = wxEmptyString, wxMenu *popupmenu = 0); + void DoProcessLeftClick(wxMouseEvent &event); + +private: + wxFrame *m_frame; + ctlMenuToolList *m_menuTools; +}; + +#endif + diff --git a/include/ctl/ctlProgressStatusBar.h b/include/ctl/ctlProgressStatusBar.h new file mode 100644 index 0000000..de54bc5 --- /dev/null +++ b/include/ctl/ctlProgressStatusBar.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlProgressStatusBar.h - Status bar indicating the current progress +// +////////////////////////////////////////////////////////////////////////// +// +#ifndef CTLPROGRESS_STATUSBAR_H +#define CTLPROGRESS_STATUSBAR_H + +// wxWindows headers +#include +#include +#include + +class ctlProgressStatusBar : public wxStatusBar +{ +public: + ctlProgressStatusBar(wxWindow *parent, bool showProgressInitially = true, bool autoProgressive = true, int max = -1); + virtual ~ctlProgressStatusBar(); + + void ShowProgress(bool restart = true); + void StopProgress(); + void SetProgress(int val); + virtual void SetFieldsCount(int number = 1, const int *widths = NULL); + virtual void SetStatusWidths(int n, const int widths_field[]); + + static const unsigned short ms_increment, + ms_progressbar_width, + ms_progressstatus_width; + +protected: + void OnTimer(wxTimerEvent &WXUNUSED(event)); + void OnSize(wxSizeEvent &ev); + + wxGauge *m_progress; + wxTimer m_timer; + + bool m_progressStopped; + bool m_autoProgressive; + bool m_autoValIncrementing; + + int m_hr, m_min, m_sec, m_mil; + int m_val; + + enum + { + Status_field, + ProgressBar_field, + ProgressStatus_field, + Max_Field + }; + + DECLARE_EVENT_TABLE() +}; + +#endif // CTLPROGRESS_STATUSBAR_H diff --git a/include/ctl/ctlSQLBox.h b/include/ctl/ctlSQLBox.h new file mode 100644 index 0000000..93fb6e8 --- /dev/null +++ b/include/ctl/ctlSQLBox.h @@ -0,0 +1,137 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLBox.h - SQL syntax highlighting textbox +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSQLBOX_H +#define CTLSQLBOX_H + +// wxWindows headers +#include +#include +#include +#include "utils/macros.h" + +#include "db/pgConn.h" +#include "dlg/dlgFindReplace.h" +#include "ctl/ctlAuiNotebook.h" + +// These structs are from Scintilla.h which isn't easily #included :-( +struct CharacterRange +{ + long cpMin; + long cpMax; +}; + +struct TextToFind +{ + struct CharacterRange chrg; + char *lpstrText; + struct CharacterRange chrgText; +}; + +class sysProcess; + +// Class declarations +class ctlSQLBox : public wxStyledTextCtrl +{ + static wxString sqlKeywords; + +public: + ctlSQLBox(wxWindow *parent, wxWindowID id = -1, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0); + ctlSQLBox(); + ~ctlSQLBox(); + + void Create(wxWindow *parent, wxWindowID id = -1, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = 0); + void HighlightBrace(int lb, int rb); + void SetDatabase(pgConn *db); + void Copy(); + void OnKeyDown(wxKeyEvent &event); + void OnAutoComplete(wxCommandEvent &event); + void OnSearchReplace(wxCommandEvent &event); + void OnKillFocus(wxFocusEvent &event); +// void OnBackGround(wxEraseEvent &event); + void SetQueryBook(ctlAuiNotebook *query_book); + ctlAuiNotebook* GetQueryBook() + { + return sql_query_book; + }; + + bool Find(const wxString &find, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse, bool all=false); + bool Replace(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse); + bool ReplaceAll(const wxString &find, const wxString &replace, bool wholeWord, bool matchCase, bool useRegexps); + bool DoFind(const wxString &find, const wxString &replace, bool doReplace, bool wholeWord, bool matchCase, bool useRegexps, bool startAtTop, bool reverse); + void SetAutoReplaceList(queryMacroList *autorep); + void SetAutoIndent(bool on) + { + m_autoIndent = on; + } + void EnableAutoComp(bool on) + { + m_autocompDisabled = on; + } + bool BlockComment(bool uncomment = false); + void UpdateLineNumber(); + wxString ExternalFormat(); + void AbortProcess(); + void SetDefFunction(wxArrayString &name, wxArrayString &def); + CharacterRange RegexFindText(int minPos, int maxPos, const wxString &text); + + // Having multiple SQL tabs warrants the following properties to be tracked per tab + void SetChanged(bool b); + bool IsChanged(); + wxColor SetSQLBoxColourBackground(bool transaction); + void SetOrigin(int origin); + int GetOrigin(); + void SetFilename(wxString &filename); + wxString GetFilename(); + void SetTitle(wxString &title); + wxString GetTitle(bool withChangeInd = true); + wxString GetChangeIndicator(); + long SelectQuery(int startposition); + DECLARE_DYNAMIC_CLASS(ctlSQLBox) + DECLARE_EVENT_TABLE() + +protected: + void OnEndProcess(wxProcessEvent &ev); + void UpdateTitle(); + + sysProcess *process; + long processID; + wxString processOutput, processErrorOutput; + int processExitCode; + +private: + void OnPositionStc(wxStyledTextEvent &event); + void OnDoubleClick(wxStyledTextEvent &event); + void OnMarginClick(wxStyledTextEvent &event); + ctlAuiNotebook *sql_query_book; + queryMacroList *autoreplace; + wxArrayString *m_name; // field proname + wxArrayString *m_def; // finction arguments + wxString list_table; // list table from section + wxString calltip; + int ct_hl; + dlgFindReplace *m_dlgFindReplace; + pgConn *m_database; + bool m_autoIndent, m_autocompDisabled; + + // Variables to track info per SQL box + wxString m_filename; + wxString m_title; + wxString m_changestr; + bool m_changed; + int m_origin; + int fix_pos; + + friend class QueryPrintout; +}; + +#endif + diff --git a/include/ctl/ctlSQLGrid.h b/include/ctl/ctlSQLGrid.h new file mode 100644 index 0000000..d60c8fb --- /dev/null +++ b/include/ctl/ctlSQLGrid.h @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLGrid.h - SQL Data Display Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSQLGRID_H +#define CTLSQLGRID_H + +// wxWindows headers +#include + +class GroupRows; + +class ctlSQLGrid : public wxGrid +{ +public: + ctlSQLGrid(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size); + ctlSQLGrid(); + + wxString GetExportLine(int row); + wxString GetExportLine(int row, wxArrayInt cols); + wxString GetExportLine(int row, int col1, int col2); + virtual bool IsColText(int col) + { + return false; + } + int Copy(bool gensql); + + virtual bool CheckRowPresent(int row) + { + return true; + }; + bool IsSort() + { + return isSort; + }; + void SetSort(bool flag) + { + isSort=flag; + }; + + wxSize GetBestSize(int row, int col); + void OnLabelDoubleClick(wxGridEvent &event); + void OnLabelClick(wxGridEvent &event); + void OnCellRightClick(wxGridEvent &event); + bool FullArrayCollapseRowsPlan(bool clear); + void AutoSizeColumn(int col, bool setAsMin = false, bool doLimit = true); + void AutoSizeColumns(bool setAsMin); + wxString GetRowLabelValue( int row ); + void SetRowGroup(int row); + GroupRows *grp; + bool generatesql; + WX_DECLARE_STRING_HASH_MAP( int, ColKeySizeHashMap ); + + DECLARE_DYNAMIC_CLASS(ctlSQLGrid) + DECLARE_EVENT_TABLE() + +private: + void OnCopy(wxCommandEvent &event); + void OnMouseWheel(wxMouseEvent &event); + void OnGridColSize(wxGridSizeEvent &event); + void DrawColLabel( wxDC& dc, int col ); + wxString GetColumnName(int colNum); + wxString GetColKeyValue(int col); + void AppendColumnHeader(wxString &str, int start, int end); + void AppendColumnHeader(wxString &str, wxArrayInt columns); + // Stores sizes of colums explicitly resized by user + ColKeySizeHashMap colSizes; + // Max size for each column + wxArrayInt colMaxSizes; + bool isSort; + +}; + +class GroupRows +{ +public: + GroupRows( ctlSQLGrid *grid) { + g=grid; + rowsGroup.Clear(); + rowsGroup.Add(0,g->GetNumberRows()); + end.Clear(); + end.Add(-1,g->GetNumberRows()); + run.Clear(); + run.Add(0.0,g->GetNumberRows()); + }; + void AddGroup( int rowgroup, int lastrowgroup, double actualtime) { + // default group open + rowsGroup[rowgroup]=-rowgroup; + //beg[rowgroup]=rowgroup; + wxASSERT(lastrowgroup>end.Count()," out of bounds"); + end[rowgroup]=lastrowgroup; + run[rowgroup]=actualtime; + }; + void VisibleGroup(int row, bool visible) { + int endg=end[row]; + int grp=IsGroupRow(row); + int gg; + int r=row+1; + if (grp!=0) { + + if (!visible) { + // hide group + rowsGroup[row]*=-1; + for(int i=r;i<(endg+1);i++) { + g->HideRow(i); + } + wxGridCellAttr* pAttrg = new wxGridCellAttr; + pAttrg->SetBackgroundColour(wxColour(200,191,232)); + g->SetRowAttr(row,pAttrg); + } else + { + // show group + rowsGroup[row]*=-1; + int sizerow=g->GetDefaultRowSize(); + //pAttr->SetBackgroundColour(wxColour(0,162,232)); + wxGridCellAttr* pAttrg = new wxGridCellAttr; + pAttrg->SetBackgroundColour(wxColour(248,240,130)); + g->SetRowAttr(row,pAttrg); + for(int i=r;i<(endg+1);i++) { + gg=IsGroupRow(i); + if (gg<=0) { + g->SetRowSize(i,sizerow); + } + else + { + g->SetRowSize(i,sizerow); + i=end[i]; + } + + } + + } + } + }; + // 0 - no group, -int - open group ,+int - close gruop + int IsGroupRow(int row) { + if (end[row]!=-1) { + // is group + return rowsGroup[row]; + } else return 0; + }; + void ColoriseRow(int row,const wxColour& color) { + //g->GetTable()->SetRowLabelValue(row-1,s); + wxGridCellAttr* pAttr = new wxGridCellAttr; + pAttr->SetBackgroundColour(color); + g->SetRowAttr(row,pAttr); + }; + void CalcTime() { + //g->GetTable()->SetRowLabelValue(row-1,s); + double sum=0; + double total=1; + for(int i=0;iGetTable()->SetRowLabelValue(i,"100"); + } else + { + wxString str; + if (total==0||t==0) { + str=""; + } else + { + + t=(t/total)*100; + str.Printf(wxT("%5.2f"), t); + } + g->GetTable()->SetRowLabelValue(i,str); + } + + } + + + }; + +private: + ctlSQLGrid *g; + wxArrayInt rowsGroup, end; + wxArrayDouble run; +}; + +class CursorCellRenderer : public wxGridCellStringRenderer + { + public: + virtual void Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc, + const wxRect& rect, int row, int col, bool isSelected) + { + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + ////////////////////////////////////////////////////////////////////////////// + //CursorCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); // + dc.SetBackgroundMode( wxSOLID ); + wxString text=grid.GetCellValue(row, col); + // grey out fields if the grid is disabled + if ( grid.IsEnabled() ) + { + if ( isSelected ) + { + wxColour clr; + if ( wxWindow::FindFocus() == grid.GetGridWindow() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + dc.SetBrush( wxBrush(clr, wxSOLID) ); + } + else + { + wxColor color; + color.Set(239, 228, 176); + if (text.Find(wxT('\n'))!=wxNOT_FOUND ) + dc.SetBrush( wxBrush(color, wxSOLID) ); + else + dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) ); + } + } + else + { + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID)); + } + + dc.SetPen( *wxTRANSPARENT_PEN ); + dc.DrawRectangle(rect); + + ////////////////////////////////////////////////////////////////////////////// + SetTextColoursAndFont(grid, attr, dc, isSelected); + grid.DrawTextRectangle(dc, text, + rect, hAlign, vAlign); + } + + }; + +#endif diff --git a/include/ctl/ctlSQLResult.h b/include/ctl/ctlSQLResult.h new file mode 100644 index 0000000..45e11d9 --- /dev/null +++ b/include/ctl/ctlSQLResult.h @@ -0,0 +1,130 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSQLResult.h - SQL Query result window +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSQLRESULT_H +#define CTLSQLRESULT_H + +// wxWindows headers +#include + +#include "db/pgSet.h" +#include "db/pgConn.h" +#include "ctlSQLGrid.h" +#include "frm/frmExport.h" + +#define CTLSQL_RUNNING 100 // must be greater than ExecStatusType PGRES_xxx values + +class ctlSQLResult : public ctlSQLGrid +{ +public: + ctlSQLResult(wxWindow *parent, pgConn *conn, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize); + ~ctlSQLResult(); + + + int Execute(const wxString &query, int resultToDisplay = 0, wxWindow *caller = 0, long eventId = 0, void *data = 0); // > 0: resultset to display, <=0: last result + void SetConnection(pgConn *conn); + long NumRows() const; + long InsertedCount() const; + OID InsertedOid() const; + wxColor cg; + int Abort(); + + bool Export(); + bool ToFile(); + bool ToFile(frmExport *frm); + bool CanExport() + { + return NumRows() > 0 && colNames.GetCount() > 0; + } + + wxString OnGetItemText(long item, long col) const; + wxString SummaryColumn(); + void ClearFilter(); + bool IsColText(int col); + bool hasRowNumber() + { + return !rowcountSuppressed; + } + + int RunStatus(); + wxString GetMessagesAndClear(); + wxString GetErrorMessage(); + pgError GetResultError(); + + void DisplayData(bool single = false); + + bool GetRowCountSuppressed() + { + return rowcountSuppressed; + }; + + void SetMaxRows(int rows); + void ResultsFinished(); + void OnGridSelect(wxGridRangeSelectEvent &event); + void OnGridColSort(wxGridEvent& event); + wxString SetFilter(int row,int col,bool reverse); + + wxArrayString colNames; + wxArrayString colTypes; + wxArrayLong colTypClasses; + wxString sqlquerytext; +private: + pgQueryThread *thread; + pgConn *conn; + bool rowcountSuppressed; +}; + +class sqlResultTable : public wxGridStringTable//wxGridTableBase +{ +public: + sqlResultTable(); + wxString GetValue(int row, int col); + wxString GetValueFast(int row, int col); + wxString GetRowLabelValue( int row ) ; + int GetNumberRows(); + int GetNumberCols(); + bool isplan; + bool use_map; // use maplines for GetValue + int *maplines; // maplines[visible_row]=real_row + int *colorder; // array order type -1 desc , 0 no sort, 1 asc +#define MAX_COL_SORT 5 + int colsortnumber[MAX_COL_SORT]; + int sortColumns(); // + int setSortColumn(int col); // set order for column (cycle change value -1,0,1) + int getSortColumn(int col); + int initSort(); // allocate memory + bool IsEmptyCell(int row, int col) + { + return false; + } + wxString GetColLabelValue(int col); + void SetValue(int row, int col, const wxString &value) + { + return; + } + void SetThread(pgQueryThread *t) + { + thread = t; + } + bool DeleteRows(size_t pos = 0, size_t numRows = 1) + { + return true; + } + bool DeleteCols(size_t pos = 0, size_t numCols = 1) + { + return true; + } + +private: + pgQueryThread *thread; +}; + +#endif diff --git a/include/ctl/ctlSeclabelPanel.h b/include/ctl/ctlSeclabelPanel.h new file mode 100644 index 0000000..15321d3 --- /dev/null +++ b/include/ctl/ctlSeclabelPanel.h @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSeclabelPanel.h - Panel with security label information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_SECLBLPANEL_H +#define CTL_SECLBLPANEL_H + +#include +#include + +enum +{ + CTL_LBSECLABEL = 250, + CTL_ADDSECLABEL, + CTL_DELSECLABEL, + CTL_PROVIDER, + CTL_SECLABEL +}; + +DECLARE_LOCAL_EVENT_TYPE(EVT_SECLABELPANEL_CHANGE, -1) + +class pgConn; + +class ctlSeclabelPanel : public wxPanel +{ + +public: + + ctlSeclabelPanel(wxNotebook *nb); + ~ctlSeclabelPanel(); + + ctlListView *lbSeclabels; + void SetConnection(pgConn *conn); + void SetObject(pgObject *obj); + void Disable(); + wxString GetSqlForSecLabels(wxString objecttype = wxEmptyString, wxString objectname = wxEmptyString); + void GetCurrentProviderLabelArray(wxArrayString &secLabels); +protected: + wxNotebook *nbNotebook; + pgConn *connection; + pgObject *object; + + wxButton *btnAddSeclabel, *btnDelSeclabel; + wxTextCtrl *txtProvider, *txtSeclabel; + + void OnSeclabelSelChange(wxListEvent &ev); + void OnAddSeclabel(wxCommandEvent &ev); + void OnDelSeclabel(wxCommandEvent &ev); + void OnProviderChange(wxCommandEvent &ev); + void OnSeclabelChange(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/ctl/ctlSecurityPanel.h b/include/ctl/ctlSecurityPanel.h new file mode 100644 index 0000000..2ac7aa8 --- /dev/null +++ b/include/ctl/ctlSecurityPanel.h @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlSecurityPanel.h - Panel with security information +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef CTL_SECPANEL_H +#define CTL_SECPANEL_H + +#include +#include + +enum +{ + CTL_PROPSQL = 250, + CTL_MSG, + CTL_LBPRIV, + CTL_STATICGROUP, + CTL_CBGROUP, + CTL_ADDPRIV, + CTL_DELPRIV, + CTL_ALLPRIV, + CTL_ALLPRIVGRANT, + CTL_PRIVCB // base for all privilege checkboxes, must be last +}; + +DECLARE_LOCAL_EVENT_TYPE(EVT_SECURITYPANEL_CHANGE, -1) + +class pgConn; + +class ctlSecurityPanel : public wxPanel +{ + +public: + + ctlSecurityPanel(wxNotebook *nb, const wxString &privList, const char *privChars, wxImageList *imgList); + ~ctlSecurityPanel(); + + ctlListView *lbPrivileges; + ctlComboBox *cbGroups; + wxStaticText *stGroup; + void SetConnection(pgConn *conn); + + /* + * Except column level privileges, column will be always an empty string in any case + */ + wxString GetGrant(const wxString &allPattern, const wxString &grantObject, wxArrayString *currentAcl = 0, wxString column = wxEmptyString); + wxString GetUserPrivileges(); + bool DisablePrivilege(const wxString &priv); +protected: + wxNotebook *nbNotebook; + pgConn *connection; + + wxButton *btnAddPriv, *btnDelPriv; + int privilegeCount; + const char *privilegeChars; + wxCheckBox **privCheckboxes; + wxCheckBox *allPrivileges, *allPrivilegesGrant; + + void OnPrivSelChange(wxListEvent &ev); + void OnAddPriv(wxCommandEvent &ev); + void OnGroupChange(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + void OnPrivCheck(wxCommandEvent &ev); + void OnPrivCheckAll(wxCommandEvent &ev); + void OnPrivCheckAllGrant(wxCommandEvent &ev); + + void CheckGrantOpt(int index); + bool GrantAllowed() const; + + + DECLARE_EVENT_TABLE() +}; + + + +#endif diff --git a/include/ctl/ctlTree.h b/include/ctl/ctlTree.h new file mode 100644 index 0000000..90f1dcc --- /dev/null +++ b/include/ctl/ctlTree.h @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTree.h - wxTreeCtrl containing pgObjects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CTLTREE_H +#define CTLTREE_H + +// wxWindows headers +#include +#include +#include + +class pgObject; +class pgCollection; +class pgaFactory; +class ctlTreeFindTimer; + +class ctlTree : public wxTreeCtrl +{ +public: + ctlTree(wxWindow *parent, wxWindowID id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxTR_HAS_BUTTONS); + void SetItemImage(const wxTreeItemId &item, int image, wxTreeItemIcon which = wxTreeItemIcon_Normal); + wxTreeItemId AppendItem(const wxTreeItemId &parent, const wxString &text, int image = -1, int selImage = -1, wxTreeItemData *data = NULL); + wxTreeItemId AppendObject(pgObject *parent, pgObject *object); + void RemoveDummyChild(pgObject *obj); + pgCollection *AppendCollection(pgObject *parent, pgaFactory &factory); + pgObject *GetObject(wxTreeItemId id); + pgObject *GetParentObject(wxTreeItemId id) + { + return GetObject(GetItemParent(id)); + } + pgCollection *GetParentCollection(wxTreeItemId id); + pgObject *FindObject(pgaFactory &factory, wxTreeItemId parent); + pgCollection *FindCollection(pgaFactory &factory, wxTreeItemId parent); + wxTreeItemId FindItem(const wxTreeItemId &item, const wxString &str, bool full = false); + void NavigateTree(int keyCode); + virtual ~ctlTree(); + + DECLARE_EVENT_TABLE() + +private: + void OnChar(wxKeyEvent &event); + wxString m_findPrefix; + ctlTreeFindTimer *m_findTimer; + + friend class ctlTreeFindTimer; +}; + + +// timer used to clear ctlTreeCtrl::m_findPrefix if no key was pressed +// for a sufficiently long time +class ctlTreeFindTimer : public wxTimer +{ +public: + // reset the current prefix after half a second of inactivity + enum { CTLTREE_DELAY = 500 }; + + ctlTreeFindTimer( ctlTree *owner ) + { + m_owner = owner; + } + + virtual void Notify() + { + m_owner->m_findPrefix.clear(); + } + +private: + ctlTree *m_owner; + + DECLARE_NO_COPY_CLASS(ctlTreeFindTimer) +}; + + +class treeObjectIterator +{ +public: + treeObjectIterator(ctlTree *browser, pgObject *obj); + pgObject *GetNextObject(); + +private: + wxTreeItemId lastItem; + ctlTree *browser; + pgObject *object; + wxCookieType cookie; +}; + + + +#endif diff --git a/include/ctl/explainCanvas.h b/include/ctl/explainCanvas.h new file mode 100644 index 0000000..a89bda3 --- /dev/null +++ b/include/ctl/explainCanvas.h @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// explainCanvas.h - Explain Canvas +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EXPLAINCANVAS_H +#define EXPLAINCANVAS_H + +#if wxUSE_POPUPWIN +#include "wx/popupwin.h" + +#define pgTipWindowBase wxPopupTransientWindow +#else +#include "wx/frame.h" + +#define pgTipWindowBase wxFrame +#endif + +#include + + +#if wxUSE_DEPRECATED +#error wxUSE_DEPRECATED should be 0! +#endif + + +class ExplainShape; +class ExplainPopup; +class ExplainText; + +class ExplainCanvas : public wxShapeCanvas +{ +public: + ExplainCanvas(wxWindow *parent); + ~ExplainCanvas(); + + void ShowPopup(ExplainShape *s); + void SetExplainString(const wxString &str); + void Clear(); + void SaveAsImage(const wxString &fileName, wxBitmapType imageType); + +private: + void OnMouseMotion(wxMouseEvent &ev); + + ExplainShape *rootShape; + ExplainPopup *popup; + + DECLARE_EVENT_TABLE() +}; + + +class ExplainShape : public wxBitmapShape +{ +public: + ExplainShape(const wxImage &bmp, const wxString &description, long tokenNo = -1, long detailNo = -1); + static ExplainShape *Create(long level, ExplainShape *last, const wxString &str); + + void SetCondition(const wxString &str) + { + if (condition.Length() == 0) condition = str; + else condition += wxT(" ") + str; + } + long GetLevel() + { + return level; + } + wxRealPoint GetStartPoint(); + wxRealPoint GetEndPoint(int kidNo); + int GetKidno() + { + return kidNo; + } + + ExplainShape *GetUpper() + { + return upperShape; + } + double GetAverageCost() + { + return (costHigh - costLow) / 2 + costLow; + } + +protected: + void OnDraw(wxDC &dc); + void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + + ExplainShape *upperShape; + + void SetLabel(const wxString &str, int tokenNo = -1, int detailNo = -1); + + long level; + wxString description, detail, condition, label; + wxString cost, actual; + double costLow, costHigh; + long rows, width; + int kidCount, kidNo; + int totalShapes; // horizontal space usage by shape and its kids + int usedShapes; + bool m_rootShape; + + friend class ExplainCanvas; + friend class ExplainText; +}; + + +class ExplainLine : public wxLineShape +{ +public: + ExplainLine(ExplainShape *from, ExplainShape *to, double weight = 0); + +private: + int width; + void OnDraw(wxDC &dc); +}; + + +class ExplainPopup : public pgTipWindowBase +{ +public: + ExplainPopup(ExplainCanvas *parent, ExplainShape *shape, ExplainPopup **popup = NULL); + void Close(); + ~ExplainPopup(); + +protected: + // event handlers + void OnMouseClick(wxMouseEvent &event); + void OnMouseMove(wxMouseEvent &ev); + +#if !wxUSE_POPUPWIN + void OnActivate(wxActivateEvent &event); + void OnKillFocus(wxFocusEvent &event); + +#else // wxUSE_POPUPWIN + virtual void OnDismiss(); + void OnMouseLost(wxMouseCaptureLostEvent &ev); +#endif // wxUSE_POPUPWIN/!wxUSE_POPUPWIN + + ExplainPopup **m_ptr; + wxRect m_rectBound; + + ExplainText *m_explainText; + +#if !wxUSE_POPUPWIN + long m_creationTime; +#endif // !wxUSE_POPUPWIN + + friend class ExplainText; + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/ctl/module.mk b/include/ctl/module.mk new file mode 100644 index 0000000..579a728 --- /dev/null +++ b/include/ctl/module.mk @@ -0,0 +1,42 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ctl/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/ctl/calbox.h \ + include/ctl/ctlAuiNotebook.h \ + include/ctl/ctlCheckTreeView.h \ + include/ctl/ctlColourPicker.h \ + include/ctl/ctlComboBox.h \ + include/ctl/ctlListView.h \ + include/ctl/ctlMenuToolbar.h \ + include/ctl/ctlDefaultSecurityPanel.h \ + include/ctl/ctlSeclabelPanel.h \ + include/ctl/ctlSecurityPanel.h \ + include/ctl/ctlSQLBox.h \ + include/ctl/ctlSQLGrid.h \ + include/ctl/ctlSQLResult.h \ + include/ctl/ctlProgressStatusBar.h \ + include/ctl/ctlTree.h \ + include/ctl/explainCanvas.h \ + include/ctl/timespin.h \ + include/ctl/wxgridsel.h \ + include/ctl/xh_calb.h \ + include/ctl/xh_ctlcombo.h \ + include/ctl/xh_ctlcolourpicker.h \ + include/ctl/xh_ctlchecktreeview.h \ + include/ctl/xh_ctltree.h \ + include/ctl/xh_sqlbox.h \ + include/ctl/xh_timespin.h + +EXTRA_DIST += \ + include/ctl/module.mk + + diff --git a/include/ctl/timespin.h b/include/ctl/timespin.h new file mode 100644 index 0000000..312af2c --- /dev/null +++ b/include/ctl/timespin.h @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// timespin.h - timeSpan SpinCtrl +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_TIMESPIN_H_ +#define _WX_TIMESPIN_H_ + +#include "wx/datetime.h" +#include "wx/spinbutt.h" + + +class wxTimeSpinCtrl : public wxControl +{ +public: + wxTimeSpinCtrl() + { + Init(); + } + wxTimeSpinCtrl(wxWindow *parent, + wxWindowID id, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxWANTS_CHARS, const wxString &name = wxT("wxTimeSpinCtrl")); + + bool Create(wxWindow *parent, + wxWindowID id, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxWANTS_CHARS, const wxString &name = wxT("wxTimeSpinCtrl")); + + bool Destroy(); + bool Enable(bool enable = true); + + void SetMax(long seconds, bool useDay = false); + bool SetValue(const wxTimeSpan &span); + bool SetTime(const wxDateTime &time); + wxTimeSpan GetValue(); + +private: + void Init(); + + void OnSpinUp(wxSpinEvent &ev); + void OnSpinDown(wxSpinEvent &ev); + void OnSpin(wxSpinEvent &ev); + void OnText(wxCommandEvent &ev); + void OnSetFocus(wxFocusEvent &ev); + void OnKillFocus(wxFocusEvent &ev); + void OnEditKey(wxKeyEvent &ev); + void OnNavigate(wxNavigationKeyEvent &ev); + + long GetTextTime(); + int GetTimePart(); + void DoSpin(int diff); + void Highlight(int tp); + + wxTextCtrl *m_txt; + wxSpinButton *m_spn; + wxString m_format; + long spinValue, maxSpinValue; + bool canWrap, hasDay; + + wxSize DoGetBestSize() const; + void OnSize(wxSizeEvent &event); + + DECLARE_DYNAMIC_CLASS(wxTimeSpinCtrl) + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxTimeSpinCtrl) +}; + + +#if 0 +class wxTimeSpinCtrl : public wxSpinCtrl //wxControl +{ +public: + wxTimeSpinCtrl() { } + wxTimeSpinCtrl(wxWindow *parent, + wxWindowID id, + const wxDateTime &date = wxDefaultDateTime, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxWANTS_CHARS, const wxString &name = wxT("wxTimeSpinCtrl")); + + bool Destroy(); + + + bool Create(wxWindow *parent, + wxWindowID id, + const wxDateTime &date, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name); + + bool SetValue(const wxTimeSpan &span); + wxTimeSpan GetValue(); + + virtual bool Enable(bool enable = true); + virtual bool Show(bool show = true); + virtual void DoMoveWindow(int x, int y, int width, int height); + +private: + wxTextCtrl *m_txt; + wxSpinCtrl *m_spn; + wxButton *m_btn; + wxString m_format; + + bool m_dropped, m_processing; + + void Init(); + void DropDown(bool down = true); + + void OnEditKey(wxKeyEvent &event); + void OnCalKey(wxKeyEvent &event); + void OnClick(wxMouseEvent &ev); + void OnSelChange(wxCalendarEvent &ev); + void OnActivate(wxActivateEvent &ev); + void OnSetFocus(wxFocusEvent &ev); + void OnKillFocus(wxFocusEvent &ev); + + DECLARE_DYNAMIC_CLASS(wxTimeSpinCtrl) + DECLARE_EVENT_TABLE() + DECLARE_NO_COPY_CLASS(wxTimeSpinCtrl) +}; +#endif + + +#endif // _WX_TIMESPIN_H_ + diff --git a/include/ctl/wxgridsel.h b/include/ctl/wxgridsel.h new file mode 100644 index 0000000..a5593cc --- /dev/null +++ b/include/ctl/wxgridsel.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// wxgridsel.h - replacement for wx/generic/gridsel.h +// if binary wxWindows 2.4.0 distribution is used. +// This file is necessary until wxGrid supports multiple wxGrid::SetTable() calls +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __WXGRIDSEL_H +#define __WXGRIDSEL_H + + +class wxGridSelection +{ + wxGridCellCoordsArray dummy1[3]; + wxArrayInt dummy2[2]; + void *dummy3; + wxGrid::wxGridSelectionModes dummy4; +}; + +#endif diff --git a/include/ctl/xh_calb.h b/include/ctl/xh_calb.h new file mode 100644 index 0000000..bded110 --- /dev/null +++ b/include/ctl/xh_calb.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_calb.h - wxCalendarBox handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CALB_H_ +#define _WX_XH_CALB_H_ + + +#include "wx/xrc/xmlres.h" + +//class WXDLLIMPEXP_XRC +class wxCalendarBoxXmlHandler : public wxXmlResourceHandler +{ + DECLARE_DYNAMIC_CLASS(wxCalendarBoxXmlHandler) +public: + wxCalendarBoxXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif // _WX_XH_CALB_H_ diff --git a/include/ctl/xh_ctlchecktreeview.h b/include/ctl/xh_ctlchecktreeview.h new file mode 100644 index 0000000..f96ce47 --- /dev/null +++ b/include/ctl/xh_ctlchecktreeview.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlchecktreeview.h - ctlCheckTreeView handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLCHECKTREEVIEW_H_ +#define _WX_XH_CTLCHECKTREEVIEW_H_ + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_tree.h" + +//class WXDLLIMPEXP_XRC +class ctlCheckTreeViewXmlHandler : public wxTreeCtrlXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlCheckTreeViewXmlHandler) +public: + ctlCheckTreeViewXmlHandler() : wxTreeCtrlXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_ctlcolourpicker.h b/include/ctl/xh_ctlcolourpicker.h new file mode 100644 index 0000000..0d584d7 --- /dev/null +++ b/include/ctl/xh_ctlcolourpicker.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the BSD Licence +// +// xh_ctlcolourpicker.h - ctlColourPicker handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLCOLOURPICKER_H_ +#define _WX_XH_CTLCOLOURPICKER_H_ + + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_bmpbt.h" + +//class WXDLLIMPEXP_XRC +class ctlColourPickerXmlHandler : public wxBitmapButtonXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlColourPickerXmlHandler) +public: + ctlColourPickerXmlHandler() : wxBitmapButtonXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_ctlcombo.h b/include/ctl/xh_ctlcombo.h new file mode 100644 index 0000000..a117260 --- /dev/null +++ b/include/ctl/xh_ctlcombo.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctlcombo.h - ctlComboBox handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLCOMBO_H_ +#define _WX_XH_CTLCOMBO_H_ + + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_combo.h" + +//class WXDLLIMPEXP_XRC +class ctlComboBoxXmlHandler : public wxComboBoxXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlComboBoxXmlHandler) +public: + ctlComboBoxXmlHandler() : wxComboBoxXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_ctltree.h b/include/ctl/xh_ctltree.h new file mode 100644 index 0000000..a9e7adc --- /dev/null +++ b/include/ctl/xh_ctltree.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_ctltree.h - ctlTree handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_CTLTREE_H_ +#define _WX_XH_CTLTREE_H_ + +#include "wx/xrc/xmlres.h" +#include "wx/xrc/xh_tree.h" + +//class WXDLLIMPEXP_XRC +class ctlTreeXmlHandler : public wxTreeCtrlXmlHandler +{ + DECLARE_DYNAMIC_CLASS(ctlTreeXmlHandler) +public: + ctlTreeXmlHandler() : wxTreeCtrlXmlHandler() {} + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif diff --git a/include/ctl/xh_sqlbox.h b/include/ctl/xh_sqlbox.h new file mode 100644 index 0000000..f744b0b --- /dev/null +++ b/include/ctl/xh_sqlbox.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_sqlbox.h - wxSqlBox handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_SQLBOX_H_ +#define _WX_XH_SQLBOX_H_ + + +#include "wx/xrc/xmlres.h" + +//class WXDLLIMPEXP_XRC +class ctlSQLBoxXmlHandler : public wxXmlResourceHandler +{ + DECLARE_DYNAMIC_CLASS(ctlSQLBoxXmlHandler) +public: + ctlSQLBoxXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif // _WX_XH_SQLBOX_H_ diff --git a/include/ctl/xh_timespin.h b/include/ctl/xh_timespin.h new file mode 100644 index 0000000..d1a8f63 --- /dev/null +++ b/include/ctl/xh_timespin.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// xh_timespin.h - wxTimeSpinCtrl handler +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_XH_TIMESPIN_H_ +#define _WX_XH_TIMESPIN_H_ + + +#include "wx/xrc/xmlres.h" + +//class WXDLLIMPEXP_XRC +class wxTimeSpinXmlHandler : public wxXmlResourceHandler +{ + DECLARE_DYNAMIC_CLASS(wxTimeSpinXmlHandler) +public: + wxTimeSpinXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); +}; + + +#endif // _WX_XH_TIMESPIN_H_ diff --git a/include/db/module.mk b/include/db/module.mk new file mode 100644 index 0000000..fe82643 --- /dev/null +++ b/include/db/module.mk @@ -0,0 +1,20 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/db/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/db/pgConn.h \ + include/db/pgQueryThread.h \ + include/db/pgQueryResultEvent.h \ + include/db/pgSet.h + +EXTRA_DIST += \ + include/db/module.mk + diff --git a/include/db/pgConn.h b/include/db/pgConn.h new file mode 100644 index 0000000..2af4733 --- /dev/null +++ b/include/db/pgConn.h @@ -0,0 +1,315 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConn.h - PostgreSQL Connection class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCONN_H +#define PGCONN_H + +// wxWindows headers +#include + +// PostgreSQL headers +#include + +// App headers +#include "pgSet.h" + +// status enums +enum +{ + PGCONN_OK = CONNECTION_OK, + PGCONN_BAD = CONNECTION_BAD, + PGCONN_REFUSED, + PGCONN_DNSERR, + PGCONN_ABORTED, // connect user aborted + PGCONN_BROKEN, // tcp/pipe broken + PGCONN_SSHTUNNEL_ERROR +}; + +enum +{ + PGCONN_EMPTY_QUERY = PGRES_EMPTY_QUERY, + PGCONN_COMMAND_OK = PGRES_COMMAND_OK, + PGCONN_TUPLES_OK = PGRES_TUPLES_OK, + PGCONN_COPY_OUT = PGRES_COPY_OUT, + PGCONN_COPY_IN = PGRES_COPY_IN, + PGCONN_BAD_RESPONSE = PGRES_BAD_RESPONSE, + PGCONN_NONFATAL_ERROR = PGRES_NONFATAL_ERROR, + PGCONN_FATAL_ERROR = PGRES_FATAL_ERROR +}; + +enum +{ + PGCONN_TXSTATUS_IDLE = PQTRANS_IDLE, + PGCONN_TXSTATUS_ACTIVE = PQTRANS_ACTIVE, + PGCONN_TXSTATUS_INTRANS = PQTRANS_INTRANS, + PGCONN_TXSTATUS_INERROR = PQTRANS_INERROR, + PGCONN_TXSTATUS_UNKNOWN = PQTRANS_UNKNOWN +}; + +// Our version of a pgNotify +typedef struct pgNotification +{ + wxString name; + int pid; + wxString data; +} pgNotification; + +// An error record +typedef struct pgError +{ + wxString severity; + wxString sql_state; + wxString msg_primary; + wxString msg_detail; + wxString msg_hint; + wxString statement_pos; + wxString internal_pos; + wxString internal_query; + wxString context; + wxString source_file; + wxString source_line; + wxString source_function; + wxString formatted_msg; + + void SetError(PGresult *_res = NULL, wxMBConv *_conv = NULL); +} pgError; + +class pgConn +{ +public: + pgConn(const wxString &server = wxT(""), const wxString &service = wxT(""), const wxString &hostaddr = wxT(""), + const wxString &database = wxT(""), const wxString &username = wxT(""), const wxString &password = wxT(""), + int port = 5432, const wxString &rolename = wxT(""), int sslmode = 0, OID oid = 0, + const wxString &applicationname = wxT("pgAdmin"), + const wxString &sslcert = wxT(""), const wxString &sslkey = wxT(""), const wxString &sslrootcert = wxT(""), const wxString &sslcrl = wxT(""), + const bool sslcompression = true); + ~pgConn(); + + bool IsSuperuser(); + bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv); + bool HasFeature(int feature = 0, bool forceCheck = false); + bool BackendMinimumVersion(int major, int minor); + bool BackendMinimumVersion(int major, int minor, int patch); + bool EdbMinimumVersion(int major, int minor); + wxString SystemNamespaceRestriction(const wxString &nsp); + int GetMajorVersion() const + { + return majorVersion; + } + int GetMinorVersion() const + { + return minorVersion; + } + bool GetIsEdb(); + bool GetIsPgProEnt(); + bool GetIsGreenplum(); + bool GetIsHawq(); + wxString EncryptPassword(const wxString &user, const wxString &password); + wxString qtDbString(const wxString &value); + pgConn *Duplicate(const wxString &_appName = wxT("")); + + static void ExamineLibpqVersion(); + static double GetLibpqVersion() + { + return libpqVersion; + } + + static bool IsValidServerEncoding(int encid) + { + return pg_valid_server_encoding_id(encid) == 0 ? false : true; + } + + void Close(); + bool Reconnect(); + bool ExecuteVoid(const wxString &sql, bool reportError = true); + wxString ExecuteScalar(const wxString &sql, bool reportError = true); + pgSet *ExecuteSet(const wxString &sql, bool reportError = true); + void CancelExecution(void); + + wxString GetHostAddr() const + { + return save_hostaddr; + } + wxString GetService() const + { + return save_service; + } + wxString GetUser() const + { + return conn ? wxString(PQuser(conn), *conv) : wxT(""); + } + wxString GetPassword() const + { + return conn ? wxString(PQpass(conn), *conv) : wxT(""); + } + wxString GetRole() const + { + return dbRole; + } + wxString GetHost() const + { + return dbHost; + } + wxString GetHostName() const + { + return dbHostName; + } + wxString GetDbname() const + { + return save_database; + } + wxString GetApplicationName() const + { + return save_applicationname; + } + wxString GetSSLCert() const + { + return save_sslcert; + } + wxString GetSSLKey() const + { + return save_sslkey; + } + wxString GetSSLRootCert() const + { + return save_sslrootcert; + } + wxString GetSSLCrl() const + { + return save_sslcrl; + } + bool GetSSLCompression() const + { + return save_sslcompression; + } + wxString GetName() const; + bool GetNeedUtfConnectString() + { + return utfConnectString; + } + int GetPort() const + { + return conn ? atoi(PQport(conn)) : 0; + }; + wxString GetTTY() const + { + return conn ? wxString(PQtty(conn), *conv) : wxT(""); + } + wxString GetOptions() const + { + return conn ? wxString(PQoptions(conn), *conv) : wxT(""); + } + int GetSslMode() const + { + return save_sslmode; + } + wxString GetSslModeName(); + int GetBackendPID() const + { + return conn ? PQbackendPID(conn) : 0; + } + int GetStatus() const; + int GetLastResultStatus() const + { + return lastResultStatus; + } + bool IsAlive(); + wxString GetLastError() const; + pgError GetLastResultError() const + { + return lastResultError; + } + wxString GetVersionString(); + OID GetLastSystemOID() const + { + return lastSystemOID; + } + OID GetDbOid() const + { + return dbOid; + } + void RegisterNoticeProcessor(PQnoticeProcessor proc, void *arg); + wxMBConv *GetConv() + { + return conv; + }; + + void LogError(const bool quiet = false); + + bool IsSSLconnected(); + PGconn *connection() + { + return conn; + } + void Notice(const char *msg); + pgNotification *GetNotification(); + int GetTxStatus(); + + void Reset(); + + bool StartCopy(const wxString query); + bool PutCopyData(const char *data, long count); + bool EndPutCopy(const wxString errormsg); + bool GetCopyFinalStatus(void); + + bool TableHasColumn(wxString schemaname, wxString tblname, const wxString &colname); + +protected: + PGconn *conn; + PGcancel *m_cancelConn; + wxMutex m_cancelConnMutex; + int lastResultStatus; + + int connStatus; + + void SetLastResultError(PGresult *res, const wxString &msg = wxEmptyString); + void SetConnCancel(void); + void ResetConnCancel(void); + pgError lastResultError; + + wxMBConv *conv; + bool needColQuoting, utfConnectString; + wxString dbRole, dbHost, dbHostName; + OID lastSystemOID; + OID dbOid; + + void *noticeArg; + PQnoticeProcessor noticeProc; + static double libpqVersion; + + friend class pgQueryThread; + +private: + bool DoConnect(); + bool Initialize(); + + wxString qtString(const wxString &value); + + bool features[32]; + int minorVersion, majorVersion, patchVersion; + bool isEdb; + bool isGreenplum; + bool isPgProEnt; + bool isHawq; + + wxString reservedNamespaces; + wxString connstr; + + wxString save_server, save_service, save_hostaddr, save_database, save_username, save_password, save_rolename, save_applicationname; + wxString save_sslcert, save_sslkey, save_sslrootcert, save_sslcrl; + int save_port, save_sslmode; + bool save_sslcompression; + OID save_oid; +}; + +#endif + + diff --git a/include/db/pgQueryResultEvent.h b/include/db/pgQueryResultEvent.h new file mode 100644 index 0000000..f47ce66 --- /dev/null +++ b/include/db/pgQueryResultEvent.h @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgQueryResultEvent.h - Query Result Event from the pgQueryThread +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGQUERYRESULTEVENT_H +#define PGQUERYRESULTEVENT_H + +#include "wx/wx.h" +#include "wx/event.h" + +class pgBatchQuery; + +extern const wxEventType PGQueryResultEvent; + + +class pgQueryResultEvent : public wxCommandEvent +{ +public: + pgQueryResultEvent(unsigned long _thrdId, pgBatchQuery *_qry, int _id = 0); + pgQueryResultEvent(const pgQueryResultEvent &_ev); + + // Required for sending with wxPostEvent() + wxEvent *Clone() const + { + return new pgQueryResultEvent(*this); + } + + pgBatchQuery *GetQuery() + { + return m_query; + } + unsigned long GetThreadID() + { + return m_thrdId; + } + + enum + { + PGQ_RESULT_ERROR = -8, + PGQ_EXECUTION_CANCELLED = -7, + PGQ_ERROR_CONSUME_INPUT = -6, + PGQ_ERROR_SEND_QUERY = -5, + PGQ_ERROR_EXECUTE_CALLABLE = -4, + PGQ_ERROR_PREPARE_CALLABLE = -3, + PGQ_STRING_INVALID = -2, + PGQ_CONN_LOST = -1, + }; + +private: + pgBatchQuery *m_query; + // Thread Id (pgQueryThread) + unsigned long m_thrdId; +}; + +typedef void (wxEvtHandler::*pgQueryResultEventFunc)(pgQueryResultEvent &); + +// This #define simplifies the one below, and makes the syntax less +// ugly if you want to use Connect() instead of an event table. +#define pgQueryResultEventHandler(func) \ + (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction) \ + wxStaticCastEvent(pgQueryResultEventFunc, &func) + +// Define the event table entry. Yes, it really *does* end in a comma. +#define EVT_PGQUERYRESULT(id, fn) \ + DECLARE_EVENT_TABLE_ENTRY(PGQueryResultEvent, id, wxID_ANY, \ + pgQueryResultEventHandler(fn), (wxObject*) NULL), + +#define EVT_PGQUERYRESULT_RANGE(id1, id2, fn) \ + DECLARE_EVENT_TABLE_ENTRY(PGQueryResultEvent, id1, id2, \ + pgQueryResultEventHandler(fn), (wxObject*) NULL), + +#endif // PGQUERYRESULTEVENT_H diff --git a/include/db/pgQueryThread.h b/include/db/pgQueryThread.h new file mode 100644 index 0000000..0946836 --- /dev/null +++ b/include/db/pgQueryThread.h @@ -0,0 +1,290 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgQueryThread.h - PostgreSQL threaded query class header +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGQUERYTHREAD_H +#define PGQUERYTHREAD_H + +#include "wx/wx.h" +#include "wx/event.h" +#include "db/pgConn.h" + +// Forward declaration +class pgSet; +class pgQueryThread; +class pgBatchQuery; + +// Support for the IN & INOUT parameters type +class pgParam : public wxObject +{ +public: + enum + { + PG_PARAM_IN = 1, + PG_PARAM_OUT = 2, + PG_PARAM_INOUT = 3, + PG_PARAM_VARIADIC = 4, + PG_PARAM_TABLE = 5 + }; + + // Any data + // + // This constructor won't call the functions - 'htonl' or 'htons' + // It will be the responsibility of the caller to take care + // to call 'htonl' or 'htons' depending on requirements. + // + // NOTE: + // This data will be owned by pgParam object and will be released. + pgParam(Oid _type, void *_val, int _len, short mode = PG_PARAM_IN); + + // wxString data + pgParam(Oid _type, wxString *_val, wxMBConv *_conv = NULL, + short mode = PG_PARAM_IN); + + ~pgParam(); + + // Returns 0 for text type and 1 for otherwise + int GetFormat(); + + Oid GetType() + { + return m_type; + } + short GetMode() + { + return m_mode; + } + +protected: + Oid m_type; + void *m_val; + int m_len; + short m_format; + // Modes are required by EnterpriseDB's callable statement + short m_mode; + + // Do not allow copy construction and shadow-copy + // to avoid ownership + // Force to use an pointer + pgParam(const pgParam &) + { + wxASSERT(0); + } + pgParam &operator= (const pgParam &) + { + wxASSERT(0); + return *this; + } + + friend class pgConn; + friend class pgQueryThread; +}; + +WX_DEFINE_ARRAY_PTR(pgParam *, pgParamsArray); + +class pgBatchQuery : public wxObject +{ +public: + pgBatchQuery(const wxString &_query, pgParamsArray *_params = NULL, + long _eventId = -1, void *_data = NULL, bool _useCallable = false, + int _resultToRetrieve = 0) + : m_query(_query), m_params(_params), m_eventID(_eventId), m_data(_data), + m_useCallable(_useCallable), m_resToRetrieve(_resultToRetrieve), + m_returnCode(-1), m_resultSet(NULL), m_rowsInserted(-1), m_insertedOid(-1) + { + // Do not honour the empty query string + wxASSERT(!_query.IsEmpty()); + } + ~pgBatchQuery(); + + bool Release(); + + pgSet *ResultSet() + { + return m_resultSet; + } + + int ReturnCode() + { + return m_returnCode; + } + + const wxString &GetMessage() + { + return m_message; + } + + long RowInserted() + { + return m_rowsInserted; + } + + const wxString &GetErrorMessage(); + +protected: + wxString m_query; // Query + pgParamsArray *m_params; // parameters + long m_eventID; // Event ID + void *m_data; // Data to be send with event + bool m_useCallable; // Use EnterpriseDB callable statement if possible + int m_resToRetrieve; // Which result to be retrieved + int m_returnCode; // Return code + pgSet *m_resultSet; // Result-Set + long m_rowsInserted; // No of rows inserted + Oid m_insertedOid; // Inserted Oid + wxString m_message; // Message generated during query execution + pgError m_err; // Error + +private: + // Do not allow copy construction and '=' operator (shadow copying) + // to avoid ownership of parameters and result-set + // + // This will force this class to be used as an pointer only. + pgBatchQuery(const pgBatchQuery &) + { + wxASSERT(0); + } + pgBatchQuery &operator= (const pgBatchQuery &) + { + wxASSERT(0); + return *this; + } + + friend class pgQueryThread; +}; +WX_DEFINE_ARRAY_PTR(pgBatchQuery *, pgBatchQueryArray); + +class pgQueryThread : public wxThread +{ +public: + // For running a single query (Used by few components) + pgQueryThread(pgConn *_conn, const wxString &qry, int resultToRetrieve = -1, + wxWindow *_caller = 0, long eventId = 0, void *_data = 0); + + // Support for multiple queries support + pgQueryThread(pgConn *_conn, wxEvtHandler *_caller = NULL, + PQnoticeProcessor _processor = NULL, void *_noticeHandler = NULL); + + ~pgQueryThread(); + + bool HasMultipleQueriesSupport() + { + return m_multiQueries; + } + + bool SupportCallableStatement() + { + return m_useCallable; + } + + void SetEventOnCancellation(bool eventOnCancelled); + + void AddQuery( + const wxString &_qry, pgParamsArray *_params = NULL, + long _eventId = 0, void *_data = NULL, bool _useCallable = false, + int _resultToRetrieve = -1); + + virtual void *Entry(); + bool DataValid(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? false : (m_queries[_idx]->m_resultSet != NULL)); + } + + pgConn *GetConn() + { + return m_conn; + } + + pgSet *DataSet(int _idx = -1) + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? NULL : m_queries[_idx]->m_resultSet); + } + + int ReturnCode(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? -1 : m_queries[_idx]->m_returnCode); + } + + long RowsInserted(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? -1L : m_queries[_idx]->m_rowsInserted); + } + + Oid InsertedOid(int _idx = -1) const + { + if (_idx == -1) + _idx = m_currIndex; + return (_idx >= 0 && _idx > m_currIndex ? -1L : m_queries[_idx]->m_insertedOid); + } + + inline void CancelExecution() + { + m_cancelled = true; + } + + inline size_t GetNumberQueries() + { + return m_queries.GetCount(); + } + + size_t QueriesExecuted() + { + return m_currIndex + 1; + } + + wxString GetMessagesAndClear(int _idx = -1); + void AppendMessage(const wxString &_str); + + int DeleteReleasedQueries(); + + pgError GetResultError(int idx = -1); + +private: + int Execute(); + int RaiseEvent(int _retval = 0); + + // Queries to be executed + pgBatchQueryArray m_queries; + // Current running query index + int m_currIndex; + // Connection object + pgConn *m_conn; + // Execution cancelled? + bool m_cancelled; + // Raise events even when cancelled the execution + bool m_eventOnCancellation; + // Does this thread support multiple queries + bool m_multiQueries; + // Use EDB callable statement (if available and require) + bool m_useCallable; + // Is executing a query + bool m_executing; + // Queries are being accessed at this time + wxMutex m_queriesLock; + // When one thread is accesing messages, other should not be able to access it + wxCriticalSection m_criticalSection; + // Event Handler + wxEvtHandler *m_caller; + // Database server notice-processor + PQnoticeProcessor m_processor; + // Notice Handler + void *m_noticeHandler; + +}; + +#endif diff --git a/include/db/pgSet.h b/include/db/pgSet.h new file mode 100644 index 0000000..acf6b26 --- /dev/null +++ b/include/db/pgSet.h @@ -0,0 +1,245 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSet.h - PostgreSQL ResultSet class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSET_H +#define PGSET_H + +// wxWindows headers +#include +#include + +// PostgreSQL headers +#include + +#include "utils/misc.h" + +typedef enum +{ + PGTYPCLASS_NUMERIC = 1, + PGTYPCLASS_BOOL, + PGTYPCLASS_STRING, + PGTYPCLASS_DATE, + PGTYPCLASS_OTHER +} pgTypClass; + +class pgConn; + +// Class declarations +class pgSet +{ +public: + pgSet(); + pgSet(PGresult *newRes, pgConn *newConn, wxMBConv &cnv, bool needColQt); + ~pgSet(); + long NumRows() const + { + return nRows; + } + long NumCols() const + { + return nCols; + } + + void MoveNext() + { + if (pos <= nRows) pos++; + } + void MovePrevious() + { + if (pos > 0) pos--; + } + void MoveFirst() + { + if (nRows) pos = 1; + else pos = 0; + } + void MoveLast() + { + pos = nRows; + } + void Locate(long l) + { + pos = l; + } + long CurrentPos() const + { + return pos; + } + bool Bof() const + { + return (!nRows || pos < 1); + } + bool Eof() const + { + return (!nRows || pos > nRows); + } + wxString ColName(const int col) const; + OID ColTypeOid(const int col) const; + long ColTypeMod(const int col) const; + wxString ColType(const int col) const; + wxString ColFullType(const int col) const; + pgTypClass ColTypClass(const int col) const; + + OID GetInsertedOid() const + { + return PQoidValue(res); + } + long GetInsertedCount() const; + int ColSize(const int col) const + { + return PQfsize(res, col); + } + bool IsNull(const int col) const + { + return (PQgetisnull(res, pos - 1, col) != 0); + } + int ColScale(const int col) const; + int ColNumber(const wxString &colName) const; + bool HasColumn(const wxString &colname) const; + + + wxString GetVal(const int col) const; + wxString GetVal(const wxString &col) const; + long GetLong(const int col) const; + long GetLong(const wxString &col) const; + bool GetBool(const int col) const; + bool GetBool(const wxString &col) const; + double GetDouble(const int col) const; + double GetDouble(const wxString &col) const; + wxDateTime GetDateTime(const int col) const; + wxDateTime GetDateTime(const wxString &col) const; + wxDateTime GetDate(const int col) const; + wxDateTime GetDate(const wxString &col) const; + wxULongLong GetLongLong(const int col) const; + wxULongLong GetLongLong(const wxString &col) const; + OID GetOid(const int col) const; + OID GetOid(const wxString &col) const; + + char *GetCharPtr(const int col) const; + char *GetCharPtr(const wxString &col) const; + + wxMBConv &GetConversion() const + { + return conv; + } + + wxString GetCommandStatus() const + { + if (res) + { + return wxString(PQcmdStatus(res), conv); + } + return wxEmptyString; + } + +protected: + pgConn *conn; + PGresult *res; + long pos, nRows, nCols; + wxString ExecuteScalar(const wxString &sql) const; + wxMBConv &conv; + bool needColQuoting; + mutable wxArrayString colTypes, colFullTypes; + mutable wxArrayInt colClasses; + +}; + + + +class pgSetIterator +{ +public: + pgSetIterator(pgSet *s); + pgSetIterator(pgConn *conn, const wxString &sql); + ~pgSetIterator(); + + bool RowsLeft(); + bool MovePrev(); + bool IsValid() + { + return set != 0; + } + pgSet *Set() + { + return set; + } + + wxString GetVal(const int col) const + { + return set->GetVal(col); + } + wxString GetVal(const wxString &col) const + { + return set->GetVal(col); + } + long GetLong(const int col) const + { + return set->GetLong(col); + } + long GetLong(const wxString &col) const + { + return set->GetLong(col); + } + bool GetBool(const int col) const + { + return set->GetBool(col); + } + bool GetBool(const wxString &col) const + { + return set->GetBool(col); + } + double GetDouble(const int col) const + { + return set->GetDouble(col); + } + double GetDouble(const wxString &col) const + { + return set->GetDouble(col); + } + wxDateTime GetDateTime(const int col) const + { + return set->GetDateTime(col); + } + wxDateTime GetDateTime(const wxString &col) const + { + return set->GetDateTime(col); + } + wxDateTime GetDate(const int col) const + { + return set->GetDate(col); + } + wxDateTime GetDate(const wxString &col) const + { + return set->GetDate(col); + } + wxULongLong GetLongLong(const int col) const + { + return set->GetLongLong(col); + } + wxULongLong GetLongLong(const wxString &col) const + { + return set->GetLongLong(col); + } + OID GetOid(const int col) const + { + return set->GetOid(col); + } + OID GetOid(const wxString &col) const + { + return set->GetOid(col); + } + +protected: + pgSet *set; + bool first; +}; + +#endif diff --git a/include/dd/dditems/figures/ddColumnFigure.h b/include/dd/dditems/figures/ddColumnFigure.h new file mode 100644 index 0000000..4cc05d3 --- /dev/null +++ b/include/dd/dditems/figures/ddColumnFigure.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigure.h - Minimal Composite Figure for a column of a table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNFIGURE_H +#define DDCOLUMNFIGURE_H +#include "hotdraw/figures/hdAttributeFigure.h" +#include "dd/dditems/figures/ddColumnKindIcon.h" +#include "dd/dditems/figures/ddColumnOptionIcon.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" + +class ddTableFigure; +class ddRelationshipItem; + +//Minimal overhead composite figure +class ddColumnFigure : public hdAttributeFigure +{ +public: + ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk = NULL); + ddColumnFigure(wxString &columnName, ddTableFigure *owner, ddColumnOptionType option, bool isGenFk, bool isPkColumn, wxString colDataType, int p = -1, int s = -1, int ukIdx = -1, ddRelationshipItem *sourceFk = NULL, ddRelationshipItem *usedAsFkDestFor = NULL ); + void Init(wxString &columnName, ddTableFigure *owner, ddRelationshipItem *sourceFk = NULL); + ~ddColumnFigure(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual void moveTo(int posIdx, int x, int y); + virtual void setOwnerTable(ddTableFigure *table); + virtual bool containsPoint(int posIdx, int x, int y); + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual hdIFigure *findFigure(int posIdx, int x, int y); + virtual hdIFigure *getFigureAt(int pos); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual ddTableFigure *getOwnerTable(); + void displayBoxUpdate(); + bool isNull(); + bool isNotNull(); + bool isNone(); + bool isPrimaryKey(); + void disablePrimaryKey(); + void enablePrimaryKey(); + bool isUniqueKey(); + bool isUniqueKey(int uniqueIndex); + int getUniqueConstraintIndex(); + void setUniqueConstraintIndex(int i); + bool isPlain(); + void setColumnKindToNone(); + void toggleColumnKind(ddColumnType type, hdDrawingView *view = NULL); + void setColumnOption(ddColumnOptionType type); + void setRightIconForColumn(); + ddColumnOptionType getColumnOption(); + ddDataType getDataType(); + void setDataType(ddDataType type); + wxString &getColumnName(bool datatype = false); + void setColumnName(wxString name); + bool isForeignKey(); + bool isGeneratedForeignKey(); + bool isUserCreatedForeignKey(); + bool isForeignKeyFromPk(); + wxString generateSQL(bool forAlterColumn = false); + bool isFkNameGenerated(); + void activateGenFkName(); + void deactivateGenFkName(); + ddRelationshipItem *getFkSource(); + void setFkSource(ddRelationshipItem *newColumn); + int getPrecision(); + void setPrecision(int n); + int getScale(); + void setScale(int n); + void setAsUserCreatedFk(ddRelationshipItem *relatedFkItem); + ddRelationshipItem *getRelatedFkItem(); + bool validateColumn(wxString &errors); + void setTextColour(wxColour colour); + ddColumnKindIcon *getKindImage() + { + return kindImage; + }; + ddColumnOptionIcon *getOptionImage() + { + return optionImage; + }; + ddTextTableItemFigure *getColumnText() + { + return columnText; + }; + + /* Disable right now, it can be useful at the future when db designer will be improved again + int getPgAttNumCol() { return pgAttNumColNumber;}; + void setPgAttNumCol(int attnum) { pgAttNumColNumber = attnum; }; + */ + wxString getRawDataType(); + +protected: + ddColumnKindIcon *kindImage; + ddColumnOptionIcon *optionImage; + ddTextTableItemFigure *columnText; + ddTableFigure *ownerTable; + ddRelationshipItem *usedAsFkDestFor; + bool generateFkName; + int pgAttNumColNumber; + +private: + ddRelationshipItem *fkSource; + + +}; +#endif diff --git a/include/dd/dditems/figures/ddColumnKindIcon.h b/include/dd/dditems/figures/ddColumnKindIcon.h new file mode 100644 index 0000000..a7db41d --- /dev/null +++ b/include/dd/dditems/figures/ddColumnKindIcon.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnKindIcon.h - Figure container for kind of Column Images +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNKINDICON_H +#define DDCOLUMNKINDICON_H + +#include "hotdraw/figures/hdAbstractMenuFigure.h" + +class ddColumnFigure; + +enum ddColumnType +{ + pk = 321, + uk, + none, + noaction //no action kind means column type don't have right now a useful value +}; + +enum +{ + MNU_DDCTPKEY = 321, + MNU_DDCTUKEY +}; + +class ddColumnKindIcon : public hdAbstractMenuFigure +{ +public: + ddColumnKindIcon(ddColumnFigure *owner); + ~ddColumnKindIcon(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view = NULL); + virtual void createMenu(wxMenu &mnu); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void toggleColumnKind(ddColumnType type, hdDrawingView *view = NULL, bool interaction = true); + virtual int getWidth(); + virtual int getHeight(); + bool isNone(); + bool isPrimaryKey(); + bool isForeignKey(); + void disableUniqueKey(); + void disablePrimaryKey(); + void enablePrimaryKey(); + ddColumnFigure *getOwnerColumn(); + bool isUniqueKey(); + bool isUniqueKey(int uniqueIndex); + int getUniqueConstraintIndex(); + void setUniqueConstraintIndex(int i); + void setRightIconForColumn(); + void setPrimaryKey(bool value); + void setUkIndex(int ukIdx); +protected: + +private: + ddColumnFigure *ownerColumn; + wxBitmap *iconToDraw; + wxBitmap icon; + int ukIndex; + bool isPk; + + //multiple Uk management at table + void syncUkIndexes(); + bool uniqueConstraintManager(bool ukCol, hdDrawingView *view = NULL, bool interaction = true); +}; +#endif diff --git a/include/dd/dditems/figures/ddColumnOptionIcon.h b/include/dd/dditems/figures/ddColumnOptionIcon.h new file mode 100644 index 0000000..f4046e9 --- /dev/null +++ b/include/dd/dditems/figures/ddColumnOptionIcon.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnOptionIcon.h - +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNOPTIONICON_H +#define DDCOLUMNOPTIONICON_H + +#include "hotdraw/figures/hdAbstractMenuFigure.h" + +class ddColumnFigure; + +enum ddColumnOptionType +{ + null = 321, + notnull +}; + +enum +{ + MNU_COLNULL = 321, + MNU_COLNOTNULL +}; + +class ddColumnOptionIcon : public hdAbstractMenuFigure +{ +public: + ddColumnOptionIcon(ddColumnFigure *owner); + ~ddColumnOptionIcon(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view = NULL); + virtual void createMenu(wxMenu &mnu); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void changeIcon(ddColumnOptionType type); + virtual int getWidth(); + virtual int getHeight(); + ddColumnOptionType getOption(); + ddColumnFigure *getOwnerColumn(); + +protected: + +private: + ddColumnOptionType colOption; + ddColumnFigure *ownerColumn; + wxBitmap *iconToDraw; + wxBitmap icon; +}; +#endif diff --git a/include/dd/dditems/figures/ddRelationshipFigure.h b/include/dd/dditems/figures/ddRelationshipFigure.h new file mode 100644 index 0000000..b9c1202 --- /dev/null +++ b/include/dd/dditems/figures/ddRelationshipFigure.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipFigure.h - Figure to draw foreign keys between tables. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDRELATIONSHIPFIGURE_H +#define DDRELATIONSHIPFIGURE_H +#include "hotdraw/figures/hdLineConnection.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" + +enum +{ + MNU_MANDATORYRELATIONSHIP = 321, + MNU_IDENTIFYINGRELATIONSHIP, + MNU_1MRELATIONSHIP, + MNU_DELETERELATIONSHIP, + MNU_FKCONSTRAINTNAME, + MNU_FKMATCHTYPESIMPLE, + MNU_FKMATCHTYPEFULL, + MNU_FKONDELETENOACTION, + MNU_FKONDELETERESTRICT, + MNU_FKONDELETECASCADE, + MNU_FKONDELETESETNULL, + MNU_FKONDELETESETDEFAULT, + MNU_FKONUPDATENOACTION, + MNU_FKONUPDATERESTRICT, + MNU_FKONUPDATECASCADE, + MNU_FKONUPDATESETNULL, + MNU_FKONUPDATESETDEFAULT, + MNU_FKEYFROMPKEY, + MNU_FKEYCUSTOMMAPPING, + MNU_FKEYFROMUKEYBASE //This constant should be always the last one to allow hack of multiple uk selection in submenu +}; + +enum actionKind +{ + FK_ACTION_NO = 600, + FK_RESTRICT, + FK_CASCADE, + FK_SETNULL, + FK_SETDEFAULT +}; +class ddRelationshipItem; + +WX_DECLARE_STRING_HASH_MAP( ddRelationshipItem *, columnsHashMap ); + + +class ddRelationshipFigure : public hdLineConnection +{ +public: + ddRelationshipFigure(); + ddRelationshipFigure(int posIdx, hdIFigure *figure1, hdIFigure *figure2); + ~ddRelationshipFigure(); + virtual void createMenu(wxMenu &mnu); + + void prepareFkForDelete(ddColumnFigure *column); + void updateForeignKey(); + void removeForeignKeys(); + void addExistingColumnFk(ddColumnFigure *startTablesourceCol, wxString destColumn); + bool getIdentifying(); + bool getOneToMany(); + bool getMandatory(); + void setOptionAtForeignKeys(ddColumnOptionType type); + void updatePkAtFkCols(); + bool isForeignKeyFromPk(); + virtual void connectEnd(hdIConnector *end, hdDrawingView *view = NULL); + virtual void connectStart(hdIConnector *start, hdDrawingView *view = NULL); + void disconnectStart(hdDrawingView *view = NULL); + void disconnectEnd(hdDrawingView *view = NULL); + void setFkFrom(bool primaryKey, int useUkIndex = -1, bool issueUpdateFk = false); + wxString generateSQL(wxString schemaName); + wxString getConstraintName(); + ddTableFigure *getStartTable(); + ddTableFigure *getEndTable(); + void changeFkOSTextColor(wxColour originalColour, wxColour fkColour, bool reset = false); + int getUkIndex(); + actionKind getOnUpdateAction(); + actionKind getOnDeleteAction(); + bool getMatchSimple(); + columnsHashMap &getItemsHashMap() + { + return chm; + }; + void initRelationValues(ddTableFigure *source, ddTableFigure *destination, int ukIdx, wxString constraint, actionKind onUpdate, actionKind onDelete, bool simpleMatch, bool identifying, bool oneToMany, bool mandatory, bool fromPk); + +protected: + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + +private: + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + bool fkFromPk; + bool fkMandatory; + bool fkOneToMany; + bool fkIdentifying; + bool matchSimple; + bool paintingFkColumns; + actionKind onUpdateAction, onDeleteAction; + wxString constraintName; + + int ukIndex; + columnsHashMap chm; + ddTableFigure *disconnectedEndTable; +}; + +#endif diff --git a/include/dd/dditems/figures/ddRelationshipItem.h b/include/dd/dditems/figures/ddRelationshipItem.h new file mode 100644 index 0000000..d9fd4ea --- /dev/null +++ b/include/dd/dditems/figures/ddRelationshipItem.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipFigure.h - Item to keep track of foreign keys between tables in a relationship. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDRELATIONSHIPITEM_H +#define DDRELATIONSHIPITEM_H +#include "hotdraw/figures/hdLineConnection.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" + +class ddRelationshipItem : public hdObject +{ +public: + ddRelationshipItem(); + ddRelationshipItem(ddRelationshipFigure *owner, ddColumnFigure *originalColumn, ddTableFigure *destination, ddColumnOptionType type, ddColumnType colType, ddColumnFigure *existingColumn = NULL); + ~ddRelationshipItem(); + void initRelationshipItemValues(ddRelationshipFigure *owner, ddTableFigure *destination, bool fromExistingColumn, ddColumnFigure *fkCol, ddColumnFigure *sourceCol, wxString initialColName); + wxString originalStartColName; + ddColumnFigure *original; + ddColumnFigure *fkColumn; + + + wxString autoGenerateNameForFk(); + void syncAutoFkName(); + + ddTableFigure *getDestinationTable() + { + return destinationTable; + }; + bool isAutomaticallyGenerated(); + bool relationIsIdentifying(); + bool relationIsMandatory(); + bool isForeignKeyFromPk(); + wxString sourceTableName(); + wxString destTableName(); + + +private: + bool fkIsAutoGenerated; + ddTableFigure *destinationTable; + ddRelationshipFigure *ownerRel; + wxString generatedName; //avoid linux bug +}; + +#endif diff --git a/include/dd/dditems/figures/ddRelationshipTerminal.h b/include/dd/dditems/figures/ddRelationshipTerminal.h new file mode 100644 index 0000000..5f704af --- /dev/null +++ b/include/dd/dditems/figures/ddRelationshipTerminal.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRelationshipTerminal.h - Draw inverse arrows at fk terminal based on kind of relationship. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDRELATIONSHIPTERMINAL_H +#define DDRELATIONSHIPTERMINAL_H +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/utilities/hdPoint.h" +#include "dd/dditems/figures/ddRelationshipFigure.h" + + + +class ddRelationshipTerminal : public hdLineTerminal +{ +public: + ddRelationshipTerminal(ddRelationshipFigure *owner, bool endFigureTerminal); + ~ddRelationshipTerminal(); + virtual hdPoint &draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view); +protected: + +private: + double lastFactor; + ddRelationshipFigure *ownerFigure; + bool endTerminal; + hdPoint value; +}; +#endif diff --git a/include/dd/dditems/figures/ddTableFigure.h b/include/dd/dditems/figures/ddTableFigure.h new file mode 100644 index 0000000..129d82b --- /dev/null +++ b/include/dd/dditems/figures/ddTableFigure.h @@ -0,0 +1,191 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableFigure.h - Draw table figure of a model +// +//////////////////////////////////////////////////////////////////////////// + +#ifndef DDTABLEFIGURE_H +#define DDTABLEFIGURE_H +#include "hotdraw/figures/hdCompositeFigure.h" +#include "hotdraw/figures/hdRectangleFigure.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" +#include "dd/dditems/figures/ddColumnFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +class ddScrollBarHandle; +class ddRelationshipFigure; +class hdDrawing; + +class ddTableFigure : public hdCompositeFigure +{ +public: + ddTableFigure(wxString tableName, int x, int y); + ddTableFigure(wxString tableName, int posIdx, int x, int y); + void InitTableValues(wxArrayString UniqueKeysName, wxString primaryKeyName, int bdc, int bdi, int maxcolsi, int minidxsi, int maxidxsi, int colsrs, int colsw, int idxsrs, int idxsw); + void Init(wxString tableName, int x, int y); + hdMultiPosRect &getBasicDisplayBox(); + ~ddTableFigure(); + + //Diagrams related functions + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + + //add remove items + ddColumnFigure *getColByName(wxString name); + void addColumn(int posIdx, ddColumnFigure *column); + void addColumnFromStorage(ddColumnFigure *column); + void syncInternalsPosAt(int posIdx, int x, int y); + void syncInternalsPosAt(wxArrayInt &x, wxArrayInt &y); + void removeColumn(int posIdx, ddColumnFigure *column); + + //movement + void manuallyNotifyChange(int posIdx) + { + changed(posIdx); + }; + virtual void basicMoveBy(int posIdx, int x, int y); + + //show messages to set fk destination + void setSelectFkDestMode(bool value); + + //delete hack tables + void processDeleteAlert(hdDrawing *drawing); + + //columns scrolls + void updateTableSize(bool notifyChange = true); + void recalculateColsPos(int posIdx); + void setColsRowsWindow(int num); + hdMultiPosRect &getColsSpace(); + hdMultiPosRect &getFullSpace(); + hdMultiPosRect &getTitleRect(); + int getTotalColumns(); + int getColumnsWindow(); + int getTopColWindowIndex(); + void setColumnsWindow(int posIdx, int value, bool maximize = false); + void columnsWindowUp(int posIdx); + void columnsWindowDown(int posIdx); + int getFiguresMaxWidth(); + int getColDefaultHeight(wxFont font); + + //metadata + wxString getTableName(); + wxString getShortTableName(); + wxString generateSQLCreate(wxString schemaName); + wxString generateSQLAlterPks(wxString schemaName); + wxString generateSQLAlterFks(wxString schemaName); + wxString generateSQLAlterUks(wxString schemaName); + wxString generateAltersTable(pgConn *connection, wxString schemaName, ddDatabaseDesign *design); + wxArrayString getAllColumnsNames(); + wxArrayString getAllFkSourceColsNames(bool pk, int ukIndex = -1); + ddColumnFigure *getColumnByName(wxString name); + bool validateTable(wxString &errors); + + //uk pk constraints + void setPkConstraintName(wxString name); + wxString getPkConstraintName(); + wxArrayString &getUkConstraintsNames(); + bool disablePrimaryKey(); + bool enablePrimaryKey(); + + //fk related + void updateFkObservers(); + void updateSizeOfObservers(); + void prepareForDeleteFkColumn(ddColumnFigure *column); + + //ScrollBar persistence related + int getBeginDrawCols() + { + return beginDrawCols; + }; + int getBeginDrawIdxs() + { + return beginDrawIdxs; + }; + int getMaxColIndex() + { + return maxColIndex; + }; + int getMinIdxIndex() + { + return minIdxIndex; + }; + int getMaxIdxIndex() + { + return maxIdxIndex; + }; + int getColsRowsSize() + { + return colsRowsSize; + }; + int getColsWindow() + { + return colsWindow; + }; + int getIdxsRowsSize() + { + return idxsRowsSize; + }; + int getIdxsWindow() + { + return idxsWindow; + }; + + //Temporary alter table instead of create Helper + bool getBelongsToSchema() + { + return belongsToSchema; + }; + void setBelongsToSchema(bool value) + { + belongsToSchema = value; + }; + +protected: + //drawing + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + +private: + //Temporary alter table instead of create Helper + bool belongsToSchema; + + //Main Rectangle Sizes + hdMultiPosRect fullSizeRect, titleRect, titleColsRect, colsRect, titleIndxsRect, indxsRect; + hdMultiPosRect unScrolledColsRect, unScrolledFullSizeRect, unScrolledTitleRect; + + //Rectangle item counters + int colsRowsSize, colsWindow, idxsRowsSize, idxsWindow; + + //vector indexes + int maxColIndex, minIdxIndex, maxIdxIndex; + + //position + int beginDrawCols, beginDrawIdxs; + + //Default Figures + hdRectangleFigure *rectangleFigure; + ddTextTableItemFigure *tableTitle; + + //helper variables + bool selectingFkDestination; + int internalPadding, externalPadding; + bool calcScrolled; + + //specials handles + ddScrollBarHandle *scrollbar; + + //methods + int getHeightFontMetric(wxString text, wxFont font); + void calcInternalSubAreas(int posIdx); + + //pk uk(s) + wxString pkName; + wxArrayString ukNames; +}; +#endif diff --git a/include/dd/dditems/figures/ddTextTableItemFigure.h b/include/dd/dditems/figures/ddTextTableItemFigure.h new file mode 100644 index 0000000..df79c6a --- /dev/null +++ b/include/dd/dditems/figures/ddTextTableItemFigure.h @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTextTableItemFigure.h - +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDTEXTTABLEITEMFIGURE_H +#define DDTEXTTABLEITEMFIGURE_H + + +#include + +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "dd/dditems/utilities/ddDataType.h" + +enum +{ + MNU_DDADDCOLUMN = 321, + MNU_DELCOLUMN, + MNU_RENAMECOLUMN, + MNU_AUTONAMCOLUMN, + MNU_NOTNULL, + MNU_PKEY, + MNU_UKEY, + MNU_TYPESERIAL, + MNU_TYPEBOOLEAN, + MNU_TYPEINTEGER, + MNU_TYPEMONEY, + MNU_TYPEVARCHAR, + MNU_TYPEOTHER, + MNU_TYPEPKEY_CONSTRAINTNAME, + MNU_TYPEUKEY_CONSTRAINTNAME, + MNU_DELTABLE +}; + +class ddColumnFigure; +class ddTableFigure; + +class ddTextTableItemFigure : public hdSimpleTextFigure +{ +public: + ddTextTableItemFigure(wxString &columnName, ddDataType dataType, ddColumnFigure *owner); + ~ddTextTableItemFigure(); + virtual wxString &getText(bool extended = false); + wxString getType(bool raw = false); + virtual void setAlias(wxString alias); + virtual wxString getAlias(); + virtual void setOneTimeNoAlias(); + virtual void createMenu(wxMenu &mnu); + virtual const wxArrayString dataTypes(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + virtual void setText(wxString textString); + virtual ddColumnFigure *getOwnerColumn(); + virtual void setOwnerColumn(ddColumnFigure *column); + virtual void setShowDataType(bool value); + virtual bool getShowDataType() + { + return showDataType; + }; + hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void displayBoxUpdate(); + void recalculateDisplayBox(); + int getTextWidth(); + int getTextHeight(); + ddDataType getDataType(); + void setDataType(ddDataType type); + void setOwnerTable(ddTableFigure *table); //only used by columns working as table title figure for setAlias method + int getPrecision(); + int getScale(); + void setPrecision(int value); + void setScale(int value); +protected: + ddColumnFigure *ownerColumn; + ddTableFigure *ownerTable; + wxString colAlias; +private: + ddDataType columnType; + wxString out; + bool showDataType; + bool showAlias; + bool oneTimeNoAlias; + int precision; + int scale; +}; +#endif diff --git a/include/dd/dditems/figures/module.mk b/include/dd/dditems/figures/module.mk new file mode 100644 index 0000000..1e5ae29 --- /dev/null +++ b/include/dd/dditems/figures/module.mk @@ -0,0 +1,25 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/figures/ddColumnFigure.h \ + include/dd/dditems/figures/ddColumnKindIcon.h \ + include/dd/dditems/figures/ddColumnOptionIcon.h \ + include/dd/dditems/figures/ddRelationshipFigure.h \ + include/dd/dditems/figures/ddRelationshipItem.h \ + include/dd/dditems/figures/ddRelationshipTerminal.h \ + include/dd/dditems/figures/ddTableFigure.h \ + include/dd/dditems/figures/ddTextTableItemFigure.h + +EXTRA_DIST += \ + include/dd/dditems/figures/module.mk + +include include/dd/dditems/figures/xml/module.mk diff --git a/include/dd/dditems/figures/xml/ddXmlStorage.h b/include/dd/dditems/figures/xml/ddXmlStorage.h new file mode 100644 index 0000000..b2794f8 --- /dev/null +++ b/include/dd/dditems/figures/xml/ddXmlStorage.h @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDXMLSTORAGE_H +#define DDXMLSTORAGE_H + +#include "hotdraw/figures/xml/hdStorage.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include + +class ddXmlStorage : public hdStorage +{ +public: + ddXmlStorage(); + + //Generic part + static bool Read(xmlTextReaderPtr reader); + static bool Write(xmlTextWriterPtr writer, hdIFigure *figure); + static void setModel(ddDatabaseDesign *sourceDesign); + static void setNotebook(ctlAuiNotebook *notebook); + static wxString getModelDTD(); + + //Write xml info Database Designer Related + static void WriteLocal( xmlTextWriterPtr writer, ddColumnOptionIcon *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddColumnKindIcon *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddTextTableItemFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddColumnFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddTableFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddRelationshipFigure *figure); + static void WriteLocal( xmlTextWriterPtr writer, ddRelationshipItem *item); + static void WriteLocal( xmlTextWriterPtr writer, hdDrawing *diagram); + static void StarDiagrams( xmlTextWriterPtr writer); + static void EndDiagrams( xmlTextWriterPtr writer); + static void StartModel( xmlTextWriterPtr writer, ddDatabaseDesign *design); + static void EndModel( xmlTextWriterPtr writer); + static bool processResult(int value); + + //Generic node processing functions + static wxString getNodeName(xmlTextReaderPtr reader); + static int getNodeType(xmlTextReaderPtr reader); + static wxString getNodeValue(xmlTextReaderPtr reader); + + //Read xml info Database Designer Related + static void selectReader(xmlTextReaderPtr reader); + static void checkVersion(xmlTextReaderPtr reader); + static ddTableFigure *getTable(xmlTextReaderPtr reader); + static ddColumnFigure *getColumn(xmlTextReaderPtr reader, ddTableFigure *colOwner); + static ddRelationshipFigure *getRelationship(xmlTextReaderPtr reader); + static ddRelationshipItem *getRelationshipItem(xmlTextReaderPtr reader, ddRelationshipFigure *itemOwner, ddTableFigure *source, ddTableFigure *destination); + static void initDiagrams(xmlTextReaderPtr reader); + static void initialModelParse(xmlTextReaderPtr reader); + +private: + + static ddDatabaseDesign *design; + static ctlAuiNotebook *tabs; +}; +#endif diff --git a/include/dd/dditems/figures/xml/module.mk b/include/dd/dditems/figures/xml/module.mk new file mode 100644 index 0000000..6c4f3b6 --- /dev/null +++ b/include/dd/dditems/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/figures/xml Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/figures/xml/ddXmlStorage.h + +EXTRA_DIST += \ + include/dd/dditems/figures/xml/module.mk diff --git a/include/dd/dditems/handles/ddAddColButtonHandle.h b/include/dd/dditems/handles/ddAddColButtonHandle.h new file mode 100644 index 0000000..e085829 --- /dev/null +++ b/include/dd/dditems/handles/ddAddColButtonHandle.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColButtonHandle.h - A handle for a table figure that allow to graphically add columns +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDCOLBUTTONHANDLE_H +#define DDADDCOLBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddAddColButtonHandle : public hdButtonHandle +{ +public: + ddAddColButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~ddAddColButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; +}; +#endif diff --git a/include/dd/dditems/handles/ddAddFkButtonHandle.h b/include/dd/dditems/handles/ddAddFkButtonHandle.h new file mode 100644 index 0000000..c51f666 --- /dev/null +++ b/include/dd/dditems/handles/ddAddFkButtonHandle.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkButtonHandle.h - A handle for a table figure that allow to graphically add relationships (fk) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDFKBUTTONHANDLE_H +#define DDADDFKBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddAddFkButtonHandle : public hdButtonHandle +{ +public: + ddAddFkButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~ddAddFkButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; +}; +#endif diff --git a/include/dd/dditems/handles/ddMinMaxTableButtonHandle.h b/include/dd/dditems/handles/ddMinMaxTableButtonHandle.h new file mode 100644 index 0000000..74a403f --- /dev/null +++ b/include/dd/dditems/handles/ddMinMaxTableButtonHandle.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableButtonHandle.h - A handle for a table figure that allow to graphically minimize or maximize table window size +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDMINMAXTABLEBUTTONHANDLE_H +#define DDMINMAXTABLEBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddMinMaxTableButtonHandle : public hdButtonHandle +{ +public: + ddMinMaxTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxBitmap &buttonSecondImage, wxSize &size); + ~ddMinMaxTableButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; + wxBitmap buttonMaximizeImage, tmpImage; + bool showFirst; +}; +#endif diff --git a/include/dd/dditems/handles/ddRemoveTableButtonHandle.h b/include/dd/dditems/handles/ddRemoveTableButtonHandle.h new file mode 100644 index 0000000..7041d84 --- /dev/null +++ b/include/dd/dditems/handles/ddRemoveTableButtonHandle.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveTableButtonHandle.h - A handle for a table figure that allow to delete it +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDREMOVETABLEBUTTONHANDLE_H +#define DDREMOVETABLEBUTTONHANDLE_H + +#include "hotdraw/handles/hdButtonHandle.h" + +class ddRemoveTableButtonHandle : public hdButtonHandle +{ +public: + ddRemoveTableButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~ddRemoveTableButtonHandle(); + + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + wxImage handleCursorImage; + wxCursor handleCursor; +}; +#endif diff --git a/include/dd/dditems/handles/ddScrollBarHandle.h b/include/dd/dditems/handles/ddScrollBarHandle.h new file mode 100644 index 0000000..4f084f8 --- /dev/null +++ b/include/dd/dditems/handles/ddScrollBarHandle.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarHandle.h - A handle for a table figure that allow to scroll it when table is not in full size +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSCROLLBARHANDLE_H +#define DDSCROLLBARHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/handles/hdLocatorHandle.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdPoint.h" +#include "dd/dditems/figures/ddTableFigure.h" + + +class ddScrollBarHandle : public hdLocatorHandle +{ +public: + ddScrollBarHandle(ddTableFigure *owner, hdILocator *scrollBarLocator , wxSize &size); + ~ddScrollBarHandle(); + + + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual hdPoint &locate(int posIdx); + virtual wxCursor createCursor(); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); + virtual hdRect &getDisplayBox(int posIdx); +protected: +private: + hdPoint pointLocate; + hdILocator *scrollLocator; + ddTableFigure *table; + wxBitmap upBitmap, downBitmap; + wxSize barSize; + int anchorY; + +}; +#endif diff --git a/include/dd/dditems/handles/ddSouthTableSizeHandle.h b/include/dd/dditems/handles/ddSouthTableSizeHandle.h new file mode 100644 index 0000000..e64d069 --- /dev/null +++ b/include/dd/dditems/handles/ddSouthTableSizeHandle.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddSouthTableSizeHandle.h - Allow to change table size by using drag and drop from south side of table rectangle +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSOUTHTABLESIZEHANDLE_H +#define DDSOUTHTABLESIZEHANDLE_H + +#include "hotdraw/handles/hdLocatorHandle.h" + +class ddTableFigure; + +class ddSouthTableSizeHandle : public hdLocatorHandle +{ +public: + ddSouthTableSizeHandle(ddTableFigure *owner, hdILocator *locator); + ~ddSouthTableSizeHandle(); + virtual wxCursor createCursor(); + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual hdRect &getDisplayBox(int posIdx); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + int anchorY; + +}; +#endif diff --git a/include/dd/dditems/handles/module.mk b/include/dd/dditems/handles/module.mk new file mode 100644 index 0000000..39fdd76 --- /dev/null +++ b/include/dd/dditems/handles/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/handles/ddAddColButtonHandle.h \ + include/dd/dditems/handles/ddAddFkButtonHandle.h \ + include/dd/dditems/handles/ddMinMaxTableButtonHandle.h \ + include/dd/dditems/handles/ddRemoveTableButtonHandle.h \ + include/dd/dditems/handles/ddScrollBarHandle.h \ + include/dd/dditems/handles/ddSouthTableSizeHandle.h + +EXTRA_DIST += \ + include/dd/dditems/handles/module.mk diff --git a/include/dd/dditems/locators/ddAddColLocator.h b/include/dd/dditems/locators/ddAddColLocator.h new file mode 100644 index 0000000..aaac8f9 --- /dev/null +++ b/include/dd/dditems/locators/ddAddColLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddColLocator.h - Locate table add column button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDCOLLOCATOR_H +#define DDADDCOLLOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddAddColLocator : public hdILocator +{ +public: + ddAddColLocator(); + ~ddAddColLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddAddFkLocator.h b/include/dd/dditems/locators/ddAddFkLocator.h new file mode 100644 index 0000000..5c8afe7 --- /dev/null +++ b/include/dd/dditems/locators/ddAddFkLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddAddFkLocator.h - Locate table add fk relationship button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDADDFKLOCATOR_H +#define DDADDFKLOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddAddFkLocator : public hdILocator +{ +public: + ddAddFkLocator(); + ~ddAddFkLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddMinMaxTableLocator.h b/include/dd/dditems/locators/ddMinMaxTableLocator.h new file mode 100644 index 0000000..04a43b9 --- /dev/null +++ b/include/dd/dditems/locators/ddMinMaxTableLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddMinMaxTableLocator.h - Locate table minimize/maximize button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDMINMAXTABLELOCATOR_H +#define DDMINMAXTABLELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddMinMaxTableLocator : public hdILocator +{ +public: + ddMinMaxTableLocator(); + ~ddMinMaxTableLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddRemoveTableLocator.h b/include/dd/dditems/locators/ddRemoveTableLocator.h new file mode 100644 index 0000000..f54fa21 --- /dev/null +++ b/include/dd/dditems/locators/ddRemoveTableLocator.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddRemoveColLocator.cpp - Locate table delete button inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDREMOVETABLELOCATOR_H +#define DDREMOVETABLELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddRemoveTableLocator : public hdILocator +{ +public: + ddRemoveTableLocator(); + ~ddRemoveTableLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: +}; +#endif diff --git a/include/dd/dditems/locators/ddScrollBarTableLocator.h b/include/dd/dditems/locators/ddScrollBarTableLocator.h new file mode 100644 index 0000000..f6283f5 --- /dev/null +++ b/include/dd/dditems/locators/ddScrollBarTableLocator.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddScrollBarTableLocator.h - Locate table scrollbar inside a table. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSCROLLBARTABLELOCATOR_H +#define DDSCROLLBARTABLELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddScrollBarTableLocator : public hdILocator +{ +public: + ddScrollBarTableLocator(); + ~ddScrollBarTableLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: + +}; +#endif diff --git a/include/dd/dditems/locators/ddTableBottomLocator.h b/include/dd/dditems/locators/ddTableBottomLocator.h new file mode 100644 index 0000000..d93e54a --- /dev/null +++ b/include/dd/dditems/locators/ddTableBottomLocator.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableBottomLocator.h - Locate bottom (south) of table for use of south table size handle. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDTABLEBOTTOMLOCATOR_H +#define DDTABLEBOTTOMLOCATOR_H + +#include "hotdraw/locators/hdILocator.h" +#include "hotdraw/figures/hdIFigure.h" + +class ddTableBottomLocator : public hdILocator +{ +public: + ddTableBottomLocator(); + ~ddTableBottomLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + +protected: + +private: + +}; +#endif diff --git a/include/dd/dditems/locators/module.mk b/include/dd/dditems/locators/module.mk new file mode 100644 index 0000000..ed83939 --- /dev/null +++ b/include/dd/dditems/locators/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/locators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/locators/ddAddColLocator.h \ + include/dd/dditems/locators/ddAddFkLocator.h \ + include/dd/dditems/locators/ddMinMaxTableLocator.h \ + include/dd/dditems/locators/ddRemoveTableLocator.h \ + include/dd/dditems/locators/ddScrollBarTableLocator.h \ + include/dd/dditems/locators/ddTableBottomLocator.h + +EXTRA_DIST += \ + include/dd/dditems/locators/module.mk diff --git a/include/dd/dditems/module.mk b/include/dd/dditems/module.mk new file mode 100644 index 0000000..a68461a --- /dev/null +++ b/include/dd/dditems/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/ Makefile fragment +# +####################################################################### + +include include/dd/dditems/figures/module.mk +include include/dd/dditems/handles/module.mk +include include/dd/dditems/locators/module.mk +include include/dd/dditems/tools/module.mk +include include/dd/dditems/utilities/module.mk + +EXTRA_DIST += \ + include/dd/dditems/module.mk diff --git a/include/dd/dditems/tools/ddColumnFigureTool.h b/include/dd/dditems/tools/ddColumnFigureTool.h new file mode 100644 index 0000000..dbb9019 --- /dev/null +++ b/include/dd/dditems/tools/ddColumnFigureTool.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnFigureTool.h - Improvement to hdFigureTool to work with composite table figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNFIGURETOOL_H +#define DDCOLUMNFIGURETOOL_H + +#include "hotdraw/tools/hdFigureTool.h" + + +class ddColumnFigureTool : public hdFigureTool +{ +public: + ddColumnFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~ddColumnFigureTool(); + virtual void setDefaultTool(hdITool *dt); + virtual hdITool *getDefaultTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void setDelegateTool(hdDrawingView *view, hdITool *tool); + virtual hdITool *getDelegateTool(); +protected: + hdITool *delegateTool; +private: +}; +#endif diff --git a/include/dd/dditems/tools/ddColumnTextTool.h b/include/dd/dditems/tools/ddColumnTextTool.h new file mode 100644 index 0000000..f4c095d --- /dev/null +++ b/include/dd/dditems/tools/ddColumnTextTool.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddColumnTextTool.h - Modification of simple text tool for editing composite figure columns +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDCOLUMNTEXTTOOL_H +#define DDCOLUMNTEXTTOOL_H + +#include "hotdraw/tools/hdSimpleTextTool.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" + + +class ddColumnTextTool : public hdSimpleTextTool +{ + +public: + ddColumnTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit = true, wxString dialogCaption = wxEmptyString, wxString dialogMessage = wxEmptyString); + ~ddColumnTextTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual bool callDialog(hdDrawingView *view); + // some events functions are needed but because a bug it were move to main View class as a hack. +protected: +private: + ddTextTableItemFigure *colTextFigure; + //Because a bug in the way wxwidgets connect events I can't declare it here, wxTextCtrl, instead I do it on the view. +}; +#endif diff --git a/include/dd/dditems/tools/module.mk b/include/dd/dditems/tools/module.mk new file mode 100644 index 0000000..707fbb4 --- /dev/null +++ b/include/dd/dditems/tools/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/tools/ddColumnFigureTool.h \ + include/dd/dditems/tools/ddColumnTextTool.h + +EXTRA_DIST += \ + include/dd/dditems/tools/module.mk diff --git a/include/dd/dditems/utilities/ddDataType.h b/include/dd/dditems/utilities/ddDataType.h new file mode 100644 index 0000000..450e02a --- /dev/null +++ b/include/dd/dditems/utilities/ddDataType.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDataType.h - data types related info for table use +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDATATYPES_H +#define DDDATATYPES_H + +enum ddMenuColumn +{ + add_column = 321, + del_column, + ren_column, + change_datatype +}; + +enum ddHiddenTypes +{ + DDTABLEFIGURE = 100, + DDRELATIONSHIPFIGURE = 200, + DDCOLUMNFIGURE = 300, + DDCOLUMNOPTIONICON = 400, + DDCOLUMNKINDICON = 500, + DDTEXTTABLEITEMFIGURE = 600 +}; + +enum ddDataType +{ + dt_null = 0, + dt_serial, + dt_boolean, + dt_integer, + dt_money, + dt_varchar, //(n) + dt_bigint, + dt_bit, //(n) + dt_bytea, + dt_char, //(n) + dt_cidr, + dt_circle, + dt_date, + dt_doubleprec, + dt_inet, + dt_interval, //(n) + dt_line, + dt_Lseg, + dt_macaddr, + dt_numeric, //(p,s) + dt_path, + dt_point, + dt_polygon, + dt_real, + dt_smallint, + dt_text, + dt_time, + dt_timestamp, + dt_varbit //(n) +}; + +static wxArrayString ddDatatypes; + +#endif diff --git a/include/dd/dditems/utilities/ddPrecisionScaleDialog.h b/include/dd/dditems/utilities/ddPrecisionScaleDialog.h new file mode 100644 index 0000000..5426a79 --- /dev/null +++ b/include/dd/dditems/utilities/ddPrecisionScaleDialog.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddPrecisionScaleDialog.h - Utility dialog class to allow user input of precision and scale +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDPRECISIONSCALEDIALOG_H +#define DDPRECISIONSCALEDIALOG_H + +class ddPrecisionScaleDialog : public pgDialog +{ +public: + ddPrecisionScaleDialog(); + ~ddPrecisionScaleDialog(); + ddPrecisionScaleDialog( wxWindow *parent, + const wxString &defaultValue1 = wxT("0"), + const wxString &defaultValue2 = wxT("0") + ); + + // Member initialization + void Init(); + + // Sets the validators for the dialog controls + //void SetDialogValidators(); + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + // Sets the help text for the dialog controls + void SetDialogHelp(); + + // Value1 accessors + void SetValue1(wxString value) + { + m_value1 = value; + } + wxString GetValue1() + { + return m_value1; + } + + // Value1 accessors + void SetValue2(wxString value) + { + m_value2 = value; + } + wxString GetValue2() + { + return m_value2; + } + + //wxEVT_COMMAND_TEXT_ENTER event_handle for DDVALUE1 + void OnEnterPressed( wxCommandEvent &event ); + + +protected: + // Data members + wxString m_value1, m_value2; + + DECLARE_EVENT_TABLE() + +}; +#endif + diff --git a/include/dd/dditems/utilities/ddSelectKindFksDialog.h b/include/dd/dditems/utilities/ddSelectKindFksDialog.h new file mode 100644 index 0000000..527808e --- /dev/null +++ b/include/dd/dditems/utilities/ddSelectKindFksDialog.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableNameDialog.h - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDSELECTKINDFKSDIALOG_H +#define DDSELECTKINDFKSDIALOG_H + +#include +#include "dd/dditems/figures/ddRelationshipFigure.h" + +class hdDrawingView; + +enum +{ + DDSELECTKINDFKSDIALOG = 10000, + DDSELECTKINDFK = 10001, + DDCHOICESELECTBASE = 30000 +}; + +class ddSelectFkKindLine : public hdObject +{ +public: + wxStaticText *sourceCtrl; + wxChoice *destinationCtrl; + + ddSelectFkKindLine(wxWindow *parent, wxString sourceColumn, wxArrayString possibleTargets, wxWindowID eventId); + ddSelectFkKindLine(); + ~ddSelectFkKindLine(); +}; + + +WX_DECLARE_STRING_HASH_MAP( ddSelectFkKindLine *, choicesControlsHashMap ); + +class ddSelectKindFksDialog : public wxDialog +{ + DECLARE_CLASS( ddSelectKindFksDialog ) + DECLARE_EVENT_TABLE() +public: + ddSelectKindFksDialog(); + ~ddSelectKindFksDialog(); + ddSelectKindFksDialog( wxWindow *parent, + ddRelationshipFigure *relation, + wxWindowID id = DDSELECTKINDFKSDIALOG, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxCAPTION + ); + + // Member initialization + void Init(); + // Creation + bool Create( wxWindow *parent, + wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style); + + + // Creates the controls and sizers + void CreateControls(); + + // Sets the validators for the dialog controls + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + // Sets the help text for the dialog controls + void SetDialogHelp(); + + //wxEVT_COMMAND_TEXT_ENTER event_handle for DDVALUE1 + void OnEnterPressed( wxCommandEvent &event ); + void OnOkButtonClicked( wxCommandEvent &event ); + void OnCancelButtonClicked( wxCommandEvent &event ); + + +protected: + //methods + void populateColumnsControls(bool primaryKey, int useUkIndex); + void deleteColsControls(); + void OnChoiceFkKind(wxCommandEvent &event); + + // Data members + ddRelationshipFigure *tablesRelation; + + // Dialog controls + choicesControlsHashMap choices; + wxBoxSizer *topSizer, *linesSizer, *okCancelBox, *colsTopSizer; + wxChoice *kindFkCtrl; + wxButton *ok, *cancel; + wxStaticLine *line; + +private: + +}; +#endif + diff --git a/include/dd/dditems/utilities/ddTableNameDialog.h b/include/dd/dditems/utilities/ddTableNameDialog.h new file mode 100644 index 0000000..925371e --- /dev/null +++ b/include/dd/dditems/utilities/ddTableNameDialog.h @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddTableNameDialog.h - Utility dialog class to allow user input of table name and short name +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDTABLENAMEDIALOGS_H +#define DDTABLENAMEDIALOGS_H + +#include "dlg/dlgClasses.h" +#include "dd/dditems/figures/ddTextTableItemFigure.h" + +class ddTableNameDialog : public pgDialog +{ +public: + ddTableNameDialog(); + ~ddTableNameDialog(); + ddTableNameDialog(wxWindow *parent, + const wxString &defaultValue1 = wxEmptyString, + const wxString &defaultValue2 = wxEmptyString, + ddTextTableItemFigure *tableItem = NULL + ); + + // Member initialization + void Init(); + + // Sets the validators for the dialog controls + //void SetDialogValidators(); + bool TransferDataToWindow(); + bool TransferDataFromWindow(); + + // Sets the help text for the dialog controls + void SetDialogHelp(); + + // Value1 accessors + void SetValue1(wxString value) + { + m_value1 = value; + } + wxString GetValue1() + { + return m_value1; + } + + // Value1 accessors + void SetValue2(wxString value) + { + m_value2 = value; + } + wxString GetValue2() + { + return m_value2; + } + + // CheckBox accessors + void SetValueGenerate(bool value) + { + checkGenerate = value; + } + bool GetValueGenerate() + { + return checkGenerate; + } + + //wxEVT_COMMAND_BUTTON_CLICKED event_handler for DDGENBUTTON + void OnGenButtonClicked( wxCommandEvent &event ); + + +protected: + // Data members + wxString m_value1, m_value2; + wxString label1, label2; + bool checkGenerate; + ddTextTableItemFigure *tabItem; + + DECLARE_EVENT_TABLE() + +private: + +}; +#endif + diff --git a/include/dd/dditems/utilities/module.mk b/include/dd/dditems/utilities/module.mk new file mode 100644 index 0000000..c43f2dd --- /dev/null +++ b/include/dd/dditems/utilities/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/dditems/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/dditems/utilities/ddDataType.h \ + include/dd/dditems/utilities/ddPrecisionScaleDialog.h \ + include/dd/dditems/utilities/ddSelectKindFksDialog.h \ + include/dd/dditems/utilities/ddTableNameDialog.h + +EXTRA_DIST += \ + include/dd/dditems/utilities/module.mk diff --git a/include/dd/ddmodel/ddBrowserDataContainer.h b/include/dd/ddmodel/ddBrowserDataContainer.h new file mode 100644 index 0000000..72c0927 --- /dev/null +++ b/include/dd/ddmodel/ddBrowserDataContainer.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddBrowserDataContainer.h - Item to contain data for each treview child. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDBROWSERDATACONTAINER_H +#define DDBROWSERDATACONTAINER_H + +#include "hotdraw/figures/hdIFigure.h" + +class ddBrowserDataContainer : public wxTreeItemData +{ +public: + ddBrowserDataContainer(hdIFigure *data); + ~ddBrowserDataContainer(); + int getFigureKindId(); + hdIFigure *getFigure(); + +private: + hdIFigure *figure; +}; +#endif diff --git a/include/dd/ddmodel/ddDBReverseEngineering.h b/include/dd/ddmodel/ddDBReverseEngineering.h new file mode 100644 index 0000000..b58620c --- /dev/null +++ b/include/dd/ddmodel/ddDBReverseEngineering.h @@ -0,0 +1,249 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDBReverseEngineering.h - Reverse engineering database functions for database designer. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDBREVERSEENGINEERING_H +#define DDDBREVERSEENGINEERING_H +#include "wx/wizard.h" +#include "hotdraw/main/hdObject.h" +#include "dd/dditems/utilities/ddDataType.h" +#include "schema/pgDatatype.h" +#include "dd/dditems/figures/ddTableFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +class SelSchemaPage; +class SelTablesPage; +class ReportPage; +class ddStubTable; + +enum +{ + DDALLSCHEMAS = 7001, + DDALLTABS, + DDSELTABS, + DDADD, + DDADDALL, + DDREMOVE, + DDREMOVEALL +}; + +WX_DECLARE_STRING_HASH_MAP( ddStubTable *, stubTablesHashMap); +WX_DEFINE_SORTED_ARRAY_INT(int, wxSortedArrayInt); + +// Stub tables related classes +class ddImportDBUtils : public hdObject +{ +public: + // Implement and replace at this and other dd related classes as Generation Wizard static wxArrayString getSchemasNames(...); + static wxArrayString getTablesNames(pgConn *connection, wxString schemaName); + static ddStubTable *getTable(pgConn *connection, wxString tableName, OID tableOid); + static ddTableFigure *getTableFigure(ddStubTable *table); + static void getAllRelationships(pgConn *connection, stubTablesHashMap &tables, ddDatabaseDesign *design); + static int getPgColumnNum(pgConn *connection, wxString schemaName, wxString tableName, wxString columnName); + static OID getTableOID(pgConn *connection, wxString schemaName, wxString tableName); + static OID getSchemaOID(pgConn *connection, wxString schemaName); + static bool existsFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName); + static wxArrayString getFkAtDbNotInModel(pgConn *connection, OID destTableOid, wxString schemaName, wxArrayString existingFkList, ddDatabaseDesign *design); + static bool isModelSameDbFk(pgConn *connection, OID destTableOid, wxString schemaName, wxString fkName, wxString sourceTableName, wxString destTableName, ddStubTable *destStubTable, ddRelationshipFigure *relation); + +private: + static bool setUniqueConstraints(pgConn *connection, ddStubTable *table); + static bool setPkName(pgConn *connection, ddStubTable *table); + static int sortFunc(int n1, int n2) + { + return n1 - n2; + } +}; + +class ddStubColumn : public hdObject +{ +public: + ddStubColumn(); + ddStubColumn(const ddStubColumn ©); + ddStubColumn(wxString name, OID oidSource, bool notNull, bool pk, pgDatatype *type, int ukIndex = -1); + ddStubColumn(wxString name, OID oidSource); + ~ddStubColumn(); + wxString columnName; + bool isNotNull; + bool isPrimaryKey; + bool isUniqueKey(); + int uniqueKeyIndex; + OID OIDTable; + pgDatatype *typeColumn; + int pgColNumber; +}; + +WX_DECLARE_STRING_HASH_MAP( ddStubColumn *, stubColsHashMap); + +class ddStubTable : public hdObject +{ +public: + ddStubTable(); + ddStubTable(wxString name, OID tableOID); + ddStubColumn *getColumnByNumber(int pgColNumber); + ~ddStubTable(); + wxString tableName; + OID OIDTable; + stubColsHashMap cols; + wxString PrimaryKeyName; + wxArrayString UniqueKeysNames; +}; + +// +// +// Wizard related classes +// +// +// + +WX_DECLARE_STRING_HASH_MAP( OID, oidsHashMap); + +class ddDBReverseEngineering : public wxWizard +{ +public: + ddDBReverseEngineering(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer = true); + ~ddDBReverseEngineering(); + + //Wizard related functions + wxWizardPage *GetFirstPage() const + { + return initialPage; + } + + // Reverse Enginnering related functions + wxArrayString getTables(); + pgConn *getConnection() + { + return conn; + }; + + //transfer data between pages + OID OIDSelectedSchema; + wxString schemaName; + oidsHashMap tablesOIDHM; + stubTablesHashMap stubsHM; + SelSchemaPage *page2; + SelTablesPage *page3; + ReportPage *page4; + ddDatabaseDesign *getDesign() + { + return figuresDesign; + }; + +private: + void OnFinishPressed(wxWizardEvent &event); + pgConn *conn; + wxWizardPageSimple *initialPage; + wxStaticText *frontText; + ddDatabaseDesign *figuresDesign; + DECLARE_EVENT_TABLE() +}; + +class SelSchemaPage : public wxWizardPage +{ +public: + SelSchemaPage(wxWizard *parent, wxWizardPage *prev); + ~SelSchemaPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } +private: + void OnWizardPageChanging(wxWizardEvent &event); + void refreshSchemas(pgConn *connection); + wxStaticText *message; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allSchemas; + wxArrayString schemasNames; + oidsHashMap schemasHM; + ddDBReverseEngineering *wparent; + DECLARE_EVENT_TABLE() +}; + + +class SelTablesPage : public wxWizardPage +{ +public: + SelTablesPage(wxWizard *parent, wxWizardPage *prev); + ~SelTablesPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + void RefreshTablesList(); + void OnButtonAdd(wxCommandEvent &); + void OnButtonAddAll(wxCommandEvent &); + void OnButtonRemove(wxCommandEvent &); + void OnButtonRemoveAll(wxCommandEvent &); +private: + void OnWizardPageChanging(wxWizardEvent &event); + wxStaticText *leftText, *rightText, *centerText; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allTables, *m_selTables; + ddDBReverseEngineering *wparent; + wxArrayString tablesNames; + wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll; + wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap; + DECLARE_EVENT_TABLE() +}; + +class ReportPage : public wxWizardPage +{ +public: + ReportPage(wxWizard *parent, wxWizardPage *prev); + ~ReportPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + wxTextCtrl *results; +private: + void OnWizardPageChanging(wxWizardEvent &event); + wxWizardPage *m_prev, *m_next; + ddDBReverseEngineering *wparent; + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/dd/ddmodel/ddDatabaseDesign.h b/include/dd/ddmodel/ddDatabaseDesign.h new file mode 100644 index 0000000..bd23eac --- /dev/null +++ b/include/dd/ddmodel/ddDatabaseDesign.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddDatabaseDesign.h - Manages all design related info and contains all model(s) and tables. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDATABASEDESIGN_H +#define DDDATABASEDESIGN_H + +#include +#include + +#include "dd/ddmodel/ddDrawingEditor.h" +#include "hotdraw/tools/hdITool.h" +#include "dd/dditems/figures/ddTableFigure.h" + +class ddModelBrowser; + +enum +{ + DDGENCREATE = 6000, + DDGENALTER, + DDGENDROPCRE, + DDGENNOTHING +}; + +WX_DECLARE_STRING_HASH_MAP( wxString , tablesMappingHashMap ); + +class ddDatabaseDesign : public wxObject +{ +public: + ddDatabaseDesign(wxWindow *parent, wxWindow *frmOwner); + ~ddDatabaseDesign(); + hdDrawingView *getView(int diagramIndex); + ddDrawingEditor *getEditor(); + void addTableToModel(hdIFigure *figure); + void addTableToView(int diagramIndex, hdIFigure *figure); + void removeTable(int diagramIndex, hdIFigure *figure); + hdDrawing *createDiagram(wxWindow *owner, wxString name, bool fromXml); + void deleteDiagram(int diagramIndex, bool deleteView = true); + void refreshDraw(int diagramIndex); + void eraseDiagram(int diagramIndex); + void emptyModel(); + wxArrayString getDiagramTables(int diagramIndex); + wxString generateDiagram(int diagramIndex, wxString schemaName); + wxArrayString getModelTables(); + wxString generateModel(wxString schemaName); + wxString generateList(wxArrayString tables, wxArrayInt options, pgConn *connection = NULL, wxString schemaName = wxEmptyString); + bool validateModel(wxString &errors); + ddTableFigure *getSelectedTable(int diagramIndex); + ddTableFigure *getTable(wxString tableName); + bool writeXmlModel(wxString file); + bool readXmlModel(wxString file, ctlAuiNotebook *notebook); + + wxString getTableId(wxString tableName); + void addTableToMapping(wxString IdKey, wxString tableName); + wxString getTableName(wxString Id); + void registerBrowser(ddModelBrowser *browser); + void refreshBrowser(); + static wxString getVersionXML(); + void markSchemaOn(wxArrayString tables); + void unMarkSchemaOnAll(); + +protected: + tablesMappingHashMap mappingNameToId; + tablesMappingHashMap mappingIdToName; +private: + ddModelBrowser *attachedBrowser; + int diagramCounter; + ddDrawingEditor *editor; + hdITool *tool; + xmlTextWriterPtr xmlWriter; + +}; +#endif diff --git a/include/dd/ddmodel/ddDrawingEditor.h b/include/dd/ddmodel/ddDrawingEditor.h new file mode 100644 index 0000000..7d0af43 --- /dev/null +++ b/include/dd/ddmodel/ddDrawingEditor.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.h - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDRAWINGEDITOR_H +#define DDDRAWINGEDITOR_H + +#include "hotdraw/main/hdDrawingEditor.h" +class frmDatabaseDesigner; + +enum +{ + MNU_NEWTABLE = 321 +}; + +class ddDatabaseDesign; + +class ddDrawingEditor : public hdDrawingEditor +{ +public: + ddDrawingEditor(wxWindow *owner, wxWindow *frmOwner, ddDatabaseDesign *design); + virtual hdDrawing *createDiagram(wxWindow *owner, bool fromXml); + virtual void remOrDelSelFigures(int diagramIndex); + void checkRelationshipsConsistency(int diagramIndex); + void checkAllDigramsRelConsistency(); + ddDatabaseDesign *getDesign() + { + return databaseDesign; + }; + virtual void notifyChanged(); + +protected: +private: + ddDatabaseDesign *databaseDesign; + frmDatabaseDesigner *frm; +}; +#endif diff --git a/include/dd/ddmodel/ddDrawingView.h b/include/dd/ddmodel/ddDrawingView.h new file mode 100644 index 0000000..f2ee5dc --- /dev/null +++ b/include/dd/ddmodel/ddDrawingView.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.h - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDDRAWINGVIEW_H +#define DDDRAWINGVIEW_H + +#include "hotdraw/main/hdDrawingView.h" +#include "dd/ddmodel/ddDrawingEditor.h" +#include "dd/ddmodel/ddDatabaseDesign.h" + +class ddDrawingView : public hdDrawingView +{ +public: + ddDrawingView(int diagram, wxWindow *ddParent, ddDrawingEditor *editor , wxSize size, hdDrawing *drawing); + //Hack To allow right click menu at canvas without a figure + virtual void createViewMenu(wxMenu &mnu); + virtual void OnGenericViewPopupClick(wxCommandEvent &event); +protected: +private: +}; + +// A drop target that do nothing only accept text, if accept then tree add table to model +class ddDropTarget : public wxTextDropTarget +{ +public: + ddDropTarget(ddDatabaseDesign *sourceDesign, hdDrawing *targetDrawing); + virtual bool OnDropText(wxCoord x, wxCoord y, const wxString &text); +private: + hdDrawing *target; + ddDatabaseDesign *source; +}; +#endif diff --git a/include/dd/ddmodel/ddGenerationWizard.h b/include/dd/ddmodel/ddGenerationWizard.h new file mode 100644 index 0000000..30d2a67 --- /dev/null +++ b/include/dd/ddmodel/ddGenerationWizard.h @@ -0,0 +1,224 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddBrowserDataContainer.h - Item to contain data for each treview child. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDGENERATIONWIZARD_H +#define DDGENERATIONWIZARD_H + +#include "hotdraw/figures/hdIFigure.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "dd/ddmodel/ddDBReverseEngineering.h" +#include + +class SelGenTablesPage; +class SelGenSchemaPage; +class ReportGridPage; + +enum +{ + DDTABSGRID = 7100 +}; + +class ddGenerationWizard : public wxWizard +{ +public: + ddGenerationWizard(wxFrame *frame, ddDatabaseDesign *design, pgConn *connection, bool useSizer = true); + ~ddGenerationWizard(); + + // Wizard related functions + wxWizardPage *GetFirstPage() const + { + return initialPage; + } + ddDatabaseDesign *getDesign() + { + return figuresDesign; + }; + pgConn *getConnection() + { + return conn; + }; + // Transfer data between pages + OID OIDSelectedSchema; + wxString schemaName; + SelGenTablesPage *page2; + SelGenSchemaPage *page3; + ReportGridPage *page4; + wxString DDL; + wxArrayString preSelTables; + +private: + + void OnWizardPageChanging(wxWizardEvent &event); + + // Page 4 - Report and Finish + void OnFinishPressed(wxWizardEvent &event); + + pgConn *conn; + wxWizardPageSimple *initialPage; + wxStaticText *frontText; + ddDatabaseDesign *figuresDesign; + DECLARE_EVENT_TABLE() +}; + +class SelGenTablesPage : public wxWizardPage +{ +public: + SelGenTablesPage(wxWizard *parent, wxWizardPage *prev); + ~SelGenTablesPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + void OnButtonAdd(wxCommandEvent &); + void OnButtonAddAll(wxCommandEvent &); + void OnButtonRemove(wxCommandEvent &); + void OnButtonRemoveAll(wxCommandEvent &); + void RefreshTablesList(); + int countSelTables() + { + return m_selTables->GetCount(); + }; + wxString getSelTableName(int index) + { + return m_selTables->GetString(index); + }; +private: + void moveToSelectList(wxString tableName); + void OnWizardPageChanging(wxWizardEvent &event); + wxStaticText *leftText, *rightText, *centerText; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allTables, *m_selTables; + ddGenerationWizard *wparent; + wxArrayString tablesNames; + wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll; + wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap; + DECLARE_EVENT_TABLE() +}; + +class SelGenSchemaPage : public wxWizardPage +{ +public: + SelGenSchemaPage(wxWizard *parent, wxWizardPage *prev); + ~SelGenSchemaPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } +private: + void OnWizardPageChanging(wxWizardEvent &event); + void refreshSchemas(pgConn *connection); + wxStaticText *message; + wxWizardPage *m_prev, *m_next; + wxListBox *m_allSchemas; + wxArrayString schemasNames; + oidsHashMap schemasHM; + ddGenerationWizard *wparent; + DECLARE_EVENT_TABLE() +}; + +// Special version of wxGrid to allow use of fast comboboxes and grid columns auto fit +// some snippets from http://forums.wxwidgets.org/viewtopic.php?t=27568 under same wxwidgets license +// others from pgAdming gqb +class wxDDGrid: public wxGrid +{ +public: + wxDDGrid(wxWindow *parent, wxWindowID id); + void ComboBoxEvent(wxGridEvent &event); + void RevertSel(); + + int sf[10]; + + void OnSizeEvt( wxSizeEvent &ev ); + int StretchIt(); + int keepFit; + +public: + void SetColStretch ( unsigned i, int factor ) + { + if( i < 10 ) sf[i] = factor; + } + int GetColStretch ( unsigned i ) const + { + return (i < 10) ? sf[i] : 1; + } + void ReLayout() + { + StretchIt(); + } + void SetFit( int fit_style ) + { + keepFit = fit_style; + } +private: + wxGridSelection *m_selTemp; +}; + +class ReportGridPage : public wxWizardPage +{ +public: + ReportGridPage(wxWizard *parent, wxWizardPage *prev); + ~ReportGridPage(); + virtual wxWizardPage *GetPrev() const + { + return m_prev; + }; + virtual wxWizardPage *GetNext() const + { + return m_next; + }; + void SetPrev(wxWizardPage *prev) + { + m_prev = prev; + } + void SetNext(wxWizardPage *next) + { + m_next = next; + } + void populateGrid(); + wxDDGrid *getGrid() + { + return reportGrid; + }; +private: + void OnWizardPageChanging(wxWizardEvent &event); + void OnCellLeftClick(wxGridEvent &ev); + + wxStaticText *message; + wxWizardPage *m_prev, *m_next; + wxDDGrid *reportGrid; + ddGenerationWizard *wparent; + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/dd/ddmodel/ddModelBrowser.h b/include/dd/ddmodel/ddModelBrowser.h new file mode 100644 index 0000000..54c6d4e --- /dev/null +++ b/include/dd/ddmodel/ddModelBrowser.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddModelBrowser.h - Tables Tree of Database Designer. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DDMODELBROWSER_H +#define DDMODELBROWSER_H + +#include "dd/ddmodel/ddDatabaseDesign.h" + +enum ddBrowser +{ + DD_BROWSER = 13000 +}; + +enum ddBrowserImages +{ + DD_IMG_FIG_DATABASE = 0, + DD_IMG_FIG_TABLE = 1 +}; + +class ddModelBrowser : public wxTreeCtrl +{ +public: + ddModelBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, ddDatabaseDesign *design); + ~ddModelBrowser(); + wxTreeItemId &createRoot(wxString Name); + void refreshFromModel(); + +private: + void OnItemActivated(wxTreeEvent &event); + void OnBeginDrag(wxTreeEvent &event); + + wxTreeItemId rootNode; + ddDatabaseDesign *ownerDesign; + wxImageList *imageList; + + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/dd/ddmodel/module.mk b/include/dd/ddmodel/module.mk new file mode 100644 index 0000000..07d6030 --- /dev/null +++ b/include/dd/ddmodel/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/ddmodel/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dd/ddmodel/ddBrowserDataContainer.h \ + include/dd/ddmodel/ddDatabaseDesign.h \ + include/dd/ddmodel/ddDrawingEditor.h \ + include/dd/ddmodel/ddDBReverseEngineering.h \ + include/dd/ddmodel/ddDrawingView.h \ + include/dd/ddmodel/ddGenerationWizard.h \ + include/dd/ddmodel/ddModelBrowser.h + +EXTRA_DIST += \ + include/dd/ddmodel/module.mk diff --git a/include/dd/module.mk b/include/dd/module.mk new file mode 100644 index 0000000..426ff07 --- /dev/null +++ b/include/dd/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dd/ Makefile fragment +# +####################################################################### + +include include/dd/dditems/module.mk +include include/dd/ddmodel/module.mk + + +EXTRA_DIST += \ + include/dd/module.mk diff --git a/include/debugger/ctlMessageWindow.h b/include/debugger/ctlMessageWindow.h new file mode 100644 index 0000000..d1882bf --- /dev/null +++ b/include/debugger/ctlMessageWindow.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlMessageWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlMessageWindow +// +// This class implements the window that displays DBMS messages at the +// bottom of the debugger window. When we create a ctlMessageWindow, the parent +// is a ctlTabWindow (the ctlMessageWindow becomes a tab in a tab control). +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLMESSAGEWINDOW_H +#define CTLMESSAGEWINDOW_H + +class ctlMessageWindow : public wxTextCtrl +{ + DECLARE_CLASS(ctlMessageWindow) + DECLARE_EVENT_TABLE() + +public: + ctlMessageWindow(wxWindow *parent, wxWindowID id); + + void AddMessage(wxString message); // Add a message to the window + void DelMessage(const char *name = NULL); // Remove a message from the window + wxString GetMessage(int row); + +protected: + wxString m_currMsg; + wxTimer m_timer; + wxMutex m_mutex; + + void OnTimer(wxTimerEvent &); +}; + +#endif diff --git a/include/debugger/ctlResultGrid.h b/include/debugger/ctlResultGrid.h new file mode 100644 index 0000000..b4844bb --- /dev/null +++ b/include/debugger/ctlResultGrid.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlResultGrid.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlResultGrid +// +// A ctlResultGrid is a grid control that knows how to display that result set +// generated by a PostgreSQL query. In the workstation application, a ctlResultGrid +// is a child of the notebook owned by a ctlTabWindow. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLRESULTGRID_H +#define CTLRESULTGRID_H + +#include + +class ctlResultGrid : public wxGrid +{ + DECLARE_CLASS(ctlResultGrid) + +public: + ctlResultGrid(wxWindow *parent, wxWindowID id); + + // Copy a result set into the grid + void FillResult(pgSet *set); +}; + +#endif diff --git a/include/debugger/ctlStackWindow.h b/include/debugger/ctlStackWindow.h new file mode 100644 index 0000000..95f6d92 --- /dev/null +++ b/include/debugger/ctlStackWindow.h @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlStackWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlStackWindow +// +// This class implements the window that displays the current call stack at +// bottom of the debugger window. When we create a ctlStackWindow, the parent +// is a ctlTabWindow (the ctlStackWindow becomes a tab in a tab control). +// +// It is a simple grid control - the grid contains two columns: +// the RowLabel column displays the stack level +// column 0 displays the function name, line number and argument list +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLSTACKWINDOW_H +#define CTLSTACKWINDOW_H + +#include +#include +#include +#include + +class dbgStackFrame : public wxClientData +{ +public: + dbgStackFrame(const wxString &_level, const wxString &_pkg, + const wxString &_func, const wxString &_desc) + : m_level(_level), m_func(_func), m_pkg(_pkg), m_desc(_desc) {} + + dbgStackFrame(const dbgStackFrame &s) + : m_level(s.m_level), m_func(s.m_func), m_pkg(s.m_pkg), m_desc(s.m_pkg) {} + + const wxString &GetLevel() const + { + return m_level; + } + const wxString &GetFunction() const + { + return m_func; + } + const wxString &GetPackage() const + { + return m_pkg; + } + const wxString &GetDescription() const + { + return m_desc; + } + +private: + wxString m_level, m_func, m_pkg, m_desc; +}; + +WX_DECLARE_LIST(dbgStackFrame, dbgStackFrameList); + + +class ctlStackWindow : public wxListBox +{ + DECLARE_CLASS( ctlVarWindow ) + +public: + ctlStackWindow(wxWindow *parent, wxWindowID id, + const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, + long style = wxCLIP_CHILDREN | wxSW_3D, + const wxString &name = wxT("stackWindow")); + + // Remove all frames from the stack trace + void ClearStack(); + // Add an array of frames to the stack trace + void SetStack(const dbgStackFrameList &stacks, int selected = -1); + void SelectFrame(const wxString &pkg, const wxString &frm); +}; + +#endif diff --git a/include/debugger/ctlTabWindow.h b/include/debugger/ctlTabWindow.h new file mode 100644 index 0000000..619f9bb --- /dev/null +++ b/include/debugger/ctlTabWindow.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlTabWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlTabWindow +// +// The ctlTabWindow class implements the tab control that displays at the +// bottom of the debugger window. +// +// A ctlTabWindow object holds a notebook control, a result window (a window +// that displays the result set generated by a query), and a varWindow (a +// window that displays the local variables when debugging a PL function). +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLTABWINDOW_H +#define CTLTABWINDOW_H + +#include +#include + +#include "debugger/ctlVarWindow.h" +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlResultGrid.h" + +WX_DECLARE_HASH_MAP(int, int, wxIntegerHash, wxIntegerEqual, wsTabHash); + +class ctlTabWindow : public ctlAuiNotebook +{ + DECLARE_CLASS(ctlTabWindow) + +public: + + ctlTabWindow(wxWindow *parent, wxWindowID id, + const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, + long style = wxCLIP_CHILDREN | wxSW_3D, + const wxString &name = wxT("layoutWindow")); + + ctlVarWindow *GetVarWindow(bool create = true); // Returns a pointer to the local-variables window (creates it if requested) + ctlVarWindow *GetPkgVarWindow(bool create = true); // Returns a pointer to the package-variables window (creates it if requested) + ctlVarWindow *GetParamWindow(bool create = true); // Returns a pointer to the parameters window (creates it if requested) + + ctlResultGrid *GetResultWindow(); // Returns a pointer to the result window (creates it if necessary) + ctlStackWindow *GetStackWindow(); // Returns a pointer to the stack-trace window (creates it if necessary) + ctlMessageWindow *GetMessageWindow(); // Returns a pointer to the DBMS messages window (creates it if necessary) + void SelectTab(wxWindowID id); + +private: + ctlResultGrid *m_resultWindow; // Displays the result set from a query + ctlVarWindow *m_varWindow; // Displays the local variables when debugging a PL function + ctlVarWindow *m_pkgVarWindow; // Displays the package variables when debugging a PL function + ctlStackWindow *m_stackWindow; // Displays the current call stack + ctlVarWindow *m_paramWindow; // Displays the parameters when debugging a PL function + ctlMessageWindow *m_messageWindow; // Displays the DBMS messages when debugging a PL function + + wsTabHash *m_tabMap; // Map window ID's to tab numbers; +}; + +#endif diff --git a/include/debugger/ctlVarWindow.h b/include/debugger/ctlVarWindow.h new file mode 100644 index 0000000..5713e99 --- /dev/null +++ b/include/debugger/ctlVarWindow.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ctlVarWindow.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class ctlVarWindow +// +// This class implements the window that displays PL variable values at the +// bottom of the debugger window. When we create a ctlVarWindow, the parent +// is a ctlTabWindow (the ctlVarWindow becomes a tab in a tab control). +// +// It is a simple grid control - the grid contains three columns: +// the RowLabel column displays the name of each variable +// column 0 displays the value of each variable +// column 1 displays the data type of each variable +// +// Each ctlVarWindow contains a hash map that can locate a grid cell given a +// variable name +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef CTLVARWINDOW_H +#define CTLVARWINDOW_H + +#include +#include +#include + +class ctlVarWindow : public wxGrid +{ + DECLARE_CLASS(ctlVarWindow) + +public: + ctlVarWindow(wxWindow *parent, wxWindowID id); + + // Add a variable to the window + void AddVar(wxString name, wxString value, wxString type, bool readOnly); + // Remove a variable from the window + void DelVar(wxString name = wxEmptyString); + + wxString GetVarName(int row); + wxString GetVarValue(int row); + +private: + + // The content of a grid cell is defined by the gridCell structure + typedef struct + { + int m_row; // Row number for this variable/grid cell + wxString m_value; // Variable value + wxString m_type; // Variable type + } gridCell; + + enum + { + COL_NAME = 0, // Column 0 contains the variable name + COL_TYPE, // This column contains the variable type + COL_VALUE // This column contains the variable value + }; + + // The m_cells hash translates variable names into gridCell references +public: + WX_DECLARE_STRING_HASH_MAP(gridCell, wsCellHash); + WX_DECLARE_HASH_SET(wxString, wxStringHash, wxStringEqual, wsStringSet); + +private: + wsStringSet m_hiddenNames; // List of hidden variable names + wsStringSet m_hiddenTypes; // List of hidden variable types + wsCellHash *m_cells; // name-to-gridCell map + wxFont m_nameFont; // Font used to display field names +}; + +#endif diff --git a/include/debugger/dbgBreakPoint.h b/include/debugger/dbgBreakPoint.h new file mode 100644 index 0000000..1cda8f1 --- /dev/null +++ b/include/debugger/dbgBreakPoint.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgBreakPoint.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class dbgBreakPoint +// +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DBGBREAKPOINT_H +#define DBGBREAKPOINT_H + +class dbgBreakPoint +{ +public: + dbgBreakPoint(const wxString &_funcOid, const wxString &_pkgOid = wxT("-1"), + const int &_lineNo = -1) + : m_func(_funcOid), m_pkg(_pkgOid), m_lineNo(_lineNo) {} + + wxString &GetFunctionOid() + { + return m_func; + } + wxString &GetPackageOid() + { + return m_pkg; + } + int &GetLineNo() + { + return m_lineNo; + } + +private: + wxString m_func; + wxString m_pkg; + int m_lineNo; +}; + +WX_DECLARE_LIST(dbgBreakPoint, dbgBreakPointList); + +#endif diff --git a/include/debugger/dbgConst.h b/include/debugger/dbgConst.h new file mode 100644 index 0000000..7e434ef --- /dev/null +++ b/include/debugger/dbgConst.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgConst.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// +// Constants and enumerator Identifiers for the entire debugger +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DBGCONST_H +#define DBGCONST_H + +const int ID_BTNNEXT = 1800; +const int ID_GRDFUNCARGS = 1810; +const int ID_TXTMESSAGE = 1820; +const int ID_TIMER = 1830; +const int ID_BTNCANCEL = 1840; + +const int ID_PARAMGRID = 1000; +const int ID_VARGRID = 1001; +const int ID_MSG_PAGE = 1002; +const int ID_PKGVARGRID = 1003; + +enum +{ + MENU_ID_EXECUTE = 10001, // Execute command entered by user + + MENU_ID_TOGGLE_BREAK, // Set/Unset breakpoint + MENU_ID_CLEAR_ALL_BREAK, // Clear all breakpoints + MENU_ID_CONTINUE, // Continue + MENU_ID_STEP_OVER, // Step over + MENU_ID_STEP_INTO, // Step into + MENU_ID_STOP, // Stop debugging + + MENU_ID_START_DEBUGGING, // Spawn a separate debugger process + MENU_ID_NOTICE_RECEIVED, // NOTICE received from server + WINDOW_ID_STACK, // Tree-control window + WINDOW_ID_CONSOLE, // Console window + WINDOW_ID_TABS, // Tab window + WINDOW_ID_BREAKPOINTS, // Breakpoints window + WINDOW_ID_RESULT_GRID, // Results window + WINDOW_ID_COMMAND, // Command window + SOCKET_ID_DEBUG, // Debugger Socket ID + + MENU_ID_VIEW_TOOLBAR, // View menu options + MENU_ID_VIEW_STACKPANE, + MENU_ID_VIEW_OUTPUTPANE, + MENU_ID_VIEW_DEFAULTVIEW, + + RESULT_ID_ATTACH_TO_PORT, // Debugger - attach to port completed + RESULT_ID_BREAKPOINT, // Debugger - breakpoint reached + RESULT_ID_GET_VARS, // Debugger - variable list complete + RESULT_ID_GET_STACK, // Debugger - stack trace complete + RESULT_ID_GET_BREAKPOINTS, // Debugger - breakpoint list complete + RESULT_ID_NEW_BREAKPOINT, // Debugger - set breakpoint complete + RESULT_ID_NEW_BREAKPOINT_WAIT, // Debugger - set breakpoint complete, wait for target progress + RESULT_ID_DEL_BREAKPOINT, // Debugger - drop breakpoint complete + RESULT_ID_DEPOSIT_VALUE, // Debugger - deposit value complete + RESULT_ID_ADD_BREAKPOINT, // Debugger - target info received, now set a breakpoint + RESULT_ID_LISTENER_CREATED, // Debugger - global listener created + RESULT_ID_TARGET_READY, // Debugger - target session attached + RESULT_ID_LAST_BREAKPOINT, // Debugger - last breakpoint created + RESULT_ID_ARGS_UPDATED, // Debugger - Values are evaluated and been updated in the arguments + RESULT_ID_ARGS_UPDATE_ERROR, // Debugger - Error while evaluateling the value for the arguments + + RESULT_ID_DIRECT_TARGET_COMPLETE, // DirectDebug - target function complete + + ID_DEBUG_INITIALIZER // Debugger - debug package initializer? checkbox + +}; + +#endif diff --git a/include/debugger/dbgController.h b/include/debugger/dbgController.h new file mode 100644 index 0000000..19fe1b3 --- /dev/null +++ b/include/debugger/dbgController.h @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgController.h - Debugger controller +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class dbgController +// +// A dbgController object controls the behaviour of the debugger. It stays +// in the central of the whole debugger mechanism. It controls the flow of +// execution and also, asks the view to update the user presentation (when +// needed), also execute commands based on the user inputs. +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DBGCONTROLLER_H +#define DBGCONTROLLER_H + +#include +#include + +#include "db/pgQueryResultEvent.h" +#include "debugger/dbgTargetInfo.h" +#include "debugger/dbgModel.h" + +class frmMain; +class frmDebugger; + +typedef enum +{ + DBG_SESSION_TYPE_UNKNOWN, // Session could be in-context or direct + DBG_SESSION_TYPE_INCONTEXT, // Session is configured for in-context debugging + DBG_SESSION_TYPE_DIRECT // Session is configured for direct debugging +} DebuggerSessionType; + + +typedef enum +{ + DEBUGGER_UNKNOWN_API = 0, + DEBUGGER_V1_API = 1, + DEBUGGER_V2_API = 2, + DEBUGGER_V3_API = 3 +} DebuggerApiVersion; + + +class dbgController : public wxEvtHandler +{ +public: + dbgController(frmMain *_main, pgObject *_obj, bool _directDebugging = false); + ~dbgController(); + + dbgTargetInfo *GetTargetInfo(); + dbgModel *GetModel() + { + return m_model; + } + + bool CanRestart() + { + return (m_dbgConn && (m_dbgConn->GetStatus() != PGCONN_OK)); + } + + // Debugging actions (called from the frmDebugger) + bool Start(); + void ClearBreakpoint(int _lineNo); + void SetBreakpoint(int _lineNo); + void Countinue(); + void StepOver(); + void StepInto(); + bool Stop(); + void DepositValue(const wxString &_name, const wxString &_val); + bool SelectFrame(int _frameNo); + void UpdateBreakpoints(); + + bool HandleQuery(pgBatchQuery *_qry, const wxString &_err); + + // Closing Debugger + bool CloseDebugger(); + bool ExecuteTarget(); + bool IsTerminated() + { + return m_terminated; + } + + // Event functions + void OnNoticeReceived(wxCommandEvent &); + void OnStartDebugging(wxCommandEvent &); + + void ResultTargetComplete(pgQueryResultEvent &); + void ResultPortAttach(pgQueryResultEvent &); + void ResultBreakpoint(pgQueryResultEvent &); + void ResultVarList(pgQueryResultEvent &); + void ResultStack(pgQueryResultEvent &); + void ResultBreakpoints(pgQueryResultEvent &); + void ResultNewBreakpoint(pgQueryResultEvent &); + void ResultNewBreakpointWait(pgQueryResultEvent &); + void ResultDeletedBreakpoint(pgQueryResultEvent &); + void ResultDepositValue(pgQueryResultEvent &); + void ResultListenerCreated(pgQueryResultEvent &); + void ResultTargetReady(pgQueryResultEvent &); + +private: + static void NoticeHandler(void *arg, const char *message); + +private: + const static wxString ms_cmdDebugSPLV1; + const static wxString ms_cmdDebugSPLV2; + const static wxString ms_cmdDebugPLPGSQLV1; + const static wxString ms_cmdDebugPLPGSQLV2; + const static wxString ms_cmdAttachToPort; + const static wxString ms_cmdWaitForBreakpointV1; + const static wxString ms_cmdWaitForBreakpointV2; + const static wxString ms_cmdGetVars; + const static wxString ms_cmdGetStack; + const static wxString ms_cmdGetBreakpoints; + const static wxString ms_cmdStepOverV1; + const static wxString ms_cmdStepOverV2; + const static wxString ms_cmdStepIntoV1; + const static wxString ms_cmdStepIntoV2; + const static wxString ms_cmdContinueV1; + const static wxString ms_cmdContinueV2; + const static wxString ms_cmdSetBreakpointV1; + const static wxString ms_cmdSetBreakpointV2; + const static wxString ms_cmdClearBreakpointV1; + const static wxString ms_cmdClearBreakpointV2; + const static wxString ms_cmdSelectFrameV1; + const static wxString ms_cmdSelectFrameV2; + const static wxString ms_cmdDepositValue; + const static wxString ms_cmdAbortTarget; + const static wxString ms_cmdAddBreakpointEDB; + const static wxString ms_cmdAddBreakpointPG; + const static wxString ms_cmdGetTargetInfo; + const static wxString ms_cmdCreateListener; + const static wxString ms_cmdWaitForTarget; + const static wxString ms_cmdIsBackendRunning; + +private: + // Debugger Version for the current server + DebuggerApiVersion m_ver; + + // Session type + DebuggerSessionType m_sessionType; + + // Line actually shown from this offset + int m_lineOffset; + + // Debugging Terminated + bool m_terminated; + bool m_isStopping; + + // Main Window for the debugger + frmDebugger *m_frm; + + // Connection for collecting the current debugging information + pgConn *m_dbgConn; + // Connetion Thread for fetching the debugging information in background + pgQueryThread *m_dbgThread; + // Connection to execute the function/procedure for the direct debugging + pgConn *m_execConn; + // Connection-thread to run the function in background for debugging + pgQueryThread *m_execConnThread; + // Mutex for debugger thread + wxMutex m_dbgThreadLock; + + // Debugger Data Model + dbgModel *m_model; + + // In-direct Debugging on which target-pid + wxString m_currTargetPid; + + DECLARE_EVENT_TABLE() + +}; + +#define MARKERINDEX_TO_MARKERMASK( MI ) ( 1 << MI ) + +#endif diff --git a/include/debugger/dbgModel.h b/include/debugger/dbgModel.h new file mode 100644 index 0000000..5379b6f --- /dev/null +++ b/include/debugger/dbgModel.h @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgModel.h - Debugger Model +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DBGMODEL_H +#define DBGMODEL_H + +#include + +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgTargetInfo.h" + +class dbgCachedStack +{ +public: + dbgCachedStack() {} + dbgCachedStack(const wxString &_pkg, const wxString &_func, + const wxString &_target, const wxString &_arg, const wxString &_src) + : m_func(_func), m_pkg(_pkg), m_source(_src), + m_target(_target), m_arg(_arg) {} + + dbgCachedStack(const dbgCachedStack &_src) + : m_func(_src.m_func), m_pkg(_src.m_pkg), m_source(_src.m_source), + m_target(_src.m_target), m_arg(_src.m_arg) {} + + dbgCachedStack &operator =(const dbgCachedStack &_src) + { + m_func = _src.m_func; + m_pkg = _src.m_pkg; + m_source = _src.m_source; + m_target = _src.m_target; + m_arg = _src.m_arg; + + return *this; + } + +private: + wxString m_pkg; // Package OID + wxString m_func; // Function OID + wxString m_target; // Target Name + wxString m_arg; // Argument passed to the target + wxString m_source; // Source code for this function + + friend class frmDebugger; +}; + +WX_DECLARE_STRING_HASH_MAP(dbgCachedStack, dbgSourceHash); + +class dbgModel +{ +public: + dbgModel(Oid _target, pgConn *_conn); + + dbgTargetInfo *GetTarget() + { + return m_target; + } + dbgBreakPointList &GetBreakPoints() + { + return m_breakpoints; + } + + wxString &GetPort() + { + return m_port; + } + wxString &GetSession() + { + return m_session; + } + wxString &GetTargetPid() + { + return m_targetPid; + } + + bool GetSource(const wxString &_funcOid, dbgCachedStack *_cached = NULL); + void ClearCachedSource(); + void AddSource(const wxString &_funcOid, const dbgCachedStack &cached); + + bool RequireDisplayUpdate() + { + return (m_focusedFuncOid != m_displayedFuncOid || + m_displayedPkgOid != m_focusedPkgOid); + } + + wxString &GetFocusedPackage() + { + return m_focusedPkgOid; + } + wxString &GetDisplayedPackage() + { + return m_displayedPkgOid; + } + wxString &GetFocusedFunction() + { + return m_focusedFuncOid; + } + wxString &GetDisplayedFunction() + { + return m_displayedFuncOid; + } + + int &GetCurrLineNo() + { + return m_currLineNo; + } + +private: + // Target Information + dbgTargetInfo *m_target; + + // Break-Points + dbgBreakPointList m_breakpoints; + + // Debugging Port, session-handle & target-backend pid + wxString m_port; + wxString m_session; + wxString m_targetPid; + + // Cached source-code for the stacked functions + dbgSourceHash m_sourceMap; + + // Current focused function-information + wxString m_focusedFuncOid; + wxString m_focusedPkgOid; + + // Current displayed function-information + wxString m_displayedFuncOid; + wxString m_displayedPkgOid; + + // Current Line number + int m_currLineNo; +}; + +#endif diff --git a/include/debugger/dbgTargetInfo.h b/include/debugger/dbgTargetInfo.h new file mode 100644 index 0000000..9ea7c9e --- /dev/null +++ b/include/debugger/dbgTargetInfo.h @@ -0,0 +1,248 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dbgTargetInfo.h - debugger +// +////////////////////////////////////////////////////////////////////////// +#ifndef DBGTARGETINFO_H +#define DBGTARGETINFO_H + +#include +#include "db/pgConn.h" +#include "db/pgQueryThread.h" + + +//////////////////////////////////////////////////////////////////////////////// +// class dbgArgInfo +// +// A dbgArgInfo object contains information about a function (or procedure) +// argument. Inside of each wsArgInfo object, we store the name of the argument, +// the argument type, and the argument mode (IN (i), OUT (o), or INOUT (b)). +// +// Once the user has had a chance to enter values for each of the IN and INOUT +// arguments, we store those values inside of the corresponding wsArgInfo objects +class dbgArgInfo +{ +public: + dbgArgInfo(const wxString &_name, const wxString &_type, Oid _typeOid, + short _mode = pgParam::PG_PARAM_IN); + + Oid GetType() + { + return m_typeOid; + } + const wxString &GetTypeName() + { + return m_type; + } + wxString &GetName() + { + return m_name; + } + short GetMode() + { + return m_mode; + } + bool IsArray() + { + return !(m_baseType.IsEmpty()); + } + const wxString &GetBaseType() + { + return m_baseType; + } + bool &Null() + { + return m_null; + } + wxString &Value() + { + return m_val; + } + + void SetDefault(const wxString &val) + { + m_hasDefault = true; + m_defValue = val; + } + wxString &Default() + { + return m_defValue; + } + bool HasDefault() + { + return m_hasDefault; + } + bool &UseDefault() + { + return m_useDefault; + } + + pgParam *GetParam(wxMBConv *_conv = NULL); + +private: + dbgArgInfo(const dbgArgInfo &_arg) + { + wxASSERT(0); + } + + dbgArgInfo &operator= (const dbgArgInfo &) + { + wxASSERT(0); + return *this; + } + + wxString m_name; /* Name of the argument */ + wxString m_type; /* Type of the argument */ + wxString m_baseType; /* Base type of an array type */ + wxString m_defValue; /* Default Value */ + Oid m_typeOid; /* OID of Type */ + short m_mode; /* IN, IN OUT, OUT, or VARAIDIC */ + bool m_hasDefault; /* Has the default value? */ + bool m_useDefault; /* Use the default value? */ + bool m_null; /* Is Value NULL */ + wxString m_val; /* Value */ +}; + +WX_DEFINE_ARRAY_PTR(dbgArgInfo *, pgDbgArgs); + +//////////////////////////////////////////////////////////////////////////////// +// class dbgTargetInfo +// +// This class implements a container that holds information necessary to invoke +// a debugger target (a function or procedure). +// +// When the constructor is called, it sends a query to the server to retreive: +// the OID of the target, +// the name of the target, +// the name of the schema in which the target is defined +// the name of the language in which the target is defined +// the number of arguments expected by the target +// the argument names +// the argument types +// the argument modes (IN, OUT, or INOUT) +// the target type (function or procedure) +// +// This class offers a number of (inline) member functions that you can call +// to extract the above information after it's been queried from the server. +// +class dbgTargetInfo +{ +public: + dbgTargetInfo(Oid _target, pgConn *_conn); + + const wxString &GetQualifiedName() + { + return m_fqName; + } + + const wxString &GetLanguage() + { + return m_language; + } + + const wxString &GetPackageName() + { + return m_package; + } + const wxString &GetSchemaName() + { + return m_schema; + } + + const wxString &GetName() + { + return m_name; + } + + const wxString &GetReturnType() + { + return m_returnType; + } + + long GetOid() + { + return m_oid; + } + + long GetPkgOid() + { + return m_pkgOid; + } + + long GetSchemaOid() + { + return m_schemaOid; + } + + long GetPkgInitOid() + { + return m_pkgInitOid; + } + + bool GetIsFunction() + { + return m_isFunction; + } + + bool GetReturnsSet() + { + return m_returnsSet; + } + + bool RequireUserInput() + { + return ((m_pkgOid != 0 && m_pkgInitOid != 0) || m_inputParamCnt != 0); + } + + bool &DebugPackageConstructor() + { + return m_debugPkgCon; + } + + dbgArgInfo *operator[](int index); + + pgDbgArgs *GetArgs() + { + return m_args; + } + + bool HasVariadic() + { + return m_hasVariadic; + } + + bool AddForExecution(pgQueryThread *_thread); + +private: + wxString m_name; // Target name (function or procedure) + wxString m_schema; // Schema in which target resides + wxString m_package; // Package in which target resides + wxString m_language; // Language in which target is defined + + wxString m_returnType; // Return type + wxString m_funcSignature; // Function Signature + + wxString m_fqName; // Function qualified name + + bool m_isFunction; // true->target is a function, false->target is a procedure + bool m_returnsSet; // Returns a set? + bool m_hasVariadic; // Has the variadic argument + + bool m_debugPkgCon; // Debug Package Constructor + + long m_oid; // Target function/procedure OID + long m_pkgOid; // Package in which target defined (if non-zero) + long m_pkgInitOid; // OID of the package initializer function. + long m_schemaOid; // OID of the schema + + size_t m_inputParamCnt; // IN/IN OUT parameter count + + pgDbgArgs *m_args; // Function arguments +}; + +#endif diff --git a/include/debugger/debugger.h b/include/debugger/debugger.h new file mode 100644 index 0000000..2574908 --- /dev/null +++ b/include/debugger/debugger.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// debugger.h - Debugger factories +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DEBUGGER_H +#define DEBUGGER_H + +// wxWindows headers +#include + +/////////////////////////////////////////////////// +// Debugger factory +/////////////////////////////////////////////////// +class debuggerFactory : public actionFactory +{ +public: + debuggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +/////////////////////////////////////////////////// +// Breakpoint factory +/////////////////////////////////////////////////// +class breakpointFactory : public actionFactory +{ +public: + breakpointFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif + + diff --git a/include/debugger/dlgDirectDbg.h b/include/debugger/dlgDirectDbg.h new file mode 100644 index 0000000..11594b4 --- /dev/null +++ b/include/debugger/dlgDirectDbg.h @@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDirectDbg.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class dlgDirectDbg +// +// This class implements 'direct-debugging'. In direct-debugging, the user +// provides a function signature, procedure signature, or OID on the command +// line (this identifies the debug target). We query the server for the +// names, types, and in/out modes for each target parameter and then prompt +// the user to enter a value for each of the IN (and IN/OUT) parameters. +// +// When the user fills in the parameter values and clicks OK, we set a +// breakpoint at the target and then execute a SELECT statement or an +// EXEC statement that invokes the target (with the parameter values +// provided by the user). +// +// A dlgDirectDbg object is typically a child of the frmDebugger object +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef DLGDIRECTDBG_H +#define DLGDIRECTDBG_H + +#include +#include +#include + +#include "dlg/dlgClasses.h" + +class dbgArgInfo; +class frmDebugger; +class dbgController; + +class ctlGridCellBoolEditor : public wxGridCellBoolEditor +{ +public: + ctlGridCellBoolEditor(dbgArgInfo *_arg = NULL); + void BeginEdit (int _row, int _col, wxGrid *_grid); + wxGridCellEditor *Clone() const; + + dbgArgInfo *GetArg() + { + return m_arg; + } + +private: + dbgArgInfo *m_arg; +}; + +class dlgDirectDbg; + +class dbgArgValueEvaluator : public wxThread +{ +public: + dbgArgValueEvaluator(pgConn *, dlgDirectDbg *); + + void *Entry(); + void CancelEval(); + static void NoticeHandler(void *, const char *); + +private: + pgConn *m_conn; + dlgDirectDbg *m_dlg; + + bool m_cancelled; +}; + + +class dlgDirectDbg : public pgDialog +{ + DECLARE_CLASS(dlgDirectDbg) + +public: + dlgDirectDbg(frmDebugger *_parent, dbgController *_controller, + pgConn *_conn); + + enum + { + COL_NAME = 0, // Column 0 contains the variable name + COL_TYPE, // Type of column + COL_NULL, // Value Set to NULL (yes/no) + COL_EXPR, // Value is an expression (yes/no) + COL_VALUE, // Value (constant ,or an expression) + COL_USE_DEF, // Use the default value + COL_DEF_VAL // Default value for the column + }; + +private: + + void PopulateParamGrid(); + + void OnOk(wxCommandEvent &event); + void OnCancel(wxCommandEvent &event); + void OnClickGridLabel(wxGridEvent &event); + + void ResultArgsUpdated(wxCommandEvent &); + void ResultArgsUpdateError(wxCommandEvent &); + + void SaveSettings(); + void LoadSettings(); + // Function to retrive last cell value if the provieded parameter value is an invalid. + void LoadLastCellSetting(int row_number, int array_row_number, + int index_number, bool isArray); + + wxGrid *GetParamsGrid(); + bool DebugPkgConstructor(); + + dbgController *m_controller; + pgConn *m_conn; + dbgArgValueEvaluator *m_thread; + + friend class dbgArgValueEvaluator; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/debugger/frmDebugger.h b/include/debugger/frmDebugger.h new file mode 100644 index 0000000..666f97a --- /dev/null +++ b/include/debugger/frmDebugger.h @@ -0,0 +1,176 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDebugger.h - debugger +// +////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +// class frmDebugger +// +// frmDebugger manages the user interface for the workstation. This class +// manages the toolbar, menu, status bar, and top-level windows. +// +// This class also defines event handlers for a number of high-level events +// (such as window sizing and layout, and creation of new windows). +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef FRMDEBUGGER_H +#define FRMDEBUGGER_H + +#include +#include + +#include "ctl/ctlProgressStatusBar.h" + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMDEBUGGER_PERSPECTIVE_VER wxT("8189") + +#ifdef __WXMAC__ +#define FRMDEBUGGER_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Toolbar;state=2108144;dir=1;layer=10;row=0;pos=1;prop=100000;bestw=154;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sourcePane;caption=Source pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=stackPane;caption=Stack pane;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=237|dock_size(2,0,0)=237|dock_size(3,0,0)=156|") +#else +#ifdef __WXGTK__ +#define FRMDEBUGGER_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Toolbar;state=2108144;dir=1;layer=10;row=0;pos=1;prop=100000;bestw=205;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sourcePane;caption=Source pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=stackPane;caption=Stack pane;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=237|dock_size(2,0,0)=237|dock_size(3,0,0)=156|") +#else +#define FRMDEBUGGER_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Toolbar;state=2108144;dir=1;layer=10;row=0;pos=1;prop=100000;bestw=154;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sourcePane;caption=Source pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=stackPane;caption=Stack pane;state=2099196;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=2099196;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=237|dock_size(2,0,0)=237|dock_size(3,0,0)=156|") +#endif +#endif + +// Debugger Controller +class dbgController; +class frmMain; +class ctlTabWindow; +class ctlResultGrid; +class ctlVarWindow; +class ctlSQLBox; +class dbgCachedStack; + +class frmDebugger : public pgFrame +{ + DECLARE_CLASS(frmDebugger) + +public: + frmDebugger(frmMain *_parent, dbgController *_controller, + const wxString &_title); + virtual ~frmDebugger(); + + void SetupDebugger(); + + void SetStatusText(const wxString &_status); + + ctlTabWindow *GetTabWindow() + { + return m_tabWindow; + } + ctlStackWindow *GetStackWindow() + { + return m_stackWindow; + } + ctlMessageWindow *GetMessageWindow() + { + return m_tabWindow->GetMessageWindow(); + } + + ctlVarWindow *GetVarWindow(bool create) + { + return m_tabWindow->GetVarWindow(create); + } + ctlVarWindow *GetParamWindow(bool create) + { + return m_tabWindow->GetParamWindow(create); + } + ctlVarWindow *GetPkgVarWindow(bool create) + { + return m_tabWindow->GetPkgVarWindow(create); + } + ctlResultGrid *GetResultWindow() + { + return m_tabWindow->GetResultWindow(); + } + + void DisplaySource(dbgCachedStack &); + + void EnableToolsAndMenus(bool enable = true); + void UnhilightCurrentLine(); + void HighlightLine(int _lineNo); + void ClearBreakpointMarkers(); + void MarkBreakpoint(int lineNo); + void CloseProgressBar(); + void LaunchWaitingDialog(const wxString &msg = wxEmptyString); + +private: + + int GetLineNo(); + bool IsBreakpoint(int _lineNo); + void ClearAllBreakpoints(); + + wxMenuBar *SetupMenuBar( void ); + ctlMenuToolbar *SetupToolBar( void ); + ctlProgressStatusBar *SetupStatusBar( void ); + + enum + { + MARKER_CURRENT = 0x02, // Current line marker + MARKER_CURRENT_BG = 0x04, // Current line marker - background hilight + MARKER_BREAKPOINT = 0x01, // Breakpoint marker + }; + +private: + // Menu bar + wxMenuBar *m_menuBar; + // Frames' toolbar + ctlMenuToolbar *m_toolBar; + // View menu (can be modified by wxCodeWindow) + wxMenu *m_viewMenu; + // Debug menu (can be modified by wxCodeWindow) + wxMenu *m_debugMenu; + + wxAuiManager m_manager; + // Frame's status bar + ctlProgressStatusBar *m_statusBar; + // Main Frame + frmMain *m_parent; + // Debugger Controller + dbgController *m_controller; + + // Stack Window + ctlStackWindow *m_stackWindow; + // Tab Window + ctlTabWindow *m_tabWindow; + // Function Code Viewer + ctlSQLBox *m_codeViewer; + + // Operation Status + wxString m_statusTxt; + + DECLARE_EVENT_TABLE() + + void OnExecute(wxCommandEvent &_ev); + void OnDebugCommand(wxCommandEvent &_ev); + void OnSelectFrame(wxCommandEvent &_ev); + // Toggle break-point on margin click + void OnMarginClick(wxStyledTextEvent &_ev); + void OnPositionStc(wxStyledTextEvent &_ev); + void OnVarChange(wxGridEvent &_ev); + void OnClose(wxCloseEvent &_ev); + void OnExit(wxCommandEvent &_ev); + void OnSize(wxSizeEvent &_ev); + void OnEraseBackground(wxEraseEvent &_ev); + void OnHelp(wxCommandEvent &_ev); + void OnContents(wxCommandEvent &_ev); + + void OnToggleToolBar(wxCommandEvent &_ev); + void OnToggleStackPane(wxCommandEvent &_ev); + void OnToggleOutputPane(wxCommandEvent &_ev); + void OnAuiUpdate(wxAuiManagerEvent &_ev); + void OnDefaultView(wxCommandEvent &_ev); +}; + +#endif diff --git a/include/debugger/module.mk b/include/debugger/module.mk new file mode 100644 index 0000000..b8b421d --- /dev/null +++ b/include/debugger/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/debugger/include/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/debugger/dbgController.h \ + include/debugger/dbgModel.h \ + include/debugger/ctlMessageWindow.h \ + include/debugger/ctlResultGrid.h \ + include/debugger/ctlStackWindow.h \ + include/debugger/ctlTabWindow.h \ + include/debugger/ctlVarWindow.h \ + include/debugger/dbgBreakPoint.h \ + include/debugger/dbgConst.h \ + include/debugger/dbgTargetInfo.h \ + include/debugger/debugger.h \ + include/debugger/dlgDirectDbg.h \ + include/debugger/frmDebugger.h + +EXTRA_DIST += \ + include/debugger/module.mk + + diff --git a/include/dlg/dlgAddFavourite.h b/include/dlg/dlgAddFavourite.h new file mode 100644 index 0000000..3ceb2eb --- /dev/null +++ b/include/dlg/dlgAddFavourite.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAddFavourite.h - Add a favourite +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgAddFavourite_H +#define dlgAddFavourite_H + +#include "dlg/dlgClasses.h" +#include "utils/favourites.h" + +// Class declarations +class dlgAddFavourite : public pgDialog +{ +public: + dlgAddFavourite(wxWindow *parent, queryFavouriteFolder *favourites); + ~dlgAddFavourite(); + int AddFavourite(wxString newtext); + +private: + queryFavouriteFolder *favourites; + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnTreeChange(wxTreeEvent &ev); + void OnNewFolder(wxCommandEvent &ev); + + bool anythingChanged; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgAggregate.h b/include/dlg/dlgAggregate.h new file mode 100644 index 0000000..8bafb41 --- /dev/null +++ b/include/dlg/dlgAggregate.h @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgAggregate.h - Aggregate properties dialog +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLG_AGGREGATEPROP +#define __DLG_AGGREGATEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgAggregate; + +class dlgAggregate : public dlgTypeProperty +{ +public: + dlgAggregate(pgaFactory *factory, frmMain *frame, pgAggregate *agg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +protected: + /* + * Aggregate Privileges: + * - Did not inherit dlgTypeProperty & dlgSecurityProperty as it will + * lead to a lot of problem later + **/ + + ctlSecurityPanel *securityPage; + wxArrayString currentAcl; + wxArrayString groups; + bool securityChanged; + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + +private: + pgSchema *schema; + pgAggregate *aggregate; + ctlSeclabelPanel *seclabelPage; + + virtual wxString GetDisplayName() + { + return GetName() + wxT("(") + GetInputTypesList() + wxT(")"); + }; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChange(wxCommandEvent &event); + void OnChangeType(wxCommandEvent &ev); + void OnChangeTypeBase(wxCommandEvent &ev); + void OnChangeTypeState(wxCommandEvent &ev); + + void OnAddInputType(wxCommandEvent &ev); + void OnRemoveInputType(wxCommandEvent &ev); + void OnSelectInputType(wxListEvent &ev); + + long GetInputTypeOid(int param); + wxString GetInputTypesList(); + wxString GetInputTypesOidList(); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgCast.h b/include/dlg/dlgCast.h new file mode 100644 index 0000000..31ab176 --- /dev/null +++ b/include/dlg/dlgCast.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCast.h - Cast property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_CASTPROP +#define __DLG_CASTPROP + +#include "dlg/dlgProperty.h" + +class pgCast; + +class dlgCast : public dlgTypeProperty +{ +public: + dlgCast(pgaFactory *factory, frmMain *frame, pgCast *ca); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChangeType(wxCommandEvent &ev); + void OnChangeTypeSrc(wxCommandEvent &ev); + void OnChangeTypeTrg(wxCommandEvent &ev); + + pgCast *cast; + wxArrayString functions; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgCheck.h b/include/dlg/dlgCheck.h new file mode 100644 index 0000000..3a4dea3 --- /dev/null +++ b/include/dlg/dlgCheck.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCheck.h - Check property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_CHECKPROP +#define __DLG_CHECKPROP + +#include "dlg/dlgProperty.h" + +class pgCheck; +class pgObject; + +class dlgCheck : public dlgProperty +{ +public: + dlgCheck(pgaFactory *factory, frmMain *frame, pgCheck *node = 0, pgObject *parentNode = 0); + + void CheckChange(); + wxString GetSql(); + wxString GetDefinition(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const + { + return wxT("pg/sql-altertable"); + } + + int Go(bool modal); + +private: + pgCheck *check; + pgObject *object; + + void OnChangeValidate(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgClasses.h b/include/dlg/dlgClasses.h new file mode 100644 index 0000000..c8b44b1 --- /dev/null +++ b/include/dlg/dlgClasses.h @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgClasses.h - Some dialogue base classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGCLASSES_H +#define DLGCLASSES_H + +#include + +WX_DECLARE_LIST(wxWindow, windowList); + +#define btnOK CTRL_BUTTON("wxID_OK") +#define btnCancel CTRL_BUTTON("wxID_CANCEL") + + +class frmMain; +class pgObject; +class pgQueryThread; +class ctlMenuToolbar; + +class pgDialog : public wxDialog +{ +public: + pgDialog() + { + statusBar = 0; + } + void RestorePosition(int defaultX = -1, int defaultY = -1, int defaultW = -1, int defaultH = -1, int minW = -1, int minH = -1); + void SavePosition(); + void LoadResource(wxWindow *parent, const wxChar *name = 0); + +protected: + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &event); + void AddStatusBar(); + + void PostCreation(); + wxString dlgName; + wxStatusBar *statusBar; + + DECLARE_EVENT_TABLE() +}; + + +class menuFactoryList; + +class pgFrame : public wxFrame +{ +public: + pgFrame(wxFrame *parent, const wxString &title, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long flags = wxDEFAULT_FRAME_STYLE) ; + ~pgFrame(); + void RemoveFrame(wxWindow *frame); + void AddFrame(wxWindow *wnd) + { + frames.Append(wnd); + } + void RestorePosition(int defaultX = -1, int defaultY = -1, int defaultW = -1, int defaultH = -1, int minW = 100, int minH = 70); + void SavePosition(); + void OnAction(wxCommandEvent &event); + + void UpdateRecentFiles(bool updatefile = true); + + menuFactoryList *GetMenuFactories() + { + return menuFactories; + } + +protected: + + void OnKeyDown(wxKeyEvent &event); + void OnExit(wxCommandEvent &event); + void OnRecent(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + + virtual void OpenLastFile() {} + virtual bool CheckChanged(bool canVeto) + { + return false; + } + virtual wxString GetHelpPage() const + { + return wxEmptyString; + } + + windowList frames; + menuFactoryList *menuFactories; + wxString dlgName; + wxString lastFilename, lastDir, lastPath; + wxString recentKey; + wxMenu *fileMenu, *editMenu, *viewMenu, *recentFileMenu, *helpMenu; + wxStatusBar *statusBar; + wxMenuBar *menuBar; + ctlMenuToolbar *toolBar; + bool changed; + + DECLARE_EVENT_TABLE() +}; + + +class DialogWithHelp : public pgDialog +{ +public: + DialogWithHelp(frmMain *frame); + +protected: + frmMain *mainForm; + void OnHelp(wxCommandEvent &ev); + +private: + virtual wxString GetHelpPage() const = 0; + DECLARE_EVENT_TABLE() +}; + +class ExecutionDialog : public DialogWithHelp +{ +public: + ExecutionDialog(frmMain *frame, pgObject *_object); + virtual wxString GetSql() = 0; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &event); + + void Abort(); + +protected: + + void EnableOK(const bool enable); + + pgConn *conn; + pgObject *object; + pgQueryThread *thread; + wxTextCtrl *txtMessages; + +private: + bool bIsAborted; + bool bIsExecutionStarted; + bool bIsExecutionCompleted; + + DECLARE_EVENT_TABLE() +}; + + + +class sysProcess; +class wxProcessEvent; +class wxTimer; +class wxTimerEvent; +class ExternProcessDialog : public DialogWithHelp +{ +public: + ExternProcessDialog(frmMain *frame); + ~ExternProcessDialog(); + virtual wxString GetDisplayCmd(int version) = 0; + virtual wxString GetCmd(int step) = 0; + bool Execute(int step = 0, bool finalStep = true); + void Abort(); + +protected: + wxTextCtrl *txtMessages; + sysProcess *process; + bool done, final; + long processID; + wxArrayString environment; + +#if __GNUC__ >= 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +public: +#endif + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &event); +protected: + + void OnEndProcess(wxProcessEvent &event); + void OnPollProcess(wxTimerEvent &event); + void checkStreams(); + + wxTimer *timer; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgCollation.h b/include/dlg/dlgCollation.h new file mode 100644 index 0000000..7981dab --- /dev/null +++ b/include/dlg/dlgCollation.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgCollation.h - Collation property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_COLLATIONPROP +#define __DLG_COLLATIONPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgCollation; + +class dlgCollation : public dlgTypeProperty +{ +public: + dlgCollation(pgaFactory *factory, frmMain *frame, pgCollation *coll, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnSelChangeTyp(wxCommandEvent &ev); + + pgSchema *schema; + pgCollation *collation; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgColumn.h b/include/dlg/dlgColumn.h new file mode 100644 index 0000000..aada503 --- /dev/null +++ b/include/dlg/dlgColumn.h @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgColumn.h - Column property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_COLUMNPROP +#define __DLG_COLUMNPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgColumn; +class pgTable; + +class dlgColumn : public dlgTypeProperty +{ +public: + dlgColumn(pgaFactory *factory, frmMain *frame, pgColumn *column, pgTable *parentNode); + void SetSecurityPage(const pgColumn *node); + void CheckChange(); + void SetChangedCol(pgColumn *changedCol); + void ApplyChangesToObj(pgColumn *changedCol); + void ApplyChangesToDlg(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetDefinition(); + void GetVariableList(wxArrayString &); + void GetSecLabelList(wxArrayString &); + wxString GetPreviousDefinition() + { + return previousDefinition; + } + wxString GetComment() + { + return txtComment->GetValue(); + } + wxString GetStatistics() + { + return CTRL_TEXT("txtAttstattarget")->GetValue(); + } + wxString GetTypeOid(); + + int Go(bool modal); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtable"); + } + +protected: + /* + * Column Level Privileges: + * - Did not inherit dlgTypeProperty & dlgSecurityProperty as, it will + * lead to a lot of problem later + **/ + + ctlSecurityPanel *securityPage; + wxArrayString currentAcl; + wxArrayString groups; + bool securityChanged; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnVarnameSelChange(wxCommandEvent &ev); + void SetupVarEditor(int var); + +private: + pgColumn *column; + pgTable *table; + pgColumn *changedColumn; + wxArrayString varInfo; + bool dirtyVars; + + void OnSelChangeTyp(wxCommandEvent &ev); + + wxString previousDefinition; + wxArrayString sequences; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgConnect.h b/include/dlg/dlgConnect.h new file mode 100644 index 0000000..89c1b0d --- /dev/null +++ b/include/dlg/dlgConnect.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConnect.h - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGCONNECT_H +#define DLGCONNECT_H + +#include "dlg/dlgClasses.h" + +// Class declarations +class dlgConnect : public DialogWithHelp +{ +public: + dlgConnect(frmMain *form, const wxString &description, bool needPwd); + ~dlgConnect(); + wxString GetHelpPage() const; + + + wxString GetPassword(); + bool GetStorePwd(); + int Go(); + +private: + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgConversion.h b/include/dlg/dlgConversion.h new file mode 100644 index 0000000..584d8ed --- /dev/null +++ b/include/dlg/dlgConversion.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgConversion.h - Conversion property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_CONVERSIONPROP +#define __DLG_CONVERSIONPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgConversion; + +class dlgConversion : public dlgProperty +{ +public: + dlgConversion(pgaFactory *factory, frmMain *frame, pgConversion *cc, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgConversion *conversion; + pgSchema *schema; + wxArrayString functions; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgDatabase.h b/include/dlg/dlgDatabase.h new file mode 100644 index 0000000..9773fa8 --- /dev/null +++ b/include/dlg/dlgDatabase.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDatabase.h - Database property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_DATABASEPROP +#define __DLG_DATABASEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgDatabase; + +class dlgDatabase : public dlgDefaultSecurityProperty +{ +public: + dlgDatabase(pgaFactory *factory, frmMain *frame, pgDatabase *db); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + wxString GetSql2(); + bool GetDisconnectFirst(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + +private: + pgDatabase *database; + wxArrayString varInfo; + bool schemaRestrictionOk; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + void OnChangeRestr(wxCommandEvent &ev); + void OnGroupAdd(wxCommandEvent &ev); + void OnGroupRemove(wxCommandEvent &ev); + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnCollateSelChange(wxCommandEvent &ev); + void OnCTypeSelChange(wxCommandEvent &ev); + void OnConnLimitChange(wxCommandEvent &ev); + + void OnVarnameSelChange(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + + void SetupVarEditor(int var); + bool executeDDLSql(const wxString &strSql); + + bool dirtyVars; + + DECLARE_EVENT_TABLE() + + friend class pgDatabaseFactory; +}; + + +#endif diff --git a/include/dlg/dlgDomain.h b/include/dlg/dlgDomain.h new file mode 100644 index 0000000..07f7418 --- /dev/null +++ b/include/dlg/dlgDomain.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgDomain.h - Domain property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_DOMAINPROP +#define __DLG_DOMAINPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgDomain; + +class dlgDomain : public dlgTypeProperty +{ +public: + dlgDomain(pgaFactory *factory, frmMain *frame, pgDomain *dom, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnSelChangeTyp(wxCommandEvent &ev); + void OnChangeValidate(wxCommandEvent &ev); + + void OnAddConstr(wxCommandEvent &ev); + void OnRemoveConstr(wxCommandEvent &ev); + void OnSelChangeConstr(wxListEvent &ev); + + pgSchema *schema; + pgDomain *domain; + ctlSeclabelPanel *seclabelPage; + wxArrayString previousConstraints, constraintsDefinition; + wxTreeItemId constraintsItem; + + void OnChange(wxCommandEvent &event); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgEditGridOptions.h b/include/dlg/dlgEditGridOptions.h new file mode 100644 index 0000000..eb07b2e --- /dev/null +++ b/include/dlg/dlgEditGridOptions.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEditGridOptions.h - Edit grid options +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGEDITGRIDOPTIONS_H +#define __DLGEDITGRIDOPTIONS_H + +// wxWindows headers +#include +#include + +#ifdef __WX_FULLSOURCE +#include "wx/generic/gridsel.h" +#else +#include "ctl/wxgridsel.h" +#endif + +#include + +#include "dlg/dlgClasses.h" +class ctlSQLEditGrid; +class ctlSQLBox; +class pgConn; +class frmEditGrid; +//////////////////////////////////////////////////////////////////////////////// +// Class declaration +//////////////////////////////////////////////////////////////////////////////// + +class dlgEditGridOptions : public pgDialog +{ +public: + + // Construction + dlgEditGridOptions(frmEditGrid *parent, pgConn *conn, const wxString &rel, ctlSQLEditGrid *grid); + ~dlgEditGridOptions(); + +private: + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnFilterChange(wxStyledTextEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClose(wxCloseEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnRemove(wxCommandEvent &ev); + void OnAsc(wxCommandEvent &ev); + void OnDesc(wxCommandEvent &ev); + void OnValidate(wxCommandEvent &ev); + void OnCboColumnsChange(wxCommandEvent &ev); + void OnLstSortColsChange(wxListEvent &ev); + bool Validate(); + frmEditGrid *parent; + pgConn *connection; + wxString relation; + ctlSQLEditGrid *editGrid; + ctlSQLBox *filter; + wxMBConv *conv; + + // Macros + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgEventTrigger.h b/include/dlg/dlgEventTrigger.h new file mode 100644 index 0000000..829150d --- /dev/null +++ b/include/dlg/dlgEventTrigger.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgEventTrigger.h - Event trigger property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EVENTTRIGGERPROP +#define __DLG_EVENTTRIGGERPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgEventTrigger; + +class dlgEventTrigger : public dlgProperty +{ +public: + dlgEventTrigger(pgaFactory *factory, frmMain *frame, pgEventTrigger *evntrig, pgObject *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + bool CanDropCascaded() + { + return true; + } + +private: + pgEventTrigger *eventTrigger; + ctlSeclabelPanel *seclabelPage; + void OnChange(wxCommandEvent &ev); + void OnChangeEnable(wxCommandEvent &ev); + virtual bool IsUpToDate(); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + DECLARE_EVENT_TABLE() +}; + + +#endif \ No newline at end of file diff --git a/include/dlg/dlgExtTable.h b/include/dlg/dlgExtTable.h new file mode 100644 index 0000000..d1f6fac --- /dev/null +++ b/include/dlg/dlgExtTable.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtTable.h - Greenplum External Table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EXTTABLEPROP +#define __DLG_EXTTABLEPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class gpExtTable; +class ctlSQLBox; + +class dlgExtTable : public dlgSecurityProperty +{ +public: + dlgExtTable(pgaFactory *factory, frmMain *frame, gpExtTable *v, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void SetObject(pgObject *obj) + { + extTable = (gpExtTable *)obj; + } + +private: + + virtual bool IsUpToDate(); + + pgSchema *schema; + gpExtTable *extTable; + wxString oldDefinition; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgExtension.h b/include/dlg/dlgExtension.h new file mode 100644 index 0000000..3092cd0 --- /dev/null +++ b/include/dlg/dlgExtension.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgExtension.h - Extension property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_EXTENSIONPROP +#define __DLG_EXTENSIONPROP + +#include "dlg/dlgProperty.h" + +class pgExtension; + +class dlgExtension : public dlgProperty +{ +public: + dlgExtension(pgaFactory *factory, frmMain *frame, pgExtension *ext); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgExtension *extension; + void OnChangeName(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgFindReplace.h b/include/dlg/dlgFindReplace.h new file mode 100644 index 0000000..cd27a82 --- /dev/null +++ b/include/dlg/dlgFindReplace.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFindReplace.h - Search and replace +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgFindReplace_H +#define dlgFindReplace_H + +#include "dlg/dlgClasses.h" +#include "ctl/ctlAuiNotebook.h" + +class ctlSQLBox; + +// Class declarations +class dlgFindReplace : public pgDialog +{ +public: + dlgFindReplace(ctlSQLBox *parent); + ~dlgFindReplace(); + void FocusSearch(); + void FindNext(); + void SetFindString(const wxString &val); + +private: + + void OnClose(wxCloseEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnFind(wxCommandEvent &ev); + void OnReplace(wxCommandEvent &ev); + void OnReplaceAll(wxCommandEvent &ev); + void ResetTabOrder(); + void SaveSettings(); + + ctlSQLBox *sqlbox,*startsqlbox; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgForeignDataWrapper.h b/include/dlg/dlgForeignDataWrapper.h new file mode 100644 index 0000000..34c787c --- /dev/null +++ b/include/dlg/dlgForeignDataWrapper.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignDataWrapper.h - Foreign Data Wrapper property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNDATAWRAPPERPROP +#define __DLG_FOREIGNDATAWRAPPERPROP + +#include "dlg/dlgProperty.h" + +class pgForeignDataWrapper; + +class dlgForeignDataWrapper : public dlgSecurityProperty +{ +public: + dlgForeignDataWrapper(pgaFactory *factory, frmMain *frame, pgForeignDataWrapper *db); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignDataWrapper *fdw; + + void OnChange(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgForeignKey.h b/include/dlg/dlgForeignKey.h new file mode 100644 index 0000000..ebac707 --- /dev/null +++ b/include/dlg/dlgForeignKey.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignKey.h - ForeignKey property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNKEYPROP +#define __DLG_FOREIGNKEYPROP + +#include "dlg/dlgProperty.h" + + +class pgForeignKey; +class pgTable; + +class dlgForeignKey : public dlgCollistProperty +{ +public: + dlgForeignKey(pgaFactory *factory, frmMain *frame, pgForeignKey *node, pgTable *parentNode); + dlgForeignKey(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + void CheckChange(); + wxString GetSql(); + wxString GetDefinition(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const + { + return wxT("pg/sql-altertable"); + } + + int Go(bool modal); + +private: + pgForeignKey *foreignKey; + wxString savedIndexName, savedFKName; + + wxString DefaultIndexName(const wxString &name); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + void OnChangeValidate(wxCommandEvent &ev); + void OnSelChangeCol(wxListEvent &ev); + void OnSelChangeRef(wxCommandEvent &ev); + void OnSelChangeRefCol(wxCommandEvent &ev); + void OnAddRef(wxCommandEvent &ev); + void OnRemoveRef(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgForeignServer.h b/include/dlg/dlgForeignServer.h new file mode 100644 index 0000000..5a82e31 --- /dev/null +++ b/include/dlg/dlgForeignServer.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignServer.h - Foreign Server property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNSERVERPROP +#define __DLG_FOREIGNSERVERPROP + +#include "dlg/dlgProperty.h" + +class pgForeignDataWrapper; +class pgForeignServer; + +class dlgForeignServer : public dlgSecurityProperty +{ +public: + dlgForeignServer(pgaFactory *factory, frmMain *frame, pgForeignServer *node, pgForeignDataWrapper *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignDataWrapper *foreigndatawrapper; + pgForeignServer *foreignserver; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgForeignTable.h b/include/dlg/dlgForeignTable.h new file mode 100644 index 0000000..75494b8 --- /dev/null +++ b/include/dlg/dlgForeignTable.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgForeignTable.h - Foreign Table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FOREIGNTABLEPROP +#define __DLG_FOREIGNTABLEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgForeignTable; + +class dlgForeignTable : public dlgTypeProperty +{ +public: + dlgForeignTable(pgaFactory *factory, frmMain *frame, pgForeignTable *node, pgSchema *schema); + + void CheckChange(); + wxString GetSql(); + wxString GetSqlForTypes(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + bool WannaSplitQueries() + { + return queriesToBeSplitted; + } + + int Go(bool modal); + +private: + pgSchema *schema; + pgForeignTable *foreigntable; + ctlSeclabelPanel *seclabelPage; + + void OnMemberAdd(wxCommandEvent &ev); + void OnMemberChange(wxCommandEvent &ev); + void OnMemberRemove(wxCommandEvent &ev); + void OnMemberSelChange(wxListEvent &ev); + void OnSelChangeTyp(wxCommandEvent &ev); + void OnSelChangeTypOrLen(wxCommandEvent &ev); + void OnChangeMember(wxCommandEvent &ev); + + void OnChange(wxCommandEvent &event); + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + void showDefinition(int panel); + wxString GetFullTypeName(int type); + + wxArrayString memberTypes, memberLengths, memberPrecisions, memberNotNulls; + bool queriesToBeSplitted; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgFunction.h b/include/dlg/dlgFunction.h new file mode 100644 index 0000000..819c594 --- /dev/null +++ b/include/dlg/dlgFunction.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgFunction.h - Function property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_FUNCTIONPROP +#define __DLG_FUNCTIONPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgFunction; + +class dlgFunction : public dlgSecurityProperty +{ +public: + dlgFunction(pgaFactory *factory, frmMain *frame, pgFunction *func, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetObject(pgObject *obj) + { + function = (pgFunction *)obj; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createfunction"); + } + +private: + pgSchema *schema; + pgFunction *function; + ctlSeclabelPanel *seclabelPage; + wxArrayString varInfo; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChangeArgName(wxCommandEvent &ev); + void OnChangeReturn(wxCommandEvent &ev); + void OnChangeSetof(wxCommandEvent &ev); + void OnSelChangeLanguage(wxCommandEvent &ev); + void OnSelChangeArg(wxListEvent &ev); + void OnSelChangeType(wxCommandEvent &ev); + void OnAddArg(wxCommandEvent &ev); + void OnChangeArg(wxCommandEvent &ev); + void OnChangeArgMode(wxCommandEvent &ev); + void OnRemoveArg(wxCommandEvent &ev); + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnVarnameSelChange(wxCommandEvent &ev); + void OnChangeWindow(wxCommandEvent &ev); + void SetupVarEditor(int var); + + wxString GetSelectedDirection(); + wxString GetArgs(const bool withNames = true, const bool inOnly = false); + void ReplaceSizer(wxWindow *w, bool isC, int border); + + virtual bool IsUpToDate(); + + wxArrayString typOids; + wxArrayString types; + wxArrayString argOids; + + int typeColNo; + +protected: + bool isProcedure; + bool isBackendMinVer84; + bool isEdbWrapped; + + DECLARE_EVENT_TABLE() +}; + + +class dlgProcedure : public dlgFunction +{ +public: + dlgProcedure(pgaFactory *factory, frmMain *frame, pgFunction *node, pgSchema *sch); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createprocedure"); + } +}; + + +#endif diff --git a/include/dlg/dlgGroup.h b/include/dlg/dlgGroup.h new file mode 100644 index 0000000..b21bf28 --- /dev/null +++ b/include/dlg/dlgGroup.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgGroup.h - Group property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_GROUPPROP +#define __DLG_GROUPPROP + +#include "dlg/dlgProperty.h" + +class pgGroup; + +class dlgGroup : public dlgProperty +{ +public: + dlgGroup(pgaFactory *factory, frmMain *frame, pgGroup *node = 0); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void CheckChange(); + int Go(bool modal); + +private: + pgGroup *group; + + void OnUserAdd(wxCommandEvent &ev); + void OnUserRemove(wxCommandEvent &ev); + + wxArrayString usersIn; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgHbaConfig.h b/include/dlg/dlgHbaConfig.h new file mode 100644 index 0000000..165dda9 --- /dev/null +++ b/include/dlg/dlgHbaConfig.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgHbaConfig.h - Configure setting +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGHBACONFIG_H +#define __DLGHBACONFIG_H + +#include "dlg/dlgClasses.h" +#include "utils/pgconfig.h" + +// Class declarations +class dlgHbaConfig : public DialogWithHelp +{ +public: + dlgHbaConfig(pgFrame *parent, pgHbaConfigLine *line, pgConn *_conn); + ~dlgHbaConfig(); + wxString GetHelpPage() const; + + int Go(); + +private: + pgHbaConfigLine *line; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnAddDatabase(wxCommandEvent &ev); + void OnAddUser(wxCommandEvent &ev); + void OnAddValue(wxCommandEvent &ev); + + wxString database, user; + + bool databaseAdding, userAdding; + + pgConn *conn; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgIndex.h b/include/dlg/dlgIndex.h new file mode 100644 index 0000000..66f4fa2 --- /dev/null +++ b/include/dlg/dlgIndex.h @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndex.h - Index property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_INDEXPROP +#define __DLG_INDEXPROP + +#include "dlg/dlgProperty.h" + + +class pgIndex; +class pgIndexBase; + +#define btnAddCol CTRL_BUTTON("btnAddCol") +#define btnRemoveCol CTRL_BUTTON("btnRemoveCol") + +class dlgIndexBase : public dlgCollistProperty +{ +public: + dlgIndexBase(pgaFactory *factory, frmMain *frame, const wxString &resName, pgIndexBase *index, pgTable *parentNode); + dlgIndexBase(pgaFactory *factory, frmMain *frame, const wxString &resName, ctlListView *colList); + + void OnSelectComboCol(wxCommandEvent &ev); + void OnSelectListCol(wxListEvent &ev); + void OnSelectCol(); + void CheckChange(); + pgObject *GetObject(); + int Go(bool modal); + +protected: + pgIndexBase *index; + +private: + DECLARE_EVENT_TABLE() +}; + + +class dlgIndex : public dlgIndexBase +{ +public: + dlgIndex(pgaFactory *factory, frmMain *frame, pgIndex *index, pgTable *parentNode); + + int Go(bool modal); + void CheckChange(); + wxString GetColumns(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + +private: +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelectType(wxCommandEvent &ev); + void OnDescChange(wxCommandEvent &ev); + void OnAddCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + + wxString m_previousType; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgIndexConstraint.h b/include/dlg/dlgIndexConstraint.h new file mode 100644 index 0000000..d69e382 --- /dev/null +++ b/include/dlg/dlgIndexConstraint.h @@ -0,0 +1,93 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgIndexConstraint.h - IndexConstraint property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_INDEXCONSTRAINTPROP +#define __DLG_INDEXCONSTRAINTPROP + + +#include "dlg/dlgIndex.h" + + +class pgTable; +class pgIndexBase; +class pgPrimaryKey; +class pgUnique; +class pgExclude; + +class dlgIndexConstraint : public dlgIndexBase +{ +protected: + dlgIndexConstraint(pgaFactory *factory, frmMain *frame, const wxString &resName, pgIndexBase *index, pgTable *parentNode); + dlgIndexConstraint(pgaFactory *factory, frmMain *frame, const wxString &resName, ctlListView *colList); + +public: + ctlListView *columns; + + + int Go(bool modal); + void CheckChange(); + wxString GetDefinition(); + wxString GetColumns(); + wxString GetSql(); + wxString GetHelpPage() const + { + return wxT("pg/sql-altertable"); + } + +private: +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnAddCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + void OnSelectType(wxCommandEvent &ev); + void OnSelectComboCol(wxCommandEvent &ev); + void OnChangeIndex(wxCommandEvent &ev); + + wxString m_previousType; + + DECLARE_EVENT_TABLE() +}; + + +class dlgPrimaryKey : public dlgIndexConstraint +{ +public: + dlgPrimaryKey(pgaFactory *factory, frmMain *frame, pgPrimaryKey *index, pgTable *parentNode); + dlgPrimaryKey(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + pgObject *CreateObject(pgCollection *collection); +}; + + +class dlgUnique : public dlgIndexConstraint +{ +public: + dlgUnique(pgaFactory *factory, frmMain *frame, pgUnique *index, pgTable *parentNode); + dlgUnique(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + pgObject *CreateObject(pgCollection *collection); +}; + + +class dlgExclude : public dlgIndexConstraint +{ +public: + dlgExclude(pgaFactory *factory, frmMain *frame, pgExclude *index, pgTable *parentNode); + dlgExclude(pgaFactory *factory, frmMain *frame, ctlListView *colList); + + pgObject *CreateObject(pgCollection *collection); +}; + + +#endif diff --git a/include/dlg/dlgLanguage.h b/include/dlg/dlgLanguage.h new file mode 100644 index 0000000..11b71a4 --- /dev/null +++ b/include/dlg/dlgLanguage.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgLanguage.h - Language properties dialog +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLG_LANGUAGEPROP +#define __DLG_LANGUAGEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgLanguage; + +class dlgLanguage : public dlgSecurityProperty +{ +public: + dlgLanguage(pgaFactory *factory, frmMain *frame, pgLanguage *node, pgObject *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgLanguage *language; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + void OnChangeName(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgMainConfig.h b/include/dlg/dlgMainConfig.h new file mode 100644 index 0000000..565f76d --- /dev/null +++ b/include/dlg/dlgMainConfig.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMainConfig.h - Configure setting +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGMAINCONFIG_H +#define __DLGMAINCONFIG_H + +#include "dlg/dlgClasses.h" +#include "utils/pgconfig.h" + +// Class declarations +class dlgMainConfig : public DialogWithHelp +{ +public: + dlgMainConfig(pgFrame *parent, pgSettingItem *item); + ~dlgMainConfig(); + wxString GetHelpPage() const; + + int Go(); + +private: + pgSettingItem *item; + wxString GetValue(); + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgManageFavourites.h b/include/dlg/dlgManageFavourites.h new file mode 100644 index 0000000..3c11a6d --- /dev/null +++ b/include/dlg/dlgManageFavourites.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageFavourites.h - Manage favourites +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgManageFavourites_H +#define dlgManageFavourites_H + +#include "dlg/dlgClasses.h" +#include "utils/favourites.h" + +// Class declarations +class dlgManageFavourites : public pgDialog +{ +public: + dlgManageFavourites(wxWindow *parent, queryFavouriteFolder *favourites); + ~dlgManageFavourites(); + int ManageFavourites(); // returns: 0=no changes, 1=changes to save, -1=changes to rollback + +private: + queryFavouriteFolder *favourites; + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnTreeChange(wxTreeEvent &ev); + void OnRename(wxCommandEvent &ev); + void OnDelete(wxCommandEvent &ev); + void OnNewFolder(wxCommandEvent &ev); + + bool anythingChanged; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgManageMacros.h b/include/dlg/dlgManageMacros.h new file mode 100644 index 0000000..98a4dd9 --- /dev/null +++ b/include/dlg/dlgManageMacros.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgManageMacros.h - Manage macros +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgManageMacros_H +#define dlgManageMacros_H + +#include "dlg/dlgClasses.h" +#include "utils/macros.h" + +class dlgManageMacros : public DialogWithHelp +{ +public: + dlgManageMacros(wxWindow *parent, frmMain *form, queryMacroList *macros); + ~dlgManageMacros(); + int ManageMacros(); // returns: 0=no changes, 1=changes to save, -1=changes to rollback + + +private: + queryMacroList *macros; + wxString GetHelpPage() const; + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnClear(wxCommandEvent &ev); + void OnSave (wxCommandEvent &ev); + void OnKeySelect(wxListEvent &ev); + void OnNameChange(wxCommandEvent &ev); + void OnQueryChange(wxStyledTextEvent &ev); + + // Helper methods + void AddKeyToList(int position, const wxString &key); + void DeleteMacro(int listItem); + void SetMacro(bool silent); + + bool anythingChanged; + bool thisMacroChanged; + + DECLARE_EVENT_TABLE() +}; + +#endif /*dlgManageMacros_H*/ + diff --git a/include/dlg/dlgMoveTablespace.h b/include/dlg/dlgMoveTablespace.h new file mode 100644 index 0000000..5354af6 --- /dev/null +++ b/include/dlg/dlgMoveTablespace.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgMoveTablespace.h - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgMoveTablespace_H +#define dlgMoveTablespace_H + +// wxWindows headers +#include +#include + + +#include "dlg/dlgClasses.h" +class pgConn; +class pgTablespace; + +// Class declarations +class dlgMoveTablespace : public pgDialog +{ +public: + dlgMoveTablespace(frmMain *win, pgConn *conn, pgTablespace *tblspc); + ~dlgMoveTablespace(); + wxString GetTablespace(); + wxArrayString GetKind(); + wxString GetOwner(); +private: + pgConn *connection; + frmMain *parent; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgOperator.h b/include/dlg/dlgOperator.h new file mode 100644 index 0000000..edf86c5 --- /dev/null +++ b/include/dlg/dlgOperator.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgOperator.h - Operator property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_OPERATORPROP +#define __DLG_OPERATORPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgOperator; + +class dlgOperator : public dlgTypeProperty +{ +public: + dlgOperator(pgaFactory *factory, frmMain *frame, pgOperator *op, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void CheckChangeType(); + void OnChangeTypeLeft(wxCommandEvent &ev); + void OnChangeTypeRight(wxCommandEvent &ev); + void OnChangeJoin(wxCommandEvent &ev); + + void AppendFilledOperator(wxString &sql, const wxChar *txt, ctlComboBoxFix *cb); + + pgSchema *schema; + pgOperator *oper; + wxArrayString procedures; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgPackage.h b/include/dlg/dlgPackage.h new file mode 100644 index 0000000..a0fea18 --- /dev/null +++ b/include/dlg/dlgPackage.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPackage.h - EnterpriseDB Package property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_PACKAGEPROP +#define __DLG_PACKAGEPROP + +#include "dlg/dlgProperty.h" + +class edbPackage; + +class dlgPackage : public dlgSecurityProperty +{ +public: + dlgPackage(pgaFactory *f, frmMain *frame, edbPackage *node, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetObject(pgObject *obj) + { + package = (edbPackage *)obj; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/packages-create"); + } + +private: + edbPackage *package; + pgSchema *schema; + + virtual bool IsUpToDate(); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgPgpassConfig.h b/include/dlg/dlgPgpassConfig.h new file mode 100644 index 0000000..112de95 --- /dev/null +++ b/include/dlg/dlgPgpassConfig.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgPgpassConfig.h - Configure setting +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLGPGPASSCONFIG_H +#define __DLGPGPASSCONFIG_H + +#include "dlg/dlgClasses.h" +#include "utils/pgconfig.h" + +// Class declarations +class dlgPgpassConfig : public DialogWithHelp +{ +public: + dlgPgpassConfig(pgFrame *parent, pgPassConfigLine *line); + ~dlgPgpassConfig(); + wxString GetHelpPage() const; + + int Go(); + +private: + pgPassConfigLine *line; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + + wxString database, user; + + bool databaseAdding, userAdding; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgProperty.h b/include/dlg/dlgProperty.h new file mode 100644 index 0000000..12504c4 --- /dev/null +++ b/include/dlg/dlgProperty.h @@ -0,0 +1,383 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgProperty.h - common property dialog class +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_PROP +#define __DLG_PROP + + +#include +#include +#include "schema/pgObject.h" +#include "db/pgConn.h" +#include "ctl/ctlSecurityPanel.h" + +class pgSchema; +class pgTable; +class frmMain; +class pgaFactory; + +#define stComment CTRL_STATIC("stComment") +#define lstColumns CTRL_LISTVIEW("lstColumns") +#define cbColumns CTRL_COMBOBOX("cbColumns") + +class dataType +{ +public: + void SetTypename(wxString name); + wxString GetTypename(); + + void SetOid(OID id); + OID GetOid(); + +private: + wxString typeName; + OID oid; + +}; + + +/* + * We need the definition of replClientData in dlgDatabase too, to hack + * the execution of default privileges statements (sqls) before getting + * disconnected. + */ +class replClientData : public wxClientData +{ +public: + replClientData(const wxString &c, long s, long ma, long mi) + { + cluster = c; + setId = s; + majorVer = ma; + minorVer = mi; + } + wxString cluster; + long setId; + long majorVer; + long minorVer; +}; + + +WX_DEFINE_ARRAY(dataType *, dataTypeCache); + +class dlgProperty : public DialogWithHelp +{ +public: + static bool CreateObjectDialog(frmMain *frame, pgObject *node, pgaFactory *factory = 0); + static bool EditObjectDialog(frmMain *frame, ctlSQLBox *sqlbox, pgObject *node); + void InitDialog(frmMain *frame, pgObject *node); + + wxString GetName(); + virtual wxString GetDisplayName() + { + return GetName(); + }; + + virtual wxString GetSql() = 0; + virtual wxString GetSql2() + { + return wxEmptyString; + }; + virtual bool GetDisconnectFirst() + { + return false; + }; + virtual pgObject *CreateObject(pgCollection *collection) = 0; + virtual pgObject *GetObject() = 0; + virtual void SetObject(pgObject *obj) {} // only necessary if apply is implemented + + virtual void CreateAdditionalPages(); + virtual wxString GetHelpPage() const; + virtual wxString GetHelpPage(bool forCreate) const + { + return wxEmptyString; + } + virtual void SetConnection(pgConn *conn) + { + connection = conn; + } + void SetDatabase(pgDatabase *db); + void SetDatatypeCache(dataTypeCache cache); + virtual int Go(bool modal = false); + virtual void CheckChange() = 0; + + virtual bool WannaSplitQueries() + { + return false; + } + +protected: + dlgProperty(pgaFactory *factory, frmMain *frame, const wxString &resName); + ~dlgProperty(); + + void EnableOK(bool enable); + void SetSqlReadOnly(bool readonly); + virtual bool IsUpToDate() + { + return true; + }; + void ShowObject(); + + void FillSQLTextfield(); + + void CheckValid(bool &enable, const bool condition, const wxString &msg); + static dlgProperty *CreateDlg(frmMain *frame, pgObject *node, bool asNew, pgaFactory *factory = 0); + void AppendNameChange(wxString &sql, const wxString &objname = wxEmptyString); + void AppendOwnerChange(wxString &sql, const wxString &objName = wxEmptyString); + void AppendOwnerNew(wxString &sql, const wxString &objname); + void AppendSchemaChange(wxString &sql, const wxString &objname = wxEmptyString); + void AppendComment(wxString &sql, const wxString &objType, pgSchema *schema, pgObject *obj); + void AppendComment(wxString &sql, const wxString &objName, pgObject *obj); + void AppendQuoted(wxString &sql, const wxString &name); + void AppendQuotedType(wxString &sql, const wxString &name); + wxString qtDbString(const wxString &str); + +#if __GNUC__ >= 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) + // ANSI spec 11.5 is quite brain dead about pointers of protected members: In order to access + // them using the base class name, they can't be protected. + // apparently, only gcc 3.4 knows that; other compilers take protected as protected. +public: + +#endif + + void OnPageSelect(wxNotebookEvent &event); + void OnOK(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnChangeOwner(wxCommandEvent &ev); + void OnChangeStc(wxStyledTextEvent &event); + void OnChangeReadOnly(wxCommandEvent &event); + +protected: + void AddDatabases(ctlComboBoxFix *cb = 0); + void AddGroups(ctlComboBoxFix *comboBox = 0); + void AddUsers(ctlComboBoxFix *cb1, ctlComboBoxFix *cb2 = 0); + void AddSchemas(ctlComboBoxFix *comboBox = 0); + void FillCombobox(const wxString &query, ctlComboBoxFix *cb1, ctlComboBoxFix *cb2 = 0); + void PrepareTablespace(ctlComboBoxFix *cb, const OID current = 0); + void OnHelp(wxCommandEvent &ev); + + pgConn *connection; + pgDatabase *database; + pgObject *obj; + + frmMain *mainForm; + wxPanel *sqlPane; + + wxTextValidator numericValidator; + + wxNotebook *nbNotebook; + wxTextCtrl *txtName, *txtOid, *txtComment; + ctlComboBox *cbOwner; + ctlComboBox *cbSchema; + wxComboBox *cbClusterSet; + wxCheckBox *chkReadOnly; + ctlSQLBox *sqlTextField1; + ctlSQLBox *sqlTextField2; + bool enableSQL2; + + int width, height; + wxTreeItemId item, owneritem; + bool readOnly; + bool processing; + pgaFactory *factory; + dataTypeCache dtCache; + +private: + bool tryUpdate(wxTreeItemId collectionItem); + bool apply(const wxString &sql, const wxString &sql2); + wxString BuildSql(const wxString &sql); + wxArrayString SplitQueries(const wxString &sql); + + DECLARE_EVENT_TABLE() +}; + + +#define cbDatatype CTRL_COMBOBOX2("cbDatatype") + + +class dlgTypeProperty : public dlgProperty +{ +public: + wxString GetQuotedTypename(int sel); + wxString GetTypeOid(int sel); + wxString GetTypeInfo(int sel); + void AddType(const wxString &typ, const OID oid, const wxString quotedName = wxEmptyString); + + + int Go(bool modal); + +protected: + dlgTypeProperty(pgaFactory *factory, frmMain *frame, const wxString &resName); + void CheckLenEnable(); + void FillDatatype(ctlComboBox *cb, bool withDomains = true, bool addSerials = false); + void FillDatatype(ctlComboBox *cb, ctlComboBox *cb2, bool withDomains = true, bool addSerials = false); + + bool isVarLen, isVarPrec; + long minVarLen, maxVarLen; + wxTextCtrl *txtLength, *txtPrecision; + +private: + wxArrayString types; +}; + + +class dlgCollistProperty : public dlgProperty +{ +public: + int Go(bool modal); + +protected: + dlgCollistProperty(pgaFactory *factory, frmMain *frame, const wxString &resName, pgTable *table); + dlgCollistProperty(pgaFactory *factory, frmMain *frame, const wxString &resName, ctlListView *colList); + + ctlListView *columns; + pgTable *table; +}; + + +class dlgSecurityProperty : public dlgProperty +{ +protected: + dlgSecurityProperty(pgaFactory *factory, frmMain *frame, pgObject *obj, const wxString &resName, const wxString &privilegeList, const char *privilegeChar); + ~dlgSecurityProperty(); + void AddGroups(ctlComboBox *comboBox = 0); + void AddUsers(ctlComboBox *comboBox = 0); + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + void EnableOK(bool enable, bool ignoreSql = false); + virtual wxString GetHelpPage() const; + virtual int Go(bool modal = false); + bool DisablePrivilege(const wxString &priv); + void SetPrivilegesLayout(); + void AppendCurrentAcl(const wxString &name, const wxString &value); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + ctlSecurityPanel *securityPage; + +private: + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + bool securityChanged; + + wxArrayString currentAcl; + + DECLARE_EVENT_TABLE() +}; + +class ctlDefaultSecurityPanel; + +class dlgDefaultSecurityProperty : public dlgSecurityProperty +{ + +protected: + dlgDefaultSecurityProperty(pgaFactory *factory, frmMain *frame, pgObject *obj, const wxString &resName, + const wxString &privilegeList, const char *privilegeChar, bool createDefPrivPanel = true); + + virtual int Go(bool modal = false, bool createDefPrivs = false, + const wxString &defPrivsOnTables = wxT(""), + const wxString &defPrivsOnSeqs = wxT(""), + const wxString &defPrivsOnFuncs = wxT(""), + const wxString &defPrivsOnTypes = wxT("")); + + virtual wxString GetHelpPage() const; + + void EnableOK(bool enable, bool ignoreSql = false); + wxString GetDefaultPrivileges(const wxString &schemaName = wxT("")); + void AddGroups(ctlComboBox *comboBox = 0); + void AddUsers(ctlComboBox *comboBox = 0); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + bool defaultSecurityChanged; + +private: + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + + ctlDefaultSecurityPanel *defaultSecurityPage; + + DECLARE_EVENT_TABLE() +}; + + + +class dlgAgentProperty : public dlgProperty +{ +public: + +protected: + dlgAgentProperty(pgaFactory *factory, frmMain *frame, const wxString &resName); + void OnOK(wxCommandEvent &ev); + bool executeSql(); + virtual wxString GetInsertSql() = 0; + virtual wxString GetUpdateSql() = 0; + wxString GetSql(); + long GetRecId() + { + return recId; + } + + DECLARE_EVENT_TABLE() + + long recId; +}; + + +class propertyFactory : public contextActionFactory +{ +public: + propertyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class createFactory : public actionFactory +{ +public: + createFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class dropFactory : public contextActionFactory +{ +public: + dropFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class dropCascadedFactory : public contextActionFactory +{ +public: + dropCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class refreshFactory : public contextActionFactory +{ +public: + refreshFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/dlg/dlgReassignDropOwned.h b/include/dlg/dlgReassignDropOwned.h new file mode 100644 index 0000000..ed5eb11 --- /dev/null +++ b/include/dlg/dlgReassignDropOwned.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgReassignDropOwned.h - Reassign or drop owned objects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef dlgReassignDropOwned_H +#define dlgReassignDropOwned_H + +// wxWindows headers +#include +#include + + +#include "dlg/dlgClasses.h" +class pgConn; +class pgRole; + +// Class declarations +class dlgReassignDropOwned : public pgDialog +{ +public: + dlgReassignDropOwned(frmMain *win, pgConn *conn, pgRole *role, wxString dbrestriction); + ~dlgReassignDropOwned(); + wxString GetDatabase(); + wxString GetRole(); + bool IsReassign(); + +private: + pgConn *connection; + frmMain *parent; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgResourceGroup.h b/include/dlg/dlgResourceGroup.h new file mode 100644 index 0000000..6608c44 --- /dev/null +++ b/include/dlg/dlgResourceGroup.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgResourceGroup.h - Resource Group property +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DLG_RESOURCEGROUPPROP +#define __DLG_RESOURCEGROUPPROP + +#include "dlg/dlgProperty.h" + +class edbResourceGroup; + +class dlgResourceGroup : public dlgProperty +{ +public: + dlgResourceGroup(pgaFactory *factory, frmMain *frame, edbResourceGroup *node = 0); + wxString GetSql(); + wxString GetSql2(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void CheckChange(); + int Go(bool modal); + +private: + void OnChange(wxCommandEvent &event); + void OnOK(wxCommandEvent &ev); + +private: + edbResourceGroup *resourceGroup; + wxString m_cpuRate; + wxString m_dirtyRate; + bool m_isNameChange; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgRole.h b/include/dlg/dlgRole.h new file mode 100644 index 0000000..a6a65e9 --- /dev/null +++ b/include/dlg/dlgRole.h @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRole.h - Role property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_ROLEPROP +#define __DLG_ROLEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/calbox.h" +#include "ctl/timespin.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgRole; + +class dlgRole : public dlgProperty +{ +public: + dlgRole(pgaFactory *factory, frmMain *frame, pgRole *node = 0, bool chkLogin = false); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + int Go(bool modal); + +private: + pgRole *role; + wxArrayString varInfo; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + + void OnOK(wxCommandEvent &ev); + void OnChangeSuperuser(wxCommandEvent &ev); + void OnChangeSpin(wxSpinEvent &ev); + void OnChangeCal(wxCalendarEvent &ev); + void OnChangeDate(wxDateEvent &ev); + void OnRoleAdd(wxCommandEvent &ev); + void OnRoleRemove(wxCommandEvent &ev); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + + void OnVarnameSelChange(wxCommandEvent &ev); + void OnChangePasswd(wxCommandEvent &ev); + + void SetupVarEditor(int var); + + wxArrayString groupsIn; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgRule.h b/include/dlg/dlgRule.h new file mode 100644 index 0000000..8d42e3e --- /dev/null +++ b/include/dlg/dlgRule.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRule.h - Rule property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_RULEPROP +#define __DLG_RULEPROP + +#include "dlg/dlgProperty.h" + +class pgTable; +class pgRule; +class ctlSQLBox; + +class dlgRule : public dlgProperty +{ +public: + dlgRule(pgaFactory *factory, frmMain *frame, pgRule *r, pgTable *tab); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgTable *table; + pgRule *rule; + wxString oldDefinition; + + bool didChange(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgSchema.h b/include/dlg/dlgSchema.h new file mode 100644 index 0000000..a0c10fc --- /dev/null +++ b/include/dlg/dlgSchema.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSchema.h - Schemaproperty +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SCHEMAPROP +#define __DLG_SCHEMAPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; + +class dlgSchema : public dlgDefaultSecurityProperty +{ +public: + dlgSchema(pgaFactory *factory, frmMain *frame, pgSchema *node, pgObject *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgSchema *schema; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgSearchObject.h b/include/dlg/dlgSearchObject.h new file mode 100644 index 0000000..5aea40a --- /dev/null +++ b/include/dlg/dlgSearchObject.h @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSearchObject.h - Search dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGSEARCHOBJECT_H +#define DLGSEARCHOBJECT_H + +#include "dlg/dlgClasses.h" +#include "ctl/ctlListView.h" +#include "schema/pgDatabase.h" +#include "utils/sysSettings.h" +#include "schema/pgSchema.h" + +// Class declarations +class dlgSearchObject : public pgDialog +{ +public: + dlgSearchObject(frmMain *p, pgDatabase *db, pgObject *obj); + ~dlgSearchObject(); + +private: + void OnHelp(wxCommandEvent &ev); + void OnSearch(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnSelSearchResult(wxListEvent &ev); + void SaveSettings(); + void RestoreSettings(); + wxString TranslatePath(wxString &path); + wxString getMapKeyByValue(wxString); + void ToggleBtnSearch(bool enable); + WX_DECLARE_STRING_HASH_MAP(wxString, LngMapping); + LngMapping aMap; + + pgDatabase *currentdb; + frmMain *parent; + wxString header; + wxArrayString sectionName, sectionData, sectionTableHeader, sectionTableRows, sectionTableInfo, sectionSql; + wxString currentSchema; + int cbSchemaIdxCurrent; + + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////////// +// Search Object Factory base class +/////////////////////////////////////////////////////// +class searchObjectBaseFactory : public actionFactory +{ +private: + searchObjectBaseFactory(menuFactoryList *list) : actionFactory(list) {} + frmMain *GetFrmMain() + { + return parent; + }; + + frmMain *parent; +public: + bool CheckEnable(pgObject *obj) + { + return false; + }; +}; + + +class searchObjectFactory : public contextActionFactory +{ +public: + searchObjectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + +}; + +#endif diff --git a/include/dlg/dlgSelectConnection.h b/include/dlg/dlgSelectConnection.h new file mode 100644 index 0000000..3077ade --- /dev/null +++ b/include/dlg/dlgSelectConnection.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectConnection.h - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGSELECTCONNECTION_H +#define DLGSELECTCONNECTION_H + +#include +#include "dlg/dlgClasses.h" + +class pgServer; +// Class declarations +class dlgSelectConnection : public DialogWithHelp +{ +public: + dlgSelectConnection(wxWindow *parent, frmMain *form); + ~dlgSelectConnection(); + wxString GetHelpPage() const; + pgServer *GetServer() + { + return remoteServer; + } + pgConn *CreateConn(wxString &applicationame, bool &createdNew); + pgConn *CreateConn(wxString &server, wxString &dbname, wxString &username, int port, wxString &rolename, int sslmode, wxString &applicationame, bool writeMRU = false); + wxString GetServerName(); + wxString GetDatabase(); + + int Go(pgConn *conn, wxBitmapComboBox *cb); + +private: + void OnChangeServer(wxCommandEvent &ev); + void OnChangeDatabase(wxCommandEvent &ev); + void OnTextChange(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + + pgServer *remoteServer; + wxBitmapComboBox *cbConnection; + ctlComboBoxFix *cbServer; + wxComboBox *cbDatabase, *cbUsername, *cbRolename; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgSelectDatabase.h b/include/dlg/dlgSelectDatabase.h new file mode 100644 index 0000000..a5dddca --- /dev/null +++ b/include/dlg/dlgSelectDatabase.h @@ -0,0 +1,66 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSelectDatabase.h - Connect to a database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef DLGSELECTDATABASE_H +#define DLGSELECTDATABASE_H + +#include +#include +#include + + +class pgServer; + + +class dlgSelDBNode : public wxTreeItemData +{ + +public: + dlgSelDBNode(pgServer *server, const wxString &dbname = wxEmptyString); + dlgSelDBNode *createChild(const wxString &dbName); + + wxString getDatabase() + { + return dbname; + } + wxString getConnectionString(); + +private: + pgServer *server; // Do not remove it, not owned by this + wxString dbname; + + friend class dlgSelectDatabase; + +}; + + +class dlgSelectDatabase: public wxDialog +{ + +public: + dlgSelectDatabase(wxWindow *parent, int id, const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize, long style = wxCLOSE_BOX); + + wxString getConnInfo(); + static bool getValidConnectionString(wxString connStr, wxString &resultStr); + +protected: + void Initialize(); + void OnSelect(wxTreeEvent &ev); + void OnSelActivate(wxTreeEvent &ev); + + wxTreeCtrl *tcServers; + dlgSelDBNode *selectedConn; + + DECLARE_EVENT_TABLE() +}; + +#endif + diff --git a/include/dlg/dlgSequence.h b/include/dlg/dlgSequence.h new file mode 100644 index 0000000..1d58e4f --- /dev/null +++ b/include/dlg/dlgSequence.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSequence.h - Sequence property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SEQUENCEPROP +#define __DLG_SEQUENCEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgSequence; + +class dlgSequence : public dlgSecurityProperty +{ +public: + dlgSequence(pgaFactory *factory, frmMain *frame, pgSequence *seq, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + bool doesOverflowBigInt(const wxString &str, bool emptyAllowed); + + pgSchema *schema; + pgSequence *sequence; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgServer.h b/include/dlg/dlgServer.h new file mode 100644 index 0000000..49acaf7 --- /dev/null +++ b/include/dlg/dlgServer.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgServer.h - Server property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SERVERPROP +#define __DLG_SERVERPROP + +#include "dlg/dlgProperty.h" +#include +#include + +class pgServer; + +class dlgServer : public dlgProperty +{ +public: + dlgServer(pgaFactory *factory, frmMain *frame, pgServer *s); + ~dlgServer(); + int Go(bool modal); + int GoNew(); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + wxString GetPassword(); + bool GetTryConnect(); + +private: + pgServer *server; + bool dbRestrictionOk; + + void OnOK(wxCommandEvent &ev); + void OnChangeRestr(wxCommandEvent &ev); + void OnChangeTryConnect(wxCommandEvent &ev); + void OnPageSelect(wxNotebookEvent &event); + void OnChangeColour(wxColourPickerEvent &ev); + void OnChangeFile(wxFileDirPickerEvent &ev); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + void OnCheckSSHTunnel(wxCommandEvent &ev); + void OnChangeAuthOption(wxCommandEvent &ev); + void EnableSSHTunnelControls(const bool &bEnable); + void EnableAuthenticationOptions(); +#endif + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgSynonym.h b/include/dlg/dlgSynonym.h new file mode 100644 index 0000000..6bc2d1c --- /dev/null +++ b/include/dlg/dlgSynonym.h @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgSynonym.h - EnterpriseDB Synonym property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_SYNONYMPROP +#define __DLG_SYNONYMPROP + +#include "dlg/dlgProperty.h" + +class edbSynonym; +class edbPrivateSynonymFactory; +class edbPrivateSynonym; +class pgSchema; + +class dlgSynonym : public dlgProperty +{ +public: + dlgSynonym(pgaFactory *factory, frmMain *frame, edbSynonym *sy); + dlgSynonym(edbPrivateSynonymFactory *factory, frmMain *frame, edbPrivateSynonym *syn, pgSchema *schema); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createpubsynonym"); + } + +private: + void OnChangeTargetType(wxCommandEvent &ev) + { + ProcessTypeChange(); + }; + void OnChangeTargetSchema(wxCommandEvent &ev) + { + ProcessSchemaChange(); + }; + void ProcessTypeChange(); + void ProcessSchemaChange(); + + edbSynonym *synonym; + edbPrivateSynonym *privSynonym; + pgSchema *synonymSchema; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTable.h b/include/dlg/dlgTable.h new file mode 100644 index 0000000..1b82fe0 --- /dev/null +++ b/include/dlg/dlgTable.h @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTable.h - Table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TABLEPROP +#define __DLG_TABLEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +enum +{ + COL_NAME = 0, + COL_DEFINITION, + COL_INHERIT, + COL_SQLCHANGE, + COL_COMMENTS, + COL_STATISTICS, + COL_PGCOLUMN, + COL_TYPEOID, + COL_CHANGEDCOL, + COL_VARIABLE_LIST, + COL_SECLABEL_LIST +}; + +enum +{ + TAB_PROPERTIES = 0, + TAB_DEFINITION, + TAB_INHERITS, + TAB_LIKE, + TAB_COLUMNS, + TAB_CONSTRAINTS, + TAB_AUTOVACUUM, + TAB_PRIVILEGES, + TAB_SECLABEL, + TAB_SQL +}; + +class pgSchema; +class pgTable; +class pgColumn; + +class dlgTable : public dlgSecurityProperty +{ +public: + dlgTable(pgaFactory *factory, frmMain *frame, pgTable *db, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + bool Destroy(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + ~dlgTable(); + +private: + pgSchema *schema; + pgTable *table; + ctlSeclabelPanel *seclabelPage; + dataTypeCache dtCache; + + void OnChange(wxCommandEvent &event); + + void OnOK(wxCommandEvent &ev); + void OnChangeTable(wxCommandEvent &ev); +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnChangeOfType(wxCommandEvent &ev); + + void OnAddTable(wxCommandEvent &ev); + void OnRemoveTable(wxCommandEvent &ev); + void OnSelChangeTable(wxCommandEvent &ev); + + void OnAddCol(wxCommandEvent &ev); + void OnChangeCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + void OnSelChangeCol(wxListEvent &ev); + + void OnAddConstr(wxCommandEvent &ev); + void OnRemoveConstr(wxCommandEvent &ev); + void OnSelChangeConstr(wxListEvent &ev); + + void OnChangeVacuum(wxCommandEvent &ev); + + void FillConstraint(); + void FillAutoVacuumParameters(wxString &setString, wxString &resetStr, + const wxString ¶meter, const wxString &val); + void PopulateDatatypeCache(); + wxString GetItemConstraintType(ctlListView *list, long pos); + bool hasPK; + + wxArrayString previousColumns, previousConstraints, previousTables, constraintsDefinition; + wxArrayString tableOids, inheritedTableOids; + wxTreeItemId columnsItem, constraintsItem; + + wxString GetNumString(wxTextCtrl *ctl, bool enabled, const wxString &val); + wxString AppendNum(bool &changed, wxTextCtrl *ctl, wxString val); + + bool tableVacEnabled, hasVacuum, settingAutoVacuum; + wxString settingVacBaseThr, settingAnlBaseThr, settingCostDelay, + settingCostLimit, settingFreezeMinAge, settingFreezeMaxAge, + settingFreezeTableAge; + wxString tableVacBaseThr, tableAnlBaseThr, tableCostDelay, + tableCostLimit, tableFreezeMinAge, tableFreezeMaxAge, + tableFreezeTableAge; + wxString settingVacFactor, settingAnlFactor; + wxString tableVacFactor, tableAnlFactor; + + /* Toast Table */ + bool toastTableVacEnabled, toastTableHasVacuum; + wxString toastTableVacBaseThr, + toastTableCostDelay, toastTableCostLimit, + toastTableFreezeMinAge, toastTableFreezeMaxAge, + toastTableFreezeTableAge; + wxString toastTableVacFactor; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgTablespace.h b/include/dlg/dlgTablespace.h new file mode 100644 index 0000000..83b7dad --- /dev/null +++ b/include/dlg/dlgTablespace.h @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTablespace.h - Tablespace property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TABLESPACEPROP +#define __DLG_TABLESPACEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgTablespace; + +class dlgTablespace : public dlgSecurityProperty +{ +public: + dlgTablespace(pgaFactory *factory, frmMain *frame, pgTablespace *node = 0); + + void CheckChange(); + wxString GetSql(); + wxString GetSql2(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + int Go(bool modal); + +private: + pgTablespace *tablespace; + wxArrayString varInfo; + bool dirtyVars; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + void OnVarnameSelChange(wxCommandEvent &ev); + void SetupVarEditor(int var); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchConfiguration.h b/include/dlg/dlgTextSearchConfiguration.h new file mode 100644 index 0000000..e8ea8c6 --- /dev/null +++ b/include/dlg/dlgTextSearchConfiguration.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchConfiguration.h - Text Search Configuration property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSCONFIGURATIONPROP +#define __DLG_TSCONFIGURATIONPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchConfiguration; + +class dlgTextSearchConfiguration : public dlgTypeProperty +{ +public: + dlgTextSearchConfiguration(pgaFactory *factory, frmMain *frame, pgTextSearchConfiguration *cfg, pgSchema *sch); + int Go(bool modal); + + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsconfig"); + } + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchConfiguration *config; + bool dirtyTokens; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeToken(wxListEvent &ev); + void OnChangeCbToken(wxCommandEvent &ev); + void OnChangeTxtDictionary(wxCommandEvent &ev); + void OnChangeCbDictionary(wxCommandEvent &ev); + void OnAddToken(wxCommandEvent &ev); + void OnChangeToken(wxCommandEvent &ev); + void OnRemoveToken(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchDictionary.h b/include/dlg/dlgTextSearchDictionary.h new file mode 100644 index 0000000..69fd77b --- /dev/null +++ b/include/dlg/dlgTextSearchDictionary.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchDictionary.h - Text Search Dictionary property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSDICTIONARYPROP +#define __DLG_TSDICTIONARYPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchDictionary; + +class dlgTextSearchDictionary : public dlgTypeProperty +{ +public: + dlgTextSearchDictionary(pgaFactory *factory, frmMain *frame, pgTextSearchDictionary *cfg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsdictionary"); + } + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchDictionary *dict; + + wxString GetOptionsSql(); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchParser.h b/include/dlg/dlgTextSearchParser.h new file mode 100644 index 0000000..2ed256d --- /dev/null +++ b/include/dlg/dlgTextSearchParser.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchParser.h - Text Search Parser property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSPARSERPROP +#define __DLG_TSPARSERPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchParser; + +class dlgTextSearchParser : public dlgTypeProperty +{ +public: + dlgTextSearchParser(pgaFactory *factory, frmMain *frame, pgTextSearchParser *cfg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsparser"); + } + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchParser *parser; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTextSearchTemplate.h b/include/dlg/dlgTextSearchTemplate.h new file mode 100644 index 0000000..d5e4a45 --- /dev/null +++ b/include/dlg/dlgTextSearchTemplate.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTextSearchTemplate.h - Text Search Template property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TSTEMPLATEPROP +#define __DLG_TSTEMPLATEPROP + +#include "dlg/dlgProperty.h" + +class pgSchema; +class pgTextSearchTemplate; + +class dlgTextSearchTemplate : public dlgTypeProperty +{ +public: + dlgTextSearchTemplate(pgaFactory *factory, frmMain *frame, pgTextSearchTemplate *cfg, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtstemplate"); + } + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + void OnChange(wxCommandEvent &ev); + + pgSchema *schema; + pgTextSearchTemplate *tmpl; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgTrigger.h b/include/dlg/dlgTrigger.h new file mode 100644 index 0000000..5d9f56f --- /dev/null +++ b/include/dlg/dlgTrigger.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgTrigger.h - Trigger property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TRIGGERPROP +#define __DLG_TRIGGERPROP + +#include "dlg/dlgProperty.h" + +class pgTrigger; +class pgTable; + +class dlgTrigger : public dlgCollistProperty +{ +public: + dlgTrigger(pgaFactory *factory, frmMain *frame, pgTrigger *trg, pgTable *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + void SetObject(pgObject *obj) + { + trigger = (pgTrigger *)obj; + } + wxString GetColumns(); + + +private: + pgTable *table; + pgTrigger *trigger; + + void OnChange(wxCommandEvent &ev); + void OnChangeFunc(wxCommandEvent &ev); + void OnChangeConstraint(wxCommandEvent &ev); + void OnSelectComboCol(wxCommandEvent &ev); + void OnSelectListCol(wxListEvent &ev); + void OnSelectCol(); + void OnAddCol(wxCommandEvent &ev); + void OnRemoveCol(wxCommandEvent &ev); + + virtual bool IsUpToDate(); + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/dlg/dlgType.h b/include/dlg/dlgType.h new file mode 100644 index 0000000..69f153c --- /dev/null +++ b/include/dlg/dlgType.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgType.h - Typeproperty +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_TYPEPROP +#define __DLG_TYPEPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgType; + +class dlgType : public dlgTypeProperty +{ +public: + dlgType(pgaFactory *factory, frmMain *frame, pgType *node, pgSchema *schema); + + void CheckChange(); + wxString GetSql(); + wxString GetSqlForTypes(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + bool WannaSplitQueries() + { + return queriesToBeSplitted; + } + + int Go(bool modal); + +protected: + /* + * Type Privileges: + * - Did not inherit dlgTypeProperty & dlgSecurityProperty as it will + * lead to a lot of problem later + **/ + + ctlSecurityPanel *securityPage; + wxArrayString currentAcl; + wxArrayString groups; + bool securityChanged; + + wxString GetGrant(const wxString &allPattern, const wxString &grantObject); + + void OnAddPriv(wxCommandEvent &ev); + void OnDelPriv(wxCommandEvent &ev); + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + +private: + pgSchema *schema; + pgType *type; + ctlSeclabelPanel *seclabelPage; + + void OnChange(wxCommandEvent &event); + void OnTypeChange(wxCommandEvent &ev); + void OnMemberAdd(wxCommandEvent &ev); + void OnMemberChange(wxCommandEvent &ev); + void OnMemberRemove(wxCommandEvent &ev); + void OnMemberSelChange(wxListEvent &ev); + void OnLabelAddBefore(wxCommandEvent &ev); + void OnLabelAddAfter(wxCommandEvent &ev); + void OnLabelRemove(wxCommandEvent &ev); + void OnLabelSelChange(wxListEvent &ev); + void OnSelChangeTyp(wxCommandEvent &ev); + void OnSelChangeTypOrLen(wxCommandEvent &ev); + void OnChangeMember(wxCommandEvent &ev); + void OnNameChange(wxCommandEvent &ev); + void OnSubtypeChange(wxCommandEvent &ev); + + void showDefinition(int panel); + wxString GetFullTypeName(int type); + + wxString catGetText(wxString c); + wxString catGetChar(wxString t); + + wxArrayString memberTypes, memberLengths, memberPrecisions, memberCollations, memberOriginalNames; + bool queriesToBeSplitted; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgUser.h b/include/dlg/dlgUser.h new file mode 100644 index 0000000..56a4b76 --- /dev/null +++ b/include/dlg/dlgUser.h @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUser.h - User property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_USERPROP +#define __DLG_USERPROP + +#include "dlg/dlgProperty.h" +#include "ctl/calbox.h" +#include "ctl/timespin.h" + +class pgUser; + +class dlgUser : public dlgProperty +{ +public: + dlgUser(pgaFactory *factory, frmMain *frame, pgUser *node = 0); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + wxString GetHelpPage() const; + + int Go(bool modal); + +private: + pgUser *user; + wxArrayString varInfo; + + void OnChangeSuperuser(wxCommandEvent &ev); + void OnChangeSpin(wxSpinEvent &ev); + void OnChangeCal(wxCalendarEvent &ev); + void OnChangeDate(wxDateEvent &ev); + void OnGroupAdd(wxCommandEvent &ev); + void OnGroupRemove(wxCommandEvent &ev); + + void OnVarAdd(wxCommandEvent &ev); + void OnVarRemove(wxCommandEvent &ev); + void OnVarSelChange(wxListEvent &ev); + + void OnVarnameSelChange(wxCommandEvent &ev); + void OnChangePasswd(wxCommandEvent &ev); + + void SetupVarEditor(int var); + + wxArrayString groupsIn; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgUserMapping.h b/include/dlg/dlgUserMapping.h new file mode 100644 index 0000000..cd819dc --- /dev/null +++ b/include/dlg/dlgUserMapping.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgUserMapping.h - User Mapping property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_USERMAPPINGPROP +#define __DLG_USERMAPPINGPROP + +#include "dlg/dlgProperty.h" + +class pgForeignServer; +class pgUserMapping; + +class dlgUserMapping : public dlgProperty +{ +public: + dlgUserMapping(pgaFactory *factory, frmMain *frame, pgUserMapping *node, pgForeignServer *parent); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + pgForeignServer *foreignserver; + pgUserMapping *usermapping; + +#ifdef __WXMAC__ + void OnChangeSize(wxSizeEvent &ev); +#endif + + void OnSelChangeOption(wxListEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnChangeOptionName(wxCommandEvent &ev); + void OnAddOption(wxCommandEvent &ev); + void OnChangeOption(wxCommandEvent &ev); + void OnRemoveOption(wxCommandEvent &ev); + + wxString GetOptionsSql(); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/dlgView.h b/include/dlg/dlgView.h new file mode 100644 index 0000000..6c4b79a --- /dev/null +++ b/include/dlg/dlgView.h @@ -0,0 +1,82 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgView.h - View property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_VIEWPROP +#define __DLG_VIEWPROP + +#include "dlg/dlgProperty.h" +#include "ctl/ctlSeclabelPanel.h" + +class pgSchema; +class pgView; +class ctlSQLBox; + +class dlgView : public dlgSecurityProperty +{ +public: + dlgView(pgaFactory *factory, frmMain *frame, pgView *v, pgSchema *sch); + int Go(bool modal); + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + + void SetObject(pgObject *obj) + { + view = (pgView *)obj; + } + +private: + + virtual bool IsUpToDate(); + void OnChangeVacuum(wxCommandEvent &ev); + void OnCheckMaterializedView(wxCommandEvent &ev); + void FillAutoVacuumParameters(wxString &setStr, wxString &resetStr, const wxString ¶meter, const wxString &val); + wxString AppendNum(bool &changed, wxTextCtrl *ctl, wxString val); + void DisableMaterializedView(); + void DisableStorageParameters(); + int GetIndexCheckOption(const wxString &str) const; + + pgSchema *schema; + pgView *view; + ctlSeclabelPanel *seclabelPage; + wxString oldDefinition; + wxTextValidator mviewNumericValidator; + + void OnChange(wxCommandEvent &event); + + bool tableVacEnabled, hasVacuum, settingAutoVacuum; + wxString settingVacBaseThr, settingAnlBaseThr, settingCostDelay, + settingCostLimit, settingFreezeMinAge, settingFreezeMaxAge, + settingFreezeTableAge; + wxString tableVacBaseThr, tableAnlBaseThr, tableCostDelay, + tableCostLimit, tableFreezeMinAge, tableFreezeMaxAge, + tableFreezeTableAge; + wxString settingVacFactor, settingAnlFactor; + wxString tableVacFactor, tableAnlFactor; + + /* Toast Table */ + bool toastTableVacEnabled, toastTableHasVacuum; + wxString toastTableVacBaseThr, + toastTableCostDelay, toastTableCostLimit, + toastTableFreezeMinAge, toastTableFreezeMaxAge, + toastTableFreezeTableAge; + wxString toastTableVacFactor; + + bool forceSecurityBarrierChanged; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/dlg/module.mk b/include/dlg/module.mk new file mode 100644 index 0000000..8fed68d --- /dev/null +++ b/include/dlg/module.mk @@ -0,0 +1,72 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/dlg/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/dlg/dlgAddFavourite.h \ + include/dlg/dlgAggregate.h \ + include/dlg/dlgCast.h \ + include/dlg/dlgCheck.h \ + include/dlg/dlgClasses.h \ + include/dlg/dlgCollation.h \ + include/dlg/dlgColumn.h \ + include/dlg/dlgConnect.h \ + include/dlg/dlgConversion.h \ + include/dlg/dlgDatabase.h \ + include/dlg/dlgDomain.h \ + include/dlg/dlgEventTrigger.h \ + include/dlg/dlgExtension.h \ + include/dlg/dlgEditGridOptions.h \ + include/dlg/dlgFindReplace.h \ + include/dlg/dlgForeignDataWrapper.h \ + include/dlg/dlgForeignKey.h \ + include/dlg/dlgForeignServer.h \ + include/dlg/dlgForeignTable.h \ + include/dlg/dlgFunction.h \ + include/dlg/dlgGroup.h \ + include/dlg/dlgHbaConfig.h \ + include/dlg/dlgIndex.h \ + include/dlg/dlgIndexConstraint.h \ + include/dlg/dlgLanguage.h \ + include/dlg/dlgMainConfig.h \ + include/dlg/dlgManageFavourites.h \ + include/dlg/dlgMoveTablespace.h \ + include/dlg/dlgOperator.h \ + include/dlg/dlgPackage.h \ + include/dlg/dlgPgpassConfig.h \ + include/dlg/dlgProperty.h \ + include/dlg/dlgReassignDropOwned.h \ + include/dlg/dlgRole.h \ + include/dlg/dlgRule.h \ + include/dlg/dlgSchema.h \ + include/dlg/dlgSearchObject.h \ + include/dlg/dlgSelectConnection.h \ + include/dlg/dlgSequence.h \ + include/dlg/dlgServer.h \ + include/dlg/dlgSynonym.h \ + include/dlg/dlgTable.h \ + include/dlg/dlgTablespace.h \ + include/dlg/dlgTextSearchConfiguration.h \ + include/dlg/dlgTextSearchDictionary.h \ + include/dlg/dlgTextSearchParser.h \ + include/dlg/dlgTextSearchTemplate.h \ + include/dlg/dlgTrigger.h \ + include/dlg/dlgType.h \ + include/dlg/dlgUser.h \ + include/dlg/dlgUserMapping.h \ + include/dlg/dlgView.h \ + include/dlg/dlgManageMacros.h \ + include/dlg/dlgExtTable.h \ + include/dlg/dlgSelectDatabase.h \ + include/dlg/dlgResourceGroup.h + +EXTRA_DIST += \ + include/dlg/module.mk + diff --git a/include/frm/frmAbout.h b/include/frm/frmAbout.h new file mode 100644 index 0000000..82217e0 --- /dev/null +++ b/include/frm/frmAbout.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmAbout.h - About Box +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMABOUT_H +#define FRMABOUT_H + +// Class declarations +class frmAbout : public wxFrame +{ +public: + frmAbout(wxFrame *parent); + + void OnPaint(wxPaintEvent &); + +private: + void SetWindowShape(); + void OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)); + void OnLeftDown(wxMouseEvent &WXUNUSED(evt)); + void OnKeyUp(wxKeyEvent &evt); + + wxBitmap about; + DECLARE_EVENT_TABLE() +}; + +class aboutFactory : public actionFactory +{ +public: + aboutFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmBackup.h b/include/frm/frmBackup.h new file mode 100644 index 0000000..94e3978 --- /dev/null +++ b/include/frm/frmBackup.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackup.h - Backup database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMBACKUP_H +#define FRMBACKUP_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmBackup : public ExternProcessDialog +{ +public: + frmBackup(frmMain *form, pgObject *_object); + ~frmBackup(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + void OnChangePlain(wxCommandEvent &ev); + wxString getCmdPart1(); + wxString getCmdPart2(); + void OnOK(wxCommandEvent &ev); + + pgObject *object; + + wxString backupExecutable; + bool canBlob; + wxString processedFile; + + DECLARE_EVENT_TABLE() +}; + + +class backupFactory : public contextActionFactory +{ +public: + backupFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmBackupGlobals.h b/include/frm/frmBackupGlobals.h new file mode 100644 index 0000000..7e9f6ae --- /dev/null +++ b/include/frm/frmBackupGlobals.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupGlobals.h - Backup globals dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMBACKUPGLOBALS_H +#define FRMBACKUPGLOBALS_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmBackupGlobals : public ExternProcessDialog +{ +public: + frmBackupGlobals(frmMain *form, pgObject *_object); + ~frmBackupGlobals(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + wxString getCmdPart1(); + wxString getCmdPart2(); + void OnOK(wxCommandEvent &ev); + + pgObject *object; + wxString processedFile; + wxString backupExecutable; + + DECLARE_EVENT_TABLE() +}; + + +class backupGlobalsFactory : public contextActionFactory +{ +public: + backupGlobalsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmBackupServer.h b/include/frm/frmBackupServer.h new file mode 100644 index 0000000..697bf3e --- /dev/null +++ b/include/frm/frmBackupServer.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackupServer.h - Backup server dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMBACKUPSERVER_H +#define FRMBACKUPSERVER_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmBackupServer : public ExternProcessDialog +{ +public: + frmBackupServer(frmMain *form, pgObject *_object); + ~frmBackupServer(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + wxString getCmdPart1(); + wxString getCmdPart2(); + void OnOK(wxCommandEvent &ev); + + pgObject *object; + wxString processedFile; + wxString backupExecutable; + + DECLARE_EVENT_TABLE() +}; + + +class backupServerFactory : public contextActionFactory +{ +public: + backupServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmConfig.h b/include/frm/frmConfig.h new file mode 100644 index 0000000..01a9312 --- /dev/null +++ b/include/frm/frmConfig.h @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmConfig.h - Configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMCONFIG_H +#define FRMCONFIG_H + +#include + +class pgConn; +class ctlListView; +class frmMain; + + +extern wxImageList *configImageList; + +class frmConfig : public pgFrame +{ +public: + + enum tryMode + { + NONE = 0, + ANYFILE, + HBAFILE, + MAINFILE, + PGPASSFILE + }; + + static frmConfig *Create(const wxString &title, const wxString &configFile, tryMode mode); + void Go(); + void DoOpen(const wxString &fn = wxEmptyString); + + +protected: + frmConfig(const wxString &title, const wxString &configFile); + frmConfig(frmMain *parent, const wxString &title, pgConn *conn); + ~frmConfig(); + + virtual void DisplayFile(const wxString &str) = 0; + virtual void WriteFile(pgConn *conn = 0) = 0; + virtual wxString GetHintString() + { + return wxEmptyString; + } + + void OpenLastFile(); + void InitFrame(const wxChar *frameName); + bool DoWriteFile(const wxChar *str, pgConn *conn); + bool CheckChanged(bool canVeto); + +private: + + virtual void OnOpen(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + void OnSaveAs(wxCommandEvent &event); + + void OnClose(wxCloseEvent &event); + void OnExecute(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + void OnHint(wxCommandEvent &event); + void OnBugreport(wxCommandEvent &event); + + void DisplayHint(bool force); + +protected: + pgConn *conn; + frmMain *mainForm; + wxString serverFileName; + + wxTextFileType filetype; + + DECLARE_EVENT_TABLE() +}; + + + +#endif diff --git a/include/frm/frmDatabaseDesigner.h b/include/frm/frmDatabaseDesigner.h new file mode 100644 index 0000000..1ee5d71 --- /dev/null +++ b/include/frm/frmDatabaseDesigner.h @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmDatabaseDesigner.h - The database designer form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRM_DATABASEDESIGNER_H +#define __FRM_DATABASEDESIGNER_H + +// Designer headers +#include "hotdraw/figures/hdAbstractFigure.h" +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "dd/ddmodel/ddDatabaseDesign.h" +#include "ctl/ctlSQLBox.h" +#include +#include "dlg/dlgSelectConnection.h" + +enum +{ + CTL_DDNOTEBOOK = 1001, + CTL_DDCONNECTION, + CTL_IMPSCHEMA +}; + +class frmDatabaseDesigner : public pgFrame +{ +public: + frmDatabaseDesigner(frmMain *form, const wxString &_title, pgConn *conn); + ~frmDatabaseDesigner(); + void Go(); + void setModelChanged(bool value); +private: + int deletedTab; + bool changed, previousChanged; + wxBitmapComboBox *cbConnection; + wxMenu *diagramMenu, *preferencesMenu, *viewMenu; + wxString lastFile; + frmMain *mainForm; + pgConn *connection; + + // These status flags are required to work round some wierdness on wxGTK, + // particularly on Solaris. + bool closing, loading; + + ddDatabaseDesign *design; + wxPanel *browserPanel, *connectionPanel; + ddModelBrowser *modelBrowser; + ctlAuiNotebook *diagrams; + ctlSQLBox *sqltext; + void setExtendedTitle(); + void OnClose(wxCloseEvent &event); + void OnAddDiagram(wxCommandEvent &event); + void OnAddDiagram2(wxAuiNotebookEvent &event); + void OnDeleteDiagram(wxCommandEvent &event); + void OnRenameDiagram(wxCommandEvent &event); + void OnClickDiagramTab(wxAuiNotebookEvent &event); + void OnDeleteDiagramTab(wxAuiNotebookEvent &event); + void OnDeletedDiagramTab(wxAuiNotebookEvent &event); + void OnAddTable(wxCommandEvent &event); + void OnDeleteTable(wxCommandEvent &event); + void OnAddColumn(wxCommandEvent &event); + void OnNewModel(wxCommandEvent &event); + void OnModelGeneration(wxCommandEvent &event); + void OnModelSaveAs(wxCommandEvent &event); + void OnDiagramGeneration(wxCommandEvent &event); + void OnModelSave(wxCommandEvent &event); + void OnModelLoad(wxCommandEvent &event); + void OnToggleModelBrowser(wxCommandEvent &event); + void OnToggleSQLWindow(wxCommandEvent &event); + void OnChangeConnection(wxCommandEvent &event); + void OnImportSchema(wxCommandEvent &WXUNUSED(event)); + wxBitmap CreateBitmap(const wxColour &colour); + wxColour GetServerColour(pgConn *connection); + void UpdateToolbar(); + wxAuiManager manager; + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////////// + +class databaseDesignerBaseFactory : public actionFactory +{ +protected: + databaseDesignerBaseFactory(menuFactoryList *list) : actionFactory(list) {} + wxWindow *StartDialogDesigner(frmMain *form, pgObject *obj, const wxString &sql); +public: + bool CheckEnable(pgObject *obj); +}; + +class databaseDesignerFactory : public databaseDesignerBaseFactory +{ +public: + databaseDesignerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif // __FRM_DATABASEDESIGNER_H diff --git a/include/frm/frmEditGrid.h b/include/frm/frmEditGrid.h new file mode 100644 index 0000000..5042458 --- /dev/null +++ b/include/frm/frmEditGrid.h @@ -0,0 +1,376 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmEditGrid.h - The SQL Edit Grid form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMEDITGRID_H +#define __FRMEDITGRID_H + +#include +#include +// wxAUI +#include + +#define CTL_EDITGRID 357 +#include "dlg/dlgClasses.h" +#include "ctl/ctlSQLGrid.h" + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMEDITGRID_PERSPECTIVE_VER wxT("8189") + +#ifdef __WXMAC__ +#define FRMEDITGRID_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=240;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=limitBar;caption=Limit bar;state=16788208;dir=1;layer=10;row=0;pos=243;prop=100000;bestw=120;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=415;floaty=793;floatw=-1;floath=-1|name=sqlGrid;caption=Data grid;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=150;minw=200;minh=100;maxw=-1;maxh=-1;floatx=347;floaty=725;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=84|dock_size(3,0,0)=173|") +#else +#ifdef __WXGTK__ +#define FRMEDITGRID_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=305;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=limitBar;caption=Limit bar;state=16788208;dir=1;layer=10;row=0;pos=243;prop=100000;bestw=120;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=415;floaty=793;floatw=-1;floath=-1|name=sqlGrid;caption=Data grid;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=150;minw=200;minh=100;maxw=-1;maxh=-1;floatx=347;floaty=725;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=84|dock_size(3,0,0)=173|") +#else +#define FRMEDITGRID_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=232;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=limitBar;caption=Limit bar;state=16788208;dir=1;layer=10;row=0;pos=243;prop=100000;bestw=100;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=415;floaty=793;floatw=-1;floath=-1|name=sqlGrid;caption=Data grid;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=300;besth=150;minw=200;minh=100;maxw=-1;maxh=-1;floatx=347;floaty=725;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=84|dock_size(3,0,0)=173|") +#endif +#endif + +class cacheLine +{ +public: + cacheLine() + { + cols = 0; + stored = false; + readOnly = false; + } + ~cacheLine() + { + if (cols) delete[] cols; + } + + wxString *cols; + bool stored, readOnly; +}; + + +class cacheLinePool +{ +public: + cacheLinePool(int initialLines); + ~cacheLinePool(); + cacheLine *operator[] (int line) + { + return Get(line); + } + cacheLine *Get(int lineNo); + bool IsFilled(int lineNo); + void Delete(int lineNo); + +private: + cacheLine **ptr; + int anzLines; +}; + + +class sqlCell +{ +public: + sqlCell() + { + ClearCell(); + } + + void SetCell(long r, long c) + { + row = r; + col = c; + } + void ClearCell() + { + row = -1; + col = -1; + } + bool IsSet() + { + return row != -1 && col != -1; + } + + long GetRow() + { + return row; + } + long GetCol() + { + return col; + } + +private: + long row; + long col; +}; + +// we cannot derive from wxGridCellAttr because destructor is private but not virtual +class sqlCellAttr +{ +public: + sqlCellAttr() + { + attr = new wxGridCellAttr; + isPrimaryKey = false; + needResize = false; + } + ~sqlCellAttr() + { + attr->DecRef(); + } + int size(); + int precision(); + + wxGridCellAttr *attr; + wxString Quote(pgConn *conn, const wxString &value); + OID type; + long typlen, typmod; + wxString name, typeName, displayTypeName; + bool numeric, isPrimaryKey, needResize; +}; + + +class sqlTable; + +class ctlSQLEditGrid : public ctlSQLGrid +{ +public: + ctlSQLEditGrid(wxFrame *parent, wxWindowID id, const wxPoint &pos, const wxSize &size); + + sqlTable *GetTable() + { + return (sqlTable *)wxGrid::GetTable(); + } + //wxSize GetBestSize(int row, int col); + void ResizeEditor(int row, int col); + wxArrayInt GetSelectedRows() const; + bool CheckRowPresent(int row); + virtual bool IsColText(int col); +}; + +class sqlTable : public wxGridTableBase +{ +public: + sqlTable(pgConn *conn, pgQueryThread *thread, const wxString &tabName, const OID relid, bool _hasOid, const wxString &_pkCols, char _relkind); + ~sqlTable(); + bool StoreLine(); + void UndoLine(int row); + + int GetNumberRows(); + int GetNumberStoredRows(); + int GetNumberCols(); + wxString GetColLabelValue(int col); + wxString GetColLabelValueUnformatted(int col); + wxString GetRowLabelValue(int row); + wxGridCellAttr *GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind); + + wxString GetValue(int row, int col); + void SetValue(int row, int col, const wxString &value); + + bool IsEmptyCell(int row, int col) + { + return false; + } + bool needsResizing(int col) + { + return columns[col].needResize; + } + bool AppendRows(size_t rows); + bool DeleteRows(size_t pos, size_t rows); + int LastRow() + { + return lastRow; + } + bool IsColText(int col); + bool IsColBoolean(int col); + + bool CheckInCache(int row); + bool IsLineSaved(int row) + { + return GetLine(row)->stored; + } + + bool Paste(); + +private: + pgQueryThread *thread; + pgConn *connection; + bool hasOids; + char relkind; + wxString tableName; + OID relid; + wxString primaryKeyColNumbers; + + cacheLine *GetLine(int row); + wxString MakeKey(cacheLine *line); + void SetNumberEditor(int col, int len); + + cacheLinePool *dataPool, *addPool; + cacheLine savedLine; + int lastRow; + + int *lineIndex; // reindex of lines in dataSet to handle deleted rows + + int nCols; // columns from dataSet + int nRows; // rows initially returned by dataSet + int rowsCached; // rows read from dataset; if nRows=rowsCached, dataSet can be deleted + int rowsAdded; // rows added (never been in dataSet) + int rowsStored; // rows added and stored to db + int rowsDeleted; // rows deleted from initial dataSet + sqlCellAttr *columns; + + wxArrayInt colMap; + + friend class ctlSQLEditGrid; +}; + + +class frmMain; +class pgSchemaObject; + +class frmEditGrid : public pgFrame +{ +public: + frmEditGrid(frmMain *form, const wxString &_title, pgConn *conn, pgSchemaObject *obj, bool ascending = true); + ~frmEditGrid(); + + void ShowForm(bool filter = false); + void Go(); + wxString GetSortCols() const + { + return orderBy; + } ; + void SetSortCols(const wxString &cols); + wxString GetFilter() const + { + return rowFilter; + } ; + void SetFilter(const wxString &filter); + int GetLimit() const + { + return limit; + } ; + void SetLimit(const int rowlimit); + wxMenu *GetFileMenu() + { + return fileMenu; + }; + wxMenu *GetEditMenu() + { + return editMenu; + }; + +private: + void OnEraseBackground(wxEraseEvent &event); + void OnSize(wxSizeEvent &event); + + void OnCloseWindow(wxCloseEvent &event); + void OnClose(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + void OnContents(wxCommandEvent &event); + void OnRefresh(wxCommandEvent &event); + void OnDelete(wxCommandEvent &event); + void OnOptions(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + bool DoSave(); + void CancelChange(); + void OnUndo(wxCommandEvent &event); + void OnCellChange(wxGridEvent &event); + void OnGridSelectCells(wxGridRangeSelectEvent &event); + void OnEditorShown(wxGridEvent &event); + void OnEditorHidden(wxGridEvent &event); + void OnKey(wxKeyEvent &event); + void OnCopy(wxCommandEvent &event); + void OnIncludeFilter(wxCommandEvent &event); + void OnExcludeFilter(wxCommandEvent &event); + void OnRemoveFilters(wxCommandEvent &event); + void OnAscSort(wxCommandEvent &event); + void OnDescSort(wxCommandEvent &event); + void OnRemoveSort(wxCommandEvent &event); + void OnPaste(wxCommandEvent &event); + void OnLabelDoubleClick(wxGridEvent &event); + void OnLabelRightClick(wxGridEvent &event); + void OnCellRightClick(wxGridEvent &event); + void Abort(); + void OnToggleScratchPad(wxCommandEvent &event); + void OnToggleLimitBar(wxCommandEvent &event); + void OnToggleToolBar(wxCommandEvent &event); + void OnAuiUpdate(wxAuiManagerEvent &event); + void OnDefaultView(wxCommandEvent &event); + + wxAuiManager manager; + ctlSQLEditGrid *sqlGrid; + + frmMain *mainForm; + pgConn *connection; + pgQueryThread *thread; + wxMenu *fileMenu, *editMenu, *viewMenu, *toolsMenu, *helpMenu; + ctlMenuToolbar *toolBar; + wxComboBox *cbLimit; + wxTextCtrl *scratchPad; + + char relkind; + OID relid; + bool hasOids; + wxString tableName; + wxString primaryKeyColNumbers; + wxString orderBy; + bool autoOrderBy; + wxString rowFilter; + int limit; + sqlCell *editorCell; + bool closing; + + DECLARE_EVENT_TABLE() +}; + + +class editGridFactoryBase : public contextActionFactory +{ +public: + bool CheckEnable(pgObject *obj); + +protected: + editGridFactoryBase(menuFactoryList *list) : contextActionFactory(list) + { + pkAscending = true; + rowlimit = 0; + } + wxWindow *ViewData(frmMain *form, pgObject *obj, bool filter); + int rowlimit; + bool pkAscending; +}; + + +class editGridFactory : public editGridFactoryBase +{ +public: + editGridFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class editGridFilteredFactory : public editGridFactoryBase +{ +public: + editGridFilteredFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class editGridLimitedFactory : public editGridFactoryBase +{ +public: + editGridLimitedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, int limit, bool ascending); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif + + diff --git a/include/frm/frmExport.h b/include/frm/frmExport.h new file mode 100644 index 0000000..f17c5a5 --- /dev/null +++ b/include/frm/frmExport.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmExport.h - The export file dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMEXPORT_H +#define FRMEXPORT_H + + +class ctlSQLResult; +class pgSet; + +#include "dlg/dlgClasses.h" + +// Class declarations +class frmExport : public pgDialog +{ +public: + frmExport(wxWindow *parent); + ~frmExport(); + + bool Export(pgSet *set); + +private: + void OnChange(wxCommandEvent &ev); + void OnHelp(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnBrowseFile(wxCommandEvent &ev); + wxString InitXml(int cols, int rows); + bool ExportXls(ctlSQLResult *grid); + wxWindow *parent; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/frm/frmGrantWizard.h b/include/frm/frmGrantWizard.h new file mode 100644 index 0000000..ac3be7b --- /dev/null +++ b/include/frm/frmGrantWizard.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmGrantWizard.h - Grant Wizard Dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMGRANTWIZARD_H +#define FRMGRANTWIZARD_H + +#include +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class ctlSecurityPanel; + +DECLARE_LOCAL_EVENT_TYPE(EVT_SECURITYPANEL_CHANGE, -1) + +class frmGrantWizard : public ExecutionDialog +{ +public: + frmGrantWizard(frmMain *form, pgObject *_object); + ~frmGrantWizard(); + + void Go(); + wxString GetSql(); + wxString GetHelpPage() const; + +private: + + void OnPageSelect(wxNotebookEvent &event); + void OnCheckAll(wxCommandEvent &event); + void OnUncheckAll(wxCommandEvent &event); + void OnChange(wxCommandEvent &event); + + void AddObjects(pgCollection *collection); + + wxArrayPtrVoid objectArray; + ctlSQLBox *sqlPane; + wxNotebook *nbNotebook; + ctlSecurityPanel *securityPage; + + DECLARE_EVENT_TABLE() +}; + +class grantWizardFactory : public contextActionFactory +{ +public: + grantWizardFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmHbaConfig.h b/include/frm/frmHbaConfig.h new file mode 100644 index 0000000..5c66cab --- /dev/null +++ b/include/frm/frmHbaConfig.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHbaConfig.h - Backend access configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMHBACONFIG_H +#define FRMHBACONFIG_H + +#include "frm/frmConfig.h" +#include "utils/pgconfig.h" + +class pgConn; +class pgServer; +class ctlListView; + + +WX_DECLARE_OBJARRAY(pgHbaConfigLine, pgHbaConfigLineArray); + +class frmHbaConfig : public frmConfig +{ +public: + frmHbaConfig(const wxString &title, const wxString &configFile); + frmHbaConfig(frmMain *parent, pgServer *server = 0); + ~frmHbaConfig(); + +protected: + void DisplayFile(const wxString &str); + void WriteFile(pgConn *conn = 0); + wxString GetHintString(); + wxString GetHelpPage() const; + +private: + void Init(); + void UpdateDisplay(pgHbaConfigLine &line); + + void OnContents(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnDelete(wxCommandEvent &event); + void OnEditSetting(wxListEvent &event); + void OnSelectSetting(wxListEvent &event); + + ctlListView *listEdit; + pgHbaConfigLineArray lines; + + + DECLARE_EVENT_TABLE() +}; + +class hbaConfigFactory : public actionFactory +{ +public: + hbaConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class hbaConfigFileFactory : public actionFactory +{ +public: + hbaConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif diff --git a/include/frm/frmHint.h b/include/frm/frmHint.h new file mode 100644 index 0000000..c9fb24b --- /dev/null +++ b/include/frm/frmHint.h @@ -0,0 +1,79 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmHint.h - PostgreSQL Guru hints +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMHINT +#define __FRMHINT + + +#define HINT_CONNECTSERVER wxT("conn-listen") +#define HINT_MISSINGHBA wxT("conn-hba") +#define HINT_MISSINGIDENT wxT("conn-ident") +#define HINT_PRIMARYKEY wxT("pk") +#define HINT_FKINDEX wxT("fki") +#define HINT_VACUUM wxT("vacuum") +#define HINT_VACUUM_FULL wxT("vacuum-full") +#define HINT_QUERYRUNTIME wxT("query-runtime") +#define HINT_INSTRUMENTATION wxT("instrumentation") +#define HINT_INSTRUMENTATION_91_WITH wxT("instrumentation91_with") +#define HINT_INSTRUMENTATION_91_WITHOUT wxT("instrumentation91_without") +#define HINT_ENCODING_ASCII wxT("encoding-ascii") +#define HINT_ENCODING_UNICODE wxT("encoding-unicode") +#define HINT_READONLY_NOPK wxT("view-without-pk") +#define HINT_AUTOVACUUM wxT("autovacuum") +#define HINT_OBJECT_EDITING wxT("object-editing") +#define HINT_SAVING_PASSWORDS wxT("saving-passwords") + +#define HINT_RC_FIX 42 + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; +class frmHint : public DialogWithHelp +{ +public: + static int ShowHint(wxWindow *fr, const wxString &hint, const wxString &info = wxEmptyString, bool force = false); + static int ShowHint(wxWindow *fr, const wxArrayString &hints, const wxString &info = wxEmptyString, bool force = false); + static bool WantHint(const wxString &hint); + static void ResetHints(); + + void SetHint(int hint, const wxString &info); + void SetHint(const wxArrayInt &hintnos, const wxString &info); + +private: + frmHint(wxWindow *fr, bool force); + ~frmHint(); + + void SetHint(const wxString &info); + void OnFix(wxCommandEvent &ev); + static int GetHintNo(const wxString &hint); + static bool WantHint(int hintno); + wxString GetPage(const wxChar *hintpage); + wxString GetHelpPage() const; + + DECLARE_EVENT_TABLE() + + wxArrayInt hintnos; + int currentHint; + bool force; +}; + + +class hintFactory : public actionFactory +{ +public: + hintFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmImport.h b/include/frm/frmImport.h new file mode 100644 index 0000000..b83069b --- /dev/null +++ b/include/frm/frmImport.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmBackup.h - Backup database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMIMPORT_H +#define FRMIMPORT_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class frmImport : public pgDialog +{ +public: + frmImport(frmMain *form, pgObject *_object, pgConn *_conn); + ~frmImport(); + +private: + void OnHelp(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + void OnChangeFormat(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + + pgConn *connection; + pgObject *object; + bool done; + + DECLARE_EVENT_TABLE() +}; + + +class importFactory : public contextActionFactory +{ +public: + importFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmMain.h b/include/frm/frmMain.h new file mode 100644 index 0000000..90cea9a --- /dev/null +++ b/include/frm/frmMain.h @@ -0,0 +1,363 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMain.h - The main form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMMAIN_H +#define FRMMAIN_H + + +// wxWindows headers +#include +#include +#include + +// wxAUI +#include + +#include "frm/frmQuery.h" +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMMAIN_PERSPECTIVE_VER wxT("8418") + +#ifdef __WXMAC__ +#define FRMMAIN_DEFAULT_PERSPECTIVE wxT("layout2|name=objectBrowser;caption=Object browser;state=16779260;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=200;besth=450;minw=100;minh=200;maxw=-1;maxh=-1;floatx=236;floaty=222;floatw=-1;floath=-1|name=listViews;caption=Info pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlPane;caption=SQL pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=520;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=18|dock_size(3,0,0)=228|dock_size(1,10,0)=41|dock_size(4,1,0)=233|") +#else +#ifdef __WXGTK__ +#define FRMMAIN_DEFAULT_PERSPECTIVE wxT("layout2|name=objectBrowser;caption=Object browser;state=16779260;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=200;besth=450;minw=100;minh=200;maxw=-1;maxh=-1;floatx=236;floaty=222;floatw=-1;floath=-1|name=listViews;caption=Info pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlPane;caption=SQL pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=586;besth=44;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=18|dock_size(3,0,0)=228|dock_size(1,10,0)=41|dock_size(4,1,0)=233|") +#else +#define FRMMAIN_DEFAULT_PERSPECTIVE wxT("layout2|name=objectBrowser;caption=Object browser;state=16779260;dir=4;layer=1;row=0;pos=0;prop=100000;bestw=200;besth=450;minw=100;minh=200;maxw=-1;maxh=-1;floatx=236;floaty=222;floatw=-1;floath=-1|name=listViews;caption=Info pane;state=1020;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlPane;caption=SQL pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=400;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=506;besth=39;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(5,0,0)=18|dock_size(3,0,0)=228|dock_size(1,10,0)=41|dock_size(4,1,0)=233|") + +#endif +#endif +class pgServer; +class pgServerCollection; +class ctlSQLBox; +class ctlTree; +class dlgProperty; +class serverCollection; + +class propertyFactory; +class pluginUtilityFactory; +class ctlMenuButton; + +// A plugin utility +typedef struct PluginUtility +{ + wxString title; + wxString command; + wxString description; + wxString keyfile; + wxString platform; + wxArrayString server_types; + bool database; + wxArrayString applies_to; + bool set_password; + wxArrayString set_env; +} PluginUtility; + + +enum +{ + NBP_PROPERTIES = 0, + NBP_STATISTICS, + NBP_DEPENDENCIES, + NBP_DEPENDENTS +}; + +enum +{ + REFRESH_OBJECT_NONE = 0, + REFRESH_OBJECT_ONLY, + REFRESH_OBJECT_AND_CHILDREN +}; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +BEGIN_DECLARE_EVENT_TYPES() +extern const wxEventType SSH_TUNNEL_ERROR_EVENT; +END_DECLARE_EVENT_TYPES() +#endif + +// Class declarations +class frmMain : public pgFrame +{ +public: + frmMain(const wxString &title); + ~frmMain(); + + void OnAction(wxCommandEvent &ev); + void OnReport(wxCommandEvent &ev); + wxString GetHelpPage() const; + + void StartMsg(const wxString &msg); + void EndMsg(bool done = true); + void SetStatusText(const wxString &msg); + void SetCurrentObject(pgObject *data) + { + currentObject = data; + } + bool CheckAlive(); + + void execSelChange(wxTreeItemId item, bool currentNode); + void Refresh(pgObject *data); + void ExecDrop(bool cascaded); + void ShowObjStatistics(pgObject *data, wxWindow *ctrl = NULL); + + wxImageList *GetImageList() + { + return imageList; + } + ctlTree *GetBrowser() + { + return browser; + } + ctlSQLBox *GetSqlPane() + { + return sqlPane; + } + ctlListView *GetProperties() + { + return properties; + } + ctlListView *GetStatistics(); + ctlListView *GetDependencies(); + ctlListView *GetReferencedBy(); + void SelectStatisticsTab() + { + listViews->SetSelection(1); + }; + void StoreServers(); + int ReconnectServer(pgServer *server, bool restore = true); + void ReportConnError(pgServer *server); + pgServerCollection *GetServerCollection() + { + return serversObj; + } + pgServer *ConnectToServer(const wxString &servername, bool restore = false); + + void SetLastPluginUtility(pluginUtilityFactory *pluginFactory) + { + lastPluginUtility = pluginFactory; + } + pluginUtilityFactory *GetLastPluginUtility() + { + return lastPluginUtility; + } + wxMenu *GetPluginsMenu() + { + return pluginsMenu; + } + + wxString GetCurrentNodePath(); + bool SetCurrentNode(wxTreeItemId node, const wxString &path); + + void UpdateAllRecentFiles(); + void UpdateAllFavouritesList(); + void UpdateAllMacrosList(); + + void SetItemBackgroundColour(wxTreeItemId item, wxColour colour); + wxString GetNodePath(wxTreeItemId node); + void ObjectBrowserRefreshing(bool refresh) + { + m_refreshing = refresh; + } + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + void OnSSHTunnelEvent(wxCommandEvent &event); +#endif + +private: + wxAuiManager manager; + ctlTree *browser; + ctlListView *properties; + ctlListView *statistics; + ctlListView *dependents, *dependencies; + ctlAuiNotebook *listViews; + ctlSQLBox *sqlPane; + wxMenu *newMenu, *debuggingMenu, *reportMenu, *toolsMenu, *pluginsMenu, *viewMenu, + *treeContextMenu, *newContextMenu, *slonyMenu, *scriptingMenu, *viewDataMenu; + pgServerCollection *serversObj; + + pluginUtilityFactory *lastPluginUtility; + int pluginUtilityCount; + + propertyFactory *propFactory; + actionFactory *newMenuFactory; + actionFactory *debuggingMenuFactory; + actionFactory *reportMenuFactory; + actionFactory *scriptingMenuFactory; + actionFactory *viewdataMenuFactory; + + wxStopWatch stopwatch; + wxString timermsg; + long msgLevel; + + bool m_refreshing; + + wxTreeItemId denyCollapseItem; + pgObject *currentObject; + wxControl *currentControl; + + void OnChildFocus(wxChildFocusEvent &event); + void OnEraseBackground(wxEraseEvent &event); + void OnSize(wxSizeEvent &event); + void OnSelectItem(wxListEvent &event); + + void CreateMenus(); + void OnContents(wxCommandEvent &event); + void OnExit(wxCommandEvent &event); + void ViewData(bool filter = false); + void OnSaveDefinition(wxCommandEvent &event); + void OnToggleSqlPane(wxCommandEvent &event); + void OnToggleObjectBrowser(wxCommandEvent &event); + void OnToggleToolBar(wxCommandEvent &event); + void OnDefaultView(wxCommandEvent &event); + void OnAuiUpdate(wxAuiManagerEvent &event); + void OnAuiNotebookPageClose(wxAuiNotebookEvent &event); + void OnContextMenu(wxCommandEvent &event); + + void OnPageChange(wxAuiNotebookEvent &event); + void OnPropSelChanged(wxListEvent &event); + void OnPropSelActivated(wxListEvent &event); + void OnPropRightClick(wxListEvent &event); + void OnTreeSelChanged(wxTreeEvent &event); + void OnTreeKeyDown(wxTreeEvent &event); + void OnSelActivated(wxTreeEvent &event); + void OnSelRightClick(wxTreeEvent &event); + void OnCollapse(wxTreeEvent &event); + void OnExpand(wxTreeEvent &event); + void OnClose(wxCloseEvent &event); + + void OnNew(wxCommandEvent &event); + void OnDelete(wxCommandEvent &ev); + void OnCopy(wxCommandEvent &ev); + + void OnCheckAlive(wxCommandEvent &event); + + void OnPositionStc(wxStyledTextEvent &event); + + void ResetLists(); + bool dropSingleObject(pgObject *data, bool updateFinal, bool cascaded); + void doPopup(wxWindow *win, wxPoint point, pgObject *object); + void setDisplay(pgObject *data, ctlListView *props = 0, ctlSQLBox *sqlbox = 0); + void RetrieveServers(); + bool reportError(const wxString &error, const wxString &msgToIdentify, const wxString &hint); + wxTreeItemId RestoreEnvironment(pgServer *server); + + void GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes); + void ExpandChildNodes(wxTreeItemId node, wxArrayString &expandedNodes); + + + void PopulatePluginButtonMenu(wxCommandEvent &event); + + // In plugins.cpp + void LoadPluginUtilities(); + void AddPluginUtility(PluginUtility *util); + void CreatePluginUtility(PluginUtility *util); + void ClearPluginUtility(PluginUtility *util); + + DECLARE_EVENT_TABLE() +}; + +enum +{ + CTL_BROWSER = 301, + CTL_NOTEBOOK, + CTL_PROPVIEW, + CTL_STATVIEW, + CTL_DEPVIEW, + CTL_REFVIEW, + CTL_SQLPANE +}; + +class contentsFactory : public actionFactory +{ +public: + contentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class pgsqlHelpFactory : public actionFactory +{ +public: + pgsqlHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class edbHelpFactory : public actionFactory +{ +public: + edbHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class greenplumHelpFactory : public actionFactory +{ +public: + greenplumHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class slonyHelpFactory : public actionFactory +{ +public: + slonyHelpFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar, bool bigTool); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class faqFactory : public actionFactory +{ +public: + faqFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class bugReportFactory : public actionFactory +{ +public: + bugReportFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class pluginUtilityFactory : public actionFactory +{ +public: + pluginUtilityFactory(menuFactoryList *list, wxMenu *menu, PluginUtility *util); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + +private: + bool HaveDatabase(pgObject *obj); + + wxString title, command, description; + bool database, set_password; + wxArrayString applies_to, server_types, set_env; +}; + +class pluginButtonMenuFactory : public actionFactory +{ +public: + pluginButtonMenuFactory(menuFactoryList *list, wxMenu *popupmenu, ctlMenuToolbar *toolbar, int pluginCount); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + +private: + ctlMenuButton *pulldownButton; + bool enableButton; +}; + +#endif diff --git a/include/frm/frmMainConfig.h b/include/frm/frmMainConfig.h new file mode 100644 index 0000000..1635f46 --- /dev/null +++ b/include/frm/frmMainConfig.h @@ -0,0 +1,84 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMainConfig.h - Backend configuration tool +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMMAINCONFIG_H +#define FRMMAINCONFIG_H + +#include "utils/pgconfig.h" +#include "frm/frmConfig.h" +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class ctlListView; +class pgServer; + +WX_DECLARE_OBJARRAY(pgConfigOrgLine, pgConfigOrgLineArray); + +class frmMainConfig : public frmConfig +{ +public: + frmMainConfig(const wxString &title, const wxString &configFile); + frmMainConfig(frmMain *parent, pgServer *server = 0); + + ~frmMainConfig(); + +protected: + void DisplayFile(const wxString &str); + void WriteFile(pgConn *conn = 0); + wxString GetHintString(); + wxString GetHelpPage() const; + +private: + void Init(); + void Init(pgSettingReader *reader); + void InitForm(); + + void FillList(const wxString &categoryMember, const wxString &altCategoryMember = wxEmptyString); + void FillList(wxArrayString *category); + + void OnContents(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnEditSetting(wxListEvent &event); + void OnSelectSetting(wxListEvent &event); + + void UpdateLine(int line); + + void OnOpen(wxCommandEvent &event); + + + ctlListView *cfgList; + + pgSettingItemHashmap options; + pgCategoryHashmap categories; + pgConfigOrgLineArray lines; + wxString serverVersionNumber; + + DECLARE_EVENT_TABLE() +}; + + +class mainConfigFactory : public actionFactory +{ +public: + mainConfigFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class mainConfigFileFactory : public actionFactory +{ +public: + mainConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif diff --git a/include/frm/frmMaintenance.h b/include/frm/frmMaintenance.h new file mode 100644 index 0000000..32cafba --- /dev/null +++ b/include/frm/frmMaintenance.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmMaintenance.h - Maintenance options selection dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMMAINTENANCE_H +#define FRMMAINTENANCE_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +// Class declarations +class frmMaintenance : public ExecutionDialog +{ +public: + frmMaintenance(frmMain *form, pgObject *_object); + ~frmMaintenance(); + wxString GetSql(); + + void Go(); + +private: + wxString GetHelpPage() const; + void OnAction(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +class maintenanceFactory : public contextActionFactory +{ +public: + maintenanceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmOptions.h b/include/frm/frmOptions.h new file mode 100644 index 0000000..e3e6c5a --- /dev/null +++ b/include/frm/frmOptions.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmOptions.h - The main options dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMOPTIONS_H +#define FRMOPTIONS_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class frmMain; + +class ItemWithString : public wxClientData +{ +public: + wxString data; +}; + +// Class declarations +class frmOptions : public pgDialog +{ +public: + frmOptions(frmMain *parent); + ~frmOptions(); + +private: + frmMain *mainForm; + wxString menuSelection; + + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnHelp(wxCommandEvent &ev); + void OnDefault(wxCommandEvent &ev); + void OnSuppressHints(wxCommandEvent &ev); + void OnResetHints(wxCommandEvent &ev); + void OnChangeCopyQuote(wxCommandEvent &ev); + void OnChangeSQLUseCustomColour(wxCommandEvent &ev); + void OnTreeSelChanged(wxTreeEvent &event); + wxString CheckColour(wxString colour); + void UpdateColourControls(); + wxTreeItemId GetTreeItemByLabel(const wxTreeItemId &root, const wxString &label); + void ShowPanel(const wxTreeItemId &menuItem); + DECLARE_EVENT_TABLE() +}; + + +class optionsFactory : public actionFactory +{ +public: + optionsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +#endif diff --git a/include/frm/frmPassword.h b/include/frm/frmPassword.h new file mode 100644 index 0000000..c9b8f79 --- /dev/null +++ b/include/frm/frmPassword.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPassword.h - Change password +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMPASSWORD_H +#define FRMPASSWORD_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class pgServer; +// Class declarations +class frmPassword : public pgDialog +{ +public: + frmPassword(wxFrame *parent, pgObject *obj); + ~frmPassword(); + +private: + pgServer *server; + void OnHelp(wxCommandEvent &ev); + void OnOK(wxCommandEvent &event); + void OnCancel(wxCommandEvent &event); + DECLARE_EVENT_TABLE() +}; + + +class passwordFactory : public actionFactory +{ +public: + passwordFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/frmPgpassConfig.h b/include/frm/frmPgpassConfig.h new file mode 100644 index 0000000..ac91003 --- /dev/null +++ b/include/frm/frmPgpassConfig.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmPgpassConfig.h - Pgpass.conf editor +// +////////////////////////////////////////////////////////////////////////// + +#ifndef frmPgpassConfig_H +#define frmPgpassConfig_H + +#include "frm/frmConfig.h" +#include "utils/pgconfig.h" + +class pgConn; +class pgServer; +class ctlListView; + + +WX_DECLARE_OBJARRAY(pgPassConfigLine, pgPassConfigLineArray); + +class frmPgpassConfig : public frmConfig +{ +public: + frmPgpassConfig(const wxString &title, const wxString &configFile); + frmPgpassConfig(frmMain *parent); + ~frmPgpassConfig(); + +protected: + void DisplayFile(const wxString &str); + void WriteFile(pgConn *conn = 0); + wxString GetHintString(); + wxString GetHelpPage() const; + +private: + void Init(); + void UpdateDisplay(pgPassConfigLine &line); + + void OnContents(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnDelete(wxCommandEvent &event); + void OnEditSetting(wxListEvent &event); + void OnSelectSetting(wxListEvent &event); + + ctlListView *listEdit; + pgPassConfigLineArray lines; + + + DECLARE_EVENT_TABLE() +}; + +class pgpassConfigFileFactory : public actionFactory +{ +public: + pgpassConfigFileFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +#endif diff --git a/include/frm/frmQuery.h b/include/frm/frmQuery.h new file mode 100644 index 0000000..1659183 --- /dev/null +++ b/include/frm/frmQuery.h @@ -0,0 +1,462 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmQuery.h - The SQL Query form +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRM_QUERY_H +#define __FRM_QUERY_H + +#include "ctl/ctlAuiNotebook.h" +#include "db/pgQueryResultEvent.h" +#include "dlg/dlgClasses.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbModel.h" +#include "frm/frmExport.h" +#include "utils/factory.h" +#include "utils/favourites.h" +#include "utils/macros.h" +#include +#include +#include +#include + +// wxAUI +#include +#include +#include +#include + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMQUERY_PERSPECTIVE_VER wxT("8320") +#ifdef __WXMAC__ +#define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=465;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") +#else +#ifdef __WXGTK__ +#define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=590;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=30;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") +#else +#define FRMQUERY_DEFAULT_PERSPECTIVE wxT("layout2|name=toolBar;caption=Tool bar;state=16788208;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=465;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=databaseBar;caption=Database bar;state=16788208;dir=1;layer=10;row=0;pos=396;prop=100000;bestw=300;besth=21;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=sqlQuery;caption=SQL query;state=17404;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=350;besth=200;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=outputPane;caption=Output pane;state=16779260;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=550;besth=300;minw=200;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=scratchPad;caption=Scratch pad;state=16779260;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=250;besth=200;minw=100;minh=100;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|dock_size(1,10,0)=25|dock_size(5,0,0)=200|dock_size(3,0,0)=290|dock_size(2,0,0)=255|") +#endif +#endif + +class ExplainCanvas; +class ctlSQLResult; +class pgsApplication; +class pgScriptTimer; + +class QueryExecInfo +{ +public: + QueryExecInfo() + { + toFileExportForm = NULL; + } + ~QueryExecInfo() + { + if (toFileExportForm) + delete toFileExportForm; + } + + int queryOffset; + frmExport *toFileExportForm; + bool singleResult; + bool explain; + bool verbose; +}; + +enum +{ + ORIGIN_MANUAL, + ORIGIN_FILE, + ORIGIN_INITIAL, + ORIGIN_HISTORY, + ORIGIN_GQB +}; + +class frmQuery : public pgFrame +{ +public: + frmQuery(frmMain *form, const wxString &_title, pgConn *conn, const wxString &qry, const wxString &file = wxEmptyString); + ~frmQuery(); + void Go(); + + void writeScriptOutput(); + void setExtendedTitle(); + void SetLineEndingStyle(); + + void SetQueryText(wxString str) + { + sqlQuery->SetText(str); + } + void ColouriseQuery(int start, int stop) + { + sqlQuery->Colourise(start, stop); + } + void SetChanged(bool p_changed) + { + sqlQuery->SetChanged(p_changed); + } + void SetOrigin(int p_origin) + { + sqlQuery->SetOrigin(p_origin); + } + void SetLastPath(wxString p_lastpath) + { + lastPath = p_lastpath; + } + bool CheckChanged(bool canVeto); + + void UpdateFavouritesList(); + void UpdateMacrosList(); + + void UpdateAllRecentFiles(); + void UpdateAllFavouritesList(); + void UpdateAllMacrosList(); + +private: + frmMain *mainForm; + wxAuiManager manager; + ctlSQLBox *sqlQuery; + ctlAuiNotebook *outputPane; + ctlSQLResult *sqlResult; +#define MAX_RESULT_COUNT 10 + ctlSQLResult *ctlSQL[MAX_RESULT_COUNT]; + ctlSQLBox *ctlSBox[MAX_RESULT_COUNT]; + int indexResult; + ExplainCanvas *explainCanvas; + wxTextCtrl *msgResult, *msgHistory; + wxBitmapComboBox *cbConnection; + wxButton *btnModeTransaction; + wxTextCtrl *scratchPad; + wxComboBox *sqlQueries; + wxButton *btnDeleteCurrent; + wxButton *btnDeleteAll; + wxArrayString histoQueries; + wxArrayString def_func; + wxArrayString name_func; + ctlAuiNotebook *sqlQueryBook; //container for all SQL tabs + size_t sqlQueryCounter; //for initial tab names + ctlSQLBox *sqlQueryExec; //currently executing SQL tab + ctlSQLBox *sqlQueryExecLast; //output pane shows results for this SQL tab + + // Query timing/status update + wxTimer timer; + wxLongLong elapsedQuery, startTimeQuery; + + // pgScript interface + pgsApplication *pgScript; + wxString pgsOutputString; + wxStringOutputStream pgsStringOutput; + wxTextOutputStream pgsOutput; + pgScriptTimer *pgsTimer; + wxString *querys; + //GQB related + void OnChangeNotebook(wxAuiNotebookEvent &event); + void OnChangeNotebookOutpane(wxAuiNotebookEvent &event); + void OnAdjustSizesTimer(wxTimerEvent &event); + void OnResizeHorizontally(wxSplitterEvent &event); + void adjustGQBSizes(); + bool updateFromGqb(bool executing); + ctlAuiNotebook *sqlNotebook; + gqbModel *model; + gqbController *controller; + bool firstTime; + bool gqbUpdateRunning; + wxTimer *adjustSizesTimer; + + // Our connection + pgConn *conn; + + // These status flags are required to work round some wierdness on wxGTK, + // particularly on Solaris. + bool closing, loading; + + void OnEraseBackground(wxEraseEvent &event); + void OnSize(wxSizeEvent &event); + + void OnChangeStc(wxStyledTextEvent &event); + void OnPositionStc(wxStyledTextEvent &event); + void OnLabelRightClick(wxGridEvent &event); + void OnCellLeftDClick(wxGridEvent &event); + void OnClose(wxCloseEvent &event); + void OnSetFocus(wxFocusEvent &event); + void OnContents(wxCommandEvent &event); + void OnHelp(wxCommandEvent &event); + void OnCancel(wxCommandEvent &event); + void OnExecute(wxCommandEvent &event); + void OnExecuteShift(wxCommandEvent &event); + void OnExecScript(wxCommandEvent &event); + void OnExecFile(wxCommandEvent &event); + void OnExplain(wxCommandEvent &event); + void OnCommit(wxCommandEvent &event); + void OnRollback(wxCommandEvent &event); + void OnBuffers(wxCommandEvent &event); + void OnTiming(wxCommandEvent &event); + void OnNew(wxCommandEvent &event); + void OnOpen(wxCommandEvent &event); + void OnSave(wxCommandEvent &event); + void OnSaveAs(wxCommandEvent &event); + void SaveExplainAsImage(wxCommandEvent &event); + void OnExport(wxCommandEvent &event); + void OnExit(wxCommandEvent &event); + void OnCut(wxCommandEvent &event); + void OnCopy(wxCommandEvent &event); + void OnPaste(wxCommandEvent &event); + void OnClear(wxCommandEvent &event); + void OnSummary_Column(wxCommandEvent &event); + void OnCopy_Insert(wxCommandEvent &event); + void OnClear_Filter(wxCommandEvent &event); + void OnSearchReplace(wxCommandEvent &event); + void OnUndo(wxCommandEvent &event); + void OnRedo(wxCommandEvent &event); + void OnSaveHistory(wxCommandEvent &event); + void OnAutoSelectQuery(wxCommandEvent &event); + void SelectQuery(); + void OnAutoRollback(wxCommandEvent &event); + void OnAutoCommit(wxCommandEvent &event); + void OnChangeConnection(wxCommandEvent &ev); + void OnClearHistory(wxCommandEvent &event); + void OnActivate(wxActivateEvent &event); + void OnFocus(wxFocusEvent &event); + void OnSelectAll(wxCommandEvent &event); + void OnAddFavourite(wxCommandEvent &event); + void OnInjectFavourite(wxCommandEvent &event); + void OnManageFavourites(wxCommandEvent &event); + void OnSelectFavourite(wxCommandEvent &event); + void OnQuickReport(wxCommandEvent &event); + void OnAutoIndent(wxCommandEvent &event); + void OnWordWrap(wxCommandEvent &event); + void OnShowIndentGuides(wxCommandEvent &event); + void OnShowWhitespace(wxCommandEvent &event); + void OnShowLineEnds(wxCommandEvent &event); + void OnShowLineNumber(wxCommandEvent &event); + + void OnToggleScratchPad(wxCommandEvent &event); + void OnToggleDatabaseBar(wxCommandEvent &event); + void OnToggleToolBar(wxCommandEvent &event); + void OnToggleOutputPane(wxCommandEvent &event); + void OnAuiUpdate(wxAuiManagerEvent &event); + void OnDefaultView(wxCommandEvent &event); + void OnBlockIndent(wxCommandEvent &event); + void OnBlockOutDent(wxCommandEvent &event); + void OnChangeToUpperCase(wxCommandEvent &event); + void OnChangeToLowerCase(wxCommandEvent &event); + void OnCommentText(wxCommandEvent &event); + void OnUncommentText(wxCommandEvent &event); + void OnExternalFormat(wxCommandEvent &event); + + void OnDeleteCurrent(wxCommandEvent &event); + void OnDeleteAll(wxCommandEvent &event); + void OnModeTransaction(wxCommandEvent &event); + + void OnTimer(wxTimerEvent &event); + + void OpenLastFile(); + void SaveTempFile(); + void updateMenu(bool allowUpdateModelSize = true); + void execQuery(const wxString &query, int resultToRetrieve = 0, bool singleResult = false, const int queryOffset = 0, bool toFile = false, bool explain = false, bool verbose = false); + void OnQueryComplete(pgQueryResultEvent &ev); + void completeQuery(bool done, bool explain, bool verbose); + bool isBeginNotRequired(wxString query); + void OnScriptComplete(wxCommandEvent &ev); + void setTools(const bool running); + void showMessage(const wxString &msg, const wxString &msgShort = wxT("")); + int GetLineEndingStyle(); + void OnSetEOLMode(wxCommandEvent &event); + void OnAutoEditObject(wxCommandEvent &event); + void SetEOLModeDisplay(int mode); + void OnMacroInvoke(wxCommandEvent &event); + void OnMacroManage(wxCommandEvent &event); + void OnAutoReplaceManage(wxCommandEvent &event); + void LoadQueries(); + void SaveQueries(); + void OnChangeQuery(wxCommandEvent &event); + + wxBitmap CreateBitmap(const wxColour &colour); + wxColour GetServerColour(pgConn *connection); + + bool relatesToWindow(wxWindow *which, wxWindow *related); + + // Methods related to SQL tabs + void SqlBookAddPage(); + bool SqlBookRemovePage(); + bool SqlBookCanChangePage(); + void SqlBookSetAutoIndent(bool b); + void SqlBookSetWrapMode(bool b); + void SqlBookSetIndentGuides(bool b); + void SqlBookSetViewWhiteSpace(bool b); + void SqlBookSetViewEOL(bool b); + void SqlBookSetViewLineNumbers(bool b); + void SqlBookSetDatabase(pgConn *con); + void SqlBookUpdatePageTitle(); + void SqlBookDisconnectPage(ctlSQLBox *box = NULL); + bool SqlBookClose(bool canVeto); + // SQL tabs event handlers + void OnSqlBookAddPage(wxCommandEvent &event); + void OnSqlBookPageClose(wxAuiNotebookEvent &event); + void OnSqlBookPageClosed(wxAuiNotebookEvent &event); + void OnSqlBookPageChanged(wxAuiNotebookEvent &event); + void OnSqlBookPageChanging(wxAuiNotebookEvent &event); + void OnSqlBookTabRDown(wxAuiNotebookEvent &event); + void OnNotebookOutpaneTabRDown(wxAuiNotebookEvent &event); + + void BeginPerspectiveChange(); + void EndPerspectiveChange(bool update = false); + void SetOutputPaneCaption(bool update = false); + + wxWindow *currentControl(); + wxMenu *queryMenu; + wxMenu *favouritesMenu; + wxMenu *macrosMenu; + wxMenu *lineEndMenu; + wxMenu *formatMenu; + wxMenu *saveasImageMenu; + + wxString title; + wxString lastFilename, lastDir; + + queryFavouriteFolder *favourites; + queryMacroList *macros; + queryMacroList *autoreplace; + bool isfilterresult; + bool aborted; + bool lastFileFormat; + bool m_loadingfile; + + // A simple mutex-like flag to prevent concurrent script execution. + // Required because the pgScript parser isn't currently thread-safe :-( + static bool ms_pgScriptRunning; + + DECLARE_EVENT_TABLE() +}; + +// Position of status line fields +enum +{ + STATUSPOS_MSGS = 1, + STATUSPOS_FORMAT, + STATUSPOS_POS, + STATUSPOS_SEL, + STATUSPOS_ROWS, + STATUSPOS_SECS +}; + +enum +{ + CTL_SQLQUERY = 331, + CTL_SQLRESULT, + CTL_MSGRESULT, + CTL_MSGHISTORY, + CTL_NTBKCENTER, + CTL_COLSGRID, + CTL_TIMERSIZES, + CTL_TIMERFRM, + CTL_NTBKGQB, + CTL_SQLQUERYCBOX, + CTL_DELETECURRENTBTN, + CTL_DELETEALLBTN, + CTL_SCRATCHPAD +}; + +/////////////////////////////////////////////////////// + +class queryToolBaseFactory : public actionFactory +{ +protected: + queryToolBaseFactory(menuFactoryList *list) : actionFactory(list) {} + wxWindow *StartDialogSql(frmMain *form, pgObject *obj, const wxString &sql); +public: + bool CheckEnable(pgObject *obj); +}; + +class queryToolDataFactory : public queryToolBaseFactory +{ +protected: + queryToolDataFactory(menuFactoryList *list) : queryToolBaseFactory(list) {} +public: + bool CheckEnable(pgObject *obj); +}; + +class queryToolFactory : public queryToolBaseFactory +{ +public: + queryToolFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + +class queryToolSqlFactory : public queryToolBaseFactory +{ +public: + queryToolSqlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolSelectFactory : public queryToolDataFactory +{ +public: + queryToolSelectFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolExecFactory : public queryToolDataFactory +{ +public: + queryToolExecFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolDeleteFactory : public queryToolDataFactory +{ +public: + queryToolDeleteFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolInsertFactory : public queryToolDataFactory +{ +public: + queryToolInsertFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolUpdateFactory : public queryToolDataFactory +{ +public: + queryToolUpdateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class queryToolCreateCascadeFactory : public queryToolDataFactory +{ +public: + queryToolCreateCascadeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + wxArrayString GetArrayList(wxString *strobj); +}; + +/////////////////////////////////////////////////////// +class pgScriptTimer : public wxTimer +{ +private: + frmQuery *m_parent; + +public: + pgScriptTimer(frmQuery *parent); + void Notify(); +}; + +#endif // __FRM_QUERY_H diff --git a/include/frm/frmReport.h b/include/frm/frmReport.h new file mode 100644 index 0000000..3eb0bbf --- /dev/null +++ b/include/frm/frmReport.h @@ -0,0 +1,240 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmReport.h - The report file dialogue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FRMREPORT_H +#define FRMREPORT_H + +#include "dlg/dlgClasses.h" +#include "ctl/ctlListView.h" +#include "ctl/ctlSQLResult.h" +#include "schema/pgDatabase.h" +#include + +// Class declarations +class frmReport : public pgDialog +{ +public: + frmReport(wxWindow *p); + ~frmReport(); + + void SetReportTitle(const wxString &t); + + void XmlAddHeaderValue(const wxString &name, const wxString &value); + int XmlCreateSection(const wxString &name); + void XmlSetSectionTableHeader(const int section, const int columns, const wxChar *name, ...); + void XmlAddSectionTableRow(const int section, const int number, const int columns, const wxChar *value, ...); + void XmlAddSectionTableFromListView(const int section, ctlListView *list); + void XmlAddSectionTableFromGrid(const int section, ctlSQLResult *grid); + void XmlSetSectionTableInfo(const int section, const wxString &info) + { + sectionTableInfo[section - 1] = info; + }; + void XmlSetSectionSql(int section, const wxString &sql); + void XmlAddSectionValue(const int section, const wxString &name, const wxString &value); + +private: + void OnChange(wxCommandEvent &ev); + void OnHelp(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnCancel(wxCommandEvent &ev); + void OnBrowseFile(wxCommandEvent &ev); + void OnBrowseStylesheet(wxCommandEvent &ev); + + wxString GetSectionTableColumns(const int section); + wxString GetSectionTableRows(const int section); + wxString GetSectionTable(const int section); + wxString GetSection(const int section); + wxString GetXmlReport(const wxString &stylesheet); + wxString XslProcessReport(const wxString &xml, const wxString &xsl); + + wxString GetCssLink(const wxString &file); + wxString GetEmbeddedCss(const wxString &css); + const wxString GetDefaultCss(); + wxString GetDefaultXsl(const wxString &css); + + wxWindow *parent; + wxString header; + wxArrayString sectionName, sectionData, sectionTableHeader, sectionTableRows, sectionTableInfo, sectionSql; + + DECLARE_EVENT_TABLE() +}; + +/////////////////////////////////////////////////////// +// Report Factory base class +/////////////////////////////////////////////////////// +class reportBaseFactory : public actionFactory +{ +protected: + reportBaseFactory(menuFactoryList *list) : actionFactory(list) {} + wxWindow *StartDialog(frmMain *form, pgObject *obj); + frmMain *GetFrmMain() + { + return parent; + }; + virtual void GenerateReport(frmReport *report, pgObject *object) {}; + + frmMain *parent; +public: + bool CheckEnable(pgObject *obj) + { + return false; + }; +}; +class SQL; + +WX_DECLARE_LIST(SQL, MyListSql); +WX_DECLARE_OBJARRAY(SQL, ArraySQL); + +class SQL { + public: + // One of: INSERT, DELETE or EQUAL. + wxString sql; + wxString sql2; + wxString pathtree; + int countchild,mode; + // The text associated with this diff operation. + + /** + * Constructor. Initializes the diff with the provided values. + * @param operation One of INSERT, DELETE or EQUAL. + * @param text The text being applied. + */ + SQL(const wxString &_sql, const wxString &_pathtree); + SQL(); +// inline bool isNull() const; + wxString toString() const; + bool operator==(const SQL &d) const; + bool operator!=(const SQL &d) const; + + //static wxString strOperation(Operation op); +}; + +WX_DECLARE_STRING_HASH_MAP( int, MyHashSQL ); + +#define __Remove 1 +#define __Equal 0 +#define __Insert 2 + +class reportCompareFactory : public actionFactory +{ +private: + wxString titleline; + wxString list_head; + wxString rowlist; + wxString list_end; + wxString tableheader; + wxString head; + wxString tableheader2; + wxString tableshtml; + int startpathpos,countdiffline; + short Diff_EditCost; + float Match_Threshold; + int Match_Distance; +protected: + //reportCompareFactory(menuFactoryList *list) : actionFactory(list) {} + wxString reportCompareFactory::GetNodePath(wxTreeItemId node); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + void reportCompareFactory::GetExpandedChildNodes(wxTreeItemId node, wxArrayString &expandedNodes, ArraySQL &list,time_t *t,wxBusyInfo *w, MyHashSQL &h_path,int lvl); + std::wstring reportCompareFactory::printdiff(std::wstring str1, std::wstring str2 ); + wxString printlvl(int element,int lvl,ArraySQL &list, wxHashTable &htab); + frmMain *GetFrmMain() + { + return parent; + }; + frmMain *parent; +public: + reportCompareFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar): actionFactory(list) { + mnu->Append(id, _("&Compare other objects"), _("Compare other host database select objects.")); + }; + bool CheckEnable(pgObject *obj) + { + return true; + }; +}; + +/////////////////////////////////////////////////////// +// Object properties report +/////////////////////////////////////////////////////// +class reportObjectPropertiesFactory : public reportBaseFactory +{ +public: + reportObjectPropertiesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object DDL report +/////////////////////////////////////////////////////// +class reportObjectDdlFactory : public reportBaseFactory +{ +public: + reportObjectDdlFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object Data dictionary report +/////////////////////////////////////////////////////// +class reportObjectDataDictionaryFactory : public reportBaseFactory +{ +public: + reportObjectDataDictionaryFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object statistics report +/////////////////////////////////////////////////////// +class reportObjectStatisticsFactory : public reportBaseFactory +{ +public: + reportObjectStatisticsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object dependencies report +/////////////////////////////////////////////////////// +class reportObjectDependenciesFactory : public reportBaseFactory +{ +public: + reportObjectDependenciesFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object Dependents report +/////////////////////////////////////////////////////// +class reportObjectDependentsFactory : public reportBaseFactory +{ +public: + reportObjectDependentsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +/////////////////////////////////////////////////////// +// Object list report +/////////////////////////////////////////////////////// +class reportObjectListFactory : public reportBaseFactory +{ +public: + reportObjectListFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + bool CheckEnable(pgObject *obj); + void GenerateReport(frmReport *report, pgObject *object); +}; + +#endif diff --git a/include/frm/frmRestore.h b/include/frm/frmRestore.h new file mode 100644 index 0000000..3d6c6f6 --- /dev/null +++ b/include/frm/frmRestore.h @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmRestore.h - Restore database dialogue +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef FRMRESTORE_H +#define FRMRESTORE_H + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" + +class pgServer; +class frmRestore : public ExternProcessDialog +{ +public: + frmRestore(frmMain *_form, pgObject *_object); + ~frmRestore(); + + void Go(); + wxString GetDisplayCmd(int step); + wxString GetCmd(int step); + +private: + wxString GetHelpPage() const; + void OnChangeName(wxCommandEvent &ev); + void OnChange(wxCommandEvent &ev); + void OnSelectFilename(wxCommandEvent &ev); + void OnView(wxCommandEvent &ev); + void OnOK(wxCommandEvent &ev); + void OnChangeFormat(wxCommandEvent &ev); + void OnChangeData(wxCommandEvent &ev); + void OnChangeSchema(wxCommandEvent &ev); + void OnChangeSection(wxCommandEvent &ev); + void OnChangeList(wxListEvent &ev); + void OnEndProcess(wxProcessEvent &event); + + wxString getCmdPart1(); + wxString getCmdPart2(int step); + + frmMain *form; + pgObject *object; + pgServer *server; + bool viewRunning, filenameValid; + wxString processedFile; + wxString restoreExecutable; + wxString restoreTOCFilename; + int numberOfTOCItems; + + DECLARE_EVENT_TABLE() +}; + + +class restoreFactory : public contextActionFactory +{ +public: + restoreFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class restoreTreeItemData : public wxTreeItemData +{ +public: + restoreTreeItemData(int id, const wxString &desc); + + int GetId() + { + return restoreId; + } + wxString GetDesc() + { + return restoreDesc; + } + +private: + int restoreId; + wxString restoreDesc; +}; + + + +#endif diff --git a/include/frm/frmSplash.h b/include/frm/frmSplash.h new file mode 100644 index 0000000..83875e5 --- /dev/null +++ b/include/frm/frmSplash.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmSplash.h - Splash Screen +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SPLASH_H +#define SPLASH_H + +// Class declarations +class frmSplash : public wxFrame +{ +public: + frmSplash(wxFrame *parent); + void OnPaint(wxPaintEvent &); + +private: + void SetWindowShape(); + void OnWindowCreate(wxWindowCreateEvent &WXUNUSED(evt)); + + wxBitmap splash; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/frm/frmStatus.h b/include/frm/frmStatus.h new file mode 100644 index 0000000..d0dc020 --- /dev/null +++ b/include/frm/frmStatus.h @@ -0,0 +1,264 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// frmStatus.h - Status Screen +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __FRMSTATUS_H +#define __FRMSTATUS_H + +// wxWindows headers +#include +#include +#include +#include +#include + +// wxAUI +#include + +#include "dlg/dlgClasses.h" +#include "utils/factory.h" +#include "ctl/ctlAuiNotebook.h" + +enum +{ + CTL_RATECBO = 250, + CTL_REFRESHBTN, + CTL_CANCELBTN, + CTL_TERMINATEBTN, + CTL_COMMITBTN, + CTL_ROLLBACKBTN, + CTL_LOGCBO, + CTL_ROTATEBTN, + CTL_STATUSLIST, + CTL_LOCKLIST, + CTL_XACTLIST, + CTL_LOGLIST, + CTL_QUERYSTATELIST, + MNU_STATUSPAGE, + MNU_LOCKPAGE, + MNU_XACTPAGE, + MNU_LOGPAGE, + MNU_QUERYSTATEPAGE, + MNU_TERMINATE, + MNU_COMMIT, + MNU_ROLLBACK, + MNU_COPY_QUERY, + MNU_COPY_QUERY_PLAN, + MNU_HIGHLIGHTSTATUS, + MNU_QUERYSTATEVERBOSE, + MNU_QUERYSTATETIME, + MNU_QUERYSTATEBUFFER, + MNU_QUERYSTATETRIGGER, + TIMER_REFRESHUI_ID, + TIMER_STATUS_ID, + TIMER_LOCKS_ID, + TIMER_XACT_ID, + TIMER_LOG_ID, + TIMER_QUERYSTATE_ID +}; + + +enum +{ + PANE_STATUS = 1, + PANE_LOCKS, + PANE_XACT, + PANE_LOG, + PANE_QUERYSTATE +}; + + +// +// This number MUST be incremented if changing any of the default perspectives +// +#define FRMSTATUS_PERSPECTIVE_VER wxT("8274") + +#ifdef __WXMAC__ +#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=321;besth=244;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=462;floaty=165;floatw=595;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=321;besth=244;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-231;floaty=235;floatw=595;floath=282|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=0;pos=2;prop=100000;bestw=0;besth=0;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=461;floaty=527;floatw=595;floath=282|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=0;besth=0;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-103;floaty=351;floatw=595;floath=282|name=toolBar;caption=Tool bar;state=2124528;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=808;besth=33;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=888;floaty=829;floatw=558;floath=49|dock_size(4,0,0)=583|dock_size(5,0,0)=10|dock_size(1,10,0)=35|") +#else +#ifdef __WXGTK__ +#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=716;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22|") +#else +#define FRMSTATUS_DEFAULT_PERSPECTIVE wxT("layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=716;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22|") +#endif +#endif + + +static wxCriticalSection gs_critsect; + + +// Class declarations + +class frmStatus : public pgFrame +{ +public: + frmStatus(frmMain *form, const wxString &_title, pgConn *conn); + ~frmStatus(); + void Go(); + +private: + wxAuiManager manager; + + frmMain *mainForm; + pgConn *connection, *locks_connection; + + wxString logFormat; + bool logHasTimestamp, logFormatKnown; + int logFmtPos; + + wxDateTime logfileTimestamp, latestTimestamp; + wxString logDirectory, logfileName; + + wxString savedPartialLine; + + bool showCurrent, isCurrent; + + long backend_pid; + int wait_event_type_col; + + bool loaded; + long logfileLength; + + int currentPane; + + int statusSortColumn; + wxString statusSortOrder; + int lockSortColumn; + wxString lockSortOrder; + int xactSortColumn; + wxString xactSortOrder; + + wxComboBox *cbRate; + wxComboBox *cbLogfiles; + wxButton *btnRotateLog; + ctlComboBoxFix *cbDatabase; + + wxTimer *refreshUITimer; + wxTimer *statusTimer, *locksTimer, *xactTimer, *logTimer, *querystateTimer; + int statusRate, locksRate, xactRate, logRate, querystateRate; + + ctlListView *statusList; + ctlListView *lockList; + ctlListView *xactList; + ctlListView *logList; + ctlListView *querystateList; + + wxMenu *actionMenu; + wxMenu *statusPopupMenu; + wxMenu *lockPopupMenu; + wxMenu *xactPopupMenu; + wxMenu *querystatePopupMenu; + wxString queryplan; + wxArrayString queries; + + int statusColWidth[12], lockColWidth[10], xactColWidth[5], querystateColWidth[5]; + + int cboToRate(); + wxString rateToCboString(int rate); + + wxImageList *listimages; + long getlongvalue(wxString source,wxString match_str); + void AddStatusPane(); + void AddLockPane(); + void AddXactPane(); + void AddLogPane(); + void AddQuerystatePane(); + + void OnHelp(wxCommandEvent &ev); + void OnContents(wxCommandEvent &ev); + void OnExit(wxCommandEvent &event); + + void OnCopy(wxCommandEvent &ev); + void OnCopyQuery(wxCommandEvent &ev); + + void OnToggleStatusPane(wxCommandEvent &event); + void OnToggleLockPane(wxCommandEvent &event); + void OnToggleXactPane(wxCommandEvent &event); + void OnToggleLogPane(wxCommandEvent &event); + void OnToggleQuerystatePane(wxCommandEvent &event); + void OnEmptyAction(wxCommandEvent &event); + + void OnToggleToolBar(wxCommandEvent &event); + void OnDefaultView(wxCommandEvent &event); + void OnHighlightStatus(wxCommandEvent &event); + + void OnRefreshUITimer(wxTimerEvent &event); + void OnRefreshStatusTimer(wxTimerEvent &event); + void OnRefreshLocksTimer(wxTimerEvent &event); + void OnRefreshXactTimer(wxTimerEvent &event); + void OnRefreshLogTimer(wxTimerEvent &event); + void OnRefreshQuerystateTimer(wxTimerEvent &event); + + void SetColumnImage(ctlListView *list, int col, int image); + void OnSortStatusGrid(wxListEvent &event); + void OnSortLockGrid(wxListEvent &event); + void OnSortXactGrid(wxListEvent &event); + + void OnRightClickStatusGrid(wxListEvent &event); + void OnRightClickLockGrid(wxListEvent &event); + void OnRightClickXactGrid(wxListEvent &event); + void OnRightClickQuerystateGrid(wxListEvent &event); + + void OnStatusMenu(wxCommandEvent &event); + void OnLockMenu(wxCommandEvent &event); + void OnXactMenu(wxCommandEvent &event); + void OnQuerystateMenu(wxCommandEvent &event); + + void OnChgColSizeStatusGrid(wxListEvent &event); + void OnChgColSizeLockGrid(wxListEvent &event); + void OnChgColSizeXactGrid(wxListEvent &event); + void OnChgColSizeQuerystateGrid(wxListEvent &event); + + void OnRateChange(wxCommandEvent &event); + + void OnPaneClose(wxAuiManagerEvent &evt); + + void OnClose(wxCloseEvent &event); + void OnRefresh(wxCommandEvent &event); + void OnCancelBtn(wxCommandEvent &event); + void OnStatusCancelBtn(wxCommandEvent &event); + void OnLocksCancelBtn(wxCommandEvent &event); + void OnTerminateBtn(wxCommandEvent &event); + void OnStatusTerminateBtn(wxCommandEvent &event); + void OnLocksTerminateBtn(wxCommandEvent &event); + void OnSelStatusItem(wxListEvent &event); + void OnSelLockItem(wxListEvent &event); + void OnSelXactItem(wxListEvent &event); + void OnSelLogItem(wxListEvent &event); + void OnSelQuerystateItem(wxListEvent &event); + void OnLoadLogfile(wxCommandEvent &event); + void OnRotateLogfile(wxCommandEvent &event); + void OnCommit(wxCommandEvent &event); + void OnRollback(wxCommandEvent &event); + + void OnChangeDatabase(wxCommandEvent &ev); + + int fillLogfileCombo(); + void emptyLogfileCombo(); + + void addLogFile(wxDateTime *dt, bool skipFirst); + void addLogFile(const wxString &filename, const wxDateTime timestamp, long len, long &read, bool skipFirst); + void addLogLine(const wxString &str, bool formatted = true, bool csv_log_format = false); + + void checkConnection(); + + DECLARE_EVENT_TABLE() +}; + + +class serverStatusFactory : public actionFactory +{ +public: + serverStatusFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/frm/lib.txt b/include/frm/lib.txt new file mode 100644 index 0000000..19cdf49 --- /dev/null +++ b/include/frm/lib.txt @@ -0,0 +1 @@ +layout2|name=Activity;caption=Activity;state=6293500;dir=4;layer=0;row=1;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=174;floaty=216;floatw=578;floath=282|name=Locks;caption=Locks;state=6293500;dir=4;layer=0;row=1;pos=2;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=136;floaty=339;floatw=576;floath=283|name=Transactions;caption=Transactions;state=6293500;dir=4;layer=0;row=1;pos=3;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=133;floaty=645;floatw=577;floath=283|name=Querystate;caption=Query State;state=6309884;dir=4;layer=0;row=1;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=154;floaty=255;floatw=1360;floath=751|name=Logfile;caption=Logfile;state=6293500;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1|name=toolBar;caption=toolBar;state=2108144;dir=1;layer=10;row=0;pos=0;prop=100000;bestw=716;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=586;floaty=525;floatw=483;floath=49|dock_size(1,10,0)=25|dock_size(4,0,1)=1115|dock_size(5,0,0)=22| \ No newline at end of file diff --git a/include/frm/menu.h b/include/frm/menu.h new file mode 100644 index 0000000..b575fe6 --- /dev/null +++ b/include/frm/menu.h @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.h - Miscellaneous Utilties +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __MENU_H +#define __MENU_H + +// Menu options +enum +{ + MNU_ADDSERVER = 101, + MNU_SAVEDEFINITION, + MNU_EXIT, + MNU_SAVEAS_IMAGE_GQB, + MNU_SAVEAS_IMAGE_EXPLAIN, + MNU_CONTEXTMENU, + MNU_SQLPANE, + MNU_OBJECTBROWSER, + MNU_TOOLBAR, + MNU_LIMITBAR, + MNU_DATABASEBAR, + MNU_SCRATCHPAD, + MNU_OUTPUTPANE, + MNU_DEFAULTVIEW, + MNU_BACK, + MNU_FORWARD, + MNU_REFRESH, + + MNU_ADDCOLUMN, + MNU_CLOSE, + MNU_MIN, + MNU_RECORD, + MNU_STOP, + MNU_APPEND, + MNU_DELETE, + MNU_OPEN, + MNU_SAVE, + MNU_SAVEAS, + MNU_NEWSQLTAB, + MNU_EXPORT, + MNU_OPTIONS, + MNU_CUT, + MNU_COPY, + MNU_INCLUDEFILTER, + MNU_EXCLUDEFILTER, + MNU_REMOVEFILTERS, + MNU_ASCSORT, + MNU_DESCSORT, + MNU_REMOVESORT, + MNU_PASTE, + MNU_CLEAR, + MNU_FIND, + MNU_REPLACE, + MNU_UNDO, + MNU_REDO, + MNU_CANCEL, + MNU_EXECUTE, + MNU_EXECUTE_2, + MNU_EXECFILE, + MNU_EXPLAIN, + MNU_EXPLAINANALYZE, + MNU_EXPLAINOPTIONS, + MNU_DOCOMMIT, + MNU_DOROLLBACK, + MNU_VERBOSE, + MNU_COSTS, + MNU_BUFFERS, + MNU_TIMING, + MNU_AUTOSELECTQUERY, + MNU_SUMMARY_COL, + MNU_COPY_INSERT, + MNU_CLEAR_FILTER, + MNU_AUTOROLLBACK, + MNU_AUTOCOMMIT, + MNU_CLEARHISTORY, + MNU_SAVEHISTORY, + MNU_CHECKALIVE, + MNU_SELECTALL, + MNU_EXECPGS, + + MNU_CONTENTS, + MNU_HELP, + MNU_HINT, + + MNU_CONFIGSUBMENU, + MNU_SLONY_SUBMENU, + + MNU_ONLINEUPDATE_NEWDATA, + + MNU_AUTOCOMPLETE, + MNU_AUTOINDENT, + MNU_WORDWRAP, + MNU_SHOWWHITESPACE, + MNU_SHOWLINEENDS, + MNU_SHOWLINENUMBER, + MNU_SHOWINDENTGUIDES, + MNU_QUICKREPORT, + + MNU_UPPER_CASE, + MNU_LOWER_CASE, + MNU_BLOCK_INDENT, + MNU_BLOCK_OUTDENT, + MNU_COMMENT_TEXT, + MNU_UNCOMMENT_TEXT, + MNU_EXTERNALFORMAT, + + MNU_PLUGINBUTTONLIST, + + MNU_LINEENDS, + MNU_CR, + MNU_CRLF, + MNU_LF, + + MNU_ADDTABLE, + MNU_DELETETABLE, + MNU_GENERATEDIAGRAM, + MNU_GENERATEMODEL, + MNU_SAVEMODEL, + MNU_SAVEMODELAS, + MNU_LOADMODEL, + MNU_NEWDIAGRAM, + MNU_DELDIAGRAM, + MNU_RENDIAGRAM, + MNU_CHGFONT, + MNU_TOGGLEDDSQL, + MNU_TOGGLEMBROWSER, + MNU_AUTOREPLACE_MANAGE, + MNU_AUTOEDITOBJECT, + MNU_RECENT, + MNU_NEW = MNU_RECENT + 15, // leave space for recent file entries + + MNU_ACTION = MNU_NEW + 1000, // leave space for objects + + MNU_FAVOURITES_ADD = MNU_ACTION + 1000, // leave space for actions + MNU_FAVOURITES_INJECT, + MNU_FAVOURITES_MANAGE, + + MNU_MACROS_MANAGE = MNU_FAVOURITES_MANAGE + 1000, //leave space for favourites + + // This is used by the Query Tool - the event is fired when the query completes + QUERY_COMPLETE = MNU_MACROS_MANAGE + 100, + PGSCRIPT_COMPLETE, + + // This is a dummy menu item + MNU_DUMMY = QUERY_COMPLETE + 1000, + + //Menu Test + MNU_GENERATESQL +}; + +#endif diff --git a/include/frm/module.mk b/include/frm/module.mk new file mode 100644 index 0000000..7ea5fd0 --- /dev/null +++ b/include/frm/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/frm/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/frm/frmAbout.h \ + include/frm/frmBackup.h \ + include/frm/frmBackupGlobals.h \ + include/frm/frmBackupServer.h \ + include/frm/frmConfig.h \ + include/frm/frmDatabaseDesigner.h \ + include/frm/frmEditGrid.h \ + include/frm/frmExport.h \ + include/frm/frmGrantWizard.h \ + include/frm/frmHbaConfig.h \ + include/frm/frmHint.h \ + include/frm/frmImport.h \ + include/frm/frmMain.h \ + include/frm/frmMainConfig.h \ + include/frm/frmMaintenance.h \ + include/frm/frmOptions.h \ + include/frm/frmPassword.h \ + include/frm/frmPgpassConfig.h \ + include/frm/frmQuery.h \ + include/frm/frmReport.h \ + include/frm/frmRestore.h \ + include/frm/frmSplash.h \ + include/frm/frmStatus.h \ + include/frm/menu.h + +EXTRA_DIST += \ + include/frm/module.mk + diff --git a/include/gqb/gqbArrayCollection.h b/include/gqb/gqbArrayCollection.h new file mode 100644 index 0000000..1298e85 --- /dev/null +++ b/include/gqb/gqbArrayCollection.h @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbArrayCollection.h - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBARRAYCOLLECTION_H +#define GQBARRAYCOLLECTION_H + +// App headers +#include "gqb/gqbCollectionBase.h" + +WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); + +class gqbArrayIterator : public gqbIteratorBase +{ +public: + gqbArrayIterator(gqbObjsArray *gqbPtrsArray); + gqbObject *Next(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + gqbObjsArray *internalArray; +}; + +class gqbArrayDownIterator : public gqbIteratorBase +{ +public: + gqbArrayDownIterator(gqbObjsArray *gqbPtrsArray); + gqbObject *Next(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + gqbObjsArray *internalArray; +}; + +//Create Array Objects used as base for gqbCollections +class gqbArrayCollection : public gqbCollectionBase +{ +public: + ~gqbArrayCollection(); + void addItem(gqbObject *item); + void removeItem(gqbObject *item); + gqbIteratorBase *createIterator(); + gqbIteratorBase *createDownIterator(); + gqbObject *getItemAt(int index); + int count(); + bool existsObject(gqbObject *item); + int getIndex(gqbObject *item); + void insertAtIndex(gqbObject *item, int index); + void deleteAll(); + void removeAll(); + gqbObject *&operator[](size_t index) + { + return gqbArray[index]; + } + +private: + gqbObjsArray gqbArray; +}; +#endif diff --git a/include/gqb/gqbBrowser.h b/include/gqb/gqbBrowser.h new file mode 100644 index 0000000..b19ff39 --- /dev/null +++ b/include/gqb/gqbBrowser.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbBrowser.h - Tables Tree of GQB. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBBROWSER_H +#define GQBBROWSER_H + +enum gqbImages +{ + GQB_IMG_DATABASE = 0, + GQB_IMG_NAMESPACE = 1, + GQB_IMG_TABLE = 2, + GQB_IMG_NAMESPACES = 3, + GQB_IMG_CATALOGS = 4, + GQB_IMG_CATALOG = 5, + GQB_IMG_CATALOG_OBJ = 6, + GQB_IMG_VIEW = 7, + GQB_IMG_EXTTABLE = 8 +}; + +class gqbController; + +class gqbBrowser : public wxTreeCtrl +{ +public: + gqbBrowser(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, gqbController *_controller); + ~gqbBrowser(); + wxTreeItemId &createRoot(wxString &Name); + wxTreeItemId &getCatalogRootNode() + { + return catalogsNode; + } + wxTreeItemId &getTablesRootNode() + { + return schemasNode; + } + void refreshTables(pgConn *connection); + void setDnDPoint(int x, int y) + { + xx = x; + yy = y; + }; + +private: + enum typeSchema // GQB-TODO: DELETE from here should be locate at gqbDatabase + { + GQB_CATALOG, + GQB_OTHER + }; + + wxTreeItemId rootNode, catalogsNode, schemasNode; + void OnItemActivated(wxTreeEvent &event); + void OnBeginDrag(wxTreeEvent &event); + wxString NumToStr(OID value); + gqbController *controller; //Allow access to controller functions like add table to model + wxImageList *imageList; + int xx, yy; + + DECLARE_EVENT_TABLE() +}; +#endif diff --git a/include/gqb/gqbCollection.h b/include/gqb/gqbCollection.h new file mode 100644 index 0000000..d73fad2 --- /dev/null +++ b/include/gqb/gqbCollection.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbCollection.h - Generic implementation of a Collection used by GQB. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCOLLECTION_H +#define GQBCOLLECTION_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbCollectionBase.h" + +class gqbCollection : public wxObject +{ +public: + gqbCollection(gqbCollectionBase *collectionBase); + virtual ~gqbCollection(); + void addItem(gqbObject *item); + void removeItem(gqbObject *item); + void deleteAll(); + void removeAll(); + int count(); + bool existsObject(gqbObject *item); + int getIndex(gqbObject *item); + gqbObject *getItemAt(int index); + void insertAtIndex(gqbObject *item, int index); + gqbIteratorBase *createIterator(); + gqbIteratorBase *createDownIterator(); + +private: + gqbCollectionBase *collection; +}; +#endif diff --git a/include/gqb/gqbCollectionBase.h b/include/gqb/gqbCollectionBase.h new file mode 100644 index 0000000..f76d604 --- /dev/null +++ b/include/gqb/gqbCollectionBase.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbCollectionBase.h - A Collection Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCOLLECTIONFACTORY_H +#define GQBCOLLECTIONFACTORY_H + +// App headers +#include "gqb/gqbObject.h" + +// This class it's like an interface (but with not all advantages of this at runtime) +// If in a future I just don't want to use an array, simple implement this abstract class again +// with the new data structure. + +class gqbIteratorBase : wxObject +{ +public: + gqbIteratorBase() {}; + virtual gqbObject *Next() = 0; + virtual bool HasNext() = 0; + virtual void ResetIterator() = 0; +}; +// OR probably let to this class to +class gqbCollectionBase : wxObject // GQB-TODO: Change to the class because probably it's not adapted to the actual use of this class +{ +public: + gqbCollectionBase() {}; + virtual ~gqbCollectionBase() {}; + virtual void addItem(gqbObject *item) = 0; + virtual void removeItem(gqbObject *item) = 0; + virtual gqbObject *getItemAt(int index) = 0; + virtual gqbIteratorBase *createIterator() = 0; + virtual gqbIteratorBase *createDownIterator() = 0; + virtual int count() = 0; + virtual bool existsObject(gqbObject *item) = 0; + virtual int getIndex(gqbObject *item) = 0; + virtual void insertAtIndex(gqbObject *item, int index) = 0; + virtual void deleteAll() = 0; + virtual void removeAll() = 0; //remove all items from collection without deleting. +}; +#endif diff --git a/include/gqb/gqbColumn.h b/include/gqb/gqbColumn.h new file mode 100644 index 0000000..82a1e24 --- /dev/null +++ b/include/gqb/gqbColumn.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbColumn.h - Column Object for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCOLUMN_H +#define GQBCOLUMN_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" + +// Create Array Objects used as base for gqbCollections +class gqbColumn : public gqbObject +{ +public: + gqbColumn(gqbObject *parent, wxString name, pgConn *connection); +}; +#endif diff --git a/include/gqb/gqbDatabase.h b/include/gqb/gqbDatabase.h new file mode 100644 index 0000000..7af4742 --- /dev/null +++ b/include/gqb/gqbDatabase.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbDatabase.h - Database object for GQB. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBDATABASE_H +#define GQBDATABASE_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbBrowser.h" + +class gqbDatabase : public gqbObject +{ +public: + gqbDatabase(wxString name, pgConn *connection); + void createObjects(gqbBrowser *_tablesBrowser); + +private: + enum typeSchema + { + GQB_CATALOG, + GQB_OTHER + }; + void createSchemas(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, typeSchema MetaType, int indexImage); +}; +#endif diff --git a/include/gqb/gqbEvents.h b/include/gqb/gqbEvents.h new file mode 100644 index 0000000..1084ff9 --- /dev/null +++ b/include/gqb/gqbEvents.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// Events.h - IDs for GQB Events +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBEVENTS_H +#define GQBEVENTS_H + +enum gqb_Events +{ + GQB_COLSTREE = 1000, + GQB_BROWSER, + GQB_HORZ_SASH +}; + +enum gqb_rMenus +{ + GQB_RMJ_DELETE = 2000, + GQB_RMJ_SETTYPE, + GQB_RMT_DELETE, + GQB_RMT_SETALIAS, + GQB_REFRESH +}; +#endif diff --git a/include/gqb/gqbGraphBehavior.h b/include/gqb/gqbGraphBehavior.h new file mode 100644 index 0000000..83f60f8 --- /dev/null +++ b/include/gqb/gqbGraphBehavior.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGraphsimple.h - A simple Graphic Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRAPHBEHAVIOR_H +#define GQBGRAPHBEHAVIOR_H + +#include + +// App headers +#include "gqb/gqbQueryObjs.h" + +// Interface class for drawing of objects in canvas +class gqbGraphBehavior : public wxObject +{ +public: + // Important: The drawTable function always should store the width & height of the graphic + // representation of the table inside the gqbQueryObject for use of controller. + virtual void drawTable(wxMemoryDC &bdc, wxPoint *origin, gqbQueryObject *queryTable) = 0; + virtual void drawTempJoinLine(wxMemoryDC &bdc, wxPoint &origin, wxPoint &end) = 0; + virtual void drawJoin(wxMemoryDC &bdc, wxPoint &origin, wxPoint &dest, wxPoint &anchorUsed, bool selected, type_Join joinKind) = 0; + virtual void calcAnchorPoint(gqbQueryJoin *join) = 0; + virtual void UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment) = 0; + + // GQB-TODO find a way to not hard code the 17 default value + virtual gqbColumn *getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility = 17) = 0; + virtual bool clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest) = 0; + virtual int getTitleRowHeight() = 0; +private: + +}; +#endif diff --git a/include/gqb/gqbGraphSimple.h b/include/gqb/gqbGraphSimple.h new file mode 100644 index 0000000..0a05744 --- /dev/null +++ b/include/gqb/gqbGraphSimple.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGraphsimple.h - A simple Implementation of the Graphic Interface for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRAPHSIMPLE_H +#define GQBGRAPHSIMPLE_H + +#include + +// App headers +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbGraphBehavior.h" + +// Create Array Objects used as base for gqbCollections +class gqbGraphSimple : public gqbGraphBehavior +{ +public: + gqbGraphSimple(); + void drawTable(wxMemoryDC &bdc, wxPoint *origin, gqbQueryObject *queryTable); + void drawTempJoinLine(wxMemoryDC &bdc, wxPoint &origin, wxPoint &end); + void calcAnchorPoint(gqbQueryJoin *join); + void drawJoin(wxMemoryDC &bdc, wxPoint &origin, wxPoint &dest, wxPoint &anchorUsed, bool selected, type_Join joinKind); + void UpdatePosObject(gqbQueryObject *queryTable, int x, int y, int cursorAdjustment); + gqbColumn *getColumnAtPosition(wxPoint *clickPoint, gqbQueryObject *queryTable, int sensibility = 17); + bool clickOnJoin(gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest); + int getTitleRowHeight(); + +private: + wxFont normalFont, TableTitleFont; + wxBrush BackgroundLayer1, BackgroundLayer2, BackgroundTitle, selectedBrush; + int minTableWidth, minTableHeight; + int rowHeight, rowLeftMargin, rowRightMargin, rowTopMargin, lineClickThreshold; + wxPen selectedPen; + wxBitmap imgSelBoxEmpty, imgSelBoxSelected; + bool insideLine(wxPoint &pt, wxPoint &p1, wxPoint &p2, int threshold); + double distanceToLine(wxPoint pt, wxPoint p1, wxPoint p2); + wxPoint findLineMiddle(wxPoint p1, wxPoint p2); +}; +#endif diff --git a/include/gqb/gqbGridJoinTable.h b/include/gqb/gqbGridJoinTable.h new file mode 100644 index 0000000..8a45337 --- /dev/null +++ b/include/gqb/gqbGridJoinTable.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridJoinTable.h - Table implementation for Join Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDJOINTABLE_H +#define GQBGRIDJOINTABLE_H + +#include +#include + +// App headers +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbArrayCollection.h" + +class gqbController; + +class gqbGridJoinTable : public wxGridTableBase +{ +public: + gqbGridJoinTable(gqbController *_controller); + ~gqbGridJoinTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell(int row, int col); + wxString GetValue(int row, int col); + wxString GetColLabelValue( int col); + void SetValue(int row, int col, const wxString &value); + void AppendJoin(gqbQueryJoin *item); + void removeJoin(gqbQueryJoin *item); + void removeJoins(gqbQueryObject *obj); + void emptyTableData(); + gqbQueryObject *DeleteRow(size_t pos); + bool ReplaceJoin(gqbQueryJoin *orig, gqbQueryJoin *newVal); + gqbQueryJoin *GetJoin(int row); + void selectJoin(gqbQueryJoin *join); + +private: + gqbController *controller; + gqbArrayCollection joins; +}; + +#endif + diff --git a/include/gqb/gqbGridOrderTable.h b/include/gqb/gqbGridOrderTable.h new file mode 100644 index 0000000..c58808e --- /dev/null +++ b/include/gqb/gqbGridOrderTable.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridOrderTable.h - Table implementation for Order By Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDORDERTABLE_H +#define GQBGRIDORDERTABLE_H + +#include + +// App headers +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbModel.h" + +class gqbGridOrderTable : public wxGridTableBase +{ +public: + gqbGridOrderTable(int numColumns, gqbObjsArray *cols, gqbObjsArray *parent, charArray *orderBy); + ~gqbGridOrderTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell( int row, int col ); + wxString GetValue( int row, int col ); + wxString GetColLabelValue( int col); + void SetValue( int row, int col, const wxString &value ); + void AppendItem(gqbColumn *column, gqbQueryObject *parent, char kindOrder); + void emptyTableData(gqbQueryObject *object); + gqbObject *getObjectAt(int pos, int col); + bool removeFirstRow(gqbObject *itemTable); + void removeRowAt(int i); + void changesRangeOnePos(int topPos, int bottomPos, int newTop); + void changesPositions(int sPos, int dPos); + +private: + int numberColumns; // GQB-TODO: replace this with grid cols number function if possible + gqbObjsArray *columns; // Here store position of the columns at Select projection clause + // [Select c1,c2,c3...,cn from...] + gqbObjsArray *colsParents; // Because above array only store a column object cannot be recovered + // the object that store it (gqbQueryObject) [remember can be use same + // table twice on a query]. + charArray *kindOfOrder; // A [Asc] D [Desc] +}; +#endif diff --git a/include/gqb/gqbGridProjTable.h b/include/gqb/gqbGridProjTable.h new file mode 100644 index 0000000..afd5926 --- /dev/null +++ b/include/gqb/gqbGridProjTable.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridProjTable.h - Table implementation for Projection Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDPROJTABLE_H +#define GQBGRIDPROJTABLE_H + +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbArrayCollection.h" + +// GQB-TODO: don't use gqbObjsArray, use a new one in the model because violating MVC Pattern + +// GQB-TODO: this is not needed the one in gqbArrayCollections works her ????? +// WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); this is not + +// Create the Data Model that will be used by wxGrid Component +class gqbGridProjTable : public wxGridTableBase +{ +public: + gqbGridProjTable(gqbObjsArray *position, gqbObjsArray *parent, wxArrayString *alias); + virtual ~gqbGridProjTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell( int row, int col ); + wxString GetValue( int row, int col ); + void SetValue( int row, int col, const wxString &value ); + void *GetValueAsCustom( int row, int col, const wxString &typeName ); + void SetValueAsCustom( int row, int col, const wxString &typeName, void *value ); + wxString GetColLabelValue( int col); + bool removeRow(gqbObject *itemTable, gqbObject *itemColumn); + void removeAllRows(gqbObject *itemTable); + void changesPositions(int spos, int dpos); + void changesRangeOnePos(int topPos, int bottomPos, int newTop); + void AppendItem(int col, gqbObject *item); + void emptyTableData(); + +private: + gqbObjsArray *colsPosition; // Here store position of the columns at Select projection clause + // [Select c1,c2,c3...,cn from...] + gqbObjsArray *colsParents; // Because above array only store a column object cannot be recovered + // the object that store it (gqbQueryObject) [remember can be use + // same table twice on a query]. + wxArrayString *columnsAlias; // GQB-TODO: find a better solution than this +}; +#endif diff --git a/include/gqb/gqbGridRestTable.h b/include/gqb/gqbGridRestTable.h new file mode 100644 index 0000000..f930783 --- /dev/null +++ b/include/gqb/gqbGridRestTable.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbGridRestTable.h - Table implementation for Restrictions Panel Grid +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBGRIDRESTTABLE_H +#define GQBGRIDRESTTABLE_H + +#include +#include + +// App headers +#include "gqb/gqbModel.h" +#include "gqb/gqbArrayCollection.h" + +class gqbGridRestTable : public wxGridTableBase +{ +public: + gqbGridRestTable(gqbRestrictions *_restrictions); + ~gqbGridRestTable(); + int GetNumberRows(); + int GetNumberCols(); + bool IsEmptyCell( int row, int col ); + wxString GetValue( int row, int col ); + wxString GetColLabelValue( int col); + void SetValue( int row, int col, const wxString &value ); + void AppendItem(gqbQueryRestriction *item); + void emptyTableData(); + bool DeleteRows(size_t pos, size_t numRows); + +private: + gqbRestrictions *restrictions; +}; + +// +// Cell rendering utilities classes +// + +class wxGridCellComboBoxRenderer : public wxGridCellStringRenderer +{ +public: + wxGridCellComboBoxRenderer(wxLayoutAlignment border = wxLAYOUT_NONE) : + m_border(border) {} + virtual void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected); + virtual wxGridCellRenderer *Clone() const + { + return new wxGridCellComboBoxRenderer; + } + +private: + wxLayoutAlignment m_border; +}; + +class wxGridCellButtonRenderer : public wxGridCellStringRenderer +{ +public: + wxGridCellButtonRenderer(wxLayoutAlignment border = wxLAYOUT_NONE) : + m_border(border) {} + virtual void Draw(wxGrid &grid, wxGridCellAttr &attr, wxDC &dc, const wxRect &rect, int row, int col, bool isSelected); + virtual wxGridCellRenderer *Clone() const + { + return new wxGridCellComboBoxRenderer; + } + +private: + wxLayoutAlignment m_border; +}; + +// Shows a wxGridCellChoiceEditor of cell's wide +class dxGridCellSizedChoiceEditor : public wxGridCellChoiceEditor +{ +public: + dxGridCellSizedChoiceEditor(const wxArrayString &choices, bool allowOthers = false); + dxGridCellSizedChoiceEditor(size_t count = 0, const wxString choices[] = NULL, bool allowOthers = false); + + ~dxGridCellSizedChoiceEditor() {} + + virtual wxGridCellEditor *Clone() const; + virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL); + +protected: + int m_maxWide; + + DECLARE_NO_COPY_CLASS(dxGridCellSizedChoiceEditor) + +}; + +// GQB-TODO: don't use gqbObjsArray, use a new one in the model because violating MVC Pattern + +// GQB-TODO: this is not needed the one in gqbArrayCollections works her ????? +// WX_DEFINE_ARRAY_PTR(gqbObject *, gqbObjsArray); this is not + +// Create the Data Model that will be used by wxGrid Component + +#endif diff --git a/include/gqb/gqbModel.h b/include/gqb/gqbModel.h new file mode 100644 index 0000000..f716000 --- /dev/null +++ b/include/gqb/gqbModel.h @@ -0,0 +1,104 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbModel.h - Model of MVC Pattern for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBMODEL_H +#define GQBMODEL_H + +// App headers +#include "gqb/gqbQueryObjs.h" + +#define MAXRECTANGLES 10 + +WX_DEFINE_ARRAY_CHAR(char, charArray); + +class gqbModel : public wxObject +{ +public: + gqbModel(); + ~gqbModel(); + void emptyAll(); + + // Tables + gqbQueryObject *addTable(gqbTable *table, wxPoint p); + void deleteTable(gqbQueryObject *table); + gqbIteratorBase *createQueryIterator(); + gqbIteratorBase *createDownQueryIterator(); + int tablesCount(); + + // Projection Panel + gqbObjsArray *getOrderedColumns() + { + return &colsPosition; + }; + gqbObjsArray *getColumnsParents() + { + return &colsParents; + }; + wxArrayString *getColumnsAlias() + { + return columnsAlias; + }; + + // Restrictions Panel + gqbQueryRestriction *addRestriction(); // GQB-TODO: delete if not use this function + gqbRestrictions *getRestrictions() + { + return restrictions; + }; + + // Order By Panel + gqbObjsArray *getOrdByAvailColumns() + { + return &AvailableColumns; + }; + gqbObjsArray *getOrdByAvailParents() + { + return &ColumnAvailParent; + }; + gqbObjsArray *getOrdByColumns() + { + return &OrderedColumns; + }; + gqbObjsArray *getOrdByParents() + { + return &ColumnOrdParent; + }; + charArray *getOrdByKind() + { + return &orderBy; + }; + +private: + // query objects [tables] with joins inside + gqbQueryObjs *queryCollection; + + // projection Panel + gqbObjsArray colsPosition; // Here store position of the columns at Select projection clause + // [Select c1,c2,c3...,cn from...] + gqbObjsArray colsParents; // Because above array only store a column object cannot be recovered + // the object that store it (gqbQueryObject) [remember can be use same + // table twice on a query]. + wxArrayString *columnsAlias; + + // restrictions Panel + gqbRestrictions *restrictions; + + // order by Panel + // For left grid [available columns to order clause] + gqbObjsArray AvailableColumns; + gqbObjsArray ColumnAvailParent; + + // For right grid [used columns on order clause] + gqbObjsArray OrderedColumns; + gqbObjsArray ColumnOrdParent; + charArray orderBy; // D or A +}; +#endif diff --git a/include/gqb/gqbObject.h b/include/gqb/gqbObject.h new file mode 100644 index 0000000..fc143c3 --- /dev/null +++ b/include/gqb/gqbObject.h @@ -0,0 +1,68 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObject.h - Main basic object used by GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBOBJECT_H +#define GQBOBJECT_H + +enum type_gqbObject +{ + GQB_DATABASE, + GQB_SCHEMA, + GQB_TABLE, + GQB_VIEW, + GQB_COLUMN, + GQB_QUERYOBJ, + GQB_QUERY, + GQB_JOIN, + GQB_RESTRICTION +}; + +// Create Array Objects used as base for gqbCollections +class gqbObject : public wxTreeItemData +{ +public: + gqbObject(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid = 0); + virtual ~gqbObject(); + const wxString &getName() + { + return Name; + } + wxTreeItemData *getOwner() + { + return Owner; + } + const type_gqbObject getType() + { + return Type; + } + void setType(const type_gqbObject type) + { + Type = type; + } + pgConn *getConnection() + { + return conn; + } + OID getOid() + { + return Oid; + } + +protected: + pgConn *conn; + +private: + wxString Name; + wxTreeItemData *Owner; + type_gqbObject Type; + OID Oid; +}; +#endif diff --git a/include/gqb/gqbObjectCollection.h b/include/gqb/gqbObjectCollection.h new file mode 100644 index 0000000..6617543 --- /dev/null +++ b/include/gqb/gqbObjectCollection.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObjectCollection.h - A Collection of simple GQB objects +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBOBJECTCOLLECTION_H +#define GQBOBJECTCOLLECTION_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbCollection.h" +#include "gqb/gqbArrayCollection.h" + +// Create Collections of gqbObjects +class gqbObjectCollection : public gqbObject +{ +public: + gqbObjectCollection(wxString name, wxTreeItemData *owner, pgConn *connection, OID oid = 0); + virtual ~gqbObjectCollection(); + +protected: + void addObject(gqbObject *object); + void removeObject(gqbObject *object); + gqbIteratorBase *createIterator(); + gqbIteratorBase *createDownIterator(); + int countObjects(); + gqbObject *getObjectAtIndex(int index); + bool existsObject(gqbObject *object); + int indexObject(gqbObject *object); + void insertObjectAt(gqbObject *object, int index); + int getCount(); + void removeAll(); // Remove all objects from collection without deleting each one. + void deleteAll(); // Remove and Delete all objects from collection. + +private: + gqbCollection *objectsCollection; + gqbArrayCollection *implementation; // GQB-TODO: DEBO Eliminar esto (que gqbArrayCollection este dentro de la clase) pero como? +}; +#endif diff --git a/include/gqb/gqbQueryObjs.h b/include/gqb/gqbQueryObjs.h new file mode 100644 index 0000000..4116ab6 --- /dev/null +++ b/include/gqb/gqbQueryObjs.h @@ -0,0 +1,195 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbQueryObjs.h - All objects used by a model of a query in the MVC Pattern model. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBQUERYOBJS_H +#define GQBQUERYOBJS_H + +// wxWindows headers +#include +#include + +// App headers +#include "gqb/gqbTable.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbObjectCollection.h" + +#define MAXRECTANGLES 10 + +class gqbQueryObject; +class gqbQueryJoin; + +// GQB-TODO: Add all kinds of joins +enum type_Join +{ + _equally, + _lesser, + _greater, + _equlesser, + _equgreater + +}; + +// Collection of main Query Objects [Tables] +class gqbQueryObjs : public gqbObjectCollection +{ +public: + gqbQueryObjs(); // No destructor, the base destructor destroy collection + // the unique dynamic object in this class + void addTable(gqbQueryObject *mtable); // Uses alias to only allow operations I want to do it. + void removeTable(gqbQueryObject *mtable); + gqbIteratorBase *createQueryIterator(); + gqbIteratorBase *createDownQueryIterator(); + int tablesCount(); + void removeAllQueryObjs(); +}; + +// Collection of main Table Objects [Columns] have joins too but in a new variable +class gqbQueryObject : public gqbObjectCollection +{ +public: + gqbQueryObject(gqbTable *table); + ~gqbQueryObject(); + gqbTable *parent; + wxPoint position; + void setSelected(bool value); + bool getSelected(); + void setWidth(int value); + int getWidth(); + void setHeight(int value); + int getHeight(); + void removeColumn(gqbColumn *column); // Used only as synonym for gqbObjectCollection removeObject + void addColumn(gqbColumn *column); // Used only as synonym for gqbObjectCollection addObject + int getColumnIndex(gqbColumn *column); + bool existsColumn(gqbColumn *column); + gqbIteratorBase *createQueryTableIterator(); + gqbIteratorBase *createJoinsIterator(); + gqbIteratorBase *createRegJoinsIterator(); + gqbQueryJoin *addJoin(gqbQueryObject *owner, gqbQueryObject *observable, gqbColumn *source, gqbColumn *destination, type_Join kind); + void removeJoin(gqbQueryJoin *join, bool unRegister); + void registerJoin(gqbQueryJoin *join); + void unregisterJoin(gqbQueryJoin *join, bool removeIt); + bool getHaveJoins(); + bool getHaveRegJoins(); + void setAlias(wxString name) + { + alias = name; + }; + wxString getAlias() + { + return alias; + }; + +private: + bool selected; + wxString alias; + int width; + int height; + bool haveJoins, haveRegisteredJoins; + gqbCollection *joinsCollection, *registeredCollection; + gqbArrayCollection *implementationj, *implementationr ; + +}; + +// A Join Object +class gqbQueryJoin : public gqbObject +{ +public: + gqbQueryJoin(gqbQueryObject *_owner, gqbQueryObject *_destination, gqbColumn *sourceCol, gqbColumn *destCol, type_Join joinKind); + void setKindofJoin(type_Join join); + type_Join getKindofJoin(); + gqbQueryObject *getSourceQTable(); + gqbQueryObject *getDestQTable(); + gqbColumn *getDCol(); + gqbColumn *getSCol(); + wxString getSourceTable(); + wxString getDestTable(); + wxString getSourceCol(); + wxString getDestCol(); + void setSourceAnchor(wxPoint pt); + void setDestAnchor(wxPoint pt); + wxPoint &getSourceAnchor(); + wxPoint &getDestAnchor(); + void setSelected(bool value); + bool getSelected(); + void setAnchorsUsed(wxPoint pt); + wxPoint &getAnchorsUsed(); + +private: + bool selected; + type_Join kindofJoin; + gqbColumn *sCol, *dCol; + gqbQueryObject *owner, *destination; + wxPoint sAnchor, dAnchor; // The source/destination anchor points of the join (for same join) + wxPoint anchorsUsed; +}; + +// A Restriction Object +class gqbQueryRestriction : public gqbObject +{ +public: + gqbQueryRestriction(); + wxString &getLeft() + { + return leftPart; + }; + wxString &getRestriction() + { + return restriction; + }; + wxString &getValue_s() + { + return value_s; + }; + wxString &getConnector() + { + return connector; + }; + void setLeft(const wxString &value) + { + leftPart = value; + }; + void setRestriction(const wxString &value) + { + restriction = value; + }; + void setValue_s(const wxString &value) + { + value_s = value; + }; + void setConnector(const wxString &value) + { + connector = value; + }; + +private: + wxString leftPart; + wxString restriction; + wxString value_s; + wxString connector; +}; + +// Collection of restrictions for a where clause +class gqbRestrictions : public gqbObjectCollection +{ +public: + gqbRestrictions(); + ~gqbRestrictions(); + + void addRestriction(gqbQueryRestriction *r); + void removeRestriction(gqbQueryRestriction *r); + void deleteAllRestrictions(); + gqbIteratorBase *createRestrictionsIterator(); + void addRestrictionAt(gqbQueryRestriction *r, int index); + int restrictionsCount(); + gqbQueryRestriction *getRestrictionAt(int index); + +}; +#endif diff --git a/include/gqb/gqbSchema.h b/include/gqb/gqbSchema.h new file mode 100644 index 0000000..6e91b3d --- /dev/null +++ b/include/gqb/gqbSchema.h @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbSchema.h - Schema object for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBSCHEMA_H +#define GQBSCHEMA_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbTable.h" + +class gqbSchema : public gqbObject +{ +public: + gqbSchema(gqbObject *parent, wxString name, pgConn *connection, OID oid); + void createObjects(gqbBrowser *tablesBrowser, OID oidVal, wxTreeItemId parentNode, int tableImage, int viewImage, int xTableImage); + +private: + void createTables(gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal, int tableImage, int viewImage, int xTableImage); +}; +#endif diff --git a/include/gqb/gqbTable.h b/include/gqb/gqbTable.h new file mode 100644 index 0000000..a7e9342 --- /dev/null +++ b/include/gqb/gqbTable.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbTable.h - Table object for GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBTABLE_H +#define GQBTABLE_H + +// App headers +#include "gqb/gqbObject.h" +#include "gqb/gqbBrowser.h" +#include "gqb/gqbObjectCollection.h" + +class gqbColumn; + +// Create Array Objects used as base for gqbCollections +class gqbTable : public gqbObjectCollection +{ +public: + gqbTable(gqbObject *parent, wxString name, pgConn *connection, type_gqbObject type, OID oid); + void createObjects(gqbBrowser *_tablesBrowser, pgConn *_conn, OID oidVal, wxTreeItemId parentNode); + gqbIteratorBase *createColumnsIterator(); + int countCols(); + gqbColumn *getColumnAtIndex(int index); + int indexColumn(gqbColumn *col); + +private: + void addColumn(gqbColumn *column); // Used only as synonym for gqbObjectCollection addObject + void createColumns(pgConn *conn, gqbBrowser *tablesBrowser, wxTreeItemId parentNode, OID oidVal); + +}; +#endif diff --git a/include/gqb/gqbViewController.h b/include/gqb/gqbViewController.h new file mode 100644 index 0000000..18734d0 --- /dev/null +++ b/include/gqb/gqbViewController.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbViewController.h - View and Controller implementation for MVC Pattern of GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBCONTROLLER_H +#define GQBCONTROLLER_H + +#include +#include +#include +#include +#include +#include + +// App headers +#include "ctl/ctlAuiNotebook.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbGraphBehavior.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridJoinTable.h" +#include "gqb/gqbBrowser.h" + +#define GQB_MIN_WIDTH 1280 +#define GQB_MIN_HEIGHT 800 + +class gqbView; + +enum pointerMode +{ + pt_normal, + pt_join +}; + +// Utility Class to avoid a bug when the event sash resize is called +class gqbSplitter: public wxSplitterWindow +{ +public: + gqbSplitter(wxWindow *parent, wxWindowID id, const wxPoint &point, const wxSize &size, long style); + void setTablesBrowser(gqbBrowser *b) + { + tablesBrowser = b; + }; + void setBrowserPanel(wxPanel *p) + { + browserPanel = p; + }; + +private: + void onVerticalSashResize(wxSplitterEvent &event); + gqbBrowser *tablesBrowser; // tables Browser Tree + wxPanel *browserPanel; // Container of tables Browser Tree + DECLARE_EVENT_TABLE() +}; + +// This enum is useful to select particular page from the tabs +enum tabsIndex +{ + ti_colsGridPanel = 0, + ti_criteriaPanel, + ti_orderPanel, + ti_joinsPanel +}; + +class gqbController: public wxObject +{ +public: + gqbController(gqbModel *_model, wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size); + ~gqbController(); + gqbQueryObject *addTableToModel(gqbTable *table, wxPoint p); + gqbQueryJoin *addJoin(gqbQueryObject *sTable, gqbColumn *sColumn, gqbQueryObject *dTable, gqbColumn *dColumn, type_Join kind); + void removeJoin(gqbQueryJoin *join); + void removeTableFromModel(gqbQueryObject *table, gqbGridProjTable *gridTable, gqbGridOrderTable *orderLTable, gqbGridOrderTable *orderRTable); + void unsetModelSelected(bool queryTable); + void processColumnInModel(gqbQueryObject *table, gqbColumn *column, gqbGridProjTable *gridTable); + void setPointerMode(pointerMode pm); // Find selected table with their coordinates point + gqbView *getView() + { + return view; + }; + void nullView() + { + view = NULL; + }; + gqbObject *getModelSelected(wxPoint &pt, gqbQueryObject *lastSelected, gqbQueryJoin *lastJoinSelected, bool mark); + wxString generateSQL(); + wxSplitterWindow *getViewContainer() + { + return gqbMainContainer; + }; + wxSplitterWindow *getDialogParent() + { + return (wxSplitterWindow *) gqbContainer; + }; + void setSashVertPosition(int pos); + void setSashHorizPosition(int pos); + int getSashHorizPosition(); + gqbBrowser *getTablesBrowser() + { + return tablesBrowser; + }; + wxNotebook *getTabs() + { + return tabs; + }; + void emptyModel(); + void calcGridColsSizes(); + gqbQueryRestriction *addRestriction(); + int getTableCount() + { + return model->tablesCount(); + }; + +protected: + gqbView *view; // owned by caller application shouldn't be destroy by this class + wxWindow *pparent; // GQB-TODO: deberia ser privada no se porque no funciona [la estoy usando?] + gqbModel *model; // owned by caller application shouldn't be destroy by this class + wxNotebook *tabs; + gqbSplitter *gqbContainer; // container of canvas & tables browser. + wxSplitterWindow *gqbMainContainer; + gqbBrowser *tablesBrowser; // tables Browser Tree + wxPanel *browserPanel; // Container of tables Browser Tree +}; + +class gqbView: public wxScrolledWindow +{ +public: + gqbView(wxWindow *gqbParent, ctlAuiNotebook *gridParent, wxSize size, gqbController *controller, gqbModel *model); + ~gqbView(); + void SaveAsImage(const wxString &path, wxBitmapType imgType); + bool canSaveAsImage(); + void drawAll(wxMemoryDC &bdc, bool adjustScrolling); + void setPointerMode(pointerMode pm); + + // Events for wxScrolledWindow + void onPaint(wxPaintEvent &event); + void onMotion(wxMouseEvent &event); + void onDoubleClick(wxMouseEvent &event); + void onRightClick(wxMouseEvent &event); + void onErase(wxEraseEvent &event); + void onEraseBackGround(wxEraseEvent &event); + void OnKeyDown(wxKeyEvent &event); + void OnSize(wxSizeEvent &event); + wxPanel *getColsGridPanel() + { + return (wxPanel *)projectionPanel; + }; + wxPanel *getCriteriaPanel() + { + return (wxPanel *)criteriaPanel; + }; + wxPanel *getOrderPanel() + { + return (wxPanel *)orderPanel; + }; + wxPanel *getJoinsPanel() + { + return joinsPanel; + } + void newTableAdded(gqbQueryObject *item); + bool clickOnJoin (gqbQueryJoin *join, wxPoint &pt, wxPoint &origin, wxPoint &dest); + void updateTable(gqbQueryObject *table); + const wxSize &getModelSize() + { + return modelSize; + } + + // Functions for all gqb extra Panels (projection, criteria..) + void emptyPanelsData(); + + void updateModelSize(gqbQueryObject *obj, bool updateAnyWay); + +private: + gqbController *controller; // owned by caller application shouldn't be destroy + // by this class + gqbModel *model; // owned by caller application shouldn't be destroy + // by this class + gqbGraphBehavior *graphBehavior; // This points to the Graph behavior for objects, + // if change the way objects were draw changes too. + gqbIteratorBase *iterator; //include here for reuse of iterator, should be + // delete when class destroy + wxPanel *projectionPanel, *criteriaPanel, *orderPanel, *joinsPanel; + gqbGridProjTable *gridTable; // Data model for the columns grid internals + gqbGridRestTable *restrictionsGridTable; // Data model for restricions grid internals + gqbGridJoinTable *joinsGridTable; // Data model for joins grid internals + + gqbGridOrderTable *orderByLGridTable, *orderByRGridTable; // Data model for order by grid internals + wxSize canvasSize, modelSize; + bool changeTOpressed; + + // just a point to the selected item on the collection, shouldn't be destroy inside this class + gqbQueryObject *collectionSelected, *joinSource, *joinDest, *cTempSelected; + gqbQueryJoin *joinSelected, *jTempSelected; + gqbColumn *joinSCol, *joinDCol; + int pressed, selected, refreshRate; + wxPoint pos, jpos; // Position of the last event of the mouse & the first event of a join event + pointerMode mode; // pointer is used as normally or as in joins by example + wxImage joinCursorImage; + wxCursor joinCursor; + wxMenu *m_rightJoins, *m_rightTables, *m_gqbPopup; + void OnMenuJoinDelete(wxCommandEvent &event); + void OnMenuTableDelete(wxCommandEvent &event); + void OnMenuTableSetAlias(wxCommandEvent &event); + void OnRefresh(wxCommandEvent &ev); + + wxArrayString joinTypeChoices; + + DECLARE_EVENT_TABLE() +}; + +// A drop target that do nothing only accept text, if accept then tree add table to model +class DnDText : public wxTextDropTarget +{ +public: + DnDText(gqbBrowser *tablesBrowser) + { + tree = tablesBrowser; + } + virtual bool OnDropText(wxCoord x, wxCoord y, const wxString &text) + { + tree->setDnDPoint(x, y); + return true; + } + +private: + gqbBrowser *tree; +}; + +#endif + diff --git a/include/gqb/gqbViewPanels.h b/include/gqb/gqbViewPanels.h new file mode 100644 index 0000000..b54da72 --- /dev/null +++ b/include/gqb/gqbViewPanels.h @@ -0,0 +1,258 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbViewPanels.h - All panels used by GQB +// +////////////////////////////////////////////////////////////////////////// + +#ifndef GQBVIEWPANELS_H +#define GQBVIEWPANELS_H + +#include + +// App headers +#include "gqb/gqbViewController.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridJoinTable.h" + +enum gridButtons +{ + GQB_COLS_UP_BUTTON_ID, + GQB_COLS_UP_TOP_BUTTON_ID, + GQB_COLS_DOWN_BUTTON_ID, + GQB_COLS_DOWN_BOTTOM_BUTTON_ID, + GQB_COLS_ADD_BUTTON_ID, + GQB_COLS_DROP_BUTTON_ID, + + GQB_JOIN_COLS_ADD_BUTTON_ID, + GQB_JOIN_COLS_DELETE_BUTTON_ID, + + GQB_ORDER_DROP_BUTTON_ID, + GQB_ORDER_DROP_ALL_BUTTON_ID, + GQB_ORDER_ADD_ALL_BUTTON_ID, + GQB_ORDER_ADD_BUTTON_ID, + GQB_ORDER_UP_BUTTON_ID, + GQB_ORDER_UP_TOP_BUTTON_ID, + GQB_ORDER_DOWN_BUTTON_ID, + GQB_ORDER_DOWN_BOTTOM_BUTTON_ID +}; + +// +// Projection Panel +// + +class gqbGridPanel: public wxPanel +{ +public: + gqbGridPanel(wxWindow *parent, wxWindowID id, gqbGridProjTable *gridModel); + ~gqbGridPanel(); + wxBitmapButton *buttonUp, *buttonDown, *buttonUpTop, *buttonDownBottom; + wxBitmap upBitmap, upTopBitmap, downBitmap, downBottomBitmap; + void SetGridColsSize(); + + // Events for wxGrid + void OnGridSelectCell( wxGridEvent &ev ); + void OnGridRangeSelected( wxGridRangeSelectEvent &ev ); + void OnButtonUp(wxCommandEvent &); + void OnButtonUpTop(wxCommandEvent &); + void OnButtonDown(wxCommandEvent &); + void OnButtonDownBottom(wxCommandEvent &); + +private: + bool allowSelCells; + int selTop, selBottom; // Range Selection of wxGrid, -1 it's value not set. + wxGrid *colsGrid; // Columns Grid used for order of columns in sentence & single row functions + gqbGridProjTable *gModel; + DECLARE_EVENT_TABLE() +}; + +// +// Panels reusable components +// + +class gqbColsTree : public wxTreeCtrl +{ +public: + gqbColsTree(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style); + wxTreeItemId &createRoot(wxString &Name); + wxTreeItemId &getRootNode() + { + return rootNode; + } + void refreshTree(gqbModel *model, gqbQueryObject *doNotInclude = NULL); + virtual void DeleteAllItems(); + ~gqbColsTree() + { + DeleteAllItems(); + } + +private: + wxTreeItemId rootNode; +}; + +enum +{ + QR_TREE_OK = 9100, + QR_TREE +}; + +class gqbColsPopUp: public wxDialog +{ +public: + gqbColsPopUp(wxWindow *parent, wxWindowID id, wxString title, wxPoint pos, const wxSize size); + virtual void refreshTree(gqbModel *_model); + void OnPopUpOKClick(wxCommandEvent &event); + void OnPopUpTreeClick(wxTreeEvent &event); + void OnPopUpTreeDoubleClick(wxTreeEvent &event); + void setEditText(wxString text); + wxString getEditText() + { + return editTree->GetValue(); + }; + void setUsedCell(wxGrid *grid, int row, int col) + { + usedGrid = grid; + _row = row; + _col = col; + }; + void focus(); + +protected: + int _row, _col; + wxGrid *usedGrid; + gqbColsTree *colsTree; + wxTextCtrl *editTree; + wxButton *buttonTree; + gqbModel *model; // Not owned shouldn't be deleted at this class + +}; + +class gqbJoinsPanel; + +class gqbJoinsPopUp: public gqbColsPopUp +{ +public: + gqbJoinsPopUp( + gqbJoinsPanel *parent, wxWindowID id, wxString title, wxPoint pos, + const wxSize size, gqbQueryJoin *_join, bool isSource, + gqbGridJoinTable *_gmodel); + void OnPopUpOKClick(wxCommandEvent &event); + void OnPopUpTreeClick(wxTreeEvent &event); + void OnPopUpTreeDoubleClick(wxTreeEvent &event); + + // This should be called through OnPopUpOKClick & OnPopUpTreeDoubleClick + void updateJoin(); + + virtual void refreshTree(gqbModel *_model); + +private: + gqbQueryJoin *join; // Not owned, shouldn't be deletedat this class + gqbQueryObject *selectedTbl; //Not owned, shouldn't be deletedat this class + gqbColumn *selectedCol; //Not owned, shouldn't be deletedat this class + bool isSource; + gqbGridJoinTable *gModel; //Not owned, shouldn't be deletedat this class +}; + +// +// Criterias Panel +// + +class gqbCustomGrid: public wxGrid +{ +public: + gqbCustomGrid(wxWindow *parent, wxWindowID id); + void ComboBoxEvent(wxGridEvent &event); + void RevertSel(); + +private: + wxGridSelection *m_selTemp; + +}; + +class gqbCriteriaPanel: public wxPanel +{ +public: + gqbCriteriaPanel(wxWindow *parent, gqbModel *_model, gqbGridRestTable *gridModel); + void OnCellLeftClick(wxGridEvent &ev); + void refreshTree(gqbModel *_model); + void OnButtonAdd(wxCommandEvent &); + void OnButtonDrop(wxCommandEvent &); + void SetGridColsSize(); + +private: + wxBitmapButton *buttonAdd, *buttonDrop; + wxBitmap addBitmap, dropBitmap; + void showColsPopUp(int row, int col, wxPoint pos); + gqbGridRestTable *gModel; + wxGrid *restrictionsGrid; // Columns Grid used for order of columns in sentence & single row functions + gqbModel *model; // Not owned shouldn't be deleted at this class + gqbColsPopUp *colsPopUp; + DECLARE_EVENT_TABLE() + +}; + +class gqbJoinsPanel: public wxPanel +{ +public: + gqbJoinsPanel(wxWindow *parent, gqbModel *_model, gqbGridJoinTable *_gmodel, gqbController *_controller); + void OnCellLeftClick(wxGridEvent &ev); + void refreshTree(gqbModel *_model); + void OnButtonAdd(wxCommandEvent &); + void OnButtonDrop(wxCommandEvent &); + void SetGridColsSize(); + void updateView(gqbQueryObject *tbl); + void selectJoin(gqbQueryJoin *join); + +private: + wxBitmapButton *buttonAdd, *buttonDrop; + wxBitmap addBitmap, dropBitmap; + void showColsPopUp(int row, int col, wxPoint pos); + gqbCustomGrid *joinsGrid; + gqbModel *model; // Not owned shouldn't be deleted at this class + gqbJoinsPopUp *joinsPopUp; // It will be automatically deleted + gqbGridJoinTable *gModel; // Not owned shouldn't be deleted at this class + gqbController *controller; // Not owned shouldn't be deleted at this class + DECLARE_EVENT_TABLE() + +}; + +// +// Order by Panel +// + +class gqbOrderPanel: public wxPanel +{ +public: + gqbOrderPanel(wxWindow *parent, gqbGridOrderTable *gridTableLeft, gqbGridOrderTable *gridTableRight); + void SetGridColsSize(); + +private: + bool allowSelCells; + void OnButtonUp(wxCommandEvent &); + void OnButtonUpTop(wxCommandEvent &); + void OnButtonDown(wxCommandEvent &); + void OnButtonDownBottom(wxCommandEvent &); + void OnButtonRemove(wxCommandEvent &); + void OnButtonRemoveAll(wxCommandEvent &); + void OnButtonAdd(wxCommandEvent &); + void OnButtonAddAll(wxCommandEvent &); + void OnGridSelectCell( wxGridEvent &ev ); + void OnGridRangeSelected( wxGridRangeSelectEvent &ev ); + void OnCellLeftClick(wxGridEvent &ev); + int selLeft, selRightTop, selRightBottom; + gqbGridOrderTable *tableLeft, *tableRight; + wxGrid *availableColumns, *usedColumns; + wxBitmapButton *buttonAdd, *buttonAddAll, *buttonRemove, *buttonRemoveAll; + wxBitmap addBitmap, addAllBitmap, removeBitmap, removeAllBitmap; + wxBitmapButton *buttonUp, *buttonDown, *buttonUpTop, *buttonDownBottom; + wxBitmap upBitmap, upTopBitmap, downBitmap, downBottomBitmap; + DECLARE_EVENT_TABLE() +}; +#endif + diff --git a/include/gqb/module.mk b/include/gqb/module.mk new file mode 100644 index 0000000..97e72ed --- /dev/null +++ b/include/gqb/module.mk @@ -0,0 +1,37 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/gqb/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/gqb/gqbArrayCollection.h \ + include/gqb/gqbBrowser.h \ + include/gqb/gqbCollection.h \ + include/gqb/gqbCollectionBase.h \ + include/gqb/gqbColumn.h \ + include/gqb/gqbDatabase.h \ + include/gqb/gqbEvents.h \ + include/gqb/gqbGraphBehavior.h \ + include/gqb/gqbGraphSimple.h \ + include/gqb/gqbGridOrderTable.h \ + include/gqb/gqbGridProjTable.h \ + include/gqb/gqbGridRestTable.h \ + include/gqb/gqbGridJoinTable.h \ + include/gqb/gqbModel.h \ + include/gqb/gqbObject.h \ + include/gqb/gqbObjectCollection.h \ + include/gqb/gqbQueryObjs.h \ + include/gqb/gqbSchema.h \ + include/gqb/gqbTable.h \ + include/gqb/gqbViewController.h \ + include/gqb/gqbViewPanels.h + +EXTRA_DIST += \ + include/gqb/module.mk + diff --git a/include/hotdraw/connectors/hdChopBoxConnector.h b/include/hotdraw/connectors/hdChopBoxConnector.h new file mode 100644 index 0000000..c4749a3 --- /dev/null +++ b/include/hotdraw/connectors/hdChopBoxConnector.h @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChopBoxConnector.h - Connector for center of figure to line crossing one limit line of rect +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHOPBOXCONNECTOR_H +#define HDCHOPBOXCONNECTOR_H + + +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdChopBoxConnector : public hdIConnector +{ +public: + hdChopBoxConnector(hdIFigure *owner); + ~hdChopBoxConnector(); + virtual hdPoint findStart(int posIdx, hdLineConnection *connFigure); + virtual hdPoint findEnd(int posIdx, hdLineConnection *connFigure); +protected: + virtual hdPoint chop(int posIdx, hdIFigure *target, hdPoint point); +private: + hdPoint point; + hdRect rect; + +}; +#endif diff --git a/include/hotdraw/connectors/hdIConnector.h b/include/hotdraw/connectors/hdIConnector.h new file mode 100644 index 0000000..49b36b9 --- /dev/null +++ b/include/hotdraw/connectors/hdIConnector.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnector.cpp - Base class for all connectors +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDICONNECTOR_H +#define HDICONNECTOR_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" + +class hdLineConnection; +class hdIFigure; + +class hdIConnector : public hdObject +{ +public: + hdIConnector(hdIFigure *owner); + ~hdIConnector(); + virtual hdPoint findStart(int posIdx, hdLineConnection *connection); + virtual hdPoint findEnd(int posIdx, hdLineConnection *connection); + virtual bool containsPoint(int posIdx, int x, int y); + virtual void draw(wxBufferedDC &context); + virtual hdIFigure *getOwner(); + virtual hdMultiPosRect &getDisplayBox(); +protected: + virtual void setOwner(hdIFigure *owner); +private: + hdIFigure *figureOwner; + +}; +#endif diff --git a/include/hotdraw/connectors/hdLocatorConnector.h b/include/hotdraw/connectors/hdLocatorConnector.h new file mode 100644 index 0000000..1693725 --- /dev/null +++ b/include/hotdraw/connectors/hdLocatorConnector.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorConnector.h - class that puts connects at locator position +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLOCATORCONNECTOR_H +#define HDLOCATORCONNECTOR_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/locators/hdILocator.h" + +class hdLocatorConnector : public hdIConnector +{ +public: + hdLocatorConnector(hdIFigure *owner, hdILocator *locator); + ~hdLocatorConnector(); + virtual hdPoint findStart(int posIdx, hdLineConnection *connection); + virtual hdPoint findEnd(int posIdx, hdLineConnection *connection); + virtual bool containsPoint(int posIdx, int x, int y); + virtual void draw(wxBufferedDC &context); + virtual hdPoint locate(int posIdx); + virtual hdRect &getDisplayBox(int posIdx); +protected: + int size; //standard size connector + hdRect displayBox; +private: + hdILocator *figureLocator; + hdIFigure *figureOwner; + +}; +#endif diff --git a/include/hotdraw/connectors/hdStickyRectangleConnector.h b/include/hotdraw/connectors/hdStickyRectangleConnector.h new file mode 100644 index 0000000..378fff4 --- /dev/null +++ b/include/hotdraw/connectors/hdStickyRectangleConnector.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - A StickyRectangleConnector locates connection points by choping +// the connection between the centers of the two figures at the display box. The location +// of the connection point is computed once, when the user connects the figure. +// Moving the figure around will not change the location. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSTICKYRECTANGLECONNECTOR_H +#define HDSTICKYRECTANGLECONNECTOR_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/connectors/hdChopBoxConnector.h" + +class hdLineConnection; +class hdIFigure; + +class hdStickyRectangleConnector : public hdChopBoxConnector +{ +public: + hdStickyRectangleConnector(hdIFigure *owner, hdPoint p); + ~hdStickyRectangleConnector(); + virtual void setAngle(float newAngle); + virtual void updateAnchor(int posIdx, hdPoint p); + virtual hdPoint getAnchor(int posIdx); + virtual hdPoint chop(int posIdx, hdIFigure *target, hdPoint point); + virtual void draw(wxBufferedDC &context); +protected: + float angle; +private: + +}; +#endif diff --git a/include/hotdraw/connectors/module.mk b/include/hotdraw/connectors/module.mk new file mode 100644 index 0000000..c4d3ac0 --- /dev/null +++ b/include/hotdraw/connectors/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/connectors/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/connectors/hdChopBoxConnector.h \ + include/hotdraw/connectors/hdIConnector.h \ + include/hotdraw/connectors/hdLocatorConnector.h \ + include/hotdraw/connectors/hdStickyRectangleConnector.h + +EXTRA_DIST += \ + include/hotdraw/connectors/module.mk diff --git a/include/hotdraw/figures/defaultAttributes/hdFillAttribute.h b/include/hotdraw/figures/defaultAttributes/hdFillAttribute.h new file mode 100644 index 0000000..e6e8db1 --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdFillAttribute.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFillAttribute.h - Default attribute for fill color of figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFILLCOLORATTRIBUTE_H +#define HDFILLCOLORATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdFillAttribute : public hdAttribute +{ +public: + hdFillAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); + wxBrush &brush(); +protected: + wxBrush fillAttributes; +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/hdFontAttribute.h b/include/hotdraw/figures/defaultAttributes/hdFontAttribute.h new file mode 100644 index 0000000..053240c --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdFontAttribute.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.h - Default attribute for attributes of fonts +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFONTATTRIBUTE_H +#define HDFONTATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdFontAttribute : public hdAttribute +{ +public: + hdFontAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); + wxFont &font(); + static wxFont *defaultFont; + static void InitFont(); +protected: + wxFont fontAttributes; +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h b/include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h new file mode 100644 index 0000000..74fc35d --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h @@ -0,0 +1,29 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFontAttribute.cpp - Default attribute for color of fonts +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFONTCOLORATTRIBUTE_H +#define HDFONTCOLORATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdFontColorAttribute : public hdAttribute +{ +public: + hdFontColorAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); +// void setFontColorAttribute(wxColour color); + wxColour fontColor; +protected: + + +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/hdLineAttribute.h b/include/hotdraw/figures/defaultAttributes/hdLineAttribute.h new file mode 100644 index 0000000..f339c24 --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/hdLineAttribute.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineAttribute.h - Default Attribute for lines style, color an others at figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINECOLORATTRIBUTE_H +#define HDLINECOLORATTRIBUTE_H + +#include "hotdraw/figures/hdAttribute.h" + +class hdLineAttribute : public hdAttribute +{ +public: + hdLineAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); + wxPen &pen(); +protected: + wxPen penAttributes; +}; +#endif diff --git a/include/hotdraw/figures/defaultAttributes/module.mk b/include/hotdraw/figures/defaultAttributes/module.mk new file mode 100644 index 0000000..6ede488 --- /dev/null +++ b/include/hotdraw/figures/defaultAttributes/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/figures/defaultAttributes Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/figures/defaultAttributes/hdFillAttribute.h \ + include/hotdraw/figures/defaultAttributes/hdFontAttribute.h \ + include/hotdraw/figures/defaultAttributes/hdFontColorAttribute.h \ + include/hotdraw/figures/defaultAttributes/hdLineAttribute.h + +EXTRA_DIST += \ + include/hotdraw/figures/defaultAttributes/module.mk diff --git a/include/hotdraw/figures/hdAbstractFigure.h b/include/hotdraw/figures/hdAbstractFigure.h new file mode 100644 index 0000000..dac9502 --- /dev/null +++ b/include/hotdraw/figures/hdAbstractFigure.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDABSTRACTFIGURE_H +#define HDABSTRACTFIGURE_H +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdCollection.h" + +class hdAbstractFigure : public hdIFigure +{ +public: + hdAbstractFigure(); + ~hdAbstractFigure(); + + virtual bool canConnect (); + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual void drawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual bool includes(hdIFigure *figure); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void moveBy(int posIdx, int x, int y); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual void moveTo(int posIdx, int x, int y); + virtual bool containsPoint(int posIdx, int x, int y); + virtual void onFigureChanged(int posIdx, hdIFigure *figure); + +protected: + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + void willChange(); + void changed(int posIdx); + void invalidate(); + wxColour fillColor, lineColor; + double lineWidth; + wxSize spaceForMovement; + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdAbstractMenuFigure.h b/include/hotdraw/figures/hdAbstractMenuFigure.h new file mode 100644 index 0000000..24ebe65 --- /dev/null +++ b/include/hotdraw/figures/hdAbstractMenuFigure.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractMenuFigure.h - Base class for figures that show a menu with right click +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDABSTRACTMENUFIGURE_H +#define HDABSTRACTMENUFIGURE_H +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdAttributeFigure.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdCollection.h" + +class hdAbstractMenuFigure : public hdAttributeFigure +{ +public: + hdAbstractMenuFigure(); + ~hdAbstractMenuFigure(); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void createMenu(wxMenu &mnu) {} + virtual void enablePopUp(); + virtual void disablePopUp(); + virtual bool menuEnabled(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view = NULL); +protected: + wxArrayString strings; + bool showMenu; +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdAttribute.h b/include/hotdraw/figures/hdAttribute.h new file mode 100644 index 0000000..374c468 --- /dev/null +++ b/include/hotdraw/figures/hdAttribute.h @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDATTRIBUTE_H +#define HDATTRIBUTE_H +#include "hotdraw/main/hdObject.h" + +class hdAttribute : public hdObject +{ +public: + hdAttribute(); + virtual void callDefaultChangeDialog(wxWindow *owner = NULL); + virtual void apply(wxBufferedDC &context); +}; +#endif diff --git a/include/hotdraw/figures/hdAttributeFigure.h b/include/hotdraw/figures/hdAttributeFigure.h new file mode 100644 index 0000000..ff37ff1 --- /dev/null +++ b/include/hotdraw/figures/hdAttributeFigure.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDATTRIBUTEFIGURE_H +#define HDATTRIBUTEFIGURE_H + +// wxWindows headers +#include "hotdraw/figures/hdAbstractFigure.h" +#include "hotdraw/figures/hdAttribute.h" +#include "hotdraw/main/hdObject.h" +#include + +// App headers +#include "hotdraw/figures/defaultAttributes/hdFillAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdFontColorAttribute.h" +#include "hotdraw/figures/defaultAttributes/hdLineAttribute.h" + +class hdAttributeFigure : public hdAbstractFigure +{ +public: + hdAttributeFigure(); + ~hdAttributeFigure(); + + void draw(wxBufferedDC &context, hdDrawingView *view); + void drawSelected(wxBufferedDC &context, hdDrawingView *view); + void reapplyAttributes(wxBufferedDC &context, hdDrawingView *view); + void reapplySelAttributes(wxBufferedDC &context, hdDrawingView *view); + + void initializeDefaultAttributes(); + + //Draw attributes + hdFontAttribute *fontAttribute; + hdFontColorAttribute *fontColorAttribute; + hdFillAttribute *fillAttribute; + hdLineAttribute *lineAttribute; + //Draw selected attributes + hdFontAttribute *fontSelAttribute; + hdFontColorAttribute *fontSelColorAttribute; + hdFillAttribute *fillSelAttribute; + hdLineAttribute *lineSelAttribute; +protected: + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdBitmapFigure.h b/include/hotdraw/figures/hdBitmapFigure.h new file mode 100644 index 0000000..9d0e3a4 --- /dev/null +++ b/include/hotdraw/figures/hdBitmapFigure.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.h - Figure that draw a bitmap +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDBITMAPFIGURE_H +#define HDBITMAPFIGURE_H + +#include "hotdraw/figures/hdAbstractFigure.h" + +class hdBitmapFigure : public hdAbstractFigure +{ +public: + hdBitmapFigure(wxBitmap image); + ~hdBitmapFigure(); + + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual void changeBitmap(wxBitmap image); + virtual int getWidth(); + virtual int getHeight(); + +protected: + +private: + wxBitmap imageToDraw; +}; +#endif diff --git a/include/hotdraw/figures/hdCompositeFigure.h b/include/hotdraw/figures/hdCompositeFigure.h new file mode 100644 index 0000000..874d65d --- /dev/null +++ b/include/hotdraw/figures/hdCompositeFigure.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigure.h - Base class for all figures composite with figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOMPOSITEFIGURE_H +#define HDCOMPOSITEFIGURE_H +#include "hotdraw/figures/hdAttributeFigure.h" + +class hdCompositeFigure : public hdAttributeFigure +{ +public: + hdCompositeFigure(); + ~hdCompositeFigure(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual bool containsPoint(int posIdx, int x, int y); + virtual hdIteratorBase *figuresEnumerator(); + virtual hdIteratorBase *figuresInverseEnumerator(); + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual hdCollection *handlesEnumerator(); + virtual void add(hdIFigure *figure); + virtual void remove(hdIFigure *figure); + virtual bool includes(hdIFigure *figure); + virtual hdIFigure *findFigure(int posIdx, int x, int y); + virtual hdIFigure *getFigureAt(int indexOfCollection); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); +protected: + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + hdCollection *figureFigures; + hdCollection *figureHandles; + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdIConnectionFigure.h b/include/hotdraw/figures/hdIConnectionFigure.h new file mode 100644 index 0000000..9081029 --- /dev/null +++ b/include/hotdraw/figures/hdIConnectionFigure.h @@ -0,0 +1,55 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIConnectionFigure.h - Base class for all connection figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDICONNECTIONFIGURE_H +#define HDICONNECTIONFIGURE_H +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/handles/hdIHandle.h" + + +class hdIConnector; + +class hdIConnectionFigure : public hdIFigure +{ +public: + + virtual void connectStart(hdIConnector *start) = 0; + virtual void connectEnd(hdIConnector *end) = 0; + virtual void updateConnection() = 0; + virtual void disconnectStart() = 0; + virtual void disconnectEnd() = 0; + virtual bool canConnectStart(hdIFigure *figure) = 0; + virtual bool canConnectEnd(hdIFigure *figure) = 0; + virtual hdPoint *pointAt(int index) = 0; + virtual void splitSegment(int x, int y) = 0; + + virtual int pointCount() = 0; + virtual hdIConnector *getStartConnector() = 0; + virtual hdIConnector *getEndConnector() = 0; + virtual void setStartConnector(hdIConnector *connector) = 0; + virtual void setEndConnector(hdIConnector *connector) = 0; + virtual hdPoint *getStartPoint() = 0; + virtual void setStartPoint(hdPoint *point) = 0; + virtual hdPoint *getEndPoint() = 0; + virtual void setEndPoint(hdPoint *point) = 0; + virtual hdIFigure *getStartFigure() = 0; + virtual hdIFigure *getEndFigure() = 0; + virtual hdIHandle *getStartHandle() = 0; + virtual hdIHandle *getEndHandle() = 0; + +protected: + +private: + +}; +#endif diff --git a/include/hotdraw/figures/hdIFigure.h b/include/hotdraw/figures/hdIFigure.h new file mode 100644 index 0000000..aae6ddb --- /dev/null +++ b/include/hotdraw/figures/hdIFigure.h @@ -0,0 +1,69 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIFigure.h - Base class for all figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDIFIGURE_H +#define HDIFIGURE_H +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdCollection.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdMultiPosRect.h" + +class hdITool; +class hdDrawingEditor; +class hdIConnector; +class hdITool; + +WX_DEFINE_ARRAY_INT(bool, wxArrayBool); + +class hdIFigure : public hdObject +{ +public: + hdIFigure(); + ~hdIFigure(); + + virtual hdMultiPosRect &displayBox(); + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual void draw (wxBufferedDC &context, hdDrawingView *view); + virtual void drawSelected (wxBufferedDC &context, hdDrawingView *view); + virtual hdCollection *handlesEnumerator(); + virtual void addHandle (hdIHandle *handle); + virtual void removeHandle (hdIHandle *handle); + virtual hdIConnector *connectorAt (int posIdx, int x, int y); + virtual void moveBy(int posIdx, int x, int y) = 0; + virtual void moveTo(int posIdx, int x, int y) = 0; + virtual bool containsPoint(int posIdx, int x, int y) = 0; + virtual bool isSelected(int posIdx); + virtual void setSelected(int posIdx, bool value); + virtual bool includes(hdIFigure *figure); + virtual bool canConnect() = 0; + virtual void onFigureChanged(int posIdx, hdIFigure *figure) = 0; + virtual void addObserver (hdIFigure *observer); + virtual void removeObserver (hdIFigure *observer); + virtual hdIteratorBase *observersEnumerator(); + virtual void setKindId(int objectId = -1); + virtual int getKindId(); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + +protected: + hdMultiPosRect basicDisplayBox; + hdCollection *handles; + hdCollection *observers; + hdIConnector *connector; +private: + //bool selected; + wxArrayBool selected; + int kindHiddenId; + +}; +#endif diff --git a/include/hotdraw/figures/hdLineConnection.h b/include/hotdraw/figures/hdLineConnection.h new file mode 100644 index 0000000..b974f0f --- /dev/null +++ b/include/hotdraw/figures/hdLineConnection.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnection.h - Base class for line connection figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINECONNECTION_H +#define HDLINECONNECTION_H +#include "hotdraw/figures/hdPolyLineFigure.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/handles/hdIHandle.h" + +class hdLineConnection : public hdPolyLineFigure +{ +public: + hdLineConnection(); + hdLineConnection(int posIdx, hdIFigure *figure1, hdIFigure *figure2); + ~hdLineConnection(); + + virtual void connectStart(hdIConnector *start, hdDrawingView *view = NULL); + virtual void connectEnd(hdIConnector *end, hdDrawingView *view = NULL); + virtual void disconnectStart(hdDrawingView *view = NULL); + virtual void disconnectEnd(hdDrawingView *view = NULL); + virtual void updateConnection(int posIdx); + virtual bool canConnectStart(hdIFigure *figure); + virtual bool canConnectEnd(hdIFigure *figure); + virtual bool canConnect(); + virtual void setPointAt (int posIdx, int index, int x, int y); + virtual hdCollection *handlesEnumerator(); + virtual void basicMoveBy(int posIdx, int x, int y); + + virtual void onFigureChanged(int posIdx, hdIFigure *figure); + + virtual hdIConnector *getStartConnector(); + virtual hdIConnector *getEndConnector(); + virtual void setStartConnector(hdIConnector *connector); + virtual void setEndConnector(hdIConnector *connector); + virtual hdIFigure *getStartFigure(); + virtual hdIFigure *getEndFigure(); + virtual hdIHandle *getStartHandle(); + virtual hdIHandle *getEndHandle(); + virtual void addPoint (int posIdx, int x, int y); + virtual void insertPointAt (int posIdx, int index, int x, int y); + +protected: + virtual void updateHandlesIndexes(); + virtual void connectFigure (hdIConnector *connector); + virtual void disconnectFigure (hdIConnector *connector); + hdIConnector *startConnector; + hdIConnector *endConnector; + +private: + hdIHandle *changeConnStartHandle; + hdIHandle *changeConnEndHandle; +}; +#endif diff --git a/include/hotdraw/figures/hdLineTerminal.h b/include/hotdraw/figures/hdLineTerminal.h new file mode 100644 index 0000000..fb45918 --- /dev/null +++ b/include/hotdraw/figures/hdLineTerminal.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineTerminal.h - Base class for line terminal figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINETERMINAL_H +#define HDLINETERMINAL_H +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdPoint.h" + +class hdLineTerminal : public hdObject +{ +public: + hdLineTerminal(); + ~hdLineTerminal(); + + virtual hdPoint &draw (wxBufferedDC &context, hdPoint &a, hdPoint &b, hdDrawingView *view); + virtual void setLinePen(wxPen pen); +protected: + wxPen terminalLinePen; +private: + hdPoint middle; + +}; +#endif diff --git a/include/hotdraw/figures/hdPolyLineFigure.h b/include/hotdraw/figures/hdPolyLineFigure.h new file mode 100644 index 0000000..3c5f14a --- /dev/null +++ b/include/hotdraw/figures/hdPolyLineFigure.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigure.h - A simple line figure that can be split on several lines joined by flexibility points +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOLYLINEFIGURE_H +#define HDPOLYLINEFIGURE_H + +#include "hotdraw/figures/hdAbstractMenuFigure.h" +#include "hotdraw/figures/hdLineTerminal.h" +#include "hotdraw/utilities/hdArrayCollection.h" +#include "hotdraw/utilities/hdPoint.h" + + +WX_DEFINE_ARRAY(hdArrayCollection *, pointsCollections); + +class hdPolyLineFigure : public hdAbstractMenuFigure +{ +public: + hdPolyLineFigure(); + ~hdPolyLineFigure(); + + virtual hdMultiPosRect &getBasicDisplayBox(); + virtual int pointCount(int posIdx); + virtual int pointLinesCount(); + virtual void AddPosForNewDiagram(); + virtual void RemovePosOfDiagram(int posIdx); + virtual hdPoint &getStartPoint(int posIdx); + virtual void setStartPoint(int posIdx, hdPoint point); + virtual hdPoint &getEndPoint(int posIdx); + virtual void setEndPoint(int posIdx, hdPoint point); + virtual void setStartTerminal(hdLineTerminal *terminal); + virtual hdLineTerminal *getStartTerminal(); + virtual void setEndTerminal(hdLineTerminal *terminal); + virtual hdLineTerminal *getEndTerminal(); + hdCollection *handlesEnumerator(); + virtual int findSegment (int posIdx, int x, int y); + virtual void splitSegment(int posIdx, int x, int y); + virtual void changed(int posIdx); + + virtual void addPoint (int posIdx, int x, int y); + virtual void clearPoints (int posIdx); + virtual void insertPointAt (int posIdx, int index, int x, int y); + virtual void setPointAt (int posIdx, int index, int x, int y); + virtual void removePointAt (int posIdx, int index); + virtual void basicMoveBy(int posIdx, int x, int y); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + + virtual hdPoint &pointAt(int posIdx, int index); + virtual bool containsPoint (int posIdx, int x, int y); + virtual void setLinePen(wxPen pen); + int countPointsAt(int posIdx); + +protected: + virtual void basicDraw (wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + + int getMaximunIndex(); + virtual void updateHandlesIndexes(); + pointsCollections points; + hdPoint endPoint, startPoint, pointAtPos; + +private: + hdLineTerminal *startTerminal, *endTerminal; + bool handlesChanged; + wxPen linePen; + +}; +#endif diff --git a/include/hotdraw/figures/hdRectangleFigure.h b/include/hotdraw/figures/hdRectangleFigure.h new file mode 100644 index 0000000..3272d0d --- /dev/null +++ b/include/hotdraw/figures/hdRectangleFigure.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRectangleFigure.h - A simple rectangle figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDRECTANGLEFIGURE_H +#define HDRECTANGLEFIGURE_H + +#include + +#include "hotdraw/figures/hdAbstractFigure.h" + + +class hdDrawingView; + +class hdRectangleFigure : public hdAbstractFigure +{ +public: + hdRectangleFigure(); + ~hdRectangleFigure(); + void basicDraw(wxBufferedDC &context, hdDrawingView *view); + void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + void setRectangle(hdMultiPosRect &rect); + void setSize(wxSize &size); + +protected: +private: +}; +#endif diff --git a/include/hotdraw/figures/hdSimpleTextFigure.h b/include/hotdraw/figures/hdSimpleTextFigure.h new file mode 100644 index 0000000..0a9a3dd --- /dev/null +++ b/include/hotdraw/figures/hdSimpleTextFigure.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextFigure.h - A simple rectangle figure with text inside it +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSIMPLETEXTFIGURE_H +#define HDSIMPLETEXTFIGURE_H +#include "hotdraw/figures/hdAttributeFigure.h" + +class hdDrawingView; + +class hdSimpleTextFigure : public hdAttributeFigure +{ +public: + hdSimpleTextFigure(wxString textString); + ~hdSimpleTextFigure(); + virtual void setText(wxString textString); + virtual wxString &getText(bool extended = false); + virtual void setEditable(bool value); + virtual bool getEditable(); + virtual void setFont(wxFont textFont); + virtual int getPadding(); + void basicMoveBy(int posIdx, int x, int y); + virtual void basicDraw(wxBufferedDC &context, hdDrawingView *view); + virtual void basicDrawSelected(wxBufferedDC &context, hdDrawingView *view); + virtual hdITool *CreateFigureTool(hdDrawingView *view, hdITool *defaultTool); + virtual void createMenu(wxMenu &mnu) {} + virtual void enablePopUp(); + virtual void disablePopUp(); + virtual bool menuEnabled(); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); +protected: + virtual void getFontMetrics(int &width, int &height); + virtual void recalculateDisplayBox(); + wxArrayString strings; + bool showMenu; + bool textEditable; +private: + int padding; + wxString text; + wxFont font; + +}; +#endif diff --git a/include/hotdraw/figures/module.mk b/include/hotdraw/figures/module.mk new file mode 100644 index 0000000..bc1d840 --- /dev/null +++ b/include/hotdraw/figures/module.mk @@ -0,0 +1,31 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/figures/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/figures/hdAbstractFigure.h \ + include/hotdraw/figures/hdAbstractMenuFigure.h \ + include/hotdraw/figures/hdAttribute.h \ + include/hotdraw/figures/hdAttributeFigure.h \ + include/hotdraw/figures/hdBitmapFigure.h \ + include/hotdraw/figures/hdCompositeFigure.h \ + include/hotdraw/figures/hdIConnectionFigure.h \ + include/hotdraw/figures/hdIFigure.h \ + include/hotdraw/figures/hdLineConnection.h \ + include/hotdraw/figures/hdLineTerminal.h \ + include/hotdraw/figures/hdPolyLineFigure.h \ + include/hotdraw/figures/hdRectangleFigure.h \ + include/hotdraw/figures/hdSimpleTextFigure.h + +EXTRA_DIST += \ + include/hotdraw/figures/module.mk + +include include/hotdraw/figures/defaultAttributes/module.mk +include include/hotdraw/figures/xml/module.mk diff --git a/include/hotdraw/figures/xml/hdStorage.h b/include/hotdraw/figures/xml/hdStorage.h new file mode 100644 index 0000000..8593ab9 --- /dev/null +++ b/include/hotdraw/figures/xml/hdStorage.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractFigure.h - Base class for all figures with attributes (line size, fonts and others) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSTORAGE_H +#define HDSTORAGE_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdStorage : public hdObject +{ +public: + hdStorage(); + static bool Read(xmlTextReaderPtr reader); + static bool Write(xmlTextWriterPtr writer, hdIFigure *figure); +}; +#endif diff --git a/include/hotdraw/figures/xml/module.mk b/include/hotdraw/figures/xml/module.mk new file mode 100644 index 0000000..d21f8f8 --- /dev/null +++ b/include/hotdraw/figures/xml/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/figures/xml Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/figures/xml/hdStorage.h + +EXTRA_DIST += \ + include/hotdraw/figures/xml/module.mk diff --git a/include/hotdraw/handles/hdButtonHandle.h b/include/hotdraw/handles/hdButtonHandle.h new file mode 100644 index 0000000..417b3a3 --- /dev/null +++ b/include/hotdraw/handles/hdButtonHandle.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdButtonHandle.h - Handle to allow creation of buttons at figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDBUTTONHANDLE_H +#define HDBUTTONHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/handles/hdLocatorHandle.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdPoint.h" + +class hdButtonHandle : public hdIHandle +{ +public: + hdButtonHandle(hdIFigure *owner, hdILocator *buttonLocator , wxBitmap &buttonImage, wxSize &size); + ~hdButtonHandle(); + + virtual wxCursor createCursor(); + virtual hdRect &getDisplayBox(int posIdx); + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual hdPoint &locate(int posIdx); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view) = 0; +protected: + wxBitmap buttonIcon; +private: + bool clicked; + hdILocator *bLocator; + hdPoint pointLocate; + +}; +#endif diff --git a/include/hotdraw/handles/hdChangeConnectionEndHandle.h b/include/hotdraw/handles/hdChangeConnectionEndHandle.h new file mode 100644 index 0000000..099375d --- /dev/null +++ b/include/hotdraw/handles/hdChangeConnectionEndHandle.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionEndHandle.h - Handle to allow change connected figure at end of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHANGECONNECTIONENDHANDLE_H +#define HDCHANGECONNECTIONENDHANDLE_H + +#include "hotdraw/handles/hdChangeConnectionHandle.h" +#include "hotdraw/figures/hdLineConnection.h" + +class hdChangeConnectionEndHandle : public hdChangeConnectionHandle +{ +public: + hdChangeConnectionEndHandle(hdLineConnection *owner); + ~hdChangeConnectionEndHandle(); + virtual hdPoint &locate(int posIdx); + virtual hdIConnector *target(); + virtual void disconnect(hdDrawingView *view = NULL); + virtual void connect(hdIConnector *connector, hdDrawingView *view = NULL); + virtual bool isConnectionPossible(hdIFigure *figure); + virtual void setPoint(int posIdx, hdPoint p); +}; +#endif diff --git a/include/hotdraw/handles/hdChangeConnectionHandle.h b/include/hotdraw/handles/hdChangeConnectionHandle.h new file mode 100644 index 0000000..aa1f2d8 --- /dev/null +++ b/include/hotdraw/handles/hdChangeConnectionHandle.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionHandle.h - Base Handle to allow change connected figures at connection figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHANGECONNECTIONHANDLE_H +#define HDCHANGECONNECTIONHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/figures/hdLineConnection.h" +#include "hotdraw/connectors/hdIConnector.h" +#include "hotdraw/main/hdDrawing.h" + +class hdChangeConnectionHandle : public hdIHandle +{ +public: + hdChangeConnectionHandle(hdLineConnection *owner); + ~hdChangeConnectionHandle(); + + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual wxCursor createCursor(); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); + virtual hdIConnector *target() = 0; + virtual void disconnect(hdDrawingView *view = NULL) = 0; + virtual void connect(hdIConnector *connector, hdDrawingView *view = NULL) = 0; + virtual void setPoint(int posIdx, hdPoint p) = 0; + virtual bool isConnectionPossible(hdIFigure *figure) = 0; + hdIFigure *findConnectableFigure(int posIdx, int x, int y, hdDrawing *drawing); + hdIConnector *findConnectionTarget(int posIdx, int x, int y, hdDrawing *drawing); +protected: + hdLineConnection *connection; + hdIFigure *targetFigure; +private: + hdIConnector *originalTarget; +}; +#endif diff --git a/include/hotdraw/handles/hdChangeConnectionStartHandle.h b/include/hotdraw/handles/hdChangeConnectionStartHandle.h new file mode 100644 index 0000000..7bbd0f5 --- /dev/null +++ b/include/hotdraw/handles/hdChangeConnectionStartHandle.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdChangeConnectionStartHandle.h - Handle to allow change connected figure at start of connection figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCHANGECONNECTIONSTARTHANDLE_H +#define HDCHANGECONNECTIONSTARTHANDLE_H + +#include "hotdraw/handles/hdChangeConnectionHandle.h" +#include "hotdraw/figures/hdLineConnection.h" + +class hdChangeConnectionStartHandle : public hdChangeConnectionHandle +{ +public: + hdChangeConnectionStartHandle(hdLineConnection *owner); + ~hdChangeConnectionStartHandle(); + virtual hdPoint &locate(int posIdx); + virtual hdIConnector *target(); + virtual void disconnect(hdDrawingView *view = NULL); + virtual void connect(hdIConnector *connector, hdDrawingView *view = NULL); + virtual bool isConnectionPossible(hdIFigure *figure); + virtual void setPoint(int posIdx, hdPoint p); +}; +#endif diff --git a/include/hotdraw/handles/hdIHandle.h b/include/hotdraw/handles/hdIHandle.h new file mode 100644 index 0000000..6058962 --- /dev/null +++ b/include/hotdraw/handles/hdIHandle.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdIHandle.cpp - Base class for all Handles +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDIHANDLE_H +#define HDIHANDLE_H + +#include "wx/dcbuffer.h" +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdMultiPosRect.h" +#include "hotdraw/utilities/hdPoint.h" + +class hdDrawingView; +class hdIFigure; +class hdMouseEvent; + +class hdIHandle : public hdObject +{ +public: + hdIHandle(hdIFigure *owner); + ~hdIHandle(); + + static const int size = 4; + + virtual bool containsPoint(int posIdx, int x, int y); + virtual void draw(wxBufferedDC &context, hdDrawingView *view) = 0; + virtual hdPoint &locate(int posIdx) = 0; + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view) = 0; + virtual wxCursor createCursor() = 0; + virtual hdRect &getDisplayBox(int posIdx); +protected: + virtual hdIFigure *getOwner(); + hdRect displayBox; +private: + hdIFigure *figureOwner; + double lineWidth; + +}; +#endif diff --git a/include/hotdraw/handles/hdLineConnectionHandle.h b/include/hotdraw/handles/hdLineConnectionHandle.h new file mode 100644 index 0000000..453b8f9 --- /dev/null +++ b/include/hotdraw/handles/hdLineConnectionHandle.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLineConnectionHandle.h - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLINECONNECTIONHANDLE +#define HDLINECONNECTIONHANDLE + +#include "hotdraw/handles/hdPolyLineHandle.h" + +class hdLineConnectionHandle : public hdPolyLineHandle +{ +public: + hdLineConnectionHandle(hdPolyLineFigure *figure, hdILocator *loc, int index); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +private: + +}; +#endif diff --git a/include/hotdraw/handles/hdLocatorHandle.h b/include/hotdraw/handles/hdLocatorHandle.h new file mode 100644 index 0000000..0ffbba7 --- /dev/null +++ b/include/hotdraw/handles/hdLocatorHandle.h @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdLocatorHandle.h - Base class for Handles that are located at locator position +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDLOCATORHANDLE_H +#define HDLOCATORHANDLE_H + +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/locators/hdILocator.h" + +class hdDrawingView; + +class hdLocatorHandle : public hdIHandle +{ +public: + hdLocatorHandle(hdIFigure *owner, hdILocator *locator); + ~hdLocatorHandle(); + + virtual hdPoint &locate(int posIdx); + virtual hdILocator *locator(); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeEnd(hdMouseEvent &event, hdDrawingView *view); +protected: + +private: + hdILocator *loc; + hdPoint p; + +}; +#endif diff --git a/include/hotdraw/handles/hdPolyLineHandle.h b/include/hotdraw/handles/hdPolyLineHandle.h new file mode 100644 index 0000000..8c31b11 --- /dev/null +++ b/include/hotdraw/handles/hdPolyLineHandle.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineHandle.h - Handle for manipulation of multiple flexibility points lines. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOLYLINEHANDLE +#define HDPOLYLINEHANDLE + +#include "hotdraw/handles/hdLocatorHandle.h" +#include "hotdraw/utilities/hdRect.h" + +class hdDrawingView; +class hdPolyLineFigure; + +class hdPolyLineHandle : public hdLocatorHandle +{ +public: + hdPolyLineHandle(hdPolyLineFigure *figure, hdILocator *loc, int index); + ~hdPolyLineHandle(); + + virtual void draw(wxBufferedDC &context, hdDrawingView *view); + virtual void invokeStart(hdMouseEvent &event, hdDrawingView *view); + virtual void invokeStep(hdMouseEvent &event, hdDrawingView *view); + virtual wxCursor createCursor(); + virtual int getIndex(); + virtual void setIndex(int index); +protected: + +private: + int indx; + + +}; +#endif diff --git a/include/hotdraw/handles/module.mk b/include/hotdraw/handles/module.mk new file mode 100644 index 0000000..2b43776 --- /dev/null +++ b/include/hotdraw/handles/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/handles/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/handles/hdButtonHandle.h \ + include/hotdraw/handles/hdChangeConnectionEndHandle.h \ + include/hotdraw/handles/hdChangeConnectionHandle.h \ + include/hotdraw/handles/hdChangeConnectionStartHandle.h \ + include/hotdraw/handles/hdIHandle.h \ + include/hotdraw/handles/hdLineConnectionHandle.h \ + include/hotdraw/handles/hdLocatorHandle.h \ + include/hotdraw/handles/hdPolyLineHandle.h + +EXTRA_DIST += \ + include/hotdraw/handles/module.mk diff --git a/include/hotdraw/locators/hdILocator.h b/include/hotdraw/locators/hdILocator.h new file mode 100644 index 0000000..772bc4e --- /dev/null +++ b/include/hotdraw/locators/hdILocator.h @@ -0,0 +1,32 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdILocator.h - Base class for creation of a location for a ddHandle +// +////////////////////////////////////////////////////////////////////////// + +#ifndef hdILocator_H +#define hdILocator_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/figures/hdIFigure.h" + +class hdILocator : public hdObject +{ +public: + hdILocator(); + ~hdILocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner) = 0; + +protected: + hdPoint locatePoint; +private: + +}; +#endif diff --git a/include/hotdraw/locators/hdPolyLineLocator.h b/include/hotdraw/locators/hdPolyLineLocator.h new file mode 100644 index 0000000..8e862d0 --- /dev/null +++ b/include/hotdraw/locators/hdPolyLineLocator.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineLocator.h - Return multiple location at same time for a PolyLine +// +////////////////////////////////////////////////////////////////////////// + +#ifndef XWHDPOLYLINELOCATOR_H +#define XWHDPOLYLINELOCATOR_H + +#include "hotdraw/locators/hdILocator.h" + +class hdPolyLineLocator : public hdILocator +{ +public: + hdPolyLineLocator(int index); + ~hdPolyLineLocator(); + + virtual hdPoint &locate(int posIdx, hdIFigure *owner); + virtual void setIndex(int index); + +protected: + +private: + int indx; +}; +#endif diff --git a/include/hotdraw/locators/module.mk b/include/hotdraw/locators/module.mk new file mode 100644 index 0000000..9b1ec8a --- /dev/null +++ b/include/hotdraw/locators/module.mk @@ -0,0 +1,17 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/locator/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/locators/hdILocator.h \ + include/hotdraw/locators/hdPolyLineLocator.h + +EXTRA_DIST += \ + include/hotdraw/locators/module.mk diff --git a/include/hotdraw/main/hdDrawing.h b/include/hotdraw/main/hdDrawing.h new file mode 100644 index 0000000..b6488d9 --- /dev/null +++ b/include/hotdraw/main/hdDrawing.h @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawing.h - Main storage class for all objects of the model +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAWING_H +#define HDDRAWING_H + +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/utilities/hdRect.h" + + +// Main model of drawing +class hdDrawing : public wxObject +{ +public: + hdDrawing(hdDrawingEditor *owner); + virtual ~hdDrawing(); + virtual void add(hdIFigure *figure); + virtual void remove(hdIFigure *figure); + virtual bool includes(hdIFigure *figure); + virtual hdIFigure *findFigure(int posIdx, int x, int y); + virtual void recalculateDisplayBox(int posIdx); + virtual void bringToFront(hdIFigure *figure); + virtual void sendToBack(hdIFigure *figure); + virtual hdRect &DisplayBox(); + virtual hdIteratorBase *figuresEnumerator(); + virtual hdIteratorBase *figuresInverseEnumerator(); + virtual void removeAllFigures(); + virtual void deleteAllFigures(); + virtual void registerView(hdDrawingView *view) + { + usedView = view; + }; + virtual hdDrawingView *getView() + { + return usedView; + }; + virtual void addToSelection(hdIFigure *figure); + virtual void addToSelection(hdCollection *figures); + virtual void removeFromSelection(hdIFigure *figure); + virtual void deleteSelectedFigures(); + virtual void toggleSelection(hdIFigure *figure); + virtual void clearSelection(); + virtual bool isFigureSelected(hdIFigure *figure); + virtual hdIteratorBase *selectionFigures(); + virtual int countSelectedFigures(); + hdCollection *selectedFigures() + { + return selection; + }; + hdCollection *getFiguresCollection() + { + return figures; + }; + hdDrawingEditor *getOwnerEditor() + { + return ownerEditor; + }; + void setName(wxString name) + { + drawingName = name; + }; + wxString getName() + { + return drawingName; + }; +protected: + +private: + hdDrawingEditor *ownerEditor; + hdDrawingView *usedView; + hdCollection *selection; + hdCollection *figures; + hdCollection *handles; + hdRect displayBox; + wxString drawingName; +}; +#endif diff --git a/include/hotdraw/main/hdDrawingEditor.h b/include/hotdraw/main/hdDrawingEditor.h new file mode 100644 index 0000000..2752bb7 --- /dev/null +++ b/include/hotdraw/main/hdDrawingEditor.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingEditor.h - Main class that manages all other classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAWINGEDITOR_H +#define HDDRAWINGEDITOR_H + +#include "hotdraw/main/hdDrawingView.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/utilities/hdArrayCollection.h" + +class hdDrawingEditor : public hdObject +{ +public: + hdDrawingEditor(wxWindow *owner, bool defaultView = true ); + ~hdDrawingEditor(); + hdDrawingView *getExistingView(int diagramIndex); + hdDrawing *getExistingDiagram(int diagramIndex); + virtual hdDrawing *createDiagram(wxWindow *owner, bool fromXml); + virtual void deleteDiagram(int diagramIndex, bool deleteView = true); + virtual void addDiagramFigure(int diagramIndex, hdIFigure *figure); + virtual void removeDiagramFigure(int diagramIndex, hdIFigure *figure); + virtual void addModelFigure(hdIFigure *figure); + virtual void deleteModelFigure(hdIFigure *figure); + virtual void removeFromAllSelections(hdIFigure *figure); + virtual void removeAllDiagramsFigures(); + virtual void deleteAllModelFigures(); + virtual bool modelIncludes(hdIFigure *figure); + virtual void remOrDelSelFigures(int diagramIndex); + virtual void changeDefaultFiguresFont(); + int modelCount(); + hdIteratorBase *modelFiguresEnumerator(); + hdIteratorBase *diagramsEnumerator(); + bool modelHasChanged(); + virtual void notifyChanged(); + +protected: + hdArrayCollection *_diagrams; + hdArrayCollection *_model; + wxWindow *editorOwner; + bool modelChanged; + +private: +}; +#endif diff --git a/include/hotdraw/main/hdDrawingView.h b/include/hotdraw/main/hdDrawingView.h new file mode 100644 index 0000000..051d55e --- /dev/null +++ b/include/hotdraw/main/hdDrawingView.h @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDrawingView.h - Main canvas where all figures are drawn +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAWINGVIEW_H +#define HDDRAWINGVIEW_H + +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/main/hdDrawing.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" +#include "hotdraw/figures/hdAbstractMenuFigure.h" + +class hdCanvasMenuTool; + +// Create View Class for MVC pattern of graphic library of pgAdmin +enum +{ + CTL_TEXTTOOLID = 1979, + CTL_OKBUTTONID, + CTL_CANCELBUTTONID +}; + +class hdDrawingView : public wxScrolledWindow +{ +public: + hdDrawingView(int diagram, wxWindow *ddParent, hdDrawingEditor *editor , wxSize size, hdDrawing *drawing); + ~hdDrawingView(); + + virtual void ScrollToMakeVisible(hdPoint p); + virtual void ScrollToMakeVisible (hdRect r); + virtual hdIHandle *findHandle(int posIdx, double x, double y); + virtual hdDrawing *getDrawing(); + + void onPaint(wxPaintEvent &event); + void onEraseBackGround(wxEraseEvent &event); + virtual void onMouseDown(wxMouseEvent &event); + virtual void onMouseUp(wxMouseEvent &event); + virtual void onMotion(wxMouseEvent &event); + virtual void onKeyDown(wxKeyEvent &event); + virtual void onKeyUp(wxKeyEvent &event); + virtual hdMultiPosRect getVisibleArea(); + virtual hdMultiPosRect getVirtualSize(); + virtual bool AcceptsFocus () const; + hdDrawingEditor *editor(); + wxSize canvasSize; + + //Hack To allow right click menu at canvas without a figure + virtual void createViewMenu(wxMenu &mnu); + virtual void OnGenericViewPopupClick(wxCommandEvent &event); + //Hack to allow a different tool for each view + hdITool *tool(); + void setTool(hdITool *tool); + //Hack to avoid selection rectangle drawing bug + void setSelRect(hdRect &selectionRect); + void disableSelRectDraw(); + //Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event + void simpleTextToolChangeHandler(wxCommandEvent &event); + void setSimpleTextToolFigure(hdSimpleTextFigure *figure, bool onlySetFigure = false); + wxTextCtrl *getSimpleTextToolEdit(); + wxBitmapButton *getOkTxt(); + wxBitmapButton *getCancelTxt(); + //Hack to allow use (events) of wxmenu inside a tool Generic Way + void setMenuToolFigure(hdAbstractMenuFigure *figure); + //Hack to allow use (events) of wxmenu inside a tool like simpletexttool + void OnGenericPopupClick(wxCommandEvent &event); + void OnOkTxtButton(wxCommandEvent &event); + void OnCancelTxtButton(wxCommandEvent &event); + void connectPopUpMenu(wxMenu &mnu); + //Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way + void setCanvasMenuTool(hdCanvasMenuTool *menuTool); + //Hack to allow use of a figure into multiple diagrams. + int getIdx() + { + return diagramIndex; + } + void syncIdx(int newDiagramIndex) + { + diagramIndex = newDiagramIndex; + }; + void notifyChanged(); +protected: + int diagramIndex; +private: + DECLARE_EVENT_TABLE() + hdDrawing *drawing; + hdDrawingEditor *drawingEditor; + + //Hack to allow a different tool for each view + hdITool *_tool; + + //Hack to allow auto scrolling when dragging mouse. + hdPoint startDrag; + + //Hack to avoid selection rectangle drawing bug + hdRect selRect; + wxPoint selPoints[5]; + bool drawSelRect; + //End Hack to avoid selection rectangle drawing bug + + //Hack to allow use (events) of wxmenu inside a tool with a figure, Generic Way + hdAbstractMenuFigure *menuFigure; + //End hack to allow use (events) of wxmenu inside a tool with a figure, Generic Way + + //Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event && POPUP EVENT + wxTextCtrl *simpleTextToolEdit; + wxBitmapButton *okTxtButton, *cancelTxtButton; + hdSimpleTextFigure *simpleTextFigure; + wxString oldText; + //End Hack to avoid event problem with simpleTextTool wxTextCrtl at EVT_TEXT event && POPUP EVENT + + //Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way + hdCanvasMenuTool *canvasMenu; + //Hack to allow use (events) of wxmenu inside a tool without a figure, Generic Way +}; +#endif diff --git a/include/hotdraw/main/hdObject.h b/include/hotdraw/main/hdObject.h new file mode 100644 index 0000000..aa6b9ae --- /dev/null +++ b/include/hotdraw/main/hdObject.h @@ -0,0 +1,19 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gqbObject.h - +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDOBJECT_H +#define HDOBJECT_H + +class hdObject : public wxObject +{ +public: + hdObject() {}; +}; +#endif diff --git a/include/hotdraw/main/module.mk b/include/hotdraw/main/module.mk new file mode 100644 index 0000000..74cf02b --- /dev/null +++ b/include/hotdraw/main/module.mk @@ -0,0 +1,19 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/main/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/main/hdDrawing.h \ + include/hotdraw/main/hdDrawingEditor.h \ + include/hotdraw/main/hdDrawingView.h \ + include/hotdraw/main/hdObject.h + +EXTRA_DIST += \ + include/hotdraw/main/module.mk diff --git a/include/hotdraw/module.mk b/include/hotdraw/module.mk new file mode 100644 index 0000000..3e6c98f --- /dev/null +++ b/include/hotdraw/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/ Makefile fragment +# +####################################################################### + +include include/hotdraw/connectors/module.mk +include include/hotdraw/figures/module.mk +include include/hotdraw/handles/module.mk +include include/hotdraw/locators/module.mk +include include/hotdraw/main/module.mk +include include/hotdraw/tools/module.mk +include include/hotdraw/utilities/module.mk + +EXTRA_DIST += \ + include/hotdraw/module.mk diff --git a/include/hotdraw/tools/hdAbstractTool.h b/include/hotdraw/tools/hdAbstractTool.h new file mode 100644 index 0000000..8a6e756 --- /dev/null +++ b/include/hotdraw/tools/hdAbstractTool.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdAbstractTool.h - An abstract tool to allow creation of all tools +// +////////////////////////////////////////////////////////////////////////// + +#ifndef hdAbstractTool_H +#define hdAbstractTool_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/main/hdDrawingEditor.h" + + +class hdAbstractTool : public hdITool +{ +public: + hdAbstractTool(hdDrawingView *view); + ~hdAbstractTool(); + + void setAnchorCoords(int x, int y); + + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); + hdDrawingView *getDrawingView(); + +protected: + int anchorX, anchorY; + hdDrawingView *ownerView; +private: + +}; +#endif diff --git a/include/hotdraw/tools/hdCanvasMenuTool.h b/include/hotdraw/tools/hdCanvasMenuTool.h new file mode 100644 index 0000000..4dade19 --- /dev/null +++ b/include/hotdraw/tools/hdCanvasMenuTool.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMenuTool.h - Allow Edition of textTool (double click) or show a menu to modifiy in someway text (right click). +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCANVASMENUTOOL_H +#define HDCANVASMENUTOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" + +class hdCanvasMenuTool : public hdAbstractTool +{ + +public: + hdCanvasMenuTool(hdDrawingView *view, hdITool *dt); + ~hdCanvasMenuTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseDrag(hdMouseEvent &event); + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void createViewMenu(hdDrawingView *view, wxMenu &mnu); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + //Because a bug it was move to main View class as a hack. virtual void changeHandler(wxCommandEvent& event); +protected: + hdITool *defaultTool; +private: +}; +#endif diff --git a/include/hotdraw/tools/hdCompositeFigureTool.h b/include/hotdraw/tools/hdCompositeFigureTool.h new file mode 100644 index 0000000..f40398b --- /dev/null +++ b/include/hotdraw/tools/hdCompositeFigureTool.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCompositeFigureTool.h - A Tool that allow to change between all tools in a composite figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOMPOSITEFIGURETOOL_H +#define HDCOMPOSITEFIGURETOOL_H + +#include "hotdraw/tools/hdFigureTool.h" + + +class hdCompositeFigureTool : public hdFigureTool +{ +public: + hdCompositeFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdCompositeFigureTool(); + virtual void setDefaultTool(hdITool *dt); + virtual hdITool *getDefaultTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void setDelegateTool(hdDrawingView *view, hdITool *tool); + virtual hdITool *getDelegateTool(); +protected: + hdITool *delegateTool; +private: +}; +#endif diff --git a/include/hotdraw/tools/hdConnectionCreationTool.h b/include/hotdraw/tools/hdConnectionCreationTool.h new file mode 100644 index 0000000..e8deec1 --- /dev/null +++ b/include/hotdraw/tools/hdConnectionCreationTool.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdConnectionCreationTool.h - A Tool that allow to create a connection figure between two figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCONNECTIONCREATIONTOOL_H +#define HDCONNECTIONCREATIONTOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/figures/hdLineConnection.h" + +class hdConnectionCreationTool : public hdAbstractTool +{ +public: + hdConnectionCreationTool(hdDrawingView *view, hdLineConnection *figure); + ~hdConnectionCreationTool(); + + virtual void mouseDrag(hdMouseEvent &event); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); +protected: + +private: + hdLineConnection *toolConnection; + hdIHandle *handle; + int numClicks; + bool dragged; + +}; +#endif diff --git a/include/hotdraw/tools/hdCreationTool.h b/include/hotdraw/tools/hdCreationTool.h new file mode 100644 index 0000000..c0ea8ca --- /dev/null +++ b/include/hotdraw/tools/hdCreationTool.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCreationTool.h - A Tool that create a figure by just click on view +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCREATIONTOOL_H +#define HDCREATIONTOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" +#include "hotdraw/figures/hdIFigure.h" + + +class hdCreationTool : public hdAbstractTool +{ +public: + hdCreationTool(hdDrawingView *view, hdIFigure *prototype); + ~hdCreationTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void setPrototype(hdIFigure *prototype); + virtual hdIFigure *getPrototype(); + +protected: + hdIFigure *figurePrototype; + + +}; +#endif diff --git a/include/hotdraw/tools/hdDragCreationTool.h b/include/hotdraw/tools/hdDragCreationTool.h new file mode 100644 index 0000000..46c0db3 --- /dev/null +++ b/include/hotdraw/tools/hdDragCreationTool.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragCreationTool.h - A Tool that allow to move figure around view +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAGCREATIONTOOL_H +#define HDDRAGCREATIONTOOL_H + +#include "hotdraw/tools/hdCreationTool.h" +#include "hotdraw/main/hdDrawingEditor.h" + + +class hdDragCreationTool : public hdCreationTool +{ +public: + hdDragCreationTool(hdDrawingView *view, hdIFigure *prototype); + ~hdDragCreationTool(); + virtual void mouseDrag(hdMouseEvent &event); +}; +#endif diff --git a/include/hotdraw/tools/hdDragTrackerTool.h b/include/hotdraw/tools/hdDragTrackerTool.h new file mode 100644 index 0000000..93eeb84 --- /dev/null +++ b/include/hotdraw/tools/hdDragTrackerTool.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdDragTrackerTool.h - A Tool that allow to drag and drop figures at the view +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDDRAGTRACKERTOOL_H +#define HDDRAGTRACKERTOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdDragTrackerTool : public hdAbstractTool +{ +public: + hdDragTrackerTool(hdDrawingView *view, hdIFigure *anchor); + ~hdDragTrackerTool(); + + void setLastCoords(int x, int y); + bool hasMoved(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + +protected: + hdIFigure *anchorFigure; + bool hasMovedValue; + +private: + int lastX, lastY; + +}; +#endif diff --git a/include/hotdraw/tools/hdFigureTool.h b/include/hotdraw/tools/hdFigureTool.h new file mode 100644 index 0000000..2c7f2b2 --- /dev/null +++ b/include/hotdraw/tools/hdFigureTool.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdFigureTool.h - Base class for all figure tools +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDFIGURETOOL_H +#define HDFIGURETOOL_H + +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdFigureTool : public hdAbstractTool +{ +public: + hdFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdFigureTool(); + void setDefaultTool(hdITool *dt); + hdITool *getDefaultTool(); + void setFigure(hdIFigure *fig); + hdIFigure *getFigure(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); +protected: + hdITool *defaultTool; + hdIFigure *figure; +private: +}; +#endif diff --git a/include/hotdraw/tools/hdHandleTrackerTool.h b/include/hotdraw/tools/hdHandleTrackerTool.h new file mode 100644 index 0000000..0f3d10a --- /dev/null +++ b/include/hotdraw/tools/hdHandleTrackerTool.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdHandleTrackerTool.h - A Tool that allow to use multiple handles +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDHANDLETRACKERTOOL_H +#define HDHANDLETRACKERTOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/handles/hdIHandle.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdHandleTrackerTool : public hdAbstractTool +{ +public: + hdHandleTrackerTool(hdDrawingView *view, hdIHandle *anchor); + ~hdHandleTrackerTool(); + + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + +protected: + hdIHandle *anchorHandle; + +private: + +}; +#endif diff --git a/include/hotdraw/tools/hdITool.h b/include/hotdraw/tools/hdITool.h new file mode 100644 index 0000000..ed3a144 --- /dev/null +++ b/include/hotdraw/tools/hdITool.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdITool.h - Base class for all tools +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDITOOL_H +#define HDITOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdMouseEvent.h" +#include "hotdraw/utilities/hdKeyEvent.h" + + +class hdITool : public hdObject +{ +public: + hdITool(); + ~hdITool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual bool activated(); + virtual bool undoable(); + +protected: + + bool activatedValue; + bool undoableValue; + +}; +#endif diff --git a/include/hotdraw/tools/hdMenuTool.h b/include/hotdraw/tools/hdMenuTool.h new file mode 100644 index 0000000..abcca6a --- /dev/null +++ b/include/hotdraw/tools/hdMenuTool.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMenuTool.h - Allow Edition of textTool (double click) or show a menu to modifiy in someway text (right click). +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDMENUTOOL_H +#define HDMENUTOOL_H + +#include "hotdraw/tools/hdFigureTool.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" + + +class hdMenuTool : public hdFigureTool +{ + +public: + hdMenuTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdMenuTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void mouseDrag(hdMouseEvent &event); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + //Because a bug it was move to main View class as a hack. virtual void changeHandler(wxCommandEvent& event); +protected: +private: + hdAbstractMenuFigure *menuFigure; + //Because a bug in the way wxwidgets connect events I can't declare it here, wxTextCtrl *edit, instead I do it on the view. +}; +#endif diff --git a/include/hotdraw/tools/hdPolyLineFigureTool.h b/include/hotdraw/tools/hdPolyLineFigureTool.h new file mode 100644 index 0000000..b9a808e --- /dev/null +++ b/include/hotdraw/tools/hdPolyLineFigureTool.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPolyLineFigureTool.h - Tool to allow creation of flexibility points at polylines figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOLYLINEFIGURETOOL_H +#define HDPOLYLINEFIGURETOOL_H + +#include "hotdraw/tools/hdFigureTool.h" + + +class hdPolyLineFigureTool : public hdFigureTool +{ +public: + hdPolyLineFigureTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt); + ~hdPolyLineFigureTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click +protected: +private: +}; +#endif diff --git a/include/hotdraw/tools/hdSelectAreaTool.h b/include/hotdraw/tools/hdSelectAreaTool.h new file mode 100644 index 0000000..1a4bd82 --- /dev/null +++ b/include/hotdraw/tools/hdSelectAreaTool.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectAreaTool.h - Tool to allow selection of figures inside a rectangle +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSELECTAREATOOL_H +#define HDSELECTAREATOOL_H + +#include "hotdraw/main/hdObject.h" +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/figures/hdIFigure.h" +#include "hotdraw/main/hdDrawingEditor.h" +#include "hotdraw/tools/hdAbstractTool.h" + + +class hdSelectAreaTool : public hdAbstractTool +{ +public: + hdSelectAreaTool(hdDrawingView *view); + ~hdSelectAreaTool(); + + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + void selectFiguresOnRect(bool shiftPressed, hdDrawingView *view); +protected: + void drawSelectionRect(hdDrawingView *view); +private: + hdRect selectionRect; +}; +#endif diff --git a/include/hotdraw/tools/hdSelectionTool.h b/include/hotdraw/tools/hdSelectionTool.h new file mode 100644 index 0000000..a589df5 --- /dev/null +++ b/include/hotdraw/tools/hdSelectionTool.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSelectionTool.h - Tool to allow selection of figures +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSELECTIONTOOL_H +#define HDSELECTIONTOOL_H + +#include "hotdraw/tools/hdITool.h" +#include "hotdraw/tools/hdAbstractTool.h" + +class hdSelectionTool : public hdAbstractTool +{ +public: + hdSelectionTool(hdDrawingView *view); + ~hdSelectionTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void mouseUp(hdMouseEvent &event); + virtual void mouseMove(hdMouseEvent &event); + virtual void mouseDrag(hdMouseEvent &event); + virtual void keyDown(hdKeyEvent &event); + virtual void keyUp(hdKeyEvent &event); + void setDelegateTool(hdDrawingView *view, hdITool *tool); + hdITool *getDelegateTool(); + +protected: + hdITool *_delegateTool; +private: + void deleteAllFigures(hdDrawingView *view); +}; +#endif diff --git a/include/hotdraw/tools/hdSimpleTextTool.h b/include/hotdraw/tools/hdSimpleTextTool.h new file mode 100644 index 0000000..22a59a9 --- /dev/null +++ b/include/hotdraw/tools/hdSimpleTextTool.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdSimpleTextTool.h - Tool to allow edition of textTool with a double click or show a menu with a right click. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDSIMPLETEXTTOOL_H +#define HDSIMPLETEXTTOOL_H + +#include "hotdraw/tools/hdFigureTool.h" +#include "hotdraw/figures/hdSimpleTextFigure.h" + +class hdSimpleTextTool : public hdFigureTool +{ + +public: + hdSimpleTextTool(hdDrawingView *view, hdIFigure *fig, hdITool *dt, bool fastEdit = true, wxString dialogCaption = wxEmptyString, wxString dialogMessage = wxEmptyString); + ~hdSimpleTextTool(); + virtual void mouseDown(hdMouseEvent &event); //Mouse Right Click + virtual void activate(hdDrawingView *view); + virtual void deactivate(hdDrawingView *view); + virtual void mouseDrag(hdMouseEvent &event); + virtual void OnGenericPopupClick(wxCommandEvent &event, hdDrawingView *view); + virtual bool callDialog(hdDrawingView *view); + //Because a bug it was move to main View class instance as a hack. virtual void changeHandler(wxCommandEvent& event); +protected: + bool withoutDialog; + wxString dlgMessage, dlgCaption; +private: + hdSimpleTextFigure *txtFigure; + void calculateSizeEntry(hdDrawingView *view); + bool showEdit; + //Because a bug in the way wxwidgets connect events I can't declare it here, wxTextCtrl *edit, instead I do it on the view instance. +}; + +#endif diff --git a/include/hotdraw/tools/module.mk b/include/hotdraw/tools/module.mk new file mode 100644 index 0000000..163c287 --- /dev/null +++ b/include/hotdraw/tools/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/tools/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/tools/hdAbstractTool.h \ + include/hotdraw/tools/hdCanvasMenuTool.h \ + include/hotdraw/tools/hdCompositeFigureTool.h \ + include/hotdraw/tools/hdConnectionCreationTool.h \ + include/hotdraw/tools/hdCreationTool.h \ + include/hotdraw/tools/hdDragCreationTool.h \ + include/hotdraw/tools/hdDragTrackerTool.h \ + include/hotdraw/tools/hdFigureTool.h \ + include/hotdraw/tools/hdHandleTrackerTool.h \ + include/hotdraw/tools/hdITool.h \ + include/hotdraw/tools/hdMenuTool.h \ + include/hotdraw/tools/hdPolyLineFigureTool.h \ + include/hotdraw/tools/hdSelectAreaTool.h \ + include/hotdraw/tools/hdSelectionTool.h \ + include/hotdraw/tools/hdSimpleTextTool.h + +EXTRA_DIST += \ + include/hotdraw/tools/module.mk diff --git a/include/hotdraw/utilities/hdArrayCollection.h b/include/hotdraw/utilities/hdArrayCollection.h new file mode 100644 index 0000000..3a99485 --- /dev/null +++ b/include/hotdraw/utilities/hdArrayCollection.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdArrayCollection.h - Implementation of Collection Using Arrays +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDARRAYCOLLECTION_H +#define HDARRAYCOLLECTION_H + +// App headers +#include "hotdraw/utilities/hdCollectionBase.h" +#include "hotdraw/main/hdObject.h" + + +WX_DEFINE_ARRAY_PTR(hdObject *, ddObjsArray); + +class hdArrayIterator : public hdIteratorBase +{ +public: + hdArrayIterator(ddObjsArray *ddPtrsArray); + hdObject *Next(); + hdObject *Current(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + ddObjsArray *internalArray; +}; + +class hdArrayDownIterator : public hdIteratorBase +{ +public: + hdArrayDownIterator(ddObjsArray *ddPtrsArray); + hdObject *Next(); + hdObject *Current(); + bool HasNext(); + void ResetIterator(); + +private: + int position; + ddObjsArray *internalArray; +}; + +//Create Array Objects used as base for hdCollections +class hdArrayCollection : public hdCollectionBase +{ +public: + ~hdArrayCollection(); + void addItem(hdObject *item); + void removeItem(hdObject *item); + virtual void removeItemAt(int index); + hdIteratorBase *createIterator(); + hdIteratorBase *createDownIterator(); + hdObject *getItemAt(int index); + void bringToFront(hdObject *item); + void sendToBack(hdObject *item); + int count(); + bool existsObject(hdObject *item); + int getIndex(hdObject *item); + void insertAtIndex(hdObject *item, int index); + void replaceAtIndex(hdObject *item, int index); + void deleteAll(); + void removeAll(); + hdObject *&operator[](size_t index) + { + return ddArray[index]; + } +private: + ddObjsArray ddArray; +}; +#endif diff --git a/include/hotdraw/utilities/hdCollection.h b/include/hotdraw/utilities/hdCollection.h new file mode 100644 index 0000000..9dbed4a --- /dev/null +++ b/include/hotdraw/utilities/hdCollection.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCollection.h - Generic implementation of a Collection used by dd +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOLLECTION_H +#define HDCOLLECTION_H + +// App headers +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdCollectionBase.h" + +class hdCollection : public wxObject +{ +public: + hdCollection(hdCollectionBase *collectionBase); + virtual ~hdCollection(); + void addItem(hdObject *item); + void removeItem(hdObject *item); + void removeItemAt(int index); + void deleteAll(); + void removeAll(); + int count(); + bool existsObject(hdObject *item); + int getIndex(hdObject *item); + hdObject *getItemAt(int index); + void insertAtIndex(hdObject *item, int index); + void replaceAtIndex(hdObject *item, int index); + void bringToFront(hdObject *item); + void sendToBack(hdObject *item); + hdIteratorBase *createIterator(); + hdIteratorBase *createDownIterator(); + +private: + hdCollectionBase *collection; +}; +#endif diff --git a/include/hotdraw/utilities/hdCollectionBase.h b/include/hotdraw/utilities/hdCollectionBase.h new file mode 100644 index 0000000..264ac87 --- /dev/null +++ b/include/hotdraw/utilities/hdCollectionBase.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdCollectionBase.h - A Collection Interface for ERD +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDCOLLECTIONBASE_H +#define HDCOLLECTIONBASE_H + +// App headers +#include "hotdraw/main/hdObject.h" + +// This class it's like an interface (but with not all advantages of this at runtime) +// If in a future I just don't want to use an array, simple implement this abstract class again +// with the new data structure. + +class hdIteratorBase : wxObject +{ +public: + hdIteratorBase() {}; + virtual hdObject *Current() = 0; + virtual hdObject *Next() = 0; + virtual bool HasNext() = 0; + virtual void ResetIterator() = 0; +}; + + +class hdCollectionBase : wxObject +{ +public: + hdCollectionBase() {}; + virtual ~hdCollectionBase() {}; + virtual void addItem(hdObject *item) = 0; + virtual void removeItem(hdObject *item) = 0; + virtual void removeItemAt(int index) = 0; + virtual hdObject *getItemAt(int index) = 0; + virtual hdIteratorBase *createIterator() = 0; + virtual hdIteratorBase *createDownIterator() = 0; + virtual int count() = 0; + virtual bool existsObject(hdObject *item) = 0; + virtual int getIndex(hdObject *item) = 0; + virtual void insertAtIndex(hdObject *item, int index) = 0; + virtual void replaceAtIndex(hdObject *item, int index) = 0; + virtual void bringToFront(hdObject *item) = 0; + virtual void sendToBack(hdObject *item) = 0; + virtual void deleteAll() = 0; + virtual void removeAll() = 0; //remove all items from collection without deleting. +}; +#endif diff --git a/include/hotdraw/utilities/hdGeometry.h b/include/hotdraw/utilities/hdGeometry.h new file mode 100644 index 0000000..3a6dc45 --- /dev/null +++ b/include/hotdraw/utilities/hdGeometry.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdGeometry.h - Utility Geometric Functions Shared between classes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDGEOMETRY_H +#define HDGEOMETRY_H +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" +#include "hotdraw/utilities/hdMultiPosRect.h" + +class hdGeometry : public hdObject +{ +public: + static bool lineContainsPoint(double x1, double y1, double x2, double y2, double px, double py); + static int min(int a, int b); + static int max(int a, int b); + static int min(double a, double b); + static int max(double a, double b); + static double angleFromPoint(hdRect r, hdPoint point); + static double angleFromPoint(int posIdx, hdMultiPosRect r, hdPoint point); + static hdPoint edgePointFromAngle(hdRect r, double angle); + static hdPoint edgePointFromAngle(int posIdx, hdMultiPosRect r, double angle); + static double range(double min, double max, double num); + static double lineSize (hdPoint p1, hdPoint p2); + static bool intersection(hdPoint p1, hdPoint p2, hdPoint p3, hdPoint p4); + static double ddabs(double value); + static int ddabs(int value); + +private: + +}; +#endif diff --git a/include/hotdraw/utilities/hdKeyEvent.h b/include/hotdraw/utilities/hdKeyEvent.h new file mode 100644 index 0000000..787055f --- /dev/null +++ b/include/hotdraw/utilities/hdKeyEvent.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdKeyEvent.h - Wrapper Class to integrate wxKeyEvent inside library. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDKEYEVENT_H +#define HDKEYEVENT_H +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdObject.h" + +class hdDrawingView; + +class hdKeyEvent : public hdObject +{ +public: + hdKeyEvent(wxKeyEvent &event, hdDrawingView *owner); + hdDrawingView *getView(); + int GetKeyCode(); +private: + hdDrawingView *view; + wxKeyEvent &keyEvent; + int keyCode; +}; +#endif diff --git a/include/hotdraw/utilities/hdMouseEvent.h b/include/hotdraw/utilities/hdMouseEvent.h new file mode 100644 index 0000000..7f8eaaf --- /dev/null +++ b/include/hotdraw/utilities/hdMouseEvent.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMouseEvent.h - Wrapper Class to integrate conversion CalcUnscrolledPosition in a mouse event. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDMOUSEEVENT_H +#define HDMOUSEEVENT_H +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/main/hdObject.h" + +class hdDrawingView; + +class hdMouseEvent : public hdObject +{ +public: + hdMouseEvent(wxMouseEvent &event, hdDrawingView *owner); + hdPoint &getUnScrolledPosition(); + hdPoint &getScrolledPosition(); + hdPoint &GetPosition(); + int getUnScrolledPosX(); + int getUnScrolledPosY(); + int getScrolledPosX(); + int getScrolledPosY(); + bool LeftDClick(); + bool LeftDown(); + bool LeftIsDown(); + bool LeftUp(); + bool ShiftDown(); + bool RightDown(); + bool m_shiftDown; + hdDrawingView *getView(); +private: + hdDrawingView *view; + wxMouseEvent &mouseEvent; + hdPoint unScrolled, scrolled; +}; +#endif diff --git a/include/hotdraw/utilities/hdMultiPosRect.h b/include/hotdraw/utilities/hdMultiPosRect.h new file mode 100644 index 0000000..149f5cf --- /dev/null +++ b/include/hotdraw/utilities/hdMultiPosRect.h @@ -0,0 +1,342 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdMultiRect.h - hdRect improved class with new needed functionalities for allowing multiple displaybox for same figure +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDMULTIPOSRECT_H +#define HDMULTIPOSRECT_H +#include "hotdraw/main/hdObject.h" +#include "hotdraw/utilities/hdPoint.h" +#include "hotdraw/utilities/hdRect.h" + +#define MAXPOS 1 + +class hdMultiPosRect : public hdObject +{ +public: + hdMultiPosRect() + : width(0), height(0) + { + init(); + } + + hdMultiPosRect(int xx, int yy, int ww, int hh) + : width(ww), height(hh) + { + init(xx, yy); + } + + hdMultiPosRect(int posIdx, const wxPoint &topLeft, const wxPoint &bottomRight); + + hdMultiPosRect(hdPoint *point) + : width(0), height(0) + { + init(point->x, point->y); + } + + hdMultiPosRect(hdPoint &point) + : width(0), height(0) + { + init(point.x, point.y); + } + + hdMultiPosRect(const wxPoint &pt, const wxSize &size) + : width(size.x), height(size.y) + { + init(pt.x, pt.y); + } + + hdMultiPosRect(const wxSize &size) + : width(size.x), height(size.y) + { + init(0, 0); + } + // default copy ctor and assignment operators ok + + int GetX(int posIdx) const + { + return x[posIdx]; + } + void SetX(int posIdx, int xx) + { + x[posIdx] = xx; + } + + int GetY(int posIdx) const + { + return y[posIdx]; + } + void SetY(int posIdx, int yy) + { + y[posIdx] = yy; + } + + int GetWidth() const + { + return width; + } + void SetWidth(int w) + { + width = w; + } + + int GetHeight() const + { + return height; + } + void SetHeight(int h) + { + height = h; + } + + wxPoint GetPosition(int posIdx) const + { + return wxPoint(x[posIdx], y[posIdx]); + } + void SetPosition( int posIdx, const wxPoint &p ) + { + x[posIdx] = p.x; + y[posIdx] = p.y; + } + + wxSize GetSize() const + { + return wxSize(width, height); + } + void SetSize( const wxSize &s ) + { + width = s.GetWidth(); + height = s.GetHeight(); + } + + bool IsEmpty() const + { + return (width <= 0) || (height <= 0); + } + + int GetLeft(int posIdx) const + { + return x[posIdx]; + } + int GetTop(int posIdx) const + { + return y[posIdx]; + } + int GetBottom(int posIdx) const + { + return y[posIdx] + height - 1; + } + int GetRight(int posIdx) const + { + return x[posIdx] + width - 1; + } + + void SetLeft(int posIdx, int left) + { + x[posIdx] = left; + } + void SetRight(int posIdx, int right) + { + width = right - x[posIdx] + 1; + } + void SetTop(int posIdx, int top) + { + y[posIdx] = top; + } + void SetBottom(int posIdx, int bottom) + { + height = bottom - y[posIdx] + 1; + } + + wxPoint GetTopLeft(int posIdx) const + { + return GetPosition(posIdx); + } + wxPoint GetLeftTop(int posIdx) const + { + return GetTopLeft(posIdx); + } + void SetTopLeft(int posIdx, const wxPoint &p) + { + SetPosition(posIdx, p); + } + void SetLeftTop(int posIdx, const wxPoint &p) + { + SetTopLeft(posIdx, p); + } + + wxPoint GetBottomRight(int posIdx) const + { + return wxPoint(GetRight(posIdx), GetBottom(posIdx)); + } + wxPoint GetRightBottom(int posIdx) const + { + return GetBottomRight(posIdx); + } + void SetBottomRight(int posIdx, const wxPoint &p) + { + SetRight(posIdx, p.x); + SetBottom(posIdx, p.y); + } + void SetRightBottom(int posIdx, const wxPoint &p) + { + SetBottomRight(posIdx, p); + } + + wxPoint GetTopRight(int posIdx) const + { + return wxPoint(GetRight(posIdx), GetTop(posIdx)); + } + wxPoint GetRightTop(int posIdx) const + { + return GetTopRight(posIdx); + } + void SetTopRight(int posIdx, const wxPoint &p) + { + SetRight(posIdx, p.x); + SetTop(posIdx, p.y); + } + void SetRightTop(int posIdx, const wxPoint &p) + { + SetTopLeft(posIdx, p); + } + + wxPoint GetBottomLeft(int posIdx) const + { + return wxPoint(GetLeft(posIdx), GetBottom(posIdx)); + } + wxPoint GetLeftBottom(int posIdx) const + { + return GetBottomLeft(posIdx); + } + void SetBottomLeft(int posIdx, const wxPoint &p) + { + SetLeft(posIdx, p.x); + SetBottom(posIdx, p.y); + } + void SetLeftBottom(int posIdx, const wxPoint &p) + { + SetBottomLeft(posIdx, p); + } + + // operations with rect + hdMultiPosRect &Inflate(int posIdx, wxCoord dx, wxCoord dy); + hdMultiPosRect &Inflate(int posIdx, const wxSize &d) + { + return Inflate(posIdx, d.x, d.y); + } + hdMultiPosRect &Inflate(int posIdx, wxCoord d) + { + return Inflate(posIdx, d, d); + } + + hdMultiPosRect Inflate(int posIdx, wxCoord dx, wxCoord dy) const + { + hdMultiPosRect r = *this; + r.Inflate(posIdx, dx, dy); + return r; + } + + hdMultiPosRect &Deflate(int posIdx, wxCoord dx, wxCoord dy) + { + return Inflate(posIdx, -dx, -dy); + } + hdMultiPosRect &Deflate(int posIdx, const wxSize &d) + { + return Inflate(posIdx, -d.x, -d.y); + } + hdMultiPosRect &Deflate(int posIdx, wxCoord d) + { + return Inflate(posIdx, -d); + } + + hdMultiPosRect Deflate(int posIdx, wxCoord dx, wxCoord dy) const + { + hdMultiPosRect r = *this; + r.Deflate(posIdx, dx, dy); + return r; + } + + + void Offset(int posIdx, wxCoord dx, wxCoord dy) + { + x[posIdx] += dx; + y[posIdx] += dy; + } + void Offset(int posIdx, const wxPoint &pt) + { + Offset(posIdx, pt.x, pt.y); + } + + hdMultiPosRect &Intersect(int posIdx, const hdMultiPosRect &rect); + + hdMultiPosRect Intersect(int posIdx, const hdMultiPosRect &rect) const + { + hdMultiPosRect r = *this; + r.Intersect(posIdx, rect); + return r; + } + + hdMultiPosRect &Union(int posIdx, const hdMultiPosRect &rect); + + + hdMultiPosRect Union(int posIdx, const hdMultiPosRect &rect) const + { + hdMultiPosRect r = *this; + r.Union(posIdx, rect); + return r; + } + + // return true if the point is (not strcitly) inside the rect + bool Contains(int posIdx, int x, int y) const; + bool Contains(int posIdx, const wxPoint &pt) const + { + return Contains(posIdx, pt.x, pt.y); + } + // return true if the rectangle is (not strcitly) inside the rect + bool Contains(int posIdx, const hdRect &rect) const; + + // return true if the rectangles have a non empty intersection + bool Intersects(int posIdx, const hdMultiPosRect &rect) const; + + // centre this rectangle in the given (usually, but not necessarily, + // larger) one + hdMultiPosRect CentreIn(int posIdxThis, const hdMultiPosRect &r, int posIdxr, int dir = wxBOTH) const + { + return hdMultiPosRect(dir & wxHORIZONTAL ? r.x[posIdxr] + (r.width - width) / 2 : x[posIdxThis], + dir & wxVERTICAL ? r.y[posIdxr] + (r.height - height) / 2 : y[posIdxThis], + width, height); + } + + hdMultiPosRect CenterIn(int posIdxThis, const hdMultiPosRect &r, int posIdxr, int dir = wxBOTH) const + { + return CentreIn(posIdxThis, r, posIdxr, dir); + } + + void add (int posIdx, int newX, int netY); + void add (int posIdx, hdRect *newRect); + void add (int posIdx, hdRect newRect); + void add (int posIdx, hdPoint *p); + hdPoint center(int posIdx); + hdRect gethdRect(int posIdx) + { + return hdRect(x[posIdx], y[posIdx], width, height); + } + int CountPositions(); + void addNewXYPosition(); + void removeXYPosition(int posIdx); + wxArrayInt x, y; + int width, height; + +private: + void init(int valX = 0, int valY = 0); + hdPoint point; +}; +#endif + diff --git a/include/hotdraw/utilities/hdPoint.h b/include/hotdraw/utilities/hdPoint.h new file mode 100644 index 0000000..632fd0c --- /dev/null +++ b/include/hotdraw/utilities/hdPoint.h @@ -0,0 +1,24 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdPoint.h - wxPoint class to be used as wrapper and allow independence of point class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDPOINT_H +#define HDPOINT_H + +class hdPoint : public wxPoint +{ +public: + hdPoint(); + hdPoint(int x, int y); + hdPoint(const hdPoint &p); + hdPoint(const wxPoint &p); +}; + +#endif diff --git a/include/hotdraw/utilities/hdRect.h b/include/hotdraw/utilities/hdRect.h new file mode 100644 index 0000000..2679943 --- /dev/null +++ b/include/hotdraw/utilities/hdRect.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// hdRect.h - wxRect improved class with new needed functionalities +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDRECT_H +#define HDRECT_H +#include "hotdraw/utilities/hdPoint.h" + +class hdRect : public wxRect +{ +public: + hdRect(); + hdRect(int xx, int yy, int ww, int hh); + hdRect(hdPoint *topLeft, hdPoint *bottomRight); + hdRect(hdPoint *point); + hdRect(hdPoint &point); + void add (int newX, int netY); + void add (hdRect *newRect); + void add (hdRect newRect); + void add (hdPoint *p); + hdPoint center(); +protected: + +private: + hdPoint point; +}; +#endif diff --git a/include/hotdraw/utilities/hdRemoveDeleteDialog.h b/include/hotdraw/utilities/hdRemoveDeleteDialog.h new file mode 100644 index 0000000..74a0b98 --- /dev/null +++ b/include/hotdraw/utilities/hdRemoveDeleteDialog.h @@ -0,0 +1,64 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ddPrecisionScaleDialog.h - Utility dialog class to allow user input of precision and scale +// +////////////////////////////////////////////////////////////////////////// + +#ifndef HDREMOVEDELETEDIALOG_H +#define HDREMOVEDELETEDIALOG_H + +#include +#include + +enum ddRemoveDeleteButtons +{ + DD_REMOVE = 31000, + DD_DELETE = 32000 +}; + +class hdRemoveDeleteDialog : public wxDialog +{ + DECLARE_CLASS( hdRemoveDeleteDialog ) + DECLARE_EVENT_TABLE() +public: + hdRemoveDeleteDialog(); + hdRemoveDeleteDialog( const wxString &message, + const wxString &caption = _("Title"), + wxWindow *parent = NULL, + bool allowRemove = true + ); + ~hdRemoveDeleteDialog(); + + // Member initialization + void Init(); + + // Creation + bool Create( wxWindow *parent, + wxWindowID id, + const wxString &message, + const wxString &caption + ); + + // Creates the controls and sizers + void CreateControls(const wxString &message); + + //Buttons Events + void OnRemove(wxCommandEvent &WXUNUSED(event)); + void OnDelete(wxCommandEvent &WXUNUSED(event)); + void OnCancel(wxCommandEvent &WXUNUSED(event)); + +private: + bool allowRemoveButton; + wxBoxSizer *topSizer, *messageSizer, *buttonsSizer; + wxStaticText *staticText, *staticText2, *staticText3; + wxStaticLine *line; + wxButton *removeButton, *deleteButton, *cancelButton; + +}; +#endif + diff --git a/include/hotdraw/utilities/module.mk b/include/hotdraw/utilities/module.mk new file mode 100644 index 0000000..877f8e2 --- /dev/null +++ b/include/hotdraw/utilities/module.mk @@ -0,0 +1,25 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/hotdraw/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/hotdraw/utilities/hdArrayCollection.h \ + include/hotdraw/utilities/hdCollection.h \ + include/hotdraw/utilities/hdCollectionBase.h \ + include/hotdraw/utilities/hdGeometry.h \ + include/hotdraw/utilities/hdKeyEvent.h \ + include/hotdraw/utilities/hdMultiPosRect.h \ + include/hotdraw/utilities/hdMouseEvent.h \ + include/hotdraw/utilities/hdPoint.h \ + include/hotdraw/utilities/hdRect.h \ + include/hotdraw/utilities/hdRemoveDeleteDialog.h + +EXTRA_DIST += \ + include/hotdraw/utilities/module.mk diff --git a/include/images/aggregate-sm.png b/include/images/aggregate-sm.png new file mode 100644 index 0000000..d463819 Binary files /dev/null and b/include/images/aggregate-sm.png differ diff --git a/include/images/aggregate-sm.pngc b/include/images/aggregate-sm.pngc new file mode 100644 index 0000000..6a05b9a --- /dev/null +++ b/include/images/aggregate-sm.pngc @@ -0,0 +1,88 @@ +#ifndef AGGREGATE_SM_PNG_H +#define AGGREGATE_SM_PNG_H + +static const unsigned char aggregate_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xaa, +0xaa, 0xaa, 0xc9, 0xdf, 0xf1, 0xcb, 0xdf, 0xf1, +0xcd, 0xe0, 0xf1, 0xcf, 0xe1, 0xf2, 0xd2, 0xe2, +0xf2, 0xd5, 0xe3, 0xf3, 0x9c, 0xbe, 0x44, 0xd8, +0xe4, 0xf3, 0xdb, 0xe5, 0xf3, 0xde, 0xe7, 0xf4, +0x88, 0x88, 0x88, 0xe1, 0xe8, 0xf4, 0xe4, 0xe9, +0xf5, 0xe6, 0xea, 0xf5, 0xe9, 0xeb, 0xf6, 0xeb, +0xeb, 0xf6, 0xec, 0xec, 0xf6, 0x23, 0xef, 0x32, +0x78, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5a, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, 0xce, 0x49, +0x0e, 0x80, 0x20, 0x10, 0x44, 0x51, 0x9a, 0x59, +0xa0, 0x98, 0xbc, 0xff, 0x5d, 0x05, 0x34, 0x74, +0xe2, 0xc2, 0x58, 0x3b, 0xde, 0xef, 0x05, 0x42, +0xfc, 0x1a, 0xdd, 0x93, 0xfb, 0xad, 0x94, 0x36, +0xd6, 0x79, 0xda, 0xa0, 0x8f, 0xb9, 0xc0, 0x60, +0x16, 0x44, 0x06, 0x3b, 0xee, 0x43, 0x4c, 0x0c, +0x0e, 0x08, 0x40, 0x66, 0xf0, 0xb3, 0xe7, 0xc2, +0x30, 0x72, 0x02, 0x2a, 0x43, 0x9c, 0xbd, 0xb6, +0x07, 0x24, 0xd1, 0xc8, 0x05, 0xe8, 0x7c, 0xb1, +0x7a, 0x3f, 0x37, 0xc8, 0xf7, 0xd7, 0xbf, 0x77, +0x01, 0x88, 0xeb, 0x03, 0x2f, 0xf0, 0x2a, 0xa3, +0xab, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *aggregate_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_aggregate_sm_png = new wxImage(); + if (!img_aggregate_sm_png || !img_aggregate_sm_png->IsOk()) + { + wxMemoryInputStream img_aggregate_sm_pngIS(aggregate_sm_png_data, sizeof(aggregate_sm_png_data)); + img_aggregate_sm_png->LoadFile(img_aggregate_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_aggregate_sm_png; +} +#define aggregate_sm_png_img aggregate_sm_png_img() + +static wxBitmap *aggregate_sm_png_bmp() +{ + static wxBitmap *bmp_aggregate_sm_png; + if (!bmp_aggregate_sm_png || !bmp_aggregate_sm_png->IsOk()) + bmp_aggregate_sm_png = new wxBitmap(*aggregate_sm_png_img); + return bmp_aggregate_sm_png; +} +#define aggregate_sm_png_bmp aggregate_sm_png_bmp() + +static wxIcon *aggregate_sm_png_ico() +{ + static wxIcon *ico_aggregate_sm_png; + if (!ico_aggregate_sm_png || !ico_aggregate_sm_png->IsOk()) + { + ico_aggregate_sm_png = new wxIcon(); + ico_aggregate_sm_png->CopyFromBitmap(*aggregate_sm_png_bmp); + } + return ico_aggregate_sm_png; +} +#define aggregate_sm_png_ico aggregate_sm_png_ico() + +#endif // AGGREGATE_SM_PNG_H diff --git a/include/images/aggregate.png b/include/images/aggregate.png new file mode 100644 index 0000000..3145a3c Binary files /dev/null and b/include/images/aggregate.png differ diff --git a/include/images/aggregate.pngc b/include/images/aggregate.pngc new file mode 100644 index 0000000..d66632c --- /dev/null +++ b/include/images/aggregate.pngc @@ -0,0 +1,91 @@ +#ifndef AGGREGATE_PNG_H +#define AGGREGATE_PNG_H + +static const unsigned char aggregate_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x4b, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xc9, +0xdf, 0xf1, 0xca, 0xdf, 0xf1, 0xcc, 0xe0, 0xf1, +0xcd, 0xe0, 0xf2, 0xcf, 0xe1, 0xf2, 0xd0, 0xe1, +0xf2, 0xd2, 0xe2, 0xf2, 0xd4, 0xe3, 0xf3, 0xd6, +0xe4, 0xf3, 0x9c, 0xbe, 0x44, 0xd8, 0xe5, 0xf3, +0xdb, 0xe5, 0xf3, 0xdd, 0xe6, 0xf4, 0x88, 0x88, +0x88, 0xdf, 0xe7, 0xf4, 0xe1, 0xe8, 0xf4, 0xe3, +0xe9, 0xf5, 0xe5, 0xe9, 0xf5, 0xe7, 0xea, 0xf5, +0xe8, 0xeb, 0xf5, 0xea, 0xeb, 0xf6, 0xeb, 0xec, +0xf6, 0xec, 0xec, 0xf6, 0x74, 0x44, 0xc1, 0xce, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x62, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, 0x49, 0x0e, +0xc2, 0x30, 0x14, 0x04, 0xd1, 0xef, 0x84, 0x8c, +0xd8, 0x54, 0xe6, 0x70, 0xff, 0x93, 0x22, 0xa1, +0x0a, 0x12, 0xe9, 0xe5, 0x53, 0x6d, 0x3a, 0x22, +0x22, 0xfd, 0x16, 0xdf, 0xa5, 0xaa, 0xaa, 0x1f, +0x4d, 0xdb, 0xf5, 0xc3, 0x98, 0x84, 0xa7, 0xcb, +0x42, 0x7d, 0x41, 0x11, 0xec, 0x73, 0x79, 0x09, +0x0d, 0xf4, 0x90, 0x61, 0x12, 0x5a, 0x18, 0xa0, +0xc0, 0x2c, 0xd8, 0x4f, 0xf3, 0x22, 0xd8, 0xc3, +0x2a, 0xd8, 0xc3, 0x26, 0xd8, 0xaf, 0xdb, 0x2e, +0xd8, 0xc3, 0x21, 0xd8, 0xc3, 0x29, 0xd8, 0x1f, +0xe7, 0xfb, 0x7a, 0x77, 0x7b, 0xfb, 0xbf, 0x0f, +0x71, 0xc3, 0x06, 0xdd, 0x5a, 0xcc, 0x5e, 0xff, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *aggregate_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_aggregate_png = new wxImage(); + if (!img_aggregate_png || !img_aggregate_png->IsOk()) + { + wxMemoryInputStream img_aggregate_pngIS(aggregate_png_data, sizeof(aggregate_png_data)); + img_aggregate_png->LoadFile(img_aggregate_pngIS, wxBITMAP_TYPE_PNG); + } + return img_aggregate_png; +} +#define aggregate_png_img aggregate_png_img() + +static wxBitmap *aggregate_png_bmp() +{ + static wxBitmap *bmp_aggregate_png; + if (!bmp_aggregate_png || !bmp_aggregate_png->IsOk()) + bmp_aggregate_png = new wxBitmap(*aggregate_png_img); + return bmp_aggregate_png; +} +#define aggregate_png_bmp aggregate_png_bmp() + +static wxIcon *aggregate_png_ico() +{ + static wxIcon *ico_aggregate_png; + if (!ico_aggregate_png || !ico_aggregate_png->IsOk()) + { + ico_aggregate_png = new wxIcon(); + ico_aggregate_png->CopyFromBitmap(*aggregate_png_bmp); + } + return ico_aggregate_png; +} +#define aggregate_png_ico aggregate_png_ico() + +#endif // AGGREGATE_PNG_H diff --git a/include/images/aggregates.png b/include/images/aggregates.png new file mode 100644 index 0000000..c75fa9a Binary files /dev/null and b/include/images/aggregates.png differ diff --git a/include/images/aggregates.pngc b/include/images/aggregates.pngc new file mode 100644 index 0000000..d594f85 --- /dev/null +++ b/include/images/aggregates.pngc @@ -0,0 +1,91 @@ +#ifndef AGGREGATES_PNG_H +#define AGGREGATES_PNG_H + +static const unsigned char aggregates_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xaa, +0xaa, 0xaa, 0xc9, 0xdf, 0xf1, 0xcb, 0xdf, 0xf1, +0xcd, 0xe0, 0xf1, 0xcf, 0xe1, 0xf2, 0xd2, 0xe2, +0xf2, 0xd5, 0xe3, 0xf3, 0x82, 0x90, 0x5d, 0x9c, +0xbe, 0x44, 0xd8, 0xe4, 0xf3, 0xdb, 0xe5, 0xf3, +0xde, 0xe7, 0xf4, 0x88, 0x88, 0x88, 0xe1, 0xe8, +0xf4, 0xe4, 0xe9, 0xf5, 0xe6, 0xea, 0xf5, 0xe9, +0xeb, 0xf6, 0xeb, 0xeb, 0xf6, 0xec, 0xec, 0xf6, +0xec, 0x38, 0xb1, 0x22, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x5d, 0xcf, 0x49, 0x16, 0x80, 0x20, 0x0c, 0x44, +0x41, 0x82, 0x13, 0x0a, 0x34, 0xa2, 0xde, 0xff, +0xac, 0xd2, 0x44, 0xe5, 0x49, 0x96, 0x3f, 0xb5, +0x48, 0x8c, 0x31, 0xa2, 0x63, 0xcd, 0x33, 0x32, +0x0c, 0xe3, 0x34, 0x2f, 0x4e, 0x5a, 0x58, 0xff, +0x46, 0xc6, 0xce, 0xc8, 0xd4, 0x19, 0x99, 0x3b, +0x23, 0x0b, 0xcd, 0xc6, 0xf1, 0x1a, 0x1c, 0x4d, +0x0d, 0x41, 0x83, 0xa7, 0x29, 0xde, 0x87, 0xa8, +0x21, 0xd0, 0x00, 0x1e, 0x48, 0x1a, 0x22, 0x0d, +0xf7, 0x69, 0xaf, 0xc1, 0x0a, 0x0d, 0x10, 0x81, +0xfc, 0x5e, 0x52, 0x0c, 0xf7, 0xf9, 0x78, 0xcf, +0x2f, 0x06, 0xd8, 0x81, 0xb3, 0xfd, 0x53, 0xf7, +0xe7, 0xf5, 0x05, 0xdb, 0x4e, 0xbf, 0x01, 0xda, +0xed, 0x04, 0x68, 0xe7, 0xfb, 0x5e, 0x1d, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *aggregates_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_aggregates_png = new wxImage(); + if (!img_aggregates_png || !img_aggregates_png->IsOk()) + { + wxMemoryInputStream img_aggregates_pngIS(aggregates_png_data, sizeof(aggregates_png_data)); + img_aggregates_png->LoadFile(img_aggregates_pngIS, wxBITMAP_TYPE_PNG); + } + return img_aggregates_png; +} +#define aggregates_png_img aggregates_png_img() + +static wxBitmap *aggregates_png_bmp() +{ + static wxBitmap *bmp_aggregates_png; + if (!bmp_aggregates_png || !bmp_aggregates_png->IsOk()) + bmp_aggregates_png = new wxBitmap(*aggregates_png_img); + return bmp_aggregates_png; +} +#define aggregates_png_bmp aggregates_png_bmp() + +static wxIcon *aggregates_png_ico() +{ + static wxIcon *ico_aggregates_png; + if (!ico_aggregates_png || !ico_aggregates_png->IsOk()) + { + ico_aggregates_png = new wxIcon(); + ico_aggregates_png->CopyFromBitmap(*aggregates_png_bmp); + } + return ico_aggregates_png; +} +#define aggregates_png_ico aggregates_png_ico() + +#endif // AGGREGATES_PNG_H diff --git a/include/images/back.png b/include/images/back.png new file mode 100644 index 0000000..7fd33c3 Binary files /dev/null and b/include/images/back.png differ diff --git a/include/images/back.pngc b/include/images/back.pngc new file mode 100644 index 0000000..96ca1c6 --- /dev/null +++ b/include/images/back.pngc @@ -0,0 +1,89 @@ +#ifndef BACK_PNG_H +#define BACK_PNG_H + +static const unsigned char back_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, +0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, +0xcb, 0x00, 0x00, 0x00, 0x1e, 0x50, 0x4c, 0x54, +0x45, 0xd6, 0xd3, 0xce, 0x31, 0xff, 0x9c, 0x84, +0x82, 0x84, 0x00, 0x82, 0x84, 0xce, 0xcf, 0xff, +0x00, 0x82, 0x00, 0x00, 0xff, 0x00, 0x00, 0x34, +0x39, 0x21, 0x20, 0x21, 0x42, 0x9a, 0xa5, 0xdd, +0x01, 0x71, 0xcc, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x87, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x20, 0x00, 0x84, 0x90, +0xd8, 0x8c, 0xc2, 0x48, 0x1c, 0x41, 0x57, 0x05, +0x84, 0x84, 0x48, 0x6a, 0x01, 0x42, 0xc2, 0xd1, +0xb5, 0x08, 0x21, 0x21, 0x92, 0xda, 0x8c, 0x90, +0x70, 0x74, 0xed, 0x50, 0x80, 0x4b, 0x88, 0xa4, +0xa4, 0x14, 0xc0, 0x25, 0xdc, 0xdc, 0xdc, 0xcc, +0x91, 0x24, 0x52, 0x3a, 0xc0, 0x1c, 0x36, 0x41, +0x41, 0x31, 0x20, 0x80, 0x70, 0x18, 0x22, 0x67, +0x82, 0x40, 0x3b, 0x84, 0xc3, 0x3a, 0x75, 0xea, +0xd4, 0xd0, 0x50, 0x28, 0x87, 0x21, 0x32, 0x32, +0x34, 0x34, 0xb4, 0x98, 0x01, 0x2e, 0x15, 0x1a, +0x0a, 0x77, 0x42, 0x64, 0x68, 0x44, 0x47, 0x03, +0x94, 0xad, 0xa4, 0x3a, 0x35, 0xbc, 0xdc, 0x48, +0x09, 0xe2, 0x06, 0x26, 0xa5, 0xca, 0xf0, 0x22, +0x25, 0x25, 0x25, 0x88, 0x14, 0x93, 0xfa, 0x74, +0x20, 0x07, 0xe6, 0x25, 0xa5, 0x72, 0x98, 0x38, +0x0e, 0x00, 0x00, 0xca, 0x85, 0x1e, 0xd7, 0x5c, +0x7e, 0x80, 0x21, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *back_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_back_png = new wxImage(); + if (!img_back_png || !img_back_png->IsOk()) + { + wxMemoryInputStream img_back_pngIS(back_png_data, sizeof(back_png_data)); + img_back_png->LoadFile(img_back_pngIS, wxBITMAP_TYPE_PNG); + } + return img_back_png; +} +#define back_png_img back_png_img() + +static wxBitmap *back_png_bmp() +{ + static wxBitmap *bmp_back_png; + if (!bmp_back_png || !bmp_back_png->IsOk()) + bmp_back_png = new wxBitmap(*back_png_img); + return bmp_back_png; +} +#define back_png_bmp back_png_bmp() + +static wxIcon *back_png_ico() +{ + static wxIcon *ico_back_png; + if (!ico_back_png || !ico_back_png->IsOk()) + { + ico_back_png = new wxIcon(); + ico_back_png->CopyFromBitmap(*back_png_bmp); + } + return ico_back_png; +} +#define back_png_ico back_png_ico() + +#endif // BACK_PNG_H diff --git a/include/images/backup.png b/include/images/backup.png new file mode 100644 index 0000000..c5f0e42 Binary files /dev/null and b/include/images/backup.png differ diff --git a/include/images/backup.pngc b/include/images/backup.pngc new file mode 100644 index 0000000..330a04c --- /dev/null +++ b/include/images/backup.pngc @@ -0,0 +1,146 @@ +#ifndef BACKUP_PNG_H +#define BACKUP_PNG_H + +static const unsigned char backup_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfa, 0xf9, 0xf4, 0xe6, +0xde, 0xc0, 0xd3, 0xc5, 0x91, 0xc3, 0xb0, 0x6a, +0xb7, 0xa0, 0x4b, 0xaf, 0x96, 0x37, 0xd1, 0xc3, +0x8d, 0xb2, 0x9b, 0x3b, 0xc6, 0xb4, 0x69, 0xda, +0xcb, 0x8e, 0xe6, 0xdc, 0xa9, 0xed, 0xe8, 0xbd, +0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, 0xdf, +0xa2, 0xd6, 0xce, 0x88, 0xca, 0xbd, 0x6d, 0xbc, +0xad, 0x52, 0xaf, 0x98, 0x36, 0xc1, 0xad, 0x63, +0xdd, 0xd0, 0x99, 0xff, 0xfd, 0xee, 0xff, 0xfd, +0xe3, 0xfe, 0xf9, 0xd8, 0xf9, 0xf9, 0xd1, 0xf5, +0xf0, 0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, 0xb2, +0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, 0xdf, +0x9b, 0xc7, 0xbc, 0x6a, 0xb0, 0x98, 0x3b, 0xe9, +0xe1, 0xb7, 0xfc, 0xf9, 0xd9, 0xfa, 0xf7, 0xcf, +0xf4, 0xf4, 0xc7, 0xee, 0xee, 0xbe, 0xed, 0xed, +0xbb, 0xec, 0xe9, 0xbf, 0xed, 0xed, 0xca, 0xf4, +0xf4, 0xdb, 0xfc, 0xf9, 0xf2, 0xb8, 0xa2, 0x4e, +0xac, 0x92, 0x30, 0xe3, 0xdb, 0xbd, 0xe9, 0xdc, +0xb9, 0xed, 0xe3, 0xbb, 0xf5, 0xf0, 0xd4, 0xf5, +0xf2, 0xd9, 0xfb, 0xfb, 0xf1, 0xfe, 0xfe, 0xfb, +0xf7, 0xf4, 0xe8, 0xf0, 0xed, 0xd2, 0xec, 0xe9, +0xc4, 0xea, 0xe2, 0xba, 0xe5, 0xdd, 0xc2, 0xf4, +0xea, 0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, 0xee, +0xfe, 0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, 0xe1, +0x98, 0xe3, 0xd8, 0x83, 0xe0, 0xda, 0x7b, 0xdf, +0xda, 0x84, 0xe4, 0xe1, 0x96, 0xe8, 0xe3, 0xab, +0xf3, 0xe9, 0xda, 0x7f, 0x9e, 0xb9, 0x2c, 0x66, +0xbd, 0x83, 0xa5, 0xd8, 0xf2, 0xe8, 0xd9, 0xff, +0xfa, 0xef, 0x9b, 0xd0, 0xe1, 0xf2, 0xf9, 0xfc, +0xe3, 0xf3, 0xf9, 0xdb, 0xf1, 0xf8, 0xe4, 0xf5, +0xfb, 0x9d, 0xc8, 0xe6, 0xff, 0xfa, 0xf4, 0xff, +0xf9, 0xee, 0xff, 0xf3, 0xd3, 0x7a, 0xbf, 0xd7, +0xb1, 0xb1, 0xb1, 0xc8, 0xeb, 0xf7, 0x7e, 0xb4, +0xe0, 0x7b, 0xbe, 0xd8, 0xea, 0xf6, 0xfb, 0xd2, +0xee, 0xf8, 0xda, 0xf2, 0xfa, 0x7f, 0xb2, 0xe1, +0x7c, 0xbc, 0xda, 0x3b, 0x7f, 0xc4, 0x3c, 0x7b, +0xc8, 0x80, 0xb0, 0xe3, 0xfe, 0xf4, 0xd1, 0x7c, +0xba, 0xdb, 0x51, 0xa1, 0xd0, 0x52, 0x9f, 0xd2, +0x53, 0x9c, 0xd4, 0x53, 0x9a, 0xd5, 0x54, 0x97, +0xd7, 0x55, 0x95, 0xd9, 0x80, 0xae, 0xe3, 0xf2, +0xea, 0xd9, 0x7d, 0xb9, 0xdc, 0x3c, 0x7d, 0xc6, +0x3d, 0x79, 0xc9, 0x56, 0x92, 0xdb, 0x80, 0xac, +0xe5, 0xcb, 0xbc, 0x82, 0xff, 0xf8, 0xf2, 0x93, +0xc3, 0xe3, 0xe0, 0xf2, 0xf9, 0x56, 0x90, 0xdc, +0x81, 0xaa, 0xe6, 0xb0, 0x99, 0x39, 0xc2, 0xae, +0x65, 0xdb, 0xc6, 0x94, 0xed, 0xdd, 0xb5, 0xf3, +0xe6, 0xbe, 0x7e, 0x9d, 0xb7, 0xec, 0xf7, 0xfc, +0xdc, 0xf3, 0xfa, 0xa0, 0xbe, 0xed, 0x62, 0x7a, +0x86, 0x9b, 0xdc, 0xf3, 0x54, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x64, 0x62, 0x66, 0x61, 0x65, +0x03, 0x02, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06, +0x06, 0x06, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, +0x5e, 0x3e, 0x7e, 0x01, 0x41, 0x21, 0x61, 0x76, +0xa0, 0x80, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, +0x94, 0xb4, 0x8c, 0xac, 0x9c, 0xbc, 0x82, 0x08, +0x50, 0x40, 0x51, 0x49, 0x4c, 0x5c, 0x59, 0x45, +0x55, 0x4d, 0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x07, +0x28, 0xa0, 0xab, 0xa7, 0x6f, 0x60, 0x68, 0x64, +0x6c, 0x6c, 0x62, 0x6a, 0x66, 0x6e, 0xa1, 0x0b, +0x12, 0xb0, 0xb4, 0xb2, 0xb6, 0xb1, 0xb5, 0xb3, +0x77, 0x70, 0x74, 0x72, 0x76, 0x81, 0x08, 0xb8, +0x02, 0x05, 0xdc, 0xdc, 0xa1, 0xc0, 0x03, 0x28, +0xe0, 0x69, 0xed, 0x65, 0xeb, 0xee, 0xed, 0xee, +0xe3, 0xeb, 0xe7, 0xef, 0x1e, 0xe0, 0x0e, 0x12, +0x08, 0x0c, 0x0a, 0x76, 0x0f, 0x71, 0xf7, 0x0d, +0x0d, 0x0d, 0x73, 0x0f, 0x87, 0x0a, 0xd8, 0xba, +0x47, 0xb8, 0x47, 0x46, 0x85, 0x45, 0xbb, 0xc7, +0xb8, 0xc3, 0xb4, 0xc4, 0xc6, 0x81, 0x4c, 0x88, +0x4f, 0x00, 0x09, 0xb8, 0x06, 0x7a, 0x25, 0xba, +0x27, 0x25, 0xa7, 0xa4, 0xa6, 0xa5, 0x67, 0x64, +0x82, 0x04, 0xb2, 0x40, 0x5a, 0xb2, 0x73, 0x80, +0x0a, 0x72, 0xf3, 0xf2, 0x81, 0x02, 0x05, 0x56, +0x85, 0x40, 0x81, 0x22, 0x77, 0x9f, 0x62, 0x7f, +0xf7, 0x92, 0x52, 0x77, 0x06, 0xf6, 0xb2, 0xf2, +0x8a, 0xca, 0xaa, 0x6a, 0x77, 0xf7, 0x9a, 0xa8, +0x5a, 0xf7, 0xd2, 0x3a, 0x77, 0x06, 0xa8, 0xf7, +0xeb, 0x61, 0x0e, 0x03, 0x00, 0xab, 0xbd, 0x39, +0xe2, 0xd9, 0x12, 0x90, 0xf4, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x32, 0x33, 0x54, 0x30, 0x33, 0x3a, 0x30, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x44, 0xd4, 0x3d, 0x9a, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *backup_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_backup_png = new wxImage(); + if (!img_backup_png || !img_backup_png->IsOk()) + { + wxMemoryInputStream img_backup_pngIS(backup_png_data, sizeof(backup_png_data)); + img_backup_png->LoadFile(img_backup_pngIS, wxBITMAP_TYPE_PNG); + } + return img_backup_png; +} +#define backup_png_img backup_png_img() + +static wxBitmap *backup_png_bmp() +{ + static wxBitmap *bmp_backup_png; + if (!bmp_backup_png || !bmp_backup_png->IsOk()) + bmp_backup_png = new wxBitmap(*backup_png_img); + return bmp_backup_png; +} +#define backup_png_bmp backup_png_bmp() + +static wxIcon *backup_png_ico() +{ + static wxIcon *ico_backup_png; + if (!ico_backup_png || !ico_backup_png->IsOk()) + { + ico_backup_png = new wxIcon(); + ico_backup_png->CopyFromBitmap(*backup_png_bmp); + } + return ico_backup_png; +} +#define backup_png_ico backup_png_ico() + +#endif // BACKUP_PNG_H diff --git a/include/images/baddatabase.png b/include/images/baddatabase.png new file mode 100644 index 0000000..159ddc7 Binary files /dev/null and b/include/images/baddatabase.png differ diff --git a/include/images/baddatabase.pngc b/include/images/baddatabase.pngc new file mode 100644 index 0000000..6d997e3 --- /dev/null +++ b/include/images/baddatabase.pngc @@ -0,0 +1,143 @@ +#ifndef BADDATABASE_PNG_H +#define BADDATABASE_PNG_H + +static const unsigned char baddatabase_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x6e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc3, 0xb0, 0x6a, 0xb7, +0xa0, 0x4b, 0xaf, 0x96, 0x37, 0xc6, 0xb4, 0x69, +0xd8, 0xcd, 0x8b, 0xe6, 0xdc, 0xa9, 0xed, 0xe9, +0xbe, 0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, +0xdf, 0xa2, 0xca, 0xbd, 0x6d, 0xbc, 0xad, 0x52, +0xaf, 0x98, 0x36, 0xd1, 0xc3, 0x8d, 0xc1, 0xad, +0x64, 0xe6, 0xd0, 0x9c, 0xff, 0xfd, 0xee, 0xff, +0xfd, 0xe3, 0xfd, 0xf9, 0xd9, 0xf9, 0xf9, 0xd1, +0xf5, 0xf0, 0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, +0xb2, 0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, +0xdf, 0x9b, 0xc7, 0xbc, 0x6a, 0xb1, 0x99, 0x3a, +0xea, 0xe2, 0xb9, 0xfa, 0xf7, 0xcf, 0xf4, 0xf4, +0xc7, 0xee, 0xee, 0xbe, 0xed, 0xed, 0xbb, 0xed, +0xed, 0xca, 0xf4, 0xf4, 0xdb, 0xfc, 0xf9, 0xf2, +0xb8, 0xa2, 0x4e, 0xac, 0x92, 0x30, 0xe3, 0xdb, +0xbd, 0xe9, 0xdc, 0xb9, 0xed, 0xe3, 0xbb, 0xf5, +0xf0, 0xd4, 0xf5, 0xf2, 0xd9, 0xfb, 0xfb, 0xf1, +0xfe, 0xfe, 0xfb, 0xf7, 0xf4, 0xe8, 0xf0, 0xed, +0xd2, 0xec, 0xe9, 0xc4, 0xe5, 0xdd, 0xc2, 0xf4, +0xea, 0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, 0xee, +0xfe, 0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, 0xe1, +0x98, 0xd3, 0x67, 0x3f, 0xc8, 0x0b, 0x07, 0xc5, +0x00, 0x00, 0xd3, 0x5b, 0x44, 0xb1, 0x77, 0x27, +0xf3, 0xe9, 0xda, 0xf6, 0xee, 0xb4, 0xd5, 0x5d, +0x3f, 0xd5, 0x27, 0x27, 0xf4, 0x6b, 0x6b, 0xf5, +0x6c, 0x6d, 0xf3, 0x66, 0x66, 0xe0, 0x3a, 0x3a, +0xf2, 0xe8, 0xd9, 0xff, 0xfa, 0xef, 0xe9, 0xaf, +0x84, 0xd3, 0x1e, 0x1e, 0xf5, 0x71, 0x71, 0xf2, +0x5f, 0x5f, 0xf1, 0x57, 0x58, 0xe2, 0x35, 0x35, +0xd8, 0x55, 0x55, 0xff, 0xfa, 0xf4, 0xff, 0xf9, +0xee, 0xff, 0xf4, 0xd2, 0xda, 0x6d, 0x55, 0xdf, +0x3c, 0x3c, 0xed, 0x57, 0x58, 0xdd, 0x2e, 0x2e, +0xef, 0x4e, 0x4e, 0xe9, 0x3e, 0x3e, 0xcd, 0x22, +0x22, 0xcd, 0x1a, 0x14, 0xec, 0x49, 0x49, 0xee, +0x45, 0x45, 0xda, 0x22, 0x22, 0xe0, 0x77, 0x77, +0xd9, 0x96, 0x57, 0xbc, 0x3d, 0x15, 0xeb, 0xe3, +0x98, 0xd1, 0x58, 0x34, 0xdf, 0x28, 0x29, 0xd1, +0x4c, 0x39, 0xaf, 0x80, 0x2a, 0xf2, 0xea, 0xd9, +0xf3, 0xe9, 0xb6, 0xec, 0xe7, 0x96, 0xcc, 0x3a, +0x21, 0xcf, 0x4a, 0x32, 0xe0, 0xaa, 0x7f, 0xcb, +0xbc, 0x82, 0xe2, 0x2b, 0x2b, 0xea, 0x33, 0x34, +0xdb, 0x1a, 0x1b, 0xc8, 0x4d, 0x2f, 0xdb, 0xc6, +0x94, 0xed, 0xdd, 0xb5, 0xf3, 0xe6, 0xbe, 0xf3, +0xeb, 0xaf, 0xe9, 0xe1, 0x93, 0xe0, 0x25, 0x25, +0xe9, 0x2b, 0x2c, 0xda, 0x16, 0x17, 0xb6, 0x66, +0x25, 0xc1, 0x2b, 0x14, 0xca, 0x4f, 0x3b, 0xc6, +0xe4, 0x7e, 0xce, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xdd, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x00, 0x02, 0x46, 0x26, 0x66, 0x20, 0x60, +0x62, 0x64, 0x80, 0x02, 0x16, 0x56, 0x36, 0x76, +0x0e, 0x4e, 0x2e, 0x56, 0x6e, 0x1e, 0x5e, 0x3e, +0x20, 0x97, 0x5f, 0x40, 0x50, 0x48, 0x58, 0x44, +0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, 0x9a, 0x1f, +0x28, 0x20, 0x23, 0x0b, 0x14, 0x90, 0x93, 0x57, +0x50, 0x64, 0x57, 0x52, 0x56, 0x51, 0x05, 0x0a, +0xa8, 0xa9, 0x6b, 0x68, 0x6a, 0x69, 0xeb, 0xe8, +0xe8, 0xea, 0xe9, 0x1b, 0xc8, 0xaa, 0x81, 0x04, +0x0c, 0x8d, 0x8c, 0x4d, 0x4c, 0xcd, 0xcc, 0x2d, +0x2c, 0xad, 0xac, 0xac, 0x6d, 0xc0, 0x02, 0xb6, +0x40, 0x01, 0x3b, 0x7b, 0x07, 0x47, 0x27, 0x67, +0x17, 0x4b, 0xb0, 0x80, 0xab, 0xb1, 0x9b, 0xa9, +0xbb, 0x87, 0xa7, 0x93, 0xb3, 0x97, 0xb7, 0x8f, +0x2f, 0x58, 0xc0, 0xcf, 0x3f, 0x20, 0x30, 0xc8, +0x31, 0xd8, 0x2a, 0x24, 0x34, 0x2c, 0x1c, 0x2a, +0x60, 0x2a, 0x60, 0x6f, 0x15, 0x11, 0x11, 0x19, +0x15, 0x1d, 0x03, 0xd3, 0x62, 0x67, 0x1e, 0xeb, +0x11, 0x1a, 0x15, 0x1d, 0x07, 0x31, 0xd4, 0xcf, +0x2d, 0xc0, 0x2c, 0x3e, 0x21, 0x24, 0x2a, 0x31, +0x29, 0x19, 0x2c, 0x90, 0x02, 0xd4, 0x92, 0x9a, +0x16, 0x9b, 0x6e, 0x95, 0x91, 0x09, 0x76, 0x47, +0x96, 0x91, 0xb1, 0xbf, 0xa9, 0x59, 0x7c, 0x7a, +0x76, 0x4e, 0x6e, 0x1e, 0x48, 0x80, 0x41, 0x86, +0x3f, 0xbf, 0xa0, 0xb0, 0xa8, 0x38, 0xbd, 0xa4, +0xb4, 0x2c, 0x0e, 0xea, 0x5d, 0xb0, 0xf7, 0xcb, +0x2b, 0xac, 0x2a, 0x81, 0x6c, 0x00, 0x52, 0x67, +0x2e, 0x92, 0x9a, 0x81, 0x8a, 0xbb, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *baddatabase_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_baddatabase_png = new wxImage(); + if (!img_baddatabase_png || !img_baddatabase_png->IsOk()) + { + wxMemoryInputStream img_baddatabase_pngIS(baddatabase_png_data, sizeof(baddatabase_png_data)); + img_baddatabase_png->LoadFile(img_baddatabase_pngIS, wxBITMAP_TYPE_PNG); + } + return img_baddatabase_png; +} +#define baddatabase_png_img baddatabase_png_img() + +static wxBitmap *baddatabase_png_bmp() +{ + static wxBitmap *bmp_baddatabase_png; + if (!bmp_baddatabase_png || !bmp_baddatabase_png->IsOk()) + bmp_baddatabase_png = new wxBitmap(*baddatabase_png_img); + return bmp_baddatabase_png; +} +#define baddatabase_png_bmp baddatabase_png_bmp() + +static wxIcon *baddatabase_png_ico() +{ + static wxIcon *ico_baddatabase_png; + if (!ico_baddatabase_png || !ico_baddatabase_png->IsOk()) + { + ico_baddatabase_png = new wxIcon(); + ico_baddatabase_png->CopyFromBitmap(*baddatabase_png_bmp); + } + return ico_baddatabase_png; +} +#define baddatabase_png_ico baddatabase_png_ico() + +#endif // BADDATABASE_PNG_H diff --git a/include/images/cast-sm.png b/include/images/cast-sm.png new file mode 100644 index 0000000..52b7755 Binary files /dev/null and b/include/images/cast-sm.png differ diff --git a/include/images/cast-sm.pngc b/include/images/cast-sm.pngc new file mode 100644 index 0000000..3ff57a4 --- /dev/null +++ b/include/images/cast-sm.pngc @@ -0,0 +1,93 @@ +#ifndef CAST_SM_PNG_H +#define CAST_SM_PNG_H + +static const unsigned char cast_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0xad, 0x7d, 0xa5, +0x8e, 0x3c, 0x6f, 0x61, 0x95, 0x59, 0x4f, 0xba, +0x9d, 0x97, 0xd6, 0xc4, 0xb7, 0x67, 0xdd, 0xdf, +0x18, 0x7f, 0x6e, 0x7b, 0xa5, 0xa5, 0xff, 0xc7, +0xba, 0x76, 0xde, 0xe0, 0x21, 0xaa, 0xaa, 0xff, +0xbd, 0xac, 0x70, 0xe1, 0xe2, 0x2f, 0xb1, 0xb1, +0xff, 0xe4, 0xe5, 0x3f, 0xba, 0xba, 0xff, 0xc5, +0xb7, 0x60, 0xe7, 0xe8, 0x51, 0xc3, 0xc3, 0xff, +0xea, 0xea, 0x64, 0xcd, 0xcd, 0xff, 0xed, 0xed, +0x75, 0xd6, 0xd6, 0xff, 0xf0, 0xef, 0x86, 0xdf, +0xdf, 0xff, 0xf2, 0xf2, 0x93, 0xe6, 0xe6, 0xff, +0xca, 0xbd, 0x8c, 0x7e, 0x70, 0x9b, 0xb5, 0x7a, +0x52, 0x56, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5b, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x95, 0x8e, +0xcb, 0x16, 0x40, 0x30, 0x10, 0x43, 0x2b, 0x06, +0xa1, 0xd4, 0x9b, 0xaa, 0xc7, 0xff, 0x7f, 0xa6, +0xae, 0xb4, 0x76, 0xdc, 0xdd, 0x9d, 0x93, 0xc9, +0x89, 0x52, 0xdf, 0x48, 0x90, 0x4a, 0x16, 0x79, +0x8e, 0x82, 0xa5, 0x04, 0xaf, 0xa0, 0x35, 0xeb, +0x70, 0x68, 0x60, 0x8c, 0x61, 0x1b, 0x7e, 0xd0, +0x79, 0xd8, 0xcb, 0x13, 0x19, 0x00, 0x8c, 0x9c, +0x44, 0xa2, 0x5e, 0xcc, 0x5c, 0x3c, 0xa1, 0x06, +0x2b, 0xad, 0xb5, 0x71, 0x62, 0xa3, 0x73, 0xf1, +0x12, 0xec, 0x3c, 0x5e, 0xcb, 0x4e, 0x5c, 0x2f, +0xff, 0xc7, 0x0d, 0xc0, 0x41, 0x03, 0x5f, 0xb6, +0xeb, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *cast_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_cast_sm_png = new wxImage(); + if (!img_cast_sm_png || !img_cast_sm_png->IsOk()) + { + wxMemoryInputStream img_cast_sm_pngIS(cast_sm_png_data, sizeof(cast_sm_png_data)); + img_cast_sm_png->LoadFile(img_cast_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_cast_sm_png; +} +#define cast_sm_png_img cast_sm_png_img() + +static wxBitmap *cast_sm_png_bmp() +{ + static wxBitmap *bmp_cast_sm_png; + if (!bmp_cast_sm_png || !bmp_cast_sm_png->IsOk()) + bmp_cast_sm_png = new wxBitmap(*cast_sm_png_img); + return bmp_cast_sm_png; +} +#define cast_sm_png_bmp cast_sm_png_bmp() + +static wxIcon *cast_sm_png_ico() +{ + static wxIcon *ico_cast_sm_png; + if (!ico_cast_sm_png || !ico_cast_sm_png->IsOk()) + { + ico_cast_sm_png = new wxIcon(); + ico_cast_sm_png->CopyFromBitmap(*cast_sm_png_bmp); + } + return ico_cast_sm_png; +} +#define cast_sm_png_ico cast_sm_png_ico() + +#endif // CAST_SM_PNG_H diff --git a/include/images/cast.png b/include/images/cast.png new file mode 100644 index 0000000..2be7f37 Binary files /dev/null and b/include/images/cast.png differ diff --git a/include/images/cast.pngc b/include/images/cast.pngc new file mode 100644 index 0000000..2f43834 --- /dev/null +++ b/include/images/cast.pngc @@ -0,0 +1,98 @@ +#ifndef CAST_PNG_H +#define CAST_PNG_H + +static const unsigned char cast_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0x8e, 0x3c, 0xda, +0xd1, 0xaf, 0x59, 0x4f, 0xba, 0x9d, 0x97, 0xd6, +0xdd, 0xdf, 0x18, 0xc1, 0xb1, 0x78, 0x8c, 0x86, +0xcf, 0xa5, 0xa5, 0xff, 0xca, 0xbd, 0x8c, 0xde, +0xe0, 0x1e, 0xa8, 0xa8, 0xff, 0xdf, 0xe1, 0x28, +0xae, 0xae, 0xff, 0xe1, 0xe3, 0x33, 0xb3, 0xb3, +0xff, 0xe4, 0xe5, 0x3f, 0xba, 0xba, 0xff, 0xe6, +0xe7, 0x4c, 0xc1, 0xc1, 0xff, 0xe8, 0xe9, 0x5a, +0xc8, 0xc8, 0xff, 0xeb, 0xeb, 0x68, 0xd0, 0xd0, +0xff, 0xed, 0xed, 0x75, 0xd6, 0xd6, 0xff, 0xef, +0xef, 0x82, 0xde, 0xde, 0xff, 0xf1, 0xf1, 0x8d, +0xe3, 0xe3, 0xff, 0xf3, 0xf2, 0x96, 0xe8, 0xe8, +0xff, 0xbc, 0xb7, 0xe3, 0x5b, 0x9c, 0x5d, 0x5f, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x6d, 0xcf, 0xdb, 0x12, +0x82, 0x30, 0x10, 0x03, 0xd0, 0xc6, 0xd5, 0x0d, +0x97, 0x22, 0x22, 0x88, 0x48, 0xb9, 0xf8, 0xff, +0x5f, 0x69, 0xc1, 0x16, 0xfb, 0xe0, 0x79, 0x4b, +0xa6, 0x33, 0xcd, 0x1a, 0xf3, 0x1f, 0x4e, 0x46, +0xe4, 0x9c, 0xe4, 0x8b, 0x32, 0xcb, 0x24, 0xc6, +0x1c, 0x45, 0xa1, 0x2c, 0x4b, 0x39, 0xb2, 0xb5, +0x56, 0x59, 0x55, 0xb1, 0xc0, 0xd5, 0x53, 0xd6, +0x75, 0x28, 0x70, 0xdb, 0x28, 0x9b, 0xe6, 0x5b, +0xe0, 0xbe, 0x53, 0xb6, 0xad, 0xc8, 0xfe, 0x13, +0xbc, 0xae, 0x53, 0x3e, 0x76, 0xe1, 0x55, 0xdf, +0x2b, 0x9f, 0x9b, 0xb0, 0x05, 0xc3, 0xa0, 0x7c, +0x79, 0x71, 0x1b, 0xc6, 0x51, 0xe9, 0x9c, 0x3b, +0xb6, 0x62, 0x9a, 0x94, 0xf3, 0xfc, 0xdb, 0x8e, +0x65, 0x51, 0xae, 0xc9, 0x2d, 0x39, 0x60, 0xde, +0xe9, 0x6d, 0xa9, 0x0f, 0xf4, 0x4f, 0x06, 0x44, +0x0e, 0x4c, 0xb2, 0xf9, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *cast_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_cast_png = new wxImage(); + if (!img_cast_png || !img_cast_png->IsOk()) + { + wxMemoryInputStream img_cast_pngIS(cast_png_data, sizeof(cast_png_data)); + img_cast_png->LoadFile(img_cast_pngIS, wxBITMAP_TYPE_PNG); + } + return img_cast_png; +} +#define cast_png_img cast_png_img() + +static wxBitmap *cast_png_bmp() +{ + static wxBitmap *bmp_cast_png; + if (!bmp_cast_png || !bmp_cast_png->IsOk()) + bmp_cast_png = new wxBitmap(*cast_png_img); + return bmp_cast_png; +} +#define cast_png_bmp cast_png_bmp() + +static wxIcon *cast_png_ico() +{ + static wxIcon *ico_cast_png; + if (!ico_cast_png || !ico_cast_png->IsOk()) + { + ico_cast_png = new wxIcon(); + ico_cast_png->CopyFromBitmap(*cast_png_bmp); + } + return ico_cast_png; +} +#define cast_png_ico cast_png_ico() + +#endif // CAST_PNG_H diff --git a/include/images/casts.png b/include/images/casts.png new file mode 100644 index 0000000..09eb65a Binary files /dev/null and b/include/images/casts.png differ diff --git a/include/images/casts.pngc b/include/images/casts.pngc new file mode 100644 index 0000000..9ce78a7 --- /dev/null +++ b/include/images/casts.pngc @@ -0,0 +1,95 @@ +#ifndef CASTS_PNG_H +#define CASTS_PNG_H + +static const unsigned char casts_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xca, 0xbd, 0x8c, 0xa5, +0x8e, 0x3c, 0x7e, 0x70, 0x9b, 0x59, 0x4f, 0xba, +0x9d, 0x97, 0xd6, 0xdd, 0xdf, 0x18, 0x7f, 0x6e, +0x7b, 0xa5, 0xa5, 0xff, 0xde, 0xe0, 0x21, 0x95, +0x81, 0x56, 0x6f, 0x61, 0x95, 0xe1, 0xe2, 0x2f, +0xbe, 0xb1, 0x37, 0xe4, 0xe5, 0x3f, 0xbf, 0xb2, +0x3d, 0xaa, 0xaa, 0xff, 0xb1, 0xb1, 0xff, 0xba, +0xba, 0xff, 0xc5, 0xb7, 0x60, 0xe7, 0xe8, 0x51, +0xc3, 0xc3, 0xff, 0xf0, 0xef, 0x86, 0xea, 0xea, +0x64, 0xcd, 0xcd, 0xff, 0xf2, 0xf2, 0x93, 0xed, +0xed, 0x75, 0xd6, 0xd6, 0xff, 0xdf, 0xdf, 0xff, +0xe6, 0xe6, 0xff, 0xd2, 0x1c, 0x99, 0x5f, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x75, 0xcf, 0xdb, 0x0e, 0x83, +0x20, 0x10, 0x04, 0xd0, 0x65, 0xba, 0x75, 0x4a, +0xa5, 0x68, 0x2f, 0x5a, 0x2d, 0xf6, 0xff, 0x7f, +0x53, 0x7c, 0x59, 0xd0, 0xc4, 0x79, 0x23, 0x39, +0x3b, 0x61, 0x44, 0x44, 0x1c, 0x2e, 0x7a, 0x95, +0x12, 0x87, 0x86, 0x37, 0xad, 0xdf, 0xde, 0xdf, +0xd1, 0x9a, 0x71, 0x08, 0xe1, 0x51, 0x1b, 0xc4, +0xd8, 0xed, 0x8c, 0x03, 0x4e, 0x0c, 0x7b, 0xb5, +0x96, 0xcd, 0x04, 0x3e, 0xad, 0x17, 0xd9, 0xc4, +0xc8, 0x97, 0xda, 0xcd, 0x3b, 0x9b, 0x0f, 0x07, +0xd5, 0xd2, 0x3b, 0xe2, 0xcb, 0x29, 0xc7, 0xcc, +0x8c, 0x1f, 0x53, 0x4a, 0xd5, 0xef, 0x30, 0x72, +0x59, 0xea, 0x45, 0x98, 0xf9, 0x3f, 0x2c, 0xdc, +0x2f, 0x2e, 0x59, 0x01, 0x53, 0xb2, 0x04, 0x9e, +0x04, 0xe2, 0x51, 0xb7, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *casts_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_casts_png = new wxImage(); + if (!img_casts_png || !img_casts_png->IsOk()) + { + wxMemoryInputStream img_casts_pngIS(casts_png_data, sizeof(casts_png_data)); + img_casts_png->LoadFile(img_casts_pngIS, wxBITMAP_TYPE_PNG); + } + return img_casts_png; +} +#define casts_png_img casts_png_img() + +static wxBitmap *casts_png_bmp() +{ + static wxBitmap *bmp_casts_png; + if (!bmp_casts_png || !bmp_casts_png->IsOk()) + bmp_casts_png = new wxBitmap(*casts_png_img); + return bmp_casts_png; +} +#define casts_png_bmp casts_png_bmp() + +static wxIcon *casts_png_ico() +{ + static wxIcon *ico_casts_png; + if (!ico_casts_png || !ico_casts_png->IsOk()) + { + ico_casts_png = new wxIcon(); + ico_casts_png->CopyFromBitmap(*casts_png_bmp); + } + return ico_casts_png; +} +#define casts_png_ico casts_png_ico() + +#endif // CASTS_PNG_H diff --git a/include/images/catalog-sm.png b/include/images/catalog-sm.png new file mode 100644 index 0000000..b6f742f Binary files /dev/null and b/include/images/catalog-sm.png differ diff --git a/include/images/catalog-sm.pngc b/include/images/catalog-sm.pngc new file mode 100644 index 0000000..78da4ad --- /dev/null +++ b/include/images/catalog-sm.pngc @@ -0,0 +1,85 @@ +#ifndef CATALOG_SM_PNG_H +#define CATALOG_SM_PNG_H + +static const unsigned char catalog_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaf, 0x94, 0xd8, 0x77, +0x49, 0xbd, 0xbb, 0x8d, 0xff, 0xb8, 0x89, 0xff, +0xb5, 0x83, 0xff, 0xff, 0xff, 0xff, 0xb1, 0x7e, +0xfe, 0xfd, 0xff, 0x4e, 0xae, 0x78, 0xfe, 0xfe, +0xff, 0x9a, 0xa9, 0x70, 0xfe, 0xa5, 0x6a, 0xfe, +0xa0, 0x62, 0xfe, 0x9e, 0x5e, 0xfe, 0x0f, 0xed, +0x1f, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x06, +0x61, 0x66, 0xb8, 0x7d, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x45, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, 0x0b, 0x18, +0x15, 0xa1, 0x0c, 0x21, 0x23, 0x01, 0x88, 0x80, +0x8a, 0x0a, 0x44, 0x48, 0x28, 0x28, 0x29, 0x08, +0x24, 0xc4, 0xa8, 0xae, 0xd6, 0xa6, 0x0e, 0x12, +0x62, 0x9a, 0x94, 0xb1, 0x22, 0x69, 0x12, 0x48, +0x44, 0x5b, 0xad, 0x4d, 0x1b, 0xac, 0x48, 0xe8, +0x50, 0xd2, 0x21, 0xb0, 0x36, 0x46, 0x5d, 0x5d, +0xa8, 0x41, 0x42, 0x8f, 0x04, 0xd0, 0x4c, 0x46, +0x05, 0x00, 0x98, 0x6b, 0x0a, 0x8b, 0x0f, 0x84, +0xa2, 0xcd, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalog_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalog_sm_png = new wxImage(); + if (!img_catalog_sm_png || !img_catalog_sm_png->IsOk()) + { + wxMemoryInputStream img_catalog_sm_pngIS(catalog_sm_png_data, sizeof(catalog_sm_png_data)); + img_catalog_sm_png->LoadFile(img_catalog_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalog_sm_png; +} +#define catalog_sm_png_img catalog_sm_png_img() + +static wxBitmap *catalog_sm_png_bmp() +{ + static wxBitmap *bmp_catalog_sm_png; + if (!bmp_catalog_sm_png || !bmp_catalog_sm_png->IsOk()) + bmp_catalog_sm_png = new wxBitmap(*catalog_sm_png_img); + return bmp_catalog_sm_png; +} +#define catalog_sm_png_bmp catalog_sm_png_bmp() + +static wxIcon *catalog_sm_png_ico() +{ + static wxIcon *ico_catalog_sm_png; + if (!ico_catalog_sm_png || !ico_catalog_sm_png->IsOk()) + { + ico_catalog_sm_png = new wxIcon(); + ico_catalog_sm_png->CopyFromBitmap(*catalog_sm_png_bmp); + } + return ico_catalog_sm_png; +} +#define catalog_sm_png_ico catalog_sm_png_ico() + +#endif // CATALOG_SM_PNG_H diff --git a/include/images/catalog.png b/include/images/catalog.png new file mode 100644 index 0000000..7c0ef24 Binary files /dev/null and b/include/images/catalog.png differ diff --git a/include/images/catalog.pngc b/include/images/catalog.pngc new file mode 100644 index 0000000..99832d0 --- /dev/null +++ b/include/images/catalog.pngc @@ -0,0 +1,93 @@ +#ifndef CATALOG_PNG_H +#define CATALOG_PNG_H + +static const unsigned char catalog_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaf, 0x94, 0xd8, 0x77, +0x49, 0xbd, 0xbb, 0x8d, 0xff, 0xb9, 0x8b, 0xff, +0xb8, 0x89, 0xff, 0xb6, 0x85, 0xff, 0xff, 0xff, +0xff, 0xb3, 0x81, 0xff, 0xb1, 0x7e, 0xfe, 0xe4, +0xe5, 0xa7, 0xfd, 0xff, 0x4e, 0xae, 0x78, 0xfe, +0xfe, 0xff, 0x9a, 0xab, 0x74, 0xfe, 0xa8, 0x6e, +0xfe, 0xa5, 0x6a, 0xfe, 0xa3, 0x66, 0xfe, 0xa0, +0x62, 0xfe, 0x9f, 0x60, 0xfe, 0x9c, 0x5a, 0xfe, +0xbc, 0xcb, 0xef, 0x88, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x07, 0x16, 0x61, 0x88, 0xeb, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x6e, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0x8f, 0x09, +0x12, 0x80, 0x20, 0x08, 0x45, 0xe1, 0xb7, 0x68, +0x62, 0x59, 0xd6, 0xfd, 0xcf, 0x9a, 0xe8, 0x30, +0x5a, 0x0c, 0xa3, 0xbe, 0x8f, 0x6c, 0x44, 0xd5, +0x18, 0x60, 0x1a, 0x8c, 0x31, 0x4d, 0xa3, 0xc2, +0x98, 0x51, 0x9c, 0x3b, 0x2f, 0xe0, 0x7a, 0x18, +0xaf, 0x60, 0xe7, 0xea, 0xd5, 0xd8, 0x2b, 0xab, +0xe2, 0x55, 0x61, 0x6c, 0x85, 0x83, 0x48, 0x70, +0xf5, 0x49, 0x88, 0x1a, 0x97, 0x7d, 0x17, 0xfd, +0x13, 0x41, 0x38, 0x46, 0xe1, 0x40, 0x49, 0x49, +0x3d, 0x25, 0xb5, 0x22, 0xa7, 0x15, 0x3d, 0xad, +0xcd, 0xd5, 0xda, 0x5e, 0x7d, 0x90, 0xac, 0x83, +0xe5, 0x71, 0xd4, 0x1b, 0xc5, 0x3f, 0xcb, 0x3c, +0xcf, 0x7f, 0x5d, 0xe3, 0x17, 0x94, 0xdf, 0x03, +0x49, 0x68, 0xad, 0x49, 0xf2, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalog_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalog_png = new wxImage(); + if (!img_catalog_png || !img_catalog_png->IsOk()) + { + wxMemoryInputStream img_catalog_pngIS(catalog_png_data, sizeof(catalog_png_data)); + img_catalog_png->LoadFile(img_catalog_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalog_png; +} +#define catalog_png_img catalog_png_img() + +static wxBitmap *catalog_png_bmp() +{ + static wxBitmap *bmp_catalog_png; + if (!bmp_catalog_png || !bmp_catalog_png->IsOk()) + bmp_catalog_png = new wxBitmap(*catalog_png_img); + return bmp_catalog_png; +} +#define catalog_png_bmp catalog_png_bmp() + +static wxIcon *catalog_png_ico() +{ + static wxIcon *ico_catalog_png; + if (!ico_catalog_png || !ico_catalog_png->IsOk()) + { + ico_catalog_png = new wxIcon(); + ico_catalog_png->CopyFromBitmap(*catalog_png_bmp); + } + return ico_catalog_png; +} +#define catalog_png_ico catalog_png_ico() + +#endif // CATALOG_PNG_H diff --git a/include/images/catalogobject-sm.png b/include/images/catalogobject-sm.png new file mode 100644 index 0000000..7a058c3 Binary files /dev/null and b/include/images/catalogobject-sm.png differ diff --git a/include/images/catalogobject-sm.pngc b/include/images/catalogobject-sm.pngc new file mode 100644 index 0000000..17031b8 --- /dev/null +++ b/include/images/catalogobject-sm.pngc @@ -0,0 +1,93 @@ +#ifndef CATALOGOBJECT_SM_PNG_H +#define CATALOGOBJECT_SM_PNG_H + +static const unsigned char catalogobject_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, +0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, 0x49, +0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, 0xeb, +0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, 0xab, +0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, 0xb3, +0xd5, 0xed, 0xf9, 0xf6, 0x96, 0x87, 0xc0, 0xe7, +0xda, 0xc4, 0x3f, 0x7b, 0xc6, 0xfb, 0x6f, 0xc0, +0xf8, 0x28, 0x99, 0xe8, 0x41, 0x5b, 0x6c, 0xa8, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x56, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x02, +0x30, 0x22, 0x01, 0x88, 0x00, 0x13, 0x33, 0x0b, +0x2b, 0x1b, 0x3b, 0x07, 0x07, 0x27, 0x17, 0x37, +0x44, 0x80, 0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, +0x48, 0x58, 0x44, 0x14, 0xaa, 0x82, 0x47, 0x0c, +0x24, 0x20, 0x2e, 0x21, 0x22, 0x09, 0x15, 0x90, +0x92, 0x86, 0x02, 0x19, 0xa8, 0x00, 0x90, 0x29, +0x0b, 0x46, 0xd2, 0x30, 0x01, 0x59, 0x59, 0x90, +0x00, 0x90, 0x40, 0xa8, 0x80, 0x02, 0xf2, 0xb5, +0xf0, 0xf0, 0xca, 0xc9, 0x83, 0xdd, 0xa1, 0xc0, +0x48, 0x8c, 0x57, 0x01, 0xb3, 0x99, 0x0a, 0x28, +0xe4, 0x61, 0x60, 0x17, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalogobject_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalogobject_sm_png = new wxImage(); + if (!img_catalogobject_sm_png || !img_catalogobject_sm_png->IsOk()) + { + wxMemoryInputStream img_catalogobject_sm_pngIS(catalogobject_sm_png_data, sizeof(catalogobject_sm_png_data)); + img_catalogobject_sm_png->LoadFile(img_catalogobject_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogobject_sm_png; +} +#define catalogobject_sm_png_img catalogobject_sm_png_img() + +static wxBitmap *catalogobject_sm_png_bmp() +{ + static wxBitmap *bmp_catalogobject_sm_png; + if (!bmp_catalogobject_sm_png || !bmp_catalogobject_sm_png->IsOk()) + bmp_catalogobject_sm_png = new wxBitmap(*catalogobject_sm_png_img); + return bmp_catalogobject_sm_png; +} +#define catalogobject_sm_png_bmp catalogobject_sm_png_bmp() + +static wxIcon *catalogobject_sm_png_ico() +{ + static wxIcon *ico_catalogobject_sm_png; + if (!ico_catalogobject_sm_png || !ico_catalogobject_sm_png->IsOk()) + { + ico_catalogobject_sm_png = new wxIcon(); + ico_catalogobject_sm_png->CopyFromBitmap(*catalogobject_sm_png_bmp); + } + return ico_catalogobject_sm_png; +} +#define catalogobject_sm_png_ico catalogobject_sm_png_ico() + +#endif // CATALOGOBJECT_SM_PNG_H diff --git a/include/images/catalogobject.png b/include/images/catalogobject.png new file mode 100644 index 0000000..54ed738 Binary files /dev/null and b/include/images/catalogobject.png differ diff --git a/include/images/catalogobject.pngc b/include/images/catalogobject.pngc new file mode 100644 index 0000000..95ae50e --- /dev/null +++ b/include/images/catalogobject.pngc @@ -0,0 +1,96 @@ +#ifndef CATALOGOBJECT_PNG_H +#define CATALOGOBJECT_PNG_H + +static const unsigned char catalogobject_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8d, +0xd0, 0xff, 0x92, 0xcf, 0xfb, 0xa2, 0xd3, 0xf5, +0xba, 0xd8, 0xed, 0xd1, 0xdf, 0xe9, 0xdf, 0xe3, +0xe7, 0xe5, 0xe6, 0xe7, 0xe6, 0xe6, 0xe6, 0xda, +0xe1, 0xe5, 0xac, 0xce, 0xe7, 0x63, 0xb1, 0xe8, +0x2e, 0x9b, 0xe8, 0x8b, 0xcf, 0xff, 0x85, 0xcc, +0xfe, 0x7e, 0xc8, 0xfc, 0x75, 0xc3, 0xfa, 0x6c, +0xbe, 0xf8, 0x61, 0xb8, 0xf6, 0x56, 0xb2, 0xf3, +0x4b, 0xac, 0xf0, 0x40, 0xa7, 0xee, 0x37, 0xa0, +0xec, 0x2d, 0x9c, 0xea, 0x26, 0x98, 0xe9, 0x85, +0xcc, 0xfd, 0x6b, 0xbe, 0xf8, 0x41, 0xa6, 0xee, +0x36, 0xa1, 0xec, 0x2e, 0x9c, 0xea, 0xb4, 0xd6, +0xee, 0xf9, 0xf6, 0x96, 0x87, 0xbf, 0xe7, 0xda, +0xc4, 0x3f, 0xf9, 0xef, 0x9c, 0xfb, 0xd9, 0xd9, +0xfb, 0xd0, 0xd0, 0x98, 0x29, 0x62, 0x9c, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5e, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x60, 0x44, 0x01, +0x0c, 0x0c, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, +0x6c, 0xec, 0x1c, 0x9c, 0x9c, 0x5c, 0xdc, 0x3c, +0xbc, 0x20, 0x01, 0x3e, 0x7e, 0x01, 0x41, 0x21, +0x61, 0x11, 0x51, 0x31, 0x71, 0x09, 0x49, 0xb0, +0x0a, 0x3e, 0x29, 0x01, 0x41, 0x69, 0xa0, 0x80, +0x8c, 0xac, 0x1c, 0x44, 0x40, 0x5e, 0x01, 0x0e, +0x14, 0xc1, 0x02, 0x0a, 0x48, 0x00, 0x2e, 0xa0, +0x04, 0x46, 0x30, 0x01, 0x25, 0x20, 0x50, 0x80, +0x90, 0xd4, 0xd7, 0xa2, 0xac, 0xa2, 0x8c, 0xae, +0x45, 0x15, 0x55, 0x8b, 0xb2, 0x2a, 0x44, 0x00, +0xd5, 0xfb, 0x00, 0x69, 0x31, 0x13, 0x6d, 0x2d, +0xdb, 0x2d, 0xb0, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalogobject_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalogobject_png = new wxImage(); + if (!img_catalogobject_png || !img_catalogobject_png->IsOk()) + { + wxMemoryInputStream img_catalogobject_pngIS(catalogobject_png_data, sizeof(catalogobject_png_data)); + img_catalogobject_png->LoadFile(img_catalogobject_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogobject_png; +} +#define catalogobject_png_img catalogobject_png_img() + +static wxBitmap *catalogobject_png_bmp() +{ + static wxBitmap *bmp_catalogobject_png; + if (!bmp_catalogobject_png || !bmp_catalogobject_png->IsOk()) + bmp_catalogobject_png = new wxBitmap(*catalogobject_png_img); + return bmp_catalogobject_png; +} +#define catalogobject_png_bmp catalogobject_png_bmp() + +static wxIcon *catalogobject_png_ico() +{ + static wxIcon *ico_catalogobject_png; + if (!ico_catalogobject_png || !ico_catalogobject_png->IsOk()) + { + ico_catalogobject_png = new wxIcon(); + ico_catalogobject_png->CopyFromBitmap(*catalogobject_png_bmp); + } + return ico_catalogobject_png; +} +#define catalogobject_png_ico catalogobject_png_ico() + +#endif // CATALOGOBJECT_PNG_H diff --git a/include/images/catalogobjects.png b/include/images/catalogobjects.png new file mode 100644 index 0000000..85b89f1 Binary files /dev/null and b/include/images/catalogobjects.png differ diff --git a/include/images/catalogobjects.pngc b/include/images/catalogobjects.pngc new file mode 100644 index 0000000..5f88281 --- /dev/null +++ b/include/images/catalogobjects.pngc @@ -0,0 +1,97 @@ +#ifndef CATALOGOBJECTS_PNG_H +#define CATALOGOBJECTS_PNG_H + +static const unsigned char catalogobjects_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x69, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x52, 0xb0, 0xf2, 0xb3, 0xd5, 0xed, 0xf9, 0xf6, +0x96, 0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, +0xc0, 0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, +0x49, 0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, +0xeb, 0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, +0xab, 0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, +0x87, 0xc0, 0xe7, 0xda, 0xc4, 0x3f, 0x90, 0xca, +0xf3, 0x7b, 0xc6, 0xfb, 0x6f, 0xc0, 0xf8, 0x28, +0x99, 0xe8, 0xe4, 0xe9, 0xf7, 0xc8, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x71, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x5d, 0x8e, 0x09, 0x0e, 0x80, 0x20, +0x0c, 0x04, 0xa9, 0x27, 0x2a, 0x8a, 0x37, 0x9e, +0x78, 0xfc, 0xff, 0x91, 0x96, 0x8a, 0x51, 0xd9, +0x10, 0xd2, 0x4c, 0x66, 0x93, 0x65, 0xf0, 0x86, +0x51, 0xc0, 0xf3, 0x83, 0x30, 0x8a, 0x39, 0x4f, +0xd2, 0xec, 0x06, 0x22, 0xff, 0x3b, 0x20, 0x1c, +0x07, 0x0a, 0xc7, 0x01, 0xe9, 0x38, 0x08, 0xd0, +0x29, 0xab, 0xba, 0x69, 0xbb, 0x5e, 0x0d, 0x60, +0x00, 0x3a, 0xa3, 0x01, 0xd3, 0xac, 0x16, 0x0b, +0x0a, 0x69, 0xb3, 0x5a, 0x80, 0xa7, 0xa6, 0x27, +0x1f, 0xa0, 0xb5, 0x01, 0xf8, 0x01, 0xdb, 0xb6, +0xdb, 0xb0, 0x31, 0xdb, 0x9c, 0x0a, 0x23, 0xe7, +0x53, 0xa1, 0xf9, 0xff, 0x0a, 0x3a, 0xa2, 0xdc, +0x0f, 0xda, 0x71, 0xc2, 0x05, 0x1d, 0x12, 0x0a, +0x78, 0x27, 0x14, 0xeb, 0x36, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalogobjects_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalogobjects_png = new wxImage(); + if (!img_catalogobjects_png || !img_catalogobjects_png->IsOk()) + { + wxMemoryInputStream img_catalogobjects_pngIS(catalogobjects_png_data, sizeof(catalogobjects_png_data)); + img_catalogobjects_png->LoadFile(img_catalogobjects_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogobjects_png; +} +#define catalogobjects_png_img catalogobjects_png_img() + +static wxBitmap *catalogobjects_png_bmp() +{ + static wxBitmap *bmp_catalogobjects_png; + if (!bmp_catalogobjects_png || !bmp_catalogobjects_png->IsOk()) + bmp_catalogobjects_png = new wxBitmap(*catalogobjects_png_img); + return bmp_catalogobjects_png; +} +#define catalogobjects_png_bmp catalogobjects_png_bmp() + +static wxIcon *catalogobjects_png_ico() +{ + static wxIcon *ico_catalogobjects_png; + if (!ico_catalogobjects_png || !ico_catalogobjects_png->IsOk()) + { + ico_catalogobjects_png = new wxIcon(); + ico_catalogobjects_png->CopyFromBitmap(*catalogobjects_png_bmp); + } + return ico_catalogobjects_png; +} +#define catalogobjects_png_ico catalogobjects_png_ico() + +#endif // CATALOGOBJECTS_PNG_H diff --git a/include/images/catalogs.png b/include/images/catalogs.png new file mode 100644 index 0000000..caa6d3d Binary files /dev/null and b/include/images/catalogs.png differ diff --git a/include/images/catalogs.pngc b/include/images/catalogs.pngc new file mode 100644 index 0000000..cbeaa12 --- /dev/null +++ b/include/images/catalogs.pngc @@ -0,0 +1,91 @@ +#ifndef CATALOGS_PNG_H +#define CATALOGS_PNG_H + +static const unsigned char catalogs_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x33, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaf, 0x94, 0xd8, 0x77, +0x49, 0xbd, 0xbb, 0x8d, 0xff, 0xb8, 0x89, 0xff, +0xb5, 0x83, 0xff, 0xff, 0xff, 0xff, 0x8e, 0x68, +0xc8, 0xb1, 0x7e, 0xfe, 0x8f, 0x5e, 0xd8, 0xae, +0x78, 0xfe, 0xa9, 0x70, 0xfe, 0xfd, 0xff, 0x4e, +0xfe, 0xff, 0x9a, 0xa5, 0x6a, 0xfe, 0xa0, 0x62, +0xfe, 0x9e, 0x5e, 0xfe, 0xe4, 0xff, 0x31, 0xa0, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x01, 0x62, 0x4b, 0x47, 0x44, 0x06, 0x61, 0x66, +0xb8, 0x7d, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x6a, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x55, 0x8f, 0x0b, 0x0e, 0x80, 0x20, 0x0c, +0x43, 0x69, 0x55, 0x54, 0xf0, 0x77, 0xff, 0xd3, +0x5a, 0x52, 0x10, 0xdc, 0x32, 0x92, 0xf5, 0xad, +0xcb, 0x08, 0x41, 0x01, 0x22, 0x8c, 0x01, 0x4e, +0x3f, 0x05, 0x9c, 0x95, 0x18, 0xfa, 0x85, 0x51, +0xb5, 0x56, 0x0d, 0xdc, 0xd4, 0x47, 0xee, 0xcd, +0xc7, 0xa4, 0x8e, 0xaa, 0xe6, 0x03, 0x33, 0x05, +0xab, 0xcf, 0x8a, 0x50, 0xf1, 0x1d, 0x51, 0x2f, +0xbc, 0xb4, 0xf8, 0x8e, 0x53, 0x4a, 0x62, 0x5d, +0x2a, 0x5f, 0x99, 0xc8, 0x9a, 0x30, 0x24, 0x2f, +0xc9, 0x97, 0x1d, 0x86, 0xbc, 0x95, 0xf0, 0x21, +0x86, 0x7c, 0xda, 0xb5, 0x30, 0x1c, 0x7e, 0x88, +0x0e, 0x3f, 0xa5, 0xf7, 0x2f, 0x5b, 0xc2, 0x02, +0xda, 0x03, 0xe4, 0xd3, 0xf0, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *catalogs_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_catalogs_png = new wxImage(); + if (!img_catalogs_png || !img_catalogs_png->IsOk()) + { + wxMemoryInputStream img_catalogs_pngIS(catalogs_png_data, sizeof(catalogs_png_data)); + img_catalogs_png->LoadFile(img_catalogs_pngIS, wxBITMAP_TYPE_PNG); + } + return img_catalogs_png; +} +#define catalogs_png_img catalogs_png_img() + +static wxBitmap *catalogs_png_bmp() +{ + static wxBitmap *bmp_catalogs_png; + if (!bmp_catalogs_png || !bmp_catalogs_png->IsOk()) + bmp_catalogs_png = new wxBitmap(*catalogs_png_img); + return bmp_catalogs_png; +} +#define catalogs_png_bmp catalogs_png_bmp() + +static wxIcon *catalogs_png_ico() +{ + static wxIcon *ico_catalogs_png; + if (!ico_catalogs_png || !ico_catalogs_png->IsOk()) + { + ico_catalogs_png = new wxIcon(); + ico_catalogs_png->CopyFromBitmap(*catalogs_png_bmp); + } + return ico_catalogs_png; +} +#define catalogs_png_ico catalogs_png_ico() + +#endif // CATALOGS_PNG_H diff --git a/include/images/check.png b/include/images/check.png new file mode 100644 index 0000000..9d1d2a0 Binary files /dev/null and b/include/images/check.png differ diff --git a/include/images/check.pngc b/include/images/check.pngc new file mode 100644 index 0000000..736de8d --- /dev/null +++ b/include/images/check.pngc @@ -0,0 +1,95 @@ +#ifndef CHECK_PNG_H +#define CHECK_PNG_H + +static const unsigned char check_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xd2, 0xa1, 0xa5, +0xb9, 0x6e, 0xb0, 0xc1, 0x7f, 0xd5, 0xde, 0xbc, +0x71, 0x93, 0x17, 0x8f, 0xb6, 0x37, 0xa4, 0xcd, +0x4e, 0x9d, 0xc5, 0x47, 0xc7, 0xd3, 0xa4, 0x82, +0xa8, 0x2a, 0xac, 0xd8, 0x57, 0xb1, 0xdd, 0x5d, +0x87, 0xac, 0x2f, 0xcc, 0xd7, 0xad, 0xb5, 0xe3, +0x62, 0x7c, 0xa0, 0x23, 0xce, 0xd9, 0xb1, 0x8a, +0xb2, 0x31, 0x9c, 0xc7, 0x45, 0xa3, 0xcf, 0x4c, +0xac, 0xd7, 0x58, 0xc3, 0xf1, 0x70, 0x7f, 0xa3, +0x27, 0x87, 0xad, 0x2f, 0xb1, 0xde, 0x5c, 0x9e, +0xc7, 0x49, 0xcb, 0xfa, 0x79, 0x95, 0xbc, 0x3f, +0xb3, 0xc4, 0x85, 0xc4, 0xf1, 0x71, 0xc4, 0xf1, +0x72, 0xc6, 0xf3, 0x74, 0xa2, 0xca, 0x4e, 0xa7, +0xbb, 0x72, 0xaf, 0xc1, 0x7e, 0x80, 0xa3, 0x27, +0x70, 0x92, 0x16, 0xdc, 0xe4, 0xc7, 0x0a, 0xaa, +0xa9, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x58, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xa0, 0x08, 0x30, 0x32, 0x31, 0x23, 0x73, 0x59, +0x58, 0xd9, 0xd8, 0x39, 0x90, 0x44, 0x38, 0xb9, +0xb8, 0x79, 0x78, 0x21, 0x7c, 0x3e, 0x66, 0x26, +0x46, 0x06, 0x16, 0x2e, 0x7e, 0x1e, 0x01, 0x41, +0x88, 0x9c, 0x90, 0xb0, 0x08, 0x1b, 0x2b, 0xab, +0xa8, 0x98, 0x38, 0x94, 0x0f, 0x54, 0x21, 0x21, +0xc9, 0x2d, 0x25, 0x2d, 0x23, 0x8b, 0xd0, 0x2f, +0x28, 0xc0, 0x23, 0x27, 0xcf, 0x8a, 0x62, 0xa3, +0xb8, 0x82, 0xa2, 0x12, 0x8a, 0x80, 0xb2, 0x8a, +0x2a, 0x9a, 0xa3, 0xd4, 0x28, 0xf0, 0x10, 0x00, +0xbd, 0xd5, 0x03, 0x92, 0xa5, 0xe9, 0x59, 0x63, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *check_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_check_png = new wxImage(); + if (!img_check_png || !img_check_png->IsOk()) + { + wxMemoryInputStream img_check_pngIS(check_png_data, sizeof(check_png_data)); + img_check_png->LoadFile(img_check_pngIS, wxBITMAP_TYPE_PNG); + } + return img_check_png; +} +#define check_png_img check_png_img() + +static wxBitmap *check_png_bmp() +{ + static wxBitmap *bmp_check_png; + if (!bmp_check_png || !bmp_check_png->IsOk()) + bmp_check_png = new wxBitmap(*check_png_img); + return bmp_check_png; +} +#define check_png_bmp check_png_bmp() + +static wxIcon *check_png_ico() +{ + static wxIcon *ico_check_png; + if (!ico_check_png || !ico_check_png->IsOk()) + { + ico_check_png = new wxIcon(); + ico_check_png->CopyFromBitmap(*check_png_bmp); + } + return ico_check_png; +} +#define check_png_ico check_png_ico() + +#endif // CHECK_PNG_H diff --git a/include/images/checkbad.png b/include/images/checkbad.png new file mode 100644 index 0000000..32a045b Binary files /dev/null and b/include/images/checkbad.png differ diff --git a/include/images/checkbad.pngc b/include/images/checkbad.pngc new file mode 100644 index 0000000..49922f3 --- /dev/null +++ b/include/images/checkbad.pngc @@ -0,0 +1,117 @@ +#ifndef CHECKBAD_PNG_H +#define CHECKBAD_PNG_H + +static const unsigned char checkbad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x01, 0x20, 0x50, 0x4c, 0x54, 0x45, 0x70, 0x92, +0x16, 0xc5, 0x00, 0x00, 0xaa, 0x2c, 0x33, 0xe7, +0x1f, 0x20, 0xe7, 0x20, 0x20, 0xe8, 0x25, 0x25, +0xe9, 0x2a, 0x2b, 0xe9, 0x2b, 0x2b, 0x99, 0x43, +0x4a, 0x99, 0x44, 0x4b, 0xbc, 0x3b, 0x40, 0xea, +0x31, 0x31, 0xbe, 0x3d, 0x42, 0xba, 0x44, 0x46, +0xeb, 0x37, 0x37, 0xeb, 0x38, 0x38, 0xc4, 0x46, +0x4a, 0xc4, 0x47, 0x4b, 0xc5, 0x47, 0x4b, 0xec, +0x3e, 0x3f, 0xed, 0x42, 0x43, 0xed, 0x43, 0x44, +0xed, 0x44, 0x45, 0xee, 0x45, 0x45, 0xee, 0x46, +0x46, 0xee, 0x47, 0x47, 0xca, 0x51, 0x54, 0xee, +0x48, 0x48, 0xee, 0x48, 0x49, 0xee, 0x4a, 0x4a, +0xef, 0x4b, 0x4b, 0xef, 0x4c, 0x4c, 0xef, 0x4d, +0x4d, 0xef, 0x4d, 0x4e, 0xef, 0x4e, 0x4f, 0xd0, +0x57, 0x59, 0xef, 0x4f, 0x4f, 0xc5, 0x5b, 0x5d, +0xf0, 0x51, 0x51, 0xf0, 0x52, 0x52, 0xf0, 0x53, +0x53, 0xf0, 0x53, 0x54, 0xf0, 0x54, 0x54, 0xf0, +0x55, 0x55, 0xf1, 0x56, 0x56, 0xf1, 0x57, 0x57, +0xd6, 0x62, 0x62, 0xd7, 0x62, 0x62, 0xf1, 0x5b, +0x5b, 0xda, 0x65, 0x65, 0xf3, 0x61, 0x61, 0xf3, +0x62, 0x62, 0xdd, 0x69, 0x69, 0x71, 0x93, 0x17, +0xf4, 0x68, 0x68, 0xf5, 0x6d, 0x6d, 0xf5, 0x6e, +0x6e, 0xf6, 0x72, 0x72, 0x7c, 0xa0, 0x23, 0xf6, +0x76, 0x76, 0xf6, 0x77, 0x77, 0x7f, 0xa3, 0x27, +0x80, 0xa3, 0x27, 0x82, 0xa8, 0x2a, 0x87, 0xac, +0x2f, 0x87, 0xad, 0x2f, 0x8a, 0xb2, 0x31, 0x8f, +0xb6, 0x37, 0x95, 0xbc, 0x3f, 0xa5, 0xb9, 0x6e, +0xa7, 0xbb, 0x72, 0x9d, 0xc5, 0x47, 0x9c, 0xc7, +0x45, 0x9e, 0xc7, 0x49, 0xaf, 0xc1, 0x7e, 0xa2, +0xca, 0x4e, 0xb0, 0xc1, 0x7f, 0xa4, 0xcd, 0x4e, +0xb3, 0xc4, 0x85, 0xa3, 0xcf, 0x4c, 0xac, 0xd7, +0x58, 0xac, 0xd8, 0x57, 0xb1, 0xdd, 0x5d, 0xb1, +0xde, 0x5c, 0xc5, 0xd2, 0xa1, 0xc7, 0xd3, 0xa4, +0xb5, 0xe3, 0x62, 0xcc, 0xd7, 0xad, 0xce, 0xd9, +0xb1, 0xd5, 0xde, 0xbc, 0xc3, 0xf1, 0x70, 0xc4, +0xf1, 0x71, 0xc4, 0xf1, 0x72, 0xdc, 0xe4, 0xc7, +0xc6, 0xf3, 0x74, 0xcb, 0xfa, 0x79, 0x42, 0xa9, +0xe3, 0x49, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, +0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, +0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, +0x45, 0x07, 0xdb, 0x07, 0x19, 0x0f, 0x21, 0x26, +0x7e, 0xd2, 0x55, 0x6a, 0x00, 0x00, 0x00, 0x8f, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xa5, 0x8c, +0xc7, 0x0a, 0xc2, 0x50, 0x00, 0x04, 0xdf, 0xc4, +0xde, 0x7b, 0x8b, 0x25, 0xf6, 0xae, 0xb1, 0x17, +0x14, 0x04, 0x45, 0xf4, 0x10, 0x0f, 0x82, 0xf5, +0xff, 0x7f, 0x44, 0x4d, 0x4c, 0xf0, 0xee, 0xde, +0x66, 0xd8, 0x5d, 0x21, 0xfe, 0xca, 0x65, 0xaf, +0xfd, 0xe2, 0x73, 0xba, 0x3b, 0x1d, 0x4c, 0xa3, +0x52, 0xb9, 0x6e, 0xce, 0x51, 0x26, 0x3a, 0xdd, +0xb5, 0x1a, 0x6b, 0x22, 0x37, 0x3f, 0x3d, 0xc3, +0x6c, 0x8f, 0xac, 0x96, 0x0b, 0xbc, 0x74, 0xab, +0x39, 0x8c, 0x86, 0xcc, 0x7c, 0x36, 0xa6, 0x53, +0xce, 0x7e, 0x37, 0xe2, 0xa1, 0x32, 0x1a, 0xb4, +0x4b, 0x19, 0x93, 0xdf, 0x19, 0xd2, 0x2a, 0xa6, +0x91, 0x2c, 0xee, 0xd3, 0x54, 0x52, 0xb1, 0x90, +0xd5, 0x08, 0xd0, 0x28, 0x24, 0x09, 0xfa, 0x5c, +0xa6, 0xa1, 0x9e, 0x4f, 0xe0, 0xc6, 0xe9, 0xb0, +0x63, 0x08, 0x99, 0x38, 0x61, 0xe1, 0xc1, 0x66, +0x6d, 0x24, 0xfd, 0x4f, 0xfa, 0xf0, 0x0b, 0x95, +0x10, 0x0e, 0x8b, 0xa4, 0x2d, 0xc8, 0x80, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *checkbad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_checkbad_png = new wxImage(); + if (!img_checkbad_png || !img_checkbad_png->IsOk()) + { + wxMemoryInputStream img_checkbad_pngIS(checkbad_png_data, sizeof(checkbad_png_data)); + img_checkbad_png->LoadFile(img_checkbad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_checkbad_png; +} +#define checkbad_png_img checkbad_png_img() + +static wxBitmap *checkbad_png_bmp() +{ + static wxBitmap *bmp_checkbad_png; + if (!bmp_checkbad_png || !bmp_checkbad_png->IsOk()) + bmp_checkbad_png = new wxBitmap(*checkbad_png_img); + return bmp_checkbad_png; +} +#define checkbad_png_bmp checkbad_png_bmp() + +static wxIcon *checkbad_png_ico() +{ + static wxIcon *ico_checkbad_png; + if (!ico_checkbad_png || !ico_checkbad_png->IsOk()) + { + ico_checkbad_png = new wxIcon(); + ico_checkbad_png->CopyFromBitmap(*checkbad_png_bmp); + } + return ico_checkbad_png; +} +#define checkbad_png_ico checkbad_png_ico() + +#endif // CHECKBAD_PNG_H diff --git a/include/images/checked.png b/include/images/checked.png new file mode 100644 index 0000000..8ccaa5f Binary files /dev/null and b/include/images/checked.png differ diff --git a/include/images/checked.pngc b/include/images/checked.pngc new file mode 100644 index 0000000..af6ac44 --- /dev/null +++ b/include/images/checked.pngc @@ -0,0 +1,82 @@ +#ifndef CHECKED_PNG_H +#define CHECKED_PNG_H + +static const unsigned char checked_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xff, +0xff, 0xff, 0x40, 0x40, 0x40, 0xd4, 0xd0, 0xc8, +0x00, 0x00, 0x00, 0x40, 0x77, 0x45, 0x2d, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x02, 0x66, 0x0b, 0x7c, +0x64, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x43, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0xc0, 0x00, 0x8c, 0x82, 0x20, 0x20, +0x04, 0x64, 0x18, 0x83, 0x80, 0x13, 0x90, 0x61, +0xa4, 0x04, 0x04, 0x30, 0x46, 0x10, 0x94, 0xa1, +0x0a, 0x61, 0x04, 0x29, 0x85, 0x42, 0x18, 0xa1, +0xaa, 0xa1, 0x10, 0x35, 0xa1, 0xa1, 0x41, 0x10, +0x06, 0x50, 0x00, 0xaa, 0x2b, 0x08, 0xa1, 0x1d, +0xcc, 0x70, 0x01, 0x01, 0x20, 0x83, 0x49, 0x09, +0x0c, 0x10, 0x96, 0x03, 0x00, 0xe3, 0xff, 0x0f, +0x50, 0x69, 0xe0, 0x14, 0x82, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *checked_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_checked_png = new wxImage(); + if (!img_checked_png || !img_checked_png->IsOk()) + { + wxMemoryInputStream img_checked_pngIS(checked_png_data, sizeof(checked_png_data)); + img_checked_png->LoadFile(img_checked_pngIS, wxBITMAP_TYPE_PNG); + } + return img_checked_png; +} +#define checked_png_img checked_png_img() + +static wxBitmap *checked_png_bmp() +{ + static wxBitmap *bmp_checked_png; + if (!bmp_checked_png || !bmp_checked_png->IsOk()) + bmp_checked_png = new wxBitmap(*checked_png_img); + return bmp_checked_png; +} +#define checked_png_bmp checked_png_bmp() + +static wxIcon *checked_png_ico() +{ + static wxIcon *ico_checked_png; + if (!ico_checked_png || !ico_checked_png->IsOk()) + { + ico_checked_png = new wxIcon(); + ico_checked_png->CopyFromBitmap(*checked_png_bmp); + } + return ico_checked_png; +} +#define checked_png_ico checked_png_ico() + +#endif // CHECKED_PNG_H diff --git a/include/images/clearAll.png b/include/images/clearAll.png new file mode 100644 index 0000000..2ec90c0 Binary files /dev/null and b/include/images/clearAll.png differ diff --git a/include/images/clearAll.pngc b/include/images/clearAll.pngc new file mode 100644 index 0000000..9829956 --- /dev/null +++ b/include/images/clearAll.pngc @@ -0,0 +1,84 @@ +#ifndef CLEARALL_PNG_H +#define CLEARALL_PNG_H + +static const unsigned char clearAll_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x15, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, +0xc0, 0xc0, 0x80, 0x80, 0x80, 0xff, 0x00, 0x00, +0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0xbf, 0x5f, +0xc7, 0x32, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x60, +0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x3d, 0x8d, +0xd1, 0x0d, 0x80, 0x20, 0x0c, 0x44, 0x0f, 0x27, +0xe0, 0x0c, 0xe1, 0x5b, 0x70, 0x03, 0xe3, 0x02, +0x24, 0x95, 0x3d, 0x88, 0xb1, 0xfb, 0x8f, 0x60, +0xc1, 0xe0, 0x7d, 0x34, 0x2f, 0xbd, 0x5e, 0x0f, +0x98, 0x72, 0x1e, 0x39, 0xf7, 0xe9, 0xb8, 0xcb, +0x75, 0xd0, 0x03, 0x0c, 0x52, 0x1b, 0xcd, 0x4b, +0x94, 0xca, 0xd5, 0xe0, 0x64, 0x28, 0x7c, 0x80, +0x45, 0x12, 0x19, 0x75, 0x33, 0xc8, 0xa4, 0x0e, +0x90, 0x09, 0xe5, 0xb3, 0xec, 0x38, 0x36, 0xde, +0x23, 0xae, 0x3a, 0xe2, 0xb6, 0xd7, 0xfe, 0xd0, +0x2a, 0x54, 0x7b, 0xc5, 0x5f, 0x3a, 0xf5, 0x02, +0x2d, 0x5a, 0x0f, 0x70, 0x6e, 0x25, 0x18, 0x4b, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clearAll_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clearAll_png = new wxImage(); + if (!img_clearAll_png || !img_clearAll_png->IsOk()) + { + wxMemoryInputStream img_clearAll_pngIS(clearAll_png_data, sizeof(clearAll_png_data)); + img_clearAll_png->LoadFile(img_clearAll_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clearAll_png; +} +#define clearAll_png_img clearAll_png_img() + +static wxBitmap *clearAll_png_bmp() +{ + static wxBitmap *bmp_clearAll_png; + if (!bmp_clearAll_png || !bmp_clearAll_png->IsOk()) + bmp_clearAll_png = new wxBitmap(*clearAll_png_img); + return bmp_clearAll_png; +} +#define clearAll_png_bmp clearAll_png_bmp() + +static wxIcon *clearAll_png_ico() +{ + static wxIcon *ico_clearAll_png; + if (!ico_clearAll_png || !ico_clearAll_png->IsOk()) + { + ico_clearAll_png = new wxIcon(); + ico_clearAll_png->CopyFromBitmap(*clearAll_png_bmp); + } + return ico_clearAll_png; +} +#define clearAll_png_ico clearAll_png_ico() + +#endif // CLEARALL_PNG_H diff --git a/include/images/clip_copy.png b/include/images/clip_copy.png new file mode 100644 index 0000000..6b98c92 Binary files /dev/null and b/include/images/clip_copy.png differ diff --git a/include/images/clip_copy.pngc b/include/images/clip_copy.pngc new file mode 100644 index 0000000..7962ed5 --- /dev/null +++ b/include/images/clip_copy.pngc @@ -0,0 +1,106 @@ +#ifndef CLIP_COPY_PNG_H +#define CLIP_COPY_PNG_H + +static const unsigned char clip_copy_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x99, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8e, 0x8e, 0x8e, 0x60, +0x60, 0x60, 0xf2, 0xf9, 0xfc, 0xe8, 0xf3, 0xf9, +0xe6, 0xf3, 0xf8, 0xe4, 0xf1, 0xf7, 0xe3, 0xf0, +0xf6, 0xe7, 0xf3, 0xf8, 0xd8, 0xeb, 0xf4, 0xd5, +0xe9, 0xf2, 0x8f, 0x98, 0x9b, 0xe5, 0xf1, 0xf7, +0x2c, 0x66, 0xbd, 0xe2, 0xef, 0xf5, 0xcf, 0xe5, +0xee, 0xcc, 0xe3, 0xec, 0xd2, 0xe7, 0xf0, 0xe0, +0xee, 0xf3, 0xdf, 0xed, 0xf3, 0xca, 0xe1, 0xeb, +0xdc, 0xeb, 0xf1, 0xc5, 0xde, 0xe8, 0xc1, 0xdb, +0xe5, 0xc8, 0xe0, 0xea, 0xc5, 0xde, 0xe7, 0xbd, +0xd8, 0xe2, 0xd1, 0xe4, 0xeb, 0xd9, 0xe9, 0xef, +0xce, 0xe2, 0xe8, 0xd5, 0xe6, 0xed, 0xba, 0xd6, +0xe1, 0xb6, 0xd3, 0xde, 0xbe, 0xd9, 0xe3, 0xba, +0xd6, 0xe0, 0xb2, 0xd0, 0xdb, 0xca, 0xdf, 0xe6, +0xc7, 0xdc, 0xe4, 0xe1, 0xed, 0xf1, 0xcb, 0xe0, +0xe7, 0xc9, 0xde, 0xe5, 0xb3, 0xd1, 0xdc, 0xaf, +0xce, 0xd9, 0xab, 0xcc, 0xd7, 0xa8, 0xc9, 0xd5, +0xc4, 0xdb, 0xe2, 0xc1, 0xd9, 0xe0, 0xc6, 0xdc, +0xe4, 0xc2, 0xd9, 0xe1, 0xc1, 0xd8, 0xe0, 0xd9, +0xe7, 0xec, 0x5c, 0x71, 0x91, 0x5b, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x87, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x65, 0xcf, 0xd9, 0x0e, 0x82, 0x30, +0x10, 0x85, 0x61, 0x38, 0xae, 0xa8, 0x15, 0x17, +0x04, 0xb1, 0x28, 0xb8, 0x82, 0x20, 0xb8, 0xbc, +0xff, 0xc3, 0x31, 0x33, 0x04, 0x52, 0xe2, 0xb9, +0xfc, 0xf3, 0x35, 0x99, 0x5a, 0xd6, 0xdf, 0x6c, +0xc8, 0xec, 0x2e, 0x60, 0x30, 0x1c, 0x8d, 0x27, +0x46, 0xc1, 0xd4, 0x99, 0xcd, 0x4d, 0x85, 0x85, +0x52, 0x3d, 0x85, 0xa5, 0xbb, 0x62, 0xb5, 0x76, +0xb1, 0x91, 0x82, 0x2d, 0x09, 0x52, 0xca, 0xe3, +0x57, 0x1c, 0x76, 0x7e, 0xc0, 0x6a, 0x1f, 0x06, +0x07, 0x2d, 0x21, 0x22, 0x41, 0x8a, 0x77, 0x94, +0x70, 0x8a, 0x13, 0x56, 0xe7, 0x4b, 0x72, 0xbd, +0x49, 0xd0, 0x24, 0xa2, 0x46, 0xdc, 0x25, 0x3c, +0xd2, 0x8c, 0xd5, 0x33, 0x2f, 0x5e, 0x25, 0xda, +0xd3, 0x75, 0x23, 0x2a, 0xb4, 0xd7, 0x92, 0x7a, +0x97, 0x9f, 0xef, 0x0f, 0xfd, 0x0f, 0x9a, 0x5f, +0xec, 0x56, 0x03, 0xd9, 0xc4, 0x09, 0x3f, 0xb8, +0x04, 0x8e, 0xa6, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clip_copy_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clip_copy_png = new wxImage(); + if (!img_clip_copy_png || !img_clip_copy_png->IsOk()) + { + wxMemoryInputStream img_clip_copy_pngIS(clip_copy_png_data, sizeof(clip_copy_png_data)); + img_clip_copy_png->LoadFile(img_clip_copy_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clip_copy_png; +} +#define clip_copy_png_img clip_copy_png_img() + +static wxBitmap *clip_copy_png_bmp() +{ + static wxBitmap *bmp_clip_copy_png; + if (!bmp_clip_copy_png || !bmp_clip_copy_png->IsOk()) + bmp_clip_copy_png = new wxBitmap(*clip_copy_png_img); + return bmp_clip_copy_png; +} +#define clip_copy_png_bmp clip_copy_png_bmp() + +static wxIcon *clip_copy_png_ico() +{ + static wxIcon *ico_clip_copy_png; + if (!ico_clip_copy_png || !ico_clip_copy_png->IsOk()) + { + ico_clip_copy_png = new wxIcon(); + ico_clip_copy_png->CopyFromBitmap(*clip_copy_png_bmp); + } + return ico_clip_copy_png; +} +#define clip_copy_png_ico clip_copy_png_ico() + +#endif // CLIP_COPY_PNG_H diff --git a/include/images/clip_cut.png b/include/images/clip_cut.png new file mode 100644 index 0000000..88e6ce7 Binary files /dev/null and b/include/images/clip_cut.png differ diff --git a/include/images/clip_cut.pngc b/include/images/clip_cut.pngc new file mode 100644 index 0000000..b8303b9 --- /dev/null +++ b/include/images/clip_cut.pngc @@ -0,0 +1,115 @@ +#ifndef CLIP_CUT_PNG_H +#define CLIP_CUT_PNG_H + +static const unsigned char clip_cut_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x96, 0x96, 0x96, 0x6d, +0x6d, 0x6d, 0xc4, 0xc9, 0xcb, 0xc8, 0xc8, 0xc8, +0xf3, 0xf2, 0xf2, 0xc8, 0xcd, 0xcf, 0xa6, 0xa7, +0xa8, 0x9f, 0x9f, 0x9f, 0xb3, 0xb3, 0xb3, 0xe3, +0xe3, 0xe4, 0xd5, 0xd9, 0xda, 0xcd, 0xcf, 0xd0, +0x87, 0x87, 0x87, 0xc5, 0xc5, 0xc5, 0xd3, 0xd4, +0xd4, 0xe4, 0xe6, 0xe7, 0xfa, 0xfb, 0xfb, 0x89, +0x89, 0x89, 0xe0, 0xe0, 0xe0, 0xc7, 0xc8, 0xc9, +0x8d, 0x8d, 0x8d, 0xc7, 0xc7, 0xc8, 0xfe, 0xfe, +0xfe, 0xb9, 0xb9, 0xb9, 0xd0, 0xd1, 0xd1, 0xa8, +0xa8, 0xa8, 0xb6, 0xb6, 0xb6, 0x8a, 0x8a, 0x8a, +0xf7, 0xf7, 0xf7, 0xdd, 0xdd, 0xdd, 0xc6, 0xc7, +0xc7, 0x80, 0x80, 0x80, 0xc1, 0xc1, 0xc1, 0xce, +0xce, 0xcf, 0xa8, 0xa8, 0xa9, 0xd9, 0xda, 0xda, +0xc4, 0xc5, 0xc6, 0xce, 0xcf, 0xcf, 0xab, 0xab, +0xab, 0xcb, 0xcc, 0xcc, 0xa2, 0xa2, 0xa2, 0xde, +0xde, 0xde, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, +0x94, 0x96, 0x96, 0xa1, 0xa1, 0xa1, 0xd6, 0xd7, +0xd7, 0xc4, 0xc5, 0xc5, 0xee, 0xee, 0xee, 0x9a, +0x9b, 0x9b, 0xc2, 0xcb, 0xce, 0xfb, 0xfb, 0xfb, +0x98, 0x98, 0x98, 0x8e, 0x8f, 0x8f, 0xfa, 0xfa, +0xfa, 0xaf, 0xba, 0xbe, 0xf0, 0xf0, 0xf0, 0xd4, +0xd4, 0xd5, 0xfd, 0xfd, 0xfd, 0x98, 0x9a, 0x9a, +0x8a, 0x8d, 0x8f, 0xa6, 0xb2, 0xb6, 0x8d, 0x8e, +0x8e, 0xe5, 0xe4, 0xe4, 0x9d, 0x9e, 0x9e, 0xcf, +0xd6, 0xd8, 0xac, 0xb7, 0xbc, 0x82, 0x86, 0x87, +0x91, 0x91, 0x91, 0xd7, 0xd7, 0xd7, 0x9e, 0x9d, +0x9d, 0x5e, 0x66, 0x2b, 0x65, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x92, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x4d, 0xcf, 0xd7, 0x0e, 0xc2, 0x30, 0x0c, +0x05, 0xd0, 0xe4, 0xd2, 0xb2, 0x77, 0x1b, 0x56, +0x81, 0xb2, 0x37, 0xa5, 0xac, 0xb2, 0xf7, 0xfa, +0xff, 0x3f, 0xa2, 0x42, 0x0d, 0xb1, 0x25, 0xbf, +0x1c, 0x59, 0xd7, 0x36, 0x63, 0x7e, 0x71, 0xf0, +0x5f, 0xff, 0x0b, 0x21, 0x68, 0xd0, 0x41, 0x20, +0x1c, 0x89, 0xc6, 0xe2, 0x14, 0x12, 0xc9, 0x54, +0x3a, 0x43, 0x21, 0x9b, 0xcb, 0x1b, 0x26, 0x01, +0x51, 0x28, 0x96, 0xca, 0x15, 0xa1, 0xc0, 0xaa, +0xd6, 0xea, 0x76, 0xc3, 0x62, 0x64, 0xa4, 0xd9, +0x6a, 0x0b, 0x8d, 0x00, 0x3a, 0xdd, 0x5e, 0x5f, +0x1d, 0xc2, 0x81, 0xc1, 0x70, 0x34, 0x9e, 0x4c, +0x03, 0xe1, 0x8e, 0x3e, 0x73, 0x31, 0x77, 0x16, +0xcb, 0x60, 0x0f, 0x56, 0x6b, 0xcf, 0xc4, 0x06, +0xd8, 0x4a, 0xd8, 0x01, 0x7b, 0x1c, 0x8e, 0xa7, +0xb3, 0x04, 0xe3, 0xe2, 0x5d, 0x71, 0xbb, 0x3f, +0x9e, 0x32, 0xe3, 0xe5, 0xbe, 0x3f, 0xdc, 0x4f, +0xa6, 0x5b, 0xd4, 0xeb, 0x5f, 0x63, 0x0b, 0x0b, +0x6b, 0xf2, 0xd8, 0x63, 0x55, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clip_cut_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clip_cut_png = new wxImage(); + if (!img_clip_cut_png || !img_clip_cut_png->IsOk()) + { + wxMemoryInputStream img_clip_cut_pngIS(clip_cut_png_data, sizeof(clip_cut_png_data)); + img_clip_cut_png->LoadFile(img_clip_cut_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clip_cut_png; +} +#define clip_cut_png_img clip_cut_png_img() + +static wxBitmap *clip_cut_png_bmp() +{ + static wxBitmap *bmp_clip_cut_png; + if (!bmp_clip_cut_png || !bmp_clip_cut_png->IsOk()) + bmp_clip_cut_png = new wxBitmap(*clip_cut_png_img); + return bmp_clip_cut_png; +} +#define clip_cut_png_bmp clip_cut_png_bmp() + +static wxIcon *clip_cut_png_ico() +{ + static wxIcon *ico_clip_cut_png; + if (!ico_clip_cut_png || !ico_clip_cut_png->IsOk()) + { + ico_clip_cut_png = new wxIcon(); + ico_clip_cut_png->CopyFromBitmap(*clip_cut_png_bmp); + } + return ico_clip_cut_png; +} +#define clip_cut_png_ico clip_cut_png_ico() + +#endif // CLIP_CUT_PNG_H diff --git a/include/images/clip_paste.png b/include/images/clip_paste.png new file mode 100644 index 0000000..e09ebc5 Binary files /dev/null and b/include/images/clip_paste.png differ diff --git a/include/images/clip_paste.pngc b/include/images/clip_paste.pngc new file mode 100644 index 0000000..8a69886 --- /dev/null +++ b/include/images/clip_paste.pngc @@ -0,0 +1,125 @@ +#ifndef CLIP_PASTE_PNG_H +#define CLIP_PASTE_PNG_H + +static const unsigned char clip_paste_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x02, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8e, 0x8e, 0x8e, 0x60, +0x60, 0x60, 0xa3, 0x98, 0x62, 0x83, 0x70, 0x15, +0x6e, 0x67, 0x41, 0xc4, 0xc4, 0xc4, 0xc9, 0xc9, +0xc9, 0xcf, 0xcf, 0xcf, 0x95, 0x8f, 0x63, 0xe8, +0xe8, 0xe8, 0xf0, 0xf0, 0xf0, 0x90, 0x88, 0x66, +0xe1, 0xd1, 0x67, 0xd7, 0xd7, 0xd7, 0xdf, 0xdf, +0xdf, 0xf7, 0xf7, 0xf7, 0xfd, 0xfd, 0xfd, 0xff, +0xff, 0xff, 0xd2, 0xbc, 0x70, 0xdb, 0xc7, 0x57, +0x8e, 0x83, 0x4f, 0x85, 0x78, 0x53, 0xc9, 0xae, +0x61, 0xda, 0xc6, 0x58, 0xcd, 0xb3, 0x37, 0xcb, +0xb1, 0x38, 0xc9, 0xae, 0x39, 0xc7, 0xab, 0x3a, +0xc5, 0xa8, 0x3b, 0xc2, 0xa4, 0x3c, 0xc0, 0xa1, +0x3e, 0xbe, 0x9e, 0x3f, 0xbb, 0x9a, 0x40, 0xb9, +0x97, 0x41, 0xc7, 0xac, 0x62, 0xd8, 0xc4, 0x58, +0x88, 0x7c, 0x51, 0xd7, 0xc2, 0x59, 0xf2, 0xf9, +0xfc, 0xe7, 0xf3, 0xf8, 0xe5, 0xf2, 0xf7, 0xe3, +0xf0, 0xf6, 0xe0, 0xee, 0xf4, 0xd5, 0xc0, 0x5a, +0xd7, 0xea, 0xf3, 0xd3, 0xe8, 0xf1, 0xcf, 0xe5, +0xee, 0xca, 0xe2, 0xeb, 0xdc, 0xeb, 0xf0, 0xda, +0xc7, 0x6c, 0xc8, 0xad, 0x43, 0xe4, 0xf1, 0xf7, +0x2c, 0x66, 0xbd, 0xc5, 0xde, 0xe7, 0xd7, 0xc3, +0x6d, 0xce, 0xb6, 0x5e, 0xcd, 0xb4, 0x5f, 0xca, +0xb1, 0x60, 0xe2, 0xef, 0xf5, 0xce, 0xe4, 0xed, +0xc9, 0xe1, 0xea, 0xc4, 0xdd, 0xe7, 0xbf, 0xda, +0xe4, 0xba, 0xd6, 0xe0, 0xb5, 0xd2, 0xdd, 0xcc, +0xe0, 0xe7, 0xde, 0xed, 0xf3, 0xc8, 0xdd, 0xe4, +0xdb, 0xeb, 0xf1, 0xc3, 0xdc, 0xe6, 0xbd, 0xd9, +0xe3, 0xb8, 0xd5, 0xdf, 0xb3, 0xd1, 0xdc, 0xae, +0xce, 0xd9, 0xaa, 0xcb, 0xd6, 0xc4, 0xdb, 0xe2, +0xd7, 0xe8, 0xef, 0xc2, 0xd9, 0xe0, 0xe5, 0xef, +0xf4, 0xd0, 0xe3, 0xea, 0xcd, 0xe0, 0xe8, 0xca, +0xde, 0xe6, 0xc6, 0xdc, 0xe4, 0xc1, 0xd9, 0xe0, +0xd9, 0xe7, 0xec, 0x18, 0xe5, 0x5d, 0x69, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x12, 0x7b, 0xbc, 0x6c, +0x00, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xae, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x3d, 0x8e, 0x45, 0x16, 0xc3, 0x30, 0x14, 0x03, +0x13, 0xc5, 0x29, 0x33, 0x33, 0x33, 0x53, 0xca, +0xcc, 0xcc, 0xbd, 0xff, 0x55, 0x6a, 0x3b, 0x69, +0x67, 0xa7, 0xb1, 0xfe, 0xb3, 0x04, 0x81, 0x22, +0x82, 0x22, 0x0a, 0x1a, 0x12, 0x91, 0xa1, 0xd3, +0xe9, 0x0d, 0x90, 0x89, 0xa4, 0x66, 0x23, 0x68, +0x82, 0xc9, 0x0c, 0x0b, 0x37, 0xc4, 0x0a, 0x9b, +0xdd, 0x64, 0x76, 0x38, 0x5d, 0x2e, 0xb8, 0x09, +0x13, 0x1e, 0x2f, 0x34, 0x7c, 0x7e, 0x2e, 0x02, +0xc1, 0x50, 0x38, 0x12, 0x8d, 0xc5, 0x13, 0xc9, +0x54, 0x9a, 0x8b, 0x0c, 0xcb, 0x59, 0xb5, 0x23, +0x33, 0x91, 0x63, 0xef, 0xc8, 0x17, 0x8a, 0xa5, +0x32, 0xff, 0x9b, 0x54, 0x58, 0x1f, 0x85, 0x6a, +0xad, 0xde, 0x40, 0x93, 0x1a, 0xd2, 0x6a, 0xd3, +0x7b, 0x74, 0x14, 0x45, 0xe9, 0xb2, 0x2b, 0xba, +0xa3, 0xd7, 0x1f, 0x0c, 0x31, 0x1a, 0x4f, 0xa6, +0xb3, 0xf9, 0x62, 0x09, 0xb6, 0x8c, 0x82, 0x95, +0xc2, 0x59, 0x43, 0xdb, 0x8f, 0xcd, 0x76, 0xb7, +0x3f, 0x1c, 0x4f, 0xe7, 0xbf, 0xb8, 0xa8, 0x8d, +0xeb, 0x5f, 0xdc, 0xee, 0x8f, 0xe7, 0xeb, 0xfc, +0xfe, 0xfc, 0x84, 0xf8, 0x9b, 0x2f, 0x7e, 0x01, +0xfb, 0xda, 0x14, 0x63, 0x8f, 0x4e, 0x34, 0x91, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *clip_paste_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_clip_paste_png = new wxImage(); + if (!img_clip_paste_png || !img_clip_paste_png->IsOk()) + { + wxMemoryInputStream img_clip_paste_pngIS(clip_paste_png_data, sizeof(clip_paste_png_data)); + img_clip_paste_png->LoadFile(img_clip_paste_pngIS, wxBITMAP_TYPE_PNG); + } + return img_clip_paste_png; +} +#define clip_paste_png_img clip_paste_png_img() + +static wxBitmap *clip_paste_png_bmp() +{ + static wxBitmap *bmp_clip_paste_png; + if (!bmp_clip_paste_png || !bmp_clip_paste_png->IsOk()) + bmp_clip_paste_png = new wxBitmap(*clip_paste_png_img); + return bmp_clip_paste_png; +} +#define clip_paste_png_bmp clip_paste_png_bmp() + +static wxIcon *clip_paste_png_ico() +{ + static wxIcon *ico_clip_paste_png; + if (!ico_clip_paste_png || !ico_clip_paste_png->IsOk()) + { + ico_clip_paste_png = new wxIcon(); + ico_clip_paste_png->CopyFromBitmap(*clip_paste_png_bmp); + } + return ico_clip_paste_png; +} +#define clip_paste_png_ico clip_paste_png_ico() + +#endif // CLIP_PASTE_PNG_H diff --git a/include/images/closeddatabase-sm.png b/include/images/closeddatabase-sm.png new file mode 100644 index 0000000..0bf4b6d Binary files /dev/null and b/include/images/closeddatabase-sm.png differ diff --git a/include/images/closeddatabase-sm.pngc b/include/images/closeddatabase-sm.pngc new file mode 100644 index 0000000..8562b23 --- /dev/null +++ b/include/images/closeddatabase-sm.pngc @@ -0,0 +1,151 @@ +#ifndef CLOSEDDATABASE_SM_PNG_H +#define CLOSEDDATABASE_SM_PNG_H + +static const unsigned char closeddatabase_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0xc8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdb, 0xd0, 0xa6, 0xca, +0xb9, 0x7c, 0xbb, 0xa5, 0x55, 0xb0, 0x97, 0x3a, +0xaf, 0x96, 0x37, 0xb1, 0x99, 0x3d, 0xbc, 0xa6, +0x58, 0xcb, 0xbb, 0x7e, 0xe2, 0xd8, 0xb6, 0xc8, +0xb7, 0x74, 0xc1, 0xae, 0x5e, 0xd8, 0xca, 0x8f, +0xe7, 0xdc, 0xaa, 0xee, 0xe9, 0xbd, 0xf2, 0xf1, +0xc2, 0xed, 0xea, 0xb5, 0xe1, 0xdc, 0x9e, 0xd4, +0xcb, 0x83, 0xc6, 0xbb, 0x67, 0xb6, 0xa3, 0x46, +0xcb, 0xbc, 0x7f, 0xc1, 0xad, 0x61, 0xeb, 0xe2, +0xbc, 0xff, 0xfd, 0xe8, 0xfd, 0xfa, 0xdc, 0xfa, +0xf8, 0xd1, 0xf4, 0xf1, 0xc5, 0xef, 0xed, 0xbb, +0xea, 0xe9, 0xb4, 0xe7, 0xe5, 0xb1, 0xe6, 0xe6, +0xb1, 0xdd, 0xd6, 0xa0, 0xbd, 0xa9, 0x5b, 0xb6, +0xa0, 0x4a, 0xe9, 0xe1, 0xc1, 0xf3, 0xec, 0xce, +0xf7, 0xf2, 0xd2, 0xf7, 0xf4, 0xd4, 0xf7, 0xf7, +0xde, 0xf5, 0xf5, 0xda, 0xf5, 0xf4, 0xdb, 0xf0, +0xee, 0xd2, 0xef, 0xed, 0xce, 0xf1, 0xec, 0xd1, +0xb3, 0x9c, 0x42, 0xb5, 0x9e, 0x47, 0xe8, 0xdf, +0xc5, 0xf5, 0xec, 0xda, 0xfb, 0xf4, 0xe6, 0xe7, +0x9c, 0x8c, 0xd3, 0x42, 0x3f, 0xe0, 0x93, 0x74, +0xe7, 0xe2, 0x9f, 0xe5, 0xdf, 0x97, 0xdd, 0xa3, +0x74, 0xd0, 0x48, 0x39, 0xb7, 0x51, 0x1c, 0xe9, +0xe0, 0xc9, 0xf8, 0xf0, 0xe6, 0xea, 0x9f, 0x9a, +0xcb, 0x1a, 0x18, 0xf1, 0x6c, 0x6c, 0xc7, 0x14, +0x0c, 0xd6, 0x88, 0x4f, 0xd9, 0xa2, 0x5d, 0xca, +0x28, 0x18, 0xe5, 0x41, 0x41, 0xc5, 0x07, 0x04, +0xdd, 0x69, 0x69, 0xf8, 0xef, 0xe5, 0xda, 0x5d, +0x5b, 0xe9, 0x57, 0x57, 0xf5, 0x71, 0x71, 0xee, +0x5f, 0x5f, 0xcb, 0x20, 0x15, 0xcc, 0x2e, 0x1c, +0xe2, 0x3a, 0x3a, 0xef, 0x4f, 0x4f, 0xe9, 0x40, +0x41, 0xc7, 0x0b, 0x0b, 0xef, 0xb6, 0xaf, 0xd0, +0x32, 0x2e, 0xe6, 0x4b, 0x4b, 0xf3, 0x65, 0x65, +0xe8, 0x49, 0x49, 0xdf, 0x34, 0x34, 0xef, 0x4e, +0x4e, 0xe4, 0x37, 0x38, 0xc3, 0x12, 0x07, 0xff, +0xf9, 0xf0, 0xef, 0xb7, 0xa3, 0xcf, 0x31, 0x25, +0xdf, 0x37, 0x37, 0xf0, 0x54, 0x55, 0xef, 0x4d, +0x4d, 0xe1, 0x32, 0x32, 0xcf, 0x2b, 0x22, 0xb4, +0x63, 0x21, 0xeb, 0xa6, 0x94, 0xcc, 0x22, 0x1a, +0xe3, 0x3a, 0x3a, 0xef, 0x4c, 0x4c, 0xed, 0x44, +0x44, 0xe3, 0x2f, 0x2f, 0xce, 0x20, 0x1a, 0xb6, +0x56, 0x1d, 0xe9, 0xe1, 0xc9, 0xf8, 0xf1, 0xe6, +0xec, 0xa8, 0xa2, 0xcd, 0x22, 0x20, 0xe9, 0x44, +0x44, 0xee, 0x4b, 0x4b, 0xe2, 0x32, 0x33, 0xda, +0x1f, 0x1f, 0xea, 0x34, 0x34, 0xe4, 0x27, 0x27, +0xc4, 0x09, 0x04, 0xdc, 0x68, 0x68, 0xb1, 0x99, +0x3e, 0xd7, 0xc9, 0x9b, 0xf7, 0xee, 0xe0, 0xd8, +0x57, 0x54, 0xe6, 0x40, 0x40, 0xed, 0x49, 0x49, +0xe5, 0x37, 0x38, 0xc8, 0x1f, 0x11, 0xca, 0x33, +0x1c, 0xdb, 0x1b, 0x1a, 0xe7, 0x25, 0x25, 0xe5, +0x1f, 0x1f, 0xc5, 0x03, 0x03, 0xbc, 0xa7, 0x57, +0xcd, 0xb9, 0x7b, 0xd0, 0x88, 0x60, 0xc5, 0x1e, +0x11, 0xe3, 0x32, 0x33, 0xc3, 0x1a, 0x0b, 0xc9, +0x82, 0x41, 0xcb, 0x95, 0x4d, 0xc7, 0x30, 0x1d, +0xda, 0x16, 0x16, 0xca, 0x16, 0x16, 0xc9, 0xb8, +0x78, 0xba, 0xa5, 0x55, 0xbb, 0x4f, 0x20, 0xc4, +0x01, 0x00, 0xba, 0x4a, 0x1b, 0xbc, 0xa7, 0x59, +0xc7, 0x73, 0x4c, 0xc5, 0x10, 0x0b, 0xda, 0x63, +0x60, 0x96, 0xc1, 0xe3, 0xe0, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xc4, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0xc0, 0x02, 0x18, 0x99, 0x98, +0x59, 0x58, 0x59, 0xd9, 0xd8, 0x39, 0x38, 0x21, +0x7c, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e, 0x01, +0x41, 0x21, 0x61, 0x11, 0x51, 0xb0, 0x80, 0x98, +0xb8, 0x84, 0xa4, 0x94, 0xb4, 0x8c, 0xac, 0x9c, +0xbc, 0x82, 0x22, 0x58, 0x40, 0x49, 0x59, 0x45, +0x55, 0x4d, 0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x47, +0x17, 0x2c, 0xa0, 0xa7, 0x6f, 0x60, 0x68, 0x64, +0x6c, 0x62, 0x6a, 0x66, 0x6e, 0x61, 0x09, 0x11, +0xb0, 0xb2, 0xb6, 0xb1, 0xb5, 0xb3, 0x77, 0x70, +0x74, 0x72, 0x76, 0x71, 0x85, 0x08, 0xb8, 0xb9, +0x7b, 0x78, 0x7a, 0x79, 0xfb, 0xf8, 0xfa, 0xf9, +0x07, 0x40, 0x55, 0x04, 0x06, 0x05, 0x87, 0x84, +0x86, 0x85, 0x47, 0x44, 0x42, 0x55, 0x58, 0x47, +0x45, 0xc7, 0xc4, 0xc6, 0xc5, 0x27, 0x24, 0x26, +0xc1, 0xcc, 0x88, 0x4a, 0x4e, 0x49, 0x4d, 0x4b, +0xcf, 0xc8, 0xcc, 0x82, 0x08, 0x64, 0xe7, 0xe4, +0xe6, 0xe5, 0x17, 0x14, 0x16, 0x15, 0x97, 0x94, +0x96, 0x81, 0x04, 0xca, 0x2b, 0x2a, 0xab, 0xaa, +0x6b, 0x6a, 0xeb, 0xea, 0x1b, 0x1a, 0x9b, 0x9a, +0xc1, 0x4a, 0x5a, 0x5a, 0xdb, 0xda, 0x3b, 0x3a, +0xbb, 0xba, 0x7b, 0x7a, 0xfb, 0x5c, 0x21, 0xbe, +0xe9, 0x9f, 0x30, 0x71, 0xd2, 0x64, 0xb6, 0x29, +0x53, 0xa7, 0x4d, 0xc7, 0xe2, 0x75, 0x00, 0xba, +0x85, 0x30, 0x71, 0x36, 0x9e, 0x2d, 0x94, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *closeddatabase_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_closeddatabase_sm_png = new wxImage(); + if (!img_closeddatabase_sm_png || !img_closeddatabase_sm_png->IsOk()) + { + wxMemoryInputStream img_closeddatabase_sm_pngIS(closeddatabase_sm_png_data, sizeof(closeddatabase_sm_png_data)); + img_closeddatabase_sm_png->LoadFile(img_closeddatabase_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_closeddatabase_sm_png; +} +#define closeddatabase_sm_png_img closeddatabase_sm_png_img() + +static wxBitmap *closeddatabase_sm_png_bmp() +{ + static wxBitmap *bmp_closeddatabase_sm_png; + if (!bmp_closeddatabase_sm_png || !bmp_closeddatabase_sm_png->IsOk()) + bmp_closeddatabase_sm_png = new wxBitmap(*closeddatabase_sm_png_img); + return bmp_closeddatabase_sm_png; +} +#define closeddatabase_sm_png_bmp closeddatabase_sm_png_bmp() + +static wxIcon *closeddatabase_sm_png_ico() +{ + static wxIcon *ico_closeddatabase_sm_png; + if (!ico_closeddatabase_sm_png || !ico_closeddatabase_sm_png->IsOk()) + { + ico_closeddatabase_sm_png = new wxIcon(); + ico_closeddatabase_sm_png->CopyFromBitmap(*closeddatabase_sm_png_bmp); + } + return ico_closeddatabase_sm_png; +} +#define closeddatabase_sm_png_ico closeddatabase_sm_png_ico() + +#endif // CLOSEDDATABASE_SM_PNG_H diff --git a/include/images/closeddatabase.png b/include/images/closeddatabase.png new file mode 100644 index 0000000..9683290 Binary files /dev/null and b/include/images/closeddatabase.png differ diff --git a/include/images/closeddatabase.pngc b/include/images/closeddatabase.pngc new file mode 100644 index 0000000..0777f0e --- /dev/null +++ b/include/images/closeddatabase.pngc @@ -0,0 +1,146 @@ +#ifndef CLOSEDDATABASE_PNG_H +#define CLOSEDDATABASE_PNG_H + +static const unsigned char closeddatabase_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x7d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd3, 0xc5, 0x91, 0xc3, +0xb0, 0x6a, 0xb7, 0xa0, 0x4b, 0xaf, 0x96, 0x37, +0xe6, 0xde, 0xc0, 0xd1, 0xc3, 0x8d, 0xb2, 0x9b, +0x3b, 0xc6, 0xb4, 0x69, 0xda, 0xcb, 0x8e, 0xe6, +0xdc, 0xa9, 0xed, 0xe8, 0xbd, 0xf2, 0xf2, 0xc2, +0xef, 0xec, 0xb7, 0xe4, 0xdf, 0xa2, 0xd6, 0xce, +0x88, 0xca, 0xbd, 0x6d, 0xbc, 0xad, 0x52, 0xaf, +0x98, 0x36, 0xc1, 0xad, 0x63, 0xdd, 0xd0, 0x99, +0xff, 0xfd, 0xee, 0xff, 0xfd, 0xe3, 0xfe, 0xf9, +0xd8, 0xf9, 0xf9, 0xd1, 0xf5, 0xf0, 0xc5, 0xf1, +0xee, 0xbc, 0xec, 0xe9, 0xb2, 0xe5, 0xe5, 0xab, +0xe4, 0xe1, 0xa0, 0xdf, 0xdf, 0x9b, 0xc7, 0xbc, +0x6a, 0xb0, 0x98, 0x3b, 0xe9, 0xe1, 0xb7, 0xfc, +0xf9, 0xd9, 0xfa, 0xf7, 0xcf, 0xf4, 0xf4, 0xc7, +0xee, 0xee, 0xbe, 0xed, 0xed, 0xbb, 0xec, 0xe9, +0xbf, 0xed, 0xed, 0xca, 0xf4, 0xf4, 0xdb, 0xfc, +0xf9, 0xf2, 0xb8, 0xa2, 0x4e, 0xac, 0x92, 0x30, +0xe3, 0xdb, 0xbd, 0xe9, 0xdc, 0xb9, 0xed, 0xe3, +0xbb, 0xf5, 0xf0, 0xd4, 0xf5, 0xf2, 0xd9, 0xfb, +0xfb, 0xf1, 0xfe, 0xfe, 0xfb, 0xf7, 0xf4, 0xe8, +0xf0, 0xed, 0xd2, 0xec, 0xe9, 0xc4, 0xea, 0xe2, +0xba, 0xe5, 0xdd, 0xc2, 0xf4, 0xea, 0xd8, 0xff, +0xf8, 0xf3, 0xff, 0xf7, 0xee, 0xdc, 0x64, 0x57, +0xc5, 0x00, 0x00, 0xd5, 0x5d, 0x3f, 0xe1, 0xd9, +0x84, 0xe0, 0xda, 0x7b, 0xd2, 0x5d, 0x3e, 0xbb, +0x3c, 0x14, 0xf3, 0xe9, 0xda, 0xdd, 0x66, 0x62, +0xf6, 0x77, 0x77, 0xd1, 0x5b, 0x36, 0xf1, 0x57, +0x57, 0xdd, 0x69, 0x69, 0xf2, 0xe8, 0xd9, 0xf6, +0x76, 0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, 0x6e, +0xd0, 0x5a, 0x33, 0xef, 0x4f, 0x4f, 0xee, 0x48, +0x49, 0xff, 0xfa, 0xf4, 0xdd, 0x67, 0x62, 0xf5, +0x6d, 0x6d, 0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, +0xf0, 0x55, 0x55, 0xff, 0xf9, 0xee, 0xf3, 0x61, +0x61, 0xf1, 0x5b, 0x5b, 0xf0, 0x53, 0x54, 0xef, +0x4d, 0x4e, 0xee, 0x47, 0x47, 0xff, 0xfa, 0xef, +0xfe, 0xf4, 0xd3, 0xd9, 0x62, 0x4a, 0xef, 0x4d, +0x4d, 0xd4, 0x5e, 0x46, 0xf0, 0x53, 0x53, 0xef, +0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, 0x3f, +0xeb, 0x38, 0x38, 0xf2, 0xea, 0xd9, 0xf0, 0x52, +0x52, 0xef, 0x4b, 0x4b, 0xed, 0x44, 0x45, 0xeb, +0x37, 0x37, 0xea, 0x31, 0x31, 0xe9, 0x2b, 0x2b, +0xcb, 0xbc, 0x82, 0xff, 0xf8, 0xf2, 0xf0, 0x51, +0x51, 0xee, 0x4a, 0x4a, 0xed, 0x43, 0x44, 0xe8, +0x25, 0x25, 0xe7, 0x20, 0x20, 0xb0, 0x99, 0x39, +0xc2, 0xae, 0x65, 0xdb, 0xc6, 0x94, 0xd5, 0x5b, +0x4b, 0xed, 0x42, 0x43, 0xd3, 0xc8, 0x66, 0xcb, +0x52, 0x2c, 0xe7, 0x1f, 0x20, 0xbc, 0x3e, 0x17, +0xca, 0x51, 0x3c, 0xdb, 0x67, 0x64, 0xed, 0xe4, +0xba, 0x77, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xe8, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x60, 0x60, 0x64, 0x62, 0x66, 0x01, 0x02, +0x66, 0x26, 0x46, 0x56, 0x20, 0x8f, 0x81, 0x8d, +0x9d, 0x83, 0x93, 0x8b, 0x9b, 0x87, 0x97, 0x8f, +0x5f, 0x40, 0x50, 0x08, 0x24, 0x20, 0x2c, 0x22, +0x2a, 0x26, 0x2e, 0x21, 0x29, 0x25, 0x2d, 0x23, +0x2b, 0x27, 0x2f, 0x0c, 0x14, 0x50, 0x50, 0x14, +0x15, 0x53, 0x52, 0x56, 0x51, 0x55, 0x53, 0xd7, +0xd0, 0xd4, 0xd2, 0x06, 0x0a, 0xe8, 0xe8, 0xea, +0xe9, 0x1b, 0x18, 0x1a, 0x19, 0x19, 0x9b, 0x98, +0x9a, 0x99, 0xeb, 0x80, 0x04, 0x2c, 0x2c, 0xad, +0xac, 0x6d, 0x6c, 0xed, 0xec, 0x1d, 0xec, 0x1d, +0x6d, 0x9d, 0xc0, 0x02, 0xce, 0x56, 0x2e, 0xb6, +0xae, 0xb6, 0x6e, 0x0e, 0x6e, 0xb6, 0xee, 0xb6, +0x1e, 0x20, 0x01, 0x4f, 0x2b, 0x5b, 0x2f, 0x6f, +0x1f, 0x5b, 0x5f, 0x5b, 0x77, 0x3f, 0x7f, 0x5b, +0xb0, 0x40, 0x40, 0xa0, 0x6d, 0x50, 0x70, 0x88, +0x6d, 0x28, 0x90, 0x0f, 0x51, 0x11, 0x10, 0x66, +0x63, 0x1b, 0x1e, 0x11, 0x19, 0x15, 0x0d, 0x35, +0xc3, 0xd3, 0x2a, 0x26, 0x36, 0xce, 0x36, 0x32, +0x3e, 0xda, 0x36, 0x01, 0x62, 0x8b, 0x73, 0x40, +0x8c, 0x8d, 0x6d, 0x62, 0x52, 0x72, 0x4a, 0x2a, +0x54, 0x45, 0x1a, 0xd0, 0x8c, 0xf4, 0x8c, 0x4c, +0xdb, 0xac, 0xec, 0x1c, 0xb0, 0x19, 0xb9, 0x96, +0x79, 0xb6, 0xf9, 0x05, 0x85, 0x40, 0x5b, 0x72, +0x8a, 0x8a, 0x81, 0xb6, 0x30, 0x94, 0x94, 0x96, +0x95, 0xdb, 0x56, 0xd8, 0xfa, 0x56, 0x56, 0xd9, +0x56, 0x83, 0x54, 0x80, 0xbd, 0x5f, 0x63, 0x5b, +0x03, 0xf4, 0x7e, 0xad, 0x6d, 0x1d, 0x03, 0x00, +0x7e, 0x48, 0x33, 0xf7, 0x26, 0xab, 0x55, 0x6a, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *closeddatabase_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_closeddatabase_png = new wxImage(); + if (!img_closeddatabase_png || !img_closeddatabase_png->IsOk()) + { + wxMemoryInputStream img_closeddatabase_pngIS(closeddatabase_png_data, sizeof(closeddatabase_png_data)); + img_closeddatabase_png->LoadFile(img_closeddatabase_pngIS, wxBITMAP_TYPE_PNG); + } + return img_closeddatabase_png; +} +#define closeddatabase_png_img closeddatabase_png_img() + +static wxBitmap *closeddatabase_png_bmp() +{ + static wxBitmap *bmp_closeddatabase_png; + if (!bmp_closeddatabase_png || !bmp_closeddatabase_png->IsOk()) + bmp_closeddatabase_png = new wxBitmap(*closeddatabase_png_img); + return bmp_closeddatabase_png; +} +#define closeddatabase_png_bmp closeddatabase_png_bmp() + +static wxIcon *closeddatabase_png_ico() +{ + static wxIcon *ico_closeddatabase_png; + if (!ico_closeddatabase_png || !ico_closeddatabase_png->IsOk()) + { + ico_closeddatabase_png = new wxIcon(); + ico_closeddatabase_png->CopyFromBitmap(*closeddatabase_png_bmp); + } + return ico_closeddatabase_png; +} +#define closeddatabase_png_ico closeddatabase_png_ico() + +#endif // CLOSEDDATABASE_PNG_H diff --git a/include/images/collation-sm.png b/include/images/collation-sm.png new file mode 100644 index 0000000..0bc8ff7 Binary files /dev/null and b/include/images/collation-sm.png differ diff --git a/include/images/collation-sm.pngc b/include/images/collation-sm.pngc new file mode 100644 index 0000000..e054f7c --- /dev/null +++ b/include/images/collation-sm.pngc @@ -0,0 +1,74 @@ +#ifndef COLLATION_SM_PNG_H +#define COLLATION_SM_PNG_H + +static const unsigned char collation_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68, +0x36, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, +0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, 0x09, 0x0f, +0x1b, 0x05, 0xee, 0xa5, 0xd7, 0x2e, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, +0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, +0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, +0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, +0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x56, 0x49, +0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xff, +0xff, 0x3f, 0x03, 0x29, 0x80, 0x89, 0x81, 0x44, +0xc0, 0x32, 0x7f, 0xfe, 0x7c, 0xd2, 0x34, 0x30, +0x30, 0x30, 0x78, 0x5d, 0xbd, 0x0a, 0xe1, 0x88, +0xf7, 0xf4, 0x30, 0x30, 0x30, 0xbc, 0x2c, 0x29, +0xc1, 0xa5, 0x7a, 0x9b, 0xb6, 0x36, 0xc9, 0x4e, +0xa2, 0xbd, 0x06, 0x86, 0x79, 0xf3, 0xe6, 0xfd, +0x27, 0x1a, 0xcc, 0x9b, 0x37, 0x8f, 0xf4, 0x60, +0x45, 0x0e, 0x16, 0x82, 0xa1, 0xc4, 0x30, 0x28, +0x43, 0x89, 0x71, 0xde, 0xbc, 0x79, 0xa4, 0x69, +0xa0, 0x79, 0x6a, 0x05, 0x00, 0xb8, 0xc7, 0x42, +0x84, 0x48, 0xe5, 0x70, 0xb0, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *collation_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_collation_sm_png = new wxImage(); + if (!img_collation_sm_png || !img_collation_sm_png->IsOk()) + { + wxMemoryInputStream img_collation_sm_pngIS(collation_sm_png_data, sizeof(collation_sm_png_data)); + img_collation_sm_png->LoadFile(img_collation_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_collation_sm_png; +} +#define collation_sm_png_img collation_sm_png_img() + +static wxBitmap *collation_sm_png_bmp() +{ + static wxBitmap *bmp_collation_sm_png; + if (!bmp_collation_sm_png || !bmp_collation_sm_png->IsOk()) + bmp_collation_sm_png = new wxBitmap(*collation_sm_png_img); + return bmp_collation_sm_png; +} +#define collation_sm_png_bmp collation_sm_png_bmp() + +static wxIcon *collation_sm_png_ico() +{ + static wxIcon *ico_collation_sm_png; + if (!ico_collation_sm_png || !ico_collation_sm_png->IsOk()) + { + ico_collation_sm_png = new wxIcon(); + ico_collation_sm_png->CopyFromBitmap(*collation_sm_png_bmp); + } + return ico_collation_sm_png; +} +#define collation_sm_png_ico collation_sm_png_ico() + +#endif // COLLATION_SM_PNG_H diff --git a/include/images/collation.png b/include/images/collation.png new file mode 100644 index 0000000..0bc8ff7 Binary files /dev/null and b/include/images/collation.png differ diff --git a/include/images/collation.pngc b/include/images/collation.pngc new file mode 100644 index 0000000..ada945e --- /dev/null +++ b/include/images/collation.pngc @@ -0,0 +1,74 @@ +#ifndef COLLATION_PNG_H +#define COLLATION_PNG_H + +static const unsigned char collation_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68, +0x36, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, +0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, 0x09, 0x0f, +0x1b, 0x05, 0xee, 0xa5, 0xd7, 0x2e, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, +0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x43, 0x72, +0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, +0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, +0x81, 0x0e, 0x17, 0x00, 0x00, 0x00, 0x56, 0x49, +0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0xfc, 0xff, +0xff, 0x3f, 0x03, 0x29, 0x80, 0x89, 0x81, 0x44, +0xc0, 0x32, 0x7f, 0xfe, 0x7c, 0xd2, 0x34, 0x30, +0x30, 0x30, 0x78, 0x5d, 0xbd, 0x0a, 0xe1, 0x88, +0xf7, 0xf4, 0x30, 0x30, 0x30, 0xbc, 0x2c, 0x29, +0xc1, 0xa5, 0x7a, 0x9b, 0xb6, 0x36, 0xc9, 0x4e, +0xa2, 0xbd, 0x06, 0x86, 0x79, 0xf3, 0xe6, 0xfd, +0x27, 0x1a, 0xcc, 0x9b, 0x37, 0x8f, 0xf4, 0x60, +0x45, 0x0e, 0x16, 0x82, 0xa1, 0xc4, 0x30, 0x28, +0x43, 0x89, 0x71, 0xde, 0xbc, 0x79, 0xa4, 0x69, +0xa0, 0x79, 0x6a, 0x05, 0x00, 0xb8, 0xc7, 0x42, +0x84, 0x48, 0xe5, 0x70, 0xb0, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *collation_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_collation_png = new wxImage(); + if (!img_collation_png || !img_collation_png->IsOk()) + { + wxMemoryInputStream img_collation_pngIS(collation_png_data, sizeof(collation_png_data)); + img_collation_png->LoadFile(img_collation_pngIS, wxBITMAP_TYPE_PNG); + } + return img_collation_png; +} +#define collation_png_img collation_png_img() + +static wxBitmap *collation_png_bmp() +{ + static wxBitmap *bmp_collation_png; + if (!bmp_collation_png || !bmp_collation_png->IsOk()) + bmp_collation_png = new wxBitmap(*collation_png_img); + return bmp_collation_png; +} +#define collation_png_bmp collation_png_bmp() + +static wxIcon *collation_png_ico() +{ + static wxIcon *ico_collation_png; + if (!ico_collation_png || !ico_collation_png->IsOk()) + { + ico_collation_png = new wxIcon(); + ico_collation_png->CopyFromBitmap(*collation_png_bmp); + } + return ico_collation_png; +} +#define collation_png_ico collation_png_ico() + +#endif // COLLATION_PNG_H diff --git a/include/images/collations.png b/include/images/collations.png new file mode 100644 index 0000000..fa46a49 Binary files /dev/null and b/include/images/collations.png differ diff --git a/include/images/collations.pngc b/include/images/collations.pngc new file mode 100644 index 0000000..feb15ac --- /dev/null +++ b/include/images/collations.pngc @@ -0,0 +1,67 @@ +#ifndef COLLATIONS_PNG_H +#define COLLATIONS_PNG_H + +static const unsigned char collations_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x00, 0x64, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, +0xbd, 0x92, 0x51, 0x0a, 0xc0, 0x20, 0x0c, 0x43, +0x13, 0xf0, 0x0e, 0xee, 0x9e, 0x7a, 0x0c, 0xbd, +0xa7, 0x3b, 0x45, 0xf6, 0xb3, 0x82, 0x0c, 0x86, +0xa8, 0xc5, 0x7c, 0x16, 0xda, 0xbc, 0x36, 0x05, +0x36, 0x45, 0x00, 0x68, 0x29, 0xc9, 0x0a, 0xb1, +0x14, 0x00, 0xc0, 0x9d, 0xf3, 0xb0, 0xf9, 0xaa, +0x95, 0xc1, 0x9d, 0x60, 0x96, 0xc4, 0x87, 0x40, +0x92, 0xfe, 0xdc, 0x46, 0x24, 0xdb, 0x04, 0xa1, +0x9f, 0x3e, 0x93, 0x80, 0xef, 0x0d, 0xbe, 0x29, +0x18, 0xc9, 0x39, 0x02, 0xd3, 0xca, 0x3f, 0xf8, +0xa4, 0xd0, 0xb9, 0xf1, 0x75, 0xd3, 0xd2, 0x00, +0x92, 0xb6, 0x0a, 0x8e, 0xe9, 0x01, 0xed, 0xd6, +0x2a, 0x2f, 0xbc, 0xb1, 0x2d, 0x3a, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *collations_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_collations_png = new wxImage(); + if (!img_collations_png || !img_collations_png->IsOk()) + { + wxMemoryInputStream img_collations_pngIS(collations_png_data, sizeof(collations_png_data)); + img_collations_png->LoadFile(img_collations_pngIS, wxBITMAP_TYPE_PNG); + } + return img_collations_png; +} +#define collations_png_img collations_png_img() + +static wxBitmap *collations_png_bmp() +{ + static wxBitmap *bmp_collations_png; + if (!bmp_collations_png || !bmp_collations_png->IsOk()) + bmp_collations_png = new wxBitmap(*collations_png_img); + return bmp_collations_png; +} +#define collations_png_bmp collations_png_bmp() + +static wxIcon *collations_png_ico() +{ + static wxIcon *ico_collations_png; + if (!ico_collations_png || !ico_collations_png->IsOk()) + { + ico_collations_png = new wxIcon(); + ico_collations_png->CopyFromBitmap(*collations_png_bmp); + } + return ico_collations_png; +} +#define collations_png_ico collations_png_ico() + +#endif // COLLATIONS_PNG_H diff --git a/include/images/column-sm.png b/include/images/column-sm.png new file mode 100644 index 0000000..edbb7b0 Binary files /dev/null and b/include/images/column-sm.png differ diff --git a/include/images/column-sm.pngc b/include/images/column-sm.pngc new file mode 100644 index 0000000..73499c6 --- /dev/null +++ b/include/images/column-sm.pngc @@ -0,0 +1,91 @@ +#ifndef COLUMN_SM_PNG_H +#define COLUMN_SM_PNG_H + +static const unsigned char column_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x54, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x72, 0xac, 0xd6, 0x21, +0x95, 0xe7, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, 0xdd, +0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0x87, 0xbf, +0xe7, 0xa6, 0xa6, 0xa6, 0xec, 0xec, 0xec, 0xae, +0xae, 0xae, 0xe9, 0xe9, 0xe9, 0xa9, 0xa9, 0xa9, +0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, +0xea, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe1, +0xe1, 0xe1, 0xe7, 0xe7, 0xe7, 0xf0, 0xf0, 0xf0, +0xf6, 0xf6, 0xf6, 0xb8, 0xb8, 0xb8, 0xb0, 0xb0, +0xb0, 0xb1, 0xb1, 0xb1, 0xf7, 0xf7, 0xf7, 0xeb, +0xeb, 0xeb, 0xed, 0xed, 0xed, 0xca, 0x15, 0xa0, +0x16, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x56, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, 0xce, 0xc1, +0x16, 0x40, 0x20, 0x10, 0x40, 0xd1, 0x64, 0x44, +0x26, 0xc5, 0x30, 0x11, 0xff, 0xff, 0x9f, 0x9c, +0x36, 0x4d, 0x16, 0x8e, 0xb7, 0xbc, 0xab, 0xa7, +0xd4, 0xaf, 0x1a, 0x9d, 0x2b, 0xa0, 0x5b, 0x80, +0xce, 0xf4, 0x45, 0x34, 0x0c, 0xc6, 0x8e, 0x58, +0x81, 0x9b, 0x7c, 0x10, 0x30, 0x2f, 0x84, 0x44, +0x02, 0xc8, 0x21, 0xba, 0x1a, 0x9e, 0x2a, 0xc8, +0x09, 0x58, 0xfd, 0xc6, 0x91, 0x05, 0xe0, 0x7e, +0xc4, 0x98, 0x04, 0x9c, 0xf6, 0xe2, 0x94, 0xe4, +0xea, 0x6b, 0xfd, 0xb3, 0x1b, 0xc2, 0x60, 0x03, +0xbe, 0x63, 0x8f, 0xeb, 0x04, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *column_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_column_sm_png = new wxImage(); + if (!img_column_sm_png || !img_column_sm_png->IsOk()) + { + wxMemoryInputStream img_column_sm_pngIS(column_sm_png_data, sizeof(column_sm_png_data)); + img_column_sm_png->LoadFile(img_column_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_column_sm_png; +} +#define column_sm_png_img column_sm_png_img() + +static wxBitmap *column_sm_png_bmp() +{ + static wxBitmap *bmp_column_sm_png; + if (!bmp_column_sm_png || !bmp_column_sm_png->IsOk()) + bmp_column_sm_png = new wxBitmap(*column_sm_png_img); + return bmp_column_sm_png; +} +#define column_sm_png_bmp column_sm_png_bmp() + +static wxIcon *column_sm_png_ico() +{ + static wxIcon *ico_column_sm_png; + if (!ico_column_sm_png || !ico_column_sm_png->IsOk()) + { + ico_column_sm_png = new wxIcon(); + ico_column_sm_png->CopyFromBitmap(*column_sm_png_bmp); + } + return ico_column_sm_png; +} +#define column_sm_png_ico column_sm_png_ico() + +#endif // COLUMN_SM_PNG_H diff --git a/include/images/column.png b/include/images/column.png new file mode 100644 index 0000000..bd9f81d Binary files /dev/null and b/include/images/column.png differ diff --git a/include/images/column.pngc b/include/images/column.pngc new file mode 100644 index 0000000..337b467 --- /dev/null +++ b/include/images/column.pngc @@ -0,0 +1,99 @@ +#ifndef COLUMN_PNG_H +#define COLUMN_PNG_H + +static const unsigned char column_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x90, +0xca, 0xf3, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, 0xdd, +0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe5, 0xe5, +0xe5, 0xe6, 0xe6, 0xe6, 0x87, 0xbf, 0xe7, 0xa6, +0xa6, 0xa6, 0xe7, 0xe7, 0xe7, 0xe8, 0xe8, 0xe8, +0xec, 0xec, 0xec, 0xae, 0xae, 0xae, 0xe9, 0xe9, +0xe9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xad, +0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, +0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, +0xe2, 0xab, 0xab, 0xab, 0xac, 0xac, 0xac, 0xb2, +0xb2, 0xb2, 0xf0, 0xf0, 0xf0, 0xeb, 0xeb, 0xeb, +0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, +0xf5, 0xf6, 0xf6, 0xf6, 0xb8, 0xb8, 0xb8, 0xb0, +0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xf7, 0xf7, 0xf7, +0xed, 0xed, 0xed, 0xee, 0xee, 0xee, 0x6a, 0x87, +0xc1, 0xa5, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x75, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x7d, 0xcf, +0xd1, 0x12, 0x82, 0x20, 0x10, 0x85, 0x61, 0x30, +0x2c, 0x0c, 0x69, 0xd7, 0xd4, 0x4d, 0x41, 0x0b, +0x4a, 0x7b, 0xff, 0x47, 0xcc, 0x29, 0xdd, 0xe1, +0xa2, 0xf1, 0xbf, 0xfc, 0x66, 0xce, 0xc5, 0x11, +0x62, 0x49, 0xae, 0x65, 0xe2, 0x97, 0x3c, 0x28, +0x95, 0x1f, 0x4f, 0xba, 0x90, 0x1b, 0xa8, 0xb3, +0x36, 0xa5, 0xbd, 0x40, 0x02, 0x58, 0xe1, 0xb5, +0x6e, 0x18, 0xf2, 0x96, 0xe8, 0x06, 0x44, 0x0c, +0x84, 0xb0, 0x84, 0x29, 0x7c, 0x4b, 0x60, 0x6d, +0x6f, 0xd2, 0xf5, 0x3d, 0x3a, 0xcf, 0xa0, 0x0d, +0x0c, 0x76, 0xbc, 0x3f, 0x18, 0x4c, 0xed, 0xfd, +0x18, 0x62, 0x60, 0x80, 0xe7, 0xcb, 0xb9, 0x18, +0x27, 0x86, 0xc1, 0xce, 0x6f, 0x1f, 0x26, 0x06, +0x7e, 0x2b, 0xfe, 0xf5, 0x01, 0xf2, 0x14, 0x08, +0x1f, 0x7b, 0x89, 0xff, 0x76, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *column_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_column_png = new wxImage(); + if (!img_column_png || !img_column_png->IsOk()) + { + wxMemoryInputStream img_column_pngIS(column_png_data, sizeof(column_png_data)); + img_column_png->LoadFile(img_column_pngIS, wxBITMAP_TYPE_PNG); + } + return img_column_png; +} +#define column_png_img column_png_img() + +static wxBitmap *column_png_bmp() +{ + static wxBitmap *bmp_column_png; + if (!bmp_column_png || !bmp_column_png->IsOk()) + bmp_column_png = new wxBitmap(*column_png_img); + return bmp_column_png; +} +#define column_png_bmp column_png_bmp() + +static wxIcon *column_png_ico() +{ + static wxIcon *ico_column_png; + if (!ico_column_png || !ico_column_png->IsOk()) + { + ico_column_png = new wxIcon(); + ico_column_png->CopyFromBitmap(*column_png_bmp); + } + return ico_column_png; +} +#define column_png_ico column_png_ico() + +#endif // COLUMN_PNG_H diff --git a/include/images/columns.png b/include/images/columns.png new file mode 100644 index 0000000..89d7588 Binary files /dev/null and b/include/images/columns.png differ diff --git a/include/images/columns.pngc b/include/images/columns.pngc new file mode 100644 index 0000000..ce488b6 --- /dev/null +++ b/include/images/columns.pngc @@ -0,0 +1,94 @@ +#ifndef COLUMNS_PNG_H +#define COLUMNS_PNG_H + +static const unsigned char columns_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x57, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x90, +0xca, 0xf3, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, 0xdd, +0xe5, 0xe5, 0xe5, 0xe6, 0xe6, 0xe6, 0x87, 0xbf, +0xe7, 0x63, 0x9d, 0xc7, 0xde, 0xde, 0xde, 0xe1, +0xe1, 0xe1, 0xa6, 0xa6, 0xa6, 0xec, 0xec, 0xec, +0xae, 0xae, 0xae, 0xe9, 0xe9, 0xe9, 0xa9, 0xa9, +0xa9, 0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, +0xea, 0xea, 0xe7, 0xe7, 0xe7, 0xe0, 0xe0, 0xe0, +0xeb, 0xeb, 0xeb, 0xf0, 0xf0, 0xf0, 0xf6, 0xf6, +0xf6, 0xb8, 0xb8, 0xb8, 0xb0, 0xb0, 0xb0, 0xb1, +0xb1, 0xb1, 0xf7, 0xf7, 0xf7, 0xed, 0xed, 0xed, +0x74, 0x6f, 0xc2, 0x89, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x70, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x5d, 0xcf, 0x47, 0x16, 0x80, 0x20, 0x0c, 0x45, +0xd1, 0x44, 0xb1, 0xa1, 0x06, 0x3b, 0x58, 0xf6, +0xbf, 0x4e, 0x13, 0x0e, 0x60, 0xf9, 0xc3, 0x77, +0xee, 0x20, 0x01, 0x00, 0x40, 0xbf, 0x0c, 0xe2, +0x30, 0x57, 0xaa, 0x28, 0x2b, 0x7c, 0x82, 0xaa, +0xbf, 0x06, 0xd5, 0xcf, 0x60, 0x93, 0x4c, 0x08, +0xfa, 0x67, 0x38, 0xb0, 0x69, 0xcb, 0xae, 0xa7, +0x14, 0xd8, 0xb4, 0x66, 0x18, 0xa7, 0x10, 0x66, +0x31, 0x8b, 0x26, 0xad, 0x43, 0x20, 0x31, 0x86, +0xc8, 0xc4, 0xb0, 0x8a, 0x31, 0xbc, 0x10, 0x32, +0x14, 0xe3, 0x97, 0x2e, 0x61, 0x33, 0x6e, 0xd6, +0xd9, 0x18, 0xc4, 0xec, 0x87, 0x73, 0xe7, 0xeb, +0x9f, 0xb5, 0xbb, 0xec, 0xf9, 0x0a, 0x90, 0x4e, +0xbf, 0x01, 0xeb, 0x8f, 0x04, 0xc4, 0x21, 0x83, +0x70, 0xec, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *columns_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_columns_png = new wxImage(); + if (!img_columns_png || !img_columns_png->IsOk()) + { + wxMemoryInputStream img_columns_pngIS(columns_png_data, sizeof(columns_png_data)); + img_columns_png->LoadFile(img_columns_pngIS, wxBITMAP_TYPE_PNG); + } + return img_columns_png; +} +#define columns_png_img columns_png_img() + +static wxBitmap *columns_png_bmp() +{ + static wxBitmap *bmp_columns_png; + if (!bmp_columns_png || !bmp_columns_png->IsOk()) + bmp_columns_png = new wxBitmap(*columns_png_img); + return bmp_columns_png; +} +#define columns_png_bmp columns_png_bmp() + +static wxIcon *columns_png_ico() +{ + static wxIcon *ico_columns_png; + if (!ico_columns_png || !ico_columns_png->IsOk()) + { + ico_columns_png = new wxIcon(); + ico_columns_png->CopyFromBitmap(*columns_png_bmp); + } + return ico_columns_png; +} +#define columns_png_ico columns_png_ico() + +#endif // COLUMNS_PNG_H diff --git a/include/images/configuration.png b/include/images/configuration.png new file mode 100644 index 0000000..0a5caf5 Binary files /dev/null and b/include/images/configuration.png differ diff --git a/include/images/configuration.pngc b/include/images/configuration.pngc new file mode 100644 index 0000000..238c219 --- /dev/null +++ b/include/images/configuration.pngc @@ -0,0 +1,88 @@ +#ifndef CONFIGURATION_PNG_H +#define CONFIGURATION_PNG_H + +static const unsigned char configuration_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x8e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x05, +0x96, 0xd7, 0x25, 0x4e, 0x46, 0xe6, 0x4f, 0x9c, +0x79, 0xf6, 0x67, 0xe3, 0x4e, 0x24, 0xf9, 0x99, +0x4f, 0xff, 0xf6, 0x4f, 0x66, 0x40, 0x88, 0xd4, +0x9d, 0xfb, 0xff, 0x37, 0xfe, 0xf2, 0xe4, 0x46, +0xb8, 0xae, 0xc4, 0x9f, 0xbf, 0xbe, 0xf5, 0xc7, +0xf7, 0xff, 0x4c, 0x84, 0xf2, 0xfb, 0x62, 0x7e, +0xbf, 0x7b, 0x7c, 0xef, 0xe6, 0xf9, 0x93, 0x75, +0x70, 0xfe, 0xdb, 0x1b, 0xa7, 0x77, 0x6e, 0x38, +0x3a, 0x73, 0x39, 0x94, 0xff, 0xeb, 0xc5, 0xb5, +0xd3, 0xe7, 0x2e, 0x1c, 0x98, 0x39, 0x11, 0xca, +0xff, 0xf9, 0xe4, 0xc2, 0xd1, 0x7b, 0x31, 0x89, +0x75, 0x10, 0xf9, 0x35, 0x31, 0x7f, 0x9e, 0x9d, +0xdd, 0x7f, 0x27, 0xa6, 0x0f, 0x66, 0x41, 0xd5, +0xf5, 0x95, 0x0b, 0x4e, 0xdc, 0x44, 0xf0, 0x41, +0x02, 0x4b, 0xde, 0x22, 0xf1, 0x19, 0xd6, 0x54, +0x5d, 0xbf, 0x8e, 0xcc, 0x07, 0x89, 0x54, 0xad, +0x61, 0xc0, 0x0d, 0x00, 0xc6, 0xd2, 0x4b, 0xda, +0x00, 0x56, 0x73, 0xbe, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *configuration_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_configuration_png = new wxImage(); + if (!img_configuration_png || !img_configuration_png->IsOk()) + { + wxMemoryInputStream img_configuration_pngIS(configuration_png_data, sizeof(configuration_png_data)); + img_configuration_png->LoadFile(img_configuration_pngIS, wxBITMAP_TYPE_PNG); + } + return img_configuration_png; +} +#define configuration_png_img configuration_png_img() + +static wxBitmap *configuration_png_bmp() +{ + static wxBitmap *bmp_configuration_png; + if (!bmp_configuration_png || !bmp_configuration_png->IsOk()) + bmp_configuration_png = new wxBitmap(*configuration_png_img); + return bmp_configuration_png; +} +#define configuration_png_bmp configuration_png_bmp() + +static wxIcon *configuration_png_ico() +{ + static wxIcon *ico_configuration_png; + if (!ico_configuration_png || !ico_configuration_png->IsOk()) + { + ico_configuration_png = new wxIcon(); + ico_configuration_png->CopyFromBitmap(*configuration_png_bmp); + } + return ico_configuration_png; +} +#define configuration_png_ico configuration_png_ico() + +#endif // CONFIGURATION_PNG_H diff --git a/include/images/configurations.png b/include/images/configurations.png new file mode 100644 index 0000000..01bf4ee Binary files /dev/null and b/include/images/configurations.png differ diff --git a/include/images/configurations.pngc b/include/images/configurations.pngc new file mode 100644 index 0000000..8e30d1f --- /dev/null +++ b/include/images/configurations.pngc @@ -0,0 +1,91 @@ +#ifndef CONFIGURATIONS_PNG_H +#define CONFIGURATIONS_PNG_H + +static const unsigned char configurations_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa5, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, 0x81, +0x09, 0x71, 0x31, 0xf1, 0x13, 0x19, 0x10, 0x60, +0xf9, 0xcc, 0x2b, 0x8f, 0x7f, 0xc7, 0x23, 0x09, +0xd4, 0x1d, 0xbc, 0xbd, 0x28, 0x26, 0x26, 0xa6, +0x18, 0x2e, 0x90, 0xf8, 0xe9, 0x10, 0x48, 0x4d, +0x0c, 0x8c, 0xdf, 0x17, 0xf3, 0xaf, 0x1d, 0x59, +0x4d, 0x5f, 0xcc, 0xdf, 0x8f, 0xc8, 0x6a, 0xfa, +0x62, 0xfe, 0xbc, 0xe9, 0x07, 0xab, 0xf9, 0x1f, +0x0f, 0xb2, 0x6b, 0x4d, 0xcc, 0xdf, 0xd7, 0x3d, +0x60, 0x35, 0xff, 0x7f, 0xf7, 0xc7, 0x03, 0xed, +0xaa, 0xba, 0xbe, 0xb2, 0x02, 0xa2, 0xe6, 0xeb, +0xcb, 0x87, 0x57, 0xee, 0xc5, 0x00, 0x05, 0xfa, +0xa1, 0x6a, 0x6e, 0x9f, 0xd9, 0xbe, 0xfa, 0x7a, +0x1c, 0xc3, 0x9a, 0x2a, 0xa8, 0x9a, 0xeb, 0xa7, +0x4e, 0x9f, 0xd9, 0x3f, 0x73, 0x02, 0x03, 0xc3, +0x9a, 0x14, 0xb0, 0x9a, 0x8b, 0x07, 0x6f, 0xc7, +0x24, 0xd6, 0x2d, 0x07, 0x59, 0x03, 0x56, 0xb3, +0xf0, 0xf8, 0xf5, 0x98, 0x3e, 0x98, 0xc3, 0x80, +0x6a, 0x56, 0x2e, 0x7e, 0x83, 0xe0, 0x83, 0xd4, +0x5c, 0xbf, 0x8e, 0xcc, 0x07, 0xeb, 0x5a, 0x03, +0x65, 0x02, 0x00, 0x3c, 0xaa, 0x70, 0x3b, 0x00, +0xf1, 0x5f, 0x61, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *configurations_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_configurations_png = new wxImage(); + if (!img_configurations_png || !img_configurations_png->IsOk()) + { + wxMemoryInputStream img_configurations_pngIS(configurations_png_data, sizeof(configurations_png_data)); + img_configurations_png->LoadFile(img_configurations_pngIS, wxBITMAP_TYPE_PNG); + } + return img_configurations_png; +} +#define configurations_png_img configurations_png_img() + +static wxBitmap *configurations_png_bmp() +{ + static wxBitmap *bmp_configurations_png; + if (!bmp_configurations_png || !bmp_configurations_png->IsOk()) + bmp_configurations_png = new wxBitmap(*configurations_png_img); + return bmp_configurations_png; +} +#define configurations_png_bmp configurations_png_bmp() + +static wxIcon *configurations_png_ico() +{ + static wxIcon *ico_configurations_png; + if (!ico_configurations_png || !ico_configurations_png->IsOk()) + { + ico_configurations_png = new wxIcon(); + ico_configurations_png->CopyFromBitmap(*configurations_png_bmp); + } + return ico_configurations_png; +} +#define configurations_png_ico configurations_png_ico() + +#endif // CONFIGURATIONS_PNG_H diff --git a/include/images/connect.png b/include/images/connect.png new file mode 100644 index 0000000..d999e1a Binary files /dev/null and b/include/images/connect.png differ diff --git a/include/images/connect.pngc b/include/images/connect.pngc new file mode 100644 index 0000000..e256f43 --- /dev/null +++ b/include/images/connect.pngc @@ -0,0 +1,129 @@ +#ifndef CONNECT_PNG_H +#define CONNECT_PNG_H + +static const unsigned char connect_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x00, 0xde, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa3, 0x8c, 0x13, 0xea, +0xdd, 0x4c, 0xe4, 0xca, 0x1b, 0x99, 0x99, 0x95, +0x6f, 0x6f, 0x6f, 0x8e, 0x8d, 0x8e, 0xa4, 0xa4, +0xa4, 0xba, 0xa0, 0x15, 0xb9, 0xb9, 0xba, 0xc6, +0xc6, 0xc6, 0x9f, 0x94, 0x4c, 0xc4, 0xc4, 0xc4, +0xbd, 0xbd, 0xbd, 0x86, 0x86, 0x84, 0x9e, 0x9e, +0x9e, 0xb2, 0xb2, 0xb2, 0xa4, 0xa4, 0xa3, 0xe9, +0xe9, 0xe9, 0x80, 0x80, 0x80, 0x99, 0x99, 0x99, +0x94, 0x94, 0x94, 0x84, 0x84, 0x83, 0x7f, 0x7f, +0x7f, 0xfb, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0x7e, +0x7e, 0x7e, 0x8b, 0x8b, 0x8b, 0x74, 0x74, 0x74, +0x67, 0x67, 0x67, 0xc8, 0xc7, 0xbf, 0xf1, 0xf1, +0xf1, 0xd7, 0xd7, 0xd7, 0x7b, 0x7b, 0x7b, 0x7a, +0x7a, 0x7a, 0x5d, 0x5d, 0x5d, 0x57, 0x57, 0x57, +0xa4, 0xa3, 0x9f, 0xb3, 0xb3, 0xb3, 0xe5, 0xe5, +0xe5, 0xbe, 0xbe, 0xbe, 0x78, 0x78, 0x78, 0x6b, +0x6b, 0x6b, 0x59, 0x59, 0x59, 0xdf, 0xdf, 0xdf, +0xc8, 0xc8, 0xc8, 0xba, 0xba, 0xba, 0xa7, 0xa7, +0xa7, 0x75, 0x75, 0x75, 0x62, 0x62, 0x62, 0x5f, +0x5f, 0x5f, 0x72, 0x72, 0x72, 0xf7, 0xf7, 0xf7, +0xae, 0xae, 0xae, 0xa5, 0xa5, 0xa5, 0x9c, 0x9c, +0x9c, 0x63, 0x63, 0x63, 0x70, 0x70, 0x70, 0xd4, +0xd4, 0xd4, 0xa2, 0xa2, 0xa2, 0xa0, 0xa0, 0xa0, +0xa8, 0xa8, 0xa8, 0xa6, 0xa6, 0xa6, 0x85, 0x85, +0x83, 0x95, 0x95, 0x91, 0x7c, 0x7c, 0x7c, 0xa9, +0xa9, 0xa9, 0x77, 0x77, 0x77, 0x9b, 0x9a, 0x97, +0x8a, 0x8a, 0x8a, 0x8d, 0x8d, 0x8d, 0xa1, 0xa1, +0xa1, 0x97, 0x97, 0x97, 0x92, 0x92, 0x92, 0x21, +0xbe, 0x8c, 0x41, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x19, 0xec, 0x6e, 0xb5, 0x88, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xef, 0x49, 0x44, +0x41, 0x54, 0x38, 0xcb, 0xa5, 0xd1, 0x69, 0x57, +0x82, 0x40, 0x18, 0x05, 0xe0, 0x19, 0xe0, 0x35, +0x72, 0x21, 0x51, 0x20, 0x2d, 0x41, 0x13, 0xb0, +0xdc, 0x17, 0x6c, 0x51, 0xca, 0xa5, 0xd0, 0xea, +0xff, 0xff, 0xa1, 0xde, 0x04, 0x3f, 0x74, 0x86, +0x19, 0x3c, 0x79, 0xbf, 0x3e, 0xf7, 0xcc, 0xdc, +0x39, 0x43, 0xc8, 0x7f, 0x42, 0x29, 0x15, 0xbb, +0x24, 0xd3, 0x0c, 0x97, 0x38, 0x05, 0x05, 0x40, +0x11, 0x7b, 0xee, 0x02, 0x8e, 0x4e, 0x55, 0xb6, +0x85, 0x7e, 0x99, 0x87, 0x42, 0xec, 0x92, 0xac, +0xb2, 0x05, 0xf4, 0x62, 0x09, 0x28, 0x77, 0x87, +0x06, 0x57, 0xc5, 0x52, 0x59, 0xe7, 0xee, 0x50, +0xa0, 0x52, 0x35, 0xca, 0xba, 0x69, 0x01, 0xc7, +0xaf, 0x6b, 0xf5, 0xca, 0xcd, 0xad, 0x69, 0x35, +0xec, 0x64, 0xc7, 0xdf, 0x38, 0xe8, 0xb5, 0x66, +0xeb, 0xae, 0xdd, 0xb0, 0x5d, 0x0f, 0x52, 0xde, +0xe9, 0x77, 0xd0, 0xef, 0x5b, 0x0f, 0xdd, 0x9e, +0xeb, 0x79, 0x7d, 0xdc, 0xc1, 0x2c, 0x1c, 0xfc, +0xfa, 0x70, 0x34, 0x9e, 0x4c, 0xbd, 0xfe, 0xcc, +0x06, 0xa6, 0x10, 0xcc, 0x0f, 0xfe, 0xf8, 0xf4, +0x3c, 0x79, 0x99, 0xd9, 0x0b, 0xb6, 0xa0, 0x2d, +0x63, 0x0f, 0xc3, 0x57, 0x40, 0x67, 0xaf, 0xf0, +0xdf, 0x12, 0x5f, 0xc1, 0x1a, 0x52, 0x9c, 0x6c, +0xb6, 0xef, 0xb1, 0x7f, 0xa4, 0x20, 0x26, 0x0a, +0x76, 0xdd, 0xbd, 0xf1, 0xf9, 0xb5, 0xe3, 0xfa, +0x77, 0xb0, 0xf1, 0xb5, 0x40, 0xf3, 0x9d, 0xf4, +0x9f, 0x46, 0x8f, 0x88, 0x28, 0x58, 0x20, 0x59, +0x05, 0xf1, 0x09, 0xd1, 0x29, 0x47, 0x9c, 0x57, +0xc8, 0xba, 0x22, 0xca, 0x1a, 0x79, 0xc2, 0x23, +0xc4, 0x7e, 0x56, 0x7e, 0x00, 0x2d, 0x10, 0x1f, +0x97, 0xe1, 0x47, 0xe8, 0x86, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *connect_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_connect_png = new wxImage(); + if (!img_connect_png || !img_connect_png->IsOk()) + { + wxMemoryInputStream img_connect_pngIS(connect_png_data, sizeof(connect_png_data)); + img_connect_png->LoadFile(img_connect_pngIS, wxBITMAP_TYPE_PNG); + } + return img_connect_png; +} +#define connect_png_img connect_png_img() + +static wxBitmap *connect_png_bmp() +{ + static wxBitmap *bmp_connect_png; + if (!bmp_connect_png || !bmp_connect_png->IsOk()) + bmp_connect_png = new wxBitmap(*connect_png_img); + return bmp_connect_png; +} +#define connect_png_bmp connect_png_bmp() + +static wxIcon *connect_png_ico() +{ + static wxIcon *ico_connect_png; + if (!ico_connect_png || !ico_connect_png->IsOk()) + { + ico_connect_png = new wxIcon(); + ico_connect_png->CopyFromBitmap(*connect_png_bmp); + } + return ico_connect_png; +} +#define connect_png_ico connect_png_ico() + +#endif // CONNECT_PNG_H diff --git a/include/images/constraints.png b/include/images/constraints.png new file mode 100644 index 0000000..d62e137 Binary files /dev/null and b/include/images/constraints.png differ diff --git a/include/images/constraints.pngc b/include/images/constraints.pngc new file mode 100644 index 0000000..8d6ef67 --- /dev/null +++ b/include/images/constraints.pngc @@ -0,0 +1,84 @@ +#ifndef CONSTRAINTS_PNG_H +#define CONSTRAINTS_PNG_H + +static const unsigned char constraints_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x24, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd9, 0x8c, 0x75, 0xbf, +0x3c, 0x14, 0xe7, 0xbc, 0x9c, 0xe7, 0xa3, 0x81, +0xe7, 0xb2, 0x91, 0xe6, 0x92, 0x6e, 0xe6, 0x7f, +0x5a, 0xe6, 0x6d, 0x45, 0xe6, 0x5c, 0x32, 0xe6, +0x4d, 0x23, 0xe6, 0x43, 0x18, 0x79, 0x60, 0x69, +0x5c, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x4d, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, +0x04, 0x02, 0x50, 0x9a, 0x49, 0x11, 0x4c, 0x02, +0x91, 0x11, 0x48, 0x48, 0x45, 0x81, 0x81, 0xc9, +0x14, 0x28, 0xc4, 0xe4, 0x06, 0x64, 0x84, 0x24, +0x09, 0x30, 0xa8, 0xa4, 0x03, 0x19, 0x6e, 0x15, +0x0a, 0x20, 0xcc, 0xc0, 0x94, 0xde, 0xc4, 0xc0, +0xa8, 0xde, 0x09, 0x64, 0x00, 0x39, 0x0c, 0x42, +0xb3, 0x80, 0x8c, 0x26, 0xa0, 0x26, 0x46, 0x6d, +0x05, 0x06, 0x46, 0x05, 0x90, 0x39, 0x42, 0x02, +0x0c, 0x44, 0x00, 0x00, 0x90, 0x88, 0x08, 0xe6, +0x43, 0x37, 0xa6, 0x7a, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *constraints_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_constraints_png = new wxImage(); + if (!img_constraints_png || !img_constraints_png->IsOk()) + { + wxMemoryInputStream img_constraints_pngIS(constraints_png_data, sizeof(constraints_png_data)); + img_constraints_png->LoadFile(img_constraints_pngIS, wxBITMAP_TYPE_PNG); + } + return img_constraints_png; +} +#define constraints_png_img constraints_png_img() + +static wxBitmap *constraints_png_bmp() +{ + static wxBitmap *bmp_constraints_png; + if (!bmp_constraints_png || !bmp_constraints_png->IsOk()) + bmp_constraints_png = new wxBitmap(*constraints_png_img); + return bmp_constraints_png; +} +#define constraints_png_bmp constraints_png_bmp() + +static wxIcon *constraints_png_ico() +{ + static wxIcon *ico_constraints_png; + if (!ico_constraints_png || !ico_constraints_png->IsOk()) + { + ico_constraints_png = new wxIcon(); + ico_constraints_png->CopyFromBitmap(*constraints_png_bmp); + } + return ico_constraints_png; +} +#define constraints_png_ico constraints_png_ico() + +#endif // CONSTRAINTS_PNG_H diff --git a/include/images/continue.png b/include/images/continue.png new file mode 100644 index 0000000..2421546 Binary files /dev/null and b/include/images/continue.png differ diff --git a/include/images/continue.pngc b/include/images/continue.pngc new file mode 100644 index 0000000..4c07f7f --- /dev/null +++ b/include/images/continue.pngc @@ -0,0 +1,95 @@ +#ifndef CONTINUE_PNG_H +#define CONTINUE_PNG_H + +static const unsigned char continue_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0xaf, 0xcc, 0x63, +0xaf, 0xcc, 0x64, 0xa9, 0xc8, 0x56, 0x94, 0xbb, +0x2f, 0xb1, 0xcd, 0x69, 0xaa, 0xc8, 0x5a, 0x8e, +0xb7, 0x26, 0x97, 0xbc, 0x38, 0xb4, 0xcf, 0x70, +0xab, 0xc9, 0x5e, 0x90, 0xb8, 0x2c, 0x92, 0xb9, +0x31, 0x9b, 0xbf, 0x43, 0xb6, 0xd1, 0x78, 0xad, +0xcb, 0x62, 0x92, 0xba, 0x33, 0x94, 0xbb, 0x38, +0x96, 0xbc, 0x3d, 0xa5, 0xc5, 0x5a, 0xcc, 0xdf, +0xa3, 0xae, 0xcb, 0x67, 0x95, 0xbb, 0x39, 0x96, +0xbd, 0x3e, 0x9e, 0xc2, 0x4f, 0xba, 0xd3, 0x81, +0xb0, 0xcd, 0x6c, 0x97, 0xbd, 0x40, 0x9f, 0xc2, +0x51, 0xba, 0xd3, 0x83, 0xb2, 0xce, 0x71, 0x9f, +0xc3, 0x53, 0xba, 0xd4, 0x83, 0xba, 0xd4, 0x85, +0xce, 0xe0, 0xa7, 0x9d, 0xfc, 0x84, 0xf4, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x57, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x06, 0x18, +0x99, 0x18, 0x51, 0x05, 0x98, 0x98, 0xd1, 0x44, +0x98, 0x58, 0x58, 0x51, 0x45, 0x98, 0xd8, 0xd8, +0x39, 0x50, 0x44, 0x98, 0x38, 0xb9, 0xb8, 0x79, +0x90, 0x45, 0x98, 0x78, 0xf9, 0xf8, 0x05, 0x04, +0x91, 0x44, 0x98, 0x84, 0x84, 0x45, 0x44, 0xc5, +0xc4, 0x99, 0x10, 0x02, 0x12, 0x92, 0x52, 0xd2, +0x32, 0xc8, 0x2a, 0x64, 0xe5, 0xe4, 0x15, 0x50, +0xcc, 0x50, 0x54, 0x52, 0x46, 0xb5, 0x45, 0x46, +0x05, 0xcd, 0x1d, 0xaa, 0x68, 0x2e, 0xc5, 0xf0, +0x0b, 0x5e, 0x00, 0x00, 0x89, 0x7c, 0x03, 0x17, +0x05, 0x8e, 0xad, 0x66, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *continue_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_continue_png = new wxImage(); + if (!img_continue_png || !img_continue_png->IsOk()) + { + wxMemoryInputStream img_continue_pngIS(continue_png_data, sizeof(continue_png_data)); + img_continue_png->LoadFile(img_continue_pngIS, wxBITMAP_TYPE_PNG); + } + return img_continue_png; +} +#define continue_png_img continue_png_img() + +static wxBitmap *continue_png_bmp() +{ + static wxBitmap *bmp_continue_png; + if (!bmp_continue_png || !bmp_continue_png->IsOk()) + bmp_continue_png = new wxBitmap(*continue_png_img); + return bmp_continue_png; +} +#define continue_png_bmp continue_png_bmp() + +static wxIcon *continue_png_ico() +{ + static wxIcon *ico_continue_png; + if (!ico_continue_png || !ico_continue_png->IsOk()) + { + ico_continue_png = new wxIcon(); + ico_continue_png->CopyFromBitmap(*continue_png_bmp); + } + return ico_continue_png; +} +#define continue_png_ico continue_png_ico() + +#endif // CONTINUE_PNG_H diff --git a/include/images/conversion.png b/include/images/conversion.png new file mode 100644 index 0000000..3dee54c Binary files /dev/null and b/include/images/conversion.png differ diff --git a/include/images/conversion.pngc b/include/images/conversion.pngc new file mode 100644 index 0000000..68ac94e --- /dev/null +++ b/include/images/conversion.pngc @@ -0,0 +1,89 @@ +#ifndef CONVERSION_PNG_H +#define CONVERSION_PNG_H + +static const unsigned char conversion_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb2, 0xca, 0x8c, 0x7c, +0xa5, 0x3c, 0x9a, 0xcb, 0x4d, 0xa2, 0xd3, 0x55, +0xad, 0xde, 0x60, 0xb9, 0xea, 0x6c, 0xc6, 0xf7, +0x79, 0xd4, 0xff, 0x8f, 0xca, 0xda, 0xaf, 0xa5, +0xc1, 0x78, 0xd9, 0xb7, 0xe3, 0xbf, 0x86, 0xcf, +0xa2, 0x4f, 0xba, 0xd7, 0x8b, 0xff, 0xc8, 0x97, +0xd6, 0xdb, 0x96, 0xff, 0xe0, 0xa6, 0xff, 0xe6, +0xb8, 0xff, 0xed, 0xca, 0xff, 0xf2, 0xda, 0xff, +0xff, 0xe9, 0xeb, 0xf3, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x5c, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x5d, 0xce, 0x41, 0x12, 0x80, 0x20, 0x0c, 0x43, +0x51, 0xa8, 0xa0, 0x22, 0xd6, 0x2a, 0x78, 0xff, +0xb3, 0x1a, 0x81, 0x19, 0x5b, 0xff, 0x2a, 0xf3, +0x56, 0x71, 0xae, 0xe7, 0xc9, 0x3b, 0x13, 0x4d, +0x3f, 0xa1, 0x10, 0xac, 0x50, 0x8c, 0x71, 0x88, +0xa7, 0xd6, 0x8c, 0xba, 0xd0, 0xf2, 0xd5, 0x84, +0x56, 0x15, 0x01, 0xd2, 0xa6, 0x4a, 0x80, 0xbc, +0xab, 0x32, 0x80, 0x0f, 0x15, 0x03, 0x84, 0xcf, +0xaf, 0x17, 0x20, 0x17, 0xe2, 0x96, 0xb8, 0x2e, +0xa5, 0x14, 0xd6, 0x37, 0x85, 0x6b, 0x35, 0x00, +0xb9, 0x2d, 0x40, 0x64, 0xac, 0x07, 0x67, 0xec, +0x05, 0xaa, 0xfc, 0x18, 0x5a, 0xb1, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *conversion_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_conversion_png = new wxImage(); + if (!img_conversion_png || !img_conversion_png->IsOk()) + { + wxMemoryInputStream img_conversion_pngIS(conversion_png_data, sizeof(conversion_png_data)); + img_conversion_png->LoadFile(img_conversion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_conversion_png; +} +#define conversion_png_img conversion_png_img() + +static wxBitmap *conversion_png_bmp() +{ + static wxBitmap *bmp_conversion_png; + if (!bmp_conversion_png || !bmp_conversion_png->IsOk()) + bmp_conversion_png = new wxBitmap(*conversion_png_img); + return bmp_conversion_png; +} +#define conversion_png_bmp conversion_png_bmp() + +static wxIcon *conversion_png_ico() +{ + static wxIcon *ico_conversion_png; + if (!ico_conversion_png || !ico_conversion_png->IsOk()) + { + ico_conversion_png = new wxIcon(); + ico_conversion_png->CopyFromBitmap(*conversion_png_bmp); + } + return ico_conversion_png; +} +#define conversion_png_ico conversion_png_ico() + +#endif // CONVERSION_PNG_H diff --git a/include/images/conversions.png b/include/images/conversions.png new file mode 100644 index 0000000..29b94d8 Binary files /dev/null and b/include/images/conversions.png differ diff --git a/include/images/conversions.pngc b/include/images/conversions.pngc new file mode 100644 index 0000000..7ce4981 --- /dev/null +++ b/include/images/conversions.pngc @@ -0,0 +1,89 @@ +#ifndef CONVERSIONS_PNG_H +#define CONVERSIONS_PNG_H + +static const unsigned char conversions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb2, 0xca, 0x8c, 0x7c, +0xa5, 0x3c, 0x9a, 0xcb, 0x4d, 0xa7, 0xd8, 0x5a, +0x8e, 0xba, 0x48, 0x92, 0xb4, 0x5d, 0xb9, 0xea, +0x6c, 0xcd, 0xfe, 0x80, 0x92, 0x93, 0x71, 0x8f, +0x7a, 0x7b, 0x84, 0x93, 0x56, 0xa2, 0x4f, 0xba, +0xd7, 0x8b, 0xff, 0xc8, 0x97, 0xd6, 0x8f, 0x8b, +0x71, 0xb2, 0x6d, 0xc6, 0xdd, 0x9e, 0xff, 0xe6, +0xb8, 0xff, 0xf0, 0xd5, 0xff, 0x94, 0x69, 0x14, +0xaf, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0x8e, 0xd1, +0x0e, 0x80, 0x20, 0x08, 0x00, 0x91, 0x2c, 0xb3, +0x88, 0xd2, 0xfe, 0xff, 0x5f, 0x13, 0x83, 0x1a, +0xad, 0x7b, 0x62, 0xb7, 0x83, 0x01, 0x20, 0x04, +0x0c, 0xe0, 0xc0, 0xe1, 0x63, 0x30, 0x8e, 0x38, +0xe9, 0x1c, 0x50, 0x48, 0xad, 0x51, 0x83, 0x73, +0xe7, 0x6d, 0xf2, 0xb2, 0xfa, 0x86, 0xb6, 0xa7, +0x89, 0xfd, 0x32, 0xd3, 0x6e, 0x4d, 0x4a, 0x6a, +0xac, 0x91, 0x4c, 0x96, 0x8e, 0xd6, 0x18, 0x19, +0x6e, 0xb3, 0x19, 0x04, 0x6a, 0x4a, 0x29, 0x24, +0x30, 0x98, 0xa9, 0x95, 0xdc, 0xef, 0x4c, 0xa7, +0x17, 0xcd, 0x30, 0xfc, 0x73, 0x01, 0x03, 0x7c, +0x04, 0x5c, 0xa0, 0x38, 0xe9, 0xa3, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *conversions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_conversions_png = new wxImage(); + if (!img_conversions_png || !img_conversions_png->IsOk()) + { + wxMemoryInputStream img_conversions_pngIS(conversions_png_data, sizeof(conversions_png_data)); + img_conversions_png->LoadFile(img_conversions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_conversions_png; +} +#define conversions_png_img conversions_png_img() + +static wxBitmap *conversions_png_bmp() +{ + static wxBitmap *bmp_conversions_png; + if (!bmp_conversions_png || !bmp_conversions_png->IsOk()) + bmp_conversions_png = new wxBitmap(*conversions_png_img); + return bmp_conversions_png; +} +#define conversions_png_bmp conversions_png_bmp() + +static wxIcon *conversions_png_ico() +{ + static wxIcon *ico_conversions_png; + if (!ico_conversions_png || !ico_conversions_png->IsOk()) + { + ico_conversions_png = new wxIcon(); + ico_conversions_png->CopyFromBitmap(*conversions_png_bmp); + } + return ico_conversions_png; +} +#define conversions_png_ico conversions_png_ico() + +#endif // CONVERSIONS_PNG_H diff --git a/include/images/create.png b/include/images/create.png new file mode 100644 index 0000000..7621d22 Binary files /dev/null and b/include/images/create.png differ diff --git a/include/images/create.pngc b/include/images/create.pngc new file mode 100644 index 0000000..67ac2da --- /dev/null +++ b/include/images/create.pngc @@ -0,0 +1,172 @@ +#ifndef CREATE_PNG_H +#define CREATE_PNG_H + +static const unsigned char create_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x93, 0xb2, 0xbf, 0x64, +0x9b, 0xb7, 0xf8, 0xfb, 0xfb, 0xe5, 0xef, 0xf1, +0xe6, 0xf0, 0xf2, 0xe7, 0xf1, 0xf3, 0xe8, 0xf1, +0xf3, 0xe9, 0xf2, 0xf4, 0xea, 0xf2, 0xf4, 0xeb, +0xf3, 0xf5, 0xec, 0xf4, 0xf5, 0xee, 0xf5, 0xf6, +0xef, 0xf5, 0xf7, 0xfb, 0xfd, 0xfd, 0xce, 0xe2, +0xe6, 0xd0, 0xe3, 0xe7, 0xd2, 0xe4, 0xe8, 0xd4, +0xe5, 0xe9, 0xd6, 0xe6, 0xea, 0xd8, 0xe8, 0xeb, +0xdb, 0xe9, 0xec, 0xdd, 0xeb, 0xee, 0xdf, 0xec, +0xef, 0xe2, 0xee, 0xf0, 0xf1, 0xf7, 0xf8, 0xd0, +0xe3, 0xe9, 0xf3, 0xf8, 0xf9, 0x7e, 0xb5, 0xd0, +0x34, 0x8b, 0xb7, 0x80, 0xb6, 0xd0, 0xf4, 0xf8, +0xf9, 0x77, 0xb1, 0xcc, 0x64, 0xa7, 0xc8, 0xee, +0xf5, 0xfa, 0xb2, 0xd3, 0xe1, 0xf5, 0xf9, 0xfa, +0xd3, 0xe6, 0xf7, 0xde, 0xec, 0xf9, 0xa9, 0xcd, +0xde, 0xf7, 0xfa, 0xfb, 0xd6, 0xe9, 0xf9, 0x7a, +0xb3, 0xcf, 0x2c, 0x87, 0xb5, 0x6b, 0xab, 0xcb, +0xe8, 0xf2, 0xf6, 0xb3, 0xd2, 0xdf, 0x5e, 0x9d, +0xbd, 0xe5, 0xf1, 0xf8, 0xb9, 0xd7, 0xe8, 0x90, +0xc0, 0xd8, 0xd7, 0xe7, 0xec, 0xc5, 0xde, 0xeb, +0xb6, 0xd6, 0xe8, 0xb3, 0xd6, 0xf5, 0xa0, 0xcd, +0xf2, 0xc5, 0xe2, 0xf5, 0x8c, 0xbe, 0xd7, 0x46, +0x90, 0xb5, 0x27, 0x84, 0xb3, 0x99, 0xca, 0xf1, +0x9d, 0xcd, 0xf2, 0xcd, 0xe5, 0xf5, 0x50, 0x97, +0xbb, 0x98, 0xb8, 0xc3, 0x85, 0xaf, 0xc0, 0x3e, +0x8e, 0xb6, 0xb6, 0xd6, 0xe6, 0xc2, 0xdf, 0xf7, +0xc3, 0xe0, 0xf5, 0x83, 0xb9, 0xd3, 0x72, 0xaf, +0xce, 0x6f, 0xa5, 0xbd, 0xc8, 0xce, 0xc9, 0x40, +0x92, 0xbc, 0xe3, 0xef, 0xf5, 0xbb, 0xd8, 0xe4, +0x36, 0x8d, 0xb8, 0xae, 0xd5, 0xf4, 0xcc, 0xe7, +0xf8, 0xb4, 0xda, 0xee, 0xca, 0xe8, 0xf7, 0xb2, +0xd5, 0xe7, 0xa0, 0xd2, 0xf1, 0x86, 0xc7, 0xee, +0xa9, 0xda, 0xf1, 0x79, 0xc6, 0xea, 0xae, 0xdd, +0xf2, 0x7f, 0xc3, 0xec, 0x76, 0xc0, 0xeb, 0x7b, +0xc2, 0xea, 0xa5, 0xd6, 0xf1, 0x5c, 0xba, 0xe5, +0xd2, 0xd2, 0xcb, 0xb3, 0xdb, 0xf4, 0x71, 0xbf, +0xea, 0x6c, 0xbe, 0xe9, 0x73, 0xc1, 0xea, 0x8e, +0xce, 0xed, 0x8c, 0xcb, 0xec, 0x55, 0xb8, 0xe5, +0xa9, 0xc0, 0xc5, 0x65, 0xbc, 0xe8, 0x62, 0xbb, +0xe6, 0x52, 0xb7, 0xe4, 0xa5, 0xdb, 0xf0, 0x7c, +0xab, 0xbf, 0xc0, 0xe0, 0xf2, 0x85, 0xc9, 0xeb, +0x59, 0xb9, 0xe5, 0x4e, 0xb6, 0xe3, 0xba, 0xde, +0xf1, 0x4a, 0xb5, 0xe2, 0xa2, 0xd9, 0xf0, 0x47, +0xb5, 0xe1, 0x75, 0xc4, 0xe9, 0x44, 0xb3, 0xe1, +0xa0, 0xd9, 0xef, 0x51, 0xb8, 0xe3, 0x41, 0xb3, +0xe0, 0x9e, 0xd8, 0xef, 0x3e, 0xb2, 0xe0, 0xe5, +0xf5, 0xfb, 0xf9, 0xfb, 0xfc, 0xf9, 0xfc, 0xfc, +0xfb, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff, 0xff, +0xff, 0xcd, 0x71, 0x5a, 0x78, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x7f, 0x48, 0xbf, 0x71, 0xe5, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x01, 0xa7, +0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x85, 0x93, +0xf9, 0x37, 0x02, 0x51, 0x14, 0xc7, 0x53, 0xd3, +0x68, 0x4c, 0x93, 0x2d, 0x94, 0x90, 0x51, 0x14, +0x59, 0xb3, 0x55, 0xaf, 0xa2, 0xb2, 0x64, 0x19, +0x84, 0xa9, 0x30, 0x08, 0xd1, 0x62, 0xcd, 0xd6, +0xd0, 0xe2, 0x5f, 0xf7, 0xa6, 0x39, 0x42, 0xdd, +0x73, 0xba, 0x3f, 0xbe, 0xcf, 0xe7, 0x2d, 0xf7, +0x7c, 0xef, 0x53, 0x28, 0x1a, 0x56, 0x93, 0xf2, +0x6f, 0x35, 0xd5, 0x0b, 0x4a, 0x15, 0xa1, 0x56, +0x93, 0xcd, 0x1a, 0xaa, 0x85, 0xd6, 0x32, 0x3a, +0x25, 0x20, 0x10, 0xad, 0xad, 0x6d, 0xed, 0x1d, +0x9d, 0xfa, 0xae, 0xee, 0x1e, 0x83, 0x11, 0x12, +0xd4, 0x32, 0xef, 0xc5, 0x9c, 0x30, 0x81, 0x42, +0x85, 0xf7, 0xf5, 0x0f, 0x18, 0x08, 0xd2, 0x0c, +0x09, 0xa4, 0xc4, 0x07, 0xd9, 0x21, 0xd6, 0x42, +0x52, 0x56, 0x48, 0x68, 0xae, 0xf0, 0xe1, 0x11, +0xd6, 0x62, 0xa3, 0xed, 0x90, 0xa0, 0xa9, 0xf0, +0x51, 0x76, 0xcc, 0x31, 0x3e, 0x36, 0x01, 0x09, +0x94, 0x7e, 0x72, 0x6a, 0x5a, 0xe2, 0x33, 0xa3, +0xce, 0x3e, 0x48, 0x68, 0xe9, 0x9a, 0x75, 0xcc, +0x61, 0x3e, 0xbf, 0xb0, 0xe8, 0x72, 0x7b, 0x00, +0x81, 0xee, 0xee, 0xb1, 0x21, 0x1b, 0xe6, 0x5e, +0x9f, 0x9f, 0x5d, 0x5a, 0x96, 0x57, 0x03, 0xc1, +0x40, 0x55, 0xd0, 0xe2, 0xfe, 0x0d, 0xe3, 0xa1, +0x15, 0xaf, 0x6f, 0x95, 0x5d, 0x73, 0xac, 0x87, +0x37, 0x24, 0xbe, 0xb9, 0x15, 0xac, 0x0a, 0x0c, +0xee, 0x9f, 0xda, 0xe6, 0xfc, 0x3b, 0x2e, 0xcc, +0x43, 0xbb, 0x4e, 0x6c, 0x04, 0x36, 0xf7, 0x22, +0xa8, 0x2a, 0xe8, 0x8c, 0x26, 0xb3, 0xd5, 0xee, +0xe6, 0xa6, 0x31, 0xdf, 0x3f, 0x38, 0xe4, 0x9d, +0x61, 0xcc, 0xa3, 0xb1, 0xaa, 0xf0, 0x93, 0xa6, +0xc7, 0xe1, 0xc1, 0x3c, 0x7e, 0x74, 0x7c, 0xe2, +0xc6, 0x5c, 0xe0, 0x51, 0xdd, 0x6b, 0x4f, 0xa7, +0x42, 0x67, 0xf1, 0xa3, 0xf3, 0xc4, 0xc5, 0xe5, +0x55, 0x54, 0x48, 0xf2, 0xa8, 0x3e, 0xfd, 0x6b, +0xce, 0x75, 0x75, 0x91, 0x48, 0xdc, 0xa4, 0x52, +0x42, 0x32, 0x9d, 0x41, 0x40, 0xfa, 0x59, 0xee, +0xf6, 0x0e, 0x73, 0xe1, 0x3e, 0x99, 0x7e, 0xc8, +0x20, 0x28, 0xfd, 0x2c, 0xf7, 0x18, 0x95, 0xf9, +0x53, 0x0e, 0x81, 0xe9, 0x67, 0x97, 0xee, 0x64, +0xfe, 0x9c, 0x43, 0x50, 0xfa, 0xb8, 0xbf, 0x17, +0x99, 0xbf, 0xbe, 0x21, 0xa2, 0x3e, 0x7d, 0xa9, +0x7f, 0x21, 0xf9, 0x2e, 0xf1, 0xbc, 0x88, 0x48, +0xaa, 0x36, 0x7d, 0x99, 0x57, 0xf6, 0xe7, 0x3f, +0x44, 0x44, 0xd1, 0x8c, 0xea, 0xbf, 0x10, 0xdc, +0x8a, 0xc4, 0x78, 0x3e, 0x93, 0xc9, 0xe5, 0xde, +0x44, 0xf1, 0x13, 0xd1, 0x8c, 0xb1, 0x50, 0x73, +0x42, 0x10, 0xfd, 0xa9, 0x41, 0xc6, 0x68, 0x2a, +0x42, 0xe3, 0x41, 0x4b, 0xd3, 0x8d, 0xef, 0xc7, +0xdc, 0x5a, 0x82, 0x04, 0xed, 0x2f, 0xb7, 0x83, +0xff, 0x88, 0xf9, 0xe5, 0xc5, 0x32, 0x24, 0xc8, +0xe9, 0xab, 0x0a, 0xc5, 0x92, 0xae, 0xfc, 0x05, +0x08, 0x0d, 0xff, 0x72, 0x6d, 0x7d, 0x03, 0xee, +0x6e, 0x60, 0xfa, 0x69, 0xf8, 0x5b, 0xbe, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *create_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_create_png = new wxImage(); + if (!img_create_png || !img_create_png->IsOk()) + { + wxMemoryInputStream img_create_pngIS(create_png_data, sizeof(create_png_data)); + img_create_png->LoadFile(img_create_pngIS, wxBITMAP_TYPE_PNG); + } + return img_create_png; +} +#define create_png_img create_png_img() + +static wxBitmap *create_png_bmp() +{ + static wxBitmap *bmp_create_png; + if (!bmp_create_png || !bmp_create_png->IsOk()) + bmp_create_png = new wxBitmap(*create_png_img); + return bmp_create_png; +} +#define create_png_bmp create_png_bmp() + +static wxIcon *create_png_ico() +{ + static wxIcon *ico_create_png; + if (!ico_create_png || !ico_create_png->IsOk()) + { + ico_create_png = new wxIcon(); + ico_create_png->CopyFromBitmap(*create_png_bmp); + } + return ico_create_png; +} +#define create_png_ico create_png_ico() + +#endif // CREATE_PNG_H diff --git a/include/images/database-sm.png b/include/images/database-sm.png new file mode 100644 index 0000000..347d2b4 Binary files /dev/null and b/include/images/database-sm.png differ diff --git a/include/images/database-sm.pngc b/include/images/database-sm.pngc new file mode 100644 index 0000000..b0ef86f --- /dev/null +++ b/include/images/database-sm.pngc @@ -0,0 +1,130 @@ +#ifndef DATABASE_SM_PNG_H +#define DATABASE_SM_PNG_H + +static const unsigned char database_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x41, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc9, 0xb8, 0x7a, 0xb9, +0xa3, 0x51, 0xaf, 0x96, 0x37, 0xb3, 0x9b, 0x42, +0xc0, 0xac, 0x62, 0xc2, 0xaf, 0x60, 0xd9, 0xcb, +0x91, 0xe8, 0xde, 0xac, 0xee, 0xea, 0xc0, 0xf1, +0xf0, 0xc0, 0xeb, 0xe8, 0xb0, 0xde, 0xd8, 0x97, +0xd0, 0xc6, 0x7b, 0xc2, 0xb6, 0x5f, 0xb3, 0x9e, +0x40, 0xc2, 0xaf, 0x64, 0xec, 0xe5, 0xc0, 0xff, +0xfd, 0xe7, 0xfd, 0xf9, 0xda, 0xf9, 0xf8, 0xd0, +0xf3, 0xf0, 0xc4, 0xee, 0xec, 0xb9, 0xe9, 0xe8, +0xb3, 0xe7, 0xe5, 0xaf, 0xe6, 0xe6, 0xb1, 0xd5, +0xca, 0x8f, 0xbd, 0xa9, 0x5b, 0xb8, 0xa3, 0x4f, +0xeb, 0xe3, 0xc3, 0xf4, 0xed, 0xcf, 0xf7, 0xf3, +0xd4, 0xf7, 0xf4, 0xd4, 0xf7, 0xf7, 0xdc, 0xf5, +0xf5, 0xda, 0xf3, 0xf1, 0xd7, 0xef, 0xed, 0xcf, +0xef, 0xee, 0xce, 0xe8, 0xdf, 0xbc, 0xb1, 0x99, +0x3e, 0xb7, 0xa0, 0x4c, 0xe9, 0xe0, 0xc6, 0xf5, +0xec, 0xda, 0xfb, 0xf4, 0xe5, 0xfb, 0xf3, 0xd5, +0xf5, 0xef, 0xc3, 0xee, 0xe6, 0xae, 0xe8, 0xe2, +0xa0, 0xe4, 0xe0, 0x9b, 0xe6, 0xe3, 0xa3, 0xde, +0xd5, 0x9b, 0xac, 0x92, 0x30, 0xea, 0xe1, 0xcb, +0xfa, 0xf1, 0xe8, 0xff, 0xf7, 0xef, 0xfe, 0xf4, +0xd3, 0xf3, 0xeb, 0xaf, 0xe7, 0xe0, 0x90, 0xe0, +0xda, 0x7e, 0xe0, 0xdb, 0x81, 0xe3, 0xe0, 0x95, +0xde, 0xd3, 0x97, 0xf9, 0xf1, 0xe8, 0xff, 0xf9, +0xef, 0xe8, 0xe1, 0x8f, 0xe1, 0xdb, 0x7d, 0xe3, +0xde, 0x95, 0xde, 0xd6, 0x97, 0xf9, 0xf2, 0xe8, +0xfe, 0xf3, 0xd3, 0xf1, 0xe8, 0xb0, 0xe8, 0xdf, +0x8f, 0xe1, 0xd9, 0x7e, 0xdf, 0xda, 0x81, 0xde, +0xd4, 0x97, 0xf3, 0xea, 0xaf, 0xe8, 0xe0, 0x8f, +0xe0, 0xda, 0x81, 0xe3, 0xdd, 0x96, 0xdf, 0xd6, +0x97, 0xfe, 0xf4, 0xd2, 0xe1, 0xda, 0x7d, 0xea, +0xe2, 0xcb, 0xf9, 0xf3, 0xe9, 0xf1, 0xe9, 0xb0, +0xe8, 0xe2, 0x8e, 0xdf, 0xd6, 0x96, 0xb2, 0x9a, +0x41, 0xdc, 0xcf, 0xa6, 0xfa, 0xf2, 0xe7, 0xff, +0xf8, 0xee, 0xf2, 0xea, 0xaf, 0xe7, 0xdf, 0x8f, +0xe0, 0xda, 0x7d, 0xe3, 0xde, 0x97, 0xc9, 0xbb, +0x6d, 0xb7, 0xa1, 0x4a, 0xcf, 0xbb, 0x7f, 0xe4, +0xd3, 0xa5, 0xec, 0xde, 0xb1, 0xeb, 0xe1, 0x9f, +0xdf, 0xd5, 0x81, 0xd3, 0xc8, 0x69, 0xca, 0xbb, +0x5e, 0xbd, 0xa9, 0x50, 0xaf, 0x98, 0x38, 0xc3, +0xb0, 0x6a, 0x3d, 0x1f, 0x33, 0xdd, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xa6, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xc0, 0x06, 0x18, 0x99, +0x98, 0x99, 0x99, 0x59, 0x58, 0xe1, 0x7c, 0x36, +0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, +0x7e, 0x08, 0x5f, 0x40, 0x50, 0x48, 0x58, 0x44, +0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, 0x1a, 0x2c, +0x20, 0x23, 0x2b, 0x27, 0xaf, 0xa0, 0xa8, 0xa4, +0xac, 0xa2, 0xaa, 0xa6, 0x0e, 0x16, 0xd0, 0xd0, +0xd4, 0xd2, 0xd6, 0xd1, 0xd5, 0xd3, 0x37, 0x30, +0x34, 0x32, 0x86, 0x08, 0x98, 0x98, 0x9a, 0x99, +0x5b, 0x58, 0x5a, 0x59, 0xdb, 0xd8, 0xc2, 0x04, +0xec, 0xec, 0xcd, 0x2d, 0x1c, 0x1c, 0xad, 0x9d, +0x9c, 0x61, 0x02, 0x2e, 0xf6, 0xae, 0x6e, 0xee, +0x1e, 0x9e, 0x4e, 0x5e, 0x08, 0x01, 0x73, 0x6f, +0x1f, 0x47, 0x5f, 0x3f, 0x7f, 0x84, 0x40, 0x80, +0xb7, 0x7b, 0xa0, 0xa7, 0x13, 0x4c, 0x20, 0x28, +0xd8, 0xde, 0x3c, 0x24, 0x14, 0x68, 0x46, 0x18, +0x44, 0x20, 0x3c, 0x22, 0x32, 0xca, 0x3c, 0x3a, +0x26, 0xd6, 0x33, 0x2e, 0x1e, 0x22, 0xc0, 0x90, +0x90, 0x98, 0x94, 0x9c, 0x92, 0x9a, 0x96, 0x9e, +0x91, 0x09, 0xf3, 0x4c, 0x16, 0x9a, 0xe7, 0x50, +0x00, 0x00, 0xa1, 0xfa, 0x1f, 0x30, 0xa5, 0xe6, +0x68, 0xa2, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *database_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_database_sm_png = new wxImage(); + if (!img_database_sm_png || !img_database_sm_png->IsOk()) + { + wxMemoryInputStream img_database_sm_pngIS(database_sm_png_data, sizeof(database_sm_png_data)); + img_database_sm_png->LoadFile(img_database_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_database_sm_png; +} +#define database_sm_png_img database_sm_png_img() + +static wxBitmap *database_sm_png_bmp() +{ + static wxBitmap *bmp_database_sm_png; + if (!bmp_database_sm_png || !bmp_database_sm_png->IsOk()) + bmp_database_sm_png = new wxBitmap(*database_sm_png_img); + return bmp_database_sm_png; +} +#define database_sm_png_bmp database_sm_png_bmp() + +static wxIcon *database_sm_png_ico() +{ + static wxIcon *ico_database_sm_png; + if (!ico_database_sm_png || !ico_database_sm_png->IsOk()) + { + ico_database_sm_png = new wxIcon(); + ico_database_sm_png->CopyFromBitmap(*database_sm_png_bmp); + } + return ico_database_sm_png; +} +#define database_sm_png_ico database_sm_png_ico() + +#endif // DATABASE_SM_PNG_H diff --git a/include/images/database.png b/include/images/database.png new file mode 100644 index 0000000..1a743d7 Binary files /dev/null and b/include/images/database.png differ diff --git a/include/images/database.pngc b/include/images/database.pngc new file mode 100644 index 0000000..8c12156 --- /dev/null +++ b/include/images/database.pngc @@ -0,0 +1,133 @@ +#ifndef DATABASE_PNG_H +#define DATABASE_PNG_H + +static const unsigned char database_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x35, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd3, 0xc5, 0x91, 0xc3, +0xb0, 0x6a, 0xb7, 0xa0, 0x4b, 0xaf, 0x96, 0x37, +0xb2, 0x9b, 0x3b, 0xc6, 0xb4, 0x69, 0xda, 0xcb, +0x8e, 0xe6, 0xdc, 0xa9, 0xed, 0xe8, 0xbd, 0xf2, +0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, 0xdf, 0xa2, +0xd6, 0xce, 0x88, 0xca, 0xbd, 0x6d, 0xbc, 0xad, +0x52, 0xaf, 0x98, 0x36, 0xc1, 0xad, 0x63, 0xdd, +0xd0, 0x99, 0xff, 0xfd, 0xee, 0xff, 0xfd, 0xe3, +0xfe, 0xf9, 0xd8, 0xf9, 0xf9, 0xd1, 0xf5, 0xf0, +0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, 0xb2, 0xe5, +0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, 0xdf, 0x9b, +0xc7, 0xbc, 0x6a, 0xb0, 0x98, 0x3b, 0xe9, 0xe1, +0xb7, 0xfc, 0xf9, 0xd9, 0xfa, 0xf7, 0xcf, 0xf4, +0xf4, 0xc7, 0xee, 0xee, 0xbe, 0xed, 0xed, 0xbb, +0xec, 0xe9, 0xbf, 0xed, 0xed, 0xca, 0xf4, 0xf4, +0xdb, 0xfc, 0xf9, 0xf2, 0xb8, 0xa2, 0x4e, 0xac, +0x92, 0x30, 0xe3, 0xdb, 0xbd, 0xe9, 0xdc, 0xb9, +0xed, 0xe3, 0xbb, 0xf5, 0xf0, 0xd4, 0xf5, 0xf2, +0xd9, 0xfb, 0xfb, 0xf1, 0xfe, 0xfe, 0xfb, 0xf7, +0xf4, 0xe8, 0xf0, 0xed, 0xd2, 0xec, 0xe9, 0xc4, +0xea, 0xe2, 0xba, 0xe5, 0xdd, 0xc2, 0xf4, 0xea, +0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, 0xee, 0xfe, +0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, 0xe1, 0x98, +0xe3, 0xd8, 0x83, 0xe0, 0xda, 0x7b, 0xdf, 0xda, +0x84, 0xe4, 0xe1, 0x96, 0xe8, 0xe3, 0xab, 0xf3, +0xe9, 0xda, 0xf6, 0xee, 0xb4, 0xeb, 0xe3, 0x98, +0xe1, 0xdc, 0x84, 0xe8, 0xe0, 0xab, 0xf2, 0xe8, +0xd9, 0xff, 0xfa, 0xef, 0xe3, 0xde, 0x81, 0xe4, +0xdf, 0x96, 0xff, 0xfa, 0xf4, 0xff, 0xf9, 0xee, +0xff, 0xf3, 0xd3, 0xf3, 0xe9, 0xb6, 0xe4, 0xdc, +0x98, 0xea, 0xe5, 0xab, 0xfe, 0xf4, 0xd1, 0xe3, +0xdb, 0x81, 0xf2, 0xea, 0xd9, 0xec, 0xe7, 0x96, +0xe9, 0xe4, 0xaa, 0xcb, 0xbc, 0x82, 0xff, 0xf8, +0xf2, 0xe2, 0xda, 0x82, 0xe4, 0xdf, 0x98, 0xcd, +0xc0, 0x75, 0xb0, 0x99, 0x39, 0xc2, 0xae, 0x65, +0xdb, 0xc6, 0x94, 0xed, 0xdd, 0xb5, 0xf3, 0xe6, +0xbe, 0xf3, 0xeb, 0xaf, 0xe9, 0xe1, 0x93, 0xdc, +0xd4, 0x77, 0xd3, 0xc8, 0x66, 0xc9, 0xb9, 0x5c, +0xbd, 0xa9, 0x50, 0xaf, 0x98, 0x38, 0x5a, 0xd3, +0x52, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xc4, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x60, 0x60, 0x64, 0x62, 0x66, 0x01, 0x02, +0x66, 0x26, 0x06, 0x08, 0x60, 0x65, 0x63, 0xe7, +0xe0, 0xe4, 0xe2, 0xe6, 0xe1, 0xe5, 0xe3, 0x17, +0x00, 0xf1, 0x05, 0x85, 0x84, 0x45, 0x44, 0xc5, +0xc4, 0x25, 0x24, 0xa5, 0xa4, 0x65, 0x64, 0x05, +0x81, 0x02, 0x72, 0xf2, 0xc2, 0x22, 0x0a, 0x8a, +0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, +0x40, 0x01, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d, +0x03, 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x2d, +0x90, 0x80, 0x99, 0xb9, 0x85, 0xa5, 0x95, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0x83, 0x23, 0x44, 0xc0, +0x09, 0x28, 0xe0, 0xec, 0xe2, 0x6a, 0xe7, 0xea, +0xe0, 0x06, 0x11, 0x70, 0xb7, 0xf0, 0x00, 0x0a, +0x78, 0xda, 0xb9, 0x7a, 0x41, 0x55, 0xb8, 0x7b, +0xfb, 0xf8, 0xfa, 0xb9, 0x00, 0xb5, 0x78, 0xb9, +0xc1, 0x05, 0xac, 0xac, 0x41, 0x2a, 0xfc, 0x1d, +0x91, 0xb4, 0xd8, 0x78, 0x02, 0x55, 0x04, 0x40, +0x0d, 0xf5, 0xf6, 0x08, 0xb4, 0x76, 0x09, 0x02, +0x0a, 0x40, 0x55, 0x04, 0x03, 0xb5, 0xf8, 0x85, +0x80, 0x0c, 0x0d, 0x05, 0x0b, 0x84, 0x99, 0x87, +0x83, 0xcc, 0x88, 0xb0, 0xb3, 0x8f, 0x8c, 0x02, +0x09, 0x30, 0x44, 0xc7, 0xc4, 0xc6, 0xc5, 0x27, +0x24, 0x26, 0x25, 0xa7, 0xa4, 0xa6, 0x41, 0xfd, +0x8b, 0xec, 0x7d, 0x00, 0xdb, 0x98, 0x2a, 0x2f, +0x64, 0xb3, 0x7b, 0xca, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *database_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_database_png = new wxImage(); + if (!img_database_png || !img_database_png->IsOk()) + { + wxMemoryInputStream img_database_pngIS(database_png_data, sizeof(database_png_data)); + img_database_png->LoadFile(img_database_pngIS, wxBITMAP_TYPE_PNG); + } + return img_database_png; +} +#define database_png_img database_png_img() + +static wxBitmap *database_png_bmp() +{ + static wxBitmap *bmp_database_png; + if (!bmp_database_png || !bmp_database_png->IsOk()) + bmp_database_png = new wxBitmap(*database_png_img); + return bmp_database_png; +} +#define database_png_bmp database_png_bmp() + +static wxIcon *database_png_ico() +{ + static wxIcon *ico_database_png; + if (!ico_database_png || !ico_database_png->IsOk()) + { + ico_database_png = new wxIcon(); + ico_database_png->CopyFromBitmap(*database_png_bmp); + } + return ico_database_png; +} +#define database_png_ico database_png_ico() + +#endif // DATABASE_PNG_H diff --git a/include/images/databases.png b/include/images/databases.png new file mode 100644 index 0000000..bfc0966 Binary files /dev/null and b/include/images/databases.png differ diff --git a/include/images/databases.pngc b/include/images/databases.pngc new file mode 100644 index 0000000..868891e --- /dev/null +++ b/include/images/databases.pngc @@ -0,0 +1,141 @@ +#ifndef DATABASES_PNG_H +#define DATABASES_PNG_H + +static const unsigned char databases_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x71, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc3, 0xb0, 0x6a, 0xb7, +0xa0, 0x4b, 0xaf, 0x96, 0x37, 0xc6, 0xb4, 0x69, +0xda, 0xcb, 0x8e, 0xe6, 0xdc, 0xa9, 0xed, 0xe8, +0xbd, 0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, +0xdf, 0xa2, 0xd6, 0xce, 0x88, 0xca, 0xbd, 0x6d, +0xbc, 0xad, 0x52, 0xaf, 0x98, 0x37, 0xc1, 0xad, +0x64, 0xdd, 0xd0, 0x99, 0xff, 0xfd, 0xee, 0xff, +0xfd, 0xe3, 0xfe, 0xf9, 0xd8, 0xf9, 0xf9, 0xd1, +0xf5, 0xf0, 0xc5, 0xf1, 0xee, 0xbc, 0xec, 0xe9, +0xb2, 0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, +0xdf, 0x9b, 0xc7, 0xbc, 0x6a, 0xb0, 0x98, 0x3b, +0xe9, 0xe1, 0xb7, 0xfc, 0xf9, 0xd9, 0xfa, 0xf7, +0xcf, 0xf4, 0xf4, 0xc7, 0xee, 0xee, 0xbe, 0xed, +0xed, 0xbb, 0xec, 0xe9, 0xbf, 0xed, 0xed, 0xca, +0xf4, 0xf4, 0xdb, 0xfc, 0xf9, 0xf2, 0xb8, 0xa2, +0x4e, 0xac, 0x92, 0x30, 0xe3, 0xd9, 0xbb, 0xe9, +0xdc, 0xb9, 0xed, 0xe4, 0xbd, 0xf5, 0xf0, 0xd4, +0xf5, 0xf2, 0xd9, 0xfb, 0xfb, 0xf1, 0xfe, 0xfe, +0xfb, 0xf7, 0xf4, 0xe8, 0xf0, 0xed, 0xd2, 0xec, +0xe9, 0xc4, 0xea, 0xe0, 0xb8, 0xdb, 0xd1, 0xae, +0xf4, 0xea, 0xd8, 0xff, 0xf8, 0xf3, 0xff, 0xf7, +0xee, 0xfe, 0xf4, 0xd3, 0xf4, 0xec, 0xb5, 0xeb, +0xe1, 0x98, 0xe3, 0xd9, 0x83, 0xe0, 0xda, 0x7b, +0xdf, 0xda, 0x84, 0xe4, 0xe0, 0x97, 0xdf, 0xd7, +0x9d, 0xd1, 0xc4, 0x99, 0xd0, 0xbe, 0x91, 0xe5, +0xd3, 0xb3, 0xf2, 0xe4, 0xc7, 0xf6, 0xec, 0xc6, +0xf4, 0xec, 0xb2, 0xea, 0xe1, 0x97, 0xdc, 0xd4, +0x81, 0xd8, 0xcd, 0x78, 0xd1, 0xc4, 0x7b, 0xca, +0xbb, 0x7c, 0xd3, 0xc3, 0x8c, 0xe3, 0xd9, 0xbd, +0xe4, 0xd7, 0xba, 0xe0, 0xce, 0xab, 0xd4, 0xc2, +0x92, 0xc7, 0xb3, 0x7e, 0xc1, 0xad, 0x73, 0xc0, +0xac, 0x72, 0xcb, 0xbc, 0x82, 0xd7, 0xca, 0x98, +0xe3, 0xdb, 0xb2, 0xf0, 0xed, 0xd7, 0xfc, 0xfc, +0xf7, 0xb3, 0x9c, 0x44, 0xe5, 0xdb, 0xbf, 0xf2, +0xe8, 0xd9, 0xff, 0xfa, 0xf4, 0xff, 0xfc, 0xf5, +0xfe, 0xf6, 0xe5, 0xfc, 0xf9, 0xed, 0xfb, 0xf8, +0xe9, 0xf9, 0xf9, 0xe5, 0xf5, 0xf2, 0xd3, 0xf2, +0xef, 0xcc, 0xff, 0xf9, 0xee, 0xeb, 0xe3, 0x98, +0xe3, 0xde, 0x81, 0xe1, 0xdc, 0x84, 0xe4, 0xdc, +0x98, 0xce, 0xbc, 0x91, 0xdf, 0xd7, 0x7f, 0xd3, +0xc6, 0x8c, 0xe5, 0xdd, 0xc2, 0xf2, 0xea, 0xd9, +0xfe, 0xf9, 0xe5, 0xfd, 0xfa, 0xf8, 0xee, 0xe9, +0xbe, 0xcd, 0xc0, 0x75, 0xb0, 0x99, 0x39, 0xdb, +0xc6, 0x94, 0xed, 0xdd, 0xb5, 0xf3, 0xe6, 0xbe, +0xf3, 0xeb, 0xaf, 0xe9, 0xe1, 0x93, 0xdc, 0xd4, +0x77, 0xd3, 0xc8, 0x66, 0xc9, 0xb9, 0x5c, 0xd3, +0xc5, 0x91, 0xc5, 0x63, 0xab, 0x2f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xc9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, 0x26, +0x66, 0x20, 0x60, 0x62, 0x64, 0x80, 0x02, 0x16, +0x56, 0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, +0x5e, 0x3e, 0x10, 0x97, 0x5f, 0x40, 0x50, 0x48, +0x58, 0x44, 0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, +0x9a, 0x1f, 0x28, 0x20, 0x23, 0x2b, 0x28, 0x24, +0x27, 0xaf, 0xa0, 0xa8, 0xa4, 0xac, 0xa2, 0xaa, +0xa6, 0x0e, 0x14, 0xd0, 0xd0, 0xd4, 0xd2, 0xd6, +0xd1, 0xd5, 0xd3, 0xd3, 0x37, 0x30, 0x34, 0x32, +0xd6, 0x00, 0x09, 0x98, 0x98, 0x9a, 0x99, 0x5b, +0x58, 0x5a, 0x59, 0xdb, 0xd8, 0xda, 0xd9, 0x83, +0x05, 0x1c, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, +0xdc, 0x3d, 0x3c, 0xbd, 0xbc, 0xc1, 0x02, 0x3e, +0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, +0xa1, 0x61, 0xe1, 0x11, 0x20, 0x81, 0xc8, 0xa8, +0xe8, 0x98, 0xd8, 0xb8, 0x78, 0xfd, 0x84, 0xc4, +0x24, 0x6d, 0x88, 0x19, 0x51, 0xd1, 0xc9, 0x16, +0x96, 0x29, 0xa9, 0x36, 0x69, 0xe9, 0x50, 0x33, +0x32, 0xc0, 0x66, 0x64, 0x02, 0xcd, 0xc8, 0xc2, +0x6e, 0x46, 0x76, 0x4e, 0x74, 0x4c, 0x6e, 0x5c, +0x7c, 0x1e, 0xd0, 0x8c, 0x7c, 0xb0, 0x8a, 0x60, +0x53, 0x33, 0x90, 0x19, 0x20, 0x77, 0x14, 0x80, +0x04, 0x18, 0x0a, 0xf9, 0x8b, 0x8a, 0x4b, 0x4a, +0xcb, 0xca, 0x2b, 0x2a, 0xf9, 0xf9, 0x20, 0xbe, +0xad, 0x42, 0xf6, 0x3e, 0x00, 0x6d, 0x62, 0x2e, +0xe9, 0x0d, 0xa5, 0xcd, 0x58, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *databases_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_databases_png = new wxImage(); + if (!img_databases_png || !img_databases_png->IsOk()) + { + wxMemoryInputStream img_databases_pngIS(databases_png_data, sizeof(databases_png_data)); + img_databases_png->LoadFile(img_databases_pngIS, wxBITMAP_TYPE_PNG); + } + return img_databases_png; +} +#define databases_png_img databases_png_img() + +static wxBitmap *databases_png_bmp() +{ + static wxBitmap *bmp_databases_png; + if (!bmp_databases_png || !bmp_databases_png->IsOk()) + bmp_databases_png = new wxBitmap(*databases_png_img); + return bmp_databases_png; +} +#define databases_png_bmp databases_png_bmp() + +static wxIcon *databases_png_ico() +{ + static wxIcon *ico_databases_png; + if (!ico_databases_png || !ico_databases_png->IsOk()) + { + ico_databases_png = new wxIcon(); + ico_databases_png->CopyFromBitmap(*databases_png_bmp); + } + return ico_databases_png; +} +#define databases_png_ico databases_png_ico() + +#endif // DATABASES_PNG_H diff --git a/include/images/ddAddColumn.png b/include/images/ddAddColumn.png new file mode 100644 index 0000000..85942d9 Binary files /dev/null and b/include/images/ddAddColumn.png differ diff --git a/include/images/ddAddColumn.pngc b/include/images/ddAddColumn.pngc new file mode 100644 index 0000000..a7a48c1 --- /dev/null +++ b/include/images/ddAddColumn.pngc @@ -0,0 +1,65 @@ +#ifndef DDADDCOLUMN_PNG_H +#define DDADDCOLUMN_PNG_H + +static const unsigned char ddAddColumn_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x2f, 0x44, 0x9d, 0xe4, 0x55, +0x00, 0x00, 0x00, 0x25, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x40, 0x02, 0x5e, 0x31, +0x8f, 0xff, 0x7b, 0xc5, 0x3c, 0xfe, 0x8f, 0x2c, +0xc6, 0xc4, 0x40, 0x00, 0x10, 0x54, 0xc0, 0x88, +0x6e, 0x24, 0xc9, 0x26, 0x30, 0xd0, 0xde, 0x91, +0x00, 0x22, 0xa2, 0x0c, 0xb4, 0xb2, 0x3d, 0x8d, +0x0c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddAddColumn_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddAddColumn_png = new wxImage(); + if (!img_ddAddColumn_png || !img_ddAddColumn_png->IsOk()) + { + wxMemoryInputStream img_ddAddColumn_pngIS(ddAddColumn_png_data, sizeof(ddAddColumn_png_data)); + img_ddAddColumn_png->LoadFile(img_ddAddColumn_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddAddColumn_png; +} +#define ddAddColumn_png_img ddAddColumn_png_img() + +static wxBitmap *ddAddColumn_png_bmp() +{ + static wxBitmap *bmp_ddAddColumn_png; + if (!bmp_ddAddColumn_png || !bmp_ddAddColumn_png->IsOk()) + bmp_ddAddColumn_png = new wxBitmap(*ddAddColumn_png_img); + return bmp_ddAddColumn_png; +} +#define ddAddColumn_png_bmp ddAddColumn_png_bmp() + +static wxIcon *ddAddColumn_png_ico() +{ + static wxIcon *ico_ddAddColumn_png; + if (!ico_ddAddColumn_png || !ico_ddAddColumn_png->IsOk()) + { + ico_ddAddColumn_png = new wxIcon(); + ico_ddAddColumn_png->CopyFromBitmap(*ddAddColumn_png_bmp); + } + return ico_ddAddColumn_png; +} +#define ddAddColumn_png_ico ddAddColumn_png_ico() + +#endif // DDADDCOLUMN_PNG_H diff --git a/include/images/ddAddColumnCursor.png b/include/images/ddAddColumnCursor.png new file mode 100644 index 0000000..0ce824d Binary files /dev/null and b/include/images/ddAddColumnCursor.png differ diff --git a/include/images/ddAddColumnCursor.pngc b/include/images/ddAddColumnCursor.pngc new file mode 100644 index 0000000..be8882b --- /dev/null +++ b/include/images/ddAddColumnCursor.pngc @@ -0,0 +1,121 @@ +#ifndef DDADDCOLUMNCURSOR_PNG_H +#define DDADDCOLUMNCURSOR_PNG_H + +static const unsigned char ddAddColumnCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x23, 0x4d, 0x2b, 0xa8, 0x7e, +0x00, 0x00, 0x01, 0xe4, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xed, 0x96, 0xbd, 0x8a, 0xdb, 0x40, +0x14, 0x85, 0xbf, 0x3b, 0xfe, 0x19, 0x09, 0x12, +0x5c, 0xa5, 0x48, 0x99, 0x72, 0xd3, 0x6f, 0x30, +0xb6, 0x31, 0xb8, 0x4a, 0xb3, 0xa4, 0x09, 0xb8, +0x59, 0xd8, 0x22, 0x6d, 0x0a, 0xf9, 0x05, 0xdc, +0x6f, 0x3a, 0x9b, 0xb0, 0x0f, 0xb0, 0x2f, 0x10, +0xf2, 0x02, 0x02, 0xff, 0xc4, 0x20, 0x91, 0x27, +0x48, 0x9a, 0x94, 0x29, 0xb7, 0x09, 0xd8, 0xb0, +0x91, 0x26, 0x45, 0x3c, 0x8a, 0xe4, 0x78, 0x1d, +0x2b, 0x5a, 0x5b, 0xcd, 0x1e, 0x10, 0x42, 0x3f, +0xe8, 0x9c, 0x39, 0xe7, 0xde, 0x3b, 0x02, 0x30, +0x94, 0x08, 0xb5, 0x3e, 0x9b, 0x52, 0x05, 0x18, +0x63, 0x4a, 0x13, 0x61, 0x1d, 0x28, 0x4d, 0x84, +0x4a, 0x5f, 0x94, 0x21, 0x42, 0x6d, 0xde, 0x38, +0xb6, 0x88, 0x6a, 0xfa, 0x42, 0x44, 0x32, 0x5a, +0x00, 0x39, 0x9a, 0x80, 0x35, 0xb9, 0x94, 0x51, +0x88, 0xa6, 0xcc, 0x36, 0xb4, 0x0e, 0xec, 0xbd, +0xf2, 0x67, 0x57, 0xdf, 0x77, 0x8a, 0xf5, 0x4e, +0x1f, 0x31, 0x78, 0xf1, 0x58, 0xf2, 0x08, 0xc8, +0x45, 0xfe, 0xbe, 0xa7, 0x39, 0xd1, 0x37, 0x49, +0x6c, 0x22, 0x42, 0xbd, 0x5e, 0x47, 0x44, 0xb8, +0xfe, 0x22, 0x8c, 0x3f, 0xff, 0x28, 0xd6, 0x05, +0xff, 0xc2, 0x89, 0xbe, 0x21, 0x0c, 0x43, 0x5c, +0xd7, 0x4d, 0x0e, 0xad, 0x35, 0x41, 0x10, 0xf0, +0xe6, 0xb9, 0x2a, 0xd6, 0x05, 0x79, 0x30, 0x9f, +0xcf, 0x31, 0xc6, 0x20, 0x22, 0x54, 0xab, 0x55, +0x94, 0x52, 0x9b, 0x5d, 0x74, 0x18, 0x01, 0x22, +0x42, 0xab, 0xd5, 0x4a, 0xc8, 0x44, 0x04, 0xad, +0x35, 0xab, 0xd5, 0x8a, 0xe5, 0x72, 0x09, 0xd4, +0x0f, 0x1b, 0x41, 0xa5, 0x52, 0x21, 0x0c, 0x43, +0x1c, 0xc7, 0xc1, 0x71, 0x1c, 0xb4, 0xd6, 0x00, +0x04, 0x41, 0x50, 0x7c, 0x10, 0xe5, 0xc1, 0x64, +0x32, 0xb9, 0xff, 0x49, 0xb8, 0x2f, 0x9a, 0xcd, +0xe6, 0xce, 0xe7, 0x9e, 0xe7, 0x19, 0x80, 0x76, +0xbb, 0x4d, 0xbf, 0xdf, 0x97, 0x7b, 0x8d, 0xc0, +0xda, 0x6d, 0x23, 0xb0, 0x87, 0x8d, 0xe0, 0xd5, +0xd7, 0x4b, 0xce, 0x46, 0x17, 0xbc, 0x1c, 0x9d, +0xb3, 0x58, 0x2c, 0x0e, 0x17, 0xc1, 0x6c, 0x36, +0x4b, 0x0a, 0x31, 0x8a, 0x22, 0x5c, 0xd7, 0xa5, +0xd1, 0x68, 0x00, 0x70, 0x4b, 0x74, 0xb8, 0x08, +0x6a, 0xb5, 0x1a, 0xdd, 0x6e, 0x17, 0xa5, 0x54, +0xd2, 0x7a, 0x76, 0x10, 0x29, 0xf5, 0xc7, 0xd0, +0x9f, 0x7b, 0x8a, 0xf8, 0xaf, 0x36, 0x0c, 0x82, +0x80, 0x5e, 0xaf, 0xf7, 0x3b, 0x43, 0xa5, 0x18, +0x0e, 0x87, 0x99, 0x77, 0xd2, 0xe4, 0xb6, 0x1e, +0xee, 0xaa, 0x89, 0xdc, 0x02, 0xec, 0xaa, 0xa7, +0xd3, 0x29, 0x22, 0x82, 0xef, 0xfb, 0x9c, 0x8d, +0x2e, 0x12, 0xdb, 0x2d, 0x79, 0x44, 0x44, 0x77, +0xf4, 0x9a, 0x78, 0xbd, 0xcf, 0xc5, 0xc4, 0x2c, +0x06, 0x1f, 0x8b, 0x3b, 0xa0, 0x94, 0xa2, 0xd3, +0xe9, 0x24, 0xfb, 0x80, 0xef, 0xfb, 0x5b, 0xc9, +0x63, 0xe2, 0x0c, 0xf9, 0x2d, 0xf1, 0x76, 0x47, +0xf3, 0x0a, 0xd8, 0xdc, 0x0d, 0xdf, 0x3d, 0x99, +0xff, 0x55, 0xed, 0x76, 0xe5, 0x9f, 0x06, 0x1f, +0x32, 0xf7, 0xc7, 0xe3, 0xb1, 0x14, 0x76, 0xe0, +0xdb, 0xdb, 0xa7, 0x99, 0x8f, 0xf4, 0xb7, 0xcc, +0x80, 0x38, 0xf5, 0x7b, 0xb1, 0x8d, 0xb4, 0xf0, +0x1c, 0xd8, 0x07, 0xf1, 0x1d, 0x96, 0x1f, 0x45, +0xc0, 0xae, 0xcc, 0x8f, 0x02, 0xcf, 0xf3, 0x4c, +0xba, 0xfd, 0x1e, 0xf0, 0x80, 0x5d, 0xf8, 0x05, +0xa3, 0x99, 0xa3, 0xa0, 0x99, 0x3a, 0x61, 0x67, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddAddColumnCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddAddColumnCursor_png = new wxImage(); + if (!img_ddAddColumnCursor_png || !img_ddAddColumnCursor_png->IsOk()) + { + wxMemoryInputStream img_ddAddColumnCursor_pngIS(ddAddColumnCursor_png_data, sizeof(ddAddColumnCursor_png_data)); + img_ddAddColumnCursor_png->LoadFile(img_ddAddColumnCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddAddColumnCursor_png; +} +#define ddAddColumnCursor_png_img ddAddColumnCursor_png_img() + +static wxBitmap *ddAddColumnCursor_png_bmp() +{ + static wxBitmap *bmp_ddAddColumnCursor_png; + if (!bmp_ddAddColumnCursor_png || !bmp_ddAddColumnCursor_png->IsOk()) + bmp_ddAddColumnCursor_png = new wxBitmap(*ddAddColumnCursor_png_img); + return bmp_ddAddColumnCursor_png; +} +#define ddAddColumnCursor_png_bmp ddAddColumnCursor_png_bmp() + +static wxIcon *ddAddColumnCursor_png_ico() +{ + static wxIcon *ico_ddAddColumnCursor_png; + if (!ico_ddAddColumnCursor_png || !ico_ddAddColumnCursor_png->IsOk()) + { + ico_ddAddColumnCursor_png = new wxIcon(); + ico_ddAddColumnCursor_png->CopyFromBitmap(*ddAddColumnCursor_png_bmp); + } + return ico_ddAddColumnCursor_png; +} +#define ddAddColumnCursor_png_ico ddAddColumnCursor_png_ico() + +#endif // DDADDCOLUMNCURSOR_PNG_H diff --git a/include/images/ddAddForeignKey.png b/include/images/ddAddForeignKey.png new file mode 100644 index 0000000..f94315a Binary files /dev/null and b/include/images/ddAddForeignKey.png differ diff --git a/include/images/ddAddForeignKey.pngc b/include/images/ddAddForeignKey.pngc new file mode 100644 index 0000000..e633d53 --- /dev/null +++ b/include/images/ddAddForeignKey.pngc @@ -0,0 +1,66 @@ +#ifndef DDADDFOREIGNKEY_PNG_H +#define DDADDFOREIGNKEY_PNG_H + +static const unsigned char ddAddForeignKey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x19, 0x8b, 0x27, 0x71, 0xcc, +0x00, 0x00, 0x00, 0x2d, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0xf0, 0x8a, 0x79, 0xfc, 0x9f, +0x01, 0x0f, 0x60, 0xc4, 0xa6, 0x60, 0xdb, 0x12, +0x59, 0x46, 0x38, 0x07, 0x5d, 0x01, 0x21, 0x13, +0x31, 0x14, 0x30, 0x31, 0x10, 0x00, 0x4c, 0x84, +0x4c, 0x63, 0x24, 0x64, 0x05, 0x41, 0xf7, 0x00, +0x00, 0x59, 0xfa, 0x15, 0xbf, 0x0a, 0x12, 0xf9, +0xf7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddAddForeignKey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddAddForeignKey_png = new wxImage(); + if (!img_ddAddForeignKey_png || !img_ddAddForeignKey_png->IsOk()) + { + wxMemoryInputStream img_ddAddForeignKey_pngIS(ddAddForeignKey_png_data, sizeof(ddAddForeignKey_png_data)); + img_ddAddForeignKey_png->LoadFile(img_ddAddForeignKey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddAddForeignKey_png; +} +#define ddAddForeignKey_png_img ddAddForeignKey_png_img() + +static wxBitmap *ddAddForeignKey_png_bmp() +{ + static wxBitmap *bmp_ddAddForeignKey_png; + if (!bmp_ddAddForeignKey_png || !bmp_ddAddForeignKey_png->IsOk()) + bmp_ddAddForeignKey_png = new wxBitmap(*ddAddForeignKey_png_img); + return bmp_ddAddForeignKey_png; +} +#define ddAddForeignKey_png_bmp ddAddForeignKey_png_bmp() + +static wxIcon *ddAddForeignKey_png_ico() +{ + static wxIcon *ico_ddAddForeignKey_png; + if (!ico_ddAddForeignKey_png || !ico_ddAddForeignKey_png->IsOk()) + { + ico_ddAddForeignKey_png = new wxIcon(); + ico_ddAddForeignKey_png->CopyFromBitmap(*ddAddForeignKey_png_bmp); + } + return ico_ddAddForeignKey_png; +} +#define ddAddForeignKey_png_ico ddAddForeignKey_png_ico() + +#endif // DDADDFOREIGNKEY_PNG_H diff --git a/include/images/ddDeleteTableCursor.png b/include/images/ddDeleteTableCursor.png new file mode 100644 index 0000000..1cd860f Binary files /dev/null and b/include/images/ddDeleteTableCursor.png differ diff --git a/include/images/ddDeleteTableCursor.pngc b/include/images/ddDeleteTableCursor.pngc new file mode 100644 index 0000000..623a5b7 --- /dev/null +++ b/include/images/ddDeleteTableCursor.pngc @@ -0,0 +1,162 @@ +#ifndef DDDELETETABLECURSOR_PNG_H +#define DDDELETETABLECURSOR_PNG_H + +static const unsigned char ddDeleteTableCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x07, 0x71, 0x28, 0x4c, 0xaf, +0x00, 0x00, 0x03, 0x29, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xed, 0x96, 0x4f, 0x68, 0x54, 0x57, +0x14, 0xc6, 0x7f, 0xf7, 0x66, 0xc6, 0x79, 0x03, +0xa5, 0x88, 0x1b, 0x47, 0xda, 0x0e, 0x18, 0x82, +0xa0, 0x23, 0x8a, 0x34, 0xa9, 0x62, 0x21, 0xe0, +0xa2, 0x08, 0xb6, 0x1b, 0x4d, 0x8d, 0x0b, 0xa1, +0x60, 0xe8, 0xa2, 0x4f, 0x0b, 0xdd, 0xa9, 0xbb, +0x4a, 0x4b, 0x05, 0x5d, 0xb8, 0xb0, 0x6d, 0x02, +0x12, 0xb4, 0x8a, 0xa5, 0x5a, 0x0a, 0x82, 0x08, +0x49, 0x34, 0xb6, 0x26, 0x20, 0x24, 0x55, 0xb4, +0xd4, 0x3f, 0x13, 0x4b, 0x1a, 0xa5, 0xb3, 0x88, +0x94, 0xb6, 0x2e, 0x1a, 0xeb, 0xdc, 0xfb, 0x5e, +0xde, 0x71, 0x31, 0x93, 0x69, 0x66, 0x92, 0x97, +0x79, 0x2f, 0x06, 0xb2, 0xf1, 0xc2, 0xe1, 0x3d, +0x2e, 0xf7, 0xde, 0xef, 0x3b, 0xdf, 0x39, 0xf7, +0xdc, 0x03, 0x20, 0x2c, 0xe2, 0xd0, 0xe5, 0xaf, +0x2c, 0x2a, 0x01, 0x11, 0x59, 0x34, 0x12, 0x53, +0x0a, 0x2c, 0x1a, 0x09, 0x55, 0xc2, 0xfe, 0x1f, +0x57, 0x29, 0x35, 0x35, 0x3f, 0xe7, 0x10, 0x99, +0x49, 0x56, 0xa9, 0xfa, 0xfb, 0xea, 0x12, 0x98, +0x8b, 0xc4, 0x6c, 0xa0, 0xa1, 0x07, 0x47, 0x24, +0xa3, 0x6b, 0x81, 0xcb, 0xe0, 0x33, 0xc2, 0x11, +0x07, 0x3c, 0xce, 0x7a, 0x3d, 0x8b, 0xd7, 0xd3, +0x6d, 0x5e, 0xe0, 0x71, 0xf6, 0xa9, 0x69, 0x9e, +0xaa, 0xb0, 0x43, 0x1a, 0x3b, 0xc7, 0xe7, 0x95, +0x60, 0x63, 0x7b, 0x57, 0xd4, 0x0d, 0x47, 0xa2, +0x1e, 0xf8, 0xd4, 0xff, 0xc7, 0x6f, 0x67, 0x48, +0x8a, 0xcf, 0xd2, 0x84, 0x25, 0x93, 0x2c, 0xb2, +0x3c, 0xe5, 0xf3, 0x6a, 0x22, 0x60, 0x49, 0x03, +0xa8, 0xf2, 0xb2, 0x09, 0x4f, 0xf8, 0xf5, 0x6f, +0x4d, 0x4f, 0x41, 0x71, 0xe3, 0xcf, 0xea, 0x73, +0xc2, 0x48, 0x24, 0xa2, 0x64, 0x3c, 0x40, 0x20, +0xf0, 0xef, 0x64, 0x03, 0x7f, 0x99, 0x14, 0x77, +0xbc, 0x24, 0xcf, 0xbc, 0x80, 0xa7, 0x36, 0xe0, +0xa9, 0x9d, 0x2c, 0x99, 0x17, 0xf0, 0xcc, 0x04, +0xfc, 0xe7, 0x07, 0x18, 0x5f, 0xf0, 0x26, 0x03, +0x62, 0x27, 0x61, 0xfd, 0xf8, 0x09, 0x84, 0x94, +0x4e, 0x25, 0x20, 0x2a, 0xdc, 0x9b, 0xb0, 0x7c, +0x48, 0x44, 0x8d, 0xe7, 0xea, 0xd4, 0x13, 0x56, +0xa7, 0x9e, 0x54, 0xdd, 0x96, 0x5a, 0xd3, 0x5a, +0xa3, 0x94, 0xe2, 0xf4, 0x03, 0xc5, 0x89, 0xfb, +0xcc, 0x5f, 0x81, 0xd9, 0xd8, 0x46, 0x05, 0xd7, +0x5a, 0xd3, 0xb1, 0x46, 0x47, 0x56, 0x41, 0xc7, +0xc9, 0xea, 0x74, 0x3a, 0x5d, 0xb1, 0xe1, 0xe1, +0x61, 0xfe, 0xf9, 0xfc, 0x30, 0x85, 0x6c, 0x96, +0xc7, 0x9f, 0x7e, 0x46, 0x2a, 0x95, 0xaa, 0xd8, +0xc4, 0xa1, 0x43, 0x9c, 0xdd, 0xb7, 0x82, 0xb1, +0xbd, 0x6e, 0xdd, 0x33, 0x13, 0xd1, 0x2b, 0x9b, +0x62, 0x60, 0x60, 0xa0, 0xe2, 0x71, 0xfe, 0xe0, +0x49, 0x5e, 0x7f, 0xd8, 0xc7, 0x86, 0x03, 0x07, +0xb8, 0x7d, 0xe4, 0x08, 0x5f, 0xfd, 0xf4, 0x07, +0xeb, 0x8f, 0x7d, 0x84, 0xf9, 0xe2, 0x30, 0x6f, +0xdc, 0xbc, 0xc1, 0xda, 0x5d, 0xbb, 0xb8, 0xdb, +0xd5, 0x05, 0xb8, 0x34, 0x76, 0x76, 0xcd, 0x59, +0x07, 0xea, 0x4a, 0xd5, 0xd8, 0x39, 0xce, 0x8f, +0xdb, 0x8a, 0x55, 0x92, 0x17, 0xb2, 0x59, 0x36, +0xec, 0xdf, 0x0f, 0xbe, 0x8f, 0xf8, 0x3e, 0xbf, +0x1c, 0x3f, 0xce, 0xe4, 0x07, 0x1f, 0xd2, 0x70, +0xa6, 0x9b, 0xb5, 0xed, 0xed, 0x04, 0xc6, 0x20, +0xc6, 0x92, 0xef, 0xed, 0x61, 0xb3, 0x84, 0x97, +0x68, 0x1d, 0x47, 0x81, 0x74, 0x3a, 0x8d, 0xe3, +0x38, 0x38, 0x8e, 0xc3, 0x95, 0x95, 0x5b, 0xb9, +0x7d, 0xf4, 0x28, 0xe2, 0x79, 0x88, 0xb5, 0xac, +0xeb, 0xe8, 0xa0, 0xe1, 0x4c, 0x37, 0xb9, 0x9d, +0x3b, 0x09, 0x8a, 0x06, 0x31, 0x86, 0x7c, 0x6f, +0x0f, 0x19, 0xd7, 0xad, 0x5b, 0x09, 0x23, 0x29, +0x70, 0xed, 0x3d, 0xcb, 0xd0, 0xd0, 0x50, 0x25, +0xd9, 0x00, 0x5e, 0xbb, 0xd4, 0x4b, 0xf0, 0x4d, +0x37, 0xeb, 0xf6, 0xec, 0x21, 0xb0, 0x16, 0x29, +0x7b, 0x2d, 0xd6, 0x90, 0xef, 0xeb, 0x23, 0xe3, +0xce, 0x94, 0xbf, 0x56, 0x81, 0x44, 0xd8, 0x4b, +0x56, 0x4b, 0x22, 0x99, 0x4c, 0xd2, 0xda, 0xda, +0x8a, 0xd6, 0xba, 0x42, 0x42, 0x6d, 0xd9, 0xc2, +0x97, 0x03, 0x05, 0x38, 0x75, 0x8a, 0x5c, 0xdb, +0xfb, 0x88, 0x2d, 0x7b, 0x7e, 0xf9, 0x72, 0x24, +0xf0, 0xd8, 0x49, 0xe8, 0x38, 0x4e, 0xc5, 0xfb, +0xc1, 0xc1, 0x41, 0x96, 0xfe, 0x70, 0x91, 0x77, +0x1e, 0xf6, 0x91, 0x6b, 0x6b, 0x43, 0x4c, 0x11, +0x31, 0x86, 0xc0, 0x58, 0x56, 0x6d, 0xda, 0xc4, +0x6f, 0x11, 0x12, 0x70, 0x4e, 0x02, 0xb5, 0x2a, +0x68, 0xad, 0xab, 0x6e, 0xc1, 0xad, 0x4f, 0xbe, +0x2e, 0x81, 0xef, 0xd8, 0x81, 0x14, 0x8b, 0x04, +0xc6, 0x32, 0xd2, 0x7f, 0x85, 0x55, 0x1b, 0x37, +0x22, 0xd6, 0xd2, 0x94, 0xcb, 0x31, 0x3a, 0x8d, +0x44, 0xd8, 0x5b, 0xa0, 0xa2, 0x3c, 0xa7, 0x8d, +0x9d, 0xe3, 0xfc, 0xdc, 0x9e, 0xa8, 0xba, 0x05, +0xf9, 0x65, 0xcb, 0xc8, 0x6d, 0xdf, 0x5e, 0xc9, +0xf6, 0x91, 0xab, 0xfd, 0x4c, 0xec, 0xee, 0xe0, +0x95, 0x6f, 0x4f, 0xd2, 0xb4, 0x26, 0x87, 0x78, +0x16, 0xf1, 0x3c, 0xc6, 0x1e, 0x3d, 0x62, 0xb3, +0x84, 0xbf, 0x88, 0x3a, 0x6a, 0x57, 0xf3, 0xd6, +0xf7, 0x3e, 0x2d, 0xe7, 0x3d, 0x9a, 0xcf, 0x59, +0xde, 0xfc, 0xce, 0x50, 0x68, 0x6e, 0xe1, 0xde, +0x85, 0x0b, 0x48, 0xd1, 0x30, 0x72, 0xb5, 0x9f, +0x42, 0x73, 0x0b, 0xd7, 0x9b, 0xb2, 0x14, 0xb7, +0xbd, 0xcb, 0xe8, 0xfd, 0x7b, 0x88, 0x2d, 0x81, +0x67, 0x5c, 0x77, 0x5e, 0xad, 0xda, 0x0c, 0x25, +0x66, 0xb3, 0xdf, 0x5d, 0x57, 0xae, 0x53, 0xfa, +0x86, 0xcd, 0x47, 0x69, 0x48, 0x16, 0xb4, 0xc5, +0x8a, 0xdb, 0x17, 0xaa, 0xb8, 0x4a, 0x2c, 0x74, +0x53, 0xaa, 0x5e, 0x24, 0x2c, 0x0b, 0xd1, 0x96, +0xbf, 0x1c, 0x2f, 0xc7, 0x73, 0x3a, 0x0e, 0x99, +0xb1, 0xdb, 0x60, 0x70, 0xd1, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddDeleteTableCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddDeleteTableCursor_png = new wxImage(); + if (!img_ddDeleteTableCursor_png || !img_ddDeleteTableCursor_png->IsOk()) + { + wxMemoryInputStream img_ddDeleteTableCursor_pngIS(ddDeleteTableCursor_png_data, sizeof(ddDeleteTableCursor_png_data)); + img_ddDeleteTableCursor_png->LoadFile(img_ddDeleteTableCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddDeleteTableCursor_png; +} +#define ddDeleteTableCursor_png_img ddDeleteTableCursor_png_img() + +static wxBitmap *ddDeleteTableCursor_png_bmp() +{ + static wxBitmap *bmp_ddDeleteTableCursor_png; + if (!bmp_ddDeleteTableCursor_png || !bmp_ddDeleteTableCursor_png->IsOk()) + bmp_ddDeleteTableCursor_png = new wxBitmap(*ddDeleteTableCursor_png_img); + return bmp_ddDeleteTableCursor_png; +} +#define ddDeleteTableCursor_png_bmp ddDeleteTableCursor_png_bmp() + +static wxIcon *ddDeleteTableCursor_png_ico() +{ + static wxIcon *ico_ddDeleteTableCursor_png; + if (!ico_ddDeleteTableCursor_png || !ico_ddDeleteTableCursor_png->IsOk()) + { + ico_ddDeleteTableCursor_png = new wxIcon(); + ico_ddDeleteTableCursor_png->CopyFromBitmap(*ddDeleteTableCursor_png_bmp); + } + return ico_ddDeleteTableCursor_png; +} +#define ddDeleteTableCursor_png_ico ddDeleteTableCursor_png_ico() + +#endif // DDDELETETABLECURSOR_PNG_H diff --git a/include/images/ddDown.png b/include/images/ddDown.png new file mode 100644 index 0000000..87d32a0 Binary files /dev/null and b/include/images/ddDown.png differ diff --git a/include/images/ddDown.pngc b/include/images/ddDown.pngc new file mode 100644 index 0000000..044276f --- /dev/null +++ b/include/images/ddDown.pngc @@ -0,0 +1,81 @@ +#ifndef DDDOWN_PNG_H +#define DDDOWN_PNG_H + +static const unsigned char ddDown_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, +0x08, 0x06, 0x00, 0x00, 0x00, 0x11, 0xc7, 0xb4, +0xc5, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x37, 0x18, 0xb0, 0xea, 0xc4, +0x00, 0x00, 0x00, 0xa3, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0xec, 0xde, 0x98, 0xf8, 0xff, +0xfc, 0xab, 0x4d, 0x0c, 0xb8, 0x80, 0xa1, 0x98, +0x1f, 0x03, 0xcb, 0xf9, 0x57, 0x9b, 0x18, 0x4a, +0x5c, 0xa7, 0x30, 0x3c, 0x7a, 0x7b, 0x94, 0xe1, +0xdf, 0xbf, 0xdf, 0x0c, 0xff, 0x19, 0x7e, 0x33, +0xfc, 0xfb, 0xf7, 0x87, 0xe1, 0xff, 0xff, 0x3f, +0x0c, 0xd2, 0x42, 0xc6, 0x0c, 0x53, 0x0f, 0xb6, +0x31, 0x30, 0x19, 0x8a, 0xf9, 0x31, 0xf4, 0xec, +0xce, 0x61, 0xe0, 0x62, 0x13, 0x67, 0xf8, 0xf0, +0xfd, 0x05, 0xc3, 0xcb, 0x8f, 0xb7, 0x19, 0x3e, +0x7c, 0x7b, 0xca, 0xc0, 0xc5, 0x2e, 0xc6, 0x30, +0xf5, 0x60, 0x1b, 0x83, 0xa1, 0x98, 0x1f, 0x03, +0x23, 0x03, 0x03, 0x03, 0x03, 0xcc, 0xca, 0x04, +0x8b, 0x3c, 0x86, 0xd7, 0x9f, 0x6e, 0x32, 0x08, +0xf2, 0xc8, 0x31, 0x2c, 0x39, 0x35, 0x9b, 0xc1, +0x50, 0xcc, 0x8f, 0xa1, 0xd4, 0x7f, 0x3e, 0x23, +0xdc, 0xee, 0xee, 0x8d, 0x89, 0xff, 0xa3, 0x66, +0x0b, 0xff, 0x3f, 0x73, 0x7f, 0xf1, 0xff, 0xa8, +0xd9, 0xc2, 0xff, 0xbb, 0x37, 0x26, 0xfe, 0xc7, +0xea, 0x48, 0x98, 0x42, 0x74, 0x05, 0x00, 0x36, +0x71, 0x47, 0x38, 0x00, 0x67, 0xe3, 0x0c, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddDown_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddDown_png = new wxImage(); + if (!img_ddDown_png || !img_ddDown_png->IsOk()) + { + wxMemoryInputStream img_ddDown_pngIS(ddDown_png_data, sizeof(ddDown_png_data)); + img_ddDown_png->LoadFile(img_ddDown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddDown_png; +} +#define ddDown_png_img ddDown_png_img() + +static wxBitmap *ddDown_png_bmp() +{ + static wxBitmap *bmp_ddDown_png; + if (!bmp_ddDown_png || !bmp_ddDown_png->IsOk()) + bmp_ddDown_png = new wxBitmap(*ddDown_png_img); + return bmp_ddDown_png; +} +#define ddDown_png_bmp ddDown_png_bmp() + +static wxIcon *ddDown_png_ico() +{ + static wxIcon *ico_ddDown_png; + if (!ico_ddDown_png || !ico_ddDown_png->IsOk()) + { + ico_ddDown_png = new wxIcon(); + ico_ddDown_png->CopyFromBitmap(*ddDown_png_bmp); + } + return ico_ddDown_png; +} +#define ddDown_png_ico ddDown_png_ico() + +#endif // DDDOWN_PNG_H diff --git a/include/images/ddMaximizeTable.png b/include/images/ddMaximizeTable.png new file mode 100644 index 0000000..bab6188 Binary files /dev/null and b/include/images/ddMaximizeTable.png differ diff --git a/include/images/ddMaximizeTable.pngc b/include/images/ddMaximizeTable.pngc new file mode 100644 index 0000000..de7ca09 --- /dev/null +++ b/include/images/ddMaximizeTable.pngc @@ -0,0 +1,65 @@ +#ifndef DDMAXIMIZETABLE_PNG_H +#define DDMAXIMIZETABLE_PNG_H + +static const unsigned char ddMaximizeTable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x0a, 0x40, 0xd8, 0xa6, 0xd5, +0x00, 0x00, 0x00, 0x22, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0xdc, 0xc5, 0xc4, 0xff, 0x9f, +0x01, 0x0f, 0x60, 0x62, 0x20, 0x04, 0xf0, 0x99, +0xb0, 0x8b, 0x89, 0xff, 0x3f, 0x41, 0x13, 0xe8, +0xa0, 0x80, 0x91, 0x90, 0x37, 0x01, 0x99, 0xf5, +0x07, 0x35, 0xe9, 0xaf, 0xad, 0x0f, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddMaximizeTable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddMaximizeTable_png = new wxImage(); + if (!img_ddMaximizeTable_png || !img_ddMaximizeTable_png->IsOk()) + { + wxMemoryInputStream img_ddMaximizeTable_pngIS(ddMaximizeTable_png_data, sizeof(ddMaximizeTable_png_data)); + img_ddMaximizeTable_png->LoadFile(img_ddMaximizeTable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddMaximizeTable_png; +} +#define ddMaximizeTable_png_img ddMaximizeTable_png_img() + +static wxBitmap *ddMaximizeTable_png_bmp() +{ + static wxBitmap *bmp_ddMaximizeTable_png; + if (!bmp_ddMaximizeTable_png || !bmp_ddMaximizeTable_png->IsOk()) + bmp_ddMaximizeTable_png = new wxBitmap(*ddMaximizeTable_png_img); + return bmp_ddMaximizeTable_png; +} +#define ddMaximizeTable_png_bmp ddMaximizeTable_png_bmp() + +static wxIcon *ddMaximizeTable_png_ico() +{ + static wxIcon *ico_ddMaximizeTable_png; + if (!ico_ddMaximizeTable_png || !ico_ddMaximizeTable_png->IsOk()) + { + ico_ddMaximizeTable_png = new wxIcon(); + ico_ddMaximizeTable_png->CopyFromBitmap(*ddMaximizeTable_png_bmp); + } + return ico_ddMaximizeTable_png; +} +#define ddMaximizeTable_png_ico ddMaximizeTable_png_ico() + +#endif // DDMAXIMIZETABLE_PNG_H diff --git a/include/images/ddMinMaxCursor.png b/include/images/ddMinMaxCursor.png new file mode 100644 index 0000000..692ad4c Binary files /dev/null and b/include/images/ddMinMaxCursor.png differ diff --git a/include/images/ddMinMaxCursor.pngc b/include/images/ddMinMaxCursor.pngc new file mode 100644 index 0000000..dcb1dd2 --- /dev/null +++ b/include/images/ddMinMaxCursor.pngc @@ -0,0 +1,241 @@ +#ifndef DDMINMAXCURSOR_PNG_H +#define DDMINMAXCURSOR_PNG_H + +static const unsigned char ddMinMaxCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x32, 0x71, 0xc1, 0x2f, 0x0a, +0x00, 0x00, 0x05, 0xa1, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xad, 0x97, 0x5f, 0x6c, 0x53, 0xf7, +0x15, 0xc7, 0x3f, 0xbf, 0xdf, 0xbd, 0x37, 0xf7, +0xde, 0xd8, 0x4e, 0xc0, 0x24, 0xa4, 0xa1, 0x4b, +0x21, 0xd4, 0x29, 0x69, 0x18, 0x69, 0xb7, 0x76, +0xcd, 0x1f, 0x42, 0x48, 0x3b, 0x36, 0xad, 0x52, +0xab, 0x4a, 0x5d, 0xb5, 0x6e, 0xd2, 0xa8, 0xa6, +0x56, 0x9a, 0x36, 0xad, 0x0f, 0x7b, 0xd8, 0xcb, +0x1e, 0xb6, 0x49, 0x7d, 0xe9, 0xe3, 0xa6, 0x4a, +0xd5, 0x24, 0xb6, 0x56, 0x5a, 0x99, 0x34, 0xb1, +0xa1, 0x3e, 0xb4, 0x48, 0x6c, 0xc0, 0x2a, 0x92, +0x2c, 0x26, 0x86, 0x42, 0x02, 0x2c, 0x59, 0x69, +0x03, 0x11, 0x38, 0xc4, 0x24, 0xfc, 0xa9, 0x63, +0x63, 0x3b, 0xf6, 0xb5, 0xef, 0x6f, 0x0f, 0xc1, +0xae, 0x1d, 0xbb, 0xc1, 0x8e, 0x7a, 0xa4, 0x9f, +0x74, 0x75, 0xef, 0xcf, 0xbf, 0xf3, 0xfd, 0x9d, +0xef, 0xf9, 0x9e, 0x73, 0x2c, 0x00, 0x05, 0x08, +0xaa, 0xb4, 0x43, 0xff, 0x1c, 0x57, 0xc1, 0x99, +0x04, 0x33, 0x0b, 0x69, 0x96, 0x1d, 0x17, 0xcb, +0x90, 0x04, 0x5a, 0x4c, 0xfa, 0x03, 0x1e, 0x5e, +0xfe, 0x5e, 0x6f, 0xd5, 0xe7, 0xe4, 0x4d, 0xdc, +0x03, 0x40, 0x35, 0x20, 0x0e, 0xbc, 0x3f, 0xa6, +0x3e, 0x98, 0x4a, 0xd3, 0xde, 0xbd, 0x03, 0x7b, +0xd3, 0x46, 0xb2, 0x52, 0x92, 0x4c, 0xa7, 0x89, +0x2e, 0xde, 0xe1, 0xce, 0x27, 0x97, 0x79, 0x69, +0x97, 0xcd, 0x4f, 0x5f, 0xdc, 0x5d, 0x13, 0x08, +0x09, 0xa0, 0x94, 0xa2, 0x08, 0x48, 0x45, 0x3b, +0x78, 0xe4, 0x94, 0xfa, 0x60, 0x3a, 0x4d, 0x67, +0xef, 0x63, 0x98, 0x8d, 0x3e, 0x92, 0xa9, 0x65, +0x96, 0x33, 0x0e, 0xc9, 0x54, 0x1a, 0xe5, 0xad, +0xc7, 0xdc, 0xd9, 0xc1, 0xa1, 0x8b, 0x29, 0x0e, +0x1e, 0x39, 0xa5, 0x6a, 0x01, 0xa0, 0xe7, 0x1f, +0x94, 0x52, 0x08, 0x21, 0xbe, 0x94, 0x8e, 0xe0, +0x4c, 0x82, 0xc0, 0x37, 0x76, 0xa1, 0x74, 0x8d, +0x5b, 0xf3, 0x0b, 0xdc, 0xb9, 0xbe, 0x48, 0x2a, +0xba, 0x84, 0xd1, 0xe8, 0x43, 0x36, 0xf9, 0x71, +0x1a, 0x1b, 0xc8, 0xb6, 0xb7, 0x11, 0x9c, 0x09, +0xd7, 0x4e, 0xc1, 0xbd, 0x08, 0xac, 0xbc, 0x10, +0xa2, 0x8c, 0x8e, 0x83, 0x47, 0x4e, 0xa9, 0x23, +0xb3, 0x3a, 0xdb, 0x1e, 0xeb, 0xe4, 0xfa, 0x95, +0x30, 0xdb, 0x73, 0x8b, 0x74, 0xb7, 0xd9, 0x6c, +0xdd, 0x54, 0xc7, 0xd5, 0xdb, 0x19, 0x2e, 0x84, +0x53, 0x8c, 0xa6, 0x1b, 0x48, 0x34, 0xf9, 0xa9, +0xbb, 0x12, 0x66, 0xff, 0x23, 0x92, 0xf3, 0xd7, +0x52, 0x74, 0xb7, 0xd9, 0xfc, 0xec, 0xfb, 0x6b, +0x53, 0x52, 0x06, 0xa0, 0x12, 0x88, 0xd7, 0xdf, +0x3a, 0xa1, 0xd4, 0xb6, 0x2e, 0x94, 0xae, 0x93, +0x9a, 0x9a, 0xe4, 0xd5, 0x3d, 0x9b, 0xd8, 0xd3, +0xfb, 0x44, 0xe1, 0xfb, 0xfb, 0xc7, 0x43, 0xea, +0xc3, 0xc9, 0x25, 0xce, 0x6f, 0x7e, 0x88, 0x4c, +0x26, 0x8b, 0x75, 0x27, 0xca, 0x6d, 0x9f, 0x17, +0x5f, 0x2c, 0x46, 0xdc, 0xd7, 0x51, 0x1d, 0x05, +0x45, 0x8e, 0x0b, 0xac, 0xe4, 0x41, 0x44, 0xa2, +0x0e, 0x6d, 0x3e, 0x0f, 0xf3, 0x9f, 0xce, 0xb2, +0x67, 0x6b, 0x7d, 0x89, 0xf3, 0x37, 0xdf, 0x1b, +0x51, 0x6f, 0x9d, 0x4e, 0xb1, 0xdc, 0xe0, 0x27, +0xa9, 0xe9, 0x24, 0x3c, 0x06, 0x0b, 0x56, 0x1d, +0x99, 0x9c, 0xcb, 0xb6, 0xf0, 0x75, 0x0e, 0xbe, +0x2c, 0x69, 0xd0, 0x5d, 0xea, 0x34, 0x10, 0xf7, +0xd2, 0x2c, 0x78, 0x43, 0x70, 0x34, 0x2c, 0x38, +0xb3, 0x58, 0x04, 0xa0, 0x52, 0xe8, 0xf3, 0x96, +0xca, 0xb8, 0xe4, 0xa4, 0xc6, 0x52, 0xe4, 0x26, +0xdd, 0xdd, 0xfe, 0x55, 0xb9, 0x71, 0x97, 0xe8, +0xce, 0x2e, 0x92, 0x40, 0x2a, 0x97, 0x23, 0x9d, +0x73, 0x49, 0xe7, 0x5c, 0x1e, 0x9e, 0x8b, 0x30, +0x18, 0xf0, 0xf0, 0xa7, 0xd9, 0x46, 0x12, 0x19, +0x97, 0x44, 0x26, 0xb7, 0xb2, 0x1c, 0x97, 0xdb, +0x89, 0x2c, 0xe9, 0xac, 0xc2, 0xc9, 0xb9, 0x2b, +0x2a, 0x58, 0xcb, 0x39, 0x40, 0x26, 0xa7, 0x70, +0x50, 0x64, 0xd3, 0x19, 0x7c, 0x96, 0x56, 0xf2, +0xad, 0x3f, 0xe0, 0xa5, 0x6d, 0x6a, 0x1a, 0x6b, +0xe1, 0x26, 0x99, 0xec, 0x8a, 0x73, 0x99, 0x76, +0x08, 0xa8, 0x34, 0xc9, 0x47, 0xfa, 0xcb, 0xa4, +0x25, 0x54, 0xa9, 0x23, 0x51, 0x4d, 0x21, 0xfa, +0xed, 0x3b, 0x27, 0xd5, 0x99, 0x05, 0xc1, 0xb7, +0x5a, 0x14, 0x6f, 0xbc, 0x36, 0x54, 0xb6, 0xf7, +0xd8, 0xc8, 0xc7, 0x6a, 0xec, 0xb3, 0xbb, 0x1c, +0xbd, 0x9e, 0xe3, 0xe2, 0xd7, 0xb6, 0xd0, 0x39, +0x37, 0xcf, 0x2b, 0x1d, 0x75, 0xbc, 0xd0, 0xf3, +0x20, 0x42, 0x88, 0xb2, 0xa5, 0x69, 0x1a, 0x7f, +0xb9, 0x24, 0x38, 0x30, 0x5d, 0x43, 0x05, 0xfc, +0xf0, 0xa3, 0xd3, 0xea, 0xf9, 0x67, 0x9e, 0x5a, +0x73, 0xff, 0x6f, 0xfe, 0x7c, 0x52, 0x8d, 0x5e, +0x49, 0xb2, 0x67, 0x7b, 0x3d, 0x3f, 0x79, 0xba, +0x0d, 0x29, 0x65, 0x99, 0x73, 0x29, 0x25, 0x9a, +0xa6, 0x21, 0x84, 0xa0, 0xf7, 0xb0, 0x4b, 0xcd, +0xa5, 0xf3, 0x7e, 0x16, 0xfa, 0x78, 0x42, 0x35, +0x6d, 0x6c, 0xc0, 0xb6, 0x6d, 0xa4, 0x94, 0x0c, +0x0f, 0x0f, 0xd3, 0xd7, 0xd7, 0x87, 0x94, 0x92, +0xf1, 0xf1, 0x71, 0x86, 0x86, 0x86, 0xd0, 0x34, +0x0d, 0xc7, 0x71, 0xe8, 0xf9, 0x47, 0x0e, 0xbd, +0xfd, 0xed, 0x48, 0x4d, 0x95, 0x6b, 0xf6, 0x17, +0xad, 0x6b, 0x82, 0xfe, 0x61, 0xe8, 0x01, 0xfe, +0xfd, 0x6c, 0x8a, 0xe1, 0xe1, 0x61, 0xa4, 0x94, +0x85, 0x04, 0xcf, 0x2b, 0x2c, 0xff, 0x7e, 0x60, +0x60, 0xe0, 0x0b, 0x19, 0xbe, 0xbe, 0xfb, 0x01, +0x0c, 0x95, 0xa5, 0xd3, 0x8e, 0xd1, 0x62, 0x66, +0xd7, 0x94, 0x4d, 0x35, 0x66, 0x59, 0x16, 0x43, +0x43, 0x43, 0xe8, 0xba, 0x5e, 0x12, 0xfe, 0x7d, +0xfb, 0xf6, 0x15, 0x68, 0x58, 0x01, 0x17, 0x5b, +0x01, 0xe0, 0x2a, 0x88, 0xe7, 0x34, 0x8e, 0xdf, +0xf4, 0x91, 0x72, 0xdc, 0x35, 0x65, 0x53, 0x55, +0x79, 0x15, 0x02, 0xcb, 0xb2, 0x10, 0x42, 0x30, +0x32, 0x32, 0xc2, 0xc0, 0xc0, 0x00, 0x52, 0x4a, +0xc6, 0xc6, 0xc6, 0x0a, 0x14, 0xb8, 0xae, 0xbb, +0xba, 0x10, 0x29, 0x2a, 0x75, 0xa4, 0xd5, 0xb2, +0xa9, 0xaa, 0xc3, 0xdd, 0xe3, 0x3e, 0x4f, 0x41, +0x3e, 0x19, 0x8b, 0x29, 0xd8, 0xbb, 0x77, 0xef, +0x17, 0x00, 0x1e, 0x35, 0x3f, 0xe7, 0x51, 0xf3, +0x73, 0x84, 0x5f, 0xdc, 0x57, 0x36, 0xd5, 0x02, +0xc8, 0xdf, 0xba, 0x58, 0x09, 0x83, 0x83, 0x83, +0x45, 0xe1, 0xa7, 0x14, 0x40, 0x71, 0xb2, 0xac, +0x96, 0x8d, 0x94, 0x92, 0x57, 0xbb, 0x04, 0x07, +0xa6, 0xab, 0xa3, 0x20, 0x16, 0x8b, 0x95, 0xdc, +0xfc, 0xcb, 0x64, 0x58, 0x98, 0x07, 0x00, 0x6c, +0xdb, 0xc6, 0xb6, 0x6d, 0x42, 0xa1, 0x50, 0x61, +0x63, 0x28, 0x14, 0xc2, 0x34, 0x4d, 0x4c, 0xd3, +0x5c, 0xdd, 0x27, 0xee, 0x6b, 0xd5, 0x9e, 0xa7, +0xe7, 0x6f, 0x5e, 0xad, 0x6c, 0xaa, 0x4d, 0xc2, +0x9a, 0x64, 0x58, 0x8b, 0x6c, 0xbe, 0x6a, 0x19, +0x4a, 0x00, 0xc3, 0x30, 0x30, 0x0c, 0x03, 0x4d, +0xd3, 0xd0, 0x75, 0xbd, 0xb0, 0x2e, 0xcd, 0xcc, +0x16, 0x9e, 0x8b, 0x13, 0xa7, 0x5a, 0x19, 0x1a, +0x86, 0x41, 0x30, 0x18, 0x2c, 0x38, 0x1d, 0x1b, +0x1b, 0x43, 0xd7, 0x75, 0x0c, 0xc3, 0x28, 0xa5, +0xe0, 0xa9, 0xbf, 0x67, 0xcb, 0x0e, 0xf9, 0xb1, +0x79, 0x89, 0xe0, 0x6c, 0x92, 0xfe, 0xc9, 0x25, +0xfe, 0x9a, 0xde, 0x51, 0x53, 0x9f, 0xa8, 0x45, +0x86, 0x15, 0x33, 0xeb, 0xf7, 0x7f, 0x1b, 0x55, +0xff, 0x9a, 0x13, 0x18, 0xbb, 0x3a, 0x49, 0x4e, +0x4c, 0x31, 0xb0, 0x59, 0xb1, 0xbb, 0xc3, 0xcb, +0x77, 0x07, 0x9f, 0x14, 0x95, 0x3a, 0xe5, 0xd1, +0x6b, 0x0e, 0xcf, 0x3e, 0x64, 0xf0, 0xc6, 0x6b, +0x43, 0xa2, 0xfd, 0xed, 0x88, 0x3a, 0xfd, 0x03, +0xbd, 0x24, 0xd4, 0x95, 0x54, 0x05, 0xd0, 0xf5, +0x6e, 0xb4, 0x74, 0x22, 0x2a, 0x1e, 0x40, 0x37, +0x3d, 0xf1, 0x4d, 0x1c, 0x4d, 0x43, 0x3d, 0xde, +0xc5, 0x7f, 0xc2, 0x11, 0xce, 0x9d, 0x98, 0xe3, +0xcd, 0xf7, 0x46, 0xd4, 0xaf, 0x5f, 0x19, 0x2c, +0x80, 0x38, 0x37, 0x31, 0xa9, 0x7e, 0x75, 0x68, +0x8e, 0x89, 0x40, 0x3b, 0x8d, 0x33, 0xb3, 0x85, +0xdf, 0x57, 0x8a, 0x68, 0x55, 0x23, 0x19, 0xc0, +0xef, 0xde, 0x39, 0xa9, 0xce, 0xc7, 0x2d, 0xfc, +0xde, 0x7a, 0x52, 0xd9, 0x1c, 0x0a, 0x0d, 0xd5, +0xd6, 0x4a, 0x62, 0xb3, 0x9f, 0xe0, 0xb9, 0x0b, +0x25, 0x7b, 0xe3, 0xcb, 0x39, 0x1c, 0x5d, 0xc7, +0x04, 0xea, 0x34, 0x51, 0x55, 0xb3, 0xaa, 0xf8, +0xbf, 0xa0, 0xe4, 0xf6, 0x97, 0x93, 0x74, 0xf4, +0x3c, 0x8e, 0xa9, 0x49, 0x2c, 0x4d, 0xc3, 0xc8, +0xe6, 0x10, 0x73, 0x11, 0xb4, 0xff, 0x5d, 0xa6, +0x3f, 0xe0, 0x2d, 0xd9, 0x7b, 0x21, 0x9c, 0x22, +0xd6, 0xe8, 0xc5, 0x56, 0x0a, 0xbb, 0x4e, 0xae, +0xab, 0x7d, 0x97, 0x45, 0xa0, 0x65, 0xeb, 0x83, +0xa4, 0x6e, 0x45, 0x59, 0x9c, 0x8b, 0xe0, 0x6d, +0x6d, 0x46, 0x97, 0x92, 0xe6, 0xe8, 0x0d, 0x9e, +0x7f, 0xb2, 0x91, 0x17, 0xbf, 0xd3, 0x53, 0xb8, +0xdd, 0xe8, 0xf8, 0x59, 0xf5, 0xee, 0xe8, 0x6d, +0x12, 0x1b, 0xb6, 0xd0, 0xe0, 0x38, 0xb4, 0x6e, +0x30, 0xd6, 0x05, 0xa0, 0x0c, 0xf6, 0x40, 0xd3, +0x5d, 0xdc, 0xcb, 0xff, 0xe5, 0xdb, 0x2d, 0x49, +0x96, 0xae, 0xce, 0xe3, 0xf1, 0xd4, 0x13, 0xf7, +0x6f, 0x61, 0xf2, 0x5a, 0x8a, 0xc3, 0xc7, 0x42, +0xea, 0xcc, 0xd9, 0x09, 0x75, 0xf8, 0x58, 0x48, +0x1d, 0x9f, 0x8a, 0x33, 0x6d, 0x6e, 0x44, 0x5a, +0x26, 0x4d, 0xd1, 0x18, 0x3d, 0xdb, 0x3d, 0xeb, +0x02, 0xb0, 0x26, 0x5f, 0x3f, 0xff, 0xc3, 0x09, +0xe5, 0x6e, 0xef, 0x42, 0x59, 0x26, 0xd1, 0x1b, +0xb7, 0x88, 0xdf, 0x58, 0x24, 0x13, 0x8d, 0x23, +0x1a, 0xbc, 0x64, 0xfd, 0x1b, 0x48, 0xfa, 0x3c, +0x38, 0xc9, 0x65, 0x7a, 0xe3, 0x11, 0xfe, 0xf8, +0xcb, 0x7d, 0xe2, 0x2b, 0x89, 0x40, 0xe9, 0xc4, +0xeb, 0x61, 0xee, 0xfc, 0x27, 0x68, 0xd9, 0x1c, +0x1b, 0x5b, 0x9b, 0x69, 0xfe, 0xfa, 0x0e, 0x9a, +0x9f, 0xee, 0xa5, 0xbe, 0xf3, 0x61, 0xea, 0x9a, +0xfd, 0x58, 0x0a, 0x36, 0x84, 0xe7, 0xe9, 0x0f, +0xac, 0xef, 0xf6, 0xf7, 0x05, 0xb0, 0xff, 0xb9, +0x3e, 0xf1, 0xc2, 0x4e, 0x93, 0xab, 0x67, 0x2f, +0x92, 0x8d, 0x27, 0xa8, 0xb7, 0x4d, 0x6c, 0x43, +0xc7, 0xb6, 0x4c, 0x8c, 0x64, 0x0a, 0xe3, 0xd3, +0x2b, 0xfc, 0xa8, 0xbb, 0x9e, 0xfd, 0xcf, 0xf5, +0xad, 0x7b, 0xb6, 0xfc, 0x3f, 0x6c, 0x8b, 0x59, +0x04, 0xfd, 0xf9, 0x5e, 0xbb, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddMinMaxCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddMinMaxCursor_png = new wxImage(); + if (!img_ddMinMaxCursor_png || !img_ddMinMaxCursor_png->IsOk()) + { + wxMemoryInputStream img_ddMinMaxCursor_pngIS(ddMinMaxCursor_png_data, sizeof(ddMinMaxCursor_png_data)); + img_ddMinMaxCursor_png->LoadFile(img_ddMinMaxCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddMinMaxCursor_png; +} +#define ddMinMaxCursor_png_img ddMinMaxCursor_png_img() + +static wxBitmap *ddMinMaxCursor_png_bmp() +{ + static wxBitmap *bmp_ddMinMaxCursor_png; + if (!bmp_ddMinMaxCursor_png || !bmp_ddMinMaxCursor_png->IsOk()) + bmp_ddMinMaxCursor_png = new wxBitmap(*ddMinMaxCursor_png_img); + return bmp_ddMinMaxCursor_png; +} +#define ddMinMaxCursor_png_bmp ddMinMaxCursor_png_bmp() + +static wxIcon *ddMinMaxCursor_png_ico() +{ + static wxIcon *ico_ddMinMaxCursor_png; + if (!ico_ddMinMaxCursor_png || !ico_ddMinMaxCursor_png->IsOk()) + { + ico_ddMinMaxCursor_png = new wxIcon(); + ico_ddMinMaxCursor_png->CopyFromBitmap(*ddMinMaxCursor_png_bmp); + } + return ico_ddMinMaxCursor_png; +} +#define ddMinMaxCursor_png_ico ddMinMaxCursor_png_ico() + +#endif // DDMINMAXCURSOR_PNG_H diff --git a/include/images/ddMinimizeTable.png b/include/images/ddMinimizeTable.png new file mode 100644 index 0000000..650264c Binary files /dev/null and b/include/images/ddMinimizeTable.png differ diff --git a/include/images/ddMinimizeTable.pngc b/include/images/ddMinimizeTable.pngc new file mode 100644 index 0000000..0fcb898 --- /dev/null +++ b/include/images/ddMinimizeTable.pngc @@ -0,0 +1,64 @@ +#ifndef DDMINIMIZETABLE_PNG_H +#define DDMINIMIZETABLE_PNG_H + +static const unsigned char ddMinimizeTable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x3b, 0x08, 0x1d, 0x97, 0xae, +0x00, 0x00, 0x00, 0x1f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x18, 0x0e, 0x80, 0x91, +0x81, 0x81, 0x81, 0x61, 0x17, 0x13, 0xff, 0x7f, +0x6c, 0x92, 0x6e, 0xff, 0x3e, 0x32, 0x32, 0x11, +0x32, 0x01, 0x00, 0xba, 0x7c, 0x04, 0x04, 0x04, +0x8d, 0xaa, 0x96, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddMinimizeTable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddMinimizeTable_png = new wxImage(); + if (!img_ddMinimizeTable_png || !img_ddMinimizeTable_png->IsOk()) + { + wxMemoryInputStream img_ddMinimizeTable_pngIS(ddMinimizeTable_png_data, sizeof(ddMinimizeTable_png_data)); + img_ddMinimizeTable_png->LoadFile(img_ddMinimizeTable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddMinimizeTable_png; +} +#define ddMinimizeTable_png_img ddMinimizeTable_png_img() + +static wxBitmap *ddMinimizeTable_png_bmp() +{ + static wxBitmap *bmp_ddMinimizeTable_png; + if (!bmp_ddMinimizeTable_png || !bmp_ddMinimizeTable_png->IsOk()) + bmp_ddMinimizeTable_png = new wxBitmap(*ddMinimizeTable_png_img); + return bmp_ddMinimizeTable_png; +} +#define ddMinimizeTable_png_bmp ddMinimizeTable_png_bmp() + +static wxIcon *ddMinimizeTable_png_ico() +{ + static wxIcon *ico_ddMinimizeTable_png; + if (!ico_ddMinimizeTable_png || !ico_ddMinimizeTable_png->IsOk()) + { + ico_ddMinimizeTable_png = new wxIcon(); + ico_ddMinimizeTable_png->CopyFromBitmap(*ddMinimizeTable_png_bmp); + } + return ico_ddMinimizeTable_png; +} +#define ddMinimizeTable_png_ico ddMinimizeTable_png_ico() + +#endif // DDMINIMIZETABLE_PNG_H diff --git a/include/images/ddRelationshipCursor.png b/include/images/ddRelationshipCursor.png new file mode 100644 index 0000000..73a0078 Binary files /dev/null and b/include/images/ddRelationshipCursor.png differ diff --git a/include/images/ddRelationshipCursor.pngc b/include/images/ddRelationshipCursor.pngc new file mode 100644 index 0000000..99ae2ec --- /dev/null +++ b/include/images/ddRelationshipCursor.pngc @@ -0,0 +1,121 @@ +#ifndef DDRELATIONSHIPCURSOR_PNG_H +#define DDRELATIONSHIPCURSOR_PNG_H + +static const unsigned char ddRelationshipCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x18, 0x81, 0x57, 0xb5, 0x1f, +0x00, 0x00, 0x01, 0xe3, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xed, 0x96, 0xb1, 0x6e, 0xdb, 0x30, +0x10, 0x86, 0xff, 0x3b, 0x51, 0xa5, 0x34, 0xa4, +0x43, 0x97, 0x36, 0x63, 0xb6, 0xa6, 0x0f, 0x50, +0xc0, 0x88, 0x61, 0x6b, 0xf0, 0x93, 0x74, 0x6d, +0x5f, 0x27, 0x4b, 0xb6, 0xac, 0x79, 0x81, 0x0c, +0x59, 0x2c, 0x01, 0x32, 0x2c, 0x64, 0x0f, 0x90, +0x29, 0x43, 0x86, 0x16, 0x2d, 0x8a, 0x00, 0x29, +0x8c, 0xa2, 0x91, 0x4c, 0x66, 0xb0, 0xc4, 0x50, +0x32, 0xa0, 0x8a, 0x8d, 0x63, 0x01, 0x85, 0x0f, +0x20, 0x24, 0x0a, 0x22, 0xf9, 0xf3, 0xff, 0x74, +0x3c, 0x01, 0x80, 0x46, 0x8f, 0xc1, 0xe5, 0x55, +0xf7, 0x2a, 0x40, 0x6b, 0xdd, 0x9b, 0x88, 0xca, +0x81, 0xde, 0x44, 0xb0, 0xdd, 0xe9, 0x43, 0x04, +0x37, 0x1f, 0x6c, 0x5b, 0x84, 0xb0, 0x3b, 0x44, +0x54, 0xd3, 0x02, 0x80, 0xb6, 0x26, 0xa0, 0x5c, +0x9c, 0xb6, 0xfd, 0x0d, 0x90, 0x65, 0xf7, 0x46, +0x16, 0x3f, 0x38, 0xfe, 0xaa, 0xff, 0xc5, 0x81, +0x8d, 0xee, 0xfc, 0xcb, 0xd1, 0x3b, 0xf8, 0xba, +0xc0, 0xfb, 0xf0, 0x1e, 0x6f, 0x65, 0x81, 0xd7, +0x42, 0xe1, 0x95, 0x07, 0x50, 0xb9, 0xd7, 0xd9, +0x37, 0xc2, 0xf9, 0x2d, 0xe1, 0xf2, 0xfb, 0x4a, +0xc0, 0xc6, 0x6d, 0x57, 0x1a, 0xf8, 0xb5, 0xf4, +0x70, 0xf1, 0x63, 0x0f, 0xbf, 0x73, 0x85, 0xc5, +0x83, 0xc2, 0xe2, 0x61, 0xb9, 0x6a, 0xb9, 0xc2, +0xcf, 0x45, 0x81, 0x3f, 0x85, 0x46, 0xbe, 0x54, +0xeb, 0x59, 0xf0, 0xcc, 0xd0, 0xcd, 0xdb, 0x26, +0x0f, 0xd2, 0xf5, 0x1d, 0x0b, 0x57, 0x66, 0x37, +0x9f, 0xf7, 0xa9, 0x7d, 0x61, 0xe0, 0x50, 0xde, +0xe1, 0x50, 0xde, 0x81, 0xde, 0x10, 0x88, 0xd6, +0x9b, 0xe7, 0x79, 0x38, 0xbd, 0x26, 0x9c, 0x5c, +0x95, 0xdf, 0x80, 0x0b, 0xb3, 0xb6, 0x85, 0x6d, +0x01, 0x55, 0x66, 0x35, 0x1b, 0x33, 0x83, 0x99, +0xf1, 0xe9, 0x03, 0xe1, 0xe4, 0x4a, 0xad, 0x04, +0xb8, 0x30, 0xfb, 0x4b, 0x26, 0x99, 0x08, 0xc3, +0x10, 0xcc, 0x8c, 0x38, 0x8e, 0x31, 0x18, 0x0c, +0xc0, 0xcc, 0x98, 0xcf, 0xe7, 0x88, 0xa2, 0x08, +0x9e, 0xe7, 0x21, 0xcf, 0xf3, 0xe6, 0x41, 0xd4, +0x8d, 0x59, 0x4b, 0x3a, 0x9b, 0xe1, 0x44, 0x84, +0x38, 0x8e, 0xc1, 0xcc, 0x35, 0x27, 0x00, 0x98, +0xe7, 0xc3, 0xe1, 0xf0, 0x49, 0x80, 0x0b, 0xb3, +0x2e, 0xe7, 0x4a, 0x10, 0x04, 0x88, 0xa2, 0x08, +0x42, 0x88, 0xda, 0x3c, 0x93, 0xc9, 0xa4, 0x86, +0x01, 0xb8, 0x5f, 0x65, 0x41, 0x37, 0x66, 0x6c, +0x5b, 0xa5, 0xdb, 0xea, 0x05, 0x11, 0x21, 0x08, +0x02, 0xf8, 0xbe, 0x8f, 0xd9, 0x6c, 0x66, 0xe6, +0x49, 0xd3, 0x14, 0x42, 0x08, 0xf8, 0xbe, 0x6f, +0x1c, 0x61, 0x9b, 0x59, 0x18, 0x86, 0xc8, 0xb2, +0xcc, 0x0c, 0xc8, 0xb2, 0x0c, 0x52, 0x4a, 0x48, +0x29, 0xed, 0x3a, 0x41, 0x8d, 0xb6, 0x5e, 0xe1, +0x4a, 0xf6, 0x49, 0x92, 0x98, 0xbe, 0x8d, 0x60, +0x3a, 0x9d, 0x9a, 0xbe, 0x70, 0x65, 0xd6, 0xa9, +0xc4, 0x96, 0xef, 0x57, 0xee, 0x55, 0xf3, 0x8d, +0x46, 0x23, 0xcb, 0x7e, 0xeb, 0x28, 0x76, 0x61, +0xd6, 0x25, 0x3e, 0x9e, 0x15, 0x6e, 0xb5, 0xa0, +0x62, 0x46, 0x44, 0x48, 0x92, 0xc4, 0xa8, 0x4f, +0xd3, 0xd4, 0xa4, 0x8d, 0x52, 0xea, 0x39, 0x07, +0x55, 0xbb, 0x80, 0x8a, 0x59, 0x65, 0x4d, 0x93, +0x19, 0x33, 0x63, 0x3c, 0x1e, 0xbf, 0xdc, 0xff, +0x80, 0x0b, 0xb3, 0x17, 0x11, 0xe0, 0xc2, 0x6c, +0x17, 0xbb, 0xd8, 0xc5, 0x7f, 0x17, 0x8f, 0x12, +0xbf, 0xd0, 0x01, 0xb8, 0x54, 0xfe, 0x54, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddRelationshipCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddRelationshipCursor_png = new wxImage(); + if (!img_ddRelationshipCursor_png || !img_ddRelationshipCursor_png->IsOk()) + { + wxMemoryInputStream img_ddRelationshipCursor_pngIS(ddRelationshipCursor_png_data, sizeof(ddRelationshipCursor_png_data)); + img_ddRelationshipCursor_png->LoadFile(img_ddRelationshipCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRelationshipCursor_png; +} +#define ddRelationshipCursor_png_img ddRelationshipCursor_png_img() + +static wxBitmap *ddRelationshipCursor_png_bmp() +{ + static wxBitmap *bmp_ddRelationshipCursor_png; + if (!bmp_ddRelationshipCursor_png || !bmp_ddRelationshipCursor_png->IsOk()) + bmp_ddRelationshipCursor_png = new wxBitmap(*ddRelationshipCursor_png_img); + return bmp_ddRelationshipCursor_png; +} +#define ddRelationshipCursor_png_bmp ddRelationshipCursor_png_bmp() + +static wxIcon *ddRelationshipCursor_png_ico() +{ + static wxIcon *ico_ddRelationshipCursor_png; + if (!ico_ddRelationshipCursor_png || !ico_ddRelationshipCursor_png->IsOk()) + { + ico_ddRelationshipCursor_png = new wxIcon(); + ico_ddRelationshipCursor_png->CopyFromBitmap(*ddRelationshipCursor_png_bmp); + } + return ico_ddRelationshipCursor_png; +} +#define ddRelationshipCursor_png_ico ddRelationshipCursor_png_ico() + +#endif // DDRELATIONSHIPCURSOR_PNG_H diff --git a/include/images/ddRemoveColumn.png b/include/images/ddRemoveColumn.png new file mode 100644 index 0000000..eaf3e3b Binary files /dev/null and b/include/images/ddRemoveColumn.png differ diff --git a/include/images/ddRemoveColumn.pngc b/include/images/ddRemoveColumn.pngc new file mode 100644 index 0000000..0031ae2 --- /dev/null +++ b/include/images/ddRemoveColumn.pngc @@ -0,0 +1,63 @@ +#ifndef DDREMOVECOLUMN_PNG_H +#define DDREMOVECOLUMN_PNG_H + +static const unsigned char ddRemoveColumn_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x02, 0x7c, 0x35, 0x4c, 0x65, +0x00, 0x00, 0x00, 0x17, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xa0, 0x39, 0x60, 0xf4, +0x8a, 0x79, 0xfc, 0x1f, 0x9f, 0x02, 0x26, 0x86, +0x81, 0x07, 0x00, 0x9c, 0xc5, 0x02, 0x8c, 0xd8, +0x74, 0x1f, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddRemoveColumn_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddRemoveColumn_png = new wxImage(); + if (!img_ddRemoveColumn_png || !img_ddRemoveColumn_png->IsOk()) + { + wxMemoryInputStream img_ddRemoveColumn_pngIS(ddRemoveColumn_png_data, sizeof(ddRemoveColumn_png_data)); + img_ddRemoveColumn_png->LoadFile(img_ddRemoveColumn_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveColumn_png; +} +#define ddRemoveColumn_png_img ddRemoveColumn_png_img() + +static wxBitmap *ddRemoveColumn_png_bmp() +{ + static wxBitmap *bmp_ddRemoveColumn_png; + if (!bmp_ddRemoveColumn_png || !bmp_ddRemoveColumn_png->IsOk()) + bmp_ddRemoveColumn_png = new wxBitmap(*ddRemoveColumn_png_img); + return bmp_ddRemoveColumn_png; +} +#define ddRemoveColumn_png_bmp ddRemoveColumn_png_bmp() + +static wxIcon *ddRemoveColumn_png_ico() +{ + static wxIcon *ico_ddRemoveColumn_png; + if (!ico_ddRemoveColumn_png || !ico_ddRemoveColumn_png->IsOk()) + { + ico_ddRemoveColumn_png = new wxIcon(); + ico_ddRemoveColumn_png->CopyFromBitmap(*ddRemoveColumn_png_bmp); + } + return ico_ddRemoveColumn_png; +} +#define ddRemoveColumn_png_ico ddRemoveColumn_png_ico() + +#endif // DDREMOVECOLUMN_PNG_H diff --git a/include/images/ddRemoveColumnCursor.png b/include/images/ddRemoveColumnCursor.png new file mode 100644 index 0000000..166ac7b Binary files /dev/null and b/include/images/ddRemoveColumnCursor.png differ diff --git a/include/images/ddRemoveColumnCursor.pngc b/include/images/ddRemoveColumnCursor.pngc new file mode 100644 index 0000000..55d83bb --- /dev/null +++ b/include/images/ddRemoveColumnCursor.pngc @@ -0,0 +1,138 @@ +#ifndef DDREMOVECOLUMNCURSOR_PNG_H +#define DDREMOVECOLUMNCURSOR_PNG_H + +static const unsigned char ddRemoveColumnCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x0d, 0xec, 0x8a, 0x51, 0xf4, +0x00, 0x00, 0x02, 0x6f, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xed, 0x94, 0xc1, 0x4b, 0x93, 0x71, +0x18, 0xc7, 0x3f, 0xbf, 0x77, 0x63, 0xef, 0x04, +0x3b, 0x6b, 0x10, 0xd4, 0x48, 0x02, 0x5d, 0x08, +0x81, 0x86, 0x98, 0x97, 0x8a, 0x18, 0x54, 0x17, +0x15, 0xdd, 0x21, 0x08, 0x1c, 0x5d, 0x5e, 0x82, +0xf2, 0x10, 0x4a, 0x18, 0xe6, 0x59, 0x3a, 0x94, +0x61, 0xbb, 0x48, 0x96, 0x14, 0xf8, 0x1f, 0xa8, +0x2c, 0x61, 0x22, 0x83, 0x77, 0x74, 0x30, 0xbc, +0xac, 0x20, 0xcd, 0xb7, 0x43, 0x76, 0x09, 0x09, +0x24, 0xdf, 0xf7, 0xdd, 0xda, 0xd3, 0xc1, 0x6d, +0xa8, 0x07, 0xdb, 0xe6, 0xe6, 0x20, 0xfa, 0xc2, +0xcb, 0xcb, 0xef, 0x7d, 0x0f, 0xdf, 0xcf, 0xf3, +0x3c, 0xbf, 0xef, 0x03, 0x20, 0xd4, 0x50, 0x5a, +0xee, 0x2d, 0x35, 0x05, 0x10, 0x91, 0x9a, 0x41, +0xe4, 0x3b, 0x50, 0x33, 0x08, 0x6d, 0xef, 0xa1, +0x16, 0x10, 0xda, 0xc1, 0x0f, 0xc7, 0x0d, 0xe1, +0xdd, 0x7b, 0x50, 0x4a, 0xed, 0x63, 0x01, 0xd4, +0xb1, 0x01, 0xe4, 0xcc, 0x55, 0x2d, 0x2e, 0xa2, +0xd4, 0x32, 0x86, 0xf9, 0x0e, 0x14, 0x5d, 0x79, +0x60, 0x72, 0xf3, 0x50, 0xd8, 0xfb, 0xed, 0xf5, +0x0c, 0x5e, 0x3c, 0xa1, 0x4a, 0x01, 0x28, 0xc9, +0xfc, 0xf9, 0x65, 0x9d, 0x66, 0x7d, 0xab, 0x30, +0x36, 0xa5, 0x14, 0x3e, 0x9f, 0x0f, 0xa5, 0x14, +0xaf, 0x3f, 0x29, 0x9e, 0xbd, 0xdf, 0x3e, 0x5a, +0x0a, 0xfe, 0xa6, 0x66, 0x7d, 0x8b, 0x64, 0x32, +0x49, 0x5d, 0x5d, 0x5d, 0xe1, 0xd1, 0x75, 0x1d, +0xd3, 0x34, 0x89, 0xb4, 0x68, 0x47, 0x4b, 0x41, +0x29, 0x5a, 0x5e, 0x5e, 0x46, 0x44, 0x50, 0x4a, +0xe1, 0xf5, 0x7a, 0xd1, 0x34, 0xed, 0x60, 0x8a, +0xaa, 0x03, 0xa0, 0x94, 0xa2, 0xb3, 0xb3, 0xb3, +0x60, 0xa6, 0x94, 0x42, 0xd7, 0x75, 0x6c, 0xdb, +0x66, 0x67, 0x67, 0x07, 0xf0, 0x55, 0x77, 0x04, +0x1e, 0x8f, 0x87, 0x64, 0x32, 0x89, 0xdf, 0xef, +0xc7, 0xef, 0xf7, 0xa3, 0xeb, 0x3a, 0x00, 0xa6, +0x69, 0x56, 0x66, 0x13, 0x16, 0xab, 0x78, 0x3c, +0xce, 0xb7, 0x91, 0x51, 0x3e, 0x37, 0x34, 0xf0, +0xf5, 0xe1, 0xa3, 0x7d, 0xff, 0xd6, 0x0c, 0x43, +0x12, 0x20, 0x6b, 0x86, 0x51, 0xd9, 0x78, 0x07, +0x26, 0x37, 0xc5, 0xb2, 0x2c, 0xb1, 0x2c, 0x4b, +0xc6, 0x02, 0x21, 0x49, 0x80, 0xfc, 0x1a, 0x1e, +0x96, 0x04, 0xc8, 0x58, 0x20, 0x24, 0x96, 0x65, +0xc9, 0x6c, 0x5b, 0xbb, 0x24, 0x40, 0x7e, 0x86, +0xc3, 0x45, 0x41, 0xa8, 0x52, 0x01, 0xe2, 0x37, +0x5d, 0x4c, 0xd3, 0xe4, 0x54, 0x38, 0xcc, 0x85, +0xa1, 0x21, 0xc8, 0x64, 0x90, 0x4c, 0x86, 0x0f, +0x13, 0x13, 0xfc, 0xbe, 0x7d, 0x07, 0xcf, 0xcc, +0x14, 0xe7, 0xfb, 0xfb, 0xc9, 0x3a, 0x0e, 0xe2, +0xb8, 0xa4, 0xe6, 0xe7, 0xb8, 0x74, 0x88, 0x4f, +0xd9, 0x23, 0x88, 0x05, 0x42, 0xac, 0x8c, 0x8f, +0x23, 0xe9, 0x34, 0xe2, 0xba, 0xb4, 0x46, 0x22, +0x78, 0x66, 0xa6, 0x08, 0xf6, 0xf5, 0x91, 0xb5, +0x1d, 0xc4, 0x71, 0x48, 0xcd, 0xcf, 0xd1, 0x68, +0x18, 0x54, 0xb4, 0x03, 0x89, 0xee, 0xdd, 0xe8, +0x69, 0x9a, 0xc6, 0xfa, 0xf0, 0x08, 0xd9, 0x57, +0x53, 0xb4, 0x0e, 0x0c, 0x90, 0x75, 0x5d, 0x24, +0x57, 0xb5, 0xb8, 0x0e, 0xa9, 0x85, 0x05, 0x1a, +0x0d, 0x83, 0xb3, 0xd1, 0xa8, 0xaa, 0xe8, 0x25, +0x54, 0x4a, 0x61, 0x9a, 0x26, 0xba, 0xae, 0xd3, +0xfc, 0xf4, 0x09, 0xb1, 0x40, 0x88, 0xd5, 0xe9, +0x69, 0x24, 0x57, 0xb5, 0x38, 0x76, 0xd1, 0xe6, +0x65, 0x01, 0xe4, 0x17, 0xce, 0xd2, 0xd2, 0x12, +0xab, 0xf7, 0x1e, 0x70, 0xed, 0xcb, 0x02, 0xc1, +0xde, 0x5e, 0xc4, 0xb1, 0x11, 0xdb, 0x26, 0x6b, +0x3b, 0x9c, 0xeb, 0xe8, 0xe0, 0x7b, 0x34, 0x4a, +0x31, 0x29, 0x28, 0x0b, 0xa0, 0xab, 0xab, 0x8b, +0x95, 0xc1, 0x17, 0xbb, 0x33, 0xef, 0xe9, 0x29, +0x18, 0xa7, 0x62, 0xb1, 0x5d, 0x10, 0xc7, 0xa1, +0x29, 0x18, 0x2c, 0x0a, 0x42, 0x95, 0x13, 0x45, +0x80, 0x37, 0x77, 0x4f, 0x12, 0xec, 0xee, 0x2e, +0xdc, 0xf6, 0x8f, 0x8b, 0xef, 0xd8, 0xbe, 0x15, +0xa1, 0xfe, 0xed, 0x4b, 0x9a, 0x5a, 0x82, 0x48, +0xda, 0x45, 0xd2, 0x69, 0xd6, 0x37, 0x36, 0x0e, +0x4d, 0x41, 0xd9, 0xca, 0xe7, 0xfd, 0xc7, 0x95, +0xab, 0x92, 0x00, 0x99, 0x6d, 0x6b, 0x97, 0xd1, +0xc7, 0x63, 0xb2, 0x78, 0xfd, 0x86, 0x24, 0x40, +0x36, 0x4f, 0x9f, 0xa9, 0xce, 0x32, 0x2a, 0x66, +0xe3, 0x55, 0x6d, 0x13, 0xfe, 0xd7, 0x7f, 0xfd, +0x93, 0xfa, 0x03, 0x61, 0x32, 0x34, 0xbb, 0x2e, +0xd2, 0xbf, 0x18, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddRemoveColumnCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddRemoveColumnCursor_png = new wxImage(); + if (!img_ddRemoveColumnCursor_png || !img_ddRemoveColumnCursor_png->IsOk()) + { + wxMemoryInputStream img_ddRemoveColumnCursor_pngIS(ddRemoveColumnCursor_png_data, sizeof(ddRemoveColumnCursor_png_data)); + img_ddRemoveColumnCursor_png->LoadFile(img_ddRemoveColumnCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveColumnCursor_png; +} +#define ddRemoveColumnCursor_png_img ddRemoveColumnCursor_png_img() + +static wxBitmap *ddRemoveColumnCursor_png_bmp() +{ + static wxBitmap *bmp_ddRemoveColumnCursor_png; + if (!bmp_ddRemoveColumnCursor_png || !bmp_ddRemoveColumnCursor_png->IsOk()) + bmp_ddRemoveColumnCursor_png = new wxBitmap(*ddRemoveColumnCursor_png_img); + return bmp_ddRemoveColumnCursor_png; +} +#define ddRemoveColumnCursor_png_bmp ddRemoveColumnCursor_png_bmp() + +static wxIcon *ddRemoveColumnCursor_png_ico() +{ + static wxIcon *ico_ddRemoveColumnCursor_png; + if (!ico_ddRemoveColumnCursor_png || !ico_ddRemoveColumnCursor_png->IsOk()) + { + ico_ddRemoveColumnCursor_png = new wxIcon(); + ico_ddRemoveColumnCursor_png->CopyFromBitmap(*ddRemoveColumnCursor_png_bmp); + } + return ico_ddRemoveColumnCursor_png; +} +#define ddRemoveColumnCursor_png_ico ddRemoveColumnCursor_png_ico() + +#endif // DDREMOVECOLUMNCURSOR_PNG_H diff --git a/include/images/ddRemoveTable.png b/include/images/ddRemoveTable.png new file mode 100644 index 0000000..8d6aedb Binary files /dev/null and b/include/images/ddRemoveTable.png differ diff --git a/include/images/ddRemoveTable.pngc b/include/images/ddRemoveTable.pngc new file mode 100644 index 0000000..c309428 --- /dev/null +++ b/include/images/ddRemoveTable.pngc @@ -0,0 +1,67 @@ +#ifndef DDREMOVETABLE_PNG_H +#define DDREMOVETABLE_PNG_H + +static const unsigned char ddRemoveTable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x20, 0x24, 0xb7, 0x23, 0xf8, 0xd9, +0x00, 0x00, 0x00, 0x32, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x60, 0x60, 0x60, 0xd8, +0xc5, 0xc4, 0xff, 0x7f, 0x17, 0x13, 0xff, 0x7f, +0x06, 0x28, 0x40, 0xe7, 0xc3, 0x05, 0xb1, 0xb1, +0x31, 0x14, 0xa1, 0x4b, 0x32, 0x31, 0x10, 0x00, +0x04, 0x15, 0x10, 0x74, 0x03, 0x13, 0x2e, 0x47, +0xe1, 0x74, 0x28, 0x3a, 0x00, 0x00, 0x4b, 0xf4, +0x15, 0x7f, 0xf9, 0xb6, 0x68, 0x89, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddRemoveTable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddRemoveTable_png = new wxImage(); + if (!img_ddRemoveTable_png || !img_ddRemoveTable_png->IsOk()) + { + wxMemoryInputStream img_ddRemoveTable_pngIS(ddRemoveTable_png_data, sizeof(ddRemoveTable_png_data)); + img_ddRemoveTable_png->LoadFile(img_ddRemoveTable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveTable_png; +} +#define ddRemoveTable_png_img ddRemoveTable_png_img() + +static wxBitmap *ddRemoveTable_png_bmp() +{ + static wxBitmap *bmp_ddRemoveTable_png; + if (!bmp_ddRemoveTable_png || !bmp_ddRemoveTable_png->IsOk()) + bmp_ddRemoveTable_png = new wxBitmap(*ddRemoveTable_png_img); + return bmp_ddRemoveTable_png; +} +#define ddRemoveTable_png_bmp ddRemoveTable_png_bmp() + +static wxIcon *ddRemoveTable_png_ico() +{ + static wxIcon *ico_ddRemoveTable_png; + if (!ico_ddRemoveTable_png || !ico_ddRemoveTable_png->IsOk()) + { + ico_ddRemoveTable_png = new wxIcon(); + ico_ddRemoveTable_png->CopyFromBitmap(*ddRemoveTable_png_bmp); + } + return ico_ddRemoveTable_png; +} +#define ddRemoveTable_png_ico ddRemoveTable_png_ico() + +#endif // DDREMOVETABLE_PNG_H diff --git a/include/images/ddRemoveTable2.png b/include/images/ddRemoveTable2.png new file mode 100644 index 0000000..fe9bc97 Binary files /dev/null and b/include/images/ddRemoveTable2.png differ diff --git a/include/images/ddRemoveTable2.pngc b/include/images/ddRemoveTable2.pngc new file mode 100644 index 0000000..775e9e9 --- /dev/null +++ b/include/images/ddRemoveTable2.pngc @@ -0,0 +1,139 @@ +#ifndef DDREMOVETABLE2_PNG_H +#define DDREMOVETABLE2_PNG_H + +static const unsigned char ddRemoveTable2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, +0x08, 0x06, 0x00, 0x00, 0x00, 0xd4, 0xaf, 0x2c, +0xc4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x20, 0x30, 0xad, 0xf9, 0x2c, 0xa4, +0x00, 0x00, 0x02, 0x77, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0x9d, 0x93, 0x4d, 0x48, 0x54, 0x51, +0x18, 0x86, 0x9f, 0x73, 0x67, 0x6e, 0xf7, 0x0e, +0x44, 0x84, 0x9b, 0x46, 0xaa, 0x29, 0x4b, 0x24, +0x1d, 0x31, 0x04, 0x4d, 0x21, 0x30, 0x2c, 0x22, +0xb0, 0x36, 0x6a, 0xea, 0x22, 0x08, 0x94, 0x16, +0x5d, 0x0c, 0xa2, 0x8d, 0xb6, 0x4b, 0x8a, 0x0c, +0x5d, 0xb4, 0xb0, 0x44, 0x08, 0xd1, 0x92, 0xda, +0xb4, 0x71, 0x53, 0xf9, 0x6f, 0xb9, 0x48, 0x34, +0x23, 0xa3, 0x1f, 0xc7, 0xc0, 0xbf, 0x9a, 0x85, +0x12, 0x95, 0x8b, 0x34, 0xe7, 0xfe, 0xcc, 0x3d, +0x2d, 0xc6, 0xae, 0x0d, 0x28, 0x44, 0x1f, 0xbc, +0x70, 0xce, 0xe1, 0x7c, 0xef, 0xf7, 0xbd, 0xdf, +0x7b, 0x8e, 0x48, 0x6b, 0x5d, 0x94, 0xfc, 0x47, +0xcc, 0xd7, 0xa6, 0x0a, 0x00, 0x3f, 0xc0, 0xa5, +0xa3, 0x41, 0x54, 0xe9, 0xb0, 0xd3, 0x6f, 0x11, +0x54, 0x63, 0xec, 0xd2, 0x1c, 0x76, 0xf8, 0x5d, +0xb6, 0xf9, 0x40, 0x90, 0xe0, 0x5f, 0xb1, 0x25, +0xef, 0xbe, 0x2b, 0xf4, 0x44, 0x05, 0x13, 0x5f, +0x37, 0x88, 0xfc, 0x00, 0xae, 0x84, 0x9f, 0x71, +0x1f, 0xdf, 0x4c, 0x8d, 0xf7, 0xb6, 0xca, 0x9a, +0xed, 0xb2, 0x6a, 0xb9, 0xac, 0x5a, 0xf1, 0x04, +0x6c, 0x97, 0x35, 0xd3, 0xe5, 0x97, 0xe3, 0x62, +0x3a, 0x12, 0x3b, 0xee, 0x7a, 0x04, 0xca, 0x06, +0x97, 0xdc, 0x64, 0x95, 0x08, 0x21, 0x41, 0x0a, +0x10, 0x9b, 0x48, 0xf1, 0x03, 0x64, 0x6a, 0xcb, +0x64, 0x6a, 0xcb, 0x89, 0xcb, 0x42, 0x6c, 0x0a, +0x45, 0x51, 0x10, 0x42, 0xf0, 0xe0, 0x93, 0xe0, +0xde, 0x14, 0xc9, 0x1d, 0xfc, 0x6b, 0xb2, 0xa2, +0x28, 0xd4, 0x64, 0x29, 0x49, 0x1d, 0x78, 0xbb, +0x40, 0x20, 0xe0, 0x61, 0x7c, 0x7c, 0x9c, 0x1f, +0x37, 0x1a, 0x89, 0x86, 0x42, 0x2c, 0x5d, 0xbb, +0x8e, 0xa6, 0x69, 0x1e, 0x56, 0x1a, 0x1a, 0x78, +0x58, 0x9b, 0xca, 0xac, 0x61, 0x48, 0x4f, 0x82, +0x10, 0x82, 0x91, 0x91, 0x11, 0xaf, 0x62, 0xe4, +0x6a, 0x07, 0x7b, 0xe6, 0xfb, 0xc8, 0xad, 0xaf, +0x67, 0xb2, 0xa9, 0x89, 0xbb, 0xcf, 0xbf, 0x70, +0xf8, 0xf6, 0x45, 0xcc, 0x9b, 0x8d, 0xec, 0x7d, +0x3d, 0x41, 0x76, 0x55, 0x15, 0x1f, 0xda, 0xda, +0x98, 0x35, 0x0c, 0x29, 0xd2, 0x5a, 0x17, 0xe5, +0x70, 0x49, 0x2c, 0xa9, 0xe5, 0x68, 0x28, 0x44, +0x6e, 0x5d, 0x1d, 0x38, 0x0e, 0xd2, 0x71, 0x78, +0xdb, 0xd2, 0x42, 0xfc, 0xfc, 0x05, 0x7c, 0x5d, +0xed, 0x64, 0x57, 0x56, 0xe2, 0x9a, 0x26, 0xd2, +0xb4, 0x88, 0xf4, 0xf6, 0x24, 0x24, 0x08, 0x21, +0x08, 0x04, 0x02, 0xe8, 0xba, 0x8e, 0xae, 0xeb, +0x0c, 0xa4, 0x9d, 0x62, 0xb2, 0xb9, 0x19, 0x69, +0xdb, 0x48, 0xcb, 0x22, 0xa7, 0xa6, 0x06, 0x5f, +0x57, 0x3b, 0xe1, 0x8a, 0x0a, 0xdc, 0x98, 0x89, +0x34, 0x4d, 0x22, 0xbd, 0x3d, 0x04, 0x0d, 0x03, +0x91, 0xd6, 0xba, 0x28, 0x5f, 0x9c, 0xb1, 0x18, +0x1b, 0x1b, 0xf3, 0x86, 0x05, 0xb0, 0xfb, 0x49, +0x2f, 0xee, 0xfd, 0x76, 0x72, 0xaa, 0xab, 0x71, +0x2d, 0x0b, 0xb9, 0x5e, 0x55, 0x5a, 0x26, 0x91, +0xbe, 0x3e, 0x82, 0x86, 0xc1, 0xc1, 0xb6, 0x36, +0xe1, 0x07, 0x50, 0x55, 0x95, 0xa2, 0xa2, 0x22, +0x14, 0x45, 0xf1, 0x48, 0x44, 0x71, 0x31, 0x77, +0x46, 0xa2, 0xd0, 0xd9, 0x49, 0xb8, 0xfc, 0x2c, +0xd2, 0x5a, 0xaf, 0xdc, 0xdf, 0xef, 0x25, 0x7b, +0x2e, 0x08, 0x21, 0xd0, 0x75, 0x1d, 0x4d, 0xd3, +0x50, 0x55, 0x95, 0xd1, 0xd1, 0x51, 0x3e, 0x5e, +0xa9, 0xe7, 0xe4, 0x7c, 0x1f, 0xe1, 0xf2, 0x72, +0xa4, 0x19, 0x43, 0xc6, 0x62, 0xb8, 0x31, 0x93, +0x8c, 0xc2, 0x42, 0x96, 0xd6, 0x07, 0xe8, 0xb9, +0xa0, 0x28, 0x4a, 0x92, 0x0b, 0x6f, 0x2e, 0xb7, +0x26, 0x92, 0xcb, 0xca, 0x12, 0x89, 0xa6, 0xc5, +0xf4, 0xe0, 0x00, 0x19, 0x05, 0x05, 0x48, 0xcb, +0x22, 0x3d, 0x1c, 0x66, 0xe6, 0x6f, 0x17, 0x5e, +0x55, 0xfa, 0x93, 0x5c, 0x88, 0xa4, 0xa4, 0x10, +0x2e, 0x2d, 0xf5, 0xa6, 0x3d, 0x3d, 0x34, 0xc8, +0xca, 0xb9, 0x1a, 0xb6, 0x3f, 0xea, 0x20, 0x3d, +0x2b, 0x8c, 0xb4, 0x2d, 0xa4, 0x6d, 0x33, 0xb7, +0xb0, 0x90, 0xe8, 0xe0, 0xc8, 0x63, 0x27, 0xe9, +0x75, 0xdd, 0xca, 0xcb, 0x87, 0xee, 0x6e, 0x0e, +0x1d, 0x3f, 0xc1, 0xf4, 0xf0, 0x10, 0xd1, 0xbc, +0x7c, 0xa6, 0xd2, 0x43, 0x1c, 0x2b, 0x39, 0xcd, +0xcc, 0xb3, 0xa7, 0x1c, 0xd8, 0xb7, 0x9f, 0xb9, +0xcf, 0x0b, 0x04, 0x0d, 0x63, 0xeb, 0xff, 0x3e, +0x6b, 0x18, 0xf2, 0x25, 0xc8, 0x3f, 0x5a, 0xb7, +0x3a, 0xff, 0x0d, 0x83, 0x59, 0x25, 0x4a, 0xa1, +0x2d, 0x84, 0x28, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddRemoveTable2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddRemoveTable2_png = new wxImage(); + if (!img_ddRemoveTable2_png || !img_ddRemoveTable2_png->IsOk()) + { + wxMemoryInputStream img_ddRemoveTable2_pngIS(ddRemoveTable2_png_data, sizeof(ddRemoveTable2_png_data)); + img_ddRemoveTable2_png->LoadFile(img_ddRemoveTable2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddRemoveTable2_png; +} +#define ddRemoveTable2_png_img ddRemoveTable2_png_img() + +static wxBitmap *ddRemoveTable2_png_bmp() +{ + static wxBitmap *bmp_ddRemoveTable2_png; + if (!bmp_ddRemoveTable2_png || !bmp_ddRemoveTable2_png->IsOk()) + bmp_ddRemoveTable2_png = new wxBitmap(*ddRemoveTable2_png_img); + return bmp_ddRemoveTable2_png; +} +#define ddRemoveTable2_png_bmp ddRemoveTable2_png_bmp() + +static wxIcon *ddRemoveTable2_png_ico() +{ + static wxIcon *ico_ddRemoveTable2_png; + if (!ico_ddRemoveTable2_png || !ico_ddRemoveTable2_png->IsOk()) + { + ico_ddRemoveTable2_png = new wxIcon(); + ico_ddRemoveTable2_png->CopyFromBitmap(*ddRemoveTable2_png_bmp); + } + return ico_ddRemoveTable2_png; +} +#define ddRemoveTable2_png_ico ddRemoveTable2_png_ico() + +#endif // DDREMOVETABLE2_PNG_H diff --git a/include/images/ddUp.png b/include/images/ddUp.png new file mode 100644 index 0000000..7ae6e44 Binary files /dev/null and b/include/images/ddUp.png differ diff --git a/include/images/ddUp.pngc b/include/images/ddUp.pngc new file mode 100644 index 0000000..c82d8a7 --- /dev/null +++ b/include/images/ddUp.pngc @@ -0,0 +1,79 @@ +#ifndef DDUP_PNG_H +#define DDUP_PNG_H + +static const unsigned char ddUp_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, +0x08, 0x06, 0x00, 0x00, 0x00, 0x11, 0xc7, 0xb4, +0xc5, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x20, 0x0a, 0x6b, 0xf5, 0xf5, 0x16, +0x00, 0x00, 0x00, 0x96, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x40, 0x02, 0xdd, 0x1b, +0x13, 0xff, 0x47, 0xcd, 0x16, 0xfe, 0xdf, 0xbd, +0x31, 0xf1, 0x3f, 0xb2, 0x38, 0x13, 0xb2, 0x82, +0xf3, 0xaf, 0x36, 0x31, 0x14, 0xb9, 0x4c, 0x60, +0x38, 0xff, 0x6a, 0x13, 0x03, 0xb2, 0x42, 0x46, +0x64, 0x05, 0x09, 0x16, 0x79, 0x0c, 0xaf, 0x3f, +0xdd, 0x64, 0x10, 0xe4, 0x91, 0x63, 0x58, 0x72, +0x6a, 0x36, 0x83, 0xa1, 0x98, 0x1f, 0x43, 0xa9, +0xff, 0x7c, 0x46, 0x46, 0x84, 0x82, 0x02, 0x86, +0x27, 0xef, 0xcf, 0x30, 0xfc, 0xf8, 0xf5, 0x8e, +0x81, 0x95, 0x99, 0x8d, 0x41, 0x52, 0x40, 0x97, +0x61, 0xd9, 0x99, 0xc5, 0x0c, 0x86, 0x62, 0x7e, +0x0c, 0x8c, 0x51, 0xb3, 0x85, 0xff, 0x97, 0xb8, +0x4e, 0x61, 0x78, 0xf4, 0xf6, 0x28, 0xc3, 0xbf, +0x7f, 0xbf, 0x19, 0xfe, 0x33, 0xfc, 0x66, 0xf8, +0xf7, 0xef, 0x0f, 0xc3, 0xff, 0xff, 0x7f, 0x18, +0xa4, 0x85, 0x8c, 0x19, 0xa6, 0x1e, 0x6c, 0x63, +0x80, 0x9b, 0x84, 0x0b, 0x18, 0x8a, 0xf9, 0x31, +0x00, 0x00, 0x20, 0xaa, 0x46, 0xd9, 0x6c, 0x0c, +0xfa, 0x19, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddUp_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddUp_png = new wxImage(); + if (!img_ddUp_png || !img_ddUp_png->IsOk()) + { + wxMemoryInputStream img_ddUp_pngIS(ddUp_png_data, sizeof(ddUp_png_data)); + img_ddUp_png->LoadFile(img_ddUp_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddUp_png; +} +#define ddUp_png_img ddUp_png_img() + +static wxBitmap *ddUp_png_bmp() +{ + static wxBitmap *bmp_ddUp_png; + if (!bmp_ddUp_png || !bmp_ddUp_png->IsOk()) + bmp_ddUp_png = new wxBitmap(*ddUp_png_img); + return bmp_ddUp_png; +} +#define ddUp_png_bmp ddUp_png_bmp() + +static wxIcon *ddUp_png_ico() +{ + static wxIcon *ico_ddUp_png; + if (!ico_ddUp_png || !ico_ddUp_png->IsOk()) + { + ico_ddUp_png = new wxIcon(); + ico_ddUp_png->CopyFromBitmap(*ddUp_png_bmp); + } + return ico_ddUp_png; +} +#define ddUp_png_ico ddUp_png_ico() + +#endif // DDUP_PNG_H diff --git a/include/images/ddcancel.png b/include/images/ddcancel.png new file mode 100644 index 0000000..2aa07fc Binary files /dev/null and b/include/images/ddcancel.png differ diff --git a/include/images/ddcancel.pngc b/include/images/ddcancel.pngc new file mode 100644 index 0000000..732f0c4 --- /dev/null +++ b/include/images/ddcancel.pngc @@ -0,0 +1,105 @@ +#ifndef DDCANCEL_PNG_H +#define DDCANCEL_PNG_H + +static const unsigned char ddcancel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x24, 0x10, 0xf2, 0xfb, 0xc9, 0x68, +0x00, 0x00, 0x01, 0x65, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0xdd, 0x92, 0x3d, 0x4b, 0x42, 0x71, +0x14, 0xc6, 0x7f, 0xe9, 0xda, 0x07, 0x70, 0x0a, +0x24, 0x69, 0xe8, 0x86, 0x10, 0x28, 0x08, 0xcd, +0x29, 0x14, 0x0d, 0x66, 0xea, 0x10, 0x48, 0x8a, +0x11, 0xf7, 0x0b, 0xe8, 0xea, 0xec, 0xd8, 0xe2, +0x22, 0x11, 0x42, 0xd0, 0xe6, 0x58, 0xa2, 0x2e, +0xc1, 0xa5, 0xa1, 0xc1, 0x96, 0xb2, 0x21, 0x4b, +0x70, 0x69, 0xea, 0x05, 0x22, 0xee, 0xff, 0x5e, +0xbb, 0xa7, 0xc1, 0x0a, 0xf1, 0x25, 0xda, 0x82, +0x9e, 0xf1, 0xc0, 0xf3, 0x3b, 0x87, 0xe7, 0x39, +0xf0, 0xff, 0xd4, 0xca, 0xee, 0x89, 0x01, 0x72, +0x91, 0xd9, 0x95, 0xe1, 0x79, 0x47, 0xd7, 0xc5, +0x00, 0xe9, 0xe8, 0xba, 0x4c, 0x35, 0x17, 0xbc, +0x11, 0x31, 0x40, 0xde, 0xf2, 0x79, 0x31, 0x40, +0x0a, 0xde, 0x88, 0x00, 0x1c, 0x07, 0x82, 0x62, +0x80, 0xbc, 0x24, 0x93, 0x63, 0x90, 0x99, 0x61, +0x80, 0x01, 0xb2, 0x9c, 0xcb, 0x41, 0xbf, 0x8f, +0xf4, 0xfb, 0x5c, 0xee, 0xef, 0xf3, 0x9e, 0xca, +0xe2, 0xae, 0x94, 0x59, 0x4a, 0x24, 0x70, 0x94, +0x42, 0x94, 0x45, 0xfb, 0xf4, 0x84, 0x95, 0x4f, +0xaf, 0x6b, 0x18, 0x50, 0xf7, 0x46, 0x68, 0x15, +0x8b, 0x88, 0x6d, 0x23, 0x96, 0x85, 0x3f, 0x93, +0xc1, 0x5d, 0x29, 0xa3, 0xc5, 0xe3, 0x38, 0xa6, +0x42, 0x94, 0xa2, 0x7d, 0x7a, 0x82, 0x47, 0xd7, +0x99, 0x78, 0x01, 0xc0, 0xf9, 0x4e, 0x56, 0x9c, +0xc3, 0x32, 0xfe, 0x74, 0x1a, 0xc7, 0xb2, 0x90, +0xcf, 0xad, 0x62, 0x29, 0xda, 0xb5, 0x1a, 0x1e, +0x5d, 0x67, 0xbe, 0x54, 0x9a, 0xf9, 0x31, 0xc8, +0xaf, 0x2c, 0x9e, 0x63, 0x5b, 0xf2, 0xb4, 0xb1, +0x21, 0x8f, 0xe1, 0xf0, 0xd4, 0x00, 0x5d, 0xa3, +0x83, 0xb3, 0x54, 0x56, 0x56, 0xef, 0x6b, 0x68, +0xb1, 0x18, 0xa2, 0x4c, 0xc4, 0x34, 0x71, 0x4c, +0xc5, 0x42, 0x28, 0xc4, 0x43, 0xa9, 0xc4, 0x28, +0xc4, 0x35, 0xba, 0xd9, 0x5d, 0x29, 0xa3, 0x6d, +0x6e, 0x7e, 0x1b, 0xdb, 0xf5, 0xfa, 0x00, 0xa4, +0x14, 0x3e, 0x4d, 0x1b, 0x83, 0x8c, 0xb5, 0xa0, +0x45, 0xa3, 0xdf, 0x69, 0xdf, 0x34, 0x1b, 0xbc, +0x6e, 0x67, 0x98, 0x3d, 0x3a, 0xc0, 0xb7, 0xa8, +0x21, 0xb6, 0x85, 0xd8, 0x36, 0x77, 0xdd, 0xee, +0xe4, 0x16, 0x7a, 0x81, 0x20, 0x57, 0xd5, 0x2a, +0x62, 0x2a, 0x6e, 0x9a, 0x0d, 0x7a, 0x81, 0x20, +0x86, 0x6f, 0x0e, 0x73, 0x6d, 0x9d, 0xdb, 0xeb, +0x2b, 0xc4, 0x1a, 0x98, 0x87, 0x5b, 0x18, 0xd3, +0xb4, 0x8f, 0xfb, 0xd5, 0x27, 0xfe, 0x89, 0x3e, +0x00, 0x1d, 0xcc, 0xd9, 0x6e, 0x0e, 0x9f, 0x6b, +0xff, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddcancel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddcancel_png = new wxImage(); + if (!img_ddcancel_png || !img_ddcancel_png->IsOk()) + { + wxMemoryInputStream img_ddcancel_pngIS(ddcancel_png_data, sizeof(ddcancel_png_data)); + img_ddcancel_png->LoadFile(img_ddcancel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddcancel_png; +} +#define ddcancel_png_img ddcancel_png_img() + +static wxBitmap *ddcancel_png_bmp() +{ + static wxBitmap *bmp_ddcancel_png; + if (!bmp_ddcancel_png || !bmp_ddcancel_png->IsOk()) + bmp_ddcancel_png = new wxBitmap(*ddcancel_png_img); + return bmp_ddcancel_png; +} +#define ddcancel_png_bmp ddcancel_png_bmp() + +static wxIcon *ddcancel_png_ico() +{ + static wxIcon *ico_ddcancel_png; + if (!ico_ddcancel_png || !ico_ddcancel_png->IsOk()) + { + ico_ddcancel_png = new wxIcon(); + ico_ddcancel_png->CopyFromBitmap(*ddcancel_png_bmp); + } + return ico_ddcancel_png; +} +#define ddcancel_png_ico ddcancel_png_ico() + +#endif // DDCANCEL_PNG_H diff --git a/include/images/ddforeignkey.png b/include/images/ddforeignkey.png new file mode 100644 index 0000000..40b70a1 Binary files /dev/null and b/include/images/ddforeignkey.png differ diff --git a/include/images/ddforeignkey.pngc b/include/images/ddforeignkey.pngc new file mode 100644 index 0000000..0b5c086 --- /dev/null +++ b/include/images/ddforeignkey.pngc @@ -0,0 +1,86 @@ +#ifndef DDFOREIGNKEY_PNG_H +#define DDFOREIGNKEY_PNG_H + +static const unsigned char ddforeignkey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x12, 0x53, 0xb4, 0x3e, 0x83, +0x00, 0x00, 0x00, 0xc9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0x8e, 0xb1, 0x89, 0x86, 0x40, +0x18, 0x44, 0xdf, 0xa7, 0x1b, 0x28, 0x08, 0x96, +0x20, 0x82, 0xa1, 0xf9, 0x36, 0x60, 0x68, 0x60, +0x3b, 0x96, 0xa2, 0x99, 0x1d, 0x18, 0x18, 0xda, +0x80, 0xa9, 0x1b, 0xe8, 0x62, 0x60, 0x15, 0xb2, +0xa0, 0xc1, 0x5e, 0x70, 0xf7, 0x83, 0x3f, 0xdc, +0x64, 0xf3, 0x78, 0x0c, 0x23, 0xfc, 0x65, 0x9a, +0x26, 0x9f, 0xe7, 0x39, 0x00, 0xe7, 0x79, 0x52, +0xd7, 0xb5, 0x00, 0xc8, 0x3c, 0xcf, 0xde, 0x39, +0x47, 0x59, 0x96, 0x00, 0x88, 0x08, 0x22, 0x82, +0x31, 0x86, 0x28, 0x8a, 0x08, 0x8c, 0x31, 0x64, +0x59, 0xc6, 0x7d, 0xdf, 0xf4, 0x7d, 0x4f, 0xd7, +0x75, 0x3c, 0xcf, 0x43, 0x9e, 0xe7, 0x18, 0x63, +0x7e, 0x17, 0xae, 0xeb, 0xa2, 0x28, 0x0a, 0x9c, +0x73, 0x04, 0x41, 0x40, 0x92, 0x24, 0x58, 0x6b, +0x89, 0xe3, 0x98, 0xa0, 0xaa, 0x2a, 0x31, 0xc6, +0x70, 0x1c, 0x07, 0x4a, 0x29, 0xc2, 0x30, 0x64, +0xdb, 0x36, 0xd6, 0x75, 0xa5, 0xaa, 0x2a, 0xf9, +0x7c, 0xa4, 0x6d, 0x5b, 0x6f, 0xad, 0xf5, 0xfb, +0xbe, 0xfb, 0xb6, 0x6d, 0xfd, 0x87, 0x2b, 0x5e, +0x79, 0x9e, 0x07, 0xef, 0xfd, 0x1b, 0x11, 0xbc, +0x8b, 0x52, 0x0a, 0x11, 0xf9, 0x5f, 0xd0, 0x5a, +0x33, 0x0c, 0x03, 0x69, 0x9a, 0x7e, 0x09, 0x5f, +0xfa, 0x38, 0x8e, 0x7e, 0x59, 0x16, 0xb4, 0xd6, +0x34, 0x4d, 0x23, 0x00, 0x3f, 0xee, 0x43, 0x52, +0xec, 0xcd, 0x26, 0xd7, 0x2e, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkey_png = new wxImage(); + if (!img_ddforeignkey_png || !img_ddforeignkey_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkey_pngIS(ddforeignkey_png_data, sizeof(ddforeignkey_png_data)); + img_ddforeignkey_png->LoadFile(img_ddforeignkey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkey_png; +} +#define ddforeignkey_png_img ddforeignkey_png_img() + +static wxBitmap *ddforeignkey_png_bmp() +{ + static wxBitmap *bmp_ddforeignkey_png; + if (!bmp_ddforeignkey_png || !bmp_ddforeignkey_png->IsOk()) + bmp_ddforeignkey_png = new wxBitmap(*ddforeignkey_png_img); + return bmp_ddforeignkey_png; +} +#define ddforeignkey_png_bmp ddforeignkey_png_bmp() + +static wxIcon *ddforeignkey_png_ico() +{ + static wxIcon *ico_ddforeignkey_png; + if (!ico_ddforeignkey_png || !ico_ddforeignkey_png->IsOk()) + { + ico_ddforeignkey_png = new wxIcon(); + ico_ddforeignkey_png->CopyFromBitmap(*ddforeignkey_png_bmp); + } + return ico_ddforeignkey_png; +} +#define ddforeignkey_png_ico ddforeignkey_png_ico() + +#endif // DDFOREIGNKEY_PNG_H diff --git a/include/images/ddforeignkeyfromuk.png b/include/images/ddforeignkeyfromuk.png new file mode 100644 index 0000000..c32918a Binary files /dev/null and b/include/images/ddforeignkeyfromuk.png differ diff --git a/include/images/ddforeignkeyfromuk.pngc b/include/images/ddforeignkeyfromuk.pngc new file mode 100644 index 0000000..8270047 --- /dev/null +++ b/include/images/ddforeignkeyfromuk.pngc @@ -0,0 +1,89 @@ +#ifndef DDFOREIGNKEYFROMUK_PNG_H +#define DDFOREIGNKEYFROMUK_PNG_H + +static const unsigned char ddforeignkeyfromuk_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x2f, 0x0b, 0xdc, 0x72, 0x92, +0x00, 0x00, 0x00, 0xe3, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x75, 0x8e, 0xbf, 0x4a, 0xc3, 0x70, +0x14, 0x85, 0xbf, 0x9b, 0xb4, 0x85, 0x04, 0x4a, +0x45, 0x28, 0xf8, 0x00, 0x42, 0x20, 0x83, 0x8b, +0x83, 0xa3, 0x93, 0x2f, 0xd0, 0x6c, 0x75, 0x8b, +0xcf, 0x21, 0xce, 0x75, 0x75, 0xe9, 0xe2, 0xd0, +0x41, 0x47, 0x1f, 0x43, 0x31, 0x44, 0x63, 0x85, +0x4a, 0x9c, 0x8b, 0x54, 0x70, 0xfc, 0x25, 0x6d, +0xfd, 0xf3, 0xf3, 0x3a, 0xc4, 0x48, 0x15, 0xfc, +0xa6, 0xc3, 0xe1, 0x9c, 0x73, 0xaf, 0xf0, 0xcd, +0xe9, 0xd9, 0xb3, 0x86, 0x81, 0x0f, 0xc0, 0xc3, +0xe3, 0x9c, 0x83, 0xfd, 0x0d, 0x01, 0x90, 0xf3, +0x8b, 0x17, 0x5d, 0x2c, 0x2c, 0x3b, 0xdb, 0x6d, +0x00, 0x1c, 0xa9, 0x0a, 0x57, 0xa9, 0xc1, 0xf3, +0x5c, 0x9c, 0x24, 0x2b, 0x08, 0x36, 0x3d, 0x96, +0xcb, 0x4f, 0x8e, 0x8e, 0xa7, 0x1c, 0x0e, 0xa6, +0xbc, 0xbe, 0x29, 0x61, 0xe0, 0x93, 0x64, 0x45, +0xb5, 0x60, 0x0a, 0xcb, 0x56, 0xe8, 0x53, 0xce, +0x2d, 0x22, 0x42, 0xa7, 0xed, 0x32, 0x9e, 0x94, +0xd5, 0x42, 0xbf, 0xd7, 0x95, 0xeb, 0x5b, 0xc3, +0x78, 0x52, 0xd2, 0x6a, 0x39, 0x34, 0x9b, 0xc2, +0xcd, 0x7d, 0xc9, 0x65, 0x5a, 0xd0, 0xef, 0x75, +0xa5, 0xfe, 0x91, 0x28, 0xce, 0x35, 0xbd, 0x33, +0x9a, 0x64, 0x46, 0xa3, 0x38, 0xd7, 0xda, 0x6f, +0xb0, 0xc2, 0xfb, 0x87, 0x62, 0xad, 0xae, 0x5a, +0xbf, 0x03, 0xae, 0x2b, 0xfc, 0xc5, 0xa9, 0xc5, +0xde, 0x6e, 0x87, 0xc1, 0xc9, 0x13, 0xeb, 0x6b, +0x0d, 0xfe, 0x65, 0x38, 0x9a, 0x69, 0x14, 0xe7, +0x3a, 0x1c, 0xcd, 0x7e, 0xee, 0x7c, 0x01, 0xae, +0xdc, 0x55, 0x93, 0x9c, 0x6c, 0x4f, 0x08, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkeyfromuk_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkeyfromuk_png = new wxImage(); + if (!img_ddforeignkeyfromuk_png || !img_ddforeignkeyfromuk_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkeyfromuk_pngIS(ddforeignkeyfromuk_png_data, sizeof(ddforeignkeyfromuk_png_data)); + img_ddforeignkeyfromuk_png->LoadFile(img_ddforeignkeyfromuk_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkeyfromuk_png; +} +#define ddforeignkeyfromuk_png_img ddforeignkeyfromuk_png_img() + +static wxBitmap *ddforeignkeyfromuk_png_bmp() +{ + static wxBitmap *bmp_ddforeignkeyfromuk_png; + if (!bmp_ddforeignkeyfromuk_png || !bmp_ddforeignkeyfromuk_png->IsOk()) + bmp_ddforeignkeyfromuk_png = new wxBitmap(*ddforeignkeyfromuk_png_img); + return bmp_ddforeignkeyfromuk_png; +} +#define ddforeignkeyfromuk_png_bmp ddforeignkeyfromuk_png_bmp() + +static wxIcon *ddforeignkeyfromuk_png_ico() +{ + static wxIcon *ico_ddforeignkeyfromuk_png; + if (!ico_ddforeignkeyfromuk_png || !ico_ddforeignkeyfromuk_png->IsOk()) + { + ico_ddforeignkeyfromuk_png = new wxIcon(); + ico_ddforeignkeyfromuk_png->CopyFromBitmap(*ddforeignkeyfromuk_png_bmp); + } + return ico_ddforeignkeyfromuk_png; +} +#define ddforeignkeyfromuk_png_ico ddforeignkeyfromuk_png_ico() + +#endif // DDFOREIGNKEYFROMUK_PNG_H diff --git a/include/images/ddforeignkeyuniquekey.png b/include/images/ddforeignkeyuniquekey.png new file mode 100644 index 0000000..b4232ad Binary files /dev/null and b/include/images/ddforeignkeyuniquekey.png differ diff --git a/include/images/ddforeignkeyuniquekey.pngc b/include/images/ddforeignkeyuniquekey.pngc new file mode 100644 index 0000000..f2f0bbf --- /dev/null +++ b/include/images/ddforeignkeyuniquekey.pngc @@ -0,0 +1,90 @@ +#ifndef DDFOREIGNKEYUNIQUEKEY_PNG_H +#define DDFOREIGNKEYUNIQUEKEY_PNG_H + +static const unsigned char ddforeignkeyuniquekey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x1c, 0xb4, 0x0c, 0x13, 0x84, +0x00, 0x00, 0x00, 0xe9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0x8e, 0xbd, 0x4a, 0xc4, 0x40, +0x18, 0x45, 0xcf, 0x37, 0x44, 0x58, 0x50, 0xf1, +0x01, 0x16, 0x16, 0x02, 0x16, 0x0a, 0x19, 0x2c, +0x53, 0xa6, 0xc8, 0x94, 0x29, 0x94, 0x08, 0x69, +0x7d, 0x02, 0x5f, 0xc0, 0x74, 0xe2, 0x0b, 0x58, +0x5a, 0x25, 0x85, 0xc5, 0xd6, 0x1b, 0xb0, 0x49, +0xb3, 0x9d, 0xa9, 0xa7, 0x70, 0x21, 0xc5, 0x54, +0x5b, 0xae, 0x60, 0x63, 0x24, 0x44, 0x63, 0xe3, +0xcf, 0x82, 0x9e, 0xee, 0xc2, 0xb9, 0x97, 0x2b, +0x7c, 0x51, 0x55, 0xd5, 0xe8, 0xfb, 0x3e, 0x00, +0xce, 0x39, 0x92, 0x24, 0x11, 0x00, 0xa9, 0xeb, +0x7a, 0xec, 0xba, 0x8e, 0x20, 0x08, 0x00, 0x10, +0x11, 0x44, 0x04, 0x6b, 0x2d, 0x93, 0xc9, 0x04, +0xcf, 0x5a, 0x4b, 0x1c, 0xc7, 0xf4, 0x7d, 0x4f, +0x51, 0x14, 0x00, 0x2c, 0x36, 0x86, 0x2c, 0x3a, +0x64, 0xaf, 0x7d, 0x40, 0x69, 0xad, 0x71, 0xce, +0x31, 0x0c, 0x03, 0x69, 0x9a, 0xb2, 0xd8, 0x18, +0x4e, 0xcf, 0x67, 0xcc, 0x97, 0x6b, 0xb4, 0xd6, +0x28, 0x63, 0x8c, 0x58, 0x6b, 0x69, 0xdb, 0x96, +0x8b, 0xbb, 0x17, 0xae, 0x2e, 0x8f, 0x90, 0x51, +0x00, 0x30, 0xc6, 0x88, 0x02, 0xc8, 0xf3, 0x5c, +0x9a, 0xa6, 0x21, 0x8b, 0xa6, 0xdc, 0xdc, 0xae, +0xe0, 0x5d, 0xbe, 0xbf, 0xa3, 0xd8, 0xe2, 0xec, +0x64, 0xe0, 0x60, 0x77, 0x07, 0xf9, 0x50, 0xff, +0x0b, 0x9e, 0xe7, 0x71, 0x3c, 0xdb, 0x47, 0xf5, +0xde, 0x5f, 0x21, 0x0c, 0x43, 0xca, 0xb2, 0xe4, +0xf1, 0xe9, 0x99, 0xd7, 0xb7, 0xdf, 0x92, 0x6c, +0x2f, 0x5c, 0xdf, 0xaf, 0xc6, 0xf9, 0x72, 0xfd, +0x93, 0xb3, 0x68, 0xca, 0x27, 0xe5, 0x50, 0x4c, +0x2d, 0xad, 0xd7, 0xe4, 0x52, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkeyuniquekey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkeyuniquekey_png = new wxImage(); + if (!img_ddforeignkeyuniquekey_png || !img_ddforeignkeyuniquekey_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkeyuniquekey_pngIS(ddforeignkeyuniquekey_png_data, sizeof(ddforeignkeyuniquekey_png_data)); + img_ddforeignkeyuniquekey_png->LoadFile(img_ddforeignkeyuniquekey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkeyuniquekey_png; +} +#define ddforeignkeyuniquekey_png_img ddforeignkeyuniquekey_png_img() + +static wxBitmap *ddforeignkeyuniquekey_png_bmp() +{ + static wxBitmap *bmp_ddforeignkeyuniquekey_png; + if (!bmp_ddforeignkeyuniquekey_png || !bmp_ddforeignkeyuniquekey_png->IsOk()) + bmp_ddforeignkeyuniquekey_png = new wxBitmap(*ddforeignkeyuniquekey_png_img); + return bmp_ddforeignkeyuniquekey_png; +} +#define ddforeignkeyuniquekey_png_bmp ddforeignkeyuniquekey_png_bmp() + +static wxIcon *ddforeignkeyuniquekey_png_ico() +{ + static wxIcon *ico_ddforeignkeyuniquekey_png; + if (!ico_ddforeignkeyuniquekey_png || !ico_ddforeignkeyuniquekey_png->IsOk()) + { + ico_ddforeignkeyuniquekey_png = new wxIcon(); + ico_ddforeignkeyuniquekey_png->CopyFromBitmap(*ddforeignkeyuniquekey_png_bmp); + } + return ico_ddforeignkeyuniquekey_png; +} +#define ddforeignkeyuniquekey_png_ico ddforeignkeyuniquekey_png_ico() + +#endif // DDFOREIGNKEYUNIQUEKEY_PNG_H diff --git a/include/images/ddforeignkeyuniquekeyfromuk.png b/include/images/ddforeignkeyuniquekeyfromuk.png new file mode 100644 index 0000000..0ea52f9 Binary files /dev/null and b/include/images/ddforeignkeyuniquekeyfromuk.png differ diff --git a/include/images/ddforeignkeyuniquekeyfromuk.pngc b/include/images/ddforeignkeyuniquekeyfromuk.pngc new file mode 100644 index 0000000..746c13d --- /dev/null +++ b/include/images/ddforeignkeyuniquekeyfromuk.pngc @@ -0,0 +1,92 @@ +#ifndef DDFOREIGNKEYUNIQUEKEYFROMUK_PNG_H +#define DDFOREIGNKEYUNIQUEKEYFROMUK_PNG_H + +static const unsigned char ddforeignkeyuniquekeyfromuk_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x23, 0x25, 0xeb, 0x09, 0x9b, 0x8c, +0x00, 0x00, 0x00, 0xf9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0x8e, 0xad, 0x4b, 0xc4, 0x70, +0x1c, 0x87, 0x9f, 0xef, 0xcf, 0x9d, 0x65, 0x8a, +0x5a, 0x56, 0x06, 0x07, 0xb2, 0x85, 0x33, 0x09, +0x8a, 0xc2, 0xd2, 0x64, 0xc1, 0x60, 0x32, 0x08, +0xfb, 0x07, 0x34, 0x5c, 0x31, 0x29, 0x82, 0x62, +0x12, 0x93, 0xed, 0x8a, 0x7f, 0x81, 0xe1, 0x92, +0x26, 0xd3, 0x29, 0x2c, 0xed, 0x10, 0x3c, 0x30, +0x39, 0x61, 0x17, 0x0c, 0x0b, 0x77, 0xe0, 0xcb, +0x81, 0xa8, 0x4c, 0x77, 0x3f, 0x83, 0x6f, 0x07, +0xfa, 0xb4, 0x0f, 0x7c, 0xde, 0x84, 0x2f, 0x0e, +0xa2, 0x44, 0xcf, 0xda, 0x13, 0x00, 0x5c, 0x66, +0x0f, 0x6c, 0xfa, 0x15, 0x01, 0x90, 0xc3, 0x38, +0xd5, 0x4f, 0xf9, 0x3b, 0x81, 0x63, 0x01, 0xa0, +0x44, 0x00, 0x68, 0xa4, 0x1d, 0x46, 0x86, 0x0d, +0x8c, 0xf3, 0x76, 0x97, 0xd5, 0xb9, 0x49, 0x5e, +0xde, 0x0a, 0xb6, 0x8e, 0x63, 0x00, 0x7a, 0x89, +0x49, 0xe8, 0xdb, 0x5c, 0xe8, 0x2e, 0x2a, 0x70, +0x2c, 0x5a, 0xd9, 0x23, 0x79, 0xd1, 0x67, 0x63, +0x71, 0x86, 0x5e, 0x62, 0xb2, 0xbc, 0x52, 0xa6, +0x1e, 0x65, 0x04, 0x8e, 0x85, 0xaa, 0x7a, 0xae, +0x9c, 0xb5, 0x3b, 0xc4, 0xb7, 0x77, 0xec, 0xd6, +0x6e, 0xd8, 0x59, 0xaf, 0x20, 0xfa, 0x73, 0xa6, +0xea, 0xb9, 0xa2, 0x00, 0x1a, 0x6b, 0x0b, 0x72, +0x7a, 0x95, 0x12, 0xfa, 0x36, 0xfb, 0xb5, 0x04, +0x0a, 0xf9, 0xfe, 0x8e, 0x62, 0x00, 0x6f, 0x7e, +0x9c, 0x31, 0xb3, 0x84, 0xf4, 0xd5, 0xff, 0x86, +0xd2, 0x90, 0x62, 0xaa, 0x3c, 0x8a, 0xca, 0x8d, +0xbf, 0x86, 0xa5, 0x69, 0x97, 0xed, 0x93, 0x26, +0xcd, 0xeb, 0x7b, 0x9e, 0x5f, 0x7f, 0x43, 0x32, +0xd8, 0xb0, 0x77, 0x94, 0xe8, 0x7a, 0x94, 0xfd, +0xe8, 0xd0, 0xb7, 0xf9, 0x00, 0x3e, 0x68, 0x4c, +0x08, 0x27, 0xb7, 0xc9, 0xcf, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddforeignkeyuniquekeyfromuk_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddforeignkeyuniquekeyfromuk_png = new wxImage(); + if (!img_ddforeignkeyuniquekeyfromuk_png || !img_ddforeignkeyuniquekeyfromuk_png->IsOk()) + { + wxMemoryInputStream img_ddforeignkeyuniquekeyfromuk_pngIS(ddforeignkeyuniquekeyfromuk_png_data, sizeof(ddforeignkeyuniquekeyfromuk_png_data)); + img_ddforeignkeyuniquekeyfromuk_png->LoadFile(img_ddforeignkeyuniquekeyfromuk_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddforeignkeyuniquekeyfromuk_png; +} +#define ddforeignkeyuniquekeyfromuk_png_img ddforeignkeyuniquekeyfromuk_png_img() + +static wxBitmap *ddforeignkeyuniquekeyfromuk_png_bmp() +{ + static wxBitmap *bmp_ddforeignkeyuniquekeyfromuk_png; + if (!bmp_ddforeignkeyuniquekeyfromuk_png || !bmp_ddforeignkeyuniquekeyfromuk_png->IsOk()) + bmp_ddforeignkeyuniquekeyfromuk_png = new wxBitmap(*ddforeignkeyuniquekeyfromuk_png_img); + return bmp_ddforeignkeyuniquekeyfromuk_png; +} +#define ddforeignkeyuniquekeyfromuk_png_bmp ddforeignkeyuniquekeyfromuk_png_bmp() + +static wxIcon *ddforeignkeyuniquekeyfromuk_png_ico() +{ + static wxIcon *ico_ddforeignkeyuniquekeyfromuk_png; + if (!ico_ddforeignkeyuniquekeyfromuk_png || !ico_ddforeignkeyuniquekeyfromuk_png->IsOk()) + { + ico_ddforeignkeyuniquekeyfromuk_png = new wxIcon(); + ico_ddforeignkeyuniquekeyfromuk_png->CopyFromBitmap(*ddforeignkeyuniquekeyfromuk_png_bmp); + } + return ico_ddforeignkeyuniquekeyfromuk_png; +} +#define ddforeignkeyuniquekeyfromuk_png_ico ddforeignkeyuniquekeyfromuk_png_ico() + +#endif // DDFOREIGNKEYUNIQUEKEYFROMUK_PNG_H diff --git a/include/images/ddgendiagram.png b/include/images/ddgendiagram.png new file mode 100644 index 0000000..eae876c Binary files /dev/null and b/include/images/ddgendiagram.png differ diff --git a/include/images/ddgendiagram.pngc b/include/images/ddgendiagram.pngc new file mode 100644 index 0000000..51353f2 --- /dev/null +++ b/include/images/ddgendiagram.pngc @@ -0,0 +1,86 @@ +#ifndef DDGENDIAGRAM_PNG_H +#define DDGENDIAGRAM_PNG_H + +static const unsigned char ddgendiagram_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x08, +0x08, 0x03, 0x14, 0x11, 0x07, 0xb1, 0x6c, 0x9c, +0x00, 0x00, 0x00, 0xcc, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0x63, 0x60, 0xa0, 0x10, 0x30, 0x32, +0x30, 0x30, 0x30, 0xfc, 0xff, 0xff, 0xff, 0x3f, +0x8a, 0x20, 0x23, 0x23, 0x23, 0xb1, 0x06, 0x30, +0xe1, 0x92, 0x40, 0x37, 0x94, 0x24, 0x17, 0xc0, +0xc4, 0xd1, 0x5c, 0x45, 0x92, 0x0b, 0xfe, 0x23, +0x61, 0x64, 0x57, 0xe1, 0x36, 0xa0, 0x67, 0x53, +0x12, 0x43, 0xf4, 0x1c, 0x11, 0x86, 0x9e, 0x4d, +0x49, 0xb8, 0x9d, 0x8b, 0xc5, 0x15, 0x70, 0x03, +0xce, 0xbf, 0xda, 0xc4, 0x90, 0x6d, 0x5f, 0xc5, +0x70, 0xfe, 0xd5, 0x26, 0xac, 0x86, 0xfc, 0xff, +0xff, 0x1f, 0x8e, 0x71, 0x7a, 0xe1, 0xe9, 0xbb, +0xb3, 0x0c, 0x51, 0x26, 0xb1, 0xd8, 0x0c, 0xf9, +0x8f, 0xcb, 0x5b, 0x4c, 0xa8, 0x4e, 0x64, 0x61, +0x78, 0xfe, 0xe1, 0x32, 0x43, 0x8c, 0x59, 0x2a, +0x4e, 0x97, 0xa0, 0xc7, 0x12, 0x0b, 0xb2, 0x20, +0x2b, 0x0b, 0x1f, 0x83, 0xbc, 0x88, 0x2a, 0xc3, +0x82, 0x13, 0x13, 0x18, 0x0c, 0xc5, 0xfc, 0x18, +0x4a, 0xfc, 0xe6, 0xe1, 0x0b, 0x0f, 0x46, 0xb8, +0x0b, 0x60, 0x1c, 0x39, 0x61, 0x6b, 0x64, 0xcd, +0x8c, 0xd8, 0xa2, 0x13, 0x66, 0x3b, 0x0c, 0xc0, +0x05, 0xbb, 0x37, 0x26, 0xfe, 0x8f, 0x9a, 0x2d, +0xfc, 0xbf, 0x7b, 0x63, 0xe2, 0x7f, 0xe4, 0x00, +0x83, 0x62, 0x9c, 0x80, 0x11, 0x5b, 0x68, 0xe3, +0x48, 0x17, 0xa4, 0x25, 0x65, 0x92, 0x32, 0x13, +0x21, 0x80, 0x2f, 0x5f, 0x50, 0xec, 0x02, 0x00, +0x6e, 0xd6, 0x89, 0xf2, 0x11, 0xb1, 0x48, 0x22, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddgendiagram_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddgendiagram_png = new wxImage(); + if (!img_ddgendiagram_png || !img_ddgendiagram_png->IsOk()) + { + wxMemoryInputStream img_ddgendiagram_pngIS(ddgendiagram_png_data, sizeof(ddgendiagram_png_data)); + img_ddgendiagram_png->LoadFile(img_ddgendiagram_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddgendiagram_png; +} +#define ddgendiagram_png_img ddgendiagram_png_img() + +static wxBitmap *ddgendiagram_png_bmp() +{ + static wxBitmap *bmp_ddgendiagram_png; + if (!bmp_ddgendiagram_png || !bmp_ddgendiagram_png->IsOk()) + bmp_ddgendiagram_png = new wxBitmap(*ddgendiagram_png_img); + return bmp_ddgendiagram_png; +} +#define ddgendiagram_png_bmp ddgendiagram_png_bmp() + +static wxIcon *ddgendiagram_png_ico() +{ + static wxIcon *ico_ddgendiagram_png; + if (!ico_ddgendiagram_png || !ico_ddgendiagram_png->IsOk()) + { + ico_ddgendiagram_png = new wxIcon(); + ico_ddgendiagram_png->CopyFromBitmap(*ddgendiagram_png_bmp); + } + return ico_ddgendiagram_png; +} +#define ddgendiagram_png_ico ddgendiagram_png_ico() + +#endif // DDGENDIAGRAM_PNG_H diff --git a/include/images/ddmodel-32.png b/include/images/ddmodel-32.png new file mode 100644 index 0000000..869c564 Binary files /dev/null and b/include/images/ddmodel-32.png differ diff --git a/include/images/ddmodel-32.pngc b/include/images/ddmodel-32.pngc new file mode 100644 index 0000000..0bc2f41 --- /dev/null +++ b/include/images/ddmodel-32.pngc @@ -0,0 +1,124 @@ +#ifndef DDMODEL_32_PNG_H +#define DDMODEL_32_PNG_H + +static const unsigned char ddmodel_32_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x25, 0xf2, 0x12, 0xaa, 0xcd, +0x00, 0x00, 0x02, 0x00, 0x49, 0x44, 0x41, 0x54, +0x58, 0xc3, 0xe5, 0x96, 0xb1, 0x6e, 0xdb, 0x30, +0x14, 0x45, 0xef, 0x7d, 0x66, 0x4d, 0xb1, 0x73, +0x81, 0x22, 0x43, 0x86, 0x8e, 0x4d, 0xbf, 0xc0, +0x96, 0x0d, 0xf8, 0x5b, 0xba, 0x15, 0xfd, 0x81, +0xfc, 0x48, 0x97, 0x6e, 0x9d, 0x3a, 0x77, 0xed, +0x24, 0x75, 0xa2, 0x3e, 0x20, 0x4b, 0x96, 0x20, +0x08, 0xd0, 0x2e, 0x05, 0x12, 0x34, 0x46, 0x13, +0x4b, 0x96, 0x94, 0x21, 0xb5, 0x2a, 0xc5, 0x92, +0x22, 0xaa, 0xec, 0x14, 0x02, 0x84, 0x29, 0x40, +0xe6, 0xbb, 0x7c, 0x8f, 0xf7, 0xe8, 0x01, 0x4f, +0x7d, 0x10, 0x00, 0x5e, 0x7d, 0xf8, 0x51, 0xba, +0xfc, 0xe9, 0xec, 0xfd, 0x01, 0x7d, 0x09, 0x50, +0xbb, 0xc5, 0xbb, 0xd9, 0x4b, 0x3c, 0x67, 0x86, +0x83, 0xe9, 0x06, 0x87, 0xfa, 0x16, 0x2f, 0x74, +0x8e, 0x40, 0x01, 0x28, 0xef, 0xb5, 0x9d, 0xfd, +0x02, 0xbe, 0x9c, 0x0b, 0xbe, 0x5e, 0xf8, 0xcd, +0x40, 0x25, 0xa0, 0x28, 0x81, 0xcb, 0xfc, 0x19, +0xbe, 0xdf, 0x08, 0xbe, 0xa5, 0x1a, 0xeb, 0x4d, +0x8e, 0xeb, 0x3f, 0x73, 0x9d, 0xe6, 0x58, 0x6f, +0x0a, 0xfc, 0xce, 0x0a, 0xa4, 0xdb, 0xc2, 0xab, +0x00, 0x69, 0x3e, 0x96, 0xed, 0x35, 0x2a, 0x6b, +0x6b, 0xfc, 0xa7, 0x0c, 0xbc, 0x09, 0x2e, 0x71, +0x14, 0x5c, 0xdd, 0x07, 0x22, 0x41, 0x12, 0x93, +0xc9, 0x04, 0x24, 0x21, 0x22, 0x20, 0x89, 0x4f, +0xa7, 0xc4, 0xc7, 0x93, 0x0e, 0xa5, 0x03, 0xee, +0x5a, 0x6f, 0x06, 0x8e, 0x82, 0x2b, 0x18, 0x63, +0x60, 0x8c, 0x41, 0x92, 0x24, 0x95, 0x88, 0x24, +0x49, 0xa0, 0xb5, 0x46, 0x10, 0x04, 0x78, 0xfb, +0x5a, 0xea, 0x1b, 0x0e, 0x9d, 0xc3, 0x32, 0x00, +0x00, 0x51, 0x14, 0x55, 0x81, 0x77, 0x27, 0x07, +0x80, 0x38, 0x8e, 0x21, 0x22, 0x08, 0xc3, 0xd0, +0x35, 0xc3, 0x65, 0xed, 0x97, 0xbd, 0x02, 0x48, +0x62, 0x36, 0x9b, 0x35, 0x04, 0x90, 0x44, 0x18, +0x86, 0x55, 0x09, 0x48, 0x8e, 0x09, 0x8e, 0x3e, +0x11, 0x0d, 0x01, 0xc6, 0x18, 0x90, 0x44, 0x14, +0x45, 0x98, 0xcf, 0xe7, 0x20, 0x09, 0x6b, 0x2d, +0x56, 0xab, 0x15, 0x44, 0x04, 0xdb, 0xed, 0xb6, +0x37, 0xe2, 0x00, 0x9e, 0x94, 0x0f, 0x79, 0xd2, +0x10, 0x10, 0xc7, 0x71, 0xb5, 0x16, 0x91, 0xbd, +0x12, 0x2c, 0x16, 0x8b, 0x47, 0x8f, 0xed, 0xca, +0x93, 0xbd, 0x12, 0xd4, 0xd3, 0x2d, 0x22, 0x58, +0x2e, 0x97, 0x7b, 0x77, 0xa2, 0x6f, 0xb8, 0xf2, +0xa4, 0x12, 0xf0, 0xf9, 0xe7, 0x21, 0xb2, 0x02, +0xb8, 0xcd, 0xfe, 0xbe, 0x78, 0xbd, 0xc9, 0xab, +0x0d, 0xd6, 0x69, 0x8e, 0x9b, 0x2c, 0x1d, 0x59, +0xfe, 0x6e, 0x9e, 0xa8, 0x5d, 0x2d, 0x8e, 0xdb, +0x77, 0x71, 0x66, 0x8f, 0x23, 0x4f, 0x20, 0xbe, +0xc9, 0xe6, 0xc8, 0x93, 0x26, 0x07, 0x5c, 0xfc, +0xdb, 0x37, 0x5c, 0x78, 0xa2, 0xc6, 0xfa, 0xb7, +0x93, 0xb9, 0x8e, 0x3c, 0x51, 0x2d, 0x5e, 0x1e, +0x76, 0xab, 0x3a, 0x7a, 0x03, 0x57, 0x9e, 0x28, +0x1f, 0x5e, 0x7e, 0x28, 0xc0, 0x85, 0x27, 0xca, +0x87, 0x97, 0xdb, 0x4a, 0x30, 0x94, 0x27, 0xca, +0x87, 0x97, 0xeb, 0xc3, 0x95, 0x27, 0xca, 0x87, +0x97, 0xeb, 0xf7, 0xe1, 0xb8, 0xff, 0x44, 0x7c, +0xa4, 0x23, 0x1a, 0xe7, 0x65, 0x2f, 0x1d, 0xd1, +0x3f, 0x78, 0xb9, 0x7e, 0x32, 0x67, 0x6e, 0x28, +0x1f, 0x5e, 0x1e, 0x0b, 0xac, 0xce, 0x12, 0xec, +0xbc, 0x6c, 0x8c, 0x81, 0xb5, 0xb6, 0x0a, 0x68, +0xad, 0xc5, 0x74, 0x3a, 0x85, 0xd6, 0xba, 0xed, +0xcb, 0x58, 0xa7, 0x67, 0xdb, 0x74, 0xcb, 0xc0, +0x88, 0xde, 0x80, 0xde, 0x4b, 0xe0, 0xd0, 0x1b, +0xd0, 0xeb, 0x25, 0x74, 0xf4, 0x32, 0x7d, 0x08, +0x79, 0xba, 0xe3, 0x0e, 0xc2, 0x4f, 0x5a, 0xf3, +0x23, 0xd7, 0xc2, 0xd0, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddmodel_32_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddmodel_32_png = new wxImage(); + if (!img_ddmodel_32_png || !img_ddmodel_32_png->IsOk()) + { + wxMemoryInputStream img_ddmodel_32_pngIS(ddmodel_32_png_data, sizeof(ddmodel_32_png_data)); + img_ddmodel_32_png->LoadFile(img_ddmodel_32_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddmodel_32_png; +} +#define ddmodel_32_png_img ddmodel_32_png_img() + +static wxBitmap *ddmodel_32_png_bmp() +{ + static wxBitmap *bmp_ddmodel_32_png; + if (!bmp_ddmodel_32_png || !bmp_ddmodel_32_png->IsOk()) + bmp_ddmodel_32_png = new wxBitmap(*ddmodel_32_png_img); + return bmp_ddmodel_32_png; +} +#define ddmodel_32_png_bmp ddmodel_32_png_bmp() + +static wxIcon *ddmodel_32_png_ico() +{ + static wxIcon *ico_ddmodel_32_png; + if (!ico_ddmodel_32_png || !ico_ddmodel_32_png->IsOk()) + { + ico_ddmodel_32_png = new wxIcon(); + ico_ddmodel_32_png->CopyFromBitmap(*ddmodel_32_png_bmp); + } + return ico_ddmodel_32_png; +} +#define ddmodel_32_png_ico ddmodel_32_png_ico() + +#endif // DDMODEL_32_PNG_H diff --git a/include/images/ddnewdiagram.png b/include/images/ddnewdiagram.png new file mode 100644 index 0000000..fde9947 Binary files /dev/null and b/include/images/ddnewdiagram.png differ diff --git a/include/images/ddnewdiagram.pngc b/include/images/ddnewdiagram.pngc new file mode 100644 index 0000000..ce5cd8e --- /dev/null +++ b/include/images/ddnewdiagram.pngc @@ -0,0 +1,89 @@ +#ifndef DDNEWDIAGRAM_PNG_H +#define DDNEWDIAGRAM_PNG_H + +static const unsigned char ddnewdiagram_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x08, +0x08, 0x02, 0x3b, 0x12, 0x8d, 0x66, 0x6f, 0x7c, +0x00, 0x00, 0x00, 0xe3, 0x49, 0x44, 0x41, 0x54, +0x38, 0xcb, 0xd5, 0x92, 0xb1, 0x6a, 0x02, 0x41, +0x10, 0x86, 0xbf, 0x0b, 0x3e, 0x8d, 0x56, 0x16, +0x72, 0x20, 0x16, 0x79, 0x8a, 0x83, 0x90, 0xca, +0xce, 0x42, 0xd8, 0x85, 0x14, 0x79, 0x8a, 0xf4, +0x36, 0x36, 0xa6, 0xf0, 0xb4, 0xb0, 0x49, 0x93, +0xc2, 0x4e, 0xb8, 0x53, 0x7c, 0x03, 0x9f, 0xc1, +0x22, 0xdd, 0x0d, 0xec, 0xc0, 0x58, 0x29, 0x22, +0x77, 0xb9, 0xbb, 0x74, 0xf9, 0xbb, 0x1d, 0x66, +0xff, 0x99, 0x6f, 0xf7, 0x87, 0x7f, 0xaf, 0xe8, +0xb1, 0x60, 0x66, 0x56, 0xda, 0x18, 0x45, 0x51, +0x59, 0xfd, 0xa9, 0xcd, 0xb4, 0x32, 0xf3, 0x56, +0x06, 0x65, 0x5b, 0x34, 0x46, 0xa8, 0x32, 0xea, +0xd4, 0x35, 0xa7, 0xab, 0x35, 0xfb, 0x3c, 0x03, +0x60, 0x10, 0x0f, 0x79, 0x7d, 0x49, 0xda, 0x21, +0xec, 0xf3, 0x8c, 0x9f, 0xf7, 0x29, 0xe7, 0xb7, +0x09, 0xc7, 0x43, 0xd6, 0xfc, 0x11, 0xd3, 0xd5, +0x1a, 0xef, 0x3d, 0x00, 0x22, 0x82, 0x88, 0x00, +0xe0, 0xbd, 0x67, 0xbe, 0x58, 0x5a, 0x2d, 0xc2, +0x75, 0xb2, 0x88, 0xa0, 0xaa, 0x84, 0x10, 0x38, +0x8d, 0x13, 0x8a, 0xa2, 0x80, 0xf4, 0xab, 0x19, +0x82, 0xaa, 0xde, 0x2e, 0x87, 0x10, 0x6e, 0xe7, +0x7b, 0x55, 0x6e, 0x30, 0x88, 0x87, 0x1c, 0x3f, +0x66, 0x00, 0x9c, 0xc6, 0x09, 0xaa, 0x4a, 0xf7, +0x73, 0x03, 0x40, 0xaf, 0x1f, 0xff, 0x1e, 0x96, +0x7b, 0x39, 0xe7, 0xec, 0x39, 0xdf, 0xda, 0x68, +0xf7, 0x6d, 0xce, 0x39, 0x7b, 0xfc, 0xe6, 0x4e, +0x5d, 0x58, 0xe6, 0x8b, 0xa5, 0x5d, 0x99, 0x7b, +0xfd, 0xb8, 0x32, 0xd2, 0x7f, 0xd6, 0x05, 0x52, +0xb6, 0x78, 0x2e, 0xf3, 0x44, 0x0b, 0xb7, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddnewdiagram_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddnewdiagram_png = new wxImage(); + if (!img_ddnewdiagram_png || !img_ddnewdiagram_png->IsOk()) + { + wxMemoryInputStream img_ddnewdiagram_pngIS(ddnewdiagram_png_data, sizeof(ddnewdiagram_png_data)); + img_ddnewdiagram_png->LoadFile(img_ddnewdiagram_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddnewdiagram_png; +} +#define ddnewdiagram_png_img ddnewdiagram_png_img() + +static wxBitmap *ddnewdiagram_png_bmp() +{ + static wxBitmap *bmp_ddnewdiagram_png; + if (!bmp_ddnewdiagram_png || !bmp_ddnewdiagram_png->IsOk()) + bmp_ddnewdiagram_png = new wxBitmap(*ddnewdiagram_png_img); + return bmp_ddnewdiagram_png; +} +#define ddnewdiagram_png_bmp ddnewdiagram_png_bmp() + +static wxIcon *ddnewdiagram_png_ico() +{ + static wxIcon *ico_ddnewdiagram_png; + if (!ico_ddnewdiagram_png || !ico_ddnewdiagram_png->IsOk()) + { + ico_ddnewdiagram_png = new wxIcon(); + ico_ddnewdiagram_png->CopyFromBitmap(*ddnewdiagram_png_bmp); + } + return ico_ddnewdiagram_png; +} +#define ddnewdiagram_png_ico ddnewdiagram_png_ico() + +#endif // DDNEWDIAGRAM_PNG_H diff --git a/include/images/ddnotnull.png b/include/images/ddnotnull.png new file mode 100644 index 0000000..b58fccf Binary files /dev/null and b/include/images/ddnotnull.png differ diff --git a/include/images/ddnotnull.pngc b/include/images/ddnotnull.pngc new file mode 100644 index 0000000..e1ad57a --- /dev/null +++ b/include/images/ddnotnull.pngc @@ -0,0 +1,66 @@ +#ifndef DDNOTNULL_PNG_H +#define DDNOTNULL_PNG_H + +static const unsigned char ddnotnull_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x1a, 0x44, 0x74, 0x87, 0xf0, +0x00, 0x00, 0x00, 0x30, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x40, 0x05, 0xff, 0xa1, +0x18, 0x0e, 0x98, 0xd0, 0x05, 0xb0, 0x68, 0x40, +0x61, 0xfc, 0x47, 0x63, 0x33, 0x30, 0x62, 0x53, +0x0d, 0x05, 0x8c, 0x30, 0x2b, 0x88, 0x02, 0x38, +0xad, 0x40, 0x37, 0xfa, 0x3f, 0x16, 0x3e, 0x7e, +0x6f, 0x52, 0x0e, 0x00, 0x00, 0xa5, 0x12, 0xf4, +0xcc, 0xcb, 0xff, 0x17, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddnotnull_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddnotnull_png = new wxImage(); + if (!img_ddnotnull_png || !img_ddnotnull_png->IsOk()) + { + wxMemoryInputStream img_ddnotnull_pngIS(ddnotnull_png_data, sizeof(ddnotnull_png_data)); + img_ddnotnull_png->LoadFile(img_ddnotnull_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddnotnull_png; +} +#define ddnotnull_png_img ddnotnull_png_img() + +static wxBitmap *ddnotnull_png_bmp() +{ + static wxBitmap *bmp_ddnotnull_png; + if (!bmp_ddnotnull_png || !bmp_ddnotnull_png->IsOk()) + bmp_ddnotnull_png = new wxBitmap(*ddnotnull_png_img); + return bmp_ddnotnull_png; +} +#define ddnotnull_png_bmp ddnotnull_png_bmp() + +static wxIcon *ddnotnull_png_ico() +{ + static wxIcon *ico_ddnotnull_png; + if (!ico_ddnotnull_png || !ico_ddnotnull_png->IsOk()) + { + ico_ddnotnull_png = new wxIcon(); + ico_ddnotnull_png->CopyFromBitmap(*ddnotnull_png_bmp); + } + return ico_ddnotnull_png; +} +#define ddnotnull_png_ico ddnotnull_png_ico() + +#endif // DDNOTNULL_PNG_H diff --git a/include/images/ddnull.png b/include/images/ddnull.png new file mode 100644 index 0000000..a2c030d Binary files /dev/null and b/include/images/ddnull.png differ diff --git a/include/images/ddnull.pngc b/include/images/ddnull.pngc new file mode 100644 index 0000000..c7894b6 --- /dev/null +++ b/include/images/ddnull.pngc @@ -0,0 +1,66 @@ +#ifndef DDNULL_PNG_H +#define DDNULL_PNG_H + +static const unsigned char ddnull_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x10, 0xa4, 0xa1, 0x6e, 0xee, +0x00, 0x00, 0x00, 0x29, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x20, 0x00, 0x18, 0x91, +0xd8, 0xff, 0xf1, 0xc8, 0x31, 0xfc, 0x47, 0x53, +0x80, 0xce, 0xc7, 0xd0, 0x0d, 0x17, 0x63, 0x22, +0xe4, 0x06, 0x92, 0x14, 0xfc, 0xc7, 0xc6, 0x26, +0xda, 0x17, 0xe4, 0x03, 0x00, 0xda, 0x97, 0x0a, +0x01, 0xf7, 0x8c, 0x04, 0xb2, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddnull_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddnull_png = new wxImage(); + if (!img_ddnull_png || !img_ddnull_png->IsOk()) + { + wxMemoryInputStream img_ddnull_pngIS(ddnull_png_data, sizeof(ddnull_png_data)); + img_ddnull_png->LoadFile(img_ddnull_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddnull_png; +} +#define ddnull_png_img ddnull_png_img() + +static wxBitmap *ddnull_png_bmp() +{ + static wxBitmap *bmp_ddnull_png; + if (!bmp_ddnull_png || !bmp_ddnull_png->IsOk()) + bmp_ddnull_png = new wxBitmap(*ddnull_png_img); + return bmp_ddnull_png; +} +#define ddnull_png_bmp ddnull_png_bmp() + +static wxIcon *ddnull_png_ico() +{ + static wxIcon *ico_ddnull_png; + if (!ico_ddnull_png || !ico_ddnull_png->IsOk()) + { + ico_ddnull_png = new wxIcon(); + ico_ddnull_png->CopyFromBitmap(*ddnull_png_bmp); + } + return ico_ddnull_png; +} +#define ddnull_png_ico ddnull_png_ico() + +#endif // DDNULL_PNG_H diff --git a/include/images/ddprimaryforeignkey.png b/include/images/ddprimaryforeignkey.png new file mode 100644 index 0000000..6ec5a7e Binary files /dev/null and b/include/images/ddprimaryforeignkey.png differ diff --git a/include/images/ddprimaryforeignkey.pngc b/include/images/ddprimaryforeignkey.pngc new file mode 100644 index 0000000..e288f2b --- /dev/null +++ b/include/images/ddprimaryforeignkey.pngc @@ -0,0 +1,90 @@ +#ifndef DDPRIMARYFOREIGNKEY_PNG_H +#define DDPRIMARYFOREIGNKEY_PNG_H + +static const unsigned char ddprimaryforeignkey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x39, 0xcd, 0x3e, 0xa5, 0x41, +0x00, 0x00, 0x00, 0xef, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x75, 0xcc, 0xb1, 0x4b, 0x84, 0x50, +0x00, 0x80, 0xf1, 0xef, 0x29, 0xe1, 0x12, 0xe8, +0x12, 0x1c, 0x35, 0xd8, 0x12, 0x2d, 0xbd, 0xa0, +0x16, 0x87, 0x56, 0xd7, 0x8b, 0x16, 0xe7, 0xfe, +0x88, 0x38, 0x2e, 0xff, 0x14, 0x87, 0xd6, 0xe0, +0x68, 0x48, 0xb8, 0x07, 0x11, 0x38, 0x06, 0x3a, +0x44, 0x04, 0x66, 0x8b, 0x83, 0x1c, 0x5c, 0x17, +0x71, 0x90, 0x2d, 0x22, 0x9c, 0xc8, 0x6b, 0x28, +0x5a, 0xaa, 0x6f, 0xfe, 0xf1, 0x01, 0xa0, 0x94, +0xd2, 0x45, 0x51, 0x68, 0xa5, 0x94, 0x4e, 0x27, +0x7b, 0xfa, 0xfd, 0xf5, 0x56, 0xa7, 0x13, 0xa9, +0x01, 0x44, 0x92, 0x24, 0xba, 0x6d, 0x5b, 0xa4, +0x94, 0x50, 0x5f, 0xd1, 0xf7, 0x35, 0x83, 0x9d, +0x63, 0xde, 0xca, 0x1b, 0x0c, 0x73, 0x1d, 0x23, +0xcf, 0x73, 0x5c, 0xd7, 0x25, 0x8a, 0x22, 0x96, +0xb3, 0x29, 0xce, 0x60, 0x9f, 0xfb, 0xeb, 0x13, +0x9c, 0xad, 0x23, 0x96, 0xb3, 0x29, 0x86, 0x94, +0x92, 0xaa, 0xaa, 0x08, 0x82, 0x80, 0xaf, 0x56, +0x1c, 0x0e, 0x23, 0xa0, 0x07, 0xc0, 0xf0, 0x7d, +0x5f, 0xe4, 0x79, 0x8e, 0x69, 0x9a, 0x2c, 0xc4, +0x19, 0x1f, 0x8b, 0x47, 0xfa, 0x55, 0x45, 0xfd, +0x72, 0xc7, 0x86, 0x3b, 0xc4, 0x00, 0x68, 0x9a, +0x06, 0xcb, 0xb2, 0xc8, 0xb2, 0x8c, 0xf9, 0xf3, +0x25, 0xe6, 0x9a, 0xc3, 0xfc, 0xe9, 0x82, 0xed, +0x83, 0x91, 0x30, 0xbe, 0xbf, 0x74, 0x5d, 0xc7, +0x5f, 0xfd, 0x00, 0x21, 0xc4, 0xff, 0xc0, 0xf3, +0x3c, 0x6c, 0xdb, 0x06, 0x60, 0x73, 0xf7, 0x94, +0x07, 0x75, 0xfe, 0x5b, 0x86, 0x61, 0xa8, 0xe3, +0x38, 0xd6, 0x00, 0x65, 0x3a, 0xd6, 0x65, 0x3a, +0xd6, 0x00, 0x9f, 0xb8, 0xca, 0x5e, 0x40, 0x0d, +0x3a, 0xc5, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddprimaryforeignkey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddprimaryforeignkey_png = new wxImage(); + if (!img_ddprimaryforeignkey_png || !img_ddprimaryforeignkey_png->IsOk()) + { + wxMemoryInputStream img_ddprimaryforeignkey_pngIS(ddprimaryforeignkey_png_data, sizeof(ddprimaryforeignkey_png_data)); + img_ddprimaryforeignkey_png->LoadFile(img_ddprimaryforeignkey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimaryforeignkey_png; +} +#define ddprimaryforeignkey_png_img ddprimaryforeignkey_png_img() + +static wxBitmap *ddprimaryforeignkey_png_bmp() +{ + static wxBitmap *bmp_ddprimaryforeignkey_png; + if (!bmp_ddprimaryforeignkey_png || !bmp_ddprimaryforeignkey_png->IsOk()) + bmp_ddprimaryforeignkey_png = new wxBitmap(*ddprimaryforeignkey_png_img); + return bmp_ddprimaryforeignkey_png; +} +#define ddprimaryforeignkey_png_bmp ddprimaryforeignkey_png_bmp() + +static wxIcon *ddprimaryforeignkey_png_ico() +{ + static wxIcon *ico_ddprimaryforeignkey_png; + if (!ico_ddprimaryforeignkey_png || !ico_ddprimaryforeignkey_png->IsOk()) + { + ico_ddprimaryforeignkey_png = new wxIcon(); + ico_ddprimaryforeignkey_png->CopyFromBitmap(*ddprimaryforeignkey_png_bmp); + } + return ico_ddprimaryforeignkey_png; +} +#define ddprimaryforeignkey_png_ico ddprimaryforeignkey_png_ico() + +#endif // DDPRIMARYFOREIGNKEY_PNG_H diff --git a/include/images/ddprimaryforeignkeyfromuk.png b/include/images/ddprimaryforeignkeyfromuk.png new file mode 100644 index 0000000..18c79b8 Binary files /dev/null and b/include/images/ddprimaryforeignkeyfromuk.png differ diff --git a/include/images/ddprimaryforeignkeyfromuk.pngc b/include/images/ddprimaryforeignkeyfromuk.pngc new file mode 100644 index 0000000..6ff5252 --- /dev/null +++ b/include/images/ddprimaryforeignkeyfromuk.pngc @@ -0,0 +1,93 @@ +#ifndef DDPRIMARYFOREIGNKEYFROMUK_PNG_H +#define DDPRIMARYFOREIGNKEYFROMUK_PNG_H + +static const unsigned char ddprimaryforeignkeyfromuk_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x22, 0x07, 0x27, 0x72, 0xeb, 0x29, +0x00, 0x00, 0x01, 0x02, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x75, 0xcc, 0x41, 0x2b, 0x83, 0x71, +0x1c, 0xc0, 0xf1, 0xef, 0xf3, 0x7f, 0x1a, 0xc5, +0xca, 0xb3, 0x03, 0x3d, 0xd9, 0x61, 0x6a, 0xc9, +0xc1, 0x10, 0x2e, 0xca, 0x0b, 0x58, 0x3b, 0x0c, +0xef, 0x40, 0x79, 0x09, 0x4a, 0x53, 0x0e, 0xda, +0x1b, 0xe0, 0xca, 0xc1, 0x49, 0xa9, 0xb9, 0xa0, +0x29, 0x7b, 0x2e, 0xca, 0x5a, 0x3d, 0x3b, 0x68, +0xed, 0x20, 0x97, 0xa7, 0x27, 0xdb, 0xda, 0x43, +0xac, 0x3c, 0x34, 0x45, 0x4f, 0x1e, 0x3f, 0x07, +0x72, 0xc1, 0xf7, 0xfc, 0xe9, 0x0b, 0x40, 0xbe, +0xdc, 0x92, 0x92, 0xeb, 0x4b, 0xbe, 0xdc, 0x12, +0xbb, 0x90, 0x92, 0xc7, 0x3b, 0x4b, 0xec, 0xc2, +0x84, 0x00, 0x68, 0x5b, 0x55, 0x4f, 0xba, 0x41, +0x48, 0x26, 0x19, 0x63, 0xe8, 0x61, 0x87, 0x30, +0xf4, 0x31, 0x47, 0x17, 0xb8, 0x77, 0xce, 0x50, +0x7a, 0x14, 0x65, 0xb9, 0x3e, 0xb3, 0x66, 0x3f, +0x2b, 0x87, 0x35, 0x3a, 0xcd, 0x22, 0x86, 0x39, +0xc9, 0xe5, 0xd1, 0x12, 0x46, 0x7c, 0x9e, 0x4e, +0xb3, 0x88, 0x4a, 0x27, 0x63, 0x54, 0xbd, 0x17, +0x36, 0xd3, 0xe3, 0x7c, 0x15, 0x30, 0x93, 0xdd, +0x05, 0x42, 0x00, 0xd4, 0xea, 0x5c, 0x5c, 0xb3, +0x5c, 0x9f, 0x5e, 0x5d, 0xe3, 0x64, 0x60, 0x9f, +0xa7, 0xdb, 0x3a, 0x61, 0x70, 0x83, 0xef, 0x55, +0x18, 0x4c, 0x64, 0x51, 0x00, 0xaf, 0xdd, 0x67, +0xfa, 0x22, 0x8a, 0xe3, 0x7a, 0x83, 0xf6, 0xf5, +0x01, 0x7a, 0xc4, 0xa0, 0x7d, 0xb5, 0xc7, 0xc8, +0xf4, 0x9a, 0xa6, 0xbe, 0xbf, 0xbc, 0xbd, 0x7f, +0xf0, 0x57, 0x3f, 0x40, 0x57, 0xda, 0xff, 0x60, +0x71, 0x2a, 0x81, 0x19, 0xed, 0x01, 0x60, 0x78, +0x6c, 0x99, 0xda, 0xe9, 0xfa, 0x6f, 0x99, 0xda, +0xbe, 0x90, 0x8d, 0xf3, 0x86, 0x00, 0x38, 0x76, +0x4e, 0x1c, 0x3b, 0x27, 0x00, 0x9f, 0xe1, 0x0e, +0x5e, 0x78, 0xf9, 0x58, 0x08, 0x84, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddprimaryforeignkeyfromuk_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddprimaryforeignkeyfromuk_png = new wxImage(); + if (!img_ddprimaryforeignkeyfromuk_png || !img_ddprimaryforeignkeyfromuk_png->IsOk()) + { + wxMemoryInputStream img_ddprimaryforeignkeyfromuk_pngIS(ddprimaryforeignkeyfromuk_png_data, sizeof(ddprimaryforeignkeyfromuk_png_data)); + img_ddprimaryforeignkeyfromuk_png->LoadFile(img_ddprimaryforeignkeyfromuk_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimaryforeignkeyfromuk_png; +} +#define ddprimaryforeignkeyfromuk_png_img ddprimaryforeignkeyfromuk_png_img() + +static wxBitmap *ddprimaryforeignkeyfromuk_png_bmp() +{ + static wxBitmap *bmp_ddprimaryforeignkeyfromuk_png; + if (!bmp_ddprimaryforeignkeyfromuk_png || !bmp_ddprimaryforeignkeyfromuk_png->IsOk()) + bmp_ddprimaryforeignkeyfromuk_png = new wxBitmap(*ddprimaryforeignkeyfromuk_png_img); + return bmp_ddprimaryforeignkeyfromuk_png; +} +#define ddprimaryforeignkeyfromuk_png_bmp ddprimaryforeignkeyfromuk_png_bmp() + +static wxIcon *ddprimaryforeignkeyfromuk_png_ico() +{ + static wxIcon *ico_ddprimaryforeignkeyfromuk_png; + if (!ico_ddprimaryforeignkeyfromuk_png || !ico_ddprimaryforeignkeyfromuk_png->IsOk()) + { + ico_ddprimaryforeignkeyfromuk_png = new wxIcon(); + ico_ddprimaryforeignkeyfromuk_png->CopyFromBitmap(*ddprimaryforeignkeyfromuk_png_bmp); + } + return ico_ddprimaryforeignkeyfromuk_png; +} +#define ddprimaryforeignkeyfromuk_png_ico ddprimaryforeignkeyfromuk_png_ico() + +#endif // DDPRIMARYFOREIGNKEYFROMUK_PNG_H diff --git a/include/images/ddprimarykey.png b/include/images/ddprimarykey.png new file mode 100644 index 0000000..568dc77 Binary files /dev/null and b/include/images/ddprimarykey.png differ diff --git a/include/images/ddprimarykey.pngc b/include/images/ddprimarykey.pngc new file mode 100644 index 0000000..150f179 --- /dev/null +++ b/include/images/ddprimarykey.pngc @@ -0,0 +1,87 @@ +#ifndef DDPRIMARYKEY_PNG_H +#define DDPRIMARYKEY_PNG_H + +static const unsigned char ddprimarykey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x22, 0x47, 0x5b, 0x6c, 0xad, +0x00, 0x00, 0x00, 0xd8, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x8d, 0x8e, 0xb1, 0x4a, 0x42, 0x51, +0x18, 0x80, 0xbf, 0x73, 0xce, 0x95, 0x40, 0x1a, +0xee, 0x12, 0x1d, 0xb2, 0x45, 0x42, 0x5a, 0xa4, +0xa1, 0x2d, 0xea, 0x0d, 0x44, 0xa8, 0xa9, 0xd1, +0x77, 0x70, 0xd1, 0x77, 0xf0, 0x09, 0xda, 0x2e, +0x38, 0xb5, 0xdc, 0x3b, 0xd8, 0x0b, 0xdc, 0x41, +0x2e, 0x84, 0xd8, 0xd0, 0x14, 0xa2, 0xe8, 0x10, +0x24, 0x8a, 0x86, 0x42, 0x84, 0x78, 0xce, 0xef, +0x94, 0x5b, 0xd4, 0x37, 0x7e, 0x7c, 0xc3, 0xa7, +0x00, 0xb2, 0xc7, 0xb2, 0x1c, 0x9f, 0xdd, 0x11, +0x16, 0x6e, 0x00, 0xc5, 0xe7, 0x7b, 0x97, 0xe9, +0x30, 0xe6, 0xea, 0xfe, 0x55, 0xa9, 0xf1, 0x4b, +0x4b, 0x9c, 0x5b, 0x62, 0x4b, 0x15, 0xc0, 0x80, +0xca, 0xa1, 0x94, 0xe1, 0xe3, 0x2d, 0x41, 0x9b, +0x43, 0xf4, 0x6c, 0xd2, 0x21, 0xb4, 0x17, 0x78, +0xb7, 0xa0, 0x97, 0xdc, 0xd2, 0x8b, 0x2b, 0x78, +0xf7, 0x45, 0x58, 0xb8, 0x66, 0x36, 0xe9, 0x10, +0x00, 0xc0, 0x06, 0xef, 0xbe, 0xb9, 0xac, 0x3e, +0x80, 0x3e, 0xc0, 0xfb, 0x15, 0x20, 0x00, 0x28, +0x80, 0xe1, 0x73, 0x5d, 0x8e, 0x8a, 0x65, 0xfc, +0x76, 0x05, 0x3a, 0x4f, 0x90, 0x3b, 0x65, 0x3a, +0xea, 0x62, 0x4c, 0xc8, 0x9e, 0x34, 0xb2, 0xb2, +0x9e, 0x47, 0xb2, 0x9e, 0xb7, 0x25, 0x8d, 0xac, +0xfc, 0x78, 0xcd, 0x1f, 0xfc, 0x3f, 0x38, 0x39, +0xaf, 0xd1, 0x7f, 0x6a, 0x12, 0x04, 0xf9, 0xdf, +0xeb, 0x41, 0xd6, 0x90, 0x34, 0xb2, 0x32, 0xc8, +0x1a, 0xfb, 0x87, 0x1d, 0x4b, 0x11, 0x4b, 0xe4, +0x72, 0x86, 0xd5, 0x9c, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddprimarykey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddprimarykey_png = new wxImage(); + if (!img_ddprimarykey_png || !img_ddprimarykey_png->IsOk()) + { + wxMemoryInputStream img_ddprimarykey_pngIS(ddprimarykey_png_data, sizeof(ddprimarykey_png_data)); + img_ddprimarykey_png->LoadFile(img_ddprimarykey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimarykey_png; +} +#define ddprimarykey_png_img ddprimarykey_png_img() + +static wxBitmap *ddprimarykey_png_bmp() +{ + static wxBitmap *bmp_ddprimarykey_png; + if (!bmp_ddprimarykey_png || !bmp_ddprimarykey_png->IsOk()) + bmp_ddprimarykey_png = new wxBitmap(*ddprimarykey_png_img); + return bmp_ddprimarykey_png; +} +#define ddprimarykey_png_bmp ddprimarykey_png_bmp() + +static wxIcon *ddprimarykey_png_ico() +{ + static wxIcon *ico_ddprimarykey_png; + if (!ico_ddprimarykey_png || !ico_ddprimarykey_png->IsOk()) + { + ico_ddprimarykey_png = new wxIcon(); + ico_ddprimarykey_png->CopyFromBitmap(*ddprimarykey_png_bmp); + } + return ico_ddprimarykey_png; +} +#define ddprimarykey_png_ico ddprimarykey_png_ico() + +#endif // DDPRIMARYKEY_PNG_H diff --git a/include/images/ddprimarykeyuniquekey.png b/include/images/ddprimarykeyuniquekey.png new file mode 100644 index 0000000..7f3fcc2 Binary files /dev/null and b/include/images/ddprimarykeyuniquekey.png differ diff --git a/include/images/ddprimarykeyuniquekey.pngc b/include/images/ddprimarykeyuniquekey.pngc new file mode 100644 index 0000000..127265f --- /dev/null +++ b/include/images/ddprimarykeyuniquekey.pngc @@ -0,0 +1,90 @@ +#ifndef DDPRIMARYKEYUNIQUEKEY_PNG_H +#define DDPRIMARYKEYUNIQUEKEY_PNG_H + +static const unsigned char ddprimarykeyuniquekey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, +0x08, 0x06, 0x00, 0x00, 0x00, 0x89, 0xc7, 0x1f, +0x80, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x21, 0x2d, 0xd7, 0xe4, 0x71, 0x3c, +0x00, 0x00, 0x00, 0xe9, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x60, 0x60, 0x60, 0x38, +0xbe, 0x52, 0xe7, 0xff, 0xbb, 0xe7, 0x3b, 0xff, +0x1f, 0x5f, 0xa9, 0xfb, 0x9f, 0x01, 0x0d, 0x30, +0x3d, 0x38, 0xdf, 0xfd, 0x5f, 0x4c, 0xd9, 0x8f, +0x81, 0x9d, 0x8b, 0x9f, 0x41, 0x5c, 0x39, 0x88, +0xe1, 0xc1, 0xf9, 0x6e, 0x14, 0x45, 0x4c, 0xaf, +0x1f, 0x6e, 0x66, 0x10, 0x90, 0xd0, 0x63, 0x38, +0xb3, 0x3e, 0x80, 0x41, 0x40, 0xda, 0x9a, 0xe1, +0xf5, 0xc3, 0xcd, 0x0c, 0x3a, 0x69, 0x7b, 0xff, +0x37, 0x2f, 0xbd, 0xf1, 0x9f, 0x81, 0x81, 0x81, +0x81, 0x09, 0xa2, 0xee, 0x17, 0x83, 0x91, 0xef, +0x4c, 0x06, 0x06, 0x86, 0xbf, 0x0c, 0x89, 0xdb, +0xea, 0x19, 0x02, 0x42, 0xe4, 0x18, 0x56, 0x1e, +0x7c, 0x0a, 0x31, 0xc1, 0x34, 0xe0, 0x10, 0xe3, +0x87, 0x67, 0x17, 0x18, 0xfe, 0xfe, 0xba, 0xcf, +0x60, 0x57, 0xcf, 0xc6, 0x50, 0x9d, 0xa7, 0xc1, +0xc0, 0xf8, 0x9f, 0x11, 0x61, 0x05, 0x03, 0x03, +0x03, 0xc3, 0x93, 0x6b, 0xcb, 0x18, 0x98, 0x59, +0x05, 0x18, 0xc2, 0xed, 0xa5, 0x19, 0x5a, 0x27, +0xdd, 0x60, 0x60, 0xf8, 0x8b, 0xa6, 0x00, 0x06, +0xec, 0x7e, 0x3b, 0x30, 0xf0, 0x73, 0xb3, 0x32, +0x30, 0xfe, 0x63, 0xc2, 0xae, 0x80, 0x81, 0x81, +0x81, 0x41, 0x53, 0x8e, 0x97, 0x81, 0xe9, 0x17, +0x0b, 0xaa, 0x02, 0x29, 0xf5, 0x78, 0x86, 0x73, +0x5b, 0x2a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x4e, +0x5c, 0x7f, 0xc7, 0xf0, 0xed, 0x07, 0x42, 0x03, +0xdc, 0xb2, 0xdb, 0xc7, 0xcb, 0xff, 0xaf, 0xb8, +0x97, 0x08, 0x77, 0x3d, 0x03, 0x03, 0x03, 0x43, +0xb8, 0xbd, 0x34, 0x03, 0x00, 0x8a, 0xd1, 0x47, +0xb3, 0xef, 0xd2, 0xf6, 0x84, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddprimarykeyuniquekey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddprimarykeyuniquekey_png = new wxImage(); + if (!img_ddprimarykeyuniquekey_png || !img_ddprimarykeyuniquekey_png->IsOk()) + { + wxMemoryInputStream img_ddprimarykeyuniquekey_pngIS(ddprimarykeyuniquekey_png_data, sizeof(ddprimarykeyuniquekey_png_data)); + img_ddprimarykeyuniquekey_png->LoadFile(img_ddprimarykeyuniquekey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddprimarykeyuniquekey_png; +} +#define ddprimarykeyuniquekey_png_img ddprimarykeyuniquekey_png_img() + +static wxBitmap *ddprimarykeyuniquekey_png_bmp() +{ + static wxBitmap *bmp_ddprimarykeyuniquekey_png; + if (!bmp_ddprimarykeyuniquekey_png || !bmp_ddprimarykeyuniquekey_png->IsOk()) + bmp_ddprimarykeyuniquekey_png = new wxBitmap(*ddprimarykeyuniquekey_png_img); + return bmp_ddprimarykeyuniquekey_png; +} +#define ddprimarykeyuniquekey_png_bmp ddprimarykeyuniquekey_png_bmp() + +static wxIcon *ddprimarykeyuniquekey_png_ico() +{ + static wxIcon *ico_ddprimarykeyuniquekey_png; + if (!ico_ddprimarykeyuniquekey_png || !ico_ddprimarykeyuniquekey_png->IsOk()) + { + ico_ddprimarykeyuniquekey_png = new wxIcon(); + ico_ddprimarykeyuniquekey_png->CopyFromBitmap(*ddprimarykeyuniquekey_png_bmp); + } + return ico_ddprimarykeyuniquekey_png; +} +#define ddprimarykeyuniquekey_png_ico ddprimarykeyuniquekey_png_ico() + +#endif // DDPRIMARYKEYUNIQUEKEY_PNG_H diff --git a/include/images/ddunique.png b/include/images/ddunique.png new file mode 100644 index 0000000..9a25e42 Binary files /dev/null and b/include/images/ddunique.png differ diff --git a/include/images/ddunique.pngc b/include/images/ddunique.pngc new file mode 100644 index 0000000..427c5c7 --- /dev/null +++ b/include/images/ddunique.pngc @@ -0,0 +1,75 @@ +#ifndef DDUNIQUE_PNG_H +#define DDUNIQUE_PNG_H + +static const unsigned char ddunique_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0x0f, 0xbe, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, +0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x06, +0x19, 0x0d, 0x20, 0x1a, 0x76, 0x42, 0xe5, 0x72, +0x00, 0x00, 0x00, 0x71, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x80, 0x02, 0x9d, 0xb4, +0xbd, 0xff, 0x9b, 0x97, 0xde, 0xf8, 0xcf, 0x80, +0x06, 0x98, 0x60, 0x92, 0x01, 0x21, 0x72, 0x0c, +0x2b, 0x0f, 0x3e, 0x65, 0xc0, 0x50, 0xa0, 0x93, +0xb6, 0xf7, 0x7f, 0x75, 0x9e, 0x06, 0x03, 0xe3, +0x7f, 0x46, 0x06, 0x6c, 0x80, 0x29, 0xdc, 0x5e, +0x9a, 0xa1, 0x75, 0xd2, 0x0d, 0x06, 0x86, 0xbf, +0x38, 0x14, 0xd4, 0x46, 0x6b, 0x30, 0xf2, 0x73, +0xb3, 0x32, 0x30, 0xfe, 0x63, 0xc2, 0xae, 0x80, +0x81, 0x81, 0x81, 0x41, 0x53, 0x8e, 0x97, 0x81, +0xe9, 0x17, 0x0b, 0x6e, 0x05, 0x27, 0xae, 0xbf, +0x63, 0xf8, 0xf6, 0x83, 0x01, 0xbb, 0x02, 0x98, +0xd7, 0xb6, 0x1d, 0xb8, 0xc5, 0xc0, 0xc0, 0xc0, +0xc0, 0x80, 0xee, 0x55, 0x00, 0xa8, 0x66, 0x22, +0xf7, 0x68, 0xd9, 0x19, 0x56, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ddunique_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ddunique_png = new wxImage(); + if (!img_ddunique_png || !img_ddunique_png->IsOk()) + { + wxMemoryInputStream img_ddunique_pngIS(ddunique_png_data, sizeof(ddunique_png_data)); + img_ddunique_png->LoadFile(img_ddunique_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ddunique_png; +} +#define ddunique_png_img ddunique_png_img() + +static wxBitmap *ddunique_png_bmp() +{ + static wxBitmap *bmp_ddunique_png; + if (!bmp_ddunique_png || !bmp_ddunique_png->IsOk()) + bmp_ddunique_png = new wxBitmap(*ddunique_png_img); + return bmp_ddunique_png; +} +#define ddunique_png_bmp ddunique_png_bmp() + +static wxIcon *ddunique_png_ico() +{ + static wxIcon *ico_ddunique_png; + if (!ico_ddunique_png || !ico_ddunique_png->IsOk()) + { + ico_ddunique_png = new wxIcon(); + ico_ddunique_png->CopyFromBitmap(*ddunique_png_bmp); + } + return ico_ddunique_png; +} +#define ddunique_png_ico ddunique_png_ico() + +#endif // DDUNIQUE_PNG_H diff --git a/include/images/debugger.png b/include/images/debugger.png new file mode 100644 index 0000000..4430e86 Binary files /dev/null and b/include/images/debugger.png differ diff --git a/include/images/debugger.pngc b/include/images/debugger.pngc new file mode 100644 index 0000000..917d52c --- /dev/null +++ b/include/images/debugger.pngc @@ -0,0 +1,88 @@ +#ifndef DEBUGGER_PNG_H +#define DEBUGGER_PNG_H + +static const unsigned char debugger_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x24, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x80, +0x80, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x80, +0x80, 0x00, 0x80, 0x00, 0x00, 0xef, 0x7e, 0xc5, +0xfd, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x71, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x00, +0x02, 0x21, 0x06, 0x28, 0x10, 0x80, 0x50, 0x4c, +0x02, 0x8a, 0x60, 0x5a, 0x48, 0xd9, 0xc1, 0x91, +0xc1, 0x11, 0xc4, 0x0a, 0x4d, 0x0f, 0x64, 0x12, +0x04, 0x31, 0xc2, 0x5d, 0x43, 0x1d, 0x41, 0x0c, +0x85, 0x12, 0x77, 0x57, 0x47, 0x90, 0x72, 0xa1, +0x50, 0x77, 0x97, 0x10, 0x73, 0x20, 0x8b, 0xb1, +0xd4, 0xc5, 0xc5, 0x45, 0xd5, 0x9d, 0x21, 0x88, +0xa9, 0xc4, 0x25, 0xc4, 0x45, 0x51, 0x91, 0x81, +0x51, 0x50, 0xd4, 0xa5, 0x33, 0x54, 0x51, 0x10, +0xc8, 0x50, 0x71, 0x59, 0xb9, 0x14, 0x6c, 0x64, +0x52, 0x48, 0xf7, 0x26, 0x30, 0xa3, 0x48, 0x35, +0x34, 0x08, 0x6c, 0x9b, 0x93, 0xa0, 0x92, 0x12, +0x98, 0x11, 0x24, 0x20, 0x08, 0x34, 0x18, 0x00, +0x52, 0xf1, 0x12, 0x33, 0x97, 0xb8, 0x21, 0x59, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *debugger_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_debugger_png = new wxImage(); + if (!img_debugger_png || !img_debugger_png->IsOk()) + { + wxMemoryInputStream img_debugger_pngIS(debugger_png_data, sizeof(debugger_png_data)); + img_debugger_png->LoadFile(img_debugger_pngIS, wxBITMAP_TYPE_PNG); + } + return img_debugger_png; +} +#define debugger_png_img debugger_png_img() + +static wxBitmap *debugger_png_bmp() +{ + static wxBitmap *bmp_debugger_png; + if (!bmp_debugger_png || !bmp_debugger_png->IsOk()) + bmp_debugger_png = new wxBitmap(*debugger_png_img); + return bmp_debugger_png; +} +#define debugger_png_bmp debugger_png_bmp() + +static wxIcon *debugger_png_ico() +{ + static wxIcon *ico_debugger_png; + if (!ico_debugger_png || !ico_debugger_png->IsOk()) + { + ico_debugger_png = new wxIcon(); + ico_debugger_png->CopyFromBitmap(*debugger_png_bmp); + } + return ico_debugger_png; +} +#define debugger_png_ico debugger_png_ico() + +#endif // DEBUGGER_PNG_H diff --git a/include/images/delete.png b/include/images/delete.png new file mode 100644 index 0000000..daa6a7c Binary files /dev/null and b/include/images/delete.png differ diff --git a/include/images/delete.pngc b/include/images/delete.pngc new file mode 100644 index 0000000..10aab57 --- /dev/null +++ b/include/images/delete.pngc @@ -0,0 +1,120 @@ +#ifndef DELETE_PNG_H +#define DELETE_PNG_H + +static const unsigned char delete_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xbd, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd3, 0xd4, 0xd3, 0xb5, +0xb5, 0xb5, 0x9f, 0x9f, 0x9f, 0x85, 0x85, 0x85, +0x77, 0x77, 0x77, 0x6c, 0x6c, 0x6c, 0x9d, 0x9d, +0x9d, 0xcc, 0xcc, 0xcc, 0xa3, 0xa3, 0xa3, 0xbd, +0xbd, 0xbd, 0xd5, 0xd5, 0xd5, 0xe9, 0xe9, 0xe9, +0xf5, 0xf5, 0xf5, 0xf2, 0xf2, 0xf2, 0xe4, 0xe4, +0xe4, 0xd1, 0xd1, 0xd1, 0xb9, 0xb9, 0xb9, 0x9b, +0x9b, 0x9b, 0xde, 0xde, 0xde, 0xac, 0xac, 0xac, +0x95, 0x95, 0x95, 0x89, 0x89, 0x89, 0xc2, 0xc2, +0xc2, 0x7b, 0x7b, 0x7b, 0xc8, 0xc8, 0xc8, 0xd1, +0xe2, 0xcb, 0xcf, 0xdf, 0xc9, 0xe0, 0xe8, 0xdd, +0xee, 0xee, 0xee, 0xdd, 0xe6, 0xda, 0x53, 0xa3, +0x38, 0x5b, 0xa3, 0x45, 0x47, 0x9b, 0x2c, 0xbc, +0xd1, 0xb6, 0xe1, 0xe1, 0xe1, 0xb1, 0xb1, 0xb1, +0x7f, 0xb7, 0x6c, 0x87, 0xb8, 0x78, 0x3b, 0x90, +0x23, 0x99, 0xb9, 0x90, 0xb1, 0xcc, 0xa8, 0xdb, +0xdf, 0xda, 0xc6, 0xd4, 0xc2, 0xb3, 0xc5, 0xae, +0xda, 0xda, 0xda, 0xb9, 0xcc, 0xb4, 0xa5, 0xc2, +0x9d, 0x31, 0x8b, 0x1b, 0x51, 0x98, 0x3f, 0xc9, +0xd5, 0xc6, 0x5f, 0x9f, 0x4f, 0x47, 0x94, 0x33, +0x64, 0xa5, 0x52, 0x81, 0xac, 0x76, 0x8f, 0x8f, +0x8f, 0xc5, 0xc5, 0xc5, 0xc3, 0xca, 0xc2, 0xdc, +0xdc, 0xdc, 0xca, 0xcd, 0xca, 0xbc, 0xc3, 0xba, +0xce, 0xce, 0xce, 0x70, 0x70, 0x70, 0xa5, 0x34, +0xff, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xda, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x2d, 0xce, +0xeb, 0x52, 0x83, 0x30, 0x10, 0x05, 0xe0, 0x90, +0x0b, 0x24, 0x01, 0x02, 0x92, 0x12, 0x88, 0xb5, +0x0a, 0x05, 0x03, 0x55, 0x52, 0xab, 0x52, 0xa9, +0x17, 0xfa, 0xfe, 0x8f, 0xd5, 0xc0, 0x78, 0x7e, +0xed, 0x7e, 0x73, 0x76, 0x66, 0x01, 0x00, 0x1e, +0x44, 0x98, 0xf8, 0x3e, 0xc1, 0x01, 0xf4, 0x80, +0x0b, 0x25, 0x8c, 0x87, 0x51, 0x2c, 0x92, 0xf4, +0x2e, 0x20, 0xd4, 0x01, 0xce, 0x18, 0x4f, 0x65, +0x22, 0x53, 0xbe, 0xc9, 0x33, 0xec, 0x40, 0xd1, +0x82, 0xa9, 0xd2, 0x9d, 0x28, 0xc6, 0xb5, 0x72, +0x90, 0xeb, 0x38, 0x8e, 0xc5, 0xfd, 0xf6, 0x61, +0x17, 0x45, 0x45, 0xee, 0x80, 0x41, 0x21, 0x1e, +0x9f, 0xaa, 0xba, 0xde, 0x37, 0x49, 0xcb, 0x1c, +0x40, 0x26, 0x76, 0xcf, 0xb5, 0x31, 0x5d, 0x2f, +0x1b, 0x04, 0x1d, 0x68, 0x25, 0xb6, 0x07, 0xf3, +0xf2, 0xba, 0x37, 0x43, 0xa3, 0xb4, 0x03, 0x4b, +0x5c, 0xe1, 0x28, 0xe5, 0xdb, 0xe9, 0x5d, 0x12, +0xbb, 0x3c, 0xe2, 0x47, 0xa6, 0xfa, 0xb0, 0xd6, +0xfb, 0x1c, 0xad, 0xbf, 0xec, 0xa0, 0x0c, 0x0f, +0x55, 0x75, 0x3e, 0x8e, 0xe3, 0x17, 0x2d, 0x57, +0x98, 0x2e, 0xf2, 0xdc, 0x8d, 0xfd, 0xa9, 0xfb, +0xe6, 0xd3, 0x0a, 0xac, 0xfd, 0xf9, 0x1d, 0x06, +0xdd, 0xff, 0xcd, 0x1b, 0xb6, 0x02, 0x44, 0x4d, +0x98, 0xce, 0x94, 0xce, 0x36, 0x83, 0x2b, 0x80, +0x60, 0x6a, 0x75, 0xe8, 0x5d, 0xda, 0x29, 0x00, +0xff, 0x29, 0x10, 0xbe, 0x5e, 0x31, 0x2a, 0x96, +0xf9, 0x06, 0x23, 0xaa, 0x13, 0x7e, 0xcd, 0x94, +0xab, 0xc9, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *delete_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_delete_png = new wxImage(); + if (!img_delete_png || !img_delete_png->IsOk()) + { + wxMemoryInputStream img_delete_pngIS(delete_png_data, sizeof(delete_png_data)); + img_delete_png->LoadFile(img_delete_pngIS, wxBITMAP_TYPE_PNG); + } + return img_delete_png; +} +#define delete_png_img delete_png_img() + +static wxBitmap *delete_png_bmp() +{ + static wxBitmap *bmp_delete_png; + if (!bmp_delete_png || !bmp_delete_png->IsOk()) + bmp_delete_png = new wxBitmap(*delete_png_img); + return bmp_delete_png; +} +#define delete_png_bmp delete_png_bmp() + +static wxIcon *delete_png_ico() +{ + static wxIcon *ico_delete_png; + if (!ico_delete_png || !ico_delete_png->IsOk()) + { + ico_delete_png = new wxIcon(); + ico_delete_png->CopyFromBitmap(*delete_png_bmp); + } + return ico_delete_png; +} +#define delete_png_ico delete_png_ico() + +#endif // DELETE_PNG_H diff --git a/include/images/dictionaries.png b/include/images/dictionaries.png new file mode 100644 index 0000000..a97eb49 Binary files /dev/null and b/include/images/dictionaries.png differ diff --git a/include/images/dictionaries.pngc b/include/images/dictionaries.pngc new file mode 100644 index 0000000..fc627ca --- /dev/null +++ b/include/images/dictionaries.pngc @@ -0,0 +1,90 @@ +#ifndef DICTIONARIES_PNG_H +#define DICTIONARIES_PNG_H + +static const unsigned char dictionaries_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x42, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x92, 0xb4, 0xc5, 0x1a, +0x79, 0xaa, 0xd0, 0xc4, 0x75, 0x3f, 0x8b, 0xb3, +0x8c, 0xa3, 0x65, 0xcd, 0xbb, 0x3f, 0x58, 0x97, +0xb8, 0x3a, 0x89, 0xb1, 0x51, 0xc5, 0xf5, 0x45, +0xbc, 0xf1, 0x3d, 0xb7, 0xef, 0x4c, 0xc1, 0xf3, +0x34, 0xb0, 0xec, 0x2b, 0xa9, 0xe9, 0x22, 0xa3, +0xe6, 0x19, 0x9c, 0xe3, 0x11, 0x97, 0xe1, 0x0a, +0x92, 0xdf, 0x10, 0x62, 0x8f, 0x05, 0x8e, 0xdd, +0x67, 0x9f, 0xbc, 0xf9, 0x6a, 0xb7, 0x14, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x65, 0xcf, 0x4b, 0x0e, 0x80, +0x20, 0x0c, 0x45, 0x51, 0x28, 0x3f, 0x01, 0x01, +0x51, 0xd8, 0xff, 0x56, 0xb5, 0xc5, 0xbc, 0x98, +0xd8, 0xf4, 0x4e, 0xce, 0xa8, 0x55, 0xea, 0x37, +0x9a, 0x8c, 0x79, 0x96, 0x23, 0xcd, 0x60, 0x9d, +0xf7, 0xe4, 0x25, 0x67, 0x19, 0x02, 0x11, 0x6d, +0x6f, 0x81, 0x81, 0x62, 0x4c, 0xe8, 0x85, 0x8c, +0x16, 0xec, 0x05, 0x2d, 0x48, 0x15, 0x2d, 0xc8, +0x0d, 0x09, 0xec, 0xe5, 0x40, 0x02, 0xa9, 0x76, +0x24, 0x90, 0xdb, 0x89, 0x04, 0xca, 0x35, 0x90, +0x40, 0xed, 0x03, 0x31, 0xcc, 0xcf, 0xe9, 0xf3, +0xff, 0xbb, 0xba, 0x01, 0x9f, 0xbe, 0x05, 0xb8, +0xa8, 0x32, 0x2a, 0xef, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dictionaries_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dictionaries_png = new wxImage(); + if (!img_dictionaries_png || !img_dictionaries_png->IsOk()) + { + wxMemoryInputStream img_dictionaries_pngIS(dictionaries_png_data, sizeof(dictionaries_png_data)); + img_dictionaries_png->LoadFile(img_dictionaries_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dictionaries_png; +} +#define dictionaries_png_img dictionaries_png_img() + +static wxBitmap *dictionaries_png_bmp() +{ + static wxBitmap *bmp_dictionaries_png; + if (!bmp_dictionaries_png || !bmp_dictionaries_png->IsOk()) + bmp_dictionaries_png = new wxBitmap(*dictionaries_png_img); + return bmp_dictionaries_png; +} +#define dictionaries_png_bmp dictionaries_png_bmp() + +static wxIcon *dictionaries_png_ico() +{ + static wxIcon *ico_dictionaries_png; + if (!ico_dictionaries_png || !ico_dictionaries_png->IsOk()) + { + ico_dictionaries_png = new wxIcon(); + ico_dictionaries_png->CopyFromBitmap(*dictionaries_png_bmp); + } + return ico_dictionaries_png; +} +#define dictionaries_png_ico dictionaries_png_ico() + +#endif // DICTIONARIES_PNG_H diff --git a/include/images/dictionary.png b/include/images/dictionary.png new file mode 100644 index 0000000..55a880b Binary files /dev/null and b/include/images/dictionary.png differ diff --git a/include/images/dictionary.pngc b/include/images/dictionary.pngc new file mode 100644 index 0000000..7d00baa --- /dev/null +++ b/include/images/dictionary.pngc @@ -0,0 +1,124 @@ +#ifndef DICTIONARY_PNG_H +#define DICTIONARY_PNG_H + +static const unsigned char dictionary_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x11, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x86, 0xae, 0xc3, 0x1a, +0x79, 0xaa, 0xa1, 0xbb, 0xc9, 0x35, 0xa2, 0xd5, +0x33, 0xa1, 0xd5, 0x3c, 0xac, 0xdf, 0x46, 0xbd, +0xf2, 0x43, 0xbb, 0xf1, 0x38, 0xa5, 0xd6, 0x32, +0xa4, 0xdb, 0x3d, 0xad, 0xdf, 0x49, 0xbf, 0xf2, +0x45, 0xbd, 0xf1, 0x38, 0x9e, 0xcc, 0x25, 0x6e, +0x8f, 0x23, 0x6d, 0x8f, 0x2f, 0x9c, 0xcf, 0x2b, +0xa0, 0xd9, 0x43, 0xac, 0xd9, 0x48, 0xbe, 0xf2, +0x43, 0xb8, 0xeb, 0x27, 0x6f, 0x90, 0x2b, 0x87, +0xb2, 0x20, 0x6a, 0x8e, 0x1d, 0x68, 0x8d, 0x2c, +0xa7, 0xe4, 0x22, 0x93, 0xcc, 0x9a, 0xb8, 0xc8, +0x38, 0x96, 0xbf, 0x3d, 0xa7, 0xd7, 0x40, 0xb9, +0xf0, 0x35, 0x9f, 0xd1, 0x22, 0x6b, 0x8e, 0x2a, +0x94, 0xc8, 0x2c, 0xab, 0xe9, 0x28, 0xa7, 0xe8, +0x24, 0xa4, 0xe7, 0x1e, 0x97, 0xd5, 0x2a, 0x89, +0xb6, 0x32, 0x91, 0xbd, 0x36, 0xa3, 0xd5, 0x38, +0xb3, 0xed, 0x2e, 0x9d, 0xd3, 0x30, 0xad, 0xea, +0x2b, 0xaa, 0xe9, 0x27, 0xa7, 0xe8, 0x23, 0xa4, +0xe6, 0x1f, 0xa1, 0xe5, 0x1b, 0x9e, 0xe4, 0x18, +0x92, 0xd3, 0x27, 0x86, 0xb5, 0x2b, 0x8c, 0xbb, +0x2e, 0x9c, 0xd3, 0x2f, 0xac, 0xea, 0x2a, 0xa9, +0xe9, 0x26, 0xa6, 0xe8, 0x22, 0xa3, 0xe6, 0x1e, +0xa0, 0xe5, 0x1a, 0x9d, 0xe4, 0x16, 0x9b, 0xe2, +0x15, 0x8f, 0xd2, 0x22, 0x83, 0xb3, 0x24, 0x88, +0xb8, 0x26, 0x96, 0xd0, 0x25, 0xa5, 0xe7, 0x21, +0xa2, 0xe6, 0x1d, 0xa0, 0xe5, 0x19, 0x9d, 0xe3, +0x17, 0x91, 0xd2, 0x93, 0x9c, 0x67, 0x1e, 0x80, +0xb2, 0x1c, 0x82, 0xb6, 0x1d, 0x91, 0xce, 0x1c, +0x9f, 0xe4, 0x19, 0x92, 0xd3, 0x91, 0x9a, 0x6a, +0xc7, 0xb2, 0x46, 0xd0, 0xbf, 0x3b, 0x19, 0x7b, +0xae, 0x15, 0x7d, 0xb4, 0x16, 0x86, 0xc2, 0x8f, +0x97, 0x6c, 0xc5, 0xae, 0x4a, 0xcd, 0xbb, 0x3f, +0xa2, 0xb2, 0x54, 0x15, 0x7a, 0xaf, 0xca, 0xb6, +0x42, 0x9f, 0xae, 0x57, 0x81, 0xac, 0xc2, 0x9d, +0xac, 0x5a, 0x92, 0xc6, 0x21, 0xbe, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xa0, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0xce, 0xd5, 0x0e, 0xc2, 0x50, +0x10, 0x04, 0xd0, 0xdb, 0x29, 0x6e, 0xc5, 0xdd, +0xdd, 0xdd, 0x5d, 0x8b, 0xbb, 0xf3, 0xff, 0x1f, +0x02, 0xdc, 0xd0, 0x40, 0x13, 0xf6, 0x6d, 0x4e, +0x66, 0x37, 0x4b, 0xc8, 0xdf, 0x61, 0x00, 0x56, +0x1c, 0x25, 0xd2, 0xaf, 0xbc, 0xa2, 0x4c, 0xae, +0x50, 0xaa, 0x04, 0x01, 0xd4, 0x1a, 0xad, 0x8e, +0xd3, 0x1b, 0x8c, 0x1f, 0x81, 0xc9, 0x6c, 0xb1, +0x72, 0x36, 0xbb, 0xc3, 0xe9, 0x82, 0x9b, 0x82, +0xc7, 0xeb, 0xf3, 0x07, 0xec, 0xc1, 0x50, 0x38, +0x12, 0xa5, 0x1d, 0xc4, 0xe2, 0x89, 0x64, 0x2a, +0x9d, 0xc9, 0xe6, 0xf2, 0x85, 0xe2, 0x5b, 0x58, +0x94, 0xca, 0x95, 0x6a, 0xad, 0xde, 0x68, 0xb6, +0xda, 0x1d, 0x80, 0xbc, 0xa5, 0xdb, 0xeb, 0x0f, +0x86, 0xa3, 0xf1, 0x04, 0xe0, 0xe9, 0x59, 0x16, +0xd3, 0xd9, 0x7c, 0xb1, 0x04, 0x56, 0xeb, 0x0d, +0xf9, 0xc8, 0x76, 0xb7, 0xc7, 0xe1, 0x78, 0x3a, +0xd3, 0x15, 0x2a, 0x17, 0xf0, 0xd7, 0x1b, 0xc0, +0x08, 0xdf, 0xde, 0x81, 0xc7, 0x4f, 0xa4, 0x1d, +0x51, 0xfc, 0x9d, 0x27, 0xa5, 0x5a, 0x10, 0xe1, +0x70, 0x44, 0xf1, 0x23, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dictionary_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dictionary_png = new wxImage(); + if (!img_dictionary_png || !img_dictionary_png->IsOk()) + { + wxMemoryInputStream img_dictionary_pngIS(dictionary_png_data, sizeof(dictionary_png_data)); + img_dictionary_png->LoadFile(img_dictionary_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dictionary_png; +} +#define dictionary_png_img dictionary_png_img() + +static wxBitmap *dictionary_png_bmp() +{ + static wxBitmap *bmp_dictionary_png; + if (!bmp_dictionary_png || !bmp_dictionary_png->IsOk()) + bmp_dictionary_png = new wxBitmap(*dictionary_png_img); + return bmp_dictionary_png; +} +#define dictionary_png_bmp dictionary_png_bmp() + +static wxIcon *dictionary_png_ico() +{ + static wxIcon *ico_dictionary_png; + if (!ico_dictionary_png || !ico_dictionary_png->IsOk()) + { + ico_dictionary_png = new wxIcon(); + ico_dictionary_png->CopyFromBitmap(*dictionary_png_bmp); + } + return ico_dictionary_png; +} +#define dictionary_png_ico dictionary_png_ico() + +#endif // DICTIONARY_PNG_H diff --git a/include/images/disabled.png b/include/images/disabled.png new file mode 100644 index 0000000..53128fd Binary files /dev/null and b/include/images/disabled.png differ diff --git a/include/images/disabled.pngc b/include/images/disabled.pngc new file mode 100644 index 0000000..5f37ace --- /dev/null +++ b/include/images/disabled.pngc @@ -0,0 +1,78 @@ +#ifndef DISABLED_PNG_H +#define DISABLED_PNG_H + +static const unsigned char disabled_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xff, +0xff, 0xff, 0x40, 0x40, 0x40, 0xd4, 0xd0, 0xc8, +0x11, 0xa7, 0xec, 0x07, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x26, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, +0x00, 0x8c, 0x82, 0x20, 0x20, 0x04, 0x64, 0x18, +0x83, 0x80, 0x13, 0x90, 0x61, 0x08, 0x12, 0xa1, +0x26, 0xc3, 0x05, 0x04, 0x80, 0x0c, 0x26, 0x25, +0x30, 0x40, 0x58, 0x0e, 0x00, 0xa1, 0x61, 0x0a, +0x88, 0xb6, 0x0f, 0xc2, 0xed, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x38, 0x54, 0x30, 0x31, 0x3a, +0x30, 0x33, 0x3a, 0x35, 0x39, 0x2b, 0x30, 0x36, +0x3a, 0x30, 0x30, 0x68, 0xc6, 0x93, 0x0c, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *disabled_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_disabled_png = new wxImage(); + if (!img_disabled_png || !img_disabled_png->IsOk()) + { + wxMemoryInputStream img_disabled_pngIS(disabled_png_data, sizeof(disabled_png_data)); + img_disabled_png->LoadFile(img_disabled_pngIS, wxBITMAP_TYPE_PNG); + } + return img_disabled_png; +} +#define disabled_png_img disabled_png_img() + +static wxBitmap *disabled_png_bmp() +{ + static wxBitmap *bmp_disabled_png; + if (!bmp_disabled_png || !bmp_disabled_png->IsOk()) + bmp_disabled_png = new wxBitmap(*disabled_png_img); + return bmp_disabled_png; +} +#define disabled_png_bmp disabled_png_bmp() + +static wxIcon *disabled_png_ico() +{ + static wxIcon *ico_disabled_png; + if (!ico_disabled_png || !ico_disabled_png->IsOk()) + { + ico_disabled_png = new wxIcon(); + ico_disabled_png->CopyFromBitmap(*disabled_png_bmp); + } + return ico_disabled_png; +} +#define disabled_png_ico disabled_png_ico() + +#endif // DISABLED_PNG_H diff --git a/include/images/dnd_copy.png b/include/images/dnd_copy.png new file mode 100644 index 0000000..a65dc6f Binary files /dev/null and b/include/images/dnd_copy.png differ diff --git a/include/images/dnd_copy.pngc b/include/images/dnd_copy.pngc new file mode 100644 index 0000000..fc8d766 --- /dev/null +++ b/include/images/dnd_copy.pngc @@ -0,0 +1,83 @@ +#ifndef DND_COPY_PNG_H +#define DND_COPY_PNG_H + +static const unsigned char dnd_copy_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, +0xc7, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, +0x00, 0x00, 0xf5, 0xde, 0xb3, 0xd2, 0xb4, 0x8c, +0x66, 0x99, 0xff, 0xd4, 0xbc, 0xac, 0x3e, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5d, 0x49, 0x44, 0x41, +0x54, 0x28, 0xcf, 0x63, 0x60, 0x60, 0x10, 0x84, +0x01, 0x01, 0x06, 0x06, 0x05, 0x06, 0x20, 0x10, +0x36, 0x86, 0x02, 0x41, 0x74, 0x01, 0x11, 0x21, +0x25, 0x25, 0x25, 0x14, 0x01, 0x47, 0x74, 0x15, +0x2e, 0x02, 0xe8, 0x02, 0x8e, 0x0c, 0xa8, 0x86, +0x82, 0x2d, 0x02, 0x0b, 0x84, 0x82, 0x80, 0xb1, +0x89, 0x8b, 0x8b, 0x00, 0x8a, 0x0a, 0x24, 0x01, +0x88, 0x0a, 0x20, 0x40, 0x55, 0x81, 0x2c, 0x00, +0x52, 0x11, 0x8c, 0x4f, 0x85, 0x29, 0x41, 0x15, +0x83, 0xc5, 0x16, 0xa2, 0xcc, 0x08, 0x36, 0xc6, +0x6b, 0x06, 0xc5, 0x02, 0x82, 0x48, 0x40, 0x80, +0x01, 0x00, 0x68, 0xd0, 0x4c, 0xe0, 0x38, 0x0c, +0xf5, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dnd_copy_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dnd_copy_png = new wxImage(); + if (!img_dnd_copy_png || !img_dnd_copy_png->IsOk()) + { + wxMemoryInputStream img_dnd_copy_pngIS(dnd_copy_png_data, sizeof(dnd_copy_png_data)); + img_dnd_copy_png->LoadFile(img_dnd_copy_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dnd_copy_png; +} +#define dnd_copy_png_img dnd_copy_png_img() + +static wxBitmap *dnd_copy_png_bmp() +{ + static wxBitmap *bmp_dnd_copy_png; + if (!bmp_dnd_copy_png || !bmp_dnd_copy_png->IsOk()) + bmp_dnd_copy_png = new wxBitmap(*dnd_copy_png_img); + return bmp_dnd_copy_png; +} +#define dnd_copy_png_bmp dnd_copy_png_bmp() + +static wxIcon *dnd_copy_png_ico() +{ + static wxIcon *ico_dnd_copy_png; + if (!ico_dnd_copy_png || !ico_dnd_copy_png->IsOk()) + { + ico_dnd_copy_png = new wxIcon(); + ico_dnd_copy_png->CopyFromBitmap(*dnd_copy_png_bmp); + } + return ico_dnd_copy_png; +} +#define dnd_copy_png_ico dnd_copy_png_ico() + +#endif // DND_COPY_PNG_H diff --git a/include/images/dnd_move.png b/include/images/dnd_move.png new file mode 100644 index 0000000..ca09dcf Binary files /dev/null and b/include/images/dnd_move.png differ diff --git a/include/images/dnd_move.pngc b/include/images/dnd_move.pngc new file mode 100644 index 0000000..9aee9fe --- /dev/null +++ b/include/images/dnd_move.pngc @@ -0,0 +1,82 @@ +#ifndef DND_MOVE_PNG_H +#define DND_MOVE_PNG_H + +static const unsigned char dnd_move_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, +0xc7, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, +0xde, 0xb3, 0xd2, 0xb4, 0x8c, 0x66, 0x99, 0xff, +0x4d, 0x80, 0x23, 0x74, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x56, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, +0x63, 0x60, 0x60, 0x10, 0x84, 0x01, 0x01, 0x06, +0x08, 0x10, 0x52, 0x82, 0x02, 0x41, 0x74, 0x01, +0x61, 0x01, 0x74, 0x01, 0x43, 0x74, 0x01, 0x63, +0x01, 0x74, 0x01, 0x43, 0x34, 0x43, 0xa1, 0x16, +0x01, 0x05, 0x5c, 0x40, 0x40, 0x49, 0xd9, 0xd8, +0x58, 0x00, 0x45, 0x05, 0x92, 0x00, 0x44, 0x05, +0x10, 0xa0, 0xaa, 0x40, 0x16, 0x00, 0xa9, 0x70, +0xc2, 0xa7, 0x42, 0x85, 0xa0, 0x8a, 0xc1, 0x62, +0x0b, 0x51, 0x66, 0x38, 0x29, 0xe1, 0x35, 0x83, +0x62, 0x01, 0x41, 0x24, 0x20, 0xc0, 0x00, 0x00, +0xfe, 0xa4, 0x36, 0xdc, 0x20, 0x16, 0x64, 0xcc, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dnd_move_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dnd_move_png = new wxImage(); + if (!img_dnd_move_png || !img_dnd_move_png->IsOk()) + { + wxMemoryInputStream img_dnd_move_pngIS(dnd_move_png_data, sizeof(dnd_move_png_data)); + img_dnd_move_png->LoadFile(img_dnd_move_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dnd_move_png; +} +#define dnd_move_png_img dnd_move_png_img() + +static wxBitmap *dnd_move_png_bmp() +{ + static wxBitmap *bmp_dnd_move_png; + if (!bmp_dnd_move_png || !bmp_dnd_move_png->IsOk()) + bmp_dnd_move_png = new wxBitmap(*dnd_move_png_img); + return bmp_dnd_move_png; +} +#define dnd_move_png_bmp dnd_move_png_bmp() + +static wxIcon *dnd_move_png_ico() +{ + static wxIcon *ico_dnd_move_png; + if (!ico_dnd_move_png || !ico_dnd_move_png->IsOk()) + { + ico_dnd_move_png = new wxIcon(); + ico_dnd_move_png->CopyFromBitmap(*dnd_move_png_bmp); + } + return ico_dnd_move_png; +} +#define dnd_move_png_ico dnd_move_png_ico() + +#endif // DND_MOVE_PNG_H diff --git a/include/images/dnd_none.png b/include/images/dnd_none.png new file mode 100644 index 0000000..c7345e2 Binary files /dev/null and b/include/images/dnd_none.png differ diff --git a/include/images/dnd_none.pngc b/include/images/dnd_none.pngc new file mode 100644 index 0000000..629cf04 --- /dev/null +++ b/include/images/dnd_none.pngc @@ -0,0 +1,90 @@ +#ifndef DND_NONE_PNG_H +#define DND_NONE_PNG_H + +static const unsigned char dnd_none_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x04, 0x03, 0x00, 0x00, 0x00, 0x81, 0x54, 0x67, +0xc7, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, +0xde, 0xb3, 0xd2, 0xb4, 0x8c, 0xff, 0x00, 0x00, +0x66, 0x99, 0xff, 0x06, 0x09, 0x80, 0xc5, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x94, 0x49, 0x44, 0x41, +0x54, 0x28, 0xcf, 0x75, 0x90, 0xd1, 0x0d, 0xc3, +0x20, 0x0c, 0x44, 0x3d, 0x02, 0xa4, 0x9d, 0xe0, +0xe2, 0x0e, 0x10, 0xd1, 0x09, 0xe8, 0x06, 0x08, +0xf6, 0x5f, 0xa5, 0x21, 0xb6, 0x0b, 0x31, 0xea, +0x7d, 0x3e, 0x9e, 0x6c, 0x7c, 0x44, 0x14, 0x2d, +0x81, 0x24, 0x1b, 0x34, 0xd1, 0x83, 0x47, 0xf0, +0xe0, 0xf0, 0x20, 0x05, 0x0f, 0x0e, 0x37, 0x54, +0x17, 0x3d, 0x81, 0xd6, 0x83, 0x3d, 0xbd, 0x2f, +0xb0, 0x65, 0x35, 0xf6, 0xf4, 0x11, 0xc0, 0x6a, +0x80, 0x21, 0x00, 0xa6, 0x64, 0x03, 0xa2, 0x14, +0x86, 0x01, 0x55, 0xf2, 0x00, 0xdc, 0x8d, 0x8a, +0x01, 0x2e, 0x25, 0x4f, 0xa0, 0x55, 0x11, 0x86, +0x71, 0x3e, 0xe7, 0x1b, 0x68, 0xb5, 0xb6, 0x72, +0x33, 0x74, 0x91, 0x81, 0xd7, 0x6a, 0xb8, 0x19, +0xeb, 0x16, 0xff, 0x8f, 0xe5, 0xa7, 0xfe, 0x96, +0x2e, 0x94, 0x5e, 0xc7, 0xbf, 0x3e, 0xd8, 0x5a, +0xb6, 0xc6, 0x4c, 0x38, 0x15, 0x6b, 0xfd, 0xa7, +0x4c, 0xb7, 0x60, 0xdc, 0x12, 0xa7, 0x04, 0xfa, +0x02, 0xae, 0xf4, 0x3c, 0xbb, 0xe1, 0x52, 0x5e, +0xa7, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *dnd_none_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_dnd_none_png = new wxImage(); + if (!img_dnd_none_png || !img_dnd_none_png->IsOk()) + { + wxMemoryInputStream img_dnd_none_pngIS(dnd_none_png_data, sizeof(dnd_none_png_data)); + img_dnd_none_png->LoadFile(img_dnd_none_pngIS, wxBITMAP_TYPE_PNG); + } + return img_dnd_none_png; +} +#define dnd_none_png_img dnd_none_png_img() + +static wxBitmap *dnd_none_png_bmp() +{ + static wxBitmap *bmp_dnd_none_png; + if (!bmp_dnd_none_png || !bmp_dnd_none_png->IsOk()) + bmp_dnd_none_png = new wxBitmap(*dnd_none_png_img); + return bmp_dnd_none_png; +} +#define dnd_none_png_bmp dnd_none_png_bmp() + +static wxIcon *dnd_none_png_ico() +{ + static wxIcon *ico_dnd_none_png; + if (!ico_dnd_none_png || !ico_dnd_none_png->IsOk()) + { + ico_dnd_none_png = new wxIcon(); + ico_dnd_none_png->CopyFromBitmap(*dnd_none_png_bmp); + } + return ico_dnd_none_png; +} +#define dnd_none_png_ico dnd_none_png_ico() + +#endif // DND_NONE_PNG_H diff --git a/include/images/domain-sm.png b/include/images/domain-sm.png new file mode 100644 index 0000000..7521cdd Binary files /dev/null and b/include/images/domain-sm.png differ diff --git a/include/images/domain-sm.pngc b/include/images/domain-sm.pngc new file mode 100644 index 0000000..19f4ca1 --- /dev/null +++ b/include/images/domain-sm.pngc @@ -0,0 +1,95 @@ +#ifndef DOMAIN_SM_PNG_H +#define DOMAIN_SM_PNG_H + +static const unsigned char domain_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x66, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdc, 0x5b, 0x5b, 0xc8, +0x40, 0x40, 0xc2, 0x29, 0x29, 0xc1, 0x2a, 0x2a, +0xc6, 0x3e, 0x3e, 0xb9, 0x31, 0x31, 0xe1, 0xa2, +0xa9, 0xc2, 0x2d, 0x2d, 0xc7, 0x3f, 0x3f, 0xe3, +0xbd, 0xc5, 0xe5, 0xe2, 0xec, 0xdf, 0xbb, 0xc4, +0xc4, 0x2e, 0x2e, 0xe5, 0xe6, 0xf1, 0xe4, 0xe9, +0xf5, 0xe1, 0xe4, 0xf0, 0xda, 0xb9, 0xc3, 0xd6, +0x4f, 0x52, 0xe1, 0xe8, 0xf4, 0xde, 0xe7, 0xf4, +0xdb, 0xe2, 0xef, 0xd6, 0xb7, 0xc3, 0xdc, 0x54, +0x54, 0x6f, 0x6f, 0x6f, 0xe6, 0xea, 0xf5, 0xdb, +0xe5, 0xf3, 0xd8, 0xe4, 0xf3, 0xd5, 0xe3, 0xf3, +0x81, 0x60, 0x2b, 0xd2, 0xe2, 0xf2, 0xcf, 0xe1, +0xf2, 0xcd, 0xe0, 0xf1, 0xcb, 0xdf, 0xf1, 0xc9, +0xa9, 0x53, 0x58, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x62, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, +0xcf, 0xc9, 0x12, 0x40, 0x30, 0x0c, 0x80, 0xe1, +0x2a, 0x62, 0x5f, 0x5b, 0x54, 0x77, 0xef, 0xff, +0x92, 0x6a, 0x86, 0x09, 0x4e, 0xcd, 0xed, 0xff, +0x26, 0x39, 0x84, 0x90, 0xd8, 0x49, 0x7e, 0x4d, +0xd3, 0xec, 0xd3, 0x39, 0x14, 0x50, 0xbe, 0xba, +0x82, 0xba, 0x69, 0xa1, 0xc3, 0x7d, 0xa8, 0xfb, +0x61, 0x9c, 0x80, 0xde, 0x3d, 0x5f, 0xcd, 0xf8, +0xb2, 0xc2, 0x76, 0x8b, 0xd8, 0x43, 0x4b, 0xa5, +0xc5, 0x73, 0x22, 0x06, 0x66, 0x8c, 0xd1, 0x16, +0x81, 0xf1, 0x00, 0xd6, 0x21, 0x70, 0x19, 0xc0, +0x79, 0x04, 0xa9, 0x02, 0xf8, 0x03, 0xe1, 0x99, +0xb8, 0x2f, 0x4f, 0xb3, 0x75, 0x06, 0xdb, 0xf0, +0xa7, 0x4c, 0xa5, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *domain_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_domain_sm_png = new wxImage(); + if (!img_domain_sm_png || !img_domain_sm_png->IsOk()) + { + wxMemoryInputStream img_domain_sm_pngIS(domain_sm_png_data, sizeof(domain_sm_png_data)); + img_domain_sm_png->LoadFile(img_domain_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_domain_sm_png; +} +#define domain_sm_png_img domain_sm_png_img() + +static wxBitmap *domain_sm_png_bmp() +{ + static wxBitmap *bmp_domain_sm_png; + if (!bmp_domain_sm_png || !bmp_domain_sm_png->IsOk()) + bmp_domain_sm_png = new wxBitmap(*domain_sm_png_img); + return bmp_domain_sm_png; +} +#define domain_sm_png_bmp domain_sm_png_bmp() + +static wxIcon *domain_sm_png_ico() +{ + static wxIcon *ico_domain_sm_png; + if (!ico_domain_sm_png || !ico_domain_sm_png->IsOk()) + { + ico_domain_sm_png = new wxIcon(); + ico_domain_sm_png->CopyFromBitmap(*domain_sm_png_bmp); + } + return ico_domain_sm_png; +} +#define domain_sm_png_ico domain_sm_png_ico() + +#endif // DOMAIN_SM_PNG_H diff --git a/include/images/domain.png b/include/images/domain.png new file mode 100644 index 0000000..42ca929 Binary files /dev/null and b/include/images/domain.png differ diff --git a/include/images/domain.pngc b/include/images/domain.pngc new file mode 100644 index 0000000..8ff545c --- /dev/null +++ b/include/images/domain.pngc @@ -0,0 +1,97 @@ +#ifndef DOMAIN_PNG_H +#define DOMAIN_PNG_H + +static const unsigned char domain_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x6c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe1, 0x6b, 0x6b, 0xc8, +0x40, 0x40, 0xc2, 0x29, 0x29, 0xb9, 0x31, 0x31, +0xe0, 0xa3, 0xaa, 0xe2, 0xbc, 0xc4, 0xe5, 0xe2, +0xec, 0xdf, 0xbb, 0xc4, 0xe5, 0xe6, 0xf1, 0xe4, +0xe9, 0xf5, 0xe2, 0xe4, 0xf1, 0xdb, 0xb9, 0xc3, +0xe2, 0xe8, 0xf5, 0xdf, 0xe7, 0xf4, 0xdd, 0xe2, +0xf0, 0xd8, 0xb8, 0xc3, 0xf4, 0xcc, 0xcc, 0xe2, +0x70, 0x70, 0xb7, 0x32, 0x32, 0xdd, 0xe6, 0xf4, +0xdb, 0xe5, 0xf3, 0xd8, 0xe1, 0xef, 0xd4, 0xb7, +0xc3, 0x7b, 0x66, 0x66, 0xd8, 0xe4, 0xf3, 0xd6, +0xe4, 0xf3, 0xd4, 0xe0, 0xee, 0x6f, 0x6f, 0x6f, +0x81, 0x60, 0x2b, 0xd4, 0xe3, 0xf2, 0xd1, 0xe2, +0xf2, 0xcf, 0xe1, 0xf2, 0xcd, 0xe0, 0xf2, 0xcc, +0xe0, 0xf1, 0xca, 0xdf, 0xf1, 0x1b, 0xe0, 0x89, +0x6f, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x73, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x75, 0xcf, 0xeb, +0x12, 0x82, 0x20, 0x14, 0x46, 0x51, 0x23, 0xd4, +0xca, 0x3b, 0x94, 0xa1, 0x82, 0x5c, 0x7a, 0xff, +0x77, 0xec, 0x13, 0x25, 0xd3, 0x51, 0xfe, 0xed, +0xc5, 0x39, 0xcc, 0x10, 0x45, 0x27, 0xe7, 0xb2, +0x6b, 0x72, 0x25, 0xdb, 0xa6, 0x31, 0x25, 0x9b, +0x4e, 0xd2, 0xdb, 0x9f, 0xa0, 0xef, 0x8f, 0x2c, +0xff, 0x89, 0xef, 0xa2, 0xac, 0x6a, 0x4a, 0x9a, +0xa9, 0x19, 0xf7, 0xfd, 0x7c, 0xb5, 0x6f, 0xce, +0xfc, 0x84, 0x98, 0xbb, 0xeb, 0x07, 0x31, 0xaf, +0x48, 0xb4, 0x52, 0xaa, 0x1f, 0xb5, 0x5c, 0x00, +0xf7, 0x80, 0x51, 0x9b, 0x00, 0x98, 0x07, 0x68, +0x63, 0x03, 0x60, 0x1f, 0x60, 0xac, 0x0b, 0x80, +0xf7, 0x00, 0xd6, 0x7d, 0x02, 0xac, 0xe7, 0xe8, +0xdb, 0x5f, 0x4f, 0xdf, 0x09, 0x81, 0xd1, 0x85, +0xde, 0x6b, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *domain_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_domain_png = new wxImage(); + if (!img_domain_png || !img_domain_png->IsOk()) + { + wxMemoryInputStream img_domain_pngIS(domain_png_data, sizeof(domain_png_data)); + img_domain_png->LoadFile(img_domain_pngIS, wxBITMAP_TYPE_PNG); + } + return img_domain_png; +} +#define domain_png_img domain_png_img() + +static wxBitmap *domain_png_bmp() +{ + static wxBitmap *bmp_domain_png; + if (!bmp_domain_png || !bmp_domain_png->IsOk()) + bmp_domain_png = new wxBitmap(*domain_png_img); + return bmp_domain_png; +} +#define domain_png_bmp domain_png_bmp() + +static wxIcon *domain_png_ico() +{ + static wxIcon *ico_domain_png; + if (!ico_domain_png || !ico_domain_png->IsOk()) + { + ico_domain_png = new wxIcon(); + ico_domain_png->CopyFromBitmap(*domain_png_bmp); + } + return ico_domain_png; +} +#define domain_png_ico domain_png_ico() + +#endif // DOMAIN_PNG_H diff --git a/include/images/domains.png b/include/images/domains.png new file mode 100644 index 0000000..5562152 Binary files /dev/null and b/include/images/domains.png differ diff --git a/include/images/domains.pngc b/include/images/domains.pngc new file mode 100644 index 0000000..777d8f1 --- /dev/null +++ b/include/images/domains.pngc @@ -0,0 +1,102 @@ +#ifndef DOMAINS_PNG_H +#define DOMAINS_PNG_H + +static const unsigned char domains_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x7e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe1, 0x6b, 0x6b, 0xc8, +0x40, 0x40, 0xc2, 0x29, 0x29, 0xb9, 0x31, 0x31, +0xe1, 0xa2, 0xa9, 0xbe, 0x2c, 0x2c, 0xce, 0x29, +0x29, 0xe3, 0xba, 0xc2, 0xe0, 0xb6, 0xbd, 0xc4, +0x38, 0x39, 0xc2, 0x2d, 0x2d, 0xe0, 0xb9, 0xc1, +0xc5, 0x3d, 0x3e, 0xcc, 0x22, 0x22, 0xdc, 0x54, +0x54, 0xc1, 0x2a, 0x2a, 0x6f, 0x6f, 0x6f, 0xe1, +0xbc, 0xc4, 0xe1, 0xa4, 0xab, 0xd6, 0x4f, 0x52, +0xe3, 0xbd, 0xc5, 0xe5, 0xe2, 0xec, 0xdf, 0xbb, +0xc4, 0xc4, 0x2e, 0x2e, 0xe1, 0xe8, 0xf4, 0xe5, +0xe6, 0xf1, 0xe4, 0xe9, 0xf5, 0xe1, 0xe4, 0xf0, +0xda, 0xb9, 0xc3, 0xde, 0xe7, 0xf4, 0xdb, 0xe2, +0xef, 0xd6, 0xb7, 0xc3, 0xdb, 0xe5, 0xf3, 0xe6, +0xea, 0xf5, 0xd8, 0xe4, 0xf3, 0xd5, 0xe3, 0xf3, +0x81, 0x60, 0x2b, 0xd2, 0xe2, 0xf2, 0xcf, 0xe1, +0xf2, 0xcd, 0xe0, 0xf1, 0xcb, 0xdf, 0xf1, 0xe1, +0x87, 0x56, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x87, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x55, +0x8e, 0xdb, 0x16, 0x82, 0x20, 0x14, 0x05, 0x49, +0x4f, 0x17, 0x2b, 0xb3, 0x53, 0x5a, 0x91, 0x45, +0x91, 0xa2, 0xf6, 0xff, 0x3f, 0xd8, 0xe6, 0x04, +0xab, 0xd8, 0x6f, 0x33, 0x6b, 0xb8, 0x28, 0xe5, +0x37, 0x53, 0xe9, 0xb2, 0x3c, 0x4b, 0x99, 0xe6, +0x8b, 0x65, 0xc2, 0xab, 0x62, 0x9d, 0x6f, 0xfe, +0x79, 0x5b, 0xa2, 0xd9, 0x05, 0xae, 0x84, 0x7d, +0xb3, 0x0f, 0x86, 0x0f, 0xa5, 0xb8, 0x23, 0x85, +0x53, 0x5c, 0x0b, 0x37, 0xa7, 0x33, 0x5d, 0xbe, +0x42, 0xfb, 0xa6, 0xb9, 0xb6, 0xb7, 0x3b, 0xc9, +0xeb, 0x6c, 0xd0, 0x80, 0xb5, 0x79, 0x3c, 0xa9, +0xf2, 0xc2, 0xa2, 0x79, 0x81, 0x6d, 0xd7, 0xb3, +0x14, 0x8c, 0xa6, 0xd5, 0xce, 0xb9, 0x7e, 0xe0, +0x70, 0x2d, 0x1a, 0x03, 0x31, 0x8c, 0x51, 0xa0, +0xb1, 0x10, 0xe3, 0xc4, 0xf1, 0xb7, 0x6c, 0x3b, +0x88, 0xe9, 0xfd, 0x13, 0x71, 0x4a, 0x7d, 0x00, +0xed, 0x6a, 0x0b, 0x34, 0xc8, 0xd1, 0x6e, 0xaf, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *domains_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_domains_png = new wxImage(); + if (!img_domains_png || !img_domains_png->IsOk()) + { + wxMemoryInputStream img_domains_pngIS(domains_png_data, sizeof(domains_png_data)); + img_domains_png->LoadFile(img_domains_pngIS, wxBITMAP_TYPE_PNG); + } + return img_domains_png; +} +#define domains_png_img domains_png_img() + +static wxBitmap *domains_png_bmp() +{ + static wxBitmap *bmp_domains_png; + if (!bmp_domains_png || !bmp_domains_png->IsOk()) + bmp_domains_png = new wxBitmap(*domains_png_img); + return bmp_domains_png; +} +#define domains_png_bmp domains_png_bmp() + +static wxIcon *domains_png_ico() +{ + static wxIcon *ico_domains_png; + if (!ico_domains_png || !ico_domains_png->IsOk()) + { + ico_domains_png = new wxIcon(); + ico_domains_png->CopyFromBitmap(*domains_png_bmp); + } + return ico_domains_png; +} +#define domains_png_ico domains_png_ico() + +#endif // DOMAINS_PNG_H diff --git a/include/images/down.png b/include/images/down.png new file mode 100644 index 0000000..4850c67 Binary files /dev/null and b/include/images/down.png differ diff --git a/include/images/down.pngc b/include/images/down.pngc new file mode 100644 index 0000000..3da1e4e --- /dev/null +++ b/include/images/down.pngc @@ -0,0 +1,93 @@ +#ifndef DOWN_PNG_H +#define DOWN_PNG_H + +static const unsigned char down_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xba, 0xd4, 0x85, 0x9f, 0xc3, +0x53, 0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, +0xba, 0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, +0x94, 0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xba, 0xd4, +0x83, 0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, +0xbb, 0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, +0xb1, 0xcd, 0x69, 0xba, 0xd3, 0x83, 0x9e, 0xc2, +0x4f, 0x96, 0xbc, 0x3d, 0x9b, 0xbf, 0x43, 0xb4, +0xcf, 0x70, 0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, +0xcc, 0xdf, 0xa3, 0x6d, 0x2e, 0x72, 0xd0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x49, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x47, 0x0e, 0x80, +0x30, 0x0c, 0x05, 0x51, 0xdb, 0x84, 0xde, 0x7b, +0xef, 0x70, 0xff, 0x2b, 0x92, 0xaf, 0x08, 0x65, +0x76, 0x4f, 0x43, 0x2c, 0x36, 0x26, 0x71, 0x94, +0xeb, 0xf9, 0x41, 0x18, 0xc5, 0x49, 0x2a, 0xc4, +0x92, 0xe5, 0x45, 0x59, 0xd5, 0x4d, 0xdb, 0xe9, +0xa7, 0xd9, 0x0f, 0xe3, 0x34, 0x2f, 0x2b, 0x00, +0x6e, 0xfb, 0x71, 0x5e, 0x06, 0xa0, 0xba, 0x9f, +0x1f, 0xe0, 0x6b, 0x01, 0x1a, 0x7c, 0xb9, 0x54, +0x02, 0xff, 0x7a, 0xee, 0x99, 0x94, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, +0x31, 0x2d, 0x32, 0x35, 0x54, 0x31, 0x35, 0x3a, +0x30, 0x37, 0x3a, 0x33, 0x36, 0x2b, 0x30, 0x36, +0x3a, 0x30, 0x30, 0xbe, 0x1e, 0xd2, 0x9f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x38, 0x54, 0x30, 0x31, +0x3a, 0x30, 0x33, 0x3a, 0x35, 0x39, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0x68, 0xc6, 0x93, 0x0c, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *down_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_down_png = new wxImage(); + if (!img_down_png || !img_down_png->IsOk()) + { + wxMemoryInputStream img_down_pngIS(down_png_data, sizeof(down_png_data)); + img_down_png->LoadFile(img_down_pngIS, wxBITMAP_TYPE_PNG); + } + return img_down_png; +} +#define down_png_img down_png_img() + +static wxBitmap *down_png_bmp() +{ + static wxBitmap *bmp_down_png; + if (!bmp_down_png || !bmp_down_png->IsOk()) + bmp_down_png = new wxBitmap(*down_png_img); + return bmp_down_png; +} +#define down_png_bmp down_png_bmp() + +static wxIcon *down_png_ico() +{ + static wxIcon *ico_down_png; + if (!ico_down_png || !ico_down_png->IsOk()) + { + ico_down_png = new wxIcon(); + ico_down_png->CopyFromBitmap(*down_png_bmp); + } + return ico_down_png; +} +#define down_png_ico down_png_ico() + +#endif // DOWN_PNG_H diff --git a/include/images/drop.png b/include/images/drop.png new file mode 100644 index 0000000..45bd85b Binary files /dev/null and b/include/images/drop.png differ diff --git a/include/images/drop.pngc b/include/images/drop.pngc new file mode 100644 index 0000000..f884583 --- /dev/null +++ b/include/images/drop.pngc @@ -0,0 +1,159 @@ +#ifndef DROP_PNG_H +#define DROP_PNG_H + +static const unsigned char drop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdd, 0xdd, 0xdd, 0xc9, +0xc9, 0xc9, 0xb9, 0xb9, 0xb9, 0xa5, 0xa5, 0xa5, +0x9d, 0x9d, 0x9d, 0x8b, 0x8b, 0x8b, 0x83, 0x83, +0x83, 0x76, 0x76, 0x76, 0x6c, 0x6c, 0x6c, 0xb2, +0xb2, 0xb2, 0xc5, 0xc5, 0xc5, 0xd1, 0xd1, 0xd1, +0xea, 0xea, 0xea, 0xf0, 0xf0, 0xf0, 0xf5, 0xf5, +0xf5, 0xed, 0xed, 0xed, 0xe3, 0xe4, 0xe3, 0xd9, +0xd9, 0xd9, 0xc0, 0xc0, 0xc0, 0xac, 0xac, 0xac, +0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xd5, 0xd5, +0xd5, 0x7d, 0x7d, 0x7d, 0xcd, 0xcd, 0xcd, 0x95, +0x95, 0x95, 0xe8, 0xe8, 0xe8, 0xda, 0xe1, 0xd8, +0xc9, 0xdb, 0xc4, 0xc7, 0xd9, 0xc1, 0xcf, 0xda, +0xcc, 0x6b, 0xad, 0x54, 0x46, 0x9b, 0x2b, 0x3b, +0x92, 0x22, 0x5e, 0xa6, 0x48, 0xdb, 0xde, 0xda, +0x53, 0xa2, 0x39, 0x82, 0xb3, 0x74, 0xb2, 0xcb, +0xaa, 0xd3, 0xd3, 0xd3, 0x9a, 0xc1, 0x8d, 0x4e, +0x9e, 0x35, 0xc3, 0xd5, 0xbd, 0x46, 0x95, 0x32, +0xd6, 0xda, 0xd4, 0xa5, 0xc4, 0x9c, 0x91, 0xb9, +0x85, 0x76, 0xac, 0x66, 0xba, 0xcb, 0xb5, 0xc6, +0xd7, 0xc0, 0x2f, 0x89, 0x19, 0x8c, 0xb1, 0x83, +0xb0, 0xc5, 0xaa, 0xab, 0xc0, 0xa6, 0xc9, 0xcf, +0xc7, 0xce, 0xd2, 0xcd, 0xc9, 0xce, 0xc8, 0x54, +0x98, 0x44, 0xc1, 0xca, 0xbe, 0xb5, 0xc1, 0xb3, +0x63, 0x9f, 0x55, 0xa5, 0xbc, 0x9f, 0xc0, 0xc6, +0xbe, 0x82, 0xd3, 0x54, 0xa7, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x0e, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x8d, 0x93, 0xd9, 0x56, 0xa3, 0x40, 0x14, +0x45, 0x53, 0x33, 0x43, 0x05, 0x52, 0x33, 0xe0, +0x10, 0x21, 0x31, 0x62, 0x8c, 0x82, 0x9d, 0xb4, +0xda, 0x0e, 0xed, 0xff, 0xff, 0x95, 0x55, 0x21, +0x98, 0xf8, 0xe6, 0x79, 0xdd, 0x7b, 0x5d, 0x0e, +0x97, 0xcb, 0x64, 0xf2, 0xab, 0x00, 0x88, 0x30, +0xa1, 0x2c, 0x8a, 0x43, 0x22, 0x46, 0x09, 0x46, +0x10, 0x1c, 0x31, 0x24, 0x11, 0x25, 0x49, 0xca, +0xc1, 0x34, 0xcb, 0xf3, 0x7c, 0x26, 0x24, 0x54, +0x9a, 0xd0, 0x08, 0xc3, 0x03, 0x57, 0x0c, 0x89, +0x7c, 0x9f, 0x6c, 0x36, 0x35, 0xc2, 0x02, 0x29, +0x9d, 0xe3, 0x3c, 0xd5, 0x85, 0x1a, 0x04, 0x46, +0x91, 0xcd, 0x46, 0xe6, 0x78, 0x09, 0x53, 0x85, +0x50, 0x92, 0xf8, 0x21, 0x6c, 0x10, 0xa8, 0xd2, +0x05, 0xad, 0x70, 0x82, 0x94, 0x4a, 0x95, 0x42, +0x89, 0xc6, 0xa4, 0xa2, 0xac, 0x28, 0x30, 0xa2, +0x83, 0x50, 0xa5, 0xf9, 0x54, 0xaa, 0x64, 0x2c, +0x19, 0x85, 0x92, 0x5a, 0x71, 0x3b, 0x55, 0xd5, +0x20, 0x68, 0x9d, 0x1f, 0x93, 0xf9, 0xcc, 0x66, +0xb3, 0xe9, 0x99, 0x11, 0x46, 0xeb, 0x43, 0xc9, +0x2a, 0xcf, 0xf6, 0x60, 0x4f, 0xa6, 0x9e, 0x19, +0x23, 0x84, 0xb5, 0xa6, 0x3a, 0x94, 0x74, 0xec, +0x1b, 0x9f, 0x5f, 0x5c, 0x5c, 0xce, 0x07, 0x6c, +0x81, 0x29, 0xdc, 0x20, 0x98, 0xf8, 0x80, 0x2f, +0xaf, 0xae, 0xae, 0xea, 0xba, 0x59, 0x2c, 0x03, +0x06, 0x40, 0xc4, 0xe6, 0xb0, 0x88, 0x02, 0xec, +0xf9, 0xd9, 0xa2, 0xae, 0xaf, 0x17, 0x75, 0xd3, +0xac, 0x6e, 0x40, 0x48, 0x5b, 0x8c, 0x9b, 0xa4, +0x30, 0x0b, 0x0f, 0xbf, 0x5d, 0x7b, 0xe1, 0xce, +0x8f, 0x68, 0x6e, 0x81, 0x5f, 0x96, 0x4c, 0xe9, +0x28, 0xe0, 0x24, 0xf3, 0xdd, 0xe6, 0x9e, 0xd7, +0x37, 0x62, 0xd5, 0x34, 0x9b, 0xfb, 0xc0, 0xa5, +0xc6, 0xa3, 0x80, 0x48, 0x16, 0xba, 0x3f, 0x5c, +0xd7, 0x2b, 0xbb, 0xec, 0x56, 0x7d, 0xe7, 0x1e, +0xfd, 0xb6, 0x25, 0x41, 0xa3, 0x50, 0xb2, 0xec, +0xec, 0xfc, 0xf2, 0xcf, 0xdd, 0xbc, 0xbb, 0xb7, +0x60, 0xb9, 0x94, 0x0f, 0x9b, 0x4d, 0xeb, 0x5a, +0xc0, 0xca, 0x51, 0x10, 0xf1, 0xcc, 0x88, 0xbe, +0xae, 0xbb, 0xd0, 0x1d, 0xc8, 0x7e, 0xbb, 0xdd, +0xee, 0xda, 0x16, 0xc4, 0xe2, 0xfb, 0x7b, 0x47, +0xd6, 0x9c, 0x87, 0x06, 0x73, 0x19, 0x1e, 0xfe, +0xd7, 0x0b, 0x0d, 0x6c, 0x5d, 0x74, 0x3c, 0x08, +0x5a, 0x8a, 0xb9, 0xe7, 0xfd, 0x43, 0xe8, 0xe6, +0x5c, 0x18, 0xf1, 0xc4, 0x8f, 0x2f, 0x31, 0x99, +0x10, 0x64, 0xc0, 0xaa, 0x5e, 0x0f, 0xf8, 0xf9, +0xe5, 0xdf, 0x66, 0xfb, 0xfa, 0xc6, 0x13, 0x72, +0x14, 0x12, 0x6c, 0x40, 0xd7, 0x2f, 0xfa, 0x55, +0xdf, 0x3f, 0xb7, 0xfd, 0x6e, 0xd7, 0xbf, 0xf6, +0xa5, 0x23, 0xc9, 0xc9, 0xcd, 0x51, 0x21, 0xe7, +0xeb, 0xc6, 0xaf, 0xa8, 0x79, 0x7b, 0xda, 0x86, +0xbc, 0x43, 0x47, 0xe1, 0x51, 0x90, 0x91, 0x91, +0xb2, 0x6b, 0x42, 0x1e, 0x3f, 0x02, 0xff, 0x80, +0xd0, 0x45, 0xf2, 0xe4, 0xaa, 0x63, 0x2b, 0xdd, +0xcb, 0xda, 0xf3, 0xed, 0xfb, 0xff, 0x61, 0x40, +0xea, 0xe2, 0xd3, 0xb3, 0x67, 0x50, 0xba, 0xf6, +0xad, 0xeb, 0xba, 0xdd, 0x27, 0xfc, 0xd8, 0xed, +0x3c, 0x87, 0x29, 0x3b, 0x15, 0x2a, 0x24, 0xb9, +0x4f, 0xe9, 0x03, 0x3f, 0x55, 0xea, 0x03, 0x51, +0x75, 0x2a, 0x68, 0x0c, 0xf6, 0x18, 0x86, 0x04, +0x9e, 0x72, 0xac, 0x4f, 0x05, 0x4b, 0xb0, 0xf4, +0x33, 0x82, 0x90, 0x06, 0x87, 0x73, 0x4c, 0xec, +0x8f, 0x7f, 0xcf, 0x62, 0x56, 0x69, 0x04, 0xb9, +0x93, 0xae, 0x4c, 0x91, 0xae, 0x0a, 0xfc, 0x93, +0xfb, 0x70, 0x84, 0xab, 0xfd, 0xdd, 0x47, 0xac, +0xc2, 0x88, 0xff, 0xee, 0x9f, 0xfe, 0x55, 0xbe, +0x00, 0xd0, 0x54, 0x38, 0x4c, 0x0d, 0x6f, 0x60, +0xf3, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *drop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_drop_png = new wxImage(); + if (!img_drop_png || !img_drop_png->IsOk()) + { + wxMemoryInputStream img_drop_pngIS(drop_png_data, sizeof(drop_png_data)); + img_drop_png->LoadFile(img_drop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_drop_png; +} +#define drop_png_img drop_png_img() + +static wxBitmap *drop_png_bmp() +{ + static wxBitmap *bmp_drop_png; + if (!bmp_drop_png || !bmp_drop_png->IsOk()) + bmp_drop_png = new wxBitmap(*drop_png_img); + return bmp_drop_png; +} +#define drop_png_bmp drop_png_bmp() + +static wxIcon *drop_png_ico() +{ + static wxIcon *ico_drop_png; + if (!ico_drop_png || !ico_drop_png->IsOk()) + { + ico_drop_png = new wxIcon(); + ico_drop_png->CopyFromBitmap(*drop_png_bmp); + } + return ico_drop_png; +} +#define drop_png_ico drop_png_ico() + +#endif // DROP_PNG_H diff --git a/include/images/edit_clear.png b/include/images/edit_clear.png new file mode 100644 index 0000000..7dae00b Binary files /dev/null and b/include/images/edit_clear.png differ diff --git a/include/images/edit_clear.pngc b/include/images/edit_clear.pngc new file mode 100644 index 0000000..a0c7f0f --- /dev/null +++ b/include/images/edit_clear.pngc @@ -0,0 +1,122 @@ +#ifndef EDIT_CLEAR_PNG_H +#define EDIT_CLEAR_PNG_H + +static const unsigned char edit_clear_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x08, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xba, +0xba, 0xba, 0x99, 0x99, 0x99, 0x9a, 0x9a, 0x99, +0xa7, 0xa7, 0xa7, 0xc6, 0xc6, 0xc6, 0xa0, 0xa0, +0xa0, 0x90, 0x90, 0x90, 0xd1, 0xd1, 0xcf, 0xec, +0xec, 0xe9, 0x87, 0x87, 0x87, 0x82, 0x82, 0x82, +0xc0, 0xc0, 0xbe, 0xf1, 0xf1, 0xf0, 0xea, 0xea, +0xe9, 0xe9, 0xe9, 0xe7, 0xbe, 0xbe, 0xbb, 0x7f, +0x7f, 0x7f, 0xb2, 0xb2, 0xb2, 0xaf, 0xaf, 0xae, +0xeb, 0xeb, 0xe9, 0xee, 0xee, 0xed, 0xe8, 0xe8, +0xe8, 0xe3, 0xe3, 0xe3, 0xe1, 0xe1, 0xe0, 0xe4, +0xe4, 0xe1, 0x90, 0x90, 0x8f, 0xbd, 0xbd, 0xbd, +0x9c, 0x9c, 0x9c, 0x9d, 0x9d, 0x9d, 0xde, 0xde, +0xdd, 0xeb, 0xeb, 0xeb, 0xe7, 0xe7, 0xe7, 0xdf, +0xdf, 0xdf, 0xdc, 0xdc, 0xdc, 0xdd, 0xdd, 0xdc, +0xcc, 0xcc, 0xc7, 0x98, 0x98, 0x98, 0xa1, 0xa1, +0xa1, 0x8d, 0x8d, 0x8d, 0xcf, 0xcf, 0xce, 0xf5, +0xf5, 0xf4, 0xef, 0xef, 0xee, 0xea, 0xea, 0xea, +0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7, 0xe8, 0xe8, +0xe3, 0xae, 0xae, 0xae, 0xf8, 0xf8, 0xf6, 0xf3, +0xf3, 0xf2, 0xd9, 0xd9, 0xd9, 0xdb, 0xdb, 0xd9, +0xe2, 0xe2, 0xde, 0xba, 0xba, 0xb6, 0xa5, 0xa5, +0xa5, 0xc1, 0xc1, 0xc0, 0xed, 0xed, 0xed, 0xdc, +0xdc, 0xdb, 0xc7, 0xc7, 0xc3, 0x8c, 0x8c, 0x8b, +0xc7, 0xc7, 0xc7, 0x8f, 0x8f, 0x8f, 0xdf, 0xdf, +0xde, 0xec, 0xec, 0xec, 0xde, 0xde, 0xde, 0xe1, +0xe1, 0xdf, 0xd5, 0xd5, 0xd0, 0x9c, 0x9c, 0x9a, +0x9b, 0x9b, 0x9b, 0xbc, 0xbc, 0xbc, 0xb0, 0xb0, +0xb0, 0xa0, 0xa0, 0x9f, 0xe4, 0xe4, 0xe4, 0xe0, +0xe0, 0xe0, 0xe2, 0xe2, 0xe1, 0xe1, 0xe1, 0xdd, +0xad, 0xad, 0xaa, 0xb1, 0xb1, 0xb1, 0xcf, 0xcf, +0xcc, 0xe7, 0xe7, 0xe5, 0xe8, 0xe8, 0xe5, 0xbe, +0xbe, 0xba, 0x83, 0x83, 0x82, 0xd0, 0xd0, 0xcc, +0x91, 0x91, 0x90, 0xc5, 0xc5, 0xc5, 0xb9, 0xb9, +0xb9, 0xcb, 0x09, 0x27, 0x17, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x9c, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0xc0, 0x03, 0x18, 0x51, 0xb9, +0x4c, 0xcc, 0x2c, 0xac, 0x48, 0x5c, 0x36, 0x76, +0x0e, 0x4e, 0x2e, 0x6e, 0x36, 0x38, 0x9f, 0x95, +0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, 0x08, 0xca, +0x15, 0xe6, 0x10, 0x11, 0x15, 0x13, 0x97, 0x90, +0x94, 0x92, 0x66, 0x02, 0x71, 0x65, 0x64, 0xe5, +0xe4, 0xf9, 0x14, 0x14, 0x25, 0x94, 0x94, 0x55, +0x54, 0xd5, 0x80, 0x7c, 0x75, 0x0d, 0x4d, 0x2d, +0x6d, 0x1d, 0x10, 0x5f, 0x57, 0x4f, 0x1f, 0xa8, +0x47, 0xd8, 0xc0, 0xd0, 0x48, 0x0c, 0xcc, 0x37, +0x36, 0x31, 0x35, 0x63, 0x67, 0x60, 0x30, 0xb7, +0xd0, 0xb2, 0x04, 0xf1, 0x55, 0xac, 0x4c, 0xad, +0x6d, 0xd8, 0x6d, 0x19, 0x18, 0x6c, 0xed, 0xec, +0x1d, 0x80, 0x7c, 0x47, 0x27, 0x67, 0x17, 0x57, +0x37, 0xb0, 0x15, 0xee, 0x1e, 0xa2, 0x9e, 0x5e, +0xde, 0x3e, 0xbe, 0x1c, 0x7e, 0x30, 0x37, 0x30, +0xfb, 0x07, 0x04, 0x06, 0x05, 0x23, 0xb9, 0x92, +0x49, 0x3a, 0x24, 0x94, 0x3d, 0x0c, 0xd9, 0x17, +0xe1, 0x6a, 0xe1, 0x78, 0xbc, 0x0c, 0x00, 0x16, +0xd9, 0x13, 0x09, 0xa8, 0x4c, 0x28, 0xd5, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_clear_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_clear_png = new wxImage(); + if (!img_edit_clear_png || !img_edit_clear_png->IsOk()) + { + wxMemoryInputStream img_edit_clear_pngIS(edit_clear_png_data, sizeof(edit_clear_png_data)); + img_edit_clear_png->LoadFile(img_edit_clear_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_clear_png; +} +#define edit_clear_png_img edit_clear_png_img() + +static wxBitmap *edit_clear_png_bmp() +{ + static wxBitmap *bmp_edit_clear_png; + if (!bmp_edit_clear_png || !bmp_edit_clear_png->IsOk()) + bmp_edit_clear_png = new wxBitmap(*edit_clear_png_img); + return bmp_edit_clear_png; +} +#define edit_clear_png_bmp edit_clear_png_bmp() + +static wxIcon *edit_clear_png_ico() +{ + static wxIcon *ico_edit_clear_png; + if (!ico_edit_clear_png || !ico_edit_clear_png->IsOk()) + { + ico_edit_clear_png = new wxIcon(); + ico_edit_clear_png->CopyFromBitmap(*edit_clear_png_bmp); + } + return ico_edit_clear_png; +} +#define edit_clear_png_ico edit_clear_png_ico() + +#endif // EDIT_CLEAR_PNG_H diff --git a/include/images/edit_find.png b/include/images/edit_find.png new file mode 100644 index 0000000..1c3b4fc Binary files /dev/null and b/include/images/edit_find.png differ diff --git a/include/images/edit_find.pngc b/include/images/edit_find.pngc new file mode 100644 index 0000000..e184cd9 --- /dev/null +++ b/include/images/edit_find.pngc @@ -0,0 +1,127 @@ +#ifndef EDIT_FIND_PNG_H +#define EDIT_FIND_PNG_H + +static const unsigned char edit_find_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x1a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0xc1, 0x98, +0x98, 0x98, 0x75, 0x75, 0x75, 0x5e, 0x5e, 0x5e, +0xb4, 0xb4, 0xb4, 0x6e, 0x6f, 0x6f, 0xa5, 0xa8, +0xa9, 0xcc, 0xd3, 0xd7, 0xe3, 0xf1, 0xf6, 0xc9, +0xd3, 0xd7, 0xa3, 0xa7, 0xa9, 0xc2, 0xc7, 0xc9, +0xf0, 0xf8, 0xfc, 0xf9, 0xfc, 0xfe, 0xf8, 0xfc, +0xfe, 0xe8, 0xf6, 0xfb, 0xda, 0xf0, 0xf8, 0xb6, +0xbf, 0xc3, 0x6d, 0x6f, 0x6f, 0xa4, 0xa8, 0xa9, +0xef, 0xf8, 0xfc, 0xfb, 0xfd, 0xfe, 0xe6, 0xf4, +0xfa, 0xd3, 0xed, 0xf7, 0xcf, 0xec, 0xf7, 0xd2, +0xee, 0xf8, 0xcd, 0xec, 0xf7, 0xa0, 0xa6, 0xa9, +0xca, 0xd3, 0xd7, 0xe5, 0xf4, 0xfa, 0xc8, 0xe9, +0xf5, 0xc4, 0xe8, 0xf5, 0xbf, 0xe6, 0xf4, 0xbb, +0xe5, 0xf4, 0xbc, 0xe6, 0xf5, 0xbe, 0xcf, 0xd6, +0xe0, 0xef, 0xf6, 0xf7, 0xfc, 0xfd, 0xc1, 0xe7, +0xf5, 0xbd, 0xe6, 0xf4, 0xb8, 0xe4, 0xf4, 0xb4, +0xe3, 0xf4, 0xb2, 0xe3, 0xf4, 0xcd, 0xea, 0xf4, +0xc6, 0xd2, 0xd6, 0xe4, 0xf5, 0xfb, 0xca, 0xea, +0xf6, 0xb6, 0xe4, 0xf4, 0xb2, 0xe2, 0xf3, 0xad, +0xe1, 0xf3, 0xb0, 0xe3, 0xf4, 0xb9, 0xcf, 0xd6, +0x6c, 0x6b, 0x5f, 0xa1, 0xa7, 0xa9, 0xcb, 0xec, +0xf7, 0xaf, 0xe2, 0xf3, 0xab, 0xe1, 0xf3, 0xaa, +0xe0, 0xf2, 0xba, 0xe6, 0xf5, 0x9d, 0xa5, 0xa8, +0x90, 0x90, 0x90, 0x63, 0x63, 0x63, 0xb2, 0xbe, +0xc3, 0xc5, 0xe9, 0xf6, 0xb4, 0xe4, 0xf4, 0xad, +0xe1, 0xf4, 0xad, 0xe2, 0xf3, 0xb8, 0xe6, 0xf5, +0xad, 0xbd, 0xc2, 0x6c, 0x6e, 0x6f, 0xa3, 0x98, +0x62, 0x64, 0x64, 0x64, 0xa1, 0xa5, 0x94, 0x76, +0x7a, 0x77, 0x6d, 0x6e, 0x6f, 0x9e, 0xa6, 0xa8, +0xba, 0xcf, 0xd6, 0xc8, 0xe8, 0xf4, 0xb7, 0xce, +0xd6, 0x9c, 0xa5, 0xa8, 0x83, 0x70, 0x15, 0x8c, +0x80, 0x53, 0xce, 0xd0, 0xc6, 0xc5, 0xa8, 0x3b, +0xc2, 0xa3, 0x3d, 0x89, 0x7c, 0x54, 0xc4, 0xa7, +0x3b, 0xc1, 0xa3, 0x3d, 0xbe, 0x9f, 0x3f, 0xc4, +0xa6, 0x3c, 0xc1, 0xa2, 0x3d, 0xbe, 0x9e, 0x3f, +0xbd, 0x9d, 0x3f, 0x9c, 0x21, 0x19, 0xb7, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xae, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x80, 0x00, 0x46, +0x26, 0x66, 0x16, 0x66, 0x26, 0x46, 0x06, 0x18, +0x60, 0x65, 0x63, 0xe7, 0xe0, 0xe4, 0xe2, 0x66, +0x63, 0x85, 0xc9, 0xb3, 0xf1, 0xf0, 0xf2, 0xf1, +0x0b, 0x08, 0x0a, 0x09, 0x43, 0xd5, 0x30, 0x89, +0x88, 0x8a, 0x89, 0x4b, 0x48, 0x4a, 0x49, 0xcb, +0x30, 0x41, 0x04, 0x98, 0x65, 0xf9, 0xe5, 0xe4, +0x15, 0x14, 0x95, 0x94, 0x55, 0x98, 0x21, 0x02, +0x2c, 0xaa, 0x6a, 0x92, 0xea, 0x1a, 0x9a, 0x5a, +0xda, 0x3a, 0x2c, 0x50, 0x15, 0xba, 0x7a, 0xfa, +0x4a, 0x06, 0x86, 0x46, 0xc6, 0x26, 0x50, 0x15, +0xa6, 0x66, 0x52, 0xe6, 0x5a, 0x16, 0x96, 0x56, +0xd6, 0x36, 0x10, 0x33, 0x6c, 0xed, 0x84, 0xed, +0x1d, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, 0xc0, +0xb6, 0xb8, 0x7b, 0x78, 0x7a, 0x79, 0xfb, 0xf8, +0xfa, 0xf9, 0x07, 0xb8, 0x81, 0xdd, 0xe1, 0x1e, +0x18, 0xe4, 0x11, 0x6c, 0x67, 0x0a, 0x77, 0xa9, +0x7b, 0x60, 0x48, 0x68, 0x98, 0x87, 0x2d, 0xdc, +0xd1, 0xee, 0x81, 0xe1, 0x11, 0x91, 0x81, 0xee, +0x70, 0x3e, 0x43, 0x60, 0x54, 0x74, 0x0c, 0x32, +0x1f, 0xa8, 0x22, 0x16, 0x85, 0x0f, 0x12, 0x41, +0xe1, 0x03, 0x00, 0xb1, 0xb1, 0x18, 0x88, 0x2d, +0x5a, 0xd2, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_find_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_find_png = new wxImage(); + if (!img_edit_find_png || !img_edit_find_png->IsOk()) + { + wxMemoryInputStream img_edit_find_pngIS(edit_find_png_data, sizeof(edit_find_png_data)); + img_edit_find_png->LoadFile(img_edit_find_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_find_png; +} +#define edit_find_png_img edit_find_png_img() + +static wxBitmap *edit_find_png_bmp() +{ + static wxBitmap *bmp_edit_find_png; + if (!bmp_edit_find_png || !bmp_edit_find_png->IsOk()) + bmp_edit_find_png = new wxBitmap(*edit_find_png_img); + return bmp_edit_find_png; +} +#define edit_find_png_bmp edit_find_png_bmp() + +static wxIcon *edit_find_png_ico() +{ + static wxIcon *ico_edit_find_png; + if (!ico_edit_find_png || !ico_edit_find_png->IsOk()) + { + ico_edit_find_png = new wxIcon(); + ico_edit_find_png->CopyFromBitmap(*edit_find_png_bmp); + } + return ico_edit_find_png; +} +#define edit_find_png_ico edit_find_png_ico() + +#endif // EDIT_FIND_PNG_H diff --git a/include/images/edit_redo.png b/include/images/edit_redo.png new file mode 100644 index 0000000..f45c6d2 Binary files /dev/null and b/include/images/edit_redo.png differ diff --git a/include/images/edit_redo.pngc b/include/images/edit_redo.pngc new file mode 100644 index 0000000..ec2bf1e --- /dev/null +++ b/include/images/edit_redo.pngc @@ -0,0 +1,126 @@ +#ifndef EDIT_REDO_PNG_H +#define EDIT_REDO_PNG_H + +static const unsigned char edit_redo_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x26, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xb8, 0xc8, 0x6f, +0x94, 0xbd, 0x4b, 0x7d, 0xb6, 0x43, 0x78, 0xb4, +0x9a, 0xae, 0xc5, 0x4c, 0x83, 0xbe, 0x6d, 0xb1, +0xe5, 0x76, 0xc4, 0xf6, 0x72, 0xc6, 0xf8, 0x68, +0xbf, 0xf1, 0x58, 0xa9, 0xdf, 0x46, 0x81, 0xbc, +0xa3, 0xb4, 0xc7, 0x4c, 0x84, 0xbe, 0x74, 0xbb, +0xed, 0x74, 0xc0, 0xf2, 0x6c, 0xbb, 0xee, 0x6a, +0xc0, 0xf3, 0x5e, 0xb6, 0xea, 0x57, 0xb5, 0xe9, +0x4d, 0xac, 0xe1, 0x43, 0x81, 0xbc, 0x69, 0x90, +0xbc, 0x70, 0xb5, 0xe9, 0x73, 0xbf, 0xf0, 0x5f, +0xa6, 0xdb, 0x4d, 0x8b, 0xc5, 0x44, 0x7b, 0xb6, +0x49, 0x8a, 0xc3, 0x4b, 0x9e, 0xd5, 0x46, 0xad, +0xe3, 0x3f, 0xa2, 0xd9, 0x57, 0x93, 0xcb, 0x77, +0xc2, 0xf3, 0x5c, 0xa0, 0xd6, 0x7e, 0x9d, 0xc0, +0xac, 0xba, 0xc9, 0xcb, 0xcd, 0xcf, 0x41, 0x96, +0xce, 0x36, 0xaa, 0xe0, 0x3c, 0x88, 0xc3, 0x99, +0xae, 0xc5, 0x6a, 0x90, 0xbc, 0x98, 0xad, 0xc5, +0x6c, 0x92, 0xbc, 0x6b, 0xb2, 0xe6, 0x6a, 0xb6, +0xea, 0x61, 0x8b, 0xba, 0xc3, 0xc8, 0xcd, 0xae, +0xbb, 0xc9, 0x32, 0xa1, 0xd8, 0x2c, 0x9b, 0xd4, +0x34, 0x89, 0xc4, 0x21, 0x96, 0xd0, 0x2e, 0x88, +0xc2, 0x53, 0x82, 0xb7, 0x70, 0xbf, 0xf1, 0x56, +0x99, 0xd0, 0x93, 0xaa, 0xc4, 0x87, 0xa2, 0xc2, +0x40, 0x85, 0xc0, 0x38, 0x93, 0xcc, 0x28, 0xa4, +0xdc, 0x1d, 0xa6, 0xdd, 0x15, 0xa3, 0xda, 0x0f, +0xa0, 0xd8, 0x41, 0x79, 0xb5, 0x4a, 0x7c, 0xb5, +0x6d, 0xc1, 0xf4, 0x47, 0x80, 0xbb, 0xc1, 0xc7, +0xcd, 0x4d, 0x7e, 0xb6, 0x30, 0xa9, 0xe0, 0x26, +0xa9, 0xe0, 0x16, 0xa3, 0xdb, 0x0e, 0xa0, 0xd8, +0x31, 0x84, 0xbf, 0x7f, 0x9d, 0xc0, 0x44, 0x79, +0xb4, 0x68, 0xc1, 0xf3, 0x43, 0x79, 0xb5, 0xce, +0xcf, 0xd0, 0x2e, 0x92, 0xcb, 0x17, 0xa2, 0xdb, +0x0f, 0xa0, 0xd9, 0x10, 0x99, 0xd3, 0x55, 0x83, +0xb8, 0x49, 0x86, 0xc1, 0xba, 0xc2, 0xcc, 0x36, +0x82, 0xbd, 0x09, 0x9e, 0xd7, 0x31, 0x82, 0xbd, +0x8f, 0xa7, 0xc3, 0xb3, 0xbe, 0xca, 0x7d, 0x9c, +0xc0, 0x40, 0x7a, 0xb6, 0xc9, 0xcc, 0xcf, 0xec, +0x73, 0x71, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x9f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x20, 0x0a, 0x30, 0x32, 0x31, 0xb3, 0x30, +0x33, 0x31, 0xc2, 0xf9, 0xac, 0x6c, 0xec, 0x1c, +0x9c, 0x5c, 0xdc, 0x3c, 0xac, 0x50, 0x3e, 0x2f, +0x1f, 0xbf, 0x80, 0xa0, 0x90, 0xb0, 0x88, 0xa8, +0x18, 0x2f, 0x44, 0x40, 0x5c, 0x42, 0x52, 0x4a, +0x5a, 0x46, 0x56, 0x4e, 0x5e, 0x41, 0x1c, 0xa2, +0x40, 0x51, 0x49, 0x59, 0x45, 0x55, 0x4d, 0x55, +0x45, 0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x87, 0x81, +0x41, 0x57, 0x4f, 0xdf, 0xc0, 0x10, 0x28, 0x61, +0x64, 0x60, 0x6c, 0x62, 0x6a, 0x66, 0xce, 0xc0, +0x60, 0x61, 0x69, 0x65, 0x0d, 0xe4, 0xdb, 0xd8, +0xda, 0xd9, 0x3b, 0x38, 0x3a, 0x39, 0x33, 0x30, +0xb8, 0xb8, 0xba, 0xb9, 0x03, 0x05, 0x3c, 0x3c, +0xbd, 0x1c, 0xbc, 0x7d, 0x7c, 0xfd, 0x18, 0x18, +0xfc, 0x03, 0x02, 0x83, 0x40, 0x2a, 0x3c, 0x82, +0x43, 0x42, 0xc3, 0xc2, 0x81, 0x2c, 0x95, 0x08, +0x15, 0xb0, 0xe1, 0x91, 0x7e, 0x51, 0xd1, 0x31, +0xb1, 0x20, 0x56, 0x1c, 0xcc, 0x81, 0xf1, 0x09, +0xf1, 0x68, 0x5e, 0x48, 0x24, 0xca, 0xa3, 0x00, +0x9e, 0x16, 0x15, 0x00, 0x07, 0x64, 0xb5, 0xa2, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_redo_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_redo_png = new wxImage(); + if (!img_edit_redo_png || !img_edit_redo_png->IsOk()) + { + wxMemoryInputStream img_edit_redo_pngIS(edit_redo_png_data, sizeof(edit_redo_png_data)); + img_edit_redo_png->LoadFile(img_edit_redo_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_redo_png; +} +#define edit_redo_png_img edit_redo_png_img() + +static wxBitmap *edit_redo_png_bmp() +{ + static wxBitmap *bmp_edit_redo_png; + if (!bmp_edit_redo_png || !bmp_edit_redo_png->IsOk()) + bmp_edit_redo_png = new wxBitmap(*edit_redo_png_img); + return bmp_edit_redo_png; +} +#define edit_redo_png_bmp edit_redo_png_bmp() + +static wxIcon *edit_redo_png_ico() +{ + static wxIcon *ico_edit_redo_png; + if (!ico_edit_redo_png || !ico_edit_redo_png->IsOk()) + { + ico_edit_redo_png = new wxIcon(); + ico_edit_redo_png->CopyFromBitmap(*edit_redo_png_bmp); + } + return ico_edit_redo_png; +} +#define edit_redo_png_ico edit_redo_png_ico() + +#endif // EDIT_REDO_PNG_H diff --git a/include/images/edit_undo.png b/include/images/edit_undo.png new file mode 100644 index 0000000..23ff22d Binary files /dev/null and b/include/images/edit_undo.png differ diff --git a/include/images/edit_undo.pngc b/include/images/edit_undo.pngc new file mode 100644 index 0000000..02277af --- /dev/null +++ b/include/images/edit_undo.pngc @@ -0,0 +1,127 @@ +#ifndef EDIT_UNDO_PNG_H +#define EDIT_UNDO_PNG_H + +static const unsigned char edit_undo_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x29, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xb8, 0xc8, 0x6f, +0x94, 0xbd, 0x4b, 0x7d, 0xb6, 0x43, 0x78, 0xb4, +0x9a, 0xae, 0xc5, 0x4a, 0x83, 0xbd, 0x63, 0xae, +0xe3, 0x68, 0xbf, 0xf1, 0x61, 0xc0, 0xf2, 0x57, +0xb8, 0xec, 0x4b, 0xa5, 0xdb, 0x43, 0x80, 0xbb, +0xa3, 0xb4, 0xc7, 0x4b, 0x83, 0xbe, 0x69, 0xb6, +0xea, 0x67, 0xbb, 0xee, 0x5e, 0xb6, 0xea, 0x58, +0xbb, 0xee, 0x4e, 0xb0, 0xe5, 0x46, 0xaf, 0xe4, +0x3e, 0xa6, 0xdd, 0x41, 0x80, 0xbb, 0x69, 0x90, +0xbc, 0x67, 0xb2, 0xe6, 0x66, 0xba, 0xed, 0x56, +0xa2, 0xd9, 0x49, 0x8a, 0xc3, 0x43, 0x7a, 0xb6, +0x44, 0x88, 0xc2, 0x40, 0x9a, 0xd2, 0x36, 0xa7, +0xdd, 0x31, 0x9d, 0xd5, 0x98, 0xad, 0xc5, 0x6a, +0x90, 0xbc, 0x99, 0xae, 0xc5, 0x53, 0x91, 0xca, +0x69, 0xbd, 0xf0, 0x54, 0x9d, 0xd4, 0x7e, 0x9d, +0xc0, 0xac, 0xba, 0xc9, 0xcb, 0xcd, 0xcf, 0x37, +0x92, 0xcb, 0x26, 0xa3, 0xdb, 0x36, 0x86, 0xc1, +0x5c, 0x99, 0xd1, 0x6c, 0xb3, 0xe8, 0x56, 0x97, +0xcf, 0x62, 0xb0, 0xe4, 0x5e, 0xb2, 0xe6, 0x61, +0x8b, 0xba, 0xae, 0xbb, 0xc9, 0xc3, 0xc8, 0xcd, +0x24, 0x9b, 0xd4, 0x22, 0x96, 0xcf, 0x6c, 0x92, +0xbc, 0x45, 0x7a, 0xb6, 0x75, 0xc7, 0xf8, 0x6e, +0xc5, 0xf6, 0x66, 0xc1, 0xf4, 0x5a, 0xb7, 0xeb, +0x4c, 0x9b, 0xd2, 0x45, 0x87, 0xc1, 0x87, 0xa2, +0xc2, 0x93, 0xaa, 0xc4, 0x2f, 0x8b, 0xc4, 0x14, +0x9b, 0xd4, 0x53, 0x82, 0xb7, 0x7f, 0x9d, 0xc0, +0x50, 0x90, 0xc8, 0x67, 0xc2, 0xf4, 0x5e, 0xbe, +0xf1, 0x55, 0xbb, 0xee, 0x4b, 0xb7, 0xeb, 0x42, +0xb0, 0xe4, 0x4d, 0x7e, 0xb6, 0xc1, 0xc7, 0xcd, +0x3d, 0x7c, 0xb8, 0x0b, 0x9c, 0xd5, 0x4a, 0x7c, +0xb5, 0x55, 0x83, 0xb8, 0x5b, 0xb6, 0xea, 0x56, +0xbb, 0xef, 0x4c, 0xb7, 0xeb, 0x43, 0x9a, 0xd2, +0xce, 0xcf, 0xd0, 0x42, 0x78, 0xb4, 0x04, 0x9c, +0xd5, 0x44, 0x79, 0xb4, 0x8f, 0xa7, 0xc3, 0x48, +0x8b, 0xc4, 0x4d, 0xb8, 0xec, 0x43, 0x87, 0xc1, +0xba, 0xc2, 0xcc, 0x35, 0x7f, 0xbb, 0x7d, 0x9c, +0xc0, 0x43, 0x7b, 0xb6, 0xb3, 0xbe, 0xca, 0xc9, +0xcc, 0xcf, 0x0e, 0x00, 0x96, 0xd5, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x20, 0x0e, 0x30, 0x32, +0x31, 0xb3, 0x30, 0x33, 0x31, 0xc2, 0xf9, 0xac, +0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xac, +0x50, 0x3e, 0x2f, 0x1f, 0xbf, 0x80, 0xa0, 0x90, +0xb0, 0x88, 0xa8, 0x18, 0x2f, 0x44, 0x40, 0x5c, +0x42, 0x52, 0x4a, 0x5a, 0x46, 0x56, 0x4e, 0x5e, +0x41, 0x1c, 0xc8, 0x53, 0x54, 0x52, 0x56, 0x51, +0x55, 0x53, 0xd7, 0xd0, 0xd4, 0x50, 0xd7, 0xd2, +0xd6, 0x01, 0x2a, 0xd1, 0xd5, 0xd3, 0x37, 0x30, +0x34, 0x32, 0x06, 0x4a, 0x99, 0x18, 0x99, 0x9a, +0x99, 0x33, 0x30, 0x58, 0x58, 0x5a, 0x59, 0xdb, +0xd8, 0xda, 0xd9, 0x03, 0x45, 0x1c, 0x1c, 0x9d, +0x9c, 0x19, 0x18, 0x5c, 0x5c, 0xdd, 0xdc, 0x3d, +0x3c, 0xbd, 0xbc, 0x81, 0x02, 0x3e, 0xbe, 0x7e, +0xfe, 0x40, 0x2a, 0x20, 0x30, 0x28, 0x38, 0xc4, +0x1b, 0xa4, 0x22, 0x34, 0x2c, 0x3c, 0x02, 0x48, +0x45, 0x46, 0x45, 0xc7, 0xb8, 0xc4, 0x82, 0xad, +0x53, 0x8f, 0x53, 0x07, 0x51, 0xf1, 0x09, 0xf1, +0x30, 0x17, 0x26, 0x42, 0xa8, 0x24, 0x22, 0x3d, +0x08, 0x05, 0x00, 0xd7, 0x58, 0x15, 0x2c, 0x65, +0x45, 0x1e, 0x71, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x32, +0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x38, 0x3a, +0x33, 0x38, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, +0x1f, 0x2a, 0xf2, 0x4f, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *edit_undo_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_edit_undo_png = new wxImage(); + if (!img_edit_undo_png || !img_edit_undo_png->IsOk()) + { + wxMemoryInputStream img_edit_undo_pngIS(edit_undo_png_data, sizeof(edit_undo_png_data)); + img_edit_undo_png->LoadFile(img_edit_undo_pngIS, wxBITMAP_TYPE_PNG); + } + return img_edit_undo_png; +} +#define edit_undo_png_img edit_undo_png_img() + +static wxBitmap *edit_undo_png_bmp() +{ + static wxBitmap *bmp_edit_undo_png; + if (!bmp_edit_undo_png || !bmp_edit_undo_png->IsOk()) + bmp_edit_undo_png = new wxBitmap(*edit_undo_png_img); + return bmp_edit_undo_png; +} +#define edit_undo_png_bmp edit_undo_png_bmp() + +static wxIcon *edit_undo_png_ico() +{ + static wxIcon *ico_edit_undo_png; + if (!ico_edit_undo_png || !ico_edit_undo_png->IsOk()) + { + ico_edit_undo_png = new wxIcon(); + ico_edit_undo_png->CopyFromBitmap(*edit_undo_png_bmp); + } + return ico_edit_undo_png; +} +#define edit_undo_png_ico edit_undo_png_ico() + +#endif // EDIT_UNDO_PNG_H diff --git a/include/images/enumeration.png b/include/images/enumeration.png new file mode 100644 index 0000000..0b5ff02 Binary files /dev/null and b/include/images/enumeration.png differ diff --git a/include/images/enumeration.pngc b/include/images/enumeration.pngc new file mode 100644 index 0000000..f2167f5 --- /dev/null +++ b/include/images/enumeration.pngc @@ -0,0 +1,122 @@ +#ifndef ENUMERATION_PNG_H +#define ENUMERATION_PNG_H + +static const unsigned char enumeration_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x1d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8f, 0xc2, 0xd6, 0x35, +0x92, 0xb5, 0x26, 0x8a, 0xaf, 0xc7, 0xe1, 0xea, +0x3e, 0x9a, 0xba, 0xb9, 0xed, 0xf2, 0xbc, 0xf5, +0xf7, 0xba, 0xf5, 0xf6, 0xbc, 0xf6, 0xf7, 0xbc, +0xf7, 0xf7, 0xbe, 0xf8, 0xf8, 0xc2, 0xf9, 0xf8, +0xbe, 0xf2, 0xf4, 0x41, 0x9c, 0xbb, 0xc4, 0xdf, +0xe9, 0x6d, 0xb1, 0xc9, 0x8c, 0xce, 0xde, 0xac, +0xed, 0xf3, 0x50, 0x74, 0x77, 0x4f, 0x75, 0x77, +0xa5, 0xef, 0xf2, 0x51, 0x76, 0x77, 0x52, 0x77, +0x78, 0x53, 0x77, 0x78, 0x54, 0x78, 0x78, 0x55, +0x79, 0x78, 0x56, 0x79, 0x79, 0xbb, 0xf8, 0xf7, +0x96, 0xd6, 0xe1, 0x6b, 0xaf, 0xc8, 0x33, 0x91, +0xb4, 0xa6, 0xe3, 0xed, 0x9a, 0xe5, 0xee, 0x90, +0xe4, 0xed, 0x91, 0xe5, 0xee, 0x93, 0xe7, 0xef, +0x96, 0xe9, 0xf0, 0x98, 0xeb, 0xf0, 0x9b, 0xed, +0xf1, 0x9d, 0xee, 0xf2, 0x9f, 0xf0, 0xf3, 0xa2, +0xf2, 0xf3, 0xaf, 0xf5, 0xf5, 0xba, 0xf2, 0xf4, +0x30, 0x90, 0xb3, 0xa5, 0xe4, 0xef, 0x8f, 0xde, +0xeb, 0x42, 0x6c, 0x73, 0x42, 0x6d, 0x73, 0x8a, +0xe0, 0xec, 0x45, 0x6f, 0x74, 0x46, 0x70, 0x75, +0x48, 0x71, 0x75, 0x49, 0x72, 0x75, 0x4a, 0x73, +0x76, 0x4b, 0x74, 0x76, 0xa6, 0xf0, 0xf2, 0xba, +0xf4, 0xf6, 0x9b, 0xdb, 0xea, 0x8b, 0xd9, 0xea, +0x7f, 0xd7, 0xe7, 0x7e, 0xd8, 0xe8, 0x81, 0xd9, +0xe9, 0x83, 0xdb, 0xea, 0x86, 0xdd, 0xeb, 0x89, +0xdf, 0xeb, 0x8b, 0xe1, 0xec, 0x8e, 0xe3, 0xed, +0x93, 0xe5, 0xee, 0xa1, 0xea, 0xf1, 0xb0, 0xeb, +0xf2, 0x80, 0xc6, 0xdb, 0x93, 0xda, 0xea, 0x41, +0x69, 0x72, 0x40, 0x69, 0x72, 0x84, 0xd7, 0xe8, +0x42, 0x6a, 0x72, 0x43, 0x6b, 0x73, 0x44, 0x6c, +0x73, 0x45, 0x6c, 0x73, 0x47, 0x6d, 0x74, 0x49, +0x6f, 0x74, 0xa4, 0xe7, 0xf0, 0x3b, 0x98, 0xb9, +0x9e, 0xda, 0xea, 0x9a, 0xdb, 0xeb, 0x96, 0xda, +0xeb, 0x98, 0xdb, 0xeb, 0x98, 0xdc, 0xec, 0x9a, +0xdd, 0xec, 0x9b, 0xde, 0xed, 0x9d, 0xdf, 0xed, +0x9f, 0xe1, 0xed, 0xa8, 0xe1, 0xed, 0x5b, 0xac, +0x75, 0xeb, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x89, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x20, 0x03, 0x30, 0x32, 0x31, 0xc3, 0x00, 0x13, +0x23, 0x90, 0xcf, 0xc2, 0xca, 0xc6, 0xce, 0xc1, +0xc9, 0xc5, 0x0d, 0x04, 0x3c, 0xbc, 0x7c, 0xfc, +0x0c, 0x0c, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, +0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, +0x72, 0x0c, 0x0c, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, +0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, +0x3a, 0xba, 0x0c, 0x0c, 0xcc, 0x7a, 0xfa, 0x06, +0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, +0x96, 0x56, 0xcc, 0x40, 0x15, 0xd6, 0x36, 0xb6, +0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, +0x6e, 0xee, 0x40, 0x15, 0x72, 0x1e, 0x9e, 0x5e, +0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, +0xc1, 0x82, 0x40, 0x33, 0xf8, 0x43, 0x42, 0xc3, +0xc2, 0x23, 0x22, 0xa3, 0xa2, 0x63, 0x62, 0xf5, +0xe2, 0x58, 0xf9, 0xb1, 0xb8, 0x83, 0x0a, 0x00, +0x00, 0x78, 0x5e, 0x12, 0xbf, 0xe5, 0x04, 0x93, +0x6e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *enumeration_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_enumeration_png = new wxImage(); + if (!img_enumeration_png || !img_enumeration_png->IsOk()) + { + wxMemoryInputStream img_enumeration_pngIS(enumeration_png_data, sizeof(enumeration_png_data)); + img_enumeration_png->LoadFile(img_enumeration_pngIS, wxBITMAP_TYPE_PNG); + } + return img_enumeration_png; +} +#define enumeration_png_img enumeration_png_img() + +static wxBitmap *enumeration_png_bmp() +{ + static wxBitmap *bmp_enumeration_png; + if (!bmp_enumeration_png || !bmp_enumeration_png->IsOk()) + bmp_enumeration_png = new wxBitmap(*enumeration_png_img); + return bmp_enumeration_png; +} +#define enumeration_png_bmp enumeration_png_bmp() + +static wxIcon *enumeration_png_ico() +{ + static wxIcon *ico_enumeration_png; + if (!ico_enumeration_png || !ico_enumeration_png->IsOk()) + { + ico_enumeration_png = new wxIcon(); + ico_enumeration_png->CopyFromBitmap(*enumeration_png_bmp); + } + return ico_enumeration_png; +} +#define enumeration_png_ico enumeration_png_ico() + +#endif // ENUMERATION_PNG_H diff --git a/include/images/enumerations.png b/include/images/enumerations.png new file mode 100644 index 0000000..6acde4c Binary files /dev/null and b/include/images/enumerations.png differ diff --git a/include/images/enumerations.pngc b/include/images/enumerations.pngc new file mode 100644 index 0000000..5f98662 --- /dev/null +++ b/include/images/enumerations.pngc @@ -0,0 +1,107 @@ +#ifndef ENUMERATIONS_PNG_H +#define ENUMERATIONS_PNG_H + +static const unsigned char enumerations_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8f, 0xc2, 0xd6, 0x35, +0x92, 0xb5, 0x26, 0x8a, 0xaf, 0xde, 0xed, 0xf3, +0x3e, 0x9b, 0xba, 0xbc, 0xef, 0xf3, 0xbf, 0xf7, +0xf7, 0xbc, 0xf7, 0xf7, 0xbe, 0xf8, 0xf8, 0xc2, +0xf9, 0xf8, 0xbe, 0xf2, 0xf4, 0x41, 0x9c, 0xbb, +0xdb, 0xec, 0xf2, 0x8a, 0xc0, 0xd4, 0x78, 0xc1, +0xd5, 0xb0, 0xef, 0xf3, 0x3b, 0x80, 0x94, 0x2f, +0x91, 0xb4, 0x2d, 0x8e, 0xb2, 0x74, 0xb4, 0xcc, +0x82, 0xc8, 0xda, 0x8c, 0xd7, 0xe5, 0x89, 0xbf, +0xd3, 0x71, 0xbc, 0xd2, 0x5d, 0xb2, 0xcc, 0x3c, +0x98, 0xb9, 0x52, 0xa8, 0xc4, 0x51, 0x75, 0x77, +0xa3, 0xef, 0xf2, 0x52, 0x76, 0x77, 0x53, 0x77, +0x78, 0x56, 0x78, 0x78, 0xbb, 0xf7, 0xf7, 0x7f, +0xc7, 0xd7, 0x9e, 0xe5, 0xef, 0x90, 0xe2, 0xed, +0x8d, 0xe3, 0xed, 0x90, 0xe5, 0xee, 0x93, 0xe7, +0xef, 0x95, 0xe9, 0xef, 0x9d, 0xec, 0xf1, 0xac, +0xf0, 0xf4, 0x8b, 0xce, 0xdd, 0x9d, 0xe0, 0xed, +0x46, 0x6c, 0x73, 0x8b, 0xdc, 0xeb, 0x46, 0x6d, +0x73, 0x47, 0x6e, 0x74, 0x48, 0x6f, 0x74, 0x4b, +0x70, 0x75, 0xaa, 0xea, 0xf2, 0xa1, 0xdc, 0xea, +0x9e, 0xde, 0xec, 0x9a, 0xdd, 0xec, 0x9b, 0xde, +0xed, 0x9d, 0xdf, 0xed, 0x9e, 0xe0, 0xed, 0xa5, +0xe3, 0xef, 0xa9, 0xe1, 0xed, 0x3e, 0x9a, 0xba, +0x72, 0xdc, 0x21, 0x53, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x76, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x20, 0x0c, 0x18, 0x99, 0x98, 0xc1, +0x80, 0x89, 0x11, 0xc2, 0x67, 0x61, 0x65, 0x63, +0xe7, 0xe0, 0xe4, 0xe4, 0xe4, 0xe2, 0xe6, 0xe1, +0x05, 0x0b, 0xf0, 0xf1, 0x0b, 0x08, 0x0a, 0x41, +0xd4, 0x08, 0x83, 0xd5, 0x88, 0x88, 0x8a, 0xa1, +0xaa, 0x11, 0x97, 0x90, 0x44, 0x55, 0xc3, 0x2b, +0x25, 0x8d, 0xa6, 0x86, 0x51, 0x18, 0xa4, 0x46, +0x46, 0x56, 0x46, 0x4e, 0x5e, 0x41, 0x51, 0x49, +0x9c, 0x01, 0xa2, 0x46, 0x59, 0x45, 0x55, 0x4d, +0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x04, 0xec, 0x12, +0x61, 0x09, 0x1d, 0x5d, 0x3d, 0x7d, 0x03, 0x43, +0x23, 0x63, 0x7e, 0x71, 0xb0, 0xd5, 0xbc, 0x52, +0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, +0x36, 0xbc, 0xd8, 0x5d, 0x4b, 0x1a, 0x00, 0x00, +0xe5, 0x2b, 0x0a, 0x64, 0x9d, 0xc9, 0x5c, 0x81, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *enumerations_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_enumerations_png = new wxImage(); + if (!img_enumerations_png || !img_enumerations_png->IsOk()) + { + wxMemoryInputStream img_enumerations_pngIS(enumerations_png_data, sizeof(enumerations_png_data)); + img_enumerations_png->LoadFile(img_enumerations_pngIS, wxBITMAP_TYPE_PNG); + } + return img_enumerations_png; +} +#define enumerations_png_img enumerations_png_img() + +static wxBitmap *enumerations_png_bmp() +{ + static wxBitmap *bmp_enumerations_png; + if (!bmp_enumerations_png || !bmp_enumerations_png->IsOk()) + bmp_enumerations_png = new wxBitmap(*enumerations_png_img); + return bmp_enumerations_png; +} +#define enumerations_png_bmp enumerations_png_bmp() + +static wxIcon *enumerations_png_ico() +{ + static wxIcon *ico_enumerations_png; + if (!ico_enumerations_png || !ico_enumerations_png->IsOk()) + { + ico_enumerations_png = new wxIcon(); + ico_enumerations_png->CopyFromBitmap(*enumerations_png_bmp); + } + return ico_enumerations_png; +} +#define enumerations_png_ico enumerations_png_ico() + +#endif // ENUMERATIONS_PNG_H diff --git a/include/images/ex_aggregate.png b/include/images/ex_aggregate.png new file mode 100644 index 0000000..fac0c02 Binary files /dev/null and b/include/images/ex_aggregate.png differ diff --git a/include/images/ex_aggregate.pngc b/include/images/ex_aggregate.pngc new file mode 100644 index 0000000..419e923 --- /dev/null +++ b/include/images/ex_aggregate.pngc @@ -0,0 +1,178 @@ +#ifndef EX_AGGREGATE_PNG_H +#define EX_AGGREGATE_PNG_H + +static const unsigned char ex_aggregate_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x86, 0xb2, 0xd1, 0x53, +0x9d, 0xd1, 0xb7, 0xc6, 0xd0, 0x5c, 0xa8, 0xd7, +0x6c, 0xcc, 0xed, 0x47, 0xbf, 0xe9, 0x4a, 0xbf, +0xe9, 0x4d, 0xc0, 0xe9, 0x50, 0xc1, 0xe9, 0x54, +0xc1, 0xe9, 0x56, 0xc3, 0xea, 0x59, 0xc4, 0xea, +0x5c, 0xc5, 0xeb, 0x5f, 0xc6, 0xeb, 0x62, 0xc7, +0xeb, 0x67, 0xc9, 0xec, 0x6a, 0xc9, 0xec, 0x6d, +0xca, 0xec, 0x71, 0xcb, 0xec, 0x74, 0xcc, 0xec, +0x77, 0xce, 0xed, 0x7b, 0xce, 0xec, 0x7e, 0xcf, +0xed, 0x80, 0xd1, 0xed, 0x84, 0xd1, 0xed, 0x87, +0xd2, 0xee, 0x8a, 0xd3, 0xee, 0x8e, 0xd4, 0xee, +0x9e, 0xd9, 0xf0, 0x7c, 0xb9, 0xdf, 0x9e, 0xbc, +0xd0, 0xc9, 0xcd, 0xd0, 0x56, 0xa1, 0xd3, 0x38, +0xb9, 0xe8, 0x19, 0xae, 0xe4, 0x0d, 0xaa, 0xe2, +0x11, 0xab, 0xe2, 0x15, 0xac, 0xe2, 0x19, 0xad, +0xe3, 0x2b, 0xb4, 0xe5, 0x80, 0xd0, 0xee, 0x7a, +0xcd, 0xec, 0x72, 0xca, 0xeb, 0x6a, 0xc6, 0xe8, +0x67, 0xc5, 0xe8, 0x79, 0xcc, 0xeb, 0x8e, 0xca, +0xe8, 0x7d, 0xae, 0xd1, 0x8e, 0xb5, 0xd1, 0x5a, +0xa2, 0xd3, 0x56, 0xc4, 0xeb, 0x1c, 0xaf, 0xe4, +0x3a, 0xb9, 0xe7, 0x69, 0xad, 0xd9, 0x82, 0xc1, +0xe3, 0x89, 0xd0, 0xec, 0x75, 0xcb, 0xea, 0x93, +0xcc, 0xe9, 0x74, 0xab, 0xd1, 0x20, 0xb0, 0xe4, +0xb2, 0xc4, 0xd0, 0x8e, 0xce, 0xeb, 0x80, 0xce, +0xeb, 0x25, 0xb1, 0xe4, 0x1d, 0xaf, 0xe3, 0x2e, +0xb4, 0xe4, 0x92, 0xd4, 0xee, 0x97, 0xd3, 0xed, +0x64, 0xa4, 0xd1, 0x21, 0xb0, 0xe3, 0x33, 0xb5, +0xe5, 0x81, 0xbe, 0xe1, 0xa6, 0xdd, 0xf2, 0x61, +0xc7, 0xec, 0x37, 0xb8, 0xe6, 0x70, 0xcc, 0xec, +0xbf, 0xc9, 0xd0, 0x61, 0xa6, 0xd6, 0xad, 0xe0, +0xf3, 0x64, 0xc8, 0xec, 0x2a, 0xb3, 0xe4, 0x73, +0xcc, 0xed, 0xb8, 0xe4, 0xf4, 0x40, 0xba, 0xe6, +0x9c, 0xd0, 0xeb, 0x44, 0xbc, 0xe7, 0x79, 0xce, +0xed, 0xa8, 0xc0, 0xd0, 0x67, 0xab, 0xd8, 0x38, +0xb7, 0xe5, 0x48, 0xbc, 0xe7, 0x7d, 0xd0, 0xee, +0x3c, 0xb8, 0xe5, 0x4d, 0xbe, 0xe8, 0x53, 0xbf, +0xe7, 0x83, 0xd2, 0xee, 0x46, 0xbb, 0xe6, 0x4a, +0xbd, 0xe6, 0x5a, 0xc2, 0xe8, 0x89, 0xd3, 0xef, +0x4f, 0xbe, 0xe6, 0x69, 0xc7, 0xea, 0x69, 0xc8, +0xeb, 0x5d, 0xc4, 0xe9, 0x89, 0xc4, 0xe5, 0x9a, +0xd0, 0xea, 0xb8, 0xc6, 0xd0, 0x36, 0xb7, 0xe7, +0x85, 0xb1, 0xd1, 0x96, 0xb8, 0xd0, 0xaf, 0xc2, +0xd0, 0x87, 0xd1, 0xed, 0x8b, 0xd2, 0xed, 0x5f, +0xa6, 0xd6, 0x6d, 0xb0, 0xda, 0x1d, 0xb0, 0xe4, +0x6f, 0xc8, 0xe9, 0x6d, 0xc7, 0xe9, 0x5e, 0xc7, +0xec, 0x57, 0xc1, 0xe7, 0x5b, 0xc2, 0xe7, 0x5f, +0xc3, 0xe8, 0x63, 0xc4, 0xe8, 0x98, 0xd7, 0xef, +0x2f, 0xaf, 0xe2, 0x13, 0xac, 0xe3, 0x80, 0xd3, +0xf0, 0x8a, 0x67, 0x71, 0xfc, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0xe1, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd5, 0x59, 0x5f, 0xda, 0x40, 0x10, +0x00, 0xf0, 0x24, 0x28, 0x54, 0x04, 0x1a, 0x52, +0xf1, 0x46, 0xd1, 0x8a, 0x8a, 0xe2, 0x91, 0x20, +0x5a, 0x44, 0x25, 0x04, 0x25, 0xc8, 0x55, 0xa1, +0x11, 0x94, 0x53, 0x50, 0x54, 0xbc, 0xad, 0xda, +0xc3, 0x56, 0xfd, 0xea, 0x26, 0x7d, 0x31, 0x89, +0xbb, 0x8b, 0xdb, 0x67, 0xe7, 0xfd, 0xff, 0xdb, +0x99, 0xd9, 0xdd, 0x19, 0x82, 0x78, 0x8f, 0xff, +0x0e, 0x92, 0x82, 0x06, 0x09, 0x16, 0x86, 0xb6, +0x76, 0xa3, 0xd1, 0xf4, 0xa1, 0xc3, 0xdc, 0x69, +0xb1, 0xda, 0x3e, 0xd2, 0x76, 0xe6, 0x53, 0x97, +0xa3, 0xbb, 0xa7, 0xb7, 0xaf, 0x7f, 0x60, 0xd0, +0x39, 0x34, 0x0c, 0x24, 0xae, 0x11, 0x66, 0xf4, +0xf3, 0x98, 0x7b, 0x7c, 0x62, 0xd2, 0xa4, 0x22, +0x9e, 0xa9, 0x69, 0xef, 0xcc, 0xec, 0xdc, 0x3c, +0xf8, 0x18, 0x96, 0xa3, 0x7c, 0x0b, 0x32, 0xf1, +0x6b, 0x72, 0x5a, 0x5c, 0xfa, 0x12, 0x08, 0x2c, +0x07, 0xe1, 0xd5, 0x58, 0x56, 0xe4, 0x53, 0x68, +0x75, 0xee, 0xab, 0x2c, 0xb7, 0x16, 0x9a, 0x83, +0x12, 0xd9, 0x58, 0xf9, 0x89, 0xb0, 0x60, 0xd7, +0xd4, 0x3b, 0xcc, 0x45, 0xd6, 0x37, 0x50, 0x5d, +0xb3, 0xf1, 0xe1, 0xa8, 0xc8, 0x68, 0x0c, 0x1b, +0xdb, 0xa4, 0x90, 0x9d, 0x8e, 0x4f, 0x46, 0xf9, +0x44, 0x52, 0x6d, 0x52, 0xe9, 0xaf, 0x28, 0x22, +0x9b, 0x2d, 0x81, 0xcf, 0xf8, 0xb3, 0x6a, 0x43, +0x7d, 0x43, 0x12, 0xd9, 0xd0, 0x62, 0x46, 0x90, +0x1c, 0x2a, 0x13, 0xdc, 0x0e, 0x12, 0x2d, 0x8c, +0x3d, 0x21, 0x88, 0xb9, 0xfc, 0x8b, 0xd9, 0xd9, +0xdd, 0x21, 0x5a, 0x19, 0xc6, 0x2f, 0x16, 0x8a, +0xa5, 0x17, 0x63, 0x20, 0x5a, 0x05, 0x49, 0x25, +0xa5, 0x42, 0xb9, 0xe2, 0x81, 0xbd, 0x2d, 0xb0, +0xc9, 0xe6, 0xca, 0x52, 0x75, 0x0f, 0xcf, 0x38, +0x8a, 0x52, 0xcd, 0xdc, 0x8f, 0x67, 0xf2, 0x95, +0x5a, 0x7d, 0xff, 0x00, 0xcf, 0x94, 0xaa, 0xf5, +0xc6, 0x21, 0xfa, 0x12, 0x5f, 0x99, 0x23, 0xcc, +0x53, 0x14, 0x82, 0x57, 0x8b, 0x92, 0xd8, 0x31, +0x56, 0xc7, 0x94, 0xf2, 0x2d, 0x58, 0xf7, 0xa2, +0x34, 0xd9, 0x5c, 0xc2, 0x14, 0xd9, 0x8e, 0x3c, +0xa6, 0x48, 0x56, 0x1c, 0x98, 0x82, 0x29, 0x66, +0x75, 0x22, 0xd5, 0x42, 0xd8, 0x73, 0x49, 0x9d, +0x20, 0xd3, 0x24, 0x52, 0xd0, 0x12, 0xa3, 0x13, +0x86, 0x5d, 0xd4, 0xbf, 0x94, 0x3f, 0xb2, 0x44, +0xeb, 0xeb, 0x60, 0x9b, 0x27, 0xa8, 0xb1, 0x14, +0xf7, 0xbf, 0x12, 0xa7, 0x9c, 0x73, 0x79, 0x1e, +0x2e, 0x6c, 0x67, 0x5b, 0x7a, 0xe1, 0x3a, 0x6f, +0x46, 0x62, 0x17, 0x50, 0x61, 0x15, 0xe3, 0x5a, +0x91, 0xba, 0x64, 0x37, 0x62, 0x57, 0xd7, 0x90, +0x41, 0xfe, 0x6f, 0xc0, 0x8a, 0xba, 0x3d, 0xf1, +0xfd, 0x66, 0x69, 0x2d, 0x34, 0x7d, 0x7d, 0x73, +0x09, 0x13, 0xb7, 0x6e, 0x3e, 0xa7, 0x59, 0x16, +0x9e, 0x9e, 0xee, 0xc0, 0x9d, 0xf7, 0x47, 0x84, +0x73, 0x81, 0xc5, 0x4f, 0xde, 0x2d, 0x4f, 0xfe, +0x70, 0x94, 0xcf, 0x08, 0x62, 0xa1, 0x2c, 0xd5, +0xea, 0x8d, 0xea, 0xaf, 0xdf, 0xf7, 0x7f, 0x66, +0xbc, 0x77, 0x7f, 0x29, 0x88, 0x78, 0x78, 0x1c, +0x03, 0x93, 0x00, 0x70, 0xf4, 0x93, 0x94, 0x4f, +0x16, 0x10, 0x32, 0x0b, 0x5c, 0x30, 0xd4, 0x93, +0xcf, 0x04, 0x5b, 0x7c, 0x83, 0x4e, 0x60, 0x8f, +0x11, 0xcb, 0x55, 0xd9, 0xaf, 0xc0, 0xea, 0xdf, +0xe3, 0x6d, 0xf1, 0x0c, 0x8f, 0xe9, 0x5d, 0x6a, +0x93, 0x5f, 0x8e, 0x3d, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_aggregate_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_aggregate_png = new wxImage(); + if (!img_ex_aggregate_png || !img_ex_aggregate_png->IsOk()) + { + wxMemoryInputStream img_ex_aggregate_pngIS(ex_aggregate_png_data, sizeof(ex_aggregate_png_data)); + img_ex_aggregate_png->LoadFile(img_ex_aggregate_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_aggregate_png; +} +#define ex_aggregate_png_img ex_aggregate_png_img() + +static wxBitmap *ex_aggregate_png_bmp() +{ + static wxBitmap *bmp_ex_aggregate_png; + if (!bmp_ex_aggregate_png || !bmp_ex_aggregate_png->IsOk()) + bmp_ex_aggregate_png = new wxBitmap(*ex_aggregate_png_img); + return bmp_ex_aggregate_png; +} +#define ex_aggregate_png_bmp ex_aggregate_png_bmp() + +static wxIcon *ex_aggregate_png_ico() +{ + static wxIcon *ico_ex_aggregate_png; + if (!ico_ex_aggregate_png || !ico_ex_aggregate_png->IsOk()) + { + ico_ex_aggregate_png = new wxIcon(); + ico_ex_aggregate_png->CopyFromBitmap(*ex_aggregate_png_bmp); + } + return ico_ex_aggregate_png; +} +#define ex_aggregate_png_ico ex_aggregate_png_ico() + +#endif // EX_AGGREGATE_PNG_H diff --git a/include/images/ex_append.png b/include/images/ex_append.png new file mode 100644 index 0000000..017a206 Binary files /dev/null and b/include/images/ex_append.png differ diff --git a/include/images/ex_append.pngc b/include/images/ex_append.pngc new file mode 100644 index 0000000..a148078 --- /dev/null +++ b/include/images/ex_append.pngc @@ -0,0 +1,190 @@ +#ifndef EX_APPEND_PNG_H +#define EX_APPEND_PNG_H + +static const unsigned char ex_append_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x42, 0xbd, 0xe9, +0x47, 0xbe, 0xe9, 0x75, 0xce, 0xef, 0x79, 0xd0, +0xef, 0x55, 0xc2, 0xe9, 0x86, 0xd4, 0xf0, 0x66, +0xc8, 0xec, 0x6a, 0xc9, 0xec, 0x6f, 0xca, 0xeb, +0x96, 0xd9, 0xf1, 0x7b, 0xce, 0xed, 0x82, 0xd1, +0xed, 0xa6, 0xde, 0xf2, 0x8e, 0xd4, 0xee, 0x92, +0xd6, 0xef, 0xaf, 0xe1, 0xf3, 0x05, 0xa7, 0xe1, +0x4d, 0xc1, 0xe9, 0x1b, 0xae, 0xe3, 0x5b, 0xc5, +0xeb, 0x62, 0xc7, 0xeb, 0x38, 0xb7, 0xe5, 0x50, +0xbe, 0xe7, 0x6b, 0xc7, 0xe8, 0x72, 0x96, 0xa1, +0xc1, 0x8f, 0x36, 0xf4, 0xf0, 0xc8, 0xf0, 0xec, +0xb7, 0xef, 0xea, 0xb5, 0xef, 0xe9, 0xb4, 0xf2, +0xed, 0xc5, 0xed, 0xe5, 0xb1, 0xed, 0xe4, 0xb0, +0xec, 0xe3, 0xb0, 0xf1, 0xea, 0xc3, 0xf0, 0xe8, +0xc2, 0xeb, 0xdf, 0xad, 0xeb, 0xde, 0xac, 0xea, +0xdd, 0xab, 0xef, 0xe4, 0xbf, 0xeb, 0xe6, 0x9f, +0xef, 0xeb, 0xb6, 0xe9, 0xe0, 0x9a, 0xe8, 0xdf, +0x99, 0xee, 0xe6, 0xb3, 0xe7, 0xdb, 0x96, 0xe6, +0xd8, 0x94, 0xec, 0xe1, 0xae, 0xe3, 0xd2, 0x8f, +0xe2, 0xd0, 0x8d, 0xe9, 0xda, 0xa9, 0xea, 0xe3, +0x9c, 0xe8, 0xdd, 0x98, 0xe5, 0xd6, 0x92, 0xe1, +0xcc, 0x8b, 0xe9, 0xd9, 0xa7, 0xe4, 0xd5, 0x91, +0xe4, 0xd3, 0x90, 0xe2, 0xce, 0x8c, 0xe8, 0xd7, +0xa6, 0xef, 0xe8, 0xb3, 0xed, 0xe1, 0xbc, 0xc7, +0xaa, 0x75, 0xf0, 0xe6, 0xc0, 0xe7, 0xd4, 0xa4, +0xe6, 0xd3, 0xa3, 0xec, 0xdd, 0xb9, 0xe0, 0xca, +0x89, 0xde, 0xc5, 0x85, 0xde, 0xc3, 0x84, 0xdd, +0xc1, 0x82, 0xe6, 0xd1, 0xa1, 0xdf, 0xc8, 0x87, +0xe5, 0xcf, 0xa1, 0xe6, 0xd1, 0xa2, 0xdc, 0xbf, +0x80, 0xe4, 0xce, 0x9f, 0xef, 0xe6, 0xc0, 0xe6, +0xd2, 0xa3, 0xeb, 0xd9, 0xb6, 0xe4, 0xcd, 0x9e, +0xe3, 0xcc, 0x9e, 0xe3, 0xcb, 0x9e, 0xdb, 0xbd, +0x7f, 0xda, 0xba, 0x7d, 0x86, 0xa9, 0x64, 0x52, +0x8d, 0x19, 0xa5, 0xcb, 0x64, 0xa8, 0xd0, 0x68, +0xab, 0xd5, 0x6c, 0xae, 0xda, 0x71, 0xb2, 0xe0, +0x76, 0xb5, 0xe5, 0x7a, 0x92, 0x95, 0xd1, 0x66, +0x6b, 0xd1, 0xcb, 0xcc, 0xf1, 0xbc, 0xbe, 0xec, +0xbe, 0xbf, 0xed, 0xce, 0xce, 0xf2, 0xd1, 0xd1, +0xf2, 0xc1, 0xc2, 0xee, 0xc3, 0xc4, 0xef, 0xd3, +0xd4, 0xf3, 0xd5, 0xd5, 0xf4, 0xc8, 0xc8, 0xf0, +0xc9, 0xc9, 0xf1, 0xca, 0xcb, 0xf1, 0xd9, 0xda, +0xf5, 0xde, 0xde, 0xf7, 0xd7, 0xd7, 0xf5, 0xe1, +0xe1, 0xf7, 0xbc, 0xbd, 0xec, 0xa7, 0xa9, 0xe6, +0xa8, 0xaa, 0xe7, 0xbf, 0xbf, 0xee, 0xad, 0xaf, +0xe9, 0xaf, 0xb1, 0xe9, 0xc5, 0xc5, 0xef, 0xc7, +0xc8, 0xef, 0xb5, 0xb6, 0xeb, 0xb7, 0xb8, 0xeb, +0xb8, 0xb9, 0xec, 0xd4, 0xd4, 0xf4, 0xc7, 0xc7, +0xf0, 0x89, 0x96, 0xf7, 0x39, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x41, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x90, 0xeb, 0x53, 0x12, 0x51, 0x18, +0xc6, 0xed, 0x84, 0x85, 0x85, 0xa2, 0x84, 0x14, +0xd9, 0x2b, 0x2c, 0xb8, 0x08, 0xcb, 0x45, 0x60, +0x61, 0x91, 0x9b, 0x2b, 0xc9, 0x4d, 0x2e, 0x82, +0x22, 0x0b, 0x6e, 0x65, 0xb5, 0x26, 0x60, 0x68, +0x6a, 0x99, 0x76, 0xf7, 0x5f, 0x6f, 0x77, 0x27, +0x1b, 0xb0, 0x73, 0x28, 0x1c, 0x67, 0xfa, 0x50, +0xcf, 0x87, 0x77, 0xe6, 0x9d, 0x79, 0x7f, 0xe7, +0x39, 0xcf, 0x33, 0x32, 0xf2, 0x5f, 0xaa, 0x6e, +0x20, 0x45, 0xc4, 0x89, 0x43, 0xd0, 0x4d, 0x8d, +0x66, 0xf4, 0x16, 0xba, 0xad, 0xd5, 0x6a, 0xc7, +0xd0, 0xd8, 0x9d, 0xbb, 0xba, 0x71, 0x34, 0x3e, +0xa1, 0xd7, 0x4f, 0xa2, 0xc9, 0x29, 0x83, 0xe1, +0x1e, 0xc2, 0x22, 0x1a, 0xa3, 0xd1, 0x38, 0x8a, +0xa6, 0x4d, 0x26, 0xd3, 0x7d, 0xf4, 0xc0, 0x6c, +0x36, 0xeb, 0xd0, 0xc4, 0x43, 0xad, 0x56, 0x8f, +0xa6, 0x66, 0x66, 0x74, 0x06, 0x34, 0xc8, 0x65, +0xfa, 0xcf, 0x5d, 0x1e, 0xa9, 0x7f, 0x26, 0x4e, +0x1c, 0x02, 0xb3, 0x16, 0x8b, 0x65, 0xf6, 0x62, +0x5a, 0x29, 0xca, 0x06, 0x36, 0xfb, 0x1c, 0xed, +0x80, 0x79, 0xa7, 0x8b, 0x71, 0x03, 0x16, 0xb1, +0x78, 0x3c, 0x1e, 0x8b, 0x3a, 0xbd, 0x40, 0xf9, +0x7c, 0x0b, 0x7e, 0xb0, 0x07, 0x82, 0x41, 0x16, +0x9c, 0xa1, 0x50, 0x98, 0x1b, 0x8c, 0x44, 0x22, +0x56, 0x19, 0x59, 0x58, 0xb4, 0x03, 0x1d, 0x8c, +0x46, 0x9d, 0xc0, 0x84, 0xc3, 0xb1, 0xf8, 0x20, +0xc4, 0x1b, 0x89, 0x44, 0x28, 0xf0, 0x2f, 0x06, +0x02, 0x34, 0xb0, 0xd1, 0x44, 0x92, 0x01, 0x6e, +0x29, 0x16, 0xe3, 0xf1, 0xc8, 0x8f, 0x14, 0x14, +0xb5, 0xac, 0xa4, 0xa0, 0xd5, 0x14, 0x8c, 0x9c, +0xc2, 0x1d, 0xe7, 0xf9, 0x14, 0x16, 0x79, 0x0c, +0x8a, 0x88, 0x13, 0xef, 0xe2, 0xf5, 0x5a, 0x67, +0xc1, 0xe6, 0xf7, 0xdb, 0x1d, 0xe0, 0x60, 0x59, +0xe7, 0x0a, 0xb8, 0x39, 0x2e, 0x9e, 0x82, 0x54, +0x3a, 0x9d, 0xc9, 0xe2, 0x3f, 0x26, 0xa7, 0xf0, +0x2d, 0x5f, 0xa4, 0x48, 0x24, 0x43, 0x72, 0x8a, +0x58, 0x2c, 0xc7, 0x43, 0x3a, 0xbf, 0x5a, 0x28, +0xe2, 0x91, 0xbe, 0x62, 0x93, 0x4a, 0xb1, 0xf1, +0x5c, 0xae, 0x94, 0x86, 0xcc, 0x6a, 0xa1, 0x50, +0x26, 0x21, 0x97, 0x8b, 0xe5, 0x4b, 0xa5, 0x7c, +0x06, 0xd6, 0x0a, 0x95, 0x4a, 0x15, 0x8f, 0xd8, +0xfc, 0xf6, 0x39, 0xb9, 0x25, 0xd6, 0xe9, 0x5a, +0x97, 0x53, 0xc4, 0xd5, 0x14, 0x99, 0x8d, 0x2c, +0x64, 0xcb, 0xd5, 0x6a, 0xed, 0xda, 0x1a, 0x73, +0xd0, 0x2c, 0x3b, 0x0f, 0x2b, 0x0c, 0xc3, 0xb9, +0x21, 0xc5, 0xf3, 0x69, 0xf9, 0xfd, 0xb5, 0x62, +0xb9, 0x06, 0xb5, 0xcd, 0xba, 0x80, 0x77, 0x01, +0x3a, 0x1a, 0x4d, 0xb8, 0xe4, 0x14, 0x4b, 0x6a, +0x8a, 0x7c, 0x7e, 0x03, 0x8a, 0x95, 0x4a, 0xa3, +0x0a, 0xf5, 0x66, 0xb3, 0x29, 0xe0, 0x11, 0x36, +0x91, 0xb8, 0x54, 0x6c, 0xb9, 0xd2, 0x68, 0x6c, +0x82, 0x40, 0x46, 0x7e, 0x2d, 0xb6, 0xda, 0x68, +0xc8, 0xc7, 0x03, 0x90, 0x75, 0x86, 0xe3, 0xe4, +0x96, 0xf8, 0xb4, 0x92, 0xa2, 0x58, 0x56, 0x52, +0xd4, 0x95, 0x14, 0x35, 0x41, 0x10, 0xae, 0xad, +0xb1, 0xab, 0x6b, 0x4b, 0xdc, 0x22, 0x6e, 0x24, +0xe2, 0x49, 0xcf, 0x55, 0xff, 0x46, 0x24, 0x9e, +0x3e, 0xfb, 0x79, 0xd5, 0xbf, 0x11, 0xa4, 0xdc, +0x6c, 0x3f, 0x17, 0xb1, 0x1b, 0xd1, 0x45, 0xdc, +0x16, 0x7b, 0x5c, 0x7a, 0x37, 0xb2, 0x4f, 0xdf, +0xab, 0xe2, 0xef, 0x3c, 0xd4, 0xa3, 0x17, 0x22, +0x71, 0x23, 0x7e, 0x6d, 0xd8, 0x92, 0x87, 0xd2, +0x4b, 0x49, 0x11, 0x71, 0xe2, 0x10, 0x69, 0xe7, +0xd5, 0xee, 0x6e, 0x4b, 0x6a, 0x77, 0xf6, 0xf6, +0x5e, 0x4b, 0xdd, 0xfd, 0x83, 0x37, 0x87, 0xd2, +0x61, 0xab, 0xdd, 0x3e, 0x92, 0x8e, 0xba, 0xdd, +0xe3, 0xb7, 0x12, 0x16, 0x79, 0x77, 0x72, 0xf2, +0xfe, 0x54, 0xea, 0x9c, 0x9d, 0x7d, 0xf8, 0x28, +0x7d, 0xfa, 0xfc, 0xe5, 0xeb, 0x8e, 0xd4, 0x3a, +0xed, 0x74, 0xda, 0xd2, 0xb7, 0xf3, 0xfd, 0x83, +0xe3, 0xbf, 0x89, 0x0c, 0x9f, 0xe5, 0x0a, 0x8d, +0xfd, 0x93, 0xfa, 0x0e, 0xd3, 0xdf, 0xe3, 0xeb, +0x25, 0xe2, 0x64, 0x72, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_append_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_append_png = new wxImage(); + if (!img_ex_append_png || !img_ex_append_png->IsOk()) + { + wxMemoryInputStream img_ex_append_pngIS(ex_append_png_data, sizeof(ex_append_png_data)); + img_ex_append_png->LoadFile(img_ex_append_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_append_png; +} +#define ex_append_png_img ex_append_png_img() + +static wxBitmap *ex_append_png_bmp() +{ + static wxBitmap *bmp_ex_append_png; + if (!bmp_ex_append_png || !bmp_ex_append_png->IsOk()) + bmp_ex_append_png = new wxBitmap(*ex_append_png_img); + return bmp_ex_append_png; +} +#define ex_append_png_bmp ex_append_png_bmp() + +static wxIcon *ex_append_png_ico() +{ + static wxIcon *ico_ex_append_png; + if (!ico_ex_append_png || !ico_ex_append_png->IsOk()) + { + ico_ex_append_png = new wxIcon(); + ico_ex_append_png->CopyFromBitmap(*ex_append_png_bmp); + } + return ico_ex_append_png; +} +#define ex_append_png_ico ex_append_png_ico() + +#endif // EX_APPEND_PNG_H diff --git a/include/images/ex_bmp_and.png b/include/images/ex_bmp_and.png new file mode 100644 index 0000000..64d5869 Binary files /dev/null and b/include/images/ex_bmp_and.png differ diff --git a/include/images/ex_bmp_and.pngc b/include/images/ex_bmp_and.pngc new file mode 100644 index 0000000..a9d1faf --- /dev/null +++ b/include/images/ex_bmp_and.pngc @@ -0,0 +1,170 @@ +#ifndef EX_BMP_AND_PNG_H +#define EX_BMP_AND_PNG_H + +static const unsigned char ex_bmp_and_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x98, 0x50, 0x4c, 0x54, +0x45, 0x95, 0xd2, 0xfb, 0x00, 0x00, 0x00, 0x66, +0x6b, 0xd1, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, +0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x7a, 0x7a, +0x7a, 0x36, 0x88, 0xc1, 0x7b, 0x7b, 0x7b, 0x7c, +0x7c, 0x7c, 0x7e, 0x7e, 0x7e, 0x80, 0x80, 0x80, +0x82, 0x82, 0x82, 0x83, 0x83, 0x83, 0x84, 0x84, +0x84, 0x87, 0x87, 0x87, 0x88, 0x88, 0x88, 0x8b, +0x8b, 0x8b, 0x8d, 0x8d, 0x8d, 0x8e, 0x8e, 0x8e, +0x64, 0x95, 0xd0, 0x8f, 0x8f, 0x8f, 0x90, 0x90, +0x90, 0x91, 0x91, 0x91, 0x8d, 0x8e, 0xbf, 0x92, +0x92, 0x92, 0xc1, 0x8f, 0x36, 0x95, 0x95, 0x95, +0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x99, 0x99, +0x99, 0x9c, 0x9c, 0x9c, 0x9e, 0x9e, 0x9e, 0x9b, +0x9c, 0xc4, 0x9f, 0x9f, 0x9f, 0xa6, 0xa6, 0xa6, +0xa7, 0xa7, 0xa7, 0xb9, 0xa7, 0x72, 0xa8, 0xa8, +0xa8, 0x4e, 0xbe, 0xe6, 0xbb, 0xaa, 0x73, 0xab, +0xab, 0xab, 0xbb, 0xac, 0x74, 0xbb, 0xad, 0x76, +0xad, 0xad, 0xad, 0x5a, 0xc1, 0xe7, 0xae, 0xae, +0xae, 0xbc, 0xb0, 0x77, 0xaf, 0xaf, 0xaf, 0xbd, +0xb1, 0x79, 0xab, 0xac, 0xe8, 0xbe, 0xb2, 0x7a, +0x89, 0xb9, 0xdb, 0xb2, 0xb2, 0xb2, 0x64, 0xc5, +0xe8, 0xb7, 0xb7, 0xb7, 0xb3, 0xb4, 0xea, 0x71, +0xcb, 0xec, 0xda, 0xbb, 0x7e, 0x7a, 0xce, 0xec, +0xdb, 0xbd, 0x89, 0xdc, 0xbe, 0x80, 0xbc, 0xbd, +0xec, 0xbc, 0xbd, 0xed, 0xdd, 0xc1, 0x82, 0x83, +0xd1, 0xed, 0xc3, 0xc3, 0xc3, 0xdd, 0xc2, 0x83, +0xc0, 0xc1, 0xee, 0xc6, 0xc6, 0xc6, 0x8b, 0xd4, +0xee, 0xdf, 0xc6, 0x86, 0xdf, 0xc8, 0x87, 0x92, +0xd5, 0xef, 0xc6, 0xc7, 0xef, 0xe0, 0xca, 0x89, +0xca, 0xca, 0xca, 0x94, 0xd8, 0xf0, 0xe3, 0xcb, +0x9e, 0xe3, 0xcc, 0x9e, 0xe4, 0xcd, 0x9e, 0xe2, +0xd0, 0x8d, 0xe4, 0xce, 0x9f, 0xcc, 0xcd, 0xf1, +0xcd, 0xce, 0xf2, 0xe5, 0xd0, 0xa1, 0xe6, 0xd1, +0xa2, 0xd3, 0xd3, 0xd3, 0xa6, 0xde, 0xf2, 0xe5, +0xd6, 0x93, 0xe6, 0xd4, 0xa4, 0xd5, 0xd5, 0xd5, +0xe7, 0xd5, 0xa5, 0xad, 0xdf, 0xf3, 0xd4, 0xd4, +0xf3, 0xe8, 0xd7, 0xa6, 0xe8, 0xd7, 0xa7, 0xea, +0xd8, 0xb6, 0xe9, 0xda, 0xa8, 0xe9, 0xda, 0xa9, +0xda, 0xda, 0xda, 0xe9, 0xdc, 0xaa, 0xea, 0xdc, +0xaa, 0xeb, 0xdb, 0xb8, 0xdc, 0xdc, 0xdc, 0xdd, +0xdd, 0xdd, 0xeb, 0xde, 0xac, 0xec, 0xdd, 0xb9, +0xde, 0xde, 0xde, 0xec, 0xe0, 0xad, 0xec, 0xe0, +0xae, 0xed, 0xdf, 0xbb, 0xde, 0xde, 0xf6, 0xec, +0xe2, 0xaf, 0xe1, 0xe1, 0xe1, 0xec, 0xe3, 0xb0, +0xe2, 0xe2, 0xe2, 0xef, 0xe4, 0xbf, 0xe5, 0xe5, +0xe5, 0xf0, 0xe6, 0xc0, 0xf0, 0xe7, 0xc1, 0xe7, +0xe7, 0xe7, 0xe9, 0xe9, 0xe9, 0xf1, 0xeb, 0xc4, +0xea, 0xea, 0xea, 0xf0, 0xf0, 0xf0, 0xf1, 0xf1, +0xf1, 0xf2, 0xf2, 0xf2, 0xf3, 0xf3, 0xf3, 0xf5, +0xf5, 0xf5, 0xf6, 0xf6, 0xf6, 0xf8, 0xf8, 0xf8, +0xf9, 0xf9, 0xf9, 0xfd, 0xfd, 0xfd, 0xff, 0xff, +0xff, 0x25, 0xb1, 0xea, 0xff, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, +0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, +0x00, 0x01, 0xef, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0x59, 0x53, 0x13, 0x41, 0x14, +0x85, 0x73, 0x73, 0x63, 0x18, 0x89, 0x08, 0x0a, +0x28, 0xda, 0xb2, 0xc8, 0xa2, 0x88, 0x22, 0x82, +0x62, 0x94, 0x45, 0x56, 0x09, 0x44, 0x20, 0x84, +0x68, 0x46, 0x1d, 0xb6, 0x6c, 0x24, 0x22, 0x86, +0xa0, 0x09, 0x02, 0x6e, 0x18, 0x96, 0xfb, 0xb7, +0x9d, 0x9e, 0x19, 0x8a, 0xad, 0x33, 0x93, 0x54, +0xa5, 0x28, 0x1f, 0x38, 0x0f, 0xfd, 0x72, 0xeb, +0xab, 0x33, 0xe7, 0x74, 0xdf, 0xb1, 0xd9, 0x2e, +0x74, 0x9e, 0xaa, 0x96, 0xb8, 0xaa, 0xcf, 0x0e, +0xba, 0xb5, 0x41, 0xb7, 0x00, 0x91, 0xa6, 0xfb, +0x86, 0x3d, 0x0b, 0x92, 0x60, 0xf0, 0xc1, 0xe3, +0xf5, 0x8a, 0x06, 0x36, 0xa9, 0xa7, 0xf5, 0xb1, +0xdb, 0x2b, 0x42, 0x3c, 0x6e, 0x77, 0x8f, 0x57, +0x2a, 0x8e, 0x4b, 0xce, 0x2c, 0x75, 0xda, 0xa0, +0x4e, 0x80, 0xd8, 0xdf, 0xbe, 0x7e, 0xf3, 0x6e, +0xdd, 0x7e, 0x76, 0xc0, 0x7e, 0xa6, 0xd3, 0xe9, +0x2d, 0x26, 0x42, 0x06, 0x9e, 0xc2, 0xe0, 0xa2, +0x08, 0x49, 0x3f, 0x83, 0xae, 0x64, 0x61, 0xc8, +0x57, 0xf8, 0x08, 0x96, 0x08, 0xe9, 0x32, 0x90, +0xb5, 0x2e, 0x78, 0x22, 0x46, 0x8e, 0xb2, 0x10, +0x65, 0xea, 0x4b, 0x9c, 0x95, 0x53, 0x3a, 0xc4, +0xb6, 0x92, 0xc9, 0xcf, 0x9b, 0x22, 0xa4, 0xd6, +0xce, 0x55, 0xab, 0x21, 0x5f, 0x1c, 0xc8, 0x35, +0xa2, 0x21, 0xfd, 0x8c, 0xab, 0xdf, 0xc2, 0xe5, +0x36, 0xb6, 0xfc, 0xc9, 0x76, 0xe0, 0x55, 0xdd, +0x65, 0x33, 0x1e, 0x8f, 0x6f, 0x88, 0xb3, 0xdc, +0x82, 0x46, 0x2d, 0x0b, 0x91, 0x13, 0xb3, 0x44, +0xbb, 0xe8, 0xd4, 0x91, 0xf8, 0x23, 0x78, 0x18, +0x15, 0x23, 0xf0, 0x12, 0x0c, 0xe4, 0x0a, 0xfe, +0x20, 0xfa, 0x84, 0x37, 0x0c, 0x04, 0x66, 0x21, +0x6a, 0xe5, 0xd2, 0x86, 0xcd, 0xb4, 0x52, 0x86, +0x2b, 0x3a, 0xb2, 0xfc, 0x00, 0xee, 0x45, 0xac, +0x1a, 0xfb, 0xed, 0xc2, 0xeb, 0x58, 0x3a, 0xa7, +0xb7, 0xcc, 0x36, 0xa2, 0x91, 0x48, 0xca, 0xbc, +0x31, 0xa2, 0xbd, 0x06, 0xc4, 0x6b, 0x3b, 0xc6, +0xdd, 0xe4, 0xd3, 0x18, 0x65, 0xab, 0xf0, 0x8e, +0x03, 0xa7, 0x28, 0xab, 0x16, 0x40, 0x36, 0x96, +0x0a, 0x85, 0x96, 0x52, 0x16, 0x59, 0xda, 0xf1, +0x39, 0x8d, 0xe1, 0xa5, 0x58, 0x0c, 0x2b, 0x38, +0x12, 0x9a, 0x84, 0x09, 0xc5, 0xb4, 0x31, 0xa2, +0x32, 0xde, 0xf1, 0x0b, 0xbc, 0x5c, 0x85, 0x6d, +0x1c, 0x59, 0x9a, 0x80, 0x71, 0xc5, 0xd4, 0x85, +0x5f, 0xcb, 0x2f, 0x35, 0xc5, 0x7d, 0xf5, 0xfe, +0xbf, 0xab, 0x59, 0xd8, 0xfc, 0x78, 0x2e, 0xe4, +0x30, 0x0b, 0xd1, 0x4d, 0xac, 0xc9, 0xec, 0x6f, +0xb7, 0x20, 0x96, 0xef, 0x73, 0x24, 0xa5, 0x28, +0xca, 0xaa, 0x69, 0x63, 0x44, 0x31, 0xfd, 0x89, +0x61, 0x29, 0xde, 0x3d, 0xa0, 0xfc, 0x1a, 0xa3, +0x6f, 0x4d, 0x2e, 0x87, 0xab, 0xe1, 0xfd, 0xdf, +0x0a, 0xec, 0x54, 0xb3, 0xac, 0xca, 0xb2, 0x9c, +0xb0, 0xd8, 0x17, 0x3a, 0x26, 0xf5, 0xc3, 0xe4, +0x51, 0x18, 0x0a, 0x5a, 0x6e, 0xa5, 0xb1, 0x60, +0xda, 0xc1, 0xe4, 0x21, 0x78, 0x15, 0x2c, 0x6c, +0x91, 0x83, 0x2a, 0x12, 0x60, 0x05, 0xfd, 0x61, +0x12, 0xc1, 0x40, 0x20, 0x61, 0xb1, 0x95, 0x27, +0x95, 0xd7, 0x56, 0x9e, 0x76, 0x09, 0xf8, 0xfd, +0x61, 0xf3, 0x37, 0x76, 0x1a, 0xf1, 0xf7, 0x42, +0xef, 0x8c, 0xf9, 0x56, 0x8a, 0x10, 0x5f, 0x61, +0x2e, 0x33, 0x39, 0x91, 0x9c, 0x59, 0xc2, 0x3e, +0x9f, 0x2f, 0x5c, 0xa4, 0xc6, 0x2e, 0xf4, 0x1f, +0xe9, 0x1f, 0x25, 0xa9, 0x9b, 0x39, 0xad, 0x49, +0x83, 0x66, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_and_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_and_png = new wxImage(); + if (!img_ex_bmp_and_png || !img_ex_bmp_and_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_and_pngIS(ex_bmp_and_png_data, sizeof(ex_bmp_and_png_data)); + img_ex_bmp_and_png->LoadFile(img_ex_bmp_and_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_and_png; +} +#define ex_bmp_and_png_img ex_bmp_and_png_img() + +static wxBitmap *ex_bmp_and_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_and_png; + if (!bmp_ex_bmp_and_png || !bmp_ex_bmp_and_png->IsOk()) + bmp_ex_bmp_and_png = new wxBitmap(*ex_bmp_and_png_img); + return bmp_ex_bmp_and_png; +} +#define ex_bmp_and_png_bmp ex_bmp_and_png_bmp() + +static wxIcon *ex_bmp_and_png_ico() +{ + static wxIcon *ico_ex_bmp_and_png; + if (!ico_ex_bmp_and_png || !ico_ex_bmp_and_png->IsOk()) + { + ico_ex_bmp_and_png = new wxIcon(); + ico_ex_bmp_and_png->CopyFromBitmap(*ex_bmp_and_png_bmp); + } + return ico_ex_bmp_and_png; +} +#define ex_bmp_and_png_ico ex_bmp_and_png_ico() + +#endif // EX_BMP_AND_PNG_H diff --git a/include/images/ex_bmp_heap.png b/include/images/ex_bmp_heap.png new file mode 100644 index 0000000..2657d8c Binary files /dev/null and b/include/images/ex_bmp_heap.png differ diff --git a/include/images/ex_bmp_heap.pngc b/include/images/ex_bmp_heap.pngc new file mode 100644 index 0000000..51f2884 --- /dev/null +++ b/include/images/ex_bmp_heap.pngc @@ -0,0 +1,183 @@ +#ifndef EX_BMP_HEAP_PNG_H +#define EX_BMP_HEAP_PNG_H + +static const unsigned char ex_bmp_heap_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, +0x6b, 0xd1, 0x52, 0x8d, 0x19, 0x36, 0x88, 0xc1, +0x5c, 0x95, 0x22, 0x5a, 0x90, 0x65, 0x64, 0x96, +0x39, 0x09, 0xa9, 0xe2, 0x12, 0xab, 0xe2, 0x64, +0x95, 0xd0, 0x71, 0xa2, 0x39, 0x66, 0x96, 0xd1, +0x8d, 0x8e, 0xbf, 0xc1, 0x8f, 0x36, 0x7e, 0xa1, +0x70, 0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x2d, +0xb4, 0xe4, 0x9b, 0x9c, 0xc4, 0x3a, 0xb8, 0xe5, +0x8c, 0xae, 0x74, 0x96, 0xb2, 0x36, 0x42, 0xbd, +0xe9, 0x47, 0xbf, 0xe9, 0x4e, 0xbe, 0xe6, 0x4b, +0xbf, 0xe9, 0x4e, 0xc1, 0xe9, 0x5a, 0xc1, 0xe7, +0x99, 0xbc, 0x78, 0xab, 0xac, 0xe8, 0x5d, 0xc4, +0xea, 0x89, 0xb9, 0xdb, 0x64, 0xc5, 0xe8, 0x62, +0xc6, 0xea, 0xa1, 0xc4, 0x5e, 0x6b, 0xc7, 0xe8, +0x68, 0xc8, 0xec, 0xa2, 0xc6, 0x60, 0xb3, 0xb4, +0xea, 0x6e, 0xcb, 0xec, 0x71, 0xcb, 0xec, 0x6f, +0xcd, 0xee, 0xa6, 0xcc, 0x65, 0x76, 0xcd, 0xec, +0xa5, 0xc1, 0xe4, 0x7a, 0xce, 0xec, 0xdb, 0xbd, +0x89, 0xbc, 0xbd, 0xec, 0x7b, 0xd1, 0xef, 0x83, +0xd1, 0xed, 0x84, 0xd1, 0xee, 0xc0, 0xc1, 0xee, +0x84, 0xd3, 0xf0, 0xac, 0xd6, 0x6d, 0x8b, 0xd4, +0xee, 0x91, 0xd5, 0xee, 0x92, 0xd5, 0xef, 0xae, +0xda, 0x71, 0xc6, 0xc7, 0xef, 0x94, 0xd8, 0xf0, +0x97, 0xd9, 0xf1, 0xb2, 0xe0, 0x76, 0xad, 0xd6, +0xe9, 0xcc, 0xcd, 0xf1, 0xa0, 0xdb, 0xf1, 0xe7, +0xda, 0x2b, 0xe8, 0xda, 0x2a, 0xcd, 0xce, 0xf2, +0xea, 0xdb, 0x2a, 0xec, 0xdb, 0x2a, 0xee, 0xdb, +0x2a, 0xef, 0xdc, 0x2a, 0xf1, 0xdc, 0x2a, 0xf2, +0xdc, 0x2a, 0xf4, 0xdc, 0x2a, 0xb9, 0xdb, 0xec, +0xb7, 0xe7, 0x7c, 0xf6, 0xdd, 0x2a, 0xad, 0xdf, +0xf3, 0xf9, 0xdd, 0x29, 0xfa, 0xdd, 0x29, 0xd4, +0xd4, 0xf3, 0xae, 0xe0, 0xf3, 0xfb, 0xde, 0x29, +0xfc, 0xde, 0x29, 0xfe, 0xde, 0x29, 0xbe, 0xde, +0xed, 0xb9, 0xeb, 0x7f, 0xc0, 0xdf, 0xee, 0xc2, +0xe0, 0xee, 0xbb, 0xee, 0x82, 0xed, 0xe3, 0x60, +0xef, 0xe3, 0x5f, 0xc5, 0xe1, 0xef, 0xf0, 0xe4, +0x5f, 0xbc, 0xf0, 0x84, 0xf2, 0xe4, 0x5f, 0xf3, +0xe4, 0x5f, 0xc7, 0xe3, 0xf0, 0xc8, 0xe3, 0xf0, +0xf3, 0xe5, 0x5f, 0xf4, 0xe5, 0x5f, 0xca, 0xe3, +0xf0, 0xf5, 0xe5, 0x5f, 0xf7, 0xe5, 0x5f, 0xf8, +0xe5, 0x5f, 0xcb, 0xe4, 0xf1, 0xde, 0xde, 0xf6, +0xf8, 0xe6, 0x5f, 0xfa, 0xe6, 0x5f, 0xcd, 0xe5, +0xf2, 0xfc, 0xe6, 0x5f, 0xfe, 0xe6, 0x5f, 0xd1, +0xe7, 0xf2, 0xd3, 0xe8, 0xf3, 0xf2, 0xea, 0x87, +0xd4, 0xe9, 0xf3, 0xd4, 0xe9, 0xf4, 0xf4, 0xeb, +0x87, 0xd6, 0xe9, 0xf4, 0xf6, 0xeb, 0x87, 0xf8, +0xeb, 0x87, 0xd7, 0xea, 0xf5, 0xfa, 0xec, 0x87, +0xfd, 0xec, 0x86, 0xfe, 0xec, 0x86, 0xe1, 0xef, +0xf7, 0x95, 0xe0, 0x4b, 0x58, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, +0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, +0x00, 0x02, 0x6b, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0xeb, 0x53, 0xd3, 0x40, 0x14, +0xc5, 0x49, 0x13, 0x15, 0x31, 0xae, 0xa8, 0x08, +0xbe, 0x51, 0xea, 0x1b, 0xeb, 0x0b, 0x05, 0x7c, +0x56, 0x89, 0x4d, 0x4d, 0x0b, 0xb5, 0xd1, 0xa6, +0x48, 0x69, 0x08, 0x09, 0x50, 0x92, 0x62, 0x96, +0x04, 0x0a, 0xa5, 0xa5, 0x85, 0x7f, 0x9d, 0xdd, +0x84, 0x84, 0x24, 0x6d, 0x32, 0x32, 0xce, 0x38, +0x7e, 0xe0, 0x7c, 0xd8, 0xcc, 0xec, 0xe6, 0xb7, +0x67, 0xce, 0xbd, 0x77, 0xb6, 0xa7, 0xe7, 0x44, +0xff, 0x44, 0x7d, 0x14, 0x56, 0x5f, 0xc7, 0xfe, +0x1d, 0x6b, 0xdf, 0xb7, 0x3a, 0x47, 0xd4, 0x87, +0x67, 0xaf, 0x26, 0xbe, 0x53, 0x1d, 0x08, 0xf5, +0x64, 0xe8, 0xea, 0xf5, 0x97, 0xd4, 0x9b, 0x91, +0xfb, 0x8f, 0x3e, 0x52, 0x5f, 0xc6, 0x26, 0x26, +0x7f, 0xba, 0xff, 0x50, 0x8f, 0xaf, 0xdd, 0xbc, +0xfb, 0xb6, 0x0b, 0x32, 0xd4, 0xdb, 0x7b, 0xf6, +0x06, 0x35, 0x7c, 0x69, 0x60, 0xe0, 0x29, 0x35, +0x36, 0x3c, 0x72, 0x6f, 0x92, 0xfa, 0x0b, 0x97, +0xb0, 0x2c, 0x17, 0xad, 0x7d, 0xdf, 0xea, 0x1c, +0xc5, 0x3e, 0xbf, 0x7e, 0xff, 0xf5, 0x77, 0xec, +0xe8, 0xdf, 0x04, 0x4d, 0x27, 0xd0, 0x07, 0xd4, +0xca, 0xe5, 0x72, 0x0d, 0xd4, 0x44, 0x51, 0xac, +0x83, 0xba, 0x24, 0x49, 0x75, 0xe0, 0x22, 0x2f, +0xce, 0x13, 0x97, 0x7f, 0x78, 0x10, 0x7a, 0x7f, +0x9f, 0xc6, 0x48, 0x79, 0x6a, 0x8a, 0x29, 0x03, +0x91, 0x61, 0x52, 0x12, 0x90, 0x58, 0x96, 0x95, +0x3d, 0x08, 0xf1, 0x90, 0xf0, 0x21, 0xbb, 0xbb, +0x36, 0xc2, 0x30, 0x8c, 0x08, 0xc4, 0x54, 0xaa, +0x0b, 0x12, 0x74, 0xd9, 0xd9, 0xf1, 0x20, 0x52, +0x8a, 0x65, 0x2d, 0x24, 0xed, 0x41, 0x82, 0x59, +0x1c, 0xc4, 0x9b, 0xa2, 0x2e, 0xcb, 0x72, 0xc3, +0x45, 0xfa, 0x63, 0x58, 0xa7, 0xc9, 0x5b, 0x01, +0xe4, 0x39, 0xc0, 0xf2, 0xad, 0x3e, 0x97, 0x2b, +0x64, 0x9c, 0x74, 0x91, 0xed, 0x6d, 0xdb, 0xc5, +0xbe, 0x5f, 0x92, 0x65, 0xb4, 0x2a, 0x2b, 0x95, +0xa6, 0x27, 0xcb, 0x6d, 0xe2, 0x02, 0x19, 0x8f, +0x93, 0x8e, 0xe8, 0xcd, 0x4d, 0x1a, 0x7f, 0x07, +0x09, 0x96, 0x70, 0x52, 0xac, 0x70, 0x1c, 0xa7, +0xfa, 0x10, 0x44, 0x60, 0x3d, 0x18, 0x1d, 0x1d, +0x7f, 0xf7, 0x89, 0xde, 0xd8, 0xa0, 0x17, 0x91, +0x48, 0x96, 0x40, 0xc1, 0xe5, 0x74, 0x3a, 0xad, +0x80, 0x0a, 0xc7, 0x65, 0xd4, 0x08, 0x17, 0x84, +0x38, 0x2e, 0x32, 0x46, 0xbe, 0x55, 0x80, 0xca, +0x65, 0x32, 0x1a, 0x08, 0xcf, 0x82, 0x10, 0x9c, +0xc5, 0x4e, 0xd1, 0x50, 0x2a, 0x28, 0x45, 0x53, +0xd5, 0xb4, 0x66, 0xa0, 0x62, 0x67, 0xc8, 0x73, +0x2e, 0xb2, 0xbe, 0xfe, 0x27, 0x15, 0xf3, 0xf5, +0xc5, 0x46, 0x70, 0x2f, 0x94, 0x06, 0xba, 0x5f, +0x55, 0x91, 0x8b, 0xa6, 0x55, 0x5b, 0x11, 0xdd, +0x3f, 0x44, 0xbc, 0x29, 0xb4, 0x6c, 0x2e, 0xa7, +0x47, 0xcc, 0xd8, 0xda, 0x9a, 0x85, 0x28, 0x69, +0x5c, 0x58, 0x35, 0x83, 0x91, 0x6a, 0x2e, 0x97, +0x83, 0x11, 0x2e, 0xab, 0xab, 0x16, 0x62, 0xf7, +0x42, 0xcd, 0x64, 0xb3, 0x55, 0xa0, 0xfb, 0x91, +0x8e, 0x2c, 0xcb, 0xcb, 0x16, 0xe2, 0x4d, 0xd1, +0x82, 0x10, 0xb6, 0x22, 0x66, 0x6c, 0x69, 0xe9, +0xd8, 0x33, 0xb6, 0xb0, 0x70, 0xe8, 0x82, 0x7b, +0xd1, 0xd4, 0x75, 0xdd, 0x76, 0x69, 0x87, 0x76, +0xff, 0x14, 0x46, 0xc8, 0x80, 0x06, 0x09, 0x9e, +0x30, 0x42, 0x67, 0x6c, 0x1c, 0x23, 0x33, 0x33, +0xbf, 0xe6, 0xe7, 0x17, 0x8f, 0x44, 0xf2, 0x44, +0xc1, 0x88, 0x98, 0xb1, 0x52, 0xa9, 0x8b, 0x4b, +0xc1, 0xeb, 0xd2, 0x91, 0x05, 0x21, 0x56, 0x16, +0x5d, 0x87, 0x4e, 0x8a, 0xb6, 0x61, 0x18, 0xed, +0x88, 0x19, 0x9b, 0x9b, 0x3b, 0xf6, 0x8c, 0xd9, +0x88, 0x73, 0x3f, 0x84, 0x06, 0x76, 0x31, 0xcd, +0xbd, 0xb0, 0xee, 0xa3, 0x87, 0x6f, 0x7a, 0x1a, +0x3f, 0x7e, 0x00, 0xe6, 0xf3, 0x79, 0x08, 0x20, +0x5f, 0x40, 0xc1, 0x4d, 0x41, 0x28, 0x9a, 0x61, +0x33, 0x46, 0x6f, 0xcd, 0x26, 0x93, 0xb3, 0x5b, +0xb4, 0x85, 0xf0, 0x10, 0x18, 0x05, 0x41, 0x40, +0x48, 0xb1, 0xe8, 0x43, 0x02, 0x2e, 0xa5, 0x64, +0xb2, 0x64, 0xbb, 0xf0, 0xbc, 0x01, 0x0c, 0x41, +0x10, 0xcc, 0x20, 0x12, 0xc8, 0x92, 0xc0, 0x33, +0x86, 0x1e, 0x65, 0x5f, 0x8a, 0x3d, 0xd3, 0x9b, +0xc5, 0xae, 0x58, 0x7f, 0xc7, 0x33, 0x1e, 0x51, +0xb1, 0x13, 0xfd, 0x7f, 0x3a, 0x00, 0xd4, 0xf9, +0xd7, 0x22, 0x78, 0xf9, 0xcc, 0xa8, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_heap_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_heap_png = new wxImage(); + if (!img_ex_bmp_heap_png || !img_ex_bmp_heap_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_heap_pngIS(ex_bmp_heap_png_data, sizeof(ex_bmp_heap_png_data)); + img_ex_bmp_heap_png->LoadFile(img_ex_bmp_heap_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_heap_png; +} +#define ex_bmp_heap_png_img ex_bmp_heap_png_img() + +static wxBitmap *ex_bmp_heap_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_heap_png; + if (!bmp_ex_bmp_heap_png || !bmp_ex_bmp_heap_png->IsOk()) + bmp_ex_bmp_heap_png = new wxBitmap(*ex_bmp_heap_png_img); + return bmp_ex_bmp_heap_png; +} +#define ex_bmp_heap_png_bmp ex_bmp_heap_png_bmp() + +static wxIcon *ex_bmp_heap_png_ico() +{ + static wxIcon *ico_ex_bmp_heap_png; + if (!ico_ex_bmp_heap_png || !ico_ex_bmp_heap_png->IsOk()) + { + ico_ex_bmp_heap_png = new wxIcon(); + ico_ex_bmp_heap_png->CopyFromBitmap(*ex_bmp_heap_png_bmp); + } + return ico_ex_bmp_heap_png; +} +#define ex_bmp_heap_png_ico ex_bmp_heap_png_ico() + +#endif // EX_BMP_HEAP_PNG_H diff --git a/include/images/ex_bmp_index.png b/include/images/ex_bmp_index.png new file mode 100644 index 0000000..23b9733 Binary files /dev/null and b/include/images/ex_bmp_index.png differ diff --git a/include/images/ex_bmp_index.pngc b/include/images/ex_bmp_index.pngc new file mode 100644 index 0000000..c72a11f --- /dev/null +++ b/include/images/ex_bmp_index.pngc @@ -0,0 +1,191 @@ +#ifndef EX_BMP_INDEX_PNG_H +#define EX_BMP_INDEX_PNG_H + +static const unsigned char ex_bmp_index_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0xa1, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x66, +0x6b, 0xd1, 0x52, 0x8d, 0x19, 0x36, 0x88, 0xc1, +0x5c, 0x95, 0x22, 0x5a, 0x90, 0x65, 0x64, 0x96, +0x39, 0x0c, 0xa9, 0xe2, 0x74, 0x93, 0x96, 0x64, +0x95, 0xd0, 0x71, 0xa2, 0x39, 0x66, 0x96, 0xd1, +0x8d, 0x8e, 0xbf, 0xc1, 0x8f, 0x36, 0x7e, 0xa1, +0x70, 0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x2d, +0xb4, 0xe4, 0x9b, 0x9c, 0xc4, 0x3a, 0xb8, 0xe5, +0x95, 0xb1, 0x36, 0x8c, 0xae, 0x74, 0xcb, 0xa2, +0x58, 0x43, 0xbc, 0xe8, 0x49, 0xbf, 0xe9, 0x4e, +0xbe, 0xe6, 0x4e, 0xc1, 0xe9, 0x5a, 0xc1, 0xe7, +0x99, 0xbc, 0x78, 0xab, 0xac, 0xe8, 0x5d, 0xc4, +0xea, 0x89, 0xb9, 0xdb, 0x64, 0xc5, 0xe8, 0x62, +0xc6, 0xea, 0xa1, 0xc4, 0x5e, 0x6b, 0xc7, 0xe8, +0x68, 0xc8, 0xec, 0xa2, 0xc6, 0x60, 0xb3, 0xb4, +0xea, 0x6e, 0xcb, 0xec, 0x71, 0xcb, 0xec, 0x6f, +0xcd, 0xee, 0xa6, 0xcc, 0x65, 0x76, 0xcd, 0xec, +0xa5, 0xc1, 0xe4, 0xdb, 0xbc, 0x7e, 0x7a, 0xce, +0xec, 0xdb, 0xbd, 0x89, 0xdb, 0xbe, 0x80, 0xbc, +0xbd, 0xec, 0x7b, 0xd1, 0xef, 0xdd, 0xc1, 0x82, +0x83, 0xd1, 0xed, 0x84, 0xd1, 0xee, 0xdd, 0xc3, +0x83, 0xc0, 0xc1, 0xee, 0x84, 0xd3, 0xf0, 0xac, +0xd6, 0x6d, 0xde, 0xc5, 0x85, 0x8b, 0xd4, 0xee, +0xdf, 0xc7, 0x87, 0x91, 0xd5, 0xee, 0xe0, 0xc8, +0x88, 0x92, 0xd5, 0xef, 0xae, 0xda, 0x71, 0xc6, +0xc7, 0xef, 0xe0, 0xca, 0x89, 0x94, 0xd8, 0xf0, +0xe1, 0xcc, 0x8a, 0x97, 0xd9, 0xf1, 0xe2, 0xce, +0x8c, 0xe3, 0xcc, 0x9e, 0xb2, 0xe0, 0x76, 0xad, +0xd6, 0xe9, 0xcc, 0xcd, 0xf1, 0xe5, 0xce, 0xa0, +0xe3, 0xd1, 0x8e, 0xe7, 0xda, 0x2b, 0xcd, 0xce, +0xf2, 0xe6, 0xd1, 0xa1, 0xa3, 0xdd, 0xf2, 0xe4, +0xd4, 0x91, 0xe6, 0xd3, 0xa4, 0xf2, 0xdc, 0x2a, +0xe7, 0xd4, 0xa4, 0xb9, 0xdb, 0xec, 0xb7, 0xe7, +0x7c, 0xad, 0xdf, 0xf3, 0xd4, 0xd4, 0xf3, 0xae, +0xe0, 0xf3, 0xe6, 0xd9, 0x95, 0xe8, 0xd7, 0xa6, +0xff, 0xde, 0x29, 0xe9, 0xd8, 0xa7, 0xbe, 0xde, +0xed, 0xb9, 0xeb, 0x7f, 0xe7, 0xdc, 0x97, 0xc0, +0xdf, 0xee, 0xe9, 0xda, 0xa8, 0xc2, 0xe0, 0xee, +0xe8, 0xde, 0x98, 0xeb, 0xda, 0xb7, 0xea, 0xdc, +0xaa, 0xed, 0xe3, 0x60, 0xef, 0xe3, 0x5f, 0xc5, +0xe1, 0xef, 0xea, 0xdd, 0xac, 0xbc, 0xf0, 0x84, +0xf3, 0xe4, 0x5f, 0xe9, 0xe1, 0x9b, 0xec, 0xdd, +0xba, 0xc7, 0xe3, 0xf0, 0xc8, 0xe3, 0xf0, 0xca, +0xe3, 0xf0, 0xec, 0xe0, 0xad, 0xcb, 0xe4, 0xf1, +0xde, 0xde, 0xf6, 0xf9, 0xe6, 0x5f, 0xcd, 0xe5, +0xf2, 0xec, 0xe3, 0xb0, 0xff, 0xe6, 0x5f, 0xee, +0xe2, 0xbd, 0xed, 0xe5, 0xb1, 0xd1, 0xe7, 0xf2, +0xee, 0xe6, 0xb2, 0xd3, 0xe8, 0xf3, 0xef, 0xe5, +0xbf, 0xf2, 0xea, 0x87, 0xd4, 0xe9, 0xf3, 0xd4, +0xe9, 0xf4, 0xd6, 0xe9, 0xf4, 0xf0, 0xe7, 0xc1, +0xef, 0xe9, 0xb4, 0xd7, 0xea, 0xf5, 0xf1, 0xe9, +0xc3, 0xfe, 0xec, 0x86, 0xf2, 0xed, 0xc6, 0xe1, +0xef, 0xf7, 0x5e, 0xd1, 0xb4, 0x75, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, +0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, +0x00, 0x00, 0x02, 0x8c, 0x49, 0x44, 0x41, 0x54, +0x48, 0xc7, 0xed, 0x94, 0xeb, 0x53, 0x12, 0x51, +0x18, 0x87, 0x5d, 0x76, 0x2b, 0xb2, 0xed, 0xcd, +0xca, 0x4a, 0xbb, 0x59, 0xd2, 0xdd, 0xa0, 0x28, +0x92, 0x12, 0x91, 0x8a, 0x48, 0x22, 0xa0, 0x8d, +0x8b, 0x56, 0x2c, 0x18, 0x72, 0x17, 0x01, 0x15, +0x43, 0x16, 0x5c, 0xc1, 0x0b, 0x02, 0xfe, 0xd5, +0xed, 0x61, 0x2f, 0xb2, 0x8b, 0xec, 0xe4, 0x34, +0xd3, 0xf4, 0xc1, 0xf7, 0xc3, 0xd9, 0x99, 0xb3, +0xfb, 0xcc, 0x6f, 0x9e, 0x73, 0x7e, 0xb3, 0x03, +0x03, 0x27, 0xf3, 0x4f, 0x66, 0x90, 0x40, 0x33, +0xd8, 0xb3, 0x7f, 0xa7, 0xb3, 0x2f, 0x5b, 0xc5, +0x57, 0xc4, 0x87, 0x67, 0xaf, 0xa6, 0xbf, 0x11, +0x3d, 0x08, 0xf1, 0x64, 0x64, 0x74, 0xf4, 0x25, +0xf1, 0x66, 0xfc, 0xfe, 0xa3, 0x8f, 0xc4, 0xd7, +0xc9, 0xe9, 0x99, 0x1f, 0xd2, 0x37, 0xc4, 0xe3, +0xeb, 0x37, 0xef, 0xbe, 0x3d, 0x02, 0x19, 0xd1, +0x6a, 0xb5, 0x37, 0x88, 0xb1, 0x4b, 0xc3, 0xc3, +0x4f, 0x89, 0xc9, 0xb1, 0xf1, 0x7b, 0x33, 0xc4, +0x5f, 0xa4, 0xf4, 0x73, 0x39, 0xdb, 0xd9, 0xe7, +0xd7, 0x8b, 0xfc, 0x2a, 0xbe, 0xd2, 0x7c, 0x7e, +0xfd, 0xfe, 0xcb, 0x2f, 0xcd, 0xe1, 0xb7, 0x7a, +0x92, 0xd4, 0x73, 0x0f, 0xa8, 0xa7, 0xd3, 0xe9, +0x3a, 0xb4, 0x1b, 0x8d, 0x46, 0x1b, 0xda, 0x2c, +0xcb, 0xb6, 0x41, 0x42, 0x5e, 0x9c, 0xc7, 0x2e, +0x7f, 0xef, 0x42, 0xc8, 0x83, 0x03, 0x12, 0x21, +0x69, 0xaf, 0xd7, 0x9b, 0x86, 0x46, 0x3e, 0x9f, +0x6f, 0x00, 0x9b, 0x48, 0x44, 0xab, 0x5d, 0x08, +0xf6, 0x10, 0x93, 0x21, 0xfb, 0xfb, 0x0a, 0x84, +0x05, 0x36, 0x1a, 0x8d, 0x96, 0x55, 0x52, 0x76, +0x77, 0x65, 0x48, 0x22, 0xc1, 0x42, 0x35, 0x1a, +0x0a, 0x75, 0x21, 0x4a, 0x17, 0x11, 0x11, 0x5c, +0x3a, 0x16, 0xcd, 0x72, 0xb9, 0xbc, 0x27, 0x21, +0x43, 0x1a, 0x34, 0xa7, 0xf1, 0x5b, 0x0a, 0xe4, +0x1a, 0xa0, 0xe1, 0xd7, 0xe7, 0xfc, 0x2a, 0x4b, +0xb9, 0x8a, 0xeb, 0x70, 0x09, 0xd9, 0xd9, 0x91, +0xa5, 0x54, 0xab, 0x4d, 0x68, 0x16, 0x8b, 0xc5, +0xbd, 0x2e, 0x97, 0xdb, 0xd8, 0x05, 0x5c, 0xa7, +0xc3, 0xc5, 0x21, 0xb7, 0xb6, 0x48, 0xf4, 0xbc, +0x82, 0x79, 0xb1, 0xb4, 0x60, 0x51, 0xf4, 0xf9, +0x7c, 0x59, 0x19, 0xc2, 0x11, 0x68, 0x1e, 0x4c, +0x4c, 0x4c, 0xbd, 0xfb, 0x44, 0x6e, 0x6e, 0x92, +0xcb, 0xdc, 0xe0, 0x5e, 0x8c, 0xd3, 0xaf, 0x86, +0x42, 0xa1, 0xe2, 0x11, 0x88, 0x3c, 0x85, 0x43, +0xc4, 0x94, 0x0c, 0x94, 0x05, 0xc4, 0xe3, 0x49, +0x41, 0x7f, 0x17, 0x0e, 0xe1, 0x5d, 0x32, 0x99, +0xba, 0x60, 0x51, 0xcb, 0xa6, 0x52, 0x35, 0xc5, +0x89, 0x9d, 0xc1, 0xcf, 0x49, 0xc8, 0xc6, 0xc6, +0x9f, 0x9c, 0x98, 0xec, 0x5e, 0x78, 0x04, 0xea, +0xb9, 0x5c, 0xae, 0x0e, 0x7b, 0xc5, 0x6c, 0xb6, +0x06, 0xb5, 0x54, 0x2c, 0x56, 0x51, 0xb9, 0x7d, +0x01, 0xc9, 0x05, 0x02, 0x81, 0x9c, 0x60, 0x11, +0x73, 0x38, 0x1c, 0xb4, 0x4a, 0xc7, 0xd6, 0xd7, +0x25, 0xa4, 0x04, 0x59, 0x0f, 0x8f, 0xd8, 0xed, +0xb4, 0x4a, 0xca, 0xda, 0x9a, 0x84, 0x30, 0x90, +0xf2, 0xcc, 0xce, 0xc6, 0x20, 0x62, 0xb7, 0xdb, +0x82, 0x2a, 0x1d, 0x5b, 0x5d, 0xed, 0x20, 0xad, +0x52, 0xa9, 0xd4, 0x82, 0x5a, 0x0c, 0x59, 0x54, +0x68, 0x9a, 0x2e, 0xa8, 0x74, 0x6c, 0x65, 0xe5, +0xd8, 0x1d, 0x5b, 0x5a, 0x12, 0x52, 0x18, 0xa6, +0x05, 0x95, 0x48, 0x84, 0xae, 0x40, 0x21, 0x18, +0xf4, 0x17, 0xfa, 0xde, 0xfe, 0x29, 0x84, 0xf0, +0xb7, 0x1f, 0xc6, 0x18, 0xce, 0xc2, 0xc6, 0x59, +0x04, 0x2d, 0x16, 0x33, 0xd5, 0xb7, 0x63, 0x53, +0x08, 0x99, 0x9f, 0xff, 0xb9, 0x8c, 0x87, 0xb1, +0x30, 0x03, 0xb4, 0xcd, 0x66, 0x0d, 0x82, 0xdf, +0x6c, 0x56, 0x20, 0xf2, 0x8e, 0xc5, 0xe3, 0x5d, +0x29, 0xb4, 0xd5, 0x6a, 0x41, 0x88, 0xc9, 0x44, +0xa9, 0x74, 0x8c, 0x43, 0x3a, 0x2e, 0x0c, 0x72, +0xe1, 0x2d, 0x0a, 0x14, 0x45, 0x25, 0x55, 0x3a, +0xb6, 0xb8, 0x78, 0xec, 0x8e, 0xf1, 0x88, 0x98, +0xe2, 0xa7, 0xa8, 0x02, 0x24, 0xdd, 0x6e, 0x77, +0xb2, 0xdf, 0xed, 0x73, 0x3f, 0xbe, 0xb9, 0x39, +0xf4, 0xf3, 0x03, 0x26, 0x1c, 0xe6, 0xf4, 0x79, +0x0b, 0xb7, 0xd1, 0x60, 0x70, 0xf6, 0xeb, 0x18, +0xb9, 0xbd, 0xe0, 0x72, 0x2d, 0x6c, 0x93, 0x22, +0x42, 0x99, 0x4c, 0x26, 0x37, 0xb8, 0x0d, 0x72, +0x44, 0x91, 0x12, 0x77, 0xb9, 0xe2, 0x87, 0x29, +0x94, 0xc9, 0x68, 0xec, 0x41, 0x14, 0x2e, 0x7a, +0xd4, 0x31, 0xbd, 0xe4, 0xc2, 0x5b, 0x24, 0x9d, +0x4e, 0xa7, 0xf2, 0xc4, 0x86, 0x7a, 0x7e, 0xe3, +0x2a, 0x27, 0x76, 0x32, 0xff, 0xdf, 0xfc, 0x06, +0x5f, 0x84, 0xe3, 0xbd, 0x3b, 0x56, 0xfe, 0x17, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_index_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_index_png = new wxImage(); + if (!img_ex_bmp_index_png || !img_ex_bmp_index_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_index_pngIS(ex_bmp_index_png_data, sizeof(ex_bmp_index_png_data)); + img_ex_bmp_index_png->LoadFile(img_ex_bmp_index_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_index_png; +} +#define ex_bmp_index_png_img ex_bmp_index_png_img() + +static wxBitmap *ex_bmp_index_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_index_png; + if (!bmp_ex_bmp_index_png || !bmp_ex_bmp_index_png->IsOk()) + bmp_ex_bmp_index_png = new wxBitmap(*ex_bmp_index_png_img); + return bmp_ex_bmp_index_png; +} +#define ex_bmp_index_png_bmp ex_bmp_index_png_bmp() + +static wxIcon *ex_bmp_index_png_ico() +{ + static wxIcon *ico_ex_bmp_index_png; + if (!ico_ex_bmp_index_png || !ico_ex_bmp_index_png->IsOk()) + { + ico_ex_bmp_index_png = new wxIcon(); + ico_ex_bmp_index_png->CopyFromBitmap(*ex_bmp_index_png_bmp); + } + return ico_ex_bmp_index_png; +} +#define ex_bmp_index_png_ico ex_bmp_index_png_ico() + +#endif // EX_BMP_INDEX_PNG_H diff --git a/include/images/ex_bmp_or.png b/include/images/ex_bmp_or.png new file mode 100644 index 0000000..c22fc31 Binary files /dev/null and b/include/images/ex_bmp_or.png differ diff --git a/include/images/ex_bmp_or.pngc b/include/images/ex_bmp_or.pngc new file mode 100644 index 0000000..63ab5cc --- /dev/null +++ b/include/images/ex_bmp_or.pngc @@ -0,0 +1,130 @@ +#ifndef EX_BMP_OR_PNG_H +#define EX_BMP_OR_PNG_H + +static const unsigned char ex_bmp_or_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x00, 0xff, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, +0x58, 0x58, 0x66, 0x6b, 0xd1, 0x36, 0x88, 0xc1, +0x64, 0x95, 0xd0, 0x8d, 0x8e, 0xbf, 0xc1, 0x8f, +0x36, 0x8f, 0x92, 0xdd, 0x7a, 0x9e, 0xa9, 0x9a, +0x9a, 0x9a, 0x9b, 0x9c, 0xc4, 0xb9, 0xa7, 0x72, +0x4e, 0xbe, 0xe6, 0xbb, 0xaa, 0x73, 0xbb, 0xac, +0x74, 0xbb, 0xad, 0x76, 0x5a, 0xc1, 0xe7, 0xbc, +0xb0, 0x77, 0xbd, 0xb1, 0x79, 0xab, 0xac, 0xe8, +0xbe, 0xb2, 0x7a, 0x89, 0xb9, 0xdb, 0x64, 0xc5, +0xe8, 0xb3, 0xb4, 0xea, 0xba, 0xba, 0xba, 0x71, +0xcb, 0xec, 0xda, 0xbb, 0x7e, 0x7a, 0xce, 0xec, +0xdb, 0xbd, 0x89, 0xdc, 0xbe, 0x80, 0xbc, 0xbd, +0xec, 0xbc, 0xbd, 0xed, 0xdd, 0xc1, 0x82, 0x83, +0xd1, 0xed, 0xdd, 0xc2, 0x83, 0xc0, 0xc1, 0xee, +0x8b, 0xd4, 0xee, 0xdf, 0xc6, 0x86, 0xdf, 0xc8, +0x87, 0x92, 0xd5, 0xef, 0xc6, 0xc7, 0xef, 0xe0, +0xca, 0x89, 0x94, 0xd8, 0xf0, 0xe3, 0xcb, 0x9e, +0xe3, 0xcc, 0x9e, 0xe4, 0xcd, 0x9e, 0xe2, 0xd0, +0x8d, 0xe4, 0xce, 0x9f, 0xcc, 0xcd, 0xf1, 0xcd, +0xce, 0xf2, 0xd1, 0xd1, 0xd1, 0xe5, 0xd0, 0xa1, +0xe6, 0xd1, 0xa2, 0xa6, 0xde, 0xf2, 0xe5, 0xd6, +0x93, 0xe6, 0xd4, 0xa4, 0xe7, 0xd5, 0xa5, 0xad, +0xdf, 0xf3, 0xd4, 0xd4, 0xf3, 0xe8, 0xd7, 0xa6, +0xe8, 0xd7, 0xa7, 0xea, 0xd8, 0xb6, 0xe9, 0xda, +0xa8, 0xe9, 0xda, 0xa9, 0xe9, 0xdc, 0xaa, 0xea, +0xdc, 0xaa, 0xeb, 0xdb, 0xb8, 0xeb, 0xde, 0xac, +0xec, 0xdd, 0xb9, 0xec, 0xe0, 0xad, 0xec, 0xe0, +0xae, 0xed, 0xdf, 0xbb, 0xde, 0xde, 0xf6, 0xec, +0xe2, 0xaf, 0xec, 0xe3, 0xb0, 0xef, 0xe4, 0xbf, +0xe4, 0xe4, 0xe4, 0xf0, 0xe6, 0xc0, 0xf0, 0xe7, +0xc1, 0xf1, 0xeb, 0xc4, 0xec, 0xec, 0xec, 0xef, +0xef, 0xef, 0xf4, 0xf4, 0xf4, 0xff, 0xff, 0xff, +0x89, 0xb7, 0xf1, 0xf7, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x01, 0x47, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, +0xed, 0xd4, 0x6d, 0x4f, 0x82, 0x60, 0x14, 0x06, +0x60, 0x8e, 0x60, 0xa8, 0xbd, 0x67, 0x49, 0x6a, +0x56, 0x56, 0x28, 0x15, 0x12, 0x15, 0x14, 0x95, +0x08, 0x41, 0x12, 0x85, 0x2f, 0xbd, 0xfd, 0xff, +0xdf, 0x92, 0xb0, 0x58, 0x0f, 0xf3, 0x61, 0x74, +0xb6, 0x6c, 0x7d, 0xf0, 0xfe, 0xc4, 0x76, 0x76, +0xed, 0xec, 0xdc, 0x0a, 0x0c, 0x33, 0xcf, 0x5f, +0x26, 0xcf, 0x85, 0xc9, 0x4f, 0x0f, 0x2a, 0xd1, +0xa0, 0x42, 0x21, 0xdc, 0xe9, 0xce, 0x81, 0x78, +0xcb, 0x51, 0x06, 0x57, 0xa2, 0x24, 0xd1, 0x06, +0x0c, 0x57, 0x5b, 0x5e, 0x17, 0x24, 0x1a, 0x11, +0x05, 0xa1, 0x26, 0x71, 0xbf, 0xb3, 0x25, 0x79, +0xcb, 0xc7, 0x24, 0x5f, 0x8f, 0xc5, 0x68, 0x50, +0xa4, 0x10, 0xf6, 0xfc, 0xe8, 0xf8, 0xe2, 0x89, +0xfd, 0x16, 0xb1, 0xe1, 0x5f, 0x82, 0x20, 0x18, +0xf3, 0x34, 0xb2, 0xb7, 0x09, 0xfb, 0x77, 0x31, +0x79, 0x2b, 0x95, 0x86, 0x31, 0x09, 0xb6, 0xa0, +0xec, 0x65, 0x93, 0x61, 0x2e, 0x77, 0x19, 0x93, +0x67, 0xb8, 0x06, 0x24, 0x79, 0x2c, 0xc3, 0x06, +0x9d, 0x24, 0x6e, 0x21, 0xc9, 0xd8, 0xf3, 0x1e, +0x46, 0x34, 0x52, 0x60, 0xc3, 0x14, 0xa6, 0x49, +0x83, 0x0f, 0xd3, 0x40, 0x6d, 0x19, 0x39, 0x8e, +0x33, 0xa0, 0xdf, 0xb2, 0x00, 0x8b, 0xd4, 0x5b, +0x9c, 0x35, 0x58, 0xb5, 0xe9, 0x04, 0xb6, 0x81, +0x4e, 0xe0, 0x0c, 0x6c, 0xdc, 0x96, 0xfb, 0x15, +0x58, 0xb2, 0x70, 0x8d, 0x0d, 0x6c, 0xcb, 0xf2, +0x67, 0xde, 0x98, 0x6f, 0x9a, 0x5d, 0x1f, 0x77, +0x8b, 0x79, 0x02, 0x6d, 0x03, 0xd7, 0x58, 0xb7, +0x0d, 0x2d, 0x03, 0xb7, 0xe5, 0xa6, 0x95, 0x46, +0xd2, 0x6f, 0x31, 0x0c, 0xa3, 0x3f, 0xf3, 0xc6, +0xfa, 0xba, 0xae, 0xbb, 0xb8, 0xf7, 0x45, 0x3f, +0x84, 0xa6, 0x86, 0x24, 0x4d, 0xd8, 0x45, 0x12, +0x6d, 0x42, 0x54, 0x5c, 0x63, 0xae, 0xa6, 0xaa, +0x6e, 0x76, 0x63, 0xef, 0xd5, 0xea, 0x2b, 0xae, +0x31, 0xf2, 0xd3, 0xc7, 0xbb, 0xaa, 0xa2, 0xf4, +0x32, 0x7f, 0xfd, 0xd0, 0xc4, 0x4f, 0xbc, 0x52, +0x87, 0x7a, 0x27, 0xf3, 0x3f, 0x46, 0x26, 0x22, +0xf2, 0x0f, 0xb6, 0x10, 0xa4, 0x93, 0x4a, 0x12, +0xb7, 0x90, 0xa4, 0x27, 0xcb, 0x72, 0x2f, 0xb3, +0x31, 0x32, 0xe9, 0x8d, 0xcd, 0xf3, 0x8f, 0xf2, +0x09, 0xf0, 0x75, 0x51, 0xc9, 0x2e, 0xf7, 0xb2, +0x59, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_bmp_or_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_bmp_or_png = new wxImage(); + if (!img_ex_bmp_or_png || !img_ex_bmp_or_png->IsOk()) + { + wxMemoryInputStream img_ex_bmp_or_pngIS(ex_bmp_or_png_data, sizeof(ex_bmp_or_png_data)); + img_ex_bmp_or_png->LoadFile(img_ex_bmp_or_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_bmp_or_png; +} +#define ex_bmp_or_png_img ex_bmp_or_png_img() + +static wxBitmap *ex_bmp_or_png_bmp() +{ + static wxBitmap *bmp_ex_bmp_or_png; + if (!bmp_ex_bmp_or_png || !bmp_ex_bmp_or_png->IsOk()) + bmp_ex_bmp_or_png = new wxBitmap(*ex_bmp_or_png_img); + return bmp_ex_bmp_or_png; +} +#define ex_bmp_or_png_bmp ex_bmp_or_png_bmp() + +static wxIcon *ex_bmp_or_png_ico() +{ + static wxIcon *ico_ex_bmp_or_png; + if (!ico_ex_bmp_or_png || !ico_ex_bmp_or_png->IsOk()) + { + ico_ex_bmp_or_png = new wxIcon(); + ico_ex_bmp_or_png->CopyFromBitmap(*ex_bmp_or_png_bmp); + } + return ico_ex_bmp_or_png; +} +#define ex_bmp_or_png_ico ex_bmp_or_png_ico() + +#endif // EX_BMP_OR_PNG_H diff --git a/include/images/ex_broadcast_motion.png b/include/images/ex_broadcast_motion.png new file mode 100644 index 0000000..e99f574 Binary files /dev/null and b/include/images/ex_broadcast_motion.png differ diff --git a/include/images/ex_broadcast_motion.pngc b/include/images/ex_broadcast_motion.pngc new file mode 100644 index 0000000..58abe94 --- /dev/null +++ b/include/images/ex_broadcast_motion.pngc @@ -0,0 +1,86 @@ +#ifndef EX_BROADCAST_MOTION_PNG_H +#define EX_BROADCAST_MOTION_PNG_H + +static const unsigned char ex_broadcast_motion_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x02, 0x03, 0x00, 0x00, 0x00, 0x63, 0x51, 0x60, +0x22, 0x00, 0x00, 0x00, 0x09, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, +0x45, 0x46, 0xe3, 0x0e, 0x85, 0xbc, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x7c, 0x49, 0x44, 0x41, 0x54, +0x28, 0xcf, 0xb5, 0x91, 0x3b, 0x0e, 0xc0, 0x20, +0x0c, 0x43, 0x61, 0xc8, 0xde, 0x85, 0xfb, 0x70, +0x04, 0x06, 0x2c, 0xf5, 0xfe, 0x27, 0x69, 0x11, +0x2d, 0xb5, 0xa3, 0x74, 0xaa, 0x9a, 0xed, 0x91, +0x9f, 0x1d, 0x52, 0xfa, 0x2f, 0x72, 0x17, 0x42, +0x15, 0x02, 0x27, 0x0b, 0x9a, 0xe4, 0x20, 0xd0, +0x18, 0x3a, 0x03, 0x76, 0x2e, 0x2b, 0x95, 0x7b, +0xec, 0x4a, 0x19, 0x78, 0xb8, 0x31, 0x24, 0x63, +0x88, 0x4d, 0xb0, 0x6a, 0x57, 0x6f, 0xa1, 0x41, +0xc3, 0x8c, 0x26, 0x04, 0x25, 0x9e, 0x8a, 0x1e, +0x4c, 0x09, 0x37, 0xdc, 0xfe, 0xe4, 0xd5, 0x39, +0x9a, 0x8b, 0xb7, 0x75, 0xd8, 0x81, 0xab, 0xbe, +0x8c, 0xcd, 0x4f, 0xf7, 0x10, 0x42, 0xff, 0xe0, +0x84, 0x29, 0x65, 0x39, 0xe3, 0x89, 0x4a, 0x2c, +0xc9, 0x2b, 0x7a, 0xbf, 0xe7, 0xa7, 0x38, 0x00, +0xca, 0x05, 0x24, 0xf5, 0x06, 0xe1, 0xce, 0x9c, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_broadcast_motion_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_broadcast_motion_png = new wxImage(); + if (!img_ex_broadcast_motion_png || !img_ex_broadcast_motion_png->IsOk()) + { + wxMemoryInputStream img_ex_broadcast_motion_pngIS(ex_broadcast_motion_png_data, sizeof(ex_broadcast_motion_png_data)); + img_ex_broadcast_motion_png->LoadFile(img_ex_broadcast_motion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_broadcast_motion_png; +} +#define ex_broadcast_motion_png_img ex_broadcast_motion_png_img() + +static wxBitmap *ex_broadcast_motion_png_bmp() +{ + static wxBitmap *bmp_ex_broadcast_motion_png; + if (!bmp_ex_broadcast_motion_png || !bmp_ex_broadcast_motion_png->IsOk()) + bmp_ex_broadcast_motion_png = new wxBitmap(*ex_broadcast_motion_png_img); + return bmp_ex_broadcast_motion_png; +} +#define ex_broadcast_motion_png_bmp ex_broadcast_motion_png_bmp() + +static wxIcon *ex_broadcast_motion_png_ico() +{ + static wxIcon *ico_ex_broadcast_motion_png; + if (!ico_ex_broadcast_motion_png || !ico_ex_broadcast_motion_png->IsOk()) + { + ico_ex_broadcast_motion_png = new wxIcon(); + ico_ex_broadcast_motion_png->CopyFromBitmap(*ex_broadcast_motion_png_bmp); + } + return ico_ex_broadcast_motion_png; +} +#define ex_broadcast_motion_png_ico ex_broadcast_motion_png_ico() + +#endif // EX_BROADCAST_MOTION_PNG_H diff --git a/include/images/ex_cte_scan.png b/include/images/ex_cte_scan.png new file mode 100644 index 0000000..7e1d779 Binary files /dev/null and b/include/images/ex_cte_scan.png differ diff --git a/include/images/ex_cte_scan.pngc b/include/images/ex_cte_scan.pngc new file mode 100644 index 0000000..1e551d0 --- /dev/null +++ b/include/images/ex_cte_scan.pngc @@ -0,0 +1,289 @@ +#ifndef EX_CTE_SCAN_PNG_H +#define EX_CTE_SCAN_PNG_H + +static const unsigned char ex_cte_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbd, 0xe9, +0x45, 0xbe, 0xe9, 0x75, 0xce, 0xef, 0x79, 0xd0, +0xef, 0x51, 0xc2, 0xea, 0x54, 0xc2, 0xea, 0x57, +0xc3, 0xea, 0x83, 0xd3, 0xf0, 0x89, 0xd5, 0xf0, +0x66, 0xc8, 0xec, 0x6a, 0xc9, 0xec, 0x6e, 0xca, +0xec, 0x94, 0xd8, 0xf1, 0x99, 0xda, 0xf1, 0x7c, +0xce, 0xed, 0x80, 0xd0, 0xed, 0x83, 0xd1, 0xed, +0xa4, 0xdd, 0xf1, 0xa8, 0xde, 0xf2, 0x8e, 0xd4, +0xee, 0x91, 0xd5, 0xee, 0x93, 0xd6, 0xef, 0xaf, +0xe1, 0xf3, 0x04, 0xa7, 0xe1, 0x08, 0xa8, 0xe2, +0x48, 0xbf, 0xe9, 0x4d, 0xc1, 0xe9, 0x17, 0xad, +0xe3, 0x1d, 0xaf, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, +0xc7, 0xeb, 0x33, 0xb5, 0xe5, 0x38, 0xb7, 0xe5, +0x3d, 0xb8, 0xe5, 0x71, 0xcb, 0xec, 0x78, 0xce, +0xec, 0x50, 0xbe, 0xe7, 0x55, 0xc0, 0xe7, 0x59, +0xc1, 0xe7, 0x86, 0xd1, 0xed, 0x6b, 0xc7, 0xe8, +0x6f, 0xc8, 0xe9, 0x95, 0xd7, 0xef, 0x58, 0xaa, +0xab, 0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0x36, +0xc1, 0x3d, 0xd7, 0xf4, 0xc9, 0xca, 0xf0, 0xb7, +0xc9, 0xf0, 0xb6, 0xc8, 0xef, 0xb6, 0xd4, 0xf3, +0xc8, 0xc6, 0xef, 0xb6, 0xc5, 0xef, 0xb6, 0xd2, +0xf3, 0xc8, 0xd2, 0xf2, 0xc7, 0xc2, 0xee, 0xb5, +0xc1, 0xee, 0xb5, 0xd0, 0xf1, 0xc7, 0xce, 0xf1, +0xc7, 0xbe, 0xec, 0xb4, 0xbd, 0xec, 0xb4, 0xbc, +0xec, 0xb3, 0xcc, 0xf1, 0xc6, 0xe1, 0xef, 0xf7, +0xb8, 0xeb, 0x9f, 0xb5, 0xea, 0x9e, 0xc7, 0xef, +0xb6, 0xb2, 0xe9, 0x9d, 0xb1, 0xe9, 0x9d, 0xc3, +0xef, 0xb5, 0xad, 0xe8, 0x9c, 0xab, 0xe7, 0x9c, +0xaa, 0xe7, 0x9b, 0xbf, 0xed, 0xb4, 0xa6, 0xe6, +0x9a, 0xa5, 0xe6, 0x9a, 0xa4, 0xe5, 0x9a, 0xba, +0xec, 0xb3, 0xd7, 0xea, 0xf5, 0xb4, 0xea, 0x9e, +0xb3, 0xea, 0x9d, 0xaf, 0xe9, 0x9d, 0xaf, 0xe8, +0x9c, 0xa9, 0xe7, 0x9b, 0xa3, 0xe5, 0x9a, 0xa2, +0xe5, 0x99, 0xb9, 0xec, 0xb3, 0xd6, 0xe9, 0xf4, +0xc4, 0xef, 0xb6, 0xae, 0xe8, 0x9c, 0xa8, 0xe6, +0x9b, 0xa7, 0xe6, 0x9b, 0xbb, 0xec, 0xb3, 0xa0, +0xe4, 0x99, 0xb7, 0xeb, 0xb3, 0xd1, 0xf2, 0xc7, +0xc0, 0xed, 0xb5, 0xcc, 0xf0, 0xc6, 0xca, 0xf0, +0xc5, 0xb8, 0xeb, 0xb3, 0xc8, 0xef, 0xc5, 0x89, +0xdb, 0x8d, 0xd4, 0xe9, 0xf4, 0xc3, 0xee, 0xb5, +0xbe, 0xed, 0xb4, 0xcd, 0xf1, 0xc7, 0xc9, 0xf0, +0xc5, 0xb6, 0xea, 0xb2, 0xb5, 0xea, 0xb2, 0xb4, +0xea, 0xb2, 0xc5, 0xef, 0xc4, 0xd3, 0xe8, 0xf3, +0xc3, 0xef, 0xb6, 0xa7, 0xe6, 0x9a, 0x9c, 0xe3, +0x98, 0x9a, 0xe3, 0x98, 0x99, 0xe2, 0x97, 0xb2, +0xe9, 0xb1, 0xd2, 0xe7, 0xf3, 0x9e, 0xe4, 0x98, +0x9a, 0xe2, 0x97, 0x97, 0xe2, 0x97, 0xb0, 0xe9, +0xb1, 0xaf, 0xe9, 0x9c, 0x8d, 0xa8, 0x85, 0x51, +0x5d, 0x4e, 0x3a, 0x3a, 0x3a, 0x54, 0x5e, 0x52, +0x38, 0x72, 0x3b, 0x3d, 0x44, 0x3d, 0x6e, 0x83, +0x6c, 0xac, 0xdf, 0xaa, 0x96, 0xe1, 0x96, 0xaf, +0xe9, 0xb0, 0xd0, 0xe6, 0xf2, 0x7c, 0x7c, 0x7c, +0xd8, 0xd8, 0xd8, 0xff, 0xff, 0xff, 0x96, 0x96, +0x96, 0xf2, 0xf2, 0xf2, 0xa3, 0xa3, 0xa3, 0x83, +0x9a, 0x84, 0xb0, 0xe9, 0xb0, 0xc1, 0xed, 0xc3, +0xce, 0xe6, 0xf2, 0x37, 0x96, 0x3c, 0x6f, 0x6f, +0x6f, 0xca, 0xca, 0xca, 0x61, 0x61, 0x61, 0x5a, +0x7c, 0x5c, 0x36, 0xba, 0x3d, 0xce, 0xe5, 0xf2, +0x62, 0x6b, 0x60, 0x7e, 0x99, 0x7b, 0xab, 0xd6, +0xa4, 0x7e, 0x8f, 0x7b, 0x38, 0x83, 0x3c, 0xac, +0xcc, 0xa9, 0x56, 0x5e, 0x56, 0x38, 0x79, 0x3b, +0xc3, 0xee, 0xc4, 0xad, 0xe8, 0xb0, 0xac, 0xe8, +0xb0, 0xc0, 0xed, 0xc3, 0xcc, 0xe5, 0xf1, 0x81, +0xac, 0x7a, 0x9e, 0xc8, 0x9b, 0x52, 0x5d, 0x52, +0x96, 0xc5, 0x98, 0x91, 0xe0, 0x95, 0x90, 0xdf, +0x95, 0x8f, 0xdf, 0x95, 0xaa, 0xe7, 0xaf, 0xcb, +0xe4, 0xf1, 0xa8, 0xe7, 0x9b, 0x5d, 0x69, 0x5a, +0x71, 0x95, 0x6d, 0x94, 0xcf, 0x8d, 0x75, 0x8d, +0x72, 0x9d, 0xc7, 0x9a, 0x8d, 0xdf, 0x94, 0xa9, +0xe6, 0xaf, 0xca, 0xe3, 0xf0, 0x91, 0xb1, 0x8b, +0xa4, 0xde, 0xaa, 0x8c, 0xde, 0x94, 0x8b, 0xde, +0x94, 0xa7, 0xe6, 0xaf, 0xc8, 0xe3, 0xf0, 0xcb, +0xf0, 0xc6, 0x89, 0x89, 0x89, 0xe5, 0xe5, 0xe5, +0xbc, 0xec, 0xc2, 0xc7, 0xe3, 0xf0, 0x39, 0x4c, +0x3a, 0x39, 0x55, 0x3b, 0x6a, 0x9c, 0x6c, 0x38, +0x8d, 0x3c, 0x7f, 0xc7, 0x82, 0xc6, 0xe2, 0xef, +0xb3, 0xe9, 0xb1, 0xc4, 0xee, 0xc4, 0xae, 0xe8, +0xb0, 0xaa, 0xe7, 0xb0, 0xbd, 0xec, 0xc3, 0xbc, +0xec, 0xc3, 0xa6, 0xe6, 0xae, 0xa5, 0xe6, 0xae, +0xa4, 0xe6, 0xae, 0xbb, 0xec, 0xc2, 0xc5, 0xe1, +0xef, 0xb1, 0xe9, 0xb1, 0x92, 0xe0, 0x96, 0x88, +0xdd, 0x93, 0x86, 0xdd, 0x93, 0x85, 0xdc, 0x92, +0xa3, 0xe5, 0xad, 0xc3, 0xe0, 0xee, 0x89, 0xde, +0x93, 0x85, 0xdc, 0x93, 0x84, 0xdc, 0x92, 0xa2, +0xe5, 0xad, 0xc2, 0xe0, 0xef, 0xb6, 0xeb, 0xb2, +0x94, 0xe1, 0x96, 0xa4, 0xe5, 0xad, 0x82, 0xdc, +0x92, 0xa1, 0xe4, 0xad, 0xc2, 0xe0, 0xee, 0xae, +0xe9, 0xb0, 0xba, 0xeb, 0xc2, 0xb8, 0xeb, 0xc1, +0xc0, 0xdf, 0xee, 0xac, 0xe7, 0xb0, 0xab, 0xe7, +0xb0, 0xbe, 0xec, 0xc3, 0xa7, 0xe6, 0xae, 0xa0, +0xe4, 0xad, 0x9f, 0xe4, 0xad, 0xb6, 0xea, 0xc1, +0xb9, 0xdb, 0xec, 0x80, 0xdb, 0x91, 0x7e, 0xda, +0x91, 0x9e, 0xe3, 0xad, 0xd4, 0xe9, 0xf3, 0xbe, +0xde, 0xed, 0xad, 0xd6, 0xe9, 0x8d, 0xdf, 0x95, +0x8c, 0xdf, 0x94, 0x7d, 0xda, 0x91, 0xc8, 0xe3, +0xef, 0xe6, 0x81, 0x3e, 0x28, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x8e, 0x82, 0x05, 0xb3, 0x6f, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x03, 0xcd, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd4, +0x67, 0x54, 0x53, 0x67, 0x18, 0x07, 0x70, 0xbc, +0xce, 0xda, 0xba, 0xab, 0xd6, 0xaa, 0x75, 0xef, +0x99, 0x07, 0x02, 0x44, 0x83, 0x42, 0x94, 0xc4, +0x08, 0x06, 0x45, 0x51, 0x20, 0xa2, 0x10, 0x17, +0x68, 0xab, 0x0c, 0x35, 0xc6, 0xad, 0xd7, 0xa8, +0x41, 0x48, 0xc4, 0xe0, 0xc0, 0x8d, 0x23, 0xe0, +0x8a, 0x41, 0x5b, 0x47, 0x1c, 0x89, 0x03, 0x37, +0x05, 0xcb, 0x90, 0x80, 0xa0, 0xa2, 0x02, 0x2a, +0x8a, 0x0c, 0x43, 0x14, 0x8b, 0xbe, 0xf7, 0x05, +0x3c, 0xc9, 0x3d, 0xe1, 0x83, 0xe7, 0x78, 0x7a, +0xfa, 0xc1, 0xe7, 0xc3, 0x9b, 0x2f, 0xf9, 0x9d, +0x7f, 0xfe, 0xcf, 0x7d, 0x73, 0x6d, 0x6c, 0xbe, +0xcf, 0x7f, 0x3d, 0xf5, 0x08, 0x6a, 0xea, 0x3c, +0xad, 0x11, 0xa2, 0x7e, 0x83, 0x86, 0x0d, 0x1b, +0x11, 0x8d, 0x9b, 0xfc, 0xd0, 0xf4, 0x47, 0xe2, +0xa7, 0x66, 0xcd, 0x5b, 0xb4, 0x24, 0x5a, 0xb5, +0x6e, 0xf3, 0x73, 0x5b, 0xa2, 0x5d, 0xfb, 0x5f, +0x3a, 0xfc, 0x4a, 0x58, 0x25, 0x0d, 0x3a, 0x76, +0xec, 0xd4, 0x99, 0xf8, 0xad, 0x4b, 0xd7, 0xae, +0xdd, 0x88, 0xee, 0x3d, 0x7a, 0xf6, 0xea, 0x4d, +0xf4, 0xe9, 0xdb, 0xaf, 0xff, 0x00, 0xa2, 0xfd, +0xc0, 0x81, 0x83, 0x06, 0x13, 0xdf, 0x28, 0x65, +0x08, 0xfe, 0xcd, 0x75, 0x9e, 0x16, 0xdf, 0x1d, +0xca, 0x60, 0x0c, 0x45, 0x1f, 0x60, 0x6b, 0x67, +0x67, 0x67, 0x0b, 0xb6, 0x4c, 0xa6, 0xbd, 0x03, +0x38, 0x38, 0xb2, 0x58, 0xc3, 0x60, 0x38, 0x9b, +0xed, 0x34, 0x02, 0x46, 0x3a, 0xbb, 0x70, 0x46, +0x81, 0x05, 0x61, 0x8c, 0x1e, 0xcd, 0xa0, 0x88, +0x9d, 0xab, 0xab, 0x2b, 0x13, 0x98, 0x5c, 0x2e, +0x97, 0x07, 0xac, 0x31, 0x7c, 0xfe, 0x58, 0x60, +0xbb, 0xb9, 0x8f, 0x13, 0x80, 0x8b, 0xc7, 0xf8, +0x09, 0x9e, 0x34, 0x32, 0x71, 0xa2, 0x19, 0xb1, +0xe7, 0x4e, 0xf2, 0x72, 0x04, 0x16, 0x7f, 0xf2, +0x14, 0x36, 0x38, 0xb9, 0x8f, 0xf3, 0x76, 0x06, +0xce, 0x04, 0x1f, 0x5f, 0x21, 0x8d, 0x4c, 0x9d, +0x5a, 0x4b, 0xb8, 0xf6, 0xc0, 0x9b, 0xe4, 0x35, +0x86, 0x05, 0x7e, 0x53, 0xa6, 0xb9, 0x39, 0x81, +0xc0, 0x7b, 0xba, 0x3f, 0x07, 0x02, 0x7c, 0x7c, +0x45, 0x33, 0xac, 0x13, 0x5b, 0xa6, 0xfd, 0x97, +0x16, 0x33, 0xd9, 0x4e, 0xb3, 0x50, 0x0b, 0x17, +0x0e, 0x67, 0x36, 0xcc, 0x09, 0x0c, 0x9c, 0x11, +0x64, 0x95, 0xcc, 0x05, 0x6a, 0xea, 0x3c, 0x2d, +0xc9, 0xbc, 0x79, 0x38, 0xc5, 0x81, 0xc7, 0x73, +0x44, 0x29, 0x7e, 0xbf, 0xb3, 0x67, 0xc2, 0x08, +0x81, 0xe0, 0x8f, 0xf9, 0x30, 0x2a, 0xc0, 0x53, +0x38, 0x07, 0x16, 0x04, 0x87, 0x84, 0x86, 0xd1, +0x52, 0x16, 0x2e, 0xc4, 0x84, 0xe7, 0x45, 0xb5, +0x58, 0x34, 0xad, 0xa6, 0xc5, 0x62, 0x0e, 0x78, +0xfa, 0x8a, 0x50, 0x8b, 0x60, 0xf1, 0x12, 0xc9, +0x52, 0x1a, 0x59, 0xb6, 0x0c, 0x13, 0x47, 0xb4, +0x58, 0x3f, 0xb4, 0x58, 0x37, 0x77, 0x01, 0x38, +0xfb, 0x7b, 0x8c, 0x0f, 0x00, 0xa1, 0x48, 0xb4, +0x3c, 0x18, 0x42, 0x57, 0x48, 0x56, 0xae, 0xb2, +0x4e, 0x58, 0x7c, 0xfe, 0x6a, 0x36, 0xac, 0x59, +0x4b, 0x92, 0xeb, 0xa4, 0x24, 0x35, 0xeb, 0x37, +0x50, 0xa7, 0x74, 0xa3, 0x44, 0x26, 0x0b, 0xa7, +0x91, 0x4d, 0x9b, 0x30, 0x19, 0x46, 0xb5, 0x90, +0x46, 0x44, 0xca, 0xe5, 0x91, 0x0a, 0x39, 0x35, +0x9b, 0xa3, 0xa8, 0x53, 0xb1, 0x65, 0x95, 0x32, +0x3c, 0x9a, 0x46, 0xb6, 0x6e, 0xfd, 0xb2, 0xb1, +0x6d, 0xdb, 0xe5, 0x3b, 0x48, 0x32, 0x4a, 0x41, +0xc6, 0xc8, 0x23, 0xc9, 0xf5, 0x51, 0x72, 0x05, +0x49, 0xee, 0xdc, 0x65, 0x65, 0x63, 0xbb, 0x77, +0xe3, 0x14, 0xea, 0x59, 0xec, 0xd9, 0x21, 0x57, +0xec, 0xdd, 0xb7, 0x3f, 0xf6, 0x00, 0x22, 0x07, +0x0f, 0x61, 0x22, 0x3d, 0xac, 0x52, 0xc5, 0xc5, +0xd3, 0x52, 0x8e, 0x1c, 0xc1, 0x84, 0xba, 0x1e, +0xeb, 0x22, 0xe5, 0x11, 0x47, 0x7d, 0x84, 0x70, +0x0c, 0x91, 0xe3, 0x87, 0xf0, 0x0f, 0x8b, 0x39, +0xa1, 0x3e, 0xa9, 0x49, 0xa0, 0x91, 0x53, 0xa7, +0x30, 0x11, 0x78, 0x9f, 0xf6, 0xff, 0x13, 0xa5, +0xfc, 0x75, 0xe6, 0x6c, 0xec, 0xb9, 0x1a, 0x42, +0xa5, 0xc4, 0x69, 0x34, 0xe7, 0xb5, 0x34, 0x72, +0xe1, 0x42, 0x35, 0x99, 0xbe, 0xd8, 0xe3, 0x62, +0x44, 0x75, 0x97, 0xbd, 0x66, 0xe4, 0xd2, 0xf9, +0xcb, 0x3a, 0x3d, 0x8d, 0x5c, 0xb9, 0x82, 0xc9, +0x7c, 0x0e, 0x27, 0xe0, 0xaa, 0xf4, 0xda, 0x75, +0xb4, 0xb1, 0x98, 0xda, 0x2e, 0x78, 0x63, 0x5a, +0xad, 0x3e, 0x91, 0x46, 0x6e, 0xdc, 0x30, 0xbb, +0x63, 0xb1, 0x37, 0x49, 0xf2, 0xd6, 0x6d, 0x90, +0x92, 0xb7, 0xee, 0xdc, 0xc5, 0x8f, 0xc7, 0xea, +0xc6, 0xee, 0xdd, 0xc3, 0x29, 0xb3, 0x3d, 0x85, +0x81, 0x0b, 0x20, 0x28, 0x24, 0x34, 0x29, 0x0c, +0xfe, 0x56, 0x86, 0x27, 0x47, 0x43, 0x7c, 0x4a, +0x82, 0xf6, 0x3e, 0xfc, 0x93, 0x9a, 0x96, 0x9e, +0x41, 0x4b, 0x79, 0xf0, 0x00, 0x13, 0x74, 0x3d, +0x44, 0xf8, 0x7a, 0x48, 0x32, 0x21, 0xdc, 0x60, +0x50, 0xc7, 0x41, 0x0a, 0x6e, 0x91, 0x9a, 0x95, +0xfd, 0x30, 0x87, 0x46, 0x72, 0x73, 0x31, 0x09, +0x14, 0x2d, 0x17, 0x87, 0x40, 0x92, 0x64, 0xa5, +0x4c, 0x09, 0xc9, 0x6a, 0xb5, 0x26, 0x05, 0xb4, +0x3a, 0xdd, 0xa3, 0x54, 0x48, 0x7f, 0xfc, 0xf0, +0x49, 0x1e, 0x8d, 0x3c, 0x7d, 0x8a, 0xc9, 0x33, +0xb1, 0x58, 0x9c, 0x04, 0x99, 0x32, 0xd9, 0xf3, +0x64, 0x50, 0x9d, 0xd4, 0xa0, 0x67, 0xa1, 0x7f, +0x94, 0x95, 0x95, 0x06, 0xf9, 0x4f, 0x0a, 0x0a, +0x0a, 0x69, 0xe4, 0xc5, 0x0b, 0x4c, 0x82, 0x42, +0x93, 0x70, 0x8b, 0x97, 0xaa, 0xda, 0x16, 0x89, +0xa8, 0xc5, 0x2b, 0x28, 0xca, 0x2b, 0x2c, 0x2c, +0xa2, 0x91, 0xd7, 0xaf, 0xbf, 0xfa, 0x5f, 0x59, +0x4d, 0x20, 0x6c, 0x69, 0xa6, 0xf2, 0x30, 0x44, +0xab, 0xde, 0x14, 0xc7, 0xc3, 0x5b, 0xad, 0xbe, +0x24, 0x11, 0x32, 0xf2, 0x73, 0xf2, 0x8a, 0xa0, +0xa8, 0xb4, 0xb4, 0xac, 0xdc, 0x3c, 0x05, 0xbd, +0xf8, 0xde, 0xbd, 0xa3, 0x5e, 0x7e, 0xb8, 0x85, +0x0a, 0xaa, 0xaf, 0x07, 0xd5, 0x22, 0x1d, 0x72, +0x70, 0x8b, 0x52, 0xa3, 0xb1, 0xc2, 0x64, 0x4e, +0x18, 0xef, 0x3f, 0x54, 0x56, 0x7e, 0x78, 0xcf, +0xb0, 0x01, 0xe5, 0x73, 0x83, 0x41, 0x05, 0xc5, +0x1f, 0xff, 0xc5, 0x8b, 0xcd, 0xca, 0xce, 0x87, +0xbc, 0x82, 0x02, 0x63, 0x29, 0x94, 0x55, 0x54, +0x54, 0x99, 0x2c, 0x53, 0x72, 0x2b, 0x2b, 0x73, +0xa9, 0x94, 0x64, 0x83, 0x5a, 0x5d, 0x0c, 0x09, +0x97, 0x75, 0xba, 0x12, 0x48, 0xcb, 0x7e, 0x8c, +0x16, 0x5b, 0x68, 0x34, 0x1a, 0xcb, 0xc0, 0x54, +0x55, 0x65, 0x49, 0x90, 0xf9, 0xf4, 0x89, 0x7a, +0x29, 0x43, 0x74, 0x5c, 0x71, 0x4a, 0x3c, 0xdc, +0xd7, 0x97, 0xa4, 0x66, 0xc0, 0xab, 0x9a, 0x16, +0x65, 0xa8, 0x45, 0xb9, 0xc9, 0x64, 0x2a, 0xb7, +0xdc, 0x58, 0xcd, 0x6b, 0xfc, 0x6b, 0x36, 0xf6, +0x7d, 0xfe, 0x5f, 0xf3, 0x19, 0xf0, 0x45, 0xf7, +0x38, 0x1a, 0xa2, 0x14, 0xde, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_cte_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_cte_scan_png = new wxImage(); + if (!img_ex_cte_scan_png || !img_ex_cte_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_cte_scan_pngIS(ex_cte_scan_png_data, sizeof(ex_cte_scan_png_data)); + img_ex_cte_scan_png->LoadFile(img_ex_cte_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_cte_scan_png; +} +#define ex_cte_scan_png_img ex_cte_scan_png_img() + +static wxBitmap *ex_cte_scan_png_bmp() +{ + static wxBitmap *bmp_ex_cte_scan_png; + if (!bmp_ex_cte_scan_png || !bmp_ex_cte_scan_png->IsOk()) + bmp_ex_cte_scan_png = new wxBitmap(*ex_cte_scan_png_img); + return bmp_ex_cte_scan_png; +} +#define ex_cte_scan_png_bmp ex_cte_scan_png_bmp() + +static wxIcon *ex_cte_scan_png_ico() +{ + static wxIcon *ico_ex_cte_scan_png; + if (!ico_ex_cte_scan_png || !ico_ex_cte_scan_png->IsOk()) + { + ico_ex_cte_scan_png = new wxIcon(); + ico_ex_cte_scan_png->CopyFromBitmap(*ex_cte_scan_png_bmp); + } + return ico_ex_cte_scan_png; +} +#define ex_cte_scan_png_ico ex_cte_scan_png_ico() + +#endif // EX_CTE_SCAN_PNG_H diff --git a/include/images/ex_delete.png b/include/images/ex_delete.png new file mode 100644 index 0000000..ca051cd Binary files /dev/null and b/include/images/ex_delete.png differ diff --git a/include/images/ex_delete.pngc b/include/images/ex_delete.pngc new file mode 100644 index 0000000..063d370 --- /dev/null +++ b/include/images/ex_delete.pngc @@ -0,0 +1,186 @@ +#ifndef EX_DELETE_PNG_H +#define EX_DELETE_PNG_H + +static const unsigned char ex_delete_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x4d, 0x50, 0x4c, 0x54, +0x45, 0x3f, 0x00, 0xb0, 0x5b, 0x5b, 0x5b, 0xe8, +0x41, 0x07, 0xf6, 0x4d, 0x12, 0x36, 0x88, 0xc1, +0xd9, 0x73, 0x27, 0xce, 0x7d, 0x2c, 0x09, 0xa9, +0xe2, 0xd0, 0x81, 0x2f, 0x72, 0x96, 0xa1, 0x92, +0x92, 0x92, 0xc1, 0x8f, 0x36, 0xd7, 0x8f, 0x49, +0x32, 0xb5, 0xe5, 0x75, 0xa6, 0xc7, 0xea, 0x90, +0x59, 0x41, 0xbc, 0xe8, 0xcb, 0xa2, 0x58, 0xe2, +0x9f, 0x69, 0x4a, 0xc0, 0xe9, 0xc7, 0xaa, 0x75, +0xe3, 0xa3, 0x6e, 0x5d, 0xc4, 0xea, 0x63, 0xc6, +0xea, 0x6b, 0xc7, 0xe8, 0x68, 0xc8, 0xec, 0x6e, +0xcb, 0xec, 0x75, 0xcd, 0xec, 0xda, 0xbb, 0x7e, +0xdb, 0xbd, 0x7f, 0xdb, 0xbd, 0x89, 0xdc, 0xbe, +0x80, 0xdc, 0xbf, 0x80, 0x7b, 0xd1, 0xef, 0xdc, +0xc1, 0x82, 0x84, 0xd1, 0xee, 0xdd, 0xc3, 0x83, +0x84, 0xd3, 0xf0, 0xde, 0xc4, 0x84, 0xde, 0xc5, +0x85, 0xde, 0xc6, 0x86, 0x8c, 0xd4, 0xee, 0xdf, +0xc7, 0x87, 0xdf, 0xc8, 0x88, 0x91, 0xd5, 0xee, +0xe0, 0xc9, 0x89, 0xe1, 0xcc, 0x8a, 0x97, 0xd9, +0xf1, 0xe3, 0xcb, 0x9e, 0xe2, 0xce, 0x8c, 0xe3, +0xcc, 0x9e, 0xe4, 0xcd, 0x9e, 0xe2, 0xd0, 0x8d, +0xe4, 0xce, 0x9f, 0xa0, 0xdb, 0xf1, 0xe3, 0xd2, +0x8f, 0xe5, 0xd0, 0xa1, 0xe4, 0xd3, 0x90, 0xe6, +0xd1, 0xa1, 0xe6, 0xd1, 0xa2, 0xe4, 0xd4, 0x91, +0xe6, 0xd2, 0xa2, 0xe4, 0xd5, 0x92, 0xe6, 0xd3, +0xa3, 0xe5, 0xd6, 0x93, 0xe6, 0xd4, 0xa4, 0xe7, +0xd5, 0xa5, 0xae, 0xe0, 0xf3, 0xe6, 0xd9, 0x94, +0xe8, 0xd7, 0xa6, 0xe8, 0xd7, 0xa7, 0xe6, 0xda, +0x96, 0xe9, 0xd8, 0xa7, 0xe9, 0xd9, 0xa8, 0xe7, +0xdc, 0x97, 0xe9, 0xda, 0xa9, 0xea, 0xd9, 0xb6, +0xe9, 0xdb, 0xaa, 0xeb, 0xda, 0xb7, 0xe8, 0xde, +0x99, 0xea, 0xdd, 0xaa, 0xec, 0xdc, 0xb8, 0xe9, +0xe0, 0x9a, 0xeb, 0xde, 0xac, 0xec, 0xdd, 0xba, +0xeb, 0xdf, 0xad, 0xec, 0xde, 0xba, 0xec, 0xe0, +0xad, 0xea, 0xe3, 0x9c, 0xed, 0xdf, 0xbb, 0xec, +0xe1, 0xae, 0xed, 0xe0, 0xbb, 0xea, 0xe4, 0x9d, +0xec, 0xe2, 0xaf, 0xed, 0xe1, 0xbc, 0xec, 0xe3, +0xb0, 0xed, 0xe5, 0xb1, 0xef, 0xe4, 0xbe, 0xed, +0xe6, 0xb2, 0xee, 0xe6, 0xb3, 0xef, 0xe5, 0xc0, +0xf0, 0xe6, 0xc0, 0xef, 0xe8, 0xb3, 0xef, 0xe9, +0xb5, 0xf0, 0xe8, 0xc2, 0xf0, 0xe9, 0xc2, 0xf0, +0xec, 0xb6, 0xf1, 0xeb, 0xc4, 0xf2, 0xed, 0xc5, +0xf3, 0xed, 0xc6, 0xf3, 0xf0, 0xc8, 0x66, 0x7b, +0x7b, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, +0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x02, 0xb5, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0x93, +0xdb, 0x7b, 0x19, 0x51, 0x14, 0xc5, 0x85, 0xc9, +0xa5, 0xdd, 0xd5, 0x6a, 0x23, 0x9a, 0x0a, 0xd1, +0x88, 0xa4, 0x22, 0x32, 0x21, 0x08, 0x21, 0x8c, +0x51, 0xd4, 0x25, 0x62, 0x12, 0x84, 0x12, 0x86, +0x4e, 0x51, 0xb7, 0xfc, 0xff, 0x8f, 0x3d, 0x73, +0xce, 0x30, 0x26, 0x46, 0x9a, 0x87, 0x7e, 0x5f, +0xfb, 0x90, 0xfd, 0xb0, 0x9e, 0xfc, 0xe6, 0xec, +0xb5, 0xf6, 0xa2, 0xd1, 0xbc, 0xcc, 0x3f, 0x98, +0xb7, 0x94, 0x38, 0x4b, 0x55, 0x0d, 0xa1, 0xcc, +0x06, 0x83, 0x61, 0x87, 0xda, 0xdb, 0x34, 0x99, +0x0e, 0xa8, 0x83, 0x4f, 0x66, 0xf3, 0x29, 0x75, +0xba, 0xb7, 0xbf, 0x7f, 0x4e, 0x9d, 0x1f, 0xb9, +0xdd, 0x5f, 0x29, 0x55, 0xc4, 0xb0, 0xbe, 0xbe, +0x6e, 0xa0, 0x36, 0x91, 0x9a, 0xa8, 0x8f, 0x7a, +0xbd, 0xde, 0x4c, 0xed, 0x20, 0x7c, 0x9f, 0x3a, +0xda, 0xde, 0x36, 0xbb, 0xa9, 0xbf, 0xf4, 0xca, +0x2b, 0xbc, 0xf3, 0x52, 0x55, 0x43, 0xe0, 0x61, +0x38, 0x1c, 0x3e, 0x4c, 0xb5, 0xdf, 0xef, 0x8f, +0x61, 0x2c, 0x08, 0xc2, 0x08, 0x46, 0x3c, 0xcf, +0x0f, 0x80, 0xfc, 0x06, 0xc0, 0x38, 0x8f, 0x0c, +0xef, 0xef, 0x6b, 0x7d, 0x49, 0xfb, 0xb7, 0xb7, +0xb7, 0x3d, 0x10, 0x8a, 0xb9, 0x5c, 0x1b, 0xf8, +0x64, 0x32, 0x5e, 0x05, 0x42, 0x4c, 0x7e, 0x19, +0x8d, 0x0a, 0xa4, 0x86, 0x91, 0x1a, 0x41, 0x8a, +0x02, 0x08, 0xb9, 0x5c, 0x8e, 0x87, 0x66, 0x32, +0x3e, 0x45, 0xbe, 0x4f, 0x26, 0xdd, 0x0c, 0xc8, +0x48, 0xbf, 0x86, 0x7f, 0x8c, 0xb5, 0x57, 0x2c, +0x22, 0xa4, 0x9d, 0xfb, 0x96, 0xe4, 0xa1, 0x1e, +0x8f, 0xc5, 0x2a, 0x12, 0x92, 0xc9, 0x18, 0xab, +0x13, 0x90, 0xbd, 0xe0, 0xfd, 0x67, 0x2e, 0x7e, +0x60, 0x17, 0xcd, 0x01, 0x0c, 0xaa, 0x95, 0x52, +0x57, 0xf2, 0x62, 0x35, 0x7e, 0xa1, 0x87, 0x33, +0xe6, 0x3d, 0x88, 0xb3, 0x85, 0x75, 0x77, 0x51, +0xa5, 0xef, 0x5a, 0x6b, 0x9f, 0x65, 0x06, 0x74, +0xe2, 0x6c, 0x8c, 0x7b, 0x82, 0x30, 0x86, 0x51, +0xbb, 0xcd, 0x8f, 0x60, 0x50, 0xaf, 0x56, 0xbb, +0xd0, 0xe5, 0x38, 0xae, 0x33, 0xfd, 0xb0, 0x82, +0x01, 0x9d, 0x56, 0xab, 0xd5, 0x6d, 0xc8, 0x2e, +0x9a, 0xa2, 0x8b, 0xcb, 0x12, 0x70, 0x41, 0xbf, +0x3f, 0x2f, 0xef, 0x3f, 0xc7, 0x48, 0x88, 0x50, +0x2c, 0x92, 0x60, 0x93, 0x75, 0xa8, 0xc6, 0x2e, +0x2f, 0x38, 0xe0, 0xfc, 0x7e, 0x6f, 0x7e, 0x2e, +0x26, 0xcc, 0x60, 0x73, 0x53, 0x04, 0x07, 0xcb, +0xe3, 0x60, 0x2b, 0x17, 0xc1, 0x20, 0x07, 0x05, +0xaf, 0x97, 0xce, 0x82, 0x46, 0xc9, 0x18, 0x59, +0x98, 0x79, 0x59, 0x74, 0xd1, 0xc9, 0x67, 0xb3, +0x2d, 0x98, 0x3f, 0x3a, 0x58, 0xc5, 0xa3, 0x82, +0xe6, 0xcd, 0x86, 0x38, 0x7f, 0x48, 0x6c, 0xca, +0x20, 0x0a, 0xd9, 0x41, 0x57, 0x68, 0xd6, 0x07, +0x92, 0x76, 0x2b, 0x25, 0x74, 0x8b, 0x4e, 0x21, +0x9f, 0xef, 0x40, 0x2b, 0x9d, 0x4e, 0x35, 0x40, +0xd9, 0x47, 0x48, 0x67, 0x5e, 0xaf, 0x68, 0xa4, +0xfd, 0x95, 0x2e, 0x68, 0xe4, 0x22, 0x7d, 0x72, +0xec, 0x62, 0xe1, 0x51, 0x87, 0x01, 0x56, 0x10, +0x52, 0x8f, 0xc7, 0x51, 0x31, 0x88, 0x72, 0xc1, +0xa0, 0xbf, 0x00, 0x79, 0x9a, 0xa6, 0xd3, 0x90, +0x3a, 0x76, 0x39, 0x1f, 0x23, 0x12, 0x28, 0x46, +0x5a, 0x92, 0x94, 0x04, 0x9b, 0xa5, 0x4f, 0x4e, +0x52, 0x90, 0x70, 0x3a, 0x9d, 0x8c, 0x3a, 0x82, +0xf6, 0xe7, 0x7e, 0x4a, 0x2a, 0xba, 0x68, 0x21, +0x17, 0xa9, 0x44, 0x03, 0x1a, 0x2c, 0xc3, 0x94, +0x55, 0x11, 0xd2, 0xb1, 0x0f, 0x73, 0x4d, 0xdb, +0x5a, 0x96, 0x98, 0xfc, 0x0a, 0xc7, 0x15, 0x3a, +0x6b, 0xf8, 0x3a, 0xab, 0xe4, 0x46, 0x8d, 0x04, +0xcb, 0xde, 0x41, 0x39, 0x1a, 0x09, 0xdf, 0xa8, +0x2f, 0x86, 0xf7, 0x5f, 0xc3, 0x1d, 0x58, 0x25, +0x4d, 0x40, 0x2e, 0x0e, 0x19, 0x88, 0x38, 0xec, +0xf6, 0x90, 0x3a, 0x82, 0x8b, 0xa1, 0x40, 0x58, +0xe7, 0xa1, 0x23, 0x0a, 0x61, 0xbb, 0xdd, 0xb6, +0x04, 0xc1, 0x91, 0x2a, 0x10, 0xe6, 0xd0, 0xe1, +0x08, 0x43, 0xc8, 0x6e, 0xb3, 0x05, 0xd4, 0x91, +0x4e, 0x36, 0x9b, 0x6e, 0x29, 0xbc, 0x94, 0x23, +0x91, 0xf0, 0x35, 0x5c, 0x87, 0x02, 0x81, 0xeb, +0x27, 0x12, 0xdb, 0xc2, 0x4d, 0x7b, 0xb7, 0xd8, +0x37, 0xd5, 0x57, 0x5a, 0xa9, 0x04, 0xba, 0x02, +0xd1, 0x3b, 0x86, 0x89, 0x96, 0xe1, 0x26, 0x14, +0x0a, 0xa1, 0x57, 0x02, 0x3e, 0xdf, 0x95, 0xfa, +0x62, 0xa4, 0x18, 0x44, 0x19, 0x07, 0x76, 0x61, +0x13, 0x5d, 0xf8, 0x2c, 0x16, 0xcb, 0x99, 0x3a, +0x92, 0x70, 0x89, 0xc5, 0x20, 0x1a, 0xc5, 0xc1, +0xca, 0x88, 0x47, 0x1d, 0x61, 0xd1, 0x15, 0xa2, +0x92, 0x46, 0xec, 0x22, 0x12, 0xb0, 0xd9, 0x2c, +0x3e, 0x38, 0x5b, 0x8e, 0xdc, 0x31, 0x51, 0xb4, +0x3f, 0xd1, 0x79, 0x17, 0x57, 0x1e, 0x8f, 0xe7, +0xea, 0x89, 0xc4, 0x76, 0x9f, 0xf3, 0xaf, 0x7c, +0x99, 0xff, 0x69, 0x7e, 0x03, 0x34, 0xeb, 0xc6, +0xfb, 0xaa, 0xd1, 0x43, 0x09, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_delete_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_delete_png = new wxImage(); + if (!img_ex_delete_png || !img_ex_delete_png->IsOk()) + { + wxMemoryInputStream img_ex_delete_pngIS(ex_delete_png_data, sizeof(ex_delete_png_data)); + img_ex_delete_png->LoadFile(img_ex_delete_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_delete_png; +} +#define ex_delete_png_img ex_delete_png_img() + +static wxBitmap *ex_delete_png_bmp() +{ + static wxBitmap *bmp_ex_delete_png; + if (!bmp_ex_delete_png || !bmp_ex_delete_png->IsOk()) + bmp_ex_delete_png = new wxBitmap(*ex_delete_png_img); + return bmp_ex_delete_png; +} +#define ex_delete_png_bmp ex_delete_png_bmp() + +static wxIcon *ex_delete_png_ico() +{ + static wxIcon *ico_ex_delete_png; + if (!ico_ex_delete_png || !ico_ex_delete_png->IsOk()) + { + ico_ex_delete_png = new wxIcon(); + ico_ex_delete_png->CopyFromBitmap(*ex_delete_png_bmp); + } + return ico_ex_delete_png; +} +#define ex_delete_png_ico ex_delete_png_ico() + +#endif // EX_DELETE_PNG_H diff --git a/include/images/ex_foreign_scan.png b/include/images/ex_foreign_scan.png new file mode 100644 index 0000000..acba49c Binary files /dev/null and b/include/images/ex_foreign_scan.png differ diff --git a/include/images/ex_foreign_scan.pngc b/include/images/ex_foreign_scan.pngc new file mode 100644 index 0000000..44c1005 --- /dev/null +++ b/include/images/ex_foreign_scan.pngc @@ -0,0 +1,245 @@ +#ifndef EX_FOREIGN_SCAN_PNG_H +#define EX_FOREIGN_SCAN_PNG_H + +static const unsigned char ex_foreign_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0xd9, 0x50, 0x4c, 0x54, +0x45, 0x34, 0x51, 0x54, 0x2f, 0x33, 0x35, 0x32, +0x3d, 0x3d, 0x2b, 0x40, 0x44, 0x34, 0x3e, 0x3f, +0x35, 0x3f, 0x40, 0x2e, 0x43, 0x47, 0x3f, 0x43, +0x45, 0x3a, 0x45, 0x45, 0x3b, 0x46, 0x46, 0x3f, +0x4a, 0x4b, 0x31, 0x4e, 0x51, 0x32, 0x50, 0x52, +0x42, 0x4d, 0x4e, 0x48, 0x4c, 0x4e, 0x35, 0x52, +0x55, 0x49, 0x4d, 0x4f, 0x44, 0x4f, 0x4f, 0x45, +0x50, 0x50, 0x4b, 0x4f, 0x51, 0x46, 0x51, 0x52, +0x4d, 0x52, 0x54, 0x3b, 0x58, 0x5b, 0x4b, 0x56, +0x57, 0x4e, 0x59, 0x5a, 0x50, 0x5b, 0x5b, 0x41, +0x5f, 0x61, 0x50, 0x5c, 0x5c, 0x42, 0x60, 0x62, +0x51, 0x5d, 0x5d, 0x54, 0x60, 0x60, 0x47, 0x64, +0x67, 0x56, 0x61, 0x62, 0x57, 0x62, 0x63, 0x58, +0x63, 0x64, 0x49, 0x67, 0x6a, 0x59, 0x64, 0x65, +0x5a, 0x65, 0x66, 0x5b, 0x66, 0x67, 0x5c, 0x67, +0x68, 0x62, 0x67, 0x69, 0x5e, 0x69, 0x6a, 0x4f, +0x6d, 0x70, 0x5f, 0x6a, 0x6b, 0x4a, 0x70, 0x72, +0x56, 0x6d, 0x71, 0x66, 0x6b, 0x6d, 0x67, 0x6b, +0x6e, 0x61, 0x6d, 0x6e, 0x53, 0x71, 0x74, 0x62, +0x6e, 0x6f, 0x4e, 0x74, 0x76, 0x63, 0x6f, 0x70, +0x64, 0x70, 0x71, 0x65, 0x71, 0x72, 0x60, 0x73, +0x72, 0x66, 0x72, 0x73, 0x6d, 0x71, 0x74, 0x53, +0x79, 0x7b, 0x6e, 0x72, 0x75, 0x68, 0x74, 0x75, +0x6f, 0x73, 0x76, 0x69, 0x75, 0x75, 0x6b, 0x77, +0x77, 0x74, 0x78, 0x7b, 0x77, 0x79, 0x76, 0x6f, +0x7b, 0x7b, 0x2c, 0x88, 0xc1, 0x60, 0x7f, 0x82, +0x76, 0x7b, 0x7e, 0x58, 0x83, 0x8a, 0x7d, 0x7f, +0x7c, 0x75, 0x81, 0x81, 0x77, 0x83, 0x83, 0x5e, +0x8a, 0x90, 0x78, 0x84, 0x84, 0x7a, 0x86, 0x86, +0x7b, 0x87, 0x87, 0x7c, 0x88, 0x88, 0x78, 0x8b, +0x8a, 0x7e, 0x8a, 0x8a, 0x84, 0x89, 0x8c, 0x00, +0xa8, 0xe3, 0x77, 0x8e, 0x92, 0x00, 0xa9, 0xe5, +0x80, 0x8c, 0x8d, 0x82, 0x8e, 0x8f, 0x88, 0x8d, +0x90, 0x00, 0xae, 0xe3, 0x89, 0x8e, 0x91, 0x84, +0x90, 0x91, 0x00, 0xb0, 0xe5, 0x85, 0x91, 0x92, +0x7d, 0x94, 0x98, 0x87, 0x93, 0x94, 0x6d, 0x96, +0xcf, 0x8f, 0x93, 0x96, 0x89, 0x95, 0x96, 0x8a, +0x96, 0x97, 0x82, 0x99, 0x9d, 0x83, 0x9a, 0x9e, +0x6c, 0xa1, 0xa6, 0x84, 0x9b, 0x9f, 0x87, 0x9b, +0x9a, 0x8e, 0x9a, 0x9b, 0x57, 0xaa, 0xab, 0x92, +0x9e, 0x9f, 0x8c, 0xa0, 0x9f, 0x31, 0xb5, 0xe5, +0x9c, 0x9e, 0x9b, 0x8c, 0xa3, 0xa8, 0x34, 0xb7, +0xe7, 0x8d, 0xa4, 0xa9, 0x36, 0xb8, 0xe9, 0x96, +0xa6, 0xac, 0x99, 0xa6, 0xa6, 0xa0, 0xa5, 0xa8, +0x9a, 0xa7, 0xa7, 0x4a, 0xbc, 0xe7, 0x4c, 0xbd, +0xe8, 0x9e, 0xab, 0xac, 0x4d, 0xbe, 0xe9, 0xa8, +0xaa, 0xa7, 0x40, 0xc2, 0xec, 0x5a, 0xc0, 0xe6, +0x51, 0xc2, 0xed, 0x83, 0xb8, 0xbd, 0x5b, 0xc1, +0xe7, 0xad, 0xaf, 0xac, 0x5c, 0xc2, 0xe8, 0xae, +0xb0, 0xad, 0xb0, 0xb2, 0xae, 0x9f, 0xb6, 0xbb, +0x8b, 0xb9, 0xd9, 0x5f, 0xc5, 0xea, 0xb1, 0xb3, +0xaf, 0x61, 0xc7, 0xec, 0x62, 0xc8, 0xee, 0x64, +0xc9, 0xef, 0xb5, 0xb7, 0xb4, 0x6b, 0xc8, 0xe8, +0x6c, 0xc9, 0xe9, 0xa5, 0xbd, 0xc1, 0x6d, 0xca, +0xea, 0x6e, 0xcb, 0xeb, 0xaa, 0xbf, 0xbe, 0xa8, +0xc0, 0xc5, 0x70, 0xcd, 0xed, 0xa3, 0xc3, 0xc6, +0x72, 0xce, 0xee, 0xa5, 0xc1, 0xe6, 0x74, 0xd0, +0xf1, 0x7d, 0xce, 0xf0, 0x85, 0xd0, 0xec, 0xc1, +0xc3, 0xbf, 0x86, 0xd1, 0xed, 0xc2, 0xc4, 0xc1, +0x87, 0xd2, 0xee, 0xc0, 0xc5, 0xc8, 0xac, 0xcc, +0xcf, 0x8a, 0xd4, 0xf0, 0xc5, 0xc7, 0xc4, 0x8b, +0xd5, 0xf1, 0xc6, 0xc8, 0xc5, 0x90, 0xd5, 0xec, +0xae, 0xcf, 0xd2, 0xc7, 0xc9, 0xc6, 0x91, 0xd6, +0xed, 0xc5, 0xca, 0xcd, 0x92, 0xd7, 0xee, 0xb0, +0xd1, 0xd4, 0x94, 0xd8, 0xef, 0xb3, 0xd3, 0xd6, +0x96, 0xda, 0xf1, 0xb4, 0xd4, 0xd7, 0xb5, 0xd5, +0xd8, 0xaa, 0xd7, 0xeb, 0xce, 0xd0, 0xcc, 0xb6, +0xd6, 0xd9, 0xcf, 0xd1, 0xce, 0xb7, 0xd7, 0xda, +0xd0, 0xd2, 0xcf, 0xb8, 0xd8, 0xdb, 0xc2, 0xd7, +0xd6, 0xa7, 0xdd, 0xf0, 0xd2, 0xd4, 0xd1, 0xa8, +0xde, 0xf1, 0xba, 0xdb, 0xde, 0xd3, 0xd5, 0xd2, +0xba, 0xdb, 0xeb, 0xbb, 0xdc, 0xdf, 0xbc, 0xdd, +0xe0, 0xab, 0xe1, 0xf4, 0xbd, 0xde, 0xe1, 0xc4, +0xdc, 0xe1, 0xc5, 0xdd, 0xe2, 0xbe, 0xde, 0xee, +0xd8, 0xda, 0xd6, 0xbf, 0xdf, 0xef, 0xc6, 0xdf, +0xe3, 0xc0, 0xe0, 0xf1, 0xc7, 0xe0, 0xe4, 0xc1, +0xe1, 0xf2, 0xc8, 0xe1, 0xe6, 0xc6, 0xe2, 0xed, +0xc9, 0xe2, 0xe7, 0xc7, 0xe3, 0xee, 0xca, 0xe3, +0xe8, 0xc8, 0xe4, 0xef, 0xcf, 0xe4, 0xe3, 0xc9, +0xe5, 0xf0, 0xcd, 0xe5, 0xea, 0xdf, 0xe1, 0xde, +0xd0, 0xe5, 0xe4, 0xd1, 0xe6, 0xe5, 0xd1, 0xe5, +0xf1, 0xd2, 0xe7, 0xe6, 0xd2, 0xe6, 0xf2, 0xe1, +0xe4, 0xe0, 0xd3, 0xe8, 0xe7, 0xd3, 0xe7, 0xf4, +0xda, 0xe7, 0xe7, 0xd4, 0xe8, 0xf5, 0xdb, 0xe8, +0xe9, 0xe4, 0xe6, 0xe3, 0xd5, 0xe9, 0xf6, 0xdc, +0xe9, 0xea, 0xe5, 0xe7, 0xe4, 0xdd, 0xea, 0xeb, +0xd6, 0xeb, 0xf7, 0xde, 0xeb, 0xec, 0xdf, 0xec, +0xed, 0xe0, 0xed, 0xee, 0xe1, 0xee, 0xef, 0xea, +0xec, 0xe9, 0xdf, 0xf0, 0xf6, 0xef, 0xf1, 0xee, +0xf1, 0xf3, 0xf0, 0xf4, 0xf7, 0xf3, 0xf7, 0xf9, +0xf6, 0xfa, 0xfc, 0xf9, 0xfc, 0xff, 0xfb, 0xfe, +0xff, 0xfc, 0x02, 0x67, 0x00, 0x4f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, +0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, +0x00, 0x00, 0x03, 0x07, 0x49, 0x44, 0x41, 0x54, +0x48, 0xc7, 0xed, 0x94, 0xd9, 0x4f, 0x13, 0x51, +0x14, 0xc6, 0x71, 0xdf, 0x50, 0x14, 0xa2, 0xe2, +0xae, 0x28, 0xee, 0x8a, 0xbb, 0xa2, 0x51, 0xd4, +0x11, 0x15, 0x57, 0xc0, 0xc4, 0x0d, 0xb5, 0xe2, +0xbe, 0x8b, 0x1b, 0x88, 0xca, 0x75, 0x57, 0x12, +0x71, 0x97, 0xba, 0xa0, 0x82, 0x4b, 0x5c, 0x6a, +0xa5, 0x85, 0x34, 0x55, 0x8c, 0x34, 0xb6, 0x83, +0x4c, 0x87, 0x10, 0x86, 0x52, 0x67, 0x58, 0x87, +0x84, 0x58, 0x28, 0x88, 0x28, 0x39, 0x7f, 0x81, +0xb3, 0xd4, 0xda, 0x19, 0xda, 0x07, 0x12, 0x63, +0x7c, 0xe0, 0x3c, 0x9c, 0x79, 0xb9, 0xbf, 0xfb, +0xdd, 0xef, 0xcc, 0x39, 0xc7, 0xcb, 0xab, 0x25, +0xfe, 0x75, 0x5c, 0xc4, 0xf8, 0xf0, 0x98, 0xdd, +0x21, 0xd8, 0xed, 0xd8, 0xb8, 0xb8, 0x64, 0xec, +0x6e, 0x42, 0xc2, 0xd9, 0x47, 0xd8, 0xd3, 0xc4, +0xc4, 0xeb, 0x6f, 0xb0, 0xb7, 0xf7, 0xee, 0xa7, +0xbc, 0xc7, 0x3e, 0xa4, 0x3d, 0x7f, 0xf9, 0x09, +0x73, 0x8b, 0xc4, 0x46, 0x46, 0x46, 0xc6, 0x63, +0x27, 0xd7, 0x46, 0x45, 0x5d, 0xc2, 0x12, 0xf7, +0x1d, 0x3c, 0x74, 0x03, 0x4b, 0x8e, 0x3f, 0x75, +0x3a, 0x05, 0x4b, 0x4b, 0x4a, 0xba, 0xfa, 0x1a, +0xfb, 0x4b, 0x2a, 0xbb, 0x85, 0x37, 0x7b, 0xcc, +0x92, 0xb3, 0x4a, 0x85, 0x42, 0xc9, 0x7d, 0x50, +0x1d, 0xcb, 0xb2, 0x75, 0x42, 0xae, 0x45, 0xb5, +0xce, 0x6c, 0x47, 0x76, 0xab, 0x95, 0xb6, 0x23, +0x09, 0xa2, 0xa8, 0xaf, 0x57, 0xf0, 0x08, 0x6b, +0xb1, 0x58, 0x58, 0xc4, 0x92, 0x24, 0xe9, 0x9a, +0x19, 0x64, 0x25, 0x08, 0x13, 0x2d, 0x43, 0xaa, +0xab, 0x3d, 0x23, 0x84, 0x15, 0xd1, 0x26, 0x53, +0x13, 0xa4, 0xaa, 0xea, 0x37, 0x42, 0x4a, 0x11, +0x86, 0x20, 0x08, 0x5a, 0x40, 0x2c, 0xee, 0x11, +0x99, 0x8b, 0x12, 0xde, 0x05, 0x4d, 0xd7, 0x20, +0x1b, 0x4d, 0x73, 0xea, 0xee, 0x90, 0x74, 0xc4, +0x87, 0xc7, 0x2c, 0x45, 0x2a, 0x2b, 0x05, 0x95, +0x5a, 0x17, 0x15, 0x3b, 0xc3, 0x30, 0x9c, 0x0a, +0x4d, 0xd3, 0x36, 0x64, 0xa3, 0x28, 0x4a, 0xae, +0xe2, 0x40, 0xd8, 0x5d, 0xe1, 0x9b, 0x56, 0xf4, +0x5f, 0x7c, 0x78, 0x75, 0x74, 0x78, 0xdf, 0x29, +0x53, 0x2f, 0xec, 0x0d, 0x1c, 0x7a, 0xf3, 0x40, +0xe0, 0xa4, 0xe3, 0xdb, 0x8f, 0xed, 0x8c, 0x51, +0x93, 0x32, 0xa4, 0xa2, 0x42, 0x44, 0x7a, 0x03, +0x17, 0x8f, 0x43, 0xb8, 0xd4, 0xf0, 0x24, 0x74, +0xe9, 0x16, 0x38, 0x31, 0x6d, 0x38, 0xc0, 0x98, +0xd1, 0x97, 0x61, 0x7c, 0xaa, 0x27, 0xa4, 0x1b, +0xc0, 0x86, 0x41, 0xf3, 0x47, 0x01, 0xcc, 0x1d, +0xf7, 0x0c, 0xd6, 0xcc, 0x68, 0x2c, 0x0b, 0x09, +0x05, 0x88, 0xe8, 0xf5, 0xa5, 0xb1, 0xab, 0x4a, +0x8e, 0x94, 0x96, 0x8a, 0x5e, 0xfc, 0x00, 0xf6, +0x8c, 0x0d, 0x0b, 0x00, 0x08, 0x5f, 0xb8, 0x19, +0x3e, 0xcf, 0x79, 0x05, 0x3d, 0xcf, 0x37, 0xfc, +0x38, 0xd7, 0x19, 0x1e, 0x0e, 0x79, 0x27, 0xf7, +0x52, 0x5c, 0x2c, 0x56, 0xac, 0x0d, 0xff, 0xb0, +0x8c, 0x2e, 0x00, 0x33, 0xef, 0x4c, 0x84, 0x9f, +0xde, 0xeb, 0x20, 0xf8, 0xdb, 0x99, 0x2b, 0xdf, +0x67, 0xc3, 0xa2, 0xc9, 0x4d, 0x2a, 0x26, 0x22, +0x82, 0x4a, 0x88, 0xf7, 0x48, 0x7f, 0x80, 0x23, +0x4b, 0x22, 0x20, 0xc3, 0x37, 0x08, 0x3e, 0x42, +0xf0, 0x3c, 0xc8, 0x02, 0xbf, 0x5b, 0x64, 0xb9, +0x4c, 0xa5, 0xa8, 0x48, 0xf4, 0xd2, 0x03, 0x20, +0x1a, 0xd1, 0x03, 0x01, 0x96, 0x2f, 0x78, 0x01, +0xb3, 0x46, 0x74, 0xfc, 0x0a, 0xd0, 0xa1, 0x3b, +0x40, 0xd9, 0xf4, 0x54, 0x9d, 0xdc, 0x4b, 0x61, +0xa1, 0x80, 0x30, 0x03, 0x00, 0xd6, 0x23, 0x5a, +0xa8, 0xd8, 0x83, 0xa0, 0x95, 0x31, 0xbe, 0x47, +0x21, 0xc3, 0xbf, 0x4f, 0x16, 0xec, 0xdf, 0xa6, +0xd3, 0x11, 0x32, 0xa4, 0xa0, 0x40, 0x44, 0xe6, +0xb4, 0x6a, 0x1b, 0x80, 0xe8, 0x1d, 0xed, 0x5a, +0x77, 0x6a, 0x3f, 0x61, 0xe3, 0x35, 0xdd, 0x32, +0x9f, 0x7e, 0x83, 0xb7, 0xae, 0x1a, 0xe6, 0x13, +0x96, 0x9a, 0x99, 0xe9, 0x01, 0xa9, 0xe1, 0xfe, +0xb5, 0x05, 0xb1, 0x5c, 0x76, 0x36, 0x27, 0x41, +0xe0, 0x0c, 0xd7, 0x9c, 0x38, 0xc1, 0xb8, 0x45, +0x9a, 0xd5, 0x63, 0xf9, 0xf9, 0x4e, 0x15, 0x1b, +0x62, 0x29, 0xca, 0xd9, 0xfc, 0xe5, 0xdc, 0xbc, +0x94, 0x08, 0x23, 0x20, 0x57, 0xc9, 0xcb, 0x13, +0x10, 0x7e, 0x2e, 0x28, 0x44, 0xe9, 0xf5, 0x7a, +0x12, 0x91, 0x7a, 0x3d, 0x57, 0x25, 0x52, 0xc7, +0xbb, 0x20, 0x34, 0x9a, 0x74, 0x5c, 0x86, 0x98, +0xcd, 0x0e, 0xc4, 0x68, 0xa0, 0xf8, 0xc3, 0x3c, +0xa2, 0xd3, 0x71, 0x08, 0x91, 0x29, 0x20, 0xe9, +0xe9, 0x9e, 0x10, 0x8b, 0xc1, 0x60, 0x20, 0x65, +0x88, 0x46, 0x43, 0x20, 0xdc, 0x33, 0xc2, 0x52, +0xa4, 0x5b, 0x17, 0x56, 0x1c, 0xc7, 0xad, 0x32, +0x24, 0x37, 0xb7, 0xd9, 0x15, 0x13, 0x11, 0x97, +0x45, 0x51, 0x8e, 0x4a, 0x84, 0xfb, 0x19, 0xe1, +0x7e, 0x4e, 0x45, 0xba, 0x2e, 0xb8, 0xc5, 0x97, +0x9d, 0xcd, 0x2f, 0x3f, 0x17, 0x17, 0x84, 0xc4, +0x05, 0xae, 0x56, 0xab, 0x8c, 0x48, 0x32, 0xc6, +0x39, 0x5a, 0x6d, 0x0e, 0x37, 0xca, 0x7f, 0x10, +0xb1, 0xb0, 0x1a, 0x9c, 0x47, 0xd4, 0x38, 0x32, +0xa9, 0x54, 0x52, 0x44, 0xa9, 0x30, 0x6b, 0xb5, +0x66, 0x51, 0x85, 0xaf, 0x12, 0x29, 0x16, 0x56, +0xe3, 0xb8, 0x5f, 0x6d, 0x42, 0x46, 0x39, 0xc2, +0x31, 0x5c, 0xc3, 0x28, 0x1d, 0x5e, 0xe4, 0x2e, +0xf8, 0xa5, 0x67, 0x31, 0x1a, 0x8d, 0xb2, 0xd5, +0xe7, 0x58, 0xe3, 0xcd, 0xa9, 0x58, 0x4b, 0xfc, +0x5f, 0xf1, 0x0b, 0x47, 0x3c, 0xe8, 0x0b, 0x70, +0xc6, 0x5a, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_foreign_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_foreign_scan_png = new wxImage(); + if (!img_ex_foreign_scan_png || !img_ex_foreign_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_foreign_scan_pngIS(ex_foreign_scan_png_data, sizeof(ex_foreign_scan_png_data)); + img_ex_foreign_scan_png->LoadFile(img_ex_foreign_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_foreign_scan_png; +} +#define ex_foreign_scan_png_img ex_foreign_scan_png_img() + +static wxBitmap *ex_foreign_scan_png_bmp() +{ + static wxBitmap *bmp_ex_foreign_scan_png; + if (!bmp_ex_foreign_scan_png || !bmp_ex_foreign_scan_png->IsOk()) + bmp_ex_foreign_scan_png = new wxBitmap(*ex_foreign_scan_png_img); + return bmp_ex_foreign_scan_png; +} +#define ex_foreign_scan_png_bmp ex_foreign_scan_png_bmp() + +static wxIcon *ex_foreign_scan_png_ico() +{ + static wxIcon *ico_ex_foreign_scan_png; + if (!ico_ex_foreign_scan_png || !ico_ex_foreign_scan_png->IsOk()) + { + ico_ex_foreign_scan_png = new wxIcon(); + ico_ex_foreign_scan_png->CopyFromBitmap(*ex_foreign_scan_png_bmp); + } + return ico_ex_foreign_scan_png; +} +#define ex_foreign_scan_png_ico ex_foreign_scan_png_ico() + +#endif // EX_FOREIGN_SCAN_PNG_H diff --git a/include/images/ex_gatcher.png b/include/images/ex_gatcher.png new file mode 100644 index 0000000..1d7d701 Binary files /dev/null and b/include/images/ex_gatcher.png differ diff --git a/include/images/ex_gatcher.pngc b/include/images/ex_gatcher.pngc new file mode 100644 index 0000000..4cf4bd9 --- /dev/null +++ b/include/images/ex_gatcher.pngc @@ -0,0 +1,176 @@ +#ifndef EX_GATCHER_PNG_H +#define EX_GATCHER_PNG_H + +static const unsigned char ex_gatcher_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88, +0xb1, 0x00, 0x00, 0x03, 0xe7, 0x49, 0x44, 0x41, +0x54, 0x78, 0xda, 0xed, 0x97, 0xcb, 0x4f, 0x53, +0x51, 0x10, 0xc6, 0xf9, 0x37, 0xfc, 0x03, 0x5c, +0xbb, 0x73, 0x69, 0xdc, 0xb8, 0x74, 0xe3, 0x5e, +0x12, 0xe2, 0x6b, 0x21, 0x0b, 0x5d, 0x98, 0x18, +0x37, 0xf8, 0x42, 0xf0, 0x89, 0x41, 0x51, 0x24, +0x42, 0x04, 0x14, 0x84, 0x06, 0x44, 0x23, 0x0f, +0x11, 0xc2, 0xab, 0xa5, 0x95, 0x00, 0x52, 0x9e, +0x0a, 0x05, 0x5a, 0x0a, 0x97, 0x47, 0x6f, 0x69, +0x81, 0x10, 0x97, 0xe3, 0xfd, 0xa6, 0x4c, 0x73, +0xb1, 0xa5, 0x8f, 0x1b, 0x6a, 0x6b, 0xbd, 0x93, +0x7c, 0x39, 0x61, 0xda, 0x9c, 0xf3, 0xfd, 0xce, +0xdc, 0x99, 0x5b, 0x72, 0x72, 0xcc, 0x30, 0xc3, +0x8c, 0xff, 0x27, 0x4a, 0xcb, 0x9c, 0x74, 0xf1, +0x72, 0xa4, 0x8c, 0xe4, 0xd3, 0x7a, 0x1e, 0x92, +0x23, 0xa3, 0xdb, 0xd4, 0xd5, 0xad, 0x52, 0x4f, +0xaf, 0x9f, 0xe5, 0x74, 0x6e, 0xf3, 0x97, 0x27, +0x26, 0x77, 0xc8, 0xee, 0x08, 0x68, 0x0a, 0xd2, +0xd0, 0xd0, 0x16, 0xcd, 0xcd, 0xed, 0x72, 0x1e, +0x2b, 0x3e, 0x83, 0xa6, 0x67, 0x76, 0xc9, 0xe3, +0xf9, 0xc5, 0xf9, 0x44, 0x40, 0x52, 0x76, 0x1e, +0x12, 0xd8, 0xb4, 0xee, 0xbd, 0x42, 0x0d, 0x96, +0x55, 0x56, 0x5f, 0xff, 0x26, 0x7f, 0xd1, 0x66, +0x0b, 0x50, 0x6b, 0x9b, 0x8f, 0xf5, 0xa5, 0x53, +0x65, 0x03, 0xc8, 0xe3, 0xe0, 0x01, 0x6b, 0x80, +0x6c, 0x83, 0x41, 0x3e, 0x14, 0x9b, 0x27, 0x03, +0x92, 0x92, 0xf3, 0x4c, 0x90, 0x4c, 0x04, 0xc9, +0x8a, 0x1e, 0xc9, 0x9a, 0xa9, 0x95, 0x75, 0x71, +0xaf, 0xe1, 0x3c, 0x9d, 0x79, 0x7c, 0x84, 0xb0, +0xfe, 0xd3, 0x3e, 0xf1, 0x61, 0xb5, 0x35, 0x97, +0xbf, 0x94, 0xc9, 0x20, 0x71, 0x7d, 0x1a, 0x01, +0xb1, 0x37, 0x5e, 0xa3, 0xbe, 0x92, 0xe3, 0x11, +0x32, 0x92, 0x4f, 0x2b, 0x08, 0x4c, 0xec, 0x04, +0x1d, 0x14, 0x54, 0xdb, 0xc2, 0xc2, 0xdf, 0x92, +0x0f, 0xac, 0x7f, 0x0e, 0x6b, 0xc7, 0x3f, 0x18, +0xca, 0x6b, 0xeb, 0xa6, 0xf2, 0x89, 0xe5, 0x5f, +0xf9, 0x48, 0x5b, 0x3e, 0x2b, 0xe7, 0xd3, 0x0e, +0x02, 0xf3, 0x1b, 0xcb, 0x95, 0x61, 0xc1, 0x34, +0xf2, 0x58, 0xd7, 0xdd, 0x15, 0x61, 0xc1, 0x38, +0xf2, 0x58, 0x57, 0x5d, 0x2f, 0x69, 0x75, 0xee, +0x05, 0x4b, 0xf5, 0xb6, 0x64, 0x20, 0x88, 0xf7, +0x75, 0x04, 0xc8, 0xda, 0xc2, 0x2b, 0x96, 0x80, +0xa0, 0x0a, 0x00, 0x50, 0x7e, 0x96, 0xb1, 0xd4, +0xa5, 0x0f, 0x87, 0x0f, 0x52, 0x6b, 0xcf, 0x33, +0x06, 0xa2, 0x01, 0x88, 0x04, 0x04, 0xc6, 0x05, +0x62, 0x6d, 0xbe, 0x9c, 0x01, 0x90, 0x47, 0x05, +0x42, 0x10, 0xcf, 0x69, 0x65, 0xe6, 0x19, 0xa9, +0xee, 0xa6, 0xa4, 0x41, 0x62, 0xfa, 0x34, 0x0a, +0x12, 0xaf, 0x17, 0x00, 0xa0, 0xef, 0x05, 0xac, +0xa8, 0x82, 0xea, 0x6e, 0x66, 0x88, 0xe0, 0x5a, +0x7f, 0xfa, 0x41, 0xd2, 0x35, 0xb5, 0xe2, 0x82, +0xd4, 0x0d, 0x5f, 0x48, 0xbe, 0x22, 0xda, 0xcd, +0xa3, 0x12, 0x32, 0x89, 0xa4, 0x22, 0x7c, 0xf3, +0xda, 0x63, 0xc4, 0xd2, 0x2a, 0x20, 0x37, 0x8f, +0xd5, 0xb7, 0xd8, 0xc4, 0xda, 0x70, 0x35, 0x52, +0x60, 0xa5, 0x37, 0xe9, 0x8a, 0xc4, 0xf4, 0x69, +0x14, 0x24, 0xdc, 0x0b, 0x5a, 0x1f, 0x60, 0x1a, +0xed, 0xef, 0x85, 0x50, 0x1f, 0xe8, 0x7b, 0x01, +0x00, 0xde, 0xf1, 0x92, 0x90, 0xc6, 0x9e, 0xd0, +0xfa, 0x6c, 0x43, 0x0a, 0x40, 0xc6, 0x2e, 0x19, +0x03, 0xd9, 0x83, 0xd0, 0x8f, 0x53, 0x54, 0x41, +0x20, 0x96, 0xa7, 0x4a, 0x19, 0x00, 0x79, 0x54, +0x01, 0x00, 0x22, 0x43, 0x20, 0xb1, 0x7c, 0x1a, +0x05, 0x91, 0x71, 0x2a, 0x23, 0x55, 0xc6, 0x29, +0x9a, 0x19, 0x00, 0xac, 0x89, 0xa7, 0x0c, 0xa0, +0x07, 0xf1, 0x8c, 0x3c, 0x62, 0xa5, 0x04, 0xc4, +0x32, 0x95, 0x9f, 0x34, 0x48, 0xc2, 0xbd, 0xb0, +0xdc, 0x13, 0x7a, 0xbf, 0x68, 0x2b, 0xcc, 0xb3, +0x7e, 0xd4, 0xd3, 0xe6, 0x52, 0x77, 0xd2, 0x20, +0x31, 0x7d, 0x1a, 0x01, 0x49, 0xd7, 0xd4, 0x8a, +0xe9, 0x33, 0xaf, 0xec, 0x18, 0x97, 0x2c, 0xb7, +0xfc, 0x28, 0xf5, 0x39, 0x3a, 0x29, 0x91, 0x9f, +0xce, 0x72, 0xf3, 0xf2, 0x4e, 0xc0, 0xed, 0x07, +0x95, 0xd0, 0x14, 0xc2, 0x34, 0x42, 0x25, 0xe4, +0xf6, 0xe5, 0xe6, 0xb1, 0xae, 0xcd, 0xd4, 0xb3, +0x56, 0xa7, 0xdf, 0x91, 0x7f, 0xf1, 0x6b, 0x44, +0x45, 0x0e, 0x3c, 0x4f, 0xf3, 0x05, 0x7f, 0xf0, +0x09, 0xbf, 0x51, 0x41, 0xae, 0x54, 0x9e, 0xa2, +0x8a, 0xa1, 0xb3, 0x74, 0xbd, 0xf9, 0x04, 0x55, +0xb5, 0x16, 0xed, 0x83, 0xc1, 0xa6, 0x9d, 0xfe, +0x5b, 0x11, 0x9b, 0x87, 0x7a, 0xa1, 0x29, 0x6a, +0x2f, 0xc0, 0xbc, 0xf4, 0x81, 0x67, 0xf8, 0x01, +0x3f, 0x46, 0xc8, 0x03, 0xc0, 0xed, 0x28, 0xa6, +0x45, 0x7b, 0x11, 0x4b, 0x99, 0x7c, 0xbb, 0x0f, +0x44, 0x20, 0xe4, 0x3c, 0x3d, 0x04, 0x7c, 0xc1, +0x1f, 0x7c, 0xc2, 0x6f, 0x54, 0x90, 0x87, 0x96, +0x7c, 0x2a, 0xee, 0x3a, 0x4d, 0x95, 0x63, 0xe7, +0xe8, 0x46, 0xcb, 0x49, 0x26, 0xc7, 0x46, 0x22, +0x6c, 0xdc, 0x15, 0xbc, 0xbb, 0x0f, 0x46, 0xc6, +0x29, 0x00, 0x64, 0x9c, 0x46, 0x80, 0x68, 0x10, +0x10, 0x00, 0x90, 0x47, 0x15, 0x00, 0xb0, 0x60, +0x2b, 0x64, 0x29, 0x13, 0xb5, 0x61, 0x10, 0x81, +0xc0, 0x39, 0x02, 0x22, 0x82, 0x1f, 0xf8, 0x82, +0x3f, 0xf8, 0x84, 0xdf, 0xa8, 0x20, 0x3d, 0xf6, +0x76, 0xd2, 0xc3, 0x58, 0x16, 0xae, 0x52, 0x87, +0xaf, 0x80, 0x37, 0x14, 0x08, 0x91, 0xdc, 0x54, +0x78, 0x0a, 0xed, 0x41, 0xe8, 0xc7, 0x29, 0x83, +0x68, 0x00, 0xee, 0x6f, 0xf7, 0x59, 0x00, 0x40, +0x1e, 0x15, 0x60, 0x08, 0x6b, 0x21, 0xcd, 0x0f, +0xdc, 0x21, 0xc5, 0x59, 0x13, 0x06, 0x11, 0x08, +0x91, 0x9c, 0x0d, 0x1f, 0xf0, 0xa3, 0x87, 0x80, +0xdf, 0x03, 0x1b, 0x49, 0x60, 0x50, 0x36, 0x3c, +0x83, 0xfa, 0x1b, 0xd1, 0x43, 0xe8, 0x2b, 0x12, +0xaf, 0x17, 0x00, 0xa0, 0xef, 0x05, 0x75, 0xbe, +0x93, 0xab, 0xa0, 0x8c, 0xd7, 0x30, 0x84, 0xea, +0xea, 0x88, 0x5a, 0x11, 0x39, 0x4b, 0x04, 0x3f, +0xf0, 0x15, 0x17, 0x22, 0xde, 0xa4, 0xf8, 0x13, +0x22, 0x55, 0x53, 0x4b, 0x0f, 0x73, 0xe8, 0xff, +0x76, 0xc7, 0x9a, 0x5a, 0xb8, 0x79, 0x79, 0x27, +0xa0, 0x02, 0x52, 0x11, 0x54, 0x00, 0x8f, 0x11, +0x4b, 0xab, 0x00, 0x2a, 0xc1, 0x15, 0xd1, 0x2a, +0xa0, 0x38, 0xab, 0x69, 0xe5, 0x7b, 0x48, 0xbe, +0xd9, 0xf6, 0x84, 0xa7, 0x56, 0xca, 0x82, 0x7b, +0x41, 0x03, 0x90, 0x3e, 0xc0, 0x34, 0x8a, 0xd7, +0x0b, 0x30, 0xef, 0xea, 0xb9, 0xc9, 0x9a, 0xeb, +0x2e, 0xa0, 0xe5, 0xd1, 0x37, 0x49, 0xbd, 0x10, +0x53, 0x06, 0xc2, 0xe3, 0x74, 0x0f, 0x42, 0x3f, +0x4e, 0x51, 0x05, 0x00, 0xb0, 0xfa, 0x6e, 0x33, +0x80, 0x1e, 0x04, 0x10, 0x90, 0x77, 0xb8, 0x2a, +0x33, 0x40, 0x64, 0x9c, 0xca, 0x48, 0x95, 0x71, +0x8a, 0x0a, 0x08, 0x04, 0x8c, 0x0b, 0x08, 0x2a, +0x20, 0x10, 0x19, 0x05, 0x12, 0xab, 0x17, 0xa4, +0x0f, 0xf4, 0xbd, 0x80, 0x15, 0xe6, 0x45, 0xd1, +0x7a, 0xe4, 0xaf, 0x47, 0x3a, 0x7e, 0x6b, 0x99, +0x61, 0x86, 0x19, 0x66, 0x98, 0x61, 0x86, 0x19, +0xd9, 0x1e, 0xbf, 0x01, 0x5b, 0x58, 0xee, 0x4f, +0xa7, 0x3d, 0xf0, 0xa2, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_gatcher_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_gatcher_png = new wxImage(); + if (!img_ex_gatcher_png || !img_ex_gatcher_png->IsOk()) + { + wxMemoryInputStream img_ex_gatcher_pngIS(ex_gatcher_png_data, sizeof(ex_gatcher_png_data)); + img_ex_gatcher_png->LoadFile(img_ex_gatcher_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_gatcher_png; +} +#define ex_gatcher_png_img ex_gatcher_png_img() + +static wxBitmap *ex_gatcher_png_bmp() +{ + static wxBitmap *bmp_ex_gatcher_png; + if (!bmp_ex_gatcher_png || !bmp_ex_gatcher_png->IsOk()) + bmp_ex_gatcher_png = new wxBitmap(*ex_gatcher_png_img); + return bmp_ex_gatcher_png; +} +#define ex_gatcher_png_bmp ex_gatcher_png_bmp() + +static wxIcon *ex_gatcher_png_ico() +{ + static wxIcon *ico_ex_gatcher_png; + if (!ico_ex_gatcher_png || !ico_ex_gatcher_png->IsOk()) + { + ico_ex_gatcher_png = new wxIcon(); + ico_ex_gatcher_png->CopyFromBitmap(*ex_gatcher_png_bmp); + } + return ico_ex_gatcher_png; +} +#define ex_gatcher_png_ico ex_gatcher_png_ico() + +#endif // EX_GATCHER_PNG_H diff --git a/include/images/ex_gather.png b/include/images/ex_gather.png new file mode 100644 index 0000000..381d00d Binary files /dev/null and b/include/images/ex_gather.png differ diff --git a/include/images/ex_gather.pngc b/include/images/ex_gather.pngc new file mode 100644 index 0000000..751e38f --- /dev/null +++ b/include/images/ex_gather.pngc @@ -0,0 +1,1264 @@ +#ifndef EX_GATHER_PNG_H +#define EX_GATHER_PNG_H + +static const unsigned char ex_gather_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, +0x08, 0x06, 0x00, 0x00, 0x00, 0x9a, 0x76, 0x82, +0x70, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0e, 0xc2, 0x00, 0x00, 0x0e, +0xc2, 0x01, 0x15, 0x28, 0x4a, 0x80, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x50, +0x61, 0x69, 0x6e, 0x74, 0x2e, 0x4e, 0x45, 0x54, +0x20, 0x76, 0x33, 0x2e, 0x35, 0x2e, 0x38, 0x37, +0x3b, 0x80, 0x5d, 0x00, 0x00, 0x25, 0x9a, 0x49, +0x44, 0x41, 0x54, 0x78, 0x5e, 0xed, 0xd7, 0x31, +0x0d, 0x00, 0x00, 0x0c, 0xc3, 0xb0, 0xf1, 0x27, +0xdd, 0xb1, 0xc8, 0xe5, 0x11, 0xa8, 0x64, 0xed, +0xc9, 0xcd, 0x11, 0x20, 0x40, 0x80, 0x00, 0x01, +0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x20, 0x12, +0xb8, 0x68, 0xc7, 0x0c, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, +0x26, 0x40, 0x3c, 0x01, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0x20, 0x40, 0xfc, 0x00, 0x01, 0x02, 0x04, 0x08, +0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x99, +0x80, 0x00, 0xc9, 0xa8, 0x0d, 0x11, 0x20, 0x40, +0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, +0xf0, 0x0e, 0x37, 0x69, 0xd1, 0xd1, 0xd7, 0x23, +0x17, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_gather_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_gather_png = new wxImage(); + if (!img_ex_gather_png || !img_ex_gather_png->IsOk()) + { + wxMemoryInputStream img_ex_gather_pngIS(ex_gather_png_data, sizeof(ex_gather_png_data)); + img_ex_gather_png->LoadFile(img_ex_gather_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_gather_png; +} +#define ex_gather_png_img ex_gather_png_img() + +static wxBitmap *ex_gather_png_bmp() +{ + static wxBitmap *bmp_ex_gather_png; + if (!bmp_ex_gather_png || !bmp_ex_gather_png->IsOk()) + bmp_ex_gather_png = new wxBitmap(*ex_gather_png_img); + return bmp_ex_gather_png; +} +#define ex_gather_png_bmp ex_gather_png_bmp() + +static wxIcon *ex_gather_png_ico() +{ + static wxIcon *ico_ex_gather_png; + if (!ico_ex_gather_png || !ico_ex_gather_png->IsOk()) + { + ico_ex_gather_png = new wxIcon(); + ico_ex_gather_png->CopyFromBitmap(*ex_gather_png_bmp); + } + return ico_ex_gather_png; +} +#define ex_gather_png_ico ex_gather_png_ico() + +#endif // EX_GATHER_PNG_H diff --git a/include/images/ex_gather_motion.png b/include/images/ex_gather_motion.png new file mode 100644 index 0000000..06b7282 Binary files /dev/null and b/include/images/ex_gather_motion.png differ diff --git a/include/images/ex_gather_motion.pngc b/include/images/ex_gather_motion.pngc new file mode 100644 index 0000000..08c2100 --- /dev/null +++ b/include/images/ex_gather_motion.pngc @@ -0,0 +1,72 @@ +#ifndef EX_GATHER_MOTION_PNG_H +#define EX_GATHER_MOTION_PNG_H + +static const unsigned char ex_gather_motion_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x01, 0x00, 0x00, 0x00, 0x00, 0x36, 0x44, 0xb5, +0x1c, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x01, 0xdd, 0x8a, 0x13, 0xa4, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x0e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x18, 0x05, +0x83, 0x09, 0x00, 0x00, 0x01, 0x90, 0x00, 0x01, +0xc5, 0x9b, 0xdb, 0x49, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_gather_motion_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_gather_motion_png = new wxImage(); + if (!img_ex_gather_motion_png || !img_ex_gather_motion_png->IsOk()) + { + wxMemoryInputStream img_ex_gather_motion_pngIS(ex_gather_motion_png_data, sizeof(ex_gather_motion_png_data)); + img_ex_gather_motion_png->LoadFile(img_ex_gather_motion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_gather_motion_png; +} +#define ex_gather_motion_png_img ex_gather_motion_png_img() + +static wxBitmap *ex_gather_motion_png_bmp() +{ + static wxBitmap *bmp_ex_gather_motion_png; + if (!bmp_ex_gather_motion_png || !bmp_ex_gather_motion_png->IsOk()) + bmp_ex_gather_motion_png = new wxBitmap(*ex_gather_motion_png_img); + return bmp_ex_gather_motion_png; +} +#define ex_gather_motion_png_bmp ex_gather_motion_png_bmp() + +static wxIcon *ex_gather_motion_png_ico() +{ + static wxIcon *ico_ex_gather_motion_png; + if (!ico_ex_gather_motion_png || !ico_ex_gather_motion_png->IsOk()) + { + ico_ex_gather_motion_png = new wxIcon(); + ico_ex_gather_motion_png->CopyFromBitmap(*ex_gather_motion_png_bmp); + } + return ico_ex_gather_motion_png; +} +#define ex_gather_motion_png_ico ex_gather_motion_png_ico() + +#endif // EX_GATHER_MOTION_PNG_H diff --git a/include/images/ex_group.png b/include/images/ex_group.png new file mode 100644 index 0000000..8d5de31 Binary files /dev/null and b/include/images/ex_group.png differ diff --git a/include/images/ex_group.pngc b/include/images/ex_group.pngc new file mode 100644 index 0000000..45facda --- /dev/null +++ b/include/images/ex_group.pngc @@ -0,0 +1,198 @@ +#ifndef EX_GROUP_PNG_H +#define EX_GROUP_PNG_H + +static const unsigned char ex_group_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6e, 0xca, 0xec, 0x44, 0xbd, 0xe9, +0x76, 0xce, 0xee, 0x7b, 0xcf, 0xee, 0x4f, 0xc0, +0xe8, 0x55, 0xc2, 0xe9, 0x86, 0xd4, 0xf0, 0x66, +0xc8, 0xec, 0x96, 0xd9, 0xf1, 0x82, 0xd1, 0xed, +0xa6, 0xde, 0xf2, 0x8e, 0xd4, 0xee, 0x92, 0xd6, +0xef, 0xaf, 0xe1, 0xf3, 0x05, 0xa7, 0xe1, 0x1b, +0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, 0xc7, 0xeb, +0x38, 0xb7, 0xe5, 0x6b, 0xc7, 0xe8, 0xb3, 0xc1, +0xa6, 0x7f, 0xa5, 0x5b, 0x52, 0x8d, 0x19, 0x86, +0xa9, 0x64, 0x72, 0x96, 0xa1, 0x84, 0xb1, 0x46, +0xa1, 0xc4, 0x5e, 0xc1, 0x8f, 0x36, 0xf4, 0xf0, +0xc8, 0xf0, 0xec, 0xb7, 0xef, 0xe9, 0xb5, 0xf2, +0xed, 0xc5, 0xed, 0xe5, 0xb1, 0xed, 0xe4, 0xb0, +0xec, 0xe3, 0xb0, 0xf1, 0xea, 0xc3, 0xf0, 0xe8, +0xc2, 0xec, 0xe0, 0xad, 0xeb, 0xde, 0xac, 0xea, +0xdd, 0xab, 0xef, 0xe4, 0xbf, 0x73, 0xa4, 0x36, +0xeb, 0xe6, 0x9f, 0xe9, 0xe0, 0x9a, 0xe8, 0xde, +0x98, 0xee, 0xe6, 0xb3, 0xe6, 0xd9, 0x95, 0xe4, +0xd3, 0x90, 0xe2, 0xd0, 0x8e, 0xe9, 0xda, 0xa9, +0xea, 0xe3, 0x9c, 0xe4, 0xd5, 0x92, 0xe1, 0xcc, +0x8b, 0xe9, 0xd9, 0xa7, 0xe2, 0xce, 0x8c, 0xe8, +0xd7, 0xa6, 0xa2, 0xc7, 0x60, 0xef, 0xe8, 0xb3, +0xed, 0xe1, 0xbc, 0xa6, 0xcc, 0x65, 0xc7, 0xaa, +0x75, 0xf0, 0xe6, 0xc0, 0xe7, 0xd4, 0xa4, 0xe6, +0xd3, 0xa3, 0xec, 0xdd, 0xb9, 0x76, 0xa9, 0x3a, +0x9e, 0xb5, 0x87, 0xe0, 0xca, 0x89, 0xde, 0xc5, +0x85, 0xde, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe6, +0xd1, 0xa1, 0xdf, 0xc8, 0x87, 0xe5, 0xcf, 0xa0, +0xac, 0xd6, 0x6d, 0xdc, 0xbe, 0x80, 0xe4, 0xcd, +0x9e, 0x8b, 0xbe, 0x50, 0xef, 0xe6, 0xc0, 0xeb, +0xd9, 0xb6, 0xb5, 0xe5, 0x7b, 0xe3, 0xcc, 0x9e, +0xe3, 0xcb, 0x9e, 0xbb, 0xef, 0x83, 0xda, 0xbb, +0x7d, 0x7b, 0xb4, 0x43, 0x95, 0xcb, 0x5c, 0x75, +0xa0, 0x4c, 0x67, 0x98, 0x38, 0x8e, 0x85, 0xab, +0x66, 0x6b, 0xd1, 0xcc, 0xcd, 0xf1, 0xbc, 0xbe, +0xec, 0xbe, 0xbf, 0xed, 0xcf, 0xcf, 0xf2, 0xd1, +0xd1, 0xf2, 0xc2, 0xc2, 0xee, 0xc3, 0xc5, 0xef, +0xd3, 0xd4, 0xf3, 0xd5, 0xd5, 0xf4, 0xc8, 0xc8, +0xf0, 0xc9, 0xc9, 0xf1, 0xca, 0xcb, 0xf1, 0xd9, +0xda, 0xf5, 0xde, 0xde, 0xf7, 0xd7, 0xd7, 0xf5, +0xe1, 0xe1, 0xf7, 0xbc, 0xbd, 0xec, 0xa7, 0xa9, +0xe6, 0xa8, 0xaa, 0xe7, 0xbf, 0xbf, 0xee, 0xc0, +0xc2, 0xee, 0xad, 0xaf, 0xe9, 0xaf, 0xb1, 0xe9, +0xc5, 0xc5, 0xef, 0xc7, 0xc8, 0xef, 0xb5, 0xb6, +0xeb, 0xb7, 0xb8, 0xeb, 0xb8, 0xb9, 0xec, 0xcb, +0xcc, 0xf1, 0xce, 0xce, 0xf2, 0xc0, 0xc1, 0xee, +0xd4, 0xd4, 0xf4, 0xc7, 0xc7, 0xf0, 0x92, 0x95, +0xd1, 0xbb, 0x47, 0x69, 0xb4, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x83, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0x69, 0x57, 0xda, 0x40, 0x14, +0x86, 0xd3, 0x01, 0xb7, 0x8a, 0x52, 0x69, 0x5d, +0x42, 0xf5, 0xca, 0x62, 0x30, 0x04, 0x04, 0x22, +0x61, 0x31, 0x8a, 0x35, 0x48, 0x51, 0x20, 0x85, +0x8a, 0x22, 0x76, 0x99, 0x56, 0xb1, 0x55, 0xab, +0xb6, 0xd6, 0xda, 0x7d, 0xfd, 0xeb, 0x9d, 0x09, +0x4b, 0x49, 0x84, 0x73, 0xcc, 0xe9, 0x39, 0x3d, +0xfd, 0xe0, 0x7c, 0xb8, 0x7c, 0xe1, 0xe1, 0xce, +0xf3, 0xe6, 0x0d, 0x0c, 0x73, 0x7d, 0xfe, 0xf5, +0xb9, 0x81, 0xe8, 0xe9, 0x3a, 0x3b, 0x21, 0xc8, +0x62, 0xb5, 0x5a, 0x7b, 0x50, 0x6f, 0x5f, 0x7f, +0xff, 0x00, 0x1a, 0xb8, 0x69, 0xb1, 0x0c, 0xa2, +0xc1, 0x5e, 0x9b, 0x6d, 0x08, 0x0d, 0x0d, 0xdb, +0xed, 0xb7, 0x50, 0x47, 0xc4, 0x3a, 0x32, 0x32, +0x62, 0x45, 0x7d, 0x0e, 0x87, 0xe3, 0x36, 0xba, +0x33, 0x3a, 0x3a, 0x6a, 0x41, 0x3d, 0x04, 0xb7, +0xa1, 0xe1, 0xb1, 0x31, 0x8b, 0x1d, 0xfd, 0xf5, +0x96, 0xf1, 0x09, 0x96, 0x75, 0x32, 0x77, 0xb5, +0x3b, 0x77, 0x9d, 0x06, 0x62, 0x72, 0x6a, 0x8a, +0x65, 0x60, 0xda, 0xe5, 0x72, 0x4d, 0x37, 0xa7, +0xdb, 0xed, 0xf6, 0x80, 0xc7, 0x3b, 0xc3, 0xf9, +0x60, 0x96, 0xf7, 0x0b, 0x01, 0xd0, 0x21, 0x84, +0x08, 0x92, 0x2d, 0xe0, 0x9a, 0x9b, 0x9b, 0x73, +0x35, 0xa6, 0x3b, 0x14, 0x0a, 0x47, 0xc0, 0x2b, +0x8a, 0x22, 0x0f, 0xfe, 0xf9, 0x68, 0x54, 0xd2, +0x23, 0xec, 0x54, 0xd0, 0x49, 0x3e, 0x5a, 0x48, +0x2c, 0xe6, 0x26, 0x48, 0x38, 0xec, 0x05, 0x4e, +0x8c, 0xc7, 0xfd, 0x20, 0x44, 0xa3, 0x89, 0xa4, +0x11, 0x61, 0x99, 0x36, 0x24, 0x46, 0x91, 0x48, +0x38, 0x2c, 0x72, 0xc0, 0xc7, 0xe3, 0xf3, 0x02, +0x48, 0x0b, 0x89, 0x84, 0x6c, 0x40, 0x16, 0xeb, +0x48, 0xcb, 0x62, 0x89, 0x5a, 0x70, 0xd4, 0xc2, +0x2f, 0x10, 0x8b, 0x40, 0x52, 0x96, 0x53, 0x06, +0x64, 0x59, 0x43, 0xee, 0x01, 0x3d, 0x5d, 0x67, +0x3b, 0xe1, 0x0c, 0x4e, 0x3a, 0x9b, 0x5b, 0xdc, +0xd3, 0xe0, 0x89, 0x44, 0xbc, 0x3e, 0xf0, 0xf1, +0x3c, 0xbf, 0x02, 0x01, 0x49, 0x4a, 0xa6, 0x20, +0xa5, 0x28, 0xe9, 0x55, 0xd0, 0x11, 0xcb, 0x99, +0xfb, 0x75, 0x97, 0x58, 0x2c, 0xb4, 0x44, 0x2c, +0x44, 0x71, 0x86, 0x58, 0xcc, 0x53, 0x8b, 0x44, +0x22, 0x2b, 0x83, 0xb2, 0xb6, 0x9e, 0xcb, 0x83, +0xee, 0x5a, 0x19, 0x6d, 0x09, 0x43, 0x83, 0x0d, +0xe9, 0x83, 0x4d, 0x66, 0xb3, 0x05, 0x05, 0xd2, +0xeb, 0xb9, 0x9c, 0xaa, 0xdb, 0x92, 0x79, 0xd0, +0xd8, 0xf2, 0x27, 0x58, 0xbe, 0x11, 0xac, 0x5c, +0x28, 0xac, 0xa5, 0x21, 0x9f, 0xcb, 0x15, 0x4b, +0x3a, 0x7d, 0x67, 0xe6, 0x61, 0xdd, 0xc5, 0x13, +0xf1, 0xce, 0xd0, 0x67, 0xcd, 0xfb, 0x37, 0x88, +0x45, 0x52, 0xb3, 0x48, 0x13, 0x8b, 0x55, 0x55, +0x2d, 0x95, 0x0d, 0x89, 0x6d, 0x9a, 0x4d, 0xac, +0x89, 0x80, 0x8f, 0xe3, 0xf8, 0x59, 0x58, 0x11, +0x04, 0x29, 0x00, 0x29, 0x59, 0x56, 0xc8, 0xef, +0xe7, 0xf3, 0x6a, 0x19, 0xca, 0xa5, 0xad, 0x8a, +0x71, 0xcb, 0x76, 0x1d, 0xe1, 0xe2, 0xf5, 0x7a, +0x2c, 0x68, 0x16, 0x6b, 0x9a, 0x45, 0x91, 0x58, +0x6c, 0x55, 0xab, 0xd5, 0x8a, 0x11, 0xd9, 0xd1, +0x3a, 0xd6, 0xa8, 0x47, 0x5b, 0xb0, 0x6a, 0xb1, +0x58, 0x2d, 0x41, 0xe5, 0x32, 0x32, 0xf1, 0x68, +0x7b, 0x87, 0x36, 0xf9, 0x72, 0xb0, 0xa5, 0x22, +0xfd, 0x72, 0x07, 0x64, 0x9c, 0x30, 0xe4, 0x6e, +0xb0, 0x21, 0x48, 0x12, 0x49, 0x49, 0x56, 0x34, +0x0b, 0x95, 0x5a, 0x6c, 0x51, 0x8b, 0x72, 0xa5, +0x62, 0x74, 0x19, 0x7f, 0xcc, 0xb2, 0xec, 0x13, +0xe6, 0x29, 0xa6, 0xa7, 0xeb, 0x34, 0xbc, 0x62, +0x8b, 0xcb, 0xa4, 0x99, 0xf8, 0xd9, 0xf3, 0xdd, +0xdd, 0x3d, 0x5c, 0xdb, 0xdf, 0x7f, 0xf1, 0x12, +0x1f, 0x1c, 0x1e, 0xbd, 0x3a, 0xc6, 0xc7, 0x7b, +0xb5, 0xda, 0x09, 0x3e, 0x39, 0x38, 0x38, 0x7d, +0x8d, 0x0d, 0xe5, 0x0f, 0xd2, 0x77, 0x1f, 0xbf, +0x39, 0x3b, 0x7b, 0x7b, 0x8e, 0xdf, 0x5d, 0x5c, +0xbc, 0xff, 0x80, 0x3f, 0x7e, 0xfa, 0xfc, 0xe5, +0x2b, 0xfe, 0x76, 0xfe, 0x7d, 0xbf, 0x86, 0x7f, +0xfc, 0x3c, 0x3c, 0x3a, 0x35, 0x22, 0x5a, 0x63, +0x4c, 0x20, 0xcd, 0xf2, 0x5f, 0x1d, 0x69, 0x95, +0xff, 0xea, 0x2e, 0xad, 0xf2, 0xff, 0xd2, 0x92, +0xe9, 0x3a, 0x3b, 0x95, 0xdf, 0x44, 0x62, 0xcd, +0xf2, 0x9b, 0x4a, 0x6c, 0x73, 0xc7, 0x64, 0x62, +0x14, 0x31, 0xfb, 0x5c, 0x68, 0xc5, 0xb6, 0xcd, +0x3d, 0x7d, 0xfa, 0xc7, 0x4f, 0xb6, 0x5c, 0x3d, +0xb1, 0xeb, 0xf3, 0xbf, 0x9d, 0xdf, 0x62, 0xdf, +0x24, 0x3b, 0x36, 0x2f, 0xa7, 0x42, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_group_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_group_png = new wxImage(); + if (!img_ex_group_png || !img_ex_group_png->IsOk()) + { + wxMemoryInputStream img_ex_group_pngIS(ex_group_png_data, sizeof(ex_group_png_data)); + img_ex_group_png->LoadFile(img_ex_group_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_group_png; +} +#define ex_group_png_img ex_group_png_img() + +static wxBitmap *ex_group_png_bmp() +{ + static wxBitmap *bmp_ex_group_png; + if (!bmp_ex_group_png || !bmp_ex_group_png->IsOk()) + bmp_ex_group_png = new wxBitmap(*ex_group_png_img); + return bmp_ex_group_png; +} +#define ex_group_png_bmp ex_group_png_bmp() + +static wxIcon *ex_group_png_ico() +{ + static wxIcon *ico_ex_group_png; + if (!ico_ex_group_png || !ico_ex_group_png->IsOk()) + { + ico_ex_group_png = new wxIcon(); + ico_ex_group_png->CopyFromBitmap(*ex_group_png_bmp); + } + return ico_ex_group_png; +} +#define ex_group_png_ico ex_group_png_ico() + +#endif // EX_GROUP_PNG_H diff --git a/include/images/ex_hash.png b/include/images/ex_hash.png new file mode 100644 index 0000000..9f35c76 Binary files /dev/null and b/include/images/ex_hash.png differ diff --git a/include/images/ex_hash.pngc b/include/images/ex_hash.pngc new file mode 100644 index 0000000..8f3584c --- /dev/null +++ b/include/images/ex_hash.pngc @@ -0,0 +1,191 @@ +#ifndef EX_HASH_PNG_H +#define EX_HASH_PNG_H + +static const unsigned char ex_hash_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x86, 0xa9, 0x64, 0x52, +0x8d, 0x19, 0x75, 0xa6, 0xc7, 0x36, 0x88, 0xc1, +0xa1, 0xc4, 0x5e, 0x6f, 0xcd, 0xee, 0x4f, 0xc1, +0xe9, 0x62, 0xc6, 0xea, 0x77, 0xce, 0xed, 0xa6, +0xde, 0xf2, 0x41, 0xbd, 0xe9, 0x09, 0xa9, 0xe2, +0x2c, 0xb3, 0xe4, 0x49, 0xbc, 0xe6, 0x89, 0xd3, +0xee, 0x6c, 0x84, 0xcd, 0x66, 0x6b, 0xd1, 0xcc, +0xcd, 0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, +0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, 0xa3, 0xc7, +0x61, 0xbc, 0xbd, 0xed, 0xab, 0xac, 0xe8, 0xb3, +0xb4, 0xea, 0xd4, 0xd4, 0xf3, 0xa6, 0xcc, 0x65, +0x46, 0xbf, 0xe9, 0x7e, 0xd1, 0xee, 0xa9, 0xd1, +0x69, 0x8b, 0xd5, 0xf0, 0x91, 0xd7, 0xf0, 0x72, +0xcc, 0xec, 0x7c, 0xce, 0xed, 0xa0, 0xdb, 0xf1, +0x8e, 0xd4, 0xee, 0x93, 0xd5, 0xef, 0xaf, 0xe0, +0xf3, 0x4b, 0xbf, 0xe9, 0xac, 0xd6, 0x6d, 0x65, +0xc8, 0xeb, 0x43, 0xbb, 0xe6, 0x50, 0xbe, 0xe7, +0x6c, 0xc7, 0xe9, 0xae, 0xda, 0x71, 0x92, 0x95, +0xd1, 0x72, 0x96, 0xa1, 0xb2, 0xe0, 0x76, 0xc1, +0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, +0xb4, 0xe4, 0x79, 0xf3, 0xee, 0xc7, 0xef, 0xe8, +0xb3, 0xee, 0xe6, 0xb2, 0xf1, 0xeb, 0xc4, 0xec, +0xe3, 0xb0, 0xec, 0xe1, 0xae, 0xec, 0xe0, 0xad, +0xf0, 0xe7, 0xc1, 0xeb, 0xe6, 0x9e, 0xb7, 0xe8, +0x7d, 0xef, 0xe9, 0xb5, 0xe8, 0xdd, 0x98, 0xe5, +0xd5, 0x92, 0xe4, 0xd3, 0x90, 0xea, 0xdd, 0xac, +0xba, 0xed, 0x81, 0xe6, 0xda, 0x95, 0xec, 0xe2, +0xaf, 0xe3, 0xd1, 0x8e, 0xe9, 0xdc, 0xaa, 0xbc, +0xf0, 0x84, 0xe2, 0xcf, 0x8d, 0xe9, 0xda, 0xa8, +0xeb, 0xe0, 0xad, 0xef, 0xe5, 0xc0, 0xee, 0xe1, +0xbd, 0x9f, 0x4b, 0x64, 0xa9, 0x17, 0x17, 0xc7, +0xaa, 0x75, 0x80, 0x8e, 0x25, 0x75, 0x76, 0x24, +0xb5, 0x53, 0x3e, 0xe3, 0x63, 0x63, 0xe5, 0x43, +0x43, 0xdd, 0x41, 0x41, 0xb9, 0xeb, 0x80, 0x8f, +0x7c, 0x38, 0xef, 0xe4, 0xbf, 0xe8, 0xd7, 0xa7, +0xe7, 0xd6, 0xa5, 0xec, 0xde, 0xbb, 0x86, 0x5b, +0x17, 0xd3, 0x3e, 0x3f, 0xe0, 0xc8, 0x88, 0xdf, +0xc6, 0x86, 0xe6, 0xd4, 0xa4, 0xb0, 0xdd, 0x73, +0xc9, 0x10, 0x11, 0xcc, 0x3c, 0x3c, 0xe1, 0xcc, +0x8a, 0xde, 0xc4, 0x84, 0xe6, 0xd2, 0xa2, 0xbe, +0x0e, 0x0e, 0xc5, 0x3b, 0x3b, 0xe0, 0xc9, 0x88, +0xdd, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe6, 0xd1, +0xa1, 0xcc, 0x5d, 0x5d, 0xe8, 0xd6, 0xa6, 0xec, +0xdd, 0xb9, 0xe6, 0xd1, 0xa2, 0xe5, 0xd0, 0xa1, +0xeb, 0xdb, 0xb7, 0xf0, 0xe8, 0xc2, 0xe6, 0xd3, +0xa4, 0xe4, 0xce, 0xa0, 0xea, 0xd9, 0xb6, 0xdb, +0xbd, 0x7f, 0xda, 0xba, 0x7d, 0xe3, 0xcc, 0x9e, +0xdc, 0xbf, 0x81, 0xe4, 0xcd, 0x9e, 0xe3, 0xcb, +0x9e, 0xde, 0x8c, 0x45, 0xb8, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x48, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x93, 0xeb, 0x5b, 0x12, 0x41, 0x18, +0xc5, 0xf1, 0x75, 0x40, 0x11, 0x52, 0xe9, 0x86, +0x15, 0x4a, 0x37, 0x2d, 0x2a, 0x6f, 0x2f, 0x17, +0x81, 0xb8, 0xdf, 0x04, 0x59, 0xc4, 0x25, 0x03, +0x89, 0x45, 0x12, 0x02, 0x24, 0x11, 0x4b, 0x30, +0x6e, 0x22, 0xff, 0xba, 0xbb, 0x24, 0x06, 0x4b, +0x4b, 0xf8, 0xc9, 0x3e, 0x78, 0x3e, 0xcc, 0x33, +0x33, 0xfb, 0xfc, 0x9e, 0x33, 0xe7, 0xcc, 0xac, +0x48, 0x74, 0xa7, 0xdb, 0xd5, 0x18, 0x8c, 0x09, +0x7e, 0x1b, 0x27, 0x9c, 0xc6, 0x07, 0x08, 0xb1, +0x30, 0x43, 0x24, 0x13, 0x93, 0xd2, 0x29, 0x32, +0x40, 0x88, 0x85, 0x19, 0x22, 0x93, 0xdf, 0x9b, +0x9e, 0xe1, 0x21, 0x1c, 0xc1, 0x32, 0x37, 0x73, +0x61, 0x0f, 0x26, 0xe8, 0x32, 0xab, 0xe0, 0x34, +0xcb, 0xdf, 0x06, 0x41, 0x0f, 0x91, 0x48, 0x71, +0xff, 0xc1, 0xc3, 0x47, 0x8f, 0x15, 0x03, 0x88, +0x72, 0x08, 0x32, 0xf7, 0xe4, 0xe9, 0xdc, 0xb3, +0x6b, 0xe4, 0xaa, 0x40, 0x02, 0x2a, 0x20, 0xdd, +0x39, 0xbf, 0x52, 0x1e, 0x42, 0x24, 0xb2, 0xf9, +0x79, 0x29, 0x59, 0x00, 0x35, 0x3c, 0x27, 0x2f, +0x5e, 0x4a, 0x5f, 0xbd, 0x26, 0x53, 0x8b, 0x8b, +0x4b, 0x6f, 0xc8, 0x10, 0x44, 0x26, 0x97, 0xcb, +0xdf, 0x92, 0x09, 0xd0, 0xc0, 0x3b, 0x22, 0x79, +0x3f, 0xfd, 0x61, 0x81, 0xcc, 0x4c, 0x2e, 0x2f, +0x2f, 0xf5, 0x21, 0xfd, 0x59, 0x58, 0x17, 0x59, +0xc7, 0x65, 0x45, 0xd8, 0x65, 0xb5, 0xd3, 0xd8, +0x6a, 0x77, 0xb9, 0xd6, 0x39, 0xf9, 0x1a, 0x81, +0x75, 0x20, 0xdd, 0x79, 0x67, 0x14, 0x76, 0x41, +0xad, 0x4e, 0xa7, 0xd3, 0xa2, 0x16, 0xf4, 0x60, +0x40, 0xc3, 0x86, 0xd1, 0x68, 0x42, 0x93, 0xf9, +0xa3, 0xc5, 0x8a, 0xc2, 0x59, 0x50, 0x67, 0xb3, +0xd9, 0x74, 0xa8, 0x03, 0x3b, 0x38, 0xd0, 0xe8, +0x74, 0x3a, 0xcd, 0x68, 0x76, 0xb9, 0xdc, 0x9e, +0x7f, 0x23, 0x0e, 0xf0, 0xc2, 0x06, 0x8b, 0xf8, +0x7c, 0x9b, 0x68, 0x71, 0xbb, 0xfd, 0x81, 0x51, +0x90, 0x2d, 0x30, 0xa2, 0xd9, 0xe7, 0x73, 0x59, +0xd0, 0xe3, 0xf7, 0x07, 0x29, 0x1c, 0x9e, 0xc5, +0xc1, 0xa6, 0x60, 0x11, 0x36, 0xc5, 0xa6, 0x25, +0x64, 0xc5, 0xed, 0x00, 0x45, 0x85, 0x7b, 0x91, +0x1d, 0x9a, 0xd3, 0x4e, 0x77, 0x19, 0x41, 0xc4, +0x4f, 0xb0, 0x4b, 0xb3, 0x08, 0xfd, 0x19, 0x39, +0x45, 0x7e, 0x8f, 0x3d, 0x08, 0x1d, 0x8d, 0xc5, +0xf6, 0xa2, 0xf4, 0xb5, 0x8b, 0xc1, 0xe1, 0x80, +0x38, 0x7c, 0x61, 0x91, 0x28, 0x6d, 0xf5, 0x78, +0x02, 0x09, 0x0c, 0x33, 0x4c, 0x72, 0xbf, 0xd7, +0x85, 0x8e, 0xa5, 0x80, 0xaf, 0xb8, 0x17, 0x76, +0x21, 0xf5, 0x95, 0xf6, 0xf8, 0x83, 0x6c, 0x0a, +0xe6, 0x20, 0x9d, 0xce, 0xf4, 0x23, 0x20, 0x56, +0x2a, 0x95, 0x2a, 0x95, 0x5a, 0xad, 0xd1, 0xac, +0x7c, 0x5b, 0xd7, 0xeb, 0xed, 0xf6, 0xb8, 0x77, +0x0b, 0xb2, 0xd9, 0x1c, 0x1d, 0x08, 0xe6, 0xf3, +0x0c, 0x26, 0xd3, 0x87, 0x87, 0x85, 0x3e, 0x64, +0xef, 0xaf, 0x2e, 0xa9, 0xec, 0xf7, 0x23, 0x9a, +0xca, 0xe7, 0x8b, 0x49, 0xcc, 0x1c, 0x1e, 0x97, +0x4e, 0xfa, 0x90, 0x68, 0x2e, 0x77, 0xf4, 0xe3, +0x4f, 0x16, 0x93, 0xd9, 0xcc, 0x65, 0xe9, 0x6c, +0x86, 0x99, 0x9f, 0x6c, 0x8a, 0xd3, 0xf2, 0x49, +0xe5, 0x6c, 0x84, 0xc6, 0x38, 0x09, 0x35, 0xc6, +0xbf, 0x97, 0x5f, 0x96, 0x90, 0x67, 0x1b, 0x13, +0x14, 0xc5, 0x84, 0x71, 0x3f, 0x53, 0x2d, 0x9c, +0xe2, 0x59, 0xad, 0x56, 0xab, 0x0f, 0xbb, 0xfd, +0x90, 0xdb, 0xcf, 0x3e, 0x0f, 0x2a, 0x5f, 0x3c, +0x48, 0x62, 0xf5, 0xb8, 0x54, 0xaa, 0x60, 0xad, +0xd1, 0x68, 0x9e, 0x0f, 0x43, 0xae, 0x8a, 0x2d, +0x72, 0xc5, 0x96, 0x4b, 0xad, 0x56, 0x0d, 0x2f, +0x1a, 0xcd, 0x66, 0x7b, 0x18, 0xd2, 0x5b, 0x6c, +0xa5, 0xd5, 0x6a, 0xd4, 0xf0, 0xbc, 0xc9, 0x47, +0x78, 0x59, 0x12, 0x14, 0xc3, 0xa5, 0xa8, 0x16, +0xca, 0x9d, 0x14, 0x17, 0x75, 0xac, 0xb7, 0xdb, +0xed, 0xbe, 0x2c, 0xbc, 0xbf, 0x32, 0xd2, 0xdb, +0xd2, 0x68, 0x8d, 0x8d, 0x22, 0x5e, 0x96, 0xff, +0x08, 0xb9, 0x79, 0x16, 0x5e, 0x63, 0x77, 0xba, +0x75, 0x5d, 0x02, 0x32, 0xc7, 0xa0, 0xee, 0x46, +0xff, 0x23, 0xa7, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_png = new wxImage(); + if (!img_ex_hash_png || !img_ex_hash_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_pngIS(ex_hash_png_data, sizeof(ex_hash_png_data)); + img_ex_hash_png->LoadFile(img_ex_hash_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_png; +} +#define ex_hash_png_img ex_hash_png_img() + +static wxBitmap *ex_hash_png_bmp() +{ + static wxBitmap *bmp_ex_hash_png; + if (!bmp_ex_hash_png || !bmp_ex_hash_png->IsOk()) + bmp_ex_hash_png = new wxBitmap(*ex_hash_png_img); + return bmp_ex_hash_png; +} +#define ex_hash_png_bmp ex_hash_png_bmp() + +static wxIcon *ex_hash_png_ico() +{ + static wxIcon *ico_ex_hash_png; + if (!ico_ex_hash_png || !ico_ex_hash_png->IsOk()) + { + ico_ex_hash_png = new wxIcon(); + ico_ex_hash_png->CopyFromBitmap(*ex_hash_png_bmp); + } + return ico_ex_hash_png; +} +#define ex_hash_png_ico ex_hash_png_ico() + +#endif // EX_HASH_PNG_H diff --git a/include/images/ex_hash_anti_join.png b/include/images/ex_hash_anti_join.png new file mode 100644 index 0000000..a2a4e93 Binary files /dev/null and b/include/images/ex_hash_anti_join.png differ diff --git a/include/images/ex_hash_anti_join.pngc b/include/images/ex_hash_anti_join.pngc new file mode 100644 index 0000000..78a70c5 --- /dev/null +++ b/include/images/ex_hash_anti_join.pngc @@ -0,0 +1,241 @@ +#ifndef EX_HASH_ANTI_JOIN_PNG_H +#define EX_HASH_ANTI_JOIN_PNG_H + +static const unsigned char ex_hash_anti_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0xd9, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0x89, 0xb9, 0xdb, 0x36, 0x88, 0xc1, +0xa1, 0xc4, 0x5e, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, +0xe9, 0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, +0xde, 0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, +0x2c, 0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, +0xee, 0x74, 0x8b, 0xd5, 0x66, 0x6b, 0xd1, 0xcc, +0xcd, 0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, +0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, 0xa3, 0xc7, +0x61, 0xbc, 0xbd, 0xec, 0xab, 0xac, 0xe8, 0xb3, +0xb4, 0xea, 0xbc, 0xbd, 0xed, 0xd4, 0xd4, 0xf3, +0xa5, 0xcb, 0x64, 0x58, 0x9c, 0xcb, 0x43, 0xbd, +0xe9, 0x47, 0xbf, 0xe9, 0x4b, 0xbf, 0xe9, 0x7b, +0xd1, 0xef, 0x84, 0xd3, 0xf0, 0xa8, 0xd0, 0x68, +0x97, 0xd9, 0xf1, 0xa0, 0xdb, 0xf1, 0x86, 0xd2, +0xee, 0x8c, 0xd4, 0xee, 0x90, 0xd5, 0xee, 0xae, +0xe0, 0xf3, 0x04, 0xa7, 0xe1, 0x09, 0xa9, 0xe2, +0x0f, 0xaa, 0xe2, 0x50, 0xc2, 0xea, 0x5c, 0xc5, +0xeb, 0xab, 0xd5, 0x6c, 0x75, 0xcd, 0xec, 0x81, +0xd0, 0xed, 0x5e, 0xc3, 0xe8, 0x65, 0xc5, 0xe8, +0x6b, 0xc7, 0xe8, 0x94, 0xd6, 0xef, 0xae, 0xda, +0x71, 0xa5, 0xa8, 0xe4, 0x7a, 0x9e, 0xa9, 0xb2, +0xe0, 0x76, 0x62, 0x8a, 0xa3, 0xc1, 0x8f, 0x36, +0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, 0xf4, 0xf0, +0xc8, 0xf3, 0xf0, 0xc8, 0xb5, 0xe5, 0x7a, 0xf3, +0xed, 0xc6, 0xf2, 0xec, 0xc5, 0xed, 0xe6, 0xb1, +0xed, 0xe4, 0xb0, 0xec, 0xe3, 0xb0, 0xf1, 0xea, +0xc3, 0xeb, 0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, +0xeb, 0xb6, 0xef, 0xe9, 0xb5, 0xb8, 0xe9, 0x7e, +0xee, 0xe6, 0xb3, 0xed, 0xe5, 0xb1, 0xe7, 0xda, +0x96, 0xe6, 0xd9, 0x95, 0xe6, 0xd8, 0x94, 0xec, +0xe1, 0xae, 0xf0, 0xec, 0xb6, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9d, 0xef, 0xea, 0xb5, 0xef, 0xe9, +0xb4, 0xba, 0xed, 0x81, 0xe5, 0xd7, 0x93, 0xe5, +0xd6, 0x92, 0xeb, 0xdf, 0xad, 0xea, 0xe3, 0x9c, +0xe9, 0xe2, 0x9c, 0xee, 0xe7, 0xb3, 0xbc, 0xf0, +0x84, 0xe4, 0xd5, 0x91, 0xe4, 0xd3, 0x90, 0xea, +0xdd, 0xab, 0xbf, 0x86, 0x31, 0xb7, 0x84, 0x80, +0xb0, 0x5e, 0x3e, 0xb2, 0x4a, 0x13, 0xb4, 0x61, +0x3f, 0xc4, 0x90, 0x84, 0x70, 0x66, 0xb8, 0xf3, +0xef, 0xc7, 0xef, 0xe8, 0xb3, 0xf2, 0xed, 0xc5, +0xf1, 0xe9, 0xc3, 0xf0, 0xe7, 0xc1, 0xea, 0xdd, +0xaa, 0xe7, 0xd0, 0xa9, 0xb7, 0x60, 0x1b, 0xc9, +0x4d, 0x1a, 0xd7, 0x51, 0x22, 0xe1, 0x54, 0x27, +0x97, 0x54, 0x52, 0xf5, 0xe8, 0xe1, 0xa7, 0x53, +0x6c, 0xa9, 0x17, 0x17, 0xdb, 0xbd, 0x89, 0x80, +0x8e, 0x25, 0x7f, 0x78, 0x2c, 0xbd, 0x5b, 0x46, +0xba, 0x6c, 0x22, 0xe2, 0x54, 0x28, 0xff, 0xff, +0xff, 0xda, 0xa6, 0x8a, 0xee, 0x66, 0x66, 0xe8, +0x44, 0x44, 0xe4, 0x42, 0x43, 0xdf, 0x41, 0x42, +0xe1, 0x62, 0x63, 0xee, 0xe6, 0xb2, 0xb9, 0xeb, +0x80, 0x92, 0x7d, 0x39, 0xef, 0xe4, 0xbf, 0xe9, +0xdb, 0xaa, 0xe9, 0xda, 0xa9, 0xe9, 0xd9, 0xa8, +0xbf, 0x6a, 0x34, 0xc3, 0x70, 0x43, 0xe7, 0x43, +0x44, 0x8b, 0x5c, 0x18, 0x69, 0x79, 0x19, 0x85, +0x5a, 0x16, 0xd3, 0x3e, 0x3f, 0xe1, 0xcd, 0x8b, +0xe1, 0xcb, 0x8a, 0xe0, 0xca, 0x89, 0xb3, 0x4b, +0x11, 0xb4, 0x4c, 0x14, 0xe1, 0x42, 0x42, 0xa2, +0xc6, 0x5f, 0xa4, 0xc9, 0x62, 0xa7, 0xcd, 0x66, +0xaa, 0xd2, 0x6a, 0xad, 0xd7, 0x6f, 0xb0, 0xdd, +0x73, 0xb3, 0xe2, 0x78, 0xb6, 0xe7, 0x7c, 0xbb, +0xef, 0x83, 0xce, 0x12, 0x12, 0xc7, 0x10, 0x10, +0xcc, 0x3c, 0x3c, 0xe9, 0xd9, 0xa7, 0xe0, 0xc9, +0x88, 0xdf, 0xc8, 0x87, 0xbe, 0x67, 0x2f, 0xdb, +0x40, 0x40, 0x84, 0x5a, 0x16, 0xc5, 0x0f, 0x10, +0xbe, 0x0e, 0x0e, 0xc6, 0x3b, 0x3b, 0xe8, 0xd7, +0xa6, 0xdf, 0xc7, 0x86, 0xde, 0xc5, 0x85, 0xcd, +0x8f, 0x5b, 0xdc, 0x61, 0x61, 0xcf, 0x3d, 0x3d, +0xca, 0x3c, 0x3c, 0xc5, 0x3b, 0x3b, 0xcc, 0x5d, +0x5d, 0xf0, 0xe8, 0xc2, 0xec, 0xe0, 0xad, 0xeb, +0xe0, 0xad, 0x8b, 0x7b, 0x37, 0xed, 0xdf, 0xbb, +0xe6, 0xd4, 0xa4, 0xe6, 0xd3, 0xa4, 0xe6, 0xd2, +0xa3, 0xe5, 0xca, 0xa3, 0xb5, 0x8f, 0x70, 0x8b, +0x5a, 0x72, 0xa1, 0x4f, 0x39, 0xb0, 0x48, 0x12, +0xa7, 0x9c, 0xc9, 0xf0, 0xe6, 0xc0, 0xea, 0xdc, +0xaa, 0xee, 0xe3, 0xbe, 0xed, 0xe1, 0xbc, 0xe7, +0xd6, 0xa5, 0xe7, 0xd5, 0xa4, 0xec, 0xde, 0xba, +0xec, 0xdd, 0xb9, 0xe6, 0xd1, 0xa2, 0xe5, 0xd1, +0xa1, 0xe5, 0xcf, 0xa1, 0xeb, 0xda, 0xb7, 0xe2, +0xcf, 0x8d, 0xe2, 0xce, 0x8c, 0xe1, 0xcc, 0x8b, +0xe9, 0xd8, 0xa7, 0xe7, 0xd6, 0xa6, 0xdf, 0xc7, +0x87, 0xde, 0xc6, 0x86, 0xde, 0xc4, 0x85, 0xe6, +0xd1, 0xa1, 0xdc, 0xc0, 0x81, 0xdc, 0xbf, 0x80, +0xdb, 0xbe, 0x80, 0xe4, 0xce, 0x9f, 0xe7, 0xd4, +0xa4, 0xde, 0xc3, 0x84, 0xdd, 0xc2, 0x83, 0xdc, +0xbe, 0x80, 0xdb, 0xbd, 0x7f, 0xdb, 0xbc, 0x7e, +0xe4, 0xcd, 0x9e, 0xe6, 0xd3, 0xa3, 0xdd, 0xc3, +0x83, 0xdd, 0xc2, 0x82, 0xdc, 0xc0, 0x82, 0xda, +0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xe7, 0xd5, 0xa5, +0xe5, 0xd0, 0xa1, 0xe5, 0xcf, 0xa0, 0xeb, 0xd9, +0xb6, 0xe3, 0xcc, 0x9e, 0xea, 0xd8, 0xb6, 0xb5, +0x99, 0x7e, 0x60, 0x30, 0x24, 0x3b, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x7f, 0x48, 0xbf, 0x71, 0xe5, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, +0x74, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, +0x60, 0x18, 0x05, 0x03, 0x0a, 0x18, 0x99, 0x18, +0x71, 0xca, 0x31, 0xb3, 0x80, 0x00, 0x33, 0x86, +0x0e, 0x56, 0xdc, 0x7a, 0x58, 0xd8, 0xd8, 0x39, +0x38, 0xb9, 0x58, 0x30, 0x74, 0xb0, 0xe2, 0xd6, +0xc3, 0xc2, 0xcd, 0xc3, 0xcb, 0xc7, 0x8f, 0xa6, +0x05, 0xa4, 0x03, 0xa8, 0x87, 0x34, 0x5b, 0x80, +0x0e, 0xc3, 0x69, 0x8b, 0x80, 0x20, 0x08, 0x08, +0xa0, 0x0b, 0x33, 0xe1, 0xb4, 0x83, 0x81, 0x41, +0x50, 0x48, 0x58, 0x44, 0x54, 0x4c, 0x10, 0x43, +0x8b, 0x38, 0x1e, 0x2d, 0x12, 0x92, 0x52, 0xd2, +0x32, 0x70, 0x2d, 0xd0, 0x00, 0x64, 0x61, 0x92, +0x65, 0x62, 0x81, 0xb0, 0xe5, 0x30, 0x82, 0x14, +0x4d, 0x0b, 0x0b, 0x9b, 0xbc, 0x82, 0xa2, 0x12, +0x8b, 0x32, 0x93, 0x0a, 0x93, 0x2a, 0x8b, 0x9a, +0xba, 0x86, 0xa6, 0x16, 0xa6, 0x67, 0xd1, 0xb5, +0x70, 0x6b, 0xeb, 0xe8, 0xea, 0xb1, 0xe8, 0x33, +0x19, 0x30, 0x19, 0xb2, 0x18, 0x19, 0x9b, 0x98, +0x9a, 0x61, 0x06, 0x29, 0x9a, 0x5f, 0xe0, 0xb6, +0x98, 0xe3, 0xb6, 0xc5, 0x02, 0x1c, 0x62, 0x16, +0x30, 0xae, 0x25, 0xd8, 0xe5, 0x96, 0x2c, 0x4c, +0x56, 0x4c, 0x2c, 0x10, 0xb6, 0x35, 0x46, 0x90, +0xa2, 0xd9, 0x62, 0x63, 0x6b, 0x67, 0x67, 0x67, +0x6f, 0xe3, 0xc0, 0xe4, 0xc8, 0xe4, 0x64, 0xe3, +0xec, 0xe2, 0xea, 0xe6, 0x6e, 0x83, 0x11, 0xa4, +0x68, 0x7e, 0xb1, 0xb1, 0xf3, 0xf0, 0xf4, 0xf4, +0xb2, 0xf1, 0x66, 0xf2, 0x61, 0xf2, 0xb5, 0xf1, +0xf3, 0x0f, 0x08, 0x0c, 0xb2, 0x41, 0x55, 0x80, +0x45, 0x4b, 0xb0, 0x67, 0x48, 0x68, 0x98, 0x4d, +0x38, 0x53, 0x04, 0x93, 0x9f, 0x8d, 0x5b, 0x60, +0x64, 0x54, 0x34, 0x61, 0x2d, 0x5e, 0x21, 0x31, +0xb1, 0xe1, 0x36, 0x71, 0x4c, 0xf1, 0x4c, 0x6e, +0x36, 0x41, 0x51, 0x09, 0x89, 0x49, 0xc9, 0x29, +0xa9, 0x69, 0xe9, 0x19, 0x99, 0x78, 0xfc, 0x92, +0xe5, 0x1d, 0x9e, 0x9d, 0x63, 0xe3, 0x0c, 0xd4, +0x92, 0x6b, 0x93, 0x17, 0x9d, 0x94, 0x5f, 0x50, +0x58, 0x54, 0x5c, 0x52, 0x5c, 0x54, 0x5a, 0x86, +0xd0, 0x52, 0x5e, 0x01, 0x02, 0xe5, 0x30, 0x6e, +0xa5, 0x8d, 0x8d, 0x4d, 0x15, 0x53, 0x75, 0x05, +0x50, 0x4b, 0x45, 0x0d, 0x90, 0x6d, 0x53, 0x5b, +0x54, 0x57, 0x57, 0x5f, 0x5f, 0x57, 0xd4, 0x80, +0xd0, 0x52, 0xd1, 0xd8, 0xd4, 0xdc, 0xd2, 0x5a, +0x01, 0xb7, 0xc5, 0x29, 0xae, 0x8d, 0xa9, 0x9d, +0xa9, 0x03, 0xa8, 0xa5, 0xb5, 0xa2, 0xb3, 0xab, +0xbb, 0xa7, 0xb7, 0xb8, 0x0e, 0xa4, 0xa7, 0xb8, +0x0f, 0x49, 0x4b, 0xff, 0x04, 0x26, 0x74, 0xd0, +0x1e, 0xc1, 0x34, 0x91, 0x69, 0xd2, 0xe4, 0x8a, +0xee, 0x29, 0x53, 0xa7, 0x4d, 0x2f, 0xa9, 0x07, +0xe9, 0x29, 0x99, 0x81, 0xa4, 0x65, 0x26, 0x13, +0xeb, 0x2c, 0xf1, 0xd9, 0xb2, 0x73, 0x54, 0xe6, +0x1a, 0xcc, 0x33, 0x9f, 0x6f, 0xb5, 0xc0, 0x71, +0xa1, 0x4f, 0x7b, 0xc4, 0x22, 0xa6, 0xc5, 0x4b, +0x96, 0x56, 0x2c, 0x9b, 0xb6, 0x7c, 0xc5, 0xca, +0xe2, 0x7a, 0x90, 0x1e, 0x14, 0x5b, 0x56, 0xad, +0xc6, 0x66, 0xcb, 0xea, 0x35, 0x6b, 0xd7, 0x55, +0xac, 0x5f, 0xb1, 0x61, 0xe3, 0xa6, 0x22, 0x90, +0x57, 0x50, 0xfd, 0xb2, 0x79, 0xcb, 0xd6, 0x6d, +0xdb, 0x11, 0x7e, 0xd9, 0xb1, 0x73, 0x17, 0xd0, +0x2f, 0xbb, 0xc1, 0x82, 0x7b, 0xf6, 0xee, 0xdb, +0x7f, 0x80, 0xe8, 0x10, 0x03, 0x01, 0x70, 0x88, +0xd9, 0x1c, 0x3c, 0x74, 0xf8, 0xc8, 0xe1, 0x43, +0x47, 0xf1, 0xc4, 0xcb, 0xb1, 0xa4, 0xe3, 0x5d, +0x27, 0x6c, 0x4e, 0xae, 0x3f, 0x75, 0xfa, 0x8c, +0xcd, 0xd9, 0x73, 0xe7, 0x2f, 0x5c, 0x24, 0x9c, +0xc6, 0x8e, 0x5f, 0xba, 0x7c, 0xe5, 0xaa, 0xcd, +0xb5, 0xeb, 0x37, 0x6e, 0xee, 0xb7, 0xb9, 0x75, +0xfb, 0xce, 0xdd, 0x7b, 0x84, 0x13, 0x0c, 0x28, +0x60, 0xd7, 0xdb, 0xdc, 0xdf, 0xf8, 0xe0, 0xe1, +0x2d, 0x9b, 0x0b, 0x8f, 0x1e, 0x3f, 0x79, 0x4a, +0x58, 0x0b, 0x28, 0x60, 0xef, 0xdb, 0x3c, 0x7b, +0xfe, 0xe2, 0xe5, 0x05, 0x9b, 0x7b, 0x8f, 0x9f, +0xbc, 0x7a, 0x8d, 0x45, 0x0b, 0x9a, 0x5f, 0x4e, +0x5e, 0x7b, 0xb3, 0x17, 0xe8, 0x8b, 0x5b, 0x6f, +0xdf, 0x5d, 0xb4, 0x79, 0xff, 0xe1, 0xc3, 0xeb, +0x8f, 0x98, 0x7e, 0x41, 0xcb, 0x95, 0x95, 0xe0, +0x50, 0x42, 0x26, 0x3f, 0xa1, 0x2a, 0x60, 0xc0, +0x59, 0x8e, 0xe1, 0x03, 0x82, 0x18, 0x4e, 0x1d, +0x2c, 0x5a, 0x48, 0xf7, 0x8b, 0x05, 0x46, 0x80, +0x8c, 0x82, 0x01, 0x06, 0x00, 0x4d, 0xe2, 0xeb, +0xbe, 0x2f, 0x59, 0xe1, 0xfb, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_anti_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_anti_join_png = new wxImage(); + if (!img_ex_hash_anti_join_png || !img_ex_hash_anti_join_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_anti_join_pngIS(ex_hash_anti_join_png_data, sizeof(ex_hash_anti_join_png_data)); + img_ex_hash_anti_join_png->LoadFile(img_ex_hash_anti_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_anti_join_png; +} +#define ex_hash_anti_join_png_img ex_hash_anti_join_png_img() + +static wxBitmap *ex_hash_anti_join_png_bmp() +{ + static wxBitmap *bmp_ex_hash_anti_join_png; + if (!bmp_ex_hash_anti_join_png || !bmp_ex_hash_anti_join_png->IsOk()) + bmp_ex_hash_anti_join_png = new wxBitmap(*ex_hash_anti_join_png_img); + return bmp_ex_hash_anti_join_png; +} +#define ex_hash_anti_join_png_bmp ex_hash_anti_join_png_bmp() + +static wxIcon *ex_hash_anti_join_png_ico() +{ + static wxIcon *ico_ex_hash_anti_join_png; + if (!ico_ex_hash_anti_join_png || !ico_ex_hash_anti_join_png->IsOk()) + { + ico_ex_hash_anti_join_png = new wxIcon(); + ico_ex_hash_anti_join_png->CopyFromBitmap(*ex_hash_anti_join_png_bmp); + } + return ico_ex_hash_anti_join_png; +} +#define ex_hash_anti_join_png_ico ex_hash_anti_join_png_ico() + +#endif // EX_HASH_ANTI_JOIN_PNG_H diff --git a/include/images/ex_hash_semi_join.png b/include/images/ex_hash_semi_join.png new file mode 100644 index 0000000..0051f99 Binary files /dev/null and b/include/images/ex_hash_semi_join.png differ diff --git a/include/images/ex_hash_semi_join.pngc b/include/images/ex_hash_semi_join.pngc new file mode 100644 index 0000000..502e1c2 --- /dev/null +++ b/include/images/ex_hash_semi_join.pngc @@ -0,0 +1,226 @@ +#ifndef EX_HASH_SEMI_JOIN_PNG_H +#define EX_HASH_SEMI_JOIN_PNG_H + +static const unsigned char ex_hash_semi_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x97, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0x89, 0xb9, 0xdb, 0x36, 0x88, 0xc1, +0xa1, 0xc4, 0x5e, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, +0xe9, 0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, +0xde, 0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, +0x2c, 0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, +0xee, 0x74, 0x8b, 0xd5, 0x66, 0x6b, 0xd1, 0xcc, +0xcd, 0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, +0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, 0xa3, 0xc7, +0x61, 0xbc, 0xbd, 0xec, 0xab, 0xac, 0xe8, 0xb3, +0xb4, 0xea, 0xbc, 0xbd, 0xed, 0xd4, 0xd4, 0xf3, +0x70, 0xab, 0xd3, 0x9a, 0xc3, 0xe0, 0xa5, 0xcb, +0x64, 0xc4, 0xdc, 0xed, 0xb7, 0xe6, 0xf6, 0xa8, +0xd0, 0x68, 0xbd, 0xe8, 0xf7, 0xc1, 0xe9, 0xf7, +0xb0, 0xe3, 0xf5, 0xb3, 0xe3, 0xf5, 0xb6, 0xe5, +0xf5, 0xcb, 0xec, 0xf8, 0xcf, 0xed, 0xf8, 0xc2, +0xe8, 0xf6, 0xc5, 0xe9, 0xf6, 0xc7, 0xea, 0xf6, +0xd6, 0xef, 0xf9, 0x9f, 0xdd, 0xf4, 0xab, 0xd5, +0x6c, 0xa7, 0xe0, 0xf4, 0xad, 0xe2, 0xf5, 0x96, +0xd9, 0xf1, 0x9a, 0xda, 0xf2, 0x9e, 0xdc, 0xf2, +0xba, 0xe6, 0xf5, 0xc0, 0xe7, 0xf6, 0xae, 0xe1, +0xf3, 0xb2, 0xe2, 0xf3, 0xb5, 0xe3, 0xf3, 0xc9, +0xea, 0xf7, 0xae, 0xda, 0x71, 0xa5, 0xa8, 0xe4, +0x7a, 0x9e, 0xa9, 0x72, 0x95, 0x9e, 0xe0, 0xc7, +0x9a, 0xb2, 0xe0, 0x76, 0xd4, 0xd0, 0xbc, 0xc0, +0xc0, 0xd6, 0xb2, 0xb5, 0xe8, 0xba, 0xc5, 0xea, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb7, 0xf9, 0xf8, 0xe4, 0xb5, 0xe5, 0x7a, 0xf9, +0xf7, 0xe3, 0xf9, 0xf6, 0xe3, 0xf7, 0xf3, 0xd9, +0xf6, 0xf3, 0xd9, 0xf6, 0xf2, 0xd8, 0xf8, 0xf5, +0xe1, 0xe5, 0xe6, 0xf8, 0xdf, 0xe0, 0xf6, 0xe2, +0xe3, 0xf7, 0xe6, 0xe6, 0xf8, 0xee, 0xee, 0xfa, +0xeb, 0xe6, 0x9f, 0xf7, 0xf5, 0xda, 0xb8, 0xe9, +0x7e, 0xf7, 0xf4, 0xd9, 0xf3, 0xee, 0xcc, 0xf3, +0xee, 0xcb, 0xf3, 0xed, 0xcb, 0xf6, 0xf1, 0xd7, +0xdd, 0xde, 0xf5, 0xd5, 0xd5, 0xf3, 0xd9, 0xd9, +0xf4, 0xdd, 0xde, 0xf6, 0xe9, 0xe9, 0xf9, 0xf0, +0xec, 0xb6, 0xf7, 0xf4, 0xda, 0xba, 0xed, 0x81, +0xf3, 0xed, 0xca, 0xf2, 0xec, 0xca, 0xf5, 0xf0, +0xd7, 0xeb, 0xe5, 0x9e, 0xea, 0xe4, 0x9d, 0xef, +0xe9, 0xb4, 0xbc, 0xf0, 0x84, 0xf2, 0xec, 0xc9, +0xf2, 0xeb, 0xc9, 0xf5, 0xef, 0xd6, 0xef, 0xeb, +0xb6, 0xef, 0xea, 0xb5, 0xef, 0xe8, 0xb3, 0xf2, +0xec, 0xc5, 0xf9, 0xf6, 0xe2, 0xf8, 0xf4, 0xe1, +0xf7, 0xf3, 0xe0, 0xa7, 0x53, 0x6c, 0xa9, 0x17, +0x17, 0xdb, 0xbd, 0x89, 0x80, 0x8e, 0x25, 0x7d, +0x76, 0x27, 0xc5, 0x69, 0x5e, 0xcb, 0xc6, 0xd9, +0xd2, 0xd3, 0xf1, 0xee, 0x66, 0x66, 0xe8, 0x44, +0x44, 0xe4, 0x42, 0x43, 0xdf, 0x41, 0x42, 0xe1, +0x62, 0x63, 0xf3, 0xed, 0xc6, 0xee, 0xe6, 0xb2, +0xed, 0xe4, 0xb0, 0xb9, 0xeb, 0x80, 0x92, 0x7d, +0x39, 0xf5, 0xee, 0xd5, 0xf4, 0xee, 0xd5, 0xf4, +0xed, 0xd4, 0xf7, 0xf1, 0xdf, 0xe7, 0x43, 0x44, +0x8b, 0x5c, 0x18, 0x69, 0x79, 0x19, 0x85, 0x5a, +0x16, 0xd3, 0x3e, 0x3f, 0xf1, 0xe8, 0xc6, 0xf0, +0xe7, 0xc6, 0xf0, 0xe6, 0xc5, 0xf4, 0xec, 0xd3, +0xe1, 0x42, 0x42, 0xa2, 0xc6, 0x5f, 0xa4, 0xc9, +0x62, 0xa7, 0xcd, 0x66, 0xaa, 0xd2, 0x6a, 0xad, +0xd7, 0x6f, 0xb0, 0xdd, 0x73, 0xb3, 0xe2, 0x78, +0xb6, 0xe7, 0x7c, 0xbb, 0xef, 0x83, 0xce, 0x12, +0x12, 0xc7, 0x10, 0x10, 0xcc, 0x3c, 0x3c, 0xf0, +0xe5, 0xc4, 0xf3, 0xeb, 0xd3, 0xdb, 0x40, 0x40, +0x84, 0x5a, 0x16, 0xc5, 0x0f, 0x10, 0xbe, 0x0e, +0x0e, 0xc6, 0x3b, 0x3b, 0xf4, 0xec, 0xd4, 0xf0, +0xe5, 0xc5, 0xef, 0xe5, 0xc4, 0xef, 0xe4, 0xc3, +0xf3, 0xea, 0xd2, 0xdc, 0x61, 0x61, 0xcf, 0x3d, +0x3d, 0xca, 0x3c, 0x3c, 0xc5, 0x3b, 0x3b, 0xcc, +0x5d, 0x5d, 0xef, 0xe3, 0xbe, 0xe8, 0xd8, 0xa7, +0xe7, 0xd6, 0xa5, 0x8b, 0x7b, 0x37, 0xf6, 0xf0, +0xde, 0xf5, 0xef, 0xdd, 0xec, 0xde, 0xba, 0xe6, +0xd1, 0xa2, 0xe5, 0xd0, 0xa1, 0xe4, 0xce, 0x9f, +0xeb, 0xd9, 0xb6, 0xf6, 0xf0, 0xdd, 0xf6, 0xef, +0xdd, 0xf2, 0xe9, 0xd1, 0xf2, 0xe8, 0xd0, 0xf5, +0xee, 0xdc, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, 0x7e, +0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xef, 0xe4, +0xc4, 0xef, 0xe3, 0xc3, 0xee, 0xe1, 0xc1, 0xee, +0xe0, 0xc1, 0xee, 0xe0, 0xc0, 0xf2, 0xe7, 0xd0, +0xda, 0xbb, 0x7e, 0xda, 0xba, 0x7d, 0xef, 0xe2, +0xc2, 0xed, 0xdf, 0xc0, 0xf2, 0xe6, 0xcf, 0xee, +0xe2, 0xc2, 0xed, 0xde, 0xbf, 0xf1, 0xe6, 0xcf, +0xea, 0xd8, 0xb6, 0xf5, 0xee, 0xdd, 0xf2, 0xe8, +0xd1, 0xf5, 0xed, 0xdb, 0xf1, 0xe6, 0xce, 0xf4, +0xec, 0xda, 0xd3, 0xb0, 0x70, 0xed, 0xde, 0xc4, +0x28, 0xc8, 0x42, 0x88, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x02, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, +0x63, 0x60, 0x18, 0x05, 0x03, 0x0b, 0x18, 0x99, +0x18, 0x71, 0xca, 0x31, 0xb3, 0x80, 0x00, 0x33, +0x86, 0x0e, 0x56, 0xdc, 0x7a, 0x58, 0xd8, 0xd8, +0x39, 0x38, 0xb9, 0x58, 0x30, 0x74, 0xb0, 0xe2, +0xd6, 0xc3, 0xc2, 0xcd, 0xc3, 0xcb, 0xc7, 0x8f, +0xa6, 0x05, 0xa4, 0x03, 0xa8, 0x87, 0x34, 0x5b, +0x80, 0x0e, 0xc3, 0x69, 0x8b, 0x80, 0x20, 0x08, +0x08, 0xa0, 0x0b, 0x33, 0xe1, 0xb4, 0x83, 0x81, +0x41, 0x50, 0x48, 0x58, 0x44, 0x54, 0x4c, 0x10, +0x43, 0x8b, 0x38, 0x1e, 0x2d, 0x12, 0x92, 0x52, +0xd2, 0x32, 0x70, 0x2d, 0x90, 0x00, 0x94, 0x95, +0x63, 0x92, 0x67, 0x92, 0x53, 0x90, 0x03, 0x01, +0x28, 0x89, 0x5b, 0x0b, 0xd4, 0x6b, 0x8a, 0x4c, +0x4a, 0x4c, 0xca, 0x72, 0x2a, 0xaa, 0x6a, 0xea, +0x1a, 0x72, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x72, +0x78, 0xb4, 0x40, 0x02, 0x50, 0x8f, 0x49, 0x9f, +0xc9, 0x40, 0xce, 0xd0, 0xc8, 0xd8, 0xc4, 0x54, +0xce, 0xcc, 0xdc, 0xc2, 0xd2, 0x0a, 0x45, 0x0b, +0xaa, 0x5f, 0xe0, 0xb6, 0x58, 0xe3, 0xb6, 0xc5, +0x06, 0x1c, 0x62, 0x36, 0x30, 0xae, 0x2d, 0xd8, +0x2f, 0x76, 0xf6, 0x4c, 0x0e, 0x4c, 0xf6, 0x8e, +0xf6, 0x20, 0xe0, 0xe4, 0x0c, 0x02, 0x2e, 0xb8, +0x6d, 0x71, 0x75, 0x73, 0x77, 0x77, 0x77, 0x73, +0xf5, 0x60, 0xf2, 0x64, 0xf2, 0xb2, 0xf7, 0xf6, +0xf1, 0xf5, 0xf3, 0x77, 0x0e, 0x08, 0x0c, 0x0a, +0x0e, 0x71, 0xc6, 0xed, 0x17, 0x57, 0xf7, 0xd0, +0xd0, 0x50, 0x77, 0xd7, 0x30, 0xa6, 0x70, 0xa6, +0x08, 0x7b, 0xdf, 0xc8, 0xa8, 0xe8, 0x18, 0xe7, +0xd8, 0xb8, 0xf8, 0x84, 0x44, 0x42, 0x5a, 0x92, +0x5c, 0x93, 0x99, 0x52, 0x98, 0x7c, 0xec, 0xfd, +0xa2, 0x53, 0xd3, 0xd2, 0x89, 0xd1, 0x92, 0x91, +0x99, 0x05, 0xd4, 0x92, 0xcd, 0xe4, 0x67, 0x1f, +0x93, 0x96, 0x93, 0x9b, 0x87, 0x45, 0x0b, 0xba, +0x5f, 0xf2, 0x0b, 0x0a, 0x8b, 0x5c, 0x8b, 0x81, +0x5a, 0xfc, 0xed, 0x4b, 0xd2, 0xf3, 0xf2, 0x4a, +0x31, 0xfd, 0x52, 0x56, 0x0e, 0x02, 0x65, 0x30, +0x6e, 0x85, 0xab, 0xab, 0x6b, 0x25, 0x53, 0x55, +0x39, 0x50, 0x4b, 0x79, 0x35, 0x38, 0xc4, 0x6a, +0xc0, 0x21, 0x56, 0x8b, 0xa4, 0xa5, 0xbc, 0xae, +0xbe, 0xa1, 0xb1, 0xa9, 0x1c, 0x6e, 0x4b, 0x73, +0x4b, 0x2b, 0x53, 0x1b, 0x53, 0x3b, 0x50, 0x4b, +0x53, 0x79, 0x69, 0x47, 0x67, 0x57, 0x37, 0xa6, +0x2d, 0xe5, 0x3d, 0xbd, 0x4c, 0xe8, 0xa0, 0x2d, +0x85, 0xa9, 0x8f, 0xa9, 0x7f, 0x42, 0x79, 0xe7, +0xc4, 0x49, 0x93, 0xa7, 0x60, 0xfa, 0xa5, 0x7c, +0x2a, 0x13, 0xeb, 0x34, 0xf1, 0xe9, 0xf2, 0x33, +0x94, 0x66, 0xea, 0xcf, 0xb2, 0x9e, 0xed, 0x30, +0xc7, 0x73, 0x6e, 0x78, 0x5b, 0xca, 0x3c, 0xa6, +0xf9, 0x0b, 0x16, 0x96, 0x77, 0x4d, 0x9e, 0xbc, +0x68, 0x31, 0x16, 0x2d, 0x4b, 0x96, 0x62, 0xb3, +0x65, 0xe9, 0xb2, 0xe5, 0x2b, 0xca, 0x57, 0xae, +0x5a, 0xbd, 0x66, 0x2d, 0x16, 0x2d, 0xeb, 0xd6, +0x6f, 0xd8, 0xb8, 0x09, 0xe1, 0x97, 0xcd, 0x5b, +0xb6, 0x02, 0xfd, 0xb2, 0x0d, 0x2c, 0xb8, 0x7d, +0xf1, 0xda, 0xb5, 0x3b, 0x88, 0x0e, 0x31, 0x10, +0xc0, 0x15, 0x62, 0xe8, 0xf1, 0xb2, 0x73, 0xd7, +0xee, 0x3d, 0x7b, 0x5d, 0xbb, 0x57, 0x4e, 0x59, +0xbc, 0xcf, 0x7e, 0xff, 0x81, 0x03, 0x07, 0x0f, +0x11, 0x4e, 0x63, 0xbb, 0x0f, 0x1f, 0x39, 0x7a, +0xcc, 0x75, 0xca, 0xa2, 0xe3, 0x27, 0xd6, 0xda, +0x1f, 0x38, 0x79, 0xea, 0xf4, 0x19, 0xc2, 0x09, +0x66, 0xcf, 0xd9, 0x73, 0xe7, 0x8e, 0xb9, 0x2e, +0x5e, 0x73, 0xe2, 0xfc, 0x01, 0xfb, 0x83, 0xa7, +0x2f, 0x5c, 0xb8, 0x48, 0x58, 0xcb, 0xb1, 0x73, +0x20, 0x2d, 0x6b, 0xcf, 0x5f, 0x3a, 0x79, 0xd0, +0xfe, 0xcc, 0x85, 0xcb, 0x97, 0xaf, 0x10, 0x4e, +0x63, 0x57, 0x8f, 0x1d, 0x3b, 0x76, 0xd5, 0xf5, +0xda, 0x81, 0xeb, 0x07, 0x6f, 0xd8, 0xdf, 0xb8, +0x72, 0xe5, 0xe6, 0x2d, 0x4c, 0xbf, 0xa0, 0xe5, +0x4a, 0x50, 0x88, 0xb9, 0xba, 0xde, 0x06, 0x87, +0xd5, 0x1d, 0xe2, 0x42, 0x8c, 0x18, 0x80, 0xe6, +0x97, 0x41, 0xa4, 0x85, 0x74, 0xbf, 0xa0, 0x85, +0xd8, 0x28, 0x18, 0x70, 0x00, 0x00, 0xb0, 0xac, +0xf0, 0xa0, 0x55, 0x10, 0xa4, 0x7c, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_semi_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_semi_join_png = new wxImage(); + if (!img_ex_hash_semi_join_png || !img_ex_hash_semi_join_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_semi_join_pngIS(ex_hash_semi_join_png_data, sizeof(ex_hash_semi_join_png_data)); + img_ex_hash_semi_join_png->LoadFile(img_ex_hash_semi_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_semi_join_png; +} +#define ex_hash_semi_join_png_img ex_hash_semi_join_png_img() + +static wxBitmap *ex_hash_semi_join_png_bmp() +{ + static wxBitmap *bmp_ex_hash_semi_join_png; + if (!bmp_ex_hash_semi_join_png || !bmp_ex_hash_semi_join_png->IsOk()) + bmp_ex_hash_semi_join_png = new wxBitmap(*ex_hash_semi_join_png_img); + return bmp_ex_hash_semi_join_png; +} +#define ex_hash_semi_join_png_bmp ex_hash_semi_join_png_bmp() + +static wxIcon *ex_hash_semi_join_png_ico() +{ + static wxIcon *ico_ex_hash_semi_join_png; + if (!ico_ex_hash_semi_join_png || !ico_ex_hash_semi_join_png->IsOk()) + { + ico_ex_hash_semi_join_png = new wxIcon(); + ico_ex_hash_semi_join_png->CopyFromBitmap(*ex_hash_semi_join_png_bmp); + } + return ico_ex_hash_semi_join_png; +} +#define ex_hash_semi_join_png_ico ex_hash_semi_join_png_ico() + +#endif // EX_HASH_SEMI_JOIN_PNG_H diff --git a/include/images/ex_hash_setop_except.png b/include/images/ex_hash_setop_except.png new file mode 100644 index 0000000..76c546a Binary files /dev/null and b/include/images/ex_hash_setop_except.png differ diff --git a/include/images/ex_hash_setop_except.pngc b/include/images/ex_hash_setop_except.pngc new file mode 100644 index 0000000..f56be8e --- /dev/null +++ b/include/images/ex_hash_setop_except.pngc @@ -0,0 +1,217 @@ +#ifndef EX_HASH_SETOP_EXCEPT_PNG_H +#define EX_HASH_SETOP_EXCEPT_PNG_H + +static const unsigned char ex_hash_setop_except_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x49, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0xa5, 0xa8, 0xe4, 0x45, +0xbe, 0xe9, 0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, +0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, 0x7a, 0xce, +0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, 0xee, 0xad, +0xdf, 0xf3, 0x99, 0xbc, 0x78, 0x52, 0x8d, 0x19, +0x90, 0xb6, 0x6c, 0xd8, 0xe5, 0xcb, 0x07, 0xa8, +0xe2, 0x10, 0xab, 0xe2, 0x1a, 0xae, 0xe3, 0x5d, +0xc5, 0xeb, 0x71, 0xcb, 0xec, 0x4e, 0xbe, 0xe6, +0x5a, 0xc1, 0xe7, 0x64, 0xc5, 0xe8, 0x92, 0xd5, +0xef, 0xa1, 0xc4, 0x5e, 0x84, 0xb0, 0x45, 0x72, +0xa3, 0x35, 0x7a, 0x9e, 0xa9, 0x6a, 0x8f, 0xa6, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb7, 0xf0, 0xec, 0xb6, 0xef, 0xeb, 0xb6, 0xf3, +0xef, 0xc7, 0xa2, 0xc7, 0x60, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xee, 0xe6, +0xb3, 0xa4, 0xca, 0x63, 0xef, 0xea, 0xb6, 0xe9, +0xe1, 0x9b, 0xe8, 0xdf, 0x99, 0xe7, 0xdd, 0x97, +0xec, 0xe3, 0xb0, 0xa7, 0xcd, 0x66, 0xef, 0xe8, +0xb3, 0xe8, 0xde, 0x98, 0xe7, 0xdb, 0x96, 0xe6, +0xd8, 0x94, 0xec, 0xe0, 0xad, 0x97, 0xbb, 0x75, +0x86, 0xb6, 0x49, 0x76, 0xaa, 0x3b, 0xf1, 0xeb, +0xc4, 0xec, 0xe0, 0xae, 0xeb, 0xde, 0xac, 0xef, +0xe4, 0xbf, 0xba, 0xd1, 0xa3, 0xae, 0xda, 0x71, +0x78, 0xae, 0x3e, 0xdb, 0xbd, 0x89, 0xb5, 0x99, +0x7e, 0xb4, 0xe3, 0x79, 0xf0, 0xe6, 0xc0, 0xe9, +0xdc, 0xaa, 0xe9, 0xda, 0xa8, 0xe8, 0xd7, 0xa7, +0xed, 0xdf, 0xbb, 0x7a, 0xb1, 0x41, 0xe9, 0xda, +0xa9, 0xe0, 0xcb, 0x8a, 0xdf, 0xc8, 0x87, 0xde, +0xc5, 0x85, 0xe6, 0xd1, 0xa2, 0x8d, 0xc1, 0x53, +0xe8, 0xd7, 0xa6, 0xdf, 0xc6, 0x86, 0xde, 0xc3, +0x84, 0xdd, 0xc1, 0x82, 0xe5, 0xcf, 0xa0, 0xb6, +0xe7, 0x7c, 0xe6, 0xd4, 0xa4, 0xdd, 0xc2, 0x83, +0xdc, 0xc0, 0x81, 0xdb, 0xbd, 0x7f, 0xe4, 0xcd, +0x9e, 0xb9, 0xeb, 0x7f, 0xeb, 0xdb, 0xb8, 0xe5, +0xce, 0xa0, 0xe3, 0xcc, 0x9e, 0xea, 0xd8, 0xb6, +0xba, 0xee, 0x82, 0x7c, 0xb4, 0x43, 0xbc, 0xf0, +0x84, 0x96, 0xcc, 0x5d, 0xeb, 0xe6, 0x9f, 0xeb, +0xe5, 0x9e, 0xef, 0xe9, 0xb4, 0xf2, 0xe8, 0xd6, +0xe0, 0xc7, 0x9a, 0xd0, 0xab, 0x68, 0xc5, 0x97, +0x44, 0xc7, 0xb4, 0xa5, 0xac, 0xa9, 0xd4, 0x8c, +0x90, 0xdc, 0x71, 0x75, 0xd4, 0xb2, 0xb5, 0xe8, +0xe0, 0xe1, 0xf6, 0xef, 0xea, 0xb5, 0xf2, 0xec, +0xc5, 0xe6, 0xd2, 0xae, 0xd1, 0xac, 0x6a, 0xa8, +0xbc, 0x2f, 0x98, 0xd9, 0x2b, 0x8d, 0xee, 0x27, +0xb7, 0xb1, 0xca, 0x85, 0x81, 0xbf, 0x96, 0x87, +0xa4, 0xc2, 0xb5, 0xb8, 0xf2, 0xf3, 0xfb, 0xd4, +0xd5, 0xf2, 0xa9, 0xac, 0xe5, 0x8e, 0x91, 0xdd, +0xc1, 0xc3, 0xec, 0xd2, 0xad, 0x6c, 0x9a, 0xd6, +0x2b, 0x88, 0xf6, 0x26, 0x7a, 0xbe, 0x6b, 0x8f, +0x92, 0xdd, 0xd0, 0xd1, 0xf1, 0xec, 0xdc, 0xc1, +0xf3, 0xed, 0xc6, 0xee, 0xe6, 0xb2, 0xed, 0xe4, +0xb0, 0xec, 0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0x81, +0xda, 0x49, 0xed, 0xe5, 0xb1, 0xe6, 0xd9, 0x95, +0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, 0xea, 0xdc, +0xaa, 0x77, 0xb0, 0x7c, 0xdc, 0xc0, 0x8e, 0xec, +0xe2, 0xae, 0xe4, 0xd5, 0x91, 0xe3, 0xd2, 0x8f, +0xe2, 0xce, 0x8c, 0xe9, 0xd8, 0xa7, 0xed, 0xdf, +0xc6, 0xe2, 0xd0, 0x8d, 0xe1, 0xcd, 0x8b, 0xe0, +0xca, 0x89, 0xe7, 0xd5, 0xa5, 0xfa, 0xf6, 0xee, +0xef, 0xe3, 0xbe, 0xe8, 0xd8, 0xa7, 0xe7, 0xd6, +0xa5, 0xec, 0xdd, 0xb9, 0xec, 0xde, 0xba, 0xe5, +0xd0, 0xa1, 0xe4, 0xce, 0x9f, 0xeb, 0xd9, 0xb6, +0xdc, 0xbe, 0x80, 0xdb, 0xbc, 0x7e, 0xda, 0xbb, +0x7d, 0xe3, 0xcb, 0x9e, 0xda, 0xbb, 0x7e, 0xda, +0xba, 0x7d, 0x6b, 0x60, 0x9e, 0x1f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x02, 0x4f, 0x49, 0x44, 0x41, 0x54, +0x48, 0xc7, 0x63, 0x60, 0x20, 0x1b, 0x30, 0x32, +0x81, 0x00, 0x23, 0x29, 0x5a, 0x98, 0x98, 0x59, +0x58, 0xd9, 0xd8, 0x99, 0x48, 0xd2, 0xc2, 0xc1, +0xc9, 0xc5, 0xcd, 0x43, 0x9a, 0x16, 0xd2, 0x6d, +0xe1, 0x05, 0xfb, 0x85, 0x97, 0x14, 0x2d, 0x7c, +0xfc, 0x02, 0x82, 0x42, 0xc2, 0x7c, 0x24, 0x69, +0x11, 0x11, 0x15, 0x13, 0x97, 0x18, 0x8c, 0x5a, +0x48, 0xf7, 0x8b, 0x24, 0x1f, 0x08, 0x48, 0x0e, +0x40, 0x88, 0x41, 0xd3, 0x1d, 0xae, 0xd4, 0x87, +0x4d, 0x0b, 0x13, 0xb3, 0x94, 0xb4, 0x8c, 0x2c, +0x93, 0x9c, 0xbc, 0x82, 0xa2, 0x12, 0x13, 0x3e, +0x2d, 0xca, 0x2a, 0x2a, 0xaa, 0x6a, 0x10, 0x2d, +0x1c, 0xea, 0x1a, 0x9a, 0x5a, 0x4c, 0xda, 0x3a, +0xba, 0x7a, 0xfa, 0xd8, 0xb4, 0xc0, 0xfd, 0xa2, +0x62, 0x60, 0x60, 0x08, 0xd1, 0x43, 0xc0, 0x16, +0x44, 0x88, 0x29, 0xab, 0x18, 0x01, 0xf5, 0x80, +0xc4, 0x8c, 0xc1, 0xbe, 0x30, 0xc1, 0x95, 0xfa, +0x90, 0x43, 0x4c, 0xd9, 0xc8, 0x40, 0x05, 0x44, +0x9b, 0x9a, 0x99, 0x5b, 0x58, 0x5a, 0x99, 0xe2, +0x0a, 0x4b, 0x14, 0xef, 0xab, 0x58, 0x43, 0xb4, +0x98, 0xdb, 0xd8, 0xda, 0xd9, 0x9b, 0xe2, 0x4a, +0x17, 0xa8, 0x5a, 0x1c, 0x20, 0x5a, 0x1c, 0x9d, +0x9c, 0x5d, 0x5c, 0x89, 0xd4, 0xe2, 0x06, 0xd1, +0xe2, 0xee, 0xe1, 0xe9, 0xe5, 0x8d, 0x5b, 0x0b, +0xb2, 0x8b, 0x7d, 0x7c, 0xfd, 0x94, 0x41, 0x5a, +0xfc, 0x5d, 0x03, 0x02, 0x83, 0x70, 0xfa, 0x05, +0x25, 0x8d, 0x05, 0xfb, 0x85, 0x84, 0x02, 0xf5, +0x84, 0x99, 0x82, 0x40, 0x38, 0x71, 0xa9, 0x4f, +0x39, 0x34, 0x02, 0xe8, 0x34, 0xd3, 0xc8, 0xa8, +0xe8, 0x98, 0x58, 0x53, 0xa2, 0x52, 0x5f, 0x70, +0x68, 0x44, 0x1c, 0xd0, 0x16, 0xd3, 0xf8, 0x84, +0xc4, 0xa4, 0x64, 0x9c, 0x7e, 0x41, 0x49, 0x7c, +0x3e, 0x29, 0x71, 0x60, 0xbf, 0xa4, 0xa6, 0xa5, +0x67, 0x64, 0xe2, 0xd4, 0x82, 0x52, 0x28, 0xa9, +0x64, 0x41, 0x42, 0x2c, 0x3b, 0x27, 0x37, 0x2f, +0x1f, 0xb7, 0x16, 0xe4, 0xa2, 0x4f, 0xa5, 0x00, +0xa2, 0xa5, 0xb0, 0x28, 0xbf, 0xb8, 0x04, 0xa7, +0x5f, 0x50, 0x6d, 0x29, 0x05, 0x6b, 0x21, 0x10, +0x62, 0x90, 0x24, 0x68, 0x0c, 0x09, 0xaf, 0xb2, +0x72, 0x15, 0x42, 0x61, 0xca, 0x00, 0x4e, 0x82, +0xe6, 0xe6, 0x66, 0xa6, 0x20, 0x0d, 0x2a, 0x65, +0xe5, 0x15, 0xaa, 0xc4, 0x68, 0x31, 0xaf, 0xac, +0xac, 0x34, 0x37, 0x05, 0xbb, 0x0a, 0xa8, 0x43, +0x8d, 0x58, 0x2d, 0x16, 0x10, 0x5b, 0x54, 0x88, +0xd2, 0x01, 0xd2, 0x52, 0x65, 0x53, 0x6d, 0x8a, +0x24, 0x52, 0x53, 0x5b, 0x57, 0x5f, 0x5f, 0xd7, +0xd0, 0xd8, 0xd4, 0xdc, 0xdc, 0xd4, 0xd2, 0x8a, +0xd5, 0x2f, 0x96, 0x6d, 0xee, 0xed, 0x48, 0x5a, +0x3a, 0x3a, 0xbb, 0xba, 0x7b, 0x7a, 0x7a, 0xfb, +0xfa, 0x27, 0x4c, 0x9c, 0x38, 0x69, 0xf2, 0x94, +0xa9, 0x98, 0x5a, 0x20, 0x01, 0x1a, 0x86, 0xd0, +0x31, 0x6d, 0xfa, 0x8c, 0x19, 0x33, 0x66, 0xce, +0x9a, 0x3d, 0x67, 0x5a, 0x07, 0x90, 0x3b, 0x7b, +0x16, 0xa6, 0x1e, 0xd3, 0xb9, 0xf3, 0xe6, 0x2f, +0x58, 0x08, 0xb7, 0xa5, 0xa6, 0x13, 0xa4, 0x63, +0xd1, 0x94, 0xd9, 0x0c, 0x0c, 0x73, 0x3a, 0x6b, +0x40, 0x7a, 0xa6, 0x60, 0xb8, 0xcd, 0x74, 0xf1, +0x92, 0xa5, 0xcb, 0x96, 0xc3, 0xb5, 0xd4, 0x76, +0x01, 0x75, 0xcc, 0x58, 0x31, 0x19, 0xc4, 0x5e, +0x59, 0x0b, 0x22, 0x27, 0xb7, 0x60, 0x68, 0x59, +0xb5, 0x7a, 0xcd, 0xda, 0x75, 0x70, 0x2d, 0x75, +0xdd, 0x20, 0x2d, 0x4d, 0x93, 0x40, 0xec, 0xf5, +0x75, 0x20, 0x72, 0x52, 0x13, 0x86, 0x96, 0xc0, +0x0d, 0x1b, 0x37, 0x6d, 0x86, 0x6b, 0xa9, 0xef, +0x01, 0x69, 0x69, 0x9e, 0x08, 0x62, 0x6f, 0xa9, +0x07, 0x91, 0x13, 0x9b, 0x31, 0xb4, 0x6c, 0xdd, +0xb6, 0x3d, 0x7b, 0x07, 0x49, 0x5a, 0xd0, 0x42, +0x8c, 0x28, 0x87, 0xed, 0x4c, 0xde, 0xb5, 0x7b, +0x0f, 0x69, 0xde, 0xdf, 0xb5, 0x77, 0xdf, 0xfe, +0x03, 0xa4, 0x05, 0xf2, 0xee, 0x83, 0x87, 0x0e, +0x21, 0xb4, 0x10, 0x15, 0x95, 0x07, 0x0e, 0xa1, +0x68, 0x21, 0x22, 0xc1, 0x98, 0x96, 0x1c, 0x38, +0x70, 0xa0, 0x84, 0xa4, 0x64, 0x89, 0x9e, 0xc6, +0xa8, 0x0b, 0x00, 0xa4, 0xa3, 0xdf, 0xbd, 0xfd, +0xcb, 0x1e, 0x7b, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_except_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_except_png = new wxImage(); + if (!img_ex_hash_setop_except_png || !img_ex_hash_setop_except_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_except_pngIS(ex_hash_setop_except_png_data, sizeof(ex_hash_setop_except_png_data)); + img_ex_hash_setop_except_png->LoadFile(img_ex_hash_setop_except_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_except_png; +} +#define ex_hash_setop_except_png_img ex_hash_setop_except_png_img() + +static wxBitmap *ex_hash_setop_except_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_except_png; + if (!bmp_ex_hash_setop_except_png || !bmp_ex_hash_setop_except_png->IsOk()) + bmp_ex_hash_setop_except_png = new wxBitmap(*ex_hash_setop_except_png_img); + return bmp_ex_hash_setop_except_png; +} +#define ex_hash_setop_except_png_bmp ex_hash_setop_except_png_bmp() + +static wxIcon *ex_hash_setop_except_png_ico() +{ + static wxIcon *ico_ex_hash_setop_except_png; + if (!ico_ex_hash_setop_except_png || !ico_ex_hash_setop_except_png->IsOk()) + { + ico_ex_hash_setop_except_png = new wxIcon(); + ico_ex_hash_setop_except_png->CopyFromBitmap(*ex_hash_setop_except_png_bmp); + } + return ico_ex_hash_setop_except_png; +} +#define ex_hash_setop_except_png_ico ex_hash_setop_except_png_ico() + +#endif // EX_HASH_SETOP_EXCEPT_PNG_H diff --git a/include/images/ex_hash_setop_except_all.png b/include/images/ex_hash_setop_except_all.png new file mode 100644 index 0000000..ba24ed1 Binary files /dev/null and b/include/images/ex_hash_setop_except_all.png differ diff --git a/include/images/ex_hash_setop_except_all.pngc b/include/images/ex_hash_setop_except_all.pngc new file mode 100644 index 0000000..c2e1369 --- /dev/null +++ b/include/images/ex_hash_setop_except_all.pngc @@ -0,0 +1,220 @@ +#ifndef EX_HASH_SETOP_EXCEPT_ALL_PNG_H +#define EX_HASH_SETOP_EXCEPT_ALL_PNG_H + +static const unsigned char ex_hash_setop_except_all_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x4c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0x00, 0x00, 0x00, 0xa5, +0xa8, 0xe4, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, +0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, +0xf0, 0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, +0xd4, 0xee, 0xad, 0xdf, 0xf3, 0x99, 0xbc, 0x78, +0x52, 0x8d, 0x19, 0x90, 0xb6, 0x6c, 0xd8, 0xe5, +0xcb, 0x07, 0xa8, 0xe2, 0x10, 0xab, 0xe2, 0x1a, +0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, 0xcb, 0xec, +0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, 0x64, 0xc5, +0xe8, 0x92, 0xd5, 0xef, 0xa1, 0xc4, 0x5e, 0x84, +0xb0, 0x45, 0x72, 0xa3, 0x35, 0x7a, 0x9e, 0xa9, +0x6a, 0x8f, 0xa6, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xf0, 0xec, 0xb6, 0xef, +0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xa2, 0xc7, 0x60, +0xea, 0xe4, 0x9d, 0xea, 0xe3, 0x9c, 0xe9, 0xe0, +0x9a, 0xee, 0xe6, 0xb3, 0xa4, 0xca, 0x63, 0xef, +0xea, 0xb6, 0xe9, 0xe1, 0x9b, 0xe8, 0xdf, 0x99, +0xe7, 0xdd, 0x97, 0xec, 0xe3, 0xb0, 0xa7, 0xcd, +0x66, 0xef, 0xe8, 0xb3, 0xe8, 0xde, 0x98, 0xe7, +0xdb, 0x96, 0xe6, 0xd8, 0x94, 0xec, 0xe0, 0xad, +0x97, 0xbb, 0x75, 0x86, 0xb6, 0x49, 0x76, 0xaa, +0x3b, 0xf1, 0xeb, 0xc4, 0xec, 0xe0, 0xae, 0xeb, +0xde, 0xac, 0xef, 0xe4, 0xbf, 0xba, 0xd1, 0xa3, +0xae, 0xda, 0x71, 0x78, 0xae, 0x3e, 0xdb, 0xbd, +0x89, 0xb5, 0x99, 0x7e, 0xb4, 0xe3, 0x79, 0xf0, +0xe6, 0xc0, 0xe9, 0xdc, 0xaa, 0xe9, 0xda, 0xa8, +0xe8, 0xd7, 0xa7, 0xed, 0xdf, 0xbb, 0x7a, 0xb1, +0x41, 0xe9, 0xda, 0xa9, 0xe0, 0xcb, 0x8a, 0xdf, +0xc8, 0x87, 0xde, 0xc5, 0x85, 0xe6, 0xd1, 0xa2, +0x8d, 0xc1, 0x53, 0xe8, 0xd7, 0xa6, 0xdf, 0xc6, +0x86, 0xde, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe5, +0xcf, 0xa0, 0xb6, 0xe7, 0x7c, 0xe6, 0xd4, 0xa4, +0xdd, 0xc2, 0x83, 0xdc, 0xc0, 0x81, 0xdb, 0xbd, +0x7f, 0xe4, 0xcd, 0x9e, 0xb9, 0xeb, 0x7f, 0xeb, +0xdb, 0xb8, 0xe5, 0xce, 0xa0, 0xe3, 0xcc, 0x9e, +0xea, 0xd8, 0xb6, 0xba, 0xee, 0x82, 0x7c, 0xb4, +0x43, 0xbc, 0xf0, 0x84, 0x96, 0xcc, 0x5d, 0xeb, +0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, 0xe9, 0xb4, +0xf2, 0xe8, 0xd6, 0xe0, 0xc7, 0x9a, 0xd0, 0xab, +0x68, 0xc5, 0x97, 0x44, 0xc7, 0xb4, 0xa5, 0xac, +0xa9, 0xd4, 0x8c, 0x90, 0xdc, 0x71, 0x75, 0xd4, +0xb2, 0xb5, 0xe8, 0xe0, 0xe1, 0xf6, 0xef, 0xea, +0xb5, 0xf2, 0xec, 0xc5, 0xe6, 0xd2, 0xae, 0xd1, +0xac, 0x6a, 0xa8, 0xbc, 0x2f, 0x98, 0xd9, 0x2b, +0x8d, 0xee, 0x27, 0xb7, 0xb1, 0xca, 0x85, 0x81, +0xbf, 0x96, 0x87, 0xa4, 0xc2, 0xb5, 0xb8, 0xf2, +0xf3, 0xfb, 0xd4, 0xd5, 0xf2, 0xa9, 0xac, 0xe5, +0x8e, 0x91, 0xdd, 0xc1, 0xc3, 0xec, 0xd2, 0xad, +0x6c, 0x9a, 0xd6, 0x2b, 0x88, 0xf6, 0x26, 0x7a, +0xbe, 0x6b, 0x8f, 0x92, 0xdd, 0xd0, 0xd1, 0xf1, +0xec, 0xdc, 0xc1, 0xf3, 0xed, 0xc6, 0xee, 0xe6, +0xb2, 0xed, 0xe4, 0xb0, 0xec, 0xe2, 0xaf, 0xf0, +0xe7, 0xc1, 0x81, 0xda, 0x49, 0xed, 0xe5, 0xb1, +0xe6, 0xd9, 0x95, 0xe5, 0xd6, 0x93, 0xe4, 0xd3, +0x90, 0xea, 0xdc, 0xaa, 0x77, 0xb0, 0x7c, 0xdc, +0xc0, 0x8e, 0xec, 0xe2, 0xae, 0xe4, 0xd5, 0x91, +0xe3, 0xd2, 0x8f, 0xe2, 0xce, 0x8c, 0xe9, 0xd8, +0xa7, 0xed, 0xdf, 0xc6, 0xe2, 0xd0, 0x8d, 0xe1, +0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe7, 0xd5, 0xa5, +0xfa, 0xf6, 0xee, 0xef, 0xe3, 0xbe, 0xe8, 0xd8, +0xa7, 0xe7, 0xd6, 0xa5, 0xec, 0xdd, 0xb9, 0xec, +0xde, 0xba, 0xe5, 0xd0, 0xa1, 0xe4, 0xce, 0x9f, +0xeb, 0xd9, 0xb6, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xda, +0xbb, 0x7e, 0xda, 0xba, 0x7d, 0x36, 0x98, 0x2a, +0xe2, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x65, 0x49, +0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, 0x20, +0x1b, 0x30, 0x32, 0x81, 0x00, 0x23, 0x29, 0x5a, +0x98, 0x98, 0x59, 0x58, 0xd9, 0xd8, 0x99, 0x48, +0xd2, 0xc2, 0xc1, 0xc9, 0xc5, 0xcd, 0x43, 0x9a, +0x16, 0xd2, 0x6d, 0xe1, 0x05, 0xfb, 0x85, 0x97, +0x14, 0x2d, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, +0x7c, 0x24, 0x69, 0x11, 0x11, 0x15, 0x13, 0x97, +0x18, 0x8c, 0x5a, 0x60, 0x7e, 0x91, 0x94, 0x94, +0x64, 0x90, 0x64, 0x00, 0x21, 0x42, 0x40, 0x8a, +0x0f, 0x04, 0xa4, 0x40, 0x6a, 0x89, 0xd5, 0x42, +0x86, 0x2d, 0x70, 0xbf, 0x80, 0x6d, 0x01, 0x23, +0x58, 0xba, 0xc3, 0x95, 0xfa, 0xb0, 0x79, 0x9f, +0x89, 0x59, 0x5a, 0x46, 0x56, 0x8e, 0x49, 0x5e, +0x41, 0x51, 0x49, 0x99, 0x09, 0x9f, 0x16, 0x15, +0x55, 0x55, 0x35, 0x75, 0x88, 0x16, 0x0e, 0x0d, +0x4d, 0x2d, 0x6d, 0x26, 0x1d, 0x5d, 0x3d, 0x7d, +0x03, 0x6c, 0x5a, 0xe0, 0xb1, 0xaf, 0x6a, 0x68, +0x68, 0x04, 0xd1, 0x43, 0xc0, 0x16, 0x78, 0x88, +0x01, 0x6d, 0x31, 0x06, 0xea, 0x01, 0x89, 0x99, +0x80, 0x7d, 0x61, 0x8a, 0x2b, 0xf5, 0x21, 0xa7, +0x31, 0x15, 0x63, 0x43, 0x55, 0x10, 0x6d, 0x66, +0x6e, 0x61, 0x69, 0x65, 0x6d, 0x86, 0x2b, 0xf5, +0xa1, 0x78, 0x5f, 0xd5, 0x06, 0xa2, 0xc5, 0xc2, +0xd6, 0xce, 0xde, 0xc1, 0x0c, 0x57, 0xba, 0x40, +0xd5, 0xe2, 0x08, 0xd1, 0xe2, 0xe4, 0xec, 0xe2, +0xea, 0x46, 0xa4, 0x16, 0x77, 0x88, 0x16, 0x0f, +0x4f, 0x2f, 0x6f, 0x1f, 0xdc, 0x5a, 0x90, 0x5d, +0xec, 0xeb, 0xe7, 0xaf, 0x02, 0xd2, 0x12, 0xe0, +0x16, 0x18, 0x14, 0x8c, 0xd3, 0x2f, 0x88, 0x10, +0x03, 0x82, 0x10, 0xff, 0xd0, 0x30, 0xa0, 0x9e, +0x70, 0x33, 0x10, 0x88, 0x40, 0x96, 0xc1, 0x0d, +0x54, 0xc2, 0x22, 0x81, 0x4e, 0x33, 0x8b, 0x8a, +0x8e, 0x89, 0x8d, 0x33, 0x23, 0x2a, 0xbf, 0x86, +0x84, 0x45, 0xc6, 0x03, 0x6d, 0x31, 0x4b, 0x48, +0x4c, 0x4a, 0x4e, 0xc1, 0xe9, 0x17, 0x94, 0xc4, +0xe7, 0x9b, 0x1a, 0x0f, 0xf6, 0x4b, 0x5a, 0x7a, +0x46, 0x66, 0x16, 0x4e, 0x2d, 0x28, 0x85, 0x92, +0x6a, 0x36, 0x24, 0xc4, 0x72, 0x72, 0xf3, 0xf2, +0x0b, 0x70, 0x6b, 0x41, 0x2e, 0xfa, 0x54, 0x0b, +0x21, 0x5a, 0x8a, 0x8a, 0x0b, 0x4a, 0x4a, 0x71, +0xfa, 0x05, 0xd5, 0x96, 0x32, 0xb0, 0x16, 0x02, +0x21, 0x06, 0x49, 0x82, 0x26, 0x90, 0xf0, 0x2a, +0xaf, 0x50, 0x25, 0x14, 0xa6, 0x0c, 0xe0, 0x24, +0x68, 0x61, 0x61, 0x6e, 0x06, 0xd2, 0xa0, 0x5a, +0x5e, 0x51, 0xa9, 0x46, 0x8c, 0x16, 0x8b, 0xaa, +0xaa, 0x2a, 0x0b, 0x33, 0xb0, 0xab, 0x80, 0x3a, +0xd4, 0x89, 0xd5, 0x62, 0x09, 0xb1, 0x45, 0x95, +0x28, 0x1d, 0x20, 0x2d, 0xd5, 0xb6, 0x35, 0x66, +0x48, 0x22, 0xb5, 0x75, 0xf5, 0x0d, 0x0d, 0xf5, +0x8d, 0x4d, 0xcd, 0x2d, 0x2d, 0xcd, 0xad, 0x6d, +0x58, 0xfd, 0x62, 0xd5, 0xee, 0xd1, 0x81, 0xa4, +0xa5, 0xb3, 0xab, 0xbb, 0xa7, 0xb7, 0xb7, 0xaf, +0x7f, 0xc2, 0xc4, 0x49, 0x93, 0x26, 0x4f, 0x99, +0x3a, 0x0d, 0x53, 0x0b, 0x24, 0x40, 0xc3, 0x11, +0x3a, 0xa6, 0xcf, 0x98, 0x39, 0x73, 0xe6, 0xac, +0xd9, 0x73, 0xe6, 0x4e, 0xef, 0x04, 0x72, 0xe7, +0xcc, 0xc6, 0xd4, 0x63, 0x36, 0x6f, 0xfe, 0x82, +0x85, 0x8b, 0xe0, 0xb6, 0xd4, 0x76, 0x81, 0x74, +0x2c, 0x9e, 0x3a, 0x87, 0x81, 0x61, 0x6e, 0x57, +0x2d, 0x48, 0xcf, 0x54, 0x0c, 0xb7, 0x99, 0x2d, +0x59, 0xba, 0x6c, 0xf9, 0x0a, 0xb8, 0x96, 0xba, +0x6e, 0xa0, 0x8e, 0x99, 0x2b, 0xa7, 0x80, 0xd8, +0xab, 0xea, 0x40, 0xe4, 0x94, 0x56, 0x0c, 0x2d, +0xab, 0xd7, 0xac, 0x5d, 0xb7, 0x1e, 0xae, 0xa5, +0xbe, 0x07, 0xa4, 0xa5, 0x79, 0x32, 0x88, 0xbd, +0xa1, 0x1e, 0x44, 0x4e, 0x6e, 0xc6, 0xd0, 0x12, +0xb4, 0x71, 0xd3, 0xe6, 0x2d, 0x70, 0x2d, 0x0d, +0xbd, 0x20, 0x2d, 0x2d, 0x93, 0x40, 0xec, 0xad, +0x0d, 0x20, 0x72, 0x52, 0x0b, 0x86, 0x96, 0x6d, +0xdb, 0x77, 0xe4, 0xec, 0x24, 0x49, 0x0b, 0x5a, +0x88, 0x11, 0xe5, 0xb0, 0x5d, 0x29, 0xbb, 0xf7, +0xec, 0x25, 0xcd, 0xfb, 0xbb, 0xf7, 0xed, 0x3f, +0x70, 0x90, 0xb4, 0x40, 0xde, 0x73, 0xe8, 0xf0, +0x61, 0x84, 0x16, 0xa2, 0xa2, 0xf2, 0xe0, 0x61, +0x14, 0x2d, 0x44, 0x24, 0x18, 0xb3, 0xd2, 0x83, +0x07, 0x0f, 0x96, 0x92, 0x94, 0x2c, 0xd1, 0xd3, +0x18, 0x75, 0x01, 0x00, 0x16, 0x1b, 0xe3, 0xbc, +0x97, 0x09, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_except_all_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_except_all_png = new wxImage(); + if (!img_ex_hash_setop_except_all_png || !img_ex_hash_setop_except_all_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_except_all_pngIS(ex_hash_setop_except_all_png_data, sizeof(ex_hash_setop_except_all_png_data)); + img_ex_hash_setop_except_all_png->LoadFile(img_ex_hash_setop_except_all_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_except_all_png; +} +#define ex_hash_setop_except_all_png_img ex_hash_setop_except_all_png_img() + +static wxBitmap *ex_hash_setop_except_all_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_except_all_png; + if (!bmp_ex_hash_setop_except_all_png || !bmp_ex_hash_setop_except_all_png->IsOk()) + bmp_ex_hash_setop_except_all_png = new wxBitmap(*ex_hash_setop_except_all_png_img); + return bmp_ex_hash_setop_except_all_png; +} +#define ex_hash_setop_except_all_png_bmp ex_hash_setop_except_all_png_bmp() + +static wxIcon *ex_hash_setop_except_all_png_ico() +{ + static wxIcon *ico_ex_hash_setop_except_all_png; + if (!ico_ex_hash_setop_except_all_png || !ico_ex_hash_setop_except_all_png->IsOk()) + { + ico_ex_hash_setop_except_all_png = new wxIcon(); + ico_ex_hash_setop_except_all_png->CopyFromBitmap(*ex_hash_setop_except_all_png_bmp); + } + return ico_ex_hash_setop_except_all_png; +} +#define ex_hash_setop_except_all_png_ico ex_hash_setop_except_all_png_ico() + +#endif // EX_HASH_SETOP_EXCEPT_ALL_PNG_H diff --git a/include/images/ex_hash_setop_intersect.png b/include/images/ex_hash_setop_intersect.png new file mode 100644 index 0000000..fb536b1 Binary files /dev/null and b/include/images/ex_hash_setop_intersect.png differ diff --git a/include/images/ex_hash_setop_intersect.pngc b/include/images/ex_hash_setop_intersect.pngc new file mode 100644 index 0000000..2330758 --- /dev/null +++ b/include/images/ex_hash_setop_intersect.pngc @@ -0,0 +1,218 @@ +#ifndef EX_HASH_SETOP_INTERSECT_PNG_H +#define EX_HASH_SETOP_INTERSECT_PNG_H + +static const unsigned char ex_hash_setop_intersect_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x52, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0xa5, 0xa8, 0xe4, 0x45, +0xbe, 0xe9, 0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, +0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, 0x7a, 0xce, +0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, 0xee, 0xad, +0xdf, 0xf3, 0x99, 0xbc, 0x78, 0x52, 0x8d, 0x19, +0x90, 0xb6, 0x6c, 0xd8, 0xe5, 0xcb, 0x07, 0xa8, +0xe2, 0x10, 0xab, 0xe2, 0x1a, 0xae, 0xe3, 0x5d, +0xc5, 0xeb, 0x71, 0xcb, 0xec, 0x4e, 0xbe, 0xe6, +0x5a, 0xc1, 0xe7, 0x64, 0xc5, 0xe8, 0x92, 0xd5, +0xef, 0xa1, 0xc4, 0x5e, 0x84, 0xb0, 0x45, 0x72, +0xa3, 0x35, 0x7a, 0x9e, 0xa9, 0x6a, 0x8f, 0xa6, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb7, 0xf0, 0xec, 0xb6, 0xef, 0xeb, 0xb6, 0xf3, +0xef, 0xc7, 0xa2, 0xc7, 0x60, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xee, 0xe6, +0xb3, 0xa4, 0xca, 0x63, 0xef, 0xea, 0xb6, 0xe9, +0xe1, 0x9b, 0xe8, 0xdf, 0x99, 0xe7, 0xdd, 0x97, +0xec, 0xe3, 0xb0, 0xa7, 0xcd, 0x66, 0xef, 0xe8, +0xb3, 0xe8, 0xde, 0x98, 0xe7, 0xdb, 0x96, 0xe6, +0xd8, 0x94, 0xec, 0xe0, 0xad, 0x97, 0xbb, 0x75, +0x86, 0xb6, 0x49, 0x76, 0xaa, 0x3b, 0xf1, 0xeb, +0xc4, 0xec, 0xe0, 0xae, 0xeb, 0xde, 0xac, 0xef, +0xe4, 0xbf, 0xba, 0xd1, 0xa3, 0xae, 0xda, 0x71, +0x78, 0xae, 0x3e, 0xdb, 0xbd, 0x89, 0xb5, 0x99, +0x7e, 0xb4, 0xe3, 0x79, 0xf0, 0xe6, 0xc0, 0xe9, +0xdc, 0xaa, 0xe9, 0xda, 0xa8, 0xe8, 0xd7, 0xa7, +0xed, 0xdf, 0xbb, 0x7a, 0xb1, 0x41, 0xe9, 0xda, +0xa9, 0xe0, 0xcb, 0x8a, 0xdf, 0xc8, 0x87, 0xde, +0xc5, 0x85, 0xe6, 0xd1, 0xa2, 0x8d, 0xc1, 0x53, +0xe8, 0xd7, 0xa6, 0xdf, 0xc6, 0x86, 0xde, 0xc3, +0x84, 0xdd, 0xc1, 0x82, 0xe5, 0xcf, 0xa0, 0xb6, +0xe7, 0x7c, 0xe6, 0xd4, 0xa4, 0xdd, 0xc2, 0x83, +0xdc, 0xc0, 0x81, 0xdb, 0xbd, 0x7f, 0xe4, 0xcd, +0x9e, 0xb9, 0xeb, 0x7f, 0xeb, 0xdb, 0xb8, 0xe5, +0xce, 0xa0, 0xe3, 0xcc, 0x9e, 0xea, 0xd8, 0xb6, +0xba, 0xee, 0x82, 0x7c, 0xb4, 0x43, 0xbc, 0xf0, +0x84, 0x96, 0xcc, 0x5d, 0xeb, 0xe6, 0x9f, 0xeb, +0xe5, 0x9e, 0xef, 0xe9, 0xb4, 0xf2, 0xe8, 0xd6, +0xe0, 0xc7, 0x9a, 0xd0, 0xab, 0x68, 0xc5, 0x97, +0x44, 0xc7, 0xb4, 0xa5, 0xac, 0xa9, 0xd4, 0x8c, +0x90, 0xdc, 0x71, 0x75, 0xd4, 0xb2, 0xb5, 0xe8, +0xe0, 0xe1, 0xf6, 0xef, 0xea, 0xb5, 0xf2, 0xec, +0xc5, 0xe6, 0xd2, 0xae, 0xd1, 0xac, 0x6a, 0xdc, +0xc0, 0x8e, 0xed, 0xdf, 0xc6, 0xfa, 0xf6, 0xee, +0xb7, 0xb1, 0xca, 0x77, 0x80, 0xa7, 0x87, 0x87, +0x8b, 0xc2, 0xb5, 0xb8, 0xf2, 0xf3, 0xfb, 0xd4, +0xd5, 0xf2, 0xa9, 0xac, 0xe5, 0x8e, 0x91, 0xdd, +0xc1, 0xc3, 0xec, 0xd2, 0xad, 0x6c, 0xec, 0xdc, +0xc1, 0x8f, 0x92, 0xdd, 0x7d, 0xcb, 0x5b, 0x9a, +0xd6, 0x2b, 0xd0, 0xd1, 0xf1, 0xf3, 0xed, 0xc6, +0xee, 0xe6, 0xb2, 0xed, 0xe4, 0xb0, 0xec, 0xe2, +0xaf, 0xf0, 0xe7, 0xc1, 0x88, 0xf6, 0x26, 0xed, +0xe5, 0xb1, 0xe6, 0xd9, 0x95, 0xe5, 0xd6, 0x93, +0xe4, 0xd3, 0x90, 0xea, 0xdc, 0xaa, 0x75, 0xa8, +0x86, 0xa8, 0xbc, 0x2f, 0xec, 0xe2, 0xae, 0xe4, +0xd5, 0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xce, 0x8c, +0xe9, 0xd8, 0xa7, 0x7e, 0xcf, 0x56, 0x98, 0xd9, +0x2b, 0xe2, 0xd0, 0x8d, 0xe1, 0xcd, 0x8b, 0xe0, +0xca, 0x89, 0xe7, 0xd5, 0xa5, 0x85, 0xeb, 0x34, +0x8d, 0xee, 0x27, 0xef, 0xe3, 0xbe, 0xe8, 0xd8, +0xa7, 0xe7, 0xd6, 0xa5, 0xec, 0xdd, 0xb9, 0xec, +0xde, 0xba, 0xe5, 0xd0, 0xa1, 0xe4, 0xce, 0x9f, +0xeb, 0xd9, 0xb6, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xda, +0xbb, 0x7e, 0xda, 0xba, 0x7d, 0x85, 0x81, 0xbf, +0x96, 0x87, 0xa4, 0xd1, 0xe0, 0x0d, 0xfe, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x02, 0x52, 0x49, 0x44, 0x41, +0x54, 0x48, 0xc7, 0x63, 0x60, 0x20, 0x1b, 0x30, +0x32, 0x81, 0x00, 0x23, 0x29, 0x5a, 0x98, 0x98, +0x59, 0x58, 0xd9, 0xd8, 0x99, 0x48, 0xd2, 0xc2, +0xc1, 0xc9, 0xc5, 0xcd, 0x43, 0x9a, 0x16, 0xd2, +0x6d, 0xe1, 0x05, 0xfb, 0x85, 0x97, 0x14, 0x2d, +0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x7c, 0x24, +0x69, 0x11, 0x11, 0x15, 0x13, 0x97, 0x18, 0x8c, +0x5a, 0x48, 0xf7, 0x8b, 0x24, 0x1f, 0x08, 0x48, +0x0e, 0x40, 0x88, 0x41, 0xd3, 0x1d, 0xae, 0xd4, +0x87, 0x4d, 0x0b, 0x13, 0xb3, 0x94, 0xb4, 0x8c, +0x2c, 0x93, 0x9c, 0xbc, 0x82, 0xa2, 0x12, 0x13, +0x3e, 0x2d, 0xca, 0x2a, 0x2a, 0xaa, 0x6a, 0x10, +0x2d, 0x1c, 0xea, 0x1a, 0x9a, 0x5a, 0x4c, 0xda, +0x3a, 0xba, 0x7a, 0xfa, 0xd8, 0xb4, 0xc0, 0xfd, +0xa2, 0x62, 0x60, 0x60, 0x08, 0xd1, 0x43, 0xc0, +0x16, 0x44, 0x88, 0x29, 0xab, 0x18, 0x01, 0xf5, +0x80, 0xc4, 0x8c, 0xc1, 0xbe, 0x30, 0xc1, 0x95, +0xfa, 0x90, 0x43, 0x4c, 0xd9, 0xc8, 0x40, 0x05, +0x44, 0x9b, 0x9a, 0x99, 0x5b, 0x58, 0x5a, 0x99, +0xe2, 0x0a, 0x4b, 0x14, 0xef, 0xab, 0x58, 0x43, +0xb4, 0x98, 0xdb, 0xd8, 0xda, 0xd9, 0x9b, 0xe2, +0x4a, 0x17, 0xa8, 0x5a, 0x1c, 0x20, 0x5a, 0x1c, +0x9d, 0x9c, 0x5d, 0x5c, 0x89, 0xd4, 0xe2, 0x06, +0xd1, 0xe2, 0xee, 0xe1, 0xe9, 0xe5, 0x8d, 0x5b, +0x0b, 0xb2, 0x8b, 0x7d, 0x7c, 0xfd, 0x94, 0x41, +0x5a, 0xfc, 0x5d, 0x03, 0x02, 0x83, 0x70, 0xfa, +0x05, 0x25, 0x8d, 0x05, 0xfb, 0x85, 0x84, 0x02, +0xf5, 0x84, 0x99, 0x82, 0x40, 0x38, 0x71, 0xa9, +0x4f, 0x39, 0x34, 0x02, 0xe8, 0x34, 0xd3, 0xc8, +0xa8, 0xe8, 0x98, 0x58, 0x53, 0xa2, 0x52, 0x5f, +0x70, 0x68, 0x44, 0x1c, 0xd0, 0x16, 0xd3, 0xf8, +0x84, 0xc4, 0xa4, 0x64, 0x9c, 0x7e, 0x41, 0x49, +0x7c, 0x3e, 0x29, 0x71, 0x60, 0xbf, 0xa4, 0xa6, +0xa5, 0x67, 0x64, 0xe2, 0xd4, 0x82, 0x52, 0x28, +0xa9, 0x64, 0x41, 0x42, 0x2c, 0x3b, 0x27, 0x37, +0x2f, 0x1f, 0xb7, 0x16, 0xe4, 0xa2, 0x4f, 0xa5, +0x00, 0xa2, 0xa5, 0xb0, 0x28, 0xbf, 0xb8, 0x04, +0xa7, 0x5f, 0x50, 0x6d, 0x29, 0x05, 0x6b, 0x21, +0x10, 0x62, 0x90, 0x24, 0x68, 0x0c, 0x09, 0xaf, +0xb2, 0x72, 0x15, 0x42, 0x61, 0xca, 0x00, 0x4e, +0x82, 0xe6, 0xe6, 0x66, 0xa6, 0x20, 0x0d, 0x2a, +0x65, 0xe5, 0x15, 0xaa, 0xc4, 0x68, 0x31, 0xaf, +0xac, 0xac, 0x34, 0x37, 0x05, 0xbb, 0x0a, 0xa8, +0x43, 0x8d, 0x58, 0x2d, 0x16, 0x10, 0x5b, 0x54, +0x88, 0xd2, 0x01, 0xd2, 0x52, 0x65, 0x53, 0x6d, +0x8a, 0x24, 0x52, 0x53, 0x5b, 0x57, 0x5f, 0x5f, +0xd7, 0xd0, 0xd8, 0xd4, 0xdc, 0xdc, 0xd4, 0xd2, +0x8a, 0xd5, 0x2f, 0x96, 0x6d, 0xee, 0xed, 0x48, +0x5a, 0x3a, 0x3a, 0xbb, 0xba, 0x7b, 0x7a, 0x7a, +0xfb, 0xfa, 0x27, 0x4c, 0x9c, 0x38, 0x69, 0xf2, +0x94, 0xa9, 0x98, 0x5a, 0x20, 0x01, 0x1a, 0x86, +0xd0, 0x31, 0x6d, 0x3a, 0x90, 0x9c, 0x3a, 0x63, +0xe6, 0xac, 0x69, 0x1d, 0x40, 0xc6, 0xec, 0x19, +0x98, 0x7a, 0x4c, 0xe7, 0xcc, 0x9d, 0x37, 0x7f, +0x01, 0xdc, 0x96, 0x9a, 0x4e, 0x90, 0x8e, 0xd6, +0x29, 0x33, 0x17, 0x2e, 0x9c, 0xd5, 0x59, 0x03, +0xd2, 0x33, 0x05, 0xc3, 0x6d, 0xa6, 0x8b, 0x16, +0x2f, 0x59, 0xba, 0x0c, 0xae, 0xa5, 0xb6, 0x0b, +0x44, 0xb6, 0x2c, 0x5f, 0x08, 0x04, 0x2b, 0x6a, +0x41, 0xec, 0xc9, 0x2d, 0x18, 0x5a, 0x56, 0xae, +0x5a, 0xbd, 0x66, 0x2d, 0x5c, 0x4b, 0x5d, 0x37, +0x88, 0x6c, 0x5a, 0x07, 0xd2, 0xb2, 0xbe, 0x0e, +0xc4, 0x9e, 0xd4, 0x84, 0xa1, 0x25, 0x70, 0xc3, +0xc6, 0x4d, 0x9b, 0xe1, 0x5a, 0xea, 0x7b, 0x40, +0x64, 0xf3, 0x16, 0x90, 0x96, 0xad, 0xf5, 0x20, +0xf6, 0xc4, 0x66, 0x0c, 0x2d, 0xdb, 0xb6, 0xef, +0xc8, 0xde, 0x49, 0x92, 0x16, 0xb4, 0x10, 0x23, +0xca, 0x61, 0xbb, 0x92, 0x77, 0xef, 0xd9, 0x4b, +0x9a, 0xf7, 0x77, 0xef, 0xdb, 0x7f, 0xe0, 0x20, +0x69, 0x81, 0xbc, 0xe7, 0xd0, 0xe1, 0xc3, 0x08, +0x2d, 0x44, 0x45, 0xe5, 0xc1, 0xc3, 0x28, 0x5a, +0x60, 0x09, 0xe6, 0xc8, 0x51, 0x9c, 0x09, 0xc6, +0xb4, 0xe4, 0xe0, 0xc1, 0x83, 0x25, 0x24, 0x25, +0x4b, 0xf4, 0x34, 0x46, 0x5d, 0x00, 0x00, 0xcd, +0x77, 0xdc, 0x74, 0x37, 0x56, 0x69, 0x35, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_intersect_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_intersect_png = new wxImage(); + if (!img_ex_hash_setop_intersect_png || !img_ex_hash_setop_intersect_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_intersect_pngIS(ex_hash_setop_intersect_png_data, sizeof(ex_hash_setop_intersect_png_data)); + img_ex_hash_setop_intersect_png->LoadFile(img_ex_hash_setop_intersect_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_intersect_png; +} +#define ex_hash_setop_intersect_png_img ex_hash_setop_intersect_png_img() + +static wxBitmap *ex_hash_setop_intersect_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_intersect_png; + if (!bmp_ex_hash_setop_intersect_png || !bmp_ex_hash_setop_intersect_png->IsOk()) + bmp_ex_hash_setop_intersect_png = new wxBitmap(*ex_hash_setop_intersect_png_img); + return bmp_ex_hash_setop_intersect_png; +} +#define ex_hash_setop_intersect_png_bmp ex_hash_setop_intersect_png_bmp() + +static wxIcon *ex_hash_setop_intersect_png_ico() +{ + static wxIcon *ico_ex_hash_setop_intersect_png; + if (!ico_ex_hash_setop_intersect_png || !ico_ex_hash_setop_intersect_png->IsOk()) + { + ico_ex_hash_setop_intersect_png = new wxIcon(); + ico_ex_hash_setop_intersect_png->CopyFromBitmap(*ex_hash_setop_intersect_png_bmp); + } + return ico_ex_hash_setop_intersect_png; +} +#define ex_hash_setop_intersect_png_ico ex_hash_setop_intersect_png_ico() + +#endif // EX_HASH_SETOP_INTERSECT_PNG_H diff --git a/include/images/ex_hash_setop_intersect_all.png b/include/images/ex_hash_setop_intersect_all.png new file mode 100644 index 0000000..0018157 Binary files /dev/null and b/include/images/ex_hash_setop_intersect_all.png differ diff --git a/include/images/ex_hash_setop_intersect_all.pngc b/include/images/ex_hash_setop_intersect_all.pngc new file mode 100644 index 0000000..c16fb98 --- /dev/null +++ b/include/images/ex_hash_setop_intersect_all.pngc @@ -0,0 +1,222 @@ +#ifndef EX_HASH_SETOP_INTERSECT_ALL_PNG_H +#define EX_HASH_SETOP_INTERSECT_ALL_PNG_H + +static const unsigned char ex_hash_setop_intersect_all_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x55, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0x00, 0x00, 0x00, 0xa5, +0xa8, 0xe4, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, +0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, +0xf0, 0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, +0xd4, 0xee, 0xad, 0xdf, 0xf3, 0x99, 0xbc, 0x78, +0x52, 0x8d, 0x19, 0x90, 0xb6, 0x6c, 0xd8, 0xe5, +0xcb, 0x07, 0xa8, 0xe2, 0x10, 0xab, 0xe2, 0x1a, +0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, 0xcb, 0xec, +0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, 0x64, 0xc5, +0xe8, 0x92, 0xd5, 0xef, 0xa1, 0xc4, 0x5e, 0x84, +0xb0, 0x45, 0x72, 0xa3, 0x35, 0x7a, 0x9e, 0xa9, +0x6a, 0x8f, 0xa6, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xf0, 0xec, 0xb6, 0xef, +0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xa2, 0xc7, 0x60, +0xea, 0xe4, 0x9d, 0xea, 0xe3, 0x9c, 0xe9, 0xe0, +0x9a, 0xee, 0xe6, 0xb3, 0xa4, 0xca, 0x63, 0xef, +0xea, 0xb6, 0xe9, 0xe1, 0x9b, 0xe8, 0xdf, 0x99, +0xe7, 0xdd, 0x97, 0xec, 0xe3, 0xb0, 0xa7, 0xcd, +0x66, 0xef, 0xe8, 0xb3, 0xe8, 0xde, 0x98, 0xe7, +0xdb, 0x96, 0xe6, 0xd8, 0x94, 0xec, 0xe0, 0xad, +0x97, 0xbb, 0x75, 0x86, 0xb6, 0x49, 0x76, 0xaa, +0x3b, 0xf1, 0xeb, 0xc4, 0xec, 0xe0, 0xae, 0xeb, +0xde, 0xac, 0xef, 0xe4, 0xbf, 0xba, 0xd1, 0xa3, +0xae, 0xda, 0x71, 0x78, 0xae, 0x3e, 0xdb, 0xbd, +0x89, 0xb5, 0x99, 0x7e, 0xb4, 0xe3, 0x79, 0xf0, +0xe6, 0xc0, 0xe9, 0xdc, 0xaa, 0xe9, 0xda, 0xa8, +0xe8, 0xd7, 0xa7, 0xed, 0xdf, 0xbb, 0x7a, 0xb1, +0x41, 0xe9, 0xda, 0xa9, 0xe0, 0xcb, 0x8a, 0xdf, +0xc8, 0x87, 0xde, 0xc5, 0x85, 0xe6, 0xd1, 0xa2, +0x8d, 0xc1, 0x53, 0xe8, 0xd7, 0xa6, 0xdf, 0xc6, +0x86, 0xde, 0xc3, 0x84, 0xdd, 0xc1, 0x82, 0xe5, +0xcf, 0xa0, 0xb6, 0xe7, 0x7c, 0xe6, 0xd4, 0xa4, +0xdd, 0xc2, 0x83, 0xdc, 0xc0, 0x81, 0xdb, 0xbd, +0x7f, 0xe4, 0xcd, 0x9e, 0xb9, 0xeb, 0x7f, 0xeb, +0xdb, 0xb8, 0xe5, 0xce, 0xa0, 0xe3, 0xcc, 0x9e, +0xea, 0xd8, 0xb6, 0xba, 0xee, 0x82, 0x7c, 0xb4, +0x43, 0xbc, 0xf0, 0x84, 0x96, 0xcc, 0x5d, 0xeb, +0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, 0xe9, 0xb4, +0xf2, 0xe8, 0xd6, 0xe0, 0xc7, 0x9a, 0xd0, 0xab, +0x68, 0xc5, 0x97, 0x44, 0xc7, 0xb4, 0xa5, 0xac, +0xa9, 0xd4, 0x8c, 0x90, 0xdc, 0x71, 0x75, 0xd4, +0xb2, 0xb5, 0xe8, 0xe0, 0xe1, 0xf6, 0xef, 0xea, +0xb5, 0xf2, 0xec, 0xc5, 0xe6, 0xd2, 0xae, 0xd1, +0xac, 0x6a, 0xdc, 0xc0, 0x8e, 0xed, 0xdf, 0xc6, +0xfa, 0xf6, 0xee, 0xb7, 0xb1, 0xca, 0x77, 0x80, +0xa7, 0x87, 0x87, 0x8b, 0xc2, 0xb5, 0xb8, 0xf2, +0xf3, 0xfb, 0xd4, 0xd5, 0xf2, 0xa9, 0xac, 0xe5, +0x8e, 0x91, 0xdd, 0xc1, 0xc3, 0xec, 0xd2, 0xad, +0x6c, 0xec, 0xdc, 0xc1, 0x8f, 0x92, 0xdd, 0x7d, +0xcb, 0x5b, 0x9a, 0xd6, 0x2b, 0xd0, 0xd1, 0xf1, +0xf3, 0xed, 0xc6, 0xee, 0xe6, 0xb2, 0xed, 0xe4, +0xb0, 0xec, 0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0x88, +0xf6, 0x26, 0xed, 0xe5, 0xb1, 0xe6, 0xd9, 0x95, +0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, 0xea, 0xdc, +0xaa, 0x75, 0xa8, 0x86, 0xa8, 0xbc, 0x2f, 0xec, +0xe2, 0xae, 0xe4, 0xd5, 0x91, 0xe3, 0xd2, 0x8f, +0xe2, 0xce, 0x8c, 0xe9, 0xd8, 0xa7, 0x7e, 0xcf, +0x56, 0x98, 0xd9, 0x2b, 0xe2, 0xd0, 0x8d, 0xe1, +0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe7, 0xd5, 0xa5, +0x85, 0xeb, 0x34, 0x8d, 0xee, 0x27, 0xef, 0xe3, +0xbe, 0xe8, 0xd8, 0xa7, 0xe7, 0xd6, 0xa5, 0xec, +0xdd, 0xb9, 0xec, 0xde, 0xba, 0xe5, 0xd0, 0xa1, +0xe4, 0xce, 0x9f, 0xeb, 0xd9, 0xb6, 0xdc, 0xbe, +0x80, 0xdb, 0xbc, 0x7e, 0xda, 0xbb, 0x7d, 0xe3, +0xcb, 0x9e, 0xda, 0xbb, 0x7e, 0xda, 0xba, 0x7d, +0x85, 0x81, 0xbf, 0x96, 0x87, 0xa4, 0x03, 0x64, +0x9e, 0xf9, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x6b, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, +0x20, 0x1b, 0x30, 0x32, 0x81, 0x00, 0x23, 0x29, +0x5a, 0x98, 0x98, 0x59, 0x58, 0xd9, 0xd8, 0x99, +0x48, 0xd2, 0xc2, 0xc1, 0xc9, 0xc5, 0xcd, 0x43, +0x9a, 0x16, 0xd2, 0x6d, 0xe1, 0x05, 0xfb, 0x85, +0x97, 0x14, 0x2d, 0x7c, 0xfc, 0x02, 0x82, 0x42, +0xc2, 0x7c, 0x24, 0x69, 0x11, 0x11, 0x15, 0x13, +0x97, 0x18, 0x8c, 0x5a, 0x60, 0x7e, 0x91, 0x94, +0x94, 0x64, 0x90, 0x64, 0x00, 0x21, 0x42, 0x40, +0x8a, 0x0f, 0x04, 0xa4, 0x40, 0x6a, 0x89, 0xd5, +0x42, 0x86, 0x2d, 0x70, 0xbf, 0x80, 0x6d, 0x01, +0x23, 0x58, 0xba, 0xc3, 0x95, 0xfa, 0xb0, 0x79, +0x9f, 0x89, 0x59, 0x5a, 0x46, 0x56, 0x8e, 0x49, +0x5e, 0x41, 0x51, 0x49, 0x99, 0x09, 0x9f, 0x16, +0x15, 0x55, 0x55, 0x35, 0x75, 0x88, 0x16, 0x0e, +0x0d, 0x4d, 0x2d, 0x6d, 0x26, 0x1d, 0x5d, 0x3d, +0x7d, 0x03, 0x6c, 0x5a, 0xe0, 0xb1, 0xaf, 0x6a, +0x68, 0x68, 0x04, 0xd1, 0x43, 0xc0, 0x16, 0x78, +0x88, 0x01, 0x6d, 0x31, 0x06, 0xea, 0x01, 0x89, +0x99, 0x80, 0x7d, 0x61, 0x8a, 0x2b, 0xf5, 0x21, +0xa7, 0x31, 0x15, 0x63, 0x43, 0x55, 0x10, 0x6d, +0x66, 0x6e, 0x61, 0x69, 0x65, 0x6d, 0x86, 0x2b, +0xf5, 0xa1, 0x78, 0x5f, 0xd5, 0x06, 0xa2, 0xc5, +0xc2, 0xd6, 0xce, 0xde, 0xc1, 0x0c, 0x57, 0xba, +0x40, 0xd5, 0xe2, 0x08, 0xd1, 0xe2, 0xe4, 0xec, +0xe2, 0xea, 0x46, 0xa4, 0x16, 0x77, 0x88, 0x16, +0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0xdc, 0x5a, 0x90, +0x5d, 0xec, 0xeb, 0xe7, 0xaf, 0x02, 0xd2, 0x12, +0xe0, 0x16, 0x18, 0x14, 0x8c, 0xd3, 0x2f, 0x88, +0x10, 0x03, 0x82, 0x10, 0xff, 0xd0, 0x30, 0xa0, +0x9e, 0x70, 0x33, 0x10, 0x88, 0x40, 0x96, 0xc1, +0x0d, 0x54, 0xc2, 0x22, 0x81, 0x4e, 0x33, 0x8b, +0x8a, 0x8e, 0x89, 0x8d, 0x33, 0x23, 0x2a, 0xbf, +0x86, 0x84, 0x45, 0xc6, 0x03, 0x6d, 0x31, 0x4b, +0x48, 0x4c, 0x4a, 0x4e, 0xc1, 0xe9, 0x17, 0x94, +0xc4, 0xe7, 0x9b, 0x1a, 0x0f, 0xf6, 0x4b, 0x5a, +0x7a, 0x46, 0x66, 0x16, 0x4e, 0x2d, 0x28, 0x85, +0x92, 0x6a, 0x36, 0x24, 0xc4, 0x72, 0x72, 0xf3, +0xf2, 0x0b, 0x70, 0x6b, 0x41, 0x2e, 0xfa, 0x54, +0x0b, 0x21, 0x5a, 0x8a, 0x8a, 0x0b, 0x4a, 0x4a, +0x71, 0xfa, 0x05, 0xd5, 0x96, 0x32, 0xb0, 0x16, +0x02, 0x21, 0x06, 0x49, 0x82, 0x26, 0x90, 0xf0, +0x2a, 0xaf, 0x50, 0x25, 0x14, 0xa6, 0x0c, 0xe0, +0x24, 0x68, 0x61, 0x61, 0x6e, 0x06, 0xd2, 0xa0, +0x5a, 0x5e, 0x51, 0xa9, 0x46, 0x8c, 0x16, 0x8b, +0xaa, 0xaa, 0x2a, 0x0b, 0x33, 0xb0, 0xab, 0x80, +0x3a, 0xd4, 0x89, 0xd5, 0x62, 0x09, 0xb1, 0x45, +0x95, 0x28, 0x1d, 0x20, 0x2d, 0xd5, 0xb6, 0x35, +0x66, 0x48, 0x22, 0xb5, 0x75, 0xf5, 0x0d, 0x0d, +0xf5, 0x8d, 0x4d, 0xcd, 0x2d, 0x2d, 0xcd, 0xad, +0x6d, 0x58, 0xfd, 0x62, 0xd5, 0xee, 0xd1, 0x81, +0xa4, 0xa5, 0xb3, 0xab, 0xbb, 0xa7, 0xb7, 0xb7, +0xaf, 0x7f, 0xc2, 0xc4, 0x49, 0x93, 0x26, 0x4f, +0x99, 0x3a, 0x0d, 0x53, 0x0b, 0x24, 0x40, 0xc3, +0x11, 0x3a, 0xa6, 0xcf, 0x00, 0x92, 0xd3, 0x66, +0xce, 0x9a, 0x3d, 0xbd, 0x13, 0xc8, 0x98, 0x33, +0x13, 0x53, 0x8f, 0xd9, 0xdc, 0x79, 0xf3, 0x17, +0x2c, 0x84, 0xdb, 0x52, 0xdb, 0x05, 0xd2, 0xd1, +0x36, 0x75, 0xd6, 0xa2, 0x45, 0xb3, 0xbb, 0x6a, +0x41, 0x7a, 0xa6, 0x62, 0xb8, 0xcd, 0x6c, 0xf1, +0x92, 0xa5, 0xcb, 0x96, 0xc3, 0xb5, 0xd4, 0x75, +0x83, 0xc8, 0xd6, 0x15, 0x8b, 0x80, 0x60, 0x65, +0x1d, 0x88, 0x3d, 0xa5, 0x15, 0x43, 0xcb, 0xaa, +0xd5, 0x6b, 0xd6, 0xae, 0x83, 0x6b, 0xa9, 0xef, +0x01, 0x91, 0xcd, 0xeb, 0x41, 0x5a, 0x36, 0xd4, +0x83, 0xd8, 0x93, 0x9b, 0x31, 0xb4, 0x04, 0x6d, +0xdc, 0xb4, 0x79, 0x0b, 0x5c, 0x4b, 0x43, 0x2f, +0x88, 0x6c, 0xd9, 0x0a, 0xd2, 0xb2, 0xad, 0x01, +0xc4, 0x9e, 0xd4, 0x82, 0xa1, 0x65, 0xfb, 0x8e, +0x9d, 0x39, 0xbb, 0x48, 0xd2, 0x82, 0x16, 0x62, +0x44, 0x39, 0x6c, 0x77, 0xca, 0x9e, 0xbd, 0xfb, +0xb0, 0x7a, 0xbf, 0x1b, 0x97, 0xf7, 0xf7, 0xec, +0x3f, 0x70, 0xf0, 0x10, 0x69, 0x81, 0xbc, 0xf7, +0xf0, 0x91, 0x23, 0x08, 0x2d, 0x44, 0x45, 0xe5, +0xa1, 0x23, 0x28, 0x5a, 0x60, 0x09, 0xe6, 0xe8, +0x31, 0x9c, 0x09, 0xc6, 0xac, 0xf4, 0xd0, 0xa1, +0x43, 0xa5, 0x24, 0x25, 0x4b, 0xf4, 0x34, 0x46, +0x5d, 0x00, 0x00, 0x0a, 0x47, 0xe0, 0x4d, 0xdb, +0xf8, 0x43, 0x5b, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_intersect_all_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_intersect_all_png = new wxImage(); + if (!img_ex_hash_setop_intersect_all_png || !img_ex_hash_setop_intersect_all_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_intersect_all_pngIS(ex_hash_setop_intersect_all_png_data, sizeof(ex_hash_setop_intersect_all_png_data)); + img_ex_hash_setop_intersect_all_png->LoadFile(img_ex_hash_setop_intersect_all_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_intersect_all_png; +} +#define ex_hash_setop_intersect_all_png_img ex_hash_setop_intersect_all_png_img() + +static wxBitmap *ex_hash_setop_intersect_all_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_intersect_all_png; + if (!bmp_ex_hash_setop_intersect_all_png || !bmp_ex_hash_setop_intersect_all_png->IsOk()) + bmp_ex_hash_setop_intersect_all_png = new wxBitmap(*ex_hash_setop_intersect_all_png_img); + return bmp_ex_hash_setop_intersect_all_png; +} +#define ex_hash_setop_intersect_all_png_bmp ex_hash_setop_intersect_all_png_bmp() + +static wxIcon *ex_hash_setop_intersect_all_png_ico() +{ + static wxIcon *ico_ex_hash_setop_intersect_all_png; + if (!ico_ex_hash_setop_intersect_all_png || !ico_ex_hash_setop_intersect_all_png->IsOk()) + { + ico_ex_hash_setop_intersect_all_png = new wxIcon(); + ico_ex_hash_setop_intersect_all_png->CopyFromBitmap(*ex_hash_setop_intersect_all_png_bmp); + } + return ico_ex_hash_setop_intersect_all_png; +} +#define ex_hash_setop_intersect_all_png_ico ex_hash_setop_intersect_all_png_ico() + +#endif // EX_HASH_SETOP_INTERSECT_ALL_PNG_H diff --git a/include/images/ex_hash_setop_unknown.png b/include/images/ex_hash_setop_unknown.png new file mode 100644 index 0000000..3a78fa6 Binary files /dev/null and b/include/images/ex_hash_setop_unknown.png differ diff --git a/include/images/ex_hash_setop_unknown.pngc b/include/images/ex_hash_setop_unknown.pngc new file mode 100644 index 0000000..e34b205 --- /dev/null +++ b/include/images/ex_hash_setop_unknown.pngc @@ -0,0 +1,231 @@ +#ifndef EX_HASH_SETOP_UNKNOWN_PNG_H +#define EX_HASH_SETOP_UNKNOWN_PNG_H + +static const unsigned char ex_hash_setop_unknown_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x7c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, +0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, +0xf2, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x64, 0x95, 0xd0, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, +0xf1, 0xc0, 0xc1, 0xee, 0xc6, 0xc7, 0xef, 0xcd, +0xce, 0xf2, 0xde, 0xde, 0xf6, 0xbc, 0xbd, 0xec, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0xa5, 0xa8, 0xe4, 0x45, +0xbe, 0xe9, 0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, +0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, 0x7a, 0xce, +0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, 0xee, 0xad, +0xdf, 0xf3, 0x99, 0xbc, 0x78, 0x52, 0x8d, 0x19, +0x90, 0xb6, 0x6c, 0xd8, 0xe5, 0xcb, 0x07, 0xa8, +0xe2, 0x10, 0xab, 0xe2, 0x1a, 0xae, 0xe3, 0x5d, +0xc5, 0xeb, 0x71, 0xcb, 0xec, 0x4e, 0xbe, 0xe6, +0x5a, 0xc1, 0xe7, 0x64, 0xc5, 0xe8, 0x92, 0xd5, +0xef, 0xa1, 0xc4, 0x5e, 0x84, 0xb0, 0x45, 0x72, +0xa3, 0x35, 0x7a, 0x9e, 0xa9, 0x6a, 0x8f, 0xa6, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb7, 0xf0, 0xec, 0xb6, 0xef, 0xeb, 0xb6, 0xf3, +0xef, 0xc7, 0xa2, 0xc7, 0x60, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xee, 0xe6, +0xb3, 0xa4, 0xca, 0x63, 0xef, 0xea, 0xb6, 0xe9, +0xe1, 0x9b, 0xe8, 0xdf, 0x99, 0xe7, 0xdd, 0x97, +0xec, 0xe3, 0xb0, 0xa7, 0xcd, 0x66, 0xef, 0xe8, +0xb3, 0xe8, 0xde, 0x98, 0xe7, 0xdb, 0x96, 0xe6, +0xd8, 0x94, 0xec, 0xe0, 0xad, 0x97, 0xbb, 0x75, +0x86, 0xb6, 0x49, 0x76, 0xaa, 0x3b, 0xf1, 0xeb, +0xc4, 0xec, 0xe0, 0xae, 0xeb, 0xde, 0xac, 0xef, +0xe4, 0xbf, 0xba, 0xd1, 0xa3, 0xae, 0xda, 0x71, +0x78, 0xae, 0x3e, 0xdb, 0xbd, 0x89, 0xb5, 0x99, +0x7e, 0xb4, 0xe3, 0x79, 0xf0, 0xe6, 0xc0, 0xe9, +0xdc, 0xaa, 0xe9, 0xda, 0xa8, 0xe8, 0xd7, 0xa7, +0xed, 0xdf, 0xbb, 0x7a, 0xb1, 0x41, 0xe9, 0xda, +0xa9, 0xe0, 0xcb, 0x8a, 0xdf, 0xc8, 0x87, 0xde, +0xc5, 0x85, 0xe6, 0xd1, 0xa2, 0x8d, 0xc1, 0x53, +0xe8, 0xd7, 0xa6, 0xdf, 0xc6, 0x86, 0xde, 0xc3, +0x84, 0xdd, 0xc1, 0x82, 0xe5, 0xcf, 0xa0, 0xb6, +0xe7, 0x7c, 0xe6, 0xd4, 0xa4, 0xdd, 0xc2, 0x83, +0xdc, 0xc0, 0x81, 0xdb, 0xbd, 0x7f, 0xe4, 0xcd, +0x9e, 0xb9, 0xeb, 0x7f, 0xeb, 0xdb, 0xb8, 0xe5, +0xce, 0xa0, 0xe3, 0xcc, 0x9e, 0xea, 0xd8, 0xb6, +0xba, 0xee, 0x82, 0x7c, 0xb4, 0x43, 0xbc, 0xf0, +0x84, 0x96, 0xcc, 0x5d, 0xeb, 0xe6, 0x9f, 0xeb, +0xe5, 0x9e, 0xef, 0xe9, 0xb4, 0xf6, 0xee, 0xe0, +0xe8, 0xd5, 0xb3, 0xdc, 0xc0, 0x8d, 0xd4, 0xb1, +0x73, 0xd5, 0xc7, 0xbc, 0xc1, 0xbf, 0xdf, 0xa9, +0xab, 0xe5, 0x94, 0x98, 0xdf, 0xc5, 0xc7, 0xee, +0xe8, 0xe8, 0xf8, 0xef, 0xea, 0xb5, 0xf2, 0xec, +0xc5, 0xec, 0xdd, 0xc2, 0xdc, 0xc1, 0x8f, 0xe5, +0xd0, 0xab, 0xf2, 0xe7, 0xd4, 0xfb, 0xf8, 0xf2, +0xcb, 0xb3, 0xbd, 0xb1, 0x86, 0x9c, 0xba, 0x8a, +0x8d, 0xd2, 0xb5, 0xb1, 0xf5, 0xf6, 0xfc, 0xdf, +0xe0, 0xf5, 0xbf, 0xc1, 0xec, 0xaa, 0xad, 0xe5, +0xd1, 0xd2, 0xf1, 0xdd, 0xc2, 0x91, 0xf1, 0xe5, +0xd0, 0xf7, 0xd8, 0xce, 0xd6, 0x50, 0x2a, 0xd7, +0x3c, 0x0c, 0xdd, 0x66, 0x3c, 0xfc, 0xf2, 0xef, +0xdc, 0xdd, 0xf4, 0xab, 0xae, 0xe6, 0xf3, 0xed, +0xc6, 0xee, 0xe6, 0xb2, 0xed, 0xe4, 0xb0, 0xec, +0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0xe3, 0xba, 0xb9, +0xd7, 0x52, 0x2b, 0xe2, 0x70, 0x4d, 0xda, 0x49, +0x1c, 0xdf, 0x6b, 0x45, 0xed, 0xe5, 0xb1, 0xe6, +0xd9, 0x95, 0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, +0xea, 0xdc, 0xaa, 0xc8, 0xb5, 0xd0, 0xc6, 0x9e, +0xb0, 0xdc, 0x56, 0x2c, 0xec, 0xe2, 0xae, 0xe4, +0xd5, 0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xce, 0x8c, +0xe9, 0xd8, 0xa7, 0xdf, 0x63, 0x3d, 0xd7, 0x44, +0x15, 0xe2, 0xd0, 0x8d, 0xe1, 0xcd, 0x8b, 0xe0, +0xca, 0x89, 0xe7, 0xd5, 0xa5, 0xef, 0xb1, 0x9e, +0xd5, 0x7a, 0x43, 0xef, 0xe3, 0xbe, 0xe8, 0xd8, +0xa7, 0xe7, 0xd6, 0xa5, 0xec, 0xdd, 0xb9, 0xf4, +0xcb, 0xbe, 0xea, 0xa0, 0x87, 0xec, 0xa4, 0x8e, +0xfa, 0xe5, 0xdf, 0xec, 0xde, 0xba, 0xe5, 0xd0, +0xa1, 0xe4, 0xce, 0x9f, 0xeb, 0xd9, 0xb6, 0xdc, +0xbe, 0x80, 0xdb, 0xbc, 0x7e, 0xda, 0xbb, 0x7d, +0xe3, 0xcb, 0x9e, 0xda, 0xbb, 0x7e, 0xda, 0xba, +0x7d, 0xcb, 0x5b, 0x46, 0xdb, 0x9e, 0x6d, 0xd4, +0x61, 0x42, 0xd3, 0xa2, 0x97, 0xb2, 0xa3, 0x15, +0x55, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x8d, 0x49, +0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, 0x20, +0x1b, 0x30, 0x32, 0x81, 0x00, 0x23, 0x29, 0x5a, +0x98, 0x98, 0x59, 0x58, 0xd9, 0xd8, 0x99, 0x48, +0xd2, 0xc2, 0xc1, 0xc9, 0xc5, 0xcd, 0x43, 0x9a, +0x16, 0xd2, 0x6d, 0xe1, 0x05, 0xfb, 0x85, 0x97, +0x14, 0x2d, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, +0x7c, 0x24, 0x69, 0x11, 0x11, 0x15, 0x13, 0x97, +0x18, 0x8c, 0x5a, 0x48, 0xf7, 0x8b, 0x24, 0x1f, +0x08, 0x48, 0x0e, 0x40, 0x88, 0x41, 0xd3, 0x1d, +0xae, 0xd4, 0x87, 0x4d, 0x0b, 0x13, 0xb3, 0x94, +0xb4, 0x8c, 0x2c, 0x93, 0x9c, 0xbc, 0x82, 0xa2, +0x12, 0x13, 0x3e, 0x2d, 0xca, 0x2a, 0x2a, 0xaa, +0x6a, 0x10, 0x2d, 0x1c, 0xea, 0x1a, 0x9a, 0x5a, +0x4c, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0xd8, 0xb4, +0xc0, 0xfd, 0xa2, 0x62, 0x60, 0x60, 0x08, 0xd1, +0x43, 0xc0, 0x16, 0x44, 0x88, 0x29, 0xab, 0x18, +0x01, 0xf5, 0x80, 0xc4, 0x8c, 0xc1, 0xbe, 0x30, +0xc1, 0x95, 0xfa, 0x90, 0x43, 0x4c, 0xd9, 0xc8, +0x40, 0x05, 0x44, 0x9b, 0x9a, 0x99, 0x5b, 0x58, +0x5a, 0x99, 0xe2, 0x0a, 0x4b, 0x14, 0xef, 0xab, +0x58, 0x43, 0xb4, 0x98, 0xdb, 0xd8, 0xda, 0xd9, +0x9b, 0xe2, 0x4a, 0x17, 0xa8, 0x5a, 0x1c, 0x20, +0x5a, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0x89, 0xd4, +0xe2, 0x06, 0xd1, 0xe2, 0xee, 0xe1, 0xe9, 0xe5, +0x8d, 0x5b, 0x0b, 0xb2, 0x8b, 0x7d, 0x7c, 0xfd, +0x94, 0x41, 0x5a, 0xfc, 0x5d, 0x03, 0x02, 0x83, +0x70, 0xfa, 0x05, 0x25, 0x8d, 0x05, 0xfb, 0x85, +0x84, 0x02, 0xf5, 0x84, 0x99, 0x82, 0x40, 0x38, +0x71, 0xa9, 0x4f, 0x39, 0x34, 0x02, 0xe8, 0x34, +0xd3, 0xc8, 0xa8, 0xe8, 0x98, 0x58, 0x53, 0xa2, +0x52, 0x5f, 0x70, 0x68, 0x44, 0x1c, 0xd0, 0x16, +0xd3, 0xf8, 0x84, 0xc4, 0xa4, 0x64, 0x9c, 0x7e, +0x41, 0x49, 0x7c, 0x3e, 0x29, 0x71, 0x60, 0xbf, +0xa4, 0xa6, 0xa5, 0x67, 0x64, 0xe2, 0xd4, 0x82, +0x52, 0x28, 0xa9, 0x64, 0x41, 0x42, 0x2c, 0x3b, +0x27, 0x37, 0x2f, 0x1f, 0xb7, 0x16, 0xe4, 0xa2, +0x4f, 0xa5, 0x00, 0xa2, 0xa5, 0xb0, 0x28, 0xbf, +0xb8, 0x04, 0xa7, 0x5f, 0x50, 0x6d, 0x29, 0x05, +0x6b, 0x21, 0x10, 0x62, 0x90, 0x24, 0x68, 0x0c, +0x09, 0xaf, 0xb2, 0x72, 0x15, 0x42, 0x61, 0xca, +0x00, 0x4e, 0x82, 0xe6, 0xe6, 0x66, 0xa6, 0x20, +0x0d, 0x2a, 0x65, 0xe5, 0x15, 0xaa, 0xc4, 0x68, +0x31, 0xaf, 0xac, 0xac, 0x34, 0x37, 0x05, 0xbb, +0x0a, 0xa8, 0x43, 0x8d, 0x58, 0x2d, 0x16, 0x10, +0x5b, 0x54, 0x88, 0xd2, 0x01, 0xd2, 0x52, 0x65, +0x53, 0x6d, 0x8a, 0x24, 0x52, 0x53, 0x5b, 0x57, +0x5f, 0x5f, 0xd7, 0xd0, 0xd8, 0xd4, 0xdc, 0xdc, +0xd4, 0xd2, 0x8a, 0xd5, 0x2f, 0x96, 0x6d, 0xee, +0xed, 0x48, 0x5a, 0x3a, 0x3a, 0xbb, 0xba, 0x7b, +0x7a, 0x7a, 0xfb, 0xfa, 0x27, 0x4c, 0x9c, 0x38, +0x69, 0xf2, 0x94, 0xa9, 0x98, 0x5a, 0x20, 0x01, +0x1a, 0x86, 0xd0, 0x31, 0x6d, 0x3a, 0x03, 0xc3, +0x8c, 0x99, 0xb3, 0x80, 0x60, 0xf6, 0x1c, 0x06, +0x86, 0xb9, 0xf3, 0x30, 0xf5, 0x98, 0xce, 0x5f, +0xb0, 0x70, 0xd1, 0x62, 0xb8, 0x2d, 0x35, 0x9d, +0x40, 0x1d, 0x0c, 0x4b, 0x66, 0x2d, 0x5d, 0xb6, +0x7c, 0xd6, 0xac, 0x15, 0x40, 0xe6, 0xdc, 0x29, +0x18, 0x6e, 0x33, 0x5d, 0xb9, 0x6a, 0xf5, 0x9a, +0xb5, 0x70, 0x2d, 0xb5, 0x5d, 0x20, 0x72, 0xdd, +0x7a, 0x06, 0x86, 0x39, 0x1b, 0x66, 0xcd, 0x02, +0xb1, 0x27, 0xb7, 0x60, 0x68, 0xd9, 0xb8, 0x69, +0xf3, 0x96, 0xad, 0x70, 0x2d, 0x75, 0xdd, 0x20, +0xb2, 0x69, 0x12, 0x90, 0xd8, 0x36, 0x6b, 0x3b, +0x88, 0x3d, 0xa9, 0x09, 0x43, 0x4b, 0xe0, 0x8e, +0x9d, 0xbb, 0x76, 0xc3, 0xb5, 0xd4, 0xf7, 0x80, +0xc8, 0xe6, 0x89, 0x0c, 0x0c, 0x7b, 0x66, 0xcd, +0xda, 0x0b, 0x62, 0x4f, 0x6c, 0xc6, 0xd0, 0xb2, +0x6f, 0xff, 0x81, 0xec, 0x83, 0x18, 0x5a, 0x0e, +0x6d, 0x9b, 0x35, 0xeb, 0x70, 0x3d, 0x76, 0x2d, +0x68, 0x21, 0x06, 0x73, 0xd8, 0x91, 0x59, 0xb3, +0x8e, 0x76, 0xd7, 0xe1, 0x70, 0xd8, 0xb1, 0xe4, +0xe3, 0x27, 0x4e, 0xa2, 0x79, 0xbf, 0x65, 0x32, +0x50, 0x0b, 0x43, 0x57, 0x2d, 0x0e, 0xef, 0x1f, +0x3f, 0x75, 0xfa, 0xcc, 0x59, 0xb4, 0x40, 0x6e, +0x9d, 0x32, 0x97, 0x81, 0x61, 0x7a, 0x67, 0x0d, +0x8e, 0x40, 0x3e, 0x71, 0xee, 0xfc, 0x79, 0x84, +0x16, 0x48, 0x54, 0x32, 0x4c, 0xbd, 0x30, 0x6b, +0xd6, 0xc5, 0x0e, 0x06, 0x1c, 0x51, 0x79, 0xf6, +0x3c, 0x8a, 0x16, 0x68, 0x82, 0xb9, 0x34, 0x6b, +0xd6, 0x65, 0x5c, 0x09, 0xc6, 0xb4, 0xe4, 0xec, +0xd9, 0xb3, 0x25, 0x24, 0x25, 0x4b, 0xf4, 0x34, +0x46, 0x5d, 0x00, 0x00, 0x27, 0x7e, 0xda, 0xbe, +0x95, 0x25, 0xb8, 0x90, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_hash_setop_unknown_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_hash_setop_unknown_png = new wxImage(); + if (!img_ex_hash_setop_unknown_png || !img_ex_hash_setop_unknown_png->IsOk()) + { + wxMemoryInputStream img_ex_hash_setop_unknown_pngIS(ex_hash_setop_unknown_png_data, sizeof(ex_hash_setop_unknown_png_data)); + img_ex_hash_setop_unknown_png->LoadFile(img_ex_hash_setop_unknown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_hash_setop_unknown_png; +} +#define ex_hash_setop_unknown_png_img ex_hash_setop_unknown_png_img() + +static wxBitmap *ex_hash_setop_unknown_png_bmp() +{ + static wxBitmap *bmp_ex_hash_setop_unknown_png; + if (!bmp_ex_hash_setop_unknown_png || !bmp_ex_hash_setop_unknown_png->IsOk()) + bmp_ex_hash_setop_unknown_png = new wxBitmap(*ex_hash_setop_unknown_png_img); + return bmp_ex_hash_setop_unknown_png; +} +#define ex_hash_setop_unknown_png_bmp ex_hash_setop_unknown_png_bmp() + +static wxIcon *ex_hash_setop_unknown_png_ico() +{ + static wxIcon *ico_ex_hash_setop_unknown_png; + if (!ico_ex_hash_setop_unknown_png || !ico_ex_hash_setop_unknown_png->IsOk()) + { + ico_ex_hash_setop_unknown_png = new wxIcon(); + ico_ex_hash_setop_unknown_png->CopyFromBitmap(*ex_hash_setop_unknown_png_bmp); + } + return ico_ex_hash_setop_unknown_png; +} +#define ex_hash_setop_unknown_png_ico ex_hash_setop_unknown_png_ico() + +#endif // EX_HASH_SETOP_UNKNOWN_PNG_H diff --git a/include/images/ex_index_only_scan.png b/include/images/ex_index_only_scan.png new file mode 100644 index 0000000..7764b74 Binary files /dev/null and b/include/images/ex_index_only_scan.png differ diff --git a/include/images/ex_index_only_scan.pngc b/include/images/ex_index_only_scan.pngc new file mode 100644 index 0000000..780d464 --- /dev/null +++ b/include/images/ex_index_only_scan.pngc @@ -0,0 +1,107 @@ +#ifndef EX_INDEX_ONLY_SCAN_PNG_H +#define EX_INDEX_ONLY_SCAN_PNG_H + +static const unsigned char ex_index_only_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x00, 0x6c, 0x50, 0x4c, 0x54, +0x45, 0xff, 0xff, 0xff, 0x74, 0x74, 0x74, 0x36, +0x88, 0xc1, 0x66, 0x96, 0xd1, 0xc1, 0x8f, 0x36, +0x7a, 0x9e, 0xa9, 0x4d, 0xc0, 0xe9, 0x89, 0xb9, +0xdb, 0x61, 0xc6, 0xeb, 0x6f, 0xcd, 0xee, 0x76, +0xcd, 0xec, 0xbd, 0xbd, 0xbd, 0xa5, 0xc1, 0xe4, +0xdb, 0xbd, 0x89, 0xad, 0xd6, 0xe9, 0xa6, 0xde, +0xf2, 0xf3, 0xdc, 0x2a, 0xbc, 0xdd, 0xed, 0xff, +0xde, 0x29, 0xc0, 0xdf, 0xee, 0xc2, 0xe0, 0xee, +0xc5, 0xe1, 0xef, 0xc7, 0xe3, 0xf0, 0xc8, 0xe3, +0xf0, 0xca, 0xe3, 0xf0, 0xcb, 0xe4, 0xf1, 0xf9, +0xe6, 0x5f, 0xcd, 0xe5, 0xf2, 0xff, 0xe6, 0x5f, +0xd1, 0xe7, 0xf2, 0xd3, 0xe8, 0xf3, 0xd4, 0xe9, +0xf4, 0xd6, 0xe9, 0xf5, 0xf6, 0xeb, 0x87, 0xfe, +0xec, 0x86, 0xe1, 0xef, 0xf7, 0xc1, 0xc8, 0x34, +0x89, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x01, 0x1f, 0x49, +0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd4, 0xdb, +0x0e, 0x82, 0x30, 0x0c, 0x06, 0xe0, 0x49, 0xa7, +0xa2, 0x02, 0xca, 0xc4, 0x13, 0xce, 0x13, 0xbc, +0xff, 0x3b, 0x3a, 0x8a, 0x4e, 0x5d, 0xd7, 0x29, +0x89, 0x26, 0xc6, 0xd8, 0xab, 0x65, 0xc9, 0x17, +0x58, 0xfb, 0x6f, 0x42, 0xfc, 0xeb, 0xe7, 0x6b, +0x18, 0x61, 0x0d, 0x3b, 0x90, 0x68, 0x34, 0x88, +0xe3, 0xf1, 0x34, 0x7a, 0x1f, 0x49, 0x00, 0x12, +0x77, 0xaf, 0xdf, 0xfe, 0x58, 0x9f, 0x21, 0x50, +0xd7, 0xe0, 0xee, 0xc9, 0x53, 0x69, 0xaa, 0x92, +0x1c, 0x39, 0x1e, 0x29, 0x29, 0x67, 0xa6, 0xca, +0xcf, 0x13, 0xa5, 0x14, 0x4f, 0x0e, 0x07, 0x4a, +0xaa, 0xf0, 0x59, 0x3c, 0x24, 0x95, 0x58, 0x29, +0x47, 0xf6, 0x7b, 0x42, 0x44, 0x6f, 0x22, 0xc4, +0xa4, 0xc7, 0x8d, 0x0d, 0x76, 0x3b, 0xf0, 0x89, +0x80, 0xf1, 0x90, 0x56, 0xf0, 0x86, 0x92, 0xab, +0x60, 0x0d, 0x6c, 0xb7, 0xc0, 0x08, 0xce, 0xdc, +0x11, 0xda, 0x28, 0x7f, 0xeb, 0xee, 0x48, 0x1b, +0xad, 0x93, 0x7c, 0x36, 0x20, 0xd8, 0x6c, 0x80, +0xcd, 0x89, 0x2c, 0x4d, 0x0a, 0x94, 0x76, 0xc9, +0x7a, 0xdd, 0x99, 0xac, 0x56, 0x01, 0xa2, 0xbd, +0x64, 0xb9, 0x04, 0xf6, 0xcf, 0x65, 0xa5, 0x4d, +0x91, 0xb3, 0x2c, 0x16, 0x9d, 0x3b, 0x76, 0x23, +0xcd, 0x4c, 0xdc, 0x49, 0xd0, 0x9d, 0x47, 0x42, +0xd3, 0xe8, 0xcd, 0x27, 0x14, 0x05, 0xb0, 0x69, +0xf4, 0xe7, 0xf3, 0x46, 0x68, 0x1a, 0x99, 0x7c, +0xc2, 0x7c, 0x0e, 0xf6, 0xa0, 0x69, 0x70, 0xe1, +0x10, 0x0c, 0x4b, 0xd3, 0x4d, 0xec, 0x74, 0xbb, +0xb8, 0xf4, 0xd7, 0x2e, 0xec, 0xc3, 0x97, 0xe7, +0xcd, 0xe3, 0x87, 0x63, 0x6c, 0xa6, 0x88, 0x03, +0xc7, 0x85, 0xbe, 0x4c, 0xd1, 0x2e, 0xae, 0x37, +0x3f, 0xcf, 0xb2, 0xdc, 0xdc, 0x7e, 0x7c, 0x54, +0x2c, 0xd1, 0x01, 0x92, 0x40, 0x91, 0x65, 0x05, +0x7e, 0x45, 0xbd, 0x48, 0x8c, 0x31, 0x19, 0x4b, +0x82, 0x47, 0x70, 0xce, 0x62, 0x9f, 0xf1, 0x2e, +0x1d, 0xfb, 0xd7, 0xb7, 0xd5, 0x19, 0xf1, 0x5f, +0x1e, 0x89, 0x10, 0x3d, 0x71, 0xcf, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_index_only_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_index_only_scan_png = new wxImage(); + if (!img_ex_index_only_scan_png || !img_ex_index_only_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_index_only_scan_pngIS(ex_index_only_scan_png_data, sizeof(ex_index_only_scan_png_data)); + img_ex_index_only_scan_png->LoadFile(img_ex_index_only_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_index_only_scan_png; +} +#define ex_index_only_scan_png_img ex_index_only_scan_png_img() + +static wxBitmap *ex_index_only_scan_png_bmp() +{ + static wxBitmap *bmp_ex_index_only_scan_png; + if (!bmp_ex_index_only_scan_png || !bmp_ex_index_only_scan_png->IsOk()) + bmp_ex_index_only_scan_png = new wxBitmap(*ex_index_only_scan_png_img); + return bmp_ex_index_only_scan_png; +} +#define ex_index_only_scan_png_bmp ex_index_only_scan_png_bmp() + +static wxIcon *ex_index_only_scan_png_ico() +{ + static wxIcon *ico_ex_index_only_scan_png; + if (!ico_ex_index_only_scan_png || !ico_ex_index_only_scan_png->IsOk()) + { + ico_ex_index_only_scan_png = new wxIcon(); + ico_ex_index_only_scan_png->CopyFromBitmap(*ex_index_only_scan_png_bmp); + } + return ico_ex_index_only_scan_png; +} +#define ex_index_only_scan_png_ico ex_index_only_scan_png_ico() + +#endif // EX_INDEX_ONLY_SCAN_PNG_H diff --git a/include/images/ex_index_scan.png b/include/images/ex_index_scan.png new file mode 100644 index 0000000..d44eff4 Binary files /dev/null and b/include/images/ex_index_scan.png differ diff --git a/include/images/ex_index_scan.pngc b/include/images/ex_index_scan.pngc new file mode 100644 index 0000000..5dcd538 --- /dev/null +++ b/include/images/ex_index_scan.pngc @@ -0,0 +1,207 @@ +#ifndef EX_INDEX_SCAN_PNG_H +#define EX_INDEX_SCAN_PNG_H + +static const unsigned char ex_index_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x44, 0xbd, 0xe9, +0x75, 0xce, 0xef, 0x79, 0xd0, 0xef, 0x55, 0xc2, +0xe9, 0x86, 0xd4, 0xf0, 0x66, 0xc8, 0xec, 0x6a, +0xc9, 0xec, 0x6f, 0xca, 0xeb, 0x96, 0xd9, 0xf1, +0x7b, 0xce, 0xed, 0x82, 0xd1, 0xed, 0xa6, 0xde, +0xf2, 0x8e, 0xd4, 0xee, 0x92, 0xd6, 0xef, 0xaf, +0xe1, 0xf3, 0x05, 0xa7, 0xe1, 0x4d, 0xc1, 0xe9, +0x1b, 0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, 0xc7, +0xeb, 0x38, 0xb7, 0xe5, 0x50, 0xbe, 0xe7, 0x6b, +0xc7, 0xe8, 0x74, 0x93, 0x96, 0x7a, 0x9e, 0xa9, +0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0xc1, 0x8f, +0x36, 0xf1, 0xea, 0x87, 0xed, 0xe3, 0x60, 0xf3, +0xf0, 0xc8, 0xf0, 0xec, 0xb6, 0xef, 0xe9, 0xb5, +0xf2, 0xed, 0xc5, 0xee, 0xe6, 0xb3, 0xf1, 0xeb, +0xc4, 0xec, 0xe3, 0xb0, 0xf0, 0xe9, 0xc2, 0xe1, +0xef, 0xf7, 0xe7, 0xda, 0x2b, 0xea, 0xe4, 0x9d, +0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xef, 0xe8, +0xb3, 0xe8, 0xde, 0x99, 0xe7, 0xdc, 0x97, 0xed, +0xe5, 0xb1, 0xe6, 0xd9, 0x94, 0xe5, 0xd6, 0x93, +0xec, 0xe0, 0xad, 0xd6, 0xe9, 0xf5, 0xec, 0xe2, +0xaf, 0xe6, 0xda, 0x96, 0xec, 0xe1, 0xae, 0xe4, +0xd5, 0x92, 0xeb, 0xdf, 0xad, 0xed, 0xe6, 0xb2, +0xeb, 0xde, 0xac, 0xf0, 0xe6, 0xc0, 0xd4, 0xe9, +0xf4, 0xcb, 0xa2, 0x58, 0xdb, 0xbd, 0x89, 0xea, +0xdd, 0xaa, 0xef, 0xe4, 0xbe, 0xd3, 0xe8, 0xf3, +0xe4, 0xd4, 0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xd0, +0x8d, 0xe9, 0xda, 0xa9, 0xd1, 0xe7, 0xf2, 0xe4, +0xd3, 0x90, 0xe2, 0xce, 0x8c, 0xef, 0xe3, 0x5f, +0xe9, 0xdb, 0xaa, 0xe1, 0xcc, 0x8a, 0xe9, 0xd9, +0xa8, 0xf6, 0xeb, 0x87, 0xed, 0xe1, 0xbc, 0xcd, +0xe5, 0xf2, 0xf3, 0xe4, 0x5f, 0xe8, 0xd7, 0xa7, +0xe8, 0xd7, 0xa6, 0xed, 0xe0, 0xbb, 0xee, 0xdb, +0x2a, 0xf3, 0xdc, 0x2a, 0xe0, 0xc9, 0x89, 0xdf, +0xc8, 0x88, 0xdf, 0xc7, 0x87, 0xe6, 0xd4, 0xa4, +0xcb, 0xe4, 0xf1, 0xf9, 0xe6, 0x5f, 0xde, 0xc6, +0x86, 0xca, 0xe3, 0xf0, 0xe7, 0xd5, 0xa5, 0xe6, +0xd3, 0xa3, 0xc8, 0xe3, 0xf0, 0xfe, 0xec, 0x86, +0xef, 0xe5, 0xc0, 0xec, 0xdd, 0xba, 0xc7, 0xe3, +0xf0, 0xc5, 0xe1, 0xef, 0xff, 0xe6, 0x5f, 0xec, +0xde, 0xba, 0xe6, 0xd2, 0xa2, 0xe6, 0xd1, 0xa2, +0xe6, 0xd1, 0xa1, 0xec, 0xdc, 0xb8, 0xff, 0xde, +0x29, 0xde, 0xc4, 0x84, 0xdd, 0xc3, 0x83, 0xdc, +0xc1, 0x82, 0xe5, 0xd0, 0xa1, 0xdc, 0xbe, 0x80, +0xc2, 0xe0, 0xee, 0xe4, 0xce, 0x9f, 0xeb, 0xda, +0xb7, 0xc0, 0xdf, 0xee, 0xe4, 0xcd, 0x9e, 0xea, +0xd9, 0xb6, 0xbc, 0xdd, 0xed, 0xda, 0xbb, 0x7e, +0xe3, 0xcc, 0x9e, 0xad, 0xd6, 0xe9, 0xe3, 0xcb, +0x9e, 0x0f, 0xfa, 0x04, 0x51, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xc9, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0xd9, 0x5b, 0x12, 0x51, 0x18, +0x87, 0x6d, 0xa2, 0xb0, 0xdc, 0x53, 0xcb, 0x2c, +0xf9, 0x40, 0x60, 0x18, 0x5c, 0x59, 0x25, 0x24, +0xb0, 0x06, 0x05, 0x5c, 0x00, 0x91, 0x45, 0x50, +0x04, 0x19, 0x49, 0x45, 0x40, 0x65, 0x55, 0x04, +0xe1, 0x5f, 0xf7, 0xcc, 0x92, 0xc2, 0x71, 0xe2, +0x89, 0x9b, 0x9e, 0x2e, 0xfc, 0x2e, 0x0e, 0x37, +0xbc, 0xcf, 0x8f, 0xf7, 0xf7, 0x1d, 0x4e, 0x5f, +0xdf, 0xcb, 0xfc, 0xeb, 0x79, 0x45, 0xb0, 0xf3, +0xc7, 0x53, 0x0c, 0x21, 0x5e, 0x4b, 0x24, 0x92, +0x37, 0xc4, 0x5b, 0xa9, 0x54, 0xda, 0x4f, 0xf4, +0xbf, 0x7b, 0x3f, 0x30, 0x48, 0x0c, 0x0e, 0x0d, +0x0f, 0x8f, 0x10, 0x23, 0xa3, 0x63, 0x63, 0x1f, +0x08, 0x51, 0x44, 0x32, 0x3e, 0x3e, 0x3e, 0x41, +0x4c, 0x4c, 0x4e, 0x4e, 0x7e, 0x24, 0x3e, 0x4d, +0x4d, 0x4d, 0x0d, 0x10, 0x43, 0x9f, 0xa5, 0xd2, +0x61, 0x62, 0x74, 0x7a, 0x7a, 0x60, 0x8c, 0xe8, +0x96, 0x32, 0xf1, 0xf7, 0x29, 0x5f, 0xb8, 0xdf, +0xcc, 0x9f, 0x5f, 0x9f, 0x9f, 0x1d, 0xdf, 0x9d, +0x91, 0xc9, 0x66, 0xd0, 0x07, 0xc8, 0x15, 0x0a, +0x85, 0x1c, 0x66, 0x95, 0x4a, 0xe5, 0x2c, 0xcc, +0xaa, 0x54, 0x2a, 0x35, 0xa8, 0x49, 0x92, 0xd4, +0x80, 0x86, 0xa2, 0x28, 0x2d, 0x74, 0x20, 0xb2, +0xb9, 0x39, 0x19, 0x8b, 0x28, 0xe6, 0xe7, 0xe7, +0x15, 0xa0, 0x5c, 0x58, 0x58, 0x54, 0x81, 0x6a, +0x69, 0x69, 0x69, 0x19, 0x48, 0x9d, 0x5e, 0x6f, +0x00, 0xca, 0x68, 0x34, 0x99, 0x31, 0x64, 0x65, +0xa5, 0x03, 0x59, 0xe4, 0x11, 0x1d, 0x09, 0xa4, +0x5e, 0xaf, 0xa7, 0xc0, 0x62, 0x34, 0x75, 0x47, +0x54, 0x8b, 0x2c, 0xb2, 0xac, 0xd3, 0x21, 0xc4, +0xa0, 0xff, 0x66, 0xa4, 0xc0, 0x6a, 0x5a, 0x5d, +0xb5, 0x89, 0x23, 0x82, 0xcb, 0x6f, 0x8b, 0xef, +0x9c, 0x85, 0x45, 0x0b, 0x5a, 0xb3, 0xcd, 0xee, +0xc0, 0x90, 0xb5, 0x35, 0x16, 0xf9, 0x01, 0xec, +0xf0, 0xe7, 0xcf, 0xe7, 0xa7, 0x18, 0x22, 0xa4, +0xa8, 0x97, 0x49, 0x52, 0x0d, 0x1a, 0x83, 0x81, +0xd2, 0x80, 0xd6, 0x6a, 0x36, 0x3b, 0xc0, 0x41, +0xd3, 0xb4, 0x13, 0x4b, 0x59, 0x5f, 0x6f, 0x73, +0x79, 0xb2, 0xb0, 0xb0, 0x16, 0x1b, 0x76, 0xa0, +0x5d, 0x6e, 0xb7, 0x07, 0x43, 0x36, 0x37, 0xdb, +0x10, 0x52, 0xa7, 0xe3, 0x8b, 0x35, 0x5a, 0xc1, +0xbc, 0xba, 0xb1, 0x45, 0x03, 0xed, 0x76, 0x6f, +0x77, 0x41, 0x76, 0x84, 0x62, 0x29, 0xae, 0x58, +0xdb, 0x96, 0xcb, 0x45, 0x83, 0x77, 0x7b, 0xdb, +0xe7, 0x17, 0x47, 0xe4, 0x8a, 0x9d, 0x9d, 0x5d, +0x11, 0x0b, 0xa7, 0xc7, 0xef, 0x0f, 0x60, 0xc8, +0xde, 0x5e, 0xcf, 0x8d, 0xf1, 0x08, 0xc8, 0x83, +0xc1, 0x20, 0x4a, 0xa1, 0x2c, 0x56, 0x2d, 0x38, +0x6c, 0x76, 0xb4, 0x0b, 0xa7, 0xd7, 0xe3, 0x71, +0x42, 0x20, 0x14, 0x0a, 0x47, 0x44, 0x53, 0x20, +0xb8, 0xbf, 0x1f, 0x0d, 0x62, 0x16, 0x3e, 0x64, +0x11, 0x8a, 0x1d, 0x1c, 0xc6, 0x31, 0xe4, 0xe8, +0x48, 0x40, 0xa2, 0xd1, 0x04, 0x2a, 0xd6, 0x84, +0xae, 0x07, 0xed, 0x72, 0xb9, 0xbd, 0xe0, 0xf1, +0xf9, 0x7c, 0x21, 0x08, 0x1f, 0x1c, 0x26, 0x71, +0xe4, 0xf8, 0x98, 0x47, 0xa2, 0x2c, 0xc2, 0x16, +0x6b, 0x17, 0x8a, 0xf5, 0xfb, 0x62, 0xb1, 0x30, +0xa4, 0x92, 0xc9, 0x24, 0x83, 0x21, 0x27, 0x27, +0x1c, 0xb2, 0x9b, 0x48, 0x24, 0xd2, 0xac, 0x05, +0xfd, 0x8b, 0xb3, 0x08, 0x20, 0x8b, 0x70, 0x2a, +0x02, 0x91, 0x38, 0xc3, 0x9c, 0x62, 0xc8, 0xd9, +0x59, 0xcf, 0x8d, 0x9d, 0x9f, 0x73, 0x29, 0xe9, +0x44, 0x26, 0x93, 0x66, 0x77, 0xe1, 0x45, 0xbb, +0xf0, 0xfb, 0x43, 0x01, 0x88, 0xa4, 0xe2, 0xf1, +0x0b, 0x38, 0xcd, 0xe6, 0xf2, 0x97, 0x20, 0x8a, +0x64, 0xae, 0xae, 0xae, 0x32, 0xb8, 0xc5, 0x35, +0x03, 0xb9, 0x42, 0xb1, 0x58, 0xea, 0x86, 0xf0, +0xd7, 0x23, 0x14, 0x8b, 0x1d, 0xa4, 0x20, 0x9e, +0xbc, 0x2e, 0x64, 0x21, 0x5f, 0x2c, 0x96, 0x71, +0xa4, 0x52, 0x69, 0x43, 0x1e, 0x8b, 0x45, 0xbb, +0x60, 0xae, 0x0b, 0x85, 0x3c, 0x94, 0x8a, 0xe5, +0x72, 0x55, 0x1c, 0x49, 0x67, 0x58, 0x97, 0x0e, +0x8b, 0x5c, 0x2e, 0x7f, 0x03, 0x37, 0xa5, 0x6a, +0xf5, 0x06, 0x43, 0x6e, 0x6f, 0x7b, 0x6e, 0x8c, +0x47, 0x84, 0x94, 0x40, 0x38, 0x85, 0x76, 0x71, +0xc1, 0x30, 0xd9, 0x53, 0xb8, 0x2c, 0x95, 0x4a, +0x28, 0xa5, 0x5a, 0xab, 0xdd, 0xb5, 0xa7, 0xa0, +0x87, 0xaf, 0x5e, 0x67, 0x1f, 0x3f, 0xc1, 0x85, +0xbf, 0x1e, 0x4c, 0x81, 0xb3, 0x28, 0xb3, 0x16, +0xb5, 0x46, 0xa3, 0x71, 0xdf, 0x8e, 0xc8, 0xd6, +0xea, 0xcd, 0x66, 0x1d, 0xfd, 0xfb, 0x05, 0x24, +0x75, 0xc8, 0x5e, 0x8f, 0x2c, 0x57, 0xec, 0x13, +0xd2, 0xea, 0x4c, 0xa9, 0x34, 0x9b, 0x95, 0xa7, +0x94, 0x38, 0xda, 0x45, 0x16, 0x72, 0x45, 0x16, +0xa9, 0x96, 0xcb, 0x8d, 0x1a, 0xdc, 0xe3, 0x08, +0x62, 0xd0, 0x1d, 0x9b, 0x79, 0x74, 0xb9, 0x60, +0xb2, 0x98, 0xc5, 0x5d, 0xab, 0xd5, 0xba, 0xeb, +0x6c, 0x4c, 0x78, 0xc6, 0x7b, 0x69, 0xec, 0x65, +0xfe, 0xaf, 0x79, 0x00, 0xb6, 0x14, 0x06, 0x2a, +0x4c, 0xe8, 0x5e, 0xa2, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_index_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_index_scan_png = new wxImage(); + if (!img_ex_index_scan_png || !img_ex_index_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_index_scan_pngIS(ex_index_scan_png_data, sizeof(ex_index_scan_png_data)); + img_ex_index_scan_png->LoadFile(img_ex_index_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_index_scan_png; +} +#define ex_index_scan_png_img ex_index_scan_png_img() + +static wxBitmap *ex_index_scan_png_bmp() +{ + static wxBitmap *bmp_ex_index_scan_png; + if (!bmp_ex_index_scan_png || !bmp_ex_index_scan_png->IsOk()) + bmp_ex_index_scan_png = new wxBitmap(*ex_index_scan_png_img); + return bmp_ex_index_scan_png; +} +#define ex_index_scan_png_bmp ex_index_scan_png_bmp() + +static wxIcon *ex_index_scan_png_ico() +{ + static wxIcon *ico_ex_index_scan_png; + if (!ico_ex_index_scan_png || !ico_ex_index_scan_png->IsOk()) + { + ico_ex_index_scan_png = new wxIcon(); + ico_ex_index_scan_png->CopyFromBitmap(*ex_index_scan_png_bmp); + } + return ico_ex_index_scan_png; +} +#define ex_index_scan_png_ico ex_index_scan_png_ico() + +#endif // EX_INDEX_SCAN_PNG_H diff --git a/include/images/ex_insert.png b/include/images/ex_insert.png new file mode 100644 index 0000000..862d837 Binary files /dev/null and b/include/images/ex_insert.png differ diff --git a/include/images/ex_insert.pngc b/include/images/ex_insert.pngc new file mode 100644 index 0000000..7e82ef0 --- /dev/null +++ b/include/images/ex_insert.pngc @@ -0,0 +1,178 @@ +#ifndef EX_INSERT_PNG_H +#define EX_INSERT_PNG_H + +static const unsigned char ex_insert_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x3b, 0x50, 0x4c, 0x54, +0x45, 0x24, 0x00, 0x28, 0x5b, 0x5b, 0x5b, 0x36, +0x88, 0xc1, 0x09, 0xa9, 0xe2, 0x72, 0x96, 0xa1, +0x92, 0x92, 0x92, 0xc1, 0x8f, 0x36, 0xaa, 0x99, +0x38, 0x9d, 0x9f, 0x39, 0x32, 0xb5, 0xe5, 0x75, +0xa6, 0xc7, 0x41, 0xbc, 0xe8, 0xcb, 0xa2, 0x58, +0x12, 0xe3, 0x12, 0x0a, 0xe1, 0x46, 0x4a, 0xc0, +0xe9, 0xc7, 0xaa, 0x75, 0x5d, 0xc4, 0xea, 0x63, +0xc6, 0xea, 0x6b, 0xc7, 0xe8, 0x68, 0xc8, 0xec, +0xa9, 0xc5, 0x79, 0x6e, 0xcb, 0xec, 0x47, 0xec, +0x20, 0xb2, 0xc4, 0x7b, 0xc0, 0xc1, 0x80, 0x75, +0xcd, 0xec, 0xdb, 0xbd, 0x7f, 0xdb, 0xbd, 0x89, +0xdc, 0xbe, 0x80, 0xdc, 0xbf, 0x80, 0x7b, 0xd1, +0xef, 0xdc, 0xc1, 0x82, 0x84, 0xd1, 0xee, 0xdd, +0xc3, 0x83, 0x84, 0xd3, 0xf0, 0xde, 0xc4, 0x84, +0xde, 0xc5, 0x85, 0xde, 0xc6, 0x86, 0x8c, 0xd4, +0xee, 0xdf, 0xc7, 0x87, 0xdf, 0xc8, 0x88, 0x91, +0xd5, 0xee, 0xe0, 0xc9, 0x89, 0xe1, 0xcc, 0x8a, +0x97, 0xd9, 0xf1, 0xe2, 0xce, 0x8c, 0xe2, 0xd0, +0x8d, 0xe4, 0xce, 0x9f, 0xa0, 0xdb, 0xf1, 0xe3, +0xd2, 0x8f, 0xe5, 0xd0, 0xa1, 0xe4, 0xd3, 0x90, +0xe6, 0xd1, 0xa1, 0xe6, 0xd1, 0xa2, 0xe4, 0xd4, +0x91, 0xe6, 0xd2, 0xa2, 0xe4, 0xd5, 0x92, 0xe6, +0xd3, 0xa3, 0xe5, 0xd6, 0x93, 0xe6, 0xd4, 0xa4, +0xe7, 0xd5, 0xa5, 0xae, 0xe0, 0xf3, 0xe6, 0xd9, +0x94, 0xe8, 0xd7, 0xa6, 0xe8, 0xd7, 0xa7, 0xe6, +0xda, 0x96, 0xe9, 0xd8, 0xa7, 0xe9, 0xd9, 0xa8, +0xe7, 0xdc, 0x97, 0xe9, 0xda, 0xa9, 0xe9, 0xdb, +0xaa, 0xeb, 0xda, 0xb7, 0xe8, 0xde, 0x99, 0xea, +0xdd, 0xaa, 0xec, 0xdc, 0xb8, 0xe9, 0xe0, 0x9a, +0xeb, 0xde, 0xac, 0xec, 0xdd, 0xba, 0xeb, 0xdf, +0xad, 0xec, 0xde, 0xba, 0xec, 0xe0, 0xad, 0xea, +0xe3, 0x9c, 0xed, 0xdf, 0xbb, 0xec, 0xe1, 0xae, +0xed, 0xe0, 0xbb, 0xea, 0xe4, 0x9d, 0xec, 0xe2, +0xaf, 0xed, 0xe1, 0xbc, 0xec, 0xe3, 0xb0, 0xed, +0xe5, 0xb1, 0xef, 0xe4, 0xbe, 0xed, 0xe6, 0xb2, +0xee, 0xe6, 0xb3, 0xef, 0xe5, 0xc0, 0xf0, 0xe6, +0xc0, 0xef, 0xe8, 0xb3, 0xef, 0xe9, 0xb5, 0xf0, +0xe8, 0xc2, 0xf0, 0xe9, 0xc2, 0xf0, 0xec, 0xb6, +0xf1, 0xeb, 0xc4, 0xf2, 0xed, 0xc5, 0xf3, 0xed, +0xc6, 0xf3, 0xf0, 0xc8, 0x13, 0xc1, 0xb2, 0x65, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, +0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, +0x9c, 0x18, 0x00, 0x00, 0x02, 0x87, 0x49, 0x44, +0x41, 0x54, 0x48, 0xc7, 0xed, 0x95, 0x5b, 0x73, +0xd2, 0x50, 0x14, 0x46, 0x69, 0xd0, 0x4d, 0x11, +0xdb, 0x06, 0xab, 0xa0, 0xc5, 0x5a, 0xa0, 0x48, +0xb9, 0xa4, 0x40, 0xa1, 0x50, 0x08, 0x41, 0x88, +0x84, 0x5b, 0xe4, 0x52, 0x10, 0x0a, 0x01, 0x23, +0x20, 0xb7, 0xfe, 0xff, 0x5f, 0xe0, 0x49, 0xce, +0xe1, 0x12, 0x0c, 0x23, 0xce, 0x38, 0xa3, 0x0f, +0xdd, 0x0f, 0xeb, 0x81, 0xc9, 0x4a, 0xf6, 0xf7, +0x9d, 0x33, 0x83, 0xc1, 0xf0, 0x34, 0xff, 0x60, +0x5e, 0x50, 0xca, 0xec, 0xa4, 0x9e, 0x42, 0xd9, +0x2c, 0x16, 0xcb, 0x19, 0x75, 0x71, 0x62, 0xb5, +0x5e, 0x52, 0x97, 0xaf, 0x6d, 0xb6, 0x6b, 0xea, +0xfa, 0xc2, 0xe5, 0xba, 0xa1, 0x6e, 0xae, 0x02, +0x81, 0x4f, 0x94, 0xae, 0x62, 0x31, 0x1a, 0x8d, +0x16, 0xea, 0x04, 0xd1, 0x4a, 0xbd, 0x32, 0x9b, +0xcd, 0x36, 0xea, 0x0c, 0xe9, 0x2e, 0xea, 0xea, +0xf4, 0xd4, 0x16, 0xa0, 0xfe, 0xd2, 0x57, 0x9e, +0xa9, 0x3b, 0xef, 0xa4, 0x9e, 0x02, 0x8f, 0xd3, +0xe9, 0xf4, 0x71, 0xc9, 0xf1, 0x78, 0x3c, 0x87, +0xb9, 0x2c, 0xcb, 0x33, 0x98, 0x49, 0x92, 0x34, +0x01, 0xfc, 0x0c, 0x00, 0xbd, 0xa9, 0x4c, 0x1f, +0x1e, 0x5a, 0x63, 0xc2, 0x71, 0xb5, 0x5a, 0x1d, +0x81, 0x5c, 0x29, 0x14, 0xfa, 0x20, 0x65, 0xb3, +0xe9, 0x26, 0x60, 0x63, 0xf1, 0x83, 0xa6, 0x35, +0x4a, 0x4b, 0x55, 0x5a, 0x58, 0xa9, 0xc8, 0x20, +0x17, 0x0a, 0x05, 0x09, 0xba, 0xd9, 0xf4, 0x52, +0xf9, 0xba, 0x58, 0x0c, 0xf3, 0xb0, 0x56, 0xc6, +0x2d, 0xf5, 0x61, 0x95, 0xa3, 0x4a, 0x05, 0x29, +0xfd, 0xc2, 0xe7, 0xac, 0x04, 0xed, 0x74, 0x2a, +0xd5, 0x20, 0x4a, 0x3e, 0x4f, 0x37, 0x17, 0xb0, +0xce, 0xa2, 0xee, 0xbf, 0x4a, 0xf1, 0x4d, 0x4d, +0xd1, 0x9d, 0xc0, 0xa4, 0xd9, 0xa8, 0x0d, 0x49, +0x16, 0x07, 0xfd, 0x91, 0x99, 0xae, 0x9c, 0x97, +0xa0, 0xcc, 0xfb, 0x5d, 0x24, 0xef, 0x75, 0xb4, +0x3e, 0xac, 0x1d, 0x98, 0x8f, 0x64, 0x79, 0x4e, +0x38, 0xeb, 0xf7, 0xa5, 0x19, 0x4c, 0xda, 0xcd, +0xe6, 0x10, 0x86, 0xa2, 0x28, 0x0e, 0x96, 0x2f, +0xd6, 0x38, 0x64, 0xff, 0x75, 0x8a, 0xae, 0x92, +0xe2, 0xae, 0x06, 0x62, 0x34, 0x1c, 0x2e, 0xae, +0xf7, 0xdf, 0x70, 0x50, 0xa5, 0x15, 0x54, 0x29, +0x26, 0x2a, 0x36, 0xdb, 0x86, 0x66, 0xea, 0xee, +0x56, 0x04, 0x31, 0x1c, 0x0e, 0x15, 0x37, 0x6a, +0x52, 0x1d, 0x35, 0x1c, 0xa9, 0x14, 0x53, 0x52, +0x8b, 0x6d, 0xdc, 0x46, 0xa3, 0x22, 0x94, 0x42, +0x21, 0x46, 0x00, 0x83, 0xd6, 0xa1, 0x39, 0xf4, +0x0b, 0xd9, 0xff, 0xd7, 0x14, 0x83, 0xa2, 0x20, +0xf4, 0x60, 0xf3, 0xd0, 0xc1, 0xa1, 0x1c, 0x2a, +0xec, 0xd7, 0xd8, 0xd2, 0x41, 0x16, 0x8a, 0x83, +0x4e, 0xa1, 0xdb, 0x9e, 0x10, 0x0e, 0x1b, 0x35, +0x74, 0x16, 0x83, 0x52, 0xb1, 0x38, 0x80, 0x1e, +0xcf, 0xe7, 0x3a, 0xa0, 0xbd, 0x8f, 0xc0, 0xe7, +0x9f, 0x1f, 0x18, 0xc8, 0xfe, 0xda, 0x14, 0x0c, +0x4a, 0xc1, 0x07, 0xfd, 0x3e, 0x0e, 0xb6, 0xee, +0x30, 0xc0, 0x01, 0x52, 0xda, 0xe9, 0x34, 0xba, +0x18, 0x98, 0x62, 0x34, 0x1a, 0x2e, 0x41, 0x91, +0x61, 0x18, 0x1e, 0x72, 0x7e, 0x9f, 0x77, 0x5b, +0x21, 0xa2, 0x52, 0x69, 0x8d, 0x10, 0x17, 0x2b, +0x30, 0xc1, 0x60, 0x0e, 0x32, 0x5e, 0xaf, 0x97, +0xd5, 0x57, 0xd0, 0xfe, 0xe2, 0x77, 0x42, 0x25, +0x45, 0x0f, 0xa5, 0xc8, 0x65, 0x3a, 0xd0, 0xe1, +0x58, 0xb6, 0xae, 0xab, 0xfc, 0x41, 0x63, 0xeb, +0xaf, 0x88, 0x62, 0x69, 0x40, 0x38, 0x10, 0x04, +0xbe, 0x07, 0x9d, 0x0c, 0xc7, 0xdd, 0x43, 0x3d, +0x99, 0x88, 0x7f, 0xd1, 0x5f, 0x0c, 0xef, 0xbf, +0x95, 0xc2, 0xc3, 0x42, 0xc2, 0xed, 0x74, 0xc6, +0xf4, 0x15, 0x7c, 0x31, 0x30, 0xf9, 0x60, 0xd0, +0x9f, 0x01, 0xce, 0xeb, 0x71, 0x27, 0x21, 0xee, +0x74, 0x9e, 0xef, 0x50, 0x70, 0xa5, 0xab, 0x62, +0xd1, 0x59, 0xb0, 0x1e, 0xb7, 0x3b, 0x0e, 0x31, +0xe7, 0xf9, 0x79, 0x44, 0x5f, 0xc1, 0xfb, 0x6b, +0x52, 0x24, 0x12, 0xf1, 0x32, 0x94, 0x63, 0x91, +0x48, 0xf9, 0xb7, 0x8d, 0xbd, 0x33, 0x29, 0xa3, +0xa1, 0xee, 0x57, 0x7a, 0xb9, 0x0c, 0x3a, 0x05, +0x95, 0xa6, 0x23, 0x65, 0x0e, 0x8f, 0x95, 0x21, +0xd4, 0x55, 0xf0, 0xc5, 0x50, 0x69, 0x3a, 0xb2, +0xdb, 0xed, 0x48, 0x41, 0x3c, 0x26, 0xd4, 0x55, +0x32, 0x3e, 0xe5, 0x62, 0xa8, 0xdc, 0x57, 0xe1, +0xd0, 0x29, 0x24, 0x31, 0xf7, 0x55, 0xee, 0xd9, +0x64, 0xb2, 0x8e, 0xb9, 0x67, 0x96, 0xcd, 0xc6, +0xde, 0x1c, 0x2a, 0xf3, 0x76, 0x93, 0x4f, 0x7f, +0xf3, 0xff, 0xeb, 0xfc, 0x04, 0xb9, 0x24, 0xbf, +0x70, 0x98, 0x34, 0xea, 0x9e, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_insert_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_insert_png = new wxImage(); + if (!img_ex_insert_png || !img_ex_insert_png->IsOk()) + { + wxMemoryInputStream img_ex_insert_pngIS(ex_insert_png_data, sizeof(ex_insert_png_data)); + img_ex_insert_png->LoadFile(img_ex_insert_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_insert_png; +} +#define ex_insert_png_img ex_insert_png_img() + +static wxBitmap *ex_insert_png_bmp() +{ + static wxBitmap *bmp_ex_insert_png; + if (!bmp_ex_insert_png || !bmp_ex_insert_png->IsOk()) + bmp_ex_insert_png = new wxBitmap(*ex_insert_png_img); + return bmp_ex_insert_png; +} +#define ex_insert_png_bmp ex_insert_png_bmp() + +static wxIcon *ex_insert_png_ico() +{ + static wxIcon *ico_ex_insert_png; + if (!ico_ex_insert_png || !ico_ex_insert_png->IsOk()) + { + ico_ex_insert_png = new wxIcon(); + ico_ex_insert_png->CopyFromBitmap(*ex_insert_png_bmp); + } + return ico_ex_insert_png; +} +#define ex_insert_png_ico ex_insert_png_ico() + +#endif // EX_INSERT_PNG_H diff --git a/include/images/ex_join.png b/include/images/ex_join.png new file mode 100644 index 0000000..c391233 Binary files /dev/null and b/include/images/ex_join.png differ diff --git a/include/images/ex_join.pngc b/include/images/ex_join.pngc new file mode 100644 index 0000000..101d819 --- /dev/null +++ b/include/images/ex_join.pngc @@ -0,0 +1,181 @@ +#ifndef EX_JOIN_PNG_H +#define EX_JOIN_PNG_H + +static const unsigned char ex_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x45, 0xbe, 0xe9, +0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, 0x85, 0xd4, +0xf0, 0x94, 0xd8, 0xf0, 0x7a, 0xce, 0xec, 0x83, +0xd1, 0xed, 0x8b, 0xd4, 0xee, 0xad, 0xdf, 0xf3, +0x40, 0xbc, 0xe9, 0x07, 0xa8, 0xe2, 0x10, 0xab, +0xe2, 0x1a, 0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, +0xcb, 0xec, 0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, +0x64, 0xc5, 0xe8, 0x92, 0xd5, 0xef, 0x5c, 0x8d, +0xc8, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, 0xf1, 0xbd, +0xbf, 0xed, 0xbf, 0xc1, 0xed, 0xc2, 0xc2, 0xee, +0xd3, 0xd4, 0xf3, 0xd8, 0xd9, 0xf4, 0xce, 0xcf, +0xf2, 0xd1, 0xd1, 0xf2, 0xd4, 0xd4, 0xf4, 0xe0, +0xe0, 0xf7, 0x72, 0x96, 0xa1, 0x5b, 0x87, 0xb8, +0xbc, 0xbd, 0xec, 0xa7, 0xa9, 0xe7, 0xaa, 0xac, +0xe7, 0xae, 0xaf, 0xe9, 0xc5, 0xc6, 0xef, 0xcb, +0xcc, 0xf1, 0xbe, 0xbf, 0xed, 0xc5, 0xc6, 0xf0, +0xd6, 0xd6, 0xf4, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xc0, 0xc1, 0xee, 0xc6, +0xc7, 0xef, 0xcd, 0xce, 0xf2, 0xde, 0xde, 0xf6, +0xeb, 0xe6, 0x9f, 0xab, 0xac, 0xe8, 0xb3, 0xb4, +0xea, 0xbc, 0xbd, 0xed, 0xd4, 0xd4, 0xf3, 0x92, +0x95, 0xd1, 0x86, 0xa9, 0x64, 0x52, 0x8d, 0x19, +0x7f, 0xa5, 0x5b, 0xb3, 0xc1, 0xa6, 0xa1, 0xc4, +0x5e, 0x85, 0xb2, 0x46, 0xc7, 0xaa, 0x75, 0x8e, +0x85, 0xab, 0x72, 0xa3, 0x35, 0xa2, 0xc7, 0x60, +0xf0, 0xec, 0xb6, 0xa6, 0xcc, 0x65, 0xeb, 0xe5, +0x9e, 0xea, 0xe4, 0x9d, 0xef, 0xe9, 0xb4, 0xef, +0xeb, 0xb6, 0xef, 0xe8, 0xb3, 0xf2, 0xec, 0xc5, +0x84, 0xa8, 0x62, 0x76, 0xaa, 0x3b, 0x9e, 0xb5, +0x87, 0xae, 0xda, 0x71, 0x78, 0xae, 0x3e, 0xf3, +0xee, 0xc6, 0xee, 0xe6, 0xb2, 0xed, 0xe5, 0xb1, +0xec, 0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0xb5, 0xe4, +0x7a, 0xe6, 0xda, 0x96, 0xe5, 0xd7, 0x93, 0xe4, +0xd3, 0x90, 0xea, 0xdc, 0xaa, 0x7b, 0xb3, 0x42, +0xe4, 0xd5, 0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xcf, +0x8d, 0xe9, 0xd8, 0xa7, 0x8d, 0xc1, 0x53, 0xeb, +0xde, 0xac, 0xe2, 0xd0, 0x8e, 0xe1, 0xcd, 0x8b, +0xe0, 0xca, 0x89, 0xe7, 0xd4, 0xa4, 0xee, 0xe2, +0xbd, 0xe8, 0xd7, 0xa6, 0xec, 0xdd, 0xb9, 0xb9, +0xeb, 0x7f, 0xba, 0xee, 0x82, 0xe5, 0xd1, 0xa1, +0xe4, 0xce, 0x9f, 0xea, 0xd8, 0xb6, 0xec, 0xe3, +0xb0, 0xbc, 0xf0, 0x84, 0xdc, 0xbe, 0x80, 0xdb, +0xbc, 0x7e, 0xda, 0xba, 0x7d, 0xe3, 0xcb, 0x9e, +0xea, 0xe3, 0x9c, 0xe9, 0xe1, 0x9b, 0x96, 0xcc, +0x5d, 0xe8, 0xdf, 0x99, 0xec, 0xe0, 0xad, 0xe9, +0xda, 0xa9, 0xf0, 0xe9, 0xc2, 0xef, 0xe6, 0xc0, +0xde, 0xc5, 0x85, 0xdd, 0xc1, 0x82, 0xe4, 0xcd, +0x9e, 0xb5, 0x43, 0xee, 0xe6, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0xf9, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x93, 0xd9, 0x5b, 0xd3, 0x40, 0x14, +0xc5, 0x63, 0x50, 0x40, 0x94, 0x55, 0xc5, 0x41, +0x50, 0x94, 0xd5, 0xf5, 0x36, 0x2e, 0x55, 0x34, +0xa3, 0x05, 0xb1, 0x2c, 0x65, 0x29, 0x2d, 0x2d, +0x05, 0xba, 0x5a, 0x30, 0x6d, 0x35, 0x69, 0xa9, +0x0d, 0x05, 0x0a, 0x2d, 0xff, 0x3a, 0x49, 0x3a, +0xf2, 0x11, 0x33, 0x03, 0x03, 0x3c, 0xf0, 0xc2, +0x7d, 0x98, 0x97, 0x7c, 0xbf, 0x7b, 0x72, 0xce, +0x77, 0xae, 0x20, 0x5c, 0xcf, 0x45, 0xe6, 0x86, +0x68, 0x0e, 0x79, 0xf9, 0x10, 0xb1, 0xe1, 0xe6, +0xad, 0xc6, 0x26, 0xb1, 0xf9, 0x76, 0xcb, 0x9d, +0xbb, 0x22, 0xdf, 0x32, 0xb1, 0xb5, 0xad, 0xbd, +0xa3, 0x53, 0xec, 0xba, 0x77, 0xff, 0x41, 0xb7, +0xc8, 0xb7, 0x8c, 0xad, 0xc2, 0x5c, 0xf6, 0xd0, +0x12, 0x26, 0x2f, 0x9f, 0x0a, 0xea, 0x79, 0xd4, +0xdb, 0xf7, 0x18, 0x3d, 0xe9, 0x7f, 0xfa, 0x6c, +0x00, 0xd9, 0x90, 0x41, 0x6b, 0xcd, 0x90, 0x73, +0x19, 0x1a, 0x1e, 0x19, 0x7d, 0xfe, 0x02, 0xbd, +0x7c, 0xd5, 0xf7, 0xfa, 0x8d, 0x1d, 0x01, 0x97, +0x24, 0x49, 0x2e, 0xd4, 0xf3, 0xf6, 0xdd, 0xfb, +0x0f, 0x88, 0x13, 0x91, 0xdc, 0x6e, 0xb7, 0x84, +0x86, 0x3f, 0x7e, 0x1a, 0xfb, 0x7c, 0x69, 0x84, +0xe9, 0x85, 0x89, 0x7c, 0x41, 0xe6, 0x90, 0x57, +0x10, 0x64, 0x8c, 0xbf, 0x7e, 0x3b, 0xcb, 0x8b, +0x5d, 0x05, 0x7b, 0x3c, 0xe3, 0x84, 0x99, 0x00, +0x73, 0xbe, 0xff, 0x5b, 0xc6, 0xf4, 0x22, 0xe3, +0x49, 0x83, 0x39, 0x67, 0x62, 0xf2, 0xa4, 0x07, +0x9f, 0x37, 0x31, 0xfc, 0xe3, 0x04, 0xe2, 0xe5, +0x4a, 0x0c, 0x4f, 0x1d, 0x23, 0xd3, 0x33, 0xb3, +0x67, 0x27, 0x76, 0x12, 0x71, 0xf9, 0x7c, 0x73, +0xf3, 0x14, 0x2f, 0xce, 0x59, 0x18, 0x5f, 0x94, +0x4f, 0x4d, 0xcc, 0x39, 0xfe, 0xc5, 0xa5, 0x80, +0xc9, 0x40, 0x70, 0x39, 0x14, 0x5e, 0xe1, 0x52, +0x11, 0xe4, 0x40, 0xc4, 0xfc, 0x35, 0x08, 0xad, +0xae, 0xad, 0x47, 0x29, 0x5e, 0x9c, 0xe7, 0xea, +0x0f, 0x44, 0x62, 0x96, 0x4a, 0x38, 0x9e, 0x48, +0xa6, 0x28, 0x88, 0xf3, 0x90, 0x16, 0x7e, 0x5a, +0x84, 0x00, 0xe9, 0x8d, 0xcd, 0x5f, 0x0a, 0x0d, +0x71, 0x9c, 0x2b, 0x8e, 0x90, 0xc4, 0x32, 0xa9, +0xac, 0x92, 0xa3, 0x78, 0x71, 0xaa, 0xe0, 0xdf, +0xf8, 0xf4, 0x8e, 0xd5, 0xcf, 0x95, 0xbc, 0x75, +0xe4, 0x0f, 0x51, 0xc9, 0xa9, 0xaa, 0x96, 0xa7, +0xa8, 0x18, 0xe5, 0xf3, 0xfa, 0x82, 0x30, 0x1f, +0x2a, 0x84, 0x57, 0xc0, 0xca, 0x2b, 0xb6, 0x45, +0x10, 0xb5, 0xf8, 0xb7, 0xa4, 0x53, 0xbc, 0x80, +0x77, 0x66, 0xbb, 0x3c, 0x67, 0x06, 0x1a, 0x4f, +0x83, 0xd9, 0xe4, 0xd8, 0xd6, 0x0e, 0x69, 0xb2, +0x56, 0x2a, 0xd1, 0x11, 0xdf, 0x76, 0x79, 0x77, +0x19, 0x0a, 0x6b, 0xf1, 0x44, 0x14, 0xcc, 0xbf, +0x32, 0x88, 0xfa, 0xbd, 0x80, 0xce, 0x42, 0x66, +0xcb, 0xbb, 0xab, 0x05, 0xd8, 0x5b, 0x4f, 0x24, +0x2b, 0x60, 0xbf, 0xca, 0xbc, 0xae, 0xeb, 0x54, +0x2f, 0x46, 0x2d, 0x0a, 0xfb, 0x70, 0x10, 0xad, +0xa4, 0x32, 0x60, 0x2b, 0x01, 0x33, 0xb1, 0xfa, +0x07, 0xf2, 0xda, 0x10, 0xb6, 0xca, 0x7e, 0x78, +0x2f, 0x7d, 0x00, 0x99, 0xac, 0xa2, 0xe4, 0xec, +0x2a, 0x6c, 0x2f, 0x46, 0x93, 0x36, 0x2a, 0x90, +0xaa, 0x56, 0x6b, 0x2a, 0x2f, 0x92, 0x4e, 0x24, +0x37, 0xb3, 0xa0, 0x54, 0x6b, 0x35, 0x8d, 0x17, +0x89, 0x26, 0x8d, 0xf2, 0x81, 0x5a, 0x2b, 0x16, +0x0f, 0xff, 0x43, 0x98, 0x5e, 0xac, 0xf2, 0x41, +0x4e, 0xd3, 0x0e, 0xf3, 0x97, 0x4e, 0xec, 0x7a, +0xae, 0x66, 0x8e, 0x00, 0xfe, 0x64, 0xb7, 0xba, +0x0a, 0x9b, 0x95, 0x81, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_join_png = new wxImage(); + if (!img_ex_join_png || !img_ex_join_png->IsOk()) + { + wxMemoryInputStream img_ex_join_pngIS(ex_join_png_data, sizeof(ex_join_png_data)); + img_ex_join_png->LoadFile(img_ex_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_join_png; +} +#define ex_join_png_img ex_join_png_img() + +static wxBitmap *ex_join_png_bmp() +{ + static wxBitmap *bmp_ex_join_png; + if (!bmp_ex_join_png || !bmp_ex_join_png->IsOk()) + bmp_ex_join_png = new wxBitmap(*ex_join_png_img); + return bmp_ex_join_png; +} +#define ex_join_png_bmp ex_join_png_bmp() + +static wxIcon *ex_join_png_ico() +{ + static wxIcon *ico_ex_join_png; + if (!ico_ex_join_png || !ico_ex_join_png->IsOk()) + { + ico_ex_join_png = new wxIcon(); + ico_ex_join_png->CopyFromBitmap(*ex_join_png_bmp); + } + return ico_ex_join_png; +} +#define ex_join_png_ico ex_join_png_ico() + +#endif // EX_JOIN_PNG_H diff --git a/include/images/ex_limit.png b/include/images/ex_limit.png new file mode 100644 index 0000000..cc3efd5 Binary files /dev/null and b/include/images/ex_limit.png differ diff --git a/include/images/ex_limit.pngc b/include/images/ex_limit.pngc new file mode 100644 index 0000000..da5541e --- /dev/null +++ b/include/images/ex_limit.pngc @@ -0,0 +1,199 @@ +#ifndef EX_LIMIT_PNG_H +#define EX_LIMIT_PNG_H + +static const unsigned char ex_limit_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x44, 0xbd, 0xe9, +0x75, 0xce, 0xef, 0x79, 0xd0, 0xef, 0x54, 0xc2, +0xea, 0x86, 0xd4, 0xf0, 0x66, 0xc8, 0xec, 0x6a, +0xc9, 0xec, 0x6f, 0xca, 0xeb, 0x96, 0xd9, 0xf1, +0x7b, 0xce, 0xed, 0x82, 0xd1, 0xed, 0xa6, 0xde, +0xf2, 0x8e, 0xd4, 0xee, 0x92, 0xd6, 0xef, 0xaf, +0xe1, 0xf3, 0x05, 0xa7, 0xe1, 0x4d, 0xc1, 0xe9, +0x1b, 0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, 0xc7, +0xeb, 0x38, 0xb7, 0xe5, 0x50, 0xbe, 0xe7, 0x55, +0xc0, 0xe7, 0x59, 0xc1, 0xe7, 0x6b, 0xc7, 0xe8, +0xb9, 0x63, 0x63, 0xa9, 0x17, 0x17, 0xf0, 0x72, +0x72, 0xed, 0x71, 0x71, 0xe9, 0x70, 0x70, 0xe7, +0x6f, 0x70, 0xe5, 0x6f, 0x6f, 0xe1, 0x6e, 0x6e, +0xdd, 0x6d, 0x6d, 0xd9, 0x6c, 0x6c, 0xd3, 0x6b, +0x6b, 0x86, 0xa9, 0x64, 0x52, 0x8d, 0x19, 0xc1, +0x8f, 0x36, 0xf4, 0xf1, 0xc8, 0xf0, 0xec, 0xb7, +0xef, 0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xef, 0xe9, +0xb4, 0xf3, 0xed, 0xc6, 0xf2, 0xec, 0xc5, 0xee, +0xe6, 0xb3, 0xed, 0xe6, 0xb2, 0xed, 0xe5, 0xb1, +0xf1, 0xeb, 0xc4, 0xec, 0xe2, 0xaf, 0xec, 0xe1, +0xae, 0xec, 0xe0, 0xad, 0xf0, 0xe8, 0xc2, 0xa2, +0xc6, 0x60, 0xeb, 0xe5, 0x9e, 0xea, 0xe3, 0x9c, +0xef, 0xea, 0xb5, 0xe9, 0xe0, 0x9a, 0xe7, 0xdc, +0x97, 0xe7, 0xdb, 0x96, 0xec, 0xe3, 0xb0, 0xe5, +0xd7, 0x93, 0xe5, 0xd5, 0x92, 0xeb, 0xdf, 0xad, +0xa6, 0xcc, 0x65, 0xe8, 0xde, 0x99, 0xe6, 0xd9, +0x95, 0xe4, 0xd4, 0x91, 0xe4, 0xd3, 0x90, 0xea, +0xdd, 0xaa, 0xef, 0xe8, 0xb3, 0xe8, 0xdd, 0x98, +0xe6, 0xd8, 0x94, 0xe3, 0xd2, 0x8f, 0xaa, 0xd3, +0x6b, 0xef, 0xe6, 0xc0, 0xef, 0xe4, 0xbf, 0xae, +0xd9, 0x70, 0xc7, 0xaa, 0x75, 0xb1, 0xde, 0x75, +0xed, 0xe4, 0xb0, 0xeb, 0xde, 0xac, 0xe9, 0xdb, +0xaa, 0xe9, 0xda, 0xa8, 0xee, 0xe1, 0xbd, 0xb4, +0xe3, 0x79, 0xb6, 0xe7, 0x7c, 0xb8, 0xea, 0x7f, +0xe2, 0xce, 0x8c, 0xe1, 0xcc, 0x8b, 0xe9, 0xd8, +0xa7, 0xb9, 0xeb, 0x80, 0xe3, 0xd0, 0x8e, 0xe0, +0xca, 0x89, 0xe8, 0xd7, 0xa6, 0xe7, 0xd6, 0xa6, +0xe7, 0xd5, 0xa5, 0xed, 0xdf, 0xbb, 0xcd, 0x69, +0x69, 0xec, 0xdd, 0xba, 0xe6, 0xd2, 0xa3, 0xe6, +0xd1, 0xa2, 0xec, 0xdc, 0xb8, 0xdf, 0xc8, 0x87, +0xdf, 0xc6, 0x86, 0xe6, 0xd4, 0xa4, 0xdd, 0xc2, +0x83, 0xdd, 0xc1, 0x82, 0xe5, 0xd0, 0xa1, 0xde, +0xc4, 0x85, 0xdc, 0xc0, 0x81, 0xdd, 0xc3, 0x84, +0xdb, 0xbe, 0x80, 0xe4, 0xce, 0x9f, 0xef, 0xe5, +0xc0, 0xeb, 0xda, 0xb7, 0xe6, 0xd3, 0xa3, 0xe6, +0xd1, 0xa1, 0xe4, 0xcd, 0x9e, 0xe3, 0xcc, 0x9e, +0xea, 0xd9, 0xb6, 0xda, 0xbb, 0x7d, 0xe3, 0xcb, +0x9e, 0x09, 0x9d, 0x91, 0xe8, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x8c, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x93, 0xed, 0x53, 0x12, 0x51, 0x14, +0xc6, 0x69, 0xa3, 0xb0, 0x50, 0xd4, 0x90, 0xb2, +0x54, 0x82, 0x94, 0x64, 0x8f, 0xc8, 0xea, 0x8a, +0xbc, 0x24, 0x6f, 0x0b, 0x04, 0xb8, 0x88, 0x49, +0x29, 0x2f, 0x9a, 0x10, 0xa0, 0x26, 0x88, 0xc8, +0x82, 0x10, 0x88, 0xc2, 0xbf, 0xde, 0x5d, 0xb8, +0x60, 0xe0, 0x62, 0x4e, 0xf6, 0xa1, 0x66, 0x7c, +0x3e, 0xdc, 0xd9, 0x9d, 0x39, 0xbf, 0x39, 0xf7, +0x39, 0xcf, 0xb9, 0x22, 0xd1, 0x83, 0xfe, 0x6d, +0x3d, 0x22, 0x78, 0x0d, 0x3c, 0x85, 0x10, 0xe2, +0xb1, 0x58, 0x2c, 0x7e, 0x42, 0x3c, 0x95, 0x48, +0x24, 0x43, 0xc4, 0xd0, 0xb3, 0xe7, 0xd2, 0x61, +0x62, 0x78, 0x44, 0x26, 0x1b, 0x25, 0x46, 0xc7, +0xc6, 0xc7, 0x5f, 0x10, 0x82, 0x88, 0x58, 0x2e, +0x97, 0x8b, 0x89, 0x09, 0x85, 0x42, 0xf1, 0x92, +0x78, 0x35, 0x39, 0x39, 0x29, 0x25, 0x46, 0x5e, +0xbf, 0x99, 0x92, 0x11, 0x63, 0xd3, 0xd3, 0xd2, +0x71, 0xe2, 0xb6, 0x2e, 0x13, 0x92, 0xa9, 0x3b, +0x74, 0x99, 0x51, 0xde, 0x4d, 0x33, 0xd7, 0x88, +0xf2, 0x6d, 0x9f, 0x54, 0x2a, 0x95, 0x5a, 0xa5, +0x56, 0xbf, 0x9b, 0x9d, 0x9d, 0x9d, 0x9b, 0x9b, +0xd3, 0x68, 0x34, 0xef, 0x91, 0xe6, 0xe7, 0x95, +0xf7, 0xea, 0xa2, 0x25, 0xb5, 0x22, 0x11, 0x2c, +0xe8, 0x74, 0xba, 0x05, 0xfe, 0x5c, 0xd4, 0x83, +0x9e, 0xa2, 0xa8, 0x25, 0x58, 0xa6, 0x57, 0x0c, +0xab, 0xb0, 0x6a, 0x34, 0x99, 0x2d, 0x80, 0xab, +0x3a, 0x22, 0x3f, 0x90, 0x08, 0xd1, 0xad, 0xad, +0xad, 0xe9, 0xd0, 0x69, 0xb5, 0xda, 0x80, 0xb2, +0xdb, 0xed, 0x34, 0xd0, 0x0e, 0xa7, 0x93, 0x01, +0xa3, 0xcb, 0xed, 0xf6, 0x00, 0xae, 0xea, 0x22, +0x1f, 0xaf, 0x91, 0x45, 0xab, 0xd5, 0x4a, 0x21, +0xc4, 0xeb, 0xa5, 0xc1, 0xe0, 0xf4, 0xf9, 0x8c, +0x60, 0x76, 0xfb, 0xd7, 0x59, 0xc0, 0x55, 0x42, +0x88, 0xad, 0x85, 0x04, 0xbc, 0xde, 0x0d, 0x03, +0x30, 0x3e, 0x5f, 0xd0, 0x04, 0x66, 0xff, 0xfa, +0xe6, 0x4d, 0xe4, 0x13, 0xd9, 0xf6, 0xd2, 0x76, +0x11, 0xe0, 0x5d, 0x18, 0xba, 0x2e, 0xb6, 0x58, +0x96, 0x0d, 0x01, 0xae, 0xea, 0x22, 0x9f, 0xd1, +0xcf, 0x17, 0xe0, 0x35, 0xf0, 0xc4, 0x55, 0x9d, +0x79, 0x91, 0xdb, 0x24, 0xa9, 0x05, 0xfd, 0xa2, +0x8d, 0xd2, 0xc3, 0x52, 0x80, 0xa6, 0x97, 0x61, +0x75, 0x87, 0x61, 0x2c, 0x60, 0x31, 0x7b, 0xc2, +0x5b, 0x10, 0x8a, 0x44, 0xa3, 0x31, 0xc0, 0x55, +0x9d, 0x1e, 0xdb, 0xbb, 0x7b, 0x5f, 0x49, 0xde, +0x85, 0x9d, 0x02, 0x1a, 0xbb, 0x08, 0xba, 0xcc, +0xd8, 0x45, 0x64, 0x3f, 0x1e, 0x4f, 0x00, 0xae, +0xea, 0x74, 0xd9, 0xdd, 0xfb, 0x86, 0xba, 0x50, +0x56, 0xbb, 0x3d, 0x00, 0xf4, 0x86, 0xc3, 0xb9, +0x03, 0x4c, 0xd0, 0xe5, 0x36, 0x43, 0x78, 0x33, +0x99, 0x8c, 0x40, 0x34, 0x1e, 0x4f, 0xa5, 0x01, +0x57, 0x75, 0x6f, 0xc6, 0x7f, 0xf3, 0x59, 0xa0, +0xc1, 0xae, 0x38, 0x9c, 0x3e, 0x06, 0x4c, 0x2e, +0xb7, 0x3f, 0x0c, 0x6c, 0x72, 0x7f, 0x3f, 0x0a, +0x89, 0x54, 0x2a, 0x75, 0x00, 0xb8, 0xaa, 0x37, +0x7d, 0xec, 0x82, 0xe9, 0x77, 0x11, 0x4b, 0x1f, +0x1c, 0x1e, 0xf5, 0xa7, 0xff, 0x27, 0x9b, 0x7c, +0x73, 0x69, 0x91, 0xbe, 0xdf, 0xd0, 0xfd, 0x36, +0xb9, 0x25, 0xde, 0x85, 0x51, 0xc8, 0xc5, 0x71, +0x26, 0x93, 0x3d, 0x01, 0xa1, 0x87, 0x8c, 0xb3, +0xf0, 0xac, 0x6f, 0x26, 0x59, 0x7e, 0xb0, 0xf1, +0x34, 0x1c, 0xe4, 0x4e, 0x4f, 0xf3, 0x90, 0x39, +0x2b, 0x14, 0x38, 0x61, 0xc4, 0xe8, 0x72, 0xa1, +0x25, 0x67, 0x71, 0x16, 0x29, 0x94, 0xc5, 0xe1, +0x69, 0xb1, 0x98, 0x81, 0x6c, 0xa1, 0x54, 0x1a, +0x80, 0x98, 0xdc, 0x3d, 0x59, 0xe4, 0x0e, 0x21, +0x5f, 0x2c, 0x9e, 0x67, 0x81, 0x2b, 0x95, 0xca, +0x15, 0x61, 0xc4, 0xe2, 0x09, 0xb3, 0x3f, 0x20, +0x14, 0xfd, 0xd5, 0x45, 0x16, 0xb9, 0xa8, 0x72, +0x95, 0x4a, 0x55, 0x10, 0xf9, 0xed, 0x26, 0x0b, +0x74, 0x41, 0xef, 0x22, 0x12, 0x82, 0x58, 0x22, +0x9d, 0x3e, 0x82, 0xa3, 0x7c, 0xbe, 0x76, 0x0c, +0x27, 0x17, 0x1c, 0x57, 0x85, 0x6a, 0xa5, 0x7e, +0x79, 0x25, 0x7c, 0xb1, 0x5e, 0x17, 0xe7, 0x5d, +0x17, 0xf5, 0x46, 0xa3, 0xd1, 0x14, 0x46, 0xda, +0x4b, 0x9e, 0xce, 0xe5, 0xd0, 0x60, 0x6b, 0xe7, +0x67, 0x85, 0x0b, 0xe0, 0xca, 0x65, 0x84, 0x5c, +0x0e, 0x46, 0xda, 0x4b, 0x8e, 0xb2, 0x28, 0xd6, +0xf8, 0x2c, 0xd0, 0x60, 0x2b, 0xe5, 0x72, 0xa3, +0x7e, 0x1b, 0xd2, 0xe3, 0x82, 0x6b, 0xb9, 0xa8, +0xf3, 0x2e, 0xae, 0x9a, 0xcd, 0xe6, 0xd5, 0xdf, +0x9a, 0xd8, 0x83, 0xfe, 0x73, 0xfd, 0x04, 0xce, +0x8c, 0x03, 0x60, 0x06, 0x19, 0xd7, 0x9f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_limit_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_limit_png = new wxImage(); + if (!img_ex_limit_png || !img_ex_limit_png->IsOk()) + { + wxMemoryInputStream img_ex_limit_pngIS(ex_limit_png_data, sizeof(ex_limit_png_data)); + img_ex_limit_png->LoadFile(img_ex_limit_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_limit_png; +} +#define ex_limit_png_img ex_limit_png_img() + +static wxBitmap *ex_limit_png_bmp() +{ + static wxBitmap *bmp_ex_limit_png; + if (!bmp_ex_limit_png || !bmp_ex_limit_png->IsOk()) + bmp_ex_limit_png = new wxBitmap(*ex_limit_png_img); + return bmp_ex_limit_png; +} +#define ex_limit_png_bmp ex_limit_png_bmp() + +static wxIcon *ex_limit_png_ico() +{ + static wxIcon *ico_ex_limit_png; + if (!ico_ex_limit_png || !ico_ex_limit_png->IsOk()) + { + ico_ex_limit_png = new wxIcon(); + ico_ex_limit_png->CopyFromBitmap(*ex_limit_png_bmp); + } + return ico_ex_limit_png; +} +#define ex_limit_png_ico ex_limit_png_ico() + +#endif // EX_LIMIT_PNG_H diff --git a/include/images/ex_lock_rows.png b/include/images/ex_lock_rows.png new file mode 100644 index 0000000..41c1148 Binary files /dev/null and b/include/images/ex_lock_rows.png differ diff --git a/include/images/ex_lock_rows.pngc b/include/images/ex_lock_rows.pngc new file mode 100644 index 0000000..47bc491 --- /dev/null +++ b/include/images/ex_lock_rows.pngc @@ -0,0 +1,234 @@ +#ifndef EX_LOCK_ROWS_PNG_H +#define EX_LOCK_ROWS_PNG_H + +static const unsigned char ex_lock_rows_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x5b, 0x50, 0x4c, 0x54, +0x45, 0x05, 0x00, 0x4c, 0x6e, 0x6b, 0x6b, 0x6f, +0x6d, 0x6d, 0x71, 0x6e, 0x6e, 0x75, 0x72, 0x72, +0xb7, 0x64, 0x51, 0x84, 0x73, 0x5c, 0xb8, 0x65, +0x51, 0xb8, 0x67, 0x51, 0xb8, 0x69, 0x51, 0x7b, +0x78, 0x78, 0xba, 0x6a, 0x51, 0xba, 0x6b, 0x51, +0x36, 0x88, 0xc1, 0xba, 0x6e, 0x51, 0x7e, 0x7c, +0x7c, 0xba, 0x71, 0x51, 0x80, 0x7e, 0x7e, 0xbc, +0x73, 0x51, 0x83, 0x80, 0x80, 0xbc, 0x75, 0x51, +0x85, 0x82, 0x82, 0xbd, 0x78, 0x51, 0x88, 0x86, +0x86, 0xbe, 0x7c, 0x51, 0x8a, 0x88, 0x88, 0xbf, +0x80, 0x51, 0x8c, 0x8a, 0x8a, 0x09, 0xa9, 0xe2, +0xbf, 0x82, 0x51, 0x8d, 0x8c, 0x8c, 0x8e, 0x8c, +0x8c, 0xc0, 0x84, 0x51, 0x8e, 0x8e, 0x8e, 0x72, +0x96, 0xa1, 0x90, 0x8f, 0x8f, 0xc0, 0x88, 0x51, +0xc2, 0x88, 0x51, 0x92, 0x92, 0x92, 0x93, 0x93, +0x93, 0xc1, 0x8f, 0x36, 0x9a, 0x95, 0x7c, 0xc2, +0x8e, 0x51, 0x95, 0x95, 0x95, 0x95, 0x96, 0x96, +0x96, 0x97, 0x97, 0x97, 0x98, 0x98, 0xc4, 0x92, +0x51, 0xc4, 0x98, 0x51, 0x32, 0xb5, 0xe5, 0x9a, +0x9e, 0x9e, 0x9b, 0x9e, 0x9e, 0x75, 0xa6, 0xc7, +0x9c, 0xa1, 0xa1, 0xc2, 0x9e, 0x51, 0xc6, 0x9e, +0x51, 0x9e, 0xa3, 0xa3, 0x9e, 0xa4, 0xa4, 0xc7, +0xa3, 0x51, 0x41, 0xbc, 0xe8, 0xcb, 0xa2, 0x58, +0xc9, 0xa7, 0x51, 0xc9, 0xa8, 0x51, 0x4a, 0xc0, +0xe9, 0xca, 0xab, 0x51, 0xd7, 0xa8, 0x4e, 0xca, +0xad, 0x51, 0xc7, 0xaf, 0x53, 0xcc, 0xaf, 0x51, +0xa7, 0xb1, 0xb1, 0xcc, 0xb2, 0x52, 0xa8, 0xb3, +0xb3, 0x5d, 0xc4, 0xea, 0xfd, 0xad, 0x01, 0xaa, +0xb5, 0xb5, 0xaa, 0xb6, 0xb6, 0x63, 0xc6, 0xea, +0xcd, 0xb6, 0x55, 0x6b, 0xc7, 0xe8, 0x68, 0xc8, +0xec, 0xce, 0xba, 0x58, 0xad, 0xba, 0xba, 0xce, +0xba, 0x59, 0xaf, 0xbc, 0xbc, 0x6e, 0xcb, 0xec, +0xb0, 0xbe, 0xbe, 0x75, 0xcd, 0xec, 0xda, 0xbb, +0x7e, 0xb4, 0xc2, 0xc2, 0xdb, 0xbd, 0x89, 0xe3, +0xbd, 0x73, 0xdc, 0xbe, 0x80, 0xff, 0xbd, 0x30, +0x7b, 0xd1, 0xef, 0xb6, 0xc4, 0xc4, 0xdc, 0xc1, +0x82, 0x84, 0xd1, 0xee, 0xdd, 0xc3, 0x83, 0x84, +0xd3, 0xf0, 0xde, 0xc4, 0x84, 0xde, 0xc6, 0x86, +0x8c, 0xd4, 0xee, 0xdf, 0xc7, 0x87, 0xdf, 0xc8, +0x88, 0x91, 0xd5, 0xee, 0xe0, 0xc9, 0x89, 0xe1, +0xcc, 0x8a, 0x97, 0xd9, 0xf1, 0xe3, 0xcb, 0x9e, +0xe2, 0xce, 0x8c, 0xe3, 0xcc, 0x9e, 0xe4, 0xcd, +0x9e, 0xe2, 0xd0, 0x8d, 0xe4, 0xce, 0x9f, 0xa0, +0xdb, 0xf1, 0xe3, 0xd2, 0x8f, 0xe5, 0xd0, 0xa1, +0xe4, 0xd3, 0x90, 0xe6, 0xd1, 0xa1, 0xe6, 0xd1, +0xa2, 0xe4, 0xd4, 0x91, 0xe6, 0xd2, 0xa2, 0xe4, +0xd5, 0x92, 0xe6, 0xd3, 0xa3, 0xe5, 0xd6, 0x93, +0xe6, 0xd4, 0xa4, 0xe7, 0xd5, 0xa5, 0xae, 0xe0, +0xf3, 0xe6, 0xd9, 0x94, 0xe8, 0xd7, 0xa6, 0xe8, +0xd7, 0xa7, 0xe6, 0xda, 0x96, 0xe9, 0xd9, 0xa8, +0xe7, 0xdc, 0x97, 0xe9, 0xda, 0xa9, 0xea, 0xd9, +0xb6, 0xe9, 0xdb, 0xaa, 0xeb, 0xda, 0xb7, 0xe8, +0xde, 0x99, 0xea, 0xdd, 0xaa, 0xec, 0xdc, 0xb8, +0xe9, 0xe0, 0x9a, 0xeb, 0xde, 0xac, 0xf2, 0xdd, +0xa6, 0xec, 0xdd, 0xba, 0xeb, 0xdf, 0xad, 0xf2, +0xde, 0xa7, 0xec, 0xde, 0xba, 0xf4, 0xde, 0xa9, +0xec, 0xe0, 0xad, 0xea, 0xe3, 0x9c, 0xf4, 0xdf, +0xa9, 0xec, 0xe1, 0xae, 0xed, 0xe0, 0xbb, 0xea, +0xe4, 0x9d, 0xec, 0xe2, 0xaf, 0xed, 0xe1, 0xbc, +0xf4, 0xe1, 0xaa, 0xec, 0xe3, 0xb0, 0xf4, 0xe3, +0xad, 0xed, 0xe5, 0xb1, 0xf4, 0xe4, 0xaf, 0xef, +0xe4, 0xbe, 0xed, 0xe6, 0xb2, 0xee, 0xe6, 0xb3, +0xef, 0xe5, 0xc0, 0xf6, 0xe5, 0xb2, 0xf0, 0xe6, +0xc0, 0xf9, 0xe5, 0xb1, 0xef, 0xe8, 0xb3, 0xf6, +0xe7, 0xb3, 0xf6, 0xe7, 0xb4, 0xef, 0xe9, 0xb5, +0xf9, 0xe7, 0xb3, 0xf0, 0xe9, 0xc2, 0xf8, 0xe8, +0xb6, 0xf0, 0xec, 0xb6, 0xf6, 0xea, 0xba, 0xf8, +0xea, 0xb8, 0xf1, 0xeb, 0xc4, 0xfd, 0xea, 0xb6, +0xf8, 0xec, 0xba, 0xf2, 0xed, 0xc5, 0xf9, 0xed, +0xbe, 0xf9, 0xee, 0xbf, 0xf9, 0xee, 0xc5, 0xf3, +0xf0, 0xc8, 0xff, 0xef, 0xbf, 0xf9, 0xf1, 0xc0, +0xf9, 0xf1, 0xc1, 0xfb, 0xf1, 0xc3, 0xff, 0xf1, +0xbe, 0xff, 0xf1, 0xd2, 0xfd, 0xf4, 0xcd, 0xff, +0xf3, 0xd4, 0xff, 0xf4, 0xd1, 0xff, 0xf6, 0xc7, +0xff, 0xf6, 0xc9, 0xff, 0xf6, 0xda, 0xff, 0xf6, +0xdb, 0xff, 0xf8, 0xcd, 0xaa, 0xbb, 0xd1, 0x2a, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, +0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, +0x9c, 0x18, 0x00, 0x00, 0x03, 0x2e, 0x49, 0x44, +0x41, 0x54, 0x48, 0xc7, 0xed, 0x93, 0xe9, 0x57, +0x12, 0x51, 0x18, 0xc6, 0xb5, 0x7d, 0x1b, 0xdb, +0x4d, 0xcb, 0x6c, 0xb7, 0x9b, 0xd9, 0x62, 0xbb, +0x52, 0xd9, 0x9e, 0xb6, 0xd8, 0x22, 0x89, 0x8a, +0x86, 0x28, 0x6e, 0xb8, 0x81, 0xa0, 0x88, 0x03, +0x04, 0x04, 0xa8, 0x8c, 0x6b, 0x86, 0xa1, 0xd2, +0x64, 0x34, 0xa5, 0x26, 0x91, 0x46, 0x59, 0x5a, +0xd9, 0xbe, 0xfc, 0x59, 0xdd, 0xb9, 0x77, 0x14, +0x3c, 0x8e, 0x9e, 0xce, 0xa9, 0x73, 0xea, 0x83, +0xef, 0x87, 0x67, 0x66, 0xce, 0x99, 0xdf, 0x79, +0xdf, 0xe7, 0xb9, 0xef, 0x0d, 0x0a, 0x9a, 0xa9, +0x7f, 0x50, 0x07, 0x08, 0xb6, 0xa6, 0x54, 0x3e, +0x84, 0x10, 0x0a, 0x04, 0x82, 0x54, 0x22, 0x2b, +0x21, 0x31, 0x31, 0x87, 0xc8, 0xb9, 0x22, 0x14, +0x16, 0x13, 0xc5, 0x59, 0xd9, 0xd9, 0x15, 0x44, +0x45, 0x5e, 0x61, 0xe1, 0x2d, 0x82, 0x17, 0x11, +0x44, 0x44, 0x44, 0x08, 0x88, 0x04, 0xa8, 0x89, +0xc4, 0xa5, 0xd8, 0xd8, 0x58, 0x21, 0x91, 0x0a, +0xf1, 0x6c, 0x22, 0x2f, 0x39, 0x59, 0x58, 0x48, +0xfc, 0x41, 0x97, 0xdd, 0x3b, 0xa3, 0xb6, 0x44, +0x86, 0xe3, 0xf7, 0xcd, 0x68, 0xe6, 0x29, 0x95, +0x23, 0x76, 0x9d, 0x4f, 0xbb, 0x99, 0x76, 0xed, +0xc8, 0x4a, 0xf4, 0x01, 0x46, 0x06, 0x06, 0x06, +0x46, 0xc6, 0xd4, 0xe3, 0xf1, 0x0c, 0x81, 0x21, +0x86, 0x61, 0x7c, 0xc0, 0x47, 0xd3, 0xb4, 0x17, +0x60, 0x22, 0x26, 0xe5, 0x42, 0xcc, 0xba, 0xf0, +0xc8, 0xb8, 0xb8, 0x45, 0x08, 0x19, 0xe8, 0xec, +0x6c, 0xf7, 0x70, 0xea, 0x69, 0x6c, 0x6c, 0xec, +0x03, 0x8c, 0xdd, 0x6a, 0xed, 0x06, 0xb4, 0xd1, +0xa8, 0x73, 0x70, 0xc8, 0xd9, 0x8b, 0x1b, 0xd8, +0xc7, 0xd2, 0x7d, 0xdb, 0x39, 0xa4, 0x1d, 0x21, +0xed, 0x18, 0xb1, 0x33, 0x80, 0xb1, 0x5a, 0xad, +0x34, 0xe8, 0x32, 0xea, 0xc6, 0x90, 0xa8, 0x94, +0x18, 0x8c, 0x2e, 0xdf, 0x3f, 0x9b, 0x45, 0x3c, +0xed, 0xe8, 0x67, 0xa4, 0x7d, 0x76, 0x3b, 0x44, +0xba, 0xad, 0xb7, 0x8d, 0x34, 0x70, 0xea, 0x6a, +0x6a, 0x5a, 0x31, 0xb2, 0xe9, 0x06, 0x67, 0x7c, +0xce, 0xc1, 0x60, 0xe4, 0x05, 0xcd, 0x3f, 0xee, +0xe2, 0x11, 0x72, 0xd1, 0xe5, 0x05, 0x5e, 0x47, +0x6b, 0x53, 0x0f, 0x42, 0xae, 0xef, 0x58, 0xb3, +0xfa, 0xf4, 0x99, 0x13, 0xc7, 0xe2, 0x0f, 0xcd, +0x0a, 0x9e, 0x17, 0x1d, 0x14, 0x74, 0x12, 0xb0, +0x95, 0x81, 0x34, 0x7d, 0xb2, 0xb2, 0xc8, 0xd5, +0xf7, 0xa3, 0x9f, 0xbe, 0x7c, 0xfc, 0xf1, 0xfd, +0xf3, 0xf0, 0x60, 0x7f, 0xff, 0x56, 0xd8, 0x25, +0x93, 0x2d, 0x30, 0xd4, 0xc7, 0x30, 0x43, 0xc0, +0xd7, 0xdd, 0x4d, 0xfb, 0x80, 0xd7, 0xe9, 0x70, +0xf4, 0x80, 0x1e, 0x8a, 0xa2, 0xdc, 0xa8, 0xcb, +0xe5, 0x77, 0xa3, 0xc3, 0x6c, 0x0d, 0x0e, 0xf6, +0xf6, 0x3e, 0x59, 0xcf, 0x22, 0x49, 0x49, 0x49, +0x99, 0x01, 0x2e, 0xba, 0x58, 0x17, 0xd5, 0x4d, +0x80, 0x52, 0x29, 0x14, 0x36, 0x84, 0x9c, 0x7b, +0x83, 0x90, 0x51, 0x16, 0x79, 0x18, 0x36, 0x8e, +0x30, 0x76, 0x3b, 0x0e, 0xd6, 0xe8, 0x04, 0x8e, +0x9a, 0xea, 0x4a, 0x0a, 0x50, 0x0a, 0x45, 0x29, +0x46, 0x4e, 0xbd, 0xf6, 0x23, 0x0f, 0x42, 0xfd, +0x08, 0x0a, 0x96, 0x46, 0xc1, 0xb6, 0x56, 0xaa, +0x54, 0x14, 0xa8, 0x2b, 0x2d, 0x95, 0x5b, 0x10, +0x72, 0xfc, 0x95, 0x1f, 0xb9, 0xbf, 0x62, 0xdc, +0xcb, 0x64, 0x17, 0x6e, 0x9b, 0xc5, 0xe2, 0x42, +0x48, 0xfc, 0x0b, 0x3f, 0x72, 0x37, 0xe4, 0xb7, +0x12, 0x3b, 0xfc, 0x9c, 0x45, 0x46, 0x11, 0x72, +0x67, 0x31, 0xec, 0xe2, 0xa3, 0xbb, 0x9c, 0x5e, +0x4e, 0x7b, 0x5a, 0x9b, 0xe0, 0x59, 0xb8, 0xeb, +0x6c, 0x36, 0x37, 0x70, 0x99, 0xcd, 0xa6, 0x0e, +0xd4, 0x65, 0xef, 0xd3, 0x67, 0x2f, 0x3f, 0x7c, +0xfd, 0xf9, 0xed, 0x6d, 0xef, 0xbd, 0xe6, 0xe6, +0x05, 0x10, 0xc1, 0xf3, 0x4f, 0x74, 0x21, 0x87, +0x2e, 0xcc, 0x45, 0x05, 0xf9, 0x7a, 0x84, 0xec, +0x89, 0xde, 0xb6, 0x71, 0x6d, 0x58, 0xe8, 0xaa, +0x65, 0x21, 0x4b, 0x16, 0xce, 0x9f, 0x0b, 0x11, +0xa7, 0x4e, 0x07, 0x17, 0x03, 0x2b, 0xa5, 0x52, +0x29, 0xea, 0x80, 0x4d, 0x2e, 0x97, 0x9b, 0x81, +0xa9, 0x20, 0x5f, 0xa6, 0x07, 0x7c, 0x57, 0x0c, +0x45, 0xda, 0xc4, 0x29, 0x0e, 0xd6, 0x22, 0x2f, +0x2a, 0x32, 0x01, 0x83, 0x4c, 0x26, 0x23, 0xf9, +0x11, 0x38, 0x3f, 0xf5, 0x98, 0x53, 0xd6, 0x85, +0x0b, 0xba, 0x30, 0x19, 0x3a, 0x40, 0x87, 0x9e, +0x24, 0x5b, 0x78, 0x91, 0xa3, 0x01, 0x89, 0x65, +0x4c, 0x4e, 0x8f, 0xbf, 0x0b, 0x45, 0xd5, 0xb9, +0xb9, 0xd3, 0xc1, 0xda, 0x61, 0xd0, 0xeb, 0xdb, +0x40, 0x8b, 0x56, 0x53, 0xd5, 0xc0, 0x3f, 0x18, +0x9e, 0x1f, 0xef, 0x00, 0x56, 0xe8, 0x22, 0x97, +0x04, 0x1a, 0xa9, 0x44, 0xa2, 0xe6, 0x47, 0xf0, +0x62, 0x04, 0x22, 0x7a, 0x59, 0xae, 0x54, 0x0b, +0xaa, 0x24, 0x12, 0xf1, 0x14, 0x08, 0x8e, 0x34, +0x10, 0x21, 0x73, 0xa5, 0xd2, 0x2a, 0xa0, 0x96, +0x88, 0xc5, 0x4a, 0x7e, 0xc4, 0x6d, 0xb1, 0x98, +0x5d, 0x13, 0xbc, 0xb4, 0x68, 0x34, 0x55, 0xf5, +0xa0, 0x5e, 0xad, 0x54, 0xd6, 0xff, 0xb5, 0xc4, +0x5c, 0x26, 0x03, 0x3c, 0x05, 0xac, 0x6d, 0x24, +0xa9, 0x6d, 0x01, 0x0d, 0x6a, 0xb5, 0x1a, 0x76, +0x51, 0x96, 0x97, 0xd7, 0xf2, 0x0f, 0x86, 0x17, +0x03, 0x2b, 0x29, 0x45, 0x2e, 0xc4, 0xac, 0x8b, +0x72, 0x91, 0x48, 0x54, 0xc6, 0x8f, 0x18, 0xf2, +0xd9, 0xc5, 0xc0, 0xaa, 0x45, 0xc1, 0xfa, 0x91, +0x12, 0x7e, 0x44, 0x0f, 0x4f, 0x41, 0xcb, 0xa9, +0x46, 0xc2, 0x22, 0x4a, 0xb1, 0x58, 0x54, 0x0e, +0xca, 0xa6, 0x46, 0xda, 0x48, 0x2d, 0x9c, 0x1f, +0x6b, 0xa0, 0x8b, 0xda, 0x92, 0x92, 0x92, 0xda, +0x69, 0x12, 0x4b, 0x9f, 0xee, 0x56, 0xce, 0xd4, +0xff, 0x58, 0xbf, 0x00, 0x90, 0xaf, 0xdd, 0x9c, +0x12, 0x96, 0x95, 0x51, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_lock_rows_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_lock_rows_png = new wxImage(); + if (!img_ex_lock_rows_png || !img_ex_lock_rows_png->IsOk()) + { + wxMemoryInputStream img_ex_lock_rows_pngIS(ex_lock_rows_png_data, sizeof(ex_lock_rows_png_data)); + img_ex_lock_rows_png->LoadFile(img_ex_lock_rows_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_lock_rows_png; +} +#define ex_lock_rows_png_img ex_lock_rows_png_img() + +static wxBitmap *ex_lock_rows_png_bmp() +{ + static wxBitmap *bmp_ex_lock_rows_png; + if (!bmp_ex_lock_rows_png || !bmp_ex_lock_rows_png->IsOk()) + bmp_ex_lock_rows_png = new wxBitmap(*ex_lock_rows_png_img); + return bmp_ex_lock_rows_png; +} +#define ex_lock_rows_png_bmp ex_lock_rows_png_bmp() + +static wxIcon *ex_lock_rows_png_ico() +{ + static wxIcon *ico_ex_lock_rows_png; + if (!ico_ex_lock_rows_png || !ico_ex_lock_rows_png->IsOk()) + { + ico_ex_lock_rows_png = new wxIcon(); + ico_ex_lock_rows_png->CopyFromBitmap(*ex_lock_rows_png_bmp); + } + return ico_ex_lock_rows_png; +} +#define ex_lock_rows_png_ico ex_lock_rows_png_ico() + +#endif // EX_LOCK_ROWS_PNG_H diff --git a/include/images/ex_materialize.png b/include/images/ex_materialize.png new file mode 100644 index 0000000..c3bd0bb Binary files /dev/null and b/include/images/ex_materialize.png differ diff --git a/include/images/ex_materialize.pngc b/include/images/ex_materialize.pngc new file mode 100644 index 0000000..6313c91 --- /dev/null +++ b/include/images/ex_materialize.pngc @@ -0,0 +1,197 @@ +#ifndef EX_MATERIALIZE_PNG_H +#define EX_MATERIALIZE_PNG_H + +static const unsigned char ex_materialize_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa3, 0xbb, 0xcc, 0x83, +0xac, 0xc8, 0x75, 0xa6, 0xc7, 0x36, 0x88, 0xc1, +0x9e, 0xcd, 0xde, 0x8c, 0xc7, 0xdd, 0x93, 0xc9, +0xdd, 0xaa, 0xd2, 0xe0, 0xb2, 0xd4, 0xe0, 0xa5, +0xcf, 0xde, 0xad, 0xd2, 0xdf, 0xbe, 0xd8, 0xe2, +0x70, 0xcc, 0xed, 0x43, 0xbd, 0xe9, 0x4d, 0xbf, +0xe8, 0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, +0xd8, 0xf0, 0x7a, 0xce, 0xec, 0x87, 0xd3, 0xee, +0xad, 0xdf, 0xf3, 0x6b, 0xbc, 0xd9, 0x73, 0xbe, +0xda, 0x10, 0xab, 0xe2, 0x64, 0xc5, 0xe8, 0x5c, +0xc3, 0xe9, 0x92, 0xd5, 0xef, 0x9f, 0xad, 0xac, +0x7f, 0x9b, 0xa2, 0x72, 0x96, 0xa1, 0xc8, 0xaf, +0x83, 0xe2, 0xe0, 0xcb, 0xe0, 0xde, 0xc3, 0xc1, +0x8f, 0x36, 0xf4, 0xf0, 0xc8, 0xf0, 0xec, 0xb7, +0xde, 0xdb, 0xb7, 0xdd, 0xda, 0xb6, 0xe0, 0xdd, +0xc2, 0xeb, 0xe6, 0x9f, 0xea, 0xe4, 0x9e, 0xef, +0xe9, 0xb5, 0xea, 0xe3, 0x9d, 0xdd, 0xd9, 0xb5, +0xe9, 0xe1, 0x9b, 0xef, 0xe8, 0xb3, 0xe0, 0xdc, +0xc1, 0xf2, 0xed, 0xc5, 0xcc, 0xbd, 0xa3, 0xc7, +0xaa, 0x75, 0xdf, 0xdb, 0xc1, 0xe1, 0xdd, 0xca, +0xee, 0xe6, 0xb2, 0xf1, 0xea, 0xc4, 0xdc, 0xd7, +0xb4, 0xdc, 0xd5, 0xb3, 0xde, 0xda, 0xc0, 0xe7, +0xdc, 0x97, 0xe6, 0xd9, 0x94, 0xec, 0xe3, 0xb0, +0xdd, 0xd8, 0xb5, 0xdb, 0xd4, 0xb1, 0xe9, 0xe0, +0x9a, 0xe8, 0xdf, 0x99, 0xec, 0xe0, 0xad, 0xde, +0xd8, 0xbe, 0xe4, 0xd5, 0x91, 0xe0, 0xdb, 0xc8, +0x86, 0xa9, 0x64, 0x52, 0x8d, 0x19, 0xf0, 0xe6, +0xc0, 0xab, 0xd4, 0x6c, 0xdd, 0xd6, 0xbd, 0xe0, +0xda, 0xc7, 0xaf, 0xdb, 0x72, 0xb3, 0xe1, 0x77, +0xf0, 0xe8, 0xc2, 0xea, 0xdd, 0xab, 0xe9, 0xdc, +0xaa, 0xee, 0xe2, 0xbd, 0xda, 0xd1, 0xaf, 0xd9, +0xcf, 0xae, 0xd9, 0xce, 0xad, 0xa2, 0xc5, 0x5f, +0xa5, 0xcb, 0x64, 0xb0, 0xdc, 0x73, 0xb7, 0xe7, +0x7c, 0xb8, 0xeb, 0x7f, 0xe3, 0xd1, 0x8f, 0xe2, +0xce, 0x8c, 0xe9, 0xd9, 0xa8, 0xda, 0xd2, 0xb0, +0xdc, 0xd4, 0xbb, 0xba, 0xec, 0x81, 0xe1, 0xcc, +0x8a, 0xe8, 0xd7, 0xa7, 0xd8, 0xcc, 0xac, 0xdc, +0xd3, 0xba, 0xe0, 0xca, 0x89, 0xe7, 0xd6, 0xa6, +0xdf, 0xd8, 0xc5, 0xec, 0xdd, 0xba, 0xdb, 0xd2, +0xba, 0xdb, 0xd1, 0xb8, 0xe6, 0xd4, 0xa4, 0xe6, +0xd3, 0xa3, 0xd7, 0xc9, 0xa9, 0xdf, 0xc8, 0x87, +0xde, 0xc5, 0x85, 0xdd, 0xc1, 0x82, 0xe6, 0xd1, +0xa1, 0xd8, 0xcc, 0xab, 0xd8, 0xcb, 0xab, 0xd6, +0xc7, 0xa8, 0xda, 0xcf, 0xb7, 0xe4, 0xce, 0xa0, +0xdc, 0xbe, 0x80, 0xde, 0xd5, 0xc3, 0xeb, 0xd9, +0xb6, 0xda, 0xce, 0xb7, 0xda, 0xcd, 0xb7, 0xe4, +0xcd, 0x9e, 0xe3, 0xcc, 0x9e, 0xe3, 0xcb, 0x9e, +0xd5, 0xc5, 0xa6, 0xda, 0xba, 0x7d, 0xdb, 0xbd, +0x7f, 0xd0, 0x14, 0x54, 0x5d, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x7c, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd2, 0xd7, 0x57, 0x1a, 0x41, 0x14, +0x07, 0x60, 0x42, 0x50, 0x4c, 0x8c, 0x9a, 0x62, +0x22, 0xa6, 0x0d, 0xac, 0xf4, 0x22, 0x26, 0x0b, +0xca, 0x4a, 0x51, 0x8a, 0xe0, 0x1a, 0x43, 0x91, +0x18, 0x43, 0x0b, 0xbd, 0xb7, 0x28, 0x5d, 0x40, +0xfe, 0xf5, 0xcc, 0xc8, 0x9a, 0xe3, 0x0c, 0x70, +0xf2, 0xc0, 0x39, 0x39, 0x79, 0xf0, 0x3e, 0xdc, +0x97, 0xd9, 0x6f, 0xee, 0xfe, 0xee, 0x2e, 0x8f, +0xf7, 0x50, 0xff, 0xa8, 0x1e, 0xf1, 0x51, 0x71, +0x1d, 0x3b, 0x79, 0x2c, 0x40, 0xc5, 0xf5, 0xfb, +0x07, 0xfc, 0x85, 0xc5, 0x45, 0xe1, 0x12, 0xff, +0xc9, 0xd3, 0xa5, 0xe5, 0x67, 0x7c, 0x8c, 0x08, +0x56, 0x56, 0xd7, 0x9e, 0xbf, 0x10, 0xbc, 0x7c, +0xb5, 0xbe, 0xfe, 0x5a, 0x80, 0x91, 0xc5, 0x37, +0x1b, 0x1b, 0x42, 0x08, 0x85, 0x0b, 0xcb, 0x04, +0x59, 0x15, 0x89, 0x44, 0x9b, 0x82, 0x95, 0xb5, +0xb7, 0x9b, 0xef, 0x04, 0x73, 0x4e, 0x79, 0xff, +0x01, 0x15, 0xd7, 0x31, 0xf2, 0xf1, 0x36, 0x05, +0xd7, 0xef, 0x1f, 0x00, 0xb1, 0x44, 0x22, 0x11, +0x73, 0x1d, 0x23, 0xd4, 0x96, 0x54, 0x2a, 0xdd, +0xe2, 0x3a, 0x46, 0x24, 0x32, 0x99, 0x4c, 0x82, +0xba, 0x5c, 0x41, 0x10, 0xa9, 0x52, 0xa9, 0x94, +0xa2, 0xae, 0x52, 0x4f, 0x25, 0x72, 0xf9, 0x2c, +0xa2, 0x52, 0x69, 0x66, 0x10, 0xad, 0x76, 0x06, +0xd1, 0x68, 0x74, 0xdb, 0x38, 0xe1, 0xb2, 0x28, +0x14, 0xfa, 0x19, 0x59, 0xd4, 0xea, 0xed, 0x1d, +0x8c, 0x7c, 0x02, 0xa8, 0xb8, 0x8e, 0x91, 0xcf, +0x14, 0x2a, 0xae, 0x13, 0x53, 0x14, 0x0a, 0x38, +0x45, 0x4f, 0xd3, 0x86, 0x89, 0x29, 0x6a, 0xf5, +0x16, 0xb5, 0x63, 0x34, 0x1a, 0x77, 0x89, 0x2c, +0x30, 0x85, 0x1e, 0xd0, 0x7b, 0x26, 0x13, 0x43, +0x66, 0xd1, 0xe8, 0x60, 0x0a, 0xe3, 0xfe, 0xbe, +0xd9, 0x82, 0x13, 0x85, 0xd6, 0x6a, 0xa5, 0x01, +0x6d, 0x32, 0xd9, 0x48, 0xa2, 0xd6, 0x1d, 0x1c, +0x1a, 0x21, 0x31, 0x9b, 0xed, 0x04, 0xb1, 0x5a, +0xf7, 0x68, 0xc0, 0x98, 0x6c, 0x36, 0x07, 0x49, +0x0e, 0x0e, 0x21, 0xb1, 0x98, 0xcd, 0x4e, 0x82, +0x88, 0x69, 0x94, 0xc2, 0xc0, 0x38, 0x1c, 0xae, +0x3b, 0x72, 0xe4, 0x3e, 0x42, 0x64, 0x9c, 0x62, +0xd7, 0x6e, 0xb7, 0x7b, 0xfe, 0xba, 0x31, 0xf7, +0x31, 0x32, 0xb3, 0x37, 0x66, 0x60, 0x18, 0xc6, +0x05, 0x5c, 0x2c, 0xcb, 0x9e, 0x00, 0x78, 0xff, +0x6d, 0x7d, 0x39, 0x85, 0x86, 0xda, 0xb5, 0x58, +0x2c, 0x5f, 0x29, 0x8f, 0xd7, 0xeb, 0xf3, 0xe3, +0x2f, 0xc6, 0xd8, 0x50, 0x0a, 0x36, 0x70, 0x16, +0x64, 0x01, 0xcf, 0xfd, 0xed, 0xfc, 0xfc, 0xf8, +0xf8, 0xfb, 0xe9, 0xc5, 0x0f, 0x37, 0x8f, 0x4b, +0xe1, 0x0d, 0x85, 0xc3, 0x11, 0x92, 0x44, 0xa3, +0x2c, 0x60, 0xcf, 0x82, 0xc1, 0xd8, 0x9f, 0x29, +0x17, 0x3f, 0xd1, 0x14, 0xbb, 0xd3, 0xe9, 0xf4, +0x52, 0xbe, 0x70, 0x3c, 0x9e, 0xc0, 0x89, 0x23, +0x1a, 0x08, 0x40, 0x12, 0x4c, 0x26, 0x53, 0x77, +0xf1, 0xdd, 0x48, 0x20, 0x12, 0x0a, 0xf9, 0xa8, +0x48, 0x3c, 0x9d, 0xce, 0xe0, 0x64, 0x9c, 0x22, +0x1b, 0x4b, 0xa5, 0xb2, 0xc4, 0xc6, 0x3c, 0x5e, +0x1f, 0x4c, 0xe1, 0x4f, 0x64, 0x32, 0xb9, 0xb9, +0xff, 0xb1, 0x13, 0x96, 0x8d, 0x65, 0x41, 0x36, +0x9f, 0x2f, 0x64, 0x89, 0x4f, 0xe9, 0x89, 0x44, +0x12, 0x7e, 0x2a, 0x57, 0x2c, 0x95, 0xf0, 0x29, +0x5c, 0x8a, 0x7c, 0xb9, 0x5c, 0x2e, 0x10, 0x04, +0xa6, 0xa8, 0x64, 0xa8, 0x62, 0xb5, 0x56, 0xab, +0xe3, 0x24, 0x96, 0xfc, 0x75, 0x99, 0x07, 0x85, +0x72, 0xf9, 0xaa, 0x41, 0x90, 0x44, 0xba, 0x52, +0x2d, 0x52, 0xf5, 0x5a, 0xad, 0xd6, 0xc4, 0x49, +0xea, 0xf2, 0x12, 0xde, 0x5f, 0xb8, 0xba, 0x9a, +0x20, 0x99, 0x4a, 0xb5, 0x5a, 0x82, 0xa4, 0xd5, +0x22, 0x08, 0x4a, 0xd1, 0x06, 0xed, 0x46, 0xa3, +0xd1, 0x26, 0x08, 0x4c, 0x51, 0xcf, 0x51, 0x9d, +0x66, 0xb3, 0xd9, 0x99, 0x7b, 0x63, 0xd9, 0x42, +0x01, 0xde, 0xdf, 0xee, 0x76, 0x7b, 0x13, 0x53, +0xea, 0x75, 0x78, 0x7f, 0xe7, 0xba, 0x3f, 0xc0, +0xa7, 0x70, 0x29, 0xba, 0xc3, 0xe1, 0xb0, 0x47, +0x90, 0x7a, 0x0b, 0xa5, 0xe8, 0xdf, 0xdc, 0xdc, +0x0c, 0x70, 0xd2, 0x80, 0xa4, 0x0b, 0x7a, 0x53, +0x48, 0xb3, 0x35, 0x1a, 0x5d, 0x53, 0x83, 0xa9, +0x04, 0x3e, 0x3c, 0x95, 0x8c, 0x46, 0xf0, 0xe1, +0x29, 0x64, 0x9c, 0xa2, 0xdd, 0xeb, 0x4d, 0x64, +0xe9, 0xf4, 0x51, 0x8a, 0xce, 0x60, 0x30, 0x98, +0x7b, 0x63, 0x0f, 0xf5, 0xbf, 0xd5, 0x6f, 0x90, +0x0c, 0xd1, 0xf0, 0x63, 0x89, 0x1f, 0xe1, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_materialize_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_materialize_png = new wxImage(); + if (!img_ex_materialize_png || !img_ex_materialize_png->IsOk()) + { + wxMemoryInputStream img_ex_materialize_pngIS(ex_materialize_png_data, sizeof(ex_materialize_png_data)); + img_ex_materialize_png->LoadFile(img_ex_materialize_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_materialize_png; +} +#define ex_materialize_png_img ex_materialize_png_img() + +static wxBitmap *ex_materialize_png_bmp() +{ + static wxBitmap *bmp_ex_materialize_png; + if (!bmp_ex_materialize_png || !bmp_ex_materialize_png->IsOk()) + bmp_ex_materialize_png = new wxBitmap(*ex_materialize_png_img); + return bmp_ex_materialize_png; +} +#define ex_materialize_png_bmp ex_materialize_png_bmp() + +static wxIcon *ex_materialize_png_ico() +{ + static wxIcon *ico_ex_materialize_png; + if (!ico_ex_materialize_png || !ico_ex_materialize_png->IsOk()) + { + ico_ex_materialize_png = new wxIcon(); + ico_ex_materialize_png->CopyFromBitmap(*ex_materialize_png_bmp); + } + return ico_ex_materialize_png; +} +#define ex_materialize_png_ico ex_materialize_png_ico() + +#endif // EX_MATERIALIZE_PNG_H diff --git a/include/images/ex_merge.png b/include/images/ex_merge.png new file mode 100644 index 0000000..3fd8299 Binary files /dev/null and b/include/images/ex_merge.png differ diff --git a/include/images/ex_merge.pngc b/include/images/ex_merge.pngc new file mode 100644 index 0000000..dbfa8ac --- /dev/null +++ b/include/images/ex_merge.pngc @@ -0,0 +1,185 @@ +#ifndef EX_MERGE_PNG_H +#define EX_MERGE_PNG_H + +static const unsigned char ex_merge_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x92, 0x95, 0xd1, 0x66, +0x6b, 0xd1, 0xcd, 0xce, 0xf2, 0xbc, 0xbd, 0xec, +0xbf, 0xc0, 0xed, 0xd1, 0xd1, 0xf2, 0xd3, 0xd4, +0xf3, 0xc7, 0xc8, 0xef, 0xc7, 0xc8, 0xf0, 0xca, +0xca, 0xf1, 0xdb, 0xdb, 0xf5, 0xd6, 0xd7, 0xf5, +0xe1, 0xe1, 0xf7, 0xa6, 0xa8, 0xe6, 0xa9, 0xab, +0xe7, 0xc1, 0xc2, 0xee, 0xc5, 0xc5, 0xef, 0xb5, +0xb6, 0xeb, 0xb9, 0xba, 0xec, 0xc3, 0xc4, 0xef, +0xc5, 0xc6, 0xf0, 0x86, 0xa9, 0x64, 0x52, 0x8d, +0x19, 0xa1, 0xc4, 0x5e, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbc, 0xe8, +0x4a, 0xc0, 0xe9, 0x7b, 0xd1, 0xef, 0x84, 0xd3, +0xf0, 0x63, 0xc6, 0xea, 0x68, 0xc8, 0xec, 0x6e, +0xcb, 0xec, 0x97, 0xd9, 0xf1, 0xa0, 0xdb, 0xf1, +0x84, 0xd1, 0xee, 0x8c, 0xd4, 0xee, 0x91, 0xd5, +0xee, 0xae, 0xe0, 0xf3, 0x09, 0xa9, 0xe2, 0x5d, +0xc4, 0xea, 0x32, 0xb5, 0xe5, 0x75, 0xcd, 0xec, +0x6b, 0xc7, 0xe8, 0xa3, 0xc7, 0x61, 0x72, 0x96, +0xa1, 0xc1, 0x8f, 0x36, 0xf3, 0xf0, 0xc8, 0xf0, +0xec, 0xb6, 0xef, 0xe9, 0xb4, 0xf3, 0xed, 0xc6, +0xee, 0xe6, 0xb2, 0xed, 0xe5, 0xb1, 0xf1, 0xeb, +0xc4, 0xea, 0xe4, 0x9d, 0xe9, 0xe0, 0x9a, 0xe7, +0xdc, 0x97, 0xe7, 0xdb, 0x96, 0xec, 0xe3, 0xb0, +0xa6, 0xcc, 0x65, 0xea, 0xe3, 0x9c, 0xe8, 0xde, +0x99, 0xe6, 0xd9, 0x95, 0xec, 0xe2, 0xaf, 0xe8, +0xdd, 0x98, 0xe6, 0xd9, 0x94, 0xe5, 0xd7, 0x93, +0xec, 0xe0, 0xad, 0xa6, 0xd0, 0x67, 0xec, 0xe0, +0xae, 0xf0, 0xe8, 0xc2, 0xc7, 0xaa, 0x75, 0xab, +0xd5, 0x6c, 0xeb, 0xdf, 0xad, 0xea, 0xdc, 0xaa, +0xef, 0xe5, 0xc0, 0xe3, 0xd2, 0x8f, 0xe3, 0xd0, +0x8e, 0xe9, 0xda, 0xa9, 0x61, 0x95, 0x2f, 0x5e, +0x98, 0x25, 0xc1, 0xc8, 0xba, 0xe4, 0xd5, 0x92, +0x70, 0x9d, 0x45, 0x9a, 0xca, 0x5d, 0x78, 0xae, +0x3e, 0x9e, 0xb5, 0x87, 0xba, 0xed, 0x81, 0xe4, +0xd3, 0x90, 0xe1, 0xcd, 0x8c, 0x8b, 0xab, 0x6c, +0x88, 0xbc, 0x4d, 0x9d, 0xd0, 0x63, 0x7a, 0xb0, +0x40, 0xbc, 0xf0, 0x84, 0xef, 0xe4, 0xbf, 0xe9, +0xd8, 0xa7, 0xee, 0xe2, 0xbd, 0xbf, 0xc7, 0xb7, +0xab, 0xde, 0x71, 0xb8, 0xeb, 0x7f, 0xf0, 0xe6, +0xc0, 0xe8, 0xd7, 0xa7, 0xe7, 0xd6, 0xa5, 0xed, +0xdf, 0xbb, 0xe1, 0xcc, 0x8a, 0xe0, 0xc8, 0x88, +0xdf, 0xc7, 0x87, 0xe6, 0xd4, 0xa4, 0xde, 0xc5, +0x85, 0xe6, 0xd3, 0xa3, 0xe0, 0xc9, 0x89, 0xde, +0xc4, 0x85, 0xdd, 0xc3, 0x83, 0xe6, 0xd1, 0xa2, +0xec, 0xdd, 0xba, 0xe6, 0xd2, 0xa2, 0xec, 0xdc, +0xb8, 0xe6, 0xd1, 0xa1, 0xe5, 0xcf, 0xa1, 0xeb, +0xda, 0xb7, 0xdc, 0xbf, 0x80, 0xdb, 0xbd, 0x7f, +0xe4, 0xce, 0xa0, 0xdd, 0xc1, 0x82, 0xe3, 0xcc, +0x9e, 0x3a, 0xd1, 0x83, 0xbf, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x1e, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd3, 0xeb, 0x57, 0xd2, 0x70, 0x18, +0x07, 0x70, 0x9a, 0x17, 0x32, 0x2d, 0xcd, 0xca, +0xd5, 0x82, 0x32, 0xcb, 0x0c, 0xed, 0xf2, 0xc0, +0x18, 0xf7, 0x18, 0x20, 0x08, 0xb5, 0x09, 0xd3, +0xb0, 0x42, 0xba, 0x4c, 0xd6, 0x65, 0x13, 0x06, +0x2c, 0x30, 0x9b, 0xa0, 0xfc, 0xeb, 0xfd, 0xc6, +0x81, 0x73, 0x58, 0x67, 0xc7, 0xdf, 0xd4, 0x37, +0xbd, 0xf0, 0x79, 0xf1, 0xbc, 0xfb, 0x9c, 0xe7, +0xf7, 0xfd, 0xee, 0xcc, 0xe1, 0xb8, 0x1c, 0xc7, +0x15, 0xc2, 0x18, 0xd3, 0xc6, 0x11, 0x62, 0x6c, +0x7c, 0x62, 0x62, 0x92, 0x70, 0x5e, 0x9d, 0xba, +0x36, 0x4d, 0x4c, 0x3b, 0x9d, 0x33, 0xd7, 0x09, +0x2c, 0x19, 0xbf, 0x31, 0x3b, 0x3b, 0x47, 0xdc, +0x9c, 0x9f, 0xbf, 0x35, 0x46, 0x4c, 0xde, 0xbe, +0x33, 0x35, 0xf3, 0xbf, 0x90, 0xb3, 0x67, 0x39, +0x47, 0x63, 0x17, 0x98, 0x05, 0x72, 0xe1, 0xac, +0x84, 0xbc, 0x4b, 0x5e, 0x88, 0xdc, 0xa3, 0x8c, +0x31, 0x6d, 0x1c, 0xa1, 0xee, 0xbb, 0xdc, 0xee, +0x07, 0xd4, 0xc3, 0xc5, 0x47, 0x4b, 0x8f, 0xa9, +0x27, 0xcb, 0x4f, 0x57, 0x9e, 0x51, 0x58, 0xe2, +0xf2, 0x78, 0x3c, 0x6e, 0x6a, 0x75, 0x6d, 0xcd, +0xf5, 0x9c, 0x5a, 0x5e, 0x5d, 0x7c, 0xb1, 0x82, +0x27, 0xf6, 0xae, 0xbc, 0x1c, 0x21, 0xaf, 0xfa, +0xef, 0x37, 0x6d, 0x1c, 0x01, 0xaf, 0xcf, 0xe7, +0xf3, 0x82, 0x97, 0xa6, 0x69, 0x3f, 0xf8, 0x19, +0x26, 0x10, 0x04, 0x2c, 0xf1, 0x85, 0x42, 0x21, +0x1a, 0xe8, 0x70, 0x38, 0xcc, 0x00, 0x13, 0x89, +0x46, 0x63, 0x96, 0xe4, 0xf5, 0x3f, 0x24, 0x6e, +0x10, 0x96, 0x65, 0x20, 0x10, 0x4d, 0x24, 0x92, +0x36, 0x48, 0x3c, 0x8e, 0x08, 0xc3, 0xb2, 0xa9, +0x00, 0xc4, 0x12, 0xeb, 0xe9, 0x8c, 0x25, 0xd9, +0x30, 0x65, 0x19, 0xa4, 0x08, 0xa0, 0x14, 0xc1, +0x64, 0x36, 0x93, 0xc3, 0x92, 0x37, 0x60, 0x8c, +0x69, 0x5b, 0x91, 0xb7, 0xa3, 0x57, 0xfc, 0x34, +0xc3, 0xf8, 0x21, 0x18, 0x8b, 0x25, 0x73, 0x90, +0xe3, 0x38, 0x7e, 0x13, 0xb0, 0x84, 0x61, 0x53, +0x11, 0x94, 0x62, 0x3d, 0x8d, 0x52, 0x70, 0xf9, +0x7c, 0x41, 0xb0, 0x22, 0x5b, 0x1b, 0xdb, 0xef, +0x1c, 0xc3, 0x7f, 0x00, 0x98, 0x54, 0x04, 0x15, +0x9b, 0x4c, 0xa7, 0x8b, 0x1c, 0xf0, 0x85, 0x82, +0x35, 0xd9, 0x79, 0xff, 0xe1, 0x23, 0x32, 0x64, +0xc9, 0x30, 0xa8, 0xd8, 0x28, 0x2a, 0x36, 0x5b, +0x2c, 0xee, 0xf2, 0x88, 0x94, 0xcb, 0x96, 0xe4, +0xd3, 0xe7, 0x2f, 0x5f, 0xb7, 0x49, 0x92, 0x2c, +0x89, 0xc8, 0x8c, 0xa4, 0xd8, 0x83, 0x3d, 0x41, +0xa8, 0x48, 0x56, 0xe4, 0x1b, 0x32, 0xdf, 0x7f, +0x94, 0x4a, 0xa2, 0x28, 0x92, 0x36, 0x1b, 0x43, +0x66, 0x67, 0x0b, 0x5d, 0x11, 0xfb, 0x57, 0x72, +0xd9, 0x0c, 0xf7, 0x13, 0x36, 0x79, 0x41, 0x90, +0x40, 0x92, 0x65, 0x65, 0xdf, 0xea, 0xca, 0xb0, +0x38, 0xb1, 0x9f, 0x25, 0xd3, 0x4f, 0x21, 0x94, +0xcb, 0xd5, 0x0a, 0xc8, 0x35, 0x55, 0xad, 0x9f, +0x42, 0x06, 0x8d, 0x71, 0xbb, 0xf9, 0x82, 0x41, +0xaa, 0x55, 0x19, 0x14, 0xb5, 0xd1, 0x68, 0x9e, +0x42, 0x06, 0xdf, 0x85, 0xcf, 0x1b, 0xc5, 0x0a, +0x55, 0x4d, 0x53, 0xa0, 0xde, 0xf8, 0xd5, 0x6a, +0xe3, 0xc9, 0x30, 0x85, 0x82, 0x52, 0x1c, 0x34, +0x7f, 0xb7, 0x0f, 0xb1, 0xc4, 0x66, 0x63, 0xa6, +0x2b, 0x92, 0x50, 0x91, 0x25, 0xd8, 0xaf, 0xd7, +0x9b, 0x07, 0x70, 0xf8, 0x47, 0xd7, 0x8f, 0xf0, +0x0f, 0xab, 0x68, 0x5a, 0x6d, 0x98, 0x42, 0xef, +0x74, 0xba, 0xc7, 0x78, 0x22, 0x6b, 0x35, 0x54, +0x6c, 0xb3, 0xd5, 0x3a, 0xd1, 0x11, 0xe9, 0x76, +0x7b, 0x78, 0xa2, 0xa8, 0x2a, 0x2a, 0xb6, 0xdd, +0x3a, 0xe9, 0xe8, 0x70, 0xdc, 0xb5, 0x45, 0x06, +0x29, 0x74, 0x23, 0xc5, 0x51, 0xaf, 0xd7, 0xc3, +0x67, 0x39, 0x47, 0x63, 0x97, 0x63, 0x39, 0x7f, +0x01, 0x65, 0x61, 0xa4, 0xf3, 0x27, 0x1c, 0x01, +0x1c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_merge_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_merge_png = new wxImage(); + if (!img_ex_merge_png || !img_ex_merge_png->IsOk()) + { + wxMemoryInputStream img_ex_merge_pngIS(ex_merge_png_data, sizeof(ex_merge_png_data)); + img_ex_merge_png->LoadFile(img_ex_merge_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_png; +} +#define ex_merge_png_img ex_merge_png_img() + +static wxBitmap *ex_merge_png_bmp() +{ + static wxBitmap *bmp_ex_merge_png; + if (!bmp_ex_merge_png || !bmp_ex_merge_png->IsOk()) + bmp_ex_merge_png = new wxBitmap(*ex_merge_png_img); + return bmp_ex_merge_png; +} +#define ex_merge_png_bmp ex_merge_png_bmp() + +static wxIcon *ex_merge_png_ico() +{ + static wxIcon *ico_ex_merge_png; + if (!ico_ex_merge_png || !ico_ex_merge_png->IsOk()) + { + ico_ex_merge_png = new wxIcon(); + ico_ex_merge_png->CopyFromBitmap(*ex_merge_png_bmp); + } + return ico_ex_merge_png; +} +#define ex_merge_png_ico ex_merge_png_ico() + +#endif // EX_MERGE_PNG_H diff --git a/include/images/ex_merge_anti_join.png b/include/images/ex_merge_anti_join.png new file mode 100644 index 0000000..7a9aa51 Binary files /dev/null and b/include/images/ex_merge_anti_join.png differ diff --git a/include/images/ex_merge_anti_join.pngc b/include/images/ex_merge_anti_join.pngc new file mode 100644 index 0000000..6bd0c99 --- /dev/null +++ b/include/images/ex_merge_anti_join.pngc @@ -0,0 +1,244 @@ +#ifndef EX_MERGE_ANTI_JOIN_PNG_H +#define EX_MERGE_ANTI_JOIN_PNG_H + +static const unsigned char ex_merge_anti_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0xa8, 0xe4, 0x66, +0x6b, 0xd1, 0xcc, 0xcd, 0xf1, 0xbc, 0xbe, 0xec, +0xbe, 0xbf, 0xed, 0xbf, 0xc1, 0xed, 0xd0, 0xd1, +0xf2, 0xd3, 0xd4, 0xf3, 0xc7, 0xc8, 0xef, 0xc8, +0xc9, 0xf0, 0xcb, 0xcb, 0xf1, 0xd9, 0xda, 0xf5, +0xdc, 0xdc, 0xf5, 0xd2, 0xd3, 0xf3, 0xd4, 0xd4, +0xf4, 0xd5, 0xd6, 0xf4, 0xe1, 0xe1, 0xf7, 0xbc, +0xbd, 0xec, 0xa6, 0xa8, 0xe6, 0xa8, 0xaa, 0xe7, +0xaa, 0xac, 0xe7, 0xc1, 0xc2, 0xee, 0xc5, 0xc5, +0xef, 0xb4, 0xb5, 0xea, 0xb6, 0xb7, 0xeb, 0xb9, +0xba, 0xec, 0xcd, 0xce, 0xf2, 0xd1, 0xd1, 0xf2, +0xc3, 0xc4, 0xef, 0xc5, 0xc6, 0xf0, 0xc7, 0xc8, +0xf0, 0xd7, 0xd7, 0xf5, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0xa1, 0xc4, 0x5e, 0x89, 0xb9, 0xdb, +0x36, 0x88, 0xc1, 0x58, 0x9c, 0xcb, 0x6f, 0xcd, +0xee, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, 0x53, +0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, +0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, +0xee, 0xad, 0xdf, 0xf3, 0x4d, 0xc0, 0xe9, 0x61, +0xc6, 0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, 0xf2, +0x40, 0xbc, 0xe9, 0x07, 0xa8, 0xe2, 0x10, 0xab, +0xe2, 0x1a, 0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, +0xcb, 0xec, 0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, +0x64, 0xc5, 0xe8, 0x92, 0xd5, 0xef, 0x12, 0xab, +0xe2, 0x2c, 0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, +0xd3, 0xee, 0xa2, 0xc6, 0x5f, 0x7a, 0x9e, 0xa9, +0x62, 0x8a, 0xa3, 0x74, 0x8b, 0xd5, 0xa3, 0xc7, +0x61, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, +0xec, 0xb7, 0xf4, 0xf0, 0xc8, 0xf3, 0xf0, 0xc8, +0xef, 0xea, 0xb6, 0xef, 0xe9, 0xb5, 0xef, 0xe9, +0xb4, 0xf3, 0xee, 0xc6, 0xc0, 0xc1, 0xee, 0xc6, +0xc7, 0xef, 0xde, 0xde, 0xf6, 0xa4, 0xc9, 0x62, +0xeb, 0xe6, 0x9f, 0xeb, 0xe5, 0x9e, 0xef, 0xeb, +0xb6, 0xef, 0xea, 0xb5, 0xe9, 0xe2, 0x9b, 0xe9, +0xe1, 0x9b, 0xe9, 0xe0, 0x9a, 0xee, 0xe7, 0xb3, +0xab, 0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, +0xed, 0xd4, 0xd4, 0xf3, 0xa5, 0xcb, 0x64, 0xea, +0xe4, 0x9d, 0xe8, 0xdf, 0x99, 0xe8, 0xde, 0x99, +0xee, 0xe6, 0xb2, 0xa6, 0xcd, 0x66, 0xf0, 0xec, +0xb6, 0xea, 0xe3, 0x9d, 0xea, 0xe2, 0x9c, 0xef, +0xe8, 0xb3, 0xe8, 0xdd, 0x98, 0xe7, 0xdc, 0x97, +0xed, 0xe4, 0xb0, 0xa8, 0xcf, 0x68, 0xf3, 0xed, +0xc6, 0xf2, 0xec, 0xc5, 0xed, 0xe6, 0xb2, 0xed, +0xe5, 0xb1, 0xed, 0xe3, 0xb0, 0xf1, 0xea, 0xc3, +0xa9, 0xd2, 0x6a, 0xdb, 0xbd, 0x89, 0xb5, 0x99, +0x7e, 0xab, 0xd5, 0x6c, 0xf3, 0xee, 0xc7, 0xf1, +0xeb, 0xc4, 0xec, 0xe3, 0xaf, 0xec, 0xe2, 0xae, +0xec, 0xe0, 0xad, 0xf0, 0xe7, 0xc1, 0xbf, 0x86, +0x31, 0xbf, 0x8c, 0x83, 0xb5, 0x62, 0x3f, 0xb4, +0x4b, 0x13, 0xb8, 0x65, 0x40, 0xc9, 0x95, 0x86, +0x70, 0x66, 0xb8, 0xad, 0xd7, 0x6f, 0xe8, 0xde, +0x98, 0xec, 0xe2, 0xaf, 0xe5, 0xd7, 0x93, 0xe5, +0xd5, 0x92, 0xe4, 0xd4, 0x91, 0xe4, 0xcb, 0x98, +0xb7, 0x60, 0x1b, 0xc9, 0x4d, 0x1a, 0xd7, 0x51, +0x22, 0xe1, 0x54, 0x27, 0x97, 0x54, 0x52, 0xf5, +0xe8, 0xe1, 0x67, 0x9b, 0x35, 0xa3, 0xd1, 0x66, +0x5e, 0x98, 0x25, 0xea, 0xf1, 0xe3, 0xe7, 0xdb, +0x96, 0xe6, 0xda, 0x95, 0xe4, 0xd3, 0x90, 0xe3, +0xd2, 0x8f, 0xcf, 0x95, 0x5e, 0xe2, 0x54, 0x28, +0xff, 0xff, 0xff, 0xda, 0xa6, 0x8a, 0x7b, 0xa8, +0x50, 0x9a, 0xca, 0x5d, 0x78, 0xae, 0x3e, 0xba, +0xd1, 0xa3, 0xb9, 0xec, 0x80, 0xe6, 0xda, 0x96, +0xe6, 0xd9, 0x95, 0xe5, 0xd8, 0x94, 0xeb, 0xdf, +0xad, 0xe3, 0xd2, 0x90, 0xe3, 0xd1, 0x8e, 0xe2, +0xd0, 0x8d, 0xbe, 0x68, 0x30, 0xc3, 0x70, 0x43, +0xa0, 0xc0, 0x81, 0x87, 0xba, 0x4c, 0x9c, 0xce, +0x61, 0x7a, 0xb0, 0x40, 0xba, 0xee, 0x82, 0xbb, +0xef, 0x83, 0xec, 0xe1, 0xae, 0xef, 0xe6, 0xc0, +0xea, 0xdc, 0xaa, 0xe9, 0xdb, 0xaa, 0xe9, 0xda, +0xa9, 0xb4, 0x4c, 0x14, 0xe7, 0xef, 0xdf, 0x88, +0xbd, 0x4e, 0x9e, 0xd1, 0x64, 0xab, 0xde, 0x71, +0xb8, 0xeb, 0x7f, 0xba, 0xec, 0x81, 0xbc, 0xf0, +0x84, 0xb5, 0x57, 0x16, 0xea, 0xdd, 0xac, 0xea, +0xdd, 0xab, 0xef, 0xe4, 0xbf, 0xee, 0xe3, 0xbd, +0xe9, 0xd9, 0xa7, 0xe8, 0xd7, 0xa7, 0xe8, 0xd7, +0xa6, 0xd1, 0x96, 0x67, 0xeb, 0xde, 0xac, 0xe2, +0xcf, 0x8d, 0xe9, 0xd8, 0xa7, 0xe0, 0xcb, 0x89, +0xe0, 0xc8, 0x88, 0xdf, 0xc7, 0x87, 0xe0, 0xc2, +0x91, 0xea, 0xdd, 0xaa, 0xe2, 0xce, 0x8c, 0xe1, +0xcd, 0x8c, 0xdf, 0xc8, 0x87, 0xdf, 0xc6, 0x86, +0xde, 0xc5, 0x85, 0xe6, 0xd3, 0xa3, 0xb7, 0x84, +0x80, 0xb0, 0x5e, 0x3e, 0xb2, 0x4a, 0x13, 0xc4, +0x90, 0x84, 0xe1, 0xcc, 0x8b, 0xe7, 0xd5, 0xa5, +0xde, 0xc5, 0x86, 0xde, 0xc4, 0x85, 0xdd, 0xc3, +0x84, 0xe6, 0xd1, 0xa2, 0xe8, 0xd6, 0xa6, 0xed, +0xdf, 0xbb, 0xec, 0xde, 0xba, 0xe6, 0xd1, 0xa1, +0xeb, 0xdb, 0xb8, 0xed, 0xe0, 0xbc, 0xe6, 0xd4, +0xa4, 0xe6, 0xd3, 0xa4, 0xec, 0xdd, 0xba, 0xec, +0xdc, 0xb8, 0xe5, 0xd0, 0xa1, 0xe5, 0xcf, 0xa1, +0xe5, 0xce, 0xa0, 0xeb, 0xda, 0xb7, 0xe7, 0xd4, +0xa4, 0xde, 0xc4, 0x84, 0xdc, 0xbe, 0x80, 0xdb, +0xbd, 0x7f, 0xe4, 0xcd, 0x9f, 0xdd, 0xc2, 0x83, +0xdd, 0xc1, 0x82, 0xe4, 0xce, 0xa0, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7e, 0xe3, 0xcc, 0x9e, 0xdc, +0xc0, 0x81, 0xdc, 0xbf, 0x81, 0xda, 0xba, 0x7d, +0xe3, 0xcb, 0x9e, 0xe4, 0xce, 0x9f, 0xea, 0xd9, +0xb6, 0xa8, 0x9c, 0x9e, 0x5c, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x9d, 0x06, 0xbb, 0xf2, 0xb1, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x69, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, +0x18, 0x05, 0x8c, 0x4c, 0x20, 0x80, 0x42, 0x12, +0xd2, 0xc2, 0xc4, 0xcc, 0xc2, 0xca, 0xc6, 0xce, +0xc4, 0xc1, 0xc9, 0xc5, 0xcd, 0xc3, 0xc4, 0xcb, +0xc7, 0x2f, 0x20, 0xc8, 0x44, 0x50, 0x8b, 0x90, +0xb0, 0x88, 0xa8, 0x18, 0x93, 0xb8, 0x84, 0xa4, +0x94, 0x34, 0x93, 0x8c, 0xac, 0x9c, 0xbc, 0xc2, +0x60, 0xd1, 0x42, 0xba, 0x5f, 0xc8, 0x08, 0x31, +0x0a, 0x80, 0xa2, 0x92, 0x22, 0xa9, 0x5a, 0x94, +0x94, 0x95, 0x28, 0xd2, 0xa2, 0xa2, 0x0a, 0x02, +0x10, 0x52, 0x0d, 0xc2, 0x26, 0xa4, 0x45, 0x55, +0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x55, 0x47, 0x57, +0x4f, 0xdf, 0x40, 0x55, 0xdd, 0xd0, 0xc8, 0xd8, +0x44, 0x95, 0xa0, 0x16, 0x53, 0x33, 0x73, 0x0b, +0x4b, 0x55, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x55, +0x53, 0x7b, 0x07, 0x47, 0x27, 0xc2, 0x5a, 0x88, +0xb3, 0xc5, 0x19, 0x49, 0x8b, 0x0b, 0xd8, 0xfd, +0x10, 0xd2, 0x15, 0x1c, 0x59, 0x6e, 0xd8, 0xb4, +0xb8, 0x23, 0x69, 0xf1, 0xf0, 0xf4, 0xf2, 0xf2, +0xf2, 0xf6, 0xf0, 0xf1, 0xf5, 0xf3, 0x0f, 0xf0, +0x60, 0x0e, 0x0c, 0x92, 0x0e, 0xc6, 0x96, 0x24, +0x94, 0x42, 0x90, 0xb5, 0x78, 0x85, 0x86, 0x86, +0x85, 0x7b, 0x44, 0x44, 0x46, 0x45, 0xc7, 0x78, +0x08, 0xc5, 0xc6, 0xc5, 0x27, 0x60, 0xd5, 0x92, +0x88, 0xa2, 0x25, 0x2c, 0x2c, 0x29, 0xc2, 0xc3, +0x3f, 0x3a, 0x39, 0x25, 0x15, 0x8f, 0x96, 0x34, +0x64, 0x2d, 0xe9, 0x49, 0x19, 0x99, 0xfe, 0x1e, +0x59, 0xc9, 0xd9, 0x39, 0xb9, 0x78, 0xb4, 0xe4, +0x21, 0x6b, 0xf1, 0x89, 0xf0, 0xf3, 0xcf, 0xf7, +0x28, 0x28, 0x2c, 0x2a, 0x2e, 0xc1, 0xe3, 0x97, +0x52, 0x24, 0x2d, 0x65, 0x1e, 0x20, 0x00, 0x21, +0xcb, 0x71, 0x26, 0x6f, 0xa5, 0x0a, 0x64, 0x5b, +0x2a, 0xb3, 0x62, 0x52, 0xab, 0x3c, 0x4a, 0xaa, +0x6b, 0x6a, 0xeb, 0xea, 0x1b, 0x1a, 0x9b, 0x9a, +0x5b, 0x5a, 0xb1, 0x69, 0x69, 0x43, 0xd6, 0x12, +0xd3, 0x9e, 0x9d, 0x53, 0xec, 0xd1, 0xd1, 0xd9, +0xd5, 0xdd, 0xd3, 0xdb, 0xd7, 0x3f, 0xa1, 0xbf, +0x6f, 0xe2, 0x24, 0x4c, 0x2d, 0x93, 0xa7, 0x4c, +0x9d, 0xc6, 0x00, 0xcb, 0x03, 0x1e, 0xa9, 0x39, +0xd3, 0x67, 0x74, 0x78, 0xd4, 0x76, 0xcd, 0x9c, +0x35, 0xbb, 0x6f, 0xce, 0x9c, 0xb9, 0x73, 0xe7, +0xf4, 0xcd, 0xc3, 0xd4, 0x32, 0x7f, 0xc1, 0xc2, +0x45, 0x40, 0x3d, 0x4a, 0x8b, 0x41, 0x7a, 0x3c, +0x72, 0x97, 0x2c, 0x5d, 0x56, 0xeb, 0xb1, 0x7c, +0xc5, 0xca, 0x55, 0xab, 0xfb, 0xe7, 0x80, 0xf4, +0xf4, 0xaf, 0xc1, 0xd4, 0xb2, 0x76, 0xdd, 0xfa, +0x0d, 0x53, 0x95, 0x94, 0x94, 0x36, 0x6e, 0x02, +0xea, 0xf1, 0x28, 0xe9, 0xd8, 0x5c, 0x5b, 0xe7, +0xb1, 0x65, 0xeb, 0xb6, 0xed, 0x4d, 0x13, 0xe6, +0x82, 0xf4, 0x4c, 0xd8, 0x81, 0xa9, 0x65, 0xe7, +0xda, 0x5d, 0xbb, 0xf7, 0xec, 0xdd, 0xb7, 0x71, +0xd3, 0xfe, 0xfd, 0x4a, 0xc8, 0x21, 0x76, 0xa0, +0x7f, 0x2e, 0x48, 0x0f, 0x36, 0x5b, 0x80, 0x7a, +0xe6, 0x4f, 0x06, 0xda, 0x02, 0xd4, 0x01, 0xb4, +0xa5, 0x6e, 0xf9, 0xc1, 0x43, 0x87, 0x3d, 0x8e, +0x1c, 0x3d, 0x76, 0xfc, 0x44, 0x1f, 0xc8, 0x2b, +0x58, 0xfd, 0x02, 0x0b, 0xb8, 0xfd, 0x60, 0xbf, +0x9c, 0x9c, 0xb5, 0xea, 0xd4, 0x76, 0x8f, 0xd3, +0x67, 0xce, 0x9e, 0x3b, 0x8f, 0x3b, 0xc4, 0xa0, +0x00, 0x1a, 0x62, 0x17, 0x4e, 0x5d, 0xbc, 0x74, +0xda, 0xe3, 0xf8, 0xe5, 0x2b, 0x57, 0xaf, 0xd5, +0x5f, 0xbf, 0x71, 0xb3, 0xf1, 0x56, 0x2b, 0x03, +0x01, 0xe0, 0xb1, 0xed, 0xd2, 0xed, 0x33, 0xc7, +0x3d, 0xee, 0xdc, 0xbd, 0x77, 0xff, 0x01, 0xee, +0x34, 0x86, 0xaa, 0xe5, 0xc8, 0xe9, 0x63, 0x0f, +0x1f, 0x79, 0x3c, 0xbe, 0xf6, 0xe0, 0xc9, 0x53, +0xdc, 0x69, 0x0c, 0x05, 0x10, 0x97, 0xc6, 0x50, +0x6d, 0x79, 0x76, 0xe7, 0xf9, 0x8b, 0x97, 0x1e, +0xaf, 0x5e, 0xbf, 0x79, 0xfb, 0x8e, 0x48, 0x5b, +0x3c, 0xde, 0x5f, 0xfd, 0x70, 0xff, 0x89, 0xc7, +0x9b, 0x8f, 0x9f, 0x3e, 0x7d, 0x26, 0xd6, 0x2f, +0xd7, 0xee, 0x7f, 0xf9, 0xfa, 0xda, 0xe3, 0xdb, +0xa7, 0xef, 0x3f, 0x7e, 0x12, 0xab, 0xe5, 0xc1, +0xd7, 0x5f, 0xbf, 0xdf, 0x7a, 0x7c, 0xfe, 0xfe, +0xe3, 0xcf, 0x5f, 0x62, 0xb5, 0x3c, 0x7d, 0xf3, +0xf6, 0xdf, 0x3b, 0x8f, 0xff, 0x3f, 0xff, 0xfe, +0xfd, 0x4f, 0xbb, 0x10, 0x1b, 0x05, 0xd8, 0x01, +0x00, 0x26, 0xe3, 0x15, 0x51, 0xc3, 0xf0, 0xc4, +0xd2, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_merge_anti_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_merge_anti_join_png = new wxImage(); + if (!img_ex_merge_anti_join_png || !img_ex_merge_anti_join_png->IsOk()) + { + wxMemoryInputStream img_ex_merge_anti_join_pngIS(ex_merge_anti_join_png_data, sizeof(ex_merge_anti_join_png_data)); + img_ex_merge_anti_join_png->LoadFile(img_ex_merge_anti_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_anti_join_png; +} +#define ex_merge_anti_join_png_img ex_merge_anti_join_png_img() + +static wxBitmap *ex_merge_anti_join_png_bmp() +{ + static wxBitmap *bmp_ex_merge_anti_join_png; + if (!bmp_ex_merge_anti_join_png || !bmp_ex_merge_anti_join_png->IsOk()) + bmp_ex_merge_anti_join_png = new wxBitmap(*ex_merge_anti_join_png_img); + return bmp_ex_merge_anti_join_png; +} +#define ex_merge_anti_join_png_bmp ex_merge_anti_join_png_bmp() + +static wxIcon *ex_merge_anti_join_png_ico() +{ + static wxIcon *ico_ex_merge_anti_join_png; + if (!ico_ex_merge_anti_join_png || !ico_ex_merge_anti_join_png->IsOk()) + { + ico_ex_merge_anti_join_png = new wxIcon(); + ico_ex_merge_anti_join_png->CopyFromBitmap(*ex_merge_anti_join_png_bmp); + } + return ico_ex_merge_anti_join_png; +} +#define ex_merge_anti_join_png_ico ex_merge_anti_join_png_ico() + +#endif // EX_MERGE_ANTI_JOIN_PNG_H diff --git a/include/images/ex_merge_append.png b/include/images/ex_merge_append.png new file mode 100644 index 0000000..12fc55d Binary files /dev/null and b/include/images/ex_merge_append.png differ diff --git a/include/images/ex_merge_append.pngc b/include/images/ex_merge_append.pngc new file mode 100644 index 0000000..64ec67c --- /dev/null +++ b/include/images/ex_merge_append.pngc @@ -0,0 +1,167 @@ +#ifndef EX_MERGE_APPEND_PNG_H +#define EX_MERGE_APPEND_PNG_H + +static const unsigned char ex_merge_append_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0xbc, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, +0x6b, 0xd1, 0x52, 0x8d, 0x19, 0x36, 0x88, 0xc1, +0x07, 0xa8, 0xe2, 0x10, 0xab, 0xe2, 0x64, 0x95, +0xd0, 0x72, 0xa3, 0x35, 0x1a, 0xae, 0xe3, 0xc1, +0x8f, 0x36, 0x76, 0xaa, 0x3b, 0x7a, 0x9e, 0xa9, +0x78, 0xae, 0x3e, 0xb5, 0x99, 0x7e, 0x7a, 0xb1, +0x41, 0x84, 0xb0, 0x45, 0x7c, 0xb4, 0x43, 0x86, +0xb6, 0x49, 0x40, 0xbc, 0xe9, 0x45, 0xbe, 0xe9, +0x90, 0xb6, 0x6c, 0x4e, 0xbe, 0xe6, 0x4c, 0xc0, +0xe9, 0xa5, 0xa8, 0xe4, 0xa7, 0xa9, 0xe7, 0x53, +0xc2, 0xea, 0x5a, 0xc1, 0xe7, 0x8d, 0xc1, 0x53, +0x97, 0xbb, 0x75, 0x99, 0xbc, 0x78, 0xaa, 0xac, +0xe7, 0x89, 0xb9, 0xdb, 0x5d, 0xc5, 0xeb, 0x64, +0xc5, 0xe8, 0xae, 0xaf, 0xe9, 0xa1, 0xc4, 0x5e, +0xa2, 0xc7, 0x60, 0x96, 0xcc, 0x5d, 0x71, 0xcb, +0xec, 0xa4, 0xca, 0x63, 0x6f, 0xcd, 0xee, 0xa7, +0xcd, 0x66, 0x7a, 0xce, 0xec, 0xdb, 0xbe, 0x7f, +0xdb, 0xbd, 0x89, 0xbc, 0xbd, 0xec, 0xdc, 0xbf, +0x81, 0xdc, 0xc0, 0x81, 0xbd, 0xbf, 0xed, 0xbe, +0xbf, 0xed, 0xdd, 0xc1, 0x82, 0x83, 0xd1, 0xed, +0xdd, 0xc2, 0x83, 0xbf, 0xc1, 0xed, 0xde, 0xc4, +0x84, 0xc2, 0xc2, 0xee, 0x85, 0xd4, 0xf0, 0xde, +0xc5, 0x85, 0xc2, 0xc3, 0xef, 0x8b, 0xd4, 0xee, +0xdf, 0xc7, 0x86, 0x92, 0xd5, 0xef, 0xc5, 0xc6, +0xef, 0xba, 0xd1, 0xa3, 0xc5, 0xc6, 0xf0, 0xae, +0xda, 0x71, 0x94, 0xd8, 0xf0, 0xe1, 0xcc, 0x8a, +0xe2, 0xcf, 0x8d, 0xcb, 0xcc, 0xf1, 0xe4, 0xcd, +0x9e, 0xe4, 0xce, 0x9f, 0xcc, 0xcd, 0xf1, 0xe5, +0xce, 0xa0, 0xe3, 0xd1, 0x8e, 0xe5, 0xcf, 0xa0, +0xe3, 0xd2, 0x8f, 0xce, 0xcf, 0xf2, 0xb4, 0xe3, +0x79, 0xe4, 0xd3, 0x90, 0xe5, 0xd1, 0xa1, 0xe4, +0xd4, 0x91, 0xe6, 0xd2, 0xa3, 0xe4, 0xd5, 0x92, +0xd1, 0xd1, 0xf2, 0xe6, 0xd4, 0xa4, 0xe7, 0xd4, +0xa4, 0xb6, 0xe7, 0x7c, 0xe5, 0xd7, 0x93, 0xe7, +0xd5, 0xa5, 0xad, 0xdf, 0xf3, 0xd3, 0xd4, 0xf3, +0xd4, 0xd4, 0xf4, 0xe8, 0xd7, 0xa6, 0xe8, 0xd7, +0xa7, 0xe6, 0xda, 0x95, 0xe9, 0xd8, 0xa7, 0xd6, +0xd6, 0xf4, 0xb9, 0xeb, 0x7f, 0xe9, 0xd9, 0xa8, +0xe7, 0xdc, 0x97, 0xe9, 0xda, 0xa9, 0xea, 0xd9, +0xb6, 0xd8, 0xd9, 0xf4, 0xba, 0xee, 0x82, 0xe9, +0xdc, 0xaa, 0xea, 0xdc, 0xaa, 0xe8, 0xdf, 0x99, +0xeb, 0xdb, 0xb8, 0xe9, 0xe0, 0x9a, 0xbc, 0xf0, +0x84, 0xeb, 0xde, 0xac, 0xe9, 0xe1, 0x9b, 0xec, +0xdd, 0xba, 0xeb, 0xdf, 0xad, 0xec, 0xde, 0xba, +0xea, 0xe2, 0x9c, 0xec, 0xe0, 0xad, 0xec, 0xe1, +0xae, 0xea, 0xe4, 0x9d, 0xd8, 0xe5, 0xcb, 0xec, +0xe2, 0xaf, 0xed, 0xe1, 0xbc, 0xec, 0xe3, 0xaf, +0xec, 0xe3, 0xb0, 0xed, 0xe3, 0xb0, 0xe0, 0xe0, +0xf7, 0xee, 0xe2, 0xbd, 0xed, 0xe4, 0xb1, 0xee, +0xe3, 0xbe, 0xed, 0xe5, 0xb1, 0xee, 0xe6, 0xb2, +0xef, 0xe5, 0xbf, 0xef, 0xe6, 0xc0, 0xef, 0xe8, +0xb3, 0xef, 0xe9, 0xb4, 0xf0, 0xe8, 0xc1, 0xf0, +0xe8, 0xc2, 0xef, 0xea, 0xb6, 0xef, 0xeb, 0xb6, +0xf1, 0xea, 0xc3, 0xf0, 0xec, 0xb6, 0xf0, 0xec, +0xb7, 0xf2, 0xec, 0xc5, 0xf3, 0xed, 0xc6, 0xf3, +0xef, 0xc7, 0xf4, 0xf1, 0xc9, 0x04, 0x44, 0xd7, +0x8c, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x01, 0xb1, 0x49, +0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0x93, 0x55, +0x53, 0xc3, 0x40, 0x14, 0x85, 0xb3, 0xd9, 0x00, +0xe5, 0x42, 0x71, 0x97, 0x60, 0xc5, 0xdd, 0xdd, +0xdd, 0x9d, 0xa2, 0x2d, 0xee, 0xee, 0xae, 0xc5, +0x1d, 0xfe, 0x30, 0x49, 0xc8, 0x00, 0x4d, 0xbb, +0xd9, 0xc0, 0x0c, 0xc3, 0x0b, 0xe7, 0xe1, 0xbe, +0xec, 0x7c, 0x73, 0xee, 0xd9, 0xb3, 0xcb, 0x30, +0xff, 0xfa, 0x91, 0xc2, 0x39, 0x51, 0xf2, 0xd4, +0x86, 0x70, 0xf1, 0x3e, 0xfe, 0x41, 0xf9, 0x5c, +0x65, 0x62, 0x56, 0xd1, 0x00, 0xa7, 0x11, 0xf1, +0x76, 0x70, 0x74, 0x8e, 0xe0, 0x62, 0xfd, 0x82, +0x23, 0x4b, 0xb8, 0x5f, 0x73, 0x71, 0x92, 0x52, +0xc8, 0x53, 0x5b, 0x48, 0xb6, 0x3e, 0x3d, 0xa7, +0x70, 0x90, 0x9d, 0x6e, 0xe9, 0x1e, 0x3a, 0x62, +0xb5, 0xd9, 0xb3, 0x29, 0x81, 0x28, 0xaa, 0x94, +0xad, 0xc9, 0xc8, 0x2b, 0x1f, 0x65, 0xb5, 0x85, +0x24, 0x23, 0xdf, 0x77, 0x21, 0x86, 0x54, 0x66, +0xe1, 0x31, 0xf6, 0xdd, 0x51, 0x0f, 0xc9, 0x04, +0xb0, 0xa2, 0xe4, 0xc9, 0x30, 0xd8, 0x60, 0xf0, +0x78, 0x67, 0x88, 0xf6, 0xb6, 0x2e, 0x3a, 0x81, +0xa1, 0x20, 0x29, 0x28, 0x0c, 0x7d, 0x3d, 0xe1, +0x75, 0x06, 0xfc, 0x4d, 0x84, 0xc1, 0xd1, 0x58, +0x3d, 0x8b, 0x1d, 0x24, 0x4e, 0x42, 0xdc, 0x40, +0x94, 0x3c, 0x29, 0xed, 0xe3, 0x04, 0x09, 0x81, +0xd7, 0xc7, 0x87, 0xdb, 0x17, 0x78, 0x3a, 0x3b, +0xdc, 0xbd, 0x06, 0xb5, 0x1b, 0x13, 0x14, 0xea, +0xe5, 0xc2, 0x8b, 0xc8, 0xc3, 0x36, 0x5a, 0xb9, +0x84, 0xb3, 0xe1, 0xbe, 0xae, 0x65, 0xa0, 0x3c, +0xd4, 0x32, 0x97, 0x0a, 0xbd, 0xc0, 0xc0, 0xdd, +0x06, 0x9a, 0xb7, 0xc0, 0x7e, 0x5f, 0x47, 0xf3, +0x2c, 0x0d, 0x61, 0x78, 0x7d, 0xab, 0xb0, 0x1a, +0x5c, 0x2d, 0xa2, 0x89, 0x03, 0xd8, 0x6c, 0x6b, +0xac, 0x1e, 0xa7, 0xba, 0xe8, 0x5b, 0xdd, 0x45, +0x97, 0x67, 0xcb, 0xc9, 0xc1, 0x0d, 0x5c, 0xcc, +0x4d, 0x8e, 0xec, 0x01, 0xe5, 0xef, 0x87, 0x86, +0x88, 0x84, 0xca, 0x8d, 0xd9, 0x3e, 0x58, 0xdc, +0x4b, 0xe9, 0xc5, 0xf6, 0x5b, 0xe0, 0x31, 0x6c, +0xbf, 0x30, 0x15, 0x97, 0x19, 0x0a, 0xe2, 0x2a, +0xa5, 0x90, 0xa7, 0x74, 0x5f, 0x9e, 0x4b, 0x14, +0x44, 0x51, 0x32, 0x8f, 0x3d, 0x97, 0x62, 0x7c, +0xd5, 0xb3, 0x28, 0x4a, 0xc6, 0x33, 0x02, 0xb1, +0x63, 0xff, 0x59, 0x7c, 0x20, 0xd6, 0x25, 0x7f, +0xfe, 0x4a, 0xb8, 0xdf, 0xdd, 0x5c, 0x3e, 0x87, +0x63, 0x73, 0x7f, 0xcf, 0xaa, 0x75, 0x2f, 0xc4, +0x92, 0x61, 0x0b, 0x35, 0xa3, 0x49, 0x30, 0x15, +0x17, 0x64, 0xb7, 0x2b, 0x10, 0x52, 0xc9, 0xb0, +0x86, 0xaa, 0x91, 0x19, 0x8c, 0xb9, 0xd9, 0x69, +0x0d, 0xd6, 0x48, 0xb2, 0x54, 0xaf, 0x3c, 0xad, +0x90, 0x39, 0x54, 0x85, 0xfa, 0xa1, 0x33, 0x33, +0x35, 0xa9, 0x56, 0xe1, 0x42, 0x5a, 0x19, 0x4e, +0x47, 0x4c, 0xc6, 0x75, 0x58, 0x68, 0xaa, 0xab, +0x9d, 0x52, 0x20, 0xa4, 0x95, 0x89, 0xf6, 0x2a, +0x2b, 0x13, 0x45, 0x5e, 0x99, 0x8c, 0x10, 0x57, +0x26, 0x8a, 0xbc, 0xf2, 0xbf, 0xfe, 0x44, 0x6f, +0xcd, 0xbf, 0x9d, 0xa5, 0x3e, 0x0e, 0x99, 0xef, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_merge_append_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_merge_append_png = new wxImage(); + if (!img_ex_merge_append_png || !img_ex_merge_append_png->IsOk()) + { + wxMemoryInputStream img_ex_merge_append_pngIS(ex_merge_append_png_data, sizeof(ex_merge_append_png_data)); + img_ex_merge_append_png->LoadFile(img_ex_merge_append_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_append_png; +} +#define ex_merge_append_png_img ex_merge_append_png_img() + +static wxBitmap *ex_merge_append_png_bmp() +{ + static wxBitmap *bmp_ex_merge_append_png; + if (!bmp_ex_merge_append_png || !bmp_ex_merge_append_png->IsOk()) + bmp_ex_merge_append_png = new wxBitmap(*ex_merge_append_png_img); + return bmp_ex_merge_append_png; +} +#define ex_merge_append_png_bmp ex_merge_append_png_bmp() + +static wxIcon *ex_merge_append_png_ico() +{ + static wxIcon *ico_ex_merge_append_png; + if (!ico_ex_merge_append_png || !ico_ex_merge_append_png->IsOk()) + { + ico_ex_merge_append_png = new wxIcon(); + ico_ex_merge_append_png->CopyFromBitmap(*ex_merge_append_png_bmp); + } + return ico_ex_merge_append_png; +} +#define ex_merge_append_png_ico ex_merge_append_png_ico() + +#endif // EX_MERGE_APPEND_PNG_H diff --git a/include/images/ex_merge_semi_join.png b/include/images/ex_merge_semi_join.png new file mode 100644 index 0000000..6ce4839 Binary files /dev/null and b/include/images/ex_merge_semi_join.png differ diff --git a/include/images/ex_merge_semi_join.pngc b/include/images/ex_merge_semi_join.pngc new file mode 100644 index 0000000..df427ef --- /dev/null +++ b/include/images/ex_merge_semi_join.pngc @@ -0,0 +1,212 @@ +#ifndef EX_MERGE_SEMI_JOIN_PNG_H +#define EX_MERGE_SEMI_JOIN_PNG_H + +static const unsigned char ex_merge_semi_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x02, 0x91, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0xa8, 0xe4, 0x66, +0x6b, 0xd1, 0xcc, 0xcd, 0xf1, 0xbc, 0xbe, 0xec, +0xbe, 0xbf, 0xed, 0xbf, 0xc1, 0xed, 0xd0, 0xd1, +0xf2, 0xd3, 0xd4, 0xf3, 0xc7, 0xc8, 0xef, 0xc8, +0xc9, 0xf0, 0xcb, 0xcb, 0xf1, 0xd9, 0xda, 0xf5, +0xdc, 0xdc, 0xf5, 0xd2, 0xd3, 0xf3, 0xd4, 0xd4, +0xf4, 0xd5, 0xd6, 0xf4, 0xe1, 0xe1, 0xf7, 0xbc, +0xbd, 0xec, 0xa6, 0xa8, 0xe6, 0xa8, 0xaa, 0xe7, +0xaa, 0xac, 0xe7, 0xc1, 0xc2, 0xee, 0xc5, 0xc5, +0xef, 0xb4, 0xb5, 0xea, 0xb6, 0xb7, 0xeb, 0xb9, +0xba, 0xec, 0xcd, 0xce, 0xf2, 0xd1, 0xd1, 0xf2, +0xc3, 0xc4, 0xef, 0xc5, 0xc6, 0xf0, 0xc7, 0xc8, +0xf0, 0xd7, 0xd7, 0xf5, 0x99, 0xbc, 0x78, 0x52, +0x8d, 0x19, 0xa1, 0xc4, 0x5e, 0x89, 0xb9, 0xdb, +0x36, 0x88, 0xc1, 0x70, 0xab, 0xd3, 0x9a, 0xc3, +0xe0, 0xc4, 0xdc, 0xed, 0x6f, 0xcd, 0xee, 0x4d, +0xc0, 0xe9, 0x61, 0xc6, 0xeb, 0x76, 0xcd, 0xec, +0xa6, 0xde, 0xf2, 0xb7, 0xe6, 0xf6, 0xa2, 0xde, +0xf4, 0xa5, 0xdf, 0xf4, 0xa9, 0xe0, 0xf4, 0xc2, +0xe9, 0xf7, 0xc9, 0xeb, 0xf7, 0xbc, 0xe6, 0xf5, +0xc1, 0xe8, 0xf6, 0xc5, 0xe9, 0xf6, 0xd6, 0xef, +0xf9, 0x40, 0xbc, 0xe9, 0x12, 0xab, 0xe2, 0x2c, +0xb3, 0xe4, 0x48, 0xbc, 0xe6, 0x89, 0xd3, 0xee, +0x9f, 0xdd, 0xf4, 0x83, 0xd3, 0xf0, 0x87, 0xd5, +0xf0, 0x8c, 0xd6, 0xf1, 0xae, 0xe2, 0xf5, 0xb8, +0xe5, 0xf5, 0xac, 0xe0, 0xf3, 0xb1, 0xe2, 0xf3, +0xc8, 0xea, 0xf7, 0xa2, 0xc6, 0x5f, 0x7a, 0x9e, +0xa9, 0x72, 0x95, 0x9e, 0xe0, 0xc7, 0x9a, 0xd0, +0xc6, 0xbb, 0xb2, 0xb5, 0xe8, 0xba, 0xc5, 0xea, +0xa3, 0xc7, 0x61, 0xc1, 0x8f, 0x36, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xf9, 0xf8, 0xe4, 0xf7, +0xf5, 0xdb, 0xe5, 0xe6, 0xf8, 0xdf, 0xe0, 0xf6, +0xe2, 0xe3, 0xf7, 0xe6, 0xe6, 0xf8, 0xee, 0xee, +0xfa, 0xa4, 0xc9, 0x62, 0xeb, 0xe6, 0x9f, 0xf5, +0xf2, 0xcf, 0xdd, 0xde, 0xf5, 0xd5, 0xd5, 0xf3, +0xd9, 0xd9, 0xf4, 0xdd, 0xde, 0xf6, 0xe9, 0xe9, +0xf9, 0xa5, 0xcb, 0x64, 0xa6, 0xcd, 0x66, 0xa8, +0xcf, 0x68, 0xa9, 0xd2, 0x6a, 0xdb, 0xbd, 0x89, +0xd3, 0xb0, 0x70, 0xda, 0xcc, 0xbf, 0xd2, 0xd3, +0xf1, 0xab, 0xd5, 0x6c, 0xf0, 0xec, 0xb6, 0xef, +0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xf7, 0xf5, 0xda, +0xf9, 0xf7, 0xe3, 0xad, 0xd7, 0x6f, 0xea, 0xe4, +0x9d, 0xea, 0xe3, 0x9c, 0xe9, 0xe0, 0x9a, 0xee, +0xe6, 0xb3, 0xf4, 0xf1, 0xce, 0xf4, 0xf1, 0xcd, +0xf4, 0xef, 0xcc, 0xf6, 0xf2, 0xd9, 0x67, 0x9b, +0x35, 0xa3, 0xd1, 0x66, 0x5d, 0x97, 0x24, 0xea, +0xf1, 0xe3, 0xef, 0xea, 0xb6, 0xe9, 0xe1, 0x9b, +0xe8, 0xdf, 0x99, 0xe7, 0xdd, 0x97, 0xec, 0xe3, +0xb0, 0xf7, 0xf4, 0xda, 0xf4, 0xf0, 0xcd, 0xf3, +0xef, 0xcc, 0xf3, 0xee, 0xcb, 0xf5, 0xf1, 0xd7, +0x7b, 0xa8, 0x50, 0x9a, 0xca, 0x5d, 0x78, 0xae, +0x3e, 0xba, 0xd1, 0xa3, 0xb9, 0xec, 0x80, 0xef, +0xe8, 0xb3, 0xe8, 0xde, 0x98, 0xe7, 0xdb, 0x96, +0xe6, 0xd8, 0x94, 0xec, 0xe0, 0xad, 0xf7, 0xf3, +0xd9, 0xf3, 0xed, 0xca, 0xf2, 0xeb, 0xc9, 0xf5, +0xef, 0xd6, 0xa0, 0xc0, 0x81, 0x87, 0xba, 0x4c, +0x9c, 0xce, 0x61, 0x7a, 0xb0, 0x40, 0x5e, 0x98, +0x25, 0xba, 0xee, 0x82, 0xbb, 0xef, 0x83, 0xf1, +0xeb, 0xc4, 0xec, 0xe0, 0xae, 0xeb, 0xde, 0xac, +0xef, 0xe4, 0xbf, 0xf8, 0xf5, 0xe1, 0xf5, 0xee, +0xd5, 0xf7, 0xf1, 0xdf, 0xe7, 0xef, 0xdf, 0x88, +0xbd, 0x4e, 0x9e, 0xd1, 0x64, 0xab, 0xde, 0x71, +0xb8, 0xeb, 0x7f, 0xba, 0xec, 0x81, 0xbc, 0xf0, +0x84, 0xf0, 0xe6, 0xc0, 0xe9, 0xdc, 0xaa, 0xe9, +0xda, 0xa8, 0xe8, 0xd7, 0xa7, 0xed, 0xdf, 0xbb, +0xf7, 0xf2, 0xdf, 0xf4, 0xed, 0xd4, 0xf4, 0xec, +0xd3, 0xf3, 0xeb, 0xd3, 0xf6, 0xef, 0xdd, 0xe9, +0xda, 0xa9, 0xe0, 0xcb, 0x8a, 0xdf, 0xc8, 0x87, +0xde, 0xc5, 0x85, 0xe6, 0xd1, 0xa2, 0xf4, 0xec, +0xd4, 0xef, 0xe5, 0xc4, 0xef, 0xe3, 0xc3, 0xee, +0xe2, 0xc2, 0xf2, 0xe8, 0xd0, 0xe8, 0xd7, 0xa6, +0xdf, 0xc6, 0x86, 0xde, 0xc3, 0x84, 0xdd, 0xc1, +0x82, 0xe5, 0xcf, 0xa0, 0xf3, 0xeb, 0xd2, 0xef, +0xe2, 0xc2, 0xee, 0xe1, 0xc1, 0xee, 0xe0, 0xc0, +0xf2, 0xe7, 0xcf, 0xe6, 0xd4, 0xa4, 0xdd, 0xc2, +0x83, 0xdc, 0xc0, 0x81, 0xdb, 0xbd, 0x7f, 0xe4, +0xcd, 0x9e, 0xf2, 0xe9, 0xd1, 0xee, 0xe0, 0xc1, +0xed, 0xdf, 0xc0, 0xed, 0xde, 0xbf, 0xf1, 0xe6, +0xce, 0xeb, 0xdb, 0xb8, 0xe5, 0xce, 0xa0, 0xe3, +0xcc, 0x9e, 0xea, 0xd8, 0xb6, 0xf5, 0xed, 0xdb, +0xf2, 0xe6, 0xcf, 0xf1, 0xe5, 0xce, 0xf4, 0xeb, +0xda, 0xe3, 0xcb, 0x9e, 0xda, 0xba, 0x7d, 0xec, +0xdc, 0xbe, 0xef, 0xc3, 0x82, 0xc1, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x01, 0xe6, 0x49, 0x44, 0x41, 0x54, +0x48, 0xc7, 0x63, 0x60, 0x18, 0x05, 0x0c, 0x8c, +0x4c, 0x20, 0x80, 0x42, 0x12, 0xd2, 0xc2, 0xc4, +0xcc, 0xc2, 0xca, 0xc6, 0xce, 0xc4, 0xc1, 0xc9, +0xc5, 0xcd, 0xc3, 0xc4, 0xcb, 0xc7, 0x2f, 0x20, +0xc8, 0x44, 0x50, 0x8b, 0x90, 0xb0, 0x88, 0xa8, +0x18, 0x93, 0xb8, 0x84, 0xa4, 0x94, 0x34, 0x93, +0x8c, 0xac, 0x9c, 0xbc, 0xc2, 0x60, 0xd1, 0x42, +0xba, 0x5f, 0xc8, 0x08, 0x31, 0x0a, 0x80, 0xa2, +0x92, 0x22, 0xa9, 0x5a, 0x94, 0x94, 0x95, 0x28, +0xd2, 0xa2, 0xa2, 0x0a, 0x02, 0x6a, 0xea, 0x20, +0xa0, 0x01, 0x21, 0x09, 0x69, 0x51, 0xd5, 0xd4, +0xd2, 0xd6, 0xd1, 0x55, 0xd5, 0xd3, 0x37, 0x30, +0x34, 0x52, 0x37, 0x36, 0x31, 0x35, 0x33, 0x57, +0x27, 0xa8, 0xc5, 0xc2, 0xd2, 0xca, 0xda, 0x46, +0xd5, 0xd6, 0xce, 0xde, 0xc1, 0x51, 0xdd, 0x49, +0xd7, 0xd9, 0xc5, 0x95, 0xb0, 0x16, 0xe2, 0x6c, +0x71, 0x43, 0xd2, 0xe2, 0x0e, 0xf6, 0x8b, 0x87, +0x27, 0x08, 0x78, 0x79, 0x83, 0x80, 0x0f, 0x36, +0x2d, 0xbe, 0x48, 0x5a, 0xfc, 0xfc, 0x03, 0x02, +0x02, 0xfc, 0xfd, 0x02, 0x83, 0x82, 0x82, 0x02, +0x3d, 0x83, 0x43, 0x42, 0xc3, 0xc2, 0xbd, 0xb1, +0x69, 0x89, 0x40, 0xd6, 0x12, 0x10, 0x19, 0x19, +0x19, 0xe0, 0x17, 0x14, 0x15, 0x15, 0x15, 0xe4, +0x19, 0x1d, 0x13, 0x1b, 0x17, 0x8f, 0x55, 0x4b, +0x02, 0xe9, 0x5a, 0x12, 0x49, 0xd7, 0x92, 0x44, +0xba, 0x5f, 0x92, 0x91, 0xb4, 0xa4, 0xf8, 0x81, +0x40, 0x2a, 0x38, 0xc4, 0xd2, 0xc0, 0x21, 0x96, +0x8e, 0x4d, 0x4b, 0x06, 0xaa, 0x2d, 0x99, 0x59, +0xd9, 0x40, 0x5b, 0x72, 0x72, 0x72, 0xf1, 0xd8, +0x92, 0x87, 0xe2, 0x97, 0xfc, 0x82, 0xc2, 0x22, +0xbf, 0xa0, 0xe2, 0x92, 0xd2, 0x32, 0xdc, 0x7e, +0x29, 0xaf, 0xa8, 0xac, 0x62, 0x80, 0xe5, 0x01, +0xbf, 0xea, 0x9a, 0xda, 0xba, 0x7a, 0xbf, 0x86, +0xc6, 0xa6, 0xe6, 0x16, 0xdc, 0x5a, 0x5a, 0xdb, +0xda, 0x3b, 0x80, 0x7a, 0x94, 0x3a, 0x41, 0x7a, +0xfc, 0xba, 0xba, 0x7b, 0x7a, 0xfb, 0xfc, 0xfa, +0x9b, 0x27, 0x4c, 0x9c, 0x84, 0x5b, 0xcb, 0xe4, +0x29, 0x53, 0xa7, 0x4d, 0x57, 0x52, 0x52, 0x9a, +0x31, 0x13, 0xa8, 0xc7, 0x6f, 0x56, 0xfd, 0xec, +0x39, 0x73, 0xfd, 0xe6, 0xb5, 0x4c, 0x9a, 0xbf, +0x00, 0xb7, 0x5f, 0x16, 0x4e, 0x5e, 0xb4, 0x78, +0xc9, 0xd2, 0x65, 0x33, 0x66, 0x2e, 0x5f, 0xae, +0x44, 0x64, 0x88, 0x01, 0xf5, 0xb4, 0x96, 0x03, +0x6d, 0x01, 0xea, 0x00, 0xda, 0xb2, 0x62, 0xe5, +0xaa, 0xd5, 0x6b, 0xfc, 0xd6, 0xae, 0x5b, 0xbf, +0x61, 0x23, 0x6e, 0x5b, 0x60, 0x01, 0xb7, 0x1c, +0xec, 0x97, 0x4d, 0x9b, 0xb7, 0x6c, 0xdd, 0xe6, +0xb7, 0x7d, 0xc7, 0xce, 0x5d, 0xbb, 0x71, 0xfb, +0x05, 0x0a, 0xa0, 0x21, 0xb6, 0x67, 0xef, 0xbe, +0xfd, 0x07, 0xfc, 0x0e, 0x1e, 0x3a, 0x7c, 0xe4, +0x28, 0x41, 0x2d, 0xd0, 0x78, 0x39, 0x76, 0xfc, +0xc4, 0xc9, 0x53, 0x7e, 0xa7, 0xcf, 0x9c, 0x3d, +0x77, 0x9e, 0x58, 0x2d, 0x17, 0x2e, 0x9e, 0xba, +0x74, 0xd9, 0xef, 0xca, 0xd5, 0xf3, 0xd7, 0xae, +0x13, 0xf4, 0x0b, 0x04, 0x10, 0x19, 0x62, 0x28, +0xb6, 0x5c, 0xbe, 0x71, 0xe3, 0xc6, 0x65, 0xbf, +0xeb, 0xd7, 0xae, 0x11, 0x6d, 0x8b, 0xdf, 0x8d, +0x9b, 0x37, 0x6f, 0xde, 0xf0, 0xbb, 0x76, 0xeb, +0xd6, 0xad, 0x6b, 0xc4, 0xfa, 0x85, 0x3e, 0x5a, +0x48, 0xf7, 0x0b, 0x19, 0x21, 0x36, 0x0a, 0xb0, +0x02, 0x00, 0x4b, 0xf8, 0x03, 0x0f, 0x08, 0xe5, +0xcb, 0x37, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_merge_semi_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_merge_semi_join_png = new wxImage(); + if (!img_ex_merge_semi_join_png || !img_ex_merge_semi_join_png->IsOk()) + { + wxMemoryInputStream img_ex_merge_semi_join_pngIS(ex_merge_semi_join_png_data, sizeof(ex_merge_semi_join_png_data)); + img_ex_merge_semi_join_png->LoadFile(img_ex_merge_semi_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_merge_semi_join_png; +} +#define ex_merge_semi_join_png_img ex_merge_semi_join_png_img() + +static wxBitmap *ex_merge_semi_join_png_bmp() +{ + static wxBitmap *bmp_ex_merge_semi_join_png; + if (!bmp_ex_merge_semi_join_png || !bmp_ex_merge_semi_join_png->IsOk()) + bmp_ex_merge_semi_join_png = new wxBitmap(*ex_merge_semi_join_png_img); + return bmp_ex_merge_semi_join_png; +} +#define ex_merge_semi_join_png_bmp ex_merge_semi_join_png_bmp() + +static wxIcon *ex_merge_semi_join_png_ico() +{ + static wxIcon *ico_ex_merge_semi_join_png; + if (!ico_ex_merge_semi_join_png || !ico_ex_merge_semi_join_png->IsOk()) + { + ico_ex_merge_semi_join_png = new wxIcon(); + ico_ex_merge_semi_join_png->CopyFromBitmap(*ex_merge_semi_join_png_bmp); + } + return ico_ex_merge_semi_join_png; +} +#define ex_merge_semi_join_png_ico ex_merge_semi_join_png_ico() + +#endif // EX_MERGE_SEMI_JOIN_PNG_H diff --git a/include/images/ex_nested.png b/include/images/ex_nested.png new file mode 100644 index 0000000..15c4731 Binary files /dev/null and b/include/images/ex_nested.png differ diff --git a/include/images/ex_nested.pngc b/include/images/ex_nested.pngc new file mode 100644 index 0000000..885d8fc --- /dev/null +++ b/include/images/ex_nested.pngc @@ -0,0 +1,183 @@ +#ifndef EX_NESTED_PNG_H +#define EX_NESTED_PNG_H + +static const unsigned char ex_nested_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc1, 0xc2, 0xd0, 0x96, +0x99, 0xd1, 0x7f, 0x83, 0xd1, 0x73, 0x77, 0xd1, +0x66, 0x6b, 0xd1, 0xa2, 0xa5, 0xe4, 0xb5, 0xb7, +0xea, 0xbb, 0xbe, 0xec, 0xc3, 0xc4, 0xef, 0xc0, +0xc1, 0xed, 0xc0, 0xc1, 0xee, 0xc1, 0xc2, 0xee, +0xc2, 0xc3, 0xee, 0xc4, 0xc5, 0xef, 0xc5, 0xc6, +0xef, 0xc6, 0xc7, 0xef, 0xc7, 0xc8, 0xef, 0xc8, +0xc9, 0xf0, 0xc8, 0xca, 0xf0, 0xca, 0xcb, 0xf1, +0xcb, 0xcc, 0xf1, 0xcc, 0xcd, 0xf2, 0xcd, 0xce, +0xf2, 0xce, 0xce, 0xf1, 0xce, 0xcf, 0xf2, 0xd0, +0xd0, 0xf2, 0xd2, 0xd3, 0xf3, 0xd4, 0xd4, 0xf3, +0xd5, 0xd5, 0xf4, 0xd7, 0xd7, 0xf5, 0xab, 0xae, +0xe6, 0xae, 0xb1, 0xe8, 0xa7, 0xaa, 0xe6, 0xbf, +0xc0, 0xed, 0xb9, 0xbb, 0xeb, 0xb1, 0xb3, 0xe9, +0x92, 0x95, 0xdf, 0x74, 0x79, 0xd6, 0x98, 0x9b, +0xe1, 0xc1, 0xc2, 0xed, 0xa6, 0xa8, 0xd0, 0xc3, +0xc4, 0xd0, 0xbc, 0xbe, 0xec, 0xd9, 0xd9, 0xf5, +0xbd, 0xbf, 0xec, 0xc7, 0xc5, 0xb7, 0xab, 0xa5, +0x6c, 0x9d, 0x94, 0x45, 0x95, 0x8b, 0x2f, 0x8d, +0x81, 0x19, 0xc3, 0xc2, 0x74, 0xd5, 0xd9, 0x91, +0xdf, 0xe6, 0x9c, 0xe6, 0xf3, 0xa7, 0xe4, 0xf1, +0xa1, 0xe3, 0xf0, 0xa0, 0xe3, 0xf0, 0x9e, 0xe2, +0xee, 0x9e, 0xe2, 0xed, 0x9d, 0xe1, 0xec, 0x9c, +0xe1, 0xec, 0x9b, 0xe0, 0xea, 0x9b, 0xdf, 0xe8, +0x99, 0xde, 0xe7, 0x98, 0xe0, 0xe8, 0x9e, 0xd9, +0xdc, 0x95, 0xd1, 0xd2, 0x8d, 0xbf, 0xbc, 0x70, +0xd2, 0xd8, 0x8b, 0xcd, 0xd3, 0x7d, 0xd2, 0xda, +0x87, 0xda, 0xe2, 0x93, 0xd4, 0xda, 0x8a, 0xc8, +0xca, 0x76, 0xcd, 0xcf, 0x82, 0xcd, 0xce, 0xf1, +0xb3, 0xb0, 0x5c, 0x98, 0x8e, 0x2c, 0xb1, 0xac, +0x59, 0xce, 0xcf, 0x84, 0xc7, 0xc8, 0x73, 0xcf, +0xcf, 0x89, 0x92, 0x95, 0xd1, 0xb5, 0xb0, 0x87, +0xc8, 0xc6, 0xba, 0xd9, 0xdf, 0x8c, 0xdd, 0xe2, +0x99, 0xda, 0xdf, 0x92, 0xda, 0xde, 0x91, 0xd9, +0xdd, 0x8f, 0xea, 0xf3, 0xb7, 0xc8, 0xc9, 0xef, +0xa9, 0xa2, 0x64, 0xd9, 0xdc, 0x8f, 0xad, 0xae, +0xe8, 0xd8, 0xdb, 0x8f, 0xbd, 0xbf, 0xed, 0xd7, +0xda, 0x8c, 0xb7, 0xb8, 0xeb, 0xb8, 0xb9, 0xeb, +0xd7, 0xd8, 0x8c, 0xe5, 0xee, 0xac, 0xe3, 0xeb, +0xa3, 0xd8, 0xe4, 0x80, 0xd6, 0xd7, 0x8b, 0xeb, +0xf2, 0xbd, 0xe9, 0xef, 0xba, 0xd5, 0xd7, 0x8a, +0xdd, 0xe7, 0x91, 0xd5, 0xd6, 0x89, 0xd5, 0xd5, +0x8a, 0xde, 0xe5, 0x96, 0xd4, 0xd4, 0x88, 0x97, +0x8d, 0x2b, 0xd8, 0xdb, 0x93, 0xcc, 0xcd, 0x7d, +0xaf, 0xa8, 0x55, 0xd1, 0xcf, 0x89, 0xc8, 0xc4, +0x79, 0xc2, 0xbe, 0x6d, 0xcb, 0xc8, 0x84, 0xd2, +0xd5, 0x86, 0xd7, 0xda, 0x8e, 0xbc, 0xb6, 0x6b, +0xdc, 0xe1, 0x97, 0xd7, 0xd6, 0x8e, 0xd6, 0xd6, +0xf4, 0x43, 0x9e, 0x2a, 0xa4, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x0b, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd5, 0xeb, 0x53, 0xda, 0x40, 0x10, +0x00, 0x70, 0x04, 0x4e, 0x04, 0x95, 0x5a, 0x4b, +0xad, 0x82, 0x82, 0x42, 0xc5, 0x07, 0x95, 0x84, +0x05, 0x1f, 0x69, 0x2d, 0x60, 0x45, 0xea, 0x13, +0x54, 0xc4, 0x2a, 0xca, 0xa3, 0x69, 0xa3, 0x44, +0x11, 0x44, 0xf1, 0x6d, 0xeb, 0xbf, 0xae, 0xe2, +0x38, 0xc3, 0x25, 0x77, 0x27, 0xf2, 0xb5, 0xdd, +0x2f, 0x99, 0xdc, 0xcc, 0x6f, 0xf6, 0x76, 0xee, +0x6e, 0x57, 0xa3, 0xf9, 0x1f, 0x0f, 0xd1, 0xa4, +0xd5, 0xe9, 0x11, 0x33, 0xf4, 0x3a, 0x6d, 0x13, +0x2e, 0x9a, 0x0d, 0x2d, 0x46, 0x53, 0x6b, 0x5b, +0x5b, 0xbb, 0xd1, 0x6c, 0x7e, 0xd3, 0xf1, 0xb6, +0xf3, 0x9d, 0xc5, 0xf2, 0xbe, 0xeb, 0x43, 0x77, +0x8f, 0xd5, 0x6a, 0xb5, 0xd9, 0x7a, 0x7b, 0xfb, +0xec, 0xdd, 0x66, 0x07, 0x66, 0xb4, 0xcd, 0xfd, +0x03, 0xfd, 0x06, 0x16, 0xe9, 0x74, 0xba, 0x4c, +0x0e, 0x6d, 0x0d, 0xd1, 0x19, 0x06, 0x3e, 0x0e, +0xba, 0x59, 0xfb, 0x72, 0x0f, 0x0d, 0xbb, 0xcc, +0xba, 0x1a, 0xa2, 0x77, 0x39, 0x06, 0x47, 0x46, +0x59, 0xc5, 0x8e, 0x8e, 0x0c, 0x99, 0x7a, 0xf4, +0x35, 0x0b, 0xc8, 0xe9, 0x71, 0x33, 0xc5, 0x83, +0x71, 0x5b, 0x3e, 0xa1, 0x5a, 0xe2, 0xf1, 0x20, +0xcd, 0x0b, 0x81, 0xec, 0x0a, 0x32, 0xf6, 0xf4, +0xeb, 0xe5, 0x78, 0x1f, 0x28, 0xc2, 0xc7, 0x73, +0xde, 0x2a, 0xb1, 0x93, 0x88, 0x97, 0xf3, 0x07, +0xc6, 0x27, 0x26, 0xa7, 0x04, 0x41, 0xf8, 0xfc, +0x65, 0xfa, 0x6b, 0x30, 0x18, 0x0c, 0x85, 0x67, +0xbe, 0xcd, 0x46, 0x1e, 0x0d, 0x85, 0x70, 0xfe, +0xb9, 0xe8, 0xf7, 0x79, 0x4c, 0x84, 0x17, 0xa2, +0x8b, 0x4b, 0x11, 0x4e, 0x4d, 0x96, 0x97, 0xab, +0xbf, 0x7c, 0x20, 0x3a, 0xb7, 0x12, 0xc3, 0xf7, +0x15, 0x8b, 0xaf, 0xae, 0xad, 0xf3, 0x2a, 0x92, +0x40, 0x28, 0xf1, 0xf8, 0x85, 0x09, 0x61, 0x65, +0x23, 0x89, 0x97, 0x9d, 0xdc, 0x88, 0x6f, 0xfe, +0x00, 0x15, 0x79, 0x0e, 0x98, 0x14, 0x62, 0x49, +0xe5, 0x62, 0x32, 0xb6, 0xb9, 0xc5, 0x24, 0x40, +0x58, 0xdd, 0x66, 0x91, 0x29, 0x32, 0x49, 0x01, +0xbd, 0x96, 0x9d, 0x1d, 0x12, 0x49, 0xa9, 0x49, +0x02, 0xed, 0xee, 0x56, 0x4d, 0x1a, 0x20, 0x4d, +0x22, 0x19, 0x25, 0x49, 0xa0, 0xf6, 0x6c, 0xd6, +0xf8, 0x94, 0x87, 0x14, 0x90, 0xc9, 0x29, 0x09, +0xb2, 0x79, 0xb2, 0xd9, 0x9f, 0x7d, 0xd4, 0x5b, +0x06, 0x39, 0x51, 0x9d, 0x05, 0xfd, 0xfa, 0x8d, +0x18, 0x59, 0x44, 0x11, 0xa8, 0x17, 0x86, 0x52, +0x8b, 0x28, 0x51, 0x49, 0x1a, 0xf6, 0xf6, 0x08, +0x06, 0x24, 0x2a, 0x49, 0xc3, 0x7e, 0x3e, 0xbf, +0xaf, 0x36, 0x20, 0xc9, 0x34, 0x02, 0x07, 0xc1, +0x7c, 0x3e, 0x74, 0xa8, 0x3a, 0x19, 0x90, 0x0b, +0xf4, 0x2c, 0x70, 0x74, 0x44, 0xa8, 0x06, 0x0a, +0x45, 0x7a, 0xf9, 0x10, 0x0a, 0x93, 0x4e, 0xbf, +0x58, 0x62, 0x90, 0xf0, 0x31, 0x89, 0x94, 0xcb, +0x0c, 0x32, 0x7e, 0x4c, 0xb8, 0xfc, 0x27, 0x65, +0x99, 0x4e, 0x7c, 0xa7, 0x95, 0xb8, 0xfa, 0x89, +0x9d, 0xf9, 0xcf, 0x7d, 0x54, 0xc2, 0xcf, 0x2e, +0xae, 0xc6, 0x15, 0x0f, 0xf9, 0xe4, 0xec, 0xe2, +0xf2, 0x8a, 0xa7, 0xb7, 0x8b, 0xc8, 0xd2, 0x5a, +0xe5, 0x7a, 0x6b, 0x3b, 0x95, 0xc9, 0xdd, 0x88, +0x92, 0x24, 0xcb, 0x85, 0x62, 0xa9, 0xe2, 0xbf, +0xbc, 0xb8, 0xe5, 0x18, 0x4d, 0x29, 0xb2, 0x1e, +0xf8, 0x83, 0x89, 0xd2, 0xdf, 0xf3, 0xab, 0x5b, +0x46, 0x53, 0x7a, 0x55, 0xeb, 0xab, 0xa3, 0xc1, +0xde, 0xe1, 0xa4, 0x9e, 0x36, 0x7e, 0x87, 0xf5, +0xe4, 0xba, 0x86, 0x85, 0x13, 0x1b, 0x16, 0x0d, +0x8c, 0xa4, 0x06, 0x06, 0x5f, 0x03, 0xe3, 0xb5, +0x81, 0x21, 0xfe, 0xaf, 0xc6, 0x3d, 0x6d, 0x9d, +0x91, 0x34, 0x65, 0xd8, 0x6c, 0x2c, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_nested_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_nested_png = new wxImage(); + if (!img_ex_nested_png || !img_ex_nested_png->IsOk()) + { + wxMemoryInputStream img_ex_nested_pngIS(ex_nested_png_data, sizeof(ex_nested_png_data)); + img_ex_nested_png->LoadFile(img_ex_nested_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_nested_png; +} +#define ex_nested_png_img ex_nested_png_img() + +static wxBitmap *ex_nested_png_bmp() +{ + static wxBitmap *bmp_ex_nested_png; + if (!bmp_ex_nested_png || !bmp_ex_nested_png->IsOk()) + bmp_ex_nested_png = new wxBitmap(*ex_nested_png_img); + return bmp_ex_nested_png; +} +#define ex_nested_png_bmp ex_nested_png_bmp() + +static wxIcon *ex_nested_png_ico() +{ + static wxIcon *ico_ex_nested_png; + if (!ico_ex_nested_png || !ico_ex_nested_png->IsOk()) + { + ico_ex_nested_png = new wxIcon(); + ico_ex_nested_png->CopyFromBitmap(*ex_nested_png_bmp); + } + return ico_ex_nested_png; +} +#define ex_nested_png_ico ex_nested_png_ico() + +#endif // EX_NESTED_PNG_H diff --git a/include/images/ex_nested_loop_anti_join.png b/include/images/ex_nested_loop_anti_join.png new file mode 100644 index 0000000..c1c0763 Binary files /dev/null and b/include/images/ex_nested_loop_anti_join.png differ diff --git a/include/images/ex_nested_loop_anti_join.pngc b/include/images/ex_nested_loop_anti_join.pngc new file mode 100644 index 0000000..35cfc9f --- /dev/null +++ b/include/images/ex_nested_loop_anti_join.pngc @@ -0,0 +1,262 @@ +#ifndef EX_NESTED_LOOP_ANTI_JOIN_PNG_H +#define EX_NESTED_LOOP_ANTI_JOIN_PNG_H + +static const unsigned char ex_nested_loop_anti_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xea, 0xeb, 0xf9, 0xab, +0xae, 0xe6, 0x8b, 0x8e, 0xdc, 0x79, 0x7d, 0xd7, +0x66, 0x6b, 0xd1, 0xa2, 0xa5, 0xe4, 0xb7, 0xb8, +0xea, 0xbd, 0xbf, 0xec, 0xc5, 0xc6, 0xef, 0xc3, +0xc4, 0xef, 0xc4, 0xc5, 0xef, 0xc7, 0xc8, 0xef, +0xc8, 0xc9, 0xf0, 0xca, 0xcb, 0xf0, 0xcb, 0xcc, +0xf1, 0xcc, 0xcd, 0xf2, 0xce, 0xce, 0xf2, 0xcf, +0xd0, 0xf2, 0xd1, 0xd1, 0xf2, 0xd3, 0xd3, 0xf3, +0xd5, 0xd6, 0xf4, 0xcd, 0xcd, 0xf1, 0xc3, 0xc4, +0xee, 0xab, 0xad, 0xe6, 0xaf, 0xb2, 0xe8, 0xa8, +0xaa, 0xe6, 0xb9, 0xb9, 0xeb, 0xbe, 0xbf, 0xed, +0xb8, 0xb9, 0xec, 0xbf, 0xc0, 0xed, 0x89, 0xb9, +0xdb, 0x36, 0x88, 0xc1, 0xb5, 0xb7, 0xea, 0xb2, +0xb4, 0xe9, 0x92, 0x96, 0xdf, 0x74, 0x78, 0xd5, +0x75, 0x79, 0xd6, 0x98, 0x9b, 0xe1, 0xc0, 0xc1, +0xed, 0xb8, 0xba, 0xeb, 0xc4, 0xc5, 0xee, 0x6f, +0xcd, 0xee, 0x45, 0xbe, 0xe9, 0x4c, 0xc0, 0xe9, +0x53, 0xc2, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, +0xf0, 0x7a, 0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, +0xd4, 0xee, 0xad, 0xdf, 0xf3, 0xba, 0xbc, 0xeb, +0xac, 0xae, 0xe7, 0xc2, 0xc4, 0xed, 0xec, 0xed, +0xf9, 0x40, 0xbc, 0xe9, 0x07, 0xa8, 0xe2, 0x10, +0xab, 0xe2, 0x1a, 0xae, 0xe3, 0x5d, 0xc5, 0xeb, +0x71, 0xcb, 0xec, 0x4e, 0xbe, 0xe6, 0x5a, 0xc1, +0xe7, 0x64, 0xc5, 0xe8, 0x92, 0xd5, 0xef, 0xc0, +0xc1, 0xee, 0xbd, 0xbf, 0xed, 0x73, 0x78, 0xd5, +0x75, 0x7a, 0xd6, 0xc9, 0xca, 0xf0, 0xd9, 0xd9, +0xf5, 0xd6, 0xd6, 0xf4, 0xd7, 0xd7, 0xf5, 0xa9, +0xa0, 0x7a, 0xc1, 0x8f, 0x36, 0xa1, 0x8e, 0x77, +0x74, 0x8b, 0xd5, 0xef, 0xee, 0xdf, 0xc0, 0xba, +0x81, 0xa8, 0x9f, 0x50, 0x9b, 0x90, 0x35, 0x8d, +0x81, 0x19, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, +0xcc, 0xcd, 0xf1, 0xc6, 0xc7, 0xef, 0xcd, 0xce, +0xf2, 0xde, 0xde, 0xf6, 0xc2, 0xc2, 0x76, 0xd5, +0xdb, 0x94, 0xde, 0xe7, 0x9a, 0xe6, 0xf4, 0xa6, +0xe7, 0xf4, 0xa9, 0xd5, 0xd9, 0x91, 0xc2, 0xc1, +0x75, 0xeb, 0xe6, 0x9f, 0xbc, 0xbd, 0xec, 0xab, +0xac, 0xe8, 0xb3, 0xb4, 0xea, 0xbc, 0xbd, 0xed, +0xd4, 0xd4, 0xf3, 0xd3, 0xd9, 0x8b, 0xce, 0xd5, +0x80, 0xd3, 0xdc, 0x86, 0xe3, 0xf2, 0x9d, 0xe2, +0xf0, 0x9a, 0xcc, 0xd3, 0x7a, 0xd1, 0xd6, 0x89, +0xc1, 0xc0, 0x74, 0xcd, 0xce, 0xf1, 0xce, 0xcf, +0xf1, 0xcd, 0xd5, 0x7c, 0xd4, 0xda, 0x8d, 0xb4, +0xb0, 0x5c, 0xa3, 0x9c, 0x3f, 0xca, 0xd1, 0x79, +0xd3, 0xd5, 0x8d, 0xa5, 0xa8, 0xe4, 0xe4, 0xf3, +0x9c, 0xd1, 0xcd, 0xa3, 0xe5, 0xe2, 0xcb, 0xb3, +0xaf, 0x5b, 0xdf, 0xea, 0x95, 0xe2, 0xea, 0xa1, +0xe6, 0xf4, 0xa3, 0x99, 0x8f, 0x2d, 0xf1, 0xf0, +0xe3, 0xe0, 0xe9, 0x99, 0xdb, 0xbd, 0x89, 0xb5, +0x99, 0x7e, 0xe5, 0xf3, 0xa2, 0xe4, 0xf1, 0xa0, +0xdf, 0xe8, 0x98, 0xe4, 0xf2, 0xa1, 0xdd, 0xe5, +0x96, 0xeb, 0xf4, 0xb7, 0xdd, 0xe3, 0x95, 0xf0, +0xec, 0xb6, 0xbf, 0x86, 0x31, 0xb7, 0x84, 0x80, +0xb0, 0x5e, 0x3e, 0xb3, 0x4b, 0x13, 0xb5, 0x62, +0x3f, 0xc4, 0x90, 0x84, 0x70, 0x66, 0xb8, 0xbc, +0xb5, 0x78, 0xdb, 0xe1, 0x93, 0xde, 0xea, 0xd4, +0x97, 0xbb, 0x75, 0xba, 0xd1, 0xa3, 0xeb, 0xe5, +0x9e, 0xea, 0xe4, 0x9d, 0xe7, 0xd5, 0x9f, 0xb7, +0x60, 0x1b, 0xc9, 0x4d, 0x1a, 0xd7, 0x51, 0x22, +0xe1, 0x54, 0x27, 0x97, 0x54, 0x52, 0xf5, 0xe8, +0xe1, 0xc2, 0xc3, 0xee, 0xad, 0xaf, 0xe9, 0xc5, +0xc5, 0xef, 0xda, 0xdf, 0x92, 0x81, 0xae, 0x42, +0x73, 0xa5, 0x37, 0x99, 0xbc, 0x78, 0xef, 0xeb, +0xb6, 0xef, 0xe8, 0xb3, 0xd3, 0x9c, 0x6c, 0xe2, +0x54, 0x28, 0xff, 0xff, 0xff, 0xda, 0xa6, 0x8a, +0xbc, 0xbe, 0xec, 0xd9, 0xdd, 0x90, 0xa7, 0xcf, +0x67, 0x76, 0xab, 0x3b, 0xb5, 0x57, 0x16, 0xc3, +0x70, 0x43, 0xd8, 0xdc, 0x8f, 0xb0, 0xdd, 0x74, +0x52, 0x8d, 0x19, 0xf3, 0xed, 0xc6, 0xee, 0xe6, +0xb2, 0xed, 0xe5, 0xb1, 0xec, 0xe2, 0xaf, 0xd7, +0xda, 0x8d, 0xb2, 0xe0, 0x76, 0x7a, 0xb1, 0x41, +0xe6, 0xd9, 0x95, 0xe5, 0xd6, 0x92, 0xe4, 0xd3, +0x90, 0xbf, 0x68, 0x30, 0xe4, 0xea, 0xa9, 0xd7, +0xd8, 0x8c, 0x8c, 0xc0, 0x52, 0xe3, 0xd2, 0x8f, +0xe2, 0xce, 0x8c, 0xce, 0x92, 0x5d, 0xd5, 0xde, +0x7c, 0xd4, 0xdc, 0x7a, 0xde, 0xe4, 0x9c, 0xd6, +0xd7, 0x8a, 0xeb, 0xde, 0xac, 0xe2, 0xd0, 0x8d, +0xe1, 0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe0, 0xc3, +0x92, 0xe9, 0xef, 0xba, 0xd2, 0xda, 0x78, 0xe6, +0xe9, 0xb5, 0xd5, 0xd5, 0x89, 0xef, 0xe3, 0xbe, +0xe8, 0xd8, 0xa7, 0xe7, 0xd5, 0xa5, 0xec, 0xde, +0xba, 0xbf, 0x8c, 0x83, 0xb8, 0x65, 0x40, 0xc9, +0x95, 0x86, 0xd8, 0xdf, 0x8a, 0xd7, 0xdc, 0x88, +0xd4, 0xd4, 0x8b, 0xd4, 0xd3, 0x87, 0xe5, 0xd0, +0xa1, 0xe4, 0xce, 0x9f, 0xeb, 0xd9, 0xb6, 0xd8, +0xdb, 0x8d, 0xd3, 0xd2, 0x86, 0xdc, 0xbe, 0x80, +0xdb, 0xbc, 0x7e, 0xda, 0xbb, 0x7e, 0xe3, 0xcb, +0x9e, 0xd9, 0xdd, 0x93, 0x98, 0x8d, 0x2c, 0xda, +0xba, 0x7d, 0xc7, 0xc6, 0x74, 0xb0, 0xa9, 0x56, +0xaf, 0xa7, 0x55, 0xc5, 0xc2, 0x70, 0xd0, 0xcd, +0x88, 0xcd, 0xcb, 0x87, 0xc3, 0xc0, 0x6e, 0xc9, +0xc6, 0x7e, 0xa0, 0x97, 0x3b, 0xc8, 0xc5, 0x7a, +0xc2, 0xbe, 0x6c, 0xcb, 0xc8, 0x84, 0xea, 0xd8, +0xb6, 0xbc, 0xb7, 0x6c, 0xd0, 0xcf, 0x7f, 0xcf, +0xce, 0x7c, 0xbf, 0xbb, 0x68, 0xc7, 0xc3, 0x78, +0xd6, 0xd5, 0x8e, 0xca, 0xc6, 0x80, 0xd5, 0xd5, +0xf4, 0x26, 0xf3, 0x51, 0x9f, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0xab, 0xc9, 0x01, 0x67, 0x28, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0xf7, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, +0x18, 0xf1, 0x80, 0x91, 0x89, 0x99, 0x85, 0x15, +0x05, 0xb0, 0x30, 0x33, 0x31, 0xe2, 0xd7, 0xc1, +0xc6, 0xce, 0xc1, 0xc9, 0xc5, 0xcd, 0xc9, 0xc3, +0xcb, 0xc7, 0x2f, 0x20, 0x28, 0x24, 0x2c, 0x22, +0x2a, 0x26, 0x2e, 0x81, 0x57, 0x0f, 0x13, 0x9b, +0xa4, 0x94, 0xa4, 0x34, 0xb2, 0x16, 0x1e, 0x19, +0x59, 0x39, 0x09, 0x26, 0xb8, 0x02, 0x79, 0x05, +0x10, 0x80, 0x92, 0x60, 0x11, 0x66, 0x45, 0x29, +0x25, 0x65, 0x15, 0x64, 0x77, 0xa9, 0xaa, 0xa9, +0x6b, 0x68, 0x32, 0xc3, 0xb5, 0x28, 0x68, 0x69, +0xeb, 0xe8, 0xea, 0x29, 0xe8, 0x1b, 0x18, 0x1a, +0x19, 0x2b, 0x80, 0x45, 0x58, 0x4c, 0x4c, 0x95, +0xcd, 0xcc, 0x91, 0xed, 0x35, 0x37, 0x53, 0x93, +0x13, 0x64, 0x41, 0x68, 0xb1, 0xb0, 0xb4, 0xb2, +0xb6, 0x51, 0xb0, 0xb5, 0xb3, 0x77, 0x70, 0x84, +0x68, 0x61, 0x75, 0x72, 0x76, 0x31, 0x47, 0x75, +0xab, 0xb9, 0xab, 0x9b, 0x3b, 0x2b, 0x1e, 0x5b, +0x58, 0x9d, 0x9d, 0x59, 0x19, 0xd0, 0x00, 0xab, +0x87, 0x27, 0x42, 0xcc, 0xcb, 0x1b, 0x04, 0x7c, +0xc0, 0x6e, 0xf6, 0x85, 0x6a, 0x91, 0x01, 0x4b, +0xfb, 0xf9, 0x07, 0x04, 0x06, 0x05, 0x05, 0xf8, +0xfb, 0xa1, 0x6b, 0xf1, 0x0e, 0x0e, 0x09, 0x09, +0x09, 0xf6, 0x0e, 0x75, 0x0a, 0x0b, 0x8f, 0x60, +0x45, 0xd6, 0xe2, 0xe7, 0x1f, 0x19, 0x15, 0x1d, +0x13, 0x1b, 0x17, 0x0f, 0xd2, 0x83, 0xaa, 0x25, +0x24, 0x21, 0x21, 0x21, 0xc4, 0x3b, 0x31, 0x29, +0x39, 0x25, 0x15, 0x45, 0x8b, 0x7f, 0x64, 0x5a, +0x7a, 0x46, 0x66, 0x56, 0x76, 0x4e, 0xae, 0x3f, +0x61, 0x2d, 0x79, 0xf9, 0x20, 0x46, 0x40, 0x5c, +0x41, 0x61, 0x51, 0x71, 0x51, 0x4e, 0x49, 0x69, +0x00, 0x41, 0x2d, 0x65, 0xac, 0xac, 0x65, 0x40, +0x2a, 0x28, 0xb6, 0xbc, 0xa8, 0xa2, 0xb2, 0xa2, +0xaa, 0xba, 0x26, 0x88, 0xa0, 0x5f, 0xa0, 0x20, +0xa8, 0x36, 0xb3, 0xae, 0x9e, 0xa1, 0xbe, 0xae, +0xba, 0x01, 0x5d, 0x4b, 0x23, 0x38, 0xc4, 0x9a, +0xc0, 0x21, 0x56, 0x86, 0xa2, 0xa5, 0xb9, 0x25, +0x08, 0x44, 0xb5, 0x46, 0x13, 0x6f, 0x4b, 0x1b, +0x44, 0x4b, 0x74, 0x7b, 0x10, 0xd1, 0x7e, 0xe9, +0xe8, 0x00, 0x6b, 0x69, 0xef, 0xc4, 0xaa, 0xa5, +0xab, 0xbb, 0xa7, 0xb7, 0xaf, 0x7f, 0xc2, 0x44, +0x88, 0x0e, 0x5e, 0x37, 0x90, 0x9e, 0x49, 0x41, +0x41, 0x93, 0x40, 0x5a, 0x3a, 0x27, 0xc3, 0xb5, +0x4c, 0x99, 0x3a, 0x0d, 0xaa, 0x65, 0xfa, 0x8c, +0x99, 0xb3, 0x66, 0xcf, 0x99, 0x3b, 0x67, 0xf6, +0xbc, 0xf9, 0x20, 0x1d, 0x0b, 0x16, 0x2e, 0x5c, +0x84, 0xf0, 0x56, 0xd0, 0xe4, 0xc5, 0x70, 0x2d, +0x53, 0x97, 0x2c, 0x5d, 0x06, 0xf6, 0xcb, 0xf2, +0xe5, 0x2b, 0x56, 0xce, 0x5e, 0xb5, 0x6a, 0xf5, +0xea, 0x55, 0xb3, 0xd7, 0x00, 0x25, 0x45, 0xd6, +0x2e, 0x5c, 0x28, 0x27, 0x0a, 0x77, 0x46, 0xd0, +0xe2, 0x75, 0x70, 0x2d, 0xd3, 0x96, 0xae, 0xdf, +0xb0, 0x0c, 0x1a, 0x62, 0x1b, 0xe7, 0xac, 0x02, +0xe9, 0x99, 0xb3, 0x09, 0xec, 0x13, 0x59, 0x0d, +0xa4, 0xc0, 0x0b, 0x5a, 0xb7, 0x19, 0xe1, 0x97, +0x65, 0x1b, 0xb6, 0x6c, 0x05, 0xda, 0xb2, 0x6d, +0xfb, 0x8e, 0x9d, 0x7d, 0x73, 0x57, 0x83, 0xf4, +0xcc, 0xed, 0x43, 0x4a, 0x30, 0x30, 0xbf, 0x6c, +0xde, 0x85, 0xb0, 0x65, 0xc3, 0xee, 0x3d, 0x40, +0x5b, 0xbc, 0x77, 0xec, 0xdd, 0xb7, 0xff, 0xc0, +0x9c, 0xd5, 0x20, 0x3d, 0x20, 0x5b, 0x60, 0x5a, +0x26, 0x05, 0x1d, 0x3c, 0x08, 0xd2, 0x13, 0xb4, +0xeb, 0x10, 0xc2, 0x2f, 0x87, 0xf7, 0x80, 0xfd, +0xb2, 0x73, 0xdf, 0x91, 0xa3, 0xc7, 0x66, 0x83, +0xbc, 0x02, 0xf6, 0x0b, 0x54, 0xcb, 0xa4, 0xa0, +0x9a, 0xe3, 0x27, 0x4e, 0x02, 0xf5, 0x04, 0x1d, +0x3a, 0x85, 0x11, 0x62, 0xa7, 0xcf, 0x9c, 0x3d, +0x77, 0x1e, 0x11, 0x62, 0x50, 0x2d, 0x41, 0x17, +0xda, 0x4f, 0x5c, 0x5c, 0x7c, 0x29, 0x88, 0x21, +0xe8, 0xd4, 0x65, 0x8c, 0x78, 0xb9, 0x72, 0xf5, +0xda, 0xb5, 0xeb, 0xdd, 0x37, 0xfa, 0xfb, 0x6e, +0xde, 0x9a, 0xc8, 0x80, 0x64, 0x4b, 0xd0, 0xed, +0x3b, 0x20, 0xdf, 0x04, 0x5d, 0xbe, 0x4b, 0x38, +0x8d, 0x41, 0xbd, 0x0f, 0x09, 0x5d, 0x86, 0xa0, +0xbb, 0xf7, 0x30, 0x6c, 0xb9, 0x7e, 0xff, 0xfe, +0x83, 0x87, 0x58, 0x72, 0x65, 0xd0, 0xba, 0x47, +0x60, 0x2d, 0x8f, 0x1f, 0x63, 0x68, 0xb9, 0xff, +0xe4, 0xe9, 0xb3, 0xe7, 0x58, 0x72, 0x65, 0xd0, +0x8b, 0x43, 0x2f, 0x81, 0x89, 0xff, 0xe5, 0x63, +0x0c, 0x87, 0x79, 0x3f, 0x78, 0xf6, 0xea, 0x15, +0x36, 0x2d, 0x81, 0xa5, 0xaf, 0xdf, 0x00, 0xb3, +0xd8, 0xdb, 0x77, 0xef, 0x03, 0xd1, 0xb5, 0x3c, +0x7f, 0x85, 0x5d, 0x4b, 0xc0, 0x87, 0x8f, 0x9f, +0xde, 0x7e, 0x7e, 0xfb, 0xe5, 0xeb, 0x37, 0x8c, +0x8c, 0xfc, 0xfd, 0xf9, 0xf3, 0xe7, 0xdf, 0xb1, +0xf8, 0xc5, 0xff, 0xc7, 0x97, 0xaf, 0xef, 0x7e, +0xfe, 0xfa, 0xfd, 0xe7, 0x87, 0x3f, 0xb1, 0x21, +0xe6, 0xe7, 0xff, 0xe3, 0xdb, 0xfb, 0xbb, 0x7f, +0xff, 0xfd, 0xc0, 0x2c, 0x94, 0x70, 0xd9, 0x82, +0xa7, 0xe8, 0xc3, 0xe2, 0x17, 0x2c, 0x05, 0xec, +0x7f, 0xfc, 0x5a, 0xb0, 0x15, 0xe3, 0xff, 0xdd, +0xf1, 0x69, 0xc1, 0x5a, 0x59, 0xc8, 0x20, 0x55, +0x16, 0x98, 0x7e, 0x21, 0x58, 0x25, 0x61, 0x86, +0x18, 0xc1, 0x8a, 0x0f, 0x13, 0x90, 0x51, 0xbd, +0x92, 0x51, 0x89, 0x8f, 0x64, 0x00, 0x00, 0xfa, +0x07, 0x8b, 0x87, 0x52, 0x14, 0x6c, 0xcd, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_nested_loop_anti_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_nested_loop_anti_join_png = new wxImage(); + if (!img_ex_nested_loop_anti_join_png || !img_ex_nested_loop_anti_join_png->IsOk()) + { + wxMemoryInputStream img_ex_nested_loop_anti_join_pngIS(ex_nested_loop_anti_join_png_data, sizeof(ex_nested_loop_anti_join_png_data)); + img_ex_nested_loop_anti_join_png->LoadFile(img_ex_nested_loop_anti_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_nested_loop_anti_join_png; +} +#define ex_nested_loop_anti_join_png_img ex_nested_loop_anti_join_png_img() + +static wxBitmap *ex_nested_loop_anti_join_png_bmp() +{ + static wxBitmap *bmp_ex_nested_loop_anti_join_png; + if (!bmp_ex_nested_loop_anti_join_png || !bmp_ex_nested_loop_anti_join_png->IsOk()) + bmp_ex_nested_loop_anti_join_png = new wxBitmap(*ex_nested_loop_anti_join_png_img); + return bmp_ex_nested_loop_anti_join_png; +} +#define ex_nested_loop_anti_join_png_bmp ex_nested_loop_anti_join_png_bmp() + +static wxIcon *ex_nested_loop_anti_join_png_ico() +{ + static wxIcon *ico_ex_nested_loop_anti_join_png; + if (!ico_ex_nested_loop_anti_join_png || !ico_ex_nested_loop_anti_join_png->IsOk()) + { + ico_ex_nested_loop_anti_join_png = new wxIcon(); + ico_ex_nested_loop_anti_join_png->CopyFromBitmap(*ex_nested_loop_anti_join_png_bmp); + } + return ico_ex_nested_loop_anti_join_png; +} +#define ex_nested_loop_anti_join_png_ico ex_nested_loop_anti_join_png_ico() + +#endif // EX_NESTED_LOOP_ANTI_JOIN_PNG_H diff --git a/include/images/ex_nested_loop_semi_join.png b/include/images/ex_nested_loop_semi_join.png new file mode 100644 index 0000000..d0e8a17 Binary files /dev/null and b/include/images/ex_nested_loop_semi_join.png differ diff --git a/include/images/ex_nested_loop_semi_join.pngc b/include/images/ex_nested_loop_semi_join.pngc new file mode 100644 index 0000000..abcbf7c --- /dev/null +++ b/include/images/ex_nested_loop_semi_join.pngc @@ -0,0 +1,254 @@ +#ifndef EX_NESTED_LOOP_SEMI_JOIN_PNG_H +#define EX_NESTED_LOOP_SEMI_JOIN_PNG_H + +static const unsigned char ex_nested_loop_semi_join_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xea, 0xeb, 0xf9, 0xab, +0xae, 0xe6, 0x8b, 0x8e, 0xdc, 0x79, 0x7d, 0xd7, +0x66, 0x6b, 0xd1, 0xa2, 0xa5, 0xe4, 0xb7, 0xb8, +0xea, 0xbd, 0xbf, 0xec, 0xc5, 0xc6, 0xef, 0xc3, +0xc4, 0xef, 0xc4, 0xc5, 0xef, 0xc7, 0xc8, 0xef, +0xc8, 0xc9, 0xf0, 0xca, 0xcb, 0xf0, 0xcb, 0xcc, +0xf1, 0xcc, 0xcd, 0xf2, 0xce, 0xce, 0xf2, 0xcf, +0xd0, 0xf2, 0xd1, 0xd1, 0xf2, 0xd3, 0xd3, 0xf3, +0xd5, 0xd6, 0xf4, 0xcd, 0xcd, 0xf1, 0xc3, 0xc4, +0xee, 0xab, 0xad, 0xe6, 0xaf, 0xb2, 0xe8, 0xa8, +0xaa, 0xe6, 0xb9, 0xb9, 0xea, 0xbe, 0xbf, 0xed, +0xb8, 0xb9, 0xeb, 0xbf, 0xc0, 0xec, 0x89, 0xb9, +0xdb, 0x36, 0x88, 0xc1, 0x70, 0xab, 0xd3, 0x9a, +0xc3, 0xe0, 0xc4, 0xdc, 0xed, 0xb5, 0xb7, 0xea, +0xb2, 0xb4, 0xe9, 0x92, 0x96, 0xdf, 0x74, 0x78, +0xd5, 0x75, 0x79, 0xd6, 0x98, 0x9b, 0xe1, 0xc0, +0xc1, 0xed, 0xb8, 0xba, 0xeb, 0xc4, 0xc5, 0xee, +0x6f, 0xcd, 0xee, 0x4d, 0xc0, 0xe9, 0x61, 0xc6, +0xeb, 0x76, 0xcd, 0xec, 0xa6, 0xde, 0xf2, 0xb7, +0xe6, 0xf6, 0xa6, 0xdf, 0xf4, 0xb0, 0xe2, 0xf5, +0xba, 0xe6, 0xf5, 0xd2, 0xee, 0xf8, 0xba, 0xbc, +0xeb, 0xac, 0xae, 0xe7, 0xc2, 0xc4, 0xed, 0xec, +0xed, 0xf9, 0xbf, 0xc0, 0xed, 0x40, 0xbc, 0xe9, +0x12, 0xab, 0xe2, 0x2c, 0xb3, 0xe4, 0x48, 0xbc, +0xe6, 0x89, 0xd3, 0xee, 0x9f, 0xdd, 0xf4, 0x88, +0xd5, 0xf0, 0x95, 0xd9, 0xf1, 0xa3, 0xdd, 0xf2, +0xc4, 0xe9, 0xf6, 0xc0, 0xc1, 0xee, 0xbd, 0xbf, +0xed, 0x73, 0x78, 0xd5, 0x75, 0x7a, 0xd6, 0xc9, +0xca, 0xf0, 0xd9, 0xd9, 0xf5, 0xd6, 0xd6, 0xf4, +0xd7, 0xd7, 0xf5, 0xa9, 0xa0, 0x7a, 0xc1, 0x8f, +0x36, 0x9e, 0x93, 0x76, 0xb2, 0xb5, 0xe8, 0xa8, +0xbb, 0xe4, 0xef, 0xee, 0xdf, 0xc0, 0xba, 0x81, +0xa8, 0x9f, 0x50, 0x9b, 0x90, 0x35, 0x8d, 0x81, +0x19, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, 0xe5, +0xe6, 0xf8, 0xdf, 0xe0, 0xf6, 0xe2, 0xe3, 0xf7, +0xe6, 0xe6, 0xf8, 0xee, 0xee, 0xfa, 0xc2, 0xc2, +0x76, 0xd5, 0xdb, 0x94, 0xde, 0xe7, 0x9d, 0xe6, +0xf4, 0xa6, 0xe7, 0xf4, 0xa9, 0xd4, 0xd8, 0x90, +0xc2, 0xc1, 0x75, 0xeb, 0xe6, 0x9f, 0xdd, 0xde, +0xf5, 0xd5, 0xd5, 0xf3, 0xd9, 0xd9, 0xf4, 0xdd, +0xde, 0xf6, 0xe9, 0xe9, 0xf9, 0xd3, 0xd9, 0x8b, +0xce, 0xd5, 0x80, 0xd3, 0xdc, 0x86, 0xe3, 0xf2, +0x9d, 0xe2, 0xf0, 0x9a, 0xcc, 0xd3, 0x7a, 0xd1, +0xd6, 0x89, 0xc1, 0xc0, 0x74, 0xcd, 0xce, 0xf1, +0xce, 0xcf, 0xf1, 0xd5, 0xda, 0x91, 0xcd, 0xd5, +0x7c, 0xd4, 0xda, 0x8d, 0xb4, 0xb0, 0x5c, 0xa3, +0x9c, 0x3f, 0xca, 0xd1, 0x79, 0xd3, 0xd5, 0x8d, +0xa5, 0xa8, 0xe4, 0xe4, 0xf3, 0x9c, 0xd1, 0xcd, +0xa3, 0xe5, 0xe2, 0xcb, 0xb3, 0xaf, 0x5b, 0xdf, +0xeb, 0x94, 0xe2, 0xeb, 0xa1, 0xe6, 0xf4, 0xa3, +0x99, 0x8f, 0x2d, 0xf1, 0xf0, 0xe3, 0xdf, 0xe9, +0x95, 0xe0, 0xe9, 0x99, 0xdb, 0xbd, 0x89, 0xc8, +0xab, 0x83, 0xd2, 0xd3, 0xf1, 0xe5, 0xf3, 0xa2, +0xe4, 0xf1, 0xa0, 0xdf, 0xe8, 0x98, 0xde, 0xe7, +0x98, 0xe4, 0xf2, 0xa1, 0xdd, 0xe5, 0x96, 0xeb, +0xf4, 0xb7, 0xdd, 0xe3, 0x95, 0xf0, 0xec, 0xb6, +0xbc, 0xb5, 0x78, 0xdb, 0xe1, 0x93, 0xde, 0xea, +0xd4, 0x97, 0xbb, 0x75, 0xba, 0xd1, 0xa3, 0xeb, +0xe5, 0x9e, 0xea, 0xe4, 0x9d, 0xef, 0xe9, 0xb4, +0xc2, 0xc3, 0xee, 0xad, 0xaf, 0xe9, 0xc5, 0xc5, +0xef, 0xda, 0xdf, 0x92, 0x81, 0xae, 0x42, 0x73, +0xa5, 0x37, 0x99, 0xbc, 0x78, 0xef, 0xeb, 0xb6, +0xef, 0xea, 0xb5, 0xef, 0xe8, 0xb3, 0xf3, 0xed, +0xc6, 0xbc, 0xbe, 0xec, 0xd9, 0xdd, 0x90, 0xa7, +0xcf, 0x67, 0x76, 0xab, 0x3b, 0xb8, 0xb9, 0xec, +0xd8, 0xdc, 0x8f, 0xb0, 0xdd, 0x74, 0x52, 0x8d, +0x19, 0xee, 0xe6, 0xb2, 0xed, 0xe5, 0xb1, 0xec, +0xe2, 0xaf, 0xf0, 0xe7, 0xc1, 0xd7, 0xda, 0x8d, +0xb2, 0xe0, 0x76, 0x7a, 0xb1, 0x41, 0xe6, 0xd9, +0x95, 0xe5, 0xd6, 0x93, 0xe4, 0xd3, 0x90, 0xea, +0xdc, 0xaa, 0xe4, 0xeb, 0xa9, 0xe3, 0xe9, 0xa8, +0xd7, 0xd8, 0x8c, 0x8c, 0xc0, 0x52, 0xe4, 0xd5, +0x91, 0xe3, 0xd2, 0x8f, 0xe2, 0xce, 0x8c, 0xe9, +0xd8, 0xa7, 0xe1, 0xe9, 0xa0, 0xd5, 0xde, 0x7c, +0xd4, 0xdc, 0x7a, 0xde, 0xe4, 0x9c, 0xd6, 0xd7, +0x8a, 0xeb, 0xde, 0xac, 0xe2, 0xd0, 0x8d, 0xe1, +0xcd, 0x8b, 0xe0, 0xca, 0x89, 0xe7, 0xd6, 0xa5, +0xe9, 0xef, 0xba, 0xd2, 0xda, 0x78, 0xe6, 0xe9, +0xb5, 0xd5, 0xd5, 0x89, 0xef, 0xe3, 0xbe, 0xe6, +0xd4, 0xa4, 0xec, 0xde, 0xba, 0xd8, 0xdf, 0x8a, +0xd7, 0xdc, 0x88, 0xd4, 0xd4, 0x89, 0xd4, 0xd3, +0x87, 0xe6, 0xd1, 0xa2, 0xe5, 0xd0, 0xa1, 0xe4, +0xce, 0x9f, 0xeb, 0xd9, 0xb6, 0xd8, 0xdb, 0x8d, +0xd3, 0xd2, 0x86, 0xdc, 0xbe, 0x80, 0xdb, 0xbc, +0x7e, 0xda, 0xbb, 0x7d, 0xe3, 0xcb, 0x9e, 0xd9, +0xdd, 0x93, 0x98, 0x8d, 0x2c, 0x97, 0x8d, 0x2b, +0xd4, 0xd4, 0x8b, 0xda, 0xbb, 0x7e, 0xda, 0xba, +0x7d, 0xc7, 0xc6, 0x74, 0xb0, 0xa9, 0x56, 0xaf, +0xa7, 0x55, 0xc5, 0xc2, 0x70, 0xd0, 0xcd, 0x88, +0xcd, 0xcb, 0x87, 0xc3, 0xc0, 0x6e, 0xc9, 0xc6, +0x7e, 0xa0, 0x97, 0x3b, 0xc8, 0xc5, 0x7a, 0xc1, +0xbd, 0x6b, 0xcb, 0xc8, 0x84, 0xea, 0xd8, 0xb6, +0xbd, 0xb7, 0x6c, 0xc2, 0xbf, 0x6d, 0xd0, 0xcf, +0x7f, 0xcf, 0xce, 0x7c, 0xbf, 0xbb, 0x68, 0xc7, +0xc3, 0x78, 0xbc, 0xb6, 0x6b, 0xd6, 0xd5, 0x8e, +0xca, 0xc6, 0x80, 0xd5, 0xd5, 0xf4, 0xd8, 0xd8, +0xf5, 0xdc, 0x7c, 0xd9, 0x75, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0x63, 0x60, 0x18, 0x05, 0x8c, 0x4c, 0xcc, +0x2c, 0xac, 0x28, 0x80, 0x85, 0x99, 0x89, 0x11, +0xbf, 0x0e, 0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, +0x4e, 0x1e, 0x5e, 0x3e, 0x7e, 0x01, 0x41, 0x21, +0x61, 0x11, 0x51, 0x31, 0x71, 0x09, 0xbc, 0x7a, +0x98, 0xd8, 0x24, 0xa5, 0x24, 0xa5, 0x91, 0xb5, +0xf0, 0xc8, 0xc8, 0xca, 0x49, 0x30, 0xc1, 0x15, +0xc8, 0x2b, 0x80, 0x80, 0xa2, 0x12, 0x08, 0x28, +0x83, 0x45, 0x98, 0x55, 0xa4, 0x54, 0xd5, 0xd4, +0x91, 0xdd, 0xa5, 0xa1, 0xa9, 0xa5, 0xad, 0xc3, +0x0c, 0xd7, 0xa2, 0xa0, 0xab, 0xa7, 0x6f, 0x60, +0xa8, 0x60, 0x64, 0x6c, 0x62, 0x6a, 0xa6, 0x04, +0x16, 0x61, 0x31, 0xb7, 0x50, 0xb3, 0xb4, 0x42, +0xb6, 0xd7, 0xca, 0x52, 0xd3, 0x5a, 0x90, 0x05, +0xa1, 0xc5, 0xc6, 0xd6, 0xce, 0xde, 0x41, 0xc1, +0xd1, 0xc9, 0xd9, 0xc5, 0x15, 0xa2, 0x85, 0xd5, +0xcd, 0xdd, 0xc3, 0x0a, 0xd5, 0xad, 0x56, 0x9e, +0x5e, 0xde, 0xac, 0x78, 0x6c, 0x61, 0x75, 0x77, +0x67, 0x65, 0x40, 0x03, 0xac, 0x3e, 0xbe, 0x08, +0x31, 0x3f, 0x7f, 0x10, 0x08, 0x08, 0x04, 0x81, +0x20, 0xa8, 0x16, 0x19, 0xb0, 0x74, 0x70, 0x48, +0x68, 0x58, 0x78, 0x78, 0x68, 0x48, 0x30, 0xba, +0x16, 0xff, 0x88, 0xc8, 0xc8, 0xc8, 0x08, 0xff, +0xa8, 0xe8, 0x98, 0xd8, 0xb8, 0x40, 0x64, 0x2d, +0xc1, 0x21, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, +0xa9, 0x20, 0x3d, 0xa8, 0x5a, 0x22, 0xd3, 0xd2, +0xd2, 0x22, 0xfd, 0xd3, 0x33, 0x32, 0xb3, 0xb2, +0x51, 0xb4, 0x84, 0xc4, 0xe7, 0xe4, 0xe6, 0xe5, +0x17, 0x14, 0x16, 0x15, 0x87, 0x10, 0xd6, 0x52, +0x52, 0x0a, 0x92, 0x0e, 0x2d, 0x2b, 0xaf, 0xa8, +0xac, 0xaa, 0x2c, 0xaa, 0xae, 0x09, 0x25, 0xa8, +0xa5, 0x96, 0x95, 0xb5, 0x16, 0x48, 0x85, 0x27, +0xd7, 0x55, 0xd6, 0x37, 0xd4, 0x37, 0x36, 0x35, +0x87, 0x13, 0xf4, 0x0b, 0x14, 0x84, 0xb7, 0xe4, +0xb7, 0xb6, 0x31, 0xb4, 0xb5, 0xb6, 0x77, 0xa0, +0x6b, 0xe9, 0x04, 0x87, 0x58, 0x17, 0x38, 0xc4, +0xba, 0x51, 0xb4, 0xf4, 0xf4, 0x86, 0x83, 0xa8, +0xbe, 0x7e, 0xe2, 0x6d, 0x99, 0x00, 0xd1, 0xd2, +0x3f, 0x31, 0x9c, 0x68, 0xbf, 0x4c, 0x9a, 0x04, +0xd6, 0x32, 0x71, 0x32, 0x56, 0x2d, 0x53, 0x90, +0xb4, 0xd4, 0xb2, 0xf2, 0x7a, 0x81, 0xf4, 0x4c, +0x0d, 0x0f, 0x9f, 0x0a, 0xd2, 0x32, 0x79, 0x1a, +0x5c, 0xcb, 0xf4, 0x19, 0x33, 0xa1, 0x5a, 0x66, +0xcd, 0x9e, 0x83, 0xd0, 0x52, 0xcb, 0x3a, 0x77, +0xde, 0xbc, 0xf9, 0x60, 0x7b, 0x20, 0xee, 0x9b, +0xb6, 0x00, 0xae, 0x65, 0xc6, 0xc2, 0x45, 0x8b, +0xc1, 0x7e, 0x59, 0xb2, 0x74, 0xd9, 0x72, 0x84, +0x5f, 0x58, 0x45, 0x56, 0xcc, 0x9b, 0x67, 0x2d, +0x0a, 0x77, 0x46, 0xf8, 0x82, 0x95, 0x70, 0x2d, +0x33, 0x17, 0xad, 0x5a, 0xbd, 0x18, 0x33, 0xc4, +0x80, 0x3e, 0x59, 0xa3, 0xcd, 0x8a, 0x64, 0xcb, +0xca, 0xb5, 0x08, 0xbf, 0x2c, 0x5e, 0xbd, 0x6e, +0x3d, 0xd0, 0x96, 0xe5, 0x1b, 0x36, 0x6e, 0xda, +0x8c, 0x25, 0x8d, 0xc1, 0xfc, 0xb2, 0x76, 0x0b, +0xc2, 0x96, 0xd5, 0x5b, 0xb7, 0x01, 0x6d, 0xf1, +0xdf, 0xb8, 0x7d, 0xc7, 0xce, 0x5d, 0x98, 0x69, +0x6c, 0x6a, 0xf8, 0xee, 0x3d, 0x20, 0x3d, 0xe1, +0x5b, 0xf6, 0x22, 0xfc, 0xb2, 0x6f, 0x1b, 0xd8, +0x2f, 0x9b, 0xf6, 0x1f, 0x38, 0x78, 0x08, 0x43, +0xcb, 0xd4, 0xf0, 0xc3, 0x47, 0x8e, 0x1e, 0x03, +0xea, 0x09, 0xdf, 0x7b, 0x1c, 0x23, 0xc4, 0x4e, +0x9c, 0x3c, 0x75, 0xfa, 0x0c, 0x86, 0x96, 0xf0, +0xb3, 0x13, 0x8f, 0x9e, 0x5b, 0x70, 0x3e, 0x9c, +0x21, 0xfc, 0xf8, 0x05, 0x8c, 0x78, 0xb9, 0x78, +0xe8, 0xcc, 0xa5, 0xcb, 0x18, 0x7e, 0x01, 0xfa, +0xe4, 0xca, 0x55, 0x90, 0x6f, 0xc2, 0x2f, 0x5c, +0x23, 0x9c, 0xc6, 0xa0, 0xde, 0x87, 0x84, 0x2e, +0x43, 0xf8, 0xb5, 0xeb, 0x18, 0xb6, 0x5c, 0xbe, +0x71, 0xf3, 0xd6, 0x6d, 0x2c, 0x21, 0x16, 0xbe, +0xf2, 0x0e, 0x58, 0xcb, 0xdd, 0xbb, 0x18, 0x5a, +0x6e, 0xde, 0xbb, 0xff, 0xe0, 0x21, 0x96, 0x5c, +0x19, 0xfe, 0x68, 0xef, 0x63, 0x60, 0xe2, 0x7f, +0x72, 0xf7, 0x29, 0x86, 0x96, 0x5b, 0xcf, 0x9e, +0x3f, 0xc7, 0xa6, 0x25, 0xac, 0xe6, 0xc5, 0x4b, +0x60, 0x16, 0x7b, 0xf5, 0xfa, 0x4d, 0x18, 0xba, +0x96, 0x87, 0xcf, 0xb1, 0x6b, 0x09, 0x7d, 0xfb, +0xee, 0xfd, 0xab, 0x0f, 0xaf, 0x3e, 0x7e, 0xfa, +0x8c, 0x91, 0x91, 0xbf, 0x3c, 0x7c, 0xf8, 0xf0, +0x0b, 0x16, 0xbf, 0x84, 0x7c, 0xfd, 0xf8, 0xed, +0xf5, 0xf7, 0x1f, 0x3f, 0x7f, 0xfd, 0x0e, 0x21, +0x36, 0xc4, 0x82, 0x43, 0xbe, 0x7e, 0x7e, 0xf3, +0xf4, 0xcf, 0xdf, 0xdf, 0x98, 0x85, 0x12, 0x2e, +0x5b, 0xf0, 0x14, 0x7d, 0x58, 0xfc, 0x82, 0xa5, +0x80, 0xfd, 0x87, 0x5f, 0x0b, 0xb6, 0x62, 0xfc, +0xdf, 0x7f, 0x7c, 0x5a, 0xb0, 0x56, 0x16, 0x32, +0x48, 0x95, 0x05, 0xa6, 0x5f, 0x08, 0x56, 0x49, +0x98, 0x21, 0x46, 0xb0, 0xe2, 0xc3, 0x04, 0x64, +0x54, 0xaf, 0x64, 0x54, 0xe2, 0x23, 0x18, 0x00, +0x00, 0xf9, 0xa7, 0x8d, 0xae, 0xd2, 0x97, 0x8e, +0x2b, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_nested_loop_semi_join_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_nested_loop_semi_join_png = new wxImage(); + if (!img_ex_nested_loop_semi_join_png || !img_ex_nested_loop_semi_join_png->IsOk()) + { + wxMemoryInputStream img_ex_nested_loop_semi_join_pngIS(ex_nested_loop_semi_join_png_data, sizeof(ex_nested_loop_semi_join_png_data)); + img_ex_nested_loop_semi_join_png->LoadFile(img_ex_nested_loop_semi_join_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_nested_loop_semi_join_png; +} +#define ex_nested_loop_semi_join_png_img ex_nested_loop_semi_join_png_img() + +static wxBitmap *ex_nested_loop_semi_join_png_bmp() +{ + static wxBitmap *bmp_ex_nested_loop_semi_join_png; + if (!bmp_ex_nested_loop_semi_join_png || !bmp_ex_nested_loop_semi_join_png->IsOk()) + bmp_ex_nested_loop_semi_join_png = new wxBitmap(*ex_nested_loop_semi_join_png_img); + return bmp_ex_nested_loop_semi_join_png; +} +#define ex_nested_loop_semi_join_png_bmp ex_nested_loop_semi_join_png_bmp() + +static wxIcon *ex_nested_loop_semi_join_png_ico() +{ + static wxIcon *ico_ex_nested_loop_semi_join_png; + if (!ico_ex_nested_loop_semi_join_png || !ico_ex_nested_loop_semi_join_png->IsOk()) + { + ico_ex_nested_loop_semi_join_png = new wxIcon(); + ico_ex_nested_loop_semi_join_png->CopyFromBitmap(*ex_nested_loop_semi_join_png_bmp); + } + return ico_ex_nested_loop_semi_join_png; +} +#define ex_nested_loop_semi_join_png_ico ex_nested_loop_semi_join_png_ico() + +#endif // EX_NESTED_LOOP_SEMI_JOIN_PNG_H diff --git a/include/images/ex_pscan.png b/include/images/ex_pscan.png new file mode 100644 index 0000000..d197f25 Binary files /dev/null and b/include/images/ex_pscan.png differ diff --git a/include/images/ex_pscan.pngc b/include/images/ex_pscan.pngc new file mode 100644 index 0000000..3f6556a --- /dev/null +++ b/include/images/ex_pscan.pngc @@ -0,0 +1,204 @@ +#ifndef EX_PSCAN_PNG_H +#define EX_PSCAN_PNG_H + +static const unsigned char ex_pscan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x3f, 0x88, +0xb1, 0x00, 0x00, 0x04, 0xc2, 0x49, 0x44, 0x41, +0x54, 0x78, 0xda, 0xed, 0x98, 0x31, 0x6f, 0x1c, +0x45, 0x14, 0xc7, 0xd3, 0xf0, 0x29, 0xf8, 0x04, +0x31, 0x7d, 0x44, 0x4b, 0x81, 0x44, 0x99, 0x06, +0x24, 0x44, 0x61, 0x1a, 0x28, 0xa0, 0x70, 0x45, +0x01, 0x74, 0x20, 0x25, 0xa4, 0x09, 0x12, 0x22, +0x91, 0x68, 0xa8, 0x40, 0x40, 0x01, 0x94, 0x28, +0x45, 0x4c, 0x1c, 0x14, 0x6c, 0x02, 0x58, 0x58, +0x31, 0x4e, 0x94, 0x8b, 0x0d, 0xc6, 0x77, 0x3e, +0x9f, 0x6f, 0xbd, 0x7b, 0xbb, 0x7b, 0xbb, 0xe7, +0x3b, 0xdf, 0x79, 0x98, 0xff, 0xdc, 0x7b, 0xeb, +0xd9, 0xf5, 0xcc, 0x7a, 0xce, 0x4e, 0x2c, 0x2b, +0xd9, 0x91, 0xfe, 0x9a, 0xdb, 0xe7, 0x27, 0xfb, +0xfd, 0xe6, 0xed, 0x7b, 0x6f, 0x7c, 0xe7, 0xce, +0x55, 0xab, 0x5a, 0xd5, 0xaa, 0xd6, 0x53, 0xb7, +0xae, 0xdc, 0xa8, 0x89, 0x0b, 0x9f, 0xcc, 0x1d, +0xd2, 0x69, 0xd8, 0x1f, 0x2b, 0x08, 0x7e, 0xe9, +0xcc, 0x9f, 0xbe, 0x78, 0xe9, 0x66, 0x4b, 0xbc, +0x3c, 0x3b, 0xd6, 0x7b, 0x8b, 0x81, 0xfa, 0x63, +0xef, 0xff, 0x15, 0x88, 0x8b, 0xb7, 0xb7, 0xc5, +0x6b, 0xbf, 0x8c, 0xf5, 0xf1, 0xbd, 0xce, 0x38, +0x88, 0xbf, 0x3b, 0xe2, 0xad, 0x05, 0x4f, 0xbc, +0xf3, 0x9b, 0x27, 0x66, 0xee, 0x7a, 0xe2, 0xf3, +0x07, 0xa1, 0xb2, 0x7f, 0xf1, 0x30, 0x14, 0x1f, +0x2e, 0xee, 0x88, 0x8f, 0x96, 0xc6, 0xfa, 0x6a, +0x75, 0x6c, 0xff, 0x76, 0x2d, 0x12, 0x57, 0x97, +0x7d, 0xf1, 0xd9, 0x4a, 0xa0, 0xf4, 0xe3, 0x7a, +0xac, 0xec, 0x8f, 0x1d, 0x04, 0x10, 0xcf, 0x7d, +0xb3, 0x9e, 0xe9, 0x95, 0x9f, 0x5b, 0xea, 0x0f, +0x01, 0xe2, 0xf9, 0x1f, 0x36, 0x32, 0xbd, 0x71, +0xa7, 0xad, 0xec, 0x80, 0x78, 0xf1, 0xa7, 0x46, +0x26, 0xc0, 0xc0, 0x0e, 0x88, 0x8b, 0xb3, 0x4d, +0xf1, 0xea, 0xad, 0xa6, 0x78, 0x7d, 0xae, 0x29, +0x2e, 0x49, 0x18, 0xd8, 0x01, 0xf1, 0xee, 0xfc, +0x96, 0xd2, 0xcc, 0x42, 0x4b, 0x5c, 0xbb, 0x1f, +0x3c, 0x19, 0x90, 0xa7, 0x22, 0x23, 0x1f, 0x7c, +0xf9, 0x9d, 0xf1, 0x1d, 0x3e, 0x0d, 0xfb, 0xc4, +0xc1, 0x7e, 0x3d, 0x57, 0x17, 0x6f, 0x5f, 0x5f, +0x52, 0xc2, 0x67, 0xfd, 0x67, 0x73, 0x9f, 0x5e, +0x10, 0xe1, 0xf6, 0x65, 0xb1, 0xb3, 0xf1, 0x66, +0x26, 0x3c, 0xeb, 0x76, 0x9f, 0x14, 0x91, 0x3d, +0x96, 0x7b, 0xb0, 0x31, 0x3d, 0x56, 0x7d, 0x5a, +0xc4, 0xed, 0xb1, 0xbd, 0x2b, 0xf7, 0x8e, 0x7c, +0x86, 0x42, 0xa9, 0x2e, 0xd9, 0x13, 0xb9, 0x47, +0xf2, 0x99, 0x95, 0x92, 0xdd, 0x35, 0xc6, 0x6c, +0xe1, 0x87, 0xeb, 0x41, 0x4f, 0x09, 0x9f, 0x8b, +0x20, 0x08, 0xb6, 0xf9, 0xf0, 0x85, 0x4c, 0x78, +0x86, 0x1d, 0xc1, 0x6f, 0xc9, 0xe7, 0xb1, 0xa6, +0x54, 0xe0, 0xb0, 0x63, 0xdf, 0xae, 0x4d, 0x65, +0x42, 0xe0, 0xb0, 0x63, 0xf7, 0xe4, 0x33, 0x2b, +0x22, 0x3b, 0x76, 0x5f, 0x3e, 0x07, 0xa4, 0xb8, +0x31, 0x7d, 0x08, 0xa4, 0x2c, 0xc6, 0x9c, 0xd3, +0xfd, 0xed, 0x44, 0x69, 0x72, 0x90, 0x29, 0xa5, +0x96, 0x0e, 0x52, 0x3f, 0x00, 0x69, 0x6b, 0x20, +0x21, 0x81, 0xec, 0x90, 0x74, 0x10, 0x05, 0xf1, +0x48, 0xfa, 0x4a, 0x75, 0x2d, 0x20, 0xb6, 0x18, +0x73, 0x4e, 0x2b, 0xad, 0xae, 0xd2, 0x51, 0x20, +0x38, 0x7d, 0x5f, 0x03, 0x69, 0x11, 0x84, 0x02, +0xa9, 0x1f, 0x80, 0xb4, 0x09, 0x02, 0x0a, 0xb5, +0x80, 0x19, 0xc2, 0xd7, 0x40, 0x62, 0xbc, 0x6e, +0x04, 0x01, 0x25, 0x16, 0x10, 0x5b, 0x8c, 0xce, +0x20, 0xa8, 0x05, 0xff, 0x18, 0xb5, 0x10, 0x3a, +0xd6, 0x42, 0x4f, 0xee, 0xc8, 0x42, 0x42, 0xda, +0x35, 0xd4, 0xc8, 0x89, 0x41, 0x6a, 0x37, 0xaf, +0xa8, 0x5f, 0x5a, 0xd4, 0x69, 0xd8, 0x8f, 0x05, +0xb2, 0x2c, 0x1d, 0x96, 0x2d, 0x19, 0x89, 0x28, +0x23, 0x7c, 0xfa, 0x31, 0x67, 0x44, 0x9e, 0x5c, +0x40, 0x5d, 0xa8, 0xa3, 0x9d, 0x3c, 0xf6, 0x50, +0x3b, 0xf9, 0x84, 0xec, 0xc8, 0x00, 0x5e, 0x23, +0x14, 0x33, 0x32, 0xd0, 0xd3, 0x32, 0xc2, 0xd9, +0x48, 0x4b, 0x32, 0x62, 0x8b, 0x31, 0xe7, 0x74, +0x6f, 0x2b, 0x56, 0x32, 0x81, 0xb8, 0xd4, 0x82, +0x67, 0xa8, 0x05, 0xbf, 0x58, 0x0b, 0x8d, 0x83, +0x5a, 0x08, 0xb5, 0x5a, 0xc0, 0x1e, 0xc9, 0xe7, +0x98, 0xd4, 0xb3, 0xd4, 0x88, 0x2d, 0xc6, 0x9c, +0xd3, 0x52, 0x33, 0x52, 0x32, 0x81, 0x20, 0x0b, +0x00, 0xe0, 0x4e, 0x14, 0x68, 0xed, 0xb4, 0x5d, +0xd2, 0x4e, 0xb9, 0xa5, 0xc6, 0x64, 0xef, 0x12, +0x48, 0x58, 0x00, 0x41, 0x16, 0x00, 0xd0, 0x25, +0xed, 0x5a, 0x40, 0x6c, 0x31, 0x4e, 0x04, 0x62, +0x9a, 0x0b, 0xa1, 0x36, 0x17, 0x8c, 0xed, 0x94, +0x5a, 0x6a, 0x57, 0x3b, 0x79, 0x00, 0x44, 0xa4, +0x94, 0xec, 0xc8, 0x00, 0x43, 0x24, 0x00, 0xd9, +0x7c, 0x42, 0x20, 0x65, 0xb5, 0x10, 0x95, 0xd4, +0x42, 0xd7, 0xb1, 0x16, 0xfa, 0x72, 0x47, 0x16, +0x00, 0x00, 0x0d, 0xbc, 0xcb, 0xc7, 0x07, 0x59, +0xdc, 0x8c, 0x94, 0xce, 0x72, 0xd7, 0xb2, 0xc5, +0x98, 0x77, 0x6a, 0x44, 0x4a, 0xa6, 0x8c, 0x70, +0x17, 0x62, 0x25, 0x86, 0xb9, 0x10, 0x17, 0xe6, +0x42, 0x62, 0x98, 0x0b, 0xd8, 0x91, 0x89, 0x1e, +0xa9, 0x4f, 0x76, 0x64, 0x00, 0x99, 0xe8, 0x93, +0xf6, 0xbc, 0x4b, 0xc6, 0x8c, 0xd8, 0x62, 0xcc, +0x39, 0xfd, 0xd1, 0x08, 0x95, 0x8c, 0x03, 0xf1, +0xa8, 0xab, 0x45, 0x2d, 0x7f, 0xb5, 0x38, 0xaa, +0x16, 0x50, 0x07, 0xc9, 0xea, 0x41, 0x2d, 0x60, +0xef, 0xc9, 0x67, 0x68, 0x77, 0xf5, 0xbc, 0x18, +0x58, 0x6a, 0xc4, 0x16, 0x63, 0xce, 0xe9, 0xf7, +0x7a, 0xa8, 0x64, 0x03, 0xb1, 0x5d, 0x2d, 0x02, +0xc3, 0xd5, 0xc2, 0xd6, 0x4e, 0xb1, 0x33, 0x44, +0xaa, 0x81, 0x20, 0x0b, 0x00, 0x60, 0xed, 0x59, +0x40, 0x6c, 0x31, 0xe6, 0x9c, 0xee, 0x6e, 0x74, +0x94, 0x8c, 0x03, 0x51, 0x6b, 0xa7, 0xbe, 0x43, +0x3b, 0x4d, 0xa8, 0x9d, 0x72, 0x4b, 0x65, 0x10, +0x04, 0x9e, 0x12, 0x04, 0x4e, 0xbf, 0x4f, 0x01, +0x0f, 0x08, 0xa4, 0x4f, 0xb2, 0x81, 0xd8, 0x62, +0xcc, 0x39, 0x2d, 0x48, 0x87, 0x05, 0x0b, 0x08, +0xd7, 0x42, 0x4c, 0xea, 0x39, 0xd4, 0x02, 0xd7, +0x01, 0xba, 0x51, 0xdf, 0x2b, 0xaf, 0x85, 0xa1, +0xdc, 0x11, 0x3c, 0x6b, 0x68, 0xa9, 0x11, 0x5b, +0x8c, 0x39, 0xa7, 0x79, 0xe9, 0x30, 0x6f, 0x70, +0x3a, 0x4b, 0x5d, 0xcb, 0x16, 0x63, 0xce, 0xe9, +0xd7, 0xff, 0x02, 0x25, 0x53, 0x46, 0x52, 0xba, +0x9d, 0xf2, 0x0d, 0xb5, 0xa7, 0x9d, 0x3c, 0xcf, +0x84, 0x54, 0xeb, 0x42, 0x6a, 0x2e, 0x6c, 0x1e, +0x9e, 0x0b, 0xd8, 0xf1, 0x1a, 0x0d, 0x0a, 0x27, +0xcf, 0x19, 0x19, 0x92, 0x46, 0x96, 0x8c, 0xd8, +0x62, 0xcc, 0x39, 0xdd, 0x59, 0x0f, 0x94, 0x8c, +0xed, 0x77, 0xc2, 0xab, 0x45, 0x59, 0x2d, 0xf4, +0x0d, 0xb5, 0x80, 0xe0, 0xf7, 0xd6, 0xce, 0x2b, +0x0d, 0xa5, 0x46, 0x96, 0x1a, 0xb1, 0xc5, 0xe8, +0x0c, 0x52, 0x6c, 0xa7, 0x3a, 0x88, 0xe9, 0x6a, +0xa1, 0xb7, 0xd3, 0x9e, 0xd6, 0x4e, 0xf7, 0x08, +0x64, 0x40, 0xd2, 0x41, 0x86, 0x04, 0x01, 0xed, +0x9f, 0x04, 0xe4, 0xf6, 0xbf, 0xbe, 0x92, 0x0d, +0x84, 0x21, 0xe2, 0xc2, 0x5c, 0xb0, 0xb5, 0x53, +0x9e, 0x09, 0x7a, 0x3b, 0xc5, 0x3e, 0xd0, 0x40, +0x86, 0x64, 0x1f, 0x69, 0x20, 0xa3, 0x12, 0x10, +0x5b, 0x8c, 0xce, 0x20, 0x3c, 0x91, 0xd3, 0xc2, +0x44, 0xb6, 0xd5, 0x02, 0xba, 0xd1, 0x24, 0xb5, +0x80, 0x1d, 0xc1, 0x67, 0xb2, 0xd4, 0x88, 0x13, +0xc8, 0xad, 0x7f, 0x7c, 0xa5, 0xb3, 0xdc, 0xb5, +0x6c, 0x31, 0x3a, 0x39, 0xf1, 0xc9, 0xf3, 0x4c, +0x50, 0x73, 0x40, 0xeb, 0x42, 0x3c, 0x13, 0x06, +0x25, 0x73, 0x41, 0x3f, 0x79, 0xbc, 0x46, 0x2c, +0x3e, 0xf9, 0x7d, 0xc7, 0x8c, 0x58, 0x41, 0xf4, +0x2f, 0xbd, 0x6e, 0xd4, 0x3c, 0xa5, 0xe2, 0x97, +0x60, 0xc7, 0xb9, 0x5a, 0xe8, 0xb5, 0xa0, 0x3a, +0x51, 0xa1, 0x16, 0x46, 0x85, 0x5a, 0x50, 0xc1, +0xe3, 0x99, 0x24, 0xb4, 0x1a, 0x71, 0x89, 0x91, +0xfe, 0x0f, 0x8e, 0xc5, 0xec, 0xda, 0x8e, 0xf8, +0x7e, 0xa5, 0xa5, 0x84, 0xcf, 0xb0, 0x31, 0x75, +0xb1, 0x9d, 0xa6, 0x0e, 0x57, 0x0b, 0x06, 0xe1, +0x96, 0x3a, 0xd2, 0x40, 0x46, 0x13, 0x82, 0xb8, +0xc4, 0x98, 0xd1, 0xa2, 0x80, 0xd8, 0x89, 0x8b, +0x49, 0xcf, 0x08, 0x83, 0x70, 0x4b, 0x1d, 0x18, +0xe6, 0xc2, 0xc0, 0x30, 0x17, 0x86, 0x85, 0xb9, +0xb0, 0x4f, 0x20, 0x59, 0xd0, 0x64, 0x17, 0x0e, +0x19, 0x29, 0x8b, 0x31, 0x07, 0xa3, 0xdf, 0x63, +0x74, 0x87, 0x93, 0xd6, 0xc2, 0xbe, 0x43, 0x2d, +0x60, 0x47, 0xf0, 0xac, 0x62, 0x8d, 0x1c, 0x15, +0xa3, 0xd3, 0x17, 0xc4, 0x67, 0xa5, 0x6b, 0x39, +0x7d, 0x89, 0x5d, 0xad, 0x6a, 0x55, 0xab, 0x5a, +0xd5, 0xaa, 0xd6, 0xb3, 0xbc, 0xfe, 0x07, 0xf8, +0x15, 0xdd, 0x40, 0x92, 0xef, 0xe9, 0x45, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_pscan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_pscan_png = new wxImage(); + if (!img_ex_pscan_png || !img_ex_pscan_png->IsOk()) + { + wxMemoryInputStream img_ex_pscan_pngIS(ex_pscan_png_data, sizeof(ex_pscan_png_data)); + img_ex_pscan_png->LoadFile(img_ex_pscan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_pscan_png; +} +#define ex_pscan_png_img ex_pscan_png_img() + +static wxBitmap *ex_pscan_png_bmp() +{ + static wxBitmap *bmp_ex_pscan_png; + if (!bmp_ex_pscan_png || !bmp_ex_pscan_png->IsOk()) + bmp_ex_pscan_png = new wxBitmap(*ex_pscan_png_img); + return bmp_ex_pscan_png; +} +#define ex_pscan_png_bmp ex_pscan_png_bmp() + +static wxIcon *ex_pscan_png_ico() +{ + static wxIcon *ico_ex_pscan_png; + if (!ico_ex_pscan_png || !ico_ex_pscan_png->IsOk()) + { + ico_ex_pscan_png = new wxIcon(); + ico_ex_pscan_png->CopyFromBitmap(*ex_pscan_png_bmp); + } + return ico_ex_pscan_png; +} +#define ex_pscan_png_ico ex_pscan_png_ico() + +#endif // EX_PSCAN_PNG_H diff --git a/include/images/ex_pscan2.png b/include/images/ex_pscan2.png new file mode 100644 index 0000000..d197f25 Binary files /dev/null and b/include/images/ex_pscan2.png differ diff --git a/include/images/ex_recursive_union.png b/include/images/ex_recursive_union.png new file mode 100644 index 0000000..66952ea Binary files /dev/null and b/include/images/ex_recursive_union.png differ diff --git a/include/images/ex_recursive_union.pngc b/include/images/ex_recursive_union.pngc new file mode 100644 index 0000000..97fa351 --- /dev/null +++ b/include/images/ex_recursive_union.pngc @@ -0,0 +1,197 @@ +#ifndef EX_RECURSIVE_UNION_PNG_H +#define EX_RECURSIVE_UNION_PNG_H + +static const unsigned char ex_recursive_union_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0xf5, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x45, 0xbe, 0xe9, +0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, 0x85, 0xd4, +0xf0, 0x94, 0xd8, 0xf0, 0x7a, 0xce, 0xec, 0x83, +0xd1, 0xed, 0x8b, 0xd4, 0xee, 0xad, 0xdf, 0xf3, +0x40, 0xbc, 0xe9, 0x07, 0xa8, 0xe2, 0x10, 0xab, +0xe2, 0x1a, 0xae, 0xe3, 0x5d, 0xc5, 0xeb, 0x71, +0xcb, 0xec, 0x4e, 0xbe, 0xe6, 0x5a, 0xc1, 0xe7, +0x64, 0xc5, 0xe8, 0x92, 0xd5, 0xef, 0x64, 0x95, +0xd0, 0xde, 0xea, 0xd4, 0x97, 0xbb, 0x75, 0xba, +0xd1, 0xa3, 0x66, 0x6b, 0xd1, 0xcc, 0xcd, 0xf1, +0xbd, 0xbf, 0xed, 0xbf, 0xc1, 0xed, 0xc2, 0xc3, +0xef, 0xd3, 0xd4, 0xf3, 0xd8, 0xd9, 0xf4, 0xce, +0xcf, 0xf2, 0xd1, 0xd1, 0xf2, 0xd4, 0xd4, 0xf4, +0xe0, 0xe0, 0xf7, 0x81, 0xae, 0x42, 0x72, 0xa5, +0x36, 0x99, 0xbc, 0x78, 0xbc, 0xbd, 0xec, 0xa7, +0xa9, 0xe7, 0xaa, 0xac, 0xe7, 0xae, 0xaf, 0xe9, +0xc5, 0xc6, 0xef, 0xcb, 0xcc, 0xf1, 0xbe, 0xbf, +0xed, 0xc2, 0xc2, 0xee, 0xc5, 0xc6, 0xf0, 0xd6, +0xd6, 0xf4, 0x73, 0xa5, 0x37, 0xa7, 0xcf, 0x67, +0x76, 0xaa, 0x3a, 0x76, 0xab, 0x3b, 0xb0, 0xdd, +0x74, 0x52, 0x8d, 0x19, 0x77, 0xab, 0x3c, 0xb2, +0xe0, 0x76, 0x7a, 0xb1, 0x40, 0x8c, 0xc0, 0x52, +0x7a, 0xb1, 0x41, 0xa5, 0xa8, 0xe4, 0x90, 0xb6, +0x6c, 0xd8, 0xe5, 0xcb, 0xa1, 0xc4, 0x5e, 0x84, +0xb0, 0x45, 0x72, 0xa3, 0x35, 0xa2, 0xc7, 0x60, +0xa4, 0xca, 0x63, 0xa7, 0xcd, 0x66, 0x86, 0xb6, +0x49, 0x76, 0xaa, 0x3b, 0xae, 0xda, 0x71, 0x78, +0xae, 0x3e, 0xb4, 0xe3, 0x79, 0xb5, 0x99, 0x7e, +0xc1, 0x8f, 0x36, 0x8d, 0xc1, 0x53, 0xf4, 0xf1, +0xc9, 0xf0, 0xec, 0xb7, 0xf0, 0xec, 0xb6, 0xef, +0xea, 0xb6, 0xf3, 0xef, 0xc7, 0xf2, 0xec, 0xc5, +0xed, 0xe5, 0xb1, 0xed, 0xe3, 0xb0, 0xec, 0xe2, +0xaf, 0xf0, 0xe8, 0xc1, 0xb6, 0xe7, 0x7c, 0xea, +0xe4, 0x9d, 0xea, 0xe3, 0x9c, 0xe9, 0xe1, 0x9b, +0xef, 0xe8, 0xb3, 0xe6, 0xda, 0x95, 0xe5, 0xd7, +0x93, 0xe4, 0xd5, 0x92, 0xeb, 0xde, 0xac, 0xb9, +0xeb, 0x7f, 0xef, 0xeb, 0xb6, 0xea, 0xe2, 0x9c, +0xe8, 0xdf, 0x99, 0xee, 0xe6, 0xb2, 0xec, 0xe3, +0xaf, 0xe4, 0xd4, 0x91, 0xe3, 0xd2, 0x8f, 0xe9, +0xdc, 0xaa, 0x7a, 0x9e, 0xa9, 0xba, 0xee, 0x82, +0xef, 0xe9, 0xb4, 0xe9, 0xe0, 0x9a, 0xe8, 0xde, +0x99, 0xe7, 0xdc, 0x97, 0xec, 0xe3, 0xb0, 0xec, +0xe0, 0xad, 0xe4, 0xd3, 0x90, 0xe3, 0xd1, 0x8e, +0xe2, 0xcf, 0x8d, 0xe9, 0xd9, 0xa8, 0x7c, 0xb4, +0x43, 0xbc, 0xf0, 0x84, 0xf3, 0xed, 0xc6, 0xed, +0xe4, 0xb1, 0xf0, 0xe8, 0xc2, 0xef, 0xe6, 0xc0, +0xea, 0xdc, 0xaa, 0xe9, 0xda, 0xa9, 0xe9, 0xd8, +0xa7, 0xed, 0xe1, 0xbc, 0x96, 0xcc, 0x5d, 0xdb, +0xbd, 0x89, 0xf1, 0xea, 0xc3, 0xef, 0xe5, 0xbf, +0xee, 0xe2, 0xbd, 0xe8, 0xd7, 0xa7, 0xe7, 0xd5, +0xa5, 0xe6, 0xd4, 0xa4, 0xec, 0xdd, 0xba, 0xec, +0xe1, 0xae, 0xe4, 0xd5, 0x91, 0xe2, 0xd0, 0x8e, +0xe8, 0xd7, 0xa6, 0xdf, 0xc7, 0x86, 0xde, 0xc5, +0x85, 0xdd, 0xc2, 0x83, 0xe5, 0xd1, 0xa1, 0xeb, +0xdf, 0xad, 0xe3, 0xd1, 0x8f, 0xe1, 0xcd, 0x8b, +0xe7, 0xd4, 0xa4, 0xde, 0xc4, 0x84, 0xdc, 0xc0, +0x81, 0xe5, 0xce, 0xa0, 0xe2, 0xce, 0x8c, 0xe1, +0xcc, 0x8a, 0xe0, 0xc9, 0x89, 0xe6, 0xd2, 0xa3, +0xdd, 0xc1, 0x82, 0xdc, 0xbf, 0x81, 0xdb, 0xbe, +0x7f, 0xe4, 0xcd, 0x9e, 0xee, 0xe3, 0xbe, 0xec, +0xde, 0xba, 0xeb, 0xdb, 0xb8, 0xe5, 0xcf, 0xa0, +0xe4, 0xce, 0x9f, 0xea, 0xd9, 0xb6, 0x58, 0x36, +0xab, 0x05, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x0a, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0x60, +0x18, 0x05, 0xe4, 0x01, 0x46, 0x26, 0x10, 0x80, +0x92, 0xc4, 0x69, 0x61, 0x62, 0x66, 0x61, 0x65, +0x63, 0x67, 0xe2, 0xe0, 0xe4, 0xe2, 0xe6, 0x61, +0x22, 0x52, 0x0b, 0x2f, 0x1f, 0xbf, 0x80, 0x20, +0x93, 0x90, 0xb0, 0x88, 0xa8, 0x18, 0xb1, 0x5a, +0x48, 0xb7, 0x45, 0x1c, 0xec, 0x0b, 0x28, 0x49, +0xc8, 0x8b, 0x12, 0x92, 0x52, 0x40, 0x52, 0x5a, +0x46, 0x56, 0x4e, 0x5e, 0x41, 0x5a, 0x51, 0x49, +0x59, 0x45, 0x55, 0x9a, 0x90, 0xe5, 0x92, 0x6a, +0xea, 0x1a, 0x40, 0x2d, 0x9a, 0x5a, 0xda, 0x3a, +0xba, 0xd2, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc8, +0x5a, 0xb0, 0x7a, 0x51, 0xca, 0xd8, 0xc4, 0x54, +0x03, 0xa7, 0x16, 0xec, 0x5e, 0xd4, 0x30, 0x33, +0xb7, 0xc0, 0xa5, 0x05, 0xbb, 0x17, 0xa5, 0x2c, +0xad, 0xac, 0x35, 0x70, 0xf9, 0x05, 0xbb, 0xb0, +0xa4, 0x8d, 0x2d, 0xd0, 0x2f, 0x76, 0xd2, 0x20, +0x00, 0x25, 0x19, 0x34, 0x2c, 0x2c, 0xec, 0x1d, +0xc0, 0x5a, 0xb0, 0x5a, 0x8e, 0x2d, 0xc4, 0x2c, +0x1c, 0x1d, 0x9d, 0xc0, 0x7a, 0x70, 0xb8, 0x97, +0x01, 0xd3, 0x38, 0x0d, 0x0b, 0x67, 0xa0, 0x1e, +0x92, 0xb4, 0x00, 0xc3, 0xc4, 0xd9, 0xd1, 0x02, +0x77, 0x74, 0x61, 0xd5, 0xc2, 0x60, 0xe1, 0x02, +0xd2, 0x82, 0xea, 0x45, 0x34, 0x2d, 0xe8, 0xc6, +0x59, 0xb8, 0x62, 0xda, 0x02, 0xf1, 0x36, 0x0c, +0x60, 0x18, 0x67, 0xe1, 0x66, 0x81, 0x61, 0x39, +0x24, 0xa1, 0xe0, 0x04, 0x92, 0xee, 0x1e, 0x18, +0xe9, 0x08, 0x92, 0x50, 0x70, 0x02, 0x29, 0x0f, +0x4f, 0x2f, 0x8c, 0x74, 0x04, 0x4e, 0x28, 0xb8, +0x81, 0x86, 0x97, 0xb7, 0x05, 0x9a, 0x5f, 0x20, +0x09, 0x05, 0x67, 0xc6, 0x90, 0xf2, 0xf2, 0x06, +0xa6, 0x0a, 0x1f, 0x5f, 0x10, 0x80, 0x92, 0xd0, +0x84, 0x82, 0x33, 0xc9, 0x4a, 0xfa, 0x81, 0xa4, +0x7d, 0xfd, 0x03, 0x02, 0x83, 0x82, 0x7d, 0x43, +0x42, 0xc3, 0xc2, 0x23, 0x7c, 0xd1, 0x42, 0x0c, +0x23, 0x63, 0x58, 0x44, 0x82, 0x5c, 0xed, 0x1b, +0x18, 0x15, 0x1d, 0x13, 0xeb, 0x1b, 0x1a, 0x17, +0x9f, 0x90, 0xe8, 0x8b, 0xe6, 0x72, 0x0c, 0x5b, +0x2c, 0x92, 0xc0, 0x5a, 0x92, 0x53, 0x62, 0x52, +0xd3, 0x7c, 0xd3, 0xe3, 0x33, 0x32, 0xb3, 0xd0, +0xb5, 0x64, 0x83, 0x7d, 0x01, 0x25, 0xc1, 0x5a, +0x72, 0xc0, 0x5a, 0x72, 0xf3, 0xf2, 0x0b, 0x0a, +0x7d, 0x8b, 0x8a, 0x4b, 0x4a, 0xcb, 0xd0, 0xb5, +0xa0, 0x3a, 0x1a, 0x18, 0x5e, 0xe5, 0x15, 0x60, +0x2d, 0x95, 0x69, 0x55, 0x85, 0xd5, 0xbe, 0x35, +0xb5, 0x75, 0xf5, 0x0d, 0x08, 0x2d, 0x10, 0x3f, +0xa1, 0x3a, 0x5a, 0xc3, 0xa2, 0xbc, 0xa2, 0x11, +0x94, 0x92, 0x9b, 0xc0, 0x61, 0x05, 0x25, 0x11, +0xd1, 0x0c, 0x4e, 0x05, 0xa8, 0x8e, 0xb6, 0xc8, +0x01, 0xea, 0x00, 0xe5, 0x17, 0xdf, 0xe6, 0xf0, +0xa2, 0xc4, 0x16, 0xdf, 0xd6, 0xb6, 0xf6, 0x8e, +0x4e, 0x84, 0x2d, 0x90, 0x54, 0x80, 0xea, 0x68, +0x78, 0xae, 0xf4, 0xed, 0xea, 0xce, 0xec, 0xa9, +0xf3, 0xed, 0xed, 0xeb, 0x9f, 0x30, 0x11, 0xc9, +0x2f, 0xe0, 0x54, 0x80, 0xdd, 0xd1, 0x0c, 0xbe, +0x93, 0x26, 0x97, 0x4e, 0x69, 0xf3, 0x9d, 0x3a, +0x6d, 0xc2, 0xf4, 0x19, 0x48, 0xb6, 0x80, 0x53, +0x01, 0x76, 0x47, 0x33, 0xf8, 0xd6, 0xce, 0x9c, +0x35, 0xbb, 0xdd, 0x77, 0xce, 0xdc, 0x79, 0xf3, +0x17, 0x20, 0xb4, 0x40, 0x52, 0x01, 0x76, 0x47, +0x33, 0xf8, 0x2e, 0xac, 0xef, 0x9d, 0xba, 0xc8, +0x77, 0xf1, 0x92, 0xa5, 0x0b, 0x96, 0x61, 0x84, +0x18, 0x76, 0x47, 0xe3, 0xb0, 0x1c, 0x8f, 0xa3, +0xf1, 0x02, 0xec, 0x8e, 0xc6, 0xaf, 0x05, 0xab, +0xa3, 0xf1, 0x02, 0x7c, 0x8e, 0x1e, 0x05, 0xf4, +0x07, 0x00, 0x43, 0x58, 0xdb, 0x1d, 0x64, 0x20, +0x01, 0x79, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_recursive_union_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_recursive_union_png = new wxImage(); + if (!img_ex_recursive_union_png || !img_ex_recursive_union_png->IsOk()) + { + wxMemoryInputStream img_ex_recursive_union_pngIS(ex_recursive_union_png_data, sizeof(ex_recursive_union_png_data)); + img_ex_recursive_union_png->LoadFile(img_ex_recursive_union_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_recursive_union_png; +} +#define ex_recursive_union_png_img ex_recursive_union_png_img() + +static wxBitmap *ex_recursive_union_png_bmp() +{ + static wxBitmap *bmp_ex_recursive_union_png; + if (!bmp_ex_recursive_union_png || !bmp_ex_recursive_union_png->IsOk()) + bmp_ex_recursive_union_png = new wxBitmap(*ex_recursive_union_png_img); + return bmp_ex_recursive_union_png; +} +#define ex_recursive_union_png_bmp ex_recursive_union_png_bmp() + +static wxIcon *ex_recursive_union_png_ico() +{ + static wxIcon *ico_ex_recursive_union_png; + if (!ico_ex_recursive_union_png || !ico_ex_recursive_union_png->IsOk()) + { + ico_ex_recursive_union_png = new wxIcon(); + ico_ex_recursive_union_png->CopyFromBitmap(*ex_recursive_union_png_bmp); + } + return ico_ex_recursive_union_png; +} +#define ex_recursive_union_png_ico ex_recursive_union_png_ico() + +#endif // EX_RECURSIVE_UNION_PNG_H diff --git a/include/images/ex_redistribute_motion.png b/include/images/ex_redistribute_motion.png new file mode 100644 index 0000000..06b7282 Binary files /dev/null and b/include/images/ex_redistribute_motion.png differ diff --git a/include/images/ex_redistribute_motion.pngc b/include/images/ex_redistribute_motion.pngc new file mode 100644 index 0000000..d10962a --- /dev/null +++ b/include/images/ex_redistribute_motion.pngc @@ -0,0 +1,72 @@ +#ifndef EX_REDISTRIBUTE_MOTION_PNG_H +#define EX_REDISTRIBUTE_MOTION_PNG_H + +static const unsigned char ex_redistribute_motion_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x01, 0x00, 0x00, 0x00, 0x00, 0x36, 0x44, 0xb5, +0x1c, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x01, 0xdd, 0x8a, 0x13, 0xa4, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x0e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x18, 0x05, +0x83, 0x09, 0x00, 0x00, 0x01, 0x90, 0x00, 0x01, +0xc5, 0x9b, 0xdb, 0x49, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_redistribute_motion_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_redistribute_motion_png = new wxImage(); + if (!img_ex_redistribute_motion_png || !img_ex_redistribute_motion_png->IsOk()) + { + wxMemoryInputStream img_ex_redistribute_motion_pngIS(ex_redistribute_motion_png_data, sizeof(ex_redistribute_motion_png_data)); + img_ex_redistribute_motion_png->LoadFile(img_ex_redistribute_motion_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_redistribute_motion_png; +} +#define ex_redistribute_motion_png_img ex_redistribute_motion_png_img() + +static wxBitmap *ex_redistribute_motion_png_bmp() +{ + static wxBitmap *bmp_ex_redistribute_motion_png; + if (!bmp_ex_redistribute_motion_png || !bmp_ex_redistribute_motion_png->IsOk()) + bmp_ex_redistribute_motion_png = new wxBitmap(*ex_redistribute_motion_png_img); + return bmp_ex_redistribute_motion_png; +} +#define ex_redistribute_motion_png_bmp ex_redistribute_motion_png_bmp() + +static wxIcon *ex_redistribute_motion_png_ico() +{ + static wxIcon *ico_ex_redistribute_motion_png; + if (!ico_ex_redistribute_motion_png || !ico_ex_redistribute_motion_png->IsOk()) + { + ico_ex_redistribute_motion_png = new wxIcon(); + ico_ex_redistribute_motion_png->CopyFromBitmap(*ex_redistribute_motion_png_bmp); + } + return ico_ex_redistribute_motion_png; +} +#define ex_redistribute_motion_png_ico ex_redistribute_motion_png_ico() + +#endif // EX_REDISTRIBUTE_MOTION_PNG_H diff --git a/include/images/ex_result.png b/include/images/ex_result.png new file mode 100644 index 0000000..bfd7b59 Binary files /dev/null and b/include/images/ex_result.png differ diff --git a/include/images/ex_result.pngc b/include/images/ex_result.pngc new file mode 100644 index 0000000..a450225 --- /dev/null +++ b/include/images/ex_result.pngc @@ -0,0 +1,209 @@ +#ifndef EX_RESULT_PNG_H +#define EX_RESULT_PNG_H + +static const unsigned char ex_result_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbf, 0xc9, 0xd0, 0x96, +0xb8, 0xd0, 0xaf, 0xc2, 0xd0, 0x7d, 0xae, 0xd1, +0xb0, 0xc3, 0xd0, 0x85, 0xb1, 0xd1, 0x5d, 0xa5, +0xd5, 0x6e, 0xb9, 0xe0, 0x8f, 0xb5, 0xd1, 0xc1, +0xca, 0xd0, 0x68, 0xae, 0xda, 0x8d, 0xca, 0xe8, +0x90, 0xca, 0xe8, 0x64, 0xaa, 0xd8, 0xc8, 0xcd, +0xd0, 0x6a, 0xb4, 0xde, 0x86, 0xd4, 0xf0, 0x71, +0xbe, 0xe4, 0x82, 0xcf, 0xec, 0x61, 0xa9, 0xd8, +0xb7, 0xc6, 0xd0, 0x9e, 0xbc, 0xd0, 0x6c, 0xa7, +0xd1, 0x7f, 0xc0, 0xe3, 0x91, 0xcd, 0xe8, 0x60, +0xa6, 0xd6, 0x9e, 0xd4, 0xed, 0x81, 0xbe, 0xe1, +0x74, 0xab, 0xd1, 0xa8, 0xc0, 0xd0, 0x5d, 0xa8, +0xd7, 0x6a, 0xca, 0xed, 0x6e, 0xbd, 0xe4, 0x65, +0xc8, 0xec, 0x73, 0xb8, 0xe0, 0x58, 0xa1, 0xd3, +0x91, 0xd1, 0xec, 0x85, 0xc3, 0xe5, 0x5a, 0xa2, +0xd3, 0x97, 0xd2, 0xec, 0x59, 0xa2, 0xd3, 0x6e, +0xc1, 0xe6, 0x51, 0xc1, 0xea, 0x8d, 0xb5, 0xd1, +0x75, 0xbc, 0xe3, 0x8d, 0xd4, 0xee, 0x65, 0xad, +0xda, 0x8e, 0xcd, 0xe9, 0xb8, 0xc6, 0xd0, 0x9f, +0xda, 0xf0, 0x5a, 0xa5, 0xd5, 0x5b, 0xa0, 0xd1, +0x82, 0xc6, 0xe6, 0x73, 0xb4, 0xdd, 0x95, 0xd8, +0xef, 0x90, 0xca, 0xe7, 0x6f, 0xbb, 0xe2, 0x39, +0xb9, 0xe7, 0x5d, 0xc4, 0xe9, 0x76, 0xba, 0xe0, +0x75, 0xcd, 0xed, 0x7d, 0xc2, 0xe4, 0x91, 0xd5, +0xee, 0x64, 0xa4, 0xd1, 0x5e, 0xc1, 0xe8, 0x32, +0xb7, 0xe6, 0x75, 0xca, 0xea, 0x6e, 0xcb, 0xec, +0x6d, 0xb0, 0xda, 0x92, 0xd3, 0xed, 0x61, 0xac, +0xda, 0x40, 0xbc, 0xe8, 0x7a, 0xc0, 0xe4, 0x7a, +0xca, 0xea, 0x83, 0xd0, 0xed, 0x8a, 0xc6, 0xe5, +0x63, 0xbd, 0xe5, 0x23, 0xb2, 0xe4, 0x3c, 0xba, +0xe7, 0x55, 0xc1, 0xe8, 0x7f, 0xce, 0xec, 0x94, +0xd5, 0xee, 0x66, 0xb2, 0xdd, 0x61, 0xc0, 0xe7, +0x1c, 0xaf, 0xe4, 0x35, 0xb8, 0xe7, 0x65, 0xb7, +0xe0, 0x5a, 0xc3, 0xe9, 0x78, 0xc5, 0xe8, 0x75, +0xc5, 0xe8, 0x5c, 0xbc, 0xe5, 0x2c, 0xb5, 0xe5, +0x45, 0xbb, 0xe6, 0x7f, 0xc8, 0xe8, 0x80, 0xc8, +0xe8, 0x64, 0xc6, 0xeb, 0x88, 0xd1, 0xed, 0x3e, +0xb9, 0xe5, 0x6c, 0xc9, 0xeb, 0x53, 0x9d, 0xd1, +0x71, 0xc9, 0xe9, 0xa6, 0xbf, 0xd0, 0x64, 0xb0, +0xdc, 0x70, 0xb6, 0xde, 0x7c, 0xb9, 0xdf, 0x75, +0xc4, 0xe7, 0x49, 0xbe, 0xe9, 0x7b, 0xc5, 0xe7, +0x48, 0xbd, 0xe7, 0x7e, 0xcd, 0xeb, 0x94, 0xce, +0xea, 0x56, 0xa1, 0xd3, 0x4c, 0xc0, 0xea, 0x79, +0xcc, 0xea, 0x69, 0xbf, 0xe6, 0x6b, 0xb7, 0xe0, +0x65, 0xbf, 0xe6, 0x41, 0xbb, 0xe8, 0x6b, 0xb2, +0xdc, 0x75, 0xb6, 0xde, 0x69, 0xc8, 0xeb, 0x68, +0xba, 0xe3, 0x8c, 0xc8, 0xe6, 0x82, 0xcd, 0xeb, +0x7a, 0xbb, 0xe1, 0xa5, 0xda, 0xf0, 0x4f, 0xb7, +0xe3, 0x2d, 0x6b, 0x8a, 0xc1, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xdf, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x55, 0xe9, 0x53, 0xda, 0x40, 0x14, +0x0f, 0x21, 0x84, 0x44, 0x2c, 0xa9, 0x57, 0x28, +0xc8, 0x42, 0x2d, 0xc8, 0x95, 0x94, 0x82, 0x50, +0xbc, 0xa0, 0x22, 0x51, 0x01, 0x95, 0xc3, 0x03, +0x8a, 0x16, 0x5a, 0xa5, 0x08, 0x56, 0x45, 0xc5, +0xa3, 0xf5, 0xa8, 0xed, 0xbf, 0xde, 0x70, 0x04, +0x76, 0x43, 0x74, 0xa6, 0x5f, 0x3a, 0xfd, 0xe0, +0x9b, 0x61, 0x86, 0xb7, 0xbb, 0xbf, 0xf7, 0xde, +0xef, 0x5d, 0xc1, 0xb0, 0x67, 0xf9, 0xf7, 0xa2, +0xc2, 0x71, 0x15, 0xa4, 0xaa, 0x09, 0x0d, 0xa6, +0x11, 0x7f, 0x4f, 0x08, 0xa9, 0xa5, 0x28, 0x2d, +0x2d, 0x69, 0x03, 0xb4, 0x6e, 0x90, 0xc0, 0x88, +0x17, 0x7a, 0x9c, 0x79, 0x1c, 0xf1, 0x72, 0x88, +0x1a, 0x1e, 0x19, 0x1d, 0x6b, 0x6b, 0xac, 0xe1, +0x95, 0xd1, 0x24, 0x7a, 0xd1, 0x8f, 0x9b, 0x81, +0xe5, 0x11, 0x84, 0xc5, 0xfa, 0x7a, 0x82, 0x1c, +0x7e, 0x63, 0xc3, 0xdb, 0x08, 0xfb, 0xa4, 0xa3, +0xf5, 0x94, 0x75, 0x8e, 0xbb, 0xdc, 0xac, 0x32, +0x04, 0x78, 0x38, 0x1d, 0xff, 0xd6, 0xfb, 0x4e, +0xdd, 0x54, 0x34, 0x76, 0x9f, 0xcf, 0xed, 0x6f, +0x83, 0xdd, 0x53, 0x2e, 0xa7, 0x22, 0x21, 0x55, +0x80, 0xe3, 0x02, 0x2a, 0x3e, 0xd8, 0xe2, 0xc2, +0x10, 0xef, 0x87, 0xf4, 0x92, 0x69, 0x3a, 0x34, +0x3d, 0x43, 0x28, 0xf1, 0xe1, 0x67, 0xe7, 0xe6, +0x83, 0x92, 0x42, 0x87, 0x23, 0x1f, 0xc8, 0x9e, +0x7f, 0xe3, 0x82, 0x99, 0x56, 0x80, 0x44, 0x17, +0x63, 0x1e, 0xd0, 0xf9, 0xef, 0xd7, 0x0a, 0x4b, +0x3a, 0x75, 0x8f, 0xe5, 0xb2, 0x77, 0xc5, 0xe4, +0xef, 0x27, 0x1f, 0x4f, 0xcc, 0x51, 0xb8, 0x94, +0xbb, 0xe4, 0xfc, 0x6a, 0x14, 0x36, 0x37, 0xb9, +0xb6, 0x4e, 0xca, 0x00, 0x2c, 0x69, 0x48, 0xa5, +0x33, 0x71, 0xbc, 0x5d, 0x02, 0x95, 0x76, 0x29, +0x9b, 0x84, 0x9f, 0x90, 0xeb, 0x1b, 0x9b, 0x26, +0x15, 0x8a, 0xd8, 0x1a, 0xde, 0x8e, 0xe5, 0xf2, +0x1f, 0x29, 0xca, 0xde, 0xc4, 0xf0, 0xc9, 0x6c, +0xc1, 0x06, 0xe7, 0x15, 0x37, 0x8f, 0x8c, 0x98, +0x71, 0x04, 0x02, 0x76, 0x76, 0x3f, 0x15, 0x73, +0x25, 0xcf, 0xe7, 0x2f, 0x2d, 0x36, 0x51, 0xa1, +0xb4, 0x07, 0x51, 0x11, 0x3b, 0x67, 0x79, 0x5f, +0x70, 0x45, 0x11, 0x88, 0x05, 0x00, 0x7b, 0x26, +0x9d, 0x02, 0xa0, 0x55, 0xbc, 0xb1, 0xd1, 0xbd, +0xf2, 0xd7, 0x0a, 0x7c, 0xcf, 0x38, 0xbd, 0x07, +0x0b, 0xb2, 0xc8, 0xb0, 0x6a, 0x2d, 0x93, 0x97, +0xd8, 0xb3, 0x87, 0xd9, 0x72, 0x04, 0x81, 0x60, +0x95, 0xcd, 0x83, 0xfd, 0x6f, 0xb2, 0x16, 0xe0, +0xa9, 0x62, 0xa6, 0x56, 0xed, 0x44, 0x6e, 0xe3, +0x4a, 0x47, 0x00, 0xb9, 0x8e, 0x4e, 0x0a, 0x72, +0x32, 0x98, 0x61, 0x3b, 0x7d, 0x1c, 0xe8, 0x78, +0x06, 0x27, 0xf5, 0xfa, 0x09, 0x0a, 0x01, 0x83, +0xc2, 0xe9, 0x19, 0x7a, 0xc4, 0x9c, 0x37, 0x72, +0x8b, 0x12, 0x3f, 0x70, 0x54, 0xea, 0x83, 0xf8, +0x2e, 0x2e, 0x8c, 0xe8, 0x91, 0x48, 0x25, 0x7d, +0x49, 0xfc, 0x15, 0x04, 0xbf, 0x2a, 0xc6, 0xba, +0xb5, 0x07, 0x3b, 0x75, 0x25, 0x88, 0x2c, 0x30, +0x70, 0x9d, 0x4e, 0xc4, 0xa5, 0x4a, 0x90, 0xc9, +0xe3, 0xfa, 0x91, 0x9c, 0xcb, 0xc5, 0xe9, 0x0c, +0x81, 0x1c, 0x55, 0x1a, 0x39, 0xae, 0x9b, 0x56, +0x3c, 0xcc, 0x7d, 0x17, 0x82, 0xc8, 0xbd, 0xc1, +0x27, 0xcf, 0x98, 0x3a, 0x9e, 0xc9, 0x5d, 0x77, +0xed, 0x56, 0x7f, 0x14, 0xca, 0x4b, 0xfd, 0x75, +0xb9, 0xa9, 0xa2, 0x54, 0x62, 0xc5, 0x59, 0xbe, +0x9b, 0x3e, 0xfb, 0x6d, 0xf9, 0x56, 0x0b, 0xd7, +0xba, 0x59, 0x7d, 0x59, 0x5f, 0xf2, 0x77, 0xc5, +0xb9, 0x5a, 0xcf, 0x88, 0x61, 0xa7, 0xde, 0xdf, +0x63, 0x67, 0x06, 0x94, 0x5d, 0x2a, 0xd7, 0xb0, +0xf7, 0x46, 0x95, 0x3d, 0x2c, 0x14, 0xc2, 0x70, +0xe4, 0x62, 0x27, 0xaf, 0xc9, 0x8a, 0x5f, 0x69, +0xa4, 0xb7, 0x21, 0x23, 0x8c, 0x5d, 0xc8, 0x26, +0xe1, 0xfc, 0x10, 0xf7, 0x1b, 0x9b, 0x4e, 0x64, +0xfa, 0xc7, 0xac, 0x99, 0xe2, 0x15, 0x6c, 0x84, +0x0e, 0xcf, 0x47, 0x20, 0xaf, 0x58, 0x70, 0x65, +0x5f, 0x36, 0xfc, 0xec, 0x56, 0xbe, 0xdb, 0x60, +0x1d, 0x37, 0xab, 0xb7, 0xb6, 0x9e, 0x8d, 0x6a, +0xc8, 0xbb, 0x82, 0x3a, 0xc1, 0xc8, 0xbb, 0xfc, +0xb5, 0xac, 0x1b, 0x74, 0x91, 0x9f, 0xd1, 0xee, +0x23, 0x60, 0x9c, 0x0e, 0x41, 0x41, 0x58, 0x00, +0x8b, 0x45, 0x0b, 0xc7, 0x71, 0xd9, 0x0e, 0x25, +0xc3, 0x6b, 0x0f, 0xd2, 0xf4, 0xd3, 0xa1, 0x29, +0x07, 0xb4, 0x09, 0x34, 0xd6, 0xdd, 0x2d, 0xd6, +0xca, 0x5d, 0xa2, 0x4e, 0xc4, 0xd0, 0x48, 0xc7, +0xb4, 0xbe, 0x1d, 0x3e, 0x6b, 0xfa, 0x75, 0x4f, +0x0e, 0x40, 0xb9, 0xf0, 0x24, 0x52, 0xc4, 0xe5, +0x9e, 0xb5, 0x6f, 0x51, 0xfb, 0xc9, 0x87, 0xa9, +0xd6, 0xbe, 0xc4, 0x4d, 0xe3, 0x0e, 0x12, 0x5e, +0x62, 0xe4, 0x44, 0xe2, 0x77, 0x2a, 0x52, 0x53, +0xd8, 0x85, 0x0c, 0xad, 0x73, 0xdd, 0xb0, 0x22, +0xf5, 0x5f, 0x21, 0x7e, 0x00, 0x31, 0x76, 0x3e, +0xe1, 0xa1, 0x02, 0x4a, 0xdb, 0xb3, 0xb9, 0xfc, +0x1f, 0x70, 0xb1, 0x8a, 0x6e, 0xd9, 0x00, 0x8b, +0x01, 0x00, 0x5e, 0x85, 0x29, 0x0b, 0x23, 0x6e, +0x42, 0xe6, 0x89, 0x0f, 0xd2, 0xb3, 0xfc, 0x37, +0xf2, 0x07, 0x24, 0x4d, 0x7b, 0x3b, 0xff, 0xeb, +0xb4, 0x15, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_result_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_result_png = new wxImage(); + if (!img_ex_result_png || !img_ex_result_png->IsOk()) + { + wxMemoryInputStream img_ex_result_pngIS(ex_result_png_data, sizeof(ex_result_png_data)); + img_ex_result_png->LoadFile(img_ex_result_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_result_png; +} +#define ex_result_png_img ex_result_png_img() + +static wxBitmap *ex_result_png_bmp() +{ + static wxBitmap *bmp_ex_result_png; + if (!bmp_ex_result_png || !bmp_ex_result_png->IsOk()) + bmp_ex_result_png = new wxBitmap(*ex_result_png_img); + return bmp_ex_result_png; +} +#define ex_result_png_bmp ex_result_png_bmp() + +static wxIcon *ex_result_png_ico() +{ + static wxIcon *ico_ex_result_png; + if (!ico_ex_result_png || !ico_ex_result_png->IsOk()) + { + ico_ex_result_png = new wxIcon(); + ico_ex_result_png->CopyFromBitmap(*ex_result_png_bmp); + } + return ico_ex_result_png; +} +#define ex_result_png_ico ex_result_png_ico() + +#endif // EX_RESULT_PNG_H diff --git a/include/images/ex_scan.png b/include/images/ex_scan.png new file mode 100644 index 0000000..396dfb4 Binary files /dev/null and b/include/images/ex_scan.png differ diff --git a/include/images/ex_scan.pngc b/include/images/ex_scan.pngc new file mode 100644 index 0000000..dacd795 --- /dev/null +++ b/include/images/ex_scan.pngc @@ -0,0 +1,209 @@ +#ifndef EX_SCAN_PNG_H +#define EX_SCAN_PNG_H + +static const unsigned char ex_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbd, 0xe9, +0x45, 0xbe, 0xe9, 0x75, 0xce, 0xef, 0x79, 0xd0, +0xef, 0x50, 0xc2, 0xea, 0x56, 0xc3, 0xea, 0x83, +0xd3, 0xf0, 0x89, 0xd5, 0xf0, 0x65, 0xc8, 0xec, +0x6a, 0xc9, 0xec, 0x6f, 0xca, 0xec, 0x94, 0xd8, +0xf1, 0x99, 0xda, 0xf1, 0x7b, 0xce, 0xed, 0x82, +0xd1, 0xed, 0xa4, 0xdd, 0xf1, 0xa8, 0xde, 0xf2, +0x8e, 0xd4, 0xee, 0x92, 0xd6, 0xef, 0xaf, 0xe1, +0xf3, 0x05, 0xa7, 0xe1, 0x48, 0xbf, 0xe9, 0x1b, +0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x38, 0xb7, 0xe5, +0x50, 0xbe, 0xe7, 0x55, 0xc0, 0xe7, 0x59, 0xc1, +0xe7, 0x86, 0xd1, 0xed, 0x6b, 0xc7, 0xe8, 0x6f, +0xc8, 0xe9, 0x95, 0xd7, 0xef, 0x7a, 0x9e, 0xa9, +0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0xc1, 0x8f, +0x36, 0xf1, 0xea, 0x87, 0xed, 0xe3, 0x60, 0xee, +0xe3, 0x60, 0xf2, 0xea, 0x87, 0xf3, 0xea, 0x87, +0xef, 0xe3, 0x5f, 0xef, 0xe4, 0x5f, 0xf3, 0xeb, +0x87, 0xf4, 0xeb, 0x87, 0xf0, 0xe4, 0x5f, 0xf1, +0xe4, 0x5f, 0xf5, 0xeb, 0x87, 0xf2, 0xe4, 0x5f, +0xf6, 0xeb, 0x87, 0xe1, 0xef, 0xf7, 0xe7, 0xda, +0x2b, 0xe8, 0xda, 0x2b, 0xe8, 0xda, 0x2a, 0xea, +0xdb, 0x2a, 0xec, 0xdb, 0x2a, 0xee, 0xdb, 0x2a, +0xef, 0xdb, 0x2a, 0xf3, 0xe5, 0x5f, 0xd7, 0xea, +0xf5, 0xe9, 0xda, 0x2a, 0xeb, 0xdb, 0x2a, 0xed, +0xdb, 0x2a, 0xef, 0xdc, 0x2a, 0xf0, 0xdc, 0x2a, +0xf4, 0xe5, 0x5f, 0xd6, 0xe9, 0xf4, 0xf3, 0xe4, +0x5f, 0xf5, 0xe5, 0x5f, 0xf7, 0xeb, 0x87, 0xf8, +0xeb, 0x87, 0xdb, 0xbd, 0x89, 0xd4, 0xe9, 0xf4, +0xf6, 0xe5, 0x5f, 0xd3, 0xe8, 0xf3, 0xf1, 0xdc, +0x2a, 0xf2, 0xdc, 0x2a, 0xf3, 0xdc, 0x2a, 0xf7, +0xe5, 0x5f, 0xd1, 0xe7, 0xf2, 0xf4, 0xdc, 0x2a, +0xf8, 0xe5, 0x5f, 0xf5, 0xdc, 0x2a, 0xf8, 0xe6, +0x5f, 0xf9, 0xeb, 0x87, 0xfa, 0xec, 0x87, 0xce, +0xe6, 0xf2, 0xce, 0xe5, 0xf2, 0xf9, 0xe6, 0x5f, +0xfb, 0xec, 0x86, 0xcc, 0xe5, 0xf1, 0xf5, 0xdd, +0x2a, 0xf7, 0xdd, 0x2a, 0xf8, 0xdd, 0x29, 0xfa, +0xe6, 0x5f, 0xcb, 0xe4, 0xf1, 0xf6, 0xdd, 0x2a, +0xfb, 0xe6, 0x5f, 0xca, 0xe3, 0xf0, 0xf9, 0xdd, +0x29, 0xc8, 0xe3, 0xf0, 0xf9, 0xec, 0x87, 0xfc, +0xec, 0x86, 0xc7, 0xe3, 0xf0, 0xc6, 0xe2, 0xef, +0xfc, 0xe6, 0x5f, 0xfd, 0xec, 0x86, 0xc5, 0xe1, +0xef, 0xfb, 0xde, 0x29, 0xfc, 0xde, 0x29, 0xfd, +0xe6, 0x5f, 0xf7, 0xdd, 0x29, 0xfa, 0xdd, 0x29, +0xfe, 0xe6, 0x5f, 0xc2, 0xe0, 0xee, 0xfd, 0xde, +0x29, 0xfe, 0xec, 0x86, 0xc0, 0xdf, 0xee, 0xb9, +0xdb, 0xec, 0xfe, 0xde, 0x29, 0xff, 0xe6, 0x5f, +0xd4, 0xe9, 0xf3, 0xbe, 0xde, 0xed, 0xad, 0xd6, +0xe9, 0x5f, 0x01, 0x98, 0x46, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xdf, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0xdb, 0x53, 0xda, 0x40, 0x14, +0x87, 0x6d, 0xaa, 0xad, 0xb6, 0xf6, 0xa2, 0xad, +0xd6, 0x5a, 0x7b, 0xb1, 0xad, 0x1c, 0x41, 0x83, +0x24, 0x04, 0x2f, 0x5c, 0x14, 0x30, 0x48, 0xa0, +0x46, 0x21, 0x82, 0x41, 0x45, 0x05, 0x04, 0xb1, +0x2a, 0x0a, 0x94, 0x80, 0x0a, 0xca, 0xbf, 0xde, +0xdd, 0x84, 0x58, 0xd8, 0x81, 0x07, 0x66, 0x3a, +0x9d, 0x3e, 0x78, 0x1e, 0x96, 0x17, 0xbe, 0x3d, +0xf9, 0x7e, 0xe7, 0xcc, 0xf6, 0xf4, 0x3c, 0xd4, +0xbf, 0xae, 0x47, 0x14, 0xae, 0x8e, 0x67, 0x3b, +0x84, 0x7a, 0xdc, 0xdb, 0xd7, 0xf7, 0x84, 0x7a, +0xda, 0x3f, 0x30, 0xf0, 0x8c, 0x7a, 0x3e, 0xf8, +0xe2, 0xe5, 0x2b, 0xea, 0xf5, 0xd0, 0xf0, 0xf0, +0x1b, 0xea, 0xed, 0xc8, 0xe8, 0xe8, 0x3b, 0xaa, +0x2d, 0xd2, 0x3b, 0x36, 0x36, 0xf6, 0x9e, 0xea, +0x1f, 0x1f, 0x1f, 0xff, 0x40, 0x0d, 0x4e, 0x4c, +0x4c, 0xbc, 0xa4, 0x86, 0x3e, 0x7e, 0xfa, 0xfc, +0x85, 0x1a, 0x99, 0x9c, 0xfc, 0xfa, 0x8d, 0xfa, +0x4b, 0x5d, 0xbe, 0xab, 0xdf, 0xdc, 0xf1, 0x6c, +0xf9, 0xef, 0x94, 0xc1, 0x30, 0x85, 0x7e, 0x60, +0xda, 0x68, 0x34, 0x4e, 0xa3, 0xd3, 0x64, 0x9a, +0x81, 0x59, 0x9a, 0x36, 0xcf, 0x81, 0x85, 0x61, +0x58, 0x0b, 0x58, 0x39, 0x8e, 0xb3, 0x41, 0x0b, +0x62, 0x98, 0x9f, 0x37, 0x60, 0xc4, 0xb8, 0xb0, +0xb0, 0x60, 0x04, 0xd3, 0xe2, 0xe2, 0x12, 0x0d, +0xb4, 0xdd, 0x6e, 0x67, 0x80, 0x71, 0x38, 0x1c, +0x1c, 0x70, 0x4e, 0x97, 0x6b, 0x99, 0x40, 0x56, +0x56, 0x9a, 0x91, 0xa5, 0x25, 0x37, 0x0d, 0x66, +0xbb, 0xdd, 0xc3, 0x00, 0xeb, 0xf0, 0x7a, 0x11, +0xe2, 0x5a, 0xe5, 0x7d, 0x04, 0xb2, 0xb6, 0xa6, +0x23, 0x8b, 0x26, 0x30, 0xb9, 0xdd, 0x6e, 0x33, +0x98, 0x3d, 0x1e, 0x0f, 0x0b, 0x9c, 0xd7, 0xeb, +0xe4, 0xc0, 0xcf, 0xf3, 0xbc, 0xd0, 0x1e, 0x99, +0x36, 0x35, 0x5b, 0xb0, 0xf7, 0x16, 0x01, 0x9f, +0x20, 0x04, 0xdb, 0x22, 0x3f, 0x00, 0x57, 0xc7, +0xb3, 0x15, 0x59, 0x5f, 0x57, 0xbb, 0xcc, 0x98, +0x68, 0x7a, 0x16, 0xe6, 0xcc, 0x0c, 0x63, 0x01, +0x0b, 0xcb, 0x71, 0x56, 0xb0, 0xf9, 0x97, 0x7d, +0x01, 0x08, 0x08, 0x82, 0x48, 0x76, 0xd9, 0xd8, +0x50, 0x91, 0x7b, 0x0b, 0x07, 0xb6, 0x70, 0x22, +0x8b, 0x65, 0x9e, 0xdf, 0x14, 0x40, 0x08, 0x85, +0xc3, 0x12, 0x81, 0x6c, 0x6d, 0xa9, 0x08, 0xed, +0xb6, 0xdb, 0xcd, 0xc0, 0x78, 0xb4, 0x60, 0x9d, +0x2e, 0x3f, 0xf8, 0xf8, 0x4d, 0x84, 0x88, 0xe1, +0x48, 0x24, 0xda, 0x01, 0x51, 0x67, 0xc1, 0x3a, +0x1c, 0x6a, 0xb0, 0xae, 0x55, 0x1f, 0x08, 0x9b, +0xa1, 0x90, 0x08, 0x52, 0x24, 0xb2, 0x2d, 0xb7, +0x47, 0x1a, 0x16, 0x9c, 0x66, 0xe1, 0xbb, 0xb7, +0x88, 0x45, 0x65, 0x79, 0x87, 0x40, 0x76, 0x77, +0xbb, 0x4e, 0x6c, 0x6f, 0x4f, 0xed, 0x62, 0x61, +0x59, 0xd6, 0x8a, 0x67, 0xe1, 0xb7, 0xe1, 0xfb, +0xd1, 0x2c, 0x82, 0xa2, 0x24, 0xc5, 0x60, 0x47, +0x8e, 0xc7, 0xf7, 0x89, 0x2e, 0x07, 0x07, 0x2a, +0xa2, 0xaf, 0x87, 0x8b, 0xff, 0x63, 0xb1, 0x7d, +0x28, 0x83, 0x9c, 0x48, 0x24, 0x53, 0x04, 0x72, +0x74, 0xa4, 0x21, 0xda, 0x7a, 0xac, 0xe2, 0xf5, +0xd0, 0x82, 0x95, 0xb6, 0x0f, 0xd3, 0x32, 0xc4, +0x93, 0xc9, 0x64, 0x86, 0x40, 0x8e, 0x8f, 0x55, +0x04, 0x05, 0xeb, 0xd4, 0x83, 0x15, 0xc2, 0xe1, +0x88, 0x04, 0x72, 0x3a, 0x9d, 0x88, 0x43, 0x2a, +0x99, 0xcd, 0x92, 0xc8, 0xc9, 0x89, 0x8a, 0x58, +0x39, 0xbf, 0x3f, 0xa0, 0x5b, 0x48, 0x52, 0xf4, +0x67, 0xc3, 0xe2, 0x34, 0x93, 0xc9, 0x9c, 0x12, +0xc8, 0xd9, 0x59, 0xd7, 0x89, 0x9d, 0x9f, 0xab, +0x5d, 0x6c, 0x3e, 0x9f, 0x10, 0x80, 0xa0, 0x20, +0x8a, 0x31, 0x88, 0xc9, 0x78, 0x16, 0x3b, 0xa9, +0x14, 0xba, 0xff, 0x34, 0x93, 0xcb, 0x5d, 0x10, +0x5d, 0x2e, 0x2f, 0x55, 0xa4, 0x79, 0x3d, 0x1a, +0x16, 0x59, 0x6c, 0x91, 0xcb, 0xe7, 0x0b, 0xc5, +0xf6, 0x08, 0x0e, 0x16, 0x21, 0xea, 0x7a, 0xa0, +0x60, 0x7f, 0xa5, 0x20, 0x93, 0x2d, 0x95, 0x10, +0x52, 0x28, 0x14, 0x14, 0x02, 0x29, 0x97, 0x35, +0x24, 0x14, 0x0a, 0x8b, 0x7a, 0xb0, 0x09, 0x1c, +0x6c, 0xa6, 0x54, 0x2a, 0xe5, 0xa0, 0x58, 0x28, +0x54, 0x3a, 0x20, 0x41, 0x51, 0x94, 0x74, 0x8b, +0xfd, 0x26, 0x8b, 0x0b, 0x45, 0x51, 0xae, 0x08, +0xe4, 0xfa, 0xba, 0xeb, 0xc4, 0x34, 0x04, 0x62, +0x52, 0x54, 0x46, 0xb3, 0x88, 0xc7, 0x53, 0xda, +0x2c, 0xd0, 0xfd, 0xc5, 0x62, 0xf1, 0x0a, 0xae, +0xc8, 0x2e, 0xe8, 0xe1, 0xbb, 0xb9, 0xc1, 0x8f, +0x5f, 0xcb, 0x7a, 0x20, 0x8b, 0x3c, 0xb6, 0xa8, +0x20, 0x0b, 0xa5, 0x5a, 0xad, 0xd6, 0x9a, 0x11, +0xc3, 0xed, 0x5d, 0xbd, 0x7e, 0x77, 0x6b, 0xe8, +0xc1, 0xc1, 0xa6, 0xf5, 0xf5, 0xc8, 0x94, 0xf2, +0xf9, 0x22, 0x14, 0x2b, 0x6d, 0x91, 0x29, 0x43, +0xb9, 0x5e, 0x2f, 0xe3, 0x2e, 0x72, 0x3a, 0x91, +0x48, 0xe1, 0x59, 0xe0, 0x60, 0xf3, 0x05, 0x34, +0x0b, 0xa5, 0x52, 0xad, 0x2a, 0x50, 0x23, 0x11, +0xc4, 0xa0, 0x1d, 0x43, 0x8f, 0x32, 0x69, 0xa1, +0xe8, 0x16, 0x57, 0xb5, 0x5a, 0x8d, 0x48, 0xac, +0xf1, 0x8c, 0x77, 0x93, 0xd8, 0x43, 0xfd, 0x5f, +0xf5, 0x1b, 0x60, 0xd9, 0x1d, 0xe7, 0xe4, 0xbb, +0xd2, 0xdf, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_scan_png = new wxImage(); + if (!img_ex_scan_png || !img_ex_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_scan_pngIS(ex_scan_png_data, sizeof(ex_scan_png_data)); + img_ex_scan_png->LoadFile(img_ex_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_scan_png; +} +#define ex_scan_png_img ex_scan_png_img() + +static wxBitmap *ex_scan_png_bmp() +{ + static wxBitmap *bmp_ex_scan_png; + if (!bmp_ex_scan_png || !bmp_ex_scan_png->IsOk()) + bmp_ex_scan_png = new wxBitmap(*ex_scan_png_img); + return bmp_ex_scan_png; +} +#define ex_scan_png_bmp ex_scan_png_bmp() + +static wxIcon *ex_scan_png_ico() +{ + static wxIcon *ico_ex_scan_png; + if (!ico_ex_scan_png || !ico_ex_scan_png->IsOk()) + { + ico_ex_scan_png = new wxIcon(); + ico_ex_scan_png->CopyFromBitmap(*ex_scan_png_bmp); + } + return ico_ex_scan_png; +} +#define ex_scan_png_ico ex_scan_png_ico() + +#endif // EX_SCAN_PNG_H diff --git a/include/images/ex_seek.png b/include/images/ex_seek.png new file mode 100644 index 0000000..130fbd8 Binary files /dev/null and b/include/images/ex_seek.png differ diff --git a/include/images/ex_seek.pngc b/include/images/ex_seek.pngc new file mode 100644 index 0000000..51ddbcd --- /dev/null +++ b/include/images/ex_seek.pngc @@ -0,0 +1,210 @@ +#ifndef EX_SEEK_PNG_H +#define EX_SEEK_PNG_H + +static const unsigned char ex_seek_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6e, 0xca, 0xec, 0x44, 0xbd, 0xe9, +0x76, 0xce, 0xee, 0x7b, 0xcf, 0xee, 0x4f, 0xc0, +0xe8, 0x55, 0xc2, 0xe9, 0x86, 0xd4, 0xf0, 0x66, +0xc8, 0xec, 0x96, 0xd9, 0xf1, 0x82, 0xd1, 0xed, +0xa6, 0xde, 0xf2, 0x8e, 0xd4, 0xee, 0x92, 0xd6, +0xef, 0xaf, 0xe1, 0xf3, 0x05, 0xa7, 0xe1, 0x1b, +0xae, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, 0xc7, 0xeb, +0x38, 0xb7, 0xe5, 0x6b, 0xc7, 0xe8, 0x72, 0x96, +0xa1, 0x86, 0xa9, 0x64, 0x52, 0x8d, 0x19, 0xc1, +0x8f, 0x36, 0xf4, 0xf0, 0xc8, 0xf0, 0xec, 0xb7, +0xef, 0xeb, 0xb6, 0xf3, 0xef, 0xc7, 0xef, 0xe9, +0xb4, 0xf2, 0xed, 0xc5, 0xee, 0xe6, 0xb3, 0xf1, +0xea, 0xc4, 0xec, 0xe3, 0xb0, 0xa1, 0xc4, 0x5e, +0xeb, 0xe5, 0x9e, 0xea, 0xe3, 0x9c, 0xef, 0xea, +0xb5, 0xe9, 0xe0, 0x9a, 0xef, 0xe8, 0xb3, 0xe8, +0xde, 0x99, 0xe7, 0xdc, 0x97, 0xed, 0xe5, 0xb1, +0xe6, 0xd8, 0x94, 0xec, 0xe0, 0xad, 0xec, 0xe2, +0xaf, 0xe4, 0xd5, 0x92, 0xec, 0xe1, 0xae, 0xeb, +0xdf, 0xad, 0xed, 0xe6, 0xb2, 0xf0, 0xe8, 0xc2, +0xef, 0xe6, 0xc0, 0xc7, 0xaa, 0x75, 0xf0, 0xe6, +0xc0, 0xea, 0xdc, 0xaa, 0xef, 0xe3, 0xbe, 0xe3, +0xd2, 0x8f, 0xe2, 0xd0, 0x8d, 0xe9, 0xd9, 0xa8, +0xe4, 0xd3, 0x90, 0xe2, 0xce, 0x8c, 0xe1, 0xcc, +0x8b, 0xe8, 0xd8, 0xa7, 0xed, 0xe1, 0xbc, 0x5e, +0x97, 0x24, 0xc1, 0xc8, 0xba, 0xc4, 0x9a, 0x50, +0xa5, 0xcc, 0x64, 0x74, 0xa7, 0x38, 0x9e, 0xb5, +0x87, 0xae, 0xd9, 0x71, 0xf1, 0xea, 0x87, 0xed, +0xe3, 0x60, 0xee, 0xe3, 0x5d, 0xf3, 0xe8, 0x83, +0xef, 0xe0, 0x59, 0xf3, 0xe7, 0x80, 0xf0, 0xe0, +0x56, 0xf0, 0xdf, 0x54, 0xf4, 0xe6, 0x7d, 0x8f, +0xc0, 0x53, 0xb1, 0xde, 0x74, 0x00, 0x00, 0x00, +0xe7, 0xda, 0x2a, 0xe8, 0xd9, 0x28, 0xe9, 0xd8, +0x25, 0xea, 0xd6, 0x22, 0xeb, 0xd4, 0x1c, 0x7d, +0xb2, 0x43, 0xab, 0xd4, 0x6c, 0xb3, 0xe2, 0x77, +0xea, 0xd5, 0x1f, 0xec, 0xd3, 0x18, 0xf2, 0xdd, +0x51, 0x70, 0x9d, 0x45, 0x61, 0x95, 0x2f, 0xf5, +0xe4, 0x7a, 0xe8, 0xd7, 0xa6, 0xe7, 0xd4, 0xa4, +0xec, 0xdc, 0xb9, 0xe6, 0xd1, 0xa2, 0xe0, 0xc9, +0x89, 0xdf, 0xc7, 0x86, 0xde, 0xc4, 0x85, 0xe6, +0xd3, 0xa4, 0xdd, 0xc3, 0x84, 0xdc, 0xc0, 0x82, +0xdf, 0xc8, 0x88, 0xdc, 0xbf, 0x80, 0xe4, 0xce, +0xa0, 0xa9, 0xda, 0x6e, 0x9e, 0xd1, 0x64, 0xbc, +0xf0, 0x84, 0xf2, 0xdd, 0x4e, 0xf3, 0xdb, 0x4c, +0xf7, 0xe3, 0x76, 0xf4, 0xda, 0x48, 0x8b, 0xab, +0x6c, 0xa0, 0xd5, 0x67, 0xee, 0xd0, 0x14, 0xee, +0xcf, 0x10, 0xef, 0xce, 0x0e, 0xf3, 0xda, 0x4a, +0xf0, 0xcd, 0x0b, 0xbf, 0xc7, 0xb7, 0xa2, 0xd7, +0x69, 0xbe, 0x39, 0x46, 0x36, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xe5, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd2, 0xd9, 0x53, 0xda, 0x50, 0x14, +0x07, 0x60, 0x1b, 0x70, 0xab, 0x5b, 0xb5, 0xd5, +0x9a, 0x03, 0x88, 0x81, 0x0a, 0xc8, 0x26, 0x52, +0xac, 0xc8, 0x22, 0x6a, 0xab, 0x45, 0x30, 0x82, +0x18, 0x40, 0x94, 0x45, 0x05, 0x82, 0x28, 0x4a, +0x2b, 0x88, 0x05, 0xb4, 0xfe, 0xeb, 0xbd, 0xb9, +0x2c, 0x89, 0x4e, 0xe2, 0x8c, 0x33, 0x9d, 0x4e, +0x1f, 0xbc, 0x0f, 0xf7, 0x29, 0xdf, 0x3d, 0xf9, +0x9d, 0x73, 0x7a, 0x7a, 0x5e, 0xcf, 0xbf, 0x3f, +0x6f, 0x08, 0xee, 0x48, 0xde, 0x62, 0x84, 0x90, +0xc9, 0xe5, 0xf2, 0x5e, 0xa2, 0xaf, 0x7f, 0x60, +0x60, 0x90, 0x18, 0x7c, 0x2b, 0x93, 0x0d, 0x11, +0x43, 0x7d, 0xc3, 0xc3, 0x23, 0xc4, 0xc8, 0xe8, +0xd8, 0xd8, 0x3b, 0x42, 0x94, 0xc8, 0xc7, 0xc7, +0xc7, 0xe5, 0x44, 0xff, 0xc4, 0xc4, 0xc4, 0x7b, +0xe2, 0xc3, 0xe4, 0xe4, 0xa4, 0x8c, 0xe8, 0x45, +0x7c, 0x98, 0x18, 0x9d, 0x9a, 0x92, 0x8d, 0x11, +0x7f, 0xa9, 0xca, 0x47, 0xfc, 0xcf, 0x92, 0x77, +0xfb, 0xab, 0x69, 0x72, 0x9a, 0x27, 0xa0, 0x50, +0x2a, 0x95, 0x0a, 0xee, 0x56, 0x29, 0x60, 0x46, +0xad, 0x56, 0xcf, 0xc2, 0x2c, 0x45, 0x51, 0x1a, +0xd0, 0x68, 0xb5, 0x5a, 0x0d, 0xb4, 0xbf, 0x22, +0x3f, 0x91, 0x02, 0xa2, 0x9c, 0x9b, 0x9b, 0x53, +0x82, 0x52, 0xa7, 0xd3, 0xe9, 0x41, 0x6d, 0x30, +0x18, 0xe6, 0x81, 0x32, 0x9a, 0x4c, 0x66, 0xd0, +0x5a, 0x2c, 0x16, 0xeb, 0x73, 0x44, 0x85, 0x88, +0x9a, 0x23, 0x46, 0x0a, 0x28, 0x93, 0xc9, 0xa4, +0x85, 0x05, 0x8b, 0xc5, 0xf6, 0x0c, 0x51, 0x81, +0x1e, 0x93, 0x79, 0xa3, 0x11, 0x11, 0xb3, 0xc9, +0x64, 0xd1, 0xc2, 0xa2, 0xcd, 0x66, 0xb3, 0x8b, +0x13, 0x85, 0x52, 0xa5, 0x9a, 0xe1, 0x53, 0x7c, +0xc6, 0x29, 0x16, 0x1c, 0xe0, 0xb0, 0xda, 0xed, +0x4b, 0xa2, 0xe4, 0x0b, 0x70, 0x47, 0xf2, 0x16, +0xaf, 0xa2, 0xd7, 0xab, 0x51, 0x95, 0x79, 0x8a, +0x42, 0x55, 0xcc, 0x66, 0xd4, 0x25, 0xcd, 0xa2, +0xd5, 0xea, 0x80, 0x65, 0xa7, 0xd3, 0xb9, 0x22, +0xfe, 0x63, 0x28, 0x85, 0x81, 0x4f, 0x61, 0xe9, +0xa6, 0x70, 0xba, 0xdc, 0x6e, 0x8f, 0x38, 0x51, +0xeb, 0x5a, 0x8d, 0x35, 0xb6, 0x1b, 0xbb, 0x08, +0x56, 0x9b, 0xcd, 0xeb, 0x04, 0xa7, 0xdb, 0xbd, +0x2a, 0x45, 0xd0, 0x2c, 0x3a, 0x8d, 0x6d, 0xcd, +0xc2, 0xee, 0x75, 0xb9, 0x10, 0x59, 0xf5, 0xf9, +0x24, 0xc8, 0x2c, 0x4e, 0xa1, 0xc1, 0x29, 0x1c, +0x82, 0x14, 0x2b, 0x1e, 0xcf, 0xda, 0x3a, 0x4f, +0x36, 0xbe, 0x76, 0xf7, 0xe6, 0x1b, 0xee, 0x8c, +0xe4, 0xdd, 0x21, 0x9b, 0x5b, 0xdf, 0x91, 0x21, +0xfd, 0x9c, 0x81, 0xed, 0x40, 0x20, 0xb0, 0xdd, +0xbd, 0x83, 0xc1, 0x1d, 0xd8, 0xa1, 0x69, 0x7a, +0x07, 0x76, 0x43, 0xa1, 0xf0, 0x5e, 0xb7, 0xca, +0x66, 0x64, 0x6b, 0x83, 0x24, 0x49, 0xff, 0x3e, +0x32, 0x10, 0x60, 0xa2, 0x4c, 0x00, 0x02, 0xd1, +0x68, 0x34, 0x00, 0xc1, 0x58, 0x2c, 0x1e, 0x04, +0xfa, 0xe0, 0xe0, 0x80, 0x86, 0x50, 0x22, 0x91, +0x08, 0xf3, 0xe4, 0x30, 0xb2, 0x79, 0xe4, 0xf7, +0xef, 0x27, 0x93, 0x24, 0x22, 0x51, 0x26, 0x8a, +0x49, 0x2c, 0x08, 0xc1, 0x78, 0x3c, 0x4e, 0x23, +0x92, 0x4a, 0x85, 0x20, 0x9c, 0x48, 0xa7, 0x33, +0x3c, 0x21, 0x8f, 0x4f, 0x50, 0x15, 0x24, 0xf8, +0x2a, 0xb1, 0x58, 0x8b, 0xa0, 0xf7, 0xe9, 0x54, +0x0a, 0xbd, 0x1f, 0x4e, 0x0b, 0xc9, 0x11, 0xee, +0x18, 0x99, 0x14, 0x66, 0x09, 0x3e, 0x4d, 0xb1, +0x97, 0xc9, 0x64, 0x4e, 0x9f, 0x90, 0x17, 0x75, +0xcc, 0x2f, 0x9c, 0x8b, 0xc3, 0x6a, 0xb5, 0x2f, +0xc3, 0x52, 0x7b, 0x16, 0x6b, 0xd9, 0x75, 0x58, +0xcf, 0xe5, 0x72, 0x79, 0xc8, 0xb3, 0x2c, 0x9b, +0x07, 0x51, 0x22, 0x5c, 0x0f, 0x8f, 0xaf, 0x50, +0xc8, 0x42, 0xee, 0xac, 0x58, 0x3c, 0x07, 0xf6, +0xa2, 0x54, 0x62, 0xbb, 0x64, 0x5f, 0x48, 0xec, +0x5e, 0x2f, 0x5e, 0x8f, 0x55, 0xb4, 0x1e, 0xd9, +0x42, 0xe1, 0x32, 0x07, 0xb9, 0x62, 0xf1, 0x82, +0x05, 0xb6, 0x54, 0xba, 0x2a, 0x4b, 0x10, 0x97, +0xcb, 0xed, 0x44, 0xef, 0xfb, 0x7c, 0x6b, 0x90, +0xbd, 0x3c, 0x3b, 0xcb, 0xc1, 0x79, 0xf1, 0x02, +0x93, 0x2b, 0x01, 0x49, 0x0a, 0x89, 0x54, 0x8a, +0x7c, 0xb9, 0x5c, 0xee, 0x66, 0x39, 0xf9, 0xf1, +0xe2, 0x1d, 0x3b, 0xfe, 0x79, 0x88, 0x77, 0xec, +0x1a, 0xcf, 0x85, 0x9b, 0xc5, 0x2e, 0xec, 0x86, +0xc3, 0xad, 0x59, 0x54, 0x4e, 0xe1, 0xb4, 0x5a, +0xad, 0xde, 0xc0, 0x4d, 0xad, 0x56, 0xbb, 0xe9, +0x54, 0xb9, 0x8d, 0xfc, 0x3a, 0xe4, 0x76, 0xec, +0x9a, 0x33, 0x40, 0x33, 0x29, 0x26, 0xd4, 0x9e, +0x75, 0xa6, 0x5e, 0xaf, 0x57, 0xa0, 0xda, 0x68, +0x36, 0xef, 0xa0, 0x76, 0x7f, 0x7f, 0x5f, 0xeb, +0x90, 0xdf, 0xb7, 0x91, 0x87, 0xe4, 0x35, 0x3e, +0x68, 0xc7, 0xe8, 0x14, 0xd3, 0x5d, 0x8f, 0x4a, +0xbd, 0xde, 0xa8, 0xc2, 0x5d, 0xb3, 0xd9, 0xac, +0x3d, 0x26, 0xc8, 0xe0, 0x1d, 0x6b, 0x55, 0x09, +0x31, 0x09, 0x26, 0x0c, 0x99, 0x74, 0xbd, 0x8e, +0x48, 0xa3, 0x81, 0x09, 0xf7, 0xf1, 0x63, 0xd2, +0x6e, 0x5c, 0x2b, 0x4b, 0x27, 0x45, 0xa5, 0x95, +0xe2, 0xae, 0x93, 0xe2, 0x51, 0x96, 0xf6, 0x79, +0x49, 0xc7, 0x5e, 0xcf, 0xff, 0x77, 0xfe, 0x00, +0x08, 0x01, 0xf7, 0x1f, 0x25, 0x73, 0x2a, 0xde, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_seek_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_seek_png = new wxImage(); + if (!img_ex_seek_png || !img_ex_seek_png->IsOk()) + { + wxMemoryInputStream img_ex_seek_pngIS(ex_seek_png_data, sizeof(ex_seek_png_data)); + img_ex_seek_png->LoadFile(img_ex_seek_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_seek_png; +} +#define ex_seek_png_img ex_seek_png_img() + +static wxBitmap *ex_seek_png_bmp() +{ + static wxBitmap *bmp_ex_seek_png; + if (!bmp_ex_seek_png || !bmp_ex_seek_png->IsOk()) + bmp_ex_seek_png = new wxBitmap(*ex_seek_png_img); + return bmp_ex_seek_png; +} +#define ex_seek_png_bmp ex_seek_png_bmp() + +static wxIcon *ex_seek_png_ico() +{ + static wxIcon *ico_ex_seek_png; + if (!ico_ex_seek_png || !ico_ex_seek_png->IsOk()) + { + ico_ex_seek_png = new wxIcon(); + ico_ex_seek_png->CopyFromBitmap(*ex_seek_png_bmp); + } + return ico_ex_seek_png; +} +#define ex_seek_png_ico ex_seek_png_ico() + +#endif // EX_SEEK_PNG_H diff --git a/include/images/ex_setop.png b/include/images/ex_setop.png new file mode 100644 index 0000000..f3a9b19 Binary files /dev/null and b/include/images/ex_setop.png differ diff --git a/include/images/ex_setop.pngc b/include/images/ex_setop.pngc new file mode 100644 index 0000000..8dd4e3b --- /dev/null +++ b/include/images/ex_setop.pngc @@ -0,0 +1,187 @@ +#ifndef EX_SETOP_PNG_H +#define EX_SETOP_PNG_H + +static const unsigned char ex_setop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb8, 0xb9, 0xd0, 0x9e, +0xa0, 0xd0, 0x88, 0x8b, 0xd1, 0x76, 0x7a, 0xd1, +0x6a, 0x6f, 0xd1, 0xcd, 0xc1, 0xad, 0xc9, 0xb2, +0x8b, 0xc6, 0xa4, 0x67, 0xc3, 0x99, 0x4e, 0xc2, +0x92, 0x3c, 0x93, 0x95, 0xd1, 0x7f, 0x83, 0xd9, +0x9a, 0x9d, 0xe1, 0xb1, 0xb3, 0xea, 0xbd, 0xbe, +0xed, 0xc8, 0xc8, 0xf0, 0xc1, 0xc2, 0xee, 0xb4, +0xb5, 0xea, 0x9e, 0xa2, 0xe2, 0x81, 0x85, 0xd9, +0xc7, 0xaa, 0x76, 0xcc, 0xa3, 0x57, 0xd9, 0xbc, +0x7d, 0xe4, 0xd1, 0x9a, 0xea, 0xdd, 0xa8, 0xed, +0xe6, 0xb3, 0xe3, 0xcd, 0x95, 0xa2, 0xa4, 0xd0, +0xa7, 0xa9, 0xe7, 0xbb, 0xbc, 0xed, 0xb8, 0xb9, +0xeb, 0xb7, 0xb8, 0xeb, 0xae, 0xb0, 0xe9, 0xe0, +0xc8, 0x8e, 0xec, 0xe5, 0xab, 0xeb, 0xe3, 0xa3, +0xe9, 0xe1, 0x9b, 0xcc, 0xcb, 0xcb, 0x94, 0x97, +0xdf, 0xb6, 0xb7, 0xeb, 0xb0, 0xb2, 0xe9, 0xb2, +0xb3, 0xea, 0xba, 0xbb, 0xec, 0xbe, 0xc1, 0xee, +0x6d, 0x99, 0xd3, 0x68, 0x8b, 0xb6, 0xd8, 0xd3, +0xaa, 0xe8, 0xde, 0x98, 0xe7, 0xdc, 0x97, 0xea, +0xdd, 0xa5, 0xe6, 0xd4, 0xa3, 0xd7, 0xb7, 0x78, +0xad, 0xaf, 0xe8, 0x7a, 0xa5, 0xd7, 0x64, 0xad, +0xd7, 0x65, 0x93, 0xbf, 0xe6, 0xda, 0x96, 0xe8, +0xdb, 0x9a, 0xad, 0xae, 0xe8, 0xaa, 0xac, 0xe8, +0x84, 0xa9, 0xda, 0x5a, 0xaa, 0xd6, 0x5f, 0xc4, +0xe9, 0x66, 0xc6, 0xe9, 0x76, 0x98, 0xb7, 0xe6, +0xd9, 0x95, 0xe6, 0xd8, 0x94, 0xe5, 0xd7, 0x93, +0xe5, 0xd6, 0x92, 0xd6, 0xb5, 0x75, 0x9f, 0xb3, +0xe3, 0x49, 0x96, 0xca, 0x53, 0xbd, 0xe6, 0x35, +0xb7, 0xe6, 0x4a, 0xbd, 0xe6, 0x75, 0xc8, 0xe8, +0x53, 0x9d, 0xcd, 0xa6, 0xb0, 0xa7, 0xe4, 0xd5, +0x92, 0xe4, 0xd4, 0x91, 0xe6, 0xd6, 0x98, 0xa4, +0xa7, 0xe4, 0xa8, 0xaa, 0xe7, 0x5b, 0xb4, 0xde, +0x29, 0xb3, 0xe4, 0x3a, 0xb8, 0xe5, 0x75, 0xb7, +0xdc, 0x5f, 0x8e, 0xbd, 0xe4, 0xd3, 0x90, 0xe3, +0xd2, 0x8f, 0xdd, 0xc2, 0x88, 0x20, 0xb0, 0xe4, +0x81, 0xcd, 0xea, 0xe3, 0xd0, 0x8e, 0xb3, 0xb4, +0xea, 0x18, 0xad, 0xe3, 0xe2, 0xce, 0x8c, 0xe1, +0xcc, 0x8b, 0xaa, 0xad, 0xe6, 0x61, 0x99, 0xcf, +0x1e, 0xb0, 0xe4, 0x84, 0xc3, 0xe2, 0x52, 0x8a, +0xc0, 0xe1, 0xcb, 0x8a, 0xdf, 0xc6, 0x8f, 0xb5, +0xb6, 0xea, 0x8c, 0xcd, 0xe9, 0x40, 0x86, 0xc2, +0xe0, 0xca, 0x89, 0xe5, 0xcf, 0xa0, 0x3a, 0x89, +0xc3, 0x0f, 0xab, 0xe3, 0x90, 0xd3, 0xec, 0xe0, +0xc9, 0x88, 0xdf, 0xc8, 0x89, 0xdf, 0xc7, 0x87, +0xde, 0xc5, 0x85, 0xe2, 0xcb, 0x9a, 0xde, 0xc4, +0x85, 0xde, 0xc2, 0x8e, 0xdd, 0xc2, 0x83, 0xdb, +0xbd, 0x84, 0xdc, 0xc0, 0x82, 0xe0, 0xc7, 0x93, +0xd3, 0xb0, 0x6f, 0xd2, 0xc4, 0x9f, 0xde, 0xc5, +0x8a, 0x27, 0x40, 0xc4, 0x43, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd4, 0x6b, 0x53, 0xda, 0x40, 0x14, +0x06, 0x60, 0xee, 0xb7, 0x88, 0x5c, 0x1a, 0x02, +0x31, 0x0a, 0x18, 0x40, 0xc5, 0x80, 0x85, 0x02, +0x52, 0x2a, 0x55, 0xac, 0x2d, 0x82, 0xa8, 0xad, +0x55, 0xd0, 0x4a, 0x4b, 0x85, 0xde, 0xb4, 0x2d, +0xd8, 0x1a, 0x0c, 0x04, 0xb0, 0xfe, 0x75, 0x37, +0x40, 0x92, 0x25, 0x98, 0x19, 0xa7, 0x33, 0xed, +0x27, 0xce, 0x37, 0x66, 0x78, 0xe6, 0xbc, 0xbb, +0x39, 0x7b, 0x14, 0x8a, 0x49, 0x4d, 0xea, 0x3f, +0x96, 0x52, 0xa5, 0xd6, 0x68, 0xb5, 0x1a, 0xb5, +0x4a, 0x39, 0xf8, 0xad, 0xd3, 0x1b, 0x8c, 0x26, +0x93, 0xd1, 0xa0, 0xd7, 0xc9, 0x01, 0x64, 0xca, +0x3c, 0x6d, 0xb1, 0x5a, 0x6d, 0xf6, 0x47, 0x28, +0x02, 0x90, 0xce, 0x81, 0x39, 0x5d, 0xf8, 0xcc, +0x0c, 0x4e, 0x38, 0x31, 0xc7, 0xbd, 0x68, 0x16, +0x9d, 0xb3, 0xb8, 0x3d, 0x5e, 0xaf, 0xc7, 0x62, +0xb3, 0x5a, 0xe7, 0xd1, 0x59, 0x3d, 0x46, 0xfa, +0x7c, 0x7e, 0x7f, 0x20, 0x10, 0xf0, 0xfb, 0x70, +0x12, 0xd3, 0x8f, 0x81, 0x05, 0x64, 0x71, 0xc9, +0x3b, 0x1d, 0x5c, 0xb6, 0x2f, 0x79, 0x28, 0x37, +0x40, 0xa1, 0xf0, 0xca, 0x63, 0x1f, 0xf7, 0xff, +0x40, 0x24, 0x12, 0x89, 0x46, 0x9e, 0xc4, 0xe2, +0x8e, 0x05, 0x09, 0x41, 0xcc, 0x54, 0x30, 0x31, +0xcf, 0x93, 0x50, 0x68, 0x35, 0x99, 0x7c, 0xca, +0x83, 0x68, 0x34, 0x95, 0x7a, 0x86, 0x3b, 0x1d, +0x92, 0x54, 0x8b, 0xd4, 0x5a, 0x7a, 0x4d, 0x24, +0xcf, 0xd7, 0x37, 0x32, 0xc9, 0x4d, 0x0e, 0x00, +0x91, 0x7a, 0xb1, 0xf5, 0xf2, 0xd5, 0x16, 0x9e, +0x1d, 0xc9, 0xa6, 0x44, 0xed, 0x89, 0x34, 0x44, +0xb6, 0x73, 0xf9, 0x9d, 0xc2, 0xee, 0xde, 0xfe, +0xa0, 0x05, 0x27, 0x5e, 0xbf, 0x39, 0x70, 0x61, +0xf0, 0x1d, 0x20, 0x6f, 0x97, 0x0f, 0x61, 0x12, +0x3e, 0xda, 0x29, 0x96, 0x32, 0xc7, 0x27, 0x11, +0x01, 0xbc, 0x3b, 0x3d, 0x3d, 0x28, 0x43, 0xd1, +0x94, 0x53, 0x9e, 0x34, 0x4c, 0xb6, 0x73, 0x85, +0xf7, 0xc5, 0x52, 0xfe, 0xc3, 0xde, 0x3e, 0x00, +0x43, 0x51, 0xa9, 0x54, 0x62, 0x50, 0x1b, 0x95, +0xf9, 0xe3, 0x1c, 0x4c, 0x56, 0xd7, 0x8b, 0x67, +0xc5, 0x52, 0x61, 0xf7, 0x78, 0x33, 0x25, 0x80, +0x6a, 0xb5, 0xe6, 0x8a, 0x8b, 0xa7, 0x51, 0x7f, +0x4a, 0x8c, 0x90, 0xcf, 0x47, 0x5f, 0x38, 0x92, +0xf9, 0xfa, 0x6d, 0x98, 0x89, 0x03, 0xb5, 0x73, +0xe2, 0xc2, 0x20, 0x10, 0xcd, 0xf7, 0xf4, 0x08, +0xc9, 0xe5, 0xcf, 0xfa, 0xe4, 0xc7, 0x4f, 0xb1, +0x45, 0xed, 0xbc, 0x5e, 0x6b, 0x18, 0x05, 0xa2, +0x75, 0x1f, 0xc2, 0x84, 0xba, 0x2c, 0xfc, 0xe2, +0xc8, 0xc6, 0xef, 0x4b, 0xb1, 0x45, 0xfd, 0x8a, +0xa6, 0x63, 0x26, 0x39, 0xe2, 0x16, 0x49, 0x1f, +0x54, 0xfb, 0xa0, 0xd9, 0x6c, 0x42, 0x44, 0x12, +0x8c, 0xca, 0x15, 0xf8, 0x60, 0x7c, 0xa6, 0x2b, +0x00, 0xae, 0x69, 0xc6, 0xf8, 0x80, 0xe3, 0xf3, +0x99, 0x00, 0xb8, 0x6e, 0x91, 0x6d, 0xc3, 0x03, +0x2e, 0x59, 0x6c, 0xd1, 0x62, 0x59, 0x02, 0x1a, +0x19, 0xf9, 0x4f, 0x59, 0x1f, 0xb6, 0x68, 0x01, +0xd1, 0x62, 0xe0, 0x89, 0x91, 0x0c, 0x4c, 0x88, +0x1f, 0x98, 0x3a, 0x9f, 0x89, 0x05, 0x45, 0x76, +0xe0, 0x59, 0x96, 0x1b, 0xcb, 0xe6, 0x20, 0x13, +0x27, 0xba, 0xe5, 0xde, 0xc8, 0x58, 0xca, 0x0c, +0x3f, 0x2d, 0xb4, 0xe8, 0x76, 0x59, 0xe6, 0x46, +0xf2, 0x30, 0x25, 0x4f, 0xcc, 0x06, 0x9e, 0xd8, +0x09, 0x7f, 0x6c, 0x00, 0xba, 0x65, 0x26, 0x2b, +0x79, 0x62, 0x63, 0x0f, 0xd9, 0x12, 0x5e, 0xf9, +0x43, 0xd0, 0xc3, 0x4c, 0x5d, 0xf6, 0xa2, 0x77, +0x33, 0xf6, 0x90, 0x25, 0xeb, 0x22, 0xc1, 0xad, +0x8b, 0x4e, 0x83, 0x20, 0x6f, 0xc1, 0x4d, 0xdd, +0xf6, 0x98, 0xce, 0x3d, 0xeb, 0xa2, 0xbf, 0x94, +0x50, 0x73, 0x70, 0x74, 0x29, 0xc5, 0xdb, 0x4c, +0xa3, 0xc1, 0xb4, 0xb3, 0x32, 0x4b, 0x49, 0xf1, +0x17, 0xab, 0x6f, 0x52, 0x93, 0xfa, 0x27, 0x75, +0x07, 0x79, 0xe0, 0xdd, 0x95, 0xa0, 0xf6, 0xda, +0x07, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, +0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_setop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_setop_png = new wxImage(); + if (!img_ex_setop_png || !img_ex_setop_png->IsOk()) + { + wxMemoryInputStream img_ex_setop_pngIS(ex_setop_png_data, sizeof(ex_setop_png_data)); + img_ex_setop_png->LoadFile(img_ex_setop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_setop_png; +} +#define ex_setop_png_img ex_setop_png_img() + +static wxBitmap *ex_setop_png_bmp() +{ + static wxBitmap *bmp_ex_setop_png; + if (!bmp_ex_setop_png || !bmp_ex_setop_png->IsOk()) + bmp_ex_setop_png = new wxBitmap(*ex_setop_png_img); + return bmp_ex_setop_png; +} +#define ex_setop_png_bmp ex_setop_png_bmp() + +static wxIcon *ex_setop_png_ico() +{ + static wxIcon *ico_ex_setop_png; + if (!ico_ex_setop_png || !ico_ex_setop_png->IsOk()) + { + ico_ex_setop_png = new wxIcon(); + ico_ex_setop_png->CopyFromBitmap(*ex_setop_png_bmp); + } + return ico_ex_setop_png; +} +#define ex_setop_png_ico ex_setop_png_ico() + +#endif // EX_SETOP_PNG_H diff --git a/include/images/ex_sort.png b/include/images/ex_sort.png new file mode 100644 index 0000000..1d46fd3 Binary files /dev/null and b/include/images/ex_sort.png differ diff --git a/include/images/ex_sort.pngc b/include/images/ex_sort.pngc new file mode 100644 index 0000000..57c95a8 --- /dev/null +++ b/include/images/ex_sort.pngc @@ -0,0 +1,189 @@ +#ifndef EX_SORT_PNG_H +#define EX_SORT_PNG_H + +static const unsigned char ex_sort_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x75, 0xa6, 0xc7, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x43, 0xbd, 0xe9, +0x4c, 0xc0, 0xe9, 0x53, 0xc2, 0xea, 0x5d, 0xc5, +0xeb, 0x66, 0xc8, 0xec, 0x71, 0xcb, 0xec, 0x7a, +0xce, 0xec, 0x83, 0xd1, 0xed, 0x8b, 0xd4, 0xee, +0xad, 0xdf, 0xf3, 0x07, 0xa8, 0xe2, 0x15, 0xad, +0xe3, 0x2d, 0xb4, 0xe5, 0x41, 0xba, 0xe5, 0x4e, +0xbe, 0xe6, 0x5a, 0xc1, 0xe7, 0x64, 0xc5, 0xe8, +0x92, 0xd5, 0xef, 0x72, 0x96, 0xa1, 0xff, 0x68, +0x68, 0xff, 0xe7, 0xe7, 0xff, 0xde, 0xde, 0x48, +0xd6, 0x01, 0xda, 0xff, 0xc8, 0xcc, 0xff, 0xb3, +0xff, 0xd4, 0xd4, 0x00, 0x00, 0x00, 0xff, 0xd1, +0xd1, 0xff, 0xdc, 0xdc, 0xbd, 0xff, 0x9c, 0xbb, +0xff, 0x99, 0xb9, 0xff, 0x95, 0xc8, 0xff, 0xac, +0xff, 0xda, 0xda, 0xb7, 0xff, 0x92, 0xff, 0xcd, +0xcd, 0xb5, 0xff, 0x8f, 0xff, 0xe2, 0xe2, 0xd2, +0xff, 0xbb, 0xff, 0x3d, 0x3d, 0x4d, 0xe7, 0x01, +0xbb, 0x9b, 0x01, 0xff, 0xee, 0x9e, 0xff, 0xeb, +0x88, 0xff, 0xea, 0x83, 0xff, 0xe8, 0x7a, 0xfd, +0xe6, 0x75, 0x7a, 0x8f, 0xff, 0xe9, 0xed, 0xff, +0xe1, 0xe6, 0xff, 0xdf, 0xe5, 0xff, 0xdd, 0xe2, +0xff, 0xe5, 0xea, 0xff, 0xff, 0xe3, 0x57, 0xff, +0xe0, 0x4b, 0xff, 0xdf, 0x44, 0xff, 0xe6, 0x6b, +0xd6, 0xdd, 0xff, 0xd4, 0xdb, 0xff, 0xd1, 0xd9, +0xff, 0xce, 0xd6, 0xff, 0xcb, 0xd4, 0xff, 0xd9, +0xdf, 0xff, 0xff, 0xdd, 0x38, 0xff, 0xe5, 0x64, +0xca, 0xd3, 0xff, 0x86, 0xa9, 0x64, 0x52, 0x8d, +0x19, 0xd7, 0xb2, 0x01, 0xab, 0xd4, 0x6c, 0x48, +0x65, 0xff, 0xb3, 0xff, 0x8c, 0xb0, 0xff, 0x89, +0xaf, 0xdb, 0x72, 0xb3, 0xe1, 0x77, 0xff, 0xc9, +0xc9, 0xa6, 0xff, 0x78, 0xa1, 0xff, 0x72, 0x9c, +0xff, 0x6a, 0x97, 0xff, 0x62, 0x93, 0xff, 0x5c, +0xad, 0xff, 0x83, 0xa2, 0xc5, 0x5f, 0xa5, 0xcb, +0x64, 0xb0, 0xdc, 0x73, 0xb7, 0xe7, 0x7c, 0xb9, +0xec, 0x80, 0xff, 0xc5, 0xc5, 0xff, 0xbd, 0xbd, +0xff, 0xb9, 0xb9, 0xff, 0xb5, 0xb5, 0x8d, 0xff, +0x53, 0xa9, 0xff, 0x7e, 0xff, 0xc1, 0xc1, 0x99, +0xff, 0x65, 0x0c, 0xc5, 0xff, 0xc0, 0xf0, 0xff, +0xa6, 0xe9, 0xff, 0x9e, 0xe8, 0xff, 0x9c, 0xe7, +0xff, 0xb6, 0xee, 0xff, 0x85, 0xe2, 0xff, 0x7f, +0xe0, 0xff, 0x7c, 0xdf, 0xff, 0x76, 0xde, 0xff, +0x96, 0xe6, 0xff, 0x72, 0xdd, 0xff, 0xa2, 0xe9, +0xff, 0x93, 0xe5, 0xff, 0xac, 0xeb, 0xff, 0x07, +0xc4, 0xff, 0xc6, 0xd0, 0xff, 0xc4, 0xcd, 0xff, +0xc2, 0xcc, 0xff, 0xc1, 0xcb, 0xff, 0xb0, 0x99, +0x2d, 0xec, 0xd5, 0x69, 0xe9, 0xd2, 0x66, 0xf6, +0xdf, 0x73, 0xb1, 0xbe, 0xff, 0xad, 0xba, 0xff, +0xda, 0xc3, 0x57, 0xf7, 0xe0, 0x74, 0xd1, 0xba, +0x4e, 0x9a, 0xbf, 0x84, 0x8f, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x3c, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0xd3, 0xeb, 0x57, 0x12, 0x41, 0x18, +0xc0, 0xe1, 0x95, 0xec, 0x7e, 0xd1, 0x6e, 0xae, +0x22, 0xbc, 0x0b, 0x2c, 0x17, 0x6f, 0xdc, 0x24, +0x40, 0x8b, 0x8b, 0x18, 0xb2, 0x22, 0xa6, 0x88, +0x90, 0x15, 0x26, 0xd8, 0x26, 0x68, 0x85, 0x91, +0x08, 0x48, 0xbb, 0xe5, 0xbf, 0xde, 0x0c, 0xb0, +0xad, 0x33, 0xed, 0x9e, 0x83, 0x7d, 0xe8, 0xf4, +0xc1, 0xdf, 0x7c, 0xdb, 0xf7, 0x3c, 0x67, 0x98, +0xdd, 0x81, 0x61, 0xae, 0xfa, 0x47, 0x0d, 0x19, +0xd4, 0x86, 0x06, 0x9b, 0x18, 0xae, 0x0d, 0x5f, +0xbf, 0x71, 0xf3, 0xd6, 0xed, 0x3b, 0x77, 0xef, +0xdd, 0x37, 0x30, 0x03, 0x4d, 0x0c, 0xc3, 0x0f, +0x46, 0x46, 0x46, 0x47, 0x1f, 0x3e, 0x7a, 0xfc, +0xe4, 0x29, 0x45, 0xf4, 0x26, 0x7f, 0xb1, 0xcb, +0xd8, 0x85, 0x5f, 0x3c, 0xc6, 0x0c, 0x34, 0x61, +0xc7, 0x27, 0x94, 0xc6, 0x59, 0x82, 0x18, 0x27, +0x4d, 0x4a, 0x93, 0x46, 0x82, 0x4c, 0x98, 0xcd, +0x80, 0x17, 0xc7, 0x59, 0x28, 0x62, 0xb2, 0xa2, +0xc0, 0x6a, 0xb5, 0xf1, 0x76, 0x2d, 0xc2, 0x21, +0xe2, 0xd0, 0x24, 0x36, 0x9e, 0x77, 0x6a, 0x10, +0x0e, 0x2f, 0x97, 0x16, 0xb1, 0x01, 0xef, 0x74, +0x4e, 0x51, 0x04, 0x9f, 0xc5, 0x62, 0xb1, 0x38, +0x1c, 0x8e, 0x69, 0x8d, 0xb3, 0xd8, 0x4d, 0x76, +0xd4, 0x0c, 0x41, 0x66, 0x59, 0xb5, 0x59, 0x82, +0xcc, 0x19, 0xd5, 0xe6, 0x2e, 0x0e, 0xdc, 0x1e, +0xaf, 0xd7, 0xe7, 0xf3, 0xf9, 0xfd, 0xfe, 0x79, +0x8f, 0x9b, 0x20, 0x81, 0x67, 0xc1, 0x60, 0x08, +0x15, 0x0e, 0x87, 0x17, 0x02, 0x04, 0xf1, 0xc2, +0x22, 0x5a, 0xcf, 0xe1, 0x05, 0x44, 0x28, 0x12, +0x8c, 0xc6, 0x62, 0x10, 0x87, 0xa5, 0xa5, 0xc4, +0x32, 0x49, 0x7c, 0x7d, 0xf0, 0x12, 0x92, 0x14, +0x09, 0xc5, 0x62, 0x71, 0x4c, 0x12, 0x7f, 0x92, +0x1e, 0xd0, 0x22, 0x71, 0x04, 0x20, 0xb1, 0xb2, +0x12, 0x25, 0x89, 0x07, 0x9d, 0x22, 0x12, 0x49, +0x26, 0x93, 0x8b, 0x3e, 0x85, 0xa4, 0x84, 0x14, +0x26, 0x0b, 0xe8, 0x14, 0xcb, 0xa8, 0x68, 0x34, +0x44, 0x90, 0x55, 0xb7, 0xda, 0x6a, 0xff, 0x99, +0x90, 0xc6, 0x66, 0x2d, 0xa0, 0xb6, 0x46, 0xbc, +0xfd, 0x19, 0x7c, 0x23, 0x78, 0xe7, 0x54, 0x66, +0x1d, 0x7d, 0xb0, 0x94, 0xd0, 0xed, 0xd5, 0x06, +0x32, 0xec, 0xb4, 0xd9, 0xcc, 0xa1, 0x5c, 0xae, +0x4d, 0xf2, 0x23, 0x1b, 0xad, 0xd9, 0xad, 0xad, +0x1c, 0xe4, 0xb6, 0xf3, 0xf9, 0x82, 0x91, 0x11, +0x5e, 0xef, 0xec, 0xa4, 0xd3, 0x6f, 0x36, 0xde, +0xbe, 0x13, 0x18, 0xd6, 0x5c, 0x2c, 0xc2, 0x2e, +0x5a, 0xef, 0xf7, 0x36, 0x49, 0x62, 0x43, 0x22, +0x07, 0xf9, 0x7c, 0xbe, 0x54, 0xfe, 0xbd, 0x0b, +0x12, 0x68, 0x17, 0x6e, 0x7f, 0x1f, 0x03, 0xd8, +0xa3, 0x09, 0x9f, 0xcb, 0x7d, 0xd8, 0x46, 0xa4, +0x54, 0xca, 0x2a, 0xd7, 0x42, 0xc0, 0x02, 0x91, +0xdd, 0x2e, 0x40, 0xa4, 0x48, 0x12, 0x7b, 0x26, +0xb3, 0x5e, 0x28, 0x14, 0xca, 0xe5, 0xac, 0x4d, +0x21, 0xbd, 0x37, 0xc6, 0x3a, 0xd0, 0x29, 0x70, +0xc5, 0x22, 0x47, 0x10, 0xdd, 0x9b, 0xa4, 0x7f, +0xfb, 0xc4, 0x8f, 0x07, 0xb8, 0x4a, 0xa5, 0x52, +0x3d, 0x14, 0x99, 0x81, 0x26, 0xe2, 0xc1, 0x11, +0x1c, 0xc1, 0x27, 0xf8, 0x0c, 0x5f, 0x6a, 0x14, +0xd1, 0x9b, 0xe0, 0x41, 0xf7, 0x31, 0x1c, 0x6b, +0x10, 0xcd, 0x89, 0xf8, 0xb5, 0xff, 0x18, 0x8e, +0xeb, 0x14, 0xd1, 0x9b, 0x88, 0x87, 0x95, 0x6a, +0xb5, 0x5a, 0xab, 0xd5, 0xea, 0xf5, 0x6f, 0x14, +0xd1, 0x9b, 0x9c, 0x88, 0x6a, 0x27, 0xcc, 0x40, +0x93, 0x40, 0xb4, 0xd1, 0x68, 0x9c, 0xa2, 0x9a, +0xad, 0x38, 0x71, 0x5f, 0x99, 0xf6, 0xfc, 0x59, +0xaf, 0x4e, 0xe7, 0x7b, 0x9b, 0x20, 0x0d, 0x49, +0x92, 0x40, 0x06, 0x59, 0x96, 0x5b, 0x14, 0x39, +0x83, 0x1f, 0xfd, 0xd5, 0x21, 0xc9, 0xa9, 0x24, +0xc9, 0x97, 0x26, 0xf2, 0x65, 0x49, 0xac, 0xd9, +0x6c, 0xf5, 0xa2, 0xcf, 0xf2, 0xb3, 0xa3, 0x44, +0x9e, 0x45, 0xf7, 0xbf, 0xc7, 0x9c, 0xb7, 0xd5, +0xce, 0x99, 0xab, 0xfe, 0xe3, 0x7e, 0x01, 0xe5, +0xdc, 0xd6, 0xf5, 0x68, 0xe0, 0x9b, 0x58, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_sort_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_sort_png = new wxImage(); + if (!img_ex_sort_png || !img_ex_sort_png->IsOk()) + { + wxMemoryInputStream img_ex_sort_pngIS(ex_sort_png_data, sizeof(ex_sort_png_data)); + img_ex_sort_png->LoadFile(img_ex_sort_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_sort_png; +} +#define ex_sort_png_img ex_sort_png_img() + +static wxBitmap *ex_sort_png_bmp() +{ + static wxBitmap *bmp_ex_sort_png; + if (!bmp_ex_sort_png || !bmp_ex_sort_png->IsOk()) + bmp_ex_sort_png = new wxBitmap(*ex_sort_png_img); + return bmp_ex_sort_png; +} +#define ex_sort_png_bmp ex_sort_png_bmp() + +static wxIcon *ex_sort_png_ico() +{ + static wxIcon *ico_ex_sort_png; + if (!ico_ex_sort_png || !ico_ex_sort_png->IsOk()) + { + ico_ex_sort_png = new wxIcon(); + ico_ex_sort_png->CopyFromBitmap(*ex_sort_png_bmp); + } + return ico_ex_sort_png; +} +#define ex_sort_png_ico ex_sort_png_ico() + +#endif // EX_SORT_PNG_H diff --git a/include/images/ex_subplan.png b/include/images/ex_subplan.png new file mode 100644 index 0000000..e13d779 Binary files /dev/null and b/include/images/ex_subplan.png differ diff --git a/include/images/ex_subplan.pngc b/include/images/ex_subplan.pngc new file mode 100644 index 0000000..ef487f4 --- /dev/null +++ b/include/images/ex_subplan.pngc @@ -0,0 +1,205 @@ +#ifndef EX_SUBPLAN_PNG_H +#define EX_SUBPLAN_PNG_H + +static const unsigned char ex_subplan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc2, 0xc3, 0xd0, 0x96, +0x99, 0xd1, 0x7f, 0x83, 0xd1, 0x74, 0x78, 0xd3, +0x66, 0x6b, 0xd1, 0xa2, 0xa5, 0xe4, 0xb6, 0xb8, +0xea, 0xbd, 0xbf, 0xec, 0xc4, 0xc5, 0xef, 0xc2, +0xc4, 0xee, 0xc6, 0xc8, 0xef, 0xc8, 0xc8, 0xf0, +0xc9, 0xca, 0xf0, 0xcb, 0xcc, 0xf1, 0xcd, 0xce, +0xf2, 0xcf, 0xd0, 0xf2, 0xd1, 0xd1, 0xf2, 0xd3, +0xd3, 0xf3, 0xd7, 0xd7, 0xf5, 0xac, 0xae, 0xe8, +0xaf, 0xb1, 0xe8, 0xa9, 0xab, 0xe6, 0xb8, 0xb9, +0xeb, 0xbe, 0xbf, 0xed, 0xc0, 0xc1, 0xed, 0xb2, +0xb4, 0xe9, 0x92, 0x96, 0xdf, 0x98, 0x9b, 0xe1, +0xba, 0xbc, 0xeb, 0xa6, 0xa8, 0xd0, 0xd9, 0xda, +0xf5, 0xc7, 0xc5, 0xb7, 0xab, 0xa5, 0x6c, 0x9d, +0x94, 0x45, 0x97, 0x8d, 0x2e, 0x8d, 0x81, 0x19, +0x92, 0x95, 0xd1, 0xc5, 0xc5, 0x75, 0xd5, 0xd8, +0x91, 0xdb, 0xe1, 0x95, 0xe5, 0xee, 0xa9, 0xe2, +0xec, 0xa0, 0xe1, 0xea, 0x9c, 0xd1, 0xd1, 0x8b, +0xc0, 0xbd, 0x71, 0xc2, 0xc0, 0x6e, 0xd4, 0xd7, +0x8a, 0xcd, 0xd1, 0x7d, 0xd2, 0xd8, 0x87, 0xd6, +0xd9, 0x8d, 0xc9, 0xcb, 0x76, 0xcd, 0xcd, 0x84, +0xbe, 0xbc, 0x70, 0xb1, 0xac, 0x58, 0xea, 0xf2, +0xb8, 0xb5, 0xb0, 0x87, 0xc8, 0xc6, 0xba, 0xd8, +0xdd, 0x8e, 0xa9, 0xa2, 0x64, 0xd8, 0xe3, 0x81, +0xd7, 0xe1, 0x7f, 0xe8, 0xed, 0xb8, 0xca, 0xca, +0x7d, 0xd1, 0xd3, 0x85, 0xbc, 0xb6, 0x6c, 0x86, +0xa9, 0x64, 0x52, 0x8d, 0x19, 0x75, 0xa6, 0xc7, +0x36, 0x88, 0xc1, 0xa8, 0xcf, 0x68, 0x6d, 0xcb, +0xec, 0x43, 0xbd, 0xe9, 0x4d, 0xbf, 0xe8, 0x57, +0xc3, 0xea, 0x85, 0xd4, 0xf0, 0x94, 0xd8, 0xf0, +0x7a, 0xce, 0xec, 0x87, 0xd3, 0xee, 0xad, 0xdf, +0xf3, 0x10, 0xab, 0xe2, 0x92, 0xd5, 0xef, 0xaa, +0xd2, 0x6a, 0x72, 0x96, 0xa1, 0xac, 0xd7, 0x6e, +0xc1, 0x8f, 0x36, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, +0xb6, 0xef, 0xe9, 0xb4, 0xf3, 0xed, 0xc6, 0xed, +0xe4, 0xb1, 0xec, 0xe1, 0xae, 0xf0, 0xe9, 0xc2, +0xea, 0xe2, 0x9c, 0xe7, 0xdb, 0x96, 0xe4, 0xd5, +0x92, 0xeb, 0xde, 0xac, 0xc1, 0xc8, 0xba, 0x5d, +0x97, 0x24, 0xae, 0xda, 0x71, 0xe8, 0xdf, 0x99, +0xe3, 0xd1, 0x8e, 0xea, 0xdc, 0xaa, 0x9e, 0xb5, +0x87, 0x78, 0xad, 0x3d, 0xb8, 0xe9, 0x7e, 0xe9, +0xda, 0xa9, 0x9a, 0xc9, 0x5d, 0x9d, 0xce, 0x62, +0xba, 0xee, 0x82, 0xef, 0xe6, 0xc0, 0xe9, 0xd8, +0xa7, 0xee, 0xe2, 0xbd, 0x87, 0xbb, 0x4d, 0x6f, +0x9c, 0x43, 0xc7, 0xaa, 0x75, 0x8b, 0xab, 0x6c, +0xbf, 0xc7, 0xb7, 0xe8, 0xd6, 0xa6, 0xe6, 0xd3, +0xa3, 0xeb, 0xdc, 0xb9, 0xde, 0xc5, 0x85, 0xdd, +0xc2, 0x83, 0xe1, 0xcc, 0x8b, 0xdc, 0xc0, 0x81, +0xe5, 0xce, 0xa0, 0xdb, 0xbe, 0x7f, 0xe4, 0xcd, +0x9e, 0x0d, 0x5f, 0xc3, 0x29, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0xba, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xcd, 0x94, 0xe9, 0x53, 0xda, 0x40, 0x18, +0xc6, 0x39, 0x12, 0x05, 0xaa, 0x52, 0x21, 0x8a, +0xd4, 0xa3, 0x06, 0x96, 0x43, 0x43, 0x91, 0x22, +0xa2, 0x82, 0xd6, 0xea, 0x96, 0x7a, 0xb4, 0xb5, +0x94, 0xb2, 0x6a, 0x83, 0xc8, 0xa1, 0x28, 0xa8, +0x78, 0xd5, 0x7a, 0x5b, 0xff, 0xf5, 0xee, 0xc6, +0xa0, 0x10, 0xdc, 0xc0, 0xd8, 0x99, 0x4e, 0x9f, +0x0f, 0x9b, 0x99, 0x77, 0x9f, 0xdf, 0xbc, 0xc7, +0xee, 0x46, 0xa3, 0xf9, 0xe7, 0xd2, 0xea, 0xf4, +0x0c, 0xab, 0x14, 0xa3, 0xd7, 0x69, 0x55, 0x88, +0x96, 0x56, 0x83, 0xd1, 0x64, 0x32, 0x1a, 0x5f, +0xb4, 0xb5, 0x77, 0x74, 0x98, 0xcd, 0x2f, 0x3b, +0x3b, 0x2d, 0x56, 0xb3, 0x89, 0xa3, 0x33, 0xba, +0x96, 0xae, 0xee, 0x2e, 0x9b, 0x02, 0x69, 0xeb, +0xb1, 0xd9, 0x39, 0x1d, 0x0d, 0xd1, 0xb7, 0x76, +0xbf, 0xea, 0x55, 0x56, 0xc6, 0xf4, 0xd9, 0x6d, +0x26, 0x3d, 0x0d, 0x61, 0xfa, 0xb9, 0xde, 0x01, +0x65, 0x0d, 0xda, 0x81, 0x3e, 0xcb, 0x6b, 0x96, +0x86, 0xb0, 0x9d, 0x66, 0x86, 0x10, 0x83, 0xbc, +0xc3, 0x09, 0x88, 0x9c, 0x0e, 0x7e, 0x50, 0xa3, +0x65, 0x2c, 0x56, 0x2a, 0xe2, 0x62, 0x59, 0x97, +0x44, 0xb8, 0x3d, 0xde, 0xa1, 0xe1, 0x61, 0x41, +0xf0, 0xfa, 0xde, 0x60, 0x86, 0xb5, 0xd2, 0x11, +0x59, 0xbc, 0x7f, 0x24, 0xf0, 0xd6, 0x2b, 0x08, +0x42, 0x30, 0x30, 0x1a, 0x1a, 0xe3, 0x55, 0x11, +0x39, 0x8b, 0xc3, 0x13, 0x18, 0x09, 0x93, 0xca, +0x9c, 0xe1, 0x90, 0x3b, 0xe4, 0x50, 0x43, 0x5c, +0x6c, 0x5b, 0x3b, 0x61, 0xc0, 0xf8, 0x78, 0x78, +0x62, 0x12, 0x07, 0x26, 0x27, 0xc2, 0x11, 0x2f, +0x50, 0x41, 0x5c, 0xac, 0x89, 0xe3, 0x8c, 0x98, +0x89, 0x02, 0x10, 0xbd, 0x0f, 0x4d, 0x3a, 0x23, +0x11, 0x35, 0x84, 0xb5, 0x18, 0x38, 0xce, 0x5e, +0xbb, 0x0b, 0xd4, 0x11, 0xdc, 0x89, 0xcd, 0xc6, +0xd6, 0x64, 0xc1, 0x48, 0x10, 0xa8, 0xb6, 0xcf, +0x1a, 0x7a, 0xf0, 0x5e, 0x14, 0x0c, 0x0d, 0x55, +0x18, 0x10, 0x6c, 0x06, 0x89, 0x82, 0xe1, 0xa9, +0x69, 0x41, 0x66, 0x9a, 0x43, 0xc0, 0xb8, 0x30, +0x35, 0xed, 0x7d, 0x07, 0xee, 0xdb, 0x1f, 0x69, +0x2e, 0x0b, 0x88, 0x8c, 0x86, 0xa5, 0x2c, 0x78, +0xc8, 0x6e, 0x9f, 0xb3, 0x89, 0x5e, 0x34, 0x0e, +0xdf, 0x68, 0x48, 0x3e, 0xca, 0x19, 0xbf, 0xfa, +0x51, 0x56, 0x10, 0x7e, 0x2c, 0xe0, 0x9e, 0x79, +0x1f, 0x09, 0x06, 0x43, 0x6e, 0xbf, 0x7b, 0x96, +0x6f, 0x80, 0x18, 0xc8, 0xde, 0x20, 0x3f, 0xe6, +0xf3, 0x44, 0x30, 0xe2, 0xf1, 0x85, 0x66, 0x1b, +0x5c, 0x4b, 0xd6, 0xde, 0xf3, 0xe4, 0xe5, 0xb7, +0xd2, 0xdf, 0x0b, 0xed, 0x89, 0xd9, 0xcd, 0x0c, +0x0d, 0xa1, 0x3d, 0xe4, 0x7e, 0x23, 0xf5, 0x21, +0x3f, 0xe3, 0x77, 0xf1, 0x8c, 0x9f, 0xd2, 0x33, +0x7e, 0x7d, 0x7f, 0xa9, 0x39, 0x38, 0x47, 0xdf, +0xfc, 0x10, 0x23, 0x92, 0xd7, 0x87, 0x28, 0xfc, +0x08, 0xe9, 0x8e, 0xd8, 0xfc, 0xc2, 0xe2, 0xd2, +0xa7, 0xd8, 0xe7, 0x2f, 0xcb, 0xcb, 0x5f, 0x63, +0x4f, 0x22, 0x75, 0x8e, 0xd8, 0x42, 0x3c, 0x1e, +0x5f, 0x8a, 0xcd, 0x2f, 0x2e, 0xcd, 0x7f, 0xab, +0x42, 0x12, 0x55, 0x88, 0xd2, 0x41, 0xc9, 0x92, +0x50, 0xc9, 0xf2, 0x5d, 0xaa, 0x51, 0x5e, 0x1f, +0x91, 0xe4, 0x23, 0x52, 0xe7, 0x40, 0x2b, 0xab, +0xab, 0x6b, 0x2b, 0xe8, 0x87, 0x28, 0xa6, 0xd6, +0xd1, 0x93, 0x48, 0x9d, 0x03, 0xad, 0xa6, 0xd3, +0xe9, 0x35, 0x24, 0x6e, 0x64, 0x32, 0x59, 0x54, +0x19, 0x6f, 0x2e, 0xbf, 0x99, 0xcf, 0x55, 0x46, +0xad, 0x74, 0x48, 0x81, 0x2d, 0x11, 0x89, 0x99, +0x4c, 0x61, 0x1b, 0x11, 0x17, 0x9e, 0x55, 0x6e, +0xa7, 0x98, 0x2c, 0xee, 0xe4, 0x34, 0xb0, 0x44, +0x18, 0x85, 0x03, 0x07, 0xd6, 0xb6, 0xb6, 0x36, +0x44, 0x94, 0xcd, 0x14, 0x0a, 0xbb, 0x88, 0x10, +0x09, 0x08, 0xf3, 0xc5, 0xbd, 0xfd, 0xfd, 0x62, +0x1e, 0xc2, 0x52, 0x19, 0x33, 0xb5, 0x0e, 0x82, +0xe0, 0x1a, 0xc5, 0x75, 0x74, 0xb0, 0xbd, 0x7b, +0x78, 0x84, 0xf0, 0x79, 0x24, 0x12, 0xc9, 0xe4, +0xe6, 0xde, 0xf1, 0xc9, 0xf1, 0x7e, 0xa9, 0x54, +0x2a, 0x97, 0xcb, 0x50, 0xe1, 0xc0, 0xfa, 0x89, +0x88, 0xe4, 0x15, 0x67, 0x49, 0x24, 0x21, 0x84, +0x27, 0xa7, 0xbf, 0x4e, 0x4f, 0xf0, 0xb7, 0x4c, +0xb2, 0xd4, 0x3a, 0x48, 0x96, 0xf5, 0x54, 0x2a, +0x7b, 0x80, 0x8e, 0xce, 0xce, 0xce, 0x2f, 0xa4, +0x5e, 0xaa, 0x66, 0x05, 0xcb, 0x52, 0x2f, 0xb5, +0x0e, 0x1c, 0x48, 0x49, 0x35, 0x1e, 0x5e, 0x5e, +0x5e, 0x9d, 0x3f, 0x4c, 0xac, 0xe6, 0x72, 0x2a, +0x1d, 0x1a, 0x94, 0x2d, 0x14, 0xae, 0xcf, 0xd0, +0xf9, 0xe5, 0xd5, 0xcd, 0xed, 0xe3, 0xb9, 0x54, +0xab, 0xce, 0x81, 0xb6, 0xaf, 0xaf, 0x49, 0xe0, +0xea, 0xe6, 0xf7, 0x1d, 0x05, 0x51, 0x3a, 0xd0, +0xd1, 0x21, 0xa9, 0xf1, 0xe2, 0xf6, 0xf6, 0xee, +0x82, 0x82, 0x28, 0x1d, 0x75, 0xf3, 0xa8, 0x53, +0x63, 0xc7, 0xff, 0xa1, 0x3f, 0x99, 0xd5, 0xf6, +0x52, 0x1e, 0xe8, 0x44, 0xe6, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_subplan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_subplan_png = new wxImage(); + if (!img_ex_subplan_png || !img_ex_subplan_png->IsOk()) + { + wxMemoryInputStream img_ex_subplan_pngIS(ex_subplan_png_data, sizeof(ex_subplan_png_data)); + img_ex_subplan_png->LoadFile(img_ex_subplan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_subplan_png; +} +#define ex_subplan_png_img ex_subplan_png_img() + +static wxBitmap *ex_subplan_png_bmp() +{ + static wxBitmap *bmp_ex_subplan_png; + if (!bmp_ex_subplan_png || !bmp_ex_subplan_png->IsOk()) + bmp_ex_subplan_png = new wxBitmap(*ex_subplan_png_img); + return bmp_ex_subplan_png; +} +#define ex_subplan_png_bmp ex_subplan_png_bmp() + +static wxIcon *ex_subplan_png_ico() +{ + static wxIcon *ico_ex_subplan_png; + if (!ico_ex_subplan_png || !ico_ex_subplan_png->IsOk()) + { + ico_ex_subplan_png = new wxIcon(); + ico_ex_subplan_png->CopyFromBitmap(*ex_subplan_png_bmp); + } + return ico_ex_subplan_png; +} +#define ex_subplan_png_ico ex_subplan_png_ico() + +#endif // EX_SUBPLAN_PNG_H diff --git a/include/images/ex_tid_scan.png b/include/images/ex_tid_scan.png new file mode 100644 index 0000000..0a6063a Binary files /dev/null and b/include/images/ex_tid_scan.png differ diff --git a/include/images/ex_tid_scan.pngc b/include/images/ex_tid_scan.pngc new file mode 100644 index 0000000..18b2ed6 --- /dev/null +++ b/include/images/ex_tid_scan.pngc @@ -0,0 +1,179 @@ +#ifndef EX_TID_SCAN_PNG_H +#define EX_TID_SCAN_PNG_H + +static const unsigned char ex_tid_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd1, 0xe0, 0xf1, 0x93, +0xb6, 0xdf, 0xbc, 0xd4, 0xeb, 0xfe, 0xfe, 0xff, +0xc1, 0xd6, 0xed, 0x99, 0xbb, 0xe1, 0xa5, 0xc2, +0xe4, 0xea, 0xf1, 0xf9, 0xf0, 0xf4, 0xfa, 0xd9, +0xe5, 0xf4, 0xc7, 0xd8, 0xee, 0xd9, 0xeb, 0xf5, +0xab, 0xc6, 0xe6, 0x8c, 0xb1, 0xdd, 0xca, 0xdb, +0xef, 0xe3, 0xec, 0xf7, 0x85, 0xad, 0xdb, 0x75, +0xa1, 0xd6, 0xa6, 0xc5, 0xe4, 0xcb, 0xe4, 0xf1, +0xcd, 0xe5, 0xf1, 0xbd, 0xd8, 0xed, 0x71, 0x9e, +0xd4, 0xd5, 0xe3, 0xf3, 0xae, 0xc9, 0xe7, 0x7f, +0xa7, 0xd9, 0xd0, 0xe6, 0xf2, 0xd6, 0xea, 0xf4, +0xc5, 0xe1, 0xf0, 0xc1, 0xdf, 0xef, 0xc9, 0xe3, +0xf0, 0x6b, 0x99, 0xd2, 0xa3, 0xc3, 0xe4, 0xc2, +0xda, 0xee, 0x7b, 0xa6, 0xd8, 0xb5, 0xd0, 0xe9, +0xb0, 0xcc, 0xe8, 0xa1, 0xc1, 0xe3, 0xc5, 0xe0, +0xee, 0xc5, 0xde, 0xee, 0xf8, 0xfa, 0xfd, 0xa3, +0xc5, 0xe4, 0x79, 0xa4, 0xd7, 0xe9, 0xe4, 0xdb, +0xd5, 0xc7, 0xae, 0xc8, 0xb3, 0x90, 0xbe, 0xa4, +0x75, 0xba, 0x9a, 0x60, 0xb8, 0x91, 0x4b, 0xc4, +0x95, 0x3b, 0x8c, 0x8a, 0x88, 0x81, 0x81, 0x81, +0x87, 0x87, 0x87, 0x8e, 0x8e, 0x8e, 0x96, 0x96, +0x96, 0xa0, 0xa0, 0xa0, 0xac, 0xac, 0xac, 0xbc, +0xbc, 0xbc, 0xcd, 0xcd, 0xcd, 0xdc, 0xdc, 0xdc, +0xf0, 0xf0, 0xf0, 0xe1, 0xe1, 0xe1, 0xc1, 0xbf, +0xbb, 0xab, 0x9f, 0x8a, 0xc9, 0x9c, 0x43, 0xce, +0xa7, 0x4f, 0xd8, 0xb5, 0x5c, 0xde, 0xc1, 0x68, +0xe1, 0xca, 0x69, 0xea, 0xd3, 0x6a, 0xed, 0xd6, +0x7a, 0xe0, 0xd2, 0xba, 0xeb, 0xe9, 0xe4, 0xe6, +0xe6, 0xe6, 0xd9, 0xd9, 0xd9, 0xd2, 0xd2, 0xd2, +0xc8, 0xc8, 0xc8, 0xc0, 0xc0, 0xc0, 0xb4, 0xb4, +0xb4, 0xaa, 0xaa, 0xaa, 0x99, 0x99, 0x99, 0xa3, +0xa3, 0xa3, 0x9e, 0x9b, 0x97, 0xeb, 0xde, 0x85, +0xf1, 0xe9, 0x7e, 0xf7, 0xe7, 0x69, 0xf1, 0xe2, +0x55, 0xf5, 0xe1, 0x46, 0xf5, 0xde, 0x38, 0xc9, +0xa6, 0x68, 0xdf, 0xdf, 0xdf, 0xd6, 0xd6, 0xd6, +0xd0, 0xd0, 0xd0, 0xca, 0xca, 0xca, 0xc5, 0xc5, +0xc5, 0xed, 0xed, 0xed, 0xe1, 0xd5, 0xc0, 0xd4, +0xb9, 0x89, 0xc9, 0xa0, 0x58, 0xd3, 0xab, 0x52, +0xfb, 0xe6, 0x5a, 0xd0, 0xbc, 0x98, 0xce, 0xce, +0xce, 0xc6, 0xc6, 0xc6, 0xc3, 0xc3, 0xc3, 0xba, +0xba, 0xba, 0x91, 0x91, 0x91, 0xea, 0xea, 0xea, +0xdd, 0xce, 0xb3, 0xcf, 0xc7, 0xb9, 0xbe, 0xbe, +0xbe, 0xb8, 0xb8, 0xb8, 0xb7, 0xb7, 0xb7, 0xde, +0xdb, 0xd7, 0xcc, 0xb2, 0x84, 0xcb, 0xbb, 0xa0, +0xbd, 0xbd, 0xbd, 0xe4, 0xe4, 0xe4, 0x9c, 0x9c, +0x9c, 0xe8, 0xe8, 0xe8, 0x9b, 0x9b, 0x9b, 0xb0, +0xb0, 0xb0, 0x9f, 0x9f, 0x9f, 0xaf, 0xaf, 0xaf, +0xa5, 0xa5, 0xa5, 0x85, 0x85, 0x85, 0x94, 0x94, +0x94, 0xe2, 0xe9, 0x35, 0xeb, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0xe9, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xed, 0x94, 0x59, 0x53, 0xda, 0x50, 0x18, +0x86, 0x95, 0x68, 0x10, 0x6a, 0x02, 0x01, 0x59, +0xa3, 0x10, 0x15, 0x71, 0xa9, 0x4b, 0x65, 0x49, +0x48, 0x82, 0x51, 0x14, 0x51, 0x63, 0x16, 0xc0, +0x56, 0xad, 0x61, 0xd1, 0xb6, 0x96, 0x12, 0x6d, +0x29, 0xad, 0xfb, 0xfa, 0xd7, 0x3d, 0xc1, 0xf1, +0xca, 0x10, 0xe0, 0x4e, 0x67, 0x78, 0x2f, 0x33, +0xe7, 0x99, 0xf7, 0xc9, 0xf9, 0xf2, 0xa5, 0xa7, +0xa7, 0x9b, 0x77, 0x93, 0x5e, 0x13, 0xd4, 0xd7, +0x21, 0x62, 0xea, 0x87, 0xcd, 0x03, 0x9d, 0x00, +0x16, 0xeb, 0x07, 0xd3, 0x20, 0x82, 0xda, 0xda, +0x3c, 0x6e, 0xef, 0x37, 0x63, 0x0e, 0xcc, 0xe4, +0x1c, 0x72, 0xb9, 0x3d, 0x48, 0xeb, 0xe3, 0x7d, +0x5e, 0x1f, 0xea, 0x87, 0x7d, 0x6e, 0x7c, 0x78, +0x18, 0x1f, 0x09, 0x04, 0x07, 0x89, 0x56, 0xc0, +0x00, 0x44, 0x60, 0xa3, 0x10, 0x8e, 0xe3, 0x63, +0x4e, 0x74, 0xdc, 0x13, 0x0a, 0x0c, 0x8d, 0xb7, +0x68, 0xb1, 0x84, 0x1c, 0x70, 0xc8, 0xe5, 0x0a, +0x3a, 0x31, 0x0f, 0x81, 0xd8, 0xec, 0x13, 0xe1, +0x20, 0x6c, 0x36, 0x26, 0x6c, 0x1e, 0xd8, 0x1d, +0x9c, 0x44, 0x30, 0x02, 0xf1, 0x5a, 0xb4, 0xeb, +0xf5, 0x62, 0x53, 0x7e, 0xe3, 0x6b, 0xb6, 0xa1, +0xa1, 0x11, 0x77, 0xd8, 0x11, 0xb6, 0x4e, 0xbf, +0x3c, 0x81, 0xfc, 0x90, 0x71, 0x09, 0x3c, 0x11, +0x98, 0xf9, 0xe8, 0xeb, 0x68, 0x12, 0x56, 0x02, +0x35, 0xdb, 0x3b, 0x01, 0x40, 0xa6, 0xdb, 0x9d, +0x5b, 0x93, 0xcc, 0xce, 0xcd, 0x2f, 0x7c, 0x5a, +0x5c, 0x8c, 0x44, 0x63, 0xb1, 0x58, 0x9c, 0xa4, +0x12, 0x34, 0xc3, 0x26, 0x97, 0x0c, 0xce, 0x73, +0xcb, 0x2b, 0xa9, 0xd5, 0xb5, 0xf4, 0x7a, 0x26, +0xb3, 0x11, 0xd9, 0xdc, 0xe2, 0xb9, 0x6d, 0x41, +0x94, 0xe4, 0x6c, 0x8e, 0xcc, 0x4b, 0x9c, 0x3e, +0xc0, 0xcb, 0x3b, 0x91, 0xd5, 0xf4, 0xe7, 0x2f, +0xbb, 0x7b, 0xfb, 0x5f, 0xf7, 0x33, 0x07, 0x4a, +0xb2, 0x50, 0x28, 0x16, 0xd9, 0x92, 0x28, 0x8a, +0x0c, 0x4d, 0xc9, 0xbc, 0x0e, 0xa1, 0x50, 0xe5, +0xc3, 0xad, 0xa3, 0x6f, 0xdf, 0x23, 0x3f, 0xd2, +0x99, 0xe3, 0xe3, 0xdd, 0xb5, 0x9f, 0x05, 0xa1, +0x52, 0xfa, 0x55, 0x95, 0x18, 0x55, 0x55, 0xa5, +0xb2, 0x7c, 0xa2, 0xbc, 0x46, 0xb2, 0xec, 0xe1, +0xa9, 0x96, 0xd9, 0xdf, 0x0d, 0x6c, 0x23, 0xf5, +0x87, 0x15, 0xcb, 0x52, 0x4d, 0xfd, 0x5b, 0x97, +0x65, 0xb9, 0x2e, 0x31, 0xd9, 0xe6, 0xc8, 0x29, +0xcf, 0x73, 0xff, 0xe6, 0xfe, 0x1f, 0x9c, 0x69, +0xc4, 0xf9, 0x33, 0xd1, 0x04, 0x11, 0x81, 0x98, +0x06, 0xf1, 0x17, 0x9c, 0xb2, 0x5d, 0x10, 0xd8, +0x67, 0xa9, 0x46, 0x45, 0x43, 0x4c, 0xd4, 0x69, +0xa9, 0xd1, 0x97, 0xaa, 0x70, 0x05, 0x10, 0xf0, +0xe2, 0x42, 0x05, 0x54, 0x80, 0x0e, 0x95, 0xa9, +0x49, 0xd5, 0xb2, 0x4a, 0x53, 0xd7, 0x37, 0xfa, +0x62, 0xc5, 0xfa, 0x2d, 0x79, 0x4b, 0xab, 0xd5, +0x52, 0x45, 0x10, 0x84, 0xa2, 0x26, 0xc6, 0xd4, +0xef, 0xee, 0x73, 0x51, 0xf2, 0x3a, 0x6b, 0x20, +0x96, 0x64, 0xcf, 0xef, 0xf2, 0xb9, 0x93, 0xe8, +0x03, 0x18, 0xe5, 0x43, 0x3c, 0x4a, 0x3e, 0xe6, +0x12, 0xf7, 0x37, 0x5d, 0xb1, 0xf7, 0x25, 0xa6, +0xb4, 0x10, 0xd3, 0xf9, 0xf8, 0xc1, 0x8a, 0x19, +0x88, 0xe9, 0xae, 0x18, 0x08, 0x27, 0xe5, 0x75, +0xc5, 0x9a, 0x2e, 0x72, 0x23, 0x4b, 0x49, 0x96, +0xa1, 0x13, 0x14, 0x19, 0x6f, 0xf3, 0x77, 0xd1, +0xcd, 0xdb, 0xc8, 0x13, 0x66, 0x96, 0xed, 0xaf, +0x62, 0x22, 0xf3, 0x03, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_tid_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_tid_scan_png = new wxImage(); + if (!img_ex_tid_scan_png || !img_ex_tid_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_tid_scan_pngIS(ex_tid_scan_png_data, sizeof(ex_tid_scan_png_data)); + img_ex_tid_scan_png->LoadFile(img_ex_tid_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_tid_scan_png; +} +#define ex_tid_scan_png_img ex_tid_scan_png_img() + +static wxBitmap *ex_tid_scan_png_bmp() +{ + static wxBitmap *bmp_ex_tid_scan_png; + if (!bmp_ex_tid_scan_png || !bmp_ex_tid_scan_png->IsOk()) + bmp_ex_tid_scan_png = new wxBitmap(*ex_tid_scan_png_img); + return bmp_ex_tid_scan_png; +} +#define ex_tid_scan_png_bmp ex_tid_scan_png_bmp() + +static wxIcon *ex_tid_scan_png_ico() +{ + static wxIcon *ico_ex_tid_scan_png; + if (!ico_ex_tid_scan_png || !ico_ex_tid_scan_png->IsOk()) + { + ico_ex_tid_scan_png = new wxIcon(); + ico_ex_tid_scan_png->CopyFromBitmap(*ex_tid_scan_png_bmp); + } + return ico_ex_tid_scan_png; +} +#define ex_tid_scan_png_ico ex_tid_scan_png_ico() + +#endif // EX_TID_SCAN_PNG_H diff --git a/include/images/ex_unique.png b/include/images/ex_unique.png new file mode 100644 index 0000000..cb70480 Binary files /dev/null and b/include/images/ex_unique.png differ diff --git a/include/images/ex_unique.pngc b/include/images/ex_unique.pngc new file mode 100644 index 0000000..b35c842 --- /dev/null +++ b/include/images/ex_unique.pngc @@ -0,0 +1,199 @@ +#ifndef EX_UNIQUE_PNG_H +#define EX_UNIQUE_PNG_H + +static const unsigned char ex_unique_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xcd, 0xc4, 0xc4, 0xbd, +0x77, 0x77, 0xc7, 0x42, 0x42, 0xab, 0x1a, 0x1a, +0xc9, 0xb0, 0xb0, 0xb7, 0x29, 0x29, 0xe4, 0x65, +0x66, 0xd0, 0xce, 0xce, 0xc7, 0xaa, 0x75, 0xc1, +0x8f, 0x36, 0xb6, 0x55, 0x27, 0xcc, 0x46, 0x46, +0xcd, 0x4a, 0x4a, 0xb3, 0x49, 0x24, 0x86, 0xa9, +0x64, 0x52, 0x8d, 0x19, 0x7f, 0xa5, 0x5b, 0xb3, +0xc1, 0xa6, 0xf4, 0xf1, 0xc9, 0xf0, 0xec, 0xb7, +0xef, 0xea, 0xb5, 0xb4, 0x38, 0x2e, 0xe2, 0xbf, +0x9f, 0xa1, 0xc5, 0x5e, 0x85, 0xb2, 0x46, 0xeb, +0xe5, 0x9e, 0xea, 0xe2, 0x9c, 0xe9, 0xe1, 0x9b, +0xdb, 0xb6, 0x80, 0xb6, 0x2e, 0x2b, 0xed, 0xe4, +0xb1, 0x72, 0xa3, 0x35, 0xe8, 0xdd, 0x98, 0xc7, +0x76, 0x54, 0xec, 0xe0, 0xad, 0xdd, 0x65, 0x65, +0xef, 0xe5, 0xbf, 0xa6, 0xcc, 0x65, 0xf2, 0xeb, +0xc4, 0xb2, 0x25, 0x25, 0xe0, 0xc0, 0x95, 0xea, +0xdc, 0xaa, 0x76, 0xaa, 0x3b, 0xe9, 0xd8, 0xa7, +0xec, 0xdc, 0xb9, 0xe6, 0xd8, 0x94, 0xd6, 0xa3, +0x78, 0xd4, 0x5c, 0x5c, 0xe2, 0xcf, 0x8d, 0x9e, +0xb5, 0x87, 0xae, 0xda, 0x71, 0x78, 0xae, 0x3e, +0xe4, 0xd4, 0x91, 0xe0, 0xc9, 0x88, 0xdf, 0xc7, +0x86, 0xe6, 0xd1, 0xa2, 0xbf, 0x5c, 0x43, 0xc2, +0x3f, 0x3f, 0xe1, 0xcc, 0x8a, 0xe8, 0xd7, 0xa6, +0xb5, 0xe4, 0x7a, 0xdd, 0xc1, 0x82, 0xe3, 0xcc, +0x9e, 0xaf, 0x21, 0x21, 0x7b, 0xb3, 0x42, 0xe3, +0xd1, 0x8f, 0xdb, 0xbd, 0x7f, 0xb8, 0x31, 0x31, +0xb8, 0x45, 0x38, 0x8d, 0xc1, 0x53, 0xe7, 0xd4, +0xa4, 0xe4, 0xce, 0xa0, 0xbd, 0x3b, 0x3b, 0xd3, +0x66, 0x66, 0xb9, 0xeb, 0x7f, 0xd0, 0x93, 0x6d, +0xc9, 0x55, 0x55, 0xbb, 0xef, 0x83, 0xc6, 0x4e, +0x4e, 0x96, 0xcc, 0x5d, 0xb8, 0x35, 0x35, 0xb1, +0x3d, 0x21, 0xb8, 0x62, 0x2a, 0xcc, 0x63, 0x64, +0xba, 0x47, 0x4b, 0xba, 0x65, 0x65, 0x92, 0x95, +0xd1, 0x66, 0x6b, 0xd1, 0x88, 0x41, 0x73, 0x8c, +0x3c, 0x68, 0xcd, 0xce, 0xf1, 0xbd, 0xbf, 0xed, +0xbf, 0xc1, 0xed, 0xc2, 0xc2, 0xee, 0xc5, 0xc6, +0xf0, 0xc8, 0xc9, 0xf0, 0xcb, 0xcc, 0xf1, 0xae, +0x31, 0x36, 0xd4, 0xb5, 0xc8, 0xbc, 0xbd, 0xeb, +0xa7, 0xa9, 0xe7, 0xaa, 0xac, 0xe7, 0xae, 0xaf, +0xe9, 0xb1, 0xb3, 0xea, 0xb6, 0xb7, 0xeb, 0xbc, +0x9d, 0xbf, 0xac, 0x2c, 0x32, 0xd5, 0xd5, 0xf4, +0xb4, 0x66, 0x7b, 0xc0, 0xa7, 0xca, 0xaf, 0x37, +0x3d, 0xe0, 0xe0, 0xf7, 0xc5, 0xc4, 0xec, 0xc9, +0xb7, 0xd6, 0xd1, 0xd1, 0xf2, 0xb5, 0x8b, 0xad, +0xba, 0xbb, 0xec, 0xbe, 0xbf, 0xed, 0xab, 0x51, +0x66, 0xb3, 0x73, 0x8e, 0xb9, 0xac, 0xd8, 0xaf, +0x3f, 0x4a, 0x92, 0x35, 0x58, 0x83, 0x46, 0x80, +0xaa, 0x7e, 0xa7, 0xa7, 0xa4, 0xe0, 0x7f, 0x4b, +0x8b, 0x92, 0xca, 0x81, 0x3c, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x8d, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0xcd, 0x94, 0xfb, 0x5b, 0xd2, 0x50, 0x18, +0xc7, 0x87, 0xcc, 0x11, 0x83, 0xb9, 0x95, 0x40, +0x28, 0x97, 0xc9, 0xad, 0x14, 0x71, 0x82, 0x81, +0xa0, 0xc0, 0x90, 0x80, 0x00, 0x13, 0x88, 0x4a, +0x99, 0x62, 0x98, 0x45, 0x37, 0x2f, 0x59, 0x46, +0xde, 0xba, 0xf8, 0xaf, 0x77, 0xb6, 0x73, 0x60, +0x40, 0x4f, 0x9e, 0xf1, 0x43, 0xcf, 0xe3, 0xfb, +0x23, 0x67, 0x9f, 0xbd, 0xef, 0xfb, 0xe5, 0xec, +0x43, 0x10, 0x83, 0xa5, 0x1b, 0xd3, 0x11, 0x23, +0xd6, 0x98, 0x9e, 0x1c, 0x91, 0x19, 0xa7, 0x0c, +0xe4, 0x1d, 0x6d, 0x8f, 0x1a, 0x69, 0x58, 0x26, +0x33, 0x33, 0x61, 0x24, 0x08, 0x96, 0xe3, 0xee, +0xde, 0xc3, 0x20, 0xf4, 0xa4, 0xc5, 0x2a, 0x97, +0xcd, 0x40, 0xdd, 0xa7, 0x09, 0x82, 0xb3, 0xdb, +0xa7, 0x70, 0x0c, 0x6d, 0x99, 0x76, 0x38, 0x9c, +0x4e, 0x17, 0x65, 0x70, 0xf3, 0xb4, 0xdc, 0x65, +0x06, 0x30, 0x18, 0xc4, 0x2a, 0x13, 0x1e, 0xaf, +0xd9, 0xec, 0xf5, 0xd1, 0xf2, 0x0f, 0xec, 0x8c, +0x9d, 0xc3, 0x21, 0x00, 0xf0, 0x78, 0xdc, 0x7e, +0xca, 0x05, 0x11, 0x30, 0x1b, 0x0e, 0x99, 0xe4, +0xad, 0x3c, 0xef, 0xa2, 0xfc, 0x36, 0x5f, 0x00, +0x21, 0x0f, 0x30, 0x08, 0x4c, 0x6c, 0x82, 0xd1, +0x9b, 0x68, 0xda, 0xd8, 0x8f, 0x74, 0xa3, 0x94, +0xcb, 0x38, 0xd8, 0xe5, 0x21, 0xcf, 0xf3, 0x3e, +0xd2, 0x3f, 0x3b, 0x17, 0x44, 0x5d, 0xd8, 0xa9, +0x79, 0x16, 0x46, 0x69, 0xb1, 0x80, 0x01, 0x7c, +0xc1, 0xd0, 0x02, 0x3d, 0x88, 0xf0, 0x82, 0x20, +0x2c, 0xba, 0xc3, 0xb6, 0x48, 0x24, 0x04, 0x4f, +0x96, 0xe6, 0x1f, 0x45, 0x59, 0x25, 0xca, 0x69, +0x87, 0x47, 0x88, 0x45, 0x96, 0xe3, 0x89, 0x21, +0xc4, 0x27, 0xc4, 0x62, 0x2b, 0xcc, 0xaa, 0x37, +0x99, 0x4c, 0xa1, 0x13, 0x36, 0x9a, 0xe6, 0x14, +0xc4, 0xa9, 0x10, 0xa2, 0x98, 0x19, 0x46, 0x62, +0xb1, 0x08, 0xe9, 0x5f, 0x73, 0x25, 0x97, 0x11, +0xb2, 0x14, 0x4d, 0x67, 0x59, 0x25, 0x4a, 0x8f, +0xf0, 0x38, 0x19, 0x17, 0xc5, 0xdc, 0x30, 0x12, +0x08, 0x06, 0x17, 0xf3, 0xe1, 0x42, 0x2a, 0x95, +0x42, 0x23, 0xb3, 0x4f, 0xb2, 0x2c, 0x5c, 0x12, +0xac, 0x51, 0x4c, 0x94, 0x32, 0x99, 0xa1, 0x5d, +0x8c, 0x4a, 0x5e, 0x65, 0x93, 0x1a, 0x0c, 0x97, +0xc6, 0x25, 0x16, 0x08, 0x26, 0xc8, 0xf5, 0xb5, +0xb9, 0x62, 0x31, 0x81, 0x5e, 0xc6, 0x3d, 0xc5, +0xfd, 0x95, 0xa1, 0xe4, 0x46, 0xbe, 0x52, 0x10, +0x41, 0xa1, 0x60, 0xb8, 0x2a, 0x0e, 0x49, 0xc5, +0x57, 0x6a, 0x65, 0xaf, 0x8c, 0x94, 0xe0, 0x1d, +0xcb, 0xe2, 0x11, 0x91, 0x5c, 0x27, 0x5d, 0x62, +0x2e, 0x97, 0x2b, 0x29, 0x37, 0x39, 0x5b, 0x7d, +0x86, 0xbb, 0xc9, 0x0b, 0x1b, 0xf5, 0x4a, 0x21, +0x51, 0x2a, 0x95, 0x94, 0x60, 0xb8, 0x2a, 0x20, +0x30, 0xdf, 0x8b, 0x91, 0x7e, 0x5e, 0xab, 0xbf, +0xe8, 0x05, 0xa3, 0xe5, 0xab, 0x24, 0x74, 0xe4, +0xcb, 0x91, 0x3d, 0x31, 0xbb, 0xb9, 0x35, 0x1a, +0x01, 0x98, 0xad, 0x71, 0xa5, 0xdb, 0x2d, 0xf3, +0x58, 0x43, 0x82, 0xb5, 0x6d, 0x66, 0x76, 0x1a, +0xda, 0x12, 0x93, 0x9a, 0xbb, 0xaf, 0x5a, 0x7b, +0xaf, 0xf7, 0xdf, 0x18, 0xa8, 0xb7, 0x92, 0x36, +0x8f, 0x49, 0xed, 0x77, 0xef, 0x3f, 0x7c, 0xfc, +0x74, 0x40, 0x19, 0x0e, 0x8f, 0x24, 0x6d, 0x1e, +0x43, 0xc8, 0xb1, 0xd9, 0x7c, 0x2c, 0x23, 0x5a, +0x3c, 0x86, 0x90, 0x43, 0x3f, 0xf5, 0x19, 0x22, +0x78, 0x8f, 0xc1, 0x5d, 0x0e, 0x28, 0xff, 0xc9, +0xd1, 0x17, 0x84, 0xe0, 0x3c, 0x06, 0x13, 0xdb, +0x61, 0xf4, 0xdb, 0x92, 0xd4, 0xe8, 0x47, 0xba, +0x51, 0xca, 0xd5, 0xf8, 0xbb, 0xcb, 0x57, 0xe0, +0xb1, 0xd3, 0x6e, 0x17, 0xe4, 0xb1, 0x6e, 0x94, +0xcd, 0x6f, 0xdd, 0x83, 0x81, 0x5d, 0x3a, 0xee, +0xf0, 0x49, 0x6b, 0x0f, 0xed, 0x82, 0x3c, 0x86, +0x96, 0xfc, 0x7e, 0xd6, 0x3b, 0x18, 0x40, 0xce, +0x99, 0xd5, 0x0b, 0xf5, 0x04, 0x7a, 0x0c, 0x83, +0x00, 0x8f, 0x5d, 0xaa, 0x5d, 0xa0, 0xc7, 0x6e, +0x40, 0x9a, 0xbb, 0xad, 0x4e, 0x3e, 0x7c, 0xa5, +0x8e, 0x8c, 0x3c, 0xf6, 0xef, 0x5d, 0xe4, 0x60, +0x7e, 0xd4, 0xca, 0x3f, 0xd5, 0x60, 0x90, 0xc7, +0x6e, 0x4a, 0xec, 0xac, 0x0d, 0x3c, 0x76, 0xaa, +0xbe, 0x0c, 0xeb, 0x31, 0x30, 0xf2, 0xaf, 0x7c, +0xe5, 0xaa, 0x6f, 0x64, 0xac, 0xc7, 0x00, 0x72, +0x5e, 0x2b, 0x5f, 0xa8, 0x08, 0xde, 0x63, 0x52, +0xfb, 0x37, 0xf0, 0xd8, 0x65, 0x17, 0xd1, 0xe2, +0x31, 0x69, 0xbf, 0x93, 0xaf, 0x6c, 0xf6, 0x82, +0xd1, 0xe2, 0xb1, 0x06, 0xc8, 0xab, 0x7e, 0xdd, +0x0b, 0xe6, 0x16, 0x7a, 0xec, 0xff, 0xd4, 0x1f, +0x22, 0xc4, 0xba, 0x5d, 0xaf, 0x2e, 0xab, 0x14, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_unique_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_unique_png = new wxImage(); + if (!img_ex_unique_png || !img_ex_unique_png->IsOk()) + { + wxMemoryInputStream img_ex_unique_pngIS(ex_unique_png_data, sizeof(ex_unique_png_data)); + img_ex_unique_png->LoadFile(img_ex_unique_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_unique_png; +} +#define ex_unique_png_img ex_unique_png_img() + +static wxBitmap *ex_unique_png_bmp() +{ + static wxBitmap *bmp_ex_unique_png; + if (!bmp_ex_unique_png || !bmp_ex_unique_png->IsOk()) + bmp_ex_unique_png = new wxBitmap(*ex_unique_png_img); + return bmp_ex_unique_png; +} +#define ex_unique_png_bmp ex_unique_png_bmp() + +static wxIcon *ex_unique_png_ico() +{ + static wxIcon *ico_ex_unique_png; + if (!ico_ex_unique_png || !ico_ex_unique_png->IsOk()) + { + ico_ex_unique_png = new wxIcon(); + ico_ex_unique_png->CopyFromBitmap(*ex_unique_png_bmp); + } + return ico_ex_unique_png; +} +#define ex_unique_png_ico ex_unique_png_ico() + +#endif // EX_UNIQUE_PNG_H diff --git a/include/images/ex_unknown.png b/include/images/ex_unknown.png new file mode 100644 index 0000000..d5d54f5 Binary files /dev/null and b/include/images/ex_unknown.png differ diff --git a/include/images/ex_unknown.pngc b/include/images/ex_unknown.pngc new file mode 100644 index 0000000..9b7b22d --- /dev/null +++ b/include/images/ex_unknown.pngc @@ -0,0 +1,180 @@ +#ifndef EX_UNKNOWN_PNG_H +#define EX_UNKNOWN_PNG_H + +static const unsigned char ex_unknown_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x7d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaf, 0xc2, 0xd0, 0x96, +0xb8, 0xd0, 0x8e, 0xb5, 0xd1, 0x74, 0xab, 0xd1, +0x85, 0xb1, 0xd1, 0xa6, 0xbf, 0xd0, 0xc8, 0xcd, +0xd0, 0xb8, 0xc6, 0xd0, 0x53, 0x9d, 0xd1, 0x63, +0xac, 0xda, 0x72, 0xb9, 0xe0, 0x70, 0xbd, 0xe3, +0x77, 0xc5, 0xe8, 0x75, 0xc4, 0xe7, 0x78, 0xc5, +0xe7, 0x7d, 0xc6, 0xe7, 0x7d, 0xc2, 0xe4, 0x79, +0xba, 0xe0, 0x6f, 0xb3, 0xdc, 0x59, 0xa1, 0xd3, +0xc1, 0xca, 0xd0, 0x5a, 0xa4, 0xd5, 0x6e, 0xbe, +0xe5, 0x5b, 0xc5, 0xeb, 0x4a, 0xbe, 0xe8, 0x42, +0xbc, 0xe8, 0x40, 0xbb, 0xe7, 0x3f, 0xba, 0xe6, +0x43, 0xbb, 0xe7, 0x46, 0xbd, 0xe8, 0x4e, 0xbe, +0xe7, 0x59, 0xc2, 0xe9, 0x64, 0xc6, 0xe9, 0x6d, +0xc9, 0xea, 0x85, 0xd0, 0xed, 0x83, 0xc2, 0xe4, +0x69, 0xae, 0xda, 0x9f, 0xbc, 0xd0, 0x6c, 0xa7, +0xd1, 0x6e, 0xb8, 0xe0, 0x4d, 0xc0, 0xe9, 0x2f, +0xb5, 0xe6, 0x20, 0xb0, 0xe4, 0x1f, 0xaf, 0xe3, +0x24, 0xb1, 0xe4, 0x29, 0xb3, 0xe4, 0x2f, 0xb4, +0xe4, 0x34, 0xb6, 0xe5, 0x3a, 0xb8, 0xe5, 0x40, +0xb9, 0xe5, 0x45, 0xbb, 0xe6, 0x4b, 0xbd, 0xe6, +0x50, 0xbe, 0xe7, 0x6b, 0xc7, 0xe9, 0x59, 0xa2, +0xd3, 0x57, 0xa1, 0xd3, 0x68, 0xc3, 0xe8, 0x1a, +0xae, 0xe3, 0x15, 0xac, 0xe3, 0x55, 0xc0, 0xe7, +0x5a, 0xc1, 0xe7, 0x79, 0xcc, 0xeb, 0x92, 0xce, +0xea, 0x5a, 0xa2, 0xd3, 0x68, 0xbc, 0xe3, 0x2a, +0xb4, 0xe6, 0x11, 0xab, 0xe2, 0x5f, 0xc3, 0xe8, +0x95, 0xd0, 0xeb, 0x64, 0xae, 0xda, 0x0d, 0xaa, +0xe2, 0x63, 0xc4, 0xe8, 0x80, 0xcf, 0xec, 0x89, +0xc3, 0xe4, 0x64, 0xa4, 0xd1, 0x56, 0xc0, 0xe8, +0x09, 0xa9, 0xe2, 0x32, 0xb5, 0xe4, 0x46, 0xbc, +0xe6, 0x67, 0xc6, 0xe8, 0x70, 0xc9, 0xea, 0x96, +0xd7, 0xef, 0x66, 0xb0, 0xdc, 0x30, 0xb7, 0xe6, +0x60, 0xc6, 0xeb, 0x70, 0xc2, 0xe6, 0x5e, 0xc5, +0xea, 0x51, 0xc0, 0xe8, 0x83, 0xbe, 0xe1, 0x7d, +0xae, 0xd1, 0x61, 0xbd, 0xe5, 0x05, 0xa8, 0xe1, +0x5b, 0xa0, 0xd1, 0x77, 0xbd, 0xe2, 0x7e, 0xce, +0xeb, 0x79, 0xc9, 0xea, 0xbf, 0xc9, 0xd0, 0x55, +0xc2, 0xe9, 0x1d, 0xb0, 0xe4, 0x12, 0xac, 0xe3, +0x61, 0xaa, 0xd8, 0xb0, 0xc3, 0xd0, 0x69, 0xb4, +0xde, 0x5e, 0xa6, 0xd6, 0x71, 0xcb, 0xec, 0x7b, +0xc7, 0xe9, 0x8c, 0xd3, 0xed, 0x75, 0xb6, 0xde, +0x77, 0xcc, 0xea, 0x67, 0xab, 0xd8, 0x76, 0xc0, +0xe4, 0x8a, 0xca, 0xe8, 0x6d, 0xc3, 0xe8, 0xa8, +0xc0, 0xd0, 0x60, 0xc5, 0xe9, 0x7a, 0xce, 0xed, +0x75, 0xba, 0xe0, 0x41, 0xbb, 0xe8, 0x68, 0xc8, +0xeb, 0x6a, 0xc0, 0xe6, 0x80, 0xc7, 0xe8, 0x7e, +0xc8, 0xe8, 0x62, 0xc7, 0xeb, 0x67, 0xc8, 0xec, +0x6b, 0xca, 0xec, 0x7c, 0xcf, 0xed, 0x36, 0x3b, +0x47, 0xff, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x01, 0xfa, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd3, +0xfd, 0x57, 0xd2, 0x50, 0x18, 0x07, 0xf0, 0x71, +0xb9, 0x97, 0xb7, 0xf9, 0x12, 0x13, 0x51, 0x10, +0xc7, 0x36, 0x60, 0x30, 0x4c, 0x84, 0xd4, 0x69, +0x80, 0x80, 0x92, 0x96, 0x02, 0x19, 0x21, 0xb2, +0x54, 0x4c, 0x28, 0x43, 0xc3, 0xd4, 0x2c, 0x7c, +0xc9, 0xea, 0x6f, 0x6f, 0x78, 0x77, 0x4e, 0xc7, +0x4e, 0x63, 0xf7, 0x07, 0xfd, 0x8d, 0xef, 0x8f, +0x3b, 0xf7, 0x73, 0xf6, 0xdc, 0xe7, 0x79, 0x2e, +0x45, 0xf5, 0xf3, 0x00, 0x31, 0x01, 0x33, 0x54, +0x83, 0x80, 0xc5, 0x4a, 0x74, 0xde, 0x86, 0xec, +0x0e, 0x7a, 0x60, 0x70, 0x68, 0xf8, 0x89, 0x93, +0x19, 0x71, 0x21, 0x93, 0x21, 0x18, 0x45, 0xee, +0xb1, 0x71, 0x8f, 0x77, 0xc2, 0x37, 0xc9, 0xfa, +0x39, 0x5e, 0x08, 0x04, 0x43, 0x68, 0xb4, 0xb7, +0x10, 0xc3, 0x11, 0x29, 0x3a, 0xf5, 0x74, 0x3a, +0x36, 0x13, 0x4f, 0x3c, 0x9b, 0x9d, 0x9b, 0xe7, +0xe4, 0x40, 0x70, 0x41, 0xec, 0x59, 0xd4, 0xe2, +0xf3, 0x68, 0x32, 0x95, 0xfc, 0x4b, 0xd2, 0x4b, +0x7c, 0x26, 0x9b, 0xeb, 0x65, 0xd0, 0xf2, 0x4a, +0x3e, 0x7f, 0x9f, 0xbc, 0xe0, 0x33, 0xab, 0x39, +0xfd, 0xda, 0xc0, 0x5a, 0x22, 0xff, 0xf2, 0x5f, +0xf2, 0x4a, 0x5e, 0xdf, 0x40, 0xba, 0xa4, 0x50, +0x4c, 0x95, 0x34, 0xf2, 0xda, 0xb7, 0x39, 0xab, +0x91, 0x37, 0xe5, 0xb7, 0x39, 0xbd, 0x66, 0x8b, +0x95, 0xad, 0x12, 0x26, 0xb1, 0x89, 0xea, 0xf6, +0x50, 0xb9, 0xa6, 0x60, 0x22, 0x07, 0xde, 0x01, +0x1d, 0xb2, 0xb3, 0x9b, 0xdc, 0xbb, 0x23, 0xd3, +0xec, 0x80, 0x0b, 0xc2, 0xfa, 0x3e, 0xaf, 0x60, +0xf2, 0x5e, 0xb7, 0xb2, 0xba, 0x54, 0xc2, 0x24, +0x3e, 0xb6, 0x63, 0x53, 0x47, 0x54, 0x38, 0x28, +0x62, 0x92, 0xc9, 0xc2, 0xff, 0x8b, 0x86, 0xbb, +0xf9, 0x21, 0xf5, 0xb1, 0xdb, 0x31, 0xcf, 0xe1, +0xa7, 0xee, 0x07, 0x38, 0xcc, 0x19, 0x92, 0xd6, +0xf2, 0x6e, 0x51, 0x62, 0xbd, 0xde, 0x72, 0xfd, +0xee, 0x6a, 0x47, 0xc7, 0x69, 0x4c, 0xd6, 0x37, +0xcc, 0x3a, 0x85, 0x35, 0x00, 0x82, 0x05, 0xfb, +0xa2, 0xa3, 0xd2, 0xea, 0x9e, 0x00, 0xae, 0xcf, +0x1c, 0xbe, 0xbe, 0xd0, 0x3e, 0xb1, 0xf4, 0xdc, +0x19, 0xab, 0xc9, 0xd2, 0x9d, 0xb6, 0xf9, 0xf0, +0x80, 0xf3, 0x63, 0xf2, 0x65, 0x35, 0x4c, 0x19, +0xc7, 0x8a, 0x22, 0xb2, 0x7f, 0x13, 0xcf, 0x45, +0x68, 0x9f, 0x8a, 0xc6, 0xc2, 0x86, 0xe8, 0xda, +0xa4, 0x36, 0x7d, 0xb9, 0xcd, 0x98, 0x49, 0xc4, +0x59, 0x33, 0xa1, 0x2d, 0x8c, 0x1c, 0x60, 0x90, +0xb1, 0xa0, 0xd0, 0x99, 0x14, 0xc7, 0x3b, 0xb6, +0x24, 0xb7, 0x4f, 0x09, 0xfe, 0xa1, 0x2e, 0x8e, +0x12, 0xc5, 0x6b, 0x99, 0x16, 0xce, 0x17, 0x48, +0x04, 0x15, 0xfe, 0x1a, 0xc7, 0x9b, 0x3c, 0x2f, +0x04, 0xe1, 0x05, 0x89, 0x50, 0xb7, 0x20, 0x86, +0xc9, 0x37, 0x27, 0xb2, 0x91, 0x08, 0xca, 0x52, +0x61, 0xf1, 0x7b, 0x99, 0xcb, 0xb8, 0xc8, 0x04, +0x05, 0x22, 0x3e, 0x4c, 0x9a, 0x4e, 0x92, 0x5e, +0x61, 0x52, 0x95, 0x94, 0x26, 0x57, 0xe3, 0xbf, +0x33, 0x80, 0x90, 0x34, 0xdc, 0x8e, 0x35, 0x35, +0xa1, 0x50, 0xe8, 0xa8, 0x41, 0x48, 0x28, 0x11, +0x68, 0x21, 0xd8, 0x13, 0x4d, 0xb4, 0x22, 0x34, +0x4d, 0x77, 0x3a, 0x1d, 0xe6, 0x84, 0xd4, 0xc0, +0x41, 0xcf, 0x25, 0xeb, 0x51, 0x6f, 0x73, 0x75, +0x0e, 0x49, 0xc9, 0xf5, 0x0c, 0xee, 0x98, 0x72, +0xd3, 0x27, 0x64, 0xe4, 0xc7, 0xed, 0x78, 0xf5, +0xf6, 0xe7, 0xaf, 0xe3, 0xdf, 0x59, 0x52, 0x72, +0x01, 0xed, 0x5a, 0xc8, 0x1e, 0x4b, 0x3f, 0x8f, +0x90, 0x3f, 0x48, 0xfb, 0x7e, 0x02, 0x56, 0xac, +0xeb, 0xf4, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, +0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_unknown_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_unknown_png = new wxImage(); + if (!img_ex_unknown_png || !img_ex_unknown_png->IsOk()) + { + wxMemoryInputStream img_ex_unknown_pngIS(ex_unknown_png_data, sizeof(ex_unknown_png_data)); + img_ex_unknown_png->LoadFile(img_ex_unknown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_unknown_png; +} +#define ex_unknown_png_img ex_unknown_png_img() + +static wxBitmap *ex_unknown_png_bmp() +{ + static wxBitmap *bmp_ex_unknown_png; + if (!bmp_ex_unknown_png || !bmp_ex_unknown_png->IsOk()) + bmp_ex_unknown_png = new wxBitmap(*ex_unknown_png_img); + return bmp_ex_unknown_png; +} +#define ex_unknown_png_bmp ex_unknown_png_bmp() + +static wxIcon *ex_unknown_png_ico() +{ + static wxIcon *ico_ex_unknown_png; + if (!ico_ex_unknown_png || !ico_ex_unknown_png->IsOk()) + { + ico_ex_unknown_png = new wxIcon(); + ico_ex_unknown_png->CopyFromBitmap(*ex_unknown_png_bmp); + } + return ico_ex_unknown_png; +} +#define ex_unknown_png_ico ex_unknown_png_ico() + +#endif // EX_UNKNOWN_PNG_H diff --git a/include/images/ex_update.png b/include/images/ex_update.png new file mode 100644 index 0000000..a45c53f Binary files /dev/null and b/include/images/ex_update.png differ diff --git a/include/images/ex_update.pngc b/include/images/ex_update.pngc new file mode 100644 index 0000000..8fe3f13 --- /dev/null +++ b/include/images/ex_update.pngc @@ -0,0 +1,181 @@ +#ifndef EX_UPDATE_PNG_H +#define EX_UPDATE_PNG_H + +static const unsigned char ex_update_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x3e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0x5b, 0x36, +0x88, 0xc1, 0x09, 0xa9, 0xe2, 0x72, 0x96, 0xa1, +0x92, 0x92, 0x92, 0xc1, 0x8f, 0x36, 0x32, 0xb5, +0xe5, 0x75, 0xa6, 0xc7, 0x41, 0xbc, 0xe8, 0xcb, +0xa2, 0x58, 0x4a, 0xc0, 0xe9, 0xd7, 0xa8, 0x4e, +0xc7, 0xaa, 0x75, 0x5d, 0xc4, 0xea, 0xfd, 0xad, +0x01, 0x63, 0xc6, 0xea, 0x6b, 0xc7, 0xe8, 0x68, +0xc8, 0xec, 0x6e, 0xcb, 0xec, 0x75, 0xcd, 0xec, +0xda, 0xbb, 0x7e, 0xdb, 0xbd, 0x7f, 0xdb, 0xbd, +0x89, 0xe3, 0xbd, 0x73, 0xdc, 0xbe, 0x80, 0xdc, +0xbf, 0x80, 0xff, 0xbd, 0x30, 0x7b, 0xd1, 0xef, +0xdc, 0xc1, 0x82, 0x84, 0xd1, 0xee, 0xdd, 0xc3, +0x83, 0x84, 0xd3, 0xf0, 0xde, 0xc4, 0x84, 0xde, +0xc5, 0x85, 0xde, 0xc6, 0x86, 0x8c, 0xd4, 0xee, +0xdf, 0xc7, 0x87, 0xdf, 0xc8, 0x88, 0x91, 0xd5, +0xee, 0xe0, 0xc9, 0x89, 0xe1, 0xcc, 0x8a, 0x97, +0xd9, 0xf1, 0xe3, 0xcb, 0x9e, 0xe2, 0xce, 0x8c, +0xe3, 0xcc, 0x9e, 0xe4, 0xcd, 0x9e, 0xe2, 0xd0, +0x8d, 0xe4, 0xce, 0x9f, 0xa0, 0xdb, 0xf1, 0xe3, +0xd2, 0x8f, 0xe5, 0xd0, 0xa1, 0xe4, 0xd3, 0x90, +0xe6, 0xd1, 0xa1, 0xe6, 0xd1, 0xa2, 0xe4, 0xd4, +0x91, 0xe6, 0xd2, 0xa2, 0xe4, 0xd5, 0x92, 0xe6, +0xd3, 0xa3, 0xe5, 0xd6, 0x93, 0xe6, 0xd4, 0xa4, +0xe7, 0xd5, 0xa5, 0xae, 0xe0, 0xf3, 0xe6, 0xd9, +0x94, 0xe8, 0xd7, 0xa6, 0xe8, 0xd7, 0xa7, 0xe6, +0xda, 0x96, 0xe9, 0xd8, 0xa7, 0xe9, 0xd9, 0xa8, +0xe7, 0xdc, 0x97, 0xe9, 0xda, 0xa9, 0xea, 0xd9, +0xb6, 0xe9, 0xdb, 0xaa, 0xeb, 0xda, 0xb7, 0xe8, +0xde, 0x99, 0xea, 0xdd, 0xaa, 0xec, 0xdc, 0xb8, +0xe9, 0xe0, 0x9a, 0xeb, 0xde, 0xac, 0xec, 0xdd, +0xba, 0xeb, 0xdf, 0xad, 0xec, 0xde, 0xba, 0xec, +0xe0, 0xad, 0xea, 0xe3, 0x9c, 0xed, 0xdf, 0xbb, +0xec, 0xe1, 0xae, 0xed, 0xe0, 0xbb, 0xea, 0xe4, +0x9d, 0xec, 0xe2, 0xaf, 0xed, 0xe1, 0xbc, 0xec, +0xe3, 0xb0, 0xed, 0xe5, 0xb1, 0xef, 0xe4, 0xbe, +0xed, 0xe6, 0xb2, 0xee, 0xe6, 0xb3, 0xef, 0xe5, +0xc0, 0xf0, 0xe6, 0xc0, 0xef, 0xe8, 0xb3, 0xef, +0xe9, 0xb5, 0xf0, 0xe8, 0xc2, 0xf0, 0xe9, 0xc2, +0xf0, 0xec, 0xb6, 0xf1, 0xeb, 0xc4, 0xf2, 0xed, +0xc5, 0xf3, 0xed, 0xc6, 0xf3, 0xf0, 0xc8, 0xd8, +0xb5, 0xa3, 0x75, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x02, +0x9d, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, +0x93, 0xdd, 0x56, 0xda, 0x50, 0x10, 0x85, 0x31, +0xb6, 0x43, 0xa9, 0x45, 0x6b, 0x11, 0x95, 0x2a, +0xa2, 0x45, 0xd4, 0x88, 0x02, 0x12, 0x41, 0x08, +0xa1, 0x80, 0x40, 0x80, 0x44, 0x01, 0x43, 0x41, +0x08, 0x34, 0x45, 0xca, 0x9f, 0xef, 0xff, 0x02, +0x3d, 0x39, 0xe7, 0x00, 0x41, 0x43, 0x97, 0x17, +0xae, 0xd5, 0x5e, 0x38, 0x17, 0xfb, 0x2a, 0x5f, +0xb2, 0xf7, 0x9e, 0x89, 0xc5, 0xf2, 0x36, 0xff, +0x60, 0x3e, 0x30, 0xfa, 0x2c, 0x54, 0x33, 0x84, +0x71, 0xd8, 0x6c, 0xb6, 0x0d, 0x66, 0x77, 0x65, +0x75, 0x75, 0x9f, 0xd9, 0xff, 0xe2, 0x70, 0x9c, +0x32, 0xa7, 0xbb, 0x7b, 0x7b, 0x17, 0xcc, 0xc5, +0xe1, 0xf1, 0xf1, 0x77, 0xc6, 0x14, 0xb1, 0x2d, +0x2f, 0x2f, 0xdb, 0x98, 0x15, 0xa4, 0xab, 0xcc, +0x67, 0xab, 0xd5, 0xea, 0x60, 0x36, 0x10, 0xbe, +0xc7, 0x1c, 0xae, 0xaf, 0x3b, 0x8e, 0x99, 0x57, +0xfa, 0xca, 0x3b, 0xec, 0x79, 0xa1, 0x9a, 0x21, +0xf0, 0x38, 0x18, 0x0c, 0x1e, 0x27, 0xda, 0xeb, +0xf5, 0x46, 0x30, 0xd2, 0x34, 0x6d, 0x08, 0x43, +0x55, 0x55, 0xfb, 0x40, 0x9e, 0x01, 0xb0, 0x1b, +0x91, 0xc1, 0xfd, 0x7d, 0xad, 0x47, 0xb5, 0x77, +0x7b, 0x7b, 0xfb, 0x00, 0x9a, 0x94, 0xcf, 0xb7, +0x41, 0x4d, 0xa5, 0x12, 0x0a, 0x10, 0x62, 0xfc, +0xdb, 0x6e, 0x9f, 0x43, 0x6a, 0x18, 0xa9, 0x11, +0x44, 0xd2, 0x40, 0xcb, 0xe7, 0xf3, 0x2a, 0x34, +0x53, 0x89, 0x09, 0xf2, 0x63, 0x3c, 0xee, 0x66, +0x61, 0x86, 0xf4, 0x6a, 0xf8, 0x61, 0xac, 0x0f, +0x92, 0x84, 0x90, 0x76, 0xfe, 0x3a, 0xa5, 0x42, +0x3d, 0x11, 0x8f, 0x57, 0x29, 0x92, 0xcd, 0xda, +0x95, 0x31, 0xcc, 0xb2, 0x60, 0xff, 0xd3, 0x14, +0x3f, 0x71, 0x8a, 0x66, 0x1f, 0xfa, 0x4a, 0xb5, +0xdc, 0xa5, 0x59, 0x36, 0xed, 0xdf, 0xd8, 0xc1, +0x94, 0xf9, 0x04, 0xfa, 0x6c, 0x63, 0xdd, 0x7a, +0xae, 0xf4, 0xbd, 0x9b, 0xb5, 0xaf, 0x33, 0x06, +0x76, 0xf4, 0x81, 0xd1, 0x83, 0xa6, 0x8d, 0x60, +0xd8, 0x6e, 0xab, 0x43, 0xe8, 0xd7, 0x15, 0xa5, +0x0b, 0x5d, 0x59, 0x96, 0x3b, 0x93, 0x17, 0xcf, +0x31, 0xb0, 0xb3, 0xb6, 0xb6, 0xb6, 0x63, 0x48, +0xd1, 0xd4, 0x53, 0x5c, 0x95, 0x41, 0x0e, 0x07, +0x83, 0xe2, 0xcc, 0xbf, 0x81, 0xa1, 0x88, 0x26, +0x49, 0xa4, 0xd8, 0x54, 0x1d, 0x94, 0xf8, 0xd5, +0xa5, 0x0c, 0x72, 0x30, 0x78, 0x26, 0x1a, 0x6a, +0xc2, 0x0c, 0x0e, 0x37, 0x41, 0x70, 0xb1, 0x2a, +0x2e, 0xb6, 0x7a, 0x19, 0x0e, 0xcb, 0x50, 0x3c, +0x3b, 0x63, 0x73, 0x60, 0x99, 0x67, 0xec, 0x02, +0x4c, 0xb3, 0x3c, 0x4f, 0xd1, 0x11, 0x73, 0xb9, +0x16, 0x18, 0x97, 0x0e, 0x9b, 0xfa, 0x52, 0xe1, +0x65, 0x8d, 0x4d, 0x18, 0x44, 0xa1, 0x38, 0x68, +0x0b, 0xcd, 0x7a, 0x9f, 0x6a, 0xb7, 0x5a, 0x46, +0xbb, 0xe8, 0x14, 0x45, 0xb1, 0x03, 0xad, 0x4c, +0x26, 0xdd, 0x80, 0xf9, 0x7b, 0x84, 0x4c, 0xf6, +0xfd, 0x92, 0x85, 0xfa, 0x9f, 0x4f, 0xc1, 0xa2, +0x14, 0x99, 0x93, 0x23, 0x9f, 0x00, 0x4f, 0x6e, +0x18, 0x60, 0x09, 0x21, 0xf5, 0x44, 0x02, 0x1d, +0x06, 0x51, 0x39, 0x1c, 0x0e, 0x16, 0x41, 0x64, +0x59, 0x36, 0x03, 0xe9, 0x23, 0x9f, 0xf7, 0x29, +0x42, 0x41, 0xbd, 0xd2, 0x32, 0x55, 0x52, 0x6c, +0x8e, 0x3d, 0x39, 0x49, 0x43, 0xd2, 0xeb, 0xf5, +0xf2, 0xe6, 0x08, 0xf2, 0x2f, 0xff, 0xa2, 0xaa, +0xa7, 0x68, 0xa1, 0x14, 0xe9, 0x64, 0x03, 0x1a, +0x02, 0xcf, 0x57, 0x4c, 0x91, 0x8f, 0x86, 0xc6, +0xb6, 0x9f, 0xb7, 0x67, 0xfe, 0x15, 0x59, 0x2e, +0x76, 0xe8, 0x76, 0x88, 0x36, 0x92, 0x82, 0x70, +0x07, 0x95, 0x58, 0x34, 0x72, 0x63, 0x6e, 0x8c, +0xf8, 0x27, 0x37, 0x40, 0x14, 0xa5, 0x38, 0xe0, +0x21, 0xea, 0x71, 0xbb, 0x39, 0x73, 0x84, 0x1c, +0x86, 0x11, 0x11, 0xbc, 0x07, 0x9e, 0x18, 0x44, +0xdc, 0x6e, 0xd7, 0x02, 0x84, 0x54, 0x6a, 0x44, +0xf8, 0x03, 0x8f, 0x27, 0x02, 0x9c, 0xdb, 0xe5, +0x0a, 0x99, 0x23, 0x9d, 0x5c, 0x2e, 0xd3, 0x9a, +0xcb, 0x52, 0x89, 0x46, 0x23, 0x25, 0x28, 0x71, +0xa1, 0x50, 0xe9, 0xd5, 0x1a, 0x6b, 0xa5, 0x93, +0x68, 0x0b, 0x44, 0xef, 0x78, 0x3e, 0x56, 0x81, +0x1b, 0x8e, 0xe3, 0xd0, 0x57, 0x42, 0x81, 0x40, +0xc1, 0xdc, 0x18, 0x39, 0x0c, 0xa2, 0xbc, 0x07, +0xa7, 0x70, 0xe9, 0x29, 0x02, 0x4e, 0xa7, 0xf3, +0xdc, 0x1c, 0x49, 0xfa, 0xf4, 0xc3, 0x20, 0x1a, +0xc3, 0xc5, 0xce, 0x10, 0xbf, 0x39, 0x22, 0xa0, +0x2d, 0xc4, 0xa8, 0x46, 0xdd, 0x3a, 0x12, 0x72, +0xb9, 0x9c, 0x01, 0x38, 0x5f, 0x8c, 0xdc, 0xf1, +0x31, 0xe4, 0x9f, 0xa8, 0x31, 0x45, 0xc1, 0xef, +0xf7, 0x17, 0xfe, 0xd2, 0xd8, 0xd6, 0x4b, 0xfe, +0xca, 0xb7, 0xf9, 0x9f, 0xe6, 0x0f, 0x68, 0xe9, +0xb8, 0x20, 0x04, 0x8f, 0x61, 0xba, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_update_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_update_png = new wxImage(); + if (!img_ex_update_png || !img_ex_update_png->IsOk()) + { + wxMemoryInputStream img_ex_update_pngIS(ex_update_png_data, sizeof(ex_update_png_data)); + img_ex_update_png->LoadFile(img_ex_update_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_update_png; +} +#define ex_update_png_img ex_update_png_img() + +static wxBitmap *ex_update_png_bmp() +{ + static wxBitmap *bmp_ex_update_png; + if (!bmp_ex_update_png || !bmp_ex_update_png->IsOk()) + bmp_ex_update_png = new wxBitmap(*ex_update_png_img); + return bmp_ex_update_png; +} +#define ex_update_png_bmp ex_update_png_bmp() + +static wxIcon *ex_update_png_ico() +{ + static wxIcon *ico_ex_update_png; + if (!ico_ex_update_png || !ico_ex_update_png->IsOk()) + { + ico_ex_update_png = new wxIcon(); + ico_ex_update_png->CopyFromBitmap(*ex_update_png_bmp); + } + return ico_ex_update_png; +} +#define ex_update_png_ico ex_update_png_ico() + +#endif // EX_UPDATE_PNG_H diff --git a/include/images/ex_values_scan.png b/include/images/ex_values_scan.png new file mode 100644 index 0000000..15b5ab4 Binary files /dev/null and b/include/images/ex_values_scan.png differ diff --git a/include/images/ex_values_scan.pngc b/include/images/ex_values_scan.pngc new file mode 100644 index 0000000..f2ad485 --- /dev/null +++ b/include/images/ex_values_scan.pngc @@ -0,0 +1,159 @@ +#ifndef EX_VALUES_SCAN_PNG_H +#define EX_VALUES_SCAN_PNG_H + +static const unsigned char ex_values_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x01, 0x7d, 0x50, 0x4c, 0x54, +0x45, 0x89, 0xb9, 0xdb, 0x36, 0x88, 0xc1, 0x6f, +0xcd, 0xee, 0x41, 0xbd, 0xe9, 0x45, 0xbe, 0xe9, +0x75, 0xce, 0xef, 0x79, 0xd0, 0xef, 0x50, 0xc2, +0xea, 0x56, 0xc3, 0xea, 0x83, 0xd3, 0xf0, 0x89, +0xd5, 0xf0, 0x65, 0xc8, 0xec, 0x6a, 0xc9, 0xec, +0x6f, 0xca, 0xec, 0x94, 0xd8, 0xf1, 0x99, 0xda, +0xf1, 0x7b, 0xce, 0xed, 0x82, 0xd1, 0xed, 0xa4, +0xdd, 0xf1, 0xa8, 0xde, 0xf2, 0x8e, 0xd4, 0xee, +0x92, 0xd6, 0xef, 0xaf, 0xe1, 0xf3, 0x05, 0xa7, +0xe1, 0x48, 0xbf, 0xe9, 0x1b, 0xae, 0xe3, 0x5b, +0xc5, 0xeb, 0x38, 0xb7, 0xe5, 0x50, 0xbe, 0xe7, +0x55, 0xc0, 0xe7, 0x59, 0xc1, 0xe7, 0x86, 0xd1, +0xed, 0x6b, 0xc7, 0xe8, 0x6f, 0xc8, 0xe9, 0x95, +0xd7, 0xef, 0x7a, 0x9e, 0xa9, 0xa5, 0xc1, 0xe4, +0x66, 0x96, 0xd1, 0xc1, 0x8f, 0x36, 0xf1, 0xea, +0x87, 0xed, 0xe3, 0x60, 0xee, 0xe3, 0x60, 0xf2, +0xea, 0x87, 0xf3, 0xea, 0x87, 0xef, 0xe3, 0x5f, +0xef, 0xe4, 0x5f, 0xf3, 0xeb, 0x87, 0xf4, 0xeb, +0x87, 0xf0, 0xe4, 0x5f, 0xf1, 0xe4, 0x5f, 0xf5, +0xeb, 0x87, 0xf2, 0xe4, 0x5f, 0xf6, 0xeb, 0x87, +0xe1, 0xef, 0xf7, 0xe7, 0xda, 0x2b, 0xe8, 0xda, +0x2b, 0xe8, 0xda, 0x2a, 0xea, 0xdb, 0x2a, 0xec, +0xdb, 0x2a, 0xee, 0xdb, 0x2a, 0xef, 0xdb, 0x2a, +0xf3, 0xe5, 0x5f, 0xd7, 0xea, 0xf5, 0xe9, 0xda, +0x2a, 0xeb, 0xdb, 0x2a, 0xed, 0xdb, 0x2a, 0xef, +0xdc, 0x2a, 0xf0, 0xdc, 0x2a, 0xf4, 0xe5, 0x5f, +0xd6, 0xe9, 0xf4, 0xf3, 0xe4, 0x5f, 0xf5, 0xe5, +0x5f, 0xf7, 0xeb, 0x87, 0xf8, 0xeb, 0x87, 0xdb, +0xbd, 0x89, 0xd4, 0xe9, 0xf4, 0xf6, 0xe5, 0x5f, +0xd3, 0xe8, 0xf3, 0xf1, 0xdc, 0x2a, 0xf2, 0xdc, +0x2a, 0xf3, 0xdc, 0x2a, 0xf7, 0xe5, 0x5f, 0xd1, +0xe7, 0xf2, 0xf4, 0xdc, 0x2a, 0xf8, 0xe5, 0x5f, +0xf5, 0xdc, 0x2a, 0xf8, 0xe6, 0x5f, 0xf9, 0xeb, +0x87, 0xfa, 0xec, 0x87, 0xce, 0xe6, 0xf2, 0xce, +0xe5, 0xf2, 0xf9, 0xe6, 0x5f, 0xfb, 0xec, 0x86, +0xcc, 0xe5, 0xf1, 0xf5, 0xdd, 0x2a, 0xf7, 0xdd, +0x2a, 0xf8, 0xdd, 0x29, 0xfa, 0xe6, 0x5f, 0xcb, +0xe4, 0xf1, 0xf6, 0xdd, 0x2a, 0xfb, 0xe6, 0x5f, +0xca, 0xe3, 0xf0, 0xf9, 0xdd, 0x29, 0xc8, 0xe3, +0xf0, 0xf9, 0xec, 0x87, 0xfc, 0xec, 0x86, 0xc7, +0xe3, 0xf0, 0xc6, 0xe2, 0xef, 0xfc, 0xe6, 0x5f, +0xfd, 0xec, 0x86, 0xc5, 0xe1, 0xef, 0xfb, 0xde, +0x29, 0xfc, 0xde, 0x29, 0xfd, 0xe6, 0x5f, 0xf7, +0xdd, 0x29, 0xfa, 0xdd, 0x29, 0xfe, 0xe6, 0x5f, +0xc2, 0xe0, 0xee, 0xfd, 0xde, 0x29, 0xfe, 0xec, +0x86, 0xc0, 0xdf, 0xee, 0xb9, 0xdb, 0xec, 0xfe, +0xde, 0x29, 0xff, 0xe6, 0x5f, 0xd4, 0xe9, 0xf3, +0xbe, 0xde, 0xed, 0xad, 0xd6, 0xe9, 0x34, 0x56, +0x14, 0x02, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, +0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x01, 0xad, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd5, +0xc9, 0x72, 0x82, 0x40, 0x10, 0x06, 0x60, 0x1f, +0xc6, 0x99, 0x07, 0x88, 0xf1, 0x66, 0x79, 0x88, +0x0b, 0x41, 0x51, 0x41, 0x14, 0x17, 0x5c, 0x40, +0x11, 0xa3, 0xa2, 0x48, 0x58, 0x5c, 0x4a, 0x79, +0xf6, 0x60, 0x66, 0x10, 0x1c, 0xc5, 0x48, 0x55, +0x2a, 0x87, 0x94, 0x7d, 0x9a, 0xcb, 0xd7, 0x53, +0x74, 0xff, 0x35, 0x24, 0x12, 0xcf, 0xfa, 0xaf, +0x55, 0x82, 0xa7, 0x2a, 0xc5, 0x21, 0xf0, 0x25, +0x95, 0x2a, 0xbe, 0xc2, 0x58, 0x24, 0x95, 0xc9, +0xe4, 0xf2, 0xf0, 0x81, 0x0b, 0x93, 0x00, 0x24, +0x11, 0x29, 0xbe, 0xe5, 0x72, 0xd4, 0x37, 0x81, +0xef, 0x14, 0x45, 0xd1, 0x91, 0x17, 0x82, 0x74, +0x1a, 0x20, 0x92, 0xcf, 0x55, 0xab, 0x98, 0x50, +0xd5, 0x5a, 0x8d, 0x89, 0xbc, 0x10, 0x64, 0xb3, +0x98, 0x04, 0xad, 0x21, 0x55, 0x63, 0x59, 0x0e, +0x1d, 0x69, 0x86, 0xe3, 0x5a, 0x97, 0x17, 0x82, +0x42, 0x01, 0x90, 0x13, 0x83, 0x14, 0xcb, 0xf2, +0x98, 0x70, 0x7c, 0x73, 0x20, 0x44, 0x90, 0xf0, +0x24, 0x68, 0x8e, 0x6b, 0x7c, 0x60, 0xd2, 0x1c, +0x8c, 0x1f, 0x20, 0xe1, 0x0b, 0x85, 0xf1, 0x78, +0x28, 0x12, 0xa4, 0x5c, 0x06, 0xf7, 0x46, 0xdf, +0x16, 0x44, 0xb1, 0x47, 0x90, 0x4a, 0x05, 0xc4, +0xcc, 0x04, 0xa8, 0xd7, 0x41, 0xcc, 0xc0, 0x9c, +0x09, 0xa4, 0x29, 0x86, 0x69, 0xc1, 0x58, 0x84, +0x61, 0x79, 0xbe, 0xf1, 0x48, 0x60, 0x40, 0xa7, +0xe3, 0x13, 0x9e, 0x6f, 0xa2, 0x71, 0xc2, 0x96, +0x20, 0x08, 0xed, 0xe8, 0xc0, 0x74, 0xbb, 0x98, +0x04, 0x1b, 0x08, 0x4d, 0xf6, 0xe6, 0xe7, 0xf7, +0xfb, 0x98, 0x04, 0xad, 0xa1, 0x30, 0x1c, 0x7e, +0xca, 0xe8, 0xd8, 0x96, 0x65, 0x65, 0x46, 0x0c, +0x79, 0x34, 0xba, 0x0e, 0x8c, 0x38, 0x94, 0x24, +0x05, 0x11, 0x59, 0x55, 0x55, 0x85, 0x20, 0x93, +0xc9, 0x75, 0x60, 0x7a, 0xe7, 0xd6, 0x50, 0x51, +0x4d, 0x93, 0x24, 0xd3, 0xe9, 0xdd, 0xc0, 0x28, +0xa6, 0x69, 0x6a, 0x04, 0x99, 0xcf, 0xef, 0x06, +0x66, 0xa6, 0x68, 0xda, 0x92, 0x20, 0x8b, 0x45, +0xec, 0xc0, 0xac, 0x56, 0xb1, 0x03, 0xe3, 0x13, +0xd8, 0x16, 0x45, 0xb9, 0xf7, 0x50, 0x60, 0x6c, +0x1b, 0x13, 0x51, 0xf2, 0x27, 0xfb, 0x53, 0x60, +0xce, 0x44, 0x96, 0xfc, 0x0d, 0x78, 0xdf, 0xac, +0x28, 0xcb, 0xe8, 0xc0, 0x6c, 0xb7, 0x3e, 0x51, +0x55, 0xbc, 0x81, 0xd3, 0x64, 0x75, 0x2d, 0x3a, +0x30, 0x67, 0x12, 0xb4, 0xf6, 0x88, 0xae, 0x1b, +0xe8, 0xb8, 0x34, 0x0c, 0x63, 0x03, 0x2f, 0x1f, +0xbe, 0xdd, 0x0e, 0x3d, 0x7e, 0xe1, 0xfd, 0x69, +0xfa, 0x7a, 0x8d, 0x89, 0xb1, 0x76, 0x1c, 0x2b, +0x4c, 0xc0, 0xe1, 0xe8, 0xba, 0xc7, 0x03, 0xb1, +0x99, 0x53, 0x6b, 0x6b, 0x83, 0x89, 0x43, 0x90, +0x24, 0xb0, 0x5d, 0xd7, 0xc6, 0x4f, 0xec, 0xcd, +0xc0, 0x58, 0xce, 0x7e, 0x7f, 0x41, 0x3c, 0xe3, +0x65, 0x2c, 0x79, 0x27, 0x30, 0x1b, 0xcb, 0xb2, +0x36, 0xf0, 0xf6, 0x33, 0xfe, 0x6b, 0x7f, 0x9d, +0x67, 0xfd, 0x71, 0x7d, 0x01, 0xb5, 0x7e, 0x99, +0x0d, 0x58, 0x8e, 0x13, 0xf3, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_values_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_values_scan_png = new wxImage(); + if (!img_ex_values_scan_png || !img_ex_values_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_values_scan_pngIS(ex_values_scan_png_data, sizeof(ex_values_scan_png_data)); + img_ex_values_scan_png->LoadFile(img_ex_values_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_values_scan_png; +} +#define ex_values_scan_png_img ex_values_scan_png_img() + +static wxBitmap *ex_values_scan_png_bmp() +{ + static wxBitmap *bmp_ex_values_scan_png; + if (!bmp_ex_values_scan_png || !bmp_ex_values_scan_png->IsOk()) + bmp_ex_values_scan_png = new wxBitmap(*ex_values_scan_png_img); + return bmp_ex_values_scan_png; +} +#define ex_values_scan_png_bmp ex_values_scan_png_bmp() + +static wxIcon *ex_values_scan_png_ico() +{ + static wxIcon *ico_ex_values_scan_png; + if (!ico_ex_values_scan_png || !ico_ex_values_scan_png->IsOk()) + { + ico_ex_values_scan_png = new wxIcon(); + ico_ex_values_scan_png->CopyFromBitmap(*ex_values_scan_png_bmp); + } + return ico_ex_values_scan_png; +} +#define ex_values_scan_png_ico ex_values_scan_png_ico() + +#endif // EX_VALUES_SCAN_PNG_H diff --git a/include/images/ex_window_aggregate.png b/include/images/ex_window_aggregate.png new file mode 100644 index 0000000..1f858be Binary files /dev/null and b/include/images/ex_window_aggregate.png differ diff --git a/include/images/ex_window_aggregate.pngc b/include/images/ex_window_aggregate.pngc new file mode 100644 index 0000000..d0f45b3 --- /dev/null +++ b/include/images/ex_window_aggregate.pngc @@ -0,0 +1,297 @@ +#ifndef EX_WINDOW_AGGREGATE_PNG_H +#define EX_WINDOW_AGGREGATE_PNG_H + +static const unsigned char ex_window_aggregate_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0xb7, 0xe4, 0x66, +0x84, 0xd1, 0xca, 0xe3, 0xf0, 0xcc, 0xe5, 0xf1, +0xce, 0xe5, 0xf1, 0xd0, 0xe6, 0xf2, 0xd4, 0xe9, +0xf3, 0xcf, 0xe7, 0xf2, 0xc8, 0xe3, 0xf0, 0xc6, +0xe4, 0xef, 0xc3, 0xe4, 0xee, 0xc2, 0xe2, 0xed, +0xc2, 0xe2, 0xee, 0xc0, 0xe2, 0xed, 0xc1, 0xe4, +0xed, 0xc1, 0xe5, 0xee, 0xc2, 0xe6, 0xed, 0xc3, +0xe8, 0xed, 0xc3, 0xe9, 0xee, 0xc5, 0xea, 0xee, +0xc7, 0xeb, 0xef, 0xc6, 0xec, 0xef, 0xc7, 0xed, +0xef, 0xc8, 0xee, 0xef, 0xc9, 0xef, 0xf0, 0xca, +0xef, 0xf0, 0xca, 0xf0, 0xf0, 0xcb, 0xf0, 0xef, +0xcd, 0xf1, 0xf0, 0xc5, 0xdf, 0xef, 0xc5, 0xe1, +0xef, 0xcb, 0xe4, 0xf0, 0xd2, 0xe9, 0xf2, 0xce, +0xe6, 0xf1, 0xc9, 0xe4, 0xf0, 0xc3, 0xe6, 0xee, +0xc7, 0xed, 0xee, 0xc9, 0xee, 0xef, 0xca, 0xee, +0xef, 0xca, 0xf0, 0xef, 0xbf, 0xdd, 0xed, 0xc0, +0xde, 0xee, 0xc2, 0xdf, 0xee, 0xc3, 0xe0, 0xee, +0xc6, 0xe2, 0xef, 0xd6, 0xea, 0xf4, 0xcc, 0xe6, +0xf1, 0xc9, 0xe6, 0xf0, 0xc8, 0xe5, 0xef, 0xc6, +0xe7, 0xef, 0xc5, 0xe7, 0xee, 0xc4, 0xea, 0xee, +0xc9, 0xef, 0xef, 0xb8, 0xd9, 0xeb, 0xba, 0xda, +0xeb, 0xba, 0xdb, 0xec, 0xbc, 0xdc, 0xec, 0xd0, +0xe9, 0xf2, 0xce, 0xe8, 0xf1, 0xcb, 0xe7, 0xf0, +0xca, 0xe8, 0xf0, 0xc9, 0xe8, 0xef, 0xc8, 0xe8, +0xf0, 0xc7, 0xe9, 0xef, 0xb3, 0xd7, 0xea, 0xb4, +0xd8, 0xea, 0xd4, 0xeb, 0xf3, 0xd2, 0xea, 0xf2, +0xcf, 0xea, 0xf1, 0xcc, 0xea, 0xf0, 0xc9, 0xeb, +0xf0, 0xb0, 0xd4, 0xe9, 0xb1, 0xd6, 0xe9, 0xb6, +0xd9, 0xea, 0xbf, 0xde, 0xed, 0xd7, 0xeb, 0xf4, +0xd0, 0xeb, 0xf2, 0xce, 0xeb, 0xf1, 0xcd, 0xec, +0xf0, 0xca, 0xec, 0xef, 0xc8, 0xec, 0xef, 0xc8, +0xef, 0xef, 0xc9, 0xf0, 0xef, 0xab, 0xd2, 0xe8, +0xad, 0xd3, 0xe8, 0xaf, 0xd4, 0xe8, 0xd8, 0xec, +0xf4, 0xd6, 0xec, 0xf3, 0xd5, 0xed, 0xf3, 0xd2, +0xec, 0xf2, 0xd1, 0xed, 0xf1, 0xcf, 0xed, 0xf1, +0xaa, 0xd1, 0xe7, 0xaf, 0xd5, 0xe9, 0xb2, 0xd7, +0xea, 0xf7, 0xfb, 0xfd, 0xf8, 0xfc, 0xfd, 0xf9, +0xfc, 0xfd, 0xc9, 0xec, 0xf0, 0xa9, 0xd0, 0xe7, +0xae, 0xd4, 0xe9, 0xed, 0xf6, 0xfa, 0xc9, 0xcb, +0xcb, 0x91, 0x91, 0x91, 0x9c, 0x9d, 0x9d, 0x9e, +0x9f, 0x9f, 0x7b, 0x7c, 0x7c, 0x68, 0x69, 0x69, +0x5a, 0x5a, 0x5a, 0x55, 0x55, 0x55, 0x57, 0x58, +0x58, 0x51, 0x51, 0x52, 0x41, 0x41, 0x41, 0xcb, +0xed, 0xf0, 0xa8, 0xd0, 0xe7, 0xa9, 0xd1, 0xe7, +0xad, 0xd4, 0xe8, 0xb0, 0xd6, 0xe9, 0xb1, 0xb3, +0xb4, 0x81, 0x82, 0x82, 0x75, 0x75, 0x75, 0xaf, +0xb0, 0xb1, 0xc5, 0xc8, 0xc8, 0xc5, 0xc7, 0xc8, +0x35, 0x35, 0x35, 0xa7, 0xcf, 0xe7, 0xaa, 0xd2, +0xe7, 0x61, 0x61, 0x61, 0x5e, 0x5f, 0x5f, 0x6b, +0x6b, 0x6c, 0xeb, 0xf7, 0xf9, 0xf9, 0xfd, 0xfd, +0xd0, 0xd2, 0xd3, 0x3a, 0x3a, 0x3a, 0xdc, 0xe0, +0xe0, 0xdb, 0xf2, 0xf5, 0xcd, 0xee, 0xf1, 0xa7, +0xcf, 0xe6, 0xa8, 0xd0, 0xe6, 0xb8, 0xda, 0xeb, +0xf0, 0xf7, 0xfb, 0xd2, 0xd5, 0xd5, 0x49, 0x49, +0x49, 0xda, 0xef, 0xf4, 0x89, 0x8b, 0x8b, 0xc2, +0xc4, 0xc5, 0xe7, 0xf6, 0xf8, 0xce, 0xee, 0xf1, +0xa6, 0xcf, 0xe6, 0xa7, 0xd0, 0xe6, 0xaa, 0xac, +0xac, 0xb6, 0xb8, 0xb9, 0xfa, 0xfd, 0xfe, 0xda, +0xf0, 0xf4, 0xda, 0xf0, 0xf5, 0xd9, 0xf0, 0xf4, +0xe5, 0xf5, 0xf8, 0xdd, 0xf3, 0xf5, 0xcc, 0xee, +0xf0, 0xab, 0xd3, 0xe8, 0xae, 0xd5, 0xe9, 0xec, +0xef, 0xf0, 0xef, 0xf8, 0xfa, 0xe0, 0xf4, 0xf6, +0xd3, 0xef, 0xf2, 0xcf, 0xee, 0xf1, 0xa6, 0xce, +0xe6, 0xa9, 0xd1, 0xe6, 0xe3, 0xf2, 0xf7, 0x50, +0x50, 0x50, 0xdf, 0xf2, 0xf5, 0xd8, 0xf0, 0xf4, +0xd6, 0xf0, 0xf3, 0xcd, 0xee, 0xf0, 0xca, 0xee, +0xf0, 0xae, 0xd5, 0xe8, 0xf6, 0xfb, 0xfc, 0xdb, +0xf0, 0xf5, 0xdb, 0xf0, 0xf4, 0xda, 0xf1, 0xf4, +0xd0, 0xef, 0xf2, 0x9f, 0xa0, 0xa0, 0x2e, 0x2e, +0x2e, 0x27, 0x27, 0x27, 0xd8, 0xf1, 0xf4, 0xcb, +0xee, 0xf0, 0xa5, 0xce, 0xe6, 0xbe, 0xdd, 0xed, +0xdb, 0xef, 0xf5, 0x21, 0x21, 0x21, 0xf1, 0xf9, +0xfb, 0xd4, 0xef, 0xf2, 0xd7, 0xed, 0xf3, 0x92, +0x94, 0x94, 0xc4, 0xe1, 0xef, 0xdf, 0xf2, 0xf6, +0xd9, 0xf1, 0xf4, 0xef, 0xf3, 0xf4, 0x63, 0x64, +0x64, 0xec, 0xee, 0xef, 0xa8, 0xd1, 0xe6, 0xae, +0xd4, 0xe8, 0xa7, 0xa9, 0xa9, 0xf3, 0xfa, 0xfc, +0xf7, 0xfc, 0xfc, 0x7f, 0x7f, 0x7f, 0xdc, 0xf0, +0xf5, 0xaa, 0xd2, 0xe8, 0xbc, 0xbe, 0xbe, 0xd8, +0xee, 0xf4, 0xe4, 0xe7, 0xe8, 0x96, 0x97, 0x97, +0xfa, 0xfd, 0xfd, 0xaf, 0xd5, 0xe8, 0xcd, 0xef, +0xf0, 0xf5, 0xfa, 0xfc, 0x1d, 0x1d, 0x1d, 0xd0, +0xef, 0xf1, 0xcb, 0xef, 0xf0, 0xa9, 0xd2, 0xe7, +0xd2, 0xf0, 0xf2, 0xcc, 0xef, 0xf0, 0xde, 0xf1, +0xf5, 0xd7, 0xf1, 0xf4, 0xd4, 0xf0, 0xf3, 0xce, +0xf1, 0xf1, 0xbe, 0xe0, 0xed, 0xde, 0xf3, 0xf6, +0xd0, 0xf0, 0xf1, 0xcf, 0xf2, 0xf1, 0xd0, 0xf2, +0xf1, 0xbb, 0xde, 0xec, 0xcd, 0xe9, 0xf1, 0xd6, +0xee, 0xf4, 0xdb, 0xf1, 0xf5, 0xd1, 0xf1, 0xf2, +0xd1, 0xf2, 0xf2, 0xd3, 0xf2, 0xf2, 0xb2, 0xd8, +0xe9, 0xd2, 0xed, 0xf3, 0xd4, 0xf2, 0xf3, 0xd6, +0xf3, 0xf3, 0xaf, 0xd6, 0xe9, 0xb6, 0xda, 0xeb, +0xb8, 0xdd, 0xeb, 0xd8, 0xf3, 0xf4, 0xd8, 0xf3, +0xf3, 0xd9, 0xf4, 0xf4, 0xb4, 0xda, 0xea, 0xb6, +0xdc, 0xeb, 0xde, 0xf5, 0xf5, 0xdc, 0xf4, 0xf5, +0xc2, 0xe4, 0xee, 0xc9, 0xe9, 0xf0, 0xdf, 0xf6, +0xf6, 0xcb, 0x3b, 0x99, 0xf4, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x04, 0x1c, 0x49, 0x44, 0x41, 0x54, 0x48, +0xc7, 0x63, 0x60, 0x18, 0x05, 0x64, 0x01, 0x46, +0x26, 0x22, 0x00, 0x23, 0x8a, 0x16, 0x26, 0x66, +0x20, 0x60, 0x61, 0x65, 0x63, 0x67, 0xe7, 0x60, +0xe1, 0xe4, 0xe2, 0xe6, 0xe1, 0xe5, 0xe3, 0xe3, +0xe7, 0x17, 0x10, 0x10, 0x14, 0x12, 0x16, 0x16, +0x11, 0x15, 0x13, 0x97, 0x90, 0x94, 0x92, 0x96, +0x91, 0x65, 0x42, 0xd5, 0x22, 0x27, 0x2f, 0x2f, +0xcf, 0xc9, 0xac, 0xc0, 0xc6, 0xae, 0xa8, 0xa4, +0xa0, 0xcc, 0xc5, 0xc5, 0x0d, 0x02, 0x82, 0x82, +0x2a, 0x20, 0x2d, 0x22, 0x62, 0xe2, 0xaa, 0x6a, +0xea, 0x52, 0x1a, 0x32, 0x68, 0x5a, 0x34, 0x35, +0x35, 0xb5, 0xb4, 0x75, 0x74, 0x15, 0x38, 0xf4, +0x14, 0x95, 0xf4, 0x0d, 0x0c, 0x0d, 0x0d, 0xb9, +0x8c, 0x8c, 0x8c, 0x8d, 0x8d, 0x45, 0x84, 0x4d, +0x80, 0x5a, 0x54, 0x55, 0x25, 0xd4, 0x4c, 0x31, +0xb4, 0x98, 0x99, 0x9b, 0x5b, 0x58, 0x6a, 0x6a, +0xeb, 0xb2, 0x28, 0xea, 0x29, 0x5a, 0x59, 0x2b, +0xd9, 0xd8, 0xd8, 0xd8, 0xda, 0xda, 0xd9, 0xdb, +0x3b, 0x88, 0x88, 0x00, 0x1d, 0x86, 0x5d, 0x8b, +0xa3, 0xa3, 0xa3, 0x93, 0x99, 0x85, 0xa5, 0x36, +0xa7, 0x12, 0xbb, 0x9e, 0xb3, 0x8b, 0xa2, 0x95, +0x95, 0x95, 0xab, 0xab, 0x9b, 0x9b, 0x9b, 0xbb, +0xbb, 0xa8, 0x28, 0x2e, 0x2d, 0x1e, 0x1e, 0x1e, +0x9e, 0x8e, 0x5e, 0xe6, 0xde, 0xf2, 0x0a, 0x8a, +0x7a, 0x3e, 0xce, 0x40, 0xe0, 0xe2, 0xe2, 0xeb, +0xeb, 0xeb, 0xe7, 0x1f, 0x00, 0xd4, 0x13, 0x28, +0x0e, 0xd4, 0x12, 0x14, 0xac, 0x81, 0xa6, 0x25, +0x24, 0x34, 0x34, 0xcc, 0xd3, 0xc9, 0xcc, 0x52, +0x87, 0x93, 0x83, 0x3d, 0x3c, 0x3c, 0x02, 0x08, +0x22, 0x23, 0x23, 0xa3, 0xa2, 0xa2, 0x63, 0x02, +0x02, 0x02, 0x71, 0x68, 0x89, 0x0d, 0x09, 0x09, +0x8d, 0x8b, 0xf7, 0x02, 0xba, 0x2c, 0x21, 0x31, +0x09, 0x01, 0x12, 0x13, 0x13, 0x03, 0x92, 0x71, +0x68, 0x49, 0x89, 0x8d, 0x0d, 0x49, 0xf5, 0x74, +0xb2, 0xd0, 0x4e, 0x4b, 0xcf, 0xc8, 0xcc, 0xca, +0xc8, 0xce, 0xc9, 0xcd, 0xcb, 0xcf, 0xcd, 0xcd, +0x2d, 0x28, 0x4c, 0x8c, 0x29, 0x52, 0x13, 0x97, +0xc0, 0xa6, 0xa5, 0xb8, 0xa4, 0x24, 0xa4, 0xb4, +0xcc, 0xd1, 0x42, 0x4b, 0x37, 0xa1, 0x3c, 0xbb, +0xa2, 0xb2, 0x2a, 0xbd, 0xba, 0xa6, 0xba, 0xba, +0x3a, 0xab, 0xb0, 0x16, 0xa8, 0xa5, 0x08, 0xbb, +0x96, 0xba, 0xe2, 0xe2, 0xfa, 0xd0, 0x38, 0x90, +0x16, 0x9f, 0xc4, 0xec, 0x86, 0xc6, 0xa6, 0xa4, +0x66, 0x10, 0x68, 0x69, 0x6d, 0x6b, 0xef, 0xe8, +0x2c, 0x52, 0xc3, 0xaa, 0xa5, 0xab, 0xbb, 0x38, +0x16, 0xa8, 0xa5, 0xc7, 0x5b, 0x97, 0xa5, 0xb7, +0xaf, 0xbf, 0xb0, 0x2d, 0x23, 0x69, 0x02, 0x08, +0xb4, 0x4c, 0x9c, 0x34, 0x79, 0x0a, 0x50, 0x8b, +0x1a, 0x16, 0x2d, 0x53, 0xa7, 0x75, 0x97, 0x40, +0xb5, 0x70, 0x24, 0x4e, 0xaf, 0xad, 0xad, 0x9d, +0x31, 0x73, 0xc2, 0xac, 0xd9, 0x73, 0xe6, 0xb6, +0xb6, 0xcf, 0x9b, 0x32, 0x5f, 0x5d, 0x0d, 0xbb, +0x96, 0x69, 0x25, 0x0b, 0x16, 0x02, 0xb5, 0xc8, +0xb3, 0x70, 0xb8, 0x24, 0x56, 0xd4, 0xd6, 0x16, +0x2e, 0x5a, 0x3c, 0x6b, 0xf6, 0xac, 0x39, 0x73, +0x97, 0x2c, 0x5d, 0x06, 0xd4, 0x22, 0x89, 0x45, +0xcb, 0xf2, 0xae, 0x69, 0x2b, 0x60, 0x5a, 0x14, +0x57, 0x2e, 0x5a, 0xd5, 0xd6, 0x96, 0x33, 0x73, +0x35, 0x50, 0xcb, 0x9a, 0xb5, 0x4b, 0x97, 0xad, +0x5b, 0x8f, 0x5b, 0xcb, 0x06, 0x90, 0x16, 0x05, +0x0e, 0x45, 0xe7, 0x8d, 0xad, 0x6d, 0xb5, 0xb5, +0x99, 0x33, 0x37, 0x6d, 0xde, 0x02, 0xd4, 0xb2, +0xb5, 0x13, 0xa4, 0xc5, 0x14, 0x87, 0x16, 0x4f, +0xa8, 0x96, 0x88, 0xa4, 0x6d, 0xb5, 0xdb, 0x77, +0xb4, 0x4e, 0xde, 0xb4, 0x65, 0x27, 0x48, 0xcb, +0x2e, 0xac, 0x5a, 0x76, 0x43, 0xb5, 0xec, 0x81, +0x68, 0xd9, 0x9b, 0x58, 0xb9, 0x63, 0x5f, 0xf9, +0x7e, 0x90, 0x96, 0x03, 0x44, 0x6a, 0x39, 0x98, +0x34, 0x69, 0xdf, 0xa1, 0x99, 0x9b, 0x08, 0x6a, +0x09, 0x01, 0x69, 0x39, 0x0c, 0xd6, 0xb2, 0x7f, +0x11, 0xd0, 0xfb, 0x47, 0x80, 0x5a, 0x8e, 0x12, +0xab, 0x65, 0xe5, 0xb1, 0xe3, 0xf9, 0x27, 0x9a, +0x37, 0x11, 0xd2, 0xd2, 0x75, 0x32, 0xe4, 0x94, +0xa7, 0x17, 0x58, 0x4b, 0x78, 0xd2, 0xe9, 0xfc, +0xbe, 0x33, 0x9b, 0xc0, 0x5a, 0xe6, 0x9e, 0x5d, +0xdb, 0xb9, 0x4b, 0x1d, 0xa7, 0x96, 0x52, 0xa0, +0x16, 0x1d, 0x65, 0x25, 0xc5, 0xc4, 0xf4, 0x73, +0x35, 0x49, 0x7b, 0xcf, 0x9f, 0x07, 0x6a, 0x99, +0xdc, 0x5e, 0x75, 0x16, 0xa2, 0x05, 0x23, 0x57, +0x82, 0xb4, 0x5c, 0x00, 0x6a, 0x01, 0xe6, 0x31, +0xfd, 0x84, 0xf6, 0x8c, 0x8b, 0x49, 0x97, 0x20, +0x5a, 0x5a, 0xb6, 0xa5, 0x4f, 0x9e, 0x02, 0xd4, +0xa2, 0x8e, 0x45, 0xcb, 0x54, 0x90, 0x96, 0x38, +0x27, 0x60, 0x1e, 0x3b, 0x73, 0xf9, 0xca, 0xb6, +0xa4, 0x84, 0x44, 0x30, 0xb8, 0xda, 0xde, 0xdf, +0xb2, 0x14, 0xa4, 0x45, 0x0a, 0xb7, 0x16, 0x0b, +0xef, 0xb4, 0x63, 0x19, 0x95, 0xd3, 0x81, 0xa0, +0xfc, 0xe2, 0xa4, 0x49, 0x17, 0x0f, 0xf5, 0xaf, +0x6a, 0xd9, 0x0a, 0x4c, 0x97, 0x52, 0x52, 0x52, +0x58, 0xb5, 0xd4, 0x97, 0x5e, 0x73, 0xec, 0x51, +0xdc, 0x78, 0x2e, 0xaf, 0x10, 0x98, 0x5c, 0x6a, +0xdb, 0xfa, 0x57, 0xf5, 0xb7, 0xd5, 0x6e, 0x6f, +0x6c, 0x59, 0x7a, 0x7d, 0xfe, 0x2e, 0x29, 0x60, +0x69, 0x89, 0x55, 0x4b, 0xe8, 0xa9, 0x78, 0xaf, +0x1b, 0x13, 0x81, 0x49, 0x65, 0xdf, 0xcd, 0x9b, +0xfb, 0xf6, 0xed, 0xd8, 0x01, 0xa2, 0x0f, 0x9d, +0x5d, 0x7a, 0xeb, 0xfa, 0xed, 0xdb, 0xb7, 0x31, +0x0b, 0xd8, 0xe5, 0x40, 0xef, 0xdf, 0x59, 0x00, +0x0c, 0x65, 0x8e, 0x1b, 0x1b, 0x13, 0x40, 0x1e, +0x49, 0x4a, 0x6a, 0x69, 0x99, 0x09, 0x04, 0x2d, +0x1d, 0x77, 0x6f, 0x5d, 0xbf, 0x77, 0xef, 0x9e, +0x8c, 0x2c, 0x76, 0x2d, 0xa5, 0x65, 0x4e, 0x3d, +0x96, 0xbc, 0x5c, 0x06, 0x4a, 0x56, 0x2e, 0xce, +0x07, 0x2f, 0x4d, 0xd8, 0x74, 0x7f, 0xf5, 0xbc, +0x2d, 0x0f, 0x1e, 0x6e, 0xbd, 0x7e, 0x5d, 0xf6, +0xba, 0xac, 0xec, 0x23, 0xac, 0x5a, 0x42, 0xaf, +0xc5, 0x7b, 0x59, 0x3c, 0x06, 0xea, 0xb1, 0xb1, +0x72, 0x89, 0x8a, 0x04, 0xea, 0x59, 0xfd, 0xa4, +0x63, 0xe7, 0xda, 0xbb, 0x4f, 0x9f, 0x3e, 0x7a, +0xf4, 0xe8, 0xd9, 0x73, 0xcc, 0x5c, 0x09, 0xd2, +0xb2, 0xc1, 0xd3, 0xa9, 0xe7, 0x05, 0x58, 0xcf, +0x4b, 0xdf, 0xa8, 0xc8, 0x57, 0x13, 0x5e, 0x3f, +0x99, 0xd7, 0xf1, 0xe0, 0xe1, 0xdd, 0x37, 0x6f, +0xde, 0xbc, 0x7d, 0xfb, 0x0e, 0x87, 0x96, 0xb2, +0xf7, 0x5e, 0x40, 0x3d, 0x3c, 0xdc, 0x86, 0x06, +0x2f, 0x5d, 0x7d, 0x3f, 0xbc, 0x5a, 0x03, 0xd6, +0xb3, 0xf6, 0x23, 0x10, 0x7c, 0xfa, 0x84, 0x51, +0xc2, 0x74, 0xaf, 0xa8, 0x5f, 0x10, 0x7a, 0xea, +0x73, 0xbc, 0xd3, 0x97, 0xaf, 0x2f, 0x1e, 0xf3, +0x71, 0x73, 0xd9, 0xdb, 0xba, 0xf9, 0x45, 0x1d, +0x58, 0xd3, 0xb1, 0x64, 0x5e, 0xc7, 0xb7, 0xef, +0xdf, 0xbe, 0xfd, 0xf8, 0xf1, 0x03, 0xb3, 0x1c, +0x2b, 0xb9, 0x00, 0xb4, 0xe5, 0x73, 0xfc, 0xfb, +0x9f, 0xbf, 0x40, 0x7a, 0xf8, 0xb9, 0x8d, 0xec, +0xdc, 0xfc, 0xa2, 0x0f, 0x1c, 0x7d, 0xb2, 0xe4, +0xf7, 0x1f, 0x30, 0xf8, 0x8d, 0x5e, 0xc0, 0x96, +0x94, 0xd4, 0x2f, 0x28, 0x2d, 0xdd, 0x50, 0x06, +0xd1, 0x02, 0xd4, 0xf3, 0x57, 0xc5, 0xe8, 0x9f, +0x5b, 0xcc, 0xd2, 0xb5, 0x1d, 0x4b, 0x96, 0xfc, +0x06, 0x82, 0xff, 0xff, 0xff, 0xa3, 0x6a, 0x21, +0xa3, 0x7a, 0x1d, 0x05, 0x44, 0x03, 0x00, 0xb8, +0x51, 0x33, 0x07, 0xb4, 0x85, 0xa6, 0x20, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_window_aggregate_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_window_aggregate_png = new wxImage(); + if (!img_ex_window_aggregate_png || !img_ex_window_aggregate_png->IsOk()) + { + wxMemoryInputStream img_ex_window_aggregate_pngIS(ex_window_aggregate_png_data, sizeof(ex_window_aggregate_png_data)); + img_ex_window_aggregate_png->LoadFile(img_ex_window_aggregate_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_window_aggregate_png; +} +#define ex_window_aggregate_png_img ex_window_aggregate_png_img() + +static wxBitmap *ex_window_aggregate_png_bmp() +{ + static wxBitmap *bmp_ex_window_aggregate_png; + if (!bmp_ex_window_aggregate_png || !bmp_ex_window_aggregate_png->IsOk()) + bmp_ex_window_aggregate_png = new wxBitmap(*ex_window_aggregate_png_img); + return bmp_ex_window_aggregate_png; +} +#define ex_window_aggregate_png_bmp ex_window_aggregate_png_bmp() + +static wxIcon *ex_window_aggregate_png_ico() +{ + static wxIcon *ico_ex_window_aggregate_png; + if (!ico_ex_window_aggregate_png || !ico_ex_window_aggregate_png->IsOk()) + { + ico_ex_window_aggregate_png = new wxIcon(); + ico_ex_window_aggregate_png->CopyFromBitmap(*ex_window_aggregate_png_bmp); + } + return ico_ex_window_aggregate_png; +} +#define ex_window_aggregate_png_ico ex_window_aggregate_png_ico() + +#endif // EX_WINDOW_AGGREGATE_PNG_H diff --git a/include/images/ex_worktable_scan.png b/include/images/ex_worktable_scan.png new file mode 100644 index 0000000..b51e0b3 Binary files /dev/null and b/include/images/ex_worktable_scan.png differ diff --git a/include/images/ex_worktable_scan.pngc b/include/images/ex_worktable_scan.pngc new file mode 100644 index 0000000..b3f567c --- /dev/null +++ b/include/images/ex_worktable_scan.pngc @@ -0,0 +1,290 @@ +#ifndef EX_WORKTABLE_SCAN_PNG_H +#define EX_WORKTABLE_SCAN_PNG_H + +static const unsigned char ex_worktable_scan_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x32, +0x08, 0x03, 0x00, 0x00, 0x00, 0x29, 0xe1, 0x78, +0x83, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xb9, 0xdb, 0x36, +0x88, 0xc1, 0x6f, 0xcd, 0xee, 0x41, 0xbd, 0xe9, +0x45, 0xbe, 0xe9, 0x75, 0xce, 0xef, 0x79, 0xd0, +0xef, 0x51, 0xc2, 0xea, 0x54, 0xc2, 0xea, 0x57, +0xc3, 0xea, 0x83, 0xd3, 0xf0, 0x89, 0xd5, 0xf0, +0x66, 0xc8, 0xec, 0x6a, 0xc9, 0xec, 0x6e, 0xca, +0xec, 0x94, 0xd8, 0xf1, 0x99, 0xda, 0xf1, 0x7c, +0xce, 0xed, 0x80, 0xd0, 0xed, 0x83, 0xd1, 0xed, +0xa4, 0xdd, 0xf1, 0xa8, 0xde, 0xf2, 0x8e, 0xd4, +0xee, 0x91, 0xd5, 0xee, 0x93, 0xd6, 0xef, 0xaf, +0xe1, 0xf3, 0x04, 0xa7, 0xe1, 0x08, 0xa8, 0xe2, +0x48, 0xbf, 0xe9, 0x4d, 0xc1, 0xe9, 0x17, 0xad, +0xe3, 0x1d, 0xaf, 0xe3, 0x5b, 0xc5, 0xeb, 0x62, +0xc7, 0xeb, 0x33, 0xb5, 0xe5, 0x38, 0xb7, 0xe5, +0x3d, 0xb8, 0xe5, 0x71, 0xcb, 0xec, 0x78, 0xce, +0xec, 0x50, 0xbe, 0xe7, 0x55, 0xc0, 0xe7, 0x59, +0xc1, 0xe7, 0x86, 0xd1, 0xed, 0x6b, 0xc7, 0xe8, +0x6f, 0xc8, 0xe9, 0x95, 0xd7, 0xef, 0x7d, 0x8b, +0xb5, 0xa5, 0xc1, 0xe4, 0x66, 0x96, 0xd1, 0xd0, +0x44, 0x65, 0xf4, 0xc9, 0xd9, 0xf0, 0xb7, 0xcc, +0xef, 0xb6, 0xcb, 0xf3, 0xc7, 0xd7, 0xee, 0xb3, +0xc8, 0xee, 0xb2, 0xc7, 0xf1, 0xc4, 0xd4, 0xec, +0xb0, 0xc5, 0xec, 0xaf, 0xc4, 0xec, 0xae, 0xc3, +0xf0, 0xc1, 0xd1, 0xef, 0xc0, 0xd0, 0xea, 0xab, +0xc0, 0xe9, 0xaa, 0xbf, 0xee, 0xbe, 0xce, 0xe1, +0xef, 0xf7, 0xeb, 0x9f, 0xbb, 0xea, 0x9d, 0xba, +0xea, 0x9c, 0xb9, 0xe9, 0x9b, 0xb8, 0xef, 0xb4, +0xc9, 0xe8, 0x99, 0xb5, 0xe7, 0x98, 0xb4, 0xe7, +0x97, 0xb3, 0xe5, 0x94, 0xaf, 0xe4, 0x92, 0xae, +0xeb, 0xad, 0xc2, 0xe2, 0x8e, 0xa9, 0xe1, 0x8c, +0xa7, 0xe8, 0xa8, 0xbc, 0xd7, 0xea, 0xf5, 0xe9, +0x9c, 0xb8, 0xe9, 0x9a, 0xb7, 0xe6, 0x96, 0xb2, +0xe3, 0x91, 0xac, 0xe3, 0x90, 0xab, 0xe0, 0x8a, +0xa5, 0xd6, 0xe9, 0xf4, 0xef, 0xb4, 0xca, 0xe8, +0x99, 0xb6, 0xed, 0xb1, 0xc6, 0xe6, 0x95, 0xb1, +0xe5, 0x94, 0xb0, 0xdf, 0x89, 0xa4, 0xdf, 0x88, +0xa3, 0xe6, 0xa5, 0xb9, 0x8b, 0x3f, 0x51, 0x53, +0x4d, 0x4f, 0x46, 0x43, 0x44, 0x94, 0x74, 0x7e, +0x85, 0x6d, 0x76, 0x3a, 0x3a, 0x3a, 0x77, 0x3e, +0x4c, 0xc4, 0xa2, 0xae, 0x76, 0x64, 0x6a, 0x84, +0x6b, 0x74, 0x84, 0x71, 0x78, 0x44, 0x3b, 0x3d, +0x5d, 0x51, 0x55, 0xa7, 0x81, 0x8e, 0x82, 0x68, +0x70, 0xc0, 0x9c, 0xa8, 0x6c, 0x3d, 0x48, 0x81, +0x66, 0x6e, 0x69, 0x5c, 0x60, 0xa0, 0x41, 0x57, +0x50, 0x46, 0x49, 0xe5, 0xe5, 0xe5, 0xf2, 0xf2, +0xf2, 0x89, 0x89, 0x89, 0xff, 0xff, 0xff, 0xb0, +0xb0, 0xb0, 0xbd, 0xbd, 0xbd, 0x54, 0x54, 0x54, +0xd8, 0xd8, 0xd8, 0x61, 0x61, 0x61, 0x96, 0x96, +0x96, 0x6f, 0x6f, 0x6f, 0xca, 0xca, 0xca, 0x67, +0x51, 0x57, 0xd4, 0xe9, 0xf4, 0xa3, 0xa3, 0xa3, +0x47, 0x47, 0x47, 0xd3, 0xe8, 0xf3, 0x95, 0x40, +0x54, 0x7c, 0x7c, 0x7c, 0xa4, 0x7e, 0x8b, 0x45, +0x40, 0x41, 0x51, 0x48, 0x4b, 0xd2, 0xe7, 0xf3, +0xbc, 0x43, 0x5f, 0xaf, 0x85, 0x93, 0x5c, 0x4c, +0x50, 0x73, 0x5d, 0x64, 0x4f, 0x43, 0x47, 0xce, +0x92, 0xa4, 0x51, 0x49, 0x4c, 0x7f, 0x62, 0x6a, +0xd0, 0xe6, 0xf2, 0xce, 0xe6, 0xf2, 0xe3, 0x91, +0xa4, 0x62, 0x3d, 0x45, 0x80, 0x3f, 0x4e, 0xce, +0xe5, 0xf2, 0x69, 0x5a, 0x5f, 0xb5, 0x96, 0xa0, +0xc8, 0x95, 0xa5, 0x83, 0x6e, 0x75, 0xa3, 0x7b, +0x87, 0xcf, 0x94, 0xa6, 0xcc, 0xe5, 0xf1, 0xd4, +0x9c, 0xaf, 0x7d, 0x5d, 0x66, 0x66, 0x4f, 0x57, +0xa9, 0x41, 0x5a, 0x68, 0x57, 0x5c, 0x73, 0x5c, +0x63, 0x7c, 0x58, 0x63, 0xd8, 0x7c, 0x96, 0xd9, +0x98, 0xaa, 0xcb, 0xe4, 0xf1, 0x8c, 0x6e, 0x77, +0xb8, 0x6e, 0x83, 0x93, 0x6e, 0x78, 0xb2, 0x42, +0x5c, 0xca, 0xe3, 0xf0, 0xc8, 0xe3, 0xf0, 0xca, +0xa4, 0xb1, 0xbf, 0x86, 0x95, 0x96, 0x7a, 0x82, +0x8c, 0x72, 0x79, 0xc7, 0xe3, 0xf0, 0x89, 0x62, +0x6c, 0xc6, 0xe2, 0xef, 0x4e, 0x3b, 0x40, 0xc5, +0xe1, 0xef, 0xc5, 0x91, 0xa1, 0xc5, 0x75, 0x8c, +0xc2, 0xe0, 0xee, 0x70, 0x52, 0x5b, 0xb9, 0x87, +0x96, 0x89, 0x69, 0x72, 0xd9, 0x7d, 0x97, 0x71, +0x5a, 0x60, 0x66, 0x53, 0x58, 0xec, 0xba, 0xc9, +0xe4, 0xa1, 0xb5, 0xea, 0xb6, 0xc5, 0xe2, 0x9e, +0xb1, 0xe2, 0x9d, 0xb0, 0xe1, 0x9c, 0xaf, 0xe8, +0xb4, 0xc3, 0xe8, 0xb2, 0xc1, 0xdf, 0x98, 0xab, +0xdf, 0x97, 0xaa, 0xe6, 0xb0, 0xbf, 0xe6, 0xae, +0xbc, 0xdd, 0x95, 0xa7, 0xdd, 0x94, 0xa7, 0xdd, +0x93, 0xa6, 0xe4, 0xad, 0xbb, 0xe4, 0xab, 0xba, +0xdb, 0x91, 0xa4, 0xdb, 0x90, 0xa2, 0xda, 0x8f, +0xa2, 0xe3, 0xab, 0xb8, 0xc0, 0xdf, 0xee, 0xeb, +0xb8, 0xc7, 0xe3, 0x9f, 0xb3, 0xe3, 0x9e, 0xb2, +0xe0, 0x9b, 0xae, 0xe0, 0x9a, 0xad, 0xe0, 0x99, +0xac, 0xe7, 0xb2, 0xc0, 0xde, 0x96, 0xa9, 0xde, +0x95, 0xa8, 0xdc, 0x92, 0xa4, 0xda, 0x8f, 0xa1, +0xda, 0x8e, 0xa0, 0xb9, 0xdb, 0xec, 0xe1, 0x9c, +0xb0, 0xd6, 0x78, 0x92, 0xd5, 0x77, 0x90, 0xd5, +0x76, 0x8f, 0xd3, 0x72, 0x8c, 0xd2, 0x70, 0x89, +0xd0, 0x6d, 0x86, 0xcf, 0x6c, 0x84, 0xcf, 0x6b, +0x83, 0xcd, 0x68, 0x81, 0xcd, 0x67, 0x7f, 0xd9, +0x8c, 0x9e, 0xd4, 0xe9, 0xf3, 0xbe, 0xde, 0xed, +0xad, 0xd6, 0xe9, 0xd8, 0x7b, 0x95, 0xd7, 0x7a, +0x94, 0xd4, 0x74, 0x8e, 0xd1, 0x6f, 0x88, 0xce, +0x6a, 0x82, 0xcc, 0x66, 0x7e, 0xce, 0x69, 0x82, +0xce, 0x69, 0x81, 0xda, 0x8e, 0xa1, 0xe2, 0xa9, +0xb6, 0x7c, 0xe0, 0xeb, 0x8e, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x79, 0xa1, 0xdc, 0xd4, 0xd0, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x03, 0xd7, +0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0x94, +0x79, 0x54, 0x55, 0x55, 0x14, 0xc6, 0xe9, 0xa6, +0x4d, 0x36, 0x4f, 0x6a, 0x36, 0xd8, 0x3c, 0x59, +0xf1, 0x36, 0x3c, 0x19, 0xc4, 0x20, 0x31, 0x2a, +0x42, 0xd1, 0x1c, 0x30, 0x6d, 0x70, 0xea, 0xbc, +0x14, 0x34, 0x21, 0xba, 0xf7, 0xee, 0x37, 0xdc, +0xf7, 0xae, 0xde, 0x27, 0x2f, 0x35, 0xa1, 0x40, +0x2d, 0x4d, 0xd4, 0x4c, 0x93, 0xac, 0xd0, 0x4a, +0x53, 0x83, 0x92, 0x0a, 0x32, 0xa3, 0xc0, 0x01, +0x27, 0x44, 0x24, 0x40, 0x4d, 0x20, 0xe4, 0x29, +0x0a, 0x6a, 0xe1, 0x39, 0x27, 0x28, 0xee, 0xed, +0xd1, 0x5a, 0xae, 0xe5, 0x6a, 0xf5, 0x87, 0xfb, +0x8f, 0x7d, 0xdf, 0xbb, 0xeb, 0xfc, 0xd6, 0xb7, +0xbf, 0xfd, 0xdd, 0x75, 0xfc, 0xfc, 0xce, 0xd7, +0x7f, 0x5d, 0x17, 0x08, 0xac, 0x3a, 0xec, 0xbe, +0x10, 0xe1, 0xc2, 0x4e, 0x9d, 0x3b, 0x5f, 0x24, +0x5c, 0x7c, 0xc9, 0xa5, 0x97, 0x75, 0x11, 0x2e, +0xbf, 0xe2, 0xca, 0xab, 0xae, 0x16, 0xae, 0xb9, +0xf6, 0xba, 0xeb, 0x6f, 0x10, 0x6e, 0xec, 0xda, +0xad, 0xfb, 0x4d, 0x82, 0x4f, 0xa4, 0x53, 0x8f, +0x1e, 0x37, 0xdf, 0x22, 0xdc, 0x7a, 0x5b, 0xcf, +0x9e, 0xb7, 0x0b, 0x77, 0xdc, 0x79, 0xd7, 0xdd, +0xf7, 0x08, 0xf7, 0xde, 0x77, 0xff, 0x03, 0x0f, +0x0a, 0x5d, 0x7b, 0xf5, 0x7a, 0xe8, 0x61, 0xe1, +0x1c, 0xa9, 0x3c, 0xc2, 0x67, 0xee, 0xb0, 0xeb, +0xce, 0xfa, 0x9b, 0x4c, 0xfe, 0xf4, 0x01, 0x01, +0x81, 0x81, 0x81, 0x01, 0x10, 0x60, 0x36, 0x9b, +0x7b, 0x43, 0xef, 0xa0, 0xa0, 0xe0, 0x10, 0x08, +0x09, 0xed, 0x13, 0xd6, 0x17, 0x1e, 0x0d, 0x8f, +0x88, 0x78, 0x0c, 0x74, 0x88, 0xa9, 0x5f, 0x3f, +0x13, 0x43, 0x02, 0x23, 0x23, 0x23, 0xcd, 0x60, +0xee, 0xff, 0x78, 0xd4, 0x13, 0x10, 0xf4, 0xe4, +0x53, 0xd1, 0xa1, 0xd0, 0xe7, 0xe9, 0x98, 0x98, +0x01, 0x10, 0x3e, 0x30, 0x36, 0x76, 0x90, 0x01, +0x19, 0x3c, 0xb8, 0x3d, 0xf2, 0x4c, 0xd4, 0x90, +0x20, 0x08, 0x8e, 0x8e, 0x1e, 0x1a, 0x0a, 0x61, +0x31, 0xc3, 0x86, 0x87, 0x43, 0x44, 0x6c, 0x5c, +0x9c, 0x11, 0x19, 0x31, 0xa2, 0x0d, 0xe9, 0x6f, +0x86, 0x67, 0xa3, 0x86, 0x8c, 0x0c, 0x86, 0x51, +0x43, 0x9f, 0x7b, 0x3e, 0x0c, 0x06, 0x0c, 0x1b, +0x3e, 0x30, 0x02, 0x06, 0xc5, 0xbd, 0xf0, 0xe2, +0x68, 0x9f, 0xc8, 0x98, 0xb1, 0xe3, 0xc6, 0xbf, +0x44, 0x2c, 0x2f, 0x4f, 0x20, 0x13, 0xe3, 0x13, +0x08, 0x99, 0x34, 0x39, 0x9e, 0xd0, 0x7a, 0x65, +0x4a, 0x22, 0x49, 0x4a, 0x22, 0xaf, 0x26, 0xfb, +0x42, 0x5e, 0x13, 0xa5, 0x04, 0x19, 0xad, 0x89, +0x36, 0xb4, 0x5b, 0x25, 0x44, 0x87, 0xa2, 0x20, +0x2d, 0x27, 0xfd, 0xaf, 0xb8, 0x50, 0x9d, 0xaa, +0x47, 0xa6, 0x4d, 0x63, 0x88, 0xc5, 0x8a, 0x76, +0x27, 0xaa, 0x63, 0x45, 0x51, 0x46, 0x8d, 0xd8, +0x51, 0x55, 0xe8, 0x43, 0x44, 0x37, 0x45, 0x1c, +0xa2, 0xdb, 0xa0, 0x32, 0x7d, 0x3a, 0x43, 0x52, +0x64, 0xf4, 0xa8, 0x28, 0xb9, 0x25, 0xab, 0x13, +0xe5, 0xd7, 0x67, 0x48, 0x12, 0x47, 0xc4, 0x99, +0x36, 0x54, 0x51, 0x1e, 0x6f, 0xf0, 0x32, 0x6b, +0x16, 0x43, 0xde, 0xb0, 0xa3, 0x53, 0x54, 0xd1, +0x83, 0xb2, 0x86, 0x9e, 0xd9, 0xa9, 0x0e, 0x89, +0x0d, 0x26, 0x2a, 0x69, 0x36, 0xda, 0xdf, 0x7c, +0xcb, 0x27, 0x02, 0xe9, 0x14, 0x70, 0x49, 0x2a, +0x1b, 0xaf, 0x4d, 0x45, 0x43, 0x99, 0x22, 0x36, +0xd4, 0x32, 0x0c, 0xc8, 0x9c, 0x39, 0x1c, 0x89, +0xb7, 0x4a, 0xd2, 0x38, 0x55, 0x12, 0xd3, 0x3d, +0x7f, 0x79, 0x99, 0x29, 0x8a, 0xdc, 0x0b, 0xba, +0x52, 0xf4, 0xc8, 0xdc, 0xb9, 0x0c, 0x99, 0x47, +0xcd, 0xa8, 0x6f, 0x3b, 0xd1, 0x6a, 0xb1, 0xb4, +0x6d, 0x4c, 0x7b, 0xc7, 0x83, 0x2a, 0x45, 0x14, +0x74, 0xa4, 0xea, 0x91, 0xf9, 0xf3, 0xb9, 0x4a, +0xc8, 0x44, 0xb2, 0xe0, 0x5d, 0x0b, 0x49, 0x5a, +0xb8, 0x30, 0x93, 0xe5, 0xb2, 0x28, 0x93, 0x64, +0x2e, 0xce, 0x20, 0x0b, 0x12, 0x49, 0x46, 0x06, +0x99, 0x64, 0x50, 0x59, 0xb2, 0x84, 0x2f, 0x99, +0x25, 0x47, 0x2c, 0xef, 0x2d, 0x25, 0xef, 0xcf, +0x5e, 0x96, 0x46, 0x7f, 0x2e, 0x4f, 0xfe, 0x80, +0xac, 0xc8, 0xfa, 0x90, 0xbf, 0x37, 0x7a, 0x59, +0xb9, 0x92, 0x22, 0x92, 0x9b, 0x25, 0x87, 0xda, +0x47, 0x1a, 0xaa, 0xcb, 0x69, 0x7e, 0x48, 0xa7, +0xa4, 0x33, 0x7d, 0xfc, 0x89, 0x93, 0xbd, 0x56, +0xb2, 0xf5, 0xc8, 0xaa, 0x55, 0x7f, 0xaa, 0x28, +0x68, 0x23, 0x96, 0x74, 0x91, 0x66, 0xc3, 0x22, +0xb7, 0xa2, 0xab, 0x15, 0x71, 0xfe, 0x53, 0x65, +0xf5, 0x6a, 0xee, 0xe5, 0x53, 0x8a, 0x4c, 0x58, +0xe6, 0x62, 0xc9, 0x31, 0x84, 0x7e, 0x38, 0xb4, +0x7f, 0xf6, 0x39, 0x43, 0x66, 0xac, 0x31, 0x20, +0x6b, 0xd7, 0xf2, 0x8d, 0x65, 0x53, 0x24, 0xf1, +0x0b, 0x0d, 0xed, 0x92, 0x3a, 0x95, 0x0f, 0xc6, +0xf6, 0x9b, 0x3d, 0x86, 0x0d, 0x26, 0x25, 0xcc, +0xd3, 0x23, 0xeb, 0xd6, 0xfd, 0xad, 0xb2, 0x5e, +0x64, 0x27, 0xdc, 0x7c, 0xb3, 0xd6, 0x8e, 0x55, +0x36, 0x6c, 0xe0, 0xc8, 0x97, 0x14, 0x49, 0x73, +0xd1, 0x03, 0x32, 0xca, 0xf4, 0xb0, 0x87, 0x23, +0x24, 0x95, 0x7b, 0x59, 0xfa, 0x2f, 0x88, 0xa2, +0xd9, 0x73, 0xdc, 0x9a, 0xcc, 0x07, 0xb3, 0xb3, +0xee, 0xf0, 0xb9, 0xb1, 0xdc, 0x5c, 0x8e, 0x8c, +0x5e, 0x41, 0xbe, 0xfa, 0x3a, 0x7b, 0x63, 0x4e, +0x5e, 0xce, 0xc6, 0x94, 0x6f, 0x68, 0x16, 0xdf, +0x26, 0xb3, 0x9e, 0xca, 0x73, 0x31, 0xaa, 0xb4, +0x22, 0xdf, 0xe5, 0xe7, 0xe7, 0x17, 0x40, 0xc1, +0xf7, 0x9b, 0x7e, 0xd8, 0x0c, 0x3f, 0x16, 0x16, +0xfe, 0xf4, 0x33, 0x14, 0x15, 0x6f, 0xd9, 0xba, +0x0d, 0xb6, 0x97, 0xec, 0xd8, 0xb9, 0xcb, 0x80, +0xec, 0xde, 0xcd, 0x37, 0x06, 0xac, 0x3a, 0xec, +0xbe, 0x10, 0xd8, 0x53, 0x5a, 0xba, 0xb7, 0x00, +0x36, 0x97, 0xed, 0x2b, 0xdf, 0x0f, 0xfb, 0x2b, +0x7e, 0x29, 0x2e, 0x82, 0xa2, 0xca, 0xca, 0x92, +0xed, 0xb0, 0xab, 0xaa, 0xaa, 0x5a, 0xa7, 0x42, +0x2f, 0xbe, 0x03, 0x07, 0xd8, 0xe5, 0x07, 0xa5, +0x79, 0x79, 0x59, 0x07, 0xa1, 0xec, 0xd0, 0xaf, +0x87, 0x0b, 0xa1, 0xa2, 0xa6, 0xb6, 0x76, 0x2b, +0x54, 0xd6, 0xfd, 0x56, 0xbf, 0x13, 0xaa, 0x8e, +0x1c, 0x69, 0xf0, 0xb6, 0x47, 0x4c, 0x47, 0x8f, +0x35, 0x36, 0x1e, 0x3b, 0x6a, 0xf2, 0x83, 0xbd, +0x59, 0xc7, 0x4f, 0x94, 0x41, 0xf9, 0xe1, 0xa6, +0xa6, 0x0a, 0x28, 0xae, 0x6d, 0x6e, 0xae, 0x84, +0x92, 0xfa, 0xfa, 0x93, 0x55, 0x50, 0xdd, 0xd0, +0x70, 0xca, 0xab, 0x57, 0xc9, 0x6d, 0x6c, 0xcc, +0x65, 0x2a, 0x9b, 0x8e, 0x9f, 0x38, 0x54, 0x0e, +0x85, 0x4d, 0x35, 0x35, 0xc5, 0xb0, 0xa5, 0xb9, +0xae, 0xae, 0x04, 0x76, 0x9c, 0x3c, 0xfd, 0x7b, +0x35, 0x45, 0x4e, 0xe9, 0x11, 0xca, 0xd0, 0x6f, +0xcc, 0x9f, 0x7a, 0x69, 0xef, 0x62, 0x5b, 0xab, +0x8b, 0x3f, 0xaa, 0x5b, 0xa0, 0xc5, 0xeb, 0xf5, +0xb6, 0xe8, 0x37, 0xd6, 0x7a, 0x8d, 0x9f, 0xcd, +0xc6, 0xce, 0xd7, 0xff, 0xab, 0xce, 0x00, 0x12, +0x8e, 0x07, 0x90, 0xbf, 0x23, 0x5e, 0xfa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *ex_worktable_scan_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_ex_worktable_scan_png = new wxImage(); + if (!img_ex_worktable_scan_png || !img_ex_worktable_scan_png->IsOk()) + { + wxMemoryInputStream img_ex_worktable_scan_pngIS(ex_worktable_scan_png_data, sizeof(ex_worktable_scan_png_data)); + img_ex_worktable_scan_png->LoadFile(img_ex_worktable_scan_pngIS, wxBITMAP_TYPE_PNG); + } + return img_ex_worktable_scan_png; +} +#define ex_worktable_scan_png_img ex_worktable_scan_png_img() + +static wxBitmap *ex_worktable_scan_png_bmp() +{ + static wxBitmap *bmp_ex_worktable_scan_png; + if (!bmp_ex_worktable_scan_png || !bmp_ex_worktable_scan_png->IsOk()) + bmp_ex_worktable_scan_png = new wxBitmap(*ex_worktable_scan_png_img); + return bmp_ex_worktable_scan_png; +} +#define ex_worktable_scan_png_bmp ex_worktable_scan_png_bmp() + +static wxIcon *ex_worktable_scan_png_ico() +{ + static wxIcon *ico_ex_worktable_scan_png; + if (!ico_ex_worktable_scan_png || !ico_ex_worktable_scan_png->IsOk()) + { + ico_ex_worktable_scan_png = new wxIcon(); + ico_ex_worktable_scan_png->CopyFromBitmap(*ex_worktable_scan_png_bmp); + } + return ico_ex_worktable_scan_png; +} +#define ex_worktable_scan_png_ico ex_worktable_scan_png_ico() + +#endif // EX_WORKTABLE_SCAN_PNG_H diff --git a/include/images/exclude.png b/include/images/exclude.png new file mode 100644 index 0000000..bd62eef Binary files /dev/null and b/include/images/exclude.png differ diff --git a/include/images/exclude.pngc b/include/images/exclude.pngc new file mode 100644 index 0000000..b4b3756 --- /dev/null +++ b/include/images/exclude.pngc @@ -0,0 +1,135 @@ +#ifndef EXCLUDE_PNG_H +#define EXCLUDE_PNG_H + +static const unsigned char exclude_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x50, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x86, 0xd8, 0xf2, 0x76, +0xa5, 0xb5, 0x4f, 0xc6, 0xec, 0x43, 0xa4, 0xc1, +0x41, 0xc3, 0xeb, 0x2e, 0x88, 0xaa, 0x4f, 0xa4, +0xbe, 0xff, 0xff, 0xff, 0x4e, 0xa5, 0xc5, 0x5c, +0xcb, 0xed, 0x40, 0xc3, 0xeb, 0x20, 0x5f, 0x80, +0x34, 0x94, 0xb4, 0xa9, 0xcc, 0xd8, 0xf3, 0xe8, +0xe9, 0xde, 0x94, 0x94, 0xd4, 0x68, 0x68, 0xd4, +0x6a, 0x6a, 0xe0, 0x9a, 0x9a, 0xfa, 0xef, 0xef, +0xec, 0xf2, 0xf5, 0x62, 0xb5, 0xd2, 0x25, 0x79, +0x9c, 0x44, 0xc4, 0xeb, 0x19, 0x49, 0x69, 0x5a, +0x92, 0xac, 0xc0, 0xd2, 0xdc, 0xcd, 0x61, 0x61, +0xe5, 0x75, 0x75, 0xeb, 0x65, 0x65, 0xe5, 0x78, +0x78, 0xd0, 0x64, 0x64, 0xdb, 0xe5, 0xeb, 0x2d, +0x83, 0xa6, 0x19, 0x6e, 0x91, 0x19, 0x4a, 0x6a, +0x98, 0xb7, 0xc7, 0xc0, 0x85, 0x8a, 0xe4, 0x71, +0x71, 0xfe, 0xfa, 0xfa, 0xf4, 0xb0, 0xb0, 0xf3, +0xa4, 0xa4, 0xfe, 0xfd, 0xfd, 0xe3, 0x7c, 0x7c, +0xc4, 0x92, 0x96, 0x1a, 0x6e, 0x92, 0x18, 0x77, +0x9c, 0x25, 0x5b, 0x7b, 0xad, 0xc8, 0xd4, 0xbf, +0x4d, 0x4e, 0xde, 0x59, 0x59, 0xea, 0x9e, 0x9e, +0xfe, 0xfe, 0xfe, 0xec, 0xa8, 0xa8, 0xbc, 0x59, +0x5b, 0x18, 0x74, 0x98, 0x19, 0x86, 0xac, 0x26, +0x67, 0x88, 0xae, 0xcd, 0xd9, 0xb7, 0x42, 0x43, +0xca, 0x46, 0x46, 0xe1, 0x94, 0x94, 0xe5, 0xa1, +0xa1, 0xb6, 0x4f, 0x50, 0x19, 0x82, 0xa8, 0x19, +0x94, 0xbc, 0x19, 0x6c, 0x90, 0x9b, 0xc7, 0xd7, +0xb5, 0x70, 0x74, 0xc0, 0x51, 0x51, 0xfd, 0xfb, +0xfb, 0xd8, 0x95, 0x95, 0xd5, 0x8c, 0x8c, 0xfe, +0xfc, 0xfc, 0xc1, 0x57, 0x57, 0xb5, 0x7d, 0x81, +0x19, 0x91, 0xb8, 0x19, 0xa1, 0xca, 0x3f, 0xc2, +0xe9, 0x19, 0x7b, 0xa0, 0x61, 0xaf, 0xcb, 0xc8, +0xd2, 0xda, 0xab, 0x31, 0x32, 0xba, 0x4f, 0x4f, +0xae, 0x2d, 0x2d, 0xb9, 0x4c, 0x4c, 0xab, 0x3d, +0x3e, 0xba, 0xd0, 0xdb, 0x1e, 0xa0, 0xc8, 0x19, +0xac, 0xd6, 0x3e, 0xbc, 0xe2, 0x1c, 0x8c, 0xb3, +0x3f, 0xb0, 0xd4, 0xdc, 0xf1, 0xf8, 0xef, 0xd9, +0xd9, 0xbe, 0x63, 0x63, 0xa7, 0x2b, 0x2b, 0xa8, +0x2d, 0x2d, 0xc1, 0x6c, 0x6c, 0xe3, 0xdb, 0xdd, +0x92, 0xc7, 0xd8, 0x2b, 0xac, 0xd3, 0x1b, 0xb6, +0xe0, 0x3c, 0xa7, 0xc9, 0x2b, 0xa4, 0xcc, 0x77, +0xa7, 0xb5, 0x25, 0xbb, 0xe4, 0x50, 0x8e, 0xa0, +0x65, 0xce, 0xee, 0x3a, 0xb1, 0xd6, 0x26, 0x73, +0x8a, 0xc3, 0x80, 0xf8, 0x88, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x08, 0x86, 0xde, 0x95, 0x7a, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xaf, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x00, 0x8c, 0x4c, 0x68, 0x02, 0xcc, 0x2c, +0x68, 0x02, 0xac, 0x6c, 0xec, 0x0c, 0x0c, 0x1c, +0x1c, 0x1c, 0x20, 0x36, 0x27, 0x17, 0x90, 0xe0, +0xe6, 0xe1, 0xe5, 0xe3, 0x17, 0x10, 0x14, 0x12, +0x16, 0x11, 0x15, 0x13, 0x97, 0x00, 0x09, 0x48, +0x4a, 0x49, 0xcb, 0xc8, 0xca, 0xc9, 0xc9, 0x2b, +0x28, 0x2a, 0x29, 0x73, 0x83, 0x04, 0x54, 0x54, +0xd5, 0xd4, 0x35, 0x34, 0xb5, 0xb4, 0x75, 0x74, +0xf5, 0xf4, 0xc1, 0x02, 0x06, 0x86, 0x46, 0xc6, +0x26, 0xa6, 0xa6, 0x66, 0xc6, 0xe6, 0x16, 0x96, +0x60, 0x01, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x53, +0x53, 0x7b, 0x5b, 0x07, 0x47, 0x27, 0xb0, 0x80, +0xb3, 0x8b, 0xab, 0x9b, 0xbb, 0x87, 0xa7, 0x97, +0xb7, 0x8f, 0xaf, 0x1f, 0x48, 0xc0, 0x3f, 0x20, +0x30, 0x28, 0x38, 0x24, 0x34, 0x34, 0x2c, 0x3c, +0x22, 0x32, 0x0a, 0x24, 0x10, 0x1d, 0x13, 0x1b, +0x17, 0x9f, 0x90, 0x98, 0x94, 0x9c, 0x92, 0x9a, +0x96, 0x0e, 0x12, 0xc8, 0xc8, 0x64, 0x04, 0x3b, +0x8c, 0x83, 0x21, 0x2b, 0x23, 0x1b, 0x24, 0x90, +0x93, 0x0b, 0x77, 0x74, 0x4e, 0x1e, 0x37, 0x9a, +0x37, 0xf2, 0xd1, 0x05, 0x80, 0x00, 0x00, 0x98, +0x5b, 0x1b, 0x75, 0xf5, 0x62, 0x1f, 0xcb, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, +0x30, 0x31, 0x2d, 0x30, 0x35, 0x54, 0x31, 0x38, +0x3a, 0x30, 0x39, 0x3a, 0x33, 0x32, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0xc7, 0x88, 0x36, 0x86, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x31, +0x2d, 0x30, 0x31, 0x2d, 0x30, 0x35, 0x54, 0x31, +0x38, 0x3a, 0x30, 0x39, 0x3a, 0x33, 0x32, 0x2b, +0x30, 0x36, 0x3a, 0x30, 0x30, 0xb6, 0xd5, 0x8e, +0x3a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *exclude_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_exclude_png = new wxImage(); + if (!img_exclude_png || !img_exclude_png->IsOk()) + { + wxMemoryInputStream img_exclude_pngIS(exclude_png_data, sizeof(exclude_png_data)); + img_exclude_png->LoadFile(img_exclude_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exclude_png; +} +#define exclude_png_img exclude_png_img() + +static wxBitmap *exclude_png_bmp() +{ + static wxBitmap *bmp_exclude_png; + if (!bmp_exclude_png || !bmp_exclude_png->IsOk()) + bmp_exclude_png = new wxBitmap(*exclude_png_img); + return bmp_exclude_png; +} +#define exclude_png_bmp exclude_png_bmp() + +static wxIcon *exclude_png_ico() +{ + static wxIcon *ico_exclude_png; + if (!ico_exclude_png || !ico_exclude_png->IsOk()) + { + ico_exclude_png = new wxIcon(); + ico_exclude_png->CopyFromBitmap(*exclude_png_bmp); + } + return ico_exclude_png; +} +#define exclude_png_ico exclude_png_ico() + +#endif // EXCLUDE_PNG_H diff --git a/include/images/extension-sm.png b/include/images/extension-sm.png new file mode 100644 index 0000000..432d2f4 Binary files /dev/null and b/include/images/extension-sm.png differ diff --git a/include/images/extension-sm.pngc b/include/images/extension-sm.pngc new file mode 100644 index 0000000..375c0ce --- /dev/null +++ b/include/images/extension-sm.pngc @@ -0,0 +1,97 @@ +#ifndef EXTENSION_SM_PNG_H +#define EXTENSION_SM_PNG_H + +static const unsigned char extension_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xd9, 0x86, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xf7, 0xef, 0xd4, +0xd8, 0xb3, 0x1f, 0xe3, 0xcd, 0x39, 0xed, 0xe2, +0x4f, 0xf4, 0xf2, 0x5f, 0xf4, 0xea, 0xc5, 0xda, +0xb7, 0x23, 0xec, 0xde, 0x4b, 0xf8, 0xf9, 0x67, +0xe6, 0xd0, 0x69, 0xe8, 0xd6, 0x43, 0xf8, 0xfa, +0x69, 0xe8, 0xd1, 0x80, 0xda, 0xb6, 0x32, 0xf4, +0xee, 0x5f, 0xf9, 0xfa, 0x6b, 0xda, 0xb6, 0x38, +0xf4, 0xef, 0x60, 0xfa, 0xfb, 0x6d, 0xe9, 0xd6, +0x47, 0xfb, 0xfb, 0x6f, 0xdb, 0xb8, 0x25, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x07, 0x86, 0xb5, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x8d, 0x8f, 0x49, 0x0e, 0x80, +0x20, 0x10, 0x04, 0x47, 0x14, 0x5c, 0x50, 0xdc, +0x77, 0xdc, 0x40, 0xff, 0xff, 0x45, 0x13, 0x98, +0x18, 0xb9, 0x51, 0xb7, 0xae, 0xa4, 0x33, 0x3d, +0x00, 0x7e, 0x04, 0x24, 0x0c, 0x09, 0x44, 0x5f, +0xa6, 0x2c, 0x4e, 0x92, 0x98, 0xd1, 0x14, 0x73, +0xc6, 0x73, 0x03, 0xcf, 0x6c, 0x2e, 0x44, 0x89, +0x88, 0xca, 0x88, 0xba, 0x69, 0x91, 0xa6, 0x33, +0xa2, 0xeb, 0x07, 0xa4, 0xb7, 0xa2, 0x1a, 0x27, +0x64, 0xb4, 0x15, 0x98, 0x97, 0xd5, 0xb0, 0xcc, +0x78, 0x25, 0x95, 0xdb, 0x7e, 0x1c, 0xe7, 0x29, +0x7f, 0xcb, 0xc8, 0xa5, 0xb4, 0x56, 0xce, 0xd8, +0x5b, 0x3d, 0xae, 0x00, 0x50, 0xb7, 0xdf, 0x9f, +0x2f, 0xe4, 0x0e, 0x07, 0xe3, 0xd8, 0x9f, 0xd2, +0x10, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *extension_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_extension_sm_png = new wxImage(); + if (!img_extension_sm_png || !img_extension_sm_png->IsOk()) + { + wxMemoryInputStream img_extension_sm_pngIS(extension_sm_png_data, sizeof(extension_sm_png_data)); + img_extension_sm_png->LoadFile(img_extension_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_extension_sm_png; +} +#define extension_sm_png_img extension_sm_png_img() + +static wxBitmap *extension_sm_png_bmp() +{ + static wxBitmap *bmp_extension_sm_png; + if (!bmp_extension_sm_png || !bmp_extension_sm_png->IsOk()) + bmp_extension_sm_png = new wxBitmap(*extension_sm_png_img); + return bmp_extension_sm_png; +} +#define extension_sm_png_bmp extension_sm_png_bmp() + +static wxIcon *extension_sm_png_ico() +{ + static wxIcon *ico_extension_sm_png; + if (!ico_extension_sm_png || !ico_extension_sm_png->IsOk()) + { + ico_extension_sm_png = new wxIcon(); + ico_extension_sm_png->CopyFromBitmap(*extension_sm_png_bmp); + } + return ico_extension_sm_png; +} +#define extension_sm_png_ico extension_sm_png_ico() + +#endif // EXTENSION_SM_PNG_H diff --git a/include/images/extension.png b/include/images/extension.png new file mode 100644 index 0000000..e3c5333 Binary files /dev/null and b/include/images/extension.png differ diff --git a/include/images/extension.pngc b/include/images/extension.pngc new file mode 100644 index 0000000..a3947cc --- /dev/null +++ b/include/images/extension.pngc @@ -0,0 +1,169 @@ +#ifndef EXTENSION_PNG_H +#define EXTENSION_PNG_H + +static const unsigned char extension_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x02, 0xfa, 0x50, 0x4c, 0x54, 0x45, 0x67, 0x58, +0x10, 0x82, 0x76, 0x3a, 0xd2, 0xcd, 0xb7, 0xaa, +0xa1, 0x79, 0xad, 0xa4, 0x7b, 0xf0, 0xec, 0xde, +0xc8, 0xc1, 0xa0, 0x6b, 0x5d, 0x16, 0xa6, 0xc2, +0xa5, 0x55, 0x8b, 0x54, 0x9a, 0xba, 0x99, 0xc0, +0xba, 0x9c, 0x9a, 0x8f, 0x5d, 0xf7, 0xf3, 0xe6, +0xe7, 0xe1, 0xcb, 0x66, 0x56, 0x0d, 0xaa, 0xc4, +0xa9, 0x52, 0x8f, 0x54, 0x8f, 0xc1, 0x96, 0x5a, +0x98, 0x5e, 0x6c, 0x9a, 0x6b, 0x7a, 0x6d, 0x2e, +0xda, 0xd3, 0xb9, 0xa8, 0x9c, 0x6c, 0xaf, 0xa8, +0x81, 0xc2, 0xd5, 0xc2, 0x3e, 0x80, 0x3f, 0xbd, +0xe9, 0xc8, 0x77, 0xb1, 0x7d, 0x44, 0x7e, 0x42, +0x80, 0x73, 0x37, 0xa2, 0x99, 0x6d, 0xbf, 0xb8, +0x99, 0xcc, 0xc7, 0xae, 0xdf, 0xdc, 0xcc, 0xbd, +0xb6, 0x96, 0x5e, 0x4e, 0x01, 0xf1, 0xea, 0xd6, +0xb6, 0xab, 0x7e, 0x9e, 0x95, 0x67, 0x3e, 0x7b, +0x3c, 0x96, 0xcc, 0xa0, 0x33, 0x76, 0x33, 0xba, +0xb3, 0x91, 0x9d, 0x93, 0x63, 0x90, 0x84, 0x4e, +0x7d, 0x70, 0x30, 0x9c, 0x91, 0x5d, 0xd9, 0xd0, +0xb3, 0xf0, 0xe9, 0xd2, 0xee, 0xe5, 0xca, 0x98, +0x8b, 0x50, 0x6a, 0x5b, 0x12, 0x78, 0x68, 0x21, +0x10, 0x5b, 0x0e, 0xae, 0xe3, 0xbc, 0x2d, 0x72, +0x2d, 0xfc, 0xfb, 0xf7, 0xfb, 0xf8, 0xf2, 0xf9, +0xf6, 0xec, 0xf5, 0xf0, 0xe0, 0xf3, 0xec, 0xd9, +0xeb, 0xe1, 0xc2, 0xe8, 0xdd, 0xba, 0xe6, 0xd9, +0xb2, 0xe3, 0xd5, 0xa9, 0xe0, 0xd1, 0xa1, 0xa0, +0x8f, 0x4f, 0x1a, 0x60, 0x16, 0x1e, 0x65, 0x1c, +0x29, 0x6e, 0x28, 0x69, 0xa8, 0x70, 0xaa, 0xe3, +0xb9, 0x68, 0xab, 0x70, 0x1b, 0x63, 0x19, 0x40, +0x7c, 0x3e, 0xdd, 0xcc, 0x98, 0xa8, 0x97, 0x57, +0x35, 0x6a, 0x25, 0x9e, 0xc9, 0xa3, 0xc9, 0xed, +0xd2, 0xa1, 0xd0, 0xaa, 0xb3, 0xe1, 0xbd, 0xb7, +0xe7, 0xc3, 0xb0, 0xe5, 0xbe, 0xa3, 0xe1, 0xb3, +0x9d, 0xdf, 0xae, 0x90, 0xd7, 0xa1, 0x76, 0xc1, +0x85, 0x71, 0xbf, 0x80, 0x7f, 0xd3, 0x95, 0xda, +0xc8, 0x90, 0xad, 0x9a, 0x58, 0x45, 0x6e, 0x2c, +0x83, 0xb6, 0x88, 0xc3, 0xeb, 0xce, 0x96, 0xdd, +0xa8, 0x90, 0xda, 0xa3, 0x89, 0xd8, 0x9d, 0x82, +0xd6, 0x98, 0x7c, 0xd4, 0x93, 0xcf, 0xc0, 0x8f, +0x95, 0x85, 0x45, 0x56, 0x50, 0x04, 0x68, 0x58, +0x0d, 0x9a, 0x88, 0x43, 0xab, 0x97, 0x52, 0x7b, +0xb1, 0x81, 0x75, 0xd2, 0x8d, 0x7e, 0x7d, 0x3a, +0x28, 0x67, 0x20, 0x28, 0x6d, 0x27, 0x5f, 0x78, +0x3b, 0x8a, 0x7d, 0x33, 0x24, 0x63, 0x1b, 0xa5, +0xd5, 0xae, 0x76, 0xc5, 0x87, 0x40, 0x8f, 0x48, +0x11, 0x5c, 0x0f, 0x18, 0x65, 0x18, 0x3f, 0x95, +0x4a, 0xb4, 0xa4, 0x6a, 0x31, 0x67, 0x20, 0x84, +0xb3, 0x87, 0xd5, 0xf1, 0xdc, 0xad, 0xd5, 0xb4, +0x5c, 0x97, 0x5f, 0x61, 0x9e, 0x66, 0x3f, 0x8e, +0x47, 0x97, 0xb8, 0x96, 0x64, 0x95, 0x63, 0x82, +0x77, 0x31, 0xcf, 0xef, 0xd7, 0xb7, 0xe4, 0xc1, +0x5c, 0xab, 0x69, 0x62, 0x93, 0x60, 0x91, 0xb4, +0x90, 0x73, 0x6d, 0x25, 0x34, 0x83, 0x3a, 0xb0, +0xc9, 0xb0, 0x8f, 0x7f, 0x39, 0x16, 0x5e, 0x13, +0xc2, 0xe8, 0xcb, 0x98, 0xcd, 0xa1, 0x50, 0x92, +0x54, 0x8d, 0xc9, 0x99, 0x2b, 0x7b, 0x30, 0xbe, +0xd3, 0xbe, 0xd8, 0xc4, 0x87, 0xc1, 0xac, 0x69, +0x39, 0x5e, 0x14, 0x5e, 0x9a, 0x62, 0x84, 0xba, +0x8b, 0x70, 0xac, 0x76, 0x36, 0x7b, 0x37, 0x4e, +0x63, 0x1e, 0x1d, 0x62, 0x19, 0x93, 0xd6, 0xa3, +0x38, 0x8d, 0x42, 0xd5, 0xbf, 0x7e, 0xd2, 0xbb, +0x76, 0x93, 0x81, 0x35, 0x43, 0x5d, 0x14, 0x3f, +0x6e, 0x2b, 0x41, 0x67, 0x22, 0x6c, 0x6d, 0x1c, +0x95, 0x7e, 0x27, 0x39, 0x6d, 0x29, 0x72, 0xba, +0x7e, 0x6f, 0xd0, 0x88, 0x5a, 0xbb, 0x70, 0xcf, +0xb7, 0x6d, 0xcd, 0xb3, 0x65, 0xc0, 0xa6, 0x54, +0x9d, 0x86, 0x33, 0xad, 0x92, 0x3b, 0xc2, 0xa4, +0x46, 0x92, 0x79, 0x22, 0x46, 0x74, 0x34, 0x63, +0xad, 0x6e, 0x68, 0xce, 0x83, 0x62, 0xcc, 0x7d, +0x36, 0x92, 0x42, 0x26, 0x6a, 0x25, 0x70, 0x9d, +0x6e, 0x48, 0x82, 0x47, 0x27, 0x86, 0x33, 0xca, +0xaf, 0x5d, 0xc7, 0xab, 0x55, 0xc5, 0xa7, 0x4d, +0xc0, 0xa0, 0x3f, 0x8a, 0x72, 0x1c, 0x4d, 0x7a, +0x3c, 0x5c, 0xca, 0x78, 0x56, 0xc8, 0x73, 0x4a, +0xbc, 0x66, 0x33, 0x9a, 0x45, 0x3a, 0xa9, 0x51, +0x40, 0xc0, 0x61, 0xbe, 0x9d, 0x39, 0x7d, 0x67, +0x11, 0x58, 0x84, 0x4b, 0x56, 0xa6, 0x62, 0x50, +0xc6, 0x6f, 0x4b, 0xc4, 0x6a, 0x45, 0xc2, 0x66, +0x3b, 0xbf, 0x5d, 0xa1, 0x8f, 0x4b, 0x8e, 0x7b, +0x33, 0x86, 0x73, 0x29, 0x8b, 0x78, 0x2c, 0xb8, +0xa0, 0x52, 0xb6, 0x9c, 0x47, 0x8a, 0x74, 0x21, +0x82, 0x6c, 0x19, 0x84, 0x6d, 0x16, 0x6f, 0x5c, +0x09, 0x5a, 0x89, 0x52, 0x56, 0xa9, 0x64, 0x36, +0xbd, 0x59, 0x84, 0x78, 0x3d, 0xa6, 0x9d, 0x73, +0xc8, 0xc3, 0xa8, 0x89, 0x75, 0x26, 0xc0, 0xa4, +0x4f, 0xbb, 0xb4, 0x93, 0xc6, 0xc1, 0xa5, 0xc4, +0xbe, 0xa2, 0x5f, 0x91, 0x5d, 0x1c, 0x69, 0x1d, +0x12, 0x5e, 0x11, 0x1a, 0x6a, 0x1d, 0x36, 0x97, +0x45, 0x2d, 0x8f, 0x3c, 0x14, 0x63, 0x15, 0xb5, +0x99, 0x41, 0x77, 0x69, 0x28, 0x19, 0x6a, 0x1b, +0x50, 0x87, 0x4e, 0x88, 0x7c, 0x43, 0x91, 0x7a, +0x27, 0x2c, 0x92, 0x3d, 0x80, 0xa8, 0x7f, 0x6b, +0x5a, 0x0b, 0x96, 0x7c, 0x22, 0x7e, 0xa6, 0x7d, +0x3e, 0xbb, 0x5d, 0x16, 0x68, 0x18, 0x7f, 0x6a, +0x16, 0x81, 0x6b, 0x15, 0x1b, 0x77, 0x24, 0x49, +0x82, 0x48, 0x18, 0x6e, 0x1d, 0x17, 0x6d, 0x1c, +0x07, 0x6a, 0xcc, 0x0a, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, +0x49, 0x4d, 0x45, 0x07, 0xdb, 0x03, 0x1b, 0x0d, +0x3a, 0x0e, 0xbe, 0x5c, 0x8c, 0x2f, 0x00, 0x00, +0x00, 0x56, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x20, 0x1e, 0xb8, 0xb8, 0xa0, 0xf1, +0x43, 0x42, 0x90, 0x45, 0xcc, 0x5c, 0x80, 0x02, +0x21, 0x66, 0x48, 0xf2, 0xd2, 0x21, 0xa1, 0x09, +0x2e, 0x30, 0x5d, 0x40, 0xda, 0x05, 0xc4, 0x07, +0xb2, 0xa0, 0x02, 0x01, 0x21, 0x40, 0x7e, 0x92, +0x0b, 0xaa, 0xfa, 0xa4, 0x14, 0x17, 0x64, 0x0b, +0x5d, 0x92, 0x52, 0x56, 0x22, 0xb4, 0x80, 0xc4, +0x52, 0x56, 0x6e, 0x3d, 0xe4, 0xe2, 0x82, 0xac, +0xc8, 0xe5, 0xd0, 0x99, 0x33, 0x28, 0x4e, 0x73, +0x41, 0xe3, 0x63, 0x3a, 0x1d, 0x27, 0x00, 0x00, +0xa7, 0x4e, 0x19, 0xac, 0xbe, 0x56, 0xe6, 0xc8, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *extension_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_extension_png = new wxImage(); + if (!img_extension_png || !img_extension_png->IsOk()) + { + wxMemoryInputStream img_extension_pngIS(extension_png_data, sizeof(extension_png_data)); + img_extension_png->LoadFile(img_extension_pngIS, wxBITMAP_TYPE_PNG); + } + return img_extension_png; +} +#define extension_png_img extension_png_img() + +static wxBitmap *extension_png_bmp() +{ + static wxBitmap *bmp_extension_png; + if (!bmp_extension_png || !bmp_extension_png->IsOk()) + bmp_extension_png = new wxBitmap(*extension_png_img); + return bmp_extension_png; +} +#define extension_png_bmp extension_png_bmp() + +static wxIcon *extension_png_ico() +{ + static wxIcon *ico_extension_png; + if (!ico_extension_png || !ico_extension_png->IsOk()) + { + ico_extension_png = new wxIcon(); + ico_extension_png->CopyFromBitmap(*extension_png_bmp); + } + return ico_extension_png; +} +#define extension_png_ico extension_png_ico() + +#endif // EXTENSION_PNG_H diff --git a/include/images/extensions.png b/include/images/extensions.png new file mode 100644 index 0000000..eed7ca9 Binary files /dev/null and b/include/images/extensions.png differ diff --git a/include/images/extensions.pngc b/include/images/extensions.pngc new file mode 100644 index 0000000..43be15b --- /dev/null +++ b/include/images/extensions.pngc @@ -0,0 +1,172 @@ +#ifndef EXTENSIONS_PNG_H +#define EXTENSIONS_PNG_H + +static const unsigned char extensions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x02, 0xf7, 0x50, 0x4c, 0x54, 0x45, 0x82, 0x76, +0x3a, 0xd2, 0xcd, 0xb7, 0xaa, 0xa1, 0x79, 0xad, +0xa4, 0x7b, 0xf0, 0xec, 0xde, 0xc8, 0xc1, 0xa0, +0x6b, 0x5d, 0x16, 0xa6, 0xc2, 0xa5, 0x55, 0x8b, +0x54, 0x9a, 0xba, 0x99, 0xc0, 0xba, 0x9c, 0x9a, +0x8f, 0x5d, 0xf7, 0xf3, 0xe6, 0xe7, 0xe1, 0xcb, +0x66, 0x56, 0x0d, 0xaa, 0xc4, 0xa9, 0x52, 0x8f, +0x54, 0x8f, 0xc1, 0x96, 0x5a, 0x98, 0x5e, 0x6c, +0x9a, 0x6b, 0x7a, 0x6d, 0x2e, 0xda, 0xd3, 0xb9, +0xa8, 0x9c, 0x6c, 0xaf, 0xa8, 0x81, 0xc2, 0xd5, +0xc2, 0x3e, 0x80, 0x3f, 0xbd, 0xe9, 0xc8, 0x77, +0xb1, 0x7d, 0x44, 0x7e, 0x42, 0x80, 0x73, 0x37, +0xa2, 0x99, 0x6d, 0xbf, 0xb8, 0x99, 0xcc, 0xc7, +0xae, 0xdf, 0xdc, 0xcc, 0xbd, 0xb6, 0x96, 0x5e, +0x4e, 0x01, 0xf1, 0xea, 0xd6, 0xb6, 0xab, 0x7e, +0x9e, 0x95, 0x67, 0x3e, 0x7b, 0x3c, 0x96, 0xcc, +0xa0, 0x33, 0x76, 0x33, 0xba, 0xb3, 0x91, 0x9d, +0x93, 0x63, 0x90, 0x84, 0x4e, 0x7d, 0x70, 0x30, +0x9c, 0x91, 0x5d, 0xd9, 0xd0, 0xb3, 0xf0, 0xe9, +0xd2, 0xee, 0xe5, 0xca, 0x98, 0x8b, 0x50, 0x6a, +0x5b, 0x12, 0x78, 0x68, 0x21, 0x10, 0x5b, 0x0e, +0xae, 0xe3, 0xbc, 0x2d, 0x72, 0x2d, 0xfc, 0xfb, +0xf7, 0xfb, 0xf8, 0xf2, 0xf9, 0xf6, 0xec, 0xf5, +0xf0, 0xe0, 0xf3, 0xec, 0xd9, 0xeb, 0xe1, 0xc2, +0xe8, 0xdd, 0xba, 0xe6, 0xd9, 0xb2, 0xe3, 0xd5, +0xa9, 0xe0, 0xd1, 0xa1, 0xa0, 0x8f, 0x4f, 0x1a, +0x60, 0x16, 0x1e, 0x65, 0x1c, 0x29, 0x6e, 0x28, +0x69, 0xa8, 0x70, 0xaa, 0xe3, 0xb9, 0x68, 0xab, +0x70, 0x1b, 0x63, 0x19, 0x40, 0x7c, 0x3e, 0xdd, +0xcc, 0x98, 0xa8, 0x97, 0x57, 0x35, 0x6a, 0x25, +0x9e, 0xc9, 0xa3, 0xc9, 0xed, 0xd2, 0xa1, 0xd0, +0xaa, 0xb3, 0xe1, 0xbd, 0xb7, 0xe7, 0xc3, 0xb0, +0xe5, 0xbe, 0xa3, 0xe1, 0xb3, 0x9d, 0xdf, 0xae, +0x90, 0xd7, 0xa1, 0x76, 0xc1, 0x85, 0x71, 0xbf, +0x80, 0x7f, 0xd3, 0x95, 0xda, 0xc8, 0x90, 0xad, +0x9a, 0x58, 0x45, 0x6e, 0x2c, 0x83, 0xb6, 0x88, +0xc3, 0xeb, 0xce, 0x96, 0xdd, 0xa8, 0x90, 0xda, +0xa3, 0x89, 0xd8, 0x9d, 0x82, 0xd6, 0x98, 0x7c, +0xd4, 0x93, 0xcf, 0xc0, 0x8f, 0x95, 0x85, 0x45, +0x56, 0x50, 0x04, 0x68, 0x58, 0x0d, 0x9a, 0x88, +0x43, 0xab, 0x97, 0x52, 0x7b, 0xb1, 0x81, 0x75, +0xd2, 0x8d, 0x7e, 0x7d, 0x3a, 0x28, 0x67, 0x20, +0x28, 0x6d, 0x27, 0x5f, 0x78, 0x3b, 0x8a, 0x7d, +0x33, 0x24, 0x63, 0x1b, 0xa5, 0xd5, 0xae, 0x76, +0xc5, 0x87, 0x40, 0x8f, 0x48, 0x11, 0x5c, 0x0f, +0x18, 0x65, 0x18, 0x3f, 0x95, 0x4a, 0xb4, 0xa4, +0x6a, 0x31, 0x67, 0x20, 0x84, 0xb3, 0x87, 0xd5, +0xf1, 0xdc, 0xad, 0xd5, 0xb4, 0x5c, 0x97, 0x5f, +0x61, 0x9e, 0x66, 0x3f, 0x8e, 0x47, 0x97, 0xb8, +0x96, 0x64, 0x95, 0x63, 0x82, 0x77, 0x31, 0xcf, +0xef, 0xd7, 0xb7, 0xe4, 0xc1, 0x5c, 0xab, 0x69, +0x62, 0x93, 0x60, 0x91, 0xb4, 0x90, 0x73, 0x6d, +0x25, 0x34, 0x83, 0x3a, 0xb0, 0xc9, 0xb0, 0x8f, +0x7f, 0x39, 0x16, 0x5e, 0x13, 0xc2, 0xe8, 0xcb, +0x98, 0xcd, 0xa1, 0x50, 0x92, 0x54, 0x8d, 0xc9, +0x99, 0x2b, 0x7b, 0x30, 0xbe, 0xd3, 0xbe, 0xd8, +0xc4, 0x87, 0xc1, 0xac, 0x69, 0x39, 0x5e, 0x14, +0x5e, 0x9a, 0x62, 0x84, 0xba, 0x8b, 0x70, 0xac, +0x76, 0x36, 0x7b, 0x37, 0x4e, 0x63, 0x1e, 0x1d, +0x62, 0x19, 0x93, 0xd6, 0xa3, 0x38, 0x8d, 0x42, +0xd5, 0xbf, 0x7e, 0xd2, 0xbb, 0x76, 0x93, 0x81, +0x35, 0x43, 0x5d, 0x14, 0x3f, 0x6e, 0x2b, 0x41, +0x67, 0x22, 0x6c, 0x6d, 0x1c, 0x95, 0x7e, 0x27, +0x39, 0x6d, 0x29, 0x72, 0xba, 0x7e, 0x6f, 0xd0, +0x88, 0x5a, 0xbb, 0x70, 0xcf, 0xb7, 0x6d, 0xcd, +0xb3, 0x65, 0xc0, 0xa6, 0x54, 0x9d, 0x86, 0x33, +0xad, 0x92, 0x3b, 0xc2, 0xa4, 0x46, 0x92, 0x79, +0x22, 0x46, 0x74, 0x34, 0x63, 0xad, 0x6e, 0x68, +0xce, 0x83, 0x62, 0xcc, 0x7d, 0x36, 0x92, 0x42, +0x26, 0x6a, 0x25, 0x70, 0x9d, 0x6e, 0x48, 0x82, +0x47, 0x27, 0x86, 0x33, 0xca, 0xaf, 0x5d, 0xc7, +0xab, 0x55, 0xc5, 0xa7, 0x4d, 0xc0, 0xa0, 0x3f, +0x8a, 0x72, 0x1c, 0x4d, 0x7a, 0x3c, 0x5c, 0xca, +0x78, 0x56, 0xc8, 0x73, 0x4a, 0xbc, 0x66, 0x33, +0x9a, 0x45, 0x3a, 0xa9, 0x51, 0x40, 0xc0, 0x61, +0xbe, 0x9d, 0x39, 0x7d, 0x67, 0x11, 0x58, 0x84, +0x4b, 0x56, 0xa6, 0x62, 0x50, 0xc6, 0x6f, 0x4b, +0xc4, 0x6a, 0x45, 0xc2, 0x66, 0x3b, 0xbf, 0x5d, +0xa1, 0x8f, 0x4b, 0x8e, 0x7b, 0x33, 0x86, 0x73, +0x29, 0x8b, 0x78, 0x2c, 0xb8, 0xa0, 0x52, 0xb6, +0x9c, 0x47, 0x8a, 0x74, 0x21, 0x82, 0x6c, 0x19, +0x84, 0x6d, 0x16, 0x6f, 0x5c, 0x09, 0x5a, 0x89, +0x52, 0x56, 0xa9, 0x64, 0x36, 0xbd, 0x59, 0x84, +0x78, 0x3d, 0xa6, 0x9d, 0x73, 0xc8, 0xc3, 0xa8, +0x89, 0x75, 0x26, 0xc0, 0xa4, 0x4f, 0xbb, 0xb4, +0x93, 0xc6, 0xc1, 0xa5, 0xc4, 0xbe, 0xa2, 0x5f, +0x91, 0x5d, 0x1c, 0x69, 0x1d, 0x12, 0x5e, 0x11, +0x1a, 0x6a, 0x1d, 0x36, 0x97, 0x45, 0x2d, 0x8f, +0x3c, 0x14, 0x63, 0x15, 0xb5, 0x99, 0x41, 0x77, +0x69, 0x28, 0x19, 0x6a, 0x1b, 0x50, 0x87, 0x4e, +0x88, 0x7c, 0x43, 0x91, 0x7a, 0x27, 0x2c, 0x92, +0x3d, 0x80, 0xa8, 0x7f, 0x6b, 0x5a, 0x0b, 0x96, +0x7c, 0x22, 0x7e, 0xa6, 0x7d, 0x3e, 0xbb, 0x5d, +0x16, 0x68, 0x18, 0x7f, 0x6a, 0x16, 0x81, 0x6b, +0x15, 0x1b, 0x77, 0x24, 0x49, 0x82, 0x48, 0x18, +0x6e, 0x1d, 0x17, 0x6d, 0x1c, 0x16, 0xe2, 0x34, +0x8b, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x88, +0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, +0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, +0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, +0x07, 0xdb, 0x03, 0x1b, 0x11, 0x13, 0x21, 0x44, +0xf7, 0x74, 0x89, 0x00, 0x00, 0x00, 0x6e, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0x90, 0xb1, +0x0d, 0xc0, 0x20, 0x0c, 0x04, 0x99, 0x83, 0x3d, +0x32, 0xc1, 0x0d, 0x90, 0xc2, 0xf4, 0xc8, 0x62, +0x39, 0x06, 0xc8, 0x02, 0xd4, 0x2c, 0x15, 0x03, +0x96, 0x02, 0xf9, 0x8a, 0x7f, 0xdf, 0x1b, 0x41, +0x08, 0x53, 0x10, 0x0e, 0x21, 0xb2, 0x27, 0x17, +0x23, 0xd8, 0x12, 0xa2, 0xa4, 0x8f, 0xb1, 0x09, +0x32, 0x19, 0x87, 0xb8, 0xc5, 0xe6, 0xc6, 0x64, +0x87, 0x88, 0x60, 0xe7, 0xb4, 0xa0, 0x6b, 0x54, +0x26, 0x93, 0x17, 0xc4, 0x62, 0xac, 0xad, 0x0c, +0x6f, 0x66, 0xae, 0x75, 0x48, 0x39, 0x2e, 0xce, +0x5a, 0xb6, 0xc0, 0xa4, 0xa5, 0x7a, 0xc5, 0xa3, +0x52, 0x9f, 0x06, 0x07, 0xd4, 0x7a, 0x3f, 0xde, +0xc8, 0xcf, 0xfb, 0x1f, 0xbc, 0x3e, 0xe1, 0x2b, +0xe7, 0x28, 0x8a, 0xef, 0xe7, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *extensions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_extensions_png = new wxImage(); + if (!img_extensions_png || !img_extensions_png->IsOk()) + { + wxMemoryInputStream img_extensions_pngIS(extensions_png_data, sizeof(extensions_png_data)); + img_extensions_png->LoadFile(img_extensions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_extensions_png; +} +#define extensions_png_img extensions_png_img() + +static wxBitmap *extensions_png_bmp() +{ + static wxBitmap *bmp_extensions_png; + if (!bmp_extensions_png || !bmp_extensions_png->IsOk()) + bmp_extensions_png = new wxBitmap(*extensions_png_img); + return bmp_extensions_png; +} +#define extensions_png_bmp extensions_png_bmp() + +static wxIcon *extensions_png_ico() +{ + static wxIcon *ico_extensions_png; + if (!ico_extensions_png || !ico_extensions_png->IsOk()) + { + ico_extensions_png = new wxIcon(); + ico_extensions_png->CopyFromBitmap(*extensions_png_bmp); + } + return ico_extensions_png; +} +#define extensions_png_ico extensions_png_ico() + +#endif // EXTENSIONS_PNG_H diff --git a/include/images/exttable-sm.png b/include/images/exttable-sm.png new file mode 100644 index 0000000..acd43cb Binary files /dev/null and b/include/images/exttable-sm.png differ diff --git a/include/images/exttable-sm.pngc b/include/images/exttable-sm.pngc new file mode 100644 index 0000000..e0876b4 --- /dev/null +++ b/include/images/exttable-sm.pngc @@ -0,0 +1,121 @@ +#ifndef EXTTABLE_SM_PNG_H +#define EXTTABLE_SM_PNG_H + +static const unsigned char exttable_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0b, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, +0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, 0x49, +0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, 0xeb, +0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, 0xab, +0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, 0x53, +0x61, 0xb1, 0x41, 0x43, 0xad, 0xd7, 0xd7, 0xdb, +0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe2, 0xe2, +0xe2, 0xe3, 0xe3, 0xe3, 0xa5, 0xa6, 0xd6, 0x37, +0x39, 0x78, 0x66, 0x91, 0xae, 0xc0, 0xc0, 0xc8, +0x31, 0x33, 0x9c, 0x27, 0x2b, 0xc1, 0x76, 0x77, +0x97, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xe2, 0x46, +0x48, 0xac, 0x25, 0x28, 0xbf, 0x66, 0x67, 0x8e, +0xdd, 0xdd, 0xdd, 0xa6, 0xa6, 0xa6, 0x58, 0x59, +0x8b, 0x26, 0x29, 0xc9, 0x46, 0x48, 0xa9, 0x2d, +0x30, 0xc1, 0x23, 0x26, 0x98, 0x87, 0x87, 0x91, +0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, 0x61, 0x63, +0xba, 0x27, 0x2b, 0xd3, 0x24, 0x27, 0xb5, 0xb8, +0xb9, 0xc7, 0xe9, 0xe9, 0xe9, 0xeb, 0xeb, 0xeb, +0xcf, 0xcf, 0xdb, 0x32, 0x35, 0xb1, 0x21, 0x24, +0xa9, 0x9d, 0x9e, 0xad, 0x58, 0x5a, 0xac, 0x25, +0x29, 0xc6, 0x71, 0x72, 0xa2, 0xf1, 0xf1, 0xf1, +0xed, 0xed, 0xed, 0x8f, 0x90, 0xb5, 0x26, 0x29, +0xc5, 0x31, 0x33, 0x8b, 0x9f, 0x9f, 0xa1, 0xe5, +0xe5, 0xe5, 0x81, 0x82, 0xa5, 0x27, 0x2b, 0xc2, +0x27, 0x29, 0x8b, 0xc8, 0xc8, 0xcd, 0x89, 0x89, +0x91, 0x84, 0x84, 0xaa, 0xe4, 0xe4, 0xe4, 0xec, +0xec, 0xec, 0xe0, 0xe0, 0xeb, 0x47, 0x4a, 0xba, +0x75, 0x76, 0x8c, 0x7b, 0xc6, 0xfb, 0x6f, 0xc0, +0xf8, 0x28, 0x99, 0xe8, 0x0c, 0xe7, 0x2c, 0x90, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x90, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x02, +0x30, 0x22, 0x01, 0x88, 0x00, 0x13, 0x33, 0x0b, +0x2b, 0x1b, 0x3b, 0x07, 0x07, 0x27, 0x17, 0x37, +0x44, 0x80, 0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, +0x48, 0x58, 0x44, 0x14, 0xaa, 0x82, 0x47, 0x0c, +0x24, 0x20, 0x2e, 0x21, 0x22, 0x09, 0x15, 0x90, +0x92, 0x96, 0x91, 0x95, 0x93, 0x57, 0x50, 0x54, +0x52, 0x86, 0x0a, 0xa8, 0xa8, 0xaa, 0xa9, 0x6b, +0x68, 0x6a, 0x69, 0xeb, 0x70, 0x40, 0x05, 0x74, +0xf5, 0xf4, 0x0d, 0x0c, 0x8d, 0x8c, 0x4d, 0x4c, +0xcd, 0xa0, 0x02, 0xb2, 0x72, 0x72, 0xe6, 0x16, +0x96, 0x56, 0xd6, 0x66, 0x36, 0x50, 0x01, 0x39, +0x5b, 0x3b, 0x7b, 0x07, 0x47, 0x27, 0x67, 0x17, +0x57, 0xa8, 0x80, 0x9b, 0xbb, 0x87, 0xa7, 0x97, +0xb5, 0xb7, 0x8f, 0xaf, 0x1f, 0x54, 0xc0, 0x3f, +0x20, 0xd0, 0x8b, 0xc3, 0x26, 0x28, 0x38, 0x24, +0x14, 0xe6, 0x0e, 0xde, 0xb0, 0x70, 0xb0, 0x3b, +0x22, 0x18, 0x89, 0xf1, 0x2a, 0x00, 0x48, 0x95, +0x11, 0xce, 0x91, 0xf1, 0x80, 0x50, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *exttable_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_exttable_sm_png = new wxImage(); + if (!img_exttable_sm_png || !img_exttable_sm_png->IsOk()) + { + wxMemoryInputStream img_exttable_sm_pngIS(exttable_sm_png_data, sizeof(exttable_sm_png_data)); + img_exttable_sm_png->LoadFile(img_exttable_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exttable_sm_png; +} +#define exttable_sm_png_img exttable_sm_png_img() + +static wxBitmap *exttable_sm_png_bmp() +{ + static wxBitmap *bmp_exttable_sm_png; + if (!bmp_exttable_sm_png || !bmp_exttable_sm_png->IsOk()) + bmp_exttable_sm_png = new wxBitmap(*exttable_sm_png_img); + return bmp_exttable_sm_png; +} +#define exttable_sm_png_bmp exttable_sm_png_bmp() + +static wxIcon *exttable_sm_png_ico() +{ + static wxIcon *ico_exttable_sm_png; + if (!ico_exttable_sm_png || !ico_exttable_sm_png->IsOk()) + { + ico_exttable_sm_png = new wxIcon(); + ico_exttable_sm_png->CopyFromBitmap(*exttable_sm_png_bmp); + } + return ico_exttable_sm_png; +} +#define exttable_sm_png_ico exttable_sm_png_ico() + +#endif // EXTTABLE_SM_PNG_H diff --git a/include/images/exttable.png b/include/images/exttable.png new file mode 100644 index 0000000..5d84035 Binary files /dev/null and b/include/images/exttable.png differ diff --git a/include/images/exttable.pngc b/include/images/exttable.pngc new file mode 100644 index 0000000..56c1601 --- /dev/null +++ b/include/images/exttable.pngc @@ -0,0 +1,144 @@ +#ifndef EXTTABLE_PNG_H +#define EXTTABLE_PNG_H + +static const unsigned char exttable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x7d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8d, +0xd0, 0xff, 0x92, 0xcf, 0xfb, 0xa2, 0xd3, 0xf5, +0xba, 0xd8, 0xed, 0xd1, 0xdf, 0xe9, 0xdf, 0xe3, +0xe7, 0xe5, 0xe6, 0xe7, 0xe6, 0xe6, 0xe6, 0xda, +0xe1, 0xe5, 0xac, 0xce, 0xe7, 0x63, 0xb1, 0xe8, +0x2e, 0x9b, 0xe8, 0x8b, 0xcf, 0xff, 0x85, 0xcc, +0xfe, 0x7e, 0xc8, 0xfc, 0x75, 0xc3, 0xfa, 0x6c, +0xbe, 0xf8, 0x61, 0xb8, 0xf6, 0x56, 0xb2, 0xf3, +0x4b, 0xac, 0xf0, 0x40, 0xa7, 0xee, 0x37, 0xa0, +0xec, 0x2d, 0x9c, 0xea, 0x26, 0x98, 0xe9, 0x85, +0xcc, 0xfd, 0x6b, 0xbe, 0xf8, 0x41, 0xa6, 0xee, +0x36, 0xa1, 0xec, 0x2d, 0x99, 0xe6, 0x5b, 0x6c, +0x87, 0x68, 0x6a, 0xb7, 0xdd, 0xdd, 0xdd, 0xde, +0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, +0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, +0xe3, 0x31, 0x33, 0x70, 0x21, 0x2d, 0x4e, 0x9f, +0x9f, 0xb0, 0x23, 0x26, 0xb1, 0x52, 0x54, 0xbb, +0x32, 0x33, 0x7a, 0x2c, 0x2f, 0xc8, 0xa6, 0xa6, +0xc0, 0xb8, 0xb9, 0xc1, 0x21, 0x24, 0xa2, 0x45, +0x47, 0xbd, 0xa7, 0xa7, 0xa9, 0xe4, 0xe4, 0xe4, +0xa7, 0xa7, 0xa7, 0x2f, 0x30, 0x7e, 0x2f, 0x32, +0xc6, 0xd6, 0xd7, 0xeb, 0xea, 0xea, 0xea, 0x91, +0x91, 0x92, 0x1e, 0x21, 0x90, 0x30, 0x34, 0xbf, +0xd5, 0xd6, 0xe2, 0xd5, 0xd5, 0xd5, 0x23, 0x25, +0x89, 0x2d, 0x30, 0xbf, 0xa6, 0xa6, 0xb1, 0xaf, +0xaf, 0xaf, 0xeb, 0xeb, 0xeb, 0xd4, 0xd4, 0xd5, +0x28, 0x2b, 0x84, 0x2e, 0x31, 0xc3, 0x26, 0x29, +0x95, 0x34, 0x37, 0xc4, 0xdc, 0xdc, 0xe7, 0xec, +0xec, 0xec, 0xed, 0xed, 0xed, 0xe9, 0xe9, 0xe9, +0x8e, 0x8e, 0x90, 0x21, 0x24, 0xb0, 0x28, 0x2b, +0xd4, 0x92, 0x92, 0xb5, 0xef, 0xef, 0xef, 0xf0, +0xf0, 0xf0, 0xf2, 0xf2, 0xf2, 0xee, 0xee, 0xee, +0xa9, 0xa9, 0xa9, 0xab, 0xab, 0xab, 0x9c, 0x9c, +0x9e, 0x21, 0x24, 0x9c, 0x41, 0x44, 0xc3, 0x3c, +0x3d, 0x6f, 0x28, 0x2c, 0xca, 0x8d, 0x8e, 0xb5, +0xb2, 0xb2, 0xb2, 0xe7, 0xe7, 0xe7, 0xbd, 0xbd, +0xc4, 0x23, 0x26, 0xad, 0x4b, 0x4d, 0xbf, 0xeb, +0xeb, 0xec, 0x43, 0x44, 0x6b, 0x28, 0x2c, 0xcf, +0xa6, 0xa7, 0xe3, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, +0xf5, 0xbe, 0xbe, 0xc8, 0x24, 0x27, 0xb0, 0x54, +0x57, 0xc5, 0xb1, 0xb1, 0xb2, 0xb5, 0xb5, 0xb5, +0x63, 0x64, 0x81, 0x27, 0x2a, 0xc8, 0x8b, 0x8d, +0xda, 0xf6, 0xf6, 0xf6, 0xa7, 0xa8, 0xb7, 0x23, +0x26, 0xb3, 0x48, 0x4a, 0xb2, 0xf1, 0xf1, 0xf1, +0xb6, 0xb6, 0xb6, 0x5f, 0x60, 0x71, 0x25, 0x28, +0xb5, 0x89, 0x8b, 0xd4, 0x20, 0x93, 0xe5, 0x26, +0x29, 0x8d, 0x68, 0x6a, 0xc1, 0x92, 0x92, 0x9c, +0x93, 0x94, 0xa1, 0x20, 0x91, 0xe3, 0xa0, 0x10, +0xb2, 0x94, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xd3, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x44, 0x01, 0x0c, 0x0c, 0x0c, 0x8c, 0x4c, +0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x9c, +0x5c, 0xdc, 0x3c, 0xbc, 0x20, 0x01, 0x3e, 0x7e, +0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71, +0x09, 0x49, 0xb0, 0x0a, 0x3e, 0x29, 0x01, 0x41, +0x69, 0xa0, 0x80, 0x8c, 0xac, 0x1c, 0x44, 0x40, +0x5e, 0x41, 0x51, 0x49, 0x59, 0x45, 0x55, 0x4d, +0x5d, 0x49, 0x43, 0x13, 0x2c, 0xa0, 0xa5, 0xad, +0xa3, 0x04, 0xe2, 0xab, 0xe8, 0xea, 0xe9, 0x83, +0x05, 0x14, 0x0d, 0x0c, 0x8d, 0x8c, 0xd5, 0x4c, +0x4c, 0xcd, 0xcc, 0x2d, 0x2c, 0xc1, 0x02, 0x4a, +0xa6, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, +0x8e, 0x4e, 0xce, 0x60, 0x01, 0xa0, 0x7e, 0x17, +0x57, 0x37, 0x77, 0x0f, 0x4f, 0x4b, 0x2f, 0x6f, +0xb0, 0x80, 0x8a, 0x8f, 0x8f, 0xa5, 0xaf, 0x9f, +0x7f, 0x40, 0x60, 0x50, 0x70, 0x08, 0x58, 0x40, +0x35, 0x34, 0x2c, 0x3c, 0x22, 0x32, 0x2a, 0x3a, +0x26, 0x36, 0x36, 0x08, 0x2c, 0xc0, 0x19, 0x17, +0x9f, 0x90, 0x98, 0xe4, 0x9c, 0x9c, 0x92, 0x9a, +0x96, 0x0e, 0x16, 0x88, 0xcb, 0xc8, 0xcc, 0xca, +0x0e, 0x09, 0xca, 0xc9, 0xcd, 0xcb, 0x2f, 0x00, +0x0b, 0x14, 0x16, 0x15, 0x67, 0xc7, 0x06, 0x95, +0xe4, 0x94, 0x96, 0x95, 0x57, 0x80, 0x04, 0x2a, +0xab, 0xaa, 0xbd, 0x43, 0x82, 0x4a, 0x82, 0xd3, +0xd2, 0x0b, 0x6a, 0x6a, 0xc1, 0x2a, 0xea, 0x50, +0xbc, 0x0f, 0x00, 0xf4, 0x38, 0x29, 0x8c, 0x4e, +0x17, 0xac, 0x1f, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x34, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x38, 0x99, 0x25, 0x1e, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *exttable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_exttable_png = new wxImage(); + if (!img_exttable_png || !img_exttable_png->IsOk()) + { + wxMemoryInputStream img_exttable_pngIS(exttable_png_data, sizeof(exttable_png_data)); + img_exttable_png->LoadFile(img_exttable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exttable_png; +} +#define exttable_png_img exttable_png_img() + +static wxBitmap *exttable_png_bmp() +{ + static wxBitmap *bmp_exttable_png; + if (!bmp_exttable_png || !bmp_exttable_png->IsOk()) + bmp_exttable_png = new wxBitmap(*exttable_png_img); + return bmp_exttable_png; +} +#define exttable_png_bmp exttable_png_bmp() + +static wxIcon *exttable_png_ico() +{ + static wxIcon *ico_exttable_png; + if (!ico_exttable_png || !ico_exttable_png->IsOk()) + { + ico_exttable_png = new wxIcon(); + ico_exttable_png->CopyFromBitmap(*exttable_png_bmp); + } + return ico_exttable_png; +} +#define exttable_png_ico exttable_png_ico() + +#endif // EXTTABLE_PNG_H diff --git a/include/images/exttables.png b/include/images/exttables.png new file mode 100644 index 0000000..c5dfbd4 Binary files /dev/null and b/include/images/exttables.png differ diff --git a/include/images/exttables.pngc b/include/images/exttables.pngc new file mode 100644 index 0000000..f6bf978 --- /dev/null +++ b/include/images/exttables.pngc @@ -0,0 +1,127 @@ +#ifndef EXTTABLES_PNG_H +#define EXTTABLES_PNG_H + +static const unsigned char exttables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x1a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x52, 0xb0, 0xf2, 0xb3, 0xd5, 0xed, 0xdd, 0xdd, +0xdd, 0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, +0xc0, 0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, +0x49, 0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, +0xeb, 0x27, 0x99, 0xe9, 0xde, 0xde, 0xde, 0x83, +0xcb, 0xfd, 0x4a, 0xab, 0xf0, 0x3d, 0xa4, 0xed, +0x31, 0x98, 0xe9, 0x28, 0x99, 0xe9, 0xdf, 0xdf, +0xdf, 0x46, 0x51, 0xb2, 0x3c, 0x3e, 0x9a, 0xd4, +0xd4, 0xd7, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, +0x61, 0x55, 0xcd, 0x30, 0x2b, 0xd2, 0x7c, 0xb1, +0xd5, 0xe0, 0xe0, 0xe0, 0xc5, 0xc5, 0xd2, 0x36, +0x38, 0xb0, 0x26, 0x29, 0xb7, 0x77, 0x77, 0x92, +0xca, 0xc7, 0xde, 0x36, 0x2d, 0xcc, 0x30, 0x2a, +0xce, 0x8e, 0x88, 0xaf, 0xe9, 0xe9, 0xe9, 0xe1, +0xe1, 0xe1, 0xa6, 0xa6, 0xa6, 0x58, 0x5a, 0x97, +0x26, 0x2a, 0xcb, 0x43, 0x3f, 0xb1, 0x2c, 0x2b, +0xd5, 0x35, 0x29, 0xaa, 0x98, 0x98, 0x9a, 0xaf, +0xaf, 0xaf, 0xea, 0xea, 0xea, 0x90, 0xca, 0xf3, +0x46, 0x3c, 0xc1, 0x28, 0x2b, 0xd6, 0x29, 0x29, +0xb9, 0xcf, 0xd0, 0xd6, 0xeb, 0xeb, 0xeb, 0xbf, +0xbb, 0xd7, 0x33, 0x2c, 0xcf, 0x32, 0x2a, 0xca, +0xac, 0xa8, 0xc3, 0x4b, 0x4d, 0xa9, 0x26, 0x2a, +0xcf, 0x81, 0x83, 0xb8, 0xf1, 0xf1, 0xf1, 0xed, +0xed, 0xed, 0x6d, 0x63, 0xbb, 0x2b, 0x2b, 0xd6, +0x41, 0x35, 0xb0, 0xa8, 0xa8, 0xa8, 0xe5, 0xe5, +0xe5, 0x7a, 0x7b, 0x98, 0x25, 0x28, 0xbb, 0x32, +0x34, 0xa3, 0xd6, 0xd6, 0xdf, 0x38, 0x2e, 0xc6, +0x82, 0x78, 0xbb, 0xe4, 0xe4, 0xe4, 0xec, 0xec, +0xec, 0xe2, 0xe2, 0xe4, 0x3f, 0x41, 0xa7, 0x2b, +0x2e, 0xbb, 0x7b, 0xc6, 0xfb, 0x6f, 0xc0, 0xf8, +0x23, 0x80, 0xd0, 0x81, 0xc1, 0x8e, 0xa2, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xb3, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x5d, 0xcf, 0x45, 0x16, 0xc2, +0x40, 0x10, 0x45, 0xd1, 0x2e, 0x34, 0x40, 0x80, +0xe0, 0x04, 0x0b, 0xee, 0x16, 0x5c, 0x82, 0x04, +0x77, 0x77, 0xd9, 0xff, 0x36, 0xe8, 0x26, 0x03, +0x0e, 0xa9, 0xe1, 0x3b, 0x77, 0xf0, 0x0b, 0xc1, +0xef, 0xd0, 0xf7, 0x40, 0xa1, 0x54, 0xa9, 0x35, +0x5a, 0x8a, 0xd2, 0xe9, 0x0d, 0x52, 0xa0, 0x8d, +0xff, 0x06, 0x68, 0x99, 0x01, 0x93, 0xcc, 0x80, +0x59, 0x66, 0x70, 0xc0, 0x86, 0xb1, 0x58, 0x6d, +0x76, 0x87, 0xd3, 0xe5, 0x06, 0x04, 0x2c, 0x31, +0x1e, 0x12, 0xbc, 0x3e, 0x7f, 0x00, 0x07, 0x0e, +0x87, 0x60, 0x28, 0xcc, 0x72, 0x91, 0x68, 0x2c, +0x9e, 0xc0, 0x21, 0x89, 0x4d, 0x2a, 0x9d, 0xc9, +0x26, 0x73, 0xf9, 0x42, 0x91, 0xc7, 0xa1, 0x44, +0x4c, 0xb9, 0x52, 0xad, 0xd5, 0x1b, 0xcd, 0x56, +0x1b, 0x90, 0x20, 0x10, 0xc3, 0xb1, 0x9d, 0x6e, +0xaf, 0xcf, 0xb7, 0x45, 0xb2, 0x8d, 0x98, 0xc1, +0x70, 0x34, 0x9e, 0x4c, 0x67, 0xf3, 0x05, 0x09, +0xd8, 0x2c, 0x57, 0xeb, 0xcd, 0x96, 0xdf, 0xed, +0x0f, 0x47, 0xe9, 0x43, 0x38, 0x9d, 0x2f, 0x5b, +0x4a, 0xbc, 0xde, 0xee, 0x0f, 0x29, 0x08, 0x34, +0xf3, 0x7c, 0x91, 0x1d, 0xae, 0x37, 0x7c, 0x00, +0x0a, 0x4a, 0x16, 0xe9, 0x3e, 0x23, 0x57, 0xc9, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, +0x1e, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *exttables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_exttables_png = new wxImage(); + if (!img_exttables_png || !img_exttables_png->IsOk()) + { + wxMemoryInputStream img_exttables_pngIS(exttables_png_data, sizeof(exttables_png_data)); + img_exttables_png->LoadFile(img_exttables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_exttables_png; +} +#define exttables_png_img exttables_png_img() + +static wxBitmap *exttables_png_bmp() +{ + static wxBitmap *bmp_exttables_png; + if (!bmp_exttables_png || !bmp_exttables_png->IsOk()) + bmp_exttables_png = new wxBitmap(*exttables_png_img); + return bmp_exttables_png; +} +#define exttables_png_bmp exttables_png_bmp() + +static wxIcon *exttables_png_ico() +{ + static wxIcon *ico_exttables_png; + if (!ico_exttables_png || !ico_exttables_png->IsOk()) + { + ico_exttables_png = new wxIcon(); + ico_exttables_png->CopyFromBitmap(*exttables_png_bmp); + } + return ico_exttables_png; +} +#define exttables_png_ico exttables_png_ico() + +#endif // EXTTABLES_PNG_H diff --git a/include/images/favourite.png b/include/images/favourite.png new file mode 100644 index 0000000..a7fe1d6 Binary files /dev/null and b/include/images/favourite.png differ diff --git a/include/images/favourite.pngc b/include/images/favourite.pngc new file mode 100644 index 0000000..5f2b0f3 --- /dev/null +++ b/include/images/favourite.pngc @@ -0,0 +1,117 @@ +#ifndef FAVOURITE_PNG_H +#define FAVOURITE_PNG_H + +static const unsigned char favourite_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xfc, 0x50, 0x4c, 0x54, +0x45, 0xff, 0xff, 0xff, 0xd2, 0xbc, 0x8e, 0xc9, +0xa9, 0x52, 0xd5, 0xbd, 0x85, 0xdc, 0xb2, 0x1a, +0xf6, 0xf3, 0xeb, 0xe8, 0xde, 0xc8, 0xe9, 0xd0, +0x7a, 0xf6, 0xc6, 0x0a, 0xdc, 0xcc, 0xac, 0xf3, +0xee, 0xe4, 0xed, 0xe7, 0xd7, 0xd8, 0xc5, 0x9e, +0xfe, 0xe3, 0x6e, 0xff, 0xcf, 0x0a, 0xd3, 0xb9, +0x73, 0xed, 0xe6, 0xd7, 0xc6, 0xa0, 0x43, 0xe6, +0xcf, 0x7e, 0xdf, 0xce, 0x8c, 0xd9, 0xc4, 0x83, +0xdc, 0xc8, 0x99, 0xff, 0xd6, 0x2c, 0xff, 0xd6, +0x20, 0xe0, 0xc8, 0x66, 0xd7, 0xc2, 0x84, 0xde, +0xc4, 0x74, 0xe6, 0xc8, 0x67, 0xcc, 0xaa, 0x4b, +0xdd, 0xcc, 0xa8, 0xd3, 0xa7, 0x1e, 0xfc, 0xe8, +0x5e, 0xff, 0xf0, 0x6d, 0xff, 0xdc, 0x32, 0xff, +0xce, 0x06, 0xff, 0xe1, 0x40, 0xff, 0xf8, 0x87, +0xff, 0xf6, 0x80, 0xff, 0xdb, 0x2e, 0xd8, 0xa8, +0x0b, 0xd3, 0xbc, 0x88, 0xce, 0xb0, 0x64, 0xe6, +0xba, 0x18, 0xff, 0xd3, 0x14, 0xff, 0xd3, 0x16, +0xff, 0xeb, 0x5f, 0xff, 0xfe, 0x95, 0xef, 0xd8, +0x56, 0xc8, 0xa7, 0x4b, 0xf0, 0xea, 0xdc, 0xcc, +0xb2, 0x78, 0xff, 0xd7, 0x35, 0xff, 0xdd, 0x34, +0xff, 0xf6, 0x7e, 0xff, 0xf9, 0x89, 0xce, 0xaa, +0x36, 0xfa, 0xf9, 0xf5, 0xed, 0xe7, 0xd6, 0xde, +0xc2, 0x75, 0xff, 0xd0, 0x0e, 0xf6, 0xda, 0x49, +0xf1, 0xe8, 0xa6, 0xff, 0xf0, 0x72, 0xef, 0xc4, +0x19, 0xde, 0xcf, 0xae, 0xd0, 0xb9, 0x88, 0xfe, +0xdc, 0x58, 0xee, 0xc4, 0x1c, 0xcc, 0xb0, 0x6b, +0xd2, 0xbd, 0x8f, 0xe6, 0xd2, 0x90, 0xff, 0xd3, +0x20, 0xce, 0xae, 0x56, 0xce, 0xb0, 0x67, 0xe4, +0xb4, 0x0e, 0xd3, 0xbe, 0x8a, 0xda, 0xca, 0xa5, +0xdc, 0xc4, 0x85, 0xda, 0xbd, 0x54, 0xd4, 0xbe, +0x88, 0xe1, 0xd3, 0xb2, 0xe6, 0xdc, 0xc4, 0xcc, +0xb6, 0x80, 0xfa, 0xf9, 0xf6, 0x80, 0x47, 0x32, +0x54, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x80, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, +0x16, 0x30, 0x32, 0xa1, 0x09, 0x30, 0xb3, 0xb0, +0xa2, 0xf0, 0xd9, 0xd8, 0x39, 0x38, 0xe1, 0x1c, +0x2e, 0x6e, 0x56, 0x06, 0x1e, 0x5e, 0x3e, 0x7e, +0x06, 0x56, 0x01, 0x01, 0xb0, 0x80, 0xa0, 0x90, +0xb0, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, 0x94, +0xb4, 0x0c, 0x58, 0x40, 0x56, 0x4e, 0x5e, 0x41, +0x51, 0x49, 0x59, 0x45, 0x55, 0x4d, 0x5d, 0x03, +0xa2, 0x87, 0x55, 0x53, 0x4b, 0x5b, 0x47, 0x57, +0x4f, 0xdf, 0xc0, 0x10, 0x6e, 0x8c, 0x91, 0xb1, +0x89, 0xa9, 0x99, 0xb9, 0x05, 0x9c, 0x6f, 0x69, +0x65, 0x6d, 0x63, 0x6b, 0x67, 0xef, 0x00, 0x17, +0x70, 0x74, 0x72, 0x76, 0x71, 0x75, 0x73, 0xf7, +0x80, 0x0b, 0x78, 0x7a, 0x79, 0x33, 0x30, 0xf8, +0xf8, 0xfa, 0xc1, 0xdd, 0xe6, 0x1f, 0x00, 0x22, +0x03, 0x83, 0x82, 0x89, 0xf2, 0x25, 0x00, 0x73, +0xdc, 0x0d, 0xc3, 0xdd, 0x86, 0xc9, 0xe2, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x38, 0x99, 0x25, 0x1e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *favourite_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_favourite_png = new wxImage(); + if (!img_favourite_png || !img_favourite_png->IsOk()) + { + wxMemoryInputStream img_favourite_pngIS(favourite_png_data, sizeof(favourite_png_data)); + img_favourite_png->LoadFile(img_favourite_pngIS, wxBITMAP_TYPE_PNG); + } + return img_favourite_png; +} +#define favourite_png_img favourite_png_img() + +static wxBitmap *favourite_png_bmp() +{ + static wxBitmap *bmp_favourite_png; + if (!bmp_favourite_png || !bmp_favourite_png->IsOk()) + bmp_favourite_png = new wxBitmap(*favourite_png_img); + return bmp_favourite_png; +} +#define favourite_png_bmp favourite_png_bmp() + +static wxIcon *favourite_png_ico() +{ + static wxIcon *ico_favourite_png; + if (!ico_favourite_png || !ico_favourite_png->IsOk()) + { + ico_favourite_png = new wxIcon(); + ico_favourite_png->CopyFromBitmap(*favourite_png_bmp); + } + return ico_favourite_png; +} +#define favourite_png_ico favourite_png_ico() + +#endif // FAVOURITE_PNG_H diff --git a/include/images/file_new.png b/include/images/file_new.png new file mode 100644 index 0000000..f6affd3 Binary files /dev/null and b/include/images/file_new.png differ diff --git a/include/images/file_new.pngc b/include/images/file_new.pngc new file mode 100644 index 0000000..90c41e4 --- /dev/null +++ b/include/images/file_new.pngc @@ -0,0 +1,73 @@ +#ifndef FILE_NEW_PNG_H +#define FILE_NEW_PNG_H + +static const unsigned char file_new_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x01, 0x00, 0x00, 0x00, 0x00, 0x37, 0x88, 0xc2, +0xcc, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x01, 0xdd, 0x8a, 0x13, 0xa4, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x16, 0x49, 0x44, +0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x01, +0xfe, 0x03, 0x0c, 0xfc, 0x17, 0xc0, 0xe4, 0x0f, +0xec, 0x08, 0x0c, 0x00, 0xe5, 0x43, 0x0a, 0xb6, +0x5e, 0x9f, 0x71, 0xbb, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *file_new_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_file_new_png = new wxImage(); + if (!img_file_new_png || !img_file_new_png->IsOk()) + { + wxMemoryInputStream img_file_new_pngIS(file_new_png_data, sizeof(file_new_png_data)); + img_file_new_png->LoadFile(img_file_new_pngIS, wxBITMAP_TYPE_PNG); + } + return img_file_new_png; +} +#define file_new_png_img file_new_png_img() + +static wxBitmap *file_new_png_bmp() +{ + static wxBitmap *bmp_file_new_png; + if (!bmp_file_new_png || !bmp_file_new_png->IsOk()) + bmp_file_new_png = new wxBitmap(*file_new_png_img); + return bmp_file_new_png; +} +#define file_new_png_bmp file_new_png_bmp() + +static wxIcon *file_new_png_ico() +{ + static wxIcon *ico_file_new_png; + if (!ico_file_new_png || !ico_file_new_png->IsOk()) + { + ico_file_new_png = new wxIcon(); + ico_file_new_png->CopyFromBitmap(*file_new_png_bmp); + } + return ico_file_new_png; +} +#define file_new_png_ico file_new_png_ico() + +#endif // FILE_NEW_PNG_H diff --git a/include/images/file_open.png b/include/images/file_open.png new file mode 100644 index 0000000..82326bb Binary files /dev/null and b/include/images/file_open.png differ diff --git a/include/images/file_open.pngc b/include/images/file_open.pngc new file mode 100644 index 0000000..b98ad34 --- /dev/null +++ b/include/images/file_open.pngc @@ -0,0 +1,137 @@ +#ifndef FILE_OPEN_PNG_H +#define FILE_OPEN_PNG_H + +static const unsigned char file_open_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x56, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9d, 0xa9, 0xcf, 0xb4, +0xba, 0xd0, 0x67, 0x80, 0xcf, 0x43, 0x64, 0xce, +0x49, 0x68, 0xce, 0x63, 0x7c, 0xce, 0x89, 0x9a, +0xcf, 0x8b, 0x9b, 0xcf, 0xca, 0xcc, 0xd0, 0x94, +0xa2, 0xcf, 0x66, 0x7f, 0xcf, 0xc0, 0xb0, 0x62, +0xb5, 0x99, 0x15, 0xfa, 0xf6, 0xa1, 0xf6, 0xef, +0x7f, 0xf5, 0xed, 0x7e, 0xf7, 0xf1, 0x94, 0xf0, +0xe4, 0x51, 0xef, 0xe2, 0x4f, 0xef, 0xe3, 0x59, +0xf4, 0xec, 0x86, 0xed, 0xe0, 0x4e, 0xeb, 0xde, +0x4c, 0xeb, 0xde, 0x57, 0xee, 0xe3, 0x6d, 0xef, +0xe4, 0x77, 0xed, 0xe2, 0x76, 0xeb, 0xe0, 0x75, +0xea, 0xde, 0x73, 0xf2, 0xea, 0x97, 0xf5, 0xec, +0x7d, 0xca, 0xb4, 0x2b, 0xc0, 0xaf, 0x60, 0xcb, +0xc6, 0xad, 0xf3, 0xeb, 0x7c, 0xd4, 0xc1, 0x35, +0xd1, 0xbf, 0x5d, 0xf6, 0xf4, 0xb6, 0xf4, 0xf1, +0xaa, 0xf4, 0xf1, 0xa7, 0xf5, 0xf1, 0xa3, 0xf5, +0xf1, 0x9f, 0xf5, 0xf1, 0x9a, 0xf5, 0xf1, 0x96, +0xf5, 0xf1, 0x91, 0xf8, 0xf3, 0x9d, 0xdf, 0xd2, +0x74, 0xf2, 0xea, 0x7a, 0xe9, 0xdb, 0x4b, 0xbf, +0xa5, 0x1f, 0xeb, 0xe4, 0x9a, 0xef, 0xec, 0x93, +0xee, 0xea, 0x88, 0xef, 0xea, 0x83, 0xef, 0xea, +0x7e, 0xef, 0xe9, 0x78, 0xf0, 0xe9, 0x72, 0xf0, +0xe9, 0x6c, 0xf1, 0xe8, 0x68, 0xf5, 0xef, 0x84, +0xc2, 0xab, 0x32, 0xf1, 0xe8, 0x7a, 0xdd, 0xcb, +0x3e, 0xc4, 0xad, 0x3b, 0xf3, 0xf1, 0xa6, 0xee, +0xea, 0x8a, 0xef, 0xea, 0x84, 0xef, 0xea, 0x7f, +0xef, 0xe9, 0x79, 0xf0, 0xe9, 0x73, 0xf0, 0xe9, +0x6d, 0xf1, 0xe8, 0x67, 0xf2, 0xea, 0x6c, 0xea, +0xe1, 0x7f, 0xbb, 0xa5, 0x3d, 0xf0, 0xe6, 0x78, +0xc7, 0xb0, 0x28, 0xdf, 0xd4, 0x81, 0xf0, 0xed, +0x96, 0xef, 0xea, 0x85, 0xef, 0xea, 0x80, 0xef, +0xe9, 0x7a, 0xf0, 0xe9, 0x74, 0xf0, 0xe9, 0x6e, +0xf1, 0xe8, 0x62, 0xf4, 0xed, 0x77, 0xcf, 0xbd, +0x4f, 0xc6, 0xbb, 0x8a, 0xeb, 0xdf, 0x70, 0xba, +0xa0, 0x22, 0xf2, 0xef, 0xa6, 0xf0, 0xeb, 0x8a, +0xef, 0xe9, 0x7b, 0xf0, 0xe9, 0x75, 0xf1, 0xe8, +0x63, 0xf2, 0xe9, 0x63, 0xf2, 0xeb, 0x83, 0xb7, +0x9c, 0x1a, 0xcf, 0xce, 0xc9, 0xd8, 0xc8, 0x5f, +0xd4, 0xc4, 0x65, 0xf8, 0xf5, 0xb6, 0xf5, 0xf1, +0xa2, 0xf5, 0xf1, 0x9e, 0xf5, 0xf1, 0x94, 0xf5, +0xf0, 0x90, 0xf6, 0xf0, 0x8b, 0xf6, 0xf0, 0x88, +0xf8, 0xf1, 0x8f, 0xdc, 0xce, 0x6a, 0xc1, 0xb2, +0x69, 0xba, 0xa2, 0x35, 0xcc, 0xc8, 0xb6, 0x9a, +0x70, 0x84, 0x4f, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xc3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x80, 0x01, 0x46, 0x46, 0x26, 0x06, 0x64, +0xc0, 0xcc, 0xc2, 0xca, 0xc6, 0xce, 0xc0, 0x02, +0xe7, 0x73, 0x30, 0x33, 0x70, 0x72, 0x71, 0xb3, +0xb0, 0xa0, 0x28, 0x62, 0x60, 0x01, 0x09, 0xf0, +0xf0, 0x02, 0x01, 0x0f, 0x94, 0xcf, 0x0a, 0x14, +0xe0, 0xe5, 0xe3, 0x17, 0x10, 0x84, 0x8a, 0x80, +0x01, 0x2f, 0xbf, 0x90, 0xb0, 0x88, 0x28, 0x2f, +0x2f, 0x5c, 0x21, 0xaf, 0x80, 0xb0, 0x98, 0xb8, +0x84, 0xa4, 0x94, 0xb4, 0x8c, 0xac, 0x1c, 0x2f, +0x58, 0x40, 0x5e, 0x4c, 0x5c, 0x81, 0x17, 0x06, +0x14, 0x95, 0x18, 0x78, 0x95, 0xc5, 0x55, 0x54, +0xd5, 0xd4, 0x35, 0x34, 0xb5, 0xb4, 0x75, 0x74, +0xf5, 0xf4, 0x15, 0x19, 0x78, 0x0d, 0x0c, 0x8d, +0x8c, 0x4d, 0x4c, 0xcd, 0xcc, 0x2d, 0x2c, 0xad, +0xac, 0x6d, 0x6c, 0x81, 0x2a, 0xec, 0xec, 0x1d, +0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, 0xdc, 0x3d, +0x3c, 0xbd, 0xbc, 0x81, 0x66, 0xf8, 0xf8, 0xfa, +0xf9, 0x07, 0x04, 0x06, 0x05, 0x87, 0x78, 0x84, +0x86, 0x85, 0x47, 0x00, 0x05, 0x22, 0xa3, 0xa2, +0x63, 0x02, 0x63, 0xe3, 0x42, 0xac, 0xe3, 0x13, +0x12, 0x93, 0x92, 0x81, 0x02, 0x29, 0xa9, 0x69, +0xe9, 0x19, 0xda, 0x99, 0x59, 0xd9, 0x39, 0xb9, +0x79, 0xf9, 0x0c, 0x50, 0xa7, 0x43, 0x41, 0x41, +0x21, 0x03, 0x03, 0x00, 0x5a, 0x33, 0x1d, 0xa8, +0x77, 0xb7, 0xf6, 0x35, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *file_open_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_file_open_png = new wxImage(); + if (!img_file_open_png || !img_file_open_png->IsOk()) + { + wxMemoryInputStream img_file_open_pngIS(file_open_png_data, sizeof(file_open_png_data)); + img_file_open_png->LoadFile(img_file_open_pngIS, wxBITMAP_TYPE_PNG); + } + return img_file_open_png; +} +#define file_open_png_img file_open_png_img() + +static wxBitmap *file_open_png_bmp() +{ + static wxBitmap *bmp_file_open_png; + if (!bmp_file_open_png || !bmp_file_open_png->IsOk()) + bmp_file_open_png = new wxBitmap(*file_open_png_img); + return bmp_file_open_png; +} +#define file_open_png_bmp file_open_png_bmp() + +static wxIcon *file_open_png_ico() +{ + static wxIcon *ico_file_open_png; + if (!ico_file_open_png || !ico_file_open_png->IsOk()) + { + ico_file_open_png = new wxIcon(); + ico_file_open_png->CopyFromBitmap(*file_open_png_bmp); + } + return ico_file_open_png; +} +#define file_open_png_ico file_open_png_ico() + +#endif // FILE_OPEN_PNG_H diff --git a/include/images/file_save.png b/include/images/file_save.png new file mode 100644 index 0000000..52da505 Binary files /dev/null and b/include/images/file_save.png differ diff --git a/include/images/file_save.pngc b/include/images/file_save.pngc new file mode 100644 index 0000000..d9047e4 --- /dev/null +++ b/include/images/file_save.pngc @@ -0,0 +1,124 @@ +#ifndef FILE_SAVE_PNG_H +#define FILE_SAVE_PNG_H + +static const unsigned char file_save_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x70, 0x92, 0xc5, 0x2c, +0x66, 0xbd, 0x9b, 0xd0, 0xe1, 0xf2, 0xf9, 0xfc, +0xe9, 0xf5, 0xfa, 0xe6, 0xf4, 0xfa, 0xe3, 0xf3, +0xf9, 0xde, 0xf1, 0xf9, 0xda, 0xf0, 0xf8, 0xe6, +0xf5, 0xfb, 0x9d, 0xc9, 0xe6, 0x7a, 0xbf, 0xd7, +0xb1, 0xb1, 0xb1, 0xcd, 0xec, 0xf7, 0x7d, 0xb6, +0xde, 0xe5, 0xf3, 0xfa, 0xd2, 0xec, 0xf6, 0xcb, +0xea, 0xf5, 0xc4, 0xe8, 0xf5, 0xbc, 0xe5, 0xf4, +0xb4, 0xe3, 0xf4, 0xad, 0xe1, 0xf3, 0xc5, 0xea, +0xf7, 0x7e, 0xb4, 0xe0, 0x7b, 0xbe, 0xd8, 0xbf, +0xe8, 0xf6, 0x7f, 0xb3, 0xe0, 0x7b, 0xbd, 0xd9, +0xe7, 0xf6, 0xfb, 0xd2, 0xee, 0xf8, 0xc8, 0xeb, +0xf7, 0xc4, 0xea, 0xf7, 0xc0, 0xe9, 0xf7, 0xbd, +0xe8, 0xf6, 0xd6, 0xf1, 0xfa, 0x7f, 0xb0, 0xe2, +0x7c, 0xbc, 0xda, 0x3b, 0x80, 0xc4, 0x3c, 0x7a, +0xc8, 0x80, 0xaf, 0xe3, 0x7c, 0xba, 0xda, 0x51, +0xa2, 0xcf, 0x51, 0xa0, 0xd1, 0x52, 0x9f, 0xd2, +0x52, 0x9d, 0xd3, 0x53, 0x9c, 0xd4, 0x53, 0x9a, +0xd5, 0x54, 0x99, 0xd6, 0x54, 0x97, 0xd7, 0x55, +0x95, 0xd8, 0x55, 0x94, 0xda, 0x80, 0xae, 0xe4, +0x7d, 0xb9, 0xdc, 0x52, 0x9e, 0xd2, 0x53, 0x9b, +0xd4, 0x54, 0x98, 0xd7, 0x54, 0x96, 0xd8, 0x55, +0x95, 0xd9, 0x55, 0x93, 0xda, 0x56, 0x92, 0xdb, +0x80, 0xad, 0xe5, 0x7d, 0xb7, 0xdd, 0x3c, 0x7c, +0xc6, 0x3d, 0x79, 0xc9, 0x56, 0x90, 0xdc, 0x81, +0xab, 0xe6, 0xe4, 0xf3, 0xf9, 0xdc, 0xf1, 0xf8, +0xe5, 0xf5, 0xfb, 0x56, 0x90, 0xdd, 0x57, 0x8f, +0xdd, 0x81, 0xaa, 0xe6, 0x94, 0xc1, 0xe4, 0x5e, +0xa0, 0xd8, 0xe7, 0xf4, 0xfa, 0xb6, 0xe4, 0xf4, +0xc7, 0xeb, 0xf7, 0x57, 0x8e, 0xde, 0x57, 0x8d, +0xde, 0x81, 0xa9, 0xe7, 0x94, 0xbe, 0xe6, 0xea, +0xf6, 0xfb, 0xd4, 0xef, 0xf8, 0xcb, 0xec, 0xf7, +0xc3, 0xea, 0xf7, 0xd8, 0xf1, 0xfa, 0x81, 0xaa, +0xe7, 0x82, 0xa9, 0xe7, 0xa1, 0xbd, 0xed, 0x07, +0x7f, 0x8b, 0xc1, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xa5, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, +0xcf, 0xe5, 0x0e, 0xc2, 0x00, 0x0c, 0x04, 0x60, +0x76, 0x30, 0x1c, 0x86, 0xbb, 0x3b, 0x0c, 0x77, +0x77, 0x77, 0x97, 0xf7, 0x7f, 0x11, 0x46, 0x81, +0x84, 0xb0, 0xfb, 0xf9, 0xa5, 0x4d, 0x7b, 0x12, +0x89, 0x28, 0x0c, 0x7e, 0xc2, 0x08, 0x00, 0x29, +0x64, 0x2c, 0x2b, 0x57, 0x28, 0x55, 0x6a, 0x68, +0xf0, 0x02, 0x2d, 0x58, 0x1d, 0x45, 0x0f, 0xee, +0x03, 0x06, 0xa3, 0xc9, 0x6c, 0xb1, 0xda, 0xec, +0x70, 0x10, 0x38, 0xa1, 0x7c, 0x4f, 0xb8, 0xe0, +0x26, 0xf0, 0xc0, 0xeb, 0xd3, 0xfb, 0x03, 0xc1, +0x50, 0x18, 0x11, 0x82, 0x68, 0xec, 0x7b, 0x23, +0x9e, 0x20, 0x48, 0xa6, 0xf8, 0x74, 0x26, 0x9b, +0xcb, 0x17, 0x8a, 0xa5, 0x32, 0x41, 0x85, 0xaf, +0x66, 0x6a, 0xb9, 0x7a, 0xa3, 0xd9, 0x6a, 0x77, +0x08, 0xba, 0xd5, 0x1e, 0x2d, 0xf4, 0xdb, 0x83, +0x21, 0x01, 0x97, 0x15, 0x3e, 0x1b, 0x8d, 0x27, +0x98, 0xce, 0xe6, 0x04, 0x8b, 0x25, 0x56, 0x30, +0xaf, 0x37, 0xd8, 0xee, 0xf6, 0xa0, 0x2e, 0x07, +0x1c, 0x4f, 0xe7, 0xcb, 0x15, 0xb7, 0xfb, 0x03, +0xff, 0xed, 0x18, 0x71, 0xf9, 0x27, 0x79, 0x13, +0x12, 0x4f, 0xeb, 0x94, 0x1d, 0x51, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *file_save_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_file_save_png = new wxImage(); + if (!img_file_save_png || !img_file_save_png->IsOk()) + { + wxMemoryInputStream img_file_save_pngIS(file_save_png_data, sizeof(file_save_png_data)); + img_file_save_png->LoadFile(img_file_save_pngIS, wxBITMAP_TYPE_PNG); + } + return img_file_save_png; +} +#define file_save_png_img file_save_png_img() + +static wxBitmap *file_save_png_bmp() +{ + static wxBitmap *bmp_file_save_png; + if (!bmp_file_save_png || !bmp_file_save_png->IsOk()) + bmp_file_save_png = new wxBitmap(*file_save_png_img); + return bmp_file_save_png; +} +#define file_save_png_bmp file_save_png_bmp() + +static wxIcon *file_save_png_ico() +{ + static wxIcon *ico_file_save_png; + if (!ico_file_save_png || !ico_file_save_png->IsOk()) + { + ico_file_save_png = new wxIcon(); + ico_file_save_png->CopyFromBitmap(*file_save_png_bmp); + } + return ico_file_save_png; +} +#define file_save_png_ico file_save_png_ico() + +#endif // FILE_SAVE_PNG_H diff --git a/include/images/folder.png b/include/images/folder.png new file mode 100644 index 0000000..d7d09d2 Binary files /dev/null and b/include/images/folder.png differ diff --git a/include/images/folder.pngc b/include/images/folder.pngc new file mode 100644 index 0000000..f6c8ddc --- /dev/null +++ b/include/images/folder.pngc @@ -0,0 +1,108 @@ +#ifndef FOLDER_PNG_H +#define FOLDER_PNG_H + +static const unsigned char folder_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x9c, 0x50, 0x4c, 0x54, +0x45, 0xff, 0xff, 0xff, 0xcc, 0x99, 0x34, 0xcb, +0x98, 0x33, 0xc9, 0x96, 0x31, 0xc7, 0x94, 0x2f, +0xdf, 0xdf, 0xdf, 0xf6, 0xf6, 0xf6, 0xc2, 0x8f, +0x2a, 0xc8, 0xc8, 0xc8, 0xff, 0xff, 0x99, 0xbd, +0x8a, 0x25, 0xba, 0x87, 0x22, 0xb7, 0x84, 0x1f, +0xb5, 0x82, 0x1d, 0xb3, 0x81, 0x1b, 0xb0, 0x7e, +0x18, 0xf7, 0xf7, 0xf7, 0xff, 0xf7, 0x91, 0xff, +0xf4, 0x8e, 0xae, 0x7c, 0x16, 0x8c, 0x8c, 0x8c, +0xde, 0xde, 0xde, 0xff, 0xeb, 0x85, 0xff, 0xe6, +0x81, 0xc5, 0x92, 0x2d, 0xc0, 0x8d, 0x28, 0xbc, +0x89, 0x24, 0xb8, 0x85, 0x20, 0xb4, 0x81, 0x1c, +0xff, 0xe0, 0x7b, 0xa3, 0x71, 0x0b, 0xff, 0xd4, +0x6f, 0xf8, 0xc5, 0x60, 0xa0, 0x6e, 0x08, 0x6d, +0x6d, 0x6d, 0xff, 0xcc, 0x67, 0xef, 0xbc, 0x57, +0x9e, 0x6c, 0x06, 0x6c, 0x6c, 0x6c, 0xe6, 0xb3, +0x4e, 0x9c, 0x6a, 0x04, 0xbf, 0x8c, 0x27, 0xdc, +0xa9, 0x44, 0x9a, 0x68, 0x02, 0xd3, 0xa0, 0x3b, +0x99, 0x67, 0x01, 0xab, 0x79, 0x13, 0xa8, 0x76, +0x10, 0xa5, 0x73, 0x0d, 0x4b, 0x4b, 0x4b, 0x83, +0x83, 0x83, 0xd6, 0xd6, 0xd6, 0xa3, 0x75, 0x43, +0x26, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x97, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0xe9, +0x0e, 0x82, 0x40, 0x0c, 0x04, 0xe0, 0xe1, 0x58, +0xa0, 0xa0, 0x28, 0x82, 0x1c, 0x22, 0x20, 0xac, +0xac, 0x28, 0xe2, 0x81, 0xef, 0xff, 0x6e, 0x02, +0x59, 0xc5, 0xc4, 0xef, 0x47, 0x93, 0xc9, 0x24, +0x4d, 0x0b, 0xfc, 0x53, 0x54, 0x4d, 0x67, 0xc6, +0x4f, 0x1e, 0x87, 0x69, 0x19, 0x73, 0xa6, 0x01, +0x6c, 0x67, 0xb1, 0x74, 0x57, 0x6c, 0x0d, 0xa8, +0xde, 0x66, 0x34, 0x95, 0x7e, 0xb0, 0x05, 0xb4, +0x30, 0x8a, 0x27, 0xc9, 0x2e, 0xdd, 0xbb, 0x2e, +0x83, 0x9e, 0xc5, 0xdf, 0x75, 0x11, 0xf2, 0x00, +0x71, 0xa1, 0xd0, 0xc7, 0x81, 0xca, 0x0a, 0x26, +0x57, 0xc9, 0x93, 0x8e, 0x54, 0x0b, 0x24, 0x3c, +0xa6, 0x50, 0x3a, 0x51, 0x23, 0x60, 0xf3, 0x33, +0x65, 0xd2, 0x85, 0x5a, 0x01, 0x87, 0xa7, 0x54, +0x48, 0x57, 0xea, 0x2a, 0xb0, 0xe1, 0x1e, 0xff, +0x76, 0x7f, 0xe4, 0x65, 0xdd, 0xb4, 0xdd, 0xb3, +0x87, 0x61, 0xf5, 0x62, 0xd6, 0x5b, 0x80, 0xc1, +0x5e, 0xb3, 0xdf, 0x27, 0xa5, 0x37, 0x56, 0xfe, +0x10, 0xee, 0x9b, 0x30, 0x4c, 0xd0, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *folder_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_folder_png = new wxImage(); + if (!img_folder_png || !img_folder_png->IsOk()) + { + wxMemoryInputStream img_folder_pngIS(folder_png_data, sizeof(folder_png_data)); + img_folder_png->LoadFile(img_folder_pngIS, wxBITMAP_TYPE_PNG); + } + return img_folder_png; +} +#define folder_png_img folder_png_img() + +static wxBitmap *folder_png_bmp() +{ + static wxBitmap *bmp_folder_png; + if (!bmp_folder_png || !bmp_folder_png->IsOk()) + bmp_folder_png = new wxBitmap(*folder_png_img); + return bmp_folder_png; +} +#define folder_png_bmp folder_png_bmp() + +static wxIcon *folder_png_ico() +{ + static wxIcon *ico_folder_png; + if (!ico_folder_png || !ico_folder_png->IsOk()) + { + ico_folder_png = new wxIcon(); + ico_folder_png->CopyFromBitmap(*folder_png_bmp); + } + return ico_folder_png; +} +#define folder_png_ico folder_png_ico() + +#endif // FOLDER_PNG_H diff --git a/include/images/foreigndatawrapper-sm.png b/include/images/foreigndatawrapper-sm.png new file mode 100644 index 0000000..2467ccf Binary files /dev/null and b/include/images/foreigndatawrapper-sm.png differ diff --git a/include/images/foreigndatawrapper-sm.pngc b/include/images/foreigndatawrapper-sm.pngc new file mode 100644 index 0000000..dc4cefa --- /dev/null +++ b/include/images/foreigndatawrapper-sm.pngc @@ -0,0 +1,97 @@ +#ifndef FOREIGNDATAWRAPPER_SM_PNG_H +#define FOREIGNDATAWRAPPER_SM_PNG_H + +static const unsigned char foreigndatawrapper_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xd9, 0x86, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xf7, 0xef, 0xd4, +0xd8, 0xb3, 0x1f, 0xe3, 0xcd, 0x39, 0xed, 0xe2, +0x4f, 0xf4, 0xf2, 0x5f, 0xf4, 0xea, 0xc5, 0xda, +0xb7, 0x23, 0xec, 0xde, 0x4b, 0xf8, 0xf9, 0x67, +0xe6, 0xd0, 0x69, 0xe8, 0xd6, 0x43, 0xf8, 0xfa, +0x69, 0xe8, 0xd1, 0x80, 0xda, 0xb6, 0x32, 0xf4, +0xee, 0x5f, 0xf9, 0xfa, 0x6b, 0xda, 0xb6, 0x38, +0xf4, 0xef, 0x60, 0xfa, 0xfb, 0x6d, 0xe9, 0xd6, +0x47, 0xfb, 0xfb, 0x6f, 0xdb, 0xb8, 0x25, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x07, 0x86, 0xb5, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x8d, 0x8f, 0x49, 0x0e, 0x80, +0x20, 0x10, 0x04, 0x47, 0x14, 0x5c, 0x50, 0xdc, +0x77, 0xdc, 0x40, 0xff, 0xff, 0x45, 0x13, 0x98, +0x18, 0xb9, 0x51, 0xb7, 0xae, 0xa4, 0x33, 0x3d, +0x00, 0x7e, 0x04, 0x24, 0x0c, 0x09, 0x44, 0x5f, +0xa6, 0x2c, 0x4e, 0x92, 0x98, 0xd1, 0x14, 0x73, +0xc6, 0x73, 0x03, 0xcf, 0x6c, 0x2e, 0x44, 0x89, +0x88, 0xca, 0x88, 0xba, 0x69, 0x91, 0xa6, 0x33, +0xa2, 0xeb, 0x07, 0xa4, 0xb7, 0xa2, 0x1a, 0x27, +0x64, 0xb4, 0x15, 0x98, 0x97, 0xd5, 0xb0, 0xcc, +0x78, 0x25, 0x95, 0xdb, 0x7e, 0x1c, 0xe7, 0x29, +0x7f, 0xcb, 0xc8, 0xa5, 0xb4, 0x56, 0xce, 0xd8, +0x5b, 0x3d, 0xae, 0x00, 0x50, 0xb7, 0xdf, 0x9f, +0x2f, 0xe4, 0x0e, 0x07, 0xe3, 0xd8, 0x9f, 0xd2, +0x10, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, +0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xd3, 0xe6, +0xa8, 0x62, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, +0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, +0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xa2, +0xbb, 0x10, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigndatawrapper_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigndatawrapper_sm_png = new wxImage(); + if (!img_foreigndatawrapper_sm_png || !img_foreigndatawrapper_sm_png->IsOk()) + { + wxMemoryInputStream img_foreigndatawrapper_sm_pngIS(foreigndatawrapper_sm_png_data, sizeof(foreigndatawrapper_sm_png_data)); + img_foreigndatawrapper_sm_png->LoadFile(img_foreigndatawrapper_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigndatawrapper_sm_png; +} +#define foreigndatawrapper_sm_png_img foreigndatawrapper_sm_png_img() + +static wxBitmap *foreigndatawrapper_sm_png_bmp() +{ + static wxBitmap *bmp_foreigndatawrapper_sm_png; + if (!bmp_foreigndatawrapper_sm_png || !bmp_foreigndatawrapper_sm_png->IsOk()) + bmp_foreigndatawrapper_sm_png = new wxBitmap(*foreigndatawrapper_sm_png_img); + return bmp_foreigndatawrapper_sm_png; +} +#define foreigndatawrapper_sm_png_bmp foreigndatawrapper_sm_png_bmp() + +static wxIcon *foreigndatawrapper_sm_png_ico() +{ + static wxIcon *ico_foreigndatawrapper_sm_png; + if (!ico_foreigndatawrapper_sm_png || !ico_foreigndatawrapper_sm_png->IsOk()) + { + ico_foreigndatawrapper_sm_png = new wxIcon(); + ico_foreigndatawrapper_sm_png->CopyFromBitmap(*foreigndatawrapper_sm_png_bmp); + } + return ico_foreigndatawrapper_sm_png; +} +#define foreigndatawrapper_sm_png_ico foreigndatawrapper_sm_png_ico() + +#endif // FOREIGNDATAWRAPPER_SM_PNG_H diff --git a/include/images/foreigndatawrapper.png b/include/images/foreigndatawrapper.png new file mode 100644 index 0000000..0cb9676 Binary files /dev/null and b/include/images/foreigndatawrapper.png differ diff --git a/include/images/foreigndatawrapper.pngc b/include/images/foreigndatawrapper.pngc new file mode 100644 index 0000000..ee20c4d --- /dev/null +++ b/include/images/foreigndatawrapper.pngc @@ -0,0 +1,96 @@ +#ifndef FOREIGNDATAWRAPPER_PNG_H +#define FOREIGNDATAWRAPPER_PNG_H + +static const unsigned char foreigndatawrapper_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcc, 0x50, 0x4c, 0x54, 0x45, 0x96, 0x81, +0x8f, 0x83, 0x6c, 0x7c, 0xea, 0xdf, 0xe7, 0xe2, +0xd5, 0xde, 0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, +0xc6, 0xb1, 0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, +0x82, 0x99, 0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, +0xdf, 0xe5, 0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, +0xbf, 0xa8, 0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, +0xd8, 0xea, 0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, +0xbe, 0xca, 0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, +0xf2, 0xf1, 0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, +0xf2, 0xfa, 0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, +0xdb, 0xdf, 0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, +0xe0, 0xd3, 0xd7, 0xc4, 0xab, 0xb5, 0xb4, 0x95, +0xa1, 0xc4, 0xad, 0xb6, 0xef, 0xee, 0xee, 0xf7, +0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0xb2, 0x90, 0x9e, +0xc3, 0xad, 0xb5, 0xf6, 0xf5, 0xf5, 0xe1, 0xd4, +0xd8, 0xc4, 0xae, 0xb8, 0xef, 0xee, 0xef, 0xc3, +0xaa, 0xb3, 0xb2, 0x90, 0x9d, 0xc4, 0xad, 0xb7, +0xc7, 0xc6, 0xc7, 0xe0, 0xd4, 0xd8, 0xa2, 0x8c, +0x94, 0xb5, 0x96, 0xa3, 0xa1, 0x8e, 0x96, 0xcd, +0xcc, 0xcc, 0x91, 0x75, 0x80, 0xb4, 0x96, 0xa1, +0xc3, 0xad, 0xb6, 0xac, 0xa2, 0xa7, 0xf0, 0xee, +0xf0, 0xba, 0xb0, 0xb4, 0x7b, 0x94, 0xa4, 0x4b, +0x98, 0xa8, 0x8c, 0xab, 0xb8, 0xe1, 0xd4, 0xd9, +0xa1, 0x8c, 0x94, 0x5a, 0xa2, 0xb4, 0x1f, 0xda, +0xc7, 0x52, 0xa4, 0xb3, 0x67, 0x83, 0x92, 0x5b, +0xa5, 0xb6, 0x63, 0x28, 0xe2, 0xd4, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x03, +0x1d, 0x15, 0x11, 0x30, 0x3e, 0x13, 0xc1, 0xf9, +0x00, 0x00, 0x00, 0x3b, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0xbd, 0xcf, 0xd1, 0x0d, 0x00, 0x40, +0x04, 0x03, 0xd0, 0x1a, 0xa3, 0xfb, 0x2f, 0x2a, +0xae, 0x45, 0x2c, 0x70, 0x3e, 0x88, 0xf7, 0x51, +0x01, 0xc4, 0x29, 0xa0, 0x80, 0xae, 0x81, 0x98, +0xfd, 0x01, 0x2d, 0x35, 0x04, 0x12, 0x35, 0x01, +0x15, 0xc8, 0x05, 0x76, 0xd0, 0x00, 0x1d, 0xbc, +0xd0, 0x87, 0xff, 0xc1, 0x7d, 0x3f, 0x01, 0x57, +0x52, 0x0d, 0x71, 0x7e, 0x86, 0xdc, 0xc2, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigndatawrapper_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigndatawrapper_png = new wxImage(); + if (!img_foreigndatawrapper_png || !img_foreigndatawrapper_png->IsOk()) + { + wxMemoryInputStream img_foreigndatawrapper_pngIS(foreigndatawrapper_png_data, sizeof(foreigndatawrapper_png_data)); + img_foreigndatawrapper_png->LoadFile(img_foreigndatawrapper_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigndatawrapper_png; +} +#define foreigndatawrapper_png_img foreigndatawrapper_png_img() + +static wxBitmap *foreigndatawrapper_png_bmp() +{ + static wxBitmap *bmp_foreigndatawrapper_png; + if (!bmp_foreigndatawrapper_png || !bmp_foreigndatawrapper_png->IsOk()) + bmp_foreigndatawrapper_png = new wxBitmap(*foreigndatawrapper_png_img); + return bmp_foreigndatawrapper_png; +} +#define foreigndatawrapper_png_bmp foreigndatawrapper_png_bmp() + +static wxIcon *foreigndatawrapper_png_ico() +{ + static wxIcon *ico_foreigndatawrapper_png; + if (!ico_foreigndatawrapper_png || !ico_foreigndatawrapper_png->IsOk()) + { + ico_foreigndatawrapper_png = new wxIcon(); + ico_foreigndatawrapper_png->CopyFromBitmap(*foreigndatawrapper_png_bmp); + } + return ico_foreigndatawrapper_png; +} +#define foreigndatawrapper_png_ico foreigndatawrapper_png_ico() + +#endif // FOREIGNDATAWRAPPER_PNG_H diff --git a/include/images/foreigndatawrappers.png b/include/images/foreigndatawrappers.png new file mode 100644 index 0000000..6b1c854 Binary files /dev/null and b/include/images/foreigndatawrappers.png differ diff --git a/include/images/foreigndatawrappers.pngc b/include/images/foreigndatawrappers.pngc new file mode 100644 index 0000000..e01147c --- /dev/null +++ b/include/images/foreigndatawrappers.pngc @@ -0,0 +1,100 @@ +#ifndef FOREIGNDATAWRAPPERS_PNG_H +#define FOREIGNDATAWRAPPERS_PNG_H + +static const unsigned char foreigndatawrappers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xae, 0x50, 0x4c, 0x54, 0x45, 0x96, 0x81, +0x8f, 0x83, 0x6c, 0x7c, 0xea, 0xdf, 0xe7, 0xe2, +0xd5, 0xde, 0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, +0xc6, 0xb1, 0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, +0x82, 0x99, 0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, +0xdf, 0xe5, 0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, +0xbf, 0xa8, 0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, +0xd8, 0xea, 0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, +0xbe, 0xca, 0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, +0xf2, 0xf1, 0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, +0xf2, 0xfa, 0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, +0xdb, 0xdf, 0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, +0xe0, 0xd3, 0xd7, 0xc4, 0xab, 0xb5, 0x5c, 0xa4, +0xb6, 0x8c, 0xab, 0xb8, 0xef, 0xee, 0xee, 0xf7, +0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0x5b, 0xa0, 0xb3, +0x1f, 0xda, 0xc7, 0x63, 0xb1, 0xc1, 0x98, 0x7c, +0x95, 0x67, 0x85, 0x9b, 0x4f, 0x97, 0xad, 0xf4, +0xf1, 0xf2, 0xe1, 0xd4, 0xd8, 0xc3, 0xaa, 0xb3, +0x5b, 0xa5, 0xb6, 0xef, 0xee, 0xef, 0xe0, 0xd4, +0xd8, 0x5b, 0xa2, 0xb4, 0xf5, 0xf1, 0xf3, 0xf9, +0xf9, 0xf9, 0xe6, 0xef, 0xf1, 0xcf, 0xdb, 0xe0, +0xe1, 0xd4, 0xd9, 0xc3, 0xab, 0xb4, 0x5a, 0xa2, +0xb4, 0xf6, 0xf5, 0xf5, 0x98, 0xa4, 0xe8, 0x99, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, +0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, +0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, +0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, +0xdb, 0x03, 0x1d, 0x15, 0x11, 0x24, 0x24, 0xc9, +0x15, 0x84, 0x00, 0x00, 0x00, 0x7a, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x8e, 0xb1, 0x0a, +0x04, 0x21, 0x10, 0x43, 0xb5, 0xbd, 0x6d, 0xc5, +0x20, 0xd8, 0x68, 0x33, 0x90, 0x3e, 0xff, 0xff, +0x6b, 0x37, 0x3a, 0xbb, 0x8b, 0x77, 0x69, 0x24, +0x8f, 0x98, 0x49, 0xca, 0x87, 0xd2, 0x92, 0xbf, +0x6d, 0xeb, 0x00, 0xbf, 0x99, 0xdc, 0xfe, 0x32, +0x1b, 0x9c, 0x19, 0x07, 0x91, 0xf9, 0x14, 0xb3, +0xa1, 0x17, 0x64, 0xa3, 0x69, 0x18, 0x19, 0xa0, +0x65, 0x0e, 0x74, 0x01, 0x28, 0x37, 0xb0, 0x01, +0xd1, 0xd0, 0x3b, 0x1e, 0xe0, 0x9e, 0xaa, 0x52, +0xdd, 0xc3, 0x32, 0xb5, 0x3c, 0xea, 0xec, 0x8a, +0xc3, 0xbc, 0xe6, 0x2a, 0x55, 0x9d, 0x8a, 0xad, +0xbc, 0x00, 0xbf, 0x60, 0xa8, 0x16, 0xf3, 0x3d, +0xee, 0x7f, 0xb8, 0x9a, 0x02, 0x94, 0xb1, 0xbc, +0xd7, 0x30, 0x40, 0x4a, 0x66, 0xbc, 0xf5, 0x05, +0x6f, 0x95, 0x13, 0x38, 0x14, 0x91, 0x2d, 0xb4, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigndatawrappers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigndatawrappers_png = new wxImage(); + if (!img_foreigndatawrappers_png || !img_foreigndatawrappers_png->IsOk()) + { + wxMemoryInputStream img_foreigndatawrappers_pngIS(foreigndatawrappers_png_data, sizeof(foreigndatawrappers_png_data)); + img_foreigndatawrappers_png->LoadFile(img_foreigndatawrappers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigndatawrappers_png; +} +#define foreigndatawrappers_png_img foreigndatawrappers_png_img() + +static wxBitmap *foreigndatawrappers_png_bmp() +{ + static wxBitmap *bmp_foreigndatawrappers_png; + if (!bmp_foreigndatawrappers_png || !bmp_foreigndatawrappers_png->IsOk()) + bmp_foreigndatawrappers_png = new wxBitmap(*foreigndatawrappers_png_img); + return bmp_foreigndatawrappers_png; +} +#define foreigndatawrappers_png_bmp foreigndatawrappers_png_bmp() + +static wxIcon *foreigndatawrappers_png_ico() +{ + static wxIcon *ico_foreigndatawrappers_png; + if (!ico_foreigndatawrappers_png || !ico_foreigndatawrappers_png->IsOk()) + { + ico_foreigndatawrappers_png = new wxIcon(); + ico_foreigndatawrappers_png->CopyFromBitmap(*foreigndatawrappers_png_bmp); + } + return ico_foreigndatawrappers_png; +} +#define foreigndatawrappers_png_ico foreigndatawrappers_png_ico() + +#endif // FOREIGNDATAWRAPPERS_PNG_H diff --git a/include/images/foreignkey.png b/include/images/foreignkey.png new file mode 100644 index 0000000..b360550 Binary files /dev/null and b/include/images/foreignkey.png differ diff --git a/include/images/foreignkey.pngc b/include/images/foreignkey.pngc new file mode 100644 index 0000000..394ae2a --- /dev/null +++ b/include/images/foreignkey.pngc @@ -0,0 +1,82 @@ +#ifndef FOREIGNKEY_PNG_H +#define FOREIGNKEY_PNG_H + +static const unsigned char foreignkey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x0a, +0xd8, 0xd3, 0xdf, 0xbf, 0x07, 0x99, 0xdf, 0xba, +0xe5, 0xea, 0xd5, 0xcd, 0xad, 0x48, 0xf2, 0x5b, +0x1e, 0xde, 0xb9, 0x7e, 0x6b, 0x63, 0x25, 0x04, +0x6c, 0x60, 0x60, 0xe8, 0xbf, 0xfa, 0xa0, 0xf2, +0xe6, 0xb9, 0x8b, 0x37, 0x6e, 0xdd, 0xb8, 0x7e, +0xf9, 0xca, 0xe3, 0x4a, 0x90, 0xc0, 0xfd, 0xca, +0x9b, 0x67, 0x2e, 0xdc, 0x5c, 0x7d, 0x67, 0xe5, +0x95, 0x1b, 0x20, 0x15, 0x7b, 0xb6, 0xdc, 0xbf, +0x79, 0xf9, 0xea, 0x86, 0x4a, 0x10, 0x04, 0xf1, +0x81, 0x86, 0x6e, 0xbe, 0x74, 0x61, 0x63, 0x0b, +0x3e, 0x6b, 0x29, 0x07, 0x00, 0x9e, 0xeb, 0x37, +0x01, 0xa0, 0xe0, 0xd3, 0x5c, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignkey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignkey_png = new wxImage(); + if (!img_foreignkey_png || !img_foreignkey_png->IsOk()) + { + wxMemoryInputStream img_foreignkey_pngIS(foreignkey_png_data, sizeof(foreignkey_png_data)); + img_foreignkey_png->LoadFile(img_foreignkey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignkey_png; +} +#define foreignkey_png_img foreignkey_png_img() + +static wxBitmap *foreignkey_png_bmp() +{ + static wxBitmap *bmp_foreignkey_png; + if (!bmp_foreignkey_png || !bmp_foreignkey_png->IsOk()) + bmp_foreignkey_png = new wxBitmap(*foreignkey_png_img); + return bmp_foreignkey_png; +} +#define foreignkey_png_bmp foreignkey_png_bmp() + +static wxIcon *foreignkey_png_ico() +{ + static wxIcon *ico_foreignkey_png; + if (!ico_foreignkey_png || !ico_foreignkey_png->IsOk()) + { + ico_foreignkey_png = new wxIcon(); + ico_foreignkey_png->CopyFromBitmap(*foreignkey_png_bmp); + } + return ico_foreignkey_png; +} +#define foreignkey_png_ico foreignkey_png_ico() + +#endif // FOREIGNKEY_PNG_H diff --git a/include/images/foreignkeybad.png b/include/images/foreignkeybad.png new file mode 100644 index 0000000..975561b Binary files /dev/null and b/include/images/foreignkeybad.png differ diff --git a/include/images/foreignkeybad.pngc b/include/images/foreignkeybad.pngc new file mode 100644 index 0000000..e76dd1f --- /dev/null +++ b/include/images/foreignkeybad.pngc @@ -0,0 +1,122 @@ +#ifndef FOREIGNKEYBAD_PNG_H +#define FOREIGNKEYBAD_PNG_H + +static const unsigned char foreignkeybad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x02, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbc, 0xbc, 0xbc, 0x8f, +0x8f, 0x8f, 0x90, 0x90, 0x90, 0xd1, 0xd0, 0xd1, +0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0x85, 0x85, +0x85, 0xb4, 0xb4, 0xb4, 0xd1, 0xca, 0xce, 0xd7, +0x62, 0x62, 0xc5, 0x00, 0x00, 0xd0, 0x57, 0x59, +0xb4, 0x95, 0xa1, 0xc5, 0x47, 0x4b, 0xdd, 0x69, +0x69, 0xe1, 0xe1, 0xe1, 0xba, 0xb1, 0xb7, 0xca, +0x51, 0x54, 0xf6, 0x77, 0x77, 0xc3, 0x47, 0x4b, +0x9b, 0x86, 0x8f, 0xbd, 0x3d, 0x42, 0xf1, 0x57, +0x57, 0xd5, 0xd5, 0xd5, 0xe0, 0xe0, 0xe0, 0x7c, +0x74, 0x7a, 0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, +0xf5, 0x6e, 0x6e, 0xbc, 0x3b, 0x40, 0xf1, 0x56, +0x56, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0xdf, +0xdf, 0xdf, 0x7a, 0x76, 0x79, 0xf5, 0x6d, 0x6d, +0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, +0x55, 0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0xd3, +0xd2, 0xd3, 0xd0, 0xc8, 0xcc, 0xf3, 0x61, 0x61, +0xf1, 0x5b, 0x5b, 0xf0, 0x54, 0x54, 0xef, 0x4d, +0x4e, 0xee, 0x47, 0x47, 0xb3, 0xb3, 0xb3, 0xd2, +0xd2, 0xd2, 0xd0, 0xcf, 0xcf, 0xc3, 0xc2, 0xc3, +0xda, 0x65, 0x65, 0xf0, 0x53, 0x54, 0xef, 0x4d, +0x4d, 0xee, 0x46, 0x46, 0xaa, 0x2c, 0x33, 0x8e, +0x8e, 0x8e, 0xb7, 0xb0, 0xb3, 0xd6, 0x62, 0x62, +0xf0, 0x53, 0x53, 0xef, 0x4c, 0x4c, 0xee, 0x45, +0x45, 0xec, 0x3e, 0x3f, 0xeb, 0x38, 0x38, 0xbb, +0x43, 0x45, 0xf0, 0x52, 0x52, 0xef, 0x4b, 0x4b, +0xed, 0x44, 0x45, 0xeb, 0x37, 0x37, 0xea, 0x31, +0x31, 0xe9, 0x2b, 0x2b, 0xf0, 0x51, 0x51, 0xee, +0x4a, 0x4a, 0xed, 0x43, 0x44, 0x99, 0x43, 0x4a, +0xe9, 0x2a, 0x2b, 0xe8, 0x25, 0x25, 0xe7, 0x20, +0x20, 0xed, 0x42, 0x43, 0xc4, 0x46, 0x4a, 0x67, +0x83, 0x92, 0x99, 0x44, 0x4b, 0xe7, 0x1f, 0x20, +0x83, 0x6c, 0x7c, 0xef, 0x86, 0x87, 0x1f, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0xad, 0x8d, 0xe5, 0x12, 0x82, +0x50, 0x14, 0x84, 0x2f, 0x88, 0x82, 0xac, 0x89, +0xdd, 0x8a, 0xdd, 0x1d, 0xd8, 0xdd, 0x1d, 0xef, +0xff, 0x2a, 0x72, 0x45, 0xc6, 0x17, 0x70, 0x7f, +0x9c, 0x99, 0xfd, 0xce, 0xce, 0x2e, 0x21, 0x7f, +0x11, 0xc3, 0x1a, 0x38, 0xa3, 0xe9, 0xe7, 0x79, +0x81, 0x33, 0x8b, 0xb0, 0x10, 0x62, 0xb5, 0xc1, +0x4e, 0xff, 0x82, 0xc3, 0x29, 0xc1, 0x05, 0xb7, +0xc7, 0x0b, 0x1f, 0x25, 0xac, 0x3f, 0x10, 0x44, +0x28, 0x1c, 0x41, 0x14, 0xb1, 0x78, 0x02, 0x14, +0xc8, 0x49, 0x09, 0xa9, 0x74, 0x06, 0xd9, 0x5c, +0x9e, 0x26, 0x18, 0x41, 0x2e, 0x14, 0x45, 0x94, +0xca, 0x95, 0x6a, 0xed, 0xd3, 0x41, 0xf8, 0x7a, +0xa3, 0xd9, 0x6a, 0xa3, 0xd3, 0xed, 0x41, 0xf9, +0xce, 0xf6, 0x07, 0x43, 0x8c, 0xc6, 0x93, 0xe9, +0x4c, 0x4b, 0xa8, 0x9a, 0x63, 0xb1, 0x5c, 0x61, +0xbd, 0xd9, 0xea, 0x04, 0xbb, 0xfd, 0x01, 0x47, +0x9c, 0xce, 0x17, 0x68, 0x40, 0xc2, 0x15, 0xb7, +0xfb, 0x03, 0x4f, 0x3d, 0xf1, 0x52, 0x68, 0x9f, +0x7a, 0x55, 0xff, 0x06, 0x83, 0xde, 0x11, 0x90, +0x83, 0x8e, 0xca, 0x44, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, +0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, +0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xd3, 0xe6, 0xa8, 0x62, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, +0x2d, 0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, +0x37, 0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0xa2, 0xbb, 0x10, 0xde, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignkeybad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignkeybad_png = new wxImage(); + if (!img_foreignkeybad_png || !img_foreignkeybad_png->IsOk()) + { + wxMemoryInputStream img_foreignkeybad_pngIS(foreignkeybad_png_data, sizeof(foreignkeybad_png_data)); + img_foreignkeybad_png->LoadFile(img_foreignkeybad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignkeybad_png; +} +#define foreignkeybad_png_img foreignkeybad_png_img() + +static wxBitmap *foreignkeybad_png_bmp() +{ + static wxBitmap *bmp_foreignkeybad_png; + if (!bmp_foreignkeybad_png || !bmp_foreignkeybad_png->IsOk()) + bmp_foreignkeybad_png = new wxBitmap(*foreignkeybad_png_img); + return bmp_foreignkeybad_png; +} +#define foreignkeybad_png_bmp foreignkeybad_png_bmp() + +static wxIcon *foreignkeybad_png_ico() +{ + static wxIcon *ico_foreignkeybad_png; + if (!ico_foreignkeybad_png || !ico_foreignkeybad_png->IsOk()) + { + ico_foreignkeybad_png = new wxIcon(); + ico_foreignkeybad_png->CopyFromBitmap(*foreignkeybad_png_bmp); + } + return ico_foreignkeybad_png; +} +#define foreignkeybad_png_ico foreignkeybad_png_ico() + +#endif // FOREIGNKEYBAD_PNG_H diff --git a/include/images/foreignserver-sm.png b/include/images/foreignserver-sm.png new file mode 100644 index 0000000..2467ccf Binary files /dev/null and b/include/images/foreignserver-sm.png differ diff --git a/include/images/foreignserver-sm.pngc b/include/images/foreignserver-sm.pngc new file mode 100644 index 0000000..6fab220 --- /dev/null +++ b/include/images/foreignserver-sm.pngc @@ -0,0 +1,97 @@ +#ifndef FOREIGNSERVER_SM_PNG_H +#define FOREIGNSERVER_SM_PNG_H + +static const unsigned char foreignserver_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xd9, 0x86, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xf7, 0xef, 0xd4, +0xd8, 0xb3, 0x1f, 0xe3, 0xcd, 0x39, 0xed, 0xe2, +0x4f, 0xf4, 0xf2, 0x5f, 0xf4, 0xea, 0xc5, 0xda, +0xb7, 0x23, 0xec, 0xde, 0x4b, 0xf8, 0xf9, 0x67, +0xe6, 0xd0, 0x69, 0xe8, 0xd6, 0x43, 0xf8, 0xfa, +0x69, 0xe8, 0xd1, 0x80, 0xda, 0xb6, 0x32, 0xf4, +0xee, 0x5f, 0xf9, 0xfa, 0x6b, 0xda, 0xb6, 0x38, +0xf4, 0xef, 0x60, 0xfa, 0xfb, 0x6d, 0xe9, 0xd6, +0x47, 0xfb, 0xfb, 0x6f, 0xdb, 0xb8, 0x25, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x07, 0x86, 0xb5, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x8d, 0x8f, 0x49, 0x0e, 0x80, +0x20, 0x10, 0x04, 0x47, 0x14, 0x5c, 0x50, 0xdc, +0x77, 0xdc, 0x40, 0xff, 0xff, 0x45, 0x13, 0x98, +0x18, 0xb9, 0x51, 0xb7, 0xae, 0xa4, 0x33, 0x3d, +0x00, 0x7e, 0x04, 0x24, 0x0c, 0x09, 0x44, 0x5f, +0xa6, 0x2c, 0x4e, 0x92, 0x98, 0xd1, 0x14, 0x73, +0xc6, 0x73, 0x03, 0xcf, 0x6c, 0x2e, 0x44, 0x89, +0x88, 0xca, 0x88, 0xba, 0x69, 0x91, 0xa6, 0x33, +0xa2, 0xeb, 0x07, 0xa4, 0xb7, 0xa2, 0x1a, 0x27, +0x64, 0xb4, 0x15, 0x98, 0x97, 0xd5, 0xb0, 0xcc, +0x78, 0x25, 0x95, 0xdb, 0x7e, 0x1c, 0xe7, 0x29, +0x7f, 0xcb, 0xc8, 0xa5, 0xb4, 0x56, 0xce, 0xd8, +0x5b, 0x3d, 0xae, 0x00, 0x50, 0xb7, 0xdf, 0x9f, +0x2f, 0xe4, 0x0e, 0x07, 0xe3, 0xd8, 0x9f, 0xd2, +0x10, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, +0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xd3, 0xe6, +0xa8, 0x62, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, +0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, +0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xa2, +0xbb, 0x10, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignserver_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignserver_sm_png = new wxImage(); + if (!img_foreignserver_sm_png || !img_foreignserver_sm_png->IsOk()) + { + wxMemoryInputStream img_foreignserver_sm_pngIS(foreignserver_sm_png_data, sizeof(foreignserver_sm_png_data)); + img_foreignserver_sm_png->LoadFile(img_foreignserver_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignserver_sm_png; +} +#define foreignserver_sm_png_img foreignserver_sm_png_img() + +static wxBitmap *foreignserver_sm_png_bmp() +{ + static wxBitmap *bmp_foreignserver_sm_png; + if (!bmp_foreignserver_sm_png || !bmp_foreignserver_sm_png->IsOk()) + bmp_foreignserver_sm_png = new wxBitmap(*foreignserver_sm_png_img); + return bmp_foreignserver_sm_png; +} +#define foreignserver_sm_png_bmp foreignserver_sm_png_bmp() + +static wxIcon *foreignserver_sm_png_ico() +{ + static wxIcon *ico_foreignserver_sm_png; + if (!ico_foreignserver_sm_png || !ico_foreignserver_sm_png->IsOk()) + { + ico_foreignserver_sm_png = new wxIcon(); + ico_foreignserver_sm_png->CopyFromBitmap(*foreignserver_sm_png_bmp); + } + return ico_foreignserver_sm_png; +} +#define foreignserver_sm_png_ico foreignserver_sm_png_ico() + +#endif // FOREIGNSERVER_SM_PNG_H diff --git a/include/images/foreignserver.png b/include/images/foreignserver.png new file mode 100644 index 0000000..dda392a Binary files /dev/null and b/include/images/foreignserver.png differ diff --git a/include/images/foreignserver.pngc b/include/images/foreignserver.pngc new file mode 100644 index 0000000..5b94e99 --- /dev/null +++ b/include/images/foreignserver.pngc @@ -0,0 +1,109 @@ +#ifndef FOREIGNSERVER_PNG_H +#define FOREIGNSERVER_PNG_H + +static const unsigned char foreignserver_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcf, 0x50, 0x4c, 0x54, 0x45, 0xb0, 0x90, +0x9b, 0x83, 0x6c, 0x7c, 0x96, 0x81, 0x8f, 0xea, +0xdf, 0xe7, 0xe2, 0xd5, 0xde, 0xd9, 0xc9, 0xd5, +0xd0, 0xbd, 0xcb, 0xc6, 0xb1, 0xc0, 0xbf, 0xa6, +0xb9, 0x89, 0x72, 0x82, 0x99, 0x86, 0x93, 0xb8, +0xa8, 0xb3, 0xe9, 0xdf, 0xe5, 0xd8, 0xc9, 0xd4, +0xcf, 0xbd, 0xca, 0xbf, 0xa8, 0xb8, 0x9d, 0x84, +0x96, 0xdb, 0xd1, 0xd8, 0xea, 0xdf, 0xe6, 0xe2, +0xd5, 0xdd, 0xcf, 0xbe, 0xca, 0xb0, 0x97, 0xa9, +0xd0, 0xc5, 0xcb, 0xf2, 0xf1, 0xf2, 0xf9, 0xf8, +0xf9, 0xf5, 0xf1, 0xf2, 0xfa, 0xf9, 0xfa, 0xf1, +0xed, 0xef, 0xe4, 0xdb, 0xdf, 0xf0, 0xee, 0xef, +0xf6, 0xf5, 0xf6, 0xe0, 0xd3, 0xd7, 0xc4, 0xab, +0xb5, 0xb4, 0x95, 0xa1, 0xc4, 0xad, 0xb6, 0xef, +0xee, 0xee, 0xf7, 0xf5, 0xf6, 0xc4, 0xab, 0xb4, +0xb2, 0x90, 0x9e, 0xc3, 0xad, 0xb5, 0xf6, 0xf5, +0xf5, 0xe1, 0xd4, 0xd8, 0xc4, 0xae, 0xb8, 0xef, +0xee, 0xef, 0xc3, 0xaa, 0xb3, 0xb2, 0x90, 0x9d, +0xc4, 0xad, 0xb7, 0xc7, 0xc6, 0xc7, 0xe0, 0xd4, +0xd8, 0xa2, 0x8c, 0x94, 0xb5, 0x96, 0xa3, 0xa1, +0x8e, 0x96, 0xcd, 0xcc, 0xcc, 0x91, 0x75, 0x80, +0xb4, 0x96, 0xa1, 0xc3, 0xad, 0xb6, 0xac, 0xa2, +0xa7, 0xf0, 0xee, 0xf0, 0xba, 0xb0, 0xb4, 0x7b, +0x94, 0xa4, 0x4b, 0x98, 0xa8, 0x8c, 0xab, 0xb8, +0xe1, 0xd4, 0xd9, 0xa1, 0x8c, 0x94, 0x5a, 0xa2, +0xb4, 0x1f, 0xda, 0xc7, 0x52, 0xa4, 0xb3, 0x67, +0x83, 0x92, 0x5b, 0xa5, 0xb6, 0x4f, 0x2b, 0x24, +0x00, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x00, 0x88, +0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, +0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, +0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, +0x07, 0xdb, 0x03, 0x1d, 0x15, 0x06, 0x1a, 0xe0, +0x2b, 0x8c, 0xb9, 0x00, 0x00, 0x00, 0xa3, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0x8e, 0xbd, +0x0e, 0xc2, 0x30, 0x0c, 0x84, 0x1b, 0x28, 0xb4, +0x94, 0x16, 0x08, 0x7f, 0x31, 0x10, 0x68, 0xa5, +0x30, 0x20, 0x31, 0x64, 0xc9, 0x90, 0x20, 0x65, +0xb1, 0xfc, 0xfe, 0xcf, 0x44, 0xaa, 0xb8, 0x70, +0xdb, 0x7d, 0x3e, 0x9f, 0x5d, 0x14, 0x49, 0x22, +0xab, 0xf8, 0x69, 0x36, 0x2f, 0x17, 0xcb, 0xaa, +0x5e, 0x4d, 0xbe, 0x59, 0xb7, 0x65, 0xb7, 0xa9, +0xb6, 0xbb, 0x86, 0x81, 0x90, 0xfb, 0x43, 0x77, +0xac, 0xea, 0xd3, 0xb4, 0x24, 0xce, 0x0a, 0x2e, +0x70, 0xbd, 0xe9, 0x3f, 0xb8, 0x3f, 0xfa, 0xe1, +0xe3, 0x89, 0xa2, 0x64, 0x60, 0x9e, 0x3d, 0x21, +0xd9, 0x48, 0x88, 0x9c, 0x78, 0x61, 0x84, 0xa0, +0x01, 0xc0, 0x67, 0xf0, 0xa6, 0x08, 0x0e, 0x11, +0x42, 0x00, 0x4e, 0x10, 0x58, 0x44, 0xa7, 0x9c, +0x54, 0x19, 0xa0, 0x4d, 0x73, 0x09, 0xca, 0x04, +0xcd, 0xa0, 0x35, 0xa9, 0xd4, 0x69, 0x65, 0x32, +0xf0, 0xd8, 0x02, 0x20, 0xa6, 0x62, 0x15, 0x39, +0x21, 0xc7, 0xce, 0xd4, 0x2a, 0xf9, 0xac, 0x8f, +0x72, 0xf4, 0x68, 0xf9, 0x0f, 0x21, 0x88, 0x90, +0xf5, 0x05, 0xaf, 0x89, 0x19, 0x99, 0x48, 0x2d, +0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignserver_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignserver_png = new wxImage(); + if (!img_foreignserver_png || !img_foreignserver_png->IsOk()) + { + wxMemoryInputStream img_foreignserver_pngIS(foreignserver_png_data, sizeof(foreignserver_png_data)); + img_foreignserver_png->LoadFile(img_foreignserver_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignserver_png; +} +#define foreignserver_png_img foreignserver_png_img() + +static wxBitmap *foreignserver_png_bmp() +{ + static wxBitmap *bmp_foreignserver_png; + if (!bmp_foreignserver_png || !bmp_foreignserver_png->IsOk()) + bmp_foreignserver_png = new wxBitmap(*foreignserver_png_img); + return bmp_foreignserver_png; +} +#define foreignserver_png_bmp foreignserver_png_bmp() + +static wxIcon *foreignserver_png_ico() +{ + static wxIcon *ico_foreignserver_png; + if (!ico_foreignserver_png || !ico_foreignserver_png->IsOk()) + { + ico_foreignserver_png = new wxIcon(); + ico_foreignserver_png->CopyFromBitmap(*foreignserver_png_bmp); + } + return ico_foreignserver_png; +} +#define foreignserver_png_ico foreignserver_png_ico() + +#endif // FOREIGNSERVER_PNG_H diff --git a/include/images/foreignservers.png b/include/images/foreignservers.png new file mode 100644 index 0000000..c107176 Binary files /dev/null and b/include/images/foreignservers.png differ diff --git a/include/images/foreignservers.pngc b/include/images/foreignservers.pngc new file mode 100644 index 0000000..d93d791 --- /dev/null +++ b/include/images/foreignservers.pngc @@ -0,0 +1,104 @@ +#ifndef FOREIGNSERVERS_PNG_H +#define FOREIGNSERVERS_PNG_H + +static const unsigned char foreignservers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xb1, 0x50, 0x4c, 0x54, 0x45, 0x7b, 0x94, +0xa4, 0x83, 0x6c, 0x7c, 0x96, 0x81, 0x8f, 0xea, +0xdf, 0xe7, 0xe2, 0xd5, 0xde, 0xd9, 0xc9, 0xd5, +0xd0, 0xbd, 0xcb, 0xc6, 0xb1, 0xc0, 0xbf, 0xa6, +0xb9, 0x89, 0x72, 0x82, 0x99, 0x86, 0x93, 0xb8, +0xa8, 0xb3, 0xe9, 0xdf, 0xe5, 0xd8, 0xc9, 0xd4, +0xcf, 0xbd, 0xca, 0xbf, 0xa8, 0xb8, 0x9d, 0x84, +0x96, 0xdb, 0xd1, 0xd8, 0xea, 0xdf, 0xe6, 0xe2, +0xd5, 0xdd, 0xcf, 0xbe, 0xca, 0xb0, 0x97, 0xa9, +0xd0, 0xc5, 0xcb, 0xf2, 0xf1, 0xf2, 0xf9, 0xf8, +0xf9, 0xf5, 0xf1, 0xf2, 0xfa, 0xf9, 0xfa, 0xf1, +0xed, 0xef, 0xe4, 0xdb, 0xdf, 0xf0, 0xee, 0xef, +0xf6, 0xf5, 0xf6, 0xe0, 0xd3, 0xd7, 0xc4, 0xab, +0xb5, 0x5c, 0xa4, 0xb6, 0x8c, 0xab, 0xb8, 0xef, +0xee, 0xee, 0xf7, 0xf5, 0xf6, 0xc4, 0xab, 0xb4, +0x5b, 0xa0, 0xb3, 0x1f, 0xda, 0xc7, 0x63, 0xb1, +0xc1, 0x98, 0x7c, 0x95, 0x67, 0x85, 0x9b, 0x4f, +0x97, 0xad, 0xf4, 0xf1, 0xf2, 0xe1, 0xd4, 0xd8, +0xc3, 0xaa, 0xb3, 0x5b, 0xa5, 0xb6, 0xef, 0xee, +0xef, 0xe0, 0xd4, 0xd8, 0x5b, 0xa2, 0xb4, 0xf5, +0xf1, 0xf3, 0xf9, 0xf9, 0xf9, 0xe6, 0xef, 0xf1, +0xcf, 0xdb, 0xe0, 0xe1, 0xd4, 0xd9, 0xc3, 0xab, +0xb4, 0x5a, 0xa2, 0xb4, 0xf6, 0xf5, 0xf5, 0x80, +0xa4, 0x15, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, +0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, +0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, +0x4d, 0x45, 0x07, 0xdb, 0x03, 0x1d, 0x15, 0x06, +0x17, 0x9e, 0x9a, 0xf0, 0x04, 0x00, 0x00, 0x00, +0x97, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, +0x8e, 0xcb, 0x12, 0x82, 0x30, 0x0c, 0x45, 0xa9, +0xa2, 0x20, 0xe0, 0xdb, 0xda, 0xeb, 0xa3, 0xe2, +0xb4, 0x2e, 0xc2, 0x64, 0x9f, 0xff, 0xff, 0x34, +0x5b, 0x49, 0xc7, 0xbb, 0xbb, 0x67, 0x92, 0x93, +0x54, 0x55, 0x8a, 0xd1, 0x54, 0x25, 0x8b, 0x65, +0xbd, 0x5a, 0x37, 0xed, 0xa6, 0xf4, 0xae, 0x1f, +0xea, 0xed, 0xae, 0xd9, 0x1f, 0x3a, 0x05, 0xe6, +0x78, 0x3a, 0x6f, 0x2f, 0x4d, 0x6b, 0xcb, 0x8e, +0xb9, 0x3a, 0xdc, 0x70, 0x7f, 0x3c, 0xff, 0xc0, +0xbf, 0xc6, 0x77, 0x6f, 0x89, 0x82, 0x28, 0x88, +0x9f, 0x91, 0x98, 0x24, 0x10, 0xf3, 0x0f, 0x4c, +0xd3, 0xc4, 0x01, 0x5e, 0x00, 0x58, 0x75, 0x50, +0x80, 0x30, 0xc1, 0x7b, 0xa8, 0x83, 0x52, 0x67, +0x71, 0x22, 0x6e, 0x06, 0x2c, 0xb9, 0xc3, 0x45, +0x2f, 0xb3, 0x83, 0x87, 0x98, 0xa5, 0xe2, 0xa2, +0xe8, 0xc4, 0x00, 0xa4, 0x0b, 0x04, 0x47, 0x65, +0x25, 0x3b, 0x38, 0x9b, 0x66, 0x60, 0x43, 0xee, +0x49, 0xa3, 0x7f, 0x18, 0x43, 0xc4, 0x9a, 0x2f, +0x14, 0x00, 0x14, 0xa5, 0x82, 0x02, 0x8f, 0x3b, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreignservers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreignservers_png = new wxImage(); + if (!img_foreignservers_png || !img_foreignservers_png->IsOk()) + { + wxMemoryInputStream img_foreignservers_pngIS(foreignservers_png_data, sizeof(foreignservers_png_data)); + img_foreignservers_png->LoadFile(img_foreignservers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreignservers_png; +} +#define foreignservers_png_img foreignservers_png_img() + +static wxBitmap *foreignservers_png_bmp() +{ + static wxBitmap *bmp_foreignservers_png; + if (!bmp_foreignservers_png || !bmp_foreignservers_png->IsOk()) + bmp_foreignservers_png = new wxBitmap(*foreignservers_png_img); + return bmp_foreignservers_png; +} +#define foreignservers_png_bmp foreignservers_png_bmp() + +static wxIcon *foreignservers_png_ico() +{ + static wxIcon *ico_foreignservers_png; + if (!ico_foreignservers_png || !ico_foreignservers_png->IsOk()) + { + ico_foreignservers_png = new wxIcon(); + ico_foreignservers_png->CopyFromBitmap(*foreignservers_png_bmp); + } + return ico_foreignservers_png; +} +#define foreignservers_png_ico foreignservers_png_ico() + +#endif // FOREIGNSERVERS_PNG_H diff --git a/include/images/foreigntable.png b/include/images/foreigntable.png new file mode 100644 index 0000000..53c1338 Binary files /dev/null and b/include/images/foreigntable.png differ diff --git a/include/images/foreigntable.pngc b/include/images/foreigntable.pngc new file mode 100644 index 0000000..f1b3024 --- /dev/null +++ b/include/images/foreigntable.pngc @@ -0,0 +1,115 @@ +#ifndef FOREIGNTABLE_PNG_H +#define FOREIGNTABLE_PNG_H + +static const unsigned char foreigntable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xd5, 0x50, 0x4c, 0x54, 0x45, 0xe4, 0xe4, +0xe4, 0x21, 0x95, 0xe7, 0x8d, 0xd0, 0xff, 0x92, +0xcf, 0xfb, 0xa2, 0xd3, 0xf5, 0xba, 0xd8, 0xed, +0xd1, 0xdf, 0xe9, 0xdf, 0xe3, 0xe7, 0xe5, 0xe6, +0xe7, 0xe6, 0xe6, 0xe6, 0xda, 0xe1, 0xe5, 0xac, +0xce, 0xe7, 0x63, 0xb1, 0xe8, 0x2e, 0x9b, 0xe8, +0x8b, 0xcf, 0xff, 0x85, 0xcc, 0xfe, 0x7e, 0xc8, +0xfc, 0x75, 0xc3, 0xfa, 0x6c, 0xbe, 0xf8, 0x61, +0xb8, 0xf6, 0x56, 0xb2, 0xf3, 0x4b, 0xac, 0xf0, +0x40, 0xa7, 0xee, 0x37, 0xa0, 0xec, 0x2d, 0x9c, +0xea, 0x26, 0x98, 0xe9, 0x85, 0xcc, 0xfd, 0x6b, +0xbe, 0xf8, 0x41, 0xa6, 0xee, 0x36, 0xa1, 0xec, +0x2e, 0x9c, 0xea, 0xb4, 0xd6, 0xee, 0xdd, 0xdd, +0xdd, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xe0, +0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe2, 0xe2, 0xe2, +0xe3, 0xe3, 0xe3, 0xe5, 0xe5, 0xe5, 0x87, 0xbf, +0xe7, 0xe8, 0xe8, 0xe8, 0xe9, 0xe9, 0xe9, 0xe7, +0xe7, 0xe7, 0xa9, 0xa9, 0xa9, 0xac, 0xac, 0xac, +0xec, 0xec, 0xec, 0xed, 0xed, 0xed, 0xef, 0xef, +0xef, 0xea, 0xea, 0xea, 0xa7, 0xa7, 0xa7, 0xa8, +0xa8, 0xa8, 0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, +0xeb, 0xeb, 0xeb, 0xf0, 0xf0, 0xf0, 0xf2, 0xf2, +0xf2, 0xee, 0xee, 0xee, 0xab, 0xab, 0xab, 0xb0, +0xb0, 0xb0, 0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, +0xf1, 0xf1, 0xf1, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, +0xf5, 0xb5, 0xb5, 0xb5, 0xf6, 0xf6, 0xf6, 0xf8, +0xf8, 0xf8, 0xb6, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, +0xf7, 0xf7, 0xf7, 0x54, 0xa5, 0x3f, 0x3d, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, +0x48, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, +0x03, 0x1c, 0x15, 0x28, 0x24, 0x92, 0xf1, 0xff, +0x5b, 0x00, 0x00, 0x00, 0xca, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x55, 0xcf, 0xdd, 0x6e, 0x82, +0x40, 0x10, 0x05, 0xe0, 0x9d, 0xc2, 0x42, 0x57, +0x66, 0x2d, 0xd4, 0xe2, 0x4f, 0x4b, 0x8b, 0x54, +0x6d, 0xb7, 0x40, 0x44, 0x31, 0x71, 0x13, 0x6d, +0xb2, 0x31, 0xf3, 0xfe, 0xef, 0xe4, 0x2c, 0xb5, +0x17, 0xce, 0xdd, 0x7c, 0x39, 0x99, 0xcc, 0x11, +0x02, 0xee, 0x46, 0x08, 0x01, 0x0f, 0x41, 0x28, +0xa3, 0xf8, 0x51, 0xa9, 0x51, 0x82, 0xda, 0xc3, +0xf8, 0x29, 0xcd, 0x9e, 0x27, 0x2f, 0xf9, 0x74, +0x36, 0x5f, 0x0c, 0x89, 0xf1, 0x6b, 0x9a, 0xbd, +0x31, 0x14, 0xef, 0x1f, 0x7f, 0x50, 0x2e, 0x97, +0xd5, 0xe7, 0x6a, 0xbd, 0xf9, 0xfa, 0x56, 0x66, +0x80, 0xdb, 0x7e, 0xe9, 0x11, 0x8d, 0x1c, 0x40, +0x35, 0x3f, 0xed, 0x06, 0x35, 0x26, 0x06, 0x35, +0x5f, 0x85, 0xaa, 0x3f, 0xb4, 0xad, 0x36, 0x64, +0x23, 0x22, 0xea, 0x19, 0x7c, 0x1e, 0x0d, 0x85, +0x30, 0x23, 0x6b, 0x89, 0x61, 0x55, 0xd7, 0x7b, +0xa4, 0x00, 0x20, 0x74, 0xa5, 0x74, 0x0c, 0xeb, +0xf6, 0xa4, 0x93, 0x72, 0x01, 0x92, 0x5c, 0x67, +0x23, 0x06, 0xd5, 0xd4, 0x10, 0x77, 0x39, 0x4c, +0xca, 0xc8, 0x75, 0x1e, 0x9a, 0x9d, 0x85, 0x98, +0xa8, 0x00, 0xc8, 0xc8, 0xa5, 0x0c, 0xf5, 0xf9, +0x97, 0xe3, 0x21, 0x37, 0x2b, 0x48, 0xf2, 0x67, +0x70, 0xdc, 0x76, 0xbd, 0x91, 0x43, 0xd7, 0x40, +0x7b, 0xf0, 0x83, 0xf9, 0x7f, 0xff, 0x2b, 0x4a, +0x72, 0x14, 0xd3, 0xbe, 0x1e, 0x53, 0xe5, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigntable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigntable_png = new wxImage(); + if (!img_foreigntable_png || !img_foreigntable_png->IsOk()) + { + wxMemoryInputStream img_foreigntable_pngIS(foreigntable_png_data, sizeof(foreigntable_png_data)); + img_foreigntable_png->LoadFile(img_foreigntable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigntable_png; +} +#define foreigntable_png_img foreigntable_png_img() + +static wxBitmap *foreigntable_png_bmp() +{ + static wxBitmap *bmp_foreigntable_png; + if (!bmp_foreigntable_png || !bmp_foreigntable_png->IsOk()) + bmp_foreigntable_png = new wxBitmap(*foreigntable_png_img); + return bmp_foreigntable_png; +} +#define foreigntable_png_bmp foreigntable_png_bmp() + +static wxIcon *foreigntable_png_ico() +{ + static wxIcon *ico_foreigntable_png; + if (!ico_foreigntable_png || !ico_foreigntable_png->IsOk()) + { + ico_foreigntable_png = new wxIcon(); + ico_foreigntable_png->CopyFromBitmap(*foreigntable_png_bmp); + } + return ico_foreigntable_png; +} +#define foreigntable_png_ico foreigntable_png_ico() + +#endif // FOREIGNTABLE_PNG_H diff --git a/include/images/foreigntables.png b/include/images/foreigntables.png new file mode 100644 index 0000000..dc1f742 Binary files /dev/null and b/include/images/foreigntables.png differ diff --git a/include/images/foreigntables.pngc b/include/images/foreigntables.pngc new file mode 100644 index 0000000..932fd34 --- /dev/null +++ b/include/images/foreigntables.pngc @@ -0,0 +1,106 @@ +#ifndef FOREIGNTABLES_PNG_H +#define FOREIGNTABLES_PNG_H + +static const unsigned char foreigntables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xba, 0x50, 0x4c, 0x54, 0x45, 0x63, 0xb9, +0xf6, 0x21, 0x95, 0xe7, 0x8a, 0xce, 0xfe, 0x94, +0xcf, 0xf9, 0xad, 0xd5, 0xf2, 0xca, 0xdc, 0xea, +0xde, 0xe3, 0xe7, 0xe6, 0xe7, 0xe7, 0xe6, 0xe6, +0xe6, 0xc5, 0xd8, 0xe6, 0x76, 0xb9, 0xe8, 0x30, +0x9c, 0xe8, 0x88, 0xcd, 0xfe, 0x52, 0xb0, 0xf2, +0xb3, 0xd5, 0xed, 0xdd, 0xdd, 0xdd, 0x83, 0xcb, +0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, 0xf9, 0x56, +0xb2, 0xf3, 0x49, 0xab, 0xf0, 0x3d, 0xa5, 0xed, +0x31, 0x9e, 0xeb, 0x27, 0x99, 0xe9, 0xde, 0xde, +0xde, 0x83, 0xcb, 0xfd, 0x4a, 0xab, 0xf0, 0x3d, +0xa4, 0xed, 0x28, 0x99, 0xe9, 0xdf, 0xdf, 0xdf, +0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, +0xe5, 0x87, 0xc0, 0xe7, 0xe0, 0xe0, 0xe0, 0xa7, +0xa7, 0xa7, 0xac, 0xac, 0xac, 0xec, 0xec, 0xec, +0xee, 0xee, 0xee, 0xe9, 0xe9, 0xe9, 0xe1, 0xe1, +0xe1, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xad, +0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, +0x90, 0xca, 0xf3, 0xe7, 0xe7, 0xe7, 0xeb, 0xeb, +0xeb, 0xe8, 0xe8, 0xe8, 0xa9, 0xa9, 0xa9, 0xef, +0xef, 0xef, 0xf1, 0xf1, 0xf1, 0xed, 0xed, 0xed, +0xaa, 0xaa, 0xaa, 0xb0, 0xb0, 0xb0, 0xb2, 0xb2, +0xb2, 0xe4, 0xe4, 0xe4, 0xf0, 0xf0, 0xf0, 0x7b, +0xc6, 0xfb, 0x6f, 0xc0, 0xf8, 0x28, 0x99, 0xe8, +0x89, 0x9f, 0xc5, 0x23, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, +0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, +0x49, 0x4d, 0x45, 0x07, 0xdb, 0x03, 0x1c, 0x15, +0x28, 0x26, 0x7c, 0xff, 0x9e, 0x77, 0x00, 0x00, +0x00, 0x9e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x5d, 0xcf, 0xbd, 0x0e, 0xc2, 0x30, 0x0c, 0x46, +0xd1, 0x7c, 0x34, 0x81, 0xd6, 0x2e, 0xe1, 0x57, +0x08, 0x0a, 0x0c, 0x61, 0x6a, 0x96, 0x4c, 0xae, +0x84, 0xc2, 0xfb, 0xbf, 0x17, 0x4e, 0x0b, 0x42, +0xd4, 0xe3, 0xcd, 0x91, 0xe5, 0x18, 0xfc, 0xc6, +0x8c, 0x83, 0x45, 0x65, 0xdd, 0x72, 0x55, 0xd7, +0x0d, 0xf1, 0x14, 0xda, 0xf5, 0xbf, 0x41, 0x3b, +0x33, 0xf0, 0x33, 0x83, 0xcd, 0xc7, 0x3c, 0x23, +0x11, 0x35, 0x5c, 0x82, 0x9a, 0xed, 0x8e, 0x98, +0x42, 0x20, 0xd6, 0x70, 0x2e, 0xe6, 0xc2, 0x24, +0xd9, 0x89, 0x48, 0x34, 0xb8, 0x17, 0xc3, 0x41, +0x2c, 0x4e, 0x92, 0xb3, 0x18, 0x3c, 0x8a, 0x21, +0xa9, 0x00, 0x2b, 0xd6, 0x69, 0xe8, 0xd5, 0xb0, +0xb7, 0x37, 0x78, 0x91, 0x21, 0x3b, 0x93, 0x92, +0x1a, 0x2c, 0x87, 0x0e, 0x07, 0x7d, 0x1f, 0x5c, +0xb9, 0xa4, 0xd7, 0x20, 0x72, 0x04, 0xf6, 0x22, +0x2f, 0x0d, 0x6a, 0xd0, 0xe8, 0x4e, 0xe0, 0x2a, +0x6e, 0xfa, 0x21, 0x62, 0xf0, 0xe3, 0x9d, 0x89, +0xa7, 0x90, 0xda, 0xd8, 0x7d, 0x6f, 0x7f, 0x03, +0x79, 0xd2, 0x0d, 0x0a, 0xf0, 0x40, 0xe0, 0x16, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *foreigntables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_foreigntables_png = new wxImage(); + if (!img_foreigntables_png || !img_foreigntables_png->IsOk()) + { + wxMemoryInputStream img_foreigntables_pngIS(foreigntables_png_data, sizeof(foreigntables_png_data)); + img_foreigntables_png->LoadFile(img_foreigntables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_foreigntables_png; +} +#define foreigntables_png_img foreigntables_png_img() + +static wxBitmap *foreigntables_png_bmp() +{ + static wxBitmap *bmp_foreigntables_png; + if (!bmp_foreigntables_png || !bmp_foreigntables_png->IsOk()) + bmp_foreigntables_png = new wxBitmap(*foreigntables_png_img); + return bmp_foreigntables_png; +} +#define foreigntables_png_bmp foreigntables_png_bmp() + +static wxIcon *foreigntables_png_ico() +{ + static wxIcon *ico_foreigntables_png; + if (!ico_foreigntables_png || !ico_foreigntables_png->IsOk()) + { + ico_foreigntables_png = new wxIcon(); + ico_foreigntables_png->CopyFromBitmap(*foreigntables_png_bmp); + } + return ico_foreigntables_png; +} +#define foreigntables_png_ico foreigntables_png_ico() + +#endif // FOREIGNTABLES_PNG_H diff --git a/include/images/forward.png b/include/images/forward.png new file mode 100644 index 0000000..3b22d70 Binary files /dev/null and b/include/images/forward.png differ diff --git a/include/images/forward.pngc b/include/images/forward.pngc new file mode 100644 index 0000000..34760f6 --- /dev/null +++ b/include/images/forward.pngc @@ -0,0 +1,88 @@ +#ifndef FORWARD_PNG_H +#define FORWARD_PNG_H + +static const unsigned char forward_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, +0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, +0xcb, 0x00, 0x00, 0x00, 0x1e, 0x50, 0x4c, 0x54, +0x45, 0xd6, 0xd3, 0xce, 0x00, 0xff, 0x00, 0x00, +0x82, 0x84, 0x42, 0x9a, 0xa5, 0x00, 0x82, 0x00, +0x31, 0xff, 0x9c, 0xce, 0xcf, 0xff, 0x00, 0x34, +0x39, 0x84, 0x82, 0x84, 0x31, 0x30, 0x63, 0x1b, +0x45, 0xdb, 0xbc, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x86, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xc0, 0x0b, 0x84, 0x0c, +0x90, 0x38, 0x82, 0xce, 0x48, 0x9c, 0xd0, 0x14, +0x24, 0xa9, 0xb0, 0x30, 0x24, 0xa9, 0xd0, 0x54, +0x24, 0xa9, 0x30, 0x84, 0x94, 0xa0, 0xa0, 0x68, +0x6a, 0x6a, 0x8a, 0x03, 0x54, 0x51, 0x28, 0x50, +0x26, 0x4c, 0x05, 0xc6, 0x49, 0x05, 0x82, 0x24, +0x07, 0x28, 0x27, 0x10, 0x21, 0x15, 0x1a, 0x2a, +0x28, 0x2a, 0x2a, 0x28, 0xe8, 0x04, 0x31, 0xcb, +0x18, 0x04, 0xcc, 0x8b, 0x20, 0x32, 0xce, 0xce, +0x2e, 0x2e, 0x2e, 0xe5, 0x0a, 0x60, 0x8e, 0x98, +0x89, 0x89, 0x8b, 0x8b, 0x7b, 0x11, 0xcc, 0x99, +0xce, 0x70, 0x09, 0x06, 0xf7, 0xf2, 0x62, 0xa0, +0x44, 0x47, 0x47, 0x47, 0x03, 0x98, 0xeb, 0xec, +0x52, 0xa9, 0x01, 0xe4, 0x80, 0x98, 0x1c, 0x1d, +0xce, 0xee, 0x93, 0x60, 0xe2, 0x0c, 0x1d, 0x20, +0x09, 0x98, 0xa3, 0x39, 0xda, 0x27, 0x31, 0x10, +0x00, 0x00, 0xb9, 0x91, 0x24, 0x76, 0xe1, 0x57, +0x5f, 0x47, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *forward_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_forward_png = new wxImage(); + if (!img_forward_png || !img_forward_png->IsOk()) + { + wxMemoryInputStream img_forward_pngIS(forward_png_data, sizeof(forward_png_data)); + img_forward_png->LoadFile(img_forward_pngIS, wxBITMAP_TYPE_PNG); + } + return img_forward_png; +} +#define forward_png_img forward_png_img() + +static wxBitmap *forward_png_bmp() +{ + static wxBitmap *bmp_forward_png; + if (!bmp_forward_png || !bmp_forward_png->IsOk()) + bmp_forward_png = new wxBitmap(*forward_png_img); + return bmp_forward_png; +} +#define forward_png_bmp forward_png_bmp() + +static wxIcon *forward_png_ico() +{ + static wxIcon *ico_forward_png; + if (!ico_forward_png || !ico_forward_png->IsOk()) + { + ico_forward_png = new wxIcon(); + ico_forward_png->CopyFromBitmap(*forward_png_bmp); + } + return ico_forward_png; +} +#define forward_png_ico forward_png_ico() + +#endif // FORWARD_PNG_H diff --git a/include/images/function.png b/include/images/function.png new file mode 100644 index 0000000..656854a Binary files /dev/null and b/include/images/function.png differ diff --git a/include/images/function.pngc b/include/images/function.pngc new file mode 100644 index 0000000..120dcab --- /dev/null +++ b/include/images/function.pngc @@ -0,0 +1,85 @@ +#ifndef FUNCTION_PNG_H +#define FUNCTION_PNG_H + +static const unsigned char function_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0xac, 0xe2, 0x4a, +0x72, 0xcd, 0xa5, 0xd4, 0xfc, 0xe1, 0xf1, 0xff, +0xfd, 0xff, 0xfe, 0xde, 0xf3, 0xf9, 0xb4, 0xdc, +0xf3, 0x9a, 0xc3, 0xed, 0x7d, 0xa4, 0xe7, 0x67, +0x8c, 0xe1, 0x64, 0x88, 0xe0, 0x76, 0x9b, 0xe4, +0x8f, 0xb8, 0xe9, 0x64, 0xbc, 0xe8, 0xb6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x52, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x40, 0x02, 0x42, +0x8a, 0x10, 0x9a, 0x51, 0xd9, 0x48, 0x00, 0xcc, +0x60, 0x72, 0x71, 0x81, 0x08, 0x31, 0xaa, 0x86, +0x06, 0x01, 0x85, 0x18, 0x95, 0x94, 0x94, 0xd2, +0xd2, 0x80, 0x42, 0x4c, 0xe5, 0x20, 0x50, 0x24, +0xc0, 0xc0, 0xd4, 0x01, 0x06, 0x0a, 0x0c, 0x4c, +0x33, 0x41, 0x60, 0x92, 0x00, 0x58, 0xcd, 0xaa, +0x55, 0x60, 0x6d, 0x8c, 0xda, 0xbb, 0x37, 0x81, +0x0d, 0x62, 0x3a, 0x73, 0x06, 0x6a, 0x8e, 0xee, +0x25, 0x01, 0x54, 0xbb, 0xd0, 0x00, 0x00, 0x78, +0xa5, 0x13, 0xc3, 0xc7, 0x68, 0x28, 0x82, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *function_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_function_png = new wxImage(); + if (!img_function_png || !img_function_png->IsOk()) + { + wxMemoryInputStream img_function_pngIS(function_png_data, sizeof(function_png_data)); + img_function_png->LoadFile(img_function_pngIS, wxBITMAP_TYPE_PNG); + } + return img_function_png; +} +#define function_png_img function_png_img() + +static wxBitmap *function_png_bmp() +{ + static wxBitmap *bmp_function_png; + if (!bmp_function_png || !bmp_function_png->IsOk()) + bmp_function_png = new wxBitmap(*function_png_img); + return bmp_function_png; +} +#define function_png_bmp function_png_bmp() + +static wxIcon *function_png_ico() +{ + static wxIcon *ico_function_png; + if (!ico_function_png || !ico_function_png->IsOk()) + { + ico_function_png = new wxIcon(); + ico_function_png->CopyFromBitmap(*function_png_bmp); + } + return ico_function_png; +} +#define function_png_ico function_png_ico() + +#endif // FUNCTION_PNG_H diff --git a/include/images/functions.png b/include/images/functions.png new file mode 100644 index 0000000..c44874e Binary files /dev/null and b/include/images/functions.png differ diff --git a/include/images/functions.pngc b/include/images/functions.pngc new file mode 100644 index 0000000..c9b22a2 --- /dev/null +++ b/include/images/functions.pngc @@ -0,0 +1,88 @@ +#ifndef FUNCTIONS_PNG_H +#define FUNCTIONS_PNG_H + +static const unsigned char functions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x33, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0xac, 0xe2, 0x4a, +0x72, 0xcd, 0xa5, 0xd4, 0xfc, 0x8e, 0xa9, 0xe2, +0x69, 0x8a, 0xd5, 0xc1, 0xe5, 0xf5, 0x7b, 0xa1, +0xdd, 0x57, 0x7c, 0xd1, 0x9d, 0xc7, 0xee, 0x6c, +0x95, 0xdb, 0x7a, 0xa1, 0xe6, 0xef, 0xf7, 0xff, +0xf3, 0xfb, 0xfc, 0x64, 0x87, 0xe0, 0x6c, 0x91, +0xe2, 0x8a, 0xb2, 0xe8, 0xd0, 0x3f, 0x31, 0x0e, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x61, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x8f, 0x47, 0x0e, +0xc0, 0x30, 0x08, 0x04, 0xf1, 0x3a, 0xdd, 0xf5, +0xff, 0xaf, 0x8d, 0x29, 0x41, 0x76, 0xe6, 0xc6, +0x6a, 0x04, 0x0b, 0x11, 0x51, 0x00, 0x10, 0x68, +0x02, 0x31, 0xc6, 0x25, 0x09, 0xd8, 0x86, 0xb3, +0xfb, 0xc4, 0xb0, 0x63, 0x09, 0x8e, 0xc1, 0x29, +0xce, 0xa5, 0xc1, 0xfd, 0xac, 0x0e, 0x92, 0x39, +0x39, 0x67, 0x49, 0xc6, 0x0e, 0x73, 0x4a, 0x29, +0x7a, 0xcb, 0x1c, 0x41, 0x12, 0x76, 0x1c, 0xe8, +0xe5, 0xf4, 0x61, 0xfd, 0xb4, 0x4b, 0xad, 0xd5, +0xfb, 0x72, 0xd2, 0x5a, 0x9b, 0xfb, 0xa3, 0xf7, +0xfe, 0xfb, 0xe7, 0xf7, 0xb1, 0xf3, 0x02, 0x84, +0x99, 0x03, 0x0d, 0xf0, 0xed, 0x6f, 0x7b, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, +0x30, 0x31, 0x2d, 0x32, 0x35, 0x54, 0x31, 0x35, +0x3a, 0x30, 0x37, 0x3a, 0x30, 0x35, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0x01, 0x79, 0xcf, 0xe1, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *functions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_functions_png = new wxImage(); + if (!img_functions_png || !img_functions_png->IsOk()) + { + wxMemoryInputStream img_functions_pngIS(functions_png_data, sizeof(functions_png_data)); + img_functions_png->LoadFile(img_functions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_functions_png; +} +#define functions_png_img functions_png_img() + +static wxBitmap *functions_png_bmp() +{ + static wxBitmap *bmp_functions_png; + if (!bmp_functions_png || !bmp_functions_png->IsOk()) + bmp_functions_png = new wxBitmap(*functions_png_img); + return bmp_functions_png; +} +#define functions_png_bmp functions_png_bmp() + +static wxIcon *functions_png_ico() +{ + static wxIcon *ico_functions_png; + if (!ico_functions_png || !ico_functions_png->IsOk()) + { + ico_functions_png = new wxIcon(); + ico_functions_png->CopyFromBitmap(*functions_png_bmp); + } + return ico_functions_png; +} +#define functions_png_ico functions_png_ico() + +#endif // FUNCTIONS_PNG_H diff --git a/include/images/gqbAdd.png b/include/images/gqbAdd.png new file mode 100644 index 0000000..620e7d8 Binary files /dev/null and b/include/images/gqbAdd.png differ diff --git a/include/images/gqbAdd.pngc b/include/images/gqbAdd.pngc new file mode 100644 index 0000000..fe68c38 --- /dev/null +++ b/include/images/gqbAdd.pngc @@ -0,0 +1,73 @@ +#ifndef GQBADD_PNG_H +#define GQBADD_PNG_H + +static const unsigned char gqbAdd_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x01, 0x03, 0x00, 0x00, 0x00, 0x3c, 0x8a, 0x66, +0x6f, 0x00, 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x4a, 0x5c, 0xe3, 0xf7, +0x67, 0x10, 0x43, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x15, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0x80, 0x81, 0x0f, 0xa8, 0x98, 0xff, 0x3f, +0x02, 0xa3, 0xcb, 0x41, 0x01, 0x00, 0x40, 0x64, +0x0a, 0xab, 0x7a, 0x5a, 0x99, 0x4d, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbAdd_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbAdd_png = new wxImage(); + if (!img_gqbAdd_png || !img_gqbAdd_png->IsOk()) + { + wxMemoryInputStream img_gqbAdd_pngIS(gqbAdd_png_data, sizeof(gqbAdd_png_data)); + img_gqbAdd_png->LoadFile(img_gqbAdd_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbAdd_png; +} +#define gqbAdd_png_img gqbAdd_png_img() + +static wxBitmap *gqbAdd_png_bmp() +{ + static wxBitmap *bmp_gqbAdd_png; + if (!bmp_gqbAdd_png || !bmp_gqbAdd_png->IsOk()) + bmp_gqbAdd_png = new wxBitmap(*gqbAdd_png_img); + return bmp_gqbAdd_png; +} +#define gqbAdd_png_bmp gqbAdd_png_bmp() + +static wxIcon *gqbAdd_png_ico() +{ + static wxIcon *ico_gqbAdd_png; + if (!ico_gqbAdd_png || !ico_gqbAdd_png->IsOk()) + { + ico_gqbAdd_png = new wxIcon(); + ico_gqbAdd_png->CopyFromBitmap(*gqbAdd_png_bmp); + } + return ico_gqbAdd_png; +} +#define gqbAdd_png_ico gqbAdd_png_ico() + +#endif // GQBADD_PNG_H diff --git a/include/images/gqbAddRest.png b/include/images/gqbAddRest.png new file mode 100644 index 0000000..55f4702 Binary files /dev/null and b/include/images/gqbAddRest.png differ diff --git a/include/images/gqbAddRest.pngc b/include/images/gqbAddRest.pngc new file mode 100644 index 0000000..4dd225c --- /dev/null +++ b/include/images/gqbAddRest.pngc @@ -0,0 +1,111 @@ +#ifndef GQBADDREST_PNG_H +#define GQBADDREST_PNG_H + +static const unsigned char gqbAddRest_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x08, 0x03, 0x00, 0x00, 0x00, 0x31, 0x9a, 0x04, +0x1e, 0x00, 0x00, 0x00, 0xa8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0x97, 0xb5, 0x78, +0x7a, 0xb4, 0x70, 0x73, 0xb4, 0xb9, 0xba, 0xd9, +0x81, 0x83, 0xbd, 0xf0, 0xf1, 0xf3, 0xf0, 0xe6, +0xff, 0xe5, 0xd8, 0xfb, 0xdd, 0xd3, 0xf4, 0xd9, +0xcd, 0xf2, 0xd3, 0xc9, 0xec, 0xd0, 0xc2, 0xec, +0xc9, 0xbc, 0xe7, 0xc5, 0xbc, 0xe1, 0xea, 0xe7, +0xf3, 0x70, 0x88, 0xb4, 0xd5, 0xbd, 0xfa, 0xcd, +0xb1, 0xf9, 0xc6, 0xaf, 0xee, 0xc3, 0xa7, 0xf2, +0xb7, 0x9c, 0xe8, 0xad, 0x92, 0xe1, 0xa6, 0x8b, +0xdb, 0x9e, 0x83, 0xd5, 0x96, 0x7c, 0xce, 0x90, +0x75, 0xc9, 0x99, 0x83, 0xcc, 0x88, 0x8a, 0xa8, +0x5a, 0x7a, 0xaa, 0xbb, 0xa7, 0xe3, 0xa7, 0xa8, +0xa9, 0x6f, 0x6f, 0x6f, 0xa4, 0xa6, 0xa9, 0xab, +0x97, 0xd8, 0x8e, 0x73, 0xc8, 0x5f, 0xe6, 0xdb, +0x5b, 0xe2, 0xd7, 0x85, 0x6b, 0xc2, 0x57, 0xde, +0xd3, 0xc3, 0xb5, 0xe1, 0x53, 0xda, 0xcf, 0x9d, +0xa2, 0xa7, 0x7d, 0x63, 0xbc, 0x4e, 0xd5, 0xca, +0x49, 0xd0, 0xc5, 0x45, 0xcc, 0xc1, 0x40, 0xc7, +0xbc, 0xbb, 0xad, 0xdb, 0x6f, 0x55, 0xb0, 0x3c, +0xc3, 0xb8, 0xb6, 0xa8, 0xd7, 0x9a, 0xa0, 0xa6, +0xaf, 0xa2, 0xd2, 0xe4, 0xe4, 0xe4, 0xab, 0xad, +0xd3, 0x1c, 0xaf, 0x55, 0x68, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xa4, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x55, 0x8f, 0xdb, 0x16, 0x81, 0x50, 0x10, +0x40, 0x27, 0xc7, 0xa1, 0x9b, 0x2e, 0x12, 0x42, +0x4c, 0xa5, 0x52, 0x14, 0x21, 0xfd, 0xff, 0x9f, +0x99, 0xa8, 0x13, 0xfb, 0x61, 0x1e, 0xf6, 0x9a, +0x3d, 0x6b, 0x0d, 0x48, 0x23, 0xf6, 0xcf, 0x18, +0x80, 0x4f, 0xa6, 0x32, 0xa1, 0xa8, 0xaa, 0xa6, +0xeb, 0x33, 0x43, 0x33, 0x39, 0x80, 0xc5, 0x65, +0x7b, 0xee, 0x2c, 0x5c, 0x77, 0xb9, 0x5a, 0x7b, +0x9b, 0xad, 0xc1, 0x69, 0x0f, 0x76, 0x5c, 0xb1, +0x7f, 0x94, 0x0f, 0x2d, 0x12, 0x57, 0x1c, 0xa1, +0x2c, 0x80, 0x4e, 0xaa, 0xfb, 0x8f, 0x3a, 0x20, +0x06, 0x9d, 0x03, 0x9f, 0x6b, 0xa1, 0x17, 0x79, +0x06, 0x1e, 0x63, 0xec, 0x1d, 0xdd, 0xdc, 0x47, +0x49, 0xc8, 0x31, 0x4e, 0x07, 0x07, 0xec, 0x94, +0x50, 0x88, 0x69, 0x46, 0x23, 0x17, 0xee, 0x4c, +0x61, 0x9a, 0x5d, 0x8a, 0xf2, 0xda, 0xaf, 0xb2, +0x5b, 0x85, 0x9d, 0xba, 0x0b, 0xf7, 0xa8, 0x02, +0xca, 0x8a, 0x92, 0xc6, 0xb3, 0x77, 0x66, 0x5d, +0xbf, 0x18, 0x0e, 0x21, 0xd1, 0xb4, 0xdf, 0x37, +0x38, 0x84, 0x82, 0xfc, 0x1b, 0xbe, 0x01, 0x8c, +0x25, 0x12, 0x58, 0x74, 0xb2, 0x44, 0xef, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbAddRest_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbAddRest_png = new wxImage(); + if (!img_gqbAddRest_png || !img_gqbAddRest_png->IsOk()) + { + wxMemoryInputStream img_gqbAddRest_pngIS(gqbAddRest_png_data, sizeof(gqbAddRest_png_data)); + img_gqbAddRest_png->LoadFile(img_gqbAddRest_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbAddRest_png; +} +#define gqbAddRest_png_img gqbAddRest_png_img() + +static wxBitmap *gqbAddRest_png_bmp() +{ + static wxBitmap *bmp_gqbAddRest_png; + if (!bmp_gqbAddRest_png || !bmp_gqbAddRest_png->IsOk()) + bmp_gqbAddRest_png = new wxBitmap(*gqbAddRest_png_img); + return bmp_gqbAddRest_png; +} +#define gqbAddRest_png_bmp gqbAddRest_png_bmp() + +static wxIcon *gqbAddRest_png_ico() +{ + static wxIcon *ico_gqbAddRest_png; + if (!ico_gqbAddRest_png || !ico_gqbAddRest_png->IsOk()) + { + ico_gqbAddRest_png = new wxIcon(); + ico_gqbAddRest_png->CopyFromBitmap(*gqbAddRest_png_bmp); + } + return ico_gqbAddRest_png; +} +#define gqbAddRest_png_ico gqbAddRest_png_ico() + +#endif // GQBADDREST_PNG_H diff --git a/include/images/gqbColNotSel.png b/include/images/gqbColNotSel.png new file mode 100644 index 0000000..5b1abee Binary files /dev/null and b/include/images/gqbColNotSel.png differ diff --git a/include/images/gqbColNotSel.pngc b/include/images/gqbColNotSel.pngc new file mode 100644 index 0000000..58cf3e8 --- /dev/null +++ b/include/images/gqbColNotSel.pngc @@ -0,0 +1,90 @@ +#ifndef GQBCOLNOTSEL_PNG_H +#define GQBCOLNOTSEL_PNG_H + +static const unsigned char gqbColNotSel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xfd, 0xfe, 0xfe, 0xfb, 0xfe, 0xfe, +0xf9, 0xfc, 0xfe, 0xf7, 0xfb, 0xfe, 0xf4, 0xfa, +0xfd, 0xf2, 0xfa, 0xfc, 0xfc, 0xfe, 0xfe, 0xfa, +0xfd, 0xfe, 0xf7, 0xfb, 0xfd, 0xf5, 0xfb, 0xfd, +0xf3, 0xfa, 0xfc, 0xf0, 0xf9, 0xfc, 0xf8, 0xfc, +0xfe, 0xf6, 0xfb, 0xfd, 0xf3, 0xfa, 0xfd, 0xf2, +0xf9, 0xfd, 0xef, 0xf8, 0xfc, 0xf9, 0xfd, 0xfe, +0xf7, 0xfc, 0xfd, 0xf4, 0xfb, 0xfd, 0xed, 0xf7, +0xfb, 0xee, 0xf8, 0xfc, 0xec, 0xf7, 0xfb, 0xf6, +0xfc, 0xfd, 0xf2, 0xf9, 0xfc, 0xed, 0xf8, 0xfb, +0xea, 0xf7, 0xfb, 0x1c, 0x1f, 0x0e, 0x04, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x47, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x02, 0x60, +0x64, 0x02, 0x03, 0x46, 0xb8, 0x00, 0x13, 0x33, +0x0b, 0x2b, 0x1b, 0x3b, 0x07, 0x13, 0x42, 0x80, +0x93, 0x8b, 0x9b, 0x87, 0x97, 0x0f, 0x49, 0x80, +0x8b, 0x5f, 0x40, 0x50, 0x48, 0x18, 0x49, 0x40, +0x44, 0x54, 0x8c, 0x97, 0x4f, 0x1c, 0x49, 0x80, +0x9f, 0x47, 0x90, 0x4f, 0x42, 0x12, 0x49, 0x40, +0x8a, 0x5d, 0x5a, 0x58, 0x46, 0x96, 0x09, 0xb7, +0xb5, 0x54, 0x00, 0x00, 0x35, 0xfc, 0x02, 0x5e, +0x0d, 0x87, 0x6c, 0x90, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbColNotSel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbColNotSel_png = new wxImage(); + if (!img_gqbColNotSel_png || !img_gqbColNotSel_png->IsOk()) + { + wxMemoryInputStream img_gqbColNotSel_pngIS(gqbColNotSel_png_data, sizeof(gqbColNotSel_png_data)); + img_gqbColNotSel_png->LoadFile(img_gqbColNotSel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbColNotSel_png; +} +#define gqbColNotSel_png_img gqbColNotSel_png_img() + +static wxBitmap *gqbColNotSel_png_bmp() +{ + static wxBitmap *bmp_gqbColNotSel_png; + if (!bmp_gqbColNotSel_png || !bmp_gqbColNotSel_png->IsOk()) + bmp_gqbColNotSel_png = new wxBitmap(*gqbColNotSel_png_img); + return bmp_gqbColNotSel_png; +} +#define gqbColNotSel_png_bmp gqbColNotSel_png_bmp() + +static wxIcon *gqbColNotSel_png_ico() +{ + static wxIcon *ico_gqbColNotSel_png; + if (!ico_gqbColNotSel_png || !ico_gqbColNotSel_png->IsOk()) + { + ico_gqbColNotSel_png = new wxIcon(); + ico_gqbColNotSel_png->CopyFromBitmap(*gqbColNotSel_png_bmp); + } + return ico_gqbColNotSel_png; +} +#define gqbColNotSel_png_ico gqbColNotSel_png_ico() + +#endif // GQBCOLNOTSEL_PNG_H diff --git a/include/images/gqbColSel.png b/include/images/gqbColSel.png new file mode 100644 index 0000000..7e9c811 Binary files /dev/null and b/include/images/gqbColSel.png differ diff --git a/include/images/gqbColSel.pngc b/include/images/gqbColSel.pngc new file mode 100644 index 0000000..7a5d50d --- /dev/null +++ b/include/images/gqbColSel.pngc @@ -0,0 +1,95 @@ +#ifndef GQBCOLSEL_PNG_H +#define GQBCOLSEL_PNG_H + +static const unsigned char gqbColSel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x84, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xfd, 0xfe, 0xfe, 0xfb, 0xfe, 0xfe, +0xf9, 0xfc, 0xfe, 0xf7, 0xfb, 0xfe, 0xf1, 0xf6, +0xf9, 0xec, 0xf6, 0xfa, 0x57, 0x57, 0x57, 0xfc, +0xfe, 0xfe, 0xfa, 0xfd, 0xfe, 0xf7, 0xfb, 0xfd, +0xf1, 0xf9, 0xfc, 0xde, 0xb2, 0xb4, 0xd8, 0xa6, +0xac, 0x5e, 0x5b, 0x5c, 0xf9, 0xfb, 0xfc, 0xed, +0xd1, 0xd3, 0xed, 0xe7, 0xe9, 0xe2, 0xcc, 0xcd, +0xcd, 0x61, 0x63, 0xd1, 0x91, 0x96, 0x60, 0x5f, +0x60, 0xf3, 0xe6, 0xe6, 0xd6, 0x70, 0x72, 0xd6, +0x85, 0x87, 0xd1, 0x78, 0x7b, 0xcb, 0x75, 0x79, +0xd6, 0xd7, 0xdd, 0x6a, 0x70, 0x72, 0xf5, 0xf8, +0xf9, 0xdd, 0xa6, 0xa8, 0xcd, 0x4e, 0x50, 0xca, +0x62, 0x65, 0xd6, 0xc3, 0xc9, 0xe2, 0xf1, 0xf7, +0x65, 0x6a, 0x6c, 0xf2, 0xfa, 0xfc, 0xe9, 0xe6, +0xeb, 0xd2, 0x95, 0x9a, 0xd5, 0xaf, 0xb4, 0xe6, +0xf1, 0xf5, 0xea, 0xf7, 0xfb, 0x35, 0xf1, 0x6c, +0x18, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x4b, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, +0x02, 0x60, 0x64, 0x02, 0x03, 0x46, 0xb8, 0x00, +0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b, 0x07, 0x27, +0x42, 0x80, 0x8b, 0x9b, 0x87, 0x97, 0x8f, 0x5f, +0x00, 0x21, 0x20, 0x28, 0x24, 0x2c, 0x22, 0x2a, +0x26, 0x8e, 0x10, 0x90, 0x90, 0x94, 0x92, 0x96, +0x91, 0x95, 0x43, 0x08, 0xc8, 0x2b, 0x28, 0x2a, +0x29, 0xab, 0xa8, 0x22, 0x04, 0xd4, 0xd4, 0x35, +0x34, 0xb5, 0xb4, 0x99, 0x70, 0x5b, 0x4b, 0x05, +0x00, 0x00, 0xe7, 0xfa, 0x03, 0xda, 0xec, 0xa6, +0x06, 0x71, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbColSel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbColSel_png = new wxImage(); + if (!img_gqbColSel_png || !img_gqbColSel_png->IsOk()) + { + wxMemoryInputStream img_gqbColSel_pngIS(gqbColSel_png_data, sizeof(gqbColSel_png_data)); + img_gqbColSel_png->LoadFile(img_gqbColSel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbColSel_png; +} +#define gqbColSel_png_img gqbColSel_png_img() + +static wxBitmap *gqbColSel_png_bmp() +{ + static wxBitmap *bmp_gqbColSel_png; + if (!bmp_gqbColSel_png || !bmp_gqbColSel_png->IsOk()) + bmp_gqbColSel_png = new wxBitmap(*gqbColSel_png_img); + return bmp_gqbColSel_png; +} +#define gqbColSel_png_bmp gqbColSel_png_bmp() + +static wxIcon *gqbColSel_png_ico() +{ + static wxIcon *ico_gqbColSel_png; + if (!ico_gqbColSel_png || !ico_gqbColSel_png->IsOk()) + { + ico_gqbColSel_png = new wxIcon(); + ico_gqbColSel_png->CopyFromBitmap(*gqbColSel_png_bmp); + } + return ico_gqbColSel_png; +} +#define gqbColSel_png_ico gqbColSel_png_ico() + +#endif // GQBCOLSEL_PNG_H diff --git a/include/images/gqbDown.png b/include/images/gqbDown.png new file mode 100644 index 0000000..2b3f981 Binary files /dev/null and b/include/images/gqbDown.png differ diff --git a/include/images/gqbDown.pngc b/include/images/gqbDown.pngc new file mode 100644 index 0000000..4b95046 --- /dev/null +++ b/include/images/gqbDown.pngc @@ -0,0 +1,93 @@ +#ifndef GQBDOWN_PNG_H +#define GQBDOWN_PNG_H + +static const unsigned char gqbDown_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xba, 0xd4, 0x85, 0x9f, 0xc3, +0x53, 0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, +0xba, 0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, +0x94, 0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xba, 0xd4, +0x83, 0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, +0xbb, 0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, +0xb1, 0xcd, 0x69, 0xba, 0xd3, 0x83, 0x9e, 0xc2, +0x4f, 0x96, 0xbc, 0x3d, 0x9b, 0xbf, 0x43, 0xb4, +0xcf, 0x70, 0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, +0xcc, 0xdf, 0xa3, 0x6d, 0x2e, 0x72, 0xd0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x49, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x47, 0x0e, 0x80, +0x30, 0x0c, 0x05, 0x51, 0xdb, 0x84, 0xde, 0x7b, +0xef, 0x70, 0xff, 0x2b, 0x92, 0xaf, 0x08, 0x65, +0x76, 0x4f, 0x43, 0x2c, 0x36, 0x26, 0x71, 0x94, +0xeb, 0xf9, 0x41, 0x18, 0xc5, 0x49, 0x2a, 0xc4, +0x92, 0xe5, 0x45, 0x59, 0xd5, 0x4d, 0xdb, 0xe9, +0xa7, 0xd9, 0x0f, 0xe3, 0x34, 0x2f, 0x2b, 0x00, +0x6e, 0xfb, 0x71, 0x5e, 0x06, 0xa0, 0xba, 0x9f, +0x1f, 0xe0, 0x6b, 0x01, 0x1a, 0x7c, 0xb9, 0x54, +0x02, 0xff, 0x7a, 0xee, 0x99, 0x94, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbDown_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbDown_png = new wxImage(); + if (!img_gqbDown_png || !img_gqbDown_png->IsOk()) + { + wxMemoryInputStream img_gqbDown_pngIS(gqbDown_png_data, sizeof(gqbDown_png_data)); + img_gqbDown_png->LoadFile(img_gqbDown_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbDown_png; +} +#define gqbDown_png_img gqbDown_png_img() + +static wxBitmap *gqbDown_png_bmp() +{ + static wxBitmap *bmp_gqbDown_png; + if (!bmp_gqbDown_png || !bmp_gqbDown_png->IsOk()) + bmp_gqbDown_png = new wxBitmap(*gqbDown_png_img); + return bmp_gqbDown_png; +} +#define gqbDown_png_bmp gqbDown_png_bmp() + +static wxIcon *gqbDown_png_ico() +{ + static wxIcon *ico_gqbDown_png; + if (!ico_gqbDown_png || !ico_gqbDown_png->IsOk()) + { + ico_gqbDown_png = new wxIcon(); + ico_gqbDown_png->CopyFromBitmap(*gqbDown_png_bmp); + } + return ico_gqbDown_png; +} +#define gqbDown_png_ico gqbDown_png_ico() + +#endif // GQBDOWN_PNG_H diff --git a/include/images/gqbDownBottom.png b/include/images/gqbDownBottom.png new file mode 100644 index 0000000..e14c023 Binary files /dev/null and b/include/images/gqbDownBottom.png differ diff --git a/include/images/gqbDownBottom.pngc b/include/images/gqbDownBottom.pngc new file mode 100644 index 0000000..3b69ced --- /dev/null +++ b/include/images/gqbDownBottom.pngc @@ -0,0 +1,88 @@ +#ifndef GQBDOWNBOTTOM_PNG_H +#define GQBDOWNBOTTOM_PNG_H + +static const unsigned char gqbDownBottom_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xad, 0xcb, +0x62, 0xab, 0xc9, 0x5e, 0xa9, 0xc8, 0x56, 0xaf, +0xcc, 0x63, 0xc5, 0xda, 0x8d, 0xba, 0xd4, 0x85, +0x9f, 0xc3, 0x53, 0x97, 0xbd, 0x40, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x94, 0xbb, 0x2f, 0xaf, +0xcc, 0x64, 0xba, 0xd4, 0x83, 0x9f, 0xc2, 0x51, +0x94, 0xbb, 0x38, 0x92, 0xb9, 0x31, 0xb1, 0xcd, +0x69, 0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xcc, +0xdf, 0xa3, 0x83, 0x9c, 0x90, 0x4c, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x43, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x60, 0x64, 0x82, 0x01, +0x46, 0x06, 0x06, 0x06, 0x26, 0x66, 0x16, 0x56, +0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x26, 0x20, +0x8f, 0x91, 0x89, 0x87, 0x97, 0x8f, 0x5f, 0x40, +0x50, 0x08, 0x2c, 0x07, 0xe4, 0x0a, 0x8b, 0x88, +0x8a, 0x89, 0x43, 0x38, 0x20, 0x2e, 0x8b, 0x84, +0x24, 0x8c, 0x03, 0xe2, 0x4a, 0x21, 0x38, 0x20, +0x2e, 0x23, 0x9c, 0x85, 0xb0, 0x01, 0x00, 0x6d, +0x3d, 0x01, 0xa9, 0x68, 0xc0, 0x2b, 0x7f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbDownBottom_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbDownBottom_png = new wxImage(); + if (!img_gqbDownBottom_png || !img_gqbDownBottom_png->IsOk()) + { + wxMemoryInputStream img_gqbDownBottom_pngIS(gqbDownBottom_png_data, sizeof(gqbDownBottom_png_data)); + img_gqbDownBottom_png->LoadFile(img_gqbDownBottom_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbDownBottom_png; +} +#define gqbDownBottom_png_img gqbDownBottom_png_img() + +static wxBitmap *gqbDownBottom_png_bmp() +{ + static wxBitmap *bmp_gqbDownBottom_png; + if (!bmp_gqbDownBottom_png || !bmp_gqbDownBottom_png->IsOk()) + bmp_gqbDownBottom_png = new wxBitmap(*gqbDownBottom_png_img); + return bmp_gqbDownBottom_png; +} +#define gqbDownBottom_png_bmp gqbDownBottom_png_bmp() + +static wxIcon *gqbDownBottom_png_ico() +{ + static wxIcon *ico_gqbDownBottom_png; + if (!ico_gqbDownBottom_png || !ico_gqbDownBottom_png->IsOk()) + { + ico_gqbDownBottom_png = new wxIcon(); + ico_gqbDownBottom_png->CopyFromBitmap(*gqbDownBottom_png_bmp); + } + return ico_gqbDownBottom_png; +} +#define gqbDownBottom_png_ico gqbDownBottom_png_ico() + +#endif // GQBDOWNBOTTOM_PNG_H diff --git a/include/images/gqbJoin.png b/include/images/gqbJoin.png new file mode 100644 index 0000000..776fe7d Binary files /dev/null and b/include/images/gqbJoin.png differ diff --git a/include/images/gqbJoin.pngc b/include/images/gqbJoin.pngc new file mode 100644 index 0000000..60c6ff4 --- /dev/null +++ b/include/images/gqbJoin.pngc @@ -0,0 +1,108 @@ +#ifndef GQBJOIN_PNG_H +#define GQBJOIN_PNG_H + +static const unsigned char gqbJoin_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0c, +0x08, 0x03, 0x00, 0x00, 0x00, 0x5c, 0x39, 0xcd, +0xb3, 0x00, 0x00, 0x00, 0xbd, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9c, 0x80, +0x80, 0x80, 0xc0, 0xc0, 0xc2, 0x94, 0x93, 0x95, +0xf9, 0xf9, 0xf9, 0xdf, 0xdf, 0xe1, 0xa6, 0xa6, +0xa6, 0x76, 0x76, 0x76, 0xde, 0xde, 0xe0, 0xda, +0xda, 0xdd, 0xe2, 0xe2, 0xe2, 0xa1, 0xa1, 0xa2, +0xb2, 0xb2, 0xb4, 0x70, 0x70, 0x71, 0x76, 0x76, +0x77, 0x75, 0x74, 0x75, 0xd3, 0xd3, 0xd3, 0x92, +0x92, 0x92, 0xf8, 0xf8, 0xf8, 0xde, 0xdd, 0xe0, +0x7a, 0x7a, 0x7a, 0x85, 0x85, 0x86, 0xa6, 0xa6, +0xa8, 0xa1, 0xa1, 0xa3, 0xcc, 0xcb, 0xcf, 0xb2, +0xb1, 0xb4, 0x82, 0x82, 0x82, 0x47, 0x47, 0x47, +0xf6, 0xf6, 0xf6, 0xa0, 0xa0, 0xa0, 0xcd, 0xcd, +0xcd, 0x75, 0x75, 0x76, 0x69, 0x69, 0x6a, 0x9b, +0x9a, 0x9d, 0xd8, 0xd8, 0xdb, 0xc8, 0xc8, 0xcb, +0x55, 0x55, 0x56, 0xf0, 0xf0, 0xf0, 0xdc, 0xdb, +0xde, 0x7c, 0x7c, 0x7c, 0xab, 0xab, 0xab, 0x83, +0x82, 0x84, 0xa8, 0xa7, 0xaa, 0xa5, 0xa5, 0xa8, +0xc6, 0xc6, 0xc9, 0x5c, 0x5c, 0x5e, 0xed, 0xed, +0xed, 0xdb, 0xda, 0xdd, 0xf7, 0xf7, 0xf7, 0x8c, +0x8c, 0x8e, 0xd0, 0xcf, 0xd3, 0x5d, 0x5d, 0x5f, +0xea, 0xea, 0xea, 0x61, 0x60, 0x62, 0xd4, 0xd4, +0xd7, 0xe8, 0xe8, 0xe8, 0xda, 0xd9, 0xdc, 0xcb, +0xcb, 0xcd, 0xb7, 0xb7, 0xba, 0xb7, 0xb7, 0xb9, +0xc8, 0xc8, 0xca, 0xd4, 0xd3, 0xd6, 0x3d, 0x62, +0x42, 0x94, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x74, +0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, +0xc0, 0x07, 0x18, 0x99, 0x98, 0x51, 0x05, 0x58, +0x58, 0xd9, 0x90, 0xb9, 0xcc, 0xec, 0x1c, 0xac, +0x9c, 0x40, 0x9a, 0x8b, 0x9b, 0x07, 0x48, 0xf2, +0xf2, 0xf1, 0x0b, 0x08, 0x0a, 0x09, 0x8b, 0x00, +0x99, 0x9c, 0xac, 0xa2, 0x62, 0x0c, 0x0c, 0xe2, +0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x10, 0x01, +0x39, 0x79, 0x05, 0x06, 0x45, 0x25, 0x06, 0x65, +0x15, 0x55, 0x35, 0x75, 0x90, 0x80, 0xb0, 0x86, +0xa6, 0x96, 0xb6, 0x8e, 0x2e, 0x90, 0xa9, 0xa7, +0x6f, 0x00, 0x12, 0x30, 0x94, 0x31, 0x32, 0x86, +0x18, 0x6b, 0x62, 0xca, 0x05, 0x12, 0x90, 0x35, +0x33, 0x87, 0xda, 0x63, 0x62, 0x61, 0x09, 0x24, +0xcd, 0xad, 0xac, 0x61, 0x16, 0xdb, 0xd8, 0xda, +0x61, 0xba, 0x16, 0x00, 0x7b, 0x82, 0x08, 0xb6, +0xa4, 0x8c, 0x66, 0x4d, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbJoin_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbJoin_png = new wxImage(); + if (!img_gqbJoin_png || !img_gqbJoin_png->IsOk()) + { + wxMemoryInputStream img_gqbJoin_pngIS(gqbJoin_png_data, sizeof(gqbJoin_png_data)); + img_gqbJoin_png->LoadFile(img_gqbJoin_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbJoin_png; +} +#define gqbJoin_png_img gqbJoin_png_img() + +static wxBitmap *gqbJoin_png_bmp() +{ + static wxBitmap *bmp_gqbJoin_png; + if (!bmp_gqbJoin_png || !bmp_gqbJoin_png->IsOk()) + bmp_gqbJoin_png = new wxBitmap(*gqbJoin_png_img); + return bmp_gqbJoin_png; +} +#define gqbJoin_png_bmp gqbJoin_png_bmp() + +static wxIcon *gqbJoin_png_ico() +{ + static wxIcon *ico_gqbJoin_png; + if (!ico_gqbJoin_png || !ico_gqbJoin_png->IsOk()) + { + ico_gqbJoin_png = new wxIcon(); + ico_gqbJoin_png->CopyFromBitmap(*gqbJoin_png_bmp); + } + return ico_gqbJoin_png; +} +#define gqbJoin_png_ico gqbJoin_png_ico() + +#endif // GQBJOIN_PNG_H diff --git a/include/images/gqbJoinCursor.png b/include/images/gqbJoinCursor.png new file mode 100644 index 0000000..deb59ca Binary files /dev/null and b/include/images/gqbJoinCursor.png differ diff --git a/include/images/gqbJoinCursor.pngc b/include/images/gqbJoinCursor.pngc new file mode 100644 index 0000000..791e1c6 --- /dev/null +++ b/include/images/gqbJoinCursor.pngc @@ -0,0 +1,74 @@ +#ifndef GQBJOINCURSOR_PNG_H +#define GQBJOINCURSOR_PNG_H + +static const unsigned char gqbJoinCursor_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x01, 0x47, +0x59, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x01, 0xdd, 0x8a, 0x13, 0xa4, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x22, 0x49, 0x44, +0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x03, +0x07, 0x10, 0x91, 0x00, 0x22, 0x0a, 0x40, 0x44, +0x05, 0x9c, 0xeb, 0xc0, 0x80, 0x13, 0x30, 0xa3, +0x12, 0x70, 0x2d, 0x08, 0x82, 0x42, 0x00, 0x00, +0x7c, 0x4b, 0x03, 0x52, 0x24, 0xcf, 0x43, 0xcb, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbJoinCursor_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbJoinCursor_png = new wxImage(); + if (!img_gqbJoinCursor_png || !img_gqbJoinCursor_png->IsOk()) + { + wxMemoryInputStream img_gqbJoinCursor_pngIS(gqbJoinCursor_png_data, sizeof(gqbJoinCursor_png_data)); + img_gqbJoinCursor_png->LoadFile(img_gqbJoinCursor_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbJoinCursor_png; +} +#define gqbJoinCursor_png_img gqbJoinCursor_png_img() + +static wxBitmap *gqbJoinCursor_png_bmp() +{ + static wxBitmap *bmp_gqbJoinCursor_png; + if (!bmp_gqbJoinCursor_png || !bmp_gqbJoinCursor_png->IsOk()) + bmp_gqbJoinCursor_png = new wxBitmap(*gqbJoinCursor_png_img); + return bmp_gqbJoinCursor_png; +} +#define gqbJoinCursor_png_bmp gqbJoinCursor_png_bmp() + +static wxIcon *gqbJoinCursor_png_ico() +{ + static wxIcon *ico_gqbJoinCursor_png; + if (!ico_gqbJoinCursor_png || !ico_gqbJoinCursor_png->IsOk()) + { + ico_gqbJoinCursor_png = new wxIcon(); + ico_gqbJoinCursor_png->CopyFromBitmap(*gqbJoinCursor_png_bmp); + } + return ico_gqbJoinCursor_png; +} +#define gqbJoinCursor_png_ico gqbJoinCursor_png_ico() + +#endif // GQBJOINCURSOR_PNG_H diff --git a/include/images/gqbOrderAdd.png b/include/images/gqbOrderAdd.png new file mode 100644 index 0000000..59205c3 Binary files /dev/null and b/include/images/gqbOrderAdd.png differ diff --git a/include/images/gqbOrderAdd.pngc b/include/images/gqbOrderAdd.pngc new file mode 100644 index 0000000..441a67b --- /dev/null +++ b/include/images/gqbOrderAdd.pngc @@ -0,0 +1,83 @@ +#ifndef GQBORDERADD_PNG_H +#define GQBORDERADD_PNG_H + +static const unsigned char gqbOrderAdd_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x09, +0x08, 0x03, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x56, +0x58, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xba, 0xd4, 0x85, 0xb2, 0xce, 0x71, 0x9f, 0xc3, +0x53, 0xba, 0xd4, 0x83, 0xb0, 0xcd, 0x6c, 0x97, +0xbd, 0x40, 0x9f, 0xc2, 0x51, 0xa9, 0xc8, 0x56, +0x94, 0xbb, 0x2f, 0xb1, 0xcd, 0x69, 0xaf, 0xcc, +0x63, 0xaf, 0xcc, 0x64, 0xc5, 0xda, 0x8d, 0xc4, +0x24, 0xea, 0x05, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x35, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x4d, +0xcd, 0xc9, 0x11, 0x00, 0x20, 0x0c, 0x02, 0x40, +0xc4, 0xfb, 0xd6, 0xfe, 0x9b, 0xf5, 0x67, 0xc8, +0x6f, 0x87, 0x81, 0x00, 0x80, 0xa3, 0x83, 0x1d, +0xbd, 0x92, 0x21, 0x0a, 0x99, 0x72, 0x31, 0xb2, +0xb6, 0x1e, 0x3e, 0x39, 0xe6, 0x92, 0x6c, 0x1f, +0xed, 0x5d, 0xdd, 0xb4, 0x7f, 0x0f, 0x2c, 0x29, +0x00, 0xc6, 0xcc, 0xd6, 0xee, 0x82, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbOrderAdd_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbOrderAdd_png = new wxImage(); + if (!img_gqbOrderAdd_png || !img_gqbOrderAdd_png->IsOk()) + { + wxMemoryInputStream img_gqbOrderAdd_pngIS(gqbOrderAdd_png_data, sizeof(gqbOrderAdd_png_data)); + img_gqbOrderAdd_png->LoadFile(img_gqbOrderAdd_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderAdd_png; +} +#define gqbOrderAdd_png_img gqbOrderAdd_png_img() + +static wxBitmap *gqbOrderAdd_png_bmp() +{ + static wxBitmap *bmp_gqbOrderAdd_png; + if (!bmp_gqbOrderAdd_png || !bmp_gqbOrderAdd_png->IsOk()) + bmp_gqbOrderAdd_png = new wxBitmap(*gqbOrderAdd_png_img); + return bmp_gqbOrderAdd_png; +} +#define gqbOrderAdd_png_bmp gqbOrderAdd_png_bmp() + +static wxIcon *gqbOrderAdd_png_ico() +{ + static wxIcon *ico_gqbOrderAdd_png; + if (!ico_gqbOrderAdd_png || !ico_gqbOrderAdd_png->IsOk()) + { + ico_gqbOrderAdd_png = new wxIcon(); + ico_gqbOrderAdd_png->CopyFromBitmap(*gqbOrderAdd_png_bmp); + } + return ico_gqbOrderAdd_png; +} +#define gqbOrderAdd_png_ico gqbOrderAdd_png_ico() + +#endif // GQBORDERADD_PNG_H diff --git a/include/images/gqbOrderAddAll.png b/include/images/gqbOrderAddAll.png new file mode 100644 index 0000000..d95e9d2 Binary files /dev/null and b/include/images/gqbOrderAddAll.png differ diff --git a/include/images/gqbOrderAddAll.pngc b/include/images/gqbOrderAddAll.pngc new file mode 100644 index 0000000..b1024c0 --- /dev/null +++ b/include/images/gqbOrderAddAll.pngc @@ -0,0 +1,85 @@ +#ifndef GQBORDERADDALL_PNG_H +#define GQBORDERADDALL_PNG_H + +static const unsigned char gqbOrderAddAll_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x09, +0x08, 0x03, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x56, +0x58, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd3, 0x81, +0xba, 0xd4, 0x85, 0xb2, 0xce, 0x71, 0x9f, 0xc3, +0x53, 0xba, 0xd4, 0x83, 0xb0, 0xcd, 0x6c, 0x97, +0xbd, 0x40, 0x9f, 0xc2, 0x51, 0xa9, 0xc8, 0x56, +0x94, 0xbb, 0x2f, 0xb1, 0xcd, 0x69, 0xaf, 0xcc, +0x63, 0xaf, 0xcc, 0x64, 0xc5, 0xda, 0x8d, 0xc4, +0x24, 0xea, 0x05, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x45, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x55, +0x8d, 0x49, 0x16, 0xc0, 0x20, 0x08, 0x43, 0x03, +0xda, 0x41, 0xad, 0x5a, 0xef, 0x7f, 0xd9, 0x46, +0xb2, 0xea, 0xe6, 0x93, 0x81, 0x07, 0x30, 0x37, +0x00, 0x22, 0xe0, 0x69, 0x0b, 0x91, 0x33, 0x1f, +0x14, 0x22, 0xdd, 0x79, 0xdd, 0x6e, 0x22, 0x5d, +0xa9, 0x2d, 0xbb, 0xc8, 0x9d, 0xa7, 0x0f, 0x76, +0x41, 0x76, 0xf3, 0xdd, 0x59, 0x90, 0x6e, 0x45, +0xb6, 0x74, 0xf3, 0xf7, 0xef, 0x03, 0x57, 0x95, +0x01, 0x8a, 0x9f, 0x12, 0x72, 0xd4, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbOrderAddAll_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbOrderAddAll_png = new wxImage(); + if (!img_gqbOrderAddAll_png || !img_gqbOrderAddAll_png->IsOk()) + { + wxMemoryInputStream img_gqbOrderAddAll_pngIS(gqbOrderAddAll_png_data, sizeof(gqbOrderAddAll_png_data)); + img_gqbOrderAddAll_png->LoadFile(img_gqbOrderAddAll_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderAddAll_png; +} +#define gqbOrderAddAll_png_img gqbOrderAddAll_png_img() + +static wxBitmap *gqbOrderAddAll_png_bmp() +{ + static wxBitmap *bmp_gqbOrderAddAll_png; + if (!bmp_gqbOrderAddAll_png || !bmp_gqbOrderAddAll_png->IsOk()) + bmp_gqbOrderAddAll_png = new wxBitmap(*gqbOrderAddAll_png_img); + return bmp_gqbOrderAddAll_png; +} +#define gqbOrderAddAll_png_bmp gqbOrderAddAll_png_bmp() + +static wxIcon *gqbOrderAddAll_png_ico() +{ + static wxIcon *ico_gqbOrderAddAll_png; + if (!ico_gqbOrderAddAll_png || !ico_gqbOrderAddAll_png->IsOk()) + { + ico_gqbOrderAddAll_png = new wxIcon(); + ico_gqbOrderAddAll_png->CopyFromBitmap(*gqbOrderAddAll_png_bmp); + } + return ico_gqbOrderAddAll_png; +} +#define gqbOrderAddAll_png_ico gqbOrderAddAll_png_ico() + +#endif // GQBORDERADDALL_PNG_H diff --git a/include/images/gqbOrderRemove.png b/include/images/gqbOrderRemove.png new file mode 100644 index 0000000..06f7dc7 Binary files /dev/null and b/include/images/gqbOrderRemove.png differ diff --git a/include/images/gqbOrderRemove.pngc b/include/images/gqbOrderRemove.pngc new file mode 100644 index 0000000..f5dab80 --- /dev/null +++ b/include/images/gqbOrderRemove.pngc @@ -0,0 +1,83 @@ +#ifndef GQBORDERREMOVE_PNG_H +#define GQBORDERREMOVE_PNG_H + +static const unsigned char gqbOrderRemove_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x09, +0x08, 0x03, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x56, +0x58, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd4, 0x85, +0xba, 0xd3, 0x81, 0xba, 0xd4, 0x83, 0x9f, 0xc3, +0x53, 0xb2, 0xce, 0x71, 0x9f, 0xc2, 0x51, 0x97, +0xbd, 0x40, 0xb0, 0xcd, 0x6c, 0xb1, 0xcd, 0x69, +0x94, 0xbb, 0x2f, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, +0x64, 0xaf, 0xcc, 0x63, 0xc5, 0xda, 0x8d, 0x36, +0x33, 0x65, 0xdd, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x36, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0x80, 0x00, 0x46, 0x26, 0x46, 0x06, 0x38, +0x60, 0x64, 0x62, 0x66, 0x42, 0xe2, 0xb0, 0xb0, +0x32, 0x21, 0x38, 0x6c, 0xec, 0x1c, 0x4c, 0x70, +0x0e, 0x2b, 0x27, 0x17, 0x37, 0x92, 0x1c, 0x0f, +0x2f, 0x1f, 0xb2, 0x3e, 0x7e, 0x01, 0x26, 0x64, +0x33, 0x05, 0x91, 0x78, 0x50, 0xfb, 0x00, 0x2a, +0x9b, 0x00, 0xc7, 0x7e, 0x4c, 0x14, 0x4d, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbOrderRemove_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbOrderRemove_png = new wxImage(); + if (!img_gqbOrderRemove_png || !img_gqbOrderRemove_png->IsOk()) + { + wxMemoryInputStream img_gqbOrderRemove_pngIS(gqbOrderRemove_png_data, sizeof(gqbOrderRemove_png_data)); + img_gqbOrderRemove_png->LoadFile(img_gqbOrderRemove_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderRemove_png; +} +#define gqbOrderRemove_png_img gqbOrderRemove_png_img() + +static wxBitmap *gqbOrderRemove_png_bmp() +{ + static wxBitmap *bmp_gqbOrderRemove_png; + if (!bmp_gqbOrderRemove_png || !bmp_gqbOrderRemove_png->IsOk()) + bmp_gqbOrderRemove_png = new wxBitmap(*gqbOrderRemove_png_img); + return bmp_gqbOrderRemove_png; +} +#define gqbOrderRemove_png_bmp gqbOrderRemove_png_bmp() + +static wxIcon *gqbOrderRemove_png_ico() +{ + static wxIcon *ico_gqbOrderRemove_png; + if (!ico_gqbOrderRemove_png || !ico_gqbOrderRemove_png->IsOk()) + { + ico_gqbOrderRemove_png = new wxIcon(); + ico_gqbOrderRemove_png->CopyFromBitmap(*gqbOrderRemove_png_bmp); + } + return ico_gqbOrderRemove_png; +} +#define gqbOrderRemove_png_ico gqbOrderRemove_png_ico() + +#endif // GQBORDERREMOVE_PNG_H diff --git a/include/images/gqbOrderRemoveAll.png b/include/images/gqbOrderRemoveAll.png new file mode 100644 index 0000000..773aa10 Binary files /dev/null and b/include/images/gqbOrderRemoveAll.png differ diff --git a/include/images/gqbOrderRemoveAll.pngc b/include/images/gqbOrderRemoveAll.pngc new file mode 100644 index 0000000..7dd627f --- /dev/null +++ b/include/images/gqbOrderRemoveAll.pngc @@ -0,0 +1,84 @@ +#ifndef GQBORDERREMOVEALL_PNG_H +#define GQBORDERREMOVEALL_PNG_H + +static const unsigned char gqbOrderRemoveAll_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x09, +0x08, 0x03, 0x00, 0x00, 0x00, 0xde, 0xa4, 0x56, +0x58, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xce, 0xe0, 0xa7, 0xba, 0xd4, 0x85, +0xba, 0xd3, 0x81, 0xba, 0xd4, 0x83, 0x9f, 0xc3, +0x53, 0xb2, 0xce, 0x71, 0x9f, 0xc2, 0x51, 0x97, +0xbd, 0x40, 0xb0, 0xcd, 0x6c, 0xb1, 0xcd, 0x69, +0x94, 0xbb, 0x2f, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, +0x64, 0xaf, 0xcc, 0x63, 0xc5, 0xda, 0x8d, 0x36, +0x33, 0x65, 0xdd, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x41, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0x00, 0x02, 0x46, 0x26, 0x46, 0x38, 0x09, +0xa4, 0x98, 0x99, 0x60, 0x24, 0x90, 0x62, 0x61, +0x65, 0x82, 0x92, 0x40, 0x8a, 0x8d, 0x9d, 0x83, +0x09, 0x42, 0x02, 0x39, 0xac, 0x9c, 0x5c, 0xdc, +0x4c, 0x10, 0x12, 0x24, 0xc7, 0xc3, 0xcb, 0xc7, +0x04, 0x21, 0xc1, 0xfa, 0xf8, 0x05, 0x98, 0xa0, +0x24, 0x98, 0x2b, 0xc8, 0x04, 0x23, 0x91, 0xed, +0x03, 0x00, 0x54, 0x79, 0x01, 0x8c, 0x64, 0xba, +0x1b, 0xba, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbOrderRemoveAll_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbOrderRemoveAll_png = new wxImage(); + if (!img_gqbOrderRemoveAll_png || !img_gqbOrderRemoveAll_png->IsOk()) + { + wxMemoryInputStream img_gqbOrderRemoveAll_pngIS(gqbOrderRemoveAll_png_data, sizeof(gqbOrderRemoveAll_png_data)); + img_gqbOrderRemoveAll_png->LoadFile(img_gqbOrderRemoveAll_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbOrderRemoveAll_png; +} +#define gqbOrderRemoveAll_png_img gqbOrderRemoveAll_png_img() + +static wxBitmap *gqbOrderRemoveAll_png_bmp() +{ + static wxBitmap *bmp_gqbOrderRemoveAll_png; + if (!bmp_gqbOrderRemoveAll_png || !bmp_gqbOrderRemoveAll_png->IsOk()) + bmp_gqbOrderRemoveAll_png = new wxBitmap(*gqbOrderRemoveAll_png_img); + return bmp_gqbOrderRemoveAll_png; +} +#define gqbOrderRemoveAll_png_bmp gqbOrderRemoveAll_png_bmp() + +static wxIcon *gqbOrderRemoveAll_png_ico() +{ + static wxIcon *ico_gqbOrderRemoveAll_png; + if (!ico_gqbOrderRemoveAll_png || !ico_gqbOrderRemoveAll_png->IsOk()) + { + ico_gqbOrderRemoveAll_png = new wxIcon(); + ico_gqbOrderRemoveAll_png->CopyFromBitmap(*gqbOrderRemoveAll_png_bmp); + } + return ico_gqbOrderRemoveAll_png; +} +#define gqbOrderRemoveAll_png_ico gqbOrderRemoveAll_png_ico() + +#endif // GQBORDERREMOVEALL_PNG_H diff --git a/include/images/gqbRemove.png b/include/images/gqbRemove.png new file mode 100644 index 0000000..2b3a3f3 Binary files /dev/null and b/include/images/gqbRemove.png differ diff --git a/include/images/gqbRemove.pngc b/include/images/gqbRemove.pngc new file mode 100644 index 0000000..7fd85d4 --- /dev/null +++ b/include/images/gqbRemove.pngc @@ -0,0 +1,73 @@ +#ifndef GQBREMOVE_PNG_H +#define GQBREMOVE_PNG_H + +static const unsigned char gqbRemove_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x01, 0x03, 0x00, 0x00, 0x00, 0x3c, 0x8a, 0x66, +0x6f, 0x00, 0x00, 0x00, 0x06, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfb, 0x03, 0x3d, 0x6f, +0xb3, 0x3a, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x12, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0xc0, 0x02, 0xec, 0xff, 0x37, 0x60, 0x60, +0x2c, 0x00, 0x00, 0x04, 0x5a, 0x08, 0xb7, 0xd0, +0x5b, 0x4a, 0xb6, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbRemove_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbRemove_png = new wxImage(); + if (!img_gqbRemove_png || !img_gqbRemove_png->IsOk()) + { + wxMemoryInputStream img_gqbRemove_pngIS(gqbRemove_png_data, sizeof(gqbRemove_png_data)); + img_gqbRemove_png->LoadFile(img_gqbRemove_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbRemove_png; +} +#define gqbRemove_png_img gqbRemove_png_img() + +static wxBitmap *gqbRemove_png_bmp() +{ + static wxBitmap *bmp_gqbRemove_png; + if (!bmp_gqbRemove_png || !bmp_gqbRemove_png->IsOk()) + bmp_gqbRemove_png = new wxBitmap(*gqbRemove_png_img); + return bmp_gqbRemove_png; +} +#define gqbRemove_png_bmp gqbRemove_png_bmp() + +static wxIcon *gqbRemove_png_ico() +{ + static wxIcon *ico_gqbRemove_png; + if (!ico_gqbRemove_png || !ico_gqbRemove_png->IsOk()) + { + ico_gqbRemove_png = new wxIcon(); + ico_gqbRemove_png->CopyFromBitmap(*gqbRemove_png_bmp); + } + return ico_gqbRemove_png; +} +#define gqbRemove_png_ico gqbRemove_png_ico() + +#endif // GQBREMOVE_PNG_H diff --git a/include/images/gqbRemoveRest.png b/include/images/gqbRemoveRest.png new file mode 100644 index 0000000..a8a937b Binary files /dev/null and b/include/images/gqbRemoveRest.png differ diff --git a/include/images/gqbRemoveRest.pngc b/include/images/gqbRemoveRest.pngc new file mode 100644 index 0000000..23880c8 --- /dev/null +++ b/include/images/gqbRemoveRest.pngc @@ -0,0 +1,136 @@ +#ifndef GQBREMOVEREST_PNG_H +#define GQBREMOVEREST_PNG_H + +static const unsigned char gqbRemoveRest_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, +0x08, 0x03, 0x00, 0x00, 0x00, 0x31, 0x9a, 0x04, +0x1e, 0x00, 0x00, 0x01, 0x44, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x95, 0x97, 0xb5, 0x78, +0x7a, 0xb4, 0x70, 0x73, 0xb4, 0xb9, 0xba, 0xd9, +0x81, 0x83, 0xbd, 0xf0, 0xf1, 0xf3, 0xf0, 0xe6, +0xff, 0xe5, 0xd8, 0xfb, 0xdd, 0xd3, 0xf4, 0xd9, +0xcd, 0xf2, 0xd3, 0xc9, 0xec, 0xd0, 0xc2, 0xec, +0xc9, 0xbc, 0xe7, 0xc5, 0xbc, 0xe1, 0xea, 0xe7, +0xf3, 0x70, 0x88, 0xb4, 0xd5, 0xbd, 0xfa, 0xcd, +0xb1, 0xf9, 0xc6, 0xaf, 0xee, 0xc3, 0xa7, 0xf2, +0xb7, 0x9c, 0xe8, 0xad, 0x92, 0xe1, 0xa6, 0x8b, +0xdb, 0x9e, 0x83, 0xd5, 0x96, 0x7c, 0xce, 0x90, +0x75, 0xc9, 0x99, 0x83, 0xcc, 0x88, 0x8a, 0xa8, +0x5a, 0x7a, 0xaa, 0xbb, 0xa7, 0xe3, 0xab, 0x97, +0xd8, 0x8e, 0x73, 0xc8, 0xca, 0x8d, 0x9e, 0xc2, +0x19, 0x1a, 0xa9, 0x67, 0x76, 0xde, 0x6c, 0x6c, +0xc9, 0x21, 0x21, 0xdf, 0x77, 0x77, 0x85, 0x6b, +0xc2, 0xaf, 0x4b, 0x61, 0xd9, 0x3d, 0x3e, 0xc7, +0x24, 0x25, 0xc5, 0x28, 0x28, 0xdc, 0x2e, 0x2e, +0xd2, 0x3b, 0x3b, 0xc3, 0xb5, 0xe1, 0x7d, 0x63, +0xbc, 0xb8, 0x2a, 0x36, 0xd4, 0x36, 0x3a, 0xff, +0x87, 0x87, 0xe8, 0x41, 0x41, 0xc0, 0x23, 0x25, +0xbb, 0x27, 0x2a, 0xdf, 0x31, 0x31, 0xf9, 0x5a, +0x5b, 0xd7, 0x23, 0x23, 0x6f, 0x55, 0xb0, 0xb6, +0xa8, 0xd7, 0xae, 0x38, 0x4a, 0xe1, 0x47, 0x47, +0xfe, 0x7a, 0x7a, 0xdd, 0x39, 0x3a, 0xdf, 0x33, +0x33, 0xfb, 0x5e, 0x5f, 0xde, 0x29, 0x29, 0xd1, +0x35, 0x35, 0xbb, 0xad, 0xdb, 0xaf, 0xa2, 0xd2, +0x84, 0x71, 0xa2, 0xc0, 0x0b, 0x0c, 0xe0, 0x35, +0x36, 0xf4, 0x5d, 0x5d, 0xf2, 0x51, 0x51, 0xdc, +0x2a, 0x2a, 0xcf, 0x34, 0x34, 0x82, 0x72, 0xa4, +0xbe, 0x0d, 0x0e, 0xdf, 0x2e, 0x2e, 0xf1, 0x46, +0x46, 0xdb, 0x22, 0x22, 0xd0, 0x35, 0x35, 0xe4, +0xe4, 0xe4, 0xac, 0x37, 0x4c, 0xde, 0x38, 0x39, +0xfc, 0x5c, 0x5c, 0xdc, 0x29, 0x29, 0xdb, 0x22, +0x23, 0xf5, 0x3c, 0x3c, 0xdb, 0x17, 0x17, 0xd1, +0x33, 0x33, 0xab, 0xad, 0xd3, 0xb6, 0x05, 0x06, +0xd5, 0x20, 0x1f, 0xfd, 0x58, 0x58, 0xd9, 0x1c, +0x1c, 0xb9, 0x26, 0x29, 0xbe, 0x2c, 0x2f, 0xdc, +0x15, 0x15, 0xf0, 0x24, 0x24, 0xd2, 0x0f, 0x0f, +0x9e, 0x34, 0x35, 0xc4, 0x2d, 0x2d, 0xda, 0x20, +0x20, 0xc4, 0x28, 0x28, 0xc9, 0x2b, 0x2c, 0xd3, +0x10, 0x10, 0xd2, 0x3a, 0x3a, 0xc2, 0x43, 0xa1, +0x8a, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xcd, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x64, +0x62, 0x46, 0x05, 0x2c, 0x0c, 0x0c, 0xac, 0x6c, +0xec, 0x1c, 0x40, 0xc0, 0xc9, 0xc5, 0xc5, 0xcd, +0xc3, 0xc3, 0xcb, 0xc7, 0xcd, 0xcf, 0xca, 0xc0, +0x20, 0xc0, 0xca, 0x21, 0x28, 0x24, 0x2c, 0x22, +0x2a, 0x2a, 0x26, 0x2e, 0x21, 0x29, 0x25, 0xcd, +0xc7, 0x0a, 0x54, 0xc7, 0x20, 0xc3, 0xca, 0x29, +0x88, 0x24, 0x24, 0xcb, 0x00, 0x02, 0x8c, 0xac, +0x9c, 0xc2, 0x70, 0x21, 0x01, 0x06, 0x06, 0xa8, +0x20, 0x97, 0x1c, 0x8a, 0x2a, 0x10, 0x90, 0x65, +0xe5, 0x96, 0x97, 0x54, 0x90, 0x54, 0x54, 0x52, +0x66, 0x60, 0x50, 0x51, 0x55, 0x83, 0x08, 0xca, +0xb0, 0xca, 0x29, 0xa8, 0xcb, 0x6b, 0x68, 0x6a, +0x31, 0x30, 0x68, 0xeb, 0xe8, 0x42, 0x55, 0x32, +0xeb, 0xa9, 0xeb, 0x1b, 0x18, 0x1a, 0x19, 0x9b, +0x98, 0x9a, 0x99, 0x5b, 0xc0, 0xc5, 0xf4, 0x2d, +0xad, 0xac, 0x6d, 0x6c, 0xed, 0xec, 0x1d, 0x1c, +0x9d, 0x60, 0x62, 0xce, 0x96, 0x96, 0x2e, 0xae, +0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x30, 0x5b, +0x98, 0xad, 0x80, 0x62, 0x3e, 0xbe, 0x7e, 0x9e, +0xfe, 0x01, 0x81, 0x70, 0x31, 0x7e, 0x17, 0x97, +0xa0, 0xe0, 0x90, 0xd0, 0xb0, 0xf0, 0x88, 0xc8, +0x28, 0xa8, 0x58, 0x34, 0xd0, 0xf3, 0x31, 0xb1, +0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0x0c, +0x08, 0x90, 0x9a, 0x96, 0x9e, 0xc1, 0xc0, 0x90, +0x99, 0x95, 0x0d, 0x00, 0xbd, 0xaa, 0x1d, 0x9c, +0x04, 0x1b, 0xbb, 0xd3, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbRemoveRest_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbRemoveRest_png = new wxImage(); + if (!img_gqbRemoveRest_png || !img_gqbRemoveRest_png->IsOk()) + { + wxMemoryInputStream img_gqbRemoveRest_pngIS(gqbRemoveRest_png_data, sizeof(gqbRemoveRest_png_data)); + img_gqbRemoveRest_png->LoadFile(img_gqbRemoveRest_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbRemoveRest_png; +} +#define gqbRemoveRest_png_img gqbRemoveRest_png_img() + +static wxBitmap *gqbRemoveRest_png_bmp() +{ + static wxBitmap *bmp_gqbRemoveRest_png; + if (!bmp_gqbRemoveRest_png || !bmp_gqbRemoveRest_png->IsOk()) + bmp_gqbRemoveRest_png = new wxBitmap(*gqbRemoveRest_png_img); + return bmp_gqbRemoveRest_png; +} +#define gqbRemoveRest_png_bmp gqbRemoveRest_png_bmp() + +static wxIcon *gqbRemoveRest_png_ico() +{ + static wxIcon *ico_gqbRemoveRest_png; + if (!ico_gqbRemoveRest_png || !ico_gqbRemoveRest_png->IsOk()) + { + ico_gqbRemoveRest_png = new wxIcon(); + ico_gqbRemoveRest_png->CopyFromBitmap(*gqbRemoveRest_png_bmp); + } + return ico_gqbRemoveRest_png; +} +#define gqbRemoveRest_png_ico gqbRemoveRest_png_ico() + +#endif // GQBREMOVEREST_PNG_H diff --git a/include/images/gqbUp.png b/include/images/gqbUp.png new file mode 100644 index 0000000..d780b11 Binary files /dev/null and b/include/images/gqbUp.png differ diff --git a/include/images/gqbUp.pngc b/include/images/gqbUp.pngc new file mode 100644 index 0000000..009f17d --- /dev/null +++ b/include/images/gqbUp.pngc @@ -0,0 +1,93 @@ +#ifndef GQBUP_PNG_H +#define GQBUP_PNG_H + +static const unsigned char gqbUp_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xcc, 0xdf, 0xa3, 0xba, 0xd3, 0x81, +0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xba, 0xd3, +0x83, 0x9e, 0xc2, 0x4f, 0x96, 0xbc, 0x3d, 0x9b, +0xbf, 0x43, 0xb4, 0xcf, 0x70, 0xba, 0xd4, 0x83, +0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, 0xbb, +0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, 0xb1, +0xcd, 0x69, 0xba, 0xd4, 0x85, 0x9f, 0xc3, 0x53, +0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, 0x94, +0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xce, 0xe0, 0xa7, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xf4, 0x19, 0x1e, 0xf0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x4a, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x57, 0x0e, 0x80, +0x20, 0x00, 0x04, 0x51, 0x76, 0xc5, 0xde, 0x7b, +0xef, 0x7a, 0xff, 0x2b, 0x0a, 0x31, 0xca, 0xfc, +0xbd, 0x8c, 0x10, 0x3a, 0x10, 0xe2, 0x0f, 0xb4, +0x0c, 0x41, 0x69, 0x3b, 0x1f, 0x41, 0xd7, 0xf3, +0x83, 0xf0, 0x25, 0x18, 0xc5, 0x49, 0x9a, 0xe5, +0x85, 0x26, 0x58, 0x56, 0x75, 0xd3, 0x76, 0xfd, +0x30, 0x2a, 0x72, 0x92, 0xf3, 0xb2, 0x6e, 0xfb, +0x71, 0x5e, 0x37, 0xd5, 0x33, 0xe1, 0x01, 0x65, +0x4f, 0x02, 0xff, 0x59, 0xbc, 0x1a, 0xd1, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbUp_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbUp_png = new wxImage(); + if (!img_gqbUp_png || !img_gqbUp_png->IsOk()) + { + wxMemoryInputStream img_gqbUp_pngIS(gqbUp_png_data, sizeof(gqbUp_png_data)); + img_gqbUp_png->LoadFile(img_gqbUp_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbUp_png; +} +#define gqbUp_png_img gqbUp_png_img() + +static wxBitmap *gqbUp_png_bmp() +{ + static wxBitmap *bmp_gqbUp_png; + if (!bmp_gqbUp_png || !bmp_gqbUp_png->IsOk()) + bmp_gqbUp_png = new wxBitmap(*gqbUp_png_img); + return bmp_gqbUp_png; +} +#define gqbUp_png_bmp gqbUp_png_bmp() + +static wxIcon *gqbUp_png_ico() +{ + static wxIcon *ico_gqbUp_png; + if (!ico_gqbUp_png || !ico_gqbUp_png->IsOk()) + { + ico_gqbUp_png = new wxIcon(); + ico_gqbUp_png->CopyFromBitmap(*gqbUp_png_bmp); + } + return ico_gqbUp_png; +} +#define gqbUp_png_ico gqbUp_png_ico() + +#endif // GQBUP_PNG_H diff --git a/include/images/gqbUpTop.png b/include/images/gqbUpTop.png new file mode 100644 index 0000000..49ae936 Binary files /dev/null and b/include/images/gqbUpTop.png differ diff --git a/include/images/gqbUpTop.pngc b/include/images/gqbUpTop.pngc new file mode 100644 index 0000000..69ac0a0 --- /dev/null +++ b/include/images/gqbUpTop.pngc @@ -0,0 +1,88 @@ +#ifndef GQBUPTOP_PNG_H +#define GQBUPTOP_PNG_H + +static const unsigned char gqbUpTop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xcc, 0xdf, 0xa3, 0xba, 0xd3, 0x81, +0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xba, 0xd4, +0x83, 0x9f, 0xc2, 0x51, 0x94, 0xbb, 0x38, 0x92, +0xb9, 0x31, 0xb1, 0xcd, 0x69, 0xba, 0xd4, 0x85, +0x9f, 0xc3, 0x53, 0x97, 0xbd, 0x40, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x94, 0xbb, 0x2f, 0xaf, +0xcc, 0x64, 0xce, 0xe0, 0xa7, 0xb2, 0xce, 0x71, +0xb0, 0xcd, 0x6c, 0xad, 0xcb, 0x62, 0xab, 0xc9, +0x5e, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, 0xc5, +0xda, 0x8d, 0x32, 0x8e, 0x4b, 0xa5, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x41, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x60, 0x64, 0x82, 0x01, +0x46, 0x06, 0x08, 0x60, 0x84, 0xb3, 0xc0, 0x1c, +0x66, 0x04, 0x97, 0x91, 0x89, 0x85, 0x95, 0x0d, +0xc6, 0x65, 0x64, 0x62, 0xe7, 0xe0, 0xe4, 0xe2, +0x86, 0x70, 0x19, 0x99, 0x78, 0x78, 0xf9, 0xf8, +0x05, 0x04, 0x85, 0xc0, 0x5c, 0x26, 0x61, 0x16, +0x11, 0x51, 0x31, 0x71, 0x09, 0x49, 0x29, 0x26, +0xb0, 0x1c, 0xc2, 0x06, 0x00, 0x3a, 0x4b, 0x01, +0xa9, 0x63, 0x1c, 0xbf, 0xf9, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *gqbUpTop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_gqbUpTop_png = new wxImage(); + if (!img_gqbUpTop_png || !img_gqbUpTop_png->IsOk()) + { + wxMemoryInputStream img_gqbUpTop_pngIS(gqbUpTop_png_data, sizeof(gqbUpTop_png_data)); + img_gqbUpTop_png->LoadFile(img_gqbUpTop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_gqbUpTop_png; +} +#define gqbUpTop_png_img gqbUpTop_png_img() + +static wxBitmap *gqbUpTop_png_bmp() +{ + static wxBitmap *bmp_gqbUpTop_png; + if (!bmp_gqbUpTop_png || !bmp_gqbUpTop_png->IsOk()) + bmp_gqbUpTop_png = new wxBitmap(*gqbUpTop_png_img); + return bmp_gqbUpTop_png; +} +#define gqbUpTop_png_bmp gqbUpTop_png_bmp() + +static wxIcon *gqbUpTop_png_ico() +{ + static wxIcon *ico_gqbUpTop_png; + if (!ico_gqbUpTop_png || !ico_gqbUpTop_png->IsOk()) + { + ico_gqbUpTop_png = new wxIcon(); + ico_gqbUpTop_png->CopyFromBitmap(*gqbUpTop_png_bmp); + } + return ico_gqbUpTop_png; +} +#define gqbUpTop_png_ico gqbUpTop_png_ico() + +#endif // GQBUPTOP_PNG_H diff --git a/include/images/group.png b/include/images/group.png new file mode 100644 index 0000000..819ff81 Binary files /dev/null and b/include/images/group.png differ diff --git a/include/images/group.pngc b/include/images/group.pngc new file mode 100644 index 0000000..566091c --- /dev/null +++ b/include/images/group.pngc @@ -0,0 +1,145 @@ +#ifndef GROUP_PNG_H +#define GROUP_PNG_H + +static const unsigned char group_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x77, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x71, +0x71, 0x71, 0x62, 0x61, 0x5f, 0xa5, 0xa1, 0x91, +0xda, 0xd4, 0xb9, 0xd9, 0xd4, 0xb9, 0xa4, 0xa1, +0x92, 0xf4, 0xed, 0xcd, 0xf3, 0xed, 0xcd, 0xf3, +0xed, 0xce, 0x9d, 0x9b, 0x8c, 0x5e, 0x5c, 0x5a, +0x8f, 0x80, 0x71, 0xb7, 0x9e, 0x84, 0xb8, 0x9f, +0x83, 0x92, 0x82, 0x71, 0xf2, 0xee, 0xce, 0x96, +0x95, 0x88, 0xca, 0xac, 0x8d, 0xcc, 0xad, 0x8c, +0xce, 0xae, 0x8c, 0xd1, 0xb0, 0x8c, 0x94, 0x84, +0x70, 0xe4, 0xe0, 0xc3, 0xa3, 0xa1, 0x92, 0x59, +0x58, 0x58, 0x65, 0x61, 0x5d, 0x90, 0x81, 0x70, +0xc3, 0xa6, 0x87, 0xd3, 0xb2, 0x8b, 0xc0, 0xa4, +0x82, 0x62, 0x61, 0x60, 0xa7, 0xa0, 0x99, 0xdd, +0xd1, 0xc8, 0xdd, 0xd1, 0xca, 0xa6, 0xa0, 0x9c, +0x62, 0x61, 0x61, 0xc8, 0xaa, 0x86, 0xd5, 0xb3, +0x8b, 0xc2, 0xa5, 0x81, 0xbf, 0xbf, 0xbf, 0x62, +0x62, 0x5f, 0xa4, 0xa2, 0x92, 0xf8, 0xea, 0xdf, +0xf8, 0xea, 0xe1, 0xf7, 0xea, 0xe3, 0xf7, 0xea, +0xe6, 0xa6, 0xa0, 0x9f, 0x95, 0x84, 0x70, 0xd8, +0xb5, 0x8a, 0x98, 0x86, 0x70, 0x73, 0x6e, 0x65, +0xc5, 0xb2, 0x8f, 0xaa, 0x9a, 0x7f, 0x5a, 0x59, +0x57, 0xf7, 0xea, 0xe8, 0xdc, 0xd1, 0xd2, 0x67, +0x62, 0x5c, 0x60, 0x5d, 0x5a, 0xa7, 0xa7, 0xa7, +0xad, 0x9e, 0x83, 0xff, 0xe0, 0xaa, 0xff, 0xdf, +0xa7, 0x71, 0x6b, 0x61, 0xf7, 0xea, 0xeb, 0xdc, +0xd1, 0xd4, 0x58, 0x5a, 0x56, 0x90, 0xaa, 0x5f, +0xa2, 0xc4, 0x62, 0x69, 0x72, 0x58, 0x78, 0x78, +0x78, 0xdc, 0xc4, 0x99, 0xff, 0xdd, 0xa0, 0xaa, +0x98, 0x79, 0xf7, 0xea, 0xed, 0xa6, 0xa0, 0xa2, +0xca, 0xfd, 0x68, 0xc8, 0xfb, 0x66, 0x90, 0xaa, +0x5d, 0x5a, 0x5a, 0x5a, 0xfa, 0xdb, 0xa5, 0xff, +0xdc, 0x9d, 0xbf, 0xa8, 0x7e, 0x62, 0x61, 0x62, +0x9e, 0xbe, 0x61, 0xc7, 0xfa, 0x65, 0xae, 0xd7, +0x60, 0x55, 0x55, 0x55, 0xe1, 0xc3, 0x8b, 0x6c, +0x70, 0x70, 0xaa, 0xb8, 0xbb, 0x93, 0x9f, 0xa2, +0x69, 0x6d, 0x6f, 0x68, 0x6d, 0x6f, 0x8a, 0x9c, +0xa5, 0x9b, 0xb2, 0xbc, 0x67, 0x6d, 0x71, 0xb3, +0xdd, 0x62, 0xc5, 0xf8, 0x63, 0xc0, 0xf2, 0x61, +0xff, 0xda, 0x97, 0x97, 0xa3, 0xa5, 0xd2, 0xe9, +0xf0, 0xcd, 0xe7, 0xf1, 0xc9, 0xe5, 0xf1, 0xc4, +0xe3, 0xf1, 0xbf, 0xe1, 0xf1, 0xbb, 0xdf, 0xf1, +0x8b, 0xa4, 0x5c, 0xc3, 0xf6, 0x61, 0xc2, 0xf5, +0x60, 0xff, 0xd7, 0x91, 0xb9, 0xcb, 0xd0, 0xb6, +0xdd, 0xf2, 0xa0, 0xc0, 0xd2, 0x6b, 0x76, 0x57, +0xc1, 0xf4, 0x5f, 0x9b, 0x9b, 0x9b, 0xff, 0xd6, +0x8e, 0x5a, 0x58, 0x56, 0xca, 0xe3, 0xed, 0xb3, +0xdb, 0xf2, 0xae, 0xd6, 0xee, 0x58, 0x59, 0x55, +0xf7, 0x38, 0x4b, 0x12, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xe4, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x60, 0x60, 0x60, 0x64, 0x62, 0x62, +0x64, 0x40, 0x02, 0xcc, 0x2c, 0xac, 0x6c, 0xec, +0x48, 0xc2, 0x8c, 0x2c, 0x1c, 0x9c, 0x5c, 0x5c, +0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x3c, 0x20, +0x01, 0x26, 0x56, 0x20, 0x5f, 0x50, 0x88, 0x57, +0x58, 0x44, 0x54, 0x4c, 0x1c, 0xa4, 0x86, 0x89, +0x8d, 0x8b, 0x4b, 0x42, 0x52, 0x4a, 0x5a, 0x46, +0x56, 0x4c, 0x4e, 0x9e, 0x09, 0xa4, 0x85, 0x9d, +0x4b, 0x42, 0x41, 0x51, 0x49, 0x59, 0x45, 0x55, +0x4d, 0x5d, 0x03, 0x24, 0xa0, 0xa9, 0xa5, 0x2d, +0xa4, 0xa8, 0xa3, 0xab, 0xa7, 0x6f, 0x60, 0x68, +0x64, 0x0c, 0xd2, 0x62, 0x62, 0x6a, 0x66, 0xae, +0x04, 0xe4, 0x5b, 0x58, 0x5a, 0x19, 0x5b, 0x03, +0xf9, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0xca, 0x40, +0xbe, 0xa3, 0x93, 0xb3, 0x8b, 0xab, 0x1b, 0x03, +0x83, 0xbb, 0x87, 0xbd, 0xa7, 0x97, 0x0a, 0x90, +0xef, 0xed, 0xe3, 0xe2, 0xeb, 0xe7, 0x6f, 0xc3, +0x10, 0x10, 0xe8, 0x19, 0x14, 0xac, 0x6a, 0x60, +0xe9, 0xe4, 0x13, 0x12, 0xea, 0x17, 0x16, 0xee, +0xce, 0x10, 0xe1, 0x19, 0x14, 0x19, 0x15, 0x1d, +0x13, 0x1b, 0x17, 0x9f, 0x90, 0x98, 0x94, 0x9c, +0x12, 0xc0, 0x10, 0x11, 0x94, 0x1a, 0x91, 0x96, +0x9e, 0x91, 0x99, 0x95, 0x9d, 0x13, 0x9f, 0x9b, +0x97, 0x1f, 0xc1, 0x10, 0x91, 0x5a, 0x10, 0x51, +0x08, 0xe6, 0x17, 0x15, 0x97, 0xe4, 0x97, 0x46, +0x30, 0x94, 0x45, 0x94, 0x57, 0x54, 0x82, 0xf9, +0x55, 0xd5, 0x35, 0xa5, 0x11, 0x65, 0x0c, 0x40, +0x11, 0x24, 0x50, 0xc6, 0x00, 0x00, 0x38, 0xf9, +0x33, 0xa2, 0xe6, 0x2d, 0xf4, 0x51, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *group_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_group_png = new wxImage(); + if (!img_group_png || !img_group_png->IsOk()) + { + wxMemoryInputStream img_group_pngIS(group_png_data, sizeof(group_png_data)); + img_group_png->LoadFile(img_group_pngIS, wxBITMAP_TYPE_PNG); + } + return img_group_png; +} +#define group_png_img group_png_img() + +static wxBitmap *group_png_bmp() +{ + static wxBitmap *bmp_group_png; + if (!bmp_group_png || !bmp_group_png->IsOk()) + bmp_group_png = new wxBitmap(*group_png_img); + return bmp_group_png; +} +#define group_png_bmp group_png_bmp() + +static wxIcon *group_png_ico() +{ + static wxIcon *ico_group_png; + if (!ico_group_png || !ico_group_png->IsOk()) + { + ico_group_png = new wxIcon(); + ico_group_png->CopyFromBitmap(*group_png_bmp); + } + return ico_group_png; +} +#define group_png_ico group_png_ico() + +#endif // GROUP_PNG_H diff --git a/include/images/groups.png b/include/images/groups.png new file mode 100644 index 0000000..62d0b82 Binary files /dev/null and b/include/images/groups.png differ diff --git a/include/images/groups.pngc b/include/images/groups.pngc new file mode 100644 index 0000000..070d401 --- /dev/null +++ b/include/images/groups.pngc @@ -0,0 +1,139 @@ +#ifndef GROUPS_PNG_H +#define GROUPS_PNG_H + +static const unsigned char groups_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x44, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xc5, 0xc5, 0x7f, +0x7f, 0x7f, 0x8a, 0x87, 0x7d, 0xcd, 0xc7, 0xaf, +0xcc, 0xc7, 0xaf, 0x8a, 0x88, 0x7d, 0x71, 0x71, +0x71, 0x79, 0x76, 0x73, 0xd0, 0xc5, 0xbc, 0xd0, +0xc5, 0xbe, 0x8b, 0x87, 0x85, 0xf3, 0xed, 0xcd, +0xf3, 0xed, 0xce, 0xcb, 0xc8, 0xb0, 0x7b, 0x71, +0x68, 0xac, 0x96, 0x7f, 0xaf, 0x97, 0x7e, 0x7e, +0x73, 0x67, 0xc0, 0xb7, 0xb1, 0xf7, 0xea, 0xe4, +0xcf, 0xc5, 0xc4, 0x7d, 0x7d, 0x7d, 0xf2, 0xee, +0xce, 0xcb, 0xc8, 0xb1, 0x5f, 0x5f, 0x5f, 0xcc, +0xad, 0x8c, 0xcf, 0xaf, 0x8c, 0xb4, 0x9b, 0x7e, +0x7d, 0x7a, 0x78, 0xf7, 0xea, 0xe8, 0xcf, 0xc5, +0xc7, 0x5a, 0x5a, 0x58, 0xa3, 0xa1, 0x92, 0x62, +0x62, 0x5f, 0x55, 0x55, 0x55, 0x90, 0x80, 0x70, +0xd3, 0xb2, 0x8b, 0xb7, 0x9d, 0x7e, 0x72, 0x6f, +0x6f, 0x8b, 0x87, 0x88, 0x58, 0x5a, 0x5a, 0xb7, +0xb7, 0xb7, 0x9d, 0x92, 0x7d, 0xc5, 0xb2, 0x8f, +0x71, 0x6b, 0x62, 0x8b, 0x87, 0x82, 0x94, 0x83, +0x70, 0x81, 0x75, 0x67, 0x58, 0x5a, 0x56, 0x71, +0x77, 0x7a, 0x9e, 0xb3, 0xbc, 0x81, 0x90, 0x97, +0x80, 0x80, 0x80, 0xd4, 0xbe, 0x97, 0xff, 0xdf, +0xa7, 0x7f, 0x76, 0x67, 0xf8, 0xea, 0xe1, 0x5d, +0x5f, 0x57, 0x72, 0x7f, 0x5a, 0x87, 0x9d, 0x5c, +0x61, 0x66, 0x56, 0x65, 0x69, 0x6b, 0x9a, 0xb1, +0xbc, 0x9f, 0xbb, 0xca, 0x5b, 0x5b, 0x5b, 0xf9, +0xda, 0xa4, 0xc5, 0xae, 0x84, 0x5f, 0x5c, 0x58, +0x73, 0x71, 0x6f, 0xc0, 0xb7, 0xb3, 0x71, 0x7d, +0x5a, 0xa1, 0xc2, 0x60, 0x92, 0xab, 0xb8, 0xa1, +0xa1, 0xa1, 0x59, 0x59, 0x59, 0xa5, 0x9f, 0xa0, +0x6f, 0x7b, 0x58, 0x56, 0x56, 0x56, 0x5c, 0x5e, +0x5f, 0x6f, 0x76, 0x7a, 0xbe, 0xe0, 0xf1, 0x9c, +0xb6, 0xc4, 0x89, 0x88, 0x7e, 0x5a, 0x59, 0x57, +0x59, 0x5a, 0x5a, 0xb3, 0xd8, 0xeb, 0x8a, 0xa0, +0xac, 0x7f, 0x77, 0x69, 0xc5, 0xab, 0x7d, 0x9d, +0x8b, 0x6b, 0x8c, 0x95, 0x97, 0xa9, 0xb7, 0xbb, +0x73, 0x79, 0x7b, 0x72, 0x79, 0x7c, 0xff, 0xdc, +0x9d, 0xff, 0xd7, 0x91, 0xff, 0xd4, 0x88, 0xd4, +0xb1, 0x74, 0xb4, 0xc4, 0xc8, 0xd0, 0xe8, 0xf0, +0xca, 0xe6, 0xf1, 0xc4, 0xe3, 0xf1, 0xff, 0xd1, +0x7f, 0xf9, 0xc9, 0x74, 0xcc, 0xe3, 0xeb, 0xb8, +0xde, 0xf2, 0xb1, 0xd7, 0xec, 0x0b, 0x8d, 0x8e, +0x72, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xe8, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x60, +0x60, 0x64, 0x62, 0x62, 0x64, 0x60, 0x40, 0xa2, +0x99, 0x59, 0x58, 0xd9, 0x18, 0x19, 0x99, 0xd8, +0x39, 0x38, 0xb9, 0xb8, 0x41, 0x22, 0x4c, 0x2c, +0x3c, 0xbc, 0x7c, 0xec, 0xfc, 0x02, 0x82, 0x42, +0xc2, 0x22, 0xa2, 0x4c, 0x40, 0x01, 0x31, 0x56, +0x5e, 0x71, 0x09, 0x49, 0x01, 0x29, 0x69, 0x19, +0x59, 0x39, 0x79, 0x31, 0xa0, 0x80, 0x02, 0x1b, +0x9f, 0xa2, 0x92, 0xb2, 0x8a, 0xb4, 0xaa, 0x9a, +0xba, 0xbc, 0x86, 0x26, 0x03, 0x83, 0x96, 0xb6, +0x8e, 0xae, 0x1e, 0x50, 0xb7, 0xbe, 0x9a, 0x81, +0xa1, 0x91, 0xb1, 0x89, 0x16, 0x83, 0xa9, 0x99, +0xb9, 0x05, 0xa7, 0xa5, 0x88, 0xa8, 0x95, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0x83, 0x29, 0x83, 0xa3, +0x93, 0xb3, 0x8b, 0xab, 0x9b, 0x9c, 0xbc, 0xbb, +0x07, 0xc8, 0x36, 0x4f, 0x47, 0x06, 0x2f, 0x6f, +0x90, 0x06, 0x1f, 0x0d, 0x4d, 0x5f, 0x90, 0x6d, +0x7e, 0x5e, 0x40, 0x6b, 0x41, 0x1a, 0xfc, 0x8d, +0x4d, 0x94, 0x41, 0xb6, 0x81, 0x6c, 0x11, 0xe3, +0x12, 0x91, 0x93, 0x0f, 0x08, 0x0c, 0x02, 0xda, +0x26, 0x11, 0x1c, 0x02, 0x14, 0x08, 0xe5, 0x16, +0x05, 0x5a, 0x17, 0x16, 0xae, 0xad, 0x13, 0x61, +0x11, 0x19, 0xa5, 0xc5, 0xa0, 0x15, 0x1d, 0x13, +0x1b, 0x07, 0xd4, 0xe0, 0x67, 0x66, 0x1e, 0x9f, +0x90, 0x98, 0x64, 0xca, 0x60, 0x9a, 0x9c, 0x92, +0x9a, 0x16, 0xe8, 0x60, 0xea, 0xe8, 0x04, 0xe4, +0xa7, 0x67, 0x38, 0x32, 0x38, 0x66, 0x02, 0xf9, +0x59, 0xd9, 0x8e, 0x5e, 0x8e, 0xca, 0x40, 0xe0, +0xe8, 0xc5, 0x00, 0x67, 0x40, 0x01, 0x00, 0xf3, +0xbf, 0x26, 0x67, 0xda, 0xb1, 0xe6, 0xd2, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *groups_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_groups_png = new wxImage(); + if (!img_groups_png || !img_groups_png->IsOk()) + { + wxMemoryInputStream img_groups_pngIS(groups_png_data, sizeof(groups_png_data)); + img_groups_png->LoadFile(img_groups_pngIS, wxBITMAP_TYPE_PNG); + } + return img_groups_png; +} +#define groups_png_img groups_png_img() + +static wxBitmap *groups_png_bmp() +{ + static wxBitmap *bmp_groups_png; + if (!bmp_groups_png || !bmp_groups_png->IsOk()) + bmp_groups_png = new wxBitmap(*groups_png_img); + return bmp_groups_png; +} +#define groups_png_bmp groups_png_bmp() + +static wxIcon *groups_png_ico() +{ + static wxIcon *ico_groups_png; + if (!ico_groups_png || !ico_groups_png->IsOk()) + { + ico_groups_png = new wxIcon(); + ico_groups_png->CopyFromBitmap(*groups_png_bmp); + } + return ico_groups_png; +} +#define groups_png_ico groups_png_ico() + +#endif // GROUPS_PNG_H diff --git a/include/images/help.png b/include/images/help.png new file mode 100644 index 0000000..5d9805f Binary files /dev/null and b/include/images/help.png differ diff --git a/include/images/help.pngc b/include/images/help.pngc new file mode 100644 index 0000000..1d4b8c2 --- /dev/null +++ b/include/images/help.pngc @@ -0,0 +1,126 @@ +#ifndef HELP_PNG_H +#define HELP_PNG_H + +static const unsigned char help_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x17, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb8, 0xc2, 0x8e, 0xa0, +0xb5, 0x4c, 0x94, 0xae, 0x2b, 0xa8, 0xb9, 0x62, +0xc0, 0xc7, 0xa4, 0xc5, 0xca, 0xb1, 0xac, 0xbc, +0x6d, 0xb7, 0xcc, 0x5e, 0xd7, 0xe9, 0x85, 0xe4, +0xf7, 0x8f, 0xe2, 0xf6, 0x8b, 0xe3, 0xf7, 0x8f, +0xcb, 0xdf, 0x78, 0xaa, 0xc2, 0x4c, 0xad, 0xbc, +0x6f, 0xcd, 0xce, 0xc7, 0xc8, 0xdb, 0x78, 0xe3, +0xf7, 0x87, 0xde, 0xf5, 0x74, 0xdb, 0xf4, 0x6e, +0xda, 0xf4, 0x6b, 0xda, 0xf3, 0x6c, 0xdb, 0xf4, +0x72, 0xdf, 0xf5, 0x84, 0xbb, 0xd0, 0x63, 0xab, +0xc2, 0x4d, 0xe3, 0xf7, 0x8a, 0xdd, 0xf4, 0x70, +0xdc, 0xf4, 0x71, 0xde, 0xf5, 0x7c, 0xdf, 0xf5, +0x81, 0xdc, 0xf4, 0x76, 0xd8, 0xf2, 0x69, 0xd7, +0xf2, 0x67, 0xdf, 0xf4, 0x86, 0x9f, 0xb8, 0x3b, +0xc8, 0xcb, 0xba, 0xce, 0xe0, 0x80, 0xe1, 0xf6, +0x82, 0xdc, 0xf4, 0x70, 0xdf, 0xf5, 0x7e, 0xb6, +0xcc, 0x5b, 0xbe, 0xd4, 0x64, 0xd9, 0xf3, 0x6f, +0xd5, 0xf1, 0x61, 0xda, 0xf3, 0x76, 0xb4, 0xcb, +0x5a, 0xc6, 0xda, 0x73, 0xe4, 0xf7, 0x92, 0xdc, +0xed, 0x91, 0x9c, 0xb3, 0x41, 0xb9, 0xd0, 0x5e, +0xd8, 0xf2, 0x6e, 0xd4, 0xf1, 0x60, 0xd9, 0xf3, +0x75, 0xb5, 0xcb, 0x5b, 0xdc, 0xf3, 0x7c, 0xd5, +0xf1, 0x63, 0xd4, 0xf2, 0x63, 0xd8, 0xef, 0x7e, +0x9f, 0xb8, 0x3a, 0xd5, 0xf1, 0x64, 0xda, 0xf3, +0x7b, 0xb4, 0xcb, 0x59, 0xb1, 0xbe, 0x7a, 0xaa, +0xc1, 0x4b, 0xde, 0xf4, 0x81, 0xdb, 0xf3, 0x7e, +0xa9, 0xc1, 0x4a, 0xca, 0xde, 0x78, 0xd8, 0xf2, +0x6d, 0xd3, 0xf1, 0x5f, 0xd8, 0xf2, 0x75, 0xa4, +0xbc, 0x42, 0xa4, 0xb7, 0x57, 0xd0, 0xe4, 0x82, +0xdd, 0xf5, 0x86, 0xdc, 0xf3, 0x81, 0xd3, 0xe8, +0x85, 0xb5, 0xc1, 0x85, 0xd9, 0xec, 0x8f, 0xdb, +0xf3, 0x7f, 0xda, 0xf3, 0x7e, 0xd8, 0xec, 0x8c, +0xd3, 0xeb, 0x79, 0xd0, 0xef, 0x5c, 0xcf, 0xef, +0x5b, 0xd1, 0xea, 0x76, 0xd8, 0xec, 0x8d, 0xd9, +0xf3, 0x7d, 0xd9, 0xf2, 0x7c, 0xd7, 0xec, 0x8a, +0x12, 0x0e, 0x8d, 0x50, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xab, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x00, 0x02, 0x46, 0x26, 0x66, 0x66, +0x66, 0x16, 0x56, 0x06, 0x28, 0x60, 0x63, 0xe7, +0xe0, 0xe4, 0xe2, 0xe6, 0xe1, 0xe5, 0xe3, 0x17, +0x80, 0x08, 0xb0, 0x0b, 0x0a, 0x09, 0x8b, 0x88, +0x8a, 0x89, 0x4b, 0x48, 0xf2, 0x83, 0xf9, 0xac, +0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, +0x4a, 0xca, 0x2a, 0xaa, 0x20, 0x01, 0x16, 0x35, +0x75, 0x0d, 0x4d, 0x2d, 0x66, 0x6d, 0x1d, 0x5d, +0x3d, 0x7d, 0x46, 0xb0, 0x89, 0x1c, 0x06, 0x86, +0x46, 0xc6, 0xfc, 0x26, 0xa6, 0x66, 0xe6, 0x10, +0x01, 0x06, 0x46, 0x76, 0x66, 0x63, 0x7e, 0x0b, +0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x55, 0x98, 0x45, +0xfc, 0x92, 0x96, 0x76, 0xd6, 0xf6, 0x0e, 0x8e, +0x30, 0x3e, 0xab, 0x93, 0xb3, 0x95, 0xb5, 0x8b, +0x2b, 0x3f, 0x8c, 0xcf, 0xc0, 0xe2, 0xe6, 0xee, +0xe1, 0xe9, 0x85, 0xe0, 0x33, 0x78, 0xfb, 0xf8, +0xfa, 0xf9, 0x33, 0x21, 0xf8, 0x0c, 0x01, 0xc6, +0xcc, 0xcc, 0xc6, 0x01, 0x48, 0x02, 0xc6, 0x81, +0x41, 0xc1, 0x21, 0xc6, 0xc8, 0x02, 0xa1, 0x61, +0xe1, 0x11, 0x28, 0x02, 0x91, 0x51, 0xd1, 0x31, +0xc6, 0x38, 0xcc, 0x00, 0x00, 0x65, 0xab, 0x15, +0xce, 0xf3, 0x3a, 0x85, 0xbb, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x31, 0x37, 0x54, 0x31, 0x34, 0x3a, 0x32, +0x34, 0x3a, 0x31, 0x37, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0xe0, 0xbb, 0x7b, 0xf6, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *help_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_help_png = new wxImage(); + if (!img_help_png || !img_help_png->IsOk()) + { + wxMemoryInputStream img_help_pngIS(help_png_data, sizeof(help_png_data)); + img_help_png->LoadFile(img_help_pngIS, wxBITMAP_TYPE_PNG); + } + return img_help_png; +} +#define help_png_img help_png_img() + +static wxBitmap *help_png_bmp() +{ + static wxBitmap *bmp_help_png; + if (!bmp_help_png || !bmp_help_png->IsOk()) + bmp_help_png = new wxBitmap(*help_png_img); + return bmp_help_png; +} +#define help_png_bmp help_png_bmp() + +static wxIcon *help_png_ico() +{ + static wxIcon *ico_help_png; + if (!ico_help_png || !ico_help_png->IsOk()) + { + ico_help_png = new wxIcon(); + ico_help_png->CopyFromBitmap(*help_png_bmp); + } + return ico_help_png; +} +#define help_png_ico help_png_ico() + +#endif // HELP_PNG_H diff --git a/include/images/help2.png b/include/images/help2.png new file mode 100644 index 0000000..ff6d4d0 Binary files /dev/null and b/include/images/help2.png differ diff --git a/include/images/help2.pngc b/include/images/help2.pngc new file mode 100644 index 0000000..f8f0ce5 --- /dev/null +++ b/include/images/help2.pngc @@ -0,0 +1,163 @@ +#ifndef HELP2_PNG_H +#define HELP2_PNG_H + +static const unsigned char help2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc4, 0xca, 0xa0, 0xb7, +0xc2, 0x80, 0xa1, 0xb6, 0x4b, 0x94, 0xae, 0x2b, +0xae, 0xbd, 0x6b, 0xd1, 0xd2, 0xc2, 0xbc, 0xc5, +0x8d, 0xae, 0xc3, 0x5a, 0xc2, 0xd2, 0x7d, 0xdd, +0xeb, 0xa0, 0xeb, 0xf9, 0xaa, 0xe8, 0xf8, 0xa2, +0xeb, 0xf9, 0xad, 0xcc, 0xdc, 0x89, 0xc1, 0xd2, +0x7c, 0xaf, 0xbe, 0x6d, 0xa7, 0xbe, 0x4e, 0xde, +0xec, 0xa3, 0xe8, 0xf8, 0x9c, 0xe3, 0xf6, 0x88, +0xdf, 0xf5, 0x7a, 0xdc, 0xf4, 0x6e, 0xdb, 0xf4, +0x6b, 0xda, 0xf4, 0x6b, 0xda, 0xf4, 0x6a, 0xd9, +0xf3, 0x6e, 0xe1, 0xf6, 0x8a, 0xea, 0xf9, 0xa7, +0xa5, 0xb8, 0x56, 0xc0, 0xc8, 0x98, 0xb3, 0xc0, +0x78, 0xe1, 0xf6, 0x7d, 0xdc, 0xf4, 0x6d, 0xdb, +0xf4, 0x6c, 0xd9, 0xf3, 0x69, 0xd8, 0xf3, 0x67, +0xe1, 0xf5, 0x8a, 0xd8, 0xe6, 0x9e, 0xc4, 0xca, +0xa2, 0xc8, 0xcc, 0xac, 0xa1, 0xb8, 0x42, 0xe7, +0xf5, 0xa9, 0xd7, 0xf2, 0x65, 0xd7, 0xf2, 0x67, +0xde, 0xf5, 0x82, 0xd3, 0xe1, 0x98, 0xaa, 0xbb, +0x60, 0xce, 0xdd, 0x8f, 0xe3, 0xf7, 0x87, 0xd6, +0xf2, 0x63, 0xd5, 0xf2, 0x62, 0xd6, 0xf1, 0x66, +0xe2, 0xf6, 0x97, 0xa7, 0xbd, 0x4d, 0xd1, 0xd1, +0xc0, 0x9a, 0xb3, 0x37, 0xdc, 0xf5, 0x72, 0xe0, +0xf5, 0x86, 0xe4, 0xf7, 0x9a, 0xe5, 0xf7, 0x9e, +0xe2, 0xf6, 0x8d, 0xdb, 0xf3, 0x74, 0xd5, 0xf1, +0x61, 0xd4, 0xf1, 0x60, 0xdd, 0xf4, 0x7f, 0xc7, +0xd7, 0x87, 0xb2, 0xc0, 0x76, 0xe4, 0xf6, 0x8e, +0xe4, 0xf6, 0x95, 0xc1, 0xd2, 0x7b, 0xdc, 0xed, +0x91, 0xd4, 0xf1, 0x5f, 0xda, 0xf3, 0x77, 0xcc, +0xdc, 0x8d, 0xcf, 0xdd, 0x93, 0xe0, 0xf5, 0x83, +0xc0, 0xd2, 0x77, 0xbf, 0xd1, 0x73, 0xdb, 0xf4, +0x78, 0xd3, 0xf1, 0x5e, 0xd9, 0xf3, 0x77, 0xbb, +0xcd, 0x71, 0xee, 0xfa, 0xb9, 0xe7, 0xf7, 0xa1, +0xee, 0xf9, 0xbf, 0xd3, 0xe5, 0x8e, 0xd9, 0xf2, +0x70, 0xde, 0xf4, 0x86, 0xb7, 0xc3, 0x82, 0xd1, +0xe1, 0x90, 0xd5, 0xf1, 0x65, 0xd2, 0xf1, 0x5e, +0xd7, 0xf2, 0x6d, 0xdf, 0xee, 0x9f, 0xdc, 0xf3, +0x7e, 0xe0, 0xf2, 0x9a, 0xd5, 0xf1, 0x62, 0xd3, +0xf1, 0x60, 0xe1, 0xf2, 0x9e, 0xe0, 0xf5, 0x90, +0xd7, 0xf2, 0x6a, 0xd4, 0xf2, 0x64, 0xda, 0xea, +0x9c, 0xc6, 0xd7, 0x81, 0xd2, 0xe1, 0x94, 0xdb, +0xf3, 0x7a, 0xcd, 0xcf, 0xb8, 0x9d, 0xb3, 0x40, +0xdf, 0xee, 0xa0, 0xd2, 0xf1, 0x5d, 0xd3, 0xf0, +0x61, 0xdd, 0xf1, 0x91, 0xe6, 0xf1, 0xbd, 0xe3, +0xf6, 0x99, 0xe0, 0xec, 0xb1, 0xcc, 0xcf, 0xb6, +0xe1, 0xf5, 0x96, 0xee, 0xf9, 0xc4, 0xd0, 0xf0, +0x59, 0xcf, 0xef, 0x58, 0xcf, 0xef, 0x57, 0xce, +0xef, 0x56, 0xe0, 0xf5, 0x95, 0xe0, 0xf4, 0x94, +0xdf, 0xf5, 0x8e, 0xcd, 0xee, 0x55, 0xdf, 0xf4, +0x93, 0x2e, 0x28, 0xbb, 0x78, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0x6a, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x63, 0x60, 0xa0, 0x26, 0x60, 0x64, 0x62, +0x66, 0x01, 0x01, 0x56, 0x26, 0x36, 0x6c, 0xd2, +0xec, 0xcc, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0x3c, +0x3c, 0xbc, 0x7c, 0xfc, 0x2c, 0x02, 0x98, 0x4a, +0x04, 0x04, 0x85, 0x84, 0x45, 0x44, 0xc5, 0xc4, +0x25, 0x24, 0xa5, 0x44, 0xa5, 0x65, 0xf8, 0x65, +0xe5, 0xd0, 0xe4, 0xe5, 0x05, 0xb9, 0x15, 0xc4, +0x14, 0x95, 0x80, 0xf2, 0xca, 0xca, 0x2a, 0x2a, +0x52, 0xaa, 0x6a, 0xb2, 0xea, 0x28, 0xf2, 0x1a, +0x9a, 0x5a, 0x0a, 0x8a, 0x70, 0x79, 0x6d, 0x6d, +0x1d, 0x5d, 0x3d, 0x7d, 0x14, 0x05, 0xac, 0x06, +0x86, 0x62, 0x48, 0xf2, 0x46, 0xc6, 0x26, 0xa6, +0x66, 0x1a, 0x48, 0xf2, 0xe6, 0x16, 0x32, 0x96, +0x20, 0x79, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, +0xa0, 0xbc, 0xbd, 0x83, 0xa3, 0x93, 0x33, 0x92, +0x02, 0x26, 0x4e, 0x17, 0xb0, 0xbc, 0xab, 0x1b, +0x0b, 0x8b, 0xa0, 0xbb, 0x14, 0x50, 0xde, 0xc3, +0xd3, 0x8b, 0x15, 0xd9, 0x06, 0x6f, 0x11, 0x90, +0xf9, 0x3e, 0xbe, 0x40, 0xef, 0x31, 0xf9, 0xf9, +0x03, 0xe5, 0x03, 0x02, 0x51, 0x14, 0xb0, 0x07, +0x05, 0x03, 0x03, 0x20, 0x24, 0x54, 0x50, 0x83, +0x41, 0x5d, 0x36, 0x2c, 0x1c, 0x28, 0x1f, 0x10, +0xe1, 0xc6, 0x84, 0x12, 0x0a, 0xe0, 0x20, 0x64, +0x11, 0x60, 0x88, 0xb4, 0x88, 0xd2, 0x8d, 0xf6, +0x08, 0x88, 0x89, 0x8d, 0xb3, 0x30, 0xc7, 0x12, +0x9a, 0x6c, 0x02, 0x82, 0x71, 0xf1, 0x60, 0xf9, +0x04, 0xb3, 0x48, 0xac, 0xf2, 0xfc, 0xd6, 0xe1, +0x89, 0x1e, 0x01, 0x49, 0xe1, 0xc9, 0x66, 0xf2, +0xd8, 0xa2, 0x43, 0x80, 0x3f, 0x25, 0x15, 0x68, +0x7f, 0x5a, 0x7c, 0xba, 0x26, 0x56, 0x79, 0x46, +0x0e, 0x6b, 0xb0, 0x7c, 0x44, 0x06, 0x33, 0x3b, +0xd6, 0xe8, 0xd6, 0xcf, 0xf4, 0x04, 0xca, 0xc7, +0x64, 0x65, 0x08, 0x64, 0x63, 0x4f, 0x0f, 0x39, +0xb9, 0xa9, 0x1e, 0x01, 0x79, 0xf9, 0x05, 0x16, +0x38, 0xe4, 0x19, 0x72, 0x0a, 0x43, 0x8a, 0x8a, +0x8a, 0x6c, 0x8a, 0x99, 0x71, 0xc8, 0x33, 0x44, +0xe6, 0x80, 0x03, 0x03, 0x87, 0x03, 0x88, 0x01, +0xd0, 0xe0, 0x04, 0x86, 0x27, 0x76, 0x50, 0xa2, +0x19, 0x6a, 0x6a, 0x6a, 0x5a, 0x5a, 0x5a, 0xc6, +0x82, 0x53, 0x41, 0x4a, 0x79, 0x79, 0x45, 0x65, +0x55, 0x35, 0x3e, 0x05, 0x40, 0xf9, 0xaa, 0x1a, +0xdc, 0x0a, 0x6a, 0x41, 0xf2, 0x75, 0xf8, 0x14, +0x80, 0xe4, 0xeb, 0xea, 0x71, 0x2b, 0x08, 0xad, +0xae, 0xae, 0xa9, 0xa9, 0xc7, 0xe9, 0x48, 0x82, +0xde, 0x24, 0x13, 0x00, 0x00, 0x9e, 0x18, 0x4d, +0x38, 0xc6, 0x7b, 0x47, 0xd7, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *help2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_help2_png = new wxImage(); + if (!img_help2_png || !img_help2_png->IsOk()) + { + wxMemoryInputStream img_help2_pngIS(help2_png_data, sizeof(help2_png_data)); + img_help2_png->LoadFile(img_help2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_help2_png; +} +#define help2_png_img help2_png_img() + +static wxBitmap *help2_png_bmp() +{ + static wxBitmap *bmp_help2_png; + if (!bmp_help2_png || !bmp_help2_png->IsOk()) + bmp_help2_png = new wxBitmap(*help2_png_img); + return bmp_help2_png; +} +#define help2_png_bmp help2_png_bmp() + +static wxIcon *help2_png_ico() +{ + static wxIcon *ico_help2_png; + if (!ico_help2_png || !ico_help2_png->IsOk()) + { + ico_help2_png = new wxIcon(); + ico_help2_png->CopyFromBitmap(*help2_png_bmp); + } + return ico_help2_png; +} +#define help2_png_ico help2_png_ico() + +#endif // HELP2_PNG_H diff --git a/include/images/hint.png b/include/images/hint.png new file mode 100644 index 0000000..0ff0561 Binary files /dev/null and b/include/images/hint.png differ diff --git a/include/images/hint.pngc b/include/images/hint.pngc new file mode 100644 index 0000000..57e8cee --- /dev/null +++ b/include/images/hint.pngc @@ -0,0 +1,188 @@ +#ifndef HINT_PNG_H +#define HINT_PNG_H + +static const unsigned char hint_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd0, 0xbb, 0xbb, 0xcf, +0xa3, 0xa3, 0xce, 0x8f, 0x8f, 0xd0, 0x80, 0x7e, +0xc1, 0xc1, 0xc1, 0xb0, 0xae, 0xae, 0xb8, 0x8e, +0x8e, 0xd9, 0x93, 0x90, 0xe3, 0xa9, 0xa7, 0xed, +0xbc, 0xba, 0xf4, 0xcd, 0xc9, 0xf5, 0xce, 0xc4, +0xec, 0xba, 0xb4, 0xd7, 0x8f, 0x8c, 0xc8, 0xc8, +0xc8, 0xb0, 0xb0, 0xb0, 0x99, 0x99, 0x99, 0x9f, +0x90, 0x90, 0xd1, 0x82, 0x81, 0xf7, 0xd3, 0xcf, +0xf7, 0xd1, 0xcb, 0xf6, 0xd0, 0xc7, 0xf5, 0xcd, +0xc1, 0xf0, 0xc6, 0xb9, 0xe1, 0xa2, 0x99, 0xb4, +0xb4, 0xb4, 0x89, 0x89, 0x89, 0xd1, 0xc8, 0xc8, +0xe2, 0xb2, 0xb1, 0xf8, 0xd5, 0xd2, 0xf4, 0xca, +0xbc, 0xe4, 0xa8, 0x9b, 0xa1, 0xa1, 0xa1, 0xac, +0xac, 0xad, 0xd5, 0xd5, 0xd5, 0xf8, 0xf8, 0xf8, +0xf3, 0xc8, 0xb7, 0xf3, 0xc6, 0xb2, 0xaa, 0xa9, +0xaa, 0xa6, 0xa6, 0xa6, 0xc6, 0xc6, 0xc6, 0xcf, +0xcf, 0xcf, 0xb9, 0xb9, 0xb9, 0xee, 0xee, 0xee, +0xf1, 0xf1, 0xf1, 0xe5, 0xc9, 0xc9, 0xdd, 0x9a, +0x9a, 0xf2, 0xc3, 0xad, 0x9c, 0x9c, 0x9c, 0xeb, +0xeb, 0xeb, 0xcd, 0x7d, 0x7d, 0xe8, 0xce, 0xcd, +0xab, 0xad, 0xb2, 0x78, 0x92, 0x9c, 0xe8, 0xc8, +0xbf, 0xe5, 0xc4, 0xba, 0xa9, 0xa6, 0xa3, 0x77, +0x8f, 0x97, 0xe2, 0xbc, 0xa8, 0xe5, 0xe5, 0xe5, +0xdf, 0xc8, 0xc8, 0x6f, 0x92, 0xa0, 0xaf, 0xc3, +0xca, 0xe5, 0xeb, 0xee, 0xe1, 0xb9, 0xa2, 0xd7, +0x8c, 0x83, 0xdd, 0xdd, 0xdd, 0xd5, 0xab, 0xab, +0xa7, 0xbd, 0xc6, 0xee, 0xf8, 0xfc, 0xa9, 0xa8, +0xa7, 0xa7, 0xa1, 0x9b, 0xe0, 0x9d, 0x8a, 0x80, +0x80, 0x80, 0xd0, 0x96, 0x96, 0xc2, 0xde, 0xe8, +0x80, 0x8f, 0x95, 0xe5, 0xa8, 0x92, 0x83, 0x83, +0x83, 0xcc, 0xcc, 0xcc, 0xcd, 0x85, 0x85, 0xf2, +0xc8, 0xc5, 0xa9, 0xd5, 0xe4, 0x90, 0xb3, 0xbf, +0x6e, 0x89, 0x92, 0xea, 0xb1, 0x96, 0xbc, 0xbc, +0xbc, 0x7d, 0xb0, 0xc2, 0x9a, 0xd9, 0xef, 0xee, +0xb8, 0x97, 0xe8, 0xc9, 0xc5, 0x62, 0x8d, 0x9e, +0x70, 0xab, 0xc0, 0x7b, 0xc3, 0xdd, 0xe5, 0xbf, +0xaf, 0xe0, 0xb5, 0x99, 0xed, 0xb7, 0x93, 0x90, +0x8e, 0x8e, 0xf1, 0xc6, 0xc0, 0xea, 0xaf, 0x91, +0xc6, 0x8b, 0x8b, 0xd7, 0xb6, 0xaa, 0xec, 0xbe, +0xa7, 0xd1, 0xae, 0x9c, 0xda, 0xb2, 0x9b, 0xef, +0xba, 0x9b, 0xe4, 0xa5, 0x8b, 0xb4, 0x9e, 0x9a, +0xaf, 0x99, 0x8d, 0x8c, 0x86, 0x82, 0xb5, 0x9b, +0x8a, 0xde, 0x99, 0x86, 0x97, 0x80, 0x80, 0xe1, +0xb0, 0x8f, 0x92, 0x92, 0x92, 0xaf, 0x92, 0x85, +0xa2, 0x96, 0x96, 0xbe, 0xa3, 0x95, 0xa7, 0x95, +0x8c, 0xd2, 0xaa, 0x91, 0xaf, 0x91, 0x8d, 0xa1, +0x89, 0x81, 0xc5, 0xbc, 0xbc, 0xd0, 0xc1, 0xc1, +0xdf, 0x9e, 0x93, 0xc2, 0x9f, 0x9f, 0xe2, 0xe2, +0xe2, 0xe0, 0xd4, 0xa9, 0x6a, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x37, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x95, 0x93, 0xeb, 0x53, 0xda, 0x40, 0x14, +0xc5, 0xa3, 0x12, 0x79, 0x88, 0x4d, 0x22, 0x20, +0x35, 0x01, 0x25, 0x84, 0x4a, 0xc8, 0x82, 0x25, +0x89, 0x84, 0x87, 0xf1, 0x51, 0x91, 0x82, 0xa8, +0x0d, 0x54, 0x6d, 0x2c, 0x55, 0x11, 0x5a, 0xa9, +0x58, 0x2c, 0xda, 0x58, 0xa0, 0xd5, 0xb6, 0xff, +0x7a, 0x97, 0x84, 0x0e, 0xca, 0x80, 0x33, 0x3d, +0x5f, 0xce, 0xcc, 0xfe, 0xce, 0xce, 0xde, 0xb9, +0x77, 0x2f, 0x82, 0xfc, 0x8f, 0xc6, 0xc6, 0x27, +0x4c, 0xa6, 0x89, 0xf1, 0xb1, 0xe1, 0x14, 0x9d, +0x34, 0x5b, 0xac, 0xb6, 0x29, 0xfb, 0xb4, 0xf5, +0x99, 0x79, 0x12, 0x1d, 0xa4, 0x18, 0x4e, 0xcc, +0x38, 0xac, 0x53, 0x4e, 0xa7, 0x6b, 0xd6, 0xee, +0x7e, 0x3e, 0xe7, 0x98, 0x21, 0x70, 0xec, 0x21, +0x27, 0x29, 0xdc, 0xe3, 0xf0, 0xce, 0xcf, 0x3b, +0x5d, 0xdd, 0xc0, 0xc2, 0x82, 0xcf, 0xe1, 0xc1, +0x29, 0xb2, 0x7f, 0x9d, 0xf6, 0x33, 0x01, 0xaf, +0xb5, 0xcf, 0x5f, 0x2c, 0xce, 0x79, 0x03, 0x4c, +0x90, 0x0d, 0x19, 0x9c, 0x43, 0x41, 0x38, 0xb2, +0xf4, 0x12, 0x72, 0xe7, 0x3f, 0x1e, 0x8d, 0x5a, +0x96, 0x22, 0x61, 0x80, 0x72, 0x7a, 0x00, 0xf0, +0x82, 0x20, 0x88, 0xb6, 0xe5, 0x98, 0x24, 0xc5, +0xe2, 0x6e, 0x77, 0x22, 0x29, 0xa5, 0x92, 0x2b, +0x3e, 0x11, 0x1e, 0xf2, 0x40, 0x0f, 0x10, 0x21, +0x59, 0x5e, 0xb5, 0x2c, 0xaf, 0xad, 0x6f, 0x6c, +0xac, 0xaf, 0x25, 0x12, 0x86, 0xbf, 0xda, 0x5c, +0x95, 0xe5, 0x10, 0xa1, 0x07, 0x28, 0x2e, 0x9d, +0xde, 0xb2, 0xc6, 0x32, 0xaf, 0xa1, 0x32, 0xc1, +0xac, 0xe1, 0xb9, 0xed, 0xad, 0x74, 0x9a, 0xa3, +0xf4, 0x40, 0x9e, 0x61, 0x98, 0x1d, 0x9b, 0xb4, +0x9b, 0xd9, 0xdb, 0xcb, 0xec, 0x4a, 0x3d, 0x4f, +0xbd, 0xd9, 0x81, 0xc7, 0x8a, 0x1e, 0x50, 0x0a, +0x1c, 0x57, 0x7c, 0x2b, 0xed, 0x1f, 0x1c, 0x1e, +0x1e, 0xec, 0x4b, 0x3d, 0x4f, 0xbd, 0x2b, 0x72, +0x5c, 0xc1, 0x08, 0x50, 0x2a, 0x86, 0x89, 0xae, +0xd8, 0xd1, 0x7b, 0xa8, 0xa3, 0x64, 0xd2, 0xf0, +0x5c, 0x49, 0xc4, 0x30, 0xd5, 0x78, 0x82, 0xf0, +0xa3, 0xa8, 0xe8, 0xfa, 0x70, 0x7c, 0x72, 0x7a, +0x7a, 0x72, 0x5c, 0x2e, 0x1b, 0x7e, 0x56, 0x11, +0x51, 0xd4, 0x6f, 0x14, 0x09, 0xaa, 0x00, 0x14, +0x3f, 0xce, 0xc6, 0x83, 0x92, 0x94, 0x2d, 0x2f, +0x46, 0x57, 0x72, 0xa9, 0x54, 0xee, 0xac, 0xf4, +0xa9, 0x08, 0x20, 0xe8, 0x35, 0x8a, 0xc0, 0xcf, +0xa7, 0xed, 0x70, 0x06, 0xb5, 0x1a, 0x6c, 0xd1, +0xe7, 0x8b, 0xfa, 0xe5, 0x65, 0xa9, 0xf4, 0xe5, +0x1c, 0x27, 0x7a, 0x8d, 0x82, 0xad, 0xae, 0x9a, +0xad, 0xf6, 0x78, 0x43, 0xe1, 0x79, 0xa5, 0x71, +0xa5, 0xd0, 0xc4, 0xd7, 0x66, 0xa9, 0x72, 0x6d, +0xae, 0xd2, 0xfd, 0x79, 0x91, 0x37, 0x96, 0x9a, +0x42, 0xca, 0x82, 0x20, 0xd3, 0x24, 0xec, 0x60, +0x9a, 0x6d, 0x7e, 0xdb, 0xbc, 0x21, 0x1f, 0x8e, +0x13, 0x13, 0xf3, 0x00, 0x63, 0x35, 0x82, 0x26, +0x49, 0x5a, 0xd3, 0xfc, 0x85, 0xec, 0xad, 0xf8, +0x68, 0xdc, 0x08, 0xf2, 0x9d, 0x27, 0xf2, 0xad, +0xda, 0x45, 0xab, 0xdd, 0x6e, 0x75, 0x3a, 0xf0, +0x19, 0xad, 0xf1, 0x98, 0x17, 0xf2, 0xca, 0x8f, +0x32, 0x2c, 0xb0, 0x55, 0xbd, 0xaa, 0x97, 0x2a, +0x95, 0xce, 0x4f, 0x25, 0xcf, 0x0d, 0x24, 0xee, +0x1c, 0xbe, 0x68, 0xbd, 0xad, 0xca, 0x58, 0xb5, +0x59, 0xa9, 0x6c, 0x9b, 0xee, 0x06, 0x38, 0xd4, +0xbd, 0xe9, 0x57, 0xbb, 0x10, 0x08, 0x04, 0x22, +0xf4, 0xed, 0xb5, 0xe9, 0x7e, 0xd8, 0xaf, 0xf5, +0x34, 0xd8, 0x70, 0x57, 0x82, 0xf6, 0xdb, 0x33, +0xfc, 0x5f, 0x13, 0xa1, 0x3f, 0xba, 0x00, 0x3d, +0x62, 0x2d, 0x68, 0x9c, 0xd1, 0x85, 0x8f, 0x0a, +0xa0, 0x14, 0x8a, 0x75, 0xa5, 0xa9, 0xa3, 0x36, +0x8b, 0xad, 0x02, 0x55, 0x55, 0x59, 0x1e, 0x19, +0x29, 0x5a, 0xc3, 0xf1, 0xac, 0xa2, 0x8e, 0x0e, +0x20, 0x1a, 0x4f, 0x2b, 0xfe, 0x27, 0x38, 0x5c, +0x31, 0x25, 0x88, 0x3c, 0x29, 0x30, 0x30, 0x23, +0xe4, 0x2f, 0x35, 0x6e, 0x7b, 0xa7, 0xc9, 0x5c, +0x2f, 0x74, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *hint_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_hint_png = new wxImage(); + if (!img_hint_png || !img_hint_png->IsOk()) + { + wxMemoryInputStream img_hint_pngIS(hint_png_data, sizeof(hint_png_data)); + img_hint_png->LoadFile(img_hint_pngIS, wxBITMAP_TYPE_PNG); + } + return img_hint_png; +} +#define hint_png_img hint_png_img() + +static wxBitmap *hint_png_bmp() +{ + static wxBitmap *bmp_hint_png; + if (!bmp_hint_png || !bmp_hint_png->IsOk()) + bmp_hint_png = new wxBitmap(*hint_png_img); + return bmp_hint_png; +} +#define hint_png_bmp hint_png_bmp() + +static wxIcon *hint_png_ico() +{ + static wxIcon *ico_hint_png; + if (!ico_hint_png || !ico_hint_png->IsOk()) + { + ico_hint_png = new wxIcon(); + ico_hint_png->CopyFromBitmap(*hint_png_bmp); + } + return ico_hint_png; +} +#define hint_png_ico hint_png_ico() + +#endif // HINT_PNG_H diff --git a/include/images/hint2.png b/include/images/hint2.png new file mode 100644 index 0000000..c36e3c2 Binary files /dev/null and b/include/images/hint2.png differ diff --git a/include/images/hint2.pngc b/include/images/hint2.pngc new file mode 100644 index 0000000..c17580b --- /dev/null +++ b/include/images/hint2.pngc @@ -0,0 +1,138 @@ +#ifndef HINT2_PNG_H +#define HINT2_PNG_H + +static const unsigned char hint2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x4a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xb0, +0xb0, 0xb0, 0xa2, 0x9a, 0x9a, 0xad, 0x84, 0x84, +0xc1, 0x7d, 0x7d, 0xb4, 0xb4, 0xb4, 0x8f, 0x8f, +0x8f, 0xb6, 0xab, 0xab, 0xd2, 0x83, 0x83, 0xe3, +0xa8, 0xa8, 0xf1, 0xc6, 0xc3, 0xf0, 0xc3, 0xbe, +0xe2, 0xa5, 0xa0, 0xd2, 0x82, 0x81, 0xa9, 0xa9, +0xa9, 0xaa, 0xaa, 0xaa, 0xdd, 0xdd, 0xdd, 0xe1, +0xb1, 0xb1, 0xe5, 0xad, 0xad, 0xf8, 0xd5, 0xd3, +0xf7, 0xd3, 0xce, 0xf6, 0xd0, 0xc7, 0xf5, 0xcd, +0xc0, 0xe3, 0xa6, 0x9d, 0xb5, 0xb5, 0xb5, 0xa7, +0xa7, 0xa7, 0xea, 0xea, 0xea, 0xe6, 0xcf, 0xcf, +0xa1, 0x8f, 0x96, 0x72, 0x90, 0x9d, 0xb1, 0xb0, +0xb4, 0xf2, 0xcf, 0xc8, 0xf1, 0xcb, 0xc1, 0xae, +0xaa, 0xa9, 0x71, 0x8e, 0x99, 0xa0, 0x8b, 0x8f, +0x97, 0x97, 0x97, 0xce, 0xce, 0xce, 0xf0, 0xf0, +0xf0, 0xa2, 0x9b, 0xa2, 0xa5, 0xbb, 0xc4, 0xec, +0xf0, 0xf2, 0xb0, 0xac, 0xae, 0xae, 0xab, 0xaa, +0x82, 0x82, 0x82, 0xe5, 0xe5, 0xe5, 0x6d, 0x88, +0x95, 0xc7, 0xe2, 0xec, 0x6a, 0x77, 0x7c, 0x71, +0x8f, 0x9a, 0xc5, 0xc5, 0xc5, 0xe3, 0xe3, 0xe3, +0x9a, 0x80, 0x87, 0x79, 0xaa, 0xbd, 0x92, 0xc9, +0xdd, 0x7a, 0xa1, 0xb0, 0xae, 0xaa, 0xa8, 0xaa, +0xa5, 0xa1, 0x7b, 0x9f, 0xad, 0x9e, 0x9e, 0x9e, +0xd3, 0xd3, 0xd3, 0xce, 0x90, 0x90, 0x93, 0x90, +0x92, 0x88, 0x88, 0x88, 0x9a, 0x9a, 0x9a, 0x95, +0x8d, 0x89, 0xa0, 0xa0, 0xa0, 0x93, 0x8c, 0x89, +0xb1, 0x91, 0x91, 0xa5, 0xa5, 0xa5, 0xec, 0xec, +0xec, 0xf1, 0xf1, 0xf1, 0xda, 0xda, 0xda, 0xe4, +0xe4, 0xe4, 0xe8, 0xe8, 0xe8, 0x9d, 0x9d, 0x9d, +0xb6, 0x93, 0x93, 0x92, 0x92, 0x92, 0xb7, 0xb7, +0xb7, 0x99, 0x99, 0x99, 0x91, 0x91, 0x91, 0xab, +0xab, 0xab, 0xcc, 0xcc, 0xcc, 0x83, 0x83, 0x83, +0x9a, 0x87, 0x87, 0xb6, 0x93, 0x8d, 0x81, 0x81, +0x81, 0xae, 0xae, 0xae, 0xa8, 0x94, 0x87, 0xc4, +0x93, 0x84, 0x9b, 0x87, 0x87, 0xcd, 0xcd, 0xcd, +0xd0, 0xc5, 0xc5, 0x9c, 0x80, 0x7f, 0xf8, 0xf8, +0xf8, 0xf2, 0xf2, 0xf2, 0xc0, 0x80, 0x7d, 0x85, +0x84, 0x84, 0xed, 0xed, 0xed, 0xbc, 0xbc, 0xbc, +0xa3, 0xa0, 0xa0, 0xa6, 0xa6, 0xa6, 0xa2, 0xa2, +0xa2, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xc1, +0xc1, 0xc1, 0xa1, 0xa1, 0xa1, 0xc0, 0xc0, 0xc0, +0xb3, 0xb3, 0xb3, 0xf9, 0x72, 0x45, 0xe7, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xdd, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x60, 0x60, 0x60, +0x64, 0x62, 0x66, 0x61, 0x65, 0x65, 0x61, 0x66, +0x62, 0x64, 0x00, 0x03, 0x36, 0x76, 0x0e, 0x4e, +0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x0e, 0x76, 0x36, +0x10, 0x9f, 0x5f, 0x40, 0x50, 0x48, 0x58, 0x44, +0x54, 0x4c, 0x5c, 0x42, 0x48, 0x50, 0x80, 0x9f, +0x81, 0x41, 0x52, 0x4a, 0x5a, 0x46, 0x56, 0x4e, +0x5e, 0x41, 0x51, 0x49, 0x59, 0x45, 0x46, 0x5a, +0x4a, 0x92, 0x41, 0x55, 0x4d, 0x5d, 0x43, 0x53, +0x4b, 0x53, 0x5b, 0x07, 0x48, 0x68, 0xa8, 0xab, +0xa9, 0x32, 0xe8, 0xea, 0x49, 0xeb, 0x1b, 0x18, +0x1a, 0x18, 0x29, 0x03, 0x09, 0x7d, 0x69, 0x3d, +0x5d, 0x06, 0x55, 0x63, 0x13, 0x53, 0x33, 0x73, +0x0b, 0x4b, 0x2b, 0x6b, 0x73, 0x33, 0x53, 0x13, +0x63, 0x55, 0x06, 0x49, 0x1b, 0x5b, 0x3b, 0x7b, +0x07, 0x47, 0x27, 0x07, 0x67, 0x07, 0x17, 0x3b, +0x5b, 0x1b, 0x49, 0xa0, 0x2d, 0x36, 0xae, 0x6e, +0xee, 0x1e, 0x9e, 0x5e, 0x1e, 0xde, 0x3e, 0xbe, +0x36, 0xfc, 0x60, 0x7b, 0xfd, 0xfc, 0x03, 0xfc, +0x02, 0x55, 0xfd, 0x1c, 0x25, 0xd9, 0x83, 0xc0, +0x0e, 0x0b, 0x0e, 0x09, 0x0d, 0x0b, 0x8f, 0x08, +0x8c, 0x8c, 0x8a, 0xd6, 0x8d, 0x81, 0x38, 0x35, +0x38, 0x36, 0x2e, 0x26, 0x3e, 0x21, 0x20, 0x31, +0x16, 0xca, 0x07, 0x82, 0x24, 0xbd, 0xe4, 0xe4, +0x94, 0x54, 0x06, 0x04, 0x48, 0x4b, 0xcf, 0xc8, +0x0c, 0xcc, 0x42, 0x12, 0x60, 0xb0, 0x61, 0xb3, +0xc9, 0x46, 0xe6, 0x33, 0xe4, 0x84, 0xe7, 0x42, +0x59, 0x00, 0x5b, 0xfe, 0x23, 0xd7, 0x88, 0xae, +0x4f, 0x49, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *hint2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_hint2_png = new wxImage(); + if (!img_hint2_png || !img_hint2_png->IsOk()) + { + wxMemoryInputStream img_hint2_pngIS(hint2_png_data, sizeof(hint2_png_data)); + img_hint2_png->LoadFile(img_hint2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_hint2_png; +} +#define hint2_png_img hint2_png_img() + +static wxBitmap *hint2_png_bmp() +{ + static wxBitmap *bmp_hint2_png; + if (!bmp_hint2_png || !bmp_hint2_png->IsOk()) + bmp_hint2_png = new wxBitmap(*hint2_png_img); + return bmp_hint2_png; +} +#define hint2_png_bmp hint2_png_bmp() + +static wxIcon *hint2_png_ico() +{ + static wxIcon *ico_hint2_png; + if (!ico_hint2_png || !ico_hint2_png->IsOk()) + { + ico_hint2_png = new wxIcon(); + ico_hint2_png->CopyFromBitmap(*hint2_png_bmp); + } + return ico_hint2_png; +} +#define hint2_png_ico hint2_png_ico() + +#endif // HINT2_PNG_H diff --git a/include/images/index.png b/include/images/index.png new file mode 100644 index 0000000..a239c12 Binary files /dev/null and b/include/images/index.png differ diff --git a/include/images/index.pngc b/include/images/index.pngc new file mode 100644 index 0000000..effe3a3 --- /dev/null +++ b/include/images/index.pngc @@ -0,0 +1,115 @@ +#ifndef INDEX_PNG_H +#define INDEX_PNG_H + +static const unsigned char index_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xed, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xab, 0xdf, 0x31, +0x7f, 0xd1, 0x29, 0x7c, 0xcb, 0x1f, 0x77, 0xc4, +0x33, 0x7f, 0xd1, 0x2c, 0x7d, 0xcd, 0x21, 0x78, +0xc6, 0x16, 0x73, 0xbf, 0x0b, 0x6e, 0xb8, 0x35, +0x7f, 0xd3, 0x88, 0xb4, 0xe5, 0xcb, 0xe7, 0xf6, +0xc8, 0xe5, 0xf5, 0xc5, 0xe3, 0xf4, 0xc1, 0xe0, +0xf3, 0xbd, 0xdd, 0xf2, 0xb8, 0xd9, 0xf1, 0xb3, +0xd6, 0xef, 0xae, 0xd2, 0xee, 0xa9, 0xce, 0xec, +0xa4, 0xca, 0xeb, 0x50, 0x5c, 0x62, 0x4f, 0x5b, +0x62, 0x4e, 0x5a, 0x61, 0x4c, 0x58, 0x61, 0xb9, +0xda, 0xf1, 0x48, 0x56, 0x60, 0x46, 0x54, 0x5f, +0x44, 0x53, 0x5e, 0x42, 0x51, 0x5e, 0xa0, 0xc7, +0xe9, 0xc9, 0xe6, 0xf5, 0xc6, 0xe4, 0xf5, 0xc2, +0xe1, 0xf4, 0xbe, 0xde, 0xf2, 0xb4, 0xd7, 0xef, +0xaf, 0xd3, 0xee, 0xaa, 0xcf, 0xec, 0xa5, 0xcb, +0xeb, 0xa0, 0xc8, 0xea, 0x9c, 0xc5, 0xe8, 0x4e, +0x5a, 0x62, 0x4c, 0x59, 0x61, 0x4a, 0x58, 0x60, +0xb0, 0xd3, 0xee, 0x44, 0x53, 0x5f, 0x42, 0x52, +0x5e, 0x40, 0x50, 0x5e, 0x3e, 0x4f, 0x5d, 0x98, +0xc2, 0xe7, 0xc3, 0xe2, 0xf4, 0xbf, 0xdf, 0xf3, +0xba, 0xdb, 0xf1, 0xb6, 0xd8, 0xf0, 0xb0, 0xd4, +0xee, 0xab, 0xd0, 0xed, 0xa6, 0xcc, 0xeb, 0xa1, +0xc9, 0xea, 0x9d, 0xc5, 0xe9, 0x99, 0xc2, 0xe7, +0x95, 0xc0, 0xe6, 0x4b, 0x58, 0x60, 0x49, 0x56, +0x60, 0x47, 0x55, 0x60, 0x45, 0x54, 0x5f, 0xa7, +0xcd, 0xec, 0x41, 0x50, 0x5e, 0x3f, 0x4f, 0x5d, +0x99, 0xc3, 0xe7, 0xbc, 0xdc, 0xf2, 0xb7, 0xd9, +0xf0, 0xb2, 0xd5, 0xef, 0xad, 0xd1, 0xed, 0xa8, +0xcd, 0xec, 0xa3, 0xca, 0xea, 0x9e, 0xc6, 0xe9, +0x9a, 0xc3, 0xe8, 0x96, 0xc0, 0xe7, 0xec, 0xc6, +0xb1, 0x23, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7c, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x20, 0x02, 0x30, 0x32, 0x31, 0xb3, 0xa0, 0x08, +0xb0, 0xb2, 0xb1, 0x73, 0x70, 0x22, 0x0b, 0x70, +0x21, 0x00, 0x37, 0x98, 0xcf, 0xc3, 0xc3, 0xcb, +0xc7, 0x2f, 0x20, 0x28, 0x24, 0x2c, 0x22, 0xca, +0x05, 0x11, 0x10, 0x13, 0x97, 0x90, 0x94, 0x92, +0x96, 0x91, 0x95, 0x93, 0x87, 0x08, 0x28, 0x28, +0x2a, 0x29, 0x4b, 0xa9, 0xa8, 0xaa, 0xa9, 0x6b, +0x68, 0x42, 0x04, 0x14, 0xb5, 0xb4, 0x75, 0xa4, +0x75, 0xf5, 0xf4, 0x0d, 0x0c, 0x8d, 0x20, 0x02, +0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, +0xd6, 0x36, 0xb6, 0x10, 0x01, 0x13, 0x3b, 0x7b, +0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x08, 0x9f, +0x81, 0xcb, 0xcd, 0xdd, 0xc3, 0xd3, 0xcb, 0xdb, +0xc7, 0xd7, 0x0f, 0x62, 0x2b, 0x03, 0x37, 0xaa, +0x2b, 0xc8, 0x00, 0x00, 0x9b, 0xf4, 0x0e, 0x54, +0x27, 0x14, 0x92, 0xaf, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *index_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_index_png = new wxImage(); + if (!img_index_png || !img_index_png->IsOk()) + { + wxMemoryInputStream img_index_pngIS(index_png_data, sizeof(index_png_data)); + img_index_png->LoadFile(img_index_pngIS, wxBITMAP_TYPE_PNG); + } + return img_index_png; +} +#define index_png_img index_png_img() + +static wxBitmap *index_png_bmp() +{ + static wxBitmap *bmp_index_png; + if (!bmp_index_png || !bmp_index_png->IsOk()) + bmp_index_png = new wxBitmap(*index_png_img); + return bmp_index_png; +} +#define index_png_bmp index_png_bmp() + +static wxIcon *index_png_ico() +{ + static wxIcon *ico_index_png; + if (!ico_index_png || !ico_index_png->IsOk()) + { + ico_index_png = new wxIcon(); + ico_index_png->CopyFromBitmap(*index_png_bmp); + } + return ico_index_png; +} +#define index_png_ico index_png_ico() + +#endif // INDEX_PNG_H diff --git a/include/images/indexes.png b/include/images/indexes.png new file mode 100644 index 0000000..bb1513c Binary files /dev/null and b/include/images/indexes.png differ diff --git a/include/images/indexes.pngc b/include/images/indexes.pngc new file mode 100644 index 0000000..ed005b5 --- /dev/null +++ b/include/images/indexes.pngc @@ -0,0 +1,103 @@ +#ifndef INDEXES_PNG_H +#define INDEXES_PNG_H + +static const unsigned char indexes_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x9c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x89, 0xab, 0xdf, 0x31, +0x7f, 0xd1, 0x29, 0x7c, 0xcb, 0x1f, 0x77, 0xc4, +0x33, 0x7f, 0xd1, 0x2c, 0x7d, 0xcd, 0x21, 0x78, +0xc6, 0x16, 0x73, 0xbf, 0x0b, 0x6e, 0xb8, 0x88, +0xb4, 0xe5, 0x35, 0x7f, 0xd3, 0xcb, 0xe7, 0xf6, +0xc7, 0xe4, 0xf5, 0xc2, 0xe1, 0xf3, 0xbc, 0xdc, +0xf2, 0xb5, 0xd7, 0xf0, 0xae, 0xd2, 0xee, 0xa7, +0xcd, 0xec, 0xa0, 0xc8, 0xea, 0x72, 0xa9, 0xe1, +0xc8, 0xe6, 0xf5, 0xc5, 0xe3, 0xf4, 0xc0, 0xdf, +0xf3, 0x50, 0x5c, 0x62, 0x4e, 0x5a, 0x62, 0x4c, +0x58, 0x61, 0xb6, 0xd8, 0xf0, 0x46, 0x54, 0x5f, +0x43, 0x52, 0x5e, 0x40, 0x50, 0x5e, 0x9b, 0xc4, +0xe8, 0xc4, 0xe2, 0xf4, 0xbe, 0xde, 0xf2, 0xb8, +0xd9, 0xf0, 0xb1, 0xd4, 0xee, 0xa9, 0xcf, 0xec, +0xa3, 0xca, 0xea, 0x9c, 0xc5, 0xe8, 0x97, 0xc1, +0xe7, 0x4c, 0x59, 0x61, 0x4a, 0x57, 0x60, 0x47, +0x55, 0x60, 0xab, 0xd0, 0xed, 0x42, 0x51, 0x5e, +0x3f, 0x4f, 0x5d, 0xba, 0xdb, 0xf1, 0xb3, 0xd6, +0xef, 0xac, 0xd0, 0xed, 0xa5, 0xcb, 0xeb, 0x9e, +0xc6, 0xe9, 0x98, 0xc2, 0xe7, 0x8a, 0x75, 0x4e, +0x44, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x6f, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, +0x00, 0x8c, 0x4c, 0xcc, 0x2c, 0x28, 0x02, 0xac, +0x6c, 0xec, 0x1c, 0x9c, 0x48, 0x7c, 0x2e, 0x6e, +0x18, 0xe0, 0x82, 0x08, 0x70, 0xf3, 0xf0, 0xf0, +0xf2, 0xf1, 0x0b, 0x08, 0x0a, 0x09, 0x73, 0xc3, +0x04, 0x44, 0x50, 0xd5, 0x70, 0x8b, 0xa2, 0xa9, +0xe1, 0x16, 0x43, 0x53, 0xc3, 0x2d, 0x8e, 0xa6, +0x06, 0x68, 0x0b, 0x50, 0x8d, 0x84, 0xa4, 0x94, +0xb4, 0x8c, 0xac, 0x9c, 0x3c, 0x44, 0x13, 0x50, +0x8d, 0x82, 0xa2, 0x92, 0xb2, 0x8a, 0xaa, 0x9a, +0x3a, 0xc4, 0x26, 0xa0, 0x1a, 0x0d, 0x4d, 0x2d, +0x6d, 0x1d, 0x5d, 0x75, 0xb8, 0x5b, 0xc4, 0xf5, +0xf4, 0x0d, 0x0c, 0x8d, 0x8c, 0x61, 0x7c, 0xb8, +0x6b, 0xb9, 0x18, 0x88, 0x01, 0x00, 0x95, 0x17, +0x09, 0xf1, 0xd3, 0xde, 0x00, 0x00, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *indexes_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_indexes_png = new wxImage(); + if (!img_indexes_png || !img_indexes_png->IsOk()) + { + wxMemoryInputStream img_indexes_pngIS(indexes_png_data, sizeof(indexes_png_data)); + img_indexes_png->LoadFile(img_indexes_pngIS, wxBITMAP_TYPE_PNG); + } + return img_indexes_png; +} +#define indexes_png_img indexes_png_img() + +static wxBitmap *indexes_png_bmp() +{ + static wxBitmap *bmp_indexes_png; + if (!bmp_indexes_png || !bmp_indexes_png->IsOk()) + bmp_indexes_png = new wxBitmap(*indexes_png_img); + return bmp_indexes_png; +} +#define indexes_png_bmp indexes_png_bmp() + +static wxIcon *indexes_png_ico() +{ + static wxIcon *ico_indexes_png; + if (!ico_indexes_png || !ico_indexes_png->IsOk()) + { + ico_indexes_png = new wxIcon(); + ico_indexes_png->CopyFromBitmap(*indexes_png_bmp); + } + return ico_indexes_png; +} +#define indexes_png_ico indexes_png_ico() + +#endif // INDEXES_PNG_H diff --git a/include/images/job.png b/include/images/job.png new file mode 100644 index 0000000..7754674 Binary files /dev/null and b/include/images/job.png differ diff --git a/include/images/job.pngc b/include/images/job.pngc new file mode 100644 index 0000000..b3130ff --- /dev/null +++ b/include/images/job.pngc @@ -0,0 +1,129 @@ +#ifndef JOB_PNG_H +#define JOB_PNG_H + +static const unsigned char job_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xb4, 0xb4, 0x7e, +0x7f, 0x80, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xf9, 0xfd, 0xfe, 0xf6, 0xfb, 0xfd, 0xf2, 0xfa, +0xfc, 0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe4, +0xf4, 0xfa, 0xde, 0xf2, 0xf9, 0x1e, 0x50, 0xad, +0xd9, 0xf0, 0xf8, 0xd3, 0xed, 0xf6, 0xce, 0xeb, +0xf5, 0xdb, 0xdc, 0xdf, 0xdb, 0xbb, 0xb8, 0xde, +0x9f, 0x96, 0xe1, 0x8a, 0x7f, 0xd0, 0x81, 0x78, +0xef, 0xb5, 0xaf, 0x64, 0x6a, 0xa1, 0xc2, 0x89, +0x8c, 0xe2, 0x8e, 0x81, 0xe2, 0x88, 0x7c, 0xe2, +0x81, 0x76, 0xe2, 0x7a, 0x70, 0xe3, 0x73, 0x69, +0xe7, 0x82, 0x7b, 0xdf, 0xa2, 0x98, 0xeb, 0xb4, +0xad, 0xf1, 0xda, 0xd7, 0xf0, 0xf4, 0xf7, 0xe8, +0xd2, 0xd2, 0xe3, 0x9f, 0x9c, 0xe3, 0x64, 0x5c, +0xe7, 0x76, 0x70, 0x8b, 0x76, 0x97, 0xf5, 0xf8, +0xf9, 0xf0, 0xf9, 0xfc, 0xe2, 0xf3, 0xf9, 0xdb, +0xec, 0xf4, 0xdd, 0x93, 0x92, 0xe4, 0x54, 0x4e, +0xf0, 0x9c, 0x99, 0xf0, 0xd9, 0xd7, 0xef, 0xf8, +0xfc, 0xe8, 0xf6, 0xfa, 0xd2, 0xed, 0xf6, 0xd1, +0xc0, 0xc7, 0xe4, 0x4d, 0x47, 0xe9, 0x67, 0x64, +0xdd, 0x87, 0x7d, 0xee, 0xf3, 0xf7, 0xe7, 0xf5, +0xfa, 0xe0, 0xf2, 0xf9, 0x89, 0xae, 0xd9, 0xc9, +0xe9, 0xf4, 0xc2, 0xe0, 0xec, 0xe4, 0x45, 0x41, +0xe5, 0x43, 0x3f, 0xdc, 0x94, 0x8d, 0xe5, 0xd1, +0xd2, 0xd7, 0xef, 0xf7, 0x88, 0xad, 0xd9, 0x7f, +0xa9, 0xd7, 0xc5, 0xb7, 0xc0, 0xe4, 0x3e, 0x3a, +0xe9, 0x5c, 0x59, 0x8b, 0x67, 0x8b, 0xe1, 0x9d, +0x9b, 0xd5, 0xea, 0xf3, 0xc6, 0xe8, 0xf4, 0x7f, +0xa9, 0xd6, 0xb9, 0xde, 0xec, 0xd1, 0x7b, 0x7f, +0xe4, 0x37, 0x34, 0xf1, 0x8c, 0x8b, 0xc3, 0xe7, +0xf3, 0xbe, 0xe5, 0xf2, 0xc3, 0xc9, 0xd2, 0xdc, +0x7e, 0x79, 0xda, 0x91, 0x91, 0xce, 0xbe, 0xc6, +0xbf, 0xde, 0xeb, 0xc4, 0xb6, 0xc0, 0xe9, 0x50, +0x4f, 0xa2, 0x75, 0x73, 0xd3, 0x61, 0x5c, 0x22, +0x28, 0xc7, 0x77, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x03, 0x11, 0x0c, 0x4c, 0xf2, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xc2, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x3d, 0x8f, 0xd5, 0x12, +0xc2, 0x50, 0x0c, 0x05, 0xc3, 0x85, 0x52, 0x4a, +0xd3, 0x16, 0xa7, 0xb8, 0xbb, 0x3b, 0x14, 0x77, +0x77, 0xff, 0xff, 0x1f, 0x81, 0x0a, 0xec, 0x4b, +0x26, 0x7b, 0x32, 0x99, 0x39, 0xa0, 0x23, 0x7f, +0x40, 0x81, 0xe8, 0xf5, 0x06, 0xca, 0x48, 0x9b, +0x18, 0x33, 0x4b, 0x34, 0x81, 0x14, 0x2a, 0x70, +0x9a, 0xf8, 0xe5, 0x1c, 0xaf, 0x09, 0x0a, 0x69, +0xf5, 0x42, 0xd0, 0x84, 0x9a, 0x5b, 0xac, 0x36, +0xbb, 0xc3, 0xa9, 0x08, 0x1a, 0x19, 0x44, 0x97, +0x5b, 0xf4, 0x78, 0x7d, 0xfe, 0x80, 0x2c, 0x94, +0x3c, 0x28, 0x86, 0xc2, 0x91, 0x68, 0x2c, 0x9e, +0xf8, 0x0a, 0x06, 0x59, 0x4c, 0x8a, 0xa1, 0x54, +0x1a, 0x33, 0xd9, 0x5c, 0xbe, 0x00, 0x44, 0xfe, +0x6f, 0xf3, 0x14, 0x4b, 0x65, 0xe4, 0x2a, 0xd5, +0x5a, 0x1d, 0x08, 0x8b, 0x3c, 0x36, 0xbc, 0xcd, +0x56, 0x1b, 0x3b, 0x52, 0xb7, 0xd7, 0x07, 0xc2, +0xf1, 0x82, 0x34, 0xf0, 0x0d, 0xd9, 0xd1, 0x18, +0x27, 0xd3, 0xd9, 0x1c, 0x08, 0x8f, 0x12, 0x2e, +0xfc, 0xcb, 0x95, 0xb0, 0xde, 0x6c, 0x77, 0xfb, +0x03, 0x10, 0x41, 0x3a, 0x9e, 0xce, 0x97, 0xf8, +0xf5, 0x76, 0x7f, 0xec, 0xf6, 0x4f, 0x00, 0xb5, +0xed, 0xeb, 0x9d, 0xaf, 0xf5, 0x66, 0xf2, 0xfe, +0xa7, 0x50, 0xef, 0xcf, 0x0f, 0xdf, 0xf9, 0x01, +0x07, 0x78, 0x17, 0xab, 0x6e, 0xd4, 0x7b, 0x8c, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *job_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_job_png = new wxImage(); + if (!img_job_png || !img_job_png->IsOk()) + { + wxMemoryInputStream img_job_pngIS(job_png_data, sizeof(job_png_data)); + img_job_png->LoadFile(img_job_pngIS, wxBITMAP_TYPE_PNG); + } + return img_job_png; +} +#define job_png_img job_png_img() + +static wxBitmap *job_png_bmp() +{ + static wxBitmap *bmp_job_png; + if (!bmp_job_png || !bmp_job_png->IsOk()) + bmp_job_png = new wxBitmap(*job_png_img); + return bmp_job_png; +} +#define job_png_bmp job_png_bmp() + +static wxIcon *job_png_ico() +{ + static wxIcon *ico_job_png; + if (!ico_job_png || !ico_job_png->IsOk()) + { + ico_job_png = new wxIcon(); + ico_job_png->CopyFromBitmap(*job_png_bmp); + } + return ico_job_png; +} +#define job_png_ico job_png_ico() + +#endif // JOB_PNG_H diff --git a/include/images/jobdisabled.png b/include/images/jobdisabled.png new file mode 100644 index 0000000..a9bf3ef Binary files /dev/null and b/include/images/jobdisabled.png differ diff --git a/include/images/jobdisabled.pngc b/include/images/jobdisabled.pngc new file mode 100644 index 0000000..74ef465 --- /dev/null +++ b/include/images/jobdisabled.pngc @@ -0,0 +1,120 @@ +#ifndef JOBDISABLED_PNG_H +#define JOBDISABLED_PNG_H + +static const unsigned char jobdisabled_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd2, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xb4, 0xb4, 0x7e, +0x7f, 0x80, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xf9, 0xfd, 0xfe, 0xf6, 0xfb, 0xfd, 0xf2, 0xfa, +0xfc, 0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe4, +0xf4, 0xfa, 0xde, 0xf2, 0xf9, 0x1e, 0x50, 0xad, +0xd9, 0xf0, 0xf8, 0xd3, 0xed, 0xf6, 0xce, 0xeb, +0xf5, 0xcf, 0x64, 0x67, 0xc5, 0x00, 0x00, 0xcb, +0x62, 0x65, 0xc9, 0xe9, 0xf4, 0xdd, 0x69, 0x69, +0x80, 0x21, 0x47, 0xf6, 0x77, 0x77, 0xc3, 0xe7, +0xf3, 0xa8, 0x34, 0x35, 0xf1, 0x57, 0x57, 0xf6, +0x76, 0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, 0x6e, +0xc2, 0x5e, 0x64, 0xf1, 0x56, 0x56, 0xef, 0x4f, +0x4f, 0xee, 0x48, 0x49, 0xf5, 0x6d, 0x6d, 0xf4, +0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, 0x55, +0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0xc7, 0x60, +0x64, 0xf3, 0x61, 0x61, 0xf1, 0x5b, 0x5b, 0xf0, +0x54, 0x54, 0xef, 0x4d, 0x4e, 0xee, 0x47, 0x47, +0xf0, 0x53, 0x54, 0xef, 0x4d, 0x4d, 0xee, 0x46, +0x46, 0xf0, 0x53, 0x53, 0xef, 0x4c, 0x4c, 0xee, +0x45, 0x45, 0xec, 0x3e, 0x3f, 0xeb, 0x38, 0x38, +0xf0, 0x52, 0x52, 0xef, 0x4b, 0x4b, 0xed, 0x44, +0x45, 0xeb, 0x37, 0x37, 0xea, 0x31, 0x31, 0xe9, +0x2b, 0x2b, 0xbe, 0xe5, 0xf2, 0xf0, 0x51, 0x51, +0xee, 0x4a, 0x4a, 0xed, 0x43, 0x44, 0xb9, 0x5b, +0x62, 0xe9, 0x2a, 0x2b, 0xe8, 0x25, 0x25, 0xe7, +0x20, 0x20, 0xed, 0x42, 0x43, 0xbd, 0x4a, 0x4b, +0xe7, 0x1f, 0x20, 0xca, 0x4c, 0x75, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xb1, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x3d, 0x8f, 0xe7, 0x16, 0x82, 0x30, 0x14, 0x83, +0x4b, 0x11, 0x11, 0x29, 0x60, 0x04, 0x04, 0xf7, +0xde, 0x7b, 0xef, 0xad, 0xef, 0xff, 0x4a, 0xb6, +0xb5, 0x9a, 0x1f, 0xf7, 0x9c, 0x7e, 0x49, 0xd3, +0x5e, 0xa2, 0xd1, 0xbf, 0x34, 0x22, 0x44, 0x75, +0x3d, 0x61, 0x24, 0xcd, 0x94, 0x95, 0xb6, 0xa9, +0x02, 0xcc, 0x60, 0x52, 0x8e, 0x02, 0x3f, 0xdf, +0x71, 0x15, 0x30, 0x98, 0xf9, 0x4d, 0x78, 0x0a, +0x48, 0x3f, 0x83, 0xac, 0xe7, 0xd3, 0x00, 0x01, +0x07, 0x26, 0xb3, 0x58, 0x88, 0x1c, 0xc2, 0x28, +0x46, 0x9e, 0x13, 0x2a, 0xee, 0xa3, 0x50, 0x2c, +0xa1, 0x8c, 0x4a, 0xb5, 0x06, 0x42, 0x2d, 0x66, +0xf3, 0x44, 0xbd, 0xd1, 0x44, 0xab, 0xdd, 0x11, +0x09, 0xd1, 0xef, 0x75, 0xd1, 0xeb, 0x0f, 0x86, +0x23, 0xd9, 0x61, 0x33, 0x97, 0x3f, 0x11, 0x62, +0x3c, 0x99, 0x8a, 0x33, 0xa1, 0xdc, 0xf7, 0xa3, +0x32, 0x66, 0xf3, 0xc5, 0x72, 0x25, 0x13, 0x2e, +0xf3, 0xb9, 0xbf, 0xde, 0x6c, 0xb1, 0xdb, 0x1f, +0x44, 0x07, 0xf7, 0x8f, 0x38, 0x9d, 0x2f, 0xb8, +0xe2, 0x76, 0x7f, 0x80, 0xc8, 0x6d, 0x63, 0x3c, +0x11, 0xd3, 0x17, 0xde, 0xb2, 0x45, 0x48, 0xfe, +0x51, 0xce, 0x0f, 0x5a, 0x11, 0x10, 0x4d, 0x4b, +0x35, 0xa2, 0x5a, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *jobdisabled_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_jobdisabled_png = new wxImage(); + if (!img_jobdisabled_png || !img_jobdisabled_png->IsOk()) + { + wxMemoryInputStream img_jobdisabled_pngIS(jobdisabled_png_data, sizeof(jobdisabled_png_data)); + img_jobdisabled_png->LoadFile(img_jobdisabled_pngIS, wxBITMAP_TYPE_PNG); + } + return img_jobdisabled_png; +} +#define jobdisabled_png_img jobdisabled_png_img() + +static wxBitmap *jobdisabled_png_bmp() +{ + static wxBitmap *bmp_jobdisabled_png; + if (!bmp_jobdisabled_png || !bmp_jobdisabled_png->IsOk()) + bmp_jobdisabled_png = new wxBitmap(*jobdisabled_png_img); + return bmp_jobdisabled_png; +} +#define jobdisabled_png_bmp jobdisabled_png_bmp() + +static wxIcon *jobdisabled_png_ico() +{ + static wxIcon *ico_jobdisabled_png; + if (!ico_jobdisabled_png || !ico_jobdisabled_png->IsOk()) + { + ico_jobdisabled_png = new wxIcon(); + ico_jobdisabled_png->CopyFromBitmap(*jobdisabled_png_bmp); + } + return ico_jobdisabled_png; +} +#define jobdisabled_png_ico jobdisabled_png_ico() + +#endif // JOBDISABLED_PNG_H diff --git a/include/images/jobrun.png b/include/images/jobrun.png new file mode 100644 index 0000000..a94176c Binary files /dev/null and b/include/images/jobrun.png differ diff --git a/include/images/jobrun.pngc b/include/images/jobrun.pngc new file mode 100644 index 0000000..1164373 --- /dev/null +++ b/include/images/jobrun.pngc @@ -0,0 +1,93 @@ +#ifndef JOBRUN_PNG_H +#define JOBRUN_PNG_H + +static const unsigned char jobrun_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x01, 0xd9, 0xc9, 0x2c, 0x7f, 0x00, 0x00, +0x00, 0x81, 0x50, 0x4c, 0x54, 0x45, 0xb3, 0xb4, +0xb4, 0x7e, 0x7f, 0x80, 0x00, 0x00, 0x00, 0xff, +0xff, 0xff, 0xfd, 0xfe, 0xff, 0xf9, 0xfd, 0xfe, +0xf6, 0xfb, 0xfd, 0xf2, 0xfa, 0xfc, 0xed, 0xf8, +0xfc, 0xe9, 0xf6, 0xfb, 0xe4, 0xf4, 0xfa, 0xde, +0xf2, 0xf9, 0x1e, 0x50, 0xad, 0xd9, 0xf0, 0xf8, +0xd3, 0xed, 0xf6, 0x1e, 0x51, 0xac, 0x12, 0x98, +0x66, 0x1a, 0x65, 0x98, 0xce, 0xeb, 0xf5, 0xcf, +0xfd, 0xd3, 0x00, 0xff, 0x00, 0x06, 0xff, 0x06, +0x5c, 0xfc, 0x62, 0xe2, 0xf6, 0xf3, 0x19, 0x6e, +0x90, 0x04, 0xe8, 0x17, 0x16, 0x7f, 0x7f, 0xc9, +0xfb, 0xd1, 0x2d, 0xfb, 0x34, 0x6d, 0x91, 0x6e, +0x03, 0xfc, 0x03, 0x00, 0xff, 0x00, 0x13, 0xeb, +0x14, 0x00, 0xff, 0x00, 0x00, 0xfe, 0x01, 0x5f, +0xf8, 0x6d, 0x7b, 0x82, 0x7c, 0x45, 0xfb, 0x4d, +0xaa, 0xf3, 0xc2, 0x04, 0xe5, 0x1a, 0x13, 0x8d, +0x71, 0xd3, 0xf9, 0xe0, 0xdd, 0xf6, 0xee, 0xd3, +0x1d, 0xbd, 0x7f, 0x00, 0x00, 0x00, 0x2b, 0x74, +0x52, 0x4e, 0x53, 0xff, 0xff, 0x00, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0xff, 0x8e, 0xff, 0x4f, 0xff, 0xff, 0xff, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0xe3, +0x0f, 0x5d, 0x00, 0x00, 0x00, 0x78, 0x49, 0x44, +0x41, 0x54, 0x78, 0x9c, 0x65, 0x8f, 0xe9, 0x12, +0x82, 0x20, 0x14, 0x46, 0x41, 0x42, 0xb3, 0xd0, +0xc4, 0xae, 0x4b, 0xae, 0x95, 0x4b, 0xe9, 0xfb, +0x3f, 0xa0, 0xca, 0x20, 0x5c, 0xeb, 0xfc, 0x3c, +0xdc, 0x39, 0xf3, 0x41, 0x08, 0x35, 0x10, 0x67, +0x85, 0x50, 0xc6, 0x4e, 0xdc, 0xf5, 0xce, 0xfe, +0xe5, 0x4a, 0xb5, 0x10, 0x5c, 0x28, 0x02, 0x2d, +0xf6, 0xf7, 0x20, 0xd4, 0x82, 0x0b, 0xef, 0x16, +0xc9, 0xf5, 0x22, 0xa6, 0xa6, 0x71, 0x87, 0x24, +0xcd, 0x70, 0x23, 0x07, 0x80, 0x47, 0x81, 0x1a, +0x25, 0x6c, 0x54, 0xb5, 0x69, 0xe4, 0x4a, 0x40, +0xd3, 0xda, 0x86, 0xe2, 0xf9, 0xc2, 0x0d, 0x78, +0x77, 0xfd, 0xa1, 0x31, 0x8c, 0x68, 0x87, 0x84, +0xcf, 0xd7, 0xee, 0xd8, 0x96, 0x4e, 0xb3, 0x5d, +0xfa, 0xf7, 0x5b, 0xe7, 0x87, 0x05, 0x7d, 0x55, +0x08, 0xe4, 0x94, 0x7a, 0x19, 0xe3, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *jobrun_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_jobrun_png = new wxImage(); + if (!img_jobrun_png || !img_jobrun_png->IsOk()) + { + wxMemoryInputStream img_jobrun_pngIS(jobrun_png_data, sizeof(jobrun_png_data)); + img_jobrun_png->LoadFile(img_jobrun_pngIS, wxBITMAP_TYPE_PNG); + } + return img_jobrun_png; +} +#define jobrun_png_img jobrun_png_img() + +static wxBitmap *jobrun_png_bmp() +{ + static wxBitmap *bmp_jobrun_png; + if (!bmp_jobrun_png || !bmp_jobrun_png->IsOk()) + bmp_jobrun_png = new wxBitmap(*jobrun_png_img); + return bmp_jobrun_png; +} +#define jobrun_png_bmp jobrun_png_bmp() + +static wxIcon *jobrun_png_ico() +{ + static wxIcon *ico_jobrun_png; + if (!ico_jobrun_png || !ico_jobrun_png->IsOk()) + { + ico_jobrun_png = new wxIcon(); + ico_jobrun_png->CopyFromBitmap(*jobrun_png_bmp); + } + return ico_jobrun_png; +} +#define jobrun_png_ico jobrun_png_ico() + +#endif // JOBRUN_PNG_H diff --git a/include/images/jobrun_.png b/include/images/jobrun_.png new file mode 100644 index 0000000..a94e9e6 Binary files /dev/null and b/include/images/jobrun_.png differ diff --git a/include/images/jobs.png b/include/images/jobs.png new file mode 100644 index 0000000..705e233 Binary files /dev/null and b/include/images/jobs.png differ diff --git a/include/images/jobs.pngc b/include/images/jobs.pngc new file mode 100644 index 0000000..19559a5 --- /dev/null +++ b/include/images/jobs.pngc @@ -0,0 +1,110 @@ +#ifndef JOBS_PNG_H +#define JOBS_PNG_H + +static const unsigned char jobs_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x9f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xb4, 0xb4, 0x7e, +0x7f, 0x80, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xfe, +0xf8, 0xfc, 0xfe, 0xf3, 0xfa, 0xfd, 0xed, 0xf8, +0xfc, 0xe7, 0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xda, +0xf0, 0xf8, 0x56, 0x6c, 0x93, 0x1e, 0x50, 0xad, +0xd3, 0xed, 0xf6, 0xcd, 0xeb, 0xf5, 0xc6, 0xe8, +0xf4, 0xd3, 0xb4, 0xaf, 0xd8, 0x7e, 0x6d, 0xde, +0x56, 0x3e, 0xc5, 0x59, 0x49, 0xf3, 0xb9, 0xb1, +0x66, 0x53, 0x82, 0xe2, 0x79, 0x65, 0xf0, 0xbd, +0xb4, 0xf1, 0xf0, 0xf0, 0xe6, 0xb4, 0xb0, 0xe2, +0x6a, 0x5e, 0xef, 0xbc, 0xb4, 0xf0, 0xf9, 0xfc, +0xdd, 0xf1, 0xf8, 0xd8, 0xaa, 0xaa, 0xea, 0x6c, +0x63, 0xd7, 0x50, 0x3c, 0xed, 0xee, 0xf0, 0xe4, +0xf4, 0xfa, 0x89, 0xae, 0xd9, 0xc7, 0xdc, 0xe8, +0xe4, 0x36, 0x2d, 0xc0, 0xe5, 0xf3, 0xd5, 0x75, +0x69, 0xe1, 0xb2, 0xae, 0xd7, 0xef, 0xf7, 0x87, +0xad, 0xd8, 0xc9, 0xa0, 0xa5, 0xec, 0x64, 0x5f, +0xa3, 0x69, 0x62, 0xdc, 0x66, 0x5a, 0xd3, 0xa8, +0xaa, 0xc2, 0xdb, 0xe7, 0xc7, 0x9f, 0xa5, 0xda, +0x53, 0x51, 0xf5, 0xac, 0xaa, 0xf4, 0xb4, 0xaf, +0xb8, 0xcd, 0x1d, 0xe8, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x03, 0x11, 0x0c, 0x4c, 0xf2, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x94, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, 0xd9, +0x12, 0x83, 0x20, 0x0c, 0x40, 0xd1, 0x48, 0x15, +0x91, 0x06, 0xac, 0xdd, 0x77, 0xed, 0x62, 0x57, +0xbb, 0xda, 0xff, 0xff, 0xb6, 0x42, 0xc0, 0x69, +0xc7, 0x3c, 0xde, 0x1c, 0x66, 0x02, 0x04, 0xcc, +0x0f, 0xf8, 0x61, 0x9d, 0x30, 0xe2, 0xb1, 0x48, +0x64, 0x53, 0x58, 0xd8, 0x6d, 0x4c, 0xe0, 0x42, +0xd4, 0x32, 0x8c, 0xff, 0x19, 0x0a, 0x71, 0xcb, +0x30, 0x61, 0x0d, 0x72, 0x34, 0xa3, 0x28, 0x24, +0xd6, 0xd0, 0x5e, 0x69, 0x0a, 0xd2, 0x1a, 0x14, +0x56, 0xa4, 0x14, 0x94, 0x35, 0x76, 0xdf, 0xcb, +0xfa, 0x83, 0x21, 0x80, 0xb9, 0xd4, 0x18, 0x94, +0x38, 0x1a, 0x4f, 0xa6, 0xb3, 0x39, 0x78, 0x63, +0xde, 0x67, 0x8b, 0x25, 0xae, 0xd6, 0x39, 0x38, +0x83, 0x1a, 0x8b, 0xcd, 0x16, 0x77, 0xfb, 0xd2, +0x1d, 0xa7, 0x74, 0x7a, 0x38, 0x9e, 0xce, 0x17, +0xbc, 0x56, 0x14, 0xe8, 0xc7, 0xb7, 0xfb, 0xe3, +0xf9, 0x7a, 0xd7, 0xf0, 0x9b, 0x4f, 0x5e, 0x56, +0x35, 0x7c, 0x01, 0x01, 0xa1, 0x09, 0x49, 0xf9, +0x16, 0x39, 0xcb, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *jobs_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_jobs_png = new wxImage(); + if (!img_jobs_png || !img_jobs_png->IsOk()) + { + wxMemoryInputStream img_jobs_pngIS(jobs_png_data, sizeof(jobs_png_data)); + img_jobs_png->LoadFile(img_jobs_pngIS, wxBITMAP_TYPE_PNG); + } + return img_jobs_png; +} +#define jobs_png_img jobs_png_img() + +static wxBitmap *jobs_png_bmp() +{ + static wxBitmap *bmp_jobs_png; + if (!bmp_jobs_png || !bmp_jobs_png->IsOk()) + bmp_jobs_png = new wxBitmap(*jobs_png_img); + return bmp_jobs_png; +} +#define jobs_png_bmp jobs_png_bmp() + +static wxIcon *jobs_png_ico() +{ + static wxIcon *ico_jobs_png; + if (!ico_jobs_png || !ico_jobs_png->IsOk()) + { + ico_jobs_png = new wxIcon(); + ico_jobs_png->CopyFromBitmap(*jobs_png_bmp); + } + return ico_jobs_png; +} +#define jobs_png_ico jobs_png_ico() + +#endif // JOBS_PNG_H diff --git a/include/images/key.png b/include/images/key.png new file mode 100644 index 0000000..90405e7 Binary files /dev/null and b/include/images/key.png differ diff --git a/include/images/key.pngc b/include/images/key.pngc new file mode 100644 index 0000000..ce543ac --- /dev/null +++ b/include/images/key.pngc @@ -0,0 +1,101 @@ +#ifndef KEY_PNG_H +#define KEY_PNG_H + +static const unsigned char key_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x99, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xf2, 0xf6, 0xe7, 0xc1, +0xd3, 0x8a, 0x97, 0xb5, 0x3c, 0x8f, 0xb0, 0x2b, +0xbd, 0xd3, 0x7f, 0xe0, 0xf1, 0xbd, 0xdf, 0xf0, +0xba, 0xbc, 0xd3, 0x7b, 0x8e, 0xb0, 0x29, 0xef, +0xff, 0xd6, 0xeb, 0xfe, 0xcc, 0xe6, 0xfd, 0xbe, +0xe6, 0xfc, 0xbb, 0xb9, 0xd2, 0x74, 0x83, 0xa7, +0x15, 0xb6, 0xcb, 0x75, 0xee, 0xff, 0xd2, 0xe6, +0xfd, 0xbd, 0xdb, 0xfa, 0xa0, 0xdb, 0xf9, 0x9e, +0xde, 0xf9, 0xa5, 0xdf, 0xf8, 0xa6, 0xdb, 0xf7, +0x9c, 0xd8, 0xf6, 0x93, 0xd2, 0xf4, 0x82, 0xd2, +0xf3, 0x82, 0xe1, 0xf7, 0xad, 0xe0, 0xf1, 0xbc, +0xec, 0xfe, 0xce, 0xe3, 0xfc, 0xb5, 0xd8, 0xf9, +0x95, 0xd8, 0xf8, 0x94, 0xdd, 0xf8, 0xa3, 0xb1, +0xcf, 0x5f, 0xdd, 0xf7, 0xa2, 0xae, 0xce, 0x57, +0xd2, 0xf4, 0x84, 0xd6, 0xf4, 0x8d, 0xbc, 0xd3, +0x7d, 0xeb, 0xfe, 0xc9, 0xe4, 0xfc, 0xb8, 0xdd, +0xfa, 0xa4, 0xdd, 0xf9, 0xa2, 0xb6, 0xd1, 0x6c, +0x8f, 0xb0, 0x2a, 0xbb, 0xd2, 0x79, 0xda, 0xee, +0xab, 0xd7, 0xed, 0xa4, 0xb8, 0xd2, 0x71, 0x8e, +0xaf, 0x27, 0x72, 0x37, 0xf8, 0x42, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x60, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xa0, 0x06, 0x60, 0x64, +0x62, 0x66, 0x66, 0x62, 0x44, 0xe2, 0xb3, 0xb0, +0xb2, 0xb1, 0x73, 0x70, 0x22, 0x44, 0x98, 0x58, +0xb9, 0xb8, 0x79, 0x78, 0xf9, 0xf8, 0x21, 0x40, +0x80, 0x81, 0x81, 0x99, 0x4d, 0x90, 0x5f, 0x48, +0x58, 0x44, 0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, +0x9a, 0x1f, 0x28, 0x20, 0x23, 0xcb, 0x2f, 0x27, +0xaf, 0xa0, 0xa8, 0xa4, 0xac, 0xa2, 0xaa, 0x06, +0x52, 0xc1, 0xa4, 0xae, 0xa1, 0xa9, 0xa5, 0xad, +0xc3, 0x2f, 0x00, 0x84, 0x20, 0x3e, 0x03, 0xa3, +0xae, 0x9e, 0xbe, 0x81, 0xa1, 0x11, 0x23, 0x6e, +0x6b, 0xa9, 0x00, 0x00, 0x17, 0xe6, 0x06, 0x39, +0xcf, 0x53, 0xa2, 0x70, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *key_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_key_png = new wxImage(); + if (!img_key_png || !img_key_png->IsOk()) + { + wxMemoryInputStream img_key_pngIS(key_png_data, sizeof(key_png_data)); + img_key_png->LoadFile(img_key_pngIS, wxBITMAP_TYPE_PNG); + } + return img_key_png; +} +#define key_png_img key_png_img() + +static wxBitmap *key_png_bmp() +{ + static wxBitmap *bmp_key_png; + if (!bmp_key_png || !bmp_key_png->IsOk()) + bmp_key_png = new wxBitmap(*key_png_img); + return bmp_key_png; +} +#define key_png_bmp key_png_bmp() + +static wxIcon *key_png_ico() +{ + static wxIcon *ico_key_png; + if (!ico_key_png || !ico_key_png->IsOk()) + { + ico_key_png = new wxIcon(); + ico_key_png->CopyFromBitmap(*key_png_bmp); + } + return ico_key_png; +} +#define key_png_ico key_png_ico() + +#endif // KEY_PNG_H diff --git a/include/images/language-sm.png b/include/images/language-sm.png new file mode 100644 index 0000000..432d2f4 Binary files /dev/null and b/include/images/language-sm.png differ diff --git a/include/images/language-sm.pngc b/include/images/language-sm.pngc new file mode 100644 index 0000000..154b58a --- /dev/null +++ b/include/images/language-sm.pngc @@ -0,0 +1,97 @@ +#ifndef LANGUAGE_SM_PNG_H +#define LANGUAGE_SM_PNG_H + +static const unsigned char language_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xd9, 0x86, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xf7, 0xef, 0xd4, +0xd8, 0xb3, 0x1f, 0xe3, 0xcd, 0x39, 0xed, 0xe2, +0x4f, 0xf4, 0xf2, 0x5f, 0xf4, 0xea, 0xc5, 0xda, +0xb7, 0x23, 0xec, 0xde, 0x4b, 0xf8, 0xf9, 0x67, +0xe6, 0xd0, 0x69, 0xe8, 0xd6, 0x43, 0xf8, 0xfa, +0x69, 0xe8, 0xd1, 0x80, 0xda, 0xb6, 0x32, 0xf4, +0xee, 0x5f, 0xf9, 0xfa, 0x6b, 0xda, 0xb6, 0x38, +0xf4, 0xef, 0x60, 0xfa, 0xfb, 0x6d, 0xe9, 0xd6, +0x47, 0xfb, 0xfb, 0x6f, 0xdb, 0xb8, 0x25, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x07, 0x86, 0xb5, 0xf6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x8d, 0x8f, 0x49, 0x0e, 0x80, +0x20, 0x10, 0x04, 0x47, 0x14, 0x5c, 0x50, 0xdc, +0x77, 0xdc, 0x40, 0xff, 0xff, 0x45, 0x13, 0x98, +0x18, 0xb9, 0x51, 0xb7, 0xae, 0xa4, 0x33, 0x3d, +0x00, 0x7e, 0x04, 0x24, 0x0c, 0x09, 0x44, 0x5f, +0xa6, 0x2c, 0x4e, 0x92, 0x98, 0xd1, 0x14, 0x73, +0xc6, 0x73, 0x03, 0xcf, 0x6c, 0x2e, 0x44, 0x89, +0x88, 0xca, 0x88, 0xba, 0x69, 0x91, 0xa6, 0x33, +0xa2, 0xeb, 0x07, 0xa4, 0xb7, 0xa2, 0x1a, 0x27, +0x64, 0xb4, 0x15, 0x98, 0x97, 0xd5, 0xb0, 0xcc, +0x78, 0x25, 0x95, 0xdb, 0x7e, 0x1c, 0xe7, 0x29, +0x7f, 0xcb, 0xc8, 0xa5, 0xb4, 0x56, 0xce, 0xd8, +0x5b, 0x3d, 0xae, 0x00, 0x50, 0xb7, 0xdf, 0x9f, +0x2f, 0xe4, 0x0e, 0x07, 0xe3, 0xd8, 0x9f, 0xd2, +0x10, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *language_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_language_sm_png = new wxImage(); + if (!img_language_sm_png || !img_language_sm_png->IsOk()) + { + wxMemoryInputStream img_language_sm_pngIS(language_sm_png_data, sizeof(language_sm_png_data)); + img_language_sm_png->LoadFile(img_language_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_language_sm_png; +} +#define language_sm_png_img language_sm_png_img() + +static wxBitmap *language_sm_png_bmp() +{ + static wxBitmap *bmp_language_sm_png; + if (!bmp_language_sm_png || !bmp_language_sm_png->IsOk()) + bmp_language_sm_png = new wxBitmap(*language_sm_png_img); + return bmp_language_sm_png; +} +#define language_sm_png_bmp language_sm_png_bmp() + +static wxIcon *language_sm_png_ico() +{ + static wxIcon *ico_language_sm_png; + if (!ico_language_sm_png || !ico_language_sm_png->IsOk()) + { + ico_language_sm_png = new wxIcon(); + ico_language_sm_png->CopyFromBitmap(*language_sm_png_bmp); + } + return ico_language_sm_png; +} +#define language_sm_png_ico language_sm_png_ico() + +#endif // LANGUAGE_SM_PNG_H diff --git a/include/images/language.png b/include/images/language.png new file mode 100644 index 0000000..f391a08 Binary files /dev/null and b/include/images/language.png differ diff --git a/include/images/language.pngc b/include/images/language.pngc new file mode 100644 index 0000000..97125c2 --- /dev/null +++ b/include/images/language.pngc @@ -0,0 +1,103 @@ +#ifndef LANGUAGE_PNG_H +#define LANGUAGE_PNG_H + +static const unsigned char language_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x87, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe2, 0xc5, 0x61, 0xda, +0xb5, 0x34, 0xd5, 0xab, 0x1a, 0xed, 0xdb, 0x9c, +0xd9, 0xb4, 0x20, 0xe3, 0xcb, 0x38, 0xec, 0xe0, +0x4c, 0xf2, 0xef, 0x5c, 0xf6, 0xf8, 0x65, 0xf0, +0xe2, 0xb0, 0xdf, 0xc3, 0x2f, 0xef, 0xe5, 0x52, +0xf8, 0xf9, 0x66, 0xdd, 0xbe, 0x2b, 0xf2, 0xeb, +0x5a, 0xf8, 0xf9, 0x68, 0xe5, 0xcb, 0x71, 0xea, +0xdb, 0x48, 0xf9, 0xfa, 0x69, 0xd9, 0xb4, 0x32, +0xf5, 0xf0, 0x61, 0xf9, 0xfa, 0x6b, 0xf5, 0xf1, +0x62, 0xfa, 0xfb, 0x6d, 0xec, 0xdb, 0x4b, 0xfb, +0xfb, 0x6e, 0xde, 0xbf, 0x2d, 0xf5, 0xed, 0x60, +0xfc, 0xfb, 0x70, 0xed, 0xdc, 0x9e, 0xe1, 0xc4, +0x33, 0xf2, 0xe7, 0x5b, 0xfc, 0xfc, 0x72, 0xd9, +0xb5, 0x22, 0xe5, 0xcd, 0x3e, 0xf0, 0xe2, 0x56, +0xf8, 0xf1, 0x68, 0xfc, 0xfb, 0x73, 0xfd, 0xfc, +0x74, 0xd4, 0xaa, 0x16, 0xfe, 0xfd, 0x75, 0xe6, +0xcd, 0x76, 0xfe, 0xfd, 0x77, 0xff, 0xfd, 0x78, +0xc4, 0x97, 0x4c, 0x3b, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x81, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x6d, 0xce, 0xe9, 0x0e, 0x82, 0x30, 0x10, 0x46, +0xd1, 0x01, 0xd9, 0xf7, 0xb2, 0xca, 0xa2, 0x55, +0x40, 0x6d, 0xc1, 0xf7, 0x7f, 0x3e, 0xa7, 0xd4, +0xd2, 0x90, 0x70, 0xfe, 0x7d, 0x37, 0x69, 0x3a, +0x00, 0x82, 0x61, 0x5e, 0x4c, 0xc3, 0x02, 0xc5, +0x76, 0x5c, 0xcf, 0xf7, 0x5c, 0xc7, 0x0e, 0xe4, +0x0e, 0xa3, 0x58, 0x8a, 0xc2, 0x6d, 0x27, 0x69, +0xa6, 0xa4, 0x09, 0x6e, 0x92, 0x17, 0x5a, 0x4e, +0x00, 0xca, 0xaa, 0xd6, 0xaa, 0x12, 0x43, 0x73, +0xd5, 0x1a, 0x0c, 0xa4, 0xed, 0xb4, 0x16, 0x9f, +0x40, 0x3f, 0xdc, 0x94, 0xa1, 0x17, 0xbf, 0xdc, +0xe9, 0xe3, 0xf9, 0x47, 0xe5, 0x1d, 0xc1, 0x38, +0xcd, 0xaf, 0xf7, 0x07, 0x31, 0x75, 0xaa, 0x85, +0xa7, 0x33, 0xce, 0xf9, 0x1e, 0x84, 0x85, 0xad, +0xeb, 0x21, 0x60, 0xf9, 0x1e, 0x03, 0x96, 0x05, +0x4e, 0xfc, 0x00, 0x5d, 0x43, 0x0e, 0x13, 0xf9, +0xce, 0x89, 0x8e, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *language_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_language_png = new wxImage(); + if (!img_language_png || !img_language_png->IsOk()) + { + wxMemoryInputStream img_language_pngIS(language_png_data, sizeof(language_png_data)); + img_language_png->LoadFile(img_language_pngIS, wxBITMAP_TYPE_PNG); + } + return img_language_png; +} +#define language_png_img language_png_img() + +static wxBitmap *language_png_bmp() +{ + static wxBitmap *bmp_language_png; + if (!bmp_language_png || !bmp_language_png->IsOk()) + bmp_language_png = new wxBitmap(*language_png_img); + return bmp_language_png; +} +#define language_png_bmp language_png_bmp() + +static wxIcon *language_png_ico() +{ + static wxIcon *ico_language_png; + if (!ico_language_png || !ico_language_png->IsOk()) + { + ico_language_png = new wxIcon(); + ico_language_png->CopyFromBitmap(*language_png_bmp); + } + return ico_language_png; +} +#define language_png_ico language_png_ico() + +#endif // LANGUAGE_PNG_H diff --git a/include/images/languages.png b/include/images/languages.png new file mode 100644 index 0000000..e730cb2 Binary files /dev/null and b/include/images/languages.png differ diff --git a/include/images/languages.pngc b/include/images/languages.pngc new file mode 100644 index 0000000..86fd422 --- /dev/null +++ b/include/images/languages.pngc @@ -0,0 +1,104 @@ +#ifndef LANGUAGES_PNG_H +#define LANGUAGES_PNG_H + +static const unsigned char languages_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x8a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xec, 0xda, 0x99, 0xe0, +0xc2, 0x59, 0xd8, 0xb1, 0x29, 0xd8, 0xb3, 0x1f, +0xe3, 0xcd, 0x39, 0xed, 0xe2, 0x4f, 0xf4, 0xf2, +0x5f, 0xf4, 0xea, 0xc5, 0xda, 0xb7, 0x23, 0xec, +0xde, 0x4b, 0xf8, 0xf9, 0x67, 0xf4, 0xf0, 0x5e, +0xe8, 0xd6, 0x43, 0xde, 0xc1, 0x2d, 0xd7, 0xb1, +0x1d, 0xdb, 0xb9, 0x25, 0xe8, 0xd1, 0x80, 0xf8, +0xfa, 0x69, 0xef, 0xe6, 0x54, 0xda, 0xb6, 0x38, +0xf4, 0xee, 0x5f, 0xf3, 0xed, 0x5d, 0xf4, 0xef, +0x60, 0xe5, 0xcf, 0x3e, 0xe9, 0xd6, 0x47, 0xda, +0xb6, 0x23, 0xdb, 0xb8, 0x25, 0xd8, 0xb2, 0x1f, +0xd6, 0xae, 0x1b, 0xf9, 0xfa, 0x6b, 0xf4, 0xe9, +0xc4, 0xfa, 0xfb, 0x6d, 0xfb, 0xfb, 0x6f, 0xee, +0xe0, 0x53, 0xfc, 0xfc, 0x72, 0xd9, 0xb3, 0x20, +0xe6, 0xce, 0x3f, 0xf1, 0xe5, 0x59, 0xfa, 0xf5, +0x6c, 0xfd, 0xfc, 0x74, 0xd6, 0xad, 0x1e, 0xd4, +0xaa, 0x16, 0xfe, 0xfd, 0x76, 0xe6, 0xcd, 0x76, +0xff, 0xfd, 0x78, 0x3e, 0xab, 0x28, 0x67, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x8a, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x55, 0x8f, 0xd9, 0x16, 0x82, +0x30, 0x0c, 0x05, 0xc3, 0x5e, 0xd0, 0x5a, 0xab, +0x45, 0xac, 0x15, 0x17, 0x44, 0xc1, 0x82, 0xff, +0xff, 0x7b, 0x86, 0x12, 0x97, 0xce, 0x5b, 0xe6, +0xcc, 0xc3, 0x0d, 0x00, 0x40, 0x10, 0x46, 0x51, +0x18, 0xc0, 0x97, 0x38, 0x49, 0xb3, 0x2c, 0x4d, +0x62, 0x46, 0x77, 0x5e, 0x2c, 0x96, 0x7c, 0x25, +0xc4, 0x5a, 0xcc, 0xb7, 0xe4, 0x9b, 0xed, 0xa7, +0x71, 0x42, 0x95, 0x3b, 0xbf, 0x51, 0xd5, 0xde, +0x6f, 0xa4, 0x3e, 0xb8, 0xc6, 0x51, 0xe4, 0x68, +0xcc, 0x71, 0x6a, 0x08, 0x2e, 0xd1, 0xd4, 0xd8, +0x9c, 0x88, 0x52, 0xa1, 0x38, 0x63, 0x73, 0x21, +0xaa, 0x49, 0x00, 0xab, 0xf5, 0x95, 0xd0, 0x72, +0x1e, 0x63, 0x9a, 0x9b, 0xa3, 0x31, 0xb4, 0x96, +0xb5, 0xf7, 0x47, 0xd7, 0xf5, 0x7d, 0xfb, 0x7b, +0x08, 0xc2, 0xa7, 0x1d, 0x06, 0x0b, 0xff, 0x8c, +0xf6, 0xe5, 0x0b, 0x34, 0x23, 0xc0, 0x1b, 0x0e, +0x4e, 0x0d, 0x9b, 0x6f, 0x99, 0x1c, 0xf3, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *languages_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_languages_png = new wxImage(); + if (!img_languages_png || !img_languages_png->IsOk()) + { + wxMemoryInputStream img_languages_pngIS(languages_png_data, sizeof(languages_png_data)); + img_languages_png->LoadFile(img_languages_pngIS, wxBITMAP_TYPE_PNG); + } + return img_languages_png; +} +#define languages_png_img languages_png_img() + +static wxBitmap *languages_png_bmp() +{ + static wxBitmap *bmp_languages_png; + if (!bmp_languages_png || !bmp_languages_png->IsOk()) + bmp_languages_png = new wxBitmap(*languages_png_img); + return bmp_languages_png; +} +#define languages_png_bmp languages_png_bmp() + +static wxIcon *languages_png_ico() +{ + static wxIcon *ico_languages_png; + if (!ico_languages_png || !ico_languages_png->IsOk()) + { + ico_languages_png = new wxIcon(); + ico_languages_png->CopyFromBitmap(*languages_png_bmp); + } + return ico_languages_png; +} +#define languages_png_ico languages_png_ico() + +#endif // LANGUAGES_PNG_H diff --git a/include/images/loginroles.png b/include/images/loginroles.png new file mode 100644 index 0000000..33f2621 Binary files /dev/null and b/include/images/loginroles.png differ diff --git a/include/images/loginroles.pngc b/include/images/loginroles.pngc new file mode 100644 index 0000000..531a5fc --- /dev/null +++ b/include/images/loginroles.pngc @@ -0,0 +1,140 @@ +#ifndef LOGINROLES_PNG_H +#define LOGINROLES_PNG_H + +static const unsigned char loginroles_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x70, +0x70, 0x70, 0x6a, 0x6a, 0x6a, 0x98, 0x95, 0x92, +0xb1, 0xa8, 0xa2, 0xe1, 0xd5, 0xcb, 0xe6, 0xda, +0xd2, 0xb7, 0xaf, 0xab, 0x93, 0x8f, 0x8e, 0x91, +0x8d, 0x8a, 0xbd, 0xb4, 0xad, 0xf1, 0xe3, 0xd9, +0xf7, 0xea, 0xe1, 0xf7, 0xea, 0xe2, 0xf3, 0xe6, +0xe1, 0xc9, 0xbf, 0xbd, 0x90, 0x8c, 0x8c, 0xa2, +0x9e, 0x9a, 0xe4, 0xd7, 0xce, 0xf7, 0xea, 0xe0, +0xf7, 0xea, 0xe4, 0xf7, 0xea, 0xe7, 0xe9, 0xde, +0xdd, 0xad, 0xa7, 0xa8, 0x9e, 0x99, 0x95, 0xef, +0xe2, 0xd9, 0xf7, 0xea, 0xe9, 0xf1, 0xe4, 0xe6, +0xaf, 0xa9, 0xaa, 0xa3, 0x9f, 0x9d, 0xe0, 0xd5, +0xcf, 0xf7, 0xea, 0xeb, 0xe8, 0xdc, 0xdf, 0xab, +0xa6, 0xa7, 0x89, 0x85, 0x84, 0xb6, 0xae, 0xab, +0xef, 0xe2, 0xe0, 0xf2, 0xe6, 0xea, 0xc2, 0xb9, +0xbd, 0x87, 0x83, 0x85, 0x6e, 0x6d, 0x6d, 0xa5, +0x9f, 0x9f, 0xdc, 0xd1, 0xd3, 0xe3, 0xd8, 0xda, +0xad, 0xa6, 0xa9, 0x73, 0x71, 0x72, 0x5a, 0x5c, +0x5c, 0x8b, 0x94, 0x95, 0xb3, 0xc3, 0xc7, 0x9c, +0xa9, 0xad, 0x77, 0x7e, 0x80, 0x71, 0x78, 0x7b, +0x90, 0xa0, 0xa7, 0xa7, 0xbf, 0xca, 0x88, 0x98, +0xa0, 0x68, 0x6f, 0x72, 0x7b, 0x81, 0x82, 0xbf, +0xd2, 0xd7, 0xd1, 0xe8, 0xf0, 0xce, 0xe7, 0xf0, +0xcf, 0xdf, 0xd6, 0xd5, 0xbf, 0x64, 0xcb, 0xb0, +0x3e, 0xe0, 0xcf, 0x8b, 0xae, 0xce, 0xde, 0x7a, +0x88, 0x90, 0x93, 0x96, 0x96, 0xa4, 0xb1, 0xb5, +0xcd, 0xe1, 0xe1, 0xd0, 0xb6, 0x4d, 0xe8, 0xdc, +0xa3, 0xee, 0xe8, 0xb8, 0xe0, 0xd0, 0x83, 0xc5, +0xb7, 0x5c, 0x9d, 0xb0, 0xaa, 0x96, 0x96, 0x7d, +0x85, 0x88, 0x89, 0xbb, 0xcf, 0xd5, 0xca, 0xe5, +0xf0, 0xda, 0xc6, 0x75, 0xe7, 0xdb, 0x9f, 0xed, +0xe5, 0xb1, 0xef, 0xe9, 0xaf, 0xf2, 0xec, 0xae, +0xdd, 0xcb, 0x6f, 0xcf, 0xb5, 0x3f, 0xcf, 0xb5, +0x3d, 0xcf, 0xb5, 0x3a, 0xcf, 0xb4, 0x36, 0xcf, +0xb5, 0x3c, 0xd2, 0xba, 0x55, 0x6d, 0x70, 0x71, +0xc9, 0xe1, 0xea, 0xc6, 0xe3, 0xf1, 0xef, 0xe9, +0xbd, 0xdb, 0xc8, 0x71, 0xe6, 0xda, 0x8d, 0xf0, +0xe8, 0x95, 0xf1, 0xe9, 0x98, 0xee, 0xe4, 0x94, +0xf1, 0xe8, 0x97, 0xe8, 0xda, 0x78, 0xf2, 0xe8, +0x83, 0xe9, 0xdb, 0x79, 0xd1, 0xb7, 0x4b, 0x58, +0x58, 0x58, 0x67, 0x6b, 0x6c, 0x65, 0x69, 0x6b, +0xd6, 0xc1, 0x69, 0xe8, 0xdd, 0xa2, 0xe9, 0xde, +0x9b, 0xec, 0xe4, 0x99, 0xf1, 0xe9, 0x97, 0xe1, +0xd0, 0x71, 0xd8, 0xc3, 0x5f, 0xd8, 0xc2, 0x59, +0xda, 0xc6, 0x69, 0xd6, 0xbf, 0x46, 0xd3, 0xbb, +0x4c, 0xd6, 0xbf, 0x65, 0xd3, 0xbb, 0x56, 0xe9, +0xde, 0x9d, 0xee, 0xe6, 0xa3, 0xe3, 0xd3, 0x7e, +0xcc, 0xb0, 0x39, 0xd7, 0xc3, 0x6a, 0xcf, 0xb7, +0x4c, 0x00, 0x1e, 0xb5, 0x77, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xb6, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, 0x26, 0x66, +0x46, 0x06, 0x24, 0xc0, 0xc2, 0xca, 0xc6, 0xce, +0xc1, 0x89, 0xe0, 0x73, 0x71, 0xf3, 0xf0, 0xf2, +0xf1, 0x0b, 0x08, 0xc2, 0x05, 0x84, 0x84, 0x45, +0xf8, 0x44, 0xc5, 0xc4, 0x25, 0xe0, 0x02, 0x92, +0x52, 0x40, 0xbe, 0xb4, 0x8c, 0x2c, 0x5c, 0x40, +0x4e, 0x1e, 0xc8, 0x57, 0x50, 0x54, 0x82, 0x0b, +0x28, 0xab, 0xa8, 0x4a, 0x2b, 0xa8, 0xa9, 0x6b, +0x20, 0x4c, 0xd5, 0xd4, 0xd2, 0xd6, 0xd1, 0xd5, +0xd3, 0x87, 0xf3, 0x0d, 0x0c, 0x8d, 0x8c, 0x4d, +0x4c, 0xcd, 0xcc, 0x2d, 0xa0, 0x7c, 0x4b, 0x2b, +0x6b, 0x1b, 0x5b, 0x3b, 0x7b, 0x07, 0x47, 0x27, +0x08, 0xdf, 0xd9, 0xc5, 0xda, 0xc6, 0xd5, 0xcd, +0xdd, 0xc3, 0xd3, 0xcb, 0xdb, 0x07, 0x2c, 0xe0, +0xeb, 0x67, 0xe3, 0x1f, 0x10, 0x18, 0x14, 0x1c, +0x12, 0x1a, 0x16, 0x1e, 0x11, 0x19, 0x15, 0xcd, +0x10, 0x13, 0xeb, 0x1f, 0x67, 0x1f, 0x9f, 0x90, +0x98, 0x94, 0x9c, 0x92, 0x9a, 0x96, 0x9e, 0x91, +0xc9, 0x90, 0x95, 0x9d, 0x93, 0x93, 0x9b, 0x97, +0x5f, 0x50, 0x58, 0x54, 0x5c, 0x52, 0x5a, 0x56, +0x5e, 0x01, 0x31, 0xa8, 0xb2, 0xaa, 0xba, 0xa6, +0x16, 0xd9, 0xbf, 0x0c, 0x75, 0xf5, 0x30, 0x16, +0x00, 0x3c, 0x17, 0x22, 0x37, 0xb0, 0xae, 0x9d, +0x91, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *loginroles_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_loginroles_png = new wxImage(); + if (!img_loginroles_png || !img_loginroles_png->IsOk()) + { + wxMemoryInputStream img_loginroles_pngIS(loginroles_png_data, sizeof(loginroles_png_data)); + img_loginroles_png->LoadFile(img_loginroles_pngIS, wxBITMAP_TYPE_PNG); + } + return img_loginroles_png; +} +#define loginroles_png_img loginroles_png_img() + +static wxBitmap *loginroles_png_bmp() +{ + static wxBitmap *bmp_loginroles_png; + if (!bmp_loginroles_png || !bmp_loginroles_png->IsOk()) + bmp_loginroles_png = new wxBitmap(*loginroles_png_img); + return bmp_loginroles_png; +} +#define loginroles_png_bmp loginroles_png_bmp() + +static wxIcon *loginroles_png_ico() +{ + static wxIcon *ico_loginroles_png; + if (!ico_loginroles_png || !ico_loginroles_png->IsOk()) + { + ico_loginroles_png = new wxIcon(); + ico_loginroles_png->CopyFromBitmap(*loginroles_png_bmp); + } + return ico_loginroles_png; +} +#define loginroles_png_ico loginroles_png_ico() + +#endif // LOGINROLES_PNG_H diff --git a/include/images/module.mk b/include/images/module.mk new file mode 100644 index 0000000..6d60abf --- /dev/null +++ b/include/images/module.mk @@ -0,0 +1,330 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - include/images/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/images/aggregate-sm.png \ + include/images/aggregate.png \ + include/images/aggregates.png \ + include/images/back.png \ + include/images/backup.png \ + include/images/baddatabase.png \ + include/images/cast-sm.png \ + include/images/cast.png \ + include/images/casts.png \ + include/images/catalog.png \ + include/images/catalog-sm.png \ + include/images/catalogs.png \ + include/images/catalogobject.png \ + include/images/catalogobject-sm.png \ + include/images/catalogobjects.png \ + include/images/check.png \ + include/images/checkbad.png \ + include/images/checked.png \ + include/images/clearAll.png \ + include/images/clip_copy.png \ + include/images/clip_cut.png \ + include/images/clip_paste.png \ + include/images/closeddatabase-sm.png \ + include/images/closeddatabase.png \ + include/images/collation-sm.png \ + include/images/collation.png \ + include/images/collations.png \ + include/images/column-sm.png \ + include/images/column.png \ + include/images/columns.png \ + include/images/configuration.png \ + include/images/configurations.png \ + include/images/connect.png \ + include/images/constraints.png \ + include/images/continue.png \ + include/images/conversion.png \ + include/images/conversions.png \ + include/images/create.png \ + include/images/database-sm.png \ + include/images/database.png \ + include/images/databases.png \ + include/images/ddAddColumn.png \ + include/images/ddAddColumnCursor.png \ + include/images/ddAddForeignKey.png \ + include/images/ddDeleteTableCursor.png \ + include/images/ddDown.png \ + include/images/ddMaximizeTable.png \ + include/images/ddMinMaxCursor.png \ + include/images/ddMinimizeTable.png \ + include/images/ddRelationshipCursor.png \ + include/images/ddRemoveColumn.png \ + include/images/ddRemoveColumnCursor.png \ + include/images/ddRemoveTable.png \ + include/images/ddRemoveTable2.png \ + include/images/ddUp.png \ + include/images/ddcancel.png \ + include/images/ddforeignkey.png \ + include/images/ddforeignkeyfromuk.png \ + include/images/ddforeignkeyuniquekey.png \ + include/images/ddforeignkeyuniquekeyfromuk.png \ + include/images/ddgendiagram.png \ + include/images/ddmodel-32.png \ + include/images/ddnewdiagram.png \ + include/images/ddnotnull.png \ + include/images/ddnull.png \ + include/images/ddprimaryforeignkey.png \ + include/images/ddprimaryforeignkeyfromuk.png \ + include/images/ddprimarykey.png \ + include/images/ddprimarykeyuniquekey.png \ + include/images/ddunique.png \ + include/images/debugger.png \ + include/images/delete.png \ + include/images/dictionary.png \ + include/images/dictionaries.png \ + include/images/disabled.png \ + include/images/dnd_copy.png \ + include/images/dnd_move.png \ + include/images/dnd_none.png \ + include/images/domain-sm.png \ + include/images/domain.png \ + include/images/domains.png \ + include/images/extension-sm.png \ + include/images/extension.png \ + include/images/extensions.png \ + include/images/down.png \ + include/images/drop.png \ + include/images/edit_clear.png \ + include/images/edit_find.png \ + include/images/edit_redo.png \ + include/images/edit_undo.png \ + include/images/enumeration.png \ + include/images/enumerations.png \ + include/images/ex_aggregate.png \ + include/images/ex_append.png \ + include/images/ex_bmp_and.png \ + include/images/ex_bmp_heap.png \ + include/images/ex_bmp_index.png \ + include/images/ex_bmp_or.png \ + include/images/ex_cte_scan.png \ + include/images/ex_delete.png \ + include/images/ex_foreign_scan.png \ + include/images/ex_group.png \ + include/images/ex_hash.png \ + include/images/ex_hash_anti_join.png \ + include/images/ex_hash_semi_join.png \ + include/images/ex_hash_setop_except.png \ + include/images/ex_hash_setop_except_all.png \ + include/images/ex_hash_setop_intersect.png \ + include/images/ex_hash_setop_intersect_all.png \ + include/images/ex_hash_setop_unknown.png \ + include/images/ex_index_only_scan.png \ + include/images/ex_index_scan.png \ + include/images/ex_insert.png \ + include/images/ex_join.png \ + include/images/ex_limit.png \ + include/images/ex_lock_rows.png \ + include/images/ex_materialize.png \ + include/images/ex_merge.png \ + include/images/ex_merge_anti_join.png \ + include/images/ex_merge_append.png \ + include/images/ex_merge_semi_join.png \ + include/images/ex_nested.png \ + include/images/ex_nested_loop_anti_join.png \ + include/images/ex_nested_loop_semi_join.png \ + include/images/ex_recursive_union.png \ + include/images/ex_result.png \ + include/images/ex_scan.png \ + include/images/ex_seek.png \ + include/images/ex_setop.png \ + include/images/ex_sort.png \ + include/images/ex_subplan.png \ + include/images/ex_tid_scan.png \ + include/images/ex_unique.png \ + include/images/ex_unknown.png \ + include/images/ex_update.png \ + include/images/ex_values_scan.png \ + include/images/ex_window_aggregate.png \ + include/images/ex_worktable_scan.png \ + include/images/exclude.png \ + include/images/favourite.png \ + include/images/file_new.png \ + include/images/file_open.png \ + include/images/file_save.png \ + include/images/folder.png \ + include/images/foreigndatawrapper.png \ + include/images/foreigndatawrapper-sm.png \ + include/images/foreigndatawrappers.png \ + include/images/foreignkey.png \ + include/images/foreignkeybad.png \ + include/images/foreignserver.png \ + include/images/foreignserver-sm.png \ + include/images/foreignservers.png \ + include/images/foreigntable.png \ + include/images/foreigntables.png \ + include/images/forward.png \ + include/images/function.png \ + include/images/functions.png \ + include/images/gqbAdd.png \ + include/images/gqbAddRest.png \ + include/images/gqbColNotSel.png \ + include/images/gqbColSel.png \ + include/images/gqbDown.png \ + include/images/gqbDownBottom.png \ + include/images/gqbJoin.png \ + include/images/gqbJoinCursor.png \ + include/images/gqbOrderAdd.png \ + include/images/gqbOrderAddAll.png \ + include/images/gqbOrderRemove.png \ + include/images/gqbOrderRemoveAll.png \ + include/images/gqbRemove.png \ + include/images/gqbRemoveRest.png \ + include/images/gqbUp.png \ + include/images/gqbUpTop.png \ + include/images/group.png \ + include/images/groups.png \ + include/images/help.png \ + include/images/help2.png \ + include/images/hint.png \ + include/images/hint2.png \ + include/images/index.png \ + include/images/indexes.png \ + include/images/job.png \ + include/images/jobdisabled.png \ + include/images/jobs.png \ + include/images/key.png \ + include/images/language-sm.png \ + include/images/language.png \ + include/images/languages.png \ + include/images/loginroles.png \ + include/images/mview.png \ + include/images/mview-sm.png \ + include/images/namespace-sm.png \ + include/images/namespace.png \ + include/images/namespaces.png \ + include/images/operator.png \ + include/images/operators.png \ + include/images/operatorclass.png \ + include/images/operatorclasses.png \ + include/images/operatorfamily.png \ + include/images/operatorfamilies.png \ + include/images/package.png \ + include/images/packages.png \ + include/images/parser.png \ + include/images/parsers.png \ + include/images/plugins.png \ + include/images/pgAdmin3.png \ + include/images/pgAdmin3-16.png \ + include/images/pgAdmin3-32.png \ + include/images/primarykey.png \ + include/images/procedures.png \ + include/images/procedure.png \ + include/images/properties.png \ + include/images/property.png \ + include/images/query_cancel.png \ + include/images/query_execfile.png \ + include/images/query_execute.png \ + include/images/query_explain.png \ + include/images/query_commit.png \ + include/images/query_rollback.png \ + include/images/query_pgscript.png \ + include/images/readdata.png \ + include/images/refresh.png \ + include/images/reload.png \ + include/images/resourcegroup.png \ + include/images/resourcegroups.png \ + include/images/restore.png \ + include/images/roles.png \ + include/images/rule.png \ + include/images/rulebad.png \ + include/images/rules.png \ + include/images/schedule.png \ + include/images/schedules.png \ + include/images/sequence-repl.png \ + include/images/sequence.png \ + include/images/sequences.png \ + include/images/server-sm.png \ + include/images/server.png \ + include/images/serverbad-sm.png \ + include/images/serverbad.png \ + include/images/servers.png \ + include/images/setBreak.png \ + include/images/slcluster.png \ + include/images/slclusters.png \ + include/images/sllisten.png \ + include/images/sllistens.png \ + include/images/slnode-disabled.png \ + include/images/slnode-local.png \ + include/images/slnode.png \ + include/images/slnodes.png \ + include/images/slpath.png \ + include/images/slpaths.png \ + include/images/slset.png \ + include/images/slset2.png \ + include/images/slsets.png \ + include/images/slsubscription.png \ + include/images/slsubscription2.png \ + include/images/slsubscriptions.png \ + include/images/sortfilter.png \ + include/images/splash.png \ + include/images/sql.png \ + include/images/sql-16.png \ + include/images/sql-32.png \ + include/images/statistics.png \ + include/images/step.png \ + include/images/steps.png \ + include/images/stepInto.png \ + include/images/stepOver.png \ + include/images/stop.png \ + include/images/storedata.png \ + include/images/synonym.png \ + include/images/synonyms.png \ + include/images/table-repl-sm.png \ + include/images/table-repl.png \ + include/images/table-sm.png \ + include/images/table.png \ + include/images/tables.png \ + include/images/tablespace.png \ + include/images/tablespaces.png \ + include/images/template.png \ + include/images/templates.png \ + include/images/terminate_backend.png \ + include/images/textsearch.png \ + include/images/trigger.png \ + include/images/triggerbad.png \ + include/images/triggerfunction.png \ + include/images/triggerfunctions.png \ + include/images/triggers.png \ + include/images/type.png \ + include/images/types.png \ + include/images/uncheck.png \ + include/images/unchecked.png \ + include/images/unique.png \ + include/images/up.png \ + include/images/user.png \ + include/images/usermapping.png \ + include/images/usermapping-sm.png \ + include/images/usermappings.png \ + include/images/users.png \ + include/images/vacuum.png \ + include/images/variable.png \ + include/images/variables.png \ + include/images/view-sm.png \ + include/images/view.png \ + include/images/viewdata.png \ + include/images/viewfiltereddata.png \ + include/images/views.png \ + include/images/ex_broadcast_motion.png \ + include/images/ex_redistribute_motion.png \ + include/images/ex_gather_motion.png \ + include/images/exttable-sm.png \ + include/images/exttables.png \ + include/images/exttable.png + +EXTRA_DIST += \ + include/images/module.mk \ + include/images/pgAdmin3.ico \ + include/images/sql.ico + diff --git a/include/images/mview-sm.png b/include/images/mview-sm.png new file mode 100644 index 0000000..7b72bdb Binary files /dev/null and b/include/images/mview-sm.png differ diff --git a/include/images/mview-sm.pngc b/include/images/mview-sm.pngc new file mode 100644 index 0000000..52b3b49 --- /dev/null +++ b/include/images/mview-sm.pngc @@ -0,0 +1,87 @@ +#ifndef MVIEW_SM_PNG_H +#define MVIEW_SM_PNG_H + +static const unsigned char mview_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x01, 0x0a, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, +0x63, 0x60, 0x18, 0x68, 0xc0, 0x08, 0x63, 0x6c, +0xb9, 0x18, 0xfd, 0xff, 0xc5, 0xb7, 0x83, 0x44, +0x69, 0x32, 0x94, 0x29, 0x64, 0x30, 0x96, 0x2d, +0x66, 0x64, 0x60, 0x60, 0x60, 0x60, 0x81, 0x09, +0xbe, 0xfa, 0x7e, 0x94, 0xc1, 0xcd, 0xb4, 0x8a, +0x81, 0xf1, 0x97, 0x20, 0xc3, 0xff, 0x1f, 0xe2, +0x0c, 0x4c, 0x7f, 0x44, 0x19, 0x18, 0xff, 0x72, +0x33, 0x30, 0xfe, 0xe7, 0x80, 0x6b, 0xfc, 0xcf, +0xf8, 0x83, 0xe1, 0x13, 0xc3, 0x69, 0x86, 0xbb, +0xaf, 0x36, 0xc1, 0xc5, 0xe0, 0x06, 0xfc, 0xfb, +0xff, 0x87, 0xe1, 0x3f, 0xf3, 0x57, 0x86, 0x5d, +0x17, 0xdb, 0xf0, 0xda, 0x2e, 0xad, 0xc8, 0xc5, +0xf0, 0xe2, 0xdb, 0x37, 0x4c, 0x03, 0x90, 0x41, +0xb2, 0xc5, 0x63, 0xac, 0x9a, 0xe7, 0x9e, 0x90, +0xc5, 0x10, 0x63, 0xc1, 0x65, 0x13, 0xba, 0x62, +0x5c, 0x86, 0xb2, 0xe0, 0x73, 0xae, 0x83, 0xea, +0x04, 0x06, 0xae, 0x5f, 0x56, 0x0c, 0xdb, 0x1e, +0x9a, 0xe1, 0x54, 0x83, 0xd7, 0x80, 0xf7, 0xec, +0xab, 0x18, 0x54, 0x44, 0x42, 0x18, 0xe6, 0x1c, +0x97, 0x81, 0x8b, 0x79, 0x4a, 0xdc, 0x42, 0xe1, +0xe3, 0x35, 0xe0, 0xe2, 0x95, 0x63, 0x0c, 0x0c, +0x0c, 0x0c, 0x0c, 0x29, 0x96, 0x4f, 0x18, 0x92, +0xff, 0x43, 0x68, 0xa2, 0x5d, 0x00, 0xf3, 0x73, +0x0a, 0x03, 0x23, 0xc3, 0x9c, 0xe3, 0x32, 0x0c, +0x8c, 0x8c, 0x10, 0x1a, 0xdd, 0x10, 0x16, 0x62, +0x43, 0x1b, 0xd9, 0xd9, 0x78, 0x0d, 0x70, 0x31, +0xcf, 0x62, 0xf8, 0xf3, 0xef, 0x07, 0xc3, 0xdf, +0x7f, 0xdf, 0x19, 0x3e, 0xfd, 0x7c, 0xc8, 0xc0, +0xc0, 0xb0, 0x8a, 0x41, 0x5d, 0x43, 0x85, 0x81, +0x81, 0x81, 0x81, 0xe1, 0xfb, 0xef, 0x77, 0x0c, +0x0c, 0x0c, 0x4f, 0xb0, 0x27, 0xe5, 0xb3, 0x8f, +0x7b, 0xff, 0x9f, 0x7f, 0xd2, 0x4f, 0x72, 0x52, +0x1e, 0x78, 0x00, 0x00, 0x10, 0x6b, 0x57, 0x5d, +0x16, 0xbb, 0xff, 0xb2, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *mview_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_mview_sm_png = new wxImage(); + if (!img_mview_sm_png || !img_mview_sm_png->IsOk()) + { + wxMemoryInputStream img_mview_sm_pngIS(mview_sm_png_data, sizeof(mview_sm_png_data)); + img_mview_sm_png->LoadFile(img_mview_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_mview_sm_png; +} +#define mview_sm_png_img mview_sm_png_img() + +static wxBitmap *mview_sm_png_bmp() +{ + static wxBitmap *bmp_mview_sm_png; + if (!bmp_mview_sm_png || !bmp_mview_sm_png->IsOk()) + bmp_mview_sm_png = new wxBitmap(*mview_sm_png_img); + return bmp_mview_sm_png; +} +#define mview_sm_png_bmp mview_sm_png_bmp() + +static wxIcon *mview_sm_png_ico() +{ + static wxIcon *ico_mview_sm_png; + if (!ico_mview_sm_png || !ico_mview_sm_png->IsOk()) + { + ico_mview_sm_png = new wxIcon(); + ico_mview_sm_png->CopyFromBitmap(*mview_sm_png_bmp); + } + return ico_mview_sm_png; +} +#define mview_sm_png_ico mview_sm_png_ico() + +#endif // MVIEW_SM_PNG_H diff --git a/include/images/mview.png b/include/images/mview.png new file mode 100644 index 0000000..40e65a9 Binary files /dev/null and b/include/images/mview.png differ diff --git a/include/images/mview.pngc b/include/images/mview.pngc new file mode 100644 index 0000000..0167419 --- /dev/null +++ b/include/images/mview.pngc @@ -0,0 +1,91 @@ +#ifndef MVIEW_PNG_H +#define MVIEW_PNG_H + +static const unsigned char mview_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, +0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, +0x01, 0x28, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, +0xa5, 0x93, 0xbf, 0x4a, 0xc3, 0x50, 0x14, 0x87, +0xbf, 0xdb, 0x46, 0x8a, 0x82, 0xd5, 0xcd, 0x82, +0xc9, 0x20, 0x08, 0x3a, 0xb8, 0x88, 0xa0, 0xd5, +0xc5, 0xa5, 0x0e, 0x3e, 0x85, 0x43, 0x3b, 0x89, +0x20, 0xe2, 0xe2, 0x33, 0x08, 0xe2, 0x0b, 0xa4, +0x2f, 0xe0, 0xe4, 0x22, 0x0e, 0x4e, 0x2e, 0x26, +0x88, 0x41, 0xb7, 0x42, 0x05, 0x07, 0x9b, 0xd9, +0x45, 0x12, 0x63, 0x93, 0xdc, 0xeb, 0xa0, 0x04, +0x13, 0x9a, 0x1a, 0xc9, 0x5d, 0x2e, 0x87, 0x7b, +0x7e, 0xdf, 0xf9, 0x77, 0x0f, 0x94, 0x3c, 0x02, +0xc0, 0x19, 0x9c, 0xa9, 0x47, 0xf7, 0xfc, 0x5f, +0xc2, 0xce, 0xa6, 0x2b, 0x12, 0x80, 0x69, 0xe9, +0x6a, 0xa7, 0x79, 0x08, 0x51, 0x0d, 0x35, 0x9c, +0x85, 0xa0, 0x41, 0x35, 0x9a, 0xa3, 0x22, 0xeb, +0x08, 0x55, 0x4b, 0x44, 0x4a, 0x7c, 0xf2, 0x8e, +0xc3, 0x9b, 0xb8, 0xe6, 0xf9, 0xf5, 0x8e, 0xbd, +0xf5, 0x9e, 0xd0, 0x7e, 0x53, 0x6f, 0x1e, 0x4e, +0x0b, 0x45, 0x9f, 0x5f, 0x98, 0x22, 0x8c, 0x7d, +0x00, 0xb4, 0xec, 0x63, 0xbb, 0x39, 0x18, 0x2b, +0xee, 0xda, 0x46, 0xca, 0xd6, 0x8a, 0x38, 0x8d, +0x83, 0x6b, 0x79, 0x91, 0xb6, 0x57, 0x4e, 0x98, +0xf4, 0x5a, 0x54, 0x64, 0x1d, 0xaf, 0x7a, 0xcf, +0xed, 0xcb, 0xc1, 0x48, 0xbf, 0x5c, 0xc0, 0x70, +0xa2, 0x87, 0x37, 0xed, 0x10, 0x4a, 0x8f, 0x50, +0x7a, 0xb9, 0x25, 0xe5, 0x02, 0x94, 0x12, 0x85, +0x1a, 0xaa, 0x15, 0x71, 0xda, 0x9a, 0xb9, 0xc2, +0xb4, 0xf4, 0xc4, 0xde, 0x6d, 0xf4, 0x13, 0x3b, +0x17, 0x60, 0x3f, 0x5d, 0x66, 0x3f, 0x0e, 0x6d, +0xf5, 0x7d, 0xff, 0x99, 0x41, 0xb6, 0xdb, 0x1d, +0x04, 0x4a, 0x29, 0x84, 0x10, 0x98, 0x96, 0x9e, +0x82, 0x68, 0x45, 0x47, 0xd8, 0xb5, 0x8d, 0x54, +0x19, 0x23, 0x01, 0xad, 0x8d, 0x7d, 0x22, 0x19, +0x10, 0xcb, 0x0f, 0x22, 0xe9, 0x13, 0xc6, 0xfe, +0xcf, 0x04, 0x2e, 0x58, 0x5a, 0x5e, 0x24, 0x8c, +0x7d, 0x22, 0x19, 0x00, 0x6e, 0xf9, 0x65, 0x5a, +0xd5, 0x8f, 0x58, 0x33, 0x8e, 0x45, 0xd9, 0x6d, +0xe6, 0x0b, 0x67, 0x7b, 0x6f, 0xb4, 0x6b, 0x3e, +0xe4, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *mview_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_mview_png = new wxImage(); + if (!img_mview_png || !img_mview_png->IsOk()) + { + wxMemoryInputStream img_mview_pngIS(mview_png_data, sizeof(mview_png_data)); + img_mview_png->LoadFile(img_mview_pngIS, wxBITMAP_TYPE_PNG); + } + return img_mview_png; +} +#define mview_png_img mview_png_img() + +static wxBitmap *mview_png_bmp() +{ + static wxBitmap *bmp_mview_png; + if (!bmp_mview_png || !bmp_mview_png->IsOk()) + bmp_mview_png = new wxBitmap(*mview_png_img); + return bmp_mview_png; +} +#define mview_png_bmp mview_png_bmp() + +static wxIcon *mview_png_ico() +{ + static wxIcon *ico_mview_png; + if (!ico_mview_png || !ico_mview_png->IsOk()) + { + ico_mview_png = new wxIcon(); + ico_mview_png->CopyFromBitmap(*mview_png_bmp); + } + return ico_mview_png; +} +#define mview_png_ico mview_png_ico() + +#endif // MVIEW_PNG_H diff --git a/include/images/namespace-sm.png b/include/images/namespace-sm.png new file mode 100644 index 0000000..b16dc1e Binary files /dev/null and b/include/images/namespace-sm.png differ diff --git a/include/images/namespace-sm.pngc b/include/images/namespace-sm.pngc new file mode 100644 index 0000000..f78cc91 --- /dev/null +++ b/include/images/namespace-sm.pngc @@ -0,0 +1,85 @@ +#ifndef NAMESPACE_SM_PNG_H +#define NAMESPACE_SM_PNG_H + +static const unsigned char namespace_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd8, 0x94, 0x94, 0xbd, +0x49, 0x49, 0xff, 0x8d, 0x8d, 0xff, 0x88, 0x88, +0xff, 0x83, 0x83, 0xff, 0xff, 0xff, 0xff, 0x7d, +0x7d, 0xff, 0x76, 0x76, 0xff, 0x6f, 0x6f, 0xff, +0x68, 0x68, 0xff, 0x60, 0x60, 0xff, 0x5c, 0x5c, +0xac, 0xe6, 0x88, 0x75, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x06, 0x61, 0x66, 0xb8, 0x7d, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x45, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, +0x0b, 0x18, 0x15, 0xa1, 0x0c, 0x21, 0x23, 0x01, +0x88, 0x80, 0x8a, 0x0a, 0x44, 0x48, 0x28, 0x28, +0x29, 0x08, 0x24, 0xc4, 0xa8, 0xae, 0xa6, 0xa6, +0x0e, 0x12, 0x62, 0x6a, 0x4a, 0x52, 0x4a, 0x6a, +0x02, 0x89, 0x68, 0xaa, 0xa9, 0x69, 0x82, 0x15, +0x09, 0x2d, 0x4a, 0x5a, 0x04, 0xd6, 0xc6, 0xa8, +0xad, 0x0d, 0x35, 0x48, 0xe8, 0x90, 0x00, 0x9a, +0xc9, 0xa8, 0x00, 0x00, 0x27, 0x75, 0x08, 0xb7, +0x3c, 0xf4, 0xbe, 0xbd, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *namespace_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_namespace_sm_png = new wxImage(); + if (!img_namespace_sm_png || !img_namespace_sm_png->IsOk()) + { + wxMemoryInputStream img_namespace_sm_pngIS(namespace_sm_png_data, sizeof(namespace_sm_png_data)); + img_namespace_sm_png->LoadFile(img_namespace_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_namespace_sm_png; +} +#define namespace_sm_png_img namespace_sm_png_img() + +static wxBitmap *namespace_sm_png_bmp() +{ + static wxBitmap *bmp_namespace_sm_png; + if (!bmp_namespace_sm_png || !bmp_namespace_sm_png->IsOk()) + bmp_namespace_sm_png = new wxBitmap(*namespace_sm_png_img); + return bmp_namespace_sm_png; +} +#define namespace_sm_png_bmp namespace_sm_png_bmp() + +static wxIcon *namespace_sm_png_ico() +{ + static wxIcon *ico_namespace_sm_png; + if (!ico_namespace_sm_png || !ico_namespace_sm_png->IsOk()) + { + ico_namespace_sm_png = new wxIcon(); + ico_namespace_sm_png->CopyFromBitmap(*namespace_sm_png_bmp); + } + return ico_namespace_sm_png; +} +#define namespace_sm_png_ico namespace_sm_png_ico() + +#endif // NAMESPACE_SM_PNG_H diff --git a/include/images/namespace.png b/include/images/namespace.png new file mode 100644 index 0000000..4dacf18 Binary files /dev/null and b/include/images/namespace.png differ diff --git a/include/images/namespace.pngc b/include/images/namespace.pngc new file mode 100644 index 0000000..1883277 --- /dev/null +++ b/include/images/namespace.pngc @@ -0,0 +1,91 @@ +#ifndef NAMESPACE_PNG_H +#define NAMESPACE_PNG_H + +static const unsigned char namespace_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x36, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd8, 0x94, 0x94, 0xbd, +0x49, 0x49, 0xff, 0x8d, 0x8d, 0xff, 0x8a, 0x8a, +0xff, 0x88, 0x88, 0xff, 0x84, 0x84, 0xff, 0xff, +0xff, 0xff, 0x80, 0x80, 0xff, 0x7c, 0x7c, 0xff, +0x77, 0x77, 0xff, 0x73, 0x73, 0xff, 0x6d, 0x6d, +0xff, 0x69, 0x69, 0xff, 0x65, 0x65, 0xff, 0x60, +0x60, 0xff, 0x5e, 0x5e, 0xff, 0x59, 0x59, 0xfb, +0x3f, 0x48, 0xc1, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x07, 0x16, 0x61, 0x88, 0xeb, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x6c, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x4f, 0x8b, 0x12, +0x80, 0x20, 0x08, 0x83, 0x59, 0x69, 0xf8, 0xca, +0xff, 0xff, 0xd9, 0x04, 0xcf, 0xd3, 0xe2, 0x38, +0x75, 0x43, 0xd8, 0x20, 0xb2, 0x60, 0x80, 0x69, +0x0b, 0x86, 0x73, 0x3b, 0xc3, 0x38, 0xd0, 0x93, +0x17, 0x3e, 0xc1, 0x76, 0x4c, 0x7c, 0x81, 0xbd, +0xb7, 0x6b, 0xe0, 0xa0, 0x58, 0x99, 0xa0, 0x0c, +0xe3, 0xee, 0x58, 0x55, 0xbc, 0x3d, 0x09, 0xa2, +0x75, 0x88, 0x40, 0xff, 0x08, 0x08, 0xd1, 0x88, +0x18, 0x8d, 0x88, 0xe8, 0x2d, 0x69, 0xb5, 0xa4, +0x31, 0x24, 0xcf, 0xa1, 0x79, 0xca, 0x94, 0x21, +0x5b, 0x96, 0x91, 0xaa, 0xc6, 0xea, 0x6e, 0xf5, +0x41, 0xcf, 0xcf, 0x32, 0xad, 0xfd, 0xd7, 0x9d, +0xf8, 0x05, 0x47, 0x4f, 0x02, 0xa5, 0xaf, 0xb6, +0x01, 0x95, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *namespace_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_namespace_png = new wxImage(); + if (!img_namespace_png || !img_namespace_png->IsOk()) + { + wxMemoryInputStream img_namespace_pngIS(namespace_png_data, sizeof(namespace_png_data)); + img_namespace_png->LoadFile(img_namespace_pngIS, wxBITMAP_TYPE_PNG); + } + return img_namespace_png; +} +#define namespace_png_img namespace_png_img() + +static wxBitmap *namespace_png_bmp() +{ + static wxBitmap *bmp_namespace_png; + if (!bmp_namespace_png || !bmp_namespace_png->IsOk()) + bmp_namespace_png = new wxBitmap(*namespace_png_img); + return bmp_namespace_png; +} +#define namespace_png_bmp namespace_png_bmp() + +static wxIcon *namespace_png_ico() +{ + static wxIcon *ico_namespace_png; + if (!ico_namespace_png || !ico_namespace_png->IsOk()) + { + ico_namespace_png = new wxIcon(); + ico_namespace_png->CopyFromBitmap(*namespace_png_bmp); + } + return ico_namespace_png; +} +#define namespace_png_ico namespace_png_ico() + +#endif // NAMESPACE_PNG_H diff --git a/include/images/namespaces.png b/include/images/namespaces.png new file mode 100644 index 0000000..9733882 Binary files /dev/null and b/include/images/namespaces.png differ diff --git a/include/images/namespaces.pngc b/include/images/namespaces.pngc new file mode 100644 index 0000000..5ffccc4 --- /dev/null +++ b/include/images/namespaces.pngc @@ -0,0 +1,91 @@ +#ifndef NAMESPACES_PNG_H +#define NAMESPACES_PNG_H + +static const unsigned char namespaces_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd8, 0x94, 0x94, 0xbd, +0x49, 0x49, 0xff, 0x8d, 0x8d, 0xff, 0x88, 0x88, +0xff, 0x83, 0x83, 0xff, 0xff, 0xff, 0xc8, 0x68, +0x68, 0xff, 0x7d, 0x7d, 0xd8, 0x5e, 0x5e, 0xff, +0x76, 0x76, 0xff, 0x6f, 0x6f, 0xff, 0x68, 0x68, +0xff, 0x60, 0x60, 0xff, 0x5c, 0x5c, 0x15, 0x89, +0x1c, 0x8d, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x06, +0x61, 0x66, 0xb8, 0x7d, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x73, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x2d, 0x8e, 0x51, 0x15, 0x80, +0x30, 0x08, 0x45, 0xa1, 0xc1, 0xa4, 0xc1, 0xd0, +0xa1, 0x47, 0xa7, 0x1f, 0x46, 0x58, 0x84, 0x45, +0x20, 0x8a, 0x11, 0x8c, 0x60, 0x04, 0x23, 0x18, +0xc1, 0x08, 0x26, 0x91, 0x4d, 0xe1, 0x87, 0x73, +0xcf, 0x85, 0x07, 0x00, 0x90, 0x83, 0x5a, 0xd8, +0xfa, 0x6f, 0xa0, 0x94, 0x2a, 0xc2, 0x20, 0xa1, +0x2f, 0x8c, 0x36, 0xd5, 0x7d, 0x35, 0x36, 0x0a, +0x4b, 0xd7, 0x19, 0xa2, 0xb3, 0xe5, 0xac, 0xd9, +0x01, 0x72, 0x1a, 0x44, 0x06, 0x6f, 0x32, 0x1f, +0x6a, 0x5d, 0xe4, 0x49, 0x64, 0xf2, 0x26, 0x8f, +0x7c, 0xe9, 0xe5, 0x4c, 0x56, 0x9d, 0x67, 0xdb, +0xc2, 0x28, 0x91, 0x9f, 0x72, 0x9b, 0xee, 0xbb, +0xa9, 0x69, 0xb8, 0xfc, 0xa1, 0xff, 0x1b, 0x2f, +0x82, 0xd6, 0x15, 0x62, 0xd1, 0x7d, 0xf3, 0x7e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *namespaces_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_namespaces_png = new wxImage(); + if (!img_namespaces_png || !img_namespaces_png->IsOk()) + { + wxMemoryInputStream img_namespaces_pngIS(namespaces_png_data, sizeof(namespaces_png_data)); + img_namespaces_png->LoadFile(img_namespaces_pngIS, wxBITMAP_TYPE_PNG); + } + return img_namespaces_png; +} +#define namespaces_png_img namespaces_png_img() + +static wxBitmap *namespaces_png_bmp() +{ + static wxBitmap *bmp_namespaces_png; + if (!bmp_namespaces_png || !bmp_namespaces_png->IsOk()) + bmp_namespaces_png = new wxBitmap(*namespaces_png_img); + return bmp_namespaces_png; +} +#define namespaces_png_bmp namespaces_png_bmp() + +static wxIcon *namespaces_png_ico() +{ + static wxIcon *ico_namespaces_png; + if (!ico_namespaces_png || !ico_namespaces_png->IsOk()) + { + ico_namespaces_png = new wxIcon(); + ico_namespaces_png->CopyFromBitmap(*namespaces_png_bmp); + } + return ico_namespaces_png; +} +#define namespaces_png_ico namespaces_png_ico() + +#endif // NAMESPACES_PNG_H diff --git a/include/images/operator.png b/include/images/operator.png new file mode 100644 index 0000000..1c82730 Binary files /dev/null and b/include/images/operator.png differ diff --git a/include/images/operator.pngc b/include/images/operator.pngc new file mode 100644 index 0000000..c8eba3a --- /dev/null +++ b/include/images/operator.pngc @@ -0,0 +1,84 @@ +#ifndef OPERATOR_PNG_H +#define OPERATOR_PNG_H + +static const unsigned char operator_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xaa, +0xaa, 0xaa, 0xe7, 0xea, 0xf5, 0xe5, 0xe9, 0xf5, +0xe3, 0xe9, 0xf5, 0xe1, 0xe8, 0xf4, 0xdf, 0xe7, +0xf4, 0xdd, 0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xd8, +0xe5, 0xf3, 0xd6, 0xe4, 0xf3, 0xd4, 0xe3, 0xf3, +0xd2, 0xe2, 0xf2, 0x34, 0x9e, 0x47, 0xe6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x48, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, 0x06, 0x18, +0x85, 0xa0, 0x0c, 0x61, 0x47, 0x28, 0x43, 0x24, +0x10, 0xca, 0x10, 0x4d, 0x84, 0xa8, 0x10, 0x14, +0x2b, 0x14, 0x04, 0xa9, 0x12, 0x76, 0x4d, 0xef, +0x5c, 0x7d, 0x10, 0xa4, 0x22, 0xac, 0x62, 0xd6, +0x9e, 0x8b, 0x40, 0x86, 0xa2, 0xa0, 0xe4, 0x42, +0x41, 0x01, 0xb0, 0x2a, 0xa9, 0x8d, 0x50, 0x5d, +0xd2, 0x07, 0xa1, 0x0c, 0x99, 0x8b, 0x30, 0x2b, +0x04, 0xb0, 0xda, 0x0c, 0x00, 0xfc, 0xee, 0x0b, +0x6e, 0xfb, 0x04, 0xfd, 0x81, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operator_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operator_png = new wxImage(); + if (!img_operator_png || !img_operator_png->IsOk()) + { + wxMemoryInputStream img_operator_pngIS(operator_png_data, sizeof(operator_png_data)); + img_operator_png->LoadFile(img_operator_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operator_png; +} +#define operator_png_img operator_png_img() + +static wxBitmap *operator_png_bmp() +{ + static wxBitmap *bmp_operator_png; + if (!bmp_operator_png || !bmp_operator_png->IsOk()) + bmp_operator_png = new wxBitmap(*operator_png_img); + return bmp_operator_png; +} +#define operator_png_bmp operator_png_bmp() + +static wxIcon *operator_png_ico() +{ + static wxIcon *ico_operator_png; + if (!ico_operator_png || !ico_operator_png->IsOk()) + { + ico_operator_png = new wxIcon(); + ico_operator_png->CopyFromBitmap(*operator_png_bmp); + } + return ico_operator_png; +} +#define operator_png_ico operator_png_ico() + +#endif // OPERATOR_PNG_H diff --git a/include/images/operatorclass.png b/include/images/operatorclass.png new file mode 100644 index 0000000..175fc51 Binary files /dev/null and b/include/images/operatorclass.png differ diff --git a/include/images/operatorclass.pngc b/include/images/operatorclass.pngc new file mode 100644 index 0000000..4a92043 --- /dev/null +++ b/include/images/operatorclass.pngc @@ -0,0 +1,118 @@ +#ifndef OPERATORCLASS_PNG_H +#define OPERATORCLASS_PNG_H + +static const unsigned char operatorclass_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xb7, 0xb7, 0x93, +0x93, 0x93, 0x79, 0x79, 0x79, 0xc2, 0xc2, 0xc2, +0x88, 0x88, 0x8b, 0xac, 0xad, 0xb3, 0xc9, 0xcc, +0xd4, 0xde, 0xe1, 0xec, 0xdd, 0xe0, 0xec, 0xc7, +0xcb, 0xd4, 0xa9, 0xac, 0xb2, 0x86, 0x88, 0x8a, +0xb2, 0xb2, 0xb2, 0xa1, 0xa1, 0xa6, 0xd5, 0xd7, +0xe0, 0xe7, 0xea, 0xf5, 0xe6, 0xea, 0xf5, 0xe5, +0xe9, 0xf5, 0xe4, 0xe9, 0xf5, 0xe2, 0xe8, 0xf5, +0xe1, 0xe8, 0xf4, 0xcd, 0xd3, 0xde, 0x9c, 0x9f, +0xa5, 0xe2, 0xe4, 0xef, 0xa0, 0xa1, 0xa6, 0x6f, +0x6f, 0x6f, 0x9e, 0xa1, 0xa6, 0xdf, 0xe7, 0xf4, +0xde, 0xe7, 0xf4, 0xd6, 0xdf, 0xed, 0x9b, 0x9f, +0xa4, 0xe1, 0x76, 0x55, 0xdf, 0x70, 0x52, 0xdc, +0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xc8, 0xd2, 0xdd, +0x84, 0x87, 0x8a, 0xdd, 0x6a, 0x4e, 0xd9, 0xe5, +0xf3, 0xd8, 0xe4, 0xf3, 0xa3, 0xaa, 0xb1, 0xdb, +0x63, 0x4a, 0x9a, 0x9f, 0xa5, 0xd6, 0xe4, 0xf3, +0xbc, 0xc6, 0xd2, 0xd8, 0x5c, 0x46, 0xd6, 0x55, +0x42, 0xd4, 0x4e, 0x3e, 0xd1, 0x47, 0x3a, 0xd5, +0xe3, 0xf3, 0xcc, 0xdb, 0xe9, 0xcf, 0x40, 0x36, +0xd3, 0xe3, 0xf2, 0xcb, 0xda, 0xe9, 0x98, 0x9f, +0xa5, 0xd2, 0xe2, 0xf2, 0xb8, 0xc5, 0xd2, 0xd0, +0xe1, 0xf2, 0x9f, 0xa8, 0xb1, 0xbf, 0xce, 0xdc, +0x82, 0x86, 0x8a, 0xca, 0xdb, 0xeb, 0x95, 0x9d, +0xa4, 0x6d, 0xd0, 0x21, 0xd2, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xc3, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x3d, 0x8f, 0xe7, 0x12, 0x82, 0x40, 0x0c, +0x84, 0x8f, 0x3b, 0x50, 0xa4, 0xd8, 0x05, 0x8d, +0x60, 0xa1, 0x0a, 0x8a, 0xa0, 0x58, 0x00, 0x0b, +0xef, 0xff, 0x56, 0x5e, 0x40, 0xcd, 0x8f, 0x4c, +0x76, 0xf2, 0x4d, 0xb2, 0x4b, 0x08, 0x96, 0x40, +0x19, 0xa3, 0x02, 0xf9, 0x95, 0x28, 0x75, 0xba, +0x72, 0x4f, 0x51, 0x35, 0xb1, 0xd5, 0x7a, 0x7f, +0x30, 0x1c, 0x8d, 0x27, 0xd3, 0x99, 0x61, 0xea, +0xcd, 0xbe, 0x3f, 0x1f, 0x8e, 0x16, 0x00, 0x4b, +0xcb, 0x5e, 0xad, 0x91, 0x91, 0x70, 0x0f, 0x9b, +0x2d, 0xd8, 0x8e, 0xeb, 0xf9, 0xfc, 0x5e, 0x07, +0x79, 0xd8, 0x06, 0xe0, 0xb8, 0xe1, 0x2e, 0x12, +0x08, 0xed, 0x22, 0x0f, 0x41, 0xcc, 0xdb, 0xfe, +0x90, 0x50, 0xc2, 0x64, 0xe4, 0x83, 0xf8, 0x98, +0x66, 0x27, 0x38, 0xe7, 0x8c, 0xb0, 0x1e, 0xf2, +0x8d, 0xbe, 0xc0, 0xf5, 0xc6, 0x08, 0x55, 0xa6, +0x4b, 0x4e, 0xa7, 0x19, 0x6f, 0xf7, 0xa2, 0xa4, +0x44, 0x50, 0x67, 0x96, 0xed, 0x00, 0xf2, 0xd7, +0xa2, 0x7a, 0x70, 0xbb, 0x9a, 0xc1, 0xff, 0x01, +0xf2, 0x45, 0xf5, 0x7c, 0xa1, 0x31, 0x73, 0xe5, +0x86, 0x7b, 0xe4, 0xab, 0x77, 0xdd, 0x9a, 0x5f, +0x7b, 0xbb, 0x03, 0xf2, 0xcf, 0x5a, 0xff, 0xa6, +0xf3, 0xa3, 0x24, 0xbf, 0x95, 0x8f, 0x97, 0xf8, +0xcf, 0xdb, 0xc4, 0x6f, 0xc7, 0x0f, 0x91, 0xe7, +0x17, 0x02, 0x64, 0xce, 0x51, 0xf5, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorclass_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorclass_png = new wxImage(); + if (!img_operatorclass_png || !img_operatorclass_png->IsOk()) + { + wxMemoryInputStream img_operatorclass_pngIS(operatorclass_png_data, sizeof(operatorclass_png_data)); + img_operatorclass_png->LoadFile(img_operatorclass_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorclass_png; +} +#define operatorclass_png_img operatorclass_png_img() + +static wxBitmap *operatorclass_png_bmp() +{ + static wxBitmap *bmp_operatorclass_png; + if (!bmp_operatorclass_png || !bmp_operatorclass_png->IsOk()) + bmp_operatorclass_png = new wxBitmap(*operatorclass_png_img); + return bmp_operatorclass_png; +} +#define operatorclass_png_bmp operatorclass_png_bmp() + +static wxIcon *operatorclass_png_ico() +{ + static wxIcon *ico_operatorclass_png; + if (!ico_operatorclass_png || !ico_operatorclass_png->IsOk()) + { + ico_operatorclass_png = new wxIcon(); + ico_operatorclass_png->CopyFromBitmap(*operatorclass_png_bmp); + } + return ico_operatorclass_png; +} +#define operatorclass_png_ico operatorclass_png_ico() + +#endif // OPERATORCLASS_PNG_H diff --git a/include/images/operatorclasses.png b/include/images/operatorclasses.png new file mode 100644 index 0000000..db292e3 Binary files /dev/null and b/include/images/operatorclasses.png differ diff --git a/include/images/operatorclasses.pngc b/include/images/operatorclasses.pngc new file mode 100644 index 0000000..55459b1 --- /dev/null +++ b/include/images/operatorclasses.pngc @@ -0,0 +1,104 @@ +#ifndef OPERATORCLASSES_PNG_H +#define OPERATORCLASSES_PNG_H + +static const unsigned char operatorclasses_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x81, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xba, 0xba, 0xba, 0x8f, +0x8f, 0x8f, 0x73, 0x73, 0x73, 0x7f, 0x7f, 0x80, +0xaa, 0xab, 0xb0, 0xcd, 0xcf, 0xd7, 0xe3, 0xe7, +0xf1, 0xca, 0xce, 0xd7, 0xa6, 0xa9, 0xb0, 0x7d, +0x7e, 0x80, 0xbe, 0xbf, 0xc6, 0xe8, 0xea, 0xf5, +0x9a, 0x9c, 0x9f, 0x6f, 0x6f, 0x6f, 0x7a, 0x7a, +0x7b, 0x72, 0x72, 0x73, 0x7f, 0x80, 0x82, 0x76, +0x77, 0x78, 0xca, 0xcd, 0xd5, 0xa0, 0xa2, 0xa6, +0x9e, 0xa1, 0xa6, 0xdf, 0xe7, 0xf4, 0xb6, 0xbc, +0xc5, 0xe6, 0xea, 0xf5, 0xe0, 0x75, 0x54, 0xdd, +0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xa2, 0xa7, 0xaf, +0xdd, 0x6b, 0x4f, 0x9a, 0x9f, 0xa5, 0xbf, 0xca, +0xd5, 0xda, 0x60, 0x48, 0xd6, 0x55, 0x42, 0xd2, +0x4a, 0x3b, 0xd1, 0xe0, 0xee, 0x99, 0x9f, 0xa5, +0xbb, 0xc8, 0xd5, 0xd4, 0xe3, 0xf2, 0xd1, 0xe2, +0xf2, 0x9d, 0xa6, 0xae, 0x7b, 0x7d, 0x7f, 0xad, +0xb9, 0xc4, 0x94, 0x4a, 0x6b, 0xef, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x8f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x5d, 0x8f, 0xd9, 0x16, 0x82, 0x30, +0x0c, 0x44, 0xdb, 0x20, 0xab, 0x30, 0x40, 0x65, +0x91, 0x5d, 0x36, 0x01, 0xff, 0xff, 0x03, 0xa5, +0xb8, 0xd4, 0x3a, 0x6f, 0x93, 0x73, 0x93, 0xc9, +0x30, 0xc6, 0x18, 0x27, 0x83, 0x38, 0x53, 0x3a, +0x99, 0x96, 0xed, 0xb8, 0x9e, 0xf2, 0x67, 0x3f, +0x40, 0x18, 0xc5, 0xe2, 0xed, 0xb9, 0xe9, 0x5f, +0x34, 0x86, 0xac, 0x40, 0x67, 0x0c, 0x1b, 0x3a, +0x43, 0x4e, 0x78, 0x30, 0x09, 0xd2, 0x2c, 0x97, +0x13, 0xee, 0x46, 0x92, 0xb9, 0xa2, 0x40, 0x59, +0xd5, 0x32, 0xdd, 0x8b, 0x77, 0x26, 0x01, 0x1a, +0xa0, 0xed, 0x48, 0x2e, 0x09, 0xc9, 0x14, 0xcd, +0xad, 0x1f, 0x30, 0x1a, 0xc7, 0xdd, 0x9d, 0x49, +0x81, 0x1e, 0x98, 0x66, 0x7a, 0x45, 0x0b, 0x37, +0x2b, 0x31, 0xe0, 0xbe, 0xac, 0x9f, 0x06, 0x5b, +0x5e, 0xb5, 0x98, 0x96, 0xc7, 0xf6, 0xfd, 0xdf, +0xab, 0xbb, 0x71, 0x5e, 0xb7, 0x9f, 0x86, 0xff, +0x8d, 0x95, 0x9e, 0x77, 0xa9, 0x09, 0x6b, 0xf3, +0xa2, 0xf7, 0x16, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorclasses_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorclasses_png = new wxImage(); + if (!img_operatorclasses_png || !img_operatorclasses_png->IsOk()) + { + wxMemoryInputStream img_operatorclasses_pngIS(operatorclasses_png_data, sizeof(operatorclasses_png_data)); + img_operatorclasses_png->LoadFile(img_operatorclasses_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorclasses_png; +} +#define operatorclasses_png_img operatorclasses_png_img() + +static wxBitmap *operatorclasses_png_bmp() +{ + static wxBitmap *bmp_operatorclasses_png; + if (!bmp_operatorclasses_png || !bmp_operatorclasses_png->IsOk()) + bmp_operatorclasses_png = new wxBitmap(*operatorclasses_png_img); + return bmp_operatorclasses_png; +} +#define operatorclasses_png_bmp operatorclasses_png_bmp() + +static wxIcon *operatorclasses_png_ico() +{ + static wxIcon *ico_operatorclasses_png; + if (!ico_operatorclasses_png || !ico_operatorclasses_png->IsOk()) + { + ico_operatorclasses_png = new wxIcon(); + ico_operatorclasses_png->CopyFromBitmap(*operatorclasses_png_bmp); + } + return ico_operatorclasses_png; +} +#define operatorclasses_png_ico operatorclasses_png_ico() + +#endif // OPERATORCLASSES_PNG_H diff --git a/include/images/operatorfamilies.png b/include/images/operatorfamilies.png new file mode 100644 index 0000000..cad9e59 Binary files /dev/null and b/include/images/operatorfamilies.png differ diff --git a/include/images/operatorfamilies.pngc b/include/images/operatorfamilies.pngc new file mode 100644 index 0000000..3072715 --- /dev/null +++ b/include/images/operatorfamilies.pngc @@ -0,0 +1,98 @@ +#ifndef OPERATORFAMILIES_PNG_H +#define OPERATORFAMILIES_PNG_H + +static const unsigned char operatorfamilies_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x6f, +0x6f, 0x6f, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xfb, 0xfd, 0xfe, 0xf9, 0xfb, 0xfd, 0xf6, 0xf9, +0xfd, 0xf2, 0xf7, 0xfc, 0xef, 0xf5, 0xfb, 0xec, +0xf3, 0xfa, 0xe8, 0xf1, 0xf9, 0xa9, 0xa9, 0xaa, +0xa7, 0xa8, 0xa9, 0xa4, 0xa6, 0xa9, 0xe4, 0xef, +0xf8, 0x5e, 0xe5, 0xda, 0xe0, 0xed, 0xf7, 0x58, +0xdf, 0xd4, 0x9e, 0xa3, 0xa7, 0xdd, 0xea, 0xf6, +0x51, 0xd8, 0xcd, 0x49, 0xd0, 0xc5, 0x42, 0xc9, +0xbe, 0xd9, 0xe8, 0xf5, 0x9b, 0xa1, 0xa6, 0xd6, +0xe6, 0xf4, 0xd3, 0xe4, 0xf3, 0xd0, 0xe3, 0xf3, +0xcd, 0xe1, 0xf2, 0x8a, 0xac, 0xc7, 0xc9, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x7d, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x65, 0x8f, 0x5b, 0x12, 0x82, 0x30, 0x10, 0x04, +0xa1, 0x25, 0x09, 0x24, 0x42, 0x10, 0x10, 0x15, +0xf0, 0xfe, 0xd7, 0x74, 0x37, 0x40, 0x95, 0xc6, +0xf9, 0xec, 0xe9, 0xda, 0x47, 0x51, 0x72, 0xa6, +0x2c, 0x52, 0xb8, 0x54, 0xc6, 0xba, 0xba, 0xf1, +0x81, 0x03, 0x54, 0xd7, 0x5f, 0x07, 0x93, 0x39, +0xd8, 0xcc, 0xc1, 0x65, 0x0e, 0xb5, 0x3a, 0xc6, +0xb6, 0x74, 0x3e, 0x44, 0x05, 0x8d, 0x3a, 0xd6, +0xd1, 0x13, 0xe2, 0x4d, 0x81, 0x57, 0xa7, 0x85, +0x01, 0xc6, 0x49, 0x41, 0x48, 0x4e, 0x3f, 0xdc, +0xe7, 0x07, 0x4f, 0x01, 0x72, 0xa9, 0x38, 0x1d, +0xcc, 0xf0, 0x5a, 0xf6, 0xc5, 0xe2, 0xc8, 0x7c, +0xe9, 0x97, 0x35, 0x01, 0x75, 0x42, 0x1c, 0xa5, +0x5f, 0xb7, 0xf3, 0x7c, 0x99, 0x3f, 0x49, 0xbf, +0xbd, 0x0f, 0xf0, 0xf7, 0xf1, 0x77, 0x3e, 0xa8, +0xcc, 0x05, 0xbf, 0x9f, 0x78, 0xbc, 0xb6, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorfamilies_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorfamilies_png = new wxImage(); + if (!img_operatorfamilies_png || !img_operatorfamilies_png->IsOk()) + { + wxMemoryInputStream img_operatorfamilies_pngIS(operatorfamilies_png_data, sizeof(operatorfamilies_png_data)); + img_operatorfamilies_png->LoadFile(img_operatorfamilies_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorfamilies_png; +} +#define operatorfamilies_png_img operatorfamilies_png_img() + +static wxBitmap *operatorfamilies_png_bmp() +{ + static wxBitmap *bmp_operatorfamilies_png; + if (!bmp_operatorfamilies_png || !bmp_operatorfamilies_png->IsOk()) + bmp_operatorfamilies_png = new wxBitmap(*operatorfamilies_png_img); + return bmp_operatorfamilies_png; +} +#define operatorfamilies_png_bmp operatorfamilies_png_bmp() + +static wxIcon *operatorfamilies_png_ico() +{ + static wxIcon *ico_operatorfamilies_png; + if (!ico_operatorfamilies_png || !ico_operatorfamilies_png->IsOk()) + { + ico_operatorfamilies_png = new wxIcon(); + ico_operatorfamilies_png->CopyFromBitmap(*operatorfamilies_png_bmp); + } + return ico_operatorfamilies_png; +} +#define operatorfamilies_png_ico operatorfamilies_png_ico() + +#endif // OPERATORFAMILIES_PNG_H diff --git a/include/images/operatorfamily.png b/include/images/operatorfamily.png new file mode 100644 index 0000000..461dcee Binary files /dev/null and b/include/images/operatorfamily.png differ diff --git a/include/images/operatorfamily.pngc b/include/images/operatorfamily.pngc new file mode 100644 index 0000000..e06b453 --- /dev/null +++ b/include/images/operatorfamily.pngc @@ -0,0 +1,102 @@ +#ifndef OPERATORFAMILY_PNG_H +#define OPERATORFAMILY_PNG_H + +static const unsigned char operatorfamily_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x6f, +0x6f, 0x6f, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, +0xfc, 0xfd, 0xfe, 0xfa, 0xfc, 0xfe, 0xf9, 0xfb, +0xfd, 0xf6, 0xfa, 0xfd, 0xf4, 0xf8, 0xfc, 0xf2, +0xf7, 0xfc, 0xef, 0xf5, 0xfb, 0xec, 0xf4, 0xfa, +0xea, 0xf2, 0xf9, 0xe7, 0xf1, 0xf9, 0xa7, 0xa8, +0xa9, 0xa4, 0xa6, 0xa9, 0xe4, 0xef, 0xf8, 0x5f, +0xe6, 0xdb, 0x5b, 0xe2, 0xd7, 0xe1, 0xed, 0xf7, +0x57, 0xde, 0xd3, 0xdf, 0xec, 0xf7, 0x53, 0xda, +0xcf, 0x9d, 0xa2, 0xa7, 0xdc, 0xea, 0xf6, 0x4e, +0xd5, 0xca, 0x49, 0xd0, 0xc5, 0x45, 0xcc, 0xc1, +0x40, 0xc7, 0xbc, 0xd9, 0xe8, 0xf5, 0x3c, 0xc3, +0xb8, 0xd7, 0xe7, 0xf4, 0x9a, 0xa0, 0xa6, 0xd4, +0xe5, 0xf4, 0xd2, 0xe4, 0xf3, 0xd0, 0xe3, 0xf3, +0xce, 0xe1, 0xf2, 0xcc, 0xe0, 0xf2, 0x24, 0x8d, +0x77, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x03, +0x11, 0x0c, 0x4c, 0xf2, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x84, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x6d, 0x8f, 0xd9, 0x0e, 0x82, +0x30, 0x14, 0x44, 0x61, 0x70, 0xc5, 0x0d, 0xc5, +0x0a, 0x08, 0x0a, 0xb6, 0xc5, 0xff, 0xff, 0x44, +0xee, 0xcc, 0x93, 0x11, 0xe6, 0xe1, 0x26, 0x73, +0x7a, 0x92, 0x49, 0x93, 0x64, 0x96, 0x14, 0x3f, +0x49, 0x0d, 0x20, 0x5b, 0xad, 0x37, 0xdb, 0xdd, +0x3e, 0x3f, 0x1c, 0x4f, 0x67, 0x10, 0xb0, 0x5f, +0x80, 0xc2, 0xfa, 0x55, 0x80, 0xef, 0xb8, 0x95, +0xb0, 0x7e, 0x17, 0xa0, 0x8f, 0xd2, 0xc1, 0xfa, +0x43, 0x80, 0x3e, 0x5c, 0x65, 0xa7, 0x6e, 0x04, +0xe8, 0xbb, 0xea, 0xd9, 0x76, 0x2f, 0xbc, 0x05, +0xe8, 0xab, 0xf7, 0x18, 0x04, 0xf2, 0xc2, 0xec, +0xb6, 0xb3, 0xf3, 0xf1, 0x02, 0xda, 0xa7, 0x3f, +0xf8, 0x20, 0xa0, 0x7d, 0xfa, 0x3e, 0x44, 0x01, +0xee, 0xd7, 0xf4, 0x43, 0x1c, 0x05, 0xb8, 0xdf, +0xd0, 0x8f, 0xe3, 0x17, 0x4b, 0x9f, 0xfb, 0xcb, +0x04, 0x5f, 0xe8, 0x09, 0xa5, 0x6b, 0xe7, 0x90, +0xd0, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operatorfamily_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operatorfamily_png = new wxImage(); + if (!img_operatorfamily_png || !img_operatorfamily_png->IsOk()) + { + wxMemoryInputStream img_operatorfamily_pngIS(operatorfamily_png_data, sizeof(operatorfamily_png_data)); + img_operatorfamily_png->LoadFile(img_operatorfamily_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operatorfamily_png; +} +#define operatorfamily_png_img operatorfamily_png_img() + +static wxBitmap *operatorfamily_png_bmp() +{ + static wxBitmap *bmp_operatorfamily_png; + if (!bmp_operatorfamily_png || !bmp_operatorfamily_png->IsOk()) + bmp_operatorfamily_png = new wxBitmap(*operatorfamily_png_img); + return bmp_operatorfamily_png; +} +#define operatorfamily_png_bmp operatorfamily_png_bmp() + +static wxIcon *operatorfamily_png_ico() +{ + static wxIcon *ico_operatorfamily_png; + if (!ico_operatorfamily_png || !ico_operatorfamily_png->IsOk()) + { + ico_operatorfamily_png = new wxIcon(); + ico_operatorfamily_png->CopyFromBitmap(*operatorfamily_png_bmp); + } + return ico_operatorfamily_png; +} +#define operatorfamily_png_ico operatorfamily_png_ico() + +#endif // OPERATORFAMILY_PNG_H diff --git a/include/images/operators.png b/include/images/operators.png new file mode 100644 index 0000000..1ce795f Binary files /dev/null and b/include/images/operators.png differ diff --git a/include/images/operators.pngc b/include/images/operators.pngc new file mode 100644 index 0000000..a557578 --- /dev/null +++ b/include/images/operators.pngc @@ -0,0 +1,85 @@ +#ifndef OPERATORS_PNG_H +#define OPERATORS_PNG_H + +static const unsigned char operators_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0xe7, +0xea, 0xf5, 0xe5, 0xe9, 0xf5, 0x9f, 0xa1, 0xa6, +0xaa, 0xaa, 0xaa, 0xe3, 0xe8, 0xf5, 0xe0, 0xe7, +0xf4, 0xdd, 0xe6, 0xf4, 0xdb, 0xe5, 0xf3, 0xd8, +0xe4, 0xf3, 0xd5, 0xe3, 0xf3, 0xd3, 0xe2, 0xf2, +0x73, 0xba, 0x6f, 0xb2, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x51, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0x40, 0x00, 0x46, 0x01, 0x28, 0x43, +0xc8, 0x10, 0xca, 0x10, 0x76, 0x14, 0x05, 0x51, +0xac, 0x82, 0x62, 0x42, 0x86, 0x01, 0x20, 0x15, +0xca, 0xe9, 0x10, 0x21, 0x46, 0x13, 0x98, 0x90, +0x20, 0x50, 0x28, 0x51, 0x00, 0x2a, 0x54, 0x28, +0x08, 0x15, 0xea, 0x5c, 0x0d, 0x12, 0x0a, 0x34, +0xab, 0x98, 0xb5, 0x47, 0x00, 0x6c, 0x80, 0xe4, +0x42, 0xb0, 0x14, 0x43, 0xa0, 0xd4, 0x46, 0xa8, +0xd9, 0xd2, 0x07, 0xa1, 0x8c, 0x40, 0x01, 0x24, +0x37, 0x00, 0x00, 0x38, 0x5e, 0x0d, 0x7b, 0xce, +0x63, 0xbc, 0x20, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *operators_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_operators_png = new wxImage(); + if (!img_operators_png || !img_operators_png->IsOk()) + { + wxMemoryInputStream img_operators_pngIS(operators_png_data, sizeof(operators_png_data)); + img_operators_png->LoadFile(img_operators_pngIS, wxBITMAP_TYPE_PNG); + } + return img_operators_png; +} +#define operators_png_img operators_png_img() + +static wxBitmap *operators_png_bmp() +{ + static wxBitmap *bmp_operators_png; + if (!bmp_operators_png || !bmp_operators_png->IsOk()) + bmp_operators_png = new wxBitmap(*operators_png_img); + return bmp_operators_png; +} +#define operators_png_bmp operators_png_bmp() + +static wxIcon *operators_png_ico() +{ + static wxIcon *ico_operators_png; + if (!ico_operators_png || !ico_operators_png->IsOk()) + { + ico_operators_png = new wxIcon(); + ico_operators_png->CopyFromBitmap(*operators_png_bmp); + } + return ico_operators_png; +} +#define operators_png_ico operators_png_ico() + +#endif // OPERATORS_PNG_H diff --git a/include/images/package.png b/include/images/package.png new file mode 100644 index 0000000..3231977 Binary files /dev/null and b/include/images/package.png differ diff --git a/include/images/package.pngc b/include/images/package.pngc new file mode 100644 index 0000000..9943fc6 --- /dev/null +++ b/include/images/package.pngc @@ -0,0 +1,129 @@ +#ifndef PACKAGE_PNG_H +#define PACKAGE_PNG_H + +static const unsigned char package_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x3e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd6, 0xb8, 0x79, 0xb9, +0x87, 0x1b, 0xfe, 0xfa, 0xbf, 0xfd, 0xf9, 0xb9, +0xfc, 0xf8, 0xb2, 0xfb, 0xf6, 0xab, 0xfa, 0xf5, +0xa3, 0xf9, 0xf3, 0x9a, 0xf8, 0xf1, 0x92, 0xca, +0xc7, 0x93, 0xca, 0xc6, 0x8e, 0xc9, 0xc5, 0x88, +0xc8, 0xc4, 0x82, 0xc7, 0xc2, 0x7a, 0xc6, 0xc1, +0x74, 0xc6, 0xbf, 0x6d, 0xfe, 0xfa, 0xbd, 0xca, +0xc7, 0x92, 0xfc, 0xf7, 0xb1, 0xfb, 0xf6, 0xa9, +0xfa, 0xf4, 0xa1, 0xf9, 0xf3, 0x99, 0xf8, 0xf1, +0x90, 0xf7, 0xef, 0x87, 0xf6, 0xee, 0x7d, 0xc4, +0xbd, 0x5d, 0xf4, 0xea, 0x6b, 0xfd, 0xf9, 0xb7, +0xca, 0xc6, 0x8d, 0xfb, 0xf6, 0xa8, 0xfa, 0xf4, +0xa0, 0xf9, 0xf3, 0x98, 0xf8, 0xf1, 0x8f, 0xf7, +0xef, 0x86, 0xf6, 0xed, 0x7c, 0xf5, 0xec, 0x73, +0xc3, 0xbb, 0x55, 0xf2, 0xe8, 0x61, 0xfc, 0xf7, +0xaf, 0xc9, 0xc5, 0x86, 0xfa, 0xf4, 0x9f, 0xf9, +0xf2, 0x97, 0xf8, 0xf1, 0x8e, 0xf7, 0xef, 0x85, +0xf5, 0xeb, 0x72, 0xf3, 0xea, 0x69, 0xc2, 0xba, +0x4d, 0xf1, 0xe6, 0x57, 0xfb, 0xf6, 0xa7, 0xc8, +0xc3, 0x7f, 0xf9, 0xf2, 0x96, 0xf8, 0xf1, 0x8d, +0xf7, 0xef, 0x84, 0xf6, 0xed, 0x7b, 0xf4, 0xeb, +0x71, 0xf3, 0xe9, 0x68, 0xf2, 0xe8, 0x5f, 0xc1, +0xb8, 0x45, 0xf0, 0xe4, 0x4d, 0xfa, 0xf4, 0x9e, +0xc7, 0xc2, 0x77, 0xf8, 0xf0, 0x8c, 0xf7, 0xef, +0x83, 0xf6, 0xed, 0x7a, 0xf4, 0xeb, 0x70, 0xf3, +0xe9, 0x67, 0xf2, 0xe7, 0x5e, 0xf1, 0xe6, 0x55, +0xc0, 0xb6, 0x3d, 0xef, 0xe2, 0x44, 0xf9, 0xf2, +0x94, 0xc6, 0xc0, 0x6f, 0xf7, 0xee, 0x82, 0xf5, +0xed, 0x79, 0xf4, 0xeb, 0x6f, 0xf3, 0xe9, 0x66, +0xf2, 0xe7, 0x5d, 0xf1, 0xe6, 0x54, 0xf0, 0xe4, +0x4c, 0xbf, 0xb5, 0x36, 0xee, 0xe1, 0x3c, 0xf8, +0xf0, 0x8a, 0xc5, 0xbe, 0x67, 0xf5, 0xec, 0x78, +0xf3, 0xe9, 0x65, 0xf2, 0xe7, 0x5c, 0xf1, 0xe5, +0x53, 0xf0, 0xe4, 0x4b, 0xef, 0xe2, 0x43, 0xbe, +0xb4, 0x2f, 0xed, 0xdf, 0x34, 0xc3, 0xbb, 0x58, +0xc2, 0xba, 0x50, 0xc2, 0xb9, 0x49, 0xc1, 0xb7, +0x42, 0xc0, 0xb6, 0x3b, 0xbf, 0xb5, 0x35, 0xbe, +0xb4, 0x2e, 0xf3, 0xe8, 0x63, 0xf2, 0xe7, 0x5a, +0xf1, 0xe5, 0x52, 0xf0, 0xe3, 0x49, 0xef, 0xe2, +0x41, 0xee, 0xe0, 0x3a, 0xed, 0xdf, 0x33, 0x25, +0x96, 0xcf, 0xd2, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x9a, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0xc0, 0x02, 0x18, 0x99, 0x20, 0x80, 0x11, +0x26, 0xc0, 0xc4, 0xcc, 0xc2, 0xca, 0xc6, 0xce, +0xc1, 0xc9, 0x04, 0x97, 0xe7, 0xe2, 0xe6, 0xe1, +0xe5, 0xe3, 0x17, 0x80, 0xaa, 0x61, 0x12, 0x14, +0x12, 0x16, 0x11, 0x15, 0x13, 0x97, 0x90, 0x94, +0x92, 0x06, 0xab, 0x61, 0x92, 0x91, 0x95, 0x93, +0x57, 0x50, 0x54, 0x52, 0x56, 0x51, 0x55, 0x83, +0x08, 0xa8, 0x6b, 0x68, 0x6a, 0x69, 0xeb, 0x28, +0xeb, 0xea, 0xe9, 0x1b, 0x40, 0x04, 0x0c, 0x8d, +0x8c, 0x4d, 0x4c, 0xcd, 0xcc, 0x2d, 0x2c, 0xad, +0xac, 0x21, 0x02, 0x36, 0xb6, 0x76, 0xf6, 0x0e, +0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0x10, 0x01, +0x77, 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, +0xff, 0x80, 0x40, 0x88, 0x40, 0x50, 0x70, 0x88, +0x77, 0x68, 0x58, 0x78, 0x44, 0x64, 0x54, 0x34, +0x13, 0xd4, 0x1d, 0x31, 0xb1, 0x71, 0xf1, 0x09, +0x89, 0x49, 0x70, 0xb7, 0x32, 0x25, 0xa7, 0xa4, +0xa6, 0xa5, 0x67, 0x64, 0x32, 0xe1, 0xf4, 0x0b, +0x7e, 0x00, 0x00, 0x6b, 0x09, 0x16, 0x81, 0x4b, +0x7c, 0xf9, 0xee, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *package_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_package_png = new wxImage(); + if (!img_package_png || !img_package_png->IsOk()) + { + wxMemoryInputStream img_package_pngIS(package_png_data, sizeof(package_png_data)); + img_package_png->LoadFile(img_package_pngIS, wxBITMAP_TYPE_PNG); + } + return img_package_png; +} +#define package_png_img package_png_img() + +static wxBitmap *package_png_bmp() +{ + static wxBitmap *bmp_package_png; + if (!bmp_package_png || !bmp_package_png->IsOk()) + bmp_package_png = new wxBitmap(*package_png_img); + return bmp_package_png; +} +#define package_png_bmp package_png_bmp() + +static wxIcon *package_png_ico() +{ + static wxIcon *ico_package_png; + if (!ico_package_png || !ico_package_png->IsOk()) + { + ico_package_png = new wxIcon(); + ico_package_png->CopyFromBitmap(*package_png_bmp); + } + return ico_package_png; +} +#define package_png_ico package_png_ico() + +#endif // PACKAGE_PNG_H diff --git a/include/images/packages.png b/include/images/packages.png new file mode 100644 index 0000000..f1f91db Binary files /dev/null and b/include/images/packages.png differ diff --git a/include/images/packages.pngc b/include/images/packages.pngc new file mode 100644 index 0000000..0f289a1 --- /dev/null +++ b/include/images/packages.pngc @@ -0,0 +1,114 @@ +#ifndef PACKAGES_PNG_H +#define PACKAGES_PNG_H + +static const unsigned char packages_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd5, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd6, 0xb8, 0x79, 0xb9, +0x87, 0x1b, 0xfe, 0xfa, 0xbc, 0xfd, 0xf8, 0xb4, +0xfc, 0xf6, 0xac, 0xfa, 0xf5, 0xa2, 0xf9, 0xf3, +0x98, 0xca, 0xc6, 0x8f, 0xc0, 0xa1, 0x48, 0xc5, +0x9b, 0x41, 0xfd, 0xf9, 0xba, 0xca, 0xc6, 0x8e, +0xfb, 0xf6, 0xa9, 0xfc, 0xf8, 0xb1, 0xc0, 0xa1, +0x47, 0xfb, 0xf6, 0xa7, 0xfa, 0xf3, 0x9b, 0xc9, +0xc5, 0x88, 0xc8, 0xc3, 0x81, 0xc7, 0xc2, 0x78, +0xc6, 0xc0, 0x6f, 0xf8, 0xf1, 0x8f, 0xfa, 0xf4, +0x9f, 0xf9, 0xf2, 0x95, 0xf7, 0xf0, 0x8a, 0xf6, +0xee, 0x7f, 0xc4, 0xbd, 0x5c, 0xf3, 0xe9, 0x68, +0xc9, 0xc5, 0x86, 0xfa, 0xf4, 0x9e, 0xf9, 0xf2, +0x94, 0xf7, 0xf0, 0x89, 0xf6, 0xee, 0x7d, 0xf5, +0xeb, 0x72, 0xc2, 0xba, 0x52, 0xf2, 0xe7, 0x5c, +0xc8, 0xc3, 0x7e, 0xf8, 0xf2, 0x92, 0xf7, 0xef, +0x87, 0xf6, 0xed, 0x7c, 0xf4, 0xeb, 0x71, 0xf3, +0xe9, 0x65, 0xc2, 0xb9, 0x48, 0xf0, 0xe5, 0x50, +0xc6, 0xc1, 0x74, 0xf7, 0xef, 0x86, 0xf6, 0xed, +0x7a, 0xf4, 0xeb, 0x6f, 0xf3, 0xe9, 0x64, 0xf2, +0xe6, 0x59, 0xc0, 0xb6, 0x3e, 0xef, 0xe2, 0x44, +0xc6, 0xbf, 0x6a, 0xf5, 0xed, 0x79, 0xf4, 0xea, +0x6e, 0xf3, 0xe8, 0x62, 0xf1, 0xe6, 0x57, 0xf0, +0xe4, 0x4d, 0xbf, 0xb5, 0x36, 0xee, 0xe0, 0x3a, +0xc3, 0xbb, 0x56, 0xc2, 0xba, 0x4e, 0xc1, 0xb8, +0x45, 0xc0, 0xb6, 0x3d, 0xbf, 0xb5, 0x35, 0xf2, +0xe8, 0x60, 0xf1, 0xe6, 0x55, 0xf0, 0xe4, 0x4a, +0xef, 0xe2, 0x41, 0xee, 0xe0, 0x38, 0x98, 0x3e, +0xfb, 0xb4, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x8f, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x60, 0x64, 0x02, 0x01, 0x46, 0x06, 0x38, +0x60, 0x62, 0x66, 0x61, 0x65, 0x63, 0x67, 0x82, +0x71, 0x81, 0xf2, 0x1c, 0x9c, 0x60, 0x35, 0x5c, +0x50, 0x79, 0x6e, 0x1e, 0x5e, 0x14, 0x35, 0x4c, +0x7c, 0xfc, 0xa8, 0x6a, 0x98, 0x04, 0xd0, 0xd4, +0x30, 0x09, 0x42, 0xd4, 0x08, 0x09, 0x8b, 0x88, +0x82, 0xed, 0x62, 0x12, 0x83, 0xa8, 0x11, 0x97, +0x90, 0x94, 0x92, 0x96, 0x61, 0x02, 0xdb, 0x02, +0x54, 0x23, 0x2b, 0x27, 0xaf, 0xa0, 0xa8, 0xa4, +0xac, 0x02, 0xd1, 0x04, 0x54, 0xa3, 0xaa, 0xa6, +0xae, 0xa1, 0xa9, 0xa5, 0xad, 0x03, 0x16, 0xe0, +0x02, 0xaa, 0xd1, 0xd5, 0xd3, 0x37, 0x30, 0x34, +0x32, 0x36, 0x81, 0x59, 0x2d, 0x66, 0x6a, 0x66, +0x6e, 0x61, 0x69, 0x65, 0x6d, 0x03, 0x15, 0x00, +0xaa, 0xb1, 0xb5, 0xb3, 0x77, 0x70, 0x44, 0xf2, +0x11, 0x93, 0x93, 0xb3, 0x8b, 0xab, 0x1b, 0x13, +0xc2, 0x83, 0x18, 0x3e, 0x46, 0x00, 0x00, 0xb2, +0x83, 0x0b, 0x81, 0x87, 0xe4, 0xc4, 0xc2, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *packages_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_packages_png = new wxImage(); + if (!img_packages_png || !img_packages_png->IsOk()) + { + wxMemoryInputStream img_packages_pngIS(packages_png_data, sizeof(packages_png_data)); + img_packages_png->LoadFile(img_packages_pngIS, wxBITMAP_TYPE_PNG); + } + return img_packages_png; +} +#define packages_png_img packages_png_img() + +static wxBitmap *packages_png_bmp() +{ + static wxBitmap *bmp_packages_png; + if (!bmp_packages_png || !bmp_packages_png->IsOk()) + bmp_packages_png = new wxBitmap(*packages_png_img); + return bmp_packages_png; +} +#define packages_png_bmp packages_png_bmp() + +static wxIcon *packages_png_ico() +{ + static wxIcon *ico_packages_png; + if (!ico_packages_png || !ico_packages_png->IsOk()) + { + ico_packages_png = new wxIcon(); + ico_packages_png->CopyFromBitmap(*packages_png_bmp); + } + return ico_packages_png; +} +#define packages_png_ico packages_png_ico() + +#endif // PACKAGES_PNG_H diff --git a/include/images/parser.png b/include/images/parser.png new file mode 100644 index 0000000..47eca99 Binary files /dev/null and b/include/images/parser.png differ diff --git a/include/images/parser.pngc b/include/images/parser.pngc new file mode 100644 index 0000000..b27efb1 --- /dev/null +++ b/include/images/parser.pngc @@ -0,0 +1,134 @@ +#ifndef PARSER_PNG_H +#define PARSER_PNG_H + +static const unsigned char parser_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x5c, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xbd, 0x86, 0x79, +0xa2, 0x30, 0x60, 0x94, 0x04, 0x9b, 0xb5, 0x6e, +0x82, 0xae, 0x38, 0xc9, 0xe8, 0xa2, 0xe0, 0xff, +0xc1, 0xdd, 0xfe, 0xbc, 0xdc, 0xfe, 0xb7, 0xda, +0xfe, 0xb2, 0xd7, 0xfc, 0xac, 0xd5, 0xfb, 0xa6, +0xd3, 0xfb, 0x9e, 0xd1, 0xfa, 0x9b, 0xbe, 0xe4, +0x84, 0x7f, 0xad, 0x2e, 0x6b, 0x9a, 0x18, 0xd8, +0xf5, 0xb7, 0xd8, 0xff, 0xb0, 0xd3, 0xfe, 0xa5, +0xcf, 0xfd, 0x9d, 0xcd, 0xfc, 0x96, 0xca, 0xfb, +0x8e, 0xcc, 0xfb, 0x92, 0xd7, 0xfb, 0xa7, 0xd4, +0xfa, 0xa0, 0xd2, 0xf9, 0x9b, 0xd3, 0xf8, 0x9c, +0xcc, 0xf1, 0x93, 0xdf, 0xff, 0xbe, 0xbb, 0x24, +0xd7, 0xc9, 0xfb, 0x8b, 0x92, 0xb2, 0x69, 0xab, +0xc3, 0x8a, 0xd0, 0x98, 0xc4, 0xc4, 0x2a, 0xe4, +0xc4, 0x2a, 0xe3, 0xb4, 0x75, 0xad, 0xd7, 0xf8, +0xa4, 0x7b, 0xa6, 0x2e, 0xdc, 0xfe, 0xb8, 0xce, +0xfd, 0x99, 0xcb, 0xfc, 0x91, 0xc8, 0xfa, 0x89, +0xc4, 0xf9, 0x80, 0xd5, 0xfa, 0xa3, 0xd0, 0x8b, +0xc8, 0xd9, 0x63, 0xe4, 0xde, 0xc5, 0xb8, 0xdc, +0xc4, 0xb4, 0xd8, 0x62, 0xde, 0xd0, 0x8a, 0xc8, +0xda, 0xfd, 0xb1, 0x87, 0xa8, 0x60, 0x85, 0xa8, +0x5a, 0xc3, 0xf9, 0x7d, 0x81, 0xa6, 0x4d, 0xa8, +0xc3, 0x83, 0xc6, 0x1c, 0xec, 0xe4, 0xd7, 0xb8, +0x9a, 0xba, 0x5a, 0x99, 0xba, 0x55, 0xe1, 0xd6, +0xac, 0xcd, 0x24, 0xf0, 0xd7, 0xfc, 0xaa, 0xc6, +0xfa, 0x84, 0xc2, 0xf8, 0x7a, 0xbe, 0xf7, 0x70, +0xbb, 0xf6, 0x66, 0xcf, 0xf8, 0x92, 0xcc, 0x8a, +0xbe, 0xd8, 0x62, 0xdf, 0xdb, 0xc3, 0xad, 0xda, +0xc3, 0xaa, 0xd7, 0x62, 0xda, 0xce, 0x89, 0xc1, +0xd4, 0xfb, 0xa2, 0x81, 0xa6, 0x50, 0x7f, 0xa6, +0x49, 0x7d, 0xa4, 0x42, 0xb6, 0xf4, 0x59, 0x86, +0xac, 0x4b, 0xa2, 0xc1, 0x73, 0xb2, 0x75, 0xa7, +0xca, 0x35, 0xe1, 0xc2, 0x29, 0xde, 0xaf, 0x73, +0xa0, 0xcf, 0xf5, 0x8e, 0x71, 0xa0, 0x20, 0x6c, +0x9b, 0x1a, 0xca, 0xf0, 0x97, 0xc1, 0xf7, 0x75, +0xb9, 0xf5, 0x61, 0xb5, 0xf3, 0x56, 0xb1, 0xf2, +0x4c, 0xad, 0xf1, 0x42, 0xb2, 0xf1, 0x4e, 0xc3, +0xf4, 0x74, 0xc1, 0xf3, 0x6e, 0xc0, 0xf2, 0x6a, +0xc3, 0xf2, 0x6f, 0xbf, 0xeb, 0x71, 0x9d, 0xb6, +0x70, 0x83, 0xb1, 0x36, 0xc7, 0xef, 0x8b, 0xc8, +0xf6, 0x80, 0xc4, 0xf5, 0x77, 0xc1, 0xf4, 0x6f, +0xbf, 0xf3, 0x68, 0xbc, 0xf2, 0x62, 0xb9, 0xf2, +0x5b, 0xb7, 0xf1, 0x56, 0xb7, 0xf0, 0x54, 0xb7, +0xe9, 0x5f, 0x7f, 0xaf, 0x29, 0xf8, 0x7b, 0x6f, +0x74, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa6, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, +0x02, 0x30, 0x32, 0x31, 0x43, 0x01, 0x13, 0x23, +0x88, 0xcf, 0xc2, 0xca, 0xc6, 0xce, 0xc1, 0xc9, +0xc5, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, 0xc0, 0x02, +0x14, 0x10, 0x14, 0x12, 0x16, 0x11, 0x15, 0x13, +0x97, 0x90, 0x94, 0x92, 0x96, 0x91, 0x15, 0x04, +0x0a, 0x30, 0xcb, 0xc9, 0xcb, 0xcb, 0x2b, 0x28, +0x2a, 0x29, 0xab, 0xa8, 0xaa, 0xa9, 0x6b, 0x80, +0x04, 0x34, 0xb5, 0xb4, 0x75, 0x74, 0xf5, 0xf4, +0x0d, 0x0c, 0x8d, 0x8c, 0x4d, 0xc0, 0x02, 0xa6, +0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, +0x76, 0xf6, 0x0e, 0x60, 0x01, 0x47, 0x27, 0x67, +0x17, 0x57, 0x37, 0x77, 0x0f, 0x4f, 0x2f, 0x6f, +0x1f, 0xb0, 0x80, 0xaf, 0x9f, 0x7f, 0x40, 0x60, +0x50, 0x70, 0x48, 0x68, 0x58, 0x78, 0x44, 0x24, +0x50, 0x20, 0x2a, 0x3a, 0x26, 0x36, 0x2e, 0x3e, +0x21, 0x31, 0x29, 0x39, 0x25, 0x35, 0x2d, 0x0a, +0x28, 0x90, 0x9e, 0x91, 0x99, 0x95, 0x9d, 0x93, +0x9b, 0x97, 0x5f, 0x50, 0x58, 0x54, 0x9c, 0x0e, +0x76, 0x99, 0x20, 0xcc, 0xa5, 0x82, 0x2c, 0xc4, +0xf8, 0x0c, 0x03, 0x00, 0x00, 0x17, 0xde, 0x1c, +0x04, 0x4e, 0x08, 0x84, 0xe7, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *parser_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_parser_png = new wxImage(); + if (!img_parser_png || !img_parser_png->IsOk()) + { + wxMemoryInputStream img_parser_pngIS(parser_png_data, sizeof(parser_png_data)); + img_parser_png->LoadFile(img_parser_pngIS, wxBITMAP_TYPE_PNG); + } + return img_parser_png; +} +#define parser_png_img parser_png_img() + +static wxBitmap *parser_png_bmp() +{ + static wxBitmap *bmp_parser_png; + if (!bmp_parser_png || !bmp_parser_png->IsOk()) + bmp_parser_png = new wxBitmap(*parser_png_img); + return bmp_parser_png; +} +#define parser_png_bmp parser_png_bmp() + +static wxIcon *parser_png_ico() +{ + static wxIcon *ico_parser_png; + if (!ico_parser_png || !ico_parser_png->IsOk()) + { + ico_parser_png = new wxIcon(); + ico_parser_png->CopyFromBitmap(*parser_png_bmp); + } + return ico_parser_png; +} +#define parser_png_ico parser_png_ico() + +#endif // PARSER_PNG_H diff --git a/include/images/parsers.png b/include/images/parsers.png new file mode 100644 index 0000000..340ec6b Binary files /dev/null and b/include/images/parsers.png differ diff --git a/include/images/parsers.pngc b/include/images/parsers.pngc new file mode 100644 index 0000000..d5a5553 --- /dev/null +++ b/include/images/parsers.pngc @@ -0,0 +1,122 @@ +#ifndef PARSERS_PNG_H +#define PARSERS_PNG_H + +static const unsigned char parsers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x05, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xbd, 0x86, 0x79, +0xa2, 0x30, 0x60, 0x94, 0x04, 0x9b, 0xb5, 0x6e, +0x82, 0xae, 0x38, 0xc9, 0xe8, 0xa2, 0xe0, 0xff, +0xc1, 0xdf, 0xff, 0xbf, 0xdd, 0xfe, 0xbb, 0xdb, +0xfe, 0xb6, 0xd9, 0xfd, 0xb0, 0xd7, 0xfc, 0xa8, +0xd5, 0xfb, 0xa4, 0xc0, 0xe5, 0x89, 0x7f, 0xad, +0x30, 0x6b, 0x9a, 0x18, 0xd8, 0xf5, 0xb7, 0xab, +0xd7, 0x70, 0x79, 0xaa, 0x27, 0x76, 0xa7, 0x20, +0x67, 0x98, 0x10, 0xa0, 0xca, 0x62, 0x6c, 0x9e, +0x15, 0x6c, 0x9b, 0x1a, 0xd8, 0xff, 0xb1, 0xd4, +0xfe, 0xa7, 0xd0, 0xfe, 0x9f, 0xcd, 0xfc, 0x97, +0xca, 0xfb, 0x8e, 0xc6, 0xfa, 0x84, 0xc2, 0xf8, +0x79, 0xbe, 0xf7, 0x6f, 0xbf, 0xf6, 0x70, 0xc6, +0xef, 0x88, 0x9d, 0xb6, 0x70, 0xdf, 0xff, 0xbe, +0xd1, 0xfe, 0xa2, 0xbb, 0x24, 0xd7, 0xc3, 0xf9, +0x7c, 0x9d, 0x65, 0x92, 0xba, 0x23, 0xd5, 0xbc, +0x93, 0x93, 0xc3, 0xf5, 0x74, 0x66, 0x98, 0x0f, +0xdb, 0xfe, 0xb4, 0xcb, 0xfc, 0x93, 0xc8, 0xfa, +0x89, 0xc4, 0xf9, 0x7e, 0xc0, 0xf7, 0x73, 0xc3, +0x89, 0xab, 0xd9, 0x63, 0xe3, 0xdd, 0xc4, 0xb5, +0xdc, 0xc4, 0xb0, 0xd8, 0x62, 0xdd, 0xc3, 0x87, +0xa8, 0xd7, 0xfc, 0xa9, 0xc5, 0xf9, 0x82, 0x81, +0xa6, 0x4f, 0x7e, 0xa5, 0x48, 0xb8, 0xf5, 0x5f, +0xc0, 0x18, 0xe2, 0xd4, 0xc2, 0xaa, 0x98, 0xba, +0x52, 0x96, 0xb9, 0x4d, 0xe0, 0xd5, 0xa7, 0xc9, +0x23, 0xe7, 0xcc, 0xf0, 0x99, 0xc2, 0xf8, 0x77, +0xba, 0xf5, 0x63, 0xb5, 0xf3, 0x56, 0xb0, 0xf2, +0x4a, 0xba, 0x86, 0x94, 0xd7, 0x62, 0xdc, 0xd9, +0xc3, 0xa6, 0xd9, 0xc3, 0xa2, 0xd7, 0x62, 0xda, +0xc0, 0x81, 0xa6, 0x83, 0xb1, 0x35, 0xc5, 0xf5, +0x7c, 0xc2, 0xf5, 0x71, 0xbf, 0xf3, 0x69, 0xbc, +0xf2, 0x62, 0xc0, 0x93, 0x9b, 0xc7, 0x34, 0xda, +0xbf, 0x8e, 0x9e, 0x7f, 0xaf, 0x29, 0x7b, 0x20, +0x17, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x9e, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x00, 0x8c, 0x4c, 0xcc, 0x10, 0xc0, 0xc4, +0x08, 0xe6, 0xb3, 0xb0, 0xb2, 0xb1, 0x73, 0x70, +0x72, 0x71, 0xf3, 0xf0, 0xf2, 0xf1, 0xb3, 0x80, +0x04, 0x04, 0x04, 0x85, 0x84, 0xa1, 0x4a, 0x44, +0x44, 0x41, 0x02, 0xcc, 0x62, 0x68, 0x4a, 0x98, +0xc5, 0xd1, 0x94, 0x30, 0xa3, 0x2b, 0x91, 0x00, +0x2a, 0x91, 0x94, 0x92, 0x96, 0x91, 0x95, 0x93, +0x57, 0x50, 0x54, 0x12, 0x60, 0x60, 0x50, 0x66, +0x66, 0x56, 0x51, 0x55, 0x53, 0x53, 0x53, 0xd7, +0x50, 0xd3, 0xd4, 0xd2, 0x66, 0x06, 0xea, 0xd1, +0x61, 0xd6, 0xd5, 0xd3, 0x37, 0x30, 0x34, 0x32, +0x36, 0x31, 0x35, 0x33, 0x07, 0x09, 0x28, 0x33, +0x5b, 0x58, 0x5a, 0x59, 0xdb, 0xd8, 0xda, 0xd9, +0x3b, 0x38, 0x3a, 0x81, 0x04, 0x18, 0x74, 0x9c, +0x5d, 0x5c, 0xdd, 0xdc, 0x3d, 0x3c, 0xbd, 0xbc, +0x7d, 0x7c, 0x25, 0x40, 0x02, 0xca, 0x7e, 0x4a, +0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0x21, 0xa1, +0x61, 0xca, 0x10, 0xd7, 0x0b, 0x40, 0xdd, 0x21, +0xc0, 0xc2, 0x40, 0x04, 0x00, 0x00, 0xc0, 0xa1, +0x12, 0x68, 0x9c, 0xcd, 0x37, 0xe1, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *parsers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_parsers_png = new wxImage(); + if (!img_parsers_png || !img_parsers_png->IsOk()) + { + wxMemoryInputStream img_parsers_pngIS(parsers_png_data, sizeof(parsers_png_data)); + img_parsers_png->LoadFile(img_parsers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_parsers_png; +} +#define parsers_png_img parsers_png_img() + +static wxBitmap *parsers_png_bmp() +{ + static wxBitmap *bmp_parsers_png; + if (!bmp_parsers_png || !bmp_parsers_png->IsOk()) + bmp_parsers_png = new wxBitmap(*parsers_png_img); + return bmp_parsers_png; +} +#define parsers_png_bmp parsers_png_bmp() + +static wxIcon *parsers_png_ico() +{ + static wxIcon *ico_parsers_png; + if (!ico_parsers_png || !ico_parsers_png->IsOk()) + { + ico_parsers_png = new wxIcon(); + ico_parsers_png->CopyFromBitmap(*parsers_png_bmp); + } + return ico_parsers_png; +} +#define parsers_png_ico parsers_png_ico() + +#endif // PARSERS_PNG_H diff --git a/include/images/pgAdmin3-128.png b/include/images/pgAdmin3-128.png new file mode 100644 index 0000000..48bf5cb Binary files /dev/null and b/include/images/pgAdmin3-128.png differ diff --git a/include/images/pgAdmin3-16.png b/include/images/pgAdmin3-16.png new file mode 100644 index 0000000..8d7db54 Binary files /dev/null and b/include/images/pgAdmin3-16.png differ diff --git a/include/images/pgAdmin3-16.pngc b/include/images/pgAdmin3-16.pngc new file mode 100644 index 0000000..c8bdfb6 --- /dev/null +++ b/include/images/pgAdmin3-16.pngc @@ -0,0 +1,151 @@ +#ifndef PGADMIN3_16_PNG_H +#define PGADMIN3_16_PNG_H + +static const unsigned char pgAdmin3_16_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, +0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, +0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, +0x6b, 0x01, 0x0e, 0x5f, 0x5b, 0x51, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, +0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, +0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, +0xee, 0x3c, 0x1a, 0x00, 0x00, 0x02, 0xcf, 0x49, +0x44, 0x41, 0x54, 0x38, 0x8d, 0x85, 0x92, 0x5d, +0x48, 0x53, 0x61, 0x1c, 0xc6, 0x9f, 0xf3, 0xe1, +0xbe, 0x8e, 0xf3, 0xec, 0x6c, 0x73, 0xdb, 0xd1, +0x4d, 0xb7, 0x79, 0x16, 0x07, 0xc5, 0xb4, 0xf9, +0x15, 0x06, 0x26, 0x8a, 0x44, 0x20, 0x88, 0x75, +0xd1, 0x97, 0x04, 0x5e, 0x79, 0x57, 0x74, 0x51, +0x50, 0xde, 0x7a, 0x11, 0x18, 0x41, 0x74, 0x11, +0x11, 0x21, 0x74, 0xd1, 0x4d, 0xd2, 0xc7, 0x45, +0x18, 0x5d, 0x24, 0xa9, 0x41, 0x98, 0x19, 0x81, +0x26, 0x4e, 0xcd, 0xa9, 0x33, 0x4d, 0xa7, 0xfb, +0xd0, 0xb9, 0xb9, 0x8f, 0x73, 0xba, 0xb0, 0x1d, +0xd4, 0x8a, 0x9e, 0xbb, 0x97, 0xe7, 0xf7, 0x3e, +0xfc, 0x9f, 0xff, 0xfb, 0x12, 0xb2, 0x2c, 0x03, +0x80, 0x79, 0x6e, 0x79, 0xe3, 0xaa, 0xff, 0x67, +0xa8, 0x4a, 0xa3, 0xa2, 0xb7, 0x4c, 0x2c, 0xb3, +0x66, 0xca, 0xd3, 0x8e, 0x2c, 0xaf, 0x47, 0x5a, +0x83, 0x91, 0x1d, 0xa7, 0x5e, 0xab, 0x06, 0x41, +0x10, 0x86, 0xd9, 0x95, 0x20, 0xad, 0xc9, 0x51, +0x45, 0x9c, 0xbc, 0xc1, 0xef, 0x15, 0x0a, 0xbb, +0x00, 0x44, 0x08, 0x59, 0x96, 0x6d, 0x03, 0xa3, +0xd3, 0xef, 0xef, 0x3e, 0x1b, 0x3a, 0x12, 0xda, +0x8a, 0x03, 0x00, 0x1a, 0x2b, 0x4b, 0x60, 0x66, +0x75, 0x78, 0x31, 0x3c, 0x89, 0x8c, 0x24, 0x81, +0x22, 0x49, 0xd4, 0x88, 0x76, 0x94, 0xbb, 0x6c, +0x78, 0x3c, 0xf0, 0x09, 0x8c, 0x46, 0x85, 0x9b, +0x17, 0x1a, 0x27, 0x4a, 0x05, 0xcb, 0x45, 0xaa, +0xfd, 0x72, 0x57, 0xef, 0x8d, 0x87, 0xaf, 0x4f, +0xc5, 0xe2, 0x49, 0x00, 0x40, 0x0e, 0x4d, 0xa1, +0xf5, 0xb8, 0x88, 0xbe, 0x37, 0x63, 0xf8, 0x3d, +0x1d, 0x64, 0x59, 0x46, 0x60, 0x3d, 0x82, 0xd5, +0xcd, 0x2d, 0x9c, 0x69, 0x28, 0xc7, 0xe8, 0xd4, +0x12, 0x06, 0xbf, 0x7e, 0xb7, 0x34, 0x57, 0x78, +0xb4, 0x64, 0x64, 0x2b, 0x6e, 0x49, 0xa6, 0x32, +0xc8, 0xca, 0x65, 0xe3, 0x30, 0xe6, 0x0b, 0xe0, +0x6f, 0xfa, 0xb1, 0x11, 0x05, 0x01, 0x20, 0x4f, +0xa7, 0x86, 0x24, 0xc9, 0x48, 0x24, 0x53, 0x1a, +0x5a, 0x92, 0x20, 0xef, 0x87, 0x2a, 0x85, 0x02, +0x14, 0x5b, 0x8d, 0xa8, 0x2f, 0x2b, 0xc6, 0xec, +0xf2, 0x06, 0x5e, 0x8e, 0x4c, 0x2a, 0x5e, 0x77, +0x47, 0x33, 0x68, 0x92, 0x40, 0xb5, 0xe8, 0xc0, +0xe7, 0xe9, 0x00, 0x72, 0x19, 0xd5, 0x3c, 0x6d, +0x33, 0xeb, 0xc7, 0x0d, 0xb9, 0xda, 0xb3, 0xe1, +0xed, 0xbd, 0xfe, 0x34, 0x45, 0xe1, 0xde, 0xf3, +0x61, 0x38, 0xad, 0x1c, 0x9a, 0xbd, 0x1e, 0xe5, +0x72, 0xae, 0x56, 0x05, 0x5f, 0x60, 0x1d, 0x0b, +0xab, 0x21, 0x24, 0x92, 0x69, 0x9c, 0xae, 0x13, +0x83, 0x0e, 0x8e, 0x7b, 0x44, 0x8a, 0x8e, 0xfc, +0xfe, 0x6a, 0xd1, 0x1e, 0xce, 0x82, 0x34, 0x45, +0x20, 0x9d, 0x96, 0xe0, 0x0b, 0x04, 0xb1, 0x9b, +0x4a, 0x2b, 0x01, 0xb1, 0x44, 0x12, 0xf9, 0x2c, +0x83, 0x44, 0x2a, 0x0d, 0x9a, 0x22, 0x51, 0x27, +0x3a, 0xc6, 0x58, 0x56, 0x33, 0x4f, 0x02, 0xf0, +0x55, 0xb8, 0x0b, 0x96, 0xb2, 0x60, 0x78, 0x3b, +0x01, 0x53, 0x9e, 0xee, 0x8f, 0xfe, 0xb2, 0x0c, +0xf8, 0x57, 0x43, 0x30, 0xb3, 0x0c, 0x6a, 0x44, +0x47, 0xbc, 0xd8, 0x6c, 0xe8, 0x01, 0x00, 0x12, +0x00, 0x78, 0x4e, 0xef, 0xcf, 0x82, 0x1f, 0xbf, +0x2d, 0xa2, 0xa5, 0xda, 0x03, 0x9a, 0x22, 0x21, +0xc9, 0x07, 0xd6, 0x83, 0xb7, 0x63, 0x3e, 0xb4, +0xd5, 0x97, 0x42, 0x28, 0x34, 0x7d, 0x29, 0x2a, +0xe0, 0x3e, 0x28, 0x01, 0x6e, 0xde, 0xf0, 0xa4, +0x56, 0xb4, 0xc7, 0x00, 0x20, 0xb4, 0x1d, 0xc7, +0xd1, 0x12, 0x7e, 0xea, 0xfe, 0x95, 0xb6, 0x89, +0x1c, 0x8a, 0x3a, 0x10, 0x90, 0xce, 0x48, 0x98, +0x09, 0x04, 0xe1, 0xb4, 0x72, 0xd1, 0xb9, 0xe5, +0x8d, 0x9e, 0x95, 0x60, 0xa4, 0x8a, 0x04, 0x80, +0x22, 0x9b, 0xb1, 0xbf, 0xa3, 0xc5, 0x3b, 0xae, +0xce, 0xa1, 0xd1, 0xdd, 0xd1, 0x34, 0x23, 0x16, +0x59, 0xfa, 0x36, 0xa3, 0xf1, 0x1d, 0x17, 0x6f, +0xcc, 0x08, 0x85, 0xa6, 0x03, 0x21, 0x2e, 0xde, +0x88, 0xfe, 0xa1, 0x89, 0xda, 0x85, 0xb5, 0xd0, +0xf9, 0xe0, 0x76, 0xc2, 0x4e, 0x66, 0x0d, 0xc1, +0xce, 0x77, 0x3e, 0xb8, 0xd6, 0xfe, 0xb4, 0xd1, +0x5b, 0xd2, 0x1e, 0x0c, 0xef, 0xb4, 0x66, 0x24, +0x49, 0x16, 0x1d, 0xe6, 0x5e, 0x33, 0xcb, 0x28, +0x3d, 0x38, 0xbd, 0x16, 0x46, 0x96, 0xb9, 0x7d, +0xfd, 0x5c, 0x43, 0x55, 0xd3, 0x31, 0xc1, 0x53, +0xee, 0xb4, 0xbe, 0xa2, 0xb3, 0xa6, 0x85, 0x55, +0xcf, 0x59, 0x58, 0xfe, 0xd2, 0xde, 0x5f, 0xe0, +0x4f, 0x56, 0x0a, 0x3c, 0x00, 0x88, 0x46, 0xbd, +0xae, 0x13, 0x80, 0x15, 0x00, 0xec, 0xf9, 0x86, +0x5d, 0x77, 0xbe, 0x61, 0x10, 0x80, 0xb2, 0x33, +0x65, 0x82, 0x7f, 0x28, 0xc6, 0xe9, 0xb5, 0x51, +0x65, 0xca, 0x42, 0xd3, 0x2a, 0xc3, 0xa8, 0x7d, +0xfb, 0x81, 0xff, 0x05, 0x84, 0x6d, 0x9c, 0x3e, +0x96, 0x3d, 0x9c, 0x28, 0x2b, 0xf6, 0x03, 0x58, +0xdc, 0x0f, 0x10, 0xf2, 0xa1, 0xa7, 0x3a, 0xac, +0x89, 0x85, 0x95, 0x5b, 0xb3, 0x81, 0x50, 0xab, +0x51, 0xaf, 0x0b, 0x57, 0xb8, 0x6d, 0x77, 0xd8, +0x5c, 0xcd, 0xbb, 0xfd, 0xfe, 0x2f, 0xef, 0x15, +0xfe, 0xe5, 0x06, 0xdb, 0x32, 0xf1, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *pgAdmin3_16_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_pgAdmin3_16_png = new wxImage(); + if (!img_pgAdmin3_16_png || !img_pgAdmin3_16_png->IsOk()) + { + wxMemoryInputStream img_pgAdmin3_16_pngIS(pgAdmin3_16_png_data, sizeof(pgAdmin3_16_png_data)); + img_pgAdmin3_16_png->LoadFile(img_pgAdmin3_16_pngIS, wxBITMAP_TYPE_PNG); + } + return img_pgAdmin3_16_png; +} +#define pgAdmin3_16_png_img pgAdmin3_16_png_img() + +static wxBitmap *pgAdmin3_16_png_bmp() +{ + static wxBitmap *bmp_pgAdmin3_16_png; + if (!bmp_pgAdmin3_16_png || !bmp_pgAdmin3_16_png->IsOk()) + bmp_pgAdmin3_16_png = new wxBitmap(*pgAdmin3_16_png_img); + return bmp_pgAdmin3_16_png; +} +#define pgAdmin3_16_png_bmp pgAdmin3_16_png_bmp() + +static wxIcon *pgAdmin3_16_png_ico() +{ + static wxIcon *ico_pgAdmin3_16_png; + if (!ico_pgAdmin3_16_png || !ico_pgAdmin3_16_png->IsOk()) + { + ico_pgAdmin3_16_png = new wxIcon(); + ico_pgAdmin3_16_png->CopyFromBitmap(*pgAdmin3_16_png_bmp); + } + return ico_pgAdmin3_16_png; +} +#define pgAdmin3_16_png_ico pgAdmin3_16_png_ico() + +#endif // PGADMIN3_16_PNG_H diff --git a/include/images/pgAdmin3-22.png b/include/images/pgAdmin3-22.png new file mode 100644 index 0000000..626d3db Binary files /dev/null and b/include/images/pgAdmin3-22.png differ diff --git a/include/images/pgAdmin3-24.png b/include/images/pgAdmin3-24.png new file mode 100644 index 0000000..d4343fb Binary files /dev/null and b/include/images/pgAdmin3-24.png differ diff --git a/include/images/pgAdmin3-256.png b/include/images/pgAdmin3-256.png new file mode 100644 index 0000000..cb5c55a Binary files /dev/null and b/include/images/pgAdmin3-256.png differ diff --git a/include/images/pgAdmin3-32.png b/include/images/pgAdmin3-32.png new file mode 100644 index 0000000..ba75990 Binary files /dev/null and b/include/images/pgAdmin3-32.png differ diff --git a/include/images/pgAdmin3-32.pngc b/include/images/pgAdmin3-32.pngc new file mode 100644 index 0000000..5ac09cc --- /dev/null +++ b/include/images/pgAdmin3-32.pngc @@ -0,0 +1,283 @@ +#ifndef PGADMIN3_32_PNG_H +#define PGADMIN3_32_PNG_H + +static const unsigned char pgAdmin3_32_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x06, 0x00, 0x00, 0x00, 0x73, 0x7a, 0x7a, +0xf4, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, +0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, +0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, +0xd7, 0x01, 0x2b, 0x27, 0x69, 0xeb, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, +0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, +0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, +0xee, 0x3c, 0x1a, 0x00, 0x00, 0x06, 0xef, 0x49, +0x44, 0x41, 0x54, 0x58, 0x85, 0xb5, 0x97, 0x7b, +0x70, 0x54, 0x67, 0x19, 0xc6, 0x7f, 0xe7, 0x3b, +0x67, 0xcf, 0xee, 0xd9, 0x7b, 0x92, 0xcd, 0x9d, +0x84, 0x04, 0xd2, 0x84, 0x40, 0x0a, 0x61, 0xb8, +0xa7, 0x90, 0x22, 0x8c, 0x92, 0x92, 0xd2, 0x42, +0x1d, 0x3b, 0xb4, 0xea, 0x94, 0x42, 0x1d, 0x2c, +0xe3, 0x68, 0x67, 0x1c, 0x65, 0x2c, 0x76, 0x3a, +0x55, 0x47, 0xec, 0x15, 0x75, 0xaa, 0x85, 0x4e, +0xc7, 0x4b, 0x47, 0xa1, 0x96, 0x48, 0xc1, 0xc6, +0x52, 0x95, 0x82, 0x08, 0x2d, 0x83, 0xdc, 0x0d, +0x17, 0x09, 0x92, 0x12, 0x4a, 0x02, 0x49, 0x48, +0x97, 0x64, 0x93, 0xcd, 0xee, 0x9e, 0x9b, 0x7f, +0x58, 0xb6, 0x9b, 0x64, 0x37, 0x6d, 0xa7, 0xf6, +0x99, 0x39, 0x7f, 0x9c, 0xf3, 0xbc, 0xe7, 0x79, +0x9f, 0xf9, 0xce, 0xfb, 0xbd, 0xef, 0x77, 0x24, +0xdb, 0xb6, 0x19, 0x81, 0x42, 0x60, 0x0e, 0x30, +0x15, 0x18, 0x00, 0xde, 0x4b, 0xb9, 0x3a, 0x01, +0x1b, 0x50, 0x81, 0x06, 0xa0, 0x2a, 0x1a, 0xd3, +0xab, 0x65, 0x59, 0x0a, 0x3b, 0x1d, 0xca, 0x79, +0x20, 0xaf, 0x7f, 0x30, 0x56, 0x2f, 0x84, 0x98, +0xe0, 0x50, 0x44, 0xbe, 0x04, 0x22, 0x96, 0x30, +0xda, 0x1d, 0xb2, 0x38, 0xa6, 0xb9, 0xd4, 0xa3, +0xc0, 0x2b, 0x40, 0x57, 0x6a, 0x32, 0x29, 0xc5, +0x80, 0x16, 0xd7, 0x8d, 0x8d, 0xb1, 0x84, 0xb9, +0xea, 0x78, 0xeb, 0x95, 0x44, 0xcb, 0xa5, 0x6b, +0x7e, 0xbf, 0xe6, 0x34, 0x4a, 0x72, 0x03, 0xb1, +0xa2, 0x50, 0xc0, 0xca, 0xcb, 0xf2, 0x38, 0x3c, +0x9a, 0x53, 0x97, 0x85, 0xf4, 0x96, 0xae, 0x9b, +0xf5, 0xe7, 0x2e, 0xf7, 0xb8, 0x4e, 0xfe, 0xa7, +0xd3, 0xdb, 0xde, 0x15, 0x56, 0x3d, 0x2e, 0x95, +0xb2, 0x82, 0xac, 0xf8, 0xbc, 0x29, 0xe3, 0x15, +0x59, 0x08, 0xf9, 0x8f, 0xff, 0x68, 0x61, 0xdb, +0xde, 0x93, 0x00, 0x94, 0x17, 0x64, 0x51, 0x51, +0x1c, 0x62, 0x4a, 0x59, 0xfe, 0x40, 0xe3, 0xbc, +0x6a, 0xcb, 0x21, 0xc4, 0x66, 0xa7, 0xaa, 0x6c, +0x00, 0x8c, 0x54, 0x03, 0xca, 0x50, 0x5c, 0x3f, +0xb3, 0xe7, 0xd8, 0x85, 0xc2, 0xa7, 0xfe, 0xb0, +0xdf, 0x37, 0x14, 0xd7, 0x47, 0xae, 0x0a, 0x00, +0x2b, 0x17, 0xd5, 0x72, 0xff, 0xe2, 0x5a, 0x7b, +0xfd, 0x96, 0x37, 0xa4, 0x73, 0x97, 0xbb, 0xd3, +0xc6, 0x54, 0x96, 0xe4, 0xb2, 0x7e, 0xe5, 0x42, +0x2e, 0x76, 0xf6, 0xf2, 0x93, 0x6d, 0xfb, 0xb0, +0xac, 0x0f, 0x57, 0xd8, 0xef, 0x76, 0xf2, 0xd8, +0x57, 0x17, 0x0f, 0xce, 0xaa, 0x1e, 0x7f, 0xc8, +0xeb, 0x72, 0x34, 0x02, 0x09, 0x01, 0x60, 0x59, +0xac, 0x6d, 0x79, 0xf7, 0x5a, 0xc1, 0x13, 0x2f, +0xef, 0xc9, 0x98, 0xbc, 0x72, 0x5c, 0x88, 0xfb, +0x17, 0xd7, 0xf2, 0xd0, 0x33, 0x4d, 0x19, 0x93, +0x03, 0xb4, 0xbe, 0xd7, 0xc3, 0xc3, 0x9b, 0x76, +0xe0, 0x73, 0x3b, 0xd9, 0xb4, 0x6e, 0x19, 0x6e, +0xa7, 0x23, 0xc9, 0xf5, 0x47, 0xe3, 0x7c, 0xf7, +0xc5, 0x37, 0x3c, 0x7b, 0x8e, 0x9d, 0xaf, 0x8b, +0x44, 0xe3, 0xaf, 0x00, 0x08, 0x40, 0x8d, 0x1b, +0xc6, 0x0f, 0x9f, 0xdc, 0xf6, 0x77, 0x7f, 0x46, +0x55, 0x60, 0xed, 0xb2, 0xb9, 0xfc, 0x72, 0xd7, +0x21, 0xba, 0xc3, 0x03, 0x63, 0x85, 0x01, 0x90, +0x30, 0x4c, 0x1e, 0x7d, 0x69, 0x37, 0x17, 0x3b, +0x7b, 0x79, 0xfe, 0x9b, 0xcb, 0x11, 0x92, 0x94, +0xe4, 0x6c, 0x1b, 0x9e, 0x7d, 0xf5, 0x80, 0x5b, +0x75, 0xc8, 0x4b, 0x00, 0x49, 0x00, 0xc5, 0x7d, +0x03, 0x43, 0xb4, 0x77, 0x85, 0x33, 0x0a, 0x86, +0x02, 0x1e, 0x6e, 0x29, 0x0e, 0xf1, 0xd7, 0x23, +0xad, 0x1f, 0x99, 0x3c, 0x35, 0xd1, 0xcf, 0x77, +0xbc, 0x4d, 0xd7, 0x8d, 0x01, 0x56, 0x2c, 0xa8, +0x19, 0xc6, 0x0d, 0xc5, 0x75, 0x7a, 0xfa, 0x06, +0x75, 0xa0, 0x4a, 0x00, 0x85, 0xdd, 0x37, 0x06, +0xcd, 0xb1, 0xc4, 0x6a, 0x2b, 0x8a, 0x38, 0x7e, +0xa1, 0x03, 0x6b, 0xf4, 0x8e, 0xf9, 0x48, 0xfc, +0xb4, 0xe9, 0x20, 0xab, 0xef, 0x98, 0x89, 0xdf, +0xe3, 0x1a, 0xf6, 0x3c, 0x12, 0x4d, 0xd8, 0x40, +0x50, 0x00, 0x85, 0x5d, 0xef, 0xf7, 0x8b, 0xb1, +0x44, 0xa6, 0x57, 0x14, 0xf1, 0xaf, 0xb6, 0xab, +0x9f, 0x38, 0xb9, 0x10, 0x12, 0x91, 0xa1, 0x38, +0xfb, 0x4f, 0xb5, 0xd1, 0x38, 0x67, 0xd2, 0x30, +0xae, 0x34, 0x2f, 0xa0, 0x02, 0xe7, 0x15, 0xc0, +0x37, 0x18, 0xd3, 0x95, 0xb1, 0x84, 0xaa, 0x4b, +0xf3, 0x38, 0xd0, 0xf2, 0x2e, 0x8f, 0x7e, 0x79, +0x11, 0xd3, 0x6f, 0x29, 0xc2, 0x34, 0x6d, 0x8e, +0x5f, 0xb8, 0xc2, 0x73, 0xdb, 0x0f, 0x60, 0x98, +0x56, 0xda, 0x77, 0xee, 0xaa, 0x9b, 0xcc, 0xda, +0x65, 0x73, 0x90, 0x90, 0x70, 0xa9, 0x0a, 0x87, +0xce, 0xb6, 0x27, 0x39, 0xaf, 0xa6, 0x22, 0x0b, +0x61, 0x01, 0x61, 0x05, 0x68, 0xad, 0x2c, 0x09, +0xa5, 0x2f, 0xfd, 0x0f, 0x10, 0x0a, 0x7a, 0xf8, +0xc1, 0x83, 0x5f, 0x60, 0xdb, 0x5b, 0x27, 0xd9, +0x7f, 0xaa, 0x8d, 0x99, 0x95, 0xe3, 0x28, 0x2f, +0xca, 0xe2, 0xae, 0xba, 0xc9, 0xec, 0x38, 0x70, +0x7a, 0x54, 0x7c, 0x41, 0xb6, 0x8f, 0xaf, 0x2f, +0x9b, 0x4b, 0xd3, 0xfe, 0x16, 0x6c, 0x6c, 0xae, +0xbe, 0x1f, 0x61, 0x7a, 0x45, 0x51, 0x92, 0x9f, +0x50, 0x98, 0x43, 0x34, 0x9e, 0x68, 0x77, 0xa9, +0x0a, 0x02, 0x38, 0x53, 0x96, 0x9f, 0xed, 0x1a, +0xa5, 0x92, 0x02, 0xd3, 0xb2, 0x58, 0xf5, 0xe4, +0xab, 0xfc, 0xfa, 0xcd, 0xa3, 0x9c, 0x6e, 0xbb, +0x86, 0x2c, 0x24, 0x76, 0x1e, 0x3c, 0xcb, 0xed, +0xd3, 0x26, 0xa4, 0x8d, 0xbf, 0xb5, 0xbc, 0x80, +0xa3, 0xad, 0x57, 0xd8, 0xba, 0xf7, 0x04, 0x3b, +0x0e, 0x9e, 0x26, 0xc7, 0xef, 0xe6, 0x7a, 0xdf, +0x60, 0x92, 0xaf, 0x9f, 0x5a, 0x6e, 0x3a, 0x64, +0xf1, 0x27, 0xf8, 0xdf, 0x36, 0xec, 0x03, 0xe2, +0x41, 0xaf, 0x96, 0xd1, 0x80, 0x22, 0xcb, 0x44, +0xa2, 0x71, 0x00, 0xfa, 0xa2, 0x31, 0x9e, 0x6b, +0x3a, 0x40, 0x4b, 0xdb, 0x55, 0x8a, 0x43, 0x81, +0xb4, 0xf1, 0x5d, 0xe1, 0x01, 0x42, 0x01, 0x0f, +0xb1, 0x84, 0x41, 0xdf, 0x40, 0x8c, 0x1c, 0xbf, +0x9b, 0xde, 0xfe, 0x68, 0x92, 0xbf, 0x73, 0xde, +0xe4, 0x98, 0xcf, 0xed, 0x7a, 0xe9, 0xa6, 0x01, +0x74, 0xd3, 0x3c, 0x55, 0x53, 0x9e, 0x9f, 0xd1, +0x80, 0x43, 0x16, 0xe8, 0xc6, 0xf0, 0x8d, 0xd2, +0xdb, 0x1f, 0x25, 0xdb, 0xa7, 0x91, 0xb2, 0xc5, +0x93, 0x38, 0xdb, 0xde, 0x45, 0x59, 0x41, 0x16, +0xb9, 0x01, 0x0f, 0x00, 0x71, 0xdd, 0x44, 0x75, +0xc8, 0x00, 0xd4, 0x94, 0x17, 0x20, 0x84, 0xd4, +0x01, 0xb4, 0x25, 0x0d, 0x04, 0x3c, 0xae, 0xed, +0xb7, 0x4f, 0x9b, 0x98, 0xb1, 0xc3, 0x28, 0xb2, +0x40, 0x37, 0x46, 0x17, 0x9b, 0x94, 0x2e, 0x3b, +0x60, 0x98, 0x16, 0xbb, 0x0f, 0x9f, 0x67, 0xf9, +0xfc, 0x29, 0x00, 0x84, 0x23, 0x51, 0xb2, 0x7d, +0x6e, 0x00, 0x96, 0xce, 0x9e, 0x94, 0xd0, 0x54, +0xe5, 0x85, 0x9b, 0xb1, 0x37, 0xb7, 0xdf, 0xee, +0xfa, 0xa9, 0x65, 0xe9, 0xcb, 0x39, 0x43, 0x22, +0xbf, 0xdb, 0xc9, 0x50, 0x42, 0x27, 0x53, 0x6b, +0x78, 0xed, 0xe0, 0x69, 0x96, 0xcf, 0x9f, 0x82, +0x2c, 0x04, 0xe1, 0xc8, 0x10, 0x41, 0xaf, 0x86, +0xdb, 0xa5, 0xd2, 0x30, 0xb7, 0x4a, 0xd7, 0x9c, +0x8e, 0xdf, 0x8f, 0x34, 0x70, 0xc9, 0xe5, 0x50, +0xfa, 0x4b, 0x72, 0x83, 0x69, 0xc5, 0xfa, 0x06, +0x62, 0x04, 0xbd, 0xc3, 0xeb, 0x74, 0xfe, 0xad, +0xe5, 0xb4, 0xb4, 0x5d, 0xcb, 0xe4, 0x99, 0x2b, +0x3d, 0x7d, 0x9c, 0xba, 0x78, 0x95, 0x7b, 0x16, +0xd4, 0xe0, 0x54, 0x15, 0x4c, 0xcb, 0xe2, 0x81, +0x25, 0x33, 0x0c, 0xd3, 0x30, 0xb7, 0x02, 0x3d, +0x23, 0x0d, 0x20, 0x84, 0xd8, 0x79, 0x5b, 0xcd, +0xf8, 0xb4, 0x1d, 0xb1, 0xbd, 0x3b, 0xcc, 0xb4, +0x89, 0x45, 0xc3, 0x9e, 0x35, 0xce, 0x9d, 0x44, +0xf3, 0xa1, 0x73, 0x19, 0x0d, 0x00, 0x3c, 0xbf, +0xf3, 0x1d, 0x56, 0x35, 0xcc, 0xa0, 0xba, 0x34, +0x8f, 0xfe, 0xc1, 0x38, 0xf7, 0x2e, 0x9c, 0x3a, +0x94, 0xe5, 0x73, 0xaf, 0x4f, 0x8d, 0x49, 0x1a, +0xd0, 0x9c, 0x8e, 0x5d, 0x4b, 0x66, 0x57, 0xf6, +0xa5, 0x13, 0x7a, 0xf1, 0xf5, 0xc3, 0x7c, 0x63, +0x79, 0x5d, 0xb2, 0x9d, 0x06, 0x3c, 0x2e, 0x2a, +0x8a, 0x43, 0xbc, 0x73, 0xa6, 0x3d, 0x5d, 0x78, +0x12, 0x9d, 0xd7, 0xfb, 0xf9, 0xcb, 0x91, 0x56, +0x1a, 0xe7, 0x4e, 0xa2, 0x24, 0x3f, 0x10, 0x97, +0x6c, 0xfb, 0x49, 0x60, 0xd8, 0xd0, 0x49, 0x6d, +0xc1, 0xfb, 0x26, 0x14, 0x86, 0xac, 0xd2, 0xbc, +0xd1, 0x9f, 0xe1, 0xdc, 0xe5, 0x6e, 0xf6, 0x9d, +0xbc, 0x48, 0xd3, 0xe3, 0x5f, 0x31, 0x56, 0x7e, +0xae, 0x56, 0xbf, 0x67, 0x41, 0x0d, 0x27, 0x2e, +0x74, 0x60, 0x5a, 0x19, 0xcb, 0xe6, 0x43, 0xf3, +0xcd, 0x87, 0x19, 0x8a, 0xeb, 0xdc, 0x56, 0x53, +0x16, 0xf3, 0xba, 0x5d, 0xcf, 0x8c, 0xe4, 0x53, +0x0d, 0x98, 0x4e, 0x45, 0x7e, 0xf6, 0xbe, 0xc5, +0xb5, 0xd1, 0x91, 0x41, 0x59, 0x3e, 0x8d, 0x86, +0x59, 0x95, 0x83, 0x7e, 0xb7, 0x6b, 0xc3, 0xb7, +0xbe, 0x38, 0xff, 0x17, 0x0f, 0x36, 0xcc, 0xec, +0x98, 0x53, 0x5d, 0xc2, 0x13, 0xab, 0x3e, 0x3f, +0x6c, 0xd4, 0xa6, 0xc3, 0xc2, 0xda, 0x89, 0x98, +0x96, 0x0d, 0x48, 0xa2, 0x3f, 0x1a, 0xdf, 0x1e, +0x89, 0xc6, 0x5f, 0x8f, 0x0c, 0xc6, 0xcf, 0x44, +0xe3, 0x89, 0x76, 0xa0, 0x66, 0xd8, 0x10, 0x52, +0x14, 0xb1, 0x65, 0xe9, 0x9c, 0x49, 0x7a, 0x6a, +0x31, 0xba, 0x54, 0x85, 0x17, 0x1e, 0x59, 0x11, +0xd5, 0x9c, 0xca, 0x06, 0x45, 0x11, 0x9b, 0x1c, +0x8a, 0x38, 0x62, 0x58, 0xb6, 0x77, 0xcd, 0xd3, +0x4d, 0x94, 0xe4, 0x06, 0x59, 0x32, 0xab, 0x72, +0x4c, 0x03, 0x6b, 0x96, 0xce, 0x62, 0xdd, 0xcf, +0x5e, 0x63, 0xc5, 0x63, 0xbf, 0xf5, 0x7d, 0xff, +0x57, 0x6f, 0x2e, 0x7b, 0xfc, 0x37, 0x7f, 0xbb, +0xf3, 0xc4, 0xc5, 0xce, 0x2a, 0xdb, 0x92, 0x34, +0xa0, 0x7f, 0xe4, 0x10, 0x0a, 0xbb, 0x1c, 0xf2, +0xba, 0xa7, 0x1f, 0x6e, 0xdc, 0xbc, 0xe6, 0xa9, +0xed, 0x3e, 0xa7, 0xaa, 0xb0, 0xf1, 0xa1, 0x86, +0x58, 0x6e, 0xc0, 0xfb, 0xb2, 0xa2, 0xc8, 0x93, +0x63, 0x09, 0xa3, 0xe7, 0x42, 0xc7, 0x75, 0xe3, +0xc7, 0xbf, 0xdb, 0x1b, 0xe8, 0xed, 0x8f, 0x52, +0x9a, 0x1f, 0xb4, 0x67, 0x56, 0x8d, 0x93, 0x76, +0xff, 0xf3, 0x7c, 0xda, 0xe4, 0x42, 0x48, 0xe4, +0xf8, 0xdc, 0xac, 0xbb, 0xbb, 0xce, 0xd2, 0x75, +0x23, 0x5a, 0x5d, 0x96, 0x6f, 0x14, 0x64, 0xf9, +0x5c, 0x83, 0x43, 0x89, 0xdd, 0x1e, 0xcd, 0xf1, +0x00, 0x10, 0x19, 0x35, 0x05, 0x65, 0x59, 0xde, +0x9a, 0xed, 0x77, 0xcf, 0x6e, 0xde, 0xb8, 0x7a, +0x0d, 0x20, 0x99, 0xa6, 0xb5, 0x29, 0xe0, 0x75, +0x9d, 0xd0, 0x0d, 0x73, 0xfb, 0x96, 0xe6, 0xc3, +0xe2, 0x72, 0x57, 0x98, 0x69, 0x15, 0x85, 0xac, +0x5a, 0x32, 0x23, 0xea, 0x70, 0x28, 0x6f, 0x0f, +0xc4, 0x12, 0x0b, 0x01, 0xc7, 0x48, 0x1d, 0x80, +0xbc, 0xa0, 0x17, 0xc3, 0xb4, 0x7a, 0xeb, 0x6b, +0x4a, 0xd7, 0xa8, 0xaa, 0xaa, 0x02, 0x2d, 0x40, +0xab, 0x4b, 0x55, 0x92, 0xc5, 0x93, 0x76, 0x0c, +0x67, 0x7b, 0xb5, 0x47, 0x80, 0x1f, 0x01, 0x4e, +0xa0, 0x03, 0x40, 0x48, 0xf2, 0xdd, 0xf7, 0x2d, +0x9a, 0xbe, 0xd2, 0xb2, 0xac, 0x00, 0x82, 0xde, +0x5c, 0xbf, 0x67, 0x33, 0x50, 0x95, 0x17, 0xf4, +0x4e, 0x06, 0x8a, 0xd3, 0xe9, 0x14, 0x66, 0xfb, +0xd0, 0x2d, 0xbb, 0x4d, 0x55, 0xd5, 0x5d, 0x69, +0x97, 0x28, 0x93, 0x81, 0x0f, 0x70, 0x3d, 0xf5, +0x46, 0x96, 0x69, 0xce, 0xf1, 0x6b, 0xcd, 0x23, +0x62, 0x8a, 0xbd, 0x9a, 0x6a, 0x64, 0x12, 0x28, +0xcc, 0xf1, 0xe3, 0x74, 0xc8, 0x63, 0x36, 0x8b, +0x31, 0x4f, 0x42, 0x1f, 0x03, 0x11, 0xaf, 0xe6, +0xcc, 0x78, 0x4e, 0x2b, 0xcd, 0xcb, 0xba, 0x11, +0xf4, 0xb8, 0x46, 0x1f, 0x18, 0xfe, 0x8f, 0x06, +0x06, 0x52, 0x8f, 0xdd, 0x23, 0x31, 0xa1, 0x28, +0x6b, 0x00, 0x18, 0xb3, 0x5b, 0x7d, 0x6a, 0x03, +0x9a, 0xd3, 0x91, 0x51, 0xa3, 0xac, 0x20, 0xdb, +0x04, 0x2e, 0x7d, 0x96, 0x06, 0x22, 0x99, 0x0c, +0x84, 0x02, 0x1e, 0x4a, 0xf3, 0x82, 0x1a, 0x70, +0xea, 0xb3, 0x34, 0xd0, 0xed, 0xd3, 0x9c, 0x5a, +0x61, 0xb6, 0x6f, 0x14, 0xb1, 0xfa, 0x8e, 0x59, +0x1d, 0x8a, 0x2c, 0x36, 0x03, 0xf1, 0xb1, 0x04, +0xa4, 0x34, 0x7f, 0xc7, 0x9f, 0x14, 0x5f, 0xfb, +0xf7, 0xe5, 0xee, 0x8d, 0xdf, 0xd9, 0xfc, 0xe7, +0x9c, 0xbe, 0xc1, 0x18, 0x95, 0x25, 0xb9, 0xc6, +0xb7, 0xbf, 0x54, 0xdf, 0x59, 0x59, 0x12, 0xd2, +0x65, 0x21, 0xea, 0x80, 0xcc, 0xff, 0x71, 0x00, +0xb6, 0x6d, 0x7f, 0xea, 0x4b, 0xd7, 0xcd, 0xef, +0x45, 0x63, 0x7a, 0x77, 0x2c, 0xa1, 0xdf, 0x88, +0x25, 0xf4, 0xe3, 0xb6, 0x6d, 0xdf, 0x6b, 0xdb, +0xb6, 0xf8, 0x38, 0xef, 0xfe, 0x17, 0x21, 0x8e, +0xd6, 0x18, 0xd5, 0x75, 0x26, 0x38, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *pgAdmin3_32_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_pgAdmin3_32_png = new wxImage(); + if (!img_pgAdmin3_32_png || !img_pgAdmin3_32_png->IsOk()) + { + wxMemoryInputStream img_pgAdmin3_32_pngIS(pgAdmin3_32_png_data, sizeof(pgAdmin3_32_png_data)); + img_pgAdmin3_32_png->LoadFile(img_pgAdmin3_32_pngIS, wxBITMAP_TYPE_PNG); + } + return img_pgAdmin3_32_png; +} +#define pgAdmin3_32_png_img pgAdmin3_32_png_img() + +static wxBitmap *pgAdmin3_32_png_bmp() +{ + static wxBitmap *bmp_pgAdmin3_32_png; + if (!bmp_pgAdmin3_32_png || !bmp_pgAdmin3_32_png->IsOk()) + bmp_pgAdmin3_32_png = new wxBitmap(*pgAdmin3_32_png_img); + return bmp_pgAdmin3_32_png; +} +#define pgAdmin3_32_png_bmp pgAdmin3_32_png_bmp() + +static wxIcon *pgAdmin3_32_png_ico() +{ + static wxIcon *ico_pgAdmin3_32_png; + if (!ico_pgAdmin3_32_png || !ico_pgAdmin3_32_png->IsOk()) + { + ico_pgAdmin3_32_png = new wxIcon(); + ico_pgAdmin3_32_png->CopyFromBitmap(*pgAdmin3_32_png_bmp); + } + return ico_pgAdmin3_32_png; +} +#define pgAdmin3_32_png_ico pgAdmin3_32_png_ico() + +#endif // PGADMIN3_32_PNG_H diff --git a/include/images/pgAdmin3-36.png b/include/images/pgAdmin3-36.png new file mode 100644 index 0000000..3389aca Binary files /dev/null and b/include/images/pgAdmin3-36.png differ diff --git a/include/images/pgAdmin3-48.png b/include/images/pgAdmin3-48.png new file mode 100644 index 0000000..45d8107 Binary files /dev/null and b/include/images/pgAdmin3-48.png differ diff --git a/include/images/pgAdmin3-96.png b/include/images/pgAdmin3-96.png new file mode 100644 index 0000000..571aa30 Binary files /dev/null and b/include/images/pgAdmin3-96.png differ diff --git a/include/images/pgAdmin3.ico b/include/images/pgAdmin3.ico new file mode 100644 index 0000000..3fcebaf Binary files /dev/null and b/include/images/pgAdmin3.ico differ diff --git a/include/images/pgAdmin3.png b/include/images/pgAdmin3.png new file mode 100644 index 0000000..2ec3e93 Binary files /dev/null and b/include/images/pgAdmin3.png differ diff --git a/include/images/pgAdmin3.pngc b/include/images/pgAdmin3.pngc new file mode 100644 index 0000000..bf56b6d --- /dev/null +++ b/include/images/pgAdmin3.pngc @@ -0,0 +1,977 @@ +#ifndef PGADMIN3_PNG_H +#define PGADMIN3_PNG_H + +static const unsigned char pgAdmin3_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x80, +0x08, 0x06, 0x00, 0x00, 0x00, 0x22, 0x79, 0xb6, +0xdf, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, +0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, +0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x02, 0x0d, 0x00, 0x00, 0x02, +0x0d, 0x01, 0x77, 0x4e, 0xbe, 0x70, 0x00, 0x00, +0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, +0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, +0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, +0xee, 0x3c, 0x1a, 0x00, 0x00, 0x1c, 0x9f, 0x49, +0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x7d, 0x69, +0x78, 0x1c, 0xd5, 0x95, 0xf6, 0x7b, 0xaa, 0x7a, +0x6f, 0xed, 0x92, 0x25, 0xd9, 0xd6, 0xe6, 0x15, +0x63, 0x1b, 0x1b, 0xdb, 0x02, 0x6c, 0x76, 0x0c, +0x1f, 0x24, 0x84, 0xb0, 0x63, 0x96, 0x19, 0x20, +0x0c, 0xc1, 0x36, 0x90, 0x4c, 0x20, 0x61, 0x99, +0x84, 0x4c, 0x88, 0x27, 0xdf, 0x93, 0x2f, 0x10, +0xc6, 0x0b, 0x66, 0x09, 0x66, 0x0b, 0x4c, 0x42, +0x82, 0x01, 0xb3, 0xef, 0x04, 0xdb, 0x18, 0x6c, +0xbc, 0x6f, 0x32, 0x36, 0xb6, 0xe4, 0x45, 0xfb, +0xee, 0x56, 0xab, 0xd7, 0x5a, 0xee, 0xf9, 0x7e, +0x54, 0x57, 0xab, 0xed, 0xc8, 0xb6, 0xa4, 0x96, +0x5a, 0x62, 0xba, 0xdf, 0xe7, 0xd1, 0xa3, 0x7b, +0xab, 0xab, 0x6f, 0xdf, 0xaa, 0xb7, 0xce, 0xb9, +0xe7, 0x9e, 0x7b, 0xee, 0x29, 0x62, 0x66, 0xa4, +0x90, 0x9c, 0x90, 0x06, 0xbb, 0x03, 0x29, 0x0c, +0x1e, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x52, 0xe4, 0x27, 0x31, 0x52, 0xe4, 0x27, +0x31, 0x2c, 0x83, 0xdd, 0x81, 0xef, 0x32, 0x66, +0xde, 0xb1, 0xa4, 0x40, 0xb7, 0x48, 0xa5, 0x2c, +0x44, 0x29, 0x11, 0x5b, 0x84, 0xa0, 0x76, 0x96, +0x44, 0x9b, 0x55, 0xb7, 0xb6, 0xf9, 0x6d, 0x52, +0x4b, 0xc5, 0x93, 0x77, 0xf9, 0x06, 0xbb, 0x8f, +0xc7, 0x03, 0x0d, 0xf5, 0x4d, 0x1b, 0x67, 0xfe, +0x7c, 0x91, 0x53, 0x0d, 0x5a, 0x4e, 0x11, 0xa0, +0x34, 0x66, 0x2d, 0x28, 0xb1, 0xc5, 0x07, 0x70, +0x00, 0xd0, 0x03, 0x36, 0x37, 0x7b, 0xd6, 0x2e, +0xbc, 0x37, 0xd8, 0x97, 0x76, 0xcb, 0xe7, 0x2d, +0x1d, 0xc3, 0x84, 0xa9, 0xc4, 0x7a, 0x0e, 0x40, +0x99, 0x00, 0xb9, 0x04, 0x8b, 0x3a, 0x62, 0xde, +0xa7, 0x59, 0x9c, 0xdf, 0x6e, 0x7f, 0x7a, 0x7e, +0x73, 0xec, 0xb9, 0x20, 0xbe, 0x94, 0x99, 0x27, +0x11, 0x49, 0x65, 0x00, 0x97, 0x02, 0x28, 0x05, +0xe0, 0x3c, 0xfe, 0xaf, 0x70, 0x05, 0x33, 0x3e, +0x93, 0x04, 0x7d, 0x1a, 0xec, 0x38, 0xfc, 0x45, +0xc5, 0xf2, 0x87, 0x87, 0xd4, 0xc3, 0x30, 0xa4, +0xc8, 0x27, 0x02, 0x9d, 0x76, 0xc7, 0x92, 0x72, +0x9d, 0xe8, 0x74, 0x89, 0x30, 0x83, 0x19, 0x33, +0x40, 0x98, 0x88, 0x63, 0x6b, 0x28, 0x06, 0x73, +0x15, 0x03, 0x9b, 0x01, 0xda, 0xc2, 0x84, 0xcd, +0x1c, 0x16, 0x9b, 0xb7, 0xbe, 0x78, 0x8f, 0xa7, +0xbb, 0x93, 0xa7, 0xcf, 0x5f, 0x72, 0xae, 0x0c, +0xe9, 0x2e, 0x06, 0x9f, 0x0b, 0x60, 0xf8, 0xf1, +0x7b, 0xc3, 0x5e, 0x30, 0x0e, 0x42, 0x92, 0x46, +0x82, 0x39, 0x37, 0xae, 0x0b, 0x33, 0xa0, 0x82, +0xc5, 0x4a, 0x9d, 0xc5, 0x82, 0xad, 0xcb, 0x7e, +0xbe, 0xb6, 0x1f, 0xda, 0x8b, 0x1b, 0x43, 0x82, +0x7c, 0x22, 0xd0, 0xf4, 0xf9, 0x8f, 0x5f, 0x49, +0x02, 0xbf, 0x05, 0x61, 0x4a, 0x9c, 0xcd, 0xe9, +0x10, 0x62, 0x0d, 0x13, 0xbd, 0xa1, 0x4b, 0xe2, +0xcd, 0x6d, 0x4f, 0xdf, 0x5b, 0x57, 0x3e, 0x6f, +0xe9, 0x18, 0x22, 0xf1, 0x28, 0x83, 0xae, 0xee, +0x97, 0x0e, 0x03, 0x00, 0x83, 0x85, 0xa6, 0xb4, +0xeb, 0x6a, 0xb0, 0x45, 0x0b, 0x05, 0x5b, 0x58, +0x68, 0x8a, 0x6c, 0xb5, 0xbb, 0x25, 0x8b, 0x35, +0x8d, 0x2c, 0xd6, 0x74, 0x8b, 0xd5, 0x51, 0x00, +0x49, 0x76, 0x74, 0xfb, 0x55, 0x4d, 0x79, 0x1f, +0x24, 0xee, 0xdf, 0xfc, 0xec, 0x03, 0xbb, 0xfb, +0xad, 0x3f, 0x7d, 0xc0, 0xa0, 0x93, 0x3f, 0xf3, +0x8e, 0xa5, 0x45, 0xba, 0x8c, 0xe5, 0x0c, 0x9e, +0xd5, 0xfd, 0x19, 0xac, 0x69, 0x21, 0x7f, 0xb5, +0xae, 0x2a, 0x5e, 0x92, 0x64, 0x1b, 0xc9, 0xb2, +0x5d, 0x22, 0xc9, 0x41, 0x92, 0x6c, 0x27, 0x8b, +0x35, 0x9d, 0x48, 0xb2, 0x1f, 0xa7, 0x79, 0x06, +0xd0, 0x08, 0xc2, 0x30, 0xf0, 0x91, 0xda, 0x83, +0x35, 0xd5, 0xab, 0x04, 0xbc, 0x7b, 0x75, 0x25, +0xd0, 0x2e, 0x54, 0x25, 0xc8, 0xba, 0xae, 0x58, +0x9c, 0xee, 0x1c, 0x8b, 0xdd, 0x5d, 0x28, 0xdb, +0x5d, 0x85, 0x92, 0xd5, 0x96, 0x03, 0x80, 0xba, +0x6b, 0x53, 0x0d, 0x78, 0xf7, 0xb6, 0xef, 0xdd, +0xf8, 0x4e, 0xed, 0xfa, 0x77, 0x36, 0x03, 0x08, +0x02, 0xf0, 0x03, 0x08, 0x00, 0xd0, 0x00, 0xd8, +0x00, 0xd8, 0x64, 0xbb, 0xdd, 0x99, 0x3f, 0xe9, +0xbc, 0x69, 0x19, 0x23, 0xc7, 0x4f, 0xb3, 0x67, +0x15, 0x4c, 0xb6, 0x3a, 0x33, 0xc6, 0x82, 0x20, +0xc7, 0xf4, 0x4c, 0x67, 0x5d, 0xfd, 0x1f, 0x16, +0xca, 0x03, 0x5b, 0x5e, 0xf8, 0x65, 0x4b, 0x2f, +0x6e, 0x59, 0xbf, 0x61, 0x50, 0xc9, 0x9f, 0x71, +0xd7, 0xd2, 0x99, 0x24, 0xf8, 0x4d, 0x00, 0x85, +0xe6, 0x31, 0x16, 0x7a, 0x20, 0x78, 0xb8, 0x71, +0x63, 0xd8, 0xd3, 0x5c, 0xd5, 0xd9, 0x78, 0xa0, +0xaa, 0x7d, 0xef, 0xfa, 0x6a, 0x5d, 0x09, 0x85, +0x01, 0x74, 0x00, 0x08, 0x03, 0x90, 0x23, 0x7f, +0x16, 0xc8, 0xb2, 0x35, 0x67, 0xf4, 0xf4, 0x51, +0xe9, 0x23, 0xc7, 0x8d, 0x73, 0x65, 0x17, 0x8c, +0xb6, 0xa6, 0xe7, 0x8e, 0xb1, 0x38, 0xd3, 0xc6, +0x12, 0xa8, 0xfb, 0x59, 0x0c, 0x43, 0x0f, 0xb4, +0x56, 0x7f, 0xde, 0xb4, 0xe3, 0xf3, 0x8f, 0xda, +0x2b, 0xb7, 0xd6, 0x45, 0xda, 0x6b, 0x83, 0x41, +0xa0, 0x0a, 0x40, 0x87, 0x31, 0x8e, 0xa7, 0xd9, +0x9c, 0x99, 0xb9, 0x19, 0xc5, 0xe3, 0x4b, 0x33, +0x8b, 0x27, 0x4e, 0x70, 0x17, 0x8d, 0xbf, 0xc0, +0xea, 0x48, 0x1b, 0x73, 0x74, 0x73, 0x5a, 0xd8, +0xff, 0x77, 0x7f, 0x53, 0xc3, 0xbc, 0xca, 0x0f, +0x97, 0xfa, 0x60, 0x3c, 0x68, 0x26, 0xcc, 0x87, +0x46, 0x02, 0x90, 0x03, 0xa0, 0x20, 0xa3, 0x6c, +0xd2, 0xa4, 0xa2, 0xd3, 0x2e, 0x9b, 0xeb, 0xc8, +0x19, 0x7e, 0x5e, 0x6c, 0xff, 0x84, 0xa6, 0x1e, +0xea, 0x6c, 0x3b, 0x74, 0xe1, 0xbe, 0x37, 0x1f, +0xaf, 0xea, 0xe3, 0x6d, 0xec, 0x33, 0x06, 0x8d, +0xfc, 0xe9, 0xf3, 0x9f, 0x28, 0x97, 0x20, 0xd6, +0x00, 0x70, 0x00, 0x00, 0x0b, 0xa1, 0xf8, 0x1a, +0xab, 0xde, 0xab, 0x5e, 0xf3, 0xda, 0xfb, 0x21, +0x4f, 0x93, 0x07, 0x40, 0x1d, 0x80, 0x76, 0x00, +0x87, 0x61, 0x10, 0xaf, 0x1f, 0xa3, 0x29, 0x02, +0x90, 0x06, 0xe3, 0x26, 0x67, 0xa7, 0x0d, 0x1f, +0x3d, 0x6a, 0xd8, 0xd4, 0xd9, 0x3f, 0xcc, 0x2e, +0x99, 0x74, 0x43, 0xac, 0x56, 0x08, 0x77, 0xb6, +0x6d, 0xa9, 0xdf, 0xf0, 0xee, 0x5f, 0xdb, 0x2b, +0xb7, 0xd6, 0x02, 0xd8, 0x0f, 0xa0, 0x12, 0x80, +0x17, 0x47, 0x92, 0x16, 0xdb, 0x26, 0x60, 0x3c, +0x64, 0x69, 0x00, 0xf2, 0x0a, 0xa7, 0x5f, 0x72, +0x71, 0xee, 0x98, 0x69, 0xd7, 0xd9, 0xb3, 0x0b, +0xce, 0x24, 0x92, 0xac, 0xe6, 0x89, 0x42, 0x53, +0x0f, 0xaa, 0x4a, 0xe8, 0xba, 0x9d, 0x2f, 0x3f, +0xb4, 0xe9, 0x58, 0xd7, 0x4a, 0x44, 0x14, 0x69, +0xd3, 0x35, 0x62, 0xda, 0xc5, 0x97, 0xe5, 0x4e, +0x9c, 0x75, 0xbf, 0x2d, 0x2d, 0x67, 0x7a, 0xb4, +0x0d, 0x55, 0x69, 0xec, 0x6c, 0xab, 0xbe, 0xb0, +0xf2, 0xed, 0xa5, 0xbb, 0x39, 0x81, 0x84, 0x0c, +0x0a, 0xf9, 0x67, 0xdf, 0xfe, 0x68, 0x7a, 0xc8, +0xea, 0xd8, 0x0a, 0x60, 0x0c, 0x00, 0x08, 0x4d, +0x6d, 0xaf, 0x5d, 0xff, 0xf6, 0x7f, 0xb7, 0x54, +0xac, 0xd9, 0x0b, 0xe0, 0x5b, 0x00, 0xfb, 0x60, +0x48, 0x25, 0x7a, 0x7a, 0x33, 0x22, 0x37, 0x18, +0x93, 0xae, 0xfb, 0xad, 0xdb, 0x9e, 0x9d, 0xb9, +0x92, 0x48, 0x2a, 0x07, 0x00, 0xd6, 0xf5, 0x40, +0xf3, 0x8e, 0xcf, 0x9f, 0xa8, 0xdd, 0xf0, 0xde, +0x16, 0x00, 0xf5, 0x00, 0x76, 0x02, 0xf0, 0x32, +0xb3, 0xe8, 0x69, 0x7f, 0x63, 0xc8, 0xcb, 0xc9, +0x2c, 0x9e, 0x30, 0x7d, 0xe4, 0xcc, 0x2b, 0x1f, +0x74, 0xe6, 0x0c, 0x9f, 0x1d, 0x3d, 0x81, 0x59, +0xd5, 0x42, 0x9d, 0xff, 0xb9, 0xfd, 0xe5, 0xff, +0x7c, 0xf4, 0x44, 0xfd, 0x25, 0x22, 0x09, 0x40, +0x66, 0xd9, 0xec, 0x5b, 0xe6, 0xe5, 0x8c, 0x99, +0xb6, 0x80, 0x24, 0xc9, 0x66, 0xdc, 0x03, 0xa5, +0xc5, 0xdf, 0x54, 0xfd, 0x7f, 0xf6, 0xbe, 0xb7, +0x74, 0x47, 0xa2, 0x1e, 0x80, 0x41, 0x99, 0xe7, +0x07, 0x2d, 0x8e, 0x27, 0x29, 0x42, 0x3c, 0x6b, +0xaa, 0x77, 0xdf, 0x87, 0x7f, 0xfa, 0x8d, 0xaf, +0xbe, 0xb2, 0x1a, 0xc0, 0x3a, 0x00, 0x6d, 0x7d, +0xb9, 0x78, 0x66, 0x66, 0x5a, 0xb0, 0x40, 0x72, +0x34, 0x64, 0xff, 0x05, 0x40, 0x79, 0xe4, 0xa8, +0x56, 0xbf, 0xf9, 0xc3, 0xc7, 0x1a, 0xb7, 0x7e, +0xba, 0x0d, 0xc0, 0x06, 0x00, 0x0d, 0xbd, 0x21, +0x3d, 0xb6, 0x6d, 0x18, 0x1a, 0xa2, 0x95, 0x88, +0x3e, 0xed, 0xa8, 0xf9, 0xc3, 0x9a, 0xb1, 0xdf, +0x9f, 0x7b, 0x6f, 0x46, 0xd1, 0x84, 0x87, 0x48, +0x92, 0x5d, 0x20, 0xb2, 0x5a, 0x9c, 0x19, 0x7f, +0x98, 0x74, 0xfd, 0xaf, 0x73, 0x89, 0xe8, 0x3f, +0x8e, 0xf7, 0x1b, 0x91, 0xcf, 0x0e, 0x13, 0xd1, +0xa3, 0xb6, 0xf4, 0xec, 0x03, 0x69, 0x05, 0x65, +0x2f, 0x11, 0x49, 0x76, 0xc9, 0x62, 0x1b, 0xe6, +0x2e, 0x28, 0xfd, 0xfc, 0xa4, 0xcb, 0x7f, 0x72, +0x09, 0x11, 0x6d, 0x4e, 0xc4, 0x03, 0x90, 0x70, +0x0f, 0x5f, 0xf9, 0xbc, 0xc5, 0xd3, 0x89, 0x70, +0x73, 0xa4, 0xca, 0x8d, 0x15, 0xab, 0x9e, 0xf2, +0xd5, 0x57, 0xd6, 0x02, 0x58, 0x89, 0x3e, 0x12, +0x1f, 0x6d, 0xbb, 0x21, 0xeb, 0x36, 0x00, 0x57, +0x98, 0xf5, 0xd6, 0x3d, 0x5f, 0x3f, 0xdb, 0xb8, +0xf5, 0xd3, 0x0a, 0x18, 0x0f, 0x55, 0x7d, 0x5f, +0x88, 0x3f, 0x1a, 0x6c, 0x20, 0x58, 0xf9, 0xe1, +0xb2, 0x3f, 0x34, 0xee, 0x58, 0x79, 0x89, 0x16, +0xf4, 0x7d, 0x6b, 0x7e, 0xe6, 0xc8, 0x1a, 0x76, +0xff, 0xc9, 0x57, 0xff, 0xe2, 0x57, 0x11, 0xe9, +0x3e, 0x51, 0x3b, 0x62, 0xef, 0xdb, 0x4b, 0x96, +0xfb, 0x9a, 0x0f, 0xdd, 0x00, 0xa1, 0x87, 0x00, +0x40, 0xb2, 0x58, 0x73, 0x9c, 0xb9, 0xc5, 0xaf, +0x03, 0x99, 0x59, 0xf1, 0xf6, 0xb3, 0x27, 0x48, +0x38, 0xf9, 0x0c, 0xe9, 0x6e, 0xb3, 0x1c, 0x6c, +0xaf, 0x5b, 0x55, 0xbf, 0xfe, 0xbd, 0x6d, 0x00, +0x36, 0x01, 0xf0, 0xc7, 0x45, 0xfc, 0xbc, 0x65, +0x56, 0x06, 0x3d, 0x64, 0xd6, 0x7d, 0x0d, 0x55, +0x6f, 0x1f, 0x5a, 0xfd, 0xf7, 0xd5, 0x91, 0xb6, +0x9b, 0xfa, 0x5b, 0x92, 0x98, 0x59, 0xd4, 0xaf, +0x7f, 0xf7, 0xab, 0x03, 0x9f, 0x3f, 0x7d, 0xa6, +0x1a, 0xe8, 0x58, 0x67, 0x1e, 0x77, 0x0e, 0x2b, +0x5e, 0x70, 0xf2, 0x55, 0xf7, 0xdc, 0x69, 0x0e, +0x43, 0x27, 0x68, 0x83, 0xf7, 0xbe, 0xb5, 0xf8, +0x6d, 0x6f, 0x63, 0xd5, 0x75, 0xcc, 0x22, 0x08, +0x00, 0xb2, 0xcd, 0x51, 0x5a, 0x7c, 0xd6, 0x85, +0x77, 0x12, 0x91, 0x7c, 0xa2, 0xef, 0xc7, 0x8b, +0x84, 0x92, 0x3f, 0xe5, 0xae, 0xa7, 0xb3, 0x89, +0x70, 0xa3, 0x59, 0x6f, 0xdc, 0xb6, 0xf2, 0x03, +0x00, 0x07, 0x60, 0xa8, 0xe3, 0x38, 0xc9, 0x09, +0xdd, 0x0a, 0x60, 0x14, 0x00, 0x08, 0x4d, 0xf5, +0xec, 0xff, 0xc7, 0x9f, 0x57, 0x00, 0xd8, 0x03, +0xe0, 0xd0, 0x40, 0xa9, 0x50, 0x66, 0xe6, 0x8e, +0x9a, 0x9a, 0x76, 0xbd, 0xa6, 0xf1, 0x62, 0x2d, +0xe4, 0xdf, 0x0a, 0x00, 0x04, 0x92, 0x5c, 0xf9, +0x65, 0x8b, 0xc7, 0x7d, 0x6f, 0xde, 0x55, 0x3d, +0x7d, 0x00, 0xf6, 0xbd, 0xfb, 0xe4, 0xfb, 0x7a, +0x38, 0xf0, 0x27, 0xf3, 0x58, 0x66, 0xf1, 0xa4, +0x2b, 0x01, 0x14, 0xf4, 0xe4, 0xfb, 0xf1, 0x20, +0xa1, 0xe4, 0xdb, 0x74, 0xf5, 0x1a, 0x44, 0x5c, +0xa2, 0xaa, 0xcf, 0xb3, 0xab, 0x7d, 0xdf, 0xc6, +0x1a, 0x00, 0xfb, 0xe2, 0x55, 0xc7, 0xe5, 0xf3, +0x96, 0x59, 0x41, 0xf8, 0x95, 0x59, 0xef, 0xac, +0xdb, 0xf3, 0x9e, 0xea, 0xf7, 0x76, 0x00, 0xd8, +0xdd, 0x1f, 0xaa, 0xfe, 0x44, 0xa8, 0x58, 0xf9, +0xa4, 0xaf, 0xad, 0xb1, 0xea, 0x22, 0x2d, 0x1c, +0xd8, 0x63, 0x1c, 0x21, 0x8b, 0x7b, 0xc4, 0xe8, +0xa7, 0xb2, 0xca, 0x4e, 0x2d, 0xed, 0xc9, 0xf7, +0x99, 0x99, 0xd9, 0x6a, 0x59, 0x68, 0xd6, 0xad, +0xe9, 0xd9, 0x27, 0x03, 0x18, 0x3d, 0x20, 0x9d, +0x8d, 0x41, 0x42, 0xc9, 0x67, 0x70, 0xb9, 0x59, +0xee, 0x6c, 0xdc, 0xbf, 0x0e, 0x40, 0x33, 0x8c, +0x69, 0x5c, 0x5c, 0x20, 0x0a, 0x5f, 0x0b, 0x53, +0xea, 0x75, 0xb5, 0xe3, 0xd0, 0x9a, 0xd7, 0x3f, +0x83, 0x31, 0x6b, 0x50, 0xe3, 0x6d, 0xbb, 0xa7, +0xa8, 0xf9, 0xe8, 0xb9, 0x76, 0xc5, 0xdb, 0x34, +0x5b, 0xe8, 0x5a, 0x3b, 0x00, 0xc8, 0x56, 0x47, +0xc1, 0xc8, 0xd3, 0xbe, 0xb7, 0x94, 0x88, 0x8e, +0xe7, 0x84, 0x8a, 0x62, 0xfb, 0xb3, 0x0f, 0xd4, +0xc2, 0x70, 0x14, 0x41, 0x92, 0x64, 0xb7, 0x6c, +0xb3, 0x15, 0xa2, 0x7b, 0x27, 0x53, 0xbf, 0x21, +0xa1, 0xe4, 0x13, 0xd1, 0x54, 0xb3, 0x1c, 0x68, +0x3e, 0x74, 0x08, 0x40, 0x2d, 0xba, 0x9f, 0x67, +0xf7, 0x0a, 0x82, 0xf9, 0x72, 0xb3, 0xdc, 0x59, +0x5f, 0xf5, 0x91, 0xea, 0xf7, 0x78, 0x00, 0xec, +0x4f, 0xe4, 0x9c, 0x19, 0x00, 0xbe, 0x79, 0x63, +0x51, 0x83, 0xae, 0x06, 0xe7, 0x9a, 0x75, 0x47, +0xce, 0xf0, 0x1f, 0x94, 0xcd, 0xbe, 0xf9, 0xb6, +0x9e, 0x18, 0x80, 0x11, 0xb4, 0x46, 0xfe, 0x93, +0x33, 0xb7, 0x38, 0x17, 0x03, 0xcc, 0x4f, 0xc2, +0xc8, 0xa7, 0x05, 0x0b, 0x24, 0x00, 0xa7, 0x00, +0x00, 0x18, 0xdc, 0xbe, 0x7f, 0x5b, 0x0d, 0x00, +0x4f, 0xbc, 0x04, 0xcd, 0x99, 0xf3, 0x9a, 0x4c, +0x84, 0x8b, 0xcd, 0x7a, 0xfb, 0xde, 0xaf, 0x37, +0xc0, 0x70, 0xe0, 0x24, 0x4c, 0xea, 0x63, 0xb1, +0xe3, 0xa5, 0x5f, 0xaf, 0xd0, 0xd5, 0xd0, 0x6b, +0x91, 0x2a, 0x65, 0x96, 0x4e, 0x7a, 0x08, 0x70, +0x15, 0xf6, 0x70, 0xfc, 0x6e, 0x33, 0x0b, 0x8e, +0xf4, 0x9c, 0x34, 0x18, 0xae, 0xe2, 0x01, 0x43, +0xc2, 0xc8, 0x3f, 0xbd, 0x36, 0xb7, 0x14, 0x80, +0x1b, 0x00, 0x74, 0x35, 0xd4, 0xac, 0xfa, 0x3d, +0x41, 0xf4, 0x83, 0xca, 0x3f, 0x98, 0xd5, 0x70, +0x06, 0x0c, 0xef, 0x1e, 0x74, 0x25, 0xd4, 0x14, +0x71, 0xdb, 0xd6, 0x26, 0x5a, 0xea, 0x4d, 0x30, +0x33, 0xab, 0x9d, 0xc1, 0xf9, 0x2c, 0x84, 0x07, +0x00, 0x2c, 0x36, 0x67, 0x51, 0xe9, 0xf9, 0x57, +0xdd, 0x89, 0x9e, 0xdd, 0x6b, 0xb7, 0x59, 0x50, +0x42, 0x7e, 0x05, 0xff, 0x5b, 0xc8, 0x17, 0x16, +0x11, 0xbd, 0x30, 0xd6, 0xb5, 0x00, 0x8c, 0xc5, +0x10, 0x2d, 0xde, 0x76, 0x59, 0xa6, 0x1f, 0x98, +0xe5, 0x90, 0xa7, 0x69, 0x2b, 0x00, 0x1f, 0x80, +0xce, 0x78, 0xdb, 0x8d, 0x07, 0x15, 0xcb, 0x1f, +0x6e, 0x67, 0xa1, 0x2f, 0x32, 0xeb, 0x59, 0xa5, +0x93, 0xfe, 0x05, 0xc0, 0xc8, 0x1e, 0x48, 0x7f, +0xbe, 0x59, 0x08, 0x36, 0xd7, 0x7a, 0x70, 0x6c, +0x97, 0x76, 0xbf, 0x20, 0x81, 0x63, 0x3e, 0x59, +0xbb, 0xca, 0xac, 0xa1, 0x9f, 0xd4, 0xb2, 0x00, +0x9f, 0x6e, 0x96, 0x7d, 0x0d, 0x55, 0xdb, 0x01, +0x34, 0xa0, 0x1f, 0xec, 0x88, 0x78, 0x21, 0xc9, +0xda, 0x12, 0xb0, 0xe8, 0x04, 0x00, 0x8b, 0xc3, +0x3d, 0x6a, 0x64, 0xf9, 0x0f, 0xae, 0xc6, 0x71, +0x0c, 0xb8, 0xf2, 0x79, 0xcb, 0xac, 0x00, 0xb2, +0x00, 0x63, 0x71, 0x4b, 0x0d, 0x79, 0x15, 0x00, +0xa1, 0x81, 0xec, 0x63, 0x22, 0xdd, 0xbb, 0x51, +0xf2, 0x99, 0x85, 0x0e, 0xa0, 0x5f, 0xa6, 0x60, +0xc4, 0x98, 0x60, 0x96, 0xbd, 0xb5, 0xdf, 0xd6, +0x02, 0x68, 0xea, 0x8f, 0x76, 0xfb, 0xd4, 0x17, +0x02, 0x9d, 0xfa, 0xa3, 0xc5, 0x99, 0x56, 0x27, +0x72, 0x48, 0x72, 0xba, 0x74, 0x4d, 0x7f, 0x57, +0x92, 0x71, 0x13, 0x00, 0xb8, 0x87, 0x8f, 0x3a, +0x13, 0xc0, 0x5f, 0x01, 0x74, 0xbb, 0x7c, 0x6b, +0x11, 0xe1, 0x02, 0x2d, 0xe2, 0xd6, 0x11, 0x9a, +0xe2, 0x41, 0xd7, 0x2a, 0xe3, 0x80, 0x21, 0x81, +0xe4, 0x93, 0x35, 0x2a, 0x90, 0xcc, 0x1a, 0xfa, +0x41, 0x3a, 0x27, 0xdf, 0xfd, 0x54, 0x9a, 0x03, +0x28, 0x32, 0x9a, 0x14, 0x61, 0x6f, 0xed, 0xbe, +0x56, 0x00, 0x1d, 0x93, 0xae, 0xfb, 0xad, 0xf5, +0xb4, 0x3b, 0x97, 0xfc, 0x50, 0x08, 0x3a, 0x0b, +0x40, 0x09, 0x11, 0x17, 0x32, 0xa3, 0x11, 0xe0, +0x0a, 0xc1, 0xf4, 0xfe, 0xd6, 0x65, 0x3f, 0xdb, +0x18, 0xef, 0x6f, 0xc7, 0xe2, 0xb4, 0xb9, 0x4f, +0x7c, 0x5f, 0x90, 0xb8, 0x71, 0xc6, 0x3c, 0x5c, +0x0e, 0x48, 0x99, 0x22, 0xf2, 0x58, 0x4b, 0x72, +0x97, 0x93, 0xce, 0x99, 0x57, 0x34, 0x0b, 0x86, +0xe3, 0xa6, 0xb5, 0x3b, 0x7b, 0x44, 0x95, 0x79, +0xb2, 0xa9, 0x16, 0x34, 0x25, 0xd8, 0x8c, 0x01, +0x96, 0x7a, 0x20, 0x81, 0xe4, 0xeb, 0xac, 0x09, +0x29, 0x32, 0xca, 0xb0, 0xb1, 0x9e, 0x1d, 0xb7, +0xe4, 0x3b, 0x34, 0x65, 0xbc, 0xb9, 0x34, 0xae, +0x2b, 0xc1, 0xc6, 0x9c, 0x93, 0xca, 0x0b, 0xcb, +0xce, 0xbb, 0xf1, 0xbf, 0x88, 0xe8, 0x66, 0x66, +0xe4, 0x75, 0x8d, 0xb0, 0x04, 0xa3, 0x4c, 0xd7, +0xc8, 0x84, 0xdf, 0x4c, 0xbb, 0xfd, 0xd1, 0xa7, +0x7d, 0x0d, 0xb5, 0x3f, 0xdf, 0xf7, 0xc1, 0xe3, +0xe1, 0x78, 0x7e, 0x7f, 0xf2, 0xdd, 0x4f, 0xa5, +0x39, 0x74, 0xed, 0x45, 0x48, 0xb8, 0xf6, 0x44, +0x83, 0xb9, 0x6c, 0x75, 0x14, 0x00, 0x28, 0x06, +0xf0, 0x0d, 0xba, 0x7b, 0xf0, 0x59, 0xcc, 0x34, +0xaf, 0x45, 0xe9, 0x6c, 0x3b, 0x00, 0xc3, 0x26, +0x1a, 0xd0, 0xe1, 0x2b, 0x61, 0xe4, 0x5b, 0x2d, +0xd6, 0xbd, 0xba, 0x66, 0x68, 0x31, 0x8b, 0xdd, +0x35, 0x02, 0xfd, 0xe0, 0xc0, 0x90, 0x58, 0xce, +0x11, 0x64, 0xdc, 0x1f, 0xd9, 0x62, 0xcf, 0x1b, +0x75, 0xfe, 0x4d, 0x8b, 0x4e, 0xf0, 0x15, 0x00, +0x20, 0xd9, 0xea, 0xb8, 0xcb, 0x5d, 0x30, 0x7c, +0x2a, 0x11, 0x5d, 0xc0, 0xcc, 0x7d, 0xb6, 0x3d, +0x1c, 0xba, 0xf6, 0x06, 0xd0, 0x35, 0xcd, 0x04, +0x00, 0x21, 0x74, 0x1f, 0xab, 0x4a, 0x27, 0xb3, +0x08, 0xcb, 0x16, 0x5b, 0x26, 0x59, 0xac, 0xd9, +0xc6, 0x07, 0xba, 0x8e, 0x18, 0x6b, 0xfe, 0x9f, +0xae, 0x85, 0xa4, 0x33, 0x4c, 0xa6, 0x03, 0x2d, +0x75, 0x95, 0x30, 0xe2, 0x18, 0x06, 0x14, 0x09, +0x23, 0x7f, 0xfd, 0x13, 0x77, 0xb7, 0x95, 0xcf, +0x5b, 0xd2, 0x04, 0xa2, 0x02, 0xc9, 0x62, 0xcd, +0x72, 0xe7, 0x15, 0x0d, 0xf7, 0xb7, 0xd6, 0xc6, +0xd5, 0xa6, 0x06, 0x91, 0x29, 0x45, 0x9e, 0x21, +0x92, 0x2d, 0x47, 0xdc, 0x58, 0x2d, 0xec, 0xaf, +0xf1, 0x37, 0x55, 0xaf, 0x09, 0x7b, 0x9b, 0xea, +0xc3, 0x3e, 0x8f, 0xd7, 0x99, 0x91, 0x9b, 0x9d, +0x36, 0x72, 0xc2, 0x99, 0x8e, 0xcc, 0x61, 0x67, +0x00, 0x80, 0xc5, 0xee, 0x3e, 0xab, 0xe4, 0x9c, +0xeb, 0xef, 0x26, 0xa2, 0xc7, 0xfb, 0xe2, 0x02, +0x3e, 0xed, 0xae, 0x25, 0x97, 0x03, 0x64, 0x12, +0xcf, 0xc1, 0x96, 0xea, 0x4f, 0xb4, 0xb0, 0xbf, +0xc3, 0x96, 0x9e, 0x57, 0xa2, 0x2b, 0xa1, 0xb6, +0x83, 0xab, 0xfe, 0xf6, 0xb2, 0xd5, 0x9d, 0x2e, +0x8f, 0xbb, 0xf4, 0xce, 0x57, 0x00, 0x80, 0x85, +0xde, 0x89, 0xe3, 0x48, 0x32, 0x03, 0x51, 0xc3, +0xd5, 0x73, 0x70, 0xfb, 0x7e, 0x18, 0x81, 0x2c, +0x03, 0x8a, 0x84, 0xae, 0xe7, 0x33, 0xa1, 0x82, +0x80, 0x02, 0x00, 0x48, 0x2f, 0x99, 0x38, 0xce, +0xdf, 0x5a, 0x6b, 0x43, 0x1c, 0x63, 0x1b, 0x11, +0x4a, 0x8e, 0x68, 0x5f, 0xe8, 0x4a, 0xf0, 0x70, +0xd3, 0xda, 0xb6, 0x6f, 0xbf, 0xfe, 0xbc, 0x79, +0xe7, 0xea, 0xbd, 0x00, 0x3a, 0x26, 0x5d, 0xf7, +0xab, 0xd9, 0xf6, 0xec, 0x61, 0xf3, 0x00, 0xa8, +0x5a, 0xc8, 0xbf, 0x3a, 0xe4, 0x69, 0xaa, 0x75, +0x64, 0x15, 0x5c, 0x03, 0x00, 0x99, 0x25, 0x27, +0xff, 0x08, 0xc0, 0xab, 0x44, 0xd4, 0xd8, 0x5b, +0xbf, 0x80, 0xd0, 0xe9, 0x16, 0x73, 0x58, 0xf1, +0x35, 0x54, 0xbd, 0x63, 0xcf, 0xcc, 0x9f, 0xe0, +0x1c, 0x56, 0x32, 0x1a, 0x80, 0x15, 0x2c, 0x82, +0x23, 0x4f, 0xbf, 0xf4, 0x73, 0x7b, 0x66, 0xe1, +0x3f, 0xba, 0xce, 0xd7, 0x7c, 0x00, 0x94, 0xee, +0xda, 0x3a, 0x63, 0xee, 0x93, 0xe3, 0x21, 0x45, +0x7c, 0x15, 0x9a, 0xd2, 0xee, 0x6b, 0xd8, 0x7f, +0x18, 0xc0, 0xe1, 0x81, 0xf6, 0x55, 0x24, 0xd6, +0xbd, 0x0b, 0xae, 0x30, 0xcb, 0xae, 0xbc, 0x91, +0xc5, 0x00, 0x32, 0xe3, 0x5b, 0xb9, 0xa2, 0x68, +0x48, 0xb5, 0x10, 0xba, 0xef, 0xe0, 0xaa, 0xbf, +0x3e, 0xb4, 0xfb, 0xf5, 0x47, 0x9e, 0x6c, 0xde, +0xb9, 0xfa, 0x63, 0x00, 0x9f, 0x03, 0xf8, 0xc4, +0x91, 0x53, 0x30, 0x82, 0x20, 0x15, 0x12, 0x49, +0x65, 0x16, 0xbb, 0xfb, 0x46, 0x4d, 0x55, 0x6a, +0xc0, 0xac, 0x00, 0x80, 0x2d, 0x2d, 0x7b, 0x6a, +0x56, 0xe9, 0xe4, 0x99, 0xe8, 0xc3, 0x10, 0x44, +0x44, 0x51, 0x49, 0x6d, 0xda, 0xb1, 0x6a, 0x65, +0xa0, 0xa5, 0xfa, 0x19, 0xa1, 0x69, 0x1e, 0xa1, +0xab, 0x1d, 0x81, 0xb6, 0xfa, 0xaf, 0x2a, 0x3f, +0x7a, 0xe1, 0x90, 0xea, 0x6d, 0x1d, 0x15, 0xed, +0x9f, 0xae, 0xf8, 0x71, 0x0c, 0xf2, 0x85, 0xac, +0x5f, 0x69, 0x96, 0xd5, 0xce, 0xc3, 0xdf, 0xc2, +0x88, 0x29, 0xec, 0xd3, 0x7e, 0x84, 0xde, 0x20, +0xb1, 0x91, 0x3c, 0x8c, 0x0a, 0xf3, 0x36, 0xdb, +0x33, 0xf2, 0x8a, 0x01, 0x64, 0xc2, 0x58, 0xdc, +0xe9, 0x5b, 0x73, 0xac, 0x57, 0x98, 0xcb, 0xde, +0x61, 0x4f, 0xcb, 0xd6, 0xf6, 0x7d, 0x9b, 0xab, +0x00, 0xac, 0x02, 0xd0, 0x61, 0xaa, 0xf2, 0x99, +0xff, 0xba, 0xe0, 0x2e, 0x3f, 0xe0, 0xb2, 0x3a, +0xdc, 0x67, 0x87, 0x3a, 0x5a, 0x77, 0x55, 0xbe, +0xfd, 0xf8, 0xba, 0x29, 0xb7, 0xfc, 0x6e, 0xa6, +0x64, 0x73, 0xcc, 0x04, 0x00, 0x47, 0xee, 0x88, +0xa9, 0x38, 0x54, 0xf1, 0x31, 0x22, 0x8b, 0x2a, +0xbd, 0xf8, 0xf5, 0xe8, 0xbd, 0x53, 0x7c, 0xed, +0xfe, 0xca, 0x8f, 0x96, 0xbd, 0x06, 0xe0, 0x75, +0x5b, 0x5a, 0xce, 0x4c, 0xc5, 0xd7, 0xae, 0x00, +0xa8, 0x4b, 0x1b, 0x39, 0x36, 0x1a, 0xf4, 0xa9, +0x87, 0xc3, 0x87, 0x71, 0x0c, 0xf2, 0x99, 0x8d, +0xe9, 0x20, 0x00, 0x78, 0x6b, 0x77, 0xaf, 0x83, +0xe1, 0xe3, 0x1f, 0x70, 0x5f, 0x45, 0x62, 0xd5, +0xbe, 0x10, 0x15, 0x24, 0x1b, 0xca, 0xc6, 0xea, +0x4c, 0x2f, 0x06, 0x90, 0x11, 0x4f, 0x7b, 0x12, +0x51, 0xd4, 0x93, 0x27, 0xc9, 0xb2, 0x03, 0x40, +0x23, 0x62, 0x88, 0x07, 0x80, 0xaf, 0xff, 0xf2, +0xb0, 0x97, 0x88, 0x6e, 0x84, 0xb1, 0xae, 0x50, +0x08, 0xa0, 0x99, 0xac, 0xf6, 0xdd, 0x00, 0x0c, +0xf2, 0x33, 0xf3, 0xf2, 0x01, 0xa4, 0x13, 0x51, +0xb0, 0x97, 0x6a, 0xb6, 0x1e, 0x91, 0x8d, 0x1f, +0xae, 0xbc, 0x91, 0x59, 0x81, 0xd6, 0x5a, 0x05, +0x40, 0xad, 0xe2, 0x6b, 0x7f, 0x03, 0x46, 0xe0, +0xa7, 0x46, 0x24, 0x9d, 0x6f, 0x9e, 0xac, 0x85, +0x3b, 0x5b, 0x61, 0x48, 0xf3, 0x11, 0xbf, 0x31, +0x7d, 0xfe, 0xd2, 0x89, 0x12, 0x30, 0x15, 0x30, +0x9c, 0x3b, 0xf5, 0x5b, 0x3e, 0xd9, 0x06, 0xa0, +0xa6, 0x17, 0xfd, 0xe8, 0x33, 0x12, 0xaa, 0xf6, +0x9d, 0x42, 0xdb, 0x85, 0xc8, 0xc5, 0x5b, 0xec, +0x6e, 0x53, 0xf2, 0xfb, 0xac, 0xf6, 0x45, 0x0c, +0xf9, 0x64, 0xb1, 0xd8, 0x61, 0xdc, 0xf4, 0x7f, +0x22, 0x90, 0x99, 0xc3, 0x00, 0x36, 0x03, 0xf8, +0x00, 0xc0, 0x46, 0x62, 0x1c, 0x34, 0x3f, 0xb3, +0xba, 0xb3, 0x87, 0xe1, 0x38, 0x56, 0xf8, 0xb1, +0xc0, 0x8c, 0x7a, 0xb3, 0x6c, 0x4f, 0xcb, 0xcb, +0x06, 0xe0, 0x88, 0x84, 0x78, 0x09, 0x66, 0x56, +0x99, 0x99, 0x21, 0x49, 0x45, 0xe6, 0x39, 0xaa, +0xbf, 0xb3, 0x0d, 0xdd, 0x68, 0x17, 0x62, 0x8e, +0x4a, 0x7d, 0xf0, 0x70, 0xd3, 0x06, 0x3d, 0xe4, +0xf7, 0x01, 0xe8, 0xb5, 0x0d, 0xd2, 0x17, 0x24, +0x94, 0xfc, 0x2f, 0x9f, 0x7f, 0xa0, 0x13, 0xcc, +0x35, 0x80, 0x61, 0x9d, 0xa7, 0x17, 0x9d, 0x54, +0x16, 0x4f, 0x7b, 0x24, 0x49, 0x5d, 0x37, 0x88, +0x89, 0x60, 0x68, 0xb2, 0x6e, 0x1f, 0xa6, 0x18, +0x62, 0x98, 0xa4, 0x2e, 0xf2, 0x6d, 0xce, 0xf4, +0x3e, 0x91, 0x4f, 0x12, 0xa2, 0x53, 0x15, 0x47, +0x6e, 0xe1, 0x08, 0x00, 0x8e, 0x6e, 0xec, 0x97, +0x91, 0x66, 0x41, 0xed, 0xf4, 0x74, 0x4f, 0x7e, +0x4c, 0x64, 0x93, 0xe7, 0xe0, 0x8e, 0xaf, 0x60, +0x84, 0xac, 0xc7, 0xbd, 0xe6, 0xd1, 0x13, 0x24, +0x7e, 0x8b, 0x36, 0x21, 0x6a, 0xf4, 0x65, 0x16, +0x4d, 0x1c, 0x87, 0x13, 0x6e, 0x76, 0x3c, 0x4e, +0x53, 0x7a, 0xd7, 0xb0, 0x21, 0x74, 0xb5, 0xc7, +0x06, 0x92, 0x8e, 0x2e, 0xf2, 0x25, 0x87, 0x2b, +0x1f, 0x80, 0xab, 0xb7, 0xbf, 0xcd, 0xcc, 0xab, +0xcd, 0xb2, 0x3b, 0xbf, 0x6c, 0x16, 0xba, 0x19, +0xc2, 0x98, 0xbb, 0x8c, 0x36, 0xb2, 0xc8, 0x16, +0x1c, 0x65, 0xc4, 0xcd, 0xb8, 0x6b, 0xe9, 0x4c, +0x44, 0x22, 0x76, 0x84, 0xa6, 0x1c, 0x6e, 0xd8, +0xfa, 0x49, 0x05, 0x12, 0xa4, 0xf2, 0x81, 0xc1, +0xd9, 0x9f, 0x1f, 0x0d, 0x76, 0x4c, 0x2b, 0x2c, +0x9b, 0x04, 0x20, 0xab, 0xef, 0x16, 0x3f, 0x67, +0x46, 0x8b, 0xba, 0x16, 0x84, 0x21, 0x31, 0x27, +0x54, 0x97, 0x12, 0xd3, 0x41, 0xb3, 0x6c, 0xb1, +0x3a, 0x4c, 0xc9, 0xef, 0x55, 0x1f, 0xb4, 0x80, +0xfa, 0x1e, 0x22, 0x92, 0x6c, 0x75, 0x65, 0x8c, +0xcf, 0x1e, 0x33, 0x65, 0xda, 0xd1, 0x6d, 0x10, +0x75, 0xf9, 0xf1, 0x2d, 0xce, 0xf4, 0xf4, 0x7f, +0xfa, 0x5c, 0x74, 0xa9, 0xfc, 0x40, 0x5b, 0xc3, +0x3a, 0xe8, 0x7a, 0x00, 0x40, 0x73, 0xa2, 0x96, +0xa3, 0x13, 0x4f, 0x3e, 0xd3, 0x2a, 0xb3, 0x68, +0xcf, 0xc8, 0x9b, 0x04, 0x60, 0x58, 0xdf, 0x1b, +0x13, 0x51, 0xf2, 0x75, 0x4d, 0x31, 0xb7, 0x5c, +0x9d, 0x10, 0xa3, 0x0f, 0x0f, 0xaf, 0x43, 0xc4, +0xbd, 0x4c, 0xc6, 0x9e, 0xbc, 0x5e, 0xab, 0xfd, +0xed, 0x2f, 0xdf, 0xe7, 0x67, 0x16, 0xef, 0x46, +0xaa, 0x94, 0x7b, 0xd2, 0xac, 0x1f, 0xe0, 0x68, +0x0d, 0x22, 0x84, 0x19, 0x99, 0x03, 0xd9, 0xee, +0xca, 0x04, 0x10, 0x0d, 0xe9, 0x9a, 0x33, 0xe7, +0x35, 0x19, 0xc0, 0x1c, 0xb3, 0xde, 0x5e, 0xb9, +0xf9, 0x2b, 0x18, 0x52, 0x3f, 0xe0, 0x31, 0x87, +0x26, 0x06, 0x41, 0xf2, 0x1d, 0xeb, 0x01, 0x0e, +0x02, 0x80, 0xc5, 0x91, 0x56, 0xe6, 0xcc, 0x2d, +0x1a, 0x8d, 0xbe, 0x1a, 0x7d, 0x44, 0x31, 0x6a, +0xbf, 0xe7, 0xe4, 0xd7, 0x16, 0xd5, 0xda, 0x60, +0x5e, 0xbb, 0x10, 0x21, 0xf4, 0x71, 0xe8, 0x91, +0x88, 0xff, 0x66, 0x96, 0xd3, 0x0b, 0x46, 0x5f, +0x04, 0x9b, 0xad, 0xf4, 0x08, 0x2d, 0x16, 0x23, +0xf9, 0x56, 0xbb, 0x23, 0x03, 0x91, 0xad, 0x69, +0x00, 0xb0, 0x3f, 0xbb, 0xf1, 0x42, 0x44, 0x1c, +0x5e, 0xba, 0x1a, 0x6c, 0x68, 0xa9, 0x58, 0x5d, +0x05, 0xa0, 0x26, 0x91, 0x41, 0x28, 0x09, 0x27, +0x7f, 0xd3, 0x33, 0x73, 0x55, 0x66, 0xfa, 0x0a, +0x00, 0x40, 0xa0, 0x61, 0x13, 0x4e, 0x9b, 0x89, +0x3e, 0x46, 0xac, 0x30, 0x53, 0xba, 0x59, 0x16, +0x6a, 0x54, 0xed, 0x9f, 0x10, 0x8a, 0x5f, 0x8e, +0x6a, 0x1b, 0xa1, 0x2a, 0x1d, 0x3d, 0xfd, 0xde, +0xd1, 0x08, 0xb6, 0x7b, 0x3f, 0x64, 0x16, 0x0d, +0x00, 0x20, 0xd9, 0x1c, 0x85, 0x65, 0x67, 0xcf, +0xb9, 0x19, 0x31, 0xf7, 0x54, 0x30, 0x45, 0x7d, +0x18, 0x92, 0xd5, 0x99, 0x8e, 0x18, 0xc9, 0x87, +0xd4, 0xa5, 0xf2, 0xfd, 0xcd, 0x35, 0x6b, 0x61, +0x04, 0xa0, 0x0c, 0xb8, 0x4b, 0x37, 0x16, 0x83, +0x94, 0x93, 0x47, 0xac, 0x32, 0x4b, 0xee, 0xfc, +0xd1, 0x93, 0x01, 0xe4, 0xf5, 0x65, 0xdc, 0x27, +0xea, 0x32, 0xb2, 0x58, 0x0b, 0x07, 0xd0, 0x43, +0xc9, 0x17, 0x24, 0x45, 0x23, 0x66, 0x84, 0xae, +0x74, 0xa0, 0x8f, 0x2e, 0xe6, 0x8a, 0xe5, 0x0f, +0x2b, 0xcc, 0x78, 0xcc, 0xac, 0x67, 0x15, 0x4f, +0xba, 0x11, 0x40, 0x71, 0xf4, 0x5a, 0x24, 0x8e, +0x4a, 0xbe, 0x64, 0xb5, 0x47, 0xd5, 0x7e, 0xf9, +0xbc, 0x65, 0x2e, 0x30, 0xae, 0x32, 0x3f, 0x6b, +0xfb, 0x66, 0x9d, 0xa9, 0xf2, 0x13, 0x1a, 0x84, +0x32, 0x28, 0xe4, 0x4b, 0x3a, 0x56, 0x99, 0xe5, +0xc8, 0xb8, 0x9f, 0x7f, 0xec, 0xb3, 0x8f, 0x03, +0xea, 0x52, 0xd7, 0x9a, 0x1a, 0x0e, 0xa3, 0x87, +0x12, 0x2c, 0x43, 0x74, 0x91, 0xaf, 0x84, 0x3d, +0x88, 0x6c, 0x0a, 0xed, 0x0b, 0x14, 0x4f, 0xc7, +0x32, 0x33, 0x5e, 0x4f, 0x76, 0xb8, 0x4a, 0x4a, +0xce, 0xbd, 0xe1, 0x56, 0x44, 0x86, 0x31, 0x89, +0xe5, 0x18, 0xc9, 0xb7, 0x66, 0xc0, 0x20, 0x9f, +0x40, 0xa1, 0xf9, 0x88, 0xcc, 0x0e, 0xb4, 0x90, +0x6f, 0x7f, 0xfb, 0xfe, 0x2d, 0xf5, 0x00, 0xaa, +0x13, 0x1d, 0x77, 0x38, 0x28, 0xe4, 0xb3, 0xec, +0xda, 0x60, 0x8e, 0xfb, 0xb2, 0xc3, 0x55, 0x9c, +0x51, 0x3a, 0xf1, 0x64, 0xf4, 0x61, 0xdc, 0x67, +0xd1, 0xa5, 0x46, 0x85, 0x12, 0x0a, 0xa1, 0x87, +0xe4, 0xb3, 0x10, 0xd1, 0x10, 0x72, 0x4d, 0x09, +0x7a, 0x60, 0x48, 0x7e, 0x9f, 0x6e, 0x7c, 0xc5, +0xf2, 0x87, 0x7d, 0x60, 0xb1, 0xc4, 0xac, 0x67, +0x8f, 0x9e, 0x72, 0x3b, 0x9c, 0xce, 0x22, 0x22, +0x22, 0x61, 0x95, 0xa2, 0xfd, 0x21, 0xc3, 0x0f, +0x61, 0x9f, 0x72, 0xf3, 0x7d, 0x4e, 0x00, 0x0f, +0x98, 0xc7, 0x3d, 0x07, 0x76, 0x7e, 0x00, 0x43, +0xdd, 0x27, 0x3c, 0xee, 0x70, 0x50, 0xc8, 0xdf, +0xf4, 0xcc, 0x5c, 0x95, 0x01, 0x73, 0x9e, 0x4c, +0x79, 0x27, 0xcd, 0x9a, 0x8d, 0x3e, 0x18, 0x5d, +0x44, 0x5d, 0xfe, 0x75, 0x92, 0x64, 0x0b, 0x7a, +0x1a, 0x17, 0x28, 0x49, 0xd7, 0x99, 0x45, 0x7f, +0xd3, 0xc1, 0x5d, 0x88, 0x73, 0x11, 0x85, 0x24, +0x75, 0x51, 0x34, 0x5a, 0xd7, 0xee, 0x2e, 0x1e, +0x73, 0xce, 0x0d, 0x3f, 0x05, 0x20, 0x41, 0xe3, +0x2e, 0xdb, 0x42, 0xa8, 0x01, 0x00, 0x64, 0x71, +0x8e, 0xbc, 0x03, 0xa6, 0xa1, 0x17, 0x0e, 0x36, +0x1c, 0xfa, 0xea, 0xb5, 0xb5, 0x30, 0xb6, 0xa4, +0x27, 0x3c, 0xee, 0x70, 0xf0, 0xf2, 0xf0, 0x09, +0xac, 0x30, 0x8b, 0x69, 0xc3, 0x4a, 0xce, 0x40, +0xcf, 0xa2, 0x5b, 0x8f, 0x46, 0x34, 0x9b, 0x85, +0x33, 0x67, 0x78, 0x19, 0x80, 0x13, 0x6e, 0x6e, +0x9c, 0x71, 0xf7, 0xa2, 0xb1, 0x00, 0xa6, 0x01, +0xa6, 0x2f, 0xfd, 0xe3, 0xed, 0x88, 0x63, 0x71, +0x09, 0x00, 0x36, 0x3d, 0xf3, 0x60, 0x07, 0x58, +0xfb, 0xbd, 0x59, 0xcf, 0x28, 0x3a, 0xf9, 0x47, +0xb6, 0xdc, 0x11, 0xe3, 0x64, 0x3d, 0x66, 0x78, +0xd1, 0x54, 0xbf, 0xdd, 0x95, 0x4d, 0x44, 0x52, +0x97, 0xd4, 0x1f, 0xda, 0xf1, 0x16, 0x74, 0xbd, +0x03, 0x09, 0xb6, 0xf2, 0x4d, 0x0c, 0x1a, 0xf9, +0xac, 0x05, 0xde, 0x42, 0x24, 0x40, 0xd1, 0xea, +0xce, 0x9a, 0x90, 0x3e, 0x62, 0x6c, 0xef, 0x55, +0x3f, 0xf3, 0x66, 0xb3, 0xe8, 0xc8, 0x2e, 0x9c, +0x82, 0x48, 0xf4, 0xeb, 0xf1, 0x40, 0x9a, 0x1c, +0x75, 0xa7, 0x86, 0x3c, 0x2d, 0x9b, 0xf5, 0x90, +0xdf, 0x8f, 0x7e, 0xd8, 0xc5, 0xdb, 0xae, 0xf9, +0x97, 0xb2, 0xd0, 0x0d, 0xcb, 0xdf, 0x6a, 0xcf, +0x2b, 0x39, 0xe3, 0x8a, 0x5f, 0x68, 0xac, 0x96, +0x99, 0x9f, 0x0b, 0x4d, 0xf1, 0x97, 0x5d, 0x74, +0xf3, 0x25, 0x88, 0x2c, 0x06, 0xe9, 0x4a, 0xa8, +0xa9, 0xe6, 0x8b, 0xd7, 0xbf, 0x84, 0xb1, 0x99, +0x34, 0x61, 0x73, 0xfb, 0x58, 0x0c, 0x1a, 0xf9, +0x5b, 0x5e, 0xf8, 0x65, 0x0b, 0xb3, 0xf8, 0x12, +0x00, 0x40, 0x90, 0x73, 0x27, 0x9c, 0x79, 0x09, +0x62, 0xa7, 0x42, 0x3d, 0x80, 0x1c, 0x0a, 0xae, +0xe9, 0xf2, 0x19, 0xb8, 0x47, 0x95, 0x5d, 0x78, +0xf3, 0xf5, 0x38, 0xce, 0x03, 0x74, 0xc1, 0x82, +0x05, 0x16, 0x10, 0xe6, 0x99, 0x75, 0xcf, 0xa1, +0x8a, 0xb5, 0x30, 0x56, 0xe7, 0xe2, 0xf6, 0xa5, +0x1f, 0x78, 0xf1, 0xe1, 0x10, 0x0b, 0xfe, 0xb5, +0x59, 0x4f, 0x1f, 0x31, 0xf6, 0x06, 0x82, 0x88, +0xfe, 0x56, 0xd8, 0xef, 0xa9, 0x73, 0xe7, 0x97, +0xfe, 0x4b, 0xf4, 0xb7, 0x0f, 0xee, 0x7c, 0x4b, +0x37, 0x66, 0x1a, 0x09, 0x37, 0xf4, 0x4c, 0x0c, +0x6a, 0xfa, 0x55, 0x22, 0xbc, 0x61, 0x96, 0xd3, +0x0b, 0xcb, 0xce, 0x00, 0x30, 0xbc, 0x37, 0xaa, +0x7f, 0xfd, 0x4b, 0xbf, 0x6c, 0x13, 0x42, 0x5f, +0x6c, 0xd6, 0xb3, 0x4a, 0x4e, 0xb9, 0xdd, 0x9e, +0x31, 0x6c, 0xcc, 0xb1, 0xda, 0xf0, 0x35, 0x66, +0x5f, 0x8b, 0xc8, 0x62, 0x8b, 0xae, 0x84, 0x9a, +0xea, 0x37, 0x7c, 0xb0, 0x1d, 0x40, 0x75, 0x9f, +0x2f, 0xe0, 0x28, 0x6c, 0xf5, 0x7e, 0xfd, 0x92, +0xd0, 0xb5, 0xbd, 0x00, 0x20, 0xc9, 0x96, 0x34, +0xc9, 0x62, 0x9f, 0x02, 0x18, 0xf9, 0x86, 0xac, +0x8e, 0xf4, 0x1c, 0x92, 0x2d, 0x79, 0x00, 0xa0, +0xab, 0xa1, 0x96, 0x9a, 0xaf, 0x96, 0xaf, 0x81, +0x21, 0xf5, 0x03, 0x1a, 0x9e, 0x7d, 0x3c, 0x0c, +0x2a, 0xf9, 0x1a, 0xf1, 0x0a, 0x44, 0x0c, 0x1d, +0x6b, 0x5a, 0xf6, 0x29, 0xf6, 0x9c, 0xe1, 0xe3, +0x7a, 0xdb, 0x46, 0x40, 0xd7, 0xfe, 0x1f, 0x0b, +0xbd, 0x15, 0x00, 0x64, 0x9b, 0x3d, 0xbf, 0xe4, +0xdc, 0xeb, 0x7f, 0x89, 0x63, 0xc4, 0x29, 0x30, +0x23, 0x9a, 0x18, 0xa2, 0xb3, 0x6e, 0xdf, 0xc7, +0x80, 0xee, 0x45, 0x3f, 0x26, 0x6e, 0xe0, 0xe5, +0xcb, 0x75, 0x82, 0xb8, 0xf3, 0xe8, 0xe3, 0x8a, +0xaf, 0x6d, 0x9b, 0x3b, 0xaf, 0xf8, 0x22, 0xb3, +0xde, 0xb6, 0x67, 0xfd, 0xcb, 0xba, 0xa2, 0x78, +0x30, 0x80, 0xb9, 0x03, 0x7a, 0x82, 0x41, 0x25, +0x7f, 0xdb, 0xd3, 0xf7, 0xd6, 0x81, 0x79, 0x03, +0x00, 0x10, 0x49, 0xd6, 0x91, 0x33, 0x2e, 0xb9, +0x0a, 0xbd, 0xf4, 0xf6, 0xed, 0x79, 0xfe, 0x81, +0x4e, 0x21, 0xc4, 0xc3, 0x66, 0x3d, 0x63, 0xe4, +0xb8, 0x1f, 0x4d, 0xbe, 0xe9, 0xb7, 0xcf, 0x8d, +0xba, 0xe0, 0xb6, 0x23, 0x12, 0x20, 0x9e, 0x7e, +0xf7, 0xc2, 0x62, 0x00, 0x67, 0x01, 0x00, 0x98, +0xd5, 0xba, 0x0d, 0xef, 0xae, 0x86, 0xb1, 0xa1, +0xb3, 0x5f, 0xc7, 0xdb, 0x2d, 0xcf, 0xdd, 0xbf, +0x52, 0x28, 0xa1, 0x15, 0xb1, 0xc7, 0x64, 0x9b, +0x2b, 0xdf, 0xcc, 0xc1, 0xa7, 0x74, 0xb6, 0x6d, +0xad, 0x59, 0xbb, 0x62, 0x23, 0x80, 0x1d, 0x18, +0x44, 0xa9, 0x07, 0x86, 0x40, 0xd6, 0x6d, 0x06, +0x5e, 0x34, 0xcb, 0xe9, 0x23, 0xc7, 0x5f, 0x8a, +0x58, 0x0f, 0x59, 0x0f, 0x91, 0x55, 0xe5, 0x5b, +0x26, 0x74, 0x75, 0x67, 0xa4, 0x4a, 0xf6, 0xf4, +0xec, 0x5b, 0x72, 0x46, 0x4f, 0xda, 0x36, 0xe5, +0xb6, 0x05, 0xd1, 0xdd, 0x3c, 0x42, 0x93, 0xe7, +0x20, 0x62, 0x0f, 0x84, 0xbc, 0xad, 0x5b, 0x43, +0x9e, 0x26, 0x2f, 0x06, 0x40, 0xf2, 0x98, 0x99, +0x41, 0xf8, 0x69, 0x64, 0x4b, 0x1a, 0x00, 0xc0, +0xe2, 0x70, 0x97, 0x01, 0x86, 0xfa, 0xaf, 0xf9, +0x72, 0xc5, 0x9f, 0x61, 0xd8, 0x19, 0x75, 0x83, +0x29, 0xf5, 0xc0, 0x10, 0x20, 0x9f, 0xe0, 0xf9, +0x9f, 0xd8, 0x39, 0x72, 0xd1, 0xcc, 0x2b, 0xae, +0x41, 0x2f, 0xad, 0xfe, 0x95, 0x2b, 0x1f, 0xd6, +0x82, 0x6d, 0x6d, 0x17, 0x08, 0x2d, 0x14, 0x1d, +0xbf, 0xc9, 0x6a, 0x3b, 0xc9, 0x66, 0xcf, 0xda, +0x39, 0x7d, 0xee, 0xa2, 0x2f, 0x67, 0xcc, 0x5b, +0xfc, 0x08, 0x88, 0xa2, 0xfb, 0xe6, 0xbd, 0xd5, +0xbb, 0xbe, 0x84, 0x11, 0xf2, 0x15, 0xd7, 0xa6, +0x8d, 0x63, 0x61, 0xcb, 0xf3, 0x0f, 0xd4, 0xb3, +0xa2, 0x3c, 0x70, 0xf4, 0x71, 0x5f, 0x7d, 0xe5, +0xdb, 0x9e, 0xea, 0x8a, 0x7a, 0x00, 0xdb, 0x13, +0x91, 0x31, 0xe4, 0x44, 0x18, 0xf4, 0xf4, 0xab, +0x00, 0x30, 0x63, 0xee, 0xc2, 0x47, 0x48, 0xb2, +0x3c, 0x00, 0x00, 0xe1, 0x8e, 0xd6, 0x8d, 0x15, +0x7f, 0xff, 0xdd, 0xe5, 0xe8, 0xe5, 0x58, 0x7c, +0xda, 0x9d, 0x4b, 0x7e, 0xc2, 0x4c, 0x4b, 0x7b, +0x72, 0xae, 0xae, 0xab, 0x1e, 0x12, 0xfc, 0x8d, +0x6c, 0xb5, 0x2c, 0xda, 0xf4, 0xcc, 0xbd, 0x6f, +0xf4, 0xb7, 0x04, 0x96, 0xcf, 0x5b, 0x66, 0x25, +0x0a, 0x3e, 0xca, 0xa0, 0x7b, 0xcc, 0x63, 0x0c, +0xa1, 0x1d, 0xde, 0xb7, 0xf5, 0x45, 0xd6, 0xd5, +0x95, 0xb9, 0x23, 0x4e, 0xfa, 0x54, 0x76, 0xe7, +0xa6, 0xab, 0xb2, 0x5e, 0x4c, 0x40, 0x09, 0x09, +0x2e, 0x86, 0x24, 0x15, 0x91, 0xe1, 0xe8, 0x52, +0x15, 0x5d, 0xf9, 0xc3, 0xf6, 0x67, 0xef, 0x3b, +0xd0, 0x9f, 0x7d, 0xea, 0x0e, 0x43, 0x82, 0xfc, +0xa9, 0x77, 0x3c, 0x5a, 0x64, 0x95, 0x1c, 0x07, +0x41, 0x90, 0x19, 0x2c, 0x0e, 0xae, 0xfa, 0xdb, +0xf5, 0xed, 0xdf, 0xae, 0x5f, 0xd1, 0x53, 0xe9, +0x98, 0x71, 0xe7, 0xe3, 0x57, 0x11, 0xe3, 0x75, +0x44, 0x34, 0x99, 0xe2, 0x6d, 0xdd, 0xcc, 0x24, +0xc9, 0xf6, 0xb4, 0x9c, 0x53, 0x8e, 0xc8, 0x77, +0xdb, 0x0d, 0xb4, 0x50, 0xe7, 0x8b, 0xdb, 0x5f, +0xfa, 0xf5, 0x8f, 0xfb, 0x4b, 0x12, 0x2f, 0xb8, +0xed, 0xcf, 0x0e, 0x9f, 0xdd, 0xfb, 0x26, 0x03, +0xdf, 0xeb, 0x6b, 0x1b, 0xac, 0x69, 0x35, 0xad, +0x87, 0x76, 0x9d, 0x5f, 0xfd, 0xd9, 0x0b, 0x07, +0x06, 0x72, 0x68, 0x18, 0x74, 0xb5, 0x0f, 0x18, +0xf9, 0x68, 0x84, 0xd0, 0xdf, 0x04, 0x8c, 0x6c, +0x56, 0xf9, 0x13, 0x67, 0xdd, 0x8c, 0x1e, 0x06, +0x58, 0x9c, 0x3e, 0xf7, 0xf1, 0x33, 0x89, 0xf1, +0x0a, 0x22, 0xd7, 0xa2, 0xfa, 0x3c, 0xbb, 0xbe, +0x79, 0xe3, 0x8f, 0x8b, 0x2b, 0x5e, 0x59, 0xf0, +0xb3, 0xdd, 0x6f, 0xfe, 0xf1, 0xf2, 0xe6, 0x6f, +0xd6, 0x3c, 0x16, 0xea, 0x68, 0x3e, 0x66, 0x8a, +0x73, 0x8b, 0x23, 0xfd, 0xb6, 0x31, 0x17, 0xff, +0xf8, 0x27, 0xbd, 0x48, 0x9d, 0x72, 0x5c, 0x74, +0xda, 0xbc, 0xf7, 0xc4, 0x12, 0xaf, 0x85, 0x02, +0xb5, 0xac, 0x6b, 0xbd, 0xf2, 0xdb, 0x93, 0xc5, +0x52, 0x2c, 0x43, 0xbf, 0x13, 0x31, 0xeb, 0xff, +0x03, 0x81, 0xa1, 0xf3, 0xa6, 0x0d, 0xa1, 0x2f, +0x84, 0x2c, 0x5f, 0x0b, 0x00, 0xae, 0x61, 0xa5, +0xdf, 0x2f, 0x2a, 0xbf, 0xf4, 0x62, 0x22, 0x5a, +0x71, 0xbc, 0x27, 0xff, 0x8c, 0xb9, 0x4f, 0x8e, +0x17, 0x12, 0xde, 0x41, 0xe4, 0x26, 0xe9, 0xa1, +0x40, 0xf5, 0xde, 0xf7, 0x9f, 0xf8, 0x6f, 0x5d, +0x09, 0xd5, 0x02, 0x58, 0x17, 0x68, 0xa9, 0xd5, +0xc7, 0x5e, 0x36, 0x23, 0x64, 0xb5, 0xb9, 0x7e, +0x66, 0x7e, 0x47, 0x53, 0x02, 0xb5, 0xf5, 0x1b, +0x3f, 0xfc, 0x53, 0xfe, 0xa4, 0x73, 0x2e, 0x75, +0x64, 0xe5, 0x9f, 0x09, 0x00, 0x69, 0x23, 0xc6, +0xdc, 0x07, 0x60, 0x05, 0x11, 0xc5, 0x6f, 0x84, +0x11, 0x9d, 0x6f, 0xba, 0xe9, 0x3b, 0x6b, 0xf7, +0xbe, 0xb6, 0xf7, 0xfd, 0x27, 0x57, 0xa4, 0x15, +0x8c, 0x41, 0xe1, 0xb4, 0x0b, 0x2f, 0xb4, 0xa7, +0xe7, 0x8c, 0xb5, 0x38, 0xd3, 0x4b, 0x25, 0x9b, +0x63, 0x18, 0x6b, 0x6a, 0xa7, 0xd0, 0xc2, 0x6d, +0x5a, 0x38, 0xd0, 0x2e, 0x59, 0xec, 0x6e, 0x7b, +0x46, 0xee, 0x74, 0x44, 0x6c, 0x1d, 0x06, 0x8b, +0xb6, 0xbd, 0x1b, 0xab, 0x61, 0xec, 0xea, 0x1d, +0xb0, 0xe9, 0xe0, 0x90, 0x21, 0x7f, 0xcb, 0xf3, +0xf7, 0xad, 0x9b, 0x71, 0xc7, 0xc2, 0x35, 0x24, +0x5b, 0xce, 0x21, 0x92, 0xac, 0x79, 0x93, 0xcf, +0x79, 0xec, 0xf0, 0xa1, 0x6f, 0xbe, 0x82, 0x61, +0x98, 0xfd, 0x13, 0x66, 0xde, 0xb1, 0xa4, 0x40, +0x97, 0xe9, 0x23, 0x00, 0xb9, 0x00, 0x20, 0x54, +0xa5, 0xad, 0xf2, 0xd3, 0xe7, 0x1f, 0x0d, 0x79, +0x5a, 0xea, 0xf3, 0x4e, 0x3a, 0x6b, 0x73, 0xe9, +0x79, 0xd7, 0x5f, 0x4c, 0xc4, 0x37, 0x30, 0x70, +0x15, 0x22, 0xb9, 0x01, 0xd4, 0x60, 0x67, 0xd5, +0xee, 0x37, 0x1e, 0xf9, 0x9d, 0xea, 0xef, 0x6c, +0x02, 0x4b, 0xaf, 0x96, 0x9c, 0x7d, 0xe5, 0x3e, +0x80, 0x60, 0xb1, 0xb9, 0x8a, 0x64, 0x57, 0xfa, +0x34, 0x3d, 0xd0, 0x59, 0x8f, 0x38, 0x17, 0x58, +0x08, 0x3c, 0xc9, 0x6c, 0xa0, 0x71, 0xeb, 0xa7, +0xab, 0x00, 0x54, 0xf8, 0x9a, 0xaa, 0x76, 0x57, +0x7e, 0x54, 0xf5, 0x0e, 0x8c, 0xed, 0xe4, 0xd9, +0x30, 0x42, 0xd6, 0xdd, 0x59, 0x25, 0x93, 0xd2, +0x47, 0xce, 0xba, 0xfc, 0x0a, 0x5b, 0x46, 0xce, +0xd9, 0x30, 0x8d, 0x5c, 0x06, 0x1f, 0xae, 0xda, +0xf2, 0x82, 0xb7, 0xfa, 0x9b, 0x26, 0xc4, 0x99, +0x91, 0xf4, 0x44, 0x18, 0x32, 0xe4, 0x03, 0x80, +0x06, 0x71, 0xab, 0x45, 0x88, 0x0a, 0x92, 0x24, +0x97, 0x6c, 0x77, 0x95, 0x95, 0x9e, 0x77, 0xed, +0x52, 0x22, 0xba, 0xe9, 0xe8, 0x9d, 0xb4, 0x53, +0x6f, 0x79, 0xcc, 0x6d, 0x75, 0xd9, 0xde, 0x47, +0x24, 0xfd, 0x1a, 0x0b, 0x3d, 0x50, 0xb3, 0xe6, +0xd5, 0x47, 0xd2, 0x86, 0x8f, 0x76, 0x8e, 0xbf, +0x74, 0xfe, 0xf5, 0x24, 0x5b, 0x5f, 0x01, 0x38, +0x27, 0xf6, 0xae, 0xe9, 0x4a, 0xb8, 0xb9, 0xf2, +0xa3, 0xe7, 0xfe, 0xa8, 0xfa, 0x3b, 0xeb, 0x00, +0x7c, 0x51, 0x76, 0xfa, 0x0f, 0x0b, 0x84, 0x39, +0xa9, 0x20, 0x90, 0x33, 0xb3, 0x70, 0x84, 0x2f, +0xd0, 0x29, 0x23, 0x8e, 0x79, 0xff, 0xcc, 0x7f, +0x5f, 0x9a, 0xc1, 0x66, 0xbe, 0x00, 0x80, 0x33, +0x4a, 0x4e, 0x2e, 0x19, 0x71, 0xd6, 0xe5, 0xe9, +0xe9, 0xee, 0xfc, 0x61, 0xba, 0xcb, 0x92, 0xc6, +0x2a, 0x86, 0x03, 0x18, 0x2e, 0x11, 0x4d, 0x04, +0x49, 0x97, 0x21, 0xb2, 0xc0, 0x64, 0x82, 0x85, +0x50, 0xda, 0xf6, 0x6e, 0x78, 0xee, 0xd0, 0xea, +0xbf, 0xad, 0x06, 0xb0, 0x05, 0x46, 0x8a, 0x99, +0x01, 0xc3, 0x90, 0x22, 0x7f, 0xfb, 0xb3, 0xf7, +0x1d, 0x98, 0x7a, 0xeb, 0xef, 0x7f, 0x66, 0x75, +0xa6, 0x3d, 0x0b, 0x00, 0xce, 0x9c, 0xe2, 0x6b, +0x46, 0xcd, 0xfe, 0xd7, 0x5b, 0x89, 0xe8, 0x05, +0xd3, 0x20, 0x8b, 0x10, 0xff, 0x26, 0x80, 0x19, +0x00, 0x00, 0x66, 0xd5, 0x5b, 0xbb, 0xe7, 0xad, +0xa2, 0x73, 0xae, 0xbb, 0x47, 0xb6, 0x3a, 0x46, +0x74, 0xd7, 0xae, 0x16, 0xf4, 0x55, 0x1e, 0xfa, +0xf2, 0xd5, 0x27, 0x03, 0xcd, 0x07, 0x6b, 0x01, +0xac, 0x9b, 0x31, 0x77, 0x49, 0xa1, 0x20, 0x7c, +0x72, 0xe4, 0x59, 0x02, 0x30, 0x1c, 0x4c, 0x7d, +0xde, 0xb2, 0x2d, 0x42, 0xfa, 0x68, 0x48, 0x86, +0xe9, 0x40, 0x00, 0x15, 0x4c, 0x9d, 0xfd, 0x20, +0x80, 0x07, 0x05, 0x00, 0xd2, 0x71, 0xac, 0xb7, +0x00, 0x00, 0x00, 0x42, 0x1d, 0x2d, 0x1b, 0x6a, +0xd6, 0xae, 0xf8, 0x8b, 0xb7, 0xfa, 0x9b, 0x7a, +0x18, 0xc4, 0x1f, 0x1c, 0x68, 0x3f, 0xc0, 0x90, +0x22, 0x1f, 0x00, 0x76, 0xbc, 0xfc, 0xd0, 0xf3, +0xa7, 0xde, 0xf6, 0xc8, 0x15, 0xb2, 0xcd, 0x71, +0x19, 0x08, 0x94, 0x3d, 0x66, 0xfa, 0x12, 0x77, +0x7e, 0xa9, 0x6b, 0xdc, 0xa5, 0xff, 0xfe, 0x4c, +0x7a, 0xc9, 0xb8, 0x31, 0x36, 0x97, 0xf5, 0x25, +0x8e, 0x66, 0xd5, 0x06, 0x1f, 0xde, 0xbf, 0xfd, +0x2f, 0x59, 0xa3, 0xa7, 0xdc, 0x74, 0xf4, 0x1b, +0x37, 0xf4, 0x70, 0xa0, 0xce, 0xdf, 0x5a, 0xbb, +0xae, 0x6d, 0xcf, 0xda, 0x75, 0x91, 0x0c, 0x5d, +0x6d, 0x00, 0x36, 0x4e, 0xff, 0xf1, 0xa2, 0x12, +0x18, 0xc4, 0x17, 0x1d, 0xfd, 0xdb, 0xf1, 0x42, +0x10, 0xca, 0x7a, 0x73, 0x3e, 0xb3, 0x08, 0x2b, +0xde, 0xc3, 0xbb, 0xda, 0x2a, 0x37, 0x7e, 0xd8, +0xb0, 0xe9, 0xc3, 0x9d, 0x30, 0xf2, 0x12, 0xee, +0x00, 0xe0, 0x4b, 0x84, 0x03, 0x68, 0xc8, 0x91, +0xcf, 0xcc, 0x3c, 0x79, 0xce, 0x82, 0x5b, 0x29, +0xd3, 0xb2, 0x5b, 0x92, 0x2d, 0xf9, 0x24, 0xc9, +0x2e, 0x7b, 0x66, 0xfe, 0x12, 0x7b, 0x66, 0xfe, +0x42, 0x80, 0x65, 0xee, 0xf2, 0xff, 0xb0, 0xe7, +0xc0, 0xb6, 0x97, 0x15, 0x9f, 0xa7, 0x39, 0x96, +0x78, 0x5d, 0x0d, 0x36, 0xb4, 0xec, 0x58, 0xf3, +0x62, 0xdd, 0xa6, 0xf7, 0x77, 0xc0, 0x78, 0x99, +0x42, 0x0d, 0x90, 0x55, 0x3b, 0xed, 0x8e, 0xdf, +0x4c, 0x95, 0x64, 0xf9, 0x31, 0x30, 0xae, 0x07, +0x60, 0x04, 0x7e, 0x32, 0x18, 0x14, 0x69, 0x50, +0x92, 0xe2, 0x4e, 0x16, 0xc1, 0xa0, 0x51, 0xd1, +0xd4, 0x2a, 0x21, 0xdf, 0x01, 0x5d, 0x09, 0xb7, +0xcb, 0x36, 0x7b, 0x36, 0x59, 0x6c, 0x59, 0xd0, +0xf5, 0xb0, 0xae, 0x2b, 0x1e, 0x56, 0x15, 0x8f, +0x16, 0xf2, 0xb7, 0xf9, 0xea, 0xf7, 0xef, 0x6a, +0xda, 0xb1, 0x72, 0x97, 0x1a, 0xf2, 0x06, 0x61, +0xe4, 0x11, 0xaa, 0x84, 0xe1, 0xdb, 0x48, 0x98, +0xf3, 0x67, 0xc8, 0x91, 0x0f, 0x18, 0xa9, 0xcc, +0x26, 0xdf, 0xf0, 0x9b, 0x8b, 0xad, 0xae, 0xb4, +0x77, 0x64, 0x9b, 0xc3, 0xdc, 0x83, 0x7f, 0xc4, +0xfb, 0x69, 0xda, 0xf6, 0xad, 0x5f, 0x76, 0x70, +0xe5, 0x2b, 0xab, 0x32, 0x4b, 0x26, 0x54, 0x15, +0x4c, 0x39, 0xef, 0x5e, 0x10, 0xd9, 0x00, 0x40, +0xb6, 0x3a, 0x87, 0x17, 0xce, 0xb8, 0xf8, 0x57, +0x05, 0xd3, 0x2f, 0x6a, 0x06, 0x49, 0xad, 0x11, +0xc7, 0x49, 0x26, 0x80, 0x9c, 0x58, 0x53, 0x8e, +0x75, 0xcd, 0xcf, 0x2c, 0x14, 0xc9, 0x62, 0xcb, +0xee, 0xaf, 0x7e, 0x13, 0x51, 0x34, 0xd7, 0x6e, +0x67, 0x7d, 0xd5, 0xea, 0xfd, 0x9f, 0xbe, 0xf0, +0x2a, 0x8c, 0x8d, 0x1d, 0x8e, 0xc8, 0x9f, 0x06, +0x23, 0x64, 0x2c, 0x14, 0x39, 0xde, 0x02, 0x23, +0x90, 0x44, 0x03, 0x7a, 0xfe, 0x62, 0x89, 0xfe, +0xc2, 0x90, 0x24, 0x1f, 0x00, 0x2a, 0xfe, 0xfe, +0x5f, 0xdb, 0xf3, 0x27, 0x9f, 0x7e, 0x46, 0xde, +0x49, 0xe7, 0x2d, 0xb2, 0x67, 0xe6, 0x9d, 0x2d, +0xdb, 0x9c, 0x23, 0x59, 0xe8, 0xa1, 0xb0, 0xb7, +0x75, 0x6b, 0xcb, 0x9e, 0x75, 0x1f, 0x35, 0x6f, +0x5f, 0xb9, 0x07, 0xc0, 0xe6, 0x8e, 0xea, 0x3d, +0x07, 0x75, 0x25, 0x70, 0x95, 0x64, 0xb1, 0x2f, +0x8f, 0xcd, 0xce, 0x41, 0x46, 0x84, 0x6e, 0xb7, +0x81, 0xa1, 0x5a, 0xc8, 0x7f, 0xb0, 0xf6, 0xeb, +0x77, 0x9e, 0x2e, 0x39, 0xeb, 0xea, 0x7b, 0xbb, +0x8e, 0x72, 0x7f, 0xe4, 0xb9, 0x2d, 0x33, 0x0b, +0x4a, 0x67, 0x7b, 0x33, 0x8c, 0x8c, 0xe2, 0xfb, +0xba, 0x39, 0x2f, 0x4a, 0xf2, 0x60, 0xfa, 0xf7, +0x87, 0x2c, 0xf9, 0x00, 0xd0, 0x5c, 0xb1, 0xa1, +0x91, 0x88, 0x6e, 0x05, 0x30, 0xc1, 0xe6, 0xca, +0x1a, 0xa5, 0x87, 0x03, 0x2e, 0x5d, 0x57, 0xc2, +0x30, 0x72, 0xed, 0x55, 0x02, 0x68, 0x65, 0x66, +0x26, 0xa2, 0x0f, 0x73, 0x27, 0x9f, 0x7b, 0x5a, +0x76, 0xd1, 0x84, 0x9f, 0xbb, 0x86, 0x15, 0x9d, +0x6d, 0x71, 0xa4, 0x95, 0x90, 0x24, 0x1f, 0xb1, +0x7b, 0x46, 0x68, 0xaa, 0x27, 0xd0, 0x56, 0xbf, +0xb6, 0x7d, 0xdf, 0x86, 0x35, 0x2d, 0xbb, 0xbe, +0x3c, 0x00, 0xe0, 0x70, 0xd9, 0xb9, 0x37, 0x44, +0x63, 0xf7, 0xe4, 0x13, 0x47, 0x80, 0xf5, 0x04, +0x65, 0x66, 0x21, 0xd4, 0x56, 0xd7, 0x02, 0xc3, +0x5a, 0xe7, 0xc1, 0x5e, 0xc0, 0x39, 0x16, 0x86, +0x34, 0xf9, 0x00, 0xc0, 0xcc, 0x0a, 0x11, 0xed, +0x54, 0x02, 0x9e, 0x0a, 0x18, 0xaa, 0x5f, 0x00, +0x10, 0xb1, 0x37, 0x34, 0xf2, 0x00, 0xec, 0x69, +0xab, 0xf8, 0xe2, 0xa7, 0x30, 0xde, 0x74, 0x59, +0x94, 0x3e, 0x62, 0x6c, 0xa9, 0x6c, 0x77, 0xb8, +0xf5, 0x80, 0x3f, 0x1c, 0x0a, 0x78, 0xc3, 0x6a, +0x67, 0x9b, 0xa9, 0x6e, 0xab, 0x23, 0x7f, 0x87, +0x41, 0x92, 0x7e, 0xd4, 0xb4, 0x3e, 0x5e, 0xe9, +0x2f, 0x33, 0x0b, 0x1d, 0xf5, 0xfb, 0x5a, 0x10, +0xe7, 0x0b, 0x24, 0x06, 0x1a, 0x43, 0x9e, 0x7c, +0xe0, 0x88, 0x77, 0xdc, 0x1c, 0xef, 0xdd, 0x35, +0x0c, 0x20, 0x44, 0x44, 0x7b, 0x01, 0xec, 0xeb, +0xac, 0xaf, 0x04, 0x8c, 0x71, 0x56, 0x86, 0xb1, +0x6e, 0xae, 0x45, 0xfe, 0xa2, 0x92, 0x58, 0x3e, +0xff, 0xf1, 0xae, 0x07, 0x48, 0x8a, 0x4f, 0xed, +0x4f, 0xbb, 0x6d, 0x71, 0x96, 0x6c, 0x97, 0x32, +0x01, 0x80, 0x85, 0xe6, 0x55, 0xfd, 0x1e, 0x73, +0x5c, 0x1f, 0xb2, 0xf8, 0x4e, 0x90, 0xdf, 0x1b, +0xc4, 0x3c, 0x28, 0xc0, 0x89, 0x6f, 0x7e, 0x8c, +0x54, 0xca, 0x71, 0x91, 0x6f, 0xb5, 0xa2, 0xcc, +0x7c, 0x32, 0x35, 0x25, 0xd4, 0x02, 0x63, 0xb9, +0x38, 0x21, 0xfb, 0xec, 0xfb, 0x8a, 0x21, 0xb1, +0xb0, 0xf3, 0xbf, 0x01, 0xb1, 0x73, 0x7c, 0x3d, +0x1c, 0x6c, 0x85, 0x91, 0x44, 0x71, 0x48, 0x23, +0xd9, 0xc9, 0xef, 0x92, 0x7c, 0x29, 0xbe, 0x5b, +0xc1, 0xa0, 0x68, 0xe6, 0x2d, 0x3d, 0xd4, 0xd9, +0x02, 0x43, 0xeb, 0x0c, 0xd9, 0xf1, 0x1e, 0x48, +0x76, 0xf2, 0xb9, 0xcb, 0x86, 0x90, 0x48, 0x3e, +0x66, 0x4a, 0x97, 0x9e, 0x20, 0x76, 0x8e, 0xaf, +0xf8, 0xbc, 0xcd, 0x48, 0x49, 0xfe, 0x50, 0x07, +0x47, 0x57, 0x0c, 0x1d, 0x59, 0xf9, 0x59, 0x88, +0xcf, 0xda, 0x2f, 0x33, 0x0b, 0x8a, 0xb7, 0xbd, +0x05, 0x29, 0xf2, 0x87, 0x3a, 0x38, 0x1a, 0xf3, +0x67, 0xcf, 0xc8, 0xcb, 0x43, 0x7c, 0xc1, 0x13, +0x65, 0x66, 0x21, 0xe0, 0xa9, 0x35, 0xd5, 0xfe, +0x90, 0x46, 0x72, 0x93, 0x4f, 0x74, 0xc8, 0x2c, +0xda, 0xdc, 0x59, 0x79, 0x00, 0x5c, 0x71, 0x64, +0x04, 0x2d, 0x33, 0x0b, 0x9d, 0x75, 0x55, 0xad, +0x18, 0xe2, 0x73, 0x7c, 0x20, 0xd9, 0xc9, 0x8f, +0xa4, 0x85, 0x03, 0x00, 0x8b, 0x3b, 0x3d, 0x17, +0x7d, 0xc8, 0xca, 0x05, 0x18, 0x2f, 0x8b, 0x84, +0xb1, 0x7e, 0x00, 0xd6, 0xd4, 0xef, 0xc4, 0x1c, +0x1f, 0x48, 0x72, 0xf2, 0x49, 0x74, 0x49, 0xbe, +0xc5, 0xe6, 0xcc, 0x43, 0x1f, 0xc9, 0xb7, 0x0b, +0x75, 0x96, 0x59, 0xd6, 0x94, 0x60, 0x03, 0xbe, +0x03, 0x73, 0x7c, 0x20, 0xc9, 0xc9, 0x87, 0xe8, +0xda, 0xa7, 0x27, 0xd9, 0x1c, 0x7d, 0x26, 0x9f, +0x89, 0x2f, 0x31, 0xcb, 0x21, 0x4f, 0xd3, 0x2e, +0x0c, 0xf2, 0x0b, 0x9e, 0x7a, 0x8a, 0xa4, 0x26, +0xdf, 0x9a, 0x29, 0xa2, 0xe4, 0xcb, 0x56, 0x87, +0xa9, 0xf6, 0x7b, 0x35, 0xe6, 0x13, 0x81, 0xc0, +0xf4, 0x7d, 0xb3, 0xee, 0xad, 0xde, 0x6d, 0xee, +0xf7, 0x1f, 0xd2, 0xe3, 0x3d, 0x90, 0xe4, 0xe4, +0xaf, 0x5d, 0x78, 0x6f, 0x10, 0x91, 0x00, 0x51, +0x92, 0x64, 0x57, 0xc1, 0xb4, 0x8b, 0x4e, 0xed, +0x6d, 0x1b, 0xe5, 0xf3, 0x96, 0xfc, 0x1b, 0x80, +0x71, 0x80, 0x11, 0x23, 0xd0, 0x52, 0xb1, 0xa6, +0x12, 0x09, 0xca, 0x9d, 0x1b, 0x2f, 0x92, 0x9a, +0x7c, 0x03, 0x1c, 0xdd, 0x54, 0x39, 0x6c, 0xe2, +0x59, 0xd7, 0x03, 0xc8, 0xeb, 0xe9, 0x37, 0xa7, +0xff, 0xf4, 0x89, 0x11, 0x0c, 0x7a, 0xc4, 0xac, +0xfb, 0x1a, 0xf6, 0x7f, 0xa0, 0x1b, 0xf9, 0x00, +0x07, 0xfc, 0x15, 0x29, 0xfd, 0x81, 0x14, 0xf9, +0xac, 0x2c, 0x64, 0x18, 0xa1, 0x53, 0xf6, 0xb4, +0x9c, 0x53, 0x4f, 0xbe, 0xfa, 0xbe, 0xdf, 0xf7, +0x64, 0x03, 0x47, 0xf9, 0xbc, 0xc5, 0x57, 0x4a, +0xaa, 0xd8, 0x8e, 0x48, 0xe8, 0xb8, 0x1e, 0x0e, +0xd6, 0x55, 0x7d, 0xfa, 0xfc, 0x3b, 0x30, 0x82, +0x37, 0x06, 0x75, 0xf7, 0x6d, 0x4f, 0x31, 0x24, +0xb6, 0x6b, 0x0d, 0x36, 0xa6, 0xdf, 0xfe, 0xc7, +0xc7, 0x24, 0xab, 0xfd, 0x17, 0x91, 0x2a, 0x2b, +0xfe, 0x8e, 0xd7, 0x6c, 0x92, 0xed, 0xfe, 0x4d, +0x2f, 0x3d, 0x78, 0x44, 0xe2, 0x86, 0xf2, 0x79, +0x8b, 0x87, 0x83, 0xa4, 0x2b, 0x98, 0x70, 0x0d, +0x31, 0x2e, 0xea, 0xfa, 0x84, 0xb5, 0xba, 0xf5, +0xef, 0xfd, 0xdf, 0xc6, 0x6d, 0x9f, 0x6d, 0x00, +0xf0, 0x59, 0x3c, 0x2f, 0x6d, 0x4a, 0x24, 0x52, +0xe4, 0x03, 0xa0, 0x39, 0x73, 0xe4, 0xa9, 0xae, +0xe9, 0xab, 0x2c, 0x0e, 0xd7, 0xd9, 0xd1, 0x83, +0xcc, 0x0a, 0x83, 0x37, 0x13, 0x49, 0x32, 0x8c, +0x90, 0x6e, 0x17, 0x8c, 0xb1, 0xfd, 0x08, 0x83, +0x50, 0x28, 0xa1, 0xc6, 0xba, 0x4d, 0x1f, 0x3c, +0xd5, 0xbc, 0x73, 0xf5, 0x6e, 0x00, 0x5f, 0x30, +0x73, 0x5c, 0xc9, 0x9d, 0x12, 0x89, 0x14, 0xf9, +0x11, 0x4c, 0x9e, 0xb3, 0x20, 0x47, 0x76, 0xca, +0xef, 0x59, 0x9d, 0x19, 0xb3, 0x4e, 0x7c, 0x36, +0x00, 0x66, 0x3d, 0xd0, 0x5a, 0xf3, 0x79, 0xe5, +0xc7, 0xcf, 0xff, 0x55, 0xf5, 0x7b, 0x5a, 0x00, +0x6c, 0x44, 0x24, 0xac, 0x6c, 0x40, 0x3b, 0xda, +0x8f, 0x48, 0x91, 0x1f, 0x03, 0x22, 0x72, 0x14, +0xcf, 0xbc, 0xf2, 0xb6, 0xac, 0xb1, 0xa7, 0xce, +0xb7, 0xb9, 0xb3, 0xa7, 0x1c, 0xfd, 0xb9, 0x11, +0x67, 0xdf, 0xb6, 0xd3, 0xd7, 0xb4, 0x7f, 0x63, +0xe3, 0xd6, 0x7f, 0x6c, 0x0a, 0x79, 0x9a, 0x3a, +0x01, 0xec, 0x07, 0xb0, 0x93, 0x23, 0x2f, 0x6d, +0xfa, 0x2e, 0x21, 0x45, 0xfe, 0x51, 0x88, 0x18, +0x7b, 0x79, 0xd9, 0xe3, 0xcb, 0x67, 0x5b, 0x6c, +0xce, 0x51, 0x1c, 0x0e, 0xa9, 0x9a, 0x1a, 0x56, +0x35, 0x25, 0xa0, 0x06, 0x5b, 0x6b, 0x3b, 0x74, +0x25, 0x14, 0x86, 0x31, 0x3d, 0xac, 0x83, 0x11, +0x48, 0x1a, 0xfe, 0x2e, 0x49, 0x7b, 0x2c, 0x52, +0xe4, 0x1f, 0x03, 0x91, 0x87, 0xc0, 0x0d, 0x63, +0xbc, 0x37, 0x5f, 0xfc, 0xac, 0xc3, 0x70, 0xdd, +0xea, 0xc0, 0xe0, 0x86, 0x5d, 0xf7, 0x07, 0x52, +0xe4, 0x27, 0x31, 0x52, 0xf3, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0x46, 0x8a, 0xfc, 0x24, 0x46, +0x8a, 0xfc, 0x24, 0xc6, 0xff, 0x07, 0x4e, 0xdb, +0x8a, 0xd3, 0x88, 0xea, 0x3d, 0xd2, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *pgAdmin3_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_pgAdmin3_png = new wxImage(); + if (!img_pgAdmin3_png || !img_pgAdmin3_png->IsOk()) + { + wxMemoryInputStream img_pgAdmin3_pngIS(pgAdmin3_png_data, sizeof(pgAdmin3_png_data)); + img_pgAdmin3_png->LoadFile(img_pgAdmin3_pngIS, wxBITMAP_TYPE_PNG); + } + return img_pgAdmin3_png; +} +#define pgAdmin3_png_img pgAdmin3_png_img() + +static wxBitmap *pgAdmin3_png_bmp() +{ + static wxBitmap *bmp_pgAdmin3_png; + if (!bmp_pgAdmin3_png || !bmp_pgAdmin3_png->IsOk()) + bmp_pgAdmin3_png = new wxBitmap(*pgAdmin3_png_img); + return bmp_pgAdmin3_png; +} +#define pgAdmin3_png_bmp pgAdmin3_png_bmp() + +static wxIcon *pgAdmin3_png_ico() +{ + static wxIcon *ico_pgAdmin3_png; + if (!ico_pgAdmin3_png || !ico_pgAdmin3_png->IsOk()) + { + ico_pgAdmin3_png = new wxIcon(); + ico_pgAdmin3_png->CopyFromBitmap(*pgAdmin3_png_bmp); + } + return ico_pgAdmin3_png; +} +#define pgAdmin3_png_ico pgAdmin3_png_ico() + +#endif // PGADMIN3_PNG_H diff --git a/include/images/pgAdmin3.svg b/include/images/pgAdmin3.svg new file mode 100644 index 0000000..770c0da --- /dev/null +++ b/include/images/pgAdmin3.svg @@ -0,0 +1,54 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/include/images/plugins.png b/include/images/plugins.png new file mode 100644 index 0000000..88c15dc Binary files /dev/null and b/include/images/plugins.png differ diff --git a/include/images/plugins.pngc b/include/images/plugins.pngc new file mode 100644 index 0000000..8ebd2f6 --- /dev/null +++ b/include/images/plugins.pngc @@ -0,0 +1,227 @@ +#ifndef PLUGINS_PNG_H +#define PLUGINS_PNG_H + +static const unsigned char plugins_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x03, 0x00, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x93, 0x88, 0x55, 0x67, +0x58, 0x10, 0x82, 0x76, 0x3a, 0xd2, 0xcd, 0xb7, +0xaa, 0xa1, 0x79, 0xad, 0xa4, 0x7b, 0xf0, 0xec, +0xde, 0xc8, 0xc1, 0xa0, 0x6b, 0x5d, 0x16, 0xa6, +0xc2, 0xa5, 0x55, 0x8b, 0x54, 0x9a, 0xba, 0x99, +0xc0, 0xba, 0x9c, 0x9a, 0x8f, 0x5d, 0xf7, 0xf3, +0xe6, 0xe7, 0xe1, 0xcb, 0x66, 0x56, 0x0d, 0xaa, +0xc4, 0xa9, 0x52, 0x8f, 0x54, 0x8f, 0xc1, 0x96, +0x5a, 0x98, 0x5e, 0x6c, 0x9a, 0x6b, 0x7a, 0x6d, +0x2e, 0xda, 0xd3, 0xb9, 0xa8, 0x9c, 0x6c, 0xaf, +0xa8, 0x81, 0xc2, 0xd5, 0xc2, 0x3e, 0x80, 0x3f, +0xbd, 0xe9, 0xc8, 0x77, 0xb1, 0x7d, 0x44, 0x7e, +0x42, 0x80, 0x73, 0x37, 0xa2, 0x99, 0x6d, 0xbf, +0xb8, 0x99, 0xcc, 0xc7, 0xae, 0xdf, 0xdc, 0xcc, +0xbd, 0xb6, 0x96, 0x5e, 0x4e, 0x01, 0xf1, 0xea, +0xd6, 0xb6, 0xab, 0x7e, 0x9e, 0x95, 0x67, 0x3e, +0x7b, 0x3c, 0x96, 0xcc, 0xa0, 0x33, 0x76, 0x33, +0xba, 0xb3, 0x91, 0x9d, 0x93, 0x63, 0x90, 0x84, +0x4e, 0x7d, 0x70, 0x30, 0x9c, 0x91, 0x5d, 0xd9, +0xd0, 0xb3, 0xf0, 0xe9, 0xd2, 0xee, 0xe5, 0xca, +0x98, 0x8b, 0x50, 0x6a, 0x5b, 0x12, 0x78, 0x68, +0x21, 0x10, 0x5b, 0x0e, 0xae, 0xe3, 0xbc, 0x2d, +0x72, 0x2d, 0xfc, 0xfb, 0xf7, 0xfb, 0xf8, 0xf2, +0xf9, 0xf6, 0xec, 0xf5, 0xf0, 0xe0, 0xf3, 0xec, +0xd9, 0xeb, 0xe1, 0xc2, 0xe8, 0xdd, 0xba, 0xe6, +0xd9, 0xb2, 0xe3, 0xd5, 0xa9, 0xe0, 0xd1, 0xa1, +0xa0, 0x8f, 0x4f, 0x1a, 0x60, 0x16, 0x1e, 0x65, +0x1c, 0x29, 0x6e, 0x28, 0x69, 0xa8, 0x70, 0xaa, +0xe3, 0xb9, 0x68, 0xab, 0x70, 0x1b, 0x63, 0x19, +0x40, 0x7c, 0x3e, 0xdd, 0xcc, 0x98, 0xa8, 0x97, +0x57, 0x35, 0x6a, 0x25, 0x9e, 0xc9, 0xa3, 0xc9, +0xed, 0xd2, 0xa1, 0xd0, 0xaa, 0xb3, 0xe1, 0xbd, +0xb7, 0xe7, 0xc3, 0xb0, 0xe5, 0xbe, 0xa3, 0xe1, +0xb3, 0x9d, 0xdf, 0xae, 0x90, 0xd7, 0xa1, 0x76, +0xc1, 0x85, 0x71, 0xbf, 0x80, 0x7f, 0xd3, 0x95, +0xda, 0xc8, 0x90, 0xad, 0x9a, 0x58, 0x45, 0x6e, +0x2c, 0x83, 0xb6, 0x88, 0xc3, 0xeb, 0xce, 0x96, +0xdd, 0xa8, 0x90, 0xda, 0xa3, 0x89, 0xd8, 0x9d, +0x82, 0xd6, 0x98, 0x7c, 0xd4, 0x93, 0xcf, 0xc0, +0x8f, 0x95, 0x85, 0x45, 0x56, 0x50, 0x04, 0x68, +0x58, 0x0d, 0x9a, 0x88, 0x43, 0xab, 0x97, 0x52, +0x7b, 0xb1, 0x81, 0x75, 0xd2, 0x8d, 0x7e, 0x7d, +0x3a, 0x28, 0x67, 0x20, 0x28, 0x6d, 0x27, 0x5f, +0x78, 0x3b, 0x8a, 0x7d, 0x33, 0x24, 0x63, 0x1b, +0xa5, 0xd5, 0xae, 0x76, 0xc5, 0x87, 0x40, 0x8f, +0x48, 0x11, 0x5c, 0x0f, 0x18, 0x65, 0x18, 0x3f, +0x95, 0x4a, 0xb4, 0xa4, 0x6a, 0x31, 0x67, 0x20, +0x84, 0xb3, 0x87, 0xd5, 0xf1, 0xdc, 0xad, 0xd5, +0xb4, 0x5c, 0x97, 0x5f, 0x61, 0x9e, 0x66, 0x3f, +0x8e, 0x47, 0x97, 0xb8, 0x96, 0x64, 0x95, 0x63, +0x82, 0x77, 0x31, 0xcf, 0xef, 0xd7, 0xb7, 0xe4, +0xc1, 0x5c, 0xab, 0x69, 0x62, 0x93, 0x60, 0x91, +0xb4, 0x90, 0x73, 0x6d, 0x25, 0x34, 0x83, 0x3a, +0xb0, 0xc9, 0xb0, 0x8f, 0x7f, 0x39, 0x16, 0x5e, +0x13, 0xc2, 0xe8, 0xcb, 0x98, 0xcd, 0xa1, 0x50, +0x92, 0x54, 0x8d, 0xc9, 0x99, 0x2b, 0x7b, 0x30, +0xbe, 0xd3, 0xbe, 0xd8, 0xc4, 0x87, 0xc1, 0xac, +0x69, 0x39, 0x5e, 0x14, 0x5e, 0x9a, 0x62, 0x84, +0xba, 0x8b, 0x70, 0xac, 0x76, 0x36, 0x7b, 0x37, +0x4e, 0x63, 0x1e, 0x1d, 0x62, 0x19, 0x93, 0xd6, +0xa3, 0x38, 0x8d, 0x42, 0xd5, 0xbf, 0x7e, 0xd2, +0xbb, 0x76, 0x93, 0x81, 0x35, 0x43, 0x5d, 0x14, +0x3f, 0x6e, 0x2b, 0x41, 0x67, 0x22, 0x6c, 0x6d, +0x1c, 0x95, 0x7e, 0x27, 0x39, 0x6d, 0x29, 0x72, +0xba, 0x7e, 0x6f, 0xd0, 0x88, 0x5a, 0xbb, 0x70, +0xcf, 0xb7, 0x6d, 0xcd, 0xb3, 0x65, 0xc0, 0xa6, +0x54, 0x9d, 0x86, 0x33, 0xad, 0x92, 0x3b, 0xc2, +0xa4, 0x46, 0x92, 0x79, 0x22, 0x46, 0x74, 0x34, +0x63, 0xad, 0x6e, 0x68, 0xce, 0x83, 0x62, 0xcc, +0x7d, 0x36, 0x92, 0x42, 0x26, 0x6a, 0x25, 0x70, +0x9d, 0x6e, 0x48, 0x82, 0x47, 0x27, 0x86, 0x33, +0xca, 0xaf, 0x5d, 0xc7, 0xab, 0x55, 0xc5, 0xa7, +0x4d, 0xc0, 0xa0, 0x3f, 0x8a, 0x72, 0x1c, 0x4d, +0x7a, 0x3c, 0x5c, 0xca, 0x78, 0x56, 0xc8, 0x73, +0x4a, 0xbc, 0x66, 0x33, 0x9a, 0x45, 0x3a, 0xa9, +0x51, 0x40, 0xc0, 0x61, 0xbe, 0x9d, 0x39, 0x7d, +0x67, 0x11, 0x58, 0x84, 0x4b, 0x56, 0xa6, 0x62, +0x50, 0xc6, 0x6f, 0x4b, 0xc4, 0x6a, 0x45, 0xc2, +0x66, 0x3b, 0xbf, 0x5d, 0xa1, 0x8f, 0x4b, 0x8e, +0x7b, 0x33, 0x86, 0x73, 0x29, 0x8b, 0x78, 0x2c, +0xb8, 0xa0, 0x52, 0xb6, 0x9c, 0x47, 0x8a, 0x74, +0x21, 0x82, 0x6c, 0x19, 0x84, 0x6d, 0x16, 0x6f, +0x5c, 0x09, 0x5a, 0x89, 0x52, 0x56, 0xa9, 0x64, +0x36, 0xbd, 0x59, 0x84, 0x78, 0x3d, 0xa6, 0x9d, +0x73, 0xc8, 0xc3, 0xa8, 0x89, 0x75, 0x26, 0xc0, +0xa4, 0x4f, 0xbb, 0xb4, 0x93, 0xc6, 0xc1, 0xa5, +0xc4, 0xbe, 0xa2, 0x5f, 0x91, 0x5d, 0x1c, 0x69, +0x1d, 0x12, 0x5e, 0x11, 0x1a, 0x6a, 0x1d, 0x36, +0x97, 0x45, 0x2d, 0x8f, 0x3c, 0x14, 0x63, 0x15, +0xb5, 0x99, 0x41, 0x77, 0x69, 0x28, 0x19, 0x6a, +0x1b, 0x50, 0x87, 0x4e, 0x88, 0x7c, 0x43, 0x91, +0x7a, 0x27, 0x2c, 0x92, 0x3d, 0x80, 0xa8, 0x7f, +0x6b, 0x5a, 0x0b, 0x96, 0x7c, 0x22, 0x7e, 0xa6, +0x7d, 0x3e, 0xbb, 0x5d, 0x16, 0x68, 0x18, 0x7f, +0x6a, 0x16, 0x81, 0x6b, 0x15, 0x1b, 0x77, 0x24, +0x49, 0x82, 0x48, 0x18, 0x6e, 0x1d, 0x17, 0x6d, +0x1c, 0x48, 0xa4, 0x86, 0x44, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0xe8, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x63, 0x60, 0xa0, 0x1a, 0x60, 0x64, 0x62, +0x66, 0xc1, 0x27, 0xcf, 0xca, 0xc6, 0xce, 0xc1, +0x89, 0xc4, 0xe7, 0xe2, 0xe6, 0x41, 0x55, 0xc0, +0xcb, 0xc7, 0x2f, 0x20, 0x88, 0xe0, 0x0a, 0x09, +0x8b, 0x88, 0x8a, 0xa1, 0xaa, 0x10, 0x97, 0x90, +0x94, 0x42, 0xf0, 0xa4, 0x65, 0x64, 0xe5, 0xe4, +0xa1, 0x6c, 0x05, 0x45, 0x25, 0x65, 0x15, 0x15, +0x55, 0x35, 0x75, 0x0d, 0x4d, 0x24, 0xf5, 0x5a, +0xda, 0x3a, 0x30, 0xa6, 0x9a, 0xae, 0x9e, 0xbe, +0x81, 0x81, 0xa1, 0x91, 0xb1, 0x89, 0xa9, 0x9a, +0x9a, 0x99, 0xb9, 0x2e, 0x44, 0xd4, 0xc2, 0xd2, +0x0a, 0xae, 0xc0, 0xda, 0xc6, 0x96, 0xdf, 0xce, +0xde, 0xd8, 0xc4, 0xc1, 0xd1, 0xc9, 0xd9, 0xc5, +0xd5, 0xcd, 0xc2, 0x42, 0xcb, 0xdd, 0xc2, 0xc3, +0xd3, 0xcb, 0xdb, 0xc7, 0xd7, 0xd7, 0xc2, 0x02, +0xa4, 0x00, 0x59, 0xde, 0xcf, 0x3f, 0x20, 0x30, +0x28, 0x38, 0x24, 0x34, 0xcc, 0x2b, 0x3c, 0x22, +0x32, 0x2a, 0x3a, 0x06, 0xac, 0x00, 0x59, 0x3e, +0x36, 0x2e, 0x3e, 0x21, 0x51, 0x16, 0x2c, 0x9f, +0x94, 0x9c, 0x92, 0x9a, 0x06, 0x56, 0x00, 0x93, +0x4f, 0xcf, 0xc8, 0xcc, 0xca, 0xce, 0x89, 0xcf, +0x45, 0x92, 0xcf, 0x03, 0x2b, 0x80, 0xe9, 0xcf, +0x2f, 0x28, 0x74, 0x2b, 0x2a, 0x2e, 0x29, 0x85, +0xca, 0x97, 0x95, 0x57, 0x54, 0x56, 0x81, 0x15, +0x40, 0xe5, 0xab, 0x6b, 0x6a, 0xeb, 0xea, 0x1b, +0x2c, 0x1a, 0x61, 0xfa, 0x9b, 0x9a, 0x19, 0x18, +0x5a, 0xc0, 0x0a, 0xa0, 0xf6, 0xb7, 0xfa, 0xd4, +0xb5, 0x05, 0x25, 0xb6, 0xc3, 0xe4, 0x3b, 0x3a, +0x41, 0x5e, 0xec, 0x02, 0x29, 0x80, 0xba, 0xaf, +0xbb, 0x10, 0x28, 0x8f, 0xb0, 0xbf, 0xa7, 0x17, +0x1e, 0x0e, 0x50, 0xf7, 0xf7, 0xf5, 0x4f, 0x48, +0x94, 0x9d, 0x38, 0x69, 0x32, 0xd4, 0x7d, 0x53, +0xa6, 0xc2, 0x15, 0x40, 0xe4, 0xa7, 0x4d, 0x9f, +0x31, 0x73, 0xd6, 0xec, 0x39, 0x73, 0xe7, 0xcd, +0x87, 0xb8, 0x7f, 0x01, 0x3c, 0x36, 0xd5, 0x20, +0xf2, 0x0b, 0x17, 0x2d, 0x5e, 0xb2, 0x74, 0xd9, +0xf2, 0x15, 0x2b, 0x57, 0x81, 0xe5, 0x57, 0xaf, +0x29, 0x04, 0xca, 0x35, 0x83, 0x22, 0x44, 0x0d, +0x2a, 0xbf, 0x76, 0xdd, 0xfa, 0x0d, 0x1b, 0x37, +0x6d, 0xde, 0xb2, 0x15, 0x2c, 0xbf, 0x6d, 0xfb, +0x8e, 0x9d, 0xbb, 0x76, 0xef, 0x01, 0xfb, 0x02, +0x26, 0xbf, 0x77, 0xdf, 0xfe, 0x4d, 0x07, 0x0e, +0x1e, 0xea, 0x80, 0xc8, 0x1f, 0x3e, 0x72, 0xf4, +0xd8, 0xf1, 0x13, 0x60, 0x05, 0xc8, 0xf2, 0x27, +0x4f, 0x9d, 0x3e, 0x03, 0x95, 0x3f, 0x7b, 0xee, +0xfc, 0x89, 0x0b, 0x60, 0x05, 0xfe, 0x17, 0x2f, +0x5d, 0xbe, 0x72, 0x75, 0xef, 0xb5, 0xeb, 0x37, +0x6e, 0xdc, 0xbc, 0x79, 0xeb, 0xf6, 0x1d, 0x24, +0xf9, 0xbb, 0x20, 0x05, 0xf7, 0x34, 0xef, 0x2b, +0x3d, 0x50, 0x7a, 0xf8, 0xc8, 0xec, 0xf1, 0x93, +0xa7, 0x4a, 0x4a, 0x4a, 0xcf, 0x9e, 0xbf, 0xb0, +0xb0, 0x78, 0xf9, 0xea, 0xec, 0xeb, 0x37, 0x16, +0x15, 0x6f, 0xde, 0x54, 0xc0, 0x53, 0x90, 0xda, +0xdb, 0x77, 0xc8, 0x09, 0xf0, 0xfd, 0xf1, 0x0f, +0xa8, 0x29, 0xf2, 0xe3, 0xa7, 0x4d, 0x07, 0x59, +0x91, 0xf8, 0x16, 0x9f, 0xbf, 0xa0, 0x2a, 0xf8, +0xba, 0xe9, 0xc0, 0x37, 0x3e, 0x04, 0xf7, 0xfb, +0x9e, 0x1f, 0x3f, 0x51, 0x15, 0x28, 0xfc, 0xfa, +0xad, 0x86, 0xc4, 0x7d, 0xf1, 0xe3, 0xc2, 0x1f, +0xbc, 0xd9, 0xec, 0xef, 0xbf, 0xff, 0x56, 0x0c, +0x74, 0x03, 0x00, 0x6f, 0x3f, 0xeb, 0x4d, 0x72, +0x00, 0x4a, 0xd0, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *plugins_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_plugins_png = new wxImage(); + if (!img_plugins_png || !img_plugins_png->IsOk()) + { + wxMemoryInputStream img_plugins_pngIS(plugins_png_data, sizeof(plugins_png_data)); + img_plugins_png->LoadFile(img_plugins_pngIS, wxBITMAP_TYPE_PNG); + } + return img_plugins_png; +} +#define plugins_png_img plugins_png_img() + +static wxBitmap *plugins_png_bmp() +{ + static wxBitmap *bmp_plugins_png; + if (!bmp_plugins_png || !bmp_plugins_png->IsOk()) + bmp_plugins_png = new wxBitmap(*plugins_png_img); + return bmp_plugins_png; +} +#define plugins_png_bmp plugins_png_bmp() + +static wxIcon *plugins_png_ico() +{ + static wxIcon *ico_plugins_png; + if (!ico_plugins_png || !ico_plugins_png->IsOk()) + { + ico_plugins_png = new wxIcon(); + ico_plugins_png->CopyFromBitmap(*plugins_png_bmp); + } + return ico_plugins_png; +} +#define plugins_png_ico plugins_png_ico() + +#endif // PLUGINS_PNG_H diff --git a/include/images/primarykey.png b/include/images/primarykey.png new file mode 100644 index 0000000..b57f597 Binary files /dev/null and b/include/images/primarykey.png differ diff --git a/include/images/primarykey.pngc b/include/images/primarykey.pngc new file mode 100644 index 0000000..2c6b06e --- /dev/null +++ b/include/images/primarykey.pngc @@ -0,0 +1,100 @@ +#ifndef PRIMARYKEY_PNG_H +#define PRIMARYKEY_PNG_H + +static const unsigned char primarykey_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x93, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe0, 0xcf, 0x8b, 0xcb, +0xb0, 0x3e, 0xc7, 0xa9, 0x2d, 0xde, 0xcc, 0x7f, +0xee, 0xe7, 0xba, 0xee, 0xe7, 0xb7, 0xdd, 0xcc, +0x7b, 0xc7, 0xa9, 0x2c, 0xf6, 0xf3, 0xd0, 0xf4, +0xf0, 0xc6, 0xf2, 0xee, 0xb8, 0xf4, 0xee, 0xb6, +0xdd, 0xca, 0x74, 0xc1, 0xa0, 0x18, 0xdb, 0xc7, +0x77, 0xf5, 0xf2, 0xcd, 0xf3, 0xef, 0xb8, 0xf0, +0xe9, 0x9a, 0xf1, 0xea, 0x9a, 0xf3, 0xec, 0xa3, +0xf4, 0xed, 0xa3, 0xf4, 0xeb, 0x9a, 0xf3, 0xea, +0x91, 0xf2, 0xe8, 0x81, 0xf3, 0xe8, 0x82, 0xf7, +0xf0, 0xad, 0xee, 0xe7, 0xb9, 0xf5, 0xf1, 0xc8, +0xf3, 0xed, 0xb1, 0xf0, 0xe7, 0x90, 0xf1, 0xe8, +0x90, 0xf3, 0xec, 0xa0, 0xdb, 0xc7, 0x60, 0xf5, +0xed, 0xa0, 0xda, 0xc6, 0x58, 0xf3, 0xe8, 0x83, +0xf4, 0xea, 0x8d, 0xde, 0xcc, 0x7d, 0xf5, 0xf1, +0xc5, 0xf3, 0xee, 0xb3, 0xf1, 0xeb, 0xa0, 0xf2, +0xeb, 0x9e, 0xdd, 0xc9, 0x6d, 0xdd, 0xcc, 0x7a, +0xed, 0xe4, 0xa8, 0xed, 0xe4, 0xa2, 0xdd, 0xca, +0x72, 0xc7, 0xa9, 0x2a, 0x26, 0xed, 0xdc, 0x2b, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5f, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x0a, +0x60, 0x64, 0x62, 0x62, 0x44, 0xe6, 0x33, 0xb3, +0xb0, 0xb2, 0xb1, 0x73, 0x20, 0xc9, 0xb3, 0x70, +0x72, 0x71, 0xf3, 0xf0, 0xf2, 0x41, 0x00, 0x3f, +0x03, 0x03, 0x13, 0xab, 0x00, 0x9f, 0xa0, 0x90, +0xb0, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, 0x14, +0x1f, 0x50, 0x40, 0x5a, 0x86, 0x4f, 0x56, 0x4e, +0x5e, 0x41, 0x51, 0x49, 0x59, 0x45, 0x15, 0xa4, +0x82, 0x51, 0x4d, 0x5d, 0x43, 0x53, 0x4b, 0x9b, +0x8f, 0x1f, 0x08, 0x41, 0x7c, 0x06, 0x06, 0x0e, +0x1d, 0x5d, 0x3d, 0x7d, 0x03, 0x34, 0x6b, 0xa9, +0xe3, 0x7e, 0x38, 0x00, 0x00, 0xd8, 0xad, 0x05, +0xb8, 0xcc, 0xed, 0x53, 0x77, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *primarykey_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_primarykey_png = new wxImage(); + if (!img_primarykey_png || !img_primarykey_png->IsOk()) + { + wxMemoryInputStream img_primarykey_pngIS(primarykey_png_data, sizeof(primarykey_png_data)); + img_primarykey_png->LoadFile(img_primarykey_pngIS, wxBITMAP_TYPE_PNG); + } + return img_primarykey_png; +} +#define primarykey_png_img primarykey_png_img() + +static wxBitmap *primarykey_png_bmp() +{ + static wxBitmap *bmp_primarykey_png; + if (!bmp_primarykey_png || !bmp_primarykey_png->IsOk()) + bmp_primarykey_png = new wxBitmap(*primarykey_png_img); + return bmp_primarykey_png; +} +#define primarykey_png_bmp primarykey_png_bmp() + +static wxIcon *primarykey_png_ico() +{ + static wxIcon *ico_primarykey_png; + if (!ico_primarykey_png || !ico_primarykey_png->IsOk()) + { + ico_primarykey_png = new wxIcon(); + ico_primarykey_png->CopyFromBitmap(*primarykey_png_bmp); + } + return ico_primarykey_png; +} +#define primarykey_png_ico primarykey_png_ico() + +#endif // PRIMARYKEY_PNG_H diff --git a/include/images/procedure.png b/include/images/procedure.png new file mode 100644 index 0000000..8b65dff Binary files /dev/null and b/include/images/procedure.png differ diff --git a/include/images/procedure.pngc b/include/images/procedure.pngc new file mode 100644 index 0000000..a0f0b95 --- /dev/null +++ b/include/images/procedure.pngc @@ -0,0 +1,85 @@ +#ifndef PROCEDURE_PNG_H +#define PROCEDURE_PNG_H + +static const unsigned char procedure_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xde, 0x9a, 0x9a, 0xc6, +0x52, 0x52, 0xe9, 0xb9, 0xb9, 0xf8, 0xe8, 0xe8, +0xff, 0xfd, 0xfd, 0xf6, 0xe2, 0xe2, 0xea, 0xbe, +0xbe, 0xe2, 0xa6, 0xa6, 0xd9, 0x8b, 0x8b, 0xd2, +0x76, 0x76, 0xd1, 0x73, 0x73, 0xd7, 0x83, 0x83, +0x74, 0x72, 0xdd, 0xd3, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x52, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0x40, 0x02, 0x42, 0x8a, 0x10, 0x9a, +0x51, 0xd9, 0x48, 0x00, 0xcc, 0x60, 0x72, 0x71, +0x81, 0x08, 0x31, 0xaa, 0x86, 0x06, 0x01, 0x85, +0x18, 0x95, 0x94, 0x94, 0xd2, 0xd2, 0x80, 0x42, +0x4c, 0xe5, 0x20, 0x50, 0x24, 0xc0, 0xc0, 0xd4, +0x01, 0x06, 0x0a, 0x0c, 0x4c, 0x33, 0x41, 0x60, +0x92, 0x00, 0x58, 0xcd, 0xaa, 0x55, 0x60, 0x6d, +0x8c, 0xda, 0xbb, 0x37, 0x81, 0x0d, 0x62, 0x3a, +0x73, 0x06, 0x6a, 0x8e, 0xa2, 0x90, 0x00, 0xaa, +0x5d, 0x68, 0x00, 0x00, 0x5f, 0xe5, 0x12, 0xf7, +0x4e, 0xde, 0x81, 0x96, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, +0x32, 0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x37, +0x3a, 0x33, 0x36, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xbe, 0x1e, 0xd2, 0x9f, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *procedure_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_procedure_png = new wxImage(); + if (!img_procedure_png || !img_procedure_png->IsOk()) + { + wxMemoryInputStream img_procedure_pngIS(procedure_png_data, sizeof(procedure_png_data)); + img_procedure_png->LoadFile(img_procedure_pngIS, wxBITMAP_TYPE_PNG); + } + return img_procedure_png; +} +#define procedure_png_img procedure_png_img() + +static wxBitmap *procedure_png_bmp() +{ + static wxBitmap *bmp_procedure_png; + if (!bmp_procedure_png || !bmp_procedure_png->IsOk()) + bmp_procedure_png = new wxBitmap(*procedure_png_img); + return bmp_procedure_png; +} +#define procedure_png_bmp procedure_png_bmp() + +static wxIcon *procedure_png_ico() +{ + static wxIcon *ico_procedure_png; + if (!ico_procedure_png || !ico_procedure_png->IsOk()) + { + ico_procedure_png = new wxIcon(); + ico_procedure_png->CopyFromBitmap(*procedure_png_bmp); + } + return ico_procedure_png; +} +#define procedure_png_ico procedure_png_ico() + +#endif // PROCEDURE_PNG_H diff --git a/include/images/procedures.png b/include/images/procedures.png new file mode 100644 index 0000000..7c13a9b Binary files /dev/null and b/include/images/procedures.png differ diff --git a/include/images/procedures.pngc b/include/images/procedures.pngc new file mode 100644 index 0000000..d13ee2a --- /dev/null +++ b/include/images/procedures.pngc @@ -0,0 +1,87 @@ +#ifndef PROCEDURES_PNG_H +#define PROCEDURES_PNG_H + +static const unsigned char procedures_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xde, 0x9c, 0x9c, 0xc6, +0x52, 0x52, 0xef, 0xbd, 0xbd, 0xde, 0x94, 0x94, +0xd6, 0x6b, 0x6b, 0xef, 0xce, 0xce, 0xd6, 0x84, +0x84, 0xce, 0x5a, 0x5a, 0xe7, 0xad, 0xad, 0xd6, +0x73, 0x73, 0xff, 0xf7, 0xf7, 0xd6, 0x7b, 0x7b, +0x0d, 0x3b, 0x0e, 0xe6, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x61, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0x60, 0x54, 0x52, 0x64, 0x00, 0x03, +0x26, 0x63, 0x23, 0x01, 0x30, 0x83, 0x51, 0x45, +0x49, 0x15, 0x44, 0x0b, 0x29, 0x29, 0x19, 0x1b, +0x05, 0x00, 0x19, 0x6a, 0x69, 0xe9, 0x2a, 0x4a, +0x1a, 0x40, 0x86, 0xe6, 0x22, 0xa8, 0x90, 0x3a, +0x50, 0x48, 0x7b, 0x37, 0x50, 0x95, 0x10, 0x48, +0x68, 0xf7, 0x26, 0x01, 0xb0, 0x10, 0x10, 0x28, +0x82, 0x84, 0x66, 0x02, 0xc1, 0x24, 0xa0, 0x39, +0xea, 0xe5, 0x40, 0xa0, 0x08, 0x31, 0x69, 0xd5, +0x22, 0x90, 0xe1, 0x8c, 0x4a, 0x3a, 0x67, 0x20, +0xd6, 0x31, 0xb9, 0x38, 0x41, 0x6d, 0x83, 0xd9, +0x0f, 0x06, 0x00, 0xe0, 0x9a, 0x15, 0x41, 0x5d, +0x96, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x32, +0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x37, 0x3a, +0x33, 0x36, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, +0xbe, 0x1e, 0xd2, 0x9f, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *procedures_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_procedures_png = new wxImage(); + if (!img_procedures_png || !img_procedures_png->IsOk()) + { + wxMemoryInputStream img_procedures_pngIS(procedures_png_data, sizeof(procedures_png_data)); + img_procedures_png->LoadFile(img_procedures_pngIS, wxBITMAP_TYPE_PNG); + } + return img_procedures_png; +} +#define procedures_png_img procedures_png_img() + +static wxBitmap *procedures_png_bmp() +{ + static wxBitmap *bmp_procedures_png; + if (!bmp_procedures_png || !bmp_procedures_png->IsOk()) + bmp_procedures_png = new wxBitmap(*procedures_png_img); + return bmp_procedures_png; +} +#define procedures_png_bmp procedures_png_bmp() + +static wxIcon *procedures_png_ico() +{ + static wxIcon *ico_procedures_png; + if (!ico_procedures_png || !ico_procedures_png->IsOk()) + { + ico_procedures_png = new wxIcon(); + ico_procedures_png->CopyFromBitmap(*procedures_png_bmp); + } + return ico_procedures_png; +} +#define procedures_png_ico procedures_png_ico() + +#endif // PROCEDURES_PNG_H diff --git a/include/images/properties.png b/include/images/properties.png new file mode 100644 index 0000000..f9b8c14 Binary files /dev/null and b/include/images/properties.png differ diff --git a/include/images/properties.pngc b/include/images/properties.pngc new file mode 100644 index 0000000..8aeb23a --- /dev/null +++ b/include/images/properties.pngc @@ -0,0 +1,158 @@ +#ifndef PROPERTIES_PNG_H +#define PROPERTIES_PNG_H + +static const unsigned char properties_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x68, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xde, 0xce, 0x66, 0xe4, +0xca, 0x1d, 0xe4, 0xca, 0x1b, 0xde, 0xce, 0x63, +0xee, 0xde, 0x71, 0xfe, 0xfd, 0xd6, 0xfe, 0xfe, +0xc8, 0xfe, 0xfe, 0xc9, 0xfe, 0xfe, 0xcb, 0xfe, +0xfe, 0xcc, 0xfe, 0xfe, 0xce, 0xfe, 0xfe, 0xd0, +0xfe, 0xfe, 0xd2, 0xfe, 0xfe, 0xd3, 0xfe, 0xfe, +0xd5, 0xfe, 0xfe, 0xd7, 0xff, 0xff, 0xf5, 0xfe, +0xfd, 0xbe, 0xfd, 0xfd, 0x99, 0xfd, 0xfd, 0x93, +0xfd, 0xfd, 0x97, 0xfd, 0xfd, 0x9a, 0xfd, 0xfd, +0x9e, 0xfd, 0xfd, 0xa1, 0xfd, 0xfd, 0xa5, 0xfd, +0xfd, 0xa8, 0xfd, 0xfd, 0xac, 0xfe, 0xfd, 0xb0, +0xfe, 0xfd, 0xb3, 0xfe, 0xfe, 0xdb, 0xef, 0xe0, +0x50, 0xe4, 0xcb, 0x1c, 0xff, 0xff, 0xee, 0xfd, +0xfe, 0xbc, 0xfd, 0xfe, 0xbd, 0xfd, 0xfe, 0xbe, +0xfd, 0xfe, 0xbf, 0xfd, 0xfe, 0xc0, 0xfd, 0xfe, +0xc2, 0xfd, 0xfe, 0xc3, 0xfe, 0xfe, 0xbf, 0xfe, +0xfe, 0xad, 0xfc, 0xfd, 0x7b, 0xfc, 0xfd, 0x7d, +0xfc, 0xfd, 0x80, 0xfc, 0xfd, 0x82, 0xfc, 0xfd, +0x85, 0xfc, 0xfd, 0x87, 0xfd, 0xfd, 0x8a, 0xfd, +0xfd, 0x8d, 0xfd, 0xfd, 0x90, 0xee, 0xdf, 0x43, +0xfe, 0xfd, 0xb7, 0xfe, 0xfe, 0xdc, 0xfe, 0xfd, +0xba, 0xfe, 0xfe, 0xde, 0xfe, 0xfe, 0xe0, 0xfe, +0xfe, 0xc4, 0xfe, 0xfd, 0xc1, 0xfe, 0xfe, 0xe1, +0xfe, 0xfe, 0xc6, 0x9a, 0x9b, 0x51, 0xb6, 0xb7, +0x61, 0xa1, 0xa1, 0xa1, 0xfe, 0xfd, 0xc4, 0xfe, +0xfe, 0xe3, 0xfe, 0xfe, 0xc7, 0xcb, 0xcb, 0x6d, +0xda, 0xda, 0x77, 0xfe, 0xfd, 0xc8, 0xfe, 0xfe, +0xe5, 0xfe, 0xfd, 0xcb, 0xfe, 0xfd, 0xe6, 0x9b, +0x9b, 0x56, 0xb7, 0xb7, 0x68, 0xfe, 0xfc, 0xce, +0xff, 0xfd, 0xe8, 0xcb, 0xcb, 0x74, 0xda, 0xda, +0x7f, 0xff, 0xfc, 0xd1, 0xff, 0xfd, 0xe9, 0xff, +0xff, 0xf2, 0xff, 0xfc, 0xd3, 0xff, 0xfd, 0xea, +0x9b, 0x9b, 0x5c, 0xb7, 0xb7, 0x6f, 0xff, 0xfc, +0xd6, 0xff, 0xfd, 0xeb, 0xcb, 0xcb, 0x7c, 0xda, +0xda, 0x88, 0xff, 0xfc, 0xd8, 0xff, 0xfd, 0xed, +0xff, 0xfc, 0xdb, 0xff, 0xfd, 0xee, 0xfd, 0xfd, +0xb5, 0xfe, 0xfd, 0xb6, 0xfe, 0xfd, 0xcd, 0xfe, +0xfd, 0xd7, 0xff, 0xfd, 0xe0, 0xff, 0xfd, 0xe1, +0xff, 0xfd, 0xdd, 0xff, 0xfc, 0xda, 0xff, 0xfc, +0xdd, 0xfd, 0xfd, 0xb6, 0xf5, 0xed, 0xa1, 0xeb, +0xd7, 0x53, 0xf6, 0xed, 0xa3, 0xfe, 0xfd, 0xc5, +0xf6, 0xed, 0xa9, 0xf6, 0xed, 0xaa, 0xff, 0xfc, +0xde, 0xff, 0xfd, 0xef, 0xfe, 0xfe, 0xe9, 0xe8, +0xd3, 0x41, 0xd9, 0xd1, 0x9e, 0xff, 0xfe, 0xee, +0xff, 0xfe, 0xf2, 0xff, 0xfe, 0xf6, 0xff, 0xff, +0xfb, 0x9c, 0x67, 0x31, 0x36, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x01, 0x5b, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0xbd, 0x92, 0xd9, 0x3f, 0x02, 0x51, 0x18, +0x40, 0xe3, 0x0e, 0x6a, 0x94, 0x65, 0xb4, 0xda, +0xb5, 0x5b, 0x9a, 0x36, 0x4b, 0x1b, 0xa9, 0x68, +0x61, 0x90, 0xc2, 0x20, 0x0d, 0x12, 0x31, 0xb6, +0x34, 0x96, 0x7f, 0xdf, 0xdc, 0xdb, 0x36, 0x8d, +0xfb, 0xd3, 0x13, 0xdf, 0xe3, 0x9c, 0xf3, 0xdd, +0xf3, 0x30, 0x9f, 0x42, 0xf1, 0xcf, 0xd3, 0xd3, +0x0b, 0xda, 0x43, 0x60, 0x78, 0x5f, 0xff, 0x80, +0x52, 0x45, 0x0e, 0xaa, 0x35, 0x43, 0xc3, 0x23, +0xa3, 0x00, 0xc3, 0xa9, 0x31, 0xad, 0x4e, 0x6f, +0x30, 0x9a, 0xc6, 0x27, 0x26, 0xa7, 0xa6, 0x9b, +0x02, 0xd1, 0x7a, 0x13, 0xf2, 0x99, 0xd9, 0x1f, +0x11, 0x30, 0x67, 0xb6, 0x58, 0x6d, 0x76, 0x87, +0x73, 0x7e, 0x41, 0xe4, 0x98, 0x08, 0x30, 0x2f, +0x2e, 0xb9, 0x68, 0xb7, 0xc7, 0xeb, 0xf3, 0x8b, +0x1c, 0x13, 0x01, 0x96, 0xe5, 0xdf, 0x23, 0xc0, +0xda, 0x25, 0x02, 0x6c, 0x5d, 0x22, 0xc0, 0x2e, +0x8f, 0xb4, 0xf8, 0xca, 0x2a, 0x12, 0x1c, 0xb2, +0x48, 0x9b, 0xaf, 0x05, 0x90, 0xe0, 0xec, 0x8c, +0x48, 0x38, 0x15, 0x44, 0x42, 0x08, 0x46, 0xb0, +0x3c, 0x1c, 0x41, 0xc2, 0x3a, 0x8c, 0xb8, 0xe8, +0x8d, 0x28, 0xe4, 0x9b, 0x92, 0x09, 0xc7, 0xe2, +0x48, 0x48, 0xc0, 0x08, 0xed, 0xde, 0xda, 0x96, +0xef, 0xc7, 0x92, 0x29, 0x24, 0x28, 0x61, 0x04, +0xf3, 0x7e, 0x2c, 0x99, 0xce, 0x20, 0x41, 0x05, +0x23, 0x1e, 0xef, 0xce, 0x2e, 0xe4, 0xd2, 0x44, +0x9a, 0xd9, 0x43, 0x02, 0x09, 0x23, 0x5e, 0xdf, +0xfe, 0x81, 0x7c, 0x9f, 0xc9, 0x1e, 0x22, 0x21, +0x07, 0x23, 0x98, 0xf7, 0x99, 0x6c, 0xfe, 0x08, +0xd4, 0xef, 0x41, 0x8c, 0xf8, 0xb5, 0xc7, 0x27, +0x90, 0x4b, 0x13, 0x79, 0xf6, 0xb4, 0xf1, 0x3f, +0xc5, 0x88, 0x56, 0x77, 0x76, 0x2e, 0xdf, 0x67, +0x0b, 0x17, 0x0d, 0x41, 0x8c, 0x60, 0xde, 0x67, +0x0b, 0x45, 0x0e, 0x34, 0x8f, 0x4e, 0xa5, 0x37, +0x98, 0x2e, 0x43, 0x09, 0xea, 0xaa, 0xce, 0xaf, +0x4b, 0x37, 0xe5, 0xdb, 0xbb, 0x62, 0x85, 0x6b, +0xde, 0x25, 0x20, 0x0d, 0xc6, 0xfb, 0x07, 0x9e, +0x7f, 0x7c, 0xaa, 0xef, 0x97, 0x9e, 0x79, 0xfe, +0xa5, 0x5c, 0x79, 0xad, 0xb6, 0x84, 0x9c, 0x5a, +0xf3, 0x56, 0x13, 0x84, 0xda, 0x7b, 0x20, 0x18, +0x89, 0xa7, 0x32, 0x1f, 0xbc, 0x20, 0xf0, 0x9f, +0x5c, 0xf5, 0xab, 0xe3, 0xb2, 0x09, 0xc9, 0x85, +0x13, 0xed, 0x6f, 0x7f, 0x3f, 0xdf, 0x2a, 0x0c, +0x61, 0x7b, 0x5d, 0x3a, 0x20, 0x56, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *properties_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_properties_png = new wxImage(); + if (!img_properties_png || !img_properties_png->IsOk()) + { + wxMemoryInputStream img_properties_pngIS(properties_png_data, sizeof(properties_png_data)); + img_properties_png->LoadFile(img_properties_pngIS, wxBITMAP_TYPE_PNG); + } + return img_properties_png; +} +#define properties_png_img properties_png_img() + +static wxBitmap *properties_png_bmp() +{ + static wxBitmap *bmp_properties_png; + if (!bmp_properties_png || !bmp_properties_png->IsOk()) + bmp_properties_png = new wxBitmap(*properties_png_img); + return bmp_properties_png; +} +#define properties_png_bmp properties_png_bmp() + +static wxIcon *properties_png_ico() +{ + static wxIcon *ico_properties_png; + if (!ico_properties_png || !ico_properties_png->IsOk()) + { + ico_properties_png = new wxIcon(); + ico_properties_png->CopyFromBitmap(*properties_png_bmp); + } + return ico_properties_png; +} +#define properties_png_ico properties_png_ico() + +#endif // PROPERTIES_PNG_H diff --git a/include/images/property.png b/include/images/property.png new file mode 100644 index 0000000..c410cb0 Binary files /dev/null and b/include/images/property.png differ diff --git a/include/images/property.pngc b/include/images/property.pngc new file mode 100644 index 0000000..406af53 --- /dev/null +++ b/include/images/property.pngc @@ -0,0 +1,116 @@ +#ifndef PROPERTY_PNG_H +#define PROPERTY_PNG_H + +static const unsigned char property_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xef, 0xe0, 0x7c, 0xe4, +0xcb, 0x1e, 0xe4, 0xca, 0x1b, 0xef, 0xe0, 0x79, +0xee, 0xde, 0x71, 0xfe, 0xfd, 0xd7, 0xfe, 0xfe, +0xca, 0xfe, 0xfe, 0xcd, 0xfe, 0xfe, 0xcf, 0xfe, +0xfe, 0xd2, 0xfe, 0xfe, 0xd5, 0xff, 0xff, 0xf5, +0xfe, 0xfd, 0xbf, 0xfd, 0xfd, 0x9e, 0xfd, 0xfd, +0x9b, 0xfd, 0xfd, 0xa0, 0xfd, 0xfd, 0xa6, 0xfd, +0xfd, 0xac, 0xfe, 0xfd, 0xb2, 0xfe, 0xfe, 0xdb, +0xff, 0xff, 0xee, 0xfd, 0xfe, 0xbe, 0xfd, 0xfe, +0xc0, 0xfd, 0xfe, 0xc2, 0xfe, 0xfe, 0xbf, 0xfe, +0xfe, 0xaf, 0xfe, 0xfd, 0xb8, 0xfe, 0xfe, 0xde, +0xa1, 0xa1, 0xa1, 0xfd, 0xfd, 0x8b, 0xfd, 0xfd, +0x90, 0xfe, 0xfe, 0xe1, 0xfc, 0xfd, 0x86, 0xfd, +0xfd, 0x95, 0xfe, 0xfd, 0xbd, 0xfe, 0xfd, 0xc3, +0xfe, 0xfe, 0xe3, 0xfe, 0xfe, 0xe6, 0xfe, 0xfe, +0xc5, 0xfe, 0xfd, 0xc8, 0xfe, 0xfd, 0xcd, 0xff, +0xfd, 0xe8, 0xfe, 0xfe, 0xc7, 0xff, 0xfd, 0xea, +0xfd, 0xfd, 0x9f, 0xfd, 0xfd, 0xb1, 0xfe, 0xfe, +0xc3, 0xfe, 0xfd, 0xc0, 0xfe, 0xfd, 0xbb, 0xfe, +0xfd, 0xce, 0xfe, 0xfe, 0xda, 0xfe, 0xfe, 0xdd, +0xff, 0xfd, 0xda, 0xff, 0xfc, 0xd8, 0xff, 0xfd, +0xec, 0xfd, 0xfd, 0xb2, 0xf5, 0xed, 0xa0, 0xeb, +0xd7, 0x53, 0xf6, 0xed, 0xa4, 0xfe, 0xfd, 0xc9, +0xf6, 0xed, 0xa7, 0xf6, 0xed, 0xaa, 0xff, 0xfd, +0xe1, 0xff, 0xfd, 0xee, 0xff, 0xff, 0xf3, 0xfe, +0xfe, 0xe9, 0xe8, 0xd3, 0x41, 0xf8, 0xf1, 0xc5, +0xff, 0xfe, 0xf0, 0xff, 0xfe, 0xf6, 0xff, 0xff, +0xfb, 0x8d, 0x2e, 0x7b, 0xad, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0xc0, 0x01, 0x18, 0x99, 0x98, +0xc1, 0x80, 0x05, 0xc6, 0x67, 0x65, 0x63, 0xe7, +0xe0, 0xe4, 0xe2, 0xe6, 0x61, 0x66, 0x60, 0x01, +0x4b, 0xb0, 0xf2, 0xf2, 0xf1, 0x0b, 0x08, 0x0a, +0x09, 0x8b, 0x30, 0x33, 0x30, 0x8b, 0x8a, 0x89, +0x4b, 0x48, 0x4a, 0x41, 0xf8, 0xd2, 0x32, 0x40, +0x01, 0x31, 0x59, 0x59, 0x39, 0x79, 0x59, 0x28, +0x50, 0x00, 0x0a, 0x88, 0x2b, 0xca, 0xc9, 0x2b, +0x41, 0xe4, 0x95, 0x55, 0x54, 0x81, 0x02, 0x12, +0xb2, 0xb2, 0x4a, 0xfc, 0x30, 0x15, 0x6a, 0x40, +0x01, 0x75, 0x84, 0xbc, 0x86, 0xa6, 0x16, 0x50, +0x40, 0x5b, 0x56, 0x56, 0x40, 0x10, 0xa6, 0x42, +0x07, 0x28, 0xc0, 0xae, 0xab, 0xa7, 0xaf, 0x6d, +0x60, 0x68, 0x60, 0x64, 0x6c, 0x62, 0x6a, 0x66, +0x0e, 0x14, 0xe0, 0xb0, 0xb0, 0xb4, 0xb2, 0xb2, +0xb6, 0x31, 0xb2, 0xb5, 0xb2, 0xb2, 0xb3, 0x77, +0x00, 0x0a, 0x38, 0x3a, 0x39, 0xbb, 0xb8, 0x38, +0xbb, 0xba, 0x5a, 0xb9, 0xb8, 0x58, 0xb9, 0xb9, +0x83, 0x5d, 0x0a, 0x74, 0x3f, 0x32, 0x49, 0x08, +0x00, 0x00, 0xe8, 0xce, 0x13, 0x85, 0xc7, 0x26, +0xe0, 0x45, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *property_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_property_png = new wxImage(); + if (!img_property_png || !img_property_png->IsOk()) + { + wxMemoryInputStream img_property_pngIS(property_png_data, sizeof(property_png_data)); + img_property_png->LoadFile(img_property_pngIS, wxBITMAP_TYPE_PNG); + } + return img_property_png; +} +#define property_png_img property_png_img() + +static wxBitmap *property_png_bmp() +{ + static wxBitmap *bmp_property_png; + if (!bmp_property_png || !bmp_property_png->IsOk()) + bmp_property_png = new wxBitmap(*property_png_img); + return bmp_property_png; +} +#define property_png_bmp property_png_bmp() + +static wxIcon *property_png_ico() +{ + static wxIcon *ico_property_png; + if (!ico_property_png || !ico_property_png->IsOk()) + { + ico_property_png = new wxIcon(); + ico_property_png->CopyFromBitmap(*property_png_bmp); + } + return ico_property_png; +} +#define property_png_ico property_png_ico() + +#endif // PROPERTY_PNG_H diff --git a/include/images/query_cancel.png b/include/images/query_cancel.png new file mode 100644 index 0000000..f749a68 Binary files /dev/null and b/include/images/query_cancel.png differ diff --git a/include/images/query_cancel.pngc b/include/images/query_cancel.pngc new file mode 100644 index 0000000..566df25 --- /dev/null +++ b/include/images/query_cancel.pngc @@ -0,0 +1,107 @@ +#ifndef QUERY_CANCEL_PNG_H +#define QUERY_CANCEL_PNG_H + +static const unsigned char query_cancel_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc3, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0x8d, 0x5f, 0xbf, +0x5e, 0x10, 0xe9, 0xd0, 0xa6, 0xe3, 0xc0, 0x86, +0xe4, 0xbf, 0x83, 0xe6, 0xbe, 0x7e, 0xe8, 0xbc, +0x7a, 0xe9, 0xba, 0x75, 0xec, 0xb9, 0x70, 0xf2, +0xc8, 0x8f, 0xe3, 0xc0, 0x85, 0xdc, 0xa9, 0x58, +0xde, 0xa7, 0x52, 0xe0, 0xa5, 0x4c, 0xe3, 0xa3, +0x46, 0xe6, 0xa0, 0x3f, 0xe9, 0x9e, 0x37, 0xf1, +0xb4, 0x64, 0xe5, 0xbf, 0x81, 0xe1, 0xa5, 0x4b, +0xe3, 0xa2, 0x45, 0xe6, 0xa0, 0x3e, 0xe9, 0x9d, +0x36, 0xec, 0x9b, 0x2f, 0xf3, 0xb2, 0x5d, 0xe6, +0xbd, 0x7d, 0xe1, 0xa5, 0x4a, 0xe4, 0xa2, 0x44, +0xe7, 0xa0, 0x3c, 0xea, 0x9d, 0x35, 0xed, 0x9a, +0x2e, 0xf0, 0x98, 0x26, 0xf5, 0xb0, 0x57, 0xe9, +0xbb, 0x77, 0xe4, 0xa2, 0x43, 0xe7, 0x9f, 0x3b, +0xea, 0x9d, 0x34, 0xed, 0x9a, 0x2d, 0xf0, 0x97, +0x25, 0xf3, 0x95, 0x1e, 0xf8, 0xad, 0x51, 0xec, +0xb9, 0x71, 0xe7, 0x9f, 0x3a, 0xea, 0x9c, 0x33, +0xed, 0x9a, 0x2b, 0xf0, 0x97, 0x24, 0xf3, 0x94, +0x1d, 0xf6, 0x92, 0x16, 0xfb, 0xac, 0x4c, 0xee, +0xb6, 0x6b, 0xeb, 0x9c, 0x32, 0xee, 0x99, 0x2a, +0xf1, 0x96, 0x23, 0xf4, 0x94, 0x1c, 0xf6, 0x92, +0x15, 0xf9, 0x8f, 0x0f, 0xfc, 0xaa, 0x47, 0xf4, +0xc7, 0x8b, 0xf2, 0xb3, 0x5f, 0xf5, 0xb0, 0x59, +0xf7, 0xaf, 0x54, 0xf9, 0xad, 0x4f, 0xfb, 0xab, +0x4a, 0xfe, 0xbd, 0x71, 0x9c, 0x0a, 0xd6, 0x59, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x66, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x0b, +0x30, 0x32, 0x41, 0x01, 0x23, 0x54, 0x80, 0x89, +0x99, 0x85, 0x95, 0x8d, 0x9d, 0x83, 0x93, 0x8b, +0x09, 0x26, 0xc0, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, +0x20, 0x28, 0x04, 0x17, 0x10, 0xe6, 0x15, 0x11, +0x15, 0x13, 0x97, 0x90, 0x84, 0x0b, 0x48, 0x49, +0xcb, 0xc8, 0xca, 0xc9, 0x2b, 0x28, 0xc2, 0x05, +0x94, 0x94, 0x55, 0x54, 0xd5, 0xd4, 0x35, 0x34, +0xe1, 0x02, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, +0x06, 0x86, 0x70, 0x01, 0x23, 0x63, 0x13, 0x53, +0x33, 0x73, 0x0b, 0x4b, 0xb8, 0x80, 0x95, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0xa5, 0x03, 0x13, 0x2e, +0x87, 0x91, 0x08, 0x00, 0xea, 0xbb, 0x08, 0xa8, +0x5b, 0xa9, 0x89, 0x69, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, +0x32, 0x35, 0x54, 0x31, 0x35, 0x3a, 0x30, 0x38, +0x3a, 0x33, 0x38, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0x1f, 0x2a, 0xf2, 0x4f, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_cancel_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_cancel_png = new wxImage(); + if (!img_query_cancel_png || !img_query_cancel_png->IsOk()) + { + wxMemoryInputStream img_query_cancel_pngIS(query_cancel_png_data, sizeof(query_cancel_png_data)); + img_query_cancel_png->LoadFile(img_query_cancel_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_cancel_png; +} +#define query_cancel_png_img query_cancel_png_img() + +static wxBitmap *query_cancel_png_bmp() +{ + static wxBitmap *bmp_query_cancel_png; + if (!bmp_query_cancel_png || !bmp_query_cancel_png->IsOk()) + bmp_query_cancel_png = new wxBitmap(*query_cancel_png_img); + return bmp_query_cancel_png; +} +#define query_cancel_png_bmp query_cancel_png_bmp() + +static wxIcon *query_cancel_png_ico() +{ + static wxIcon *ico_query_cancel_png; + if (!ico_query_cancel_png || !ico_query_cancel_png->IsOk()) + { + ico_query_cancel_png = new wxIcon(); + ico_query_cancel_png->CopyFromBitmap(*query_cancel_png_bmp); + } + return ico_query_cancel_png; +} +#define query_cancel_png_ico query_cancel_png_ico() + +#endif // QUERY_CANCEL_PNG_H diff --git a/include/images/query_commit.png b/include/images/query_commit.png new file mode 100644 index 0000000..500ef88 Binary files /dev/null and b/include/images/query_commit.png differ diff --git a/include/images/query_commit.pngc b/include/images/query_commit.pngc new file mode 100644 index 0000000..c2f7814 --- /dev/null +++ b/include/images/query_commit.pngc @@ -0,0 +1,133 @@ +#ifndef QUERY_COMMIT_PNG_H +#define QUERY_COMMIT_PNG_H + +static const unsigned char query_commit_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0e, 0xc2, 0x00, 0x00, 0x0e, +0xc2, 0x01, 0x15, 0x28, 0x4a, 0x80, 0x00, 0x00, +0x00, 0x18, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x70, +0x61, 0x69, 0x6e, 0x74, 0x2e, 0x6e, 0x65, 0x74, +0x20, 0x34, 0x2e, 0x30, 0x2e, 0x35, 0x65, 0x85, +0x32, 0x65, 0x00, 0x00, 0x02, 0x41, 0x49, 0x44, +0x41, 0x54, 0x38, 0x4f, 0x7d, 0x91, 0x5b, 0x48, +0x93, 0x61, 0x1c, 0xc6, 0xa7, 0xe0, 0x11, 0x15, +0x19, 0x96, 0xc2, 0xac, 0x8c, 0xb2, 0x42, 0x74, +0x9f, 0x87, 0x9c, 0xb3, 0x05, 0x51, 0x17, 0xdd, +0x04, 0x12, 0x75, 0xdb, 0x5d, 0x14, 0x24, 0x74, +0xd9, 0x55, 0x77, 0xd1, 0x75, 0xd0, 0x81, 0x31, +0x33, 0x4a, 0x24, 0x0b, 0xf3, 0x30, 0xb1, 0xac, +0xd4, 0x29, 0xcb, 0x74, 0x1d, 0xa4, 0x08, 0x8c, +0x5a, 0xea, 0x58, 0x6b, 0xe7, 0x43, 0x5e, 0xe8, +0xa0, 0x0c, 0xf2, 0xd7, 0xfb, 0xce, 0xf9, 0xd9, +0xd7, 0xaa, 0x3f, 0x3c, 0x7c, 0xef, 0xf7, 0xfe, +0x9f, 0xe7, 0x79, 0x9f, 0xf7, 0xff, 0xea, 0x00, +0x0d, 0x3a, 0xb3, 0xb2, 0xe8, 0xce, 0xc9, 0x61, +0xb8, 0xb8, 0x98, 0x87, 0x25, 0x25, 0xd8, 0x8b, +0x8a, 0xe8, 0xc9, 0xcb, 0xe3, 0xa6, 0x4e, 0xb6, +0xb5, 0x5c, 0x89, 0x8c, 0x8d, 0xdb, 0xd9, 0xd9, +0x38, 0xb7, 0x57, 0x10, 0xac, 0xaf, 0x25, 0xd2, +0xa4, 0x10, 0x6f, 0x30, 0x12, 0x6b, 0x36, 0x32, +0x59, 0x56, 0x26, 0xda, 0x5a, 0xae, 0x44, 0xc6, +0xc6, 0x2d, 0x91, 0xc0, 0x59, 0x5d, 0x49, 0xa8, +0xa9, 0x8e, 0xc8, 0x7e, 0x85, 0x88, 0x49, 0xa0, +0x55, 0x61, 0x5c, 0xaf, 0x17, 0x6d, 0x2d, 0x57, +0x42, 0x5d, 0x74, 0x14, 0xe5, 0x22, 0xe3, 0xcb, +0x04, 0xae, 0x23, 0x0d, 0xeb, 0xc2, 0x16, 0x85, +0x90, 0x45, 0x7c, 0x0f, 0x35, 0x33, 0x6b, 0x30, +0x30, 0x56, 0x5a, 0xca, 0x9d, 0x3f, 0xae, 0xa2, +0x2e, 0xba, 0x64, 0xf4, 0x8a, 0xad, 0xbc, 0xdd, +0xb5, 0x83, 0xa0, 0x10, 0xc6, 0x4d, 0x0d, 0x04, +0x8e, 0x9a, 0xf0, 0xb6, 0xb5, 0x10, 0x39, 0xd8, +0x48, 0xd8, 0xac, 0xf0, 0x61, 0xdf, 0xee, 0xd4, +0x21, 0x1b, 0x1a, 0x09, 0x75, 0x21, 0xd1, 0x93, +0x9b, 0xcb, 0xb8, 0xa1, 0x1c, 0xf7, 0x61, 0x85, +0x8f, 0x27, 0x1b, 0x09, 0x1d, 0x50, 0x08, 0x9b, +0x8c, 0xf8, 0xea, 0x6b, 0x98, 0xdc, 0x56, 0x4e, +0x7f, 0x41, 0x81, 0xa0, 0x6d, 0xf2, 0x25, 0x34, +0x35, 0x37, 0x73, 0x95, 0xde, 0xfc, 0x7c, 0x66, +0xf6, 0x54, 0xe1, 0xb1, 0xd4, 0x11, 0x16, 0x73, +0xf0, 0x99, 0x6b, 0x71, 0xee, 0x34, 0x70, 0x57, +0xbc, 0x4c, 0x9a, 0xa6, 0x96, 0xc6, 0x60, 0xb8, +0xd3, 0x82, 0xeb, 0xd1, 0x39, 0xe6, 0x67, 0xaf, +0xd0, 0x5f, 0x58, 0x88, 0xa3, 0xb2, 0x82, 0xf7, +0x35, 0xd5, 0x4c, 0xef, 0xad, 0xe2, 0x9e, 0x48, +0xf6, 0x7a, 0xe2, 0x3c, 0x8e, 0x81, 0x13, 0xd8, +0x6d, 0x26, 0x55, 0xa5, 0x1a, 0x3c, 0x1b, 0x38, +0x8d, 0xe7, 0x5d, 0x07, 0xfc, 0x5c, 0x12, 0xf0, +0xb3, 0xb6, 0xea, 0xe6, 0xbe, 0x78, 0xfb, 0xc1, +0x2d, 0xfa, 0x94, 0x38, 0x18, 0xec, 0x23, 0xe0, +0xeb, 0xc2, 0xeb, 0xed, 0xe4, 0x85, 0xa3, 0x1d, +0xc9, 0x97, 0x3a, 0xd5, 0x60, 0xc8, 0x66, 0xe1, +0xd5, 0xe8, 0x29, 0xe6, 0x5e, 0x9e, 0xe5, 0xab, +0x67, 0x84, 0x95, 0xd0, 0xe4, 0x3a, 0xe2, 0x76, +0xa2, 0xbe, 0xeb, 0x2a, 0x64, 0x5f, 0xf2, 0x9e, +0x76, 0xb7, 0x69, 0x0d, 0xfa, 0xaf, 0xd5, 0xe3, +0x5f, 0x98, 0x20, 0xba, 0x38, 0xca, 0xf3, 0xa1, +0x76, 0x9e, 0x74, 0x1d, 0xc3, 0x6e, 0x6d, 0x51, +0x21, 0xff, 0xe5, 0x7e, 0x22, 0x3a, 0x4d, 0xec, +0xcb, 0x18, 0x92, 0x2f, 0x75, 0x1a, 0x83, 0xa0, +0x67, 0x8a, 0x64, 0xcc, 0x0d, 0xdf, 0x57, 0xe0, +0xdb, 0x12, 0x6b, 0xc9, 0x39, 0x92, 0x89, 0x11, +0xe2, 0x3e, 0x1b, 0x9f, 0xe7, 0x2f, 0xe2, 0x9d, +0xbf, 0x2c, 0xae, 0x61, 0x25, 0xe2, 0xef, 0xfb, +0xb7, 0xc1, 0x72, 0xec, 0x13, 0xfc, 0x48, 0xc2, +0xea, 0xba, 0xc1, 0x4a, 0xf4, 0x31, 0x89, 0xb0, +0x35, 0x65, 0xe0, 0x5b, 0x14, 0x06, 0x5e, 0x2b, +0xd1, 0xc0, 0x83, 0xbf, 0x1b, 0xcc, 0x3a, 0x2e, +0xa5, 0x13, 0x2c, 0xab, 0x06, 0xa9, 0x04, 0xfe, +0xdf, 0x12, 0x78, 0x6d, 0xbc, 0x71, 0x5e, 0xc8, +0x34, 0x90, 0x35, 0xd4, 0xd1, 0xca, 0xd4, 0xe0, +0x19, 0x16, 0x5c, 0x37, 0x36, 0x07, 0x99, 0x1e, +0xe2, 0xc6, 0xf0, 0x26, 0x7a, 0x8f, 0x8b, 0x67, +0x34, 0xab, 0x2a, 0x8d, 0xc1, 0x46, 0xfd, 0x6f, +0x88, 0x69, 0x8a, 0x5a, 0x80, 0xee, 0x17, 0x32, +0x36, 0x62, 0x47, 0xaf, 0xdc, 0xcb, 0x78, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_commit_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_commit_png = new wxImage(); + if (!img_query_commit_png || !img_query_commit_png->IsOk()) + { + wxMemoryInputStream img_query_commit_pngIS(query_commit_png_data, sizeof(query_commit_png_data)); + img_query_commit_png->LoadFile(img_query_commit_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_commit_png; +} +#define query_commit_png_img query_commit_png_img() + +static wxBitmap *query_commit_png_bmp() +{ + static wxBitmap *bmp_query_commit_png; + if (!bmp_query_commit_png || !bmp_query_commit_png->IsOk()) + bmp_query_commit_png = new wxBitmap(*query_commit_png_img); + return bmp_query_commit_png; +} +#define query_commit_png_bmp query_commit_png_bmp() + +static wxIcon *query_commit_png_ico() +{ + static wxIcon *ico_query_commit_png; + if (!ico_query_commit_png || !ico_query_commit_png->IsOk()) + { + ico_query_commit_png = new wxIcon(); + ico_query_commit_png->CopyFromBitmap(*query_commit_png_bmp); + } + return ico_query_commit_png; +} +#define query_commit_png_ico query_commit_png_ico() + +#endif // QUERY_COMMIT_PNG_H diff --git a/include/images/query_execfile.png b/include/images/query_execfile.png new file mode 100644 index 0000000..c0b5f24 Binary files /dev/null and b/include/images/query_execfile.png differ diff --git a/include/images/query_execfile.pngc b/include/images/query_execfile.pngc new file mode 100644 index 0000000..6e10a50 --- /dev/null +++ b/include/images/query_execfile.pngc @@ -0,0 +1,119 @@ +#ifndef QUERY_EXECFILE_PNG_H +#define QUERY_EXECFILE_PNG_H + +static const unsigned char query_execfile_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xed, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0xaf, 0xcc, 0x63, +0xaf, 0xcc, 0x64, 0xa9, 0xc8, 0x56, 0x94, 0xbb, +0x2f, 0xb1, 0xcd, 0x69, 0xaa, 0xc8, 0x5a, 0x8e, +0xb7, 0x26, 0x97, 0xbc, 0x38, 0xb4, 0xcf, 0x70, +0xab, 0xc9, 0x5e, 0x90, 0xb8, 0x2c, 0x92, 0xb9, +0x31, 0x9b, 0xbf, 0x43, 0xb6, 0xd1, 0x78, 0xad, +0xcb, 0x62, 0x92, 0xba, 0x33, 0x94, 0xbb, 0x38, +0x96, 0xbc, 0x3d, 0xa5, 0xc5, 0x5a, 0x6e, 0x98, +0xb2, 0x2c, 0x66, 0xbd, 0x70, 0x92, 0xc5, 0xae, +0xcb, 0x67, 0x95, 0xbb, 0x39, 0x96, 0xbd, 0x3e, +0x9e, 0xc2, 0x4f, 0xba, 0xd3, 0x81, 0x9b, 0xd0, +0xe1, 0xf2, 0xf9, 0xfc, 0xe3, 0xf3, 0xf9, 0xdb, +0xf1, 0xf8, 0xe4, 0xf5, 0xfb, 0x9d, 0xc8, 0xe6, +0xb0, 0xcd, 0x6c, 0x97, 0xbd, 0x40, 0x9f, 0xc2, +0x51, 0xba, 0xd3, 0x83, 0x7a, 0xbf, 0xd7, 0xb1, +0xb1, 0xb1, 0xc8, 0xeb, 0xf7, 0x7e, 0xb4, 0xe0, +0xb2, 0xce, 0x71, 0x9f, 0xc3, 0x53, 0xba, 0xd4, +0x83, 0x7b, 0xbe, 0xd8, 0xea, 0xf6, 0xfb, 0xd2, +0xee, 0xf8, 0xda, 0xf2, 0xfa, 0x7f, 0xb2, 0xe1, +0xba, 0xd4, 0x85, 0x7c, 0xbc, 0xda, 0x3b, 0x7f, +0xc4, 0x3c, 0x7b, 0xc8, 0x80, 0xb0, 0xe3, 0xce, +0xe0, 0xa7, 0x7c, 0xba, 0xdb, 0x51, 0xa1, 0xd0, +0x52, 0x9f, 0xd2, 0x53, 0x9c, 0xd4, 0x53, 0x9a, +0xd5, 0x54, 0x97, 0xd7, 0x55, 0x95, 0xd9, 0x80, +0xae, 0xe3, 0x7d, 0xb9, 0xdc, 0x3c, 0x7d, 0xc6, +0x3d, 0x79, 0xc9, 0x56, 0x92, 0xdb, 0x80, 0xac, +0xe5, 0x93, 0xc3, 0xe3, 0xe0, 0xf2, 0xf9, 0x56, +0x90, 0xdc, 0x81, 0xaa, 0xe6, 0xec, 0xf7, 0xfc, +0xdc, 0xf3, 0xfa, 0xa0, 0xbe, 0xed, 0xa6, 0x3b, +0x61, 0xb6, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa2, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, +0xd7, 0x0e, 0x82, 0x50, 0x10, 0x04, 0xd0, 0xcb, +0xda, 0x7b, 0xd7, 0xb1, 0x21, 0x88, 0x15, 0x7b, +0xef, 0xbd, 0x8b, 0xfa, 0xff, 0x9f, 0xe3, 0x25, +0x42, 0x02, 0xee, 0xe3, 0xc9, 0x66, 0x66, 0x97, +0x09, 0x24, 0x30, 0xdb, 0x90, 0xe3, 0x4f, 0xc8, +0xe9, 0xb2, 0x0b, 0xb9, 0x3d, 0x5e, 0x9b, 0x90, +0xcf, 0x1f, 0x08, 0x5a, 0x85, 0x42, 0xe1, 0x48, +0x34, 0x66, 0x11, 0x8a, 0x27, 0x92, 0xa9, 0x74, +0x06, 0xc6, 0x64, 0x19, 0xe5, 0xf2, 0x85, 0xa2, +0x88, 0x12, 0x24, 0xb9, 0xac, 0xa0, 0x02, 0x46, +0xd5, 0x5a, 0xbd, 0x41, 0x68, 0x42, 0x56, 0xd5, +0x16, 0xda, 0x1c, 0x3a, 0xdd, 0x1e, 0x09, 0xe8, +0x63, 0x30, 0x6c, 0x8d, 0x30, 0xe6, 0x20, 0x4e, +0x78, 0x22, 0xa6, 0x33, 0x3d, 0x61, 0xbe, 0xe0, +0xb0, 0xd4, 0x1b, 0xb0, 0x5a, 0x6f, 0xb6, 0xbb, +0xfd, 0xe1, 0x08, 0xf6, 0xfb, 0x05, 0xa7, 0x33, +0x5f, 0xb8, 0x5c, 0x6f, 0x30, 0xca, 0x71, 0x87, +0xf4, 0x50, 0xf0, 0xd4, 0x4c, 0xc8, 0x02, 0xaf, +0xe1, 0x1b, 0xda, 0xc7, 0x04, 0x5d, 0x7e, 0x87, +0x7d, 0x01, 0x67, 0x1b, 0x12, 0x46, 0x9d, 0x00, +0xe4, 0xe9, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_execfile_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_execfile_png = new wxImage(); + if (!img_query_execfile_png || !img_query_execfile_png->IsOk()) + { + wxMemoryInputStream img_query_execfile_pngIS(query_execfile_png_data, sizeof(query_execfile_png_data)); + img_query_execfile_png->LoadFile(img_query_execfile_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_execfile_png; +} +#define query_execfile_png_img query_execfile_png_img() + +static wxBitmap *query_execfile_png_bmp() +{ + static wxBitmap *bmp_query_execfile_png; + if (!bmp_query_execfile_png || !bmp_query_execfile_png->IsOk()) + bmp_query_execfile_png = new wxBitmap(*query_execfile_png_img); + return bmp_query_execfile_png; +} +#define query_execfile_png_bmp query_execfile_png_bmp() + +static wxIcon *query_execfile_png_ico() +{ + static wxIcon *ico_query_execfile_png; + if (!ico_query_execfile_png || !ico_query_execfile_png->IsOk()) + { + ico_query_execfile_png = new wxIcon(); + ico_query_execfile_png->CopyFromBitmap(*query_execfile_png_bmp); + } + return ico_query_execfile_png; +} +#define query_execfile_png_ico query_execfile_png_ico() + +#endif // QUERY_EXECFILE_PNG_H diff --git a/include/images/query_execute.png b/include/images/query_execute.png new file mode 100644 index 0000000..23c8dcb Binary files /dev/null and b/include/images/query_execute.png differ diff --git a/include/images/query_execute.pngc b/include/images/query_execute.pngc new file mode 100644 index 0000000..ca32fe4 --- /dev/null +++ b/include/images/query_execute.pngc @@ -0,0 +1,95 @@ +#ifndef QUERY_EXECUTE_PNG_H +#define QUERY_EXECUTE_PNG_H + +static const unsigned char query_execute_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0xaf, 0xcc, 0x63, +0xaf, 0xcc, 0x64, 0xa9, 0xc8, 0x56, 0x94, 0xbb, +0x2f, 0xb1, 0xcd, 0x69, 0xaa, 0xc8, 0x5a, 0x8e, +0xb7, 0x26, 0x97, 0xbc, 0x38, 0xb4, 0xcf, 0x70, +0xab, 0xc9, 0x5e, 0x90, 0xb8, 0x2c, 0x92, 0xb9, +0x31, 0x9b, 0xbf, 0x43, 0xb6, 0xd1, 0x78, 0xad, +0xcb, 0x62, 0x92, 0xba, 0x33, 0x94, 0xbb, 0x38, +0x96, 0xbc, 0x3d, 0xa5, 0xc5, 0x5a, 0xcc, 0xdf, +0xa3, 0xae, 0xcb, 0x67, 0x95, 0xbb, 0x39, 0x96, +0xbd, 0x3e, 0x9e, 0xc2, 0x4f, 0xba, 0xd3, 0x81, +0xb0, 0xcd, 0x6c, 0x97, 0xbd, 0x40, 0x9f, 0xc2, +0x51, 0xba, 0xd3, 0x83, 0xb2, 0xce, 0x71, 0x9f, +0xc3, 0x53, 0xba, 0xd4, 0x83, 0xba, 0xd4, 0x85, +0xce, 0xe0, 0xa7, 0x9d, 0xfc, 0x84, 0xf4, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x57, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x06, 0x18, +0x99, 0x18, 0x51, 0x05, 0x98, 0x98, 0xd1, 0x44, +0x98, 0x58, 0x58, 0x51, 0x45, 0x98, 0xd8, 0xd8, +0x39, 0x50, 0x44, 0x98, 0x38, 0xb9, 0xb8, 0x79, +0x90, 0x45, 0x98, 0x78, 0xf9, 0xf8, 0x05, 0x04, +0x91, 0x44, 0x98, 0x84, 0x84, 0x45, 0x44, 0xc5, +0xc4, 0x99, 0x10, 0x02, 0x12, 0x92, 0x52, 0xd2, +0x32, 0xc8, 0x2a, 0x64, 0xe5, 0xe4, 0x15, 0x50, +0xcc, 0x50, 0x54, 0x52, 0x46, 0xb5, 0x45, 0x46, +0x05, 0xcd, 0x1d, 0xaa, 0x68, 0x2e, 0xc5, 0xf0, +0x0b, 0x5e, 0x00, 0x00, 0x89, 0x7c, 0x03, 0x17, +0x05, 0x8e, 0xad, 0x66, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_execute_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_execute_png = new wxImage(); + if (!img_query_execute_png || !img_query_execute_png->IsOk()) + { + wxMemoryInputStream img_query_execute_pngIS(query_execute_png_data, sizeof(query_execute_png_data)); + img_query_execute_png->LoadFile(img_query_execute_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_execute_png; +} +#define query_execute_png_img query_execute_png_img() + +static wxBitmap *query_execute_png_bmp() +{ + static wxBitmap *bmp_query_execute_png; + if (!bmp_query_execute_png || !bmp_query_execute_png->IsOk()) + bmp_query_execute_png = new wxBitmap(*query_execute_png_img); + return bmp_query_execute_png; +} +#define query_execute_png_bmp query_execute_png_bmp() + +static wxIcon *query_execute_png_ico() +{ + static wxIcon *ico_query_execute_png; + if (!ico_query_execute_png || !ico_query_execute_png->IsOk()) + { + ico_query_execute_png = new wxIcon(); + ico_query_execute_png->CopyFromBitmap(*query_execute_png_bmp); + } + return ico_query_execute_png; +} +#define query_execute_png_ico query_execute_png_ico() + +#endif // QUERY_EXECUTE_PNG_H diff --git a/include/images/query_explain.png b/include/images/query_explain.png new file mode 100644 index 0000000..986aa8a Binary files /dev/null and b/include/images/query_explain.png differ diff --git a/include/images/query_explain.pngc b/include/images/query_explain.pngc new file mode 100644 index 0000000..7aa5059 --- /dev/null +++ b/include/images/query_explain.pngc @@ -0,0 +1,101 @@ +#ifndef QUERY_EXPLAIN_PNG_H +#define QUERY_EXPLAIN_PNG_H + +static const unsigned char query_explain_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x84, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc8, 0xac, 0x62, 0xc2, +0x93, 0x15, 0xeb, 0xdb, 0x9a, 0xe7, 0xd3, 0x73, +0xec, 0xda, 0x68, 0xf5, 0xe8, 0x85, 0xe6, 0xcd, +0x36, 0xed, 0xd6, 0x27, 0xf7, 0xe8, 0x51, 0xf1, +0xe3, 0x8d, 0xf2, 0xe0, 0x5d, 0xfd, 0xf2, 0x74, +0xa0, 0x85, 0x3c, 0x7f, 0x77, 0x63, 0x81, 0x81, +0x81, 0xc5, 0xda, 0xe2, 0x82, 0x87, 0x88, 0xb7, +0xb7, 0xb7, 0x99, 0x99, 0x99, 0x72, 0x72, 0x72, +0xd5, 0xef, 0xf8, 0xb5, 0xc6, 0xcd, 0x82, 0x86, +0x88, 0xd3, 0xed, 0xf8, 0x95, 0x9e, 0xa2, 0x93, +0x80, 0x4c, 0xd5, 0xee, 0xf8, 0xc4, 0xd9, 0xe2, +0xd2, 0xec, 0xf9, 0x94, 0x9e, 0xa3, 0xd4, 0xed, +0xf8, 0xc2, 0xd8, 0xe3, 0x90, 0x90, 0x90, 0xb2, +0xc5, 0xce, 0xb2, 0xc4, 0xce, 0x81, 0x86, 0x88, +0xcf, 0xea, 0xf9, 0x93, 0x9d, 0xa3, 0x7c, 0x7e, +0x80, 0xb2, 0xc3, 0xce, 0xc0, 0xd6, 0xe3, 0xce, +0xe9, 0xfa, 0xcd, 0xe9, 0xfa, 0x0b, 0xc0, 0xe8, +0x25, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7a, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x55, 0xcf, 0xcb, +0x16, 0x82, 0x30, 0x0c, 0x45, 0xd1, 0xb4, 0xa2, +0x88, 0x88, 0xc5, 0x72, 0x85, 0x52, 0x44, 0x05, +0x04, 0x1f, 0xfc, 0xff, 0xff, 0xe9, 0xa8, 0x69, +0x32, 0xbc, 0x83, 0x7d, 0x56, 0x48, 0xe9, 0xff, +0x29, 0xe2, 0xd3, 0x9b, 0x64, 0xbb, 0xd3, 0xf1, +0x90, 0xa4, 0xfb, 0x4c, 0x0c, 0x87, 0x3c, 0x3b, +0xc6, 0x83, 0xd2, 0xc5, 0xa9, 0x88, 0x0d, 0x22, +0x53, 0x9e, 0x6d, 0x85, 0x8a, 0x75, 0x5c, 0xea, +0x06, 0xae, 0xf5, 0x41, 0x47, 0x57, 0x5f, 0x9d, +0xeb, 0x11, 0x74, 0x74, 0x30, 0xe8, 0x6f, 0x3e, +0xe8, 0xb8, 0x83, 0xa4, 0xe1, 0x40, 0xb2, 0xf2, +0x68, 0x64, 0x65, 0x18, 0xa7, 0x27, 0xe6, 0x85, +0x2b, 0xf6, 0xf5, 0xfe, 0xcc, 0xdf, 0x95, 0x2b, +0x64, 0x07, 0x83, 0x75, 0xf1, 0xe2, 0x07, 0x36, +0x7e, 0x70, 0x8c, 0x08, 0x96, 0x85, 0x6a, 0x4b, +0x1c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_explain_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_explain_png = new wxImage(); + if (!img_query_explain_png || !img_query_explain_png->IsOk()) + { + wxMemoryInputStream img_query_explain_pngIS(query_explain_png_data, sizeof(query_explain_png_data)); + img_query_explain_png->LoadFile(img_query_explain_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_explain_png; +} +#define query_explain_png_img query_explain_png_img() + +static wxBitmap *query_explain_png_bmp() +{ + static wxBitmap *bmp_query_explain_png; + if (!bmp_query_explain_png || !bmp_query_explain_png->IsOk()) + bmp_query_explain_png = new wxBitmap(*query_explain_png_img); + return bmp_query_explain_png; +} +#define query_explain_png_bmp query_explain_png_bmp() + +static wxIcon *query_explain_png_ico() +{ + static wxIcon *ico_query_explain_png; + if (!ico_query_explain_png || !ico_query_explain_png->IsOk()) + { + ico_query_explain_png = new wxIcon(); + ico_query_explain_png->CopyFromBitmap(*query_explain_png_bmp); + } + return ico_query_explain_png; +} +#define query_explain_png_ico query_explain_png_ico() + +#endif // QUERY_EXPLAIN_PNG_H diff --git a/include/images/query_pgscript.png b/include/images/query_pgscript.png new file mode 100644 index 0000000..c212ca5 Binary files /dev/null and b/include/images/query_pgscript.png differ diff --git a/include/images/query_pgscript.pngc b/include/images/query_pgscript.pngc new file mode 100644 index 0000000..36e5dbd --- /dev/null +++ b/include/images/query_pgscript.pngc @@ -0,0 +1,101 @@ +#ifndef QUERY_PGSCRIPT_PNG_H +#define QUERY_PGSCRIPT_PNG_H + +static const unsigned char query_pgscript_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x7b, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xc5, 0xda, 0x8d, 0x00, 0x00, 0x66, +0xaf, 0xcc, 0x63, 0xaf, 0xcc, 0x64, 0xa9, 0xc8, +0x56, 0x94, 0xbb, 0x2f, 0xb1, 0xcd, 0x69, 0xaa, +0xc8, 0x5a, 0x8e, 0xb7, 0x26, 0x97, 0xbc, 0x38, +0xb4, 0xcf, 0x70, 0xab, 0xc9, 0x5e, 0x90, 0xb8, +0x2c, 0x92, 0xb9, 0x31, 0x9b, 0xbf, 0x43, 0xb6, +0xd1, 0x78, 0xad, 0xcb, 0x62, 0x92, 0xba, 0x33, +0x94, 0xbb, 0x38, 0x96, 0xbc, 0x3d, 0xa5, 0xc5, +0x5a, 0xcc, 0xdf, 0xa3, 0xae, 0xcb, 0x67, 0x95, +0xbb, 0x39, 0x96, 0xbd, 0x3e, 0x9e, 0xc2, 0x4f, +0xba, 0xd3, 0x81, 0xb0, 0xcd, 0x6c, 0x97, 0xbd, +0x40, 0x9f, 0xc2, 0x51, 0xba, 0xd3, 0x83, 0xb2, +0xce, 0x71, 0x9f, 0xc3, 0x53, 0xba, 0xd4, 0x83, +0x00, 0x66, 0x00, 0x99, 0x00, 0x00, 0xba, 0xd4, +0x85, 0xce, 0xe0, 0xa7, 0x2f, 0x35, 0x67, 0xc3, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7e, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x65, 0x8f, 0xe7, 0x12, +0xc2, 0x30, 0x0c, 0x83, 0x15, 0x51, 0xf6, 0x2a, +0x7b, 0x96, 0x51, 0x70, 0xe0, 0xfd, 0x9f, 0x10, +0x57, 0x6d, 0x8e, 0x72, 0xe8, 0xf4, 0xc7, 0x9f, +0x65, 0x27, 0x46, 0x60, 0xc0, 0x8f, 0xd8, 0x69, +0x48, 0xe6, 0x12, 0xe8, 0xf6, 0x12, 0x91, 0xc1, +0xfe, 0x60, 0x58, 0x93, 0x04, 0x46, 0xe3, 0xc9, +0x54, 0x24, 0x8d, 0xcc, 0xe6, 0xf9, 0x62, 0x59, +0x91, 0xac, 0x59, 0xba, 0x5a, 0x6f, 0xb6, 0xbb, +0x3d, 0x53, 0x00, 0x3c, 0x1c, 0x4f, 0xe7, 0xa2, +0xf5, 0x36, 0x2f, 0xd7, 0xdb, 0xbd, 0xfd, 0x17, +0x96, 0x8f, 0x27, 0x83, 0x99, 0x01, 0xd1, 0xe5, +0xa0, 0x78, 0x79, 0xad, 0x5e, 0x94, 0xf9, 0xf6, +0x7c, 0x0d, 0x50, 0x05, 0xa0, 0x5b, 0x0c, 0x9a, +0x51, 0x42, 0x32, 0x39, 0x7e, 0x01, 0xd4, 0xd7, +0xce, 0x3f, 0x7d, 0x00, 0x1c, 0xed, 0x07, 0x6f, +0x41, 0x27, 0xa7, 0x0b, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_pgscript_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_pgscript_png = new wxImage(); + if (!img_query_pgscript_png || !img_query_pgscript_png->IsOk()) + { + wxMemoryInputStream img_query_pgscript_pngIS(query_pgscript_png_data, sizeof(query_pgscript_png_data)); + img_query_pgscript_png->LoadFile(img_query_pgscript_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_pgscript_png; +} +#define query_pgscript_png_img query_pgscript_png_img() + +static wxBitmap *query_pgscript_png_bmp() +{ + static wxBitmap *bmp_query_pgscript_png; + if (!bmp_query_pgscript_png || !bmp_query_pgscript_png->IsOk()) + bmp_query_pgscript_png = new wxBitmap(*query_pgscript_png_img); + return bmp_query_pgscript_png; +} +#define query_pgscript_png_bmp query_pgscript_png_bmp() + +static wxIcon *query_pgscript_png_ico() +{ + static wxIcon *ico_query_pgscript_png; + if (!ico_query_pgscript_png || !ico_query_pgscript_png->IsOk()) + { + ico_query_pgscript_png = new wxIcon(); + ico_query_pgscript_png->CopyFromBitmap(*query_pgscript_png_bmp); + } + return ico_query_pgscript_png; +} +#define query_pgscript_png_ico query_pgscript_png_ico() + +#endif // QUERY_PGSCRIPT_PNG_H diff --git a/include/images/query_rollback.png b/include/images/query_rollback.png new file mode 100644 index 0000000..b78ce61 Binary files /dev/null and b/include/images/query_rollback.png differ diff --git a/include/images/query_rollback.pngc b/include/images/query_rollback.pngc new file mode 100644 index 0000000..fa2f64b --- /dev/null +++ b/include/images/query_rollback.pngc @@ -0,0 +1,117 @@ +#ifndef QUERY_ROLLBACK_PNG_H +#define QUERY_ROLLBACK_PNG_H + +static const unsigned char query_rollback_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, +0x61, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x0e, 0xc2, 0x00, 0x00, 0x0e, +0xc2, 0x01, 0x15, 0x28, 0x4a, 0x80, 0x00, 0x00, +0x00, 0x18, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, +0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x70, +0x61, 0x69, 0x6e, 0x74, 0x2e, 0x6e, 0x65, 0x74, +0x20, 0x34, 0x2e, 0x30, 0x2e, 0x35, 0x65, 0x85, +0x32, 0x65, 0x00, 0x00, 0x01, 0xc5, 0x49, 0x44, +0x41, 0x54, 0x38, 0x4f, 0x85, 0x91, 0xdd, 0x4b, +0x53, 0x71, 0x18, 0xc7, 0xfd, 0x1f, 0xfa, 0x1f, +0xbc, 0x12, 0x52, 0x02, 0x9d, 0x88, 0x11, 0x74, +0xa7, 0xe0, 0x4b, 0xdd, 0x0d, 0xf1, 0xc2, 0xa8, +0x48, 0xba, 0xe8, 0x42, 0x21, 0xf0, 0x4a, 0xeb, +0x5a, 0x6c, 0xd9, 0x71, 0x63, 0x90, 0x61, 0x78, +0xa1, 0x36, 0x37, 0xc2, 0xb7, 0xcd, 0xb3, 0xca, +0xf9, 0x92, 0xb2, 0xa4, 0x62, 0x37, 0xa5, 0x8e, +0xe3, 0x9c, 0x2f, 0x9d, 0x39, 0xbd, 0x70, 0x03, +0x4d, 0xa8, 0x4f, 0xfb, 0x1d, 0x77, 0x7e, 0xed, +0xb4, 0x33, 0x7b, 0xe0, 0xcb, 0xe1, 0xf7, 0x3c, +0xdf, 0xef, 0x87, 0x87, 0xe7, 0x94, 0x01, 0xb6, +0x72, 0x7a, 0xaf, 0xd0, 0xe5, 0x69, 0x40, 0x7c, +0xff, 0x9d, 0x15, 0xca, 0xb6, 0x69, 0x86, 0x3f, +0x69, 0xaf, 0xff, 0x0b, 0x29, 0x6a, 0x98, 0xe1, +0x99, 0xaf, 0x8f, 0x19, 0x5d, 0x76, 0x12, 0x8a, +0xf5, 0x5e, 0x0a, 0xb1, 0x3c, 0xcc, 0xf0, 0xd4, +0xe7, 0x47, 0x78, 0xdf, 0xdf, 0x44, 0x51, 0xeb, +0x79, 0x19, 0x69, 0xce, 0x41, 0x9e, 0x94, 0x84, +0x14, 0x85, 0x07, 0xe7, 0xaf, 0xd2, 0x3f, 0x5b, +0xce, 0xc0, 0x5c, 0x05, 0xae, 0xd0, 0x35, 0x5e, +0xcc, 0xd7, 0x32, 0x14, 0xbe, 0xc1, 0xf0, 0xe2, +0x6d, 0x5b, 0x88, 0x05, 0x60, 0xca, 0x6e, 0x83, +0xc2, 0xb9, 0x99, 0x11, 0xb2, 0x54, 0x6c, 0xf9, +0x99, 0x61, 0x18, 0x52, 0x1d, 0xb8, 0x82, 0x55, +0xb9, 0x6d, 0x1c, 0x28, 0xe1, 0xeb, 0x0c, 0x47, +0x5a, 0x8d, 0x7e, 0xde, 0x26, 0xcb, 0x02, 0x78, +0xeb, 0xad, 0x63, 0x65, 0xea, 0x81, 0x61, 0x1c, +0x5f, 0x75, 0x32, 0xb1, 0xd6, 0x8e, 0x2f, 0xda, +0xc1, 0x64, 0xf4, 0x3e, 0x81, 0xf5, 0x87, 0x46, +0x5f, 0xf5, 0xdd, 0xc2, 0xef, 0xae, 0x96, 0x29, +0x09, 0x58, 0xf0, 0xdd, 0x21, 0xfe, 0xc5, 0x03, +0xbf, 0x8e, 0x0d, 0x63, 0x29, 0x69, 0x9a, 0x97, +0x8f, 0x6a, 0x27, 0xc2, 0x2f, 0x72, 0x12, 0x10, +0x70, 0xd7, 0xb1, 0x16, 0x6c, 0x23, 0xb6, 0x7a, +0x8f, 0xa3, 0xf8, 0x34, 0x99, 0xfd, 0x77, 0x17, +0x3a, 0xf4, 0xa3, 0x27, 0x9e, 0x4b, 0x89, 0xb9, +0xf0, 0xcd, 0x8d, 0x34, 0x59, 0x01, 0x6f, 0x5c, +0x95, 0x24, 0x37, 0xc3, 0xe8, 0x5b, 0x41, 0x16, +0x03, 0x9d, 0xcc, 0xbe, 0x6a, 0xc4, 0xaf, 0xd4, +0x48, 0x89, 0xb7, 0xe8, 0xa7, 0xf5, 0x25, 0x52, +0x3b, 0x21, 0x84, 0x5f, 0xe4, 0x2c, 0x80, 0xbd, +0x78, 0x84, 0x6c, 0xea, 0x1b, 0x9c, 0x65, 0xe0, +0xf4, 0x98, 0xdf, 0xd9, 0x18, 0xd9, 0xf4, 0x34, +0x87, 0x09, 0x37, 0xdb, 0x1b, 0x3d, 0x68, 0x1b, +0x4f, 0xd9, 0x4d, 0x28, 0xfc, 0x48, 0x4e, 0x94, +0x06, 0x9c, 0xa4, 0xbe, 0xc3, 0x79, 0x16, 0x7e, +0x5e, 0x00, 0x32, 0xfa, 0x0c, 0xe9, 0x03, 0xc5, +0x00, 0x24, 0xb6, 0x72, 0x00, 0x4d, 0x41, 0xdf, +0x1d, 0xb7, 0x07, 0x44, 0xd5, 0xbe, 0xfc, 0x06, +0x27, 0x12, 0x60, 0x6c, 0x90, 0x2c, 0xd8, 0x40, +0x73, 0xb3, 0xfe, 0xa1, 0xbb, 0x18, 0x20, 0x2a, +0xe0, 0xa9, 0x25, 0x32, 0x79, 0x97, 0xcd, 0x95, +0xc1, 0xbf, 0x87, 0xcc, 0x1f, 0xd1, 0x3c, 0x5e, +0x78, 0xac, 0x25, 0xf7, 0x1b, 0x1d, 0x32, 0x65, +0x01, 0x98, 0x75, 0xd9, 0x11, 0xf3, 0x16, 0x59, +0x40, 0xd9, 0x1f, 0xfc, 0xa3, 0x79, 0xae, 0xb1, +0x5a, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *query_rollback_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_query_rollback_png = new wxImage(); + if (!img_query_rollback_png || !img_query_rollback_png->IsOk()) + { + wxMemoryInputStream img_query_rollback_pngIS(query_rollback_png_data, sizeof(query_rollback_png_data)); + img_query_rollback_png->LoadFile(img_query_rollback_pngIS, wxBITMAP_TYPE_PNG); + } + return img_query_rollback_png; +} +#define query_rollback_png_img query_rollback_png_img() + +static wxBitmap *query_rollback_png_bmp() +{ + static wxBitmap *bmp_query_rollback_png; + if (!bmp_query_rollback_png || !bmp_query_rollback_png->IsOk()) + bmp_query_rollback_png = new wxBitmap(*query_rollback_png_img); + return bmp_query_rollback_png; +} +#define query_rollback_png_bmp query_rollback_png_bmp() + +static wxIcon *query_rollback_png_ico() +{ + static wxIcon *ico_query_rollback_png; + if (!ico_query_rollback_png || !ico_query_rollback_png->IsOk()) + { + ico_query_rollback_png = new wxIcon(); + ico_query_rollback_png->CopyFromBitmap(*query_rollback_png_bmp); + } + return ico_query_rollback_png; +} +#define query_rollback_png_ico query_rollback_png_ico() + +#endif // QUERY_ROLLBACK_PNG_H diff --git a/include/images/readdata.png b/include/images/readdata.png new file mode 100644 index 0000000..fd9aa5a Binary files /dev/null and b/include/images/readdata.png differ diff --git a/include/images/readdata.pngc b/include/images/readdata.pngc new file mode 100644 index 0000000..4ac7a3c --- /dev/null +++ b/include/images/readdata.pngc @@ -0,0 +1,147 @@ +#ifndef READDATA_PNG_H +#define READDATA_PNG_H + +static const unsigned char readdata_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xcf, 0xb8, 0xb8, 0xcd, +0x75, 0x75, 0xcb, 0x3b, 0x3b, 0xca, 0x11, 0x11, +0xce, 0x96, 0x96, 0xce, 0x17, 0x15, 0xde, 0x57, +0x4f, 0xea, 0x84, 0x74, 0xf2, 0x9d, 0x85, 0xf2, +0x9b, 0x82, 0xeb, 0x80, 0x70, 0xdf, 0x54, 0x4c, +0xcf, 0x16, 0x13, 0xcc, 0x56, 0x56, 0xc9, 0x00, +0x00, 0xd4, 0x2c, 0x28, 0xe9, 0x7f, 0x70, 0xf4, +0x99, 0x7a, 0xf3, 0x88, 0x63, 0xf2, 0x7f, 0x57, +0xf3, 0x7b, 0x51, 0xf5, 0x7e, 0x55, 0xf7, 0x8b, +0x65, 0xeb, 0x76, 0x63, 0xd4, 0x2a, 0x24, 0xfc, +0xb5, 0x9d, 0xf3, 0x91, 0x70, 0xf3, 0x85, 0x60, +0xf5, 0x8a, 0x66, 0xf6, 0x91, 0x6f, 0xf6, 0x8e, +0x6a, 0xf6, 0x80, 0x57, 0xf7, 0x72, 0x44, 0xf8, +0x7a, 0x4d, 0xe7, 0x5d, 0x49, 0xfa, 0x80, 0x55, +0xfc, 0x8f, 0x69, 0xf8, 0xb8, 0xa2, 0xf6, 0xa3, +0x88, 0xf2, 0x98, 0x80, 0xe1, 0x5f, 0x55, 0xd1, +0x1f, 0x1c, 0xf5, 0x78, 0x54, 0xf9, 0x68, 0x35, +0xfa, 0x5f, 0x2a, 0xfb, 0x57, 0x1e, 0xfc, 0x80, +0x55, 0xd0, 0xca, 0xca, 0xca, 0x15, 0x15, 0xcd, +0x68, 0x68, 0xcf, 0xae, 0xae, 0xe2, 0x4d, 0x3c, +0xfa, 0x63, 0x2e, 0xfb, 0x52, 0x17, 0xfc, 0x4f, +0x12, 0xfd, 0x7d, 0x50, 0xfb, 0x84, 0x5a, 0xfc, +0x4d, 0x10, 0xfd, 0x4b, 0x0c, 0xfe, 0x7b, 0x4d, +0x9e, 0xcc, 0x56, 0x7b, 0xc9, 0x00, 0xfd, 0xb1, +0x97, 0xfd, 0x8b, 0x64, 0xfd, 0x7d, 0x51, 0xfe, +0x7c, 0x4e, 0xfe, 0xa0, 0x7f, 0xd9, 0xf2, 0x85, +0xca, 0xed, 0x56, 0xd0, 0xef, 0x67, 0xdf, 0xf5, +0x99, 0xb6, 0xe6, 0x17, 0xb9, 0xe8, 0x20, 0xcb, +0xee, 0x5c, 0xb7, 0xe7, 0x18, 0xbe, 0xeb, 0x32, +0xa8, 0xdd, 0x3d, 0xc2, 0xcf, 0xae, 0xa6, 0xcd, +0x68, 0x84, 0xca, 0x15, 0xce, 0xd0, 0xca, 0xcb, +0xee, 0x59, 0xbd, 0xea, 0x2c, 0xc0, 0xeb, 0x37, +0xc4, 0xec, 0x54, 0xad, 0xdf, 0x4d, 0x8c, 0xd1, +0x1c, 0xaf, 0xe1, 0x55, 0xd0, 0xf2, 0x80, 0xd8, +0xf7, 0x88, 0xe1, 0xfa, 0xa3, 0xaa, 0xdf, 0x4f, +0xab, 0xcd, 0x75, 0xd1, 0xf0, 0x6c, 0xca, 0xef, +0x57, 0xb5, 0xe5, 0x46, 0xc7, 0xef, 0x4e, 0xc4, +0xef, 0x44, 0xc9, 0xf1, 0x57, 0xcf, 0xf4, 0x6a, +0xd0, 0xf5, 0x6f, 0xce, 0xf5, 0x66, 0xcb, 0xf6, +0x60, 0xd1, 0xf7, 0x71, 0xc1, 0xec, 0x72, 0x87, +0xcf, 0x15, 0xc6, 0xcf, 0xb8, 0xe0, 0xf6, 0x9e, +0x92, 0xd3, 0x24, 0xbe, 0xe7, 0x63, 0xce, 0xf3, +0x65, 0xc8, 0xf2, 0x55, 0xc7, 0xf3, 0x52, 0xc9, +0xf4, 0x57, 0xcd, 0xf6, 0x64, 0xd4, 0xf9, 0x7c, +0x93, 0xd4, 0x29, 0xb8, 0xce, 0x96, 0x87, 0xce, +0x13, 0xa9, 0xde, 0x4c, 0xc3, 0xeb, 0x70, 0xd2, +0xf4, 0x82, 0xd4, 0xf5, 0x86, 0xc4, 0xed, 0x76, +0xab, 0xdf, 0x50, 0x93, 0xcb, 0x3b, 0x82, 0xca, +0x11, 0xee, 0xba, 0xb3, 0x8b, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xea, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, 0x26, 0x66, +0x16, 0x16, 0x66, 0x26, 0x46, 0x06, 0x28, 0x60, +0x65, 0x63, 0xe7, 0xe0, 0xe4, 0xe2, 0xe6, 0xe1, +0x65, 0xe5, 0xe3, 0xe7, 0x03, 0xf1, 0x05, 0x04, +0x85, 0x84, 0x45, 0x44, 0xc5, 0xc4, 0x25, 0x24, +0xf9, 0xa5, 0xf8, 0x81, 0xea, 0xd9, 0x04, 0xa5, +0x65, 0x64, 0xe5, 0xe4, 0x15, 0x14, 0x95, 0x94, +0x55, 0x54, 0x81, 0x02, 0x4c, 0xec, 0x6a, 0xea, +0x1a, 0x9a, 0x5a, 0x5a, 0xec, 0xda, 0x3a, 0xba, +0x7a, 0xfa, 0x40, 0x01, 0x03, 0x3e, 0x7e, 0x7e, +0x43, 0x23, 0x63, 0x63, 0x3e, 0x13, 0x53, 0x33, +0x73, 0x0b, 0x7e, 0x98, 0xc1, 0x0c, 0x7c, 0xfc, +0x96, 0x7a, 0x56, 0xd6, 0x36, 0xfc, 0x0c, 0xb6, +0x76, 0x60, 0x60, 0xcb, 0x6f, 0xef, 0xe0, 0xe8, +0x64, 0xe3, 0xcc, 0xcf, 0x60, 0xe7, 0xe2, 0xea, +0xea, 0xea, 0xe6, 0x6e, 0x07, 0xd4, 0x08, 0x02, +0x7c, 0x0c, 0x76, 0xae, 0x1e, 0x1e, 0x9e, 0x5e, +0x76, 0xb6, 0x70, 0xbd, 0x76, 0xae, 0xde, 0xde, +0x3e, 0xbe, 0xb6, 0x7e, 0x7e, 0xfe, 0x01, 0x40, +0x8d, 0x81, 0x40, 0x81, 0x20, 0xcf, 0xe0, 0x90, +0xd0, 0xb0, 0xf0, 0xf0, 0x88, 0xc8, 0xa8, 0xe8, +0x98, 0x58, 0xa0, 0x40, 0x5c, 0x7c, 0x42, 0x62, +0x52, 0x72, 0x4a, 0x6a, 0x5a, 0x7a, 0x46, 0x66, +0x56, 0x36, 0x50, 0x20, 0xc7, 0x2e, 0x37, 0x2f, +0xbf, 0xa0, 0xb0, 0xa8, 0xb8, 0x24, 0xb3, 0xb4, +0x0c, 0x68, 0x86, 0xad, 0x9d, 0x6d, 0x59, 0x79, +0x45, 0x65, 0x55, 0x75, 0x4d, 0x6d, 0x56, 0x19, +0xcc, 0xe0, 0xec, 0xd8, 0xba, 0xfa, 0xfa, 0xba, +0xd8, 0x6c, 0x10, 0x1b, 0x00, 0xe2, 0x22, 0x2e, +0x84, 0x11, 0x16, 0xcf, 0x75, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *readdata_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_readdata_png = new wxImage(); + if (!img_readdata_png || !img_readdata_png->IsOk()) + { + wxMemoryInputStream img_readdata_pngIS(readdata_png_data, sizeof(readdata_png_data)); + img_readdata_png->LoadFile(img_readdata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_readdata_png; +} +#define readdata_png_img readdata_png_img() + +static wxBitmap *readdata_png_bmp() +{ + static wxBitmap *bmp_readdata_png; + if (!bmp_readdata_png || !bmp_readdata_png->IsOk()) + bmp_readdata_png = new wxBitmap(*readdata_png_img); + return bmp_readdata_png; +} +#define readdata_png_bmp readdata_png_bmp() + +static wxIcon *readdata_png_ico() +{ + static wxIcon *ico_readdata_png; + if (!ico_readdata_png || !ico_readdata_png->IsOk()) + { + ico_readdata_png = new wxIcon(); + ico_readdata_png->CopyFromBitmap(*readdata_png_bmp); + } + return ico_readdata_png; +} +#define readdata_png_ico readdata_png_ico() + +#endif // READDATA_PNG_H diff --git a/include/images/refresh.png b/include/images/refresh.png new file mode 100644 index 0000000..4c7b134 Binary files /dev/null and b/include/images/refresh.png differ diff --git a/include/images/refresh.pngc b/include/images/refresh.pngc new file mode 100644 index 0000000..a318ae9 --- /dev/null +++ b/include/images/refresh.pngc @@ -0,0 +1,193 @@ +#ifndef REFRESH_PNG_H +#define REFRESH_PNG_H + +static const unsigned char refresh_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd4, 0xc9, 0xc0, 0xd2, +0x96, 0x90, 0xcf, 0x62, 0x5e, 0xd0, 0x36, 0x34, +0xcd, 0x18, 0x17, 0xcb, 0x0a, 0x0a, 0xd4, 0xbe, +0xb6, 0xd4, 0xc3, 0xbb, 0xd0, 0x77, 0x72, 0xd8, +0x42, 0x3e, 0xe4, 0x76, 0x70, 0xec, 0x93, 0x85, +0xf5, 0xa4, 0x8b, 0xf8, 0xac, 0x91, 0xf2, 0x9d, +0x86, 0xec, 0x8b, 0x7d, 0xdf, 0x60, 0x5b, 0xf4, +0x8d, 0x6b, 0xf4, 0x82, 0x5a, 0xf2, 0x76, 0x4b, +0xf4, 0x6f, 0x40, 0xfc, 0x94, 0x71, 0xf7, 0xbb, +0xb0, 0xf0, 0x78, 0x4f, 0xf2, 0x71, 0x44, 0xf4, +0x6b, 0x3c, 0xf5, 0x68, 0x36, 0xfb, 0x65, 0x31, +0xf6, 0x64, 0x31, 0xfa, 0x70, 0x3f, 0xf4, 0x88, +0x63, 0xed, 0x83, 0x73, 0xf3, 0x94, 0x7c, 0xc9, +0x00, 0x00, 0xcf, 0x70, 0x6b, 0xdc, 0x55, 0x52, +0xf1, 0x7c, 0x53, 0xf8, 0x60, 0x2b, 0xf9, 0x59, +0x21, 0xfb, 0x71, 0x42, 0xf6, 0x7a, 0x58, 0xfa, +0x54, 0x1a, 0xfb, 0x4f, 0x13, 0xfc, 0x92, 0x6c, +0xf6, 0x98, 0x77, 0xf7, 0x9d, 0x7d, 0xf8, 0x6f, +0x40, 0xfe, 0x90, 0x6a, 0xe0, 0x65, 0x60, 0xfd, +0x4b, 0x0d, 0xd2, 0xa5, 0x9e, 0xe3, 0x5a, 0x4c, +0xf9, 0x68, 0x37, 0xdb, 0x51, 0x4d, 0xf5, 0x99, +0x7e, 0xf4, 0x93, 0x71, 0xf9, 0xb1, 0x97, 0xfb, +0x9a, 0x77, 0xff, 0xc4, 0xaf, 0xce, 0x57, 0x54, +0xfa, 0xd0, 0xc3, 0xa3, 0xce, 0x5b, 0x7b, 0xc9, +0x00, 0x7e, 0xc9, 0x07, 0xd0, 0xd3, 0xbf, 0x82, +0xcc, 0x0e, 0xf5, 0xfd, 0xe3, 0xde, 0xfb, 0xa1, +0xe2, 0xfa, 0xa9, 0xc1, 0xd2, 0x9e, 0x96, 0xd1, +0x39, 0xda, 0xf9, 0x8d, 0xc4, 0xf5, 0x4a, 0xc6, +0xf9, 0x54, 0xcb, 0xfa, 0x61, 0xdd, 0xf6, 0xa8, +0x87, 0xca, 0x1b, 0xae, 0xcf, 0x71, 0xb5, 0xe1, +0x70, 0xd4, 0xf7, 0x7a, 0xc6, 0xf7, 0x50, 0xcf, +0xfa, 0x6d, 0xd2, 0xef, 0x9c, 0xdb, 0xf3, 0x8c, +0xdd, 0xf4, 0x94, 0xe9, 0xf8, 0xb9, 0xec, 0xf7, +0xdb, 0x89, 0xcf, 0x1b, 0xcd, 0xd3, 0xb9, 0xd0, +0xd3, 0xc0, 0xcd, 0xed, 0x93, 0xcd, 0xf7, 0x65, +0xc7, 0xf9, 0x57, 0xd5, 0xfc, 0x81, 0xc1, 0xe6, +0x86, 0xb7, 0xe6, 0x18, 0xb8, 0xe8, 0x1f, 0xba, +0xe9, 0x23, 0xc5, 0xee, 0x4b, 0xd9, 0xf1, 0x9f, +0xc8, 0xf7, 0x58, 0xa2, 0xd9, 0x4b, 0xbb, 0xd1, +0x90, 0xb8, 0xe7, 0x1b, 0xbc, 0xeb, 0x2a, 0xca, +0xee, 0x6a, 0xaa, 0xcf, 0x6b, 0xab, 0xdc, 0x5c, +0xd5, 0xf4, 0x91, 0xc8, 0xfa, 0x5a, 0xd0, 0xfc, +0x75, 0xd3, 0xf1, 0x9d, 0xbd, 0xed, 0x32, 0xde, +0xfd, 0x9b, 0xc1, 0xef, 0x3d, 0xd1, 0xf6, 0x70, +0x85, 0xcd, 0x14, 0xc8, 0xf3, 0x54, 0xd8, 0xf6, +0x84, 0xdd, 0xf8, 0x97, 0xd8, 0xf6, 0xa0, 0xbf, +0xf0, 0x39, 0xc2, 0xf2, 0x42, 0xad, 0xdd, 0x60, +0xd3, 0xf1, 0x8c, 0xb0, 0xdf, 0x5f, 0xcb, 0xf2, +0x5b, 0xd9, 0x68, 0x05, 0x49, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x02, 0x5d, 0x49, 0x44, 0x41, 0x54, 0x38, +0xcb, 0x95, 0x91, 0xe7, 0x5f, 0xda, 0x40, 0x1c, +0xc6, 0x01, 0xb9, 0x2b, 0x41, 0x76, 0x02, 0xc6, +0x81, 0xb8, 0xa0, 0x95, 0x55, 0xd1, 0x0e, 0x6d, +0x2b, 0x23, 0x8c, 0x00, 0x81, 0x44, 0xc4, 0xc5, +0x56, 0x28, 0xe0, 0xa8, 0x28, 0x02, 0x0e, 0xd0, +0xfa, 0xaf, 0xf7, 0x12, 0x12, 0xa0, 0x2f, 0xfc, +0x7c, 0xda, 0xe7, 0xdd, 0xdd, 0xf3, 0xbd, 0xe7, +0x37, 0x4e, 0x26, 0xfb, 0x77, 0xc9, 0x15, 0x53, +0x4a, 0x00, 0x21, 0x50, 0x4e, 0x29, 0xe4, 0xc2, +0xc5, 0xbb, 0xbf, 0x6c, 0x15, 0x06, 0xd5, 0xd3, +0x1a, 0xad, 0x4e, 0xab, 0x37, 0x4c, 0xab, 0x21, +0xa6, 0x92, 0xc9, 0x30, 0x80, 0x4d, 0xf8, 0x0a, +0x60, 0xd4, 0x68, 0x4d, 0x38, 0x61, 0x36, 0x9b, +0x09, 0xdc, 0x62, 0x30, 0x42, 0x05, 0x06, 0x66, +0xc0, 0xd8, 0xc7, 0xd4, 0x06, 0x3d, 0x4e, 0xce, +0xce, 0x9a, 0xe7, 0xe6, 0xe6, 0x17, 0xac, 0xd6, +0x45, 0xdb, 0x92, 0x1a, 0x2c, 0xeb, 0x56, 0x46, +0xfe, 0xea, 0x9a, 0xde, 0x64, 0x27, 0x08, 0x1e, +0x98, 0x9f, 0xb7, 0x3a, 0x1c, 0xef, 0x1d, 0x1f, +0xd6, 0xd7, 0x17, 0x2c, 0x23, 0x00, 0x5b, 0xd3, +0xdb, 0x90, 0x4f, 0x08, 0x01, 0x56, 0x1e, 0x40, +0x72, 0xba, 0xdc, 0x12, 0xa0, 0x50, 0xeb, 0x6d, +0x24, 0x89, 0x00, 0xbb, 0xc9, 0xe3, 0xf5, 0xba, +0xf1, 0x8f, 0x08, 0x70, 0x3a, 0x5d, 0xae, 0x0d, +0x11, 0x50, 0x01, 0x83, 0xc9, 0x4e, 0x12, 0xa4, +0xdd, 0x63, 0xf0, 0x29, 0x21, 0x54, 0x1a, 0x97, +0x70, 0x07, 0x7a, 0xef, 0xda, 0x94, 0x00, 0xcc, +0xe8, 0xb5, 0x93, 0x24, 0x89, 0x2f, 0xfb, 0x20, +0xb6, 0x25, 0x97, 0x6f, 0x61, 0xf0, 0xd3, 0x67, +0xe7, 0x04, 0x20, 0x87, 0x1a, 0x9b, 0xe0, 0x7f, +0x59, 0x1d, 0xee, 0x07, 0x03, 0x26, 0x2b, 0x02, +0x36, 0x25, 0x40, 0xa1, 0xd6, 0xa2, 0x00, 0xbb, +0xc7, 0xb7, 0x2a, 0x06, 0x82, 0xaf, 0x8b, 0x42, +0x05, 0x09, 0x98, 0x9a, 0xde, 0xe6, 0x03, 0x0c, +0x50, 0xdc, 0x2f, 0x98, 0xd9, 0xf9, 0x66, 0xb1, +0x58, 0xdc, 0x1b, 0x1b, 0xdf, 0x87, 0x80, 0x92, +0xaf, 0x40, 0x6c, 0xfb, 0xa4, 0xbd, 0x62, 0x60, +0x45, 0xd2, 0x0f, 0xe1, 0x02, 0x68, 0x71, 0x04, +0x78, 0x95, 0x5b, 0x6f, 0x7d, 0x22, 0xdc, 0xdd, +0xd1, 0xe9, 0x74, 0xbb, 0x62, 0x05, 0x51, 0xfe, +0x00, 0xaf, 0xa0, 0x5f, 0xe8, 0x01, 0x4e, 0xc4, +0x89, 0x0a, 0x51, 0xe1, 0x48, 0x34, 0x1a, 0x0d, +0x07, 0xdf, 0x4a, 0x8d, 0xd1, 0xf1, 0x44, 0x22, +0xc9, 0xa4, 0xd2, 0xe3, 0x34, 0x5e, 0x69, 0x56, +0x02, 0x58, 0x6e, 0x2f, 0x93, 0x49, 0xee, 0x67, +0x69, 0xfe, 0x10, 0x08, 0x1f, 0x08, 0x3a, 0x3c, +0x3a, 0x3e, 0xc9, 0x0d, 0xfd, 0x3c, 0x55, 0x28, +0x66, 0x92, 0xa5, 0x72, 0x45, 0xe8, 0x21, 0x70, +0x70, 0x7a, 0x7a, 0x7a, 0x76, 0x56, 0xad, 0xfd, +0x3c, 0x61, 0x47, 0x01, 0xf1, 0x7a, 0xb2, 0xc4, +0x44, 0x1a, 0x4d, 0x11, 0x38, 0x3f, 0x3f, 0xab, +0x5e, 0x5c, 0x4a, 0x7e, 0xfe, 0xea, 0xd7, 0x75, +0x31, 0x59, 0x6a, 0xdd, 0xdc, 0x52, 0x79, 0x09, +0x40, 0x7e, 0xfb, 0x92, 0xa3, 0xd8, 0x58, 0x28, +0x14, 0x63, 0x29, 0xee, 0x7a, 0xbf, 0x54, 0x6a, +0x31, 0x77, 0xdc, 0xf0, 0x45, 0xe0, 0x00, 0xe5, +0x5f, 0x5c, 0xb4, 0x3b, 0xdd, 0x02, 0x47, 0x53, +0x14, 0xcd, 0x15, 0xe2, 0x4c, 0x1d, 0xf9, 0xe5, +0x42, 0x2f, 0x24, 0x01, 0x55, 0x14, 0x80, 0x88, +0xfb, 0xee, 0xc3, 0xe3, 0x63, 0x7c, 0xaf, 0x88, +0xea, 0xb7, 0x98, 0x9b, 0xa7, 0x61, 0x07, 0x3c, +0x50, 0xed, 0xd4, 0x6a, 0xed, 0x76, 0xbb, 0xdf, +0x1f, 0x0c, 0x06, 0x89, 0x04, 0x9a, 0x8f, 0xf7, +0x23, 0xcf, 0x52, 0xcb, 0x81, 0xc3, 0xda, 0xcb, +0xef, 0x97, 0xd7, 0x4e, 0xbf, 0xdf, 0x19, 0xfb, +0xe5, 0xa7, 0xe7, 0x2b, 0x69, 0x29, 0x81, 0x23, +0x34, 0x5f, 0xa3, 0xf0, 0x70, 0x3f, 0x7a, 0xcf, +0xdc, 0xdc, 0x15, 0x1a, 0xa3, 0xa5, 0xc9, 0xd2, +0xc7, 0x68, 0xbe, 0x66, 0x8f, 0xcb, 0xc6, 0xbb, +0xc5, 0x7a, 0xa6, 0xce, 0xec, 0x97, 0x23, 0xb7, +0x5c, 0xaf, 0x39, 0xde, 0x3b, 0x2b, 0xcc, 0x9f, +0x63, 0xa9, 0x46, 0x25, 0x9b, 0x8a, 0x46, 0x53, +0xd9, 0x4a, 0x83, 0x62, 0x73, 0x93, 0x3f, 0x23, +0x1e, 0x42, 0x4d, 0x3f, 0x9d, 0x0e, 0x06, 0xd3, +0xb4, 0xbf, 0x99, 0x97, 0xfd, 0x87, 0xfe, 0x00, +0x33, 0x42, 0x90, 0xe8, 0xdf, 0x34, 0x60, 0x87, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *refresh_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_refresh_png = new wxImage(); + if (!img_refresh_png || !img_refresh_png->IsOk()) + { + wxMemoryInputStream img_refresh_pngIS(refresh_png_data, sizeof(refresh_png_data)); + img_refresh_png->LoadFile(img_refresh_pngIS, wxBITMAP_TYPE_PNG); + } + return img_refresh_png; +} +#define refresh_png_img refresh_png_img() + +static wxBitmap *refresh_png_bmp() +{ + static wxBitmap *bmp_refresh_png; + if (!bmp_refresh_png || !bmp_refresh_png->IsOk()) + bmp_refresh_png = new wxBitmap(*refresh_png_img); + return bmp_refresh_png; +} +#define refresh_png_bmp refresh_png_bmp() + +static wxIcon *refresh_png_ico() +{ + static wxIcon *ico_refresh_png; + if (!ico_refresh_png || !ico_refresh_png->IsOk()) + { + ico_refresh_png = new wxIcon(); + ico_refresh_png->CopyFromBitmap(*refresh_png_bmp); + } + return ico_refresh_png; +} +#define refresh_png_ico refresh_png_ico() + +#endif // REFRESH_PNG_H diff --git a/include/images/reload.png b/include/images/reload.png new file mode 100644 index 0000000..4dd0e00 Binary files /dev/null and b/include/images/reload.png differ diff --git a/include/images/reload.pngc b/include/images/reload.pngc new file mode 100644 index 0000000..fd1d315 --- /dev/null +++ b/include/images/reload.pngc @@ -0,0 +1,90 @@ +#ifndef RELOAD_PNG_H +#define RELOAD_PNG_H + +static const unsigned char reload_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, +0x04, 0x03, 0x00, 0x00, 0x00, 0x12, 0x59, 0x20, +0xcb, 0x00, 0x00, 0x00, 0x1b, 0x50, 0x4c, 0x54, +0x45, 0xd6, 0xd3, 0xce, 0x63, 0x65, 0xce, 0x31, +0x30, 0x63, 0xc6, 0xc3, 0xc6, 0x9c, 0x9a, 0xff, +0x21, 0x20, 0x21, 0x00, 0x00, 0x84, 0xce, 0xcf, +0xff, 0x84, 0x82, 0x84, 0x7e, 0xd7, 0x45, 0xcb, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x99, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x8d, +0x8e, 0xb1, 0x0a, 0xc3, 0x20, 0x10, 0x86, 0x15, +0x3a, 0xb8, 0x9e, 0x51, 0xc8, 0x98, 0xdc, 0xd0, +0xbd, 0x50, 0xc8, 0x5c, 0xb0, 0xed, 0x2e, 0xd8, +0x07, 0x08, 0xc4, 0xbd, 0x20, 0xdc, 0x9a, 0xd1, +0xc7, 0xee, 0x69, 0x6c, 0xb2, 0x95, 0x7e, 0xd3, +0x7d, 0xfc, 0xff, 0x1d, 0x27, 0xc4, 0x2f, 0x24, +0x00, 0xe8, 0xaf, 0x74, 0xc6, 0xc0, 0x0b, 0x5b, +0x70, 0x75, 0xce, 0x86, 0x79, 0x28, 0xe3, 0x44, +0x89, 0x71, 0xd6, 0xd7, 0x12, 0x3d, 0x99, 0x7b, +0xa8, 0x3d, 0x39, 0x95, 0xc4, 0xc7, 0x6d, 0xa9, +0x23, 0x22, 0x7b, 0x6e, 0xc2, 0x5b, 0x6f, 0x1f, +0x9b, 0x70, 0x64, 0xc7, 0x5d, 0xe4, 0xc5, 0xcb, +0x5d, 0x04, 0x0e, 0x32, 0x2e, 0x78, 0x7c, 0xc4, +0xa2, 0xca, 0xc0, 0xc7, 0x28, 0x3d, 0x02, 0xaa, +0x95, 0x25, 0x39, 0xc6, 0x2e, 0x98, 0x0f, 0x09, +0x08, 0xa5, 0x96, 0x0c, 0x03, 0x5e, 0xf7, 0x45, +0x4e, 0x50, 0x19, 0x73, 0x3d, 0x75, 0xd3, 0x88, +0x33, 0xf6, 0xeb, 0x76, 0x58, 0xe5, 0x82, 0xf8, +0x97, 0x0f, 0x78, 0xd0, 0x24, 0xa9, 0x6b, 0x30, +0x10, 0x07, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *reload_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_reload_png = new wxImage(); + if (!img_reload_png || !img_reload_png->IsOk()) + { + wxMemoryInputStream img_reload_pngIS(reload_png_data, sizeof(reload_png_data)); + img_reload_png->LoadFile(img_reload_pngIS, wxBITMAP_TYPE_PNG); + } + return img_reload_png; +} +#define reload_png_img reload_png_img() + +static wxBitmap *reload_png_bmp() +{ + static wxBitmap *bmp_reload_png; + if (!bmp_reload_png || !bmp_reload_png->IsOk()) + bmp_reload_png = new wxBitmap(*reload_png_img); + return bmp_reload_png; +} +#define reload_png_bmp reload_png_bmp() + +static wxIcon *reload_png_ico() +{ + static wxIcon *ico_reload_png; + if (!ico_reload_png || !ico_reload_png->IsOk()) + { + ico_reload_png = new wxIcon(); + ico_reload_png->CopyFromBitmap(*reload_png_bmp); + } + return ico_reload_png; +} +#define reload_png_ico reload_png_ico() + +#endif // RELOAD_PNG_H diff --git a/include/images/resourcegroup.png b/include/images/resourcegroup.png new file mode 100644 index 0000000..668089e Binary files /dev/null and b/include/images/resourcegroup.png differ diff --git a/include/images/resourcegroup.pngc b/include/images/resourcegroup.pngc new file mode 100644 index 0000000..bcbf18e --- /dev/null +++ b/include/images/resourcegroup.pngc @@ -0,0 +1,165 @@ +#ifndef RESOURCEGROUP_PNG_H +#define RESOURCEGROUP_PNG_H + +static const unsigned char resourcegroup_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, +0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, +0x83, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x80, +0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, +0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, +0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00, 0x00, 0x01, +0xaa, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, +0x46, 0xa0, 0xf3, 0x4b, 0xa6, 0xfb, 0x4b, 0xa7, +0xfb, 0x4b, 0xa7, 0xfd, 0x49, 0xa3, 0xf8, 0x46, +0x9f, 0xee, 0x47, 0x9d, 0xe0, 0x45, 0x9a, 0xdc, +0x43, 0x98, 0xdc, 0x48, 0x99, 0xd6, 0x4e, 0x9c, +0xcd, 0x40, 0x98, 0xe7, 0x2f, 0x83, 0xd2, 0x23, +0x73, 0xc2, 0x27, 0x72, 0xb9, 0x26, 0x72, 0xb8, +0x47, 0xa1, 0xf3, 0x29, 0x79, 0xc3, 0x47, 0xa1, +0xf5, 0x45, 0x9f, 0xf2, 0x4a, 0xa4, 0xfa, 0x3d, +0x91, 0xcd, 0x36, 0x87, 0xc1, 0x34, 0x83, 0xb5, +0x4a, 0xa4, 0xf6, 0x35, 0x83, 0xaa, 0x4b, 0xa2, +0xdb, 0x46, 0x9f, 0xe5, 0x2f, 0x81, 0xcc, 0x30, +0x84, 0xce, 0x30, 0x83, 0xd1, 0x2b, 0x7e, 0xcc, +0x29, 0x7b, 0xc9, 0x41, 0x9a, 0xec, 0x46, 0xa0, +0xf3, 0x34, 0x88, 0xd5, 0x30, 0x83, 0xce, 0x2e, +0x81, 0xd0, 0x2f, 0x80, 0xc9, 0x2b, 0x78, 0xb4, +0x99, 0xcb, 0xff, 0xae, 0xd5, 0xfd, 0xae, 0xd5, +0xff, 0xad, 0xd4, 0xff, 0x9e, 0xcd, 0xff, 0x63, +0xb3, 0xff, 0x45, 0x97, 0xd3, 0xda, 0x54, 0x0e, +0xda, 0x5b, 0x01, 0xe0, 0x5d, 0x09, 0xdf, 0x58, +0x0b, 0xdd, 0x51, 0x13, 0xd4, 0xe9, 0xff, 0xda, +0xeb, 0xff, 0xd2, 0xe7, 0xff, 0xa1, 0xd0, 0xff, +0x4c, 0xa8, 0xff, 0x3d, 0x8e, 0xcc, 0xe2, 0x62, +0x07, 0xff, 0x7e, 0x1c, 0xfd, 0x8a, 0x2d, 0xfd, +0x85, 0x29, 0xe0, 0x5e, 0x04, 0xd8, 0xea, 0xff, +0x44, 0x9e, 0xf1, 0x38, 0x88, 0xc8, 0xe6, 0x66, +0x07, 0xff, 0x81, 0x1e, 0xff, 0x86, 0x24, 0xfd, +0x8a, 0x2e, 0xdf, 0x5f, 0x04, 0xa3, 0xd0, 0xff, +0x42, 0x9c, 0xee, 0x34, 0x85, 0xcb, 0xe2, 0x5f, +0x09, 0xff, 0x74, 0x20, 0xff, 0x85, 0x28, 0xfd, +0x7d, 0x30, 0xe0, 0x5e, 0x05, 0x9c, 0xcc, 0xff, +0x7f, 0xc0, 0xff, 0x3d, 0x95, 0xe6, 0x35, 0x87, +0xce, 0xd9, 0x56, 0x20, 0xdc, 0x54, 0x16, 0xe0, +0x5a, 0x18, 0xdc, 0x58, 0x11, 0xd2, 0x57, 0x04, +0x48, 0xa2, 0xf6, 0x36, 0x8d, 0xdd, 0x31, 0x86, +0xd6, 0x32, 0x87, 0xd8, 0x30, 0x84, 0xd3, 0x44, +0x99, 0xce, 0x40, 0x94, 0xd6, 0x30, 0x7b, 0xb9, +0x2c, 0x73, 0xaf, 0x2a, 0x73, 0xb4, 0x2f, 0x78, +0xb6, 0x4a, 0xa4, 0xfa, 0x40, 0x99, 0xeb, 0x42, +0x9a, 0xe6, 0x4a, 0xa4, 0xf8, 0x59, 0xae, 0xff, +0x50, 0xaa, 0xff, 0x4b, 0xa6, 0xfb, 0xa9, 0xd3, +0xff, 0xb1, 0xd6, 0xfd, 0xad, 0xd4, 0xfd, 0x9f, +0xd0, 0xec, 0x56, 0xab, 0xe5, 0x4b, 0xa7, 0xfd, +0x96, 0xca, 0xff, 0xab, 0xd4, 0xfd, 0xab, 0xd4, +0xff, 0xd5, 0xe9, 0xff, 0xd4, 0xe9, 0xfd, 0xa6, +0xd1, 0xfa, 0x43, 0x9c, 0xeb, 0x45, 0x9f, 0xf2, +0xa9, 0xd3, 0xfd, 0xd0, 0xe6, 0xfd, 0xd5, 0xe9, +0xfb, 0xd2, 0xe7, 0xfa, 0xae, 0xd6, 0xf6, 0xda, +0xeb, 0xfd, 0x36, 0x8d, 0xdc, 0x3e, 0x96, 0xe7, +0xb1, 0xd6, 0xfb, 0x9c, 0xcc, 0xfd, 0x33, 0x87, +0xd1, 0x3b, 0x93, 0xe3, 0xa7, 0xd2, 0xff, 0xaf, +0xd6, 0xf1, 0xb1, 0xd6, 0xff, 0x96, 0xca, 0xfd, +0x35, 0x88, 0xd2, 0x3c, 0x94, 0xe3, 0xb1, 0xd8, +0xf2, 0x9e, 0xd0, 0xe2, 0xff, 0xff, 0xff, 0x4c, +0x4c, 0x22, 0xb7, 0x00, 0x00, 0x00, 0x29, 0x74, +0x52, 0x4e, 0x53, 0x00, 0xef, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xef, 0xf7, +0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, +0xf7, 0xf7, 0xf7, 0xef, 0xc4, 0xe4, 0x36, 0xb0, +0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, +0x00, 0x88, 0x05, 0x1d, 0x48, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2e, +0x23, 0x00, 0x00, 0x2e, 0x23, 0x01, 0x78, 0xa5, +0x3f, 0x76, 0x00, 0x00, 0x00, 0xe2, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x00, +0x8c, 0x4c, 0xcc, 0x2c, 0x2c, 0x2c, 0xac, 0x6c, +0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x8c, 0x40, 0x01, +0x26, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d, +0x03, 0x43, 0x23, 0x63, 0x13, 0x1e, 0xa0, 0x00, +0x8b, 0x8e, 0xa9, 0x99, 0xb9, 0x85, 0xa5, 0x95, +0xb5, 0x8d, 0xad, 0x9d, 0x3d, 0x2f, 0x48, 0x40, +0xcb, 0xcc, 0xd4, 0xc1, 0xc2, 0xd1, 0xc9, 0xd9, +0xc5, 0xd5, 0xcd, 0x9d, 0x0f, 0x24, 0xa0, 0x6d, +0xee, 0x60, 0xea, 0xe1, 0xe9, 0xe5, 0xed, 0xe3, +0xeb, 0xe7, 0xcf, 0x0f, 0x12, 0xd0, 0xd4, 0xd4, +0x0d, 0x08, 0x0c, 0x0a, 0x0e, 0x09, 0x0d, 0x0b, +0x8f, 0x10, 0x00, 0x0a, 0x08, 0x46, 0x46, 0x45, +0xc7, 0x44, 0xc7, 0xc6, 0xc5, 0x27, 0x24, 0x26, +0x25, 0x0b, 0x01, 0x05, 0x84, 0x53, 0x3c, 0x53, +0x53, 0x3d, 0xd3, 0xd2, 0x33, 0x32, 0x53, 0xb2, +0x2c, 0x45, 0x40, 0x5a, 0x02, 0xb2, 0x73, 0x72, +0xf3, 0xf2, 0x0b, 0x0a, 0x8b, 0xb4, 0x8b, 0x3d, +0x44, 0x21, 0x86, 0x96, 0x94, 0x96, 0x95, 0x57, +0x54, 0x56, 0x55, 0xd7, 0xd4, 0x8a, 0x01, 0x05, +0x98, 0xb5, 0xeb, 0x4a, 0x1d, 0x2c, 0xea, 0x1b, +0x74, 0x1c, 0x4a, 0xcc, 0x1a, 0xc5, 0x41, 0x02, +0x3a, 0xa5, 0x75, 0xa6, 0x4d, 0xcd, 0x2d, 0xad, +0xe6, 0x75, 0xa5, 0x6d, 0x12, 0x40, 0x01, 0x49, +0x4d, 0xad, 0xc6, 0xf6, 0x8e, 0xce, 0x2e, 0x8b, +0x9c, 0xee, 0xda, 0x1e, 0x29, 0xa0, 0x80, 0xb4, +0x8c, 0xac, 0x9c, 0xbc, 0x82, 0xa2, 0x92, 0xb2, +0x8a, 0xaa, 0x9a, 0xba, 0x06, 0xa6, 0xe7, 0x01, +0x99, 0x36, 0x32, 0xbc, 0x5d, 0x30, 0x9e, 0x18, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x34, +0x2d, 0x30, 0x37, 0x2d, 0x30, 0x35, 0x54, 0x31, +0x33, 0x3a, 0x30, 0x34, 0x3a, 0x30, 0x37, 0x2b, +0x30, 0x34, 0x3a, 0x30, 0x30, 0x75, 0x54, 0x1e, +0x89, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x34, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x39, 0x54, +0x31, 0x34, 0x3a, 0x34, 0x32, 0x3a, 0x31, 0x35, +0x2b, 0x30, 0x34, 0x3a, 0x30, 0x30, 0x3b, 0x74, +0x71, 0x48, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *resourcegroup_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_resourcegroup_png = new wxImage(); + if (!img_resourcegroup_png || !img_resourcegroup_png->IsOk()) + { + wxMemoryInputStream img_resourcegroup_pngIS(resourcegroup_png_data, sizeof(resourcegroup_png_data)); + img_resourcegroup_png->LoadFile(img_resourcegroup_pngIS, wxBITMAP_TYPE_PNG); + } + return img_resourcegroup_png; +} +#define resourcegroup_png_img resourcegroup_png_img() + +static wxBitmap *resourcegroup_png_bmp() +{ + static wxBitmap *bmp_resourcegroup_png; + if (!bmp_resourcegroup_png || !bmp_resourcegroup_png->IsOk()) + bmp_resourcegroup_png = new wxBitmap(*resourcegroup_png_img); + return bmp_resourcegroup_png; +} +#define resourcegroup_png_bmp resourcegroup_png_bmp() + +static wxIcon *resourcegroup_png_ico() +{ + static wxIcon *ico_resourcegroup_png; + if (!ico_resourcegroup_png || !ico_resourcegroup_png->IsOk()) + { + ico_resourcegroup_png = new wxIcon(); + ico_resourcegroup_png->CopyFromBitmap(*resourcegroup_png_bmp); + } + return ico_resourcegroup_png; +} +#define resourcegroup_png_ico resourcegroup_png_ico() + +#endif // RESOURCEGROUP_PNG_H diff --git a/include/images/resourcegroups.png b/include/images/resourcegroups.png new file mode 100644 index 0000000..4ea2387 Binary files /dev/null and b/include/images/resourcegroups.png differ diff --git a/include/images/resourcegroups.pngc b/include/images/resourcegroups.pngc new file mode 100644 index 0000000..19f0bc2 --- /dev/null +++ b/include/images/resourcegroups.pngc @@ -0,0 +1,191 @@ +#ifndef RESOURCEGROUPS_PNG_H +#define RESOURCEGROUPS_PNG_H + +static const unsigned char resourcegroups_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, +0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, +0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, +0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, +0x83, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0x80, +0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, +0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, +0x6f, 0x92, 0x5f, 0xc5, 0x46, 0x00, 0x00, 0x02, +0x4c, 0x50, 0x4c, 0x54, 0x45, 0x3f, 0x95, 0xdc, +0xff, 0xff, 0xff, 0x43, 0x95, 0xc2, 0x52, 0x98, +0x7d, 0x79, 0x9d, 0x0d, 0x49, 0x96, 0xa6, 0x17, +0x59, 0x6a, 0x14, 0x59, 0x75, 0x3a, 0x58, 0x09, +0x31, 0x58, 0x1d, 0x0e, 0x55, 0x82, 0x30, 0x55, +0x1d, 0x9b, 0xa6, 0x6a, 0xb6, 0xbf, 0x94, 0x44, +0x9a, 0xfc, 0x57, 0xa5, 0xef, 0x57, 0xa4, 0xf6, +0x52, 0xa3, 0xff, 0x3b, 0x94, 0xff, 0x2b, 0x88, +0xe9, 0x37, 0x92, 0xfc, 0x56, 0xa4, 0xff, 0x56, +0xa4, 0xff, 0x43, 0x95, 0xc4, 0x51, 0xa2, 0xff, +0x31, 0x88, 0xd6, 0x35, 0x91, 0xf9, 0x4b, 0x96, +0x9a, 0x3e, 0x96, 0xff, 0x4e, 0x98, 0x8d, 0x51, +0xa2, 0xff, 0x4b, 0x96, 0x9d, 0x56, 0xa4, 0xfc, +0x79, 0x9d, 0x0d, 0x77, 0x9d, 0x11, 0x57, 0xa5, +0xed, 0x35, 0x8d, 0xc6, 0x34, 0x91, 0xff, 0x45, +0x9a, 0xef, 0x3d, 0x94, 0xea, 0x26, 0x7e, 0xc0, +0x4e, 0x9f, 0xfc, 0x56, 0xa4, 0xf9, 0x45, 0x9a, +0xf6, 0x41, 0x98, 0xe1, 0x37, 0x91, 0xed, 0x25, +0x7f, 0xd3, 0x2a, 0x87, 0xe5, 0x54, 0xa2, 0xca, +0x45, 0x98, 0xca, 0x45, 0x9d, 0xfc, 0x3e, 0x94, +0xd1, 0x3a, 0x4e, 0x00, 0x3b, 0x92, 0xb7, 0x35, +0x8e, 0xc7, 0x31, 0x8b, 0xd4, 0x2c, 0x87, 0xd7, +0x23, 0x7e, 0xde, 0x44, 0x99, 0xea, 0x3a, 0x93, +0xed, 0x3f, 0x94, 0xc4, 0x29, 0x80, 0xba, 0x32, +0x8b, 0xe7, 0x2b, 0x89, 0xf1, 0xb0, 0xd4, 0xfc, +0xbf, 0xde, 0xf9, 0x8e, 0xc3, 0xff, 0x3a, 0x93, +0xed, 0xaf, 0x66, 0x04, 0xdf, 0x80, 0x03, 0xc3, +0x70, 0x09, 0x26, 0x83, 0xe5, 0xbf, 0xde, 0xff, +0x3d, 0x95, 0xff, 0x2b, 0x8b, 0xfc, 0x1a, 0x71, +0xc7, 0x8d, 0x58, 0x02, 0xaf, 0x6b, 0x03, 0xa2, +0x64, 0x05, 0x21, 0x78, 0xce, 0x65, 0xae, 0xff, +0x27, 0x85, 0xef, 0x40, 0x98, 0xff, 0x53, 0xa3, +0xf9, 0x4e, 0x9f, 0xe1, 0x45, 0x9a, 0xe5, 0x34, +0x8f, 0xe1, 0x30, 0x8a, 0xd6, 0x31, 0x89, 0xde, +0x29, 0x88, 0xf6, 0x18, 0x6f, 0xca, 0x51, 0xa2, +0xfc, 0xb0, 0xd4, 0xf6, 0xc0, 0xdf, 0xea, 0x8e, +0xc3, 0xf9, 0x3b, 0x94, 0xdf, 0xb2, 0x5e, 0x16, +0xd7, 0x7d, 0x02, 0xbe, 0x71, 0x07, 0x26, 0x83, +0xea, 0x67, 0xaf, 0xfc, 0x2f, 0x8d, 0xf1, 0x57, +0xa5, 0xff, 0xbf, 0xde, 0xfc, 0xd4, 0xea, 0xf3, +0x86, 0xbf, 0xfc, 0x2c, 0x8a, 0xea, 0xb5, 0x6a, +0x06, 0xff, 0x8e, 0x1c, 0xda, 0x7d, 0x0c, 0x1f, +0x78, 0xd7, 0x99, 0xc8, 0xff, 0x3a, 0x94, 0xf9, +0x56, 0xa4, 0xff, 0x7e, 0xba, 0xf6, 0x77, 0xb7, +0xe5, 0x1c, 0x74, 0xd0, 0x18, 0x6e, 0xc3, 0x7f, +0x52, 0x05, 0x80, 0x53, 0x07, 0x86, 0x54, 0x04, +0x20, 0x74, 0xbc, 0x96, 0xc7, 0xfc, 0x38, 0x92, +0xfc, 0x41, 0x99, 0xfc, 0x32, 0x8f, 0xf6, 0x29, +0x83, 0xd6, 0x16, 0x6d, 0xc6, 0x30, 0x8e, 0xfc, +0x3d, 0x94, 0xef, 0x43, 0x99, 0xe7, 0x3e, 0x94, +0xe5, 0x2e, 0x8a, 0xdc, 0x2f, 0x8a, 0xd7, 0x8a, +0xc2, 0xf3, 0x6b, 0xb1, 0xe9, 0x29, 0x88, 0xf3, +0xb0, 0xd4, 0xff, 0xbf, 0xde, 0xf6, 0x8e, 0xc4, +0xf6, 0x39, 0x93, 0xf3, 0xae, 0x63, 0x11, 0xd0, +0x78, 0x18, 0xb9, 0x6a, 0x2e, 0x27, 0x83, 0xe1, +0x7f, 0xba, 0xf1, 0x2b, 0x8b, 0xff, 0x4d, 0xa1, +0xf6, 0xbe, 0xdc, 0xff, 0xd4, 0xe9, 0xf9, 0x85, +0xbe, 0xf3, 0x2b, 0x8a, 0xf6, 0xb4, 0x6b, 0x02, +0xff, 0x87, 0x31, 0xd4, 0x79, 0x1c, 0x20, 0x78, +0xd3, 0xb1, 0xd6, 0xf6, 0x84, 0xbc, 0xef, 0x2b, +0x8a, 0xf3, 0x47, 0x9d, 0xfc, 0x7a, 0xb9, 0xff, +0x7e, 0xba, 0xf3, 0x62, 0xab, 0xf3, 0x28, 0x85, +0xe9, 0xa9, 0x5e, 0x0b, 0xaf, 0x62, 0x0d, 0xa9, +0x5b, 0x13, 0x1f, 0x75, 0xc6, 0x37, 0x92, 0xfc, +0x25, 0x82, 0xe9, 0x2f, 0x8e, 0xff, 0x3e, 0x92, +0xde, 0x2e, 0x84, 0xcb, 0x2e, 0x85, 0xc4, 0x3e, +0x98, 0xfc, 0x86, 0xbf, 0xff, 0x71, 0xb4, 0xfc, +0x3e, 0x96, 0xfc, 0x75, 0xb6, 0xfc, 0x9a, 0xca, +0xf6, 0x98, 0xc8, 0xea, 0x42, 0x9b, 0xfc, 0xd4, +0xe9, 0xff, 0x86, 0xbf, 0xf9, 0x2b, 0x89, 0xed, +0x8e, 0xc3, 0xe3, 0xd4, 0xe9, 0xf3, 0xc0, 0xe1, +0xe3, 0xaf, 0xd6, 0xf9, 0xc2, 0xde, 0xfc, 0x83, +0xbe, 0xef, 0x26, 0x82, 0xdf, 0x8d, 0xc3, 0xd7, +0xc2, 0xde, 0xf3, 0xb6, 0xda, 0xdc, 0xff, 0xff, +0xff, 0x2f, 0x3e, 0xf7, 0x2e, 0x00, 0x00, 0x00, +0x3e, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0xe2, 0xf0, 0xf0, 0xf0, 0xfd, +0xfe, 0xfe, 0xf4, 0xf0, 0x0d, 0xf0, 0xfd, 0xfb, +0x0c, 0xf0, 0x12, 0xf3, 0x05, 0xf0, 0x03, 0x01, +0xf4, 0xf8, 0xf9, 0xe2, 0xf0, 0xfd, 0xfe, 0xf4, +0xe2, 0xf0, 0xf0, 0xf7, 0xf8, 0xf0, 0xf0, 0xfe, +0xf4, 0x0a, 0xf7, 0xfe, 0xfc, 0xfd, 0xfa, 0xf6, +0xf1, 0xf0, 0xe2, 0xb5, 0x10, 0x5e, 0xb0, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x01, +0xff, 0x02, 0x2d, 0xde, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x2e, 0x23, +0x00, 0x00, 0x2e, 0x23, 0x01, 0x78, 0xa5, 0x3f, +0x76, 0x00, 0x00, 0x00, 0xfa, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0xe0, 0xe3, 0x17, 0x10, +0x14, 0xb2, 0xb3, 0x17, 0x16, 0x61, 0x60, 0x04, +0x03, 0x06, 0x51, 0x07, 0x47, 0x27, 0x67, 0x17, +0x57, 0x37, 0x77, 0x26, 0xa8, 0x80, 0x98, 0x87, +0xa7, 0x97, 0xb7, 0x8f, 0xaf, 0x9f, 0xbf, 0x38, +0x33, 0x44, 0x40, 0x22, 0x20, 0x30, 0x28, 0x38, +0x24, 0x34, 0x2c, 0x3c, 0x42, 0x52, 0x4a, 0x9a, +0x05, 0x28, 0x20, 0x13, 0x19, 0x15, 0x1d, 0x13, +0x1b, 0x17, 0x9f, 0x90, 0x98, 0x94, 0x2c, 0x0b, +0x12, 0x90, 0x4b, 0x49, 0x4d, 0x4b, 0xcf, 0xc8, +0xcc, 0xca, 0xce, 0xc9, 0xcd, 0x93, 0x07, 0x09, +0x28, 0xe4, 0x17, 0x14, 0x16, 0x15, 0x97, 0x94, +0x96, 0x95, 0x57, 0x54, 0x32, 0x2a, 0x2a, 0xb1, +0x32, 0x28, 0x57, 0x55, 0xd7, 0xd4, 0xd6, 0xd5, +0x37, 0x34, 0x36, 0x36, 0x35, 0xab, 0xb4, 0xb4, +0xaa, 0x32, 0xa8, 0xa9, 0x6b, 0x68, 0xb6, 0xb5, +0x77, 0x04, 0x77, 0x76, 0x75, 0xf7, 0xf4, 0xf6, +0xf5, 0x4f, 0x60, 0x60, 0x64, 0x63, 0x17, 0x73, +0x9c, 0x38, 0x69, 0xf2, 0x94, 0xa9, 0xd3, 0xa6, +0xcf, 0x98, 0x39, 0x6b, 0x36, 0x03, 0x23, 0x07, +0xa7, 0xd6, 0x9c, 0xb9, 0xf3, 0xe6, 0x2f, 0x58, +0xb8, 0x68, 0xf1, 0x92, 0xa5, 0xcb, 0x96, 0x83, +0x1c, 0xac, 0xad, 0xa3, 0xab, 0xb7, 0x62, 0xd2, +0xca, 0xc0, 0x55, 0xab, 0xd7, 0xac, 0xd5, 0x87, +0xf8, 0x80, 0x8b, 0x71, 0xdd, 0xfa, 0xfc, 0x0d, +0x1b, 0x37, 0x6d, 0xde, 0x62, 0x00, 0x11, 0xe0, +0x66, 0xdc, 0x9a, 0xbe, 0x6d, 0xfb, 0x8e, 0x9d, +0xbb, 0x76, 0x1b, 0x42, 0x04, 0x78, 0x18, 0x8d, +0xf6, 0xec, 0xdd, 0xb7, 0xff, 0xc0, 0xc1, 0x43, +0xc6, 0x10, 0x01, 0x5e, 0x13, 0x53, 0x33, 0x73, +0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x00, 0xb7, +0x22, 0x4d, 0x03, 0xad, 0x66, 0xb4, 0x78, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x34, 0x2d, +0x30, 0x37, 0x2d, 0x30, 0x35, 0x54, 0x31, 0x33, +0x3a, 0x30, 0x34, 0x3a, 0x31, 0x35, 0x2b, 0x30, +0x34, 0x3a, 0x30, 0x30, 0x2e, 0x61, 0x0f, 0x3e, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x34, +0x2d, 0x30, 0x36, 0x2d, 0x32, 0x39, 0x54, 0x31, +0x34, 0x3a, 0x34, 0x32, 0x3a, 0x31, 0x35, 0x2b, +0x30, 0x34, 0x3a, 0x30, 0x30, 0x3b, 0x74, 0x71, +0x48, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *resourcegroups_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_resourcegroups_png = new wxImage(); + if (!img_resourcegroups_png || !img_resourcegroups_png->IsOk()) + { + wxMemoryInputStream img_resourcegroups_pngIS(resourcegroups_png_data, sizeof(resourcegroups_png_data)); + img_resourcegroups_png->LoadFile(img_resourcegroups_pngIS, wxBITMAP_TYPE_PNG); + } + return img_resourcegroups_png; +} +#define resourcegroups_png_img resourcegroups_png_img() + +static wxBitmap *resourcegroups_png_bmp() +{ + static wxBitmap *bmp_resourcegroups_png; + if (!bmp_resourcegroups_png || !bmp_resourcegroups_png->IsOk()) + bmp_resourcegroups_png = new wxBitmap(*resourcegroups_png_img); + return bmp_resourcegroups_png; +} +#define resourcegroups_png_bmp resourcegroups_png_bmp() + +static wxIcon *resourcegroups_png_ico() +{ + static wxIcon *ico_resourcegroups_png; + if (!ico_resourcegroups_png || !ico_resourcegroups_png->IsOk()) + { + ico_resourcegroups_png = new wxIcon(); + ico_resourcegroups_png->CopyFromBitmap(*resourcegroups_png_bmp); + } + return ico_resourcegroups_png; +} +#define resourcegroups_png_ico resourcegroups_png_ico() + +#endif // RESOURCEGROUPS_PNG_H diff --git a/include/images/restore.png b/include/images/restore.png new file mode 100644 index 0000000..81e7ac4 Binary files /dev/null and b/include/images/restore.png differ diff --git a/include/images/restore.pngc b/include/images/restore.pngc new file mode 100644 index 0000000..b0c9796 --- /dev/null +++ b/include/images/restore.pngc @@ -0,0 +1,147 @@ +#ifndef RESTORE_PNG_H +#define RESTORE_PNG_H + +static const unsigned char restore_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfa, 0xf9, 0xf4, 0xe6, +0xde, 0xc0, 0xd3, 0xc5, 0x91, 0xc3, 0xb0, 0x6a, +0xb7, 0xa1, 0x4c, 0xaf, 0x96, 0x37, 0xd1, 0xc3, +0x8d, 0xb2, 0x9b, 0x3b, 0xc6, 0xb4, 0x69, 0xda, +0xcb, 0x8e, 0xe6, 0xdc, 0xa9, 0xed, 0xe9, 0xbe, +0xf2, 0xf2, 0xc2, 0xef, 0xec, 0xb7, 0xe4, 0xdf, +0xa2, 0xd6, 0xce, 0x88, 0xca, 0xbd, 0x6d, 0xbc, +0xad, 0x52, 0xaf, 0x98, 0x36, 0xc1, 0xad, 0x64, +0xdd, 0xd0, 0x99, 0xff, 0xfd, 0xee, 0xff, 0xfd, +0xe3, 0xac, 0xbc, 0x64, 0x72, 0x91, 0x13, 0xa8, +0xb8, 0x5c, 0xf1, 0xee, 0xbc, 0xec, 0xe9, 0xb2, +0xe5, 0xe5, 0xab, 0xe4, 0xe1, 0xa0, 0xdf, 0xdf, +0x9b, 0xc7, 0xbc, 0x6a, 0xb0, 0x98, 0x3b, 0xe9, +0xe1, 0xb7, 0xab, 0xbc, 0x6a, 0xb6, 0xdd, 0x7b, +0xa5, 0xb7, 0x59, 0xed, 0xed, 0xbb, 0xed, 0xed, +0xca, 0xf6, 0xf4, 0xe2, 0xfc, 0xf9, 0xf2, 0xac, +0x92, 0x30, 0xe3, 0xdb, 0xbd, 0xa3, 0xb0, 0x57, +0xa3, 0xd3, 0x57, 0x93, 0xcd, 0x32, 0xaa, 0xd9, +0x58, 0xac, 0xbe, 0x73, 0xf0, 0xed, 0xd2, 0xec, +0xe9, 0xc4, 0xea, 0xe2, 0xba, 0xe5, 0xdd, 0xc2, +0x9d, 0xd0, 0x4b, 0xa4, 0xd8, 0x46, 0xc3, 0xe7, +0x7c, 0xe0, 0xda, 0x7b, 0xdf, 0xda, 0x84, 0xe4, +0xe1, 0x96, 0xe8, 0xe3, 0xab, 0xa7, 0xb5, 0x65, +0xa8, 0xd7, 0x56, 0x88, 0xa8, 0x2c, 0x55, 0x7f, +0x59, 0x2c, 0x66, 0xbd, 0x83, 0xa5, 0xd8, 0xf2, +0xe8, 0xd9, 0xff, 0xf8, 0xf3, 0xb3, 0xdf, 0x62, +0xa1, 0xc4, 0x4e, 0x83, 0xab, 0x67, 0xf2, 0xf9, +0xfc, 0xe3, 0xf3, 0xf8, 0xdb, 0xf2, 0xf9, 0xe4, +0xf5, 0xfb, 0x9d, 0xc8, 0xe6, 0xff, 0xfa, 0xf4, +0x75, 0x93, 0x16, 0xb2, 0xdf, 0x59, 0xac, 0xd5, +0x4f, 0x78, 0x97, 0x1a, 0x31, 0x69, 0xb1, 0xb1, +0xb1, 0xb1, 0xc8, 0xeb, 0xf7, 0x7f, 0xb3, 0xe1, +0x84, 0xa3, 0x2b, 0xb2, 0xdb, 0x5a, 0xae, 0xdc, +0x48, 0x97, 0xb8, 0x3e, 0xd2, 0xee, 0xf8, 0xa5, +0xc8, 0x52, 0xb2, 0xe0, 0x49, 0xb1, 0xd6, 0x52, +0x2e, 0x67, 0xb8, 0x3d, 0x7a, 0xc9, 0x80, 0xb0, +0xe3, 0xf3, 0xe9, 0xda, 0xe2, 0xe5, 0xc2, 0xb6, +0xdd, 0x58, 0xb4, 0xdb, 0x53, 0x9e, 0xbf, 0x45, +0x61, 0x98, 0x79, 0x53, 0x9b, 0xd5, 0x54, 0x97, +0xd7, 0x55, 0x95, 0xd9, 0x80, 0xae, 0xe3, 0xf2, +0xea, 0xd9, 0xff, 0xf9, 0xee, 0xc5, 0xcc, 0x85, +0xb4, 0xd5, 0x5d, 0x56, 0x91, 0xdc, 0x80, 0xac, +0xe5, 0xcb, 0xbc, 0x82, 0xf4, 0xea, 0xd8, 0xfe, +0xf4, 0xd3, 0x48, 0x77, 0x78, 0x7b, 0x9a, 0x1d, +0x3f, 0x72, 0x8e, 0x81, 0xaa, 0xe6, 0xb0, 0x99, +0x39, 0xdb, 0xc6, 0x94, 0xed, 0xdd, 0xb5, 0xf3, +0xe6, 0xbe, 0x7e, 0x9d, 0xb7, 0x34, 0x6b, 0xaa, +0xec, 0xf7, 0xfc, 0xa0, 0xbe, 0xed, 0x62, 0x7a, +0x86, 0x99, 0xec, 0x0b, 0x1f, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xed, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x64, 0x62, 0x66, 0x61, 0x65, +0x03, 0x02, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06, +0x06, 0x06, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, +0x5e, 0x3e, 0x7e, 0x01, 0x41, 0x21, 0x61, 0x76, +0xa0, 0x80, 0x88, 0xa8, 0x98, 0xb8, 0x84, 0xa4, +0x94, 0xb4, 0x8c, 0xac, 0x9c, 0xbc, 0x82, 0x08, +0x50, 0x40, 0x51, 0x49, 0x4c, 0x59, 0x52, 0x45, +0x52, 0x55, 0x8d, 0x47, 0x5d, 0x43, 0x93, 0x15, +0x28, 0xa0, 0xa5, 0xad, 0x23, 0xa9, 0xab, 0xa7, +0x2f, 0x69, 0xa0, 0x61, 0x68, 0x64, 0xac, 0x05, +0x12, 0x30, 0x91, 0x54, 0x31, 0xd5, 0x33, 0x33, +0x97, 0xb4, 0xb0, 0xb4, 0xb2, 0x86, 0x08, 0xd8, +0x48, 0x4a, 0xda, 0xda, 0x49, 0xda, 0x3b, 0x80, +0x81, 0x23, 0x50, 0xc0, 0xc9, 0x59, 0xd2, 0xc5, +0xd5, 0xcd, 0xc1, 0xdd, 0xc3, 0xd3, 0xcb, 0xc1, +0xdb, 0x01, 0x24, 0xe0, 0xe3, 0xeb, 0xe7, 0x1f, +0x10, 0xe8, 0x11, 0x14, 0x14, 0xec, 0x10, 0x02, +0x11, 0x08, 0x0d, 0x0b, 0x8f, 0x90, 0xf4, 0x88, +0x0c, 0xf6, 0x84, 0x0a, 0x38, 0x2b, 0x47, 0x45, +0xc7, 0xd8, 0xf9, 0xc6, 0x3a, 0x38, 0xc4, 0xc5, +0x83, 0x04, 0x12, 0x7c, 0x12, 0x43, 0x93, 0x92, +0x53, 0x52, 0xd3, 0xd2, 0xd2, 0x33, 0x32, 0x41, +0x02, 0x59, 0x3e, 0xd9, 0x39, 0x11, 0xb9, 0x01, +0x81, 0x40, 0x05, 0x79, 0xf9, 0x40, 0x81, 0x82, +0x42, 0xe7, 0xec, 0xa2, 0xe2, 0x92, 0x52, 0x77, +0x0f, 0x2f, 0x87, 0xbc, 0x32, 0x07, 0x06, 0xf6, +0x72, 0x91, 0x8a, 0xca, 0xaa, 0xea, 0x1a, 0x87, +0xda, 0x48, 0x4f, 0x87, 0xb2, 0x3a, 0x07, 0x06, +0xa8, 0xf7, 0xeb, 0x1d, 0xa0, 0x0e, 0x03, 0x00, +0xb9, 0x10, 0x36, 0xae, 0x12, 0x10, 0xc4, 0x1b, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *restore_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_restore_png = new wxImage(); + if (!img_restore_png || !img_restore_png->IsOk()) + { + wxMemoryInputStream img_restore_pngIS(restore_png_data, sizeof(restore_png_data)); + img_restore_png->LoadFile(img_restore_pngIS, wxBITMAP_TYPE_PNG); + } + return img_restore_png; +} +#define restore_png_img restore_png_img() + +static wxBitmap *restore_png_bmp() +{ + static wxBitmap *bmp_restore_png; + if (!bmp_restore_png || !bmp_restore_png->IsOk()) + bmp_restore_png = new wxBitmap(*restore_png_img); + return bmp_restore_png; +} +#define restore_png_bmp restore_png_bmp() + +static wxIcon *restore_png_ico() +{ + static wxIcon *ico_restore_png; + if (!ico_restore_png || !ico_restore_png->IsOk()) + { + ico_restore_png = new wxIcon(); + ico_restore_png->CopyFromBitmap(*restore_png_bmp); + } + return ico_restore_png; +} +#define restore_png_ico restore_png_ico() + +#endif // RESTORE_PNG_H diff --git a/include/images/roles.png b/include/images/roles.png new file mode 100644 index 0000000..68d3605 Binary files /dev/null and b/include/images/roles.png differ diff --git a/include/images/roles.pngc b/include/images/roles.pngc new file mode 100644 index 0000000..78cf4ee --- /dev/null +++ b/include/images/roles.pngc @@ -0,0 +1,122 @@ +#ifndef ROLES_PNG_H +#define ROLES_PNG_H + +static const unsigned char roles_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xe7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x84, 0x84, 0x84, 0x5c, +0x5c, 0x5c, 0xbf, 0xbf, 0xbf, 0xa0, 0xa0, 0xa0, +0x86, 0x82, 0x7e, 0xcb, 0xc1, 0xb8, 0xf2, 0xe4, +0xdb, 0xcb, 0xc1, 0xbb, 0x92, 0x8d, 0x8b, 0x7a, +0x77, 0x74, 0xf4, 0xe6, 0xda, 0xf8, 0xea, 0xe0, +0xf8, 0xea, 0xe2, 0xf7, 0xea, 0xe4, 0xf3, 0xe6, +0xe2, 0x92, 0x8d, 0x8c, 0x93, 0x93, 0x93, 0xbd, +0xb4, 0xac, 0xf7, 0xea, 0xe6, 0xf7, 0xea, 0xe8, +0xca, 0xc1, 0xc1, 0x70, 0x70, 0x70, 0xde, 0xd3, +0xca, 0xf7, 0xea, 0xea, 0xf1, 0xe4, 0xe6, 0xb6, +0xb6, 0xb6, 0x9b, 0x95, 0x92, 0x98, 0x92, 0x92, +0x55, 0x55, 0x55, 0x9b, 0x9b, 0x9b, 0x64, 0x63, +0x62, 0xd3, 0xc9, 0xc6, 0xff, 0xff, 0xff, 0xfc, +0xfe, 0xfe, 0xf8, 0xfc, 0xfe, 0xf3, 0xfa, 0xfd, +0xed, 0xf8, 0xfc, 0xe7, 0xf5, 0xfa, 0xe1, 0xf3, +0xf9, 0xda, 0xf0, 0xf8, 0x56, 0x56, 0x56, 0x64, +0x63, 0x63, 0x9b, 0x95, 0x95, 0xdb, 0x93, 0x96, +0xc8, 0x00, 0x00, 0xd3, 0xed, 0xf6, 0x5c, 0x5d, +0x5e, 0x9a, 0xa5, 0xa8, 0xc7, 0xdc, 0xe1, 0x9b, +0xa9, 0xad, 0xd3, 0x90, 0x95, 0xcd, 0xeb, 0xf5, +0x97, 0xa2, 0xa5, 0xd3, 0xea, 0xf0, 0xd0, 0xe8, +0xf0, 0xcc, 0xe6, 0xf1, 0xd4, 0x5e, 0x60, 0xcf, +0x5c, 0x5f, 0xc6, 0xe8, 0xf4, 0xde, 0xde, 0xde, +0x6e, 0x72, 0x73, 0xc8, 0xe5, 0xf1, 0xd4, 0x99, +0x9f, 0xc0, 0xe5, 0xf3, 0xa8, 0xa8, 0xa8, 0x96, +0xa2, 0xa5, 0xc4, 0xe3, 0xf1, 0x1e, 0x50, 0xad, +0xba, 0xe3, 0xf1, 0x72, 0x72, 0x72, 0xbb, 0xcf, +0xd6, 0xc0, 0xe1, 0xf1, 0xb4, 0xe1, 0xf0, 0xb8, +0xb8, 0xb8, 0xaf, 0xdf, 0xef, 0xab, 0xdd, 0xef, +0x1a, 0x9c, 0x0d, 0x68, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x21, 0xc4, 0x6c, 0x0d, 0x16, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xaf, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0x8e, 0xd7, +0x16, 0x82, 0x40, 0x0c, 0x05, 0x17, 0xc5, 0xae, +0xd8, 0xb0, 0x1b, 0x2c, 0xb4, 0x55, 0x01, 0x1b, +0xf6, 0xae, 0x88, 0x05, 0xff, 0xff, 0x7b, 0xdc, +0x28, 0xe8, 0x7d, 0x9b, 0xb9, 0xc9, 0x49, 0x08, +0xc1, 0x70, 0x21, 0x2e, 0x4c, 0xfe, 0xe1, 0x23, +0xd1, 0x58, 0x3c, 0xc1, 0xff, 0x45, 0x32, 0x95, +0xce, 0x08, 0xd9, 0xdc, 0x8f, 0xf3, 0x05, 0xc6, +0x45, 0xb1, 0xc4, 0x05, 0xa2, 0x5c, 0x41, 0xae, +0xd6, 0x42, 0x81, 0xa8, 0x37, 0x84, 0x62, 0x13, +0xfc, 0x48, 0x68, 0x5a, 0x6d, 0x11, 0x3a, 0x5d, +0x59, 0x51, 0x35, 0x9d, 0x02, 0x8a, 0x5e, 0x7f, +0x00, 0xc8, 0x86, 0x49, 0x2d, 0x14, 0xc3, 0xd1, +0x78, 0x02, 0xb2, 0x62, 0x1a, 0xe6, 0xd4, 0xb2, +0x51, 0xcc, 0xe6, 0x8b, 0x25, 0x28, 0xea, 0xca, +0x5c, 0x5b, 0xf6, 0x06, 0xc8, 0x76, 0xc7, 0x78, +0x0f, 0x6c, 0xff, 0xc0, 0xf8, 0x08, 0xe4, 0x74, +0x66, 0x7c, 0x01, 0xcd, 0xa1, 0x0e, 0xcb, 0x15, +0x88, 0x7b, 0x63, 0x7c, 0x07, 0x9d, 0x62, 0x7f, +0x7d, 0x00, 0x79, 0xba, 0x9f, 0xfb, 0xd4, 0xb1, +0x71, 0xc2, 0x03, 0xff, 0x39, 0xf8, 0xf6, 0xde, +0x2b, 0x10, 0xd2, 0xef, 0xd3, 0x37, 0xae, 0xc9, +0x1c, 0xa0, 0x5e, 0x13, 0x39, 0xf6, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *roles_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_roles_png = new wxImage(); + if (!img_roles_png || !img_roles_png->IsOk()) + { + wxMemoryInputStream img_roles_pngIS(roles_png_data, sizeof(roles_png_data)); + img_roles_png->LoadFile(img_roles_pngIS, wxBITMAP_TYPE_PNG); + } + return img_roles_png; +} +#define roles_png_img roles_png_img() + +static wxBitmap *roles_png_bmp() +{ + static wxBitmap *bmp_roles_png; + if (!bmp_roles_png || !bmp_roles_png->IsOk()) + bmp_roles_png = new wxBitmap(*roles_png_img); + return bmp_roles_png; +} +#define roles_png_bmp roles_png_bmp() + +static wxIcon *roles_png_ico() +{ + static wxIcon *ico_roles_png; + if (!ico_roles_png || !ico_roles_png->IsOk()) + { + ico_roles_png = new wxIcon(); + ico_roles_png->CopyFromBitmap(*roles_png_bmp); + } + return ico_roles_png; +} +#define roles_png_ico roles_png_ico() + +#endif // ROLES_PNG_H diff --git a/include/images/rule.png b/include/images/rule.png new file mode 100644 index 0000000..8b49780 Binary files /dev/null and b/include/images/rule.png differ diff --git a/include/images/rule.pngc b/include/images/rule.pngc new file mode 100644 index 0000000..47beb1f --- /dev/null +++ b/include/images/rule.pngc @@ -0,0 +1,91 @@ +#ifndef RULE_PNG_H +#define RULE_PNG_H + +static const unsigned char rule_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x57, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdd, 0xa9, 0x1d, 0xeb, +0xcc, 0x7a, 0xff, 0xe5, 0x9c, 0xff, 0xe5, 0x99, +0xff, 0xe4, 0x94, 0xff, 0xe3, 0x8d, 0xfe, 0xe2, +0x86, 0xfe, 0xe1, 0x7f, 0xff, 0xe5, 0x9a, 0xff, +0xe4, 0x95, 0xff, 0xe3, 0x8f, 0xfe, 0xe2, 0x87, +0xfe, 0xe1, 0x81, 0xfe, 0xe0, 0x7b, 0xff, 0xe5, +0x9b, 0xff, 0xe4, 0x97, 0xff, 0xe3, 0x90, 0xfe, +0xe2, 0x89, 0xfe, 0xe1, 0x82, 0xfe, 0xe0, 0x7c, +0xfe, 0xe0, 0x77, 0xff, 0xe5, 0x98, 0xff, 0xe4, +0x92, 0xff, 0xe3, 0x8b, 0xfe, 0xe2, 0x84, 0xfe, +0xe1, 0x7d, 0xfe, 0xe0, 0x78, 0xfe, 0xe0, 0x79, +0xa4, 0x04, 0xf3, 0x66, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x55, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0xad, 0x8e, 0x37, 0x16, 0x80, 0x30, 0x0c, 0x43, +0x23, 0x48, 0x23, 0x8d, 0x6a, 0xfa, 0xfd, 0xcf, +0x89, 0x93, 0x09, 0x1e, 0x6b, 0xbe, 0x26, 0x7f, +0x0d, 0xb2, 0x10, 0x35, 0xc0, 0x9b, 0x86, 0xef, +0x96, 0x23, 0xa1, 0xa0, 0x61, 0x60, 0x51, 0x44, +0x07, 0x07, 0x8f, 0x80, 0x88, 0x94, 0x45, 0x2f, +0x07, 0x8c, 0x7a, 0xc2, 0x6c, 0x17, 0x50, 0x16, +0xab, 0xdb, 0xfc, 0x1e, 0x8e, 0x78, 0xa6, 0x8b, +0x8a, 0x50, 0x5c, 0x1b, 0xae, 0x6f, 0xa2, 0x22, +0x9a, 0xcf, 0x4a, 0x95, 0xbf, 0xff, 0x3c, 0x90, +0x3c, 0x03, 0x01, 0x0c, 0x01, 0xee, 0x4f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *rule_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_rule_png = new wxImage(); + if (!img_rule_png || !img_rule_png->IsOk()) + { + wxMemoryInputStream img_rule_pngIS(rule_png_data, sizeof(rule_png_data)); + img_rule_png->LoadFile(img_rule_pngIS, wxBITMAP_TYPE_PNG); + } + return img_rule_png; +} +#define rule_png_img rule_png_img() + +static wxBitmap *rule_png_bmp() +{ + static wxBitmap *bmp_rule_png; + if (!bmp_rule_png || !bmp_rule_png->IsOk()) + bmp_rule_png = new wxBitmap(*rule_png_img); + return bmp_rule_png; +} +#define rule_png_bmp rule_png_bmp() + +static wxIcon *rule_png_ico() +{ + static wxIcon *ico_rule_png; + if (!ico_rule_png || !ico_rule_png->IsOk()) + { + ico_rule_png = new wxIcon(); + ico_rule_png->CopyFromBitmap(*rule_png_bmp); + } + return ico_rule_png; +} +#define rule_png_ico rule_png_ico() + +#endif // RULE_PNG_H diff --git a/include/images/rulebad.png b/include/images/rulebad.png new file mode 100644 index 0000000..94df61c Binary files /dev/null and b/include/images/rulebad.png differ diff --git a/include/images/rulebad.pngc b/include/images/rulebad.pngc new file mode 100644 index 0000000..9defcb4 --- /dev/null +++ b/include/images/rulebad.pngc @@ -0,0 +1,123 @@ +#ifndef RULEBAD_PNG_H +#define RULEBAD_PNG_H + +static const unsigned char rulebad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xdd, 0xa9, 0x1d, 0xdc, +0xa9, 0x1d, 0xe6, 0xc9, 0x7d, 0xed, 0xd7, 0x9d, +0xe7, 0xc9, 0x7d, 0xde, 0xad, 0x2a, 0xde, 0xb4, +0x49, 0xc3, 0x98, 0x37, 0xeb, 0xcc, 0x7a, 0xff, +0xe5, 0x9c, 0xf7, 0xdd, 0x99, 0xd3, 0xbc, 0x95, +0xd7, 0x62, 0x62, 0xc5, 0x00, 0x00, 0xd0, 0x57, +0x59, 0xcf, 0xaa, 0x6c, 0xfa, 0xdd, 0x8d, 0xb9, +0x97, 0x8f, 0xc5, 0x47, 0x4b, 0xdd, 0x69, 0x69, +0xb4, 0x9b, 0x87, 0xca, 0x51, 0x54, 0xf6, 0x77, +0x77, 0xc5, 0x46, 0x49, 0xbd, 0x9c, 0x9a, 0xbe, +0x3d, 0x42, 0xf1, 0x57, 0x57, 0xff, 0xe5, 0x9b, +0xff, 0xe5, 0x99, 0xbe, 0xa5, 0x89, 0xf6, 0x76, +0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, 0x6e, 0xbc, +0x3b, 0x40, 0xf1, 0x56, 0x56, 0xef, 0x4f, 0x4f, +0xee, 0x48, 0x49, 0xff, 0xe5, 0x98, 0xff, 0xe4, +0x95, 0xc9, 0xb0, 0x88, 0xf5, 0x6d, 0x6d, 0xf4, +0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, 0x55, +0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0xff, 0xe4, +0x94, 0xff, 0xe3, 0x90, 0xfe, 0xe2, 0x8c, 0xe7, +0xd3, 0xa9, 0xf3, 0x61, 0x61, 0xf1, 0x5b, 0x5b, +0xf0, 0x54, 0x54, 0xef, 0x4d, 0x4e, 0xee, 0x47, +0x47, 0xdc, 0xaa, 0x25, 0xcd, 0xbe, 0x98, 0xda, +0x65, 0x65, 0xf0, 0x53, 0x54, 0xef, 0x4d, 0x4d, +0xee, 0x46, 0x46, 0xaa, 0x2c, 0x33, 0xd0, 0xc5, +0xcb, 0xd6, 0x62, 0x62, 0xf0, 0x53, 0x53, 0xef, +0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, 0x3f, +0xeb, 0x38, 0x38, 0x83, 0x6c, 0x7c, 0xbb, 0x43, +0x45, 0xf0, 0x52, 0x52, 0xef, 0x4b, 0x4b, 0xed, +0x44, 0x45, 0xeb, 0x37, 0x37, 0xea, 0x31, 0x31, +0xe9, 0x2b, 0x2b, 0xf0, 0x51, 0x51, 0xee, 0x4a, +0x4a, 0xed, 0x43, 0x44, 0x99, 0x43, 0x4a, 0xe9, +0x2a, 0x2b, 0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, +0xed, 0x42, 0x43, 0xc4, 0x46, 0x4a, 0x67, 0x83, +0x92, 0x99, 0x44, 0x4b, 0xe7, 0x1f, 0x20, 0x96, +0xef, 0xc2, 0x38, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x9f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xad, +0x8d, 0xd5, 0x15, 0xc2, 0x00, 0x14, 0x43, 0xfb, +0x70, 0x0d, 0x5e, 0xdc, 0xdd, 0xdd, 0xa1, 0x78, +0x71, 0xf7, 0xfd, 0x17, 0xa1, 0x2d, 0x32, 0x01, +0xf9, 0xcb, 0x3d, 0x11, 0x86, 0xf9, 0x87, 0x88, +0x48, 0x26, 0x57, 0x28, 0x89, 0x54, 0x6a, 0x0d, +0x69, 0x05, 0xaf, 0x23, 0xbd, 0xc1, 0x08, 0x93, +0xd9, 0x62, 0xb5, 0xc1, 0x4e, 0x12, 0x70, 0xb0, +0x70, 0xc2, 0xe5, 0xf6, 0xc0, 0x0b, 0xbb, 0x00, +0x7c, 0xfe, 0x00, 0x82, 0xa1, 0x30, 0x22, 0x88, +0xc6, 0xe2, 0x10, 0x40, 0x22, 0x99, 0x62, 0x91, +0xce, 0x64, 0x91, 0xcb, 0x17, 0xa4, 0x44, 0xb1, +0x54, 0xae, 0x18, 0x51, 0xad, 0xd5, 0x1b, 0x4d, +0x69, 0x43, 0x2b, 0xbc, 0xb4, 0xda, 0x1d, 0x74, +0x7b, 0x7d, 0x70, 0xf4, 0x79, 0x1e, 0x0c, 0x31, +0x1a, 0x4f, 0xa6, 0x33, 0xb1, 0x21, 0x8a, 0x9f, +0x63, 0xb1, 0x5c, 0x61, 0xbd, 0xd9, 0x7e, 0x09, +0x76, 0xfb, 0x03, 0x8e, 0x38, 0x9d, 0x2f, 0x78, +0x03, 0x16, 0x57, 0xdc, 0xee, 0x0f, 0x3c, 0x7f, +0x1d, 0x0e, 0x1c, 0xcf, 0x30, 0x9c, 0xe8, 0x5f, +0x5c, 0xfd, 0x13, 0x88, 0xd9, 0x2c, 0xd6, 0x76, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, +0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, 0x31, +0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, 0x2b, +0x30, 0x36, 0x3a, 0x30, 0x30, 0xd3, 0xe6, 0xa8, +0x62, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x31, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x38, 0x54, +0x31, 0x32, 0x3a, 0x31, 0x37, 0x3a, 0x30, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xa2, 0xbb, +0x10, 0xde, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *rulebad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_rulebad_png = new wxImage(); + if (!img_rulebad_png || !img_rulebad_png->IsOk()) + { + wxMemoryInputStream img_rulebad_pngIS(rulebad_png_data, sizeof(rulebad_png_data)); + img_rulebad_png->LoadFile(img_rulebad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_rulebad_png; +} +#define rulebad_png_img rulebad_png_img() + +static wxBitmap *rulebad_png_bmp() +{ + static wxBitmap *bmp_rulebad_png; + if (!bmp_rulebad_png || !bmp_rulebad_png->IsOk()) + bmp_rulebad_png = new wxBitmap(*rulebad_png_img); + return bmp_rulebad_png; +} +#define rulebad_png_bmp rulebad_png_bmp() + +static wxIcon *rulebad_png_ico() +{ + static wxIcon *ico_rulebad_png; + if (!ico_rulebad_png || !ico_rulebad_png->IsOk()) + { + ico_rulebad_png = new wxIcon(); + ico_rulebad_png->CopyFromBitmap(*rulebad_png_bmp); + } + return ico_rulebad_png; +} +#define rulebad_png_ico rulebad_png_ico() + +#endif // RULEBAD_PNG_H diff --git a/include/images/rules.png b/include/images/rules.png new file mode 100644 index 0000000..cfe6ed2 Binary files /dev/null and b/include/images/rules.png differ diff --git a/include/images/rules.pngc b/include/images/rules.pngc new file mode 100644 index 0000000..56fc6bf --- /dev/null +++ b/include/images/rules.pngc @@ -0,0 +1,89 @@ +#ifndef RULES_PNG_H +#define RULES_PNG_H + +static const unsigned char rules_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x42, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xeb, 0xcc, 0x7a, 0xdd, +0xa9, 0x1d, 0xff, 0xe5, 0x9c, 0xff, 0xe5, 0x9a, +0xff, 0xe4, 0x96, 0xff, 0xe4, 0x92, 0xff, 0xe3, +0x8e, 0xff, 0xe5, 0x98, 0xff, 0xe5, 0x9b, 0xff, +0xe4, 0x94, 0xff, 0xe3, 0x90, 0xff, 0xe3, 0x8c, +0xeb, 0xc1, 0x4f, 0xfe, 0xe2, 0x87, 0xfe, 0xe2, +0x89, 0xfe, 0xe2, 0x85, 0xfe, 0xe1, 0x80, 0xfe, +0xe1, 0x82, 0xfe, 0xe1, 0x7e, 0xfe, 0xe1, 0x7c, +0xfe, 0xe0, 0x7a, 0x36, 0xb8, 0x2b, 0xe2, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5a, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x95, 0x8e, 0x4b, 0x0e, 0x80, +0x20, 0x0c, 0x44, 0xe1, 0xa1, 0x88, 0x8a, 0x28, +0x7e, 0xee, 0x7f, 0x55, 0x4b, 0x04, 0x12, 0xdc, +0x31, 0x9b, 0xa6, 0xd3, 0xd7, 0x4e, 0x95, 0xea, +0x97, 0xa6, 0x28, 0x1b, 0x18, 0x06, 0x46, 0x2c, +0x53, 0x76, 0x70, 0xb4, 0x8c, 0xcc, 0xcc, 0x2c, +0xee, 0xc2, 0xfa, 0x31, 0x78, 0xdc, 0x56, 0x19, +0x9d, 0x9c, 0xc4, 0x34, 0x77, 0x12, 0x93, 0x36, +0xa4, 0x06, 0x72, 0xb0, 0x95, 0xfd, 0x3d, 0x1c, +0xc4, 0x92, 0xe4, 0xa5, 0x3b, 0xe3, 0x75, 0x3f, +0xf5, 0x99, 0xdf, 0x73, 0x7d, 0x7a, 0x01, 0x1b, +0x48, 0x02, 0x60, 0xa7, 0x73, 0x42, 0xc8, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *rules_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_rules_png = new wxImage(); + if (!img_rules_png || !img_rules_png->IsOk()) + { + wxMemoryInputStream img_rules_pngIS(rules_png_data, sizeof(rules_png_data)); + img_rules_png->LoadFile(img_rules_pngIS, wxBITMAP_TYPE_PNG); + } + return img_rules_png; +} +#define rules_png_img rules_png_img() + +static wxBitmap *rules_png_bmp() +{ + static wxBitmap *bmp_rules_png; + if (!bmp_rules_png || !bmp_rules_png->IsOk()) + bmp_rules_png = new wxBitmap(*rules_png_img); + return bmp_rules_png; +} +#define rules_png_bmp rules_png_bmp() + +static wxIcon *rules_png_ico() +{ + static wxIcon *ico_rules_png; + if (!ico_rules_png || !ico_rules_png->IsOk()) + { + ico_rules_png = new wxIcon(); + ico_rules_png->CopyFromBitmap(*rules_png_bmp); + } + return ico_rules_png; +} +#define rules_png_ico rules_png_ico() + +#endif // RULES_PNG_H diff --git a/include/images/schedule.png b/include/images/schedule.png new file mode 100644 index 0000000..4203174 Binary files /dev/null and b/include/images/schedule.png differ diff --git a/include/images/schedule.pngc b/include/images/schedule.pngc new file mode 100644 index 0000000..f9e5c8f --- /dev/null +++ b/include/images/schedule.pngc @@ -0,0 +1,130 @@ +#ifndef SCHEDULE_PNG_H +#define SCHEDULE_PNG_H + +static const unsigned char schedule_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x2f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe2, 0x82, 0x76, 0xe7, +0x9f, 0x94, 0xe3, 0x89, 0x7e, 0xe7, 0x96, 0x8b, +0xf6, 0xd3, 0xd0, 0xef, 0xc6, 0xbe, 0xe1, 0x93, +0x85, 0xe2, 0x8d, 0x80, 0xe2, 0x87, 0x7b, 0xe2, +0x7c, 0x71, 0xe2, 0x76, 0x6c, 0xe3, 0x72, 0x68, +0xf0, 0xad, 0xa9, 0xe1, 0x92, 0x84, 0xe5, 0x9b, +0x90, 0xed, 0xbf, 0xba, 0xf1, 0xe0, 0xdf, 0xf0, +0xf6, 0xf8, 0xe9, 0xda, 0xdb, 0xe4, 0xb0, 0xad, +0xe3, 0x7a, 0x74, 0xe3, 0x63, 0x5b, 0xf0, 0xa6, +0xa2, 0xf5, 0xdd, 0xd9, 0xf0, 0xd3, 0xd0, 0xf4, +0xfb, 0xfd, 0xef, 0xf9, 0xfc, 0x1e, 0x50, 0xad, +0xe5, 0xf4, 0xfa, 0xdf, 0xf2, 0xf9, 0xdd, 0xbe, +0xc1, 0xe1, 0x6e, 0x69, 0xe3, 0x57, 0x51, 0xf6, +0xc6, 0xc4, 0xf4, 0xfa, 0xfd, 0xef, 0xf8, 0xfc, +0xea, 0xf6, 0xfb, 0xde, 0xf2, 0xf9, 0xd8, 0xef, +0xf7, 0xd2, 0xed, 0xf6, 0xd8, 0x9d, 0x9f, 0xe4, +0x4f, 0x49, 0xee, 0x8f, 0x8d, 0xef, 0xdf, 0xdf, +0xee, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe3, 0xf4, +0xfa, 0xcc, 0xea, 0xf5, 0xcd, 0xc6, 0xce, 0xe4, +0x48, 0x44, 0xe8, 0x60, 0x5c, 0xed, 0xf5, 0xf8, +0xe8, 0xf6, 0xfb, 0xe3, 0xf3, 0xf9, 0xdd, 0xf1, +0xf8, 0x89, 0xae, 0xd9, 0xcb, 0xea, 0xf5, 0xc5, +0xe7, 0xf4, 0xc0, 0xe1, 0xee, 0xe4, 0x42, 0x3e, +0xe5, 0x40, 0x3d, 0xe7, 0xd9, 0xda, 0xe2, 0xf3, +0xf9, 0xdc, 0xf1, 0xf8, 0xd6, 0xee, 0xf7, 0x82, +0xab, 0xd8, 0xbf, 0xe5, 0xf2, 0xc3, 0xbf, 0xc9, +0xe4, 0x3c, 0x39, 0xe9, 0x56, 0x53, 0xed, 0xaf, +0xa8, 0xe2, 0xaf, 0xad, 0xdb, 0xf0, 0xf8, 0xd5, +0xee, 0xf7, 0xcf, 0xec, 0xf6, 0xc9, 0xe9, 0xf5, +0x82, 0xab, 0xd7, 0x7b, 0xa8, 0xd6, 0xcd, 0x8c, +0x91, 0xe5, 0x36, 0x33, 0xef, 0x81, 0x7f, 0xe2, +0x7a, 0x74, 0xda, 0xbd, 0xc0, 0xcf, 0xeb, 0xf6, +0xc9, 0xe9, 0xf4, 0xc3, 0xe7, 0xf3, 0xbd, 0xe4, +0xf2, 0x7a, 0xa8, 0xd6, 0xc4, 0xa6, 0xaf, 0xde, +0x4b, 0x4b, 0xe5, 0x33, 0x30, 0xf7, 0xbb, 0xbb, +0xe0, 0x6e, 0x69, 0xd6, 0x9c, 0x9f, 0xca, 0xc4, +0xcd, 0xbe, 0xe0, 0xed, 0xc2, 0xbe, 0xc9, 0xcc, +0x8b, 0x91, 0xe5, 0x31, 0x2e, 0xf1, 0x8b, 0x8b, +0x2c, 0xbc, 0x56, 0xbe, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xb3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0xc0, 0x0a, 0x18, 0x99, 0x98, 0x59, +0x18, 0x59, 0xe1, 0x5c, 0x36, 0x76, 0x0e, 0x4e, +0x46, 0x2e, 0x6e, 0x1e, 0x5e, 0x98, 0x00, 0x1f, +0xbf, 0x80, 0xa0, 0x90, 0xb0, 0x88, 0xa8, 0x98, +0x38, 0x98, 0x2b, 0xc1, 0xce, 0x2f, 0x29, 0x25, +0x2d, 0x23, 0x2b, 0x27, 0xaf, 0xa0, 0xa8, 0x04, +0xd6, 0xcf, 0x21, 0xa0, 0xac, 0xa2, 0x2a, 0xa3, +0xa6, 0xae, 0xa1, 0xa9, 0xa5, 0x0d, 0x12, 0x60, +0xe2, 0xd4, 0xd1, 0xd5, 0xd3, 0x97, 0x51, 0xd7, +0x30, 0x30, 0x34, 0x32, 0x06, 0x09, 0x30, 0x33, +0x9a, 0x98, 0x9a, 0x99, 0xcb, 0x58, 0x58, 0x5a, +0x59, 0xdb, 0xd8, 0x82, 0x04, 0x58, 0xb8, 0xec, +0xec, 0x1d, 0x1c, 0x2d, 0x64, 0x9c, 0x9c, 0x5d, +0x5c, 0xdd, 0x40, 0x02, 0xee, 0xdc, 0x1e, 0x9e, +0x5e, 0xde, 0x3e, 0xbe, 0x32, 0x7e, 0xfe, 0x01, +0x81, 0x60, 0x6b, 0x78, 0x82, 0x82, 0x43, 0x42, +0xc3, 0xc2, 0x23, 0x22, 0xa3, 0xa2, 0x63, 0xc0, +0x02, 0xbc, 0x62, 0xb1, 0x71, 0xf1, 0x09, 0x89, +0x49, 0x51, 0xc9, 0x29, 0x50, 0x87, 0x89, 0x2b, +0x6a, 0x19, 0xd9, 0xb8, 0x06, 0x44, 0xa7, 0xc0, +0xdd, 0xae, 0xa4, 0x6d, 0x6c, 0xeb, 0x16, 0x18, +0xc3, 0x40, 0x1c, 0x00, 0x00, 0x95, 0xf7, 0x19, +0x84, 0xec, 0x44, 0x1a, 0x19, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *schedule_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_schedule_png = new wxImage(); + if (!img_schedule_png || !img_schedule_png->IsOk()) + { + wxMemoryInputStream img_schedule_pngIS(schedule_png_data, sizeof(schedule_png_data)); + img_schedule_png->LoadFile(img_schedule_pngIS, wxBITMAP_TYPE_PNG); + } + return img_schedule_png; +} +#define schedule_png_img schedule_png_img() + +static wxBitmap *schedule_png_bmp() +{ + static wxBitmap *bmp_schedule_png; + if (!bmp_schedule_png || !bmp_schedule_png->IsOk()) + bmp_schedule_png = new wxBitmap(*schedule_png_img); + return bmp_schedule_png; +} +#define schedule_png_bmp schedule_png_bmp() + +static wxIcon *schedule_png_ico() +{ + static wxIcon *ico_schedule_png; + if (!ico_schedule_png || !ico_schedule_png->IsOk()) + { + ico_schedule_png = new wxIcon(); + ico_schedule_png->CopyFromBitmap(*schedule_png_bmp); + } + return ico_schedule_png; +} +#define schedule_png_ico schedule_png_ico() + +#endif // SCHEDULE_PNG_H diff --git a/include/images/schedules.png b/include/images/schedules.png new file mode 100644 index 0000000..43b2ae4 Binary files /dev/null and b/include/images/schedules.png differ diff --git a/include/images/schedules.pngc b/include/images/schedules.pngc new file mode 100644 index 0000000..83d3bb8 --- /dev/null +++ b/include/images/schedules.pngc @@ -0,0 +1,126 @@ +#ifndef SCHEDULES_PNG_H +#define SCHEDULES_PNG_H + +static const unsigned char schedules_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x05, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xf8, 0xe7, 0xe4, 0xee, +0xc3, 0xbc, 0xe7, 0xa3, 0x98, 0xe3, 0x8b, 0x7f, +0xe7, 0x98, 0x8f, 0xef, 0xb5, 0xaf, 0xf9, 0xdf, +0xdc, 0xf4, 0xda, 0xd5, 0xe6, 0xa5, 0x99, 0xe2, +0x8e, 0x81, 0xe2, 0x88, 0x7c, 0xe2, 0x81, 0x76, +0xe2, 0x7a, 0x70, 0xe3, 0x73, 0x69, 0xe7, 0x82, +0x7b, 0xf5, 0xc7, 0xc4, 0xeb, 0xb4, 0xad, 0xed, +0xcb, 0xc5, 0xe8, 0xbf, 0xb8, 0xe3, 0x9b, 0x90, +0xe2, 0x89, 0x7d, 0xe2, 0x7c, 0x71, 0xe4, 0x78, +0x70, 0xf4, 0xc1, 0xbd, 0xee, 0xd6, 0xd1, 0xe3, +0xa4, 0x99, 0xe5, 0x73, 0x6b, 0xed, 0xca, 0xc5, +0xe7, 0xbe, 0xb8, 0xe3, 0x9a, 0x90, 0xf1, 0xda, +0xd7, 0xf0, 0xf4, 0xf7, 0xe8, 0xd2, 0xd2, 0xe3, +0x9f, 0x9c, 0xe3, 0x64, 0x5c, 0xe7, 0x76, 0x70, +0xf9, 0xd7, 0xd6, 0xe2, 0x88, 0x7d, 0xf5, 0xf8, +0xf9, 0xf0, 0xf9, 0xfc, 0x1e, 0x50, 0xad, 0xe2, +0xf3, 0xf9, 0xdb, 0xec, 0xf4, 0xdd, 0x93, 0x92, +0xe4, 0x54, 0x4e, 0xf0, 0x9c, 0x99, 0xf0, 0xd9, +0xd7, 0xef, 0xf8, 0xfc, 0xe8, 0xf6, 0xfa, 0xd9, +0xf0, 0xf8, 0xd2, 0xed, 0xf6, 0xd1, 0xc0, 0xc7, +0xe4, 0x4d, 0x47, 0xe9, 0x67, 0x64, 0xee, 0xf3, +0xf7, 0xe7, 0xf5, 0xfa, 0xe0, 0xf2, 0xf9, 0x89, +0xae, 0xd9, 0xc9, 0xe9, 0xf4, 0xc2, 0xe0, 0xec, +0xe4, 0x45, 0x41, 0xe5, 0x43, 0x3f, 0xe5, 0xd1, +0xd2, 0xde, 0xf2, 0xf9, 0xd7, 0xef, 0xf7, 0x88, +0xad, 0xd9, 0x7f, 0xa9, 0xd7, 0xc5, 0xb7, 0xc0, +0xe4, 0x3e, 0x3a, 0xe9, 0x5c, 0x59, 0xe1, 0x9d, +0x9b, 0xd5, 0xea, 0xf3, 0xce, 0xeb, 0xf5, 0xc6, +0xe8, 0xf4, 0x7f, 0xa9, 0xd6, 0xb9, 0xde, 0xec, +0xd1, 0x7b, 0x7f, 0xe4, 0x37, 0x34, 0xf1, 0x8c, +0x8b, 0xda, 0x91, 0x91, 0xce, 0xbe, 0xc6, 0xbf, +0xde, 0xeb, 0xc4, 0xb6, 0xc0, 0xe9, 0x50, 0x4f, +0xf9, 0xce, 0xcd, 0xf6, 0xb2, 0xb2, 0x5b, 0x82, +0x19, 0xf8, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xbc, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x60, 0x60, 0x64, 0x62, 0x66, 0x61, 0x65, 0x63, +0x67, 0x80, 0x01, 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, +0x5e, 0x3e, 0x7e, 0x01, 0x28, 0x9f, 0x91, 0x93, +0x4b, 0x50, 0x48, 0x58, 0x44, 0x54, 0x4c, 0x5c, +0x02, 0x22, 0xc0, 0xc4, 0x25, 0x28, 0x29, 0x05, +0x56, 0x23, 0x0d, 0x51, 0xc3, 0xcc, 0x2d, 0x23, +0x85, 0xa2, 0x86, 0x85, 0x47, 0x16, 0x55, 0x0d, +0x2b, 0xaf, 0x1c, 0x58, 0x8d, 0xbc, 0x82, 0xa2, +0x92, 0xb2, 0x8a, 0x2a, 0x03, 0x03, 0x1b, 0x9f, +0x1a, 0x48, 0x8d, 0xba, 0x86, 0xa6, 0x96, 0xb6, +0x8e, 0xae, 0x1e, 0x03, 0x03, 0x3b, 0xbf, 0x18, +0x50, 0x8d, 0xbe, 0x81, 0xa1, 0xa6, 0x91, 0xb1, +0x89, 0xa9, 0x19, 0x50, 0x8f, 0x80, 0x38, 0x50, +0x8d, 0xb9, 0x85, 0xa5, 0xa6, 0x95, 0xb5, 0x8d, +0xad, 0x1d, 0xc8, 0x58, 0x09, 0x69, 0x31, 0x5e, +0x7b, 0x07, 0x47, 0x27, 0x4d, 0x67, 0x17, 0x57, +0x37, 0xb0, 0xcd, 0x40, 0x35, 0xee, 0x1e, 0x9e, +0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x10, 0xc7, +0x49, 0x48, 0x2b, 0x07, 0x04, 0x06, 0x05, 0xfb, +0xfa, 0x85, 0x84, 0x42, 0xdd, 0x2f, 0xa0, 0xa2, +0x6b, 0x6a, 0xeb, 0xea, 0x17, 0x12, 0x06, 0xf7, +0xa1, 0xaa, 0x9e, 0x99, 0x9d, 0x9b, 0x7f, 0x28, +0x03, 0x16, 0x00, 0x00, 0xfe, 0xdd, 0x17, 0xa7, +0x45, 0x29, 0x9f, 0x80, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *schedules_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_schedules_png = new wxImage(); + if (!img_schedules_png || !img_schedules_png->IsOk()) + { + wxMemoryInputStream img_schedules_pngIS(schedules_png_data, sizeof(schedules_png_data)); + img_schedules_png->LoadFile(img_schedules_pngIS, wxBITMAP_TYPE_PNG); + } + return img_schedules_png; +} +#define schedules_png_img schedules_png_img() + +static wxBitmap *schedules_png_bmp() +{ + static wxBitmap *bmp_schedules_png; + if (!bmp_schedules_png || !bmp_schedules_png->IsOk()) + bmp_schedules_png = new wxBitmap(*schedules_png_img); + return bmp_schedules_png; +} +#define schedules_png_bmp schedules_png_bmp() + +static wxIcon *schedules_png_ico() +{ + static wxIcon *ico_schedules_png; + if (!ico_schedules_png || !ico_schedules_png->IsOk()) + { + ico_schedules_png = new wxIcon(); + ico_schedules_png->CopyFromBitmap(*schedules_png_bmp); + } + return ico_schedules_png; +} +#define schedules_png_ico schedules_png_ico() + +#endif // SCHEDULES_PNG_H diff --git a/include/images/sequence-repl.png b/include/images/sequence-repl.png new file mode 100644 index 0000000..676299f Binary files /dev/null and b/include/images/sequence-repl.png differ diff --git a/include/images/sequence-repl.pngc b/include/images/sequence-repl.pngc new file mode 100644 index 0000000..125c436 --- /dev/null +++ b/include/images/sequence-repl.pngc @@ -0,0 +1,118 @@ +#ifndef SEQUENCE_REPL_PNG_H +#define SEQUENCE_REPL_PNG_H + +static const unsigned char sequence_repl_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xed, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xa7, 0xdc, 0x84, +0x69, 0xc4, 0xca, 0xc6, 0xe2, 0xdf, 0xdf, 0xef, +0xe1, 0xdf, 0xed, 0xe2, 0xde, 0xee, 0xfb, 0xfd, +0xfb, 0xfc, 0xfc, 0xfc, 0xfa, 0xfc, 0xfc, 0xfd, +0xfb, 0xff, 0xfc, 0xfc, 0xfe, 0xff, 0xfb, 0xff, +0xee, 0xea, 0xf8, 0xf0, 0xea, 0xfa, 0xf0, 0xea, +0xf8, 0xda, 0xd0, 0xf0, 0xda, 0xce, 0xf0, 0xc1, +0xb1, 0xe6, 0xc2, 0xb2, 0xe5, 0x9c, 0xb2, 0x55, +0xb6, 0xde, 0x79, 0x94, 0xa1, 0x66, 0x87, 0x70, +0xbc, 0xab, 0x98, 0xd9, 0xa7, 0x98, 0xce, 0xad, +0x9a, 0xd3, 0xab, 0x97, 0xde, 0xad, 0x97, 0xde, +0x9c, 0xb3, 0x55, 0xaa, 0xd3, 0x6a, 0xb0, 0xdd, +0x77, 0x8c, 0xa8, 0x3a, 0xa2, 0xb0, 0x6f, 0x92, +0xbf, 0x4f, 0x87, 0xa0, 0x31, 0x9e, 0x88, 0xd7, +0x48, 0x82, 0xbe, 0x78, 0x92, 0xcb, 0x5f, 0x89, +0x81, 0x86, 0xb2, 0x68, 0x9b, 0xce, 0x61, 0x8d, +0xbc, 0x4a, 0x8f, 0xc8, 0x56, 0x7e, 0x99, 0x22, +0x73, 0xc6, 0xdf, 0x71, 0xc4, 0xde, 0x6e, 0xc1, +0xdd, 0x63, 0xae, 0xd3, 0x62, 0x91, 0x7e, 0x8d, +0xc2, 0x51, 0x89, 0xc4, 0x50, 0x82, 0xbf, 0x49, +0x70, 0xc3, 0xde, 0x6e, 0xc0, 0xdd, 0x5d, 0xa5, +0xcf, 0x5a, 0x89, 0x87, 0x88, 0xc2, 0x51, 0x83, +0xbd, 0x48, 0x7d, 0xba, 0x43, 0x78, 0xb7, 0x3e, +0x6d, 0xbf, 0xdc, 0x51, 0x91, 0xc5, 0x5d, 0xa6, +0xd0, 0x5b, 0xa5, 0xd0, 0x60, 0x7d, 0xaa, 0xaf, +0xac, 0xb9, 0x82, 0x73, 0xa1, 0xaa, 0xa3, 0xb3, +0x6f, 0x9c, 0xcc, 0x63, 0x9d, 0xcc, 0x8f, 0xb2, +0xd7, 0x64, 0x9b, 0xcb, 0x5e, 0xac, 0xd4, 0x52, +0x96, 0xc8, 0x61, 0x7a, 0xc1, 0x60, 0x92, 0xc6, +0x58, 0x99, 0xca, 0x87, 0xad, 0xd4, 0xa4, 0xd7, +0x13, 0x27, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x95, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0x00, 0x01, 0x46, 0x26, 0x46, 0x06, 0x64, 0xc0, +0xc8, 0xc4, 0x8c, 0x22, 0xc2, 0xc8, 0xc4, 0xc2, +0xca, 0x86, 0x2c, 0xc2, 0xc4, 0xce, 0xce, 0xc1, +0xc9, 0x89, 0x24, 0xc2, 0xc8, 0xc4, 0xc5, 0xc5, +0xcd, 0xc3, 0x85, 0x22, 0xc2, 0xcb, 0xc7, 0xcb, +0xcb, 0x8f, 0x22, 0x22, 0x20, 0x28, 0x20, 0x20, +0x80, 0x22, 0x22, 0x24, 0x24, 0x2c, 0x24, 0x04, +0x15, 0x11, 0x11, 0x15, 0x13, 0x97, 0x90, 0x94, +0x92, 0x96, 0x81, 0xa9, 0x90, 0x95, 0x93, 0x57, +0x50, 0x54, 0x52, 0x56, 0x81, 0xf0, 0x55, 0x55, +0x55, 0xd5, 0xd4, 0x35, 0x34, 0xb5, 0xb4, 0x75, +0xa0, 0xf2, 0xaa, 0xba, 0x7a, 0xfa, 0x06, 0x86, +0x46, 0xc6, 0x26, 0x3a, 0x50, 0xf5, 0xaa, 0xa6, +0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0x3a, +0x50, 0xf3, 0x55, 0x6d, 0xed, 0xec, 0x1d, 0x1c, +0x9d, 0x9c, 0x5d, 0x60, 0x16, 0xba, 0xba, 0xb9, +0x7b, 0x78, 0x7a, 0x79, 0xa3, 0xfa, 0xd6, 0xc7, +0xd7, 0x0f, 0xce, 0x06, 0x00, 0x45, 0x0c, 0x0d, +0xf4, 0x00, 0xdb, 0xf9, 0x11, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sequence_repl_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sequence_repl_png = new wxImage(); + if (!img_sequence_repl_png || !img_sequence_repl_png->IsOk()) + { + wxMemoryInputStream img_sequence_repl_pngIS(sequence_repl_png_data, sizeof(sequence_repl_png_data)); + img_sequence_repl_png->LoadFile(img_sequence_repl_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sequence_repl_png; +} +#define sequence_repl_png_img sequence_repl_png_img() + +static wxBitmap *sequence_repl_png_bmp() +{ + static wxBitmap *bmp_sequence_repl_png; + if (!bmp_sequence_repl_png || !bmp_sequence_repl_png->IsOk()) + bmp_sequence_repl_png = new wxBitmap(*sequence_repl_png_img); + return bmp_sequence_repl_png; +} +#define sequence_repl_png_bmp sequence_repl_png_bmp() + +static wxIcon *sequence_repl_png_ico() +{ + static wxIcon *ico_sequence_repl_png; + if (!ico_sequence_repl_png || !ico_sequence_repl_png->IsOk()) + { + ico_sequence_repl_png = new wxIcon(); + ico_sequence_repl_png->CopyFromBitmap(*sequence_repl_png_bmp); + } + return ico_sequence_repl_png; +} +#define sequence_repl_png_ico sequence_repl_png_ico() + +#endif // SEQUENCE_REPL_PNG_H diff --git a/include/images/sequence.png b/include/images/sequence.png new file mode 100644 index 0000000..1ce216c Binary files /dev/null and b/include/images/sequence.png differ diff --git a/include/images/sequence.pngc b/include/images/sequence.pngc new file mode 100644 index 0000000..6d03fcd --- /dev/null +++ b/include/images/sequence.pngc @@ -0,0 +1,95 @@ +#ifndef SEQUENCE_PNG_H +#define SEQUENCE_PNG_H + +static const unsigned char sequence_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x69, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xa7, 0xdc, 0x84, +0x69, 0xc4, 0xca, 0xc6, 0xe2, 0xdf, 0xdf, 0xef, +0xe1, 0xdf, 0xed, 0xe2, 0xde, 0xee, 0xfb, 0xfd, +0xfb, 0xfc, 0xfc, 0xfc, 0xfa, 0xfc, 0xfc, 0xfd, +0xfb, 0xff, 0xfc, 0xfc, 0xfe, 0xff, 0xfb, 0xff, +0xee, 0xea, 0xf8, 0xf0, 0xea, 0xfa, 0xf0, 0xea, +0xf8, 0xda, 0xd0, 0xf0, 0xda, 0xce, 0xf0, 0xc1, +0xb1, 0xe6, 0xc2, 0xb2, 0xe5, 0xab, 0x97, 0xdc, +0xaa, 0x98, 0xdd, 0xad, 0x97, 0xdc, 0xab, 0x97, +0xde, 0xad, 0x97, 0xde, 0xa0, 0x88, 0xd7, 0x9e, +0x88, 0xd7, 0x9e, 0x86, 0xd7, 0x9d, 0x85, 0xd6, +0xa5, 0x8f, 0xd8, 0xa5, 0x8f, 0xda, 0xb2, 0xa2, +0xdd, 0xb1, 0xa1, 0xde, 0xb0, 0xa0, 0xdd, 0xbe, +0xb2, 0xe3, 0x9c, 0x6e, 0x07, 0x8b, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x63, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x65, 0x8f, 0xc9, 0x1a, 0x40, 0x30, +0x0c, 0x06, 0x9b, 0xd8, 0x4b, 0xa9, 0xda, 0x5b, +0xb5, 0xbd, 0xff, 0x43, 0xe2, 0x42, 0xc2, 0xdc, +0x66, 0x0e, 0xff, 0x97, 0x08, 0x71, 0x01, 0x08, +0x82, 0x02, 0x18, 0xb0, 0x02, 0x18, 0x46, 0x31, +0x2d, 0x98, 0x24, 0x69, 0x96, 0x91, 0x02, 0x28, +0x65, 0x5e, 0x48, 0x56, 0x54, 0xa9, 0x54, 0xc5, +0x8a, 0xae, 0xb5, 0xd6, 0xac, 0x18, 0xd3, 0x18, +0xf3, 0x14, 0xc0, 0xb6, 0xeb, 0x87, 0x91, 0xf8, +0x64, 0x9d, 0xb3, 0xc4, 0xe7, 0x9b, 0x77, 0x01, +0xfd, 0xe2, 0xbd, 0x67, 0x8b, 0xeb, 0xb6, 0x7f, +0x6e, 0x3f, 0x7e, 0xdf, 0x71, 0x67, 0x9c, 0x0e, +0xb9, 0x04, 0x45, 0x50, 0x0a, 0x28, 0x6f, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sequence_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sequence_png = new wxImage(); + if (!img_sequence_png || !img_sequence_png->IsOk()) + { + wxMemoryInputStream img_sequence_pngIS(sequence_png_data, sizeof(sequence_png_data)); + img_sequence_png->LoadFile(img_sequence_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sequence_png; +} +#define sequence_png_img sequence_png_img() + +static wxBitmap *sequence_png_bmp() +{ + static wxBitmap *bmp_sequence_png; + if (!bmp_sequence_png || !bmp_sequence_png->IsOk()) + bmp_sequence_png = new wxBitmap(*sequence_png_img); + return bmp_sequence_png; +} +#define sequence_png_bmp sequence_png_bmp() + +static wxIcon *sequence_png_ico() +{ + static wxIcon *ico_sequence_png; + if (!ico_sequence_png || !ico_sequence_png->IsOk()) + { + ico_sequence_png = new wxIcon(); + ico_sequence_png->CopyFromBitmap(*sequence_png_bmp); + } + return ico_sequence_png; +} +#define sequence_png_ico sequence_png_ico() + +#endif // SEQUENCE_PNG_H diff --git a/include/images/sequences.png b/include/images/sequences.png new file mode 100644 index 0000000..905554d Binary files /dev/null and b/include/images/sequences.png differ diff --git a/include/images/sequences.pngc b/include/images/sequences.pngc new file mode 100644 index 0000000..ac0bde0 --- /dev/null +++ b/include/images/sequences.pngc @@ -0,0 +1,89 @@ +#ifndef SEQUENCES_PNG_H +#define SEQUENCES_PNG_H + +static const unsigned char sequences_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x3f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb7, 0xa7, 0xdc, 0x84, +0x69, 0xc4, 0xfa, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, +0xff, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xee, 0xea, +0xf8, 0xb0, 0x9e, 0xd9, 0xad, 0x97, 0xdc, 0x94, +0x7c, 0xcf, 0x9e, 0x86, 0xd7, 0x9e, 0x88, 0xd7, +0xf0, 0xea, 0xf8, 0x9d, 0x85, 0xd6, 0xda, 0xd0, +0xf0, 0xa5, 0x8f, 0xd8, 0xc2, 0xb2, 0xe5, 0xc1, +0xb1, 0xe6, 0xab, 0x97, 0xde, 0xad, 0x97, 0xde, +0x26, 0x4d, 0x26, 0x20, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x65, 0xcf, 0x5b, 0x0e, 0x80, 0x20, 0x0c, 0x44, +0xd1, 0xce, 0xf8, 0x40, 0x45, 0x01, 0xd1, 0xfd, +0xaf, 0x55, 0x10, 0x34, 0x54, 0xfb, 0xd7, 0x9b, +0x13, 0x48, 0x45, 0x04, 0x84, 0xb4, 0x03, 0x76, +0xba, 0xb0, 0x1f, 0x46, 0xb6, 0x09, 0x34, 0x93, +0x46, 0xe0, 0x17, 0xa5, 0xa2, 0x10, 0x38, 0x2f, +0x05, 0xa1, 0xee, 0xd6, 0xae, 0x4c, 0xc8, 0x6c, +0xa5, 0xd0, 0x39, 0xc7, 0x8c, 0xbc, 0xf7, 0x77, +0x01, 0x03, 0x0b, 0xda, 0x63, 0xac, 0xa5, 0xa2, +0xe3, 0x7c, 0xde, 0x7d, 0x11, 0x9a, 0x8f, 0x33, +0x82, 0xba, 0x28, 0xfc, 0x6e, 0xd4, 0xfb, 0x3b, +0x17, 0x56, 0x47, 0x02, 0xc0, 0x66, 0x1a, 0x00, +0xd1, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sequences_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sequences_png = new wxImage(); + if (!img_sequences_png || !img_sequences_png->IsOk()) + { + wxMemoryInputStream img_sequences_pngIS(sequences_png_data, sizeof(sequences_png_data)); + img_sequences_png->LoadFile(img_sequences_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sequences_png; +} +#define sequences_png_img sequences_png_img() + +static wxBitmap *sequences_png_bmp() +{ + static wxBitmap *bmp_sequences_png; + if (!bmp_sequences_png || !bmp_sequences_png->IsOk()) + bmp_sequences_png = new wxBitmap(*sequences_png_img); + return bmp_sequences_png; +} +#define sequences_png_bmp sequences_png_bmp() + +static wxIcon *sequences_png_ico() +{ + static wxIcon *ico_sequences_png; + if (!ico_sequences_png || !ico_sequences_png->IsOk()) + { + ico_sequences_png = new wxIcon(); + ico_sequences_png->CopyFromBitmap(*sequences_png_bmp); + } + return ico_sequences_png; +} +#define sequences_png_ico sequences_png_ico() + +#endif // SEQUENCES_PNG_H diff --git a/include/images/server-sm.png b/include/images/server-sm.png new file mode 100644 index 0000000..40d864d Binary files /dev/null and b/include/images/server-sm.png differ diff --git a/include/images/server-sm.pngc b/include/images/server-sm.pngc new file mode 100644 index 0000000..3183e47 --- /dev/null +++ b/include/images/server-sm.pngc @@ -0,0 +1,119 @@ +#ifndef SERVER_SM_PNG_H +#define SERVER_SM_PNG_H + +static const unsigned char server_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x05, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x9a, +0x86, 0x94, 0xd2, 0xc4, 0xcd, 0xe3, 0xd6, 0xdf, +0xd8, 0xc8, 0xd4, 0xcd, 0xba, 0xc8, 0xc3, 0xac, +0xbd, 0xa2, 0x8a, 0x9b, 0xab, 0x9a, 0xa6, 0xdd, +0xd2, 0xd9, 0xe2, 0xd6, 0xde, 0xd7, 0xc8, 0xd3, +0xcd, 0xba, 0xc7, 0xc3, 0xad, 0xbc, 0xae, 0x96, +0xa8, 0x96, 0x81, 0x90, 0xae, 0x9d, 0xa8, 0xe6, +0xde, 0xe3, 0xec, 0xe5, 0xea, 0xe5, 0xdb, 0xe1, +0xe1, 0xd7, 0xde, 0xda, 0xcd, 0xd7, 0xcd, 0xbd, +0xc8, 0x94, 0x7f, 0x8d, 0xab, 0x9a, 0xa5, 0xe6, +0xe2, 0xe4, 0xf6, 0xf5, 0xf6, 0xe7, 0xdd, 0xe0, +0xd5, 0xc5, 0xcb, 0xcc, 0xb8, 0xbf, 0xce, 0xbb, +0xc3, 0x96, 0x81, 0x8e, 0xe5, 0xe1, 0xe3, 0xf5, +0xf4, 0xf5, 0xde, 0xd1, 0xd5, 0xbf, 0xa5, 0xaf, +0xb2, 0x91, 0x9e, 0xbc, 0xa2, 0xac, 0x93, 0x7c, +0x8a, 0xe6, 0xe1, 0xe4, 0xf5, 0xf4, 0xf4, 0xdf, +0xd2, 0xd6, 0xbf, 0xa5, 0xae, 0xb1, 0x91, 0x9d, +0xbd, 0xa3, 0xad, 0x93, 0x7c, 0x8b, 0xe5, 0xe1, +0xe4, 0xbf, 0xa4, 0xaf, 0xbd, 0xa2, 0xac, 0xdf, +0xdb, 0xdd, 0xf4, 0xf2, 0xf3, 0xdf, 0xd1, 0xd5, +0xb9, 0x9f, 0xa8, 0xb2, 0x92, 0x9e, 0xb8, 0x9e, +0xa9, 0x91, 0x7a, 0x89, 0xd4, 0xd0, 0xd2, 0xe4, +0xe3, 0xe4, 0xac, 0x93, 0x9d, 0xab, 0x8c, 0x98, +0xb0, 0x98, 0xa2, 0x8e, 0x77, 0x85, 0xa1, 0x90, +0x9b, 0xe0, 0xdb, 0xde, 0xcb, 0xbf, 0xc4, 0xb6, +0xa2, 0xad, 0x81, 0x8c, 0x9a, 0x93, 0xa2, 0xaf, +0x8b, 0x7c, 0x8b, 0xa5, 0x94, 0x9f, 0xcf, 0xcb, +0xcd, 0xf1, 0xf0, 0xf1, 0xd2, 0xc6, 0xcb, 0x9c, +0x97, 0xa1, 0x4e, 0xad, 0xb4, 0x4c, 0xb3, 0xb8, +0x7b, 0x7a, 0x8a, 0xe1, 0xdd, 0xdf, 0xd6, 0xd5, +0xd5, 0xdf, 0xd1, 0xd6, 0xa9, 0x9e, 0xa9, 0x5d, +0x96, 0xa4, 0x6d, 0xab, 0xb7, 0x82, 0x7b, 0x8b, +0x83, 0x6d, 0x7c, 0x82, 0x6c, 0x7c, 0x02, 0xa1, +0xb1, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x88, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x06, 0x18, 0xc1, 0x00, 0x49, 0x80, 0x89, +0x99, 0x85, 0x95, 0x8d, 0x9d, 0x03, 0x21, 0xc0, +0xc9, 0xc5, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, 0x00, +0x17, 0x10, 0x14, 0x12, 0x16, 0x11, 0x15, 0x13, +0x97, 0x80, 0x0b, 0x48, 0x4a, 0x49, 0xcb, 0xc8, +0xca, 0xc9, 0x2b, 0x20, 0x04, 0x14, 0x95, 0x94, +0x55, 0x54, 0xd5, 0xd4, 0x11, 0x02, 0x1a, 0x9a, +0x5a, 0xda, 0x3a, 0xba, 0x7a, 0x08, 0x01, 0x7d, +0x25, 0x65, 0x03, 0x1d, 0x43, 0x24, 0x15, 0x46, +0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x08, 0x01, +0x4b, 0x2b, 0x65, 0x6b, 0x1b, 0x5b, 0x3b, 0xb8, +0x80, 0xbd, 0x83, 0x95, 0xa3, 0x93, 0xb3, 0x8b, +0x2b, 0x5c, 0xc0, 0xcd, 0xdd, 0xc3, 0xd3, 0xcb, +0xdb, 0xc7, 0x17, 0xa1, 0xc5, 0xcf, 0x3f, 0x20, +0x30, 0x28, 0x38, 0x04, 0xe1, 0xb9, 0x50, 0xa0, +0xdf, 0xc2, 0xc2, 0x90, 0xbd, 0x87, 0x00, 0x00, +0x7b, 0xdb, 0x10, 0x89, 0x63, 0xc0, 0x91, 0x38, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *server_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_server_sm_png = new wxImage(); + if (!img_server_sm_png || !img_server_sm_png->IsOk()) + { + wxMemoryInputStream img_server_sm_pngIS(server_sm_png_data, sizeof(server_sm_png_data)); + img_server_sm_png->LoadFile(img_server_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_server_sm_png; +} +#define server_sm_png_img server_sm_png_img() + +static wxBitmap *server_sm_png_bmp() +{ + static wxBitmap *bmp_server_sm_png; + if (!bmp_server_sm_png || !bmp_server_sm_png->IsOk()) + bmp_server_sm_png = new wxBitmap(*server_sm_png_img); + return bmp_server_sm_png; +} +#define server_sm_png_bmp server_sm_png_bmp() + +static wxIcon *server_sm_png_ico() +{ + static wxIcon *ico_server_sm_png; + if (!ico_server_sm_png || !ico_server_sm_png->IsOk()) + { + ico_server_sm_png = new wxIcon(); + ico_server_sm_png->CopyFromBitmap(*server_sm_png_bmp); + } + return ico_server_sm_png; +} +#define server_sm_png_ico server_sm_png_ico() + +#endif // SERVER_SM_PNG_H diff --git a/include/images/server.png b/include/images/server.png new file mode 100644 index 0000000..2ab73d5 Binary files /dev/null and b/include/images/server.png differ diff --git a/include/images/server.pngc b/include/images/server.pngc new file mode 100644 index 0000000..fc52104 --- /dev/null +++ b/include/images/server.pngc @@ -0,0 +1,114 @@ +#ifndef SERVER_PNG_H +#define SERVER_PNG_H + +static const unsigned char server_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd2, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x96, +0x81, 0x8f, 0xea, 0xdf, 0xe7, 0xe2, 0xd5, 0xde, +0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, 0xc6, 0xb1, +0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, 0x82, 0x99, +0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, 0xdf, 0xe5, +0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, 0xbf, 0xa8, +0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, 0xd8, 0xea, +0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, 0xbe, 0xca, +0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, 0xf2, 0xf1, +0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0xfa, +0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, 0xdb, 0xdf, +0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, 0xe0, 0xd3, +0xd7, 0xc4, 0xab, 0xb5, 0xb0, 0x90, 0x9b, 0xb4, +0x95, 0xa1, 0xc4, 0xad, 0xb6, 0xef, 0xee, 0xee, +0xf7, 0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0xb2, 0x90, +0x9e, 0xc3, 0xad, 0xb5, 0xf6, 0xf5, 0xf5, 0xe1, +0xd4, 0xd8, 0xc4, 0xae, 0xb8, 0xef, 0xee, 0xef, +0xc3, 0xaa, 0xb3, 0xb2, 0x90, 0x9d, 0xc4, 0xad, +0xb7, 0xc7, 0xc6, 0xc7, 0xe0, 0xd4, 0xd8, 0xa2, +0x8c, 0x94, 0xb5, 0x96, 0xa3, 0xa1, 0x8e, 0x96, +0xcd, 0xcc, 0xcc, 0x91, 0x75, 0x80, 0xb4, 0x96, +0xa1, 0xc3, 0xad, 0xb6, 0xac, 0xa2, 0xa7, 0xf0, +0xee, 0xf0, 0xba, 0xb0, 0xb4, 0x7b, 0x94, 0xa4, +0x4b, 0x98, 0xa8, 0x8c, 0xab, 0xb8, 0xe1, 0xd4, +0xd9, 0xa1, 0x8c, 0x94, 0x5a, 0xa2, 0xb4, 0x1f, +0xda, 0xc7, 0x52, 0xa4, 0xb3, 0x67, 0x83, 0x92, +0x5b, 0xa5, 0xb6, 0xb8, 0xda, 0xef, 0x96, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x8e, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, +0x08, 0x60, 0x80, 0x03, 0x26, 0x66, 0x16, 0x56, +0x36, 0x76, 0x0e, 0x4e, 0x18, 0x9f, 0x8b, 0x9b, +0x87, 0x85, 0x97, 0x8f, 0x9d, 0x5f, 0x80, 0x0b, +0x2a, 0xc0, 0x28, 0x28, 0x24, 0xcc, 0x2b, 0xc2, +0xce, 0x21, 0x0a, 0xd3, 0xc4, 0x28, 0x26, 0x2e, +0x21, 0x29, 0x21, 0x25, 0x2d, 0x83, 0x10, 0x90, +0x95, 0x93, 0x57, 0x50, 0x54, 0x52, 0x46, 0x08, +0xa8, 0xa8, 0xca, 0xab, 0xa9, 0x2b, 0x69, 0x20, +0xa9, 0xd0, 0xd4, 0x52, 0x53, 0x54, 0xd2, 0x46, +0x08, 0xe8, 0xa8, 0xa2, 0x69, 0x91, 0x95, 0xd3, +0xd2, 0xd5, 0x53, 0xd2, 0x47, 0x08, 0x18, 0xa8, +0x1a, 0x1a, 0xe9, 0x19, 0x9b, 0x20, 0x69, 0x31, +0xd5, 0x52, 0x30, 0x33, 0xb7, 0x80, 0x0b, 0x58, +0x5a, 0xa9, 0x5a, 0xab, 0xd9, 0xd8, 0xda, 0x21, +0x69, 0x91, 0xb3, 0x77, 0x70, 0x74, 0x72, 0x46, +0xd1, 0xa2, 0xeb, 0xe2, 0x8a, 0x50, 0x01, 0x07, +0x40, 0x0e, 0x00, 0x5a, 0x67, 0x0f, 0x17, 0x87, +0x0c, 0x6b, 0x93, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *server_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_server_png = new wxImage(); + if (!img_server_png || !img_server_png->IsOk()) + { + wxMemoryInputStream img_server_pngIS(server_png_data, sizeof(server_png_data)); + img_server_png->LoadFile(img_server_pngIS, wxBITMAP_TYPE_PNG); + } + return img_server_png; +} +#define server_png_img server_png_img() + +static wxBitmap *server_png_bmp() +{ + static wxBitmap *bmp_server_png; + if (!bmp_server_png || !bmp_server_png->IsOk()) + bmp_server_png = new wxBitmap(*server_png_img); + return bmp_server_png; +} +#define server_png_bmp server_png_bmp() + +static wxIcon *server_png_ico() +{ + static wxIcon *ico_server_png; + if (!ico_server_png || !ico_server_png->IsOk()) + { + ico_server_png = new wxIcon(); + ico_server_png->CopyFromBitmap(*server_png_bmp); + } + return ico_server_png; +} +#define server_png_ico server_png_ico() + +#endif // SERVER_PNG_H diff --git a/include/images/serverbad-sm.png b/include/images/serverbad-sm.png new file mode 100644 index 0000000..ddb7adb Binary files /dev/null and b/include/images/serverbad-sm.png differ diff --git a/include/images/serverbad-sm.pngc b/include/images/serverbad-sm.pngc new file mode 100644 index 0000000..bb4dc04 --- /dev/null +++ b/include/images/serverbad-sm.pngc @@ -0,0 +1,133 @@ +#ifndef SERVERBAD_SM_PNG_H +#define SERVERBAD_SM_PNG_H + +static const unsigned char serverbad_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x59, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x9b, +0x87, 0x95, 0xd2, 0xc4, 0xce, 0xe3, 0xd6, 0xdf, +0xd8, 0xc8, 0xd4, 0xcd, 0xba, 0xc8, 0xc3, 0xac, +0xbd, 0xa2, 0x8a, 0x9b, 0xac, 0x9b, 0xa6, 0xde, +0xd2, 0xda, 0xe2, 0xd6, 0xde, 0xd7, 0xc8, 0xd3, +0xcd, 0xba, 0xc7, 0xc3, 0xad, 0xbc, 0xaf, 0x97, +0xa8, 0x92, 0x7a, 0x8b, 0xad, 0x9d, 0xa8, 0xe6, +0xdf, 0xe4, 0xee, 0xe8, 0xec, 0xe8, 0xdf, 0xe4, +0xe5, 0xdd, 0xe3, 0xdf, 0xd4, 0xdc, 0xd2, 0xc3, +0xcd, 0x95, 0x80, 0x8f, 0xab, 0x9a, 0xa5, 0xd9, +0x99, 0x9b, 0xd3, 0x49, 0x49, 0xd9, 0x81, 0x83, +0xce, 0xba, 0xc2, 0xc3, 0xab, 0xb4, 0xc9, 0x88, +0x8e, 0xba, 0x30, 0x35, 0xd8, 0x60, 0x61, 0xa8, +0x62, 0x6b, 0xc7, 0x20, 0x21, 0xec, 0x60, 0x60, +0xc5, 0x09, 0x0a, 0xc0, 0x5c, 0x62, 0xb6, 0x71, +0x7c, 0xc1, 0x20, 0x22, 0xe3, 0x3d, 0x3d, 0xc9, +0x0d, 0x0d, 0xdd, 0x69, 0x69, 0xa5, 0x38, 0x40, +0xe3, 0x4b, 0x4b, 0xf5, 0x70, 0x70, 0xf2, 0x68, +0x68, 0xc7, 0x14, 0x15, 0xc2, 0x23, 0x26, 0xdf, +0x34, 0x34, 0xef, 0x4f, 0x50, 0xe9, 0x41, 0x41, +0xc7, 0x0b, 0x0b, 0xa9, 0x6f, 0x79, 0xca, 0x37, +0x38, 0xe3, 0x46, 0x46, 0xf3, 0x65, 0x65, 0xeb, +0x50, 0x50, 0xdd, 0x2f, 0x2f, 0xef, 0x4e, 0x4f, +0xe5, 0x39, 0x39, 0xcd, 0x20, 0x20, 0xcf, 0xa1, +0xa3, 0xcf, 0x3d, 0x3d, 0xdd, 0x33, 0x34, 0xf0, +0x55, 0x56, 0xef, 0x4d, 0x4e, 0xe2, 0x34, 0x34, +0xc0, 0x19, 0x1b, 0xd7, 0x5c, 0x5d, 0xd0, 0x97, +0x99, 0xcc, 0x2e, 0x2e, 0xe2, 0x38, 0x38, 0xef, +0x4c, 0x4d, 0xed, 0x44, 0x45, 0xe4, 0x31, 0x31, +0xc4, 0x14, 0x16, 0xd9, 0x5e, 0x5e, 0xa1, 0x60, +0x69, 0xc4, 0x24, 0x25, 0xe5, 0x3e, 0x3e, 0xef, +0x4b, 0x4b, 0xe5, 0x38, 0x38, 0xd7, 0x1c, 0x1c, +0xea, 0x34, 0x34, 0xe5, 0x28, 0x28, 0xca, 0x11, +0x11, 0xdd, 0x68, 0x68, 0xa5, 0x35, 0x3c, 0xe1, +0x37, 0x37, 0xee, 0x4a, 0x4a, 0xe9, 0x3d, 0x3e, +0xba, 0x11, 0x13, 0xa8, 0x2a, 0x2f, 0xd8, 0x18, +0x18, 0xe7, 0x25, 0x25, 0xe5, 0x1f, 0x1f, 0xc5, +0x03, 0x03, 0x9f, 0x61, 0x6b, 0xbd, 0x21, 0x24, +0xdf, 0x2d, 0x2e, 0xbe, 0x0c, 0x0e, 0xa5, 0x58, +0x61, 0x7c, 0x6a, 0x77, 0xac, 0x26, 0x2b, 0xd7, +0x14, 0x15, 0xcc, 0x17, 0x17, 0xdc, 0x69, 0x69, +0x9e, 0x3f, 0x49, 0xc1, 0x05, 0x06, 0xa8, 0x2e, +0x36, 0x99, 0x47, 0x52, 0xbe, 0x0b, 0x0d, 0xdb, +0x60, 0x60, 0xf6, 0x7f, 0xd9, 0x0f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x9f, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0xc0, 0x02, 0x18, 0x21, +0x00, 0x21, 0xc0, 0xc4, 0xcc, 0xc2, 0xca, 0xc6, +0xce, 0x81, 0x10, 0xe0, 0xe4, 0xe2, 0xe6, 0xe1, +0xe5, 0xe3, 0x17, 0x80, 0x0b, 0x08, 0x0a, 0x09, +0x8b, 0x88, 0x8a, 0x89, 0x4b, 0xc0, 0x05, 0x24, +0xa5, 0xa4, 0x65, 0x64, 0xe5, 0xe4, 0x15, 0x14, +0x61, 0x02, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, +0x1a, 0x9a, 0x5a, 0xda, 0x50, 0x01, 0x1d, 0x5d, +0x3d, 0x7d, 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, +0xa8, 0x80, 0x99, 0xb9, 0x85, 0xa5, 0x95, 0xb5, +0x8d, 0xad, 0x1d, 0x4c, 0x85, 0xa4, 0xbd, 0x83, +0xa3, 0x93, 0xb3, 0x8b, 0xab, 0x1b, 0xdc, 0x50, +0x77, 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, +0x98, 0x80, 0x7f, 0x40, 0x60, 0x50, 0x70, 0x48, +0x68, 0x58, 0x78, 0x04, 0x54, 0x20, 0x32, 0x2a, +0x3a, 0x26, 0x36, 0x2e, 0x3e, 0x21, 0x31, 0x09, +0x2a, 0x90, 0x9c, 0x92, 0x9a, 0x96, 0x9e, 0x91, +0x99, 0x95, 0x9d, 0x03, 0xf3, 0x5c, 0x6e, 0x5e, +0x3e, 0x23, 0x63, 0x41, 0x61, 0x11, 0x36, 0x9f, +0x33, 0x00, 0x00, 0x60, 0xd0, 0x1a, 0x02, 0x8f, +0x05, 0x3b, 0xa3, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *serverbad_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_serverbad_sm_png = new wxImage(); + if (!img_serverbad_sm_png || !img_serverbad_sm_png->IsOk()) + { + wxMemoryInputStream img_serverbad_sm_pngIS(serverbad_sm_png_data, sizeof(serverbad_sm_png_data)); + img_serverbad_sm_png->LoadFile(img_serverbad_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_serverbad_sm_png; +} +#define serverbad_sm_png_img serverbad_sm_png_img() + +static wxBitmap *serverbad_sm_png_bmp() +{ + static wxBitmap *bmp_serverbad_sm_png; + if (!bmp_serverbad_sm_png || !bmp_serverbad_sm_png->IsOk()) + bmp_serverbad_sm_png = new wxBitmap(*serverbad_sm_png_img); + return bmp_serverbad_sm_png; +} +#define serverbad_sm_png_bmp serverbad_sm_png_bmp() + +static wxIcon *serverbad_sm_png_ico() +{ + static wxIcon *ico_serverbad_sm_png; + if (!ico_serverbad_sm_png || !ico_serverbad_sm_png->IsOk()) + { + ico_serverbad_sm_png = new wxIcon(); + ico_serverbad_sm_png->CopyFromBitmap(*serverbad_sm_png_bmp); + } + return ico_serverbad_sm_png; +} +#define serverbad_sm_png_ico serverbad_sm_png_ico() + +#endif // SERVERBAD_SM_PNG_H diff --git a/include/images/serverbad.png b/include/images/serverbad.png new file mode 100644 index 0000000..2061239 Binary files /dev/null and b/include/images/serverbad.png differ diff --git a/include/images/serverbad.pngc b/include/images/serverbad.pngc new file mode 100644 index 0000000..e799deb --- /dev/null +++ b/include/images/serverbad.pngc @@ -0,0 +1,125 @@ +#ifndef SERVERBAD_PNG_H +#define SERVERBAD_PNG_H + +static const unsigned char serverbad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x14, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x96, +0x81, 0x8f, 0xea, 0xdf, 0xe7, 0xe2, 0xd5, 0xde, +0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, 0xc6, 0xb1, +0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, 0x82, 0x99, +0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, 0xdf, 0xe5, +0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, 0xbf, 0xa8, +0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, 0xd8, 0xea, +0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, 0xbe, 0xca, +0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, 0xf2, 0xf1, +0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0xfa, +0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, 0xdb, 0xdf, +0xd7, 0x62, 0x62, 0xc5, 0x00, 0x00, 0xd0, 0x57, +0x59, 0xc4, 0xab, 0xb5, 0xb0, 0x90, 0x9b, 0xb4, +0x95, 0xa1, 0xc5, 0x47, 0x4b, 0xdd, 0x69, 0x69, +0xca, 0x51, 0x54, 0xf6, 0x77, 0x77, 0xc5, 0x46, +0x4a, 0xb2, 0x90, 0x9e, 0xbe, 0x3d, 0x42, 0xf1, +0x57, 0x57, 0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, +0xf5, 0x6e, 0x6e, 0xbc, 0x3b, 0x40, 0xf1, 0x56, +0x56, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0xf5, +0x6d, 0x6d, 0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, +0xf0, 0x55, 0x55, 0xef, 0x4e, 0x4f, 0xee, 0x48, +0x48, 0xf3, 0x61, 0x61, 0xf1, 0x5b, 0x5b, 0xf0, +0x54, 0x54, 0xef, 0x4d, 0x4e, 0xee, 0x47, 0x47, +0xc7, 0xc6, 0xc7, 0xda, 0x65, 0x65, 0xf0, 0x53, +0x54, 0xef, 0x4d, 0x4d, 0xee, 0x46, 0x46, 0xaa, +0x2c, 0x33, 0xd6, 0x62, 0x62, 0xf0, 0x53, 0x53, +0xef, 0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, +0x3f, 0xeb, 0x38, 0x38, 0xbb, 0x43, 0x45, 0xf0, +0x52, 0x52, 0xef, 0x4b, 0x4b, 0xed, 0x44, 0x45, +0xeb, 0x37, 0x37, 0xea, 0x31, 0x31, 0xe9, 0x2b, +0x2b, 0xf0, 0x51, 0x51, 0xee, 0x4a, 0x4a, 0xed, +0x43, 0x44, 0x99, 0x43, 0x4a, 0xe9, 0x2a, 0x2b, +0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, 0xed, 0x42, +0x43, 0xc4, 0x46, 0x4a, 0x67, 0x83, 0x92, 0x99, +0x44, 0x4b, 0xe7, 0x1f, 0x20, 0x84, 0xa8, 0x02, +0xeb, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa6, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0x8d, 0x55, +0x0e, 0xc3, 0x40, 0x10, 0x43, 0xb3, 0xa5, 0x94, +0x99, 0xc1, 0x65, 0x66, 0x66, 0x4a, 0x99, 0x99, +0xef, 0x7f, 0x8f, 0xa6, 0x52, 0x76, 0xeb, 0x8f, +0x91, 0xfc, 0xe4, 0xb1, 0x39, 0x4e, 0x14, 0x91, +0xc4, 0x51, 0xc9, 0xe4, 0x0a, 0xa5, 0x8a, 0x57, +0x6b, 0xa8, 0xd7, 0xea, 0xf4, 0x0a, 0x83, 0x91, +0x37, 0x99, 0x29, 0x20, 0x16, 0xab, 0xcd, 0x60, +0xe7, 0xd5, 0x0e, 0xfa, 0x43, 0x9c, 0x2e, 0xb7, +0xc7, 0xed, 0xf5, 0xf9, 0xff, 0x20, 0x80, 0x60, +0x28, 0x1c, 0x89, 0x22, 0x26, 0x81, 0x38, 0x12, +0x48, 0xa6, 0xd2, 0xc8, 0x48, 0x84, 0x20, 0x9b, +0xcb, 0xa3, 0x80, 0x62, 0xa9, 0x0c, 0x9a, 0xa8, +0x54, 0x6b, 0xa8, 0x37, 0x9a, 0x34, 0x21, 0x76, +0xb4, 0xda, 0x9d, 0x6e, 0x8f, 0x75, 0x38, 0xfb, +0x03, 0x0c, 0x47, 0x63, 0x08, 0x6c, 0x65, 0x82, +0xe9, 0x6c, 0xbe, 0x58, 0xb2, 0xc4, 0x0a, 0xeb, +0xcd, 0x16, 0xbb, 0xfd, 0x81, 0xad, 0x1c, 0x4f, +0x67, 0x5c, 0x70, 0xbd, 0xdd, 0xd9, 0xca, 0x03, +0xcf, 0xd7, 0x1b, 0x1f, 0x9a, 0x20, 0x02, 0x04, +0xf2, 0xbb, 0xa2, 0xff, 0x02, 0x8e, 0x5c, 0x16, +0xd7, 0xaa, 0x72, 0xf6, 0xc5, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *serverbad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_serverbad_png = new wxImage(); + if (!img_serverbad_png || !img_serverbad_png->IsOk()) + { + wxMemoryInputStream img_serverbad_pngIS(serverbad_png_data, sizeof(serverbad_png_data)); + img_serverbad_png->LoadFile(img_serverbad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_serverbad_png; +} +#define serverbad_png_img serverbad_png_img() + +static wxBitmap *serverbad_png_bmp() +{ + static wxBitmap *bmp_serverbad_png; + if (!bmp_serverbad_png || !bmp_serverbad_png->IsOk()) + bmp_serverbad_png = new wxBitmap(*serverbad_png_img); + return bmp_serverbad_png; +} +#define serverbad_png_bmp serverbad_png_bmp() + +static wxIcon *serverbad_png_ico() +{ + static wxIcon *ico_serverbad_png; + if (!ico_serverbad_png || !ico_serverbad_png->IsOk()) + { + ico_serverbad_png = new wxIcon(); + ico_serverbad_png->CopyFromBitmap(*serverbad_png_bmp); + } + return ico_serverbad_png; +} +#define serverbad_png_ico serverbad_png_ico() + +#endif // SERVERBAD_PNG_H diff --git a/include/images/servers.png b/include/images/servers.png new file mode 100644 index 0000000..bd49bd2 Binary files /dev/null and b/include/images/servers.png differ diff --git a/include/images/servers.pngc b/include/images/servers.pngc new file mode 100644 index 0000000..fd96384 --- /dev/null +++ b/include/images/servers.pngc @@ -0,0 +1,107 @@ +#ifndef SERVERS_PNG_H +#define SERVERS_PNG_H + +static const unsigned char servers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb4, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0x6c, 0x7c, 0x96, +0x81, 0x8f, 0xea, 0xdf, 0xe7, 0xe2, 0xd5, 0xde, +0xd9, 0xc9, 0xd5, 0xd0, 0xbd, 0xcb, 0xc6, 0xb1, +0xc0, 0xbf, 0xa6, 0xb9, 0x89, 0x72, 0x82, 0x99, +0x86, 0x93, 0xb8, 0xa8, 0xb3, 0xe9, 0xdf, 0xe5, +0xd8, 0xc9, 0xd4, 0xcf, 0xbd, 0xca, 0xbf, 0xa8, +0xb8, 0x9d, 0x84, 0x96, 0xdb, 0xd1, 0xd8, 0xea, +0xdf, 0xe6, 0xe2, 0xd5, 0xdd, 0xcf, 0xbe, 0xca, +0xb0, 0x97, 0xa9, 0xd0, 0xc5, 0xcb, 0xf2, 0xf1, +0xf2, 0xf9, 0xf8, 0xf9, 0xf5, 0xf1, 0xf2, 0xfa, +0xf9, 0xfa, 0xf1, 0xed, 0xef, 0xe4, 0xdb, 0xdf, +0xf0, 0xee, 0xef, 0xf6, 0xf5, 0xf6, 0xe0, 0xd3, +0xd7, 0xc4, 0xab, 0xb5, 0x7b, 0x94, 0xa4, 0x5c, +0xa4, 0xb6, 0x8c, 0xab, 0xb8, 0xef, 0xee, 0xee, +0xf7, 0xf5, 0xf6, 0xc4, 0xab, 0xb4, 0x5b, 0xa0, +0xb3, 0x1f, 0xda, 0xc7, 0x63, 0xb1, 0xc1, 0x98, +0x7c, 0x95, 0x67, 0x85, 0x9b, 0x4f, 0x97, 0xad, +0xf4, 0xf1, 0xf2, 0xe1, 0xd4, 0xd8, 0xc3, 0xaa, +0xb3, 0x5b, 0xa5, 0xb6, 0xef, 0xee, 0xef, 0xe0, +0xd4, 0xd8, 0x5b, 0xa2, 0xb4, 0xf5, 0xf1, 0xf3, +0xf9, 0xf9, 0xf9, 0xe6, 0xef, 0xf1, 0xcf, 0xdb, +0xe0, 0xe1, 0xd4, 0xd9, 0xc3, 0xab, 0xb4, 0x5a, +0xa2, 0xb4, 0xf6, 0xf5, 0xf5, 0x29, 0xc3, 0xc9, +0x52, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x7b, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, +0x02, 0x46, 0x28, 0x60, 0x80, 0x01, 0x26, 0x66, +0x16, 0x56, 0x36, 0x76, 0x0e, 0x4e, 0x18, 0x9f, +0x8b, 0x9b, 0x87, 0x85, 0x97, 0x8f, 0x9d, 0x5f, +0x80, 0x0b, 0x2a, 0xc0, 0x28, 0x28, 0x24, 0xcc, +0x2b, 0xc2, 0xce, 0x21, 0x0a, 0xd3, 0xc3, 0x28, +0x26, 0x2e, 0x21, 0x29, 0x21, 0x25, 0x2d, 0x83, +0x10, 0x90, 0x95, 0x93, 0x57, 0x50, 0x54, 0x52, +0x46, 0x08, 0xa8, 0xa8, 0xca, 0xab, 0xa9, 0x6b, +0x68, 0xc2, 0x05, 0xb4, 0x40, 0x40, 0x5b, 0x47, +0x1b, 0xd9, 0x0c, 0x5d, 0x74, 0x33, 0xf4, 0xf4, +0x15, 0x0d, 0x90, 0xcc, 0x30, 0x54, 0x35, 0x52, +0x33, 0x26, 0x60, 0x86, 0x89, 0x84, 0xa9, 0x99, +0x39, 0xb2, 0x19, 0x16, 0x96, 0x56, 0x48, 0x5a, +0xc4, 0x0c, 0xad, 0x51, 0x0d, 0x65, 0x44, 0xf2, +0x3f, 0x00, 0x25, 0x8d, 0x0d, 0xdb, 0x72, 0x5c, +0x23, 0xa7, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *servers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_servers_png = new wxImage(); + if (!img_servers_png || !img_servers_png->IsOk()) + { + wxMemoryInputStream img_servers_pngIS(servers_png_data, sizeof(servers_png_data)); + img_servers_png->LoadFile(img_servers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_servers_png; +} +#define servers_png_img servers_png_img() + +static wxBitmap *servers_png_bmp() +{ + static wxBitmap *bmp_servers_png; + if (!bmp_servers_png || !bmp_servers_png->IsOk()) + bmp_servers_png = new wxBitmap(*servers_png_img); + return bmp_servers_png; +} +#define servers_png_bmp servers_png_bmp() + +static wxIcon *servers_png_ico() +{ + static wxIcon *ico_servers_png; + if (!ico_servers_png || !ico_servers_png->IsOk()) + { + ico_servers_png = new wxIcon(); + ico_servers_png->CopyFromBitmap(*servers_png_bmp); + } + return ico_servers_png; +} +#define servers_png_ico servers_png_ico() + +#endif // SERVERS_PNG_H diff --git a/include/images/setBreak.png b/include/images/setBreak.png new file mode 100644 index 0000000..9bb52b6 Binary files /dev/null and b/include/images/setBreak.png differ diff --git a/include/images/setBreak.pngc b/include/images/setBreak.pngc new file mode 100644 index 0000000..7f95839 --- /dev/null +++ b/include/images/setBreak.pngc @@ -0,0 +1,82 @@ +#ifndef SETBREAK_PNG_H +#define SETBREAK_PNG_H + +static const unsigned char setBreak_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x12, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x80, +0x80, 0x80, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, +0x80, 0x00, 0x00, 0x4d, 0x75, 0xde, 0x34, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x50, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x40, 0x02, 0x82, +0x82, 0x10, 0x5a, 0xc8, 0xd8, 0x44, 0x11, 0x44, +0x33, 0x1a, 0x1b, 0x9b, 0x86, 0x2a, 0x00, 0x19, +0xc2, 0x20, 0x46, 0x20, 0x90, 0xa1, 0xac, 0x08, +0x64, 0x84, 0x80, 0x64, 0x04, 0x9d, 0x4d, 0x43, +0x43, 0x05, 0x40, 0x0c, 0x63, 0x28, 0xc3, 0xd8, +0x38, 0x14, 0x85, 0xc1, 0xa0, 0x0c, 0x92, 0x09, +0x02, 0x6b, 0x07, 0x0a, 0x80, 0xb4, 0x33, 0xba, +0x02, 0x19, 0x0a, 0x60, 0x2b, 0x42, 0x43, 0x15, +0x51, 0x2d, 0x85, 0x00, 0x00, 0x59, 0x8e, 0x10, +0x28, 0x64, 0xac, 0xd7, 0xec, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *setBreak_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_setBreak_png = new wxImage(); + if (!img_setBreak_png || !img_setBreak_png->IsOk()) + { + wxMemoryInputStream img_setBreak_pngIS(setBreak_png_data, sizeof(setBreak_png_data)); + img_setBreak_png->LoadFile(img_setBreak_pngIS, wxBITMAP_TYPE_PNG); + } + return img_setBreak_png; +} +#define setBreak_png_img setBreak_png_img() + +static wxBitmap *setBreak_png_bmp() +{ + static wxBitmap *bmp_setBreak_png; + if (!bmp_setBreak_png || !bmp_setBreak_png->IsOk()) + bmp_setBreak_png = new wxBitmap(*setBreak_png_img); + return bmp_setBreak_png; +} +#define setBreak_png_bmp setBreak_png_bmp() + +static wxIcon *setBreak_png_ico() +{ + static wxIcon *ico_setBreak_png; + if (!ico_setBreak_png || !ico_setBreak_png->IsOk()) + { + ico_setBreak_png = new wxIcon(); + ico_setBreak_png->CopyFromBitmap(*setBreak_png_bmp); + } + return ico_setBreak_png; +} +#define setBreak_png_ico setBreak_png_ico() + +#endif // SETBREAK_PNG_H diff --git a/include/images/slcluster.png b/include/images/slcluster.png new file mode 100644 index 0000000..ee5b1e1 Binary files /dev/null and b/include/images/slcluster.png differ diff --git a/include/images/slcluster.pngc b/include/images/slcluster.pngc new file mode 100644 index 0000000..1177263 --- /dev/null +++ b/include/images/slcluster.pngc @@ -0,0 +1,123 @@ +#ifndef SLCLUSTER_PNG_H +#define SLCLUSTER_PNG_H + +static const unsigned char slcluster_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xff, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xec, 0xe6, 0xd1, 0xde, +0xd4, 0xae, 0xc3, 0xb1, 0x6c, 0xc1, 0xae, 0x67, +0xc9, 0xb8, 0x7b, 0xd2, 0xc5, 0x91, 0xd5, 0xc8, +0x98, 0xdd, 0xd2, 0xab, 0xc4, 0xb3, 0x6e, 0xd4, +0xc7, 0x91, 0xec, 0xe4, 0xc0, 0xf2, 0xee, 0xcf, +0xea, 0xe7, 0xbb, 0xe1, 0xdb, 0xa8, 0xd7, 0xce, +0x94, 0xc3, 0xb2, 0x6b, 0xd0, 0xc2, 0x8d, 0xe6, +0xdc, 0xb4, 0xff, 0xfe, 0xf2, 0xfe, 0xfb, 0xe3, +0xfb, 0xfb, 0xdd, 0xf1, 0xef, 0xc7, 0xea, 0xe9, +0xbc, 0xde, 0xd7, 0xa0, 0xca, 0xbc, 0x7b, 0xc1, +0xaf, 0x68, 0xc4, 0xb2, 0x6f, 0xee, 0xe9, 0xca, +0xfd, 0xfb, 0xe3, 0xfb, 0xf8, 0xdb, 0xf1, 0xf1, +0xcd, 0xd6, 0xcb, 0x96, 0xdd, 0xd3, 0xaf, 0xd6, +0xc8, 0x96, 0xc3, 0xb0, 0x6b, 0xc3, 0xb1, 0x6b, +0xcb, 0xbb, 0x7c, 0xd5, 0xc8, 0x94, 0xfb, 0xf7, +0xdc, 0xec, 0xec, 0xc1, 0xeb, 0xe9, 0xb9, 0xd5, +0xcd, 0x91, 0xdc, 0xd0, 0x9e, 0xf1, 0xef, 0xd0, +0xf2, 0xf2, 0xd8, 0xfd, 0xfb, 0xf5, 0xca, 0xb9, +0x7c, 0xce, 0xbf, 0x85, 0xf8, 0xf5, 0xe4, 0xfe, +0xfe, 0xfc, 0xf9, 0xf7, 0xee, 0xf4, 0xf2, 0xde, +0xef, 0xea, 0xcd, 0xfe, 0xf6, 0xde, 0xf4, 0xec, +0xc1, 0xe7, 0xe4, 0x9e, 0xe7, 0xe3, 0xa5, 0xed, +0xea, 0xc1, 0xea, 0xe4, 0xcf, 0xef, 0xe6, 0xcc, +0xf7, 0xf3, 0xdf, 0xf4, 0xef, 0xc0, 0xe8, 0xe4, +0xa5, 0xec, 0xe6, 0xd2, 0xf7, 0xef, 0xe3, 0xff, +0xf9, 0xf2, 0xfe, 0xf7, 0xdd, 0xf4, 0xed, 0xc0, +0xf5, 0xee, 0xe3, 0xff, 0xfb, 0xf2, 0xee, 0xea, +0xc0, 0xf6, 0xef, 0xe4, 0xff, 0xfb, 0xf3, 0xda, +0xd0, 0x99, 0xf5, 0xef, 0xe3, 0xf5, 0xec, 0xcf, +0xf2, 0xeb, 0xbc, 0xdd, 0xd5, 0x8e, 0xd5, 0xca, +0x87, 0xc2, 0xb1, 0x6c, 0xd8, 0xcd, 0xa2, 0xc3, +0xb2, 0x6d, 0xd1, 0xc2, 0x8e, 0xf1, 0xe6, 0xc9, +0x55, 0x49, 0x7a, 0xa4, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xac, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x60, 0x64, 0x62, 0x66, 0x66, 0x61, +0x65, 0x63, 0x67, 0x80, 0x02, 0x0e, 0x4e, 0x2e, +0x6e, 0x1e, 0x5e, 0x3e, 0x7e, 0x01, 0x0e, 0xa8, +0x80, 0xa0, 0x90, 0xb0, 0x88, 0xa8, 0x98, 0xb8, +0x84, 0xa4, 0x14, 0x54, 0x9d, 0xb4, 0x8c, 0xb0, +0xac, 0x9c, 0xbc, 0x02, 0x42, 0x1d, 0x8b, 0xa2, +0x92, 0xb2, 0x0a, 0x8b, 0xb2, 0xaa, 0x9a, 0xba, +0xa8, 0x98, 0x86, 0xa6, 0x96, 0x20, 0x03, 0x0b, +0x4c, 0x4e, 0x5b, 0x4e, 0x5e, 0x47, 0x57, 0x4f, +0x9f, 0x81, 0x05, 0x6c, 0x06, 0x50, 0xce, 0xc0, +0xd0, 0xc8, 0xd8, 0xc4, 0x94, 0x85, 0x81, 0x05, +0x6c, 0x06, 0x48, 0xce, 0xcc, 0xdc, 0xc2, 0xd2, +0x0a, 0x28, 0x60, 0x6d, 0x63, 0x0b, 0x91, 0x33, +0xb3, 0xb3, 0xb0, 0x07, 0x09, 0x38, 0x38, 0x3a, +0x41, 0xe4, 0x9c, 0x5d, 0x20, 0x2a, 0x1c, 0x5c, +0xdd, 0x20, 0x72, 0x20, 0xd2, 0x1d, 0x24, 0xe0, +0xe1, 0x09, 0x91, 0x33, 0x03, 0x92, 0x5e, 0x20, +0x01, 0x6f, 0x37, 0x88, 0x9c, 0x8f, 0xaf, 0x9f, +0x7f, 0x00, 0xd0, 0x61, 0x81, 0x8e, 0x6e, 0x10, +0x39, 0xa8, 0xd3, 0x39, 0x82, 0x82, 0x43, 0xa0, +0x72, 0x50, 0x80, 0xe6, 0x7d, 0x00, 0xf1, 0xb9, +0x1f, 0x71, 0xf9, 0xd1, 0xc7, 0xbd, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slcluster_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slcluster_png = new wxImage(); + if (!img_slcluster_png || !img_slcluster_png->IsOk()) + { + wxMemoryInputStream img_slcluster_pngIS(slcluster_png_data, sizeof(slcluster_png_data)); + img_slcluster_png->LoadFile(img_slcluster_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slcluster_png; +} +#define slcluster_png_img slcluster_png_img() + +static wxBitmap *slcluster_png_bmp() +{ + static wxBitmap *bmp_slcluster_png; + if (!bmp_slcluster_png || !bmp_slcluster_png->IsOk()) + bmp_slcluster_png = new wxBitmap(*slcluster_png_img); + return bmp_slcluster_png; +} +#define slcluster_png_bmp slcluster_png_bmp() + +static wxIcon *slcluster_png_ico() +{ + static wxIcon *ico_slcluster_png; + if (!ico_slcluster_png || !ico_slcluster_png->IsOk()) + { + ico_slcluster_png = new wxIcon(); + ico_slcluster_png->CopyFromBitmap(*slcluster_png_bmp); + } + return ico_slcluster_png; +} +#define slcluster_png_ico slcluster_png_ico() + +#endif // SLCLUSTER_PNG_H diff --git a/include/images/slclusters.png b/include/images/slclusters.png new file mode 100644 index 0000000..91884fd Binary files /dev/null and b/include/images/slclusters.png differ diff --git a/include/images/slclusters.pngc b/include/images/slclusters.pngc new file mode 100644 index 0000000..6e07aee --- /dev/null +++ b/include/images/slclusters.pngc @@ -0,0 +1,129 @@ +#ifndef SLCLUSTERS_PNG_H +#define SLCLUSTERS_PNG_H + +static const unsigned char slclusters_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xec, 0xe6, 0xd1, 0xde, +0xd4, 0xae, 0xc3, 0xb1, 0x6c, 0xc1, 0xae, 0x67, +0xc9, 0xb8, 0x7b, 0xd2, 0xc5, 0x91, 0xd5, 0xc8, +0x98, 0xdd, 0xd2, 0xab, 0xc4, 0xb3, 0x6e, 0xd4, +0xc7, 0x91, 0xec, 0xe4, 0xc0, 0x79, 0xa6, 0xb7, +0x25, 0x74, 0xa6, 0x72, 0x9e, 0xa7, 0xd7, 0xce, +0x94, 0xc3, 0xb2, 0x6b, 0xd0, 0xc2, 0x8d, 0xe6, +0xdc, 0xb4, 0xff, 0xfe, 0xf2, 0x7e, 0xac, 0xbf, +0xa7, 0xd3, 0xd6, 0x77, 0xa4, 0xae, 0xd5, 0xcd, +0x91, 0xc4, 0xb2, 0x6f, 0xee, 0xe9, 0xca, 0x7f, +0xad, 0xc5, 0x9a, 0xca, 0xd2, 0x7e, 0xac, 0xc7, +0xca, 0xb9, 0x7c, 0xea, 0xe4, 0xcf, 0x7c, 0xbb, +0xc9, 0x71, 0xb3, 0xc6, 0x97, 0xc7, 0xd1, 0x65, +0x8c, 0x8c, 0x6d, 0x96, 0x9e, 0xec, 0xe6, 0xd2, +0x7b, 0xa7, 0xbf, 0x78, 0xb6, 0xc9, 0x93, 0xc3, +0xd0, 0x97, 0xc2, 0xd1, 0xf5, 0xee, 0xe3, 0x7f, +0xac, 0xc5, 0x73, 0xb1, 0xc7, 0x5b, 0xa2, 0xc0, +0x7a, 0xb2, 0xc9, 0x75, 0xad, 0xc8, 0x73, 0xab, +0xc7, 0xf6, 0xef, 0xe4, 0xff, 0xfb, 0xf3, 0x7e, +0xaa, 0xbd, 0x42, 0x92, 0xba, 0x49, 0x96, 0xbc, +0x52, 0x99, 0xbe, 0x44, 0x8f, 0xba, 0x65, 0xa2, +0xc3, 0xfd, 0xfb, 0xf5, 0xf5, 0xef, 0xe3, 0xff, +0xfb, 0xf2, 0xfe, 0xf6, 0xde, 0x7a, 0xa7, 0xb1, +0x3b, 0x8b, 0xb8, 0x38, 0x88, 0xb7, 0x35, 0x85, +0xb6, 0x62, 0x9f, 0xc3, 0xef, 0xea, 0xcd, 0xd8, +0xcd, 0xa2, 0xf7, 0xef, 0xe3, 0xf4, 0xed, 0xc0, +0x32, 0x81, 0xb6, 0x60, 0x9d, 0xc2, 0xed, 0xea, +0xc1, 0xc3, 0xb2, 0x6d, 0xd1, 0xc2, 0x8e, 0xf1, +0xe6, 0xc9, 0xf5, 0xec, 0xcf, 0x79, 0xa5, 0xaf, +0x2f, 0x7f, 0xb5, 0x5e, 0x9b, 0xc1, 0x81, 0xb0, +0xcb, 0x7f, 0xad, 0xcb, 0x75, 0xa2, 0xa6, 0xee, +0xea, 0xc0, 0xe7, 0xe4, 0x9e, 0xe7, 0xe3, 0xa5, +0xda, 0xd0, 0x99, 0xf2, 0xeb, 0xbc, 0xdd, 0xd5, +0x8e, 0xd5, 0xca, 0x87, 0xc2, 0xb1, 0x6c, 0xe9, +0x11, 0x9d, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xca, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, +0x90, 0xd9, 0x76, 0x01, 0x51, 0x14, 0x44, 0x6f, +0xf4, 0x41, 0x07, 0x15, 0x63, 0x24, 0x88, 0xa0, +0x35, 0xda, 0xd0, 0xe6, 0x29, 0xa6, 0x36, 0x93, +0x18, 0x22, 0x42, 0xc8, 0xff, 0xff, 0x88, 0xbb, +0x7a, 0x58, 0xea, 0xad, 0xf6, 0xc3, 0x5e, 0x75, +0x0e, 0x63, 0x0f, 0x36, 0x41, 0x20, 0xbb, 0xc3, +0xc9, 0xcc, 0x88, 0x8f, 0x2e, 0xb7, 0x07, 0x4f, +0x5e, 0x9f, 0x68, 0x02, 0x7f, 0x20, 0x18, 0xc2, +0x33, 0xc2, 0x2f, 0x7e, 0x13, 0xbc, 0x46, 0xa2, +0xbc, 0xc7, 0xf0, 0x16, 0x37, 0x01, 0xbd, 0xf3, +0x9e, 0x48, 0xa6, 0x20, 0x09, 0x12, 0xd2, 0xdc, +0x44, 0x72, 0x06, 0xb1, 0x64, 0x16, 0x39, 0x78, +0xa0, 0x80, 0x9b, 0x48, 0xce, 0x17, 0x90, 0x42, +0xb1, 0xa4, 0xa2, 0x5c, 0x01, 0x37, 0x91, 0x5c, +0xad, 0xd5, 0x91, 0x2b, 0x35, 0x9a, 0xad, 0x76, +0x07, 0xdd, 0x38, 0x07, 0x1f, 0xbd, 0xfe, 0x00, +0x6a, 0x73, 0x38, 0xd2, 0xc6, 0x98, 0x10, 0xa3, +0xe9, 0xac, 0xd7, 0x9f, 0x4b, 0x68, 0x8d, 0xb4, +0xc5, 0x12, 0x2b, 0x62, 0x6c, 0xfd, 0xf9, 0xb5, +0xd9, 0xa2, 0xdc, 0xd6, 0x16, 0xbb, 0xbd, 0x0e, +0x18, 0x9f, 0x0e, 0xa5, 0xd2, 0x19, 0x2f, 0xf7, +0xdf, 0x06, 0xe0, 0x39, 0xc0, 0xc8, 0xcf, 0x91, +0xac, 0x79, 0xba, 0xe9, 0xf7, 0x74, 0xb6, 0x80, +0x6e, 0xfa, 0xbb, 0x5c, 0xff, 0xad, 0x13, 0xef, +0x4f, 0xb8, 0x01, 0xd7, 0x15, 0x1a, 0xac, 0x8f, +0x04, 0xb7, 0x62, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slclusters_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slclusters_png = new wxImage(); + if (!img_slclusters_png || !img_slclusters_png->IsOk()) + { + wxMemoryInputStream img_slclusters_pngIS(slclusters_png_data, sizeof(slclusters_png_data)); + img_slclusters_png->LoadFile(img_slclusters_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slclusters_png; +} +#define slclusters_png_img slclusters_png_img() + +static wxBitmap *slclusters_png_bmp() +{ + static wxBitmap *bmp_slclusters_png; + if (!bmp_slclusters_png || !bmp_slclusters_png->IsOk()) + bmp_slclusters_png = new wxBitmap(*slclusters_png_img); + return bmp_slclusters_png; +} +#define slclusters_png_bmp slclusters_png_bmp() + +static wxIcon *slclusters_png_ico() +{ + static wxIcon *ico_slclusters_png; + if (!ico_slclusters_png || !ico_slclusters_png->IsOk()) + { + ico_slclusters_png = new wxIcon(); + ico_slclusters_png->CopyFromBitmap(*slclusters_png_bmp); + } + return ico_slclusters_png; +} +#define slclusters_png_ico slclusters_png_ico() + +#endif // SLCLUSTERS_PNG_H diff --git a/include/images/sllisten.png b/include/images/sllisten.png new file mode 100644 index 0000000..04e1343 Binary files /dev/null and b/include/images/sllisten.png differ diff --git a/include/images/sllisten.pngc b/include/images/sllisten.pngc new file mode 100644 index 0000000..4149dda --- /dev/null +++ b/include/images/sllisten.pngc @@ -0,0 +1,94 @@ +#ifndef SLLISTEN_PNG_H +#define SLLISTEN_PNG_H + +static const unsigned char sllisten_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x66, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xad, 0xad, 0xad, 0x73, +0x73, 0x73, 0xd4, 0xd4, 0xca, 0xc6, 0xc6, 0xc0, +0xc2, 0xc2, 0xbb, 0xad, 0xad, 0xac, 0xb8, 0xb8, +0xb2, 0xd4, 0xd4, 0xcd, 0xc5, 0xc5, 0xc0, 0xbc, +0xbc, 0xb9, 0xa2, 0xa2, 0xa2, 0xb3, 0xb3, 0xad, +0xae, 0xae, 0xae, 0xa8, 0xa8, 0xa8, 0x9c, 0x9c, +0x9c, 0xaf, 0xaf, 0xa8, 0xc1, 0xc1, 0xbc, 0x96, +0x96, 0x96, 0xaa, 0xaa, 0xa4, 0xbc, 0xbc, 0xb7, +0x90, 0x90, 0x90, 0xa6, 0xa6, 0x9e, 0xc8, 0xc8, +0xbe, 0xa9, 0xa9, 0xa4, 0x97, 0x97, 0x95, 0x8a, +0x8a, 0x8a, 0xa2, 0xa2, 0x9a, 0xac, 0xac, 0xa4, +0x8c, 0x8c, 0x8a, 0x9f, 0x9f, 0x97, 0xa6, 0xa6, +0x9d, 0xa4, 0xa4, 0x9a, 0xbb, 0xbb, 0xab, 0x6a, +0xa4, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x5a, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x75, +0xcf, 0x39, 0x16, 0x80, 0x20, 0x0c, 0x04, 0x50, +0x18, 0x11, 0x45, 0x70, 0xdf, 0x77, 0xbd, 0xff, +0x25, 0xa5, 0x33, 0xd1, 0xc7, 0x74, 0xf3, 0x53, +0x24, 0x11, 0x22, 0x18, 0x09, 0xf9, 0xe9, 0x11, +0x18, 0x40, 0xc5, 0x20, 0x53, 0x40, 0xe9, 0xe4, +0x05, 0xa4, 0x26, 0xd3, 0xd6, 0x11, 0x30, 0x79, +0x61, 0xcb, 0x8a, 0x40, 0xed, 0x7b, 0xd3, 0x12, +0xe8, 0x7c, 0xef, 0x07, 0x02, 0xa3, 0x9b, 0xe6, +0x65, 0xe5, 0x5b, 0xb6, 0xfd, 0x60, 0x77, 0x48, +0x9c, 0x17, 0x3f, 0x4c, 0xe2, 0xe6, 0xf0, 0xfb, +0x25, 0x98, 0x07, 0x72, 0x99, 0x02, 0xee, 0x56, +0xd7, 0x19, 0x28, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sllisten_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sllisten_png = new wxImage(); + if (!img_sllisten_png || !img_sllisten_png->IsOk()) + { + wxMemoryInputStream img_sllisten_pngIS(sllisten_png_data, sizeof(sllisten_png_data)); + img_sllisten_png->LoadFile(img_sllisten_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sllisten_png; +} +#define sllisten_png_img sllisten_png_img() + +static wxBitmap *sllisten_png_bmp() +{ + static wxBitmap *bmp_sllisten_png; + if (!bmp_sllisten_png || !bmp_sllisten_png->IsOk()) + bmp_sllisten_png = new wxBitmap(*sllisten_png_img); + return bmp_sllisten_png; +} +#define sllisten_png_bmp sllisten_png_bmp() + +static wxIcon *sllisten_png_ico() +{ + static wxIcon *ico_sllisten_png; + if (!ico_sllisten_png || !ico_sllisten_png->IsOk()) + { + ico_sllisten_png = new wxIcon(); + ico_sllisten_png->CopyFromBitmap(*sllisten_png_bmp); + } + return ico_sllisten_png; +} +#define sllisten_png_ico sllisten_png_ico() + +#endif // SLLISTEN_PNG_H diff --git a/include/images/sllistens.png b/include/images/sllistens.png new file mode 100644 index 0000000..6cd5dcd Binary files /dev/null and b/include/images/sllistens.png differ diff --git a/include/images/sllistens.pngc b/include/images/sllistens.pngc new file mode 100644 index 0000000..d7e30bd --- /dev/null +++ b/include/images/sllistens.pngc @@ -0,0 +1,96 @@ +#ifndef SLLISTENS_PNG_H +#define SLLISTENS_PNG_H + +static const unsigned char sllistens_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xad, 0xad, 0xad, 0x73, +0x73, 0x73, 0xd4, 0xd4, 0xca, 0xc6, 0xc6, 0xc0, +0xc2, 0xc2, 0xbb, 0xad, 0xad, 0xac, 0xb8, 0xb8, +0xb2, 0xd4, 0xd4, 0xcd, 0xc5, 0xc5, 0xc0, 0xbc, +0xbc, 0xb9, 0xa2, 0xa2, 0xa2, 0x8d, 0x8d, 0x8b, +0xae, 0xae, 0xae, 0x89, 0x89, 0x89, 0xc1, 0xc1, +0xbc, 0xa8, 0xa8, 0xa8, 0xcb, 0xcb, 0xc3, 0xb3, +0xb3, 0xad, 0x9c, 0x9c, 0x9c, 0xaf, 0xaf, 0xa8, +0x96, 0x96, 0x96, 0xaa, 0xaa, 0xa4, 0xad, 0xad, +0xa9, 0x9c, 0x9c, 0x9b, 0x90, 0x90, 0x90, 0xa6, +0xa6, 0x9e, 0xb1, 0xb1, 0xa8, 0x91, 0x91, 0x8f, +0xa2, 0xa2, 0x9a, 0xa9, 0xa9, 0xa0, 0xa6, 0xa6, +0x9d, 0xbb, 0xbb, 0xab, 0x97, 0xe4, 0xa3, 0x07, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x6d, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x5d, 0x90, 0xd9, 0x12, +0x83, 0x30, 0x0c, 0x03, 0x93, 0xe5, 0x08, 0x14, +0xda, 0x84, 0xb3, 0x77, 0xe1, 0xff, 0xbf, 0x12, +0xc8, 0x14, 0x12, 0xe3, 0x37, 0x69, 0x76, 0x64, +0xd9, 0x4a, 0xf9, 0xd1, 0x68, 0x15, 0x8f, 0x26, +0x41, 0xea, 0x34, 0xe3, 0x80, 0x34, 0x90, 0xe6, +0x86, 0x03, 0xa2, 0x28, 0x2f, 0x79, 0x55, 0x07, +0x88, 0xf2, 0x7a, 0x13, 0x10, 0xd6, 0x45, 0xd0, +0x66, 0x34, 0x26, 0x82, 0xfe, 0xa1, 0x3b, 0xd4, +0xee, 0xb9, 0x1e, 0x72, 0x55, 0xd7, 0x13, 0x36, +0xdb, 0x55, 0x0f, 0x23, 0xa1, 0x5a, 0x63, 0xee, +0x8f, 0xe7, 0x8b, 0xa8, 0x2c, 0xbc, 0x3f, 0x5f, +0x44, 0x7f, 0x7e, 0x13, 0xa7, 0x13, 0x67, 0x69, +0xf8, 0x27, 0x2c, 0xea, 0xb0, 0x04, 0x2a, 0x97, +0x29, 0x5f, 0x2d, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sllistens_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sllistens_png = new wxImage(); + if (!img_sllistens_png || !img_sllistens_png->IsOk()) + { + wxMemoryInputStream img_sllistens_pngIS(sllistens_png_data, sizeof(sllistens_png_data)); + img_sllistens_png->LoadFile(img_sllistens_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sllistens_png; +} +#define sllistens_png_img sllistens_png_img() + +static wxBitmap *sllistens_png_bmp() +{ + static wxBitmap *bmp_sllistens_png; + if (!bmp_sllistens_png || !bmp_sllistens_png->IsOk()) + bmp_sllistens_png = new wxBitmap(*sllistens_png_img); + return bmp_sllistens_png; +} +#define sllistens_png_bmp sllistens_png_bmp() + +static wxIcon *sllistens_png_ico() +{ + static wxIcon *ico_sllistens_png; + if (!ico_sllistens_png || !ico_sllistens_png->IsOk()) + { + ico_sllistens_png = new wxIcon(); + ico_sllistens_png->CopyFromBitmap(*sllistens_png_bmp); + } + return ico_sllistens_png; +} +#define sllistens_png_ico sllistens_png_ico() + +#endif // SLLISTENS_PNG_H diff --git a/include/images/slnode-disabled.png b/include/images/slnode-disabled.png new file mode 100644 index 0000000..98dfa2a Binary files /dev/null and b/include/images/slnode-disabled.png differ diff --git a/include/images/slnode-disabled.pngc b/include/images/slnode-disabled.pngc new file mode 100644 index 0000000..f5c4ec9 --- /dev/null +++ b/include/images/slnode-disabled.pngc @@ -0,0 +1,89 @@ +#ifndef SLNODE_DISABLED_PNG_H +#define SLNODE_DISABLED_PNG_H + +static const unsigned char slnode_disabled_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0xa0, +0xbd, 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x00, 0x76, 0x93, 0xcd, 0x38, 0x00, +0x00, 0x00, 0x02, 0x62, 0x4b, 0x47, 0x44, 0x00, +0x00, 0xaa, 0x8d, 0x23, 0x32, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x97, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x6d, 0xcf, 0xd1, 0x0a, +0x82, 0x30, 0x14, 0xc6, 0x71, 0x5f, 0x7b, 0x5e, +0x38, 0x22, 0x92, 0x76, 0x53, 0x3e, 0x42, 0x62, +0x8e, 0xe6, 0x36, 0x77, 0x66, 0x2e, 0x96, 0x2b, +0x28, 0x82, 0xba, 0xea, 0x26, 0x7a, 0xa0, 0x54, +0x66, 0x64, 0x78, 0xee, 0xfe, 0xbf, 0x8b, 0x0f, +0x4e, 0x10, 0x4c, 0x1f, 0x20, 0x04, 0x23, 0x40, +0xef, 0x17, 0x1a, 0xc3, 0xe3, 0xfe, 0x07, 0xb7, +0xeb, 0x2f, 0x98, 0x44, 0x34, 0xb6, 0x58, 0xb3, +0x2f, 0x24, 0xce, 0x55, 0xaa, 0x36, 0xab, 0xa1, +0x4b, 0xe5, 0x40, 0x72, 0x06, 0xac, 0xf4, 0x40, +0x2e, 0x7b, 0xc9, 0x77, 0x39, 0x3d, 0x90, 0x01, +0x4e, 0xaa, 0xed, 0x2c, 0xd3, 0x1e, 0x74, 0x6c, +0x65, 0xdb, 0xe9, 0x46, 0xc4, 0xba, 0x87, 0x25, +0x18, 0xd1, 0x03, 0xa5, 0x8b, 0xb4, 0xed, 0xf0, +0xe9, 0x1a, 0x7e, 0xac, 0xa0, 0xde, 0xca, 0xe2, +0x1c, 0x76, 0x60, 0x04, 0xc6, 0x98, 0x10, 0x1c, +0x45, 0x39, 0xef, 0x40, 0xcf, 0x95, 0x1f, 0xb7, +0x6a, 0x36, 0xf1, 0xf7, 0x07, 0x90, 0x01, 0x4d, +0x13, 0xc8, 0x5e, 0x98, 0x6b, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slnode_disabled_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slnode_disabled_png = new wxImage(); + if (!img_slnode_disabled_png || !img_slnode_disabled_png->IsOk()) + { + wxMemoryInputStream img_slnode_disabled_pngIS(slnode_disabled_png_data, sizeof(slnode_disabled_png_data)); + img_slnode_disabled_png->LoadFile(img_slnode_disabled_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnode_disabled_png; +} +#define slnode_disabled_png_img slnode_disabled_png_img() + +static wxBitmap *slnode_disabled_png_bmp() +{ + static wxBitmap *bmp_slnode_disabled_png; + if (!bmp_slnode_disabled_png || !bmp_slnode_disabled_png->IsOk()) + bmp_slnode_disabled_png = new wxBitmap(*slnode_disabled_png_img); + return bmp_slnode_disabled_png; +} +#define slnode_disabled_png_bmp slnode_disabled_png_bmp() + +static wxIcon *slnode_disabled_png_ico() +{ + static wxIcon *ico_slnode_disabled_png; + if (!ico_slnode_disabled_png || !ico_slnode_disabled_png->IsOk()) + { + ico_slnode_disabled_png = new wxIcon(); + ico_slnode_disabled_png->CopyFromBitmap(*slnode_disabled_png_bmp); + } + return ico_slnode_disabled_png; +} +#define slnode_disabled_png_ico slnode_disabled_png_ico() + +#endif // SLNODE_DISABLED_PNG_H diff --git a/include/images/slnode-local.png b/include/images/slnode-local.png new file mode 100644 index 0000000..1873d90 Binary files /dev/null and b/include/images/slnode-local.png differ diff --git a/include/images/slnode-local.pngc b/include/images/slnode-local.pngc new file mode 100644 index 0000000..00b6983 --- /dev/null +++ b/include/images/slnode-local.pngc @@ -0,0 +1,131 @@ +#ifndef SLNODE_LOCAL_PNG_H +#define SLNODE_LOCAL_PNG_H + +static const unsigned char slnode_local_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x44, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0x95, 0xcb, 0x8c, +0x4a, 0xa7, 0xd1, 0xbd, 0xeb, 0xd0, 0xbb, 0xe9, +0xc2, 0xa8, 0xe5, 0xc0, 0xa6, 0xe5, 0xbd, 0xa1, +0xe4, 0xbc, 0x9f, 0xe2, 0xbf, 0x9b, 0xce, 0x9e, +0x68, 0xb8, 0xb2, 0x8a, 0xce, 0xb4, 0x94, 0xe0, +0xb1, 0x91, 0xde, 0xaf, 0x87, 0xcc, 0x9d, 0x66, +0xb7, 0xb5, 0x8c, 0xc6, 0xb3, 0xc3, 0x7d, 0x80, +0x9b, 0x26, 0xb8, 0xac, 0xb1, 0xb5, 0x95, 0xe0, +0xaa, 0x87, 0xdc, 0xa8, 0x83, 0xdb, 0xae, 0x8c, +0xdb, 0xb6, 0x94, 0xd5, 0x9c, 0x65, 0xb6, 0x9c, +0xb9, 0x53, 0xa0, 0xc2, 0x56, 0x9a, 0xa8, 0x6c, +0xad, 0xa1, 0xaf, 0xa9, 0x93, 0xbe, 0x93, 0x8d, +0x81, 0xaa, 0x9f, 0xa9, 0xab, 0x87, 0xd8, 0xaf, +0x87, 0xca, 0xba, 0x92, 0xca, 0x96, 0xac, 0x4b, +0xb8, 0xe5, 0x81, 0xb2, 0xe1, 0x7b, 0x82, 0x9c, +0x29, 0x93, 0xaa, 0x46, 0x97, 0xca, 0x5b, 0x7e, +0x99, 0x22, 0xa0, 0x79, 0xd3, 0xb5, 0x95, 0xd6, +0x9a, 0x60, 0xb2, 0x48, 0x82, 0xbe, 0x70, 0x71, +0xb8, 0x64, 0x8f, 0x70, 0x8a, 0xb5, 0x5b, 0x9c, +0xd0, 0x63, 0x8f, 0xc1, 0x50, 0x8d, 0xc2, 0x50, +0x9d, 0x74, 0xd2, 0xb0, 0x8e, 0xd3, 0x73, 0xc7, +0xdf, 0x71, 0xc4, 0xde, 0x6f, 0xc1, 0xdd, 0x6a, +0xbb, 0xda, 0x66, 0x8f, 0x65, 0x91, 0xc9, 0x59, +0x8a, 0xc4, 0x51, 0x82, 0xbb, 0x46, 0x9a, 0x70, +0xd0, 0xab, 0x86, 0xd1, 0x97, 0x5c, 0xb0, 0xbc, +0x96, 0xcc, 0x6e, 0xc1, 0xdd, 0x62, 0xae, 0xd4, +0x54, 0x88, 0x9b, 0x81, 0xb8, 0x5b, 0x86, 0xc1, +0x4d, 0x7f, 0xbd, 0x46, 0x7a, 0xb5, 0x3e, 0x9a, +0x70, 0xcf, 0xa1, 0x7a, 0xd1, 0xab, 0x82, 0xc9, +0x95, 0x5a, 0xb0, 0xae, 0x81, 0xc1, 0x6e, 0xc0, +0xdd, 0x6b, 0xbd, 0xdb, 0x68, 0xb9, 0xda, 0x49, +0x82, 0xba, 0x70, 0x92, 0x49, 0xa8, 0x7f, 0xc9, +0xab, 0x88, 0xd2, 0xa6, 0x82, 0xd1, 0xbc, 0xa0, +0xd9, 0x8d, 0x4b, 0xa8, 0x6c, 0x9b, 0xcb, 0x56, +0x9b, 0xcb, 0x61, 0xb0, 0xd5, 0x60, 0x7d, 0xbc, +0x92, 0x53, 0xab, 0x90, 0x51, 0xab, 0xad, 0x83, +0xc6, 0xb1, 0x8b, 0xcb, 0x93, 0xb5, 0xd9, 0x6e, +0x9c, 0xcb, 0x93, 0x59, 0xaf, 0x6a, 0x99, 0xca, +0x5d, 0xaa, 0xd3, 0x53, 0x98, 0xc9, 0xc2, 0xa0, +0xd0, 0xba, 0x93, 0xcb, 0x92, 0x55, 0xad, 0x6b, +0x9b, 0xcb, 0x61, 0x98, 0xca, 0xc1, 0x06, 0xc0, +0x19, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa8, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, +0x0e, 0x18, 0x99, 0x98, 0x18, 0x51, 0x04, 0x98, +0x98, 0x59, 0x98, 0x50, 0x05, 0x58, 0xd9, 0xd0, +0x04, 0xd8, 0x39, 0x90, 0x05, 0x38, 0xb9, 0xb8, +0x79, 0x78, 0xf9, 0xf8, 0x05, 0x60, 0x7c, 0x41, +0x21, 0x61, 0x11, 0x51, 0x31, 0x71, 0x09, 0x49, +0x98, 0x80, 0x94, 0xb4, 0x8c, 0xac, 0x9c, 0xbc, +0x82, 0xa2, 0x92, 0x32, 0x54, 0x40, 0x45, 0x55, +0x4d, 0x5d, 0x43, 0x53, 0x4b, 0x5b, 0x47, 0x17, +0xc4, 0xd3, 0xd3, 0xd3, 0xd3, 0x37, 0x30, 0x34, +0x32, 0x36, 0xd1, 0x32, 0x35, 0x83, 0x08, 0x98, +0x5b, 0x58, 0x5a, 0x59, 0xdb, 0xd8, 0xda, 0x69, +0xd9, 0x3b, 0x38, 0x3a, 0x81, 0x04, 0x2c, 0x9c, +0x5d, 0x5c, 0xdd, 0xdc, 0x3d, 0x3c, 0xb5, 0xbc, +0xbc, 0x7d, 0x7c, 0xfd, 0x80, 0x02, 0xfe, 0x01, +0x81, 0x41, 0xc1, 0x5a, 0x40, 0x10, 0x12, 0x1a, +0x16, 0x1e, 0x01, 0x14, 0x70, 0x89, 0x8c, 0x8a, +0x8e, 0x89, 0xd5, 0xd5, 0x8d, 0x8d, 0x8b, 0x8b, +0x4f, 0x00, 0x0a, 0x24, 0x26, 0x25, 0xa7, 0xa4, +0xa6, 0xe9, 0x81, 0x8c, 0x4b, 0xcf, 0xc8, 0x84, +0xda, 0x9b, 0x95, 0x8d, 0x70, 0x35, 0x00, 0xfa, +0xf7, 0x1b, 0x20, 0xdc, 0xb6, 0x43, 0x0e, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slnode_local_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slnode_local_png = new wxImage(); + if (!img_slnode_local_png || !img_slnode_local_png->IsOk()) + { + wxMemoryInputStream img_slnode_local_pngIS(slnode_local_png_data, sizeof(slnode_local_png_data)); + img_slnode_local_png->LoadFile(img_slnode_local_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnode_local_png; +} +#define slnode_local_png_img slnode_local_png_img() + +static wxBitmap *slnode_local_png_bmp() +{ + static wxBitmap *bmp_slnode_local_png; + if (!bmp_slnode_local_png || !bmp_slnode_local_png->IsOk()) + bmp_slnode_local_png = new wxBitmap(*slnode_local_png_img); + return bmp_slnode_local_png; +} +#define slnode_local_png_bmp slnode_local_png_bmp() + +static wxIcon *slnode_local_png_ico() +{ + static wxIcon *ico_slnode_local_png; + if (!ico_slnode_local_png || !ico_slnode_local_png->IsOk()) + { + ico_slnode_local_png = new wxIcon(); + ico_slnode_local_png->CopyFromBitmap(*slnode_local_png_bmp); + } + return ico_slnode_local_png; +} +#define slnode_local_png_ico slnode_local_png_ico() + +#endif // SLNODE_LOCAL_PNG_H diff --git a/include/images/slnode.png b/include/images/slnode.png new file mode 100644 index 0000000..e087eea Binary files /dev/null and b/include/images/slnode.png differ diff --git a/include/images/slnode.pngc b/include/images/slnode.pngc new file mode 100644 index 0000000..5fe31c9 --- /dev/null +++ b/include/images/slnode.pngc @@ -0,0 +1,122 @@ +#ifndef SLNODE_PNG_H +#define SLNODE_PNG_H + +static const unsigned char slnode_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x08, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0x95, 0xcb, 0x8c, +0x4a, 0xa7, 0xd1, 0xbd, 0xeb, 0xd0, 0xbb, 0xe9, +0xc2, 0xa8, 0xe5, 0xc0, 0xa6, 0xe5, 0xbd, 0xa1, +0xe4, 0xbc, 0x9f, 0xe2, 0xbf, 0x9b, 0xce, 0x9e, +0x68, 0xb8, 0xb2, 0x8a, 0xce, 0xb4, 0x94, 0xe0, +0xb1, 0x91, 0xde, 0xaf, 0x87, 0xcc, 0x9d, 0x66, +0xb7, 0xb5, 0x8c, 0xc6, 0xbc, 0x9c, 0xda, 0xb5, +0x95, 0xe0, 0xaa, 0x87, 0xdc, 0xa8, 0x83, 0xdb, +0xae, 0x8c, 0xdb, 0xb6, 0x94, 0xd5, 0x9c, 0x65, +0xb6, 0xba, 0x92, 0xca, 0xb5, 0x8f, 0xcf, 0xb5, +0x96, 0xe0, 0xa9, 0x85, 0xdb, 0xa6, 0x80, 0xda, +0xa4, 0x7d, 0xd8, 0xa2, 0x7c, 0xd6, 0xab, 0x87, +0xd8, 0xaf, 0x87, 0xca, 0x9a, 0x60, 0xb2, 0xbf, +0xa2, 0xdd, 0xac, 0x89, 0xdc, 0xa1, 0x7a, 0xd6, +0x9f, 0x76, 0xd4, 0xa0, 0x79, 0xd3, 0xb5, 0x95, +0xd6, 0xbb, 0x9c, 0xdc, 0x9c, 0x73, 0xd2, 0x9d, +0x74, 0xd2, 0xb0, 0x8e, 0xd3, 0xbc, 0x96, 0xcc, +0x97, 0x5c, 0xb0, 0xb6, 0x95, 0xda, 0xa6, 0x80, +0xd9, 0x9a, 0x70, 0xd1, 0x9a, 0x70, 0xd0, 0xab, +0x86, 0xd1, 0x97, 0x5d, 0xb2, 0xb4, 0x8f, 0xd1, +0xaf, 0x8d, 0xdc, 0xa5, 0x80, 0xd7, 0xa2, 0x7a, +0xd5, 0x9e, 0x76, 0xd3, 0x9b, 0x72, 0xd0, 0x9a, +0x70, 0xcf, 0xa1, 0x7a, 0xd1, 0xab, 0x82, 0xc9, +0x95, 0x5a, 0xb0, 0xae, 0x81, 0xc1, 0x8d, 0x4b, +0xa8, 0xca, 0xb4, 0xe5, 0xb7, 0x98, 0xde, 0xb6, +0x98, 0xdc, 0xae, 0x87, 0xce, 0xb7, 0x98, 0xd9, +0xb2, 0x8f, 0xd5, 0xb0, 0x8d, 0xd3, 0xb2, 0x91, +0xd6, 0xa8, 0x7f, 0xc9, 0xab, 0x88, 0xd2, 0xa6, +0x82, 0xd1, 0xbc, 0xa0, 0xd9, 0x8d, 0x4c, 0xa8, +0xba, 0x97, 0xd2, 0xb3, 0x8c, 0xcc, 0x91, 0x52, +0xab, 0x92, 0x53, 0xab, 0x90, 0x51, 0xab, 0xad, +0x83, 0xc6, 0xb1, 0x8b, 0xcb, 0x93, 0x57, 0xae, +0xba, 0x93, 0xcb, 0xc2, 0xa0, 0xd0, 0x92, 0x55, +0xad, 0x56, 0x7d, 0x3a, 0xa8, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x98, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0xc0, 0x0e, 0x18, 0x99, 0x98, +0x18, 0x51, 0x04, 0x98, 0x98, 0x59, 0x98, 0x50, +0x05, 0x58, 0xd9, 0xd0, 0x04, 0xd8, 0x39, 0x90, +0x05, 0x38, 0xb9, 0xb8, 0x79, 0x78, 0xf9, 0xf8, +0x05, 0xe0, 0x02, 0x5c, 0x82, 0x42, 0xc2, 0x22, +0xa2, 0x62, 0xe2, 0x30, 0xbe, 0x84, 0xa4, 0x94, +0xb4, 0x8c, 0xac, 0x9c, 0xbc, 0x82, 0x04, 0x54, +0x40, 0x51, 0x49, 0x59, 0x46, 0x56, 0x45, 0x55, +0x4d, 0x5d, 0x11, 0x26, 0xa0, 0x21, 0x02, 0xe4, +0x6b, 0x6a, 0x69, 0x43, 0x05, 0x74, 0x74, 0xf5, +0xf4, 0x81, 0x7c, 0x03, 0x43, 0x23, 0x5d, 0x1d, +0xb0, 0x80, 0xb1, 0x89, 0xa9, 0x99, 0xb9, 0x85, +0xa6, 0xa5, 0x95, 0xb5, 0x8d, 0xad, 0x1d, 0x90, +0x6f, 0xef, 0xe0, 0xe8, 0xe4, 0xec, 0xe2, 0xea, +0xe6, 0xee, 0xe1, 0xe9, 0xe5, 0x6d, 0x0f, 0x14, +0xf0, 0xf1, 0xf5, 0xf3, 0xf7, 0x0f, 0x50, 0x54, +0x0c, 0x08, 0x0c, 0x0c, 0x0a, 0x06, 0x09, 0xe8, +0x84, 0x84, 0x42, 0x0d, 0x0f, 0x0b, 0x0d, 0xc7, +0xe2, 0x6f, 0x00, 0xf9, 0x6d, 0x13, 0x61, 0xf0, +0x39, 0x5b, 0xcc, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slnode_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slnode_png = new wxImage(); + if (!img_slnode_png || !img_slnode_png->IsOk()) + { + wxMemoryInputStream img_slnode_pngIS(slnode_png_data, sizeof(slnode_png_data)); + img_slnode_png->LoadFile(img_slnode_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnode_png; +} +#define slnode_png_img slnode_png_img() + +static wxBitmap *slnode_png_bmp() +{ + static wxBitmap *bmp_slnode_png; + if (!bmp_slnode_png || !bmp_slnode_png->IsOk()) + bmp_slnode_png = new wxBitmap(*slnode_png_img); + return bmp_slnode_png; +} +#define slnode_png_bmp slnode_png_bmp() + +static wxIcon *slnode_png_ico() +{ + static wxIcon *ico_slnode_png; + if (!ico_slnode_png || !ico_slnode_png->IsOk()) + { + ico_slnode_png = new wxIcon(); + ico_slnode_png->CopyFromBitmap(*slnode_png_bmp); + } + return ico_slnode_png; +} +#define slnode_png_ico slnode_png_ico() + +#endif // SLNODE_PNG_H diff --git a/include/images/slnodes.png b/include/images/slnodes.png new file mode 100644 index 0000000..7cfab77 Binary files /dev/null and b/include/images/slnodes.png differ diff --git a/include/images/slnodes.pngc b/include/images/slnodes.pngc new file mode 100644 index 0000000..53ff9bb --- /dev/null +++ b/include/images/slnodes.pngc @@ -0,0 +1,106 @@ +#ifndef SLNODES_PNG_H +#define SLNODES_PNG_H + +static const unsigned char slnodes_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x99, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0x95, 0xcb, 0x8c, +0x4a, 0xa7, 0xd6, 0xc4, 0xeb, 0xcd, 0xb8, 0xe8, +0xbf, 0x99, 0xce, 0xa8, 0x78, 0xc1, 0xb7, 0x94, +0xd5, 0xb9, 0x9b, 0xe0, 0xc1, 0xa4, 0xe3, 0xb1, +0x90, 0xdf, 0x9f, 0x70, 0xc8, 0x94, 0x5a, 0xb5, +0xba, 0x99, 0xd6, 0x98, 0x63, 0xbe, 0x91, 0x51, +0xaa, 0xc3, 0xa8, 0xe3, 0xb9, 0x90, 0xc9, 0xac, +0x7c, 0xc0, 0xb4, 0x8f, 0xd2, 0xb4, 0x90, 0xd3, +0xa5, 0x75, 0xbf, 0xc5, 0xad, 0xe3, 0x8d, 0x4d, +0xa9, 0xab, 0x87, 0xdc, 0xab, 0x88, 0xda, 0xb7, +0x98, 0xdc, 0xa4, 0x73, 0xbe, 0xcf, 0xbb, 0xe6, +0x93, 0x55, 0xad, 0xa8, 0x83, 0xdb, 0xa4, 0x7e, +0xd8, 0xa1, 0x7a, 0xd6, 0xa5, 0x7f, 0xd6, 0xb2, +0x8c, 0xcf, 0x9f, 0x69, 0xb6, 0x9e, 0x75, 0xd4, +0x9f, 0x76, 0xd2, 0xb6, 0x97, 0xd8, 0xa8, 0x83, +0xd9, 0x9b, 0x71, 0xd1, 0x9c, 0x73, 0xd0, 0xaa, +0x82, 0xca, 0xb0, 0x8f, 0xda, 0xa0, 0x78, 0xd2, +0xa6, 0x81, 0xd2, 0xba, 0x9d, 0xd9, 0xaf, 0x89, +0xcd, 0xa1, 0x6f, 0xbb, 0xc3, 0xaa, 0xdb, 0xd4, +0xbb, 0xde, 0x68, 0x10, 0x2b, 0x12, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x88, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x5d, 0xcf, 0xe9, 0x12, 0x82, 0x30, +0x0c, 0x04, 0xe0, 0x10, 0x05, 0x15, 0x90, 0x62, +0xbc, 0x10, 0x14, 0x0a, 0x02, 0xca, 0xe1, 0xf9, +0xfe, 0x0f, 0x27, 0x2d, 0xc5, 0xa1, 0xec, 0xcf, +0x9d, 0x6f, 0x26, 0x59, 0x80, 0x2e, 0x06, 0x1a, +0xa0, 0x05, 0x67, 0x38, 0x29, 0xe6, 0x38, 0x6e, +0x4c, 0x6b, 0xb1, 0xd4, 0x8c, 0xb5, 0xb2, 0x9d, +0xb1, 0x71, 0xd7, 0xb6, 0xa7, 0x19, 0xe6, 0x3b, +0xca, 0x6c, 0xfa, 0x82, 0xb6, 0xca, 0xec, 0xf6, +0x66, 0xff, 0xc3, 0xe1, 0x28, 0x4d, 0x70, 0x0a, +0x23, 0x79, 0xf2, 0x8c, 0x17, 0x61, 0xe2, 0x84, +0xa7, 0x19, 0x49, 0x71, 0x15, 0x26, 0x48, 0x78, +0x5e, 0x94, 0x0c, 0xfe, 0xe6, 0xc6, 0xf3, 0x7b, +0x55, 0x13, 0xc0, 0x60, 0x9a, 0xb4, 0x68, 0x1f, +0xcf, 0x61, 0x53, 0x67, 0xa2, 0xac, 0x7c, 0xbd, +0xf1, 0xa3, 0x7e, 0x11, 0x6b, 0x89, 0xd1, 0x17, +0xa6, 0xab, 0x45, 0x7e, 0x57, 0x78, 0x08, 0xdf, +0x27, 0x50, 0xc5, 0x73, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slnodes_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slnodes_png = new wxImage(); + if (!img_slnodes_png || !img_slnodes_png->IsOk()) + { + wxMemoryInputStream img_slnodes_pngIS(slnodes_png_data, sizeof(slnodes_png_data)); + img_slnodes_png->LoadFile(img_slnodes_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slnodes_png; +} +#define slnodes_png_img slnodes_png_img() + +static wxBitmap *slnodes_png_bmp() +{ + static wxBitmap *bmp_slnodes_png; + if (!bmp_slnodes_png || !bmp_slnodes_png->IsOk()) + bmp_slnodes_png = new wxBitmap(*slnodes_png_img); + return bmp_slnodes_png; +} +#define slnodes_png_bmp slnodes_png_bmp() + +static wxIcon *slnodes_png_ico() +{ + static wxIcon *ico_slnodes_png; + if (!ico_slnodes_png || !ico_slnodes_png->IsOk()) + { + ico_slnodes_png = new wxIcon(); + ico_slnodes_png->CopyFromBitmap(*slnodes_png_bmp); + } + return ico_slnodes_png; +} +#define slnodes_png_ico slnodes_png_ico() + +#endif // SLNODES_PNG_H diff --git a/include/images/slpath.png b/include/images/slpath.png new file mode 100644 index 0000000..3c8b762 Binary files /dev/null and b/include/images/slpath.png differ diff --git a/include/images/slpath.pngc b/include/images/slpath.pngc new file mode 100644 index 0000000..b663247 --- /dev/null +++ b/include/images/slpath.pngc @@ -0,0 +1,109 @@ +#ifndef SLPATH_PNG_H +#define SLPATH_PNG_H + +static const unsigned char slpath_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb9, 0x4a, 0x86, 0xe5, +0xbc, 0xd2, 0xb9, 0x49, 0x86, 0xbe, 0x56, 0x90, +0xd9, 0x94, 0xc3, 0xcd, 0x78, 0xac, 0xc9, 0x72, +0xa2, 0xe6, 0xbd, 0xd3, 0xcb, 0x73, 0xa6, 0xd4, +0x8a, 0xb7, 0xe2, 0xb3, 0xcc, 0xd0, 0x7f, 0xb2, +0xec, 0xbc, 0xec, 0xe8, 0xae, 0xe8, 0xe0, 0xa1, +0xd2, 0xc5, 0x66, 0x9e, 0xd3, 0x8c, 0xb3, 0xf0, +0xd7, 0xe4, 0xc5, 0x64, 0x9b, 0xda, 0x95, 0xc5, +0xde, 0x99, 0xd0, 0xe2, 0xa5, 0xd2, 0xcc, 0x76, +0xa8, 0xd6, 0x94, 0xb8, 0xcd, 0x77, 0xac, 0xe5, +0xab, 0xde, 0xe5, 0xa7, 0xe3, 0xe5, 0xa8, 0xe1, +0xd8, 0x91, 0xc1, 0xbe, 0x55, 0x8f, 0xbe, 0x54, +0x8f, 0xd6, 0x8d, 0xbd, 0xdf, 0x9b, 0xd3, 0xdc, +0x94, 0xce, 0xdc, 0x98, 0xc9, 0xca, 0x71, 0xa3, +0xdd, 0xa6, 0xc4, 0xba, 0x4a, 0x87, 0xd4, 0x88, +0xb8, 0xe5, 0xa9, 0xe0, 0xe1, 0x9e, 0xdb, 0xe1, +0x9d, 0xd8, 0xdf, 0x9a, 0xd5, 0xdd, 0x95, 0xd1, +0xdf, 0x9c, 0xd1, 0xd1, 0x81, 0xb0, 0xbf, 0x58, +0x92, 0xd8, 0x8e, 0xc0, 0xdb, 0x8d, 0xd2, 0xd9, +0x8a, 0xce, 0xd5, 0x89, 0xbb, 0xbf, 0x57, 0x90, +0xed, 0xd1, 0xe0, 0xdd, 0x96, 0xd2, 0xdd, 0x96, +0xcd, 0xdb, 0x94, 0xca, 0xda, 0x91, 0xc7, 0xdb, +0x93, 0xc8, 0xd9, 0x90, 0xc5, 0xbd, 0x54, 0x8d, +0xe1, 0xa5, 0xcb, 0xe0, 0xa3, 0xc8, 0xda, 0x9f, +0xbf, 0x76, 0x96, 0x42, 0xe1, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x20, 0x02, 0x30, 0x32, 0xc1, +0x58, 0x4c, 0xcc, 0x20, 0x92, 0x85, 0x95, 0x8d, +0x9d, 0x03, 0xcc, 0x67, 0xe7, 0xe4, 0x62, 0x61, +0x60, 0xe0, 0xe6, 0xe1, 0xe5, 0xe3, 0x17, 0x10, +0x14, 0x62, 0x10, 0x14, 0x16, 0x11, 0x15, 0x13, +0xe7, 0x66, 0x60, 0x90, 0x90, 0x94, 0x92, 0x96, +0x91, 0x95, 0x93, 0x57, 0x50, 0x54, 0x52, 0x56, +0x91, 0x00, 0xa9, 0x54, 0x55, 0x53, 0xd7, 0xd0, +0xd4, 0xd2, 0xd6, 0xd1, 0xd5, 0x53, 0x53, 0x85, +0x1a, 0x26, 0xa1, 0x6f, 0x60, 0x68, 0x64, 0x6c, +0x22, 0x81, 0xb0, 0xc8, 0x94, 0xd9, 0x4c, 0x89, +0x19, 0xc5, 0x6a, 0x66, 0x51, 0x73, 0x34, 0x01, +0x73, 0x0b, 0x34, 0x01, 0x0b, 0x4b, 0x34, 0x01, +0x2b, 0x6b, 0x54, 0x01, 0x1b, 0x5b, 0x3b, 0x1b, +0x54, 0x0f, 0xd9, 0xd8, 0xd8, 0xe3, 0xf0, 0x2a, +0x00, 0x21, 0x9c, 0x0a, 0x15, 0x07, 0xed, 0x59, +0x3c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slpath_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slpath_png = new wxImage(); + if (!img_slpath_png || !img_slpath_png->IsOk()) + { + wxMemoryInputStream img_slpath_pngIS(slpath_png_data, sizeof(slpath_png_data)); + img_slpath_png->LoadFile(img_slpath_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slpath_png; +} +#define slpath_png_img slpath_png_img() + +static wxBitmap *slpath_png_bmp() +{ + static wxBitmap *bmp_slpath_png; + if (!bmp_slpath_png || !bmp_slpath_png->IsOk()) + bmp_slpath_png = new wxBitmap(*slpath_png_img); + return bmp_slpath_png; +} +#define slpath_png_bmp slpath_png_bmp() + +static wxIcon *slpath_png_ico() +{ + static wxIcon *ico_slpath_png; + if (!ico_slpath_png || !ico_slpath_png->IsOk()) + { + ico_slpath_png = new wxIcon(); + ico_slpath_png->CopyFromBitmap(*slpath_png_bmp); + } + return ico_slpath_png; +} +#define slpath_png_ico slpath_png_ico() + +#endif // SLPATH_PNG_H diff --git a/include/images/slpaths.png b/include/images/slpaths.png new file mode 100644 index 0000000..c9cfd45 Binary files /dev/null and b/include/images/slpaths.png differ diff --git a/include/images/slpaths.pngc b/include/images/slpaths.pngc new file mode 100644 index 0000000..66a2332 --- /dev/null +++ b/include/images/slpaths.pngc @@ -0,0 +1,109 @@ +#ifndef SLPATHS_PNG_H +#define SLPATHS_PNG_H + +static const unsigned char slpaths_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc0, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xbb, 0x4e, 0x8a, 0xc9, +0x72, 0xa2, 0xe6, 0xbd, 0xd3, 0xbb, 0x4d, 0x89, +0xba, 0x4b, 0x88, 0xdf, 0xa2, 0xce, 0xe2, 0xa8, +0xd6, 0xc6, 0x67, 0x9e, 0xd3, 0x8c, 0xb3, 0xc5, +0x65, 0x9b, 0xdd, 0x9c, 0xc8, 0xd9, 0x96, 0xc0, +0xba, 0x4b, 0x87, 0xbd, 0x53, 0x8e, 0xea, 0xba, +0xe5, 0xe7, 0xae, 0xe9, 0xe5, 0xaa, 0xe2, 0xd9, +0x93, 0xc4, 0xbe, 0x55, 0x90, 0xbe, 0x55, 0x8f, +0xd7, 0x8e, 0xbe, 0xdf, 0x9d, 0xd4, 0xdd, 0x97, +0xcf, 0xe1, 0xa8, 0xcd, 0xbc, 0x51, 0x8c, 0xdd, +0xa6, 0xc4, 0xba, 0x4a, 0x87, 0xcc, 0x78, 0xac, +0xc3, 0x5d, 0x9a, 0xd3, 0x81, 0xbc, 0xe0, 0x9d, +0xd7, 0xde, 0x97, 0xd2, 0xdf, 0x9c, 0xd1, 0xd0, +0x81, 0xaf, 0xc1, 0x5e, 0x94, 0xc5, 0x62, 0xa1, +0xcf, 0x7b, 0xaf, 0xbe, 0x54, 0x8e, 0xc4, 0x65, +0x99, 0xe7, 0xae, 0xe6, 0xcb, 0x77, 0xa4, 0xd4, +0x8a, 0xba, 0xe7, 0xad, 0xe4, 0xe3, 0xa2, 0xdf, +0xe1, 0xa0, 0xdb, 0xb9, 0x49, 0x86, 0xbf, 0x58, +0x92, 0xd8, 0x8f, 0xc2, 0xdc, 0x90, 0xd3, 0xda, +0x8c, 0xcf, 0xd5, 0x89, 0xbb, 0xbf, 0x57, 0x90, +0xd6, 0x94, 0xb8, 0xbf, 0x58, 0x90, 0xd6, 0x8f, +0xba, 0xde, 0x98, 0xd3, 0xdc, 0x94, 0xce, 0xde, +0x99, 0xd0, 0xdc, 0x95, 0xcc, 0xdd, 0x98, 0xcd, +0xdb, 0x94, 0xc9, 0xe0, 0xa7, 0xcc, 0xe0, 0xa4, +0xc9, 0x7f, 0x51, 0x1d, 0xaa, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x7d, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x60, 0x64, 0x62, 0x66, 0x00, +0x01, 0x26, 0x16, 0x30, 0xc5, 0xc0, 0xca, 0xc6, +0xce, 0xc1, 0xc9, 0xc0, 0xc0, 0xc9, 0xc5, 0xcd, +0xc3, 0x0b, 0x16, 0xe0, 0xe3, 0x17, 0x10, 0x14, +0x12, 0x16, 0x11, 0x15, 0x13, 0x97, 0x90, 0x04, +0x0b, 0x48, 0x49, 0xcb, 0x30, 0xca, 0xca, 0xc9, +0x2b, 0x28, 0x2a, 0x49, 0x2b, 0x23, 0x69, 0x52, +0x51, 0x55, 0x53, 0xc7, 0xad, 0x89, 0x81, 0x38, +0x4d, 0x1a, 0x28, 0x9a, 0x34, 0xa5, 0xb5, 0xb4, +0x75, 0x74, 0xc1, 0x9a, 0x18, 0xa0, 0x40, 0x4f, +0xdf, 0xc0, 0xd0, 0xc8, 0xd8, 0xc4, 0x14, 0xc6, +0x67, 0x30, 0x33, 0xd7, 0xb3, 0xb0, 0xd4, 0x63, +0x40, 0x02, 0x66, 0x7a, 0x56, 0xd6, 0x28, 0x02, +0x0c, 0x7a, 0x36, 0xb6, 0xa8, 0x02, 0x66, 0x76, +0xf6, 0x66, 0x0c, 0xa8, 0x22, 0x10, 0x3e, 0x00, +0x62, 0xe9, 0x0f, 0x06, 0xee, 0xa0, 0x94, 0x85, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slpaths_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slpaths_png = new wxImage(); + if (!img_slpaths_png || !img_slpaths_png->IsOk()) + { + wxMemoryInputStream img_slpaths_pngIS(slpaths_png_data, sizeof(slpaths_png_data)); + img_slpaths_png->LoadFile(img_slpaths_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slpaths_png; +} +#define slpaths_png_img slpaths_png_img() + +static wxBitmap *slpaths_png_bmp() +{ + static wxBitmap *bmp_slpaths_png; + if (!bmp_slpaths_png || !bmp_slpaths_png->IsOk()) + bmp_slpaths_png = new wxBitmap(*slpaths_png_img); + return bmp_slpaths_png; +} +#define slpaths_png_bmp slpaths_png_bmp() + +static wxIcon *slpaths_png_ico() +{ + static wxIcon *ico_slpaths_png; + if (!ico_slpaths_png || !ico_slpaths_png->IsOk()) + { + ico_slpaths_png = new wxIcon(); + ico_slpaths_png->CopyFromBitmap(*slpaths_png_bmp); + } + return ico_slpaths_png; +} +#define slpaths_png_ico slpaths_png_ico() + +#endif // SLPATHS_PNG_H diff --git a/include/images/slset.png b/include/images/slset.png new file mode 100644 index 0000000..c018b13 Binary files /dev/null and b/include/images/slset.png differ diff --git a/include/images/slset.pngc b/include/images/slset.pngc new file mode 100644 index 0000000..12aa3d8 --- /dev/null +++ b/include/images/slset.pngc @@ -0,0 +1,123 @@ +#ifndef SLSET_PNG_H +#define SLSET_PNG_H + +static const unsigned char slset_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xfc, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xc3, 0x7d, 0x7e, +0x99, 0x22, 0xc3, 0xed, 0x8c, 0xc2, 0xec, 0x8b, +0xbb, 0xe7, 0x84, 0xb9, 0xe6, 0x82, 0xb5, 0xe3, +0x7e, 0xb0, 0xe0, 0x79, 0x9b, 0xd1, 0x63, 0xad, +0xdd, 0x76, 0xa3, 0xd6, 0x6b, 0x98, 0xcf, 0x60, +0x93, 0xcb, 0x5b, 0x48, 0x82, 0xbe, 0x5e, 0x8b, +0x7e, 0xa0, 0xd4, 0x68, 0x9a, 0xd0, 0x62, 0x95, +0xcc, 0x5d, 0x90, 0xc9, 0x57, 0x8b, 0xc5, 0x52, +0x74, 0xc8, 0xe0, 0x73, 0xc7, 0xdf, 0x72, 0xc5, +0xdf, 0x70, 0xc3, 0xde, 0x6f, 0xc1, 0xdd, 0x6d, +0xbf, 0xdc, 0x92, 0xca, 0x5a, 0x8d, 0xc7, 0x54, +0x88, 0xc3, 0x4f, 0x83, 0xc0, 0x4b, 0x73, 0xc6, +0xdf, 0x6e, 0xc1, 0xdd, 0x6c, 0xbe, 0xdc, 0x8f, +0xc8, 0x56, 0x8a, 0xc4, 0x51, 0xa4, 0x9f, 0x30, +0xb9, 0x87, 0x1b, 0xa0, 0x9c, 0x2c, 0x71, 0xc5, +0xdf, 0x6e, 0xc0, 0xdd, 0x8c, 0xc6, 0x53, 0x87, +0xc2, 0x4e, 0x83, 0xbf, 0x4a, 0xfc, 0xf7, 0xad, +0xa1, 0x8e, 0x1e, 0x70, 0xc2, 0xde, 0x6a, 0xbb, +0xdb, 0x68, 0xb9, 0xda, 0x94, 0x89, 0x44, 0xfa, +0xf4, 0x9f, 0xf8, 0xf1, 0x91, 0xd6, 0xb8, 0x79, +0x6d, 0xc0, 0xdd, 0x6c, 0xbd, 0xdc, 0x67, 0xb8, +0xda, 0x63, 0xb3, 0xd7, 0xfd, 0xf8, 0xb4, 0xfb, +0xf6, 0xa9, 0xfa, 0xf4, 0x9c, 0xf8, 0xf1, 0x8f, +0xf6, 0xee, 0x80, 0xf5, 0xeb, 0x72, 0x6b, 0xbd, +0xdc, 0x61, 0xb0, 0xd6, 0xfb, 0xf6, 0xa7, 0xf9, +0xf3, 0x9a, 0xf8, 0xf0, 0x8c, 0xf6, 0xee, 0x7e, +0xf4, 0xeb, 0x6f, 0xf3, 0xe8, 0x61, 0xf1, 0xe5, +0x53, 0x5f, 0xad, 0xd5, 0xf9, 0xf3, 0x98, 0xf7, +0xf0, 0x8a, 0xf6, 0xed, 0x7c, 0xf4, 0xea, 0x6d, +0xf2, 0xe8, 0x5f, 0xf1, 0xe5, 0x51, 0x93, 0xb5, +0xd9, 0x92, 0x95, 0x67, 0xf2, 0xe7, 0x5c, 0xf0, +0xe4, 0x4f, 0xf0, 0xe4, 0x4c, 0x3a, 0x03, 0xd3, +0xe2, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xac, 0x49, +0x44, 0x41, 0x54, 0x18, 0xd3, 0x55, 0x8f, 0xd5, +0x12, 0xc2, 0x50, 0x0c, 0x05, 0xdb, 0xe0, 0x96, +0xe2, 0x14, 0xa7, 0x40, 0x70, 0x77, 0x77, 0x77, +0xf9, 0xff, 0x7f, 0xe1, 0xde, 0x32, 0x4c, 0xe9, +0xbe, 0x65, 0x73, 0x4e, 0x66, 0x22, 0x08, 0x1c, +0x11, 0x44, 0xe1, 0x1f, 0x11, 0x0c, 0xa0, 0x13, +0x60, 0x04, 0x13, 0xe8, 0x72, 0x60, 0xb6, 0x58, +0x41, 0x04, 0x1b, 0x68, 0x1d, 0x3b, 0x38, 0xc0, +0xe9, 0xe2, 0x02, 0xbf, 0x48, 0x6e, 0x8f, 0xd7, +0xe7, 0x57, 0x45, 0x20, 0x18, 0x92, 0xc3, 0x11, +0x84, 0x68, 0x2c, 0x9e, 0x50, 0x45, 0x32, 0x24, +0xa7, 0x14, 0x94, 0xd2, 0x99, 0x2c, 0xe5, 0x54, +0x91, 0x97, 0x0b, 0x6c, 0x2e, 0x96, 0xca, 0x54, +0xa1, 0x2a, 0x17, 0xb5, 0x82, 0x52, 0x6f, 0x60, +0x93, 0x88, 0x5a, 0x6d, 0xea, 0x30, 0xd1, 0xed, +0x61, 0x1f, 0x07, 0x34, 0x1c, 0x8d, 0x27, 0xd3, +0x19, 0x33, 0x38, 0x47, 0x01, 0x07, 0x0b, 0x5a, +0xae, 0xd6, 0x9b, 0xed, 0x6e, 0x4f, 0x2c, 0xc2, +0x7b, 0x07, 0x3a, 0x9e, 0xce, 0x97, 0xeb, 0x8d, +0x77, 0x38, 0x77, 0x7c, 0xb0, 0x1b, 0xcf, 0x17, +0x69, 0xef, 0xb0, 0x1c, 0xbd, 0x7f, 0xfb, 0x1f, +0xea, 0xfe, 0x03, 0x50, 0x7e, 0x13, 0x7b, 0x0f, +0x2a, 0x86, 0xfa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slset_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slset_png = new wxImage(); + if (!img_slset_png || !img_slset_png->IsOk()) + { + wxMemoryInputStream img_slset_pngIS(slset_png_data, sizeof(slset_png_data)); + img_slset_png->LoadFile(img_slset_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slset_png; +} +#define slset_png_img slset_png_img() + +static wxBitmap *slset_png_bmp() +{ + static wxBitmap *bmp_slset_png; + if (!bmp_slset_png || !bmp_slset_png->IsOk()) + bmp_slset_png = new wxBitmap(*slset_png_img); + return bmp_slset_png; +} +#define slset_png_bmp slset_png_bmp() + +static wxIcon *slset_png_ico() +{ + static wxIcon *ico_slset_png; + if (!ico_slset_png || !ico_slset_png->IsOk()) + { + ico_slset_png = new wxIcon(); + ico_slset_png->CopyFromBitmap(*slset_png_bmp); + } + return ico_slset_png; +} +#define slset_png_ico slset_png_ico() + +#endif // SLSET_PNG_H diff --git a/include/images/slset2.png b/include/images/slset2.png new file mode 100644 index 0000000..6f3eb0f Binary files /dev/null and b/include/images/slset2.png differ diff --git a/include/images/slset2.pngc b/include/images/slset2.pngc new file mode 100644 index 0000000..915b9a7 --- /dev/null +++ b/include/images/slset2.pngc @@ -0,0 +1,110 @@ +#ifndef SLSET2_PNG_H +#define SLSET2_PNG_H + +static const unsigned char slset2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb3, 0xc3, 0x7d, 0x7e, +0x99, 0x22, 0xc3, 0xed, 0x8c, 0xc2, 0xec, 0x8b, +0xbb, 0xe7, 0x84, 0xb9, 0xe6, 0x82, 0xb5, 0xe3, +0x7e, 0xb0, 0xe0, 0x79, 0x9b, 0xd1, 0x63, 0xad, +0xdd, 0x76, 0xa3, 0xd6, 0x6b, 0x98, 0xcf, 0x60, +0x93, 0xcb, 0x5b, 0x48, 0x82, 0xbe, 0x5e, 0x8b, +0x7e, 0xa0, 0xd4, 0x68, 0x9a, 0xd0, 0x62, 0x95, +0xcc, 0x5d, 0x90, 0xc9, 0x57, 0x8b, 0xc5, 0x52, +0x74, 0xc8, 0xe0, 0x73, 0xc7, 0xdf, 0x72, 0xc5, +0xdf, 0x70, 0xc3, 0xde, 0x6f, 0xc1, 0xdd, 0x6d, +0xbf, 0xdc, 0x92, 0xca, 0x5a, 0x8d, 0xc7, 0x54, +0x88, 0xc3, 0x4f, 0x83, 0xc0, 0x4b, 0x73, 0xc6, +0xdf, 0x6e, 0xc1, 0xdd, 0x6c, 0xbe, 0xdc, 0x8f, +0xc8, 0x56, 0x8a, 0xc4, 0x51, 0x85, 0xc1, 0x4d, +0x81, 0xbe, 0x48, 0x7d, 0xbb, 0x44, 0x71, 0xc5, +0xdf, 0x6e, 0xc0, 0xdd, 0x8c, 0xc6, 0x53, 0x87, +0xc2, 0x4e, 0x83, 0xbf, 0x4a, 0x7f, 0xbd, 0x46, +0x7b, 0xba, 0x42, 0x78, 0xb8, 0x3f, 0x70, 0xc2, +0xde, 0x6a, 0xbb, 0xdb, 0x68, 0xb9, 0xda, 0x6d, +0xc0, 0xdd, 0x6c, 0xbd, 0xdc, 0x67, 0xb8, 0xda, +0x63, 0xb3, 0xd7, 0x6b, 0xbd, 0xdc, 0x93, 0xb5, +0xd9, 0x61, 0xb0, 0xd6, 0x5f, 0xae, 0xd5, 0x5f, +0xad, 0xd5, 0x5c, 0xa9, 0xd3, 0x5b, 0xa9, 0xd3, +0x61, 0xa6, 0x3b, 0x47, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x8f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x55, 0xce, 0x57, 0x0e, 0xc2, 0x30, 0x10, 0x04, +0xd0, 0x78, 0xe8, 0x6d, 0x42, 0x4f, 0xe8, 0x84, +0x1a, 0x7a, 0x0d, 0xa6, 0xdd, 0xff, 0x5c, 0x38, +0x46, 0x8a, 0xe3, 0x91, 0xf6, 0x63, 0x9f, 0x46, +0xda, 0x75, 0x1c, 0x1d, 0x01, 0xe1, 0xa4, 0x23, +0x90, 0x81, 0x05, 0xc8, 0x22, 0xa7, 0x3a, 0xa6, +0x27, 0x90, 0x2f, 0x14, 0x21, 0x50, 0x32, 0x3d, +0x94, 0x51, 0x41, 0xb5, 0x16, 0x03, 0xff, 0x71, +0xeb, 0x8d, 0x66, 0xab, 0xad, 0xa1, 0xd3, 0xf5, +0xfc, 0x5e, 0x9f, 0x18, 0x0c, 0x47, 0x63, 0x0d, +0x13, 0xcf, 0x9f, 0x06, 0x74, 0x67, 0xf3, 0xc5, +0x72, 0xa5, 0x61, 0xed, 0x87, 0x6a, 0xdf, 0x6c, +0x77, 0xfb, 0xc3, 0x51, 0xc3, 0x29, 0x0c, 0xce, +0x17, 0xba, 0xd0, 0x89, 0xe1, 0x7a, 0xe3, 0x9d, +0x11, 0x93, 0x83, 0x7c, 0x50, 0x32, 0x7a, 0xbe, +0x12, 0x91, 0x94, 0x6a, 0xde, 0xfc, 0x30, 0xfd, +0xbb, 0xe4, 0x57, 0xb9, 0x2d, 0xf6, 0x6e, 0xf2, +0x03, 0x16, 0xad, 0x0b, 0x8a, 0x2b, 0x6b, 0xf7, +0x15, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slset2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slset2_png = new wxImage(); + if (!img_slset2_png || !img_slset2_png->IsOk()) + { + wxMemoryInputStream img_slset2_pngIS(slset2_png_data, sizeof(slset2_png_data)); + img_slset2_png->LoadFile(img_slset2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slset2_png; +} +#define slset2_png_img slset2_png_img() + +static wxBitmap *slset2_png_bmp() +{ + static wxBitmap *bmp_slset2_png; + if (!bmp_slset2_png || !bmp_slset2_png->IsOk()) + bmp_slset2_png = new wxBitmap(*slset2_png_img); + return bmp_slset2_png; +} +#define slset2_png_bmp slset2_png_bmp() + +static wxIcon *slset2_png_ico() +{ + static wxIcon *ico_slset2_png; + if (!ico_slset2_png || !ico_slset2_png->IsOk()) + { + ico_slset2_png = new wxIcon(); + ico_slset2_png->CopyFromBitmap(*slset2_png_bmp); + } + return ico_slset2_png; +} +#define slset2_png_ico slset2_png_ico() + +#endif // SLSET2_PNG_H diff --git a/include/images/slsets.png b/include/images/slsets.png new file mode 100644 index 0000000..18b1551 Binary files /dev/null and b/include/images/slsets.png differ diff --git a/include/images/slsets.pngc b/include/images/slsets.pngc new file mode 100644 index 0000000..ad939be --- /dev/null +++ b/include/images/slsets.pngc @@ -0,0 +1,99 @@ +#ifndef SLSETS_PNG_H +#define SLSETS_PNG_H + +static const unsigned char slsets_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x7e, 0x99, 0x22, 0xb3, +0xc3, 0x7d, 0xc3, 0xed, 0x8c, 0xc0, 0xeb, 0x89, +0xb7, 0xe5, 0x80, 0xb2, 0xe1, 0x7b, 0x91, 0xb5, +0x44, 0x48, 0x82, 0xbe, 0x68, 0x90, 0x62, 0x74, +0xc8, 0xe0, 0x73, 0xc6, 0xdf, 0x71, 0xc4, 0xde, +0x78, 0xa9, 0x6f, 0x72, 0xc6, 0xdf, 0x70, 0xc3, +0xde, 0x58, 0x9c, 0xcb, 0x6e, 0xc0, 0xdd, 0xac, +0xdd, 0x75, 0xa6, 0xd9, 0x6f, 0x9a, 0xd0, 0x62, +0x6d, 0xbf, 0xdc, 0xa0, 0xd4, 0x68, 0x93, 0xcb, +0x5b, 0x8d, 0xc7, 0x55, 0x93, 0xb5, 0xd9, 0x88, +0xc3, 0x4f, 0x82, 0xbf, 0x4a, 0x7e, 0xbc, 0x45, +0x7a, 0xb9, 0x41, 0x6b, 0xbd, 0xdb, 0x75, 0xa6, +0x6e, 0x68, 0xb9, 0xda, 0x65, 0xb5, 0xd8, 0x62, +0xb2, 0xd7, 0x62, 0xb1, 0xd7, 0x5d, 0xab, 0xd4, +0x5d, 0xaa, 0xd4, 0x8a, 0xff, 0xf6, 0x2a, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x7c, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x55, 0xcf, 0xd9, 0x16, 0xc2, +0x20, 0x0c, 0x45, 0xd1, 0xdc, 0x3a, 0x5d, 0x47, +0x44, 0xab, 0x36, 0xad, 0xf3, 0xf0, 0xff, 0xbf, +0x68, 0xa8, 0x0b, 0x4c, 0x79, 0xe3, 0xac, 0x0d, +0x04, 0x11, 0x5b, 0xa8, 0xc4, 0xaf, 0x0a, 0x23, +0x0c, 0x02, 0xc6, 0x98, 0x00, 0xbe, 0x61, 0x3a, +0x33, 0x94, 0x0b, 0xc9, 0x39, 0x3c, 0xe2, 0x62, +0xb9, 0x5a, 0xc3, 0x21, 0x6e, 0xc2, 0xb6, 0x20, +0xb1, 0xc4, 0x10, 0x33, 0xda, 0xed, 0x51, 0x43, +0x78, 0x60, 0x46, 0xc7, 0xfa, 0xd4, 0x40, 0x94, +0x5a, 0x50, 0xd3, 0x76, 0xbf, 0x6b, 0x7a, 0x14, +0xd1, 0x76, 0xe7, 0x4b, 0x1f, 0xd4, 0x9e, 0x0e, +0xf1, 0x7a, 0x03, 0xfe, 0xf3, 0x19, 0xba, 0x3f, +0x9e, 0xd4, 0x32, 0x6c, 0x42, 0x2f, 0xbe, 0xe9, +0xbf, 0xa4, 0xfc, 0x0c, 0xf6, 0xa9, 0xa4, 0x13, +0x5f, 0x9b, 0x88, 0x06, 0x71, 0x34, 0x11, 0x66, +0x61, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsets_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsets_png = new wxImage(); + if (!img_slsets_png || !img_slsets_png->IsOk()) + { + wxMemoryInputStream img_slsets_pngIS(slsets_png_data, sizeof(slsets_png_data)); + img_slsets_png->LoadFile(img_slsets_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsets_png; +} +#define slsets_png_img slsets_png_img() + +static wxBitmap *slsets_png_bmp() +{ + static wxBitmap *bmp_slsets_png; + if (!bmp_slsets_png || !bmp_slsets_png->IsOk()) + bmp_slsets_png = new wxBitmap(*slsets_png_img); + return bmp_slsets_png; +} +#define slsets_png_bmp slsets_png_bmp() + +static wxIcon *slsets_png_ico() +{ + static wxIcon *ico_slsets_png; + if (!ico_slsets_png || !ico_slsets_png->IsOk()) + { + ico_slsets_png = new wxIcon(); + ico_slsets_png->CopyFromBitmap(*slsets_png_bmp); + } + return ico_slsets_png; +} +#define slsets_png_ico slsets_png_ico() + +#endif // SLSETS_PNG_H diff --git a/include/images/slsubscription.png b/include/images/slsubscription.png new file mode 100644 index 0000000..78f4953 Binary files /dev/null and b/include/images/slsubscription.png differ diff --git a/include/images/slsubscription.pngc b/include/images/slsubscription.pngc new file mode 100644 index 0000000..d48682d --- /dev/null +++ b/include/images/slsubscription.pngc @@ -0,0 +1,132 @@ +#ifndef SLSUBSCRIPTION_PNG_H +#define SLSUBSCRIPTION_PNG_H + +static const unsigned char slsubscription_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x29, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0xff, +0xff, 0xff, 0xfd, 0xfe, 0xff, 0xfb, 0xfd, 0xfe, +0xf8, 0xfc, 0xfe, 0xf5, 0xfb, 0xfd, 0xf1, 0xf9, +0xfc, 0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe5, +0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xdd, 0xf1, 0xf8, +0xfa, 0xfd, 0xfe, 0xf7, 0xfc, 0xfe, 0xf4, 0xfb, +0xfd, 0xed, 0xf8, 0xfb, 0xe2, 0xdf, 0xe4, 0xd1, +0x79, 0x7c, 0xda, 0xdc, 0xe3, 0xd8, 0xef, 0xf7, +0xf7, 0xfc, 0xfd, 0xf0, 0xf9, 0xfc, 0xc5, 0x00, +0x00, 0xcc, 0x77, 0x7b, 0xd3, 0xed, 0xf6, 0xf0, +0xe4, 0xe7, 0xd9, 0x7c, 0x7e, 0xe8, 0xe2, 0xe5, +0xe8, 0xf6, 0xfb, 0xe1, 0xdf, 0xe4, 0xd1, 0xd9, +0xe1, 0xce, 0xeb, 0xf5, 0xf3, 0xfa, 0xfd, 0xd5, +0x7b, 0x7d, 0xd0, 0x79, 0x7c, 0xc9, 0xe9, 0xf4, +0xef, 0xf9, 0xfc, 0xd5, 0x7a, 0x7d, 0xcd, 0xeb, +0xf5, 0xc4, 0xe7, 0xf4, 0xeb, 0xf7, 0xfb, 0xe7, +0xf5, 0xfa, 0xe0, 0xdf, 0xe4, 0xd0, 0xd8, 0xe1, +0xc8, 0xe9, 0xf4, 0xbe, 0xaf, 0x74, 0xb9, 0x87, +0x1b, 0x90, 0x72, 0x33, 0xe3, 0xf3, 0xf9, 0xde, +0xf2, 0xf9, 0xd8, 0xdb, 0xe3, 0xcb, 0x77, 0x7b, +0xcc, 0xea, 0xf5, 0xc4, 0xe7, 0xf3, 0xfc, 0xf7, +0xad, 0xd6, 0xb8, 0x79, 0xe2, 0xf3, 0xf9, 0xd9, +0xf0, 0xf8, 0xd5, 0xee, 0xf7, 0xd0, 0xec, 0xf6, +0xbf, 0xaf, 0x74, 0xfa, 0xf4, 0x9f, 0xf8, 0xf1, +0x91, 0x1e, 0x50, 0xad, 0xfd, 0xf8, 0xb4, 0xfb, +0xf6, 0xa9, 0xfa, 0xf4, 0x9c, 0xf8, 0xf1, 0x8f, +0xf6, 0xee, 0x80, 0xf5, 0xeb, 0x72, 0xd9, 0xef, +0xf7, 0xd4, 0xee, 0xf7, 0xcb, 0xea, 0xf5, 0xc7, +0xe8, 0xf4, 0xc2, 0xe6, 0xf3, 0xfb, 0xf6, 0xa7, +0xf9, 0xf3, 0x9a, 0xf8, 0xf0, 0x8c, 0xf6, 0xee, +0x7e, 0xf4, 0xeb, 0x6f, 0xf3, 0xe8, 0x61, 0xf1, +0xe5, 0x53, 0xd4, 0xed, 0xf7, 0xf9, 0xf3, 0x98, +0xf7, 0xf0, 0x8a, 0xf6, 0xed, 0x7c, 0xf4, 0xea, +0x6d, 0xf2, 0xe8, 0x5f, 0xf1, 0xe5, 0x51, 0xcf, +0xeb, 0xf6, 0xca, 0xea, 0xf5, 0xc6, 0xe8, 0xf4, +0xbe, 0xe4, 0xf2, 0xba, 0xe3, 0xf1, 0xb8, 0xac, +0x73, 0xf2, 0xe7, 0x5c, 0xf0, 0xe4, 0x4f, 0xf0, +0xe4, 0x4c, 0x2f, 0xc4, 0xf0, 0x26, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xc0, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, +0x60, 0x60, 0x44, 0x00, 0x06, 0x10, 0x60, 0x64, +0x62, 0x66, 0x61, 0x65, 0x63, 0xe7, 0xe0, 0xe4, +0xe2, 0xe6, 0x01, 0x8b, 0x30, 0x32, 0xf3, 0xf2, +0xf1, 0xb3, 0x0b, 0x70, 0x0a, 0x0a, 0x09, 0x8b, +0x40, 0x04, 0x78, 0x45, 0xf9, 0xc5, 0x40, 0x7c, +0x71, 0x09, 0x49, 0x88, 0x80, 0xa8, 0x94, 0xb4, +0x8c, 0xac, 0x1c, 0x90, 0x2f, 0xaf, 0x00, 0x11, +0x50, 0x94, 0x16, 0x57, 0x92, 0x53, 0x06, 0xf1, +0x55, 0x20, 0x02, 0xaa, 0x32, 0x6a, 0xe2, 0x20, +0xbe, 0xba, 0x8a, 0x06, 0x44, 0x40, 0x53, 0x4b, +0x1b, 0xc8, 0xd7, 0x51, 0xd7, 0xd5, 0xd3, 0x37, +0x00, 0x0b, 0x68, 0x19, 0x1a, 0x19, 0x9b, 0xe8, +0x98, 0xea, 0x9a, 0xe9, 0x9b, 0xeb, 0x5b, 0x80, +0x04, 0x2c, 0x8d, 0xac, 0xac, 0x6d, 0x4c, 0x6d, +0xf5, 0xf5, 0xf5, 0xed, 0xec, 0x41, 0x22, 0x8c, +0x3c, 0x0e, 0x20, 0xa0, 0xef, 0xe8, 0xe4, 0xec, +0xe2, 0xea, 0x06, 0x14, 0x61, 0x74, 0xf7, 0xb0, +0xf1, 0xf4, 0xf2, 0xd6, 0xf7, 0xf1, 0xf5, 0xf3, +0x0f, 0x08, 0x0c, 0xd2, 0x67, 0x60, 0x0c, 0x86, +0xa8, 0x08, 0x09, 0x0d, 0x0b, 0x8f, 0x88, 0x04, +0xa9, 0x88, 0x8a, 0x8e, 0xf1, 0x8e, 0x8d, 0x8b, +0x07, 0x9a, 0x91, 0x90, 0x08, 0x31, 0x15, 0x06, +0xf4, 0x93, 0xc0, 0x7c, 0x24, 0xa0, 0x0f, 0x22, +0x00, 0x16, 0xa6, 0x1e, 0x2c, 0x4f, 0x9b, 0x2b, +0xa5, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsubscription_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsubscription_png = new wxImage(); + if (!img_slsubscription_png || !img_slsubscription_png->IsOk()) + { + wxMemoryInputStream img_slsubscription_pngIS(slsubscription_png_data, sizeof(slsubscription_png_data)); + img_slsubscription_png->LoadFile(img_slsubscription_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsubscription_png; +} +#define slsubscription_png_img slsubscription_png_img() + +static wxBitmap *slsubscription_png_bmp() +{ + static wxBitmap *bmp_slsubscription_png; + if (!bmp_slsubscription_png || !bmp_slsubscription_png->IsOk()) + bmp_slsubscription_png = new wxBitmap(*slsubscription_png_img); + return bmp_slsubscription_png; +} +#define slsubscription_png_bmp slsubscription_png_bmp() + +static wxIcon *slsubscription_png_ico() +{ + static wxIcon *ico_slsubscription_png; + if (!ico_slsubscription_png || !ico_slsubscription_png->IsOk()) + { + ico_slsubscription_png = new wxIcon(); + ico_slsubscription_png->CopyFromBitmap(*slsubscription_png_bmp); + } + return ico_slsubscription_png; +} +#define slsubscription_png_ico slsubscription_png_ico() + +#endif // SLSUBSCRIPTION_PNG_H diff --git a/include/images/slsubscription2.png b/include/images/slsubscription2.png new file mode 100644 index 0000000..9b7837f Binary files /dev/null and b/include/images/slsubscription2.png differ diff --git a/include/images/slsubscription2.pngc b/include/images/slsubscription2.pngc new file mode 100644 index 0000000..9c4dab0 --- /dev/null +++ b/include/images/slsubscription2.pngc @@ -0,0 +1,124 @@ +#ifndef SLSUBSCRIPTION2_PNG_H +#define SLSUBSCRIPTION2_PNG_H + +static const unsigned char slsubscription2_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x02, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, +0xfb, 0xfd, 0xfe, 0xf8, 0xfc, 0xfe, 0xf5, 0xfb, +0xfd, 0xf1, 0xf9, 0xfc, 0xed, 0xf8, 0xfc, 0xe9, +0xf6, 0xfb, 0xe5, 0xf5, 0xfa, 0xe1, 0xf3, 0xf9, +0xdd, 0xf1, 0xf8, 0xfa, 0xfd, 0xfe, 0xf7, 0xfc, +0xfe, 0xf4, 0xfb, 0xfd, 0xed, 0xf8, 0xfb, 0xe2, +0xdf, 0xe4, 0xd1, 0x79, 0x7c, 0xda, 0xdc, 0xe3, +0xd8, 0xef, 0xf7, 0xf7, 0xfc, 0xfd, 0xf0, 0xf9, +0xfc, 0xc5, 0x00, 0x00, 0xcc, 0x77, 0x7b, 0xd3, +0xed, 0xf6, 0xf0, 0xe4, 0xe7, 0xd9, 0x7c, 0x7e, +0xe8, 0xe2, 0xe5, 0xe8, 0xf6, 0xfb, 0xe1, 0xdf, +0xe4, 0xd1, 0xd9, 0xe1, 0xce, 0xeb, 0xf5, 0xf3, +0xfa, 0xfd, 0xd5, 0x7b, 0x7d, 0xd0, 0x79, 0x7c, +0xc9, 0xe9, 0xf4, 0xef, 0xf9, 0xfc, 0xd5, 0x7a, +0x7d, 0xcd, 0xeb, 0xf5, 0xc4, 0xe7, 0xf4, 0xeb, +0xf7, 0xfb, 0xe7, 0xf5, 0xfa, 0xe0, 0xdf, 0xe4, +0xd0, 0xd8, 0xe1, 0xc8, 0xe9, 0xf4, 0xc4, 0xe7, +0xf3, 0xc0, 0xe5, 0xf3, 0xe3, 0xf3, 0xf9, 0xde, +0xf2, 0xf9, 0xd8, 0xdb, 0xe3, 0xcb, 0x77, 0x7b, +0xcc, 0xea, 0xf5, 0xbf, 0xe5, 0xf3, 0xbb, 0xe3, +0xf2, 0xe2, 0xf3, 0xf9, 0xd9, 0xf0, 0xf8, 0xd5, +0xee, 0xf7, 0xd0, 0xec, 0xf6, 0xc8, 0xe8, 0xf4, +0xc3, 0xe7, 0xf3, 0xbf, 0xe5, 0xf2, 0xb7, 0xe2, +0xf1, 0x1e, 0x50, 0xad, 0xb3, 0xe0, 0xf0, 0xd9, +0xef, 0xf7, 0xd4, 0xee, 0xf7, 0xcb, 0xea, 0xf5, +0xc7, 0xe8, 0xf4, 0xc2, 0xe6, 0xf3, 0xbe, 0xe5, +0xf2, 0xba, 0xe3, 0xf2, 0xb0, 0xdf, 0xf0, 0xd4, +0xed, 0xf7, 0xad, 0xde, 0xef, 0xcf, 0xeb, 0xf6, +0xca, 0xea, 0xf5, 0xc6, 0xe8, 0xf4, 0xbe, 0xe4, +0xf2, 0xba, 0xe3, 0xf1, 0xb6, 0xe1, 0xf1, 0xb2, +0xe0, 0xf0, 0xaf, 0xdf, 0xef, 0xac, 0xdd, 0xef, +0xaa, 0xdc, 0xee, 0x83, 0x89, 0x3b, 0xee, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, +0x62, 0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0xa7, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x60, 0x64, 0x42, 0x00, 0x46, 0x06, +0x20, 0x60, 0x62, 0x66, 0x61, 0x65, 0x63, 0xe7, +0xe0, 0xe4, 0xe2, 0xe6, 0xe1, 0x65, 0x02, 0x0b, +0xb0, 0xf0, 0xf1, 0x0b, 0x70, 0x08, 0x72, 0x09, +0x09, 0x8b, 0x88, 0x42, 0x04, 0xf8, 0xc4, 0x04, +0xc4, 0x41, 0x7c, 0x09, 0x49, 0x29, 0x88, 0x80, +0x98, 0xb4, 0x8c, 0xac, 0x9c, 0x3c, 0x90, 0xaf, +0xa0, 0x08, 0x11, 0x50, 0x92, 0x91, 0x50, 0x96, +0x57, 0x01, 0xf1, 0x55, 0x21, 0x02, 0x6a, 0xb2, +0xea, 0x12, 0x20, 0xbe, 0x86, 0xaa, 0x26, 0x44, +0x40, 0x4b, 0x5b, 0x07, 0xc8, 0xd7, 0xd5, 0xd0, +0xd3, 0x37, 0x80, 0x08, 0x68, 0x1b, 0x1a, 0x19, +0x9b, 0xe8, 0x9a, 0xea, 0xe9, 0x9b, 0x99, 0x43, +0x04, 0x2c, 0x8c, 0x2c, 0xad, 0xac, 0x4d, 0x6d, +0x6c, 0xed, 0xcc, 0xed, 0x21, 0x02, 0xbc, 0x0e, +0x30, 0xe0, 0x08, 0x11, 0x70, 0x72, 0xb6, 0x76, +0x71, 0x75, 0x73, 0xf7, 0xb0, 0x77, 0xf4, 0x84, +0x08, 0x78, 0xc1, 0x55, 0x78, 0x43, 0x04, 0x7c, +0x7c, 0xfd, 0xdc, 0xfc, 0x03, 0x02, 0x83, 0x82, +0x43, 0x42, 0xc1, 0x02, 0x18, 0xbe, 0x45, 0x03, +0x00, 0xb1, 0x4f, 0x18, 0x29, 0x71, 0x18, 0xc8, +0x5f, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsubscription2_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsubscription2_png = new wxImage(); + if (!img_slsubscription2_png || !img_slsubscription2_png->IsOk()) + { + wxMemoryInputStream img_slsubscription2_pngIS(slsubscription2_png_data, sizeof(slsubscription2_png_data)); + img_slsubscription2_png->LoadFile(img_slsubscription2_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsubscription2_png; +} +#define slsubscription2_png_img slsubscription2_png_img() + +static wxBitmap *slsubscription2_png_bmp() +{ + static wxBitmap *bmp_slsubscription2_png; + if (!bmp_slsubscription2_png || !bmp_slsubscription2_png->IsOk()) + bmp_slsubscription2_png = new wxBitmap(*slsubscription2_png_img); + return bmp_slsubscription2_png; +} +#define slsubscription2_png_bmp slsubscription2_png_bmp() + +static wxIcon *slsubscription2_png_ico() +{ + static wxIcon *ico_slsubscription2_png; + if (!ico_slsubscription2_png || !ico_slsubscription2_png->IsOk()) + { + ico_slsubscription2_png = new wxIcon(); + ico_slsubscription2_png->CopyFromBitmap(*slsubscription2_png_bmp); + } + return ico_slsubscription2_png; +} +#define slsubscription2_png_ico slsubscription2_png_ico() + +#endif // SLSUBSCRIPTION2_PNG_H diff --git a/include/images/slsubscriptions.png b/include/images/slsubscriptions.png new file mode 100644 index 0000000..50f7e60 Binary files /dev/null and b/include/images/slsubscriptions.png differ diff --git a/include/images/slsubscriptions.pngc b/include/images/slsubscriptions.pngc new file mode 100644 index 0000000..09b21a4 --- /dev/null +++ b/include/images/slsubscriptions.pngc @@ -0,0 +1,95 @@ +#ifndef SLSUBSCRIPTIONS_PNG_H +#define SLSUBSCRIPTIONS_PNG_H + +static const unsigned char slsubscriptions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9b, 0x9b, 0x9b, 0x55, +0x55, 0x55, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xfe, +0xf8, 0xfc, 0xfe, 0xf3, 0xfa, 0xfd, 0xed, 0xf8, +0xfc, 0xe7, 0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xda, +0xf0, 0xf8, 0x96, 0x99, 0x9a, 0x1e, 0x50, 0xad, +0xdb, 0x93, 0x96, 0xc8, 0x00, 0x00, 0xd3, 0xed, +0xf6, 0xd3, 0x90, 0x95, 0xcd, 0xeb, 0xf5, 0xd4, +0x5e, 0x60, 0xcf, 0x5c, 0x5f, 0xc6, 0xe8, 0xf4, +0xd4, 0x99, 0x9f, 0xc0, 0xe5, 0xf3, 0xba, 0xe3, +0xf1, 0xb4, 0xe1, 0xf0, 0xaf, 0xdf, 0xef, 0xab, +0xdd, 0xef, 0x8c, 0x00, 0xd8, 0x8d, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x03, 0x11, 0x0c, 0x4c, 0xf2, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x71, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, +0x8f, 0x49, 0x0e, 0x80, 0x20, 0x0c, 0x00, 0xb1, +0xca, 0x22, 0xb2, 0xb8, 0x23, 0xfe, 0xff, 0xa1, +0xd6, 0x56, 0x34, 0xc4, 0xb9, 0x75, 0x3a, 0x09, +0x54, 0x34, 0xf0, 0xd0, 0x08, 0x06, 0xda, 0x4e, +0x2a, 0x6d, 0x7a, 0x0b, 0x45, 0x74, 0x72, 0xa8, +0x22, 0x90, 0xaa, 0x8e, 0x40, 0xe9, 0x3a, 0x02, +0x6d, 0xea, 0x08, 0x8c, 0xe3, 0x48, 0x69, 0x1f, +0x6c, 0x44, 0x81, 0x96, 0xa2, 0xe0, 0xc3, 0x18, +0x27, 0x14, 0xd6, 0x71, 0x34, 0x87, 0x25, 0x4e, +0x2b, 0x0a, 0xb4, 0x14, 0xf5, 0x1b, 0xce, 0x3b, +0x88, 0xfb, 0xa7, 0x14, 0x11, 0x89, 0x5f, 0xa6, +0xe8, 0xde, 0xa7, 0x83, 0x04, 0x47, 0x44, 0x7e, +0x0f, 0xe0, 0x7d, 0x3e, 0x8b, 0xf8, 0xdd, 0xfc, +0x71, 0x01, 0xdc, 0x00, 0x06, 0x0c, 0x5f, 0x40, +0xf6, 0x9c, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *slsubscriptions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_slsubscriptions_png = new wxImage(); + if (!img_slsubscriptions_png || !img_slsubscriptions_png->IsOk()) + { + wxMemoryInputStream img_slsubscriptions_pngIS(slsubscriptions_png_data, sizeof(slsubscriptions_png_data)); + img_slsubscriptions_png->LoadFile(img_slsubscriptions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_slsubscriptions_png; +} +#define slsubscriptions_png_img slsubscriptions_png_img() + +static wxBitmap *slsubscriptions_png_bmp() +{ + static wxBitmap *bmp_slsubscriptions_png; + if (!bmp_slsubscriptions_png || !bmp_slsubscriptions_png->IsOk()) + bmp_slsubscriptions_png = new wxBitmap(*slsubscriptions_png_img); + return bmp_slsubscriptions_png; +} +#define slsubscriptions_png_bmp slsubscriptions_png_bmp() + +static wxIcon *slsubscriptions_png_ico() +{ + static wxIcon *ico_slsubscriptions_png; + if (!ico_slsubscriptions_png || !ico_slsubscriptions_png->IsOk()) + { + ico_slsubscriptions_png = new wxIcon(); + ico_slsubscriptions_png->CopyFromBitmap(*slsubscriptions_png_bmp); + } + return ico_slsubscriptions_png; +} +#define slsubscriptions_png_ico slsubscriptions_png_ico() + +#endif // SLSUBSCRIPTIONS_PNG_H diff --git a/include/images/sortfilter.png b/include/images/sortfilter.png new file mode 100644 index 0000000..378d029 Binary files /dev/null and b/include/images/sortfilter.png differ diff --git a/include/images/sortfilter.pngc b/include/images/sortfilter.pngc new file mode 100644 index 0000000..306d5b2 --- /dev/null +++ b/include/images/sortfilter.pngc @@ -0,0 +1,108 @@ +#ifndef SORTFILTER_PNG_H +#define SORTFILTER_PNG_H + +static const unsigned char sortfilter_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa3, 0xa4, 0xc3, 0x7b, +0x7e, 0xb7, 0x70, 0x73, 0xb4, 0x81, 0x83, 0xbd, +0xed, 0xee, 0xf6, 0xf0, 0xe6, 0xff, 0xe8, 0xda, +0xfe, 0xe4, 0xd6, 0xfb, 0xe2, 0xd4, 0xf9, 0xde, +0xd0, 0xf7, 0xdb, 0xcd, 0xf4, 0xd7, 0xc9, 0xf1, +0xd3, 0xc5, 0xee, 0xcf, 0xc1, 0xea, 0xca, 0xbc, +0xe7, 0xc7, 0xba, 0xe4, 0xd5, 0xcc, 0xea, 0xec, +0xec, 0xf5, 0x80, 0x83, 0xbd, 0xdf, 0xd7, 0xf5, +0xd4, 0xbc, 0xf9, 0xc7, 0xab, 0xf4, 0xbf, 0xa3, +0xef, 0xb8, 0x9c, 0xe9, 0xb0, 0x95, 0xe3, 0xa8, +0x8d, 0xdd, 0xa0, 0x85, 0xd6, 0x97, 0x7c, 0xd0, +0x90, 0x76, 0xca, 0x99, 0x83, 0xcc, 0xc5, 0xbc, +0xe0, 0xdc, 0xd3, 0xf3, 0xca, 0xb2, 0xf2, 0xb9, +0x9e, 0xe9, 0xd7, 0xcf, 0xef, 0xbd, 0xa6, 0xe8, +0xa9, 0x8f, 0xde, 0xd1, 0xc9, 0xeb, 0xad, 0x95, +0xdb, 0x8e, 0x74, 0xc9, 0x95, 0x7f, 0xca, 0xc3, +0xba, 0xdf, 0xbc, 0xaa, 0xe1, 0x85, 0x6b, 0xc2, +0xaa, 0x99, 0xd3, 0xc4, 0xb6, 0xe3, 0x7c, 0x62, +0xbb, 0xb6, 0xa8, 0xd8, 0xc1, 0xb4, 0xe0, 0x74, +0x5a, 0xb4, 0xb4, 0xa6, 0xd5, 0xbc, 0xaf, 0xdc, +0x6b, 0x51, 0xad, 0xaf, 0xa2, 0xd2, 0xb8, 0xab, +0xd9, 0x62, 0x49, 0xa7, 0xab, 0x9e, 0xcf, 0xea, +0xe6, 0xf3, 0xe6, 0xe2, 0xf0, 0x98, 0x99, 0xc0, +0x13, 0x99, 0x88, 0xa2, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x63, 0x60, 0x40, 0x07, 0x8c, 0x4c, 0xcc, 0x48, +0x80, 0x89, 0x91, 0x81, 0x85, 0x95, 0x8d, 0x9d, +0x83, 0x93, 0x8b, 0x9b, 0x87, 0x97, 0x8f, 0x5f, +0x40, 0x50, 0x48, 0x98, 0x81, 0x91, 0x45, 0x44, +0x54, 0x4c, 0x5c, 0x42, 0x52, 0x4a, 0x5a, 0x46, +0x56, 0x4e, 0x5e, 0x98, 0x11, 0xa8, 0x87, 0x45, +0x41, 0x51, 0x09, 0x89, 0x0f, 0x12, 0x51, 0x56, +0x51, 0x45, 0xe2, 0x83, 0x44, 0xd4, 0xd4, 0x65, +0x34, 0x34, 0xb5, 0x60, 0x7c, 0x90, 0x88, 0xb6, +0x86, 0x8e, 0x2e, 0x82, 0xcf, 0xc0, 0xc0, 0xac, +0xa7, 0xa3, 0x6f, 0xc0, 0x8c, 0xe4, 0x18, 0x66, +0x43, 0x7d, 0x23, 0x63, 0x14, 0x01, 0x13, 0x23, +0x53, 0x33, 0x14, 0x01, 0x73, 0x53, 0x0b, 0x4b, +0x14, 0x01, 0x2b, 0x33, 0x4b, 0x6b, 0x64, 0x01, +0x1b, 0x90, 0x3f, 0x6c, 0x18, 0x88, 0x03, 0x00, +0x38, 0xdc, 0x0a, 0xf8, 0xf9, 0x50, 0xb7, 0xe4, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sortfilter_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sortfilter_png = new wxImage(); + if (!img_sortfilter_png || !img_sortfilter_png->IsOk()) + { + wxMemoryInputStream img_sortfilter_pngIS(sortfilter_png_data, sizeof(sortfilter_png_data)); + img_sortfilter_png->LoadFile(img_sortfilter_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sortfilter_png; +} +#define sortfilter_png_img sortfilter_png_img() + +static wxBitmap *sortfilter_png_bmp() +{ + static wxBitmap *bmp_sortfilter_png; + if (!bmp_sortfilter_png || !bmp_sortfilter_png->IsOk()) + bmp_sortfilter_png = new wxBitmap(*sortfilter_png_img); + return bmp_sortfilter_png; +} +#define sortfilter_png_bmp sortfilter_png_bmp() + +static wxIcon *sortfilter_png_ico() +{ + static wxIcon *ico_sortfilter_png; + if (!ico_sortfilter_png || !ico_sortfilter_png->IsOk()) + { + ico_sortfilter_png = new wxIcon(); + ico_sortfilter_png->CopyFromBitmap(*sortfilter_png_bmp); + } + return ico_sortfilter_png; +} +#define sortfilter_png_ico sortfilter_png_ico() + +#endif // SORTFILTER_PNG_H diff --git a/include/images/splash.png b/include/images/splash.png new file mode 100644 index 0000000..63755e6 Binary files /dev/null and b/include/images/splash.png differ diff --git a/include/images/splash.pngc b/include/images/splash.pngc new file mode 100644 index 0000000..3e58f41 --- /dev/null +++ b/include/images/splash.pngc @@ -0,0 +1,12625 @@ +#ifndef SPLASH_PNG_H +#define SPLASH_PNG_H + +static const unsigned char splash_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x01, 0xf3, 0x00, 0x00, 0x01, 0x54, +0x08, 0x06, 0x00, 0x00, 0x00, 0x30, 0x16, 0xd5, +0x1d, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, +0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, +0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x80, 0x00, 0x49, 0x44, 0x41, 0x54, +0x78, 0xda, 0xec, 0xbd, 0x7b, 0x7c, 0x5c, 0xc7, +0x75, 0x1f, 0xfe, 0xdd, 0xdd, 0xbb, 0x7b, 0xef, +0x62, 0x17, 0xc0, 0x02, 0x04, 0x09, 0x80, 0x2f, +0x80, 0x14, 0x25, 0x82, 0xd4, 0x8b, 0x92, 0x65, +0x89, 0x92, 0x2c, 0x5b, 0x7e, 0xc9, 0x8e, 0x1d, +0xbb, 0x4e, 0xe2, 0x38, 0x76, 0x9c, 0x34, 0x4e, +0x9b, 0x87, 0x93, 0x34, 0x2f, 0x37, 0xbf, 0x34, +0xbf, 0xc4, 0x49, 0xd4, 0x38, 0x75, 0xd3, 0xb4, +0x4d, 0xd3, 0x5f, 0x9a, 0x34, 0x4d, 0x9a, 0xa4, +0x49, 0xf3, 0x70, 0x9c, 0xb8, 0x7e, 0xc5, 0xb2, +0xe4, 0x87, 0x24, 0x3f, 0x49, 0xd9, 0xb2, 0x04, +0x5b, 0x0f, 0x42, 0x12, 0x25, 0x82, 0x22, 0x29, +0x00, 0x24, 0x48, 0x2c, 0x88, 0x5d, 0xec, 0x7b, +0xf7, 0xf7, 0xc7, 0xe2, 0x5c, 0x9c, 0x7b, 0xf6, +0xcc, 0xdc, 0xbb, 0x0b, 0x50, 0xa2, 0xd3, 0xcc, +0xe7, 0x83, 0x0f, 0x76, 0xef, 0x9d, 0x39, 0x73, +0xe6, 0xcc, 0xec, 0x9c, 0x39, 0xcf, 0x89, 0xe1, +0x7f, 0x3c, 0xdc, 0x82, 0x52, 0x06, 0xdc, 0x24, +0x2e, 0x56, 0x6a, 0x91, 0x9f, 0x6f, 0x66, 0xe1, +0x7d, 0x84, 0xf5, 0xb7, 0xd1, 0xf7, 0x51, 0xf0, +0xd8, 0xac, 0x3e, 0xa2, 0xc2, 0xb1, 0xd5, 0x93, +0xef, 0xba, 0xa9, 0xbb, 0xd9, 0xf4, 0xe9, 0x85, +0x96, 0x97, 0xb2, 0xfd, 0x66, 0xcd, 0xc3, 0xe5, +0x80, 0x6f, 0x37, 0xf3, 0xfc, 0x62, 0x94, 0xcd, +0x1e, 0xcf, 0x66, 0xc1, 0xdd, 0x8c, 0xfa, 0xdd, +0xb6, 0xb9, 0xd4, 0xeb, 0x67, 0xb3, 0x7e, 0xe3, +0x9b, 0xb9, 0x66, 0x36, 0xf3, 0xb7, 0xb5, 0x11, +0xdc, 0x7a, 0x59, 0x47, 0x9b, 0xdd, 0x57, 0x2f, +0xef, 0x5f, 0x8c, 0xdf, 0x6f, 0xdc, 0xf4, 0xc2, +0xd4, 0x71, 0xd4, 0x89, 0x1a, 0x70, 0x93, 0x1d, +0xcf, 0x6c, 0xdf, 0x4d, 0x7d, 0x84, 0xf5, 0xb7, +0x91, 0xf7, 0x1c, 0x07, 0x0d, 0x1f, 0x6a, 0x1b, +0xb5, 0x8f, 0xa8, 0xf0, 0xc2, 0xe0, 0xd8, 0xea, +0xc9, 0x77, 0xdd, 0xd4, 0xdd, 0x6c, 0xfa, 0x98, +0xde, 0x69, 0xed, 0xa2, 0xae, 0x9b, 0x30, 0x3c, +0xa3, 0xae, 0x9b, 0x28, 0x63, 0xb6, 0x8d, 0xaf, +0x5b, 0xba, 0xc8, 0xff, 0x1b, 0xa5, 0x7d, 0xd4, +0x79, 0xb6, 0xd1, 0xc3, 0x84, 0xa3, 0xa9, 0xdd, +0xa5, 0xa4, 0xff, 0x46, 0xf6, 0x93, 0xb0, 0xf9, +0x92, 0xfb, 0x8d, 0x09, 0x57, 0x6d, 0x5f, 0xea, +0x06, 0x8f, 0xb0, 0xba, 0x1a, 0x0e, 0xb6, 0x3a, +0x51, 0xdb, 0xf6, 0xfa, 0x1b, 0x97, 0x07, 0x02, +0x53, 0xd9, 0xc8, 0xef, 0xb7, 0xd7, 0xdf, 0x4d, +0xaf, 0xeb, 0xb9, 0x97, 0x75, 0x64, 0x5b, 0x3f, +0x1b, 0xd9, 0x4f, 0xba, 0x79, 0x1f, 0x95, 0x2e, +0xa6, 0xef, 0x51, 0x7e, 0xe7, 0x46, 0x66, 0x6e, +0xda, 0xa4, 0xb4, 0x0e, 0xb5, 0x09, 0x0d, 0x5b, +0x90, 0xf2, 0x7b, 0x14, 0xe2, 0x46, 0x29, 0xdd, +0x2c, 0x5a, 0x13, 0xb1, 0xbb, 0x81, 0x11, 0x05, +0xde, 0xb7, 0x4b, 0xe9, 0xf5, 0x87, 0xd9, 0x2b, +0x1d, 0xa2, 0xf4, 0x17, 0x56, 0x27, 0x6c, 0xbd, +0xf4, 0x8a, 0x67, 0xd4, 0x83, 0x8c, 0x3c, 0x80, +0xf5, 0x4a, 0xb3, 0x28, 0x25, 0xea, 0x01, 0xd1, +0x44, 0xb3, 0xb0, 0x79, 0xb9, 0x14, 0xf4, 0xdf, +0xcc, 0x7a, 0x26, 0xfc, 0xb5, 0xfd, 0x46, 0xc3, +0x55, 0xab, 0x17, 0xf6, 0x5b, 0xef, 0x75, 0x3f, +0xe1, 0xef, 0xa3, 0x30, 0xb1, 0x5e, 0xe9, 0xda, +0x6b, 0x9b, 0x8d, 0xfe, 0x7e, 0xa3, 0x1c, 0x5a, +0x7b, 0x59, 0x3b, 0x61, 0xf0, 0xa2, 0x1e, 0x5e, +0xc3, 0x60, 0x6b, 0xbf, 0x89, 0x6e, 0xe7, 0xbb, +0xdb, 0x62, 0xe2, 0x71, 0x51, 0x78, 0x65, 0x14, +0xda, 0xc5, 0x4c, 0x6a, 0xf6, 0x30, 0xa4, 0x36, +0xca, 0xac, 0x5e, 0x4c, 0x35, 0x4b, 0x54, 0x98, +0x97, 0x4a, 0x65, 0xd5, 0x2b, 0xce, 0xb6, 0x1f, +0x4c, 0xaf, 0xea, 0x26, 0x13, 0xbc, 0x97, 0xba, +0x5c, 0x0a, 0xb5, 0xf2, 0x4b, 0xad, 0x9a, 0xee, +0x06, 0xaf, 0xa8, 0x26, 0x9d, 0x17, 0x8b, 0x56, +0x97, 0x92, 0xfe, 0xda, 0x58, 0x2f, 0xe5, 0x5c, +0x5d, 0x6e, 0xeb, 0xa0, 0x5b, 0x5a, 0xbf, 0xd8, +0xea, 0xda, 0x8d, 0x8c, 0x65, 0xb3, 0xe9, 0xd1, +0xcd, 0x1a, 0x7a, 0xa9, 0xc7, 0x7b, 0xa9, 0xd4, +0xf9, 0x51, 0xdb, 0xc7, 0xf9, 0x83, 0xa8, 0x85, +0x88, 0x28, 0x01, 0x76, 0x53, 0x7a, 0x1d, 0x74, +0x18, 0xbc, 0x28, 0x6a, 0x2c, 0x53, 0x5b, 0xdb, +0xe9, 0x27, 0xaa, 0xe4, 0xde, 0xcd, 0x58, 0x35, +0x3a, 0xca, 0xf7, 0xdd, 0xa8, 0x95, 0x7a, 0x55, +0x51, 0xf1, 0xb6, 0x1b, 0x3d, 0x7d, 0x6a, 0xb8, +0x44, 0x59, 0x2b, 0xdd, 0xa8, 0x16, 0x39, 0x1c, +0xdb, 0x7c, 0xdb, 0xe6, 0x2c, 0xaa, 0xe4, 0xdd, +0xcb, 0x98, 0xc3, 0x54, 0xd8, 0x26, 0x29, 0x32, +0xea, 0x8f, 0x3a, 0xaa, 0x96, 0xab, 0x1b, 0x9c, +0xe5, 0x5a, 0x0c, 0x5b, 0x9b, 0xd4, 0xb6, 0x1b, +0x35, 0xbf, 0xc4, 0xb7, 0x17, 0xcd, 0x58, 0x18, +0x6c, 0xf9, 0x2c, 0xca, 0xe1, 0x36, 0x0a, 0x8c, +0x6e, 0xdb, 0xdb, 0x4a, 0x37, 0x26, 0x14, 0x89, +0x3f, 0x9f, 0x97, 0x6e, 0xd5, 0xc6, 0xbd, 0x16, +0xdb, 0x6f, 0xc7, 0xa4, 0xc2, 0xee, 0xe6, 0xf7, +0x65, 0xa3, 0x87, 0x69, 0x5f, 0x8f, 0x6a, 0x02, +0xdd, 0xe8, 0x58, 0xe5, 0xbb, 0x28, 0x07, 0xed, +0x6e, 0x4b, 0x2f, 0xfe, 0x1d, 0xb2, 0xfd, 0x80, +0x9b, 0x0c, 0x97, 0xcc, 0x7b, 0x3d, 0x01, 0xc9, +0xd3, 0x55, 0x2f, 0x48, 0x5f, 0x8a, 0xb2, 0x99, +0x12, 0x88, 0x76, 0x82, 0xdc, 0xec, 0x93, 0xe2, +0x8b, 0xe5, 0xe0, 0xf2, 0x62, 0xe0, 0x7b, 0xb9, +0x8f, 0xe1, 0x72, 0xc2, 0x65, 0x33, 0x70, 0x34, +0xad, 0xc9, 0x6f, 0x87, 0x71, 0x46, 0x1d, 0x4b, +0xaf, 0xb4, 0xb9, 0x94, 0x38, 0xf6, 0x32, 0x9e, +0x97, 0x1a, 0x77, 0x13, 0x5e, 0x2f, 0x35, 0x1e, +0xdd, 0xd6, 0x8b, 0xb2, 0xe6, 0x6d, 0x9a, 0xb1, +0xcb, 0xa1, 0x48, 0x7e, 0x19, 0x15, 0xb7, 0x78, +0x58, 0x85, 0xa8, 0x27, 0xa0, 0x30, 0x7b, 0x74, +0x14, 0xe9, 0x61, 0xb3, 0xa5, 0xa5, 0xcd, 0x92, +0x00, 0xc3, 0x68, 0xd3, 0x0d, 0x9d, 0x36, 0xd2, +0x47, 0x37, 0xef, 0x36, 0xb3, 0x44, 0x71, 0xc8, +0x88, 0x7a, 0x60, 0xdb, 0xa8, 0x5d, 0x7e, 0x23, +0xeb, 0x22, 0xaa, 0x84, 0xd0, 0xcd, 0x78, 0xc3, +0xfa, 0xd9, 0x6c, 0x3b, 0x79, 0x37, 0x1a, 0x99, +0x4b, 0xb1, 0x26, 0x37, 0xd3, 0x96, 0xdb, 0x8d, +0xbf, 0x43, 0x2f, 0xce, 0xa1, 0x97, 0x62, 0x2c, +0xb6, 0x12, 0x26, 0x61, 0x6b, 0x75, 0x37, 0x32, +0x47, 0xbd, 0xf8, 0x21, 0x84, 0xf9, 0x40, 0x85, +0xe1, 0xd3, 0xeb, 0x5c, 0x9a, 0xea, 0x74, 0xe3, +0x90, 0x68, 0xdb, 0xcf, 0xc3, 0xf0, 0xef, 0xd6, +0x5f, 0x64, 0x33, 0x35, 0x1d, 0xdd, 0x3a, 0x9e, +0x4a, 0x7e, 0x19, 0xd5, 0x9f, 0x27, 0x6e, 0x02, +0xdc, 0xed, 0xa4, 0x75, 0xbb, 0x18, 0x35, 0xb5, +0x5a, 0x14, 0xf5, 0x4a, 0x54, 0x7c, 0xc2, 0x70, +0xea, 0xc6, 0xf1, 0xa5, 0xdb, 0x09, 0x35, 0xd5, +0xef, 0x4f, 0x3a, 0xa1, 0xed, 0x7a, 0x71, 0xc0, +0xe8, 0xd5, 0x69, 0x23, 0xea, 0xbb, 0x28, 0x0e, +0x19, 0xdd, 0x7a, 0x92, 0x47, 0xa1, 0x5f, 0xd8, +0x1a, 0xe9, 0x76, 0x4c, 0xbd, 0xe2, 0x68, 0x1b, +0xaf, 0x69, 0x83, 0x09, 0xc3, 0x37, 0xca, 0x66, +0xb1, 0x11, 0x9f, 0x8a, 0x6e, 0xc6, 0x67, 0xa2, +0x9f, 0xf6, 0xb9, 0x17, 0xfa, 0x9b, 0x36, 0xa3, +0xb0, 0xdf, 0x78, 0x54, 0x86, 0xd2, 0x0d, 0x53, +0x0b, 0x33, 0x77, 0x6c, 0x86, 0x03, 0x54, 0xd8, +0xe6, 0xdc, 0x2d, 0xfc, 0x5e, 0xf6, 0x5c, 0xd3, +0x38, 0xa3, 0x30, 0x3b, 0x5b, 0xd9, 0xec, 0xa8, +0x84, 0xa8, 0xfb, 0x7c, 0x58, 0x1f, 0xdd, 0x6a, +0x03, 0xb5, 0xcf, 0x1a, 0xbc, 0x8d, 0x38, 0xb4, +0x46, 0xe5, 0x6b, 0x1b, 0xf9, 0xfd, 0xf2, 0xcf, +0x71, 0x53, 0xc5, 0x8d, 0x4c, 0xda, 0x66, 0xd9, +0x94, 0xbb, 0x71, 0x0c, 0xe9, 0x16, 0x9f, 0xb0, +0x85, 0xb1, 0x91, 0x71, 0x9a, 0xda, 0xae, 0xd4, +0xea, 0xa1, 0x74, 0xe8, 0x65, 0xc1, 0xf6, 0x4a, +0xbf, 0xcd, 0x96, 0xfa, 0xc3, 0x6c, 0xd8, 0x51, +0xda, 0x6b, 0x7d, 0x73, 0xd5, 0x59, 0x58, 0x7b, +0x5b, 0xbd, 0x30, 0xa9, 0xa4, 0x9b, 0x71, 0x86, +0x15, 0x1b, 0xa3, 0xe0, 0xf3, 0x12, 0x36, 0x07, +0x9b, 0x71, 0x38, 0xe9, 0xa6, 0xc8, 0x83, 0x48, +0x98, 0x13, 0xa6, 0xfc, 0x1e, 0x85, 0xfe, 0x26, +0xb5, 0x68, 0x37, 0x38, 0x46, 0xa1, 0x43, 0x18, +0x53, 0xed, 0xf5, 0xc0, 0xbe, 0x11, 0xdf, 0x94, +0x28, 0xed, 0x36, 0x7a, 0xe8, 0xd8, 0x08, 0x0e, +0xdd, 0xfe, 0x7e, 0x37, 0x4b, 0x52, 0xdf, 0x0c, +0x27, 0xba, 0xa8, 0x25, 0x8a, 0xd0, 0x18, 0x55, +0x82, 0xee, 0xf5, 0xf7, 0x79, 0x29, 0x34, 0x92, +0xb1, 0xb0, 0xa4, 0x31, 0x36, 0x1b, 0xca, 0x66, +0x31, 0xdb, 0x4b, 0x51, 0xa2, 0xe0, 0x1b, 0xd5, +0xde, 0xd2, 0x6d, 0x5f, 0x97, 0xd2, 0x46, 0xb9, +0xd9, 0xb0, 0x2f, 0xe7, 0x39, 0xfc, 0x76, 0x2b, +0x97, 0x0b, 0xad, 0x4c, 0xce, 0x7f, 0xbd, 0xa8, +0xa1, 0x2f, 0xa7, 0xf1, 0x84, 0xd9, 0x3d, 0xa3, +0xb6, 0xbd, 0xd4, 0xb8, 0x45, 0x6d, 0xd3, 0x6d, +0x1f, 0xbd, 0xc0, 0xba, 0x94, 0x78, 0x6d, 0x26, +0x8c, 0x4b, 0xbd, 0x67, 0x02, 0x9b, 0x73, 0xf8, +0xbd, 0x94, 0x3e, 0x41, 0x1b, 0xb5, 0xe5, 0xc7, +0xa9, 0x41, 0x2f, 0x36, 0x9d, 0x5e, 0xd5, 0x64, +0xb6, 0xc1, 0xf4, 0xf2, 0xde, 0x86, 0xbf, 0xed, +0x99, 0xe6, 0xc1, 0x1b, 0x86, 0xf7, 0x46, 0xd5, +0x41, 0x1b, 0x2d, 0x9b, 0xe5, 0xc9, 0x4c, 0x2a, +0xff, 0xb0, 0xf6, 0xbd, 0x48, 0x05, 0x51, 0xeb, +0x6e, 0xb6, 0x3d, 0x79, 0xb3, 0x4b, 0x98, 0xca, +0x59, 0xd6, 0xed, 0xe6, 0x47, 0x7b, 0x29, 0xc6, +0x6c, 0xda, 0xb4, 0x6c, 0x3e, 0x2b, 0xb6, 0x71, +0x5d, 0x0e, 0x8c, 0x9c, 0xe3, 0x11, 0x66, 0xf7, +0xd4, 0xe8, 0x71, 0xa9, 0x7c, 0x59, 0x6c, 0xb8, +0x6d, 0xd4, 0x4c, 0x67, 0x1a, 0x83, 0xad, 0x7f, +0x53, 0x5f, 0xbd, 0xf8, 0x58, 0x44, 0xa9, 0xab, +0x8d, 0xd3, 0x06, 0x63, 0xa3, 0x9a, 0x84, 0x8d, +0xd0, 0x30, 0xaa, 0xcf, 0x96, 0xe9, 0x5d, 0x37, +0x66, 0x81, 0x30, 0x7a, 0x74, 0x2b, 0xc9, 0x77, +0xe3, 0xbb, 0xd0, 0x53, 0x9c, 0x39, 0x07, 0x78, +0x29, 0x4f, 0xbb, 0x2f, 0x76, 0xbf, 0x61, 0xfd, +0x5c, 0xea, 0x7e, 0xfb, 0x93, 0x8e, 0xaa, 0x8a, +0xdf, 0x08, 0x1e, 0xbd, 0x7a, 0x85, 0x6e, 0xc6, +0xbb, 0xa8, 0xa5, 0x5b, 0x0d, 0xc9, 0x66, 0x8c, +0xc9, 0xf6, 0xfe, 0x52, 0x6b, 0x3b, 0x4c, 0x75, +0xc2, 0x54, 0xda, 0x2f, 0x95, 0x17, 0xf7, 0x66, +0x69, 0xac, 0x5e, 0x8c, 0xd2, 0x2d, 0x9d, 0x36, +0x82, 0xe3, 0x8b, 0x45, 0xf7, 0x28, 0x7d, 0xbd, +0x94, 0xbf, 0xdf, 0x97, 0xba, 0xbc, 0x94, 0x1a, +0x85, 0xa8, 0xed, 0x2f, 0xd5, 0x5e, 0xc3, 0x4b, +0x68, 0x06, 0x38, 0x5b, 0x31, 0xd9, 0x9f, 0x7a, +0x25, 0x86, 0x06, 0x57, 0xab, 0xb3, 0xd9, 0x76, +0x7b, 0xdb, 0x49, 0x55, 0xda, 0x39, 0x2f, 0xa5, +0x34, 0x68, 0xb2, 0xa9, 0xf7, 0x6a, 0x23, 0x8c, +0x4a, 0x2b, 0x59, 0xaf, 0x1b, 0x09, 0x2d, 0x6c, +0x01, 0xf7, 0x62, 0x53, 0xeb, 0x86, 0x91, 0x47, +0x81, 0xd3, 0xed, 0x98, 0x37, 0xaa, 0x51, 0x8a, +0x82, 0x5f, 0x37, 0xa7, 0x70, 0xfe, 0x6e, 0x23, +0x73, 0x1c, 0x85, 0x66, 0x51, 0x70, 0xe6, 0xbf, +0x89, 0x8d, 0xd0, 0x3f, 0x0a, 0x2e, 0xbd, 0x16, +0x93, 0x3d, 0x5f, 0xbe, 0xef, 0x75, 0xfd, 0x86, +0xb5, 0xdd, 0x8c, 0xd2, 0x8d, 0x26, 0xa2, 0x9b, +0xdf, 0x6f, 0xd4, 0xb5, 0x6e, 0x73, 0xd2, 0xec, +0xd6, 0xae, 0x7b, 0x29, 0xf7, 0xcd, 0xcd, 0x98, +0x87, 0x8d, 0xee, 0xed, 0xdd, 0x68, 0xa9, 0xbb, +0xdd, 0x6b, 0xa2, 0xfa, 0xf8, 0x44, 0x96, 0xcc, +0x2f, 0x95, 0xed, 0x69, 0xb3, 0xe0, 0x45, 0x3d, +0x19, 0xf5, 0x2a, 0x35, 0x75, 0x8b, 0x0b, 0x70, +0xe9, 0x7f, 0xec, 0x97, 0xda, 0x1e, 0x16, 0xc6, +0x50, 0x5f, 0x2a, 0x0d, 0xc9, 0xb7, 0x73, 0x7f, +0x2f, 0xe6, 0x58, 0x5e, 0xcc, 0x35, 0xdf, 0x2b, +0x7e, 0x13, 0x19, 0x67, 0xe3, 0x80, 0x58, 0x79, +0xec, 0x42, 0xe9, 0x45, 0x1f, 0x43, 0x14, 0xba, +0xed, 0xed, 0x4f, 0x21, 0x93, 0x4c, 0x74, 0x0d, +0xff, 0x64, 0xb1, 0xde, 0xb3, 0x44, 0xf7, 0x52, +0x68, 0x38, 0x7b, 0xd9, 0x93, 0xc2, 0xf6, 0x4b, +0xe9, 0x90, 0xd9, 0xeb, 0x9a, 0xa1, 0xb5, 0x11, +0x55, 0xd3, 0x19, 0x05, 0xaf, 0xcb, 0xc9, 0x5f, +0xc9, 0x67, 0xe6, 0x9b, 0xa1, 0x52, 0x7e, 0xa9, +0x17, 0xc7, 0xa5, 0xc2, 0xe5, 0x52, 0xfc, 0x28, +0xfa, 0x93, 0x0e, 0x52, 0x71, 0x60, 0x30, 0xd5, +0x56, 0x8e, 0x6c, 0xef, 0x6b, 0x2f, 0x9c, 0x3e, +0x27, 0x8e, 0xc2, 0x72, 0x1e, 0xf3, 0xf5, 0x04, +0x32, 0x7d, 0x69, 0xbf, 0x7e, 0x2f, 0x9b, 0xd4, +0x8b, 0x75, 0x50, 0x7a, 0x31, 0xe0, 0x5f, 0x2a, +0x55, 0x5a, 0xaf, 0x07, 0xa2, 0x28, 0x2a, 0xd0, +0x5e, 0x1c, 0xb6, 0x36, 0x32, 0x9e, 0x8d, 0x98, +0x1f, 0xba, 0x1d, 0xdb, 0x66, 0xe0, 0xfb, 0xb1, +0xbb, 0xf6, 0xe1, 0x75, 0x3b, 0xb2, 0x9b, 0x46, +0x8f, 0x6a, 0xb3, 0x85, 0xf7, 0x3c, 0x38, 0x8b, +0x4f, 0x9c, 0x5c, 0xde, 0x34, 0x98, 0xdd, 0x8e, +0x49, 0x2b, 0x3b, 0xfa, 0x92, 0x38, 0xfa, 0xb6, +0x29, 0x0c, 0xb9, 0xeb, 0xcc, 0xbc, 0xd9, 0xa8, +0x23, 0x9e, 0x08, 0x67, 0x4a, 0xff, 0xe3, 0xd8, +0x22, 0xfe, 0xf5, 0xd1, 0xd3, 0x91, 0xfb, 0xea, +0x15, 0xc7, 0x4b, 0x4d, 0x83, 0xcd, 0x12, 0x3c, +0x3e, 0x78, 0xd3, 0x76, 0xfc, 0xcc, 0xb5, 0xdb, +0xba, 0xc6, 0xb1, 0xd9, 0xa8, 0xe3, 0x07, 0xbe, +0x70, 0x0a, 0x9f, 0x38, 0xb9, 0xfc, 0xa2, 0x99, +0x24, 0x2e, 0x45, 0x7d, 0x5b, 0x1d, 0x7f, 0x35, +0x45, 0x55, 0xe5, 0xda, 0x00, 0x5e, 0x0a, 0x89, +0xbd, 0x57, 0x26, 0xda, 0x6d, 0x3b, 0x9b, 0x14, +0xd3, 0x8d, 0x8a, 0xcb, 0xd6, 0xe7, 0xa8, 0x97, +0xc0, 0x81, 0x9c, 0x8b, 0x83, 0x39, 0x0f, 0x87, +0x47, 0xfb, 0x31, 0x52, 0x5f, 0x41, 0xaa, 0xb6, +0xce, 0xa4, 0xab, 0xc9, 0x34, 0x06, 0xcb, 0x79, +0xac, 0x54, 0x5d, 0x00, 0x40, 0x7f, 0xaa, 0x89, +0x6a, 0xb3, 0x85, 0xc5, 0x2a, 0xf0, 0xad, 0xf1, +0x3e, 0x00, 0xc0, 0x97, 0x0a, 0x49, 0x3c, 0x38, +0xbf, 0x6a, 0xed, 0x5f, 0xa3, 0xdd, 0x46, 0x16, +0x69, 0x2f, 0x27, 0xed, 0x6e, 0xfa, 0xea, 0x86, +0x29, 0x86, 0xf5, 0x6f, 0xc3, 0x57, 0xeb, 0xa7, +0x1b, 0xe6, 0x67, 0x52, 0x7b, 0x86, 0xd1, 0x7f, +0x23, 0x9b, 0x47, 0x94, 0xf1, 0x68, 0xdf, 0xbb, +0xfd, 0x6d, 0x44, 0x1d, 0xdb, 0x66, 0xd1, 0xff, +0xba, 0x5c, 0x0a, 0xaf, 0x19, 0xf3, 0xd0, 0xe7, +0x84, 0xe6, 0xad, 0x8a, 0x5c, 0xfa, 0x00, 0xfc, +0xcc, 0xd5, 0xdb, 0xf0, 0xe0, 0xfc, 0x6a, 0x4f, +0x87, 0x91, 0x6e, 0x24, 0x44, 0x8d, 0x3e, 0xa6, +0xbe, 0x86, 0x3d, 0x07, 0x43, 0x6e, 0x22, 0x38, +0x56, 0x27, 0x15, 0x8a, 0xcf, 0x6a, 0xbd, 0x89, +0x2b, 0x06, 0x3c, 0xb5, 0x2f, 0x89, 0xd7, 0x4b, +0xfd, 0xfb, 0x0d, 0x3b, 0x20, 0x76, 0x33, 0x1f, +0xb6, 0xf7, 0x07, 0x87, 0xfb, 0xd0, 0x6c, 0xd4, +0x91, 0x75, 0xc3, 0xe9, 0xc7, 0x4b, 0xa1, 0x01, +0xec, 0xca, 0xa4, 0x36, 0x9d, 0x8e, 0x51, 0x7e, +0x67, 0x51, 0xd7, 0x60, 0x94, 0xfa, 0x36, 0x38, +0x3d, 0xe9, 0x2b, 0x5e, 0x0c, 0x75, 0x5c, 0x37, +0x83, 0x37, 0x95, 0x6e, 0x0e, 0x1d, 0x9b, 0xed, +0xf5, 0x9a, 0x49, 0xc4, 0xd0, 0xef, 0xc4, 0xb0, +0x33, 0x9b, 0xc2, 0x9d, 0x83, 0x2d, 0xdc, 0x34, +0x10, 0xc3, 0x35, 0x83, 0x29, 0xa4, 0xe2, 0x2d, +0x54, 0x2a, 0x79, 0xa0, 0x90, 0xf7, 0xeb, 0x96, +0xcb, 0x65, 0x78, 0x9e, 0x87, 0xda, 0xf2, 0x05, +0x94, 0x9d, 0x04, 0x5a, 0xf5, 0x06, 0x9a, 0xf5, +0x1a, 0xca, 0xcd, 0xf6, 0x0f, 0x79, 0x18, 0xc0, +0x9d, 0x6e, 0x05, 0x00, 0x70, 0x5b, 0xa2, 0x81, +0xef, 0x77, 0x6a, 0x40, 0xca, 0xc3, 0xa9, 0x78, +0x06, 0x19, 0x34, 0xf1, 0xfc, 0xd9, 0x25, 0x3c, +0x5a, 0xf1, 0xf0, 0xd5, 0x92, 0x87, 0x95, 0x5a, +0x3d, 0xf2, 0x98, 0xbb, 0xa1, 0x75, 0x37, 0xc5, +0xb6, 0xe8, 0x7b, 0xc1, 0xa3, 0x17, 0xbb, 0xff, +0x46, 0xeb, 0x6d, 0xc4, 0x13, 0x5a, 0xfe, 0x28, +0x7b, 0xa5, 0xfd, 0x46, 0x4e, 0xf5, 0x2f, 0x85, +0x53, 0x53, 0x37, 0xf4, 0xff, 0xf1, 0x83, 0x3b, +0x22, 0x49, 0xa6, 0xdd, 0x96, 0xc3, 0xa3, 0x19, +0xfc, 0x24, 0x8e, 0xe3, 0x81, 0x52, 0x0c, 0x0f, +0xa5, 0x77, 0x77, 0x45, 0x87, 0x8d, 0x1e, 0xda, +0x2f, 0x05, 0xcd, 0xb7, 0x97, 0xce, 0xe2, 0x07, +0x16, 0x8f, 0xe2, 0x42, 0xaa, 0x1f, 0xf7, 0x0c, +0x5c, 0x7d, 0x49, 0xfb, 0x8d, 0x62, 0x92, 0x89, +0xf2, 0x1b, 0xb5, 0xad, 0xfb, 0xcd, 0xc0, 0xb5, +0x5b, 0x46, 0x0e, 0x00, 0xf1, 0x84, 0x83, 0xdb, +0x57, 0x9e, 0xc6, 0xfc, 0xd2, 0x09, 0x9c, 0x4c, +0x0d, 0xe3, 0xe1, 0xcc, 0xe4, 0xa6, 0xe0, 0xb6, +0x19, 0x7c, 0x2a, 0x0a, 0xdd, 0xa2, 0x14, 0x87, +0x80, 0xf4, 0x3a, 0x98, 0xcb, 0xa1, 0xf4, 0xaa, +0x29, 0xb8, 0x14, 0xf6, 0xff, 0x6b, 0x07, 0x12, +0xd8, 0x1d, 0xaf, 0xe0, 0x15, 0xb9, 0x18, 0xf6, +0x26, 0xeb, 0x18, 0x70, 0xea, 0x18, 0xe8, 0x4b, +0x03, 0x68, 0xa1, 0x55, 0xab, 0x60, 0xb9, 0x5c, +0x0e, 0xb4, 0x29, 0xaf, 0x7d, 0xaf, 0xd6, 0x1b, +0x81, 0xef, 0xf2, 0x33, 0x00, 0xc4, 0x9d, 0xf6, +0x3c, 0xed, 0x70, 0x01, 0xa0, 0x8c, 0x2b, 0x5c, +0x20, 0x9e, 0x72, 0x71, 0x7d, 0xc2, 0xc3, 0x5b, +0x00, 0x7c, 0x29, 0x5f, 0xc2, 0xfd, 0x45, 0x17, +0xdf, 0xc8, 0x37, 0x70, 0xbe, 0x11, 0x0b, 0x64, +0x9c, 0x0b, 0x4b, 0x58, 0xb3, 0x19, 0xe5, 0xc5, +0x3c, 0x30, 0xbc, 0x94, 0x63, 0x79, 0x31, 0x61, +0x5c, 0x8e, 0x7d, 0x6d, 0xb4, 0x5c, 0x3b, 0x9c, +0xc6, 0x9b, 0x77, 0x0f, 0x6e, 0xaa, 0x54, 0x4e, +0xa5, 0xcf, 0x89, 0xe3, 0xdd, 0x2f, 0xbb, 0x0a, +0xcd, 0x8f, 0x7e, 0x02, 0x4f, 0x78, 0xe3, 0x28, +0xc4, 0x2e, 0x6d, 0xf8, 0xe2, 0xa5, 0x2c, 0x7d, +0x4e, 0x1c, 0x39, 0x07, 0x18, 0x2f, 0x2f, 0x62, +0xa2, 0x76, 0x01, 0x8f, 0x66, 0x26, 0x30, 0x97, +0xd8, 0x3c, 0xb3, 0x84, 0x56, 0xbe, 0x1d, 0xd6, +0xfd, 0x6a, 0xbd, 0xd9, 0xf5, 0xda, 0xe9, 0x73, +0xe2, 0xe8, 0x6f, 0x94, 0x31, 0x55, 0x9e, 0xc7, +0xee, 0xda, 0x05, 0xcc, 0xf4, 0xed, 0xb8, 0xec, +0xd6, 0xc6, 0x46, 0xe9, 0xe6, 0x6c, 0x06, 0x90, +0x6f, 0xd7, 0xb2, 0x99, 0xe3, 0xbe, 0x7d, 0xab, +0x87, 0x9f, 0xde, 0xd1, 0x76, 0x74, 0xe9, 0x8b, +0xa7, 0xd0, 0xaa, 0x55, 0x50, 0x2e, 0x07, 0x19, +0xb4, 0x64, 0xce, 0x40, 0x9b, 0x41, 0x37, 0xeb, +0x35, 0xac, 0x16, 0x56, 0x3a, 0xde, 0x91, 0xc4, +0x4e, 0xed, 0x3c, 0xcf, 0x53, 0xe1, 0x78, 0x9e, +0x07, 0xcf, 0xf3, 0xf0, 0xe6, 0x9d, 0x39, 0xbc, +0xb2, 0xda, 0xc0, 0xa3, 0x2b, 0xc0, 0x97, 0xf3, +0x2d, 0xdc, 0x91, 0x2e, 0x62, 0x38, 0xd1, 0x44, +0xb3, 0x5a, 0xc6, 0xef, 0xcc, 0xa5, 0x70, 0xac, +0x95, 0x45, 0xb1, 0xd1, 0x73, 0x24, 0xe2, 0xa6, +0x97, 0x7f, 0x0c, 0x61, 0x31, 0x2f, 0x75, 0xf9, +0x76, 0xa4, 0xe1, 0xbb, 0xf6, 0x0e, 0x21, 0x15, +0x8f, 0x5d, 0x32, 0xf8, 0x13, 0xfb, 0xae, 0xc4, +0xb6, 0xdc, 0x00, 0x6e, 0x5e, 0x39, 0x8e, 0xfb, +0x07, 0x0e, 0xbc, 0xd4, 0xc3, 0xdd, 0x50, 0xa9, +0x36, 0x81, 0xfe, 0x64, 0x1c, 0x95, 0x26, 0x50, +0x6f, 0x34, 0x80, 0xee, 0x7d, 0xe8, 0x5e, 0xf4, +0xf2, 0xed, 0xb8, 0x26, 0x5f, 0xaa, 0xf2, 0xa2, +0x84, 0xa6, 0x7d, 0x3b, 0x95, 0x97, 0x72, 0xe1, +0x64, 0x12, 0x31, 0x5c, 0xd3, 0xd7, 0xc4, 0xdb, +0xb6, 0xc5, 0x71, 0x45, 0xbc, 0x84, 0x74, 0xa3, +0xb2, 0xc6, 0xc8, 0xd7, 0x24, 0xee, 0xe6, 0x3a, +0xf3, 0x2c, 0x2b, 0x52, 0x79, 0xb3, 0x5e, 0x0b, +0x7c, 0x2f, 0x97, 0xcb, 0xc8, 0xe7, 0xf3, 0x7e, +0xdd, 0x7c, 0x3e, 0x1f, 0x78, 0x4f, 0xef, 0xf8, +0x5f, 0x3e, 0x9f, 0xc7, 0xf2, 0x6a, 0x09, 0xf3, +0xf3, 0xf3, 0x68, 0xd5, 0xab, 0x38, 0x3c, 0xe4, +0xe0, 0x17, 0xf6, 0x24, 0x71, 0x6d, 0x5f, 0x13, +0x99, 0x52, 0x1e, 0xc9, 0x62, 0x1e, 0xff, 0x66, +0xe0, 0x2c, 0xde, 0x1d, 0x3f, 0x8d, 0xd1, 0xf8, +0xe5, 0xf3, 0x23, 0xbb, 0x9c, 0x7e, 0xf0, 0x97, +0x3a, 0x01, 0xcd, 0xa5, 0x2a, 0x97, 0x13, 0x0d, +0xa3, 0x94, 0x2d, 0xae, 0x83, 0x1f, 0xbc, 0x6a, +0xcb, 0x25, 0x91, 0xca, 0xa9, 0x64, 0xdd, 0x14, +0x6e, 0xb9, 0xe1, 0x10, 0x0e, 0x96, 0xe7, 0x91, +0x6d, 0x85, 0x6b, 0xe7, 0x2e, 0xf7, 0x52, 0x69, +0xb6, 0xff, 0x3b, 0x89, 0xcd, 0xe7, 0xe4, 0x97, +0x62, 0xfc, 0x97, 0x7a, 0x4d, 0xf6, 0xb2, 0x76, +0x56, 0xeb, 0x6d, 0x22, 0xba, 0x71, 0xa0, 0x76, +0x19, 0x9d, 0x88, 0x36, 0x93, 0x56, 0xce, 0xff, +0xad, 0xa7, 0xa8, 0x5e, 0xc7, 0x9d, 0x49, 0xc4, +0x90, 0x73, 0x1d, 0x4c, 0xc4, 0xcb, 0xb8, 0x26, +0x1b, 0xc7, 0x6b, 0xc6, 0x3c, 0x0c, 0xc5, 0x9b, +0x18, 0x49, 0xd5, 0x01, 0xb8, 0x1d, 0x0c, 0xbb, +0x59, 0xad, 0xa0, 0x0c, 0x5d, 0x7d, 0xae, 0x49, +0xda, 0x24, 0x8d, 0xf3, 0x22, 0xeb, 0xf3, 0x7a, +0xf4, 0xbf, 0x74, 0x71, 0x19, 0xad, 0xb5, 0xf7, +0xcd, 0x6a, 0x05, 0x71, 0x27, 0x09, 0xcf, 0xf3, +0x30, 0x3c, 0xb2, 0x15, 0x2f, 0x9c, 0x3e, 0x85, +0x72, 0xb9, 0x8c, 0x3b, 0x92, 0x65, 0xdc, 0x91, +0xbc, 0x88, 0x3f, 0xab, 0x8c, 0xe2, 0x21, 0x6c, +0xd9, 0x14, 0x29, 0xfd, 0x1f, 0xcb, 0xfa, 0x79, +0xb1, 0x22, 0x1f, 0x5e, 0xb4, 0xd2, 0xa8, 0x03, +0x9b, 0x64, 0x93, 0xde, 0xcc, 0x31, 0x7d, 0xc7, +0xae, 0xfe, 0x80, 0x57, 0xf7, 0xa5, 0x2a, 0x07, +0x0e, 0x1c, 0xc0, 0xc4, 0xd1, 0xa3, 0x98, 0xa8, +0x2c, 0xe2, 0x09, 0x6f, 0xdc, 0x58, 0xef, 0x72, +0x8f, 0xf6, 0x48, 0xc5, 0x01, 0xd4, 0x2a, 0x40, +0xd2, 0xbd, 0x24, 0x92, 0xf9, 0x65, 0xb1, 0x56, +0xbb, 0x28, 0x47, 0x17, 0x56, 0xf0, 0xb2, 0x91, +0x34, 0x2a, 0xcd, 0x16, 0x72, 0xb5, 0x82, 0xff, +0xdc, 0x75, 0x5d, 0x54, 0x2a, 0x15, 0xff, 0x7b, +0x33, 0xe5, 0x21, 0x5e, 0x0d, 0xee, 0xc5, 0x24, +0x18, 0x25, 0xd1, 0x78, 0xa9, 0x87, 0x71, 0x49, +0x8a, 0xf3, 0xed, 0x36, 0x99, 0x9b, 0x55, 0xba, +0x1d, 0x77, 0xb6, 0x55, 0xc3, 0x6d, 0x23, 0x2e, +0xbe, 0xc7, 0xbd, 0x80, 0x89, 0xdd, 0xbb, 0x31, +0x50, 0x6f, 0xc1, 0x75, 0xe2, 0x00, 0xda, 0x27, +0xbe, 0x66, 0xb5, 0x62, 0x6c, 0x5b, 0x2e, 0x97, +0x51, 0x69, 0xb6, 0x30, 0xd8, 0x97, 0x0e, 0x30, +0x66, 0x4d, 0xed, 0xae, 0x3d, 0x97, 0xea, 0x76, +0x2e, 0x95, 0xd3, 0x77, 0x00, 0x18, 0x1b, 0x1b, +0xf3, 0x17, 0x2c, 0x31, 0xfe, 0xe1, 0x91, 0xad, +0xc8, 0xe5, 0x72, 0xbe, 0x44, 0xef, 0x79, 0x1e, +0x7e, 0x18, 0x0b, 0x78, 0x59, 0xa2, 0x8e, 0x7b, +0x56, 0xfb, 0xf1, 0x44, 0x23, 0x8d, 0xae, 0x8a, +0x60, 0x12, 0xff, 0xb7, 0xae, 0x1f, 0x53, 0xe1, +0xce, 0x6f, 0xfd, 0x89, 0xb6, 0x27, 0x73, 0xb9, +0xd1, 0xc2, 0x42, 0xb9, 0xf1, 0xa2, 0xd0, 0xaa, +0x3f, 0xe9, 0x60, 0xab, 0x17, 0x47, 0x26, 0xb9, +0x3e, 0xaf, 0x17, 0xca, 0x75, 0xac, 0x34, 0x36, +0x7e, 0x01, 0xc8, 0x46, 0xcb, 0x80, 0x9b, 0xc4, +0xcf, 0x5d, 0x3b, 0x7a, 0x49, 0xa5, 0x72, 0x2a, +0xde, 0x40, 0x0e, 0x53, 0x53, 0x53, 0xb8, 0xf9, +0x5b, 0x27, 0xf0, 0x44, 0x72, 0xeb, 0xa6, 0x1d, +0x6c, 0xe4, 0x78, 0x00, 0xb4, 0xe3, 0x9e, 0x33, +0x0e, 0x2e, 0x94, 0xeb, 0xb8, 0x58, 0x6b, 0x6d, +0x9a, 0x7f, 0x8a, 0x2f, 0x4d, 0xba, 0x2e, 0x0a, +0x48, 0x5c, 0x12, 0xc9, 0x9c, 0x97, 0x4c, 0x22, +0x86, 0xed, 0x59, 0x17, 0x5e, 0x62, 0xdd, 0x04, +0x72, 0xb2, 0x58, 0x47, 0xa3, 0x5e, 0xef, 0xe9, +0xe0, 0x3f, 0xe0, 0x26, 0xd1, 0xa8, 0xd7, 0x31, +0xda, 0x97, 0x0c, 0xc4, 0xd8, 0x9b, 0x62, 0xe7, +0xa3, 0x94, 0xdf, 0xfa, 0xe6, 0x02, 0x7e, 0xff, +0xc9, 0xf3, 0xd8, 0xd6, 0x58, 0xc1, 0x7b, 0x2e, +0x1c, 0x81, 0x17, 0x8f, 0xa1, 0x54, 0x5a, 0x8f, +0x08, 0x4a, 0xa7, 0xd3, 0x81, 0xef, 0xf2, 0x59, +0xa5, 0x52, 0x01, 0xbc, 0xee, 0x1d, 0xe8, 0x7a, +0xa1, 0x65, 0xce, 0x75, 0x30, 0xec, 0xad, 0xaf, +0xbb, 0x0b, 0xe5, 0x3a, 0xce, 0xac, 0x6e, 0xe2, +0x1e, 0x20, 0xf6, 0xe2, 0xcd, 0x5f, 0xe1, 0xff, +0x48, 0xcb, 0x60, 0xa6, 0x0f, 0xef, 0xbb, 0x32, +0x8d, 0xad, 0x70, 0x00, 0x94, 0xd1, 0x6c, 0xd6, +0x90, 0x8a, 0x33, 0x49, 0x19, 0x41, 0xa9, 0xba, +0x4a, 0x1e, 0xe9, 0x6b, 0x8c, 0xb6, 0x55, 0xad, +0xa0, 0xcc, 0xec, 0x84, 0x36, 0xa6, 0xae, 0x49, +0xe0, 0xf9, 0x7c, 0xbe, 0xe3, 0x39, 0x44, 0x9f, +0xc4, 0xc8, 0x25, 0xec, 0x5c, 0x2e, 0x87, 0x5c, +0x2e, 0x17, 0x78, 0x7e, 0x97, 0x97, 0xc4, 0x2b, +0xcb, 0x79, 0xfc, 0xef, 0xd5, 0x04, 0x3e, 0x5d, +0xec, 0x8b, 0xbe, 0x01, 0x5d, 0x82, 0x4d, 0xf1, +0x72, 0x28, 0x51, 0x93, 0x7a, 0xb8, 0xb1, 0x16, +0x2a, 0xad, 0x18, 0xca, 0x8d, 0x16, 0x9e, 0x59, +0x5e, 0x9f, 0xb7, 0x01, 0x37, 0x89, 0x3b, 0xc7, +0xfa, 0xf0, 0x96, 0xdd, 0x83, 0x38, 0x30, 0x94, +0xc6, 0x58, 0x5f, 0x12, 0xc3, 0x6e, 0xc2, 0xb7, +0x0d, 0x17, 0xeb, 0x4d, 0x9c, 0x2a, 0x54, 0x71, +0xba, 0x58, 0xc7, 0x67, 0x4f, 0x2f, 0xe3, 0xd3, +0xa7, 0x96, 0xf1, 0xdc, 0x4a, 0x75, 0x53, 0x70, +0xbf, 0x72, 0xd0, 0xc3, 0xed, 0xa3, 0x59, 0x7c, +0xe7, 0xee, 0x01, 0x1c, 0x1a, 0xe9, 0xc3, 0xb0, +0x9b, 0x40, 0x6d, 0xcd, 0xbc, 0x93, 0x71, 0xe2, +0x28, 0xd6, 0x9b, 0xa8, 0x36, 0x5a, 0x38, 0x59, +0xa8, 0xe2, 0x9b, 0xe7, 0x57, 0x71, 0xdf, 0xe9, +0x8b, 0xf8, 0xca, 0x7c, 0x11, 0xe7, 0x2b, 0xeb, +0x73, 0x7e, 0xed, 0x70, 0x77, 0x87, 0x3a, 0x39, +0xfe, 0x28, 0xe5, 0xba, 0x5c, 0x0a, 0x53, 0x39, +0xaf, 0xab, 0x36, 0xbd, 0x96, 0x3e, 0x27, 0x8e, +0x5b, 0x6f, 0xbd, 0x15, 0x47, 0x9f, 0x78, 0x0a, +0xfb, 0x6a, 0xe7, 0x71, 0x1c, 0x5b, 0x36, 0xbc, +0x76, 0x77, 0xf4, 0x25, 0xf1, 0xb6, 0xc9, 0x1c, +0x5e, 0xbf, 0x73, 0x10, 0x3b, 0x33, 0x0e, 0x46, +0xd3, 0x49, 0x64, 0x92, 0xed, 0x83, 0x49, 0xad, +0xd9, 0x42, 0xb5, 0xd1, 0xc2, 0x42, 0xa9, 0x86, +0x63, 0xf9, 0x32, 0x8e, 0x2e, 0x14, 0x71, 0xaa, +0x58, 0xed, 0x08, 0x23, 0xed, 0x76, 0x0c, 0x24, +0x6d, 0x66, 0xd1, 0x40, 0xac, 0x51, 0xf3, 0x25, +0xf3, 0x2d, 0xae, 0x83, 0xed, 0x99, 0xee, 0x54, +0xe4, 0x92, 0x89, 0xee, 0xe8, 0x4b, 0xe2, 0xf5, +0x3b, 0x07, 0x71, 0xfb, 0x68, 0x1f, 0x0e, 0x0c, +0xa5, 0x31, 0x91, 0x4d, 0x21, 0x93, 0x8c, 0xfb, +0x63, 0x19, 0x74, 0x5a, 0x28, 0xb5, 0xe2, 0x38, +0x57, 0xaa, 0xe3, 0xf8, 0xc5, 0x2a, 0x8e, 0x2e, +0xac, 0xe0, 0x73, 0xa7, 0x97, 0xf1, 0xf0, 0x79, +0xf3, 0xbc, 0x5f, 0x39, 0xe8, 0xe1, 0xae, 0x1d, +0xfd, 0xf8, 0xae, 0xc9, 0x1c, 0x26, 0x07, 0x5c, +0xb8, 0xf1, 0x98, 0x4f, 0xa3, 0x62, 0xad, 0x89, +0x54, 0x22, 0x86, 0x6a, 0xa3, 0x85, 0xa7, 0xf2, +0x65, 0x7c, 0xed, 0x6c, 0x11, 0xf7, 0x9c, 0x5a, +0xc6, 0xb7, 0xf2, 0xd5, 0xc8, 0xcc, 0x3d, 0x93, +0x88, 0x61, 0xb2, 0x3f, 0x89, 0xed, 0xf5, 0x24, +0x06, 0x6b, 0x03, 0x88, 0xc5, 0xe3, 0xf0, 0xfa, +0x07, 0x51, 0x6c, 0x00, 0x7d, 0xb1, 0xf6, 0xe1, +0xc7, 0xeb, 0x1f, 0xec, 0x68, 0xd7, 0xe8, 0x1b, +0xc4, 0x85, 0xf3, 0xe7, 0x00, 0xb7, 0x1d, 0xe2, +0x5b, 0x68, 0xc6, 0x7c, 0x5a, 0xf6, 0x92, 0xd0, +0x47, 0xd2, 0x72, 0xc0, 0x4d, 0xe2, 0xae, 0xf1, +0x0c, 0x6e, 0x1d, 0xcb, 0xe2, 0xfa, 0xe1, 0x34, +0x26, 0x07, 0x5c, 0x0c, 0xaf, 0x69, 0xa0, 0x6a, +0xcd, 0x16, 0x92, 0xf1, 0x18, 0x6a, 0xcd, 0x16, +0x4e, 0x15, 0xaa, 0x38, 0x96, 0x2f, 0xe3, 0xe3, +0x27, 0xf2, 0x38, 0x72, 0xb6, 0x18, 0x8d, 0xb9, +0x9b, 0xb4, 0x6c, 0xe2, 0xd9, 0x86, 0x72, 0xb3, +0xff, 0xdf, 0x52, 0x5e, 0x31, 0x9a, 0xc1, 0xf7, +0x8f, 0x34, 0x70, 0x4b, 0x7f, 0xd3, 0x7f, 0x26, +0x25, 0x71, 0x4d, 0x7a, 0x96, 0xef, 0x01, 0xb3, +0x44, 0xae, 0x15, 0x29, 0x89, 0xcb, 0x67, 0x00, +0xfc, 0x13, 0xe7, 0xd0, 0xd0, 0x50, 0x87, 0xb3, +0x1c, 0x67, 0xfe, 0x63, 0x63, 0x63, 0xea, 0x01, +0x00, 0x00, 0x5e, 0x40, 0x1a, 0xff, 0xa9, 0x38, +0xd6, 0xf5, 0xe6, 0xfc, 0x8f, 0xa5, 0xec, 0xed, +0x4f, 0xe1, 0x0b, 0x6f, 0xd9, 0xdf, 0xa1, 0xfe, +0x0d, 0x4b, 0xec, 0xf1, 0xfd, 0xf7, 0x9f, 0xc0, +0x57, 0xe6, 0x8b, 0xf8, 0xd1, 0xa9, 0x2d, 0xf8, +0x91, 0x03, 0x5b, 0x31, 0x96, 0x6e, 0xd7, 0xb5, +0x49, 0x9e, 0x24, 0x6d, 0x55, 0x9b, 0x2d, 0xdc, +0x7f, 0x66, 0x05, 0xff, 0xf6, 0x91, 0xb9, 0x9e, +0xb3, 0x96, 0x5d, 0x3b, 0x9c, 0xc6, 0x2f, 0x5e, +0x3f, 0x8a, 0xbb, 0x76, 0x0e, 0x20, 0x1d, 0x6b, +0xfa, 0xb8, 0x46, 0xe9, 0x7f, 0xbe, 0x54, 0xc7, +0xff, 0x3c, 0x76, 0x0e, 0xbf, 0xf7, 0xf8, 0x59, +0xbc, 0x76, 0xe7, 0x00, 0xfe, 0xfa, 0x35, 0x7b, +0xba, 0xea, 0x7b, 0xa9, 0xd2, 0xc0, 0xe1, 0x8f, +0xcd, 0x74, 0x25, 0x69, 0x50, 0x92, 0x98, 0x17, +0x43, 0x32, 0xa7, 0xb1, 0x7e, 0xf4, 0x6f, 0xff, +0x06, 0xf7, 0x9c, 0x29, 0xe2, 0x6f, 0x86, 0x6e, +0xea, 0x19, 0xce, 0x8e, 0xbe, 0x24, 0xde, 0x77, +0xdd, 0x28, 0x7e, 0xe0, 0xca, 0x61, 0x6c, 0xf5, +0x9c, 0x50, 0x6f, 0x6a, 0xa2, 0x31, 0x00, 0xcc, +0xe4, 0xcb, 0x78, 0xe8, 0x6c, 0x11, 0x3f, 0xd4, +0xa3, 0x9f, 0xc0, 0xf1, 0xe3, 0xc7, 0xf1, 0xe7, +0x7f, 0xfe, 0xe7, 0x00, 0x80, 0x3f, 0x1a, 0x7b, +0x0d, 0xce, 0xa5, 0x06, 0x91, 0x49, 0xc4, 0x70, +0xdf, 0x9b, 0xaf, 0xc2, 0xa1, 0x2d, 0xdd, 0x1d, +0xc0, 0x28, 0x01, 0xcd, 0x2b, 0x46, 0x33, 0xf8, +0xb9, 0x6b, 0x47, 0x71, 0xcb, 0xb6, 0x4c, 0x67, +0xfc, 0x7b, 0x08, 0x3d, 0x01, 0xe0, 0xcf, 0x9f, +0x3e, 0x8f, 0x5f, 0x3b, 0xfa, 0x3c, 0xce, 0x37, +0xd6, 0x85, 0x13, 0xbe, 0x16, 0x33, 0x6b, 0xf0, +0xa2, 0xfe, 0x0e, 0x9e, 0xbb, 0x58, 0xc1, 0x6f, +0x3d, 0x3a, 0x8f, 0xcf, 0xcc, 0x15, 0x43, 0x99, +0xfa, 0x6f, 0xdf, 0xb2, 0x03, 0x3f, 0x79, 0x70, +0xab, 0xfa, 0xae, 0xcf, 0x89, 0x07, 0x68, 0x2f, +0xcb, 0x6f, 0xfe, 0xc3, 0x97, 0xf1, 0xc0, 0xf3, +0x17, 0x70, 0x3e, 0xe6, 0xe2, 0xb8, 0x37, 0x0a, +0xa0, 0x7d, 0xf8, 0xb8, 0xff, 0xcd, 0x57, 0x76, +0x6d, 0xfa, 0xf9, 0x83, 0x27, 0xcf, 0xe1, 0x17, +0x1f, 0x3a, 0x03, 0xa0, 0xcd, 0x1f, 0x7e, 0xf7, +0xb6, 0x5d, 0xd8, 0x3b, 0xe0, 0x22, 0x15, 0x8f, +0x45, 0xa2, 0xe7, 0x6a, 0xbd, 0x89, 0xa5, 0x4a, +0x03, 0xbf, 0xff, 0xc4, 0x59, 0xfc, 0xc1, 0xcc, +0x85, 0x4d, 0xd1, 0x7e, 0x7d, 0xfb, 0x88, 0x59, +0x9b, 0x68, 0x03, 0xec, 0xa6, 0xdc, 0xb5, 0x25, +0x8e, 0x9f, 0xdf, 0xba, 0x82, 0x9d, 0x03, 0x69, +0x94, 0xcb, 0x95, 0x0e, 0x29, 0x99, 0xab, 0xb5, +0xb9, 0xe3, 0x1a, 0x49, 0xc4, 0xb6, 0x50, 0x33, +0x5b, 0x91, 0x8c, 0x57, 0x63, 0xe8, 0xa5, 0x52, +0x09, 0x95, 0x4a, 0x25, 0xd0, 0x0f, 0xd5, 0xa7, +0x3f, 0x6a, 0x37, 0x3f, 0x3f, 0x0f, 0x00, 0xc8, +0xe5, 0x72, 0x1d, 0x7d, 0x6d, 0x47, 0x09, 0xbf, +0x93, 0x39, 0x81, 0x7f, 0xa8, 0xa7, 0xf0, 0xd7, +0xd5, 0xd1, 0x17, 0x25, 0x8c, 0xed, 0x72, 0x2a, +0x99, 0x64, 0x42, 0xdf, 0xd4, 0x2c, 0x89, 0x3d, +0x56, 0xeb, 0x4d, 0xbc, 0x61, 0xe7, 0x00, 0x7e, +0xf1, 0xfa, 0x31, 0x1c, 0xda, 0x92, 0x8e, 0xbc, +0x21, 0x52, 0xbd, 0x3e, 0x00, 0x6f, 0xdc, 0x35, +0x80, 0x37, 0xee, 0x1a, 0xc0, 0x6f, 0x3e, 0x32, +0x87, 0xdf, 0x7b, 0xfc, 0x6c, 0x64, 0x55, 0x66, +0x7f, 0xd2, 0xc1, 0x4f, 0x1d, 0xdc, 0x82, 0x9f, +0xbf, 0x6e, 0x14, 0x19, 0x27, 0xde, 0x15, 0x93, +0xa0, 0xba, 0x63, 0x69, 0x07, 0xef, 0xbf, 0x71, +0x1c, 0x37, 0x6d, 0xcd, 0xe0, 0xe1, 0x73, 0xc5, +0xc0, 0xbb, 0xa8, 0x65, 0xd8, 0x73, 0x22, 0x33, +0xf3, 0x6b, 0x87, 0xd3, 0x78, 0xe5, 0x78, 0xa6, +0x67, 0xe7, 0xa5, 0x56, 0xa5, 0x84, 0x4c, 0x26, +0xd3, 0x55, 0xbb, 0x3e, 0x27, 0x8e, 0x5b, 0x6e, +0xb9, 0x05, 0x33, 0x7f, 0xfd, 0x21, 0x8c, 0x37, +0x0a, 0x5d, 0x87, 0x75, 0xf5, 0x27, 0x1d, 0xbc, +0xf3, 0x8a, 0x1c, 0x7e, 0xed, 0xc6, 0xf1, 0xc0, +0xfa, 0x08, 0x1b, 0x03, 0x7f, 0x3f, 0x95, 0xf3, +0x70, 0xe3, 0x48, 0x5f, 0xd7, 0x63, 0xa6, 0x71, +0x03, 0x6d, 0x35, 0xfb, 0x4a, 0x6d, 0x9d, 0x49, +0xc5, 0xe3, 0x09, 0x4c, 0x64, 0x53, 0x5d, 0xd3, +0xf2, 0xfa, 0xe1, 0x34, 0x7e, 0xe9, 0xfa, 0x51, +0xfc, 0xe2, 0xa1, 0xb1, 0xc8, 0x4c, 0x47, 0x1b, +0xd7, 0x0f, 0x5d, 0xb5, 0x05, 0xb7, 0x6c, 0xcb, +0xe0, 0x1d, 0x9f, 0x7b, 0x0e, 0xcb, 0xd5, 0x26, +0x7e, 0x74, 0x6a, 0x0b, 0xde, 0x7f, 0xe3, 0x78, +0x24, 0xda, 0x48, 0x58, 0x7d, 0x6b, 0x34, 0xfa, +0xd3, 0x57, 0xee, 0xc4, 0xdf, 0x9e, 0xb8, 0x88, +0xf7, 0x1d, 0x7d, 0xc1, 0xba, 0xff, 0x5c, 0x35, +0x98, 0xb6, 0xf6, 0x63, 0xeb, 0x7f, 0x65, 0xcb, +0x2e, 0x3c, 0x34, 0xef, 0x05, 0xf8, 0x88, 0x97, +0x88, 0x75, 0x75, 0xa0, 0xf1, 0xf1, 0x18, 0x70, +0x71, 0xed, 0x70, 0x1a, 0xbf, 0x7e, 0xe3, 0x38, +0xde, 0xb8, 0x6b, 0xa0, 0xab, 0xb1, 0xf3, 0xba, +0x3f, 0x7f, 0xdd, 0x28, 0xbe, 0x73, 0x22, 0x87, +0x7f, 0xfe, 0xc0, 0x89, 0x0d, 0x6b, 0xea, 0x5e, +0x5a, 0x66, 0xde, 0x0d, 0x83, 0xbe, 0xd4, 0x8c, +0x5c, 0xe0, 0x92, 0x49, 0xc4, 0xf0, 0xd6, 0x11, +0xe0, 0x3d, 0x3b, 0x1c, 0x6c, 0xf7, 0x92, 0x2a, +0x73, 0xe5, 0xdf, 0xb5, 0xa2, 0xa9, 0xcf, 0x79, +0x7d, 0x7e, 0x30, 0xd0, 0x18, 0x3d, 0xf7, 0x68, +0xe7, 0xcc, 0x9c, 0xda, 0x97, 0x4a, 0x25, 0xb8, +0xae, 0x8b, 0x72, 0xad, 0x81, 0x56, 0xbd, 0xda, +0xc1, 0xc4, 0x39, 0x7e, 0x52, 0x4d, 0x2f, 0x9d, +0xef, 0xca, 0xe5, 0x32, 0x5e, 0xe7, 0x96, 0x71, +0xc8, 0xab, 0xe0, 0x2f, 0x97, 0xd2, 0xf8, 0x4a, +0x73, 0xe8, 0xd2, 0xd2, 0x3b, 0xe2, 0x3c, 0x74, +0xfd, 0x7e, 0x33, 0xfb, 0xb2, 0x94, 0x3e, 0x27, +0x8e, 0x1f, 0xba, 0x6a, 0x8b, 0xff, 0xb9, 0x57, +0x18, 0x00, 0xf0, 0xfe, 0x1b, 0xc7, 0x71, 0x78, +0x5b, 0x06, 0xef, 0xbe, 0xff, 0x44, 0x24, 0x86, +0xfe, 0x5b, 0x37, 0x8f, 0xe3, 0x5d, 0xfb, 0x86, +0x91, 0x4b, 0xf5, 0x6e, 0x43, 0xa5, 0xbe, 0xdf, +0xb8, 0x6b, 0x00, 0x77, 0x6d, 0xef, 0xeb, 0x7a, +0x0c, 0xcd, 0x46, 0x1d, 0x6f, 0x5a, 0xfa, 0x26, +0xae, 0x5a, 0x2a, 0x60, 0x7a, 0xcb, 0x01, 0x3c, +0xdb, 0xb4, 0x4b, 0x89, 0xef, 0x3d, 0x30, 0xd2, +0x73, 0x38, 0xda, 0x89, 0xa7, 0x8e, 0x21, 0x97, +0xcb, 0x75, 0xcd, 0xcc, 0x01, 0x60, 0xfb, 0xe4, +0x5e, 0x8c, 0x6e, 0xdb, 0x86, 0x1b, 0x8a, 0x27, +0x31, 0x67, 0x48, 0xba, 0xa2, 0x95, 0x1d, 0x7d, +0x49, 0xfc, 0xfe, 0xed, 0xbb, 0xf0, 0xca, 0xed, +0xfd, 0x9b, 0x42, 0xe7, 0x5e, 0xdb, 0x72, 0xa7, +0xae, 0x8d, 0xd8, 0xcc, 0x57, 0xeb, 0x4d, 0x1c, +0x1e, 0xcd, 0xe0, 0xe6, 0x11, 0x17, 0xd9, 0x0d, +0x8c, 0x87, 0xf0, 0x9a, 0xca, 0x79, 0xf8, 0xeb, +0xdb, 0x47, 0x51, 0x4f, 0xf5, 0x75, 0x75, 0x98, +0x35, 0xd2, 0xc8, 0x49, 0xe1, 0x5d, 0xfb, 0x86, +0x01, 0x00, 0x3f, 0xfa, 0xa5, 0xe7, 0xc3, 0xeb, +0xf7, 0x30, 0xfe, 0xab, 0xcb, 0xf3, 0x78, 0xd7, +0xc5, 0xc7, 0xf0, 0x4c, 0x6a, 0x44, 0x4d, 0x1a, +0xd3, 0x0d, 0xac, 0xdb, 0x46, 0x52, 0xf8, 0xfc, +0x1b, 0x26, 0xd0, 0xe7, 0xf5, 0x9e, 0xc5, 0x90, +0xda, 0xdd, 0x36, 0x9a, 0xc1, 0x87, 0x5f, 0xb7, +0x17, 0x6f, 0xf8, 0xc4, 0xb1, 0x75, 0x6d, 0x47, +0x0f, 0x7b, 0xd3, 0x8b, 0x1f, 0x9a, 0xd6, 0x60, +0xa7, 0xae, 0x5e, 0x36, 0xd2, 0xc6, 0x25, 0x92, +0x1a, 0x19, 0x2e, 0x3b, 0xfa, 0x92, 0xf8, 0xb5, +0xbd, 0x09, 0xfc, 0xab, 0xf1, 0x06, 0x86, 0x51, +0x09, 0x30, 0x5a, 0x2e, 0xed, 0x92, 0xf4, 0x0d, +0x74, 0x32, 0x5c, 0x00, 0x1d, 0xdf, 0xa9, 0xbd, +0x7c, 0xc7, 0xa5, 0x69, 0x1e, 0x6e, 0xc6, 0xe1, +0x50, 0x5b, 0xaa, 0xb3, 0xb4, 0xb4, 0x04, 0xa0, +0xed, 0xdc, 0x91, 0xeb, 0xcf, 0x20, 0xe6, 0xa4, +0xb0, 0xb4, 0xb4, 0x14, 0x08, 0x5f, 0xe3, 0x0c, +0x3c, 0x97, 0xcb, 0xc1, 0xf3, 0x3c, 0xcc, 0xcf, +0xcf, 0xab, 0x7d, 0x50, 0xbd, 0x6c, 0x69, 0x19, +0xef, 0xc1, 0x2c, 0x7e, 0x2c, 0x79, 0x06, 0x99, +0xc4, 0xa5, 0x8b, 0x05, 0x8e, 0x32, 0x0f, 0xea, +0x5c, 0x87, 0xbd, 0x0f, 0x2b, 0x72, 0xfd, 0x6d, +0x60, 0x3d, 0xf5, 0x75, 0x29, 0x15, 0xdb, 0xe0, +0xbc, 0x6e, 0xe7, 0x00, 0x3e, 0xf2, 0xca, 0xb1, +0xd0, 0x50, 0xaa, 0x9f, 0x3a, 0xb8, 0x75, 0xc3, +0x8c, 0x5c, 0xf6, 0xdd, 0x4b, 0x46, 0xad, 0x58, +0xbd, 0x86, 0x7d, 0xb1, 0x22, 0xae, 0xaf, 0xce, +0xe3, 0x86, 0xb3, 0x8f, 0x59, 0xeb, 0xee, 0xe8, +0x4b, 0xe2, 0xad, 0x13, 0xb9, 0x9e, 0x37, 0xe1, +0xe9, 0xe9, 0x69, 0x4c, 0x4f, 0x4f, 0xa3, 0x50, +0xe9, 0x5e, 0x72, 0xe9, 0x73, 0xe2, 0xb8, 0xf5, +0xe5, 0x2f, 0xc3, 0xfe, 0xf2, 0x5c, 0x28, 0x6d, +0xa9, 0x64, 0x12, 0x31, 0xfc, 0xd7, 0xdb, 0x36, +0xce, 0xc8, 0x37, 0xa3, 0xb8, 0x6e, 0x3b, 0xb5, +0x73, 0x2a, 0xb1, 0xb1, 0x75, 0x46, 0x6b, 0xb5, +0x97, 0xb9, 0x36, 0xc1, 0xbb, 0x66, 0x7c, 0xcb, +0x86, 0x19, 0xb9, 0x84, 0xf9, 0xae, 0x7d, 0xc3, +0xf8, 0xf1, 0xcc, 0xf9, 0xc8, 0x73, 0xd5, 0x0d, +0xec, 0x5d, 0xd5, 0x0b, 0x38, 0x50, 0x3d, 0x8b, +0x3b, 0x8a, 0xc7, 0x37, 0x04, 0xbf, 0xcf, 0x89, +0x63, 0x24, 0xdb, 0x87, 0x91, 0x6c, 0xf7, 0x87, +0x60, 0x0d, 0x16, 0x00, 0xdc, 0x38, 0xd2, 0x87, +0x0f, 0xec, 0xaa, 0x22, 0x43, 0xe9, 0xbd, 0x7b, +0xe0, 0x8d, 0x2f, 0x3e, 0x33, 0xdf, 0xa8, 0x54, +0x75, 0x09, 0x25, 0xf4, 0xfe, 0xa4, 0x83, 0x1b, +0xfb, 0x9a, 0xf8, 0x95, 0x6d, 0x05, 0xbc, 0x22, +0x53, 0xf5, 0x25, 0x89, 0x6a, 0xbd, 0xd1, 0xa1, +0xe2, 0x36, 0x31, 0x65, 0x2a, 0x5c, 0xfa, 0x96, +0x85, 0x3b, 0xaa, 0x69, 0x1e, 0xea, 0x5c, 0x22, +0x97, 0x71, 0xe5, 0x4b, 0x4b, 0x4b, 0xbe, 0x7a, +0xbd, 0x52, 0xa9, 0x20, 0x9f, 0xcf, 0x63, 0x7e, +0x7e, 0x1e, 0xf9, 0xf3, 0xe7, 0x02, 0xdf, 0x39, +0xd3, 0xd6, 0xf0, 0xa0, 0xf7, 0xbc, 0x90, 0xa3, +0x5c, 0x2e, 0x97, 0xc3, 0xcb, 0x1b, 0x67, 0xf1, +0x2b, 0xad, 0x27, 0xf0, 0xc6, 0xea, 0xec, 0x25, +0xa3, 0x77, 0x68, 0x09, 0x9b, 0xeb, 0x5e, 0xd6, +0x82, 0x6c, 0x73, 0x99, 0x38, 0xf4, 0xf5, 0x39, +0x71, 0xbc, 0x62, 0x72, 0x14, 0xbf, 0xbd, 0xa7, +0x69, 0x3c, 0x60, 0xbc, 0x62, 0x34, 0x83, 0x0f, +0xbc, 0x7c, 0xfb, 0x4b, 0xce, 0x60, 0x00, 0xf8, +0x52, 0x72, 0xa5, 0x09, 0x24, 0x43, 0x18, 0xcd, +0xdb, 0x26, 0x73, 0x3d, 0x87, 0xa3, 0xb5, 0x2a, +0xed, 0xfc, 0x09, 0x33, 0x33, 0x33, 0x88, 0xd5, +0x7b, 0xdb, 0x80, 0xa7, 0xa6, 0xa6, 0xb0, 0x63, +0x30, 0x83, 0x6b, 0x57, 0x4e, 0x44, 0xaa, 0xff, +0x9e, 0xfd, 0x23, 0x78, 0xe3, 0xae, 0x81, 0xcb, +0x82, 0xce, 0x40, 0xdb, 0x03, 0xbb, 0xda, 0x68, +0x6e, 0x1c, 0xd0, 0x26, 0x97, 0xcd, 0x3a, 0xcc, +0x4a, 0x98, 0xff, 0xfa, 0xe6, 0x3d, 0x78, 0x43, +0xfe, 0x31, 0xe3, 0xef, 0xc0, 0x66, 0x17, 0x37, +0x15, 0xd9, 0xa6, 0xd0, 0x7c, 0x09, 0x04, 0x95, +0x10, 0xbc, 0xde, 0xf1, 0xb2, 0xfd, 0xf8, 0x89, +0xd2, 0xf4, 0x3a, 0x43, 0xef, 0xb2, 0xfc, 0xa3, +0x48, 0x1a, 0xb3, 0x59, 0xe5, 0xfb, 0x53, 0x0b, +0xf8, 0x85, 0x2d, 0xcb, 0x78, 0xf9, 0x70, 0x2a, +0xa0, 0x12, 0x6c, 0xd6, 0x6b, 0x1d, 0xaa, 0x70, +0x5b, 0x56, 0xb7, 0x30, 0x3b, 0xb9, 0x16, 0x47, +0x4e, 0x8c, 0x5b, 0xb6, 0x21, 0xe6, 0x4d, 0xef, +0x89, 0x89, 0xf3, 0x7a, 0xd5, 0x78, 0xd2, 0xff, +0xee, 0xba, 0x2e, 0x06, 0x07, 0x07, 0xe1, 0xba, +0x2e, 0x4a, 0xa5, 0x12, 0xe6, 0xe6, 0xe6, 0x70, +0xe2, 0xc4, 0x89, 0x00, 0xf3, 0xf6, 0x3c, 0x0f, +0x63, 0x63, 0x63, 0x18, 0x1b, 0x1b, 0x53, 0x3d, +0xe4, 0x89, 0xa1, 0x4f, 0x0c, 0x78, 0x78, 0x73, +0xf2, 0x02, 0x7e, 0xfc, 0xf4, 0xbd, 0xd8, 0xd1, +0x77, 0xf9, 0x27, 0xd7, 0x78, 0x29, 0x4b, 0xb1, +0x58, 0xf4, 0x7f, 0x98, 0xc5, 0x62, 0xb1, 0x27, +0x18, 0x7d, 0x4e, 0x1c, 0x3f, 0x78, 0xdb, 0x75, +0x78, 0x6f, 0xec, 0x39, 0x75, 0x23, 0xbb, 0xfb, +0x65, 0xbd, 0x33, 0xf2, 0xd5, 0x7a, 0x33, 0xb0, +0x71, 0xf4, 0xb2, 0x21, 0xf2, 0x52, 0xa8, 0x54, +0x51, 0x2e, 0x97, 0x43, 0x99, 0xcc, 0x80, 0x9b, +0xc4, 0x0f, 0xef, 0xdf, 0xd2, 0x33, 0xce, 0x33, +0x33, 0x33, 0xc8, 0xe7, 0xf3, 0x28, 0x95, 0x4a, +0x38, 0x79, 0x66, 0xae, 0x27, 0xbc, 0x63, 0x6e, +0x1a, 0xb7, 0xdc, 0x70, 0x08, 0x2f, 0x2b, 0x9f, +0x09, 0x95, 0xc8, 0x76, 0xf4, 0x25, 0xf1, 0x81, +0x97, 0x6f, 0xef, 0x99, 0x49, 0xd1, 0xdc, 0x6f, +0x94, 0xbe, 0x5a, 0x49, 0x5c, 0xe2, 0xd0, 0xb4, +0xcb, 0xa5, 0x8c, 0xed, 0xda, 0x8d, 0x57, 0x0d, +0x34, 0x71, 0x4b, 0xf5, 0x05, 0xf5, 0xfd, 0x46, +0x0e, 0x10, 0xdc, 0xf7, 0xe0, 0x72, 0x2b, 0xde, +0x40, 0x0e, 0xd7, 0x8f, 0xe5, 0xf0, 0x1d, 0xcb, +0x76, 0x4d, 0x97, 0xe9, 0x90, 0x73, 0x79, 0x88, +0x25, 0x97, 0x41, 0xb9, 0xb1, 0xaf, 0x89, 0x57, +0xef, 0x1e, 0xc6, 0x15, 0xcc, 0xf4, 0xc7, 0x99, +0x2a, 0xe5, 0x4e, 0x27, 0xd5, 0xb5, 0x2d, 0x4e, +0xdc, 0xf6, 0xdd, 0x24, 0xc9, 0xcb, 0xef, 0x5c, +0x95, 0x6e, 0xaa, 0x43, 0xb6, 0x70, 0xde, 0x0f, +0xb7, 0xb1, 0xb9, 0xae, 0x8b, 0x74, 0x3a, 0xed, +0xbf, 0xe7, 0xda, 0x02, 0xcd, 0x51, 0x8f, 0x3f, +0x4b, 0x0f, 0x0c, 0xc2, 0xab, 0x56, 0x90, 0x8a, +0xc7, 0xe0, 0x25, 0x62, 0xb8, 0xa6, 0xf8, 0x10, +0x3e, 0x19, 0xdb, 0x81, 0xaf, 0x24, 0xc6, 0x5e, +0x9c, 0x94, 0xb0, 0xd2, 0x66, 0xf4, 0x12, 0x39, +0x40, 0x46, 0x29, 0xb4, 0x71, 0x3f, 0xfa, 0xd0, +0x11, 0xcc, 0xcc, 0xcc, 0x60, 0x72, 0x72, 0x12, +0x37, 0xdc, 0x70, 0x03, 0xbc, 0x81, 0xee, 0x55, +0xcb, 0x99, 0x4c, 0x06, 0x3f, 0x7a, 0xdb, 0x35, +0x78, 0xfa, 0x33, 0xdf, 0x0c, 0xa4, 0x22, 0xbd, +0x72, 0xd0, 0xc3, 0xe1, 0xd1, 0xee, 0x6d, 0xc6, +0x84, 0x5f, 0xf9, 0x62, 0x1e, 0x47, 0xbf, 0xf1, +0x08, 0x4e, 0x3c, 0xfd, 0x14, 0xa6, 0xa6, 0xa6, +0x70, 0xf8, 0xf0, 0x61, 0xac, 0xa2, 0x77, 0x15, +0x29, 0xa9, 0x6b, 0x8d, 0xea, 0xdf, 0xb5, 0xf9, +0x3a, 0x3c, 0xe2, 0x61, 0x2a, 0xd7, 0x9b, 0x5d, +0xb1, 0xd9, 0xa8, 0x63, 0x7a, 0x7a, 0xda, 0x8f, +0xb3, 0xfe, 0xc4, 0x37, 0x9f, 0xc6, 0xcf, 0xec, +0xdd, 0xdb, 0x35, 0x9c, 0x3e, 0x27, 0x8e, 0x03, +0x07, 0x0e, 0x60, 0xdb, 0x03, 0x0f, 0x60, 0xac, +0x72, 0xc1, 0xf7, 0x64, 0xd6, 0xca, 0x4f, 0x1d, +0xdc, 0xda, 0xb3, 0x6d, 0xbf, 0x58, 0x2c, 0x62, +0x76, 0x76, 0x16, 0xd3, 0xd3, 0xd3, 0xf0, 0x3c, +0x0f, 0x87, 0x0f, 0x1f, 0xee, 0xd9, 0xd6, 0x4f, +0xa5, 0x52, 0xa9, 0xc0, 0x75, 0x5d, 0x54, 0x6b, +0x4d, 0x34, 0x36, 0x31, 0x69, 0x0c, 0x37, 0x59, +0x6c, 0x96, 0xea, 0x5d, 0x1e, 0x62, 0x63, 0x6e, +0x6f, 0xeb, 0x2b, 0xeb, 0xa6, 0xb0, 0x67, 0xd7, +0x0e, 0xdc, 0x36, 0xfd, 0x84, 0x9a, 0x5f, 0xbf, +0x97, 0xdc, 0xec, 0x54, 0xfa, 0x93, 0x71, 0xac, +0x54, 0xcb, 0xc8, 0xc6, 0x5b, 0x28, 0xf4, 0x04, +0xa1, 0xb3, 0x70, 0x07, 0xcd, 0x42, 0xa5, 0xda, +0x15, 0x3d, 0xe5, 0x38, 0x26, 0x27, 0x27, 0xb1, +0xe7, 0xe9, 0xcf, 0xdb, 0x1d, 0x36, 0x0d, 0xfb, +0xe0, 0xe5, 0xb9, 0x3b, 0xbe, 0xc8, 0x65, 0xcc, +0x8d, 0xe3, 0x1d, 0x23, 0x35, 0x5c, 0x3d, 0x94, +0x0d, 0x30, 0x47, 0xee, 0xac, 0x96, 0x72, 0x12, +0xc8, 0x17, 0x56, 0x42, 0x43, 0xcb, 0x34, 0x55, +0x3b, 0x3d, 0xd7, 0x12, 0xbf, 0x98, 0xea, 0x02, +0x9d, 0x09, 0x10, 0x4c, 0xc9, 0x64, 0xb4, 0x67, +0xdc, 0x6b, 0xbd, 0x54, 0x2a, 0x05, 0xc6, 0x93, +0xcf, 0xe7, 0x7d, 0x1b, 0xfa, 0xf0, 0xc8, 0x56, +0x5f, 0xf3, 0x40, 0x1e, 0xef, 0xc0, 0x5a, 0x5c, +0x3c, 0x57, 0xd1, 0x97, 0xcb, 0x78, 0x4b, 0xe3, +0x0c, 0xf6, 0x9c, 0x7c, 0x14, 0x9f, 0xdf, 0xfb, +0x7a, 0x1c, 0xaf, 0x6e, 0xa2, 0x94, 0xa0, 0x31, +0xea, 0xcb, 0x54, 0x1d, 0xae, 0x95, 0xa5, 0x85, +0x39, 0x7c, 0xec, 0x63, 0x1f, 0xf3, 0x0f, 0x5f, +0x73, 0x73, 0x73, 0x98, 0x99, 0x99, 0xc1, 0x7b, +0xde, 0xf3, 0x1e, 0xc0, 0xe9, 0x7e, 0x23, 0xbf, +0x6a, 0xef, 0x1e, 0x7c, 0x07, 0xee, 0xc3, 0x6c, +0x6d, 0x14, 0xcf, 0x25, 0xdb, 0x4e, 0x41, 0x77, +0xed, 0xe8, 0xef, 0x09, 0xb7, 0x62, 0xb1, 0x88, +0x99, 0x99, 0x19, 0x1c, 0x3d, 0x7a, 0x14, 0xf3, +0xf3, 0xf3, 0x70, 0x5d, 0x17, 0x0f, 0x7e, 0xa5, +0x7d, 0xe8, 0x78, 0xdb, 0xdb, 0xde, 0x06, 0x8c, +0x8e, 0xf7, 0xb4, 0x31, 0x16, 0x2a, 0x6d, 0x87, +0x4b, 0x97, 0x37, 0xe5, 0xf3, 0x98, 0x70, 0x90, +0x49, 0xc4, 0xf0, 0x8b, 0xd7, 0x8f, 0xf5, 0x4c, +0xd7, 0x6a, 0xb1, 0x80, 0xb9, 0xb9, 0x39, 0x00, +0xed, 0x38, 0xeb, 0x4f, 0x5d, 0x74, 0xf1, 0x83, +0x95, 0x46, 0x4f, 0xf8, 0x7a, 0x03, 0x39, 0x1c, +0x38, 0x70, 0x00, 0x77, 0x3c, 0xfd, 0xac, 0x91, +0x99, 0x0f, 0xb8, 0xc9, 0x9e, 0x53, 0xcd, 0x16, +0x2a, 0x55, 0xdc, 0x77, 0xef, 0xbd, 0x38, 0x76, +0xec, 0x98, 0xff, 0xec, 0xd8, 0xb1, 0x63, 0xb8, +0xf1, 0x96, 0xc3, 0xb8, 0xf3, 0xd5, 0xaf, 0xe9, +0x99, 0xf9, 0x6c, 0x96, 0xcd, 0x9c, 0x97, 0x62, +0xb1, 0x88, 0x93, 0xb3, 0xb3, 0x98, 0x99, 0x99, +0xc1, 0xfc, 0xfc, 0x3c, 0x26, 0x27, 0x27, 0x71, +0xe7, 0x9d, 0x77, 0x6e, 0xe8, 0xd0, 0x51, 0xa8, +0x54, 0xb1, 0x9c, 0xcf, 0xe3, 0xe8, 0xd1, 0xa3, +0xc8, 0xe7, 0xf3, 0x98, 0x9a, 0x9a, 0xc2, 0xa1, +0x43, 0x87, 0x7a, 0x5a, 0xff, 0xab, 0xf5, 0x26, +0x26, 0x27, 0x27, 0x31, 0xf4, 0xe8, 0xa3, 0x98, +0x5a, 0x3d, 0xb3, 0x21, 0x67, 0x35, 0xad, 0xd4, +0x53, 0x9b, 0x97, 0xeb, 0x60, 0xb5, 0xde, 0xc4, +0x0b, 0xb3, 0xcf, 0xe1, 0xa9, 0xa7, 0x9e, 0xf2, +0x69, 0x79, 0xf8, 0xf0, 0xe1, 0x9e, 0x69, 0x39, +0x39, 0x39, 0x89, 0xfe, 0x64, 0xbc, 0x6b, 0x87, +0x4d, 0xe0, 0xa5, 0x60, 0xe6, 0x1b, 0x91, 0xb0, +0x2e, 0x91, 0x74, 0xf6, 0xea, 0x5c, 0x0b, 0xaf, +0x1d, 0x71, 0xfc, 0x3c, 0xea, 0xdc, 0xfb, 0x5b, +0x86, 0x85, 0x49, 0xef, 0x73, 0x93, 0x2d, 0x9d, +0x8a, 0x6c, 0x27, 0x25, 0x69, 0x59, 0x96, 0x96, +0x96, 0xfc, 0xd3, 0x38, 0x95, 0x4a, 0x65, 0x9d, +0xb1, 0xc6, 0xfb, 0xfa, 0x71, 0xe1, 0x85, 0x53, +0xaa, 0x06, 0x40, 0x3e, 0x1b, 0x1b, 0x1b, 0xf3, +0x19, 0x74, 0xb9, 0x5c, 0xc6, 0xd8, 0xd8, 0x98, +0x5f, 0x97, 0x1f, 0x0c, 0xa4, 0x23, 0x9c, 0x7c, +0x4f, 0x70, 0x6b, 0xb5, 0x26, 0xae, 0x1e, 0x1f, +0xc1, 0x9e, 0xd5, 0x6f, 0xe2, 0xc1, 0xe6, 0x30, +0xee, 0x4d, 0x4d, 0x6e, 0xce, 0x04, 0xd8, 0x24, +0xf0, 0xcd, 0x98, 0xf3, 0x4b, 0x28, 0xe5, 0xaf, +0xd6, 0x9b, 0xb8, 0xf7, 0xde, 0x7b, 0xfd, 0x79, +0x43, 0xb2, 0x3d, 0x6f, 0x4f, 0xe4, 0xcb, 0xf8, +0xd4, 0x43, 0xd3, 0x78, 0xc7, 0x6b, 0x6e, 0xef, +0x1a, 0x66, 0xcb, 0x49, 0x62, 0x6c, 0x6c, 0x0c, +0x77, 0xcd, 0x7e, 0x13, 0x7f, 0xb9, 0xf5, 0x15, +0x28, 0xc4, 0x92, 0x78, 0xf5, 0xf6, 0xfe, 0x9e, +0x19, 0xc2, 0x83, 0x0f, 0x3e, 0xb8, 0x9e, 0x01, +0xab, 0x09, 0xd4, 0xe2, 0x09, 0x3c, 0x72, 0xb1, +0x85, 0xe4, 0x83, 0x5f, 0xc2, 0x8f, 0xbd, 0xfb, +0x9d, 0x3d, 0xc1, 0xcc, 0xba, 0x29, 0x94, 0x6a, +0x8d, 0xf6, 0x98, 0x49, 0x10, 0x11, 0x34, 0xdd, +0xbb, 0xa6, 0x4d, 0xe8, 0x15, 0x6f, 0x62, 0x8c, +0x95, 0x4a, 0x05, 0xab, 0x5e, 0x3f, 0xbe, 0xd9, +0xc8, 0xe2, 0x13, 0x27, 0xf3, 0x3d, 0xc5, 0x6c, +0xf7, 0x39, 0x71, 0x1c, 0x3e, 0x7c, 0x18, 0xd3, +0x4f, 0xfc, 0x19, 0xb6, 0x57, 0x97, 0xf0, 0x42, +0xaa, 0x33, 0x5a, 0xe3, 0xaa, 0x6c, 0xa2, 0x67, +0xdb, 0xfe, 0x53, 0x8f, 0x3f, 0x86, 0x63, 0xc7, +0x8e, 0x05, 0xd6, 0xc0, 0x72, 0x22, 0x8d, 0x8f, +0x3c, 0x3c, 0x83, 0xeb, 0x0f, 0x1e, 0x40, 0xdf, +0x8e, 0x1d, 0x3d, 0xc1, 0x25, 0x4d, 0x5b, 0xb5, +0xd1, 0x0c, 0x24, 0x8d, 0xe9, 0xb5, 0xac, 0xd6, +0x9b, 0x78, 0xf0, 0xc1, 0x07, 0xf1, 0xe8, 0xa3, +0x8f, 0xfa, 0xf0, 0x97, 0x96, 0x96, 0xe0, 0x79, +0x1e, 0x5e, 0xfb, 0xda, 0xd7, 0xf6, 0x0c, 0xf7, +0x99, 0xa7, 0x9f, 0xc6, 0xa7, 0x3e, 0xfe, 0x31, +0xff, 0xfb, 0xec, 0xec, 0x2c, 0xf2, 0xf9, 0x3c, +0x5e, 0xfd, 0x86, 0xef, 0xe8, 0x69, 0xae, 0x68, +0xff, 0xbb, 0xa9, 0x78, 0xa2, 0xe3, 0x86, 0xb3, +0xcd, 0xb0, 0xd3, 0xf3, 0xa4, 0x31, 0xbd, 0x96, +0x62, 0xb1, 0x88, 0xe9, 0xe9, 0x69, 0x3c, 0xf0, +0xc0, 0x03, 0xfe, 0x9e, 0x3d, 0x3b, 0x3b, 0x8b, +0x72, 0xb9, 0xdc, 0xf3, 0xb8, 0xcb, 0x6b, 0x9a, +0xd4, 0xbd, 0xe5, 0xb3, 0x40, 0x66, 0xff, 0xfa, +0x6f, 0x2a, 0xc2, 0x1e, 0xb6, 0x39, 0x3b, 0x5a, +0x37, 0xe1, 0x44, 0x5a, 0x3d, 0x7a, 0xdf, 0xed, +0x26, 0xcb, 0xeb, 0x47, 0xd9, 0xb0, 0x45, 0xfd, +0x4c, 0x2a, 0x89, 0x9f, 0xec, 0x5b, 0xc0, 0x5b, +0xb7, 0xf4, 0x03, 0xf0, 0xd0, 0xac, 0x56, 0x3a, +0x24, 0x72, 0x2a, 0x61, 0x2a, 0x71, 0xfa, 0xaf, +0xd9, 0xd6, 0xa5, 0x03, 0x1b, 0xa9, 0xbe, 0x25, +0x3c, 0xde, 0x8e, 0x16, 0x07, 0x31, 0x72, 0x82, +0xdb, 0x5c, 0x5d, 0x31, 0x1e, 0x04, 0x80, 0xf5, +0x38, 0xf2, 0xf9, 0xf9, 0x79, 0x94, 0x4a, 0x25, +0xa4, 0xd3, 0x69, 0xa4, 0xd3, 0xe9, 0xc0, 0x41, +0x82, 0x17, 0x29, 0xc5, 0xcb, 0x77, 0x02, 0x4b, +0x94, 0x1b, 0x09, 0x54, 0xf2, 0x79, 0xbc, 0x16, +0xcb, 0x78, 0xa5, 0xb7, 0x8a, 0xbf, 0x6e, 0xee, +0xc0, 0xe3, 0x60, 0x19, 0x97, 0xa2, 0xce, 0xa1, +0x9c, 0x73, 0xfa, 0x2f, 0xe7, 0x53, 0xae, 0x8b, +0x28, 0x6b, 0x45, 0xbe, 0xd3, 0x60, 0x6e, 0x42, +0x59, 0xad, 0x37, 0xb1, 0xb4, 0x30, 0x87, 0xf9, +0x73, 0xe7, 0xdb, 0x0f, 0x92, 0x2e, 0xce, 0x27, +0xd2, 0xf8, 0xdc, 0xc0, 0x41, 0xcc, 0xbb, 0xc3, +0xf8, 0xfc, 0x62, 0x3f, 0xee, 0xaa, 0x36, 0xba, +0xb6, 0x73, 0xc7, 0x13, 0x0e, 0x26, 0x27, 0x27, +0x71, 0xe2, 0xc4, 0x09, 0x3f, 0xb7, 0xf8, 0x64, +0x7f, 0x6f, 0xaa, 0x50, 0xb2, 0x37, 0x13, 0x7e, +0x27, 0x93, 0xc3, 0x78, 0x20, 0xb3, 0x17, 0x67, +0xd2, 0xdb, 0xf0, 0xe1, 0x4a, 0x0c, 0xaf, 0x58, +0x2a, 0xe3, 0xe0, 0x50, 0xf7, 0x92, 0x4a, 0xa1, +0x52, 0x45, 0xac, 0x51, 0x83, 0xeb, 0xba, 0x48, +0x34, 0xea, 0xea, 0x7c, 0xfc, 0xcc, 0xd5, 0x5b, +0xbb, 0x86, 0x4b, 0x85, 0x34, 0x0a, 0xc4, 0x1c, +0xbf, 0xe9, 0xb5, 0x37, 0xf4, 0x8f, 0xcf, 0xe6, +0xfd, 0x90, 0xc0, 0x6e, 0xcb, 0xe0, 0xc8, 0x56, +0xec, 0xba, 0x62, 0x1f, 0x6e, 0x3d, 0x73, 0x02, +0x1f, 0x49, 0x0d, 0x75, 0xe0, 0x7c, 0x28, 0xd3, +0x9b, 0xf9, 0x88, 0x6c, 0xfb, 0xf4, 0x9b, 0x2d, +0x20, 0x81, 0x2f, 0x0c, 0x1c, 0x68, 0xab, 0x88, +0x9b, 0x31, 0xf4, 0x3d, 0x57, 0xc5, 0xef, 0xf5, +0xc6, 0xcb, 0xfd, 0x92, 0x4a, 0xc4, 0xd1, 0x4a, +0xb4, 0x19, 0x5a, 0xb3, 0xd9, 0x7b, 0x6e, 0xf1, +0x56, 0xa5, 0xb4, 0x4e, 0x57, 0x00, 0xab, 0x5e, +0x3f, 0x56, 0x01, 0x7c, 0xe4, 0xf8, 0x39, 0x1c, +0x3e, 0x5c, 0xec, 0x49, 0xa2, 0x2c, 0x54, 0xaa, +0x78, 0xe4, 0x6b, 0x0f, 0x01, 0x58, 0x3f, 0x2c, +0xd6, 0xbc, 0x7e, 0xdc, 0xf7, 0xec, 0x02, 0xee, +0xac, 0x94, 0x7a, 0x92, 0xce, 0x09, 0xbf, 0x2d, +0x8d, 0xb5, 0xb5, 0x4b, 0x73, 0xd5, 0x6a, 0x6e, +0x48, 0xcd, 0x4e, 0x25, 0x1b, 0x6f, 0xa1, 0xb0, +0xc1, 0xc8, 0xa8, 0x96, 0x93, 0xc4, 0xf4, 0xf4, +0x34, 0x80, 0xb5, 0xdc, 0xf0, 0x4d, 0xa0, 0xe6, +0xf6, 0xe1, 0xcb, 0x73, 0x2b, 0xb8, 0xa5, 0x5c, +0x46, 0x5f, 0xb6, 0xfb, 0xfc, 0x02, 0xae, 0xeb, +0x22, 0xe6, 0xa4, 0x30, 0x58, 0x2d, 0x61, 0x6b, +0xa3, 0x88, 0x73, 0x89, 0xb5, 0xbd, 0xd5, 0xa6, +0xa9, 0x5c, 0xa3, 0x8d, 0x63, 0xdc, 0x54, 0x4d, +0x9b, 0xa6, 0xf6, 0xdc, 0xb4, 0xd1, 0xda, 0x36, +0x4f, 0xad, 0xbd, 0x89, 0x19, 0x9b, 0x36, 0x76, +0x6d, 0xc3, 0x96, 0x6d, 0x4d, 0x04, 0x48, 0x38, +0xb8, 0x3e, 0x5d, 0xc7, 0x3b, 0xae, 0xdc, 0xaa, +0x26, 0x66, 0x01, 0xf4, 0xf0, 0x31, 0xfa, 0x6c, +0x7a, 0x6f, 0x7a, 0x47, 0x2a, 0x58, 0x6e, 0xd3, +0x06, 0x82, 0x52, 0x32, 0x79, 0xa9, 0xf3, 0x92, +0xcb, 0xe5, 0x02, 0xce, 0x6b, 0xd2, 0x43, 0x9d, +0x7f, 0x26, 0x66, 0xed, 0xba, 0x2e, 0x3c, 0xcf, +0xc3, 0xc2, 0xc2, 0x42, 0x80, 0x51, 0xbb, 0xae, +0x8b, 0xa1, 0xa1, 0xb6, 0x44, 0x42, 0x52, 0x3a, +0x1f, 0xab, 0x1c, 0x07, 0x6f, 0xab, 0x1d, 0x06, +0x92, 0xf9, 0x05, 0xfc, 0xb8, 0xb7, 0x8c, 0xaf, +0xc4, 0xb7, 0xe1, 0xb3, 0xee, 0x5e, 0x9c, 0xaf, +0x36, 0xc2, 0xe7, 0xba, 0xdb, 0xb9, 0x37, 0xcd, +0xb3, 0xe9, 0x10, 0x47, 0xef, 0x4c, 0xeb, 0xb4, +0xd7, 0x83, 0xa3, 0x52, 0xfa, 0x9c, 0x38, 0x8e, +0xcc, 0xcc, 0xa0, 0x55, 0xaf, 0xfa, 0xd2, 0xe3, +0x87, 0x87, 0x6f, 0xc6, 0x05, 0x27, 0x03, 0x34, +0xea, 0x78, 0x66, 0xb9, 0x8c, 0x47, 0xce, 0xad, +0x76, 0x2d, 0x9d, 0xf6, 0x39, 0x71, 0x4c, 0x4e, +0x4e, 0xa2, 0xd2, 0x04, 0xa6, 0x4a, 0x73, 0x38, +0x35, 0xb8, 0x1b, 0x7b, 0x07, 0xdc, 0xc8, 0xed, +0x79, 0xa1, 0x39, 0xab, 0x34, 0x81, 0x93, 0xc9, +0x61, 0x7c, 0x6c, 0xcb, 0xcb, 0x7c, 0x29, 0xa7, +0x58, 0xad, 0xe1, 0xc8, 0x42, 0x01, 0x93, 0xfd, +0xdd, 0x27, 0x20, 0x21, 0xbb, 0x60, 0xa5, 0x52, +0x41, 0xa3, 0xbf, 0xf3, 0x37, 0xbe, 0xa3, 0x2f, +0x89, 0xb7, 0x4e, 0xf6, 0x16, 0x8e, 0x46, 0x70, +0x81, 0xb6, 0xda, 0xb1, 0xdc, 0x68, 0x21, 0x39, +0x78, 0x25, 0xae, 0x75, 0xd2, 0x58, 0xad, 0x37, +0x31, 0x5f, 0xaa, 0x63, 0x6f, 0x0f, 0x87, 0x9b, +0xac, 0x9b, 0xc2, 0x2b, 0x5e, 0x7e, 0x13, 0x9e, +0x3b, 0xf1, 0x77, 0xeb, 0x36, 0x49, 0xb6, 0x0e, +0x0e, 0x6c, 0xef, 0xed, 0xf0, 0xd1, 0x6c, 0xd4, +0x7d, 0xe7, 0xd3, 0x4a, 0x13, 0xb8, 0x7f, 0x60, +0x3f, 0x1e, 0x4e, 0x6d, 0x07, 0x62, 0x0e, 0x90, +0x00, 0xa6, 0xcf, 0x97, 0x7a, 0x66, 0x40, 0xfe, +0x05, 0x22, 0x9b, 0x74, 0xd1, 0x0a, 0x1d, 0xee, +0xe8, 0xd0, 0xf1, 0xd5, 0xfe, 0xab, 0xf0, 0x4c, +0x72, 0x0b, 0x2a, 0xc9, 0x2c, 0x7e, 0x05, 0x29, +0xf4, 0xa2, 0x1c, 0x8e, 0xd5, 0x6b, 0x81, 0xbd, +0xe1, 0xf1, 0xf4, 0x4e, 0x1c, 0xed, 0x9b, 0xc4, +0x05, 0x27, 0x83, 0xb7, 0xe5, 0x9b, 0x38, 0xec, +0xf6, 0xce, 0x7c, 0x6b, 0xf1, 0x04, 0x06, 0x6a, +0x05, 0x14, 0x98, 0x26, 0x65, 0xc3, 0xe1, 0x60, +0x8d, 0xcd, 0x49, 0xa3, 0xbc, 0xbc, 0x78, 0xce, +0xd7, 0xc8, 0xd5, 0xdc, 0x3e, 0x3c, 0x9c, 0xd9, +0x8d, 0xe9, 0xbe, 0xdd, 0xa8, 0xc4, 0xb3, 0xf8, +0xde, 0x32, 0xd0, 0xe7, 0xf5, 0x36, 0xee, 0x56, +0xbd, 0x8d, 0xdf, 0xb6, 0xe6, 0x2a, 0xce, 0x61, +0x30, 0x9c, 0x27, 0xaf, 0x7d, 0x76, 0xd4, 0x8d, +0x8e, 0x55, 0xb0, 0x6e, 0xc2, 0x1a, 0xd0, 0xa8, +0x52, 0xb8, 0x6d, 0x43, 0x0d, 0xdb, 0xcc, 0xc3, +0x36, 0xe4, 0xb0, 0x43, 0x01, 0xd6, 0x92, 0xc2, +0x0c, 0x37, 0x51, 0x2e, 0x57, 0xad, 0x92, 0x2e, +0x60, 0x4f, 0xc1, 0x2a, 0xd5, 0xe6, 0x92, 0xe1, +0x95, 0xcb, 0xe5, 0x60, 0x92, 0x7f, 0x74, 0x32, +0x74, 0x60, 0x3d, 0x2d, 0x2b, 0xbf, 0xfd, 0x87, +0x3c, 0xd7, 0x4d, 0x0e, 0x73, 0xd2, 0xbe, 0x4f, +0x99, 0xde, 0xb8, 0xaa, 0x7c, 0x7e, 0x7e, 0x1e, +0xb9, 0x5c, 0xce, 0xf7, 0x5c, 0x37, 0x25, 0x95, +0xe1, 0xf8, 0x4a, 0x67, 0x39, 0x2a, 0x9c, 0xb9, +0x73, 0x5c, 0x6e, 0x6f, 0x9e, 0xc5, 0x2b, 0xe3, +0x65, 0xfc, 0xa9, 0x3b, 0x89, 0x87, 0x69, 0x68, +0x3c, 0x86, 0x3b, 0xaa, 0xfd, 0xbb, 0x1b, 0xc9, +0x59, 0xab, 0x6b, 0x5a, 0xbf, 0x36, 0xc6, 0xbe, +0x81, 0xb2, 0x5a, 0x6f, 0xa2, 0x42, 0x57, 0xdc, +0xae, 0x49, 0x8f, 0x17, 0x48, 0x0a, 0x59, 0xeb, +0xa7, 0x50, 0xeb, 0x4d, 0x8a, 0x4a, 0xa7, 0xd3, +0x70, 0xe3, 0xc0, 0x78, 0x6d, 0x19, 0x57, 0x65, +0x13, 0x3d, 0x3b, 0x65, 0x71, 0x73, 0xcd, 0x4c, +0x7a, 0x2c, 0xe8, 0x4c, 0x94, 0x70, 0x30, 0x7d, +0xbe, 0x84, 0x77, 0xed, 0xdb, 0x00, 0x11, 0xd6, +0x54, 0xca, 0xf2, 0xb7, 0xf8, 0x83, 0x57, 0x0e, +0xfb, 0x69, 0x3d, 0x7b, 0x29, 0xde, 0x40, 0x0e, +0xef, 0x7c, 0xe7, 0xba, 0x09, 0xe0, 0x1d, 0x89, +0x76, 0x3f, 0xd5, 0x46, 0x0b, 0x99, 0x64, 0xbc, +0x67, 0xe6, 0x78, 0xf0, 0xaa, 0x7d, 0xd8, 0x35, +0x34, 0x80, 0xc9, 0xe2, 0x0b, 0x98, 0x1b, 0xb8, +0x2a, 0x80, 0xf3, 0x15, 0x03, 0xbd, 0x39, 0xea, +0x71, 0x66, 0xb6, 0x9a, 0x48, 0x61, 0xa6, 0x6f, +0x47, 0x9b, 0x91, 0xaf, 0x95, 0xd9, 0x62, 0x03, +0xcd, 0x46, 0xdd, 0x9a, 0x51, 0xd0, 0x54, 0xaa, +0xcd, 0x75, 0xa9, 0x8f, 0x4a, 0x3c, 0xde, 0x3b, +0x47, 0x27, 0xb3, 0x5b, 0xa5, 0x09, 0x9c, 0xf2, +0xb6, 0xe0, 0xa1, 0xd4, 0x76, 0x00, 0x40, 0xff, +0x06, 0x60, 0xd2, 0x01, 0xa1, 0xd2, 0x6c, 0x9b, +0x16, 0xbe, 0xd8, 0x7f, 0x95, 0xbf, 0xce, 0x7a, +0x59, 0xff, 0xab, 0xf5, 0xa6, 0xbf, 0x0f, 0x26, +0x93, 0x2e, 0x6a, 0x9b, 0x10, 0x74, 0xc5, 0xe7, +0x75, 0x35, 0x91, 0x5a, 0x53, 0xb3, 0x6f, 0xec, +0x30, 0xcf, 0x35, 0x5e, 0xe7, 0x12, 0xfd, 0xb8, +0x3f, 0x73, 0x65, 0xfb, 0x7b, 0xa3, 0x85, 0xd3, +0x85, 0x6a, 0x4f, 0x99, 0xff, 0x2a, 0x95, 0x0a, +0x62, 0x4e, 0x0a, 0x6e, 0xbd, 0x8a, 0x74, 0xa3, +0x62, 0xe7, 0xb9, 0x7c, 0x5f, 0x83, 0x54, 0xb3, +0x87, 0x49, 0x2c, 0x61, 0xcc, 0xda, 0xa6, 0xda, +0xd6, 0x36, 0x5f, 0xdb, 0x46, 0xab, 0x15, 0x09, +0xc3, 0x26, 0x9d, 0x99, 0xfa, 0x5b, 0x2b, 0xef, +0xde, 0xda, 0xc4, 0xf5, 0x6e, 0x05, 0x40, 0xa2, +0x83, 0xb1, 0x55, 0xeb, 0x0d, 0xa4, 0x9c, 0x44, +0x87, 0x34, 0x2c, 0x99, 0xa0, 0xb4, 0x35, 0xd3, +0xa2, 0x4e, 0xa7, 0xd3, 0xfe, 0x4d, 0x65, 0x3c, +0xc5, 0x2b, 0xd5, 0xa3, 0x49, 0xa3, 0xff, 0xb9, +0x5c, 0xae, 0xc3, 0x4e, 0x6e, 0xbb, 0x51, 0xcd, +0xa4, 0xf2, 0x97, 0xff, 0x79, 0x42, 0x1b, 0x99, +0x40, 0x86, 0x87, 0xa6, 0x69, 0xf9, 0xdc, 0x35, +0x66, 0xaf, 0x49, 0xe7, 0xad, 0x44, 0x12, 0xb1, +0x46, 0x0d, 0xf5, 0x72, 0x09, 0x3f, 0x9e, 0x7c, +0x1a, 0x2f, 0x1b, 0xd8, 0x8d, 0xcf, 0xd7, 0x72, +0x38, 0x5e, 0x45, 0xf8, 0x5a, 0xd0, 0xd6, 0x97, +0xa9, 0x5e, 0x94, 0xcf, 0xdd, 0x30, 0x76, 0xdb, +0x3a, 0xeb, 0xa2, 0xb4, 0xaa, 0x15, 0xff, 0x64, +0xfe, 0x98, 0xb7, 0xbd, 0x73, 0xbc, 0xe8, 0x4d, +0x92, 0xf0, 0x06, 0x72, 0x48, 0xa7, 0xd3, 0xe8, +0x2b, 0x55, 0x51, 0xca, 0x2f, 0x75, 0xdd, 0x9e, +0x4a, 0xb5, 0x09, 0x5f, 0xb2, 0x7b, 0x21, 0x29, +0x2e, 0xa0, 0xb8, 0x44, 0x09, 0x98, 0xfa, 0x93, +0x0e, 0xde, 0xbe, 0x77, 0x68, 0x13, 0xb2, 0x82, +0xad, 0xcb, 0x89, 0xbd, 0xbb, 0x66, 0x05, 0xcb, +0x6a, 0xbd, 0x89, 0x43, 0x87, 0x0e, 0xe1, 0xd4, +0x03, 0x5f, 0xc4, 0x63, 0xfd, 0x7b, 0x36, 0xcd, +0x53, 0xba, 0x5c, 0x6b, 0xa0, 0xd2, 0x04, 0xce, +0x25, 0xb3, 0x6b, 0x31, 0xcc, 0xeb, 0xeb, 0x2c, +0x5f, 0xa9, 0x63, 0xb9, 0x1e, 0x43, 0xb6, 0x07, +0xe5, 0x4a, 0xab, 0xb6, 0x7e, 0xf0, 0x4f, 0x35, +0xda, 0x9f, 0x7b, 0x55, 0xb3, 0xaf, 0xd6, 0x9b, +0x98, 0x9f, 0x9f, 0xf7, 0xd7, 0xc3, 0xb7, 0xd2, +0x6b, 0xba, 0xff, 0x84, 0xb3, 0x21, 0xd5, 0x7d, +0x3e, 0x9f, 0xf7, 0x0f, 0x1b, 0xb3, 0xa9, 0xe1, +0x75, 0x9a, 0xf6, 0xb8, 0xfe, 0xa9, 0xbe, 0x3c, +0xc4, 0x10, 0xbc, 0x5e, 0xe6, 0x88, 0x22, 0x4e, +0x2a, 0x95, 0x0a, 0x6a, 0x5e, 0x7a, 0xc3, 0xde, +0xec, 0x81, 0xd0, 0xc3, 0x5a, 0x05, 0x4f, 0xe6, +0x76, 0xfa, 0xb4, 0xdc, 0x08, 0x9e, 0x00, 0xe0, +0x25, 0x13, 0x38, 0x5b, 0x6a, 0x22, 0x11, 0x8f, +0x47, 0xd3, 0x58, 0xae, 0xfd, 0x8f, 0x73, 0x22, +0x05, 0x2a, 0xf0, 0xe7, 0x61, 0xef, 0xb5, 0x77, +0xfc, 0x99, 0xa6, 0x66, 0x95, 0xc8, 0x99, 0x24, +0x74, 0xfe, 0xdf, 0x76, 0xc8, 0xd0, 0xf0, 0x34, +0x6c, 0x56, 0xd7, 0xb8, 0x55, 0xbc, 0x26, 0x53, +0x46, 0x96, 0xdd, 0x94, 0xc3, 0x99, 0x17, 0xdd, +0x76, 0x26, 0x13, 0xc3, 0x98, 0xae, 0x20, 0xa5, +0xd0, 0x2e, 0xcf, 0xf3, 0x7c, 0x0f, 0x74, 0x92, +0xc8, 0x35, 0x49, 0x5d, 0xcb, 0x16, 0x07, 0x98, +0x25, 0x71, 0xc9, 0x60, 0x6d, 0x59, 0xe4, 0x28, +0x46, 0x9c, 0x9e, 0xcd, 0xcf, 0xcf, 0x1b, 0xb3, +0xd3, 0xcd, 0xcf, 0xcf, 0xe3, 0xd8, 0xb1, 0x63, +0x81, 0xf7, 0x54, 0x9f, 0x0a, 0x97, 0xe6, 0xc9, +0x03, 0x9e, 0x33, 0xfd, 0x74, 0x32, 0xd1, 0x1e, +0x77, 0x32, 0x81, 0x5c, 0x2e, 0x87, 0xb7, 0x8f, +0xc6, 0xf1, 0x1b, 0xa3, 0x17, 0xf1, 0xa3, 0x5b, +0x2a, 0xfa, 0xfa, 0x30, 0x1d, 0xbc, 0xf8, 0xe7, +0x30, 0x33, 0x8a, 0xed, 0x10, 0x17, 0x36, 0xff, +0x9b, 0x20, 0x91, 0xcb, 0xe2, 0xba, 0x2e, 0x6a, +0xb1, 0x04, 0x4a, 0x49, 0x76, 0x12, 0x67, 0xb8, +0xf5, 0x1a, 0x73, 0xec, 0x79, 0x1e, 0x92, 0xcd, +0x06, 0xbc, 0x5a, 0x11, 0x4b, 0x95, 0xde, 0x37, +0x5b, 0x3a, 0x24, 0x76, 0x48, 0x38, 0x1b, 0x38, +0xcc, 0xac, 0xd6, 0x9b, 0x41, 0x8d, 0x16, 0xa3, +0xeb, 0x1b, 0x76, 0x64, 0x5f, 0xb4, 0xdb, 0xd1, +0xba, 0x2d, 0x7d, 0x4e, 0x1c, 0x87, 0x0e, 0x1d, +0xc2, 0xd6, 0x74, 0x0a, 0x13, 0x95, 0xc5, 0xe0, +0xcb, 0x56, 0x6f, 0xf3, 0xc4, 0x35, 0x6d, 0x79, +0x27, 0xdd, 0xb1, 0xd7, 0x25, 0x9c, 0xde, 0xe8, +0x2c, 0xd7, 0x4d, 0x33, 0xd5, 0x5b, 0x8e, 0x77, +0x3e, 0x76, 0x2a, 0xb5, 0x78, 0x02, 0x73, 0x8d, +0x94, 0x3f, 0x6f, 0xbd, 0xe2, 0x08, 0x00, 0xb1, +0xa4, 0xdb, 0xbe, 0x73, 0x1d, 0xc0, 0x09, 0x6f, +0x9b, 0x3f, 0xee, 0x8d, 0xac, 0x2f, 0x4d, 0x7b, +0x89, 0x84, 0x03, 0xc4, 0x36, 0x96, 0xa8, 0xc6, +0x75, 0xdd, 0x4d, 0xbb, 0xcf, 0xdc, 0xc7, 0x31, +0xe9, 0xe2, 0x54, 0xa2, 0xbf, 0x63, 0xdf, 0xea, +0xd5, 0xac, 0x02, 0x00, 0xa9, 0xe6, 0x5a, 0x3e, +0x04, 0x8d, 0x57, 0x1a, 0xf6, 0xaf, 0x38, 0xef, +0x5c, 0x25, 0x1e, 0xfd, 0xef, 0x76, 0x63, 0xb4, +0xa5, 0x6d, 0xb5, 0xc1, 0xd5, 0xda, 0x99, 0x0e, +0x10, 0xe4, 0x78, 0x63, 0xc2, 0x47, 0x69, 0x97, +0x49, 0xc4, 0xf0, 0x03, 0xa3, 0x31, 0xec, 0xea, +0x6f, 0x13, 0x2d, 0x4c, 0xc5, 0x6e, 0x4b, 0x0a, +0x43, 0x6a, 0x16, 0x2e, 0x7d, 0x93, 0x94, 0xbd, +0xb4, 0xb4, 0x84, 0x85, 0x85, 0x05, 0xbf, 0xbe, +0xe9, 0xe2, 0x14, 0x99, 0x7e, 0xd5, 0x74, 0x70, +0x90, 0xfd, 0x9b, 0xf0, 0x92, 0x59, 0xe3, 0xa4, +0x97, 0x7b, 0x3e, 0x9f, 0xc7, 0xec, 0x5a, 0x58, +0xca, 0xec, 0xec, 0xac, 0xef, 0x8c, 0x47, 0x99, +0xe3, 0x34, 0x9f, 0x01, 0x09, 0x8f, 0x8a, 0xe6, +0x15, 0x9f, 0xcf, 0xe7, 0xd1, 0xdf, 0x28, 0xe3, +0xbb, 0x87, 0x6b, 0xf8, 0xd0, 0x55, 0x35, 0xec, +0x4b, 0x89, 0x1f, 0x8e, 0xe9, 0xe0, 0x45, 0xcf, +0x6c, 0x87, 0x49, 0xdb, 0x7c, 0x77, 0x93, 0xfa, +0x35, 0xac, 0x5d, 0xc4, 0x62, 0xfc, 0xb1, 0x8a, +0x71, 0xf4, 0x64, 0x37, 0xab, 0x94, 0x90, 0x5f, +0x29, 0x02, 0xb5, 0x0a, 0xfa, 0xcb, 0x17, 0xb1, +0x50, 0xea, 0x2d, 0xfb, 0xd9, 0x60, 0x46, 0xc9, +0x99, 0xce, 0xc6, 0xdc, 0xed, 0xcd, 0x5b, 0x1c, +0x3f, 0x00, 0xfe, 0x26, 0x0e, 0xc0, 0x0f, 0x47, +0xfb, 0xa1, 0xfd, 0x23, 0x3d, 0xc1, 0x7c, 0xb1, +0x4a, 0x26, 0x93, 0xc1, 0xd4, 0xd4, 0x14, 0xee, +0xb8, 0x38, 0x13, 0x48, 0x22, 0x73, 0xae, 0xdc, +0xdb, 0x5a, 0x70, 0x5d, 0x17, 0x5e, 0x32, 0x01, +0xd4, 0x2a, 0x38, 0xe7, 0x0e, 0xf9, 0xb4, 0xa0, +0xff, 0xfd, 0x09, 0x20, 0xd5, 0x43, 0x6a, 0x64, +0xf2, 0xea, 0x26, 0xe9, 0xb4, 0xde, 0x68, 0x6c, +0xca, 0xe1, 0x80, 0x0e, 0x9f, 0xd5, 0xbe, 0x01, +0x1f, 0xc7, 0x56, 0xb3, 0xf7, 0xdc, 0x11, 0xad, +0xda, 0xba, 0x56, 0x71, 0x89, 0xae, 0x85, 0x66, +0xeb, 0xbf, 0x97, 0xc3, 0x2c, 0x37, 0x37, 0x06, +0x72, 0xd2, 0xb7, 0x9a, 0x3d, 0xc1, 0xa3, 0xdf, +0x60, 0xa5, 0x52, 0x41, 0xb2, 0xb5, 0x71, 0x66, +0xee, 0xcf, 0xcd, 0x1a, 0x8e, 0x9a, 0x29, 0xa0, +0x17, 0x3c, 0xfd, 0xe8, 0x85, 0xb5, 0x44, 0x60, +0x91, 0xfc, 0xc3, 0xd6, 0xfe, 0xeb, 0xbb, 0x4c, +0xb7, 0x1b, 0xa3, 0xd6, 0x26, 0x4c, 0xfa, 0x32, +0xc1, 0xd5, 0x36, 0x5a, 0x53, 0x7d, 0x6e, 0x7b, +0x37, 0xb5, 0x17, 0x52, 0xfd, 0x7e, 0xb7, 0x81, +0xc9, 0x64, 0x1d, 0x68, 0xae, 0xdd, 0x7d, 0x6b, +0xb0, 0x87, 0xdb, 0x18, 0x2b, 0x31, 0xb8, 0xe5, +0xe5, 0x65, 0x5f, 0x92, 0x25, 0x69, 0x7c, 0x6e, +0x6e, 0xce, 0x7f, 0x67, 0x52, 0x7f, 0x4b, 0x38, +0x3c, 0xfb, 0x9b, 0x96, 0x05, 0x8e, 0x17, 0x13, +0x13, 0x97, 0x0c, 0x5e, 0x7a, 0xa8, 0x73, 0xb3, +0x00, 0x49, 0xef, 0x14, 0x5b, 0x3e, 0x3b, 0x3b, +0xeb, 0xc7, 0xa2, 0x53, 0x3b, 0x4d, 0x2b, 0xc1, +0x0f, 0x2d, 0xa6, 0x43, 0x50, 0xb5, 0xd9, 0x42, +0xb9, 0x5c, 0x46, 0xe1, 0xfc, 0x39, 0xec, 0x70, +0x81, 0xbf, 0xb8, 0xce, 0xc5, 0x8f, 0x8d, 0x29, +0x1b, 0x85, 0x4d, 0x05, 0xcf, 0xbf, 0xcb, 0x36, +0xa6, 0x03, 0x9b, 0x4d, 0x63, 0xa4, 0xf5, 0xb7, +0x09, 0xaa, 0x76, 0x29, 0x9d, 0xfa, 0x29, 0x22, +0x19, 0xcc, 0x6c, 0x97, 0xf7, 0x24, 0x53, 0xa9, +0x54, 0x2a, 0x68, 0xd5, 0xab, 0x70, 0x5d, 0x17, +0x5b, 0x2a, 0x79, 0x1c, 0xcb, 0xf7, 0x76, 0x3d, +0xed, 0xe0, 0xc8, 0x56, 0x8c, 0x8f, 0x8f, 0xab, +0x63, 0xbf, 0x76, 0x38, 0x8d, 0x77, 0xed, 0x1b, +0xee, 0xcd, 0x4e, 0xec, 0xa6, 0xdb, 0x6b, 0x21, +0x19, 0xd4, 0x1d, 0xdf, 0x30, 0xd2, 0x87, 0x57, +0x6f, 0x7f, 0xf1, 0xae, 0x39, 0xed, 0xb5, 0xdc, +0x78, 0xcb, 0x61, 0x6c, 0x6f, 0x95, 0x30, 0x58, +0x5e, 0x37, 0x61, 0x4c, 0x9f, 0xef, 0x2d, 0x8d, +0x26, 0x00, 0xb8, 0x99, 0xfe, 0xa0, 0xff, 0x00, +0x5b, 0xc7, 0xc3, 0x9e, 0xd3, 0xb3, 0xff, 0x40, +0xb5, 0x09, 0x3f, 0x96, 0x3f, 0x89, 0xe6, 0x86, +0x19, 0x2f, 0x95, 0xcd, 0x60, 0x68, 0xfe, 0xd8, +0x5d, 0xf2, 0x67, 0x60, 0xcc, 0x8b, 0xc6, 0xdf, +0xa3, 0x24, 0x4d, 0xbe, 0x02, 0x00, 0xda, 0x21, +0x79, 0x0c, 0xde, 0x46, 0x4b, 0x2d, 0x96, 0xd8, +0xb4, 0x74, 0xae, 0xdc, 0x34, 0x2a, 0x4b, 0xaf, +0xbf, 0x81, 0x72, 0xad, 0x81, 0x54, 0x22, 0x8e, +0xc6, 0x1a, 0x8f, 0xea, 0x10, 0x62, 0x78, 0x61, +0xfb, 0x58, 0xdc, 0xc8, 0x30, 0xa3, 0x32, 0x54, +0x7a, 0xa7, 0x31, 0x75, 0xd3, 0xc6, 0x6c, 0x93, +0xf4, 0x4d, 0xff, 0xa3, 0x48, 0x60, 0xda, 0x7f, +0xd6, 0xef, 0xbe, 0x54, 0x03, 0x3f, 0x9e, 0xbb, +0x88, 0x2d, 0xad, 0x32, 0x56, 0x0b, 0x2b, 0x00, +0x3a, 0x2f, 0x48, 0x91, 0x92, 0xa9, 0x29, 0x8d, +0x2b, 0x7d, 0xa6, 0x3f, 0x62, 0xec, 0xc4, 0xc4, +0xb5, 0xcb, 0x59, 0x34, 0x58, 0x9c, 0x41, 0x6a, +0x2a, 0x79, 0xde, 0x8f, 0x94, 0x8a, 0x6d, 0x7f, +0xda, 0x4d, 0x6b, 0xd2, 0x31, 0x8e, 0xfa, 0x1b, +0x1c, 0x0c, 0xda, 0x52, 0x4d, 0xb6, 0x79, 0x00, +0x01, 0x35, 0xbe, 0x16, 0xdb, 0xbe, 0x7a, 0x71, +0xd9, 0xef, 0x7b, 0x7e, 0x7e, 0x1e, 0x8d, 0xd5, +0x15, 0xfc, 0xf4, 0x5e, 0x0f, 0xf7, 0xdd, 0x98, +0xc2, 0x8d, 0x7d, 0xcd, 0x48, 0x8b, 0xb2, 0x63, +0x8d, 0x85, 0x85, 0x65, 0x68, 0xb0, 0x4c, 0xeb, +0x65, 0x13, 0x24, 0x72, 0x2a, 0x7d, 0x4e, 0x1c, +0xbb, 0xaf, 0xb8, 0xd2, 0x3f, 0x4d, 0x67, 0xe3, +0xad, 0x00, 0xec, 0x1d, 0x7d, 0x49, 0x5c, 0xdb, +0xa3, 0xe4, 0x7b, 0xe1, 0xc2, 0x05, 0x54, 0x2a, +0x15, 0xac, 0xd4, 0x9a, 0x58, 0x4a, 0xa4, 0x71, +0xdf, 0xa9, 0xe5, 0x9e, 0xd5, 0xf5, 0x87, 0x0e, +0x1d, 0x82, 0x97, 0xf6, 0xda, 0xcc, 0x60, 0x6d, +0x63, 0xc8, 0x24, 0x62, 0x1b, 0x0a, 0x1d, 0x03, +0xc4, 0x81, 0x6e, 0x6d, 0xcc, 0x3f, 0x7e, 0x70, +0x63, 0x30, 0x5f, 0xac, 0x32, 0x3e, 0xb2, 0x05, +0x07, 0x0e, 0x1c, 0xc0, 0x2b, 0xcb, 0xcf, 0xfb, +0x34, 0x79, 0x66, 0xb9, 0xb7, 0x03, 0x53, 0x26, +0x93, 0xc1, 0x96, 0x2d, 0xc3, 0xc1, 0x87, 0x6c, +0x1d, 0x1f, 0xde, 0xb6, 0x31, 0x8b, 0xbf, 0x94, +0xfe, 0x7a, 0xb5, 0x6f, 0x73, 0xe9, 0xb4, 0x16, +0x63, 0x87, 0xcc, 0x0d, 0xfe, 0x16, 0xaa, 0x6b, +0xcb, 0x32, 0x95, 0x88, 0xaf, 0x4b, 0xa8, 0x34, +0xfe, 0x1e, 0x25, 0xe9, 0x54, 0x5c, 0x8c, 0x9b, +0xc1, 0xdb, 0xd0, 0x41, 0x71, 0xed, 0xc0, 0xe5, +0xff, 0x56, 0x37, 0x50, 0x78, 0x6a, 0xed, 0x24, +0x82, 0x07, 0x99, 0x44, 0x3c, 0xd6, 0xb3, 0x46, +0x82, 0x4a, 0x22, 0xce, 0x68, 0x69, 0xd2, 0x58, +0xb2, 0xb9, 0x73, 0x8c, 0x92, 0x4d, 0x14, 0xc9, +0xc5, 0x66, 0xcb, 0x0e, 0x8b, 0xf3, 0xb6, 0xd9, +0xd2, 0x6d, 0xce, 0x51, 0x61, 0x4e, 0x50, 0xca, +0xbb, 0xb1, 0xbe, 0x14, 0xde, 0x92, 0x2d, 0xe1, +0xb5, 0xb9, 0x26, 0x32, 0xa5, 0x12, 0x80, 0xa0, +0x0d, 0x1a, 0xe8, 0xcc, 0xc0, 0xc6, 0xb3, 0xa5, +0xf1, 0xc2, 0x99, 0x21, 0xaf, 0x2f, 0x0b, 0x67, +0xde, 0xdc, 0xd3, 0x5d, 0xde, 0x90, 0x66, 0x73, +0x38, 0x93, 0x45, 0xde, 0xa4, 0x66, 0x52, 0x7b, +0x4b, 0xf8, 0xf2, 0x20, 0xc1, 0xed, 0xdf, 0x00, +0xb0, 0xbc, 0xbc, 0xec, 0xc3, 0x18, 0x1a, 0x1a, +0x0a, 0x84, 0xa5, 0xf1, 0xcf, 0x26, 0x2f, 0x77, +0xd9, 0xa7, 0x96, 0x90, 0x66, 0xd8, 0xf3, 0xf0, +0xe7, 0x87, 0xd2, 0xb8, 0xe7, 0x5c, 0x03, 0xff, +0xe5, 0xf9, 0x26, 0xe6, 0x2b, 0x5d, 0x2c, 0xf4, +0xa8, 0x51, 0x0f, 0xb6, 0xf5, 0x22, 0x9f, 0x73, +0x18, 0x1b, 0x28, 0xe3, 0xe3, 0x63, 0x98, 0x9c, +0x9c, 0xc4, 0x93, 0xf3, 0xe7, 0x3b, 0xfa, 0x78, +0xf5, 0xf6, 0x6c, 0xcf, 0x12, 0xd9, 0xd3, 0x27, +0x66, 0xe1, 0xba, 0x2e, 0x5c, 0x00, 0xc5, 0x64, +0x06, 0x9f, 0x3e, 0xb5, 0x82, 0xa5, 0x1e, 0xb2, +0x9f, 0x65, 0xdd, 0x14, 0x5e, 0xf6, 0xb2, 0x97, +0x61, 0xcf, 0x9e, 0x3d, 0x18, 0x7e, 0xfc, 0x79, +0x7c, 0xbc, 0x90, 0xc1, 0x44, 0xbf, 0x8b, 0xef, +0xdb, 0x3b, 0x84, 0x1b, 0xb7, 0xf6, 0x7e, 0xeb, +0x53, 0x9f, 0x13, 0x0f, 0xae, 0xfb, 0x84, 0x83, +0x2b, 0x07, 0x3d, 0xbc, 0x79, 0xf7, 0xe0, 0x65, +0x2f, 0x95, 0x53, 0xb9, 0xfe, 0xfa, 0xeb, 0xf1, +0xf5, 0x63, 0x7f, 0x87, 0x71, 0x94, 0x31, 0x97, +0xc8, 0xe2, 0x89, 0xa5, 0x32, 0x8a, 0x3d, 0x3a, +0x57, 0x5d, 0x77, 0xf0, 0x00, 0x9e, 0x3c, 0x36, +0x83, 0x2d, 0xb5, 0x15, 0x20, 0x1d, 0x5c, 0x63, +0xdf, 0xb7, 0xb7, 0xb7, 0xeb, 0x84, 0x57, 0xeb, +0x4d, 0xa4, 0xe2, 0x9b, 0xe7, 0xcd, 0xae, 0x5e, +0x36, 0x92, 0xc0, 0x86, 0x1d, 0x41, 0xc9, 0x49, +0xaf, 0xda, 0x68, 0x06, 0x99, 0xda, 0x5a, 0xe9, +0x65, 0x3d, 0xa8, 0x36, 0x73, 0x60, 0xe3, 0x92, +0x79, 0xad, 0x02, 0x24, 0xd6, 0xa2, 0x0a, 0x36, +0xf8, 0xdb, 0x77, 0x5d, 0x77, 0x3d, 0xbe, 0x9c, +0x0e, 0x31, 0x6b, 0x7b, 0x52, 0xa3, 0xd9, 0xea, +0xf9, 0x77, 0x40, 0xa1, 0x69, 0x81, 0x12, 0xc1, +0x51, 0x3c, 0x1e, 0x49, 0x25, 0x69, 0x7b, 0x16, +0x45, 0x7d, 0x69, 0xb2, 0x91, 0x6b, 0xdf, 0x6d, +0x8e, 0x70, 0x26, 0x7c, 0x4c, 0x38, 0x34, 0xea, +0xd8, 0x97, 0x8e, 0xe1, 0xd7, 0xc6, 0x4b, 0x78, +0xc7, 0xe0, 0x2a, 0x06, 0xe3, 0x0d, 0x9f, 0x09, +0xd5, 0x13, 0xeb, 0x97, 0x93, 0x50, 0xd1, 0x6c, +0xc4, 0x40, 0x50, 0xe5, 0x2c, 0xed, 0xc7, 0x52, +0xa2, 0xe7, 0x4c, 0x5e, 0x4b, 0xd1, 0xca, 0xfb, +0xd1, 0xb4, 0x01, 0x9c, 0x59, 0x6a, 0x99, 0xd8, +0xb4, 0x50, 0x31, 0xf9, 0x5c, 0x32, 0x57, 0xde, +0x3e, 0x97, 0xcb, 0x61, 0x62, 0x62, 0x02, 0x93, +0x93, 0x93, 0x18, 0x1c, 0x1c, 0x84, 0xe7, 0x79, +0xfe, 0x7f, 0x8e, 0x8b, 0x29, 0xde, 0x9e, 0xab, +0xea, 0xb9, 0xc3, 0x9d, 0xc4, 0x5b, 0xd2, 0x8c, +0x6e, 0x9e, 0x7b, 0x45, 0xba, 0x8c, 0xdf, 0xdd, +0xdb, 0xc0, 0x5d, 0x5b, 0xe2, 0xed, 0xdb, 0x81, +0x4c, 0x1a, 0xa0, 0x28, 0x36, 0x6e, 0xd3, 0x73, +0xa1, 0xe6, 0x54, 0xff, 0x6f, 0xa2, 0x47, 0xfb, +0x1b, 0xdf, 0xf8, 0x46, 0xec, 0xdd, 0x3a, 0x8c, +0x56, 0x65, 0xd5, 0x87, 0x7f, 0xe5, 0xa0, 0x87, +0x9f, 0xbb, 0x76, 0xb4, 0xe7, 0x1f, 0xf4, 0xdc, +0xf3, 0x27, 0xfd, 0x93, 0xff, 0xa9, 0x44, 0x3f, +0xce, 0x57, 0xea, 0xf8, 0x9b, 0x67, 0x2f, 0xf4, +0x8c, 0x63, 0x2a, 0x93, 0xc5, 0x3f, 0x7f, 0xd9, +0x95, 0xf8, 0xd0, 0xeb, 0xf6, 0xe2, 0x3f, 0xdf, +0x3c, 0x86, 0x1b, 0xb7, 0xf6, 0x6d, 0xf8, 0x56, +0x30, 0xcf, 0xf3, 0x02, 0x36, 0xf3, 0xef, 0x99, +0x1c, 0xec, 0x39, 0x84, 0xee, 0xa5, 0x28, 0xdb, +0x27, 0xf7, 0x62, 0x72, 0xe7, 0x4e, 0xdc, 0x76, +0xf1, 0x69, 0x00, 0xc0, 0x99, 0xd5, 0x1a, 0x9e, +0x59, 0xae, 0x74, 0x0d, 0x87, 0xf2, 0x02, 0x1c, +0xba, 0xfa, 0x00, 0x86, 0xab, 0x2b, 0xfe, 0xf3, +0x6c, 0xab, 0x86, 0x1f, 0x9d, 0x1a, 0xe9, 0x39, +0x0b, 0x1e, 0x97, 0xa4, 0x79, 0xd9, 0xa8, 0x64, +0x4e, 0xd2, 0x5f, 0x36, 0xde, 0xda, 0x54, 0x67, +0x50, 0x5f, 0x32, 0x67, 0x30, 0x7b, 0x91, 0x50, +0x29, 0x34, 0x8d, 0xf0, 0xe4, 0x07, 0x84, 0x44, +0xac, 0xb5, 0xa1, 0x4b, 0x6c, 0x5c, 0xd7, 0xdd, +0x14, 0x13, 0x83, 0xf1, 0x3a, 0xde, 0x0d, 0xfa, +0x0a, 0xa8, 0xc5, 0x16, 0xb1, 0xc3, 0x8a, 0xa3, +0x86, 0x87, 0xc9, 0x0d, 0x4f, 0x3e, 0xa7, 0x77, +0xbc, 0x9e, 0xa9, 0x8d, 0x86, 0x8c, 0x06, 0x8f, +0x23, 0x27, 0xdb, 0x69, 0x61, 0x4a, 0x72, 0x60, +0x0a, 0x9e, 0xd7, 0xf4, 0x35, 0xf1, 0x93, 0xe3, +0x2d, 0xec, 0xf7, 0x1a, 0x58, 0xbd, 0x58, 0x06, +0x50, 0x86, 0xb3, 0xc6, 0x64, 0x16, 0xcf, 0x9c, +0x0a, 0x78, 0xa1, 0x4b, 0xe9, 0xda, 0xe4, 0xe8, +0x65, 0x4a, 0xde, 0x42, 0xff, 0x4d, 0xe1, 0x5d, +0x26, 0xc6, 0x1d, 0x96, 0xeb, 0x5d, 0x5e, 0x82, +0x22, 0x25, 0x60, 0x69, 0x1b, 0xd7, 0x54, 0xf1, +0x54, 0xb8, 0x24, 0x4f, 0xe1, 0x69, 0x1a, 0x6e, +0xa6, 0x76, 0xda, 0x78, 0xf9, 0x7f, 0x8e, 0x93, +0x4c, 0x5d, 0xdb, 0xac, 0xd7, 0x50, 0x05, 0x50, +0xae, 0x56, 0xb1, 0x23, 0x1e, 0xc3, 0xaf, 0x8e, +0x02, 0x8f, 0xf5, 0xc7, 0xf1, 0x6f, 0xce, 0x78, +0x58, 0x29, 0x97, 0xcd, 0x71, 0xe0, 0xdd, 0xc6, +0x8d, 0x9b, 0xc2, 0x11, 0x43, 0x62, 0x34, 0x7b, +0x2d, 0x59, 0x37, 0x05, 0x8c, 0x6c, 0xc5, 0x7b, +0xde, 0xfd, 0x2e, 0x5c, 0xf9, 0xdc, 0x1c, 0x7e, +0xe7, 0x54, 0x0b, 0x37, 0x8e, 0xf4, 0xe1, 0x47, +0x0e, 0x6c, 0xc5, 0x58, 0xba, 0xb7, 0x83, 0xc2, +0x99, 0x33, 0x67, 0xfc, 0x9c, 0xe4, 0x35, 0xb7, +0x0f, 0xcb, 0xb1, 0x36, 0x7d, 0xff, 0xc3, 0xf4, +0x02, 0xde, 0xb4, 0x6b, 0xb0, 0xa7, 0x8c, 0x6d, +0x59, 0x37, 0x05, 0xf8, 0x17, 0x40, 0x6c, 0x3c, +0xaf, 0x7e, 0xb1, 0x58, 0x0c, 0xd8, 0xcc, 0x07, +0xdc, 0x24, 0x7e, 0x64, 0xaa, 0xb7, 0xbc, 0xe6, +0x54, 0xe4, 0x85, 0x15, 0x40, 0x3b, 0x86, 0x3b, +0xe6, 0xb6, 0x4d, 0x15, 0xad, 0x4a, 0x09, 0x2d, +0x27, 0xe9, 0x3f, 0x6b, 0x55, 0x4a, 0x3d, 0x5f, +0xe6, 0x01, 0xb4, 0x99, 0xdb, 0x1d, 0x2f, 0xbf, +0x11, 0xb3, 0x1f, 0xfd, 0x04, 0x86, 0xeb, 0x45, +0x5c, 0x70, 0x32, 0xf8, 0xc3, 0x27, 0xcf, 0xe2, +0xd0, 0x96, 0x89, 0x9e, 0x2e, 0xc8, 0xf9, 0x8e, +0x7f, 0xf6, 0x5d, 0xb8, 0x7e, 0xf6, 0x39, 0x94, +0x4f, 0xb4, 0xdb, 0xfe, 0xd0, 0xfe, 0x91, 0x4d, +0xf3, 0x1f, 0x70, 0x37, 0x41, 0xd9, 0xa1, 0x32, +0x17, 0xfa, 0x0d, 0x24, 0x7b, 0x3f, 0xd4, 0xf2, +0xc4, 0x36, 0x7e, 0x59, 0xfb, 0x5d, 0x35, 0x5a, +0xb1, 0x9e, 0x42, 0xd3, 0x3a, 0x24, 0x73, 0x92, +0x78, 0x7b, 0x80, 0x27, 0xcb, 0x66, 0xd8, 0xcc, +0xd5, 0xeb, 0x78, 0x39, 0x5f, 0xda, 0x80, 0xd7, +0x7d, 0xcc, 0x49, 0x01, 0xd5, 0xea, 0xba, 0xcd, +0xdc, 0xe4, 0x57, 0x26, 0xf6, 0x34, 0xc7, 0xaf, +0x6c, 0x62, 0xe8, 0xbc, 0xd8, 0xc4, 0x7c, 0x1b, +0xa3, 0xb5, 0x6d, 0xcc, 0x1c, 0x41, 0x9b, 0x33, +0x9c, 0xad, 0x6f, 0xd1, 0x7e, 0x34, 0xd9, 0xc2, +0xbf, 0x18, 0x8f, 0xe1, 0x7a, 0xaf, 0xd1, 0xb6, +0x8f, 0x5f, 0x2c, 0x77, 0xa8, 0xb4, 0x39, 0x43, +0x94, 0xcc, 0x88, 0x2e, 0x22, 0xa1, 0x67, 0x5c, +0x3d, 0x0e, 0x74, 0xda, 0x9f, 0x81, 0xb6, 0xc4, +0x4a, 0x59, 0xd5, 0xe8, 0x73, 0x98, 0x5a, 0x5d, +0x63, 0x90, 0x9a, 0x07, 0xba, 0x89, 0xb9, 0x72, +0xc9, 0x9c, 0x8f, 0x85, 0xdb, 0xc0, 0xb5, 0xd4, +0xb1, 0xd2, 0xbe, 0xce, 0xc7, 0xae, 0x1d, 0x1a, +0x24, 0x7c, 0xce, 0xb0, 0x4d, 0xa5, 0x5a, 0x6f, +0x74, 0x1c, 0x82, 0xfa, 0xb2, 0xc9, 0x00, 0xfe, +0xd7, 0xf6, 0x35, 0xf1, 0xe1, 0xc9, 0x3c, 0xfe, +0xec, 0x5c, 0x0a, 0x1f, 0xce, 0xc3, 0xce, 0xa0, +0xa3, 0xae, 0x1f, 0x5b, 0xb6, 0x24, 0x8d, 0xe1, +0x6f, 0x82, 0x64, 0x4e, 0x8c, 0xf2, 0xae, 0x6b, +0xf7, 0xe1, 0xe6, 0xfd, 0x0d, 0xd4, 0x9a, 0x2d, +0x64, 0x36, 0x70, 0xd7, 0xf3, 0xd1, 0xa3, 0x47, +0x01, 0xb4, 0x37, 0xc9, 0xe5, 0x58, 0x0a, 0x31, +0xa7, 0x8d, 0xf7, 0xf9, 0x0a, 0xf0, 0xbe, 0x23, +0xa7, 0xf0, 0x97, 0xaf, 0xdc, 0x81, 0x91, 0x1e, +0x52, 0x45, 0x6e, 0x66, 0xc9, 0x64, 0x32, 0xeb, +0x92, 0xb9, 0x07, 0xbc, 0x75, 0x57, 0x16, 0x63, +0x7d, 0xbd, 0xdf, 0xbe, 0xb5, 0x5a, 0x6f, 0xe2, +0x81, 0xfb, 0x3e, 0x8d, 0xd9, 0xd9, 0x59, 0xff, +0x99, 0x5c, 0x7f, 0x94, 0xd3, 0x80, 0xaf, 0xd9, +0xa9, 0xa9, 0x29, 0xdc, 0xfa, 0xaa, 0x57, 0xf7, +0x4c, 0xeb, 0x89, 0x7d, 0x57, 0x62, 0xd7, 0xd0, +0x00, 0xf6, 0xaf, 0x9e, 0xc1, 0x91, 0x81, 0xab, +0xf0, 0xd1, 0x13, 0x79, 0xbc, 0xf7, 0xe0, 0x36, +0xdc, 0xd6, 0xc3, 0x0d, 0x75, 0x7d, 0x4e, 0x1c, +0xdb, 0x27, 0xf7, 0xe2, 0x7f, 0x4d, 0x06, 0x9f, +0x6d, 0x84, 0x26, 0x7e, 0x5a, 0xe7, 0x26, 0x54, +0x15, 0x76, 0xaf, 0x25, 0xd9, 0x6a, 0x74, 0xc4, +0xc3, 0xf7, 0x5a, 0x78, 0xea, 0x69, 0x72, 0xd2, +0x93, 0xe3, 0xe8, 0x96, 0x0e, 0xdc, 0x76, 0x1c, +0xb0, 0x99, 0xf7, 0x08, 0x8f, 0x0e, 0x87, 0x81, +0x38, 0xf3, 0x58, 0xef, 0xd7, 0x3a, 0xab, 0x69, +0x6f, 0xf9, 0xb8, 0x37, 0x90, 0x76, 0xb6, 0x43, +0xcd, 0x1e, 0xb6, 0x07, 0x06, 0x92, 0xc6, 0x74, +0xe3, 0xdc, 0x16, 0x16, 0xe3, 0x6b, 0x92, 0xb8, +0xbb, 0x91, 0xde, 0x39, 0x9c, 0xa8, 0x36, 0x7b, +0xd6, 0xc7, 0xbf, 0xd8, 0x11, 0xc3, 0x77, 0x6e, +0x8d, 0xfb, 0x4c, 0x9c, 0x8a, 0xc9, 0x99, 0xcd, +0xe6, 0xf0, 0xc5, 0x8b, 0x64, 0xb0, 0xf2, 0x9d, +0xcc, 0xc8, 0x46, 0x7d, 0x68, 0x59, 0xd6, 0xe8, +0xbf, 0x74, 0x5a, 0xd3, 0x9c, 0xca, 0x34, 0x07, +0x35, 0x2a, 0xf4, 0x23, 0xe2, 0xaa, 0x72, 0x8a, +0x75, 0x27, 0x46, 0x4e, 0xd2, 0xbd, 0xd6, 0x9e, +0x4b, 0xf6, 0xa6, 0xf8, 0x72, 0x13, 0x5d, 0x24, +0x9e, 0x3c, 0x54, 0x03, 0xe5, 0x32, 0xe0, 0x24, +0x02, 0xe3, 0x4d, 0x39, 0x09, 0xa4, 0x9c, 0x34, +0xf2, 0xd5, 0xf5, 0x53, 0xf7, 0x40, 0xda, 0xc3, +0xcf, 0xee, 0x06, 0xee, 0xcc, 0x55, 0xf0, 0x5f, +0x96, 0x06, 0xf1, 0xcc, 0x85, 0x82, 0x7d, 0xf1, +0x9a, 0x98, 0xb5, 0xcd, 0xb1, 0x2e, 0xcc, 0x7f, +0x63, 0x13, 0xcb, 0x46, 0x54, 0xd7, 0xab, 0xf5, +0x26, 0x4e, 0x3c, 0x75, 0x2c, 0x70, 0x61, 0xc7, +0x93, 0x99, 0xb5, 0xac, 0x6d, 0x89, 0x36, 0xce, +0x9f, 0x39, 0xb3, 0x82, 0x1f, 0xf8, 0xe2, 0x99, +0x4d, 0x63, 0xe8, 0x24, 0xad, 0xf5, 0x62, 0x27, +0xa6, 0x14, 0xa6, 0x89, 0x46, 0x1d, 0xef, 0xb9, +0x6a, 0x64, 0x43, 0x8c, 0x8b, 0x72, 0x86, 0x53, +0x26, 0xb1, 0x5a, 0x3c, 0x01, 0xe0, 0xe2, 0xda, +0xdb, 0x8b, 0xa2, 0xf6, 0xfa, 0xf7, 0xca, 0xb1, +0x19, 0xdc, 0xfa, 0xaa, 0x57, 0xf7, 0xdc, 0x6f, +0xd6, 0x4d, 0xb5, 0xaf, 0x84, 0x3d, 0xfa, 0x8d, +0x76, 0x12, 0x99, 0x46, 0x12, 0x3f, 0xf7, 0x95, +0x93, 0xf8, 0xcc, 0x77, 0xee, 0xef, 0x69, 0x2e, +0x37, 0xd3, 0x5f, 0x80, 0x87, 0x3f, 0xd5, 0xdc, +0xbe, 0x0d, 0x67, 0x42, 0x0b, 0xc4, 0x99, 0xc7, +0x12, 0x40, 0xbd, 0x06, 0x38, 0x1b, 0xcf, 0xf7, +0xee, 0x33, 0xde, 0xa4, 0x8b, 0x72, 0x5c, 0x1c, +0xe8, 0x7a, 0x8c, 0xdd, 0x07, 0xe0, 0x8f, 0x7b, +0x33, 0xe0, 0xc5, 0xd7, 0x7e, 0xeb, 0x81, 0x38, +0xf3, 0x4d, 0x30, 0x31, 0xd0, 0xef, 0xd4, 0x3f, +0x68, 0xd1, 0xbe, 0xd2, 0xa3, 0x64, 0x4e, 0xfb, +0xa7, 0xaf, 0x89, 0xb1, 0x25, 0xd0, 0x12, 0xfb, +0xa3, 0xd3, 0xb1, 0xa9, 0x45, 0xc9, 0xb2, 0x66, +0x03, 0xac, 0xbd, 0x8b, 0x22, 0x49, 0xf1, 0x12, +0x55, 0x45, 0x2f, 0xea, 0x6c, 0x49, 0xb4, 0xf0, +0x63, 0x3b, 0x80, 0x57, 0xf6, 0x95, 0xb1, 0x7a, +0xb1, 0x16, 0x9a, 0xb2, 0x94, 0x24, 0x70, 0x19, +0x0e, 0x66, 0x72, 0x4e, 0xa3, 0x10, 0x34, 0x99, +0xba, 0xd5, 0x16, 0x2e, 0xc6, 0x3f, 0x93, 0x7d, +0x59, 0xbb, 0xf0, 0x44, 0x4a, 0xe4, 0x54, 0x9f, +0xf2, 0xa9, 0x6b, 0xf8, 0x00, 0xed, 0x58, 0x77, +0x62, 0xc8, 0x94, 0x77, 0x5d, 0x1b, 0x03, 0x37, +0x29, 0xd0, 0x77, 0x2a, 0x7d, 0xd9, 0x7e, 0xa4, +0x9c, 0x84, 0xaf, 0x4d, 0x90, 0x30, 0x34, 0x55, +0x3f, 0x8d, 0x9f, 0x1f, 0x14, 0x34, 0xe7, 0xbd, +0xb8, 0x93, 0x84, 0x14, 0xe0, 0xf9, 0x38, 0xe9, +0x9e, 0xf8, 0x5b, 0xc6, 0xfa, 0xf1, 0xd1, 0x89, +0x14, 0x7e, 0xf7, 0x44, 0x06, 0x7f, 0x73, 0xa6, +0xda, 0xbe, 0x33, 0xdd, 0xa4, 0x99, 0xb1, 0xad, +0x39, 0x2a, 0x26, 0xad, 0x51, 0x58, 0xbb, 0x97, +0xb0, 0x94, 0x2f, 0xe6, 0x71, 0xef, 0xbd, 0xf7, +0x02, 0x80, 0x9f, 0x3b, 0x7b, 0xba, 0x6f, 0x77, +0x47, 0xbd, 0xcf, 0x3c, 0xbf, 0x84, 0x37, 0xfd, +0xdd, 0x3c, 0xfe, 0xd7, 0xed, 0xe3, 0x38, 0x78, +0xd5, 0xbe, 0x0d, 0xf7, 0xe9, 0x0d, 0xe4, 0xba, +0x6e, 0xe7, 0xdb, 0x73, 0x9b, 0xc0, 0xc1, 0xfd, +0x93, 0x3d, 0xdf, 0xb5, 0x4e, 0x85, 0x18, 0x39, +0x00, 0xa0, 0x56, 0xc1, 0xb3, 0xfd, 0x13, 0x91, +0xda, 0x3d, 0xbb, 0x0a, 0xbc, 0x79, 0xfe, 0x2c, +0x76, 0x8d, 0x6d, 0xeb, 0x99, 0x91, 0xde, 0x70, +0xc3, 0x0d, 0xf8, 0xfa, 0x63, 0x4f, 0xf8, 0x97, +0xda, 0x3c, 0x7c, 0xbe, 0x8c, 0xdf, 0x9e, 0x9e, +0xc7, 0xfb, 0x6f, 0xec, 0xed, 0x7a, 0xd8, 0xcd, +0x2c, 0x7e, 0x66, 0xc8, 0x66, 0x23, 0x18, 0x6f, +0xdd, 0x43, 0x91, 0x76, 0xde, 0x6c, 0xca, 0x41, +0x61, 0x2d, 0xed, 0xec, 0x46, 0x52, 0xc4, 0x72, +0x95, 0xb8, 0xd7, 0xac, 0x02, 0xc8, 0x04, 0x7e, +0x5b, 0x1b, 0xa5, 0xa1, 0x1f, 0x85, 0xb1, 0x49, +0xf0, 0x00, 0x6c, 0x4a, 0x68, 0x1a, 0xd7, 0x9a, +0x48, 0x2f, 0x7e, 0xb2, 0xed, 0xf7, 0xa2, 0x91, +0x88, 0x39, 0x29, 0x94, 0xab, 0xd5, 0x00, 0x3c, +0xab, 0x56, 0xd1, 0x57, 0xb3, 0x87, 0x49, 0x40, +0x54, 0xa2, 0x32, 0x72, 0x59, 0x42, 0x3c, 0xcd, +0xd5, 0x4d, 0xd5, 0xb6, 0xd1, 0x2a, 0xcf, 0x86, +0x5b, 0x15, 0x6c, 0x77, 0x9b, 0xf8, 0x81, 0xd1, +0x18, 0x5e, 0xe6, 0x14, 0x50, 0x2e, 0xae, 0xdb, +0xc6, 0x35, 0xc9, 0x98, 0x8a, 0xa6, 0xe6, 0x06, +0x82, 0x4c, 0x4a, 0xb6, 0x27, 0x69, 0x97, 0x33, +0x45, 0xe9, 0x65, 0x6e, 0xf2, 0x82, 0xd7, 0xec, +0xf0, 0xd2, 0x73, 0x9c, 0xc3, 0xa5, 0x13, 0xaf, +0x86, 0xbf, 0x66, 0xb7, 0x0e, 0x4b, 0x80, 0xa3, +0xf9, 0x08, 0x68, 0xc9, 0x65, 0x4c, 0x1a, 0x08, +0x99, 0xec, 0x86, 0xe2, 0xd4, 0x79, 0xff, 0xf2, +0x40, 0x94, 0x72, 0x12, 0xa8, 0x02, 0x68, 0x8a, +0xcb, 0x18, 0x78, 0xdd, 0x6a, 0xb3, 0x85, 0x66, +0xbd, 0x86, 0xa6, 0x57, 0xc1, 0xcf, 0xee, 0xf4, +0x70, 0x63, 0xbc, 0x8c, 0x3f, 0x38, 0x9b, 0xc4, +0xe3, 0xab, 0x71, 0x7d, 0x0d, 0xda, 0xc2, 0xd8, +0x4c, 0x6b, 0x2f, 0x44, 0x45, 0xf5, 0x52, 0x97, +0x42, 0xa5, 0x8a, 0x4f, 0x7f, 0xfa, 0xd3, 0x81, +0xfb, 0xeb, 0x1f, 0x4e, 0xef, 0x5e, 0xcf, 0xf5, +0xce, 0xf1, 0x4d, 0x38, 0x78, 0xb8, 0x02, 0x7c, +0xef, 0xfd, 0xb3, 0xf8, 0xc0, 0xcc, 0x31, 0xdc, +0x7a, 0xdb, 0x6d, 0x18, 0xcc, 0x45, 0x4b, 0x9f, +0x4a, 0x92, 0xf8, 0xd2, 0xc2, 0x1c, 0x1e, 0x7c, +0xf0, 0x41, 0xe4, 0x72, 0x39, 0xbc, 0xf9, 0xcd, +0x6f, 0xee, 0x09, 0x67, 0x5a, 0x1b, 0xaf, 0xbb, +0xf6, 0xaa, 0x0d, 0x8d, 0x5d, 0xde, 0x90, 0x36, +0xd3, 0x3f, 0x81, 0x8f, 0x0c, 0x5c, 0x17, 0xf9, +0xa0, 0x35, 0x7c, 0xa2, 0x8a, 0xff, 0x32, 0x16, +0xa9, 0xaa, 0xde, 0x7e, 0x78, 0x18, 0x57, 0xed, +0xdd, 0x83, 0x9b, 0x9f, 0x38, 0x81, 0x93, 0xee, +0x08, 0x0a, 0xb1, 0x24, 0x7e, 0xef, 0xf1, 0xb3, +0xd8, 0x9a, 0x4e, 0xe2, 0xc7, 0x0f, 0x6c, 0x4c, +0xe3, 0xb0, 0xd1, 0xc2, 0xd5, 0xcd, 0x74, 0x05, +0x6a, 0xaf, 0x8c, 0x37, 0xeb, 0xae, 0x4b, 0xcd, +0xb5, 0x4d, 0xf0, 0x9b, 0x00, 0x82, 0x69, 0x52, +0xc1, 0xf3, 0xa8, 0x6f, 0x50, 0x2d, 0xce, 0x0f, +0x31, 0x9b, 0xa1, 0x66, 0xe7, 0x70, 0xe1, 0xa5, +0x90, 0x69, 0xd6, 0x50, 0x4c, 0xf6, 0x16, 0x36, +0x4a, 0xa5, 0xc3, 0x57, 0x80, 0xed, 0x31, 0x1b, +0xb1, 0xed, 0xab, 0x6a, 0x76, 0x4e, 0x53, 0x03, +0x4f, 0x75, 0x8c, 0x0c, 0xb9, 0x9b, 0xcf, 0xbd, +0x30, 0x7d, 0x53, 0x3d, 0x82, 0x61, 0xea, 0x73, +0xed, 0x7b, 0xbf, 0xe7, 0x61, 0x22, 0xbe, 0x8a, +0x5b, 0xb3, 0x2d, 0xdc, 0xd0, 0xef, 0x20, 0xd7, +0x28, 0xa2, 0xbf, 0x5e, 0x86, 0x4c, 0xe2, 0x64, +0x62, 0xe4, 0xb6, 0x2c, 0x6a, 0xdc, 0x81, 0xcb, +0xf3, 0x3c, 0xff, 0xbe, 0x5f, 0x4a, 0xd1, 0x6a, +0x92, 0x58, 0x79, 0x2e, 0x74, 0x2a, 0x92, 0x41, +0x72, 0x55, 0x3a, 0xcf, 0x97, 0xce, 0xeb, 0x84, +0x15, 0x93, 0x03, 0x1a, 0x7d, 0xb6, 0x69, 0x18, +0x4c, 0x61, 0x77, 0xd2, 0x8e, 0x2e, 0x6d, 0xe2, +0x94, 0xb3, 0x1e, 0xe8, 0xbc, 0xb1, 0x4d, 0xa3, +0xb3, 0xa6, 0x45, 0xd0, 0x0e, 0x10, 0xb9, 0x5c, +0x0e, 0x39, 0x71, 0x48, 0xb8, 0xb6, 0x0f, 0x78, +0xff, 0x78, 0x05, 0xdf, 0x2c, 0x27, 0xf1, 0x47, +0xf3, 0x89, 0xf5, 0xdb, 0xd8, 0xba, 0x59, 0x9b, +0xdd, 0xd4, 0xeb, 0xb1, 0x6c, 0xc6, 0x55, 0x8c, +0x00, 0x70, 0xfc, 0xf8, 0x71, 0xdc, 0x77, 0xdf, +0x7d, 0xeb, 0x77, 0xa2, 0x03, 0x78, 0xa1, 0x6f, +0x14, 0x0f, 0xa5, 0x27, 0xdb, 0x15, 0xb4, 0xdf, +0x45, 0xc2, 0xc1, 0xb1, 0xc6, 0x00, 0x7e, 0xe6, +0x54, 0x0c, 0xdf, 0xff, 0xe7, 0x1f, 0xc2, 0xfe, +0x9c, 0x87, 0xa9, 0xa9, 0x29, 0x4c, 0x4e, 0x4e, +0xaa, 0x7e, 0x12, 0x00, 0x30, 0x37, 0x37, 0x87, +0xd9, 0xd9, 0x59, 0xcc, 0xcf, 0xcf, 0x63, 0x6e, +0x6e, 0x0e, 0x95, 0x4a, 0x05, 0x87, 0x0f, 0x1f, +0xee, 0x09, 0x67, 0x72, 0x80, 0x1b, 0xdd, 0xb6, +0x0d, 0x07, 0xf7, 0xed, 0xdd, 0x10, 0x1d, 0xf2, +0xf9, 0x3c, 0x66, 0x4f, 0x9d, 0xf1, 0x37, 0xc5, +0x99, 0x34, 0x4b, 0x72, 0x13, 0xb6, 0x2f, 0x01, +0xf8, 0xfc, 0xec, 0x22, 0x70, 0xeb, 0xce, 0x0d, +0xcd, 0xc1, 0x2d, 0x2f, 0xbb, 0x11, 0xc7, 0x9e, +0x3c, 0x86, 0xb1, 0xca, 0x05, 0x1c, 0xf7, 0x46, +0x51, 0xac, 0xd6, 0xf0, 0xaf, 0x8f, 0x9e, 0xc6, +0xe2, 0xa9, 0x59, 0xfc, 0xbf, 0xaf, 0x3d, 0x14, +0x60, 0x84, 0xdd, 0x14, 0x72, 0xea, 0x9b, 0x99, +0x99, 0xc1, 0x81, 0xeb, 0x6f, 0xe8, 0x5d, 0xf5, +0x4a, 0x8c, 0xb2, 0x51, 0x47, 0xb3, 0x87, 0x6c, +0x72, 0x12, 0x5e, 0xd2, 0x4b, 0xad, 0xdb, 0xcc, +0x81, 0x9e, 0x61, 0x92, 0x29, 0x20, 0x10, 0x3e, +0xc7, 0xe6, 0xac, 0xde, 0xea, 0x3d, 0xad, 0x69, +0x40, 0x85, 0xbd, 0x41, 0xc9, 0x9c, 0x7b, 0xf2, +0x2f, 0x23, 0xd1, 0xf6, 0x43, 0xd9, 0x84, 0x12, +0x18, 0x37, 0x5f, 0x9b, 0x1b, 0xb0, 0x99, 0x93, +0x03, 0x9c, 0x1f, 0x67, 0x4e, 0xb0, 0x05, 0x6d, +0xe5, 0x7f, 0xc7, 0x28, 0xfd, 0x76, 0xe3, 0xc1, +0x2e, 0x8b, 0x0c, 0x13, 0x0a, 0x53, 0x91, 0xca, +0x7a, 0x72, 0x00, 0x6b, 0x9f, 0x33, 0x89, 0x18, +0xc6, 0x13, 0x75, 0xbc, 0x36, 0x79, 0x1e, 0x77, +0x66, 0x2a, 0x18, 0xc9, 0xa6, 0xd1, 0x97, 0xed, +0xc7, 0x6a, 0x61, 0x05, 0xe5, 0x6a, 0x19, 0x95, +0x46, 0x13, 0x6e, 0x22, 0xee, 0x4b, 0xcb, 0x3c, +0x4c, 0x8c, 0x8a, 0x54, 0x17, 0x4b, 0x07, 0x36, +0x19, 0x9b, 0x9d, 0xcf, 0xe7, 0x91, 0x4e, 0xa7, +0x03, 0xdf, 0xb5, 0x30, 0x2d, 0x2d, 0xe1, 0x8b, +0xe6, 0x38, 0x46, 0x85, 0xdb, 0xd7, 0x35, 0xc6, +0x0e, 0x98, 0xaf, 0x4b, 0x95, 0xaa, 0x78, 0x82, +0xa7, 0xd9, 0xe5, 0x35, 0x29, 0x9c, 0xea, 0xcb, +0xdb, 0xdc, 0x68, 0x71, 0x4a, 0x75, 0xbd, 0xe7, +0x79, 0x81, 0x2b, 0x53, 0x35, 0x69, 0x5e, 0x73, +0xa0, 0xe3, 0x78, 0x98, 0x7c, 0x17, 0x38, 0xde, +0xbc, 0x7d, 0xa2, 0x5c, 0xc6, 0x6d, 0x9e, 0x87, +0xeb, 0x27, 0x73, 0xf8, 0x4f, 0x27, 0x9b, 0x78, +0xb8, 0x1e, 0x12, 0x0d, 0x11, 0x65, 0x8d, 0x29, +0x6b, 0x6a, 0x23, 0xa5, 0xcf, 0x89, 0xe3, 0x1b, +0xdf, 0xf8, 0x06, 0x3c, 0xcf, 0xc3, 0xc4, 0xbe, +0xf6, 0x8d, 0x49, 0xdd, 0x6c, 0xfa, 0xc5, 0x62, +0x11, 0x5f, 0xf8, 0xea, 0x11, 0x3c, 0xf2, 0xd0, +0x51, 0x5f, 0x12, 0x71, 0x5d, 0x17, 0x4b, 0xb1, +0x14, 0x3e, 0x9e, 0xbb, 0x1e, 0xc5, 0x58, 0x32, +0x30, 0x86, 0x4c, 0x22, 0x86, 0xbd, 0x83, 0x1e, +0x8a, 0xb5, 0x06, 0x16, 0x56, 0x6b, 0x40, 0x22, +0x89, 0x65, 0x0c, 0xe3, 0x0f, 0x93, 0x37, 0xe1, +0xce, 0x0b, 0x4f, 0xe2, 0x99, 0x07, 0xbe, 0x88, +0x2c, 0x1e, 0x40, 0xcc, 0x49, 0xf9, 0xa7, 0x7b, +0xf2, 0x9f, 0x90, 0xeb, 0x8a, 0x24, 0xbe, 0xe1, +0x91, 0xad, 0x3d, 0x6d, 0x3a, 0x31, 0x37, 0x0d, +0xcf, 0xf3, 0x50, 0x4b, 0xa4, 0xb0, 0x54, 0x28, +0x62, 0x7e, 0x2d, 0xfd, 0x64, 0xae, 0xbe, 0xda, +0x35, 0x1d, 0xa7, 0xa7, 0xa7, 0xdb, 0xd9, 0xee, +0xe2, 0xc0, 0xd9, 0x58, 0x1a, 0xb3, 0x89, 0x9c, +0x5e, 0xd1, 0x30, 0xa7, 0xcf, 0x95, 0x81, 0x8f, +0xce, 0xe6, 0x71, 0xeb, 0xb6, 0xbe, 0x9e, 0xfa, +0xa7, 0xe2, 0x25, 0x13, 0x78, 0x79, 0xe9, 0x14, +0x8e, 0x7b, 0xa3, 0xfe, 0xb3, 0x7f, 0xff, 0x3c, +0x70, 0xe1, 0x23, 0x5f, 0xc0, 0x4f, 0xdf, 0xb4, +0x07, 0x93, 0x7b, 0xa3, 0x1d, 0x5a, 0x48, 0x5a, +0x6d, 0x55, 0x4a, 0x98, 0x9d, 0x9d, 0xc5, 0xd1, +0xa3, 0x47, 0xd7, 0xf7, 0x97, 0x74, 0x74, 0x69, +0xd0, 0x75, 0x5d, 0x9c, 0x3c, 0x79, 0xb2, 0x93, +0x61, 0x00, 0x78, 0xe8, 0x6c, 0x11, 0x87, 0xb6, +0x78, 0x70, 0x9b, 0x35, 0xa4, 0x9b, 0xb5, 0x40, +0x1b, 0x63, 0x8c, 0x36, 0xda, 0xbf, 0x37, 0xd7, +0x75, 0x51, 0x6b, 0x35, 0xd6, 0x9d, 0xc0, 0xd6, +0x68, 0xf9, 0xd0, 0xd9, 0x22, 0x6e, 0xd9, 0x96, +0x01, 0x6a, 0xe5, 0x00, 0xcc, 0xb0, 0x42, 0x69, +0xab, 0xb5, 0xf2, 0xf0, 0xb9, 0x22, 0x0e, 0x8d, +0xf4, 0x01, 0xad, 0x66, 0x57, 0x73, 0xc3, 0xc7, +0xcd, 0x7d, 0x05, 0x9e, 0x5c, 0x2a, 0xe3, 0x9a, +0x2d, 0xd5, 0xae, 0xe1, 0xd1, 0xd8, 0x01, 0x04, +0x6c, 0xe6, 0x17, 0xca, 0x75, 0xcc, 0xe4, 0xcb, +0xc8, 0xb9, 0x0e, 0xdc, 0x46, 0x25, 0xf2, 0xb8, +0x69, 0x6e, 0x02, 0x85, 0xf1, 0xc6, 0x36, 0x9e, +0xdd, 0x8d, 0xdb, 0x75, 0x5d, 0xcc, 0xcd, 0xcd, +0x05, 0x25, 0x73, 0x8d, 0x97, 0x1a, 0x8a, 0x13, +0xa8, 0x14, 0xf5, 0xbf, 0x04, 0x6c, 0x92, 0xd4, +0x7b, 0x81, 0x6b, 0x50, 0xb1, 0xef, 0x4b, 0x35, +0xf0, 0x9a, 0xe1, 0x38, 0x5e, 0x93, 0xa9, 0x22, +0x53, 0xaa, 0x22, 0x97, 0x5b, 0x63, 0x38, 0xf1, +0x78, 0x87, 0xf4, 0xa7, 0x65, 0x60, 0xa3, 0xff, +0x3c, 0x4e, 0x9c, 0xa4, 0x4f, 0x2d, 0x15, 0xaa, +0xf4, 0xaa, 0xa5, 0xfb, 0xc8, 0x01, 0x04, 0x36, +0x47, 0x2d, 0xfd, 0xa9, 0x64, 0xba, 0x5c, 0x92, +0xa7, 0x45, 0xc5, 0xed, 0xd3, 0x9a, 0x23, 0x1c, +0xef, 0x3b, 0xec, 0xc7, 0xa9, 0x7d, 0xa6, 0xb6, +0x9a, 0x04, 0x4d, 0xf8, 0x6b, 0xd9, 0xea, 0x80, +0xf6, 0x0f, 0xc9, 0xf3, 0x3c, 0x8c, 0x8e, 0x8e, +0xfa, 0xf6, 0x7a, 0x39, 0xde, 0xb0, 0x62, 0x92, +0xfa, 0x65, 0xda, 0xda, 0xbe, 0x81, 0x41, 0x0c, +0xf4, 0xa5, 0x03, 0x73, 0x47, 0x12, 0x7b, 0xb9, +0x5c, 0xc6, 0x60, 0xbc, 0x81, 0xff, 0x7a, 0xd0, +0xc3, 0x47, 0x0b, 0x2e, 0xfe, 0xd3, 0x33, 0x75, +0xb3, 0xd9, 0xa6, 0x97, 0xb5, 0xbb, 0x41, 0xe9, +0x9c, 0x6e, 0xa1, 0x3a, 0x7a, 0xf4, 0x28, 0x86, +0x46, 0xc7, 0x70, 0xfd, 0x81, 0x29, 0x4c, 0x4d, +0x4d, 0x19, 0x25, 0x63, 0xd7, 0x75, 0xfd, 0xdc, +0xf8, 0x24, 0x21, 0x07, 0xae, 0xbe, 0x5d, 0xbb, +0x42, 0xf2, 0xde, 0x81, 0x83, 0xb8, 0x10, 0x73, +0x3b, 0xf0, 0xfd, 0xf5, 0x9b, 0xb6, 0xe3, 0x27, +0x0f, 0x6e, 0x45, 0xb3, 0xd1, 0xbe, 0x85, 0x0b, +0x00, 0x2a, 0xcd, 0x16, 0x1e, 0xbf, 0x50, 0x06, +0x70, 0x00, 0x5e, 0xad, 0x88, 0xfc, 0xd2, 0x12, +0x9a, 0xe7, 0xe7, 0xd0, 0xdf, 0x58, 0xbb, 0x38, +0xe7, 0xfc, 0x12, 0x62, 0xae, 0x87, 0xb3, 0xf9, +0x8b, 0x48, 0x36, 0x1b, 0x6d, 0xc7, 0x32, 0xb7, +0x0f, 0xab, 0xb1, 0x04, 0x6a, 0x5e, 0x1a, 0xc3, +0x3b, 0x76, 0x47, 0x19, 0x6a, 0x47, 0x69, 0x55, +0xda, 0xe9, 0x8b, 0x97, 0x96, 0xe6, 0xf0, 0x81, +0x3f, 0xfd, 0x1b, 0xfc, 0x55, 0xee, 0xe5, 0x38, +0x54, 0x3e, 0x83, 0x37, 0x16, 0x67, 0xd0, 0xaa, +0x94, 0xfd, 0x43, 0x44, 0x8c, 0x5d, 0xfb, 0xd9, +0xaa, 0x57, 0xdb, 0x07, 0xe3, 0xb5, 0x6b, 0x31, +0x5b, 0xf5, 0xaa, 0x7f, 0xf0, 0x20, 0x29, 0xec, +0xb9, 0xcc, 0xb6, 0x75, 0xf5, 0x67, 0x54, 0x41, +0x20, 0xe1, 0xe0, 0xbd, 0x5f, 0x6c, 0x6f, 0xac, +0xef, 0xce, 0x7f, 0x1d, 0xbb, 0xaa, 0xf9, 0x00, +0xae, 0x5e, 0x32, 0x11, 0x70, 0x08, 0x2d, 0xd7, +0x1a, 0x3e, 0x2e, 0x00, 0x7c, 0x3c, 0x5b, 0xf5, +0x2a, 0x76, 0xd6, 0x8a, 0x18, 0x1f, 0x08, 0xde, +0x75, 0xfe, 0x57, 0x85, 0x01, 0x3c, 0xf5, 0xe9, +0x69, 0xbc, 0x3b, 0xfb, 0x05, 0x4c, 0x4e, 0x4e, +0x62, 0x62, 0x62, 0x02, 0xe3, 0xe3, 0xe3, 0xc6, +0xdf, 0x65, 0xa9, 0xd4, 0x96, 0xc4, 0xa7, 0xa7, +0xa7, 0x7d, 0xe6, 0x09, 0x00, 0x7f, 0xf6, 0x67, +0x7f, 0x86, 0x98, 0xbb, 0x76, 0xe0, 0x6e, 0x34, +0x7d, 0x1c, 0x78, 0xff, 0x44, 0x1f, 0xbe, 0xa1, +0x4b, 0x55, 0x6e, 0x11, 0x0e, 0x7e, 0xe8, 0x81, +0x13, 0x00, 0x10, 0xa0, 0x39, 0x15, 0x0d, 0x56, +0xcc, 0x49, 0xc1, 0x4b, 0x26, 0xd6, 0x99, 0xb9, +0x1f, 0x9e, 0xd5, 0x1e, 0x63, 0xb1, 0xd1, 0xc2, +0xdb, 0x3f, 0xf7, 0x1c, 0x32, 0x89, 0x58, 0x07, +0x4c, 0x0d, 0x0e, 0x8d, 0x53, 0xe2, 0xe8, 0x7b, +0xb3, 0xaf, 0xd1, 0xee, 0xf7, 0x1e, 0x3f, 0x8b, +0xdf, 0x7f, 0xf2, 0x3c, 0xb6, 0xae, 0x9e, 0xc5, +0x0f, 0x17, 0xa7, 0xfd, 0x71, 0x13, 0x1c, 0x3e, +0x17, 0x34, 0x47, 0xbe, 0x90, 0xc1, 0x7d, 0xdd, +0xd6, 0x60, 0xfe, 0xf2, 0xc3, 0x2f, 0xe0, 0xb7, +0x1e, 0x3b, 0x87, 0x91, 0xc2, 0x02, 0x7e, 0xb8, +0x38, 0xed, 0xaf, 0x35, 0x39, 0x8f, 0x12, 0x67, +0x35, 0x11, 0x0b, 0x80, 0x33, 0x2b, 0x25, 0xbc, +0xea, 0x13, 0x4f, 0x21, 0x1e, 0x4f, 0xe0, 0x5d, +0x17, 0x8e, 0x06, 0xd6, 0x0e, 0xb5, 0xa5, 0x35, +0x54, 0x66, 0xd7, 0xb9, 0x12, 0xbc, 0xc0, 0xdc, +0xb0, 0xdf, 0xeb, 0x2f, 0x3f, 0xfc, 0x02, 0xfe, +0xdd, 0xa3, 0x73, 0x18, 0x2d, 0x9f, 0xc7, 0x0f, +0x17, 0xa7, 0xe1, 0xc5, 0x63, 0x81, 0xf1, 0xf1, +0x71, 0x52, 0x1f, 0x46, 0x98, 0x8d, 0x7a, 0x24, +0xbe, 0xba, 0xbe, 0x2b, 0x76, 0xbb, 0x29, 0x86, +0xa8, 0xbe, 0x7a, 0xde, 0x64, 0x19, 0x8c, 0x2d, +0x89, 0x16, 0xf6, 0xa7, 0x9b, 0xb8, 0x6d, 0x5b, +0x1f, 0x5e, 0x9b, 0x38, 0x8f, 0x81, 0xb4, 0x87, +0x0b, 0x8b, 0xc1, 0x1f, 0x2a, 0xa5, 0x0f, 0xcd, +0xe5, 0x72, 0x68, 0xd5, 0xaa, 0x1d, 0xb6, 0x68, +0xe9, 0x88, 0xa6, 0x31, 0x19, 0xba, 0x03, 0x9c, +0x87, 0xa6, 0x49, 0x69, 0x31, 0x9d, 0x4e, 0xfb, +0xfd, 0x90, 0xc4, 0x4f, 0x92, 0x3c, 0x6f, 0x4f, +0x6d, 0xe8, 0xfb, 0xd8, 0xd8, 0x98, 0xff, 0x9e, +0x24, 0x78, 0xfe, 0x99, 0xf0, 0xd0, 0xe2, 0xd8, +0x3d, 0xcf, 0xeb, 0x38, 0x69, 0x97, 0x4a, 0x25, +0x7f, 0x11, 0x48, 0xa6, 0x21, 0x7f, 0x5c, 0xe5, +0x72, 0xd9, 0xf7, 0x84, 0xe7, 0x30, 0xf8, 0x81, +0xc7, 0xe6, 0xc1, 0xbf, 0xb0, 0xb0, 0x80, 0x4a, +0xa5, 0xd2, 0xa1, 0xb1, 0xe0, 0xf8, 0xf1, 0x62, +0xf3, 0x7e, 0xe7, 0xea, 0x7b, 0xa2, 0xdd, 0xfc, +0xfc, 0x3c, 0x2e, 0x9c, 0x5d, 0xc0, 0x05, 0x04, +0xb5, 0x0e, 0x9c, 0xa1, 0x17, 0x6a, 0x0d, 0x5c, +0x58, 0x3c, 0x87, 0xd7, 0x66, 0xca, 0xf8, 0xcb, +0xbe, 0x81, 0xf5, 0xcc, 0x71, 0x51, 0x0f, 0x8d, +0xb2, 0x44, 0xf5, 0x82, 0xef, 0xa2, 0xb8, 0xae, +0x8b, 0xa5, 0x0b, 0x4b, 0xb8, 0xe7, 0xe8, 0x37, +0x70, 0xe4, 0xc8, 0x11, 0x7f, 0xf3, 0xe0, 0x1b, +0x8b, 0x49, 0x3a, 0xe6, 0x37, 0x2f, 0x7d, 0x33, +0xbd, 0x03, 0x0f, 0x64, 0xae, 0x42, 0x31, 0x9e, +0x54, 0x7f, 0x53, 0x57, 0x0d, 0xac, 0x25, 0xfb, +0x70, 0x53, 0x81, 0xeb, 0x34, 0xd7, 0xe3, 0xd9, +0xb3, 0xc0, 0xe4, 0x28, 0x80, 0x29, 0xff, 0x5d, +0xb5, 0xd9, 0xc2, 0x52, 0xa9, 0x8a, 0x9f, 0xf8, +0xf0, 0x83, 0xb8, 0x50, 0x6c, 0xe3, 0x50, 0x4a, +0xb8, 0x38, 0xe9, 0x8e, 0x60, 0x5b, 0x3a, 0x89, +0x5f, 0x1d, 0xe9, 0xcd, 0x26, 0x4c, 0x97, 0x09, +0x55, 0x9a, 0xc0, 0x85, 0x4a, 0x13, 0xb1, 0x7a, +0x15, 0x7b, 0x96, 0x9f, 0x47, 0xab, 0x51, 0x46, +0x01, 0x09, 0x14, 0x4a, 0x55, 0x00, 0x09, 0x24, +0xd7, 0x1c, 0x79, 0xda, 0xde, 0xe9, 0x09, 0x54, +0x8a, 0xa5, 0xb5, 0xcf, 0x00, 0x90, 0x00, 0xea, +0x8d, 0xf6, 0xff, 0x35, 0xaf, 0xe5, 0x69, 0x6f, +0x7b, 0x24, 0xcf, 0x5d, 0x59, 0xa7, 0x88, 0xf6, +0xb3, 0x6f, 0x3a, 0xdb, 0xb0, 0xb5, 0x70, 0x96, +0xf5, 0x01, 0xac, 0xd4, 0x1b, 0x68, 0xd5, 0x9a, +0xa8, 0x34, 0x4b, 0xa8, 0x36, 0x9a, 0x88, 0x25, +0x93, 0xc0, 0x1a, 0x8e, 0xad, 0x5a, 0xad, 0xfd, +0x7d, 0xad, 0x4e, 0xaa, 0x59, 0x6b, 0xdf, 0x75, +0x9e, 0xd9, 0xeb, 0xc3, 0x2f, 0x34, 0x63, 0x78, +0xd0, 0xdd, 0x8d, 0xd3, 0xab, 0xe7, 0xf1, 0x96, +0xa3, 0xdf, 0xc0, 0xd0, 0x91, 0x23, 0x88, 0xb9, +0x5e, 0x80, 0xd9, 0xf1, 0x83, 0x0b, 0x1d, 0x4e, +0x48, 0xd3, 0xb2, 0x52, 0x6b, 0xf7, 0xb9, 0x1a, +0x4b, 0xe1, 0x01, 0x6f, 0x0a, 0xd7, 0x95, 0xce, +0x60, 0x6f, 0xb5, 0x8d, 0x23, 0xd1, 0x89, 0xe8, +0x50, 0x28, 0x55, 0x91, 0x5c, 0xf3, 0x2c, 0xf7, +0xc7, 0xe0, 0xf6, 0xf9, 0xcf, 0x08, 0xa7, 0x62, +0xb5, 0x06, 0x24, 0x1c, 0xd4, 0xeb, 0x75, 0x94, +0x4b, 0xe5, 0xc0, 0x78, 0x51, 0x6f, 0x20, 0xd9, +0xc4, 0x1a, 0xec, 0x75, 0x3a, 0xaf, 0xd4, 0x1b, +0x48, 0x26, 0xd7, 0xa4, 0xfc, 0x44, 0x3b, 0x69, +0x8c, 0xef, 0x08, 0xd6, 0x58, 0x67, 0xea, 0x95, +0x6a, 0x35, 0x00, 0x53, 0x85, 0x23, 0x70, 0x4c, +0x26, 0xd9, 0xcd, 0x7c, 0x6c, 0xce, 0x68, 0x5e, +0x92, 0x31, 0x97, 0xc1, 0x5c, 0x87, 0x43, 0x70, +0x69, 0x5d, 0xf8, 0xf4, 0x00, 0x82, 0xb7, 0x9b, +0x31, 0x98, 0x17, 0x2b, 0x40, 0xb6, 0x15, 0x43, +0xb9, 0x54, 0x56, 0xf1, 0x83, 0xbf, 0xfe, 0x80, +0x64, 0x13, 0x40, 0xb5, 0xba, 0x8e, 0x67, 0xb3, +0x01, 0x24, 0x80, 0x42, 0xb5, 0x0e, 0xb8, 0xe9, +0x36, 0x8e, 0x8d, 0x16, 0x50, 0x2d, 0xe3, 0x7c, +0x3d, 0x8e, 0xad, 0xac, 0xee, 0x3a, 0x3c, 0xe0, +0x62, 0xa9, 0x8c, 0x54, 0x22, 0x1e, 0x58, 0xcb, +0x7c, 0x6e, 0x1a, 0xf1, 0xce, 0xdf, 0x6b, 0xb1, +0x5a, 0xc3, 0x4a, 0x2b, 0x81, 0x95, 0x4a, 0x0d, +0xe5, 0xb5, 0x83, 0x34, 0x8d, 0x2f, 0x30, 0xce, +0xc0, 0x6f, 0x44, 0xcc, 0x77, 0x98, 0x79, 0x3b, +0xa0, 0x66, 0xdf, 0x88, 0x24, 0x1d, 0x62, 0x90, +0xef, 0xf6, 0xff, 0x96, 0x54, 0x02, 0x4e, 0xab, +0x8e, 0xab, 0x63, 0x17, 0xf0, 0xba, 0xfe, 0x2a, +0x26, 0xfb, 0x5d, 0x0c, 0x24, 0x5a, 0x68, 0x95, +0xcf, 0xc2, 0xf1, 0x3c, 0xcc, 0x2d, 0x2c, 0x63, +0xe9, 0xdc, 0x59, 0x4c, 0x4e, 0x4e, 0xfa, 0x4c, +0xd1, 0xe4, 0xe5, 0x2d, 0xa5, 0x71, 0xcd, 0x29, +0x0d, 0x08, 0xde, 0x78, 0x26, 0x53, 0xaf, 0xd2, +0xb3, 0x52, 0xa9, 0xe4, 0x4b, 0xa8, 0x74, 0xad, +0x29, 0x3f, 0x28, 0x70, 0xa9, 0x53, 0x4a, 0xfc, +0xbc, 0x4f, 0xae, 0xf6, 0xd7, 0xc2, 0xd0, 0x78, +0x7c, 0xbb, 0x7c, 0x47, 0x9b, 0xbe, 0x89, 0x81, +0xf3, 0xab, 0x53, 0xa9, 0xd0, 0x41, 0x83, 0x4b, +0xd3, 0x26, 0x3f, 0x01, 0xad, 0xf0, 0xe7, 0xae, +0xeb, 0x62, 0x7c, 0x7c, 0xbc, 0x83, 0x81, 0x13, +0xec, 0x6a, 0xbd, 0xe1, 0x5f, 0x1d, 0x2b, 0x6d, +0xf3, 0x32, 0x76, 0x9d, 0xab, 0xee, 0xa5, 0x29, +0x84, 0x67, 0xd2, 0xf3, 0x3c, 0x0f, 0x03, 0x03, +0x83, 0xb8, 0x50, 0x6c, 0x67, 0xd5, 0x3a, 0x90, +0x8d, 0xb7, 0x99, 0xb9, 0x2d, 0x07, 0x41, 0x94, +0x50, 0x8e, 0x4d, 0x64, 0xe4, 0x54, 0x56, 0x13, +0x29, 0xfc, 0xd1, 0xc0, 0xcb, 0x71, 0xa0, 0xb1, +0x84, 0xa9, 0xd2, 0x3c, 0x26, 0x9a, 0x17, 0x80, +0xb5, 0x1f, 0x29, 0xff, 0xe1, 0x02, 0xed, 0x0d, +0xa5, 0x1d, 0x6a, 0x04, 0xd4, 0xbc, 0x7e, 0xcc, +0x27, 0x73, 0xf8, 0xa2, 0xb7, 0x1b, 0xf9, 0xec, +0x68, 0x7b, 0x63, 0xd1, 0x4e, 0xe2, 0x80, 0xd1, +0xfe, 0x68, 0x63, 0xc6, 0x7d, 0x00, 0x52, 0x71, +0x17, 0xbf, 0xf6, 0xd6, 0x57, 0xe2, 0x77, 0xbf, +0xb5, 0x80, 0xa7, 0x2e, 0x56, 0x10, 0x07, 0xf0, +0xae, 0x6d, 0x19, 0xfc, 0xf8, 0x81, 0x91, 0x9e, +0xd3, 0xcd, 0x3e, 0xfa, 0xe8, 0xa3, 0xeb, 0xe3, +0x49, 0xc4, 0x51, 0x68, 0xc6, 0xf0, 0x40, 0x66, +0x2f, 0x66, 0x9a, 0xeb, 0xe6, 0x98, 0x44, 0xbc, +0x7d, 0x59, 0x04, 0xfd, 0x07, 0x80, 0x64, 0xa3, +0x8a, 0x66, 0xd2, 0xeb, 0x78, 0x0e, 0xb4, 0x0f, +0x19, 0x2f, 0xd0, 0x55, 0x92, 0x61, 0x9a, 0x14, +0xc3, 0xfc, 0x3f, 0xee, 0x6c, 0x45, 0x63, 0xe0, +0xa0, 0x8a, 0xb3, 0xec, 0x4f, 0x7e, 0xa7, 0x67, +0xcf, 0x25, 0x06, 0xd5, 0x03, 0xc4, 0xf1, 0xc4, +0x28, 0xfe, 0x28, 0x31, 0x80, 0xeb, 0x4a, 0xa7, +0x70, 0x7d, 0xf9, 0x0c, 0x06, 0x90, 0x40, 0xb2, +0xd9, 0x40, 0xa5, 0x58, 0xc2, 0x6a, 0x22, 0x85, +0xe4, 0x1a, 0x93, 0x23, 0xed, 0x07, 0x2a, 0xab, +0x40, 0xd2, 0xc5, 0x9c, 0x37, 0x82, 0x47, 0xb3, +0x13, 0xbe, 0x73, 0xdd, 0x52, 0xdc, 0xc3, 0x73, +0xde, 0xb6, 0x8e, 0xbe, 0x6d, 0xf8, 0x96, 0x12, +0x6e, 0xfb, 0x8a, 0x5d, 0x21, 0x4c, 0x3d, 0x1e, +0x1b, 0x44, 0x63, 0xe0, 0xa0, 0x6f, 0x5f, 0xe5, +0x74, 0xd5, 0xc6, 0x47, 0x25, 0x9f, 0x48, 0xaf, +0xa5, 0x73, 0xed, 0xfc, 0x3d, 0x1c, 0x4b, 0x8d, +0x02, 0x03, 0x9d, 0x38, 0x84, 0xe1, 0x5a, 0x88, +0x25, 0xdb, 0x38, 0xc6, 0x3a, 0x61, 0x56, 0x13, +0x29, 0x7c, 0x6c, 0xe8, 0x06, 0xa4, 0xd7, 0xee, +0x64, 0x0f, 0xd8, 0x83, 0xd7, 0xf0, 0xee, 0x06, +0xe6, 0x0b, 0x89, 0xfe, 0x00, 0xbc, 0x30, 0x1a, +0xf2, 0x71, 0xe4, 0x13, 0x69, 0x9f, 0x91, 0xf3, +0xf1, 0x1f, 0xc9, 0xec, 0xc1, 0x69, 0x6f, 0xc4, +0x6f, 0x1b, 0xaf, 0x95, 0x51, 0x5b, 0x4b, 0xfd, +0xca, 0xe9, 0xab, 0xe1, 0x58, 0x4d, 0xa4, 0x80, +0x66, 0xe7, 0xba, 0x2c, 0xc5, 0xfb, 0xf0, 0xa9, +0xc1, 0xeb, 0x8c, 0x78, 0x9a, 0xd6, 0x60, 0xa3, +0xd9, 0xc4, 0x31, 0x67, 0x6b, 0x57, 0x3e, 0x68, +0x4e, 0xe8, 0xa6, 0x68, 0x7a, 0x6e, 0x0a, 0x29, +0xb3, 0xc1, 0xe9, 0x18, 0x49, 0xdb, 0x0e, 0xbe, +0xbf, 0x2f, 0x8e, 0x91, 0x74, 0x1c, 0x6f, 0xeb, +0x2f, 0x61, 0x38, 0xd1, 0x44, 0xe3, 0x7c, 0x1e, +0xdb, 0x86, 0xdb, 0xcc, 0x73, 0x79, 0xa5, 0xe4, +0xa7, 0x88, 0x74, 0x13, 0x71, 0x5f, 0x3d, 0x2d, +0xd5, 0xe3, 0x61, 0x4c, 0x9d, 0x9e, 0xe7, 0x57, +0x8a, 0x68, 0xd5, 0xab, 0x18, 0x1f, 0x1f, 0x57, +0xa5, 0x74, 0xaa, 0xc7, 0x19, 0x50, 0xa9, 0x54, +0xc2, 0xfc, 0xfc, 0x3c, 0xc6, 0xc6, 0xc6, 0x7c, +0xf5, 0xbb, 0xe6, 0x68, 0x26, 0x13, 0xc4, 0x48, +0x0d, 0x01, 0x80, 0x80, 0xed, 0x99, 0xe3, 0x6a, +0x73, 0x84, 0x23, 0x09, 0xae, 0x52, 0xa9, 0x04, +0x98, 0x79, 0xa9, 0x54, 0xf2, 0x99, 0xb8, 0x29, +0xcb, 0x9c, 0xec, 0x47, 0xa3, 0x93, 0xcd, 0x11, +0x90, 0x27, 0xd1, 0xe1, 0x07, 0x10, 0x1a, 0x87, +0x8f, 0x2b, 0x8b, 0x2b, 0xe7, 0xb4, 0xa4, 0x76, +0xfc, 0x66, 0x38, 0x7a, 0x2e, 0x69, 0x2f, 0xaf, +0x60, 0x9d, 0x9f, 0x9f, 0xc7, 0xa4, 0xe7, 0xc1, +0xc9, 0xf4, 0xa3, 0x5e, 0x5c, 0xc1, 0x95, 0xc9, +0x0c, 0x1e, 0x68, 0x34, 0xba, 0x63, 0xd6, 0xa6, +0x28, 0x89, 0x4d, 0x08, 0x4b, 0x93, 0x4c, 0xb4, +0x18, 0x4b, 0xe1, 0xe1, 0xcc, 0x24, 0x1e, 0xf6, +0x76, 0x62, 0x6b, 0xa3, 0x88, 0x6d, 0xcd, 0xd5, +0xc0, 0xe6, 0x25, 0x7f, 0xb4, 0x2f, 0x24, 0x07, +0x71, 0x31, 0x99, 0x5d, 0xb7, 0x5b, 0x36, 0xd8, +0xe5, 0x0f, 0xca, 0xef, 0xf2, 0xe9, 0x1e, 0x6f, +0x4e, 0xeb, 0x73, 0xe2, 0x38, 0xb4, 0x25, 0x8d, +0xff, 0xf5, 0xea, 0x49, 0x14, 0xd7, 0xec, 0xb9, +0xc4, 0xc4, 0x7b, 0x91, 0xca, 0x0b, 0x95, 0x6a, +0xc0, 0xfb, 0x7c, 0x36, 0x31, 0x00, 0x24, 0x1c, +0x9c, 0x49, 0x0d, 0xe3, 0x0c, 0x86, 0xed, 0x26, +0x39, 0x2a, 0xdd, 0x1e, 0xc8, 0x34, 0xba, 0x28, +0xcf, 0x8b, 0xf1, 0x24, 0x1e, 0xce, 0x4c, 0x46, +0xf7, 0xab, 0x90, 0xb8, 0x84, 0xf8, 0x02, 0x15, +0x93, 0x69, 0x1c, 0x89, 0xef, 0xc5, 0x63, 0xfd, +0x7b, 0x90, 0xae, 0xad, 0x62, 0x5b, 0x73, 0x15, +0xd9, 0x56, 0x4d, 0x65, 0xa2, 0xa5, 0x41, 0x17, +0x67, 0xe3, 0x7d, 0x38, 0x97, 0xc8, 0x04, 0xc6, +0xf1, 0x42, 0xa2, 0x1f, 0x2f, 0xa4, 0x86, 0xa2, +0x8d, 0xdd, 0x76, 0xa8, 0x49, 0x38, 0x28, 0x26, +0x06, 0xf1, 0x30, 0x06, 0x7b, 0x37, 0x33, 0x29, +0xf5, 0x8a, 0xc9, 0x34, 0x1e, 0x8e, 0xef, 0xb4, +0xf6, 0xdb, 0xed, 0xe1, 0xb9, 0xd0, 0x8c, 0xe1, +0x09, 0x6f, 0x3c, 0xdc, 0x3c, 0xab, 0xbd, 0x8f, +0xe9, 0xbf, 0xe5, 0x27, 0xb0, 0x15, 0x48, 0xa2, +0x37, 0x61, 0x54, 0x59, 0x87, 0x2f, 0xa4, 0x86, +0xf0, 0x42, 0x83, 0x1d, 0x26, 0xd3, 0x11, 0xc6, +0x4c, 0x25, 0xe6, 0x00, 0xe8, 0x3c, 0x84, 0x17, +0x60, 0x18, 0xb7, 0xc9, 0x97, 0x47, 0x1b, 0x7f, +0x44, 0x1f, 0xb4, 0x70, 0xc9, 0xdc, 0xf4, 0x43, +0x30, 0x01, 0xb7, 0xc1, 0x61, 0xcf, 0xfa, 0x93, +0x0e, 0xae, 0x75, 0x2b, 0x78, 0xeb, 0x70, 0x13, +0xd7, 0x0f, 0x24, 0x30, 0x10, 0xaf, 0xe2, 0x62, +0xa9, 0x86, 0xd3, 0xcf, 0x3e, 0x13, 0xb0, 0x2d, +0xa7, 0xfb, 0x07, 0xda, 0x9b, 0x86, 0xa2, 0xd6, +0xd5, 0x6c, 0xdd, 0xd2, 0x0e, 0xcd, 0x99, 0x65, +0x3e, 0x9f, 0x6f, 0xdb, 0x7b, 0x92, 0xe9, 0x80, +0x07, 0xba, 0xe6, 0x71, 0xcd, 0x0b, 0x49, 0xc5, +0xdc, 0xe1, 0x4d, 0x32, 0x50, 0xce, 0xe8, 0x4c, +0xd9, 0xd4, 0x38, 0x5e, 0x32, 0xcb, 0x9c, 0xec, +0x9f, 0xe0, 0xc8, 0x2b, 0xf6, 0x3a, 0xec, 0x54, +0x08, 0x9a, 0x0f, 0xb4, 0x98, 0x7a, 0x4d, 0x8b, +0x61, 0xba, 0x40, 0x46, 0xf3, 0x90, 0x97, 0x7d, +0xf3, 0xf1, 0x70, 0xd8, 0x1c, 0x2e, 0x97, 0xb0, +0xf9, 0xfc, 0xc8, 0xa2, 0xf9, 0x2c, 0x94, 0x4a, +0x25, 0xdf, 0x3e, 0x35, 0x3b, 0x3b, 0x8b, 0x91, +0x1d, 0xbb, 0xe0, 0x79, 0x1e, 0x0e, 0x35, 0xab, +0xe8, 0xf7, 0x32, 0x9d, 0xe9, 0x5f, 0x7b, 0xd9, +0xc4, 0x36, 0x41, 0x32, 0x57, 0xe3, 0x76, 0xd7, +0x60, 0x9e, 0x4b, 0x0d, 0xe2, 0x5c, 0x23, 0xb3, +0xbe, 0xd9, 0x98, 0xf0, 0x88, 0xd9, 0x7f, 0x27, +0x7e, 0x7d, 0x00, 0x7f, 0xf3, 0xdc, 0x12, 0x7e, +0xe6, 0xda, 0xde, 0xe2, 0xa9, 0xfb, 0x36, 0xc0, +0xbc, 0x79, 0x29, 0x16, 0x8b, 0x78, 0xe8, 0xe8, +0xd1, 0x80, 0x0f, 0xc9, 0xf3, 0xc9, 0x5c, 0x28, +0xd3, 0xe1, 0xe3, 0x30, 0x9a, 0xe9, 0xa2, 0x6c, +0xc0, 0x52, 0xc8, 0x90, 0x70, 0xc3, 0xfa, 0x0f, +0xd9, 0x97, 0xa2, 0xfe, 0x2f, 0x00, 0x28, 0x24, +0x32, 0x6d, 0x46, 0x4d, 0x25, 0xe4, 0xa0, 0xd1, +0x93, 0xe6, 0x28, 0xc2, 0xba, 0xe8, 0x9a, 0x86, +0xdd, 0x6a, 0xae, 0xe4, 0xb3, 0x6e, 0xeb, 0x6b, +0xf8, 0x86, 0xc1, 0x0b, 0x9b, 0xcf, 0xa8, 0x87, +0x82, 0x8d, 0x1c, 0xf4, 0x7b, 0x81, 0x1b, 0x75, +0x3d, 0xda, 0xb4, 0xdd, 0xbd, 0xcc, 0x93, 0x2f, +0x99, 0xdb, 0x2a, 0xd2, 0x3b, 0xd3, 0xe0, 0x65, +0xb1, 0x48, 0xf6, 0xa3, 0xf1, 0x1a, 0x0e, 0x0d, +0xc4, 0x70, 0xed, 0x88, 0x8b, 0x9b, 0x62, 0x79, +0xec, 0xea, 0x77, 0xb1, 0x7a, 0xb1, 0x00, 0xac, +0x02, 0x17, 0x13, 0x49, 0x2c, 0x9e, 0x39, 0xe5, +0x83, 0x21, 0x26, 0xd0, 0xaa, 0x55, 0x31, 0xd0, +0x97, 0x36, 0x32, 0x29, 0x2d, 0xb5, 0xa8, 0x64, +0xe0, 0x52, 0x02, 0x25, 0x66, 0x34, 0x37, 0x37, +0x67, 0x0c, 0xdf, 0x32, 0x49, 0xfe, 0x1a, 0xf3, +0x91, 0x9f, 0x89, 0xc1, 0x91, 0xad, 0x99, 0xfa, +0xd4, 0xda, 0x69, 0xe3, 0xe2, 0x4c, 0x8f, 0xdf, +0x68, 0x26, 0x8b, 0x66, 0x67, 0xd7, 0xc6, 0x29, +0x1d, 0xf1, 0x4c, 0xe1, 0x62, 0x7c, 0x9c, 0x12, +0x0f, 0x00, 0xbe, 0xdf, 0x80, 0xb4, 0x8b, 0x93, +0x7d, 0x9b, 0x54, 0xe3, 0xbc, 0xc8, 0x4b, 0x6b, +0x24, 0xfe, 0x52, 0x8a, 0xf7, 0x4d, 0x19, 0xe7, +0xcf, 0xa1, 0x5c, 0x5c, 0xf1, 0xdb, 0xed, 0xdd, +0x77, 0x25, 0xf6, 0x94, 0xca, 0x18, 0x8d, 0x55, +0xb0, 0xa2, 0xad, 0xb3, 0x6e, 0x37, 0xb1, 0x4d, +0x60, 0xe8, 0xe4, 0xb9, 0x4e, 0xb1, 0xab, 0x7e, +0x1f, 0x1c, 0x3f, 0x89, 0xab, 0x0d, 0x0f, 0xd3, +0x6f, 0x71, 0xad, 0xcd, 0x63, 0xe7, 0x56, 0xf0, +0x07, 0x4f, 0x9e, 0xc3, 0x4f, 0x1e, 0xdc, 0xfa, +0x92, 0xc4, 0x3e, 0xaf, 0xd6, 0x9b, 0x78, 0xfa, +0xb9, 0x13, 0x38, 0x72, 0xe4, 0x48, 0xfb, 0x41, +0xd2, 0xc5, 0x0b, 0xc9, 0x1c, 0xce, 0xa4, 0x86, +0xed, 0xe3, 0x33, 0xd1, 0x03, 0x40, 0xf3, 0xbd, +0x37, 0x87, 0xf6, 0x39, 0x5f, 0xaa, 0x63, 0x7a, +0x71, 0x15, 0x7f, 0xf1, 0xcc, 0x79, 0x7c, 0xe2, +0xb9, 0xf3, 0x3a, 0x8d, 0x64, 0x3f, 0x72, 0xbf, +0xda, 0x20, 0x33, 0xdd, 0x9b, 0x71, 0xf0, 0x3b, +0xaf, 0xdc, 0x87, 0xb7, 0x7d, 0xe6, 0x78, 0xcf, +0x9b, 0xed, 0x86, 0x99, 0x05, 0xaf, 0x2b, 0xd7, +0x1a, 0xab, 0x77, 0xed, 0xd6, 0x7e, 0xfc, 0xe0, +0x95, 0xc3, 0x78, 0xcd, 0xf6, 0x7e, 0x4c, 0xe5, +0x3c, 0x7f, 0xad, 0x9c, 0x29, 0xd6, 0xf0, 0x8d, +0xc5, 0x12, 0x3e, 0xf5, 0x7c, 0x1e, 0x7f, 0xfd, +0xcc, 0xf9, 0xb6, 0xdd, 0xdd, 0xd2, 0xff, 0xb5, +0x5b, 0xfb, 0xf1, 0x9e, 0xab, 0xb6, 0xe0, 0x55, +0xe3, 0x59, 0x1f, 0xce, 0x6a, 0xbd, 0x89, 0x99, +0x7c, 0x19, 0x5f, 0x98, 0x2b, 0xe0, 0xff, 0x3c, +0xbb, 0x88, 0xaf, 0xcc, 0x17, 0x8c, 0x7c, 0xa1, +0xf9, 0xa3, 0x37, 0x02, 0x00, 0xe2, 0x7f, 0xfc, +0x48, 0x6f, 0xbf, 0x87, 0xb5, 0xba, 0x61, 0x6b, +0xc4, 0x54, 0xe2, 0x7f, 0xf8, 0xb5, 0xde, 0x18, +0x71, 0xb7, 0x87, 0x1d, 0x36, 0x06, 0xc2, 0x35, +0xfe, 0x87, 0x5f, 0xb3, 0xc3, 0x93, 0xf4, 0xd2, +0xe8, 0xd1, 0xe5, 0x3a, 0x71, 0x22, 0x21, 0x2b, +0x07, 0x15, 0x55, 0xe2, 0x69, 0xd4, 0x91, 0x8d, +0xb7, 0x30, 0xe9, 0xb5, 0x70, 0x30, 0x0d, 0xdc, +0x99, 0x6b, 0x61, 0x4f, 0xb2, 0x86, 0x6c, 0xb2, +0x86, 0xb8, 0x93, 0xc4, 0xc5, 0xe2, 0x2a, 0xea, +0xe5, 0x72, 0x87, 0xad, 0x58, 0x32, 0x54, 0x8d, +0x51, 0xd3, 0x67, 0xe9, 0x91, 0xae, 0x31, 0x56, +0xaa, 0x53, 0x2a, 0x95, 0x30, 0x3e, 0x3e, 0xae, +0x3a, 0xc2, 0x51, 0x3d, 0xce, 0x94, 0x66, 0x67, +0x67, 0x7d, 0xf5, 0xef, 0xd4, 0xd4, 0x14, 0x66, +0x66, 0x66, 0x7c, 0x75, 0x3b, 0xd5, 0xa3, 0xba, +0x5a, 0x3a, 0x57, 0x99, 0x04, 0x86, 0xee, 0x10, +0x97, 0x63, 0x35, 0x8d, 0x8d, 0x7f, 0x96, 0xaa, +0x71, 0x49, 0x13, 0x8d, 0x91, 0x9b, 0xc2, 0xc4, +0x6c, 0x45, 0x93, 0xcc, 0x79, 0x02, 0x1b, 0x20, +0x18, 0x56, 0x47, 0xdf, 0xf9, 0x21, 0x86, 0x1f, +0xae, 0xb8, 0x96, 0x45, 0xf6, 0xaf, 0xf9, 0x0c, +0x90, 0xb3, 0x21, 0x15, 0x32, 0x71, 0xa4, 0xfb, +0x07, 0x30, 0x3e, 0x3a, 0x8a, 0x3b, 0xc7, 0xfa, +0x70, 0xfc, 0xf9, 0x4a, 0xe7, 0xba, 0x0b, 0x5b, +0xec, 0xb6, 0x75, 0xda, 0x63, 0xf1, 0x25, 0xf3, +0x64, 0x50, 0x7b, 0xb2, 0xe9, 0x92, 0x10, 0xfb, +0xff, 0x6f, 0x1f, 0x7e, 0x01, 0x43, 0xa9, 0x04, +0xbe, 0x6f, 0xcf, 0x40, 0xcf, 0xb1, 0xcf, 0xbd, +0x96, 0x13, 0x4f, 0x1d, 0xc3, 0xa7, 0x3e, 0xfe, +0xb1, 0xf5, 0x07, 0xb5, 0x0a, 0xbe, 0x36, 0xb4, +0x67, 0x63, 0xe3, 0x0b, 0x29, 0x7d, 0x4e, 0x1c, +0x7b, 0xfb, 0x53, 0xd8, 0xdb, 0x9f, 0xc2, 0x77, +0xef, 0xc9, 0xe1, 0xaf, 0x8e, 0x0f, 0xe1, 0x07, +0x3f, 0x77, 0xbc, 0x7b, 0x06, 0xd8, 0x2b, 0x33, +0x5d, 0x7b, 0xff, 0xad, 0x77, 0x1d, 0x6a, 0x33, +0xc5, 0x5e, 0x0f, 0x69, 0x1b, 0x95, 0xcc, 0x4d, +0x87, 0x44, 0xde, 0x6f, 0xa3, 0x8e, 0x0f, 0xde, +0xb2, 0x1b, 0xbf, 0x74, 0x83, 0x9e, 0x41, 0x67, +0x47, 0x26, 0x89, 0x1d, 0x99, 0x24, 0xde, 0x3a, +0x31, 0x80, 0x5f, 0xbb, 0x71, 0x1c, 0xef, 0xfc, +0xec, 0x33, 0xf8, 0xca, 0xb9, 0x72, 0x47, 0x3f, +0x63, 0x6e, 0x1c, 0xff, 0xed, 0x8e, 0xab, 0xf0, +0xdd, 0x7b, 0x72, 0xea, 0x7c, 0xdc, 0x38, 0xd2, +0x87, 0x1b, 0x47, 0xfa, 0xf0, 0xf3, 0xd7, 0x6e, +0xc3, 0x27, 0x4e, 0x5e, 0xc4, 0xbf, 0xfc, 0xc2, +0x2c, 0xce, 0xaf, 0x96, 0xcd, 0xf3, 0xba, 0x91, +0xdf, 0x43, 0x84, 0x35, 0x62, 0x2c, 0x9b, 0x31, +0x1f, 0x51, 0xd6, 0x87, 0x9c, 0x97, 0x88, 0x6b, +0x2a, 0x94, 0x1e, 0xa6, 0xcf, 0x46, 0xc9, 0x3c, +0x8c, 0x18, 0x1a, 0xa2, 0x16, 0x55, 0x45, 0x26, +0x11, 0xc3, 0x78, 0x2a, 0x86, 0x2b, 0xbc, 0x16, +0x6e, 0x70, 0xcb, 0xb8, 0xce, 0xab, 0x61, 0xc8, +0x4b, 0x22, 0x9b, 0x4c, 0x20, 0xee, 0x24, 0xd1, +0x5c, 0xcb, 0xe9, 0x0c, 0x94, 0x51, 0x10, 0x99, +0xd3, 0xf2, 0xf9, 0x3c, 0x26, 0x27, 0x27, 0x7d, +0xa7, 0x2d, 0x62, 0x94, 0x52, 0x75, 0xcb, 0x99, +0xb1, 0x49, 0x75, 0x4b, 0x36, 0x5a, 0x9e, 0x00, +0x86, 0xc7, 0x4f, 0xf3, 0x50, 0x95, 0xa5, 0xa5, +0x25, 0x3f, 0x96, 0x5c, 0xaa, 0x8b, 0x25, 0xbc, +0xc9, 0xc9, 0x49, 0x00, 0x6d, 0xf5, 0x2f, 0x3f, +0x4c, 0xf0, 0x4c, 0x68, 0xfc, 0x3f, 0xe1, 0xcb, +0xed, 0xc1, 0x9a, 0x4a, 0x5a, 0x33, 0x0b, 0x48, +0x26, 0x2d, 0xd5, 0xe4, 0x26, 0xdb, 0xb7, 0x64, +0x92, 0x1a, 0x13, 0xa5, 0xe7, 0x51, 0xb2, 0xc6, +0x01, 0xeb, 0x8e, 0x77, 0x26, 0x7c, 0xb4, 0x08, +0x02, 0xae, 0x19, 0xb1, 0x25, 0x91, 0xe1, 0x38, +0x73, 0xb3, 0x07, 0x3f, 0x00, 0x2c, 0x9d, 0x3b, +0x8b, 0xd1, 0x2d, 0xc3, 0x78, 0xfb, 0x76, 0x17, +0xd3, 0xc5, 0x18, 0x1e, 0x3e, 0x5b, 0xe8, 0x6d, +0x53, 0xb8, 0x04, 0x92, 0xb9, 0x1b, 0x07, 0x56, +0x81, 0xe0, 0xc5, 0x15, 0x61, 0xa7, 0x7d, 0x2a, +0x61, 0xf8, 0x88, 0x76, 0xc5, 0x6a, 0x0d, 0x3f, +0xfa, 0xa5, 0xe7, 0x71, 0x61, 0xde, 0xc1, 0x4f, +0xbd, 0xe2, 0x1a, 0x00, 0x9b, 0x9b, 0x0f, 0x5c, +0x96, 0x42, 0xa5, 0x8a, 0x6a, 0xb1, 0x80, 0x23, +0x47, 0x8e, 0x60, 0xfa, 0xb1, 0x27, 0x00, 0xac, +0x85, 0x0c, 0xd5, 0x2a, 0xb8, 0x3f, 0x77, 0x35, +0x9e, 0x48, 0x6e, 0x55, 0xf1, 0xec, 0x78, 0x16, +0x42, 0xef, 0xdf, 0xfc, 0xcd, 0xdf, 0x5c, 0xcf, +0x4b, 0xbd, 0x76, 0x70, 0x24, 0x8f, 0xf0, 0xa1, +0xa1, 0x21, 0xec, 0xb9, 0x6a, 0x3f, 0xee, 0x7c, +0xf5, 0x6b, 0xf0, 0xee, 0x7d, 0xc3, 0xf8, 0xe2, +0xdc, 0x18, 0xfe, 0x78, 0x66, 0x31, 0xda, 0x9c, +0x6b, 0x9a, 0x01, 0xfa, 0x6e, 0xc3, 0x51, 0xfc, +0x27, 0x1a, 0xbf, 0xa9, 0xf8, 0x14, 0xee, 0x19, +0xb8, 0x5a, 0x6f, 0x1b, 0xa5, 0xd8, 0x84, 0xa5, +0xb0, 0xc2, 0xfb, 0x50, 0xd6, 0xd7, 0x2f, 0x5d, +0x3f, 0x8a, 0x5f, 0xba, 0x61, 0x0c, 0xab, 0xf5, +0x26, 0xfe, 0xfb, 0xd7, 0x9e, 0xc6, 0xf9, 0xe3, +0xc7, 0x70, 0x61, 0xf1, 0x1c, 0x72, 0xab, 0xe7, +0x91, 0x45, 0x03, 0xe9, 0x74, 0x1a, 0xdb, 0x76, +0xee, 0xc6, 0xcd, 0xb7, 0xdf, 0x81, 0xfd, 0x3b, +0xc7, 0x70, 0xdf, 0x77, 0x4e, 0xe1, 0xd6, 0x8f, +0x3f, 0x85, 0xc7, 0x2e, 0xac, 0x9b, 0xee, 0x76, +0xf4, 0x25, 0x71, 0xdf, 0x9b, 0xae, 0xc4, 0xc1, +0x21, 0x0f, 0xab, 0xf5, 0x26, 0xfe, 0xe2, 0x6b, +0x33, 0x38, 0xf1, 0xfc, 0xf3, 0x68, 0x9d, 0x79, +0x16, 0x6e, 0x71, 0x09, 0x6e, 0x1c, 0x18, 0x1f, +0x1f, 0xc7, 0xee, 0x43, 0xb7, 0xe0, 0xf6, 0xeb, +0x0f, 0xe2, 0xad, 0x13, 0x03, 0xf8, 0xc2, 0x5b, +0xae, 0xc2, 0x1b, 0xee, 0x79, 0x06, 0x67, 0x56, +0x4a, 0xea, 0x3a, 0xf8, 0x95, 0x33, 0x9f, 0xc4, +0xbf, 0xdb, 0xfd, 0x5d, 0x66, 0x7a, 0x6b, 0xf3, +0xc8, 0x4a, 0xfc, 0x0f, 0xbf, 0x86, 0xdf, 0x58, +0xfc, 0x0c, 0x2a, 0xcd, 0xf6, 0x6f, 0x8d, 0xd6, +0xc9, 0x07, 0x3e, 0xf0, 0x01, 0x00, 0xc0, 0xaf, +0xfe, 0xea, 0xaf, 0xaa, 0xeb, 0xe6, 0x57, 0x2a, +0x95, 0x76, 0xbf, 0xb6, 0xb9, 0x89, 0xca, 0xd0, +0x6d, 0x73, 0x22, 0xd5, 0xe3, 0x00, 0x7e, 0x63, +0xe1, 0x1e, 0xfc, 0xda, 0xc8, 0x5d, 0xe1, 0xed, +0xb4, 0xb1, 0x9b, 0x3e, 0x87, 0x8c, 0xc1, 0x09, +0xfd, 0x11, 0x98, 0x06, 0x2c, 0xfe, 0x5f, 0xe3, +0x56, 0x71, 0x6b, 0xb6, 0x85, 0x9b, 0xdc, 0x12, +0xfa, 0x13, 0x2d, 0x6c, 0x4d, 0xb6, 0x37, 0xe8, +0xb8, 0xe3, 0x61, 0xb5, 0xb0, 0x82, 0xfc, 0x9a, +0x47, 0x32, 0xdf, 0xd4, 0x89, 0x69, 0x4b, 0xb5, +0xae, 0xa6, 0x7e, 0x96, 0x21, 0x67, 0xd2, 0x3b, +0x9d, 0x33, 0x6e, 0x2d, 0x3c, 0x8a, 0xb7, 0x95, +0x8c, 0x3a, 0x9d, 0x4e, 0xab, 0xea, 0x61, 0x6a, +0x07, 0x20, 0xe0, 0x15, 0x6e, 0x53, 0x1d, 0x4b, +0x5c, 0x25, 0x4c, 0x93, 0x07, 0x3e, 0xff, 0xce, +0x19, 0xb5, 0x4c, 0x28, 0xa3, 0x25, 0x80, 0x31, +0xc1, 0xe1, 0xdf, 0x4d, 0x92, 0x7c, 0x94, 0xe2, +0xba, 0xae, 0xef, 0x6c, 0x37, 0x36, 0x36, 0x16, +0x08, 0xe7, 0x93, 0xce, 0x70, 0x44, 0x63, 0x99, +0x0b, 0x9e, 0x87, 0xe3, 0xc9, 0xbe, 0xb5, 0x03, +0x19, 0xf5, 0xc3, 0xc7, 0x3b, 0x3f, 0x3f, 0x8f, +0xbd, 0x03, 0x83, 0xf8, 0xbe, 0x31, 0x07, 0x0f, +0x9f, 0x85, 0xbe, 0x29, 0xf6, 0xc0, 0xd0, 0x8b, +0xb5, 0x46, 0x4f, 0x89, 0x23, 0xf8, 0x3a, 0x01, +0xb0, 0x9e, 0x22, 0xb2, 0x57, 0x8d, 0x81, 0x56, +0x57, 0x3e, 0x5b, 0xfb, 0xfc, 0x6f, 0x66, 0xea, +0x58, 0x9c, 0xff, 0x0c, 0xfe, 0xf9, 0xb5, 0xbb, +0x30, 0x39, 0x39, 0x89, 0x4c, 0x26, 0xd3, 0xf3, +0xa5, 0x29, 0xb2, 0x14, 0x2a, 0x55, 0x64, 0xdd, +0x14, 0x2e, 0x5c, 0xb8, 0x80, 0x63, 0xc7, 0x8e, +0xe1, 0xe8, 0xd1, 0xa3, 0xfe, 0xfc, 0xd3, 0x7a, +0xf8, 0x66, 0xff, 0x04, 0x1e, 0xeb, 0xdf, 0x03, +0x28, 0x59, 0xbf, 0xba, 0x92, 0x38, 0xc5, 0x3a, +0x03, 0x10, 0x08, 0xeb, 0x02, 0xda, 0xbf, 0xbd, +0xa5, 0xa5, 0x25, 0xb4, 0xaa, 0x15, 0xbc, 0xf9, +0xcd, 0x6f, 0xc6, 0xfb, 0xf6, 0xa4, 0xf0, 0x37, +0xc7, 0x6a, 0x28, 0x24, 0x92, 0xd1, 0xfb, 0xd1, +0x36, 0xc8, 0x6e, 0xda, 0xae, 0x95, 0x1b, 0xf2, +0x4f, 0xaf, 0x33, 0xf3, 0xcd, 0x50, 0xab, 0x13, +0x9c, 0xa8, 0xeb, 0xd7, 0xa2, 0x7e, 0xfd, 0xa9, +0xab, 0xb7, 0x01, 0x00, 0xfe, 0xbf, 0x8f, 0xde, +0x8b, 0xfa, 0x53, 0x8f, 0x20, 0xd1, 0x04, 0xb6, +0xd6, 0xd6, 0x13, 0x04, 0x51, 0xa2, 0xa8, 0xa7, +0x9f, 0x7a, 0x0a, 0xef, 0xfc, 0x9e, 0xef, 0xc2, +0xd5, 0x57, 0x5f, 0x8d, 0x3f, 0xb9, 0x3a, 0x89, +0x9b, 0x1f, 0x5c, 0xf1, 0xe1, 0xfc, 0xfe, 0x2b, +0x26, 0x70, 0x70, 0xc8, 0xc3, 0x57, 0x17, 0x8a, +0xf8, 0xd0, 0xdf, 0xfe, 0x2d, 0xb6, 0x5d, 0x7c, +0x01, 0xa9, 0xb5, 0xc3, 0x1b, 0xc1, 0xa1, 0x3c, +0x09, 0x4f, 0x1f, 0x1d, 0xc3, 0xbb, 0xde, 0xf5, +0x2e, 0x1c, 0x1c, 0x1e, 0xc6, 0xdf, 0xbe, 0x6e, +0x2f, 0x5e, 0xf1, 0xd1, 0x27, 0xd4, 0xb9, 0x75, +0x5d, 0x77, 0xc3, 0x12, 0x31, 0x4f, 0x74, 0x24, +0xfd, 0x88, 0xf8, 0x77, 0x9e, 0x2f, 0x3d, 0xd0, +0xaf, 0x69, 0xbe, 0x4c, 0x74, 0x8f, 0x32, 0xbf, +0xbc, 0x2d, 0x7d, 0x96, 0xc5, 0xb4, 0xce, 0x6c, +0xf3, 0xae, 0xc1, 0xb5, 0xf5, 0xbd, 0xb6, 0xa6, +0x37, 0x74, 0x9f, 0x79, 0xb6, 0x55, 0xc3, 0xed, +0x43, 0x31, 0xbc, 0x3a, 0x57, 0xc3, 0xf5, 0x6e, +0x15, 0x4e, 0xa3, 0x1d, 0x9a, 0xe4, 0x25, 0x83, +0xd2, 0x63, 0x3d, 0x91, 0x04, 0xa5, 0x01, 0xe5, +0x52, 0x17, 0xbf, 0x26, 0x94, 0x3e, 0xcb, 0x98, +0x6d, 0x1e, 0x9b, 0x4c, 0xed, 0xe4, 0x7f, 0xee, +0x75, 0xad, 0xc5, 0x2b, 0xd3, 0x3b, 0x0a, 0x2b, +0x3b, 0x7b, 0xb1, 0x88, 0x6d, 0x03, 0x99, 0x0e, +0xd5, 0xb8, 0x84, 0x2b, 0x3d, 0xd1, 0x49, 0x5b, +0x20, 0x0f, 0x1a, 0x52, 0xbd, 0x1e, 0x26, 0x85, +0x9a, 0x0e, 0x1a, 0x36, 0x69, 0xda, 0xe4, 0xa1, +0xaf, 0xc1, 0xe6, 0x0c, 0x54, 0x3a, 0xdf, 0x85, +0x15, 0x53, 0x5b, 0x1a, 0x3f, 0x3f, 0x08, 0x90, +0x46, 0x03, 0x40, 0xe0, 0x6e, 0x74, 0xee, 0x0c, +0xc8, 0xb3, 0xf1, 0x99, 0xf0, 0x21, 0xfa, 0x49, +0x4f, 0x7f, 0x29, 0xf5, 0xe7, 0xf3, 0x79, 0xbc, +0xf0, 0xfc, 0x49, 0x5c, 0xbb, 0x7b, 0x3f, 0xc6, +0xfa, 0x52, 0x98, 0x5f, 0x65, 0x0e, 0x68, 0x51, +0x0f, 0xa2, 0xca, 0xb3, 0xe7, 0x56, 0x80, 0x57, +0x7d, 0xe2, 0x29, 0x00, 0xeb, 0x49, 0x47, 0xb4, +0x38, 0x71, 0x99, 0xdc, 0x81, 0x9e, 0x93, 0xcd, +0x9c, 0xae, 0x2a, 0xed, 0x59, 0x8d, 0xa8, 0x9d, +0xc0, 0x2d, 0xf8, 0xff, 0xf7, 0x8b, 0x43, 0xf8, +0xc6, 0xbd, 0xd3, 0x78, 0x75, 0xf3, 0xd3, 0x18, +0x1b, 0x1e, 0xc2, 0xf8, 0xee, 0x09, 0x4c, 0x6c, +0x1f, 0x87, 0xeb, 0xba, 0x18, 0x1e, 0x1e, 0xee, +0xc8, 0x51, 0x60, 0xca, 0x0e, 0x46, 0xc9, 0x6c, +0x4a, 0xa5, 0x12, 0x96, 0x97, 0x97, 0x31, 0x33, +0x33, 0xe3, 0xaf, 0x7f, 0x1a, 0x9f, 0xeb, 0xba, +0xed, 0x94, 0xa2, 0xf1, 0x04, 0x66, 0x52, 0x5b, +0x71, 0x5f, 0xee, 0x5a, 0x63, 0x68, 0x53, 0xa4, +0x31, 0x8b, 0xb1, 0x56, 0x9a, 0xc0, 0xbf, 0xdb, +0x76, 0xd7, 0xfa, 0xf8, 0x08, 0xc6, 0xda, 0xf7, +0x4c, 0xad, 0x84, 0x6b, 0x9e, 0x3d, 0x87, 0x37, +0x03, 0xd8, 0xbf, 0x73, 0x0c, 0x37, 0xaf, 0x7c, +0x1e, 0xf7, 0x67, 0xda, 0x59, 0xf7, 0x76, 0xf4, +0xa7, 0xf1, 0xbe, 0xeb, 0x46, 0xf1, 0x86, 0x9d, +0x03, 0xfe, 0x5d, 0xef, 0xcf, 0xad, 0x54, 0x71, +0xdf, 0xa9, 0x65, 0xfc, 0xee, 0xe3, 0xe7, 0x3a, +0x6e, 0xe2, 0xbb, 0x76, 0x6b, 0x3f, 0x7e, 0xf1, +0xfa, 0x51, 0xdc, 0x39, 0xde, 0x8f, 0x1d, 0x99, +0xa4, 0x5f, 0x7f, 0x7a, 0x71, 0x15, 0x1f, 0x3a, +0x7e, 0x01, 0x7f, 0xff, 0xec, 0xa2, 0x8f, 0x97, +0xb4, 0xd7, 0x7e, 0xe0, 0x03, 0x1f, 0xc0, 0x07, +0xd6, 0x3e, 0xc7, 0xff, 0xf8, 0x11, 0xff, 0xf9, +0xed, 0x5b, 0x3d, 0xfc, 0x3f, 0x37, 0xec, 0xc4, +0xeb, 0x76, 0xb4, 0xef, 0x2f, 0x7f, 0x72, 0xa9, +0x8c, 0xff, 0xfe, 0xe4, 0x39, 0xfc, 0xfe, 0x93, +0xe7, 0xd6, 0xed, 0xa8, 0x54, 0xbf, 0xb1, 0x6e, +0x5b, 0xdd, 0xf7, 0xa1, 0xc7, 0xf1, 0xe1, 0xd7, +0x4d, 0xe1, 0xc6, 0x91, 0x3e, 0x7c, 0xea, 0xf9, +0x8b, 0x78, 0xcb, 0x7d, 0xc7, 0xfd, 0x71, 0x8f, +0xb9, 0x71, 0xbc, 0xef, 0xd0, 0x44, 0xe0, 0x0e, +0xfb, 0x33, 0xc5, 0x1a, 0x3e, 0x71, 0x32, 0x8f, +0x3f, 0x3c, 0xb6, 0x88, 0xc7, 0xce, 0xad, 0x04, +0xd6, 0xc9, 0x90, 0xdb, 0x8e, 0x26, 0xa9, 0x3f, +0xf5, 0x08, 0x0a, 0x48, 0xe0, 0x4b, 0x99, 0x3d, +0x38, 0xee, 0x8d, 0xa2, 0x94, 0xec, 0xf3, 0xe7, +0x2a, 0x53, 0x2b, 0x61, 0xb0, 0x55, 0xc6, 0xb3, +0x5f, 0x7c, 0x12, 0x7f, 0x7d, 0xf5, 0xd5, 0x38, +0xb8, 0x6f, 0x2f, 0x5e, 0xf3, 0xa9, 0x87, 0x70, +0x7f, 0xe6, 0x4a, 0xdc, 0xb5, 0xa3, 0x1f, 0x6f, +0x9d, 0x18, 0xc0, 0x99, 0x62, 0x0d, 0x9f, 0xfe, +0xf3, 0xff, 0x81, 0x6d, 0xd5, 0x55, 0x2c, 0xc5, +0x52, 0x38, 0x9a, 0xd9, 0x8d, 0xe7, 0x93, 0x39, +0x2c, 0x7b, 0x43, 0x28, 0xc4, 0x92, 0xc8, 0xb6, +0x6a, 0xd8, 0x56, 0x5f, 0xc1, 0x64, 0x69, 0x01, +0xf9, 0x3f, 0xf9, 0x53, 0xfc, 0xec, 0xcf, 0xfc, +0x0c, 0x6e, 0x1b, 0xcd, 0xe0, 0x47, 0xf6, 0x64, +0xf0, 0x3f, 0x9f, 0x37, 0x84, 0x8a, 0x45, 0x3d, +0x64, 0x19, 0xea, 0x77, 0x48, 0xd8, 0x09, 0x07, +0xef, 0x67, 0xe0, 0x7f, 0x6d, 0xf4, 0x4d, 0xd6, +0x35, 0xb6, 0xa3, 0x2f, 0x89, 0xf7, 0x5d, 0xb7, +0x13, 0xff, 0x6c, 0x32, 0x87, 0xbd, 0xfd, 0xed, +0xdf, 0xf1, 0x93, 0x4b, 0x65, 0x7c, 0x61, 0x6e, +0xa5, 0xbd, 0x46, 0x96, 0xcb, 0x9d, 0xfd, 0x26, +0x1c, 0xec, 0xe8, 0x4b, 0xe2, 0x97, 0x6f, 0xd8, +0x85, 0x37, 0xec, 0x1a, 0xec, 0x68, 0xf7, 0x9f, +0xbf, 0x71, 0x0a, 0xcf, 0x15, 0x15, 0xe6, 0x8c, +0x35, 0xed, 0x41, 0x84, 0xf5, 0xf6, 0x17, 0xcf, +0x9c, 0xc7, 0x27, 0x4e, 0x2e, 0x9b, 0x0f, 0x6c, +0xf2, 0xb7, 0x24, 0x7f, 0x5f, 0x01, 0x35, 0x7b, +0xd8, 0x49, 0x49, 0x0e, 0x10, 0xed, 0x64, 0x2e, +0xdf, 0xb3, 0x15, 0xd8, 0x9b, 0x02, 0xae, 0x77, +0xcb, 0xa8, 0x17, 0x57, 0x50, 0xaf, 0x03, 0x8b, +0xf9, 0x3c, 0x46, 0x76, 0xec, 0x02, 0x1a, 0x6d, +0xc9, 0xc6, 0xc9, 0xf4, 0xa3, 0x0e, 0xa0, 0x70, +0xfe, 0x5c, 0x47, 0x8a, 0x54, 0x2a, 0x5c, 0x5a, +0x96, 0x8c, 0x55, 0x3a, 0x91, 0x51, 0xc9, 0xe5, +0x72, 0x58, 0x5a, 0x5a, 0xf2, 0xe3, 0x9e, 0xa5, +0xfa, 0x59, 0xb3, 0x49, 0xd3, 0xfb, 0xf9, 0xf9, +0x79, 0xa4, 0xc4, 0x3b, 0xba, 0x79, 0x8c, 0x98, +0x10, 0xe5, 0x62, 0xe7, 0x8c, 0x5d, 0xaa, 0xd2, +0x6d, 0xea, 0x63, 0xd3, 0x77, 0x2d, 0x14, 0x4c, +0x86, 0xb4, 0x45, 0x29, 0x1a, 0x1c, 0x2d, 0xb4, +0x4d, 0xd2, 0x41, 0x3a, 0x04, 0xf2, 0xfa, 0x9a, +0xca, 0x9d, 0x1f, 0x64, 0xf8, 0xe9, 0x57, 0x66, +0xc4, 0xe3, 0x61, 0x77, 0x32, 0x7e, 0x9e, 0xfc, +0x04, 0xb8, 0x2d, 0x5d, 0xd2, 0x82, 0xe2, 0xf8, +0x4d, 0x0c, 0x9f, 0xfa, 0x23, 0x6f, 0xfa, 0xa9, +0x5c, 0x0e, 0xff, 0x7a, 0xdf, 0x16, 0xdc, 0x3d, +0xd3, 0x0a, 0xde, 0xae, 0xa6, 0x6d, 0x06, 0xca, +0xfa, 0xd5, 0xd6, 0x3c, 0x25, 0xb7, 0x08, 0x24, +0x8e, 0x08, 0x24, 0xa0, 0x58, 0x4f, 0x20, 0x01, +0xf0, 0x64, 0x1a, 0x09, 0xb4, 0xe2, 0xc9, 0xf5, +0x8b, 0x2b, 0xa2, 0x9e, 0xfc, 0x7b, 0xfd, 0xcf, +0xf0, 0x2f, 0x34, 0xea, 0xb8, 0x3f, 0x73, 0x25, +0x2e, 0x96, 0xd3, 0xb8, 0x63, 0xfe, 0x38, 0x66, +0xcf, 0xcc, 0xe1, 0x91, 0xf8, 0xba, 0x74, 0xc2, +0xb3, 0xaf, 0x01, 0x11, 0x32, 0xb0, 0xad, 0x15, +0x29, 0x21, 0x03, 0x6d, 0x66, 0x7b, 0x32, 0x39, +0x8c, 0xfb, 0x07, 0xf6, 0xb7, 0xc3, 0xaa, 0x00, +0x04, 0x42, 0x71, 0xba, 0x95, 0xc8, 0xa5, 0xf4, +0x46, 0xca, 0x04, 0x83, 0x30, 0x51, 0x8c, 0x27, +0xf1, 0x78, 0xb6, 0x7d, 0x93, 0xda, 0x6a, 0xbd, +0x89, 0x9b, 0x4a, 0xcf, 0xe3, 0xfe, 0x81, 0x03, +0x78, 0xeb, 0xc4, 0x20, 0xfe, 0xfa, 0x35, 0x7b, +0x3a, 0xb4, 0x11, 0x7b, 0xfb, 0x53, 0xf8, 0x89, +0x83, 0x5b, 0xf1, 0x43, 0x57, 0x6d, 0xc1, 0xcf, +0x1f, 0x39, 0xdd, 0x56, 0xcb, 0x37, 0xea, 0xb8, +0x6b, 0xf7, 0x10, 0xfe, 0xcf, 0x5d, 0x57, 0xa8, +0xf5, 0xc9, 0x2e, 0xff, 0xd3, 0x7d, 0x49, 0xfc, +0xfe, 0x93, 0xe7, 0x42, 0x55, 0xac, 0xd9, 0x56, +0x0d, 0x85, 0x66, 0x0c, 0xef, 0x39, 0x30, 0x86, +0xff, 0x76, 0xfb, 0xce, 0x00, 0xcc, 0x83, 0x43, +0x1e, 0x7e, 0xef, 0xf6, 0x5d, 0xd8, 0x3b, 0xc0, +0xa4, 0x48, 0x45, 0x82, 0xfb, 0xa3, 0x3b, 0x26, +0x70, 0xe3, 0x48, 0x3b, 0x61, 0x4e, 0xbe, 0xba, +0x4e, 0xcf, 0x57, 0x8c, 0x66, 0xf0, 0x89, 0x37, +0xee, 0xeb, 0xb8, 0x86, 0x75, 0x47, 0x26, 0xa9, +0x8e, 0x0b, 0x00, 0xa6, 0xcf, 0x97, 0x70, 0xdb, +0x68, 0x06, 0xdf, 0xfd, 0x8e, 0x77, 0xe2, 0x9f, +0x7f, 0x3d, 0x8f, 0x47, 0x56, 0x9a, 0x9d, 0xeb, +0x3c, 0x99, 0x46, 0x11, 0x69, 0x7c, 0x08, 0x43, +0xf8, 0xe2, 0xef, 0x7f, 0x1e, 0x3f, 0x3c, 0xff, +0x20, 0xae, 0xf7, 0xfa, 0x71, 0x7f, 0xe6, 0x4a, +0xfc, 0xe0, 0x55, 0x5b, 0x00, 0x00, 0x5f, 0xfa, +0xd2, 0x17, 0xe1, 0x56, 0x57, 0x71, 0x2c, 0xb5, +0x0d, 0x9f, 0xcc, 0x5d, 0x1f, 0xbc, 0xf7, 0xbb, +0xd1, 0x0e, 0xb7, 0x2a, 0x24, 0x87, 0xf1, 0x5c, +0x7c, 0x00, 0x5f, 0x8b, 0xef, 0xc3, 0x96, 0x2f, +0x7e, 0x03, 0xef, 0x7d, 0xfd, 0xad, 0xf8, 0xd9, +0x9d, 0xc0, 0x87, 0x4e, 0xd6, 0xd6, 0x0f, 0x79, +0x6b, 0xa5, 0x52, 0xa9, 0x74, 0xb7, 0xbe, 0xa3, +0x9a, 0x4d, 0x22, 0xc2, 0x7f, 0xeb, 0xde, 0x2d, +0xea, 0x1a, 0x39, 0x38, 0xe4, 0xe1, 0xe0, 0x90, +0x87, 0x1f, 0xba, 0x6a, 0x0b, 0x7e, 0xee, 0xf3, +0xc7, 0xda, 0x07, 0x91, 0x2e, 0xdb, 0xfd, 0xfc, +0x91, 0xd3, 0xf8, 0xe3, 0x27, 0xe6, 0x3b, 0xe6, +0x95, 0x7e, 0x37, 0x77, 0xed, 0x1e, 0xc2, 0xbd, +0x6f, 0xba, 0xb2, 0x63, 0xed, 0x04, 0xd6, 0xdb, +0x57, 0x4e, 0xe1, 0xf7, 0x1f, 0x9b, 0x8b, 0xcc, +0x7f, 0x4d, 0xfb, 0x8b, 0x63, 0xfa, 0x71, 0x69, +0x8d, 0x33, 0x89, 0x18, 0xae, 0x4f, 0xd7, 0xf1, +0x03, 0x13, 0x19, 0xbc, 0xdc, 0x2d, 0x61, 0xe1, +0xc2, 0x0a, 0x16, 0xcf, 0x2c, 0x04, 0x1c, 0xc8, +0xb2, 0xc9, 0x04, 0x90, 0x4c, 0xa0, 0x5c, 0x2e, +0x23, 0xbb, 0xf6, 0x9f, 0x0a, 0xdf, 0xa0, 0x89, +0x79, 0xf2, 0xb4, 0xa6, 0x9c, 0xa1, 0x72, 0x29, +0x9b, 0x33, 0x68, 0x6a, 0x4f, 0xaa, 0x71, 0x29, +0x91, 0xcb, 0xfe, 0x38, 0x33, 0x5f, 0x5a, 0x5a, +0x42, 0x2e, 0x97, 0xeb, 0xc8, 0xc6, 0xc5, 0x73, +0xaf, 0xf3, 0xf4, 0xa9, 0x3c, 0xf6, 0x99, 0xab, +0xef, 0xb9, 0x3d, 0x9e, 0xf7, 0xa5, 0xe1, 0xc3, +0x55, 0xe4, 0x84, 0xbb, 0xf6, 0x9f, 0x17, 0xa2, +0x0f, 0xf7, 0x0e, 0xd7, 0xcc, 0x0e, 0xbc, 0x3e, +0xd7, 0x1e, 0x98, 0x0e, 0x05, 0x1a, 0x6d, 0xb4, +0xba, 0xf2, 0x80, 0x42, 0x0b, 0x93, 0xfc, 0x0c, +0x64, 0x18, 0x19, 0x1d, 0x86, 0xc8, 0x31, 0x50, +0xe2, 0xc3, 0x71, 0xe4, 0xe6, 0x14, 0x69, 0x02, +0x30, 0x39, 0x3e, 0x7a, 0x9e, 0xe7, 0xe7, 0x05, +0xc8, 0xe7, 0xf3, 0x98, 0x9e, 0x9e, 0xc6, 0xa1, +0xa9, 0x29, 0xbc, 0x6b, 0xc7, 0x58, 0xf0, 0x07, +0x28, 0x17, 0x7a, 0x37, 0xcf, 0xd6, 0xfe, 0x1f, +0xc9, 0xec, 0xc1, 0xc9, 0xd4, 0xb0, 0x4a, 0x3f, +0x53, 0xe2, 0x08, 0x80, 0x27, 0xe1, 0x90, 0x8d, +0xba, 0xb4, 0xab, 0x86, 0x49, 0xe6, 0xca, 0xfb, +0x87, 0xbd, 0x9d, 0x98, 0xe9, 0xdb, 0x81, 0x89, +0xca, 0x22, 0xa6, 0x4a, 0x73, 0xd8, 0x1a, 0x5b, +0xc6, 0x40, 0xab, 0xea, 0x1f, 0x3e, 0x78, 0xb6, +0xae, 0xca, 0x5a, 0x16, 0x38, 0x9e, 0x89, 0x0b, +0x6b, 0x19, 0xd8, 0xa8, 0x5e, 0x61, 0x6d, 0x10, +0x35, 0xaf, 0x1f, 0x2f, 0xc4, 0xfb, 0x70, 0x32, +0x37, 0x84, 0xa7, 0x92, 0x5b, 0x7c, 0xc9, 0xac, +0x43, 0x92, 0xb2, 0xe1, 0x17, 0x55, 0x2b, 0xa1, +0xd1, 0x41, 0x6c, 0x56, 0x3f, 0x7d, 0x4d, 0x5b, +0x8d, 0xfc, 0xc2, 0xec, 0x73, 0xc8, 0xa2, 0x81, +0xbd, 0xfd, 0x29, 0x7f, 0xb3, 0xfd, 0xda, 0xa9, +0x73, 0xf8, 0xc8, 0x57, 0xbe, 0x81, 0xd2, 0xb3, +0x4f, 0x60, 0x5b, 0xab, 0xed, 0xe8, 0xfa, 0xca, +0xd7, 0xbe, 0x1e, 0x57, 0x4e, 0xee, 0xc6, 0xff, +0xb8, 0x63, 0x37, 0x4e, 0xae, 0x54, 0xf0, 0x99, +0xe7, 0x97, 0xf0, 0x3b, 0xb7, 0xee, 0x42, 0x9f, +0x13, 0xc7, 0x7f, 0xfe, 0xea, 0x0c, 0x9e, 0x7d, +0x6c, 0x1a, 0x03, 0xe7, 0x4e, 0x20, 0xd9, 0x6c, +0x20, 0x97, 0x49, 0xe3, 0x9a, 0xdb, 0x5e, 0x85, +0x37, 0xdc, 0x7a, 0x13, 0x7e, 0xfd, 0xfa, 0x2d, +0xfe, 0xe6, 0x1a, 0xff, 0xe3, 0x47, 0xf0, 0x1b, +0x0b, 0xf7, 0xe0, 0xfd, 0xef, 0x6f, 0xcb, 0x81, +0x64, 0xdb, 0x77, 0x5d, 0x17, 0x3f, 0x51, 0x6b, +0xe2, 0x63, 0x57, 0xbf, 0xdd, 0x67, 0xe4, 0x1f, +0x9d, 0x79, 0x01, 0x9f, 0xfd, 0xc2, 0x17, 0xb1, +0x65, 0xe1, 0x38, 0x46, 0xb7, 0x6d, 0xc3, 0xed, +0xb7, 0xdf, 0x86, 0x9f, 0xbf, 0xf6, 0x1a, 0x7f, +0x48, 0xbf, 0xb1, 0xf8, 0x99, 0xb6, 0x1d, 0x95, +0xad, 0x83, 0x43, 0xe9, 0x1a, 0x6e, 0xfa, 0xab, +0x87, 0x71, 0xf3, 0xec, 0x17, 0xb0, 0x23, 0xd5, +0xc2, 0x0f, 0xd4, 0xfb, 0xf0, 0xc0, 0xee, 0x3b, +0xf0, 0x89, 0x37, 0xee, 0x43, 0xad, 0xd9, 0xc2, +0x2f, 0x7f, 0xed, 0x0c, 0xf2, 0x8f, 0x7e, 0x09, +0xce, 0xe2, 0x19, 0x6c, 0x6b, 0xb5, 0x7f, 0x7f, +0x3b, 0xae, 0x3e, 0x84, 0xb7, 0xdc, 0x71, 0x18, +0xff, 0xe3, 0x8e, 0xdd, 0x38, 0xb6, 0x54, 0xc2, +0x97, 0x5f, 0x68, 0x47, 0xbc, 0xfc, 0xc4, 0x97, +0x9f, 0xc7, 0x91, 0x7f, 0xb6, 0x1f, 0x07, 0xaf, +0xda, 0x87, 0x87, 0xaf, 0x6a, 0x4b, 0x90, 0x47, +0x16, 0x0a, 0x98, 0x3e, 0x5f, 0xc2, 0x33, 0xcb, +0x65, 0x7c, 0x6b, 0xb1, 0xd8, 0xd6, 0x66, 0xad, +0xd1, 0xf3, 0x85, 0x44, 0xff, 0xba, 0xc4, 0x9b, +0x70, 0x70, 0xe7, 0x78, 0x3f, 0x00, 0xe0, 0xfc, +0xb3, 0x33, 0x78, 0x21, 0x96, 0xc6, 0xdf, 0x0c, +0x1c, 0x5a, 0x4b, 0x84, 0x82, 0xe0, 0x9c, 0x33, +0xfc, 0x0b, 0xb1, 0x24, 0xfe, 0xfb, 0xc5, 0x34, +0xde, 0x0b, 0x60, 0x72, 0x72, 0x12, 0xd7, 0xde, +0xfb, 0x49, 0x1c, 0x19, 0xb8, 0xaa, 0x73, 0xad, +0x6b, 0xeb, 0x5f, 0xfb, 0x3d, 0x98, 0x0e, 0xe5, +0x61, 0xbf, 0x23, 0x43, 0xbd, 0xbd, 0x19, 0x27, +0xd2, 0x1a, 0xf9, 0xa3, 0x37, 0x5c, 0x8d, 0x99, +0x4f, 0x3c, 0x85, 0x2f, 0x2f, 0x14, 0x01, 0x40, +0x6d, 0xb7, 0xf2, 0xec, 0x13, 0xd8, 0xde, 0x2a, +0x61, 0xcf, 0x9e, 0x3d, 0xb8, 0xe5, 0x96, 0x5b, +0xb0, 0x6f, 0xdf, 0xbe, 0xf5, 0xb5, 0x75, 0x66, +0x45, 0x1d, 0xcb, 0x1f, 0xdc, 0xd1, 0x3e, 0x80, +0xd2, 0x7a, 0x4b, 0x2f, 0x3e, 0x8f, 0xa1, 0x56, +0x15, 0x7d, 0xb9, 0x21, 0xdc, 0x70, 0xfd, 0xf5, +0x78, 0xf5, 0x1d, 0xaf, 0xc0, 0x2f, 0x5d, 0x9d, +0x6b, 0xaf, 0x37, 0x39, 0x8e, 0x28, 0xbf, 0x2f, +0xab, 0x64, 0x2e, 0x1b, 0xb3, 0x0d, 0xe6, 0xdd, +0x5b, 0x9b, 0xf8, 0xae, 0x91, 0x18, 0xb2, 0xcd, +0x25, 0xe4, 0xf3, 0x65, 0x2c, 0x9d, 0x5d, 0x50, +0x6d, 0xb5, 0x32, 0x34, 0x8c, 0x3e, 0x97, 0xcb, +0x65, 0xdf, 0x43, 0x5c, 0x4a, 0x8a, 0x53, 0x53, +0x53, 0x01, 0x27, 0x31, 0xae, 0x5e, 0xe7, 0x4c, +0x53, 0xe6, 0x34, 0x97, 0x36, 0xe4, 0x52, 0xa9, +0x14, 0x60, 0x24, 0xbc, 0xbf, 0x4a, 0xa5, 0x82, +0x93, 0x27, 0x4f, 0x06, 0xec, 0xeb, 0xa6, 0xc3, +0x86, 0xe6, 0x9c, 0xc5, 0xc3, 0xe1, 0x34, 0x86, +0xa3, 0x31, 0x66, 0x53, 0xc8, 0x9c, 0x56, 0xa4, +0x59, 0xc0, 0x06, 0xd7, 0xe4, 0x88, 0x66, 0xea, +0x57, 0x0b, 0x3d, 0x33, 0xf9, 0x16, 0x10, 0xed, +0x88, 0xf1, 0x72, 0x5b, 0x29, 0x31, 0x74, 0x0a, +0x53, 0xe3, 0xd7, 0xb4, 0xca, 0xbe, 0x4d, 0xb4, +0xe1, 0xd2, 0xb7, 0xd4, 0xc8, 0xf0, 0x83, 0x13, +0xcd, 0x3b, 0xad, 0x0b, 0x7e, 0x08, 0x9b, 0x99, +0x99, 0xc1, 0xeb, 0x0e, 0x78, 0x38, 0xda, 0xe7, +0xe2, 0xf1, 0x15, 0x74, 0x6e, 0x36, 0x61, 0x52, +0xa2, 0xf2, 0x63, 0xa0, 0x0d, 0x6e, 0x5d, 0xf2, +0x84, 0x79, 0x03, 0xe9, 0x55, 0x1a, 0x35, 0xf4, +0xdb, 0x01, 0xa7, 0x4b, 0xc9, 0xbe, 0xd0, 0xa8, +0xe3, 0x09, 0x6f, 0xdc, 0x4f, 0x50, 0x31, 0xdc, +0xaa, 0x20, 0xd1, 0xac, 0x63, 0xb0, 0x59, 0x46, +0xae, 0x51, 0xb2, 0x66, 0xb0, 0xe2, 0xcf, 0xf3, +0x89, 0x34, 0x96, 0xe3, 0xed, 0x79, 0xe3, 0xea, +0x59, 0x95, 0x1e, 0x9b, 0x31, 0x5e, 0x59, 0x44, +0x9d, 0x4c, 0x22, 0x86, 0x03, 0x39, 0x17, 0x3f, +0x3c, 0xd5, 0x96, 0x46, 0x01, 0xe0, 0xa1, 0x87, +0x1e, 0xc2, 0xd9, 0x58, 0x1a, 0xff, 0xfa, 0xba, +0x51, 0xf4, 0x39, 0x71, 0x7c, 0xe6, 0xf8, 0x1c, +0xbe, 0xf4, 0xd7, 0x7f, 0x82, 0xfe, 0x38, 0x90, +0xaa, 0x54, 0x50, 0x49, 0xb6, 0x2f, 0xac, 0xf8, +0xdb, 0xbf, 0xfc, 0x0b, 0xbc, 0xf3, 0x9d, 0xef, +0xc4, 0xbe, 0x7d, 0xfb, 0xf0, 0x5f, 0xaf, 0xeb, +0xc7, 0x81, 0x33, 0x2b, 0xbe, 0xba, 0xda, 0xfd, +0xd6, 0x17, 0xb1, 0x7d, 0xf1, 0xac, 0xcf, 0x98, +0xf3, 0xf9, 0x3c, 0xbe, 0xfe, 0xf9, 0x7b, 0xf1, +0xf5, 0xcf, 0xdf, 0x8b, 0x4a, 0xa5, 0x82, 0x9b, +0xb6, 0xdc, 0x80, 0x87, 0xbd, 0x9d, 0x00, 0x3a, +0x2f, 0x3c, 0x22, 0x73, 0x45, 0xbf, 0xeb, 0xe2, +0xbd, 0x6b, 0x57, 0xa4, 0x7e, 0xe6, 0xb1, 0xe3, +0x78, 0xe2, 0xe3, 0x1f, 0xc2, 0x96, 0x35, 0x78, +0x0b, 0x67, 0x4e, 0xe1, 0xff, 0x7c, 0xf4, 0x63, +0x48, 0xc5, 0x63, 0xb8, 0xfa, 0xea, 0xab, 0x83, +0x70, 0xd8, 0xd8, 0x1f, 0x78, 0xe0, 0x01, 0x5c, +0xff, 0xfc, 0x1c, 0xb6, 0x94, 0xf3, 0x68, 0xb5, +0x5c, 0x5c, 0x48, 0x8f, 0xe2, 0x67, 0xaf, 0xdd, +0x86, 0x5c, 0x2a, 0x81, 0x77, 0xfe, 0xdd, 0x51, +0x5c, 0x79, 0xec, 0x73, 0xd8, 0x4e, 0x4e, 0x5f, +0x6b, 0xbf, 0xbf, 0xe3, 0x0f, 0x1f, 0xc1, 0x9f, +0xcd, 0x3e, 0x8b, 0x7f, 0xf5, 0xde, 0x1f, 0xc3, +0xfb, 0x0f, 0x0e, 0xe0, 0x8d, 0x6b, 0x0c, 0xe8, +0xb1, 0x73, 0x2b, 0xf8, 0x85, 0x3f, 0xf9, 0x30, +0x7e, 0xf4, 0xb6, 0x6b, 0xb0, 0xff, 0xc0, 0x41, +0x5f, 0x82, 0xe4, 0xe5, 0x4c, 0xb1, 0x86, 0x07, +0xe7, 0x56, 0xf0, 0x77, 0xcf, 0x2d, 0xb5, 0xd5, +0xbb, 0x8c, 0xde, 0xa4, 0x02, 0x5e, 0x5a, 0x5a, +0xc2, 0xe7, 0x06, 0x5f, 0x16, 0x79, 0x9d, 0x93, +0x03, 0x5d, 0x26, 0x93, 0xc1, 0x54, 0x75, 0x11, +0x47, 0x1a, 0x7b, 0x03, 0x63, 0xec, 0xb0, 0x5d, +0x0b, 0x1a, 0x58, 0xa5, 0xf2, 0x08, 0x6b, 0xc7, +0x66, 0x93, 0xff, 0x7f, 0x5f, 0xbe, 0xdb, 0x5f, +0x23, 0x5f, 0xfb, 0xd0, 0x9f, 0x20, 0xb5, 0x36, +0x6f, 0x95, 0x4a, 0xa5, 0x63, 0x8d, 0xfc, 0xf1, +0x8d, 0x83, 0x38, 0xf0, 0x0f, 0xcb, 0xc6, 0x76, +0xdb, 0xd7, 0xda, 0x9d, 0x38, 0x71, 0x02, 0x33, +0xcf, 0x9e, 0xc0, 0x0f, 0x7d, 0x3f, 0x5b, 0x5b, +0xcf, 0x2f, 0x41, 0x2b, 0xa4, 0x9a, 0xf7, 0x1e, +0xfd, 0x3c, 0xb6, 0x9c, 0x5f, 0x5a, 0x77, 0xe0, +0xcb, 0x2f, 0xe1, 0xfe, 0xcf, 0xdc, 0x87, 0xfb, +0x3f, 0x73, 0x1f, 0x5c, 0xd7, 0xc5, 0x2d, 0x03, +0xd7, 0xe0, 0xa1, 0xd4, 0xf6, 0xc8, 0xbf, 0x77, +0xed, 0x7f, 0x30, 0x03, 0x9c, 0x42, 0xbc, 0x7d, +0xa9, 0x06, 0xae, 0xf0, 0xea, 0x98, 0x6c, 0x2c, +0xe3, 0xce, 0x66, 0x05, 0xf5, 0x0b, 0x31, 0x94, +0x0d, 0xce, 0x67, 0x61, 0x8c, 0xdc, 0x14, 0x56, +0x25, 0x53, 0x98, 0x9a, 0xd4, 0xe6, 0x12, 0x2e, +0xf5, 0x49, 0xea, 0x6f, 0xda, 0xec, 0xb9, 0xd3, +0x1a, 0x00, 0x3f, 0xa4, 0x6c, 0x7e, 0x7e, 0x1e, +0xb5, 0x7a, 0x03, 0x49, 0x27, 0xa1, 0x32, 0x48, +0xde, 0x96, 0xab, 0xaa, 0x65, 0x3f, 0x1c, 0x17, +0x19, 0x16, 0xa7, 0x39, 0xaa, 0x99, 0x42, 0xd0, +0xa4, 0xd4, 0x6a, 0xc2, 0xc7, 0xa4, 0x16, 0x97, +0x92, 0xae, 0x2c, 0x9a, 0x54, 0x6f, 0x3a, 0x84, +0x48, 0x46, 0x2a, 0x9f, 0xf1, 0x3e, 0x88, 0xce, +0xa4, 0xe5, 0x58, 0x5e, 0x5e, 0x46, 0x3a, 0x9d, +0xf6, 0xc3, 0xf6, 0x6c, 0x61, 0x74, 0x1c, 0x37, +0x3e, 0xef, 0xd2, 0x84, 0xc1, 0xff, 0x93, 0x2d, +0x5d, 0x3a, 0x25, 0x9e, 0x3b, 0x36, 0x8d, 0xef, +0xdf, 0xb6, 0x07, 0x7f, 0x9a, 0xde, 0x8a, 0xe3, +0xa5, 0x96, 0xf9, 0xe4, 0x6f, 0x72, 0x42, 0x91, +0x9a, 0x28, 0xf9, 0xd9, 0x74, 0x0a, 0xd6, 0x60, +0x6b, 0xc5, 0x24, 0x79, 0xd8, 0x70, 0xb4, 0xd5, +0x89, 0x0a, 0x0b, 0x58, 0xbb, 0xa8, 0xc5, 0x6d, +0x27, 0x35, 0x49, 0x22, 0x5a, 0x91, 0x34, 0xe1, +0x59, 0xad, 0x4c, 0x75, 0xe4, 0x73, 0x1b, 0x5d, +0x2d, 0x74, 0x7b, 0xff, 0xfb, 0xdf, 0x1f, 0xb0, +0x81, 0x9a, 0xca, 0x3d, 0x9f, 0xfd, 0x1c, 0x66, +0x9e, 0x3d, 0x81, 0xa3, 0x03, 0x07, 0xf1, 0x73, +0x3b, 0xdb, 0x92, 0xe4, 0xa9, 0x2f, 0xdc, 0x83, +0x6a, 0xa3, 0x89, 0x19, 0x6f, 0x3b, 0x8e, 0x0c, +0xed, 0x69, 0x67, 0xd5, 0x6b, 0xc6, 0xb0, 0xa3, +0x7a, 0x01, 0xab, 0x5f, 0x7d, 0x0c, 0x1f, 0xdc, +0xb7, 0x0f, 0xbb, 0xc6, 0xb6, 0xe1, 0x96, 0xd2, +0x51, 0x3c, 0xb2, 0xd8, 0xb6, 0x4f, 0xff, 0xab, +0xf7, 0xfe, 0x18, 0xbe, 0xfa, 0xec, 0x19, 0x3c, +0xb4, 0x9a, 0xc4, 0x91, 0xf9, 0x02, 0x1e, 0x99, +0xcf, 0x63, 0x61, 0xa5, 0x84, 0x5b, 0x4a, 0xb3, +0xb8, 0xb5, 0x79, 0x02, 0x77, 0x14, 0x8f, 0xfb, +0xcc, 0xfc, 0xdf, 0xed, 0x78, 0x8b, 0x6f, 0x27, +0xaf, 0x54, 0x2a, 0xf8, 0x77, 0x3b, 0xde, 0xe2, +0xe3, 0xf3, 0xf8, 0xce, 0x76, 0xde, 0xd3, 0xa7, +0xbf, 0x72, 0x3f, 0x2a, 0x95, 0x0a, 0x1e, 0xcd, +0x5d, 0x85, 0xa3, 0x7d, 0x93, 0xb8, 0x10, 0x73, +0x31, 0xdc, 0xaa, 0xa0, 0xf1, 0x8d, 0xa7, 0xf1, +0xc1, 0x35, 0x66, 0xee, 0x9b, 0xaa, 0xd8, 0xd8, +0x67, 0x67, 0x67, 0xe1, 0x36, 0x81, 0xdf, 0x1d, +0x7f, 0x63, 0x3b, 0x27, 0x3f, 0x80, 0xdf, 0xde, +0xd5, 0xbe, 0x4f, 0xe1, 0x43, 0xdf, 0x7b, 0x18, +0xc0, 0x61, 0x2b, 0x3d, 0x6e, 0xdb, 0xb5, 0x05, +0xfb, 0xca, 0xd3, 0x38, 0x9e, 0x6c, 0x1f, 0x74, +0xfe, 0xb0, 0xb5, 0x17, 0xa7, 0xef, 0xfd, 0x3a, +0x6e, 0xfe, 0xf8, 0xc7, 0x30, 0x3e, 0x3e, 0x8e, +0xf1, 0xdd, 0x13, 0x18, 0x1d, 0x1e, 0x42, 0x76, +0x74, 0x07, 0x76, 0x8d, 0x6d, 0xc3, 0x8e, 0x4c, +0x12, 0xef, 0xde, 0x37, 0x8c, 0x77, 0xef, 0x1b, +0xc6, 0xff, 0x39, 0x91, 0xc7, 0x7b, 0x3e, 0xfb, +0x14, 0x0a, 0x02, 0xe6, 0x4a, 0xad, 0x89, 0xb9, +0xc4, 0x80, 0x79, 0xbe, 0x2c, 0xeb, 0x6e, 0x7b, +0x2d, 0xaf, 0xd7, 0x31, 0x3d, 0x0b, 0x83, 0x19, +0xa2, 0x62, 0xf7, 0x8b, 0x81, 0xc1, 0xbd, 0x7a, +0xc7, 0xda, 0xfc, 0x7c, 0xee, 0x93, 0x00, 0x80, +0x99, 0xfe, 0x09, 0x1c, 0xc9, 0xec, 0xc1, 0x0b, +0x89, 0x7e, 0x64, 0xe3, 0x2d, 0x0c, 0x96, 0x97, +0xfc, 0x35, 0xb2, 0x7f, 0xe7, 0x18, 0x6e, 0x2a, +0x7f, 0x15, 0x0f, 0x7b, 0x3b, 0xfd, 0x76, 0xa7, +0xbe, 0x70, 0x4f, 0x47, 0x3b, 0x00, 0xd8, 0xde, +0x58, 0x41, 0xfd, 0xc1, 0x87, 0xf1, 0xef, 0xd7, +0xd6, 0x16, 0xb5, 0xa3, 0x42, 0x07, 0xb7, 0xaf, +0x2e, 0x14, 0x71, 0xdb, 0x68, 0x06, 0x3f, 0xf5, +0x53, 0x3f, 0x85, 0xaf, 0x3e, 0x7b, 0x06, 0x47, +0x16, 0x56, 0xf0, 0x74, 0xc5, 0xc5, 0x03, 0x2f, +0x14, 0x50, 0xcd, 0x2f, 0x62, 0x5f, 0x79, 0x01, +0xdf, 0x51, 0x3a, 0x8e, 0xdb, 0x56, 0x9e, 0xc6, +0x43, 0x5b, 0xb6, 0x77, 0xe7, 0xfb, 0x23, 0x68, +0xe5, 0x74, 0x34, 0x40, 0xdb, 0x26, 0xfe, 0xdd, +0x5b, 0x1a, 0xb8, 0xc9, 0x2d, 0xa0, 0x59, 0x59, +0xc5, 0xae, 0x7e, 0x0f, 0x4b, 0x67, 0xcf, 0xc2, +0xa9, 0x7b, 0x80, 0xd3, 0x8e, 0xbf, 0xe6, 0x9e, +0xdd, 0x93, 0x93, 0x93, 0xaa, 0x0a, 0x58, 0xc6, +0x7e, 0x7b, 0x5e, 0xfb, 0xce, 0x65, 0x2e, 0xe1, +0x72, 0xaf, 0x65, 0x8d, 0xf1, 0xf1, 0x83, 0x02, +0x67, 0xf0, 0xf3, 0xf3, 0xf3, 0x98, 0x9c, 0x9c, +0xf4, 0x25, 0xb6, 0x74, 0x3a, 0xdd, 0x71, 0xc3, +0xd7, 0xdc, 0xdc, 0x1c, 0x96, 0x97, 0x97, 0xfd, +0x1b, 0xaa, 0x08, 0x46, 0x63, 0x2d, 0x87, 0x78, +0xc2, 0x49, 0x22, 0xe9, 0x48, 0xbd, 0x28, 0x7c, +0xdc, 0xa9, 0x2f, 0x93, 0x4a, 0x5a, 0x93, 0x78, +0xf9, 0x3b, 0x93, 0x33, 0x9e, 0x89, 0xb9, 0x69, +0xa1, 0x67, 0xa6, 0x7e, 0xa9, 0x98, 0x42, 0xf3, +0xb4, 0x3e, 0xc2, 0xd4, 0xea, 0xb2, 0x1e, 0x3d, +0x97, 0xf6, 0x72, 0x62, 0xe6, 0xdc, 0xc3, 0x59, +0x1e, 0xba, 0x38, 0x5c, 0x7e, 0xf8, 0x92, 0x34, +0x22, 0x9f, 0x08, 0xd2, 0xb8, 0xc8, 0xb4, 0xaf, +0x9a, 0x86, 0x86, 0x0e, 0x56, 0x73, 0x73, 0x73, +0xc8, 0x25, 0x92, 0xf8, 0xae, 0x5c, 0x1c, 0x7f, +0x51, 0x1f, 0xc2, 0x42, 0x33, 0x69, 0x3d, 0x98, +0xfa, 0x8e, 0x25, 0xfc, 0x3d, 0xaf, 0x23, 0x3f, +0x47, 0x39, 0x0c, 0x98, 0xea, 0xdb, 0xe0, 0x74, +0xf3, 0x83, 0xed, 0x06, 0x7e, 0x98, 0x4a, 0xd2, +0xa6, 0x61, 0x90, 0x34, 0x89, 0x52, 0x27, 0x6c, +0xa3, 0x0f, 0x1b, 0x6f, 0x84, 0x52, 0xa8, 0x54, +0xb1, 0xbc, 0x78, 0x0e, 0xb3, 0xb3, 0xb3, 0x98, +0x99, 0x99, 0x69, 0xff, 0xef, 0x9f, 0xc0, 0xc3, +0xde, 0x4e, 0xec, 0x1d, 0x68, 0xaf, 0xa5, 0xb9, +0xb9, 0x39, 0x3c, 0x31, 0xb0, 0x07, 0xf7, 0x64, +0xf6, 0xb7, 0x1b, 0xc5, 0x1c, 0x20, 0x01, 0x9c, +0x49, 0x0d, 0xe3, 0xb7, 0x56, 0x81, 0x0f, 0xa2, +0xed, 0xe1, 0xff, 0xf2, 0x95, 0x67, 0xf1, 0x8e, +0x4f, 0xcf, 0xe0, 0x9b, 0xdf, 0xbd, 0x1f, 0x99, +0x4c, 0x06, 0xb7, 0x5d, 0xb1, 0x03, 0xb7, 0x01, +0xf8, 0xf9, 0x6b, 0xdb, 0xea, 0xfb, 0xe7, 0x56, +0xaa, 0xf8, 0xf8, 0xec, 0x95, 0xf8, 0x5f, 0x4f, +0x9f, 0x5f, 0x77, 0x2e, 0x93, 0xb6, 0x7d, 0xee, +0x49, 0x9d, 0x70, 0x7c, 0xc9, 0x37, 0xbf, 0x78, +0x16, 0xf7, 0xe7, 0xae, 0xc6, 0x91, 0xcc, 0x5e, +0xff, 0xdd, 0x85, 0x06, 0xf0, 0x5b, 0x95, 0x09, +0x7c, 0x70, 0xad, 0xba, 0xbc, 0xc6, 0x14, 0x68, +0xff, 0x86, 0x3e, 0x37, 0xf8, 0x32, 0x9f, 0x91, +0x03, 0xe8, 0x90, 0xa6, 0x6d, 0x25, 0xeb, 0xa6, +0xda, 0xd7, 0xb6, 0xae, 0x31, 0x73, 0x00, 0xf8, +0x87, 0xfe, 0xab, 0xf1, 0x50, 0xdf, 0x24, 0xae, +0xcd, 0xbf, 0x80, 0xed, 0x67, 0x9f, 0xc6, 0xf6, +0xc6, 0x32, 0xb2, 0x6b, 0x97, 0x96, 0x8c, 0x8f, +0x8f, 0x63, 0x6c, 0x6c, 0x0c, 0xb7, 0xde, 0x7a, +0x2b, 0xbe, 0x7b, 0xcf, 0x30, 0x4e, 0xdf, 0xb2, +0x0b, 0x3f, 0x77, 0xe4, 0xb4, 0x3f, 0xfe, 0xbd, +0xfd, 0x29, 0xec, 0xde, 0xb6, 0x25, 0x78, 0x73, +0x9d, 0x5c, 0x07, 0xe2, 0xb7, 0x74, 0xe5, 0x70, +0x16, 0x00, 0x70, 0xe1, 0xc2, 0x85, 0x75, 0xdf, +0x87, 0xb0, 0x75, 0x14, 0xb6, 0xd6, 0xa3, 0xfe, +0x5e, 0xe5, 0x5a, 0x13, 0xff, 0x49, 0x32, 0xce, +0x2f, 0x9e, 0xc5, 0x83, 0xe9, 0x3d, 0xbe, 0xd3, +0x24, 0xd0, 0x36, 0x11, 0x14, 0xd8, 0x1a, 0x01, +0x80, 0xc3, 0xc5, 0x13, 0x78, 0x38, 0x33, 0xe9, +0xb7, 0x9b, 0x9d, 0x9d, 0xc5, 0x91, 0xdc, 0xd4, +0x7a, 0x3b, 0xd2, 0xe0, 0xa5, 0x86, 0xf0, 0x1f, +0x5a, 0x43, 0xf8, 0xf7, 0x6b, 0x6b, 0xeb, 0x70, +0xf1, 0x44, 0x80, 0x99, 0xd3, 0x3a, 0xf9, 0xe7, +0x9f, 0x79, 0x2a, 0xb8, 0xde, 0xae, 0x58, 0x47, +0xf9, 0xb9, 0x8b, 0x65, 0xfc, 0xc3, 0x89, 0x0b, +0xf8, 0x93, 0xe3, 0xd7, 0xaf, 0xaf, 0xb7, 0xa8, +0xbf, 0x29, 0xfa, 0xcc, 0x68, 0xb1, 0xbe, 0xaa, +0xea, 0x6d, 0xa7, 0xb5, 0x9b, 0xdc, 0x0a, 0x5e, +0x9d, 0x2e, 0xe2, 0xae, 0xc1, 0x64, 0x7b, 0xd3, +0x5c, 0x5a, 0xc0, 0xdc, 0x9a, 0x06, 0x41, 0x4a, +0x7a, 0xe4, 0x01, 0x4b, 0x4c, 0x8d, 0x7b, 0x23, +0xd3, 0xa6, 0x2c, 0x43, 0xc5, 0xa4, 0x9a, 0x9a, +0xdb, 0x87, 0x65, 0x48, 0x16, 0x0f, 0x07, 0xd3, +0x54, 0xb5, 0x54, 0x9f, 0xec, 0xe7, 0x24, 0xdd, +0xb9, 0xae, 0xeb, 0x5f, 0xef, 0x49, 0x70, 0x75, +0xa7, 0x31, 0xa0, 0x51, 0xaf, 0xa9, 0xb6, 0x5b, +0x59, 0x4c, 0xea, 0x68, 0xa9, 0x32, 0x96, 0x45, +0x93, 0x84, 0x39, 0x0c, 0x5b, 0xe2, 0x18, 0x0e, +0x43, 0x6b, 0x13, 0xc5, 0x61, 0x4e, 0xc3, 0xdb, +0xa4, 0xba, 0x37, 0xe1, 0xcd, 0x6f, 0xfd, 0xe2, +0xf1, 0xf9, 0x26, 0x27, 0x40, 0x19, 0x5d, 0x20, +0xa5, 0x70, 0xd9, 0x0f, 0xd7, 0x82, 0xd0, 0x41, +0x8d, 0xe6, 0x92, 0xaf, 0x23, 0x79, 0xd3, 0xdc, +0x9e, 0x3d, 0x7b, 0x50, 0x2e, 0x97, 0x71, 0x55, +0xf1, 0x0c, 0x7e, 0x76, 0xa0, 0x89, 0xff, 0x59, +0x1e, 0xc3, 0x73, 0x45, 0x31, 0x90, 0xa8, 0x0c, +0x2f, 0x8c, 0xd1, 0x98, 0x36, 0x97, 0x30, 0xa9, +0x39, 0xa2, 0x13, 0x4f, 0x28, 0xc3, 0x34, 0x1d, +0x4a, 0xc2, 0x0e, 0x15, 0x1a, 0x4e, 0x5a, 0x9f, +0x1b, 0x60, 0xb8, 0x56, 0x69, 0xdd, 0x86, 0x0f, +0x63, 0x6a, 0xdc, 0x16, 0x1d, 0x70, 0xbc, 0xab, +0x54, 0x50, 0x8d, 0x27, 0xb1, 0x92, 0xca, 0xe0, +0x79, 0x6f, 0x1b, 0x9e, 0xde, 0x76, 0x5b, 0x80, +0x71, 0x51, 0x9d, 0xa3, 0x5b, 0x26, 0xf5, 0x71, +0xb2, 0x3e, 0xb6, 0xb5, 0x4a, 0x78, 0xae, 0x58, +0xc7, 0xbf, 0xfc, 0xe3, 0x8f, 0xe0, 0x7b, 0x77, +0x65, 0x30, 0x35, 0x35, 0xe5, 0x87, 0xf5, 0x01, +0xed, 0x8d, 0xff, 0xe7, 0xaf, 0xdd, 0x86, 0x9f, +0xbf, 0x76, 0x1b, 0xde, 0xf6, 0x99, 0x67, 0xd7, +0xb3, 0xcd, 0x99, 0x8a, 0x18, 0xcf, 0xb7, 0xd2, +0xbb, 0xac, 0x9a, 0x09, 0x37, 0xae, 0xd3, 0x6a, +0x6e, 0x2d, 0xb7, 0xbd, 0x7c, 0xfe, 0x9b, 0xbf, +0xf9, 0x9b, 0x81, 0x31, 0x6a, 0x8e, 0x89, 0x00, +0xb0, 0xb3, 0xd6, 0x44, 0xe1, 0x7d, 0x37, 0xa1, +0xcf, 0x89, 0x63, 0xeb, 0x5f, 0x7c, 0x0b, 0xe7, +0x57, 0xcb, 0x38, 0x97, 0x1a, 0xc4, 0xfd, 0x89, +0x0c, 0x30, 0xd0, 0x86, 0x4b, 0x52, 0xe8, 0xf8, +0xca, 0x2a, 0xc6, 0x2e, 0x9c, 0xc5, 0x57, 0x4e, +0x7c, 0x14, 0x1f, 0xfc, 0x57, 0xff, 0x12, 0xff, +0x72, 0xdf, 0x20, 0xfe, 0xe3, 0x17, 0xbe, 0x85, +0x33, 0xa9, 0x61, 0x1c, 0x59, 0x28, 0x60, 0x6f, +0xff, 0x30, 0xf6, 0x5c, 0xb5, 0x1f, 0x99, 0x67, +0x4a, 0x9d, 0xb7, 0xf7, 0x19, 0xd6, 0xed, 0xf7, +0x4c, 0xb6, 0x35, 0x09, 0x73, 0x73, 0x73, 0x6d, +0x7f, 0x0b, 0xd3, 0x7a, 0x08, 0x5b, 0x5f, 0x1a, +0x53, 0xd7, 0xd6, 0x99, 0xcd, 0x4c, 0x63, 0x59, +0xc7, 0xd3, 0x7d, 0xbb, 0x83, 0x6b, 0x42, 0xd1, +0xc0, 0x6d, 0x6b, 0x05, 0xfd, 0xa9, 0x5c, 0xd7, +0x5d, 0x6f, 0x27, 0x69, 0x60, 0x69, 0x47, 0x42, +0x8e, 0x75, 0xbd, 0x0d, 0x78, 0xf8, 0x99, 0xeb, +0xb7, 0xe3, 0x47, 0xae, 0x1e, 0xc3, 0x7b, 0x1e, +0x98, 0x0d, 0x44, 0x51, 0x18, 0xc7, 0x63, 0x59, +0x5f, 0xce, 0xde, 0x8c, 0x83, 0x9b, 0xbc, 0x2a, +0x96, 0x9b, 0x49, 0xbc, 0x3a, 0xd7, 0xc2, 0xee, +0x56, 0x15, 0xc9, 0x62, 0x11, 0xe5, 0xb2, 0x87, +0x58, 0x6a, 0x3d, 0x3e, 0x91, 0x18, 0xb5, 0x64, +0xc4, 0x3c, 0x46, 0x9b, 0x4b, 0xd1, 0x54, 0x34, +0x66, 0xce, 0x1d, 0xe6, 0xe8, 0x19, 0x10, 0xb4, +0x87, 0x53, 0xd1, 0x0e, 0x04, 0x63, 0x63, 0x63, +0x58, 0x5a, 0x5a, 0x0a, 0x6c, 0xf2, 0x73, 0x73, +0x73, 0x81, 0x64, 0x33, 0x84, 0x2b, 0xb7, 0x3f, +0xdb, 0xa4, 0x67, 0x59, 0x4c, 0x0e, 0x6a, 0xa6, +0xc3, 0x85, 0x94, 0x26, 0x25, 0x2c, 0xed, 0x96, +0x35, 0x5e, 0x4c, 0xf6, 0x6b, 0x4d, 0x65, 0x1d, +0x66, 0xa7, 0xb7, 0x31, 0x7a, 0x5b, 0x5b, 0x1e, +0x27, 0xce, 0xfb, 0xe2, 0x0c, 0x9c, 0xdb, 0xf4, +0x79, 0x2c, 0x30, 0x67, 0xf0, 0xd2, 0x23, 0x3d, +0xea, 0x61, 0xc4, 0x75, 0x5d, 0x8c, 0x8e, 0x8e, +0xfa, 0x73, 0x2a, 0x13, 0xed, 0x70, 0x5f, 0x07, +0x3e, 0xbf, 0xe5, 0x72, 0x19, 0xbb, 0xaa, 0x4b, +0xf8, 0x37, 0xc3, 0x1e, 0xbe, 0xbe, 0x6d, 0x14, +0xff, 0xb0, 0x50, 0x0b, 0x86, 0xad, 0x01, 0xe1, +0xcc, 0xd8, 0xc6, 0x60, 0x6d, 0x12, 0x34, 0x6f, +0x13, 0x85, 0xb1, 0x46, 0x85, 0xaf, 0xc1, 0x35, +0xb5, 0x0f, 0xc3, 0xc1, 0xe4, 0x0b, 0x13, 0x06, +0x3f, 0x2a, 0xce, 0x51, 0x0e, 0x2b, 0xda, 0xb8, +0xd8, 0xfb, 0x8a, 0x29, 0xc1, 0x87, 0x8d, 0x16, +0x6b, 0x65, 0x72, 0x72, 0x12, 0x17, 0x6a, 0xae, +0x8a, 0xc3, 0xab, 0xb7, 0xb4, 0xdb, 0x5f, 0xb8, +0x70, 0xc1, 0xdf, 0x60, 0x3f, 0xec, 0x4d, 0x61, +0x71, 0xf6, 0x19, 0x5c, 0x3f, 0xf3, 0x29, 0xf4, +0x95, 0x57, 0x7c, 0xe7, 0xcd, 0xc9, 0xc9, 0x49, +0x1c, 0x38, 0x70, 0x00, 0xc3, 0xc3, 0xc3, 0xf8, +0x9f, 0xb7, 0x8d, 0x63, 0xcf, 0xf1, 0x79, 0xc8, +0xb3, 0x21, 0x0f, 0x39, 0x42, 0xc2, 0xf1, 0xa5, +0xd9, 0xa1, 0xa1, 0xa1, 0x36, 0xf3, 0x13, 0x63, +0x23, 0xa9, 0xb5, 0x83, 0xa6, 0x04, 0xaf, 0x89, +0x60, 0x3b, 0xb4, 0xed, 0xda, 0x3b, 0x32, 0x49, +0xec, 0xd9, 0xb3, 0x07, 0x33, 0x33, 0x33, 0x00, +0x82, 0x1a, 0x01, 0x3f, 0xc4, 0x30, 0xe9, 0xa2, +0xda, 0x68, 0xa2, 0x3f, 0x19, 0xf7, 0x3d, 0xd9, +0xdf, 0x79, 0xc5, 0x50, 0xdb, 0x99, 0x4a, 0xe0, +0x41, 0x52, 0xe8, 0x19, 0x0c, 0x03, 0xde, 0x4e, +0x3c, 0x90, 0x4a, 0xe2, 0x83, 0x68, 0xdb, 0xb9, +0xdf, 0xb2, 0xf2, 0x04, 0xfe, 0x70, 0xcb, 0x1d, +0xf8, 0xdf, 0x4f, 0x9f, 0xc7, 0xbb, 0xf7, 0x0d, +0xe3, 0x55, 0xb7, 0xdd, 0x8a, 0x43, 0xcf, 0x3c, +0x80, 0xaf, 0x24, 0xb6, 0x77, 0xcc, 0xfd, 0xdb, +0x27, 0x73, 0x98, 0x5d, 0x29, 0xb7, 0x93, 0x36, +0x01, 0x18, 0x8d, 0xd7, 0xf0, 0x8b, 0x87, 0xda, +0xbc, 0x61, 0x66, 0x66, 0x06, 0xe7, 0x12, 0xfd, +0x9d, 0x63, 0xe4, 0xbe, 0x02, 0x51, 0x7e, 0x0f, +0x61, 0xeb, 0x49, 0xac, 0x01, 0x2b, 0xfc, 0xb5, +0x32, 0x34, 0x34, 0xd4, 0x36, 0x3d, 0x29, 0x7d, +0x76, 0xac, 0x11, 0xf6, 0x3e, 0x37, 0xb2, 0x0d, +0x17, 0x20, 0x32, 0x3c, 0xae, 0xf5, 0x73, 0xfb, +0x56, 0xcf, 0x6f, 0x27, 0x8b, 0x3f, 0x5f, 0x09, +0x07, 0x1f, 0xf6, 0xa6, 0x70, 0x6a, 0xf6, 0x39, +0x1c, 0xb6, 0xac, 0xb7, 0x3f, 0xb8, 0x75, 0x0c, +0x9f, 0x7e, 0x66, 0x2e, 0xa0, 0xa1, 0x09, 0x75, +0x1a, 0x14, 0xfb, 0x90, 0xf3, 0x8e, 0xfe, 0x02, +0x5e, 0x91, 0x59, 0xdf, 0xf8, 0x5a, 0xd5, 0x0a, +0xf2, 0x6b, 0x1b, 0x68, 0x75, 0x35, 0x78, 0xdd, +0x27, 0xdd, 0x1a, 0xa6, 0x31, 0x25, 0x9e, 0x10, +0x84, 0x4b, 0x68, 0xfc, 0x20, 0x20, 0x1d, 0xc9, +0x48, 0xc5, 0x4e, 0xd2, 0x18, 0xa5, 0x4c, 0xa5, +0x3b, 0xb8, 0x81, 0xce, 0xe4, 0x21, 0xc4, 0xb0, +0xc7, 0xc7, 0xc7, 0x7d, 0x5c, 0xb8, 0x23, 0x1d, +0x57, 0xd3, 0x4a, 0x46, 0x4e, 0xff, 0x35, 0x26, +0xa3, 0xbd, 0x0b, 0x8b, 0xed, 0xb6, 0x79, 0x87, +0xdb, 0xbc, 0xea, 0x65, 0x7f, 0x26, 0xe6, 0x26, +0x0f, 0x31, 0x12, 0x17, 0x0e, 0x33, 0x4c, 0xca, +0x0f, 0x0b, 0x9d, 0xa3, 0x67, 0xf2, 0xf2, 0x17, +0x93, 0x8a, 0xdf, 0x75, 0x5d, 0x5f, 0x62, 0xe7, +0xd9, 0xe1, 0x34, 0x87, 0x3c, 0xd3, 0x98, 0xe5, +0xc2, 0x27, 0x38, 0xe9, 0x74, 0x1a, 0x83, 0x83, +0x83, 0x98, 0x98, 0x98, 0xf0, 0x35, 0x2c, 0x7c, +0x6d, 0x49, 0x6d, 0x48, 0xb5, 0xd9, 0x42, 0xb3, +0x5a, 0x41, 0x7c, 0xfe, 0x04, 0xfe, 0xd9, 0x58, +0x09, 0xaf, 0xdb, 0x3b, 0x86, 0xff, 0x33, 0x5b, +0xc4, 0x93, 0xcd, 0x34, 0x1e, 0xaf, 0xa4, 0x3a, +0x37, 0x08, 0xed, 0x87, 0xd2, 0x8b, 0x8a, 0xaf, +0x17, 0xc9, 0x37, 0x0c, 0xbe, 0xed, 0xbb, 0x89, +0x29, 0x87, 0xc1, 0x34, 0xa9, 0xe6, 0x64, 0x1b, +0x5b, 0x1f, 0x51, 0x71, 0x0e, 0xd3, 0x76, 0xc8, +0xf7, 0x7c, 0x0d, 0x68, 0xe3, 0xb4, 0xa8, 0xfe, +0x9f, 0x5c, 0x2a, 0xe3, 0xe0, 0x90, 0x87, 0x57, +0xbd, 0xea, 0x55, 0x18, 0xfe, 0xec, 0x1c, 0x2e, +0x34, 0x3a, 0xeb, 0xbc, 0xef, 0xa6, 0x49, 0x00, +0xc0, 0x89, 0x13, 0x27, 0x50, 0x5b, 0xbb, 0x33, +0x1d, 0x09, 0x07, 0xf7, 0x67, 0xae, 0xc4, 0xfd, +0x99, 0x2b, 0x31, 0x8e, 0x32, 0x76, 0x94, 0x17, +0x31, 0xf6, 0xc2, 0x32, 0xb6, 0x3e, 0xff, 0x28, +0xb6, 0x7f, 0xe5, 0x21, 0x7c, 0xe0, 0x17, 0xdf, +0x87, 0x91, 0x6c, 0x1f, 0xbe, 0x6b, 0xf9, 0x9b, +0xf8, 0xcb, 0xa1, 0x9b, 0x02, 0x20, 0x03, 0x78, +0x36, 0xea, 0xb8, 0xef, 0xd4, 0x32, 0x7e, 0xe2, +0xe0, 0x56, 0xdc, 0x78, 0xf3, 0x2d, 0xc8, 0x7c, +0xbd, 0xb2, 0xbe, 0x19, 0xaf, 0x8d, 0xf1, 0xe7, +0xae, 0xd9, 0xea, 0xb7, 0x55, 0x63, 0xfc, 0x95, +0x90, 0xbc, 0x4f, 0x9c, 0xcc, 0xe3, 0x27, 0x0e, +0x6e, 0xc5, 0x77, 0x7c, 0xc7, 0x77, 0xe0, 0x17, +0xca, 0xfb, 0xb0, 0x50, 0x8b, 0x75, 0xb4, 0xfb, +0x91, 0x3d, 0x19, 0xfc, 0xd1, 0x1b, 0xae, 0xc6, +0x57, 0x17, 0x8a, 0x78, 0xc5, 0x47, 0x9f, 0xc0, +0xd3, 0x4f, 0x9e, 0xc5, 0x6d, 0xa3, 0x7b, 0xf0, +0x1f, 0x6e, 0xd9, 0x81, 0x0b, 0xe7, 0x17, 0xf1, +0x37, 0x2f, 0xb0, 0xc4, 0x47, 0xca, 0x5a, 0xf9, +0xed, 0xc3, 0x6d, 0x95, 0xf0, 0x99, 0x33, 0x67, +0xb0, 0xa5, 0xd1, 0x96, 0x2a, 0x3f, 0x73, 0x66, +0x05, 0x9f, 0x39, 0x3e, 0x87, 0xbb, 0xf6, 0x8d, +0xe3, 0x7f, 0xbe, 0xf5, 0x26, 0xbc, 0xf9, 0xcb, +0x8b, 0x78, 0x8e, 0x9c, 0x4b, 0x01, 0xdc, 0xb4, +0xc5, 0xc3, 0xff, 0x7a, 0xf5, 0x24, 0xfa, 0x9c, +0x38, 0xf2, 0xd5, 0x06, 0x7e, 0xf5, 0xeb, 0x2f, +0xe0, 0x87, 0xf7, 0x6f, 0x41, 0x2e, 0x95, 0xc0, +0xdc, 0xe2, 0x79, 0x1c, 0x3b, 0x76, 0x0c, 0x8f, +0x65, 0xf5, 0xeb, 0x67, 0x43, 0x4d, 0x4a, 0x26, +0x89, 0x33, 0x6c, 0xbd, 0x86, 0xc0, 0xa7, 0x35, +0xf2, 0x86, 0x37, 0xbc, 0x01, 0x99, 0xcf, 0x2c, +0xac, 0x27, 0x75, 0x62, 0xe5, 0x57, 0x6e, 0xd9, +0xd3, 0xb1, 0x46, 0xa8, 0xdd, 0x1b, 0x5f, 0xf7, +0x1a, 0x8c, 0x7f, 0xee, 0x05, 0xcc, 0xc1, 0x0b, +0xe2, 0x96, 0x70, 0xf0, 0x6f, 0x5f, 0xbe, 0xcb, +0x6f, 0xb7, 0x52, 0x33, 0x5c, 0x13, 0xbb, 0xd6, +0xd7, 0x91, 0x81, 0xab, 0x70, 0x24, 0xb3, 0x17, +0xc3, 0xad, 0x0a, 0xf6, 0x56, 0xce, 0x61, 0xec, +0x85, 0x65, 0xe4, 0x9e, 0xff, 0x26, 0xf6, 0x7f, +0xf5, 0x08, 0x7e, 0xe5, 0xff, 0xf9, 0x85, 0xf5, +0xf5, 0x36, 0x72, 0xd8, 0x4e, 0x0f, 0xcb, 0x21, +0x27, 0x0e, 0x00, 0x69, 0xcf, 0x43, 0xab, 0x5a, +0x41, 0xe9, 0xe2, 0x72, 0x40, 0xc2, 0xbc, 0x70, +0x76, 0x01, 0x40, 0x90, 0x71, 0xd1, 0xe5, 0x24, +0x32, 0x1c, 0xcc, 0xc6, 0xbc, 0xb8, 0xbd, 0x5a, +0xaa, 0x62, 0xcb, 0xe5, 0x32, 0x8e, 0x1d, 0x3b, +0x16, 0xf8, 0xce, 0x99, 0x83, 0x84, 0x45, 0xf5, +0xc8, 0x7e, 0x46, 0x57, 0x92, 0x72, 0x46, 0x4e, +0xea, 0x75, 0xae, 0x62, 0x97, 0xd2, 0x22, 0xb5, +0x21, 0xb8, 0x52, 0x92, 0xe4, 0x7f, 0xe4, 0x04, +0xc7, 0x8b, 0xac, 0x23, 0x61, 0xdb, 0x3c, 0xd6, +0x6d, 0xce, 0x80, 0x1a, 0x6c, 0x09, 0x53, 0x6a, +0x2f, 0xb4, 0x83, 0x8a, 0xe9, 0x00, 0x10, 0x25, +0x24, 0x8d, 0xe3, 0x60, 0x52, 0xc7, 0x73, 0xc6, +0x2b, 0xeb, 0xcb, 0x7c, 0x01, 0x51, 0x61, 0x52, +0x98, 0x1b, 0xf7, 0x98, 0xdf, 0xb3, 0x67, 0x0f, +0x26, 0x27, 0x27, 0x71, 0xe8, 0xd0, 0x21, 0x1c, +0x3e, 0x7c, 0x18, 0x53, 0x53, 0x53, 0x7e, 0x08, +0x5c, 0x2e, 0x97, 0xc3, 0xf6, 0xdd, 0x13, 0xd8, +0xbd, 0x7d, 0x1c, 0x43, 0xdb, 0x46, 0xfd, 0xb5, +0xb1, 0xa5, 0x92, 0xc7, 0x8f, 0x4f, 0x24, 0xf1, +0x53, 0xd9, 0x45, 0xbc, 0x61, 0x40, 0x61, 0x64, +0xfc, 0xc7, 0xc1, 0x7f, 0x20, 0x5a, 0x3d, 0x7a, +0xaf, 0xd5, 0x23, 0xaf, 0x73, 0x59, 0x2f, 0x44, +0x92, 0xb0, 0xc2, 0x97, 0xcf, 0x24, 0xdc, 0x28, +0x36, 0x44, 0x09, 0x4f, 0xfe, 0xd7, 0xf0, 0xe3, +0x70, 0xc2, 0xf0, 0xe7, 0xf5, 0x35, 0xdc, 0x0d, +0xaa, 0xc8, 0xae, 0x4c, 0x14, 0x1a, 0x6e, 0xa2, +0xed, 0xdd, 0x0f, 0xbf, 0x00, 0x00, 0xd8, 0xb7, +0x6f, 0x1f, 0xee, 0xf9, 0xce, 0x29, 0xdc, 0x3e, +0x96, 0x5d, 0x97, 0x9a, 0xc6, 0xb2, 0xf8, 0xdc, +0x9b, 0xae, 0xc4, 0x9b, 0x77, 0xb7, 0x1d, 0x99, +0x8e, 0x7c, 0xfd, 0x1b, 0x78, 0x21, 0x31, 0x88, +0x87, 0xdf, 0x7e, 0x0d, 0x9a, 0x3f, 0x7a, 0x23, +0x7e, 0xfb, 0xb6, 0x09, 0x5c, 0xbb, 0xb5, 0x1f, +0x73, 0x89, 0x2c, 0x1e, 0xf6, 0x76, 0xe2, 0x1f, +0xfa, 0xaf, 0xc6, 0x63, 0xfb, 0x5f, 0x83, 0x97, +0xbf, 0xe3, 0x5f, 0x00, 0x00, 0x8e, 0x1f, 0x3f, +0x8e, 0xab, 0x1a, 0x17, 0xfc, 0xbe, 0x29, 0xbb, +0xde, 0x9e, 0x3d, 0x7b, 0x02, 0xa8, 0x7e, 0xf0, +0xd1, 0x79, 0xac, 0xd6, 0x9b, 0xb8, 0xf5, 0xe5, +0x37, 0xe1, 0x23, 0x77, 0x8c, 0x62, 0x47, 0x7f, +0x1a, 0x48, 0x38, 0xd8, 0xeb, 0x01, 0xbf, 0xff, +0xca, 0x3d, 0xf8, 0x89, 0x83, 0xeb, 0xcc, 0x9c, +0x4b, 0x6b, 0x54, 0x7c, 0x06, 0xcf, 0x68, 0xf1, +0xc1, 0x47, 0xe7, 0x51, 0xa8, 0x54, 0x31, 0x3c, +0x3c, 0x8c, 0x87, 0xbf, 0xe7, 0x20, 0xde, 0x7e, +0xc5, 0x08, 0x32, 0xa9, 0xb6, 0xca, 0x7b, 0x6f, +0xc6, 0xc1, 0x2f, 0xdd, 0xb8, 0x03, 0x7f, 0xf4, +0x86, 0xb6, 0x53, 0xdd, 0x6f, 0x7c, 0xa3, 0x4d, +0x83, 0xbf, 0x7c, 0xea, 0x1c, 0x9e, 0x99, 0x7d, +0x1e, 0x7d, 0x4e, 0x1c, 0x7f, 0xf5, 0xd6, 0x1b, +0xf0, 0xf7, 0x6f, 0xb8, 0x0a, 0x6f, 0xbf, 0x62, +0xa4, 0x8d, 0x0f, 0xd9, 0x8f, 0x73, 0x7d, 0x78, +0xfb, 0x15, 0x23, 0xf8, 0xdc, 0x9b, 0xae, 0xf4, +0xf1, 0x7a, 0xf0, 0xc1, 0x07, 0xb1, 0xba, 0x76, +0x67, 0x37, 0x1a, 0x75, 0xbc, 0xfd, 0xfe, 0xe7, +0xf1, 0xd4, 0xe9, 0x79, 0xec, 0xdf, 0x39, 0x86, +0x6f, 0xbd, 0xfd, 0x20, 0x7e, 0xf7, 0xe6, 0x31, +0xdc, 0xb4, 0x2d, 0x8b, 0x4c, 0x2a, 0x89, 0x87, +0xcf, 0x16, 0x70, 0xcb, 0x5f, 0x1c, 0xc1, 0x91, +0x87, 0xbe, 0x86, 0x5c, 0x2a, 0x81, 0xdf, 0xbb, +0x7d, 0x97, 0x1f, 0x23, 0x7f, 0xcf, 0xc7, 0x3f, +0x86, 0xb3, 0xb1, 0x74, 0xdb, 0x6e, 0x6c, 0xf2, +0x36, 0xd7, 0xd6, 0xab, 0x6d, 0x2d, 0x9a, 0xd6, +0x4d, 0x17, 0xf0, 0xf9, 0x1a, 0x79, 0xe4, 0x4d, +0xbb, 0xda, 0xd2, 0xf4, 0xda, 0xba, 0xa5, 0x35, +0xf2, 0x9a, 0x1d, 0xfd, 0x58, 0xad, 0x37, 0x71, +0xf4, 0xe8, 0x51, 0xbc, 0x90, 0x18, 0xec, 0x68, +0xf7, 0xd1, 0x37, 0x1f, 0xc0, 0x2b, 0xb6, 0x0f, +0xfa, 0xb0, 0xb5, 0x76, 0x73, 0xde, 0x88, 0xaa, +0xfa, 0x7f, 0xf8, 0xed, 0xd7, 0xa0, 0xf9, 0xde, +0x9b, 0xf1, 0xbb, 0x37, 0x8f, 0xe1, 0xda, 0xad, +0xfd, 0xa8, 0x26, 0x52, 0xfe, 0x7a, 0x9b, 0xd9, +0x7f, 0x27, 0xae, 0x7d, 0xc7, 0x8f, 0xf9, 0xeb, +0x6d, 0x62, 0x75, 0x2e, 0x9c, 0x1e, 0xa6, 0xdf, +0x3f, 0x00, 0xa7, 0x51, 0x5e, 0xc5, 0xea, 0xc5, +0x46, 0x87, 0x2d, 0x1b, 0x00, 0xf2, 0x2b, 0x45, +0xe4, 0xfa, 0x33, 0x01, 0x35, 0x31, 0xd0, 0x99, +0x09, 0xcd, 0xe4, 0x19, 0xcd, 0xdb, 0x71, 0x3b, +0x2a, 0xd0, 0x56, 0x8d, 0x91, 0x74, 0xbe, 0xbc, +0xbc, 0x8c, 0xf1, 0xf1, 0x71, 0xff, 0x39, 0x15, +0xae, 0x86, 0xe7, 0x30, 0xa7, 0xa7, 0xa7, 0x03, +0x36, 0x59, 0xce, 0x1c, 0xb9, 0x04, 0x27, 0x25, +0xd3, 0x28, 0xcc, 0xd6, 0x64, 0xe3, 0xb6, 0x31, +0x4a, 0xa9, 0x92, 0xef, 0x26, 0xce, 0x5b, 0x63, +0xec, 0x36, 0x55, 0xb4, 0xa6, 0x39, 0x08, 0xb3, +0xf5, 0x87, 0x79, 0xb2, 0xdb, 0x70, 0x35, 0xd9, +0xba, 0xa5, 0x56, 0x41, 0xe2, 0x2d, 0x55, 0xe2, +0x1a, 0xed, 0xb9, 0xea, 0x90, 0xdb, 0xe5, 0x81, +0x75, 0xe7, 0x3a, 0x1e, 0xfe, 0x96, 0x4e, 0xa7, +0x3b, 0xbc, 0xea, 0x5d, 0x00, 0xa9, 0x78, 0xac, +0x0d, 0x73, 0x78, 0x68, 0x7d, 0x1d, 0x03, 0xb8, +0x66, 0x74, 0x08, 0xf1, 0x7c, 0x01, 0x40, 0x16, +0xf7, 0xe9, 0x91, 0x23, 0x76, 0x67, 0x33, 0x4d, +0xed, 0x27, 0x4b, 0x37, 0xb6, 0x78, 0x0d, 0xbe, +0xec, 0x2b, 0x4c, 0xb5, 0xa6, 0xf5, 0xa5, 0xc1, +0xb6, 0xfd, 0x97, 0x70, 0x4c, 0xb0, 0xc2, 0xd4, +0xf3, 0x1b, 0xb1, 0xed, 0x6b, 0xaa, 0x52, 0x93, +0x26, 0xc0, 0xd0, 0xf6, 0xef, 0x9f, 0x5d, 0xc4, +0x1f, 0x62, 0x01, 0xef, 0x7d, 0xfd, 0xad, 0xb8, +0x79, 0xd7, 0x56, 0x7c, 0x69, 0xd7, 0x56, 0xc8, +0xb2, 0x5a, 0x6f, 0xe2, 0xd3, 0x1f, 0xff, 0x28, +0xf2, 0x8b, 0x67, 0xf1, 0xc0, 0xc0, 0x4d, 0x38, +0xf1, 0xe5, 0x59, 0x7c, 0xfa, 0x3b, 0xf6, 0xe1, +0x17, 0xae, 0x1b, 0xc5, 0x2f, 0x5c, 0x37, 0xaa, +0x2e, 0x89, 0xc5, 0xc2, 0x2a, 0xee, 0xbb, 0xef, +0x3e, 0x9c, 0x48, 0xe4, 0xfc, 0xb1, 0xcd, 0xe4, +0xcb, 0xb8, 0x71, 0xa4, 0x0f, 0xef, 0x7e, 0xf7, +0xbb, 0xf1, 0x6e, 0xb4, 0x1d, 0xf3, 0x06, 0xfe, +0x6c, 0x1a, 0x67, 0x56, 0x4a, 0x78, 0xdf, 0xa7, +0x1f, 0xc5, 0x1f, 0xbe, 0xe5, 0x65, 0xb8, 0xeb, +0xda, 0x7d, 0x38, 0x75, 0x2d, 0xc2, 0x0b, 0xb7, +0xa3, 0xbb, 0x9d, 0x2a, 0xdc, 0x33, 0x2b, 0x25, +0x7c, 0xef, 0xc7, 0xa6, 0xf1, 0xf7, 0xdf, 0x79, +0x35, 0x76, 0xe4, 0xfa, 0xf1, 0xe1, 0xd7, 0xf7, +0xab, 0x60, 0xfe, 0xf0, 0xb3, 0x47, 0xf0, 0x8a, +0x47, 0x3e, 0x8f, 0xfe, 0xd4, 0x18, 0x3e, 0x32, +0x70, 0x1d, 0x5e, 0xfb, 0xd9, 0x53, 0xf8, 0xf0, +0x4d, 0x79, 0x1c, 0xbe, 0xe1, 0x3a, 0x7c, 0xf7, +0x9e, 0x9c, 0x7a, 0x51, 0x8a, 0xa4, 0xcb, 0x89, +0x13, 0x27, 0xf0, 0xa5, 0xec, 0x41, 0x9f, 0xa6, +0x85, 0x66, 0x0c, 0xaf, 0xff, 0xf4, 0xb3, 0xf8, +0xdb, 0x43, 0xa7, 0x71, 0xeb, 0xcb, 0x6f, 0xc2, +0xcf, 0x5c, 0xbf, 0x1d, 0x3f, 0x73, 0xfd, 0x76, +0xeb, 0x70, 0x56, 0xeb, 0x4d, 0xf4, 0x0d, 0x0c, +0xe2, 0x23, 0xb5, 0x2b, 0xd5, 0x75, 0x16, 0x25, +0x52, 0x21, 0x70, 0xcb, 0x98, 0x84, 0x61, 0x5b, +0x9b, 0xb2, 0x68, 0x6b, 0x24, 0x53, 0xc6, 0x7b, +0x6f, 0x3b, 0x88, 0x2b, 0x27, 0x77, 0xe3, 0x4b, +0x93, 0x9d, 0x4d, 0x0a, 0x95, 0x2a, 0x3e, 0xf9, +0x89, 0x4f, 0x60, 0x69, 0x69, 0x09, 0x47, 0xd7, +0x42, 0xf2, 0x78, 0xbb, 0x9b, 0x77, 0x6d, 0xc5, +0x17, 0x2d, 0x6b, 0x6b, 0x7e, 0x7e, 0x1e, 0x0f, +0x6d, 0x09, 0x66, 0x0a, 0xa4, 0xf5, 0xfc, 0xb3, +0x6b, 0xeb, 0xcd, 0x46, 0x47, 0x5a, 0x6f, 0xe7, +0xbd, 0x9c, 0x3a, 0x06, 0x9f, 0x1e, 0x36, 0x1f, +0x97, 0x84, 0x83, 0xc4, 0xed, 0xdf, 0xf3, 0xee, +0xbb, 0x27, 0xdc, 0x96, 0xcf, 0x64, 0x1d, 0xc7, +0x41, 0xbd, 0x5e, 0x87, 0xe3, 0x38, 0x28, 0x97, +0x56, 0xfd, 0xef, 0x9e, 0xe7, 0xa1, 0x5e, 0xaf, +0xfb, 0x36, 0xf2, 0x42, 0xa1, 0x00, 0xc7, 0x71, +0x02, 0xf9, 0xd0, 0xe9, 0x7b, 0xb9, 0x5c, 0xc6, +0xe2, 0xe2, 0x62, 0x1b, 0xc6, 0x1a, 0xb3, 0x1a, +0x19, 0x19, 0xf1, 0x25, 0x7a, 0xc7, 0x71, 0x30, +0x32, 0x32, 0x82, 0x91, 0x91, 0x11, 0x2c, 0x2e, +0x2e, 0xa2, 0x54, 0x2a, 0x21, 0x99, 0x4c, 0xfa, +0x30, 0x47, 0x46, 0x46, 0xfc, 0x36, 0xd4, 0xf7, +0xe3, 0x8f, 0x3f, 0x8e, 0xd9, 0xd9, 0x59, 0x2c, +0x2e, 0x2e, 0x62, 0x71, 0x71, 0x11, 0x85, 0x42, +0x21, 0xc0, 0x20, 0x0a, 0x85, 0x02, 0x0a, 0x85, +0x82, 0x51, 0x53, 0xe0, 0x38, 0xc1, 0xc9, 0xe7, +0xdf, 0x69, 0xbc, 0xf4, 0x99, 0xd3, 0x81, 0xfe, +0x78, 0x7d, 0x7a, 0x57, 0x2e, 0x97, 0xfd, 0xe7, +0xbc, 0x3f, 0x6a, 0xc3, 0x0b, 0x31, 0x3a, 0x4e, +0x4f, 0x1a, 0x2f, 0xef, 0xb3, 0x5c, 0x2e, 0x23, +0x9b, 0xcd, 0xfa, 0x75, 0xf9, 0x1f, 0xc1, 0xce, +0x66, 0xb3, 0x81, 0x3e, 0x09, 0x3f, 0x8e, 0x2b, +0x7d, 0xe6, 0x8c, 0x9e, 0xc3, 0xa2, 0x3e, 0xf9, +0xdc, 0x72, 0xba, 0x48, 0xe6, 0x1b, 0x8b, 0xc5, +0xd4, 0x77, 0x12, 0x3f, 0x0e, 0x1b, 0x68, 0x1f, +0x06, 0x24, 0x5e, 0x54, 0xb7, 0xd1, 0x68, 0x74, +0xd0, 0xbd, 0x52, 0xa9, 0xa0, 0x58, 0x2c, 0xa2, +0x52, 0xa9, 0xf8, 0xf3, 0x59, 0x2c, 0x16, 0x51, +0x2c, 0x16, 0x51, 0x2e, 0x97, 0x7d, 0xba, 0xb7, +0x5a, 0x2d, 0xa4, 0xd3, 0x69, 0x24, 0x93, 0x49, +0xb4, 0x5a, 0x2d, 0x1f, 0x47, 0xa2, 0x1d, 0x8d, +0x69, 0xab, 0xe7, 0xe0, 0x0a, 0xb7, 0x89, 0xa4, +0xeb, 0x61, 0xb6, 0xd8, 0x40, 0xb5, 0xd9, 0x0a, +0xfe, 0xf0, 0x01, 0xa0, 0xd5, 0x5c, 0xff, 0x9f, +0x70, 0xf4, 0xef, 0xf4, 0x4c, 0xbe, 0xa7, 0x22, +0x9f, 0xd1, 0xff, 0x78, 0xdc, 0x0e, 0xdf, 0xd4, +0x4e, 0xf6, 0xa7, 0xf5, 0xab, 0xc1, 0xe1, 0xf5, +0x64, 0xdb, 0x84, 0xd3, 0x89, 0x0f, 0xdf, 0x18, +0xb4, 0xb1, 0x68, 0x63, 0xe5, 0x7d, 0xc8, 0x7e, +0x08, 0x8e, 0x7c, 0x2f, 0x9f, 0xaf, 0xfd, 0xff, +0xf5, 0x9b, 0x76, 0x00, 0x00, 0xbe, 0xfa, 0xd5, +0xaf, 0xe2, 0x81, 0xf4, 0x9e, 0x4e, 0x7a, 0x9b, +0xc6, 0xbb, 0x56, 0xef, 0x53, 0x4b, 0x71, 0xcc, +0x3d, 0xfe, 0x08, 0xc6, 0x1b, 0x05, 0xdf, 0x59, +0x13, 0x68, 0xdb, 0x31, 0xa7, 0xbf, 0xf5, 0x18, +0x3e, 0xfd, 0xc9, 0x8f, 0xe3, 0xf8, 0xf1, 0xe3, +0xb8, 0x27, 0x77, 0x1d, 0x9e, 0x72, 0x47, 0x71, +0xaa, 0x50, 0xc5, 0x67, 0x8f, 0x9d, 0xc4, 0xc1, +0xd5, 0xd3, 0xc8, 0x66, 0xb3, 0x68, 0x25, 0x5d, +0x24, 0xe3, 0x6d, 0x35, 0xf6, 0x99, 0x33, 0x67, +0xf0, 0xf5, 0xaf, 0x7f, 0x1d, 0x1f, 0xff, 0xe4, +0x27, 0x71, 0xae, 0x50, 0xc2, 0xc7, 0xfa, 0xaf, +0xc6, 0x4a, 0xa2, 0x2d, 0x69, 0x1f, 0x39, 0x5b, +0xc4, 0x6b, 0x06, 0x1a, 0xe8, 0xeb, 0xeb, 0x43, +0x32, 0x1e, 0x43, 0xad, 0x52, 0x46, 0xe3, 0xfe, +0x0f, 0xe1, 0x2b, 0x7d, 0x7b, 0xf1, 0x8d, 0x95, +0x16, 0xe6, 0x9f, 0x7e, 0x12, 0x7b, 0xdd, 0x16, +0xd2, 0xd9, 0x2c, 0x52, 0x4e, 0x02, 0x85, 0x4a, +0x15, 0xcf, 0xcf, 0x9e, 0xc0, 0xa7, 0x3f, 0xfd, +0x69, 0x5c, 0x77, 0xdd, 0x75, 0x28, 0x54, 0xaa, +0xf8, 0xc2, 0x03, 0xf7, 0xe3, 0x4b, 0x03, 0xfb, +0x81, 0x84, 0x83, 0x5f, 0x7f, 0x59, 0x5b, 0x78, +0xf9, 0xe2, 0x17, 0xbf, 0x88, 0x07, 0xfa, 0xae, +0xe8, 0x18, 0xf7, 0xb3, 0x65, 0xe0, 0xfe, 0x87, +0xbf, 0x89, 0xf1, 0xc5, 0x67, 0x11, 0x8f, 0xc7, +0x91, 0xca, 0xb4, 0xe1, 0x16, 0x8b, 0x45, 0x3c, +0xf3, 0xcc, 0x33, 0xf8, 0xe4, 0x27, 0x3f, 0x89, +0x53, 0x4f, 0x7e, 0x0b, 0x17, 0xe2, 0x69, 0xfc, +0xfd, 0xe0, 0x0d, 0xa8, 0xc5, 0x12, 0xb8, 0xd8, +0x4a, 0xe0, 0xde, 0x13, 0x67, 0x51, 0x7d, 0xfc, +0x28, 0x62, 0xa5, 0x15, 0x24, 0x12, 0x09, 0x24, +0x12, 0x09, 0xa4, 0x52, 0x6d, 0xc9, 0xbb, 0x58, +0x2c, 0xe2, 0xf9, 0xe7, 0x9f, 0xc7, 0xa3, 0x8f, +0x3e, 0x8a, 0xbf, 0xfb, 0xd0, 0xdf, 0xe0, 0xcc, +0xd9, 0x45, 0x7c, 0xb6, 0x6f, 0x1f, 0xbe, 0xd6, +0x37, 0x11, 0x58, 0x0b, 0x17, 0x1b, 0x31, 0x7c, +0x78, 0xa1, 0x89, 0x53, 0x0f, 0x7f, 0x19, 0xb9, +0xca, 0x72, 0x07, 0x9c, 0x0b, 0x17, 0x2e, 0xe0, +0xcc, 0x99, 0x33, 0x78, 0xf4, 0xd1, 0x47, 0x71, +0xe2, 0xc4, 0x09, 0xec, 0x9a, 0xdc, 0x83, 0x1b, +0xaf, 0xbd, 0x1a, 0xb7, 0x0e, 0x39, 0xf8, 0xd3, +0xe7, 0x56, 0xfc, 0xb1, 0xd0, 0xdc, 0x46, 0x29, +0x89, 0x7b, 0xff, 0xac, 0x4d, 0x07, 0x6d, 0x8d, +0x69, 0xeb, 0x94, 0xc1, 0xff, 0xec, 0x67, 0x3f, +0x8b, 0x2f, 0x0d, 0x5d, 0x6d, 0x5c, 0xaf, 0x9f, +0x5a, 0xa8, 0x1a, 0xd7, 0xc8, 0x23, 0x8f, 0x3c, +0x82, 0xfb, 0xee, 0xb9, 0x07, 0x27, 0x9e, 0x7d, +0x16, 0xf7, 0xe4, 0xae, 0xc3, 0xe3, 0xee, 0xd8, +0xfa, 0xda, 0x0a, 0x69, 0xf7, 0xb1, 0x8f, 0xfc, +0x3d, 0xe6, 0xe6, 0xe6, 0x70, 0xdf, 0xf0, 0x21, +0x7c, 0xab, 0x6f, 0x17, 0xd0, 0xa8, 0x77, 0xac, +0xe7, 0x53, 0x85, 0x2a, 0xbe, 0x70, 0x62, 0x01, +0xfb, 0x2f, 0xce, 0x06, 0xd6, 0xdb, 0x6a, 0xbd, +0x89, 0x95, 0xfc, 0x12, 0xbe, 0xfa, 0xd5, 0xaf, +0xe2, 0xe3, 0x1f, 0xfb, 0x38, 0xf2, 0x85, 0x22, +0xfe, 0x76, 0xf8, 0xe5, 0x58, 0x89, 0xbb, 0xdd, +0xed, 0x47, 0xec, 0x7f, 0xec, 0xc7, 0xfe, 0xf4, +0xe3, 0xad, 0x97, 0x37, 0xce, 0x76, 0xc4, 0x85, +0xf3, 0x0c, 0x64, 0x73, 0x73, 0x73, 0xbe, 0xe7, +0x30, 0xbd, 0xe7, 0x12, 0xb6, 0x94, 0x12, 0x29, +0x51, 0x0b, 0xb0, 0x6e, 0xe3, 0xa6, 0x10, 0x24, +0xae, 0x01, 0xc8, 0xe5, 0x72, 0x98, 0x9e, 0x9e, +0xf6, 0x43, 0xcc, 0xb8, 0xcd, 0x96, 0xfa, 0x24, +0x38, 0x47, 0x8f, 0x1e, 0x0d, 0x38, 0xcf, 0x69, +0x9e, 0xef, 0x5a, 0xaa, 0x52, 0x7a, 0xaf, 0x7d, +0xe6, 0xdf, 0x35, 0x49, 0x33, 0x8a, 0x84, 0x4d, +0xf5, 0x4c, 0xaa, 0x6e, 0x4d, 0xca, 0x36, 0x85, +0x9b, 0x49, 0xc7, 0x33, 0x1b, 0x8e, 0x7c, 0x0e, +0xa4, 0xd3, 0xa1, 0x6d, 0xfc, 0x12, 0x7f, 0x0d, +0x3f, 0xee, 0x07, 0x01, 0xc0, 0xbf, 0xb9, 0x4a, +0xc3, 0x85, 0x8f, 0x9f, 0x3f, 0xa3, 0xb6, 0x32, +0x2b, 0x9c, 0xcd, 0x5f, 0xc1, 0xf6, 0x9f, 0xd3, +0x85, 0xc3, 0xe0, 0x52, 0xbb, 0xcc, 0xec, 0x57, +0xa9, 0x54, 0x50, 0x2e, 0x97, 0x51, 0xad, 0x37, +0x50, 0xae, 0x56, 0xf1, 0xb9, 0x95, 0x14, 0xfe, +0x62, 0x29, 0xdd, 0xbe, 0xdd, 0x89, 0x97, 0x6e, +0xa5, 0xea, 0x28, 0x9e, 0xf0, 0x51, 0xea, 0x47, +0x85, 0x6f, 0xc2, 0xd3, 0x54, 0x6c, 0xbe, 0x01, +0x51, 0xe0, 0x44, 0x85, 0xaf, 0x99, 0x2c, 0xba, +0x85, 0x81, 0x76, 0x66, 0xb4, 0x80, 0x03, 0x5c, +0x0f, 0x9e, 0xf5, 0x3b, 0xaa, 0x17, 0x70, 0xb8, +0x7c, 0x1a, 0x23, 0xc5, 0xb3, 0xd8, 0x91, 0x6c, +0x6f, 0x70, 0x67, 0x6a, 0x71, 0x9c, 0x72, 0xb7, +0xe0, 0xeb, 0x83, 0x57, 0xb5, 0xe3, 0xed, 0x59, +0x19, 0x47, 0x19, 0x37, 0x14, 0x4f, 0x62, 0x6f, +0xf9, 0x2c, 0x06, 0x1b, 0x25, 0xb8, 0xf1, 0x76, +0x7c, 0x35, 0x79, 0xcd, 0x7f, 0x21, 0xbd, 0xb7, +0xe3, 0xd2, 0x9c, 0x1d, 0xd5, 0x0b, 0xb8, 0xab, +0x78, 0x1c, 0x7b, 0x1a, 0x79, 0x00, 0xed, 0x4c, +0x79, 0xbf, 0x3d, 0xf2, 0x5a, 0x1f, 0xe6, 0xde, +0xe6, 0x45, 0xdc, 0xb6, 0xbc, 0x1e, 0x0a, 0xb6, +0x52, 0x6b, 0x22, 0xbe, 0xeb, 0x2a, 0xfc, 0xfb, +0x1f, 0x79, 0x27, 0xce, 0x9c, 0x39, 0x83, 0xff, +0xef, 0x8f, 0xfe, 0x04, 0xff, 0x71, 0xfc, 0x8d, +0x7e, 0xfd, 0x5f, 0x39, 0xfb, 0x19, 0xb8, 0x71, +0x04, 0x6f, 0xd7, 0x12, 0x63, 0xde, 0xde, 0x58, +0xc1, 0x8d, 0xab, 0xcf, 0x63, 0xb2, 0x7a, 0x01, +0x83, 0xe5, 0xb6, 0x96, 0xaa, 0x80, 0x04, 0xce, +0x25, 0xfa, 0xf1, 0x64, 0x66, 0xe7, 0x7a, 0xa2, +0x11, 0xd1, 0xfe, 0xea, 0xda, 0x39, 0x4c, 0x95, +0xe6, 0x30, 0x5e, 0x5b, 0x46, 0x5f, 0xab, 0x8a, +0x2c, 0x1a, 0xa8, 0x54, 0x2a, 0xa8, 0xb9, 0x7d, +0x38, 0x97, 0xe8, 0xc7, 0x4c, 0x6a, 0x04, 0x8f, +0xf5, 0xef, 0x59, 0xbb, 0xe9, 0xcf, 0xbc, 0x26, +0xb6, 0x37, 0x56, 0x30, 0x55, 0x9e, 0xc7, 0x55, +0xe5, 0x79, 0x0c, 0x30, 0x38, 0xab, 0x5e, 0x3f, +0xe6, 0x93, 0x39, 0x2c, 0x24, 0x32, 0x48, 0x79, +0x69, 0xfc, 0xca, 0xa1, 0x51, 0x0c, 0x6d, 0x1d, +0xc5, 0x7f, 0xfe, 0xc8, 0xbd, 0xf8, 0xb3, 0x91, +0xdb, 0x7c, 0x58, 0xbf, 0xf2, 0xfc, 0x47, 0xd5, +0x8b, 0x50, 0xf8, 0x67, 0xfa, 0xff, 0x6b, 0x23, +0x77, 0x75, 0xfd, 0x9b, 0xf3, 0xd7, 0xce, 0x8e, +0xb7, 0x84, 0xb6, 0xa5, 0x35, 0x32, 0x5e, 0x5b, +0xc6, 0xb6, 0x56, 0x5b, 0xf3, 0xb7, 0xec, 0xe5, +0x30, 0x9b, 0x1a, 0xc6, 0x23, 0x7d, 0xbb, 0xdb, +0xc9, 0xa2, 0x94, 0xf5, 0x46, 0xed, 0x76, 0xd7, +0x2e, 0x60, 0xa8, 0x55, 0x0d, 0xb4, 0xfb, 0x6a, +0x72, 0x27, 0x2e, 0x78, 0x83, 0x81, 0xfa, 0x1d, +0xeb, 0x19, 0xc0, 0x70, 0xab, 0x82, 0xc3, 0xab, +0xb3, 0xd8, 0x5d, 0x3e, 0x8b, 0xed, 0x6b, 0x7d, +0x23, 0xe9, 0xe2, 0x7c, 0x22, 0x8d, 0xa7, 0xbd, +0x31, 0x3c, 0x94, 0xda, 0x8e, 0xa2, 0x37, 0x18, +0xed, 0x77, 0x6f, 0x98, 0xab, 0xd8, 0xff, 0xf3, +0xd7, 0xf7, 0xb4, 0x76, 0x9f, 0x7f, 0xb6, 0xc3, +0x1e, 0x4b, 0x9e, 0xe5, 0xb9, 0x5c, 0x0e, 0x27, +0x4e, 0x9c, 0xc0, 0x0d, 0x37, 0xdc, 0xe0, 0x27, +0x05, 0x21, 0x3b, 0xb5, 0xe7, 0x79, 0xea, 0x2d, +0x5a, 0x33, 0x33, 0x33, 0x81, 0xd8, 0x70, 0x9e, +0xc9, 0x8b, 0x87, 0x18, 0xe5, 0x72, 0x39, 0x1c, +0x3b, 0x76, 0xcc, 0x57, 0xb1, 0xcf, 0xcd, 0xcd, +0x61, 0x68, 0x68, 0xc8, 0x3f, 0x40, 0x90, 0x16, +0x60, 0x69, 0x69, 0x09, 0x4f, 0x3d, 0xf5, 0x54, +0x60, 0x83, 0xef, 0x30, 0x09, 0x08, 0x47, 0x37, +0x5e, 0x4c, 0xcc, 0x31, 0xcc, 0xb9, 0xcc, 0x54, +0xcf, 0xa4, 0xbe, 0x37, 0x79, 0xc0, 0x4b, 0xf8, +0x36, 0x2f, 0x75, 0xce, 0x0c, 0xa5, 0x83, 0x9b, +0x1c, 0x0b, 0x1d, 0x00, 0x4c, 0x9e, 0xf0, 0x7c, +0x3c, 0x5a, 0x89, 0xca, 0x30, 0x09, 0x1f, 0xcd, +0x0b, 0xdf, 0x34, 0x46, 0x3e, 0x4e, 0x6e, 0x3a, +0xe1, 0x07, 0x12, 0xfa, 0x21, 0x4b, 0x6d, 0x8a, +0x29, 0xea, 0x40, 0xa3, 0x19, 0x95, 0xbe, 0x81, +0x41, 0xf4, 0xa7, 0xdb, 0xdf, 0xb9, 0x63, 0x1e, +0x8f, 0x85, 0xaf, 0x36, 0x5b, 0x38, 0x5b, 0x28, +0xe3, 0x2f, 0xce, 0x25, 0xf0, 0xd8, 0x4a, 0x03, +0xb3, 0xc5, 0xc6, 0xfa, 0x66, 0x66, 0x2a, 0x51, +0x19, 0x4a, 0x0f, 0x0c, 0x28, 0x12, 0xfc, 0x30, +0x86, 0x1b, 0xc6, 0xb8, 0xa3, 0xf4, 0x63, 0x83, +0xd5, 0xcd, 0xb8, 0xa2, 0x1c, 0x6e, 0xc2, 0x0e, +0x3e, 0x51, 0xe0, 0x46, 0x71, 0x5e, 0x34, 0xf5, +0x03, 0x44, 0xa3, 0x57, 0xc4, 0x52, 0xf8, 0x91, +0x76, 0x48, 0xd8, 0x2f, 0x7f, 0xed, 0x0c, 0xfe, +0xf7, 0x33, 0x17, 0x70, 0x66, 0xb5, 0x06, 0x34, +0xea, 0xd8, 0x92, 0x4a, 0xe0, 0xf6, 0x9d, 0x39, +0xfc, 0xce, 0xad, 0xbb, 0xb0, 0xb7, 0x3f, 0x85, +0x4f, 0x7d, 0xea, 0x53, 0xb8, 0x6f, 0x7a, 0x06, +0xff, 0x6d, 0xcb, 0x1d, 0xd1, 0x68, 0xd0, 0xed, +0x7a, 0x8a, 0x7a, 0xa0, 0x8c, 0xda, 0x36, 0x0c, +0x2f, 0x51, 0xb2, 0xf1, 0x16, 0x6e, 0x5e, 0x39, +0x8e, 0xa1, 0x46, 0x09, 0x1f, 0x19, 0xb8, 0x2e, +0xfa, 0x5c, 0x76, 0x33, 0x86, 0x28, 0x63, 0x37, +0x1d, 0x30, 0x7b, 0xfd, 0x1d, 0xf7, 0x72, 0x30, +0xee, 0x66, 0x1c, 0x51, 0xd6, 0x74, 0x44, 0x9c, +0x9d, 0x84, 0xd7, 0x17, 0x64, 0x5a, 0xb5, 0x06, +0x72, 0xfd, 0xed, 0x53, 0x2c, 0x31, 0x14, 0x7e, +0xd7, 0x37, 0x31, 0x57, 0x62, 0xba, 0xdc, 0x49, +0x8c, 0xdb, 0x4a, 0x81, 0xe0, 0xb5, 0xa3, 0x7c, +0x73, 0xe7, 0xd2, 0xf5, 0xd0, 0xd0, 0x90, 0xcf, +0x88, 0x97, 0x97, 0x97, 0x03, 0x0e, 0x26, 0xdc, +0x99, 0x4d, 0x5e, 0xce, 0x62, 0xb2, 0x8b, 0xd3, +0x38, 0xb4, 0x62, 0xb3, 0x37, 0xf3, 0xf6, 0x5a, +0x1b, 0xed, 0x99, 0xf4, 0x25, 0xb0, 0xd9, 0xa0, +0x6d, 0xa1, 0x68, 0x26, 0xc9, 0x98, 0xfa, 0x90, +0x07, 0x11, 0x6e, 0xcf, 0x0e, 0x83, 0x2b, 0xf1, +0x8d, 0x82, 0x9b, 0x7c, 0x26, 0xed, 0x7a, 0x9a, +0x23, 0x23, 0xc7, 0x55, 0xd2, 0x99, 0x0e, 0x81, +0x1c, 0xae, 0x84, 0x29, 0x25, 0x77, 0x4d, 0xca, +0xd7, 0x70, 0xe3, 0x7d, 0x5f, 0x40, 0xe7, 0x61, +0x24, 0x70, 0x75, 0x22, 0x80, 0xfe, 0xb4, 0x87, +0x5f, 0x1e, 0xa8, 0x60, 0xa5, 0xda, 0xc0, 0xa3, +0x2b, 0x4d, 0xfc, 0xd5, 0x99, 0x1a, 0xbe, 0xb5, +0xd2, 0x34, 0x33, 0xf5, 0xa8, 0x1b, 0x49, 0x98, +0xd3, 0x98, 0xa9, 0x74, 0x73, 0x12, 0xb7, 0xf5, +0xa7, 0xc1, 0xd2, 0x1c, 0xe7, 0xa2, 0xc0, 0x0a, +0xb3, 0x8f, 0xdb, 0x6c, 0xea, 0x61, 0xbe, 0x05, +0xb6, 0x77, 0x36, 0x1a, 0xd9, 0x68, 0x66, 0xa3, +0x81, 0x36, 0x4e, 0x09, 0x37, 0xec, 0x30, 0x60, +0xd9, 0x70, 0x7f, 0xf3, 0x91, 0x39, 0x7c, 0xf0, +0xe6, 0x1d, 0xfe, 0x9f, 0x56, 0x1e, 0x9e, 0x39, +0x8e, 0x47, 0x1f, 0x7d, 0x14, 0xdf, 0x48, 0xef, +0x33, 0xdb, 0x7a, 0xa3, 0xd0, 0x24, 0x8a, 0x26, +0xa5, 0x17, 0xad, 0x8b, 0x8d, 0xfe, 0x51, 0x7c, +0x18, 0x00, 0x14, 0x9a, 0xb1, 0x40, 0x42, 0x96, +0xc8, 0x07, 0x09, 0x5b, 0x5f, 0xdd, 0xb6, 0xb3, +0x8d, 0xc5, 0x26, 0xd9, 0x46, 0xf1, 0x37, 0x31, +0xd1, 0x4f, 0xda, 0xef, 0x4d, 0xb0, 0xc3, 0xc6, +0x16, 0xe5, 0x30, 0x15, 0xf2, 0xdb, 0x4a, 0xbc, +0xe2, 0xfb, 0xde, 0x73, 0xf7, 0xce, 0x64, 0x03, +0x89, 0x58, 0x0c, 0x4b, 0x2b, 0x45, 0xa4, 0x93, +0x09, 0x7f, 0x83, 0x1e, 0x19, 0x19, 0x41, 0xa1, +0x50, 0xf0, 0xed, 0x9e, 0x9e, 0xe7, 0x21, 0x9b, +0xcd, 0xa2, 0x58, 0x2c, 0xfa, 0xde, 0xc4, 0x64, +0xc3, 0x04, 0xda, 0x76, 0xcf, 0x42, 0xa1, 0x00, +0xa0, 0x2d, 0xd9, 0x17, 0x0a, 0x05, 0x64, 0xb3, +0x59, 0xdf, 0x86, 0x4e, 0x9f, 0xe5, 0xa1, 0x20, +0x97, 0xcb, 0xf9, 0x75, 0xeb, 0xf5, 0x3a, 0xf2, +0xf9, 0x3c, 0xea, 0xf5, 0x3a, 0xce, 0x9c, 0x39, +0xd3, 0x11, 0x6a, 0xc6, 0xfb, 0x23, 0x58, 0xdc, +0x3e, 0xec, 0x38, 0x4e, 0xc0, 0xde, 0xcc, 0xed, +0xcf, 0xdc, 0x76, 0xce, 0xed, 0xbf, 0x1c, 0xa6, +0x66, 0x9b, 0xa6, 0xef, 0xb2, 0x70, 0x3b, 0x30, +0x7f, 0xc6, 0xbf, 0x93, 0xad, 0x9a, 0xea, 0x4a, +0x95, 0x3c, 0x67, 0xbc, 0x84, 0x2f, 0xef, 0x8f, +0xdb, 0xd8, 0x79, 0x5f, 0xc4, 0xe0, 0xc8, 0xce, +0x2e, 0xf1, 0xd4, 0x7c, 0x02, 0xb8, 0xbd, 0x5c, +0x1e, 0x82, 0xa4, 0x4f, 0x80, 0x6c, 0x97, 0x4c, +0x26, 0x3b, 0xf0, 0x93, 0x38, 0xd1, 0xf8, 0x38, +0xfd, 0x89, 0x99, 0xd3, 0x3c, 0x50, 0x89, 0xc5, +0x62, 0x68, 0x34, 0x1a, 0x01, 0x5a, 0x48, 0xda, +0x71, 0x3c, 0xa4, 0xff, 0x02, 0xe1, 0x9c, 0xf2, +0xd2, 0x48, 0xc4, 0xe3, 0x3e, 0x3e, 0x7c, 0x4d, +0x34, 0x1a, 0x0d, 0xd4, 0xeb, 0x75, 0x54, 0x2a, +0x95, 0x80, 0xcd, 0xbf, 0xbf, 0xbf, 0x1f, 0xa9, +0x78, 0x0c, 0x57, 0xf4, 0xa7, 0x70, 0xe7, 0x68, +0x1a, 0xbb, 0x5d, 0x60, 0xb6, 0xd8, 0xc0, 0x85, +0x16, 0xb3, 0x29, 0x4b, 0xfb, 0xb2, 0x66, 0xbb, +0xd6, 0x98, 0x86, 0xb4, 0x1d, 0x6b, 0x6d, 0xe5, +0x7f, 0x6e, 0x1f, 0x06, 0xac, 0x36, 0x62, 0xab, +0x3d, 0x5c, 0xb3, 0x35, 0x9b, 0x6c, 0xd7, 0x12, +0xae, 0xc9, 0x36, 0x17, 0x66, 0xb3, 0x97, 0xbe, +0x01, 0x26, 0x5b, 0xba, 0xa4, 0x69, 0x18, 0x4d, +0x34, 0xdb, 0xbf, 0x66, 0x47, 0x37, 0xd5, 0x33, +0xd9, 0x5c, 0x65, 0xff, 0x26, 0xfa, 0x9a, 0x6c, +0xf6, 0xa2, 0xdd, 0x97, 0xcf, 0x96, 0xb0, 0xfa, +0xcc, 0x37, 0xb1, 0x3d, 0x56, 0x41, 0x26, 0x93, +0xe9, 0xb0, 0x4f, 0x7f, 0xfa, 0xd3, 0x9f, 0xc6, +0xc3, 0x5f, 0xfd, 0x32, 0x9e, 0x28, 0x27, 0xf0, +0xe5, 0x6d, 0x37, 0xb6, 0x7d, 0x36, 0x7a, 0x5d, +0x47, 0x61, 0x74, 0x31, 0xf9, 0x2c, 0x68, 0x6b, +0xca, 0xe4, 0x5b, 0x61, 0x9a, 0x1f, 0x9b, 0x0f, +0x43, 0x37, 0x73, 0x65, 0xf2, 0xa9, 0xd0, 0x7c, +0x39, 0xba, 0x5d, 0x1f, 0x36, 0xfc, 0x4d, 0xbf, +0xab, 0x6e, 0xfa, 0x31, 0xad, 0xef, 0x28, 0xbe, +0x2f, 0xa6, 0xf1, 0x77, 0xe3, 0x7b, 0x12, 0xf2, +0xdb, 0x77, 0x1a, 0xe5, 0x55, 0x34, 0x1b, 0x95, +0x75, 0xc9, 0xba, 0xb8, 0x12, 0xb0, 0x47, 0x53, +0x7c, 0x39, 0xb7, 0x77, 0x93, 0x8d, 0x9b, 0x7b, +0x2c, 0xf3, 0x70, 0x35, 0x52, 0xa3, 0xd3, 0x35, +0xa5, 0x00, 0x02, 0x8c, 0x9b, 0x36, 0xf0, 0x4a, +0xa5, 0x12, 0x90, 0xe2, 0x96, 0x96, 0x96, 0x7c, +0x7b, 0x7b, 0x3e, 0x9f, 0x0f, 0xa8, 0xf3, 0xa5, +0x1a, 0x96, 0x8a, 0xc9, 0x1e, 0x1e, 0x16, 0x06, +0x45, 0xc5, 0x24, 0x55, 0x47, 0x55, 0x27, 0x13, +0x0c, 0x53, 0x5f, 0xd2, 0xc3, 0x5f, 0xeb, 0xd7, +0x66, 0xd3, 0x06, 0x10, 0x30, 0x59, 0x98, 0xf0, +0x88, 0xa2, 0x55, 0x08, 0x1b, 0x1f, 0x9f, 0x8b, +0xc1, 0xc1, 0xc1, 0x8e, 0x4c, 0x53, 0x26, 0x3b, +0xbe, 0xe9, 0x19, 0xff, 0xcf, 0x73, 0xaf, 0x9b, +0xf0, 0xb2, 0x99, 0x0b, 0xb4, 0xb1, 0xb6, 0xff, +0x77, 0x6a, 0x03, 0x34, 0xb8, 0xc0, 0xba, 0x94, +0xce, 0x6d, 0xeb, 0xe3, 0xfd, 0x69, 0x7c, 0x97, +0x03, 0xdc, 0x31, 0x08, 0xfc, 0xe9, 0xd9, 0x04, +0x3e, 0x79, 0xba, 0x80, 0x05, 0x84, 0x24, 0x6e, +0xa0, 0x12, 0x45, 0x5a, 0x96, 0xa7, 0x7e, 0x93, +0x44, 0x19, 0x76, 0x02, 0x8f, 0x22, 0x9d, 0x76, +0xab, 0x06, 0xb4, 0x49, 0x89, 0x36, 0x49, 0x3a, +0x0a, 0x2d, 0x4c, 0xe3, 0x8f, 0x8a, 0x7f, 0x54, +0x75, 0xba, 0x49, 0xba, 0x89, 0x22, 0x99, 0xdb, +0xe8, 0x6b, 0x9a, 0x0f, 0x29, 0x75, 0x01, 0xf8, +0x8f, 0xf9, 0x61, 0xdc, 0x73, 0xff, 0x2c, 0xa6, +0x4a, 0x47, 0x7c, 0xbb, 0x2a, 0xd0, 0xb6, 0xa9, +0xbf, 0x90, 0x18, 0xc4, 0xa3, 0x83, 0x37, 0xe0, +0x89, 0x91, 0xad, 0x6b, 0x37, 0x90, 0x85, 0xe0, +0x1d, 0x46, 0x83, 0xa8, 0x6b, 0x24, 0xea, 0x7a, +0x8a, 0x3a, 0x3f, 0x1b, 0xf5, 0xfb, 0x88, 0xba, +0x2e, 0x4c, 0xf3, 0x62, 0x5a, 0x1f, 0xb2, 0x8e, +0x09, 0x7f, 0x0d, 0x27, 0x6d, 0x6d, 0xd8, 0x7e, +0x67, 0x36, 0x15, 0xbe, 0x69, 0x1c, 0x61, 0xe3, +0xb7, 0x69, 0x07, 0xb4, 0x62, 0xd2, 0x22, 0x24, +0x9c, 0x76, 0x3a, 0x57, 0xcf, 0x6b, 0x67, 0x7b, +0x93, 0x2a, 0x53, 0x7a, 0x47, 0xff, 0x4d, 0xe1, +0x60, 0x5a, 0x98, 0x15, 0x2f, 0xe5, 0x72, 0xd9, +0x77, 0xa0, 0xe2, 0x92, 0x39, 0xdd, 0x94, 0x46, +0x87, 0x02, 0xba, 0xd1, 0x8c, 0x98, 0xb9, 0x64, +0x7e, 0xa6, 0x84, 0x24, 0xda, 0x86, 0x1f, 0x16, +0x8e, 0xa5, 0x39, 0xa9, 0xd9, 0x1c, 0xba, 0x38, +0x6c, 0xd9, 0x8e, 0xd3, 0x4b, 0xc3, 0xc9, 0xa6, +0x0a, 0xd7, 0xec, 0xc3, 0xa6, 0x3a, 0x12, 0x4f, +0x5b, 0x1b, 0xd3, 0x1c, 0xca, 0x77, 0xf2, 0x39, +0xc1, 0xe7, 0xce, 0x29, 0x32, 0xeb, 0x9a, 0xc9, +0x0c, 0x60, 0xf2, 0x19, 0xe0, 0xf3, 0x49, 0x87, +0x3d, 0xfa, 0x93, 0x87, 0x9d, 0x4e, 0x66, 0x1d, +0x9c, 0x7f, 0xd3, 0xfc, 0x52, 0xd1, 0x9c, 0x01, +0xe5, 0x5c, 0xf1, 0x03, 0x0a, 0x69, 0x7d, 0x46, +0xfa, 0xfb, 0xf0, 0xeb, 0xdb, 0xd2, 0x78, 0xdd, +0x70, 0x0c, 0xf7, 0xcf, 0x97, 0xf0, 0xf1, 0xb3, +0x75, 0x14, 0x1b, 0x58, 0x57, 0xbf, 0xdb, 0x18, +0x70, 0x17, 0x6a, 0xd9, 0x48, 0x76, 0xd1, 0x6e, +0x55, 0x82, 0xbc, 0x1d, 0xc1, 0xa5, 0xef, 0xa6, +0x8d, 0xce, 0xf4, 0x2c, 0x8a, 0x1a, 0x50, 0xdb, +0xbc, 0xc2, 0x98, 0x94, 0xd6, 0xce, 0xa6, 0xc2, +0xd5, 0xea, 0xd9, 0x98, 0x86, 0x84, 0xaf, 0xc1, +0xb1, 0x3d, 0xb3, 0x31, 0x3f, 0x1b, 0x5e, 0x6b, +0x7d, 0x3e, 0xe1, 0x8d, 0xe3, 0x89, 0x64, 0x67, +0xf8, 0x92, 0x91, 0x3e, 0xdd, 0xae, 0x97, 0x30, +0xa6, 0x1e, 0x15, 0x7f, 0x93, 0xfa, 0x37, 0xca, +0xfc, 0xd8, 0xe6, 0x44, 0xf6, 0x13, 0xc5, 0x4c, +0x13, 0xf6, 0x5d, 0xc3, 0xc7, 0xb6, 0xfe, 0xa3, +0xac, 0x2f, 0x13, 0x9e, 0x36, 0xba, 0x84, 0xfd, +0xde, 0x6c, 0x78, 0xd8, 0x68, 0x19, 0x46, 0x1f, +0x8d, 0x0e, 0xa6, 0x43, 0x67, 0xa3, 0x0e, 0xe7, +0x62, 0xb3, 0x7d, 0xd1, 0x88, 0x1b, 0x8f, 0xa1, +0x25, 0x6c, 0xc1, 0xdc, 0x2b, 0x5d, 0xbb, 0x36, +0x94, 0xdb, 0x32, 0xb5, 0x44, 0x26, 0xc4, 0xc0, +0x97, 0x96, 0x96, 0xfc, 0x18, 0x61, 0xda, 0x58, +0xa7, 0xa6, 0xa6, 0x30, 0x3d, 0x3d, 0x8d, 0x99, +0x99, 0x99, 0x80, 0x6d, 0x55, 0x63, 0xe4, 0x5a, +0xaa, 0x54, 0x93, 0x43, 0x1b, 0xef, 0xdf, 0xc6, +0xc4, 0x34, 0xe6, 0xdb, 0x0d, 0x1c, 0x5b, 0xbf, +0xb2, 0xd8, 0x3c, 0xd9, 0x35, 0x98, 0x5a, 0x8e, +0xf7, 0x28, 0x4e, 0x75, 0x26, 0x67, 0x3e, 0x53, +0x1b, 0xd3, 0x18, 0x89, 0x89, 0x13, 0x43, 0x0f, +0xf3, 0x41, 0xb0, 0xc5, 0xdd, 0x6b, 0x87, 0x12, +0xad, 0x5d, 0x14, 0x6f, 0x76, 0x5e, 0x57, 0xf3, +0x57, 0x00, 0xd6, 0xd7, 0x8a, 0xe9, 0x40, 0x65, +0x72, 0x64, 0xa4, 0x72, 0xe3, 0x50, 0x0a, 0x37, +0x0e, 0xa5, 0xf0, 0x5d, 0x23, 0x79, 0xdc, 0x7f, +0x72, 0x11, 0xdf, 0x58, 0x75, 0xf0, 0x7c, 0x62, +0x10, 0xc7, 0xab, 0x6b, 0x17, 0xf2, 0x74, 0xb3, +0x11, 0xd8, 0x24, 0x93, 0xb0, 0xf7, 0xb6, 0x36, +0xbc, 0x98, 0x98, 0x7c, 0x54, 0xdb, 0x6c, 0x98, +0x5d, 0x32, 0x0c, 0xbe, 0x89, 0x11, 0x77, 0xd3, +0x4f, 0x18, 0xe3, 0xb1, 0xe1, 0x13, 0xb6, 0x49, +0xda, 0x68, 0xc7, 0x9f, 0x45, 0x61, 0x8e, 0xb6, +0xf9, 0x30, 0x49, 0x65, 0xf4, 0x2e, 0x6c, 0x1e, +0xa3, 0xcc, 0x51, 0x94, 0xfe, 0xc3, 0x98, 0xb6, +0x89, 0x31, 0x46, 0xf9, 0x1c, 0x36, 0x8f, 0x51, +0x6c, 0xdc, 0x61, 0x73, 0x1b, 0x86, 0x5b, 0x14, +0xad, 0x80, 0x0d, 0xa7, 0xb0, 0xf5, 0xda, 0x2d, +0x3d, 0xb4, 0xbe, 0xc2, 0x34, 0x0d, 0x61, 0x74, +0xb2, 0x1d, 0xb6, 0x4d, 0x34, 0x4c, 0x38, 0x48, +0xdc, 0xf4, 0xdd, 0x3f, 0x78, 0xf7, 0xf6, 0xfa, +0x32, 0x92, 0x7d, 0x19, 0xa0, 0xd1, 0xc0, 0xec, +0xa9, 0x33, 0xc8, 0x66, 0xfa, 0x7c, 0x7b, 0xf9, +0xc8, 0xc8, 0x08, 0x1c, 0xc7, 0xf1, 0x19, 0x2d, +0xd9, 0xb6, 0x17, 0x17, 0x17, 0x31, 0x32, 0x32, +0x02, 0x60, 0x3d, 0x6d, 0x2b, 0xb0, 0xce, 0xf4, +0x0b, 0x85, 0x82, 0x6f, 0xdf, 0x3c, 0x7f, 0xfe, +0x3c, 0x5a, 0xad, 0x16, 0x92, 0xc9, 0x64, 0xe0, +0x3a, 0x4b, 0xb2, 0xa5, 0xf3, 0x18, 0x71, 0xb2, +0xe7, 0x6a, 0x9b, 0xba, 0x66, 0xd7, 0xa5, 0x42, +0x4c, 0x82, 0xdb, 0x72, 0xf9, 0x3b, 0x19, 0x17, +0xce, 0xeb, 0x72, 0x3b, 0xac, 0x8c, 0x2b, 0xa7, +0xe7, 0xc4, 0x1c, 0xb4, 0x18, 0x72, 0xfa, 0x4e, +0x0c, 0x83, 0xdb, 0x9a, 0xb5, 0x38, 0x75, 0xd9, +0x5e, 0xda, 0x86, 0xe5, 0xf8, 0x64, 0x7c, 0xb7, +0x8c, 0x3b, 0xd7, 0xec, 0xf9, 0x84, 0x6f, 0x36, +0x9b, 0xed, 0x88, 0x57, 0x97, 0x7f, 0x44, 0xaf, +0x4c, 0x26, 0x03, 0xc7, 0x71, 0xfc, 0x28, 0x02, +0x8a, 0xe5, 0xa6, 0x3a, 0x1a, 0xbe, 0x1c, 0x1f, +0x3e, 0x77, 0xf4, 0x7d, 0x65, 0x65, 0x05, 0xc5, +0x62, 0x11, 0xad, 0x56, 0x0b, 0xfd, 0xfd, 0xfd, +0x01, 0xfa, 0x48, 0x3b, 0x3a, 0x5f, 0x03, 0xda, +0xdc, 0xf3, 0x5c, 0x08, 0x1c, 0x17, 0xbe, 0x5e, +0x08, 0x06, 0xf9, 0x6e, 0x48, 0x9f, 0x02, 0xee, +0xbf, 0xc0, 0xed, 0xfd, 0x85, 0x42, 0x01, 0x8d, +0x46, 0xc3, 0xb7, 0xad, 0x0f, 0x0d, 0x0e, 0xe0, +0xaa, 0x41, 0x17, 0xdb, 0x97, 0x4f, 0xe1, 0xaa, +0x8b, 0x27, 0xd1, 0x4c, 0xba, 0x38, 0xd1, 0x4a, +0xeb, 0x36, 0x59, 0x9b, 0xbd, 0x58, 0xd6, 0x31, +0xd9, 0x22, 0x35, 0xfb, 0xa3, 0x66, 0x47, 0xe4, +0x75, 0x6c, 0x36, 0x48, 0xbe, 0xf9, 0xd8, 0xec, +0x89, 0xa6, 0x8d, 0xba, 0x5b, 0xdb, 0x1f, 0xe1, +0xab, 0xd9, 0xa4, 0xb5, 0x7e, 0x6c, 0xfe, 0x08, +0x92, 0x9e, 0x61, 0xe3, 0xd5, 0xe8, 0x47, 0x7d, +0xc8, 0x7e, 0x4c, 0xdf, 0xe9, 0xb3, 0x69, 0x5c, +0xa6, 0x58, 0x7e, 0x0d, 0x7f, 0x8e, 0x93, 0x29, +0x3e, 0x9f, 0xf7, 0x6d, 0x5a, 0x03, 0xda, 0xfa, +0xb2, 0xd9, 0x76, 0x35, 0xfc, 0x6d, 0x78, 0xda, +0xf2, 0x0c, 0x68, 0xb6, 0x6f, 0xd3, 0xba, 0x8a, +0x6a, 0x7b, 0x36, 0xd1, 0x37, 0x2c, 0xaf, 0x81, +0xa4, 0x8b, 0x36, 0x1f, 0xa6, 0xf5, 0x65, 0xf3, +0x19, 0xe1, 0x73, 0x6f, 0x3b, 0xb0, 0x68, 0xfd, +0xd8, 0x6c, 0xf2, 0x51, 0x6c, 0xf7, 0x61, 0x36, +0x7a, 0x39, 0x06, 0x93, 0xed, 0x9f, 0xcd, 0x53, +0xe2, 0x65, 0xdf, 0xf9, 0xbd, 0x77, 0x8f, 0xd6, +0x96, 0xe1, 0xac, 0x6d, 0x62, 0xf9, 0xa5, 0x0b, +0x81, 0xa4, 0x24, 0xe4, 0x94, 0xc6, 0x93, 0xc0, +0x64, 0xb3, 0x59, 0x3f, 0x69, 0x0b, 0xd5, 0xa5, +0xef, 0xb4, 0xe1, 0xd6, 0xeb, 0x75, 0x9c, 0x3b, +0x77, 0x0e, 0x8d, 0x46, 0x03, 0x9e, 0xe7, 0x61, +0xeb, 0xd6, 0xad, 0x18, 0x19, 0x19, 0xc1, 0xf4, +0xf4, 0xb4, 0x9f, 0xc1, 0x8d, 0xe0, 0x92, 0x93, +0x1b, 0x31, 0x26, 0xee, 0xc4, 0x44, 0x1b, 0xb9, +0x96, 0xf4, 0x85, 0x3b, 0x5a, 0x11, 0x53, 0x20, +0x7c, 0x81, 0x75, 0xa7, 0x32, 0xe9, 0xdc, 0x46, +0x9f, 0xe9, 0x3b, 0x39, 0xe6, 0xc9, 0xe4, 0x27, +0x44, 0x03, 0xce, 0x44, 0xa5, 0x73, 0x9b, 0xc6, +0x78, 0x78, 0x91, 0x8c, 0x5c, 0x16, 0x4d, 0xc5, +0x6d, 0x1a, 0x2b, 0x15, 0xee, 0x98, 0xc7, 0x0b, +0x8d, 0x81, 0x6b, 0x1a, 0xb4, 0xbe, 0x5d, 0xd7, +0x45, 0xa3, 0xd1, 0x80, 0xeb, 0xba, 0xfe, 0x98, +0xfb, 0xfb, 0xfb, 0xfd, 0xa4, 0x40, 0x54, 0x92, +0xc9, 0x24, 0x72, 0xb9, 0x5c, 0xe0, 0x30, 0x41, +0xf0, 0xa5, 0x03, 0x1c, 0xa7, 0x31, 0x3f, 0x20, +0xc5, 0x62, 0x31, 0x1f, 0xaf, 0x58, 0x2c, 0xd6, +0xe1, 0xe0, 0x26, 0x0f, 0x06, 0xd2, 0x99, 0x8f, +0xd6, 0x05, 0xa7, 0x25, 0x3f, 0xc0, 0xd0, 0x1c, +0xd0, 0xe1, 0x91, 0x1f, 0xcc, 0xa4, 0x73, 0x23, +0x87, 0x2b, 0xe7, 0x94, 0xfe, 0xaa, 0xf5, 0x06, +0xea, 0xb5, 0x2a, 0x62, 0xad, 0x26, 0xfa, 0x3c, +0x0f, 0xdb, 0xb6, 0x0c, 0xa3, 0x55, 0xaf, 0x61, +0xa2, 0xbc, 0x88, 0x74, 0xac, 0x85, 0xe7, 0x5b, +0x69, 0x54, 0xc5, 0xc5, 0x18, 0x46, 0x26, 0x1e, +0xc5, 0xf9, 0x46, 0x16, 0xb9, 0x89, 0x49, 0x06, +0xa1, 0xc1, 0x30, 0x6d, 0xd2, 0xb2, 0x6e, 0x18, +0x0e, 0x26, 0x9c, 0xb4, 0xb1, 0x99, 0x70, 0xb7, +0x6d, 0xc6, 0x54, 0xf8, 0xa6, 0x1e, 0x85, 0x36, +0x61, 0x34, 0x33, 0xd1, 0x39, 0xcc, 0x21, 0x50, +0xe2, 0x1b, 0x65, 0x4e, 0xb4, 0x0d, 0x3d, 0x0c, +0x3f, 0x0d, 0x4e, 0xd4, 0xfe, 0x4c, 0xb4, 0xb4, +0x39, 0x23, 0x9a, 0x8a, 0xc6, 0xe0, 0x4c, 0x78, +0x87, 0x3d, 0xd3, 0x0e, 0x9c, 0xbd, 0xe0, 0x67, +0x3a, 0x08, 0xd9, 0xe8, 0x12, 0x86, 0xbf, 0xa9, +0xaf, 0xa8, 0xeb, 0x2a, 0xca, 0xbc, 0xd0, 0xb8, +0xe5, 0xf8, 0x65, 0xff, 0x51, 0xd7, 0x74, 0x18, +0xbd, 0x22, 0xfc, 0xd6, 0x13, 0x2f, 0x7f, 0xe3, +0x5b, 0xef, 0xde, 0x1e, 0x6f, 0x27, 0xe5, 0xf7, +0x3c, 0x0f, 0x8b, 0x8b, 0x8b, 0xfe, 0x26, 0xc8, +0x37, 0xcd, 0x42, 0xa1, 0x80, 0xb1, 0xb1, 0x31, +0x7f, 0x73, 0x24, 0x2f, 0x77, 0x2a, 0x5c, 0x6a, +0x25, 0xe6, 0x98, 0x4c, 0x26, 0xb1, 0xb2, 0xb2, +0x82, 0xfe, 0xfe, 0x7e, 0x64, 0xb3, 0x59, 0x7c, +0xf9, 0xcb, 0x5f, 0xc6, 0xec, 0xec, 0xac, 0xff, +0xbe, 0x5e, 0xaf, 0xfb, 0x36, 0x73, 0xbe, 0x11, +0x93, 0x54, 0x25, 0xd5, 0xbf, 0x52, 0x9a, 0xa4, +0x22, 0xa5, 0x46, 0xbe, 0xf9, 0xcb, 0x0c, 0x67, +0x52, 0x12, 0xe7, 0x0c, 0x85, 0x32, 0xb2, 0x49, +0x06, 0xce, 0xc7, 0xc8, 0x8b, 0xe6, 0x79, 0xcd, +0xfb, 0x97, 0x0c, 0x45, 0x32, 0x56, 0x29, 0xf1, +0x73, 0x58, 0x1c, 0x67, 0xd3, 0x61, 0x46, 0x16, +0xce, 0x18, 0x35, 0xfc, 0x81, 0x75, 0x7b, 0x31, +0x49, 0xe0, 0xc9, 0x64, 0x12, 0xc9, 0x64, 0xdb, +0xe1, 0x8b, 0xfe, 0x97, 0x4a, 0x25, 0x7f, 0xce, +0x34, 0x1a, 0x73, 0xf8, 0x1c, 0x5f, 0x69, 0xcf, +0x27, 0x3a, 0xd7, 0x6a, 0x35, 0x54, 0x2a, 0x15, +0x5f, 0x3b, 0xc3, 0xb5, 0x20, 0xd4, 0x96, 0x0e, +0x61, 0xf4, 0x4c, 0x66, 0x10, 0xe4, 0x34, 0x92, +0xcf, 0x89, 0x96, 0x9c, 0xde, 0xfc, 0x19, 0xd1, +0x5f, 0x6a, 0x3e, 0xa8, 0xaf, 0x4c, 0x26, 0xe3, +0x7b, 0xbe, 0x97, 0x56, 0x57, 0x01, 0xc0, 0x67, +0xea, 0x99, 0x4c, 0x06, 0xa3, 0x5b, 0xb7, 0x22, +0xd1, 0x6a, 0x62, 0x7b, 0x7d, 0x19, 0x43, 0xc9, +0x18, 0x4e, 0x37, 0x92, 0x28, 0x9a, 0x42, 0xd9, +0x6c, 0x4c, 0x4c, 0x2b, 0x52, 0x5a, 0xeb, 0x96, +0xc1, 0xf2, 0x3a, 0x26, 0x29, 0x70, 0x23, 0x45, +0x63, 0x94, 0x97, 0x0b, 0x9c, 0xb0, 0xc3, 0x85, +0xd6, 0x56, 0xd3, 0x08, 0x74, 0x53, 0xa2, 0x1c, +0xb6, 0x4c, 0xf8, 0x6e, 0x46, 0xe9, 0x16, 0xde, +0x66, 0xd1, 0xdd, 0x04, 0x37, 0x8a, 0x86, 0xc2, +0x56, 0x2e, 0x05, 0x6e, 0x2f, 0x46, 0x79, 0x31, +0xf1, 0xb6, 0x09, 0x05, 0xbc, 0xda, 0x4d, 0xdf, +0xf9, 0x3d, 0x77, 0x0f, 0x57, 0xdb, 0x17, 0xa3, +0x93, 0x2a, 0x33, 0x97, 0xcb, 0xf9, 0x9b, 0x29, +0xff, 0xa3, 0x7c, 0xec, 0xa4, 0x46, 0x97, 0x9b, +0x29, 0x49, 0xda, 0xa4, 0x8e, 0x07, 0xda, 0x17, +0x13, 0xec, 0xdc, 0xb9, 0x13, 0xc7, 0x8f, 0x1f, +0xc7, 0xf4, 0xf4, 0x74, 0x80, 0x61, 0x2f, 0x2e, +0x2e, 0xfa, 0x07, 0x03, 0x2e, 0x95, 0x53, 0x31, +0xa5, 0x16, 0x35, 0x31, 0x36, 0x29, 0x91, 0x72, +0xa6, 0x4e, 0x45, 0x3e, 0x93, 0xea, 0x56, 0x13, +0x13, 0xa4, 0x67, 0x1a, 0x2c, 0x1a, 0xbf, 0xa6, +0x7e, 0xa6, 0xef, 0xf2, 0x50, 0x60, 0x52, 0x77, +0x73, 0x9c, 0x6c, 0x07, 0x17, 0xae, 0x39, 0xd0, +0xa4, 0x7f, 0x2e, 0xa1, 0xf3, 0x77, 0x3c, 0x85, +0x6a, 0x32, 0x99, 0xec, 0x38, 0x24, 0x91, 0x04, +0x2d, 0x0f, 0x10, 0x52, 0x3a, 0x97, 0xf3, 0xa1, +0x99, 0x15, 0xf8, 0xda, 0xa0, 0x7e, 0xeb, 0xf5, +0xba, 0x2f, 0xa1, 0xf3, 0xba, 0xa4, 0x72, 0xe7, +0x2a, 0x72, 0x2d, 0xa3, 0x1f, 0x1d, 0x24, 0xce, +0x9d, 0x3b, 0xe7, 0x6b, 0x11, 0x0a, 0x85, 0x02, +0x56, 0x56, 0x56, 0x02, 0xdf, 0xa9, 0xae, 0x3c, +0x94, 0x12, 0x3e, 0x1c, 0xf7, 0x62, 0xb1, 0x88, +0xc1, 0xc1, 0x41, 0x24, 0x93, 0x49, 0x34, 0x11, +0x43, 0xab, 0xd9, 0x44, 0x69, 0x75, 0xd5, 0x77, +0x04, 0x24, 0xa7, 0xbd, 0x66, 0xad, 0x8a, 0xed, +0xf5, 0x65, 0xdc, 0x95, 0xad, 0xe0, 0x64, 0xcd, +0xc1, 0x0b, 0xf0, 0xf4, 0x93, 0x79, 0x37, 0xa5, +0x5b, 0xe6, 0xdf, 0x0b, 0xdc, 0xb0, 0x62, 0xdb, +0x84, 0xbb, 0x39, 0x20, 0xd8, 0xde, 0x5f, 0x8a, +0x83, 0x40, 0x2f, 0x8c, 0xc3, 0x46, 0xef, 0x8d, +0x32, 0xf7, 0xb0, 0xf7, 0x9b, 0xc1, 0xd8, 0x37, +0x1b, 0xbf, 0xcd, 0xc4, 0xc3, 0xc6, 0xe0, 0x36, +0xfb, 0x50, 0x73, 0x29, 0x60, 0x5f, 0x0a, 0x38, +0x36, 0x98, 0x51, 0xfb, 0x8b, 0x88, 0x53, 0xe2, +0xf0, 0xeb, 0xbf, 0xe3, 0xee, 0x6c, 0x75, 0xdd, +0xbe, 0x48, 0x9b, 0xe4, 0xfc, 0xfc, 0x3c, 0x6a, +0xb5, 0x1a, 0x1a, 0x8d, 0x06, 0x76, 0xee, 0xdc, +0xe9, 0xab, 0xcd, 0xeb, 0xf5, 0x3a, 0x86, 0x86, +0x86, 0x70, 0xee, 0xdc, 0xb9, 0x80, 0x87, 0x3a, +0xa9, 0xd9, 0x4f, 0x9f, 0x3e, 0xed, 0xdb, 0xd2, +0x49, 0x1d, 0x3f, 0x3f, 0x3f, 0x8f, 0xd3, 0xa7, +0x4f, 0xe3, 0xf4, 0xe9, 0xd3, 0xfe, 0x46, 0x4b, +0x0c, 0x5c, 0xaa, 0xd3, 0xa9, 0x90, 0xb4, 0xa6, +0x49, 0xe4, 0x7c, 0x63, 0xe6, 0xb6, 0x72, 0x1e, +0x6b, 0x2c, 0x19, 0x2f, 0xe1, 0xc9, 0x99, 0x20, +0xcf, 0xe3, 0x2d, 0x99, 0x31, 0xaf, 0xc7, 0xfb, +0x95, 0x12, 0xb4, 0x54, 0x01, 0xcb, 0xd8, 0x77, +0xcd, 0x9e, 0x6d, 0xb2, 0xfd, 0x93, 0x7d, 0x5b, +0xe2, 0x60, 0x8a, 0x01, 0xe7, 0x07, 0x10, 0xcd, +0xa7, 0x40, 0x4a, 0xb2, 0x32, 0x27, 0x3a, 0x49, +0xc9, 0x04, 0x43, 0xda, 0xd0, 0xf9, 0x73, 0x2a, +0x5c, 0x9a, 0x96, 0xa6, 0x0e, 0x89, 0x33, 0xf5, +0xbb, 0xbc, 0xbc, 0x1c, 0xf0, 0x20, 0xe7, 0x07, +0x37, 0x3a, 0x38, 0x70, 0xdb, 0x3e, 0xd5, 0x21, +0x26, 0x5d, 0xaf, 0xd7, 0xfd, 0x83, 0x07, 0x8d, +0x29, 0x16, 0x8b, 0x61, 0x65, 0x65, 0x05, 0xb1, +0x58, 0x5b, 0x42, 0xa6, 0xb1, 0x48, 0x9f, 0x0b, +0xa9, 0xf1, 0x91, 0xf9, 0xf0, 0x9b, 0x88, 0x21, +0x11, 0x8f, 0xa3, 0x52, 0xa9, 0xc0, 0x71, 0x1c, +0xb8, 0xa9, 0x14, 0xaa, 0xf5, 0x06, 0x12, 0xf1, +0xb8, 0x8f, 0x0b, 0xe1, 0x98, 0x4e, 0xa7, 0x51, +0x28, 0x14, 0xb0, 0x7a, 0x71, 0x19, 0xd7, 0x26, +0x0a, 0x58, 0x6d, 0xc6, 0x70, 0xae, 0xe9, 0xa0, +0xda, 0x0a, 0xc9, 0x22, 0x17, 0xf8, 0xc5, 0x39, +0x9b, 0xc3, 0x44, 0xba, 0x2d, 0x51, 0x18, 0x76, +0x37, 0x8c, 0xc9, 0xf4, 0xde, 0x34, 0x96, 0x6e, +0xc6, 0x28, 0x25, 0x68, 0x5b, 0xbb, 0x97, 0xea, +0x00, 0x14, 0xb5, 0xd8, 0x24, 0x63, 0x93, 0xed, +0x5d, 0xab, 0xf3, 0x62, 0xac, 0x91, 0x4b, 0x59, +0x2e, 0x85, 0xd6, 0x48, 0xc2, 0xde, 0xe8, 0x6f, +0xab, 0x57, 0x9c, 0x34, 0x5f, 0x89, 0x28, 0x30, +0x37, 0x79, 0x3e, 0x9d, 0xb3, 0x4d, 0x07, 0xfb, +0x59, 0xd8, 0x19, 0xa5, 0xd7, 0x74, 0x5d, 0x17, +0xcb, 0xcb, 0xcb, 0x00, 0x82, 0xde, 0xe4, 0x95, +0x4a, 0x05, 0x27, 0x4e, 0x9c, 0xf0, 0xb3, 0xc2, +0x49, 0xaf, 0x61, 0xda, 0xb4, 0xc7, 0xc6, 0xc6, +0x30, 0x3f, 0x3f, 0x8f, 0xb9, 0xb9, 0x39, 0x1f, +0x06, 0x6d, 0xb2, 0xe4, 0x4c, 0x07, 0x74, 0xde, +0x0b, 0x0e, 0x84, 0xc7, 0x78, 0xdb, 0xe2, 0xa7, +0x6d, 0x5e, 0xd0, 0x61, 0x7d, 0x98, 0x3c, 0x9d, +0xc3, 0x60, 0x49, 0x78, 0x51, 0xe2, 0xdb, 0x6d, +0xb8, 0x84, 0x8d, 0x9f, 0x7b, 0x85, 0x87, 0xc5, +0x97, 0x6b, 0xa1, 0x78, 0xf4, 0x99, 0xe2, 0xad, +0x65, 0xd8, 0x9b, 0x06, 0x5f, 0xc3, 0x51, 0x86, +0x93, 0xf1, 0x68, 0x07, 0xbe, 0x66, 0x3a, 0x6e, +0x86, 0x62, 0x65, 0x69, 0x69, 0xfd, 0x3a, 0x33, +0xca, 0xf3, 0xcf, 0xff, 0xc6, 0xc7, 0xc7, 0x51, +0x2e, 0x97, 0xfd, 0x7a, 0x04, 0x9f, 0xa7, 0x6b, +0x95, 0x45, 0x3e, 0xd3, 0xbc, 0xfd, 0x69, 0x3d, +0xe6, 0x72, 0xe5, 0x80, 0xb9, 0x08, 0x00, 0x06, +0xb2, 0x99, 0xc0, 0xbc, 0xd3, 0x7f, 0xd7, 0x75, +0xfd, 0x9c, 0x0b, 0x1e, 0x80, 0x77, 0x60, 0x11, +0x9e, 0x93, 0xc0, 0x3d, 0xab, 0x19, 0x44, 0x2e, +0x26, 0xef, 0xec, 0x4b, 0x5d, 0xa2, 0xc4, 0xb0, +0x86, 0x95, 0x28, 0xb8, 0x46, 0xf1, 0x58, 0xef, +0x96, 0x46, 0x9b, 0x85, 0xdb, 0x66, 0x8f, 0x79, +0x23, 0xf4, 0xa0, 0x77, 0x61, 0xf1, 0xc5, 0x9b, +0x31, 0x6f, 0x97, 0x5b, 0x89, 0x1a, 0x47, 0xbd, +0x19, 0x70, 0x5f, 0xcc, 0xdf, 0x56, 0x94, 0xb2, +0x91, 0xf1, 0x85, 0xb4, 0x75, 0x1a, 0xd5, 0x2a, +0xca, 0x8d, 0xf5, 0x0d, 0xd9, 0x75, 0xdd, 0x0e, +0x06, 0xc1, 0x93, 0xc8, 0x00, 0xec, 0x0e, 0x5e, +0xac, 0x6f, 0xc6, 0xc4, 0xdc, 0x01, 0xf8, 0x61, +0x6d, 0x3c, 0x86, 0x9c, 0xc7, 0xa7, 0x03, 0xfa, +0x1d, 0xdc, 0xbc, 0x98, 0xc2, 0xc1, 0xb4, 0x3a, +0xa6, 0x50, 0xa8, 0xb0, 0x90, 0x33, 0x79, 0x45, +0xa7, 0x2d, 0x46, 0x5b, 0xeb, 0xd3, 0x14, 0x1f, +0xae, 0x85, 0x96, 0x85, 0x8d, 0x2f, 0xea, 0x61, +0x40, 0xd2, 0xd0, 0x14, 0x7b, 0xae, 0xb5, 0x31, +0xd5, 0x93, 0x71, 0xde, 0xda, 0x98, 0x34, 0x47, +0x3d, 0x9a, 0x6b, 0xd3, 0x3c, 0x49, 0x35, 0xb9, +0x89, 0xf9, 0xf2, 0xa4, 0x32, 0x74, 0x31, 0x0b, +0x3d, 0x27, 0x18, 0x7c, 0xcd, 0xf1, 0x42, 0xe1, +0x73, 0xa4, 0x62, 0x27, 0xf8, 0x54, 0x9f, 0xaf, +0x4b, 0x3a, 0x00, 0xf0, 0xc3, 0xa4, 0xbc, 0x7b, +0x3d, 0x4a, 0xcc, 0xfc, 0xe4, 0xe4, 0x24, 0x66, +0x66, 0x66, 0x90, 0x01, 0xf0, 0x96, 0x6c, 0x11, +0x5f, 0x2c, 0xf7, 0x85, 0xe7, 0x78, 0x37, 0x95, +0x6f, 0xa7, 0x4d, 0xfa, 0x72, 0xc6, 0xf5, 0x52, +0xe1, 0x16, 0x25, 0x84, 0xe8, 0x72, 0xc4, 0xfb, +0xdb, 0xb5, 0xfc, 0x63, 0xa7, 0xc7, 0x46, 0xc6, +0x67, 0x6b, 0x5b, 0xaf, 0x21, 0x71, 0xf0, 0x75, +0x6f, 0xb9, 0x3b, 0x7b, 0x71, 0x21, 0xe0, 0x80, +0x44, 0x29, 0x30, 0x1d, 0xc7, 0xf1, 0x55, 0xb2, +0xe4, 0xd0, 0x46, 0x57, 0x98, 0x16, 0x8b, 0x45, +0x24, 0x12, 0xed, 0xd8, 0xdb, 0xa1, 0xa1, 0x21, +0xac, 0xac, 0xac, 0x20, 0x99, 0x4c, 0x62, 0x7c, +0x7c, 0x1c, 0xb3, 0xb3, 0xb3, 0x38, 0x7d, 0xfa, +0x74, 0xe0, 0xba, 0x52, 0xae, 0xe2, 0xe4, 0x36, +0x72, 0xee, 0xc1, 0xad, 0x39, 0x6e, 0x49, 0x7b, +0x30, 0xf7, 0xa4, 0xa6, 0xef, 0x5c, 0xa5, 0x2a, +0xd5, 0xcb, 0x52, 0xc5, 0x0c, 0xac, 0x6f, 0xd0, +0x9a, 0x27, 0x35, 0x77, 0x90, 0xd3, 0x9c, 0xe4, +0xb8, 0x0a, 0x9f, 0x9b, 0x07, 0xa4, 0x77, 0x75, +0x58, 0x31, 0xa5, 0x8d, 0xe5, 0x63, 0x94, 0x75, +0x39, 0x8e, 0xfc, 0xb3, 0xc9, 0x5e, 0x6e, 0x52, +0xd5, 0xf3, 0x9b, 0xc6, 0xa8, 0x3f, 0x0e, 0x5f, +0x3a, 0xbe, 0x49, 0x27, 0x44, 0xdb, 0x41, 0x2b, +0x9f, 0xcf, 0xfb, 0xf3, 0x9e, 0xcf, 0xe7, 0xfd, +0x8b, 0x4e, 0x34, 0xb3, 0x87, 0xbf, 0x0e, 0xd7, +0xec, 0xe8, 0xd2, 0x23, 0x9e, 0xe0, 0xd1, 0xa1, +0x85, 0x22, 0x23, 0x88, 0x29, 0x6b, 0xf3, 0x51, +0xa9, 0x54, 0xd0, 0x68, 0x34, 0x7c, 0x38, 0x14, +0x16, 0x27, 0x9d, 0x22, 0x69, 0x3d, 0x73, 0xda, +0x10, 0xcd, 0x48, 0xcd, 0xce, 0xd7, 0x86, 0xb6, +0xa6, 0xf2, 0xf9, 0x3c, 0xb2, 0x29, 0x07, 0xcd, +0xf4, 0x00, 0x9e, 0x28, 0x45, 0x64, 0xe6, 0xf5, +0x1a, 0x10, 0x4f, 0x44, 0xab, 0xfb, 0x4f, 0x65, +0xbd, 0xfc, 0x13, 0xdd, 0xfe, 0xa9, 0xfc, 0x53, +0x31, 0x97, 0x78, 0xa2, 0x9d, 0x01, 0xce, 0x75, +0x5d, 0x3f, 0xb1, 0x0b, 0x80, 0x40, 0x78, 0x92, +0x26, 0x11, 0x91, 0xa4, 0x4d, 0x92, 0x96, 0x94, +0xe0, 0x48, 0x2a, 0x07, 0x3a, 0xd5, 0xe8, 0xb6, +0xac, 0x64, 0xfc, 0x59, 0x37, 0x09, 0x4f, 0x78, +0xd1, 0xb2, 0xa1, 0x99, 0xa4, 0x6e, 0x9e, 0x7e, +0x36, 0x0a, 0xdc, 0x30, 0xbc, 0x34, 0xb3, 0x83, +0x86, 0xbb, 0x26, 0xf5, 0x6b, 0x5a, 0x0b, 0x13, +0x2c, 0x2d, 0x19, 0x8a, 0x49, 0xfa, 0x36, 0x69, +0x3e, 0x00, 0xb3, 0x9a, 0x5d, 0xa3, 0xb5, 0x76, +0xd9, 0x89, 0x54, 0xc7, 0x13, 0xe3, 0xa5, 0x50, +0x43, 0x82, 0x6f, 0x53, 0xb3, 0xd3, 0x1a, 0xa2, +0x3f, 0x2a, 0x74, 0x1b, 0x1f, 0xbf, 0xa0, 0x65, +0x69, 0x69, 0xc9, 0xaf, 0xc3, 0x61, 0x6b, 0x6b, +0x94, 0x3f, 0xa7, 0xff, 0xf2, 0xea, 0x45, 0xbe, +0x36, 0xb9, 0xf6, 0x08, 0x28, 0xa3, 0xc9, 0x54, +0xfd, 0x72, 0x0e, 0x5c, 0xd7, 0x0d, 0xa4, 0x34, +0xbe, 0x73, 0xf7, 0x0e, 0xdc, 0xb3, 0xd4, 0x8a, +0x26, 0x9d, 0x3b, 0xc9, 0xf0, 0x3a, 0x2f, 0x45, +0xa9, 0xd7, 0x3a, 0x71, 0xd3, 0x9e, 0xbd, 0x54, +0xe5, 0x72, 0xc1, 0xe3, 0x9f, 0xca, 0x3f, 0x95, +0x97, 0xa2, 0x44, 0xf8, 0x2d, 0xc6, 0x13, 0xa9, +0x14, 0x86, 0x86, 0x86, 0xda, 0xb6, 0xf2, 0x5a, +0xfb, 0xae, 0x5a, 0x92, 0xa6, 0x78, 0x6e, 0x6e, +0xbe, 0xf1, 0x03, 0xf0, 0x37, 0x6b, 0x62, 0xfc, +0x43, 0x43, 0x43, 0x98, 0x9c, 0x9c, 0xc4, 0xb1, +0x63, 0xc7, 0xfc, 0xcd, 0x9c, 0xdf, 0x31, 0x2e, +0x43, 0x89, 0xb4, 0xa2, 0x85, 0x37, 0x49, 0x06, +0x6f, 0x82, 0x61, 0x52, 0x11, 0xcb, 0xbe, 0x35, +0x26, 0x2d, 0x33, 0xcc, 0xd9, 0x6c, 0xf2, 0xb2, +0x2f, 0x93, 0xaa, 0x5f, 0x8e, 0x4b, 0xfb, 0x1f, +0x46, 0x03, 0x1b, 0x23, 0xd6, 0xe0, 0xd0, 0x77, +0x9a, 0x33, 0x3e, 0x16, 0x13, 0x43, 0xe5, 0x07, +0x37, 0x1b, 0xde, 0x26, 0xda, 0x91, 0x8a, 0x9c, +0xe6, 0x7c, 0x76, 0x76, 0x16, 0x73, 0x73, 0x73, +0x28, 0x95, 0x4a, 0x58, 0x5e, 0x5e, 0x46, 0xa5, +0x52, 0xf1, 0xfb, 0xa8, 0x54, 0x2a, 0xfe, 0x33, +0x62, 0xb0, 0x7c, 0xad, 0x55, 0x2a, 0x15, 0xcc, +0xcf, 0xcf, 0x07, 0x0e, 0x83, 0x94, 0xf6, 0x55, +0xc3, 0x97, 0x60, 0x6a, 0x6b, 0x81, 0x7c, 0x3f, +0xb4, 0xf9, 0xd3, 0x6e, 0x6c, 0x33, 0xdd, 0xca, +0x27, 0xeb, 0x90, 0x5f, 0x09, 0xd9, 0xcf, 0x01, +0x20, 0x7e, 0xf6, 0x24, 0x26, 0xbd, 0x16, 0x5e, +0xd4, 0x52, 0xaf, 0x6d, 0x2e, 0x3c, 0x6d, 0xa3, +0xe8, 0x95, 0x81, 0xf6, 0x82, 0xdb, 0x66, 0x8f, +0xe7, 0x9f, 0xca, 0x3f, 0x15, 0xe0, 0xa5, 0x5d, +0x57, 0x9b, 0xd9, 0x77, 0x84, 0xdf, 0x62, 0xe2, +0xea, 0x37, 0xbc, 0xed, 0xee, 0x89, 0x44, 0xb5, +0x1d, 0x0b, 0x5c, 0x6a, 0xc7, 0xd8, 0x92, 0x7a, +0x1d, 0x68, 0xdf, 0x30, 0x45, 0x1b, 0x6e, 0xab, +0xd5, 0xf2, 0x55, 0x9d, 0xf3, 0xf3, 0xf3, 0x48, +0xa7, 0xd3, 0x7e, 0xec, 0xf0, 0xc8, 0xc8, 0x08, +0xea, 0xf5, 0x3a, 0xbe, 0xf1, 0x8d, 0x6f, 0xf8, +0xaa, 0x75, 0x1f, 0x8f, 0x35, 0xb5, 0x24, 0x79, +0xbc, 0x4b, 0xaf, 0x6b, 0xed, 0x19, 0xff, 0x2c, +0x13, 0xb8, 0x70, 0x35, 0xb2, 0xf4, 0x5c, 0xee, +0xa0, 0xa7, 0xf0, 0xfa, 0xd6, 0x6e, 0x57, 0x23, +0x66, 0xc1, 0x4d, 0x0d, 0xd4, 0x56, 0xaa, 0xd1, +0xb5, 0xa4, 0x25, 0x32, 0xbe, 0x5b, 0xf3, 0x7a, +0x97, 0xaa, 0x5c, 0x3e, 0x4e, 0x2d, 0x8c, 0x8e, +0x9b, 0x24, 0x24, 0x4d, 0x24, 0x5c, 0x79, 0xf8, +0xa1, 0x84, 0x30, 0x3c, 0x31, 0x0c, 0x67, 0x7a, +0x8d, 0x46, 0xa3, 0x23, 0x54, 0x8c, 0xda, 0x12, +0x1d, 0xb4, 0x84, 0x3a, 0xd2, 0x69, 0x91, 0x4b, +0xad, 0x74, 0x78, 0x9b, 0x9f, 0x9f, 0x47, 0xb1, +0x58, 0xf4, 0xc3, 0xba, 0xc8, 0x2b, 0x9d, 0xab, +0xd1, 0x49, 0xfd, 0x5f, 0x2c, 0x16, 0xfd, 0xbe, +0x79, 0xd1, 0xc2, 0x13, 0x81, 0x75, 0x46, 0x1e, +0x8b, 0xc5, 0x90, 0x4c, 0x26, 0xd1, 0xdf, 0xdf, +0x8f, 0x5a, 0xad, 0xe6, 0xaf, 0x57, 0x3e, 0x56, +0x4d, 0x3d, 0xce, 0xc7, 0x4d, 0xef, 0xc8, 0x0b, +0x5e, 0x86, 0xd5, 0x71, 0xcf, 0x78, 0x9a, 0x0b, +0x8e, 0x4f, 0x2c, 0x16, 0xf3, 0xe7, 0xb2, 0x59, +0x2e, 0x61, 0x29, 0x96, 0xc6, 0x13, 0xd5, 0x54, +0xf8, 0x8f, 0x72, 0xb3, 0xca, 0xa5, 0x50, 0x39, +0x6f, 0x96, 0x2a, 0xbb, 0x17, 0x18, 0x51, 0xda, +0xfc, 0x63, 0x50, 0xb5, 0xdb, 0xc6, 0xf0, 0x8f, +0x61, 0x7c, 0x97, 0x5b, 0x79, 0x29, 0xe9, 0x69, +0xeb, 0xfb, 0x12, 0xcc, 0x75, 0x3c, 0x51, 0x6d, +0x6f, 0x9c, 0x3c, 0xcc, 0x4c, 0x93, 0xc8, 0x81, +0xf6, 0x66, 0xca, 0xa5, 0x1a, 0xbe, 0x91, 0xcb, +0xef, 0x9a, 0x44, 0x2c, 0x55, 0x96, 0x36, 0xc7, +0x2a, 0xd9, 0x87, 0x49, 0x2a, 0x34, 0x15, 0xf9, +0x5e, 0x4a, 0xf8, 0x5c, 0x7d, 0x2c, 0xed, 0xc2, +0x9a, 0xaa, 0x5a, 0xfb, 0x6c, 0x2a, 0x61, 0xaa, +0x78, 0x89, 0x8f, 0x6c, 0x13, 0xd5, 0x13, 0x5e, +0x93, 0xa4, 0x5d, 0xd7, 0xed, 0x50, 0x3d, 0x4b, +0x35, 0x33, 0xff, 0x4c, 0x0c, 0x52, 0x26, 0x00, +0x22, 0x78, 0x9c, 0xfe, 0xda, 0xe5, 0x37, 0xf4, +0x7f, 0x7e, 0x7e, 0x1e, 0x4b, 0x4b, 0x4b, 0xfe, +0xb3, 0xe5, 0xe5, 0xe5, 0x40, 0x7b, 0x4d, 0x1a, +0x96, 0xf3, 0xc4, 0xd7, 0x0a, 0x1d, 0x0c, 0x68, +0xdd, 0x90, 0x63, 0x1c, 0x9f, 0xaf, 0x72, 0xb9, +0x8c, 0x74, 0x3a, 0x1d, 0x58, 0x97, 0x14, 0x17, +0x6e, 0x9a, 0x43, 0xee, 0x4c, 0xc7, 0xed, 0xee, +0x72, 0x7c, 0x24, 0x85, 0x6b, 0x1a, 0x1f, 0x3e, +0xa6, 0xe1, 0x91, 0xad, 0x28, 0x97, 0xcb, 0x78, +0x79, 0xb2, 0x80, 0x2d, 0xa9, 0x4d, 0xfc, 0x71, +0xbe, 0x14, 0x12, 0xc5, 0xe5, 0xae, 0xca, 0xee, +0x06, 0x3f, 0x13, 0xfd, 0x5e, 0x6a, 0x0d, 0x80, +0x6d, 0x0c, 0x97, 0x3b, 0xfd, 0x37, 0xb3, 0x6c, +0x64, 0x1e, 0x5e, 0xea, 0x39, 0xdc, 0x8c, 0x71, +0x5f, 0x82, 0xb9, 0x8e, 0x03, 0x40, 0x7e, 0xa5, +0x88, 0x56, 0x62, 0x1d, 0x38, 0x6d, 0x8c, 0x52, +0xf5, 0x08, 0xc0, 0x0f, 0x57, 0xe3, 0x97, 0x5c, +0xe4, 0x72, 0x39, 0x8c, 0x8d, 0x8d, 0xa9, 0x49, +0x3e, 0xa8, 0x2d, 0x67, 0xe8, 0x40, 0xf7, 0xe1, +0x58, 0x54, 0xc7, 0xe6, 0xf9, 0x2e, 0x71, 0x0d, +0x7b, 0xa6, 0x1d, 0x24, 0xc8, 0x86, 0x2e, 0x19, +0x82, 0xc9, 0x36, 0xaf, 0x7d, 0x8e, 0x1a, 0x16, +0xd7, 0x8d, 0xda, 0x5d, 0xb6, 0x35, 0x79, 0x91, +0x73, 0xc6, 0x4d, 0xf3, 0xc8, 0x19, 0x9d, 0x2c, +0x5a, 0x18, 0x17, 0xff, 0xcf, 0x19, 0x3b, 0xf7, +0xfe, 0xe7, 0xe3, 0xa5, 0x79, 0xa7, 0xb5, 0xa1, +0x65, 0x67, 0xe3, 0x7d, 0x6b, 0xcc, 0x51, 0xa3, +0xef, 0xec, 0xec, 0x2c, 0x66, 0x67, 0x67, 0x3b, +0x7c, 0x32, 0x08, 0x0f, 0xa9, 0x7e, 0x27, 0xa6, +0x4e, 0xe3, 0xd5, 0x0e, 0x09, 0xfc, 0x39, 0xb7, +0xd3, 0xd3, 0x41, 0x84, 0x0e, 0x11, 0xd4, 0x1f, +0x67, 0xf4, 0xf2, 0x6f, 0x79, 0x79, 0x19, 0x03, +0xd9, 0x0c, 0xc6, 0xc6, 0xc6, 0x30, 0xe9, 0x54, +0xb1, 0x3f, 0xdd, 0x65, 0xdc, 0xa8, 0x6d, 0x53, +0xda, 0x8c, 0x1f, 0x7b, 0xd8, 0xa6, 0xb7, 0xd9, +0x9b, 0xe2, 0xe5, 0xb4, 0xc9, 0x9a, 0xe8, 0x77, +0xa9, 0x18, 0xe6, 0xe5, 0x34, 0xf6, 0x6f, 0x07, +0xbc, 0x36, 0x32, 0x0f, 0xbc, 0x6d, 0x37, 0xe3, +0xbb, 0x1c, 0x68, 0xa1, 0x8d, 0x7b, 0x93, 0xf0, +0x8a, 0x37, 0x52, 0x1e, 0x5a, 0xf5, 0x2a, 0x62, +0x8d, 0x9a, 0xbf, 0x09, 0xd2, 0xa6, 0x0c, 0xc0, +0xb7, 0x79, 0x52, 0x6c, 0x2f, 0x31, 0xed, 0xc1, +0xc1, 0x41, 0x5f, 0x95, 0xca, 0xaf, 0xb4, 0xe4, +0x36, 0x4e, 0xc9, 0xc4, 0xc3, 0x18, 0xb9, 0x2d, +0x46, 0x3c, 0xcc, 0x7e, 0x4b, 0xc5, 0x26, 0x8d, +0xf3, 0xcf, 0x26, 0x2d, 0x00, 0x67, 0x96, 0x52, +0x6a, 0x97, 0x75, 0x6d, 0xb6, 0x76, 0x93, 0x33, +0x1f, 0x87, 0x6f, 0x1a, 0x67, 0x37, 0x71, 0xf4, +0x1a, 0x0c, 0x6e, 0x93, 0xe6, 0xbe, 0x0f, 0x9c, +0xd1, 0x51, 0xe1, 0x36, 0x68, 0x79, 0xe0, 0x92, +0xf4, 0xe2, 0xf3, 0x49, 0xf6, 0xf1, 0x99, 0x99, +0x99, 0x80, 0x14, 0x2d, 0x71, 0x95, 0x21, 0x60, +0x1a, 0xce, 0x12, 0x36, 0x2f, 0x74, 0xc7, 0x3d, +0xb5, 0xe7, 0xf3, 0x42, 0xdf, 0x65, 0xdc, 0xbc, +0x46, 0x3b, 0xd3, 0xa1, 0x87, 0xb7, 0x23, 0xe6, +0xae, 0x69, 0x21, 0xb4, 0xc3, 0x0c, 0x7d, 0x1e, +0x1b, 0x1b, 0x43, 0xdd, 0x71, 0x51, 0xed, 0x22, +0xb7, 0x00, 0x80, 0x4b, 0x2f, 0x89, 0x85, 0xc1, +0xdf, 0xec, 0xfe, 0xa3, 0xc2, 0x7b, 0xa9, 0x36, +0xd5, 0x4b, 0xd9, 0xef, 0xe5, 0x2a, 0x55, 0x5f, +0xae, 0x78, 0xbd, 0x14, 0xe3, 0xbb, 0x5c, 0x69, +0xd1, 0x0b, 0x5e, 0xca, 0x5a, 0x76, 0x1a, 0xd5, +0x2a, 0x00, 0xf8, 0x2a, 0xcb, 0x00, 0x23, 0x6f, +0x34, 0x03, 0xd2, 0xf7, 0xf2, 0xf2, 0x32, 0x86, +0x86, 0x86, 0xfc, 0x78, 0xf4, 0xc1, 0xc1, 0x41, +0xd5, 0xd1, 0x48, 0x93, 0xd2, 0x35, 0x26, 0x21, +0x4b, 0x14, 0x49, 0x55, 0x86, 0x66, 0xf1, 0xb6, +0xf2, 0x9d, 0x89, 0xb1, 0xd3, 0x78, 0x24, 0x5c, +0x20, 0x18, 0x53, 0x6f, 0xf2, 0x66, 0xe6, 0xfd, +0x99, 0xb4, 0x0d, 0x32, 0xae, 0x5e, 0xe2, 0x60, +0x73, 0x6e, 0xd3, 0xc2, 0xcf, 0x64, 0xdf, 0x9a, +0xc7, 0xba, 0x64, 0x5c, 0xdc, 0x5c, 0xc2, 0xbf, +0xf3, 0xb8, 0x6c, 0x5b, 0x9f, 0xf4, 0x5f, 0x9a, +0x51, 0x24, 0x7d, 0xb5, 0xeb, 0x6f, 0x4d, 0xe3, +0xe2, 0xf8, 0x85, 0x69, 0x4b, 0x08, 0x67, 0xad, +0x2d, 0x3f, 0x0c, 0xc9, 0x6b, 0x4f, 0xb9, 0x99, +0xc7, 0x46, 0xdb, 0xa8, 0x5e, 0xee, 0xda, 0x3a, +0xa3, 0xf9, 0xa5, 0xbf, 0x91, 0x6c, 0x1a, 0xaf, +0x4f, 0xba, 0x98, 0x39, 0x1d, 0xd1, 0xab, 0xfd, +0xff, 0xe6, 0xf2, 0x52, 0x6d, 0xaa, 0xbd, 0x6e, +0x9a, 0x2f, 0x66, 0xbb, 0x4b, 0x0d, 0xeb, 0xc5, +0x2a, 0xdf, 0x8e, 0x38, 0x7f, 0x3b, 0x15, 0x85, +0xb6, 0xf1, 0x58, 0xa3, 0x1e, 0xf0, 0x2c, 0x06, +0xd6, 0xd5, 0xa2, 0xad, 0x5a, 0x35, 0xb0, 0xa9, +0xd1, 0x3b, 0x59, 0x28, 0x2b, 0x16, 0x60, 0x67, +0xc8, 0x9a, 0x44, 0xa6, 0xa9, 0x73, 0x65, 0x1d, +0xd3, 0x67, 0x9b, 0x84, 0x6f, 0x3a, 0x2c, 0x84, +0x99, 0x01, 0xf8, 0x77, 0xa9, 0x72, 0x37, 0x31, +0x09, 0xfe, 0x4c, 0x32, 0xea, 0xb0, 0xf1, 0xc8, +0x03, 0x83, 0x86, 0x43, 0x14, 0x13, 0x84, 0x26, +0xbd, 0x4b, 0x29, 0x5c, 0xda, 0xd2, 0x49, 0x12, +0xe5, 0xb8, 0x72, 0xcd, 0x8a, 0xec, 0x97, 0xcc, +0x29, 0x5a, 0xa8, 0x9f, 0x4d, 0x5d, 0x6e, 0x32, +0x51, 0x48, 0xf5, 0x39, 0x3d, 0x93, 0x74, 0x36, +0xf9, 0x5f, 0x98, 0xb4, 0x28, 0x5a, 0xe2, 0x23, +0xa9, 0x49, 0xe1, 0x70, 0xb9, 0xf6, 0x22, 0x9d, +0x4e, 0xfb, 0x91, 0x1a, 0x5c, 0xbd, 0x4e, 0xda, +0x07, 0x8e, 0x1b, 0x3f, 0xb0, 0x4e, 0x4c, 0x4c, +0xe0, 0x3b, 0xb7, 0xc6, 0x31, 0x99, 0x49, 0x44, +0xbf, 0x4b, 0xfc, 0x9f, 0xca, 0x4b, 0x53, 0xea, +0xb5, 0xe8, 0x52, 0xfa, 0x4b, 0xcd, 0xc8, 0xa3, +0xe2, 0x70, 0x39, 0xa8, 0x90, 0x4d, 0x38, 0x73, +0xdc, 0x2e, 0x37, 0x3c, 0x4d, 0xe5, 0xdb, 0x05, +0x4f, 0x86, 0x6b, 0xe2, 0xe0, 0x6b, 0xdf, 0x7c, +0xf7, 0x48, 0x6d, 0x05, 0xad, 0x56, 0xcb, 0x97, +0xca, 0x8b, 0x95, 0x2a, 0xb2, 0x7d, 0x69, 0xdf, +0x3b, 0x9b, 0x3c, 0xd5, 0xb9, 0xb7, 0x36, 0x79, +0x06, 0xe7, 0x72, 0x39, 0x4c, 0x4d, 0x4d, 0xf9, +0x1b, 0xfc, 0xe9, 0xd3, 0xa7, 0xfd, 0xc4, 0x32, +0x94, 0x1c, 0x06, 0xe8, 0x4c, 0x38, 0xa2, 0xe5, +0xf2, 0xa6, 0x77, 0xa6, 0x84, 0x29, 0xd2, 0xa3, +0x58, 0x26, 0x89, 0xe1, 0xcf, 0xa8, 0x9e, 0xe6, +0x31, 0x2e, 0x13, 0xe4, 0x04, 0xe8, 0x22, 0x3c, +0x9a, 0xb5, 0x1b, 0xd5, 0x64, 0xc2, 0x18, 0x82, +0x09, 0x04, 0x93, 0x98, 0xc8, 0x22, 0xbd, 0xda, +0xf9, 0x7f, 0x62, 0x10, 0x32, 0x41, 0x8e, 0x64, +0xfe, 0x5a, 0x12, 0x18, 0x0e, 0x07, 0x00, 0x06, +0x07, 0x07, 0x7d, 0xaf, 0x6d, 0x4a, 0xd8, 0xc2, +0x71, 0x20, 0xa9, 0x9c, 0x3c, 0xc2, 0xcb, 0xe5, +0xf5, 0xab, 0x6e, 0xe9, 0x33, 0x15, 0x9a, 0x4b, +0xa2, 0x4d, 0x3e, 0x9f, 0x0f, 0xe4, 0xd5, 0xa7, +0xef, 0x04, 0x9b, 0xda, 0x72, 0xfa, 0x70, 0x2f, +0x76, 0x7e, 0x23, 0x1e, 0xd1, 0x95, 0xcf, 0x8f, +0xf4, 0x78, 0x27, 0xba, 0xf0, 0x8b, 0x58, 0x64, +0xae, 0x78, 0x6a, 0x43, 0xf5, 0xb9, 0x87, 0xbc, +0xb6, 0x36, 0x64, 0x24, 0x02, 0xcd, 0x27, 0xf7, +0xb8, 0x6f, 0x34, 0x1a, 0xfe, 0xdd, 0x04, 0x9c, +0x76, 0x72, 0x2c, 0xb4, 0x2e, 0x92, 0xc9, 0x24, +0xdc, 0x64, 0x12, 0xe9, 0x7a, 0x05, 0x8f, 0x16, +0xe2, 0x28, 0x35, 0x5e, 0xe4, 0x50, 0x35, 0x53, +0xd1, 0xbc, 0x66, 0xff, 0x6f, 0xf7, 0x9a, 0x8e, +0x27, 0x2e, 0xed, 0xf8, 0x39, 0xec, 0x17, 0x8b, +0xd6, 0x5a, 0x1f, 0x97, 0xcb, 0x3c, 0x73, 0x1c, +0x2e, 0x07, 0x7c, 0xba, 0xc5, 0xf9, 0x72, 0x29, +0xa6, 0xf9, 0x5c, 0x7b, 0x16, 0x6f, 0x29, 0x52, +0x84, 0x9b, 0x88, 0x77, 0x48, 0x9b, 0x40, 0x5b, +0xb2, 0x23, 0xb5, 0x23, 0xfd, 0x91, 0x54, 0x44, +0xce, 0x4a, 0x5c, 0x5a, 0x89, 0x22, 0x51, 0x02, +0x50, 0x1d, 0xab, 0x64, 0x7b, 0x9b, 0x3d, 0x3a, +0x4c, 0x0b, 0xd0, 0x8b, 0x83, 0x9c, 0xec, 0xcf, +0xa4, 0x96, 0x97, 0xde, 0xde, 0xa6, 0x3e, 0xf9, +0x33, 0x09, 0x4b, 0xab, 0x17, 0xc5, 0x0c, 0x61, +0x72, 0xd2, 0x93, 0xea, 0x75, 0x59, 0x64, 0xce, +0x00, 0xc2, 0x47, 0xf3, 0x77, 0xa0, 0xef, 0x24, +0xa1, 0xf2, 0xc2, 0xbd, 0xbd, 0x4d, 0x2a, 0x6e, +0x4d, 0xd3, 0x20, 0xe9, 0xa3, 0xa9, 0xb1, 0xa5, +0xe4, 0xcb, 0x3d, 0xe5, 0xb9, 0xc4, 0x6c, 0xd2, +0x64, 0xb8, 0xae, 0xdb, 0x41, 0x47, 0x4e, 0x77, +0x2d, 0xe5, 0xae, 0x49, 0xbb, 0x20, 0xe7, 0x40, +0xf6, 0xcf, 0x69, 0xf3, 0xfa, 0xed, 0x19, 0xdc, +0x94, 0x69, 0xa0, 0xab, 0x72, 0x29, 0x1d, 0xd1, +0x7a, 0x89, 0x1f, 0x7f, 0xb1, 0xa5, 0x92, 0x28, +0x92, 0x5b, 0x25, 0x82, 0x3f, 0x42, 0x94, 0x3a, +0xdd, 0xe0, 0x62, 0x7a, 0xd7, 0xad, 0x64, 0xff, +0x52, 0x49, 0x79, 0x5a, 0x12, 0xa0, 0xcd, 0xc0, +0x65, 0xa3, 0x30, 0x64, 0x7b, 0x1b, 0x5d, 0x7b, +0x95, 0xea, 0x2d, 0x75, 0x9d, 0xea, 0x6a, 0xf4, +0xf1, 0x6c, 0x64, 0x3d, 0x6c, 0xe6, 0x78, 0x80, +0xf0, 0xa4, 0x31, 0xa5, 0x7a, 0xc3, 0xf7, 0x44, +0xe6, 0x4c, 0x61, 0x70, 0x70, 0x30, 0xb0, 0x91, +0x03, 0x6d, 0x26, 0x41, 0xce, 0x6f, 0xd2, 0xc6, +0x6a, 0x0a, 0x6d, 0x8a, 0xc2, 0x94, 0xb4, 0x70, +0x35, 0x99, 0x37, 0x9d, 0x17, 0x4d, 0xa5, 0xdf, +0x8d, 0x87, 0xb8, 0xec, 0x53, 0x73, 0x26, 0x93, +0x9b, 0x7a, 0xb7, 0xce, 0x70, 0x9a, 0xcd, 0x5e, +0x32, 0x0b, 0x52, 0xdd, 0x4b, 0x06, 0x18, 0x75, +0x5c, 0x5a, 0x1f, 0xd4, 0x8f, 0x16, 0x8e, 0x66, +0xa3, 0x81, 0xa9, 0x10, 0x7e, 0x34, 0x27, 0x7c, +0x0c, 0xc4, 0x30, 0xf9, 0xf8, 0x35, 0xf5, 0xb8, +0x89, 0xc6, 0xb6, 0xb8, 0x75, 0x39, 0xb6, 0xe5, +0xe5, 0x65, 0x5f, 0xdd, 0x2d, 0x0f, 0x05, 0x12, +0x0e, 0xf9, 0x7f, 0xc8, 0xe4, 0x39, 0x5a, 0x54, +0x85, 0x56, 0xf8, 0x3b, 0x99, 0x25, 0x8f, 0x5f, +0x03, 0xcc, 0xbd, 0xea, 0x3d, 0xcf, 0xc3, 0xc5, +0x42, 0x11, 0xae, 0xeb, 0xe1, 0xda, 0x91, 0xb5, +0x8b, 0x57, 0xb4, 0x1f, 0xab, 0xc6, 0x70, 0xa2, +0xa8, 0x24, 0xb5, 0xcf, 0xa6, 0xf7, 0xb6, 0x1f, +0x7d, 0x94, 0x90, 0x2d, 0x6a, 0x1f, 0x75, 0x23, +0x0a, 0xc3, 0x27, 0xac, 0x3e, 0xc7, 0xd7, 0x44, +0x0b, 0x57, 0x99, 0x2f, 0xd9, 0x47, 0x94, 0x3a, +0x51, 0xc7, 0xae, 0xb5, 0xa5, 0x77, 0x4e, 0x32, +0x58, 0x2f, 0xec, 0x10, 0xa1, 0x31, 0x55, 0x59, +0x38, 0x8c, 0x6e, 0x69, 0x1b, 0x75, 0xac, 0x12, +0x6f, 0xad, 0x98, 0xc6, 0x12, 0x75, 0x7d, 0x44, +0xa1, 0xb7, 0xc4, 0xc1, 0x44, 0x57, 0x59, 0x57, +0xeb, 0x57, 0xa3, 0x8f, 0x6c, 0x97, 0x70, 0x02, +0x0c, 0xbc, 0x9e, 0x1e, 0xf0, 0x9f, 0x5b, 0xc7, +0x23, 0xe1, 0x44, 0x5d, 0x0f, 0x36, 0x7a, 0x47, +0x59, 0xeb, 0xa6, 0x31, 0x99, 0x9e, 0xad, 0x95, +0x38, 0x7d, 0x90, 0x9b, 0xe8, 0xf2, 0xf2, 0x72, +0x20, 0x84, 0x87, 0xde, 0x95, 0x4a, 0x25, 0x3f, +0x26, 0x5d, 0x8b, 0x39, 0x97, 0x52, 0x95, 0xdc, +0xbc, 0x13, 0x4e, 0x32, 0x92, 0xc4, 0x6d, 0x7a, +0x16, 0xc5, 0xa6, 0x6e, 0x73, 0xb4, 0xd3, 0xec, +0xaf, 0xf2, 0xbd, 0xac, 0x47, 0x70, 0xe4, 0xe6, +0x2d, 0xdb, 0xf0, 0x76, 0x5a, 0xdf, 0x54, 0xb8, +0x44, 0x47, 0x6d, 0x6c, 0xb6, 0x71, 0x4d, 0xdd, +0x1e, 0xc6, 0xd4, 0x01, 0x18, 0x2f, 0x27, 0xb1, +0x5d, 0x78, 0x02, 0x20, 0x60, 0x1b, 0xe6, 0xf0, +0xa4, 0x23, 0x1c, 0xcf, 0x4d, 0xa0, 0x79, 0xb2, +0x6b, 0xb8, 0x69, 0xb4, 0xd7, 0x24, 0x71, 0xcd, +0x86, 0xce, 0xbd, 0xcd, 0xb9, 0xf7, 0x7c, 0x98, +0x56, 0x85, 0xd3, 0x2c, 0x8a, 0x13, 0x26, 0xb7, +0xa5, 0x13, 0x3d, 0xe6, 0xe6, 0xe6, 0x02, 0xf3, +0x24, 0xf1, 0x03, 0xda, 0xb7, 0xad, 0xb5, 0x6a, +0x15, 0xdc, 0x34, 0x10, 0x43, 0x36, 0xde, 0xd2, +0x7f, 0xac, 0xae, 0x67, 0xdf, 0x8c, 0xa3, 0xd8, +0x47, 0xf9, 0x26, 0x22, 0x9f, 0xc9, 0x22, 0x99, +0x84, 0x69, 0xe3, 0xd2, 0x24, 0x48, 0xc3, 0x46, +0xe4, 0x54, 0x57, 0x01, 0x77, 0xdd, 0x81, 0xd2, +0x69, 0xd6, 0xd4, 0x67, 0x01, 0xdf, 0x01, 0x0d, +0x57, 0xfa, 0x6f, 0xf2, 0x31, 0x88, 0x40, 0x8b, +0x80, 0x94, 0xa5, 0xc1, 0xe9, 0x86, 0x9e, 0xda, +0xf3, 0x30, 0x26, 0x5a, 0xaf, 0xa9, 0x87, 0x88, +0x0e, 0xe9, 0x8f, 0x9e, 0x25, 0x9c, 0x20, 0x1d, +0xa9, 0xf0, 0x75, 0xc1, 0xe7, 0xc8, 0x30, 0xd7, +0x2a, 0x7c, 0x41, 0x73, 0xad, 0x4e, 0x07, 0xee, +0x92, 0x79, 0xcb, 0xb1, 0xd8, 0xe2, 0xa2, 0xe5, +0xfa, 0x26, 0xe6, 0x65, 0x3b, 0xc8, 0xf1, 0x22, +0x71, 0x8d, 0xea, 0x6b, 0x12, 0x65, 0xdd, 0xf3, +0xd2, 0xa8, 0xa3, 0x9e, 0xea, 0x5b, 0xc7, 0x63, +0xed, 0xc2, 0x12, 0xa7, 0x74, 0xd1, 0x0c, 0x37, +0xac, 0x5f, 0x6d, 0x6c, 0x11, 0x25, 0x6d, 0x75, +0xac, 0xda, 0x6f, 0xcb, 0x44, 0x73, 0x43, 0x3f, +0x89, 0xeb, 0x5f, 0xfb, 0xe6, 0xbb, 0x27, 0x52, +0x4d, 0xff, 0x12, 0x15, 0xcf, 0xf3, 0x50, 0x28, +0x14, 0x7c, 0x1b, 0x6a, 0x36, 0x9b, 0xf5, 0xb3, +0xbe, 0x25, 0x12, 0x09, 0x54, 0x2a, 0x15, 0xdf, +0x96, 0xb8, 0xbc, 0xbc, 0x8c, 0xc9, 0xc9, 0x49, +0x14, 0x0a, 0x05, 0x2c, 0x2e, 0x2e, 0x62, 0x69, +0x69, 0x09, 0xc5, 0x62, 0x11, 0x40, 0x7b, 0x93, +0xe3, 0x36, 0x73, 0xb2, 0x17, 0xc7, 0xe3, 0x09, +0xb4, 0x9a, 0xcd, 0x80, 0x04, 0x4e, 0xef, 0x81, +0xce, 0x2c, 0x6d, 0xd2, 0xee, 0xcd, 0x61, 0x71, +0x9b, 0x27, 0xff, 0xcf, 0xed, 0xd8, 0x1c, 0x06, +0xd9, 0x67, 0xe5, 0x45, 0x2a, 0xf2, 0x32, 0x17, +0xc7, 0x71, 0x54, 0x0f, 0x6e, 0x79, 0xdf, 0x36, +0xb7, 0xd5, 0x4a, 0xb8, 0x26, 0x5b, 0xbc, 0xc4, +0x91, 0xbf, 0x93, 0x38, 0x13, 0x6c, 0x2e, 0x15, +0xdb, 0x3c, 0xc1, 0xa9, 0xdf, 0x4c, 0x26, 0xd3, +0xd1, 0x07, 0xd0, 0x66, 0xe2, 0x74, 0xb9, 0x08, +0xdd, 0x0f, 0xce, 0x19, 0x1a, 0xd9, 0xbc, 0x09, +0x1f, 0xba, 0x8f, 0x5e, 0x66, 0xbc, 0x5b, 0x5c, +0x5c, 0x84, 0xe7, 0x79, 0x58, 0x59, 0x59, 0xc1, +0xf9, 0xf3, 0xe7, 0x03, 0x99, 0xfd, 0xb4, 0xf9, +0x90, 0xf8, 0xca, 0xec, 0x6c, 0x5a, 0xc6, 0x3d, +0x6d, 0x9c, 0xb1, 0x58, 0xcc, 0xcf, 0x44, 0x58, +0x2e, 0xaf, 0x5f, 0x94, 0xc2, 0xe7, 0x82, 0xd6, +0x10, 0xd5, 0x6f, 0xb5, 0x5a, 0xbe, 0x0d, 0x9d, +0xd3, 0x9f, 0xc6, 0xcb, 0xe7, 0x5f, 0x73, 0x44, +0x5c, 0x58, 0x58, 0xf0, 0x33, 0xc5, 0x99, 0xe2, +0xec, 0x09, 0x0e, 0xd1, 0xa0, 0xde, 0x68, 0xe1, +0xc1, 0x3c, 0xb0, 0x54, 0x63, 0x71, 0xe7, 0x51, +0xec, 0x86, 0xf2, 0x79, 0x58, 0x9b, 0x7a, 0x0d, +0x68, 0x36, 0xdb, 0xef, 0x4c, 0xf6, 0x34, 0xbe, +0x06, 0x34, 0x78, 0xbc, 0x5d, 0xc4, 0x8c, 0x55, +0xcd, 0x44, 0x32, 0x70, 0x17, 0x73, 0x33, 0x95, +0x46, 0x33, 0x9e, 0x08, 0x3e, 0x13, 0x75, 0x3a, +0xfa, 0xe2, 0x28, 0x56, 0x0a, 0xed, 0xfa, 0x68, +0x6f, 0x66, 0xcd, 0x84, 0x65, 0x53, 0x15, 0xf8, +0x36, 0x53, 0x69, 0xbf, 0x1f, 0x1f, 0x4e, 0xc2, +0x09, 0xc0, 0x54, 0xfb, 0xe6, 0xdf, 0x39, 0x1d, +0xe5, 0xf7, 0xb0, 0x39, 0xd0, 0xe8, 0xb8, 0x46, +0x13, 0xba, 0x87, 0x9c, 0x70, 0xd1, 0xe8, 0x86, +0x5a, 0xc5, 0x4c, 0x7f, 0x8b, 0xed, 0x3d, 0x32, +0x7c, 0x3e, 0x07, 0x92, 0x06, 0xf1, 0x44, 0x70, +0x7d, 0x98, 0xea, 0xd8, 0xe6, 0x40, 0xab, 0x67, +0x7b, 0x07, 0xf8, 0xf7, 0x7f, 0xf3, 0x39, 0x0a, +0xe0, 0x4e, 0x63, 0x92, 0xf8, 0x87, 0xac, 0x05, +0x2b, 0x7e, 0x54, 0x47, 0xd2, 0x8b, 0x97, 0x4a, +0x19, 0x40, 0x2b, 0x7a, 0xe6, 0x36, 0x79, 0xf8, +0xb6, 0xe1, 0x60, 0xf8, 0xfd, 0x38, 0xd5, 0xd5, +0xc0, 0x38, 0xe5, 0x1c, 0xaa, 0xbf, 0x07, 0x03, +0x7e, 0x71, 0x60, 0xfd, 0x9a, 0x48, 0x8d, 0x41, +0xf0, 0x04, 0x32, 0xf2, 0xe2, 0x0a, 0xf2, 0x6e, +0x1e, 0x1b, 0x1b, 0xc3, 0xe4, 0xe4, 0x24, 0x00, +0x84, 0x4a, 0x4a, 0x49, 0x27, 0x88, 0x88, 0x29, +0x84, 0x4d, 0x93, 0x8c, 0x6d, 0x31, 0xd8, 0xa6, +0x3e, 0x35, 0xdb, 0xb7, 0xb4, 0x0b, 0xcb, 0x62, +0xf2, 0xc8, 0xd6, 0xf0, 0xd1, 0x8a, 0xcd, 0x5e, +0x6f, 0x8b, 0xa9, 0xb7, 0x99, 0x25, 0x4c, 0x1e, +0xe0, 0x1a, 0x5d, 0x28, 0x37, 0x80, 0x0c, 0x3f, +0xe3, 0x17, 0x9a, 0x98, 0x24, 0x73, 0x1e, 0xe6, +0x25, 0x63, 0xc3, 0x49, 0xcd, 0x9d, 0xcb, 0xe5, +0xfc, 0xdc, 0xeb, 0x9a, 0xb4, 0xaa, 0xe1, 0x25, +0xc7, 0xa5, 0xf9, 0x17, 0xc8, 0xd0, 0x3d, 0xfe, +0x99, 0x9b, 0x23, 0x78, 0xbe, 0x77, 0x69, 0xe2, +0xa0, 0xef, 0x4b, 0x4b, 0x4b, 0xfe, 0x65, 0x40, +0x32, 0x89, 0x0c, 0xbf, 0x77, 0xdd, 0x34, 0x6f, +0xdc, 0x67, 0x80, 0xf0, 0x22, 0xbb, 0xbd, 0x16, +0xbd, 0x40, 0x63, 0x2a, 0x97, 0xcb, 0x68, 0x56, +0xcb, 0xe8, 0x8b, 0x47, 0x48, 0x20, 0xd3, 0xab, +0xed, 0x91, 0x4b, 0x4b, 0x9a, 0xe4, 0xd6, 0x8d, +0xed, 0xd8, 0xa6, 0x02, 0x8e, 0xa8, 0xba, 0x77, +0x4a, 0x17, 0xa3, 0x49, 0x55, 0x86, 0xbe, 0xea, +0xa9, 0x3e, 0xbf, 0xbd, 0xaf, 0x02, 0x35, 0xd1, +0x48, 0xc2, 0x60, 0xd7, 0x42, 0xd6, 0x53, 0x7d, +0xfe, 0xb3, 0x0e, 0x38, 0x1a, 0xed, 0x6c, 0x70, +0xbb, 0xcd, 0x36, 0xc7, 0x25, 0x2b, 0x71, 0x47, +0xb9, 0x8f, 0x17, 0x15, 0xa2, 0x55, 0xa3, 0x1e, +0x4d, 0x05, 0xcf, 0xf1, 0xe1, 0x6d, 0x19, 0x7c, +0x55, 0x0a, 0xe7, 0x57, 0x66, 0x46, 0xd1, 0xfa, +0x54, 0xca, 0xa1, 0x26, 0x1a, 0xa7, 0xba, 0xda, +0xbb, 0xa7, 0xfa, 0xda, 0xfb, 0xb0, 0xf5, 0xe2, +0x94, 0x2e, 0x76, 0xd2, 0xcc, 0x46, 0x13, 0xa9, +0xde, 0xb7, 0x8d, 0xc1, 0x46, 0x2f, 0xd7, 0xeb, +0xce, 0x44, 0x15, 0x35, 0x9b, 0x1f, 0xa7, 0xbd, +0x36, 0xee, 0x46, 0xdd, 0xa8, 0x99, 0xe8, 0xa0, +0x83, 0x49, 0x05, 0x5f, 0xaf, 0x21, 0x9e, 0x2f, +0x14, 0x03, 0x9b, 0xa1, 0x8c, 0xb3, 0x96, 0x71, +0xbe, 0x3c, 0xec, 0x87, 0xdb, 0xc9, 0x3d, 0xcf, +0xc3, 0xf8, 0xf8, 0xb8, 0x1f, 0xba, 0x24, 0x9d, +0x93, 0xa2, 0x14, 0xdb, 0xe6, 0x6f, 0x82, 0x65, +0x52, 0xe3, 0xca, 0x76, 0xda, 0x77, 0x9b, 0xed, +0x34, 0xcc, 0x36, 0x1e, 0x95, 0x91, 0xdb, 0x54, +0xee, 0x1a, 0x23, 0xb7, 0x31, 0x41, 0x4d, 0x5a, +0x95, 0xd2, 0x3a, 0x7d, 0x26, 0x66, 0x4d, 0x4c, +0x9d, 0xfe, 0xb8, 0xea, 0x5d, 0x3b, 0x00, 0x71, +0x95, 0xb7, 0xa4, 0x29, 0x65, 0x46, 0xa3, 0x5c, +0xfd, 0xdc, 0x01, 0x8e, 0x0e, 0x49, 0x13, 0x13, +0x13, 0x3e, 0x03, 0xa4, 0xb5, 0xa0, 0x1d, 0x46, +0x6c, 0x73, 0x23, 0xd7, 0x8e, 0x34, 0x29, 0xf0, +0x1b, 0xd9, 0x4c, 0xa1, 0x8d, 0x32, 0xf5, 0x30, +0xa7, 0xb1, 0xe9, 0x00, 0xc5, 0xd7, 0x8e, 0x96, +0x3a, 0x76, 0x79, 0x79, 0xd9, 0x57, 0xef, 0x53, +0x5b, 0x2d, 0x41, 0xd2, 0xb6, 0xac, 0x87, 0xff, +0xb8, 0x17, 0xd8, 0x9b, 0x31, 0x6c, 0x58, 0x9c, +0xa1, 0x44, 0x75, 0xb0, 0xe1, 0x25, 0x8c, 0x01, +0xd8, 0x6c, 0xc7, 0x61, 0xb6, 0xb9, 0x30, 0x1b, +0xa5, 0xb0, 0x3f, 0x02, 0x6b, 0x1b, 0x8e, 0xbc, +0x6b, 0x59, 0xd6, 0x33, 0xf5, 0xb5, 0x56, 0xcf, +0x57, 0x79, 0x32, 0x38, 0x56, 0xc6, 0xa1, 0x7d, +0x67, 0xfd, 0x1a, 0x55, 0xa8, 0x51, 0x1c, 0x02, +0xa3, 0x1e, 0x70, 0x94, 0xfa, 0x01, 0x5a, 0x18, +0xd4, 0xc8, 0x1d, 0xb8, 0x85, 0x31, 0x22, 0xf6, +0x3e, 0xd0, 0x96, 0xc1, 0x0f, 0x1c, 0x5e, 0x94, +0x39, 0xb2, 0xda, 0x9b, 0xa9, 0xb8, 0xfa, 0x9e, +0xc6, 0xd7, 0x6b, 0x07, 0x73, 0x89, 0x6a, 0xd3, +0x66, 0xef, 0x89, 0x46, 0x01, 0x58, 0x0c, 0x67, +0x7a, 0x4e, 0x63, 0x55, 0x19, 0xaf, 0x84, 0x6b, +0xa2, 0x9b, 0x01, 0x17, 0x9f, 0x5e, 0x61, 0x3e, +0x02, 0x51, 0xfb, 0x31, 0xd1, 0x54, 0xd0, 0x48, +0xce, 0x3d, 0xe1, 0xe1, 0xaf, 0x1b, 0x6d, 0xee, +0x34, 0x58, 0xca, 0x9a, 0x4d, 0x6c, 0x7f, 0xf9, +0x2b, 0xef, 0xce, 0x15, 0x17, 0xdb, 0xe1, 0x66, +0xb1, 0x38, 0x62, 0x89, 0x04, 0xd0, 0x6c, 0xa0, +0xd2, 0x68, 0x02, 0xcd, 0x06, 0x06, 0x07, 0x07, +0xe1, 0x38, 0x0e, 0x16, 0x16, 0x16, 0x7c, 0x15, +0x30, 0x25, 0x8a, 0xa1, 0xcd, 0xae, 0x5e, 0xaf, +0x63, 0x6c, 0x6c, 0x0c, 0x8f, 0x3f, 0xfe, 0x38, +0x4e, 0x9f, 0x3e, 0x1d, 0x90, 0xea, 0xf8, 0x9d, +0xe5, 0xf4, 0x5d, 0xaa, 0xcf, 0x01, 0x18, 0xd5, +0xb2, 0x7c, 0x23, 0xe7, 0xa1, 0x71, 0xf4, 0x5d, +0xbb, 0x47, 0x5c, 0x3b, 0x08, 0xf0, 0x77, 0x3c, +0xbc, 0x48, 0x53, 0x7b, 0xf3, 0x76, 0x52, 0xb5, +0x4f, 0xaa, 0x7a, 0x1e, 0x82, 0x25, 0x55, 0xea, +0xa6, 0x10, 0x3c, 0xad, 0x0f, 0x1a, 0x0f, 0xa9, +0xb8, 0xe5, 0x5d, 0xe4, 0x14, 0x92, 0x25, 0x2f, +0x7a, 0x91, 0xea, 0x7e, 0xaa, 0xcb, 0x2f, 0x1b, +0xa1, 0x4b, 0x70, 0x80, 0x36, 0x03, 0xe6, 0x21, +0x85, 0x14, 0x4e, 0x25, 0xf1, 0xa5, 0xf0, 0x33, +0xde, 0x4f, 0xa1, 0x50, 0xf0, 0x19, 0x79, 0xa1, +0x50, 0x40, 0xb1, 0x58, 0xf4, 0x19, 0xee, 0xd8, +0xd8, 0x18, 0xb6, 0x6c, 0xd9, 0xe2, 0x5f, 0x64, +0x42, 0x6a, 0x77, 0x82, 0x23, 0x2f, 0xb9, 0xe1, +0xf4, 0xe2, 0x7d, 0xf0, 0x39, 0xa2, 0xf1, 0xf0, +0x8b, 0x64, 0xb8, 0x49, 0x83, 0x87, 0x91, 0xe5, +0xf3, 0x79, 0xff, 0xbe, 0xf2, 0x58, 0x2c, 0x86, +0x95, 0x95, 0x15, 0x14, 0x8b, 0x45, 0x94, 0xcb, +0xed, 0xfb, 0xcf, 0xe9, 0x3f, 0x9f, 0x43, 0xbe, +0x26, 0x65, 0xe8, 0x1a, 0x3d, 0x27, 0xfa, 0xd2, +0x38, 0x39, 0x1e, 0x89, 0x44, 0x02, 0xc9, 0x64, +0xd2, 0x5f, 0x0b, 0xb4, 0xde, 0x89, 0x56, 0xad, +0x46, 0x03, 0xc3, 0x99, 0x34, 0x26, 0x07, 0xd2, +0xf8, 0xc6, 0x0a, 0x50, 0xa8, 0xad, 0xf5, 0x4f, +0x2a, 0x33, 0x9b, 0x4a, 0x92, 0xab, 0xe7, 0x34, +0x55, 0xaf, 0x56, 0x6c, 0x6a, 0x76, 0xd9, 0x8f, +0xa6, 0x22, 0x34, 0xa8, 0x8a, 0x55, 0x1c, 0x6b, +0x15, 0x34, 0x93, 0xcc, 0x34, 0xc3, 0xd5, 0x80, +0x6b, 0xea, 0x53, 0x00, 0x40, 0xab, 0x19, 0x54, +0x0f, 0x9a, 0x54, 0xc9, 0x6b, 0xf5, 0xe2, 0x8d, +0x5a, 0x87, 0x5a, 0xd5, 0x6f, 0x4f, 0x78, 0x49, +0x3c, 0x35, 0x5c, 0x5b, 0x4d, 0xc4, 0x1b, 0xb5, +0xf6, 0x26, 0x19, 0x45, 0x45, 0x2b, 0xd5, 0xa6, +0x52, 0x35, 0xda, 0x6c, 0xea, 0x36, 0xec, 0x08, +0x25, 0xa0, 0x46, 0x4e, 0xa5, 0xe1, 0x94, 0x2e, +0xb6, 0xd5, 0xbb, 0x52, 0x7d, 0xdc, 0x05, 0xfd, +0x39, 0x4d, 0x03, 0xa6, 0x84, 0x78, 0x7c, 0xfd, +0x7b, 0x3c, 0xde, 0x36, 0x7b, 0x68, 0x25, 0x6a, +0x98, 0x98, 0x54, 0x61, 0x6b, 0xa6, 0x0b, 0xad, +0x6e, 0x37, 0x7d, 0xd0, 0x38, 0xaa, 0xab, 0x68, +0x26, 0xdd, 0x0e, 0x9c, 0x7d, 0xda, 0xb5, 0x10, +0xae, 0xba, 0x37, 0xa9, 0xfe, 0xf9, 0x33, 0x6e, +0x4a, 0x21, 0xfa, 0xd3, 0x9e, 0x2c, 0xdb, 0xaf, +0xd5, 0x75, 0xea, 0x95, 0x70, 0xb3, 0x4f, 0x17, +0xeb, 0xa3, 0x03, 0x96, 0x5c, 0xa3, 0x6b, 0xeb, +0xb7, 0xe3, 0xf7, 0x60, 0x5b, 0xa7, 0x34, 0x5c, +0xce, 0xf8, 0xdc, 0x44, 0xdc, 0x0f, 0x4b, 0x1b, +0xcc, 0xf4, 0x21, 0x97, 0xcb, 0xf9, 0x09, 0x35, +0x34, 0x29, 0x6e, 0x6a, 0x6a, 0xca, 0x97, 0xd8, +0x66, 0x67, 0x67, 0x01, 0x00, 0x53, 0x53, 0x53, +0x6a, 0x82, 0x19, 0x2e, 0xf5, 0xd4, 0xea, 0x8d, +0x00, 0x1c, 0xcd, 0x99, 0xcb, 0x24, 0xcd, 0xcb, +0x4b, 0x5c, 0x38, 0x9c, 0x30, 0x18, 0x36, 0x0f, +0x66, 0x5b, 0x9f, 0x26, 0x09, 0x5b, 0xc3, 0x5d, +0xfb, 0x1c, 0xe6, 0xa4, 0x67, 0x82, 0x1b, 0xe6, +0x28, 0xc8, 0xf1, 0x96, 0xe6, 0x0a, 0x4a, 0x80, +0xa2, 0xa9, 0xd4, 0x35, 0x3c, 0x35, 0xa7, 0x37, +0x2d, 0xdc, 0x8c, 0x4b, 0xca, 0x74, 0x98, 0xa3, +0x35, 0x62, 0xbb, 0x98, 0xc4, 0x14, 0x0a, 0x26, +0xf1, 0x09, 0x7b, 0xaf, 0xf9, 0x0d, 0x48, 0x93, +0x82, 0xcc, 0xcf, 0x6e, 0x72, 0xba, 0x93, 0x38, +0xd2, 0x78, 0xe4, 0xdd, 0x04, 0x3c, 0xdc, 0x6d, +0x70, 0x70, 0xd0, 0x37, 0x4b, 0x2d, 0x2d, 0x2d, +0x05, 0xbc, 0xdb, 0xa9, 0x0d, 0xb5, 0xbb, 0x63, +0xb0, 0x85, 0xeb, 0xdd, 0xaa, 0xdf, 0x4f, 0x40, +0x12, 0x31, 0x49, 0x99, 0x52, 0xd2, 0x89, 0xea, +0xdd, 0xde, 0x6d, 0x92, 0x12, 0x4d, 0x8a, 0x32, +0xa9, 0xea, 0x2d, 0x92, 0x23, 0x97, 0x08, 0x9d, +0xd2, 0x45, 0x5f, 0x02, 0xed, 0x90, 0xca, 0x43, +0xa4, 0x17, 0x55, 0xba, 0x37, 0xf4, 0x19, 0x90, +0x74, 0x94, 0xfe, 0x02, 0xb0, 0xc2, 0xd4, 0xd6, +0x36, 0x67, 0x2a, 0x29, 0x89, 0x39, 0x49, 0x5d, +0x92, 0x33, 0xf4, 0x11, 0x50, 0xe7, 0x32, 0x49, +0x34, 0x20, 0x9d, 0x49, 0xda, 0x6e, 0x36, 0x7c, +0x13, 0x0c, 0x29, 0x79, 0x1a, 0x22, 0x0c, 0x34, +0xf8, 0xa1, 0xf3, 0x43, 0x25, 0xa2, 0xb9, 0xa7, +0x9e, 0x1e, 0xd0, 0x71, 0xd6, 0xe0, 0x77, 0x63, +0x06, 0x92, 0xfd, 0x47, 0x51, 0x8b, 0x8b, 0xf1, +0x4b, 0x8d, 0x87, 0x15, 0xb7, 0x28, 0xbf, 0x1f, +0xed, 0xbb, 0x80, 0x5f, 0x4f, 0x0f, 0xac, 0xaf, +0xe1, 0xb0, 0x88, 0x0f, 0x06, 0x2f, 0x5e, 0x2e, +0x97, 0x11, 0x4b, 0x75, 0x86, 0x08, 0x01, 0x41, +0x95, 0x3a, 0x31, 0x6d, 0x52, 0xd3, 0x72, 0x15, +0x23, 0xd5, 0x9f, 0x9c, 0x9c, 0x44, 0x2e, 0x97, +0xc3, 0xcc, 0xcc, 0x4c, 0x87, 0x3a, 0x3a, 0x8a, +0x07, 0x76, 0x98, 0xa7, 0xb1, 0x6d, 0xd3, 0x37, +0x79, 0x84, 0xf7, 0xa2, 0x4a, 0x97, 0xef, 0x4d, +0x78, 0x6a, 0x37, 0xae, 0xf1, 0xfa, 0x51, 0xcc, +0x0b, 0x9a, 0x0d, 0x5c, 0xc3, 0x99, 0xc2, 0xc0, +0x4c, 0x6d, 0x69, 0x2e, 0xe8, 0xbe, 0x70, 0x2a, +0xd2, 0x6e, 0xce, 0x0b, 0x31, 0x79, 0x2d, 0x6f, +0xba, 0x16, 0x36, 0x46, 0xfd, 0x98, 0x18, 0xb3, +0x8c, 0xbb, 0xd6, 0xc2, 0xf5, 0x64, 0x3f, 0x36, +0xbf, 0x05, 0x13, 0x3d, 0xa5, 0x1a, 0x5e, 0xf3, +0x03, 0x30, 0x79, 0xf2, 0x9b, 0xe6, 0x9e, 0x33, +0x71, 0xee, 0x0b, 0xc0, 0x6d, 0xe6, 0xfc, 0xd0, +0x42, 0x51, 0x1d, 0x3c, 0xc2, 0x81, 0x7c, 0x48, +0x38, 0xae, 0x37, 0xec, 0xd9, 0xa1, 0x23, 0x20, +0x19, 0x75, 0x94, 0x8b, 0x41, 0xba, 0xf5, 0xe2, +0x05, 0xec, 0x61, 0x2e, 0x36, 0x38, 0x26, 0x95, +0xab, 0x2c, 0xc2, 0x66, 0x4d, 0x1b, 0x73, 0x60, +0x13, 0xdc, 0xc8, 0xe5, 0x12, 0x21, 0xf8, 0xab, +0xfd, 0x45, 0x19, 0x5f, 0xaf, 0x85, 0xe8, 0xc2, +0x37, 0x6b, 0x8b, 0xb9, 0x44, 0xc3, 0xcb, 0x67, +0xc2, 0xcc, 0xb3, 0xbd, 0x03, 0xbe, 0x1c, 0x03, +0xd9, 0x9b, 0xa5, 0x89, 0x43, 0xc0, 0x77, 0xaa, +0xab, 0x41, 0xf8, 0x92, 0x76, 0x92, 0x39, 0x98, +0x0e, 0x4a, 0xe4, 0xcf, 0x60, 0xa0, 0xab, 0x0f, +0xdf, 0x16, 0x66, 0x27, 0x23, 0x37, 0x0c, 0x63, +0xe0, 0xf3, 0x67, 0x8c, 0x4e, 0xb0, 0x31, 0x35, +0xd3, 0x5a, 0x32, 0xac, 0x61, 0xab, 0xda, 0xde, +0xe2, 0x93, 0x21, 0x0f, 0x1c, 0x56, 0x75, 0xb8, +0xed, 0xf7, 0x23, 0x0f, 0xa3, 0x02, 0x7e, 0xc0, +0xa7, 0x20, 0x6a, 0x34, 0x46, 0xbd, 0xd6, 0x76, +0x80, 0x6b, 0x55, 0xcb, 0x2a, 0xa3, 0xe0, 0xf6, +0x72, 0x69, 0x97, 0x25, 0xa9, 0x9c, 0x6f, 0xc4, +0x24, 0xa1, 0x6b, 0x9b, 0x3d, 0x2f, 0x49, 0x27, +0xa1, 0xc6, 0x06, 0xf3, 0xbe, 0xbb, 0x29, 0xd2, +0x16, 0x6a, 0xb3, 0xb7, 0xcb, 0x3a, 0x5a, 0x4c, +0xb8, 0xd6, 0xd6, 0xc4, 0xb0, 0x6d, 0xf1, 0xe7, +0xb6, 0x22, 0x19, 0x36, 0xd7, 0x66, 0x68, 0x07, +0x04, 0xc9, 0x9c, 0xa2, 0x68, 0x1f, 0xa4, 0x44, +0xce, 0x35, 0x2c, 0x32, 0x85, 0xaf, 0x84, 0x41, +0xb0, 0x79, 0x58, 0x22, 0x67, 0xd4, 0xb9, 0x5c, +0x0e, 0xa3, 0xa3, 0xa3, 0xfe, 0x21, 0x8f, 0xd4, +0xf0, 0x72, 0xfe, 0x34, 0xc9, 0xd8, 0x26, 0x1d, +0xdb, 0xc6, 0xa8, 0x69, 0x35, 0x48, 0x52, 0x26, +0x7f, 0x00, 0x7e, 0xc9, 0x8c, 0x09, 0x1e, 0x67, +0xdc, 0x26, 0xfa, 0x0c, 0x0e, 0x0e, 0x62, 0x70, +0x70, 0x50, 0x6d, 0x4f, 0x5a, 0x0f, 0x9e, 0x27, +0x40, 0x5e, 0x34, 0x43, 0x07, 0x8e, 0x43, 0xd5, +0xf9, 0x76, 0x98, 0x9a, 0x56, 0xc2, 0x6c, 0xdf, +0x51, 0xe3, 0xb6, 0x4d, 0x3f, 0x78, 0x53, 0x68, +0x93, 0x09, 0xa6, 0x49, 0x92, 0x32, 0xc0, 0x37, +0x39, 0x5d, 0xa9, 0x52, 0xb6, 0xdc, 0x84, 0x4d, +0x71, 0xc0, 0xb6, 0x58, 0x5e, 0x8d, 0x26, 0xb2, +0x3f, 0x8b, 0xcd, 0xd1, 0xd8, 0x87, 0x89, 0x1e, +0xb6, 0xe7, 0x72, 0xb3, 0xd6, 0xc2, 0xcd, 0xd6, +0xe8, 0xa1, 0x8d, 0x33, 0x54, 0x7b, 0x60, 0x90, +0x2a, 0x3b, 0xa4, 0x63, 0x41, 0xe7, 0x0e, 0x1b, +0xac, 0xa4, 0x77, 0xd4, 0xdb, 0xe4, 0xe8, 0x7b, +0x18, 0xfe, 0x1a, 0x3c, 0x4e, 0x1b, 0x85, 0xf9, +0xca, 0x31, 0x70, 0x5c, 0xa5, 0xa6, 0xc7, 0xa7, +0x4f, 0x37, 0x57, 0xc7, 0xda, 0xa4, 0x62, 0x8d, +0x86, 0x1a, 0x8c, 0x08, 0xed, 0x3a, 0xe0, 0xf4, +0xf0, 0xfb, 0xe1, 0xe3, 0x25, 0x78, 0x56, 0x2d, +0x95, 0xe5, 0x50, 0x1e, 0x4f, 0x27, 0x1d, 0x23, +0x23, 0xd3, 0xd4, 0xa6, 0xc0, 0xba, 0x17, 0xfb, +0xfc, 0xfc, 0xbc, 0xff, 0x9f, 0x36, 0x78, 0xdb, +0x9d, 0xd7, 0x5a, 0x91, 0x0e, 0x48, 0xb2, 0xef, +0xa8, 0x8c, 0x9d, 0x7b, 0xc1, 0x6b, 0xb0, 0xf9, +0x33, 0x13, 0x5e, 0x36, 0xa6, 0xaf, 0xc1, 0x24, +0x1c, 0xa3, 0x32, 0x74, 0x9b, 0xd4, 0xaf, 0xa9, +0xb7, 0x35, 0x0d, 0x89, 0x74, 0x92, 0xd3, 0xc2, +0xa5, 0x72, 0xb9, 0x9c, 0x2f, 0x91, 0x93, 0xb3, +0x9a, 0xad, 0x78, 0x9e, 0x87, 0x52, 0xa9, 0xd4, +0xc1, 0x90, 0xe7, 0xe7, 0xe7, 0x03, 0x17, 0xef, +0xd0, 0x33, 0xea, 0x73, 0x61, 0x61, 0x21, 0xe0, +0x10, 0xc6, 0x69, 0xa2, 0x5d, 0x19, 0x6a, 0xa2, +0x89, 0x36, 0x07, 0xda, 0xe1, 0xcc, 0xf4, 0x5d, +0x83, 0x6f, 0x5a, 0x3b, 0xd4, 0x56, 0xf3, 0xc4, +0xa7, 0xef, 0x24, 0x5d, 0xa7, 0xd3, 0xe9, 0x0e, +0x27, 0x4f, 0xa0, 0xcd, 0xf4, 0x4b, 0xa5, 0x12, +0xcb, 0xe5, 0xfe, 0xd9, 0x00, 0x00, 0x80, 0x00, +0x49, 0x44, 0x41, 0x54, 0x66, 0x67, 0x67, 0x51, +0x2a, 0x95, 0x02, 0x9e, 0xf6, 0x04, 0x87, 0x0e, +0x38, 0x83, 0x89, 0x56, 0x3b, 0x5f, 0xbb, 0xa9, +0x70, 0x15, 0xb4, 0xb6, 0xa1, 0xd2, 0x7b, 0x1b, +0xc3, 0xe6, 0x9f, 0xa5, 0xc4, 0x68, 0xab, 0x1f, +0x56, 0x42, 0x92, 0x82, 0xd4, 0xe3, 0x49, 0xb3, +0x74, 0xd2, 0x45, 0xb6, 0x34, 0xa3, 0xf7, 0x72, +0x58, 0x5b, 0x6d, 0x7c, 0x32, 0xa6, 0x98, 0xc1, +0xf2, 0x9f, 0x9b, 0xbc, 0xa0, 0x4d, 0x34, 0xed, +0x42, 0x0b, 0x62, 0x32, 0xa5, 0x38, 0xd5, 0xd5, +0xa0, 0xaa, 0x5a, 0x3b, 0x8c, 0xf1, 0xb9, 0xe3, +0x0c, 0x91, 0xe3, 0x19, 0xe6, 0x6c, 0xd5, 0x2d, +0x13, 0xd0, 0xde, 0x99, 0xea, 0x56, 0x4a, 0x3a, +0xfe, 0xf2, 0xbb, 0xc6, 0x4c, 0xa3, 0xae, 0xbb, +0xca, 0xba, 0x70, 0xe1, 0xf7, 0xd5, 0x6d, 0x6e, +0x7a, 0xd3, 0x61, 0xc2, 0xd8, 0xa7, 0xc2, 0x63, +0x64, 0x74, 0x82, 0xec, 0x23, 0xca, 0xb8, 0x42, +0xe8, 0x5a, 0x8f, 0x27, 0xf5, 0xf9, 0x8a, 0x60, +0x96, 0xd2, 0x9e, 0xc5, 0x01, 0x73, 0xc6, 0x36, +0x4d, 0x92, 0x22, 0x69, 0x8d, 0x18, 0xf8, 0xcc, +0xcc, 0x0c, 0x00, 0xe0, 0xc4, 0x89, 0x13, 0x81, +0x0c, 0x61, 0x51, 0x8b, 0x64, 0x66, 0xdd, 0x30, +0x6f, 0x5e, 0xb4, 0xb0, 0xa6, 0x6e, 0xdb, 0x49, +0x29, 0x3d, 0x8c, 0x21, 0xd8, 0xf0, 0xb5, 0x31, +0x28, 0xd9, 0x8f, 0x94, 0xca, 0x6d, 0x78, 0xda, +0x9e, 0x71, 0xe6, 0x4e, 0x4c, 0x9c, 0x18, 0x39, +0x4f, 0x02, 0x44, 0x7d, 0xd3, 0x7b, 0x8d, 0x69, +0x6b, 0x12, 0x34, 0x1d, 0x5c, 0xe8, 0xd0, 0xc6, +0xef, 0xfd, 0x96, 0xf8, 0x6b, 0xf8, 0xd9, 0xfc, +0x21, 0x4c, 0x9e, 0xed, 0x26, 0xcd, 0x0d, 0xf5, +0xa5, 0xf9, 0x73, 0xd8, 0x68, 0x26, 0xdb, 0x73, +0xdb, 0x3a, 0x3f, 0xa4, 0x11, 0x5d, 0x4a, 0xa5, +0x92, 0x7f, 0x78, 0xcd, 0xe5, 0x72, 0x18, 0x1c, +0x1c, 0x84, 0xeb, 0xba, 0xbe, 0x67, 0x3b, 0xcd, +0x9f, 0xe6, 0xf3, 0x90, 0xcf, 0xe7, 0x91, 0x6d, +0x56, 0xf0, 0x93, 0x7b, 0xfa, 0xd6, 0xa5, 0x73, +0x8d, 0x51, 0x48, 0xa9, 0x53, 0x32, 0x78, 0xed, +0xbd, 0x26, 0xb1, 0x3a, 0xc9, 0xf0, 0x2c, 0x68, +0x36, 0x9b, 0xbc, 0x41, 0xda, 0x54, 0x71, 0x59, +0xfb, 0xae, 0xaa, 0x47, 0x79, 0x5b, 0x0d, 0x7f, +0xf1, 0xb9, 0x9e, 0x1e, 0x30, 0xab, 0x51, 0xbb, +0x0d, 0x19, 0xeb, 0xc6, 0x9c, 0xa0, 0xd9, 0xc4, +0x35, 0x1c, 0x24, 0x6c, 0x9b, 0x3f, 0x81, 0x9c, +0xbb, 0x35, 0x69, 0xd6, 0x68, 0x6f, 0xb6, 0xd1, +0x5f, 0xc3, 0x53, 0x4b, 0x1e, 0x93, 0x50, 0x62, +0xc5, 0xa3, 0x64, 0x11, 0xa3, 0x71, 0x84, 0xd0, +0x58, 0x3d, 0xb0, 0xd9, 0xda, 0x68, 0xcc, 0xd4, +0x24, 0xf9, 0x9a, 0xc2, 0xca, 0xe8, 0x79, 0x98, +0x6d, 0x5f, 0xeb, 0xdf, 0x74, 0x98, 0x30, 0xb5, +0x35, 0x25, 0xca, 0x81, 0xa2, 0xe1, 0xb0, 0x8d, +0x2b, 0xca, 0xef, 0x47, 0x5b, 0x2f, 0x12, 0x27, +0x6d, 0x5d, 0x9a, 0xcc, 0x23, 0xac, 0x5d, 0xbc, +0x95, 0x70, 0x90, 0xee, 0x6f, 0xff, 0x20, 0x35, +0x06, 0xa2, 0x6d, 0xc8, 0x7c, 0xe3, 0xe7, 0xd2, +0x8a, 0x26, 0xc5, 0x9b, 0xec, 0xd2, 0x51, 0xa4, +0x77, 0x8d, 0xa9, 0x46, 0x39, 0x2c, 0x44, 0x61, +0xb6, 0x36, 0xb8, 0x36, 0x1b, 0xbb, 0xa6, 0xea, +0xb5, 0x49, 0xe7, 0x26, 0x55, 0xaf, 0xc4, 0x55, +0x4a, 0x96, 0x12, 0x16, 0x39, 0x75, 0x11, 0x63, +0xa1, 0xfb, 0xe4, 0x89, 0xc1, 0x10, 0x93, 0xb1, +0x8d, 0xd9, 0x34, 0x46, 0x39, 0x6f, 0x24, 0x6d, +0xf2, 0x22, 0xe3, 0xcf, 0xf9, 0x15, 0xa0, 0x32, +0x95, 0xab, 0x74, 0x98, 0x8b, 0xc2, 0xbc, 0xc3, +0x8a, 0x36, 0xa7, 0x5c, 0x22, 0xd7, 0x54, 0xf9, +0x9a, 0xdd, 0x5f, 0x8e, 0xb7, 0x52, 0xa9, 0x18, +0xb5, 0x2a, 0xa4, 0xc2, 0xe7, 0x6d, 0xe8, 0x9a, +0xe0, 0x72, 0xb9, 0xed, 0xc9, 0x4f, 0xef, 0x25, +0x33, 0xe7, 0x0e, 0x71, 0x2f, 0x77, 0x4b, 0x78, +0xef, 0x15, 0xd9, 0xce, 0xac, 0x70, 0xdd, 0xa4, +0xb5, 0x94, 0xef, 0xa3, 0xc6, 0xf7, 0x86, 0x49, +0x44, 0x51, 0x9d, 0x97, 0x4c, 0x70, 0xd6, 0x62, +0x64, 0x03, 0xb6, 0x55, 0x93, 0xc4, 0x6b, 0xb0, +0x71, 0x3a, 0xa5, 0x8b, 0x66, 0xfb, 0x67, 0x98, +0x54, 0xaf, 0x1d, 0x22, 0xa4, 0xf4, 0xcd, 0x61, +0x6d, 0x44, 0x5b, 0x41, 0x6d, 0x6d, 0x92, 0x9f, +0xcc, 0x82, 0x66, 0x8a, 0x6b, 0x0e, 0x53, 0x7b, +0x77, 0x23, 0xdd, 0xca, 0x38, 0xe5, 0xa8, 0x07, +0x14, 0x0b, 0x13, 0xe3, 0xdf, 0x03, 0x12, 0x72, +0x37, 0xa6, 0x20, 0x13, 0x9d, 0x4d, 0x8c, 0x4b, +0x1e, 0x56, 0x39, 0x2d, 0xe5, 0x38, 0xe4, 0x21, +0x4b, 0x3b, 0x14, 0xf1, 0xb8, 0x79, 0xed, 0x37, +0x15, 0xe6, 0x84, 0x2a, 0xc7, 0x16, 0x76, 0xa0, +0xe0, 0xc5, 0xe4, 0x53, 0x61, 0xd2, 0xbe, 0x85, +0xd1, 0x53, 0x33, 0xe3, 0x88, 0xf5, 0x9c, 0xb8, +0xe2, 0xb6, 0xd7, 0xdc, 0x3d, 0x5a, 0x5f, 0xf1, +0xb3, 0x78, 0xc9, 0xb0, 0x32, 0x1e, 0xfa, 0x44, +0xe1, 0x3a, 0xb9, 0x5c, 0x0e, 0xfb, 0xf6, 0xed, +0xf3, 0x9f, 0xcb, 0x4d, 0x7b, 0x76, 0x76, 0x16, +0xc5, 0x62, 0x31, 0x70, 0x23, 0x95, 0x96, 0xf5, +0x0c, 0x58, 0xdf, 0x98, 0x65, 0x16, 0x36, 0x19, +0xfa, 0x25, 0x43, 0xc4, 0x4c, 0x37, 0x93, 0x11, +0x4c, 0x1e, 0x6a, 0xc5, 0x43, 0x90, 0xe8, 0x73, +0x98, 0x44, 0x6d, 0xea, 0x93, 0x8f, 0x89, 0xd3, +0x47, 0x32, 0x44, 0x9e, 0xa1, 0x8e, 0x8f, 0x83, +0x33, 0x14, 0x79, 0x83, 0x5a, 0x36, 0x9b, 0x45, +0x2e, 0x97, 0xf3, 0xaf, 0x2a, 0x1d, 0x19, 0x19, +0x41, 0xb9, 0x5c, 0x46, 0x7f, 0x7f, 0x3f, 0xfa, +0xfb, 0xfb, 0x11, 0x8b, 0xc5, 0xfc, 0xba, 0xf4, +0xd9, 0xf3, 0x3c, 0xff, 0xf6, 0xb3, 0x74, 0x3a, +0x0d, 0xc7, 0x71, 0xb0, 0xb2, 0xb2, 0xd2, 0x11, +0x4f, 0x4e, 0x7f, 0x5a, 0xe6, 0x39, 0xd2, 0x14, +0x64, 0x32, 0x19, 0x24, 0x93, 0x49, 0x3f, 0xb4, +0x8b, 0xea, 0x2f, 0x2e, 0x2e, 0xa2, 0x5c, 0x0e, +0xde, 0xa6, 0x46, 0x59, 0x02, 0xf9, 0x5a, 0xa1, +0x5b, 0xc4, 0x02, 0x6b, 0x95, 0xcd, 0x7b, 0xb9, +0x5c, 0xee, 0x08, 0xab, 0x93, 0xdf, 0xb5, 0xdb, +0xe0, 0xb4, 0x35, 0xc4, 0xdb, 0x70, 0x9a, 0xf2, +0x7a, 0xfc, 0x56, 0x33, 0x6d, 0x0e, 0xe8, 0x7b, +0x26, 0x93, 0x41, 0xa3, 0xd1, 0xf0, 0xc3, 0xfa, +0xe8, 0xf3, 0xd0, 0xd0, 0x10, 0x56, 0x56, 0x56, +0x90, 0x4c, 0x26, 0xfd, 0x34, 0xb2, 0xc5, 0x62, +0xd1, 0xa7, 0x93, 0xeb, 0xba, 0x7e, 0x76, 0x38, +0xc2, 0x93, 0x87, 0xbc, 0xf1, 0x7e, 0xf6, 0xe6, +0x32, 0x28, 0xb5, 0x62, 0x78, 0x7c, 0xa5, 0xb9, +0x1e, 0xf2, 0x14, 0x31, 0x63, 0x54, 0xe0, 0xbb, +0x16, 0x96, 0xa5, 0x85, 0x69, 0x55, 0xca, 0xed, +0xb0, 0x1b, 0x2d, 0xa4, 0xcb, 0x04, 0x33, 0x38, +0x71, 0x3a, 0x7c, 0x25, 0x44, 0xa6, 0x23, 0xdb, +0x5b, 0x48, 0x7d, 0x89, 0xaf, 0x1a, 0xc2, 0x46, +0xf5, 0xf9, 0xc6, 0xda, 0x6c, 0x76, 0x64, 0x6a, +0x6b, 0x7a, 0xd9, 0x60, 0x36, 0x2d, 0x5b, 0xe8, +0x9f, 0xc4, 0x43, 0x0b, 0x79, 0x93, 0x99, 0xe0, +0xe8, 0x33, 0xd1, 0xd3, 0x56, 0x64, 0x38, 0x17, +0x2b, 0xc6, 0x30, 0x23, 0xed, 0xbb, 0x46, 0x7f, +0x40, 0xc5, 0x4d, 0xcd, 0xa0, 0xa6, 0xf4, 0x6f, +0xed, 0x93, 0xaf, 0x15, 0x39, 0x4f, 0xb2, 0xbe, +0x69, 0x7e, 0xb4, 0x3e, 0x25, 0xcd, 0x78, 0xa8, +0xa5, 0x0d, 0xb6, 0x29, 0x0c, 0xad, 0x5e, 0x6b, +0x87, 0x8a, 0xc9, 0x50, 0x35, 0x53, 0x98, 0xa2, +0xe3, 0x74, 0xf6, 0x61, 0xa2, 0xa7, 0xe8, 0xc7, +0x87, 0x29, 0xd7, 0x6c, 0xd4, 0x90, 0x4e, 0xd9, +0x37, 0x5f, 0xc7, 0xf2, 0x37, 0x67, 0x1a, 0xbb, +0xb2, 0x5e, 0x79, 0x58, 0xa8, 0x7c, 0x1f, 0x07, +0x10, 0x48, 0x15, 0x6a, 0x92, 0x92, 0xb9, 0x44, +0x2a, 0x2f, 0x07, 0xe1, 0x5e, 0xd1, 0xa4, 0x8e, +0xe4, 0x0e, 0x46, 0x9a, 0x7d, 0x98, 0xfe, 0x6a, +0x6b, 0x17, 0xbd, 0xf0, 0xe7, 0xbc, 0x9d, 0x29, +0x51, 0x8a, 0x4d, 0xe2, 0x0d, 0xf3, 0x8a, 0x37, +0x95, 0x28, 0x52, 0xbc, 0x0d, 0x0f, 0x93, 0x73, +0x9d, 0x84, 0x23, 0x25, 0x7c, 0x5e, 0x47, 0xbb, +0x83, 0x5c, 0x93, 0xa2, 0xa5, 0x79, 0x80, 0xdb, +0x76, 0x97, 0x97, 0x97, 0xe1, 0xba, 0xae, 0x7f, +0xcf, 0xbc, 0x0c, 0xb1, 0x92, 0x73, 0x21, 0x93, +0x06, 0x69, 0x8e, 0x5c, 0x9a, 0x89, 0x40, 0x3a, +0xc5, 0xc9, 0xa2, 0x25, 0x63, 0x09, 0xa3, 0xb3, +0xac, 0x63, 0xd2, 0xd6, 0xf0, 0xf1, 0x74, 0x2b, +0xf9, 0x4b, 0x18, 0xfc, 0x96, 0x39, 0xfe, 0x79, +0x69, 0x69, 0xc9, 0xf7, 0x5e, 0xa7, 0x92, 0xcb, +0xe5, 0x30, 0x34, 0x34, 0xe4, 0xdb, 0xd5, 0xa9, +0x1e, 0xd5, 0x91, 0xf6, 0x73, 0xcf, 0xf3, 0xd0, +0x97, 0xed, 0xc7, 0x48, 0x0a, 0xf8, 0x85, 0x3d, +0x49, 0xdc, 0xd8, 0x1f, 0xd7, 0xa5, 0x11, 0x9b, +0x77, 0x3b, 0x6d, 0x06, 0x9a, 0x64, 0x69, 0x92, +0x82, 0x43, 0xbc, 0xa2, 0x3b, 0xfa, 0xe0, 0xf0, +0xa2, 0x96, 0x28, 0x09, 0x34, 0xa2, 0x78, 0xe0, +0x6b, 0x63, 0xd0, 0xda, 0xaa, 0xa1, 0x62, 0x25, +0xbf, 0xbe, 0x35, 0x6b, 0x18, 0x57, 0xdb, 0x9a, +0x34, 0x1c, 0xf2, 0x99, 0x4d, 0x85, 0x0a, 0xb4, +0x99, 0x55, 0x14, 0x47, 0x44, 0x20, 0x68, 0x1b, +0xb5, 0x25, 0x0b, 0x8a, 0xe2, 0x23, 0x10, 0x66, +0xc7, 0x37, 0x99, 0x6b, 0x4c, 0xb8, 0x72, 0x49, +0x96, 0xaf, 0xb5, 0x30, 0x95, 0x70, 0x98, 0xc9, +0x43, 0x7a, 0xb3, 0x9b, 0xa4, 0x69, 0x85, 0x1e, +0x26, 0xd5, 0x7e, 0x3d, 0xd5, 0xd7, 0xce, 0x41, +0x1f, 0xb5, 0xf4, 0xe2, 0x38, 0x6a, 0x2b, 0x9a, +0xd9, 0x25, 0x2c, 0xf9, 0x93, 0x4d, 0x53, 0x22, +0xe9, 0xcc, 0x4d, 0x26, 0xe4, 0x70, 0xe8, 0x6b, +0x52, 0xd2, 0x9d, 0xb4, 0x61, 0x6b, 0x21, 0x9e, +0x1c, 0xc8, 0xf9, 0xcf, 0xb9, 0x84, 0xa9, 0x85, +0x12, 0x69, 0x0c, 0x7e, 0x69, 0x69, 0xa9, 0xc3, +0xde, 0x6a, 0xca, 0x61, 0xcd, 0xff, 0xd3, 0x7b, +0x4a, 0xef, 0x1a, 0x16, 0x52, 0x66, 0x53, 0xdf, +0x4b, 0x47, 0x26, 0xad, 0x98, 0xe2, 0xc3, 0x4d, +0x4e, 0x69, 0x36, 0xc9, 0x5d, 0x53, 0xd7, 0x86, +0xe1, 0x27, 0x9f, 0x9b, 0xda, 0xf1, 0xd0, 0x32, +0xcf, 0xf3, 0x30, 0x34, 0x34, 0xa4, 0xf6, 0xa3, +0xf9, 0x39, 0x2c, 0x2d, 0x2d, 0x61, 0x76, 0x76, +0x16, 0x9e, 0xd7, 0xce, 0xc6, 0x67, 0xea, 0x53, +0xc3, 0x8b, 0xfa, 0x96, 0x0e, 0x8c, 0x1a, 0xbd, +0xb8, 0x8a, 0x5d, 0x8b, 0x0a, 0xd0, 0x9c, 0x11, +0x35, 0x3a, 0xf6, 0x62, 0x46, 0x91, 0xfd, 0x98, +0xe0, 0x69, 0xf3, 0x60, 0xaa, 0x4b, 0x9a, 0x10, +0x9e, 0xae, 0x98, 0x6b, 0x36, 0x88, 0xb9, 0xf3, +0x50, 0x34, 0x5e, 0x78, 0x3a, 0x64, 0xa2, 0x0f, +0x45, 0x76, 0xcc, 0xce, 0xce, 0xe2, 0xc2, 0xe2, +0x39, 0xac, 0x5e, 0x6c, 0xff, 0x46, 0x6e, 0x1c, +0x49, 0x87, 0xdb, 0xfd, 0xa4, 0x4a, 0x4f, 0x63, +0x3e, 0x61, 0x36, 0x75, 0x4d, 0x25, 0x68, 0xdb, +0xa8, 0x65, 0x5f, 0x26, 0x87, 0xab, 0x6e, 0xd5, +0xe1, 0x26, 0x38, 0x61, 0xaa, 0xd6, 0xb0, 0xf6, +0x1a, 0x6d, 0x6c, 0xfd, 0xc8, 0xc3, 0x80, 0xcd, +0xb9, 0x4e, 0x6e, 0xce, 0xa4, 0x32, 0x95, 0xff, +0x29, 0xfd, 0x67, 0x98, 0x0a, 0x36, 0xcc, 0x19, +0xb0, 0x1b, 0xfa, 0x5b, 0x68, 0xee, 0x54, 0x57, +0xed, 0x8c, 0x3e, 0x6c, 0xec, 0x3c, 0x9d, 0x29, +0x57, 0x71, 0x4b, 0xa6, 0xd5, 0xcb, 0x7a, 0x33, +0xcd, 0x87, 0x86, 0x47, 0xc2, 0xe9, 0x38, 0x98, +0x75, 0xe4, 0x11, 0xd0, 0x68, 0xab, 0xe1, 0x12, +0x12, 0x7a, 0xd7, 0x31, 0xa7, 0x92, 0xbe, 0xa6, +0xdf, 0x24, 0x87, 0xc5, 0x69, 0x13, 0xb2, 0x0e, +0x54, 0x46, 0xcc, 0xfa, 0xe0, 0xe1, 0x6f, 0xd2, +0x31, 0x94, 0xde, 0x05, 0xcc, 0x36, 0xbc, 0x6d, +0xb5, 0x5a, 0x8d, 0x6c, 0xbf, 0xe4, 0xd2, 0x19, +0x57, 0xc9, 0x73, 0x66, 0x9e, 0xcf, 0xe7, 0x31, +0x35, 0x35, 0x15, 0xf0, 0x72, 0x0e, 0x63, 0xcc, +0x54, 0x47, 0x16, 0x9e, 0x5a, 0x56, 0x32, 0x34, +0x0d, 0xb6, 0xf4, 0x02, 0xb7, 0x49, 0x6c, 0x9a, +0xd7, 0xb4, 0xd6, 0x3f, 0xd0, 0x99, 0xb6, 0x56, +0xaa, 0xd5, 0xbb, 0x89, 0x63, 0x97, 0xef, 0xc3, +0x60, 0x00, 0xf0, 0x9d, 0xb0, 0xb8, 0x83, 0xa1, +0xb4, 0xcb, 0xce, 0xcd, 0xcd, 0xf9, 0xd7, 0xd8, +0x4e, 0x4e, 0x4e, 0xa2, 0x5c, 0x6e, 0x27, 0x35, +0xb1, 0x39, 0xce, 0x99, 0xa4, 0x65, 0xf9, 0x59, +0x4a, 0xe5, 0x1c, 0x77, 0xe9, 0x09, 0xce, 0x25, +0x7a, 0x0d, 0x06, 0x15, 0xed, 0xca, 0x5c, 0x0d, +0xbf, 0xb0, 0x43, 0x9e, 0xcd, 0x79, 0x53, 0xae, +0x57, 0x93, 0x4f, 0x84, 0xf4, 0x6c, 0xe7, 0x70, +0xb9, 0xa6, 0x64, 0x69, 0x69, 0xc9, 0xff, 0x4c, +0xe1, 0x70, 0x3c, 0xbe, 0x9d, 0x87, 0xf9, 0x49, +0xc6, 0xbf, 0x70, 0xfe, 0x02, 0x06, 0xcb, 0x65, +0xdc, 0x90, 0xde, 0x82, 0x2d, 0x7d, 0x1e, 0xce, +0x57, 0x1b, 0xe6, 0x53, 0xbe, 0x49, 0x3a, 0x94, +0x9b, 0x93, 0x49, 0x52, 0x0f, 0x93, 0x04, 0xe4, +0x67, 0xcd, 0x56, 0xc8, 0x37, 0x6e, 0xf6, 0xde, +0x77, 0xe6, 0x72, 0x92, 0xc1, 0x30, 0xa5, 0x30, +0xe7, 0x31, 0xd9, 0x77, 0x18, 0x3e, 0x36, 0xdb, +0xa2, 0xc4, 0x8d, 0xff, 0xd7, 0xea, 0xc9, 0x62, +0x62, 0x78, 0x36, 0xdb, 0x26, 0xa0, 0xdb, 0x98, +0x4d, 0x07, 0x11, 0x13, 0xbe, 0x1a, 0x6d, 0xba, +0xa0, 0xbf, 0x84, 0xc7, 0x9d, 0xeb, 0xac, 0xa9, +0x56, 0x4d, 0xeb, 0xab, 0x52, 0x36, 0x8f, 0x4b, +0x9b, 0x9b, 0x8d, 0xac, 0x37, 0x8e, 0x1a, 0x5b, +0x47, 0xb2, 0x0e, 0x67, 0x5a, 0x81, 0xba, 0xb2, +0xbd, 0x74, 0x9c, 0xb4, 0xd1, 0xd8, 0xb4, 0x66, +0x68, 0xec, 0xf4, 0xbf, 0x97, 0x35, 0xda, 0xc5, +0xfc, 0x05, 0x2c, 0xc3, 0x0a, 0x5d, 0xf8, 0x38, +0x65, 0xba, 0x5b, 0xe3, 0xbb, 0xb5, 0x7e, 0xe2, +0x1c, 0x50, 0xa5, 0xb1, 0x6e, 0x73, 0xd1, 0xc2, +0x76, 0x80, 0xa0, 0xc3, 0x16, 0x77, 0x3e, 0xe2, +0x12, 0x9d, 0xeb, 0xba, 0x98, 0x9c, 0x9c, 0x8c, +0xc4, 0xcc, 0x4c, 0xcf, 0xc2, 0xbc, 0xa2, 0xb5, +0x12, 0xd5, 0x0b, 0xdd, 0xe6, 0xfd, 0x6c, 0x72, +0x70, 0x93, 0xed, 0xa5, 0x64, 0xda, 0x8d, 0x07, +0x3d, 0xc1, 0xe2, 0x49, 0x77, 0x4c, 0x5a, 0x85, +0x72, 0xb9, 0x7d, 0x37, 0x37, 0xd1, 0x97, 0x33, +0x14, 0x79, 0xf9, 0x08, 0x0f, 0xab, 0x22, 0x15, +0x31, 0x77, 0x96, 0xe3, 0xb4, 0xe1, 0x07, 0x25, +0x39, 0x46, 0x2d, 0x3c, 0x8e, 0xf7, 0xa9, 0xa9, +0xf9, 0x39, 0x5d, 0x64, 0xe1, 0xce, 0x81, 0x26, +0xd5, 0x78, 0x94, 0x43, 0x8d, 0x76, 0x80, 0xb3, +0x99, 0x85, 0xa2, 0x44, 0x07, 0x68, 0x73, 0xcb, +0xeb, 0x92, 0xa6, 0x44, 0xc6, 0xb0, 0xf3, 0xc2, +0x9f, 0x0f, 0x0d, 0x0d, 0xe1, 0xc0, 0x81, 0x03, +0x7e, 0x02, 0xa5, 0x58, 0xaa, 0x7d, 0x18, 0x68, +0xd5, 0xda, 0x99, 0xe0, 0xf6, 0x26, 0xeb, 0xf8, +0xe1, 0x09, 0xaf, 0xed, 0x0c, 0xa7, 0x39, 0xfc, +0x68, 0x8c, 0x48, 0x93, 0x72, 0x4c, 0x92, 0x93, +0x49, 0x92, 0xd0, 0xe0, 0x4a, 0x26, 0xc8, 0x71, +0xe1, 0x85, 0x7d, 0x97, 0x1b, 0x0a, 0xdf, 0x70, +0xd7, 0x5f, 0x18, 0xa4, 0x18, 0x9b, 0x73, 0x9a, +0xd6, 0x9f, 0x6d, 0xcc, 0x61, 0xcc, 0x5e, 0xeb, +0xcb, 0xc4, 0xe4, 0x6d, 0x34, 0x04, 0x3a, 0x99, +0x1d, 0x7d, 0x37, 0xd1, 0x3f, 0x2a, 0x1e, 0x7c, +0x5e, 0x23, 0xd2, 0x5f, 0x32, 0x0e, 0x35, 0x54, +0x4c, 0x4a, 0xde, 0xb6, 0xf5, 0xc5, 0xc7, 0x66, +0xca, 0x98, 0x66, 0xa3, 0x63, 0xb7, 0xeb, 0x4d, +0xe2, 0x2d, 0xfb, 0x11, 0xeb, 0x8a, 0xbe, 0x07, +0x92, 0xab, 0x10, 0x73, 0xe7, 0x71, 0xee, 0x61, +0x34, 0x96, 0x74, 0x94, 0xdf, 0xa5, 0x67, 0xbf, +0x6d, 0x0c, 0xbc, 0x74, 0x3b, 0x7f, 0x12, 0xbe, +0x82, 0x9f, 0x1c, 0x2b, 0x80, 0xa0, 0xc4, 0x6e, +0x08, 0x07, 0x4d, 0xec, 0xbd, 0xed, 0xb5, 0x77, +0x8f, 0x35, 0xda, 0x8e, 0x42, 0xd9, 0xbe, 0xb4, +0xef, 0x38, 0xc4, 0x9d, 0x77, 0x78, 0xee, 0x6c, +0xda, 0x8c, 0x29, 0x8f, 0x38, 0x6d, 0x7e, 0xfc, +0xda, 0x4b, 0x72, 0xca, 0xa2, 0xdc, 0xdc, 0xd2, +0xa9, 0x49, 0x73, 0x78, 0xd2, 0x1c, 0x9c, 0x78, +0x9e, 0x72, 0xe9, 0x04, 0xc5, 0xf3, 0x7b, 0x4b, +0xc7, 0x2e, 0xad, 0x50, 0x1d, 0xe9, 0xa0, 0x45, +0x7d, 0xd3, 0x7f, 0xee, 0x10, 0x06, 0x74, 0xe6, +0x72, 0xa7, 0xf1, 0x13, 0x1c, 0xca, 0xc9, 0x4d, +0xb0, 0xe5, 0xb5, 0x9a, 0x12, 0x2f, 0x82, 0x41, +0xce, 0x6e, 0x92, 0x89, 0x39, 0x8e, 0x83, 0x4c, +0x26, 0x83, 0x58, 0x2c, 0xe6, 0x5f, 0xc5, 0x5a, +0x2e, 0x97, 0xfd, 0x6b, 0x3f, 0xe9, 0x0a, 0xda, +0xe5, 0xe5, 0x65, 0xbf, 0x3f, 0xaa, 0x53, 0xaf, +0xd7, 0xd1, 0x6a, 0xb5, 0x70, 0xfe, 0xfc, 0x79, +0x14, 0x8b, 0x45, 0x8c, 0x8c, 0x8c, 0x60, 0x65, +0x65, 0xc5, 0x57, 0x03, 0xf3, 0xb1, 0x73, 0xe7, +0x41, 0x39, 0x3e, 0x72, 0xea, 0xe3, 0x73, 0x0f, +0xc0, 0xcf, 0xb9, 0xee, 0x38, 0x8e, 0xaf, 0x25, +0xd0, 0x68, 0x24, 0x1d, 0x06, 0x09, 0x16, 0x2f, +0x92, 0x99, 0x4a, 0xc7, 0x36, 0x5e, 0x47, 0xd2, +0x4f, 0xbb, 0x0a, 0x57, 0xce, 0xa1, 0xb6, 0x3e, +0xe8, 0x3f, 0x77, 0x52, 0x93, 0xf7, 0x01, 0x48, +0x07, 0x41, 0xc2, 0x4f, 0x5e, 0x2b, 0x4b, 0x6d, +0xf9, 0x0d, 0x82, 0xfd, 0xfd, 0xfd, 0x3e, 0x6c, +0xc7, 0x71, 0x70, 0xfa, 0xf4, 0x69, 0x2c, 0xae, +0xc5, 0xe2, 0xd3, 0xc1, 0xab, 0x59, 0x2a, 0x62, +0x87, 0x0b, 0x34, 0xe2, 0x49, 0x9c, 0xac, 0x25, +0x50, 0x6d, 0xc5, 0x3a, 0x1d, 0x6d, 0xf8, 0x67, +0x20, 0xf8, 0x9c, 0xbe, 0x53, 0x31, 0x39, 0x70, +0x35, 0x9b, 0xc1, 0xf7, 0xb5, 0xda, 0xba, 0x53, +0x0e, 0xff, 0x2c, 0x9c, 0x80, 0x02, 0xb9, 0xa8, +0xf9, 0xbb, 0x78, 0x62, 0xdd, 0xc1, 0x8c, 0xf0, +0xa3, 0x3e, 0xd7, 0x1c, 0xb1, 0x9c, 0xea, 0x6a, +0xdb, 0x39, 0xc9, 0x49, 0x76, 0xb6, 0x6b, 0xc1, +0xec, 0x54, 0x44, 0x70, 0xa4, 0x93, 0x10, 0x77, +0x38, 0xe2, 0x7d, 0x2a, 0x34, 0x6a, 0xe7, 0xf7, +0xf6, 0xfc, 0xe7, 0xfe, 0x77, 0x4e, 0x27, 0xee, +0x40, 0x27, 0xc7, 0x1c, 0xb3, 0xe4, 0x7e, 0xe7, +0x30, 0x69, 0xfc, 0xd2, 0x99, 0xcb, 0x84, 0x1f, +0xd1, 0x51, 0xab, 0xef, 0x24, 0xcd, 0x4e, 0x58, +0xa6, 0xcf, 0xa6, 0x2b, 0x49, 0x65, 0x1d, 0xea, +0x83, 0xe7, 0x96, 0x57, 0xe6, 0x34, 0x58, 0x5a, +0xe6, 0x1c, 0xf8, 0x1c, 0x96, 0xbc, 0x76, 0x57, +0x8e, 0x85, 0x68, 0x2d, 0x1d, 0xc6, 0x38, 0xbe, +0x1c, 0xa6, 0x56, 0x8f, 0xd3, 0x0f, 0xed, 0xfc, +0xec, 0xb4, 0x36, 0xd5, 0xab, 0x6d, 0x39, 0xce, +0xc0, 0x3a, 0x2c, 0x89, 0xbf, 0x74, 0x96, 0xf3, +0x9d, 0xf4, 0xc4, 0xd5, 0xa7, 0xa6, 0x9c, 0xfc, +0xd4, 0x1f, 0x87, 0x25, 0x7f, 0x77, 0xb2, 0x1f, +0x93, 0x46, 0xcd, 0xb0, 0x7e, 0xf8, 0x6f, 0x8c, +0xc6, 0x1a, 0x6f, 0xd4, 0xfc, 0xe7, 0xcd, 0xa4, +0x17, 0xbc, 0x13, 0x61, 0xad, 0xbd, 0x13, 0x6b, +0x04, 0x37, 0xf5, 0x58, 0x32, 0x05, 0x20, 0x28, +0xd9, 0x90, 0x04, 0xc9, 0x93, 0x8a, 0xd0, 0x33, +0xae, 0x5a, 0xa4, 0x8d, 0x8f, 0x42, 0xa5, 0xc8, +0x01, 0x8b, 0xbf, 0xa3, 0xcf, 0x61, 0xd2, 0x9c, +0x56, 0x57, 0x3e, 0x0b, 0x0b, 0x25, 0xe3, 0x45, +0xab, 0x6f, 0x72, 0x4e, 0x93, 0x75, 0x6c, 0x0e, +0x6d, 0xb2, 0x0f, 0x09, 0x4f, 0x83, 0x6f, 0xd2, +0x3e, 0x50, 0xfd, 0xe5, 0xe5, 0x65, 0x0c, 0x0e, +0x0e, 0xfa, 0x1e, 0xd4, 0x9e, 0xe7, 0x75, 0xf8, +0x25, 0x50, 0xe1, 0x73, 0x42, 0x6d, 0xa9, 0x8d, +0xed, 0xe6, 0x3a, 0x5b, 0xd8, 0x16, 0x97, 0xdc, +0x4d, 0xea, 0x77, 0xf9, 0x5e, 0xf6, 0x67, 0xa3, +0x95, 0xd6, 0xb7, 0xfc, 0x6f, 0x5a, 0x0b, 0xfc, +0x10, 0x21, 0x69, 0x28, 0x6f, 0xfc, 0xe3, 0x38, +0xcb, 0xb6, 0x9a, 0xbd, 0x9d, 0x6b, 0x0d, 0xb8, +0xd3, 0xa0, 0xcc, 0x04, 0xc7, 0x69, 0xcc, 0x1d, +0xe1, 0x34, 0x3a, 0xd0, 0x7b, 0xa9, 0xc9, 0xf8, +0xe1, 0x41, 0x07, 0xe7, 0x12, 0x29, 0x3c, 0xf0, +0xc2, 0x4a, 0xbb, 0xa1, 0xa6, 0x12, 0xe4, 0x45, +0xaa, 0x38, 0x6d, 0xd2, 0xb5, 0x84, 0x27, 0x25, +0x30, 0x2d, 0xb4, 0x6a, 0x0d, 0x86, 0x31, 0x79, +0x8b, 0xf6, 0x4e, 0x6c, 0x52, 0x9a, 0xea, 0xaf, +0xe3, 0x39, 0xeb, 0xd3, 0x97, 0xb0, 0xa2, 0xa8, +0xc2, 0x4d, 0x92, 0x8f, 0x01, 0x37, 0x15, 0x17, +0xae, 0xca, 0x8d, 0xa0, 0x9e, 0x0e, 0xa8, 0x82, +0x79, 0xbd, 0x28, 0xa6, 0x0f, 0x93, 0xd6, 0x83, +0xcf, 0x25, 0x6b, 0x1b, 0x50, 0x25, 0xd7, 0x6b, +0x70, 0x9a, 0xb5, 0xa0, 0x9a, 0x39, 0x9e, 0xec, +0x50, 0xab, 0x4b, 0xfc, 0xd4, 0x3e, 0xb4, 0xe7, +0xfc, 0x7b, 0xa3, 0xb1, 0xee, 0xa8, 0xa6, 0xe1, +0x19, 0xb6, 0xb6, 0xc2, 0xe8, 0xa1, 0x8d, 0x4f, +0xf3, 0x01, 0x09, 0x33, 0x2d, 0x39, 0x49, 0xd4, +0x11, 0x91, 0xee, 0x62, 0x8e, 0x3b, 0xd4, 0xf4, +0x9c, 0xbe, 0x52, 0xcb, 0x62, 0x98, 0x9f, 0xc8, +0xeb, 0xd1, 0x86, 0x93, 0xb6, 0x36, 0x24, 0x8c, +0x0d, 0xac, 0xef, 0xc4, 0x15, 0xb7, 0xbf, 0xee, +0xee, 0xd1, 0xd6, 0xea, 0xba, 0xd4, 0x15, 0x8f, +0x05, 0x24, 0x34, 0x2e, 0xe5, 0x2c, 0x2e, 0x2e, +0x06, 0xbc, 0xa7, 0xb3, 0xd9, 0x2c, 0x8a, 0xc5, +0x62, 0x47, 0x08, 0x50, 0xa3, 0xd1, 0x40, 0xa5, +0x52, 0x41, 0x36, 0x9b, 0x45, 0x36, 0x9b, 0xc5, +0xe2, 0xe2, 0xa2, 0x7a, 0xb3, 0x18, 0x60, 0xce, +0xdd, 0xae, 0xdd, 0x0c, 0xc6, 0xa5, 0x7f, 0x29, +0x59, 0x4a, 0x89, 0x4e, 0x0b, 0x5b, 0x93, 0x5a, +0x02, 0x09, 0x4b, 0x6a, 0x09, 0xb4, 0x30, 0x35, +0x09, 0x57, 0x86, 0x9f, 0x11, 0x1c, 0x2d, 0x7c, +0x8e, 0xea, 0x11, 0x5d, 0x78, 0x48, 0x9a, 0x0c, +0x77, 0x23, 0x1a, 0x72, 0xe6, 0x43, 0xe1, 0x5f, +0xfc, 0x56, 0x33, 0xfa, 0x4e, 0x73, 0x20, 0xb5, +0x17, 0xe5, 0x72, 0xf0, 0xd6, 0x30, 0x49, 0x37, +0x82, 0x4f, 0x9a, 0x16, 0x59, 0x8f, 0x4b, 0xb5, +0x5c, 0xfa, 0xe5, 0x34, 0x96, 0xaa, 0x69, 0x4e, +0x3b, 0x5e, 0xb4, 0x35, 0x25, 0x25, 0x6d, 0xbe, +0x06, 0x46, 0x46, 0x46, 0x02, 0xf3, 0x2f, 0xd7, +0x8f, 0x0c, 0x37, 0xa4, 0x31, 0x90, 0x66, 0xc9, +0xb4, 0x2e, 0x4c, 0xb7, 0xf5, 0xc9, 0x10, 0x46, +0x92, 0xb0, 0x63, 0xb1, 0x98, 0x7f, 0xdb, 0x1c, +0xdd, 0x18, 0x97, 0xcd, 0x66, 0x31, 0x38, 0x38, +0x88, 0x7a, 0xbd, 0x8e, 0xfe, 0xfe, 0x7e, 0x7f, +0x0e, 0x29, 0x2b, 0xdc, 0xd0, 0xd0, 0x10, 0x76, +0xee, 0xdc, 0xe9, 0xcf, 0x33, 0xfd, 0x3e, 0xe8, +0x6f, 0xc0, 0x4d, 0xe2, 0x65, 0xb9, 0x24, 0x1a, +0xf1, 0x04, 0x1e, 0x2f, 0xb2, 0x1f, 0xa5, 0x94, +0xe0, 0xe4, 0xc9, 0x5d, 0x4a, 0xb5, 0x9a, 0xe4, +0xaa, 0xd5, 0x95, 0x85, 0x87, 0x0d, 0x99, 0x6c, +0xc8, 0x26, 0xc9, 0x4a, 0x93, 0x38, 0x03, 0x3f, +0xb4, 0x75, 0x7b, 0xae, 0x94, 0xa2, 0xb8, 0xe4, +0x1f, 0xd0, 0x00, 0xf0, 0x3e, 0xb4, 0x50, 0x1d, +0x29, 0x65, 0x6a, 0xd2, 0xa5, 0x82, 0xab, 0x94, +0xd8, 0xa9, 0xa8, 0x37, 0x71, 0x69, 0xf8, 0x49, +0x5a, 0x4a, 0x3a, 0x73, 0x7c, 0xa4, 0x84, 0x2c, +0xe9, 0x63, 0xba, 0xc5, 0xab, 0xce, 0x42, 0x8e, +0xd6, 0x60, 0x70, 0xad, 0x82, 0x1f, 0x6e, 0x57, +0xaf, 0x05, 0x34, 0x08, 0xaa, 0x96, 0x84, 0x24, +0x64, 0x29, 0x3d, 0x13, 0xed, 0xe4, 0xfa, 0x71, +0x9c, 0x4e, 0xba, 0x71, 0x3c, 0xb5, 0x10, 0x4a, +0x93, 0x54, 0x2a, 0xe7, 0x8d, 0x4b, 0x9b, 0x2d, +0x74, 0xd6, 0x97, 0xf3, 0xa7, 0x85, 0x7f, 0x49, +0xcd, 0x91, 0x0c, 0x3f, 0x14, 0xff, 0xf9, 0x9a, +0xeb, 0x58, 0x67, 0xac, 0x9f, 0xc0, 0x8d, 0x7c, +0xa4, 0xa9, 0xe2, 0x12, 0x37, 0xef, 0x5b, 0x4a, +0xe2, 0xda, 0x7a, 0xa3, 0x71, 0x29, 0x9a, 0x06, +0x8e, 0xb3, 0x31, 0x7c, 0x52, 0x5b, 0xdf, 0x51, +0x7c, 0x64, 0x58, 0xdd, 0xc4, 0xde, 0x57, 0xbe, +0xf1, 0xee, 0xc9, 0x64, 0x1d, 0x95, 0x46, 0x13, +0xf5, 0x6a, 0x25, 0x10, 0xdf, 0x0d, 0xb4, 0x25, +0x70, 0x19, 0x6b, 0xce, 0xd5, 0xec, 0xe7, 0xce, +0x9d, 0xc3, 0xf2, 0xf2, 0x32, 0xea, 0xf5, 0x3a, +0x16, 0x17, 0x17, 0x03, 0x1b, 0xf3, 0xe0, 0xe0, +0x20, 0x72, 0xb9, 0x1c, 0xce, 0x9f, 0x3f, 0xdf, +0xc1, 0x80, 0xa5, 0x5a, 0x95, 0xc7, 0x30, 0x53, +0x5f, 0x52, 0xb5, 0xae, 0x31, 0x1b, 0xc2, 0x55, +0xdb, 0xa0, 0xa9, 0x70, 0x26, 0x22, 0x0b, 0x3f, +0x20, 0xc8, 0xe7, 0xbc, 0xd8, 0xae, 0x32, 0xa5, +0x4d, 0x5f, 0xb6, 0xe3, 0xa6, 0x0a, 0xae, 0xe2, +0x05, 0xda, 0x8c, 0x8a, 0x98, 0x1e, 0xe1, 0x47, +0x0c, 0x99, 0x36, 0x7f, 0x4e, 0x07, 0x52, 0x93, +0x4b, 0x06, 0x2a, 0x99, 0x2e, 0xef, 0x8b, 0x1f, +0x2e, 0x38, 0x0d, 0x24, 0x7d, 0xcb, 0xe5, 0xf5, +0x18, 0x72, 0x82, 0xc9, 0xaf, 0x42, 0xa5, 0x7e, +0xf9, 0x81, 0x8a, 0xd3, 0x8e, 0x33, 0x7b, 0xed, +0x40, 0xa3, 0x99, 0x4f, 0x78, 0x1c, 0xb6, 0xa4, +0x95, 0x54, 0x65, 0xcb, 0x83, 0x82, 0x69, 0xde, +0x64, 0x5b, 0x93, 0x0f, 0x82, 0x8c, 0x4b, 0x37, +0xad, 0x23, 0xc9, 0xfc, 0x89, 0xe6, 0x3b, 0x76, +0xec, 0xf0, 0x61, 0xa4, 0xd3, 0x69, 0xd4, 0xeb, +0x75, 0xcc, 0xcf, 0xcf, 0x63, 0x71, 0x71, 0x11, +0x23, 0x23, 0x23, 0xd8, 0xb5, 0x6b, 0x57, 0x80, +0x26, 0xdc, 0x14, 0xc3, 0xe9, 0xdf, 0xef, 0xc4, +0x70, 0xfb, 0x48, 0x0a, 0xf9, 0xd5, 0x0a, 0x4e, +0x56, 0x80, 0x6a, 0x2c, 0xd1, 0xb9, 0x09, 0xcb, +0x1f, 0xb1, 0x7c, 0xaf, 0x6d, 0xba, 0x7c, 0xe3, +0xe1, 0x4c, 0x9b, 0x3e, 0x4b, 0xa7, 0x27, 0xba, +0xee, 0xb1, 0xba, 0x1a, 0x50, 0xe7, 0x75, 0xa8, +0xa3, 0xd7, 0x36, 0xa2, 0xc0, 0x86, 0xc4, 0xfa, +0x95, 0x1b, 0x15, 0x6d, 0xe0, 0xfe, 0xf3, 0x66, +0x33, 0xc8, 0xb4, 0x4c, 0x0c, 0x9b, 0x6f, 0x6e, +0x9a, 0x7a, 0x5a, 0xd0, 0xa0, 0x63, 0x83, 0x64, +0x4c, 0x59, 0x9a, 0x0c, 0xd4, 0xcd, 0x94, 0x31, +0xbc, 0x0e, 0xfc, 0xe4, 0x26, 0x2e, 0xe9, 0x6c, +0xc2, 0xd1, 0x86, 0xb3, 0x01, 0xa6, 0x7f, 0xf0, +0x30, 0xc5, 0x55, 0x6b, 0x26, 0x15, 0x4e, 0x3f, +0x8d, 0xa9, 0x9a, 0xf0, 0xb7, 0xd1, 0x5f, 0x53, +0x7d, 0x73, 0x66, 0x63, 0x1a, 0xa3, 0x32, 0x3e, +0x95, 0xf9, 0xca, 0xf5, 0x62, 0x62, 0xf0, 0xca, +0x41, 0x95, 0xe6, 0x33, 0x70, 0x50, 0xd4, 0xe6, +0x5b, 0x1c, 0xde, 0xc8, 0xd4, 0x13, 0x30, 0x23, +0xf9, 0x92, 0xb2, 0x88, 0xe9, 0xb7, 0x99, 0xbc, +0x24, 0x2d, 0x38, 0x1c, 0xc3, 0x3a, 0xe1, 0x07, +0xc7, 0x0e, 0xfc, 0x6d, 0x6b, 0xc5, 0xf0, 0xbb, +0x0a, 0x1c, 0x3a, 0x59, 0xfb, 0x78, 0xac, 0xd1, +0xde, 0x6c, 0x06, 0x33, 0x7d, 0xfe, 0x86, 0xa5, +0x6d, 0x80, 0xb2, 0x90, 0xe4, 0x42, 0xce, 0x59, +0x5a, 0xc8, 0x15, 0x39, 0x06, 0x91, 0x33, 0x9c, +0x29, 0x5c, 0x0b, 0xe8, 0x8c, 0x6f, 0x36, 0x79, +0x29, 0xdb, 0xf0, 0x8a, 0x12, 0x9b, 0xac, 0x8d, +0x23, 0x4a, 0x09, 0x0b, 0x7b, 0x32, 0x85, 0xf4, +0x69, 0x0e, 0x65, 0x26, 0xf5, 0xba, 0xc9, 0xe1, +0x2c, 0x6c, 0x0c, 0xda, 0xbc, 0x48, 0xdc, 0x24, +0xfe, 0xfc, 0x99, 0x16, 0x3b, 0x2e, 0x71, 0xb2, +0x39, 0x1d, 0x6a, 0xe6, 0x89, 0x30, 0x4f, 0x7d, +0x9b, 0x83, 0x9a, 0x86, 0x87, 0xcd, 0x23, 0x5d, +0xc3, 0x57, 0x9b, 0x07, 0xfa, 0x2f, 0x6f, 0xf4, +0x33, 0xd1, 0x4f, 0x5b, 0x47, 0x32, 0x9e, 0x7f, +0x66, 0x66, 0xc6, 0x4f, 0x69, 0x3c, 0x36, 0x36, +0xa6, 0x9a, 0x37, 0x48, 0x93, 0xc5, 0xff, 0x78, +0xf9, 0x97, 0x7b, 0xb3, 0xb8, 0x7d, 0x30, 0xa6, +0x9f, 0xc4, 0x01, 0xbb, 0x03, 0x0e, 0xd5, 0x33, +0xa9, 0x2c, 0x39, 0xd3, 0x4e, 0x24, 0x82, 0xcf, +0xd6, 0xea, 0x50, 0xdc, 0x6e, 0xc0, 0xa1, 0x8d, +0xc7, 0xf2, 0x0a, 0x35, 0xb8, 0xea, 0xbc, 0xa4, +0xd5, 0x35, 0xa9, 0xd9, 0x4d, 0x4e, 0x70, 0x52, +0x5d, 0x69, 0xf2, 0x38, 0x17, 0xcf, 0xeb, 0x71, +0xc5, 0x2b, 0x58, 0x3e, 0x33, 0xd1, 0xcd, 0x34, +0x06, 0xcd, 0x3b, 0xdf, 0x86, 0x8b, 0x34, 0x15, +0xd8, 0x9c, 0xfb, 0x0c, 0x5e, 0xd0, 0x81, 0x30, +0xa4, 0xb5, 0xf8, 0xe2, 0x80, 0xc7, 0xb7, 0xc4, +0x2f, 0xcc, 0xb4, 0x12, 0xa6, 0x3a, 0xd7, 0xe8, +0x2f, 0xd5, 0xc0, 0x36, 0xc7, 0x40, 0x39, 0x2e, +0xc5, 0xd1, 0x2e, 0xe0, 0xa0, 0x27, 0x1c, 0xf3, +0x02, 0xb9, 0xf2, 0xa5, 0x33, 0xa1, 0x02, 0x9b, +0x5f, 0x94, 0xe3, 0xcf, 0xaf, 0xc9, 0x04, 0x24, +0xe0, 0x11, 0x1d, 0x23, 0xdd, 0x01, 0xa0, 0xfd, +0xde, 0x38, 0xfe, 0x12, 0x5f, 0x1b, 0xdd, 0x05, +0xfe, 0x81, 0x08, 0x10, 0x0d, 0x0f, 0x85, 0xce, +0xda, 0x5a, 0x96, 0xf7, 0x0c, 0x38, 0xd5, 0xd5, +0xb6, 0x9a, 0x3d, 0xb3, 0x72, 0xd6, 0xa8, 0x9a, +0xce, 0xe5, 0x72, 0xbe, 0x94, 0xc8, 0x37, 0xbf, +0x5c, 0x2e, 0xe7, 0x4b, 0xe6, 0x8d, 0x46, 0x23, +0xb0, 0xf1, 0x71, 0x89, 0xcd, 0x75, 0x5d, 0x24, +0x93, 0x49, 0x5f, 0x42, 0xe1, 0x6a, 0x4c, 0x00, +0x1d, 0x12, 0x35, 0x15, 0xfe, 0x9e, 0xb7, 0xe1, +0x12, 0x32, 0x6f, 0x17, 0x66, 0x7b, 0x27, 0xbc, +0x64, 0xe1, 0xaa, 0x74, 0xf9, 0xdc, 0xe4, 0xb8, +0xa7, 0x49, 0x91, 0x52, 0x6b, 0xc0, 0xd5, 0xd7, +0xb2, 0x90, 0x66, 0x43, 0x8e, 0x83, 0xda, 0xd1, +0x66, 0xcf, 0xa5, 0x4f, 0x4d, 0xdb, 0x40, 0xaa, +0x5b, 0xc2, 0x87, 0xb4, 0x28, 0x34, 0x97, 0xc4, +0xb4, 0xb8, 0xe3, 0x9f, 0x94, 0x44, 0xa5, 0xea, +0x9b, 0xa4, 0x49, 0x29, 0xf9, 0xcb, 0x79, 0xd3, +0x1c, 0x1b, 0xa9, 0x2f, 0xee, 0x44, 0x67, 0xa2, +0x3b, 0x3d, 0x27, 0x1c, 0xe4, 0xdc, 0x9b, 0x68, +0x2f, 0xe7, 0x9a, 0xaf, 0x5b, 0x69, 0x1a, 0xe1, +0xeb, 0x41, 0xcb, 0x3e, 0x28, 0x69, 0x4a, 0x36, +0x75, 0xde, 0x87, 0x74, 0x68, 0xac, 0xd7, 0xeb, +0x88, 0xc5, 0x62, 0x7e, 0x96, 0x3c, 0xc7, 0x71, +0x30, 0x32, 0x32, 0xe2, 0xaf, 0x73, 0xa9, 0x6d, +0x91, 0x9a, 0x9c, 0xd3, 0xa7, 0x4f, 0xfb, 0xce, +0x70, 0x85, 0x42, 0x01, 0xf9, 0x8b, 0x2b, 0xd8, +0xd2, 0xe7, 0x62, 0x6f, 0x26, 0x81, 0x99, 0xd5, +0x16, 0xce, 0x96, 0xea, 0xba, 0xc4, 0xa3, 0x49, +0xe4, 0x52, 0x42, 0xb0, 0x49, 0x54, 0x9a, 0xa4, +0xae, 0x48, 0x0e, 0xd2, 0xf1, 0xa6, 0xa3, 0x9e, +0x26, 0x89, 0xf3, 0x36, 0x52, 0xd5, 0xcf, 0x3f, +0x6b, 0x92, 0x17, 0x7d, 0xb7, 0x8d, 0xb3, 0x1b, +0x78, 0x42, 0x32, 0x55, 0x71, 0xa4, 0xd2, 0x6c, +0x06, 0x25, 0x35, 0x03, 0xbc, 0x0e, 0x07, 0x3e, +0x89, 0x8f, 0x4d, 0x22, 0x97, 0x92, 0xb2, 0x82, +0x3f, 0x87, 0x4f, 0xf8, 0x6a, 0xaa, 0x61, 0xf9, +0x39, 0xa0, 0x29, 0xe1, 0x6a, 0x6c, 0xdb, 0xfa, +0x89, 0xb2, 0x4e, 0xf8, 0xbc, 0xd8, 0xc6, 0xab, +0xad, 0x2f, 0xa5, 0xbf, 0x80, 0xc6, 0x41, 0x33, +0x9b, 0xd8, 0xe8, 0xc6, 0x3e, 0x07, 0xe6, 0x29, +0x4c, 0xab, 0xa3, 0x69, 0x32, 0x34, 0xc9, 0x97, +0x4b, 0xd5, 0x72, 0x6e, 0x4c, 0x66, 0x2f, 0x13, +0x7c, 0xae, 0xb9, 0x50, 0x68, 0xd3, 0xa1, 0x39, +0xb0, 0x39, 0xd9, 0x69, 0x26, 0x25, 0x45, 0x5b, +0xc5, 0xd7, 0x4b, 0xe2, 0x86, 0xb7, 0x7c, 0xdf, +0xdd, 0xb9, 0xd5, 0xf3, 0xc8, 0x66, 0xb3, 0xfe, +0x86, 0xcf, 0x19, 0x99, 0xf4, 0x16, 0xa7, 0xcd, +0x32, 0x97, 0xcb, 0x61, 0x64, 0x64, 0x04, 0x8b, +0x8b, 0x8b, 0x28, 0x16, 0x8b, 0x81, 0xcd, 0x9d, +0x98, 0x55, 0xb9, 0x5c, 0xc6, 0xd0, 0xd0, 0x90, +0xbf, 0xa9, 0x92, 0xba, 0x56, 0x53, 0xd5, 0x9a, +0x42, 0xd1, 0x34, 0xb5, 0x2b, 0x7f, 0x47, 0x38, +0xc9, 0xf6, 0x26, 0x95, 0xba, 0xb4, 0xf5, 0x52, +0x91, 0x76, 0x6e, 0x8d, 0x51, 0x69, 0xb8, 0x4a, +0x7a, 0x11, 0x6d, 0x38, 0x7e, 0xd2, 0x54, 0xc1, +0x43, 0xb5, 0xb8, 0x7a, 0x9a, 0xe8, 0x2f, 0x0f, +0x06, 0x9c, 0xa9, 0x70, 0x95, 0x38, 0x15, 0x69, +0x1a, 0xe1, 0xb0, 0x38, 0x83, 0x96, 0xb8, 0x6a, +0xd1, 0x01, 0x12, 0x46, 0x98, 0x2a, 0x5b, 0x1e, +0x68, 0xa4, 0xff, 0x81, 0x66, 0xc2, 0xe0, 0x26, +0x1b, 0xcd, 0x93, 0x5c, 0x46, 0x50, 0xf0, 0x7a, +0xfc, 0x90, 0xc7, 0x7d, 0x0e, 0xa4, 0x4a, 0x9c, +0xdb, 0xbc, 0xb5, 0xc3, 0x1f, 0x1f, 0x2b, 0xd5, +0xe3, 0x66, 0x0c, 0x3e, 0x3e, 0x6e, 0x22, 0xe1, +0xf3, 0x40, 0xeb, 0x9c, 0x62, 0xd1, 0x8b, 0xc5, +0x22, 0x6a, 0xb5, 0x1a, 0xb6, 0x6e, 0xdd, 0x1a, +0xa8, 0x4b, 0xcc, 0x9b, 0x18, 0xff, 0xc8, 0xc8, +0x88, 0xef, 0x3c, 0xd7, 0xd7, 0xd7, 0x07, 0xaf, +0xaf, 0x0f, 0xe3, 0x7d, 0x49, 0x1c, 0x48, 0xb7, +0xf0, 0x48, 0x29, 0x89, 0xa5, 0x52, 0x45, 0xdf, +0x70, 0x80, 0xce, 0x4d, 0xd9, 0xe9, 0x64, 0xba, +0x1d, 0x8c, 0x9e, 0x6f, 0x72, 0x29, 0x57, 0x57, +0x6b, 0x5a, 0xd4, 0x89, 0x3e, 0xc3, 0x13, 0xef, +0x7d, 0x26, 0x69, 0x91, 0x6c, 0x35, 0x9b, 0x35, +0x57, 0xbb, 0x07, 0xc6, 0xa5, 0x7d, 0x67, 0xe3, +0xf7, 0xcd, 0x00, 0x26, 0x78, 0x8a, 0xea, 0xdd, +0x84, 0x23, 0xe1, 0xd5, 0x61, 0x56, 0x90, 0xf0, +0x68, 0x9c, 0x52, 0x95, 0x2c, 0xe9, 0x2c, 0x37, +0x7a, 0x49, 0x57, 0xa2, 0x0b, 0x31, 0x3a, 0xae, +0x86, 0x4d, 0xac, 0xcf, 0x51, 0x87, 0xa7, 0x36, +0xa7, 0xbf, 0xc1, 0xa6, 0x1f, 0x50, 0xcd, 0x4b, +0x3c, 0xa5, 0x0d, 0xd6, 0x64, 0xd7, 0x96, 0xcc, +0x43, 0xae, 0x03, 0xd3, 0x78, 0x34, 0xb5, 0x3b, +0x5f, 0x8b, 0x40, 0xe7, 0xc1, 0x44, 0x32, 0x50, +0xe9, 0x5b, 0xc0, 0xbf, 0x4b, 0xf3, 0x88, 0xc9, +0x37, 0x44, 0x44, 0x50, 0x58, 0x7d, 0x1b, 0x6c, +0xeb, 0x9d, 0xe3, 0x2e, 0xcd, 0x18, 0xfe, 0x80, +0x3a, 0xd3, 0x0a, 0x77, 0xd0, 0x81, 0xfb, 0x2f, +0x70, 0xfc, 0xf9, 0x6f, 0x55, 0x3b, 0xd4, 0x2a, +0xbf, 0xeb, 0x8e, 0xdf, 0x0b, 0xeb, 0x87, 0xc3, +0x8c, 0x27, 0x52, 0x29, 0x78, 0x9e, 0xe7, 0xa7, +0x0d, 0x95, 0x8c, 0x51, 0x53, 0xf3, 0x6a, 0xaa, +0x57, 0xa9, 0xbe, 0xa5, 0x76, 0x94, 0x54, 0x83, +0x7b, 0xfe, 0x6a, 0x6d, 0x6d, 0xea, 0x6b, 0xad, +0x9e, 0x54, 0xc1, 0x6a, 0x6d, 0x79, 0xd1, 0x54, +0xd9, 0x26, 0xe7, 0x3b, 0x0d, 0x8e, 0x8c, 0xa7, +0x96, 0x6a, 0x60, 0x59, 0x8f, 0x18, 0xb6, 0xf4, +0x94, 0x96, 0x45, 0xc6, 0x5f, 0xcb, 0xbe, 0x4c, +0xf1, 0xcf, 0x72, 0x2c, 0x72, 0x5e, 0xe4, 0x5c, +0x9a, 0xcc, 0x1c, 0x1a, 0x4d, 0x6d, 0x51, 0x02, +0x26, 0x3b, 0xb4, 0x36, 0x57, 0x36, 0x5a, 0xca, +0xb1, 0xc8, 0xcc, 0x6a, 0x26, 0x1c, 0x6c, 0xea, +0x7e, 0xad, 0x3f, 0x4e, 0x0b, 0xd3, 0xdc, 0x03, +0x66, 0x33, 0x0f, 0xe1, 0x46, 0x1e, 0xed, 0xf4, +0x7c, 0x74, 0x74, 0xd4, 0xf7, 0x09, 0xa1, 0xf0, +0x34, 0xca, 0xe7, 0x5e, 0x2e, 0x97, 0x71, 0xe2, +0xc4, 0x09, 0xcc, 0xcc, 0xcc, 0xf8, 0x9a, 0x96, +0xc9, 0xc9, 0x49, 0x00, 0xf0, 0xc3, 0xd4, 0xe8, +0x37, 0xd2, 0xac, 0xd7, 0xf0, 0xc2, 0xf3, 0x27, +0x91, 0xcf, 0xe7, 0x71, 0xe5, 0xa0, 0x8b, 0x1f, +0xdb, 0x56, 0x43, 0x26, 0x0e, 0xbb, 0xa7, 0xab, +0x49, 0x05, 0x48, 0x9f, 0xe9, 0x9d, 0x49, 0x55, +0x6c, 0xf3, 0x72, 0x06, 0x82, 0x71, 0xac, 0x26, +0x2f, 0x76, 0x5b, 0x3b, 0x27, 0x69, 0x55, 0x27, +0xfa, 0x6a, 0x43, 0x93, 0x07, 0xb1, 0x01, 0x7f, +0x19, 0x7f, 0xdc, 0x01, 0x0f, 0x41, 0x93, 0x41, +0xc7, 0x78, 0xa5, 0xda, 0x35, 0x0c, 0x3f, 0x1a, +0x93, 0xa6, 0x8e, 0xe7, 0xb8, 0x69, 0x26, 0x0e, +0x93, 0x9a, 0x5d, 0xb6, 0xd1, 0xe6, 0x52, 0xd4, +0xe5, 0x5e, 0xe0, 0x1d, 0x71, 0xe5, 0xa6, 0x79, +0xd3, 0x70, 0xe1, 0x78, 0x6a, 0xaa, 0x65, 0xf9, +0xdc, 0x64, 0x02, 0xa1, 0x77, 0x51, 0x62, 0xbc, +0x4d, 0x74, 0xd4, 0xd4, 0xfb, 0xda, 0x5a, 0x30, +0x99, 0x6a, 0xe4, 0x38, 0xc5, 0xf8, 0x03, 0x66, +0x22, 0x27, 0x78, 0x55, 0x6f, 0x20, 0x45, 0x2a, +0xc7, 0xd9, 0xe4, 0x79, 0x2e, 0xc7, 0x65, 0x9a, +0x73, 0x8d, 0x4e, 0x12, 0x7f, 0x49, 0x1b, 0x53, +0xbf, 0xac, 0x4e, 0xe0, 0xf7, 0x62, 0xa8, 0x03, +0x00, 0x0e, 0xb0, 0x6e, 0xdf, 0xa6, 0xcf, 0xbc, +0xd8, 0x42, 0xc8, 0x4c, 0x36, 0x49, 0xf9, 0x0c, +0x40, 0x20, 0xbc, 0x4d, 0x26, 0x2c, 0x09, 0x83, +0x6b, 0x62, 0x5a, 0xb2, 0x98, 0xec, 0x9c, 0xa6, +0x7e, 0x08, 0x2f, 0x13, 0xe3, 0x30, 0x85, 0x4a, +0x69, 0x21, 0x52, 0xb6, 0x70, 0x39, 0xcd, 0x8e, +0x6b, 0x4a, 0x5a, 0x62, 0x2a, 0xf2, 0x50, 0x60, +0xca, 0x85, 0x6e, 0xb3, 0x55, 0x9b, 0xc2, 0xc6, +0xc2, 0xe8, 0x26, 0x9f, 0x6b, 0x36, 0x7f, 0xd3, +0xf8, 0x6d, 0x7d, 0x46, 0xf5, 0x57, 0xd0, 0xc6, +0x29, 0xfb, 0xd6, 0xe6, 0xd8, 0x34, 0x77, 0x36, +0x9c, 0x4c, 0x7d, 0x51, 0x68, 0x20, 0x1d, 0xd4, +0xe8, 0x8a, 0x59, 0xca, 0xba, 0xc7, 0x6f, 0x57, +0x9b, 0x9d, 0x9d, 0x45, 0x2e, 0x97, 0xc3, 0xd4, +0xd4, 0x94, 0xff, 0x6c, 0x66, 0x66, 0x46, 0x3d, +0x98, 0x11, 0x93, 0x07, 0x80, 0x66, 0xb5, 0x82, +0x1b, 0x46, 0x32, 0x78, 0x45, 0x7e, 0x15, 0xf7, +0x9d, 0xd3, 0xed, 0x67, 0x81, 0x12, 0xc6, 0x08, +0xe4, 0x7b, 0xcd, 0xae, 0xa9, 0xd8, 0x54, 0x8d, +0xf7, 0x48, 0x9b, 0xbc, 0x69, 0x15, 0xbb, 0x61, +0xa8, 0x4d, 0x50, 0x6e, 0x62, 0xb6, 0x31, 0x6a, +0x9b, 0x18, 0x85, 0x69, 0xc5, 0x83, 0x30, 0x02, +0xf6, 0x45, 0xd3, 0xe1, 0x47, 0x83, 0xcd, 0xfa, +0x70, 0x9a, 0x35, 0x3f, 0x0c, 0xca, 0x87, 0x6f, +0xb3, 0x1d, 0x9b, 0x36, 0x63, 0xad, 0x4f, 0x0b, +0xcd, 0x22, 0xcd, 0x91, 0x64, 0x84, 0xec, 0xb9, +0x1a, 0xe6, 0xa7, 0x31, 0xce, 0x10, 0x6d, 0x8a, +0xba, 0x5e, 0x64, 0xff, 0x8a, 0x4d, 0x58, 0x65, +0x72, 0x7c, 0x5e, 0xa2, 0xac, 0x1d, 0x6d, 0x9d, +0x98, 0xe8, 0xe8, 0x24, 0x3b, 0xc3, 0xce, 0x78, +0x7f, 0xf2, 0x30, 0xc0, 0x0f, 0x72, 0xda, 0x6f, +0x43, 0xe2, 0x63, 0x1b, 0xa7, 0xa4, 0xad, 0xf4, +0x33, 0x08, 0x1b, 0x93, 0x76, 0xd0, 0x96, 0xed, +0x6d, 0xbe, 0x12, 0xda, 0x61, 0xae, 0x51, 0x6d, +0x67, 0xa6, 0xd2, 0x36, 0x63, 0x62, 0x1a, 0x1a, +0x23, 0x8a, 0xc2, 0x34, 0x64, 0xb6, 0x30, 0x59, +0x37, 0x8a, 0x9d, 0x9b, 0x97, 0x30, 0x06, 0xa1, +0x69, 0x0c, 0x4c, 0x0c, 0x59, 0x63, 0x04, 0xb6, +0x3e, 0x4d, 0xdf, 0x35, 0xd8, 0x3c, 0xb3, 0x5b, +0x14, 0xa6, 0xa9, 0xd5, 0x37, 0x49, 0x8c, 0x72, +0x9c, 0xfc, 0x60, 0x61, 0x3b, 0xe0, 0xf0, 0x7a, +0x36, 0x3a, 0xc9, 0x31, 0xc9, 0x39, 0x34, 0x31, +0xee, 0x6e, 0x68, 0x69, 0x6a, 0x2f, 0xfb, 0x89, +0xaa, 0x31, 0x91, 0x12, 0x37, 0x8d, 0x55, 0x5e, +0x78, 0x62, 0x82, 0x2b, 0x9f, 0xc9, 0x34, 0xc2, +0x54, 0x48, 0x3a, 0xe7, 0xb1, 0xfd, 0x74, 0x4d, +0x2a, 0x31, 0xf7, 0x72, 0xb9, 0xec, 0x67, 0x7f, +0x2b, 0x97, 0xcb, 0x98, 0x9b, 0x9b, 0x03, 0x00, +0x9f, 0xe9, 0x93, 0x93, 0x1c, 0x69, 0xa9, 0xf8, +0xdc, 0x03, 0xc0, 0x48, 0x0a, 0x78, 0xdf, 0xbe, +0x3e, 0x3c, 0x53, 0xad, 0xe2, 0xb9, 0xe5, 0xb5, +0x1c, 0x0e, 0x36, 0x47, 0x27, 0x8d, 0x31, 0x1a, +0x1c, 0x69, 0x54, 0x46, 0x6a, 0x63, 0xaa, 0x21, +0x92, 0xb2, 0xc4, 0x47, 0x95, 0x20, 0x34, 0xfc, +0x4d, 0x8e, 0x59, 0x0a, 0x0e, 0x9c, 0xb1, 0xca, +0xf6, 0xa6, 0xb8, 0xf6, 0x8e, 0x62, 0x1a, 0x1b, +0x67, 0x06, 0x8c, 0x0e, 0x81, 0xfe, 0x6c, 0x9b, +0xae, 0x69, 0xac, 0x36, 0x1a, 0xf2, 0x77, 0xda, +0x5c, 0x69, 0x73, 0x2a, 0xeb, 0x18, 0xe8, 0xaf, +0xc5, 0x53, 0x77, 0xf4, 0x6b, 0x3b, 0xc8, 0x99, +0xe6, 0x3c, 0xc2, 0x01, 0x50, 0x2d, 0xda, 0x7b, +0x0d, 0x96, 0x46, 0x03, 0x6d, 0x4e, 0x15, 0x46, +0xdb, 0x91, 0xe2, 0xd4, 0xb4, 0x9e, 0x4d, 0xbf, +0x21, 0xcb, 0x61, 0x51, 0xc5, 0xc1, 0xf4, 0x9b, +0xd0, 0xe8, 0xc0, 0xea, 0xf9, 0xeb, 0x38, 0x8a, +0xa6, 0x2d, 0xea, 0xba, 0x10, 0xfd, 0xc4, 0x63, +0x8d, 0xba, 0x9f, 0xdc, 0xa5, 0x5c, 0x5e, 0x4f, +0x1a, 0x03, 0x74, 0xaa, 0x4f, 0xf9, 0xa6, 0x49, +0x9b, 0x54, 0x3a, 0x9d, 0x36, 0xaa, 0xa0, 0x65, +0x71, 0x5d, 0x37, 0x20, 0xad, 0xf0, 0x0d, 0xb5, +0x56, 0x6f, 0x74, 0xd4, 0xd7, 0x54, 0xc4, 0x92, +0x01, 0x49, 0xcf, 0x60, 0x93, 0x37, 0xb6, 0x84, +0x29, 0x3f, 0x73, 0xd8, 0x61, 0x4c, 0x44, 0xc3, +0x45, 0xd2, 0xc9, 0x74, 0x80, 0x20, 0x7c, 0xc3, +0x3c, 0xc6, 0xe5, 0xed, 0x69, 0x26, 0x15, 0xb0, +0x89, 0x56, 0xdd, 0x1c, 0x92, 0x34, 0xe9, 0x96, +0x7b, 0x61, 0xf3, 0x7a, 0x9a, 0xa6, 0x26, 0x4a, +0xb4, 0x40, 0xd8, 0x1c, 0xd8, 0xcc, 0x1a, 0x26, +0xb8, 0x1a, 0x9d, 0x6d, 0x0c, 0xd9, 0x76, 0xe0, +0xe1, 0xed, 0x4c, 0xf8, 0x2c, 0x2f, 0x2f, 0xfb, +0x12, 0x3a, 0x25, 0x45, 0xa2, 0x68, 0x0e, 0x4a, +0x24, 0x43, 0xa9, 0x73, 0x67, 0x67, 0x67, 0x31, +0x33, 0x33, 0xe3, 0x6b, 0xbc, 0xa6, 0xa6, 0xa6, +0x30, 0x39, 0x39, 0xe9, 0x33, 0x73, 0x4e, 0x5b, +0xba, 0x98, 0x65, 0x66, 0x66, 0x06, 0x8f, 0x7c, +0xed, 0x21, 0x9c, 0x9d, 0xf9, 0x26, 0xbe, 0x27, +0x79, 0x16, 0x5b, 0x63, 0xd5, 0x4e, 0x55, 0xa9, +0x41, 0xc5, 0x6d, 0x94, 0xca, 0x65, 0x3d, 0x53, +0x7d, 0x5e, 0x4c, 0x9b, 0xbf, 0x6c, 0xb7, 0x86, +0x4b, 0xc7, 0xa5, 0x0f, 0xa6, 0xa2, 0xa9, 0xa2, +0x4d, 0xf0, 0x89, 0xb1, 0xf2, 0x74, 0xb1, 0xc4, +0xb4, 0x9a, 0x11, 0xc7, 0x6a, 0x92, 0x6c, 0x58, +0x1b, 0xe9, 0x15, 0xec, 0x37, 0x0d, 0x4b, 0x4f, +0xab, 0xc1, 0xd7, 0xbe, 0x9b, 0x3e, 0xdb, 0x18, +0xa0, 0x49, 0xb2, 0x0b, 0xa1, 0xbf, 0x55, 0x15, +0x6d, 0x83, 0x1f, 0xc6, 0x94, 0x64, 0xbf, 0x5a, +0xb1, 0x98, 0x20, 0x3a, 0xd4, 0xda, 0x5a, 0x1b, +0xa9, 0x76, 0x36, 0xe1, 0xc1, 0xeb, 0xd8, 0xd6, +0xbc, 0xec, 0x4a, 0xce, 0xa7, 0xad, 0xbe, 0xf6, +0x1b, 0xb3, 0x31, 0x5d, 0x09, 0x4b, 0x61, 0xba, +0xea, 0xdc, 0x44, 0x59, 0x1f, 0x36, 0x5c, 0xc5, +0x6f, 0x25, 0x9e, 0x2f, 0x14, 0x03, 0xef, 0x29, +0x87, 0xb4, 0xc9, 0x36, 0x4a, 0x7f, 0x64, 0x1b, +0xa4, 0xe7, 0x9a, 0x14, 0xc4, 0x61, 0xd0, 0xa6, +0x66, 0x52, 0x43, 0x27, 0x9d, 0x84, 0x55, 0xd5, +0x2b, 0x37, 0x6e, 0x8e, 0x8b, 0x4d, 0x3d, 0x6a, +0xb3, 0x3d, 0xcb, 0xff, 0x26, 0x86, 0x62, 0x82, +0xa1, 0xe1, 0xa2, 0x5d, 0x81, 0x69, 0xb3, 0x33, +0x9b, 0xa4, 0x5a, 0xae, 0xb6, 0x0d, 0xb3, 0x61, +0x87, 0x31, 0xee, 0xb0, 0xfe, 0xb5, 0xf1, 0x86, +0xd1, 0xb4, 0x1b, 0x5c, 0x34, 0x8d, 0x44, 0x2f, +0x25, 0x8a, 0x4d, 0x5d, 0x9a, 0x70, 0xb8, 0xe4, +0xcb, 0xfd, 0x18, 0x08, 0x86, 0xc4, 0x59, 0x0b, +0x1d, 0x1b, 0x1c, 0x1c, 0x0c, 0x68, 0x9b, 0x48, +0x1a, 0x07, 0xda, 0x3e, 0x21, 0xd4, 0xe7, 0xe0, +0xe0, 0x20, 0x2a, 0x95, 0x0a, 0x66, 0x67, 0x67, +0xfd, 0x43, 0x81, 0xeb, 0xba, 0xfe, 0x0d, 0x76, +0xf9, 0x7c, 0x1e, 0xc7, 0x8e, 0x1d, 0xf3, 0x3f, +0x13, 0x0e, 0xf9, 0x7c, 0x1e, 0xb3, 0xb3, 0xb3, +0xfe, 0xe5, 0x44, 0xf1, 0x94, 0x8b, 0x5b, 0xfa, +0x6a, 0xf8, 0x91, 0x3d, 0x99, 0x76, 0x0e, 0x77, +0x93, 0x84, 0x44, 0xc5, 0x66, 0x73, 0xb4, 0x49, +0xd9, 0x9a, 0xad, 0x33, 0x8a, 0xea, 0x98, 0x17, +0xa7, 0xd3, 0xa6, 0x1e, 0x60, 0xee, 0x36, 0xdb, +0xa2, 0x0d, 0xbe, 0xd8, 0xbc, 0xd4, 0x4b, 0x26, +0x4c, 0x8c, 0x33, 0xaa, 0xcd, 0x5a, 0xb6, 0x65, +0x34, 0x30, 0x5e, 0x5a, 0x62, 0x32, 0x7d, 0x18, +0xa4, 0x65, 0x2b, 0x8d, 0xb5, 0x77, 0x61, 0x6a, +0xfc, 0x5e, 0xe8, 0xcf, 0xfb, 0x92, 0xcf, 0x6c, +0x07, 0xc5, 0xb0, 0xf5, 0x22, 0xf0, 0x0a, 0xd8, +0xc5, 0x15, 0xff, 0x04, 0xa3, 0x6d, 0x3d, 0x6c, +0x3d, 0xda, 0xec, 0xd1, 0xb6, 0x35, 0xcb, 0x68, +0x6a, 0x64, 0xa6, 0x61, 0xe6, 0x11, 0x1b, 0x4d, +0x6c, 0xeb, 0x96, 0xd5, 0x95, 0x3e, 0x28, 0x1a, +0x7e, 0x1d, 0x7d, 0x99, 0x0e, 0x75, 0x02, 0x07, +0x4e, 0x73, 0x27, 0xd6, 0xa8, 0x77, 0xdc, 0xae, +0x45, 0x9b, 0x1c, 0x6d, 0x52, 0xf9, 0x7c, 0x3e, +0xe0, 0xa0, 0x24, 0x37, 0xbb, 0x30, 0x86, 0x25, +0x37, 0x5e, 0x52, 0x81, 0x52, 0x49, 0xac, 0x21, +0x6c, 0xb3, 0xd7, 0xcb, 0x62, 0x52, 0xb1, 0xdb, +0xbe, 0xdb, 0x6c, 0xd7, 0x1a, 0xc3, 0x89, 0xda, +0x87, 0xe9, 0x70, 0xa0, 0x5d, 0x97, 0x69, 0xb3, +0xe1, 0x6a, 0x75, 0x4c, 0xea, 0x6f, 0x8d, 0xce, +0x40, 0xa7, 0x44, 0x6f, 0x1a, 0x87, 0x36, 0x47, +0x5c, 0x52, 0xe4, 0xfd, 0x99, 0xcc, 0x03, 0x9a, +0xed, 0xda, 0x44, 0x4f, 0x93, 0xb9, 0x43, 0xc3, +0x55, 0xce, 0x97, 0xa9, 0x4f, 0x39, 0x07, 0x9a, +0x24, 0xce, 0xc7, 0x25, 0xb5, 0x0d, 0x61, 0x7e, +0x0d, 0x54, 0x87, 0x5f, 0xae, 0x32, 0x31, 0x31, +0xe1, 0xab, 0xd5, 0x81, 0xb6, 0xfa, 0x9c, 0x0e, +0x00, 0x32, 0x9d, 0x2d, 0x31, 0xfd, 0xb9, 0xb9, +0x39, 0x5f, 0x83, 0x45, 0x36, 0xf2, 0x72, 0xb9, +0x8c, 0xe9, 0xe9, 0x69, 0xcc, 0xcf, 0xcf, 0xc3, +0x75, 0x5d, 0xec, 0xd9, 0xb3, 0x07, 0x93, 0x93, +0x93, 0x88, 0xaf, 0xfd, 0x16, 0x52, 0x4e, 0x02, +0x7b, 0x52, 0x2e, 0xce, 0x37, 0x2a, 0xf8, 0xa3, +0x93, 0xe5, 0x70, 0x35, 0x61, 0xc8, 0x46, 0xeb, +0xb7, 0xb1, 0xd9, 0xf5, 0xa4, 0x84, 0x2c, 0xa5, +0x12, 0x6d, 0xf3, 0x53, 0xe0, 0x75, 0x48, 0xbb, +0x26, 0x49, 0x4f, 0x83, 0x1f, 0x65, 0x7c, 0xb6, +0xe7, 0xb2, 0x3f, 0x1b, 0xee, 0xb2, 0x08, 0xc6, +0xa4, 0x3a, 0xfe, 0x69, 0xf8, 0x9a, 0xc6, 0x62, +0xaa, 0x13, 0xc6, 0x9c, 0x4c, 0xaa, 0xe5, 0x88, +0xf3, 0x6e, 0xd2, 0x36, 0x18, 0x69, 0xaf, 0xe1, +0xa7, 0x31, 0x58, 0x13, 0x4e, 0x36, 0xa6, 0x6d, +0x2a, 0x61, 0x07, 0xb9, 0x28, 0xb8, 0xdb, 0x68, +0x65, 0x5b, 0x73, 0xb6, 0xfe, 0xc2, 0x7c, 0x14, +0x94, 0xf5, 0xe4, 0xfb, 0x6e, 0x68, 0xef, 0xe9, +0x60, 0x68, 0xc3, 0x3b, 0xea, 0xb8, 0x94, 0x79, +0x09, 0xa4, 0x00, 0x2e, 0xd5, 0xea, 0xbe, 0xad, +0x8f, 0x6e, 0x4d, 0x23, 0x69, 0xc1, 0xb4, 0x91, +0xf2, 0xcf, 0xb4, 0xa9, 0xf1, 0x0d, 0x5d, 0x6e, +0xb0, 0x26, 0x29, 0x59, 0x7e, 0x36, 0x6d, 0xde, +0x26, 0x3b, 0xa9, 0xac, 0x67, 0xf3, 0x1a, 0xe7, +0xed, 0xb4, 0x3a, 0x51, 0x24, 0x47, 0xc9, 0xa8, +0x4c, 0x12, 0xa7, 0xc9, 0x49, 0x4c, 0x7b, 0xaf, +0xd1, 0x8d, 0xd7, 0xd3, 0x18, 0xb9, 0x26, 0x3d, +0x13, 0x1c, 0x93, 0x23, 0x23, 0x00, 0xd5, 0x69, +0x4e, 0xbe, 0x27, 0x66, 0xc7, 0x73, 0xaf, 0x4b, +0x67, 0x3f, 0xdb, 0xbc, 0x99, 0x4c, 0x33, 0x9a, +0xbf, 0x83, 0x06, 0x2b, 0x0a, 0xfd, 0x25, 0x9c, +0xb0, 0x43, 0x82, 0x76, 0x78, 0x31, 0xa9, 0xe0, +0xb5, 0x43, 0x0b, 0xd1, 0x6d, 0x62, 0x62, 0xc2, +0xa7, 0x13, 0xd5, 0x27, 0xdb, 0x77, 0xa9, 0x54, +0x82, 0xeb, 0xba, 0x01, 0x29, 0x9d, 0x98, 0x7e, +0x3a, 0x9d, 0xf6, 0x0f, 0x76, 0xda, 0x75, 0xb5, +0x53, 0x53, 0x53, 0x88, 0x3b, 0x49, 0xac, 0x16, +0x56, 0x50, 0x2e, 0xe7, 0x7d, 0x07, 0xba, 0x5c, +0x2e, 0x87, 0xef, 0x1a, 0x19, 0x45, 0xbe, 0x9c, +0xc0, 0x3d, 0x4b, 0x2d, 0x14, 0xaa, 0x75, 0xe3, +0x18, 0x8d, 0x52, 0x83, 0x49, 0x42, 0x35, 0xa9, +0x0d, 0x65, 0x35, 0x91, 0x33, 0xdc, 0xaf, 0x6f, +0xd8, 0xe8, 0x3b, 0xae, 0xb6, 0xd4, 0xfa, 0xb5, +0xd5, 0xb7, 0x6d, 0x9e, 0x51, 0xea, 0x9b, 0xc6, +0x6a, 0x1a, 0x8b, 0xa1, 0x7e, 0x47, 0xa2, 0x8e, +0x30, 0x5b, 0xa7, 0xc9, 0x3e, 0x6d, 0x93, 0xea, +0x0c, 0x34, 0x91, 0xfd, 0x05, 0x98, 0x45, 0x48, +0x7d, 0xe3, 0x18, 0xc3, 0xd6, 0x47, 0xd8, 0xe1, +0xc3, 0x30, 0x2e, 0x9e, 0x43, 0xde, 0x04, 0xcb, +0x8a, 0x53, 0x18, 0x6d, 0xe5, 0x3c, 0x2a, 0xeb, +0x2e, 0x0c, 0x7e, 0xc0, 0x51, 0x52, 0xc2, 0x0d, +0x3b, 0xc0, 0x98, 0xec, 0xda, 0xf2, 0xf0, 0x6a, +0x1a, 0x7f, 0x18, 0xad, 0xa3, 0x4a, 0xfd, 0x61, +0x30, 0x9c, 0x24, 0x1c, 0xcf, 0xf3, 0x50, 0x69, +0x55, 0x02, 0xd2, 0xf2, 0x92, 0xc5, 0x99, 0x49, +0x3a, 0x47, 0xd1, 0x41, 0x80, 0x33, 0x0a, 0x6e, +0x83, 0x97, 0xed, 0xa2, 0x30, 0xcd, 0x30, 0x09, +0x54, 0xdb, 0xd4, 0xa3, 0x3a, 0xd3, 0x85, 0x31, +0x71, 0xed, 0xd0, 0xa2, 0x31, 0x80, 0x28, 0x26, +0x01, 0x4e, 0x0b, 0x0d, 0x07, 0x1b, 0x23, 0x97, +0xb8, 0xda, 0xcc, 0x06, 0xb2, 0x5f, 0x69, 0xfe, +0x90, 0x9a, 0x14, 0x13, 0x2d, 0xf8, 0x98, 0xb9, +0x94, 0xca, 0x0f, 0x76, 0xf2, 0x90, 0x67, 0x82, +0xa9, 0xd1, 0x4c, 0xa3, 0x9f, 0xe6, 0x43, 0xc0, +0xfb, 0xb6, 0x31, 0x6d, 0x29, 0x49, 0x6b, 0xda, +0x16, 0x5e, 0x97, 0x6b, 0x9c, 0xe4, 0x7b, 0x4d, +0xdb, 0x24, 0xb5, 0x39, 0x9c, 0x46, 0xa4, 0x52, +0xcf, 0xe7, 0xf3, 0xbe, 0x36, 0x84, 0x18, 0xb4, +0xe7, 0xad, 0x7b, 0xb7, 0xa7, 0xd3, 0x69, 0x8c, +0x8d, 0x8d, 0xf9, 0xe6, 0x17, 0xaa, 0x3f, 0x35, +0x35, 0xe5, 0xaf, 0x0d, 0xca, 0x20, 0xa7, 0xad, +0x03, 0x67, 0x75, 0x19, 0x3f, 0x3e, 0xe6, 0xe2, +0x74, 0xdd, 0xc5, 0x57, 0xcf, 0xd3, 0x43, 0x65, +0xc3, 0x81, 0x78, 0xc7, 0x4b, 0x37, 0xf5, 0xc5, +0x26, 0xa1, 0x86, 0x91, 0x49, 0xbb, 0x2d, 0xfb, +0xec, 0x7b, 0x11, 0x6b, 0xfd, 0x47, 0xa9, 0x6f, +0x53, 0x3b, 0x02, 0xe1, 0xf5, 0x2d, 0xe3, 0x55, +0x25, 0xa4, 0x30, 0xfa, 0x84, 0xd5, 0xe7, 0xea, +0xd0, 0xa8, 0xcc, 0x53, 0xd3, 0x6a, 0x18, 0xe8, +0xef, 0xe3, 0xcd, 0x71, 0xe9, 0x76, 0xbe, 0x42, +0x98, 0x80, 0x11, 0x27, 0x53, 0x7f, 0xec, 0x73, +0xc0, 0xa9, 0xcb, 0x49, 0xaa, 0x6b, 0x43, 0x95, +0x5a, 0x35, 0xf8, 0x36, 0x0d, 0x8b, 0x66, 0x3a, +0x91, 0x63, 0xe6, 0x6d, 0xa4, 0x9a, 0xdf, 0xd4, +0x9f, 0xc4, 0x47, 0x16, 0x93, 0x96, 0x47, 0xd6, +0xb7, 0x8c, 0x5f, 0x5d, 0x13, 0x72, 0x3e, 0x35, +0x5a, 0xdb, 0xd6, 0x85, 0x52, 0xdf, 0x01, 0x80, +0xa5, 0x85, 0xb9, 0x0e, 0xa9, 0x55, 0xf3, 0x7e, +0xe6, 0x85, 0x6f, 0x7e, 0xf3, 0xf3, 0xf3, 0xd6, +0xcd, 0xd2, 0xe6, 0x84, 0xc6, 0x8b, 0x89, 0xb9, +0x70, 0x49, 0x31, 0x4a, 0x1b, 0xd9, 0x3e, 0x8c, +0xf9, 0x70, 0x29, 0xb4, 0x5b, 0x66, 0xaf, 0xd5, +0x95, 0x4c, 0x90, 0x8f, 0x81, 0xd7, 0xd5, 0x18, +0x15, 0x3d, 0xa3, 0x1b, 0xd3, 0x80, 0x75, 0x89, +0x5a, 0x63, 0xca, 0xb2, 0x1f, 0xa9, 0x22, 0x37, +0xf5, 0xa1, 0x8d, 0x33, 0x4c, 0x1d, 0x6f, 0x63, +0xfe, 0x72, 0xfc, 0x72, 0x7e, 0x34, 0xdb, 0x3f, +0x57, 0x83, 0x6b, 0x7d, 0x85, 0x1d, 0xfe, 0x38, +0x3c, 0x2d, 0x72, 0xc2, 0x34, 0x2e, 0x7e, 0x80, +0xd0, 0xd6, 0x90, 0xac, 0x3f, 0x3a, 0x3a, 0x0a, +0x00, 0x01, 0xe7, 0x37, 0x0e, 0x3b, 0x9d, 0x4e, +0xfb, 0xf6, 0x6e, 0x69, 0x73, 0x27, 0xdc, 0x28, +0x24, 0x73, 0x74, 0x74, 0x14, 0x07, 0x0e, 0x1c, +0x40, 0xb9, 0x5c, 0x0e, 0xd8, 0xc9, 0x81, 0x76, +0x98, 0x1a, 0x39, 0xc9, 0xc5, 0x9d, 0x24, 0x52, +0x6b, 0x7e, 0x24, 0x9e, 0xe7, 0xe1, 0x07, 0x46, +0xaa, 0xb8, 0xd8, 0x74, 0xf1, 0xf8, 0x52, 0x25, +0xd2, 0x29, 0xdd, 0xca, 0x34, 0xa2, 0x4a, 0x06, +0xda, 0x67, 0xa0, 0x3b, 0x09, 0xae, 0xd7, 0xcf, +0x12, 0x4f, 0x53, 0x7d, 0x79, 0x48, 0x30, 0x6d, +0x88, 0x9b, 0xf1, 0xdc, 0x44, 0x57, 0xf9, 0x3e, +0x6c, 0x6e, 0x34, 0xfc, 0x2f, 0xd5, 0x67, 0x1b, +0xdd, 0xa2, 0xe2, 0xb4, 0x91, 0xf5, 0x12, 0x55, +0x02, 0x0d, 0x63, 0x7c, 0x61, 0x30, 0xba, 0x59, +0xe3, 0x1b, 0x19, 0xef, 0x46, 0xc7, 0x17, 0x15, +0x9f, 0xb0, 0xdf, 0xb2, 0xb2, 0x26, 0x9d, 0x2b, +0xea, 0x4b, 0xa8, 0xc3, 0xec, 0x88, 0x25, 0x6d, +0xaa, 0x9a, 0x04, 0xa5, 0x49, 0x47, 0xf2, 0x33, +0x7d, 0xd7, 0xfa, 0x90, 0xc5, 0x24, 0x51, 0x69, +0x38, 0x45, 0x51, 0xa9, 0xdb, 0x8a, 0x8d, 0xc1, +0x69, 0x75, 0x6d, 0x38, 0x9b, 0x54, 0xb8, 0xfc, +0x99, 0xed, 0x20, 0xc0, 0x99, 0x0c, 0x49, 0x7b, +0x9a, 0x9d, 0x58, 0xd2, 0xc0, 0x74, 0x58, 0xf2, +0x3c, 0xcf, 0x0f, 0xa3, 0xe2, 0xf3, 0x2b, 0xe7, +0x51, 0xe2, 0x2f, 0x69, 0x22, 0x73, 0xef, 0x9b, +0x68, 0x16, 0x85, 0xf9, 0x6a, 0x36, 0x75, 0xdb, +0x01, 0x49, 0x6b, 0x2b, 0xc7, 0x69, 0x53, 0xa3, +0x6b, 0x5a, 0x16, 0x79, 0x15, 0xaa, 0xe9, 0x00, +0x47, 0x75, 0xb9, 0xcd, 0x9c, 0x6c, 0xe8, 0xa4, +0xf1, 0x90, 0x21, 0x70, 0xdc, 0x67, 0xc1, 0xf3, +0x3c, 0x2c, 0x2d, 0x2d, 0x61, 0x61, 0x61, 0x01, +0x9e, 0xe7, 0xe1, 0xd0, 0xa1, 0x43, 0xc8, 0xe5, +0x72, 0x98, 0x9f, 0x9f, 0xf7, 0xe7, 0xa5, 0x5c, +0x2e, 0xfb, 0x0c, 0x9c, 0xab, 0xe2, 0xb9, 0x33, +0x25, 0xa9, 0xf3, 0x7f, 0x3a, 0x37, 0x84, 0x0f, +0xac, 0xba, 0x38, 0xdd, 0xb0, 0xd8, 0x13, 0xe9, +0x7f, 0x14, 0xf5, 0x33, 0x95, 0x6e, 0x37, 0x69, +0xde, 0x9f, 0x8d, 0xe1, 0x6a, 0xb8, 0x84, 0x6d, +0x66, 0xfc, 0xb9, 0x06, 0x9f, 0xd7, 0xeb, 0xa5, +0xf4, 0x2a, 0x55, 0x77, 0x0b, 0x5f, 0xeb, 0x6b, +0x33, 0x0e, 0x54, 0x51, 0xf1, 0x33, 0xcd, 0x97, +0xf6, 0x5d, 0xd2, 0x37, 0x6a, 0x7b, 0xa0, 0x7d, +0x85, 0x2a, 0x97, 0x4a, 0xa3, 0x1c, 0x70, 0x6c, +0xf3, 0x61, 0x53, 0x85, 0x73, 0x3c, 0x4c, 0xfd, +0x75, 0x3b, 0x3f, 0x26, 0x3c, 0x6c, 0xfd, 0xcb, +0xfa, 0x74, 0x71, 0x51, 0x88, 0x86, 0x45, 0x85, +0xa3, 0x8d, 0xc9, 0x76, 0x48, 0xb5, 0xc0, 0x73, +0xf2, 0xc9, 0x0c, 0xb2, 0xd0, 0x63, 0xb7, 0xc3, +0xec, 0xc2, 0xa6, 0xcf, 0x61, 0xf6, 0x72, 0xce, +0x60, 0x24, 0x4c, 0x8d, 0x71, 0xf1, 0xef, 0x26, +0x1b, 0xb2, 0x8d, 0x91, 0xca, 0x12, 0xc5, 0xd9, +0x2d, 0xec, 0x90, 0x20, 0xfb, 0x22, 0x5b, 0xb3, +0xed, 0x40, 0x64, 0xd2, 0x2c, 0x68, 0x12, 0x31, +0x85, 0x38, 0x71, 0x89, 0x5e, 0xd3, 0x74, 0xc8, +0x43, 0x18, 0x67, 0xc0, 0xb9, 0x5c, 0x2e, 0x70, +0xdf, 0xb6, 0x54, 0xeb, 0x6b, 0xf8, 0xc9, 0xc3, +0x81, 0xb6, 0x06, 0x6c, 0x8c, 0xdd, 0x24, 0xdd, +0x9b, 0xc6, 0x6e, 0x5b, 0x5b, 0x32, 0x2c, 0x8e, +0xfe, 0x6b, 0xe1, 0x72, 0x26, 0x27, 0x38, 0x93, +0x23, 0x5e, 0xd8, 0x3c, 0x9b, 0xc6, 0xcd, 0x4d, +0x17, 0x64, 0x23, 0x27, 0x9c, 0x88, 0x91, 0xd3, +0x15, 0xa8, 0xc4, 0xb4, 0xc7, 0xc6, 0xc6, 0x7c, +0xc7, 0xb7, 0x63, 0xc7, 0x8e, 0x61, 0x61, 0x61, +0xc1, 0x87, 0x37, 0x36, 0x36, 0x86, 0xa9, 0xa9, +0x29, 0xcc, 0xcf, 0xcf, 0x63, 0x7a, 0x7a, 0x1a, +0x00, 0x02, 0x73, 0xc7, 0xe3, 0xd1, 0x73, 0x68, +0xe1, 0x4d, 0x63, 0x5e, 0xdb, 0x21, 0x0e, 0xd0, +0x99, 0x20, 0x7d, 0x37, 0x31, 0x55, 0x5e, 0x5f, +0xdb, 0x7c, 0x4c, 0x0c, 0x46, 0x53, 0x7f, 0xdb, +0xe0, 0x9b, 0x18, 0x50, 0x18, 0x03, 0x93, 0xed, +0xb5, 0xcd, 0xcd, 0x66, 0x2e, 0x08, 0xc3, 0x3f, +0x2a, 0x9c, 0x28, 0x9f, 0xbb, 0x19, 0x47, 0xd8, +0x21, 0xc2, 0xa4, 0x5e, 0x35, 0x69, 0x07, 0xa2, +0xce, 0x4b, 0x14, 0x26, 0x6b, 0x82, 0xad, 0xcd, +0xad, 0x7c, 0x46, 0xcf, 0xf9, 0x4d, 0x7c, 0x36, +0x3a, 0x69, 0x6a, 0x6a, 0xd3, 0x7b, 0x13, 0x5d, +0x4d, 0xf3, 0x67, 0x3a, 0x44, 0x9a, 0xd4, 0xe2, +0x61, 0xfd, 0x47, 0x39, 0x80, 0x01, 0xc1, 0xfb, +0xe0, 0xa3, 0x6a, 0x8c, 0x4c, 0x7d, 0x6a, 0x87, +0xd7, 0x30, 0xba, 0xac, 0x7d, 0x77, 0xce, 0xb7, +0x52, 0xc8, 0x62, 0xdd, 0x16, 0x2a, 0xe3, 0x73, +0xb9, 0xb4, 0xc8, 0x25, 0x90, 0x5c, 0x2e, 0x87, +0xd9, 0xd9, 0x59, 0xab, 0x94, 0xc6, 0x8b, 0x26, +0xb9, 0xd3, 0xf7, 0x30, 0x35, 0xb8, 0xad, 0x4d, +0xb7, 0x8c, 0xdc, 0x06, 0xdf, 0xd4, 0x5e, 0x53, +0x15, 0x47, 0xd1, 0x2e, 0x70, 0xc6, 0xaa, 0x39, +0x84, 0xd1, 0xa6, 0xad, 0xc1, 0xaa, 0x54, 0x2a, +0x7e, 0x3d, 0x9e, 0x14, 0xc6, 0x66, 0x57, 0x36, +0x49, 0xfb, 0x52, 0x05, 0x6d, 0x32, 0x59, 0x98, +0x0e, 0x74, 0xb6, 0x7a, 0xda, 0x73, 0x8d, 0x0e, +0x61, 0x07, 0x42, 0x49, 0x6b, 0xfe, 0xde, 0xe6, +0x9f, 0x60, 0x7b, 0x66, 0x6b, 0xab, 0x1d, 0x3c, +0x6c, 0x26, 0x22, 0xed, 0xa0, 0x23, 0x25, 0x74, +0x72, 0x06, 0x1d, 0x1a, 0x1a, 0xc2, 0xd2, 0xd2, +0x12, 0xf2, 0xf9, 0x3c, 0x26, 0x26, 0x26, 0xfc, +0xd0, 0x34, 0x1e, 0xb2, 0xe6, 0x79, 0x1e, 0xa6, +0xa6, 0xa6, 0x90, 0xcb, 0xe5, 0x30, 0x3d, 0x3d, +0x1d, 0x88, 0x18, 0x39, 0x7c, 0xf8, 0xb0, 0x1f, +0x8f, 0xce, 0x71, 0x28, 0x97, 0xcb, 0xf8, 0xae, +0xbe, 0x16, 0xbe, 0xba, 0x94, 0xc0, 0xe3, 0x17, +0x1b, 0x3a, 0xf3, 0xa0, 0xef, 0xda, 0x66, 0x19, +0x45, 0x72, 0x08, 0x53, 0x39, 0x47, 0x91, 0xa4, +0x4d, 0x6d, 0x6d, 0xf0, 0x25, 0x6c, 0x8e, 0xa7, +0xfc, 0x1c, 0x36, 0x6e, 0x0e, 0xdf, 0x26, 0x55, +0xd9, 0xf0, 0xd4, 0xfa, 0x91, 0x9f, 0xc3, 0x18, +0x93, 0x4d, 0x9b, 0x61, 0x1b, 0x7f, 0x98, 0xe6, +0xc2, 0x34, 0x96, 0x28, 0x66, 0x0a, 0xad, 0xad, +0xed, 0x3d, 0x7f, 0x6e, 0xc3, 0x97, 0x4b, 0xa6, +0x51, 0xe1, 0x69, 0x0c, 0x2e, 0x6c, 0x3e, 0x65, +0xbd, 0x46, 0x43, 0x3f, 0x44, 0x98, 0xe8, 0x49, +0xcf, 0xc3, 0xe6, 0xc1, 0xd6, 0x3f, 0xc7, 0x57, +0x3b, 0xc4, 0x68, 0xe3, 0xb1, 0x1d, 0xba, 0xc2, +0x0e, 0x72, 0x51, 0x0e, 0xc9, 0x40, 0x3b, 0x34, +0x0d, 0xd0, 0xd5, 0x90, 0x26, 0x3b, 0x26, 0x7d, +0x97, 0xc5, 0x24, 0xed, 0x72, 0xe6, 0xa5, 0xd9, +0x75, 0xa9, 0x2e, 0x6f, 0x27, 0xe1, 0x48, 0x78, +0xb2, 0x68, 0xd2, 0xa1, 0x49, 0x5a, 0x93, 0x38, +0x47, 0xb5, 0xcd, 0xda, 0xc6, 0xc9, 0x71, 0xd0, +0x24, 0x5d, 0xd3, 0x21, 0x49, 0xda, 0xbb, 0xf9, +0x73, 0x92, 0xe6, 0xa4, 0x17, 0xba, 0x8d, 0xa1, +0x53, 0x7d, 0xa9, 0xfe, 0xd5, 0x1c, 0xb9, 0xa2, +0x6a, 0x28, 0x6c, 0xd2, 0xb7, 0x69, 0x4e, 0xc2, +0xec, 0xd0, 0xd2, 0x7f, 0x80, 0xd7, 0x33, 0x69, +0x87, 0xa2, 0x98, 0x55, 0x4c, 0x63, 0xe0, 0xb0, +0xf8, 0x7c, 0x91, 0x6a, 0x9c, 0x92, 0xbe, 0xc8, +0x43, 0x8f, 0xc9, 0x41, 0x8f, 0xe6, 0x8b, 0x24, +0x67, 0x72, 0x6c, 0x23, 0x46, 0xbe, 0xb0, 0xb0, +0x80, 0xd1, 0xd1, 0x51, 0x8c, 0x8f, 0x8f, 0x07, +0x6c, 0xe6, 0x24, 0x71, 0x4f, 0x4e, 0x4e, 0xfa, +0x76, 0xf3, 0x52, 0xa9, 0xe4, 0x3f, 0xe3, 0xfd, +0x71, 0x9b, 0x3a, 0x65, 0x98, 0xf3, 0x06, 0x06, +0x71, 0xdb, 0xd6, 0xfd, 0x78, 0x21, 0x91, 0xc3, +0x85, 0x98, 0xdb, 0xb9, 0x31, 0xd8, 0xd4, 0xd2, +0x51, 0xd4, 0xdf, 0x61, 0x52, 0x6d, 0x54, 0xe6, +0x11, 0x15, 0x7e, 0xb7, 0xed, 0x25, 0x5e, 0x54, +0xba, 0xb5, 0x5f, 0x86, 0x49, 0xb8, 0x36, 0xfc, +0xa2, 0xd2, 0xc6, 0xc6, 0x54, 0xe5, 0x7c, 0xd9, +0xea, 0x45, 0x91, 0x74, 0x39, 0x9e, 0x12, 0xae, +0xed, 0x5d, 0x18, 0x5d, 0xc2, 0xea, 0x6b, 0x6b, +0xcc, 0x36, 0x2f, 0xda, 0x3a, 0xb5, 0xbd, 0x97, +0xf3, 0x20, 0xeb, 0x27, 0x12, 0x7a, 0xff, 0x61, +0xa6, 0x09, 0xd3, 0x3c, 0xf4, 0xda, 0x7f, 0x18, +0xfd, 0x4c, 0x34, 0xb2, 0xd1, 0xde, 0xc6, 0xc4, +0x95, 0xfa, 0x4e, 0xa9, 0x56, 0xb7, 0x32, 0x3b, +0xce, 0x6c, 0xa8, 0xc8, 0x0d, 0xde, 0x24, 0x39, +0x4b, 0x46, 0x5a, 0x2e, 0x97, 0x03, 0xa9, 0x30, +0xa3, 0x48, 0xf4, 0xfc, 0x59, 0x98, 0xfa, 0x97, +0xf7, 0x6f, 0x1a, 0x8f, 0xad, 0x1f, 0x5b, 0x1b, +0x9b, 0xea, 0xd8, 0x26, 0xc9, 0x13, 0x73, 0x20, +0x75, 0xab, 0xe9, 0x70, 0xa1, 0x39, 0xc1, 0x45, +0x71, 0x1a, 0x34, 0xd1, 0xc5, 0x24, 0xfd, 0x73, +0xd5, 0xbd, 0x76, 0x40, 0x93, 0xb4, 0xd3, 0xcc, +0x1b, 0xa6, 0x39, 0x09, 0xc3, 0xcd, 0x44, 0x23, +0x5b, 0xfd, 0x30, 0xcd, 0x8c, 0x46, 0xab, 0x30, +0x4d, 0x8e, 0x6c, 0x27, 0x6d, 0xe2, 0xbc, 0x8d, +0xeb, 0xba, 0x7e, 0xc4, 0x86, 0x3c, 0x68, 0x70, +0x75, 0x3f, 0x49, 0xd5, 0x92, 0x91, 0x13, 0x53, +0xa6, 0xc3, 0x19, 0x31, 0xed, 0xf9, 0xf9, 0x79, +0x3f, 0x8b, 0xe2, 0xf8, 0xf8, 0xb8, 0x2f, 0x89, +0x93, 0x6a, 0x9e, 0xdb, 0xd5, 0x03, 0xbe, 0x29, +0x17, 0x97, 0xb1, 0xb3, 0xf2, 0x4d, 0xdc, 0xb5, +0x65, 0x3f, 0x3e, 0x59, 0x1b, 0x41, 0x31, 0x99, +0xd1, 0x99, 0x0a, 0x10, 0xbe, 0x39, 0x69, 0xc5, +0xa6, 0x66, 0xe4, 0x25, 0x2a, 0x3c, 0x13, 0x7c, +0xfa, 0x2c, 0x61, 0xf1, 0xe7, 0x52, 0xf2, 0x32, +0xf5, 0xab, 0xe1, 0xa7, 0xd5, 0x37, 0x15, 0xea, +0x23, 0x8a, 0x66, 0x23, 0xaa, 0xb9, 0x80, 0x8f, +0xb3, 0x52, 0x36, 0xe3, 0xa2, 0x49, 0xf7, 0x61, +0x1b, 0x39, 0x1f, 0x9b, 0xa4, 0x23, 0x7d, 0x8f, +0x42, 0xe7, 0x30, 0xda, 0x84, 0xe1, 0xcb, 0xff, +0x73, 0xbb, 0xb1, 0x8d, 0xb1, 0x69, 0xeb, 0xc1, +0xf6, 0xdd, 0xa4, 0xb5, 0x91, 0xdf, 0xe5, 0x3a, +0x89, 0x72, 0xa8, 0xd4, 0xe8, 0x1b, 0xb5, 0x7f, +0x49, 0x1f, 0x13, 0x7e, 0x61, 0xea, 0xfb, 0xb0, +0xdf, 0xa2, 0xf6, 0x4c, 0x3b, 0xcc, 0x02, 0x70, +0x1a, 0xd5, 0x0a, 0x16, 0x57, 0x8a, 0x81, 0x87, +0xd2, 0xbb, 0x5b, 0x4a, 0xbb, 0xc4, 0x10, 0x68, +0xc3, 0x91, 0x92, 0x27, 0xa0, 0x33, 0x5b, 0xae, +0x6e, 0xe6, 0x75, 0xe8, 0xb3, 0x96, 0xcc, 0xc3, +0xa4, 0xca, 0xd5, 0x6c, 0xb3, 0x36, 0x09, 0xdb, +0xc6, 0x74, 0x4c, 0x36, 0xd4, 0x5e, 0x18, 0x95, +0xc6, 0x94, 0xb9, 0xe3, 0x99, 0x86, 0xaf, 0x89, +0x71, 0x2e, 0x2d, 0x2d, 0xa9, 0x12, 0xb0, 0xb4, +0x7b, 0x73, 0xf3, 0x08, 0x97, 0x1a, 0x09, 0x16, +0x7d, 0xe6, 0x8c, 0xdd, 0x64, 0x1e, 0x91, 0x74, +0x88, 0x2a, 0x81, 0x87, 0xd9, 0xca, 0x6d, 0x1a, +0x00, 0x89, 0x8b, 0x76, 0xa8, 0x31, 0x49, 0xda, +0xa6, 0x62, 0xd3, 0xd4, 0x84, 0xcd, 0x3d, 0x3d, +0xa3, 0xf0, 0x33, 0x6a, 0xcb, 0xc3, 0xd1, 0xe8, +0x26, 0xb5, 0x4a, 0xa5, 0x12, 0xb8, 0x71, 0x70, +0x61, 0x61, 0x01, 0xb9, 0x5c, 0x0e, 0x43, 0x43, +0x43, 0x01, 0x89, 0x9c, 0x3c, 0xd5, 0xc9, 0x3c, +0x35, 0x3b, 0x3b, 0x8b, 0xc1, 0xc1, 0x41, 0xec, +0xd9, 0xb3, 0xc7, 0xff, 0x2d, 0x51, 0x26, 0x38, +0x9a, 0x1f, 0x62, 0xfc, 0x64, 0x3b, 0xe7, 0xda, +0x8c, 0xad, 0x95, 0x16, 0x2e, 0x9c, 0x2f, 0xe3, +0x33, 0x95, 0x94, 0x5d, 0x0a, 0xb3, 0x31, 0x1d, +0x9b, 0x64, 0x6a, 0xdb, 0xec, 0xb4, 0xcd, 0x99, +0x18, 0x16, 0x67, 0x8a, 0x51, 0x24, 0x5f, 0x13, +0x63, 0xa4, 0x7a, 0xb4, 0x41, 0x4b, 0x66, 0xd1, +0xcd, 0x38, 0x4d, 0xda, 0x0a, 0xfa, 0x6e, 0x82, +0x1b, 0x26, 0x89, 0x87, 0x49, 0x60, 0x54, 0x6c, +0xb6, 0x64, 0x89, 0x7b, 0x2f, 0x73, 0x10, 0xc5, +0x0c, 0xc2, 0xbf, 0x47, 0x95, 0xf8, 0x4d, 0x34, +0x30, 0xb5, 0xe1, 0x25, 0x4c, 0xc2, 0x0f, 0x53, +0x3b, 0x87, 0x49, 0xff, 0xf4, 0x9d, 0x98, 0x78, +0x22, 0xa1, 0xc3, 0xed, 0x95, 0x4e, 0x51, 0xb5, +0x0f, 0xf2, 0x40, 0x93, 0x48, 0x44, 0x9b, 0xb7, +0x6e, 0x34, 0x63, 0x11, 0xdf, 0x39, 0x00, 0xe0, +0x34, 0x6a, 0x70, 0xc4, 0xe6, 0x6a, 0xba, 0x2c, +0x44, 0x63, 0x28, 0x72, 0x93, 0x97, 0x1b, 0x39, +0x79, 0xe5, 0xf2, 0x12, 0x45, 0x95, 0x1e, 0xe6, +0x04, 0x67, 0x92, 0x70, 0x25, 0x1e, 0xb2, 0x44, +0xa9, 0x23, 0xc7, 0x6e, 0xb3, 0x13, 0x4b, 0xbb, +0xb7, 0x89, 0x31, 0xcd, 0xcf, 0xcf, 0x07, 0x32, +0x80, 0x69, 0xb6, 0x58, 0x0e, 0x87, 0x24, 0xc6, +0xd1, 0xd1, 0xd1, 0xc0, 0xad, 0x5d, 0xdc, 0xb6, +0x2b, 0xf1, 0xd0, 0x34, 0x29, 0xda, 0x65, 0x39, +0xa6, 0x44, 0x30, 0x92, 0xc1, 0xca, 0x62, 0x73, +0x1e, 0xb3, 0xd9, 0xd0, 0xa3, 0x3a, 0xc6, 0xd9, +0x34, 0x35, 0x26, 0x9f, 0x01, 0x39, 0x9f, 0xda, +0x7c, 0x84, 0x15, 0x2e, 0x85, 0x03, 0xc1, 0xf0, +0x33, 0xfa, 0x4c, 0xaa, 0x78, 0x92, 0xc2, 0xb9, +0x44, 0xcf, 0xbd, 0xd6, 0xc7, 0xc6, 0xc6, 0x02, +0x92, 0x35, 0x31, 0x72, 0xcf, 0xf3, 0x7c, 0xd5, +0xb9, 0xe7, 0x79, 0x38, 0x70, 0xe0, 0x00, 0x3c, +0xcf, 0xc3, 0xcc, 0xcc, 0x4c, 0xe0, 0x39, 0x25, +0x92, 0x21, 0xbc, 0xe7, 0xe7, 0xe7, 0x31, 0x3b, +0x3b, 0xdb, 0x81, 0xef, 0x0f, 0xe6, 0x72, 0xf8, +0x66, 0x7c, 0x18, 0x0b, 0xa5, 0x08, 0x9b, 0xbc, +0xfc, 0x6e, 0x63, 0xb2, 0x54, 0x24, 0x03, 0xb4, +0xd9, 0x38, 0x69, 0x13, 0x8b, 0x02, 0x3f, 0x8a, +0x4d, 0x53, 0xfb, 0xce, 0xf1, 0xe2, 0x7d, 0x44, +0x61, 0xb4, 0x5a, 0x3b, 0x1b, 0xdc, 0xa8, 0xf8, +0x99, 0x24, 0x25, 0x7a, 0xc6, 0x25, 0x46, 0xda, +0xf0, 0xa3, 0x68, 0x46, 0xb4, 0x71, 0x6b, 0x73, +0x08, 0xac, 0x1f, 0x74, 0xa4, 0x57, 0xb5, 0x0d, +0xaf, 0x28, 0x70, 0x4d, 0x87, 0x3c, 0x4d, 0x23, +0xc3, 0xc7, 0x68, 0x3b, 0xb4, 0x68, 0x78, 0x45, +0x31, 0x6f, 0x98, 0xfa, 0xe7, 0x9a, 0x27, 0xd3, +0xf8, 0x37, 0xb3, 0x7f, 0xf9, 0x9c, 0xdb, 0xcc, +0x4d, 0xe3, 0x97, 0x7d, 0x6a, 0xe3, 0xb1, 0x1d, +0x32, 0xc2, 0xe6, 0x69, 0xad, 0xae, 0x03, 0xac, +0x6f, 0xac, 0x7c, 0xd3, 0xd7, 0x98, 0x29, 0xdf, +0x38, 0x89, 0x99, 0x4c, 0x4e, 0x4e, 0x06, 0x1c, +0x7b, 0xf8, 0x3b, 0xcd, 0x2e, 0x6a, 0x93, 0x02, +0x4d, 0xdf, 0xc3, 0x4a, 0x58, 0xfd, 0x6e, 0x9c, +0xa0, 0xc2, 0xfa, 0x09, 0xb3, 0xc5, 0x4b, 0x6d, +0x86, 0x09, 0x0f, 0x2e, 0xad, 0x6b, 0xf0, 0xb8, +0xb4, 0xcd, 0x99, 0x06, 0x9f, 0x2b, 0x79, 0xe0, +0x92, 0xf3, 0x68, 0xea, 0xdb, 0xe4, 0xfc, 0x45, +0xff, 0x65, 0x28, 0x1a, 0x77, 0xda, 0xe2, 0xdf, +0x6d, 0x9a, 0x09, 0x39, 0x2f, 0x92, 0xe1, 0x4a, +0xa6, 0x1b, 0x55, 0x62, 0xb6, 0x69, 0x42, 0xb4, +0x77, 0x26, 0xa9, 0x5c, 0x5b, 0x33, 0x3c, 0x7b, +0x9e, 0x64, 0xea, 0x74, 0x98, 0x02, 0xda, 0x89, +0x80, 0xc8, 0x86, 0x4d, 0x1e, 0xec, 0xe4, 0xa1, +0x3e, 0x39, 0x39, 0x89, 0xa5, 0xa5, 0x25, 0x9f, +0x91, 0x93, 0x54, 0xed, 0x79, 0x1e, 0x4e, 0x9c, +0x38, 0xe1, 0x4b, 0xee, 0x74, 0xe1, 0xd0, 0xd1, +0xa3, 0x47, 0x7d, 0x69, 0x7c, 0x6c, 0x6c, 0x0c, +0x87, 0x0e, 0x1d, 0xf2, 0x69, 0x3c, 0x3f, 0x3f, +0xef, 0x3b, 0xd7, 0x4d, 0x4d, 0x4d, 0xa1, 0x2f, +0xdb, 0x0f, 0x00, 0x68, 0xb2, 0x1f, 0xf9, 0x6b, +0xce, 0xa7, 0xf0, 0x37, 0xcf, 0xaf, 0x65, 0x86, +0x0b, 0x93, 0xf8, 0x6c, 0x92, 0x9f, 0x6c, 0xdf, +0xad, 0x94, 0xa0, 0xc1, 0x0c, 0x93, 0xf4, 0xb4, +0x7a, 0x26, 0x78, 0x52, 0x7a, 0x06, 0xcc, 0xd2, +0x7a, 0x2f, 0xd2, 0x8d, 0xad, 0xad, 0x56, 0x37, +0x8c, 0x0e, 0x26, 0x5c, 0xa5, 0x2a, 0xda, 0xd6, +0x4f, 0xd4, 0x31, 0x10, 0x4c, 0x09, 0xdb, 0x36, +0xef, 0xa6, 0xb5, 0xd0, 0x2d, 0x03, 0x92, 0x26, +0x0a, 0xad, 0x9d, 0x6d, 0x9d, 0x68, 0xdf, 0x4d, +0xeb, 0xc5, 0xf4, 0x99, 0x70, 0x30, 0x31, 0xf2, +0x28, 0xfd, 0x4b, 0x98, 0xa6, 0x3e, 0x25, 0x0d, +0x38, 0xcd, 0xc3, 0x0e, 0x12, 0xdd, 0xfc, 0xde, +0xc2, 0x0e, 0xa6, 0x0a, 0x2d, 0x9c, 0x44, 0xca, +0xed, 0x50, 0x01, 0xf3, 0x0d, 0x5d, 0x4a, 0xde, +0xe5, 0x72, 0x3b, 0x06, 0x9a, 0xa4, 0x40, 0x52, +0x19, 0x4a, 0x7b, 0xab, 0xe6, 0x6c, 0x65, 0x62, +0x86, 0x36, 0xa9, 0x9e, 0x7f, 0x0e, 0x53, 0xdd, +0x76, 0x5b, 0xc2, 0x9c, 0xbf, 0x4c, 0x92, 0x65, +0x98, 0xb4, 0xce, 0x69, 0x20, 0x19, 0x2b, 0x4f, +0x99, 0xca, 0xfd, 0x07, 0x78, 0x1b, 0x8d, 0xc9, +0x49, 0x2d, 0x88, 0xc6, 0x04, 0xe5, 0xe1, 0xc9, +0xc4, 0x90, 0xf9, 0x7b, 0xe9, 0xf3, 0xa0, 0x49, +0xf0, 0x92, 0xde, 0x3c, 0x5c, 0x2e, 0xcc, 0xf9, +0xcd, 0xa4, 0x42, 0x37, 0x31, 0x7d, 0x13, 0x4c, +0x5b, 0x3d, 0x93, 0x1d, 0xdf, 0xe6, 0x2c, 0xa7, +0xcd, 0xbb, 0x56, 0x9f, 0x6e, 0x45, 0xa3, 0xf7, +0xa3, 0xa3, 0xa3, 0x1d, 0x8c, 0x9c, 0x6b, 0x50, +0x96, 0x96, 0x96, 0x70, 0xf2, 0xe4, 0x49, 0x5f, +0xc2, 0x26, 0x5a, 0xcd, 0xcc, 0xcc, 0xf8, 0x73, +0x4f, 0xda, 0x99, 0xe9, 0xe9, 0x69, 0x5f, 0xe2, +0x26, 0xcf, 0x76, 0x99, 0xea, 0x95, 0xd4, 0xeb, +0xe4, 0xf1, 0xce, 0xe7, 0x61, 0x6c, 0x6c, 0x0c, +0xd7, 0xf7, 0x0d, 0xa2, 0xd6, 0xb7, 0x03, 0xf7, +0xd6, 0x87, 0x51, 0xa8, 0x1a, 0x98, 0x64, 0x98, +0xca, 0xd3, 0xb4, 0xf9, 0x77, 0xc3, 0xc8, 0xc3, +0xa4, 0x22, 0x13, 0x1c, 0xc2, 0x55, 0xe2, 0xa4, +0xd5, 0xa3, 0x98, 0x66, 0x7a, 0x96, 0x48, 0x44, +0xc3, 0xd5, 0x44, 0x0f, 0xaa, 0x4f, 0xb8, 0xdb, +0x24, 0xfd, 0xa8, 0xc5, 0x24, 0xa9, 0xf3, 0x4d, +0x9f, 0xc7, 0x66, 0xf3, 0x36, 0x26, 0x3c, 0x6d, +0x73, 0x49, 0xaa, 0x5d, 0x49, 0x63, 0xf9, 0x99, +0xd3, 0x59, 0xfb, 0x2e, 0xdf, 0x85, 0xad, 0x19, +0xfa, 0x6e, 0x92, 0x8c, 0x6d, 0xda, 0x12, 0x53, +0xff, 0x61, 0xcc, 0xcb, 0x84, 0x1b, 0x37, 0x63, +0x70, 0xed, 0x87, 0xa6, 0x01, 0x09, 0x53, 0x9b, +0x4b, 0x5c, 0x6c, 0x74, 0xe5, 0xeb, 0x92, 0x0e, +0x14, 0x9a, 0x54, 0x6d, 0x63, 0xea, 0x52, 0x4d, +0x1f, 0xf5, 0xb0, 0xa7, 0xe0, 0xe5, 0xd0, 0x33, +0x8d, 0x79, 0x98, 0xd4, 0x98, 0x27, 0x4f, 0x9e, +0xc4, 0xc2, 0xc2, 0x82, 0x6f, 0xe7, 0xd3, 0xbc, +0x84, 0xf9, 0x7f, 0x5e, 0x4c, 0x52, 0x2b, 0x7f, +0x27, 0x9f, 0x71, 0xbc, 0x34, 0x49, 0xda, 0xa4, +0x1e, 0x96, 0x12, 0xb8, 0x56, 0x6c, 0xf6, 0xd9, +0xb0, 0x43, 0x83, 0x66, 0x1a, 0xd0, 0xec, 0xd1, +0xd2, 0xc1, 0x8c, 0x33, 0x79, 0x53, 0xf2, 0x11, +0x89, 0xa3, 0xd6, 0xb7, 0xc6, 0xe8, 0xb5, 0x2b, +0x61, 0x6d, 0x38, 0x9b, 0xea, 0x48, 0x29, 0x3f, +0xcc, 0x3f, 0xc1, 0xe4, 0x64, 0x16, 0xd5, 0x54, +0x61, 0x7b, 0x6f, 0x2a, 0x26, 0x8d, 0x86, 0xe6, +0xe3, 0x61, 0x5a, 0x0b, 0xf2, 0x30, 0x43, 0x85, +0x18, 0xb5, 0x16, 0x47, 0xce, 0x35, 0x25, 0x54, +0x67, 0x74, 0x74, 0x14, 0xe9, 0x74, 0xda, 0xcf, +0xab, 0x4e, 0x49, 0x60, 0xc8, 0xc4, 0x44, 0xb8, +0x70, 0x89, 0x9c, 0xd4, 0xea, 0xfb, 0xf7, 0xef, +0x07, 0x00, 0xff, 0x50, 0x7c, 0xe8, 0xd0, 0x21, +0x5f, 0x55, 0xff, 0xe0, 0x83, 0x0f, 0xfa, 0x78, +0xf3, 0xc4, 0x32, 0x84, 0x77, 0x2d, 0x91, 0xc2, +0xeb, 0x92, 0xcb, 0x78, 0x21, 0x3d, 0x82, 0xaf, +0x2e, 0x1b, 0x36, 0xc3, 0x6e, 0x24, 0xd2, 0xa8, +0x8c, 0x5c, 0x32, 0x71, 0xe9, 0xd5, 0x1b, 0x85, +0x11, 0x98, 0xd4, 0x9e, 0xb6, 0xfe, 0xa8, 0xf4, +0xaa, 0x59, 0xd0, 0xe8, 0x61, 0xb2, 0xcb, 0xdb, +0x0e, 0x38, 0x51, 0x0f, 0x11, 0x1c, 0x3f, 0xfa, +0xcc, 0xfb, 0x33, 0x99, 0x27, 0xa2, 0x1e, 0x46, +0xa4, 0xd3, 0x17, 0xc1, 0x30, 0xcd, 0xab, 0x89, +0x5e, 0xf4, 0xdc, 0x24, 0x35, 0x47, 0x5d, 0x0f, +0x61, 0xed, 0xc2, 0xb4, 0x45, 0x5a, 0x1f, 0xda, +0x3b, 0x6d, 0x1d, 0xd9, 0xe8, 0x6b, 0x83, 0x1f, +0x36, 0x46, 0xd3, 0x7a, 0xa3, 0xc2, 0xe7, 0x80, +0xab, 0xdd, 0x35, 0xfc, 0xb5, 0xf6, 0x12, 0x6f, +0xad, 0x3f, 0x9b, 0xb6, 0x65, 0xad, 0x2f, 0x9f, +0x99, 0x23, 0xd5, 0xde, 0xe4, 0xaa, 0xcd, 0x16, +0x80, 0x4e, 0xc9, 0x98, 0x3b, 0xaf, 0xd1, 0x26, +0x64, 0x4a, 0xa1, 0xc9, 0xdb, 0x99, 0x18, 0xad, +0xd6, 0x86, 0xc7, 0x53, 0x73, 0x18, 0xda, 0x86, +0x6d, 0xf3, 0xfc, 0x96, 0xcf, 0x34, 0x26, 0xc3, +0x4b, 0x98, 0xa3, 0x9b, 0x89, 0xd9, 0x9b, 0xd4, +0xb7, 0x9a, 0xcf, 0x80, 0xec, 0x5f, 0x32, 0x79, +0x93, 0x4a, 0x58, 0xd2, 0x97, 0x24, 0x7a, 0x4d, +0xfa, 0xe5, 0x75, 0xa4, 0xb3, 0xa1, 0xb4, 0x23, +0xdb, 0x1c, 0x16, 0x4d, 0xf3, 0x26, 0x9d, 0xee, +0x6c, 0xf6, 0x7e, 0x6d, 0xee, 0x08, 0x96, 0xc9, +0xc7, 0x42, 0x5b, 0x17, 0x92, 0x41, 0xdb, 0x42, +0xda, 0x64, 0x3b, 0x39, 0x1f, 0xb6, 0xf9, 0x26, +0x75, 0x3a, 0x67, 0xd4, 0xdc, 0xf9, 0xcd, 0x75, +0xdd, 0x0e, 0x29, 0x9d, 0x3b, 0xc3, 0x01, 0x08, +0xa8, 0xd6, 0x49, 0xca, 0xe6, 0x85, 0x18, 0x39, +0x49, 0xe4, 0xb9, 0x5c, 0x0e, 0xfb, 0xf7, 0xef, +0xc7, 0xf2, 0xf2, 0xb2, 0x0f, 0x87, 0x6c, 0xe5, +0xc4, 0xc4, 0x49, 0xba, 0xf7, 0x3c, 0xcf, 0x77, +0x36, 0x25, 0xfb, 0x3b, 0x8d, 0x6b, 0x79, 0xb5, +0x84, 0xef, 0xcc, 0x9f, 0xc3, 0x53, 0xa9, 0x51, +0x9c, 0x07, 0xec, 0x4c, 0x93, 0xde, 0x6b, 0xf6, +0x3e, 0x5e, 0x47, 0xb6, 0xa5, 0x62, 0xda, 0x38, +0x09, 0x9e, 0xc9, 0x01, 0x28, 0xaa, 0x94, 0x21, +0xfb, 0xe0, 0x9e, 0xe0, 0xbc, 0x2f, 0x7a, 0xa7, +0x6d, 0xd6, 0x1c, 0x3f, 0x1b, 0x33, 0x93, 0x85, +0x4b, 0xb8, 0xb6, 0x62, 0x93, 0x20, 0x4d, 0x92, +0x1f, 0x1f, 0x0f, 0x7d, 0x37, 0x31, 0x72, 0x6d, +0x0c, 0x1a, 0xde, 0x61, 0x74, 0xb0, 0x31, 0x4b, +0x49, 0x1f, 0x8d, 0xfe, 0x9a, 0x86, 0x41, 0xe2, +0x10, 0x65, 0x7e, 0x4c, 0xf4, 0x96, 0x8c, 0xc9, +0xa4, 0x05, 0x91, 0x87, 0x0d, 0x49, 0x2b, 0x1b, +0x7d, 0x25, 0xce, 0x51, 0x0e, 0x2a, 0x26, 0xf8, +0xb6, 0x43, 0x04, 0xad, 0x7f, 0xed, 0x7d, 0x54, +0x13, 0x10, 0xa7, 0x83, 0x36, 0xaf, 0x1a, 0xfe, +0x0c, 0x8e, 0xcf, 0xcc, 0xbd, 0x38, 0x40, 0xa8, +0x98, 0x18, 0xa4, 0x49, 0x6d, 0x2e, 0x8b, 0x49, +0x2a, 0x35, 0xc1, 0x33, 0xd9, 0x56, 0xa5, 0x77, +0x7b, 0x98, 0x5a, 0x95, 0x3e, 0xdb, 0x54, 0xbf, +0x26, 0x49, 0x35, 0x4c, 0xda, 0x94, 0xe3, 0xd2, +0x8a, 0xcd, 0x36, 0x1f, 0xf6, 0x5e, 0x3a, 0xa6, +0x49, 0x67, 0x36, 0x0e, 0x43, 0x7a, 0xa4, 0x53, +0x5d, 0x53, 0x9a, 0x56, 0x5e, 0x07, 0xb0, 0xdf, +0x9e, 0x66, 0xf3, 0x07, 0xb0, 0x49, 0xd9, 0x51, +0x4c, 0x16, 0x1a, 0x03, 0x0f, 0xb3, 0x8d, 0xdb, +0xb4, 0x23, 0xa6, 0x03, 0x9c, 0xe6, 0xdb, 0xc1, +0x69, 0x23, 0x43, 0xf5, 0x00, 0x04, 0xd4, 0xe6, +0xf2, 0x3f, 0x15, 0x99, 0xfc, 0x87, 0x67, 0x82, +0x3b, 0x79, 0xf2, 0x24, 0x72, 0xb9, 0x9c, 0xcf, +0x7c, 0x67, 0x66, 0x66, 0x30, 0x38, 0x38, 0x88, +0xa1, 0xa1, 0x21, 0xcc, 0xcc, 0xcc, 0xf8, 0xaa, +0xf5, 0x99, 0x99, 0x19, 0x3f, 0x4c, 0x71, 0x62, +0x62, 0xc2, 0x67, 0xe4, 0xc4, 0xc4, 0x79, 0xd6, +0xb8, 0xa9, 0xa9, 0x29, 0x94, 0xcb, 0xe5, 0x80, +0x2a, 0x9e, 0xc2, 0x1b, 0xa9, 0xde, 0xd2, 0xd2, +0x12, 0x62, 0x4e, 0x0a, 0xb9, 0xe1, 0x61, 0xbc, +0xb6, 0x2f, 0x8d, 0x0f, 0xaf, 0xa6, 0x3a, 0x25, +0x02, 0xd3, 0x26, 0xa9, 0xa9, 0xf4, 0x6c, 0x1b, +0x9b, 0xe9, 0x3f, 0xb7, 0x59, 0x6a, 0x30, 0x4c, +0xff, 0x4d, 0x52, 0x8b, 0xdc, 0xe0, 0xf9, 0x3b, +0x40, 0xb7, 0x91, 0x46, 0x95, 0xba, 0x6c, 0x52, +0xaf, 0x89, 0x5e, 0xdd, 0x4a, 0xa2, 0x9a, 0xf6, +0x82, 0xe8, 0xad, 0x69, 0x01, 0x6c, 0xf4, 0xb6, +0xc1, 0xa6, 0xff, 0x52, 0x12, 0x35, 0xd1, 0x3e, +0x4a, 0x3f, 0x54, 0xa2, 0x6a, 0x08, 0xc2, 0xe6, +0x47, 0xd2, 0xd7, 0x36, 0x57, 0x36, 0x5a, 0x52, +0x7d, 0x7a, 0x1f, 0x95, 0xbe, 0xda, 0xfc, 0xf2, +0xbe, 0xc3, 0xb4, 0x56, 0x61, 0xfd, 0x6b, 0xea, +0x7e, 0xad, 0xff, 0xb0, 0x79, 0xe5, 0xef, 0x4d, +0xeb, 0x3b, 0x44, 0x7b, 0xe0, 0x34, 0xaa, 0x22, +0xc6, 0xd6, 0xa2, 0x96, 0xd5, 0x9e, 0x85, 0x6d, +0xfc, 0x26, 0xb5, 0xb7, 0x2c, 0x1a, 0x7c, 0xf2, +0x2e, 0xe6, 0x5e, 0xc6, 0xbc, 0x8e, 0xd4, 0x0c, +0x44, 0xf1, 0x74, 0x36, 0x49, 0x73, 0x26, 0x15, +0xb1, 0x36, 0x2e, 0xd9, 0x97, 0xcd, 0x8e, 0x6d, +0xb3, 0x0d, 0x73, 0xbc, 0x80, 0xa0, 0xf4, 0x6c, +0xf2, 0x2d, 0x30, 0x31, 0x2d, 0x39, 0x3e, 0x6d, +0x3c, 0x72, 0xfc, 0x52, 0x0a, 0x37, 0x31, 0x5f, +0x93, 0x34, 0x6d, 0x92, 0x7a, 0x65, 0x31, 0xdd, +0xda, 0x16, 0x66, 0xbe, 0xd0, 0x70, 0x31, 0x8d, +0x5d, 0x6b, 0xaf, 0xd9, 0xea, 0x89, 0x09, 0xf3, +0xb6, 0xb4, 0xbe, 0x38, 0x43, 0xe7, 0xef, 0xa4, +0x44, 0x4e, 0x49, 0x66, 0x48, 0x9d, 0x4e, 0x9a, +0x92, 0xc1, 0xc1, 0x41, 0x94, 0x4a, 0x25, 0xcc, +0xcf, 0xcf, 0xfb, 0x57, 0xa0, 0xce, 0xce, 0xce, +0x62, 0x74, 0x74, 0x14, 0x9e, 0xb7, 0xee, 0xb5, +0x4e, 0x12, 0x38, 0x49, 0xda, 0xc4, 0xc8, 0xc9, +0xae, 0x4e, 0x4e, 0x70, 0x33, 0x33, 0x33, 0xbe, +0x63, 0x1c, 0x25, 0x99, 0x39, 0x72, 0xe4, 0x48, +0xc0, 0xa6, 0x7e, 0xe0, 0xc0, 0x01, 0x9f, 0xbe, +0x63, 0xf9, 0x0b, 0x80, 0xbb, 0x03, 0x1f, 0x5e, +0x30, 0x48, 0x42, 0x61, 0x1b, 0x2a, 0x3d, 0x37, +0x49, 0x3d, 0x36, 0x55, 0x6f, 0x98, 0x94, 0x6a, +0x83, 0x6d, 0x92, 0x78, 0x34, 0x1c, 0x80, 0xce, +0x30, 0x24, 0xd3, 0x58, 0x4c, 0xfd, 0xf2, 0xe7, +0x32, 0x3e, 0x59, 0xa3, 0x97, 0x49, 0xbd, 0x69, +0x63, 0x7e, 0xfc, 0xbd, 0x64, 0x2a, 0xb4, 0xf1, +0x47, 0xd1, 0x56, 0xd8, 0x0e, 0x10, 0xb2, 0x9d, +0x94, 0xf4, 0x79, 0x7b, 0xed, 0xbb, 0x8d, 0xce, +0x51, 0xcc, 0x15, 0x1a, 0x7c, 0x39, 0x3f, 0x5a, +0x9b, 0x30, 0x09, 0xd8, 0xd4, 0xbf, 0x49, 0x63, +0xd0, 0x2d, 0x7d, 0x4d, 0x74, 0x88, 0x7a, 0xf8, +0xd4, 0x34, 0x16, 0x72, 0x8e, 0xb8, 0x46, 0x22, +0xea, 0xc1, 0x81, 0x9e, 0x6b, 0xeb, 0xdb, 0x44, +0x27, 0x4e, 0xf6, 0x6d, 0x37, 0xdc, 0x76, 0x77, +0xff, 0xca, 0x59, 0x00, 0xeb, 0x9b, 0x9f, 0xe3, +0x38, 0xfe, 0x1f, 0x00, 0xff, 0x59, 0xbd, 0x5e, +0x87, 0xe3, 0x38, 0x81, 0xcd, 0xb1, 0x5e, 0x5f, +0xbf, 0x63, 0x99, 0xd7, 0xa1, 0x76, 0x8b, 0x8b, +0x8b, 0xfe, 0x73, 0x0e, 0x9b, 0x3e, 0x03, 0x40, +0xbd, 0x5e, 0xef, 0x60, 0x3e, 0x9e, 0xe7, 0x05, +0x70, 0x70, 0x1c, 0x07, 0xb1, 0x58, 0x0c, 0xf5, +0x7a, 0x3d, 0x00, 0xab, 0x5c, 0x2e, 0xfb, 0x7d, +0xd2, 0x3b, 0x8e, 0x0b, 0x7f, 0xc7, 0x19, 0x1d, +0xc7, 0x91, 0xfe, 0x67, 0xb3, 0x59, 0xbf, 0xbd, +0x36, 0x2e, 0x2a, 0x9c, 0x09, 0x71, 0xdc, 0xf9, +0x67, 0x82, 0xc7, 0x9f, 0x13, 0x2e, 0x8e, 0xe3, +0x04, 0xfa, 0xa2, 0x42, 0x74, 0xa5, 0x77, 0xbc, +0x4d, 0x36, 0x9b, 0xf5, 0x69, 0x4f, 0x38, 0x39, +0x8e, 0x83, 0x7c, 0x3e, 0x1f, 0xc0, 0x99, 0xc6, +0x45, 0xf5, 0xa9, 0x14, 0x0a, 0x05, 0xff, 0x39, +0x1f, 0x1f, 0xa7, 0x8f, 0x2c, 0x9c, 0xfe, 0x9c, +0xb6, 0xf4, 0x8e, 0xaf, 0x0d, 0xbe, 0x16, 0xf8, +0x1c, 0xf0, 0x3a, 0x92, 0x96, 0x72, 0xae, 0xe4, +0x7a, 0xe2, 0xf8, 0x11, 0x4d, 0x38, 0x0d, 0xf9, +0xdc, 0xf3, 0xb5, 0x23, 0xc7, 0xc4, 0xd7, 0xac, +0x84, 0x5b, 0xaf, 0xd7, 0x11, 0x8b, 0xc5, 0x00, +0x74, 0x4a, 0xe2, 0xb2, 0xee, 0xd0, 0xd0, 0x10, +0x3c, 0xcf, 0x43, 0xb1, 0x58, 0x44, 0x26, 0x93, +0x81, 0xe7, 0x79, 0x38, 0x7f, 0xbe, 0x7d, 0x2f, +0xe9, 0x96, 0x2d, 0x5b, 0x00, 0xac, 0x5f, 0x83, +0xda, 0xdf, 0xdf, 0x8f, 0xd9, 0xd9, 0x59, 0x6c, +0xd9, 0xb2, 0xc5, 0xcf, 0xd3, 0x7e, 0xfa, 0xf4, +0x69, 0x8c, 0x8c, 0x8c, 0x60, 0xdf, 0xbe, 0x7d, +0x98, 0x9d, 0x9d, 0x45, 0xbd, 0x5e, 0xc7, 0xd4, +0xd4, 0x14, 0xea, 0xf5, 0x3a, 0x1e, 0x7f, 0xfc, +0x71, 0xd4, 0xeb, 0x75, 0x5c, 0x73, 0xcd, 0x35, +0x28, 0x95, 0x4a, 0x78, 0xea, 0xa9, 0xa7, 0x90, +0xcd, 0x66, 0x71, 0xcd, 0x35, 0xd7, 0x60, 0x64, +0x64, 0x04, 0xc7, 0x8e, 0x1d, 0xc3, 0x53, 0x4f, +0x3d, 0x85, 0x64, 0x32, 0x89, 0x7d, 0xfb, 0xf6, +0xf9, 0x76, 0xf5, 0x91, 0x91, 0x11, 0x5f, 0xf3, +0x92, 0xcd, 0x66, 0xb1, 0x3f, 0x13, 0xc7, 0x89, +0x6a, 0x02, 0xa7, 0x4a, 0x0d, 0x64, 0x53, 0x0e, +0xaa, 0x8d, 0x26, 0xd0, 0x6c, 0xb6, 0x07, 0xd2, +0x6c, 0xae, 0xff, 0xf1, 0xcd, 0x84, 0xbf, 0xa3, +0xcf, 0x4e, 0x12, 0x88, 0xaf, 0x6d, 0x48, 0xa6, +0xfa, 0x54, 0xa8, 0x3e, 0xdf, 0x6c, 0xe2, 0x89, +0x4e, 0x78, 0xd4, 0x87, 0x84, 0xad, 0x7d, 0x97, +0x6d, 0xe4, 0x73, 0x8e, 0x33, 0x6f, 0x4f, 0x78, +0xf0, 0xe7, 0xcd, 0x66, 0x10, 0x1f, 0xfa, 0xec, +0x24, 0x01, 0xc7, 0xe9, 0xec, 0x97, 0x8f, 0x47, +0x6b, 0x27, 0x69, 0xc8, 0xe1, 0xcb, 0xe7, 0x1a, +0x6d, 0x25, 0x0e, 0xda, 0xe6, 0xae, 0xb5, 0x69, +0x36, 0xf5, 0xcf, 0xda, 0xbc, 0x98, 0xe8, 0xa7, +0xcd, 0xa9, 0x1c, 0x97, 0x84, 0x11, 0x76, 0xe8, +0x90, 0xf0, 0x39, 0x3d, 0xb4, 0x75, 0xa1, 0xb5, +0x33, 0xf5, 0x4f, 0xb4, 0xd2, 0xd6, 0x93, 0x36, +0x1f, 0x92, 0xbe, 0x1a, 0xad, 0x25, 0x0d, 0x6d, +0xf4, 0xee, 0xa5, 0x7f, 0x0e, 0x53, 0xb6, 0x37, +0xf5, 0x67, 0xa2, 0x9f, 0xc4, 0xc5, 0xf4, 0x5b, +0x6d, 0x36, 0xdb, 0x6a, 0x76, 0x93, 0x9a, 0x3b, +0x8a, 0xe4, 0xc4, 0xa5, 0x49, 0xa9, 0xbe, 0xe5, +0x0e, 0x40, 0xb4, 0x99, 0xda, 0xe2, 0x9b, 0xa5, +0xa4, 0x45, 0x92, 0x12, 0xdd, 0x0d, 0x4d, 0x38, +0x85, 0x39, 0xa6, 0xd9, 0xea, 0xd9, 0xa4, 0x39, +0x4d, 0x85, 0x1c, 0x45, 0xf2, 0xe4, 0xcf, 0xc3, +0xb4, 0x0f, 0x36, 0x87, 0x3e, 0x93, 0x43, 0x1a, +0xd1, 0x56, 0x93, 0x70, 0x39, 0x5d, 0xa5, 0x03, +0x5d, 0x98, 0xc4, 0x6d, 0x1a, 0x7f, 0x98, 0x93, +0xa1, 0x6d, 0xfc, 0x9a, 0x6d, 0xdd, 0xd6, 0x6f, +0x94, 0x79, 0x09, 0xa3, 0xab, 0x0d, 0x96, 0xc9, +0xa7, 0x41, 0xd3, 0x38, 0xf1, 0x75, 0x56, 0x2a, +0x95, 0xfc, 0xef, 0x94, 0xaa, 0x55, 0x7e, 0x96, +0x57, 0xa2, 0x2e, 0x2f, 0x2f, 0xfb, 0xe9, 0x5d, +0x67, 0x66, 0x66, 0x30, 0x36, 0x36, 0x86, 0xa1, +0xa1, 0x21, 0x3f, 0x74, 0x93, 0x24, 0xf2, 0xd9, +0xd9, 0x59, 0xdf, 0xa1, 0x6d, 0x69, 0x69, 0x09, +0x4f, 0x3d, 0xf5, 0x14, 0x3c, 0xcf, 0xc3, 0xc4, +0xc4, 0x84, 0xef, 0x54, 0x3a, 0x31, 0x31, 0x81, +0x3d, 0x7b, 0xf6, 0x74, 0xc4, 0xab, 0x93, 0xea, +0x9d, 0xa4, 0x76, 0x8e, 0x27, 0x39, 0x52, 0xfe, +0xab, 0xa1, 0x1c, 0x9e, 0x5d, 0xcd, 0x62, 0xa1, +0x54, 0x0f, 0x97, 0xaa, 0xe4, 0x73, 0x93, 0xd3, +0x8e, 0xa9, 0xbe, 0x7c, 0xc7, 0xbf, 0x9b, 0x24, +0xb2, 0x6e, 0xdb, 0xda, 0xd4, 0xf2, 0xf2, 0x7b, +0x37, 0x9f, 0x6d, 0x36, 0x50, 0x4d, 0xbd, 0x69, +0xd3, 0x60, 0x98, 0xec, 0xb2, 0x1c, 0xb6, 0x56, +0xdf, 0x64, 0x4f, 0xd6, 0xda, 0x85, 0xf5, 0x6d, +0x33, 0x15, 0x98, 0xfa, 0x92, 0xf6, 0xea, 0x30, +0xed, 0x8a, 0x6d, 0x7c, 0x61, 0xed, 0xc2, 0x6c, +0xce, 0x61, 0x78, 0xdb, 0x34, 0x0a, 0x51, 0xcc, +0x45, 0xdd, 0xf6, 0x6f, 0x93, 0xc0, 0x35, 0x3a, +0x87, 0xf5, 0x6f, 0xa2, 0x4d, 0x18, 0xfd, 0x6c, +0xbe, 0x0f, 0x6c, 0x5d, 0x26, 0x76, 0xde, 0xfc, +0xaa, 0xbb, 0x07, 0x8b, 0x8b, 0xfe, 0x06, 0x57, +0x28, 0x14, 0x02, 0x12, 0x26, 0xd0, 0xde, 0x48, +0x47, 0x46, 0x46, 0x50, 0xaf, 0xd7, 0x3b, 0xa4, +0xcd, 0x6c, 0x36, 0x8b, 0x42, 0xa1, 0x10, 0x90, +0x22, 0x7d, 0x1c, 0xd6, 0x3e, 0x17, 0x0a, 0x05, +0x9f, 0x89, 0x93, 0x74, 0x45, 0x52, 0x53, 0x36, +0x9b, 0x0d, 0x48, 0xca, 0x24, 0x51, 0xba, 0xae, +0xeb, 0x3f, 0xeb, 0xef, 0xef, 0xf7, 0x25, 0x31, +0x2e, 0x9d, 0xd3, 0x1f, 0x97, 0xc8, 0x34, 0xe9, +0x91, 0xea, 0x70, 0x49, 0x51, 0xd6, 0xe5, 0x92, +0x3e, 0x6f, 0x2f, 0xa5, 0x47, 0x4d, 0x8a, 0xe5, +0x92, 0x3f, 0xd5, 0x21, 0x49, 0x89, 0x17, 0x4e, +0x53, 0x93, 0xa4, 0xca, 0xdb, 0x10, 0x4c, 0xd9, +0x4e, 0x4a, 0xd5, 0x5c, 0xf2, 0xa5, 0x7e, 0x88, +0xa1, 0x52, 0x5d, 0x92, 0xf8, 0x49, 0x42, 0x27, +0x7a, 0xf0, 0xb1, 0x70, 0xed, 0x05, 0xa7, 0x27, +0xcd, 0x2d, 0x1f, 0xa3, 0x49, 0x42, 0x96, 0xf8, +0x71, 0xfc, 0xe5, 0x98, 0x25, 0xfd, 0x35, 0xe9, +0x9c, 0xaf, 0x8b, 0xc5, 0xc5, 0x45, 0xff, 0x19, +0xd7, 0x0c, 0x49, 0x2d, 0x84, 0xd4, 0x50, 0xc8, +0xb9, 0xe2, 0x34, 0x23, 0x7a, 0x90, 0xf4, 0x5e, +0x2a, 0x95, 0x50, 0xaf, 0xd7, 0x7d, 0x06, 0x59, +0x2a, 0x95, 0xe0, 0x38, 0x8e, 0xea, 0xfc, 0xe6, +0x38, 0x8e, 0xff, 0xbb, 0x58, 0x5e, 0x5e, 0xc6, +0xe0, 0xe0, 0x20, 0x92, 0xc9, 0xa4, 0xaf, 0x76, +0x1f, 0x19, 0x19, 0xc1, 0xca, 0xca, 0x8a, 0x1f, +0x83, 0x7e, 0xcd, 0x35, 0xd7, 0xf8, 0x1e, 0xeb, +0xfb, 0xf6, 0xed, 0x43, 0xbd, 0x5e, 0xc7, 0xb3, +0xcf, 0x3e, 0x0b, 0xc7, 0x71, 0x7c, 0xfb, 0x39, +0xbd, 0x23, 0xc9, 0x9e, 0x18, 0xff, 0xa1, 0x43, +0x87, 0x90, 0xcd, 0x66, 0x31, 0x3b, 0x3b, 0x8b, +0xe9, 0xe9, 0x69, 0x9c, 0x3e, 0x7d, 0x1a, 0x8b, +0x8b, 0x8b, 0x88, 0xc5, 0x62, 0x48, 0x24, 0x12, +0x48, 0x26, 0xdb, 0x3f, 0xf4, 0xc5, 0xc5, 0x45, +0x54, 0x57, 0x8b, 0x88, 0xf7, 0x0d, 0xe0, 0x64, +0xd3, 0x45, 0xb5, 0x15, 0xd3, 0xa5, 0x35, 0x29, +0x39, 0x6a, 0x52, 0x29, 0x6d, 0x18, 0xb6, 0xfa, +0xa6, 0xf7, 0x1a, 0x5c, 0x5b, 0x3b, 0x4d, 0x1a, +0x97, 0x12, 0x8c, 0xd6, 0x17, 0xdf, 0xf0, 0xa2, +0xc0, 0xb5, 0x8d, 0x29, 0xca, 0x3b, 0x29, 0xd9, +0x69, 0xf5, 0xe3, 0x09, 0x7d, 0x33, 0xef, 0x86, +0x6e, 0x04, 0xc7, 0x24, 0x8d, 0xf3, 0xf1, 0x4b, +0x1a, 0x6b, 0xef, 0xb9, 0x64, 0x69, 0xd2, 0x7c, +0x84, 0xb5, 0x0b, 0x93, 0x68, 0xa3, 0xae, 0x95, +0x30, 0x9a, 0xda, 0xfa, 0x37, 0xb5, 0x37, 0xf5, +0x65, 0x1b, 0x73, 0x58, 0xff, 0x5a, 0x5b, 0xa9, +0x01, 0x31, 0x69, 0xa0, 0xc2, 0xfa, 0xb7, 0xad, +0x3d, 0xf9, 0x59, 0x6a, 0x15, 0x0c, 0xbf, 0x11, +0xc7, 0x89, 0xc7, 0x54, 0x27, 0x30, 0x93, 0x8d, +0x54, 0x7a, 0x14, 0xcb, 0xf7, 0x9a, 0x04, 0xc5, +0xdb, 0x48, 0x89, 0x59, 0x26, 0x3f, 0xe1, 0xe1, +0x3f, 0x74, 0x13, 0x15, 0xc1, 0xa4, 0x0d, 0x56, +0x93, 0x10, 0x4d, 0x76, 0x6a, 0x53, 0x3d, 0x9b, +0x97, 0x73, 0x14, 0x47, 0x35, 0xd3, 0x7b, 0x00, +0xbe, 0x74, 0x66, 0xf3, 0xf2, 0x36, 0x15, 0x92, +0xb2, 0x01, 0xf3, 0x05, 0x2b, 0x72, 0x9c, 0xe4, +0xe1, 0xce, 0x2f, 0xe9, 0x90, 0x73, 0xa6, 0x49, +0xe8, 0xb2, 0x84, 0xd1, 0xcd, 0xe6, 0x81, 0xae, +0x69, 0x15, 0xa8, 0x0d, 0x77, 0xce, 0x0b, 0xd3, +0x00, 0xd8, 0xe8, 0x62, 0x8a, 0x9c, 0xd0, 0x7c, +0x25, 0x4c, 0x78, 0xca, 0xcf, 0xd4, 0x86, 0xaf, +0x3b, 0x7e, 0x95, 0x29, 0x10, 0x5c, 0x77, 0xc4, +0xc8, 0xc9, 0xab, 0xbc, 0x5c, 0x2e, 0xfb, 0x8c, +0x9c, 0x6c, 0xe4, 0x40, 0x3b, 0xe6, 0x9c, 0x87, +0xa5, 0x1d, 0x3a, 0x74, 0x08, 0x4b, 0x4b, 0x4b, +0x00, 0x80, 0xc3, 0x87, 0x0f, 0xfb, 0xb1, 0xe7, +0x94, 0x16, 0x76, 0x61, 0x61, 0xc1, 0xb7, 0x9f, +0x93, 0x03, 0x1d, 0x5d, 0xe4, 0x32, 0x39, 0x39, +0x19, 0x48, 0xf5, 0x9a, 0xcb, 0xe5, 0x7c, 0xbb, +0xba, 0x16, 0xf5, 0x50, 0x2e, 0x97, 0xe1, 0xa2, +0x85, 0x27, 0x4b, 0xab, 0x78, 0xbc, 0x9e, 0xd2, +0x09, 0x2a, 0x4f, 0xfa, 0x26, 0x09, 0xd1, 0xe4, +0x38, 0x16, 0x26, 0x99, 0x46, 0xad, 0x1f, 0x26, +0x35, 0x99, 0xda, 0x44, 0x75, 0x9a, 0xb2, 0xd9, +0x3e, 0x4d, 0xef, 0x88, 0x2e, 0x8d, 0x46, 0xd0, +0xc3, 0xdd, 0x56, 0xdf, 0x24, 0x55, 0x9a, 0x0a, +0xd5, 0xd3, 0xee, 0xc2, 0x96, 0xc5, 0xa6, 0x5d, +0x89, 0x4a, 0xfb, 0xb0, 0x39, 0xd5, 0xfa, 0x32, +0x49, 0x90, 0x61, 0x36, 0xe3, 0x28, 0x12, 0xb0, +0x86, 0xbb, 0xad, 0x7f, 0xdb, 0x9a, 0x88, 0x2a, +0x99, 0xdb, 0xe6, 0x21, 0x6c, 0xae, 0x4c, 0x70, +0xba, 0xed, 0x3f, 0x0a, 0x7e, 0x36, 0xed, 0x80, +0x65, 0x0e, 0x12, 0xe3, 0x37, 0xdd, 0x71, 0x77, +0x66, 0x79, 0xbe, 0x43, 0x72, 0xe3, 0x12, 0x8d, +0xb4, 0x5d, 0xd3, 0x7b, 0xaa, 0x0b, 0xb4, 0xa5, +0xef, 0x6c, 0x36, 0xeb, 0x6f, 0x2e, 0x5c, 0xca, +0x25, 0x49, 0x4b, 0x4a, 0xef, 0xf2, 0x3d, 0x85, +0xe0, 0xa4, 0xd3, 0x69, 0x94, 0xcb, 0x65, 0xb4, +0x5a, 0xed, 0x30, 0x39, 0x92, 0xcc, 0x1d, 0xc7, +0xc1, 0xf2, 0xf2, 0xb2, 0x2f, 0xd5, 0x71, 0xa9, +0x8a, 0x4b, 0xce, 0x9a, 0x8a, 0x5d, 0x93, 0x32, +0x35, 0x3b, 0x2f, 0xc7, 0x95, 0xbe, 0xdb, 0x6c, +0xc7, 0xb2, 0xf0, 0xfb, 0xc3, 0xe5, 0x38, 0x25, +0x0d, 0x09, 0x9e, 0xc4, 0x43, 0x93, 0x5c, 0xa5, +0x36, 0x43, 0x4a, 0xbf, 0x72, 0x0c, 0xdc, 0xff, +0x21, 0xcc, 0xd6, 0x4c, 0x45, 0x4a, 0xdd, 0x12, +0x77, 0x2e, 0x0d, 0xf3, 0x3f, 0xd9, 0x87, 0x1c, +0x3f, 0xff, 0xae, 0xd9, 0xc4, 0xf9, 0x3b, 0x6e, +0x3f, 0x97, 0xb0, 0x4c, 0xda, 0x18, 0xee, 0x4b, +0x20, 0xed, 0xf5, 0xf2, 0x3d, 0x2f, 0xbc, 0x0f, +0xde, 0xff, 0xd0, 0xd0, 0x10, 0x56, 0x56, 0x56, +0x00, 0xb4, 0xaf, 0x33, 0xad, 0xd7, 0xeb, 0x28, +0x95, 0x4a, 0x01, 0x3f, 0x0e, 0xa2, 0xef, 0xf9, +0xf3, 0xe7, 0x7d, 0x46, 0x3e, 0x3f, 0x3f, 0x8f, +0x7a, 0xbd, 0x8e, 0xc9, 0xc9, 0x49, 0x14, 0x8b, +0x45, 0x94, 0xcb, 0x65, 0x14, 0x0a, 0x05, 0x5c, +0x71, 0xc5, 0x15, 0xbe, 0xf4, 0x3e, 0x36, 0x36, +0x86, 0x7a, 0xbd, 0x8e, 0xe9, 0xe9, 0x69, 0x78, +0x9e, 0x87, 0x9d, 0x3b, 0x77, 0xe2, 0xcc, 0x99, +0x33, 0xf0, 0xbc, 0xf6, 0xd5, 0xa7, 0xf5, 0x7a, +0x1d, 0x0f, 0x3f, 0xfc, 0x30, 0xf2, 0xf9, 0x3c, +0x76, 0xee, 0xdc, 0x89, 0xc9, 0xc9, 0x49, 0xcc, +0xcd, 0xcd, 0xf9, 0xaa, 0xf8, 0x7d, 0xfb, 0xf6, +0x61, 0x64, 0x64, 0xc4, 0xcf, 0x10, 0x37, 0xb4, +0x75, 0x1b, 0xca, 0xab, 0x45, 0xcc, 0xce, 0xce, +0x62, 0x66, 0x66, 0xc6, 0xff, 0xc3, 0xca, 0x12, +0xf6, 0x6c, 0x19, 0xc0, 0x6a, 0xdf, 0x30, 0xe6, +0xca, 0x0d, 0xb3, 0xcd, 0xba, 0x56, 0x03, 0x52, +0x6e, 0xb8, 0x84, 0x41, 0xcf, 0x01, 0xdd, 0xfe, +0x27, 0x6d, 0x88, 0xbc, 0xbe, 0x4d, 0xfa, 0x95, +0x12, 0xa3, 0x94, 0x92, 0x08, 0x3f, 0xd9, 0x97, +0xd4, 0x1c, 0xc8, 0x7e, 0xa4, 0xa4, 0xac, 0xd9, +0x32, 0x6d, 0x3e, 0x00, 0xcd, 0x66, 0x90, 0x2e, +0x26, 0xbb, 0x6a, 0xd8, 0x38, 0x25, 0x3e, 0x72, +0x1c, 0x64, 0xb3, 0x97, 0x74, 0x31, 0xd8, 0x45, +0x3b, 0xe6, 0xcb, 0xd6, 0xc6, 0x44, 0x73, 0x1b, +0x3e, 0x92, 0x81, 0xda, 0x60, 0xd3, 0xfc, 0xd5, +0x6a, 0x00, 0x5a, 0x9d, 0x74, 0x91, 0xf0, 0x38, +0x0c, 0x13, 0x4e, 0xa6, 0xfe, 0x25, 0x1c, 0xde, +0x7f, 0xa5, 0x0c, 0xc4, 0xe3, 0xba, 0xb6, 0x46, +0xce, 0xaf, 0x69, 0x3d, 0xc9, 0xf5, 0x68, 0x5a, +0x27, 0xda, 0xfa, 0xe5, 0xfd, 0x4b, 0xad, 0x91, +0x89, 0x66, 0x61, 0x36, 0x74, 0xd9, 0xde, 0x34, +0x1e, 0x86, 0x4b, 0xdc, 0x89, 0xb7, 0x9d, 0x7f, +0x3c, 0xcf, 0x43, 0xb9, 0x69, 0xce, 0x77, 0x2e, +0x25, 0x28, 0xee, 0x11, 0x2c, 0xb3, 0xc7, 0xc9, +0x12, 0x66, 0x37, 0x25, 0x09, 0x3d, 0x9f, 0xcf, +0xa3, 0x52, 0xa9, 0xa0, 0x54, 0x2a, 0xf9, 0xd2, +0x51, 0x3a, 0x9d, 0x0e, 0x4a, 0x1c, 0xae, 0xab, +0xda, 0x63, 0xa3, 0x84, 0x38, 0x45, 0x95, 0xda, +0x34, 0x98, 0xda, 0x98, 0xa4, 0xa4, 0xa8, 0xd9, +0x61, 0x35, 0x89, 0x32, 0xcc, 0x13, 0x3b, 0x0a, +0xed, 0xb9, 0x77, 0xba, 0x26, 0x7d, 0x4b, 0x2f, +0x6e, 0x2d, 0xac, 0x90, 0x8f, 0xd3, 0x84, 0xa7, +0xa4, 0x53, 0x18, 0x4d, 0x34, 0xba, 0x9a, 0xc2, +0x04, 0xb5, 0xb9, 0xd2, 0xfa, 0xd2, 0xda, 0xdb, +0xa4, 0x71, 0x0d, 0x07, 0x6d, 0x3e, 0xe9, 0x19, +0x77, 0x7c, 0xa3, 0x83, 0x24, 0xff, 0x4c, 0x19, +0xdf, 0x78, 0x1d, 0x60, 0xdd, 0xd9, 0x8d, 0x2e, +0x55, 0x21, 0x69, 0x9d, 0x60, 0x93, 0x46, 0x22, +0x9d, 0x4e, 0xa3, 0x52, 0xa9, 0xf8, 0x69, 0x5d, +0xa7, 0xa7, 0xa7, 0x91, 0xcb, 0xe5, 0x30, 0x3a, +0x3a, 0xea, 0x4b, 0xf2, 0x74, 0x93, 0x1a, 0x65, +0x7a, 0x3b, 0x74, 0xe8, 0x90, 0x2f, 0xa1, 0x3f, +0xf5, 0xd4, 0x53, 0x7e, 0x5a, 0xd8, 0xa5, 0xa5, +0x25, 0x5f, 0x42, 0x9f, 0x9c, 0x9c, 0xc4, 0xd2, +0xb9, 0xb3, 0x7e, 0xb8, 0x9b, 0x97, 0xe9, 0xc7, +0xa1, 0x43, 0x87, 0x70, 0xf8, 0xf0, 0x61, 0x1c, +0x38, 0x70, 0x00, 0xaf, 0xdd, 0x31, 0x80, 0x5f, +0x9c, 0x88, 0xe1, 0xa6, 0x4c, 0xb3, 0x53, 0x3a, +0xe0, 0x9e, 0xc0, 0x95, 0x72, 0x67, 0xce, 0x70, +0x93, 0xc4, 0xe2, 0x24, 0xdb, 0x75, 0x79, 0x36, +0x36, 0x2a, 0x3c, 0xce, 0x96, 0xde, 0x53, 0x1b, +0xde, 0x9e, 0x4b, 0x27, 0x51, 0x25, 0xa8, 0x46, +0x43, 0xc7, 0x8d, 0x4b, 0xd2, 0x1a, 0xfe, 0x1a, +0xbe, 0xd2, 0xf6, 0xa8, 0xe1, 0x48, 0xfd, 0x49, +0x09, 0x50, 0x1b, 0x9f, 0x46, 0x23, 0x39, 0x3e, +0xad, 0xdf, 0x7a, 0x6d, 0x9d, 0xee, 0xa6, 0xf1, +0x99, 0x9e, 0x51, 0xbb, 0xa8, 0xf8, 0x99, 0x34, +0x16, 0xa6, 0x31, 0x9a, 0x24, 0x46, 0x89, 0x13, +0xcf, 0x9e, 0x27, 0xe7, 0x5c, 0xda, 0xba, 0x79, +0x1d, 0x9a, 0x17, 0xdb, 0x18, 0x6c, 0xf4, 0x90, +0xfd, 0xcb, 0xac, 0x7a, 0x1a, 0x03, 0xe6, 0x85, +0xe8, 0x6d, 0x5a, 0x8f, 0xa6, 0x75, 0xa2, 0xcd, +0x1f, 0x1f, 0xbf, 0x69, 0x3d, 0xf2, 0xcf, 0xf4, +0x3b, 0x91, 0x6b, 0xcc, 0xd6, 0x4e, 0xd2, 0x53, +0x99, 0xbb, 0x38, 0xc0, 0x18, 0x4e, 0xbc, 0xfd, +0x9c, 0x12, 0xc7, 0x44, 0xd9, 0xe0, 0xa5, 0x03, +0x96, 0xc6, 0x3c, 0x25, 0xf3, 0x90, 0x6a, 0x59, +0xfa, 0x3e, 0x3f, 0x3f, 0x8f, 0x99, 0x99, 0x19, +0xf5, 0x4a, 0x4a, 0x93, 0x8a, 0xd5, 0xf4, 0x9c, +0xb7, 0x35, 0xd5, 0x8f, 0xaa, 0x02, 0xd7, 0x0e, +0x0b, 0x36, 0x46, 0x67, 0x62, 0x30, 0xda, 0xf8, +0x6d, 0x87, 0x08, 0x8d, 0xf6, 0x9a, 0x89, 0x43, +0xde, 0x95, 0x2e, 0xe1, 0x9a, 0x70, 0xd4, 0xc2, +0xdf, 0x34, 0x1c, 0xc2, 0x68, 0x6b, 0x3b, 0x9c, +0x98, 0x0e, 0x45, 0x61, 0x0c, 0x3a, 0x0c, 0x86, +0xb6, 0x86, 0x4c, 0x78, 0xda, 0x92, 0x1b, 0xf1, +0x64, 0x31, 0x74, 0x70, 0xe4, 0x4e, 0x65, 0xa4, +0x6a, 0x97, 0x9e, 0xee, 0x95, 0x4a, 0x05, 0x83, +0x83, 0x83, 0xfe, 0x2d, 0x68, 0x32, 0x79, 0x0c, +0xfd, 0x26, 0x28, 0x5c, 0x8d, 0x4c, 0x46, 0xa4, +0x5a, 0x9f, 0x9c, 0x9c, 0xf4, 0x6d, 0xe9, 0x3c, +0x99, 0x0c, 0xc5, 0x9c, 0x03, 0xf0, 0x2f, 0x5f, +0xe1, 0xb7, 0xad, 0x55, 0x2a, 0x15, 0xff, 0xc0, +0xf0, 0xe0, 0x83, 0x0f, 0xe2, 0xe8, 0xd1, 0xa3, +0xc8, 0xe5, 0x72, 0xb8, 0xf3, 0xce, 0x3b, 0x71, +0xe8, 0xda, 0xab, 0xfd, 0xfe, 0x8f, 0x1d, 0x3b, +0x86, 0x23, 0x47, 0x8e, 0x60, 0xe5, 0xa9, 0x69, +0xbc, 0xcc, 0x2d, 0xeb, 0x1b, 0x05, 0x2f, 0xc4, +0xd4, 0x65, 0x3d, 0xb9, 0x21, 0xf2, 0x1c, 0xe3, +0xbc, 0x7e, 0xbd, 0x16, 0x8c, 0x71, 0xa6, 0xf7, +0xf4, 0x2e, 0x8c, 0x81, 0x9a, 0x1c, 0xad, 0x4c, +0x17, 0x88, 0x68, 0x38, 0x6a, 0xb0, 0x25, 0xbe, +0x5a, 0x5f, 0x9a, 0x2a, 0x54, 0x8e, 0x4f, 0x8e, +0x43, 0xe6, 0x84, 0x37, 0xd5, 0xe3, 0x45, 0xeb, +0x97, 0x8f, 0x4f, 0xe2, 0x2e, 0x99, 0x13, 0x9f, +0xa7, 0xa8, 0xf8, 0xc9, 0xfe, 0x6d, 0x78, 0x9a, +0x54, 0xdc, 0x26, 0x66, 0x4f, 0xfd, 0x70, 0x3a, +0x87, 0xb5, 0xe7, 0xf3, 0x60, 0xca, 0xe9, 0x2e, +0xdb, 0x85, 0xd1, 0x83, 0xc3, 0x0d, 0x53, 0xd1, +0x4b, 0xfa, 0xc9, 0x7a, 0xa6, 0x03, 0x61, 0xd8, +0x7c, 0x70, 0x5a, 0xd8, 0x54, 0xe9, 0xf2, 0x52, +0x1c, 0x6d, 0x7d, 0x98, 0x0e, 0x5a, 0xbc, 0x9e, +0xc4, 0x0d, 0x40, 0x3c, 0x91, 0x72, 0x3b, 0x18, +0x5c, 0x6a, 0x4d, 0x5a, 0xa7, 0x22, 0x25, 0x3e, +0x93, 0x2d, 0x98, 0xda, 0xdb, 0x8a, 0x26, 0xbd, +0xd2, 0x77, 0x62, 0xe8, 0xd3, 0xd3, 0xd3, 0x58, +0x58, 0x58, 0xf0, 0x6d, 0x93, 0xbc, 0x1f, 0x2e, +0xa9, 0x4b, 0xdc, 0xc2, 0xfa, 0x94, 0x45, 0xfa, +0x08, 0xd8, 0xea, 0x98, 0xf0, 0x35, 0x45, 0x02, +0xd0, 0x77, 0x8d, 0xe9, 0x45, 0x91, 0xf8, 0xb5, +0xc3, 0x8e, 0xb4, 0x89, 0x6b, 0x78, 0xda, 0x70, +0xe6, 0x6d, 0x35, 0xf8, 0xf4, 0xcc, 0x94, 0x1b, +0xde, 0x84, 0xab, 0x09, 0xbe, 0x3c, 0x44, 0x98, +0xde, 0xd9, 0x68, 0xc8, 0xfb, 0x31, 0x49, 0xf8, +0x36, 0xad, 0x83, 0x8d, 0xce, 0xc4, 0xc8, 0x01, +0xf8, 0xd7, 0x98, 0x92, 0x5d, 0x5b, 0x7a, 0xb9, +0x0f, 0x0d, 0x0d, 0x21, 0x9d, 0x4e, 0x07, 0x3c, +0xc7, 0x81, 0x60, 0x76, 0x3f, 0xd7, 0x75, 0x7d, +0x1f, 0x0f, 0x82, 0x4f, 0x07, 0xd3, 0x7c, 0x3e, +0xef, 0xdf, 0x73, 0x4e, 0x52, 0xb8, 0xe7, 0x79, +0xbe, 0x8d, 0x9c, 0x4b, 0xdb, 0xfc, 0x80, 0x30, +0x39, 0x39, 0x09, 0xd7, 0x75, 0x31, 0x33, 0x33, +0x83, 0xd1, 0xd1, 0x51, 0x8c, 0x8d, 0x8d, 0xf9, +0xaa, 0x74, 0xcf, 0xf3, 0xf0, 0x9a, 0xbb, 0xde, +0x80, 0x43, 0x87, 0x0e, 0xf9, 0x07, 0xe1, 0x13, +0x27, 0x4e, 0xf8, 0x38, 0x03, 0xc0, 0xdc, 0xdc, +0x1c, 0x86, 0x2e, 0x3c, 0x8f, 0x4c, 0x33, 0x82, +0xf7, 0xb4, 0x29, 0x9d, 0x24, 0x10, 0x64, 0xe4, +0x5c, 0x22, 0x91, 0x9b, 0x0a, 0x49, 0x1b, 0x72, +0xb3, 0xb2, 0x31, 0x0e, 0x5e, 0x4c, 0x87, 0x0d, +0x53, 0x3b, 0x4d, 0xea, 0x93, 0x63, 0x92, 0x9b, +0xad, 0x26, 0x61, 0x72, 0x78, 0x72, 0xac, 0xda, +0x06, 0x6f, 0xfa, 0xaf, 0xe1, 0xaf, 0x31, 0x03, +0x6d, 0x2e, 0xe4, 0x61, 0x43, 0x4a, 0x8a, 0xda, +0x7c, 0x85, 0xe1, 0x17, 0x76, 0x88, 0x33, 0x31, +0x4f, 0x49, 0xd7, 0x30, 0x9c, 0x39, 0x9d, 0x65, +0x5f, 0x7c, 0x6e, 0xf8, 0xa1, 0xaf, 0x22, 0x7e, +0x9f, 0x26, 0x1a, 0x4a, 0x7a, 0x98, 0xfc, 0x00, +0x5c, 0x3b, 0xef, 0xe9, 0xa8, 0x67, 0x62, 0xa6, +0x26, 0x1a, 0xd9, 0xfa, 0xd7, 0xc6, 0x43, 0x63, +0xe1, 0x75, 0x65, 0x96, 0x41, 0xd3, 0xfc, 0x50, +0x3f, 0x61, 0x1a, 0x20, 0x06, 0x3b, 0xce, 0x93, +0xc6, 0x50, 0x91, 0x92, 0xab, 0xa6, 0xc2, 0x05, +0x82, 0x19, 0xb1, 0x34, 0xc9, 0x5b, 0xdb, 0x54, +0x6d, 0xce, 0x75, 0xfc, 0x3b, 0x79, 0xf2, 0xf2, +0xd4, 0xa5, 0x26, 0xb5, 0xba, 0x84, 0xcd, 0xbf, +0xf3, 0x76, 0xda, 0x18, 0xc3, 0xc2, 0xad, 0x4c, +0x8c, 0xc6, 0xc6, 0xe4, 0x78, 0x7d, 0x53, 0x18, +0x94, 0x09, 0x47, 0xad, 0x4f, 0xe9, 0x94, 0xa8, +0xa9, 0xb1, 0x4d, 0xce, 0x7c, 0x36, 0x95, 0xb4, +0x09, 0x2f, 0x13, 0xce, 0x9a, 0x6a, 0xde, 0x36, +0x76, 0x6d, 0xee, 0x4d, 0xf5, 0x6c, 0x45, 0x9a, +0x02, 0x4c, 0xa6, 0x04, 0x09, 0x57, 0x73, 0xba, +0x93, 0x7d, 0x12, 0xb3, 0x4d, 0xa7, 0xd3, 0x3e, +0x23, 0x97, 0x52, 0xb9, 0xa4, 0x35, 0xb5, 0xa7, +0xc3, 0xe6, 0xe0, 0xe0, 0xa0, 0x7f, 0x30, 0x38, +0x79, 0xf2, 0x24, 0x80, 0xb6, 0xef, 0x04, 0x85, +0xae, 0x51, 0xda, 0x57, 0xf2, 0x07, 0xe1, 0xb7, +0xa4, 0x79, 0xde, 0x7a, 0xb2, 0x18, 0xba, 0x2a, +0x95, 0x18, 0x39, 0xe5, 0x6c, 0x5f, 0x58, 0x58, +0xc0, 0xd8, 0xd8, 0x18, 0x2a, 0x95, 0x0a, 0xa6, +0xa7, 0xa7, 0x31, 0x3f, 0x3f, 0x8f, 0x89, 0x89, +0x09, 0x1c, 0x3e, 0x7c, 0x18, 0xab, 0x17, 0x97, +0xf1, 0xe0, 0x83, 0x0f, 0x62, 0x6e, 0x6e, 0x0e, +0xb9, 0x5c, 0x0e, 0x37, 0xdc, 0x70, 0x03, 0x0e, +0x1d, 0x3a, 0x84, 0xa9, 0xa9, 0x29, 0x1c, 0x38, +0x70, 0x00, 0x07, 0x0e, 0x1c, 0xc0, 0xe4, 0x50, +0x06, 0x6f, 0xde, 0xaa, 0xa4, 0x2a, 0xe5, 0x4c, +0x0b, 0xe8, 0x94, 0x54, 0xa4, 0x64, 0xc1, 0x13, +0x61, 0xf0, 0xcd, 0x9b, 0xd7, 0x95, 0x92, 0xb4, +0x49, 0xd2, 0x31, 0xa9, 0x70, 0x35, 0x09, 0x24, +0x91, 0xe8, 0x54, 0xc9, 0xd2, 0x7b, 0xce, 0x00, +0x35, 0xc9, 0x50, 0x8e, 0x8f, 0xfe, 0x6b, 0x6a, +0x75, 0xa2, 0x87, 0x1c, 0x9f, 0xe9, 0xf0, 0xa0, +0xd1, 0x33, 0x4c, 0x32, 0x95, 0x0c, 0x4b, 0x93, +0xd4, 0x4c, 0xcc, 0x9f, 0xcf, 0x97, 0xa4, 0xbd, +0xc4, 0xcb, 0x24, 0xd9, 0xd9, 0x4c, 0x0b, 0x92, +0xee, 0x9c, 0xae, 0x5a, 0x1d, 0x4e, 0x27, 0x53, +0xc6, 0x33, 0x39, 0x37, 0x72, 0xdc, 0xa6, 0x35, +0x60, 0x52, 0x35, 0xcb, 0xf7, 0xfc, 0x52, 0x15, +0x4d, 0xb3, 0xa4, 0xd1, 0x87, 0xf0, 0xb5, 0xcd, +0x9f, 0x89, 0x36, 0x1a, 0x7e, 0x7c, 0x3c, 0x26, +0xfa, 0xcb, 0xfe, 0xc3, 0x34, 0x09, 0x9c, 0x6e, +0xb6, 0x71, 0xb1, 0x75, 0x12, 0xaf, 0x37, 0x5b, +0x70, 0x32, 0xfd, 0x01, 0xbc, 0xb4, 0x0d, 0x56, +0xe6, 0x4d, 0xd7, 0x18, 0x0e, 0x57, 0x69, 0x52, +0x1b, 0x93, 0x3d, 0x5d, 0x93, 0x34, 0x35, 0x95, +0xf2, 0xcc, 0xcc, 0x4c, 0xe0, 0xc6, 0x28, 0x5e, +0x6c, 0x8c, 0xc2, 0x74, 0x98, 0x30, 0xd5, 0xd7, +0xc6, 0x6f, 0x92, 0x3a, 0x4d, 0xe3, 0xd7, 0xfa, +0xb0, 0x1d, 0x24, 0x24, 0xed, 0x64, 0x3b, 0xa9, +0xee, 0xe6, 0xcf, 0x39, 0x3d, 0x38, 0xb3, 0xe2, +0x34, 0xd5, 0xee, 0x31, 0x37, 0x31, 0x59, 0x99, +0x22, 0x56, 0x2b, 0xfc, 0x80, 0xa0, 0x1d, 0xde, +0xa2, 0xd8, 0xd6, 0x6d, 0x5e, 0xf1, 0x61, 0xf3, +0xa0, 0xfd, 0x0f, 0x3b, 0x2c, 0x85, 0x1d, 0xda, +0xa4, 0xe7, 0x3a, 0x7d, 0x96, 0x8c, 0xdd, 0x84, +0x2f, 0x39, 0x3c, 0x2e, 0x2f, 0x2f, 0x07, 0x32, +0xb3, 0x11, 0x3c, 0x6e, 0x7e, 0xa2, 0x6c, 0x71, +0xd4, 0xce, 0xf3, 0x82, 0xf7, 0x9b, 0x73, 0x46, +0x3e, 0x39, 0x39, 0xe9, 0x87, 0xaa, 0x91, 0x5a, +0x9d, 0x0e, 0x01, 0xfb, 0xf7, 0xef, 0xc7, 0xf8, +0xf8, 0x38, 0x8e, 0x1d, 0x3b, 0x86, 0x99, 0x99, +0x19, 0xb8, 0xae, 0x8b, 0x1b, 0x6e, 0xb8, 0xc1, +0x8f, 0x41, 0x9f, 0x9e, 0x9e, 0xc6, 0xa3, 0x8f, +0x3e, 0xea, 0xc3, 0xbd, 0x7a, 0x72, 0x17, 0xbe, +0x7b, 0x4b, 0x03, 0x7b, 0x07, 0xd3, 0x9d, 0x9b, +0x81, 0x64, 0x0c, 0x5a, 0x91, 0x1b, 0x0d, 0x49, +0x6a, 0xd2, 0x56, 0x49, 0x36, 0xc3, 0x28, 0x19, +0xd5, 0xc2, 0xfa, 0xa0, 0xff, 0x36, 0xb5, 0x31, +0xc7, 0xc1, 0x04, 0x43, 0x8e, 0x4f, 0x32, 0x04, +0x29, 0x85, 0xf3, 0xfa, 0x94, 0x51, 0x8d, 0x4b, +0x47, 0x36, 0xc9, 0x37, 0x0a, 0xa3, 0x94, 0x75, +0xb5, 0xeb, 0x4b, 0xf9, 0x21, 0x42, 0x1e, 0x80, +0x34, 0x35, 0x3b, 0xd1, 0x5d, 0xc3, 0x4f, 0xa3, +0xa9, 0x46, 0xf3, 0x28, 0x1e, 0xdf, 0x36, 0x33, +0x86, 0xbc, 0xb9, 0xcd, 0x04, 0x9f, 0x33, 0x26, +0x93, 0x64, 0x2e, 0xe9, 0xab, 0x1d, 0xaa, 0xe8, +0x33, 0x1d, 0x30, 0xe5, 0x61, 0xd3, 0x74, 0x90, +0xa4, 0x94, 0xb7, 0xda, 0xba, 0x0f, 0xeb, 0xdf, +0x04, 0x4f, 0xa6, 0x71, 0xe5, 0xbe, 0x19, 0x92, +0x16, 0x36, 0x35, 0xbb, 0x2c, 0x92, 0xf1, 0x4b, +0x9f, 0x0f, 0xe1, 0x9b, 0x11, 0x77, 0xe2, 0x31, +0x38, 0x8d, 0x5a, 0x80, 0x19, 0x68, 0x39, 0xd1, +0x01, 0xfd, 0x8a, 0x4d, 0x93, 0x94, 0x67, 0xb3, +0x81, 0xca, 0x22, 0x19, 0x0f, 0x7f, 0x5e, 0x2e, +0xb7, 0x13, 0x64, 0xdc, 0x7b, 0xef, 0xbd, 0x78, +0xf0, 0xc1, 0x07, 0x31, 0x3d, 0x3d, 0x6d, 0x65, +0x1a, 0x1a, 0x1e, 0x9a, 0xc3, 0x17, 0xaf, 0x2f, +0xff, 0x64, 0xff, 0x1a, 0x7c, 0x0d, 0x87, 0x30, +0x69, 0x95, 0xd7, 0xb3, 0xa9, 0xcc, 0x4d, 0x6d, +0xe8, 0x8f, 0x18, 0xaf, 0x29, 0xdc, 0x4f, 0x8e, +0xd5, 0xf6, 0x4e, 0xbb, 0x4f, 0x5d, 0xeb, 0x5f, +0x2b, 0x92, 0x16, 0xa6, 0x79, 0x91, 0xeb, 0xc6, +0xa6, 0xb2, 0x37, 0xf5, 0x67, 0xf3, 0x8d, 0xb0, +0x15, 0x93, 0x66, 0x25, 0x97, 0xcb, 0xf9, 0x52, +0x39, 0xa5, 0x72, 0x25, 0xbb, 0xf9, 0xd0, 0xd0, +0x50, 0x00, 0x86, 0x94, 0xd0, 0x97, 0x96, 0x96, +0xfc, 0xe4, 0x31, 0xa5, 0x52, 0xc9, 0x67, 0xe2, +0xe5, 0x72, 0xd9, 0x0f, 0x49, 0x23, 0xdb, 0x36, +0x8d, 0x5d, 0x32, 0x72, 0x7e, 0x05, 0x2e, 0x31, +0x72, 0x4a, 0x18, 0x43, 0xf9, 0xd7, 0xe9, 0x00, +0x40, 0x87, 0x5a, 0x6a, 0x0b, 0xb4, 0x93, 0xd2, +0x2c, 0x2c, 0x2c, 0xf8, 0x29, 0x5d, 0xe9, 0x77, +0x42, 0x5e, 0xf2, 0x07, 0x0e, 0x1c, 0x08, 0x84, +0x48, 0xee, 0xca, 0x24, 0xf1, 0x3d, 0xc9, 0xb3, +0xc8, 0xc6, 0x5b, 0xeb, 0x03, 0xd1, 0x18, 0x99, +0x74, 0x24, 0xa2, 0x7a, 0xb2, 0xbe, 0xb4, 0x7b, +0x4a, 0x26, 0x6e, 0xdb, 0x80, 0x39, 0x4c, 0xfa, +0x6c, 0x52, 0x15, 0x9b, 0x18, 0x89, 0x94, 0x5e, +0x24, 0x9e, 0x72, 0xf3, 0x94, 0x8c, 0x90, 0xda, +0x4a, 0x73, 0x81, 0xdc, 0x3c, 0x4d, 0xe6, 0x04, +0xd9, 0x8f, 0xc9, 0x49, 0x8a, 0x3e, 0x9b, 0x98, +0x28, 0xef, 0xc7, 0x34, 0x1e, 0x49, 0x13, 0xc9, +0xd0, 0x4d, 0x12, 0xae, 0x46, 0x8f, 0x30, 0xd3, +0x86, 0x6c, 0xab, 0x39, 0x32, 0x6a, 0x36, 0x68, +0x2e, 0x19, 0x73, 0xe6, 0x67, 0xb3, 0xf9, 0x73, +0x49, 0xd6, 0xd4, 0xbf, 0x49, 0x63, 0x11, 0x86, +0xbf, 0xa4, 0xbb, 0xc9, 0xc6, 0xdf, 0x4d, 0xff, +0x26, 0x78, 0xa6, 0xc3, 0xa0, 0xa6, 0x89, 0xd1, +0xea, 0x45, 0xf1, 0x01, 0xd1, 0xb4, 0x4e, 0x02, +0x76, 0x62, 0xdb, 0x0d, 0xb7, 0xdd, 0xbd, 0xb5, +0x76, 0x11, 0x40, 0x7b, 0x53, 0xa1, 0xb0, 0x27, +0x1e, 0x76, 0x46, 0xa1, 0x40, 0xc4, 0x70, 0x29, +0x81, 0x07, 0x85, 0xa2, 0xc9, 0x30, 0x20, 0x7a, +0xc6, 0x53, 0x70, 0xca, 0x90, 0x21, 0x5e, 0x9f, +0x17, 0x0a, 0xb5, 0x92, 0x29, 0x4d, 0x89, 0x09, +0x10, 0x5e, 0xe5, 0x72, 0xb9, 0x23, 0x14, 0x4b, +0x86, 0x54, 0xc9, 0x94, 0xb4, 0xbc, 0xae, 0x0c, +0x93, 0xa2, 0xf6, 0x1c, 0xa6, 0xc4, 0x99, 0xf7, +0xc1, 0x0f, 0x2a, 0x32, 0xd4, 0x2d, 0x97, 0xcb, +0xa9, 0x09, 0x52, 0x4c, 0x61, 0x54, 0x1a, 0xb3, +0xe5, 0xf8, 0xf1, 0x7e, 0x25, 0xbd, 0x38, 0xdd, +0xf8, 0x7f, 0x4e, 0x5f, 0xa2, 0xa5, 0x4d, 0xea, +0xe6, 0x63, 0xd6, 0x68, 0xe4, 0x79, 0xed, 0x84, +0x42, 0x7c, 0xbe, 0x25, 0xf3, 0xe6, 0xb0, 0xb5, +0x3a, 0x9c, 0x06, 0x7c, 0x7e, 0x0b, 0x85, 0x42, +0x47, 0x2a, 0x60, 0x0d, 0x2e, 0x4f, 0xe3, 0xcb, +0x8b, 0xa9, 0xad, 0x0c, 0x59, 0xe4, 0xb4, 0x6e, +0xb5, 0x5a, 0x70, 0x1c, 0x27, 0xe0, 0x6c, 0xe9, +0xba, 0xae, 0x9f, 0xde, 0x95, 0xd3, 0x73, 0x68, +0x68, 0xc8, 0x5f, 0x6f, 0xe4, 0xd9, 0x9e, 0xcb, +0xe5, 0x50, 0xaf, 0xd7, 0x51, 0xa9, 0x54, 0x90, +0xc9, 0x64, 0x50, 0x2c, 0x16, 0xfd, 0x94, 0xae, +0x94, 0xee, 0xb5, 0x5c, 0x2e, 0xe3, 0xcc, 0x99, +0x33, 0xd8, 0xb1, 0x63, 0x87, 0x9f, 0xf6, 0x75, +0x72, 0x72, 0x12, 0x8e, 0xe3, 0xe0, 0xf8, 0xf1, +0xe3, 0x18, 0x19, 0x19, 0x09, 0x68, 0x3b, 0x66, +0x67, 0x67, 0x31, 0x36, 0x36, 0xe6, 0x27, 0xa3, +0xc9, 0xe5, 0x72, 0x38, 0x7d, 0xfa, 0x34, 0x8e, +0x1f, 0x3f, 0x8e, 0x5c, 0x2e, 0x87, 0x2b, 0xae, +0xb8, 0x02, 0x9e, 0xe7, 0x61, 0x61, 0x61, 0x01, +0x85, 0x42, 0xc1, 0x0f, 0x53, 0x5b, 0x5c, 0x5c, +0xc4, 0xf1, 0xe3, 0xc7, 0x51, 0x2a, 0x95, 0xb0, +0x6b, 0xd7, 0xae, 0xc0, 0xef, 0x0e, 0x68, 0x33, +0xfe, 0x67, 0x9e, 0x3d, 0x81, 0xd1, 0x78, 0x0d, +0x6e, 0x5f, 0x3f, 0x9e, 0x28, 0xaf, 0x49, 0x51, +0xcd, 0x66, 0x30, 0xa4, 0x87, 0xbe, 0xf3, 0xa4, +0x27, 0x40, 0x30, 0xc5, 0x24, 0x5a, 0xeb, 0xff, +0x65, 0xa8, 0x54, 0xa5, 0xdc, 0xfe, 0x4c, 0x9b, +0x1b, 0x0f, 0x3b, 0x93, 0x45, 0x86, 0xe4, 0xd8, +0xea, 0x6a, 0x6d, 0x79, 0x68, 0x0e, 0xef, 0x57, +0x86, 0x28, 0xc9, 0xf1, 0xa5, 0xdc, 0xe0, 0xd8, +0xa8, 0x5d, 0xca, 0x6d, 0x8f, 0xa5, 0x83, 0x41, +0xb6, 0x04, 0xbc, 0x84, 0x1e, 0x42, 0x14, 0x56, +0x28, 0x84, 0x8b, 0xfa, 0xa1, 0xf0, 0x28, 0xc2, +0x27, 0x1e, 0x0f, 0xd2, 0xc3, 0x06, 0x9f, 0xcf, +0x1b, 0xb5, 0x6f, 0x34, 0xd6, 0x61, 0x3b, 0x4e, +0x30, 0x64, 0x4a, 0x0b, 0xb7, 0x22, 0xda, 0x49, +0xda, 0xcb, 0xff, 0x44, 0x9f, 0x56, 0xab, 0x0d, +0x97, 0xe0, 0xd3, 0x18, 0x08, 0x77, 0xb9, 0x36, +0xe4, 0x3c, 0xc9, 0x35, 0x26, 0x93, 0xd5, 0xf0, +0xb1, 0xc9, 0xfe, 0xb9, 0xc6, 0x22, 0xb5, 0xe6, +0x88, 0xca, 0x69, 0x68, 0x0b, 0x21, 0xa3, 0xef, +0x1d, 0xe1, 0x95, 0xf1, 0xee, 0xfa, 0x27, 0xfa, +0x4a, 0x1c, 0x1c, 0x27, 0xb8, 0x46, 0x68, 0x7c, +0x92, 0xd6, 0x32, 0x4d, 0xab, 0xa4, 0x93, 0x69, +0xbe, 0xa9, 0xcf, 0x46, 0x7d, 0xfd, 0x77, 0xc6, +0xd7, 0x11, 0x0b, 0x89, 0x8b, 0xbb, 0x49, 0xf3, +0xe6, 0x09, 0x74, 0x4a, 0xb8, 0xd2, 0x73, 0x5a, +0x4a, 0xe0, 0x9a, 0xe3, 0x14, 0x97, 0x26, 0x4d, +0x6a, 0x7a, 0x5e, 0x4f, 0xb6, 0x37, 0x39, 0x5a, +0xc9, 0x5b, 0xac, 0x78, 0x7f, 0x9a, 0x2a, 0xd8, +0x36, 0x4e, 0x39, 0x5e, 0xed, 0x7b, 0x98, 0xe7, +0x7c, 0x54, 0x47, 0x3c, 0x9b, 0xda, 0xdf, 0xa4, +0xcd, 0xb0, 0xd9, 0xd1, 0xf9, 0x73, 0x69, 0xd6, +0x90, 0x75, 0x6c, 0x9e, 0xdd, 0x61, 0x1e, 0xe9, +0xdd, 0x3a, 0x12, 0xca, 0x75, 0x61, 0x72, 0xa2, +0xb4, 0xf9, 0x25, 0xd8, 0xe6, 0x31, 0x8a, 0xf3, +0xa3, 0x84, 0xe1, 0xba, 0xae, 0x31, 0x07, 0x3b, +0x49, 0xe7, 0xf9, 0x7c, 0xde, 0x57, 0xaf, 0x4b, +0x35, 0x3b, 0xb0, 0x6e, 0xca, 0x20, 0xa6, 0x4e, +0x78, 0xa7, 0xd3, 0x69, 0xdf, 0x4e, 0x9e, 0x4e, +0xa7, 0xb1, 0xb0, 0xb0, 0x10, 0x58, 0xcf, 0x83, +0x83, 0x83, 0xf0, 0x3c, 0xcf, 0xf7, 0x50, 0x07, +0xda, 0x9e, 0xe7, 0xae, 0xeb, 0xfa, 0x37, 0xa5, +0xb9, 0xae, 0xeb, 0x6b, 0xc7, 0xe4, 0xc5, 0x2c, +0x95, 0x4a, 0xc5, 0x4f, 0x2e, 0x33, 0x31, 0x31, +0x81, 0xb1, 0xb1, 0x31, 0x9c, 0x38, 0x71, 0x02, +0xd3, 0xd3, 0xd3, 0x00, 0x80, 0xf1, 0xf1, 0x71, +0x3f, 0x84, 0x8d, 0xfe, 0xe8, 0x37, 0x75, 0xe8, +0xda, 0xab, 0x31, 0x75, 0xc5, 0x1e, 0xbc, 0x6d, +0xa4, 0x89, 0xab, 0xfb, 0x94, 0xc1, 0xdb, 0xbc, +0x9c, 0x6d, 0x12, 0x81, 0xb4, 0x99, 0x4a, 0x1b, +0x75, 0x98, 0xed, 0x51, 0xfb, 0xac, 0x49, 0x82, +0x26, 0x9b, 0xb0, 0xec, 0xd7, 0x54, 0x8f, 0x3e, +0xdb, 0x54, 0xf1, 0x61, 0xf8, 0x47, 0xc1, 0x53, +0x1b, 0x27, 0xf7, 0x39, 0xd0, 0xd4, 0xa6, 0x26, +0xba, 0x47, 0xa1, 0x03, 0xc1, 0x91, 0x63, 0xd0, +0x6c, 0xd8, 0xb6, 0x10, 0x2b, 0x53, 0x7f, 0x24, +0x45, 0x72, 0xa7, 0x31, 0xcd, 0x2c, 0x13, 0xa6, +0x41, 0x09, 0x9b, 0x17, 0x1b, 0xfd, 0xe4, 0x3c, +0x4b, 0x3c, 0x4c, 0xe6, 0x9b, 0x28, 0x61, 0x62, +0x1b, 0xa5, 0xaf, 0x69, 0x3d, 0x68, 0x7e, 0x03, +0x36, 0x3a, 0x99, 0x68, 0x21, 0xa3, 0x31, 0x4c, +0x3e, 0x16, 0x14, 0x9a, 0xc6, 0x8b, 0x8d, 0x31, +0xf3, 0xcf, 0xfc, 0xaa, 0x4e, 0x69, 0xaf, 0xed, +0x86, 0xd9, 0xd3, 0x73, 0xe9, 0xe4, 0x25, 0xe1, +0xf0, 0xff, 0xfc, 0x40, 0xc1, 0xb3, 0x6c, 0x45, +0xdd, 0xd8, 0x6d, 0x21, 0x4d, 0x36, 0xbb, 0xb8, +0x49, 0xe5, 0x6e, 0xa2, 0x91, 0x56, 0xcf, 0x84, +0x97, 0x76, 0x68, 0xb1, 0xb5, 0xd3, 0xfa, 0x96, +0xa6, 0x02, 0x62, 0xee, 0x1a, 0x03, 0xb7, 0x1d, +0x08, 0x34, 0x3a, 0x44, 0xb1, 0x87, 0x87, 0x79, +0xd0, 0x9b, 0xe8, 0x65, 0xb3, 0x79, 0x03, 0x50, +0x6d, 0xff, 0x26, 0x3a, 0xf2, 0xcf, 0x92, 0x16, +0xc4, 0x70, 0x81, 0xf5, 0x50, 0x34, 0x8d, 0xb1, +0x93, 0x67, 0xbb, 0x1c, 0x3b, 0x85, 0xac, 0x71, +0x9f, 0x10, 0x82, 0xc5, 0xd5, 0xe8, 0xc4, 0xb0, +0x49, 0x4d, 0x4e, 0x37, 0xac, 0x8d, 0x8f, 0x8f, +0x63, 0x6e, 0x6e, 0x2e, 0xa0, 0x2a, 0x9f, 0x98, +0x98, 0x40, 0xa5, 0x52, 0xf1, 0x61, 0xa6, 0xd3, +0x69, 0xe4, 0x72, 0x39, 0xdf, 0xd1, 0x8d, 0xdf, +0xcc, 0x46, 0x73, 0x35, 0x36, 0x36, 0x86, 0xf1, +0xf1, 0x71, 0x4c, 0x4f, 0x4f, 0xe3, 0xe4, 0xc9, +0x93, 0x98, 0x98, 0x98, 0xf0, 0xef, 0x38, 0x27, +0x7a, 0x91, 0x69, 0x6a, 0x66, 0x66, 0x06, 0xa5, +0x5a, 0xc3, 0x77, 0x28, 0x6d, 0x9c, 0x9f, 0xc7, +0x9b, 0xfa, 0x56, 0x90, 0x4d, 0xad, 0x1d, 0xe2, +0x6d, 0x1b, 0x21, 0x15, 0xd3, 0xe6, 0xa7, 0xa9, +0xd7, 0x4d, 0xa1, 0x4a, 0x5a, 0x1f, 0x36, 0xf5, +0xa8, 0xc4, 0xc5, 0xa6, 0x26, 0xe6, 0xfd, 0x6a, +0x36, 0x53, 0x6e, 0x53, 0x97, 0x1b, 0xae, 0x64, +0x4c, 0x36, 0xfc, 0xe5, 0x66, 0x2f, 0x3d, 0x9b, +0xf9, 0x77, 0xdb, 0x78, 0xa8, 0x1f, 0x9b, 0x2d, +0x5f, 0xc2, 0xd3, 0xe8, 0xc0, 0x99, 0x0c, 0x87, +0x29, 0x43, 0xf1, 0x6c, 0x4c, 0x55, 0xeb, 0x5b, +0xf6, 0xc1, 0x1d, 0x07, 0x4d, 0xf8, 0x4b, 0x58, +0x04, 0x47, 0xa3, 0x8d, 0xac, 0x6f, 0xaa, 0x23, +0x9d, 0xda, 0xc2, 0x0e, 0x2b, 0x1a, 0x2e, 0xb6, +0x70, 0x2f, 0xad, 0x4e, 0x2f, 0xf4, 0xd5, 0xe0, +0xc8, 0xb9, 0xb7, 0x1d, 0x20, 0x6c, 0x8e, 0xa1, +0xda, 0x95, 0xae, 0xfc, 0x39, 0xeb, 0x23, 0x31, +0xf9, 0x8a, 0xd7, 0xdf, 0x3d, 0xd6, 0x28, 0xf8, +0x39, 0xae, 0x65, 0xbe, 0x6c, 0xc9, 0x98, 0x49, +0x25, 0x4a, 0x9f, 0x69, 0x93, 0x2c, 0x14, 0x0a, +0x18, 0x19, 0x19, 0xf1, 0xd5, 0xe0, 0xf5, 0x7a, +0xdd, 0xb7, 0xff, 0xf1, 0x4c, 0x6d, 0xd4, 0x9e, +0xd4, 0x96, 0x5c, 0x95, 0x2d, 0x55, 0xd7, 0x52, +0x15, 0xae, 0xa9, 0xd0, 0xe9, 0x33, 0x57, 0xdf, +0xd2, 0x38, 0xb8, 0xaa, 0x5b, 0x9a, 0x03, 0x38, +0x4c, 0x2d, 0x4f, 0x38, 0x2f, 0x34, 0x46, 0x99, +0xbb, 0xdc, 0xa7, 0x25, 0x53, 0x4b, 0xcb, 0x8d, +0x5e, 0xbb, 0x25, 0x8c, 0x60, 0x49, 0xf5, 0x39, +0xe1, 0xc8, 0xd5, 0xf5, 0x1a, 0x8d, 0xb8, 0x2a, +0x9e, 0x72, 0xe9, 0xcb, 0x77, 0x9c, 0x4e, 0x54, +0x57, 0x9a, 0x43, 0x64, 0xdf, 0x94, 0x27, 0x9f, +0xd4, 0xe9, 0x72, 0x8c, 0x32, 0x83, 0x1e, 0xa7, +0x21, 0x9f, 0x4f, 0xfe, 0x5e, 0xe2, 0x20, 0x0f, +0x1e, 0x32, 0x1f, 0x3e, 0x00, 0xf5, 0x7e, 0x00, +0xd9, 0x97, 0x69, 0x6d, 0xc8, 0xff, 0xb4, 0x46, +0x39, 0x8e, 0x8d, 0x46, 0xc3, 0x57, 0xa9, 0x03, +0x40, 0x63, 0x6d, 0xb3, 0x77, 0x5d, 0x17, 0x8d, +0x46, 0x03, 0xfd, 0xfd, 0xfd, 0xfe, 0x18, 0x62, +0xb1, 0x58, 0x20, 0x5f, 0xbb, 0x3c, 0x50, 0x94, +0x4a, 0x25, 0x6c, 0xdd, 0xba, 0x15, 0xf3, 0xf3, +0xf3, 0x28, 0x14, 0x0a, 0xd8, 0xb2, 0x65, 0x0b, +0xfa, 0xfb, 0xfb, 0x51, 0x28, 0x14, 0x02, 0xd7, +0xa3, 0x4e, 0x4d, 0x4d, 0xe1, 0xf8, 0xf1, 0xe3, +0x70, 0x1c, 0xc7, 0x67, 0xc4, 0x44, 0xef, 0xf3, +0xe7, 0xcf, 0xfb, 0x8e, 0x6e, 0x94, 0x1d, 0x6e, +0x71, 0x71, 0x11, 0x63, 0x63, 0x63, 0xd8, 0xb1, +0x63, 0x07, 0x8a, 0xc5, 0x22, 0x80, 0xf5, 0xcb, +0x76, 0x32, 0x99, 0x0c, 0x9e, 0x78, 0xe2, 0x09, +0x00, 0xc0, 0xbe, 0x7d, 0xfb, 0xb0, 0x6b, 0xd7, +0x2e, 0xd4, 0xeb, 0x75, 0x2c, 0x2e, 0x2e, 0xe2, +0xd4, 0xa9, 0x53, 0x78, 0xf6, 0xd9, 0x67, 0x31, +0x3f, 0x3f, 0x8f, 0x7d, 0xfb, 0xf6, 0x61, 0xdf, +0xbe, 0x7d, 0x48, 0x26, 0xe2, 0xfe, 0xa1, 0x20, +0xd9, 0x97, 0xc1, 0x64, 0x5f, 0x1c, 0x73, 0x2d, +0x0f, 0x0b, 0xf5, 0x38, 0xaa, 0x35, 0x91, 0xcd, +0x90, 0xd4, 0x83, 0x5c, 0x4d, 0x68, 0xca, 0x04, +0x47, 0xf5, 0xf9, 0x26, 0xdb, 0xa8, 0xb7, 0xff, +0xe8, 0x3b, 0x57, 0x39, 0x3a, 0x49, 0x5d, 0xa5, +0xab, 0x6d, 0x62, 0xb2, 0x5f, 0xa9, 0xb6, 0x94, +0x6a, 0x60, 0xc7, 0x59, 0x57, 0x81, 0xca, 0x5c, +0xde, 0x5c, 0xb5, 0x2d, 0xd5, 0xae, 0xdc, 0x2c, +0x60, 0xc2, 0x9f, 0xf7, 0x69, 0x52, 0x47, 0xcb, +0x71, 0x98, 0x32, 0x9d, 0x91, 0x29, 0x88, 0xfa, +0x0c, 0xcb, 0xfa, 0x65, 0xca, 0x41, 0x4f, 0xef, +0xb8, 0x69, 0xc0, 0x71, 0x74, 0xf8, 0x61, 0x78, +0xdb, 0xe6, 0x41, 0x33, 0x3d, 0x10, 0xad, 0x35, +0x53, 0x8a, 0x2d, 0xdf, 0x78, 0x58, 0xb6, 0x33, +0xd9, 0x3f, 0xcd, 0x9d, 0xaf, 0x75, 0x71, 0x3a, +0x3f, 0xcb, 0xf5, 0x65, 0xca, 0x6e, 0x27, 0x71, +0x92, 0xd9, 0x0a, 0x25, 0xae, 0xdd, 0xd0, 0xd7, +0x36, 0xdf, 0xa6, 0x7e, 0xb4, 0x75, 0xa2, 0xd1, +0x87, 0x54, 0xf9, 0x7c, 0xec, 0x7c, 0xbd, 0xb3, +0xf5, 0x19, 0x4f, 0x27, 0xd7, 0x6d, 0x89, 0x95, +0x46, 0x1b, 0x80, 0xc9, 0x69, 0xca, 0xf3, 0x3c, +0xc4, 0x53, 0x6e, 0x87, 0xa4, 0xcd, 0x3d, 0xac, +0xe9, 0xb3, 0xa6, 0x2e, 0xa7, 0x36, 0xf4, 0x5f, +0x4a, 0x72, 0xf2, 0x56, 0x30, 0x9b, 0x7a, 0x5c, +0xf3, 0x5e, 0x2f, 0x97, 0xcb, 0xfe, 0x2d, 0x53, +0x26, 0x09, 0x3b, 0x8a, 0x44, 0x18, 0xa6, 0xe2, +0x96, 0x25, 0xcc, 0x01, 0x4c, 0xfb, 0x2e, 0x69, +0xa2, 0x49, 0x95, 0x36, 0xe9, 0x58, 0xd2, 0xf0, +0xff, 0x67, 0xef, 0x4f, 0x7f, 0x24, 0xbb, 0xb2, +0xfc, 0x40, 0xf0, 0x67, 0x6f, 0x31, 0x7b, 0xe6, +0xab, 0x79, 0xb8, 0x7b, 0xb8, 0x7b, 0x84, 0x07, +0xc3, 0x83, 0x4b, 0x66, 0x30, 0x93, 0x2c, 0x32, +0x17, 0xe6, 0x52, 0x99, 0x59, 0x95, 0x55, 0xd9, +0x5a, 0x46, 0x9a, 0x56, 0x77, 0x6b, 0x00, 0x7d, +0x68, 0x0d, 0xba, 0xd1, 0xcb, 0xa0, 0x81, 0x81, +0x80, 0x69, 0x60, 0x16, 0x0c, 0x1a, 0x18, 0x80, +0x98, 0x3f, 0x61, 0xbe, 0xcf, 0x00, 0x42, 0x7f, +0x1a, 0xf4, 0xa0, 0x3f, 0x68, 0x30, 0x0d, 0x41, +0x6a, 0x49, 0xd5, 0x52, 0xa9, 0x36, 0x55, 0x29, +0xb3, 0x54, 0xc9, 0x24, 0x29, 0x6e, 0x41, 0x32, +0x82, 0xe1, 0xc1, 0xf0, 0x08, 0x37, 0x5f, 0x6d, +0x7b, 0xcb, 0x7c, 0x30, 0x3b, 0xd7, 0xce, 0x3b, +0xef, 0x9c, 0xfb, 0x9e, 0x07, 0xa9, 0xaa, 0xcc, +0x92, 0x1d, 0xc0, 0xe1, 0xf6, 0xde, 0xbb, 0xcb, +0xb9, 0xeb, 0x59, 0xef, 0xb9, 0x75, 0xe5, 0xf3, +0xf3, 0xd0, 0xf4, 0x8d, 0x9c, 0xdf, 0xb8, 0x44, +0x27, 0xd3, 0xf8, 0x34, 0x17, 0xbe, 0x3e, 0xd5, +0xd2, 0xf8, 0xd2, 0x69, 0xc7, 0xdd, 0x7c, 0x36, +0x79, 0x89, 0xa7, 0xac, 0x43, 0x6a, 0x8b, 0xb4, +0x3a, 0xb9, 0xbd, 0x5c, 0x02, 0x39, 0xbd, 0x91, +0x33, 0x1b, 0xe5, 0xe7, 0xe7, 0xd0, 0x49, 0x52, +0xe7, 0x31, 0xd3, 0x01, 0xb8, 0xfb, 0xcc, 0xb9, +0xf3, 0x1b, 0xdd, 0x72, 0x46, 0x84, 0x9c, 0x24, +0x6c, 0x52, 0xcb, 0x73, 0x4f, 0x74, 0x60, 0x6a, +0x5b, 0xdf, 0xd9, 0xd9, 0x71, 0x81, 0x65, 0xa8, +0xfc, 0xdd, 0xdd, 0x5d, 0x77, 0xfc, 0x8d, 0xa4, +0xf1, 0x8f, 0x3e, 0xfa, 0xc8, 0xa9, 0xe4, 0xdf, +0x7d, 0xf7, 0x5d, 0x00, 0xd3, 0xf8, 0xef, 0x49, +0x92, 0xe0, 0xed, 0xb7, 0xdf, 0x76, 0x0c, 0x45, +0xaf, 0xd7, 0xc3, 0xed, 0x1b, 0x7b, 0xb8, 0x7d, +0x63, 0x0f, 0xff, 0xc5, 0xf6, 0x04, 0x77, 0xe3, +0x71, 0xb9, 0xd1, 0x4d, 0x1d, 0xba, 0x64, 0x7a, +0xf2, 0x22, 0x26, 0x8f, 0x66, 0x92, 0x68, 0xe5, +0xbd, 0xd6, 0x75, 0xe7, 0x78, 0x7d, 0xdf, 0xac, +0x34, 0x5c, 0x82, 0x0e, 0x43, 0x3d, 0x5d, 0xd3, +0x6f, 0x84, 0x2f, 0x7f, 0xd6, 0x54, 0xbe, 0x75, +0xb8, 0x5a, 0xaa, 0x79, 0xd2, 0x04, 0x58, 0x0e, +0x50, 0x5a, 0xde, 0xba, 0x3a, 0x38, 0xae, 0xbc, +0x7c, 0x79, 0x9f, 0xf6, 0x55, 0xf0, 0xe7, 0x50, +0x57, 0xbe, 0x6f, 0xec, 0x68, 0x7c, 0xea, 0xea, +0xf0, 0x7d, 0x93, 0x75, 0x59, 0xc1, 0x70, 0xb4, +0xff, 0x5a, 0x99, 0x52, 0x63, 0x60, 0xd5, 0xef, +0xeb, 0x5f, 0xf2, 0x88, 0x6f, 0x32, 0xde, 0x75, +0xf5, 0x68, 0xb8, 0xf1, 0xf2, 0xb8, 0x83, 0xa9, +0x34, 0xd3, 0x88, 0x33, 0xeb, 0xe1, 0xf3, 0xbf, +0xf1, 0xd7, 0xdf, 0xdc, 0xcd, 0xa6, 0xd2, 0x72, +0x14, 0xb4, 0x9c, 0xf4, 0xc9, 0x3d, 0xa6, 0x29, +0x0e, 0x7b, 0xaf, 0xd7, 0xc3, 0xd9, 0x2c, 0x36, +0x3a, 0x77, 0x62, 0x22, 0x55, 0x21, 0x49, 0xdd, +0x00, 0x2a, 0x92, 0x19, 0xbf, 0x59, 0x4d, 0x3a, +0x31, 0x49, 0xe9, 0xad, 0xdf, 0xef, 0xab, 0xe5, +0x90, 0xc3, 0x5d, 0x9d, 0x63, 0x97, 0xbc, 0xbb, +0x9c, 0xdf, 0xf8, 0xc5, 0xf3, 0xcb, 0x98, 0xe5, +0xf2, 0xde, 0x73, 0x8e, 0x9f, 0xfc, 0xad, 0xdd, +0x38, 0x46, 0x20, 0x99, 0x14, 0x92, 0x34, 0xe9, +0x1b, 0x4f, 0xc7, 0x25, 0x66, 0xae, 0xc1, 0xa0, +0xff, 0xd2, 0xe9, 0x4d, 0xbb, 0x31, 0x8d, 0x13, +0x31, 0x79, 0x77, 0x37, 0xbf, 0x55, 0x8c, 0x6b, +0x34, 0x28, 0x96, 0xbe, 0x75, 0x6b, 0x1a, 0xf5, +0x29, 0xd7, 0x0a, 0xf0, 0xf1, 0xe5, 0x7d, 0xcb, +0xfb, 0xce, 0xd2, 0xec, 0x10, 0x5e, 0xf2, 0x76, +0x3c, 0xd9, 0x9f, 0xd2, 0x01, 0xd0, 0x72, 0x6a, +0xe4, 0x0e, 0x90, 0x1c, 0x1f, 0xde, 0x6f, 0x72, +0x1e, 0x50, 0x7e, 0x52, 0xad, 0x53, 0xac, 0x7f, +0x2a, 0x9f, 0x24, 0x74, 0x4a, 0x47, 0xe1, 0x5c, +0xe9, 0x1a, 0x5e, 0x8a, 0xd7, 0xbe, 0xba, 0xba, +0xea, 0xea, 0xbf, 0xb8, 0xb8, 0x70, 0x78, 0xd0, +0x0d, 0x6a, 0xa3, 0xd1, 0x08, 0xad, 0x56, 0xcb, +0x49, 0xdb, 0xc4, 0x64, 0xbe, 0xf8, 0xe2, 0x8b, +0x38, 0x3f, 0x3f, 0xc7, 0xfd, 0xfb, 0xf7, 0x71, +0xfb, 0xf6, 0x6d, 0x17, 0xaf, 0x9d, 0x22, 0xbe, +0xfd, 0xfc, 0xe7, 0x3f, 0x77, 0x12, 0xfd, 0xfa, +0xfa, 0x7a, 0xe9, 0x1e, 0x82, 0x24, 0x99, 0x06, +0xa1, 0xf9, 0xe0, 0x83, 0x0f, 0x5c, 0x04, 0xb9, +0x7e, 0xbf, 0x8f, 0xf3, 0xf3, 0x73, 0x64, 0x59, +0x86, 0xa3, 0xa3, 0x23, 0xa4, 0x69, 0x8a, 0x17, +0x5e, 0x78, 0x01, 0x77, 0xee, 0xdc, 0xc1, 0xa7, +0x9f, 0x7e, 0x8a, 0xf3, 0xf3, 0xf3, 0xe9, 0x39, +0xf3, 0x99, 0xd3, 0x1d, 0xa9, 0xdf, 0xdf, 0x7f, +0xff, 0x7d, 0x3c, 0x78, 0xef, 0x6d, 0xdc, 0x0a, +0xc7, 0xf8, 0x69, 0xb1, 0x86, 0x49, 0x8b, 0x39, +0xc4, 0x5d, 0x05, 0x7c, 0x0e, 0x3b, 0x41, 0xd0, +0x3c, 0x8f, 0x04, 0x29, 0x21, 0xf9, 0xbe, 0xd5, +0xd5, 0x77, 0x55, 0xe0, 0x92, 0xfd, 0xb3, 0xf4, +0x49, 0x5d, 0x1e, 0xc2, 0x93, 0x1c, 0xa5, 0x64, +0x7a, 0x5f, 0x5e, 0x4b, 0xca, 0x94, 0xfd, 0xc1, +0x9d, 0xc3, 0x9e, 0xb5, 0x0d, 0x5a, 0xd9, 0xc0, +0xd4, 0x11, 0x4e, 0xf6, 0x91, 0x2f, 0xbd, 0x35, +0x2e, 0xbe, 0x31, 0xf6, 0x7d, 0xe7, 0x4e, 0x5f, +0x5a, 0xd9, 0x3c, 0x9f, 0x56, 0xc6, 0x55, 0xfb, +0x57, 0x42, 0x10, 0x7c, 0xb1, 0x39, 0xe2, 0x6b, +0x77, 0x9d, 0x96, 0x06, 0x98, 0xcf, 0x77, 0x62, +0x34, 0xd9, 0xf7, 0x4a, 0x6f, 0x58, 0x12, 0xb9, +0x7c, 0x47, 0x30, 0x1c, 0x0e, 0xdd, 0xd1, 0x1c, +0x99, 0x96, 0xff, 0xd7, 0xf2, 0x37, 0xb1, 0xc3, +0x72, 0xbc, 0xa4, 0xc6, 0x80, 0xdb, 0xce, 0x25, +0xd0, 0x06, 0x4a, 0xe7, 0x78, 0xb9, 0xb3, 0x9c, +0xd5, 0x5e, 0x9f, 0xf3, 0x99, 0x65, 0xd7, 0xbe, +0xaa, 0x03, 0x96, 0xfc, 0x26, 0xd5, 0xce, 0x5a, +0x5e, 0x5e, 0x86, 0x94, 0xc2, 0xb9, 0x74, 0xcd, +0x9d, 0x02, 0xf9, 0x91, 0x33, 0xd9, 0x6f, 0x04, +0x5c, 0x12, 0x97, 0xf6, 0x73, 0x7e, 0xee, 0x5c, +0xeb, 0x87, 0xa6, 0x60, 0x69, 0x64, 0xac, 0x72, +0xb4, 0xf7, 0xd6, 0xb8, 0xc8, 0xf1, 0xd3, 0xc6, +0x84, 0xd7, 0x97, 0x24, 0xe5, 0xdb, 0xd1, 0xb8, +0xad, 0x1a, 0xa8, 0x86, 0x6c, 0x95, 0xf7, 0x98, +0x03, 0x70, 0x9e, 0xed, 0xe4, 0xd5, 0x4e, 0xf6, +0x75, 0x7e, 0xde, 0x9c, 0x02, 0xc8, 0xdc, 0xbd, +0x7b, 0xd7, 0xd9, 0xcf, 0x77, 0x76, 0x76, 0x00, +0xc0, 0x39, 0xb4, 0x91, 0x83, 0xdc, 0xce, 0xce, +0x8e, 0xf3, 0x64, 0xa7, 0xf3, 0xe5, 0xda, 0xd1, +0x42, 0xba, 0x59, 0x8d, 0x1c, 0xdb, 0x28, 0x44, +0x2c, 0x39, 0xcf, 0x91, 0xa4, 0xdf, 0x8a, 0xda, +0xee, 0x18, 0xdb, 0x9d, 0x3b, 0x77, 0x5c, 0xfd, +0x3f, 0xfb, 0xd9, 0xcf, 0xf0, 0x0f, 0xff, 0xe1, +0x3f, 0x74, 0x5a, 0x81, 0x3b, 0x77, 0xee, 0xe0, +0x66, 0xbb, 0xc0, 0xdf, 0x2c, 0x9f, 0xc2, 0xd3, +0x41, 0x93, 0xec, 0x7c, 0xd2, 0x5e, 0x18, 0xa2, +0x11, 0x58, 0x65, 0x5c, 0x45, 0x7a, 0xe3, 0x12, +0xf5, 0x55, 0xeb, 0x91, 0x47, 0xe2, 0x78, 0xf9, +0xbe, 0x3c, 0x57, 0xad, 0xe7, 0xcb, 0x82, 0x26, +0x52, 0x9e, 0x4f, 0x0b, 0x71, 0x55, 0x1c, 0x7d, +0x92, 0xba, 0x56, 0x9e, 0xaf, 0xef, 0x7c, 0x8e, +0x84, 0x4d, 0xbe, 0xf3, 0xfa, 0x7d, 0xed, 0x6a, +0x7a, 0x76, 0xbe, 0x69, 0x7b, 0xb5, 0xb6, 0x68, +0x41, 0x63, 0x7c, 0x38, 0x35, 0x69, 0xd7, 0x55, +0x70, 0x94, 0x1a, 0xaf, 0x19, 0x04, 0xad, 0xac, +0x2c, 0x8d, 0xf9, 0x88, 0xb0, 0xe6, 0xc9, 0x4e, +0xef, 0x79, 0x78, 0x4b, 0x8d, 0xd8, 0xf9, 0x88, +0x83, 0xe5, 0x98, 0xc5, 0x41, 0x53, 0x89, 0x6b, +0xf8, 0x6a, 0xc4, 0xab, 0x09, 0x21, 0x97, 0xef, +0xe4, 0xb3, 0x66, 0x02, 0xf0, 0x11, 0x6a, 0xad, +0xbc, 0x26, 0x44, 0xc9, 0x2a, 0x43, 0xe6, 0xe5, +0xcf, 0x1c, 0x37, 0x8e, 0x17, 0x11, 0x74, 0x4e, +0xe0, 0x7d, 0xed, 0xd4, 0xca, 0x96, 0xcf, 0x5a, +0x3a, 0x0d, 0xb4, 0xb6, 0xd6, 0x31, 0x85, 0x75, +0x5e, 0xf3, 0xbc, 0x0c, 0x8b, 0xe1, 0xf2, 0xe1, +0x32, 0x1c, 0x0e, 0x1d, 0x11, 0x27, 0x20, 0x82, +0xc8, 0x81, 0x9e, 0xf9, 0x25, 0x29, 0x9d, 0x4e, +0x07, 0x7b, 0x7b, 0x7b, 0x38, 0x3e, 0x3e, 0x2e, +0xc5, 0x6e, 0x27, 0xe7, 0x36, 0x00, 0xce, 0x23, +0x9d, 0x9c, 0xd8, 0x86, 0xc3, 0x69, 0x24, 0x43, +0x79, 0x3d, 0xea, 0xdd, 0xbb, 0x77, 0xdd, 0x2d, +0x6c, 0xe4, 0x14, 0x47, 0xc7, 0xd2, 0x28, 0xde, +0x3b, 0xe1, 0xcb, 0xe3, 0xb8, 0x13, 0xd3, 0xc0, +0xeb, 0xff, 0xf8, 0xe3, 0x8f, 0x9d, 0x06, 0xa0, +0xd3, 0xe9, 0xe0, 0xde, 0x07, 0xef, 0x21, 0x49, +0x12, 0xdc, 0xb9, 0x73, 0x07, 0xfd, 0x7e, 0x1f, +0x7f, 0xf0, 0x07, 0x7f, 0x80, 0x3f, 0xf8, 0x83, +0x3f, 0xc0, 0xbb, 0x1f, 0x7c, 0xe8, 0x62, 0xb8, +0xff, 0xf8, 0xc7, 0x3f, 0x9e, 0x5e, 0xad, 0x7a, +0x73, 0x0f, 0x3f, 0xd9, 0x28, 0xa6, 0x17, 0xb1, +0x00, 0x57, 0x23, 0xae, 0x57, 0x55, 0x99, 0xfb, +0x36, 0xb6, 0xab, 0x32, 0x0b, 0xbe, 0x34, 0x57, +0xd9, 0x40, 0x7d, 0x6a, 0x62, 0x8b, 0xd8, 0x5c, +0x55, 0x4d, 0xec, 0x6b, 0x8b, 0xcf, 0x7b, 0xfb, +0xdf, 0x15, 0xf8, 0xf0, 0xf7, 0x9d, 0xdf, 0xb6, +0xd2, 0x36, 0x9d, 0x1b, 0x75, 0x44, 0xec, 0x2a, +0x78, 0x69, 0xef, 0xaf, 0x4a, 0x24, 0xbf, 0x88, +0xe9, 0x41, 0xbe, 0x7f, 0x16, 0xa6, 0xf4, 0xdf, +0x01, 0x04, 0x83, 0x49, 0xf5, 0x3a, 0x4f, 0x6b, +0x33, 0xa7, 0x77, 0xd2, 0xc6, 0x4a, 0xc4, 0xc2, +0x22, 0x52, 0x75, 0x12, 0xb8, 0xcf, 0xee, 0xeb, +0x23, 0x1c, 0x1a, 0x33, 0x60, 0x81, 0x4f, 0xf2, +0xb6, 0xda, 0xee, 0x23, 0x5c, 0x75, 0xde, 0xd5, +0x9a, 0xc4, 0x6f, 0xf5, 0xa5, 0x4f, 0xda, 0xe5, +0x78, 0x68, 0x7e, 0x06, 0x75, 0xf5, 0x69, 0x51, +0xf6, 0x24, 0x13, 0xa4, 0x11, 0xd1, 0xab, 0x48, +0xc7, 0x4d, 0x41, 0x7a, 0x88, 0xd7, 0x95, 0x65, +0x31, 0x70, 0x32, 0xbf, 0xa5, 0xb5, 0xf0, 0xf9, +0x37, 0x10, 0xd0, 0x1c, 0xd6, 0xbc, 0xda, 0x07, +0x83, 0x81, 0xbb, 0xc1, 0xaf, 0xdb, 0xed, 0xe2, +0xe1, 0xc3, 0x87, 0x15, 0x3b, 0x3b, 0x05, 0x80, +0x19, 0x0c, 0x06, 0xee, 0x37, 0x95, 0x7b, 0xef, +0xde, 0x3d, 0x74, 0x3a, 0x1d, 0x6c, 0x6c, 0x6c, +0x38, 0x4f, 0x77, 0x3a, 0x92, 0x46, 0xd7, 0xa1, +0x0e, 0x87, 0x43, 0x77, 0x2b, 0xda, 0xce, 0xce, +0x8e, 0x73, 0xb2, 0x23, 0x5b, 0xf9, 0xfa, 0xfa, +0x7a, 0xc5, 0xab, 0x7d, 0x6f, 0x6f, 0x0f, 0x83, +0xc1, 0xc0, 0x49, 0xd9, 0x44, 0xc8, 0xe9, 0x28, +0x5c, 0xaf, 0xd7, 0xc3, 0x47, 0x1f, 0x7d, 0xe4, +0x34, 0x52, 0xbd, 0x5e, 0x0f, 0xdf, 0xfd, 0xd6, +0x37, 0xf1, 0xe3, 0x1f, 0xff, 0xd8, 0xc5, 0x7d, +0xa7, 0x28, 0x71, 0xa7, 0xef, 0xfc, 0x14, 0xff, +0x75, 0xfb, 0x01, 0xfe, 0xaf, 0xfb, 0xd9, 0x34, +0x7e, 0x3b, 0x8f, 0xc3, 0xfd, 0x65, 0x42, 0x1d, +0x11, 0xd4, 0x24, 0xb3, 0xa6, 0xf6, 0xe3, 0xa6, +0xf5, 0x3c, 0x2b, 0x58, 0x0e, 0x7a, 0x5f, 0xb4, +0xed, 0x75, 0xd1, 0xda, 0x6a, 0x70, 0x8a, 0xf2, +0x86, 0xf9, 0x9a, 0x32, 0x46, 0x4d, 0xfc, 0x24, +0x9a, 0x7c, 0xf3, 0xd5, 0xf1, 0x2c, 0xe0, 0xb3, +0x4d, 0x3f, 0x6b, 0x9b, 0xeb, 0xf0, 0xff, 0x32, +0x7c, 0x25, 0xae, 0xf2, 0xae, 0x0e, 0x1a, 0x94, +0x13, 0xde, 0xfc, 0xd6, 0x0f, 0xde, 0xdc, 0x4e, +0xcf, 0x2b, 0x9e, 0xd1, 0x32, 0x78, 0x0a, 0xb7, +0xdf, 0x4a, 0x7b, 0x2c, 0x11, 0x03, 0x2a, 0x03, +0x40, 0xc9, 0x4e, 0x4e, 0xff, 0xf9, 0x46, 0x4a, +0x79, 0x29, 0xad, 0x15, 0x58, 0x86, 0xdb, 0x3e, +0xa5, 0x07, 0x36, 0x4f, 0xab, 0xdd, 0xb7, 0xcd, +0x41, 0xd3, 0x34, 0xc8, 0xc0, 0x2e, 0xea, 0x38, +0xcd, 0xea, 0xe6, 0x81, 0x4d, 0xb8, 0x0d, 0x5c, +0xda, 0x8c, 0xc9, 0x36, 0x4c, 0x36, 0x61, 0x59, +0x0e, 0xf7, 0x56, 0xa7, 0x34, 0x51, 0x14, 0x39, +0x49, 0xce, 0xf2, 0xca, 0x96, 0x7e, 0x06, 0x1c, +0x6f, 0x6a, 0x4b, 0xbf, 0xdf, 0x2f, 0xdd, 0x65, +0x4e, 0x92, 0x39, 0xc7, 0x59, 0x06, 0xfa, 0x91, +0x75, 0x71, 0x3b, 0x3c, 0x6f, 0x17, 0xb7, 0x39, +0x6b, 0x7d, 0xcb, 0xd3, 0x52, 0x7b, 0x79, 0xd9, +0xd2, 0x3e, 0x2f, 0x7d, 0x26, 0x78, 0x7b, 0x64, +0xbf, 0x71, 0xbc, 0xb9, 0x5d, 0x9d, 0xfc, 0x28, +0x64, 0x20, 0x1f, 0x8e, 0x87, 0x76, 0x97, 0x39, +0x95, 0xdf, 0xe9, 0x74, 0x9c, 0x6d, 0x9c, 0x7b, +0xb6, 0x53, 0x30, 0x19, 0xfe, 0x9f, 0x97, 0xd7, +0xed, 0x76, 0x31, 0x18, 0x0c, 0xb0, 0xba, 0xba, +0x8a, 0x5e, 0xaf, 0x87, 0x87, 0x0f, 0x1f, 0x3a, +0x22, 0x7c, 0xff, 0xfe, 0xfd, 0x12, 0x73, 0xb4, +0xbd, 0xbd, 0xed, 0xe6, 0x0f, 0x69, 0x4b, 0xde, +0x7f, 0xff, 0x7d, 0x24, 0x49, 0x82, 0xa2, 0x28, +0xf0, 0xe8, 0xd1, 0x23, 0xa4, 0x69, 0x8a, 0x9b, +0x37, 0x6f, 0x02, 0x98, 0xda, 0xe3, 0xc9, 0x89, +0xf3, 0x85, 0x17, 0x5e, 0x70, 0x67, 0xd9, 0x49, +0x5d, 0xbe, 0xbf, 0xbf, 0x8f, 0xf3, 0xf3, 0x73, +0x7c, 0xf0, 0xc1, 0x07, 0x48, 0xd3, 0xd4, 0x05, +0x99, 0x21, 0xdb, 0x3d, 0x79, 0xd3, 0x77, 0xbb, +0x5d, 0xdc, 0xbf, 0x7f, 0xdf, 0x9d, 0x51, 0x5f, +0x59, 0x59, 0x71, 0x11, 0xe2, 0x8e, 0x8e, 0x8e, +0x90, 0x24, 0x09, 0x6e, 0xdd, 0xba, 0x85, 0xfd, +0xfd, 0x7d, 0x3c, 0xb7, 0xbb, 0x83, 0x1b, 0xed, +0x02, 0x5f, 0x5d, 0x6b, 0xe3, 0x9d, 0x4b, 0xe0, +0xd4, 0x47, 0xcf, 0x35, 0x9b, 0x5f, 0x9d, 0xfd, +0xb3, 0x49, 0xda, 0xa6, 0xef, 0x78, 0x19, 0x14, +0xc8, 0xc3, 0x67, 0x23, 0xbd, 0x2a, 0x8e, 0x57, +0xb5, 0xb3, 0x5e, 0x05, 0xa4, 0x37, 0xff, 0xb3, +0xd4, 0x17, 0xc5, 0x88, 0xd2, 0x11, 0xf2, 0x30, +0x46, 0x5e, 0xa0, 0x59, 0xbe, 0x26, 0x7d, 0xd2, +0xd4, 0x06, 0xae, 0xbd, 0x6f, 0x3a, 0x27, 0xbe, +0x68, 0x3f, 0xfa, 0x4e, 0x35, 0x34, 0x6d, 0xf3, +0x55, 0xea, 0x7a, 0xd6, 0x3c, 0x75, 0xfd, 0xfa, +0x45, 0xfd, 0x30, 0xa4, 0xc7, 0xfb, 0x0c, 0x82, +0xb0, 0x5d, 0x96, 0x48, 0x9a, 0x78, 0x6e, 0xd7, +0x79, 0x87, 0x37, 0xf5, 0x82, 0xa6, 0xf7, 0x96, +0xf7, 0xbc, 0x54, 0x65, 0x6b, 0xde, 0xdf, 0x75, +0x2a, 0x6b, 0x2d, 0x9d, 0x26, 0x99, 0x52, 0x1a, +0x0b, 0xef, 0xa6, 0xf5, 0xf8, 0x34, 0x14, 0x96, +0x3f, 0x81, 0x4f, 0x2b, 0x31, 0x1c, 0x0e, 0x4b, +0xb7, 0x7b, 0xf9, 0xbc, 0xbe, 0x25, 0x3e, 0x24, +0x75, 0x12, 0x31, 0xd0, 0xfa, 0x57, 0xf6, 0x41, +0x1d, 0xae, 0x4d, 0xbd, 0xca, 0xad, 0x7e, 0xb2, +0xa4, 0xf1, 0xba, 0x13, 0x05, 0x56, 0xbf, 0xfa, +0xea, 0xf2, 0x8d, 0x01, 0x30, 0xb7, 0x9b, 0x93, +0xfd, 0x9b, 0xd4, 0xe9, 0x3c, 0xcc, 0x2b, 0x97, +0xd8, 0xe9, 0x3d, 0x3f, 0x6f, 0xce, 0xfd, 0x0e, +0x8e, 0x8f, 0x8f, 0x9d, 0xc3, 0x1c, 0x11, 0xee, +0xe3, 0xe3, 0xe3, 0x92, 0x4d, 0x9b, 0x24, 0x74, +0x2e, 0xc1, 0xf7, 0x7a, 0x3d, 0x9c, 0x9c, 0x9c, +0x38, 0x87, 0x3b, 0x3a, 0xd2, 0x09, 0xcc, 0xc3, +0xb7, 0x52, 0xa0, 0x19, 0xba, 0x1d, 0x8d, 0x33, +0x6b, 0xd4, 0x0f, 0x74, 0x96, 0xfd, 0xf8, 0xf8, +0xd8, 0x79, 0xc5, 0x53, 0x38, 0x58, 0x3a, 0xb7, +0x4e, 0x97, 0xb9, 0x50, 0xb9, 0xce, 0x69, 0x30, +0x9b, 0xe0, 0xe6, 0xd1, 0xfb, 0xf8, 0xbb, 0xad, +0x4f, 0xe7, 0x6a, 0x77, 0xa0, 0x99, 0x2d, 0xb3, +0xa9, 0xad, 0xf1, 0xaa, 0x69, 0xeb, 0x70, 0xa8, +0x3b, 0xc7, 0xee, 0xab, 0xd7, 0xba, 0x6f, 0xbd, +0xa9, 0xaa, 0xfc, 0x59, 0x55, 0xd2, 0x57, 0x91, +0x7e, 0xb5, 0xa2, 0xc6, 0x97, 0x48, 0xdb, 0x4b, +0x88, 0xc6, 0x97, 0x57, 0xca, 0x67, 0xe2, 0xf3, +0x2c, 0xdf, 0xad, 0x36, 0x70, 0x1f, 0x84, 0x2f, +0xa2, 0xc9, 0xf0, 0xf5, 0x6d, 0x4d, 0xb9, 0x51, +0x3e, 0x79, 0x76, 0x69, 0xb8, 0xa9, 0x3f, 0xc4, +0x17, 0x94, 0xfa, 0x2b, 0x1a, 0x95, 0xab, 0x82, +0x51, 0xbe, 0x73, 0x80, 0x6b, 0xb5, 0xcb, 0x9b, +0xbd, 0x8c, 0xae, 0x66, 0xd9, 0xd2, 0xf9, 0x77, +0x2b, 0x3a, 0x1c, 0x27, 0x56, 0x93, 0x34, 0x73, +0xff, 0xf9, 0x37, 0xcb, 0x49, 0x8b, 0x40, 0xaa, +0xa4, 0xb9, 0x0d, 0x5e, 0x53, 0x13, 0x6b, 0x2a, +0x69, 0x9e, 0x4e, 0xda, 0xd1, 0xa5, 0xca, 0x56, +0xb6, 0x9b, 0xbe, 0xf9, 0x08, 0xa0, 0xf6, 0xbf, +0x0e, 0xea, 0xd4, 0xf0, 0x00, 0xdc, 0x26, 0xcf, +0x81, 0x82, 0xc1, 0x70, 0x9f, 0x04, 0xc9, 0xf4, +0x48, 0x07, 0x37, 0xab, 0x7c, 0x5e, 0xb7, 0xec, +0xb7, 0x26, 0x47, 0xf1, 0x64, 0x3f, 0x5b, 0xce, +0x90, 0xda, 0x98, 0xf2, 0x7e, 0x6d, 0xc2, 0x24, +0x36, 0x29, 0xcf, 0x37, 0x07, 0xb4, 0xfc, 0x5c, +0x75, 0x4e, 0xbf, 0xb5, 0x3a, 0x48, 0xdd, 0x4e, +0xfd, 0x2d, 0xcb, 0x24, 0x87, 0x3a, 0x7e, 0xed, +0x29, 0x7d, 0x93, 0x17, 0xd9, 0x50, 0x3a, 0x1a, +0x37, 0x8a, 0x0e, 0xa7, 0x99, 0xac, 0x38, 0x21, +0xe7, 0xc1, 0x68, 0xb8, 0xad, 0x9e, 0xd4, 0xf0, +0x0f, 0x1f, 0x3e, 0xc4, 0xbb, 0xef, 0xbe, 0x8b, +0x24, 0x99, 0x9e, 0x6d, 0x27, 0xe7, 0x37, 0x60, +0xee, 0x90, 0xc7, 0x6d, 0xf1, 0x49, 0x32, 0xbd, +0xb5, 0xed, 0xf7, 0x7f, 0xff, 0xf7, 0xd1, 0xef, +0xf7, 0xf1, 0xed, 0x8d, 0x18, 0xff, 0xa7, 0xdb, +0x01, 0xbe, 0xb9, 0x31, 0x63, 0x62, 0x9a, 0x6e, +0xca, 0x4d, 0x1d, 0x98, 0x34, 0x78, 0x16, 0x7b, +0xea, 0x17, 0x35, 0x07, 0xf8, 0xee, 0x37, 0x6f, +0x82, 0xc3, 0x55, 0x82, 0xec, 0x7c, 0x59, 0xaa, +0xff, 0x28, 0x46, 0x1a, 0xc4, 0x7e, 0xb5, 0x6e, +0x4d, 0xfe, 0x46, 0xf8, 0x3c, 0x2b, 0xbe, 0x4d, +0x8e, 0xaa, 0x69, 0xf8, 0xd0, 0x6f, 0xed, 0xc2, +0x9c, 0x2b, 0xe2, 0x53, 0xea, 0x1f, 0xab, 0x8c, +0x3a, 0x46, 0xb3, 0xce, 0xef, 0xe2, 0x59, 0xcc, +0x22, 0x2c, 0x6d, 0xda, 0x5e, 0x32, 0xbf, 0x7d, +0x11, 0xb5, 0x7c, 0x90, 0x8d, 0xa7, 0x1b, 0x50, +0x31, 0x1e, 0x9a, 0x9b, 0xb9, 0x6f, 0x43, 0xe7, +0x67, 0xcb, 0xf9, 0x66, 0xcb, 0xdf, 0xf3, 0xb2, +0xe2, 0x68, 0xea, 0x89, 0x17, 0x47, 0xa1, 0xd7, +0x81, 0xca, 0xb7, 0xb1, 0x4b, 0xe2, 0x6d, 0x11, +0x0d, 0xcd, 0xae, 0xca, 0x41, 0x5e, 0x00, 0x62, +0xe1, 0x21, 0x89, 0xa3, 0xc4, 0x4f, 0xeb, 0x1b, +0x9f, 0xb4, 0x6f, 0x39, 0x9a, 0x59, 0x7d, 0x40, +0x9e, 0xcb, 0xd2, 0xe1, 0x4e, 0xe6, 0x93, 0xe7, +0xc6, 0x09, 0x67, 0x8b, 0x21, 0xe1, 0x0e, 0x8c, +0xbc, 0x3c, 0x9f, 0x6d, 0x9e, 0x97, 0x53, 0xd7, +0xae, 0xba, 0xb1, 0xac, 0xeb, 0x47, 0xd9, 0xa7, +0x57, 0x79, 0xaf, 0x31, 0x64, 0x9a, 0x26, 0x84, +0xc2, 0xbb, 0x5a, 0x7e, 0x0b, 0x5c, 0x4a, 0xa7, +0xb1, 0xa0, 0x8b, 0x58, 0xb8, 0xf6, 0x83, 0xce, +0xa5, 0xf3, 0xb2, 0x48, 0xca, 0xe7, 0x3e, 0x26, +0xe4, 0xe0, 0xc6, 0x25, 0xf0, 0xe1, 0x70, 0xe8, +0xbc, 0xe4, 0xfb, 0xfd, 0x3e, 0x6e, 0xdf, 0xbe, +0xed, 0x1c, 0xee, 0xc8, 0x81, 0x8e, 0xaf, 0x29, +0xfa, 0xa3, 0xcb, 0x5a, 0xf8, 0xc5, 0x2d, 0x1f, +0x7f, 0xfc, 0xb1, 0x23, 0xd4, 0xef, 0xbc, 0xf3, +0x8e, 0xbb, 0x2e, 0x95, 0x8e, 0xb2, 0x3d, 0x7c, +0xf8, 0xd0, 0x11, 0xf1, 0x9f, 0xfd, 0xec, 0x67, +0xf8, 0x67, 0xff, 0xec, 0x9f, 0xe1, 0xde, 0xbd, +0x7b, 0xe8, 0x76, 0xbb, 0xd8, 0xdd, 0xdd, 0xc5, +0x38, 0x2f, 0x10, 0x1e, 0x1f, 0xe2, 0xbf, 0xe9, +0x9d, 0xe2, 0xaf, 0x6d, 0x7f, 0x41, 0xcf, 0x67, +0xa0, 0xbc, 0x49, 0x73, 0x49, 0x58, 0xbb, 0xa7, +0xb9, 0xa9, 0xf4, 0x94, 0x65, 0xfe, 0xfb, 0xb3, +0x7d, 0xe5, 0x51, 0xfe, 0x26, 0xb7, 0x56, 0xd5, +0xe1, 0xa1, 0xb5, 0x85, 0xca, 0xe6, 0xed, 0xfe, +0xb2, 0x80, 0xd9, 0x88, 0x1d, 0xd1, 0x92, 0xf5, +0xf3, 0x67, 0xd9, 0xef, 0xcf, 0x42, 0xa4, 0xb5, +0x36, 0x58, 0xe3, 0x77, 0xc5, 0xfe, 0x8b, 0xc6, +0x97, 0xe5, 0xab, 0x67, 0xf9, 0x45, 0x3f, 0x59, +0xf6, 0x6c, 0xfd, 0x27, 0x71, 0x92, 0x7d, 0xc0, +0xdf, 0x3f, 0x8b, 0xf6, 0x88, 0xe3, 0xf7, 0x2c, +0xfd, 0x2a, 0x19, 0x1e, 0x5e, 0x1e, 0x9d, 0x63, +0xbf, 0x6a, 0xf9, 0xb3, 0x74, 0x41, 0xd8, 0xee, +0xa8, 0x92, 0x8b, 0xa5, 0x8a, 0x26, 0xe0, 0x61, +0x5c, 0x35, 0x7b, 0x34, 0x97, 0x00, 0xac, 0x23, +0x64, 0x24, 0xa5, 0x4b, 0xa2, 0xaf, 0xa9, 0xd6, +0x09, 0x34, 0x69, 0x5b, 0x7b, 0x4f, 0xef, 0x2c, +0xd0, 0x08, 0x0f, 0xf7, 0x7c, 0xd7, 0x1c, 0xe6, +0x34, 0x67, 0x35, 0x89, 0x67, 0x1d, 0x83, 0x62, +0x79, 0xa6, 0x4b, 0x07, 0x37, 0x5e, 0x0f, 0x11, +0x04, 0xeb, 0xfe, 0x78, 0x60, 0xce, 0x54, 0x49, +0x89, 0x91, 0x7b, 0xb2, 0xd3, 0xb5, 0x9b, 0xb2, +0xfc, 0xa6, 0xf8, 0x37, 0xe9, 0x73, 0xab, 0x4f, +0x7c, 0x92, 0x76, 0x9d, 0x26, 0x40, 0xa6, 0xa9, +0x73, 0x72, 0xd3, 0x70, 0xb5, 0xc6, 0x9f, 0x7b, +0xb7, 0x5b, 0x1a, 0x00, 0x52, 0xb7, 0x77, 0xbb, +0x5d, 0x27, 0x99, 0xf7, 0xfb, 0x7d, 0xa7, 0x32, +0xa7, 0x34, 0x5a, 0x7b, 0x48, 0x92, 0xa6, 0x98, +0xeb, 0x1b, 0x1b, 0x1b, 0xce, 0x39, 0x8e, 0x88, +0x2a, 0x8f, 0xd9, 0xbe, 0xb3, 0xb3, 0x83, 0x93, +0x93, 0x13, 0xdc, 0xb9, 0x73, 0xc7, 0x79, 0xbf, +0x93, 0x03, 0x1d, 0x8d, 0x2f, 0x95, 0xfd, 0xce, +0x3b, 0xef, 0x94, 0x08, 0x39, 0xa5, 0xd9, 0xd9, +0xd9, 0x71, 0x79, 0x5f, 0x7f, 0xfd, 0x75, 0xe7, +0x31, 0xdf, 0xef, 0xf7, 0xb1, 0xb7, 0xb7, 0x87, +0xe1, 0x70, 0x88, 0xdf, 0xff, 0xfd, 0xdf, 0xc7, +0x3b, 0xef, 0xbc, 0x83, 0x6e, 0xb7, 0x8b, 0x83, +0x83, 0x03, 0xdc, 0xbd, 0x7b, 0x17, 0xbd, 0x5e, +0x0f, 0x6b, 0x4b, 0x53, 0x2d, 0xd0, 0x52, 0xff, +0x21, 0xfe, 0xf6, 0xca, 0x39, 0x76, 0xba, 0xfa, +0xc5, 0x3e, 0x8d, 0x80, 0x6f, 0xd2, 0xc0, 0x7c, +0x53, 0xd2, 0xee, 0xe4, 0xe6, 0xdf, 0x7d, 0xc0, +0x43, 0x8b, 0xd6, 0x85, 0xf3, 0xd4, 0xde, 0x5b, +0xe1, 0x38, 0x39, 0xce, 0x4d, 0xc0, 0x6a, 0x0b, +0x2f, 0x5b, 0x63, 0x16, 0x9e, 0x85, 0x81, 0xf1, +0xb5, 0xc9, 0xba, 0xe5, 0x4d, 0xbb, 0x6b, 0x5e, +0x83, 0xba, 0xfa, 0xf9, 0x15, 0xb3, 0x5a, 0x58, +0xd5, 0xba, 0x32, 0x94, 0xf6, 0x92, 0x9a, 0x39, +0x0d, 0x94, 0x98, 0xe7, 0x32, 0x64, 0xea, 0x55, +0xf1, 0x95, 0xd2, 0x35, 0xe1, 0xcf, 0xfb, 0xc3, +0x9a, 0x7f, 0x16, 0xf0, 0xfc, 0x32, 0x70, 0xcb, +0xb3, 0xf4, 0xa9, 0xc4, 0x8f, 0x33, 0x32, 0xb2, +0x1f, 0x9a, 0x94, 0x3f, 0x6b, 0x73, 0xd0, 0x8d, +0x23, 0x8c, 0xf2, 0xb2, 0x4a, 0x90, 0x6f, 0xc6, +0x1a, 0x81, 0xac, 0x93, 0xbc, 0xac, 0x0d, 0x96, +0x88, 0x0a, 0x81, 0x94, 0xce, 0xe5, 0xe6, 0xaf, +0x11, 0x74, 0x4d, 0xca, 0x92, 0x75, 0x5c, 0x65, +0x83, 0xf7, 0x9d, 0x55, 0x6f, 0x6a, 0xf7, 0xa7, +0xb4, 0x75, 0x2a, 0x5d, 0x2d, 0x0d, 0xb5, 0x4f, +0xbb, 0xce, 0x94, 0x9e, 0xf9, 0xd1, 0x3f, 0x59, +0xae, 0xd6, 0xf7, 0xf2, 0x52, 0x1b, 0x29, 0x79, +0x6b, 0x63, 0xa2, 0x8d, 0x77, 0x13, 0x55, 0xbb, +0xaf, 0xdf, 0x2c, 0x42, 0x7f, 0x15, 0xbb, 0xbd, +0xe6, 0xa9, 0x7e, 0x55, 0x93, 0x46, 0x9d, 0x54, +0xdf, 0xc4, 0xff, 0x00, 0x80, 0x3b, 0x4e, 0x46, +0x63, 0x42, 0x52, 0x36, 0xdd, 0x3b, 0xce, 0xf3, +0x74, 0x3a, 0x1d, 0x27, 0x25, 0x03, 0xf3, 0x0b, +0x5b, 0x28, 0xf6, 0x01, 0x9d, 0x2f, 0xa7, 0xb2, +0x79, 0xcc, 0x76, 0x8a, 0x1e, 0x47, 0x76, 0x76, +0xce, 0x64, 0xf2, 0x73, 0xe5, 0x24, 0xc1, 0xf3, +0x2b, 0x5a, 0x29, 0x6a, 0x1c, 0xa9, 0xd9, 0x93, +0x64, 0x7a, 0x86, 0x9d, 0xae, 0x4b, 0x1d, 0x0e, +0x87, 0x78, 0xfb, 0xed, 0xb7, 0x4b, 0x47, 0xea, +0x28, 0xcd, 0xef, 0xfc, 0xce, 0xef, 0xe0, 0xa7, +0x3f, 0xfd, 0x29, 0x80, 0x29, 0xb3, 0xfe, 0xb5, +0x5e, 0x07, 0xbf, 0xb9, 0x26, 0xbd, 0xac, 0xae, +0x00, 0x3c, 0xd2, 0x19, 0x97, 0x40, 0x9a, 0x4a, +0xc4, 0xd6, 0xa6, 0xf8, 0x45, 0x24, 0x6a, 0x2d, +0xb6, 0xb7, 0xc4, 0xf9, 0x59, 0xca, 0x23, 0x7c, +0xb5, 0x8b, 0x40, 0x7c, 0xe5, 0x3f, 0x8b, 0x0f, +0x81, 0x04, 0x2b, 0x66, 0x7a, 0x93, 0x7e, 0x6a, +0x12, 0xc1, 0x8d, 0x13, 0x44, 0x6d, 0xfc, 0xae, +0x18, 0x17, 0x20, 0x0d, 0x62, 0xdb, 0xe6, 0x2f, +0x2f, 0xba, 0xb9, 0x2a, 0xbe, 0xd4, 0x85, 0x54, +0xbe, 0x1c, 0xe7, 0x2c, 0x2b, 0x13, 0xe4, 0x3a, +0xe0, 0xed, 0xe5, 0x51, 0xe1, 0x7c, 0xf9, 0x1b, +0xe0, 0x68, 0xe2, 0xd7, 0x84, 0xc1, 0xb0, 0x6c, +0xe6, 0xe7, 0x17, 0x17, 0x18, 0x9c, 0xf6, 0x55, +0x95, 0xb3, 0x65, 0x13, 0xd6, 0x08, 0x8e, 0xfc, +0xce, 0xf3, 0xd3, 0x37, 0x92, 0xd2, 0x25, 0x48, +0xe7, 0x2a, 0x8d, 0xa0, 0x58, 0x0e, 0x5a, 0x4d, +0x9c, 0xf4, 0xac, 0xcd, 0xdf, 0x72, 0xd8, 0xd3, +0x24, 0x2c, 0x4d, 0x65, 0x2f, 0x6d, 0xf6, 0x32, +0xbf, 0xc4, 0xc9, 0x92, 0x86, 0x35, 0x29, 0x5b, +0xd6, 0x4f, 0xfd, 0x27, 0xcb, 0xe3, 0x7d, 0x2b, +0xf3, 0x70, 0x46, 0x85, 0x08, 0x80, 0xe6, 0xc7, +0x40, 0xf9, 0xe4, 0x85, 0x35, 0x92, 0xf9, 0xe2, +0x69, 0x2d, 0xe9, 0x58, 0xd3, 0x5e, 0x68, 0xed, +0xe7, 0x6d, 0xd7, 0x98, 0x0d, 0x4d, 0x33, 0xe4, +0x53, 0xfd, 0xfb, 0xb4, 0x49, 0xda, 0xd8, 0x92, +0x93, 0x1a, 0x39, 0x18, 0x92, 0x2a, 0x9b, 0xa7, +0xe5, 0xef, 0xb8, 0x54, 0x4e, 0xc4, 0x93, 0xbc, +0xda, 0xa9, 0x8e, 0x4e, 0xa7, 0xe3, 0xc2, 0xb3, +0x12, 0x21, 0x5f, 0x5f, 0x5f, 0x77, 0x75, 0x91, +0x34, 0x4f, 0x67, 0xd1, 0x0f, 0x0f, 0x0f, 0x9d, +0xda, 0x7e, 0x63, 0x63, 0xc3, 0xdd, 0xb1, 0x4e, +0x67, 0xd2, 0xd7, 0xd7, 0xd7, 0x9d, 0x03, 0x1b, +0x30, 0x3d, 0xd6, 0x46, 0x01, 0x9a, 0xee, 0xde, +0xbd, 0x5b, 0xba, 0xa5, 0x8d, 0xc6, 0x9a, 0x8e, +0xb4, 0x11, 0x13, 0x40, 0xa1, 0x66, 0x49, 0xcd, +0x7e, 0xef, 0xde, 0x3d, 0x9c, 0x9c, 0x9c, 0xb8, +0x80, 0x38, 0x5c, 0xaa, 0xbf, 0x7b, 0xf7, 0x2e, +0x7e, 0xeb, 0xb7, 0x7e, 0xab, 0x74, 0xa3, 0xdb, +0x6f, 0x8f, 0xef, 0xe1, 0x95, 0x0e, 0x0b, 0xfb, +0xfa, 0x2c, 0x84, 0x86, 0x4b, 0xd0, 0xb4, 0x11, +0x36, 0xd9, 0x4c, 0x7d, 0x17, 0x94, 0x5c, 0x45, +0xb2, 0xe2, 0x78, 0xd7, 0x11, 0x8b, 0xab, 0x82, +0x2c, 0x8f, 0x33, 0x0b, 0xcf, 0x0a, 0x57, 0xb1, +0xc9, 0x5a, 0xb7, 0x99, 0x5d, 0xb5, 0x7f, 0x7c, +0xe5, 0x73, 0x49, 0xf9, 0x2a, 0xe3, 0xe7, 0x6b, +0x62, 0xa0, 0x48, 0xf9, 0xbc, 0x1f, 0x9b, 0x96, +0x6f, 0xf4, 0x8d, 0x2b, 0x5f, 0xd3, 0x92, 0x34, +0x9d, 0xc3, 0x91, 0xa2, 0x39, 0x78, 0x16, 0xf3, +0x82, 0x92, 0xde, 0xe1, 0x47, 0xc0, 0x71, 0xf4, +0x69, 0x76, 0x3c, 0x10, 0xac, 0xcc, 0xee, 0x5d, +0xe6, 0xa0, 0x6d, 0xba, 0x3e, 0x7b, 0x34, 0x7f, +0xc7, 0xc1, 0x52, 0x4f, 0x6b, 0x9b, 0xbf, 0x26, +0x81, 0x6b, 0x92, 0x58, 0x9d, 0xfa, 0xb6, 0x4e, +0x73, 0x20, 0xf1, 0xe4, 0x44, 0x8c, 0xdb, 0x9c, +0x35, 0x02, 0x50, 0xa7, 0xf2, 0xd7, 0xbe, 0xd5, +0x11, 0x3e, 0x02, 0xae, 0x3e, 0xd5, 0xc6, 0x40, +0x9a, 0x2e, 0x08, 0xa4, 0x4d, 0x5c, 0x32, 0x0b, +0xbc, 0x6f, 0x35, 0xdb, 0xb8, 0xac, 0x4b, 0x63, +0xb6, 0x24, 0x53, 0x63, 0x31, 0x03, 0x5a, 0xda, +0xba, 0x39, 0x64, 0xfd, 0xb6, 0xfa, 0xc9, 0x02, +0x8b, 0x09, 0x94, 0x6d, 0x22, 0xbc, 0xb9, 0x6a, +0x9d, 0x5f, 0x73, 0xca, 0xf1, 0xa0, 0x34, 0x5c, +0xfa, 0xe5, 0xcc, 0x00, 0x00, 0x47, 0x5c, 0x39, +0x33, 0xc5, 0xcd, 0x1a, 0x27, 0x27, 0x27, 0x18, +0x8d, 0x46, 0x38, 0x3e, 0x3e, 0x76, 0x04, 0x97, +0x9f, 0x4e, 0x00, 0x80, 0xe3, 0xe3, 0x63, 0x37, +0x0f, 0xa9, 0xae, 0x24, 0x99, 0x06, 0x94, 0x21, +0x42, 0xcb, 0xe3, 0x05, 0xec, 0xec, 0xec, 0x38, +0xc6, 0xe0, 0xe0, 0xe0, 0xc0, 0xc5, 0x6a, 0xa7, +0xb6, 0xee, 0xec, 0xec, 0x60, 0x30, 0x18, 0xb8, +0x73, 0xe6, 0x24, 0xe9, 0x13, 0x43, 0x47, 0x0c, +0x05, 0xa9, 0xdf, 0x07, 0x83, 0x01, 0x5e, 0x7f, +0xfd, 0x75, 0xc7, 0x38, 0xbc, 0xf3, 0xce, 0x3b, +0x78, 0xe7, 0x9d, 0x77, 0xf0, 0xf6, 0xdb, 0x6f, +0x63, 0xd2, 0x7f, 0x82, 0xff, 0xb4, 0x37, 0xc0, +0x0b, 0x5d, 0xcc, 0xed, 0x7a, 0x75, 0xc0, 0x6d, +0x9e, 0x52, 0x8d, 0x28, 0xd5, 0x8b, 0x4d, 0x80, +0xdb, 0x10, 0xaf, 0x22, 0x51, 0x49, 0x2f, 0x68, +0x69, 0x6b, 0xa7, 0x2b, 0x53, 0x09, 0xd7, 0x2f, +0x72, 0x4e, 0x5b, 0x03, 0x5e, 0xbe, 0x65, 0x43, +0xe7, 0x75, 0x5b, 0x76, 0x62, 0x5f, 0x9f, 0x5b, +0x2a, 0x6a, 0xde, 0xe7, 0xb2, 0xfe, 0x3a, 0x5b, +0xb4, 0x86, 0x2f, 0xf5, 0x19, 0xbd, 0xe3, 0xaa, +0x7d, 0xad, 0xff, 0x9a, 0xf6, 0x99, 0x75, 0xfd, +0xac, 0xa6, 0xd1, 0x91, 0x65, 0x4e, 0x46, 0xfe, +0xbe, 0xe1, 0xbe, 0x11, 0xd6, 0x55, 0xa6, 0x5a, +0x1e, 0xfe, 0xdf, 0xba, 0x7a, 0xb5, 0x09, 0x7e, +0x4d, 0xc6, 0xcf, 0x37, 0x76, 0x56, 0xff, 0x1a, +0xe3, 0x17, 0x0c, 0x26, 0x69, 0x2d, 0xf1, 0xe3, +0xf6, 0x71, 0xfa, 0xee, 0x93, 0xce, 0xf9, 0xbb, +0x3a, 0x89, 0x55, 0xd6, 0x67, 0x11, 0x08, 0x59, +0x87, 0x55, 0x9f, 0x95, 0xd6, 0xca, 0xc3, 0xf1, +0xf4, 0x05, 0xbf, 0xd1, 0xfa, 0xc8, 0xe7, 0x30, +0xc8, 0x89, 0xaa, 0xe6, 0x98, 0xa6, 0xf5, 0xb3, +0xe6, 0xa0, 0x47, 0x65, 0x91, 0x7d, 0xd6, 0x92, +0xe6, 0xb9, 0xc7, 0xb4, 0xfc, 0x4e, 0x78, 0xd2, +0x75, 0xb1, 0x75, 0x9a, 0x05, 0x5f, 0xc4, 0x38, +0x9f, 0xe6, 0x44, 0xd3, 0x36, 0xf0, 0xbe, 0xb2, +0xfa, 0x5d, 0xaa, 0xd3, 0x7d, 0x65, 0xd7, 0x39, +0x0d, 0xca, 0xf1, 0xb2, 0x18, 0x39, 0x52, 0x59, +0x93, 0xda, 0x9a, 0x7b, 0xb4, 0x6b, 0xed, 0x20, +0x09, 0x98, 0x1f, 0x63, 0xe3, 0x4e, 0x6f, 0x92, +0xd8, 0xaf, 0xaf, 0xaf, 0x63, 0x30, 0x18, 0x94, +0xec, 0xee, 0xda, 0xdc, 0x22, 0x89, 0x9f, 0x8f, +0x31, 0x5d, 0xa9, 0x4a, 0x92, 0x35, 0xf7, 0x5a, +0x27, 0xa9, 0x99, 0x24, 0xf7, 0x7b, 0xf7, 0xee, +0x95, 0x4c, 0x2b, 0x5f, 0xfd, 0xea, 0x57, 0x01, +0xc0, 0xdd, 0x7b, 0x4e, 0xd2, 0x3e, 0xb5, 0x85, +0x9c, 0xee, 0x0e, 0x0e, 0x0e, 0x70, 0xef, 0xde, +0x3d, 0x8c, 0x46, 0x23, 0xec, 0xed, 0xed, 0xb9, +0x71, 0xbf, 0x77, 0xef, 0x1e, 0x1e, 0x3e, 0x7c, +0x08, 0x60, 0x1a, 0x0e, 0x76, 0xef, 0xd6, 0x73, +0x78, 0xe3, 0x5a, 0x07, 0xff, 0xc7, 0xe7, 0x02, +0xbc, 0xb0, 0x12, 0x62, 0xb9, 0x49, 0x08, 0x74, +0x92, 0xc0, 0xa5, 0x7d, 0x91, 0x5f, 0x10, 0xe1, +0x23, 0xca, 0x72, 0xb3, 0xd2, 0x2e, 0x99, 0xa8, +0x23, 0xea, 0x94, 0x5e, 0x7b, 0xa7, 0xdd, 0x0f, +0x0d, 0x94, 0x09, 0x56, 0xd3, 0xe3, 0x50, 0x9a, +0x54, 0x69, 0xdd, 0x3f, 0x6d, 0xe5, 0xaf, 0xb3, +0x13, 0xfb, 0x80, 0xc2, 0xab, 0xf2, 0x3a, 0x34, +0xdb, 0x33, 0xc7, 0xb1, 0x2e, 0xfc, 0xad, 0x36, +0x6e, 0xfc, 0xb7, 0xf6, 0x9d, 0xf7, 0x9f, 0xfc, +0xed, 0x03, 0x6b, 0x3e, 0x34, 0xb1, 0x71, 0xc7, +0x1d, 0x7f, 0xd9, 0x12, 0x6f, 0xae, 0x31, 0xb1, +0xe6, 0x8f, 0x26, 0x1d, 0x6b, 0xa6, 0x13, 0xad, +0x5f, 0x88, 0xb8, 0x13, 0x34, 0x71, 0xe0, 0xf3, +0xb5, 0xdf, 0xaa, 0xdb, 0x18, 0xbf, 0xf0, 0xe6, +0xb7, 0x7e, 0xf0, 0x66, 0x7c, 0x74, 0xdf, 0x6d, +0x32, 0x3c, 0x48, 0xcb, 0x38, 0x2f, 0xb0, 0x3c, +0xdb, 0x68, 0xc6, 0x79, 0x81, 0xb0, 0xd5, 0x2a, +0x6d, 0xaa, 0x14, 0xc8, 0x83, 0x40, 0x06, 0x02, +0x49, 0x92, 0xf9, 0xd5, 0x93, 0x32, 0xa0, 0x48, +0x92, 0x24, 0x18, 0x0c, 0x47, 0x28, 0xf2, 0xdc, +0x95, 0x49, 0xf9, 0x93, 0x64, 0x1e, 0xf8, 0x45, +0x0b, 0x00, 0x23, 0x83, 0xa7, 0x58, 0xdf, 0x78, +0x40, 0x15, 0x1e, 0x8c, 0x84, 0x5f, 0x5e, 0xc1, +0xdf, 0x51, 0xbb, 0xe8, 0xfb, 0xf9, 0xf9, 0xb9, +0xbb, 0xf4, 0x45, 0x06, 0x81, 0xa1, 0x36, 0x52, +0x5e, 0xfe, 0x9c, 0x24, 0x09, 0xb6, 0xb6, 0xb6, +0x4a, 0x78, 0x68, 0xf8, 0xc8, 0x6b, 0x67, 0xb9, +0xc7, 0x32, 0x5d, 0x81, 0x4a, 0xc1, 0x77, 0xe8, +0xea, 0xcb, 0x27, 0x4f, 0x9e, 0xb8, 0x32, 0xb4, +0xe0, 0x35, 0x54, 0xbf, 0x0c, 0xe0, 0x43, 0xff, +0xf9, 0x15, 0xb6, 0x56, 0x80, 0x18, 0x59, 0x9e, +0x7c, 0x4f, 0x63, 0xcf, 0x03, 0xa9, 0xf0, 0x3e, +0x96, 0x63, 0x27, 0xfb, 0x5f, 0x5e, 0x6c, 0xc3, +0xdb, 0xcf, 0x9f, 0x65, 0x90, 0x19, 0x19, 0x34, +0xc8, 0x0a, 0x32, 0x24, 0xfb, 0xdd, 0x9a, 0x37, +0xad, 0x56, 0x0b, 0x51, 0x14, 0xb9, 0x4b, 0x51, +0x78, 0x9f, 0xd0, 0x7a, 0xe0, 0xb1, 0xdc, 0xa9, +0x6e, 0xba, 0x90, 0x25, 0xcb, 0x32, 0x77, 0xb9, +0x0a, 0x49, 0xe0, 0xeb, 0xeb, 0xeb, 0xd8, 0xd8, +0xd8, 0xc0, 0xc5, 0xc5, 0x45, 0x69, 0xac, 0x68, +0x6c, 0x5f, 0x7c, 0xf1, 0x45, 0xc4, 0x71, 0x8c, +0xc3, 0xc3, 0x43, 0x37, 0xfe, 0x64, 0xb3, 0x26, +0x9c, 0x68, 0xdc, 0xef, 0xdd, 0xbb, 0xe7, 0xd2, +0x2c, 0x2f, 0x2f, 0xe3, 0xce, 0x9d, 0x3b, 0x18, +0x0e, 0x87, 0x78, 0xf0, 0xe0, 0x81, 0x8b, 0x16, +0x77, 0x74, 0x74, 0xe4, 0xec, 0xe4, 0xb7, 0x6f, +0xdf, 0xc6, 0xc6, 0xc6, 0x86, 0x93, 0xd4, 0xb9, +0x59, 0x8b, 0xca, 0x23, 0x15, 0xfd, 0xfd, 0xfb, +0xf7, 0x1d, 0x61, 0xa7, 0xab, 0x76, 0xdf, 0x7b, +0xef, 0x3d, 0x9c, 0x9c, 0x9c, 0xb8, 0x60, 0x38, +0x2b, 0x2b, 0x2b, 0x40, 0x9e, 0x4d, 0x35, 0x06, +0x17, 0xc7, 0x78, 0x23, 0x3a, 0xc3, 0x77, 0xf7, +0x37, 0xf1, 0x46, 0x2f, 0xc4, 0x7b, 0xc3, 0x00, +0x17, 0x83, 0x01, 0x10, 0xd6, 0x38, 0xc8, 0x15, +0x05, 0x10, 0x45, 0xd3, 0x6b, 0x45, 0xa3, 0x08, +0x40, 0x31, 0x7f, 0x0f, 0xc5, 0x1e, 0x4f, 0xd2, +0x73, 0x10, 0xce, 0x2f, 0xd5, 0xc8, 0xb2, 0xe9, +0xff, 0x20, 0x98, 0xbe, 0x03, 0xf4, 0x2b, 0x4a, +0x29, 0x7f, 0xbb, 0x33, 0xcd, 0x9f, 0xa5, 0xd5, +0xef, 0x74, 0x51, 0x05, 0x5d, 0x73, 0x4a, 0x57, +0x49, 0x52, 0x99, 0x94, 0x6f, 0x32, 0xac, 0x6f, +0x1b, 0x30, 0xbf, 0xf0, 0x83, 0xfe, 0xd7, 0x95, +0xcf, 0x03, 0x7d, 0x4c, 0x46, 0xb3, 0x40, 0x28, +0xec, 0x8a, 0xcb, 0x2c, 0xb5, 0x2f, 0x32, 0x69, +0x82, 0x47, 0xbb, 0x33, 0xef, 0x6b, 0xba, 0xce, +0x95, 0x97, 0xdf, 0xf4, 0x42, 0x1a, 0x6a, 0x93, +0x6c, 0x0f, 0x31, 0x36, 0xf2, 0x3b, 0xef, 0xbf, +0xc9, 0x04, 0xc8, 0x53, 0xbd, 0xff, 0x64, 0xd0, +0x17, 0xc2, 0x87, 0xca, 0xa3, 0x2b, 0x47, 0x79, +0xff, 0xf1, 0x6b, 0x69, 0xaf, 0xd2, 0x2f, 0x79, +0x3e, 0x1f, 0xcf, 0x6c, 0xb6, 0x17, 0x84, 0xe1, +0x14, 0x67, 0x14, 0xfe, 0x80, 0x2e, 0xd4, 0x9f, +0x72, 0xbe, 0x51, 0xfe, 0x28, 0x9a, 0xf6, 0x05, +0x7d, 0xe7, 0xf8, 0xd2, 0xbc, 0xb5, 0xfa, 0x9a, +0xe6, 0x33, 0x6f, 0x3f, 0xad, 0x07, 0xde, 0x7e, +0x2a, 0xb3, 0x61, 0xfb, 0x83, 0xa1, 0xe7, 0x5c, +0x6d, 0x3b, 0x98, 0x6f, 0x72, 0xf9, 0xd8, 0x4e, +0x47, 0x50, 0x27, 0x99, 0xcb, 0x6f, 0xda, 0x6f, +0x7a, 0xf6, 0xd9, 0x46, 0xeb, 0xea, 0xad, 0x73, +0xc0, 0xf2, 0xa9, 0xc7, 0x25, 0xde, 0x52, 0x82, +0x6d, 0xd2, 0x6e, 0x89, 0xa7, 0x25, 0x79, 0xfa, +0xf0, 0x95, 0x92, 0xbf, 0x94, 0x9c, 0xc9, 0x9e, +0x2b, 0x55, 0xe4, 0x3e, 0x3b, 0x31, 0xfd, 0xb6, +0xbc, 0xe2, 0x65, 0xfb, 0xb8, 0xa6, 0x42, 0x73, +0x46, 0xb3, 0xec, 0xe3, 0xb2, 0xcd, 0x75, 0x69, +0xad, 0x71, 0xd5, 0xbe, 0x37, 0x19, 0x6b, 0x4b, +0x65, 0xaf, 0xd5, 0x7f, 0x72, 0x72, 0xe2, 0x6c, +0xda, 0x64, 0x43, 0xe6, 0x84, 0x9c, 0x13, 0xe9, +0xe1, 0x70, 0xe8, 0x9c, 0xdd, 0xf8, 0x05, 0x2c, +0x24, 0xb5, 0xd3, 0x77, 0xe9, 0x7b, 0x40, 0x1a, +0x11, 0x3a, 0x4d, 0xc0, 0x35, 0x24, 0xa4, 0x0e, +0x07, 0xe0, 0x1c, 0xd4, 0xc8, 0x8e, 0x4d, 0xb6, +0x6e, 0x0a, 0x09, 0x4b, 0x92, 0x33, 0xf7, 0x8a, +0x27, 0x07, 0xbc, 0xdb, 0xb7, 0x6f, 0xbb, 0xa3, +0x6c, 0x5c, 0x15, 0x4f, 0x76, 0x7b, 0x62, 0x16, +0x6e, 0xdf, 0xbe, 0xed, 0xca, 0xa6, 0xd0, 0xaf, +0x74, 0x16, 0xfd, 0xd1, 0xa3, 0x47, 0xe8, 0x74, +0x3a, 0x25, 0x3c, 0xa9, 0xbc, 0xdd, 0xdd, 0x5d, +0xbc, 0xfa, 0xe2, 0xf3, 0xf8, 0xc9, 0x56, 0x84, +0xff, 0xf5, 0x26, 0xf0, 0x5f, 0xee, 0xb5, 0xb0, +0xb2, 0xbc, 0x5c, 0x1d, 0xa8, 0x89, 0xb8, 0x56, +0xd6, 0x52, 0x6b, 0x5a, 0xd2, 0xa1, 0x26, 0x81, +0xf1, 0xb4, 0x52, 0x02, 0x6e, 0x92, 0x9f, 0xe3, +0x64, 0x49, 0xce, 0x32, 0x5f, 0x9d, 0xd4, 0x67, +0x49, 0x5d, 0x56, 0x79, 0x52, 0x6d, 0x4a, 0x75, +0x48, 0x89, 0xb1, 0xce, 0xfc, 0x60, 0xd5, 0xab, +0xa9, 0x85, 0x65, 0x3b, 0x9b, 0x5e, 0x80, 0x23, +0xcb, 0xe3, 0x78, 0x49, 0x15, 0xfc, 0x55, 0xfb, +0x4f, 0x4a, 0xaf, 0xd6, 0xf8, 0x35, 0xd5, 0xc0, +0x48, 0x90, 0xf3, 0x4f, 0xaa, 0xee, 0x81, 0xb9, +0xc9, 0xa5, 0x49, 0xff, 0x6a, 0x9a, 0x0d, 0x3a, +0x42, 0xc6, 0xd3, 0x68, 0xf5, 0x59, 0xa0, 0x8d, +0x03, 0xbf, 0x3e, 0xd8, 0xa7, 0xe9, 0xf1, 0x40, +0xd0, 0x0a, 0x42, 0xd3, 0xf9, 0x6b, 0x9c, 0xeb, +0x9e, 0xac, 0x3e, 0x42, 0xe8, 0xb3, 0x81, 0xbb, +0xfe, 0x4e, 0x33, 0x4c, 0xd2, 0xcc, 0x9d, 0x39, +0xa7, 0xef, 0x75, 0xea, 0x7e, 0xfe, 0x4e, 0xb3, +0xcd, 0xfa, 0x9c, 0xe1, 0x9e, 0xd5, 0x23, 0x5b, +0x4b, 0x6b, 0x7d, 0x6b, 0xe2, 0xb8, 0xc7, 0x7f, +0x5b, 0xfd, 0x0e, 0xcc, 0x4d, 0x1b, 0xdc, 0xcb, +0x9d, 0x80, 0xee, 0xd8, 0x96, 0x6a, 0x70, 0x69, +0xef, 0xb6, 0x3c, 0xc1, 0xa5, 0xfd, 0x5c, 0xc3, +0x95, 0x83, 0x75, 0x51, 0x8d, 0xd6, 0x4e, 0x6b, +0x1c, 0x2d, 0x27, 0x43, 0xdf, 0x18, 0xd4, 0x31, +0x26, 0x75, 0xe3, 0xa3, 0x39, 0x30, 0x5a, 0x8e, +0x9c, 0x74, 0x26, 0x9c, 0x62, 0xb1, 0x73, 0xbb, +0xba, 0x0f, 0x3f, 0xcb, 0x7c, 0x40, 0xc4, 0x9a, +0xfe, 0xd3, 0x25, 0x2a, 0x64, 0x3b, 0xa7, 0x3a, +0x89, 0x39, 0xe0, 0xce, 0x76, 0x94, 0x9f, 0x33, +0x16, 0x74, 0xc1, 0x0b, 0xa9, 0xd4, 0xa9, 0x1c, +0xca, 0xb3, 0xb1, 0xb1, 0xe1, 0x8e, 0x9f, 0xdd, +0xbe, 0x7d, 0xdb, 0x79, 0xb4, 0x93, 0x57, 0x3d, +0x00, 0xe7, 0x78, 0x47, 0x8c, 0x08, 0x05, 0x99, +0xa1, 0x1b, 0xdb, 0x28, 0x82, 0xdc, 0xe1, 0xe1, +0x21, 0x3e, 0xfa, 0xe8, 0x23, 0x3c, 0x7c, 0xf8, +0x10, 0x37, 0x9e, 0xbb, 0xed, 0xee, 0x5a, 0xff, +0xec, 0xfe, 0xa7, 0xf8, 0xd9, 0xcf, 0x7e, 0x86, +0x5f, 0xfc, 0xfc, 0xcf, 0xf0, 0xad, 0xf4, 0x11, +0x0e, 0x5a, 0x8a, 0x47, 0x32, 0xdb, 0xc4, 0xa3, +0x9c, 0x6d, 0x7a, 0xbe, 0xdb, 0xcd, 0x24, 0xb1, +0xa5, 0xff, 0x7c, 0x53, 0xa4, 0x34, 0x54, 0x4e, +0x9e, 0xda, 0x47, 0xcf, 0x28, 0x9d, 0x82, 0x13, +0xc2, 0x10, 0x18, 0x9c, 0x97, 0xf1, 0x91, 0xc7, +0xb8, 0x9a, 0x10, 0x3d, 0x5f, 0x1a, 0x79, 0xff, +0x34, 0xc7, 0x47, 0x96, 0x2f, 0x89, 0x02, 0xff, +0x4e, 0x6d, 0xe6, 0xfd, 0x63, 0xd5, 0xab, 0xdd, +0xc5, 0x2e, 0x1d, 0xf1, 0x7c, 0x76, 0x6c, 0x49, +0x04, 0x39, 0x71, 0xe1, 0x78, 0xcb, 0xbb, 0xdf, +0xaf, 0xda, 0x7f, 0x75, 0x7d, 0xab, 0xdd, 0x2f, +0xcf, 0x89, 0xfb, 0x44, 0x5f, 0x93, 0x2e, 0xaa, +0x9a, 0xc5, 0x44, 0xc8, 0xdb, 0xde, 0x34, 0x3c, +0x26, 0xa3, 0xea, 0x7b, 0xce, 0x08, 0xf1, 0x76, +0xe6, 0x69, 0xb9, 0x7f, 0x28, 0xad, 0xef, 0xc6, +0x3a, 0x0e, 0x16, 0x33, 0x61, 0xb5, 0xbf, 0x01, +0x04, 0x9d, 0x78, 0xae, 0x9a, 0x95, 0x04, 0xa6, +0x1d, 0xb4, 0xcc, 0x8c, 0x75, 0x1e, 0xdf, 0xf4, +0x8d, 0xff, 0x1e, 0x0e, 0x87, 0x98, 0xa4, 0x19, +0xb2, 0x74, 0x82, 0x2c, 0x9d, 0x34, 0x72, 0x5e, +0xf3, 0xd5, 0xcb, 0xc1, 0x27, 0xf9, 0x69, 0x8e, +0x74, 0xda, 0x7f, 0xfe, 0xbb, 0x0e, 0x0f, 0x09, +0x3e, 0xe2, 0xaf, 0x79, 0xb2, 0x13, 0x68, 0x81, +0x68, 0xa4, 0x93, 0x19, 0x2f, 0x8b, 0x47, 0x12, +0x93, 0xe1, 0x3c, 0xb5, 0xba, 0x7c, 0xc4, 0x4f, +0x4a, 0xde, 0x5a, 0x5f, 0x35, 0x2d, 0x4b, 0xd3, +0x66, 0x68, 0x0c, 0x8b, 0xe6, 0xd8, 0xd7, 0x94, +0x51, 0xa0, 0x77, 0x3c, 0x4f, 0x93, 0xc0, 0x3f, +0xd6, 0x98, 0x10, 0xb1, 0xe3, 0x9e, 0xea, 0x9c, +0x80, 0xf3, 0xf9, 0x2c, 0xaf, 0xf9, 0x25, 0x69, +0x5c, 0x6b, 0x2f, 0x0f, 0x0c, 0xc3, 0x3d, 0xda, +0x37, 0x36, 0x36, 0x9c, 0xed, 0x9c, 0x6c, 0xd9, +0x92, 0x49, 0x93, 0x01, 0x6c, 0x8e, 0x8f, 0x8f, +0x4b, 0x81, 0x6b, 0x34, 0x7c, 0xf8, 0xf5, 0xab, +0xbb, 0xbb, 0xbb, 0xae, 0x5c, 0xba, 0x36, 0x95, +0xe3, 0x31, 0x18, 0x0c, 0xdc, 0x35, 0xad, 0xc7, +0xc7, 0xc7, 0xa5, 0x79, 0x45, 0xc4, 0xfd, 0xf0, +0xf0, 0x10, 0x1b, 0x1b, 0x1b, 0x78, 0xf9, 0xe5, +0x97, 0x71, 0xfd, 0xda, 0x86, 0x73, 0xa4, 0x23, +0x35, 0xfd, 0xee, 0xee, 0x2e, 0x92, 0x6e, 0x17, +0xff, 0xfb, 0x83, 0x04, 0xfb, 0x1e, 0x01, 0xb6, +0xe4, 0x51, 0x0c, 0xd8, 0x0e, 0x5e, 0x72, 0x03, +0xe6, 0x76, 0x59, 0x2b, 0x0d, 0x3d, 0xf3, 0xcd, +0x9d, 0x3b, 0x67, 0x01, 0xa5, 0x8d, 0xb9, 0x14, +0x42, 0x73, 0x96, 0x37, 0xca, 0x27, 0xcf, 0xe6, +0x91, 0xad, 0xb5, 0x81, 0xf0, 0xd0, 0x88, 0x04, +0x3f, 0x43, 0x2c, 0x71, 0xe6, 0xf8, 0x5a, 0x36, +0x61, 0x8d, 0x40, 0x71, 0x1c, 0x0c, 0x02, 0x57, +0x21, 0xc8, 0x9a, 0xc6, 0x82, 0xf2, 0x3e, 0x8b, +0x26, 0xc2, 0x3a, 0x66, 0x38, 0xf1, 0x33, 0xc1, +0x5e, 0xa6, 0x4e, 0xda, 0x9c, 0x65, 0xf9, 0x06, +0x9e, 0x15, 0xef, 0x70, 0x0e, 0xd2, 0x79, 0xcf, +0x02, 0xab, 0x0f, 0x34, 0x5f, 0x03, 0x4a, 0x2b, +0xb5, 0x2a, 0x75, 0x6d, 0xaf, 0xeb, 0x03, 0x0e, +0x75, 0xc7, 0x38, 0x45, 0x5d, 0x01, 0xe0, 0x97, +0xaa, 0x38, 0x70, 0x22, 0x53, 0xf7, 0xdd, 0xda, +0xa8, 0x33, 0xc1, 0xb5, 0x58, 0x52, 0x9c, 0x4f, +0x4a, 0x97, 0x92, 0xa6, 0x26, 0xf9, 0x69, 0xef, +0x78, 0x7d, 0x9a, 0xb3, 0x95, 0x45, 0x70, 0x7d, +0x84, 0xba, 0x09, 0x58, 0x12, 0x26, 0xc7, 0x4f, +0xeb, 0x2b, 0xa9, 0x22, 0x26, 0x29, 0x0e, 0x98, +0xab, 0xda, 0xe9, 0xb7, 0x54, 0xe9, 0x6a, 0xce, +0x80, 0x1a, 0xa1, 0x96, 0x2a, 0x77, 0xcb, 0x13, +0x5d, 0x6b, 0x13, 0xaf, 0xc7, 0x92, 0x7c, 0xb5, +0xbe, 0xd6, 0x08, 0xba, 0x35, 0xd6, 0xb2, 0x4e, +0x8b, 0x31, 0xb3, 0xe6, 0x9b, 0x36, 0x9f, 0xf8, +0xef, 0xd1, 0x68, 0xe4, 0xfa, 0x8c, 0xbf, 0xe3, +0x69, 0x49, 0x0d, 0x4f, 0x40, 0x92, 0xad, 0xd6, +0xaf, 0x3c, 0xb6, 0x3b, 0x11, 0xbe, 0xd1, 0x68, +0xe4, 0x88, 0x2a, 0x27, 0xac, 0x7c, 0x0e, 0xf0, +0x3a, 0x79, 0x00, 0x20, 0x1a, 0xf3, 0x6e, 0xb7, +0x5b, 0xba, 0xa5, 0x90, 0xca, 0xa7, 0x39, 0xf0, +0xce, 0x3b, 0xef, 0x94, 0x1c, 0xe1, 0x88, 0xc0, +0x53, 0x7d, 0x64, 0x63, 0x27, 0x89, 0x1d, 0x80, +0x8b, 0x64, 0x07, 0xcc, 0x6f, 0x67, 0x7b, 0xf4, +0xe8, 0x91, 0x3b, 0x9f, 0x4e, 0x31, 0xdd, 0xdf, +0x7e, 0xfb, 0x6d, 0xf4, 0xfb, 0x7d, 0xdc, 0x78, +0xee, 0xf6, 0x9c, 0x61, 0x59, 0xea, 0xe2, 0xd6, +0xf8, 0x29, 0xfe, 0xbb, 0x83, 0x00, 0x7f, 0x63, +0x6d, 0x8c, 0x95, 0xb6, 0xc7, 0xbe, 0x4c, 0xea, +0x65, 0x92, 0xec, 0x34, 0xa0, 0x8d, 0x96, 0x4b, +0x36, 0x32, 0xad, 0xb6, 0x51, 0x4a, 0xa9, 0xdb, +0x90, 0x8c, 0xb4, 0xcd, 0x3e, 0x0d, 0x62, 0x5d, +0xea, 0xe2, 0xf5, 0x68, 0x75, 0x12, 0x5e, 0x4d, +0xbc, 0xc2, 0xb9, 0x94, 0x95, 0xce, 0xa5, 0x47, +0xc7, 0x5c, 0x70, 0x07, 0xb6, 0x26, 0xa0, 0x31, +0x0d, 0x92, 0x08, 0x49, 0x9c, 0xad, 0xf2, 0xe3, +0x8e, 0x4d, 0xc0, 0xa8, 0x0c, 0xc9, 0x00, 0xf0, +0x36, 0x4b, 0x2d, 0x80, 0x0f, 0x9f, 0x26, 0x44, +0x2e, 0xee, 0x94, 0xdb, 0xc5, 0xfb, 0xcc, 0x63, +0x26, 0xe0, 0x8c, 0x5a, 0x25, 0xee, 0x39, 0xa9, +0xa8, 0x69, 0x2c, 0x24, 0xb3, 0xd0, 0x04, 0x2f, +0x9f, 0x5a, 0x5e, 0xe2, 0xe4, 0x63, 0x8a, 0xac, +0xba, 0xac, 0xf9, 0x66, 0xb4, 0x5f, 0xd3, 0x42, +0x44, 0xf9, 0x04, 0xc1, 0xd3, 0x49, 0x55, 0x95, +0xae, 0x6d, 0x88, 0x7c, 0xa3, 0xa0, 0x77, 0x75, +0xd2, 0xb9, 0x46, 0x60, 0xc3, 0x28, 0x6e, 0xec, +0x85, 0xae, 0xe1, 0x24, 0x37, 0x66, 0xa9, 0x52, +0xb5, 0x3c, 0xb0, 0x25, 0x9e, 0x72, 0xe3, 0x97, +0xdf, 0xe4, 0x3b, 0x8e, 0x83, 0xfc, 0xae, 0x31, +0x14, 0x75, 0x2a, 0x62, 0x7e, 0xd4, 0xc8, 0xea, +0x47, 0xa9, 0x0e, 0xa7, 0x8d, 0x19, 0x80, 0xdb, +0x78, 0x65, 0x80, 0x18, 0x4a, 0x2b, 0x83, 0xe1, +0xd4, 0xe1, 0xa5, 0x49, 0xe8, 0xbc, 0x5c, 0xa9, +0x41, 0x90, 0xe5, 0x69, 0xf7, 0xd5, 0x6b, 0xed, +0x93, 0xf3, 0xca, 0x37, 0xb6, 0xb2, 0x8f, 0xb5, +0x79, 0x67, 0x11, 0x6a, 0x8d, 0x19, 0xd1, 0xd2, +0x4a, 0x86, 0x46, 0x12, 0x76, 0x22, 0x96, 0x44, +0xd4, 0x49, 0xda, 0xe5, 0xf5, 0x73, 0x53, 0x08, +0x11, 0x5f, 0x6d, 0x2e, 0xf0, 0xb8, 0xea, 0x7c, +0x1e, 0x50, 0xd9, 0xa4, 0x76, 0xef, 0xf7, 0xfb, +0xee, 0xce, 0x73, 0x7e, 0xb4, 0x8c, 0x98, 0x05, +0x8e, 0x1f, 0xbf, 0x27, 0x1d, 0x98, 0x9f, 0x81, +0xef, 0xf5, 0x7a, 0x4e, 0xbd, 0x4e, 0x78, 0x70, +0x6f, 0x78, 0x3a, 0x2e, 0x47, 0xc4, 0x9b, 0xda, +0x7e, 0x70, 0x70, 0xe0, 0xd4, 0xf5, 0xd4, 0x36, +0xd2, 0x08, 0xe4, 0xe3, 0x51, 0xc9, 0xfc, 0x33, +0x1c, 0x0e, 0x11, 0x7f, 0xf2, 0x0b, 0xfc, 0x27, +0x93, 0x0f, 0xf1, 0x83, 0xf5, 0x96, 0xbe, 0x69, +0xfb, 0xce, 0x74, 0x4b, 0xc2, 0xe0, 0xfb, 0x0e, +0xd4, 0x4b, 0x8f, 0x56, 0x3e, 0xdf, 0x86, 0xad, +0xd9, 0xe3, 0x79, 0x3d, 0x9a, 0x06, 0x40, 0xcb, +0xab, 0xe1, 0xc6, 0xbf, 0x0b, 0x9c, 0x4a, 0xcc, +0x05, 0x1d, 0xf9, 0x93, 0xea, 0x75, 0x0d, 0x9a, +0xf4, 0x81, 0x64, 0x70, 0x80, 0xaa, 0xfa, 0xbb, +0x8e, 0x88, 0xf1, 0x32, 0x24, 0x41, 0xb4, 0xfa, +0xda, 0x62, 0x48, 0x2c, 0xa6, 0xa1, 0x89, 0x76, +0x81, 0xda, 0x60, 0x69, 0x59, 0x44, 0x5f, 0x96, +0xfa, 0x75, 0x32, 0xaa, 0xfa, 0x0b, 0x48, 0x66, +0xa1, 0x8e, 0xf8, 0x72, 0xad, 0x8a, 0x75, 0xb4, +0x8f, 0x9f, 0xdc, 0xb0, 0xca, 0xe1, 0x7d, 0xea, +0x9b, 0xd7, 0xd6, 0x3c, 0x62, 0x78, 0x5b, 0x8c, +0x69, 0xb0, 0x75, 0xf6, 0x48, 0x25, 0xae, 0x80, +0x1d, 0xed, 0x4d, 0x4a, 0x24, 0x96, 0x74, 0xa5, +0xd9, 0xaa, 0xb9, 0x7a, 0x5d, 0xdb, 0x84, 0x9b, +0x38, 0x9c, 0x3d, 0x8b, 0x13, 0x95, 0x66, 0xc3, +0x97, 0x04, 0xcd, 0x92, 0x8e, 0xe5, 0xb3, 0xf5, +0xce, 0x92, 0x28, 0x7d, 0x3e, 0x06, 0x57, 0x01, +0xcd, 0x41, 0x8d, 0xfa, 0x98, 0x1f, 0x63, 0xe3, +0xdf, 0x29, 0x9f, 0xb4, 0xa7, 0x5b, 0x04, 0x50, +0x63, 0x94, 0xb4, 0xf1, 0xf2, 0xd9, 0xda, 0xeb, +0xb4, 0x1b, 0x92, 0x51, 0xb1, 0xea, 0xf3, 0xd5, +0x2d, 0xf1, 0xd0, 0x18, 0x31, 0x9f, 0xc9, 0x45, +0x3a, 0xa9, 0xd1, 0x37, 0x59, 0x36, 0x39, 0xc0, +0x01, 0x53, 0x02, 0xc8, 0x9d, 0xdd, 0x2c, 0x5c, +0x79, 0x7e, 0x1e, 0x54, 0x86, 0x88, 0xb6, 0x1c, +0x43, 0x02, 0x52, 0xf5, 0x13, 0x0e, 0xe4, 0x17, +0x41, 0x47, 0xd7, 0xf8, 0xf9, 0x74, 0xfa, 0x4d, +0xe5, 0xef, 0xec, 0xec, 0x38, 0x66, 0x80, 0xdf, +0xce, 0xc6, 0xfb, 0x86, 0x4b, 0xeb, 0xc0, 0x34, +0xb0, 0xcd, 0xce, 0xce, 0x0e, 0x86, 0xc3, 0x21, +0x1e, 0x3d, 0x7a, 0xe4, 0x9c, 0xe6, 0x28, 0x2d, +0xdd, 0x02, 0x47, 0x61, 0x67, 0x81, 0xe9, 0x91, +0x38, 0x7e, 0x0e, 0x1d, 0x00, 0x96, 0xd6, 0xd6, +0xf1, 0xb7, 0x57, 0xce, 0xf1, 0xf5, 0xf5, 0x4e, +0x95, 0xf8, 0x71, 0x5b, 0xab, 0x04, 0x85, 0xb8, +0x94, 0x36, 0xea, 0x30, 0xac, 0x97, 0x92, 0x25, +0x68, 0x76, 0xcf, 0x26, 0x04, 0xb0, 0xce, 0xd6, +0x29, 0xca, 0x90, 0x04, 0xa5, 0x22, 0x11, 0x5a, +0x36, 0x68, 0xab, 0xee, 0xab, 0xe2, 0x2b, 0xcb, +0x6f, 0xaa, 0xde, 0x25, 0x7c, 0xc3, 0xb9, 0xa7, +0xb5, 0x79, 0x8b, 0x17, 0xf5, 0x65, 0x3a, 0x99, +0xfa, 0x19, 0xf8, 0xc6, 0xb0, 0x89, 0xad, 0xd8, +0xe8, 0x93, 0x28, 0x9f, 0xf8, 0x99, 0x26, 0x8e, +0xe3, 0x64, 0xe4, 0x57, 0xa9, 0xcb, 0x7e, 0x24, +0xff, 0x8a, 0x67, 0x81, 0xb8, 0xa3, 0xdb, 0xb0, +0xaf, 0xe2, 0x48, 0x48, 0xe5, 0x34, 0xf1, 0x7b, +0xd0, 0xda, 0x6b, 0xf5, 0x9d, 0x02, 0xc1, 0xb8, +0xb7, 0x03, 0xc0, 0x4f, 0xb4, 0xea, 0xfe, 0x13, +0x58, 0x9b, 0xbf, 0xb5, 0xa9, 0xfa, 0x1c, 0x9b, +0x2c, 0x35, 0xb9, 0x15, 0xd6, 0x54, 0x3e, 0x73, +0x86, 0xc0, 0xda, 0x70, 0x2d, 0x09, 0x5f, 0x32, +0x29, 0x9a, 0x24, 0xae, 0xb5, 0x5b, 0xf6, 0x5b, +0x93, 0x3a, 0x35, 0x0d, 0x41, 0x13, 0x06, 0xc2, +0x1a, 0x23, 0x60, 0x4e, 0xe4, 0x35, 0xc7, 0x35, +0x19, 0x33, 0x40, 0xab, 0xb3, 0xa9, 0x19, 0xc1, +0x52, 0xcb, 0xd7, 0xa9, 0xb6, 0xb5, 0xf1, 0x69, +0xe2, 0x2f, 0xa1, 0x95, 0xdb, 0xc4, 0x09, 0xd2, +0xc2, 0x5b, 0xe2, 0xe0, 0xd3, 0x5a, 0xc8, 0x3a, +0xa4, 0x44, 0xaf, 0x31, 0xc0, 0x44, 0xb8, 0x49, +0xb2, 0x26, 0xa0, 0xb3, 0xea, 0xd4, 0xee, 0xf5, +0xf5, 0x75, 0xe7, 0x7c, 0xc7, 0xcb, 0x23, 0xf5, +0x3e, 0x8f, 0x38, 0x47, 0x61, 0x58, 0x89, 0xa9, +0x20, 0x46, 0x83, 0xec, 0xf1, 0x7c, 0xdc, 0xb9, +0x33, 0x65, 0xb7, 0xdb, 0x75, 0x9e, 0xeb, 0x84, +0x23, 0x39, 0xc4, 0x91, 0x87, 0x3c, 0xb7, 0xe1, +0xff, 0xc1, 0x1f, 0xfc, 0x01, 0x3e, 0xfe, 0xf8, +0xe3, 0x12, 0x03, 0x40, 0x76, 0x73, 0x2a, 0xe3, +0xce, 0x9d, 0x3b, 0x00, 0x80, 0x7c, 0x3c, 0x42, +0x72, 0xfe, 0x04, 0x7f, 0xaf, 0x77, 0x8c, 0xbf, +0xd3, 0x1b, 0x4f, 0xcf, 0xa2, 0x73, 0xbb, 0x34, +0x03, 0x53, 0x25, 0x3a, 0x4b, 0x5f, 0xd9, 0xa8, +0xeb, 0xa4, 0x16, 0x09, 0x0d, 0xd5, 0x9c, 0xcf, +0xb2, 0x59, 0xf2, 0x3c, 0x12, 0x4f, 0x2f, 0xde, +0xbe, 0x3a, 0x7c, 0xaa, 0x7a, 0x4d, 0xd3, 0x61, +0xd9, 0xb8, 0x2d, 0x66, 0xc3, 0x68, 0x97, 0x29, +0xcd, 0x5a, 0x65, 0xd6, 0x10, 0x5b, 0xd7, 0x96, +0x67, 0xd0, 0x2a, 0x94, 0xea, 0xaf, 0x4b, 0xd3, +0xa4, 0x5f, 0xe5, 0x73, 0x53, 0x8d, 0x4e, 0x53, +0xa8, 0xf3, 0x51, 0xd0, 0x18, 0xd0, 0x06, 0x38, +0xf8, 0xe6, 0x57, 0x93, 0x76, 0x07, 0x51, 0xd0, +0x02, 0xda, 0xfe, 0x48, 0x65, 0x16, 0x51, 0xb5, +0xd4, 0xe1, 0x9a, 0xea, 0xb9, 0xa9, 0x2d, 0x53, +0x23, 0x6c, 0x92, 0xc0, 0xf2, 0xff, 0x16, 0x68, +0xd1, 0xdc, 0xea, 0x08, 0xb1, 0xd6, 0x8e, 0xa6, +0x5a, 0x0a, 0x9e, 0x4f, 0x82, 0x56, 0x6f, 0x9d, +0x1a, 0x9e, 0xf7, 0x87, 0x24, 0xcc, 0xd2, 0xe6, +0x2d, 0x55, 0xdc, 0x16, 0xce, 0x3e, 0x6d, 0x87, +0x66, 0x53, 0xd7, 0xf0, 0xaa, 0x63, 0x2c, 0xac, +0x7e, 0xd2, 0xfa, 0xc2, 0x62, 0x46, 0x2c, 0xff, +0x08, 0x0b, 0x27, 0xeb, 0x7d, 0x9d, 0x66, 0xc0, +0xea, 0x73, 0x2d, 0x0d, 0x27, 0xde, 0x52, 0x85, +0xce, 0xbf, 0xf3, 0x34, 0x44, 0x60, 0x3f, 0xfe, +0xf8, 0x63, 0x67, 0x02, 0x92, 0xf6, 0x78, 0x00, +0x25, 0xe7, 0x3b, 0x2a, 0x9b, 0xdb, 0xcb, 0x81, +0x6a, 0x10, 0x1a, 0x60, 0x7e, 0x8e, 0x3c, 0x49, +0x92, 0x92, 0x77, 0x3b, 0x9f, 0x13, 0xbd, 0x5e, +0x0f, 0x83, 0xc1, 0x00, 0x83, 0xc1, 0xc0, 0x1d, +0x33, 0xe3, 0xf9, 0x89, 0x30, 0x03, 0x73, 0x3f, +0x0c, 0xb2, 0xab, 0xdf, 0xbe, 0x7d, 0xbb, 0xd4, +0x37, 0x24, 0xed, 0xf3, 0xa3, 0x6b, 0x83, 0xc9, +0xf4, 0x2a, 0xe3, 0xa5, 0x28, 0xc0, 0x7e, 0xa7, +0x85, 0xbf, 0xb3, 0x76, 0x8e, 0xff, 0x6d, 0xef, +0xd2, 0xd9, 0xd0, 0x7d, 0x44, 0xaf, 0xb1, 0x84, +0xf5, 0xac, 0x60, 0x6c, 0xea, 0x51, 0x3e, 0xa9, +0xdf, 0x2c, 0x95, 0x0d, 0xbb, 0x09, 0xbe, 0xde, +0xbb, 0xaa, 0xeb, 0x54, 0xf1, 0x1a, 0xbe, 0x35, +0x44, 0xbb, 0x52, 0xe7, 0xac, 0x0c, 0x93, 0xf8, +0x5d, 0x51, 0x82, 0xaf, 0x6d, 0x83, 0x94, 0x38, +0xaf, 0x50, 0x5f, 0x2d, 0x43, 0xd5, 0x14, 0x57, +0xee, 0x83, 0xa0, 0x3d, 0x5b, 0xa0, 0x30, 0x4b, +0x1a, 0x13, 0x54, 0x79, 0x57, 0x47, 0x98, 0x7d, +0x0c, 0xa8, 0xa6, 0x81, 0x9a, 0x41, 0x1a, 0xc4, +0x36, 0x3e, 0xda, 0x3b, 0x21, 0xf1, 0x4f, 0x75, +0x2d, 0x63, 0x5b, 0x4d, 0xac, 0x6d, 0xbc, 0xf2, +0x3d, 0xfd, 0xb7, 0x36, 0x4f, 0x9f, 0xb4, 0xe4, +0xdb, 0xfc, 0x7d, 0x12, 0xab, 0x54, 0xab, 0x5e, +0x05, 0x34, 0x7b, 0xa6, 0x8c, 0x8c, 0xe6, 0xc3, +0x8f, 0x97, 0xd1, 0x84, 0x60, 0x68, 0xfd, 0x43, +0x1a, 0x06, 0xe9, 0x8d, 0xad, 0x11, 0x77, 0x8d, +0x50, 0xf2, 0xb4, 0x75, 0xb6, 0x67, 0x49, 0x98, +0x2c, 0x53, 0x86, 0xd5, 0xd6, 0x26, 0xda, 0x02, +0x4d, 0x42, 0x6e, 0xc2, 0xb0, 0x69, 0x76, 0x6b, +0x1f, 0xb1, 0x95, 0x61, 0x53, 0x7d, 0x26, 0x0e, +0x1f, 0xe3, 0x61, 0x31, 0x2c, 0x3c, 0x8f, 0x66, +0x06, 0x90, 0xc4, 0xdb, 0xf7, 0x9d, 0xbc, 0xc0, +0xe9, 0x1b, 0x3f, 0xf2, 0x46, 0x75, 0xf0, 0xc0, +0x2e, 0xfc, 0xc8, 0x98, 0xec, 0x93, 0x8d, 0x8d, +0x8d, 0x52, 0x1c, 0x76, 0xba, 0x69, 0x8d, 0xf2, +0x71, 0xef, 0x7a, 0x49, 0xa4, 0x29, 0x3f, 0x00, +0xa7, 0x56, 0xe7, 0xda, 0x02, 0xc2, 0x95, 0xfa, +0xf6, 0xe0, 0xe0, 0xc0, 0x05, 0xbf, 0x01, 0x50, +0x3a, 0xbe, 0x46, 0x67, 0xf1, 0xa9, 0x0f, 0x37, +0x56, 0x97, 0x9d, 0xf4, 0xde, 0xef, 0xf7, 0xf1, +0xf9, 0xd3, 0x3e, 0xfe, 0xca, 0xca, 0x10, 0x7f, +0xef, 0xfa, 0x08, 0xd7, 0x42, 0x11, 0x20, 0x45, +0x03, 0xdf, 0x86, 0x5d, 0xb7, 0xb1, 0xd5, 0x39, +0x56, 0x35, 0x91, 0x04, 0x2d, 0xc9, 0xd8, 0x92, +0x44, 0x6b, 0x9e, 0x4d, 0x82, 0xdf, 0x84, 0x50, +0x3d, 0xa3, 0x04, 0xd9, 0x44, 0xb2, 0x6d, 0xf4, +0xbd, 0x01, 0x21, 0xa9, 0xa4, 0xbf, 0x6a, 0x7d, +0xac, 0x8e, 0x5a, 0x86, 0x8a, 0x3f, 0xfb, 0xb4, +0x2a, 0x68, 0xa0, 0x29, 0xd1, 0x70, 0x88, 0xab, +0x66, 0x21, 0x8d, 0x09, 0xf2, 0x6a, 0x05, 0x94, +0x7e, 0x6b, 0xd2, 0x1f, 0xae, 0xcc, 0x1a, 0x2d, +0x82, 0xe9, 0xb8, 0xa9, 0xa4, 0x0f, 0x52, 0xe3, +0x2c, 0x79, 0x9d, 0xda, 0xd5, 0x8a, 0xe1, 0x4d, +0xe9, 0x49, 0x2a, 0x90, 0xdf, 0x34, 0x47, 0x37, +0x4b, 0x02, 0x96, 0x69, 0x35, 0xa9, 0xda, 0x62, +0x22, 0x34, 0x82, 0x0d, 0xcc, 0x25, 0x76, 0x4b, +0xdd, 0x2d, 0x1d, 0xfd, 0xb4, 0xfa, 0x64, 0xbf, +0x48, 0x15, 0xad, 0x26, 0xd5, 0x49, 0xed, 0xc0, +0x55, 0x35, 0x12, 0xd4, 0xe7, 0x4d, 0x55, 0xf8, +0xb4, 0x99, 0xfb, 0xec, 0xd0, 0x5a, 0xfd, 0xb2, +0x6e, 0x9f, 0x94, 0xdf, 0x04, 0xa4, 0x59, 0x84, +0xe3, 0x34, 0x62, 0x01, 0x8b, 0xb8, 0xe3, 0x98, +0x56, 0x87, 0x1c, 0x57, 0xa9, 0x01, 0xb2, 0xfa, +0x44, 0x1b, 0x03, 0x9e, 0x46, 0x63, 0xc0, 0x2c, +0x86, 0x43, 0x7e, 0x93, 0x4e, 0x8c, 0xf2, 0x4f, +0x32, 0x28, 0xe4, 0x38, 0x47, 0xef, 0x88, 0x68, +0x93, 0x4a, 0x9d, 0x13, 0x79, 0x6e, 0xf3, 0x1e, +0x8d, 0x46, 0x8e, 0x31, 0x20, 0x7c, 0x49, 0x3d, +0x4e, 0xdf, 0x49, 0x1a, 0xa7, 0x32, 0x81, 0x79, +0x10, 0x9a, 0x6e, 0xb7, 0xeb, 0xec, 0xdf, 0x04, +0xfc, 0xf8, 0x1a, 0xa9, 0xdc, 0xa9, 0xdc, 0x7e, +0xbf, 0xef, 0xec, 0xf4, 0x74, 0x94, 0x8d, 0xca, +0x27, 0xd5, 0x3a, 0xad, 0x6f, 0x7e, 0x51, 0x4b, +0xbf, 0xdf, 0xc7, 0xad, 0xed, 0x6b, 0x58, 0x5f, +0x5e, 0xc2, 0xdf, 0xdc, 0x0e, 0xf1, 0x7f, 0x79, +0xbe, 0x8d, 0xbd, 0x88, 0x05, 0x48, 0xd1, 0xc0, +0x47, 0x0c, 0x84, 0xe4, 0xc1, 0x37, 0xb1, 0x92, +0x9d, 0xb5, 0x0e, 0x3c, 0x9b, 0xed, 0x72, 0x3c, +0x95, 0x8c, 0x97, 0x03, 0x96, 0xee, 0x2a, 0x0c, +0x42, 0xd3, 0x0d, 0xbe, 0x69, 0xbe, 0x3f, 0x6f, +0xe0, 0x78, 0x2a, 0x84, 0xe4, 0xca, 0x9a, 0x06, +0xa5, 0x5c, 0xcd, 0x9c, 0x72, 0x65, 0xd0, 0x88, +0xeb, 0xb3, 0x82, 0x86, 0x43, 0x8d, 0x4f, 0xc4, +0x95, 0xcb, 0xfb, 0x92, 0xa1, 0x89, 0x59, 0x28, +0xbc, 0xfd, 0xdd, 0xdf, 0x7c, 0x73, 0xf5, 0xfc, +0xa8, 0x12, 0x7a, 0x33, 0x49, 0x12, 0x17, 0x4a, +0x92, 0x42, 0x9a, 0x02, 0x28, 0x85, 0xdb, 0xa4, +0xf0, 0xa0, 0xb4, 0xa1, 0xf2, 0xf0, 0x99, 0x3c, +0x44, 0x27, 0x85, 0x1d, 0x1d, 0x0e, 0x87, 0xa5, +0x50, 0x9d, 0xfc, 0x8f, 0x36, 0x29, 0x2d, 0x44, +0x27, 0x3d, 0x53, 0x19, 0x3c, 0x94, 0x27, 0xcf, +0x43, 0xe9, 0x56, 0x56, 0x56, 0x5c, 0xdd, 0x84, +0x17, 0x85, 0xd4, 0x94, 0xe9, 0xb5, 0xfc, 0x54, +0x0f, 0x7f, 0x96, 0xdf, 0x7b, 0xbd, 0x5e, 0x29, +0x34, 0x2a, 0xb5, 0x8d, 0xea, 0x4b, 0x92, 0xa4, +0x14, 0xb6, 0x94, 0xf0, 0xa6, 0xfa, 0x28, 0x0f, +0x85, 0x45, 0xa5, 0x70, 0xb1, 0x52, 0xda, 0xe4, +0x63, 0xc0, 0x09, 0xd7, 0xd1, 0xd1, 0x51, 0x29, +0xa4, 0xaa, 0x6c, 0x07, 0x1f, 0x27, 0xc2, 0x93, +0x8f, 0x31, 0xbd, 0x23, 0xe0, 0x7d, 0x43, 0x75, +0x68, 0xfd, 0x4c, 0xf8, 0x50, 0x1e, 0xd9, 0xb7, +0x32, 0x2d, 0xcf, 0x4f, 0x7d, 0xc0, 0xfb, 0x76, +0x34, 0x1a, 0xb9, 0xf0, 0xa8, 0x04, 0x9a, 0xd6, +0x85, 0x70, 0xad, 0xb3, 0x8d, 0x73, 0xfc, 0xeb, +0x80, 0x8f, 0x89, 0xc4, 0x9b, 0xde, 0xf3, 0x7e, +0x92, 0xda, 0x02, 0x9a, 0x27, 0x9c, 0xb1, 0xa5, +0xb9, 0x4e, 0xa1, 0x8e, 0xa3, 0x28, 0x42, 0xbf, +0xdf, 0x77, 0x61, 0x5b, 0x79, 0xbd, 0x51, 0x14, +0xe1, 0xe8, 0xe8, 0x08, 0xbd, 0x5e, 0x0f, 0xab, +0xab, 0xab, 0xb8, 0x77, 0xef, 0x1e, 0x56, 0x56, +0x56, 0xb0, 0xb2, 0xb2, 0x82, 0xc3, 0xc3, 0x43, +0x37, 0x97, 0x3b, 0x9d, 0x0e, 0x9e, 0x3c, 0x79, +0xe2, 0xca, 0x4c, 0x92, 0x04, 0x2b, 0x2b, 0x2b, +0x38, 0x3a, 0x3a, 0xc2, 0xe6, 0xe6, 0x26, 0x9e, +0x3c, 0x79, 0xe2, 0x70, 0x0c, 0xc3, 0x10, 0x27, +0x27, 0x27, 0xd8, 0xda, 0xda, 0x72, 0xf5, 0x24, +0x49, 0x82, 0x27, 0x4f, 0x9e, 0x60, 0x77, 0x77, +0x17, 0x17, 0x17, 0x17, 0x88, 0xa2, 0xc8, 0x9d, +0x7b, 0x7f, 0xf0, 0xe0, 0x81, 0x9b, 0x47, 0x51, +0x14, 0xb9, 0x79, 0xdd, 0xeb, 0xf5, 0x70, 0x76, +0x76, 0xe6, 0x08, 0xf9, 0xca, 0xca, 0x0a, 0x5e, +0x7c, 0xf1, 0x45, 0x7c, 0xfa, 0xe9, 0xa7, 0xae, +0xac, 0xe1, 0x70, 0x88, 0xf7, 0x3f, 0xfa, 0x18, +0x67, 0xa7, 0x27, 0xd8, 0xd8, 0xd8, 0xc0, 0xd6, +0xd6, 0x16, 0xee, 0xdf, 0xbf, 0x8f, 0xa3, 0xa3, +0x23, 0x3c, 0x7c, 0xfc, 0x04, 0x5f, 0x59, 0x8d, +0xf0, 0xad, 0xf5, 0x10, 0x2f, 0x47, 0x03, 0x3c, +0x2a, 0x3a, 0x38, 0x66, 0xcb, 0x2e, 0xca, 0x27, +0xc8, 0x5b, 0x4d, 0x82, 0xb3, 0xe8, 0x47, 0xde, +0x5c, 0x5e, 0x2b, 0xe4, 0xea, 0x64, 0x34, 0xff, +0xc6, 0xd2, 0x44, 0xf9, 0x04, 0xdd, 0x30, 0x44, +0x0f, 0x63, 0x7c, 0x6d, 0xb9, 0x85, 0xef, 0x6e, +0x44, 0xf8, 0x5b, 0x3b, 0x11, 0xbe, 0xdb, 0x0b, +0x71, 0xa3, 0x1b, 0xa1, 0x95, 0x8e, 0x70, 0xd1, +0xea, 0xa0, 0xdd, 0x02, 0x26, 0x85, 0x52, 0x3e, +0x2f, 0xb7, 0x61, 0x9d, 0xde, 0x3c, 0x32, 0x4d, +0x93, 0xf2, 0x95, 0x34, 0xb2, 0x3f, 0xd5, 0xfe, +0xd5, 0xf2, 0xd7, 0xe0, 0x55, 0x2a, 0xe3, 0x2a, +0xed, 0x60, 0xe9, 0x1a, 0x8d, 0xf3, 0x55, 0xea, +0x10, 0x50, 0x69, 0xab, 0x28, 0xa3, 0xee, 0xbb, +0x96, 0xae, 0x36, 0x7d, 0xdd, 0x38, 0xe5, 0xd9, +0xfc, 0xbb, 0x2f, 0xad, 0xaf, 0xad, 0x2c, 0x9f, +0xc3, 0x47, 0xe9, 0x5f, 0x87, 0x3f, 0x7f, 0xd0, +0x6c, 0xd3, 0xf4, 0x5e, 0xa6, 0xb1, 0x24, 0x5f, +0x79, 0x2c, 0x8a, 0x38, 0x77, 0x59, 0xbe, 0x04, +0x4d, 0x3d, 0xab, 0x79, 0x28, 0xf3, 0x7a, 0x34, +0x89, 0xcc, 0xc2, 0x5b, 0xb6, 0x93, 0xd2, 0x6b, +0x5a, 0x01, 0x4d, 0x7d, 0xae, 0xd9, 0xa6, 0x79, +0x19, 0x4d, 0xa4, 0x6d, 0xab, 0xdd, 0x94, 0x97, +0x6b, 0x04, 0xe4, 0x33, 0xc7, 0x41, 0xb6, 0x85, +0x3b, 0xbc, 0xf9, 0x24, 0x61, 0xd9, 0xcf, 0x16, +0x2e, 0xd6, 0x58, 0x59, 0xd2, 0xba, 0xcf, 0xaf, +0x40, 0xeb, 0x77, 0x0e, 0xfc, 0x5c, 0x36, 0xe1, +0xc0, 0xfb, 0xda, 0xd2, 0xe4, 0x68, 0x6d, 0xd1, +0x7c, 0x06, 0x64, 0x1f, 0x6b, 0x63, 0x5c, 0x67, +0x93, 0xd7, 0x7e, 0xcb, 0xa3, 0x7a, 0x3e, 0x8d, +0x89, 0x9c, 0x13, 0xc3, 0xe1, 0xd0, 0x49, 0xcd, +0x24, 0x95, 0x93, 0x64, 0xfb, 0xda, 0x6b, 0xaf, +0x39, 0x89, 0x7e, 0x77, 0x77, 0xb7, 0x72, 0x6e, +0x5d, 0xce, 0x05, 0xb2, 0xb7, 0xcb, 0x71, 0x27, +0xf5, 0x3d, 0xb7, 0xab, 0xf3, 0x72, 0x01, 0xb8, +0x23, 0x6d, 0x7c, 0xfe, 0xd1, 0x05, 0x2e, 0x04, +0x54, 0x06, 0x5d, 0xcc, 0x42, 0xc7, 0xd7, 0x78, +0x7e, 0x22, 0xec, 0x3c, 0x4c, 0xec, 0x60, 0x92, +0xe1, 0x9d, 0x77, 0xde, 0xc1, 0xc1, 0xc1, 0x01, +0x7e, 0x63, 0x35, 0xc1, 0x8b, 0xab, 0x23, 0xfc, +0x3f, 0x1e, 0x75, 0xf0, 0xd6, 0x2c, 0x68, 0xdc, +0xb3, 0x48, 0x57, 0xaa, 0xad, 0xdb, 0x82, 0x60, +0xbe, 0xb5, 0x2d, 0x17, 0x63, 0xac, 0x07, 0x39, +0xee, 0x24, 0xc0, 0xcd, 0x4e, 0x80, 0x6f, 0x6e, +0x47, 0x78, 0x6d, 0xad, 0x83, 0x5b, 0x9b, 0x3d, +0xac, 0x2f, 0x4f, 0xfb, 0x8f, 0xae, 0xb3, 0x3d, +0x2f, 0x42, 0xfc, 0xfd, 0x3f, 0xfe, 0xb7, 0xf8, +0xfb, 0x87, 0xc0, 0xc5, 0x28, 0xbd, 0x9a, 0x44, +0x3d, 0xb3, 0xd5, 0x36, 0xb6, 0xc7, 0x6b, 0xb6, +0xd5, 0x3a, 0x4d, 0x85, 0x51, 0x5e, 0x2a, 0x54, +0xd2, 0xa9, 0x4f, 0xfa, 0x34, 0xea, 0x88, 0xf2, +0x09, 0xd2, 0x2c, 0x7f, 0x36, 0x2d, 0xca, 0x55, +0xd2, 0xf8, 0xea, 0x53, 0x24, 0x64, 0xae, 0x92, +0x8e, 0xc2, 0x40, 0x57, 0xa9, 0x73, 0x95, 0xbf, +0xd4, 0x30, 0x64, 0x39, 0x22, 0x4c, 0x6a, 0xd5, +0xe5, 0x95, 0x63, 0x6d, 0x4d, 0xc6, 0x44, 0xa6, +0xd5, 0xd2, 0x2b, 0xe3, 0xa5, 0xb5, 0x43, 0xed, +0xcb, 0xba, 0xb2, 0x19, 0x84, 0xb7, 0xbe, 0xf3, +0x1b, 0x25, 0xc9, 0x9c, 0xa4, 0x41, 0x2e, 0xb5, +0x70, 0x09, 0x14, 0x98, 0x4b, 0x80, 0xf2, 0xb2, +0x0d, 0xfe, 0x9f, 0xff, 0xa6, 0x0b, 0x3f, 0xf8, +0x06, 0x27, 0xa5, 0x63, 0x92, 0x64, 0xe9, 0x9b, +0xdc, 0x68, 0xf9, 0x05, 0x1b, 0x54, 0x1e, 0xd5, +0xc1, 0x25, 0x1d, 0x4a, 0x47, 0xe5, 0x91, 0xe6, +0x80, 0xa7, 0x95, 0x17, 0x82, 0x70, 0xe9, 0x5d, +0xbb, 0x90, 0x65, 0x65, 0x65, 0xc5, 0xd5, 0xc9, +0x25, 0x6a, 0x8e, 0xab, 0xc4, 0x83, 0x4b, 0x45, +0xbc, 0x2c, 0x5e, 0x36, 0x97, 0x90, 0xa5, 0xc6, +0x81, 0x4b, 0xd3, 0x3c, 0x3f, 0x77, 0x56, 0x22, +0xc9, 0x4d, 0xd3, 0x76, 0xf0, 0x3e, 0xe6, 0xf5, +0xf0, 0xba, 0xa8, 0x2f, 0xb4, 0x3e, 0x90, 0xe3, +0x45, 0xcf, 0x7c, 0x5c, 0x78, 0x3e, 0x6d, 0x4c, +0x29, 0x9d, 0xd4, 0x20, 0x48, 0x89, 0x9f, 0x5f, +0x5c, 0xc2, 0x71, 0xe4, 0xe9, 0xa5, 0xb6, 0xc0, +0xea, 0x1b, 0x3e, 0x77, 0xb9, 0xa6, 0x43, 0xce, +0x5d, 0x3e, 0x1e, 0x7c, 0x2c, 0x79, 0xdb, 0xac, +0x8b, 0x75, 0xb8, 0xd6, 0x84, 0xbf, 0x97, 0x73, +0x9f, 0xea, 0xe6, 0xe5, 0xd3, 0x3b, 0x7e, 0x51, +0xce, 0xea, 0xea, 0x2a, 0x8e, 0x8e, 0x8e, 0xa6, +0x6b, 0x35, 0x8e, 0xdd, 0xef, 0x95, 0x95, 0x15, +0x27, 0x49, 0x53, 0x9d, 0x24, 0x3d, 0x93, 0x14, +0x2f, 0xd7, 0xc7, 0x93, 0x27, 0x4f, 0x00, 0x94, +0x1d, 0x54, 0x8b, 0xa2, 0x70, 0xdf, 0x5e, 0x7c, +0xf1, 0x45, 0x44, 0x51, 0x84, 0xf7, 0xdf, 0x7f, +0x1f, 0xc3, 0xe1, 0xd0, 0x49, 0xf0, 0xeb, 0xeb, +0xeb, 0xae, 0xae, 0xed, 0xed, 0x6d, 0x77, 0x06, +0x3d, 0x8a, 0x22, 0x6c, 0x6e, 0x6e, 0x3a, 0x09, +0x3d, 0x49, 0x12, 0x27, 0x81, 0x0f, 0x87, 0x43, +0xec, 0xef, 0xef, 0xe3, 0xf0, 0xf0, 0x10, 0xf7, +0xef, 0xdf, 0x77, 0x1a, 0xab, 0x34, 0x4d, 0x31, +0x1a, 0x5c, 0x96, 0x8e, 0xb4, 0xad, 0xb5, 0x43, +0xec, 0x14, 0x97, 0xb8, 0x97, 0x27, 0x25, 0x09, +0xbd, 0x04, 0x52, 0xa2, 0x11, 0x60, 0x4a, 0x9a, +0xec, 0x79, 0x39, 0x8e, 0xd0, 0x6e, 0x01, 0xcf, +0x2d, 0x05, 0xf8, 0x5a, 0x3c, 0xc4, 0xdf, 0x58, +0x1b, 0xe3, 0x6f, 0xaf, 0x5e, 0xe2, 0x7f, 0xb3, +0x72, 0x8e, 0xff, 0x60, 0x27, 0xc1, 0x77, 0xd6, +0x80, 0x57, 0x76, 0x37, 0xb0, 0xbb, 0xbe, 0x82, +0xb0, 0x35, 0xed, 0xef, 0xcb, 0x49, 0x86, 0xd6, +0xec, 0x42, 0x99, 0x28, 0x8a, 0xf0, 0xa3, 0x17, +0x6f, 0x62, 0x67, 0xd4, 0xc7, 0x9f, 0x5e, 0x86, +0xb8, 0x9c, 0x78, 0x34, 0x08, 0xb3, 0xfa, 0x4d, +0x89, 0xce, 0x02, 0x43, 0xb2, 0x32, 0xdb, 0x65, +0xbd, 0xe3, 0xe5, 0xf9, 0x9e, 0x3d, 0xf9, 0x2b, +0xb8, 0xfb, 0x24, 0x5a, 0x1f, 0x1e, 0x4d, 0x35, +0x16, 0x52, 0xda, 0xac, 0xe9, 0x87, 0x3c, 0x6a, +0x97, 0xda, 0x65, 0x4a, 0xcc, 0xbe, 0x72, 0x64, +0xbe, 0x26, 0xb8, 0xd7, 0xf5, 0x03, 0x4f, 0x7f, +0x45, 0x4d, 0x82, 0x17, 0x1f, 0x89, 0x4b, 0xd3, +0xb2, 0x27, 0xa3, 0x39, 0x31, 0xd7, 0x6e, 0xbd, +0xe2, 0x1b, 0x22, 0x57, 0x1b, 0xca, 0x8d, 0x59, +0x12, 0x4c, 0xae, 0xa6, 0xa6, 0x4d, 0x56, 0xda, +0xd8, 0x35, 0x55, 0xb7, 0xbc, 0xf1, 0x8a, 0xab, +0xa3, 0xe5, 0x6d, 0x5e, 0x72, 0x43, 0xd5, 0x6e, +0x44, 0x93, 0x6a, 0x54, 0xa9, 0x76, 0xa7, 0x36, +0x71, 0xb5, 0x31, 0xc7, 0x59, 0x4a, 0xed, 0x44, +0xd0, 0x89, 0xb8, 0x73, 0x93, 0x84, 0x65, 0x66, +0xa0, 0xb2, 0x79, 0x7f, 0x51, 0x5d, 0x72, 0xf3, +0xa7, 0x3f, 0xa0, 0x2c, 0xf9, 0x51, 0x3d, 0xd4, +0xcf, 0xf4, 0x5b, 0xe2, 0x46, 0x75, 0xd2, 0xb3, +0x64, 0x4e, 0xf8, 0xf8, 0x69, 0x37, 0xca, 0x49, +0x66, 0x83, 0x03, 0x97, 0x6a, 0xb5, 0x1b, 0xcf, +0x2c, 0xe0, 0xdf, 0x2d, 0xc2, 0xcf, 0x6f, 0x22, +0xe3, 0x7d, 0xc0, 0x99, 0x48, 0x79, 0x2b, 0x1c, +0x2f, 0x83, 0x8f, 0x0d, 0x9f, 0x23, 0x75, 0x37, +0xb9, 0xf1, 0x32, 0x34, 0x42, 0xcd, 0xe7, 0x9a, +0x66, 0x26, 0x92, 0xeb, 0x81, 0x33, 0x92, 0xbc, +0x3c, 0x8e, 0x03, 0xd7, 0x64, 0x9c, 0x9f, 0x9f, +0x3b, 0x46, 0x87, 0xc6, 0x94, 0x24, 0x6c, 0xde, +0x56, 0xae, 0x66, 0x27, 0x49, 0xfb, 0xfc, 0xfc, +0x1c, 0x9b, 0x9b, 0x9b, 0x8e, 0x01, 0x4a, 0xd3, +0xd4, 0xdd, 0xaa, 0x47, 0x04, 0xba, 0xd7, 0xeb, +0xe1, 0xe8, 0xe8, 0x08, 0x59, 0x96, 0x39, 0x42, +0x9d, 0x24, 0x09, 0xce, 0xce, 0xce, 0xf0, 0xe4, +0xc9, 0x13, 0x47, 0x78, 0x49, 0xfd, 0xee, 0xf6, +0x85, 0xc9, 0x04, 0x27, 0x27, 0x27, 0x48, 0xd3, +0x14, 0x3b, 0x3b, 0xd3, 0xa3, 0xab, 0xa4, 0x8e, +0xdf, 0xdd, 0xdd, 0xc5, 0xd9, 0xd9, 0x19, 0x2e, +0x2e, 0x2e, 0xb0, 0xbb, 0xbb, 0x8b, 0xf7, 0xdf, +0x7f, 0x1f, 0x87, 0x87, 0x87, 0xb8, 0x7d, 0xfb, +0x36, 0xb2, 0x2c, 0xc3, 0xf9, 0xf9, 0xb9, 0x6b, +0x47, 0x9a, 0xa6, 0xb8, 0x7f, 0xff, 0xfe, 0x74, +0x6c, 0xb2, 0x0c, 0x5f, 0xdd, 0xee, 0xe1, 0xbb, +0xcb, 0x29, 0xfe, 0xf0, 0x22, 0xc2, 0xa9, 0xe6, +0x77, 0x56, 0x47, 0xe4, 0x66, 0xb0, 0x1c, 0x00, +0xed, 0x16, 0xb0, 0xd3, 0x8d, 0xf0, 0x5c, 0x34, +0xc6, 0x73, 0x49, 0x0b, 0x1b, 0x71, 0x0b, 0xaf, +0x26, 0x13, 0xfc, 0x97, 0xb7, 0xbb, 0xf8, 0x8f, +0xd7, 0x06, 0xf8, 0x3b, 0xd7, 0x26, 0xf8, 0xf1, +0x56, 0x1b, 0x2f, 0x06, 0x03, 0xac, 0xe4, 0x23, +0x84, 0xad, 0x16, 0xce, 0x4f, 0x4e, 0x70, 0x7e, +0x7e, 0x8e, 0xb3, 0x93, 0x13, 0xb4, 0x5a, 0x2d, +0xc4, 0x71, 0x3c, 0x1d, 0xc3, 0xa0, 0x85, 0x8b, +0x8b, 0x0b, 0xf4, 0xfb, 0x7d, 0x3c, 0xf8, 0xf4, +0x13, 0x0c, 0x2e, 0xce, 0xf1, 0xdd, 0x97, 0x6e, +0x63, 0x09, 0x19, 0xfe, 0xf8, 0xe9, 0x18, 0x83, +0xc2, 0x08, 0x6b, 0x4d, 0x44, 0x29, 0x4d, 0xaf, +0xbe, 0xa1, 0xfb, 0x40, 0x2b, 0xeb, 0x8b, 0x96, +0xdf, 0x84, 0x41, 0x12, 0x84, 0x44, 0x25, 0xe4, +0x66, 0xec, 0x73, 0x3f, 0x31, 0x35, 0xd3, 0x3d, +0xab, 0x0a, 0x1a, 0xf0, 0x32, 0x7e, 0x5f, 0x46, +0xdf, 0x10, 0x11, 0xcf, 0x5b, 0xe1, 0x33, 0xa9, +0xff, 0x65, 0x39, 0x5f, 0x04, 0x17, 0x15, 0x04, +0x33, 0x13, 0xa5, 0x79, 0x51, 0x96, 0xc0, 0xda, +0x09, 0xa0, 0xa8, 0x57, 0xe5, 0x33, 0x77, 0x02, +0xf2, 0x39, 0x8b, 0xf9, 0x54, 0xf4, 0x3e, 0xa7, +0x2f, 0xae, 0x06, 0xad, 0x3b, 0x1b, 0xad, 0xfd, +0xb6, 0xea, 0xd0, 0x70, 0xd3, 0xa2, 0xa5, 0x59, +0x79, 0xb5, 0xfc, 0x52, 0xd5, 0xce, 0xf3, 0x4a, +0x5b, 0xb7, 0x4f, 0x0d, 0xcd, 0x55, 0xeb, 0x5c, +0xf5, 0x29, 0xd3, 0xd4, 0x1d, 0x67, 0xd3, 0xc6, +0x4c, 0xeb, 0x3b, 0xcb, 0x5c, 0x20, 0xfb, 0xc3, +0xc2, 0x55, 0x53, 0x77, 0x6b, 0xe3, 0x64, 0x8d, +0x15, 0x81, 0xbc, 0xd0, 0x44, 0xe2, 0xa5, 0x8d, +0x4f, 0x9d, 0x33, 0x9e, 0x35, 0x27, 0xe9, 0x9b, +0x74, 0x2c, 0x94, 0xdf, 0x79, 0x3a, 0x9f, 0xf9, +0x43, 0x9b, 0x77, 0x72, 0x0e, 0xf0, 0x36, 0x58, +0xe3, 0x45, 0x79, 0xb8, 0x8a, 0x9b, 0x54, 0xe2, +0xa4, 0xbe, 0xd6, 0xe6, 0x34, 0x1f, 0x37, 0x52, +0xb9, 0x13, 0x90, 0xd3, 0x1b, 0x8f, 0x20, 0x37, +0x18, 0x0c, 0xdc, 0xd1, 0x33, 0x62, 0x14, 0xf8, +0xbd, 0xec, 0x74, 0x8e, 0x9d, 0xa2, 0x0b, 0x02, +0x70, 0xe9, 0x77, 0x77, 0x77, 0x5d, 0x7e, 0x6e, +0x3e, 0xbb, 0xfb, 0xf5, 0x57, 0x31, 0xbc, 0x38, +0x03, 0x00, 0x77, 0x14, 0x6e, 0x38, 0x9c, 0xde, +0xc5, 0xbe, 0xbb, 0xbb, 0x5b, 0xf2, 0xce, 0x8f, +0x01, 0xfc, 0x1f, 0xd6, 0xda, 0xf8, 0xfb, 0xa7, +0x2b, 0xb8, 0x57, 0x2c, 0xa1, 0x48, 0x53, 0x5c, +0xcc, 0x9c, 0xde, 0xf9, 0x5d, 0xe9, 0x07, 0x09, +0x30, 0x18, 0x0e, 0xb0, 0x87, 0x21, 0x96, 0xe3, +0x10, 0x6b, 0x21, 0x70, 0x9a, 0x01, 0x07, 0x71, +0x8a, 0xf5, 0x24, 0xc6, 0x8b, 0xab, 0x6d, 0xac, +0x86, 0x05, 0xb6, 0x63, 0xa0, 0xd7, 0x5b, 0x42, +0xd0, 0xee, 0xa0, 0xd3, 0xd9, 0x41, 0x3b, 0x00, +0x80, 0x4d, 0x3c, 0x7a, 0xf4, 0xa8, 0x14, 0xcd, +0x8f, 0x1c, 0x5b, 0x09, 0x47, 0xde, 0x77, 0x34, +0xff, 0x4e, 0x2e, 0x07, 0xa5, 0x3c, 0xff, 0xe9, +0x4b, 0x07, 0x00, 0x80, 0xff, 0xfb, 0x2f, 0xce, +0x1c, 0x8e, 0x2a, 0x5c, 0x55, 0x0d, 0xdb, 0xe4, +0xfb, 0x15, 0xf3, 0x98, 0x26, 0x08, 0xab, 0x1c, +0xed, 0xfd, 0x17, 0xf1, 0x84, 0xbf, 0x42, 0x9b, +0x4b, 0xb8, 0x7e, 0x91, 0xbe, 0xe3, 0x9e, 0xe8, +0xf2, 0xd8, 0xa1, 0x2f, 0x9f, 0x75, 0xc4, 0x4c, +0xe4, 0xb9, 0xd2, 0x29, 0x01, 0x0f, 0xde, 0x1a, +0x3e, 0xea, 0x78, 0x5d, 0x75, 0x1e, 0x48, 0x93, +0x04, 0x20, 0x36, 0xc7, 0xb1, 0x9f, 0x68, 0xf2, +0x77, 0x72, 0x83, 0xf1, 0xd9, 0x61, 0xb5, 0x72, +0xb4, 0x3a, 0x7c, 0xb6, 0x78, 0x6d, 0x23, 0xd4, +0x3c, 0xe6, 0x65, 0x5e, 0xbe, 0x01, 0x6b, 0xef, +0x69, 0xf1, 0xf2, 0xdf, 0x16, 0x51, 0x92, 0xf5, +0x4a, 0xad, 0x83, 0xc4, 0xc9, 0xc7, 0xb8, 0x58, +0x78, 0xf3, 0xfe, 0xd2, 0x4e, 0x0d, 0xd4, 0xf5, +0xaf, 0x95, 0x46, 0xaa, 0x9c, 0xad, 0x7e, 0xb5, +0x98, 0x27, 0xab, 0x6f, 0x7d, 0x8c, 0x8a, 0xc6, +0xf8, 0x58, 0xf5, 0x72, 0x18, 0x8d, 0x46, 0xa5, +0x68, 0x69, 0x12, 0x77, 0x5f, 0x1f, 0x5a, 0x38, +0xd4, 0xd9, 0xf7, 0x25, 0x13, 0xc5, 0xed, 0xcc, +0x75, 0x36, 0x74, 0xdf, 0x6f, 0x59, 0x07, 0xcd, +0x33, 0x22, 0xd6, 0xbc, 0x6d, 0x74, 0x81, 0x0a, +0x7d, 0xa7, 0x90, 0xae, 0x40, 0x39, 0x82, 0x1b, +0xa5, 0xe5, 0xe5, 0x12, 0x51, 0xa6, 0x31, 0xa4, +0x7c, 0x44, 0xe4, 0x29, 0x38, 0xcd, 0x70, 0x38, +0x2c, 0x9d, 0x21, 0xa7, 0x8b, 0x57, 0x28, 0x0a, +0x1c, 0x79, 0xc9, 0xf3, 0xfe, 0x27, 0x09, 0xfd, +0xe4, 0xe4, 0x04, 0x3b, 0x3b, 0x3b, 0x4e, 0xed, +0x7e, 0xf0, 0xc2, 0x4b, 0x18, 0x5e, 0x9c, 0x39, +0xdb, 0xfa, 0xe1, 0xe1, 0xa1, 0x63, 0x40, 0xe8, +0xae, 0x74, 0x22, 0xea, 0xb4, 0x2e, 0xee, 0x0e, +0x87, 0xf8, 0x7b, 0xe9, 0x23, 0xb4, 0x7a, 0xd7, +0x71, 0x1c, 0x2d, 0xe3, 0x24, 0x6b, 0x61, 0x3d, +0x2c, 0xb0, 0x16, 0x4c, 0x29, 0x66, 0x38, 0x1e, +0xe0, 0x06, 0xa6, 0x0c, 0x41, 0x2b, 0x6e, 0x63, +0x7d, 0xb9, 0x8d, 0x24, 0x49, 0x10, 0xb4, 0x3b, +0x68, 0x07, 0x2d, 0x9d, 0xa1, 0x01, 0xf0, 0xf0, +0xf3, 0xf9, 0x69, 0x81, 0xe1, 0x70, 0x88, 0xb1, +0x10, 0x54, 0x34, 0x66, 0x8d, 0x33, 0xf4, 0x7c, +0x9c, 0x89, 0x81, 0xfa, 0x9b, 0xb7, 0x6e, 0xe3, +0x9f, 0x3e, 0x1a, 0xe2, 0x77, 0x9f, 0x4c, 0x74, +0x82, 0xfe, 0x25, 0x10, 0xe2, 0x46, 0x50, 0x43, +0x9c, 0x52, 0x85, 0xb0, 0x01, 0xf8, 0x42, 0xc4, +0xb2, 0xb1, 0x8f, 0x82, 0xcf, 0x07, 0x40, 0x81, +0xd2, 0xb1, 0xac, 0x2f, 0x83, 0x81, 0xd0, 0xe2, +0x07, 0xc8, 0x63, 0x6d, 0x4d, 0x70, 0xbb, 0xca, +0xe9, 0x08, 0xed, 0xd8, 0x9c, 0x51, 0x47, 0x94, +0x4f, 0x2a, 0x3e, 0x0c, 0x0e, 0x4f, 0x1e, 0x22, +0xb7, 0x81, 0x97, 0xbd, 0x0f, 0x22, 0x52, 0x6f, +0x6a, 0x9b, 0x1b, 0x5f, 0x0c, 0x1a, 0x11, 0xd0, +0xde, 0x03, 0xe5, 0x8d, 0x84, 0xd2, 0x36, 0x25, +0x36, 0xf4, 0xcc, 0xeb, 0xb0, 0xd2, 0xd7, 0x49, +0xc8, 0x16, 0x23, 0x21, 0xeb, 0xd1, 0xf0, 0x90, +0x44, 0x83, 0x3b, 0x13, 0x69, 0x6d, 0xa6, 0xef, +0x9a, 0xb3, 0x9e, 0xc6, 0x0c, 0x71, 0x69, 0x53, +0x9e, 0x71, 0xd7, 0x98, 0x01, 0xfa, 0xed, 0x23, +0x48, 0xb2, 0xdf, 0x25, 0xd4, 0x49, 0xb4, 0x5a, +0xbf, 0x5b, 0x38, 0xf2, 0xf4, 0x16, 0x3e, 0xbc, +0xbd, 0x16, 0x51, 0x07, 0xe6, 0x4e, 0x70, 0xfc, +0x3f, 0xbf, 0xcc, 0x44, 0xe2, 0x4f, 0x67, 0xa2, +0xb5, 0x3e, 0xd6, 0xe6, 0x98, 0xd6, 0x27, 0x72, +0x7e, 0x70, 0x02, 0x2a, 0x19, 0x44, 0x92, 0xea, +0xb8, 0x23, 0x99, 0x56, 0x9e, 0x9c, 0x43, 0xb2, +0xed, 0x3e, 0x90, 0xda, 0x00, 0x9a, 0x4f, 0x3c, +0x90, 0x4c, 0x92, 0x24, 0x4e, 0xda, 0x26, 0x7c, +0xf8, 0x51, 0x34, 0x0e, 0x24, 0x1d, 0x53, 0xb0, +0x19, 0x2e, 0x8d, 0x72, 0x18, 0x8d, 0x46, 0x8e, +0xf8, 0x72, 0x06, 0x95, 0x6b, 0x04, 0xe8, 0x92, +0x16, 0x2a, 0x93, 0xda, 0x73, 0xfb, 0xf6, 0x6d, +0x14, 0xe9, 0xd8, 0x1d, 0x83, 0xe4, 0x04, 0x9d, +0xce, 0xc1, 0xf3, 0x31, 0xa7, 0x23, 0x6c, 0xbd, +0x5e, 0x0f, 0x37, 0x77, 0x77, 0x71, 0x70, 0xb0, +0xe3, 0x24, 0x79, 0x0b, 0x46, 0xa3, 0x11, 0x5a, +0x71, 0x07, 0xc5, 0x64, 0xda, 0x0f, 0xe3, 0x34, +0xc3, 0xb0, 0xdf, 0xc7, 0xc9, 0xe5, 0x00, 0xc5, +0x78, 0xa4, 0xce, 0x2d, 0xde, 0xd6, 0xc3, 0xa0, +0x55, 0x92, 0xce, 0xb9, 0x93, 0x9e, 0x36, 0x67, +0xf9, 0x1a, 0x27, 0x07, 0xbf, 0xff, 0x62, 0x3b, +0xc1, 0xbf, 0x7a, 0x78, 0x89, 0x8b, 0x68, 0xa9, +0x19, 0x61, 0xa8, 0x93, 0x78, 0x9b, 0x48, 0xc4, +0x57, 0xc9, 0x53, 0x87, 0x8f, 0x4f, 0x0a, 0xf7, +0x30, 0x22, 0xb5, 0x44, 0x97, 0xde, 0x37, 0x0d, +0x3f, 0xdb, 0xa4, 0xdd, 0x75, 0x12, 0x75, 0x13, +0x26, 0xa1, 0xae, 0x2f, 0x19, 0x34, 0xd2, 0x68, +0xc8, 0x98, 0xf4, 0x57, 0xd4, 0x68, 0x78, 0x25, +0x70, 0xdf, 0x0d, 0x72, 0x4d, 0x99, 0xc4, 0xd9, +0xfb, 0x28, 0x14, 0x85, 0xf1, 0x89, 0x4d, 0x57, +0xa0, 0x36, 0xf1, 0x52, 0xd6, 0x08, 0x20, 0x27, +0xaa, 0x92, 0xd0, 0xd4, 0x49, 0x74, 0x16, 0x4e, +0x5a, 0x7d, 0xf2, 0x3d, 0x7f, 0x96, 0xf5, 0x59, +0x04, 0xcd, 0x57, 0x1e, 0x27, 0xb2, 0x1a, 0x41, +0xd7, 0xa4, 0x5e, 0x1f, 0x2e, 0x5c, 0xfa, 0xf7, +0x49, 0x88, 0xda, 0x3b, 0xeb, 0x1b, 0xaf, 0x43, +0x23, 0x24, 0x72, 0x3c, 0x7c, 0xfd, 0xa8, 0x49, +0xf2, 0xd2, 0xfc, 0xa1, 0x8d, 0x9f, 0x8f, 0x39, +0xb0, 0x18, 0x00, 0x02, 0x19, 0xb3, 0x9c, 0x54, +0x9f, 0x14, 0x68, 0x45, 0x96, 0xc1, 0x71, 0xd1, +0xae, 0x82, 0xe5, 0xe9, 0x38, 0xc8, 0xb4, 0x44, +0xb8, 0x80, 0xb9, 0xe4, 0xab, 0xf5, 0xd3, 0xfa, +0xfa, 0x7a, 0x29, 0x38, 0x0a, 0x97, 0xe4, 0xb4, +0x39, 0x54, 0xa7, 0x52, 0x97, 0xcc, 0x1c, 0x9f, +0x1b, 0xd2, 0x4c, 0x43, 0x70, 0x7c, 0x7c, 0xec, +0xa4, 0x71, 0x19, 0x22, 0x96, 0x4b, 0xdd, 0x3c, +0x88, 0x0c, 0x67, 0x06, 0xb4, 0xeb, 0x57, 0x77, +0x77, 0x77, 0x5d, 0x5b, 0xb8, 0x74, 0x4e, 0x1a, +0x01, 0x1e, 0xb5, 0x8e, 0xa4, 0x72, 0x52, 0xb3, +0xcb, 0x4b, 0x5e, 0x68, 0x6d, 0x70, 0x6f, 0x77, +0x92, 0xc8, 0x87, 0xc3, 0x21, 0x1e, 0x3e, 0x7c, +0x88, 0x8d, 0x8d, 0x8d, 0xd2, 0x65, 0x41, 0xa4, +0x05, 0xb0, 0xe6, 0x34, 0x9f, 0xd7, 0x49, 0x92, +0xa0, 0x1d, 0x85, 0x40, 0x14, 0x96, 0xfa, 0x28, +0x88, 0x62, 0xac, 0xad, 0x2c, 0x57, 0xfa, 0x2b, +0x98, 0x5d, 0xea, 0x24, 0x63, 0x4b, 0x58, 0x63, +0xc3, 0xe7, 0x19, 0x8d, 0x03, 0x79, 0xe4, 0xbf, +0xbc, 0x9a, 0xe0, 0x5f, 0x9e, 0x36, 0x90, 0x24, +0x69, 0xc3, 0xad, 0x23, 0x80, 0xfc, 0xbb, 0x2f, +0x8f, 0xf6, 0x4d, 0xbb, 0xf0, 0x84, 0xa7, 0xb5, +0xc0, 0xca, 0xc7, 0xe1, 0x2a, 0x1a, 0x83, 0x40, +0xb1, 0x7f, 0x07, 0x51, 0xf9, 0x56, 0x39, 0x8a, +0xaf, 0xcf, 0x63, 0x06, 0xf0, 0xf6, 0xf0, 0xdb, +0xcc, 0xf2, 0xb4, 0xfc, 0xce, 0x6a, 0x9b, 0xaf, +0x6f, 0xad, 0x76, 0x70, 0xdc, 0xd8, 0xef, 0x52, +0xd4, 0x35, 0xc9, 0x14, 0x51, 0x3d, 0x79, 0x5a, +0x6d, 0x93, 0xd6, 0x9f, 0xb2, 0x4d, 0xd6, 0xf8, +0xc9, 0x76, 0x68, 0xed, 0x0d, 0x6a, 0x6c, 0xe7, +0x8a, 0x44, 0xef, 0x72, 0x58, 0x1b, 0xaf, 0x4f, +0x75, 0xce, 0x37, 0x1e, 0x4b, 0xe2, 0xb5, 0xd4, +0xcb, 0x4d, 0xec, 0x9e, 0xb2, 0x4e, 0xdf, 0x37, +0xcd, 0xe6, 0xde, 0xb4, 0x6e, 0xfe, 0x4e, 0xdb, +0x58, 0xf8, 0xa6, 0x2b, 0xed, 0x6d, 0x52, 0x6a, +0xb6, 0xea, 0xd7, 0xda, 0x62, 0x69, 0x22, 0xb8, +0x59, 0x80, 0x4b, 0x15, 0x75, 0x04, 0x51, 0xb6, +0x83, 0xe3, 0xa8, 0x95, 0x53, 0xd7, 0x97, 0xd6, +0xdc, 0xf0, 0x49, 0x9b, 0x16, 0xc1, 0xaf, 0xc3, +0x1b, 0x40, 0x49, 0x3a, 0xf7, 0xf5, 0x5b, 0xd3, +0xbe, 0xd0, 0xfa, 0xa6, 0xd7, 0xeb, 0xe1, 0xee, +0xdd, 0xbb, 0xee, 0x28, 0x18, 0x6d, 0xf4, 0x3c, +0xfc, 0x2f, 0x8d, 0x35, 0x07, 0x8a, 0x7e, 0xd6, +0xed, 0x76, 0x5d, 0x14, 0x34, 0x3e, 0xee, 0x54, +0x1e, 0x27, 0xd2, 0x96, 0x5a, 0x57, 0x12, 0x6f, +0xab, 0x9f, 0x28, 0xad, 0x26, 0xa5, 0x6b, 0xf7, +0xae, 0x6b, 0xbe, 0x05, 0x1c, 0x78, 0xac, 0x78, +0xca, 0x47, 0xd2, 0x36, 0x95, 0x4f, 0xb6, 0x77, +0x8a, 0xd7, 0x4e, 0x4c, 0x02, 0xa9, 0xff, 0xe9, +0x7f, 0xa7, 0xd3, 0x71, 0x47, 0xd5, 0xa8, 0xef, +0x0e, 0x0f, 0x0f, 0xdd, 0x6d, 0x6f, 0xc4, 0x14, +0xd0, 0x3c, 0x96, 0x84, 0x9d, 0x88, 0x38, 0x11, +0x7e, 0x6b, 0xfc, 0x78, 0x5f, 0x8e, 0xd3, 0xb9, +0xd7, 0x5c, 0x3e, 0xbb, 0xd4, 0x83, 0xde, 0xcb, +0x00, 0x3d, 0x96, 0xa6, 0x8f, 0xfa, 0xe9, 0xf0, +0xf1, 0x13, 0xf4, 0x56, 0x97, 0x2b, 0xeb, 0x9d, +0xb4, 0x07, 0xbc, 0x6f, 0xfb, 0x97, 0x03, 0xdc, +0x5a, 0xb9, 0x0d, 0xc4, 0x37, 0xea, 0x89, 0x31, +0x81, 0xa6, 0xe6, 0x25, 0x22, 0x22, 0xbf, 0x6b, +0x69, 0x69, 0xb3, 0xd6, 0x24, 0x68, 0x22, 0x7e, +0x92, 0x60, 0xc8, 0xba, 0x64, 0x5e, 0x22, 0x4a, +0x92, 0xb0, 0x59, 0x84, 0x96, 0xfe, 0x13, 0xce, +0x14, 0x0f, 0x82, 0x88, 0xae, 0xac, 0x9f, 0xe3, +0xa8, 0xa9, 0x8f, 0xad, 0x70, 0xb6, 0x94, 0x96, +0x5f, 0x64, 0x42, 0xc4, 0x9d, 0xf2, 0xf1, 0xbc, +0x1c, 0x1f, 0xde, 0x86, 0x26, 0xfd, 0xa8, 0xe1, +0x61, 0xa9, 0xe4, 0xe9, 0xbf, 0xac, 0x4f, 0xe2, +0xcb, 0xeb, 0xb7, 0xc6, 0x45, 0x63, 0x44, 0xb4, +0x71, 0xa1, 0xfa, 0xac, 0x32, 0xe8, 0x99, 0xe3, +0x41, 0x92, 0x79, 0x3a, 0x19, 0x37, 0x5a, 0x48, +0x75, 0x84, 0x49, 0x73, 0x2e, 0xaa, 0x23, 0x6a, +0x4d, 0xc0, 0x67, 0x17, 0x95, 0xd2, 0xa1, 0xa5, +0x9e, 0x96, 0xe5, 0x34, 0x65, 0x1c, 0xe4, 0x42, +0x97, 0x9b, 0xac, 0xc6, 0x2c, 0x70, 0xb5, 0xad, +0xcf, 0x4e, 0xcc, 0xcb, 0x90, 0xd2, 0x00, 0x57, +0x17, 0xf2, 0x32, 0x49, 0x45, 0xa8, 0x69, 0x3e, +0x34, 0xf5, 0xbe, 0xd5, 0x0f, 0x96, 0xfd, 0x5c, +0x93, 0xfe, 0x2d, 0x86, 0x4e, 0x8e, 0x39, 0x7f, +0x57, 0x67, 0xca, 0xe0, 0xc0, 0x6d, 0xe3, 0x9c, +0x90, 0x4b, 0x49, 0xdd, 0xa7, 0x4d, 0x91, 0xa1, +0x4b, 0x35, 0x7c, 0xf8, 0xb7, 0xc1, 0x60, 0xe0, +0x08, 0x1a, 0x11, 0x26, 0x39, 0x6e, 0x3c, 0x1f, +0xd9, 0x7f, 0xa5, 0x76, 0x86, 0xd7, 0x71, 0x70, +0x70, 0xe0, 0x24, 0x4d, 0x1a, 0x27, 0x39, 0x37, +0xb4, 0x39, 0xeb, 0x9b, 0x8f, 0x96, 0x6f, 0x03, +0xd9, 0xac, 0x79, 0x3f, 0xc9, 0xfe, 0xe2, 0x8e, +0x74, 0x84, 0x3f, 0xf5, 0x6d, 0xb7, 0xdb, 0x75, +0xaa, 0x70, 0x7a, 0x27, 0xed, 0xdd, 0xa4, 0x5e, +0xd7, 0x9c, 0x13, 0xa9, 0x7e, 0x6a, 0x0b, 0xe5, +0xbd, 0x7d, 0xfb, 0x76, 0x89, 0x90, 0xef, 0xed, +0xed, 0xa1, 0x3f, 0xbb, 0x9c, 0x65, 0x67, 0x67, +0xc7, 0x8d, 0xd5, 0x60, 0x30, 0xc0, 0xde, 0xde, +0x5e, 0xc9, 0x31, 0x2e, 0x68, 0x77, 0x70, 0xfd, +0xda, 0x46, 0xa9, 0x1e, 0x3e, 0x17, 0xad, 0x88, +0x93, 0x5c, 0x43, 0xc2, 0xfb, 0x88, 0x9b, 0x62, +0x64, 0x3a, 0xfa, 0x5d, 0xa4, 0x63, 0x6c, 0x6c, +0x6c, 0x94, 0xf2, 0x50, 0x3d, 0xa3, 0x2c, 0x47, +0x31, 0x19, 0x4f, 0xcb, 0x3c, 0x3d, 0x41, 0xba, +0xb9, 0x02, 0x5c, 0x42, 0x27, 0x4c, 0xbe, 0x0d, +0x1b, 0xb0, 0x89, 0x99, 0xb5, 0xf1, 0x03, 0xd5, +0x4b, 0x3b, 0x38, 0xc1, 0xe5, 0x9b, 0xbd, 0x55, +0xbe, 0x4f, 0x45, 0xcb, 0xf3, 0xd7, 0x9d, 0xa5, +0x96, 0x52, 0x23, 0x27, 0x62, 0x92, 0x50, 0x36, +0xd1, 0x3a, 0x68, 0x84, 0x57, 0x32, 0x15, 0x44, +0xac, 0x38, 0x81, 0xd3, 0xa4, 0x58, 0x9e, 0x4f, +0xb6, 0x93, 0xab, 0xb1, 0x89, 0x09, 0xb1, 0x98, +0x20, 0x1f, 0xde, 0x32, 0x9f, 0x26, 0x99, 0xcb, +0xd0, 0xbf, 0xb2, 0x6f, 0x25, 0xd3, 0x21, 0xcb, +0xd7, 0xc6, 0x45, 0xa6, 0x91, 0x8c, 0x95, 0xd2, +0x6f, 0x51, 0x14, 0xb7, 0x6b, 0x55, 0xbd, 0x3e, +0x7b, 0xa0, 0xb6, 0x69, 0xf1, 0x05, 0x28, 0x9d, +0xa9, 0x34, 0xbb, 0xac, 0x05, 0x3e, 0x42, 0x2e, +0xf1, 0xb4, 0x24, 0x41, 0x9f, 0xda, 0x5b, 0xa6, +0xd7, 0x24, 0x2a, 0xde, 0x0e, 0x2e, 0x79, 0x71, +0xd5, 0xbb, 0xcf, 0x86, 0xaa, 0xe1, 0x02, 0xd8, +0x31, 0xd9, 0xa9, 0x7c, 0x1f, 0x63, 0x22, 0xfb, +0xc3, 0x6a, 0xb3, 0x4c, 0xaf, 0x49, 0x2a, 0x75, +0x7d, 0xac, 0xd9, 0x7f, 0xad, 0x34, 0xd6, 0x7c, +0xf1, 0x95, 0xc9, 0xed, 0xe4, 0xf4, 0x4c, 0x20, +0x9d, 0xe0, 0xb4, 0xf7, 0x3e, 0x4d, 0x02, 0xfd, +0x26, 0x02, 0x4c, 0xfd, 0xcb, 0x6f, 0x03, 0xa3, +0xf2, 0x24, 0x7e, 0xf2, 0xba, 0x50, 0xfa, 0xcf, +0xa5, 0x50, 0xd9, 0x46, 0xf2, 0xdc, 0xbe, 0x77, +0xef, 0x1e, 0x7e, 0xf6, 0xb3, 0x9f, 0x79, 0xe7, +0x85, 0xec, 0x4b, 0xcd, 0x64, 0xc3, 0x89, 0x8b, +0x35, 0x4f, 0x78, 0xa8, 0x55, 0x02, 0xb2, 0x6f, +0x53, 0x68, 0x56, 0xde, 0x76, 0x8d, 0xd9, 0x23, +0xbb, 0x3a, 0xd7, 0x04, 0xf0, 0x7e, 0x26, 0x69, +0x9c, 0xfa, 0xb2, 0xdb, 0xed, 0xe2, 0xe3, 0x8f, +0x3f, 0xc6, 0x70, 0x38, 0x0d, 0x7e, 0xd3, 0xef, +0xf7, 0x71, 0xfb, 0xf6, 0xed, 0x92, 0x44, 0xdf, +0xed, 0x76, 0xf1, 0xf0, 0xe1, 0x43, 0x7c, 0xfc, +0xf1, 0xc7, 0xee, 0xdb, 0xf1, 0xf1, 0xb1, 0xb3, +0xd1, 0xf3, 0x3e, 0x94, 0xfe, 0x0f, 0x9a, 0x56, +0x44, 0xc2, 0x38, 0x2f, 0x9c, 0x19, 0x50, 0xd3, +0xd2, 0x50, 0xff, 0xf1, 0x3e, 0xe5, 0xb6, 0x79, +0x4a, 0x6b, 0x69, 0x38, 0x08, 0xda, 0xbb, 0xb7, +0xf0, 0x64, 0xeb, 0x39, 0xfc, 0xde, 0x80, 0x9d, +0x77, 0xf6, 0x49, 0xb3, 0xf4, 0x4c, 0xe9, 0xb4, +0xef, 0x9a, 0x64, 0x6c, 0x49, 0xf2, 0x75, 0x04, +0xda, 0x2a, 0x5f, 0xe2, 0xa7, 0xa9, 0xe8, 0xeb, +0x08, 0xad, 0xcc, 0x23, 0xf3, 0x71, 0x89, 0x52, +0xe6, 0x93, 0xaa, 0xeb, 0x3a, 0x15, 0xb3, 0x25, +0x05, 0xcb, 0xf7, 0x16, 0xf3, 0xe3, 0xeb, 0x47, +0x9e, 0x8f, 0xab, 0xcc, 0xa5, 0x96, 0x44, 0xc3, +0x9b, 0x33, 0x17, 0x32, 0xbf, 0xd5, 0x7e, 0xc2, +0x5f, 0x6a, 0x30, 0xb4, 0xf2, 0xeb, 0x98, 0x04, +0x99, 0xde, 0x6a, 0x7f, 0xdc, 0x41, 0x78, 0xf3, +0x8d, 0xdf, 0x78, 0x73, 0xfd, 0xe2, 0xa8, 0x74, +0x5e, 0x3b, 0x4d, 0x53, 0x4c, 0xd2, 0x0c, 0x9d, +0x76, 0xbb, 0x14, 0x9a, 0x12, 0x40, 0xe9, 0xbc, +0x39, 0x00, 0xf5, 0x8c, 0x32, 0x7d, 0xa7, 0x3c, +0x32, 0xa8, 0x87, 0x7c, 0x06, 0xca, 0x67, 0x90, +0x35, 0x90, 0x01, 0x3c, 0x08, 0x68, 0x13, 0xd0, +0x42, 0x8a, 0xf2, 0x7c, 0x72, 0xd3, 0x97, 0xe7, +0xb0, 0x87, 0xc3, 0x6a, 0x70, 0x13, 0x6a, 0x2f, +0xc7, 0x99, 0xf7, 0x03, 0x57, 0x5d, 0xf3, 0xfa, +0x09, 0x27, 0x1e, 0xa8, 0xc5, 0x17, 0x42, 0x56, +0xe2, 0x2f, 0xcf, 0x6f, 0xcb, 0xf3, 0xd6, 0xbc, +0xbf, 0x64, 0xa0, 0x18, 0x4d, 0xea, 0xb6, 0x82, +0xba, 0x68, 0xdf, 0xe5, 0x79, 0x7d, 0xed, 0x1c, +0x35, 0x87, 0x30, 0x8a, 0x51, 0xe4, 0xb9, 0x1a, +0xd6, 0x95, 0xa7, 0x4d, 0x92, 0x04, 0x45, 0x2b, +0xc0, 0x64, 0x3c, 0x2a, 0xe1, 0x51, 0x47, 0xb0, +0x47, 0xa3, 0x51, 0xa9, 0x1c, 0xf9, 0x9e, 0x36, +0x63, 0x7e, 0x1e, 0x9c, 0x42, 0xc4, 0xd2, 0x77, +0x1e, 0xb4, 0x85, 0x8f, 0x21, 0xc7, 0x93, 0x9f, +0xeb, 0xe6, 0xf3, 0x84, 0x18, 0x01, 0x9e, 0x86, +0xce, 0x5b, 0x6b, 0x67, 0xf2, 0xa3, 0x28, 0x72, +0xea, 0xe4, 0x7e, 0xbf, 0x5f, 0x09, 0xc0, 0xa4, +0xf5, 0x29, 0x9f, 0x13, 0x14, 0xfe, 0x55, 0xae, +0x17, 0x8e, 0x1f, 0xc5, 0x78, 0xe7, 0xe5, 0xf0, +0xb3, 0xf4, 0xcb, 0xcb, 0xcb, 0xce, 0xae, 0x3d, +0x1c, 0x0e, 0x5d, 0x7c, 0x02, 0x9a, 0xe3, 0x45, +0x51, 0x38, 0x95, 0x7a, 0xab, 0xd5, 0xc2, 0xea, +0xea, 0xaa, 0x0b, 0x09, 0x4b, 0x73, 0x87, 0xda, +0x4c, 0x67, 0xc7, 0x69, 0x0d, 0x91, 0xe4, 0x7e, +0x78, 0x78, 0x88, 0xfd, 0xfd, 0x7d, 0x87, 0xd7, +0xc6, 0xc6, 0x86, 0x53, 0x9d, 0xef, 0xef, 0xef, +0xe3, 0xec, 0xec, 0xcc, 0x31, 0x4d, 0x84, 0x1b, +0xc5, 0x7b, 0xdf, 0xda, 0xda, 0xc2, 0xd1, 0xd1, +0x11, 0x8e, 0x8f, 0x8f, 0xb1, 0xbd, 0xbd, 0xed, +0xfa, 0xe8, 0xe8, 0xe8, 0xc8, 0xf5, 0x15, 0x67, +0x2c, 0x48, 0x9a, 0xe6, 0xe7, 0xf4, 0x27, 0xb3, +0x78, 0xf4, 0x67, 0x83, 0x11, 0x5a, 0x45, 0xee, +0xfe, 0x53, 0x9a, 0xb3, 0xb3, 0x33, 0xd7, 0x1f, +0xad, 0x56, 0xcb, 0x5d, 0x3b, 0xcb, 0x43, 0x07, +0x73, 0x2d, 0x22, 0xc5, 0x69, 0xb8, 0x18, 0x8d, +0xd1, 0x0a, 0x43, 0x74, 0x57, 0x56, 0xf1, 0xe9, +0x9d, 0xef, 0xe0, 0xf7, 0xb6, 0x5e, 0xc3, 0xef, +0x4d, 0xd6, 0xf1, 0xb4, 0x88, 0xa6, 0x9b, 0x6c, +0x10, 0x4c, 0xcf, 0xf6, 0x66, 0x19, 0x10, 0xc5, +0xf3, 0xdf, 0x45, 0x3e, 0x3f, 0xf3, 0x9b, 0x65, +0x40, 0x51, 0x4c, 0xbf, 0xd3, 0x59, 0xe8, 0x50, +0xe4, 0x0f, 0x82, 0xea, 0x86, 0xcc, 0xbf, 0x03, +0xf3, 0xbc, 0xf4, 0x9e, 0xfe, 0x4f, 0x46, 0x00, +0x5a, 0x7a, 0xf9, 0x54, 0x2f, 0xe5, 0x27, 0x82, +0x19, 0xcc, 0xce, 0xfd, 0xc9, 0xfc, 0xd3, 0x45, +0x3c, 0x43, 0xa0, 0x55, 0xae, 0x87, 0xa0, 0x28, +0xa6, 0x7f, 0xf4, 0x8d, 0xda, 0x2a, 0xf3, 0xf1, +0x76, 0xb4, 0x82, 0x69, 0xf9, 0x59, 0x06, 0x64, +0x93, 0x72, 0xdf, 0x04, 0xc1, 0x34, 0x4f, 0x36, +0x99, 0xe3, 0x40, 0xdf, 0x1c, 0xa1, 0x15, 0x78, +0x50, 0xfd, 0x00, 0x93, 0x80, 0xa3, 0x6a, 0x5f, +0x95, 0xce, 0x83, 0xcf, 0xf0, 0x2a, 0x95, 0xc5, +0x70, 0x95, 0x78, 0x65, 0xb3, 0x78, 0xff, 0xfc, +0x5d, 0xc4, 0x9c, 0x00, 0xb5, 0x71, 0xe4, 0x4c, +0x09, 0xd5, 0x43, 0xed, 0xe2, 0x69, 0x1d, 0xb4, +0xe6, 0xfd, 0xc2, 0x71, 0x23, 0x82, 0x1e, 0x04, +0xe5, 0xb6, 0x86, 0x91, 0x3e, 0x2e, 0xca, 0xbc, +0x33, 0x89, 0xf9, 0x78, 0x3c, 0x41, 0x91, 0xe7, +0x95, 0x20, 0x18, 0x72, 0x93, 0xe6, 0xc4, 0x52, +0x4a, 0x00, 0xb4, 0xb9, 0x6a, 0x84, 0x87, 0x13, +0x12, 0x2e, 0xd9, 0xf1, 0x20, 0x1e, 0x32, 0x88, +0x8c, 0x16, 0x70, 0x85, 0xc7, 0x0a, 0xd7, 0x08, +0xbe, 0x0c, 0x1a, 0xc2, 0xdf, 0x4b, 0x46, 0x45, +0xab, 0x97, 0xe3, 0xc8, 0xbf, 0x6f, 0x6d, 0x6d, +0xb9, 0x0d, 0x80, 0xf0, 0x97, 0x41, 0x4d, 0xa8, +0xfd, 0x44, 0x08, 0x88, 0xe8, 0xf3, 0x00, 0x27, +0xb4, 0xd9, 0x6a, 0x71, 0xd2, 0xa9, 0x2c, 0x0a, +0x10, 0x43, 0x81, 0x38, 0xa8, 0x2c, 0xfa, 0xc6, +0xf1, 0xac, 0xeb, 0x2b, 0xd9, 0x2e, 0x3e, 0xe6, +0x3c, 0x2f, 0xe5, 0xd3, 0xf2, 0xf0, 0x34, 0x61, +0x10, 0x20, 0x8c, 0x62, 0xe4, 0x05, 0x30, 0x19, +0x8f, 0x4a, 0x75, 0x52, 0x7b, 0x29, 0x6d, 0x10, +0x86, 0x08, 0x83, 0x96, 0x2b, 0xd3, 0x22, 0xe4, +0x7c, 0x2c, 0xb5, 0x18, 0xfd, 0xd2, 0xb6, 0xae, +0x05, 0x32, 0xca, 0xb2, 0xcc, 0x6d, 0xdc, 0x72, +0x0c, 0xa4, 0x16, 0x21, 0x4d, 0x53, 0x17, 0xab, +0x7c, 0x6b, 0x6b, 0xcb, 0xf5, 0x3b, 0xe1, 0x9f, +0x24, 0x89, 0x8b, 0xad, 0x2e, 0x99, 0x57, 0x19, +0xcb, 0x9e, 0xb4, 0x2a, 0xfb, 0xfb, 0xfb, 0x4e, +0xaa, 0x25, 0xa2, 0x21, 0xe3, 0xc6, 0x73, 0x06, +0x44, 0x9a, 0xa9, 0x38, 0xf3, 0x60, 0x45, 0xe8, +0x93, 0x51, 0xe6, 0x68, 0x9e, 0x6c, 0x6d, 0x6d, +0xb9, 0x20, 0x30, 0x7c, 0x1c, 0xcf, 0xcf, 0xcf, +0xb1, 0xbf, 0xbf, 0x8f, 0x27, 0x4f, 0x9e, 0x20, +0x49, 0x12, 0x64, 0x59, 0x86, 0x4e, 0xa7, 0xe3, +0x18, 0xa0, 0xe5, 0xe5, 0x65, 0xb4, 0x5a, 0x2d, +0xac, 0xac, 0xac, 0x60, 0x79, 0x79, 0x19, 0x51, +0x14, 0xe1, 0xe2, 0xe2, 0xc2, 0xe5, 0xa5, 0x3a, +0x88, 0x89, 0x25, 0x46, 0x97, 0xce, 0x9f, 0x5f, +0x5c, 0x5c, 0x60, 0x73, 0x73, 0x13, 0xad, 0x56, +0xab, 0x14, 0xf3, 0xbd, 0xd5, 0x6a, 0xe1, 0xd6, +0xad, 0x5b, 0x38, 0x3c, 0x3c, 0x74, 0x61, 0x6c, +0x8f, 0x8e, 0x8e, 0x70, 0xeb, 0xd6, 0x2d, 0x1c, +0x1d, 0x1d, 0x39, 0x02, 0xbc, 0xb5, 0xb5, 0xe5, +0x62, 0xd3, 0x53, 0xdc, 0xfa, 0x7e, 0xbf, 0xef, +0x3c, 0xf8, 0x29, 0x20, 0x0d, 0xfd, 0xb5, 0x5a, +0x2d, 0x64, 0x33, 0x33, 0x61, 0x36, 0x19, 0xe3, +0xf8, 0xf8, 0x18, 0x4f, 0x9e, 0x3c, 0xc1, 0xf9, +0xf9, 0xb9, 0x1b, 0xff, 0x2c, 0x9b, 0x5e, 0xd1, +0x4a, 0x6d, 0xa5, 0xe7, 0x51, 0x0e, 0x20, 0x2b, +0x8f, 0xdd, 0xca, 0xca, 0x0a, 0xda, 0x2b, 0x6b, +0x78, 0x9c, 0x6c, 0xe0, 0x77, 0xf7, 0xde, 0xc0, +0x7b, 0xdd, 0x5d, 0x7c, 0x76, 0x31, 0xc6, 0x24, +0xcb, 0xe6, 0x04, 0x98, 0x08, 0x26, 0x57, 0x87, +0x72, 0x02, 0x4c, 0x1b, 0x33, 0xa5, 0x8d, 0xc4, +0x11, 0x24, 0x22, 0xa4, 0x9c, 0x29, 0x20, 0xa2, +0xc2, 0xcb, 0xe7, 0x65, 0xf2, 0x0d, 0x1f, 0x28, +0xa7, 0x95, 0xe5, 0xf3, 0x4d, 0x9f, 0xca, 0x27, +0x42, 0xc1, 0xcb, 0xe5, 0x04, 0x86, 0x70, 0x72, +0x92, 0xe1, 0x64, 0x4e, 0xa8, 0xe8, 0x3d, 0x67, +0x06, 0x24, 0x61, 0xe6, 0xe9, 0xa9, 0x6c, 0x2b, +0x3d, 0x27, 0xd6, 0x92, 0xf9, 0x29, 0x99, 0x16, +0x5a, 0xf3, 0xfe, 0xe2, 0xed, 0xa5, 0x7c, 0x1a, +0x73, 0x60, 0xd5, 0x35, 0x19, 0xcd, 0xfb, 0x49, +0x96, 0xc3, 0xcb, 0xd7, 0xf0, 0xb1, 0x98, 0x00, +0xf7, 0xdc, 0x6a, 0xd6, 0x5e, 0xd9, 0x0e, 0xcd, +0x89, 0x4e, 0x7e, 0xe3, 0x79, 0xe4, 0xb8, 0x28, +0x38, 0x97, 0x88, 0x39, 0x27, 0x22, 0x45, 0x9e, +0x57, 0xd4, 0xce, 0x16, 0x91, 0xe0, 0x52, 0x2f, +0x27, 0x56, 0x9c, 0x88, 0xf2, 0x0d, 0x4a, 0x12, +0x39, 0x2e, 0x91, 0xca, 0xcd, 0x5c, 0xdb, 0xe0, +0xa5, 0x84, 0xa8, 0x11, 0x53, 0x79, 0xc9, 0x09, +0xbd, 0xe3, 0x1b, 0x21, 0xdf, 0x8c, 0x39, 0x1e, +0x5c, 0x42, 0xe7, 0xd2, 0x35, 0x0f, 0xbd, 0xca, +0xeb, 0xa5, 0xdf, 0x9c, 0x28, 0xcb, 0xff, 0x12, +0x47, 0x6d, 0x43, 0xe6, 0x1b, 0x37, 0x4f, 0xa3, +0xd9, 0x0c, 0xe5, 0x85, 0x27, 0xfc, 0x3d, 0x67, +0x8a, 0x78, 0x5f, 0xf1, 0xf6, 0x4b, 0x4d, 0x88, +0xec, 0x07, 0xc9, 0xbc, 0x48, 0xe0, 0x78, 0x0e, +0x2e, 0x2f, 0x51, 0xe4, 0x59, 0x09, 0x17, 0xa9, +0xad, 0x89, 0xa2, 0xc8, 0x11, 0x7b, 0x19, 0xb5, +0x8f, 0x83, 0xa6, 0xa1, 0xe1, 0xef, 0x34, 0x27, +0x39, 0x2a, 0x47, 0x4a, 0xeb, 0x04, 0x59, 0x96, +0x55, 0xa4, 0x5b, 0xde, 0xd6, 0xe1, 0x70, 0x88, +0x38, 0x8e, 0xb1, 0xb5, 0xb5, 0x85, 0xad, 0xad, +0xad, 0x52, 0xdf, 0x52, 0xd4, 0xb5, 0xa2, 0x28, +0x9c, 0xe3, 0x19, 0x8d, 0x05, 0xa5, 0x4b, 0x92, +0x69, 0x88, 0x53, 0x22, 0xfa, 0xd4, 0x07, 0x7b, +0x7b, 0x7b, 0x2e, 0x1a, 0x9b, 0xa6, 0x35, 0x92, +0x63, 0x25, 0xe7, 0x0c, 0x57, 0x1b, 0xf3, 0x48, +0x82, 0x9c, 0x39, 0x96, 0x66, 0xa6, 0x28, 0x8a, +0xdc, 0xb9, 0x72, 0xa9, 0x15, 0x20, 0xfc, 0xa8, +0x3e, 0x62, 0xa4, 0x48, 0x8d, 0x4e, 0xc4, 0x9b, +0x98, 0xa1, 0x28, 0x8a, 0xdc, 0x37, 0xe9, 0x24, +0xc6, 0xfb, 0x69, 0x38, 0x1c, 0xe2, 0xc1, 0x83, +0x07, 0xd8, 0xda, 0xda, 0xc2, 0xf6, 0xf6, 0xb6, +0x0b, 0x47, 0x4b, 0x65, 0xd2, 0x59, 0xf3, 0xe5, +0xe5, 0x65, 0x64, 0x59, 0x86, 0xfb, 0xf7, 0xef, +0x3b, 0xa6, 0xe9, 0xec, 0xec, 0x0c, 0xc3, 0xe1, +0xd0, 0x5d, 0xb7, 0xca, 0xdb, 0x4a, 0x52, 0xfd, +0xc5, 0xc5, 0x05, 0x9e, 0x3c, 0x79, 0x82, 0xd1, +0x68, 0x54, 0xfa, 0x23, 0x66, 0x9a, 0xa4, 0x76, +0x1e, 0xfa, 0x56, 0xd3, 0x12, 0x12, 0x63, 0x75, +0x31, 0x1a, 0x23, 0x2c, 0x32, 0x24, 0x49, 0x82, +0x60, 0x69, 0x15, 0xd8, 0xbc, 0x81, 0x4f, 0xd7, +0x6f, 0xe1, 0xcf, 0x7a, 0x2f, 0xe1, 0x9f, 0x2c, +0xbf, 0x88, 0x3f, 0xea, 0xde, 0xc6, 0xd3, 0x22, +0xc2, 0xa0, 0x15, 0xcf, 0x25, 0x23, 0x4e, 0x70, +0x89, 0x28, 0xca, 0xf0, 0xb3, 0xd2, 0xbe, 0xec, +0x36, 0x61, 0x46, 0x50, 0xa3, 0xb8, 0x4c, 0x50, +0xb8, 0x94, 0xca, 0xcb, 0xe7, 0x75, 0x84, 0x51, +0x59, 0x32, 0xe6, 0x84, 0x43, 0x96, 0x4f, 0xc4, +0x55, 0x12, 0x99, 0x0a, 0x71, 0x42, 0x59, 0xda, +0xe4, 0xc4, 0x9d, 0x4b, 0x9c, 0xbc, 0x8e, 0x12, +0x11, 0xc3, 0x1c, 0x67, 0x1e, 0x52, 0x55, 0x4a, +0xa8, 0x3c, 0xa2, 0x99, 0x64, 0x12, 0x78, 0x3b, +0xb8, 0x34, 0xca, 0x19, 0x0b, 0x99, 0x8e, 0x33, +0x25, 0x96, 0x24, 0x2f, 0xfb, 0x83, 0xd7, 0xe9, +0x23, 0xd2, 0x9c, 0x48, 0x52, 0x1d, 0xb2, 0x1e, +0x6a, 0xa7, 0x1c, 0x03, 0xea, 0x23, 0x0d, 0x37, +0x32, 0xab, 0xc8, 0x76, 0x64, 0x93, 0xb9, 0x64, +0xad, 0x31, 0x2d, 0x79, 0x36, 0xfd, 0x93, 0x8c, +0x8a, 0x94, 0xf8, 0x67, 0x2a, 0xfd, 0x12, 0x31, +0xb7, 0x42, 0x67, 0xca, 0x98, 0xde, 0x7c, 0xc3, +0x91, 0x9b, 0x3e, 0x2d, 0x6e, 0x4e, 0xd8, 0x35, +0x35, 0xbc, 0x94, 0x50, 0x2c, 0x15, 0x3b, 0xe1, +0x23, 0xd3, 0x4b, 0xdc, 0xa8, 0x7c, 0x92, 0x5e, +0xe5, 0xa6, 0xa7, 0x49, 0xa7, 0xbc, 0xad, 0x96, +0xa3, 0x1e, 0x6f, 0x2f, 0xb5, 0x8b, 0x4b, 0x53, +0x52, 0xb2, 0xa2, 0x5b, 0xa7, 0x38, 0x7e, 0x9a, +0x36, 0xc2, 0x52, 0x97, 0xcb, 0x70, 0xba, 0xfc, +0x3f, 0x95, 0xab, 0xb5, 0x47, 0x0b, 0x5f, 0xca, +0xf1, 0x96, 0xe9, 0x7d, 0xe1, 0x74, 0x35, 0xcd, +0x0b, 0x1f, 0x63, 0x9e, 0x47, 0x2b, 0x87, 0x33, +0x81, 0x92, 0xb1, 0xd0, 0xea, 0x96, 0xfd, 0xc0, +0x9f, 0x65, 0x7a, 0x8e, 0x23, 0x27, 0x3a, 0xf4, +0x8e, 0x88, 0x3d, 0x0f, 0x11, 0x4b, 0xc4, 0x9f, +0x24, 0x3e, 0xcd, 0xac, 0x42, 0x75, 0xf7, 0x7a, +0xbd, 0x92, 0x74, 0x4e, 0x04, 0x2b, 0x8e, 0x63, +0xc4, 0x71, 0x8c, 0x4e, 0xa7, 0x83, 0x38, 0x8e, +0x5d, 0xdb, 0x72, 0xb4, 0x50, 0xe4, 0x79, 0x49, +0x3b, 0x44, 0xd2, 0xe5, 0xca, 0xca, 0x0a, 0xf6, +0xf7, 0xf7, 0x71, 0x70, 0x70, 0xe0, 0x24, 0x4d, +0x39, 0xc7, 0xb4, 0x79, 0x21, 0xd7, 0x89, 0x36, +0x77, 0x69, 0xde, 0x01, 0x28, 0xdd, 0xb8, 0x47, +0xcf, 0x9c, 0x19, 0xe5, 0xf3, 0xa0, 0xd3, 0xe9, +0x60, 0x75, 0x75, 0x15, 0x45, 0x31, 0xbf, 0xfa, +0xf8, 0xe4, 0xe4, 0x04, 0xbb, 0xbb, 0xbb, 0x4e, +0x62, 0x27, 0xa0, 0x38, 0xef, 0x3c, 0x3c, 0x2b, +0xdd, 0xe6, 0xc6, 0x4d, 0x0f, 0x14, 0xd3, 0x7c, +0x7d, 0x7d, 0x1d, 0x27, 0x27, 0x27, 0x25, 0x6f, +0xf0, 0xfd, 0xfd, 0x7d, 0x1c, 0x1d, 0x1d, 0xe1, +0xfc, 0xfc, 0x1c, 0xb7, 0x6e, 0xdd, 0xc2, 0xfd, +0xfb, 0xf7, 0x01, 0x00, 0x5b, 0x5b, 0x5b, 0xee, +0xa8, 0xdd, 0xc6, 0xc6, 0x46, 0xa9, 0xaf, 0xa9, +0xae, 0xf7, 0xdf, 0x7f, 0xbf, 0xe4, 0x8c, 0x48, +0xe6, 0x01, 0x3e, 0x0f, 0xf9, 0x8d, 0x8c, 0x7c, +0xde, 0x73, 0xd3, 0x00, 0xa9, 0xea, 0xa3, 0x28, +0x42, 0xab, 0x9d, 0xa0, 0xd8, 0xb8, 0x8e, 0x27, +0x37, 0x5e, 0xc6, 0xfd, 0xcd, 0x17, 0xf0, 0xbb, +0x2b, 0x2f, 0xe2, 0x9f, 0x16, 0xdb, 0xf8, 0xd3, +0xd6, 0x26, 0x3e, 0x6d, 0x2d, 0xe1, 0x12, 0xe1, +0x5c, 0xdd, 0x0a, 0x30, 0x7b, 0xb1, 0x46, 0xb0, +0x5b, 0x53, 0x75, 0xb2, 0xb6, 0x79, 0x73, 0x22, +0x2f, 0x55, 0xc5, 0x1a, 0xd1, 0xb7, 0x24, 0x7b, +0x2a, 0xdf, 0x92, 0xce, 0xb4, 0xf2, 0x35, 0xc9, +0xdb, 0x49, 0xf0, 0x9c, 0xc0, 0xb6, 0xca, 0x04, +0x5a, 0xd3, 0x0a, 0xc8, 0x3e, 0xd0, 0x24, 0x7f, +0xa9, 0x5e, 0xe6, 0xe9, 0xd5, 0x32, 0x5b, 0xb6, +0xc4, 0xca, 0xdb, 0xca, 0xf1, 0x96, 0x5a, 0x02, +0x4e, 0xb0, 0x39, 0x23, 0xc4, 0xdb, 0x28, 0x71, +0xd5, 0xfa, 0xd1, 0x27, 0xa9, 0x6b, 0xf8, 0x68, +0x7d, 0xa5, 0x69, 0x30, 0x64, 0x3f, 0x6b, 0xb8, +0x5a, 0xa6, 0x0a, 0xde, 0x5f, 0x12, 0x17, 0x5e, +0x17, 0xd7, 0x20, 0x84, 0xd1, 0x9c, 0x98, 0x4b, +0xb5, 0x9e, 0xdc, 0x6c, 0x2c, 0x9b, 0xb6, 0x24, +0x3e, 0x9c, 0x13, 0xe6, 0xcc, 0x81, 0xdc, 0xa4, +0x24, 0xf3, 0x60, 0x11, 0x73, 0xc9, 0x08, 0xc8, +0x6f, 0x56, 0x1a, 0x9f, 0x59, 0x40, 0xaa, 0x97, +0xad, 0xb8, 0xf4, 0x40, 0x39, 0xee, 0xb7, 0xc4, +0x81, 0x6f, 0xb6, 0xda, 0xa5, 0x17, 0x1a, 0xc1, +0x25, 0x29, 0x82, 0xca, 0xe6, 0x44, 0x85, 0xab, +0xfe, 0x2d, 0xe2, 0x2a, 0x99, 0x26, 0x5e, 0xbe, +0xa6, 0xe1, 0xa0, 0x67, 0x19, 0xaf, 0x9c, 0x83, +0xd4, 0x1a, 0xf0, 0x7a, 0xa4, 0xff, 0x83, 0x36, +0xc6, 0xda, 0x98, 0x48, 0xed, 0x02, 0xff, 0xad, +0x8d, 0xb5, 0x65, 0x02, 0x90, 0x7e, 0x02, 0x9a, +0x4a, 0x1d, 0x98, 0x4b, 0xe5, 0x92, 0xb8, 0xd3, +0xb3, 0x94, 0xce, 0xc9, 0x54, 0x22, 0xbd, 0xfb, +0xd3, 0xa2, 0x85, 0xde, 0xfa, 0x5a, 0x49, 0x8a, +0x0d, 0xc3, 0x10, 0x69, 0x9a, 0x3a, 0x82, 0x1e, +0x86, 0xa1, 0xb3, 0x37, 0x77, 0xda, 0x6d, 0xe7, +0x11, 0xdf, 0x6a, 0xb5, 0x54, 0x5c, 0x57, 0x56, +0x56, 0x70, 0x70, 0x70, 0x80, 0xdd, 0xdd, 0x5d, +0x47, 0xd0, 0x79, 0x3a, 0x6b, 0x5e, 0x4b, 0x42, +0xcf, 0x35, 0x44, 0xfc, 0x3e, 0x04, 0x02, 0x62, +0x9c, 0x09, 0x6f, 0xce, 0x08, 0x53, 0x3b, 0x37, +0x36, 0x36, 0xd0, 0xef, 0xf7, 0x4b, 0xfd, 0x14, +0xc7, 0xb1, 0x23, 0x94, 0xcb, 0xcb, 0xcb, 0x4e, +0xb5, 0xce, 0xf1, 0x27, 0x66, 0x84, 0x54, 0xf5, +0x34, 0x6f, 0xa9, 0x2d, 0xbd, 0x5e, 0x0f, 0x17, +0x17, 0x17, 0x38, 0x3a, 0x3a, 0x72, 0xf5, 0x91, +0xd7, 0x3b, 0x49, 0xf2, 0x14, 0xf3, 0x7d, 0x7f, +0x7f, 0x1f, 0x69, 0x9a, 0x3a, 0x55, 0x3c, 0xbf, +0x76, 0x95, 0xd7, 0x43, 0x5a, 0x0f, 0x72, 0x48, +0xa4, 0x0b, 0x60, 0xb8, 0xea, 0x3f, 0x4d, 0x53, +0xa7, 0xaa, 0xcf, 0x5a, 0x01, 0x46, 0x93, 0xc9, +0x4c, 0x9a, 0x61, 0x9a, 0x8f, 0x6b, 0x7b, 0x68, +0xed, 0xbf, 0x84, 0x77, 0xb6, 0x5e, 0xc6, 0x9f, +0x5d, 0x7f, 0x05, 0xff, 0x4b, 0xbc, 0x8f, 0xf7, +0xdb, 0xd7, 0xf1, 0x76, 0xda, 0xc5, 0x71, 0x1e, +0x22, 0x8d, 0xda, 0x65, 0x42, 0xcb, 0x6d, 0xbd, +0xd2, 0x66, 0xca, 0x25, 0x48, 0x29, 0xf9, 0xd2, +0x6f, 0xb2, 0x55, 0x53, 0x3e, 0x69, 0xbb, 0xe5, +0x1b, 0x3b, 0x97, 0xbc, 0x64, 0x39, 0xbc, 0x7c, +0x60, 0x8e, 0x9b, 0x74, 0x76, 0xa3, 0xfc, 0xd2, +0xb6, 0xcd, 0x25, 0x67, 0x79, 0x75, 0xa6, 0x24, +0xd0, 0x54, 0x1f, 0xaf, 0x5f, 0xb3, 0xe1, 0x6a, +0x38, 0x4a, 0xe2, 0x2d, 0xd5, 0xdb, 0x52, 0xab, +0x20, 0xfb, 0xda, 0xb5, 0x6f, 0x52, 0x95, 0x44, +0x35, 0x3f, 0x03, 0x89, 0xb3, 0xbc, 0xc4, 0x45, +0xb6, 0x91, 0xf7, 0x05, 0xb7, 0x8d, 0x13, 0x68, +0x0c, 0x0a, 0x8d, 0x3d, 0x67, 0x9a, 0x72, 0x86, +0x6f, 0xc9, 0xd4, 0xd2, 0x9a, 0x39, 0xc3, 0xf1, +0xbd, 0xb0, 0x35, 0xc7, 0x97, 0xab, 0xf8, 0xb5, +0xd8, 0xeb, 0xe4, 0xc7, 0xa1, 0x69, 0x15, 0x24, +0x73, 0xc1, 0x35, 0x3b, 0x61, 0x58, 0x62, 0x1a, +0xdc, 0x7d, 0xe6, 0x9c, 0xc0, 0x72, 0x95, 0xab, +0x74, 0xc4, 0xa2, 0x85, 0x2d, 0x6f, 0xf5, 0xd2, +0x08, 0x1d, 0xe7, 0x9e, 0xf9, 0x86, 0xc4, 0x7f, +0x4b, 0x9b, 0xa3, 0xa6, 0x26, 0xe6, 0xc4, 0x46, +0x53, 0x4b, 0xf2, 0x34, 0xf4, 0xde, 0x72, 0x98, +0xa3, 0xf4, 0x3c, 0x9d, 0x54, 0xfb, 0x6b, 0x78, +0xf2, 0xbc, 0xbc, 0xfd, 0x92, 0x78, 0x01, 0xa8, +0x10, 0x63, 0x0d, 0x5f, 0xde, 0x5e, 0xb2, 0x45, +0x4a, 0x7f, 0x01, 0xcb, 0xce, 0xaf, 0x11, 0x50, +0x8b, 0x21, 0x92, 0xc4, 0x80, 0x9b, 0x05, 0x2c, +0x3b, 0x39, 0xd7, 0x9c, 0x68, 0x0c, 0x93, 0x65, +0xcf, 0x96, 0x7d, 0x2c, 0x19, 0x38, 0xd9, 0xff, +0x12, 0x4f, 0x8b, 0xc9, 0x90, 0xda, 0x0b, 0x2d, +0x0f, 0x97, 0xca, 0x65, 0xdf, 0x70, 0xdb, 0x3a, +0xd7, 0xe6, 0x50, 0xfe, 0xfd, 0xfd, 0x7d, 0x74, +0xd7, 0x37, 0x70, 0xf8, 0xf8, 0x08, 0xc3, 0xf3, +0x53, 0x74, 0x96, 0x57, 0xb1, 0xb7, 0x73, 0xdd, +0xa5, 0x25, 0xdb, 0x6b, 0x92, 0x24, 0xce, 0x23, +0xba, 0xdb, 0xed, 0xba, 0xdb, 0xc8, 0x56, 0x57, +0x57, 0x9d, 0xb4, 0x1e, 0x86, 0xa1, 0x53, 0x01, +0x73, 0xdb, 0x32, 0x11, 0xbf, 0xad, 0xad, 0x2d, +0x47, 0xbc, 0x68, 0xcc, 0x35, 0xed, 0x91, 0x36, +0x17, 0x35, 0x06, 0x4e, 0x73, 0xa0, 0x93, 0xe5, +0x70, 0x0d, 0x92, 0xec, 0x1b, 0xba, 0xfb, 0x9c, +0x54, 0xd4, 0x51, 0x14, 0x39, 0xa6, 0x84, 0x33, +0x9b, 0xda, 0x11, 0xc8, 0xe5, 0xe5, 0x65, 0xa7, +0x86, 0x27, 0xe9, 0x98, 0xe6, 0x3e, 0x11, 0xe2, +0x07, 0x0f, 0x1e, 0x94, 0xea, 0xe2, 0xa7, 0x01, +0x88, 0x90, 0x9f, 0x9d, 0x9d, 0x61, 0x75, 0x75, +0xd5, 0x31, 0x3b, 0x44, 0xd8, 0xe9, 0x78, 0x19, +0x11, 0xf9, 0xe1, 0x70, 0x88, 0x6e, 0xb7, 0x8b, +0xc9, 0x64, 0xe2, 0xb4, 0x06, 0x00, 0x90, 0x86, +0x31, 0xf2, 0x20, 0xc4, 0xd2, 0xb5, 0xeb, 0xb8, +0x7e, 0xe3, 0x26, 0xce, 0x36, 0x6f, 0xa1, 0x7f, +0xe3, 0x2e, 0x1e, 0x6e, 0x3e, 0x8f, 0x0f, 0x37, +0x5e, 0xc0, 0x1f, 0xac, 0xbd, 0x84, 0x3f, 0x0e, +0x77, 0xf0, 0x5e, 0x6b, 0x15, 0x47, 0x79, 0x8c, +0x34, 0xcb, 0x30, 0x29, 0x0c, 0x29, 0x4f, 0xda, +0x74, 0xa5, 0x3a, 0x56, 0xaa, 0x64, 0xa5, 0x23, +0x13, 0x4f, 0xcb, 0x37, 0x5f, 0xca, 0x23, 0x25, +0x57, 0x4e, 0x98, 0xa4, 0x24, 0xca, 0x89, 0x94, +0xa6, 0x7a, 0x96, 0xe5, 0x4b, 0x86, 0x41, 0xc3, +0x5f, 0xc3, 0xb7, 0x44, 0xec, 0x26, 0x55, 0xa2, +0xcc, 0xd3, 0x48, 0xa9, 0x9a, 0x4b, 0x89, 0xb2, +0x5c, 0x59, 0x8e, 0x94, 0x86, 0x35, 0x1f, 0x82, +0x92, 0x84, 0xad, 0x10, 0x63, 0xed, 0x8e, 0x70, +0xad, 0x8d, 0x5c, 0x9d, 0xce, 0x35, 0x2b, 0x9a, +0x6d, 0x9c, 0xe3, 0xcd, 0x24, 0xdd, 0x52, 0x5f, +0xcb, 0x7e, 0xb7, 0x34, 0x2b, 0x1a, 0xf1, 0xe5, +0x38, 0xf2, 0x3b, 0xe5, 0x89, 0x71, 0xe1, 0xf3, +0x90, 0x98, 0x02, 0xcb, 0x27, 0x82, 0x7e, 0x53, +0x3a, 0xc6, 0x1c, 0x84, 0x7b, 0xdf, 0xfe, 0xd1, +0x9b, 0x9d, 0x27, 0xf7, 0x91, 0x24, 0x09, 0x2e, +0xc7, 0x13, 0x74, 0xe2, 0xb8, 0xc4, 0xf5, 0xf3, +0x85, 0x49, 0x44, 0x99, 0xbe, 0x73, 0xce, 0x5f, +0x5e, 0xe5, 0xc9, 0x09, 0xa4, 0x94, 0x92, 0xa5, +0xe4, 0x4e, 0xf5, 0x68, 0x47, 0xdf, 0x34, 0xdb, +0x3a, 0x27, 0x0e, 0xfc, 0xbb, 0x46, 0x80, 0xa5, +0x2a, 0x5e, 0xaa, 0x2e, 0x29, 0x3d, 0x67, 0x18, +0x24, 0x7e, 0x92, 0x79, 0xd1, 0x18, 0x0a, 0x5e, +0x8f, 0xc4, 0x41, 0xaa, 0xda, 0xb5, 0xe3, 0x54, +0xd4, 0x26, 0xcb, 0x34, 0xc0, 0x55, 0xed, 0x9a, +0x33, 0x95, 0xec, 0x07, 0xb9, 0xd9, 0x6b, 0xb8, +0xf0, 0x7a, 0x25, 0x91, 0xf6, 0x49, 0xdd, 0x4d, +0x80, 0x13, 0x0f, 0x4b, 0xea, 0xb6, 0xde, 0xf1, +0x3e, 0xe0, 0xfd, 0x25, 0xdb, 0x26, 0x9f, 0x89, +0xe8, 0x4a, 0x3c, 0xf9, 0x15, 0xab, 0x5c, 0xf3, +0xe1, 0x4c, 0x22, 0x6b, 0x9b, 0x78, 0xf8, 0xd2, +0xaf, 0xe3, 0x60, 0xf4, 0x78, 0x2a, 0xb5, 0xce, +0xce, 0x17, 0xf7, 0x7a, 0x3d, 0x67, 0xe7, 0xa5, +0x36, 0x51, 0x1d, 0x45, 0x51, 0xa0, 0xdb, 0xed, +0x22, 0x8e, 0xcb, 0xa1, 0x1a, 0x49, 0x72, 0x8f, +0xe3, 0xd8, 0xa9, 0xe0, 0xb9, 0x29, 0xaa, 0xd7, +0xeb, 0x61, 0x77, 0x77, 0xd7, 0x49, 0xa7, 0xa4, +0xa2, 0x96, 0x3e, 0x20, 0x72, 0x9e, 0x13, 0x13, +0x4d, 0x73, 0x58, 0x12, 0x75, 0x5a, 0x83, 0x9c, +0x09, 0xe3, 0x7e, 0x16, 0x9c, 0x41, 0x07, 0xe6, +0xf6, 0x72, 0x32, 0x3f, 0x10, 0x63, 0xc2, 0xfb, +0x89, 0x9b, 0x8b, 0xc8, 0x0e, 0x4e, 0x84, 0x35, +0x49, 0x12, 0xc7, 0x00, 0x00, 0x28, 0x79, 0x9b, +0xaf, 0xac, 0xac, 0x38, 0x95, 0x7b, 0xbf, 0xdf, +0x2f, 0xe1, 0xce, 0xcf, 0x7c, 0xf3, 0x6b, 0x57, +0xf7, 0xf6, 0xf6, 0x70, 0x78, 0x78, 0x88, 0xf3, +0xf3, 0x73, 0x77, 0xc5, 0xea, 0xd6, 0xd6, 0x96, +0x8b, 0x50, 0x77, 0xef, 0xde, 0x3d, 0xd7, 0xd6, +0x6e, 0xb7, 0x8b, 0x17, 0x5f, 0x7c, 0x11, 0x08, +0x63, 0xfc, 0x4f, 0x9d, 0xe7, 0xf1, 0xf0, 0xe6, +0xab, 0x78, 0x7f, 0xfb, 0x2e, 0x3e, 0xb9, 0xf5, +0x3a, 0xfe, 0x24, 0xd9, 0xc7, 0x1f, 0x05, 0xd7, +0xf1, 0xd3, 0x7c, 0x15, 0xef, 0x4f, 0x62, 0x7c, +0x5a, 0x74, 0x71, 0x1e, 0x25, 0x98, 0x8c, 0x27, +0x73, 0xc9, 0x95, 0xa4, 0x45, 0xfa, 0xb3, 0x1c, +0xbf, 0x2c, 0x9b, 0x29, 0xb7, 0x81, 0x96, 0x24, +0x59, 0x41, 0xec, 0x2a, 0x9e, 0xe1, 0x82, 0x21, +0x98, 0x76, 0x76, 0xf5, 0xbb, 0xb4, 0xb1, 0x96, +0x9c, 0xd3, 0x0c, 0x3b, 0xb1, 0x54, 0xbb, 0x9b, +0x0e, 0x57, 0x93, 0x72, 0x3a, 0x7e, 0x84, 0x0a, +0x98, 0x7f, 0xe3, 0xfd, 0x43, 0x38, 0x73, 0x62, +0x4f, 0x78, 0x51, 0x39, 0xa5, 0x36, 0x4d, 0xf4, +0xb6, 0x4a, 0xa7, 0x3a, 0x7a, 0x27, 0xfb, 0x49, +0x32, 0x09, 0x15, 0xc6, 0xc4, 0x28, 0x8b, 0xb7, +0x87, 0x4b, 0xc3, 0xb2, 0xaf, 0xb9, 0x86, 0x40, +0x7a, 0x91, 0xf3, 0x71, 0xae, 0x73, 0x54, 0x23, +0x4d, 0x42, 0x89, 0x39, 0xc8, 0xcb, 0x7d, 0x28, +0x89, 0x34, 0xb7, 0x7b, 0x4b, 0x73, 0x88, 0x94, +0xdc, 0x7d, 0x3e, 0x11, 0xf2, 0x08, 0x5e, 0x18, +0x4d, 0x25, 0xf3, 0x8d, 0xe1, 0x74, 0xd1, 0x8f, +0x26, 0x29, 0x3a, 0xb3, 0x6b, 0x01, 0x69, 0x43, +0xe0, 0xf6, 0x28, 0x49, 0x44, 0x34, 0x27, 0x2b, +0xf9, 0x5b, 0xda, 0x70, 0x35, 0x42, 0x25, 0xed, +0xbb, 0x72, 0x03, 0x92, 0xc4, 0x86, 0xd2, 0xd2, +0x46, 0x23, 0xeb, 0xe5, 0xcf, 0x9c, 0xa1, 0xb0, +0xce, 0xaa, 0x4b, 0x15, 0x3b, 0xb5, 0x99, 0x97, +0x2f, 0x6d, 0x94, 0x7c, 0xb3, 0xe3, 0x78, 0xcb, +0x7a, 0xa5, 0xa3, 0x95, 0x26, 0x25, 0x49, 0x6f, +0x76, 0xce, 0x74, 0xc8, 0x77, 0x1c, 0x37, 0x79, +0xed, 0xa9, 0x46, 0xc4, 0xe9, 0x9b, 0xb4, 0x2b, +0x4a, 0xe6, 0x83, 0xb7, 0x51, 0xf6, 0xdb, 0x55, +0x88, 0xb8, 0x64, 0xc0, 0x34, 0x22, 0x9c, 0xa6, +0xa9, 0x53, 0x8b, 0x6b, 0xc7, 0xed, 0x2c, 0x66, +0x44, 0xaa, 0xa7, 0x65, 0x3f, 0x6a, 0x44, 0x91, +0x13, 0x28, 0x9e, 0x86, 0xec, 0xbe, 0xc3, 0xe1, +0x10, 0x9d, 0x28, 0xc4, 0xef, 0x5d, 0xfb, 0x3a, +0xd6, 0xae, 0x6d, 0xe2, 0xc6, 0xe4, 0xc4, 0x11, +0x9b, 0xa0, 0xdd, 0xc1, 0xca, 0x52, 0xb7, 0x62, +0x1e, 0x22, 0xe7, 0x2f, 0x4e, 0xc8, 0xbb, 0xdd, +0xae, 0xc3, 0x65, 0x6d, 0x6d, 0x0d, 0x51, 0x14, +0xa1, 0x1d, 0xc7, 0xc8, 0xb2, 0xac, 0xe4, 0x25, +0xbe, 0xb9, 0xb9, 0x89, 0xd5, 0xd5, 0x55, 0x6c, +0x6d, 0x6d, 0xe1, 0xc5, 0x17, 0x5f, 0x74, 0xe7, +0xb4, 0x25, 0xe1, 0xd5, 0xd6, 0x13, 0x3f, 0xf9, +0xc0, 0xc7, 0x46, 0x6a, 0xa8, 0xa4, 0xb9, 0x88, +0x3b, 0xcf, 0x91, 0x1a, 0x9d, 0xce, 0xa8, 0xf3, +0xf9, 0x4c, 0x47, 0xb7, 0xf8, 0xdc, 0xdb, 0xdc, +0xdc, 0x74, 0xd7, 0x83, 0xd2, 0x51, 0x34, 0xae, +0x71, 0x23, 0xa6, 0x81, 0x4e, 0xb2, 0xd0, 0xb1, +0xbd, 0x34, 0x4d, 0x9d, 0xc3, 0x19, 0xf5, 0x33, +0xbf, 0xec, 0xa8, 0xd7, 0xeb, 0xb9, 0xba, 0x28, +0xb8, 0xcc, 0xd1, 0xd1, 0x11, 0x76, 0x77, 0x77, +0xf1, 0xe9, 0xa7, 0x9f, 0x62, 0x75, 0x75, 0xd5, +0x5d, 0xe1, 0x4a, 0x67, 0xd7, 0x81, 0xa9, 0x53, +0xdc, 0x8d, 0xfd, 0x5b, 0x53, 0x26, 0xa9, 0xd3, +0x46, 0x90, 0x74, 0xf1, 0x6f, 0x3a, 0x7b, 0xf8, +0xac, 0x68, 0xe3, 0x38, 0x8f, 0x70, 0x3a, 0xce, +0x30, 0xc9, 0x8b, 0xb9, 0xa4, 0x06, 0x00, 0xd9, +0x6c, 0x8e, 0x48, 0x49, 0x5c, 0x93, 0x24, 0x01, +0xa8, 0xd2, 0x26, 0xc0, 0x08, 0xa6, 0x41, 0xb0, +0xa5, 0x94, 0xad, 0x11, 0x61, 0xcb, 0xc6, 0x5c, +0x22, 0x7c, 0x9e, 0xfa, 0x35, 0x1b, 0x32, 0xe5, +0xd1, 0xda, 0x62, 0x05, 0xa6, 0x91, 0x47, 0xa8, +0xe8, 0x9d, 0xd5, 0x3f, 0xd2, 0xee, 0xcd, 0xd3, +0x70, 0x7c, 0x7c, 0xde, 0xf2, 0x5a, 0x1f, 0x49, +0x8f, 0x7b, 0x9e, 0xc6, 0x22, 0xa6, 0x94, 0x8f, +0xd4, 0xde, 0x9a, 0x2d, 0x9a, 0xb7, 0xc7, 0xd5, +0x33, 0xf1, 0x33, 0x38, 0x15, 0xbc, 0x04, 0x53, +0xa2, 0xd6, 0x23, 0xa4, 0x75, 0x4d, 0xc5, 0x5f, +0x92, 0xf4, 0x51, 0x96, 0xce, 0x35, 0x87, 0x40, +0xe9, 0x3c, 0xa8, 0xd9, 0xd2, 0x79, 0xfb, 0x66, +0x65, 0xb8, 0xfb, 0xcc, 0x87, 0xc3, 0x21, 0xc2, +0x56, 0xab, 0x42, 0x24, 0xf9, 0x19, 0x67, 0xda, +0x0c, 0x39, 0xd0, 0x06, 0xc7, 0xed, 0xbe, 0x52, +0x92, 0xb6, 0x9c, 0xcb, 0xf8, 0xa6, 0x2b, 0x37, +0x6f, 0xe9, 0x61, 0x6e, 0x11, 0x14, 0xa9, 0x86, +0x94, 0x9b, 0xbb, 0x54, 0xbf, 0x5b, 0x52, 0xa1, +0xa6, 0x82, 0x6c, 0x2a, 0x5d, 0x72, 0xc7, 0x1d, +0xde, 0x77, 0x9c, 0xc0, 0x93, 0x2a, 0x5d, 0xb6, +0x51, 0x4a, 0x40, 0x52, 0x2d, 0x2d, 0xf1, 0x90, +0x26, 0x0b, 0x4e, 0xe4, 0x25, 0xfe, 0x9a, 0xa9, +0x42, 0x33, 0x8b, 0x48, 0xcd, 0x01, 0xaf, 0x97, +0xf2, 0x75, 0xba, 0x4b, 0xce, 0x63, 0xdd, 0x07, +0x96, 0xbd, 0x5e, 0x53, 0x07, 0xcb, 0xf4, 0x9a, +0x06, 0xc6, 0x2a, 0x57, 0xd3, 0x92, 0x70, 0x4d, +0x91, 0xd4, 0x0a, 0x71, 0xfb, 0x39, 0x3f, 0x5e, +0x08, 0x00, 0xe7, 0xa7, 0x27, 0xf8, 0x78, 0xeb, +0x2b, 0xb8, 0x97, 0x5c, 0xc7, 0x37, 0xae, 0xaf, +0xa2, 0x7d, 0x71, 0x8c, 0xa3, 0xa3, 0x23, 0xe4, +0x33, 0x82, 0xcd, 0x99, 0x12, 0x3e, 0xc7, 0x39, +0x31, 0xe7, 0x52, 0x23, 0x00, 0xf7, 0x8d, 0x9b, +0x5c, 0xb8, 0xe6, 0x83, 0x88, 0xfb, 0xd6, 0xd6, +0x16, 0x0e, 0x0e, 0x0e, 0xb0, 0xb5, 0xb5, 0x85, +0xfe, 0xec, 0x9e, 0x72, 0xde, 0xff, 0x72, 0x7c, +0xe4, 0x7c, 0x95, 0xda, 0x18, 0xde, 0x76, 0x6e, +0x87, 0xa6, 0x75, 0x4c, 0xe7, 0xcb, 0xe9, 0xfc, +0xf8, 0xe6, 0xe6, 0x26, 0xe2, 0x38, 0xc6, 0xc5, +0xc5, 0x85, 0x3b, 0xba, 0x45, 0xc7, 0xd2, 0x46, +0xa3, 0x11, 0x36, 0x36, 0x36, 0x70, 0x74, 0x74, +0xe4, 0xb4, 0x14, 0xd2, 0x63, 0x9c, 0x08, 0x39, +0xbf, 0xf0, 0x85, 0x4c, 0x0d, 0x5c, 0x2a, 0x5f, +0x59, 0x59, 0x29, 0x05, 0xa0, 0xe1, 0x0c, 0x6e, +0x18, 0x86, 0x78, 0xf2, 0xe4, 0x89, 0xbb, 0x8f, +0x9d, 0x98, 0x9d, 0xf3, 0xf3, 0x73, 0x47, 0xd8, +0x49, 0x53, 0xb2, 0xb2, 0xb2, 0x82, 0x8f, 0x3e, +0xfc, 0xd0, 0xb5, 0xfd, 0x46, 0x30, 0xc1, 0xdd, +0xd5, 0x10, 0x3f, 0x1d, 0x77, 0x31, 0x18, 0x8f, +0xab, 0x36, 0x45, 0xda, 0x88, 0xa5, 0xe4, 0x58, +0x92, 0xa8, 0x26, 0x55, 0x87, 0x35, 0x22, 0x9c, +0xe2, 0xce, 0x68, 0x97, 0x9e, 0x6f, 0xc6, 0xda, +0x39, 0x6a, 0x6e, 0x5f, 0x97, 0x76, 0x53, 0xfa, +0xaf, 0x11, 0x32, 0xfa, 0x66, 0x11, 0x2f, 0x8e, +0x8b, 0x66, 0x87, 0x2e, 0x8a, 0x2a, 0x21, 0xd0, +0xf2, 0x6b, 0xaa, 0x61, 0x49, 0xd4, 0x78, 0x7f, +0xc9, 0xbe, 0x90, 0xde, 0xfc, 0x1a, 0x31, 0xd4, +0xbc, 0xe5, 0xf9, 0x37, 0x17, 0x10, 0x46, 0xa8, +0xdd, 0x25, 0x11, 0x93, 0xed, 0xe0, 0xf9, 0xa9, +0x6f, 0xb5, 0xbb, 0xcd, 0x5d, 0x3f, 0xb4, 0xca, +0xe7, 0xef, 0x81, 0xea, 0x59, 0x6e, 0xd9, 0x16, +0x7a, 0xcf, 0xc7, 0x9a, 0x33, 0x3e, 0xd4, 0x16, +0x79, 0xe4, 0x4d, 0xf6, 0x61, 0x85, 0x11, 0x84, +0xfe, 0x9f, 0xf7, 0x27, 0xaf, 0xc7, 0x62, 0x78, +0x4a, 0xed, 0x03, 0x90, 0x67, 0x08, 0xaf, 0x7f, +0xe3, 0xd7, 0xdf, 0xdc, 0x18, 0x3c, 0xad, 0xd8, +0x44, 0xa5, 0x9a, 0x9c, 0x4b, 0x51, 0xf4, 0x4d, +0x4a, 0x78, 0x9a, 0x4d, 0x57, 0x4a, 0xe7, 0x96, +0x13, 0x93, 0x66, 0x93, 0xd5, 0x54, 0xe2, 0x4d, +0xd5, 0xbf, 0xda, 0xf1, 0x2e, 0xfe, 0xcc, 0xcb, +0xb2, 0x1c, 0xc3, 0xf8, 0x86, 0x63, 0x11, 0x3f, +0xed, 0x2c, 0x39, 0xc7, 0x49, 0x1e, 0x23, 0x92, +0x7d, 0xc5, 0x09, 0x90, 0x74, 0x06, 0xd4, 0x8e, +0xd4, 0xf1, 0x36, 0x58, 0x9a, 0x0f, 0x4e, 0x34, +0xa4, 0x14, 0xa7, 0xa5, 0xd3, 0x9e, 0xf9, 0xbb, +0x34, 0x4d, 0x11, 0xce, 0xae, 0x9e, 0xd4, 0x98, +0x21, 0xde, 0xe7, 0xbe, 0xef, 0x12, 0x7f, 0x99, +0x8f, 0x33, 0x10, 0xda, 0x5c, 0xb1, 0x3c, 0xe3, +0x35, 0xb5, 0x3c, 0xb5, 0x9f, 0x07, 0x8c, 0x91, +0x52, 0x3b, 0x7d, 0x7b, 0x7a, 0x7a, 0x86, 0x17, +0x0e, 0x6e, 0xe3, 0xad, 0xf8, 0x3a, 0xde, 0x29, +0x56, 0xf0, 0xfc, 0xe6, 0x2a, 0xae, 0xe7, 0x03, +0x7c, 0xf6, 0xf9, 0x63, 0x44, 0x41, 0xcb, 0x95, +0x43, 0x12, 0x36, 0xe1, 0xc8, 0x89, 0xf9, 0x60, +0x30, 0x40, 0x1c, 0xc7, 0x25, 0x89, 0x9d, 0x3f, +0xd3, 0x6f, 0x39, 0xe7, 0x93, 0x24, 0x71, 0xc4, +0xeb, 0xee, 0xdd, 0xbb, 0xce, 0x29, 0x8f, 0x6b, +0x5d, 0xb4, 0xb1, 0x91, 0x7d, 0xc9, 0x83, 0xc3, +0x68, 0x6b, 0x91, 0x07, 0x8e, 0x01, 0xe6, 0x12, +0x3a, 0x31, 0x1b, 0x17, 0x17, 0x17, 0x68, 0xb5, +0x5a, 0x0e, 0x37, 0xf2, 0x70, 0x27, 0x2d, 0xc5, +0xe6, 0xe6, 0x66, 0x49, 0xfb, 0x20, 0xdb, 0x72, +0x74, 0x34, 0x75, 0xa2, 0xa5, 0x30, 0xb2, 0x0f, +0x1e, 0x3c, 0x28, 0xc5, 0x9e, 0xd8, 0xda, 0xda, +0xc2, 0x83, 0x07, 0x0f, 0xdc, 0xfa, 0x20, 0x62, +0x4d, 0x75, 0xad, 0xac, 0xac, 0xe0, 0xe2, 0xe2, +0xa2, 0xe4, 0x39, 0x4f, 0x7d, 0xd0, 0xed, 0x76, +0xdd, 0xfa, 0x20, 0xb3, 0x04, 0x8d, 0xf9, 0xd6, +0xd6, 0x16, 0x76, 0x56, 0xba, 0x78, 0x71, 0xad, +0x83, 0x77, 0x06, 0x01, 0x4e, 0x33, 0xe8, 0xb6, +0x67, 0xb9, 0x59, 0xf3, 0x4d, 0xb9, 0xc9, 0xb9, +0xe5, 0xba, 0xcd, 0x58, 0xaa, 0xb5, 0xb9, 0xca, +0x56, 0x96, 0xc1, 0xff, 0x93, 0x5a, 0x56, 0x6e, +0xfa, 0xd2, 0xa1, 0x4e, 0xda, 0x8b, 0xe9, 0x9d, +0x76, 0x44, 0x4b, 0xb6, 0x45, 0xcb, 0xaf, 0x39, +0xc5, 0x49, 0xdc, 0x64, 0x3e, 0x4d, 0xfa, 0xaf, +0xeb, 0x1f, 0x5e, 0x4e, 0x29, 0x22, 0x5b, 0x8d, +0x8d, 0x59, 0xb6, 0x53, 0xe2, 0x67, 0x8d, 0x05, +0x2f, 0x93, 0x33, 0x05, 0xda, 0xf1, 0x33, 0x2e, +0xb9, 0x53, 0xb0, 0x18, 0xe9, 0x0b, 0xd1, 0xa4, +0x7c, 0xae, 0x25, 0xa9, 0xeb, 0x63, 0xf9, 0x5e, +0x96, 0x57, 0xe9, 0x4f, 0xe5, 0x1c, 0xbb, 0xc4, +0x6d, 0x86, 0x7f, 0xb8, 0xff, 0x9d, 0xdf, 0x7c, +0x73, 0x27, 0x3b, 0xaf, 0xa8, 0xf3, 0xe4, 0x71, +0x26, 0x6e, 0x3b, 0xe6, 0x8e, 0x2e, 0x92, 0x70, +0x50, 0x7e, 0x8d, 0x60, 0x49, 0xc9, 0xdd, 0x52, +0xaf, 0xf3, 0x4d, 0x82, 0x97, 0x47, 0xb8, 0x58, +0xf6, 0x45, 0xa9, 0xd6, 0x96, 0xf8, 0x69, 0x9b, +0x10, 0x95, 0x2f, 0x09, 0x8c, 0x15, 0xf0, 0x86, +0x33, 0x25, 0x92, 0x40, 0xf2, 0xba, 0x34, 0x35, +0xb0, 0x24, 0xfc, 0xdc, 0xf7, 0x80, 0x7e, 0x73, +0xa2, 0xc6, 0xd5, 0xfa, 0xdc, 0x4e, 0x2a, 0x19, +0x23, 0xcd, 0xe6, 0x4d, 0x7d, 0x23, 0x25, 0x38, +0x9e, 0xdf, 0x92, 0x90, 0x79, 0xff, 0x70, 0x95, +0xab, 0x45, 0xa8, 0xad, 0x00, 0x33, 0x16, 0x58, +0x6a, 0x75, 0x29, 0x99, 0x6b, 0x12, 0xbd, 0x24, +0xf4, 0x1c, 0x47, 0x39, 0x5f, 0xe9, 0xb7, 0x0c, +0xc2, 0x23, 0xd5, 0xf1, 0x83, 0x8b, 0x0b, 0xac, +0x6c, 0xef, 0xe0, 0xfe, 0xca, 0x1e, 0x1e, 0xe5, +0x31, 0xde, 0xc6, 0x3a, 0xc2, 0x6b, 0xd7, 0xb1, +0x1f, 0x8e, 0xf0, 0xe4, 0xfe, 0x27, 0x8e, 0x50, +0x77, 0xbb, 0x5d, 0x2c, 0x2f, 0x4f, 0x2f, 0xe7, +0xb8, 0x76, 0xed, 0x1a, 0xd2, 0x34, 0xc5, 0x60, +0x30, 0x70, 0x2a, 0xea, 0xa2, 0x28, 0x1c, 0xe1, +0xa6, 0xf7, 0x1c, 0x38, 0x51, 0x27, 0x7b, 0x3b, +0x39, 0xce, 0x75, 0x3a, 0x1d, 0x47, 0xd0, 0x5f, +0x7e, 0xf9, 0x65, 0x17, 0xf2, 0x94, 0x88, 0xa4, +0x0f, 0x78, 0xbb, 0xb9, 0x86, 0x8c, 0x8f, 0x8f, +0xf4, 0xae, 0xcf, 0xb2, 0xe9, 0xe5, 0x24, 0x7b, +0x7b, 0x7b, 0x25, 0xdb, 0x37, 0x00, 0x17, 0x70, +0x26, 0x0c, 0x43, 0xf7, 0xad, 0xd5, 0x6a, 0xa1, +0x28, 0x0a, 0x17, 0x7c, 0x85, 0x9c, 0xe4, 0xf8, +0x5c, 0x27, 0x29, 0x9c, 0xd4, 0xeb, 0xf4, 0x8d, +0x9f, 0x16, 0x20, 0xa6, 0x88, 0xfa, 0x8c, 0xec, +0xe6, 0xd4, 0x56, 0x3a, 0xaf, 0x4f, 0x5e, 0xff, +0xab, 0xab, 0xab, 0xce, 0x24, 0x42, 0x4e, 0x83, +0x34, 0x8e, 0x5b, 0x5b, 0x5b, 0x88, 0xa2, 0x08, +0x4f, 0x1f, 0x7f, 0x8e, 0x95, 0xe1, 0x09, 0xbe, +0xde, 0x9e, 0xe0, 0xb8, 0xd5, 0xc1, 0x49, 0x11, +0x63, 0x52, 0xa0, 0x4a, 0x3c, 0x34, 0x62, 0xa8, +0x9d, 0x0d, 0xd6, 0xa4, 0x62, 0x6d, 0x33, 0x26, +0x07, 0x26, 0xcd, 0x3b, 0x5a, 0xb3, 0x67, 0x6b, +0x04, 0x88, 0x13, 0xde, 0x6c, 0x32, 0x7f, 0x6f, +0x6d, 0xda, 0x1a, 0x33, 0x22, 0xa5, 0x42, 0x02, +0xcb, 0x69, 0xcc, 0x22, 0xde, 0x9a, 0x4d, 0x57, +0x3b, 0xd7, 0xae, 0x9d, 0x83, 0xb7, 0xfa, 0x87, +0x47, 0x54, 0xd3, 0xd2, 0xf0, 0xe8, 0x69, 0x5a, +0x99, 0x16, 0xee, 0x1a, 0x31, 0xe4, 0x75, 0xba, +0x3e, 0x10, 0x66, 0x8d, 0xd2, 0x37, 0xa5, 0x7f, +0xb8, 0xb6, 0x80, 0x40, 0x2b, 0x9f, 0x13, 0x7d, +0xe9, 0xe4, 0xa8, 0x8d, 0xb5, 0xd4, 0x8e, 0x68, +0x0c, 0x0e, 0x07, 0xae, 0x0d, 0xa0, 0xfc, 0xea, +0x39, 0xf9, 0x79, 0x1d, 0xce, 0x66, 0x4e, 0x9b, +0x1e, 0x8f, 0x6a, 0xc6, 0x37, 0x0b, 0x22, 0x28, +0x44, 0x74, 0x78, 0x58, 0x57, 0x49, 0xd8, 0xa4, +0x94, 0x24, 0x25, 0x26, 0x6d, 0x93, 0xa6, 0x05, +0x2a, 0x89, 0x82, 0x76, 0x26, 0x9d, 0x80, 0xbf, +0xd7, 0xbc, 0xd9, 0x25, 0x01, 0xd6, 0xa4, 0x72, +0x4b, 0xfd, 0x2f, 0x99, 0x11, 0x49, 0x7c, 0xb5, +0xf6, 0xd2, 0xa6, 0x43, 0xf9, 0x49, 0x92, 0x20, +0x75, 0x2e, 0xa5, 0xe3, 0x27, 0x02, 0xa4, 0x33, +0x9c, 0x34, 0x5b, 0x58, 0x9e, 0xed, 0x92, 0xe0, +0x73, 0x82, 0x28, 0x35, 0x01, 0x1c, 0x24, 0xa1, +0xd3, 0x4c, 0x0c, 0x5a, 0xff, 0xfa, 0x40, 0x63, +0xb0, 0xa4, 0x0a, 0x9c, 0xf7, 0xbb, 0x1c, 0x2f, +0x8d, 0x19, 0xb2, 0xf2, 0x4b, 0x46, 0x4a, 0xb6, +0x43, 0x96, 0x25, 0x4d, 0x3c, 0xd4, 0xb7, 0x1c, +0xd7, 0xb3, 0xf3, 0x0b, 0xac, 0x27, 0x6d, 0x44, +0x07, 0x2f, 0xe3, 0xd3, 0x34, 0xc2, 0xa4, 0x00, +0x3e, 0x9e, 0x04, 0xe8, 0xed, 0xdc, 0xc0, 0x9d, +0x70, 0x88, 0x07, 0x1f, 0xbe, 0xef, 0x24, 0xc6, +0xd5, 0xd5, 0x55, 0xac, 0xae, 0xae, 0xba, 0x7a, +0x88, 0x38, 0x93, 0x0a, 0x9f, 0x4b, 0xe0, 0xc4, +0x04, 0x00, 0x55, 0x9b, 0x3a, 0x57, 0xcb, 0x9f, +0x9d, 0x9d, 0x95, 0xc2, 0xd6, 0x6e, 0x6f, 0x6f, +0xe3, 0xe6, 0xcd, 0x9b, 0x78, 0xf5, 0xd5, 0x57, +0x71, 0xf7, 0xee, 0x5d, 0x77, 0x4e, 0x5e, 0x1b, +0x2b, 0x8d, 0x99, 0xd5, 0x8e, 0x13, 0xd2, 0x7c, +0x93, 0xcc, 0xa4, 0x3c, 0x8a, 0x06, 0xa0, 0xa4, +0x92, 0x07, 0xa6, 0x97, 0xb6, 0x90, 0xe3, 0x1f, +0xa9, 0xca, 0xc9, 0x93, 0x9d, 0xc2, 0x1a, 0x73, +0x26, 0xa9, 0xd5, 0x6a, 0x61, 0x73, 0x73, 0x13, +0x2f, 0xbf, 0xfc, 0x32, 0x26, 0x93, 0x09, 0xb6, +0xb7, 0xb7, 0xdd, 0xf9, 0x72, 0x22, 0xe8, 0x64, +0xaf, 0x27, 0x0f, 0x77, 0x7e, 0x56, 0x3d, 0x4d, +0xe7, 0xc7, 0xd6, 0x8a, 0xa2, 0x70, 0xd7, 0xa6, +0xd2, 0x19, 0x77, 0x1a, 0xc3, 0xe1, 0x70, 0xe8, +0x9c, 0xe6, 0xc2, 0x56, 0x0b, 0x2f, 0x5e, 0xdf, +0xc0, 0x6b, 0x4b, 0x19, 0x7e, 0x2d, 0xba, 0xc0, +0x8b, 0x9d, 0x1c, 0xfd, 0xb0, 0x8b, 0xe3, 0x14, +0x3a, 0x51, 0x95, 0x52, 0x9b, 0x45, 0xc8, 0xf9, +0x11, 0x30, 0xcb, 0x81, 0x49, 0x7a, 0x47, 0x4b, +0x55, 0x2b, 0xdf, 0xb8, 0xb5, 0xb0, 0xa3, 0xd2, +0xbb, 0x9d, 0xbf, 0xd3, 0xea, 0xd6, 0xca, 0xe1, +0x6a, 0x7b, 0x69, 0x5b, 0xf5, 0xe5, 0xf7, 0x49, +0x9e, 0xdc, 0xfb, 0x5e, 0x7a, 0xb9, 0x4b, 0x49, +0xda, 0xea, 0x1f, 0x4d, 0x12, 0x95, 0xff, 0xa5, +0x76, 0xc1, 0xc7, 0x2c, 0xc9, 0x7a, 0x64, 0x79, +0x5a, 0xbf, 0xf0, 0xfe, 0x95, 0xf6, 0x7b, 0x0d, +0x2f, 0x1f, 0x83, 0x23, 0xfb, 0x4d, 0x9e, 0x0a, +0xd0, 0x34, 0x42, 0x5a, 0x3e, 0xa9, 0xed, 0xd0, +0x98, 0x13, 0x79, 0x4c, 0x4f, 0x3b, 0x27, 0xcf, +0xf2, 0x85, 0xdb, 0xaf, 0x7d, 0xf7, 0xcd, 0xf8, +0xe8, 0xd3, 0x12, 0x11, 0xd7, 0x24, 0x3b, 0xed, +0x6c, 0xb8, 0x26, 0xe9, 0xc9, 0x8d, 0x53, 0xb3, +0xf3, 0xc9, 0xcd, 0xc8, 0x92, 0x74, 0xf9, 0xa6, +0xcc, 0x81, 0x47, 0x89, 0x92, 0x12, 0x99, 0x24, +0x7c, 0xf2, 0x58, 0x9b, 0x0c, 0x62, 0xa3, 0x11, +0x1b, 0x29, 0xad, 0x4a, 0x09, 0xc4, 0x77, 0x3c, +0x8e, 0xf0, 0x22, 0x42, 0x2d, 0xed, 0xad, 0x92, +0x78, 0xcb, 0x23, 0x6e, 0xb4, 0xc9, 0xca, 0xf6, +0xf0, 0x7e, 0xe6, 0x7d, 0xc3, 0xdb, 0xa2, 0xf5, +0x97, 0x34, 0x51, 0xc8, 0xf1, 0x92, 0x6d, 0xe6, +0xd0, 0x44, 0xd2, 0xd6, 0xce, 0xa8, 0xcb, 0xf2, +0xc3, 0xb8, 0xed, 0xec, 0xed, 0xd2, 0x2e, 0x6f, +0xa9, 0xfe, 0x7d, 0x4c, 0x86, 0x46, 0xfc, 0x35, +0x9b, 0xb1, 0xd6, 0x87, 0x84, 0x33, 0xe1, 0x30, +0xce, 0x0b, 0x8c, 0x07, 0x97, 0xd8, 0x58, 0x59, +0x42, 0xb6, 0x7b, 0x07, 0xef, 0x63, 0x3a, 0x7e, +0x41, 0x91, 0xe3, 0xdd, 0x71, 0x1b, 0xf9, 0xda, +0x16, 0x76, 0x56, 0xbb, 0x48, 0x9f, 0x7e, 0x8e, +0xa3, 0x47, 0x87, 0xae, 0xae, 0x30, 0x0c, 0x1d, +0x51, 0x26, 0x35, 0xf5, 0x68, 0x34, 0x72, 0x9e, +0xec, 0xbc, 0x0d, 0x9c, 0x70, 0xf3, 0x6f, 0xdd, +0x6e, 0x17, 0x4f, 0x9f, 0x3e, 0x75, 0xc4, 0x91, +0x08, 0x3a, 0x97, 0xd8, 0xd7, 0xd7, 0xd7, 0xf1, +0xd2, 0x4b, 0x2f, 0xe1, 0xdb, 0xdf, 0xfe, 0x36, +0x0e, 0x0e, 0x0e, 0x5c, 0x3a, 0xc9, 0x44, 0x4a, +0xd0, 0x34, 0x31, 0xda, 0xd8, 0xb5, 0x5a, 0x2d, +0xf3, 0x9e, 0x02, 0x7e, 0x14, 0x55, 0x46, 0x86, +0x23, 0x87, 0xc2, 0xe5, 0xe5, 0x65, 0xac, 0xac, +0xac, 0xe0, 0xe5, 0x97, 0x5f, 0xc6, 0x2b, 0xaf, +0xbc, 0x82, 0x1f, 0xfe, 0xf0, 0x87, 0xf8, 0xfe, +0xf7, 0xbf, 0x8f, 0x5f, 0xff, 0xf5, 0x5f, 0xc7, +0xc1, 0xc1, 0x01, 0xee, 0xde, 0xbd, 0x8b, 0x57, +0x5f, 0x7d, 0x15, 0x2b, 0x2b, 0x2b, 0xce, 0x23, +0x9e, 0x98, 0x04, 0xbe, 0x96, 0xce, 0xcf, 0xcf, +0x71, 0xf3, 0xe6, 0x4d, 0x74, 0xbb, 0x5d, 0x3c, +0x79, 0xf2, 0xa4, 0x24, 0xe9, 0xaf, 0xae, 0xae, +0xe2, 0xbd, 0xf7, 0xde, 0x73, 0x0c, 0x11, 0xb5, +0x85, 0x6e, 0x79, 0xe3, 0xcc, 0xd9, 0xe0, 0xf8, +0x08, 0x3b, 0x31, 0xf0, 0xcd, 0xad, 0x2e, 0xbe, +0xbb, 0x9c, 0xe2, 0x78, 0x38, 0xc1, 0xe7, 0x45, +0xdb, 0x45, 0x1f, 0x34, 0x55, 0xc9, 0x9a, 0xbd, +0x98, 0xab, 0x78, 0x29, 0x1a, 0x57, 0x18, 0x21, +0xca, 0x27, 0xc8, 0x5b, 0x73, 0xaf, 0xe7, 0x28, +0x9f, 0x20, 0x4f, 0xd3, 0xcf, 0x8a, 0x5a, 0x22, +0x00, 0x00, 0x80, 0x00, 0x49, 0x44, 0x41, 0x54, +0xb9, 0x84, 0x66, 0x49, 0x63, 0xd2, 0xde, 0x4b, +0x20, 0x37, 0x73, 0xf9, 0x4e, 0xe2, 0x1c, 0x77, +0xca, 0x65, 0x4a, 0x3b, 0xb3, 0xf0, 0x0e, 0x8f, +0x5a, 0xc5, 0x1c, 0x5f, 0x99, 0x5f, 0xaa, 0xb2, +0xa9, 0x8f, 0xf8, 0x7f, 0xae, 0xaa, 0x97, 0xbe, +0x07, 0xb2, 0x7f, 0xea, 0xca, 0x22, 0xa0, 0x7a, +0x79, 0xb9, 0x92, 0xb0, 0x4a, 0x66, 0x89, 0x8f, +0x89, 0xec, 0x2f, 0x8b, 0x68, 0x72, 0xe9, 0x96, +0xca, 0x95, 0x1e, 0xf6, 0xb3, 0x74, 0x51, 0xab, +0x98, 0x8e, 0xa3, 0xbb, 0x9a, 0x34, 0xab, 0x8e, +0xa5, 0x56, 0x77, 0x36, 0x99, 0xe6, 0x95, 0x0c, +0x00, 0x1f, 0x67, 0xcd, 0xa6, 0xcf, 0x71, 0x33, +0x08, 0x7f, 0x84, 0xac, 0x34, 0xd7, 0x2a, 0x1a, +0x06, 0x56, 0x6e, 0xb8, 0xfd, 0xda, 0xf7, 0xde, +0x5c, 0xbf, 0x78, 0x52, 0x51, 0x3d, 0x4a, 0x35, +0xa5, 0x24, 0xe2, 0x9c, 0x40, 0x49, 0x49, 0x98, +0x40, 0x12, 0x3e, 0xb9, 0xa1, 0x4a, 0xa7, 0x2b, +0x4d, 0x05, 0xcf, 0xcb, 0xd2, 0x98, 0x07, 0xca, +0x27, 0xb5, 0x09, 0x04, 0x9a, 0x1d, 0x55, 0x0b, +0xae, 0x62, 0x79, 0xcc, 0x4b, 0xe9, 0x9b, 0xd2, +0x72, 0x67, 0x3b, 0x5e, 0x26, 0x97, 0xcc, 0x49, +0x7a, 0xe0, 0xc7, 0x8f, 0x38, 0x91, 0x97, 0xda, +0x03, 0xed, 0x18, 0x9c, 0xd5, 0x5f, 0x52, 0xb3, +0x61, 0x99, 0x21, 0x34, 0x55, 0xba, 0xec, 0x3f, +0xae, 0xaa, 0x97, 0x7d, 0x2e, 0xcd, 0x2f, 0x96, +0x5d, 0x9d, 0x7f, 0x97, 0x0c, 0x60, 0x38, 0xbb, +0xdd, 0xca, 0xaa, 0x8b, 0xdb, 0xf6, 0xb5, 0xbe, +0xd7, 0x40, 0x8e, 0x75, 0x5d, 0x8c, 0x01, 0x59, +0x16, 0xd9, 0x65, 0x07, 0x17, 0x17, 0x6e, 0x3c, +0x6f, 0xbe, 0xf8, 0x55, 0xfc, 0x2c, 0x5d, 0x42, +0xde, 0x0a, 0x11, 0x14, 0x39, 0xf2, 0x56, 0x88, +0x4f, 0xd3, 0x08, 0xef, 0xc4, 0xd7, 0xb1, 0xbc, +0x73, 0x03, 0x5b, 0xfd, 0xfb, 0x38, 0x7a, 0x34, +0xbd, 0x1e, 0x74, 0x79, 0x75, 0x0d, 0xcb, 0x4b, +0x5d, 0x77, 0xee, 0x9c, 0x08, 0x23, 0x9d, 0x47, +0xe7, 0xfd, 0xcd, 0xc3, 0xab, 0x72, 0x1b, 0x3a, +0x49, 0xee, 0x61, 0x18, 0xe2, 0xe4, 0xe4, 0xc4, +0x11, 0xc9, 0xe1, 0x70, 0x1a, 0xde, 0x94, 0x54, +0xfb, 0xab, 0xab, 0xab, 0xd8, 0xd8, 0xd8, 0xc0, +0xee, 0xee, 0x2e, 0xbe, 0xf1, 0x8d, 0x6f, 0xe0, +0x07, 0x3f, 0xf8, 0x01, 0x5e, 0x7e, 0xf9, 0x65, +0x77, 0x66, 0x9d, 0xca, 0x96, 0x0e, 0x96, 0xd2, +0x07, 0x85, 0x80, 0x07, 0x7b, 0xd1, 0xe6, 0x08, +0xcd, 0x31, 0x72, 0x60, 0x23, 0xb5, 0x7b, 0x14, +0x45, 0xe8, 0x74, 0x3a, 0xb8, 0x75, 0xeb, 0x16, +0x0e, 0x0e, 0x0e, 0xf0, 0xed, 0x6f, 0x7f, 0x1b, +0xdf, 0xfb, 0xde, 0xf7, 0xf0, 0xc6, 0x1b, 0x6f, +0xe0, 0xf5, 0xd7, 0x5f, 0xc7, 0xfe, 0xfe, 0x3e, +0x56, 0x57, 0x57, 0xd1, 0x6a, 0xb5, 0xf0, 0xd1, +0x47, 0x1f, 0xe1, 0xfe, 0xfd, 0xfb, 0xee, 0xec, +0xff, 0x57, 0xbe, 0xf2, 0x15, 0x24, 0x49, 0x82, +0xfb, 0xf7, 0xef, 0x3b, 0xa2, 0x4e, 0xe5, 0x53, +0xff, 0xd3, 0xbc, 0x26, 0x27, 0x3d, 0x22, 0xe4, +0xc7, 0xc7, 0xc7, 0x00, 0xa6, 0x97, 0xb9, 0x3c, +0x7e, 0xfc, 0xd8, 0x39, 0xe5, 0x11, 0xb1, 0xbf, +0x7f, 0xff, 0x7e, 0xc9, 0xdc, 0xb2, 0xbb, 0xbb, +0x8b, 0x8b, 0xf1, 0x04, 0xf9, 0xf9, 0x09, 0x7e, +0xeb, 0xf9, 0x5d, 0xbc, 0xb1, 0x5a, 0xa0, 0xc8, +0x32, 0xbc, 0x97, 0x76, 0xa6, 0x84, 0x37, 0x9a, +0xdd, 0x80, 0x26, 0x24, 0x25, 0x47, 0xa4, 0xd9, +0x86, 0x1c, 0xe5, 0x93, 0xe9, 0x5c, 0x88, 0xda, +0xee, 0x39, 0x0d, 0xe2, 0x12, 0x71, 0xe5, 0xdf, +0xb4, 0xfc, 0x54, 0x9f, 0xfb, 0x4e, 0xef, 0xd3, +0x14, 0xc8, 0xb3, 0x29, 0x21, 0x20, 0x9c, 0x2c, +0x49, 0x31, 0xae, 0xe2, 0x6e, 0x95, 0x57, 0x62, +0x4e, 0x80, 0xf2, 0x7b, 0xd9, 0xde, 0x19, 0xee, +0xaa, 0x3d, 0x7f, 0xf6, 0xdf, 0x87, 0x9f, 0xec, +0x9f, 0x0a, 0x71, 0xe4, 0xfd, 0xc1, 0xdf, 0x51, +0x5a, 0xce, 0x20, 0x45, 0x6d, 0x97, 0xd6, 0x95, +0x2b, 0xf2, 0xf3, 0x71, 0x73, 0x6d, 0xf6, 0x8d, +0x23, 0x93, 0xe8, 0xeb, 0xf0, 0x29, 0xf5, 0x65, +0x2b, 0x2c, 0xf7, 0x03, 0x23, 0xc4, 0x95, 0x72, +0x28, 0x2f, 0x1f, 0x33, 0x99, 0x8e, 0xc6, 0x8f, +0xe5, 0xd3, 0xca, 0xa1, 0x7c, 0xd4, 0x76, 0xce, +0x84, 0x39, 0x86, 0x41, 0x33, 0x0b, 0x4c, 0x46, +0x88, 0x92, 0xa4, 0xeb, 0x36, 0x37, 0x7e, 0x0b, +0x18, 0x2d, 0x36, 0xb9, 0x81, 0xd6, 0x79, 0xa5, +0xf3, 0x8d, 0x55, 0x6e, 0xb8, 0xf2, 0x8c, 0x35, +0x4f, 0x6f, 0xe5, 0xb5, 0xca, 0x6a, 0x02, 0xdc, +0x56, 0x57, 0xd7, 0x0e, 0xdf, 0xf9, 0x6f, 0x09, +0x54, 0x26, 0xa5, 0xe7, 0x92, 0x1e, 0x79, 0xf7, +0xf2, 0xe0, 0x1a, 0x94, 0x4e, 0xeb, 0x4f, 0xa9, +0x62, 0x97, 0x6d, 0xe5, 0x4e, 0x44, 0xfc, 0x9d, +0x86, 0x13, 0xc7, 0x43, 0xfb, 0x66, 0xf5, 0x4f, +0x93, 0xb1, 0xf5, 0x8d, 0x01, 0xaf, 0x5b, 0x06, +0x16, 0x91, 0x10, 0xc6, 0x6d, 0x58, 0x23, 0x29, +0xdb, 0xa0, 0x5d, 0x7d, 0xa9, 0xb5, 0xc9, 0x9a, +0x23, 0x1a, 0x5e, 0x72, 0x3e, 0x4c, 0xb2, 0xbc, +0x54, 0x46, 0x1a, 0xc4, 0x6e, 0xc3, 0xa6, 0xff, +0x17, 0x39, 0xf0, 0x2f, 0x27, 0x6b, 0x08, 0xf6, +0x5e, 0xc7, 0xb7, 0x0e, 0x7f, 0x8a, 0x3f, 0xfc, +0x93, 0x7f, 0x8d, 0x7e, 0xbf, 0x8f, 0xa7, 0x77, +0xef, 0xe2, 0xe0, 0xe0, 0xa0, 0x12, 0x2b, 0xbe, +0xdf, 0xef, 0xa3, 0xd3, 0xe9, 0x38, 0x22, 0xce, +0x61, 0x30, 0x18, 0xb8, 0xeb, 0x49, 0xe9, 0x3f, +0x80, 0xd2, 0xdd, 0xe2, 0x16, 0x50, 0xda, 0x6e, +0xb7, 0x8b, 0x6b, 0xd7, 0xae, 0xe1, 0x1b, 0xdf, +0xf8, 0x86, 0x2b, 0x93, 0x6e, 0x32, 0xeb, 0xf7, +0xfb, 0xee, 0xce, 0x70, 0x7e, 0xc9, 0x8b, 0xec, +0x17, 0x7e, 0x44, 0x4c, 0x02, 0x05, 0x6a, 0xa1, +0xcb, 0x67, 0xe8, 0x16, 0xb8, 0xdd, 0xdd, 0x5d, +0xd7, 0x2e, 0xc2, 0x45, 0x5e, 0x59, 0x3b, 0x18, +0x0c, 0xf0, 0xce, 0x3b, 0xef, 0xe0, 0xde, 0xbd, +0x7b, 0x95, 0x31, 0xb9, 0x7b, 0xf7, 0xae, 0xc3, +0x73, 0x38, 0x1c, 0x96, 0xae, 0x99, 0xa5, 0xbb, +0xd3, 0x39, 0x5e, 0x9d, 0x4e, 0xc7, 0xb5, 0x63, +0x7d, 0x7d, 0x1d, 0xef, 0xbc, 0xf3, 0x8e, 0x73, +0xca, 0x1b, 0x0c, 0x06, 0x4e, 0xf5, 0xce, 0xe7, +0xee, 0xee, 0xee, 0x2e, 0x4e, 0x2e, 0x07, 0x38, +0xfe, 0xfc, 0xd1, 0xf4, 0x8e, 0xf9, 0xcf, 0x3e, +0xc6, 0x36, 0x80, 0xff, 0x6c, 0x7f, 0x17, 0xff, +0xe6, 0x03, 0xe0, 0xfe, 0x79, 0x0e, 0x30, 0xc1, +0xcc, 0x11, 0xe7, 0xd9, 0xd8, 0x03, 0x28, 0x6d, +0x90, 0x29, 0x93, 0xa0, 0x4b, 0x84, 0x5c, 0xb9, +0xa2, 0x54, 0xcd, 0x0f, 0x00, 0xc1, 0x34, 0xaf, +0xac, 0x8f, 0xd2, 0xa5, 0x98, 0x7f, 0x4f, 0xc5, +0xd5, 0x9b, 0x51, 0x3e, 0x71, 0xef, 0xb4, 0xb9, +0x59, 0x29, 0x4f, 0x5c, 0x99, 0x49, 0xf9, 0xa3, +0x7c, 0xe2, 0xea, 0x91, 0xf9, 0x78, 0x1d, 0xa5, +0x3a, 0x9d, 0x14, 0x3f, 0x31, 0xf1, 0x73, 0xed, +0xe6, 0xf8, 0x06, 0x31, 0xa2, 0x30, 0x98, 0xe3, +0xc5, 0xa0, 0x82, 0xfb, 0xac, 0x1e, 0x5e, 0xbf, +0xd9, 0x9f, 0xbc, 0x4d, 0x41, 0x3c, 0x2d, 0x03, +0xd3, 0x76, 0xc9, 0xfa, 0x39, 0x7e, 0xae, 0x9e, +0x59, 0x1b, 0x24, 0x3e, 0x95, 0xbc, 0x7c, 0xbc, +0x8d, 0x3b, 0xea, 0x2b, 0x7d, 0x34, 0x61, 0x6b, +0x57, 0x96, 0x25, 0xc7, 0x4f, 0x6b, 0xb3, 0xec, +0x3f, 0xc2, 0x55, 0xf6, 0x33, 0x7f, 0x27, 0xae, +0xad, 0x8d, 0x22, 0x71, 0x27, 0xb0, 0xdc, 0x20, +0x35, 0xf0, 0x11, 0x0e, 0x99, 0xce, 0x97, 0xbf, +0x09, 0x91, 0xa9, 0xfb, 0xa6, 0x95, 0xc1, 0x89, +0xa7, 0xc6, 0x40, 0x68, 0xff, 0x79, 0xdb, 0x65, +0x1f, 0xc8, 0x3a, 0x78, 0xd9, 0x12, 0x2f, 0x8d, +0x49, 0x00, 0xe6, 0x84, 0x89, 0x98, 0x26, 0x2d, +0x00, 0x8e, 0x85, 0x83, 0xec, 0x6f, 0x0b, 0xef, +0xba, 0xb1, 0xf0, 0x11, 0x3f, 0x1f, 0x23, 0x63, +0x31, 0x5e, 0xda, 0x18, 0x12, 0x9e, 0x93, 0x2c, +0x47, 0x36, 0x19, 0x57, 0xca, 0xd2, 0xde, 0x69, +0x73, 0xc6, 0x87, 0x0f, 0xef, 0x6b, 0xdf, 0x3c, +0xd4, 0xe6, 0x32, 0xe5, 0xa5, 0xf1, 0xa3, 0x5b, +0xb7, 0xc6, 0x79, 0x81, 0x68, 0x74, 0x89, 0xed, +0x70, 0x8c, 0xc7, 0x41, 0xbb, 0xb2, 0x29, 0x5c, +0x8c, 0x46, 0xf8, 0x17, 0x9d, 0x1d, 0x3c, 0xde, +0xff, 0x11, 0x7e, 0x23, 0xf9, 0x19, 0xee, 0xdd, +0xbb, 0x87, 0xc3, 0xc3, 0x43, 0xbc, 0xfe, 0xfa, +0xeb, 0xb8, 0x7b, 0xf7, 0xae, 0xf3, 0xe2, 0x06, +0xe0, 0x88, 0x28, 0x8f, 0x48, 0xa7, 0x5d, 0x10, +0x43, 0x40, 0x84, 0x7d, 0x6f, 0x6f, 0xaf, 0x44, +0xe0, 0x01, 0x98, 0xb7, 0xca, 0x11, 0x8c, 0x46, +0x23, 0x47, 0x7c, 0xef, 0xde, 0xbd, 0x5b, 0xfa, +0x46, 0x73, 0x8e, 0xae, 0xff, 0xe4, 0xf3, 0x53, +0xf6, 0x09, 0xfd, 0xc9, 0xfa, 0x38, 0x2e, 0xdd, +0x6e, 0xb7, 0xf2, 0x9d, 0x08, 0x38, 0x01, 0x11, +0x6a, 0x3e, 0xcf, 0xef, 0xdd, 0xbb, 0x87, 0xe1, +0x70, 0x88, 0xbb, 0x77, 0xef, 0xe2, 0xbb, 0xdf, +0xfd, 0x2e, 0xde, 0x79, 0xe7, 0x9d, 0x12, 0x11, +0x4e, 0x92, 0xa4, 0x84, 0x1f, 0xe1, 0x46, 0xf7, +0xb1, 0x53, 0x3d, 0xfd, 0x7e, 0xdf, 0x05, 0xa3, +0x39, 0x38, 0x38, 0xa8, 0xcc, 0x93, 0x6b, 0xd7, +0x77, 0x5c, 0x7d, 0x74, 0xaf, 0x3c, 0x31, 0x0d, +0xad, 0x6c, 0x80, 0xff, 0xee, 0x60, 0x19, 0x3f, +0x3d, 0xeb, 0xe2, 0xa7, 0x27, 0x29, 0xde, 0x1e, +0x04, 0xb8, 0x18, 0x8d, 0xe6, 0x84, 0x2e, 0xcb, +0xe7, 0x9b, 0xe9, 0xec, 0xb7, 0xdc, 0x64, 0x1d, +0x30, 0x82, 0xe7, 0x88, 0x9c, 0x95, 0x1f, 0xa8, +0x10, 0x09, 0xc9, 0x24, 0x94, 0x9e, 0x05, 0x31, +0xe6, 0x1b, 0x7b, 0x9a, 0xe5, 0xa5, 0x3a, 0xe9, +0x3b, 0xe5, 0x2f, 0x11, 0x1f, 0x56, 0x2e, 0x9f, +0xcb, 0xf2, 0x19, 0x28, 0x13, 0xe8, 0x28, 0x64, +0x9c, 0x8e, 0x42, 0xe0, 0x2c, 0xfc, 0x52, 0x41, +0x88, 0x4a, 0x04, 0x55, 0x10, 0xad, 0x54, 0xe9, +0x4f, 0x57, 0xb6, 0x48, 0xe3, 0xfa, 0xd2, 0x20, +0x76, 0x1a, 0xc3, 0x60, 0xe1, 0x9e, 0x66, 0x33, +0x46, 0x4e, 0x61, 0x5c, 0xbc, 0x7d, 0x24, 0x1c, +0xd4, 0x1c, 0x4e, 0x40, 0xf5, 0x3f, 0x0c, 0xa6, +0x6f, 0x96, 0xa6, 0xd2, 0x5f, 0x33, 0x61, 0x42, +0x32, 0x46, 0xa9, 0xc4, 0x8d, 0xe3, 0xa4, 0x31, +0x18, 0x93, 0x11, 0xa2, 0xa1, 0xb0, 0x5f, 0x25, +0x49, 0x52, 0xba, 0x28, 0x41, 0x6e, 0xf8, 0xf4, +0x4e, 0xdb, 0xe0, 0x9b, 0x48, 0xc0, 0xbe, 0xf7, +0x5a, 0x1a, 0x1f, 0x73, 0x51, 0xb7, 0x89, 0xfb, +0xa4, 0x54, 0x8d, 0x50, 0xfb, 0x08, 0xac, 0x46, +0x40, 0x79, 0x5e, 0xae, 0xd9, 0x90, 0xc4, 0x92, +0x82, 0x65, 0x70, 0xbc, 0x88, 0x98, 0x68, 0x92, +0xa3, 0x86, 0xb3, 0xd6, 0x2e, 0x8d, 0xa9, 0xf0, +0x81, 0x24, 0xbc, 0x5a, 0x1b, 0x9b, 0x8e, 0x0f, +0xe5, 0x0f, 0xe3, 0xa9, 0xfa, 0x2d, 0x5e, 0x5e, +0xc5, 0xea, 0xee, 0x3e, 0xce, 0xaf, 0xdf, 0xc1, +0x93, 0xa5, 0x2d, 0xe4, 0x2b, 0x1b, 0x08, 0xce, +0x8f, 0x11, 0x0f, 0xcf, 0xd0, 0x59, 0x5a, 0x46, +0xfa, 0xf0, 0x1e, 0x96, 0x2e, 0x8e, 0x91, 0x0d, +0xce, 0x11, 0x9e, 0x3d, 0xc5, 0xe4, 0xe2, 0x4c, +0x25, 0xec, 0xd6, 0x7c, 0xe3, 0xcf, 0x3e, 0xad, +0x8e, 0xc6, 0xac, 0x71, 0xad, 0x88, 0x35, 0x9f, +0xf2, 0xf1, 0x08, 0xc9, 0xe7, 0xf7, 0xb0, 0x73, +0xfb, 0x0e, 0x1e, 0x73, 0x7a, 0xcb, 0x36, 0x92, +0x8b, 0x1c, 0xf8, 0x93, 0x7c, 0x19, 0xc7, 0x1b, +0xdf, 0xc4, 0x5f, 0xdd, 0x7a, 0x0e, 0xc9, 0xa3, +0xf7, 0x1d, 0x61, 0x7a, 0xf9, 0xd7, 0x5e, 0xc3, +0xed, 0x1b, 0x7b, 0xe8, 0x74, 0x3a, 0x4e, 0x7a, +0x94, 0x63, 0x43, 0x75, 0xae, 0xaf, 0xaf, 0x3b, +0x02, 0xce, 0xa5, 0xf8, 0x26, 0x84, 0x5c, 0x63, +0x10, 0x34, 0x68, 0x75, 0xba, 0xd8, 0xd8, 0xe9, +0xa2, 0x18, 0x0d, 0xb0, 0xb1, 0xb3, 0x87, 0xa5, +0x28, 0x70, 0xea, 0x72, 0x60, 0x7e, 0x34, 0x4d, +0x96, 0x4d, 0x36, 0x7c, 0xea, 0x2b, 0x3a, 0x17, +0xbe, 0xb7, 0xb7, 0x57, 0xaa, 0x17, 0x98, 0x6b, +0x19, 0x78, 0x7e, 0x39, 0x86, 0x72, 0x4d, 0xdc, +0xbd, 0x7b, 0x17, 0x77, 0xef, 0xde, 0x9d, 0xc6, +0x2e, 0xe8, 0x74, 0x5c, 0xc8, 0x56, 0x39, 0xb6, +0x24, 0x95, 0x53, 0x7f, 0x7d, 0xfc, 0xf1, 0xc7, +0xe8, 0xf5, 0x7a, 0x78, 0xf4, 0xe8, 0x91, 0x2b, +0xff, 0xe1, 0xc3, 0x87, 0xee, 0x8e, 0xf4, 0x24, +0x49, 0x90, 0x8f, 0x47, 0xb8, 0xf7, 0xf9, 0xa3, +0xd2, 0x55, 0xcc, 0x74, 0xfe, 0x7d, 0xd8, 0xef, +0x63, 0x3b, 0x49, 0xf0, 0xb7, 0x92, 0x04, 0xbf, +0xb5, 0x97, 0xe0, 0xff, 0xf6, 0x20, 0xc1, 0x21, +0xa6, 0x4c, 0x1a, 0xc2, 0xa0, 0x4c, 0x28, 0xc0, +0xa4, 0x58, 0xe7, 0xb9, 0x1c, 0x94, 0x08, 0x15, +0x11, 0x06, 0x47, 0x2c, 0xb2, 0x19, 0x61, 0xe4, +0x1b, 0xfd, 0x6c, 0xde, 0x54, 0x88, 0x02, 0xdb, +0xe0, 0xa3, 0x30, 0x28, 0x33, 0x05, 0xf4, 0x9d, +0x41, 0x9a, 0xe5, 0x53, 0x22, 0xab, 0x49, 0x6e, +0x3c, 0x1d, 0x97, 0xb4, 0x49, 0x3a, 0xc6, 0x9c, +0x88, 0xb9, 0x67, 0x83, 0x48, 0x51, 0x19, 0xaa, +0x16, 0x41, 0xc3, 0x5f, 0x10, 0x4c, 0x47, 0x2c, +0x67, 0x40, 0xf5, 0xb9, 0xfc, 0xac, 0x6d, 0x12, +0xd7, 0x4a, 0xf9, 0x94, 0x26, 0x28, 0x8f, 0x03, +0x69, 0x3a, 0x4a, 0x78, 0xcd, 0xf2, 0x38, 0xe2, +0x18, 0x94, 0xfb, 0xa3, 0x82, 0x97, 0xa2, 0x9d, +0x90, 0x69, 0xd4, 0x36, 0x10, 0xc8, 0xf1, 0x13, +0xf8, 0x4b, 0x89, 0xbc, 0x94, 0x06, 0x28, 0x69, +0x5a, 0x9c, 0xd6, 0x46, 0x6a, 0x2b, 0x58, 0xbf, +0xa5, 0x71, 0x55, 0x32, 0xe7, 0xf3, 0x86, 0xc6, +0x3a, 0x4a, 0x67, 0x8e, 0x2c, 0xb4, 0x00, 0x34, +0x8e, 0xbd, 0x8e, 0xb0, 0xf1, 0x7c, 0x96, 0x84, +0xca, 0xa1, 0x8e, 0x30, 0xd6, 0xa9, 0x8c, 0x35, +0x90, 0xd2, 0xa2, 0xfc, 0xe6, 0x63, 0x0c, 0xea, +0x18, 0x0e, 0x8d, 0x01, 0x90, 0x75, 0x5a, 0xed, +0xe4, 0x51, 0xaf, 0x2c, 0x9c, 0x7c, 0x4c, 0x8f, +0x2c, 0x4f, 0x93, 0x84, 0xad, 0xbe, 0xbd, 0x4a, +0xff, 0x59, 0x63, 0x21, 0xcb, 0xe5, 0xbf, 0xc3, +0xb8, 0x8d, 0x95, 0xeb, 0xbb, 0x68, 0xef, 0xbf, +0x84, 0x8f, 0x6e, 0x7d, 0x13, 0x0f, 0x57, 0xaf, +0xe1, 0x11, 0xba, 0xb8, 0x98, 0x31, 0x9b, 0x58, +0xbe, 0x09, 0x60, 0x3a, 0x59, 0x37, 0xae, 0xdf, +0x45, 0x3b, 0x1b, 0x21, 0x4f, 0xa7, 0x1f, 0xb7, +0x1f, 0xfe, 0x02, 0x4b, 0x1f, 0xfc, 0x6b, 0xb4, +0x8f, 0x0f, 0x91, 0xa5, 0x93, 0x4a, 0x9f, 0x37, +0xd5, 0xd8, 0x68, 0xcc, 0x90, 0x66, 0x96, 0xe0, +0xe3, 0xc0, 0x99, 0x28, 0x22, 0xf4, 0x41, 0xbb, +0x83, 0xc1, 0xc9, 0x31, 0xd6, 0x83, 0x29, 0x7e, +0xa5, 0xc5, 0x2e, 0x36, 0xe7, 0x0f, 0xf3, 0x2e, +0xfe, 0x7b, 0xdc, 0xc2, 0x0f, 0xf6, 0xd6, 0xf1, +0xa3, 0xfe, 0x5b, 0x4e, 0xbd, 0x3d, 0x78, 0xfd, +0x75, 0x1c, 0x1c, 0x1c, 0xa0, 0xdb, 0xed, 0x56, +0xd6, 0x93, 0x36, 0x76, 0xa4, 0x2e, 0xe7, 0x04, +0x11, 0x80, 0x23, 0xf2, 0x7b, 0x7b, 0x7b, 0x00, +0xca, 0x44, 0x9d, 0xa4, 0xfb, 0x4e, 0xa7, 0xe3, +0x95, 0xda, 0x8b, 0xd1, 0xa0, 0xf4, 0xfb, 0x42, +0x28, 0x04, 0x24, 0x21, 0x97, 0x51, 0xe8, 0x92, +0x24, 0x29, 0xf5, 0x23, 0xd5, 0x4b, 0x04, 0x9c, +0x24, 0xe9, 0x71, 0x9a, 0xa1, 0x1d, 0x85, 0xa5, +0x36, 0xd2, 0x1f, 0x11, 0xd2, 0xe3, 0xe3, 0xe3, +0x12, 0x73, 0x73, 0xf7, 0xee, 0x5d, 0x7c, 0xf4, +0xd1, 0x47, 0x25, 0xe2, 0xaf, 0x31, 0xa5, 0x8f, +0x1e, 0x3d, 0xc2, 0xce, 0xce, 0x8e, 0x3a, 0x96, +0x74, 0xe3, 0x1a, 0x11, 0x73, 0x6a, 0x03, 0x8d, +0xe9, 0xcf, 0x7e, 0xf6, 0x33, 0x57, 0x3f, 0xd7, +0x8a, 0x8d, 0xf3, 0x02, 0x9d, 0x4e, 0x8e, 0xff, +0x6a, 0x6d, 0x84, 0x8f, 0x27, 0x31, 0xfe, 0xc1, +0x69, 0x07, 0x0f, 0xd3, 0xd0, 0x94, 0xcc, 0x68, +0x73, 0x25, 0x55, 0x6e, 0x45, 0x52, 0x12, 0x52, +0x38, 0x97, 0xe2, 0x69, 0x13, 0xd6, 0xa4, 0x3f, +0x55, 0xc5, 0x3e, 0xdb, 0xdc, 0xf9, 0x5c, 0xd3, +0xea, 0xaf, 0x48, 0x8f, 0x42, 0xaa, 0xaf, 0xa4, +0xd1, 0xea, 0x16, 0x92, 0x24, 0xe5, 0x93, 0xfd, +0xa0, 0x49, 0xd7, 0x9a, 0xea, 0xdf, 0xcc, 0xcf, +0xda, 0xc2, 0xeb, 0xa3, 0x7e, 0xab, 0x10, 0x30, +0x4e, 0xf4, 0x15, 0x4d, 0x81, 0x03, 0x81, 0x97, +0xab, 0x97, 0x13, 0x64, 0x49, 0xf4, 0x2c, 0x4d, +0x83, 0xd6, 0x3e, 0x4b, 0x42, 0x36, 0xc6, 0xef, +0x59, 0xf1, 0x57, 0x35, 0x0d, 0x0a, 0x63, 0x53, +0x31, 0xbb, 0x88, 0xf4, 0x69, 0xdc, 0x41, 0xf8, +0xc2, 0x0f, 0x7e, 0xf2, 0xe6, 0x1e, 0xe6, 0x1b, +0x8e, 0x94, 0x60, 0x34, 0xcf, 0x72, 0xe9, 0x58, +0xc3, 0x9d, 0xb2, 0x78, 0x04, 0x2b, 0x2b, 0x10, +0x8b, 0xe6, 0x98, 0x53, 0x17, 0xc0, 0xc4, 0x2a, +0x8b, 0xff, 0x96, 0x0e, 0x77, 0x32, 0x2d, 0x3f, +0xb2, 0x23, 0x9d, 0xfd, 0x34, 0xc7, 0x2d, 0xde, +0x0f, 0xbc, 0x6c, 0xee, 0xf0, 0x26, 0x9d, 0xf7, +0xc8, 0x03, 0x58, 0xa6, 0xa3, 0x32, 0xb8, 0xa3, +0x0f, 0x3f, 0x5b, 0xce, 0x9d, 0xcd, 0x24, 0x91, +0xd7, 0xbc, 0xd5, 0xb9, 0x13, 0x9d, 0x76, 0xee, +0x5c, 0xb5, 0x57, 0x47, 0x31, 0x8a, 0x3c, 0xaf, +0xbc, 0xb7, 0x3c, 0xf4, 0xa9, 0x6e, 0xe9, 0x44, +0xb8, 0xbc, 0xba, 0x86, 0xce, 0x8b, 0xbf, 0x06, +0xbc, 0xfa, 0x43, 0x1c, 0xbe, 0xfa, 0x1f, 0xe0, +0xad, 0xed, 0xaf, 0xe1, 0x61, 0x7b, 0x03, 0xc7, +0x74, 0xbe, 0x97, 0x26, 0x1f, 0x39, 0xe0, 0xb4, +0x42, 0x5c, 0x22, 0xc4, 0x59, 0xab, 0x83, 0xf3, +0x30, 0x99, 0xfe, 0x5d, 0xbb, 0x85, 0xcf, 0x9f, +0xff, 0x0e, 0xc2, 0xe7, 0xbe, 0x8a, 0xec, 0xda, +0x1e, 0xd6, 0x06, 0xc7, 0x18, 0x9e, 0x9f, 0x55, +0xa2, 0xcc, 0x85, 0x71, 0x1b, 0x41, 0x18, 0x22, +0x08, 0x43, 0x14, 0x79, 0x56, 0x71, 0x74, 0x24, +0x42, 0x40, 0xed, 0x26, 0xa2, 0xcd, 0xfb, 0x54, +0x5e, 0x50, 0xc2, 0xc7, 0x76, 0x92, 0x66, 0x58, +0x5e, 0x5a, 0x42, 0x67, 0xe6, 0x3d, 0xde, 0xbd, +0x7e, 0x03, 0x3f, 0x2f, 0x56, 0xab, 0x52, 0x09, +0x77, 0xba, 0x69, 0x85, 0x28, 0xb2, 0x09, 0xde, +0xcb, 0x97, 0xf0, 0xf9, 0xfa, 0x2d, 0xbc, 0xbc, +0x77, 0x0d, 0x67, 0x97, 0x03, 0x3c, 0xfa, 0xf4, +0x63, 0x9c, 0x9f, 0xf4, 0x4b, 0x0e, 0x8f, 0xd2, +0x81, 0x92, 0x4e, 0x8d, 0xf0, 0x73, 0xda, 0x1c, +0xc8, 0xcb, 0x5d, 0x9e, 0x10, 0x19, 0x0e, 0x87, +0xce, 0xc1, 0x0e, 0x80, 0xf3, 0x2a, 0xe7, 0x47, +0xda, 0x28, 0x1c, 0x2b, 0xff, 0xab, 0x3b, 0xa3, +0x4e, 0xd0, 0x9a, 0x45, 0x7f, 0xa4, 0xeb, 0x48, +0x29, 0x1a, 0x1d, 0xf5, 0x37, 0x27, 0xc8, 0xfc, +0x1c, 0x79, 0x38, 0xf3, 0x0c, 0xbe, 0x77, 0xef, +0x5e, 0x29, 0x06, 0x05, 0x9f, 0x3f, 0x14, 0xcb, +0x9e, 0x82, 0xc2, 0xec, 0xef, 0xef, 0xe3, 0xe2, +0xe2, 0x02, 0xef, 0xbc, 0xf3, 0x8e, 0x73, 0x44, +0xa4, 0xbe, 0xa1, 0x31, 0xe4, 0xa1, 0x66, 0xe9, +0x37, 0x05, 0x89, 0xe1, 0x91, 0xe4, 0x8a, 0xa2, +0x70, 0xfd, 0x49, 0x0e, 0x75, 0x47, 0x47, 0x47, +0x28, 0x8a, 0xc2, 0x85, 0x89, 0x3d, 0x3e, 0x3e, +0x76, 0x1a, 0x8f, 0xe5, 0x6e, 0x17, 0xfd, 0xa7, +0x4f, 0x10, 0x9e, 0x1c, 0xe1, 0x39, 0x5c, 0xe0, +0x47, 0x5b, 0x31, 0x8e, 0xdb, 0xeb, 0x78, 0x70, +0xc9, 0x9c, 0x9e, 0x80, 0x92, 0x03, 0x52, 0xc9, +0x21, 0x6a, 0x36, 0x9f, 0xdd, 0xfc, 0xe0, 0x47, +0xc9, 0x82, 0xc0, 0xbd, 0x77, 0x8e, 0x59, 0x32, +0xfd, 0x74, 0x21, 0xce, 0x3b, 0x7e, 0xe6, 0x40, +0xe7, 0x1c, 0xa1, 0x84, 0xa3, 0x9a, 0x56, 0x7f, +0xc9, 0x11, 0xaf, 0xb4, 0xd6, 0x5a, 0xce, 0x3b, +0x9a, 0x9c, 0xab, 0xc8, 0x81, 0xca, 0x95, 0x43, +0x8e, 0x6c, 0x94, 0x2f, 0xcf, 0x5c, 0xfd, 0x9c, +0xb0, 0xe4, 0x51, 0xbb, 0x9a, 0x3e, 0xcb, 0x10, +0x21, 0x53, 0x1d, 0x00, 0x4b, 0x6d, 0x94, 0x0e, +0x5f, 0xc2, 0xa1, 0x8e, 0x3b, 0x0c, 0x06, 0x45, +0x5e, 0x95, 0xfe, 0x59, 0x3b, 0xf3, 0x56, 0x58, +0xea, 0x4b, 0xb6, 0x99, 0x55, 0xf6, 0x18, 0xcd, +0x01, 0xd1, 0xb5, 0x7f, 0x56, 0x06, 0x3d, 0x57, +0xc6, 0x8f, 0xc6, 0x30, 0x13, 0x0e, 0x92, 0x35, +0xe3, 0xa7, 0x6a, 0x2f, 0xae, 0x80, 0x3f, 0xd5, +0x55, 0x4a, 0xa3, 0x39, 0x5a, 0x7a, 0xd2, 0xd3, +0x58, 0x87, 0x07, 0x3f, 0xfc, 0x2b, 0x6f, 0x26, +0x67, 0x47, 0x38, 0x3f, 0xe9, 0x97, 0x22, 0x48, +0xf1, 0xcd, 0x52, 0x1e, 0x7f, 0x92, 0x67, 0x75, +0xf9, 0xa6, 0x23, 0x09, 0xa3, 0x45, 0x58, 0x69, +0xb1, 0x6b, 0x01, 0x5e, 0xb8, 0x87, 0x37, 0xff, +0x26, 0x3d, 0xb9, 0x65, 0x90, 0x0c, 0x7e, 0xcc, +0xcd, 0x77, 0x5c, 0x49, 0xdb, 0x40, 0x79, 0x7c, +0x74, 0xcd, 0x3b, 0xdf, 0x3a, 0xe7, 0x4d, 0x1e, +0xb5, 0x1c, 0xa4, 0x56, 0x41, 0x6a, 0x04, 0xf8, +0x79, 0x5e, 0x02, 0x79, 0x6c, 0x8c, 0x13, 0x79, +0x79, 0x05, 0x2b, 0x97, 0x42, 0xb5, 0x36, 0x69, +0x1b, 0x78, 0x92, 0x24, 0x98, 0x8c, 0xc7, 0x95, +0x77, 0x92, 0x81, 0x28, 0x5a, 0x01, 0x8a, 0x3c, +0x43, 0x18, 0xb7, 0x11, 0xb2, 0xe8, 0x67, 0xd1, +0xca, 0x3a, 0x92, 0xe7, 0x5f, 0xc1, 0xe4, 0x1b, +0x3f, 0xc1, 0xc5, 0x37, 0xff, 0x1a, 0xde, 0x79, +0xee, 0x0d, 0xdc, 0x5b, 0xb9, 0x81, 0xa7, 0xf1, +0x2a, 0x26, 0x39, 0xe6, 0x71, 0x8c, 0xe5, 0xb5, +0x8b, 0xfc, 0xf8, 0x09, 0x9d, 0xf1, 0xcc, 0x26, +0x98, 0xcc, 0x6e, 0xae, 0x3a, 0x89, 0x97, 0xf0, +0x70, 0xe3, 0x36, 0x4e, 0x9e, 0x7b, 0x0d, 0xf1, +0xee, 0x73, 0xd8, 0xcf, 0x4e, 0x91, 0x0d, 0x2f, +0xa7, 0x5e, 0xf0, 0xf1, 0x7c, 0x23, 0x21, 0x95, +0xbc, 0xef, 0xe8, 0x1d, 0x27, 0xda, 0xf4, 0xac, +0x69, 0x58, 0xf8, 0x5c, 0x28, 0xf2, 0xbc, 0x14, +0xb2, 0x78, 0x73, 0xf7, 0x06, 0x3e, 0x8d, 0x37, +0x70, 0x3a, 0x9e, 0x79, 0x19, 0xe7, 0x98, 0x87, +0xb2, 0x44, 0xcb, 0x1d, 0x3f, 0xc9, 0x8b, 0x02, +0x08, 0x23, 0x3c, 0xbe, 0x1c, 0xe1, 0xa7, 0xf9, +0x3a, 0xee, 0xc5, 0xeb, 0xb8, 0x73, 0x6d, 0x15, +0xf9, 0x67, 0x1f, 0x39, 0x49, 0x9d, 0xe6, 0x2e, +0xcd, 0x47, 0x72, 0x8c, 0x94, 0x8c, 0x1a, 0x97, +0x66, 0x8b, 0xa2, 0x28, 0x05, 0xa9, 0x49, 0xd3, +0xd4, 0x49, 0x9c, 0xf2, 0x3c, 0x3d, 0x45, 0x6c, +0x23, 0xc2, 0x0d, 0xc0, 0x05, 0xab, 0xe1, 0x69, +0x38, 0xe1, 0xb7, 0x88, 0x3c, 0x5f, 0x6b, 0x84, +0x3f, 0x5f, 0x1f, 0x74, 0x16, 0x9d, 0xf0, 0xe4, +0x0c, 0x9e, 0xc6, 0xc0, 0x13, 0x43, 0xd3, 0xef, +0xf7, 0x71, 0x76, 0x76, 0xe6, 0x6e, 0x99, 0x23, +0x9c, 0x0f, 0x0f, 0x0f, 0x5d, 0x60, 0x18, 0x5a, +0x47, 0xe4, 0x3c, 0x4a, 0xeb, 0x8c, 0xae, 0x55, +0xa5, 0x4b, 0x5c, 0xf8, 0x51, 0x35, 0xba, 0x6a, +0x95, 0x22, 0xd7, 0xd1, 0x18, 0xaf, 0xac, 0xac, +0xe0, 0xfe, 0xfd, 0xfb, 0xce, 0x0e, 0x4f, 0x41, +0x77, 0x86, 0xc3, 0x21, 0xe2, 0xd9, 0x25, 0x52, +0x34, 0xde, 0x5b, 0x5b, 0x5b, 0x58, 0x8e, 0x43, +0xbc, 0x34, 0x7a, 0x84, 0xaf, 0xae, 0x46, 0x38, +0xcd, 0x5a, 0xf8, 0x7c, 0x38, 0xdb, 0xf4, 0x69, +0xb3, 0xa4, 0x0d, 0x54, 0x1c, 0x67, 0x73, 0xef, +0x68, 0x6e, 0xcf, 0x02, 0xa9, 0xe4, 0xf2, 0xc8, +0xd8, 0x6c, 0xfe, 0x57, 0xd2, 0xd3, 0x5a, 0x88, +0x14, 0x42, 0xc0, 0x6f, 0x28, 0xcb, 0x26, 0xfe, +0xfa, 0xa9, 0x0c, 0x11, 0x60, 0x84, 0xe6, 0x27, +0xaf, 0xb3, 0xec, 0xed, 0xce, 0xc2, 0x86, 0x8a, +0x32, 0xe5, 0x7f, 0x7e, 0xe6, 0xbc, 0xe4, 0x3d, +0xce, 0x6d, 0xc2, 0x94, 0x7f, 0x46, 0x8c, 0x5c, +0x7e, 0x3a, 0xf7, 0x4e, 0xe7, 0xd5, 0x09, 0x57, +0xc6, 0x44, 0x54, 0x8e, 0x64, 0xc9, 0x7e, 0xe2, +0x41, 0x5a, 0xf8, 0xf9, 0x73, 0x56, 0x56, 0x69, +0xcc, 0xf8, 0x3d, 0xed, 0xc6, 0x7e, 0xa4, 0x8e, +0x87, 0xe8, 0x0f, 0xef, 0x78, 0xcb, 0xf7, 0x12, +0x7f, 0x0a, 0xf0, 0x42, 0xc7, 0xc8, 0x7c, 0xf8, +0xfb, 0xf0, 0xe3, 0x79, 0xb5, 0xa3, 0x6f, 0x2c, +0x6d, 0x78, 0xf3, 0x5b, 0x3f, 0x78, 0x33, 0x7e, +0x74, 0xaf, 0x62, 0xd3, 0xd5, 0x8e, 0x64, 0xf1, +0xb3, 0xd6, 0x92, 0x88, 0x73, 0x6e, 0x5c, 0x9e, +0xa9, 0xb6, 0xce, 0x33, 0x6b, 0x12, 0x2e, 0x27, +0x68, 0x92, 0x10, 0x6b, 0x47, 0xd7, 0x34, 0x89, +0x52, 0x06, 0x54, 0xd1, 0x8e, 0x73, 0x71, 0x5c, +0x34, 0x5b, 0xb2, 0x16, 0xac, 0x44, 0x02, 0x0f, +0x02, 0x23, 0xf1, 0xd4, 0xfa, 0x0b, 0x40, 0x69, +0x63, 0x22, 0x09, 0x88, 0x4b, 0xf5, 0x16, 0xf3, +0xc4, 0xdb, 0x27, 0xa5, 0x65, 0x9f, 0xf4, 0xc5, +0xf1, 0xa2, 0xbf, 0x02, 0x2d, 0x04, 0x41, 0x88, +0x3c, 0x2f, 0x9c, 0xa4, 0xde, 0x49, 0xba, 0x28, +0xf2, 0x1c, 0xcb, 0x4b, 0x5d, 0x2c, 0xad, 0xad, +0xe3, 0xfa, 0xde, 0x0d, 0xc4, 0x2f, 0xbe, 0x86, +0xa3, 0x57, 0x7f, 0x82, 0x8b, 0x57, 0x7e, 0x13, +0x6f, 0xbf, 0xf0, 0x43, 0x1c, 0x3e, 0xf7, 0x3a, +0x1e, 0x5c, 0xbb, 0x83, 0x27, 0xe1, 0x32, 0xd2, +0x56, 0x08, 0xb4, 0x82, 0x79, 0xe4, 0xa6, 0xd6, +0x4c, 0x9d, 0xd4, 0x0a, 0xe6, 0x11, 0xa2, 0x5a, +0xc1, 0x3c, 0x6e, 0x32, 0x45, 0x4e, 0x72, 0x67, +0x24, 0xa7, 0x9b, 0x7a, 0x30, 0x3b, 0x86, 0x71, +0x11, 0x26, 0x38, 0xea, 0x6e, 0xe2, 0xfc, 0xe6, +0xcb, 0x28, 0x76, 0x0f, 0x10, 0xad, 0x6f, 0xe2, +0x7a, 0x5c, 0x20, 0x1f, 0x0d, 0x91, 0x66, 0x99, +0x93, 0xcc, 0x25, 0xc8, 0xfe, 0x96, 0x47, 0xfb, +0xf8, 0xd1, 0x4a, 0xad, 0xff, 0xc2, 0x28, 0x46, +0x5e, 0x00, 0x45, 0x3e, 0x3d, 0x52, 0xb6, 0xb3, +0xb1, 0x86, 0x07, 0xab, 0x37, 0xf1, 0x79, 0xd1, +0x99, 0x6e, 0x34, 0x14, 0x80, 0x23, 0xcf, 0xe6, +0xed, 0xcd, 0xb3, 0xf9, 0xad, 0x56, 0x61, 0x84, +0xc9, 0x78, 0x84, 0xb3, 0x56, 0x07, 0x6f, 0xb7, +0x7a, 0x08, 0xaf, 0x5d, 0x47, 0xb2, 0xba, 0x56, +0x21, 0xea, 0x59, 0x30, 0x0d, 0x48, 0x22, 0x8f, +0x57, 0x92, 0x34, 0x4a, 0x73, 0xf0, 0xc9, 0x93, +0x27, 0xb8, 0x98, 0x1d, 0x97, 0xfb, 0xfc, 0xe8, +0x09, 0x8e, 0x9f, 0x3e, 0x75, 0xf3, 0x84, 0x88, +0x1f, 0x11, 0x24, 0x22, 0xfc, 0x44, 0x38, 0xcf, +0xce, 0xce, 0x70, 0x71, 0x71, 0xe1, 0xa4, 0x55, +0x0a, 0x60, 0x93, 0xa6, 0xa9, 0x93, 0xac, 0x27, +0x93, 0x09, 0xba, 0xdd, 0x2e, 0x1e, 0x3f, 0x7e, +0x8c, 0x2c, 0xcb, 0xd0, 0x6a, 0xb5, 0xf0, 0xf8, +0xf1, 0x63, 0x3c, 0x79, 0xf2, 0xc4, 0x39, 0xaf, +0x51, 0x1d, 0x9c, 0x59, 0x95, 0xc7, 0xd8, 0x2c, +0x26, 0x99, 0x6b, 0x44, 0x08, 0x4f, 0x7e, 0xb6, +0xfe, 0xc9, 0x93, 0x27, 0x8e, 0x61, 0xe0, 0x6b, +0x9f, 0x6b, 0x01, 0xf8, 0x9c, 0xa6, 0xab, 0x52, +0xd3, 0x34, 0x2d, 0xd9, 0xc2, 0xb9, 0x06, 0x8c, +0xfe, 0xb6, 0xb6, 0xb6, 0x70, 0x76, 0x76, 0xe6, +0x82, 0xd9, 0x3c, 0x78, 0xf0, 0x00, 0xfd, 0x7e, +0x1f, 0xdd, 0x6e, 0xd7, 0xf5, 0xcb, 0xc9, 0xc9, +0x89, 0x0b, 0x44, 0x03, 0x00, 0x0f, 0x1e, 0x3d, +0x42, 0xb7, 0x55, 0xe0, 0x85, 0xe5, 0x10, 0x69, +0x10, 0xe3, 0x38, 0x05, 0x26, 0x71, 0x17, 0x79, +0x9e, 0x4d, 0x89, 0x43, 0x10, 0xcd, 0xe7, 0x32, +0xcd, 0x5d, 0x1e, 0xc5, 0x8b, 0xdf, 0x9e, 0xa6, +0x5d, 0x3b, 0xca, 0xe3, 0x86, 0xf3, 0xe8, 0x61, +0x01, 0x49, 0xf4, 0x93, 0x32, 0x21, 0xa0, 0xbb, +0xad, 0xe9, 0x66, 0x37, 0x9a, 0x73, 0x3c, 0xbe, +0x38, 0x2f, 0x8f, 0xcf, 0x49, 0x4a, 0xd3, 0x0a, +0xe6, 0xeb, 0x50, 0xae, 0x3f, 0x4a, 0x03, 0x94, +0x89, 0x0d, 0x27, 0xf0, 0x9c, 0x88, 0x50, 0xfb, +0x38, 0x01, 0xe2, 0x61, 0x62, 0xd1, 0x9a, 0xd7, +0xa7, 0xc5, 0x81, 0xe7, 0xf7, 0xac, 0xf3, 0x4b, +0x61, 0x08, 0x3f, 0x4e, 0xec, 0x28, 0x1a, 0x9c, +0xc4, 0x5f, 0xe2, 0x43, 0x7d, 0xc3, 0xc7, 0x83, +0xca, 0xe4, 0xb7, 0x8a, 0x51, 0x5f, 0x68, 0xfb, +0x91, 0x1c, 0xbf, 0xd2, 0xbd, 0xf2, 0xad, 0x72, +0xbd, 0x72, 0xfc, 0x08, 0x47, 0x89, 0x1b, 0xff, +0x4f, 0x7d, 0xac, 0xe1, 0xdf, 0x0a, 0xe0, 0x02, +0x14, 0xd5, 0xe1, 0xc7, 0xfb, 0xaa, 0x28, 0xca, +0xb7, 0xb2, 0x71, 0x66, 0x30, 0xcf, 0x10, 0x6e, +0xbc, 0xf2, 0xed, 0x37, 0x3b, 0x4f, 0x1e, 0x94, +0x08, 0x39, 0x11, 0x34, 0x6b, 0xe3, 0xe4, 0x57, +0x2d, 0x72, 0x35, 0x33, 0x27, 0x88, 0x92, 0x18, +0x71, 0x69, 0x52, 0x6e, 0x00, 0x9c, 0xa8, 0x4a, +0x49, 0x5b, 0x4a, 0xac, 0x92, 0xc0, 0x49, 0xfc, +0x78, 0x99, 0xfc, 0x4f, 0xb6, 0x87, 0x4b, 0xff, +0x9c, 0xf8, 0x4b, 0xc2, 0xcf, 0xa5, 0x10, 0xc9, +0x94, 0x50, 0x7e, 0xda, 0xf0, 0x34, 0xc2, 0xa2, +0x05, 0x79, 0x91, 0x78, 0x71, 0xad, 0x80, 0x6c, +0x23, 0x57, 0x1b, 0x73, 0xfc, 0x34, 0xb5, 0x3b, +0xcf, 0xab, 0xa5, 0x21, 0x08, 0x83, 0x00, 0x61, +0x10, 0x94, 0x24, 0xf5, 0x20, 0x08, 0xd1, 0x5d, +0x59, 0xc5, 0xd2, 0x4b, 0xbf, 0x86, 0xfe, 0x37, +0xfe, 0x1a, 0x3e, 0xbc, 0xfd, 0x06, 0xfe, 0xe8, +0xda, 0xd7, 0x71, 0xb4, 0xba, 0x3b, 0x25, 0xde, +0x51, 0x07, 0x29, 0x71, 0xda, 0x61, 0x58, 0x0e, +0x2b, 0xe8, 0x0a, 0x0e, 0xcb, 0x1b, 0x9b, 0x16, +0xf7, 0x98, 0x36, 0xc7, 0x59, 0x19, 0x39, 0x97, +0x18, 0xa2, 0x18, 0xe7, 0x61, 0x82, 0xa3, 0xce, +0x3a, 0xfa, 0xdb, 0x77, 0x70, 0x7a, 0xfb, 0x55, +0xec, 0x87, 0x13, 0xb4, 0x87, 0x67, 0xc8, 0x27, +0x63, 0xd7, 0x9f, 0x14, 0x84, 0x26, 0x8c, 0x59, +0x30, 0x10, 0x94, 0xcf, 0x5a, 0x73, 0x22, 0xc4, +0x4d, 0x2b, 0x72, 0xbe, 0x16, 0x79, 0x8e, 0xc9, +0x78, 0x84, 0xa2, 0x15, 0xa0, 0xd3, 0x8e, 0xb1, +0xb2, 0xbc, 0x8c, 0x87, 0xd7, 0x0e, 0xf0, 0x30, +0x9f, 0x71, 0xc6, 0xb4, 0x41, 0x30, 0xe9, 0xab, +0x72, 0x85, 0xe6, 0xec, 0x79, 0x92, 0x17, 0xf8, +0x60, 0x14, 0xe0, 0xed, 0xe0, 0x1a, 0xc2, 0x6b, +0xd7, 0x71, 0x77, 0x39, 0xc0, 0xe8, 0xb4, 0x8f, +0x4f, 0x1f, 0x3f, 0x45, 0x31, 0xbc, 0x74, 0xd2, +0xae, 0x34, 0x29, 0x11, 0x81, 0xa2, 0xef, 0x44, +0xb4, 0x49, 0x6b, 0x40, 0xe6, 0x2f, 0x39, 0xef, +0x4e, 0x4e, 0x4e, 0x4a, 0xd7, 0x95, 0x92, 0x3a, +0x9a, 0xa4, 0x71, 0xca, 0x47, 0xdf, 0x86, 0xc3, +0xa1, 0x7b, 0x4f, 0x2a, 0xef, 0x7e, 0xbf, 0xef, +0xa4, 0x65, 0x9a, 0x47, 0x9c, 0xf9, 0xe1, 0x1a, +0x22, 0x62, 0xd8, 0x49, 0xe2, 0x96, 0xcc, 0x3e, +0x7d, 0xe3, 0xcc, 0x00, 0x95, 0x43, 0x44, 0x96, +0xca, 0x97, 0x92, 0x3f, 0x67, 0xfc, 0xe9, 0x37, +0x8f, 0x4f, 0xcf, 0xd3, 0x91, 0xb4, 0x4d, 0xfd, +0x40, 0x9a, 0x8b, 0x95, 0x95, 0x15, 0x7c, 0xf0, +0xc1, 0x07, 0x2e, 0xf0, 0x0e, 0x8f, 0x18, 0x47, +0xfd, 0x45, 0xfd, 0xe3, 0x98, 0xa0, 0x56, 0xcb, +0xed, 0x33, 0x37, 0xd2, 0x13, 0x7c, 0x7f, 0x3b, +0xc1, 0x28, 0x6f, 0x21, 0x0d, 0xdb, 0x38, 0x4b, +0x0b, 0xe4, 0x14, 0x73, 0xbb, 0x28, 0xb0, 0xdc, +0x8e, 0xa7, 0xf3, 0x4d, 0x6e, 0xda, 0x9c, 0x60, +0x71, 0x42, 0x49, 0xc4, 0x9a, 0x08, 0x00, 0x97, +0x4e, 0x03, 0x85, 0x58, 0xd1, 0x5a, 0x92, 0xeb, +0x8a, 0x2e, 0x3a, 0xe1, 0xeb, 0x49, 0xd6, 0x1f, +0x46, 0xe5, 0x75, 0x47, 0xbf, 0xe5, 0xfa, 0x23, +0x42, 0xc2, 0xeb, 0x27, 0xe9, 0x99, 0xe3, 0x6b, +0x95, 0xcf, 0xdb, 0x47, 0xeb, 0x80, 0xf6, 0x03, +0x8d, 0xf8, 0xd2, 0xcd, 0x75, 0x21, 0x33, 0x23, +0x10, 0x0e, 0x5a, 0x7a, 0x59, 0xa6, 0x86, 0x8f, +0x46, 0x28, 0x89, 0x88, 0x4b, 0x4d, 0x85, 0xb5, +0x1f, 0x35, 0x6d, 0x1f, 0x1f, 0x1b, 0x22, 0x9c, +0x94, 0x86, 0x47, 0x91, 0x93, 0x0c, 0x09, 0x6f, +0x33, 0x0f, 0x29, 0xcc, 0xf1, 0xa4, 0x34, 0x3e, +0xfc, 0x38, 0xfe, 0xd6, 0x78, 0xcd, 0x98, 0x8c, +0x70, 0xfb, 0xb5, 0xef, 0xbe, 0xb9, 0x35, 0x3e, +0x2d, 0xd9, 0x5b, 0x7d, 0x91, 0xb7, 0xa4, 0x4d, +0x56, 0x2e, 0x36, 0xda, 0x10, 0x7c, 0x84, 0x53, +0xda, 0xad, 0xf9, 0xa2, 0x97, 0xdc, 0xb9, 0x16, +0xe0, 0x84, 0x13, 0x46, 0x02, 0x9e, 0xc7, 0x17, +0xc8, 0x84, 0xe3, 0x64, 0x31, 0x2e, 0x72, 0x73, +0x92, 0x1b, 0x96, 0xc4, 0x87, 0x08, 0x07, 0x95, +0x47, 0xbf, 0x69, 0xc3, 0xd2, 0xa4, 0x17, 0xa9, +0xc2, 0x97, 0xdf, 0x64, 0x10, 0x19, 0x69, 0xc3, +0x27, 0xbc, 0x2d, 0xdc, 0x38, 0x13, 0x24, 0x09, +0xbd, 0xb4, 0x29, 0xa7, 0x69, 0x8a, 0xe5, 0xa5, +0x25, 0x44, 0xdb, 0xfb, 0xf8, 0xd9, 0xab, 0x7f, +0x13, 0xbf, 0x08, 0xae, 0xe1, 0x69, 0xd0, 0x2d, +0x4f, 0x6e, 0x39, 0x89, 0xf9, 0x26, 0xc6, 0x17, +0x33, 0x4f, 0xa3, 0xa9, 0x89, 0xf8, 0xc6, 0x47, +0xe9, 0xb8, 0xc4, 0x32, 0xe3, 0x44, 0xd3, 0x56, +0x88, 0xb3, 0xbc, 0x85, 0x07, 0x9b, 0xcf, 0x23, +0xe8, 0x6d, 0xe3, 0x3a, 0x46, 0xc8, 0xce, 0x4f, +0x91, 0x17, 0x53, 0x95, 0x7b, 0x18, 0xb7, 0x9d, +0xea, 0x5d, 0x32, 0x81, 0x9a, 0xf3, 0x99, 0x9c, +0xaf, 0xf4, 0xbf, 0x93, 0x74, 0x11, 0x06, 0x01, +0xda, 0xed, 0x36, 0x3a, 0xed, 0x36, 0x56, 0x6e, +0xbf, 0x84, 0xff, 0x39, 0xba, 0x85, 0x34, 0x60, +0x92, 0x0f, 0x97, 0x2c, 0x78, 0xbb, 0x09, 0x28, +0xea, 0xd6, 0x8c, 0xbb, 0x26, 0xa2, 0xfe, 0x56, +0xbc, 0x8d, 0xbd, 0x6b, 0x3d, 0xdc, 0x4c, 0x02, +0x74, 0x97, 0x96, 0x71, 0x76, 0xfc, 0x04, 0x47, +0x47, 0x47, 0x25, 0x1b, 0x31, 0x8d, 0x11, 0x11, +0x47, 0x39, 0x86, 0x34, 0xfe, 0x32, 0x20, 0x0c, +0x80, 0x52, 0x1e, 0x1e, 0x49, 0x90, 0xea, 0xa0, +0xb3, 0xeb, 0xfc, 0x36, 0x36, 0xae, 0x16, 0x97, +0xf3, 0x58, 0x32, 0x8c, 0x5c, 0xdb, 0xc6, 0x83, +0x21, 0x69, 0xd2, 0x39, 0x97, 0xc6, 0x69, 0xde, +0xf3, 0x3b, 0x05, 0x28, 0xaa, 0x1b, 0x5f, 0x17, +0x7c, 0x1e, 0x6b, 0x4e, 0xb1, 0x9c, 0x58, 0xf3, +0xf9, 0x4d, 0xf8, 0x73, 0xf3, 0x03, 0x11, 0x7f, +0x52, 0xd5, 0x73, 0x66, 0x42, 0x6a, 0x11, 0xce, +0xcf, 0xcf, 0x91, 0x65, 0x99, 0x8b, 0xd8, 0x77, +0x31, 0x1c, 0xe3, 0xfc, 0x72, 0x80, 0x28, 0x0c, +0xd0, 0x4e, 0x47, 0xf8, 0xd6, 0x4a, 0x8e, 0x6f, +0x2d, 0xa5, 0xb8, 0xd1, 0x6e, 0xa1, 0x15, 0xc5, +0xf8, 0x6c, 0x38, 0xd5, 0x5e, 0x4d, 0x72, 0x45, +0x5d, 0xdc, 0x62, 0x73, 0x81, 0x6f, 0xcc, 0x5c, +0x52, 0x27, 0xc2, 0xc2, 0xd3, 0x07, 0x8a, 0x64, +0xca, 0x99, 0x44, 0x5e, 0x1e, 0xdf, 0xc0, 0xa5, +0xc4, 0x2a, 0xe7, 0x27, 0xad, 0x35, 0x49, 0x5c, +0x69, 0xfd, 0x59, 0x4c, 0x87, 0x5b, 0xc3, 0x79, +0x59, 0x8d, 0xab, 0xcd, 0x7f, 0xbe, 0xde, 0x25, +0xe3, 0x21, 0x89, 0x60, 0xa0, 0x48, 0x9e, 0x12, +0x5f, 0x79, 0x66, 0xbf, 0xc4, 0x20, 0x31, 0x7c, +0xe8, 0x9b, 0x64, 0x1e, 0x80, 0x2a, 0xb1, 0x6f, +0x05, 0xd5, 0x76, 0x16, 0x9e, 0xf1, 0xb3, 0xda, +0xc7, 0x19, 0x03, 0xc9, 0x8c, 0xf0, 0x68, 0x6c, +0x12, 0x7f, 0xfa, 0x4e, 0xf8, 0xd3, 0x18, 0x50, +0xdd, 0xb2, 0xff, 0xf9, 0x3d, 0xf6, 0x72, 0xdc, +0x24, 0xc3, 0x48, 0x40, 0xf3, 0x6b, 0x26, 0xc9, +0x87, 0xfb, 0x6f, 0xfc, 0xe8, 0xcd, 0xd5, 0xf3, +0xc7, 0x15, 0xa2, 0x40, 0x0b, 0x4a, 0x2e, 0x06, +0xee, 0xdc, 0xa5, 0x39, 0x6f, 0xf1, 0x05, 0xcf, +0x17, 0xa0, 0xcf, 0xd6, 0xe9, 0xb3, 0xdf, 0x69, +0x12, 0xaf, 0xa6, 0x5a, 0x96, 0x44, 0x5c, 0xaa, +0x54, 0xf9, 0x06, 0x41, 0x1b, 0x8d, 0x8c, 0xb4, +0xa6, 0xa9, 0xe2, 0x35, 0x15, 0x3d, 0x97, 0x8e, +0xc9, 0xfe, 0xc9, 0x37, 0x5f, 0x5e, 0x2f, 0xdf, +0x40, 0x38, 0x71, 0x91, 0x6d, 0x93, 0x04, 0x9b, +0x88, 0x0f, 0xbd, 0xd7, 0xda, 0xcf, 0xfb, 0x9e, +0xbc, 0x93, 0x79, 0x9d, 0x92, 0x60, 0x6b, 0xe5, +0x11, 0xf4, 0x7a, 0x3d, 0xdc, 0xbb, 0xfb, 0x5b, +0xf8, 0x30, 0xb9, 0x3e, 0x57, 0x29, 0x4a, 0x2e, +0x99, 0x4f, 0x72, 0x39, 0x11, 0xdd, 0x04, 0x66, +0x77, 0x34, 0x73, 0xd5, 0xa4, 0xb0, 0xbd, 0x99, +0x8b, 0x59, 0x70, 0xa1, 0x69, 0x10, 0xe1, 0x68, +0xe5, 0x3a, 0xee, 0x5f, 0xbb, 0x83, 0x97, 0x3a, +0x19, 0x8a, 0xa7, 0x8f, 0x66, 0x9a, 0x85, 0x56, +0xa9, 0x4f, 0x34, 0x86, 0x47, 0x32, 0x80, 0x7c, +0x5c, 0x29, 0x4d, 0xbb, 0xdd, 0x41, 0x91, 0xe7, +0x53, 0x42, 0xbe, 0xb2, 0x82, 0xe8, 0xd6, 0x57, +0xf1, 0x8b, 0xe5, 0x5b, 0x73, 0x09, 0xcc, 0x6a, +0x37, 0xbd, 0xe3, 0x1b, 0x05, 0x2d, 0xb0, 0x99, +0xaa, 0xee, 0x7c, 0x92, 0xe2, 0x4f, 0x86, 0x6d, +0x3c, 0x5c, 0xde, 0xc5, 0xc3, 0xa5, 0xeb, 0xb8, +0xd5, 0x5b, 0xc6, 0x52, 0x3a, 0xc2, 0x70, 0x3c, +0xc1, 0xc9, 0xf1, 0x53, 0x1c, 0x9f, 0x5d, 0xe0, +0xc9, 0xe3, 0xcf, 0x4b, 0x4c, 0x1f, 0xc7, 0x91, +0xc7, 0x52, 0x97, 0xf3, 0x85, 0xdb, 0xd9, 0x69, +0x6e, 0xa5, 0x69, 0xea, 0xa4, 0x7a, 0x72, 0x3c, +0x23, 0xc2, 0x4e, 0x63, 0x4f, 0xf5, 0x70, 0x66, +0x4f, 0xae, 0x2f, 0xb2, 0xed, 0x4b, 0x3f, 0x18, +0xde, 0x77, 0x9c, 0xd8, 0x27, 0x49, 0x82, 0x76, +0xd2, 0xc5, 0xe0, 0xf2, 0xd2, 0xad, 0xa9, 0xa3, +0xa3, 0x23, 0x3c, 0x7e, 0xfc, 0x18, 0x8f, 0x1e, +0x3d, 0x2a, 0xdd, 0x41, 0xc0, 0x7d, 0x09, 0xb8, +0xc6, 0x4c, 0x5b, 0x87, 0xbc, 0x5f, 0x68, 0xcd, +0x71, 0xed, 0x86, 0x64, 0xe6, 0xe9, 0xec, 0x3a, +0x80, 0x0a, 0x23, 0xcd, 0x19, 0x23, 0x6e, 0xd3, +0xcf, 0xb2, 0x0c, 0xc3, 0xc1, 0x25, 0x50, 0xe4, +0x98, 0x4c, 0x26, 0xc8, 0xb2, 0x0c, 0x61, 0xab, +0x85, 0x47, 0x1f, 0xbd, 0x8f, 0xf5, 0xb3, 0xc7, +0xf8, 0xc1, 0x6a, 0x86, 0x1f, 0x6c, 0x46, 0x38, +0x69, 0x75, 0xf0, 0x59, 0x1a, 0x96, 0x37, 0x76, +0xdf, 0xfc, 0xa0, 0xff, 0x72, 0xb3, 0xe7, 0x44, +0x9c, 0xdb, 0x68, 0x29, 0x0d, 0x97, 0x9c, 0x39, +0xb1, 0xe1, 0x6b, 0x8b, 0x33, 0xca, 0xb2, 0xfe, +0x96, 0x60, 0xb0, 0x65, 0x5c, 0x73, 0x29, 0x99, +0xd3, 0x9c, 0xe5, 0xea, 0x7d, 0x6e, 0xe7, 0xae, +0x9b, 0xff, 0xda, 0xda, 0xb7, 0x24, 0x73, 0x0a, +0x33, 0x4b, 0xc0, 0xe3, 0xc9, 0x33, 0xbf, 0x94, +0x52, 0x1f, 0x72, 0xa2, 0xc6, 0x35, 0x65, 0x5c, +0x6d, 0xef, 0x93, 0xec, 0xa9, 0x6e, 0xbe, 0xdf, +0x34, 0x19, 0x3f, 0x4b, 0x33, 0x20, 0x25, 0x78, +0xc9, 0x1c, 0x58, 0xf8, 0xf3, 0xf1, 0xf5, 0xed, +0x97, 0x52, 0x42, 0xa7, 0xfe, 0x92, 0x6d, 0x51, +0xe6, 0x57, 0xb8, 0xfd, 0xda, 0xf7, 0xde, 0xec, +0x3c, 0x79, 0xa0, 0x3a, 0x71, 0x71, 0xe2, 0x25, +0xa5, 0x66, 0x4d, 0x7a, 0x95, 0x0b, 0x9e, 0x4b, +0x0b, 0x83, 0xe1, 0xc8, 0x79, 0xbe, 0x52, 0x1a, +0x5e, 0xa7, 0x24, 0x84, 0x3e, 0xbb, 0x31, 0x97, +0x5a, 0x49, 0x32, 0x96, 0xc4, 0x53, 0x63, 0x04, +0x34, 0x09, 0xd6, 0xe7, 0xac, 0xa7, 0x49, 0xe5, +0xf4, 0x5e, 0xda, 0x61, 0xe5, 0x7f, 0x69, 0x22, +0xe0, 0x78, 0xd3, 0x9f, 0xac, 0x9b, 0xff, 0xe6, +0x6a, 0x47, 0xee, 0x28, 0xc7, 0xc7, 0x80, 0xfe, +0xd3, 0x11, 0x1f, 0xa9, 0xbe, 0xd5, 0x1c, 0xfd, +0x78, 0x7f, 0x53, 0x9d, 0x9d, 0xee, 0x12, 0xd6, +0xbe, 0xf6, 0x4d, 0xfc, 0xeb, 0x9b, 0xdf, 0x99, +0x7b, 0x66, 0x72, 0x89, 0x83, 0x54, 0x43, 0x5c, +0x95, 0x27, 0x25, 0x53, 0x52, 0x1d, 0xc9, 0xc9, +0xca, 0x17, 0x2b, 0xff, 0x9f, 0x33, 0x67, 0x15, +0x7e, 0xe5, 0x24, 0xdf, 0x20, 0x58, 0x8c, 0xe9, +0x34, 0x88, 0xf1, 0xf4, 0xda, 0x73, 0xb8, 0xd5, +0x5b, 0x46, 0x70, 0xd9, 0x07, 0x26, 0x63, 0x84, +0x41, 0xe0, 0x1c, 0xf6, 0xa4, 0x47, 0xff, 0x24, +0xcb, 0xd1, 0x69, 0xcf, 0x2f, 0x3d, 0xb1, 0x18, +0xad, 0x20, 0x8c, 0x9c, 0xa3, 0x5f, 0x92, 0x24, +0x58, 0xdd, 0xb8, 0x86, 0x77, 0x57, 0x9f, 0xc3, +0x20, 0xcd, 0xab, 0x0b, 0x93, 0x6f, 0x82, 0xda, +0xe2, 0xa2, 0xb4, 0x5c, 0xaa, 0x88, 0x3b, 0x78, +0x3c, 0x01, 0x3e, 0x38, 0x9b, 0xe0, 0xa7, 0xa3, +0x0e, 0xde, 0xed, 0xec, 0xa0, 0xb3, 0xb9, 0x8b, +0x51, 0x67, 0x09, 0x61, 0x36, 0x41, 0x71, 0x3e, +0x55, 0x3d, 0x1f, 0x0f, 0x46, 0x28, 0x26, 0x63, +0x9c, 0x0d, 0x46, 0xc8, 0x66, 0x26, 0x85, 0xf6, +0xd2, 0x32, 0x8a, 0x2c, 0xc3, 0xf1, 0x60, 0x8c, +0x6e, 0x37, 0xc1, 0xd9, 0x2c, 0xe4, 0x2b, 0xe1, +0x3e, 0xce, 0x0b, 0x4c, 0x66, 0xde, 0xec, 0x52, +0xbb, 0x14, 0x45, 0x11, 0x46, 0x79, 0x81, 0xde, +0xec, 0x2e, 0x70, 0xbe, 0xae, 0x69, 0xcd, 0xd0, +0x1f, 0x9f, 0x87, 0xee, 0xc4, 0xc2, 0xec, 0x22, +0x15, 0x2a, 0x8b, 0xee, 0x38, 0x27, 0x95, 0x7c, +0xa7, 0xd3, 0xc1, 0xc5, 0xc5, 0x85, 0x73, 0x64, +0x7b, 0xfc, 0xf9, 0xe7, 0xce, 0x47, 0x80, 0x24, +0x64, 0x62, 0x30, 0xa5, 0x06, 0x41, 0xf3, 0x2f, +0xa1, 0x38, 0x0d, 0x72, 0x3d, 0xc8, 0x71, 0xe5, +0x27, 0x05, 0xb4, 0xf3, 0xec, 0xf4, 0x8d, 0xd2, +0x01, 0x73, 0xc6, 0x9d, 0x9b, 0x5a, 0xf8, 0x09, +0x08, 0x2a, 0x9b, 0x9c, 0xfc, 0x08, 0xf7, 0xde, +0xfa, 0x1a, 0x82, 0x20, 0xc0, 0x7a, 0x7a, 0x81, +0x1f, 0x6f, 0x46, 0xd8, 0x8a, 0x0a, 0xec, 0x24, +0x21, 0x06, 0x08, 0x71, 0x9a, 0xce, 0x9c, 0xab, +0x5a, 0x42, 0x4b, 0xc3, 0x21, 0x0c, 0x51, 0xb2, +0x63, 0x6b, 0x44, 0x40, 0x4a, 0xdb, 0xd2, 0x7c, +0x23, 0x25, 0x5b, 0xb7, 0x87, 0x8a, 0x1b, 0xb4, +0x64, 0xbd, 0xf4, 0xce, 0xd9, 0x91, 0x99, 0x44, +0xc8, 0x2f, 0x1f, 0x91, 0x73, 0x59, 0xaa, 0xfa, +0x89, 0x60, 0x56, 0x24, 0x78, 0x46, 0x50, 0xf8, +0x5a, 0x96, 0x66, 0x05, 0x8b, 0xe1, 0x25, 0x42, +0xc4, 0xd7, 0x18, 0xa5, 0xcf, 0xd3, 0x32, 0xae, +0xbc, 0x0f, 0x69, 0xbf, 0xe1, 0xfd, 0x24, 0xfd, +0x0a, 0x78, 0x1a, 0x2a, 0x9b, 0xdb, 0xa8, 0x79, +0x5a, 0xab, 0xff, 0x28, 0x1f, 0x4f, 0xcf, 0xfb, +0x4d, 0x32, 0x65, 0xbc, 0xbd, 0x57, 0xc1, 0x5f, +0xaa, 0xee, 0xa5, 0x06, 0xc1, 0x1a, 0x57, 0xc2, +0x81, 0xc5, 0xc6, 0x8f, 0x72, 0xe5, 0xa8, 0x92, +0x76, 0xd6, 0x58, 0x9e, 0xb1, 0xd6, 0xf2, 0x68, +0xdf, 0xa9, 0x9c, 0x38, 0x0a, 0x4b, 0x2a, 0x34, +0xeb, 0xac, 0x74, 0xd3, 0x20, 0x31, 0xfc, 0x18, +0x92, 0x2f, 0xe8, 0x8a, 0x2c, 0xaf, 0xee, 0x2c, +0xb3, 0x6c, 0x2f, 0x3f, 0x37, 0x6f, 0xe1, 0xac, +0x9d, 0xc1, 0x26, 0x15, 0x20, 0x3f, 0xfb, 0x2a, +0xcb, 0xe1, 0x65, 0xf0, 0x88, 0x59, 0xbc, 0x6d, +0x12, 0x67, 0x39, 0x46, 0x80, 0x1e, 0x5c, 0x44, +0x6b, 0xb7, 0x05, 0x49, 0xa7, 0x83, 0x87, 0xd7, +0xee, 0x60, 0x10, 0xb1, 0x34, 0xda, 0xed, 0x51, +0x34, 0x91, 0x34, 0xdb, 0x9e, 0xf6, 0xbd, 0x64, +0xf7, 0x13, 0xef, 0x7c, 0xe9, 0xf9, 0x7f, 0xe2, +0xa6, 0x83, 0x08, 0x4f, 0xa3, 0x25, 0xfc, 0xee, +0xee, 0xb7, 0xb1, 0xbf, 0xfb, 0x35, 0x1c, 0x1c, +0xfe, 0x02, 0xf1, 0x87, 0x3f, 0xc3, 0xc9, 0xc3, +0xfb, 0x00, 0xa6, 0x2a, 0x77, 0x3e, 0xaf, 0xe2, +0x30, 0xa8, 0xc4, 0x47, 0xd0, 0x7e, 0x67, 0x93, +0x31, 0xe2, 0x90, 0x11, 0x85, 0xac, 0x85, 0x30, +0x9f, 0x39, 0x3e, 0xf1, 0x0d, 0x2d, 0xcb, 0xe6, +0x4c, 0x08, 0xe1, 0xce, 0x35, 0x0b, 0x32, 0x9d, +0x6c, 0x23, 0x80, 0xa7, 0xe3, 0x02, 0x4f, 0x87, +0x23, 0xbc, 0x75, 0xd9, 0xc1, 0x72, 0xb0, 0x8a, +0xdd, 0xce, 0x2a, 0xda, 0xcb, 0xbb, 0xb8, 0x15, +0x4e, 0x70, 0x2d, 0x3d, 0xc7, 0xd6, 0xe4, 0x0c, +0xd7, 0x8f, 0x3f, 0xc3, 0x23, 0x11, 0x0c, 0xa6, +0xdb, 0xed, 0x22, 0xbb, 0x28, 0x4b, 0x9c, 0x49, +0x92, 0x20, 0x68, 0x77, 0x54, 0x6f, 0x7d, 0xfe, +0x47, 0x69, 0xeb, 0xe2, 0x1a, 0x48, 0xc2, 0xa8, +0x99, 0x28, 0xb8, 0xcd, 0x9b, 0xc2, 0xb2, 0x02, +0x70, 0xe7, 0xe4, 0x89, 0xf8, 0x4b, 0x87, 0x4f, +0x8e, 0x83, 0x16, 0x9f, 0x82, 0xce, 0x83, 0x4b, +0x3c, 0x24, 0x0e, 0x5c, 0xdd, 0xce, 0x63, 0x37, +0xc8, 0xb9, 0x2d, 0x23, 0x2c, 0xf2, 0x67, 0xeb, +0x4c, 0x3b, 0xd9, 0xf1, 0x2b, 0x7d, 0x76, 0x71, +0x06, 0xf2, 0xca, 0xf8, 0xfa, 0x24, 0xc3, 0x6b, +0x49, 0x17, 0x7f, 0x6b, 0x29, 0xc6, 0xd3, 0xde, +0x1a, 0xfe, 0xc7, 0xf3, 0x55, 0xfc, 0x71, 0x7f, +0x16, 0xbc, 0xa5, 0xbb, 0x02, 0x0c, 0xce, 0xa7, +0xff, 0x47, 0xac, 0x6f, 0x69, 0x0d, 0xf1, 0xf5, +0x44, 0x6b, 0x8a, 0x9c, 0xe0, 0xe4, 0xbc, 0xa1, +0x67, 0x9e, 0x86, 0xbf, 0x97, 0x69, 0xb4, 0xf9, +0xc7, 0xd3, 0xd2, 0x7f, 0x2a, 0x4f, 0x3a, 0x64, +0xc9, 0x7c, 0x3c, 0x34, 0xa9, 0xac, 0x4f, 0xfa, +0xc8, 0x64, 0x59, 0x79, 0x9e, 0xfb, 0xf6, 0x09, +0x6d, 0x7d, 0x70, 0xfc, 0xf9, 0x7b, 0xab, 0x7e, +0xde, 0x97, 0x22, 0x02, 0x5a, 0xa9, 0x3f, 0xb5, +0xfe, 0xe5, 0xdf, 0x64, 0x9d, 0x7c, 0xac, 0x64, +0xbf, 0xcb, 0xfe, 0x2b, 0x69, 0x17, 0x22, 0x7d, +0x6f, 0xe3, 0xe3, 0x4c, 0xcf, 0x12, 0x7f, 0x6d, +0xcc, 0xe5, 0xb8, 0xca, 0x7c, 0xb2, 0x3d, 0x04, +0x71, 0x07, 0x51, 0x10, 0x04, 0xde, 0xa0, 0x27, +0x57, 0x01, 0x5f, 0xa0, 0x15, 0x99, 0xc6, 0x17, +0xd0, 0xc4, 0x47, 0x78, 0xb4, 0x72, 0xac, 0x4d, +0x5b, 0x96, 0xc9, 0x37, 0x00, 0x0b, 0x07, 0x5e, +0x8e, 0x0c, 0xa2, 0x61, 0xf5, 0x8b, 0x2f, 0x78, +0x0c, 0x11, 0x69, 0x52, 0x5d, 0xf2, 0xcd, 0x4d, +0x32, 0x48, 0xbe, 0x40, 0x2d, 0x56, 0xfb, 0x00, +0x3b, 0x12, 0x98, 0x6c, 0xbb, 0x35, 0x1e, 0xd1, +0xfa, 0x06, 0x3e, 0xd8, 0x78, 0xb1, 0x3a, 0xb1, +0x9d, 0x37, 0x6b, 0x54, 0x9d, 0x3c, 0x1c, 0xf8, +0x24, 0xa3, 0x67, 0xf9, 0x5b, 0x32, 0x04, 0xbc, +0x1e, 0x79, 0xfd, 0x24, 0x4f, 0x2b, 0x36, 0x9c, +0xa0, 0x9d, 0xe0, 0xbd, 0x49, 0x8c, 0xf7, 0x76, +0xde, 0xc0, 0xcd, 0x1b, 0xaf, 0xe1, 0x5b, 0xef, +0xfd, 0x53, 0x0c, 0x3e, 0xfc, 0x05, 0x9e, 0x7e, +0xfe, 0xc8, 0x3b, 0x46, 0xb2, 0x4f, 0x2d, 0x66, +0x35, 0x38, 0x7d, 0x8a, 0xf6, 0xf5, 0x11, 0x10, +0xae, 0x56, 0x17, 0xaf, 0xd6, 0xa6, 0x20, 0xaa, +0x56, 0xc2, 0xd3, 0xc9, 0x76, 0xce, 0xda, 0x75, +0x91, 0x01, 0x1f, 0xe4, 0x21, 0x30, 0x09, 0xf0, +0x76, 0xb0, 0x0c, 0x60, 0x19, 0xcb, 0xf1, 0x0d, +0xbc, 0x7c, 0xf3, 0x25, 0x7c, 0xb3, 0xd5, 0x47, +0xfb, 0xf4, 0x31, 0x92, 0xc9, 0x00, 0xad, 0xd3, +0x27, 0xf8, 0xfc, 0xf8, 0x10, 0x9d, 0x00, 0x2e, +0x64, 0xec, 0x68, 0x34, 0x72, 0x71, 0xcd, 0x29, +0x94, 0xab, 0x45, 0x2c, 0x25, 0x21, 0x97, 0x7d, +0x63, 0xf5, 0x13, 0xc5, 0x78, 0xa7, 0x34, 0xc3, +0xe1, 0xd0, 0x05, 0x8b, 0x91, 0xfd, 0xc8, 0xd7, +0x95, 0x4a, 0x10, 0xd9, 0x37, 0xce, 0xac, 0x72, +0x1c, 0x38, 0xa3, 0xa1, 0xad, 0xbb, 0xba, 0x38, +0xfd, 0x32, 0x2d, 0x0f, 0x20, 0x24, 0xdb, 0x2b, +0xc7, 0x5e, 0x46, 0xa9, 0x23, 0xe0, 0xf1, 0xe5, +0x79, 0x60, 0x9f, 0x8d, 0x8d, 0x0d, 0xf4, 0x96, +0x27, 0xf8, 0xaf, 0xd6, 0x73, 0x1c, 0xe7, 0x1b, +0xf8, 0xe0, 0x74, 0x34, 0x25, 0xe0, 0x41, 0x34, +0x25, 0xe8, 0x9c, 0x40, 0xf2, 0xf1, 0xe7, 0xf3, +0x85, 0xd2, 0x58, 0xf3, 0x04, 0xa8, 0x12, 0x35, +0x8d, 0x08, 0xd1, 0xfc, 0xb4, 0xe6, 0xa3, 0x55, +0x9e, 0x46, 0x08, 0xf9, 0x1c, 0x95, 0x78, 0x69, +0x6d, 0x91, 0xeb, 0xc1, 0x92, 0x70, 0x35, 0xa6, +0x84, 0xf2, 0x71, 0x46, 0xc4, 0xaa, 0x8b, 0x33, +0x1a, 0xfc, 0x3b, 0xdf, 0x4f, 0xb4, 0xfe, 0xd4, +0x70, 0xe2, 0x7d, 0x06, 0xcc, 0x99, 0x73, 0x8e, +0xa7, 0xe5, 0x8c, 0x28, 0x71, 0xd5, 0xae, 0xcd, +0x95, 0xf8, 0x73, 0x86, 0x45, 0xab, 0x4b, 0x12, +0x75, 0xc9, 0xe8, 0x48, 0x86, 0x84, 0x33, 0x5b, +0x82, 0x71, 0x6a, 0x7d, 0xfd, 0x3f, 0xff, 0x6f, +0x8b, 0xdd, 0xfb, 0x7f, 0x86, 0xa0, 0xdd, 0x99, +0x86, 0xb4, 0x54, 0x88, 0x87, 0xc5, 0x35, 0x37, +0x61, 0x02, 0x34, 0x49, 0x5d, 0x96, 0x5f, 0x07, +0x1a, 0xb1, 0x96, 0x52, 0xad, 0xc6, 0xa9, 0xfb, +0xb8, 0x7d, 0xde, 0x06, 0x4b, 0x0a, 0xb7, 0x70, +0xe7, 0xe5, 0xd3, 0xa6, 0x94, 0x24, 0x49, 0x25, +0xf2, 0x98, 0x8c, 0x0d, 0xef, 0x23, 0xd6, 0xf4, +0x9b, 0x54, 0x95, 0x52, 0x92, 0xe4, 0xed, 0xe3, +0xf9, 0x69, 0x73, 0xe5, 0x91, 0xc1, 0xea, 0xb4, +0x0f, 0xbc, 0x9c, 0xe5, 0xd5, 0x35, 0xac, 0xff, +0xc6, 0xdf, 0xc2, 0x3f, 0xde, 0x79, 0xa3, 0xba, +0x09, 0x69, 0x84, 0x76, 0x36, 0x71, 0x54, 0x02, +0x4d, 0x12, 0x2d, 0x07, 0x2d, 0x9d, 0xe4, 0xaa, +0xb5, 0x4d, 0xc0, 0xfa, 0x2e, 0xea, 0xd8, 0x8e, +0x32, 0xbc, 0xf6, 0xd9, 0xbf, 0x46, 0xe7, 0xdf, +0xfc, 0x0e, 0xce, 0xce, 0x2f, 0x5c, 0x34, 0x39, +0xba, 0x40, 0x85, 0x4b, 0xe8, 0x5a, 0x9f, 0xf0, +0xf1, 0x09, 0xa3, 0x18, 0xb7, 0xf6, 0x6f, 0xe2, +0x77, 0xde, 0xf8, 0xbb, 0x78, 0x90, 0xb5, 0xab, +0x12, 0x0f, 0xef, 0x13, 0xf9, 0xbb, 0x0e, 0x7f, +0x4a, 0xcb, 0x25, 0x7b, 0xde, 0x16, 0xfe, 0x3d, +0x88, 0xb0, 0x1c, 0x87, 0x38, 0x48, 0x80, 0xfd, +0xe5, 0x18, 0xab, 0x17, 0x4f, 0x10, 0x8d, 0xa6, +0xa6, 0x96, 0xad, 0xc9, 0x19, 0x70, 0x76, 0x8c, +0xee, 0xf8, 0x02, 0x6d, 0x11, 0xd2, 0x33, 0x59, +0x5e, 0x45, 0x6f, 0x75, 0xb9, 0x32, 0x0f, 0x7d, +0x17, 0xf5, 0x90, 0x17, 0x3d, 0xbf, 0xfc, 0x05, +0x40, 0xe5, 0xe2, 0x18, 0xea, 0x2b, 0x49, 0xf8, +0x24, 0x21, 0x96, 0x9a, 0xa7, 0x3a, 0x86, 0x92, +0xd6, 0x90, 0x0c, 0xeb, 0x2a, 0xc7, 0x47, 0xae, +0x17, 0xfe, 0x2c, 0xeb, 0xd7, 0x34, 0x15, 0xda, +0xb8, 0xcb, 0x32, 0x24, 0xf4, 0x7a, 0x3d, 0x8c, +0xb2, 0x1c, 0x3b, 0x9b, 0xd7, 0x5c, 0x5a, 0x0a, +0xc5, 0x9b, 0x24, 0x09, 0x8a, 0x30, 0xc6, 0xf9, +0xe6, 0x3e, 0xfe, 0x9f, 0xa7, 0xeb, 0xf8, 0xe0, +0xdc, 0x60, 0x76, 0x35, 0xa2, 0xee, 0x63, 0x0e, +0x7d, 0x5e, 0xed, 0xda, 0x33, 0xe5, 0x97, 0xcf, +0x7c, 0x9e, 0x59, 0x75, 0x4b, 0x82, 0x22, 0xe7, +0x2f, 0x27, 0x90, 0xbe, 0x35, 0x5c, 0x37, 0xbf, +0xad, 0xf2, 0x35, 0xe6, 0x5e, 0xe2, 0x6a, 0xad, +0x97, 0xba, 0xfe, 0x95, 0xfe, 0x38, 0x16, 0x1e, +0xb2, 0xff, 0xea, 0xfa, 0x5b, 0x32, 0x01, 0x12, +0x7f, 0xad, 0xcd, 0x4d, 0xc6, 0xd6, 0x37, 0x9e, +0xfc, 0x9d, 0x35, 0x96, 0x59, 0x36, 0x95, 0xcc, +0x01, 0xa8, 0x84, 0x1c, 0xd0, 0xd5, 0xeb, 0x3e, +0xa2, 0xa4, 0x49, 0x06, 0xf4, 0x3c, 0x49, 0x33, +0x84, 0x51, 0x8c, 0x2c, 0x9d, 0x20, 0x8c, 0x62, +0xc4, 0x51, 0x88, 0x26, 0xc0, 0xb9, 0x6c, 0x8e, +0x4b, 0x9d, 0x6a, 0x9f, 0xe7, 0xf5, 0x31, 0x29, +0xb2, 0xad, 0x32, 0xaf, 0xb6, 0x59, 0x34, 0xd9, +0x18, 0xb8, 0xb4, 0xc4, 0x43, 0x4a, 0xca, 0x32, +0xb8, 0xe4, 0xe2, 0xc3, 0xd9, 0x02, 0x4e, 0xc8, +0x65, 0x7f, 0xd4, 0x99, 0x17, 0x56, 0x97, 0x97, +0x70, 0x6f, 0xf7, 0x6b, 0x00, 0x37, 0xfb, 0xd1, +0x44, 0x25, 0x0e, 0x30, 0x0c, 0x67, 0x76, 0x31, +0xa1, 0xea, 0xa2, 0x85, 0x45, 0xe9, 0x35, 0x87, +0x14, 0xa0, 0x2a, 0xdd, 0xf2, 0x89, 0x2d, 0x09, +0x1a, 0x71, 0xfc, 0xe2, 0x82, 0x02, 0x35, 0x96, +0x74, 0x18, 0xe2, 0x38, 0xcb, 0xf1, 0x2f, 0xb7, +0x5f, 0xc7, 0x6f, 0xde, 0x7e, 0x8c, 0xce, 0x47, +0x3f, 0xc7, 0xe5, 0xe9, 0x54, 0xd5, 0x1b, 0xcf, +0xc2, 0x28, 0x4e, 0xb2, 0xdc, 0x94, 0xc4, 0xe5, +0x7b, 0x62, 0x04, 0x30, 0xb8, 0x04, 0xda, 0xed, +0x39, 0x4e, 0x9a, 0x7a, 0x5d, 0x53, 0x4b, 0x3a, +0x47, 0xbf, 0xb0, 0xca, 0x59, 0x13, 0xf0, 0x67, +0xed, 0x7c, 0xea, 0x0c, 0x2e, 0x72, 0xe0, 0xad, +0xb3, 0x0c, 0x6f, 0x5d, 0x02, 0xcb, 0xc1, 0x1a, +0x80, 0x35, 0xac, 0x74, 0x22, 0x6c, 0x47, 0x97, +0xb8, 0xb9, 0xf3, 0x0a, 0xce, 0xcf, 0xcf, 0xb0, +0xd7, 0x1a, 0x63, 0x6b, 0x72, 0x82, 0xde, 0x64, +0x16, 0x9a, 0x75, 0x70, 0x8c, 0x7b, 0xf7, 0xee, +0xa1, 0xd5, 0xe9, 0xa2, 0xd3, 0x2a, 0xdb, 0x71, +0x7d, 0x66, 0x33, 0xa9, 0x46, 0xa7, 0xf7, 0xda, +0x6f, 0x39, 0xdf, 0x39, 0x58, 0xb1, 0xe8, 0xeb, +0x34, 0x74, 0xda, 0x5c, 0xe7, 0x52, 0xb5, 0x26, +0x61, 0xcb, 0x79, 0xcc, 0x71, 0xd2, 0x98, 0x67, +0x6d, 0xcf, 0x90, 0x26, 0x31, 0xde, 0x5e, 0x79, +0x9f, 0x02, 0xef, 0x03, 0xba, 0xc5, 0x6d, 0x63, +0x63, 0x03, 0x2b, 0x4f, 0xee, 0xe3, 0x7f, 0x57, +0x7c, 0x86, 0x3f, 0x5e, 0xbd, 0x89, 0xb7, 0xc6, +0x31, 0x3e, 0xc9, 0xbb, 0xd3, 0x78, 0xef, 0x7c, +0xfe, 0x6a, 0xc0, 0x09, 0x26, 0xad, 0x2d, 0xb9, +0x9e, 0x8c, 0xb9, 0x51, 0x99, 0x7f, 0x72, 0x6e, +0x6a, 0x6b, 0x46, 0x9a, 0x89, 0xa4, 0x94, 0xcf, +0xdf, 0x53, 0x19, 0x3e, 0x66, 0x55, 0xaa, 0xd7, +0xe5, 0x9c, 0xe6, 0x12, 0xae, 0x56, 0xbe, 0xb5, +0xbe, 0xa5, 0x2a, 0x9a, 0x70, 0x91, 0x52, 0xad, +0xaf, 0x7f, 0xa9, 0x3f, 0x65, 0x9f, 0x69, 0xaa, +0x78, 0x2e, 0x31, 0x5b, 0x1a, 0x42, 0xaa, 0x93, +0xf7, 0x75, 0x9e, 0xea, 0xf8, 0xfb, 0x18, 0x97, +0xd2, 0xe9, 0x9e, 0xb0, 0x4a, 0xf8, 0xe5, 0x78, +0xf2, 0xf2, 0x35, 0x8d, 0xa5, 0x10, 0x16, 0xa2, +0x28, 0x2c, 0x13, 0x54, 0x9f, 0x6d, 0x98, 0x9e, +0x7d, 0xaa, 0x6d, 0xb9, 0x40, 0xfb, 0xfd, 0x3e, +0x26, 0x69, 0xe6, 0x08, 0xb8, 0x56, 0xa6, 0x06, +0x4d, 0x54, 0xf6, 0x72, 0x91, 0x6b, 0x0b, 0x5e, +0x5b, 0xa0, 0xd6, 0x26, 0xa3, 0x49, 0x0d, 0x16, +0xd7, 0xae, 0x11, 0x6e, 0x5e, 0x9f, 0x4c, 0x27, +0x55, 0x92, 0x75, 0x1a, 0x0a, 0x8b, 0x89, 0xd2, +0x08, 0xb2, 0x75, 0x75, 0x66, 0x5d, 0xfb, 0x92, +0x24, 0x41, 0xef, 0xfa, 0x2e, 0x7e, 0x8a, 0x64, +0x3e, 0xc9, 0xb5, 0x0d, 0xc4, 0xe2, 0x70, 0xb5, +0x09, 0x4f, 0x93, 0x4f, 0xe3, 0xda, 0xb5, 0x89, +0x2d, 0x19, 0x04, 0x39, 0x89, 0xe5, 0x7b, 0x31, +0xf9, 0xd3, 0x70, 0x7a, 0xe9, 0xc5, 0x9f, 0x3e, +0xff, 0x1b, 0xf8, 0xf5, 0xe3, 0x07, 0xb8, 0x3c, +0x3d, 0x29, 0xb5, 0x93, 0x88, 0xba, 0x6c, 0xbb, +0x9c, 0x2b, 0x34, 0x37, 0x8f, 0x47, 0x29, 0xf2, +0x38, 0xa9, 0xf6, 0x81, 0xb6, 0xb9, 0x4a, 0x3c, +0xb9, 0x5a, 0xde, 0xb7, 0x21, 0x6b, 0xe7, 0x52, +0x2b, 0xc1, 0x44, 0xe6, 0x76, 0xba, 0x8b, 0xd9, +0xb7, 0x8b, 0xd1, 0x08, 0x8f, 0xe2, 0x0e, 0x7e, +0xfe, 0xd9, 0x39, 0x10, 0x27, 0x00, 0x12, 0x60, +0xd2, 0xc1, 0xf2, 0x8c, 0x89, 0xbb, 0xd3, 0x1b, +0xe3, 0x87, 0x6b, 0x8f, 0x70, 0xfc, 0xe9, 0x47, +0x88, 0xee, 0xfd, 0xa2, 0x32, 0x07, 0xb5, 0xf9, +0xa5, 0xcd, 0xeb, 0x26, 0xd0, 0xd4, 0x8c, 0xe6, +0xdb, 0x4b, 0x34, 0xa2, 0x29, 0xcb, 0xa9, 0x5b, +0x83, 0xf2, 0xb7, 0xb6, 0x7f, 0x59, 0xcc, 0xad, +0x4f, 0x92, 0x97, 0x7b, 0x1a, 0xbf, 0xe5, 0xad, +0xd7, 0xeb, 0x61, 0x34, 0x1a, 0xe1, 0xf8, 0xf8, +0xd8, 0x31, 0xd1, 0xdf, 0xeb, 0x8d, 0xf0, 0xcd, +0x34, 0xc3, 0xc9, 0xca, 0x75, 0xf4, 0x7b, 0x9b, +0xf8, 0xf9, 0x60, 0x88, 0xb7, 0xc3, 0x36, 0x9e, +0x8e, 0x0b, 0xff, 0xfc, 0x97, 0x44, 0x51, 0x9b, +0x13, 0x1a, 0xe1, 0xa3, 0x75, 0x60, 0x05, 0x2d, +0xd1, 0xb4, 0x66, 0x92, 0x28, 0xf0, 0x72, 0x24, +0xb1, 0xb0, 0xe6, 0xa7, 0x0f, 0x27, 0x9e, 0x96, +0xaf, 0x07, 0x5e, 0xbe, 0x5c, 0x1f, 0xd6, 0xfa, +0xa6, 0xfc, 0x54, 0xbe, 0xaf, 0xbe, 0x26, 0xfd, +0xab, 0x31, 0x36, 0xbe, 0x7e, 0x93, 0xfd, 0x47, +0x78, 0x6b, 0xcc, 0x95, 0xb6, 0x7e, 0x09, 0xea, +0xca, 0x97, 0x69, 0xb4, 0xf6, 0xc9, 0xfe, 0x92, +0x69, 0x66, 0x65, 0x84, 0xdb, 0xaf, 0x7d, 0xef, +0xcd, 0xe5, 0x93, 0x47, 0x00, 0xaa, 0xc7, 0x3d, +0x80, 0x72, 0xcc, 0x71, 0xcd, 0xa3, 0x9d, 0x3c, +0xc9, 0xf9, 0xc4, 0x97, 0xe7, 0xa5, 0x8b, 0x3c, +0x47, 0x81, 0x79, 0x60, 0x0a, 0xee, 0xd5, 0x6e, +0x81, 0xf4, 0x96, 0xa7, 0x05, 0x48, 0xe7, 0x88, +0xad, 0x23, 0x63, 0xd6, 0x42, 0xe7, 0x9e, 0xb1, +0xd6, 0x31, 0x3a, 0x2b, 0x28, 0x0c, 0x2f, 0x83, +0xd7, 0x29, 0xcf, 0xce, 0x5b, 0x47, 0xf6, 0xe4, +0xe6, 0x44, 0xd1, 0xdf, 0x28, 0x24, 0x25, 0x6d, +0x1c, 0xf2, 0xd8, 0x99, 0x7c, 0xc7, 0xf1, 0xe5, +0x6d, 0xc9, 0xb2, 0xcc, 0x49, 0xe7, 0xbc, 0xaf, +0x08, 0x47, 0xbe, 0x31, 0xf1, 0xf1, 0x5a, 0x59, +0x59, 0xc1, 0xf8, 0xee, 0xf7, 0xf0, 0xd6, 0xf2, +0xfe, 0xcc, 0x7b, 0x72, 0x52, 0x9d, 0x70, 0xb9, +0x5c, 0xd8, 0xcc, 0xab, 0x9d, 0x07, 0x4d, 0x90, +0x11, 0xae, 0xe8, 0x3f, 0x9d, 0xb3, 0x94, 0x61, +0x15, 0xf9, 0x71, 0x35, 0xe7, 0x11, 0x3a, 0x0f, +0x80, 0x50, 0x09, 0xb3, 0xa8, 0xd5, 0x1f, 0x4e, +0x63, 0x26, 0x07, 0x41, 0x0b, 0x59, 0x18, 0x21, +0x58, 0xe9, 0x61, 0xfb, 0xc9, 0x3d, 0xf5, 0x24, +0x03, 0xcd, 0x87, 0x30, 0x6e, 0xa3, 0xd3, 0x8e, +0x4b, 0xe3, 0xed, 0xe6, 0x68, 0x9e, 0x23, 0x59, +0x5d, 0xc3, 0xe7, 0x3b, 0x5f, 0xc5, 0x59, 0x7b, +0x65, 0x1a, 0xce, 0x35, 0x4d, 0xeb, 0x23, 0x3d, +0xf1, 0xa3, 0x24, 0x41, 0xa0, 0xf7, 0xa3, 0xd5, +0x9f, 0x5a, 0xfb, 0x4a, 0x5e, 0xcc, 0x39, 0xa2, +0x56, 0x81, 0x20, 0x68, 0xcd, 0x43, 0x74, 0xce, +0x22, 0x7a, 0x45, 0xad, 0x02, 0x79, 0x51, 0x60, +0x12, 0x4c, 0xa3, 0xd0, 0x7d, 0x3e, 0x06, 0x3e, +0x6e, 0xad, 0xe0, 0x72, 0x73, 0x1f, 0xf1, 0xde, +0x01, 0x5e, 0x5a, 0x0e, 0x90, 0x8e, 0xa7, 0x75, +0xd2, 0x1c, 0x1a, 0x0e, 0xcb, 0x41, 0x8a, 0xf8, +0x7c, 0x97, 0x6b, 0xc6, 0x8a, 0x2c, 0xc8, 0xe7, +0x14, 0xff, 0xad, 0xcd, 0x5b, 0xfe, 0x5e, 0x06, +0x92, 0xe1, 0x81, 0x67, 0xc8, 0xab, 0x5e, 0x12, +0x6d, 0x79, 0xbe, 0x5e, 0x0b, 0x54, 0xc3, 0x19, +0x69, 0x59, 0x1e, 0x95, 0x21, 0x83, 0x53, 0xc9, +0xf1, 0xe7, 0xeb, 0x99, 0x9b, 0x25, 0x28, 0xcc, +0xac, 0x76, 0xda, 0x87, 0x02, 0xef, 0xc4, 0x71, +0x8c, 0x22, 0x9d, 0x60, 0x70, 0x76, 0x8a, 0x6b, +0xad, 0x09, 0xba, 0x8f, 0xef, 0xe1, 0xdb, 0xc9, +0x18, 0xdf, 0xbf, 0x16, 0xe3, 0x69, 0x0a, 0x9c, +0xa2, 0x8d, 0x49, 0x3a, 0x29, 0x8d, 0x5d, 0x65, +0xec, 0xe5, 0xfa, 0xab, 0x1c, 0xf1, 0x82, 0xbe, +0x0e, 0xb5, 0xa0, 0x25, 0x72, 0x6e, 0xb1, 0x72, +0xa3, 0x56, 0xe1, 0xc2, 0xae, 0x46, 0xad, 0x59, +0x50, 0x1c, 0x19, 0x13, 0x42, 0x0b, 0xe4, 0x62, +0xd5, 0x21, 0xeb, 0xe7, 0xe7, 0xaa, 0x9b, 0xac, +0x8f, 0x3c, 0xd3, 0xd7, 0xb7, 0x2c, 0xff, 0x59, +0xf7, 0x17, 0x89, 0x3b, 0xa5, 0xb5, 0x22, 0xcc, +0x59, 0xfd, 0x27, 0xf7, 0x27, 0x79, 0xd4, 0x56, +0xae, 0x5f, 0x7a, 0xef, 0xc2, 0xbb, 0x02, 0xa5, +0xf3, 0xf2, 0x3c, 0x7c, 0xab, 0x36, 0xae, 0x34, +0x4f, 0xe4, 0xbc, 0x90, 0xfd, 0x45, 0xf5, 0xe4, +0x19, 0xc2, 0x9d, 0x6f, 0x7c, 0xff, 0xcd, 0xd5, +0x41, 0x1f, 0x9d, 0x38, 0x2e, 0x2d, 0x06, 0x79, +0x2c, 0x4c, 0x46, 0x16, 0xf3, 0x11, 0x4b, 0xed, +0x9c, 0x79, 0x9e, 0x4f, 0xd5, 0x7e, 0xe4, 0xd5, +0xce, 0x19, 0x01, 0xb9, 0x71, 0x58, 0xcf, 0xf2, +0x1c, 0x2a, 0x27, 0x9c, 0x3e, 0xc2, 0x2e, 0x37, +0x2f, 0x79, 0x8e, 0xdd, 0x47, 0xa4, 0xf9, 0xc2, +0xb7, 0x34, 0x12, 0xf2, 0x88, 0x9a, 0x16, 0x3a, +0x54, 0xe2, 0xa4, 0x05, 0xc3, 0x21, 0x9c, 0x38, +0x13, 0x60, 0x11, 0x74, 0xbe, 0x81, 0x59, 0xc7, +0xe2, 0xb4, 0x73, 0xd6, 0x1c, 0xbf, 0xfd, 0xfd, +0x7d, 0xbc, 0xf5, 0x95, 0x1f, 0xe3, 0x69, 0xbc, +0xda, 0x7c, 0xb1, 0xca, 0x45, 0x92, 0x1b, 0x1c, +0x2e, 0xa0, 0x7f, 0xcb, 0x6b, 0x38, 0xe2, 0xba, +0xcd, 0x49, 0xd4, 0x1f, 0x04, 0xb3, 0xf8, 0xe4, +0x68, 0xe1, 0xa4, 0xdb, 0xc3, 0x0b, 0x59, 0x1f, +0xe1, 0x79, 0x5f, 0xed, 0xdf, 0x28, 0x9a, 0x1e, +0x43, 0xd3, 0xc6, 0x80, 0xfa, 0x68, 0x63, 0x65, +0x09, 0x9b, 0x3b, 0xbb, 0xf8, 0x28, 0x9e, 0x86, +0xfb, 0xac, 0xc4, 0x48, 0xf6, 0x11, 0xe2, 0x2f, +0xb3, 0x7d, 0xc4, 0xb0, 0xcc, 0xe2, 0x61, 0xd3, +0xe5, 0x14, 0xbc, 0x9c, 0x3c, 0x4d, 0x2b, 0x7d, +0x7d, 0x89, 0x10, 0x4f, 0x27, 0x39, 0x1e, 0x84, +0x6b, 0x78, 0x2b, 0xd9, 0xc3, 0xd2, 0xfe, 0xf3, +0xf8, 0xce, 0x56, 0x82, 0x62, 0xe6, 0xed, 0xaf, +0x1d, 0x4f, 0x94, 0x84, 0x58, 0x9b, 0x73, 0x92, +0x90, 0x49, 0xa6, 0x5d, 0x1e, 0x85, 0x94, 0x04, +0x9f, 0xd7, 0x61, 0xc5, 0x76, 0x20, 0x82, 0x2f, +0x03, 0x3e, 0x69, 0xf5, 0xf3, 0x35, 0xcb, 0x05, +0x0e, 0xb9, 0x47, 0xc9, 0x23, 0x6e, 0x3c, 0x1e, +0x81, 0x0c, 0xd0, 0x94, 0x24, 0x49, 0x29, 0x34, +0x33, 0x2f, 0x9f, 0xbf, 0x23, 0x38, 0xb9, 0xb8, +0x44, 0x34, 0x9b, 0x4f, 0xa3, 0xd1, 0xc8, 0x5d, +0x2b, 0x9b, 0x65, 0x19, 0xd2, 0xf1, 0x08, 0xf1, +0xe0, 0x14, 0x2f, 0x47, 0x23, 0x2c, 0x27, 0x1d, +0x3c, 0x57, 0x9c, 0xe3, 0xf9, 0x4e, 0x8e, 0xcb, +0x70, 0x6a, 0x6b, 0xaf, 0x44, 0x92, 0xab, 0xfb, +0x6f, 0xcd, 0x9b, 0xba, 0xf9, 0x26, 0xfe, 0x97, +0x62, 0xce, 0x37, 0x21, 0x66, 0x75, 0xff, 0x65, +0xfd, 0x75, 0xc4, 0xb4, 0x2e, 0x7d, 0xd3, 0xf6, +0x3d, 0xeb, 0xfe, 0xa2, 0x11, 0xdd, 0x2f, 0x63, +0x1c, 0x6a, 0xf0, 0x77, 0x82, 0x81, 0x24, 0xe2, +0xbe, 0xf2, 0xb4, 0x6f, 0x9e, 0xf4, 0xe1, 0x4b, +0x2f, 0x7f, 0xfd, 0xcd, 0xe5, 0xf1, 0x79, 0x85, +0x48, 0x69, 0xe7, 0x94, 0x2d, 0x22, 0xa4, 0x49, +0x8b, 0x32, 0xcf, 0xe0, 0xf2, 0x12, 0x9d, 0x99, +0x1d, 0xd2, 0x5a, 0x1c, 0x3c, 0xbd, 0x24, 0x98, +0xda, 0x82, 0xe6, 0x1b, 0x05, 0x97, 0xc0, 0x64, +0xfd, 0x5c, 0xaa, 0xe6, 0x75, 0x68, 0xe7, 0xb7, +0x79, 0x54, 0x2e, 0xde, 0x27, 0x72, 0x51, 0xd3, +0x3b, 0x8d, 0x78, 0xf3, 0x7e, 0xe1, 0xe9, 0x38, +0x43, 0x20, 0xd5, 0xe8, 0x9c, 0x90, 0xf3, 0x72, +0xc2, 0x28, 0x46, 0x10, 0x84, 0x2e, 0xb8, 0x09, +0x01, 0x05, 0xec, 0xe0, 0x6d, 0x90, 0x63, 0xc4, +0x37, 0x35, 0x49, 0xf0, 0x77, 0x77, 0x77, 0xf1, +0xc9, 0xb7, 0xff, 0x23, 0xfc, 0x69, 0x6b, 0x63, +0x16, 0x03, 0x18, 0xe0, 0xd1, 0x84, 0xd4, 0x8b, +0x0e, 0x78, 0x1a, 0x26, 0x41, 0x3b, 0x6e, 0x5f, +0x12, 0x23, 0xba, 0x65, 0xac, 0x28, 0xa6, 0xe9, +0xc2, 0xc0, 0xa5, 0x8b, 0xc2, 0xa0, 0x7c, 0xa3, +0x92, 0x54, 0x39, 0xd1, 0x62, 0x0d, 0xa3, 0xf9, +0x42, 0x88, 0x3b, 0xf3, 0x9b, 0x9c, 0x66, 0x65, +0xd0, 0x0d, 0x55, 0x79, 0xd4, 0xc6, 0x24, 0x4d, +0x71, 0xda, 0xdb, 0xc7, 0x57, 0x47, 0x8f, 0x70, +0x76, 0x7a, 0x82, 0x56, 0x18, 0x61, 0x32, 0x1a, +0x21, 0x8c, 0x62, 0x74, 0xda, 0x6d, 0x17, 0x93, +0x9e, 0xfe, 0x8a, 0x3c, 0x77, 0xfd, 0x5c, 0xb4, +0x02, 0xe4, 0x45, 0x81, 0x41, 0x0e, 0x9c, 0xdd, +0xf8, 0x2a, 0xee, 0x77, 0x36, 0xa7, 0xd2, 0x70, +0x2b, 0xac, 0x4a, 0x53, 0x84, 0x07, 0x6f, 0x17, +0xa5, 0x03, 0xe6, 0x92, 0x74, 0x2b, 0xac, 0xe2, +0xce, 0x7f, 0xcf, 0xf2, 0xab, 0xaa, 0x4b, 0x92, +0x20, 0xf8, 0xf7, 0x86, 0xbf, 0xf3, 0xa8, 0x8d, +0x49, 0x01, 0x5c, 0x4e, 0x52, 0x7c, 0x50, 0x2c, +0xe3, 0x17, 0xed, 0x1d, 0x9c, 0xec, 0xbc, 0x80, +0xfb, 0xd7, 0xbf, 0x8a, 0xed, 0x95, 0x65, 0x6c, +0xc7, 0x40, 0x3a, 0x9a, 0x4b, 0xcd, 0x9a, 0x96, +0x6a, 0x9c, 0x17, 0xe8, 0xc4, 0x31, 0x34, 0xb0, +0x98, 0x76, 0x3e, 0xd7, 0xf8, 0x3c, 0xd6, 0x02, +0xc4, 0x48, 0xa9, 0xdd, 0xc7, 0xbc, 0x4b, 0xf0, +0xc5, 0x8d, 0x90, 0xe6, 0x39, 0x6d, 0xad, 0x72, +0x41, 0x82, 0xab, 0xd5, 0xe5, 0x1a, 0x96, 0x4c, +0x82, 0x5c, 0xcb, 0xe9, 0x78, 0xe4, 0xa2, 0xdc, +0xf1, 0xc0, 0x4d, 0xfc, 0xcc, 0x7a, 0x6b, 0x3c, +0xc4, 0xce, 0xd9, 0x43, 0xac, 0x3d, 0x7a, 0x1f, +0xaf, 0xc5, 0x03, 0x7c, 0x7b, 0x39, 0xc3, 0xeb, +0xdd, 0x09, 0x96, 0x37, 0xb6, 0xf0, 0xd9, 0xe9, +0x25, 0x52, 0xb4, 0x1a, 0x11, 0x20, 0x2e, 0x51, +0x97, 0xd6, 0x9c, 0xb6, 0xfe, 0x66, 0x73, 0xd0, +0x31, 0x7b, 0xda, 0x7b, 0xa0, 0xbc, 0xce, 0xac, +0xf9, 0x2d, 0xd7, 0x3b, 0x5b, 0x97, 0xf4, 0x8d, +0xea, 0x57, 0xe7, 0xb7, 0xb2, 0x5f, 0x94, 0xd6, +0x74, 0xae, 0xa8, 0xae, 0xf9, 0x9e, 0xc0, 0xf7, +0x23, 0x6b, 0xce, 0xf3, 0x7d, 0x49, 0x23, 0xf8, +0x8a, 0xc4, 0x2e, 0xf7, 0x1f, 0xbe, 0x86, 0xb5, +0xfe, 0x94, 0xfb, 0x21, 0x69, 0x04, 0xad, 0x7d, +0xc9, 0xed, 0x07, 0xb3, 0xfa, 0x2a, 0xcc, 0x38, +0xd5, 0xe3, 0xeb, 0x2f, 0xbe, 0x0f, 0x33, 0x26, +0x20, 0x0a, 0x83, 0xe9, 0xad, 0x7e, 0x62, 0xcf, +0x0d, 0xb7, 0xbe, 0xf7, 0x93, 0x37, 0xe3, 0xa3, +0x4f, 0x4b, 0x44, 0x4a, 0xaa, 0xa4, 0xb8, 0x04, +0x2c, 0x89, 0x9a, 0x24, 0xe2, 0x96, 0xa4, 0xcc, +0xcb, 0x92, 0x41, 0x57, 0x88, 0x88, 0x49, 0x95, +0xbd, 0x5c, 0xb0, 0x3c, 0x8f, 0x0c, 0x1c, 0x63, +0x05, 0x7e, 0xd1, 0x36, 0x00, 0x8b, 0x51, 0xf1, +0x31, 0x24, 0x75, 0x81, 0x65, 0xe8, 0x37, 0xef, +0x3f, 0xda, 0x54, 0x28, 0x68, 0x05, 0xf9, 0x10, +0xc8, 0xf6, 0x73, 0x09, 0x42, 0x96, 0x5b, 0xe4, +0x39, 0xd6, 0xd7, 0xd6, 0x9c, 0xa9, 0xa2, 0xc8, +0x73, 0xa7, 0x06, 0x94, 0x9b, 0x24, 0xcf, 0x4b, +0xb8, 0xd0, 0xed, 0x67, 0x74, 0x95, 0x28, 0x85, +0x2d, 0xdd, 0x7f, 0xe1, 0x25, 0xfc, 0xe3, 0xed, +0x6f, 0x4e, 0x6f, 0x3c, 0xab, 0xe1, 0xf8, 0xdc, +0xc4, 0xe5, 0xea, 0x39, 0x76, 0x45, 0xa2, 0x5c, +0x94, 0x6e, 0xb2, 0xa5, 0xe9, 0x74, 0x82, 0x72, +0x49, 0x72, 0x96, 0x8e, 0x6e, 0x4b, 0x22, 0x55, +0x31, 0x4d, 0x6e, 0x5a, 0x20, 0xfc, 0x3d, 0xdf, +0xb4, 0xd2, 0x6c, 0x1e, 0xde, 0x51, 0xdb, 0x0c, +0x86, 0xad, 0x10, 0xed, 0xad, 0x3d, 0xdc, 0xee, +0xdf, 0x73, 0x41, 0x56, 0xe2, 0xa4, 0x8b, 0x22, +0xcb, 0x30, 0x19, 0x8f, 0xd1, 0x69, 0xb7, 0x11, +0x06, 0x01, 0xf2, 0xbc, 0xc0, 0xe0, 0xf2, 0xd2, +0xf5, 0x59, 0xa7, 0x1d, 0x23, 0x0c, 0x5a, 0x48, +0xa2, 0x10, 0xe9, 0xf6, 0x73, 0x38, 0x5c, 0xbf, +0x59, 0xbe, 0xce, 0x71, 0xb6, 0xf0, 0xa2, 0x30, +0x28, 0x4b, 0xca, 0x74, 0xad, 0x22, 0x2d, 0xe2, +0xd9, 0x4d, 0x50, 0x84, 0x1b, 0x5f, 0xc4, 0x79, +0x51, 0xa8, 0xf9, 0x2b, 0xfd, 0x3d, 0xbb, 0x7c, +0x86, 0xe7, 0x75, 0x8c, 0x90, 0xe8, 0x7f, 0x39, +0x2e, 0x8e, 0x01, 0x61, 0x9b, 0xca, 0x30, 0xcd, +0xf0, 0xa0, 0x48, 0xf0, 0x38, 0x6d, 0xe1, 0xbd, +0xa5, 0x1b, 0x18, 0x6e, 0xdf, 0xc2, 0x9d, 0xe7, +0x6e, 0x61, 0x3d, 0x1d, 0xe0, 0xfc, 0xa4, 0xaf, +0xce, 0xf3, 0xac, 0x00, 0xc2, 0x59, 0x80, 0x18, +0x5a, 0x67, 0x72, 0x0d, 0x68, 0x9a, 0x32, 0x22, +0x94, 0x52, 0x2a, 0x96, 0xf9, 0x39, 0xe3, 0x4c, +0x73, 0x96, 0x33, 0x00, 0xdc, 0xb4, 0x47, 0xc0, +0xf7, 0x14, 0xbe, 0xcf, 0x48, 0x0d, 0x8b, 0xa6, +0x25, 0xe3, 0x04, 0x5c, 0x32, 0xe0, 0xf2, 0xca, +0x56, 0xbe, 0x3f, 0x48, 0xe6, 0x5e, 0xae, 0x6d, +0xa0, 0x1c, 0xb0, 0x86, 0x6b, 0x1a, 0xd3, 0x74, +0x7a, 0x6b, 0x1d, 0x5d, 0x9c, 0x03, 0x00, 0x93, +0xfe, 0x13, 0x74, 0x2f, 0x9e, 0xe2, 0xbb, 0x9d, +0x4b, 0x7c, 0x7f, 0xb3, 0x8d, 0xcb, 0x56, 0x8c, +0xa7, 0x48, 0xe6, 0x92, 0xba, 0x24, 0x66, 0x24, +0x51, 0xf3, 0x2b, 0x52, 0xf9, 0x33, 0x50, 0x22, +0x22, 0xb4, 0xee, 0xdc, 0xbc, 0x90, 0xeb, 0x51, +0xce, 0x3b, 0x21, 0x39, 0x56, 0xe6, 0xa7, 0x98, +0xff, 0x1a, 0x21, 0x26, 0x5c, 0xd4, 0xf9, 0xdd, +0x60, 0xfd, 0x48, 0x49, 0x96, 0xef, 0x03, 0x75, +0xfb, 0x4f, 0x65, 0xfe, 0x17, 0x79, 0xed, 0x7e, +0xd2, 0xb4, 0x3f, 0x39, 0x23, 0xc5, 0xf1, 0xa1, +0xb6, 0xd2, 0xbe, 0x54, 0xba, 0xb1, 0x4d, 0xec, +0x4b, 0x25, 0xa6, 0x5f, 0x94, 0xd3, 0xa8, 0xbf, +0x85, 0x10, 0x50, 0xba, 0x56, 0x55, 0xec, 0x7d, +0xe1, 0xde, 0x37, 0x7f, 0xf0, 0xe6, 0xc6, 0xf0, +0xb8, 0x42, 0x04, 0xf8, 0x22, 0x93, 0x44, 0x4b, +0x23, 0x62, 0xd2, 0x76, 0x26, 0x09, 0x1f, 0x67, +0x04, 0x9a, 0xd8, 0xdc, 0x38, 0x13, 0xc1, 0xed, +0xf5, 0xb4, 0xf0, 0xa4, 0xa4, 0xcd, 0xa5, 0x5a, +0x8b, 0x48, 0x73, 0x09, 0x55, 0x63, 0x38, 0xe4, +0x06, 0x63, 0x11, 0x6d, 0x59, 0x36, 0xbf, 0x80, +0x42, 0xb6, 0x9b, 0x6f, 0x04, 0xd2, 0x74, 0xc1, +0x09, 0xf8, 0x24, 0x9d, 0x12, 0x1b, 0x7e, 0x69, +0x0b, 0x00, 0x47, 0xc0, 0x81, 0xa9, 0xaf, 0x81, +0x26, 0xf1, 0xf3, 0x48, 0x56, 0x7c, 0x33, 0xa2, +0x2b, 0x44, 0x83, 0x30, 0x44, 0x1c, 0x06, 0x58, +0x5e, 0x9a, 0xc6, 0x21, 0xdf, 0xfa, 0xee, 0x6f, +0xe3, 0xf7, 0x6e, 0x7c, 0x17, 0x87, 0x79, 0x6c, +0x4b, 0xc4, 0x8c, 0x13, 0x77, 0x44, 0x79, 0x36, +0xd9, 0x88, 0x60, 0xf0, 0xc5, 0xcd, 0xa5, 0xd8, +0x3c, 0x6a, 0x97, 0x89, 0x11, 0x81, 0xd8, 0x08, +0xa2, 0x30, 0x98, 0x12, 0x67, 0x46, 0xec, 0x69, +0x81, 0xd0, 0x22, 0xa5, 0xbb, 0x7a, 0x11, 0x46, +0x65, 0x6e, 0x94, 0xab, 0xa9, 0x66, 0x38, 0x47, +0x33, 0x0f, 0xee, 0xc3, 0x56, 0x17, 0x4b, 0xd7, +0x6f, 0x60, 0x6f, 0x70, 0x84, 0xe1, 0x68, 0x84, +0x7c, 0x76, 0x19, 0x0b, 0xef, 0xff, 0x3c, 0x2f, +0x4a, 0x11, 0xe4, 0x8a, 0xd6, 0x34, 0x3e, 0x7b, +0x18, 0x04, 0x98, 0xec, 0xbd, 0x88, 0xcf, 0xd6, +0x6e, 0xcc, 0x17, 0x5b, 0x2b, 0x74, 0x75, 0x3b, +0x8e, 0x9b, 0x88, 0x2c, 0x93, 0x74, 0x4a, 0xd2, +0x09, 0x50, 0xd6, 0x52, 0xf0, 0x4d, 0x43, 0x5e, +0xf5, 0x28, 0xa4, 0x09, 0xde, 0xdf, 0x8e, 0x61, +0xa2, 0xfb, 0x9a, 0x69, 0xa3, 0x9e, 0xf5, 0x3f, +0xef, 0x0f, 0xd7, 0xef, 0xb3, 0xfa, 0x69, 0xe3, +0xe0, 0xe9, 0x27, 0x41, 0x84, 0xc7, 0x69, 0x0b, +0x6f, 0xe5, 0xcb, 0x58, 0xde, 0xbd, 0x85, 0xbb, +0xdb, 0xeb, 0xc0, 0x79, 0xbf, 0x32, 0x9f, 0x46, +0x93, 0xd4, 0x11, 0x73, 0x4d, 0x0a, 0xa7, 0xf5, +0x62, 0x99, 0x91, 0xac, 0xbd, 0x42, 0xee, 0x07, +0x72, 0x7f, 0xd1, 0xcc, 0x47, 0x72, 0x8d, 0x73, +0xa2, 0xc9, 0xeb, 0x92, 0xd2, 0xbd, 0xe5, 0x1b, +0x23, 0x1d, 0xf4, 0x08, 0x17, 0xcd, 0x5c, 0x28, +0x43, 0x3e, 0xfb, 0xda, 0x21, 0xd7, 0x34, 0xe5, +0xe7, 0x7b, 0x4d, 0x14, 0x4d, 0x43, 0xc8, 0x02, +0x40, 0x6b, 0x74, 0x81, 0x97, 0x8a, 0x33, 0xbc, +0x72, 0x2d, 0xc1, 0xe1, 0xa4, 0x85, 0xe1, 0x24, +0x43, 0x9a, 0x65, 0xba, 0xa4, 0x2e, 0x34, 0x61, +0x8e, 0x68, 0xb1, 0x35, 0xcb, 0xe7, 0x27, 0x97, +0xf2, 0x4a, 0xf3, 0x96, 0xe6, 0x1e, 0x5f, 0x8f, +0xbe, 0xf9, 0x2d, 0xe6, 0xbf, 0x5b, 0xff, 0xb3, +0xb5, 0xc9, 0xe7, 0x9b, 0x36, 0xbf, 0x29, 0xbf, +0x23, 0x60, 0x75, 0xf3, 0x5f, 0xe2, 0x4b, 0xfb, +0x82, 0xb1, 0xff, 0xc8, 0xf9, 0xef, 0xa4, 0x6d, +0x22, 0x7a, 0xb3, 0x72, 0x4a, 0xfb, 0x09, 0xdb, +0x7f, 0xf2, 0xa2, 0x30, 0xfb, 0x93, 0x18, 0x00, +0x89, 0x8f, 0x63, 0x0c, 0x58, 0xff, 0xf1, 0xbe, +0xe5, 0xfb, 0x61, 0x89, 0x08, 0xb3, 0xfd, 0xad, +0x24, 0x08, 0x34, 0xe9, 0xef, 0x19, 0x9e, 0x8e, +0x69, 0x50, 0xf6, 0x8d, 0xf0, 0xce, 0xf7, 0x7f, +0xfb, 0xcd, 0x8d, 0x61, 0x5f, 0x25, 0x54, 0x7c, +0x61, 0xf0, 0x89, 0x4f, 0x93, 0x98, 0x4f, 0x50, +0x49, 0x2c, 0x35, 0x0f, 0x52, 0xb9, 0x60, 0xe5, +0x62, 0x97, 0x65, 0x4a, 0xb5, 0x9c, 0x66, 0x2b, +0xe7, 0x0b, 0x51, 0xc3, 0x5b, 0x5b, 0xc0, 0xb2, +0x5e, 0xa9, 0x86, 0xe7, 0x92, 0x83, 0x6c, 0x0f, +0x57, 0x23, 0x4a, 0x5b, 0xb4, 0xc6, 0xac, 0x70, +0x8f, 0x5c, 0xb9, 0xd9, 0x51, 0x19, 0xbd, 0x5e, +0x0f, 0x93, 0xf1, 0xb8, 0xe2, 0xa8, 0x43, 0x8e, +0x59, 0xc0, 0x94, 0xd8, 0x13, 0x01, 0xe2, 0x36, +0x73, 0xc9, 0x40, 0x74, 0xba, 0x4b, 0x68, 0x77, +0x3a, 0x28, 0xf2, 0x0c, 0x9d, 0x76, 0x8c, 0xe5, +0xa5, 0xee, 0xf4, 0x86, 0xb1, 0x28, 0xc6, 0xf2, +0xd2, 0x12, 0xae, 0xbd, 0xf4, 0x0a, 0xfe, 0xd1, +0xcd, 0x1f, 0xe1, 0x41, 0xb4, 0x56, 0x5e, 0xdc, +0x06, 0xa7, 0x5e, 0x79, 0x26, 0xbb, 0x1b, 0x57, +0x21, 0x15, 0x45, 0x45, 0xc5, 0xe4, 0x16, 0x0c, +0x5f, 0x3c, 0xad, 0x62, 0x2a, 0xed, 0xb2, 0x4d, +0xc6, 0x11, 0x2c, 0xa1, 0x12, 0xe4, 0xdc, 0x3e, +0x5f, 0xd4, 0x6e, 0x21, 0x31, 0x8e, 0x95, 0x38, +0x75, 0x22, 0x5c, 0x00, 0xf0, 0x49, 0xbc, 0x81, +0xb5, 0xcd, 0x6d, 0xdc, 0x18, 0xf7, 0x91, 0x0d, +0x2f, 0x91, 0x07, 0x21, 0xf2, 0x2c, 0x77, 0xce, +0x97, 0x61, 0x10, 0xa0, 0x40, 0x0b, 0x2d, 0x14, +0x33, 0x0d, 0x48, 0x86, 0x76, 0xbb, 0x83, 0x30, +0x08, 0x90, 0xdc, 0xb8, 0x83, 0xf7, 0xd7, 0xef, +0x94, 0xef, 0x78, 0x66, 0x9b, 0x09, 0xe7, 0xb8, +0x5d, 0x1b, 0x66, 0x8b, 0xda, 0x71, 0xd3, 0xb3, +0xe7, 0x5a, 0x35, 0xbb, 0x62, 0x2b, 0xe7, 0x9b, +0x45, 0xc5, 0xc6, 0xa9, 0xf4, 0x3f, 0x1f, 0x1f, +0xb7, 0x59, 0x50, 0x1f, 0x2a, 0x1a, 0x8c, 0x20, +0x68, 0x21, 0x43, 0x0b, 0xef, 0xe5, 0x4b, 0xb8, +0x17, 0xf7, 0x70, 0xe3, 0xc6, 0x0d, 0xac, 0x65, +0x43, 0xe4, 0x83, 0x0b, 0x27, 0x55, 0x17, 0xec, +0x78, 0x8d, 0x34, 0x69, 0x8d, 0xf3, 0x02, 0x61, +0xab, 0x65, 0x6a, 0xe2, 0xa8, 0x0c, 0xc9, 0x5c, +0x4a, 0xe0, 0xeb, 0x98, 0xaf, 0x1f, 0x8b, 0x29, +0xe7, 0xb6, 0x7a, 0xbe, 0x2f, 0x58, 0x7e, 0x3e, +0xd2, 0xab, 0x9d, 0x13, 0x69, 0x69, 0x76, 0xe2, +0xed, 0x93, 0x0c, 0x0a, 0x97, 0xce, 0x25, 0x01, +0xe7, 0x21, 0x68, 0x39, 0x3e, 0xb4, 0xf6, 0xa5, +0xf6, 0xc1, 0x31, 0xe9, 0x45, 0x81, 0xc9, 0x70, +0x88, 0xcb, 0xfe, 0x13, 0x2c, 0x9d, 0x7e, 0x8e, +0xe7, 0x71, 0x81, 0xa5, 0x4e, 0x8c, 0x93, 0xb0, +0x8b, 0xcb, 0x40, 0xa8, 0xbb, 0x39, 0x11, 0x9a, +0x8d, 0x7f, 0x49, 0x6b, 0xc3, 0xd4, 0xc2, 0x8e, +0x90, 0x48, 0x95, 0x2f, 0x49, 0xe8, 0x24, 0x19, +0xf2, 0xf5, 0x58, 0x37, 0xbf, 0xf9, 0x77, 0x71, +0xef, 0x39, 0x27, 0x56, 0xbe, 0x75, 0xdc, 0x78, +0xfe, 0x4b, 0x49, 0x54, 0x91, 0x54, 0x7d, 0xf3, +0x5f, 0xee, 0x39, 0x15, 0xed, 0x01, 0xf5, 0x1b, +0xdb, 0x7f, 0xac, 0xfe, 0x54, 0x25, 0x63, 0xc6, +0xcc, 0xf0, 0x7e, 0xe1, 0x63, 0xc0, 0xfb, 0xcd, +0x6a, 0x4f, 0x49, 0x10, 0x68, 0xd2, 0xdf, 0x8c, +0xf0, 0x97, 0x84, 0x27, 0xb6, 0x6f, 0x87, 0xdb, +0xaf, 0x7d, 0xf7, 0xcd, 0x8d, 0xe1, 0x71, 0x45, +0x42, 0x95, 0x9c, 0x35, 0x27, 0x58, 0x92, 0x80, +0x69, 0x93, 0x9c, 0x13, 0x4a, 0x5a, 0x48, 0x72, +0x51, 0xc8, 0x72, 0xf8, 0x84, 0xd7, 0x6c, 0xbd, +0x52, 0x35, 0xcf, 0x09, 0xad, 0x24, 0xae, 0x9a, +0x4d, 0x5d, 0x73, 0xd2, 0xe1, 0xff, 0xa5, 0xdd, +0x5a, 0x5b, 0x9c, 0x72, 0x51, 0x4a, 0x42, 0xae, +0x95, 0xef, 0x63, 0x1c, 0x2c, 0x8f, 0x77, 0xa9, +0xad, 0x20, 0x07, 0x42, 0x22, 0xe6, 0x5c, 0x43, +0xc1, 0x6d, 0x85, 0xeb, 0x6b, 0xab, 0x08, 0x66, +0x57, 0x9c, 0x72, 0x5c, 0x97, 0x97, 0x96, 0xb0, +0x76, 0xe7, 0x2e, 0x7e, 0xe7, 0xe0, 0xb7, 0xf0, +0x98, 0x3b, 0xbc, 0x69, 0x44, 0x7c, 0x46, 0x94, +0xb8, 0x8d, 0xbb, 0x24, 0x65, 0x2b, 0xdc, 0xb4, +0x5b, 0x34, 0x82, 0xe0, 0x3a, 0x82, 0x56, 0x94, +0x37, 0x1c, 0xfe, 0x3b, 0x0d, 0xe2, 0x12, 0x27, +0x2c, 0x1d, 0xbd, 0x38, 0xf7, 0xcb, 0xa5, 0x75, +0xc2, 0x91, 0x54, 0xef, 0x54, 0x16, 0x11, 0xc0, +0xc3, 0x60, 0x09, 0x83, 0xad, 0xe7, 0xb0, 0xb2, +0xba, 0x8a, 0xf5, 0xd3, 0x47, 0xb8, 0xbc, 0x1c, +0x20, 0x4e, 0xba, 0x68, 0x85, 0x11, 0x8a, 0x2c, +0x73, 0xf7, 0xb9, 0x3b, 0xff, 0x84, 0x59, 0xdf, +0xb6, 0x6e, 0x3c, 0x8f, 0x47, 0xab, 0xbb, 0x53, +0x3b, 0xba, 0x94, 0xb2, 0x35, 0x1b, 0x98, 0x54, +0xb5, 0x4b, 0x35, 0x3b, 0xdf, 0x38, 0xb9, 0x5a, +0xce, 0xb0, 0x59, 0x6a, 0x9b, 0x1c, 0x1f, 0x0b, +0x3e, 0x6e, 0x25, 0x4e, 0x9e, 0x6d, 0x00, 0x4e, +0xad, 0xd9, 0x2a, 0x2a, 0x2a, 0x3c, 0xae, 0x55, +0x19, 0xe4, 0x05, 0x3e, 0x08, 0x7a, 0x78, 0xbc, +0xba, 0x83, 0x9d, 0xdd, 0x5d, 0x2c, 0xc7, 0x21, +0x3a, 0xc8, 0x91, 0x8e, 0x47, 0x88, 0x96, 0x56, +0xb0, 0xd2, 0x2d, 0x13, 0xc1, 0xcb, 0xf1, 0x04, +0x6d, 0xc3, 0x89, 0x50, 0xae, 0x69, 0x79, 0x04, +0xb4, 0x89, 0x0f, 0x8e, 0x5c, 0x37, 0x1c, 0xa4, +0xfd, 0x9d, 0x33, 0xc4, 0xb2, 0x1e, 0xbe, 0x16, +0xa5, 0xaf, 0x0c, 0x37, 0xd1, 0x49, 0x6d, 0x9d, +0x85, 0x9b, 0x66, 0xdb, 0x97, 0x8c, 0xbb, 0x94, +0xe0, 0x65, 0xdb, 0xf8, 0xda, 0x8f, 0xa2, 0xe9, +0x95, 0xac, 0x64, 0x5f, 0xc7, 0x79, 0x1f, 0xbb, +0xe3, 0x13, 0xbc, 0x16, 0x5e, 0xe0, 0xb9, 0xce, +0xf4, 0xe2, 0x9f, 0x5e, 0x90, 0xa1, 0x40, 0x0b, +0xe3, 0x3c, 0x47, 0x1a, 0xc4, 0x4e, 0x82, 0xe4, +0xa6, 0x14, 0xc4, 0x9d, 0xb9, 0x74, 0xcc, 0x08, +0x3d, 0x11, 0x87, 0x92, 0x5a, 0x77, 0x26, 0xa9, +0xf2, 0xf5, 0xc8, 0x89, 0x2a, 0xb7, 0xfb, 0x56, +0x18, 0x02, 0x9f, 0x23, 0x28, 0x80, 0x28, 0x9f, +0x20, 0xcd, 0xf2, 0xaa, 0xed, 0x99, 0xfa, 0x94, +0xcf, 0x79, 0x6d, 0x3f, 0xa9, 0x99, 0xff, 0x1c, +0x9f, 0x92, 0x2d, 0x7d, 0xc6, 0x44, 0x50, 0xff, +0x54, 0x18, 0x6c, 0xa9, 0xc9, 0x13, 0xfb, 0x8f, +0x66, 0x87, 0x2f, 0x49, 0xbf, 0x4c, 0xaa, 0xe7, +0x7e, 0x3a, 0x00, 0xca, 0x4c, 0x37, 0x1b, 0x0f, +0xc9, 0x14, 0xa9, 0xfb, 0x9b, 0xd8, 0x03, 0x2a, +0xc4, 0x5e, 0xfa, 0x29, 0x30, 0x3f, 0x24, 0xa9, +0x91, 0xa0, 0x7d, 0x3b, 0xdc, 0xfb, 0xe6, 0x0f, +0xde, 0xec, 0xf6, 0x1f, 0x56, 0x6c, 0x4f, 0xd2, +0x26, 0xa5, 0x4d, 0x78, 0x8d, 0x98, 0xf3, 0x85, +0xc3, 0x8f, 0x95, 0x68, 0x36, 0x31, 0xbe, 0x28, +0xa4, 0x07, 0x2a, 0xff, 0x2d, 0x2f, 0x52, 0xd1, +0xa4, 0x52, 0x4d, 0x25, 0xc7, 0xff, 0x73, 0x5c, +0x7d, 0x52, 0x32, 0x2f, 0x57, 0x5b, 0xa0, 0x16, +0xfe, 0x1c, 0x17, 0x92, 0x4c, 0xa4, 0x06, 0x41, +0xe2, 0x63, 0x79, 0xdc, 0xd2, 0xc2, 0xe7, 0xe9, +0x8a, 0x7c, 0x2a, 0x55, 0x4a, 0xed, 0x82, 0x64, +0x9e, 0xe8, 0x08, 0x20, 0x39, 0x79, 0x51, 0x9e, +0xf1, 0xd7, 0x7f, 0x88, 0x7f, 0x71, 0xeb, 0x87, +0x53, 0x42, 0x3e, 0x5b, 0x5c, 0xdc, 0xa1, 0x82, +0x16, 0xb6, 0xb3, 0x13, 0x03, 0xe5, 0xc5, 0x4e, +0x93, 0x51, 0x71, 0x5a, 0x2b, 0xd9, 0xd0, 0x69, +0x93, 0xa0, 0xb4, 0x6c, 0x71, 0x6a, 0x36, 0xf6, +0x8a, 0xad, 0x49, 0x3a, 0xb0, 0xd0, 0x44, 0x67, +0x8e, 0x66, 0x15, 0x7b, 0x1d, 0x97, 0x5c, 0x85, +0x79, 0xe0, 0x69, 0xbc, 0x8a, 0x4f, 0x96, 0x77, +0xd0, 0xee, 0x6d, 0x61, 0xff, 0xec, 0xc1, 0xd4, +0x76, 0x3e, 0x1a, 0x21, 0x68, 0x77, 0x90, 0x4d, +0x26, 0x25, 0x62, 0xee, 0xc6, 0x64, 0xfb, 0x39, +0x1c, 0xf6, 0x6e, 0x21, 0x43, 0xab, 0x6a, 0xab, +0xe3, 0x44, 0x98, 0x36, 0x3a, 0x66, 0x6e, 0xe0, +0x36, 0xfd, 0x92, 0x34, 0xd1, 0x32, 0xce, 0x04, +0x6b, 0x36, 0x4b, 0xa5, 0xbe, 0x4a, 0x7e, 0x61, +0xaf, 0x97, 0xce, 0x50, 0x25, 0x75, 0xab, 0x70, +0xea, 0xe1, 0xb6, 0x3b, 0x3a, 0xda, 0x76, 0x5a, +0x04, 0xf8, 0xb3, 0x70, 0x0b, 0x9f, 0xac, 0xdc, +0xc0, 0xe3, 0xa5, 0x6d, 0xac, 0xef, 0x1f, 0x60, +0x77, 0x25, 0xc1, 0x52, 0x51, 0x56, 0x6d, 0x73, +0x89, 0x9d, 0x8e, 0x88, 0x12, 0x73, 0x29, 0xb5, +0x5f, 0x72, 0x3f, 0xe1, 0x40, 0xeb, 0x9d, 0x9f, +0x4b, 0xd7, 0x98, 0x6b, 0x8d, 0xf1, 0xe7, 0x92, +0xbb, 0x8f, 0x39, 0x97, 0xeb, 0x4e, 0x0a, 0x1b, +0xd2, 0x49, 0x8f, 0xf0, 0x92, 0x7b, 0x86, 0xb4, +0xb7, 0xf3, 0xb5, 0xcd, 0x35, 0x75, 0x52, 0x9b, +0x67, 0xf9, 0x16, 0x11, 0x21, 0xbf, 0x18, 0x8d, +0xa7, 0x4c, 0xd3, 0xac, 0xac, 0xb0, 0xc8, 0x11, +0x0d, 0xcf, 0xb1, 0x37, 0xee, 0xe3, 0x95, 0xe0, +0x0c, 0xaf, 0xa5, 0x8f, 0xf1, 0xf5, 0xe0, 0x02, +0xbf, 0xbe, 0xde, 0xc2, 0x93, 0x2c, 0xc0, 0x45, +0xde, 0xc2, 0x28, 0xd3, 0xed, 0xb7, 0x16, 0x31, +0xae, 0x10, 0x56, 0x9a, 0x13, 0x44, 0x68, 0xc8, +0xcc, 0xc5, 0xd6, 0x99, 0x9c, 0x6f, 0xaa, 0xa3, +0x9a, 0x90, 0x3a, 0x5d, 0x7d, 0x62, 0x3d, 0x5b, +0xf3, 0xd9, 0xcd, 0x61, 0xcd, 0xa6, 0xae, 0x30, +0x0e, 0xea, 0xfa, 0x11, 0xfb, 0x43, 0x89, 0xe0, +0x33, 0x0d, 0x82, 0x57, 0xb2, 0x9f, 0x31, 0x03, +0x15, 0x66, 0x41, 0xa8, 0xfd, 0x35, 0xdf, 0x05, +0xa7, 0xba, 0x17, 0x92, 0xb7, 0x5c, 0x5f, 0x95, +0xfe, 0x10, 0x6d, 0xf1, 0xfa, 0x08, 0xc8, 0xef, +0xc6, 0x69, 0x80, 0xbc, 0x98, 0x11, 0xf3, 0xed, +0xf4, 0xac, 0xb2, 0x20, 0x34, 0x69, 0x53, 0x2e, +0x3a, 0x92, 0x0e, 0x69, 0x11, 0x50, 0x1a, 0x69, +0x3b, 0x92, 0x84, 0xd7, 0xf2, 0x60, 0x97, 0xde, +0xe3, 0x3e, 0xe7, 0x36, 0xcd, 0xd1, 0x45, 0xe3, +0xe8, 0xa5, 0x7d, 0x4d, 0x6a, 0x0d, 0x24, 0x3e, +0x12, 0x7f, 0xad, 0x4e, 0x4d, 0xcd, 0xee, 0x63, +0x28, 0xf8, 0xc6, 0x24, 0xa5, 0x7a, 0xae, 0x41, +0xe0, 0x8b, 0x5f, 0x8b, 0x22, 0xc7, 0x19, 0x1d, +0xae, 0xe2, 0x8b, 0xa2, 0x08, 0x67, 0xe7, 0x17, +0x18, 0x5c, 0x5e, 0x22, 0x0c, 0x02, 0x04, 0xc1, +0x34, 0xe8, 0x42, 0x67, 0x69, 0x09, 0xdb, 0xcf, +0x3d, 0x8f, 0xb7, 0x5e, 0xff, 0x8f, 0xf0, 0xaf, +0xaf, 0x7d, 0x15, 0x23, 0xb2, 0x21, 0x09, 0x3b, +0x6e, 0x50, 0xe4, 0x55, 0xa7, 0x0a, 0xa1, 0xda, +0xe5, 0xea, 0x5a, 0xc9, 0xd9, 0x56, 0xec, 0x43, +0x62, 0x63, 0x90, 0x4e, 0x22, 0x96, 0x9a, 0xa8, +0xb2, 0x50, 0xe9, 0x3d, 0x30, 0x5f, 0x48, 0x40, +0xd9, 0xb9, 0x84, 0x73, 0xd1, 0x8a, 0xa6, 0x81, +0x08, 0xdd, 0x61, 0xb4, 0x8a, 0x7c, 0xe7, 0x0e, +0xd6, 0x4f, 0x1f, 0x01, 0xe3, 0x21, 0xf2, 0xf1, +0x08, 0x93, 0xf1, 0xb8, 0x34, 0xae, 0x34, 0x16, +0xf1, 0xed, 0xbb, 0xf8, 0xa4, 0xbb, 0x83, 0x71, +0x58, 0x5e, 0xbc, 0x52, 0x1a, 0xe7, 0x92, 0x77, +0xe5, 0xbb, 0xf2, 0x5c, 0x72, 0x70, 0x9a, 0xb5, +0x43, 0xb5, 0xc9, 0xf3, 0xfc, 0xd2, 0x46, 0xca, +0xbd, 0xe7, 0x79, 0xff, 0x70, 0x66, 0x82, 0xdb, +0xf6, 0x66, 0x65, 0xb8, 0xf1, 0x02, 0xca, 0x36, +0x40, 0x2e, 0x29, 0x4d, 0x46, 0xb8, 0xcc, 0x80, +0x27, 0xc9, 0x06, 0xfe, 0x6d, 0xbc, 0x89, 0x77, +0x56, 0x0f, 0x30, 0xdc, 0xbd, 0x83, 0x5e, 0x2b, +0xc5, 0x72, 0x3e, 0xad, 0x4b, 0x0b, 0xc2, 0xa2, +0x69, 0xb3, 0x2c, 0xa2, 0x2b, 0x8f, 0xb4, 0xf1, +0xb5, 0xa3, 0x31, 0xbc, 0x7c, 0x9d, 0x48, 0xa6, +0xcb, 0x67, 0x1a, 0x94, 0x7b, 0x80, 0xb5, 0x2e, +0x65, 0xd9, 0x7c, 0x5f, 0xd0, 0xd2, 0x73, 0x82, +0x2c, 0x05, 0x0c, 0xc9, 0x30, 0x58, 0x81, 0xb5, +0xa8, 0x1f, 0x5a, 0x61, 0x88, 0x28, 0x68, 0x95, +0xec, 0xf2, 0x59, 0x18, 0x03, 0x59, 0x8a, 0xc9, +0xe0, 0x12, 0x67, 0xc7, 0x4f, 0xd1, 0x1e, 0x9d, +0x23, 0x78, 0xfa, 0x10, 0xdf, 0x6e, 0x5f, 0xe2, +0xb5, 0x65, 0x60, 0xaf, 0x1b, 0x61, 0x3d, 0x0e, +0x90, 0x15, 0xc0, 0x19, 0xe6, 0x1e, 0xe5, 0x25, +0x93, 0x0c, 0xb7, 0x99, 0x73, 0xe9, 0x9d, 0xa9, +0x98, 0x5d, 0x7a, 0x08, 0xc7, 0x31, 0xf9, 0x6c, +0xad, 0x57, 0x3e, 0x6f, 0x78, 0x7d, 0x62, 0xbe, +0x9b, 0xeb, 0x47, 0x78, 0x95, 0xf3, 0xf9, 0xef, +0x88, 0x19, 0x57, 0x2b, 0x1b, 0xf3, 0x9f, 0xc7, +0x60, 0x28, 0x39, 0xc5, 0x89, 0xb4, 0xae, 0xfd, +0xd4, 0x3e, 0x2a, 0x1f, 0xa8, 0x10, 0x5d, 0xb7, +0x46, 0x85, 0x1f, 0x91, 0xb4, 0xad, 0x13, 0x0e, +0x25, 0x9b, 0xb6, 0xb4, 0xb1, 0x4b, 0xa9, 0x5f, +0x32, 0x25, 0x72, 0x3d, 0x4a, 0x1f, 0x01, 0xe9, +0x43, 0x60, 0x9d, 0x72, 0x08, 0xa3, 0xb9, 0x03, +0x9c, 0xa6, 0xc2, 0x96, 0x84, 0xc7, 0x72, 0x84, +0xe1, 0x6a, 0x6e, 0xcb, 0xf1, 0x45, 0x2e, 0x5c, +0x4d, 0x72, 0xf5, 0x79, 0xc2, 0xcb, 0x32, 0xe4, +0x02, 0xf1, 0x39, 0xd1, 0x71, 0xc9, 0x5e, 0x73, +0xdc, 0x93, 0x84, 0x5d, 0xab, 0x9b, 0x6f, 0x50, +0x92, 0xdb, 0xe7, 0x5c, 0x3b, 0x7f, 0x6f, 0x6d, +0x5a, 0x7c, 0x13, 0xe4, 0xcc, 0x44, 0x81, 0x96, +0x53, 0xf5, 0xca, 0x34, 0x7c, 0x13, 0xe3, 0x1b, +0x14, 0xe1, 0x14, 0x06, 0x81, 0x3b, 0x82, 0x15, +0x06, 0x01, 0x96, 0x97, 0x96, 0xb0, 0xf1, 0xfc, +0xcb, 0xf8, 0x57, 0x2f, 0xff, 0x75, 0x7c, 0x14, +0xf5, 0x5c, 0x3b, 0x34, 0xe9, 0x57, 0xb5, 0x8d, +0x33, 0x62, 0x50, 0xf1, 0xa6, 0x14, 0x44, 0xbf, +0xe2, 0xcd, 0xde, 0x2a, 0x4b, 0xe7, 0x92, 0x23, +0xaf, 0xa8, 0xdc, 0x35, 0xdb, 0x19, 0xe7, 0x9c, +0xb9, 0xa3, 0x8d, 0x94, 0xd0, 0x01, 0x15, 0xcf, +0x8a, 0x14, 0x00, 0xe0, 0x32, 0xea, 0x22, 0xbb, +0xf1, 0x02, 0xf6, 0x30, 0x40, 0x78, 0xde, 0x57, +0x37, 0xdb, 0x5e, 0xaf, 0x87, 0xcf, 0x6e, 0xbe, +0x8a, 0x87, 0xdd, 0xcd, 0x92, 0xfa, 0xd2, 0x3c, +0x4a, 0x23, 0x25, 0x0b, 0xc5, 0xa6, 0x5f, 0xc9, +0x2f, 0x54, 0xde, 0xaa, 0xcd, 0xd2, 0xb2, 0x91, +0x6a, 0x12, 0x87, 0x30, 0x85, 0x70, 0xfb, 0xb9, +0xb3, 0xb9, 0x4a, 0x75, 0xaa, 0x9c, 0x07, 0x52, +0x7d, 0x39, 0x19, 0x39, 0x67, 0xb9, 0xa7, 0xcb, +0xdb, 0x58, 0x5e, 0xbf, 0x86, 0xb8, 0xd3, 0xc1, +0xd2, 0xe8, 0xac, 0xa4, 0xa6, 0x96, 0xc4, 0x8e, +0xce, 0x69, 0x4b, 0x46, 0xdb, 0x8a, 0x7b, 0xa0, +0x49, 0xe3, 0x72, 0x6f, 0x90, 0x26, 0x33, 0x8b, +0x28, 0x13, 0x4c, 0xd2, 0xcc, 0x99, 0x99, 0x34, +0xc1, 0x41, 0xd3, 0x6e, 0xd1, 0x7b, 0x69, 0x53, +0x97, 0xeb, 0x96, 0xb7, 0x81, 0x33, 0x36, 0x9c, +0x19, 0x6c, 0x52, 0xc6, 0x70, 0x38, 0x44, 0xdc, +0xe9, 0x20, 0x9b, 0x11, 0x1d, 0x87, 0x53, 0x96, +0x3a, 0x3b, 0x3d, 0xdf, 0x8b, 0x83, 0x3c, 0x43, +0xf1, 0xe4, 0x21, 0xb6, 0x2e, 0x3e, 0xc7, 0x37, +0xe2, 0x0b, 0xbc, 0x11, 0x9e, 0x21, 0x42, 0x8e, +0x9d, 0x19, 0x71, 0xff, 0x3c, 0x13, 0xc7, 0xaa, +0x84, 0x6d, 0x95, 0xcf, 0xbd, 0xd2, 0xda, 0xe0, +0xde, 0xd1, 0xd2, 0x51, 0x8b, 0x31, 0xf4, 0xaa, +0x5a, 0xda, 0x90, 0x22, 0x6b, 0xe7, 0xbf, 0xe5, +0x1b, 0xa3, 0xd5, 0x57, 0x33, 0xff, 0x4d, 0x5c, +0x99, 0xd9, 0xcd, 0x5b, 0x7e, 0xdd, 0x39, 0x70, +0x61, 0x43, 0xaf, 0xb4, 0x0d, 0x28, 0xd9, 0xde, +0x7d, 0xbe, 0x01, 0xea, 0xba, 0x53, 0xfc, 0x1e, +0xbc, 0xde, 0xec, 0x52, 0x63, 0xc1, 0x04, 0xac, +0xf0, 0xce, 0xf7, 0x7f, 0xfb, 0xcd, 0xd5, 0xf3, +0xa3, 0xd2, 0x64, 0x93, 0xdc, 0xb5, 0x54, 0x11, +0x69, 0x6a, 0x2c, 0x49, 0x48, 0xad, 0x05, 0xc7, +0x27, 0xba, 0xe5, 0xd1, 0x0e, 0x54, 0x03, 0xbd, +0xc8, 0xb2, 0x38, 0xae, 0x32, 0xc4, 0xac, 0xb6, +0x90, 0x24, 0x21, 0x95, 0x7e, 0x00, 0x9a, 0xf4, +0x4f, 0xc0, 0xd5, 0x87, 0x16, 0x57, 0xaf, 0xd9, +0x05, 0x35, 0xe2, 0xad, 0x95, 0xc1, 0x55, 0xe9, +0x94, 0x96, 0xb7, 0x51, 0x4a, 0x3e, 0xb2, 0x0c, +0x6e, 0xf3, 0x05, 0xa6, 0x04, 0x69, 0xf7, 0x2b, +0x5f, 0xc7, 0x3f, 0x3e, 0xf8, 0x31, 0x3e, 0xce, +0x3a, 0xe5, 0xe3, 0x52, 0x0a, 0x67, 0xc7, 0xa3, +0x8b, 0x49, 0x0e, 0xb1, 0xa2, 0xfe, 0x96, 0x9e, +0x94, 0x8a, 0x67, 0x65, 0x29, 0x1f, 0x97, 0x5e, +0x29, 0x2d, 0x50, 0x95, 0x6c, 0xe5, 0x19, 0x77, +0x56, 0x7e, 0xc5, 0xb1, 0x4b, 0x48, 0xe3, 0x15, +0xe7, 0x16, 0x26, 0x31, 0xf0, 0x74, 0x69, 0x96, +0x61, 0xd4, 0x59, 0xc5, 0x07, 0xeb, 0x07, 0xb8, +0x16, 0x03, 0xd9, 0x78, 0x84, 0xa5, 0x7c, 0x7a, +0x77, 0x38, 0x11, 0x80, 0x24, 0x49, 0x30, 0xb8, +0xf3, 0x1a, 0x3e, 0xc1, 0x52, 0xd9, 0xd1, 0x45, +0x48, 0x35, 0xa6, 0x84, 0x22, 0x8f, 0xab, 0x88, +0xef, 0x2a, 0xd3, 0x02, 0xe8, 0x36, 0x79, 0xdf, +0x99, 0x7f, 0x21, 0x51, 0xcb, 0xfe, 0x2a, 0xa9, +0x60, 0xb5, 0x71, 0xd5, 0x08, 0xb9, 0x56, 0x7e, +0x51, 0xe0, 0x2c, 0x5a, 0xc2, 0x67, 0xed, 0x0d, +0xdc, 0x5f, 0xd9, 0xc3, 0xa3, 0xcd, 0x3b, 0x88, +0x96, 0x96, 0xb1, 0x84, 0x0c, 0x4b, 0x71, 0xe0, +0x08, 0x51, 0xbf, 0xdf, 0x47, 0x1e, 0x84, 0xce, +0x31, 0x4e, 0xf3, 0x1e, 0xa7, 0x67, 0x3a, 0xa6, +0xc9, 0xd7, 0x97, 0xcf, 0xc4, 0x25, 0xa5, 0x5c, +0x5a, 0x77, 0xd6, 0x7a, 0xe5, 0x11, 0x26, 0x35, +0x3b, 0xbd, 0x26, 0x50, 0xd4, 0xed, 0x3b, 0x72, +0xef, 0x90, 0xfb, 0x06, 0xbd, 0xa3, 0xb6, 0x69, +0xc7, 0xdc, 0xb8, 0xd3, 0x5c, 0x14, 0x45, 0x53, +0x15, 0x7b, 0xd0, 0xaa, 0x48, 0xf5, 0xd2, 0xa1, +0x0e, 0xc0, 0xfc, 0x1e, 0xf9, 0x38, 0xc2, 0x64, +0x38, 0x44, 0x1b, 0x19, 0xf6, 0xce, 0x1e, 0xe2, +0xa5, 0xc9, 0x11, 0x7e, 0xd8, 0x19, 0x60, 0xb9, +0xd3, 0xc1, 0x6e, 0x12, 0x60, 0x90, 0x15, 0x4e, +0x62, 0x0f, 0x8a, 0x99, 0xad, 0x5d, 0x1c, 0xe1, +0x92, 0x2a, 0x61, 0x75, 0x7d, 0xf3, 0xc8, 0x65, +0x1a, 0xb3, 0x27, 0x09, 0x23, 0xd0, 0x7c, 0xfe, +0xd3, 0xfa, 0xb7, 0xe6, 0xbf, 0xb6, 0x1f, 0xd4, +0x05, 0x6b, 0x31, 0xf6, 0x8d, 0x8a, 0xc6, 0x4e, +0x96, 0xaf, 0xad, 0x37, 0xb1, 0xbe, 0x35, 0x0f, +0xf2, 0x4a, 0x7b, 0xa4, 0x70, 0xa4, 0x94, 0x6b, +0x3a, 0xc1, 0x15, 0x45, 0x49, 0x12, 0xaf, 0xb5, +0xa7, 0x1b, 0xa6, 0x80, 0x92, 0x03, 0x9c, 0x9c, +0x4c, 0x97, 0xe3, 0x49, 0xe9, 0x78, 0x0a, 0xfd, +0xe7, 0xb6, 0x21, 0x4d, 0xfd, 0xc5, 0x17, 0x84, +0xf4, 0x6c, 0x95, 0x1e, 0xac, 0xda, 0xa2, 0xb6, +0x9c, 0x65, 0x2c, 0x95, 0xb7, 0x94, 0xb4, 0xb5, +0x0d, 0x44, 0x2e, 0x36, 0x5e, 0xa7, 0xcc, 0xcb, +0xdb, 0x67, 0xd9, 0xd5, 0xa4, 0x19, 0x42, 0x73, +0x90, 0x91, 0xd1, 0xe3, 0x88, 0xe3, 0x96, 0x1b, +0x84, 0xcf, 0x01, 0x88, 0x6f, 0x0a, 0x9a, 0x74, +0x23, 0x37, 0xb9, 0x5e, 0xaf, 0x87, 0xbd, 0xe7, +0x0e, 0xf0, 0x0f, 0x6e, 0xfd, 0x18, 0x8f, 0x90, +0x54, 0x1d, 0xca, 0x14, 0xce, 0x4e, 0x55, 0x07, +0x37, 0xd8, 0xe8, 0x9b, 0xfc, 0x57, 0x83, 0x57, +0x5c, 0x35, 0x8a, 0x92, 0xaf, 0x7c, 0xc6, 0x21, +0xab, 0x75, 0x71, 0x55, 0x59, 0x38, 0x0d, 0x7b, +0x9a, 0xc6, 0x09, 0x9e, 0x6c, 0x1e, 0x20, 0xe9, +0x2e, 0x61, 0xfb, 0xe8, 0x43, 0x9c, 0x9f, 0x9f, +0xbb, 0x73, 0xfc, 0x1b, 0x37, 0x6f, 0xe3, 0x93, +0x1b, 0xaf, 0xe0, 0xb8, 0xa5, 0x2c, 0x24, 0x45, +0x8d, 0x58, 0x5b, 0x6f, 0x93, 0xfe, 0xb1, 0x6c, +0x8a, 0x5f, 0xc6, 0x7f, 0x11, 0x9c, 0xa2, 0x36, +0x3d, 0xdf, 0x68, 0xd9, 0x58, 0x4d, 0xb2, 0x0c, +0x97, 0x41, 0x07, 0x4f, 0xb3, 0x00, 0x1f, 0x26, +0xd7, 0xf1, 0xf3, 0xcd, 0x97, 0xf1, 0x70, 0xe3, +0x00, 0xb7, 0x3a, 0x39, 0x30, 0x1e, 0x22, 0x46, +0x8e, 0x4e, 0x1c, 0x57, 0xbc, 0xd3, 0x35, 0x67, +0x4e, 0xed, 0xbd, 0xe6, 0x88, 0x26, 0x99, 0x7e, +0xbe, 0xaf, 0x68, 0xc2, 0x85, 0x06, 0x1a, 0x03, +0xaf, 0xe5, 0x27, 0x22, 0xcb, 0x8f, 0xac, 0x71, +0xa7, 0x5d, 0x29, 0x6d, 0x6b, 0x82, 0x0c, 0x8f, +0x25, 0xc1, 0xf7, 0x37, 0xbe, 0x9f, 0x58, 0x6d, +0x95, 0x84, 0x9f, 0xef, 0x1b, 0xfc, 0xfb, 0x68, +0x34, 0x42, 0xab, 0xd5, 0x42, 0x31, 0x53, 0x89, +0x23, 0x4b, 0x71, 0xf2, 0xf4, 0x09, 0xf6, 0xf3, +0x53, 0xbc, 0x3c, 0x7a, 0x84, 0xe7, 0xd3, 0x3e, +0x7e, 0xad, 0x3b, 0xc1, 0x30, 0xee, 0xe2, 0x28, +0x6d, 0x21, 0x28, 0xa6, 0x02, 0x42, 0x9a, 0xe5, +0xea, 0x3c, 0xd0, 0x82, 0x8f, 0x54, 0xd6, 0x6a, +0xa6, 0x84, 0x10, 0xf5, 0x98, 0xb5, 0xd4, 0x79, +0xa4, 0x99, 0xcf, 0xfe, 0x1c, 0xe6, 0x7f, 0x9d, +0x46, 0xad, 0x0e, 0xbf, 0x26, 0xf5, 0x78, 0x6d, +0xda, 0x35, 0xff, 0x2b, 0x47, 0x78, 0x95, 0x73, +0xf7, 0x8d, 0xd6, 0x2b, 0x80, 0xf0, 0xd6, 0x77, +0x7f, 0xeb, 0xcd, 0xce, 0x93, 0xfb, 0xea, 0x99, +0xeb, 0x42, 0xdc, 0x88, 0xc3, 0x9d, 0x56, 0xe4, +0x82, 0xb3, 0x88, 0xb0, 0x8c, 0xad, 0xac, 0x5d, +0x74, 0x20, 0x09, 0x9f, 0xac, 0x93, 0x4b, 0xa6, +0x72, 0x31, 0x52, 0x1e, 0xf9, 0x5d, 0xf3, 0x22, +0xf5, 0x31, 0x08, 0xdc, 0xeb, 0x5e, 0xaa, 0xc0, +0x65, 0xbf, 0x48, 0x93, 0x82, 0x24, 0xc4, 0xd2, +0xc9, 0x46, 0x9a, 0x2c, 0xf8, 0x3b, 0x0d, 0xb8, +0x43, 0x20, 0x5f, 0xcc, 0xd2, 0x56, 0x29, 0xfb, +0x9b, 0x08, 0xf9, 0xbf, 0xba, 0xfd, 0x03, 0xbc, +0x87, 0xa9, 0x3f, 0x43, 0xde, 0x0a, 0xa7, 0x61, +0x41, 0x5b, 0xf3, 0x58, 0xdf, 0x6e, 0x82, 0x64, +0x59, 0x39, 0x96, 0x32, 0x30, 0xbd, 0x28, 0x80, +0xa7, 0x6f, 0x89, 0x58, 0xca, 0xf2, 0x3b, 0x2d, +0x72, 0x2d, 0x5f, 0x51, 0x20, 0xe7, 0x92, 0xb8, +0xe4, 0xc6, 0xc3, 0x08, 0x40, 0x4b, 0x2f, 0x8f, +0xf0, 0x93, 0xe5, 0x13, 0xbe, 0xb3, 0x7c, 0x39, +0x97, 0xd0, 0xd3, 0xd4, 0xc6, 0x8f, 0xbc, 0x43, +0x67, 0xdf, 0x27, 0x79, 0x81, 0xa3, 0xa5, 0x6d, +0xac, 0x6c, 0xed, 0x20, 0x9e, 0x8c, 0x10, 0x5e, +0x9c, 0x20, 0x8e, 0x42, 0xbc, 0x77, 0xf7, 0xb7, +0xf1, 0x51, 0x72, 0x1d, 0xe3, 0x1c, 0x73, 0xbb, +0x1a, 0x2f, 0x8f, 0xfa, 0x22, 0xcf, 0xa6, 0x38, +0x64, 0x93, 0x92, 0xdd, 0x7c, 0x7a, 0x21, 0x83, +0xa7, 0xbf, 0x8a, 0x7c, 0x9a, 0x8f, 0xfa, 0x87, +0xdb, 0xd8, 0x8b, 0xc2, 0xc6, 0xdf, 0x57, 0x1e, +0xef, 0x47, 0xd9, 0x5f, 0x51, 0x5c, 0x3e, 0x07, +0x4b, 0xf8, 0x59, 0xfd, 0xcf, 0x63, 0x43, 0xcf, +0xda, 0x57, 0x99, 0x17, 0xad, 0xa9, 0xe4, 0x7b, +0x8e, 0x00, 0x1f, 0x2e, 0xdf, 0xc4, 0x3b, 0xdb, +0x5f, 0xc3, 0x68, 0xe7, 0x0e, 0x96, 0xb3, 0x11, +0x36, 0xdb, 0x2d, 0x24, 0xed, 0x58, 0x25, 0x4e, +0x7c, 0x7d, 0x04, 0xed, 0x0e, 0x8a, 0x2c, 0xab, +0x98, 0xa8, 0xf8, 0xda, 0x96, 0xf3, 0x5f, 0xae, +0x41, 0x99, 0x5e, 0x13, 0x32, 0x24, 0xc1, 0xe6, +0x78, 0xc8, 0x4b, 0x5c, 0x34, 0x29, 0x5a, 0xee, +0x57, 0x9a, 0x10, 0x23, 0xb5, 0x8a, 0xbc, 0x5c, +0x2e, 0xf5, 0xfb, 0x24, 0x76, 0x69, 0x96, 0xcb, +0x5a, 0xb3, 0xb8, 0xfa, 0x98, 0x33, 0x3b, 0xfc, +0x98, 0x1b, 0x11, 0x75, 0xf2, 0x86, 0x1f, 0xa5, +0x39, 0x42, 0x14, 0xe8, 0xa4, 0x43, 0xac, 0x8d, +0xcf, 0xf1, 0xc3, 0xee, 0x10, 0xb7, 0xc2, 0x31, +0x7e, 0x73, 0x33, 0xc2, 0xd7, 0xc2, 0x01, 0xee, +0x74, 0xa6, 0x4c, 0x7d, 0x3a, 0xc9, 0x10, 0x44, +0x31, 0x26, 0x59, 0x56, 0xf6, 0xb1, 0x00, 0xf4, +0xf9, 0x4b, 0x77, 0x6a, 0xf0, 0xbd, 0x80, 0xcf, +0x87, 0x8c, 0x5f, 0xc3, 0xdb, 0x32, 0xd7, 0x9b, +0xb5, 0x7e, 0x72, 0x26, 0x75, 0x3f, 0xd3, 0xfc, +0x57, 0xe6, 0x3b, 0x7f, 0xce, 0x69, 0xdf, 0xe1, +0xd2, 0xb8, 0x6f, 0xff, 0x91, 0xeb, 0x5b, 0xec, +0x67, 0xda, 0x7e, 0xe4, 0x24, 0xeb, 0xb8, 0xe3, +0xdf, 0xcf, 0x14, 0xfc, 0x73, 0xc2, 0x87, 0xff, +0x31, 0xd3, 0xa0, 0xda, 0x5e, 0x1a, 0x2b, 0x5a, +0x9f, 0xb3, 0xfe, 0x0b, 0x77, 0x5e, 0xff, 0xde, +0x9b, 0xab, 0xe7, 0x8f, 0x2b, 0x84, 0x8b, 0x4b, +0x9b, 0x52, 0x0d, 0x04, 0xa0, 0x14, 0xe5, 0x49, +0x2e, 0x00, 0x4d, 0xf5, 0x2e, 0x8f, 0x82, 0x50, +0x7e, 0x9e, 0x4e, 0xd6, 0xc9, 0x9d, 0xbc, 0x68, +0x31, 0xc8, 0x85, 0xc9, 0x83, 0xac, 0x68, 0x8e, +0x37, 0x7c, 0x23, 0xd0, 0x1c, 0xd2, 0x24, 0x67, +0x2c, 0x83, 0x44, 0x48, 0x89, 0x9d, 0x2f, 0x5a, +0x7a, 0x4f, 0xb7, 0x96, 0x71, 0xfb, 0xb9, 0x8f, +0x93, 0xe7, 0xd2, 0x09, 0x2f, 0x8f, 0x6f, 0x04, +0x1c, 0xe8, 0x7b, 0x18, 0xb7, 0x51, 0xe4, 0x99, +0xba, 0x49, 0xed, 0xee, 0xee, 0x62, 0xfd, 0x8d, +0xdf, 0xc2, 0xbf, 0xb8, 0xf9, 0x3d, 0xfc, 0x74, +0xd4, 0x71, 0xe7, 0xad, 0x73, 0x76, 0xc1, 0xcd, +0xb4, 0xb0, 0x78, 0x3e, 0x69, 0x5a, 0xc1, 0x9c, +0xb8, 0x03, 0xd3, 0x49, 0x44, 0x1c, 0xbf, 0xcc, +0x43, 0x93, 0xab, 0x25, 0x2e, 0xc9, 0x09, 0x82, +0x79, 0x59, 0x1a, 0xf0, 0xfa, 0x38, 0x37, 0xcf, +0x71, 0xe0, 0x40, 0x9b, 0x03, 0x7d, 0x93, 0xe5, +0xd3, 0x86, 0x42, 0xcf, 0x9c, 0x30, 0xf9, 0xca, +0xa3, 0x05, 0x2a, 0xbe, 0x1f, 0x25, 0x3d, 0x8c, +0x77, 0x5f, 0x40, 0x7e, 0xfd, 0x16, 0x26, 0xcf, +0xbf, 0x86, 0x07, 0xbd, 0x03, 0x9c, 0x15, 0xc1, +0x9c, 0x39, 0x90, 0xe5, 0x51, 0x7f, 0xd1, 0xed, +0x48, 0x5a, 0xff, 0x11, 0x81, 0xd5, 0xf0, 0xa1, +0x8b, 0x13, 0x24, 0xfe, 0x56, 0xff, 0xd7, 0xb5, +0x8f, 0xf7, 0x47, 0x9e, 0x56, 0xd3, 0x51, 0x48, +0x58, 0x5e, 0xbe, 0x9c, 0x03, 0x75, 0xed, 0xb3, +0xe6, 0x45, 0x91, 0x23, 0x45, 0x6b, 0xaa, 0xe9, +0x68, 0x75, 0xf0, 0xfe, 0xce, 0xd7, 0xf0, 0x68, +0xf3, 0x00, 0x77, 0xd3, 0xa7, 0x08, 0x66, 0xf3, +0x85, 0xaf, 0x73, 0xce, 0x08, 0x93, 0xc6, 0x0f, +0xa8, 0x6a, 0xe4, 0xa4, 0xd4, 0x0e, 0xcc, 0xd7, +0x96, 0x3c, 0x1d, 0x42, 0xf9, 0xa5, 0x99, 0x8b, +0xef, 0x5b, 0xd2, 0x59, 0x8d, 0xd7, 0x21, 0x35, +0x8e, 0x04, 0xdc, 0xa1, 0x97, 0xf0, 0x90, 0x44, +0x99, 0x13, 0x6a, 0xed, 0xbc, 0xbb, 0xe5, 0xc0, +0x6b, 0x39, 0xf8, 0x95, 0x04, 0x87, 0xd9, 0x98, +0x69, 0x7b, 0x14, 0x67, 0x70, 0x5a, 0x74, 0xde, +0x3f, 0x9e, 0x06, 0xa3, 0xc9, 0xb2, 0x0c, 0xe9, +0x64, 0x8c, 0xf3, 0xc1, 0x10, 0x1b, 0x83, 0xa7, +0xe8, 0x3c, 0xfd, 0x0c, 0x6b, 0xa7, 0x8f, 0x70, +0x90, 0xf6, 0xf1, 0x6a, 0x78, 0x89, 0xef, 0x2f, +0x8d, 0xf0, 0x93, 0x5e, 0x81, 0x8d, 0xa4, 0x83, +0xb5, 0x20, 0x47, 0x11, 0x27, 0xc8, 0x5a, 0x11, +0x26, 0x74, 0xf3, 0x17, 0x27, 0x40, 0x34, 0xbf, +0xe4, 0xfc, 0xe0, 0xf3, 0xa1, 0xc8, 0x99, 0x04, +0x2f, 0xe6, 0x5a, 0xd3, 0xf9, 0xe5, 0xdb, 0x7f, +0xea, 0xe6, 0xbf, 0xdc, 0x1f, 0x68, 0xfd, 0x69, +0xf3, 0xbf, 0xc9, 0xfe, 0x23, 0xf1, 0xe3, 0xa0, +0xad, 0xaf, 0x28, 0x6e, 0xb6, 0x9f, 0x59, 0xf8, +0xf3, 0xfe, 0x93, 0xcc, 0xb6, 0xd5, 0x1f, 0x46, +0xff, 0x85, 0x37, 0xbe, 0xfd, 0x1b, 0x6f, 0x6e, +0x4f, 0x4e, 0x9d, 0x8a, 0x48, 0x12, 0x4b, 0x39, +0xf1, 0xf9, 0x44, 0x96, 0x13, 0x92, 0x4f, 0x62, +0xa9, 0xa6, 0x96, 0xf6, 0x77, 0x9f, 0x4a, 0xdd, +0xb2, 0x4f, 0x69, 0x6a, 0x6f, 0xa9, 0x8a, 0xd3, +0x02, 0xdc, 0x48, 0xa6, 0x84, 0xe3, 0xc3, 0xf3, +0xf0, 0xba, 0xa5, 0x4d, 0x4c, 0xd6, 0xc9, 0xd3, +0xf8, 0x24, 0x6c, 0xb9, 0x81, 0x58, 0xcc, 0x8e, +0xdc, 0x74, 0x78, 0x99, 0x93, 0x34, 0x9b, 0x1d, +0x4d, 0x6b, 0xb9, 0xf6, 0x76, 0x92, 0x2e, 0x82, +0x20, 0xc4, 0xfa, 0xda, 0x1a, 0xae, 0xbd, 0xf4, +0x0a, 0x3e, 0x78, 0xf5, 0xaf, 0xe1, 0x9f, 0xb4, +0x0f, 0xf0, 0x20, 0x9d, 0x07, 0x0a, 0xc9, 0x89, +0xa3, 0xd3, 0x26, 0x97, 0x9c, 0x88, 0xc4, 0x01, +0x6a, 0x20, 0x24, 0xb2, 0x4a, 0x79, 0x7c, 0xe2, +0xe7, 0x82, 0x00, 0xf2, 0xbc, 0x8e, 0xb3, 0x6f, +0xd9, 0xe5, 0xf1, 0xb4, 0x79, 0x5a, 0x5d, 0x58, +0xee, 0xee, 0xe1, 0xc9, 0x4c, 0xca, 0xc5, 0x5c, +0x8a, 0xf7, 0x95, 0xa7, 0xf5, 0x05, 0xa6, 0xcc, +0xce, 0x79, 0xd0, 0xc6, 0x60, 0x7d, 0x17, 0x9f, +0x84, 0xab, 0x18, 0x60, 0x96, 0x26, 0xcf, 0xf4, +0xc5, 0x24, 0xf1, 0xe6, 0xf8, 0x52, 0x5a, 0x5e, +0x9f, 0xec, 0x0f, 0xda, 0x7c, 0x8a, 0x7c, 0xfa, +0x17, 0x44, 0xd5, 0xfc, 0x57, 0xc0, 0xdf, 0xa5, +0x91, 0xf5, 0x56, 0xf2, 0xcf, 0x18, 0x8c, 0xa2, +0xf0, 0x8f, 0x27, 0xef, 0x7b, 0x22, 0xfa, 0x9c, +0x21, 0xcc, 0xd3, 0x69, 0x59, 0x34, 0x77, 0x84, +0x24, 0x72, 0x86, 0x18, 0x1f, 0xad, 0xec, 0xe3, +0x56, 0x30, 0xc0, 0x5a, 0x04, 0xe4, 0x93, 0xf9, +0x89, 0x01, 0xe9, 0x25, 0x6e, 0x39, 0x8c, 0xc9, +0x35, 0x46, 0xef, 0x24, 0xb3, 0x2d, 0xcd, 0x4e, +0x92, 0x80, 0x5a, 0xeb, 0x5f, 0x4a, 0xfe, 0xbc, +0x4c, 0x4d, 0x92, 0x97, 0x0c, 0x82, 0x8c, 0x52, +0xa7, 0x31, 0x06, 0x32, 0xaf, 0xe6, 0xa7, 0xa3, +0xed, 0x09, 0xda, 0x51, 0x55, 0x69, 0x66, 0x93, +0xed, 0xe2, 0x7b, 0x22, 0xdd, 0x4c, 0x87, 0x3c, +0x43, 0xab, 0xd5, 0xc2, 0xd3, 0xb3, 0x0b, 0xa4, +0xe3, 0x11, 0xd2, 0x34, 0xc5, 0xf8, 0xec, 0x04, +0xc1, 0xe0, 0x1c, 0xe9, 0xd3, 0x47, 0xb8, 0x3d, +0x3a, 0xc2, 0x1b, 0xbd, 0x10, 0xbf, 0x11, 0x9f, +0xe2, 0xc5, 0xe5, 0x00, 0x49, 0xd8, 0xc2, 0x66, +0x3b, 0x44, 0x37, 0x0e, 0x91, 0x20, 0x43, 0x11, +0xc6, 0x88, 0xf2, 0x14, 0xa9, 0x36, 0x9f, 0xf8, +0x3c, 0x75, 0x1a, 0xa2, 0xa2, 0xba, 0x16, 0xb4, +0xf9, 0x45, 0x73, 0x8a, 0xe6, 0x3f, 0x11, 0x7d, +0x6b, 0xff, 0xa9, 0x2b, 0x4f, 0xee, 0x3f, 0x7c, +0x3d, 0xc8, 0xf5, 0x79, 0x95, 0xfd, 0x87, 0xe6, +0xbf, 0x6c, 0x2b, 0x49, 0xee, 0xc4, 0x40, 0x37, +0x2d, 0xcf, 0xc2, 0x9f, 0xf7, 0x1f, 0x31, 0x21, +0x4d, 0xf6, 0x03, 0x65, 0x7d, 0x87, 0x7b, 0xdf, +0xfa, 0xe1, 0x9b, 0x1b, 0x83, 0xa7, 0x6a, 0xc0, +0x05, 0x19, 0x8b, 0x98, 0xab, 0xa4, 0x68, 0x11, +0x68, 0x6a, 0x65, 0x29, 0xc5, 0xd3, 0x44, 0xd3, +0x26, 0xba, 0x24, 0x84, 0xbc, 0x5c, 0x0e, 0x92, +0xdb, 0x95, 0x44, 0x51, 0x7a, 0xd0, 0xf2, 0x3a, +0x39, 0x43, 0x21, 0xcf, 0x81, 0x72, 0x3c, 0xf8, +0xe2, 0xf0, 0xd5, 0xa1, 0x69, 0x00, 0xe8, 0xfa, +0x51, 0xee, 0x50, 0x23, 0xb5, 0x1a, 0x54, 0xa7, +0x66, 0x73, 0x97, 0x4c, 0x08, 0xef, 0x27, 0x1e, +0xc6, 0x35, 0x8a, 0x22, 0xb4, 0x97, 0x96, 0xb1, +0xd4, 0x69, 0x63, 0x7d, 0x6d, 0x0d, 0xdb, 0x7b, +0x37, 0xf0, 0xfb, 0x2f, 0xfe, 0x04, 0xff, 0x26, +0x5f, 0x9d, 0x72, 0xd7, 0x5c, 0x8d, 0x44, 0x93, +0x8e, 0x4f, 0x4a, 0xc9, 0x49, 0xd2, 0x44, 0x04, +0xaa, 0x84, 0x87, 0x3f, 0x6b, 0x93, 0x3b, 0x4f, +0xab, 0x0b, 0x49, 0x4a, 0x9e, 0x1c, 0xb4, 0xf4, +0x5a, 0xbd, 0xbc, 0x2c, 0xa9, 0x59, 0xe0, 0x52, +0x2f, 0xa9, 0xb5, 0xb8, 0x64, 0x6a, 0xe1, 0x5f, +0xf3, 0x3c, 0x49, 0x99, 0x7a, 0xad, 0xae, 0xdc, +0xa6, 0xe5, 0x6b, 0xfd, 0xc1, 0xb9, 0xee, 0x30, +0xaa, 0xf6, 0xe7, 0x33, 0xe2, 0x5f, 0x0b, 0x52, +0xa3, 0xc1, 0xcb, 0x90, 0xe3, 0xca, 0xd3, 0xf3, +0x8d, 0x8b, 0xda, 0xc3, 0x35, 0x2d, 0x0a, 0x3e, +0x83, 0x56, 0x84, 0x7b, 0xbd, 0x3b, 0x58, 0xbf, +0xb6, 0x89, 0xfd, 0xa4, 0x85, 0x38, 0x1d, 0x57, +0x88, 0x99, 0x74, 0x3c, 0x03, 0xec, 0xbb, 0x1b, +0xb4, 0x0b, 0x8f, 0xa8, 0x1c, 0xcd, 0xe6, 0x2c, +0xcf, 0xae, 0x4b, 0xfb, 0xb8, 0xcc, 0xaf, 0xa9, +0xe0, 0x25, 0xf1, 0x94, 0x7b, 0x86, 0x73, 0x62, +0x13, 0xeb, 0x9a, 0xa7, 0xe5, 0x44, 0xdf, 0x17, +0x1f, 0xc2, 0xba, 0x58, 0x46, 0xfa, 0x31, 0x59, +0x97, 0xc1, 0x8c, 0x66, 0xaa, 0x72, 0xb9, 0xdf, +0x0e, 0x87, 0x43, 0x0c, 0x2f, 0xce, 0x4b, 0x61, +0xaa, 0x29, 0x56, 0xfc, 0xf9, 0xf9, 0x39, 0x2e, +0xfb, 0xc7, 0x38, 0x3d, 0x7a, 0x8c, 0xf0, 0xf1, +0xa7, 0x78, 0x29, 0xef, 0xe3, 0xbb, 0xe1, 0x19, +0x5e, 0xb9, 0xfc, 0x14, 0x2f, 0xe3, 0x0c, 0xdf, +0xe9, 0x0c, 0xb0, 0x95, 0xc4, 0xd8, 0xe8, 0x84, +0x38, 0x0e, 0x97, 0x30, 0x1e, 0x8f, 0xea, 0xe7, +0x9a, 0x36, 0x1f, 0xe5, 0xfc, 0x92, 0xf3, 0x3f, +0xf3, 0x68, 0xf5, 0xea, 0xe6, 0xb7, 0xb6, 0x9f, +0x58, 0xf3, 0xf9, 0xaa, 0xe9, 0xad, 0xf5, 0x22, +0xb5, 0x6e, 0xbe, 0xfd, 0xb1, 0x0e, 0x64, 0xfb, +0xb4, 0xfc, 0x75, 0xed, 0xa1, 0xfd, 0x29, 0xee, +0x20, 0xdc, 0xfd, 0xc6, 0xf7, 0x4b, 0xb1, 0xd9, +0xe9, 0x3f, 0x9f, 0x80, 0xda, 0x19, 0x6d, 0x7a, +0x96, 0x8b, 0x09, 0xb0, 0x3d, 0x4d, 0x2d, 0xf5, +0x31, 0x07, 0x19, 0x1b, 0xdd, 0x77, 0x83, 0x9b, +0xe4, 0xe8, 0x35, 0x8e, 0x9d, 0xe3, 0x21, 0x1d, +0xf0, 0x24, 0x7e, 0x3c, 0xfa, 0x9a, 0x2c, 0x43, +0xf6, 0x8f, 0x6c, 0x9f, 0xb6, 0xc8, 0xb4, 0x1b, +0x9c, 0x34, 0x33, 0x06, 0xe7, 0xae, 0xa5, 0xaa, +0x50, 0xe2, 0x0c, 0x00, 0xad, 0x70, 0xaa, 0xa6, +0x5c, 0xda, 0xde, 0xc3, 0xef, 0xdf, 0xfd, 0x5f, +0xe1, 0xbd, 0x62, 0x99, 0xd9, 0x79, 0x18, 0x70, +0xa2, 0x4d, 0xd2, 0x14, 0x77, 0xaa, 0xe0, 0x1c, +0x32, 0x11, 0x79, 0x92, 0x78, 0xe9, 0xb9, 0x28, +0xa6, 0x93, 0x05, 0xd0, 0xd3, 0xd3, 0xfd, 0xc4, +0xc4, 0x55, 0x4a, 0xc9, 0x93, 0xd2, 0x72, 0xc2, +0x40, 0x93, 0x93, 0xa4, 0x3c, 0xeb, 0x7d, 0x9e, +0xcd, 0xf3, 0x52, 0x39, 0xd2, 0xae, 0x44, 0xd2, +0x79, 0x2b, 0xa8, 0xa6, 0xd5, 0xda, 0x53, 0xd7, +0x3e, 0xde, 0xce, 0xb8, 0xd3, 0xbc, 0x3d, 0x56, +0xfb, 0x68, 0x0c, 0x28, 0x2f, 0x50, 0x76, 0x6e, +0xa9, 0xeb, 0xff, 0xa6, 0xcf, 0xf4, 0x8e, 0x8f, +0x07, 0xc7, 0x43, 0x4a, 0x44, 0xf4, 0x9d, 0x98, +0x16, 0xf9, 0x9e, 0xda, 0x4d, 0x7d, 0xe2, 0xd2, +0xa3, 0x3c, 0xcf, 0x0c, 0xfc, 0x27, 0x45, 0x0b, +0xef, 0xa7, 0x6d, 0x7c, 0xbe, 0xb2, 0x8b, 0xde, +0xfa, 0x1a, 0xd6, 0x5b, 0x19, 0xc6, 0x67, 0x27, +0xaa, 0xff, 0x08, 0xad, 0x73, 0x79, 0x72, 0x46, +0x73, 0x6c, 0x93, 0x66, 0x2f, 0x1f, 0xe1, 0x96, +0x77, 0x37, 0x0c, 0x86, 0x23, 0xf5, 0xc8, 0x9a, +0x4f, 0xbb, 0x26, 0xc3, 0x4b, 0x5b, 0x0c, 0x00, +0x5f, 0xf3, 0x5a, 0x58, 0x66, 0xad, 0x1d, 0x1c, +0x0f, 0x2d, 0x7c, 0xb4, 0x24, 0xe6, 0x7c, 0x4f, +0x28, 0xa9, 0xec, 0xf3, 0x4c, 0x75, 0xac, 0x1d, +0x31, 0x7b, 0x38, 0xf5, 0xb3, 0xbc, 0x14, 0xc6, +0xed, 0xb7, 0x59, 0x86, 0x8b, 0xb3, 0x53, 0x4c, +0x06, 0x97, 0x08, 0x2e, 0xfa, 0xe8, 0x0e, 0x4f, +0x71, 0xb3, 0xb8, 0xc0, 0x2b, 0xf9, 0x53, 0x7c, +0x3d, 0x1e, 0x61, 0x18, 0x75, 0x30, 0x9a, 0x64, +0x18, 0x14, 0x28, 0xcf, 0x15, 0x22, 0x26, 0x7c, +0x1d, 0xfb, 0xe6, 0xd7, 0x6c, 0xfe, 0x3b, 0xc7, +0x55, 0xbe, 0x9e, 0xe4, 0x1c, 0x94, 0xf3, 0x9d, +0xef, 0x0d, 0xfc, 0x3b, 0xff, 0x46, 0xf3, 0x93, +0x97, 0xc9, 0x08, 0x5e, 0x25, 0x7d, 0x10, 0xf9, +0xe7, 0xbf, 0x7c, 0x2f, 0xd6, 0xc4, 0x72, 0x3b, +0xc6, 0x6d, 0x9c, 0xa3, 0xdb, 0xca, 0x71, 0x96, +0x42, 0x6f, 0x8f, 0xaf, 0x7d, 0xbe, 0xfd, 0x8e, +0x9b, 0x41, 0xe5, 0xde, 0xc6, 0xf7, 0x9b, 0xd9, +0x7e, 0xe2, 0x8e, 0xa6, 0xa1, 0x9d, 0x00, 0x59, +0xaa, 0x4a, 0xe7, 0x7c, 0x02, 0x4a, 0x67, 0x11, +0xce, 0x91, 0xfa, 0x2e, 0x5e, 0xa0, 0xfc, 0xe7, +0xe7, 0xe7, 0xce, 0xce, 0xcd, 0x17, 0x0b, 0x4d, +0x38, 0x79, 0x43, 0x93, 0x54, 0x41, 0x69, 0x1c, +0xb4, 0xb6, 0xf0, 0x34, 0x09, 0x3b, 0x49, 0x12, +0x77, 0x83, 0x99, 0xc4, 0x4f, 0x8b, 0xe6, 0x64, +0x11, 0x73, 0xbe, 0x38, 0x34, 0xb0, 0x88, 0xbd, +0xdc, 0xa4, 0xe4, 0x77, 0x19, 0x80, 0x23, 0x4d, +0x53, 0x14, 0xad, 0x00, 0x41, 0x10, 0xa0, 0xc8, +0x73, 0xd7, 0x37, 0x61, 0xab, 0x85, 0xa7, 0x3f, +0xfe, 0xbb, 0xf8, 0xc3, 0x9d, 0x6f, 0xe2, 0x41, +0x31, 0x0f, 0x6a, 0x40, 0x0b, 0xa5, 0x44, 0xc4, +0x39, 0x91, 0x97, 0xc7, 0x40, 0xe8, 0xb7, 0xb4, +0x69, 0xf3, 0x67, 0x69, 0xd3, 0x91, 0xdf, 0xa5, +0x16, 0xc0, 0xc2, 0x03, 0xa8, 0xda, 0x96, 0xb8, +0xfa, 0xd7, 0xaa, 0xcf, 0xa9, 0xe0, 0xf2, 0x6a, +0xfd, 0x1c, 0x7f, 0x2e, 0x49, 0xfa, 0xda, 0x43, +0x6a, 0x6d, 0xc2, 0x95, 0xf0, 0xa0, 0x85, 0x1a, +0x44, 0x55, 0xe9, 0xb3, 0x49, 0x7b, 0xe4, 0x33, +0xb5, 0x83, 0xf7, 0xb3, 0x4c, 0x2f, 0xdf, 0x35, +0xc1, 0x57, 0x6b, 0x9f, 0x2c, 0x83, 0xf7, 0x57, +0x1d, 0x1e, 0x9c, 0xc1, 0x90, 0xe5, 0x34, 0x79, +0x6f, 0xe1, 0x3f, 0xab, 0xf7, 0x78, 0x9c, 0xe3, +0x5e, 0x67, 0x1b, 0xfd, 0x6b, 0xfb, 0xc0, 0xe6, +0x1e, 0xd2, 0x8d, 0x5d, 0x74, 0xb2, 0x31, 0xae, +0xad, 0xad, 0xb8, 0xfd, 0x46, 0x32, 0xcf, 0x7c, +0xbd, 0x72, 0xc2, 0x66, 0x99, 0xb7, 0x2c, 0x86, +0x5f, 0xee, 0x49, 0xcb, 0x4b, 0x4b, 0x15, 0xdb, +0xb8, 0x5c, 0xd7, 0x5a, 0x28, 0x6b, 0xa9, 0xfe, +0xb7, 0xc2, 0xd3, 0x4a, 0x9b, 0xbb, 0x75, 0x2a, +0x47, 0xe2, 0xc8, 0xcb, 0xd6, 0x84, 0x08, 0xdf, +0x29, 0x16, 0x6e, 0x1e, 0xe5, 0x65, 0x46, 0x51, +0xe4, 0x1c, 0xe8, 0xa4, 0xb0, 0x40, 0xce, 0x74, +0x51, 0x14, 0x39, 0x82, 0x3f, 0x1c, 0x0e, 0xdd, +0xfd, 0xec, 0x4f, 0x4e, 0x4e, 0x31, 0xbc, 0xbc, +0x44, 0x58, 0xe4, 0xe8, 0x3f, 0x39, 0xc2, 0x6a, +0x7a, 0x89, 0x97, 0xb3, 0x27, 0xf8, 0x61, 0xaf, +0x85, 0x8d, 0xa4, 0x8d, 0xfd, 0x38, 0xc3, 0xed, +0x6e, 0x80, 0x16, 0x0a, 0x8c, 0xc3, 0x36, 0xda, +0x51, 0x34, 0xd7, 0x0a, 0x36, 0x9c, 0x5f, 0x14, +0xa0, 0xa6, 0x62, 0x23, 0xf6, 0xad, 0x07, 0xae, +0x96, 0xe7, 0x73, 0xd1, 0xda, 0x37, 0xf8, 0xbe, +0x64, 0xad, 0x4f, 0x5f, 0xdd, 0xbe, 0xfd, 0x34, +0xee, 0xe0, 0x5b, 0xc9, 0x08, 0xff, 0x4d, 0xfb, +0x01, 0xbe, 0x72, 0xfa, 0x31, 0xee, 0x3e, 0xfc, +0x37, 0xb8, 0x38, 0x3b, 0xc3, 0x49, 0xd2, 0x9b, +0x5e, 0x6b, 0x4b, 0x79, 0xb9, 0x13, 0xa9, 0x56, +0x47, 0x1d, 0xde, 0xbc, 0xbd, 0x7c, 0x5d, 0x2b, +0xfb, 0x8f, 0x9b, 0x01, 0xc3, 0xd3, 0x7e, 0x45, +0x2d, 0x24, 0x55, 0xeb, 0x9a, 0xaa, 0x9d, 0x26, +0x07, 0x9f, 0x60, 0x9a, 0x5a, 0x49, 0x4e, 0x72, +0x19, 0xd9, 0x4c, 0x06, 0xf0, 0xb0, 0xea, 0xe6, +0x13, 0x5c, 0x82, 0x86, 0x9f, 0x96, 0x46, 0xc3, +0x4f, 0x96, 0x67, 0x11, 0x6b, 0xd9, 0xf6, 0xd1, +0x68, 0x84, 0x4e, 0xa7, 0x63, 0x2e, 0x56, 0x4a, +0xdf, 0xeb, 0xf5, 0x1c, 0x57, 0x4c, 0x0e, 0x73, +0x1c, 0x47, 0x89, 0xfb, 0xc9, 0xc9, 0x09, 0x00, +0xa0, 0xd3, 0xe9, 0xe0, 0xe2, 0x6c, 0x2e, 0x85, +0xf4, 0x7a, 0x3d, 0x64, 0xbd, 0x1d, 0x3c, 0xea, +0x6e, 0xe1, 0x34, 0x8d, 0x80, 0x4c, 0x6c, 0xd6, +0xfc, 0xc8, 0x02, 0x7f, 0xcf, 0x9f, 0xe5, 0x31, +0x0c, 0xfe, 0x5b, 0x3e, 0x13, 0xf0, 0xf2, 0x65, +0x79, 0x12, 0xe4, 0xd1, 0x09, 0x2d, 0x6d, 0x18, +0xea, 0x79, 0x65, 0x7d, 0x33, 0x2e, 0x3e, 0x95, +0xe5, 0x8a, 0x28, 0x4a, 0x8e, 0xf3, 0xae, 0x03, +0x4a, 0x47, 0xf5, 0xe7, 0x6c, 0xe3, 0x0c, 0xa2, +0x99, 0x34, 0x1d, 0x56, 0xdb, 0xd3, 0xa4, 0xed, +0x12, 0x27, 0xf1, 0x2d, 0x0a, 0x03, 0xa4, 0xd6, +0x58, 0xc9, 0x32, 0xe8, 0xb7, 0xc4, 0x57, 0x1b, +0xaf, 0xab, 0xe2, 0xa9, 0x8d, 0x95, 0x76, 0xa6, +0x58, 0x7b, 0x6f, 0x8c, 0x91, 0x8a, 0xcf, 0xec, +0xdb, 0xc5, 0x68, 0x84, 0xb7, 0x11, 0xe0, 0xed, +0x60, 0x0f, 0xe8, 0x02, 0xcb, 0x77, 0x5f, 0xc1, +0x41, 0xd6, 0xc7, 0x37, 0xce, 0x3f, 0xc6, 0xc1, +0xd3, 0x8f, 0xdc, 0xba, 0x20, 0xd0, 0xd4, 0xd3, +0xe3, 0xbc, 0x00, 0x86, 0x43, 0xf4, 0x7a, 0x3d, +0x75, 0xfd, 0x26, 0x49, 0x82, 0xd3, 0xcb, 0x41, +0x29, 0x6e, 0x3c, 0x95, 0xa1, 0xad, 0x6d, 0x8d, +0xf0, 0x4a, 0xd0, 0xf6, 0x1b, 0xad, 0xde, 0xc3, +0xc3, 0xc3, 0x12, 0x5e, 0x72, 0xdf, 0xa2, 0x6f, +0xbe, 0xba, 0x38, 0x5e, 0xf2, 0x88, 0x5c, 0x93, +0xfd, 0xb5, 0xdf, 0xef, 0xbb, 0xab, 0x91, 0xb5, +0xfd, 0x54, 0xab, 0x8b, 0xfe, 0x0a, 0xb6, 0xdf, +0xf6, 0xfb, 0x53, 0x1f, 0x87, 0xe1, 0x04, 0x62, +0x2f, 0x3a, 0x41, 0x72, 0x7a, 0x82, 0xaf, 0x02, +0x6e, 0xbf, 0x8b, 0x56, 0xd6, 0x10, 0x74, 0x96, +0x70, 0x1c, 0xaf, 0xe0, 0x24, 0x04, 0xee, 0xa5, +0x6d, 0xfc, 0xdb, 0xd6, 0x1a, 0x1e, 0xa1, 0x0b, +0x44, 0x2d, 0x8c, 0x8a, 0xd9, 0xb1, 0xe6, 0x2c, +0x9f, 0x87, 0x8e, 0x05, 0xca, 0xb7, 0x25, 0xf2, +0x23, 0x5e, 0x14, 0x4e, 0xba, 0x6e, 0x9e, 0xca, +0xbd, 0x2b, 0xcb, 0xe6, 0xeb, 0x58, 0x9b, 0x93, +0xda, 0xfc, 0x6d, 0xb2, 0x7e, 0xf9, 0x11, 0xb7, +0x30, 0x40, 0x27, 0x8a, 0xf1, 0x5c, 0x30, 0xc0, +0xde, 0x12, 0xf0, 0xb5, 0xf3, 0x77, 0x31, 0xf9, +0xec, 0x10, 0x1f, 0x7c, 0xf6, 0x11, 0x86, 0xc3, +0x21, 0x8e, 0x47, 0x29, 0x5e, 0x2a, 0xee, 0xe1, +0xa5, 0xcf, 0xfe, 0x14, 0x3f, 0xff, 0xb5, 0xff, +0x10, 0xef, 0xb6, 0xb7, 0xec, 0xf5, 0xe2, 0x6b, +0x93, 0xf6, 0xdd, 0x87, 0x3f, 0x7b, 0x1f, 0x9d, +0xcf, 0xee, 0x74, 0xe6, 0x11, 0xb0, 0xfa, 0xfd, +0x7e, 0x65, 0x02, 0x69, 0xc0, 0x17, 0xa1, 0x46, +0xe4, 0xe5, 0x24, 0xe5, 0x60, 0x11, 0x71, 0x2a, +0x57, 0x96, 0x21, 0x55, 0xfe, 0x5a, 0x3d, 0xb2, +0x7c, 0xad, 0xfe, 0xa6, 0x8c, 0x86, 0xd6, 0x96, +0x93, 0x93, 0x13, 0x37, 0x91, 0xe9, 0x9d, 0x24, +0xe4, 0x16, 0x33, 0xa1, 0xbd, 0xe3, 0x44, 0x9d, +0xd2, 0x48, 0xe6, 0x80, 0x9e, 0x39, 0x5e, 0xbd, +0xe1, 0x09, 0x82, 0x6c, 0x82, 0x34, 0x13, 0xf6, +0x1c, 0xb9, 0x01, 0x5b, 0x93, 0x46, 0xa6, 0xa9, +0x9b, 0x74, 0x93, 0xf2, 0x05, 0x03, 0x2e, 0x8d, +0x8f, 0x78, 0xf1, 0x72, 0x7c, 0x93, 0xb2, 0x01, +0x9e, 0xa9, 0x2c, 0x8f, 0x3f, 0x37, 0x25, 0x6c, +0xbe, 0x74, 0x93, 0x91, 0xce, 0x5c, 0x68, 0x7d, +0xd5, 0x60, 0x51, 0xa9, 0xed, 0x02, 0x90, 0x4e, +0x46, 0x40, 0x36, 0xd2, 0xcb, 0xf6, 0x11, 0xc4, +0xab, 0x6c, 0x0a, 0x16, 0x9e, 0x3e, 0xdc, 0xd9, +0x6f, 0xc7, 0x38, 0x59, 0xef, 0xeb, 0xe6, 0x4f, +0x83, 0xf1, 0xb8, 0x18, 0x8d, 0xf0, 0x16, 0xba, +0xb8, 0xb7, 0xf2, 0x32, 0x5e, 0x59, 0xbe, 0x81, +0xdb, 0x37, 0x4f, 0xb1, 0x71, 0x7c, 0x1f, 0xc9, +0x67, 0x1f, 0x01, 0x40, 0x85, 0x28, 0x26, 0x49, +0x02, 0x34, 0xd8, 0x8f, 0xd6, 0x96, 0xba, 0x95, +0x34, 0xe3, 0xbc, 0x50, 0x09, 0xb7, 0xdc, 0x13, +0xb4, 0xfd, 0x4a, 0xee, 0x35, 0xda, 0x1e, 0xe4, +0xdb, 0x8f, 0xb4, 0xf4, 0x12, 0xb4, 0xbd, 0x52, +0x4b, 0xc3, 0xbf, 0xc9, 0x7d, 0x92, 0xf6, 0x61, +0x1f, 0x93, 0x20, 0xf7, 0x73, 0xd7, 0x0f, 0x39, +0x30, 0x54, 0xf6, 0x5b, 0x2a, 0x5f, 0xe2, 0xc9, +0xeb, 0xee, 0xcd, 0xf6, 0xa6, 0x65, 0x00, 0xd1, +0x68, 0x84, 0x1b, 0x9d, 0x0e, 0x7e, 0xbc, 0xb9, +0x8b, 0xbc, 0x3d, 0x4d, 0x73, 0xbc, 0xbc, 0x85, +0xd3, 0x3c, 0xc4, 0xbf, 0xbc, 0x88, 0xf0, 0x74, +0x9c, 0x61, 0x18, 0xb7, 0x71, 0x3a, 0xc9, 0xa6, +0xfb, 0x48, 0xc0, 0xe6, 0x0d, 0xed, 0x2f, 0x59, +0x5e, 0x5e, 0x1f, 0x28, 0xa7, 0x51, 0xe7, 0x9b, +0xfc, 0x5d, 0xb7, 0x16, 0x2c, 0x26, 0x55, 0x59, +0xbb, 0xcb, 0x01, 0x70, 0x67, 0xa5, 0x85, 0x1f, +0x2c, 0x5f, 0x62, 0x23, 0x3d, 0xc7, 0xda, 0xe4, +0x02, 0xd9, 0xd3, 0x43, 0xf4, 0x3f, 0x7f, 0x84, +0xcf, 0x4e, 0x2e, 0x30, 0x3e, 0x7e, 0x5c, 0x9a, +0x4b, 0x5b, 0x2f, 0xbc, 0x04, 0x74, 0x96, 0xf0, +0x5a, 0x67, 0x88, 0x77, 0x23, 0xe5, 0xec, 0x3a, +0x27, 0xd8, 0xd6, 0xfe, 0x79, 0x55, 0xfc, 0xb9, +0xd0, 0x13, 0x85, 0xa1, 0x3a, 0x79, 0xe5, 0x00, +0xf2, 0x09, 0xc1, 0xd3, 0x4a, 0xe2, 0x6f, 0x01, +0x9f, 0x08, 0x5a, 0x79, 0xc4, 0xbd, 0xfa, 0xb8, +0x66, 0x6b, 0xe1, 0x58, 0x4c, 0x44, 0x93, 0x85, +0x22, 0xe1, 0xaa, 0x79, 0xa4, 0x84, 0xae, 0x05, +0x71, 0xd1, 0x16, 0x13, 0x30, 0x65, 0x04, 0x24, +0xf1, 0xee, 0x74, 0x3a, 0xae, 0xfd, 0xfc, 0x1b, +0x71, 0xdd, 0x41, 0x7b, 0xfa, 0x7d, 0x70, 0x39, +0x00, 0x96, 0xd7, 0xaa, 0x93, 0x22, 0x66, 0x17, +0x28, 0x28, 0x03, 0x5e, 0x01, 0x9f, 0xb4, 0xcb, +0x26, 0x62, 0x69, 0xa1, 0xc9, 0x49, 0x25, 0x27, +0xa4, 0x7c, 0xa7, 0x4d, 0xea, 0x26, 0xc4, 0x40, +0xc3, 0x4f, 0x96, 0xa1, 0x30, 0x09, 0x51, 0x18, +0x4c, 0x09, 0x27, 0x2b, 0xb3, 0x74, 0xa9, 0x84, +0xaf, 0x6c, 0x59, 0xbe, 0x86, 0xb7, 0xc1, 0xd5, +0x57, 0xea, 0xf5, 0xb5, 0xd1, 0xd7, 0xe7, 0x3e, +0xe9, 0x42, 0xeb, 0x1b, 0x8f, 0x44, 0xe1, 0x65, +0xda, 0x14, 0x7c, 0x52, 0xa3, 0x2e, 0x7e, 0x21, +0x87, 0x9a, 0xb7, 0xe9, 0x6f, 0xf6, 0x7c, 0xd1, +0x6a, 0xe3, 0x0f, 0xd3, 0x35, 0xfc, 0x61, 0xbc, +0x8d, 0x9b, 0x9b, 0xd7, 0xf1, 0xd5, 0xb5, 0xdb, +0x78, 0xe9, 0xf4, 0x63, 0xf4, 0x9e, 0x3e, 0x74, +0x84, 0x44, 0x63, 0x88, 0x7d, 0x52, 0x32, 0x7d, +0x1f, 0xe7, 0x05, 0xda, 0x41, 0x0b, 0x6b, 0x4b, +0x5d, 0x73, 0x3d, 0x93, 0xd4, 0x2c, 0x41, 0x23, +0xdc, 0x56, 0xdd, 0xbe, 0xb2, 0x65, 0x79, 0x9c, +0xe8, 0x4a, 0x46, 0x42, 0x6a, 0x2c, 0x65, 0x39, +0x96, 0xe0, 0xe2, 0xd3, 0x58, 0xfa, 0xb4, 0x8f, +0x96, 0xb6, 0xa2, 0xc9, 0x1e, 0xc9, 0x99, 0x08, +0xd9, 0x7f, 0x67, 0x9f, 0x7d, 0x0c, 0x60, 0xba, +0x5f, 0x3d, 0x37, 0x3c, 0xc1, 0xa8, 0x00, 0x5e, +0x69, 0x77, 0x10, 0xf7, 0x56, 0x70, 0x16, 0x2d, +0xe3, 0xfd, 0x2c, 0xc1, 0x93, 0xe1, 0x00, 0x9b, +0x49, 0x84, 0x9f, 0x0f, 0x02, 0x7c, 0x9c, 0x27, +0x38, 0x1e, 0x8e, 0x31, 0x2a, 0x14, 0x89, 0x5d, +0xce, 0x31, 0xdf, 0x7a, 0xf0, 0x31, 0xaa, 0x9a, +0xe4, 0x2b, 0xd2, 0x47, 0xe1, 0x54, 0x30, 0x4a, +0x27, 0x23, 0xec, 0xaf, 0x74, 0x70, 0x3b, 0x18, +0xe2, 0x47, 0xf1, 0xe7, 0xd8, 0x3a, 0xfd, 0x0c, +0x97, 0x8f, 0x8e, 0x71, 0x72, 0x72, 0x82, 0xb7, +0x0e, 0x0f, 0x4b, 0xed, 0xe7, 0xfd, 0xbc, 0xf2, +0xda, 0xaf, 0xe3, 0x9f, 0xef, 0xbf, 0x81, 0x47, +0xc3, 0x02, 0xa7, 0x74, 0x59, 0x55, 0xcd, 0xfa, +0x73, 0xfb, 0x45, 0x1d, 0xe3, 0x5d, 0x87, 0x3f, +0x31, 0xdc, 0xda, 0xa4, 0xd0, 0xd4, 0xe7, 0xda, +0xc2, 0xe9, 0xf7, 0xfb, 0xa5, 0x45, 0xe7, 0x9b, +0xe8, 0x16, 0xb3, 0x60, 0xa5, 0xe7, 0xef, 0x65, +0x19, 0x75, 0x13, 0xdb, 0xca, 0xe7, 0x03, 0x8b, +0x91, 0x21, 0xe9, 0xb9, 0xd3, 0xe9, 0xa8, 0xea, +0x74, 0x4d, 0x42, 0xe7, 0xf5, 0xd1, 0xc0, 0x5b, +0x38, 0x48, 0x82, 0xae, 0x69, 0x0d, 0x78, 0xde, +0xa5, 0xb5, 0x75, 0x0c, 0x67, 0x66, 0x28, 0x95, +0xa8, 0x91, 0x24, 0xab, 0x2d, 0x00, 0x9f, 0xe4, +0xe6, 0x53, 0xc5, 0xca, 0xf4, 0x56, 0x5e, 0xad, +0x2e, 0x9f, 0x24, 0x67, 0xa9, 0x74, 0x2d, 0x1c, +0xad, 0xf2, 0x04, 0x6e, 0x95, 0x05, 0xc2, 0xa5, +0x7b, 0x0d, 0x7c, 0xf8, 0xfb, 0x4c, 0x0d, 0x5a, +0xbd, 0xb2, 0x1c, 0x2b, 0xbd, 0xfc, 0x2e, 0x25, +0xe0, 0x1a, 0x5c, 0x4b, 0x1b, 0x81, 0x35, 0x7e, +0xd6, 0xa6, 0x27, 0xdb, 0xc8, 0xd3, 0x37, 0xd5, +0x18, 0x78, 0x4c, 0x1a, 0x26, 0x53, 0x63, 0x8d, +0xf3, 0x64, 0x84, 0x07, 0xf1, 0x2a, 0x1e, 0x04, +0x6d, 0x3c, 0xdc, 0xdb, 0xc1, 0x4f, 0x36, 0x3f, +0xc1, 0xc6, 0xc7, 0x6f, 0x63, 0x70, 0xda, 0x2f, +0xed, 0x29, 0x4e, 0x33, 0x25, 0x18, 0x7f, 0x6d, +0x4f, 0x90, 0xea, 0x76, 0xa0, 0x4a, 0x18, 0xe5, +0xba, 0xb4, 0xf6, 0x28, 0x4e, 0x88, 0xe9, 0x9d, +0x4c, 0x43, 0xe5, 0x5b, 0x5a, 0xbf, 0x3a, 0x93, +0xa5, 0x46, 0x20, 0x34, 0x7c, 0x7d, 0xdf, 0x7c, +0x42, 0x8f, 0x54, 0xe1, 0x6b, 0x82, 0x8f, 0x4f, +0x12, 0xb7, 0x88, 0xff, 0xe1, 0x8c, 0xc0, 0x49, +0x06, 0xa8, 0xd3, 0xe9, 0x60, 0x30, 0x18, 0xb8, +0xfd, 0x73, 0x77, 0x77, 0x17, 0x9d, 0xf0, 0x14, +0x5f, 0x07, 0x30, 0x4e, 0x27, 0xe8, 0xa4, 0x1d, +0x7c, 0x63, 0x79, 0x1a, 0xd8, 0xea, 0xa3, 0x16, +0x90, 0xaf, 0xf4, 0x00, 0x00, 0x6f, 0x8d, 0x3b, +0xf8, 0x64, 0x34, 0xc6, 0xa0, 0xdb, 0x41, 0x31, +0x1a, 0x60, 0x10, 0xb4, 0x71, 0x3a, 0x19, 0x03, +0x9d, 0xa9, 0xb9, 0xc6, 0x9c, 0x63, 0x72, 0xae, +0x35, 0x90, 0xbc, 0x29, 0x1d, 0x11, 0x72, 0x00, +0xf8, 0xab, 0x2b, 0x23, 0xfc, 0x38, 0xf8, 0x0c, +0xd9, 0xd3, 0x43, 0x7c, 0xfc, 0xd1, 0x47, 0xf8, +0xf4, 0xec, 0x74, 0xaa, 0xbd, 0x38, 0xed, 0x57, +0xe6, 0x0d, 0xf5, 0xd7, 0xb5, 0xef, 0xfc, 0x04, +0xff, 0xbf, 0xd5, 0xaf, 0xe3, 0xe9, 0x20, 0x70, +0x0c, 0x49, 0x09, 0x3f, 0x83, 0x09, 0x4f, 0x83, +0x78, 0x2a, 0x20, 0x69, 0xfb, 0x43, 0x53, 0xfc, +0x19, 0x44, 0x72, 0x72, 0xd4, 0xd9, 0x8a, 0xf9, +0x40, 0x4a, 0x62, 0xcc, 0xbf, 0xfb, 0xec, 0x54, +0xda, 0x42, 0xd2, 0xca, 0xd1, 0xa0, 0x6e, 0x92, +0x69, 0xef, 0xea, 0xd4, 0x62, 0x3e, 0x06, 0xa1, +0x89, 0x1a, 0xdd, 0xb7, 0x50, 0xeb, 0x18, 0x16, +0x5e, 0x87, 0x54, 0xc1, 0x4b, 0x06, 0x61, 0x92, +0xe5, 0x18, 0x5d, 0x5e, 0x02, 0x4b, 0x5d, 0xac, +0x9d, 0x3f, 0xc6, 0xd3, 0xcd, 0x75, 0x0c, 0x34, +0xa9, 0x5b, 0x21, 0x46, 0x15, 0xae, 0x57, 0xe1, +0x08, 0x2b, 0x9c, 0xa2, 0x4f, 0xda, 0xe6, 0x75, +0x5a, 0x1c, 0xa4, 0xc5, 0x51, 0xf3, 0x6f, 0xb3, +0xf7, 0x26, 0x57, 0xae, 0xb5, 0xad, 0xce, 0xae, +0xeb, 0x93, 0x6e, 0xaf, 0x22, 0xbd, 0x5a, 0xd2, +0xb9, 0xec, 0xe3, 0x1a, 0xad, 0x80, 0xaa, 0x51, +0x90, 0x9a, 0x14, 0x92, 0x8c, 0x81, 0xb9, 0x06, +0xc4, 0x23, 0x49, 0xa7, 0x56, 0x7b, 0xac, 0x7a, +0xad, 0x34, 0xb2, 0x9e, 0x86, 0x0c, 0x20, 0xb7, +0x81, 0xca, 0x71, 0x50, 0xa5, 0x78, 0x6d, 0xce, +0x29, 0x78, 0xbd, 0x9d, 0x76, 0xf1, 0x49, 0xeb, +0x0e, 0x5e, 0xb9, 0x7d, 0x0d, 0x5f, 0xbb, 0xb8, +0x8f, 0x8d, 0xa3, 0x8f, 0x31, 0x38, 0xed, 0x03, +0xd0, 0x05, 0x0e, 0x6d, 0xcf, 0x20, 0xa9, 0x9c, +0xf2, 0x10, 0x48, 0x62, 0xa9, 0x95, 0xe1, 0x13, +0x04, 0x34, 0xe1, 0xc6, 0x32, 0xab, 0xd5, 0xf9, +0xf7, 0xc8, 0xbc, 0x3c, 0x9d, 0x94, 0x76, 0x7d, +0xfb, 0x89, 0x86, 0x33, 0x7f, 0x67, 0x69, 0x05, +0x9b, 0xec, 0x89, 0x1a, 0x58, 0x9a, 0x00, 0x59, +0xc6, 0xa3, 0x47, 0x8f, 0x4a, 0xcf, 0x44, 0xf4, +0x39, 0x74, 0x3a, 0x1d, 0x8c, 0xf2, 0xa9, 0x3a, +0xbb, 0xdb, 0xed, 0xa2, 0xd5, 0x49, 0xf0, 0x95, +0x6e, 0x02, 0x04, 0xc0, 0x24, 0x6c, 0xa3, 0xb5, +0xbb, 0x81, 0xf3, 0xc9, 0x00, 0x00, 0xf0, 0x79, +0x11, 0xe3, 0x4f, 0x2e, 0x23, 0x6c, 0xb5, 0x43, +0x7c, 0x70, 0x31, 0x75, 0x28, 0x7b, 0xe1, 0xda, +0x1a, 0x4e, 0xf2, 0x00, 0xef, 0x3d, 0x39, 0xc5, +0x23, 0x00, 0x79, 0xab, 0xc0, 0xa0, 0x60, 0x4c, +0x5c, 0x8d, 0xa6, 0xa8, 0xdb, 0x2a, 0x10, 0x84, +0x01, 0x76, 0xc2, 0x14, 0xdf, 0x5e, 0x0b, 0x71, +0x67, 0xf8, 0x08, 0xcb, 0x87, 0xef, 0xe3, 0xad, +0x77, 0xdf, 0x75, 0x7d, 0x30, 0xce, 0xa7, 0x8e, +0x7a, 0xed, 0xa0, 0x55, 0xd1, 0x52, 0x8f, 0xf3, +0x02, 0xcf, 0xbf, 0xf2, 0x3a, 0xfe, 0x87, 0xd5, +0xaf, 0xe3, 0x69, 0xb4, 0x34, 0xd7, 0x60, 0xf2, +0xf5, 0x09, 0x94, 0xd7, 0x94, 0xb5, 0x1f, 0x68, +0xcf, 0x3e, 0x9f, 0x23, 0xe5, 0x7d, 0x94, 0xb2, +0x90, 0xad, 0x9a, 0x03, 0x86, 0x1c, 0xb4, 0x3a, +0x4e, 0x56, 0x73, 0x8e, 0xf3, 0x11, 0x6d, 0x8d, +0x4b, 0x6e, 0xe2, 0x24, 0x62, 0x4d, 0x48, 0x1f, +0x43, 0x20, 0x27, 0x61, 0x9d, 0x0a, 0xab, 0x8e, +0xeb, 0xd5, 0x98, 0x1a, 0x6d, 0xc1, 0x5b, 0x8c, +0x92, 0x26, 0x91, 0x53, 0x19, 0x92, 0x89, 0x08, +0xa3, 0x18, 0x49, 0x12, 0xa2, 0xd7, 0xeb, 0x4d, +0xd5, 0x3a, 0x41, 0x8e, 0x41, 0x94, 0xd8, 0x6a, +0x5f, 0x41, 0x80, 0x52, 0x8b, 0x30, 0xb0, 0xb4, +0x32, 0x8d, 0xca, 0x00, 0x70, 0xb0, 0x26, 0xa9, +0x04, 0x9f, 0x46, 0x80, 0xb8, 0x54, 0x56, 0x8f, +0xab, 0x77, 0x62, 0x10, 0xb5, 0x26, 0xd2, 0xba, +0x52, 0x97, 0xb3, 0xfb, 0xd7, 0x71, 0xba, 0x3e, +0x02, 0x5f, 0xd3, 0x96, 0x54, 0x5b, 0x88, 0x46, +0x99, 0x44, 0xf8, 0xd3, 0xba, 0xb2, 0xeb, 0xda, +0xd7, 0xd4, 0x6c, 0xe1, 0x2b, 0x4f, 0x23, 0xb2, +0x4d, 0xda, 0xc9, 0xd3, 0xfb, 0xa4, 0x7e, 0xab, +0x4d, 0x94, 0x9e, 0xe1, 0x74, 0x01, 0xe0, 0x0f, +0xb1, 0x86, 0x3f, 0x59, 0x7e, 0x05, 0x2f, 0x6d, +0xdc, 0xc5, 0x8f, 0x2e, 0x3f, 0x44, 0xeb, 0xd1, +0x27, 0xe8, 0x9e, 0x1d, 0xa3, 0x98, 0x05, 0xa1, +0x01, 0xca, 0x44, 0x8f, 0x4b, 0xec, 0xed, 0xa0, +0xe5, 0x08, 0xba, 0xb5, 0x47, 0x59, 0xcc, 0x80, +0x4f, 0xbb, 0xc8, 0xc1, 0x72, 0x52, 0x23, 0xf0, +0x39, 0xd8, 0xf1, 0x7d, 0x56, 0xb6, 0xc5, 0x47, +0x48, 0x7d, 0x04, 0x5d, 0xd6, 0x63, 0x69, 0x47, +0x35, 0x08, 0xda, 0xf3, 0xb9, 0xea, 0xd3, 0x76, +0x48, 0x1c, 0x78, 0x1f, 0x58, 0xa6, 0x03, 0xd9, +0xa7, 0x1a, 0x8e, 0x7d, 0x66, 0xee, 0x38, 0x86, +0x6e, 0x7e, 0x5c, 0x05, 0xf0, 0x37, 0x7a, 0x1b, +0x58, 0x2f, 0x12, 0xfc, 0x95, 0x08, 0x18, 0x66, +0x05, 0xf0, 0xf9, 0x74, 0xfe, 0x5c, 0x04, 0xd3, +0x74, 0xe1, 0xde, 0x0e, 0x3e, 0x2f, 0x62, 0xbc, +0x35, 0x9e, 0x3e, 0x9f, 0x4c, 0x86, 0x78, 0x3b, +0x6c, 0x63, 0x94, 0xa6, 0x40, 0x31, 0xc6, 0x28, +0x0c, 0x70, 0x7b, 0x39, 0x46, 0x31, 0x1a, 0xe0, +0xc5, 0x95, 0x09, 0x5e, 0x5b, 0x6d, 0xe1, 0x7a, +0x6b, 0x82, 0xd6, 0xe3, 0x4f, 0x70, 0x79, 0xef, +0x18, 0xa3, 0xd1, 0x08, 0xef, 0xde, 0xbb, 0xe7, +0xcc, 0xc6, 0xbc, 0x0d, 0xe3, 0x76, 0xc7, 0x11, +0x74, 0x6a, 0xd3, 0xee, 0xee, 0x2e, 0x7e, 0x76, +0xf3, 0xdb, 0x78, 0x1a, 0x2c, 0x95, 0xf7, 0x2d, +0x3e, 0xdf, 0x69, 0x7e, 0x13, 0x58, 0x6b, 0xd0, +0xe3, 0x38, 0xab, 0xe6, 0x53, 0xca, 0x6b, 0x7d, +0xfd, 0x3f, 0xff, 0x6f, 0x8b, 0xdd, 0xfb, 0x7f, +0x56, 0xab, 0x1e, 0x92, 0x03, 0xad, 0x0d, 0x8e, +0xe6, 0xa0, 0xa1, 0x4d, 0x42, 0x9e, 0x97, 0xe7, +0xe3, 0x1e, 0xdf, 0x5a, 0x7d, 0x1a, 0x6e, 0x92, +0x9b, 0xd5, 0x6c, 0x4e, 0x16, 0x77, 0x2d, 0x27, +0xbb, 0x0f, 0x9a, 0x98, 0x0c, 0x34, 0xe7, 0x1a, +0xab, 0x0c, 0xad, 0x2c, 0x8e, 0xbb, 0x54, 0x79, +0x85, 0x71, 0x1b, 0x71, 0x18, 0xa0, 0xd7, 0xeb, +0xa1, 0xd7, 0xeb, 0xe1, 0xf3, 0x9b, 0xaf, 0xe0, +0xf7, 0x6e, 0x7e, 0x07, 0x17, 0x69, 0x51, 0x1d, +0xe4, 0x3a, 0xe2, 0x2e, 0xa1, 0x89, 0xb3, 0x54, +0x93, 0x3a, 0x14, 0x28, 0x4d, 0xf0, 0x3a, 0x1b, +0xb1, 0x0f, 0x57, 0x4d, 0xd2, 0xb3, 0xca, 0xd4, +0xca, 0x69, 0xe2, 0xa8, 0xa6, 0x41, 0x13, 0x5b, +0x74, 0xdd, 0xb7, 0xab, 0xd4, 0x63, 0x94, 0x5d, +0x92, 0x84, 0xb5, 0x7e, 0xb3, 0xfa, 0xc7, 0x2a, +0xdf, 0xf2, 0xda, 0xd5, 0x24, 0x6e, 0x0b, 0x5f, +0x6b, 0x8c, 0x9a, 0x8c, 0x87, 0xf5, 0x4e, 0x79, +0xee, 0xa6, 0xd3, 0xf5, 0xf1, 0x6b, 0xc1, 0x19, +0xf6, 0x87, 0x47, 0xd8, 0xba, 0xf8, 0x1c, 0x2b, +0x97, 0xc7, 0x25, 0x1b, 0xb4, 0x5c, 0xcf, 0xe3, +0xbc, 0xa8, 0x38, 0xc4, 0x59, 0x12, 0xae, 0xb6, +0xaf, 0xf1, 0x6f, 0x4d, 0x7d, 0x8a, 0xb4, 0x77, +0x4d, 0x3c, 0xd9, 0x2d, 0x75, 0x3a, 0xc7, 0x85, +0xa7, 0x93, 0x38, 0xca, 0xb2, 0xaf, 0xb2, 0x6f, +0xca, 0xb6, 0x68, 0xe0, 0xdb, 0xff, 0x7d, 0x69, +0x2d, 0x5c, 0x65, 0x1b, 0x5b, 0xf1, 0xf4, 0xa2, +0x95, 0xce, 0x4c, 0xdd, 0x3d, 0x1c, 0x0e, 0xd1, +0x8a, 0xdb, 0x58, 0x5f, 0x5e, 0x2a, 0xd9, 0xe5, +0x1b, 0xf9, 0x06, 0xac, 0x6e, 0x20, 0xc9, 0x53, +0x24, 0x71, 0x88, 0x7e, 0xd6, 0x42, 0xb6, 0xb4, +0x8e, 0xf3, 0xbc, 0x85, 0xb4, 0xb3, 0x84, 0x93, +0x93, 0x53, 0xbc, 0xb6, 0x1a, 0x20, 0xca, 0x46, +0x38, 0xbe, 0x1c, 0xa1, 0x33, 0x9e, 0x3a, 0x7f, +0x9f, 0x9c, 0x9c, 0x38, 0x93, 0x31, 0xf5, 0x8d, +0x6f, 0x4e, 0x24, 0xc9, 0xf4, 0xe4, 0xc4, 0x5a, +0x6f, 0x03, 0xff, 0xec, 0x8d, 0xff, 0x0c, 0x4f, +0x8b, 0xd0, 0xaf, 0x19, 0x93, 0x20, 0x35, 0x7e, +0x40, 0x33, 0xe1, 0xc2, 0xda, 0x23, 0x48, 0x08, +0xea, 0x74, 0xa6, 0xc8, 0x71, 0xd5, 0x14, 0xef, +0x70, 0x4b, 0x8a, 0xb6, 0x3a, 0xd5, 0x22, 0x92, +0x75, 0x6a, 0x21, 0x39, 0xc8, 0x7d, 0xc3, 0xc3, +0x52, 0xa6, 0xe3, 0x13, 0x84, 0x73, 0xb7, 0x32, +0xbd, 0x05, 0x4d, 0x38, 0x4b, 0x0d, 0x67, 0x9f, +0xd4, 0xad, 0x99, 0x02, 0x34, 0x5b, 0xbe, 0x2c, +0xcb, 0x6b, 0x9f, 0xc2, 0xf4, 0xd8, 0x21, 0x95, +0xb5, 0xbb, 0xdc, 0x99, 0x1e, 0xfd, 0x88, 0xdb, +0x8e, 0xc3, 0x2b, 0x49, 0xb4, 0x3e, 0x7b, 0xb4, +0x4f, 0xf5, 0x4c, 0xcf, 0xd6, 0x3b, 0x56, 0x5e, +0x49, 0x72, 0x37, 0xca, 0x51, 0x55, 0xe7, 0x96, +0xea, 0x4b, 0xd6, 0xcd, 0xd3, 0x28, 0x93, 0x5d, +0xb5, 0x9b, 0xf9, 0x24, 0x4c, 0xab, 0xad, 0x57, +0x25, 0xfa, 0x4d, 0x24, 0x51, 0x1f, 0x13, 0xd0, +0xc4, 0x19, 0x50, 0x94, 0x9d, 0x5a, 0xf5, 0xf9, +0x6c, 0x6a, 0x96, 0xf3, 0xa0, 0x05, 0x13, 0xe1, +0x6f, 0xa1, 0xcd, 0x97, 0xa6, 0x36, 0xf5, 0x26, +0xe3, 0x2a, 0xf1, 0x31, 0xea, 0x1d, 0x14, 0x2d, +0x44, 0x61, 0x80, 0x3f, 0xcc, 0xd6, 0xf0, 0x87, +0x4b, 0xdb, 0x58, 0xee, 0xbe, 0x80, 0xe7, 0xe2, +0x0c, 0x77, 0x2e, 0x1e, 0xe2, 0xda, 0xf8, 0x0c, +0x1b, 0x47, 0x1f, 0x61, 0x38, 0xb8, 0xc4, 0xe0, +0xec, 0xd4, 0xad, 0x9d, 0xb5, 0xa5, 0xee, 0x34, +0x76, 0xc6, 0xd8, 0x26, 0x2a, 0x80, 0xae, 0x3a, +0xb7, 0xb4, 0x70, 0x1a, 0xd3, 0x2d, 0xd3, 0x59, +0xf5, 0x50, 0x3a, 0x29, 0xb0, 0xd4, 0x01, 0x2f, +0x9b, 0x08, 0x9b, 0x6f, 0x4f, 0xb4, 0x34, 0x87, +0xd6, 0x7e, 0xa6, 0x11, 0xc5, 0x3a, 0x7b, 0xfc, +0x38, 0x2f, 0x90, 0x8f, 0x47, 0x95, 0x7c, 0x5a, +0xdf, 0x69, 0x12, 0xbc, 0x82, 0x3c, 0x00, 0xa0, +0x60, 0xe5, 0x0c, 0xce, 0x4e, 0x31, 0x38, 0x3b, +0x45, 0x92, 0x24, 0x38, 0xb9, 0xb8, 0x44, 0x31, +0x19, 0xa3, 0x15, 0xb7, 0x9d, 0x66, 0x86, 0xca, +0x1b, 0x65, 0xb9, 0xfb, 0x0e, 0x00, 0x89, 0x10, +0x06, 0x29, 0xed, 0x72, 0x92, 0x20, 0x1c, 0x0e, +0x71, 0xbf, 0x9d, 0xa0, 0x13, 0x94, 0xc7, 0xf3, +0xf0, 0xf0, 0xd0, 0xfd, 0x9e, 0xa4, 0x19, 0xe2, +0x28, 0x34, 0xf7, 0xfe, 0x12, 0x8d, 0x19, 0x0f, +0x71, 0x2d, 0x4c, 0xf1, 0x34, 0x65, 0x47, 0x59, +0x3d, 0xeb, 0xa3, 0x22, 0xb9, 0xfb, 0x18, 0x6e, +0xfe, 0xdd, 0xd2, 0x4c, 0x4a, 0xcd, 0xe3, 0x64, +0x32, 0x9e, 0x77, 0xb0, 0x47, 0x35, 0xa4, 0xbd, +0xaf, 0x23, 0x70, 0x3e, 0x6e, 0x56, 0x9e, 0x17, +0xe5, 0xff, 0xa5, 0x0a, 0x4b, 0x1b, 0x1c, 0x0d, +0x7c, 0x0e, 0x28, 0xfc, 0x7b, 0xd3, 0x76, 0xd5, +0x95, 0x47, 0x83, 0x2b, 0x17, 0x67, 0x1d, 0xf7, +0x6d, 0xe1, 0x1b, 0x46, 0x31, 0xb2, 0x74, 0x62, +0x72, 0xb5, 0x49, 0x92, 0x60, 0x92, 0x66, 0x38, +0x3c, 0x3c, 0x44, 0xeb, 0x2b, 0xbf, 0x3e, 0x9d, +0x18, 0xec, 0x74, 0x9a, 0x97, 0x70, 0xce, 0x06, +0xdf, 0xd9, 0x67, 0xd9, 0x3b, 0x1f, 0xb7, 0x57, +0xb1, 0xb9, 0xb3, 0xb4, 0xa5, 0x89, 0xc9, 0xc1, +0x63, 0xa7, 0xaa, 0x94, 0xef, 0x03, 0x69, 0x8b, +0x16, 0xed, 0xf3, 0x4a, 0xfc, 0x75, 0x75, 0xd6, +0xa8, 0xad, 0x2a, 0x47, 0xb4, 0xe8, 0x77, 0x8d, +0xcd, 0xdc, 0xf4, 0x1b, 0xb0, 0xa0, 0xc9, 0xb7, +0x3a, 0xdf, 0x00, 0x9f, 0xd6, 0xc5, 0xe8, 0x4f, +0x33, 0x9f, 0x45, 0xf8, 0xb5, 0x77, 0x4d, 0xa4, +0x6f, 0x4b, 0xe2, 0xf6, 0x30, 0x5a, 0x25, 0x73, +0xc8, 0x0c, 0xf8, 0xd8, 0x5f, 0x00, 0x78, 0x3b, +0x0d, 0xf0, 0x76, 0xe7, 0x79, 0x20, 0x18, 0x61, +0xf9, 0xe0, 0x65, 0x1c, 0xe0, 0x12, 0x77, 0x07, +0x0f, 0xb1, 0xff, 0xe4, 0x1e, 0x4e, 0x07, 0x23, +0xac, 0x05, 0x19, 0xa2, 0x6c, 0x52, 0xd1, 0xf4, +0x11, 0x70, 0xc9, 0xdd, 0xe7, 0x7c, 0x46, 0xf9, +0xf8, 0x26, 0x5f, 0xb7, 0xc7, 0x58, 0xda, 0x4c, +0x9f, 0xe6, 0xce, 0xa7, 0xe1, 0xf4, 0x09, 0x03, +0x96, 0xe0, 0xc2, 0xdb, 0x74, 0x78, 0x78, 0xe8, +0xd5, 0x56, 0x4a, 0x90, 0x7b, 0x8e, 0xc4, 0xaf, +0x1d, 0xb4, 0x00, 0x05, 0x1f, 0x9f, 0xbd, 0xdd, +0xa7, 0x35, 0xb0, 0x98, 0x28, 0x97, 0x8e, 0xd2, +0x1a, 0x66, 0x55, 0xcb, 0xfe, 0xcf, 0x9f, 0x35, +0xa7, 0x49, 0x5e, 0x1f, 0xbd, 0xcf, 0xd2, 0x09, +0xb2, 0x74, 0x52, 0x2a, 0x63, 0x92, 0x4e, 0x4d, +0xd1, 0xab, 0x2b, 0xcb, 0x95, 0x36, 0x7c, 0x65, +0x7c, 0x84, 0x7b, 0xf1, 0x2d, 0xbf, 0x9f, 0x0c, +0xa0, 0xab, 0xe0, 0xaf, 0x22, 0x2c, 0x00, 0x65, +0xe7, 0x58, 0x65, 0xcf, 0x0b, 0xb7, 0x5f, 0xfb, +0xee, 0x9b, 0x2b, 0xa7, 0x9f, 0x3b, 0xe4, 0x64, +0x2c, 0x60, 0x79, 0x63, 0x19, 0x35, 0x44, 0x46, +0x5c, 0xa2, 0x0e, 0xd1, 0x2e, 0x12, 0xa1, 0xf7, +0xf4, 0x2c, 0x2f, 0x4f, 0xa1, 0x9b, 0xc6, 0xa8, +0x73, 0x79, 0x0c, 0xf5, 0x24, 0xd1, 0x63, 0xb5, +0x03, 0x7a, 0x84, 0x39, 0x2b, 0xe2, 0x12, 0x95, +0x2d, 0xc3, 0xac, 0xca, 0xfc, 0x32, 0xe4, 0x2a, +0x9f, 0x70, 0x5a, 0x34, 0x3a, 0xba, 0xcd, 0x89, +0xbf, 0xa3, 0xdb, 0x9d, 0x08, 0x6f, 0xde, 0x8f, +0xbc, 0x4c, 0xfe, 0x7b, 0x79, 0x65, 0x15, 0x00, +0xd0, 0x69, 0xb7, 0x2b, 0x38, 0x84, 0x71, 0x1b, +0x61, 0xd0, 0xc2, 0xca, 0xca, 0x0a, 0x3a, 0xed, +0x36, 0x76, 0x77, 0x77, 0x71, 0xff, 0xb9, 0x6f, +0xe2, 0x21, 0x3a, 0xee, 0x2e, 0x6f, 0xc4, 0x1d, +0xc8, 0x6b, 0xfe, 0xa2, 0x30, 0x98, 0xdf, 0x95, +0x2b, 0x23, 0x2f, 0xc5, 0x9d, 0xf9, 0x1d, 0xba, +0x32, 0x3d, 0x2f, 0x67, 0x56, 0xae, 0xbb, 0xe2, +0xcf, 0x8a, 0x2c, 0xe7, 0x8b, 0x94, 0xa6, 0x45, +0x6c, 0xb3, 0x22, 0xca, 0xf1, 0x72, 0x29, 0xc2, +0xd8, 0xec, 0xe2, 0x18, 0x57, 0x96, 0x55, 0x8f, +0x56, 0xa6, 0x2c, 0xdf, 0xca, 0x4b, 0xef, 0x64, +0x7d, 0x5a, 0x7a, 0x0d, 0x4f, 0xab, 0x2e, 0xea, +0xd7, 0xa2, 0xd0, 0xfb, 0x43, 0x2e, 0x6c, 0xd9, +0x3f, 0x46, 0xf9, 0x51, 0x18, 0x94, 0xfb, 0x84, +0xa2, 0x40, 0xf1, 0x31, 0x94, 0x38, 0xc8, 0xb9, +0xa2, 0x8d, 0x8b, 0x7c, 0xe6, 0xf9, 0x69, 0x2e, +0x35, 0x89, 0x64, 0xd7, 0xf4, 0xbd, 0xf2, 0xdb, +0xdd, 0x0b, 0xcd, 0xfb, 0xc7, 0x9a, 0x33, 0x71, +0x07, 0x93, 0x34, 0xc5, 0xe3, 0x3c, 0xc6, 0xdb, +0xe1, 0x06, 0xde, 0xd9, 0xbc, 0x8b, 0x7b, 0x6b, +0xcf, 0xe1, 0xc9, 0xee, 0x57, 0xb0, 0xb6, 0xbd, +0x83, 0xfd, 0x38, 0xc7, 0xfa, 0xf2, 0x52, 0x69, +0xbd, 0x45, 0x51, 0x84, 0x22, 0xcb, 0x2a, 0x7b, +0x98, 0x16, 0x81, 0x8d, 0xf6, 0xbb, 0x22, 0xcf, +0x4b, 0x7b, 0x8e, 0x2f, 0x7e, 0xbb, 0x0c, 0xbf, +0x2c, 0x63, 0xcc, 0x6b, 0xf1, 0xde, 0xad, 0xd0, +0xd7, 0x72, 0xdf, 0xd2, 0xf2, 0xd3, 0xbe, 0x43, +0xfb, 0x0d, 0xdf, 0x5b, 0x29, 0xda, 0x25, 0x0f, +0xdf, 0x4a, 0xfb, 0x15, 0xdf, 0x8b, 0x79, 0x28, +0x59, 0x02, 0x1e, 0xee, 0x55, 0xd2, 0x04, 0x1f, +0x33, 0x22, 0x23, 0xf8, 0x59, 0xa1, 0x6d, 0x79, +0x5f, 0xcb, 0x8b, 0x74, 0xf8, 0x3b, 0xf9, 0x27, +0xc7, 0x49, 0xd2, 0x2d, 0x19, 0xf2, 0x96, 0x7f, +0x27, 0x3a, 0xa5, 0xdd, 0xdb, 0xc1, 0x19, 0x04, +0x3e, 0x1e, 0x9d, 0x76, 0xdb, 0xdd, 0x8f, 0x21, +0xfb, 0xe7, 0xb9, 0xdd, 0x6d, 0xbc, 0x95, 0xec, +0x61, 0x12, 0x1a, 0xfb, 0x98, 0xb5, 0x7f, 0xd6, +0xed, 0x45, 0xf4, 0xcc, 0xf6, 0x81, 0xd2, 0x5e, +0xae, 0xe4, 0x09, 0xaf, 0xbf, 0xfe, 0xbd, 0x37, +0x57, 0x4e, 0x3f, 0xaf, 0xc4, 0x3c, 0xe6, 0x93, +0x42, 0x2e, 0x04, 0x6a, 0x88, 0x5c, 0x08, 0x72, +0x52, 0x52, 0xa7, 0xf1, 0x81, 0x97, 0x37, 0x10, +0xc9, 0x05, 0x62, 0x5d, 0x07, 0x2a, 0x43, 0xaf, +0xf2, 0x18, 0xee, 0x92, 0x89, 0xd0, 0xe2, 0x1b, +0xcb, 0x41, 0xd0, 0x2e, 0x52, 0xf1, 0xa9, 0xe3, +0xb5, 0xd8, 0xf3, 0xfc, 0x9b, 0x4c, 0x23, 0x17, +0x2f, 0x9f, 0xf0, 0x3c, 0x2c, 0x24, 0xe1, 0x11, +0x04, 0xa1, 0xe3, 0xfc, 0x0b, 0xb4, 0xa6, 0x13, +0x28, 0x6e, 0x63, 0x69, 0x69, 0x09, 0xdd, 0xa4, +0x83, 0xad, 0xad, 0x2d, 0xa4, 0x69, 0x8a, 0x5e, +0xaf, 0x87, 0x6f, 0x7f, 0xff, 0x07, 0xf8, 0x1f, +0xb3, 0x1d, 0x0c, 0x8b, 0xd6, 0x7c, 0x92, 0x10, +0x31, 0x60, 0x9b, 0xa0, 0x23, 0x20, 0xca, 0xe4, +0xaa, 0x4c, 0x2a, 0x4a, 0x6f, 0x11, 0x48, 0x2a, +0x9b, 0x26, 0x9f, 0xe4, 0x44, 0x79, 0xbc, 0x74, +0x59, 0x1f, 0xdf, 0x84, 0xa5, 0x04, 0xcd, 0xca, +0x2f, 0x11, 0x1c, 0xaa, 0x4f, 0x9b, 0xe4, 0xac, +0x1e, 0x47, 0x28, 0x79, 0xdb, 0xc3, 0x08, 0x51, +0xab, 0x28, 0xb7, 0x87, 0xc3, 0x6c, 0x31, 0xb8, +0x34, 0xb2, 0x2e, 0x65, 0x51, 0x95, 0xd2, 0x4a, +0xae, 0x5a, 0xf6, 0x8f, 0x68, 0x77, 0x69, 0x11, +0xca, 0x71, 0xb0, 0xfa, 0x95, 0xe3, 0xec, 0x63, +0x6e, 0x78, 0x39, 0xf1, 0x8c, 0xb9, 0xe3, 0x04, +0x97, 0x13, 0x48, 0x5e, 0x9e, 0xc8, 0x67, 0xe2, +0xc1, 0x37, 0x23, 0x1f, 0x33, 0xa3, 0xcd, 0x87, +0xd9, 0x7b, 0x37, 0x46, 0x62, 0x93, 0x8a, 0x5a, +0x45, 0x99, 0x70, 0x6b, 0x4c, 0x8e, 0xc5, 0x94, +0x68, 0x4c, 0x4f, 0xdc, 0xc1, 0x64, 0x3c, 0xc2, +0x20, 0xee, 0xe2, 0x68, 0x94, 0xe3, 0xe7, 0xe9, +0x12, 0xfe, 0x74, 0xfd, 0x25, 0xbc, 0xd7, 0x3b, +0xc0, 0xd2, 0xee, 0x2d, 0xbc, 0xb4, 0x1c, 0xa0, +0x18, 0x0d, 0x5c, 0xf1, 0x72, 0x03, 0xe7, 0x6b, +0x95, 0xf6, 0x14, 0x19, 0x9a, 0x59, 0x73, 0xa2, +0x25, 0x86, 0x9e, 0xf2, 0xd0, 0xbe, 0x65, 0xc5, +0x68, 0x97, 0xfb, 0x94, 0x16, 0xae, 0x9a, 0x5f, +0xa5, 0xcc, 0xf7, 0x0e, 0xdf, 0x95, 0xa8, 0x5c, +0x30, 0x92, 0x79, 0xf9, 0x9e, 0x4e, 0x21, 0xad, +0x2d, 0x61, 0x85, 0xd2, 0x6a, 0x84, 0x8e, 0xf2, +0xcb, 0x30, 0xd9, 0x3e, 0x47, 0x3b, 0x4e, 0x1c, +0x79, 0x1b, 0xe5, 0x5e, 0xa9, 0x5d, 0x9a, 0xc3, +0xf3, 0xf0, 0xf6, 0x53, 0x99, 0x1a, 0xbd, 0x91, +0x17, 0x7e, 0xf1, 0x32, 0x29, 0xdd, 0x60, 0x38, +0xc2, 0x78, 0x3c, 0x41, 0x18, 0x04, 0xa5, 0xba, +0x35, 0x7a, 0xc3, 0xc7, 0x8f, 0xc2, 0xe7, 0x52, +0x7b, 0x97, 0xd2, 0x21, 0x36, 0x37, 0x36, 0xf0, +0x59, 0x7b, 0x63, 0x1a, 0xd2, 0x56, 0xee, 0x0f, +0xd6, 0xfe, 0xe9, 0xdb, 0x2f, 0x69, 0x8f, 0x94, +0xeb, 0x81, 0xaf, 0x3d, 0xc9, 0xfc, 0xe7, 0xd9, +0x94, 0x98, 0x6f, 0x8d, 0x4f, 0xdd, 0x04, 0x94, +0x97, 0xac, 0x68, 0x17, 0x0b, 0xf8, 0x38, 0x4c, +0xea, 0x10, 0x6a, 0xb4, 0xc6, 0xb5, 0x12, 0xd0, +0xc4, 0xe3, 0x93, 0x55, 0xde, 0x26, 0x44, 0x20, +0x07, 0x50, 0xbb, 0xa5, 0x88, 0x6b, 0x0d, 0xe4, +0xed, 0x64, 0xda, 0xa4, 0x92, 0x13, 0x57, 0x72, +0x64, 0xf2, 0xd9, 0x1a, 0x6c, 0xbe, 0x60, 0x38, +0x1e, 0xf4, 0xcc, 0x25, 0x77, 0x39, 0x09, 0x09, +0xff, 0x4e, 0xbb, 0x3d, 0x57, 0xa5, 0x8f, 0xc7, +0x48, 0xd3, 0x14, 0x61, 0xd0, 0x42, 0x91, 0xe7, +0x88, 0xa2, 0x68, 0xee, 0xa9, 0xbb, 0xb1, 0x8d, +0x60, 0xeb, 0x06, 0xfe, 0x65, 0xb1, 0x81, 0x0c, +0xad, 0xf9, 0x26, 0x6b, 0x49, 0x3b, 0x10, 0x44, +0x52, 0x12, 0x15, 0x9a, 0x10, 0x3e, 0xee, 0x90, +0xa7, 0xa1, 0xc9, 0xa7, 0xa5, 0x99, 0x95, 0x61, +0x49, 0x8d, 0x95, 0xff, 0x62, 0x52, 0x96, 0x08, +0x94, 0xd8, 0xa4, 0x2b, 0xdc, 0xa8, 0xe4, 0x78, +0xc5, 0xa2, 0xa9, 0x30, 0x39, 0x0a, 0x33, 0x53, +0xd1, 0x52, 0x68, 0xf5, 0x11, 0x41, 0x96, 0xc4, +0x48, 0xe4, 0x73, 0x92, 0x2b, 0x27, 0xc6, 0x1a, +0x91, 0xf2, 0xf5, 0xb3, 0x18, 0x3b, 0x95, 0x08, +0x8a, 0xbc, 0x51, 0x3e, 0x99, 0xb7, 0x43, 0x93, +0x82, 0x2d, 0xed, 0x03, 0x53, 0xff, 0x99, 0x04, +0x55, 0x12, 0x79, 0x65, 0xdc, 0x4c, 0x89, 0x9f, +0x8d, 0x73, 0x49, 0x53, 0xf0, 0x8c, 0xfd, 0x5f, +0x1a, 0x6f, 0xd1, 0x56, 0x55, 0xf3, 0x31, 0x2b, +0x67, 0x32, 0x1e, 0xe1, 0x2c, 0x6b, 0xe1, 0xfd, +0x60, 0x1d, 0x1f, 0x75, 0x77, 0xb0, 0xbb, 0xb9, +0x81, 0xf5, 0x6e, 0x07, 0x1d, 0x4c, 0x63, 0x5c, +0x6b, 0xfb, 0x8e, 0x16, 0xf7, 0x9d, 0x13, 0x2d, +0x6b, 0x8f, 0xa2, 0xfd, 0xcd, 0x62, 0xe8, 0xb9, +0x80, 0x74, 0x76, 0x7e, 0x81, 0xc9, 0x78, 0xee, +0x99, 0x6f, 0xa9, 0xd0, 0x35, 0x02, 0x4e, 0xe9, +0x35, 0x5c, 0x39, 0x8e, 0x49, 0x92, 0x94, 0x88, +0xfb, 0x70, 0x38, 0x74, 0x84, 0x98, 0x13, 0x55, +0x49, 0xf8, 0x38, 0xd1, 0xd2, 0x6e, 0xb8, 0x94, +0xcc, 0x82, 0x76, 0x01, 0x17, 0x69, 0x00, 0xb8, +0x86, 0x40, 0xde, 0xac, 0xa9, 0x09, 0x8d, 0x5a, +0x7f, 0x68, 0xda, 0x52, 0x8d, 0x88, 0x6b, 0x63, +0xc0, 0x61, 0x9c, 0x17, 0x98, 0xcc, 0xce, 0xaa, +0x87, 0x41, 0xe0, 0x2e, 0xdd, 0xe1, 0xb4, 0x42, +0x63, 0x18, 0xb4, 0x3a, 0xa9, 0xde, 0x7e, 0xbf, +0x8f, 0xd5, 0xa3, 0x8f, 0x31, 0xdc, 0xba, 0x85, +0x27, 0xe1, 0x52, 0x65, 0xfe, 0x95, 0xf6, 0x1f, +0xb9, 0x7f, 0x6a, 0xe9, 0xe4, 0xfe, 0xa0, 0xad, +0x0f, 0xa3, 0xfc, 0x70, 0xf7, 0x9b, 0xbf, 0xfe, +0xe6, 0xfa, 0xc5, 0x93, 0xd2, 0x64, 0xe3, 0x8d, +0xe2, 0x5c, 0x88, 0xe4, 0xf6, 0xe4, 0x65, 0x08, +0x92, 0x78, 0x6b, 0x76, 0x62, 0xed, 0x82, 0x15, +0x6d, 0xe2, 0x4b, 0xae, 0xcc, 0x2a, 0x8f, 0x97, +0x41, 0xbf, 0xf9, 0x45, 0x2e, 0xf4, 0xde, 0x5a, +0x74, 0xbe, 0x49, 0xc2, 0x07, 0xd9, 0xba, 0xe9, +0x49, 0x12, 0x65, 0xa9, 0xb9, 0xd0, 0x6e, 0x40, +0x23, 0x35, 0x3c, 0x11, 0x79, 0xfa, 0x4e, 0xce, +0x15, 0xdc, 0xce, 0x17, 0x46, 0x31, 0x26, 0xe3, +0x31, 0xfa, 0xfd, 0x3e, 0x82, 0x76, 0x07, 0x2b, +0x71, 0x80, 0xec, 0xfa, 0x2d, 0xfc, 0x59, 0xb8, +0x89, 0x51, 0x66, 0xa8, 0x6e, 0xb8, 0xfa, 0x3c, +0xee, 0x20, 0x6f, 0x85, 0x55, 0xee, 0x50, 0x4a, +0x96, 0x4d, 0x55, 0xc7, 0x2c, 0x4d, 0xd4, 0x2a, +0x2a, 0x6a, 0xfc, 0x92, 0x6d, 0x5b, 0x93, 0x8a, +0xe3, 0x4e, 0x55, 0x6a, 0x96, 0xf8, 0x70, 0xfc, +0x25, 0xce, 0x1a, 0xc7, 0x2a, 0xda, 0xab, 0x2e, +0x08, 0x41, 0xc4, 0xdc, 0x62, 0x90, 0xea, 0x2c, +0xa9, 0xe5, 0xf0, 0x71, 0xd6, 0xec, 0x7b, 0x89, +0xa9, 0x6a, 0xba, 0x10, 0x35, 0x7c, 0xd8, 0x62, +0xaf, 0x98, 0x3c, 0x38, 0xce, 0xb3, 0xb2, 0x4c, +0x6d, 0x81, 0xc6, 0xdc, 0x51, 0xd9, 0x52, 0x92, +0xd7, 0xf0, 0xa4, 0x3e, 0xe3, 0x7d, 0xa1, 0x48, +0xc3, 0x0e, 0x47, 0xad, 0x7f, 0x78, 0x39, 0xb2, +0xfd, 0x4d, 0xfb, 0x9f, 0xde, 0xc9, 0xf2, 0x59, +0x5b, 0x4b, 0x38, 0xc8, 0xbe, 0x65, 0xbf, 0xcf, +0xb2, 0x16, 0xde, 0xc2, 0x1a, 0x3e, 0xea, 0xee, +0xa1, 0x7f, 0xfd, 0x79, 0x5c, 0x6e, 0xdf, 0xc6, +0x6a, 0x27, 0xc6, 0x66, 0xbb, 0x85, 0x28, 0x68, +0xa9, 0xc4, 0x89, 0x7e, 0x13, 0x21, 0xa0, 0x35, +0xcf, 0x05, 0x11, 0xeb, 0x12, 0x18, 0x6e, 0x5b, +0x95, 0x1a, 0xc9, 0xcb, 0xcb, 0x01, 0xf2, 0xbc, +0x40, 0xa7, 0x3d, 0xf5, 0xe4, 0xa6, 0xbd, 0x40, +0x5e, 0x36, 0x63, 0x99, 0x0d, 0x35, 0x46, 0x81, +0x40, 0x93, 0xcc, 0xb9, 0xc4, 0x0f, 0xd8, 0x5a, +0x4b, 0x2a, 0x9b, 0x83, 0x26, 0xd4, 0x70, 0xa6, +0xa6, 0x89, 0x06, 0x41, 0xee, 0xc7, 0xd2, 0x64, +0x60, 0xb5, 0x4f, 0x33, 0xdb, 0x6a, 0x69, 0xb5, +0xeb, 0x68, 0xb9, 0xd9, 0x01, 0x00, 0xc2, 0x56, +0xab, 0x62, 0xf6, 0xe4, 0x75, 0xa5, 0x69, 0x8a, +0x30, 0x8a, 0x91, 0xe7, 0x05, 0x82, 0x20, 0x74, +0xff, 0x89, 0xe8, 0x6b, 0x7d, 0x3f, 0x44, 0x88, +0x93, 0x78, 0x05, 0xef, 0xde, 0xfa, 0x16, 0xd2, +0x64, 0xa5, 0x6a, 0x86, 0xaa, 0x53, 0xad, 0x8b, +0xf5, 0xe1, 0xf6, 0x46, 0xcb, 0xb4, 0x67, 0x69, +0x1d, 0xc3, 0x08, 0xe1, 0xfe, 0x77, 0x7e, 0xf3, +0xcd, 0xd5, 0xb3, 0xcf, 0x4b, 0x04, 0x93, 0x0f, +0xb8, 0x26, 0xb1, 0xf2, 0xc9, 0x26, 0x55, 0x3d, +0x1a, 0x31, 0xe4, 0x8c, 0x01, 0x0d, 0xb8, 0x9c, +0x28, 0x7c, 0xf2, 0x5b, 0xaa, 0x7c, 0x3e, 0x58, +0x9a, 0x6d, 0x8b, 0x0f, 0xb6, 0x94, 0xd6, 0xe5, +0x44, 0x94, 0x13, 0x40, 0x93, 0xe8, 0xb9, 0x2a, +0x5c, 0x0e, 0xbe, 0x54, 0x83, 0x49, 0xdb, 0x96, +0x65, 0x47, 0x73, 0x13, 0x2b, 0x8a, 0x2b, 0xf7, +0x94, 0x9f, 0x9d, 0x5f, 0xe0, 0xec, 0xf4, 0xb4, +0xb4, 0x50, 0x8a, 0x3c, 0x47, 0x18, 0xc5, 0x58, +0x5f, 0x5b, 0xc3, 0xe6, 0xc6, 0x06, 0x7a, 0xbd, +0x1e, 0xd6, 0x6f, 0xbf, 0x84, 0x7f, 0x31, 0x59, +0x45, 0x10, 0xb4, 0x74, 0x75, 0xab, 0x4f, 0x32, +0x93, 0x1b, 0xa7, 0x35, 0xf9, 0x1a, 0x48, 0xea, +0x4e, 0xa2, 0xd3, 0x88, 0x83, 0x22, 0x69, 0xd2, +0x46, 0xad, 0xa9, 0xc5, 0xbd, 0x13, 0xdf, 0x87, +0x8f, 0xd5, 0x5e, 0xcb, 0xac, 0x20, 0x17, 0xc9, +0x15, 0xda, 0xab, 0x6a, 0x26, 0x14, 0x75, 0x97, +0x37, 0xbd, 0xb1, 0x40, 0xbd, 0x75, 0x6b, 0x84, +0x4e, 0x8e, 0x5d, 0x8d, 0xdd, 0xde, 0x94, 0xf4, +0xeb, 0xfa, 0xe7, 0xaa, 0xf8, 0x68, 0x9a, 0x9b, +0x2f, 0x32, 0xdf, 0xae, 0x3a, 0x9f, 0xeb, 0x34, +0x13, 0x79, 0x86, 0x01, 0x02, 0x3c, 0x0e, 0x57, +0x70, 0xbf, 0x48, 0xf0, 0xd6, 0xfa, 0x0b, 0x78, +0xb4, 0x79, 0x80, 0xaf, 0xef, 0xf4, 0xb0, 0x5c, +0x4c, 0x90, 0x4f, 0xc6, 0x25, 0xc9, 0x94, 0xa0, +0x13, 0xcf, 0xef, 0x25, 0xe0, 0xb7, 0x32, 0xd2, +0xb3, 0x25, 0x41, 0x5b, 0x12, 0xfd, 0x64, 0x3c, +0x46, 0x18, 0x04, 0x25, 0x93, 0x1b, 0xd7, 0x66, +0xca, 0x9b, 0x1f, 0x25, 0xf8, 0x7c, 0x88, 0xa4, +0xd0, 0x23, 0x05, 0x15, 0x5e, 0x0f, 0xd7, 0x4c, +0x6a, 0x7b, 0x9a, 0xa6, 0x1e, 0xe7, 0x65, 0x49, +0x29, 0x9f, 0xef, 0xcd, 0xd2, 0x64, 0xca, 0x69, +0x00, 0xc7, 0x93, 0x70, 0xb5, 0xfa, 0x8f, 0x03, +0xf7, 0xaf, 0x92, 0x02, 0x1f, 0x7f, 0x2f, 0xe9, +0x12, 0xaf, 0x4f, 0x12, 0x74, 0xde, 0x5f, 0x79, +0x5e, 0xbe, 0x37, 0x3c, 0x8e, 0xc2, 0x12, 0x7e, +0x79, 0x10, 0x22, 0x2b, 0x80, 0x62, 0xa6, 0x52, +0x4f, 0x11, 0xe0, 0xbd, 0x57, 0xff, 0x3a, 0x4e, +0xd7, 0x76, 0xf4, 0xbd, 0x8b, 0xcc, 0x4c, 0x92, +0xe9, 0xd5, 0xb4, 0xa6, 0x75, 0xfb, 0xa7, 0xd4, +0x68, 0x89, 0x39, 0x1f, 0x14, 0x4c, 0xd5, 0xc4, +0x1b, 0x2d, 0x09, 0xae, 0x46, 0x10, 0xf9, 0x77, +0xfe, 0x5b, 0xf3, 0x60, 0xf7, 0x79, 0xa0, 0x6b, +0xe5, 0x48, 0x4f, 0xc3, 0x3a, 0xb0, 0xf0, 0xd3, +0xda, 0xa1, 0x79, 0xd0, 0x37, 0x29, 0x5f, 0xc3, +0x6f, 0x79, 0x65, 0xb5, 0xf6, 0xa8, 0x0a, 0x7f, +0x4f, 0xaa, 0x19, 0xcd, 0x6b, 0x9d, 0x4f, 0x1c, +0x5e, 0x66, 0x1c, 0x85, 0xee, 0x7c, 0xf9, 0xad, +0xaf, 0xbd, 0x86, 0x7f, 0x90, 0x6e, 0x21, 0xcd, +0xf2, 0xf9, 0xc5, 0x27, 0xd2, 0x7b, 0x5a, 0xfe, +0xe6, 0xef, 0x80, 0xaa, 0x97, 0x32, 0x53, 0x99, +0x36, 0xf6, 0x0a, 0xf7, 0x01, 0xaf, 0x97, 0x7b, +0x61, 0x73, 0x0f, 0x6a, 0x5e, 0x86, 0xe6, 0x99, +0xed, 0xf3, 0x7e, 0xe6, 0x69, 0xad, 0xf6, 0xfa, +0x8e, 0x6a, 0x09, 0x4f, 0x6e, 0xd7, 0x6e, 0x5f, +0x7b, 0xad, 0xe3, 0x5f, 0x12, 0x1f, 0xd9, 0xaf, +0x9e, 0xbe, 0x72, 0xf5, 0x6a, 0x79, 0x67, 0xcf, +0x25, 0xdc, 0x7c, 0xc7, 0xd1, 0x2c, 0xef, 0x71, +0x56, 0x6e, 0xe5, 0xa6, 0x2a, 0x0d, 0x6a, 0xf0, +0xa9, 0x8c, 0x97, 0xd5, 0xaf, 0xb2, 0x4c, 0xab, +0x7c, 0x6b, 0xbe, 0xd5, 0xfd, 0x96, 0xe5, 0x5b, +0xf3, 0xa7, 0x6e, 0xbc, 0x26, 0x23, 0x3c, 0xc8, +0xda, 0xf8, 0x7f, 0x45, 0x5f, 0xc1, 0xef, 0xbe, +0xf0, 0x13, 0x3c, 0xf9, 0xde, 0x7f, 0x82, 0x0f, +0x5f, 0xff, 0x9b, 0xb8, 0xf6, 0x9d, 0x9f, 0x60, +0x77, 0x77, 0xb7, 0x72, 0x2c, 0x49, 0xf3, 0xf4, +0xa6, 0x67, 0x0e, 0xbe, 0x63, 0xba, 0x5a, 0x7a, +0x1e, 0x66, 0x55, 0x9e, 0xac, 0x91, 0x9e, 0xd7, +0x5a, 0x1d, 0x1c, 0xa4, 0xc7, 0x36, 0xcf, 0xaf, +0x1d, 0x8b, 0xf3, 0x1d, 0x27, 0x96, 0xde, 0xec, +0xf4, 0xc7, 0x03, 0xf6, 0x68, 0xfb, 0xa7, 0xef, +0xd4, 0x8e, 0x95, 0x46, 0x3d, 0x92, 0x2b, 0xfa, +0x5b, 0xde, 0x03, 0xa2, 0x79, 0xa4, 0xcb, 0xf2, +0xad, 0x3e, 0x22, 0x2f, 0x75, 0x02, 0x3a, 0xb1, +0x00, 0x4c, 0xf7, 0x5c, 0xfa, 0xcd, 0xa1, 0x1d, +0xb4, 0x90, 0x8f, 0x47, 0x2e, 0xef, 0xd1, 0x0b, +0x6f, 0xe0, 0x68, 0xff, 0x15, 0xef, 0x7c, 0x53, +0x03, 0xc9, 0xcc, 0xfe, 0xab, 0x27, 0x82, 0xb4, +0xfd, 0x53, 0x96, 0xaf, 0x3c, 0x87, 0x9b, 0xaf, +0x7e, 0xe7, 0xcd, 0xad, 0xf1, 0xa9, 0x7b, 0xc7, +0xef, 0xfb, 0x26, 0xa7, 0x0e, 0x87, 0x94, 0x62, +0xd7, 0x90, 0x9c, 0x19, 0x75, 0x94, 0xa6, 0xbe, +0x96, 0xea, 0x6f, 0xa9, 0xaa, 0x97, 0x9e, 0x8c, +0x94, 0x9f, 0x73, 0x74, 0x96, 0x9d, 0x86, 0xde, +0x11, 0xbe, 0x5c, 0x85, 0x4d, 0xf9, 0xb8, 0xed, +0x48, 0x6a, 0x16, 0x34, 0x67, 0x0c, 0xa9, 0xad, +0x18, 0x0c, 0x47, 0x08, 0x82, 0xd0, 0x79, 0x9c, +0x93, 0x7d, 0x9b, 0xe3, 0x23, 0x1d, 0x43, 0xf8, +0x11, 0x11, 0xfa, 0xd6, 0xeb, 0xf5, 0x2a, 0x6a, +0xb4, 0x34, 0x4d, 0x31, 0x49, 0x33, 0xe7, 0x35, +0x4b, 0x92, 0x3b, 0xb7, 0x71, 0x25, 0x49, 0x82, +0x93, 0xe7, 0xbf, 0x85, 0xdf, 0x1d, 0xaf, 0xb9, +0xfb, 0x83, 0x2b, 0x36, 0x4f, 0x4d, 0x7d, 0x23, +0xd5, 0xa0, 0x9a, 0xca, 0x37, 0xcf, 0xaa, 0x5e, +0xd0, 0x52, 0x82, 0x6b, 0xe2, 0xb1, 0xac, 0xd5, +0xdb, 0xd4, 0xf3, 0xbc, 0x26, 0xaf, 0x93, 0x2c, +0xb9, 0x5a, 0x9f, 0x3b, 0xa6, 0x69, 0x79, 0xb9, +0x03, 0x96, 0x21, 0x51, 0x9b, 0x27, 0x02, 0x14, +0x09, 0x56, 0xf5, 0x16, 0xaf, 0x69, 0x6f, 0xa9, +0x7e, 0x4b, 0xc5, 0xad, 0x49, 0xb8, 0x80, 0x6e, +0x57, 0xd6, 0xfa, 0xed, 0xcb, 0xee, 0xe7, 0x06, +0x7d, 0x52, 0x6a, 0x57, 0xdd, 0x7b, 0x39, 0xdf, +0x8c, 0x71, 0xa9, 0x38, 0xc5, 0xd5, 0x99, 0x39, +0xae, 0xd0, 0x2e, 0x5f, 0x9a, 0xa0, 0xc8, 0xf1, +0x28, 0x8b, 0xf0, 0x7e, 0xb0, 0x8e, 0xfb, 0x45, +0x82, 0x0f, 0x96, 0x76, 0x11, 0x6f, 0x5c, 0xc7, +0xdd, 0x64, 0xee, 0x0d, 0x6f, 0xf9, 0xff, 0xf0, +0xf5, 0xae, 0xf9, 0x18, 0xf1, 0xfd, 0xce, 0x3a, +0x7e, 0x46, 0xfb, 0x1f, 0xdf, 0xa3, 0x34, 0x27, +0x36, 0x0e, 0xdc, 0x64, 0xc9, 0xbd, 0xd5, 0x69, +0x5f, 0x25, 0xe6, 0x83, 0x97, 0x27, 0x19, 0x00, +0x2e, 0xc1, 0x5a, 0x3e, 0x42, 0x5c, 0x0b, 0x41, +0x44, 0x5c, 0x9a, 0x62, 0xa5, 0x27, 0x3d, 0xd7, +0xb6, 0x4a, 0x2f, 0x77, 0xee, 0xd0, 0xc6, 0x41, +0x3a, 0xb0, 0x49, 0x33, 0xa6, 0xa6, 0x45, 0xe5, +0x78, 0x52, 0x19, 0x92, 0x16, 0x51, 0x7e, 0x0e, +0x9c, 0x70, 0xf3, 0xbd, 0x3c, 0x8a, 0x22, 0xe4, +0x79, 0xe1, 0x54, 0xeb, 0x5c, 0x9b, 0xca, 0xb5, +0x26, 0x45, 0x9e, 0xe3, 0x62, 0x75, 0x1b, 0xef, +0xbe, 0xfa, 0x37, 0x90, 0xc6, 0x49, 0x75, 0xfd, +0x7e, 0xc9, 0xf3, 0xd3, 0x3c, 0xed, 0x92, 0x67, +0xee, 0x4e, 0xf8, 0x70, 0xff, 0x8d, 0x1f, 0xbd, +0xd9, 0xed, 0x3f, 0x34, 0xed, 0xdd, 0xd2, 0x96, +0xae, 0xd9, 0x2f, 0xb4, 0xc9, 0x4b, 0xf6, 0x07, +0xad, 0x53, 0x78, 0x7e, 0x4b, 0x1d, 0x63, 0x79, +0x2d, 0x4a, 0x1c, 0xa4, 0x5a, 0xc7, 0x3a, 0xfa, +0xa5, 0x39, 0xd0, 0x69, 0x47, 0xcd, 0x28, 0x9f, +0x36, 0xa1, 0xc8, 0x69, 0xc2, 0x32, 0x3f, 0xc8, +0x32, 0x38, 0xd3, 0xa0, 0xe1, 0xc5, 0x8f, 0xb0, +0x0c, 0x87, 0x43, 0x47, 0xc8, 0x01, 0xa0, 0xc8, +0x73, 0x57, 0xf6, 0xd6, 0xd6, 0x16, 0x0e, 0x0e, +0x0e, 0xd0, 0x7a, 0xe9, 0x1b, 0xf8, 0x7f, 0x0f, +0x36, 0x71, 0x9a, 0xce, 0xcf, 0x57, 0x57, 0x8e, +0x50, 0x29, 0x76, 0xe5, 0x28, 0x0c, 0xa6, 0x2a, +0xf9, 0x19, 0x21, 0x24, 0x02, 0xa8, 0x11, 0x47, +0x4a, 0x4f, 0x9b, 0xac, 0xcb, 0x9b, 0xa6, 0x65, +0x7b, 0x0e, 0xdb, 0x60, 0x39, 0x41, 0x8d, 0xc2, +0x00, 0x41, 0x91, 0x57, 0xcb, 0xe7, 0xc1, 0x0d, +0x18, 0xb1, 0x88, 0x5a, 0x85, 0xc3, 0xad, 0xe2, +0xa9, 0x2c, 0xca, 0xa7, 0x34, 0xbc, 0xfc, 0x34, +0x88, 0x2b, 0xc4, 0x82, 0xea, 0xa5, 0x7c, 0x41, +0xd0, 0x9a, 0xb7, 0x9f, 0xd2, 0x69, 0x36, 0x6b, +0x46, 0xc8, 0x2a, 0x04, 0x6d, 0xd6, 0xaf, 0x9c, +0xd0, 0xc8, 0x7e, 0x2a, 0x31, 0x15, 0xac, 0x5c, +0x5e, 0x77, 0xa9, 0x3f, 0x25, 0xd1, 0x13, 0x6a, +0x6a, 0xd7, 0x0e, 0xc2, 0xc5, 0xf0, 0x31, 0x28, +0xe1, 0xa1, 0xf5, 0x27, 0xe1, 0x24, 0x08, 0x23, +0x2f, 0x3f, 0x28, 0x72, 0x87, 0x13, 0x80, 0xea, +0x78, 0x08, 0x07, 0x1d, 0x7e, 0xa1, 0x84, 0xb4, +0xdf, 0x49, 0x95, 0x22, 0xef, 0x1b, 0x3e, 0x7e, +0xae, 0x5f, 0x84, 0x53, 0x5c, 0x29, 0xbd, 0xd6, +0x1e, 0xa5, 0x1d, 0xe6, 0xfc, 0x96, 0xe9, 0x81, +0xca, 0xfc, 0x8f, 0x5a, 0xc5, 0xbc, 0x2d, 0xb3, +0xf6, 0x4e, 0xd2, 0x14, 0xf7, 0x8a, 0x2e, 0x0e, +0xd7, 0xf7, 0xf1, 0xd1, 0xe6, 0x8b, 0x78, 0xb0, +0xfd, 0x12, 0x36, 0x77, 0xf7, 0xb0, 0xbb, 0x79, +0x0d, 0xab, 0xed, 0x08, 0xd1, 0x2c, 0xbe, 0x16, +0x97, 0x1c, 0x69, 0xad, 0xe7, 0x41, 0x88, 0x4e, +0x1c, 0x63, 0x65, 0x65, 0x05, 0xfd, 0xe1, 0x04, +0x45, 0x9a, 0x22, 0xcf, 0x0b, 0xb4, 0xa2, 0xd8, +0xa9, 0xeb, 0x79, 0xda, 0xb0, 0xd5, 0x2a, 0xed, +0xa3, 0x9a, 0xcd, 0x97, 0x1f, 0x3d, 0x93, 0x7b, +0x97, 0xf4, 0x36, 0x97, 0xc4, 0x92, 0x33, 0x0e, +0x9c, 0xe8, 0xf9, 0xf6, 0x55, 0xa9, 0xba, 0x96, +0x6d, 0x94, 0x82, 0x88, 0xa6, 0x16, 0x97, 0x36, +0x73, 0x9e, 0x4e, 0x3b, 0x7a, 0xac, 0x39, 0x60, +0xcb, 0x7d, 0x95, 0x97, 0xab, 0xa9, 0xf7, 0x79, +0x7d, 0x9a, 0xa6, 0x81, 0xef, 0xe5, 0xc0, 0x94, +0xa8, 0x07, 0x41, 0x88, 0xc9, 0x78, 0xec, 0x18, +0x9d, 0x4e, 0xbb, 0x5d, 0x6a, 0x3f, 0x8d, 0x91, +0xf4, 0x9d, 0xfa, 0xb3, 0x97, 0xff, 0xea, 0x5c, +0xbd, 0xce, 0xf6, 0x10, 0xd3, 0x47, 0x44, 0xcc, +0xbd, 0x20, 0x68, 0x21, 0xcf, 0x01, 0x14, 0x05, +0xd0, 0x0a, 0xa6, 0x7f, 0x45, 0x5e, 0xc9, 0x03, +0xb4, 0xa6, 0xef, 0xa9, 0xbc, 0x19, 0xf1, 0x76, +0x7b, 0xd3, 0xec, 0xb7, 0x8b, 0xcd, 0x4e, 0x1d, +0xc8, 0xd5, 0x3d, 0xd4, 0x01, 0x9c, 0x78, 0xc9, +0x00, 0x08, 0xfc, 0x9d, 0x16, 0xec, 0x40, 0x53, +0x55, 0xc8, 0x45, 0xc0, 0xeb, 0x6f, 0x02, 0x75, +0x69, 0x7d, 0x6a, 0x6e, 0xed, 0x18, 0x85, 0xbc, +0x0f, 0x58, 0xaa, 0xbb, 0x78, 0x1e, 0x1e, 0xec, +0x46, 0x8b, 0x4d, 0x2c, 0x55, 0x43, 0x32, 0x58, +0x82, 0xec, 0x37, 0x0d, 0x1f, 0x59, 0x27, 0xfd, +0x3f, 0x8a, 0x57, 0x31, 0x2a, 0x96, 0x80, 0xd1, +0x68, 0x3a, 0xa0, 0x75, 0x51, 0xc0, 0xe2, 0x72, +0x78, 0xce, 0x4a, 0x2c, 0x70, 0x09, 0x71, 0xf5, +0xaa, 0x50, 0xda, 0xe4, 0x2a, 0x41, 0x0f, 0x7e, +0x59, 0xd2, 0x67, 0x76, 0xd4, 0xb6, 0x34, 0x88, +0x11, 0x41, 0xb4, 0x5f, 0x04, 0x9e, 0x71, 0x57, +0x1f, 0xce, 0x82, 0x94, 0x50, 0xf9, 0xa5, 0xf4, +0x04, 0x93, 0xf2, 0x0d, 0x4b, 0x3c, 0xad, 0xbb, +0x29, 0x49, 0xa8, 0xd4, 0x6a, 0xf1, 0x57, 0xc6, +0xce, 0x2c, 0xb3, 0x66, 0x7c, 0xa7, 0x44, 0x71, +0x52, 0xce, 0x57, 0x53, 0x3e, 0xe2, 0x6a, 0xdc, +0x7e, 0xeb, 0x7d, 0x14, 0x06, 0xd3, 0xf2, 0x45, +0x5a, 0xed, 0xfd, 0x17, 0x1e, 0x6f, 0xab, 0x3d, +0x0d, 0xe7, 0x77, 0x93, 0xf4, 0x7c, 0x7e, 0x58, +0xe9, 0x3f, 0x1c, 0xd1, 0x98, 0x47, 0x78, 0x37, +0x58, 0xc6, 0x46, 0xef, 0x16, 0xae, 0xaf, 0x5d, +0x62, 0xa5, 0x98, 0x60, 0x79, 0x72, 0x81, 0x8d, +0x6c, 0x7a, 0xd4, 0x6d, 0xeb, 0xc9, 0x3d, 0x9c, +0x1e, 0x3f, 0x45, 0x32, 0x38, 0x2b, 0xc7, 0x5c, +0x4f, 0x62, 0x8c, 0xf3, 0x08, 0xf9, 0x78, 0xe4, +0x22, 0x6c, 0xca, 0x35, 0x3e, 0x6e, 0x77, 0x90, +0x8f, 0x47, 0xaa, 0xaa, 0x9e, 0xd4, 0xb9, 0x3e, +0x53, 0x63, 0xbf, 0xdf, 0x57, 0x23, 0x97, 0x8d, +0xf3, 0x02, 0x60, 0xfb, 0x11, 0x2f, 0x83, 0x47, +0x92, 0xab, 0x8d, 0xd0, 0xc6, 0xf0, 0xb1, 0xbe, +0x6b, 0xf9, 0xad, 0x00, 0x2e, 0x3c, 0xbd, 0xbc, +0xea, 0xd6, 0xca, 0x2f, 0xf7, 0xc4, 0x3a, 0x5a, +0x61, 0xa9, 0xd6, 0x79, 0x3b, 0x86, 0xc3, 0x21, +0xc2, 0x28, 0x56, 0xc7, 0x84, 0x20, 0x68, 0x77, +0x5c, 0x70, 0x21, 0x9e, 0xee, 0xe1, 0xcd, 0x57, +0x71, 0xb4, 0xf3, 0x52, 0xa9, 0x7c, 0x6b, 0xfd, +0x03, 0xfa, 0xfe, 0x32, 0x0d, 0xfa, 0xc5, 0x9c, +0xeb, 0xf2, 0xd9, 0x0a, 0x0a, 0xa2, 0xf9, 0x6f, +0xf9, 0x9e, 0x9e, 0x15, 0xd3, 0x54, 0x94, 0x33, +0x69, 0x90, 0x6c, 0x21, 0x3c, 0x94, 0xaa, 0x46, +0x70, 0x64, 0xc3, 0x7c, 0xf6, 0x74, 0xf9, 0xde, +0x47, 0xe8, 0xe8, 0xbd, 0x76, 0x4d, 0x1f, 0xe1, +0xc6, 0x71, 0xd2, 0xee, 0x3c, 0xae, 0x03, 0x8d, +0xe1, 0xb0, 0xca, 0xd0, 0xf0, 0xe3, 0x44, 0x5d, +0x8b, 0xfc, 0xa6, 0x2d, 0x48, 0x1f, 0x1e, 0xf4, +0x5b, 0x9b, 0x48, 0xc0, 0x74, 0x32, 0x0d, 0x87, +0x43, 0xe4, 0xbd, 0x6d, 0xfc, 0x51, 0xb1, 0x31, +0xbf, 0x06, 0x90, 0x0f, 0x36, 0x1f, 0x54, 0x4e, +0xe4, 0xb3, 0x0c, 0x69, 0x5e, 0xde, 0x48, 0x39, +0x94, 0x88, 0xc4, 0x2c, 0x9f, 0x46, 0xe8, 0x4b, +0xf9, 0x78, 0xf9, 0x4d, 0xd2, 0x53, 0xf9, 0x84, +0x43, 0xd3, 0xf4, 0x57, 0x2d, 0x9f, 0xe1, 0xc5, +0xaf, 0x16, 0x4c, 0xb5, 0x7c, 0x32, 0xb2, 0x18, +0x50, 0xba, 0xab, 0x5d, 0x46, 0x1f, 0x43, 0x96, +0xb9, 0x05, 0x66, 0xf6, 0x21, 0xe5, 0x2b, 0xb2, +0x6a, 0xff, 0xfb, 0xf0, 0x27, 0xdc, 0xd9, 0x98, +0x56, 0xca, 0xcc, 0x94, 0x28, 0x7c, 0xb2, 0x7f, +0x44, 0xff, 0x56, 0xc6, 0x96, 0xcd, 0x17, 0x33, +0xa4, 0x64, 0xcc, 0x6e, 0x6d, 0x93, 0xed, 0x07, +0x90, 0x16, 0xc1, 0x1c, 0x47, 0x86, 0xd7, 0x97, +0x3e, 0xde, 0x8c, 0x01, 0xa9, 0xb4, 0x47, 0x9b, +0x7f, 0xca, 0xfc, 0x56, 0xfb, 0xf8, 0x19, 0xca, +0x97, 0x65, 0x3d, 0xce, 0x80, 0xc7, 0xe8, 0x22, +0x0a, 0x97, 0x91, 0x06, 0x6b, 0x40, 0x34, 0xed, +0xdb, 0x6b, 0x7b, 0xb7, 0xb1, 0xb7, 0x3f, 0xc6, +0x0f, 0x8f, 0xfe, 0x14, 0x2b, 0x27, 0x47, 0x38, +0xcd, 0x43, 0xac, 0x05, 0x19, 0x4e, 0x2f, 0x87, +0xb8, 0xe8, 0xac, 0xe0, 0x72, 0x6d, 0x07, 0xe3, +0x2c, 0xc5, 0xb5, 0xc3, 0x77, 0x91, 0x4e, 0x26, +0x00, 0x5b, 0xf3, 0x74, 0x33, 0xd7, 0xd9, 0xf9, +0x45, 0x35, 0xca, 0xdc, 0x70, 0x58, 0x52, 0x09, +0x03, 0xe5, 0x68, 0x66, 0x6e, 0xe8, 0x66, 0xf9, +0xc6, 0x79, 0xe1, 0xf6, 0x0c, 0x7e, 0x81, 0x8a, +0xdc, 0x4b, 0x7d, 0x84, 0x56, 0xbe, 0xd7, 0xf6, +0x26, 0xb9, 0x27, 0xd6, 0xd1, 0x00, 0x29, 0xec, +0x58, 0xb4, 0x80, 0x83, 0xe6, 0x3b, 0xe0, 0xdb, +0xa7, 0x9b, 0x02, 0x6f, 0x13, 0xb7, 0x9b, 0x73, +0xc2, 0x4e, 0xc0, 0x19, 0x30, 0x00, 0xe8, 0xae, +0xae, 0x21, 0xef, 0xae, 0xe2, 0x17, 0xcf, 0xff, +0xa0, 0x52, 0xee, 0x94, 0x38, 0x47, 0xfa, 0xfa, +0xcf, 0x94, 0x3d, 0x07, 0x98, 0xae, 0xa7, 0x80, +0x69, 0xac, 0x83, 0xb2, 0xf6, 0xda, 0xad, 0x5d, +0xfe, 0x1f, 0xa8, 0xec, 0x79, 0x98, 0x8c, 0x10, +0xb5, 0xe3, 0x32, 0x67, 0xc2, 0x11, 0xe7, 0x84, +0x9d, 0xbe, 0x6b, 0xf1, 0xcf, 0x2d, 0x42, 0x44, +0x9d, 0xc5, 0x1d, 0xbb, 0xb4, 0xc1, 0x93, 0x8c, +0x03, 0x2f, 0x9f, 0x13, 0xf7, 0xab, 0x0c, 0x5a, +0x1d, 0x07, 0x67, 0x49, 0xe9, 0xd6, 0xa4, 0x92, +0x1a, 0x0a, 0xad, 0xad, 0xd6, 0x77, 0x89, 0x83, +0x0c, 0x65, 0x6b, 0xe1, 0x99, 0x24, 0x09, 0xd6, +0x96, 0xba, 0xd3, 0x7e, 0x5c, 0xdd, 0x42, 0xbf, +0xd5, 0x01, 0xc0, 0x42, 0x0d, 0xf2, 0x4d, 0xda, +0x1d, 0x6b, 0x52, 0xb8, 0x3b, 0x9f, 0x33, 0x18, +0xa5, 0xcb, 0xc5, 0xb6, 0x6b, 0x39, 0x84, 0x69, +0x5c, 0xa2, 0x2f, 0xbd, 0x56, 0x9e, 0x2f, 0xbd, +0x9c, 0xb4, 0x75, 0xe5, 0x6b, 0xf8, 0xd7, 0x39, +0xaa, 0xd1, 0xef, 0x2c, 0xab, 0xf6, 0x9f, 0xcc, +0x2f, 0xb9, 0xe4, 0x26, 0x6d, 0xac, 0xc3, 0x49, +0xc3, 0x9f, 0x81, 0x75, 0x1d, 0xac, 0xdb, 0x2c, +0xea, 0xfa, 0xc7, 0xc2, 0xaf, 0xa6, 0xfc, 0xda, +0x70, 0xb0, 0x4d, 0xda, 0x63, 0x95, 0x75, 0x95, +0xf1, 0xf6, 0xcd, 0x57, 0x6d, 0xfe, 0x35, 0x9d, +0xdf, 0xf4, 0xfb, 0x8a, 0xe5, 0x97, 0xee, 0xa8, +0x16, 0x12, 0x56, 0x9a, 0x4d, 0xd3, 0x3f, 0x2d, +0x42, 0x3c, 0x4d, 0xbb, 0xf8, 0x70, 0xe3, 0xbb, +0xe8, 0x6e, 0xcc, 0x37, 0xeb, 0xa7, 0xc5, 0x9c, +0x08, 0x77, 0x5b, 0x05, 0xb0, 0xfb, 0x6d, 0xbc, +0x9e, 0x3d, 0xc6, 0xc1, 0xc7, 0x7f, 0x82, 0xe4, +0xe1, 0x3d, 0x0c, 0x87, 0xc3, 0x79, 0x78, 0x54, +0x4c, 0x09, 0x3a, 0xe4, 0xde, 0x31, 0x7b, 0x0e, +0x66, 0x12, 0xbc, 0x46, 0x10, 0x81, 0x2a, 0x51, +0xcb, 0xc7, 0x23, 0xc0, 0xd8, 0x97, 0x78, 0xda, +0x49, 0x9a, 0x21, 0x61, 0x65, 0x58, 0x52, 0xba, +0x24, 0xac, 0x12, 0x7c, 0x04, 0x99, 0xef, 0x79, +0xce, 0xf9, 0xcc, 0xe3, 0x3f, 0xc0, 0x9f, 0x35, +0x82, 0xee, 0x73, 0x74, 0xb3, 0x68, 0x0b, 0xc7, +0x53, 0xd6, 0xc5, 0x35, 0x20, 0x9c, 0x4e, 0xed, +0xee, 0xee, 0x3a, 0xdf, 0x83, 0x49, 0x67, 0x09, +0x9f, 0x85, 0xeb, 0xf8, 0xe7, 0xc1, 0x2e, 0x86, +0x71, 0x17, 0x15, 0xf0, 0xed, 0xa9, 0x9a, 0xc3, +0x68, 0x69, 0xb0, 0xd2, 0xf2, 0x7f, 0x9a, 0x83, +0x72, 0xef, 0xb1, 0xa4, 0x77, 0x08, 0x35, 0x3b, +0x00, 0x55, 0x75, 0xcc, 0x41, 0x12, 0xf7, 0x3a, +0x22, 0x6b, 0xa9, 0xd9, 0xad, 0x41, 0xd4, 0x88, +0xa0, 0xc5, 0x8d, 0x59, 0x93, 0xae, 0xce, 0xd1, +0x44, 0x4b, 0x7b, 0x95, 0x09, 0x25, 0xeb, 0xb4, +0x34, 0x18, 0x3e, 0xbc, 0x77, 0x77, 0x77, 0x4b, +0x37, 0xf5, 0x58, 0xc4, 0x3c, 0x49, 0x12, 0xdc, +0x78, 0xfe, 0x25, 0x7c, 0x1a, 0xaf, 0xe2, 0xe9, +0xb8, 0xb0, 0x89, 0x8b, 0x6f, 0x23, 0x96, 0x79, +0x3c, 0x1b, 0xbd, 0x5a, 0xbe, 0x95, 0xd6, 0x33, +0xb1, 0x2a, 0xe5, 0xf1, 0xcd, 0x57, 0xa6, 0x2f, +0xd9, 0xad, 0x1b, 0x4e, 0xea, 0xba, 0xba, 0xea, +0xfa, 0x48, 0x12, 0x97, 0x2c, 0xab, 0xa6, 0x97, +0xef, 0x2d, 0x06, 0xc9, 0x22, 0x4e, 0x3e, 0x5c, +0x08, 0xc2, 0xb0, 0xd2, 0x8f, 0x69, 0x11, 0x00, +0xc8, 0xf5, 0x7e, 0x6f, 0xd2, 0x3f, 0x95, 0x38, +0x02, 0x33, 0x3c, 0xc2, 0x70, 0x4a, 0x88, 0x8a, +0x60, 0xaa, 0xde, 0x93, 0xe5, 0x5b, 0xb8, 0x6a, +0xcc, 0x83, 0xc5, 0xfc, 0xf8, 0xca, 0xe3, 0xc4, +0x54, 0xc3, 0xd1, 0x87, 0x83, 0xaf, 0x2f, 0x9a, +0xce, 0xef, 0xa6, 0x73, 0x43, 0x94, 0x4d, 0x04, +0x3b, 0x2d, 0x02, 0x9b, 0xb9, 0x9a, 0xa5, 0x1d, +0x00, 0x18, 0x70, 0xbc, 0x8a, 0x79, 0x5d, 0x74, +0xd7, 0xf6, 0xef, 0x07, 0xd7, 0xf1, 0xee, 0xf3, +0x7f, 0x15, 0xbf, 0xbd, 0xf7, 0x01, 0x56, 0xde, +0xfd, 0x23, 0xa4, 0x17, 0x67, 0x8e, 0xe0, 0x25, +0xc9, 0xf4, 0x46, 0x2e, 0x7e, 0x8f, 0x36, 0x11, +0x71, 0xe7, 0x45, 0xed, 0x51, 0x65, 0x5b, 0xef, +0x00, 0xdb, 0xbb, 0x9b, 0xef, 0xd1, 0x24, 0xd5, +0xbb, 0x6e, 0x21, 0xc9, 0xd5, 0xb3, 0xdf, 0x02, +0xfe, 0x8b, 0xb1, 0xd4, 0x3d, 0x76, 0xa6, 0x39, +0x18, 0x5d, 0x5e, 0x22, 0x8e, 0xc2, 0xca, 0xfe, +0x6a, 0xed, 0xfd, 0x4d, 0x84, 0x3a, 0x29, 0x71, +0x6b, 0x7d, 0x23, 0xf7, 0xdc, 0x38, 0x0a, 0xa7, +0x4c, 0xcd, 0x6c, 0xcf, 0xed, 0xf5, 0x7a, 0xd8, +0xdd, 0xdd, 0x45, 0x6b, 0xf7, 0x00, 0x3f, 0x4f, +0xf6, 0x70, 0x9c, 0x05, 0xf8, 0x79, 0xb4, 0x3d, +0xd5, 0x8c, 0xca, 0xb5, 0xc0, 0xe7, 0x90, 0xb5, +0xfe, 0xe5, 0xde, 0x23, 0x09, 0x3f, 0xcd, 0x97, +0xba, 0xbd, 0x92, 0xd2, 0x29, 0x10, 0xde, 0xfc, +0xf6, 0x0f, 0xdf, 0x5c, 0x3d, 0x7f, 0x5c, 0x72, +0x3c, 0xb3, 0x40, 0xf3, 0xc0, 0xb6, 0x9c, 0xc5, +0xb4, 0xbc, 0xd2, 0xf1, 0x8b, 0x77, 0xa8, 0xf4, +0x8a, 0x97, 0x91, 0x82, 0xa4, 0xa7, 0x3b, 0x77, +0x9c, 0xe0, 0x03, 0x25, 0xa3, 0x35, 0xc9, 0xb3, +0x8d, 0x1a, 0x13, 0x22, 0x3d, 0xe4, 0xf9, 0xa0, +0x6b, 0x5e, 0xa9, 0x72, 0x32, 0x49, 0x0f, 0x57, +0xc9, 0xdd, 0x49, 0x87, 0x3e, 0x3a, 0x31, 0x70, +0x78, 0x78, 0xa8, 0x06, 0x56, 0xe0, 0x7d, 0x92, +0x24, 0x09, 0xb0, 0xf3, 0x1c, 0xfe, 0x79, 0x72, +0x80, 0xe3, 0xb4, 0x98, 0x3b, 0x42, 0xd0, 0x20, +0xcb, 0x20, 0x25, 0x40, 0xc9, 0x29, 0x02, 0xc0, +0x3c, 0x0f, 0x01, 0x4f, 0x5f, 0x70, 0xfb, 0x64, +0x56, 0x2e, 0x9f, 0x1c, 0x32, 0x24, 0xc8, 0x09, +0xd6, 0xa4, 0xfc, 0x22, 0x2f, 0xff, 0xae, 0x2b, +0x9f, 0xbe, 0xa9, 0xdc, 0xa9, 0x52, 0x3e, 0x4f, +0x27, 0xcb, 0xd7, 0x02, 0xb9, 0x48, 0xa7, 0x12, +0x0d, 0x0f, 0xd9, 0x1f, 0x92, 0x60, 0x50, 0x19, +0xbc, 0xec, 0x28, 0x9e, 0xe7, 0x33, 0x89, 0x63, +0xa6, 0xff, 0xf6, 0xf5, 0x8f, 0x6c, 0x43, 0x10, +0x35, 0xeb, 0x1f, 0x4a, 0xc7, 0xf1, 0xa4, 0x67, +0xfa, 0x26, 0xc7, 0x5e, 0x6b, 0x23, 0x1f, 0x3f, +0x5e, 0x87, 0xd6, 0xb7, 0xf4, 0x2c, 0xfb, 0x5f, +0xcb, 0x2f, 0xdb, 0x2a, 0xe7, 0x5f, 0x14, 0x7f, +0x39, 0xf3, 0x9b, 0xf7, 0x43, 0x93, 0xf2, 0x79, +0xbb, 0x65, 0x5e, 0xde, 0x4e, 0x39, 0x3f, 0xac, +0xf9, 0xc2, 0xf3, 0x04, 0x11, 0x06, 0x05, 0xf0, +0xf1, 0xf2, 0x0d, 0x24, 0xd7, 0xb6, 0x71, 0x67, +0x2d, 0xc1, 0xe6, 0xea, 0x0a, 0x5a, 0x41, 0x80, +0xa4, 0x1d, 0xa3, 0x77, 0x6d, 0x13, 0xe1, 0xf3, +0xaf, 0x00, 0x4b, 0xab, 0x58, 0x47, 0x8a, 0xc9, +0x68, 0x84, 0x3c, 0x08, 0x51, 0x64, 0x99, 0x8b, +0x0e, 0x49, 0xfb, 0xca, 0x60, 0x38, 0x72, 0xef, +0xd2, 0x34, 0x75, 0xa1, 0xa0, 0xa3, 0x28, 0x42, +0x81, 0x56, 0x25, 0xe0, 0x09, 0x11, 0x55, 0xb9, +0xa7, 0xd1, 0xfe, 0x43, 0x81, 0x55, 0x28, 0x6d, +0x91, 0xe7, 0x2e, 0x3a, 0x25, 0x2f, 0x83, 0xf2, +0x58, 0xce, 0x6f, 0xbc, 0x5c, 0x2d, 0xa8, 0xcc, +0x24, 0xcd, 0x10, 0x14, 0xb9, 0xc3, 0x8f, 0x70, +0x95, 0xe5, 0x71, 0xa7, 0x3f, 0x2d, 0xc8, 0x17, +0x80, 0x92, 0xcf, 0x13, 0xbd, 0x5f, 0x5e, 0x5a, +0xc2, 0x78, 0x3c, 0x71, 0xa7, 0x8d, 0x38, 0xad, +0xe2, 0xfb, 0x7c, 0x18, 0x04, 0xce, 0x7b, 0x3d, +0x4e, 0xba, 0xe8, 0xc4, 0x31, 0x7a, 0xbd, 0x1e, +0x82, 0xaf, 0x7c, 0x0b, 0x7f, 0xbc, 0xf5, 0x0a, +0xfe, 0x3f, 0xe1, 0x1d, 0xbc, 0x9f, 0xb6, 0xf1, +0xa0, 0xe8, 0xcc, 0xc3, 0xb5, 0x5a, 0xeb, 0x87, +0xcf, 0x79, 0x6d, 0x6d, 0x6a, 0x27, 0x3b, 0xf8, +0xfc, 0xe7, 0xc4, 0x9b, 0xde, 0xf3, 0xfa, 0xb4, +0x79, 0xc6, 0xca, 0x8d, 0x5a, 0x41, 0x58, 0x91, +0xc4, 0x35, 0x7b, 0x88, 0x4f, 0xb5, 0x5c, 0xe7, +0x3c, 0x21, 0x1d, 0xea, 0xe4, 0xe4, 0xe2, 0x91, +0xcf, 0x2c, 0xa9, 0xdf, 0x27, 0xf9, 0x6a, 0x52, +0xb3, 0xe6, 0x48, 0xa1, 0x39, 0xbb, 0x49, 0x3c, +0xb5, 0xf2, 0xb4, 0x74, 0xd6, 0xcd, 0x6e, 0x12, +0x34, 0xfc, 0xf9, 0x59, 0x49, 0xad, 0x5f, 0x79, +0x7f, 0xac, 0x6c, 0x6e, 0xe3, 0x5f, 0x6d, 0xbd, +0x8a, 0x0f, 0x2f, 0xd9, 0xa2, 0xac, 0x53, 0xa1, +0x73, 0x29, 0x11, 0xd0, 0x1d, 0x26, 0x38, 0x04, +0xd1, 0x5c, 0x02, 0xe5, 0x65, 0xcb, 0x7c, 0x5c, +0x15, 0xa9, 0x71, 0x96, 0x56, 0x1d, 0x1a, 0xa7, +0xa9, 0xe5, 0x91, 0xe5, 0xfb, 0x54, 0x55, 0xb2, +0x7c, 0xc9, 0xdd, 0xfa, 0xd4, 0xee, 0x84, 0xb7, +0x25, 0x39, 0x5a, 0xf8, 0xf3, 0x34, 0x56, 0x5f, +0x6a, 0x12, 0x71, 0x93, 0xfe, 0x91, 0x1c, 0x79, +0x9d, 0x76, 0xa4, 0x69, 0xd9, 0x9a, 0xbd, 0x4d, +0x4a, 0xf7, 0x96, 0x96, 0x81, 0xdb, 0xf3, 0xe5, +0x38, 0xd2, 0xb3, 0x4f, 0xdd, 0xce, 0xcb, 0xf7, +0x69, 0x28, 0xa4, 0xdd, 0x90, 0x9b, 0x40, 0xb4, +0xf1, 0x97, 0x78, 0x35, 0x99, 0xdf, 0xa4, 0x01, +0x91, 0xf3, 0xc3, 0x57, 0xbe, 0x0f, 0x67, 0x69, +0x8a, 0xd1, 0xc6, 0x53, 0xcb, 0xc3, 0xd2, 0x5e, +0x8c, 0x46, 0xf8, 0xfd, 0xe8, 0x06, 0x3e, 0xbe, +0xbe, 0x8d, 0xf5, 0xbd, 0x02, 0xd7, 0xf2, 0xa9, +0x30, 0xf2, 0x5e, 0xbe, 0x8c, 0xa7, 0x45, 0x88, +0xee, 0x56, 0x81, 0x5e, 0x3e, 0xc2, 0xed, 0x47, +0xbf, 0xc0, 0xed, 0x47, 0xbf, 0x40, 0x7a, 0x71, +0xe6, 0x9c, 0xdd, 0xe8, 0xca, 0xea, 0xd5, 0x95, +0x65, 0x47, 0x1c, 0xa5, 0x16, 0x94, 0xbe, 0x01, +0x55, 0x8d, 0xa7, 0x66, 0xfe, 0xe4, 0xe5, 0x90, +0x94, 0xca, 0x25, 0x5c, 0x29, 0xb1, 0x93, 0x44, +0x4d, 0xb6, 0xe6, 0x2c, 0x9d, 0x20, 0x8c, 0xe2, +0x0a, 0x1e, 0x9a, 0xbd, 0x1d, 0x98, 0x4b, 0xc3, +0xd6, 0x99, 0x6e, 0xb9, 0x0f, 0x73, 0x9f, 0x02, +0x89, 0x4f, 0xa9, 0x9b, 0x85, 0xf6, 0xc2, 0x07, +0xd4, 0xbe, 0xa0, 0xdd, 0xc1, 0xf5, 0x6b, 0x1b, +0x58, 0xb9, 0x71, 0x1b, 0x0f, 0xb6, 0x5e, 0xc0, +0x3f, 0x89, 0x9f, 0x9b, 0x6a, 0x52, 0x5a, 0x2c, +0x71, 0x93, 0xf5, 0x23, 0x1d, 0xd7, 0xea, 0xf6, +0x6a, 0x9e, 0xc7, 0x72, 0x7c, 0xd3, 0xea, 0xe6, +0xe9, 0xc9, 0x99, 0x77, 0x34, 0x2a, 0x3b, 0x74, +0xf9, 0x9c, 0x0c, 0x34, 0xf5, 0xbb, 0x4f, 0xdd, +0x6e, 0xa9, 0x48, 0x34, 0x4f, 0x79, 0xed, 0xbb, +0x65, 0xcf, 0xae, 0xb3, 0xe9, 0xc8, 0x34, 0x4d, +0x1c, 0xe4, 0x34, 0x67, 0x0b, 0x5f, 0xb9, 0x3e, +0x42, 0xaf, 0xf5, 0x91, 0x74, 0xf0, 0xe3, 0x65, +0x73, 0xcf, 0x52, 0xfa, 0xde, 0xeb, 0xf5, 0xa6, +0xc7, 0xd1, 0x5e, 0xfe, 0x0e, 0xde, 0xc9, 0x96, +0x81, 0x20, 0xab, 0x57, 0xdb, 0x6a, 0xea, 0x5e, +0x22, 0x8a, 0x3e, 0x3b, 0xa1, 0x9c, 0x24, 0xfc, +0x59, 0xaa, 0x87, 0x24, 0x31, 0xb3, 0x54, 0x49, +0xd6, 0xc6, 0x4e, 0x60, 0xa9, 0x9f, 0xb4, 0xf7, +0xbe, 0xf2, 0x65, 0x7f, 0xc8, 0x4d, 0xbb, 0xae, +0xbd, 0x92, 0x79, 0xd1, 0x70, 0xf7, 0xe1, 0x6f, +0xb5, 0xb7, 0xce, 0x5c, 0x61, 0xd5, 0x41, 0x8b, +0x96, 0x8f, 0x5f, 0x13, 0xff, 0x85, 0x26, 0x36, +0x73, 0x6b, 0xd3, 0xf0, 0x6d, 0x38, 0x1a, 0x01, +0x6c, 0xaa, 0xaa, 0xf6, 0x99, 0x1a, 0x7c, 0xf6, +0xc5, 0xa6, 0x8c, 0x12, 0xaf, 0xc7, 0xd7, 0x7e, +0x8d, 0x39, 0xaa, 0x1b, 0x1f, 0x6b, 0x53, 0xad, +0x1b, 0xe7, 0x3a, 0xb3, 0x8a, 0x92, 0xf6, 0xb3, +0x71, 0x0b, 0x9f, 0x05, 0x31, 0x90, 0x97, 0xa5, +0xe8, 0x41, 0xd1, 0xc2, 0xa0, 0x95, 0xe0, 0xe1, +0xee, 0x37, 0xf1, 0x6f, 0xf7, 0x5e, 0xc3, 0xf6, +0xe8, 0x18, 0xc1, 0xf9, 0x31, 0xf2, 0x95, 0x0d, +0x9c, 0x23, 0xc2, 0x0a, 0x52, 0xbc, 0x7e, 0xf6, +0x01, 0xd6, 0x4e, 0x9f, 0x02, 0xc3, 0x0b, 0x8c, +0x2f, 0xce, 0x00, 0x00, 0xc3, 0xd3, 0x7e, 0xa9, +0x1c, 0xcd, 0x99, 0x18, 0x98, 0x3b, 0xcd, 0xf1, +0xfd, 0x4d, 0x5e, 0x01, 0x4a, 0x44, 0x56, 0x0a, +0x48, 0x7c, 0x3f, 0xe3, 0x8c, 0x41, 0x96, 0x4e, +0x4a, 0x6a, 0x73, 0x09, 0x1a, 0x43, 0x40, 0xe5, +0x68, 0x75, 0x58, 0x7b, 0xb1, 0x66, 0x0b, 0x97, +0xcc, 0x87, 0xc5, 0x24, 0x94, 0xca, 0x9f, 0xfd, +0xef, 0xf5, 0x7a, 0x08, 0x5f, 0x7e, 0x03, 0xff, +0x43, 0x70, 0x67, 0xea, 0xe7, 0x40, 0x81, 0xe0, +0xac, 0xf9, 0xef, 0x9b, 0x17, 0x3e, 0xc6, 0x52, +0x7e, 0x97, 0x8c, 0x76, 0x10, 0x01, 0x9d, 0x04, +0x18, 0x0d, 0xfd, 0xeb, 0x55, 0xd6, 0x0f, 0x4c, +0x1d, 0xe0, 0x34, 0x7b, 0x85, 0xec, 0x34, 0xe9, +0xc0, 0x50, 0xe7, 0x7c, 0xe1, 0xeb, 0x40, 0x4a, +0x6f, 0x11, 0x7b, 0x5f, 0x59, 0x52, 0xd2, 0xad, +0xab, 0x5b, 0xc3, 0x51, 0x63, 0x4c, 0x2c, 0x0d, +0x44, 0x13, 0xcd, 0x83, 0xcf, 0x8b, 0xdd, 0x6a, +0xaf, 0xd6, 0x87, 0x49, 0x92, 0x20, 0x68, 0x77, +0xd0, 0x0e, 0x5a, 0xd8, 0xd8, 0xbe, 0x8e, 0xcd, +0x6f, 0xfe, 0x08, 0xff, 0xfd, 0x68, 0x1b, 0x17, +0xe3, 0xd9, 0xc5, 0xf6, 0x72, 0x00, 0xf9, 0x86, +0x08, 0x54, 0x25, 0x72, 0xfe, 0x4e, 0x9b, 0x14, +0x24, 0x8d, 0xcb, 0x09, 0xab, 0x49, 0xba, 0x04, +0x3e, 0x9b, 0xaa, 0x46, 0xd8, 0x35, 0xa9, 0x16, +0x28, 0xdb, 0x8a, 0xb5, 0x7a, 0xe4, 0x3b, 0x9f, +0x3d, 0x97, 0xd7, 0xa3, 0xd8, 0xad, 0xdc, 0x51, +0x10, 0x76, 0x1c, 0x4d, 0x3a, 0x30, 0x95, 0xf2, +0x5c, 0xc1, 0x59, 0xcd, 0xbd, 0xb7, 0xfa, 0xd9, +0xc7, 0xc4, 0x58, 0x0e, 0x2e, 0x72, 0x81, 0x73, +0x10, 0x6d, 0x50, 0x71, 0x91, 0xfd, 0xdf, 0xc4, +0xb7, 0xc1, 0xd7, 0xde, 0xa6, 0x73, 0x41, 0x3a, +0x15, 0xca, 0x7e, 0x95, 0xde, 0xb8, 0xbc, 0x0c, +0x6d, 0x03, 0x64, 0x76, 0x7e, 0x09, 0xa5, 0xf6, +0x4b, 0xa6, 0x87, 0x8f, 0x87, 0xcf, 0xfe, 0xa8, +0x69, 0x1a, 0xe4, 0x33, 0xd5, 0x4f, 0x79, 0xd9, +0xc9, 0x06, 0x33, 0xaf, 0xc2, 0x88, 0x69, 0x47, +0x1a, 0xd5, 0xb9, 0xa7, 0xad, 0x3f, 0x00, 0x4f, +0x73, 0xe0, 0x69, 0x7b, 0x0b, 0xb8, 0xb6, 0x55, +0xea, 0xaf, 0x77, 0x37, 0xb7, 0x80, 0xed, 0x69, +0xfa, 0x6e, 0xab, 0x40, 0x17, 0x39, 0x9e, 0xc7, +0x19, 0x7a, 0xfd, 0x07, 0x88, 0x8e, 0x1e, 0x20, +0x3e, 0x39, 0x42, 0x06, 0x60, 0x3d, 0xcc, 0x81, +0x27, 0x8f, 0x4b, 0x92, 0x34, 0x50, 0x95, 0xc6, +0xdd, 0x34, 0xcb, 0x72, 0x00, 0x13, 0x47, 0x0c, +0xa5, 0x0d, 0x7a, 0x38, 0x1c, 0x62, 0x69, 0x6d, +0x1d, 0xed, 0xa0, 0x85, 0xa1, 0xb8, 0x4b, 0x82, +0xfe, 0x13, 0x53, 0x40, 0x79, 0xe5, 0x3d, 0xe1, +0x44, 0xf8, 0xeb, 0x9c, 0x94, 0xe9, 0x37, 0x27, +0xcc, 0xf2, 0x58, 0x19, 0x30, 0x95, 0xae, 0x63, +0xb0, 0xf8, 0x0e, 0xb3, 0xbd, 0x94, 0xbe, 0x9f, +0x5e, 0x4e, 0x8f, 0x11, 0xae, 0x2d, 0x75, 0x1d, +0x4d, 0xdb, 0xdd, 0xdd, 0xc5, 0xe7, 0x6b, 0x37, +0xf1, 0x70, 0x69, 0x13, 0xff, 0x4b, 0xbc, 0x8f, +0x8b, 0x3c, 0x9c, 0xfb, 0x39, 0x58, 0xf3, 0x5f, +0xae, 0x4d, 0x8d, 0x99, 0xd4, 0x98, 0x54, 0x4d, +0x28, 0xd1, 0xc6, 0x7b, 0x70, 0x5e, 0x4e, 0xaf, +0x95, 0x2b, 0xe7, 0x27, 0x80, 0xd6, 0x37, 0xfe, +0xeb, 0xff, 0x73, 0x71, 0xe3, 0xe1, 0x2f, 0x2a, +0x12, 0xa2, 0xd6, 0xa1, 0xd4, 0x71, 0x9a, 0xc3, +0x58, 0x9d, 0x74, 0xae, 0x49, 0xb4, 0x9a, 0x2a, +0xbd, 0xc9, 0xf9, 0x40, 0x02, 0x2d, 0x34, 0x21, +0x4f, 0x2f, 0x71, 0xf6, 0x49, 0xf7, 0x96, 0x03, +0x9a, 0xaf, 0x6c, 0xeb, 0x48, 0x86, 0xaf, 0x2c, +0x8e, 0xb3, 0xd6, 0x77, 0xbd, 0x5e, 0x0f, 0x2f, +0x7e, 0xfd, 0x55, 0x7c, 0xfc, 0xd2, 0x0f, 0xf1, +0x47, 0x93, 0x55, 0xe7, 0x0d, 0x5b, 0x3a, 0x9b, +0x68, 0x41, 0x13, 0x47, 0x34, 0xfa, 0x0d, 0xd4, +0x13, 0xee, 0x26, 0x1c, 0x26, 0xdf, 0xbc, 0x9b, +0x10, 0x8e, 0x26, 0x5c, 0xa6, 0xaf, 0x9c, 0xa6, +0xce, 0x70, 0xb3, 0xb4, 0x51, 0x2b, 0x77, 0xfd, +0xc6, 0x09, 0x80, 0xeb, 0xcf, 0x22, 0x30, 0x37, +0xd0, 0x5a, 0xfc, 0x7d, 0x79, 0xa4, 0x0a, 0xbc, +0x49, 0x3f, 0xf9, 0xea, 0xb5, 0xc6, 0xc4, 0x57, +0x56, 0x5d, 0x1f, 0xfa, 0xf0, 0x92, 0x6d, 0xd6, +0xda, 0xd6, 0xa4, 0x9f, 0xea, 0xe6, 0xa4, 0x96, +0xbf, 0x89, 0x44, 0xaf, 0xb5, 0xbf, 0xae, 0xdc, +0xba, 0x36, 0x5e, 0x75, 0x9e, 0xd5, 0x8d, 0x97, +0x98, 0x7f, 0x8d, 0xc1, 0x6a, 0xff, 0x33, 0xb4, +0xab, 0xdb, 0x2a, 0x10, 0xb4, 0x13, 0x74, 0xc6, +0x97, 0xf8, 0xde, 0xe5, 0x87, 0x58, 0xbf, 0xf7, +0xa7, 0x18, 0x1f, 0x3f, 0xc6, 0xa0, 0x15, 0xa1, +0x1b, 0x47, 0x68, 0x2f, 0xaf, 0xe2, 0xa2, 0xb3, +0x82, 0xee, 0xd9, 0x11, 0xd2, 0x8b, 0x33, 0x9c, +0x5e, 0x0e, 0x30, 0xba, 0xbc, 0x04, 0x00, 0x0c, +0x47, 0x23, 0xac, 0x2e, 0x2f, 0x21, 0x68, 0x77, +0x70, 0x79, 0x7a, 0x32, 0x23, 0xf0, 0x40, 0x1c, +0x06, 0x8e, 0x90, 0x6a, 0x52, 0x38, 0x49, 0xc8, +0x5c, 0xed, 0x3e, 0x1c, 0x0e, 0x31, 0xc9, 0x72, +0x64, 0x93, 0x71, 0x65, 0x7f, 0x94, 0x69, 0xa8, +0xfc, 0xd5, 0x95, 0xe5, 0x29, 0x1e, 0xca, 0x71, +0x5d, 0x60, 0x7e, 0x6c, 0x8c, 0x4c, 0x0e, 0x12, +0xc8, 0x5c, 0xa9, 0xed, 0xc7, 0xad, 0xb8, 0x8d, +0x70, 0xfb, 0x26, 0x7e, 0x77, 0xeb, 0x35, 0xbc, +0x5b, 0x2c, 0xbb, 0xf7, 0xa5, 0x23, 0x8a, 0x75, +0xeb, 0xf2, 0xaa, 0x7b, 0x86, 0xa5, 0x6d, 0xf3, +0xad, 0xaf, 0xba, 0x3d, 0x9b, 0x81, 0xf3, 0x66, +0xa7, 0x4e, 0xe3, 0xc4, 0x9a, 0x13, 0xf7, 0x3a, +0x5b, 0xb5, 0x26, 0x51, 0xfb, 0x08, 0xb9, 0x46, +0xb8, 0x7d, 0xe7, 0xba, 0x79, 0x3e, 0xcb, 0xb6, +0x6e, 0x11, 0xea, 0xab, 0x9c, 0x83, 0xd4, 0xd2, +0xf8, 0x8e, 0x48, 0xc8, 0xbc, 0x9a, 0xaf, 0x81, +0x05, 0x9a, 0x46, 0x24, 0x49, 0x12, 0x6c, 0xdd, +0xd8, 0xc7, 0xff, 0x17, 0xeb, 0x38, 0x0d, 0x42, +0x44, 0xb3, 0x09, 0xc6, 0x83, 0x0d, 0x98, 0x2a, +0x1d, 0x6b, 0x02, 0x68, 0x93, 0xac, 0x09, 0xd1, +0xd7, 0x54, 0xf6, 0xfc, 0xbd, 0xb4, 0x5d, 0x5a, +0xd0, 0x64, 0x31, 0x58, 0x78, 0xf8, 0x36, 0x58, +0x4d, 0x72, 0x13, 0x76, 0xe7, 0x14, 0x30, 0x83, +0x94, 0x4c, 0x9f, 0x99, 0x74, 0xa7, 0x71, 0xde, +0x75, 0x44, 0xc9, 0xc7, 0xbd, 0x13, 0x68, 0xfd, +0x54, 0xa7, 0x69, 0x90, 0x20, 0x82, 0xbf, 0xb8, +0xf6, 0x58, 0x26, 0x06, 0x0b, 0x4f, 0x39, 0xbe, +0x4d, 0xd3, 0xfa, 0xcc, 0x12, 0x96, 0x84, 0xab, +0xbd, 0x93, 0x92, 0xae, 0x66, 0x93, 0xd7, 0xfa, +0xa2, 0x49, 0xfb, 0x79, 0x3e, 0xab, 0xbf, 0xb5, +0x4d, 0xb5, 0xc9, 0xd8, 0xc8, 0x36, 0x59, 0xda, +0x13, 0x65, 0xfe, 0x11, 0x98, 0x0c, 0xb9, 0xb5, +0x51, 0x37, 0x61, 0x86, 0x7c, 0x12, 0x7d, 0x9e, +0x4e, 0xed, 0xbe, 0x39, 0x70, 0x51, 0x84, 0xf8, +0x9f, 0x96, 0x5f, 0xc6, 0xde, 0xdd, 0x5b, 0x58, +0x09, 0x32, 0x5c, 0x8e, 0x26, 0xc8, 0xe3, 0x04, +0xa3, 0x20, 0xc6, 0x00, 0x01, 0x6e, 0x86, 0x63, +0xbc, 0x31, 0xf8, 0x14, 0xbf, 0xf6, 0xf8, 0x3d, +0x7c, 0x76, 0x72, 0x81, 0xe3, 0xf6, 0x1a, 0xf6, +0x7a, 0xeb, 0xf8, 0xd9, 0xea, 0x0b, 0x00, 0x80, +0x8d, 0xa7, 0x9f, 0xe0, 0xd6, 0x87, 0x7f, 0xe8, +0x6c, 0xf6, 0x9d, 0xa5, 0x25, 0xc4, 0xcb, 0xab, +0x18, 0x1d, 0x1f, 0x95, 0x50, 0x9a, 0x64, 0x39, +0xc2, 0x99, 0x24, 0x4e, 0xd2, 0x39, 0x11, 0xf5, +0xe9, 0xb1, 0xda, 0x76, 0x89, 0x60, 0x5f, 0x9c, +0x9f, 0x21, 0x49, 0xa6, 0x4c, 0x41, 0x18, 0xc5, +0x08, 0x23, 0xbf, 0xaa, 0x5e, 0x3b, 0x92, 0x46, +0xaa, 0xf2, 0x95, 0x1b, 0xb7, 0xd1, 0x8f, 0xa7, +0x84, 0x79, 0x7b, 0xf0, 0x14, 0x9d, 0xd9, 0x76, +0xd9, 0xda, 0x3d, 0xc0, 0x27, 0xe1, 0x2a, 0x8e, +0xb2, 0x10, 0xd7, 0x97, 0xda, 0xf8, 0x68, 0x12, +0xe3, 0xbc, 0x15, 0xe3, 0x61, 0xd6, 0xc6, 0xd3, +0xd6, 0x12, 0x90, 0x0a, 0xed, 0x89, 0xa5, 0x31, +0xe3, 0xf3, 0x50, 0x8e, 0x8f, 0x8f, 0x09, 0x96, +0x65, 0x70, 0xed, 0x4e, 0x9d, 0x16, 0xb4, 0x89, +0x96, 0x8f, 0xe6, 0x17, 0x60, 0x4b, 0xb2, 0x4d, +0x88, 0x20, 0xbd, 0x23, 0x9b, 0x3b, 0xb7, 0x83, +0x58, 0xaa, 0x78, 0xa9, 0x01, 0xa8, 0xb3, 0x87, +0x37, 0xd5, 0x06, 0x58, 0x2a, 0xed, 0x26, 0x36, +0x70, 0x2b, 0x2d, 0x4f, 0x2f, 0x1d, 0xec, 0x7c, +0x76, 0x73, 0xed, 0xdc, 0xb9, 0x75, 0x9c, 0x8d, +0x3f, 0xef, 0xee, 0xee, 0x62, 0x7c, 0x71, 0x8e, +0xf5, 0xb5, 0x02, 0x9f, 0x67, 0xd5, 0x28, 0x63, +0x00, 0xf4, 0x23, 0x56, 0x1a, 0x21, 0xaa, 0x93, +0x58, 0xe4, 0x84, 0xb2, 0x36, 0x67, 0xcb, 0x9e, +0x4a, 0xdf, 0x78, 0x7e, 0x79, 0x5e, 0x97, 0xa7, +0xd1, 0xea, 0xe6, 0xbf, 0xad, 0xb3, 0xf2, 0x72, +0xb3, 0xa3, 0xdf, 0x3e, 0x22, 0x2a, 0x26, 0x3a, +0xdf, 0x40, 0x4b, 0x84, 0x5d, 0x96, 0xe7, 0x73, +0x90, 0xd2, 0xda, 0x2b, 0x89, 0x3e, 0x81, 0x75, +0x3c, 0xcc, 0xc2, 0xd1, 0xa3, 0x3e, 0xd3, 0xfa, +0x5e, 0x95, 0x20, 0x7c, 0xaa, 0x7b, 0xad, 0x0e, +0xeb, 0x9b, 0xcc, 0x57, 0x97, 0xff, 0x2a, 0xe6, +0x92, 0xba, 0xfe, 0xb4, 0xf2, 0xf9, 0xda, 0x6f, +0xcd, 0x0d, 0xcb, 0xac, 0x23, 0xcb, 0xbc, 0x0a, +0xfe, 0x12, 0x6a, 0x98, 0x1e, 0x6e, 0xd2, 0x21, +0xbc, 0x2b, 0xeb, 0xd9, 0x5a, 0x1f, 0xbe, 0xbe, +0x97, 0x73, 0xd4, 0x67, 0x02, 0x61, 0xed, 0x7c, +0xd8, 0x4a, 0xa6, 0xf6, 0xe0, 0xf6, 0xec, 0xdb, +0xcc, 0x36, 0xfc, 0x7e, 0xda, 0xc1, 0xfb, 0x9d, +0xbb, 0xb8, 0x76, 0xf3, 0x0e, 0xba, 0xb7, 0x32, +0x3c, 0xc8, 0xda, 0x28, 0xc1, 0xee, 0x16, 0xbe, +0x7a, 0xed, 0x39, 0x04, 0xe7, 0xc7, 0xe8, 0xf5, +0xd6, 0xf1, 0x5e, 0x6b, 0x0d, 0x37, 0x83, 0x21, +0x5e, 0xfa, 0xc5, 0xff, 0x8c, 0xcf, 0x3f, 0x7a, +0xcf, 0xed, 0x6f, 0x61, 0xdc, 0xc6, 0xf6, 0x8d, +0x9b, 0xe8, 0x7f, 0x7e, 0x88, 0xb3, 0x8b, 0xa9, +0x84, 0x1f, 0x87, 0x41, 0x45, 0xca, 0x26, 0xe9, +0xba, 0xb3, 0xb4, 0x84, 0xb5, 0xa5, 0x2e, 0x06, +0xad, 0x08, 0xbd, 0x38, 0x02, 0xc6, 0x43, 0x9c, +0x5e, 0x0e, 0x9c, 0xa4, 0xbd, 0xbb, 0xbb, 0x8b, +0x68, 0x79, 0x15, 0x1f, 0x26, 0x3b, 0xb8, 0x16, +0x4d, 0xfb, 0xeb, 0x49, 0xb4, 0x82, 0xcd, 0xf4, +0x1c, 0xbd, 0x70, 0x8a, 0x7c, 0xab, 0xdd, 0xc1, +0xfd, 0xf6, 0x35, 0xfc, 0x4e, 0x67, 0x0f, 0xfd, +0x56, 0x07, 0x9d, 0x2c, 0xc5, 0x26, 0x86, 0x68, +0x87, 0x01, 0x46, 0x08, 0xf0, 0x34, 0x8b, 0x70, +0x1a, 0xc4, 0x48, 0x8b, 0x1c, 0x98, 0x6d, 0xc1, +0x51, 0x18, 0x4c, 0x9f, 0x7d, 0x47, 0x0d, 0x65, +0x5f, 0x6a, 0xe6, 0x1b, 0x39, 0x47, 0x7c, 0xcc, +0x7f, 0x93, 0xf5, 0xdf, 0xf4, 0x1d, 0x07, 0xba, +0xeb, 0x60, 0x65, 0x69, 0x49, 0x25, 0x96, 0xda, +0x01, 0x7d, 0x8d, 0x18, 0x49, 0x82, 0xca, 0xed, +0x1a, 0x75, 0x67, 0xb6, 0xe9, 0x37, 0x8f, 0x68, +0x24, 0xa5, 0x54, 0xa9, 0x96, 0xb6, 0x08, 0xb1, +0x6c, 0xc3, 0x55, 0xcf, 0x5a, 0x5a, 0x92, 0xba, +0x15, 0x68, 0xc1, 0x72, 0xd6, 0x6b, 0xd2, 0x66, +0x2d, 0x1d, 0x7f, 0x97, 0x5f, 0x9e, 0xe1, 0x76, +0x76, 0x8a, 0xf7, 0x70, 0xad, 0x36, 0x5c, 0x68, +0xad, 0x87, 0xa4, 0xef, 0x3d, 0x6d, 0x70, 0x96, +0x44, 0x20, 0xeb, 0x50, 0x36, 0x28, 0x33, 0x3a, +0x1c, 0x3d, 0x53, 0x79, 0x9a, 0xba, 0x50, 0xfe, +0x96, 0xc4, 0x48, 0x53, 0x49, 0x59, 0x93, 0x5a, +0xda, 0xe0, 0x67, 0x79, 0x29, 0x9c, 0x22, 0x81, +0x54, 0xb5, 0xa7, 0x99, 0xd1, 0x56, 0x89, 0x3f, +0x7f, 0xe7, 0x23, 0x40, 0xf4, 0xed, 0x2a, 0xce, +0x60, 0xda, 0x46, 0x5c, 0x27, 0x95, 0xc9, 0xfa, +0xac, 0xff, 0x56, 0x1a, 0xad, 0x2f, 0xeb, 0xd4, +0xba, 0x72, 0x3c, 0x2c, 0x46, 0xcb, 0x6a, 0x57, +0x93, 0x36, 0x10, 0xd4, 0x99, 0x78, 0xe4, 0x7c, +0xd0, 0x9e, 0x79, 0xfb, 0x64, 0xbc, 0x00, 0xad, +0x3d, 0x75, 0x0c, 0x95, 0xaf, 0x5e, 0xe3, 0xbb, +0x8c, 0x4a, 0xc7, 0xd7, 0xce, 0x94, 0xa0, 0x04, +0xf6, 0x06, 0xaf, 0x69, 0x3a, 0x64, 0xdf, 0xd6, +0x31, 0xf1, 0x75, 0x63, 0x20, 0xbe, 0x3f, 0x2d, +0x42, 0x20, 0x58, 0x2a, 0x45, 0x2c, 0x23, 0xf8, +0xa0, 0x7b, 0x1d, 0x69, 0x7b, 0xcb, 0xb5, 0xe1, +0x61, 0x91, 0xe0, 0xe1, 0x2b, 0x7f, 0x0b, 0xcf, +0x7d, 0xb5, 0x8f, 0xf4, 0xf4, 0x18, 0x1b, 0xad, +0x14, 0x6f, 0x77, 0x6f, 0xe2, 0x41, 0x77, 0x09, +0x37, 0x9e, 0x7c, 0x84, 0xd1, 0xe5, 0x05, 0xd6, +0xf2, 0x11, 0xba, 0x71, 0x84, 0xa7, 0xdb, 0xb7, +0xf1, 0x34, 0x0d, 0x70, 0x2d, 0xca, 0xd1, 0xef, +0x9f, 0x20, 0x5f, 0xd9, 0x40, 0xde, 0xe9, 0xe2, +0x3c, 0x0f, 0x11, 0x44, 0x01, 0x96, 0xf2, 0x09, +0xce, 0xf3, 0x29, 0xed, 0x38, 0x28, 0xa6, 0x17, +0x7f, 0x3d, 0x4d, 0x03, 0xfc, 0xdb, 0x4e, 0x17, +0x9f, 0xb5, 0xaf, 0xe1, 0x62, 0x34, 0xc2, 0x72, +0xa7, 0x33, 0x8f, 0x80, 0x39, 0xc3, 0x7d, 0x39, +0xc8, 0x30, 0x2a, 0x5a, 0xb3, 0xd0, 0xce, 0x00, +0x50, 0x60, 0x14, 0xc6, 0x78, 0x9a, 0x85, 0x88, +0x0a, 0x32, 0xa5, 0xe5, 0x90, 0x3d, 0x68, 0x9a, +0x3d, 0xe4, 0x1c, 0x04, 0x6c, 0xcd, 0xa7, 0x4f, +0x2b, 0x74, 0xd5, 0x6f, 0x57, 0x01, 0x39, 0xce, +0xa4, 0xad, 0x02, 0x74, 0xc9, 0x58, 0x12, 0x1b, +0xee, 0xed, 0xce, 0xa1, 0xce, 0xe6, 0x5d, 0x17, +0xac, 0x05, 0xb0, 0xed, 0xcc, 0x75, 0x47, 0xc4, +0x78, 0x5e, 0x2b, 0x00, 0x8d, 0x26, 0x95, 0x37, +0x39, 0x96, 0x26, 0xf1, 0xb2, 0x54, 0xff, 0x1a, +0x13, 0x20, 0x99, 0x20, 0x79, 0x14, 0x4d, 0x6b, +0x23, 0x5d, 0x71, 0x9a, 0x24, 0x09, 0xd6, 0xd7, +0xd7, 0xf1, 0xdc, 0xe8, 0x08, 0x88, 0xae, 0x99, +0x9b, 0x01, 0x1f, 0x44, 0x53, 0x9d, 0x23, 0x55, +0x83, 0x72, 0xc3, 0xd0, 0x24, 0x47, 0x59, 0x86, +0x42, 0x48, 0x5d, 0x6c, 0x6b, 0x2e, 0x59, 0x70, +0xb8, 0xca, 0x06, 0x6f, 0x11, 0x4a, 0xfa, 0xa6, +0xb5, 0x51, 0x5b, 0x0c, 0xc6, 0x11, 0x3d, 0x4a, +0x49, 0xfd, 0xa6, 0x86, 0xfc, 0xe4, 0xea, 0x2f, +0x1f, 0x2e, 0xb2, 0x8f, 0xf9, 0x37, 0xcd, 0x8b, +0x5e, 0xc3, 0xb9, 0x4e, 0x12, 0xd5, 0xc6, 0x4b, +0x38, 0x52, 0x55, 0xe6, 0xc1, 0x55, 0x24, 0x6a, +0x99, 0x46, 0xdb, 0x9c, 0x7c, 0x5a, 0x15, 0x29, +0xcd, 0xd6, 0x8d, 0xa5, 0x56, 0x86, 0xf6, 0xce, +0xaa, 0xa7, 0x49, 0xfb, 0x7d, 0x4c, 0x48, 0x9d, +0x2d, 0xdc, 0xa7, 0x3d, 0xd1, 0x70, 0xe5, 0x04, +0x5e, 0x8e, 0xa3, 0xe7, 0xe4, 0x41, 0x65, 0xcd, +0xd0, 0xef, 0xc0, 0x50, 0xed, 0x5a, 0x63, 0xe7, +0x93, 0xdc, 0x34, 0x66, 0xc8, 0x2a, 0xe7, 0xaa, +0x11, 0x23, 0x8d, 0x36, 0x3c, 0xc8, 0xda, 0x78, +0x10, 0x5c, 0x07, 0x7a, 0xd7, 0xe7, 0x09, 0x33, +0xe0, 0xc1, 0xb5, 0xaf, 0x03, 0x3d, 0x31, 0xe7, +0x92, 0x59, 0x1d, 0x5b, 0x37, 0xe6, 0x6d, 0x6c, +0x61, 0x46, 0x84, 0xdb, 0xee, 0x18, 0xd8, 0xc3, +0x70, 0x65, 0xfa, 0xad, 0x8d, 0xa9, 0xe6, 0x60, +0x46, 0xc0, 0x4b, 0x84, 0x7c, 0x96, 0xff, 0x22, +0x07, 0xe6, 0xae, 0xe7, 0x73, 0x3c, 0x2b, 0x4c, +0x93, 0xd0, 0xcc, 0xc9, 0x76, 0xa8, 0xcc, 0xa3, +0xcf, 0x9f, 0xa4, 0xe9, 0xf8, 0xc8, 0xf4, 0x1a, +0x03, 0x26, 0x7f, 0x6b, 0xef, 0xa8, 0xbc, 0x4e, +0x52, 0x76, 0x90, 0x63, 0x65, 0x3b, 0x17, 0x4b, +0x22, 0x32, 0x87, 0x87, 0x87, 0x15, 0x75, 0xb8, +0x2f, 0xaa, 0x8f, 0xf6, 0x9e, 0x7f, 0xd7, 0x88, +0x98, 0x76, 0xac, 0xc0, 0x2a, 0x53, 0x23, 0xfa, +0x3e, 0x35, 0x39, 0x41, 0x9d, 0x84, 0x3e, 0x62, +0x13, 0xc3, 0x27, 0xc5, 0x5f, 0x85, 0x11, 0xd0, +0xf0, 0xd1, 0x88, 0xbb, 0xac, 0x57, 0x86, 0xc8, +0x1d, 0x8d, 0x46, 0xd8, 0x3e, 0xff, 0x1c, 0x3b, +0xa8, 0xd6, 0xe5, 0xc2, 0x70, 0x72, 0x90, 0x1b, +0x8a, 0xf6, 0x1e, 0xd0, 0x39, 0x7c, 0x2d, 0xbd, +0x9c, 0x8c, 0x41, 0xe4, 0x7e, 0xf3, 0x4b, 0x48, +0xd4, 0xfc, 0x96, 0x8a, 0x3e, 0x88, 0xe6, 0xc7, +0xe4, 0x38, 0x3e, 0x1a, 0x4e, 0x3e, 0xad, 0x82, +0x8f, 0x2b, 0xd6, 0xda, 0xc4, 0xfb, 0x0d, 0x65, +0xaf, 0xe2, 0x28, 0x0c, 0xca, 0x38, 0xd4, 0x49, +0x47, 0x3e, 0x09, 0xda, 0x27, 0xc1, 0x69, 0xaa, +0x53, 0x6b, 0xa1, 0x6b, 0x1b, 0x01, 0xd9, 0xd8, +0x50, 0xde, 0x50, 0x55, 0xfc, 0xb5, 0x3e, 0x25, +0x09, 0xb4, 0xae, 0x3d, 0x72, 0x4c, 0x7c, 0x7d, +0xcd, 0xd3, 0xc9, 0x3a, 0x7d, 0xea, 0xf8, 0x3a, +0x1f, 0x0b, 0x6d, 0x7e, 0x30, 0xbb, 0xb6, 0x69, +0x6f, 0xb6, 0xfa, 0xd1, 0x47, 0xc8, 0x35, 0xfc, +0x39, 0x8e, 0xf2, 0x7d, 0x9e, 0xea, 0x91, 0x02, +0x09, 0x28, 0xb2, 0x17, 0x7f, 0x06, 0xa6, 0x1a, +0x22, 0xb9, 0x6e, 0xac, 0xf6, 0xfa, 0xc6, 0xc7, +0xc7, 0x08, 0xf3, 0x7a, 0xb9, 0x26, 0xc2, 0x52, +0xdf, 0xfb, 0xce, 0xc9, 0xcb, 0xf2, 0x04, 0x10, +0x81, 0xf4, 0x82, 0x25, 0x99, 0x5a, 0xed, 0xae, +0xcb, 0x2b, 0xc7, 0xa3, 0x06, 0x1f, 0xcd, 0x9c, +0xc1, 0x9f, 0xcd, 0xfb, 0x01, 0xb4, 0xf9, 0xaf, +0xf5, 0xbf, 0x1c, 0x1f, 0x6d, 0x6e, 0xcb, 0xfd, +0x54, 0x8e, 0x91, 0x95, 0xaf, 0x93, 0xd8, 0xe3, +0x32, 0x3b, 0x4a, 0xae, 0xe1, 0x18, 0x0c, 0x47, +0xd5, 0x4d, 0x88, 0x08, 0x10, 0x0f, 0xd1, 0x47, +0x67, 0x9f, 0x39, 0xe1, 0x91, 0x44, 0xf9, 0xec, +0xfc, 0x02, 0x40, 0xd5, 0xa1, 0x8b, 0xc0, 0x47, +0xd0, 0xad, 0x74, 0x96, 0x6d, 0x5d, 0xe2, 0x6b, +0xa9, 0xb7, 0xb5, 0xb4, 0x5a, 0x5e, 0xab, 0x5c, +0x4d, 0xfd, 0x6f, 0xa5, 0x93, 0x75, 0xcb, 0x3e, +0xe4, 0xf5, 0x73, 0x02, 0xbf, 0xbb, 0xbb, 0xeb, +0xd2, 0x1c, 0x1e, 0x1e, 0x02, 0x00, 0x36, 0xae, +0x6d, 0x60, 0x7f, 0x46, 0xcc, 0x2b, 0x1b, 0x81, +0x5c, 0x88, 0x7c, 0xf3, 0x69, 0x32, 0x29, 0xf9, +0x04, 0xd2, 0xd2, 0x7b, 0x16, 0x57, 0x85, 0x3b, +0xd7, 0x3c, 0x8b, 0xe5, 0x84, 0xa7, 0x32, 0x64, +0x5d, 0x9a, 0xb6, 0xa0, 0x8e, 0xe0, 0x69, 0x78, +0xca, 0x8d, 0x47, 0x1c, 0x07, 0x92, 0xc7, 0x82, +0x4a, 0xbf, 0x25, 0x91, 0xd1, 0x08, 0x91, 0x26, +0x81, 0xc9, 0x36, 0x6b, 0x78, 0xfa, 0xd4, 0xa4, +0xa1, 0x38, 0xff, 0x1a, 0x77, 0xfc, 0x92, 0xea, +0xec, 0xb9, 0xd2, 0x26, 0x2b, 0xad, 0x2c, 0xb3, +0x6e, 0x9c, 0x38, 0xb1, 0x97, 0xfd, 0x21, 0xc7, +0xa3, 0xce, 0xaf, 0x40, 0x6b, 0x67, 0x9d, 0x6d, +0x5b, 0xf6, 0x9d, 0xec, 0xcf, 0x19, 0x54, 0x98, +0x31, 0xab, 0x1d, 0x72, 0xfc, 0xea, 0x36, 0x62, +0x0d, 0x7c, 0xd2, 0x3e, 0xff, 0xae, 0x11, 0x70, +0x0e, 0xec, 0x12, 0x18, 0x95, 0x19, 0x93, 0xe3, +0x66, 0xad, 0x23, 0x6d, 0x0d, 0x50, 0xde, 0xba, +0xb8, 0x08, 0x92, 0x99, 0xf3, 0xcd, 0x05, 0xab, +0x1d, 0xb3, 0x32, 0x54, 0x62, 0xd8, 0x14, 0x7c, +0x7e, 0x1b, 0xda, 0x98, 0x59, 0x63, 0xc2, 0xbe, +0x49, 0x7c, 0x38, 0x71, 0xd7, 0xa4, 0xf3, 0x5a, +0x81, 0xc4, 0x9a, 0xff, 0xda, 0xf8, 0x68, 0xeb, +0x56, 0xe2, 0x4f, 0xff, 0xf9, 0x51, 0x60, 0x8b, +0xb1, 0x0d, 0xa2, 0x39, 0xc1, 0x96, 0xed, 0xb5, +0xf6, 0x93, 0x19, 0xfe, 0x01, 0x50, 0xbd, 0x1a, +0x8f, 0xde, 0x49, 0xf5, 0x39, 0xbf, 0xa5, 0x8c, +0xff, 0x71, 0x7b, 0x79, 0xd3, 0xf3, 0xe6, 0x04, +0x4d, 0xce, 0x8a, 0xf3, 0x3a, 0x39, 0x3e, 0xcf, +0x72, 0xce, 0xbd, 0x09, 0x1e, 0xbe, 0xe3, 0x71, +0x75, 0xcc, 0x04, 0x67, 0x00, 0x2c, 0x0d, 0x02, +0xef, 0x57, 0x52, 0xad, 0xf3, 0xbe, 0x3c, 0xb9, +0x1c, 0x62, 0x30, 0x18, 0xe0, 0x4e, 0x3c, 0xbb, +0x3e, 0x2f, 0xf3, 0x1c, 0x6f, 0x21, 0x15, 0x2f, +0xfd, 0x9e, 0x41, 0xd4, 0x9a, 0x12, 0xaa, 0x12, +0xc7, 0x2a, 0x88, 0x8e, 0x29, 0x25, 0x28, 0x9b, +0x1c, 0x1d, 0xb1, 0xa9, 0x80, 0x4f, 0xd2, 0xf2, +0x11, 0x76, 0x29, 0x55, 0x34, 0xad, 0x53, 0x10, +0x91, 0x28, 0x0c, 0x2a, 0xc4, 0x9b, 0x7e, 0xbb, +0x85, 0x3c, 0xbc, 0x30, 0x25, 0x23, 0xf7, 0xbe, +0xa5, 0xa8, 0xac, 0x8d, 0xcd, 0x9e, 0xec, 0xf0, +0x8e, 0x98, 0x50, 0x1b, 0x78, 0x9a, 0x56, 0x5e, +0x4a, 0x53, 0x4a, 0x0b, 0x94, 0x36, 0x4b, 0xd7, +0x06, 0xdf, 0x78, 0xcd, 0x9e, 0xf9, 0x5c, 0x50, +0x6f, 0x5f, 0x92, 0x3e, 0x08, 0x75, 0x12, 0x12, +0x3d, 0x4f, 0x46, 0xe5, 0x3e, 0xd2, 0x70, 0xf6, +0x11, 0x3f, 0x4b, 0xea, 0x62, 0x6a, 0x79, 0xce, +0x80, 0x94, 0xc6, 0xaa, 0x25, 0x54, 0xa0, 0x1e, +0x15, 0xbe, 0x79, 0x33, 0x1a, 0x6b, 0x47, 0xa5, +0x4f, 0x7c, 0x84, 0xb2, 0x0e, 0xff, 0x3a, 0x73, +0x82, 0x36, 0x96, 0x02, 0xb4, 0xb9, 0x97, 0x4c, +0x06, 0xae, 0xed, 0xf4, 0x9b, 0x97, 0x2f, 0xc7, +0x42, 0xf6, 0x9f, 0x25, 0x95, 0xf3, 0xfe, 0x2b, +0xf5, 0xa5, 0x71, 0x56, 0xdf, 0xdb, 0x0f, 0x32, +0xad, 0x2f, 0xba, 0xa3, 0x06, 0x34, 0x1f, 0x1b, +0x08, 0x09, 0x0e, 0xf8, 0x5e, 0x66, 0xe0, 0x16, +0x85, 0x81, 0xbd, 0x1f, 0x61, 0xbe, 0x36, 0xd2, +0x4c, 0xe9, 0x5b, 0x28, 0x0c, 0xd5, 0x64, 0x84, +0x64, 0x32, 0xd0, 0xd7, 0x1e, 0xef, 0x4b, 0xea, +0x0b, 0x5e, 0xb7, 0xb1, 0xc6, 0x4a, 0xfb, 0xaf, +0xb5, 0x6e, 0xac, 0xfd, 0x56, 0x93, 0xf6, 0xad, +0x39, 0xc9, 0x04, 0xb8, 0x20, 0xe9, 0x94, 0xaf, +0xc9, 0xe3, 0xff, 0x01, 0xfd, 0xaa, 0x4e, 0x49, +0xd8, 0x38, 0x31, 0x9a, 0xa4, 0x99, 0xa9, 0x5e, +0xe7, 0xd2, 0xa8, 0xcf, 0x79, 0x8d, 0xe7, 0x23, +0x62, 0xc7, 0x99, 0x09, 0x9e, 0xc7, 0x3a, 0xfe, +0xe5, 0xc3, 0x9b, 0x80, 0x54, 0xed, 0x5a, 0xd4, +0xa1, 0xab, 0x80, 0xc6, 0x90, 0x9c, 0x9c, 0x9c, +0x78, 0x55, 0xf4, 0x92, 0x80, 0xf3, 0x3a, 0x8f, +0x3f, 0x3f, 0xc4, 0x70, 0x30, 0x44, 0x2f, 0x60, +0xf1, 0xaf, 0x7d, 0xa0, 0x2c, 0x32, 0x2f, 0x03, +0x20, 0xd2, 0x00, 0xd0, 0x17, 0x16, 0xab, 0xd7, +0xe4, 0x6a, 0xad, 0x09, 0x27, 0x41, 0x93, 0x08, +0x14, 0xfc, 0xad, 0xfb, 0xc2, 0xd5, 0xba, 0x61, +0x6f, 0xee, 0xbc, 0xfd, 0xfc, 0x86, 0x23, 0x4d, +0xe5, 0x26, 0xf3, 0x36, 0xad, 0xd3, 0xbc, 0x4a, +0x54, 0x49, 0xa3, 0x8d, 0x83, 0x66, 0xbb, 0x33, +0xcd, 0x01, 0xa8, 0x51, 0x6f, 0x5a, 0x44, 0x4a, +0xf6, 0xb7, 0x22, 0xf1, 0x68, 0x2a, 0x4a, 0x0d, +0x17, 0x5e, 0xbf, 0x2a, 0xd5, 0xd4, 0xf4, 0x5d, +0xdd, 0x58, 0x59, 0x75, 0x6a, 0x65, 0xab, 0xea, +0xf6, 0x26, 0x26, 0x1b, 0x4d, 0x22, 0x32, 0xda, +0x60, 0xd5, 0x7d, 0x15, 0xbc, 0xcc, 0xb9, 0x9a, +0x2c, 0xcf, 0xfb, 0x39, 0x59, 0xae, 0xf4, 0xaf, +0x69, 0x63, 0x57, 0x70, 0xa9, 0x78, 0x64, 0xb3, +0xdf, 0x12, 0x4f, 0x6f, 0x1f, 0x4a, 0xf0, 0xac, +0x7f, 0xf7, 0xdb, 0xa7, 0x7d, 0x9a, 0x7d, 0x4b, +0x46, 0x67, 0xf5, 0xf3, 0x53, 0x69, 0x8b, 0xd5, +0xf7, 0x9c, 0x91, 0xad, 0x1b, 0x23, 0xea, 0x67, +0xde, 0x17, 0x6a, 0x00, 0x1f, 0x36, 0x1e, 0x3c, +0x4d, 0xdd, 0xdc, 0xd5, 0xfa, 0x4a, 0x1b, 0xbf, +0xba, 0x3d, 0xc5, 0x04, 0x1f, 0x03, 0xd0, 0x5d, +0x29, 0xf5, 0x7f, 0x10, 0x3c, 0x3d, 0xac, 0xe4, +0x97, 0x04, 0xad, 0x49, 0x14, 0x34, 0xd7, 0x26, +0x25, 0xde, 0xaf, 0x64, 0x12, 0x64, 0xd8, 0xd8, +0x3a, 0x75, 0xbb, 0xa6, 0xea, 0xd6, 0x8e, 0x9f, +0x69, 0xed, 0xd0, 0x80, 0xde, 0x77, 0x3a, 0x9d, +0x8a, 0xb7, 0x7e, 0x13, 0x09, 0xdf, 0x62, 0x6a, +0xf8, 0xb7, 0x0e, 0x63, 0x92, 0x86, 0xc3, 0x61, +0xc9, 0x46, 0xef, 0x8b, 0x5e, 0x47, 0x7e, 0x0a, +0x9d, 0x00, 0x58, 0x5d, 0xef, 0x3d, 0x13, 0x47, +0xdc, 0x68, 0x92, 0x98, 0x03, 0xa8, 0xab, 0x0c, +0x7d, 0x9b, 0x4c, 0x63, 0xf0, 0x11, 0x74, 0x03, +0x2c, 0x02, 0xed, 0x6b, 0xb7, 0x46, 0x74, 0xb8, +0xba, 0xcd, 0xca, 0xab, 0xa9, 0xe3, 0x9e, 0xa5, +0x9d, 0x4d, 0xfb, 0xdf, 0xb7, 0xd0, 0xad, 0x76, +0x3f, 0xb3, 0x7a, 0xd3, 0xd2, 0x32, 0x08, 0x0d, +0x46, 0x1d, 0xbe, 0x5e, 0x33, 0x4b, 0xdc, 0xf1, +0x8e, 0x57, 0x5d, 0xdf, 0x6b, 0xed, 0xf7, 0x6d, +0xa2, 0xa6, 0x66, 0xa9, 0xc1, 0xbc, 0x2a, 0x41, +0x0d, 0x23, 0xa6, 0xd5, 0xd9, 0x88, 0xc8, 0x52, +0x9e, 0x59, 0xbf, 0x5a, 0xb6, 0x5d, 0xad, 0x7f, +0x7d, 0x7d, 0xe5, 0x9b, 0x03, 0x9a, 0x76, 0x8a, +0xff, 0xf6, 0xfa, 0x1c, 0x00, 0xea, 0xfa, 0xd7, +0x98, 0x0c, 0xf7, 0x3b, 0x88, 0xa6, 0xd2, 0xaf, +0xc7, 0x54, 0x31, 0x8c, 0xbb, 0x55, 0x26, 0x4a, +0x32, 0x5f, 0x1e, 0xa6, 0xb0, 0x4e, 0x20, 0xb1, +0xce, 0xef, 0x9b, 0x0e, 0xaf, 0xa2, 0x0e, 0xad, +0xdf, 0xad, 0x20, 0x53, 0x1a, 0x7e, 0xbc, 0xaf, +0xb4, 0x31, 0x50, 0xfb, 0xcd, 0x6a, 0x57, 0x93, +0x39, 0x4c, 0xdf, 0xc8, 0x11, 0x6e, 0x96, 0x2f, +0xb8, 0x5c, 0xde, 0x50, 0x55, 0xea, 0x1c, 0xb4, +0x80, 0x28, 0x9a, 0x2d, 0x9b, 0xdb, 0xcc, 0x7d, +0x0e, 0x5f, 0xb2, 0x2c, 0xed, 0x99, 0x13, 0xfc, +0xba, 0x28, 0x6b, 0xd6, 0x99, 0x72, 0x9f, 0x07, +0x39, 0x11, 0x5b, 0xcd, 0x2e, 0x6e, 0x49, 0xd4, +0x3e, 0xe7, 0x3c, 0x0d, 0x0f, 0x0d, 0xb4, 0xf7, +0xf2, 0xd2, 0x96, 0x5e, 0xaf, 0x87, 0xd3, 0xe1, +0x18, 0x2f, 0x64, 0x7d, 0x5c, 0x0f, 0xe5, 0x6d, +0x5f, 0xe5, 0x41, 0xf7, 0x71, 0x9b, 0x12, 0x1a, +0x11, 0x99, 0x9a, 0xd0, 0x99, 0x9a, 0x03, 0x59, +0x32, 0x3a, 0xab, 0x2f, 0x57, 0xeb, 0x0b, 0x9e, +0x8f, 0xd9, 0xe3, 0x78, 0xf9, 0x57, 0xe1, 0x68, +0x35, 0xa2, 0x67, 0x6d, 0x96, 0x15, 0x09, 0x70, +0xb6, 0xe1, 0x5a, 0x92, 0x8d, 0x8f, 0x6b, 0xf7, +0x39, 0xdf, 0x34, 0xe1, 0xc2, 0x7d, 0xce, 0x3a, +0x8d, 0xb9, 0xf8, 0x3a, 0x89, 0x87, 0xa9, 0x3c, +0x79, 0xbf, 0x6b, 0x1a, 0x0c, 0x4b, 0x82, 0x6b, +0xb2, 0xa1, 0xd5, 0x49, 0xe6, 0x5a, 0x3b, 0xbc, +0xe3, 0xe2, 0x91, 0xbc, 0x4c, 0xcd, 0x92, 0xcf, +0x61, 0x8f, 0xb7, 0x5f, 0x21, 0x64, 0x75, 0x12, +0x77, 0x53, 0x06, 0x8c, 0xbf, 0xa3, 0x7e, 0xf5, +0xcd, 0xcb, 0xba, 0xb2, 0x7c, 0x75, 0x70, 0xfc, +0x9b, 0x6a, 0x3c, 0xcc, 0xbe, 0x32, 0xb4, 0x7c, +0x3e, 0xc9, 0x7c, 0xd8, 0x59, 0x45, 0x23, 0x10, +0x75, 0x95, 0xd6, 0xbf, 0x20, 0x86, 0x75, 0x0c, +0xbb, 0xd5, 0x57, 0xbe, 0x3c, 0x16, 0xa3, 0xc8, +0xbf, 0x37, 0x5d, 0xff, 0x3e, 0xa6, 0xcb, 0xb7, +0x9e, 0x6b, 0xe1, 0x59, 0xb4, 0x9c, 0x94, 0x95, +0xdf, 0x9a, 0x06, 0xe8, 0x04, 0xf7, 0xec, 0xfc, +0xa2, 0xa2, 0x22, 0x6f, 0xea, 0x55, 0xde, 0x24, +0xf2, 0x9a, 0x15, 0xf4, 0xa5, 0x2e, 0x78, 0x8d, +0x46, 0xb4, 0xeb, 0x9c, 0xd5, 0xea, 0xc0, 0xb2, +0x6d, 0x5b, 0x75, 0x49, 0xbc, 0xad, 0x7a, 0x49, +0x0b, 0x20, 0xbf, 0xf3, 0x53, 0x04, 0x04, 0xbd, +0x5e, 0x0f, 0x9d, 0x56, 0x81, 0xf1, 0xd9, 0x29, +0xee, 0xcc, 0x92, 0x5a, 0x12, 0xba, 0xa5, 0x26, +0x6e, 0xa2, 0xa2, 0x9e, 0xce, 0x00, 0xc3, 0xa6, +0x65, 0xa8, 0x2d, 0x2b, 0x13, 0x95, 0x38, 0x6f, +0x9e, 0x47, 0xda, 0xca, 0x8c, 0xfa, 0x4a, 0x9b, +0x80, 0xb4, 0xd9, 0xa2, 0xba, 0x89, 0xa8, 0x67, +0xdb, 0x59, 0xfb, 0x2c, 0x06, 0x46, 0x4a, 0x7e, +0x52, 0x0a, 0x8f, 0xc2, 0x00, 0xc3, 0xb8, 0x5b, +0x91, 0xde, 0xad, 0x45, 0x2b, 0x6d, 0x6e, 0x75, +0x0b, 0xbb, 0x0e, 0x47, 0x99, 0x0e, 0x00, 0xe2, +0xd9, 0x15, 0x89, 0x15, 0xfb, 0x9e, 0x18, 0x4f, +0xb3, 0x7f, 0x2d, 0xcf, 0x5a, 0xd1, 0xef, 0x9a, +0x1a, 0xd6, 0xda, 0x1c, 0xf5, 0x08, 0x7a, 0x36, +0x23, 0x29, 0x71, 0xbf, 0x8a, 0xa6, 0x23, 0x9e, +0x5d, 0x15, 0x7a, 0x65, 0x4d, 0x44, 0xd3, 0xf6, +0x33, 0x87, 0x22, 0x37, 0x1f, 0xf2, 0x89, 0x19, +0xe0, 0x85, 0x43, 0x53, 0x26, 0xa5, 0x54, 0xb6, +0x31, 0xff, 0x9a, 0x82, 0xd6, 0x0f, 0xa6, 0x47, +0xb6, 0x07, 0x8f, 0x2b, 0xf5, 0xa7, 0x38, 0xc1, +0x22, 0xdb, 0x5a, 0x39, 0x1a, 0x59, 0xb7, 0xf6, +0x79, 0x9a, 0xd9, 0x38, 0x68, 0xda, 0x34, 0x3e, +0xaf, 0xea, 0x34, 0x19, 0x5a, 0xbf, 0xca, 0x36, +0xcb, 0xf4, 0x56, 0xff, 0x5f, 0x75, 0xfd, 0xcb, +0xdf, 0x75, 0xe3, 0xa9, 0x7e, 0x97, 0xfd, 0x65, +0x39, 0x39, 0x2a, 0xe3, 0x52, 0x79, 0x3d, 0x99, +0xc5, 0xca, 0xb5, 0xce, 0x8b, 0x27, 0x49, 0x52, +0x8a, 0xe8, 0x46, 0x20, 0x23, 0x9b, 0x25, 0x49, +0xe2, 0xa2, 0xfc, 0xd4, 0x11, 0x51, 0x72, 0xb2, +0x23, 0xf0, 0x1d, 0x49, 0xb3, 0xce, 0xbf, 0x6b, +0xa6, 0x00, 0x59, 0x77, 0xd3, 0xe3, 0x69, 0x5a, +0x24, 0x36, 0x0b, 0xb4, 0x80, 0x3a, 0x56, 0x84, +0xb8, 0xd1, 0x68, 0xa4, 0xd6, 0x61, 0xb5, 0x9b, +0xfb, 0x06, 0x0c, 0x87, 0x43, 0x8c, 0x2e, 0xce, +0xd0, 0x69, 0x15, 0x8d, 0x16, 0xa1, 0x8f, 0xd8, +0xc8, 0x77, 0xd6, 0x04, 0x29, 0x71, 0xca, 0xc2, +0x83, 0x5d, 0x2e, 0x36, 0x75, 0x33, 0xaa, 0x93, +0x0e, 0x1b, 0xe0, 0x2e, 0xf1, 0x96, 0x9b, 0x90, +0x4f, 0x55, 0x26, 0xcb, 0xd2, 0x24, 0x49, 0x4d, +0x95, 0xec, 0x93, 0x18, 0xe5, 0x6f, 0x9f, 0xdd, +0x31, 0x0d, 0xe2, 0x46, 0x52, 0x68, 0x05, 0x66, +0x5a, 0x09, 0x9e, 0x7e, 0x50, 0xb4, 0x4a, 0x8b, +0xb6, 0x91, 0xa6, 0xc5, 0xe3, 0x05, 0x5e, 0x01, +0xe5, 0xa8, 0x97, 0x66, 0x5e, 0xd0, 0x36, 0xc7, +0xba, 0x4d, 0xb0, 0xce, 0xa4, 0xd1, 0xb8, 0xfd, +0x9e, 0xb6, 0xd6, 0x96, 0x5f, 0xd7, 0x7e, 0x31, +0xbf, 0xaf, 0xa4, 0xce, 0x57, 0xbe, 0xc9, 0xf1, +0x36, 0x19, 0x4e, 0x65, 0xfe, 0x69, 0x5a, 0x18, +0x8b, 0x80, 0x6a, 0xed, 0xf6, 0x31, 0x0c, 0xb5, +0xe0, 0x63, 0xba, 0x45, 0xfd, 0xde, 0xf1, 0xb5, +0x8e, 0x39, 0xd6, 0x80, 0x4f, 0xe3, 0xe1, 0x23, +0xea, 0xd6, 0xbe, 0x50, 0x6b, 0xdb, 0x36, 0x70, +0x78, 0xd6, 0xf5, 0x6f, 0x69, 0xab, 0xe4, 0x98, +0xd5, 0x4a, 0xe8, 0x57, 0xd9, 0x3b, 0x0d, 0x55, +0x7c, 0xb4, 0xb2, 0xb4, 0x84, 0xfe, 0x27, 0x7d, +0x53, 0xc5, 0x4c, 0xc7, 0xd1, 0xb8, 0xe4, 0xc8, +0xd3, 0xca, 0xb3, 0xe8, 0x96, 0xed, 0x5a, 0xaa, +0xcc, 0x7d, 0xcc, 0x83, 0x3c, 0x2e, 0xa6, 0x05, +0x69, 0xb1, 0x02, 0xc5, 0xf8, 0x60, 0x34, 0x1a, +0x95, 0x6c, 0xd9, 0xfc, 0xb7, 0x55, 0x4f, 0xdd, +0x6f, 0x4b, 0x9b, 0x30, 0x1a, 0xd9, 0x5c, 0xb2, +0xec, 0x17, 0x60, 0x1e, 0x94, 0x47, 0x7e, 0x8f, +0xb2, 0x09, 0x80, 0xc8, 0x2b, 0x91, 0x36, 0x71, +0x72, 0xfb, 0xab, 0xb7, 0xaf, 0x35, 0xe8, 0xa1, +0xb5, 0x46, 0xfd, 0xf8, 0xab, 0x0d, 0xbd, 0xbf, +0x68, 0x04, 0x0c, 0x58, 0xfe, 0xe2, 0x45, 0xfc, +0x4a, 0xc3, 0xbf, 0x2f, 0xed, 0xef, 0xfd, 0x45, +0x23, 0xb0, 0x80, 0x5f, 0x21, 0xf8, 0x47, 0x9f, +0x9e, 0xda, 0x47, 0xf9, 0x04, 0x03, 0x10, 0x00, +0x53, 0xa2, 0x31, 0xce, 0x8b, 0x92, 0xc4, 0x2c, +0xc3, 0xa9, 0x6a, 0xc1, 0x5b, 0x34, 0xc2, 0x4b, +0xdf, 0x29, 0x0f, 0x7f, 0xe6, 0x1e, 0xe9, 0x75, +0x9e, 0xde, 0x75, 0x2a, 0x7c, 0x9f, 0xb3, 0x9a, +0xef, 0x7c, 0xbb, 0xef, 0x9d, 0x85, 0x3f, 0x97, +0xae, 0x09, 0x34, 0x4f, 0x78, 0x2e, 0x91, 0x77, +0x3a, 0x1d, 0xf7, 0xe7, 0x73, 0x1e, 0xa4, 0xbe, +0xe7, 0x97, 0xc7, 0x10, 0xf4, 0xcf, 0x2e, 0x70, +0x10, 0xa7, 0xb6, 0xe3, 0x13, 0x53, 0x43, 0x5a, +0x36, 0xdd, 0x2f, 0xe4, 0x0c, 0xb7, 0x80, 0x05, +0x2c, 0x60, 0x01, 0x0b, 0xf8, 0x8b, 0x03, 0x7e, +0xe4, 0xb4, 0x26, 0xf0, 0x52, 0x30, 0x1c, 0x8d, +0xd0, 0xeb, 0xf5, 0xd0, 0x0e, 0x5a, 0x38, 0xbd, +0x1c, 0x94, 0xd4, 0xdb, 0x44, 0xa8, 0xb9, 0x83, +0x16, 0x50, 0xb5, 0x57, 0xfb, 0x02, 0xaf, 0x48, +0xf0, 0x11, 0x36, 0xcd, 0x56, 0xae, 0xe5, 0xb5, +0x6c, 0xe2, 0x4d, 0xe3, 0xae, 0x5f, 0x35, 0x0d, +0x77, 0x96, 0x23, 0x90, 0x52, 0x3d, 0x81, 0x4f, +0x22, 0xb7, 0x1c, 0x00, 0xf3, 0xf1, 0xa8, 0x72, +0xf6, 0x7c, 0x38, 0x1c, 0xa2, 0x48, 0xc7, 0x38, +0xc8, 0x4e, 0x70, 0xad, 0x65, 0x44, 0x9d, 0x32, +0x54, 0x33, 0x5f, 0x8a, 0xf7, 0xf3, 0x02, 0x16, +0xb0, 0x80, 0x05, 0x2c, 0xe0, 0x2f, 0x1e, 0xe4, +0x91, 0x3e, 0xcb, 0x01, 0x2e, 0xcd, 0x32, 0x47, +0x48, 0x2e, 0x4f, 0x4f, 0xbc, 0x04, 0xd2, 0xa7, +0x42, 0xe7, 0x69, 0xa5, 0x3a, 0x5d, 0x4b, 0x6b, +0xe5, 0x91, 0x2a, 0x7b, 0xab, 0x4e, 0x9f, 0xfd, +0xd9, 0x92, 0xba, 0x3b, 0x9d, 0x8e, 0x7a, 0x44, +0x4c, 0x23, 0xe4, 0x3c, 0x1d, 0xd9, 0xbe, 0xb9, +0x0d, 0xdc, 0x02, 0x8d, 0xc8, 0x6b, 0xe7, 0xf1, +0x65, 0x1b, 0x26, 0x69, 0x56, 0xe9, 0x8b, 0x8d, +0x8d, 0x0d, 0xac, 0x66, 0x43, 0xec, 0x24, 0x2d, +0x2c, 0x60, 0x01, 0x0b, 0x58, 0xc0, 0x02, 0x16, +0x60, 0x41, 0x10, 0x85, 0x61, 0x49, 0x22, 0xa6, +0xb0, 0xad, 0x04, 0x5c, 0x2a, 0xb7, 0xa4, 0x59, +0x9f, 0xa7, 0x39, 0x7d, 0x97, 0x2a, 0x79, 0x2e, +0x81, 0x6a, 0x52, 0xbf, 0xa5, 0x2a, 0xf7, 0x79, +0x8e, 0x37, 0x39, 0x1a, 0xa6, 0xe1, 0xef, 0x03, +0x49, 0xbc, 0x39, 0xb1, 0xb6, 0x08, 0xbe, 0x24, +0xe8, 0x75, 0xb8, 0x6b, 0x4c, 0xd0, 0xee, 0xee, +0x2e, 0x86, 0xc3, 0x21, 0x3e, 0x79, 0xf0, 0x19, +0xf6, 0x2e, 0x1e, 0x7d, 0xb1, 0x51, 0x5e, 0xc0, +0x02, 0x16, 0xb0, 0x80, 0x05, 0xfc, 0xa5, 0x06, +0xa7, 0x7c, 0xe7, 0x2a, 0x75, 0x72, 0x6c, 0x3b, +0x3c, 0x3c, 0xac, 0x10, 0x5c, 0xee, 0xf4, 0x66, +0x39, 0xb3, 0xd1, 0x7f, 0x1f, 0x71, 0xa5, 0x72, +0xea, 0x3c, 0xbc, 0x79, 0x59, 0xdc, 0xde, 0xee, +0x8b, 0xfa, 0xa6, 0xe1, 0x05, 0xe8, 0x2a, 0x70, +0x9f, 0x54, 0xae, 0xa5, 0x27, 0x62, 0xcd, 0xd3, +0x48, 0x7c, 0x24, 0x41, 0xf7, 0xf5, 0xdf, 0x38, +0x2f, 0x90, 0x8f, 0x47, 0xc8, 0xd2, 0x49, 0xc5, +0x7c, 0x41, 0x79, 0x76, 0x96, 0x2f, 0x90, 0x64, +0x83, 0x52, 0x24, 0xb3, 0x05, 0x2c, 0x60, 0x01, +0x0b, 0x58, 0xc0, 0x02, 0x08, 0x9c, 0x77, 0x14, +0x97, 0x86, 0x29, 0xf8, 0x4b, 0x18, 0xc5, 0x38, +0x3b, 0xbf, 0xa8, 0x9c, 0xdf, 0xae, 0xb3, 0x37, +0x5b, 0x9e, 0xf1, 0x96, 0xca, 0xde, 0x27, 0x21, +0xfb, 0x2e, 0x31, 0xd1, 0xca, 0x7a, 0xd6, 0x50, +0xac, 0x00, 0x1a, 0xa9, 0xd1, 0x29, 0x9d, 0x56, +0x06, 0x11, 0x70, 0x4b, 0x32, 0xe7, 0xbf, 0x93, +0x24, 0xc1, 0xe1, 0xe1, 0x21, 0x46, 0x97, 0x97, +0x98, 0xa4, 0x53, 0x9b, 0x38, 0xdd, 0x58, 0x27, +0xdb, 0xbb, 0x7f, 0x71, 0x88, 0xa5, 0xd5, 0x67, +0xf3, 0x34, 0x5f, 0x38, 0xc1, 0x2d, 0x60, 0x01, +0x0b, 0x58, 0xc0, 0x5f, 0x62, 0x98, 0x39, 0xc8, +0xb9, 0xd8, 0xec, 0x5c, 0xc5, 0x1e, 0x47, 0x21, +0x1e, 0x1f, 0x3d, 0x41, 0x1c, 0x85, 0xee, 0xf2, +0x14, 0xfa, 0xd3, 0xce, 0x88, 0x6b, 0xbf, 0xf9, +0xb3, 0xb4, 0xa1, 0x5b, 0x0e, 0x6e, 0x1c, 0x48, +0x0a, 0xa7, 0xa3, 0x71, 0x94, 0x5e, 0xf3, 0xae, +0xaf, 0xab, 0x9f, 0x40, 0xaa, 0xc8, 0xb9, 0x54, +0xdd, 0x84, 0x88, 0x73, 0xd0, 0x8e, 0xcd, 0x69, +0x2a, 0x76, 0x09, 0x12, 0xa7, 0x2c, 0x9d, 0x38, +0xa9, 0x9c, 0xec, 0xe6, 0xfc, 0x5e, 0x73, 0x00, +0x68, 0x87, 0x01, 0xf6, 0xd2, 0xd3, 0x67, 0x1b, +0xe8, 0x05, 0x2c, 0x60, 0x01, 0x0b, 0x58, 0xc0, +0x5f, 0x5e, 0x98, 0x39, 0xc8, 0x05, 0xc3, 0xd1, +0xa8, 0x36, 0x68, 0x0a, 0x49, 0xe7, 0xf4, 0x5d, +0xfb, 0xcf, 0xc1, 0xfa, 0xa6, 0xc5, 0x58, 0xd7, +0x88, 0xb2, 0xbc, 0x6a, 0xb5, 0xce, 0x8e, 0x2e, +0xeb, 0xf5, 0x39, 0x9a, 0x91, 0x8a, 0x9c, 0x1f, +0x1b, 0xf3, 0x9d, 0x67, 0x97, 0xb8, 0xcb, 0xba, +0xb9, 0x54, 0xde, 0x61, 0x8c, 0x91, 0x86, 0x97, +0xef, 0x77, 0x92, 0x24, 0x8e, 0xa8, 0xd3, 0x37, +0xc7, 0x1c, 0x4c, 0x46, 0xb8, 0x3d, 0x7e, 0xfa, +0xcc, 0x63, 0xbd, 0xf0, 0x68, 0x5f, 0xc0, 0x02, +0x16, 0xb0, 0x80, 0xbf, 0xdc, 0x50, 0x51, 0xb3, +0x93, 0xc3, 0x1b, 0x49, 0xe4, 0x14, 0xd9, 0x4d, +0x1e, 0x3f, 0xf3, 0xd9, 0xac, 0x89, 0x10, 0x37, +0x51, 0xa5, 0x73, 0x49, 0x94, 0xd2, 0x73, 0xdb, +0xb8, 0x75, 0x36, 0xdb, 0x57, 0xa6, 0x0f, 0xb8, +0xf4, 0x2c, 0xf1, 0xd3, 0x34, 0x06, 0x56, 0xdc, +0x7a, 0xed, 0x06, 0x36, 0xed, 0xec, 0xb9, 0x86, +0xaf, 0xd6, 0x77, 0x61, 0x14, 0x23, 0x8c, 0x62, +0xf4, 0xfb, 0x7d, 0xe7, 0xb7, 0x30, 0x1c, 0x0e, +0xd1, 0xed, 0x76, 0x31, 0x0e, 0x62, 0xec, 0x8c, +0x4f, 0xd4, 0xeb, 0xfc, 0x24, 0x78, 0xe3, 0x57, +0x2f, 0x60, 0x01, 0x0b, 0x58, 0xc0, 0x02, 0xfe, +0x52, 0x42, 0x90, 0x74, 0x3a, 0x25, 0x8f, 0x75, +0x22, 0x28, 0x44, 0x60, 0xa5, 0x54, 0x6e, 0x05, +0x88, 0x21, 0xa8, 0x3b, 0x03, 0xce, 0xcb, 0xa1, +0xdf, 0xda, 0x65, 0x27, 0x1a, 0x48, 0x0d, 0x82, +0x56, 0xcf, 0x55, 0xde, 0x11, 0x58, 0x44, 0xd8, +0x62, 0x24, 0x2c, 0x3c, 0x2d, 0xc9, 0xdc, 0xea, +0x1f, 0xce, 0x18, 0x90, 0xba, 0x9d, 0xa7, 0x21, +0xb3, 0xc2, 0xf5, 0xb5, 0x65, 0x7c, 0xb5, 0x97, +0xe0, 0xda, 0x72, 0x52, 0x6b, 0x03, 0x97, 0xc4, +0xbb, 0x09, 0x03, 0xb0, 0x80, 0x05, 0x2c, 0x60, +0x01, 0x0b, 0xf8, 0x25, 0x04, 0x19, 0x20, 0x46, +0x09, 0x18, 0x43, 0x7b, 0xbc, 0x0b, 0x1a, 0x43, +0xd2, 0x70, 0x1c, 0x85, 0xee, 0x4e, 0x72, 0xae, +0xfa, 0xb5, 0x3c, 0xd6, 0x5d, 0x81, 0xec, 0xa8, +0x99, 0xef, 0x08, 0x9b, 0xa6, 0xfa, 0xe6, 0x65, +0xc8, 0x67, 0x2b, 0x7e, 0xb9, 0x56, 0x8e, 0x46, +0xe8, 0xb5, 0x33, 0xef, 0xd2, 0x3e, 0xee, 0x93, +0xf0, 0x25, 0x03, 0xd1, 0x44, 0x1b, 0x50, 0x77, +0x93, 0x9a, 0xef, 0x56, 0x37, 0xf9, 0xbb, 0xd3, +0xe9, 0x60, 0x38, 0x29, 0x07, 0x8d, 0xb9, 0x0a, +0xc1, 0x5e, 0x78, 0xc0, 0x2f, 0x60, 0x01, 0x0b, +0x58, 0xc0, 0xaf, 0x28, 0x58, 0xf7, 0x99, 0x33, +0xa0, 0x3d, 0x3e, 0x58, 0xba, 0x38, 0x76, 0x2f, +0x89, 0x70, 0xf1, 0x0b, 0x53, 0xac, 0x90, 0xae, +0x04, 0x3e, 0x87, 0x38, 0x0b, 0x2c, 0xa2, 0xdd, +0x24, 0x6d, 0x93, 0x5b, 0xd7, 0x78, 0x5e, 0x62, +0x30, 0x28, 0xad, 0x16, 0x8f, 0x7d, 0x3c, 0x1e, +0xbb, 0x67, 0xfe, 0x5b, 0x2b, 0xdf, 0xc2, 0xb5, +0xce, 0xf1, 0x4d, 0xe2, 0xaf, 0xa9, 0xeb, 0xc3, +0x28, 0x36, 0x35, 0x14, 0x51, 0x36, 0xc2, 0xb5, +0xb6, 0x1e, 0x87, 0xdd, 0x22, 0xd8, 0x0b, 0xa9, +0x7c, 0x01, 0x0b, 0x58, 0xc0, 0x02, 0xfe, 0xfd, +0x80, 0xe0, 0x72, 0x79, 0xc3, 0xa9, 0xd5, 0x65, +0x88, 0x56, 0x60, 0x4a, 0xac, 0x89, 0xc8, 0x10, +0xd0, 0x6f, 0x79, 0x31, 0x88, 0xcf, 0x2e, 0x4e, +0xff, 0x7d, 0x76, 0x67, 0x4d, 0x85, 0x2d, 0x1d, +0xdf, 0x34, 0xa9, 0x5c, 0x06, 0xa5, 0xe1, 0x36, +0x78, 0xf9, 0xcd, 0xc2, 0x97, 0x88, 0x78, 0xbb, +0xdd, 0x36, 0xf1, 0xbf, 0x0a, 0xd4, 0x85, 0xad, +0xd5, 0x20, 0x8e, 0xc2, 0x4a, 0xff, 0x8c, 0x46, +0x23, 0xf4, 0x56, 0x97, 0xb1, 0xb2, 0xb1, 0x89, +0x2c, 0xcb, 0x70, 0x15, 0xf8, 0x65, 0x97, 0xca, +0x83, 0x62, 0x61, 0xcf, 0x5f, 0xc0, 0x02, 0x16, +0xb0, 0x80, 0x2f, 0x03, 0xdc, 0xd1, 0x34, 0x1f, +0x90, 0x03, 0x9c, 0x04, 0x8b, 0x48, 0x5a, 0xc4, +0xcf, 0x92, 0x3a, 0x35, 0xfb, 0xf9, 0x55, 0xea, +0xb2, 0xd4, 0xfa, 0xd6, 0x51, 0x36, 0x19, 0xf4, +0x45, 0x12, 0x70, 0x4d, 0x3a, 0xd7, 0x7e, 0xfb, +0x40, 0xd3, 0x16, 0x50, 0xdb, 0xc2, 0x28, 0xf6, +0xe2, 0x0f, 0xcc, 0xcf, 0x9c, 0xf7, 0xfb, 0x7d, +0xdc, 0xbb, 0x77, 0x0f, 0xe3, 0xb3, 0x53, 0x5c, +0x8b, 0x5b, 0xaa, 0xb4, 0x2d, 0xdf, 0xfd, 0xaa, +0x48, 0xe4, 0x79, 0x6b, 0x71, 0xfe, 0x7d, 0x01, +0x0b, 0xf8, 0xf7, 0x11, 0x96, 0x82, 0xe2, 0x2f, +0x1a, 0x85, 0x5f, 0x5d, 0x88, 0x3b, 0xaa, 0xed, +0xdc, 0xdd, 0x9a, 0x26, 0x43, 0xad, 0x02, 0x70, +0x17, 0xaf, 0xc8, 0x34, 0x40, 0xd5, 0x2e, 0xcd, +0x41, 0x0b, 0xe5, 0x2a, 0x41, 0x5e, 0xaa, 0x42, +0x69, 0xf9, 0x7f, 0x5e, 0x86, 0x25, 0x59, 0xfb, +0x8e, 0xc8, 0xf9, 0x8e, 0xdc, 0x71, 0xb5, 0xf8, +0x78, 0x3c, 0x56, 0x25, 0x72, 0x49, 0xd4, 0x35, +0xdc, 0x64, 0x59, 0x5a, 0x5a, 0xa9, 0x25, 0x90, +0x67, 0xf7, 0x35, 0x70, 0x37, 0xb0, 0xcd, 0xd4, +0xea, 0xad, 0x6c, 0xea, 0x1c, 0xa7, 0x49, 0xdb, +0xf2, 0x9d, 0x7c, 0x5e, 0x04, 0x8d, 0x59, 0xc0, +0x02, 0x16, 0xf0, 0xcb, 0x04, 0x97, 0xf9, 0xe2, +0xbe, 0x89, 0x2f, 0x04, 0xcc, 0x76, 0x5e, 0x72, +0x80, 0x4b, 0xd6, 0x7a, 0xce, 0xa3, 0x9d, 0x87, +0x1a, 0xe5, 0xb7, 0x79, 0x01, 0x70, 0x91, 0xca, +0x34, 0xa2, 0xea, 0x53, 0x45, 0x6b, 0x92, 0xb3, +0xe6, 0xdc, 0x66, 0x85, 0x71, 0xb5, 0xde, 0xfb, +0x8e, 0xca, 0x69, 0x84, 0x54, 0x4b, 0x47, 0x30, +0x1e, 0x8f, 0xdd, 0x1f, 0x11, 0x76, 0x8d, 0xc0, +0x6b, 0x78, 0x12, 0x34, 0x0d, 0x3c, 0x63, 0x69, +0x13, 0xe4, 0xcd, 0x69, 0x00, 0xd0, 0x09, 0x03, +0x27, 0xa5, 0xdf, 0xec, 0x3c, 0x1b, 0x51, 0x5e, +0x1c, 0x4f, 0x5b, 0xc0, 0x02, 0x16, 0xb0, 0x80, +0x5f, 0x51, 0x88, 0x85, 0xb0, 0x38, 0x11, 0x0e, +0xdc, 0xe4, 0x00, 0x97, 0x66, 0x19, 0x30, 0x9e, +0x12, 0xd7, 0xcf, 0x9f, 0x1e, 0xab, 0x12, 0x78, +0x92, 0x24, 0x98, 0xa4, 0x99, 0x93, 0x28, 0x5d, +0x21, 0x8c, 0x00, 0xd1, 0xd9, 0x68, 0x00, 0xb5, +0x84, 0x93, 0xe7, 0x27, 0xd0, 0x2e, 0x1d, 0x91, +0x69, 0x64, 0x99, 0xd2, 0x66, 0x5f, 0x57, 0xb6, +0xe5, 0x69, 0xcf, 0x89, 0x77, 0xbb, 0xdd, 0x56, +0x25, 0x72, 0x5e, 0xa6, 0xd5, 0x2e, 0x2e, 0xa1, +0x6b, 0xea, 0xf5, 0xba, 0x88, 0x75, 0x5a, 0x7b, +0xa9, 0x8d, 0x87, 0x87, 0x87, 0x08, 0xce, 0x8e, +0xb0, 0x80, 0x05, 0x2c, 0x60, 0x01, 0x0b, 0xf8, +0xf7, 0x04, 0x82, 0x08, 0xd0, 0x7c, 0xa5, 0x34, +0x35, 0xfb, 0xda, 0xf0, 0xd4, 0x49, 0xe5, 0x97, +0xa7, 0x27, 0x2e, 0x64, 0x2b, 0xbd, 0xab, 0x3b, +0x8e, 0xc5, 0xa5, 0x4c, 0x1e, 0xb5, 0x8d, 0xff, +0xa7, 0x74, 0xf2, 0x9d, 0x06, 0x5a, 0x3c, 0x77, +0x4d, 0x55, 0xcf, 0x09, 0x79, 0x9d, 0x9a, 0x5f, +0x06, 0xa5, 0x91, 0xe9, 0x2d, 0xe2, 0xdd, 0xc4, +0x17, 0xc0, 0xe7, 0xc5, 0x6e, 0x1d, 0xbf, 0x6b, +0xa2, 0x62, 0x97, 0xb8, 0x03, 0x40, 0xda, 0x59, +0xb1, 0xeb, 0x9a, 0xa9, 0x5a, 0xb8, 0xbd, 0xfc, +0x57, 0xc5, 0x76, 0xbe, 0x80, 0x05, 0x2c, 0x60, +0x01, 0x0b, 0x50, 0x40, 0xde, 0x65, 0xce, 0xdf, +0x0b, 0x08, 0x4e, 0x93, 0xb5, 0x4a, 0x84, 0x33, +0x8d, 0x38, 0x72, 0x27, 0xb8, 0x26, 0x12, 0xa6, +0x15, 0x8b, 0xdd, 0x67, 0x43, 0xd7, 0x6e, 0x51, +0xe3, 0xdf, 0x9b, 0x9e, 0xf7, 0xb6, 0xa4, 0x7c, +0xf9, 0x9b, 0xab, 0xc5, 0x49, 0x22, 0x27, 0x35, +0xfb, 0x78, 0x3c, 0xf6, 0x5e, 0xf1, 0x2a, 0xcb, +0x90, 0xf7, 0xa4, 0xf3, 0x74, 0x5a, 0xb0, 0x1b, +0xab, 0x3c, 0xad, 0xcd, 0xf4, 0x77, 0x2a, 0x18, +0x34, 0x4e, 0xac, 0x49, 0xd5, 0xc2, 0xed, 0xe5, +0xbf, 0xec, 0xde, 0xec, 0x0b, 0x58, 0xc0, 0x02, +0x16, 0xb0, 0x80, 0x2f, 0x07, 0x82, 0x28, 0x0c, +0x01, 0x94, 0xc3, 0xb9, 0x02, 0x55, 0xbb, 0x2e, +0xbf, 0xba, 0x93, 0xbe, 0xfb, 0x9c, 0xd7, 0xea, +0x62, 0xb8, 0x6b, 0x9e, 0xed, 0x9a, 0x54, 0xae, +0x11, 0x44, 0x8e, 0xa3, 0x2c, 0xcb, 0x67, 0x3b, +0x97, 0xef, 0xe5, 0x19, 0x73, 0x0e, 0x3e, 0x7b, +0xb9, 0x2c, 0x4b, 0x5e, 0x8b, 0xaa, 0xe5, 0xa9, +0xc3, 0x47, 0xb6, 0x9d, 0x34, 0x23, 0x3c, 0xb4, +0xeb, 0xb3, 0x42, 0x9d, 0x84, 0xbe, 0x38, 0x22, +0xb6, 0x80, 0x05, 0x2c, 0x60, 0x01, 0xbf, 0xda, +0x10, 0x00, 0x50, 0xcf, 0x91, 0x37, 0x75, 0x20, +0xa3, 0x67, 0xed, 0x6c, 0xb7, 0x95, 0xaf, 0xce, +0xf6, 0x4c, 0xdf, 0x24, 0x1e, 0xfd, 0x7e, 0x1f, +0x87, 0x87, 0x87, 0x5e, 0x3c, 0xe4, 0xb3, 0x16, +0xf4, 0x85, 0x03, 0x11, 0x6d, 0xdf, 0x39, 0x73, +0x5e, 0x9e, 0xa5, 0x6a, 0xe7, 0x84, 0xdc, 0x77, +0xa6, 0x5d, 0xfb, 0x6f, 0x31, 0x25, 0xc3, 0xe1, +0x10, 0xad, 0x78, 0x8a, 0xcf, 0x79, 0xd0, 0xc1, +0x5b, 0x83, 0xb2, 0x07, 0x68, 0x53, 0xc9, 0xbb, +0x2e, 0xdd, 0xe2, 0x88, 0xd8, 0x02, 0x16, 0x50, +0x0f, 0x8b, 0xe3, 0x54, 0x0b, 0xf8, 0x65, 0x82, +0x64, 0x32, 0x28, 0x09, 0x6a, 0x01, 0x00, 0x74, +0x96, 0x96, 0x00, 0x94, 0xa5, 0x6f, 0x49, 0x88, +0xcf, 0xce, 0x2f, 0x4c, 0xaf, 0x75, 0xfe, 0xce, +0xa7, 0x2a, 0xe7, 0xe9, 0xaf, 0xea, 0x1c, 0x47, +0x17, 0x90, 0x58, 0x61, 0x5c, 0x35, 0xc7, 0x3c, +0xc9, 0x34, 0x68, 0x9e, 0xf3, 0xd6, 0xb1, 0xb4, +0xa6, 0x81, 0x62, 0xb8, 0xcd, 0x9c, 0xff, 0xb6, +0xfc, 0x06, 0x38, 0xe3, 0xa4, 0x1d, 0x07, 0x94, +0xf8, 0x77, 0xc2, 0x60, 0xfa, 0x2d, 0x99, 0x8e, +0x51, 0x5d, 0x6c, 0x76, 0x29, 0x85, 0x2f, 0xee, +0x33, 0x5f, 0xc0, 0x02, 0xbe, 0x1c, 0x58, 0x1c, +0xa7, 0x5a, 0xc0, 0x2f, 0x13, 0x0c, 0xe3, 0x6e, +0x49, 0x50, 0x0b, 0xd2, 0x2c, 0xc3, 0xda, 0x52, +0xb7, 0x42, 0x10, 0x49, 0x95, 0x4d, 0x6a, 0xde, +0x38, 0x0a, 0xdd, 0x37, 0x19, 0xa5, 0xcc, 0x72, +0xea, 0xba, 0xaa, 0x7a, 0x58, 0x12, 0x35, 0x4d, +0x62, 0xd5, 0xd2, 0x6b, 0x41, 0x62, 0x78, 0x7e, +0xcd, 0x66, 0x4d, 0x92, 0xb4, 0xf4, 0x64, 0xb7, +0x70, 0xe1, 0x79, 0x09, 0xa4, 0xf3, 0x9b, 0x16, +0xf3, 0x5d, 0x12, 0x69, 0x7e, 0xcd, 0x29, 0x2f, +0x53, 0x63, 0x40, 0xb8, 0xba, 0x7d, 0x6b, 0x39, +0xc1, 0x5a, 0x3b, 0x42, 0x9a, 0xe5, 0xde, 0xd8, +0xec, 0x34, 0xb8, 0xf4, 0x6e, 0x71, 0x2c, 0x6d, +0x01, 0x0b, 0x58, 0xc0, 0x02, 0xfe, 0xf2, 0x81, +0x14, 0xdc, 0x82, 0x31, 0x23, 0x1e, 0x14, 0x99, +0x4c, 0xb3, 0x55, 0x37, 0xb9, 0x18, 0x05, 0xd0, +0x8f, 0x8b, 0xf9, 0x6c, 0xe3, 0x56, 0x1a, 0x02, +0x7e, 0x79, 0x8b, 0x56, 0x86, 0x75, 0x06, 0x5d, +0x96, 0xad, 0xd5, 0x07, 0xf8, 0x3d, 0xd9, 0xb5, +0x23, 0x7a, 0x3e, 0xd0, 0x3c, 0xdb, 0xad, 0x33, +0xf6, 0xbe, 0xb3, 0xf3, 0xb2, 0x7d, 0xfd, 0x7e, +0x1f, 0xcb, 0xed, 0x08, 0x93, 0xc9, 0xa4, 0x8a, +0xe7, 0x64, 0x50, 0x1b, 0x48, 0x66, 0x41, 0xd0, +0x17, 0xb0, 0x80, 0x05, 0x2c, 0xe0, 0x57, 0x17, +0x34, 0xbf, 0x27, 0xb9, 0xef, 0x07, 0x00, 0x2a, +0x77, 0x98, 0xf3, 0xcb, 0x53, 0x64, 0x74, 0x38, +0xcd, 0xf3, 0x9d, 0xec, 0xd8, 0xf4, 0x9d, 0x13, +0x74, 0x9e, 0x57, 0x5e, 0xca, 0x52, 0x42, 0x56, +0x10, 0x38, 0x2d, 0x3e, 0x3b, 0xbd, 0xb7, 0x88, +0x21, 0x4f, 0xcf, 0xff, 0x03, 0x53, 0xa6, 0x80, +0x1f, 0x9d, 0xb3, 0x3c, 0xdc, 0x35, 0x5c, 0x2c, +0x02, 0x4c, 0x77, 0x98, 0xf3, 0x3b, 0xd2, 0x65, +0x39, 0xbe, 0xe8, 0x77, 0xf2, 0x9d, 0xc4, 0x99, +0x1f, 0x4d, 0xcb, 0x26, 0x63, 0xac, 0xb7, 0xc3, +0x6a, 0x59, 0x0b, 0x8f, 0xf5, 0x05, 0x2c, 0x60, +0x01, 0x0b, 0xf8, 0x4b, 0x09, 0x44, 0xc4, 0x9b, +0x5c, 0xa6, 0x15, 0x44, 0xed, 0x36, 0x26, 0x69, +0x56, 0x21, 0x3c, 0xbd, 0x5e, 0x0f, 0x67, 0xe7, +0x17, 0xa6, 0x64, 0xec, 0x0a, 0x33, 0x88, 0x62, +0x13, 0x49, 0x56, 0x2b, 0x4b, 0xe2, 0x21, 0x3d, +0xd7, 0xb5, 0xba, 0xa5, 0xaa, 0x9d, 0xfe, 0x6b, +0x6a, 0x7f, 0xf9, 0xbb, 0xdd, 0x6e, 0x7b, 0x43, +0xc1, 0x4a, 0x46, 0x42, 0x03, 0x9f, 0xba, 0xdd, +0x32, 0x35, 0xf8, 0xce, 0xe0, 0x4b, 0x86, 0x65, +0xe9, 0xda, 0x36, 0xd6, 0x57, 0xd7, 0xcc, 0x41, +0xac, 0xed, 0xd7, 0xc5, 0x79, 0xf3, 0x05, 0x2c, +0x60, 0x01, 0x0b, 0xf8, 0x95, 0x83, 0x3a, 0x61, +0xad, 0x64, 0x33, 0xef, 0x74, 0xaa, 0x77, 0x96, +0x93, 0x14, 0xcd, 0x25, 0x75, 0x8b, 0xa8, 0xc9, +0x23, 0x6b, 0xf2, 0x3b, 0x39, 0xaf, 0x59, 0x8e, +0x6b, 0x5a, 0x79, 0x4d, 0xce, 0xbd, 0x5b, 0x6a, +0x7b, 0x8d, 0xa1, 0xf0, 0x99, 0x0a, 0x38, 0xc8, +0x33, 0xf1, 0xb2, 0x4e, 0x0e, 0x56, 0xb0, 0x18, +0x29, 0xa5, 0x5b, 0xcc, 0x8e, 0xcf, 0xbb, 0x5f, +0x46, 0xd6, 0x3b, 0x7e, 0xfc, 0x08, 0x97, 0x45, +0x80, 0x47, 0xc1, 0xb2, 0x77, 0x90, 0xa5, 0x77, +0x63, 0xd3, 0x09, 0xb1, 0x80, 0x05, 0x2c, 0x60, +0x01, 0x7f, 0x51, 0xb0, 0x38, 0x1a, 0x7b, 0x35, +0xb0, 0x02, 0x83, 0x05, 0xd7, 0xa3, 0xbc, 0x64, +0x2b, 0xe7, 0x04, 0x54, 0xaa, 0xc7, 0x25, 0x31, +0x92, 0xc7, 0xd1, 0x78, 0x19, 0x00, 0x2a, 0x44, +0x59, 0x12, 0x5d, 0xed, 0x9d, 0x26, 0x6d, 0x4b, +0xf0, 0xd9, 0xcb, 0x2d, 0xf5, 0x3b, 0x2f, 0x9b, +0x24, 0x67, 0x0a, 0x12, 0x23, 0xcb, 0x96, 0xfd, +0x60, 0x69, 0x19, 0x34, 0x82, 0x4e, 0xc7, 0xd4, +0xea, 0x02, 0xc6, 0xf8, 0x1c, 0x03, 0x65, 0x7d, +0xc5, 0x64, 0x8c, 0xf0, 0xda, 0x4e, 0xe9, 0x0a, +0x54, 0x2d, 0xe2, 0x9b, 0xf4, 0x6e, 0x5c, 0xc0, +0x02, 0x16, 0xb0, 0x80, 0x5f, 0x76, 0x58, 0x1c, +0x8d, 0xf5, 0x83, 0xb6, 0xd7, 0xd3, 0x33, 0x77, +0x78, 0x0e, 0x82, 0x1b, 0x77, 0x5c, 0x74, 0x37, +0x49, 0x78, 0xb8, 0x8a, 0x9d, 0x7e, 0xcb, 0xff, +0xfc, 0x9c, 0x39, 0xa0, 0xab, 0xbc, 0xe9, 0x37, +0xb7, 0xa7, 0x6b, 0x47, 0xc7, 0x00, 0x54, 0xbe, +0x4b, 0xd5, 0x7f, 0xa9, 0x31, 0x0d, 0xa4, 0x6d, +0x1f, 0x90, 0x07, 0xbb, 0x74, 0x72, 0x93, 0x75, +0x4b, 0x62, 0x4c, 0x44, 0xdc, 0x0a, 0x16, 0xc3, +0x89, 0x7c, 0x18, 0xc5, 0x8d, 0x9c, 0x07, 0xf9, +0x73, 0x18, 0xc5, 0x15, 0xaf, 0xfc, 0xf7, 0x7f, +0xf1, 0x67, 0x38, 0x3e, 0x3d, 0xab, 0x0c, 0x22, +0x27, 0xde, 0x9a, 0x64, 0xbe, 0x50, 0xb1, 0x2f, +0x60, 0x01, 0x0b, 0x58, 0xc0, 0xaf, 0x2e, 0xc8, +0xbd, 0xde, 0x8a, 0xf6, 0x19, 0x6c, 0x66, 0x83, +0x92, 0x2a, 0x1c, 0xa8, 0xaa, 0xc6, 0x9b, 0x86, +0x20, 0x95, 0x12, 0xbc, 0x16, 0x21, 0x4e, 0x02, +0x4f, 0x63, 0x45, 0x9f, 0xe3, 0x38, 0x35, 0x95, +0x68, 0xad, 0x88, 0x73, 0x96, 0x34, 0x6f, 0x39, +0xc1, 0x59, 0x2a, 0x7c, 0xae, 0x4e, 0xe7, 0xc4, +0x5b, 0x12, 0xf6, 0x8b, 0xf3, 0x33, 0xaf, 0xbf, +0x81, 0x86, 0x6f, 0x96, 0x4e, 0xdc, 0x0d, 0x75, +0xfc, 0xfd, 0xf2, 0xd6, 0x6e, 0x65, 0x10, 0xb5, +0x41, 0xaf, 0x7b, 0xb7, 0x80, 0x05, 0x2c, 0x60, +0x01, 0x0b, 0xf8, 0xd5, 0x81, 0x26, 0x42, 0x59, +0xf0, 0xfe, 0xe7, 0x4f, 0x1d, 0x11, 0x96, 0x5e, +0xe8, 0x5c, 0x4a, 0x96, 0x92, 0xb8, 0x5a, 0xa1, +0x87, 0x30, 0xf2, 0xff, 0x54, 0x26, 0xfd, 0xe7, +0x44, 0x93, 0x3f, 0x6b, 0x12, 0xbb, 0x55, 0x4e, +0x13, 0x7c, 0x34, 0xe6, 0x44, 0xaa, 0xd2, 0xe5, +0xf9, 0x79, 0x5e, 0x17, 0x97, 0xc8, 0x2d, 0xd0, +0x02, 0xc7, 0x68, 0x78, 0xca, 0x76, 0x6b, 0x65, +0xf2, 0xef, 0xc5, 0x9d, 0x57, 0xf1, 0xe4, 0xec, +0xa2, 0x34, 0xb0, 0x96, 0xaa, 0xbd, 0xd2, 0x0f, +0x0b, 0xe9, 0x7c, 0x01, 0x0b, 0x50, 0x61, 0x61, +0xaf, 0x5d, 0xc0, 0x2f, 0x3b, 0x54, 0x8e, 0x1f, +0x07, 0x91, 0xaa, 0x81, 0x0d, 0x46, 0x93, 0xe9, +0xed, 0x2b, 0xf2, 0x8c, 0x39, 0x27, 0xde, 0xd2, +0xf6, 0xcd, 0x55, 0xed, 0x04, 0x92, 0x20, 0x03, +0xba, 0x5a, 0x9c, 0xfe, 0xd7, 0x11, 0x78, 0x59, +0x76, 0x53, 0x07, 0x36, 0x59, 0x8e, 0x96, 0xdf, +0x8a, 0xe1, 0x5e, 0xe7, 0xf4, 0x46, 0xd2, 0x38, +0xfd, 0x35, 0x01, 0xcb, 0xe4, 0x20, 0xc1, 0x2a, +0x6f, 0x92, 0x66, 0x48, 0xaf, 0xed, 0xe1, 0xfd, +0xbc, 0x7a, 0x81, 0x8a, 0xfc, 0x6f, 0xa9, 0xd8, +0x17, 0xd2, 0xf9, 0x02, 0x16, 0xa0, 0xc3, 0xc2, +0x5e, 0xbb, 0x80, 0x5f, 0x76, 0xa8, 0xec, 0xdf, +0x79, 0x5a, 0xd9, 0xf3, 0x87, 0x71, 0x17, 0xc1, +0x68, 0x34, 0xb3, 0x03, 0x2f, 0x2d, 0xa9, 0x44, +0x14, 0xa8, 0xaa, 0xcd, 0x7d, 0x8e, 0x69, 0xda, +0x79, 0x71, 0x7a, 0x4f, 0x04, 0xcb, 0x52, 0xdb, +0x6b, 0x8e, 0x76, 0x75, 0xd2, 0xad, 0x7c, 0xd6, +0x2e, 0x61, 0xd1, 0xca, 0xd1, 0x9c, 0xf3, 0xac, +0xb8, 0xf2, 0x1c, 0xe8, 0x5c, 0x39, 0xfd, 0x6e, +0x0a, 0x9a, 0x2d, 0xde, 0x4a, 0x47, 0x30, 0x49, +0x33, 0xac, 0xae, 0x2c, 0x63, 0x0d, 0x29, 0x1e, +0x5d, 0x94, 0xeb, 0xd2, 0x3c, 0x1a, 0xb5, 0x01, +0x5e, 0xc0, 0x02, 0x16, 0xb0, 0x80, 0x05, 0xfc, +0xea, 0x82, 0x4f, 0xb3, 0x5a, 0x0e, 0xe7, 0x3a, +0xbb, 0xea, 0xb3, 0x1d, 0xb4, 0x54, 0x55, 0xb6, +0x0c, 0xbc, 0xc2, 0xbf, 0x35, 0x51, 0xa7, 0xf3, +0x77, 0x44, 0xfc, 0xf8, 0x3b, 0x4d, 0x7d, 0x6f, +0xd9, 0xbd, 0xe5, 0x77, 0xd7, 0x20, 0xc3, 0xae, +0x4d, 0xc0, 0xfd, 0x01, 0xb4, 0x3a, 0x9a, 0x1e, +0x49, 0xd3, 0x6c, 0xe4, 0x3e, 0xfc, 0xae, 0xe2, +0x9c, 0x47, 0x1e, 0xf0, 0xc3, 0xe1, 0x10, 0x61, +0x14, 0x23, 0x8e, 0x42, 0x17, 0x42, 0xf7, 0x14, +0x11, 0x9e, 0x4e, 0x5a, 0xa5, 0x3b, 0x6c, 0x7d, +0x57, 0x9d, 0x2e, 0x88, 0xf8, 0x02, 0x16, 0xb0, +0x80, 0x05, 0xfc, 0x25, 0x80, 0x20, 0x9a, 0xff, +0x27, 0xf5, 0xfa, 0xec, 0x77, 0x25, 0x29, 0xa0, +0x87, 0x60, 0xed, 0xf7, 0xfb, 0x25, 0x42, 0x4b, +0x04, 0xd1, 0x77, 0xf4, 0x4b, 0x4a, 0xf2, 0xd2, +0x61, 0x4d, 0xf3, 0x4e, 0x97, 0x79, 0xe8, 0xb8, +0x5b, 0x1d, 0x81, 0xa6, 0xf7, 0xc4, 0x10, 0x50, +0xf9, 0xbe, 0xa0, 0x31, 0x1c, 0x24, 0x11, 0xe7, +0xe5, 0x71, 0x58, 0x5f, 0x5f, 0x77, 0xbf, 0xb9, +0x44, 0x6e, 0x45, 0x7d, 0xa3, 0xb2, 0xeb, 0x70, +0x97, 0x7d, 0xc7, 0xcb, 0xba, 0x38, 0x3f, 0x2b, +0x7d, 0x3b, 0x7d, 0x78, 0x1f, 0xa3, 0x60, 0x66, +0x06, 0xf1, 0xd8, 0xcb, 0x5d, 0xb9, 0x0b, 0x1b, +0xf9, 0x02, 0x16, 0xb0, 0x80, 0x05, 0xfc, 0xa5, +0x80, 0x8a, 0xe0, 0x96, 0xa7, 0x25, 0xc1, 0x8e, +0xf6, 0xfb, 0x00, 0x00, 0xc6, 0x79, 0x81, 0x24, +0x49, 0x30, 0x49, 0x33, 0xd3, 0x01, 0xcd, 0x65, +0x64, 0x44, 0xd7, 0x8a, 0x9c, 0xd6, 0xe4, 0x92, +0x12, 0x60, 0x2a, 0xe1, 0x4a, 0x46, 0xc2, 0xba, +0x2c, 0x85, 0x7e, 0xcb, 0xc0, 0x2a, 0x75, 0x44, +0x9b, 0x70, 0xd5, 0xda, 0xa0, 0xd9, 0xf9, 0x25, +0x58, 0xaa, 0xf4, 0x26, 0xd2, 0x79, 0xdd, 0x25, +0x33, 0x3e, 0x7b, 0x3a, 0xef, 0xc3, 0x7c, 0x3c, +0xc4, 0xce, 0x93, 0x0f, 0x81, 0x20, 0x6a, 0x24, +0x85, 0x2f, 0x24, 0xf3, 0x05, 0x2c, 0x60, 0x01, +0x0b, 0xf8, 0x4b, 0x00, 0x79, 0x3a, 0x95, 0xc2, +0xf3, 0x14, 0xc9, 0xe8, 0xac, 0xfc, 0x6d, 0x26, +0x9d, 0xd3, 0x7e, 0x1f, 0x44, 0xed, 0x36, 0xf2, +0xf1, 0xc8, 0x2b, 0x31, 0xfb, 0x54, 0xcf, 0x1a, +0xf1, 0x91, 0xa0, 0x45, 0x7e, 0xeb, 0xf5, 0x7a, +0x18, 0x8d, 0x46, 0x95, 0x23, 0x70, 0xd2, 0x49, +0x8d, 0x13, 0x5e, 0x92, 0xf4, 0x35, 0xc9, 0xb7, +0x4e, 0xf5, 0xaf, 0xd9, 0xff, 0xe5, 0xdf, 0x55, +0x1c, 0xd3, 0x08, 0x2c, 0x62, 0x5f, 0x77, 0x4c, +0xae, 0x0e, 0xfa, 0xfd, 0x3e, 0xce, 0xce, 0x2f, +0x80, 0xf6, 0xb4, 0xaf, 0xae, 0xed, 0xdd, 0x44, +0xb7, 0x98, 0x5f, 0xb4, 0xa2, 0x3a, 0xbd, 0x19, +0x5e, 0x8e, 0x88, 0x9b, 0x39, 0xeb, 0x2d, 0x60, +0x01, 0x0b, 0x58, 0xc0, 0x02, 0x7e, 0x79, 0xc0, +0xed, 0xe7, 0x41, 0x84, 0x61, 0x67, 0xd5, 0xfc, +0x9e, 0x4c, 0x06, 0x53, 0xc9, 0x9c, 0xce, 0x34, +0x97, 0x12, 0x19, 0xde, 0xe6, 0xdc, 0xb6, 0xcc, +0xd5, 0xe8, 0xda, 0x11, 0x33, 0xcd, 0x09, 0x8d, +0xe7, 0x3d, 0x3c, 0x3c, 0x54, 0x09, 0xa9, 0x3c, +0x7b, 0xee, 0x8b, 0x9d, 0x2e, 0x71, 0xf4, 0x11, +0xd0, 0x3a, 0x6d, 0x81, 0xe5, 0xf0, 0x46, 0xd0, +0xd4, 0x83, 0xfd, 0x0b, 0x0d, 0x1e, 0x6b, 0x7b, +0x96, 0x4e, 0x90, 0x04, 0x40, 0x36, 0x1e, 0xa1, +0xfb, 0xf9, 0x47, 0x18, 0xb4, 0xca, 0xaa, 0x76, +0x40, 0x10, 0x75, 0xe6, 0xe5, 0x58, 0xfa, 0x3e, +0x69, 0xee, 0xa8, 0xb7, 0x80, 0x05, 0x2c, 0x60, +0x01, 0x0b, 0xf8, 0xe5, 0x00, 0x47, 0xc0, 0x0d, +0xd5, 0x3a, 0x3f, 0xd1, 0x14, 0xb4, 0xe3, 0x29, +0x81, 0x18, 0x0e, 0xa7, 0x77, 0x96, 0xf3, 0xb3, +0xe5, 0x80, 0x5f, 0xb2, 0x05, 0x50, 0x21, 0xe8, +0x1c, 0xb8, 0x3d, 0x9b, 0xbe, 0x73, 0x3b, 0xb7, +0x75, 0x39, 0x0a, 0x2f, 0x9f, 0x7e, 0x4b, 0xe9, +0xde, 0x52, 0xaf, 0xd7, 0x85, 0x51, 0xb5, 0xe2, +0xa3, 0x57, 0x3a, 0x51, 0x61, 0x20, 0x7c, 0x76, +0x72, 0x5f, 0x19, 0x4d, 0x22, 0xc0, 0x69, 0xdf, +0x28, 0xff, 0xc6, 0xf6, 0x0e, 0x06, 0xb7, 0xbe, +0x36, 0x2f, 0x57, 0x91, 0xca, 0x1d, 0x11, 0x17, +0xce, 0x11, 0x0b, 0xfb, 0xf9, 0x02, 0x16, 0xb0, +0x80, 0x05, 0xfc, 0x8a, 0x02, 0x23, 0xe0, 0x00, +0x9c, 0xf6, 0x95, 0x6c, 0xe7, 0xa5, 0xd8, 0xec, +0x00, 0xdc, 0x45, 0x2b, 0x80, 0x7d, 0x14, 0xac, +0x49, 0xac, 0x74, 0x4e, 0xe0, 0xf9, 0x37, 0x72, +0xf0, 0x92, 0x41, 0x60, 0xb4, 0xc8, 0x6f, 0xd2, +0x11, 0x4e, 0xab, 0xc7, 0x87, 0x83, 0x75, 0x04, +0xad, 0xce, 0x36, 0x2e, 0xc1, 0x47, 0x6c, 0x9f, +0x45, 0x42, 0x6f, 0xea, 0x14, 0x67, 0xc1, 0xd3, +0x7b, 0xef, 0x57, 0x06, 0x76, 0x18, 0x77, 0xab, +0x47, 0xd4, 0xc2, 0xb0, 0x92, 0x66, 0x01, 0x0b, +0xf8, 0xb2, 0xa1, 0x95, 0x4e, 0xbe, 0x78, 0x21, +0x0b, 0x58, 0xc0, 0x02, 0xbc, 0x20, 0xcd, 0xa8, +0x40, 0xd5, 0x21, 0xce, 0x39, 0xc0, 0x25, 0x33, +0x22, 0x2b, 0xc3, 0xb9, 0x72, 0xd0, 0x1c, 0xe2, +0x34, 0xa2, 0xe9, 0x0b, 0x97, 0x7a, 0x72, 0x72, +0xe2, 0x08, 0xb8, 0x74, 0x7c, 0xd3, 0xee, 0x39, +0xd7, 0xea, 0xf4, 0x39, 0xc3, 0x59, 0x78, 0xd3, +0xff, 0x26, 0x0e, 0x69, 0x1a, 0x70, 0xc2, 0x4d, +0x71, 0xd8, 0xf9, 0x9f, 0x84, 0x26, 0x67, 0xcf, +0x9b, 0x68, 0x0a, 0xe8, 0xf7, 0xa7, 0xf7, 0x1f, +0x00, 0x00, 0xfa, 0x37, 0x5f, 0xae, 0x0e, 0xae, +0x32, 0xb0, 0x98, 0x8c, 0x54, 0x6e, 0x6e, 0x01, +0x0b, 0xf8, 0x32, 0xa1, 0x98, 0x05, 0x99, 0x5a, +0xc0, 0x02, 0x16, 0xf0, 0xef, 0x0e, 0x86, 0x4b, +0x3d, 0x00, 0xba, 0xa0, 0xe6, 0xd2, 0x90, 0x03, +0x1c, 0xc2, 0xe9, 0x46, 0x6f, 0x45, 0x62, 0x93, +0xdf, 0xb4, 0x67, 0x7a, 0x47, 0x4c, 0x01, 0x2f, +0x47, 0x53, 0xdb, 0x77, 0xbb, 0xdd, 0x4a, 0x70, +0x97, 0xab, 0x9c, 0x1d, 0xb7, 0x1c, 0xd6, 0x7c, +0x91, 0xe2, 0xea, 0xb4, 0x0a, 0x1a, 0x10, 0xf1, +0xa6, 0x88, 0x6f, 0x5a, 0x04, 0x38, 0x29, 0xa5, +0x6b, 0xd7, 0x9f, 0xfa, 0x4e, 0x06, 0xd4, 0x46, +0x86, 0x5b, 0x5a, 0x02, 0x00, 0x84, 0x61, 0xa8, +0x7a, 0xb3, 0xfb, 0x6e, 0xd4, 0x71, 0xff, 0x25, +0x71, 0x5f, 0xc0, 0x02, 0x16, 0xb0, 0x80, 0x05, +0xfc, 0xf2, 0xc3, 0x4c, 0x38, 0x33, 0x05, 0x35, +0x88, 0xa3, 0x69, 0xda, 0x4d, 0x67, 0x16, 0x41, +0xf4, 0x1d, 0xe7, 0xaa, 0x73, 0x54, 0xd3, 0xd4, +0xea, 0xb2, 0x7e, 0xfe, 0xec, 0x23, 0x80, 0xf2, +0x48, 0x9b, 0xf4, 0x4a, 0x97, 0xd1, 0xec, 0x00, +0x5d, 0x75, 0xef, 0x53, 0x79, 0xcb, 0x73, 0xe5, +0xfc, 0x1d, 0x50, 0xaf, 0x6e, 0xb7, 0x8e, 0xf8, +0xd5, 0x45, 0xd2, 0xa3, 0xbc, 0xbd, 0x5e, 0x0f, +0xed, 0xa0, 0x85, 0x53, 0x44, 0x78, 0x72, 0x61, +0x30, 0x23, 0xc6, 0xed, 0x69, 0xda, 0xfb, 0x05, +0x2c, 0x60, 0x01, 0x0b, 0x58, 0xc0, 0xaf, 0x0e, +0x58, 0x71, 0x45, 0x34, 0x7f, 0xa9, 0x20, 0x78, +0x7c, 0xdf, 0x24, 0xca, 0xdc, 0x63, 0xdd, 0x0a, +0x71, 0x2a, 0x83, 0xb6, 0x68, 0x47, 0xca, 0x78, +0xda, 0x9d, 0x9d, 0x1d, 0x1c, 0x1e, 0x1e, 0xba, +0x67, 0x1f, 0xf8, 0xa4, 0x69, 0x4b, 0x72, 0xb7, +0x98, 0x0d, 0x2d, 0x92, 0x5b, 0x1d, 0x48, 0x09, +0x9c, 0x4b, 0xe8, 0x4d, 0xd4, 0xe9, 0x3e, 0x2d, +0x81, 0xd5, 0x76, 0xfa, 0xc6, 0x1d, 0x04, 0x3f, +0x68, 0xad, 0xa2, 0x18, 0x0f, 0x2b, 0x0e, 0x0f, +0xda, 0x6f, 0x22, 0xe4, 0xbe, 0xa0, 0x32, 0x0b, +0x58, 0xc0, 0x02, 0x16, 0xb0, 0x80, 0x5f, 0x7e, +0xe0, 0x42, 0x59, 0xe5, 0xc2, 0x15, 0x01, 0xa5, +0xa3, 0x69, 0x96, 0xb3, 0x98, 0x94, 0x24, 0x7d, +0x6a, 0x6c, 0xeb, 0x98, 0x18, 0x97, 0x94, 0xb5, +0x88, 0x73, 0x52, 0x4a, 0x97, 0x4c, 0x81, 0xf4, +0x8c, 0xd7, 0x08, 0xb8, 0x75, 0xe5, 0xaa, 0x3c, +0x52, 0xa7, 0xe1, 0xcd, 0x41, 0xde, 0x8e, 0x26, +0xef, 0x2c, 0xbf, 0xca, 0x25, 0x2b, 0x75, 0x11, +0xe8, 0xb4, 0x7e, 0x20, 0x26, 0x2a, 0x49, 0x12, +0x64, 0xbd, 0x1d, 0xbc, 0x50, 0x9c, 0xa1, 0xd5, +0x4e, 0x2a, 0x6a, 0x76, 0x1a, 0x60, 0x4d, 0x12, +0x5f, 0x48, 0xe6, 0x0b, 0x58, 0xc0, 0x02, 0x16, +0xf0, 0xab, 0x0d, 0x52, 0x02, 0xd7, 0xee, 0xdd, +0x20, 0x1a, 0x10, 0x1c, 0xa1, 0x0d, 0x60, 0x7a, +0x6b, 0xda, 0x24, 0xcd, 0xd4, 0x10, 0xab, 0x12, +0x7c, 0x47, 0xc8, 0xe8, 0xbb, 0x96, 0xae, 0xd7, +0xeb, 0xe1, 0xe4, 0xe4, 0xc4, 0x11, 0x76, 0xa9, +0x16, 0xd7, 0x8e, 0x9f, 0xf1, 0xb2, 0xfb, 0xfd, +0x7e, 0x45, 0x45, 0xcf, 0x41, 0xda, 0xeb, 0xb5, +0xdf, 0x14, 0xac, 0x46, 0xe2, 0xcc, 0xa5, 0x70, +0x4e, 0xc4, 0x09, 0x7c, 0xb6, 0x71, 0xef, 0x60, +0x5c, 0xf1, 0xf8, 0x9b, 0xec, 0x87, 0x4d, 0x4c, +0x71, 0x19, 0x24, 0xf3, 0x80, 0x01, 0x52, 0xea, +0x96, 0x03, 0x2b, 0x27, 0xc1, 0x02, 0x16, 0xb0, +0x80, 0x05, 0x2c, 0xe0, 0x57, 0x0f, 0xe4, 0x89, +0x25, 0xf9, 0x4c, 0xef, 0x86, 0x71, 0x17, 0xee, +0xfe, 0xbf, 0x38, 0x0a, 0x31, 0x9c, 0x11, 0x31, +0xed, 0x72, 0x95, 0x4a, 0x25, 0x2c, 0x66, 0xbb, +0x46, 0x60, 0x35, 0xbb, 0x36, 0x50, 0xb6, 0x97, +0x5b, 0x67, 0xc2, 0x7d, 0x01, 0x67, 0xb4, 0x0b, +0x52, 0xb4, 0x00, 0x32, 0x75, 0xe7, 0xd4, 0x25, +0xc8, 0x78, 0xeb, 0x9c, 0xb0, 0x4b, 0x95, 0xfa, +0x55, 0xd4, 0xec, 0x96, 0x74, 0x6e, 0x39, 0xf5, +0xc9, 0x3c, 0x37, 0x9e, 0x7f, 0x09, 0x1f, 0xb4, +0x56, 0x81, 0x11, 0x63, 0x4e, 0x98, 0xd4, 0xad, +0x11, 0x72, 0x9e, 0x66, 0x01, 0x0b, 0x58, 0xc0, +0x02, 0x16, 0xf0, 0xab, 0x0b, 0x1a, 0x41, 0x07, +0xe6, 0x12, 0x39, 0xfd, 0x0e, 0xb6, 0x30, 0x76, +0x89, 0xb2, 0xc9, 0xb8, 0x96, 0xe8, 0xd5, 0x39, +0x6d, 0x69, 0x04, 0x9c, 0x7f, 0xa7, 0xa8, 0x6f, +0x80, 0x4e, 0xd0, 0x2c, 0xf5, 0xb3, 0xf4, 0x8a, +0xa7, 0xdf, 0x5a, 0x2c, 0x79, 0x1e, 0xd1, 0x4e, +0x3a, 0xdd, 0x11, 0x68, 0x52, 0xb7, 0x54, 0xa7, +0x73, 0xef, 0x75, 0x7a, 0x96, 0xef, 0x2c, 0x90, +0xe6, 0x02, 0xdf, 0xd1, 0x3e, 0xde, 0x16, 0xd9, +0xf6, 0xa7, 0x9f, 0x7d, 0x8a, 0xb3, 0x6b, 0xb7, +0x5c, 0x04, 0x20, 0x9f, 0x43, 0x04, 0x11, 0x77, +0xcb, 0xae, 0xbe, 0x80, 0x05, 0x2c, 0x60, 0x01, +0x0b, 0xf8, 0xd5, 0x01, 0x9f, 0xf6, 0x95, 0x0b, +0x73, 0xc3, 0xb8, 0x8b, 0xe8, 0x08, 0x6d, 0xec, +0xcc, 0x12, 0x85, 0x71, 0xdb, 0x1b, 0xcd, 0x4d, +0x3b, 0x8b, 0x6e, 0xc5, 0x54, 0x97, 0xf9, 0x7b, +0xbd, 0x1e, 0xee, 0xdd, 0xbb, 0x57, 0xca, 0x5b, +0x77, 0xb7, 0xb7, 0x55, 0xaf, 0x76, 0x1f, 0x39, +0x95, 0x37, 0x49, 0xb3, 0xa9, 0x96, 0x41, 0xa8, +0xab, 0x65, 0x3d, 0x9a, 0x3d, 0x9c, 0x4b, 0xe6, +0xf4, 0x5b, 0xaa, 0xdc, 0xe5, 0x77, 0x0b, 0x2c, +0xbf, 0x03, 0xd9, 0xb6, 0x3a, 0x1b, 0x7e, 0x74, +0xe3, 0x0e, 0x9e, 0xe6, 0xa1, 0x1a, 0xbe, 0x4f, +0xfb, 0x6f, 0xfd, 0xfe, 0x47, 0x1f, 0x3f, 0x2d, +0x39, 0xc7, 0x95, 0x22, 0xc6, 0x11, 0x3e, 0xa3, +0xb3, 0x52, 0xf8, 0xc0, 0x64, 0x32, 0x40, 0xab, +0x9d, 0xcc, 0xc3, 0xc8, 0xf2, 0xef, 0xe2, 0x59, +0x7e, 0xa3, 0x77, 0xc0, 0x34, 0x24, 0x61, 0xb7, +0x98, 0x60, 0xd0, 0x8a, 0xe7, 0xe9, 0xe8, 0x88, +0x85, 0x38, 0x03, 0xdf, 0x2d, 0x26, 0x28, 0xc6, +0x43, 0xb5, 0xdc, 0x64, 0x74, 0x56, 0xc2, 0xc7, +0x8b, 0xc3, 0xac, 0xfc, 0x6e, 0xab, 0x28, 0xa5, +0xd7, 0xf2, 0x10, 0x8e, 0xde, 0x79, 0x38, 0xcb, +0x53, 0xa9, 0x63, 0x86, 0xbf, 0xd5, 0x7e, 0x9e, +0x87, 0xfa, 0xc0, 0x7d, 0x8b, 0xbb, 0xde, 0xfc, +0x3e, 0x9c, 0x5d, 0x1f, 0x8a, 0xf1, 0xd3, 0xda, +0xe2, 0xed, 0xa3, 0x67, 0xc4, 0xbf, 0xc9, 0xf8, +0xf3, 0x74, 0xea, 0xb8, 0xd1, 0x5c, 0x94, 0xfd, +0xfa, 0xe7, 0xd9, 0xff, 0x80, 0xc3, 0xa1, 0x74, +0xec, 0x67, 0x76, 0xb9, 0x85, 0xfb, 0xae, 0x1c, +0x09, 0x95, 0xf8, 0x3c, 0xcb, 0xfc, 0xab, 0x1b, +0x27, 0x89, 0x7b, 0x93, 0xf5, 0xa3, 0xd5, 0xc7, +0xe7, 0x45, 0xa5, 0x1f, 0x8c, 0xb5, 0x46, 0xf3, +0x53, 0xc3, 0xb7, 0xe9, 0x5c, 0x78, 0x16, 0xfc, +0xb5, 0xf5, 0x6f, 0xcd, 0x41, 0xef, 0xdc, 0x98, +0x95, 0xef, 0xdb, 0xb7, 0xea, 0xe6, 0xee, 0x55, +0xe6, 0x5f, 0x93, 0xbd, 0xa9, 0xf4, 0x9f, 0xf5, +0x2f, 0xe5, 0xad, 0x94, 0xaf, 0x9c, 0x52, 0x92, +0x7b, 0x38, 0xfd, 0x0e, 0x00, 0x38, 0xf5, 0x7a, +0x09, 0x79, 0xa1, 0xf2, 0xb5, 0x9c, 0xd2, 0xa4, +0x37, 0x3b, 0x01, 0xb7, 0x8b, 0x03, 0x70, 0xea, +0x78, 0x4a, 0xaf, 0xa9, 0x94, 0xb5, 0xd0, 0xb0, +0x52, 0x85, 0xaf, 0x1d, 0x61, 0xa3, 0x77, 0x32, +0xc6, 0xbc, 0x26, 0xb5, 0x4b, 0xaf, 0x76, 0x49, +0x94, 0x25, 0x91, 0xf7, 0x11, 0xf7, 0xa6, 0xea, +0x76, 0x8e, 0xaf, 0xc4, 0xcf, 0x97, 0x76, 0x92, +0x66, 0xd8, 0xca, 0x07, 0x68, 0x87, 0x41, 0x89, +0x0b, 0xab, 0x93, 0xb6, 0xeb, 0xae, 0x49, 0x2d, +0x6d, 0x4c, 0x74, 0x1b, 0xcf, 0xec, 0x2c, 0x23, +0xfd, 0xa6, 0x74, 0x83, 0xa2, 0x55, 0xfa, 0x2e, +0xd3, 0xbb, 0x49, 0x47, 0xff, 0xc5, 0x77, 0xca, +0x43, 0xe5, 0xf0, 0x30, 0x84, 0xee, 0x0c, 0x3c, +0xcb, 0x33, 0x28, 0x5a, 0xa5, 0x6b, 0xfe, 0xe4, +0xe2, 0x1c, 0x14, 0xad, 0x52, 0x7a, 0x5e, 0x6f, +0xa9, 0x3d, 0xb3, 0x76, 0x57, 0xd2, 0x8b, 0x76, +0x0e, 0x3b, 0xab, 0xf3, 0xcd, 0x85, 0xa5, 0xe3, +0xe9, 0xdd, 0xa6, 0xce, 0xf0, 0xd7, 0xa2, 0xf1, +0xc9, 0x32, 0x78, 0x9e, 0x64, 0x74, 0x36, 0x3f, +0x91, 0xc0, 0x08, 0x99, 0xcc, 0x9f, 0x8c, 0xce, +0x54, 0x1c, 0x4a, 0x38, 0x8b, 0x50, 0x8e, 0x72, +0xcc, 0x4a, 0x78, 0xb3, 0xbc, 0xa5, 0xfe, 0xa7, +0x3e, 0xa2, 0x8d, 0x5e, 0xa9, 0x9f, 0xfa, 0x53, +0xe2, 0x5f, 0xc1, 0xa9, 0x0e, 0x7f, 0x6b, 0xdc, +0x30, 0x27, 0x30, 0x72, 0x6e, 0xfd, 0x79, 0xf6, +0x3f, 0x6f, 0x07, 0x5f, 0x17, 0x72, 0xbd, 0x54, +0xd6, 0xdd, 0x15, 0xe6, 0x1f, 0xef, 0x1b, 0xb9, +0xce, 0x64, 0x1b, 0x65, 0xdf, 0xf3, 0xf5, 0xe3, +0xea, 0x98, 0xad, 0x1f, 0xd9, 0x5f, 0x94, 0xae, +0x34, 0x27, 0x3a, 0xab, 0xa5, 0x3a, 0xad, 0x35, +0x5d, 0xc1, 0x4b, 0xb4, 0x91, 0xd7, 0xa5, 0xd5, +0x23, 0xfb, 0x41, 0xc3, 0x9f, 0xf7, 0xb5, 0x85, +0x3f, 0xef, 0x07, 0x3e, 0x3f, 0xa8, 0x5e, 0x89, +0x4b, 0x69, 0xfc, 0x44, 0xff, 0xcb, 0x76, 0x79, +0xdb, 0xa9, 0xcc, 0x5f, 0xd9, 0x4f, 0x95, 0x3a, +0xd8, 0xbc, 0x91, 0xb8, 0xa9, 0xe3, 0x2c, 0xe6, +0x16, 0x8d, 0x8f, 0x9b, 0x27, 0x72, 0x0e, 0xcc, +0x40, 0x9e, 0x52, 0xd2, 0x9c, 0x9f, 0x1d, 0x5b, +0x34, 0x49, 0x33, 0x64, 0x93, 0x31, 0x86, 0xc3, +0x21, 0xc2, 0x28, 0x76, 0x84, 0xc6, 0xba, 0x3e, +0x54, 0x02, 0xdd, 0x7f, 0x6e, 0xa9, 0xca, 0xf9, +0xa5, 0x2a, 0xb2, 0x3c, 0xed, 0x72, 0x16, 0x1e, +0x80, 0x46, 0x73, 0xca, 0xd3, 0xec, 0xd1, 0x71, +0x14, 0x56, 0xca, 0xe6, 0x69, 0x6f, 0x3c, 0xff, +0x92, 0xd3, 0x0e, 0x00, 0x65, 0x02, 0x2d, 0xa5, +0x6c, 0xed, 0x9b, 0x4c, 0x27, 0x99, 0x00, 0x4d, +0x52, 0x6f, 0x72, 0xa6, 0x5c, 0xe2, 0x1b, 0xc6, +0x6d, 0xd7, 0x9e, 0x4e, 0xa7, 0x83, 0xee, 0xca, +0x1a, 0xd0, 0x9f, 0x54, 0x24, 0x04, 0x9f, 0xa7, +0xa3, 0x66, 0x63, 0x91, 0x9c, 0x9c, 0x4c, 0x2f, +0xd5, 0xf4, 0xfc, 0xbd, 0xcf, 0x09, 0x83, 0x36, +0x8b, 0x4a, 0x7b, 0x6a, 0xea, 0xe1, 0x6d, 0xb0, +0xf0, 0x27, 0x2e, 0xd6, 0xc2, 0x5f, 0xf3, 0xf0, +0xb4, 0xbe, 0x69, 0x6d, 0xe0, 0x5c, 0xb2, 0xd6, +0x56, 0x0d, 0xdf, 0x52, 0x5a, 0xb6, 0x98, 0x25, +0xc7, 0x2c, 0xf3, 0xc8, 0xdf, 0x00, 0x2a, 0xf9, +0xb5, 0xd3, 0x0a, 0xbe, 0xf2, 0xdc, 0x86, 0x27, +0x2e, 0x61, 0xb0, 0xe2, 0x0e, 0xc8, 0xf6, 0x58, +0xed, 0xb4, 0xc6, 0x4b, 0x8e, 0x99, 0x93, 0x3c, +0x6a, 0xf2, 0x6b, 0x7d, 0xc7, 0xfb, 0xe0, 0x2f, +0xac, 0xff, 0xeb, 0xe6, 0x9f, 0xa2, 0xe5, 0xba, +0xca, 0xfc, 0xf3, 0xf5, 0x8d, 0x6b, 0xfb, 0x6c, +0xfc, 0xac, 0xbe, 0xb3, 0xfa, 0xc0, 0x1a, 0x6f, +0xa9, 0x71, 0xa0, 0xfe, 0xf5, 0xad, 0x7f, 0xad, +0x3e, 0x5f, 0xbf, 0xba, 0xe7, 0x99, 0x06, 0xc3, +0xea, 0x6b, 0xab, 0x2d, 0xe6, 0x7c, 0xf6, 0xe0, +0x2f, 0xdb, 0xab, 0x95, 0x79, 0x25, 0xdc, 0x1b, +0xcc, 0xff, 0xca, 0x7c, 0x37, 0x4e, 0x09, 0xd5, +0xcd, 0x35, 0xdf, 0x1e, 0xca, 0xb5, 0x02, 0x75, +0xea, 0x74, 0xad, 0x0f, 0xe8, 0x79, 0x1a, 0x34, +0xa6, 0xd3, 0x41, 0xc6, 0x62, 0x2d, 0xaf, 0xae, +0x2c, 0x4f, 0x13, 0x18, 0x6a, 0x60, 0x79, 0xdf, +0x38, 0x27, 0xe4, 0x94, 0x46, 0xde, 0x7c, 0x46, +0x12, 0xb9, 0x64, 0x0e, 0x7c, 0x77, 0xa2, 0xd3, +0x6f, 0x9e, 0x4e, 0x3b, 0x47, 0xee, 0xbb, 0x7a, +0x95, 0xe7, 0xf9, 0xf0, 0x17, 0x7f, 0x86, 0x7e, +0xbf, 0x6f, 0x46, 0x6f, 0x93, 0x81, 0x61, 0x2c, +0x42, 0x2e, 0x25, 0x72, 0x9f, 0xca, 0xdd, 0x47, +0xc4, 0xa9, 0x0c, 0xcb, 0x4f, 0x21, 0x49, 0x12, +0x2c, 0xf5, 0x36, 0xf0, 0xd9, 0xe5, 0xb8, 0x5c, +0xa6, 0x67, 0x83, 0xb1, 0x26, 0x1b, 0x77, 0x96, +0x90, 0x65, 0x69, 0x36, 0x76, 0x6b, 0x51, 0xab, +0xcf, 0x4c, 0x1d, 0x69, 0x05, 0xac, 0xf1, 0xd5, +0xe3, 0x2b, 0xbf, 0x24, 0xe1, 0x1b, 0xb8, 0xf3, +0xcd, 0xa8, 0x2e, 0xdc, 0xad, 0x55, 0xbe, 0x56, +0x9e, 0x86, 0x77, 0xc5, 0xbc, 0xc1, 0x25, 0x4b, +0x54, 0x17, 0xa3, 0xb5, 0xb8, 0x5d, 0x3d, 0x22, +0xbf, 0xec, 0x1f, 0x1f, 0x38, 0xdc, 0x98, 0x54, +0x6e, 0x6d, 0xa6, 0x5a, 0xfd, 0x84, 0xbf, 0xdc, +0x2c, 0xb5, 0x79, 0x20, 0xeb, 0xe5, 0xc4, 0xa8, +0x49, 0x7e, 0x6b, 0x03, 0xfd, 0x0b, 0xef, 0xff, +0x9a, 0xf9, 0xc1, 0x37, 0x4b, 0xad, 0x1f, 0xea, +0xe6, 0x9f, 0xc5, 0xa0, 0x94, 0xbe, 0x31, 0x86, +0xc4, 0x72, 0x62, 0xad, 0x73, 0x6e, 0xb5, 0x82, +0xe9, 0xaa, 0xd7, 0x13, 0x00, 0x00, 0x08, 0x3e, +0x49, 0x44, 0x41, 0x54, 0x89, 0x68, 0x63, 0x63, +0xe1, 0xed, 0xdb, 0x33, 0x64, 0xfb, 0xe4, 0xdc, +0xd3, 0x40, 0xdb, 0x8f, 0xac, 0x7e, 0x92, 0x6d, +0xa8, 0x3b, 0x6e, 0x5b, 0x47, 0xc8, 0xcd, 0xf9, +0x66, 0xcc, 0x3f, 0x5f, 0x5a, 0xd9, 0x4f, 0x52, +0x90, 0xe1, 0x5a, 0x32, 0x6d, 0xbd, 0xf8, 0x84, +0x2e, 0x9e, 0xdf, 0xab, 0x41, 0x05, 0xd4, 0x36, +0xf3, 0x67, 0xa7, 0x66, 0x9f, 0x64, 0x39, 0xc2, +0xb8, 0x8d, 0x49, 0x9a, 0xe1, 0xec, 0xfc, 0x02, +0xc3, 0xe1, 0xd0, 0xfd, 0xe7, 0x20, 0x1d, 0xd1, +0xe4, 0xb3, 0x75, 0xdd, 0xa9, 0xcf, 0xf9, 0x4b, +0x0b, 0x03, 0x2b, 0x55, 0xf6, 0x3e, 0x9b, 0x39, +0xff, 0xaf, 0x39, 0xbf, 0xf1, 0xef, 0xc3, 0xe1, +0xb0, 0x24, 0x75, 0x6b, 0x1e, 0xec, 0x04, 0xf2, +0xa8, 0x1a, 0x7f, 0xdf, 0xd4, 0x76, 0x2e, 0xdb, +0xc9, 0xff, 0x53, 0x3e, 0xd9, 0x1f, 0x71, 0xe8, +0x0e, 0x19, 0x20, 0x0d, 0x3b, 0x18, 0x4e, 0xf2, +0xd2, 0xe0, 0xfa, 0x24, 0x5d, 0x39, 0x79, 0x2c, +0xae, 0xd2, 0xc7, 0xc1, 0xfa, 0x24, 0x2a, 0xf9, +0x2c, 0x17, 0xb8, 0xc4, 0x91, 0xe3, 0xad, 0x95, +0xcd, 0xeb, 0xe6, 0xa0, 0x95, 0xa3, 0x7d, 0xab, +0x93, 0x30, 0x7c, 0xb8, 0x6b, 0xfd, 0x25, 0xeb, +0x95, 0x65, 0xc9, 0x6f, 0xda, 0xb5, 0xb3, 0x56, +0x7f, 0xa8, 0x78, 0x8b, 0xfc, 0xd6, 0x46, 0xc6, +0xfb, 0xda, 0x92, 0x1c, 0x9b, 0x68, 0x23, 0xae, +0x5a, 0xbf, 0xd5, 0x5f, 0x96, 0xd4, 0x60, 0xe5, +0xd7, 0xc6, 0xc3, 0x37, 0x57, 0xfe, 0xdc, 0xfa, +0xdf, 0x33, 0xff, 0xe4, 0x38, 0x58, 0x12, 0xa5, +0x6f, 0xfe, 0x69, 0x73, 0x5c, 0x23, 0x46, 0x1a, +0xe3, 0x25, 0xfb, 0xa4, 0xd2, 0x76, 0xd1, 0xbf, +0x5a, 0x7e, 0xad, 0x3f, 0x65, 0x5f, 0xf9, 0xc6, +0xc7, 0xd7, 0x0e, 0x39, 0x17, 0xac, 0x31, 0xb5, +0x18, 0x0d, 0x99, 0x47, 0xeb, 0x6b, 0x69, 0xfe, +0xf0, 0xad, 0x0f, 0x6d, 0x5c, 0x2c, 0x29, 0xbe, +0x0e, 0x57, 0x0d, 0x77, 0xc2, 0xab, 0x94, 0x8f, +0x9b, 0xb7, 0x44, 0xdb, 0x1a, 0xd5, 0xcb, 0xf2, +0x6b, 0xf3, 0x5c, 0x9b, 0x1b, 0xd6, 0x18, 0x07, +0x1b, 0x83, 0xa7, 0x58, 0x5d, 0x5e, 0x9a, 0x4a, +0xe7, 0x93, 0x71, 0x49, 0x55, 0xcd, 0x7f, 0x4b, +0x69, 0x59, 0xb3, 0x93, 0x53, 0x1a, 0xfa, 0x96, +0x24, 0x09, 0x0e, 0x0f, 0x0f, 0xb1, 0xbb, 0xbb, +0xab, 0x7a, 0x75, 0x3f, 0x4b, 0xbc, 0x74, 0x00, +0x6a, 0xf0, 0x18, 0xee, 0xfc, 0x26, 0xdf, 0xd3, +0xf3, 0xf3, 0x5f, 0x7b, 0x15, 0xcb, 0xab, 0x6b, +0xa5, 0xb2, 0x24, 0xc1, 0xb6, 0xbc, 0xd5, 0xa5, +0xa3, 0x1c, 0x4f, 0xdb, 0x14, 0x9a, 0xde, 0xdc, +0xc6, 0x89, 0x7e, 0xde, 0x4e, 0x30, 0x40, 0xe0, +0xdd, 0x18, 0xf8, 0xc0, 0xca, 0x49, 0x74, 0x15, +0xa8, 0x5b, 0x18, 0x1a, 0x87, 0x6f, 0x31, 0x12, +0x75, 0x92, 0x0a, 0xfd, 0xb6, 0x24, 0x50, 0xf9, +0xcd, 0x27, 0xf1, 0xc8, 0xf2, 0x2c, 0x26, 0x47, +0xf6, 0x8d, 0x25, 0x91, 0xc8, 0x3e, 0xe6, 0x6d, +0xf5, 0xa9, 0xce, 0xac, 0xf6, 0xf2, 0xbe, 0x95, +0xbf, 0xb5, 0x36, 0x59, 0x1c, 0xb9, 0x25, 0xb1, +0x6a, 0x44, 0xde, 0xea, 0x33, 0xad, 0xff, 0xb4, +0xb1, 0x91, 0xb8, 0x5a, 0xfd, 0x55, 0x97, 0x5f, +0x2b, 0x8b, 0xff, 0xfe, 0xf3, 0xea, 0x7f, 0x6b, +0x7e, 0x58, 0x50, 0x37, 0x4f, 0xeb, 0x88, 0x82, +0xd6, 0x0e, 0xdf, 0x9a, 0xb2, 0x98, 0x32, 0x1f, +0x03, 0xa0, 0xe5, 0xd3, 0xe6, 0x9b, 0x1c, 0x47, +0xed, 0xbf, 0xc6, 0xc8, 0x5b, 0xeb, 0x53, 0xae, +0x2f, 0x6d, 0x3c, 0xea, 0x88, 0xa9, 0x35, 0x07, +0x65, 0x3f, 0x6a, 0x8c, 0xf8, 0x55, 0xc6, 0xd7, +0xb7, 0x77, 0x69, 0xf3, 0x59, 0xeb, 0x57, 0xd9, +0x4f, 0xf2, 0x1d, 0x7f, 0x6f, 0x31, 0x4d, 0xbe, +0x79, 0x26, 0xc7, 0x5d, 0x9b, 0x0b, 0x1a, 0xc8, +0xf9, 0x19, 0x1c, 0x77, 0xaf, 0xb9, 0x8f, 0xcb, +0x2b, 0xab, 0x48, 0x92, 0xa4, 0x44, 0xc4, 0x7d, +0xaa, 0x6c, 0xee, 0x9c, 0xd6, 0xeb, 0xf5, 0xd4, +0xe3, 0x63, 0xf2, 0x3e, 0x73, 0xed, 0x76, 0x35, +0x1e, 0x32, 0xb6, 0x2e, 0x62, 0x9a, 0x75, 0xd4, +0x0b, 0x40, 0x85, 0x90, 0xd3, 0x6f, 0xaa, 0xef, +0xb3, 0x0f, 0xdf, 0x43, 0x36, 0x19, 0x57, 0x8e, +0xa0, 0x01, 0x55, 0x62, 0x2d, 0x09, 0xb6, 0x26, +0xc1, 0x6b, 0xe5, 0xa8, 0x03, 0xd6, 0xe0, 0xca, +0x53, 0xd9, 0x4f, 0x94, 0xef, 0x93, 0x34, 0x9a, +0x7a, 0x77, 0x7a, 0x24, 0x30, 0x6d, 0x43, 0xf1, +0x49, 0x76, 0xf2, 0xbd, 0x4f, 0xea, 0xf6, 0x6d, +0xf8, 0x9a, 0xb4, 0xe4, 0x93, 0x06, 0xe5, 0x77, +0x4d, 0xa2, 0xe0, 0x75, 0xf8, 0x24, 0x0e, 0x5e, +0x3e, 0xc7, 0xd5, 0xda, 0x8c, 0xac, 0x76, 0xd4, +0xb5, 0xa5, 0x6e, 0x51, 0x6b, 0xed, 0xf1, 0x49, +0xce, 0x1a, 0x4e, 0x75, 0x52, 0x94, 0xef, 0xbd, +0x26, 0x99, 0x69, 0x9a, 0x10, 0x4d, 0xca, 0x6c, +0xc2, 0xf9, 0x6b, 0x04, 0x55, 0xa6, 0xf5, 0xe5, +0xf7, 0x49, 0x8a, 0x4d, 0xe6, 0xd2, 0x97, 0xd1, +0xff, 0x72, 0x3e, 0xf9, 0x08, 0xb0, 0xc5, 0x7c, +0xf9, 0xd6, 0x97, 0x25, 0x2d, 0x36, 0x9d, 0xbb, +0x72, 0x6c, 0xeb, 0x98, 0x1e, 0x8b, 0x69, 0x93, +0x6d, 0x97, 0xf3, 0x4d, 0xfb, 0x6f, 0xf5, 0xa3, +0xd5, 0x67, 0x5a, 0x7a, 0xdf, 0x3a, 0x93, 0x6d, +0x6d, 0x22, 0x69, 0x5a, 0x63, 0xe1, 0xd3, 0x8c, +0xf8, 0xc6, 0xd7, 0x27, 0xb1, 0x5b, 0x63, 0xa0, +0x8d, 0x85, 0x86, 0xab, 0x35, 0xf6, 0x32, 0xbd, +0x85, 0x97, 0x8f, 0xb1, 0xd1, 0x08, 0xbb, 0x6f, +0x9d, 0xb8, 0x70, 0xae, 0x44, 0x08, 0xb9, 0x6a, +0x9d, 0x13, 0x4f, 0xee, 0x8c, 0xc6, 0x9f, 0x79, +0x1c, 0x71, 0x52, 0xa7, 0x73, 0xa2, 0x6e, 0xc5, +0x69, 0xe7, 0xcf, 0xda, 0x55, 0xa7, 0xd6, 0x25, +0x2c, 0x00, 0x5c, 0x6c, 0x77, 0xdf, 0x95, 0xab, +0xb2, 0x0e, 0xfa, 0x4d, 0xce, 0x65, 0xd2, 0xfe, +0x2d, 0x6f, 0x44, 0x93, 0x04, 0xdb, 0x92, 0xc0, +0x35, 0x4f, 0xf8, 0xca, 0x44, 0x6e, 0xe0, 0xfc, +0x26, 0x4d, 0x11, 0xd4, 0x07, 0x1f, 0x06, 0xeb, +0xb5, 0x84, 0xba, 0x4e, 0x52, 0xd7, 0x36, 0x47, +0x1f, 0xf1, 0xb5, 0x16, 0xb5, 0xb5, 0x18, 0x78, +0xbd, 0x32, 0x9f, 0x55, 0x6e, 0x69, 0xcc, 0x3c, +0xcc, 0x82, 0xfc, 0xef, 0x5b, 0x14, 0xda, 0x66, +0x69, 0x49, 0x08, 0xbe, 0xbe, 0xe1, 0xdf, 0x2c, +0xc9, 0xcf, 0x6a, 0x83, 0xb5, 0xd9, 0x59, 0x75, +0x58, 0x52, 0xb8, 0x86, 0x87, 0xd5, 0xaf, 0x56, +0x3f, 0xd6, 0xa5, 0xd1, 0x38, 0x7e, 0x9f, 0x44, +0xe1, 0xd3, 0xa4, 0x58, 0xf9, 0xad, 0x79, 0xa9, +0x11, 0xdd, 0x7f, 0x17, 0xfd, 0xdf, 0x84, 0x70, +0xf3, 0xf2, 0xac, 0xb9, 0xc7, 0xc7, 0x46, 0x6e, +0xa8, 0x72, 0x9e, 0x59, 0xf9, 0x65, 0x5d, 0x3e, +0x06, 0xc0, 0x22, 0x7c, 0x16, 0xb3, 0x21, 0xcb, +0xf7, 0x31, 0xc4, 0x5a, 0xda, 0x3a, 0x29, 0xb9, +0x8e, 0x18, 0x5b, 0xeb, 0xbf, 0x89, 0xd4, 0x6b, +0x7d, 0xd7, 0xd6, 0x90, 0x85, 0x13, 0x9f, 0x1f, +0x3e, 0xe2, 0xad, 0x8d, 0x97, 0x45, 0x70, 0xad, +0xb9, 0x65, 0x31, 0xc6, 0x5a, 0x5b, 0xea, 0x70, +0x97, 0x7d, 0x56, 0x97, 0xc7, 0x27, 0xe0, 0x38, +0xe3, 0xec, 0x24, 0xcd, 0x90, 0xa5, 0x93, 0x92, +0xf3, 0x1b, 0xff, 0x5f, 0xe9, 0x78, 0x71, 0x7e, +0x9a, 0x9c, 0xe0, 0x80, 0xf2, 0xed, 0x64, 0xd6, +0x2d, 0x65, 0x1a, 0xc1, 0x25, 0x82, 0xc6, 0x8f, +0x93, 0xc9, 0xe3, 0x6a, 0x9a, 0x97, 0xbd, 0x45, +0xd0, 0x35, 0xa6, 0x24, 0x9b, 0x94, 0x9d, 0xc9, +0xa4, 0x4a, 0x5d, 0x3a, 0xb6, 0xc9, 0xdf, 0xda, +0xed, 0x69, 0xbc, 0xac, 0x67, 0x05, 0xcd, 0xe1, +0xef, 0xda, 0x8d, 0x5b, 0xf8, 0xe3, 0x8b, 0xf9, +0x39, 0x4c, 0x1f, 0x17, 0xa9, 0x0d, 0xbc, 0x8f, +0x88, 0x57, 0xea, 0x57, 0xd2, 0x5b, 0x0b, 0xc3, +0xc7, 0xd1, 0xfa, 0x24, 0x52, 0x4b, 0x0a, 0xf3, +0x71, 0xd1, 0xbc, 0xac, 0x3a, 0x09, 0x41, 0xfb, +0x6e, 0x31, 0x15, 0x3e, 0x42, 0xa6, 0x6d, 0x46, +0xd6, 0xa6, 0x2d, 0xfb, 0xd7, 0xda, 0xec, 0x7c, +0xd2, 0x8b, 0xaf, 0x3d, 0x3c, 0x8d, 0x86, 0xab, +0x86, 0xb7, 0x4f, 0xa2, 0x68, 0x32, 0x57, 0xac, +0x79, 0x63, 0x8d, 0x7b, 0xd3, 0xfc, 0x16, 0xfe, +0xff, 0x2e, 0xfb, 0xdf, 0x9a, 0xbf, 0x5a, 0xf9, +0x12, 0x07, 0xdf, 0xfc, 0xb2, 0xc6, 0x4e, 0xf6, +0x77, 0x53, 0x2d, 0x85, 0xfc, 0xaf, 0x11, 0x3e, +0x8b, 0x99, 0xb0, 0xe6, 0x42, 0x93, 0xb2, 0x2d, +0x66, 0xdd, 0xb7, 0xd6, 0x7c, 0x38, 0x34, 0x65, +0xd8, 0xeb, 0xf0, 0xb7, 0x24, 0xde, 0x26, 0xfb, +0x85, 0x36, 0xde, 0x56, 0x7b, 0x7c, 0x63, 0x62, +0xed, 0x3b, 0x1a, 0xe1, 0xb5, 0xf6, 0x36, 0xdf, +0xbe, 0xa9, 0x31, 0x21, 0x3e, 0xe1, 0xc8, 0xea, +0x6f, 0x4a, 0x1b, 0x00, 0xc0, 0xc5, 0x39, 0x3b, +0xde, 0x31, 0x3b, 0x9a, 0xc6, 0x41, 0x12, 0x1a, +0x2e, 0x95, 0xf3, 0xa0, 0x2e, 0x56, 0x20, 0x19, +0x2a, 0x43, 0x23, 0xec, 0x5a, 0x40, 0x18, 0xe9, +0xdd, 0xad, 0x7d, 0xf7, 0x85, 0x48, 0xb5, 0x2e, +0x5b, 0xa1, 0xff, 0x1a, 0x91, 0xd6, 0x9c, 0xe0, +0xe4, 0xef, 0xba, 0xcb, 0x56, 0xae, 0x72, 0xe6, +0x5c, 0xa6, 0x4f, 0x92, 0x04, 0x93, 0x2c, 0x9f, +0x3a, 0x22, 0x46, 0xf1, 0xd4, 0xdf, 0x20, 0x5a, +0xc3, 0xe5, 0x78, 0xce, 0x7c, 0xf8, 0x36, 0x69, +0x6d, 0xf3, 0xe1, 0xf9, 0x24, 0xd4, 0x71, 0xe4, +0xb2, 0xac, 0x26, 0x8b, 0x5b, 0x93, 0xae, 0xac, +0xb2, 0x7c, 0x9b, 0xa5, 0x0f, 0xf7, 0x26, 0x04, +0xdd, 0xc2, 0x4d, 0xf6, 0x99, 0x25, 0x69, 0x58, +0xb8, 0xf0, 0x6f, 0x3e, 0xc6, 0xaa, 0x8e, 0x91, +0x91, 0x38, 0xf8, 0xf0, 0xd3, 0xf0, 0x95, 0x75, +0x68, 0xf3, 0x41, 0xf6, 0x5d, 0x5d, 0x1b, 0x7d, +0xf5, 0xfb, 0xfa, 0x58, 0xe2, 0xe5, 0xc3, 0x41, +0xc3, 0xf3, 0x8b, 0xf6, 0xbf, 0x25, 0xcd, 0xc8, +0x71, 0xb1, 0xa4, 0x57, 0xab, 0x5f, 0xaf, 0x82, +0xb7, 0x55, 0x2e, 0xc7, 0xc3, 0x1a, 0x2f, 0x1f, +0xe1, 0xd6, 0xc6, 0x80, 0xb7, 0x5f, 0xe6, 0xd1, +0xf0, 0xf7, 0xad, 0x03, 0x0d, 0x8f, 0x3a, 0xa2, +0xa5, 0xb5, 0xd5, 0xc2, 0xc7, 0x12, 0x38, 0x7c, +0xe9, 0xad, 0xbd, 0xc4, 0x62, 0x52, 0x65, 0xbb, +0x7d, 0xa0, 0x31, 0x18, 0x75, 0xe5, 0x6a, 0x6d, +0x95, 0xfd, 0xec, 0x63, 0x9c, 0x7d, 0x0c, 0xa0, +0xb6, 0x1f, 0x6a, 0xfd, 0xc5, 0xd3, 0xf8, 0x70, +0x0d, 0xae, 0x6d, 0x5f, 0x77, 0x0f, 0x44, 0xc4, +0xf9, 0x31, 0x35, 0x72, 0x2c, 0x03, 0xe6, 0xe7, +0xbd, 0xf9, 0x35, 0x9d, 0xda, 0x59, 0x70, 0xdf, +0xb9, 0x6a, 0x8d, 0x20, 0x5b, 0x31, 0xd6, 0x7d, +0x76, 0x72, 0x4d, 0x1a, 0x97, 0xef, 0x25, 0x53, +0xc0, 0x19, 0x07, 0xed, 0x32, 0x15, 0xcd, 0x66, +0xce, 0xc1, 0x0a, 0xe3, 0xaa, 0x95, 0xc5, 0xdf, +0xcb, 0xdf, 0xbc, 0x3c, 0x0b, 0x82, 0x76, 0x07, +0x69, 0x67, 0x49, 0x25, 0x5a, 0x9a, 0xf4, 0xa9, +0x4d, 0x82, 0x26, 0x84, 0xcf, 0x52, 0x17, 0xf9, +0xea, 0xf4, 0x11, 0x17, 0x9f, 0x94, 0x2e, 0xcb, +0xd7, 0xda, 0x52, 0xb7, 0x39, 0xf9, 0xda, 0xe5, +0xc6, 0xdd, 0x43, 0x74, 0x78, 0xdd, 0xd6, 0x86, +0xe8, 0x23, 0xa2, 0xda, 0x77, 0x0d, 0x57, 0x5f, +0x1f, 0xf3, 0x72, 0x7c, 0x0b, 0xd9, 0x22, 0x18, +0x4d, 0xb4, 0x32, 0x5a, 0x79, 0x5a, 0x5e, 0x6d, +0xc3, 0xbc, 0x6a, 0xfd, 0x75, 0x52, 0xa0, 0x46, +0x90, 0xb4, 0x77, 0xcf, 0xd2, 0xff, 0x9a, 0x36, +0xc2, 0x22, 0x60, 0x52, 0xaa, 0xb4, 0x34, 0x39, +0x56, 0xdd, 0xbe, 0xf9, 0xa3, 0x31, 0x06, 0x3e, +0xc6, 0xcd, 0xea, 0x3b, 0xd9, 0x2e, 0xdf, 0xba, +0xd2, 0x18, 0xc5, 0x3a, 0x06, 0xd7, 0x1a, 0x1f, +0x9f, 0x90, 0x60, 0x11, 0xed, 0x3a, 0xfc, 0xb4, +0x79, 0xef, 0xc3, 0xdf, 0x9a, 0x23, 0x9a, 0x54, +0xeb, 0x6b, 0xb7, 0xaf, 0x2c, 0x89, 0xbb, 0xb5, +0xfe, 0x9a, 0xae, 0x21, 0x6b, 0xac, 0x9f, 0xa5, +0x3d, 0xbe, 0xf4, 0x75, 0xed, 0x03, 0x66, 0xf7, +0x99, 0x73, 0xa7, 0xb7, 0x24, 0x49, 0x1c, 0x51, +0x1f, 0xe7, 0x05, 0xce, 0xce, 0x2f, 0xb0, 0xba, +0xb2, 0x5c, 0xb9, 0x9a, 0x93, 0x13, 0x76, 0xe9, +0x5d, 0xce, 0xa3, 0xbf, 0xf9, 0xae, 0x1d, 0xd5, +0xa4, 0x75, 0xdf, 0x37, 0x2b, 0x54, 0x2c, 0xa5, +0xe7, 0x8c, 0x07, 0x57, 0xd1, 0xcb, 0x2b, 0x50, +0xa5, 0x5d, 0x9c, 0xa0, 0xa9, 0x54, 0x2e, 0xc1, +0x67, 0x4f, 0x6f, 0x42, 0xe8, 0x2b, 0x7d, 0x30, +0x1a, 0xa1, 0x1d, 0xb4, 0x70, 0x12, 0xea, 0x13, +0x43, 0x5b, 0x80, 0x75, 0x5c, 0xa3, 0x4f, 0xf2, +0xaa, 0x93, 0x50, 0x34, 0x35, 0x95, 0xb5, 0x90, +0x2d, 0xe9, 0xca, 0x92, 0xbe, 0xae, 0x22, 0x61, +0xf0, 0x67, 0xad, 0x3e, 0x4b, 0xc2, 0xf7, 0xa9, +0xec, 0x2c, 0xe9, 0x55, 0x5b, 0x64, 0x16, 0x2e, +0x1a, 0xee, 0x16, 0x81, 0xd2, 0xf0, 0xb1, 0xa4, +0x40, 0x8b, 0x71, 0xd2, 0xe6, 0x84, 0xc4, 0xc3, +0x27, 0x2d, 0x5b, 0xa0, 0xe1, 0xec, 0x63, 0xb4, +0xea, 0xfa, 0x57, 0x23, 0x02, 0x1a, 0x93, 0x58, +0xd7, 0xff, 0x4d, 0x88, 0xa3, 0x56, 0x9e, 0xac, +0x47, 0xe2, 0x63, 0xe1, 0x6c, 0x8d, 0x89, 0x35, +0x7f, 0x34, 0xc2, 0x6e, 0xe1, 0x5d, 0x27, 0x91, +0x5a, 0x4c, 0x8e, 0x25, 0xe1, 0xf9, 0x18, 0x1e, +0x8d, 0x79, 0xf6, 0x8d, 0xbb, 0x4f, 0x1a, 0xaf, +0x23, 0x78, 0xbe, 0xb1, 0xd6, 0x98, 0x5b, 0x2d, +0xad, 0xc5, 0xf8, 0xf9, 0x18, 0x13, 0x59, 0xa6, +0x6f, 0xbf, 0xd0, 0xe6, 0xaa, 0x6f, 0x3f, 0xa9, +0x1b, 0x7f, 0xd9, 0x1f, 0xb2, 0xcd, 0x3e, 0x06, +0x49, 0xe6, 0xf3, 0x09, 0x52, 0x5a, 0x1e, 0x8d, +0x09, 0x0f, 0xf2, 0xed, 0xfd, 0xe9, 0x0b, 0xae, +0x92, 0x1e, 0x8d, 0xd0, 0xeb, 0xf5, 0xd0, 0x0e, +0x5a, 0x25, 0x22, 0x2f, 0x09, 0x39, 0x57, 0xaf, +0x73, 0x82, 0xa9, 0x39, 0xbd, 0x71, 0x15, 0xfd, +0xee, 0xee, 0x6e, 0xe5, 0xec, 0xb8, 0x43, 0xcc, +0x20, 0xd8, 0xf4, 0x8e, 0x9c, 0xdf, 0x2c, 0x87, +0x39, 0xc2, 0xb7, 0x2e, 0x58, 0x8b, 0x76, 0x13, +0x1a, 0x81, 0x46, 0x9c, 0x9f, 0xd5, 0x1e, 0xde, +0xc4, 0x71, 0xce, 0xb5, 0x63, 0xf6, 0xee, 0xff, +0xdf, 0x88, 0x19, 0xe3, 0x30, 0x0c, 0xc3, 0x30, +0xf0, 0xff, 0xaf, 0xec, 0x17, 0x3a, 0x75, 0xee, +0x14, 0x40, 0x60, 0xee, 0x28, 0x4d, 0x71, 0x80, +0xc4, 0xb4, 0x4c, 0x4a, 0xa6, 0xfc, 0x3c, 0x3f, +0xdf, 0xdf, 0x8b, 0xb8, 0x87, 0x3c, 0x13, 0x33, +0x11, 0x6e, 0x09, 0x7d, 0x75, 0xc4, 0x73, 0x4c, +0xae, 0xb2, 0x75, 0x40, 0x97, 0x83, 0x86, 0xdc, +0x3a, 0xe1, 0xcf, 0x79, 0xc8, 0xed, 0x53, 0x21, +0xb5, 0xd8, 0xd2, 0x95, 0xdb, 0x0d, 0x86, 0x19, +0x99, 0xf9, 0xcd, 0x16, 0xc3, 0xb6, 0x9e, 0x36, +0xbe, 0x74, 0x5a, 0x13, 0x67, 0xeb, 0xc6, 0xe8, +0xd0, 0xb9, 0xf0, 0x6d, 0x73, 0x34, 0xed, 0x34, +0xfc, 0xad, 0x98, 0x9b, 0x79, 0xb4, 0x83, 0x21, +0xdf, 0xf3, 0x3f, 0xd3, 0x28, 0xe5, 0x47, 0x8b, +0x3d, 0x73, 0x8e, 0x8c, 0x5b, 0xae, 0x6b, 0x72, +0x44, 0x78, 0x6d, 0x1f, 0x0d, 0x9b, 0xcc, 0x26, +0x71, 0x63, 0x1d, 0x76, 0xce, 0x63, 0x9a, 0x21, +0x8d, 0x27, 0x0f, 0x74, 0xe3, 0x40, 0xfb, 0x91, +0x3a, 0x30, 0xbd, 0x6e, 0x1d, 0x69, 0xab, 0x15, +0x86, 0x63, 0x75, 0xc3, 0x72, 0x8c, 0xb4, 0x90, +0xf8, 0xd7, 0x1b, 0x8b, 0x56, 0x7f, 0x9b, 0x59, +0xb6, 0x5a, 0x6b, 0xbc, 0xff, 0x01, 0x60, 0x63, +0x14, 0x55, 0xdf, 0x32, 0x10, 0xa1, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *splash_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_splash_png = new wxImage(); + if (!img_splash_png || !img_splash_png->IsOk()) + { + wxMemoryInputStream img_splash_pngIS(splash_png_data, sizeof(splash_png_data)); + img_splash_png->LoadFile(img_splash_pngIS, wxBITMAP_TYPE_PNG); + } + return img_splash_png; +} +#define splash_png_img splash_png_img() + +static wxBitmap *splash_png_bmp() +{ + static wxBitmap *bmp_splash_png; + if (!bmp_splash_png || !bmp_splash_png->IsOk()) + bmp_splash_png = new wxBitmap(*splash_png_img); + return bmp_splash_png; +} +#define splash_png_bmp splash_png_bmp() + +static wxIcon *splash_png_ico() +{ + static wxIcon *ico_splash_png; + if (!ico_splash_png || !ico_splash_png->IsOk()) + { + ico_splash_png = new wxIcon(); + ico_splash_png->CopyFromBitmap(*splash_png_bmp); + } + return ico_splash_png; +} +#define splash_png_ico splash_png_ico() + +#endif // SPLASH_PNG_H diff --git a/include/images/sql-16.png b/include/images/sql-16.png new file mode 100644 index 0000000..01246de Binary files /dev/null and b/include/images/sql-16.png differ diff --git a/include/images/sql-16.pngc b/include/images/sql-16.pngc new file mode 100644 index 0000000..72b6f39 --- /dev/null +++ b/include/images/sql-16.pngc @@ -0,0 +1,173 @@ +#ifndef SQL_16_PNG_H +#define SQL_16_PNG_H + +static const unsigned char sql_16_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x02, 0x3a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xeb, +0xea, 0xea, 0xd4, 0xd3, 0xcd, 0xcd, 0xca, 0xc0, +0xcd, 0xcb, 0xc0, 0xd4, 0xd2, 0xcc, 0xfa, 0xfa, +0xfa, 0xc5, 0xbd, 0xaa, 0xd6, 0xbb, 0x70, 0xf5, +0xca, 0x5d, 0xf6, 0xd0, 0x5e, 0xf5, 0xd6, 0x61, +0xf5, 0xda, 0x63, 0xf4, 0xdb, 0x63, 0xf3, 0xd8, +0x63, 0xd5, 0xbf, 0x72, 0xc6, 0xc0, 0xad, 0xf7, +0xf7, 0xf7, 0xcd, 0xb2, 0x78, 0xf7, 0xca, 0x5c, +0xf7, 0xc5, 0x5b, 0xf2, 0xc4, 0x5b, 0xdb, 0xbd, +0x6b, 0xcb, 0xbb, 0x7f, 0xc6, 0xbb, 0x88, 0xca, +0xbe, 0x84, 0xd3, 0xc0, 0x6f, 0xee, 0xcf, 0x5f, +0xf6, 0xce, 0x5e, 0xce, 0xb7, 0x7b, 0xf6, 0xf6, +0xf6, 0xc4, 0xb8, 0xa2, 0xf7, 0xc2, 0x59, 0xdc, +0xb5, 0x69, 0xba, 0xb3, 0xa4, 0xc2, 0xc2, 0xc3, +0xc9, 0xc9, 0xca, 0xca, 0xc9, 0xca, 0xca, 0xca, +0xca, 0xcb, 0xca, 0xcb, 0xc8, 0xc4, 0xb9, 0xd4, +0xb7, 0x6f, 0xf6, 0xc5, 0x5a, 0xc4, 0xba, 0x9f, +0xcd, 0xab, 0x75, 0xf7, 0xbe, 0x58, 0xd6, 0xb2, +0x69, 0xbb, 0xba, 0xb8, 0xd0, 0xd0, 0xd0, 0xdb, +0xdb, 0xdc, 0xe5, 0xe5, 0xe6, 0xdc, 0xdc, 0xdc, +0xd5, 0xd5, 0xd6, 0xd6, 0xd6, 0xd7, 0xd3, 0xd2, +0xd3, 0xda, 0xd9, 0xd9, 0xd0, 0xaf, 0x70, 0xd4, +0xb4, 0x6e, 0xce, 0xa3, 0x71, 0xf0, 0xb4, 0x56, +0xb3, 0xae, 0xa4, 0xc5, 0xc5, 0xc5, 0x73, 0x73, +0x73, 0x82, 0x82, 0x82, 0xc6, 0xc6, 0xc6, 0x80, +0x80, 0x81, 0x7d, 0x7d, 0x7d, 0xa7, 0xa7, 0xa8, +0xac, 0xac, 0xad, 0xdf, 0xde, 0xdf, 0xc7, 0xc4, +0xbe, 0xcf, 0xa2, 0x66, 0xce, 0xa3, 0x70, 0xd6, +0x9c, 0x57, 0xa7, 0xa9, 0xa9, 0xd0, 0xd0, 0xd1, +0xa6, 0xa6, 0xa7, 0x74, 0x74, 0x75, 0x8f, 0x90, +0x90, 0xd5, 0xd5, 0xd5, 0x87, 0x87, 0x88, 0xb5, +0xb5, 0xb5, 0xf3, 0xf4, 0xf4, 0xcf, 0xce, 0xcf, +0xbb, 0xa1, 0x76, 0xcd, 0xa3, 0x73, 0xd7, 0x9f, +0x56, 0xa4, 0xa4, 0xa5, 0xd0, 0xcf, 0xd0, 0x8b, +0x8b, 0x8b, 0x81, 0x81, 0x82, 0xce, 0xce, 0xce, +0x7e, 0x7e, 0x7e, 0x4f, 0x4f, 0x4f, 0xa7, 0xa7, +0xa7, 0x7b, 0x7b, 0x7b, 0xa9, 0xa9, 0xa9, 0xc7, +0xc7, 0xc7, 0xbf, 0x9b, 0x71, 0xce, 0xa4, 0x71, +0xf2, 0xa9, 0x51, 0xa6, 0x9e, 0x8f, 0xcd, 0xce, +0xcf, 0xe6, 0xe6, 0xe6, 0xfc, 0xfc, 0xfc, 0xfb, +0xfb, 0xfc, 0xfa, 0xfa, 0xfb, 0xf5, 0xf5, 0xf6, +0xdd, 0xdd, 0xde, 0xbd, 0xb3, 0xaa, 0xcf, 0xa6, +0x69, 0xd3, 0x96, 0x4c, 0x93, 0x7d, 0x5c, 0xd1, +0xd0, 0xd0, 0xe0, 0xdf, 0xdf, 0xec, 0xec, 0xec, +0xd6, 0xd5, 0xd6, 0xbf, 0xbb, 0xb8, 0xd9, 0xad, +0x66, 0xd8, 0xa6, 0x66, 0xf9, 0xf9, 0xf9, 0x83, +0x6f, 0x5b, 0x33, 0x33, 0x35, 0x2f, 0x31, 0x32, +0x75, 0x6c, 0x5c, 0xab, 0x9c, 0x7b, 0xa2, 0xa4, +0xa2, 0xc0, 0xc1, 0xc2, 0xd2, 0xd2, 0xd3, 0xd7, +0xd7, 0xd8, 0xd3, 0xd3, 0xd2, 0xc5, 0xba, 0x9e, +0xe1, 0xb4, 0x61, 0xf7, 0xa9, 0x51, 0xce, 0xa8, +0x74, 0x56, 0x58, 0x5c, 0x30, 0x31, 0x34, 0x30, +0x31, 0x32, 0x4e, 0x44, 0x35, 0xcf, 0xaa, 0x52, +0xf5, 0xd0, 0x5f, 0xe6, 0xc8, 0x61, 0xd7, 0xc1, +0x77, 0xe0, 0xcc, 0x84, 0xe4, 0xcc, 0x7d, 0xe7, +0xc3, 0x61, 0xf6, 0xbf, 0x58, 0xf7, 0xaf, 0x52, +0xf6, 0xac, 0x51, 0xc8, 0xa7, 0x80, 0x48, 0x48, +0x47, 0x52, 0x51, 0x50, 0x86, 0x69, 0x47, 0xec, +0xb5, 0x56, 0xf6, 0xc5, 0x5b, 0xf5, 0xd3, 0x66, +0xf6, 0xd9, 0x77, 0xf5, 0xd8, 0x68, 0xf5, 0xcf, +0x5e, 0xf6, 0xc3, 0x5a, 0xf7, 0xb9, 0x56, 0xf5, +0xa3, 0x50, 0xd4, 0xd0, 0xca, 0x6e, 0x6d, 0x6d, +0xb9, 0xb9, 0xb9, 0xc6, 0xbb, 0xad, 0xf1, 0xae, +0x56, 0xf5, 0xd4, 0x61, 0xf4, 0xde, 0x6c, 0xf5, +0xe0, 0x79, 0xf4, 0xde, 0x68, 0xf4, 0xd8, 0x62, +0xf6, 0xcc, 0x5d, 0xf7, 0xbb, 0x57, 0xf1, 0xab, +0x55, 0xc7, 0xbc, 0xac, 0xe0, 0xe1, 0xe1, 0xde, +0xdc, 0xda, 0xc6, 0xae, 0x87, 0xea, 0xbb, 0x60, +0xf6, 0xc8, 0x5c, 0xf6, 0xcf, 0x63, 0xf6, 0xce, +0x5f, 0xf6, 0xc7, 0x5c, 0xe9, 0xba, 0x60, 0xc6, +0xaf, 0x87, 0xde, 0xdd, 0xda, 0xd2, 0xcf, 0xc9, +0xdf, 0xde, 0xdb, 0x15, 0xd3, 0xea, 0xd6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x01, 0x03, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x00, 0x02, 0x46, +0x26, 0x66, 0x16, 0x56, 0x36, 0x26, 0x46, 0x06, +0x08, 0x60, 0xe7, 0xe0, 0xe4, 0xe2, 0xe6, 0xe1, +0xe5, 0xe3, 0x17, 0x10, 0x64, 0x07, 0xf1, 0x85, +0x84, 0x45, 0x44, 0xc5, 0xc4, 0x25, 0x24, 0xa5, +0xa4, 0x65, 0x64, 0xe5, 0xe4, 0x81, 0x02, 0x0a, +0x8a, 0xa2, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, +0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0x40, 0x01, 0x5d, +0x3d, 0x7d, 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, +0x33, 0x73, 0x0b, 0x4b, 0x2b, 0xa0, 0x80, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0x83, 0xa3, 0x93, 0xb3, +0x8b, 0xab, 0x9b, 0xbb, 0x07, 0x50, 0xc0, 0xd3, +0xcb, 0xdb, 0xc7, 0xd7, 0xcf, 0x3f, 0x40, 0x25, +0x30, 0x28, 0x38, 0x24, 0x14, 0x28, 0x10, 0x16, +0x1e, 0x11, 0x19, 0x15, 0x1d, 0x13, 0x1b, 0x17, +0x9f, 0x90, 0x98, 0x94, 0x0c, 0x14, 0x48, 0x49, +0x4d, 0x4b, 0xcf, 0xc8, 0xcc, 0xcc, 0xca, 0xce, +0xc9, 0xce, 0xcd, 0xcb, 0x07, 0x69, 0x29, 0x28, +0x0c, 0x28, 0x2a, 0x2e, 0xc9, 0xcc, 0x2a, 0x29, +0x2d, 0x2b, 0xaf, 0x60, 0x60, 0xa8, 0xac, 0xaa, +0xae, 0xa9, 0xad, 0xab, 0x6f, 0x68, 0x6c, 0x6a, +0x6e, 0x69, 0x6d, 0x6b, 0x67, 0x60, 0xe8, 0xe8, +0xec, 0xea, 0xee, 0xe9, 0xed, 0xeb, 0x9f, 0x30, +0x71, 0xd2, 0xe4, 0x29, 0x53, 0xa7, 0x31, 0x30, +0x4c, 0x9f, 0x31, 0x73, 0x96, 0xde, 0xec, 0x39, +0x73, 0xe7, 0xcd, 0x5f, 0xa0, 0xb7, 0x70, 0xd1, +0x62, 0x06, 0x86, 0x25, 0x4b, 0x97, 0x2d, 0x9f, +0xbd, 0x62, 0xe5, 0xaa, 0xd5, 0x6b, 0xd6, 0xae, +0x5b, 0xbf, 0x01, 0x68, 0xe6, 0x46, 0x06, 0x86, +0x4d, 0x9b, 0xb7, 0x6c, 0xdd, 0xb6, 0x7d, 0xc7, +0xce, 0x5d, 0xbb, 0x19, 0x60, 0xa0, 0x72, 0xf7, +0x9e, 0x3d, 0x7b, 0xc1, 0x5e, 0x65, 0x00, 0x00, +0xbc, 0xb5, 0x4c, 0x09, 0x25, 0x97, 0x54, 0xcb, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x38, 0x54, +0x30, 0x31, 0x3a, 0x30, 0x33, 0x3a, 0x35, 0x39, +0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0x68, 0xc6, +0x93, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sql_16_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sql_16_png = new wxImage(); + if (!img_sql_16_png || !img_sql_16_png->IsOk()) + { + wxMemoryInputStream img_sql_16_pngIS(sql_16_png_data, sizeof(sql_16_png_data)); + img_sql_16_png->LoadFile(img_sql_16_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sql_16_png; +} +#define sql_16_png_img sql_16_png_img() + +static wxBitmap *sql_16_png_bmp() +{ + static wxBitmap *bmp_sql_16_png; + if (!bmp_sql_16_png || !bmp_sql_16_png->IsOk()) + bmp_sql_16_png = new wxBitmap(*sql_16_png_img); + return bmp_sql_16_png; +} +#define sql_16_png_bmp sql_16_png_bmp() + +static wxIcon *sql_16_png_ico() +{ + static wxIcon *ico_sql_16_png; + if (!ico_sql_16_png || !ico_sql_16_png->IsOk()) + { + ico_sql_16_png = new wxIcon(); + ico_sql_16_png->CopyFromBitmap(*sql_16_png_bmp); + } + return ico_sql_16_png; +} +#define sql_16_png_ico sql_16_png_ico() + +#endif // SQL_16_PNG_H diff --git a/include/images/sql-32.png b/include/images/sql-32.png new file mode 100644 index 0000000..450e2c4 Binary files /dev/null and b/include/images/sql-32.png differ diff --git a/include/images/sql-32.pngc b/include/images/sql-32.pngc new file mode 100644 index 0000000..09714f7 --- /dev/null +++ b/include/images/sql-32.pngc @@ -0,0 +1,265 @@ +#ifndef SQL_32_PNG_H +#define SQL_32_PNG_H + +static const unsigned char sql_32_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x02, 0xeb, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xfa, 0xfa, 0xfa, 0xe5, +0xe5, 0xe5, 0xcd, 0xca, 0xc3, 0xc2, 0xba, 0xaa, +0xbe, 0xb5, 0x96, 0xbe, 0xb1, 0x8c, 0xc0, 0xb3, +0x8a, 0xc2, 0xbc, 0xa8, 0xce, 0xcc, 0xc5, 0xdc, +0xdb, 0xdc, 0xd0, 0xb4, 0x6d, 0xf0, 0xcb, 0x5f, +0xf5, 0xcd, 0x5d, 0xf5, 0xd0, 0x5e, 0xf4, 0xd4, +0x61, 0xf4, 0xd9, 0x62, 0xf4, 0xdc, 0x63, 0xce, +0xba, 0x72, 0xbe, 0xb3, 0x9c, 0xe1, 0xe1, 0xe1, +0xfa, 0xfb, 0xfc, 0xe8, 0xe8, 0xe8, 0xc0, 0xaf, +0x8a, 0xef, 0xc6, 0x60, 0xf6, 0xc9, 0x5c, 0xf6, +0xc6, 0x5c, 0xec, 0xcb, 0x62, 0xbf, 0xb4, 0x90, +0xec, 0xec, 0xeb, 0xd4, 0xd3, 0xd3, 0xdc, 0xb6, +0x66, 0xf6, 0xc4, 0x5a, 0xee, 0xcf, 0x5e, 0xe4, +0xca, 0x5d, 0xda, 0xc5, 0x60, 0xdf, 0xca, 0x60, +0xe9, 0xd2, 0x61, 0xf1, 0xd8, 0x62, 0xd9, 0xbd, +0x6b, 0xd8, 0xd7, 0xd3, 0xde, 0xde, 0xdb, 0xe1, +0xb8, 0x62, 0xf6, 0xc1, 0x59, 0xe8, 0xbb, 0x58, +0xca, 0xaf, 0x6c, 0xb7, 0xa9, 0x85, 0xae, 0xa9, +0x99, 0xac, 0xac, 0xac, 0xb3, 0xb1, 0xae, 0xb2, +0xb3, 0xb3, 0xae, 0xa9, 0xa3, 0xac, 0xa5, 0x88, +0xba, 0xab, 0x70, 0xdb, 0xc2, 0x5e, 0xe1, 0xc0, +0x65, 0xc6, 0xaa, 0x79, 0xeb, 0xb9, 0x57, 0xc3, +0xa9, 0x73, 0xb4, 0xaf, 0xa5, 0xb9, 0xb9, 0xb9, +0xb7, 0xb8, 0xb9, 0xba, 0xba, 0xbc, 0xc4, 0xc3, +0xc4, 0xc7, 0xc7, 0xc8, 0xcc, 0xcb, 0xcc, 0xb8, +0xb6, 0xb2, 0xaf, 0xa1, 0x77, 0xde, 0xbb, 0x5c, +0xca, 0xb5, 0x78, 0xf3, 0xbf, 0x58, 0xf6, 0xbe, +0x58, 0xdb, 0xb2, 0x5c, 0xb6, 0xaa, 0x97, 0xbe, +0xbe, 0xbe, 0xb5, 0xb6, 0xb8, 0xc0, 0xbf, 0xbd, +0xd6, 0xd7, 0xd8, 0xd0, 0xce, 0xcf, 0xcf, 0xcf, +0xd0, 0xb5, 0xb0, 0xa7, 0xc6, 0xa7, 0x5f, 0xf3, +0xc1, 0x59, 0xd0, 0xce, 0xc8, 0xc1, 0xb6, 0xa5, +0xf6, 0xbc, 0x57, 0xd3, 0xac, 0x5a, 0xaf, 0xb0, +0xb1, 0xda, 0xda, 0xdb, 0xef, 0xef, 0xf0, 0xc1, +0xa1, 0x60, 0xc0, 0xb2, 0x95, 0xbd, 0xa6, 0x8a, +0xf7, 0xb9, 0x56, 0xe1, 0xb1, 0x57, 0xab, 0xa5, +0x99, 0xc7, 0xc8, 0xc8, 0xdb, 0xdb, 0xdc, 0xdd, +0xdd, 0xdd, 0xe7, 0xe8, 0xe8, 0xec, 0xed, 0xed, +0xd0, 0xcf, 0xd0, 0xf6, 0xb0, 0x53, 0xf2, 0xb9, +0x56, 0xb1, 0x9c, 0x77, 0xbe, 0xbf, 0xc0, 0xa3, +0xa3, 0xa4, 0x3f, 0x40, 0x40, 0x43, 0x43, 0x43, +0x53, 0x52, 0x52, 0x5c, 0x5c, 0x5c, 0x67, 0x66, +0x66, 0x92, 0x92, 0x92, 0x76, 0x75, 0x75, 0xe3, +0xe3, 0xe4, 0xa9, 0x9e, 0x84, 0xed, 0xb4, 0x55, +0xc9, 0xa3, 0x73, 0xbf, 0xb5, 0xa0, 0xf6, 0xa2, +0x4e, 0xf6, 0xb5, 0x55, 0xda, 0xac, 0x55, 0x99, +0x97, 0x94, 0xc8, 0xc7, 0xc7, 0x61, 0x61, 0x61, +0x8a, 0x8a, 0x8b, 0x82, 0x83, 0x83, 0x71, 0x71, +0x72, 0x9e, 0x9e, 0x9e, 0xe7, 0xe7, 0xe8, 0xbc, +0xba, 0xba, 0xd1, 0x91, 0x53, 0xc1, 0xaa, 0x84, +0xc0, 0xb3, 0x9d, 0xf6, 0xad, 0x51, 0xbf, 0x99, +0x5e, 0xf1, 0xf1, 0xf1, 0x3b, 0x3b, 0x3b, 0x9f, +0x9f, 0xa0, 0x99, 0x99, 0x99, 0xf2, 0xf2, 0xf4, +0xef, 0xf0, 0xf1, 0xbc, 0x93, 0x6a, 0xf7, 0x9e, +0x4c, 0xae, 0x8c, 0x61, 0x79, 0x7a, 0x7d, 0xf5, +0xf5, 0xf5, 0xcb, 0xca, 0xc6, 0x97, 0x99, 0x9a, +0x8d, 0x8e, 0x90, 0x79, 0x79, 0x79, 0xf7, 0xf7, +0xf8, 0xb3, 0xa2, 0x7c, 0xc6, 0xa5, 0x75, 0xae, +0x83, 0x5a, 0x4b, 0x4b, 0x4b, 0x33, 0x34, 0x34, +0xb7, 0x94, 0x73, 0xc3, 0x98, 0x57, 0xa4, 0xa6, +0xa8, 0x64, 0x61, 0x5e, 0x6c, 0x6c, 0x6c, 0xc4, +0x8f, 0x61, 0xc1, 0xaa, 0x88, 0xf7, 0xa9, 0x50, +0xe4, 0xa9, 0x53, 0x99, 0x93, 0x8a, 0xdb, 0x94, +0x4e, 0xf6, 0xb2, 0x54, 0xb8, 0x99, 0x64, 0xe3, +0xa6, 0x50, 0xa0, 0x93, 0x79, 0xaf, 0x9f, 0x93, +0x7d, 0x62, 0x40, 0x4c, 0x43, 0x38, 0x7a, 0x75, +0x6e, 0xae, 0xa2, 0x93, 0xb1, 0x7d, 0x44, 0x47, +0x40, 0x3e, 0x2f, 0x30, 0x33, 0x2b, 0x2d, 0x2e, +0x8d, 0x88, 0x7e, 0x92, 0x90, 0x8d, 0xe5, 0xba, +0x59, 0x31, 0x32, 0x3a, 0x2c, 0x2e, 0x30, 0x99, +0x7d, 0x46, 0xaa, 0x98, 0x6e, 0x90, 0x8e, 0x87, +0x8f, 0x92, 0x93, 0x95, 0x97, 0x99, 0xd2, 0xaf, +0x60, 0xbf, 0xaf, 0x94, 0x46, 0x47, 0x4f, 0x72, +0x65, 0x3e, 0xe5, 0xba, 0x57, 0xca, 0xab, 0x5d, +0xba, 0xa5, 0x6f, 0xba, 0xad, 0x86, 0xc8, 0xbd, +0x9e, 0xd2, 0xc7, 0xa9, 0xd5, 0xc7, 0xa4, 0xd5, +0xbf, 0x8e, 0x34, 0x36, 0x40, 0x37, 0x38, 0x37, +0x3d, 0x3a, 0x34, 0xa4, 0x7b, 0x44, 0xf3, 0xe2, +0x66, 0xf4, 0xde, 0x65, 0xf4, 0xdc, 0x6b, 0xf5, +0xda, 0x74, 0xf5, 0xd7, 0x72, 0x62, 0x56, 0x41, +0xd0, 0xa0, 0x50, 0xf4, 0xe4, 0x7c, 0xf5, 0xe6, +0x91, 0xce, 0xa4, 0x6d, 0x8b, 0x6b, 0x4a, 0xe9, +0x9e, 0x4d, 0xef, 0xa3, 0x54, 0xd4, 0xd2, 0xcd, +0xc3, 0xbb, 0xb0, 0xef, 0xa6, 0x54, 0xf0, 0xa8, +0x54, 0xc5, 0xbe, 0xb2, 0x69, 0x67, 0x66, 0xcb, +0xc6, 0xc0, 0xe1, 0xa7, 0x5e, 0xf3, 0xe8, 0x6a, +0xf4, 0xef, 0x85, 0xf5, 0xf0, 0x96, 0xf5, 0xee, +0x90, 0xf3, 0xec, 0x79, 0xe2, 0xab, 0x5e, 0xcb, +0xc7, 0xbf, 0xc0, 0xaa, 0x8c, 0xed, 0xb3, 0x59, +0xf6, 0xcb, 0x66, 0xf6, 0xce, 0x68, 0xf6, 0xce, +0x63, 0xc0, 0xad, 0x8d, 0xe5, 0xe4, 0xe3, 0xce, +0xac, 0x71, 0xf0, 0xbe, 0x5c, 0xef, 0xbe, 0x5d, +0xc1, 0xb5, 0xa0, 0xc0, 0xb2, 0x9b, 0xbf, 0xb0, +0x94, 0xc4, 0xbc, 0xad, 0xae, 0x11, 0x7b, 0x5c, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x03, 0x2d, 0x49, 0x44, +0x41, 0x54, 0x38, 0xcb, 0x63, 0x60, 0x20, 0x1a, +0x30, 0x32, 0x31, 0xb3, 0xb0, 0xb2, 0xb1, 0xb3, +0xb3, 0xb3, 0x72, 0x70, 0x32, 0x31, 0x62, 0x48, +0x73, 0xb1, 0x72, 0xf3, 0xf0, 0xf2, 0xf2, 0xf1, +0x0b, 0x08, 0x08, 0x08, 0x0a, 0x08, 0xf0, 0x0b, +0x09, 0x8b, 0x88, 0x22, 0x4b, 0x8b, 0x89, 0x4b, +0xf0, 0x49, 0x4a, 0x49, 0x42, 0x15, 0x08, 0x82, +0x94, 0x48, 0xcb, 0xc8, 0x22, 0xe4, 0xe5, 0xe4, +0x25, 0x25, 0x25, 0x15, 0x14, 0x80, 0x0a, 0x14, +0x95, 0x94, 0x95, 0x55, 0x54, 0xd5, 0x04, 0xf8, +0xf9, 0xf9, 0x78, 0xd5, 0x35, 0x60, 0xf2, 0x9a, +0x5a, 0x0a, 0x52, 0x92, 0x0a, 0xda, 0x0a, 0x3a, +0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0x86, 0xc6, +0x26, 0xa6, 0x66, 0x8a, 0xbc, 0x92, 0x92, 0xe6, +0x9a, 0x50, 0xd7, 0x59, 0x68, 0x03, 0x75, 0x6b, +0x5b, 0x5a, 0x59, 0xdb, 0xd8, 0xda, 0xd9, 0x03, +0x81, 0x83, 0xa3, 0xa3, 0x93, 0xb3, 0x8b, 0xa4, +0x94, 0x82, 0x2b, 0xc4, 0xad, 0x1a, 0x6e, 0xee, +0x40, 0x15, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, +0x72, 0x7e, 0x40, 0xe0, 0xef, 0xe8, 0x20, 0xc7, +0x14, 0x10, 0x18, 0xa4, 0x20, 0x19, 0x0c, 0x56, +0x10, 0x12, 0xea, 0xae, 0xad, 0x1d, 0x66, 0x6d, +0x1f, 0x2e, 0xc7, 0xe4, 0x1b, 0xc1, 0x15, 0x21, +0xe7, 0x2b, 0x07, 0x04, 0x8e, 0x91, 0x3e, 0x51, +0x6e, 0x0a, 0xd1, 0x60, 0x05, 0x31, 0xb1, 0xa1, +0xee, 0x71, 0xf1, 0x09, 0xe1, 0x89, 0x49, 0x8e, +0xc9, 0x29, 0x91, 0x29, 0x72, 0xfe, 0x89, 0x5c, +0xbe, 0xa9, 0x89, 0x7e, 0x62, 0x86, 0x61, 0x0a, +0x16, 0x10, 0x05, 0x69, 0xb1, 0xe9, 0x19, 0x76, +0x99, 0xf6, 0x59, 0xd9, 0x39, 0xb9, 0x4c, 0x22, +0x79, 0x39, 0x39, 0xf9, 0x89, 0x05, 0x85, 0x22, +0x45, 0x8e, 0x45, 0xc5, 0x25, 0xa5, 0x60, 0x05, +0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x06, 0x4c, +0x35, 0xb5, 0x4c, 0xb5, 0x8e, 0x75, 0xf5, 0x91, +0x29, 0x79, 0x0d, 0x05, 0xf5, 0x62, 0x8d, 0x22, +0x72, 0x4d, 0xcd, 0x2d, 0x60, 0x05, 0xad, 0xe5, +0x6d, 0xed, 0xb5, 0x8e, 0x06, 0x1d, 0x46, 0x9d, +0x39, 0x75, 0xb2, 0x79, 0xb6, 0x8c, 0x8c, 0x5d, +0xf5, 0xdd, 0x85, 0x3d, 0xbd, 0x1d, 0x8e, 0x8e, +0x7d, 0x6c, 0x50, 0x2b, 0xfa, 0x27, 0x4c, 0x4c, +0x0d, 0x9f, 0x34, 0x59, 0xc4, 0x2e, 0x77, 0x4a, +0x8d, 0xc1, 0x24, 0x91, 0xa9, 0xd3, 0xba, 0x0b, +0x27, 0x4d, 0x9a, 0x9e, 0x9a, 0x3a, 0x63, 0x26, +0x44, 0x41, 0x5b, 0xdb, 0xac, 0xba, 0x04, 0xa3, +0x94, 0xbc, 0x3a, 0xfb, 0xdc, 0x2c, 0x83, 0xd9, +0x59, 0xd9, 0x73, 0xbc, 0xba, 0xf3, 0x8c, 0xbc, +0xe5, 0x1c, 0x1d, 0xe7, 0x96, 0x82, 0x23, 0x24, +0xa4, 0xbc, 0x62, 0xde, 0x54, 0x20, 0x3f, 0xa2, +0x3e, 0x6f, 0x6a, 0xc7, 0xf4, 0xf9, 0x0b, 0xf2, +0xf3, 0x6a, 0x6d, 0x17, 0x2e, 0xac, 0x9f, 0x6f, +0x9f, 0xb9, 0x68, 0x31, 0xd4, 0x91, 0x4b, 0x96, +0x2e, 0x9b, 0x9f, 0x94, 0x29, 0xcb, 0xc0, 0x28, +0x2a, 0x0a, 0xc2, 0xd3, 0x99, 0x18, 0xa7, 0x33, +0x8a, 0xca, 0xa5, 0x1a, 0x2f, 0x87, 0xba, 0x61, +0x45, 0x7f, 0xda, 0xca, 0xf9, 0x46, 0xc9, 0xf6, +0xb2, 0xa2, 0x0c, 0xa2, 0x10, 0x00, 0x54, 0x25, +0xe2, 0xe0, 0x35, 0x37, 0x1d, 0xe6, 0x86, 0xb4, +0xf2, 0x55, 0xab, 0x6d, 0x23, 0x3a, 0x52, 0xe5, +0x80, 0x61, 0x0f, 0x54, 0x04, 0x34, 0x65, 0xba, +0x9c, 0xbd, 0xfd, 0x9a, 0xa5, 0xb1, 0x90, 0x70, +0x10, 0x2e, 0x5f, 0xb5, 0x76, 0xdd, 0x7a, 0x11, +0x11, 0x03, 0xb9, 0xc6, 0x6a, 0x47, 0x26, 0xa0, +0xe1, 0xd3, 0x93, 0x53, 0xed, 0x13, 0xec, 0x37, +0x54, 0xba, 0xf7, 0x43, 0xdc, 0x10, 0xb3, 0x71, +0xd3, 0xe6, 0x2d, 0xd9, 0xd3, 0xb6, 0x6e, 0x9b, +0x92, 0x95, 0x20, 0xe2, 0x0b, 0x8c, 0xcd, 0xcc, +0x04, 0x39, 0xc7, 0xa6, 0x19, 0xdb, 0x43, 0xcb, +0xcb, 0xcb, 0x40, 0xf2, 0x4c, 0x0b, 0x76, 0xec, +0xdc, 0xb2, 0x65, 0xcb, 0x9c, 0x5d, 0x95, 0xbb, +0xf7, 0xec, 0xdd, 0xe7, 0xed, 0x9b, 0x2c, 0x9b, +0xd2, 0x38, 0x99, 0x6d, 0xbf, 0x5b, 0xc5, 0x92, +0xfe, 0xb4, 0x03, 0x40, 0x79, 0xa3, 0x83, 0x3b, +0xb6, 0x80, 0xc0, 0xa1, 0xc3, 0xda, 0xda, 0x3a, +0x47, 0x8e, 0x1e, 0x3b, 0x7e, 0xe2, 0xe4, 0x29, +0xee, 0xb8, 0x20, 0xf7, 0xd8, 0x25, 0xe5, 0x6d, +0xe5, 0x21, 0x40, 0x05, 0xa7, 0x37, 0xef, 0x9c, +0x73, 0x66, 0xce, 0xd9, 0x73, 0xe9, 0x7c, 0x82, +0xe7, 0x2f, 0x5c, 0xbc, 0x74, 0x59, 0x8d, 0x1f, +0x08, 0xf8, 0x14, 0x62, 0xdb, 0x96, 0x54, 0x2c, +0x29, 0x97, 0x03, 0x2a, 0x38, 0xd3, 0x39, 0x7b, +0x76, 0xce, 0x95, 0xab, 0x15, 0xb1, 0xb1, 0xda, +0xbc, 0xfc, 0xd7, 0xae, 0x5f, 0xbf, 0x76, 0x5e, +0x80, 0x4f, 0xca, 0x3d, 0xb6, 0xa2, 0xc2, 0xbd, +0xad, 0xff, 0x06, 0x28, 0x45, 0xcd, 0xae, 0xc9, +0xcb, 0xbd, 0x79, 0x2b, 0x56, 0x41, 0x01, 0x94, +0xee, 0x24, 0x25, 0x81, 0x49, 0x11, 0x98, 0xd6, +0xb4, 0x15, 0xa4, 0x80, 0xf2, 0xb7, 0xef, 0x80, +0xdc, 0x58, 0x98, 0xbf, 0xc0, 0xf6, 0xee, 0xbd, +0x25, 0xb1, 0x92, 0x20, 0x93, 0x41, 0x00, 0x4c, +0x4a, 0xc6, 0xa6, 0x95, 0xdf, 0x7f, 0x00, 0xf6, +0xe4, 0xc3, 0x69, 0x49, 0x0c, 0x0c, 0x8f, 0x1e, +0xaf, 0xa8, 0x70, 0xe7, 0x15, 0x78, 0xf2, 0xf4, +0xd9, 0xf3, 0x17, 0x4f, 0xce, 0x0b, 0xf0, 0x6a, +0xc7, 0xae, 0x48, 0x7b, 0xf9, 0x0a, 0x92, 0xa6, +0xbb, 0x27, 0x81, 0x73, 0xce, 0xeb, 0x37, 0xa0, +0x94, 0x2b, 0xf5, 0xf6, 0xdd, 0x7b, 0x90, 0x0d, +0xee, 0xa1, 0x6f, 0x3e, 0x88, 0x41, 0x33, 0x05, +0x2c, 0x87, 0x7d, 0x6c, 0xfd, 0xf4, 0x59, 0x8a, +0x17, 0x6c, 0xbc, 0xd4, 0x97, 0x4f, 0x5f, 0x99, +0xb0, 0xe5, 0x5e, 0x31, 0x4e, 0x96, 0x6f, 0xdf, +0x0f, 0xb4, 0xfe, 0x08, 0x16, 0x13, 0x65, 0x20, +0x1e, 0x00, 0x00, 0x56, 0x83, 0x09, 0x96, 0x3c, +0x59, 0x22, 0xb4, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x38, 0x54, 0x30, 0x31, 0x3a, 0x30, 0x33, +0x3a, 0x35, 0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0x68, 0xc6, 0x93, 0x0c, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sql_32_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sql_32_png = new wxImage(); + if (!img_sql_32_png || !img_sql_32_png->IsOk()) + { + wxMemoryInputStream img_sql_32_pngIS(sql_32_png_data, sizeof(sql_32_png_data)); + img_sql_32_png->LoadFile(img_sql_32_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sql_32_png; +} +#define sql_32_png_img sql_32_png_img() + +static wxBitmap *sql_32_png_bmp() +{ + static wxBitmap *bmp_sql_32_png; + if (!bmp_sql_32_png || !bmp_sql_32_png->IsOk()) + bmp_sql_32_png = new wxBitmap(*sql_32_png_img); + return bmp_sql_32_png; +} +#define sql_32_png_bmp sql_32_png_bmp() + +static wxIcon *sql_32_png_ico() +{ + static wxIcon *ico_sql_32_png; + if (!ico_sql_32_png || !ico_sql_32_png->IsOk()) + { + ico_sql_32_png = new wxIcon(); + ico_sql_32_png->CopyFromBitmap(*sql_32_png_bmp); + } + return ico_sql_32_png; +} +#define sql_32_png_ico sql_32_png_ico() + +#endif // SQL_32_PNG_H diff --git a/include/images/sql.ico b/include/images/sql.ico new file mode 100644 index 0000000..9c3cef9 Binary files /dev/null and b/include/images/sql.ico differ diff --git a/include/images/sql.png b/include/images/sql.png new file mode 100644 index 0000000..20cd21d Binary files /dev/null and b/include/images/sql.png differ diff --git a/include/images/sql.pngc b/include/images/sql.pngc new file mode 100644 index 0000000..a3ba7cb --- /dev/null +++ b/include/images/sql.pngc @@ -0,0 +1,3151 @@ +#ifndef SQL_PNG_H +#define SQL_PNG_H + +static const unsigned char sql_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, +0x08, 0x06, 0x00, 0x00, 0x00, 0xc3, 0x3e, 0x61, +0xcb, 0x00, 0x00, 0x20, 0x00, 0x49, 0x44, 0x41, +0x54, 0x78, 0x9c, 0xec, 0xbd, 0x79, 0xb4, 0x24, +0xd7, 0x7d, 0xdf, 0xf7, 0xb9, 0xf7, 0xd6, 0xd6, +0x7b, 0xf7, 0xdb, 0xdf, 0xbc, 0x79, 0x6f, 0x06, +0x33, 0x6f, 0x66, 0xb0, 0xcc, 0x0c, 0x36, 0x12, +0x20, 0x36, 0xc1, 0xa0, 0x09, 0x8a, 0x12, 0x48, +0x49, 0xe6, 0x22, 0xda, 0x31, 0x8f, 0x62, 0x45, +0xc7, 0x91, 0x1c, 0x5b, 0x8a, 0xf4, 0x87, 0xf2, +0x87, 0xad, 0xe3, 0x93, 0x38, 0x7f, 0x29, 0x71, +0x62, 0xe7, 0x8f, 0xf8, 0x44, 0x89, 0x8f, 0x8e, +0x73, 0x8e, 0x6c, 0x89, 0x54, 0x2c, 0x9a, 0x21, +0x48, 0x50, 0xc4, 0x42, 0x01, 0x22, 0x08, 0x90, +0x00, 0x06, 0x3b, 0x06, 0x83, 0xd9, 0xb7, 0xb7, +0x2f, 0xbd, 0x77, 0xd7, 0x76, 0x6f, 0xfe, 0xa8, +0xaa, 0x7e, 0xfd, 0xde, 0xac, 0x00, 0x29, 0xc9, +0x3a, 0xd1, 0x6f, 0x4e, 0x4d, 0xf7, 0xab, 0xaa, +0xae, 0xae, 0xba, 0xbf, 0xef, 0x6f, 0xff, 0xdd, +0xdb, 0xf0, 0x37, 0xf4, 0x37, 0xf4, 0x37, 0xf4, +0xff, 0x5f, 0x12, 0x7f, 0xd5, 0x37, 0xf0, 0xe3, +0x90, 0x10, 0x02, 0xa4, 0x1c, 0x3c, 0x84, 0x90, +0x32, 0x3b, 0x90, 0x1c, 0xfb, 0x09, 0x93, 0xd1, +0x3a, 0x79, 0x35, 0x06, 0x8c, 0x19, 0xec, 0x33, +0xe9, 0xfb, 0xbf, 0x8e, 0xf4, 0xd7, 0x02, 0x00, +0x42, 0x88, 0x84, 0xb9, 0x29, 0x63, 0x07, 0x8c, +0xbe, 0x0e, 0xc9, 0x04, 0x1b, 0x48, 0x21, 0x90, +0x12, 0x21, 0x85, 0x40, 0x88, 0xe4, 0x79, 0xaf, +0x87, 0x8d, 0x01, 0x5f, 0x4d, 0xc2, 0x68, 0xad, +0x31, 0xb1, 0x36, 0xe8, 0x2d, 0x9e, 0x5f, 0xe7, +0xb3, 0x26, 0x01, 0x49, 0xfa, 0xfa, 0xd7, 0x01, +0x18, 0xff, 0x59, 0x02, 0x40, 0x48, 0x39, 0x60, +0xf4, 0xd5, 0x98, 0x2d, 0x04, 0x28, 0x89, 0x50, +0x52, 0x00, 0x48, 0x40, 0x68, 0x8d, 0x52, 0x12, +0x89, 0x40, 0x86, 0x91, 0x51, 0x52, 0x08, 0x15, +0x69, 0xa3, 0x8c, 0x41, 0xa5, 0xe7, 0x64, 0xdb, +0xf0, 0x33, 0x8b, 0x74, 0x33, 0xe9, 0x96, 0x91, +0x1e, 0xda, 0x22, 0xc7, 0x12, 0x5a, 0x1b, 0x13, +0x0b, 0x44, 0x6c, 0x59, 0xe8, 0x38, 0x26, 0xb6, +0x94, 0xd0, 0x06, 0xa3, 0x8d, 0x41, 0xc7, 0x31, +0xc4, 0xda, 0x18, 0x7d, 0x15, 0x7e, 0x1b, 0xad, +0x07, 0x60, 0xc8, 0x34, 0xc8, 0x7f, 0x4e, 0xf4, +0x9f, 0x07, 0x00, 0x84, 0x40, 0xa6, 0xcc, 0xde, +0xc9, 0x70, 0x29, 0x40, 0x49, 0x21, 0x2c, 0x85, +0x30, 0x06, 0x69, 0xc0, 0xd2, 0x06, 0x4b, 0x6b, +0x63, 0xc7, 0x1a, 0x07, 0x70, 0x01, 0x6f, 0xe8, +0xd5, 0x01, 0x3c, 0x29, 0xf0, 0xe6, 0x26, 0x9c, +0x72, 0xce, 0x95, 0xf9, 0x5a, 0xc9, 0x2a, 0x81, +0xb0, 0x72, 0x8e, 0xc8, 0x79, 0x8e, 0x74, 0xd9, +0x7a, 0xee, 0x9d, 0x00, 0x30, 0x80, 0x69, 0xf7, +0xe3, 0x6e, 0x14, 0xe3, 0xf7, 0x03, 0xdd, 0x6f, +0x76, 0xa3, 0xd6, 0x6a, 0x3d, 0x6a, 0xd7, 0xdb, +0x71, 0x1b, 0xe8, 0x03, 0x7e, 0xfa, 0x9a, 0x6d, +0xbe, 0x92, 0x04, 0x8e, 0x25, 0x42, 0x03, 0x91, +0x52, 0x22, 0x92, 0x02, 0xed, 0x07, 0x46, 0x47, +0xda, 0xb0, 0x93, 0xe7, 0x19, 0x20, 0x74, 0xaa, +0x29, 0xfe, 0xaa, 0xe9, 0xaf, 0x14, 0x00, 0x52, +0x29, 0x84, 0x52, 0xdb, 0xec, 0xb5, 0x10, 0x60, +0x49, 0x70, 0x6c, 0x29, 0xb5, 0x36, 0x16, 0x02, +0x2b, 0x08, 0x8d, 0x17, 0x6b, 0x3c, 0x20, 0x0f, +0x14, 0x81, 0x52, 0xad, 0xa8, 0x6a, 0xfb, 0x77, +0x79, 0x33, 0xa3, 0x65, 0x6b, 0xb2, 0x56, 0xb4, +0xc6, 0x8f, 0xde, 0x92, 0x9b, 0xdc, 0xb3, 0xcb, +0x1b, 0x1f, 0xad, 0x39, 0xb5, 0x52, 0x41, 0x95, +0xf2, 0x9e, 0x2c, 0x14, 0x73, 0xca, 0x92, 0xb6, +0x54, 0xae, 0x23, 0x15, 0x12, 0xa1, 0x94, 0x90, +0xca, 0x16, 0x4a, 0x08, 0x91, 0x3e, 0xf9, 0xce, +0x57, 0xc0, 0x18, 0xc2, 0xc8, 0x44, 0x26, 0x36, +0x26, 0x8a, 0x8c, 0x0e, 0x43, 0x1d, 0xf9, 0x7d, +0x1d, 0x77, 0xba, 0x51, 0xbf, 0xd5, 0x89, 0x9b, +0xab, 0x9b, 0xc1, 0xc6, 0xe2, 0x4a, 0xb0, 0xfe, +0xd6, 0xe9, 0xce, 0xf2, 0xd2, 0x66, 0xb8, 0xb4, +0x5a, 0x8f, 0x16, 0x4f, 0x5f, 0xee, 0x5d, 0xde, +0x6c, 0xc5, 0x1b, 0x40, 0x13, 0x68, 0x03, 0x3d, +0xdb, 0x12, 0x3d, 0xcf, 0x11, 0xbe, 0x31, 0x44, +0x4a, 0x89, 0xb8, 0xd7, 0xd7, 0x3a, 0x8a, 0x13, +0x53, 0xc2, 0xe0, 0xab, 0x0c, 0x26, 0x8e, 0x13, +0x15, 0xf2, 0x57, 0x44, 0x7f, 0xe9, 0x00, 0xc8, +0xa4, 0x5c, 0x2a, 0x35, 0xd8, 0x27, 0x05, 0x38, +0xb6, 0x10, 0x80, 0xa5, 0x35, 0x4e, 0xac, 0x8d, +0x17, 0x6b, 0x8a, 0x40, 0x05, 0xa8, 0x8e, 0x57, +0xac, 0xe9, 0x3b, 0xf6, 0xe4, 0xe6, 0xe7, 0x26, +0xdc, 0xb9, 0x87, 0xef, 0x28, 0xde, 0x32, 0xbf, +0x3b, 0x37, 0x3b, 0x39, 0xee, 0x8e, 0x95, 0x2b, +0xb6, 0xeb, 0xe4, 0x95, 0x6b, 0xbb, 0xd2, 0x4e, +0xec, 0x81, 0x41, 0x68, 0x83, 0x11, 0x24, 0x48, +0xda, 0xc9, 0xe8, 0xa1, 0x4d, 0x0c, 0xf6, 0x0b, +0xb6, 0x01, 0x40, 0x0c, 0xd9, 0x82, 0x21, 0x50, +0x0c, 0x76, 0x9a, 0xf4, 0xef, 0xc8, 0x98, 0xd0, +0xd7, 0x61, 0xbf, 0x1b, 0x05, 0xcd, 0x66, 0xd4, +0x5f, 0x5a, 0xf5, 0x57, 0x4e, 0x5f, 0xec, 0x5d, +0xfa, 0xf3, 0xb7, 0x9a, 0xa7, 0xce, 0x2d, 0xf6, +0xcf, 0xbd, 0x7b, 0xb6, 0x77, 0x7a, 0xb3, 0x15, +0x2d, 0x01, 0x75, 0xa0, 0x69, 0x5b, 0xa2, 0xe3, +0x58, 0xa2, 0x2f, 0x04, 0x61, 0xac, 0x4d, 0xec, +0x87, 0x66, 0x9b, 0x45, 0xd0, 0x71, 0x8c, 0x89, +0xe3, 0xbf, 0x74, 0xbf, 0xe1, 0x2f, 0x0d, 0x00, +0x42, 0xa9, 0x44, 0xe2, 0x53, 0x69, 0x17, 0x02, +0x1c, 0x4b, 0xa0, 0x24, 0x56, 0xac, 0x71, 0x83, +0xc8, 0xe4, 0x8d, 0xa1, 0x02, 0x8c, 0x8e, 0x94, +0xd4, 0xae, 0xa3, 0xb7, 0xe4, 0x0f, 0x7f, 0xec, +0x40, 0xe1, 0xf6, 0x47, 0x8f, 0x96, 0x6f, 0xdb, +0x3f, 0x9b, 0xdb, 0x3d, 0x32, 0x62, 0x17, 0xdc, +0x82, 0xe5, 0x08, 0x4f, 0x49, 0x2c, 0x99, 0xf0, +0x23, 0x36, 0x10, 0x19, 0x44, 0x36, 0x68, 0x03, +0xc6, 0x6f, 0xbd, 0x9a, 0x8c, 0xe9, 0x3b, 0x40, +0x30, 0xd0, 0x3a, 0x42, 0x24, 0xd7, 0xda, 0xa9, +0x09, 0x06, 0xfb, 0x6e, 0x40, 0x19, 0x20, 0x74, +0xb2, 0x99, 0x50, 0xeb, 0x7e, 0x3b, 0xee, 0xaf, +0x6d, 0x06, 0xed, 0x93, 0xe7, 0xba, 0xe7, 0xff, +0xec, 0x58, 0xe3, 0xbd, 0xd7, 0x4e, 0xb4, 0xdf, +0x79, 0xfd, 0x83, 0xce, 0xbb, 0x3d, 0x5f, 0x2f, +0x03, 0xeb, 0x4a, 0xd2, 0xf4, 0x5c, 0xd9, 0xb3, +0xa4, 0x08, 0xfd, 0x50, 0xc7, 0x41, 0xb8, 0xa5, +0x19, 0x4c, 0xea, 0x54, 0x98, 0xbf, 0x24, 0xad, +0xf0, 0x17, 0x0e, 0x80, 0x9d, 0x8c, 0x57, 0x12, +0x3c, 0x5b, 0x08, 0x21, 0x84, 0xed, 0x87, 0x3a, +0x1f, 0xc6, 0x54, 0x80, 0x89, 0x5d, 0x23, 0xf6, +0x2d, 0xf7, 0x1d, 0x2a, 0x7e, 0xec, 0x0b, 0x0f, +0xd7, 0xee, 0x3f, 0xba, 0xaf, 0x70, 0x70, 0x72, +0xc2, 0xa9, 0xba, 0x45, 0xcb, 0xc5, 0x53, 0x02, +0x4b, 0x82, 0x4a, 0x98, 0x23, 0x42, 0x03, 0x81, +0x4e, 0x98, 0x8f, 0x18, 0x08, 0xb0, 0xc9, 0xdc, +0xbb, 0x61, 0xc9, 0x1f, 0xda, 0xcc, 0x80, 0xe1, +0xa4, 0xd1, 0x44, 0x2a, 0xd4, 0xc3, 0xfb, 0xb7, +0x69, 0x82, 0x6b, 0x0c, 0x8d, 0xe0, 0x4a, 0xdb, +0x3d, 0xf4, 0xa7, 0xc8, 0x00, 0x91, 0x82, 0xc2, +0x04, 0xda, 0x74, 0xdb, 0x51, 0xef, 0xf2, 0xb2, +0xbf, 0xfe, 0xfd, 0x37, 0x1a, 0x6f, 0x3e, 0xf5, +0xd2, 0xe6, 0x0f, 0x7f, 0xf8, 0x6e, 0xeb, 0x58, +0xb3, 0x13, 0x5f, 0x02, 0xd6, 0xf3, 0xae, 0x6c, +0x7a, 0xae, 0xec, 0x87, 0x91, 0x8e, 0xba, 0x7d, +0x6d, 0xe2, 0x54, 0x2b, 0xfc, 0x65, 0x99, 0x87, +0xbf, 0x30, 0x00, 0x64, 0x6a, 0x3e, 0x73, 0xea, +0x2c, 0x09, 0xae, 0x2d, 0x95, 0x36, 0xc6, 0xed, +0x87, 0xa6, 0x6c, 0x0c, 0xe3, 0x79, 0x47, 0xcc, +0x3d, 0x7c, 0xb8, 0xf4, 0x89, 0x2f, 0x3d, 0x32, +0xf2, 0xd0, 0x83, 0x77, 0x94, 0x0f, 0x4f, 0x4e, +0x38, 0x55, 0x55, 0xb0, 0x2c, 0xe1, 0x28, 0x61, +0xac, 0x21, 0x49, 0x36, 0xa9, 0xa4, 0x07, 0x1a, +0xd2, 0xf1, 0x10, 0x3b, 0x99, 0x2b, 0x48, 0x6c, +0xc9, 0x36, 0xc6, 0x8b, 0x6d, 0xef, 0xcd, 0x36, +0xd7, 0x6f, 0x58, 0xf5, 0x0f, 0x9d, 0x77, 0xb5, +0xd1, 0x11, 0x5c, 0x79, 0xd0, 0x0c, 0xbd, 0x31, +0xdb, 0xf7, 0x0f, 0xce, 0xcc, 0x80, 0x60, 0x0c, +0x46, 0x03, 0xb1, 0x36, 0xfd, 0x6e, 0xec, 0x5f, +0x5e, 0xea, 0xaf, 0x3d, 0xfd, 0xc3, 0xfa, 0xb1, +0x27, 0xff, 0x7c, 0xe3, 0xfb, 0x2f, 0xbf, 0xdb, +0x7c, 0x35, 0x8e, 0x59, 0xb0, 0x14, 0xeb, 0x79, +0x4f, 0xb5, 0x80, 0xb0, 0xe7, 0xc7, 0x3a, 0x8c, +0xb2, 0x4b, 0x18, 0x74, 0x14, 0xfd, 0x85, 0x45, +0x10, 0x7f, 0x21, 0x00, 0x90, 0x96, 0x35, 0xb0, +0xf1, 0x4a, 0x42, 0xde, 0x95, 0x32, 0x8a, 0x8d, +0xd7, 0x0b, 0x4c, 0x05, 0x98, 0x9a, 0x1d, 0xb3, +0xef, 0xf8, 0xfc, 0x83, 0xb5, 0x4f, 0x7d, 0xf1, +0x91, 0xd1, 0x47, 0x0e, 0xec, 0xc9, 0xcd, 0xb8, +0x25, 0xdb, 0x11, 0x9e, 0x12, 0x28, 0x91, 0x06, +0x6a, 0xa9, 0xfa, 0x36, 0x40, 0xac, 0xa1, 0x1f, +0x23, 0xe2, 0xed, 0x6a, 0xfb, 0x0a, 0xe9, 0xbe, +0x82, 0xf9, 0xc3, 0xe7, 0x89, 0x21, 0x53, 0xc0, +0xcd, 0x01, 0x40, 0xec, 0x78, 0xdd, 0x49, 0xe6, +0x7a, 0xef, 0xcd, 0x16, 0x10, 0xb2, 0xc4, 0x42, +0xe6, 0x47, 0x18, 0x93, 0x06, 0x98, 0xc6, 0xb4, +0xdb, 0x71, 0xf7, 0xcd, 0x13, 0xed, 0xd3, 0x7f, +0xf0, 0xad, 0xe5, 0xe7, 0x9e, 0x7a, 0x69, 0xe3, +0x7b, 0x8d, 0x76, 0x7c, 0x4a, 0x0a, 0x56, 0xf3, +0x39, 0xd9, 0xb4, 0x94, 0x08, 0xda, 0xdd, 0xd8, +0x44, 0x29, 0xe0, 0x8d, 0xd6, 0xc4, 0x61, 0x78, +0x33, 0xc3, 0xff, 0xa1, 0xe8, 0x27, 0x0a, 0x00, +0x21, 0x25, 0xd2, 0xb2, 0x92, 0x18, 0x5e, 0x40, +0xde, 0x95, 0x42, 0x80, 0xd3, 0xf1, 0x75, 0xd9, +0x18, 0x76, 0xcd, 0x8d, 0x3b, 0x47, 0x7f, 0xe9, +0x6f, 0x8f, 0x3e, 0xf1, 0xf7, 0x1e, 0x1d, 0x7d, +0x6c, 0x7a, 0xda, 0x1b, 0x95, 0x79, 0x4b, 0x61, +0xa7, 0xea, 0x7d, 0x87, 0x23, 0x06, 0x26, 0x61, +0x7c, 0xb8, 0x43, 0xdd, 0xa6, 0x0c, 0x33, 0x29, +0xc3, 0xc5, 0xb0, 0xad, 0xbf, 0x86, 0x06, 0x18, +0x38, 0x85, 0x6c, 0xed, 0xcb, 0xfe, 0x1c, 0x68, +0x8f, 0x6b, 0xd9, 0xff, 0x6d, 0xa6, 0xe0, 0x1a, +0xaa, 0x7f, 0x27, 0x00, 0x86, 0x4c, 0x84, 0xb8, +0x02, 0x00, 0xc3, 0x9b, 0x01, 0x83, 0x09, 0x23, +0x1d, 0x9d, 0x3a, 0xdf, 0xbd, 0xf4, 0xb5, 0x3f, +0x5d, 0x79, 0xe6, 0x8f, 0xbe, 0xbb, 0xfa, 0xd4, +0xd2, 0x7a, 0x78, 0xdc, 0x52, 0x62, 0xb9, 0x54, +0x50, 0xed, 0x28, 0xd2, 0x61, 0xa7, 0xa7, 0x19, +0x24, 0xa6, 0x7e, 0xc2, 0xfe, 0xc1, 0x4f, 0x0c, +0x00, 0xc3, 0x52, 0xef, 0x58, 0xe0, 0xda, 0xd2, +0xea, 0x07, 0xba, 0x14, 0xc6, 0x4c, 0x4f, 0x56, +0xad, 0xc3, 0xff, 0xd5, 0xe3, 0x63, 0x3f, 0xff, +0x95, 0x4f, 0x8e, 0x7d, 0x6a, 0xd7, 0xb4, 0x37, +0x26, 0x73, 0x96, 0xc4, 0x96, 0x20, 0x77, 0xa8, +0xe5, 0x8c, 0x09, 0x5a, 0x43, 0x2f, 0x46, 0xc4, +0x26, 0xb5, 0xd5, 0xdb, 0x99, 0x63, 0x86, 0xec, +0xbc, 0x18, 0x66, 0xba, 0x1c, 0x62, 0xe8, 0x30, +0xf3, 0xd9, 0xfa, 0x7b, 0x27, 0x00, 0xb6, 0x4c, +0xc3, 0x4e, 0x00, 0x0e, 0xf9, 0x0d, 0x3b, 0x28, +0xd9, 0x6b, 0xae, 0x03, 0x80, 0xa1, 0x9d, 0xdb, +0x22, 0x08, 0xb3, 0x9d, 0xf9, 0x6c, 0x7f, 0xaf, +0xb5, 0x89, 0xcf, 0x5c, 0xea, 0x5f, 0xfa, 0x37, +0x5f, 0xbd, 0xfc, 0xe4, 0xd7, 0x9e, 0x5e, 0xfd, +0x56, 0xa7, 0xa7, 0x4f, 0x7a, 0x8e, 0x58, 0x29, +0xe6, 0x55, 0xa7, 0xdd, 0x8d, 0xe3, 0x7e, 0x90, +0x9e, 0x17, 0xc7, 0xe8, 0x28, 0xba, 0x26, 0x2f, +0x3e, 0x0c, 0xfd, 0x44, 0x00, 0xa0, 0x6c, 0x3b, +0x09, 0xef, 0x80, 0x82, 0x27, 0x85, 0x01, 0xaf, +0xd3, 0xd7, 0xa3, 0xb6, 0x12, 0x07, 0x7e, 0xfe, +0xfe, 0xea, 0x13, 0xbf, 0xfd, 0xc5, 0xa9, 0x2f, +0x1c, 0xd8, 0x5b, 0x98, 0x55, 0x79, 0x4b, 0x61, +0x89, 0x2b, 0x98, 0xb1, 0x0d, 0x04, 0x71, 0xca, +0xfc, 0x61, 0x5b, 0xba, 0x03, 0x04, 0xc3, 0x00, +0x40, 0x08, 0x44, 0xe6, 0x00, 0xa6, 0xe6, 0x23, +0x93, 0xf8, 0x6b, 0x45, 0x00, 0x5b, 0x9a, 0x63, +0x88, 0xf9, 0xc3, 0xa3, 0x31, 0xf8, 0x9e, 0xeb, +0x0f, 0x91, 0x18, 0x66, 0x6c, 0x46, 0xc3, 0x39, +0x45, 0x93, 0xfe, 0x71, 0x95, 0x30, 0x32, 0x53, +0x72, 0xe8, 0xa1, 0x73, 0x4d, 0xf2, 0x9d, 0xa1, +0x36, 0xe1, 0xb1, 0xf7, 0xda, 0x1f, 0xfc, 0xee, +0xef, 0x9f, 0xff, 0xa3, 0x17, 0x8e, 0x35, 0x9e, +0x31, 0x70, 0xb6, 0x5c, 0x50, 0x75, 0x6d, 0x08, +0x5a, 0x9d, 0x38, 0x51, 0x26, 0x5a, 0x13, 0x47, +0xd1, 0x8f, 0x9d, 0x4c, 0x52, 0x37, 0x3e, 0xe5, +0x3a, 0x24, 0x04, 0xca, 0x71, 0x12, 0xd5, 0x2f, +0xa1, 0x9c, 0x93, 0xb2, 0x17, 0xe8, 0x92, 0x1f, +0x9a, 0xd9, 0x7d, 0x93, 0xce, 0x43, 0xff, 0xd3, +0x2f, 0xcf, 0xfe, 0xe6, 0x6f, 0x7d, 0x71, 0xd7, +0x17, 0xa6, 0x66, 0x72, 0xa3, 0xd2, 0xb3, 0x92, +0x93, 0x84, 0xd8, 0x31, 0xa6, 0x43, 0x83, 0x9f, +0x31, 0x5f, 0x5f, 0xe9, 0x77, 0x89, 0xec, 0xff, +0x01, 0x70, 0xc4, 0x0e, 0x66, 0xb2, 0xc3, 0xee, +0x0f, 0xbd, 0xbf, 0x0a, 0x00, 0xb6, 0xbc, 0xc8, +0x1d, 0xc7, 0x07, 0x5f, 0x96, 0xd6, 0x1d, 0x86, +0xbf, 0x6e, 0x58, 0x73, 0x00, 0x22, 0xe3, 0xea, +0xb6, 0xe7, 0xd9, 0xae, 0x0e, 0x76, 0x1e, 0x1a, +0x7c, 0xcd, 0x36, 0xa0, 0x6c, 0x6d, 0x42, 0x1b, +0x94, 0x41, 0xcd, 0x4c, 0xba, 0xe3, 0x4f, 0x3c, +0x36, 0x76, 0xff, 0xae, 0x71, 0x77, 0xe6, 0x9d, +0x93, 0x9d, 0xf5, 0xd5, 0xcd, 0xa8, 0x6b, 0x5b, +0x32, 0x28, 0xe6, 0x55, 0x14, 0xc6, 0x1a, 0x63, +0x92, 0x54, 0xf9, 0x8f, 0xeb, 0x1c, 0xfe, 0x58, +0x00, 0xc8, 0x24, 0x5f, 0x49, 0x28, 0x79, 0xd2, +0x6a, 0xf6, 0x74, 0x0d, 0xc3, 0xa1, 0xcf, 0xdc, +0x5b, 0xf9, 0xd2, 0xef, 0xfd, 0xfa, 0x2d, 0xbf, +0xf5, 0xd0, 0xdd, 0xd5, 0x23, 0x76, 0xc1, 0xb6, +0x51, 0xa9, 0x53, 0x70, 0x35, 0x69, 0x03, 0x04, +0x22, 0xb1, 0x95, 0xbd, 0x18, 0xf4, 0x15, 0x7c, +0x00, 0x86, 0x87, 0x75, 0x98, 0x1b, 0x0c, 0x69, +0xee, 0x54, 0xa2, 0x87, 0xee, 0x2f, 0xf3, 0x45, +0xae, 0x04, 0xc1, 0xb0, 0xba, 0x1f, 0xe2, 0xea, +0x30, 0x30, 0x76, 0x68, 0x83, 0x61, 0xda, 0xf9, +0x28, 0x3b, 0x5d, 0x83, 0x61, 0x0c, 0x5e, 0x71, +0x11, 0x93, 0x3c, 0xef, 0x76, 0xda, 0x7e, 0x01, +0x61, 0x80, 0x18, 0xe1, 0x28, 0xe1, 0xdc, 0x79, +0x7b, 0xe9, 0xc0, 0xa3, 0xf7, 0xd5, 0xee, 0x3d, +0x7e, 0xba, 0x13, 0x9c, 0xbd, 0xdc, 0xaf, 0xc7, +0xda, 0xf4, 0xcb, 0x45, 0x2b, 0xd4, 0xb1, 0x31, +0xb1, 0xe6, 0xc7, 0x06, 0xc1, 0x47, 0x06, 0x40, +0x26, 0xf9, 0xb6, 0x02, 0xd7, 0x91, 0x4e, 0xab, +0xa7, 0xc7, 0x1c, 0x4b, 0xdc, 0xf1, 0x5b, 0xbf, +0x30, 0xf5, 0x5f, 0xff, 0x8b, 0x7f, 0x30, 0xfb, +0x0f, 0xa6, 0x77, 0x79, 0x63, 0xc2, 0x91, 0xf2, +0x2a, 0x62, 0x03, 0x57, 0x01, 0x01, 0x41, 0x8c, +0x88, 0xb6, 0x9f, 0xba, 0xf3, 0xf4, 0x64, 0x87, +0xd8, 0x1a, 0xc0, 0x61, 0x06, 0x5f, 0x11, 0x21, +0x6c, 0x7d, 0xc7, 0x16, 0xc3, 0xc4, 0x90, 0xd3, +0x97, 0x09, 0x9d, 0x18, 0x68, 0xe8, 0x24, 0x3d, +0x6f, 0xd8, 0xfa, 0xc7, 0x15, 0x51, 0xde, 0x10, +0xdc, 0xb8, 0x02, 0x1d, 0xe6, 0x9a, 0x47, 0xd8, +0x0e, 0x87, 0x21, 0xfb, 0xbf, 0xed, 0x3d, 0xdb, +0xb5, 0x84, 0x06, 0x19, 0x23, 0x26, 0x46, 0x9d, +0x91, 0x9f, 0x79, 0x74, 0xf4, 0xe3, 0x7d, 0x5f, +0x3b, 0xc7, 0xde, 0x6f, 0x2f, 0xf6, 0x7a, 0xba, +0x37, 0x5a, 0xb5, 0x43, 0xad, 0xd1, 0x51, 0xfc, +0xe3, 0x81, 0xe0, 0x23, 0x01, 0x20, 0x93, 0x7c, +0x4b, 0x41, 0x39, 0xa7, 0xec, 0x76, 0x4f, 0x8f, +0x17, 0x73, 0xf2, 0xae, 0xff, 0xe1, 0xbf, 0x98, +0xf9, 0x8d, 0x7f, 0xf2, 0xf9, 0xe9, 0x9f, 0x2f, +0x54, 0xec, 0x9c, 0x90, 0x43, 0xde, 0x96, 0xd8, +0xc1, 0xf0, 0x9d, 0x20, 0xd0, 0x1a, 0xfa, 0x7a, +0xfb, 0xbe, 0x21, 0x12, 0xc3, 0x6f, 0x06, 0x97, +0x15, 0x43, 0xaa, 0x3f, 0x79, 0x1d, 0xd8, 0xfc, +0x8c, 0xd1, 0x80, 0x21, 0xc9, 0xb2, 0xc5, 0x06, +0xc2, 0xc8, 0x10, 0x46, 0x86, 0x7e, 0xa8, 0xe9, +0xfb, 0x9a, 0x6e, 0x5f, 0xd3, 0xe9, 0x69, 0x5a, +0xdd, 0x98, 0x56, 0x27, 0xa2, 0xd9, 0x89, 0x69, +0xb6, 0x63, 0xda, 0x9d, 0x98, 0x56, 0x27, 0xa6, +0xd3, 0x8d, 0xe9, 0xf6, 0x35, 0xfd, 0xbe, 0xc6, +0x0f, 0x34, 0x41, 0x64, 0x88, 0x22, 0x43, 0x56, +0x1e, 0xc6, 0x98, 0x6d, 0xbe, 0xc9, 0x40, 0xb5, +0x0f, 0x81, 0x60, 0x9b, 0xf7, 0x9f, 0xde, 0x11, +0x86, 0x21, 0xff, 0x81, 0xed, 0xa6, 0x60, 0xf0, +0xa8, 0x89, 0xf9, 0x48, 0xb4, 0x81, 0x11, 0x79, +0x47, 0x7a, 0x8f, 0xdc, 0x57, 0x3b, 0x52, 0x29, +0x59, 0xa3, 0x3f, 0x7c, 0xbb, 0x79, 0xb1, 0xd1, +0x8e, 0x9b, 0xa3, 0x55, 0xcb, 0x8f, 0x7f, 0x4c, +0x10, 0x5c, 0x45, 0xc1, 0x5d, 0x9f, 0x32, 0x6f, +0x5f, 0x49, 0xc8, 0x39, 0xd2, 0x6e, 0xf7, 0xf5, +0x58, 0x39, 0x27, 0x3f, 0xfe, 0x2f, 0x7f, 0x65, +0xf6, 0xb7, 0xbe, 0xf4, 0xd8, 0xd8, 0x23, 0xd2, +0x55, 0x6a, 0xbb, 0x8a, 0xe5, 0xfa, 0x20, 0x10, +0x06, 0x82, 0x18, 0x06, 0xe1, 0xde, 0x15, 0xfa, +0x73, 0xe8, 0x3a, 0xb0, 0x4d, 0xbf, 0x0e, 0xe2, +0xff, 0x2d, 0x00, 0x68, 0xd2, 0x0c, 0xb1, 0x36, +0x44, 0xb1, 0x21, 0x88, 0x0c, 0xfd, 0x48, 0xd3, +0xf3, 0x0d, 0xfd, 0x40, 0xd3, 0x0f, 0x34, 0x5d, +0xdf, 0xd0, 0xf3, 0xa1, 0x1f, 0x48, 0x82, 0x08, +0x82, 0x48, 0x90, 0x14, 0x6a, 0x04, 0x52, 0xe5, +0x40, 0x48, 0x74, 0xdc, 0x41, 0x4a, 0x50, 0x4a, +0xe0, 0xda, 0xe0, 0x38, 0xe0, 0x39, 0x90, 0xf3, +0x0c, 0x79, 0x57, 0x90, 0xcb, 0x49, 0x72, 0xae, +0xc4, 0x73, 0x92, 0xcd, 0xb1, 0x25, 0xb6, 0x12, +0x28, 0x29, 0x90, 0x62, 0xc8, 0xf6, 0x5f, 0x2d, +0xfc, 0xc3, 0xa4, 0x19, 0xc3, 0x9d, 0xc7, 0x0d, +0x42, 0x5f, 0x65, 0x7f, 0xf6, 0xa2, 0x20, 0xb0, +0x65, 0xf8, 0xf5, 0x67, 0x57, 0x5f, 0xf8, 0xed, +0xff, 0xe5, 0xf4, 0xbf, 0x6c, 0xf7, 0xe2, 0xd7, +0xc7, 0x6b, 0xf6, 0x46, 0xbd, 0x15, 0x85, 0x7e, +0x60, 0x30, 0xc6, 0x10, 0x07, 0xc1, 0x87, 0xe2, +0xa7, 0xf5, 0x61, 0x4e, 0x1e, 0x64, 0xf7, 0x04, +0xe4, 0x1c, 0x69, 0x75, 0x7c, 0x3d, 0xe2, 0x39, +0xe2, 0xf0, 0xef, 0xfe, 0xf2, 0xec, 0x6f, 0x7c, +0xf1, 0x93, 0x63, 0x8f, 0x28, 0x5b, 0x2a, 0x93, +0xdd, 0xae, 0x49, 0x19, 0x35, 0xac, 0xe6, 0xb2, +0xfc, 0x6b, 0xb6, 0x5f, 0xa4, 0x49, 0x91, 0xc8, +0x6c, 0xed, 0x1f, 0xe8, 0xdc, 0x1d, 0x80, 0x19, +0xde, 0x37, 0xf4, 0x36, 0xc9, 0xb8, 0x26, 0x52, +0x19, 0xc4, 0x86, 0x7e, 0x68, 0xe8, 0xf8, 0x31, +0xad, 0x6e, 0x4c, 0xb3, 0x6b, 0xa8, 0xb7, 0x0d, +0x8d, 0x9e, 0xc2, 0x8f, 0x2b, 0xf4, 0xa2, 0x02, +0x41, 0x9c, 0x43, 0xda, 0x65, 0x2c, 0xab, 0x80, +0xb2, 0xf2, 0x08, 0xe9, 0x80, 0xed, 0x20, 0x1c, +0x99, 0x3a, 0xe5, 0x22, 0x31, 0x03, 0x96, 0xce, +0xc2, 0x74, 0xda, 0x81, 0x8f, 0xf1, 0x03, 0x8c, +0xee, 0xa3, 0xe3, 0x0e, 0xc2, 0xb4, 0x71, 0xac, +0x0e, 0xae, 0xaa, 0x93, 0x77, 0xba, 0x54, 0x8b, +0x50, 0x2b, 0x4b, 0xca, 0x05, 0x45, 0x31, 0xa7, +0xc8, 0x79, 0x12, 0xd7, 0x11, 0xd8, 0x4a, 0x6c, +0xf3, 0x3b, 0x07, 0xb4, 0x4d, 0x23, 0x64, 0xc7, +0xb6, 0xdb, 0x1a, 0xb3, 0xed, 0x18, 0x08, 0x63, +0x30, 0x91, 0xc1, 0xd6, 0xc6, 0xfe, 0xc2, 0xa7, +0xc6, 0xfe, 0x16, 0xc0, 0x7f, 0xf7, 0xbf, 0x9e, +0xfe, 0xdd, 0xd5, 0xcd, 0xf0, 0xcd, 0x91, 0xb2, +0xb5, 0xa1, 0x75, 0x1c, 0x85, 0x51, 0x22, 0xa0, +0x1f, 0x26, 0x44, 0xfc, 0x50, 0x1a, 0x40, 0x39, +0x0e, 0x42, 0x08, 0x8a, 0x9e, 0x14, 0xbd, 0x40, +0x57, 0xa5, 0x10, 0x77, 0xfc, 0xce, 0xdf, 0x9d, +0xfe, 0x8d, 0x7f, 0xfc, 0xf9, 0xe9, 0xbf, 0x63, +0xdb, 0xd2, 0x1a, 0xe4, 0xd8, 0x87, 0x75, 0xf6, +0x8d, 0x34, 0x81, 0x4e, 0x9d, 0xbf, 0xab, 0x39, +0x5d, 0x57, 0xd3, 0x1a, 0x22, 0x09, 0x03, 0x0d, +0x09, 0x6e, 0x82, 0x28, 0x63, 0xb8, 0x66, 0xb3, +0xad, 0x59, 0x6f, 0x41, 0x23, 0x28, 0xd2, 0x0c, +0xc6, 0x88, 0xc4, 0x28, 0x96, 0x3b, 0x8a, 0x72, +0x2a, 0x58, 0x96, 0x8b, 0x52, 0xf6, 0x15, 0x5f, +0x92, 0x5a, 0xfa, 0x41, 0x15, 0xce, 0xa4, 0x09, +0x97, 0xac, 0xed, 0x4b, 0x0f, 0x5e, 0x93, 0x1a, +0xbe, 0x8e, 0x35, 0xc6, 0x68, 0x8c, 0x89, 0x31, +0x3a, 0xc6, 0x18, 0x1f, 0xa3, 0x9b, 0x48, 0xb3, +0x41, 0xde, 0x5e, 0xa7, 0xe4, 0xd6, 0x19, 0xaf, +0x1a, 0xc6, 0xaa, 0x92, 0x72, 0xd1, 0xa2, 0x98, +0x53, 0xb8, 0xb6, 0xc0, 0xb1, 0xc4, 0x56, 0x37, +0xca, 0x90, 0x84, 0x5f, 0xa1, 0x09, 0xb2, 0x36, +0x81, 0xc1, 0xf1, 0x2c, 0x94, 0xcc, 0xee, 0x17, +0x50, 0x82, 0xc8, 0x53, 0xd1, 0xbf, 0xfd, 0x93, +0xc5, 0x6f, 0xfe, 0xf3, 0xff, 0xfd, 0xec, 0xbf, +0xd2, 0x9a, 0x77, 0x2a, 0x25, 0x55, 0xdf, 0x6c, +0x44, 0x46, 0x1b, 0x88, 0xa3, 0xe8, 0xa6, 0x93, +0x45, 0x37, 0x0d, 0x80, 0x4c, 0xf5, 0x3b, 0x16, +0x48, 0x21, 0x0a, 0x7e, 0x68, 0x0e, 0xfc, 0xbd, +0x47, 0x47, 0x7e, 0xf9, 0x5f, 0xfd, 0xa3, 0x3d, +0xbf, 0xea, 0xe5, 0x2c, 0x77, 0x58, 0xed, 0xdf, +0x34, 0x08, 0x20, 0x09, 0xfd, 0xfc, 0xf8, 0xca, +0xf3, 0xd8, 0xf1, 0x79, 0x91, 0x30, 0x2b, 0x26, +0x61, 0x7a, 0xd7, 0x37, 0x34, 0xba, 0x31, 0x6b, +0xcd, 0x98, 0xa5, 0xba, 0xa4, 0x11, 0x8e, 0xd2, +0x35, 0xd3, 0xd8, 0xc5, 0x39, 0x1c, 0xb7, 0x86, +0x6d, 0x7b, 0x28, 0xcb, 0x62, 0x50, 0x4b, 0x48, +0x7d, 0x06, 0xa5, 0x52, 0x13, 0x66, 0x59, 0xa8, +0xb4, 0x50, 0x95, 0x35, 0xa3, 0x28, 0x65, 0x0d, +0x7c, 0x8b, 0x2c, 0xed, 0xac, 0xe3, 0x08, 0x63, +0x20, 0x8e, 0x63, 0xe2, 0x28, 0x22, 0x8a, 0x42, +0x02, 0x3f, 0xa0, 0xd7, 0xed, 0xd0, 0xeb, 0x75, +0x89, 0xc2, 0x90, 0x38, 0x8e, 0xd1, 0x3a, 0x01, +0x84, 0xd6, 0x3d, 0x4c, 0xb4, 0x8a, 0x2b, 0x97, +0xa8, 0x7a, 0x6b, 0x4c, 0x8d, 0xc4, 0x4c, 0x8e, +0x5a, 0x8c, 0x96, 0x6d, 0x0a, 0x5e, 0x62, 0x2a, +0x2c, 0xb9, 0xdd, 0x07, 0x10, 0x86, 0x44, 0x10, +0x86, 0xd2, 0x06, 0x59, 0x0d, 0x41, 0x0c, 0xe7, +0x10, 0xd8, 0xfa, 0x8c, 0xb1, 0x05, 0x81, 0x23, +0x83, 0xff, 0xfe, 0xdf, 0x9c, 0xfb, 0xbf, 0xff, +0x8f, 0x3f, 0x5e, 0xf8, 0x3d, 0xcf, 0x91, 0x27, +0x6c, 0x4b, 0x74, 0x1a, 0xed, 0xd8, 0x7c, 0x18, +0x53, 0x70, 0x53, 0x26, 0x40, 0x08, 0x31, 0x50, +0xfd, 0xb6, 0x92, 0x4e, 0xc7, 0xd7, 0x63, 0x87, +0xe7, 0xbc, 0x87, 0xff, 0xf9, 0x57, 0x66, 0xfe, +0xbe, 0xeb, 0x29, 0x67, 0xeb, 0xae, 0x52, 0x5b, +0x9c, 0x7a, 0xb2, 0x03, 0x10, 0x0c, 0xab, 0xfd, +0x61, 0x73, 0x00, 0x5b, 0xc8, 0x17, 0x66, 0x18, +0x35, 0x43, 0x20, 0x30, 0x09, 0x03, 0x34, 0x84, +0x91, 0xa6, 0xed, 0x6b, 0xd6, 0x9a, 0x11, 0x0b, +0x1b, 0x9a, 0xb5, 0x7e, 0x8d, 0xae, 0xdc, 0x8b, +0xc8, 0xef, 0x43, 0x56, 0xaa, 0x8c, 0xe5, 0xf2, +0x58, 0x52, 0x0d, 0x01, 0x49, 0xa2, 0x2c, 0x0b, +0x69, 0x59, 0x58, 0xb6, 0xbd, 0xc5, 0xec, 0xf4, +0x99, 0x18, 0xc4, 0xf9, 0xd9, 0x7b, 0xb1, 0x0d, +0x00, 0x42, 0x08, 0x84, 0x6d, 0x27, 0xe7, 0x0c, +0x7d, 0x4e, 0xa4, 0xe7, 0x1a, 0x61, 0xf0, 0xfb, +0x7d, 0x3a, 0xad, 0x16, 0xcd, 0x66, 0x83, 0x56, +0xa3, 0x49, 0xbf, 0xef, 0x12, 0xaa, 0x22, 0x81, +0x9e, 0x63, 0xd9, 0xef, 0xb1, 0x74, 0xfe, 0x22, +0xa5, 0xc5, 0x05, 0x76, 0xd5, 0x5a, 0xcc, 0x8c, +0x49, 0x46, 0xab, 0x36, 0xe5, 0xbc, 0x22, 0xe7, +0xa8, 0xac, 0xc0, 0xb9, 0x2d, 0x71, 0x94, 0x09, +0xfc, 0x76, 0x9f, 0x61, 0x6b, 0x1c, 0x45, 0x36, +0x66, 0x81, 0xc1, 0x51, 0xc2, 0xf9, 0xed, 0xff, +0x72, 0xf6, 0xcb, 0x6f, 0x9f, 0xec, 0x9c, 0xf9, +0xf3, 0x63, 0x8d, 0xcd, 0x6a, 0x49, 0x5d, 0x76, +0x6d, 0xe1, 0xfb, 0xe1, 0xcd, 0x9b, 0x82, 0x9b, +0x8a, 0x02, 0x94, 0x6d, 0x23, 0x84, 0xc0, 0xb3, +0x85, 0x0c, 0x22, 0x53, 0xce, 0x3b, 0xf2, 0xc8, +0xff, 0xf6, 0x6b, 0x73, 0xbf, 0x75, 0xe7, 0x81, +0xe2, 0xbc, 0xc8, 0xb2, 0x25, 0x03, 0xa6, 0xed, +0xf0, 0x8a, 0x77, 0x7a, 0xfc, 0x3b, 0xc9, 0xa4, +0x2e, 0xfa, 0xb6, 0xe3, 0x03, 0xab, 0x88, 0x36, +0x86, 0x7e, 0x60, 0xa8, 0xb7, 0x63, 0x2e, 0xaf, +0x07, 0x9c, 0x5a, 0xd0, 0x9c, 0x69, 0xec, 0x62, +0x4d, 0x7e, 0x1c, 0x51, 0xf9, 0x04, 0x85, 0xda, +0x3c, 0xc5, 0xd2, 0x28, 0xb9, 0x5c, 0x2e, 0x95, +0x68, 0x0b, 0xcb, 0x71, 0x71, 0x72, 0x79, 0x9c, +0x5c, 0x0e, 0xdb, 0xf5, 0xb0, 0x6c, 0x1b, 0x95, +0x96, 0xa4, 0x87, 0xa5, 0x7b, 0xeb, 0xbb, 0xc4, +0x95, 0x52, 0x36, 0x7c, 0x86, 0x10, 0x49, 0x73, +0xa9, 0x90, 0x48, 0x29, 0x91, 0x52, 0xa1, 0x94, +0xc4, 0xb2, 0x14, 0x9e, 0xe7, 0x51, 0xa9, 0x56, +0x19, 0x1b, 0x1f, 0x67, 0xd7, 0xcc, 0x0c, 0x63, +0xe3, 0xe3, 0xe4, 0x72, 0x79, 0x8c, 0x31, 0x84, +0x11, 0x18, 0x51, 0xc3, 0x37, 0xbb, 0x58, 0x6f, +0xd7, 0x58, 0x5a, 0x0b, 0x68, 0x34, 0x1b, 0xe8, +0x58, 0x27, 0xe6, 0x40, 0xa6, 0xcd, 0xab, 0x0c, +0x69, 0x84, 0x9d, 0xdf, 0x9d, 0x0e, 0x44, 0x12, +0x11, 0x98, 0xed, 0xfb, 0x63, 0x83, 0x9b, 0xb7, +0x9c, 0xbb, 0x6f, 0x2d, 0xed, 0x7d, 0xea, 0xc5, +0x8d, 0xb7, 0xd7, 0xeb, 0xd1, 0x4a, 0xa9, 0x60, +0xf5, 0xfc, 0x40, 0x1b, 0x21, 0xe4, 0x4d, 0x95, +0x92, 0x6f, 0x1a, 0x00, 0x69, 0x6f, 0x9e, 0x17, +0xc5, 0xec, 0xfd, 0x7b, 0x8f, 0x8e, 0xfc, 0xdd, +0x7f, 0xf4, 0xd9, 0xc9, 0x9f, 0x53, 0x52, 0xa8, +0x2b, 0x98, 0x7b, 0x4d, 0x10, 0x6c, 0xdf, 0x9f, +0xfc, 0x99, 0x0e, 0x7c, 0x64, 0xb6, 0x59, 0x85, +0x4c, 0x03, 0x06, 0xa1, 0xa1, 0xd9, 0x8d, 0xb9, +0xb4, 0x16, 0x72, 0xfc, 0x52, 0xc4, 0x99, 0xc6, +0x0c, 0xcd, 0xdc, 0xc3, 0x58, 0xa3, 0x1f, 0xa3, +0x54, 0x9b, 0xa3, 0x58, 0x2c, 0x63, 0x3b, 0x76, +0xc2, 0x14, 0xcb, 0x46, 0xb9, 0x1e, 0x96, 0xeb, +0x62, 0x39, 0x4e, 0xca, 0x28, 0xb9, 0xa5, 0x68, +0xb4, 0x26, 0x8a, 0x22, 0x02, 0xdf, 0xa7, 0xdf, +0xeb, 0xd1, 0xef, 0x76, 0xe9, 0x77, 0x3a, 0xf4, +0x3a, 0x1d, 0x7a, 0xdd, 0x2e, 0xbd, 0x4e, 0x9b, +0x5e, 0xa7, 0x95, 0xbc, 0xb6, 0xdb, 0xf4, 0x7a, +0x1d, 0xfa, 0xbd, 0x2e, 0x7e, 0xb7, 0x4b, 0xd0, +0xef, 0x11, 0xf8, 0x3e, 0x61, 0x18, 0x62, 0xb4, +0x46, 0x48, 0x91, 0x80, 0x6d, 0xf0, 0x1d, 0x49, +0x4f, 0xa3, 0x65, 0xdb, 0xe4, 0xf3, 0x79, 0x46, +0xc7, 0xc6, 0x98, 0xd9, 0x3d, 0xcb, 0xf8, 0xf8, +0x04, 0x8e, 0xe3, 0x10, 0x84, 0x31, 0x91, 0xf6, +0x08, 0x99, 0x62, 0xbd, 0x33, 0xc2, 0xc2, 0x6a, +0x8f, 0x76, 0xab, 0x81, 0x8e, 0xe3, 0x64, 0x5c, +0x05, 0x48, 0x39, 0x94, 0x1e, 0xca, 0x22, 0x82, +0xe1, 0xe8, 0xe0, 0x6a, 0x8c, 0x49, 0xf0, 0x20, +0x46, 0x47, 0xdd, 0xaa, 0x06, 0xf5, 0xfc, 0xb1, +0xfa, 0xbb, 0x52, 0xd0, 0xb0, 0x94, 0x08, 0xc2, +0x28, 0x31, 0x7b, 0x37, 0x0a, 0x0d, 0x6f, 0xe8, +0x03, 0x64, 0xb6, 0xdf, 0xb3, 0x85, 0xf4, 0x23, +0x33, 0x3e, 0x51, 0xb1, 0x1e, 0x7b, 0xea, 0x5f, +0x1c, 0xfa, 0x9f, 0xf7, 0xcf, 0x78, 0x33, 0x99, +0xf4, 0x0f, 0x62, 0xe1, 0x6b, 0x81, 0xe0, 0x7a, +0x3e, 0x81, 0x21, 0x49, 0xff, 0xa6, 0x7f, 0x1b, +0x63, 0x08, 0x35, 0x74, 0x7d, 0xcd, 0x46, 0x2b, +0xe2, 0xe2, 0x5a, 0xcc, 0xe5, 0xce, 0x38, 0x61, +0xf9, 0x63, 0xa8, 0xe2, 0x2c, 0x85, 0x42, 0x99, +0x9c, 0xe7, 0x0e, 0x3e, 0x6a, 0x84, 0x4c, 0xfa, +0x0a, 0xd3, 0x42, 0x94, 0x48, 0x8f, 0x68, 0xad, +0x89, 0xa3, 0x90, 0xa0, 0xef, 0x13, 0x06, 0x3e, +0x51, 0x18, 0x22, 0x85, 0xc0, 0x71, 0x5c, 0xf2, +0xf9, 0x3c, 0xb9, 0x7c, 0x9e, 0x5c, 0xce, 0xc3, +0x75, 0x5d, 0x2c, 0x3b, 0x71, 0x6e, 0x8d, 0xd1, +0xc4, 0x71, 0x12, 0x87, 0x65, 0xce, 0x60, 0x1c, +0x86, 0x84, 0x61, 0x98, 0x80, 0x27, 0x08, 0x88, +0xa3, 0x88, 0x20, 0x0c, 0x10, 0x42, 0xe0, 0xb8, +0x2e, 0x5e, 0x2e, 0xbb, 0x56, 0x0e, 0xcb, 0xb2, +0xd2, 0xb4, 0xf8, 0xd6, 0x86, 0x81, 0x5e, 0xbf, +0xc7, 0xe5, 0x0b, 0x17, 0x38, 0x7f, 0xee, 0x2c, +0xcd, 0x66, 0x93, 0x38, 0x0a, 0xd0, 0xc1, 0x2a, +0x45, 0xf1, 0x01, 0x7b, 0xc7, 0xea, 0xec, 0x9b, +0xb2, 0x99, 0xa8, 0x3a, 0xe4, 0xbd, 0xa4, 0x46, +0x26, 0x32, 0x3b, 0x3a, 0xd4, 0x8b, 0x7e, 0x45, +0x14, 0x41, 0x6a, 0x3d, 0x05, 0x50, 0xb0, 0x68, +0x74, 0xa3, 0xe6, 0xcf, 0xfd, 0xd6, 0xbb, 0xff, +0xf4, 0xcd, 0x0f, 0x3a, 0xff, 0xef, 0x78, 0xcd, +0x5a, 0x58, 0xab, 0x47, 0xb1, 0x31, 0x10, 0xf9, +0xfe, 0x75, 0xf9, 0x7b, 0x43, 0x0d, 0xa0, 0xec, +0xc4, 0x73, 0x76, 0x2c, 0xe1, 0x44, 0x31, 0x73, +0xbf, 0xfc, 0xf8, 0xd8, 0x57, 0x3e, 0xff, 0xf0, +0xc8, 0x23, 0x32, 0x33, 0x8a, 0x64, 0xe6, 0xfc, +0xa3, 0x6a, 0x02, 0x33, 0x70, 0x80, 0x8c, 0x49, +0xe2, 0xf6, 0x7a, 0x3b, 0xe6, 0xc2, 0x6a, 0xc0, +0xfb, 0x8b, 0x16, 0xab, 0xd6, 0x7d, 0xc8, 0x89, +0x47, 0x29, 0x54, 0x77, 0x53, 0xad, 0xd4, 0x70, +0x5d, 0x07, 0x21, 0x24, 0x42, 0x2a, 0xb0, 0xac, +0xa4, 0xe3, 0x28, 0x6d, 0x3a, 0x31, 0xc6, 0x10, +0x06, 0x3e, 0xed, 0x66, 0x93, 0xe6, 0xe6, 0x06, +0xdd, 0x76, 0x1b, 0x29, 0xa0, 0x56, 0xab, 0x31, +0x3b, 0x37, 0xc7, 0xc1, 0x43, 0x87, 0xb8, 0x65, +0xdf, 0x7e, 0xa6, 0x76, 0x4d, 0x53, 0xa9, 0x56, +0x70, 0x1c, 0x17, 0x6d, 0x0c, 0x41, 0x10, 0x10, +0x46, 0x21, 0x51, 0x1c, 0x13, 0xc7, 0x9a, 0x58, +0xc7, 0x69, 0x2b, 0xb7, 0x46, 0xa4, 0x7e, 0x84, +0xe3, 0xba, 0x78, 0xae, 0x87, 0xe7, 0xe5, 0x28, +0x95, 0x4a, 0x38, 0x8e, 0x83, 0xd6, 0x9a, 0x76, +0xab, 0x45, 0xb3, 0x5e, 0xa7, 0xd5, 0x6c, 0x11, +0x45, 0x11, 0x4a, 0x29, 0x1c, 0xc7, 0x49, 0x34, +0x84, 0x90, 0x28, 0x4b, 0x91, 0xf3, 0x72, 0x4c, +0x4c, 0x4d, 0x31, 0xb7, 0x67, 0x2f, 0xb9, 0x5c, +0x9e, 0x6e, 0xaf, 0x47, 0x18, 0x3b, 0xf8, 0x4c, +0xb1, 0x5a, 0xb7, 0x68, 0x34, 0x36, 0x91, 0x22, +0x4c, 0x1a, 0x9f, 0xa4, 0x48, 0x4a, 0x26, 0x3b, +0x98, 0x2e, 0x86, 0x98, 0x7e, 0x05, 0x09, 0xf0, +0x72, 0xca, 0x19, 0xa9, 0xd8, 0xc5, 0xa7, 0x5e, +0xdc, 0x78, 0x45, 0x1b, 0xd6, 0xa5, 0x20, 0x1c, +0xf4, 0x12, 0x5c, 0xa7, 0x60, 0x74, 0x5d, 0x00, +0x64, 0x71, 0xbf, 0xad, 0x10, 0x61, 0x4c, 0xb9, +0x52, 0x50, 0x77, 0xff, 0xee, 0x2f, 0xcf, 0xfe, +0xda, 0x78, 0xd5, 0xa9, 0x22, 0xc4, 0x76, 0xbe, +0xff, 0x18, 0x20, 0x30, 0x06, 0xe2, 0x40, 0xd3, +0x0b, 0x0c, 0x2b, 0xf5, 0x88, 0x13, 0x0b, 0x01, +0x27, 0xeb, 0x33, 0x84, 0x63, 0x9f, 0xc6, 0x1d, +0xbd, 0x95, 0x5a, 0x75, 0x94, 0x42, 0x3e, 0x87, +0x92, 0x69, 0x2f, 0xa0, 0x54, 0xc9, 0x8c, 0xa0, +0xb4, 0xb8, 0xa4, 0xe3, 0x98, 0x6e, 0xbb, 0x4d, +0x63, 0x7d, 0x9d, 0x66, 0xbd, 0x8e, 0x92, 0x92, +0xe9, 0xe9, 0x69, 0x0e, 0x1e, 0x3a, 0xc4, 0xa1, +0xdb, 0x6e, 0x63, 0x76, 0x6e, 0x8e, 0x6a, 0xa5, +0x4a, 0x1c, 0xc7, 0x34, 0x5b, 0x4d, 0x1a, 0xf5, +0x06, 0x9d, 0x56, 0x9b, 0xbe, 0xdf, 0x4f, 0x42, +0xa6, 0x54, 0xc5, 0x26, 0x5b, 0xf2, 0x4f, 0x5e, +0x19, 0xbd, 0x27, 0xb7, 0x2c, 0x13, 0x1f, 0xc2, +0xb2, 0x2c, 0x72, 0x39, 0x8f, 0x5c, 0x2e, 0x8f, +0xe3, 0xd8, 0x18, 0xa3, 0xe9, 0xb4, 0xdb, 0x34, +0x36, 0x37, 0x69, 0xb7, 0x5b, 0xe8, 0x38, 0xc6, +0x73, 0x5d, 0x6c, 0xc7, 0x41, 0xa9, 0x04, 0x44, +0x9e, 0xe7, 0x31, 0x3d, 0x3d, 0xcd, 0x9e, 0xbd, +0x7b, 0xb1, 0x1d, 0x9b, 0x66, 0xa3, 0x45, 0x68, +0x8a, 0xb4, 0xc2, 0x71, 0x96, 0x57, 0x9b, 0x04, +0xfd, 0x26, 0x96, 0x34, 0xd8, 0x0a, 0xec, 0xf4, +0x7b, 0xb6, 0x65, 0x0c, 0xaf, 0xc6, 0xa3, 0xcc, +0x3f, 0xb0, 0xa4, 0x98, 0x9b, 0xf2, 0x26, 0x9f, +0xfa, 0xc1, 0xe6, 0x3b, 0x17, 0x97, 0x83, 0x33, +0xc5, 0xbc, 0xea, 0xf5, 0x03, 0x63, 0x10, 0xe2, +0xba, 0x21, 0xe1, 0x75, 0x01, 0x90, 0xb5, 0x74, +0xd9, 0x4a, 0xd8, 0x91, 0x66, 0xe2, 0x33, 0xf7, +0x56, 0x3e, 0xf7, 0x2b, 0x9f, 0x1e, 0xff, 0x59, +0x29, 0x84, 0xcc, 0xb8, 0xfe, 0x91, 0x40, 0x30, +0xb4, 0xdf, 0x00, 0x91, 0x86, 0x76, 0x3b, 0x62, +0x61, 0x3d, 0xe0, 0xc4, 0x92, 0x62, 0x49, 0xdc, +0x8b, 0x3d, 0xf5, 0x08, 0xc5, 0xea, 0x14, 0x23, +0xb5, 0x2a, 0x8e, 0x6d, 0x83, 0x10, 0xc4, 0x30, +0x28, 0x05, 0x9b, 0x94, 0xf1, 0xed, 0x56, 0x8b, +0xfa, 0xea, 0x2a, 0x9d, 0x66, 0x93, 0x52, 0xb9, +0xc4, 0xc1, 0x43, 0x07, 0x39, 0x7c, 0xe4, 0x30, +0x73, 0x7b, 0xf6, 0x50, 0xa9, 0x54, 0x00, 0x68, +0xd6, 0x1b, 0xac, 0xaf, 0xaf, 0xd3, 0x6a, 0xb5, +0x08, 0xc3, 0x00, 0x8c, 0x4e, 0x66, 0x90, 0x64, +0x8e, 0x5d, 0xe6, 0xe4, 0x49, 0x81, 0x14, 0x89, +0xe4, 0x0a, 0x21, 0x93, 0xf7, 0x52, 0x22, 0xd5, +0x76, 0xb5, 0x3e, 0xb0, 0xfd, 0x32, 0xd5, 0x0e, +0xb6, 0x4b, 0x2e, 0x9f, 0x27, 0x9f, 0x2f, 0x60, +0xdb, 0x36, 0x61, 0x18, 0xd2, 0x6c, 0xd4, 0xd9, +0xdc, 0xdc, 0x24, 0x08, 0x02, 0xbc, 0x5c, 0x0e, +0xd7, 0xf3, 0x50, 0x4a, 0xa1, 0x94, 0x22, 0x5f, +0xc8, 0x33, 0xb3, 0x7b, 0x37, 0x33, 0x33, 0xbb, +0xe9, 0xf7, 0xfb, 0xb4, 0xda, 0x01, 0xbe, 0x18, +0x67, 0xb5, 0x65, 0xd3, 0x69, 0xae, 0xe3, 0xa8, +0x08, 0xc7, 0x16, 0x58, 0x2a, 0xb9, 0xaf, 0xeb, +0xd8, 0xff, 0xad, 0x57, 0x4b, 0x60, 0x29, 0x61, +0x45, 0x10, 0x3f, 0xf7, 0xa3, 0xcd, 0x1f, 0x59, +0x96, 0xac, 0xc7, 0xda, 0x44, 0xc6, 0x88, 0x64, +0x0e, 0xc2, 0x47, 0x02, 0x40, 0xd6, 0xdd, 0x03, +0x9e, 0x94, 0xec, 0xfd, 0x6f, 0x7f, 0x6e, 0xf2, +0x97, 0x8f, 0xdc, 0x92, 0xbf, 0x65, 0xbb, 0xe7, +0xff, 0x11, 0x40, 0x20, 0xb6, 0xcc, 0x7f, 0x10, +0x19, 0xea, 0x9d, 0x98, 0xf3, 0xcb, 0x01, 0xc7, +0x17, 0xf3, 0x74, 0xab, 0x8f, 0xe3, 0x8e, 0x1d, +0xa5, 0x58, 0xae, 0x30, 0x52, 0xad, 0xa0, 0xa4, +0x44, 0x1b, 0x88, 0x30, 0x69, 0x02, 0x28, 0xc9, +0xd4, 0xf5, 0xbb, 0x1d, 0xd6, 0x97, 0x57, 0xe8, +0x34, 0x9b, 0x94, 0x2b, 0x15, 0x8e, 0x1c, 0x3d, +0xca, 0xed, 0x87, 0x0f, 0x33, 0x35, 0x35, 0x8d, +0xeb, 0xb9, 0x68, 0xad, 0x69, 0x36, 0x1a, 0x6c, +0xac, 0xad, 0xd1, 0xeb, 0x76, 0x06, 0xce, 0x5b, +0xc2, 0x5c, 0x95, 0xb6, 0xa7, 0x67, 0xaf, 0x99, +0x36, 0x49, 0xcb, 0xd5, 0x32, 0x73, 0xcf, 0x05, +0x3b, 0x6b, 0xc1, 0x42, 0x5c, 0xb9, 0x0f, 0x29, +0x52, 0x30, 0x28, 0x1c, 0xd7, 0x21, 0x9f, 0xcf, +0xe3, 0xe5, 0x72, 0x89, 0xc6, 0x69, 0xd4, 0xd9, +0x58, 0x5f, 0x27, 0x8a, 0x22, 0xf2, 0xf9, 0x7c, +0xe2, 0x73, 0x28, 0x85, 0x65, 0x59, 0x54, 0x6b, +0x55, 0x6e, 0xd9, 0xb7, 0x0f, 0xcf, 0xcb, 0xb1, +0xbe, 0xbe, 0x41, 0x68, 0x4a, 0x34, 0xfc, 0x22, +0xcd, 0xcd, 0x35, 0x1c, 0x19, 0xe0, 0x58, 0x49, +0x36, 0x31, 0x51, 0x74, 0x99, 0xba, 0x1c, 0x66, +0xfc, 0x50, 0x76, 0xc8, 0x4e, 0x4e, 0xda, 0x35, +0xe1, 0x56, 0xff, 0xf0, 0xbb, 0xab, 0x2f, 0xb6, +0x3b, 0xf1, 0x82, 0xe7, 0xc8, 0x7e, 0x18, 0x99, +0x34, 0xbc, 0xbc, 0xba, 0x0a, 0xb9, 0x2e, 0x00, +0x94, 0x65, 0xa1, 0x24, 0xc2, 0x18, 0xca, 0x23, +0x25, 0xeb, 0xe8, 0xff, 0xf8, 0xf7, 0x77, 0xff, +0x83, 0x62, 0x4e, 0x15, 0xaf, 0x64, 0xf0, 0xcd, +0x82, 0x60, 0x70, 0x10, 0x83, 0x21, 0x08, 0x0d, +0x1b, 0xad, 0x88, 0x53, 0x0b, 0x01, 0xef, 0xaf, +0x8e, 0x61, 0x26, 0x3e, 0x8d, 0x5b, 0xdd, 0x4b, +0xb9, 0x54, 0xa2, 0x56, 0x29, 0x23, 0xa5, 0x24, +0x32, 0x86, 0x40, 0x27, 0x89, 0x04, 0x63, 0x20, +0x0a, 0x43, 0x36, 0xd7, 0x56, 0xd9, 0x58, 0x5d, +0xc5, 0xb1, 0x2d, 0xee, 0x38, 0x72, 0x98, 0x3b, +0xef, 0xba, 0x8b, 0xf1, 0x89, 0xc4, 0xe3, 0x06, +0xe8, 0x75, 0x7b, 0xac, 0xaf, 0xae, 0xd1, 0x6e, +0xb5, 0xd1, 0xda, 0x0c, 0x7c, 0x86, 0xc1, 0x94, +0xb3, 0x61, 0x86, 0x0e, 0xed, 0xcb, 0x36, 0x79, +0x95, 0x7d, 0xc9, 0xe9, 0xa9, 0x44, 0x8a, 0xab, +0x1d, 0xcf, 0x2a, 0x93, 0xc9, 0x35, 0x2d, 0xdb, +0x26, 0x97, 0x02, 0x21, 0x8a, 0x42, 0x36, 0x37, +0x36, 0xd9, 0x58, 0x5f, 0xc7, 0x52, 0x8a, 0x62, +0xa9, 0x84, 0x9d, 0x86, 0xa6, 0x9e, 0xe7, 0xb1, +0x7b, 0x76, 0x37, 0xe3, 0x13, 0x13, 0xac, 0xae, +0xad, 0xd1, 0x0b, 0x24, 0xad, 0xa8, 0xc6, 0xfa, +0xc6, 0x06, 0x4a, 0x77, 0x71, 0x2c, 0x91, 0xb6, +0xcf, 0xa7, 0x55, 0xd0, 0x61, 0xc6, 0x0f, 0x93, +0x2d, 0x11, 0x08, 0xf2, 0x39, 0x95, 0x7b, 0xf7, +0x7c, 0xef, 0xcc, 0xdb, 0x27, 0x3b, 0xef, 0xe6, +0x3c, 0xd9, 0xf6, 0x03, 0xa3, 0x81, 0x6b, 0x46, +0x03, 0xd7, 0x04, 0x40, 0x66, 0xff, 0xa5, 0x40, +0x69, 0x43, 0xed, 0x91, 0xdb, 0x8b, 0x8f, 0x7e, +0xe1, 0xc1, 0x91, 0x9f, 0x76, 0x93, 0x94, 0xaf, +0xb8, 0x1a, 0x63, 0x6f, 0x08, 0x82, 0x94, 0x34, +0xe0, 0x07, 0x09, 0xf3, 0xcf, 0x2c, 0xf8, 0x9c, +0xdc, 0xd8, 0x85, 0x3d, 0xfd, 0x69, 0xdc, 0xe2, +0x14, 0xd5, 0x6a, 0x85, 0x6a, 0xb9, 0x84, 0x48, +0xbd, 0x98, 0x20, 0xd6, 0x69, 0x24, 0x64, 0xe8, +0xb6, 0x5b, 0xac, 0x2e, 0x2e, 0xd0, 0xef, 0xf5, +0x98, 0x9d, 0x9d, 0xe5, 0xbe, 0xfb, 0xef, 0x67, +0xf7, 0xec, 0x2c, 0x4e, 0x9a, 0xa2, 0xd6, 0x5a, +0xd3, 0x6c, 0xb6, 0xd8, 0x58, 0xdf, 0x20, 0x0c, +0xa3, 0xd4, 0x5e, 0xcb, 0x81, 0x24, 0xef, 0x64, +0xb6, 0x94, 0x89, 0xfa, 0xcf, 0xec, 0xfa, 0x16, +0x83, 0x19, 0x30, 0x7c, 0x6b, 0x93, 0x29, 0x90, +0x64, 0x9a, 0x30, 0xda, 0x79, 0x9c, 0x81, 0x86, +0x18, 0xbe, 0x96, 0x65, 0x59, 0x03, 0xc9, 0xef, +0xf7, 0xfa, 0xac, 0x2e, 0x2f, 0xd1, 0x6e, 0xb7, +0x28, 0x95, 0x8a, 0xe4, 0x8b, 0x45, 0x54, 0x6a, +0x4e, 0xaa, 0xb5, 0x1a, 0xbb, 0x67, 0x67, 0x69, +0x36, 0x9b, 0x34, 0x9a, 0x7d, 0x7a, 0x8c, 0xb1, +0xb1, 0xd9, 0x40, 0xe9, 0x16, 0x39, 0x47, 0xe2, +0x0e, 0xf5, 0xd3, 0x6c, 0xa3, 0x2c, 0xc9, 0x66, +0xc9, 0x54, 0x48, 0x0c, 0x8d, 0xd0, 0x04, 0xdf, +0xfd, 0xfe, 0xfa, 0x8b, 0x4a, 0x8a, 0x8d, 0x28, +0x36, 0x91, 0x81, 0x6b, 0xfa, 0x01, 0xd7, 0x04, +0x40, 0x66, 0xe3, 0xa4, 0xc0, 0x36, 0x86, 0xf1, +0x9f, 0xbb, 0xbf, 0xfa, 0xb9, 0xf9, 0x69, 0xf7, +0xd0, 0x68, 0xd1, 0xca, 0x89, 0x8c, 0xab, 0x1f, +0x06, 0x04, 0xe9, 0x5b, 0x63, 0x0c, 0x7e, 0x68, +0x58, 0x6f, 0xc6, 0x9c, 0x5a, 0x08, 0x38, 0xd3, +0xdc, 0x87, 0x33, 0xfd, 0x29, 0x6c, 0xaf, 0x46, +0xb5, 0x5a, 0xa6, 0x56, 0xa9, 0x20, 0x84, 0xc4, +0x8f, 0x22, 0xfc, 0xd4, 0x8d, 0x35, 0x5a, 0xd3, +0xac, 0xd7, 0x59, 0x5d, 0x5c, 0xc4, 0xb1, 0x6d, +0xee, 0xbe, 0xfb, 0x6e, 0x0e, 0x1f, 0x3d, 0x4a, +0xa9, 0x54, 0x1a, 0x60, 0x31, 0x8e, 0x35, 0x1b, +0x1b, 0x1b, 0x34, 0x9b, 0x4d, 0xb4, 0x31, 0x5b, +0x8c, 0x90, 0x62, 0x28, 0x56, 0xdf, 0x62, 0x8c, +0x1c, 0x48, 0xb1, 0x1c, 0x6c, 0x59, 0xa2, 0x47, +0x08, 0xb5, 0x6d, 0x7f, 0x26, 0xf1, 0x09, 0x60, +0xe4, 0x00, 0x58, 0x3b, 0xb7, 0xcc, 0x9f, 0x10, +0x24, 0xe6, 0x24, 0x03, 0x8a, 0x14, 0x12, 0xdb, +0x76, 0xc8, 0xe7, 0x72, 0x08, 0x21, 0xd9, 0xdc, +0xd8, 0x64, 0x75, 0x75, 0x15, 0xc7, 0x71, 0x06, +0xcf, 0x60, 0x80, 0x5c, 0x3e, 0xf1, 0x0d, 0xfa, +0xbd, 0x1e, 0x9b, 0x9b, 0x2d, 0x7c, 0x46, 0xd8, +0xa8, 0x37, 0x71, 0x68, 0x51, 0x70, 0x33, 0x4d, +0x90, 0x85, 0xba, 0x3b, 0x00, 0x60, 0xa7, 0x73, +0x2a, 0x8d, 0xc1, 0xf5, 0x24, 0xff, 0xcf, 0xb3, +0x6b, 0x2f, 0xf8, 0x81, 0x5e, 0x10, 0x42, 0xf8, +0xda, 0x70, 0xcd, 0xa4, 0xd0, 0xcd, 0xa4, 0x82, +0x95, 0x92, 0x94, 0xf6, 0x4f, 0x38, 0xfb, 0xac, +0x48, 0xcb, 0xec, 0x4b, 0x05, 0x43, 0xb5, 0xf0, +0x81, 0x46, 0x4a, 0xec, 0xb4, 0x18, 0x4a, 0xfd, +0x0a, 0x91, 0xa6, 0x37, 0x85, 0x18, 0x62, 0x7e, +0xc4, 0xc9, 0xcb, 0x3e, 0x67, 0x5a, 0xfb, 0xf0, +0x66, 0x1e, 0x43, 0xb9, 0x65, 0xca, 0xe5, 0x22, +0xa3, 0xb5, 0x2a, 0x02, 0x41, 0x3f, 0x0c, 0x08, +0xc2, 0x28, 0xc9, 0x04, 0xc6, 0x31, 0x9b, 0xeb, +0x6b, 0x6c, 0xac, 0xac, 0x52, 0xad, 0x56, 0xf8, +0xd8, 0x7d, 0xf7, 0x31, 0x35, 0xbd, 0x0b, 0x35, +0x98, 0x44, 0x2a, 0x88, 0xa2, 0x88, 0x8d, 0xcd, +0x4d, 0xda, 0xed, 0xf6, 0x00, 0xbc, 0x99, 0x9d, +0x55, 0x96, 0x95, 0xbc, 0xee, 0x98, 0x83, 0x68, +0x74, 0x12, 0xf3, 0xc7, 0x71, 0x9c, 0x6c, 0x3a, +0xde, 0x16, 0x0d, 0x0c, 0x21, 0xf8, 0x2a, 0xb4, +0x63, 0xff, 0x36, 0xb5, 0x9c, 0x35, 0x98, 0xa4, +0xe3, 0x33, 0x5c, 0xf5, 0x73, 0x24, 0xe3, 0x13, +0x93, 0x14, 0x8b, 0x25, 0x56, 0x57, 0x57, 0x78, +0xeb, 0xcd, 0x37, 0x69, 0xd4, 0x1b, 0xcc, 0x1f, +0x3c, 0x90, 0x84, 0x95, 0xc6, 0x50, 0x28, 0x16, +0x79, 0xf8, 0xa7, 0x7e, 0x0a, 0xa9, 0x14, 0xef, +0xbe, 0xfd, 0x36, 0x7d, 0xee, 0xe6, 0xed, 0xc5, +0xd7, 0x90, 0x72, 0x83, 0x79, 0xa0, 0x56, 0xb2, +0x70, 0xad, 0xad, 0x7c, 0x47, 0x72, 0x61, 0x39, +0xb8, 0x0f, 0x01, 0x62, 0x6f, 0x51, 0xcd, 0x8c, +0x54, 0xac, 0x5d, 0xed, 0x4e, 0xec, 0x3a, 0xb6, +0x10, 0x61, 0x64, 0x8c, 0x48, 0xc7, 0x7f, 0x27, +0xdd, 0x10, 0x00, 0xc6, 0x60, 0x97, 0xf3, 0x6a, +0xe4, 0xe8, 0x9e, 0xdc, 0x74, 0x59, 0x09, 0x27, +0x2b, 0xac, 0x6c, 0x03, 0x41, 0x36, 0x26, 0xe9, +0x40, 0x5c, 0x09, 0x02, 0x30, 0xda, 0x10, 0x6a, +0x43, 0xb3, 0x13, 0x73, 0x6e, 0x39, 0xe0, 0x74, +0x7d, 0x06, 0x77, 0xf7, 0x4f, 0x21, 0x9d, 0x12, +0x9e, 0xe7, 0x30, 0x3e, 0x3a, 0x8a, 0x6d, 0x29, +0x7a, 0x7e, 0x40, 0xcf, 0x0f, 0x92, 0xd6, 0xf9, +0x38, 0x66, 0x63, 0x75, 0x85, 0xf5, 0xd5, 0x55, +0xc6, 0xc6, 0xc6, 0x78, 0xe0, 0xa1, 0x87, 0x18, +0x1b, 0x1d, 0xdb, 0xc6, 0x48, 0xad, 0x35, 0xf5, +0x46, 0x83, 0x6e, 0xb7, 0x8b, 0xe3, 0xd8, 0x78, +0x5e, 0x12, 0x9a, 0xd9, 0x29, 0xf3, 0x33, 0x2d, +0x74, 0x35, 0xa6, 0x66, 0xb7, 0x6c, 0x74, 0x12, +0xfb, 0x87, 0x61, 0x48, 0xbf, 0x9f, 0x24, 0x8d, +0x06, 0x9e, 0xf3, 0xb5, 0x30, 0x70, 0xe5, 0x38, +0x6d, 0xbb, 0xee, 0xf0, 0x4e, 0xa3, 0xcd, 0x00, +0x10, 0xc6, 0x18, 0xca, 0x95, 0x0a, 0xae, 0xe7, +0xb2, 0xbc, 0xb4, 0xcc, 0xd9, 0x33, 0xa7, 0xe9, +0xf7, 0x7b, 0xdc, 0x7a, 0xfb, 0xed, 0xb8, 0x9e, +0x87, 0x31, 0x86, 0x5c, 0x3e, 0xcf, 0x03, 0x0f, +0x3e, 0x88, 0x8e, 0x63, 0x8e, 0xbf, 0xf7, 0x1e, +0x3d, 0x73, 0x17, 0xc7, 0x17, 0x7f, 0x84, 0xa3, +0x3a, 0x28, 0x21, 0xa8, 0x16, 0x15, 0xf6, 0x50, +0xc9, 0x03, 0xc5, 0x16, 0x16, 0x22, 0x83, 0xd3, +0x8d, 0x9c, 0x8f, 0x1d, 0x2e, 0xef, 0x3b, 0x7d, +0x61, 0xc5, 0xcb, 0x7b, 0x72, 0x9b, 0x88, 0xee, +0xa4, 0x6b, 0x03, 0x40, 0x0c, 0x18, 0x6b, 0x39, +0x96, 0x28, 0x17, 0x5d, 0x59, 0xae, 0x0a, 0xdc, +0x6d, 0x85, 0xea, 0x0c, 0x04, 0x59, 0x4a, 0x77, +0x07, 0x08, 0xb2, 0x1c, 0x76, 0x12, 0xea, 0x19, +0x3a, 0xdd, 0x98, 0xcb, 0x6b, 0x01, 0xa7, 0xd6, +0x47, 0xb0, 0xa7, 0x1f, 0x43, 0x79, 0x35, 0x84, +0x80, 0xc9, 0xf1, 0x31, 0x5c, 0xd7, 0x21, 0x88, +0x22, 0xba, 0xbe, 0x8f, 0x26, 0x61, 0x4a, 0x7d, +0x7d, 0x9d, 0xb5, 0x95, 0x15, 0xc6, 0xc7, 0xc7, +0x79, 0xe8, 0xe1, 0x47, 0x18, 0x19, 0x1d, 0xdd, +0xe6, 0x7e, 0x68, 0x63, 0x68, 0xb5, 0xdb, 0x44, +0x61, 0xc8, 0xc8, 0xc8, 0x08, 0x5e, 0x1a, 0x6a, +0x89, 0x54, 0x33, 0x0d, 0x9b, 0xa0, 0x9d, 0xe1, +0x67, 0xf6, 0xbf, 0x10, 0x80, 0x54, 0x48, 0x14, +0x8e, 0x93, 0x84, 0x73, 0x71, 0x1c, 0x13, 0xf8, +0x01, 0xfd, 0x7e, 0x8f, 0x28, 0xcd, 0x13, 0x7c, +0x18, 0x1a, 0x0c, 0xc3, 0xb0, 0x89, 0x34, 0x69, +0xe1, 0xc9, 0x40, 0x1c, 0x85, 0xe4, 0x0b, 0x05, +0x76, 0xed, 0x9e, 0x61, 0x75, 0x69, 0x99, 0xc5, +0xc5, 0x45, 0xc2, 0x30, 0xe4, 0xd6, 0xdb, 0xef, +0x20, 0x9f, 0xcf, 0x61, 0x0c, 0x78, 0x5e, 0x8e, +0x8f, 0xdf, 0xff, 0x09, 0xba, 0xdd, 0x2e, 0x67, +0xcf, 0xc4, 0x34, 0xcc, 0x5d, 0x1c, 0x5f, 0x78, +0x05, 0xcf, 0x0a, 0x70, 0x94, 0x43, 0x39, 0xaf, +0x90, 0x59, 0x5b, 0xbd, 0xda, 0x52, 0xff, 0xf4, +0x22, 0x44, 0x37, 0x16, 0xfb, 0x77, 0xe7, 0xf6, +0x00, 0xb9, 0x28, 0x36, 0x12, 0xd0, 0x42, 0xca, +0xab, 0xfa, 0x01, 0xd7, 0x04, 0x40, 0x96, 0xe6, +0x11, 0xa0, 0x94, 0x14, 0xc5, 0xa9, 0x92, 0x55, +0x13, 0xcd, 0xa1, 0x99, 0x29, 0xc3, 0x12, 0x9e, +0x8a, 0xb9, 0xd9, 0x59, 0xf5, 0x4b, 0x6d, 0x9b, +0x8e, 0x0d, 0x9d, 0x7e, 0xcc, 0xe2, 0x7a, 0xc0, +0x89, 0x45, 0x97, 0xb8, 0xf6, 0x08, 0x5e, 0x7e, +0x0c, 0xad, 0x63, 0x26, 0x26, 0xc6, 0x29, 0x15, +0x8b, 0x68, 0x63, 0xe8, 0xf4, 0x7a, 0xc4, 0x3a, +0x49, 0xc5, 0x36, 0xeb, 0x75, 0x96, 0x17, 0x17, +0xa8, 0x56, 0xab, 0x7c, 0xe2, 0x81, 0x07, 0x19, +0x1d, 0x1b, 0xdb, 0x26, 0xc5, 0xc6, 0x18, 0xe2, +0x28, 0x42, 0x49, 0xc9, 0xe8, 0xe8, 0x18, 0xca, +0x1a, 0x9a, 0x78, 0x9a, 0xdd, 0xf9, 0xd0, 0xf8, +0x6f, 0x71, 0xfb, 0xea, 0x24, 0xd3, 0x63, 0x8a, +0x24, 0x56, 0x77, 0x6c, 0x87, 0x42, 0xa1, 0x80, +0xef, 0xfb, 0xf4, 0x7a, 0x3d, 0xc2, 0x1d, 0xb3, +0x72, 0xae, 0x70, 0xc6, 0x53, 0xb5, 0xbf, 0x75, +0x34, 0xcb, 0xd3, 0x9a, 0xed, 0xa6, 0x27, 0x3d, +0x25, 0x0c, 0x43, 0x0a, 0xc5, 0x22, 0xd6, 0x4c, +0x92, 0x67, 0x58, 0x5d, 0x5d, 0xc5, 0xbc, 0xfb, +0x2e, 0xb7, 0x1d, 0xbe, 0x03, 0xcf, 0xf5, 0x30, +0x46, 0x53, 0x28, 0x16, 0xb8, 0xff, 0x81, 0x07, +0xe8, 0x76, 0xba, 0x2c, 0x2f, 0x0b, 0xd6, 0xda, +0xb7, 0x71, 0xe2, 0xf2, 0x1b, 0xe4, 0x9c, 0x10, +0xc7, 0x12, 0xe4, 0x1c, 0x89, 0xf0, 0x52, 0x37, +0xce, 0xe8, 0x34, 0xad, 0x1e, 0x21, 0xfa, 0x31, +0xb5, 0x92, 0x35, 0x01, 0x78, 0x8e, 0x2d, 0x65, +0xa7, 0x77, 0xed, 0x3c, 0xc0, 0x0d, 0x4d, 0x80, +0x36, 0x28, 0x29, 0x71, 0x73, 0x96, 0xf0, 0x44, +0xa8, 0x05, 0xa1, 0x66, 0xa0, 0x7f, 0x76, 0x30, +0x5c, 0x5c, 0x05, 0x04, 0x06, 0xe8, 0x07, 0x3a, +0xb1, 0xfb, 0x4b, 0x50, 0x77, 0xef, 0xa5, 0x58, +0x99, 0x45, 0x1b, 0x43, 0xde, 0xcb, 0x31, 0x31, +0x36, 0x86, 0x52, 0x8a, 0x4e, 0xa7, 0x8b, 0x9f, +0xda, 0xfd, 0x7e, 0xb7, 0xc7, 0xf2, 0xc2, 0x65, +0x5c, 0xc7, 0xe5, 0x63, 0x1f, 0xff, 0x38, 0xe3, +0x13, 0x13, 0x03, 0xe6, 0x1b, 0x18, 0xd4, 0xe0, +0xfb, 0xfd, 0x3e, 0x71, 0x9c, 0xa8, 0xee, 0xa4, +0x9e, 0xaf, 0xb0, 0x6d, 0x3b, 0x4d, 0x17, 0xef, +0x48, 0xa0, 0x6c, 0x03, 0x44, 0x66, 0xbc, 0xb6, +0x47, 0x29, 0x5a, 0x6b, 0xa2, 0x30, 0x22, 0x08, +0xc3, 0xa4, 0xe7, 0x7e, 0xf0, 0x51, 0x91, 0x24, +0x78, 0xa2, 0x70, 0xf0, 0xcc, 0x57, 0xc3, 0x93, +0x41, 0x0e, 0x4a, 0xba, 0x71, 0x94, 0xf8, 0x15, +0x59, 0x7d, 0x5f, 0x59, 0x0a, 0x25, 0xe5, 0x96, +0x4f, 0x64, 0x0c, 0x41, 0xbf, 0x4f, 0xb1, 0x58, +0x82, 0xa9, 0xe4, 0x42, 0x6b, 0x6b, 0xab, 0x9c, +0x38, 0x7e, 0x9c, 0x43, 0xb7, 0xde, 0x8a, 0xed, +0x38, 0x18, 0x63, 0xa8, 0x8d, 0x8c, 0xf0, 0xb1, +0xfb, 0xef, 0xe7, 0xf9, 0xe7, 0x9e, 0xa5, 0xa5, +0xe7, 0xb8, 0xd4, 0xaa, 0x53, 0x5b, 0x3e, 0x43, +0xc9, 0x53, 0xa8, 0x11, 0x89, 0xa3, 0xc4, 0x56, +0x95, 0xd0, 0x18, 0x68, 0x47, 0x10, 0x6a, 0x31, +0x39, 0xea, 0x94, 0x6d, 0x4b, 0xb8, 0xfd, 0x40, +0x5f, 0x07, 0xf6, 0x37, 0xe7, 0x03, 0x08, 0x40, +0x0e, 0x16, 0x4c, 0xe9, 0xc5, 0x83, 0x90, 0xe3, +0x46, 0x20, 0x30, 0x06, 0xa2, 0xd8, 0xd0, 0xec, +0xc5, 0x5c, 0x58, 0x09, 0x59, 0x08, 0xe6, 0xc9, +0xcd, 0xde, 0x8e, 0x49, 0x4b, 0x95, 0x13, 0xe3, +0x63, 0xb8, 0x9e, 0x4b, 0x18, 0x86, 0x74, 0xfb, +0xfd, 0x54, 0xaa, 0x63, 0x56, 0x16, 0x16, 0x88, +0xc2, 0x90, 0x3b, 0xef, 0xba, 0x9b, 0xb9, 0x3d, +0x7b, 0x91, 0x52, 0x26, 0xc7, 0xe2, 0x98, 0x76, +0xbb, 0xcd, 0x85, 0x0b, 0xe7, 0x39, 0x7d, 0xfa, +0x0c, 0x27, 0x4f, 0x7e, 0x40, 0xa7, 0xd3, 0x01, +0x04, 0xae, 0xe3, 0x30, 0x3e, 0x31, 0xce, 0xfc, +0xfc, 0x3c, 0x47, 0xef, 0xbc, 0x93, 0x72, 0xb9, +0x9c, 0x14, 0x67, 0xb2, 0xb8, 0x7f, 0x1b, 0x65, +0xa9, 0xde, 0x2d, 0xc6, 0xfb, 0x81, 0xcf, 0xe6, +0xe6, 0x26, 0xe7, 0xcf, 0x9d, 0xe3, 0xad, 0xb7, +0xde, 0x62, 0x61, 0x61, 0x71, 0x70, 0xdc, 0x75, +0x1d, 0x0e, 0x1f, 0x3e, 0xcc, 0xfc, 0xfc, 0x01, +0xaa, 0x95, 0x4a, 0xd2, 0x63, 0xa0, 0x24, 0x3b, +0x20, 0x46, 0x06, 0xf8, 0x4e, 0xbb, 0xcb, 0xb9, +0x73, 0xe7, 0xd8, 0xd8, 0xd8, 0x48, 0x8b, 0x4b, +0xb0, 0x6f, 0xdf, 0x3e, 0x76, 0xef, 0xde, 0x3d, +0x70, 0x10, 0xb3, 0x6e, 0x23, 0x3f, 0xf0, 0x29, +0x95, 0x4b, 0xa9, 0x23, 0xaa, 0x59, 0x59, 0x5e, +0xc6, 0x71, 0x1c, 0x6e, 0xd9, 0xbf, 0x1f, 0x29, +0x13, 0xe9, 0x9e, 0x9e, 0x9e, 0xe6, 0xf6, 0xc3, +0x47, 0x78, 0xed, 0x95, 0x1f, 0x11, 0x15, 0x0e, +0x72, 0x76, 0x73, 0x8d, 0xb1, 0x6a, 0x07, 0xaf, +0x62, 0xa1, 0x62, 0x93, 0xe6, 0x08, 0x48, 0x5a, +0xa4, 0x5a, 0x11, 0x02, 0x98, 0x18, 0x75, 0x73, +0xae, 0x23, 0x1d, 0xd8, 0xf6, 0xa8, 0x1f, 0x1e, +0x00, 0x43, 0x23, 0x96, 0x50, 0x27, 0x82, 0x92, +0x95, 0x3d, 0x2f, 0xdb, 0x62, 0xfd, 0x0c, 0x04, +0x89, 0x51, 0xc0, 0x18, 0x43, 0xcf, 0xd7, 0x2c, +0x6f, 0x84, 0x9c, 0x59, 0x2f, 0xa0, 0xa6, 0xee, +0x41, 0x39, 0x1e, 0x61, 0x10, 0x50, 0x2e, 0x15, +0x19, 0x1b, 0xad, 0x21, 0x84, 0xa0, 0xdb, 0xef, +0x13, 0xc5, 0x89, 0xb4, 0xd4, 0x37, 0xd6, 0x69, +0xd4, 0x37, 0x99, 0x9d, 0x9b, 0xe3, 0xb6, 0xdb, +0x6f, 0x43, 0xa5, 0xf6, 0xad, 0xd1, 0x68, 0xf0, +0xca, 0x2b, 0xaf, 0xf0, 0xe4, 0x93, 0x4f, 0x72, +0xf1, 0xe2, 0x85, 0x41, 0xc8, 0x17, 0xa5, 0x92, +0x2a, 0xa5, 0x24, 0x97, 0xcb, 0x51, 0xab, 0xd5, +0x98, 0x9f, 0x9f, 0xe7, 0x53, 0x8f, 0x3f, 0xce, +0x03, 0x9f, 0x78, 0x80, 0x89, 0xc9, 0x89, 0x6d, +0x92, 0xbe, 0xc3, 0x23, 0x20, 0x0c, 0x43, 0xce, +0x9d, 0x3d, 0xcb, 0x7f, 0xfc, 0x93, 0xff, 0xc8, +0x3b, 0xef, 0xbc, 0xc3, 0xfa, 0xfa, 0x3a, 0xeb, +0xeb, 0xeb, 0x29, 0xb0, 0x12, 0x52, 0x4a, 0xf1, +0xf4, 0xd3, 0x4f, 0x53, 0xad, 0x56, 0x99, 0x9b, +0x9b, 0xe3, 0x91, 0x87, 0x1f, 0xe1, 0x81, 0x07, +0x1e, 0x24, 0x9f, 0xcf, 0x0f, 0xcc, 0x8b, 0xc9, +0x9a, 0x39, 0x30, 0x6c, 0xac, 0x6f, 0xf0, 0xed, +0x6f, 0x7f, 0x9b, 0x37, 0xdf, 0x7c, 0x93, 0x20, +0xed, 0xcc, 0xf9, 0xa5, 0x5f, 0xfa, 0x25, 0xe6, +0xe6, 0x66, 0xd3, 0x21, 0x12, 0x83, 0xf3, 0xa3, +0x28, 0x01, 0x48, 0xa5, 0x52, 0x21, 0x8e, 0x35, +0x81, 0xef, 0xb3, 0x70, 0xe9, 0x32, 0xf9, 0x42, +0x81, 0xa9, 0xe9, 0xe9, 0xe4, 0x6e, 0xa5, 0x64, +0xfe, 0xc0, 0x01, 0x16, 0x17, 0x2e, 0x73, 0xe9, +0xa2, 0xa6, 0x5f, 0xb8, 0x93, 0xb3, 0x9b, 0x2f, +0x53, 0xae, 0xc5, 0x38, 0xb6, 0x24, 0xef, 0xa6, +0xcc, 0x69, 0x86, 0xc9, 0xd4, 0x79, 0x47, 0x42, +0xe2, 0x6e, 0xc8, 0xcc, 0x3d, 0xb8, 0x16, 0xdd, +0x0c, 0x00, 0x0c, 0xa0, 0x93, 0x09, 0x9c, 0x80, +0x9f, 0xcc, 0xd6, 0xc5, 0x53, 0xa9, 0x0e, 0xcc, +0x6c, 0xdd, 0x10, 0x08, 0xd2, 0xee, 0x9e, 0x28, +0x4a, 0xea, 0xf9, 0x17, 0xd6, 0x0c, 0x6d, 0xef, +0x30, 0x95, 0xd2, 0x04, 0x61, 0x18, 0x11, 0xa7, +0xd2, 0xef, 0x38, 0x4e, 0x22, 0xfd, 0xbd, 0x7e, +0xc2, 0x8c, 0xc0, 0x67, 0x7d, 0x75, 0x05, 0xc7, +0x75, 0x39, 0x7c, 0xe4, 0x28, 0xf9, 0x7c, 0x1e, +0x10, 0xd4, 0xeb, 0x75, 0x9e, 0x7d, 0xf6, 0x19, +0xfe, 0xf0, 0x0f, 0xff, 0x90, 0x63, 0xc7, 0x8e, +0xd1, 0x6e, 0xb7, 0xaf, 0xe9, 0x98, 0x09, 0x21, +0x78, 0xff, 0xfd, 0xf7, 0x39, 0x7f, 0xfe, 0x3c, +0xed, 0x56, 0x9b, 0xc7, 0x3f, 0xfd, 0x38, 0x53, +0x93, 0x93, 0x64, 0x5e, 0xe1, 0x70, 0x98, 0xb7, +0xbe, 0xbe, 0xce, 0x2b, 0xaf, 0xbe, 0xc2, 0x37, +0xbe, 0xf1, 0x0d, 0x5e, 0x7c, 0xf1, 0x45, 0x16, +0x16, 0x16, 0x06, 0x80, 0xda, 0x49, 0x97, 0x2e, +0x5d, 0x02, 0xa0, 0x5c, 0x2e, 0x73, 0xea, 0xd4, +0x29, 0x2e, 0x5e, 0xba, 0xc8, 0x63, 0x8f, 0x7d, +0x92, 0xb9, 0xb9, 0x39, 0x2c, 0xcb, 0x1a, 0xa8, +0x7e, 0x00, 0x3f, 0x08, 0x38, 0x7f, 0xfe, 0x02, +0xef, 0xbc, 0xf3, 0x0e, 0xfd, 0x7e, 0x7f, 0xf0, +0x5d, 0x4a, 0x59, 0x83, 0x5e, 0xc3, 0xc1, 0xcc, +0x03, 0x03, 0xbe, 0xef, 0x53, 0x2e, 0x97, 0x29, +0x97, 0x4b, 0xc4, 0x7a, 0x8a, 0x8b, 0x17, 0x2e, +0x70, 0xe1, 0xfc, 0x79, 0x0a, 0x85, 0x22, 0x85, +0x62, 0x71, 0x10, 0x19, 0xdc, 0x76, 0xc7, 0x1d, +0xac, 0xaf, 0xaf, 0xd3, 0xef, 0x8e, 0xb3, 0x16, +0xee, 0x61, 0x71, 0xfd, 0x1c, 0xa5, 0x9c, 0xc2, +0x51, 0x49, 0x19, 0x99, 0x35, 0x3f, 0x19, 0xfa, +0x9b, 0x60, 0x6a, 0x46, 0x37, 0x04, 0x80, 0x92, +0x68, 0x63, 0x08, 0x23, 0x21, 0x22, 0x05, 0x0e, +0x24, 0x6a, 0x06, 0x47, 0xb1, 0xad, 0xcb, 0x71, +0x07, 0x08, 0xb4, 0xd1, 0xf4, 0x7c, 0xcd, 0x5a, +0x23, 0x62, 0xb1, 0x3b, 0x4a, 0x6e, 0xe6, 0x56, +0xb4, 0x36, 0x44, 0x61, 0x88, 0xe3, 0xd8, 0xd4, +0xaa, 0x55, 0x94, 0x52, 0x6c, 0x36, 0x9a, 0xa9, +0xf4, 0x27, 0x8e, 0x5f, 0xaf, 0xd3, 0xe1, 0xc0, +0x81, 0x83, 0xcc, 0xec, 0xde, 0x8d, 0x10, 0x89, +0xea, 0x7f, 0xe7, 0x9d, 0xb7, 0xf9, 0x4f, 0xff, +0xe9, 0x1b, 0x3c, 0xff, 0xfc, 0xf3, 0xdb, 0x18, +0x3d, 0x3e, 0x3e, 0x8e, 0xe7, 0x79, 0x00, 0xf4, +0x7a, 0x3d, 0xd6, 0xd6, 0xd6, 0x30, 0xc6, 0xd0, +0x6a, 0xb5, 0x78, 0xe9, 0xa5, 0x97, 0x70, 0x1c, +0x87, 0x89, 0xf1, 0x71, 0xa6, 0x7f, 0xe6, 0x33, +0x69, 0x64, 0xb0, 0xa5, 0xb4, 0x37, 0x36, 0x37, +0x78, 0xf1, 0xc5, 0xef, 0xf3, 0x07, 0xff, 0xfe, +0xdf, 0xf3, 0xdc, 0x73, 0xcf, 0x6d, 0x63, 0x7c, +0xb1, 0x58, 0xdc, 0x56, 0xf2, 0xed, 0xf5, 0x7a, +0xd4, 0xeb, 0x75, 0xa2, 0x28, 0xa2, 0xd9, 0x6c, +0xf2, 0xf2, 0xcb, 0x2f, 0x73, 0xf9, 0xf2, 0x65, +0x3a, 0x9d, 0x0e, 0x9f, 0xfb, 0xb9, 0x9f, 0x63, +0x76, 0x76, 0x16, 0xdb, 0xb6, 0xd3, 0xc1, 0x37, +0x69, 0xa2, 0x68, 0xfb, 0x38, 0x4a, 0x29, 0x93, +0x6a, 0xe6, 0x70, 0x5e, 0xde, 0x80, 0x4e, 0x7d, +0x82, 0x20, 0x0c, 0x29, 0x16, 0x8b, 0x84, 0x51, +0xc8, 0xd8, 0xd8, 0x18, 0x8b, 0x0b, 0x0b, 0x5c, +0xba, 0x78, 0x91, 0xfd, 0xf3, 0xf3, 0xc9, 0xa4, +0x5b, 0x63, 0x98, 0x9c, 0x9c, 0x62, 0x66, 0xf7, +0x6e, 0xce, 0x9c, 0x3a, 0x45, 0x60, 0xef, 0x63, +0xb1, 0xbe, 0xc4, 0x78, 0x39, 0xa4, 0xe8, 0x0a, +0xec, 0x7e, 0x8c, 0x68, 0x27, 0xcf, 0x60, 0x6c, +0x49, 0xaa, 0xb1, 0x6f, 0x38, 0x55, 0xe0, 0x9a, +0x00, 0x48, 0x93, 0x22, 0x89, 0x59, 0xd6, 0xa6, +0xdb, 0xf2, 0xe3, 0xb6, 0xa3, 0x18, 0x11, 0x06, +0x4c, 0x90, 0xcc, 0xe1, 0x23, 0xaf, 0x86, 0xd4, +0xeb, 0x16, 0x08, 0x0c, 0x10, 0x86, 0x86, 0x46, +0x27, 0xe6, 0xe2, 0x9a, 0xc6, 0xcf, 0xdf, 0x46, +0xde, 0xc9, 0xa5, 0x4d, 0x15, 0x3e, 0xe3, 0x63, +0x23, 0x14, 0x4b, 0x45, 0x8c, 0x36, 0xf8, 0xa9, +0x8a, 0x8c, 0xe3, 0x98, 0xb5, 0xd5, 0x15, 0x6c, +0xc7, 0xe1, 0xf6, 0x23, 0x87, 0x07, 0x79, 0xfd, +0x4e, 0xa7, 0xc3, 0xf7, 0xbf, 0xff, 0x7d, 0x5e, +0x7f, 0xfd, 0x58, 0x72, 0xc3, 0x96, 0xc5, 0xc8, +0xc8, 0x08, 0x73, 0x73, 0x73, 0xdc, 0x7d, 0xf7, +0xdd, 0xd4, 0x6a, 0x23, 0x20, 0x60, 0x6d, 0x6d, +0x8d, 0xd7, 0x8f, 0x1d, 0xe3, 0xec, 0xd9, 0xa4, +0xe9, 0x42, 0x6b, 0xcd, 0xb1, 0x63, 0xc7, 0x78, +0xf9, 0x87, 0x2f, 0xf3, 0xd0, 0x43, 0x0f, 0x51, +0xae, 0x94, 0x07, 0xe9, 0x5b, 0x63, 0x0c, 0x6f, +0xbe, 0xf9, 0x26, 0x7f, 0xf4, 0xd5, 0xaf, 0xf2, +0xec, 0xb3, 0xcf, 0x12, 0xc7, 0x31, 0x42, 0x08, +0x8a, 0xc5, 0x22, 0xbb, 0x76, 0xed, 0xe2, 0xd6, +0x5b, 0x6f, 0x65, 0xcf, 0x9e, 0x3d, 0x14, 0x0b, +0x05, 0xa2, 0x38, 0x66, 0x7d, 0x7d, 0x9d, 0x53, +0xa7, 0x4e, 0x71, 0xf2, 0xe4, 0x49, 0xd6, 0xd6, +0xd6, 0x08, 0x82, 0x80, 0x4b, 0x97, 0x2e, 0xf1, +0xd5, 0xaf, 0x7e, 0x95, 0x62, 0xb1, 0xc8, 0x97, +0x7e, 0xf1, 0x17, 0xc9, 0xa5, 0x31, 0x3c, 0x88, +0x6d, 0xed, 0x67, 0x29, 0x5a, 0x93, 0x6c, 0xa1, +0xa5, 0x10, 0x59, 0xef, 0x43, 0xea, 0x07, 0x88, +0xcc, 0x14, 0x84, 0x11, 0xf9, 0x5c, 0x8e, 0x7c, +0xbe, 0xc0, 0xc8, 0xc8, 0x28, 0x9d, 0x56, 0x8b, +0xd5, 0x95, 0x65, 0x46, 0x46, 0x47, 0x18, 0x19, +0x1d, 0xc3, 0x18, 0x83, 0x54, 0x8a, 0x5b, 0xf6, +0xed, 0x67, 0xe1, 0xf2, 0x65, 0x82, 0xbe, 0xa1, +0xde, 0x9f, 0x62, 0xa5, 0x7e, 0x8e, 0x11, 0x2f, +0xc2, 0x5d, 0xed, 0xa3, 0x74, 0xaa, 0x94, 0x1d, +0x49, 0xa7, 0xaf, 0x83, 0x38, 0x36, 0xa1, 0x10, +0x43, 0xc1, 0xc9, 0x87, 0x01, 0xc0, 0x20, 0x89, +0x01, 0x51, 0x18, 0x99, 0xe6, 0x7a, 0x3b, 0x6e, +0x8c, 0xda, 0x72, 0xc4, 0xf8, 0xe9, 0xcc, 0x85, +0x4e, 0x98, 0xd8, 0x1a, 0x8b, 0x41, 0x62, 0x28, +0x03, 0x81, 0x36, 0xc9, 0xec, 0x9b, 0xcd, 0x56, +0xc4, 0x52, 0x7f, 0x14, 0x35, 0xbe, 0x0b, 0xad, +0x0d, 0xbe, 0xdf, 0x47, 0x6b, 0x4d, 0xad, 0x56, +0xc3, 0x52, 0x8a, 0x8e, 0xdf, 0x23, 0x48, 0xc3, +0xab, 0x4e, 0xab, 0x45, 0xaf, 0xd3, 0x65, 0x6e, +0xcf, 0x1e, 0x26, 0x26, 0x26, 0x21, 0xcd, 0xed, +0x5f, 0xba, 0x7c, 0x99, 0x13, 0x27, 0x4e, 0xb0, +0xba, 0xba, 0x0a, 0x40, 0xb9, 0x5c, 0xe1, 0xd3, +0x9f, 0xfe, 0x69, 0xbe, 0xf2, 0x95, 0xaf, 0x30, +0x7f, 0xe0, 0x00, 0xae, 0x9b, 0x34, 0x24, 0xfb, +0xfd, 0x3e, 0xef, 0xbc, 0xfb, 0x2e, 0xff, 0xe7, +0xef, 0xfd, 0x1e, 0xcf, 0x3f, 0xff, 0x3c, 0xed, +0x76, 0x9b, 0x56, 0xab, 0xc5, 0xf1, 0xe3, 0xc7, +0x79, 0xeb, 0xed, 0xb7, 0x78, 0xf0, 0xc1, 0x87, +0xb0, 0xac, 0x24, 0x63, 0xd2, 0x6e, 0xb7, 0x79, +0xfe, 0xf9, 0x17, 0x78, 0xf9, 0xe5, 0x97, 0x89, +0xe3, 0x38, 0xc9, 0xc5, 0x57, 0xab, 0xdc, 0x77, +0xdf, 0x7d, 0x7c, 0xe1, 0x8b, 0x5f, 0xe4, 0xc1, +0x07, 0x1e, 0x60, 0x6c, 0x6c, 0x0c, 0x99, 0x86, +0xb1, 0x71, 0x14, 0xb1, 0xbc, 0xbc, 0xcc, 0x7f, +0xf8, 0x0f, 0xff, 0x81, 0x27, 0xbf, 0xf5, 0x2d, +0x4e, 0x9f, 0x3e, 0x8d, 0xef, 0xfb, 0xac, 0xad, +0xad, 0xf1, 0xe4, 0x93, 0x4f, 0xf2, 0xe8, 0xa3, +0x8f, 0x32, 0x52, 0xab, 0xa1, 0xd2, 0xae, 0x24, +0xb9, 0x23, 0x69, 0x9f, 0x44, 0x0c, 0x49, 0xfa, +0xd9, 0x48, 0x33, 0x94, 0x21, 0x4d, 0x17, 0xb5, +0x32, 0x49, 0xb2, 0x48, 0x6b, 0x4d, 0x3e, 0x9f, +0x23, 0x08, 0x7c, 0xc6, 0xc6, 0x27, 0x68, 0xb7, +0xcf, 0xb2, 0xb4, 0xb0, 0x48, 0xa9, 0x54, 0x46, +0x5a, 0x16, 0x06, 0x18, 0x19, 0x1d, 0x65, 0x7c, +0x7c, 0x82, 0x8b, 0x17, 0xce, 0x43, 0xe1, 0x10, +0x4b, 0x9b, 0xe7, 0xd9, 0x15, 0x74, 0x29, 0xa5, +0x0b, 0x25, 0x02, 0xe0, 0x29, 0x73, 0xee, 0x74, +0xbf, 0xde, 0xf7, 0x75, 0xaf, 0x5c, 0x54, 0xba, +0x77, 0x06, 0x0c, 0x76, 0x59, 0x00, 0x00, 0x20, +0x00, 0x49, 0x44, 0x41, 0x54, 0x6d, 0xfe, 0x73, +0x03, 0x17, 0x01, 0x04, 0x44, 0xed, 0xbe, 0xae, +0x9f, 0x58, 0xf4, 0x97, 0x71, 0xa5, 0xc9, 0x42, +0x5c, 0x62, 0xa0, 0x1d, 0x26, 0x4b, 0x9f, 0x0c, +0x85, 0xbf, 0x89, 0xb7, 0x6e, 0xe8, 0xf6, 0x34, +0x2b, 0x4d, 0x4d, 0x5b, 0xce, 0xa0, 0xdc, 0x22, +0x41, 0xe0, 0x27, 0xe1, 0x95, 0xd6, 0x8c, 0xd6, +0x6a, 0x48, 0x21, 0x09, 0xd3, 0x8c, 0x9b, 0x00, +0x1a, 0x9b, 0x9b, 0x18, 0x63, 0x98, 0x9d, 0x9b, +0xc3, 0x75, 0xdd, 0x34, 0x2e, 0x37, 0x34, 0xea, +0x9b, 0x74, 0x3a, 0x9d, 0x41, 0x66, 0xae, 0x58, +0x2c, 0x70, 0xf4, 0xe8, 0x11, 0x6e, 0xd9, 0x77, +0x0b, 0xb5, 0x6a, 0x85, 0x62, 0x21, 0x4f, 0x21, +0x95, 0x9a, 0x3b, 0x8f, 0x1c, 0xe5, 0x17, 0xbf, +0xf4, 0x8b, 0xec, 0xde, 0xbd, 0x9b, 0x62, 0xb1, +0x48, 0xa1, 0x50, 0x60, 0x7d, 0x7d, 0x9d, 0x93, +0x27, 0x4f, 0xa5, 0xdd, 0x3d, 0x82, 0x38, 0x8e, +0x79, 0xe9, 0x07, 0x3f, 0xe0, 0xd8, 0xb1, 0xd7, +0xa8, 0xd7, 0xeb, 0x00, 0x94, 0x4a, 0x25, 0x1e, +0x7f, 0xfc, 0x71, 0xfe, 0xe9, 0x3f, 0xfb, 0x67, +0x7c, 0xee, 0x73, 0x9f, 0x63, 0xf7, 0xec, 0x1c, +0xc5, 0x52, 0x89, 0x42, 0xb1, 0x48, 0xb1, 0x58, +0xa4, 0x5c, 0xa9, 0xb2, 0x6f, 0xff, 0x7e, 0xfe, +0xf1, 0x3f, 0xf9, 0x75, 0x7e, 0xe5, 0x57, 0x7e, +0x85, 0x5b, 0x6f, 0xbd, 0x15, 0x21, 0x04, 0x61, +0x18, 0x72, 0xfe, 0xfc, 0x79, 0x9e, 0x7b, 0xee, +0x7b, 0xd4, 0xeb, 0x0d, 0x2c, 0xcb, 0x46, 0x2a, +0x0b, 0x29, 0xd5, 0x15, 0x91, 0x87, 0x94, 0x02, +0x4b, 0x49, 0x2c, 0x25, 0x51, 0x56, 0xd2, 0x58, +0x2a, 0xa5, 0x44, 0x64, 0xbd, 0x06, 0x42, 0x10, +0x45, 0x31, 0x96, 0x65, 0x93, 0xf3, 0x72, 0x94, +0xcb, 0x15, 0x4a, 0xe5, 0x32, 0x8d, 0x7a, 0x9d, +0x7a, 0xbd, 0x3e, 0x30, 0x1d, 0xb6, 0x6d, 0xb3, +0x6b, 0xf7, 0x6e, 0x1c, 0xc7, 0xc1, 0xd7, 0x79, +0xfa, 0xc1, 0x04, 0x9b, 0x8b, 0x3e, 0x41, 0x94, +0x1c, 0x37, 0x80, 0x29, 0xd9, 0xac, 0x6d, 0x86, +0x8b, 0x40, 0x3f, 0x8a, 0xcd, 0x75, 0x8d, 0xc0, +0xcd, 0x38, 0x81, 0x51, 0x18, 0x99, 0xe6, 0xbb, +0x17, 0x7a, 0x67, 0x3f, 0x7b, 0x28, 0x7f, 0xbf, +0x68, 0x44, 0x49, 0xb8, 0x61, 0x93, 0xbc, 0x76, +0x23, 0xc8, 0x5b, 0x49, 0xc5, 0x2d, 0x45, 0x41, +0x18, 0x69, 0x9a, 0xdd, 0x98, 0xc5, 0x56, 0x0e, +0x59, 0x99, 0x25, 0x8c, 0x22, 0xc2, 0x30, 0x24, +0x08, 0x02, 0xca, 0xa5, 0x12, 0x85, 0x62, 0x01, +0x21, 0x05, 0xfd, 0xc0, 0x47, 0x08, 0x41, 0x10, +0x04, 0xb4, 0x5b, 0x2d, 0x3c, 0xcf, 0x63, 0x62, +0x62, 0x22, 0x95, 0xa0, 0xe1, 0x32, 0xc3, 0xd6, +0x60, 0x36, 0x9b, 0x4d, 0x5e, 0x7b, 0xed, 0x35, +0xee, 0xbf, 0xef, 0x7e, 0xca, 0xc5, 0x62, 0x02, +0x96, 0x74, 0xc0, 0x2b, 0xd5, 0x0a, 0x0f, 0x3c, +0xf8, 0x20, 0xbf, 0xfa, 0xab, 0xbf, 0xca, 0xc6, +0xc6, 0x06, 0x00, 0x23, 0x23, 0x23, 0x1c, 0x3d, +0x7a, 0x04, 0x2b, 0x6d, 0x6b, 0x8f, 0xe3, 0x98, +0x63, 0xaf, 0xbf, 0xce, 0xb9, 0x73, 0xe7, 0x06, +0xa0, 0x9a, 0x9c, 0x9c, 0xe4, 0xcb, 0x5f, 0xfe, +0x32, 0xb7, 0xdd, 0x76, 0x1b, 0x85, 0x7c, 0x61, +0x9b, 0xaf, 0x00, 0x89, 0x30, 0x4b, 0xe9, 0x30, +0x3e, 0x31, 0xc1, 0xcf, 0xfc, 0xcc, 0xcf, 0x72, +0xee, 0xdc, 0x79, 0xde, 0x79, 0xe7, 0x1d, 0xe2, +0x38, 0xa6, 0xd3, 0xe9, 0xf0, 0xf2, 0xcb, 0x2f, +0xf3, 0xd3, 0x9f, 0xf9, 0x0c, 0xbb, 0xe7, 0xe6, +0x92, 0xb6, 0xb0, 0x34, 0xfc, 0x64, 0xdb, 0x35, +0x24, 0x4a, 0x5a, 0x18, 0xf4, 0x40, 0x50, 0xb4, +0x11, 0xc9, 0xf2, 0x00, 0x52, 0xa3, 0xb5, 0x21, +0xd6, 0x09, 0x48, 0x1d, 0xd7, 0x25, 0x08, 0x43, +0x46, 0x47, 0x47, 0x69, 0xd4, 0x37, 0x59, 0x5f, +0x5d, 0xa5, 0x54, 0x4e, 0xca, 0xe3, 0x06, 0x98, +0x98, 0x9c, 0x24, 0x97, 0xcf, 0xd3, 0x6a, 0x46, +0xf4, 0xc5, 0x0c, 0x1b, 0x9d, 0x93, 0xf4, 0xca, +0x86, 0xbc, 0x9d, 0x30, 0x54, 0xd7, 0x5c, 0xf3, +0xc1, 0xb9, 0xce, 0x19, 0xa0, 0xab, 0xa4, 0xb8, +0x6e, 0x39, 0xf8, 0xba, 0x3e, 0x40, 0xfa, 0xf0, +0x1a, 0x43, 0xf0, 0xc1, 0xa5, 0xde, 0x25, 0x93, +0xb7, 0x8c, 0x90, 0xbe, 0x10, 0x3a, 0x51, 0x59, +0x48, 0x01, 0xa1, 0x86, 0x7e, 0x04, 0x9e, 0x35, +0xc8, 0xfc, 0xf9, 0xa1, 0x61, 0xb3, 0x13, 0x53, +0x0f, 0x2b, 0x18, 0xab, 0x94, 0xd8, 0xfe, 0xb4, +0xb9, 0xb2, 0x90, 0xcf, 0x63, 0x59, 0x16, 0x06, +0x41, 0x10, 0x84, 0x08, 0x20, 0x0c, 0x02, 0x7c, +0xdf, 0x67, 0xa4, 0x56, 0xa3, 0x5a, 0x4b, 0x42, +0x43, 0x04, 0x28, 0x65, 0x71, 0x60, 0x7e, 0x9e, +0xf1, 0xf1, 0xb1, 0xc1, 0x7d, 0xb5, 0xdb, 0x6d, +0x5e, 0x78, 0xe1, 0x05, 0x1a, 0x8d, 0x06, 0x1f, +0xbb, 0xf7, 0x63, 0x1c, 0xbd, 0xf3, 0x28, 0x87, +0x0f, 0x1f, 0x66, 0xf7, 0xee, 0xdd, 0x28, 0x2c, +0xc6, 0xc7, 0xc7, 0xf9, 0xec, 0x67, 0x3f, 0x9b, +0x24, 0x87, 0x10, 0x58, 0x8e, 0x4d, 0xb1, 0x58, +0x44, 0x59, 0x36, 0x42, 0x0a, 0xb4, 0x81, 0x93, +0x27, 0x4f, 0xb2, 0xbc, 0xbc, 0x02, 0x40, 0xb5, +0x5a, 0xe5, 0xae, 0xbb, 0xee, 0xe6, 0xe8, 0xd1, +0x3b, 0x29, 0xe4, 0x0b, 0xdb, 0xd6, 0x2f, 0xbc, +0x5a, 0xf8, 0x3c, 0x3b, 0x37, 0xc7, 0xbd, 0x1f, +0xbb, 0x97, 0xf9, 0x03, 0x07, 0x38, 0xf9, 0xc1, +0x07, 0x84, 0x61, 0xc8, 0xfb, 0xef, 0x1f, 0xa7, +0xd9, 0x6c, 0xe0, 0x3a, 0x0e, 0x4a, 0x4a, 0x6c, +0xa5, 0x06, 0x99, 0xc5, 0x8c, 0x64, 0x5a, 0x5e, +0x4f, 0x92, 0x45, 0x24, 0x1a, 0x09, 0x83, 0x34, +0x06, 0x34, 0x68, 0xb1, 0xe5, 0x53, 0x67, 0x3d, +0x85, 0xe5, 0x6a, 0x15, 0x2f, 0x97, 0xa3, 0x5e, +0xdf, 0xc4, 0xf7, 0x7d, 0x3c, 0x2f, 0x87, 0xc1, +0xe0, 0x38, 0x0e, 0x23, 0xa3, 0xa3, 0xb4, 0x5b, +0x2d, 0x74, 0x7e, 0x9c, 0x8e, 0xaa, 0xd0, 0x0d, +0xda, 0x54, 0x3d, 0x89, 0xca, 0x2b, 0x3a, 0xb6, +0xec, 0xbd, 0xfa, 0x56, 0xf3, 0xac, 0xe7, 0x4a, +0x3f, 0x69, 0x0d, 0xbd, 0x36, 0xdd, 0x28, 0x15, +0x9c, 0x09, 0xa2, 0x9c, 0xa9, 0x58, 0x55, 0x3f, +0x46, 0xe7, 0x72, 0x4a, 0xd2, 0x89, 0x93, 0x70, +0xd0, 0x4a, 0x73, 0x0c, 0xa1, 0x01, 0xa1, 0xc1, +0x95, 0xc9, 0x44, 0x9f, 0x40, 0xb3, 0xd9, 0x31, +0x04, 0xf6, 0x24, 0xd2, 0x24, 0x99, 0xbb, 0x30, +0x4c, 0x3a, 0x74, 0xf3, 0xb9, 0x1c, 0x96, 0xb2, +0x06, 0x53, 0xad, 0x48, 0x55, 0x69, 0x96, 0x1a, +0xcd, 0xe7, 0x73, 0x5b, 0x99, 0x36, 0x29, 0x99, +0x9c, 0x9c, 0xe2, 0xf0, 0xe1, 0x23, 0xbc, 0xf4, +0xd2, 0x4b, 0x5c, 0xbc, 0x78, 0x91, 0x28, 0x8a, +0x58, 0x5c, 0x5c, 0x64, 0x79, 0x79, 0x99, 0xe3, +0xc7, 0x8f, 0x33, 0xff, 0xf2, 0x3c, 0xfb, 0xf7, +0xcf, 0xb3, 0x77, 0xef, 0x1e, 0x26, 0x26, 0x27, +0x99, 0x49, 0x9d, 0xb8, 0x89, 0x89, 0x09, 0x2c, +0xcb, 0xce, 0x1e, 0x06, 0x01, 0x44, 0x71, 0xc4, +0xc5, 0x0b, 0x17, 0x58, 0x58, 0x5c, 0xa4, 0xdf, +0x4f, 0x2c, 0x63, 0xad, 0x56, 0xe3, 0xe8, 0xd1, +0xa3, 0x94, 0x2b, 0x95, 0x81, 0x0d, 0xbf, 0x5e, +0xca, 0xd8, 0x71, 0x1c, 0xe6, 0xe6, 0xf6, 0x70, +0xdb, 0xad, 0xb7, 0x72, 0xe6, 0xf4, 0x69, 0xc2, +0x30, 0x64, 0x63, 0x63, 0x83, 0xb3, 0x67, 0xce, +0x52, 0xaf, 0xd7, 0xa9, 0x54, 0x2a, 0x57, 0x4d, +0x3e, 0x29, 0x25, 0xb1, 0x6d, 0x6b, 0xa0, 0xa6, +0xb5, 0x4e, 0xa4, 0x3e, 0xa9, 0x9b, 0xe8, 0xc1, +0x14, 0x30, 0x83, 0x41, 0x2a, 0x0b, 0xdb, 0x71, +0x88, 0xe3, 0x98, 0x6a, 0xb5, 0xc6, 0xc2, 0xe5, +0x4b, 0xb4, 0x1a, 0x0d, 0x5c, 0x37, 0x29, 0xc5, +0x48, 0x21, 0x19, 0x1d, 0x1b, 0xe3, 0xd2, 0x85, +0x0b, 0xa8, 0x5c, 0x85, 0x8e, 0x2c, 0xd1, 0x09, +0x5b, 0x84, 0x1a, 0xac, 0x31, 0x8f, 0xb5, 0x66, +0xd4, 0x68, 0xb5, 0xa3, 0xb6, 0x14, 0xc4, 0x19, +0x00, 0xae, 0x15, 0x36, 0xdf, 0x54, 0x39, 0x58, +0x0a, 0x72, 0x7b, 0x47, 0x9d, 0x3d, 0x8b, 0xab, +0x7e, 0x77, 0x5f, 0xc5, 0x2e, 0xd3, 0x49, 0x56, +0xf1, 0x20, 0x88, 0x13, 0xf5, 0x2f, 0x80, 0x58, +0x63, 0x02, 0x88, 0x05, 0x74, 0x7d, 0x43, 0xbd, +0x03, 0xa1, 0x33, 0x82, 0xd2, 0x31, 0x61, 0x18, +0xe1, 0xf7, 0xfa, 0x04, 0x81, 0x8f, 0xeb, 0x39, +0x58, 0x96, 0xa2, 0xef, 0x47, 0xa4, 0x82, 0x4e, +0x14, 0x46, 0x18, 0x1d, 0x53, 0xca, 0xb2, 0x77, +0x43, 0x00, 0x54, 0x52, 0xf1, 0xb7, 0x1e, 0x7d, +0x94, 0x73, 0xe7, 0xce, 0xf2, 0x8d, 0x6f, 0x7c, +0x83, 0x8d, 0x8d, 0x8d, 0x44, 0x7d, 0x6a, 0xcd, +0xf9, 0xf3, 0xe7, 0x39, 0x7f, 0xfe, 0x3c, 0xcf, +0x3e, 0xfb, 0x2c, 0x85, 0x42, 0x81, 0x3d, 0x7b, +0xf7, 0x32, 0xbf, 0x7f, 0x3f, 0x0f, 0x3c, 0xf0, +0x20, 0x07, 0x0f, 0x1e, 0xe4, 0xf6, 0xdb, 0x6f, +0x67, 0x66, 0x66, 0x06, 0xdb, 0x71, 0x92, 0x5b, +0xf4, 0x63, 0xce, 0x9d, 0x3b, 0x47, 0xbb, 0xd5, +0x1e, 0x3c, 0x5c, 0xa1, 0x50, 0x64, 0x76, 0x6e, +0x36, 0x89, 0xe5, 0xaf, 0x9b, 0x34, 0xdd, 0xa2, +0x6a, 0xb5, 0xca, 0xae, 0x99, 0x19, 0xb2, 0xd6, +0x48, 0x63, 0x0c, 0x17, 0x2e, 0x5e, 0x60, 0x63, +0x7d, 0x9d, 0x5a, 0xad, 0x96, 0xac, 0x5b, 0xb4, +0x83, 0x92, 0x69, 0x69, 0x6a, 0x70, 0xbe, 0x91, +0x49, 0x7c, 0xad, 0xb5, 0x41, 0x8b, 0xa4, 0x03, +0x39, 0x3d, 0x31, 0x6d, 0x5f, 0xb7, 0x89, 0xa2, +0x90, 0x52, 0xb9, 0x0c, 0x97, 0xa0, 0xd9, 0x68, +0x30, 0x32, 0x3e, 0x9e, 0x46, 0x10, 0x50, 0x2c, +0x26, 0x5d, 0x45, 0x06, 0x43, 0x60, 0x57, 0xe8, +0x04, 0x97, 0x09, 0xb4, 0xc1, 0xdd, 0x95, 0x63, +0x4c, 0x88, 0xb2, 0x63, 0x89, 0x7c, 0xb7, 0x87, +0x54, 0x52, 0x08, 0xf8, 0x31, 0xca, 0xc1, 0xb1, +0xc1, 0x2a, 0x7a, 0xb2, 0x7a, 0xc7, 0x6e, 0x6f, +0xaa, 0x28, 0xb0, 0x28, 0x5a, 0x60, 0x8b, 0x44, +0xea, 0x7d, 0x03, 0x96, 0x86, 0x5c, 0x3a, 0x78, +0xda, 0xa0, 0x63, 0x43, 0xaf, 0x1f, 0xd3, 0x8e, +0xf2, 0xc4, 0xae, 0x43, 0x14, 0x44, 0x84, 0xbe, +0x4f, 0x18, 0x06, 0xf8, 0x81, 0x9f, 0x78, 0xbe, +0x52, 0x12, 0x6b, 0x9d, 0x94, 0x47, 0x11, 0x04, +0x7e, 0xe2, 0x0b, 0x94, 0x8a, 0xc5, 0x6d, 0xd2, +0x93, 0x4c, 0x49, 0x93, 0x7c, 0xfc, 0xbe, 0x8f, +0xe3, 0x07, 0x3e, 0xbe, 0xef, 0xf3, 0xd2, 0x4b, +0x2f, 0xb1, 0xb2, 0xb2, 0x42, 0xb7, 0xdb, 0xdd, +0xd6, 0xec, 0xd8, 0xe9, 0x74, 0x78, 0xff, 0xf8, +0x71, 0x3e, 0x38, 0x71, 0x82, 0xa7, 0x9f, 0x7e, +0x9a, 0x3d, 0x7b, 0xf6, 0xf0, 0xe5, 0x2f, 0xff, +0x5d, 0x3e, 0xff, 0xf9, 0xbf, 0xc3, 0xfe, 0xf9, +0x03, 0x5b, 0x0c, 0x1e, 0xce, 0x04, 0x01, 0x8e, +0x63, 0x53, 0x2a, 0x95, 0x06, 0xad, 0xe5, 0x37, +0x43, 0x9e, 0xe7, 0x52, 0x2c, 0x16, 0xaf, 0x89, +0x97, 0x2c, 0x85, 0xbb, 0x93, 0x86, 0x9f, 0x0b, +0x40, 0x1a, 0x83, 0x91, 0x06, 0x63, 0x24, 0xb1, +0x4e, 0xa3, 0x82, 0xb4, 0x89, 0xc5, 0xb2, 0x2c, +0x2c, 0x65, 0x91, 0x2f, 0xe4, 0x71, 0x3d, 0x8f, +0x7e, 0xaf, 0x47, 0x14, 0x84, 0xc9, 0x7c, 0xc7, +0xd4, 0x0c, 0x78, 0xb9, 0x1c, 0xad, 0x66, 0x93, +0xca, 0xe4, 0x2d, 0xf4, 0x2f, 0x7f, 0x40, 0x90, +0xb3, 0x88, 0xcb, 0x0e, 0xc5, 0xf3, 0xad, 0xfc, +0x3d, 0x87, 0x8a, 0x7b, 0xbe, 0xfd, 0x83, 0x4d, +0xaf, 0x5a, 0x54, 0xa2, 0xe7, 0x7f, 0x94, 0x72, +0x70, 0x76, 0xd3, 0x60, 0x79, 0x96, 0xa8, 0xd4, +0xf2, 0xaa, 0x3a, 0x2a, 0xf1, 0x84, 0x14, 0x50, +0x73, 0x60, 0x25, 0x9d, 0x70, 0xd0, 0x8d, 0x93, +0x6e, 0x14, 0x57, 0x61, 0x04, 0x03, 0x13, 0xd0, +0xd3, 0x39, 0x34, 0x92, 0x30, 0xf0, 0x09, 0x7d, +0x9f, 0xbe, 0xdf, 0x27, 0x8c, 0xc2, 0x24, 0x9e, +0x1d, 0xa0, 0x31, 0x61, 0xb6, 0x49, 0xa3, 0x48, +0xcb, 0x52, 0x57, 0x00, 0x40, 0x08, 0x81, 0xa5, +0x14, 0x0f, 0x3c, 0xf0, 0x00, 0xd3, 0xd3, 0xd3, +0x3c, 0xfb, 0xec, 0xb3, 0x7c, 0xf7, 0xbb, 0xdf, +0xe5, 0xf8, 0xf1, 0xe3, 0x34, 0x1a, 0x0d, 0x7c, +0x3f, 0x01, 0x46, 0x16, 0x51, 0xe8, 0x74, 0x06, +0xd0, 0xa9, 0x53, 0xa7, 0xf8, 0xb7, 0xff, 0xf6, +0xff, 0xa2, 0xd5, 0x6e, 0xf1, 0xab, 0xbf, 0xfa, +0x6b, 0xcc, 0xcd, 0xcd, 0x5d, 0xfb, 0x19, 0x6f, +0x42, 0xf2, 0xb7, 0x39, 0x85, 0x5c, 0xad, 0xbe, +0xb0, 0x75, 0xad, 0xe4, 0xd8, 0x4d, 0x5c, 0x33, +0x3d, 0x37, 0x11, 0x8a, 0x64, 0x9f, 0x95, 0xcd, +0x27, 0x90, 0x49, 0x43, 0x8b, 0x97, 0xcb, 0xe3, +0x7a, 0x2e, 0xbd, 0x6e, 0x0f, 0xdf, 0xf7, 0xc9, +0x5b, 0x0a, 0x63, 0x4c, 0xda, 0x8d, 0x9c, 0xe4, +0x4a, 0x62, 0xbb, 0x48, 0x37, 0x16, 0x04, 0x33, +0x79, 0x4c, 0x2b, 0x44, 0x36, 0x42, 0x71, 0xdb, +0xde, 0xfc, 0x9e, 0x6f, 0xff, 0x60, 0xd3, 0x0b, +0xc2, 0x8f, 0x5a, 0x0e, 0x96, 0x83, 0xce, 0x6f, +0x4b, 0x29, 0x51, 0x9c, 0x2c, 0xa8, 0xaa, 0x8a, +0xb4, 0x20, 0x36, 0x50, 0xb1, 0x61, 0x33, 0x48, +0xb4, 0x80, 0x21, 0xc9, 0x41, 0x57, 0x05, 0x38, +0x49, 0x13, 0xa7, 0x1f, 0x19, 0x7c, 0xed, 0x12, +0x46, 0x31, 0x7e, 0x14, 0x10, 0xf8, 0xc9, 0xc4, +0x0b, 0x1d, 0xeb, 0x74, 0xf0, 0x92, 0x07, 0x94, +0x52, 0xa0, 0xf5, 0xf6, 0x66, 0x8d, 0x9d, 0xcc, +0xcf, 0x1a, 0x38, 0x5d, 0xd7, 0x65, 0xff, 0xbe, +0x7d, 0x8c, 0x8f, 0x8d, 0xf1, 0xc9, 0x4f, 0x7e, +0x92, 0x85, 0x85, 0x05, 0x5e, 0x7f, 0xfd, 0x0d, +0xde, 0x7b, 0xef, 0x5d, 0xde, 0x7a, 0xeb, 0x2d, +0x4e, 0x9e, 0x3c, 0x39, 0x60, 0x7e, 0xb6, 0x2d, +0x2d, 0x2d, 0xf1, 0xad, 0x27, 0x9f, 0x64, 0xa4, +0x36, 0xc2, 0xaf, 0xff, 0xc6, 0x6f, 0x6c, 0x5d, +0x77, 0xe8, 0x39, 0x93, 0xb5, 0xf7, 0xf4, 0x4e, +0xc5, 0x70, 0x15, 0x66, 0x0d, 0x7f, 0x46, 0x5f, +0xd1, 0x62, 0x25, 0xb3, 0xfb, 0x25, 0x6b, 0x41, +0xbc, 0x39, 0x73, 0xb2, 0xf3, 0x9e, 0x92, 0x96, +0xf3, 0xc4, 0x5c, 0x58, 0x96, 0x85, 0xeb, 0x7a, +0xd8, 0x8e, 0x43, 0xb3, 0xd9, 0x24, 0x0c, 0x03, +0x8c, 0xc9, 0x61, 0x48, 0xea, 0x13, 0xd9, 0x8c, +0xa6, 0x08, 0x87, 0xbe, 0xa3, 0x08, 0x47, 0x5c, +0xd8, 0xf0, 0xa1, 0x1f, 0x33, 0x56, 0xb2, 0xa6, +0x00, 0xcf, 0xb6, 0x85, 0xe0, 0x3a, 0x93, 0x83, +0x6e, 0xa4, 0x01, 0x04, 0x20, 0x95, 0x14, 0xb9, +0x92, 0xa7, 0x0a, 0xa2, 0x11, 0x0a, 0x22, 0x03, +0xae, 0x84, 0x31, 0x17, 0x16, 0x93, 0x3c, 0x37, +0x1a, 0x68, 0x04, 0x98, 0x8a, 0x83, 0x36, 0x10, +0xc6, 0x06, 0x5f, 0x2b, 0xc2, 0x28, 0x22, 0xf0, +0x43, 0xc2, 0x20, 0x44, 0x9b, 0xec, 0xe7, 0x56, +0x92, 0xc1, 0x74, 0xb2, 0x39, 0x7d, 0x42, 0x0f, +0x52, 0xbe, 0x99, 0x4a, 0xdf, 0x92, 0xa0, 0xb4, +0x68, 0x92, 0xee, 0x57, 0x4a, 0x51, 0x1b, 0xa9, +0x51, 0x2a, 0x57, 0x98, 0xd9, 0x3d, 0xcb, 0x81, +0x83, 0x87, 0x92, 0xfe, 0xfb, 0x7a, 0x83, 0xa5, +0xc5, 0x45, 0x3e, 0x38, 0x79, 0x92, 0xd7, 0x5e, +0x7d, 0x85, 0xe7, 0x9f, 0x7f, 0x9e, 0x46, 0xa3, +0x41, 0x1c, 0x27, 0x36, 0xff, 0xb5, 0xd7, 0x5e, +0x63, 0x73, 0x73, 0x93, 0x6a, 0xb5, 0x4a, 0xa5, +0x52, 0xc5, 0x4e, 0xb3, 0x8c, 0x90, 0x98, 0x8e, +0x4b, 0x97, 0x2e, 0x11, 0xc7, 0xd1, 0x95, 0xe5, +0x5d, 0xb3, 0xa5, 0x96, 0x87, 0xe1, 0xb1, 0xb4, +0xb4, 0xc4, 0xfb, 0xef, 0xbf, 0xbf, 0xcd, 0x04, +0x95, 0xcb, 0x65, 0x72, 0x39, 0x6f, 0xab, 0x03, +0xe9, 0xe6, 0xf9, 0xbf, 0x7d, 0xc0, 0x45, 0xd6, +0xb0, 0x9a, 0x80, 0xc0, 0x75, 0x13, 0x73, 0x90, +0xb5, 0xae, 0x65, 0xf7, 0x64, 0x8c, 0x49, 0xcb, +0x1b, 0x12, 0x95, 0xaf, 0x10, 0x8c, 0xe5, 0x89, +0x43, 0x0d, 0x9b, 0x3e, 0x44, 0x46, 0x8c, 0x56, +0xac, 0x9a, 0x94, 0xb8, 0x7e, 0xa0, 0xaf, 0x6b, +0xdb, 0x6e, 0xec, 0x03, 0x24, 0x13, 0x59, 0x95, +0xd0, 0x26, 0x89, 0xa1, 0xfa, 0x31, 0x58, 0x22, +0xd1, 0x02, 0xcd, 0x10, 0x3a, 0xa9, 0x24, 0xc4, +0xc0, 0x66, 0x80, 0xb6, 0x25, 0x91, 0x86, 0x50, +0xdb, 0x04, 0x7e, 0x44, 0x14, 0x84, 0x68, 0x93, +0x9c, 0x23, 0x85, 0xa2, 0xd5, 0x6a, 0xa3, 0x8d, +0xc1, 0xb2, 0xac, 0x41, 0x13, 0xa6, 0xe7, 0x79, +0xe8, 0x38, 0xa6, 0xd9, 0x68, 0x0e, 0x24, 0x5e, +0xc0, 0xc0, 0xd1, 0x5b, 0x5f, 0x5b, 0x65, 0x65, +0x75, 0x15, 0xdf, 0xf7, 0xd9, 0xb7, 0x6f, 0x1f, +0x87, 0x8f, 0x1c, 0x25, 0x97, 0xcb, 0x91, 0xcf, +0xe7, 0xd9, 0xb5, 0x6b, 0x17, 0x02, 0xf0, 0x03, +0x9f, 0x8f, 0xaf, 0xac, 0x70, 0xef, 0x3d, 0xf7, +0x60, 0xdb, 0x0e, 0xdf, 0xfb, 0xde, 0x73, 0x6c, +0x6c, 0x6c, 0xe0, 0xfb, 0x3e, 0xcb, 0xcb, 0x4b, +0x5c, 0x38, 0x7f, 0x9e, 0x5a, 0xb5, 0xca, 0xde, +0x3d, 0x73, 0x14, 0x0b, 0x85, 0xc1, 0xf3, 0x35, +0x9b, 0x4d, 0x4e, 0x9f, 0x3e, 0x75, 0x45, 0xc3, +0x07, 0x30, 0x88, 0x34, 0x0e, 0x1f, 0x3e, 0xcc, +0xc8, 0xc8, 0xc8, 0xc0, 0x89, 0x5b, 0x5e, 0x5e, +0xe6, 0x83, 0x0f, 0x3e, 0x20, 0x4e, 0xb5, 0x80, +0x94, 0x92, 0x99, 0x99, 0x19, 0x46, 0x46, 0x46, +0x52, 0x26, 0x5e, 0x95, 0xb3, 0xc3, 0x89, 0x8d, +0x9b, 0x22, 0x21, 0x44, 0xda, 0x43, 0x20, 0xb6, +0x0a, 0x48, 0x43, 0x00, 0x48, 0x22, 0x25, 0x01, +0x96, 0x4d, 0x94, 0xb3, 0x30, 0xcd, 0x00, 0xd3, +0x08, 0x41, 0xc0, 0xdc, 0xa4, 0x5b, 0xc8, 0xb9, +0xc9, 0x8f, 0x63, 0x88, 0x6b, 0x4d, 0x3d, 0xe6, +0xc3, 0x94, 0x83, 0xb3, 0x74, 0x6f, 0x27, 0x82, +0xbc, 0x4a, 0x02, 0xd7, 0x49, 0x0f, 0xce, 0x77, +0xb7, 0xa6, 0x77, 0x6b, 0x03, 0x8d, 0x10, 0xd3, +0x89, 0xd0, 0x5a, 0x13, 0x06, 0x61, 0xd2, 0x14, +0x81, 0x41, 0x08, 0x85, 0x52, 0x16, 0x9d, 0x4e, +0x07, 0x63, 0x0c, 0x8e, 0x6d, 0x63, 0x29, 0x85, +0x8e, 0xe3, 0xa4, 0xad, 0x5b, 0x4a, 0xda, 0xed, +0x56, 0xe2, 0x23, 0xa4, 0x5f, 0x17, 0x45, 0x21, +0x4f, 0x3f, 0xf3, 0x34, 0xaf, 0xfc, 0xe8, 0x47, +0x2c, 0x2c, 0x2c, 0xe0, 0xfb, 0x3e, 0x0f, 0x3c, +0xf0, 0x20, 0xf3, 0xf3, 0x07, 0x28, 0x95, 0xcb, +0xdb, 0xd4, 0xac, 0xeb, 0x7a, 0xcc, 0xce, 0xce, +0x51, 0xa9, 0x54, 0x39, 0x77, 0xee, 0x1c, 0x6f, +0xbf, 0xfd, 0xd6, 0x20, 0x19, 0xe4, 0xfb, 0x3e, +0x9b, 0x9b, 0x1b, 0x08, 0x01, 0xa3, 0xa3, 0x63, +0xec, 0xdd, 0xbb, 0x97, 0x4a, 0xa5, 0x42, 0xa3, +0xd1, 0xa0, 0xd9, 0x6c, 0x72, 0xfc, 0xf8, 0x71, +0x96, 0x96, 0x96, 0x28, 0xa5, 0xfd, 0xfa, 0x00, +0xab, 0xab, 0xab, 0xfc, 0xd9, 0x9f, 0xfd, 0x19, +0x5f, 0xff, 0xfa, 0xd7, 0x39, 0x7a, 0xf4, 0x28, +0xf7, 0xdd, 0x77, 0x1f, 0xf7, 0xde, 0x7b, 0x2f, +0xf5, 0x7a, 0x9d, 0xd7, 0x5f, 0x7f, 0x9d, 0xc5, +0xc5, 0x45, 0xb4, 0xd6, 0x48, 0x29, 0x19, 0x1b, +0x1b, 0x63, 0x72, 0x72, 0x32, 0xad, 0x5e, 0x5e, +0x9f, 0xa1, 0x57, 0x24, 0xe6, 0x87, 0xfe, 0x94, +0x72, 0x4b, 0xd3, 0x6c, 0xe5, 0x61, 0xc4, 0xa0, +0xd2, 0xb8, 0x55, 0x72, 0x26, 0xa9, 0x23, 0x0c, +0x4c, 0xa4, 0x49, 0x16, 0xd9, 0x68, 0x84, 0x88, +0x7e, 0x0c, 0x39, 0x85, 0x10, 0x22, 0x99, 0xd0, +0xbd, 0x33, 0x21, 0xb1, 0x83, 0x6e, 0xb6, 0x1c, +0x6c, 0x06, 0xe5, 0xe0, 0x5e, 0x9c, 0xd4, 0x9c, +0x11, 0x49, 0x45, 0x70, 0xc2, 0x85, 0xa5, 0x7e, +0x5a, 0x0b, 0x48, 0x50, 0x2e, 0xfa, 0x1a, 0x42, +0x8d, 0xb6, 0x52, 0xe6, 0xa7, 0x69, 0x50, 0xd7, +0xb6, 0x69, 0x34, 0x9b, 0xc4, 0x71, 0x8c, 0xeb, +0xba, 0x78, 0x9e, 0x47, 0x18, 0x45, 0x78, 0x9e, +0x87, 0x93, 0xda, 0xb9, 0x5e, 0xaf, 0x47, 0xa9, +0x54, 0x1e, 0xa4, 0x6d, 0xdf, 0x7e, 0xeb, 0x2d, +0xbe, 0xf3, 0x9d, 0xef, 0x0c, 0x98, 0xd9, 0x6e, +0xb7, 0xf9, 0xc2, 0x17, 0x3e, 0xcf, 0x91, 0xa3, +0x77, 0x0e, 0x0a, 0x46, 0x3b, 0x07, 0x39, 0x9b, +0x32, 0x9e, 0x51, 0xa2, 0x4a, 0xdd, 0xc4, 0xa1, +0xb4, 0x24, 0xf7, 0xdf, 0x7f, 0x3f, 0xaf, 0xbf, +0xfe, 0x3a, 0x6f, 0xbc, 0xf1, 0x06, 0xdd, 0x6e, +0x97, 0xf7, 0xdf, 0x7f, 0x9f, 0xe7, 0x9e, 0x7b, +0x8e, 0x5a, 0xad, 0xc6, 0xe4, 0xe4, 0x24, 0x52, +0x4a, 0x4e, 0x9e, 0x3c, 0xc9, 0x37, 0xbe, 0xf1, +0x0d, 0x9e, 0x7c, 0xf2, 0x49, 0xbe, 0xf3, 0x9d, +0xef, 0xf0, 0xc8, 0x23, 0x8f, 0xf0, 0xc5, 0x2f, +0x7e, 0x91, 0x4b, 0x97, 0x2e, 0xf1, 0xa7, 0x7f, +0xfa, 0xa7, 0xb4, 0x5a, 0x2d, 0x00, 0x5c, 0xd7, +0xe5, 0xae, 0xbb, 0xee, 0x62, 0x74, 0x74, 0xf4, +0x26, 0x86, 0xf2, 0x4a, 0xdf, 0x20, 0x2b, 0x09, +0x03, 0xdb, 0xa6, 0xb3, 0x5f, 0xc1, 0x00, 0xa3, +0x21, 0xcb, 0x1b, 0xa4, 0xcd, 0x24, 0xda, 0x24, +0xbd, 0x17, 0x3a, 0x8e, 0xb0, 0xc2, 0x18, 0xd5, +0x08, 0xae, 0xb9, 0xce, 0xc0, 0xb5, 0xe8, 0x66, +0xca, 0xc1, 0x06, 0x88, 0xb4, 0x40, 0x2b, 0x90, +0x18, 0x93, 0x68, 0x01, 0x5b, 0x26, 0x93, 0xfa, +0xaa, 0x4e, 0x02, 0x88, 0xcd, 0x20, 0x7d, 0x88, +0x64, 0x4e, 0x9b, 0x65, 0x7c, 0x04, 0x3a, 0x65, +0x7e, 0xe2, 0xb1, 0x66, 0xb6, 0xac, 0xd1, 0x68, +0x50, 0x2a, 0x95, 0xc8, 0xe7, 0x73, 0x74, 0x3a, +0x9d, 0x74, 0x7a, 0x75, 0x9e, 0x56, 0xb3, 0x49, +0xbd, 0xde, 0xa0, 0x5c, 0xae, 0x24, 0xe1, 0x87, +0x6d, 0x71, 0xe8, 0xd0, 0x21, 0xc6, 0xc7, 0xc7, +0x59, 0x5f, 0x5f, 0x07, 0x60, 0x71, 0x71, 0x91, +0x3f, 0xf8, 0x83, 0x7f, 0xcf, 0x3f, 0xfc, 0x87, +0x39, 0xf6, 0xde, 0xb2, 0x0f, 0xcf, 0xf3, 0x90, +0x52, 0x12, 0xc7, 0x31, 0xdd, 0x6e, 0x97, 0xf3, +0xe7, 0xce, 0xf1, 0x83, 0x17, 0x5f, 0x64, 0x6d, +0x6d, 0x6d, 0x30, 0xa8, 0xc5, 0x62, 0x91, 0xf1, +0xf1, 0xf1, 0xc1, 0x9c, 0xfe, 0x87, 0x1f, 0x7e, +0x98, 0x17, 0x5e, 0x78, 0x81, 0xf7, 0xde, 0x7b, +0x8f, 0x20, 0x08, 0x58, 0x5e, 0x5e, 0xe6, 0xf7, +0x7f, 0xff, 0xf7, 0xa9, 0x56, 0xab, 0x3c, 0xf4, +0xd0, 0x43, 0x4c, 0x4c, 0x4c, 0xd0, 0x6e, 0xb7, +0x09, 0x82, 0x80, 0xa9, 0xa9, 0x29, 0x16, 0x16, +0x16, 0x78, 0xee, 0xb9, 0xe7, 0x78, 0xfb, 0xed, +0xb7, 0xe9, 0xf7, 0xfb, 0x34, 0x1a, 0x8d, 0x44, +0x53, 0x49, 0x49, 0xad, 0x56, 0xe3, 0xd3, 0x9f, +0xfe, 0x34, 0x33, 0x33, 0x33, 0xd7, 0x1d, 0xc7, +0x7e, 0xbf, 0x4f, 0xb3, 0xd9, 0xbc, 0xe6, 0x71, +0x41, 0x52, 0xe9, 0xcc, 0x80, 0xeb, 0xba, 0x49, +0x99, 0x3b, 0x0c, 0x13, 0x1f, 0x0a, 0x91, 0x4c, +0x6c, 0xc9, 0x12, 0x49, 0x61, 0x18, 0x12, 0x85, +0x61, 0xa2, 0x55, 0xc2, 0x0e, 0x4e, 0x18, 0x61, +0xc5, 0x11, 0x22, 0x6f, 0x6d, 0xad, 0x9f, 0x0c, +0xe6, 0x46, 0x0d, 0xad, 0x37, 0x2c, 0x07, 0x63, +0x88, 0x63, 0x6d, 0x7a, 0x9d, 0xd0, 0x74, 0xaa, +0x82, 0x0a, 0x06, 0x4c, 0x37, 0x86, 0x7c, 0xd2, +0x79, 0x22, 0x84, 0xc6, 0x4c, 0x78, 0xa0, 0x0d, +0xa2, 0x15, 0x21, 0xa5, 0xc0, 0xb6, 0x04, 0xb6, +0x88, 0x50, 0x4a, 0x20, 0x84, 0xc2, 0xb6, 0x6c, +0x2c, 0x95, 0x2c, 0xd3, 0x62, 0x8c, 0x66, 0x69, +0x65, 0x85, 0xb9, 0xd9, 0x59, 0x0a, 0xf9, 0x1c, +0x9b, 0x4a, 0x21, 0x5d, 0x8f, 0x72, 0xa5, 0xc2, +0x85, 0x73, 0x67, 0x59, 0x59, 0x5e, 0x66, 0x76, +0x6e, 0x16, 0x89, 0xc4, 0xb1, 0x6d, 0x1e, 0x7d, +0xf4, 0x51, 0x5e, 0x7c, 0xf1, 0x45, 0x4e, 0x9d, +0x3a, 0x95, 0xf4, 0xff, 0x6f, 0x6c, 0xf0, 0xf5, +0xaf, 0xff, 0x09, 0x60, 0x78, 0xe2, 0x89, 0xcf, +0x32, 0x7f, 0x60, 0x1e, 0xcf, 0xcb, 0xd1, 0x6e, +0xb5, 0x78, 0xeb, 0xad, 0xb7, 0x78, 0xea, 0xa9, +0x6f, 0xf3, 0xdd, 0xef, 0x7e, 0x97, 0xcd, 0xcd, +0x4d, 0x20, 0x71, 0xce, 0xf6, 0xed, 0xdb, 0xc7, +0xde, 0xbd, 0x7b, 0x93, 0x5c, 0x00, 0xb0, 0x77, +0xef, 0x5e, 0xee, 0xb9, 0xe7, 0x1e, 0x5e, 0x7d, +0xf5, 0x55, 0x4e, 0x9d, 0x3a, 0x95, 0xa6, 0x73, +0xdf, 0xe7, 0x77, 0x7e, 0xe7, 0x77, 0xf8, 0x85, +0x5f, 0xf8, 0x05, 0x7e, 0xfa, 0xa7, 0x7f, 0x9a, +0x99, 0x99, 0x19, 0x7e, 0xf3, 0x37, 0x7f, 0x93, +0x17, 0x5e, 0x78, 0x81, 0x7f, 0xfd, 0xaf, 0xff, +0x35, 0xf5, 0x7a, 0x9d, 0xa5, 0xa5, 0xa5, 0x6d, +0xf5, 0xfc, 0x7c, 0x3e, 0xcf, 0x3d, 0xf7, 0xdc, +0xc3, 0xc3, 0x0f, 0x3f, 0xcc, 0xd8, 0xd8, 0xd8, +0xb5, 0x86, 0x12, 0x63, 0x0c, 0xef, 0xbf, 0xff, +0x3e, 0x4f, 0x3d, 0xf5, 0xd4, 0x35, 0xcf, 0x91, +0x43, 0x89, 0x22, 0xd7, 0x75, 0x79, 0xe8, 0xa1, +0x87, 0xa8, 0x54, 0xaa, 0x83, 0x05, 0x2d, 0x94, +0x4a, 0xe6, 0x36, 0x64, 0x9d, 0x56, 0x51, 0x94, +0xac, 0x59, 0x90, 0x58, 0x80, 0x00, 0xb7, 0x1d, +0x62, 0x95, 0xd2, 0xc2, 0xac, 0x23, 0x89, 0xb4, +0x89, 0xb5, 0x21, 0xce, 0xfa, 0x4e, 0x3e, 0x34, +0x00, 0x76, 0x94, 0x83, 0x5b, 0xf5, 0x6e, 0xdc, +0xac, 0x2a, 0x51, 0x31, 0xd9, 0xa2, 0x05, 0xad, +0x10, 0x6a, 0x2e, 0x44, 0x80, 0x34, 0x30, 0xe5, +0x61, 0x4c, 0x1f, 0x15, 0x85, 0x78, 0x8e, 0x20, +0x27, 0xfa, 0x28, 0x21, 0xb0, 0x2c, 0x07, 0xdb, +0xb2, 0xb1, 0x6d, 0x3b, 0x89, 0xf3, 0xa5, 0x60, +0x65, 0x65, 0x95, 0x28, 0x8e, 0xc9, 0x79, 0x1e, +0xae, 0xeb, 0xd1, 0xf7, 0x7d, 0xa6, 0xa6, 0x77, +0x71, 0xe1, 0xdc, 0x39, 0xce, 0x9e, 0x39, 0xc3, +0x9d, 0x77, 0xdd, 0x85, 0xeb, 0xb9, 0x58, 0xd2, +0xe2, 0xe0, 0xc1, 0x83, 0x3c, 0xf4, 0xd0, 0x43, +0x9c, 0x38, 0x71, 0x82, 0x13, 0x27, 0x4e, 0x10, +0xc7, 0x31, 0x2b, 0x2b, 0x2b, 0xfc, 0xf1, 0x1f, +0xff, 0x31, 0xdf, 0xfb, 0xde, 0xf7, 0x06, 0x4b, +0xc3, 0x44, 0x51, 0x44, 0xbb, 0xdd, 0x66, 0x7d, +0x7d, 0x7d, 0x10, 0x01, 0x08, 0x21, 0x38, 0x74, +0xe8, 0x10, 0x0f, 0x3f, 0xfc, 0x30, 0x9e, 0xe7, +0x0d, 0xd4, 0xaf, 0xe3, 0x38, 0x3c, 0xf1, 0xc4, +0x13, 0xac, 0xae, 0xae, 0xf2, 0xef, 0xfe, 0xdd, +0xbf, 0x63, 0x6d, 0x6d, 0x8d, 0x30, 0x0c, 0x59, +0x58, 0x58, 0xe0, 0x6b, 0x5f, 0xfb, 0x1a, 0xcf, +0x3c, 0xf3, 0xcc, 0xc0, 0x9e, 0x37, 0x1a, 0x8d, +0xc1, 0x84, 0x93, 0x9d, 0xb3, 0x6c, 0xc7, 0xc7, +0xc7, 0xf9, 0xca, 0x57, 0xbe, 0xc2, 0xec, 0xec, +0xec, 0x55, 0x13, 0x49, 0xc3, 0xea, 0xfe, 0xd9, +0x67, 0x9e, 0xe1, 0xd5, 0x57, 0x5e, 0xb9, 0xe6, +0x70, 0x0f, 0x9f, 0x3b, 0x36, 0x36, 0xc6, 0x9e, +0x3d, 0x7b, 0xa8, 0x54, 0xaa, 0xf4, 0xfa, 0x3d, +0x3a, 0x9d, 0x36, 0xb6, 0xed, 0xe0, 0xb8, 0x2e, +0xc9, 0x0a, 0x65, 0x06, 0xdf, 0xf7, 0x89, 0xa2, +0xa4, 0x19, 0x36, 0x6e, 0x6d, 0xe0, 0x45, 0x51, +0x32, 0x91, 0x34, 0xe9, 0x07, 0x30, 0xe7, 0xce, +0xf7, 0x9b, 0x3d, 0x5f, 0xf7, 0x8a, 0x39, 0x79, +0xb5, 0x5f, 0xb3, 0xbb, 0x09, 0x00, 0x6c, 0x51, +0xd4, 0x0d, 0x74, 0xe3, 0xfc, 0x7a, 0xb0, 0xbe, +0x77, 0xc2, 0x9e, 0xa5, 0x97, 0x5e, 0x2e, 0x4c, +0x7a, 0x02, 0x4c, 0xd1, 0x86, 0x00, 0x70, 0x04, +0x62, 0xca, 0x43, 0xc5, 0x06, 0xb7, 0x11, 0x91, +0x97, 0x7d, 0x6c, 0x29, 0x40, 0x59, 0x58, 0xb6, +0x85, 0xb2, 0x2d, 0x2c, 0xc7, 0x42, 0x59, 0x8a, +0x8d, 0x8d, 0x0d, 0x36, 0x37, 0xeb, 0x4c, 0x4e, +0x4e, 0x50, 0x28, 0xe4, 0x09, 0xa2, 0x90, 0xd1, +0xb1, 0x31, 0x2a, 0xd5, 0x2a, 0x67, 0xce, 0x9c, +0xa6, 0xd9, 0xa8, 0x33, 0x99, 0x9b, 0x02, 0x12, +0x29, 0x7b, 0xfc, 0xf1, 0xc7, 0x59, 0x5a, 0x5a, +0xa2, 0xd9, 0x6c, 0xb2, 0xb8, 0xb8, 0x48, 0x1c, +0xc7, 0xac, 0xae, 0xae, 0x0e, 0x7a, 0x04, 0xae, +0x45, 0x7b, 0xf7, 0xee, 0xe5, 0x33, 0x9f, 0xf9, +0x0c, 0x8f, 0x3d, 0xf6, 0xd8, 0x40, 0xfa, 0xb3, +0xc1, 0x4e, 0x32, 0x85, 0x5f, 0xc6, 0xb6, 0x6d, +0xfe, 0xe8, 0x8f, 0xfe, 0x88, 0x73, 0xe7, 0xce, +0x11, 0x45, 0xd1, 0x4d, 0x5d, 0x37, 0xa3, 0x7a, +0xbd, 0xce, 0xb7, 0xbf, 0xfd, 0x6d, 0xa6, 0xa6, +0xa6, 0xb8, 0xf3, 0xce, 0x3b, 0x29, 0x16, 0x8b, +0xdb, 0x8e, 0x0f, 0xab, 0xdf, 0xac, 0xd7, 0xf0, +0x66, 0xa8, 0xd5, 0x6a, 0xd1, 0xf7, 0x7d, 0x0c, +0x86, 0x76, 0xab, 0x45, 0xb7, 0xdb, 0x65, 0x7c, +0xb2, 0x34, 0x68, 0xf0, 0xcb, 0x16, 0xa6, 0x80, +0xc4, 0x6c, 0x44, 0x1b, 0x4b, 0xe4, 0xa5, 0xc6, +0x96, 0x16, 0x52, 0x80, 0xc9, 0x29, 0x56, 0xea, +0xd1, 0x8a, 0x31, 0xf4, 0x8d, 0xe1, 0xea, 0x65, +0xc0, 0x94, 0xae, 0x3b, 0x39, 0x34, 0x5d, 0x05, +0x5c, 0x04, 0x11, 0x85, 0x5b, 0x67, 0xbc, 0x3b, +0x3f, 0xb1, 0x2f, 0x7f, 0x2b, 0xfd, 0x34, 0x73, +0x63, 0xc9, 0x24, 0xfe, 0x97, 0x02, 0x61, 0x89, +0xe4, 0xbd, 0x12, 0x98, 0xa2, 0x4d, 0xbf, 0x17, +0xb3, 0xba, 0xd1, 0x67, 0xd9, 0x4c, 0x62, 0xe5, +0x2a, 0xd8, 0xb6, 0x8d, 0xed, 0x58, 0x83, 0xf4, +0xa6, 0xd6, 0x86, 0x91, 0x91, 0x11, 0x26, 0x27, +0x27, 0xb0, 0x6c, 0x8b, 0x4e, 0xa7, 0x3b, 0x98, +0x94, 0x79, 0xf1, 0xe2, 0x45, 0x6c, 0xcb, 0x66, +0xff, 0xfc, 0xfe, 0x81, 0x54, 0x55, 0x2a, 0x15, +0x26, 0x27, 0xa7, 0x18, 0x1d, 0x1d, 0xc5, 0x18, +0x4d, 0xab, 0xd5, 0x22, 0x08, 0x82, 0xab, 0xe6, +0xb6, 0x95, 0x52, 0xcc, 0xcc, 0xcc, 0xf0, 0xf8, +0xe3, 0x8f, 0xf3, 0xa5, 0x2f, 0x7d, 0x89, 0xcf, +0x7c, 0xe6, 0x33, 0xec, 0xdb, 0xb7, 0xef, 0x0a, +0x09, 0x55, 0x4a, 0x51, 0xab, 0xd5, 0x98, 0x9b, +0x9b, 0x63, 0x2c, 0x6d, 0x4d, 0xcf, 0xda, 0xbf, +0xae, 0xd6, 0x17, 0x98, 0xb5, 0xa0, 0x8d, 0x8e, +0x8e, 0xa2, 0x94, 0xa2, 0xdf, 0xef, 0x0f, 0x3a, +0x83, 0x16, 0x16, 0x16, 0x58, 0x58, 0x58, 0xa0, +0x5c, 0x2e, 0x33, 0x39, 0x39, 0xc9, 0xf2, 0xf2, +0x32, 0xcf, 0x3f, 0xff, 0x3c, 0x67, 0xce, 0x9c, +0xb9, 0x66, 0x8f, 0xe1, 0xf5, 0xa8, 0x50, 0x28, +0xf0, 0xa5, 0x5f, 0xfc, 0x45, 0x26, 0x26, 0x26, +0x38, 0xf9, 0xc1, 0x07, 0x34, 0xea, 0x0d, 0xa6, +0x76, 0xed, 0x1a, 0x68, 0xa5, 0x28, 0x8c, 0xb8, +0x7c, 0xe1, 0x02, 0x81, 0xef, 0x83, 0x8e, 0x88, +0x2f, 0xbe, 0xc6, 0x1e, 0xaf, 0xc9, 0x58, 0x41, +0xe1, 0x5a, 0x02, 0x76, 0xe7, 0xf9, 0xda, 0x8b, +0x1b, 0x4f, 0xbd, 0x71, 0xa2, 0xf3, 0x03, 0xc7, +0x16, 0x8d, 0x20, 0x32, 0x46, 0xa7, 0x6d, 0x77, +0x3b, 0xe9, 0x86, 0xe5, 0x60, 0x93, 0x2c, 0xcd, +0xd7, 0x79, 0xf3, 0x7c, 0xf7, 0x03, 0xf3, 0xa9, +0x51, 0x23, 0x41, 0x10, 0x81, 0x71, 0x92, 0x54, +0x2e, 0xfd, 0x64, 0x91, 0x47, 0xe1, 0x28, 0x08, +0x40, 0x59, 0x82, 0xdc, 0x54, 0x8e, 0xda, 0x7a, +0x4c, 0x6e, 0xb9, 0x41, 0x2c, 0xa7, 0xb1, 0x53, +0xc9, 0x57, 0xd9, 0xfa, 0x7c, 0x96, 0xc5, 0x99, +0xb3, 0xe7, 0x38, 0x38, 0x3f, 0x4f, 0x3e, 0x9f, +0xa3, 0x58, 0x2c, 0xd0, 0x6e, 0xb7, 0x99, 0x9c, +0x9e, 0xa6, 0x5c, 0x2a, 0xf1, 0xee, 0xbb, 0xef, +0x72, 0xf7, 0x3d, 0x77, 0x33, 0x35, 0x3d, 0x8d, +0x10, 0x02, 0xcf, 0xf3, 0xb8, 0xe7, 0x9e, 0xbb, +0x99, 0x9d, 0xdd, 0xcd, 0xa1, 0x43, 0x07, 0xf9, +0xe1, 0x0f, 0x7f, 0xc8, 0xa5, 0x4b, 0x97, 0x58, +0x5f, 0x5f, 0x4f, 0x16, 0x6e, 0x4a, 0xef, 0xd5, +0x71, 0x1c, 0x76, 0xed, 0xda, 0xc5, 0xde, 0xbd, +0x7b, 0xf9, 0xe4, 0x27, 0x3f, 0xc9, 0xe1, 0xc3, +0x87, 0x29, 0x97, 0xcb, 0xd7, 0x1c, 0x68, 0xc7, +0x71, 0x38, 0x70, 0xe0, 0x00, 0x93, 0x93, 0x93, +0x1c, 0x3c, 0x78, 0x90, 0xb7, 0xde, 0x7a, 0x8b, +0xb3, 0x67, 0xcf, 0x72, 0xe9, 0xd2, 0xa5, 0x81, +0x97, 0x0f, 0x09, 0x58, 0x26, 0x27, 0x27, 0x99, +0x9d, 0x9d, 0xa5, 0x50, 0x28, 0x70, 0xe9, 0xd2, +0x25, 0x5e, 0x79, 0xe5, 0x15, 0x4e, 0x9e, 0x3c, +0xc9, 0xfa, 0xfa, 0x3a, 0xdf, 0xfc, 0xe6, 0x37, +0xd9, 0xd8, 0xd8, 0xe0, 0xe8, 0xd1, 0xa3, 0x1c, +0x39, 0x72, 0x84, 0x5a, 0xad, 0xc6, 0x63, 0x8f, +0x3d, 0xc6, 0xc4, 0xc4, 0x04, 0xfd, 0xeb, 0xac, +0xd1, 0x23, 0x10, 0x69, 0xe8, 0xb7, 0x7d, 0xdc, +0x8b, 0xa5, 0x12, 0xa3, 0xa3, 0xa3, 0xf4, 0xba, +0x5d, 0x56, 0x96, 0x97, 0xb1, 0x1d, 0x9b, 0x62, +0x29, 0xd5, 0x2e, 0x06, 0xda, 0xad, 0x16, 0x7e, +0x5a, 0x3f, 0xd1, 0x41, 0x87, 0x02, 0x1d, 0x0a, +0x8e, 0xc4, 0x4a, 0x02, 0x3f, 0x82, 0x9c, 0x0a, +0xff, 0xfc, 0xf5, 0xc6, 0x09, 0xdb, 0x12, 0x3d, +0x9d, 0x69, 0x80, 0x0f, 0x5d, 0x0d, 0xdc, 0xf2, +0x01, 0x0c, 0x10, 0xbd, 0x77, 0xa9, 0xbf, 0x16, +0x2b, 0xa9, 0xa5, 0x23, 0x25, 0x81, 0x86, 0xc0, +0x40, 0x3e, 0x75, 0x36, 0xfd, 0xa4, 0xac, 0x2b, +0x6c, 0x89, 0x0c, 0x0c, 0x2e, 0x30, 0x32, 0xe9, +0x90, 0xdf, 0xd8, 0xa0, 0x2d, 0x34, 0x52, 0xc9, +0xc4, 0x09, 0xb4, 0xec, 0xc1, 0x92, 0x6d, 0xad, +0x56, 0x9b, 0x0b, 0x17, 0x2f, 0x72, 0xdb, 0x6d, +0xb7, 0x52, 0xab, 0x56, 0xf0, 0xfd, 0x3e, 0xe5, +0x52, 0x89, 0x7d, 0xf3, 0xf3, 0xbc, 0x71, 0xec, +0x18, 0x6f, 0xbe, 0xf1, 0x26, 0xa3, 0x63, 0x63, +0x49, 0xb3, 0x65, 0x6a, 0x1f, 0xc7, 0xc7, 0xc7, +0xf9, 0xf9, 0x9f, 0xff, 0x79, 0x9e, 0x78, 0xe2, +0x09, 0x36, 0x37, 0x37, 0x39, 0x77, 0xee, 0xdc, +0xa0, 0x7d, 0xdb, 0x18, 0x43, 0xb1, 0x58, 0xe4, +0xf6, 0xdb, 0x6f, 0x4f, 0x9b, 0x44, 0xe4, 0x4d, +0x17, 0x78, 0x4a, 0xa5, 0x12, 0x8f, 0x3d, 0xf6, +0x18, 0x8f, 0x3e, 0xfa, 0x28, 0x5a, 0x6b, 0xce, +0x9c, 0x39, 0xc3, 0xc2, 0xc2, 0xc2, 0xe0, 0xb8, +0xe3, 0x38, 0xdc, 0x71, 0xc7, 0x1d, 0x94, 0x4a, +0x25, 0x80, 0x41, 0x54, 0xf0, 0x27, 0x7f, 0xf2, +0x27, 0x1c, 0x3f, 0x7e, 0x9c, 0x56, 0xab, 0xc5, +0x27, 0x3e, 0xf1, 0x09, 0xf6, 0xed, 0xdb, 0x07, +0xc0, 0xee, 0xdd, 0xbb, 0xf9, 0xb5, 0x5f, 0xfb, +0x35, 0xc2, 0x30, 0x4a, 0x56, 0x1a, 0xbd, 0x06, +0x59, 0x6a, 0x6b, 0x95, 0xb1, 0xec, 0x19, 0xe2, +0x38, 0x26, 0x8a, 0x63, 0x94, 0x52, 0x9c, 0x3c, +0x71, 0x82, 0x6e, 0xa7, 0xc3, 0xc4, 0xd4, 0x54, +0x52, 0xda, 0x4e, 0xb3, 0xa5, 0xf5, 0xcd, 0x0d, +0x74, 0xea, 0xe3, 0x44, 0xdd, 0x4d, 0x46, 0x4d, +0x93, 0x9c, 0x9d, 0xac, 0x21, 0x40, 0xc5, 0xe2, +0xd4, 0x52, 0x70, 0x79, 0x75, 0x33, 0x5c, 0x51, +0x12, 0x3f, 0x08, 0xf5, 0x47, 0x2c, 0x07, 0xa7, +0x83, 0xa7, 0x04, 0x22, 0x32, 0x58, 0xf7, 0x1f, +0x28, 0x4c, 0xb7, 0x02, 0x1d, 0x8e, 0xe4, 0x95, +0x45, 0xa0, 0x11, 0x91, 0x49, 0x9a, 0x41, 0xbc, +0x74, 0x96, 0x50, 0x98, 0x2c, 0xf4, 0x2f, 0x2d, +0x89, 0x6b, 0x0c, 0x55, 0x0b, 0xc6, 0x4a, 0x3d, +0xda, 0x61, 0x13, 0x4b, 0x56, 0x50, 0x6a, 0x6b, +0x96, 0xae, 0xa5, 0x92, 0x8a, 0xd6, 0x99, 0x73, +0xe7, 0x98, 0x9d, 0x9d, 0xa5, 0x58, 0xc8, 0x53, +0x2a, 0x14, 0x69, 0x77, 0x3a, 0xec, 0x9b, 0x9f, +0xe7, 0xc2, 0xf9, 0xf3, 0xbc, 0xf6, 0xda, 0x6b, +0xdc, 0x7a, 0xfb, 0x6d, 0xec, 0xd9, 0xb3, 0x07, +0xd8, 0x5e, 0x49, 0x73, 0x5d, 0x97, 0xc9, 0xc9, +0x49, 0xc6, 0xc6, 0xc6, 0xae, 0x78, 0x30, 0xa5, +0xae, 0xbb, 0xe6, 0xc5, 0x55, 0x29, 0x2b, 0xd5, +0x66, 0x9f, 0x3d, 0x70, 0xe0, 0x00, 0xfb, 0xf7, +0xef, 0xdf, 0x76, 0xdc, 0x1a, 0xea, 0xf2, 0xd9, +0xbd, 0x7b, 0x96, 0xcf, 0x7f, 0xfe, 0xf3, 0x1c, +0x39, 0x72, 0x84, 0xef, 0x7c, 0xe7, 0x3b, 0xbc, +0xf1, 0xc6, 0x1b, 0x3c, 0xfe, 0xf8, 0xe3, 0x03, +0x00, 0x6c, 0x31, 0x55, 0x6c, 0x09, 0xde, 0x8e, +0xf8, 0x5e, 0x29, 0xb9, 0x95, 0xe5, 0x83, 0x6d, +0xd1, 0x45, 0x92, 0x14, 0x6b, 0x73, 0xfe, 0xdc, +0xb9, 0xa4, 0x5f, 0x71, 0x64, 0x64, 0x30, 0x39, +0xa6, 0xd7, 0xed, 0xd2, 0x6a, 0x34, 0xb7, 0x2e, +0x58, 0xbf, 0x48, 0xc5, 0x8e, 0xc9, 0xd9, 0x4e, +0x32, 0x45, 0x70, 0xcc, 0xa3, 0xb5, 0x11, 0xf6, +0xa3, 0xd8, 0x84, 0xe6, 0x9a, 0x72, 0xbf, 0x45, +0xd7, 0x2e, 0x06, 0xa5, 0xaf, 0x26, 0x39, 0x27, +0xbf, 0x6f, 0xd2, 0xdd, 0xb7, 0xde, 0x8c, 0xfc, +0x91, 0x71, 0x27, 0x47, 0x23, 0x9d, 0x22, 0xd5, +0xd7, 0x49, 0x3e, 0x40, 0xa5, 0xbd, 0x2c, 0x71, +0x92, 0xa8, 0x70, 0xa4, 0xa0, 0x62, 0x2b, 0xe6, +0x0a, 0x3e, 0x17, 0x96, 0x16, 0x31, 0x66, 0x77, +0x2a, 0xf9, 0x16, 0x4a, 0xa6, 0x8b, 0x89, 0x0b, +0xc1, 0xc6, 0x66, 0x9d, 0xd3, 0x67, 0xce, 0x72, +0xe7, 0x91, 0x3b, 0xa8, 0xd6, 0xaa, 0xf8, 0x41, +0xe2, 0xd5, 0xde, 0x7d, 0xef, 0xbd, 0xbc, 0xf0, +0xbd, 0xef, 0xf1, 0xdc, 0x33, 0xcf, 0xf0, 0xf9, +0x2f, 0x7e, 0x91, 0x6a, 0xb5, 0xba, 0xed, 0xde, +0xb2, 0xfc, 0x7c, 0x96, 0xb5, 0xdb, 0x79, 0x6c, +0x5b, 0xeb, 0xf5, 0x47, 0xa0, 0x61, 0x87, 0xf1, +0x6a, 0xa3, 0xa2, 0x94, 0xa4, 0x5c, 0x2e, 0x73, +0xe4, 0xc8, 0x11, 0xf6, 0xee, 0xbd, 0x85, 0x5e, +0xaf, 0xc7, 0xe8, 0xe8, 0xc8, 0xe0, 0x73, 0xc6, +0x80, 0xd6, 0x66, 0xfb, 0xe8, 0x0f, 0x01, 0x61, +0xa7, 0xe4, 0x67, 0x94, 0x95, 0xc8, 0xb5, 0xd6, +0x5c, 0x38, 0x7f, 0x9e, 0xb5, 0xd5, 0x55, 0xc6, +0x27, 0x26, 0x29, 0x95, 0x12, 0x33, 0xa6, 0xb5, +0x66, 0x73, 0x73, 0x23, 0x55, 0xff, 0x60, 0xe2, +0x00, 0xa7, 0x71, 0x8a, 0x91, 0x8a, 0xc4, 0xb3, +0x04, 0xd2, 0x95, 0x98, 0x51, 0x87, 0x83, 0xb6, +0x9c, 0x2e, 0xe6, 0x55, 0xb5, 0xd9, 0x89, 0x2d, +0x1b, 0x88, 0xe3, 0xb4, 0x00, 0x73, 0x95, 0x31, +0xb9, 0xa1, 0x8e, 0x34, 0x06, 0xab, 0xe0, 0xca, +0xca, 0xdd, 0x7b, 0x72, 0x73, 0x05, 0x89, 0x8d, +0x25, 0xa1, 0x30, 0x34, 0x33, 0xa8, 0x13, 0x27, +0x19, 0xaa, 0xac, 0x08, 0x62, 0x0c, 0x0a, 0x43, +0xce, 0x11, 0x4c, 0x16, 0x25, 0x13, 0x6a, 0x99, +0xa0, 0xdb, 0x40, 0x49, 0xb5, 0x6d, 0x71, 0x45, +0xd2, 0x32, 0xe8, 0xa9, 0xd3, 0xa7, 0x59, 0x5d, +0x5f, 0xc7, 0xf3, 0x3c, 0x6a, 0xb5, 0xc4, 0x61, +0xdc, 0x35, 0x33, 0xc3, 0xe1, 0xa3, 0x47, 0x39, +0x73, 0xe6, 0x0c, 0xdf, 0x7f, 0xe1, 0x05, 0xfc, +0x1b, 0xac, 0x75, 0xb7, 0x8d, 0x45, 0xc3, 0x55, +0xc4, 0x9b, 0xff, 0xd4, 0x4d, 0x6e, 0x5b, 0xe7, +0x0b, 0x21, 0x71, 0x5d, 0x8f, 0xb1, 0xb1, 0x31, +0x66, 0x67, 0x67, 0xc9, 0xe7, 0x0b, 0xdb, 0xce, +0xd3, 0x57, 0x09, 0xbe, 0x84, 0x4c, 0x4a, 0xde, +0x3b, 0x99, 0x9f, 0x15, 0xc2, 0xb2, 0xcf, 0x34, +0xea, 0x75, 0x3e, 0x78, 0xff, 0x04, 0xca, 0xb2, +0x99, 0x9c, 0x9e, 0xde, 0x92, 0xfe, 0x5e, 0x8f, +0xcd, 0x8d, 0x8d, 0xac, 0x5d, 0x8a, 0x78, 0xe3, +0x1c, 0x23, 0xa2, 0x45, 0xc5, 0x4b, 0x96, 0xaa, +0x67, 0xca, 0x43, 0x58, 0x92, 0x6a, 0xa8, 0xcb, +0x87, 0x6e, 0xc9, 0xef, 0xee, 0xf5, 0xb5, 0xe7, +0x38, 0x89, 0x2a, 0xbf, 0xd6, 0x68, 0xdc, 0x8c, +0x91, 0xb4, 0x72, 0x8e, 0xa8, 0x4d, 0x55, 0xad, +0xd1, 0x11, 0x5b, 0xb8, 0x28, 0x01, 0x65, 0x7b, +0xeb, 0x8a, 0x71, 0x9a, 0x13, 0x48, 0xab, 0x53, +0x59, 0x49, 0xd7, 0xb3, 0x05, 0xb5, 0xa2, 0xc5, +0x5c, 0xb9, 0x87, 0x6e, 0x5d, 0x24, 0x8e, 0xc2, +0x6d, 0xe5, 0xdd, 0xac, 0x04, 0xda, 0xeb, 0xf5, +0x78, 0xf3, 0xed, 0x77, 0xe8, 0xf6, 0x7a, 0x94, +0x4a, 0x25, 0x8a, 0x85, 0x02, 0x8e, 0xed, 0x70, +0xc7, 0x91, 0x23, 0xdc, 0xb2, 0x6f, 0x1f, 0x3f, +0xfa, 0xd1, 0x8f, 0x38, 0xf6, 0xea, 0xab, 0x57, +0x78, 0xd3, 0xd7, 0x93, 0xf4, 0x8f, 0x06, 0x82, +0x9f, 0x0c, 0x99, 0xb4, 0xcb, 0x67, 0xe7, 0x7d, +0x25, 0x19, 0xd2, 0x2b, 0x7b, 0x05, 0xb3, 0x67, +0x88, 0xe2, 0x24, 0xbe, 0xef, 0xf7, 0x7a, 0xbc, +0xf5, 0xe6, 0x9b, 0xb4, 0x5b, 0x2d, 0xa6, 0xa6, +0xa7, 0xc9, 0xe7, 0xf3, 0x69, 0xe2, 0x27, 0x62, +0x75, 0x65, 0x79, 0xb0, 0xe0, 0xa5, 0x89, 0x7c, +0xf4, 0xc2, 0x1b, 0x4c, 0xe6, 0x34, 0x45, 0x47, +0xa2, 0x5c, 0x09, 0xbb, 0xf2, 0xd0, 0x89, 0x10, +0x9d, 0x48, 0x1c, 0xde, 0x5f, 0xd8, 0x0b, 0x78, +0x5a, 0x9b, 0xcc, 0x76, 0x5e, 0xf5, 0x7e, 0xaf, +0x09, 0x80, 0xe1, 0x7e, 0x00, 0x4b, 0x89, 0xd2, +0x48, 0x4e, 0x55, 0xdc, 0xd8, 0xa4, 0xbf, 0x0b, +0x27, 0xb7, 0xe6, 0x07, 0x42, 0x92, 0x13, 0xa8, +0x07, 0x03, 0x4d, 0x20, 0x04, 0x58, 0x96, 0xa0, +0x5c, 0x50, 0xcc, 0x8d, 0x2b, 0x6a, 0xe6, 0x2c, +0xed, 0xfa, 0x6a, 0xa2, 0xfa, 0xe5, 0x16, 0xf3, +0x33, 0x30, 0x2c, 0xaf, 0xac, 0xf0, 0xde, 0xf1, +0x13, 0x18, 0x63, 0xa8, 0x56, 0x2a, 0x78, 0x9e, +0x4b, 0x21, 0x5f, 0xe0, 0x81, 0x07, 0x1f, 0x66, +0x72, 0x6a, 0x8a, 0x67, 0x9e, 0x7e, 0x9a, 0x37, +0x8e, 0x1d, 0xbb, 0x62, 0xae, 0xfe, 0x56, 0xa4, +0x72, 0x75, 0x10, 0x0c, 0x2f, 0xe5, 0xba, 0xe3, +0x28, 0x57, 0x97, 0xec, 0x9f, 0x0c, 0x69, 0xbd, +0xd5, 0x2b, 0x20, 0xa5, 0xc0, 0xb6, 0xd5, 0x36, +0xc9, 0xdf, 0x69, 0xf7, 0xa3, 0x28, 0x1e, 0x30, +0xf9, 0xc4, 0xfb, 0xef, 0x73, 0xfe, 0xec, 0x59, +0x6a, 0x23, 0x23, 0x4c, 0xed, 0xda, 0x95, 0x34, +0x92, 0x9a, 0x64, 0xd6, 0x54, 0xab, 0xd1, 0x48, +0xae, 0x6f, 0x0c, 0xbd, 0x95, 0xd3, 0x4c, 0xe8, +0x25, 0xc6, 0x0b, 0x0a, 0xcf, 0x16, 0x88, 0x99, +0x5c, 0xc2, 0x97, 0x76, 0x84, 0xe8, 0x45, 0x4c, +0x8f, 0x3a, 0x33, 0x80, 0x27, 0x65, 0xd2, 0x6a, +0x72, 0x2d, 0x61, 0xb8, 0x91, 0x06, 0x10, 0x24, +0xeb, 0x03, 0xe4, 0xab, 0x79, 0x55, 0x14, 0x81, +0x4e, 0xbc, 0x1a, 0x29, 0xa0, 0xe2, 0x24, 0xad, +0x61, 0x19, 0x85, 0x26, 0x69, 0x46, 0x88, 0x52, +0x67, 0x50, 0x0a, 0x3c, 0x57, 0x32, 0x56, 0xb1, +0x98, 0x9f, 0xf0, 0xe9, 0xaf, 0xbd, 0x47, 0xaf, +0xdb, 0x19, 0x30, 0x3e, 0x63, 0x7e, 0x36, 0x10, +0xa7, 0x4e, 0x9d, 0xe6, 0xf4, 0x99, 0x33, 0x48, +0x4b, 0x51, 0xad, 0x56, 0x70, 0x5d, 0x87, 0x6a, +0xad, 0xc6, 0xdf, 0x7a, 0xec, 0x93, 0x94, 0x2a, +0x15, 0xbe, 0xf5, 0xe4, 0x93, 0xbc, 0x7e, 0xec, +0xd8, 0xa0, 0x26, 0x9e, 0xd1, 0xf5, 0x40, 0x90, +0x3d, 0xf8, 0x76, 0x20, 0xdc, 0x88, 0xe1, 0xe6, +0x23, 0x6f, 0x89, 0x17, 0x9f, 0xfc, 0xd0, 0x84, +0x94, 0x02, 0xcb, 0x52, 0x57, 0x74, 0x39, 0x0d, +0xdf, 0xf7, 0x96, 0xe4, 0x27, 0xab, 0xa1, 0x9c, +0x3e, 0x79, 0x92, 0xb7, 0xde, 0x7c, 0x93, 0x5c, +0x2e, 0xc7, 0xdc, 0xde, 0x3d, 0xd8, 0x56, 0xd2, +0x44, 0xda, 0xeb, 0x74, 0x58, 0x5f, 0x5d, 0x19, +0xd4, 0x01, 0x82, 0x7e, 0x17, 0x7b, 0xf9, 0x0d, +0x76, 0xe5, 0x22, 0xca, 0x9e, 0xc4, 0xae, 0xd8, +0x30, 0x93, 0x4f, 0x7e, 0x77, 0xa9, 0x1b, 0x42, +0x68, 0xc4, 0x68, 0xc5, 0x1a, 0x15, 0xc9, 0x82, +0x1e, 0xd7, 0x7d, 0xe0, 0x1b, 0x9a, 0x80, 0x38, +0x59, 0x53, 0xd1, 0x52, 0x1a, 0x45, 0x6c, 0x06, +0x71, 0x3f, 0x96, 0x48, 0x5a, 0xc3, 0x86, 0x2f, +0x1f, 0x1a, 0x58, 0x4f, 0x3a, 0x52, 0x84, 0x00, +0x4b, 0x09, 0x4a, 0xa9, 0x16, 0x98, 0xcd, 0x5f, +0xa4, 0xbe, 0x7c, 0x66, 0x50, 0x43, 0x1f, 0x7c, +0x2e, 0xf5, 0x1d, 0xc2, 0x28, 0xe4, 0xad, 0x77, +0xde, 0xe5, 0xd2, 0xa5, 0x4b, 0xd8, 0xb6, 0x4d, +0xa9, 0x54, 0xc4, 0x71, 0x6c, 0x26, 0x27, 0x27, +0xf9, 0xcc, 0xcf, 0xfe, 0x2c, 0x23, 0x63, 0x63, +0x3c, 0xf9, 0xcd, 0x6f, 0xf2, 0xe7, 0x2f, 0xbc, +0x40, 0x3f, 0x9d, 0x4a, 0xbe, 0x73, 0x30, 0xaf, +0xe7, 0xf8, 0x6d, 0x01, 0x21, 0x5b, 0x2c, 0xea, +0x46, 0x4f, 0xfe, 0x51, 0xc8, 0x20, 0x25, 0xd8, +0xb6, 0x85, 0x65, 0x25, 0x2b, 0x8a, 0x5f, 0xcb, +0x14, 0x0d, 0x24, 0x5f, 0x27, 0xa1, 0xdf, 0xd9, +0xb3, 0x67, 0x79, 0xed, 0xd5, 0x57, 0x50, 0x52, +0xb2, 0x6f, 0x7e, 0x9e, 0x7c, 0x21, 0x99, 0x14, +0xea, 0xf7, 0xfb, 0xac, 0x2c, 0x2f, 0x11, 0x06, +0x61, 0x32, 0x99, 0x26, 0x8a, 0x08, 0x16, 0xdf, +0x65, 0x32, 0xbe, 0xcc, 0x78, 0x31, 0xf9, 0x75, +0x12, 0x31, 0x5f, 0x4c, 0x38, 0x19, 0x1a, 0x68, +0x46, 0x88, 0x50, 0xb3, 0x67, 0xda, 0x2b, 0xe6, +0x3c, 0x99, 0x8b, 0xb5, 0xb9, 0x6e, 0x41, 0xf8, +0x66, 0x3b, 0x21, 0x53, 0x51, 0x25, 0xe9, 0x01, +0xcc, 0xb4, 0x40, 0xc1, 0xda, 0x6e, 0x0a, 0x04, +0x89, 0x4f, 0xb0, 0x19, 0x40, 0x33, 0xe9, 0xf9, +0xf7, 0x1c, 0xc9, 0x44, 0xd5, 0xe6, 0xf6, 0xdd, +0xe0, 0xf5, 0xde, 0x61, 0x73, 0x6d, 0x31, 0xed, +0x80, 0x15, 0x03, 0xe6, 0xa7, 0xae, 0x03, 0xfd, +0x7e, 0x9f, 0x63, 0xaf, 0xbf, 0xc9, 0xc2, 0xc2, +0x12, 0xb6, 0x6d, 0x53, 0xc8, 0xe7, 0xb0, 0x6d, +0x9b, 0xe9, 0xe9, 0x69, 0x3e, 0xfb, 0xb9, 0xcf, +0x31, 0x3b, 0x37, 0xc7, 0xd3, 0xdf, 0xfd, 0x2e, +0xdf, 0x7a, 0xf2, 0xc9, 0xab, 0xce, 0x10, 0xbe, +0x19, 0xef, 0x7f, 0xd8, 0x3f, 0xc8, 0xc0, 0xf0, +0xe3, 0x02, 0x62, 0xfb, 0x35, 0xe5, 0x60, 0x35, +0xb2, 0xab, 0x51, 0xe6, 0xf0, 0x25, 0x6a, 0x3f, +0xa9, 0xea, 0x9d, 0xfc, 0xe0, 0x03, 0x5e, 0x7a, +0xf1, 0xfb, 0x68, 0x6d, 0x98, 0x3f, 0x74, 0x88, +0x6a, 0xad, 0x06, 0xc6, 0x10, 0x84, 0x21, 0xab, +0xcb, 0xcb, 0xf4, 0xba, 0x3d, 0x10, 0x24, 0x4b, +0xe8, 0xac, 0x5f, 0xa6, 0xb0, 0xfc, 0x2a, 0x73, +0x25, 0x43, 0x35, 0xa7, 0xb0, 0xf7, 0x14, 0x10, +0x55, 0x07, 0xfa, 0x1a, 0xd1, 0x8b, 0x13, 0xfe, +0x00, 0x96, 0x12, 0x4a, 0x0a, 0x21, 0x6f, 0xd4, +0x0f, 0x70, 0xed, 0x65, 0xe2, 0x92, 0x09, 0x8e, +0x02, 0x28, 0x96, 0xf3, 0xea, 0xd0, 0x7f, 0xf3, +0xf8, 0xf8, 0x13, 0xb2, 0x13, 0x25, 0x5d, 0x41, +0xc5, 0xb4, 0xc3, 0x56, 0x8a, 0x24, 0x0f, 0x90, +0xfd, 0x9c, 0x7b, 0xba, 0xba, 0xa6, 0x11, 0x24, +0xfb, 0x02, 0x8d, 0x70, 0x25, 0xca, 0x55, 0x58, +0x4a, 0x80, 0xee, 0x72, 0x6e, 0xa9, 0x8b, 0xcc, +0x4d, 0xe2, 0xa6, 0x4b, 0xa6, 0x41, 0xda, 0x77, +0x96, 0x36, 0x43, 0x84, 0x41, 0xc8, 0xea, 0xda, +0x3a, 0xa5, 0x52, 0x91, 0x4a, 0xb9, 0x3c, 0x50, +0xa1, 0xc5, 0x62, 0x91, 0x5b, 0xf6, 0xed, 0x4f, +0x9c, 0xc6, 0x37, 0xde, 0xe0, 0xd2, 0xc5, 0x8b, +0x8c, 0x8c, 0x8c, 0x50, 0x4e, 0x1b, 0x43, 0x76, +0x7a, 0xd5, 0x19, 0x63, 0x6e, 0x86, 0x69, 0x57, +0xeb, 0x43, 0xfc, 0x30, 0xdb, 0xce, 0x6b, 0x5e, +0x8b, 0xf1, 0x90, 0x2c, 0x67, 0x17, 0x45, 0x89, +0xc3, 0x17, 0x04, 0x3e, 0xef, 0xbd, 0xf3, 0x0e, +0xaf, 0xfc, 0xe8, 0x87, 0x28, 0xcb, 0xe2, 0xe0, +0xad, 0xb7, 0x52, 0x1b, 0x19, 0x49, 0xd2, 0x2a, +0x61, 0xc8, 0xc6, 0xea, 0xca, 0x20, 0xe7, 0x1f, +0x46, 0x31, 0xed, 0x66, 0x1d, 0x73, 0xf6, 0x79, +0xe6, 0xad, 0x45, 0xe6, 0x6a, 0x36, 0xc5, 0x5d, +0x39, 0xe4, 0xc1, 0x52, 0xf2, 0xab, 0xea, 0x91, +0x41, 0xac, 0xf4, 0x93, 0x99, 0xdb, 0x96, 0xe0, +0xa2, 0xa3, 0x56, 0xbe, 0xfa, 0xf4, 0xea, 0x53, +0x52, 0xb2, 0x10, 0x84, 0x26, 0x4a, 0x16, 0xbf, +0xbe, 0x4a, 0xea, 0xfc, 0x46, 0x00, 0x10, 0x82, +0x7c, 0xc9, 0x53, 0x07, 0xff, 0xd1, 0xa7, 0xc7, +0x9e, 0x90, 0xed, 0x48, 0x0e, 0xba, 0x1e, 0xbd, +0x34, 0xf6, 0xcf, 0x40, 0xd0, 0x4f, 0x97, 0x43, +0xc9, 0xc4, 0x59, 0x88, 0xa4, 0x44, 0xdc, 0x8b, +0x91, 0x80, 0x95, 0xb7, 0xb0, 0x1d, 0x41, 0xe8, +0xd7, 0xb9, 0xb0, 0x6a, 0xc8, 0x95, 0x26, 0x06, +0x59, 0x3e, 0x21, 0x12, 0x3d, 0x60, 0x29, 0x45, +0xce, 0x75, 0xd1, 0x71, 0x4c, 0xbd, 0xd1, 0xc4, +0x71, 0x1d, 0x2a, 0xe9, 0x84, 0x0d, 0x21, 0x24, +0x85, 0x42, 0x9e, 0xf9, 0xf9, 0x79, 0x72, 0xf9, +0x3c, 0xef, 0xbe, 0xfb, 0x2e, 0x6f, 0xbf, 0xfd, +0xf6, 0xa0, 0x23, 0x27, 0xcb, 0x09, 0x5c, 0x8d, +0x01, 0x37, 0xd5, 0xf5, 0xfb, 0x11, 0x99, 0x7e, +0x33, 0xf9, 0x86, 0x4c, 0x33, 0xc5, 0xb1, 0x1e, +0x84, 0x7b, 0xf5, 0xfa, 0x26, 0xaf, 0xfc, 0xf0, +0x87, 0xbc, 0xfd, 0xf6, 0x5b, 0x14, 0x0b, 0x45, +0x6e, 0xbd, 0xfd, 0xf6, 0x41, 0xbe, 0x23, 0x0c, +0x43, 0xd6, 0x57, 0x96, 0xe9, 0xa4, 0x5a, 0x2e, +0x8c, 0x62, 0x5a, 0xed, 0x36, 0xc1, 0xc5, 0x57, +0xd8, 0xdd, 0x7d, 0x9b, 0xf9, 0x51, 0x45, 0x6d, +0xd2, 0xc5, 0x3e, 0x5c, 0x4d, 0x16, 0x8b, 0x0e, +0x74, 0xb2, 0x5d, 0xea, 0x26, 0xf3, 0x35, 0x6c, +0xc1, 0x25, 0x47, 0xad, 0x7c, 0xed, 0xbb, 0xab, +0xdf, 0x16, 0x5c, 0x1f, 0x00, 0x37, 0xaa, 0x06, +0x1a, 0x29, 0xd0, 0xb1, 0x31, 0xfd, 0x6e, 0x4c, +0xb7, 0x2c, 0x28, 0x61, 0xc0, 0x64, 0x6d, 0x61, +0x56, 0xba, 0x4c, 0x8a, 0x2d, 0x61, 0xdc, 0xc5, +0xac, 0x07, 0xc9, 0x7c, 0x41, 0x09, 0xd9, 0x1a, +0x82, 0x06, 0xd0, 0xad, 0x10, 0xab, 0x13, 0x31, +0xe2, 0x59, 0x1c, 0xda, 0x25, 0xd9, 0xe8, 0x1c, +0x67, 0xe1, 0x5c, 0x8e, 0xd9, 0xfd, 0x49, 0xd9, +0xd7, 0xb5, 0x1c, 0xc6, 0x47, 0x47, 0x98, 0xde, +0x35, 0x4d, 0xb5, 0x5a, 0xa3, 0x50, 0x28, 0x62, +0x30, 0xd4, 0xeb, 0x0d, 0x96, 0x96, 0x96, 0x19, +0x4f, 0x17, 0x93, 0x10, 0x42, 0x90, 0xcf, 0xe7, +0xf9, 0xa9, 0x9f, 0x7a, 0x94, 0xbd, 0x7b, 0xf7, +0xf2, 0xa7, 0x4f, 0x3d, 0xc5, 0x53, 0xdf, 0xfa, +0x16, 0x27, 0x4f, 0x9c, 0xe0, 0xe1, 0x47, 0x1e, +0xe1, 0x96, 0x7d, 0xfb, 0xb6, 0xa5, 0x8e, 0x77, +0x3e, 0xf0, 0x4f, 0x22, 0x2c, 0xbc, 0x91, 0xd3, +0x79, 0xb5, 0x73, 0xa3, 0x38, 0x4e, 0x42, 0x43, +0x9d, 0x48, 0xfd, 0xd9, 0x33, 0x67, 0x38, 0xf6, +0xda, 0x6b, 0xb4, 0x5b, 0x4d, 0x26, 0xa6, 0xa6, +0xd8, 0xb7, 0x7f, 0x9e, 0x5c, 0x2e, 0xe9, 0xf6, +0xf5, 0xfb, 0x7d, 0x36, 0xd7, 0xd7, 0xe8, 0x75, +0xbb, 0x40, 0xa2, 0x31, 0x9a, 0xed, 0x36, 0xc1, +0xd2, 0x7b, 0x4c, 0x36, 0x8f, 0x31, 0x3f, 0x26, +0x19, 0x19, 0x77, 0xb1, 0x8f, 0x54, 0x11, 0x4a, +0x20, 0xba, 0x51, 0x32, 0xe5, 0x7c, 0xb9, 0xb7, +0xf5, 0xd3, 0x7b, 0x8e, 0x42, 0x28, 0x99, 0x74, +0xe9, 0x5f, 0x2f, 0x17, 0xcd, 0xf5, 0xaa, 0x81, +0x42, 0x64, 0xbf, 0x93, 0xe3, 0xba, 0xb6, 0x9c, +0xf9, 0xfb, 0x3f, 0x35, 0xf2, 0xa9, 0x72, 0x6c, +0x4a, 0x26, 0xad, 0x01, 0x61, 0x00, 0x6f, 0x68, +0x7d, 0x00, 0x4b, 0x82, 0xa7, 0x30, 0x41, 0x8c, +0x8e, 0x21, 0xd0, 0x86, 0x4e, 0x68, 0x68, 0xfa, +0x9a, 0xa6, 0xaf, 0x69, 0xf5, 0x35, 0xdd, 0x46, +0x48, 0xb7, 0x19, 0xd1, 0x09, 0x7c, 0x2e, 0xae, +0x6c, 0x62, 0xe5, 0xa6, 0xd8, 0x33, 0xbb, 0x87, +0xbd, 0x73, 0xb3, 0xcc, 0xcc, 0xec, 0x66, 0x74, +0x6c, 0x8c, 0x72, 0xb9, 0x4c, 0xa1, 0x58, 0xa0, +0x94, 0x16, 0x44, 0xfc, 0xc0, 0xe7, 0xf4, 0xe9, +0xd3, 0x14, 0x0a, 0xc9, 0x4a, 0xdc, 0x59, 0x46, +0xad, 0x5c, 0x2e, 0x73, 0xe8, 0xd6, 0xdb, 0x28, +0x95, 0x8a, 0xbc, 0x7f, 0xfc, 0x38, 0xc7, 0x8e, +0x1d, 0x63, 0x6d, 0x6d, 0x9d, 0x72, 0xa9, 0x4c, +0x3e, 0x5f, 0x20, 0x5b, 0xdd, 0xf3, 0x6a, 0x0c, +0xc9, 0x9e, 0xef, 0xc3, 0xd0, 0x87, 0xc9, 0x2e, +0x66, 0xbd, 0x7b, 0xda, 0x68, 0xe2, 0xd4, 0xd6, +0x47, 0x61, 0xc8, 0xd2, 0xd2, 0x22, 0x2f, 0xfd, +0xe0, 0x45, 0xde, 0x7c, 0xfd, 0x75, 0x84, 0x14, +0x1c, 0x38, 0x74, 0x2b, 0x7b, 0x6e, 0xd9, 0x37, +0x58, 0x88, 0xa2, 0xd3, 0x6e, 0xb1, 0xb9, 0xbe, +0x46, 0x98, 0xae, 0x99, 0x10, 0x84, 0x11, 0x1b, +0x8d, 0x26, 0xfe, 0xea, 0x69, 0x6a, 0x2b, 0x7f, +0xc6, 0x6d, 0xb5, 0x80, 0xa9, 0x29, 0x97, 0xfc, +0xd1, 0x2a, 0x2a, 0xa7, 0xb6, 0x98, 0xdf, 0x0c, +0x93, 0x0e, 0xed, 0xf4, 0xf6, 0x4c, 0xc9, 0xe6, +0xe5, 0x95, 0xf0, 0xf4, 0xd7, 0x9f, 0x59, 0xfd, +0xa6, 0x65, 0x89, 0x95, 0x20, 0x34, 0xf1, 0x47, +0xd5, 0x00, 0x00, 0x61, 0xcf, 0xd7, 0xf5, 0xf3, +0xeb, 0xe1, 0xfa, 0x4c, 0x45, 0x4d, 0xd3, 0x8d, +0x13, 0xf5, 0x1e, 0x68, 0xe8, 0x45, 0x98, 0x9c, +0xc5, 0x60, 0x4d, 0x20, 0x4b, 0xe0, 0x97, 0x6c, +0x5a, 0x4b, 0x7d, 0xd6, 0x9a, 0x31, 0x97, 0x1b, +0x21, 0x4b, 0xcd, 0x88, 0xa5, 0x66, 0x44, 0x10, +0x27, 0xf1, 0xab, 0x52, 0x82, 0xd0, 0x1e, 0xe5, +0xe0, 0xd1, 0xbf, 0xcd, 0x6d, 0xf7, 0x3c, 0xc0, +0xe4, 0xd4, 0x2e, 0x2a, 0x95, 0x0a, 0xa5, 0x52, +0x89, 0x5c, 0x3e, 0x8f, 0x6d, 0x3b, 0x28, 0x4b, +0x61, 0xb4, 0xa6, 0xd7, 0xeb, 0x12, 0x87, 0x7d, +0x5a, 0xf5, 0x0d, 0x9e, 0x7d, 0xf6, 0x3c, 0xf7, +0xdf, 0x7f, 0x1f, 0x13, 0x13, 0xe3, 0x83, 0xce, +0x98, 0x5c, 0xce, 0xe3, 0xbe, 0xfb, 0x3f, 0xc1, +0xfc, 0xfc, 0x01, 0x5e, 0x7d, 0xf5, 0x15, 0xde, +0x78, 0xfd, 0x75, 0x4e, 0x1c, 0xff, 0xff, 0xda, +0x3b, 0xcf, 0x58, 0x4b, 0xae, 0xfb, 0xb0, 0xff, +0xce, 0x99, 0x76, 0xe7, 0x96, 0xd7, 0xf7, 0x6d, +0xaf, 0x24, 0x77, 0x49, 0xae, 0x44, 0x53, 0x8a, +0x2c, 0x59, 0x96, 0x64, 0xcb, 0xa4, 0x2c, 0x5b, +0x8e, 0xed, 0x38, 0x4a, 0x2c, 0xe7, 0x83, 0xbf, +0x04, 0x41, 0x12, 0x07, 0xc8, 0x87, 0x7c, 0x74, +0x0c, 0x04, 0x30, 0x8c, 0x14, 0x24, 0x40, 0x12, +0xc3, 0x30, 0x12, 0x28, 0x8e, 0x6d, 0xb9, 0xc3, +0x36, 0x22, 0xc9, 0x4d, 0x8d, 0xb2, 0x8a, 0xa9, +0x16, 0x59, 0xa4, 0x28, 0x72, 0x59, 0x96, 0x4b, +0x72, 0xdb, 0xdb, 0xb7, 0xaf, 0xb7, 0x5b, 0xa7, +0x9d, 0x7f, 0x3e, 0x9c, 0x33, 0x73, 0xe7, 0xbd, +0x7d, 0x5b, 0xd4, 0x6c, 0x39, 0xd0, 0x01, 0xe6, +0xcd, 0xdc, 0x3b, 0xf7, 0xdd, 0x3b, 0x33, 0xff, +0xde, 0x5f, 0xe4, 0xfe, 0xb3, 0x67, 0x79, 0xf3, +0x9b, 0xdf, 0xcc, 0xb1, 0xe3, 0xc7, 0x88, 0xa2, +0x46, 0xe5, 0x7a, 0x2e, 0x81, 0x53, 0xdf, 0xdf, +0x0d, 0x11, 0xbe, 0x1e, 0xa0, 0x97, 0xfb, 0xc2, +0xb1, 0xf9, 0x32, 0xb8, 0xb3, 0xba, 0xb2, 0xcc, +0x05, 0x17, 0x69, 0x14, 0x63, 0x38, 0x76, 0xe2, +0x04, 0xc7, 0x4f, 0x9e, 0xa2, 0x19, 0xc7, 0x80, +0xe5, 0x10, 0xdd, 0xed, 0x6d, 0xfa, 0xdd, 0xae, +0x4b, 0xa2, 0x55, 0x0c, 0x93, 0x84, 0xf5, 0xcd, +0x2d, 0xd2, 0xf5, 0x2b, 0x74, 0x6e, 0x7e, 0x8a, +0x07, 0xa7, 0x87, 0x1c, 0x3c, 0x16, 0x13, 0x9f, +0x9f, 0x44, 0x47, 0x1a, 0xd5, 0xcf, 0xc1, 0x08, +0x92, 0x18, 0x58, 0x1c, 0x5a, 0xd6, 0x8f, 0x33, +0x48, 0x9b, 0x9e, 0x2c, 0xad, 0x0f, 0x56, 0x0b, +0xc3, 0xb0, 0xac, 0x0e, 0xbe, 0xdd, 0xba, 0x7b, +0x65, 0x90, 0xa2, 0xe8, 0x27, 0xa6, 0x77, 0xe1, +0xda, 0x70, 0xe9, 0xad, 0x6f, 0x9a, 0x38, 0xcf, +0xa0, 0xb0, 0x8a, 0xa0, 0xa7, 0x6c, 0x82, 0xa8, +0xa7, 0x5d, 0x2a, 0xb8, 0xd0, 0x4f, 0x0c, 0xab, +0xbd, 0x9c, 0x8b, 0x6b, 0x39, 0x4f, 0xfc, 0xf5, +0x16, 0x4f, 0xbe, 0xdc, 0xe7, 0xe6, 0x76, 0x46, +0x51, 0xd8, 0x44, 0xcd, 0x28, 0x8c, 0x88, 0xe3, +0x06, 0x67, 0x4e, 0x4d, 0xf0, 0xd6, 0x81, 0x4f, +0xd4, 0x88, 0x99, 0x9d, 0x9d, 0xa5, 0xd3, 0x99, +0x20, 0x8a, 0x1b, 0x04, 0xae, 0x7c, 0x2b, 0xcf, +0x32, 0x7a, 0xdd, 0x6d, 0xd6, 0x57, 0x57, 0x58, +0x5d, 0x5d, 0x66, 0x6b, 0x73, 0x9d, 0x9b, 0x8b, +0xab, 0x7c, 0xe2, 0x89, 0xbf, 0xe4, 0xe1, 0x87, +0x1e, 0xe4, 0xa1, 0x87, 0x1e, 0xb4, 0x45, 0xa4, +0x6e, 0x4d, 0xcf, 0xcc, 0xf0, 0xd8, 0xe3, 0x8f, +0xf3, 0xba, 0xd7, 0x3f, 0xc2, 0xb3, 0xcf, 0x3c, +0xc3, 0xf3, 0x17, 0x2e, 0x70, 0xf1, 0xc5, 0x17, +0x39, 0x76, 0xfc, 0x38, 0x0f, 0x9f, 0x3f, 0xcf, +0x03, 0x0f, 0x3c, 0xc0, 0xd4, 0xf4, 0xd4, 0x2e, +0xf1, 0x70, 0x3b, 0x31, 0xf1, 0xf5, 0xac, 0x3a, +0xd0, 0x8d, 0xb1, 0xb3, 0x05, 0xc5, 0x95, 0x79, +0x0f, 0x07, 0x03, 0x16, 0x16, 0x16, 0xb8, 0x74, +0xf1, 0x25, 0x16, 0xae, 0x2f, 0x80, 0x82, 0x43, +0x87, 0x0f, 0x73, 0xfc, 0xc4, 0xc9, 0xaa, 0xd4, +0xdb, 0x98, 0x82, 0x64, 0x34, 0xa2, 0xbb, 0xb3, +0x43, 0x96, 0x24, 0x94, 0xbe, 0x84, 0xee, 0x60, +0xc8, 0xc6, 0xe6, 0x26, 0xf9, 0xc6, 0x65, 0x26, +0x96, 0x3f, 0xcd, 0xf9, 0xd9, 0x3e, 0x47, 0x4f, +0xb5, 0xe8, 0x9c, 0xeb, 0xe0, 0x05, 0x0e, 0xf8, +0x82, 0x15, 0xb7, 0x0b, 0x03, 0x37, 0x76, 0xb7, +0x76, 0x5d, 0x13, 0x21, 0x8b, 0xab, 0xc9, 0x75, +0x6a, 0xfd, 0x01, 0x6e, 0x77, 0x9f, 0x77, 0x4f, +0x08, 0x81, 0x40, 0x60, 0xee, 0xed, 0x0f, 0xb7, +0xdf, 0xf1, 0x7d, 0xe7, 0x5a, 0x0f, 0xa8, 0x6e, +0x6e, 0xd3, 0xcc, 0x03, 0x6d, 0xfb, 0xf7, 0xe7, +0xc2, 0xc8, 0x08, 0xeb, 0x3d, 0xc3, 0xe5, 0x95, +0x84, 0xcf, 0x5c, 0xe8, 0xf2, 0x1b, 0x9f, 0x5a, +0xe7, 0x53, 0x2f, 0x8e, 0xd8, 0x1a, 0x86, 0x14, +0xc6, 0x06, 0x7f, 0xc2, 0x30, 0xa4, 0xd9, 0x6e, +0x33, 0x31, 0x31, 0x49, 0x10, 0x86, 0x6c, 0x6f, +0x6d, 0xf3, 0xea, 0xab, 0xaf, 0x12, 0x04, 0x21, +0xa7, 0xcf, 0x9c, 0xa6, 0xd5, 0x6a, 0x01, 0xc2, +0x68, 0x38, 0x60, 0x63, 0x7d, 0x8d, 0xc5, 0x85, +0xeb, 0x2c, 0x2c, 0x5c, 0x67, 0xe9, 0xe6, 0x12, +0x6b, 0x6b, 0x6b, 0x6c, 0x6f, 0x77, 0x29, 0x04, +0x96, 0x56, 0x96, 0x59, 0x5a, 0x5a, 0x22, 0x8a, +0x22, 0x5a, 0xad, 0x26, 0x9e, 0xf6, 0x6c, 0xd2, +0x9b, 0x52, 0xb4, 0x9a, 0xb6, 0x40, 0xf4, 0xdc, +0x43, 0x0f, 0x11, 0xb7, 0x9a, 0xdc, 0x5c, 0x5c, +0xe4, 0xc2, 0x73, 0xcf, 0xf1, 0xcc, 0x33, 0xcf, +0xb0, 0x78, 0x63, 0x91, 0x5e, 0xaf, 0x67, 0xdb, +0xc6, 0x97, 0xee, 0xe8, 0x3b, 0x24, 0xea, 0x2b, +0xb5, 0x7f, 0x31, 0x65, 0x19, 0xe8, 0x31, 0xc6, +0x60, 0xc4, 0x90, 0x3b, 0x80, 0x8f, 0x46, 0x23, +0xba, 0xdd, 0x1e, 0x57, 0xaf, 0x5e, 0xe5, 0x99, +0xaf, 0x3e, 0xcd, 0x97, 0xbe, 0xf0, 0x05, 0x5e, +0x7c, 0xde, 0x36, 0x89, 0x3a, 0x72, 0xe4, 0x28, +0x0f, 0x9d, 0x7f, 0x98, 0xa3, 0xc7, 0x4f, 0x10, +0x3b, 0xaa, 0xcf, 0xd2, 0x94, 0x5e, 0x77, 0x87, +0x41, 0xd7, 0x4e, 0x17, 0x11, 0xac, 0xf2, 0xb7, +0xdd, 0xed, 0xb1, 0xb9, 0xb9, 0x41, 0xb6, 0xf2, +0x22, 0xb3, 0x1b, 0x4f, 0x72, 0xfe, 0xc0, 0x88, +0x63, 0xe7, 0xda, 0x74, 0xce, 0x4d, 0xd8, 0x31, +0x73, 0x03, 0x57, 0x98, 0x5b, 0x18, 0x0b, 0xfc, +0x9d, 0x7c, 0xb7, 0xa7, 0x47, 0x43, 0x76, 0x7f, +0xa7, 0xf8, 0x8f, 0xbf, 0x7e, 0xed, 0xf7, 0x56, +0x36, 0xd2, 0x67, 0xc3, 0x40, 0x75, 0xd3, 0x4c, +0x6e, 0xdb, 0x2d, 0xfc, 0xee, 0x22, 0x40, 0xa1, +0x23, 0x5f, 0x35, 0xce, 0x1e, 0x69, 0xcc, 0x0f, +0x51, 0x45, 0xd3, 0x57, 0x3e, 0xb9, 0x20, 0x99, +0x21, 0x43, 0x33, 0x48, 0x0c, 0xcb, 0x6b, 0x29, +0x2f, 0xae, 0x65, 0x7c, 0xe4, 0x6b, 0x3b, 0x7c, +0xf2, 0x6b, 0x5d, 0x76, 0x46, 0x11, 0x51, 0x78, +0x18, 0xed, 0x85, 0x64, 0xd9, 0x0e, 0x49, 0xb2, +0xc9, 0x70, 0x94, 0xd8, 0x8a, 0x9c, 0x4e, 0xc7, +0x76, 0xc1, 0x88, 0x63, 0x5a, 0xcd, 0x26, 0xcf, +0x5f, 0x78, 0x8e, 0xfe, 0xa0, 0xcf, 0xe3, 0x8f, +0x3f, 0x4e, 0xb3, 0xd9, 0x60, 0x63, 0x6d, 0x95, +0xd5, 0x95, 0x65, 0x56, 0x57, 0x56, 0xd8, 0xd8, +0xd8, 0x64, 0x6b, 0x7b, 0x9b, 0xad, 0xed, 0x6d, +0x44, 0x05, 0x34, 0x14, 0xe4, 0x79, 0xce, 0xc2, +0x8d, 0x1b, 0x2c, 0x2d, 0x2f, 0x71, 0xf2, 0xc4, +0x49, 0x1e, 0x79, 0xe4, 0x75, 0x1c, 0x9c, 0x9f, +0xc7, 0xd3, 0x9a, 0x42, 0x09, 0x5a, 0x2b, 0x26, +0x26, 0x27, 0xf9, 0xde, 0x37, 0xbf, 0x85, 0xef, +0x79, 0xf4, 0x51, 0x96, 0x97, 0x96, 0x79, 0xe5, +0xd2, 0x25, 0xae, 0x5d, 0xbd, 0xca, 0xa5, 0x97, +0x5f, 0x46, 0x29, 0xdb, 0x66, 0xe5, 0xe0, 0xa1, +0x43, 0x1c, 0x3a, 0x74, 0x88, 0x03, 0xf3, 0xf3, +0x4c, 0xcf, 0xcc, 0xd2, 0x68, 0x34, 0xaa, 0x70, +0x75, 0xd5, 0x55, 0x5c, 0x5b, 0x4b, 0xa7, 0xac, +0x39, 0x34, 0x8e, 0xa5, 0x1b, 0x57, 0xa5, 0xd3, +0xeb, 0x75, 0xd9, 0xd8, 0xb0, 0x0d, 0x1c, 0x6e, +0x2e, 0x2e, 0xb2, 0xba, 0xb2, 0x4c, 0x9a, 0x65, +0x84, 0x61, 0xc8, 0xec, 0xec, 0x2c, 0xa7, 0xef, +0xbb, 0xcf, 0x4e, 0x0e, 0x8b, 0x22, 0x87, 0x3c, +0x42, 0x96, 0xa6, 0x8c, 0x86, 0x43, 0x92, 0xd1, +0xa8, 0x72, 0x19, 0x0b, 0xd0, 0x1b, 0x0c, 0xd9, +0xea, 0xee, 0xd0, 0xdf, 0xd9, 0x22, 0xbf, 0xf9, +0x35, 0x8e, 0x25, 0xcf, 0x70, 0xf6, 0x98, 0xe1, +0xd0, 0xb9, 0x29, 0xda, 0x87, 0xd5, 0x41, 0xba, +0xe9, 0x00, 0x00, 0x20, 0x00, 0x49, 0x44, 0x41, +0x54, 0x63, 0xbc, 0xac, 0x40, 0x8d, 0x6a, 0xc0, +0xbf, 0x39, 0xb4, 0x75, 0x00, 0x7b, 0x11, 0x74, +0x22, 0x60, 0xb9, 0x9b, 0x2f, 0x2f, 0x2c, 0x25, +0xd7, 0x02, 0x5f, 0x0d, 0x93, 0x54, 0xbe, 0xc1, +0x7c, 0x80, 0xf2, 0x0b, 0x05, 0xbf, 0x19, 0xe9, +0x89, 0xa3, 0xd3, 0xfe, 0x54, 0x31, 0x2c, 0x44, +0x5a, 0x3e, 0x66, 0x33, 0x65, 0xd8, 0x37, 0x6c, +0x52, 0x70, 0xbd, 0x5b, 0xf0, 0xf9, 0x57, 0x07, +0x7c, 0xe8, 0xe9, 0x1d, 0x5e, 0x5e, 0x2e, 0xd0, +0xde, 0x34, 0x71, 0x3c, 0x89, 0x98, 0x82, 0xe1, +0x70, 0x99, 0x3c, 0xef, 0x03, 0x76, 0x86, 0xde, +0xfa, 0x86, 0x45, 0x04, 0xed, 0x79, 0x4c, 0x4f, +0x4e, 0x92, 0xe7, 0xb9, 0xad, 0x07, 0xd8, 0xdc, +0xe4, 0x8f, 0xff, 0xf0, 0x0f, 0x79, 0xe4, 0x91, +0xf3, 0x88, 0xc9, 0xd9, 0xd8, 0xd8, 0x64, 0x63, +0x63, 0x93, 0xcd, 0x2d, 0x5b, 0xb8, 0x31, 0x1a, +0x25, 0xcc, 0xce, 0xdb, 0x9e, 0x79, 0xe2, 0x80, +0x31, 0x1a, 0xe5, 0xbc, 0x74, 0xf1, 0x22, 0xaf, +0xbd, 0xf6, 0x1a, 0x67, 0xce, 0x9c, 0xe6, 0xf5, +0xaf, 0x3b, 0xcf, 0xfc, 0x81, 0x79, 0xe7, 0x7d, +0xb3, 0xe9, 0xb0, 0x41, 0x10, 0x72, 0xf4, 0xd8, +0x51, 0x0e, 0x1d, 0x3e, 0x4c, 0x96, 0xa5, 0x6c, +0x6e, 0x6c, 0xb0, 0xbc, 0xb4, 0xc4, 0xe2, 0x0d, +0xdb, 0x81, 0xeb, 0xc5, 0x17, 0x5e, 0x00, 0xb1, +0xd5, 0xca, 0x8d, 0x46, 0x83, 0xce, 0xc4, 0x24, +0xad, 0x56, 0x93, 0x46, 0xd4, 0x40, 0x7b, 0x9a, +0x66, 0xdc, 0x44, 0x6b, 0xcd, 0xa8, 0x56, 0x7c, +0x3a, 0x28, 0xc7, 0xcc, 0xd5, 0xda, 0xc7, 0x7a, +0x9e, 0x66, 0x72, 0x6a, 0x8a, 0x63, 0x27, 0x4f, +0x32, 0x3b, 0x3b, 0xcb, 0xd4, 0xf4, 0x34, 0x61, +0x18, 0x55, 0x81, 0x1f, 0x63, 0x0c, 0x59, 0x66, +0x6b, 0x24, 0xd3, 0x34, 0xb1, 0xa5, 0x6e, 0xce, +0xad, 0x9b, 0x64, 0x39, 0x5b, 0xae, 0x9f, 0x51, +0xb2, 0xb3, 0x06, 0x37, 0x3e, 0xcf, 0xfd, 0xc1, +0x15, 0x1e, 0x78, 0x30, 0x62, 0xee, 0xfe, 0x36, +0xcd, 0xb6, 0x8f, 0x37, 0xcc, 0xad, 0x4f, 0x05, +0xb1, 0x9a, 0xfe, 0xf2, 0x08, 0xb6, 0xf3, 0x5b, +0x81, 0x0f, 0xc8, 0x81, 0x86, 0x7c, 0xee, 0x99, +0xed, 0x57, 0x37, 0x77, 0xf2, 0x95, 0xc0, 0x57, +0x69, 0x19, 0x64, 0xba, 0xdd, 0xba, 0x17, 0x1d, +0xc0, 0x0b, 0x3d, 0xd5, 0x99, 0x0c, 0x74, 0xa7, +0x95, 0x19, 0x3f, 0x6d, 0xfb, 0x74, 0x6f, 0x1a, +0x96, 0x76, 0x72, 0x5e, 0x5c, 0x4b, 0xf9, 0xb3, +0x8b, 0x03, 0x3e, 0xfb, 0xf2, 0x80, 0x5e, 0xda, +0x20, 0x8a, 0x0e, 0xe2, 0x79, 0x21, 0x69, 0x6a, +0xa9, 0x5e, 0xe4, 0xd6, 0x72, 0xab, 0xc1, 0x60, +0xc0, 0xc5, 0x97, 0x2f, 0x31, 0x1c, 0x0c, 0xaa, +0x8c, 0x9d, 0x76, 0xbb, 0x85, 0x31, 0xc2, 0x9f, +0xff, 0xf9, 0x35, 0xee, 0xbf, 0xef, 0x14, 0x79, +0x9e, 0xb3, 0xb5, 0xb5, 0xcd, 0xf6, 0xf6, 0x0e, +0xb9, 0x11, 0x0e, 0x1c, 0x3a, 0x4c, 0xab, 0xd3, +0xa9, 0x80, 0x5f, 0xd6, 0x0b, 0x1a, 0x11, 0x86, +0xa3, 0x11, 0xcf, 0xbf, 0xf0, 0x22, 0x97, 0x5e, +0x79, 0x95, 0xe3, 0x47, 0x8f, 0xf2, 0xe0, 0x83, +0xe7, 0x38, 0x7e, 0xfc, 0x58, 0x95, 0x15, 0x54, +0x14, 0x85, 0x2b, 0x48, 0xb5, 0x2d, 0x5e, 0x66, +0x0f, 0x1c, 0xe0, 0xdc, 0x43, 0x0f, 0x93, 0x67, +0x39, 0xa3, 0x91, 0x6d, 0xff, 0xb6, 0xbd, 0xb5, +0x45, 0xbf, 0xdf, 0xa7, 0xdf, 0xeb, 0x31, 0x74, +0xac, 0x5c, 0xc4, 0x90, 0x8c, 0x12, 0x10, 0x83, +0xe7, 0xd9, 0xa9, 0x61, 0x4a, 0x6b, 0xa2, 0xd0, +0xc6, 0x28, 0x0e, 0x1f, 0x3d, 0x4a, 0xab, 0x6d, +0xfb, 0xf8, 0xb5, 0x5a, 0x4d, 0x3b, 0x99, 0xb4, +0xcc, 0x40, 0x12, 0xaa, 0x39, 0x85, 0xe5, 0xd8, +0x39, 0x3b, 0x5e, 0xd6, 0x38, 0xa1, 0xa3, 0x48, +0xf3, 0x8c, 0x9d, 0xfe, 0x80, 0xc1, 0x70, 0x48, +0xbf, 0xb7, 0xcd, 0x68, 0xe5, 0x12, 0x9d, 0xad, +0xbf, 0xe6, 0xbe, 0xb9, 0x2e, 0x27, 0x1e, 0xe8, +0x30, 0x73, 0x34, 0x26, 0x02, 0x74, 0x2f, 0x03, +0x83, 0x6d, 0x20, 0x91, 0x14, 0xb0, 0x32, 0x82, +0x41, 0xb1, 0xbf, 0x83, 0xdf, 0x57, 0xc8, 0xa1, +0x06, 0x6b, 0x9f, 0xdb, 0xdc, 0x2e, 0x0a, 0x19, +0xf9, 0x9e, 0x4b, 0x48, 0xfa, 0x46, 0x10, 0xc0, +0xcd, 0xe1, 0x53, 0x80, 0xef, 0x69, 0xd5, 0x9a, +0x6b, 0x79, 0x53, 0xc3, 0xcd, 0x54, 0x6d, 0x7a, +0x9a, 0x2b, 0x3b, 0x05, 0x9f, 0x7d, 0xa1, 0xc7, +0x9f, 0x5c, 0xe8, 0xf1, 0xea, 0x86, 0xe0, 0xfb, +0x96, 0xea, 0x8d, 0xc9, 0x19, 0x0c, 0x96, 0x2a, +0xaa, 0xbf, 0xdd, 0x2a, 0x8a, 0x82, 0x2b, 0xd7, +0xae, 0x93, 0x66, 0x19, 0x0f, 0x9e, 0x3d, 0x6b, +0xfb, 0x02, 0x68, 0xed, 0x8a, 0x27, 0xb6, 0x99, +0x9b, 0x9d, 0x65, 0x7b, 0x73, 0x85, 0x41, 0x77, +0x95, 0x83, 0xc7, 0xce, 0xd9, 0xd6, 0x28, 0x25, +0xe0, 0xab, 0xd8, 0xb9, 0x7d, 0xed, 0x12, 0x9e, +0x18, 0x0e, 0x47, 0x5c, 0x7c, 0xe5, 0x55, 0x5e, +0xb9, 0x72, 0x85, 0xa9, 0xc9, 0x49, 0xce, 0xde, +0x7f, 0x1f, 0x67, 0x4e, 0x9f, 0x66, 0x7a, 0x7a, +0xca, 0xb2, 0x76, 0xb1, 0x3d, 0x09, 0x4a, 0x84, +0xb0, 0x83, 0x1e, 0x7d, 0x5a, 0xed, 0x36, 0x47, +0x8e, 0x1e, 0xad, 0xbe, 0xb7, 0x28, 0x8a, 0xaa, +0xbd, 0x7b, 0x61, 0xcc, 0xf8, 0xe1, 0xb9, 0x84, +0x8a, 0xb1, 0xfe, 0xe0, 0x60, 0x2d, 0xb5, 0x9a, +0xbd, 0xd2, 0xd1, 0x53, 0xe4, 0x18, 0x07, 0x70, +0x63, 0x0c, 0x88, 0xa9, 0x5c, 0xcd, 0x69, 0x5e, +0x30, 0x4c, 0x53, 0xfa, 0xfd, 0x21, 0xc3, 0xe1, +0x80, 0xee, 0xea, 0x02, 0xd9, 0xd2, 0x53, 0x1c, +0x0f, 0x5e, 0xe1, 0xcc, 0x43, 0x3e, 0x07, 0x4f, +0x4d, 0xd1, 0x69, 0x79, 0x84, 0x99, 0x73, 0xee, +0x94, 0x00, 0xec, 0x67, 0xb0, 0x9e, 0x8e, 0xab, +0xb2, 0xca, 0x71, 0x61, 0xa5, 0xe9, 0x07, 0xc8, +0x7c, 0x03, 0xa5, 0x95, 0x3a, 0xd0, 0xd4, 0xd3, +0x5a, 0x55, 0xb5, 0x5c, 0x5f, 0x1f, 0x07, 0x50, +0x4a, 0xa1, 0x77, 0x39, 0x53, 0xf0, 0x80, 0x66, +0x7f, 0x50, 0x84, 0xab, 0xcb, 0x29, 0x2f, 0x2c, +0x24, 0x7c, 0xf8, 0xcb, 0x5b, 0x3c, 0xf9, 0x42, +0x9f, 0x41, 0x1e, 0x13, 0x35, 0x66, 0xd1, 0x3a, +0x20, 0xcb, 0xba, 0x24, 0xc9, 0x06, 0x22, 0xf7, +0x96, 0x05, 0x2b, 0x22, 0xdc, 0x58, 0xbc, 0x49, +0x9e, 0xe7, 0x1c, 0x3f, 0x7a, 0xd4, 0x76, 0xfb, +0x06, 0x36, 0xd6, 0xd7, 0x18, 0xed, 0xdc, 0xe0, +0x78, 0x6b, 0x89, 0x87, 0x0f, 0x15, 0x0c, 0xd2, +0x0d, 0xd6, 0x2e, 0x2f, 0x13, 0x4d, 0xdf, 0x4f, +0xb3, 0x33, 0x65, 0xef, 0xb9, 0x44, 0x04, 0x29, +0x01, 0x30, 0x7e, 0x08, 0x79, 0x96, 0xb1, 0xb6, +0xb6, 0xc6, 0xda, 0xda, 0x1a, 0x4f, 0x7d, 0xf5, +0xab, 0xcc, 0x4c, 0x4f, 0x73, 0xf2, 0xe4, 0x09, +0x8e, 0x1e, 0x3e, 0xc2, 0x81, 0x03, 0xd6, 0x63, +0x58, 0x35, 0x6c, 0x34, 0x86, 0xc2, 0x08, 0xc6, +0x58, 0x47, 0x8d, 0x71, 0xd3, 0x45, 0x4a, 0x04, +0xf0, 0x44, 0x2c, 0xab, 0xae, 0xf9, 0x00, 0xec, +0xde, 0xbd, 0x36, 0x82, 0x88, 0xa9, 0xb8, 0x91, +0x14, 0x66, 0xd7, 0x67, 0xad, 0x1e, 0xe1, 0x91, +0x0b, 0x64, 0x79, 0xc6, 0x28, 0x4d, 0x19, 0xa5, +0x29, 0x83, 0xfe, 0x80, 0x9d, 0xf5, 0x65, 0xfa, +0x37, 0x9f, 0x65, 0x22, 0xb9, 0xc0, 0x99, 0xa3, +0x23, 0x8e, 0x9f, 0x69, 0x31, 0x35, 0x1d, 0x12, +0x03, 0xde, 0x20, 0xb7, 0xb2, 0x5e, 0xc4, 0x46, +0x57, 0xb7, 0x33, 0xdb, 0x04, 0xda, 0x88, 0xf3, +0xb2, 0xba, 0xe9, 0x03, 0x75, 0xe5, 0xdf, 0x53, +0xc8, 0xc9, 0x16, 0x2c, 0x0e, 0x39, 0x35, 0x17, +0xb6, 0xe3, 0x86, 0x8e, 0x15, 0x68, 0xa5, 0xe4, +0x8e, 0xa6, 0xee, 0x2e, 0x04, 0xd0, 0x9e, 0x87, +0xde, 0x9d, 0x0e, 0xe5, 0x19, 0xa1, 0x95, 0x15, +0x32, 0xf5, 0xfc, 0xc2, 0x88, 0xbf, 0xfa, 0xda, +0x0e, 0x7f, 0xf6, 0x52, 0x9f, 0xab, 0x1b, 0x82, +0xe7, 0xcf, 0x11, 0xc7, 0x13, 0x88, 0x64, 0x8c, +0x86, 0x2b, 0x64, 0x79, 0x8f, 0x3b, 0x51, 0xfd, +0xed, 0xd6, 0xea, 0xda, 0x3a, 0x5a, 0x29, 0xe2, +0xb8, 0xe1, 0x3a, 0x89, 0x8e, 0x98, 0x0f, 0x0a, +0xde, 0xf2, 0xe8, 0x14, 0x27, 0xe7, 0x6d, 0xbf, +0xa0, 0xeb, 0xeb, 0x97, 0xb8, 0xb8, 0xbc, 0xc0, +0xda, 0xe6, 0x49, 0x82, 0x89, 0x93, 0xc4, 0xad, +0x0e, 0xa8, 0x71, 0x99, 0x94, 0xd3, 0x72, 0xf6, +0x7c, 0xb3, 0x2d, 0x9e, 0xb8, 0xb9, 0xb4, 0xc4, +0xcd, 0xa5, 0x25, 0x82, 0x20, 0xa2, 0xd3, 0x6e, +0x73, 0xe8, 0xe0, 0x3c, 0xf3, 0x07, 0xe7, 0x99, +0x99, 0x9e, 0x66, 0x72, 0x72, 0x82, 0xb8, 0xd1, +0xb0, 0xdd, 0xbb, 0xc4, 0xd6, 0xda, 0x55, 0xe2, +0xa5, 0x04, 0xaa, 0x7b, 0x2d, 0xce, 0xae, 0x2f, +0x9f, 0xb9, 0x88, 0xb8, 0xc6, 0x4e, 0x0a, 0xa3, +0x5c, 0x2b, 0x65, 0x17, 0xb7, 0x10, 0xe7, 0x17, +0x29, 0x7b, 0x1f, 0xa5, 0x79, 0xce, 0x28, 0xcd, +0x18, 0x0e, 0x47, 0x6c, 0xae, 0xad, 0xb0, 0x71, +0xfd, 0x19, 0x9a, 0xc3, 0xe7, 0x38, 0x77, 0xa0, +0xcb, 0xf1, 0x93, 0x11, 0x73, 0xb3, 0x13, 0xb4, +0x3d, 0x45, 0xe0, 0x72, 0x2d, 0x15, 0x62, 0xd3, +0xec, 0x47, 0x39, 0x74, 0x33, 0x24, 0xdd, 0x73, +0x6f, 0x22, 0xb6, 0x20, 0xa7, 0xba, 0x53, 0x90, +0x23, 0xb1, 0xf5, 0xcc, 0x2e, 0x0e, 0x89, 0x02, +0x1d, 0x68, 0xa5, 0xfc, 0x2c, 0xbf, 0x73, 0xa7, +0x70, 0x70, 0x08, 0xb0, 0x97, 0xea, 0xb1, 0xcc, +0x25, 0x04, 0x26, 0x80, 0x63, 0x83, 0xd4, 0x9c, +0xf9, 0x1f, 0x9f, 0x5a, 0x57, 0x5f, 0x7a, 0x79, +0xc0, 0xa8, 0x68, 0x12, 0x45, 0xb3, 0x68, 0x2f, +0x20, 0x4d, 0x4b, 0xaa, 0xbf, 0x55, 0xd6, 0xdf, +0xeb, 0x32, 0xc6, 0xb0, 0xb1, 0xb9, 0x49, 0x63, +0xd8, 0x70, 0x6c, 0x34, 0x27, 0xcb, 0x23, 0xe6, +0x26, 0x03, 0x0e, 0xce, 0x04, 0x34, 0x22, 0xcd, +0x81, 0x69, 0xe1, 0xf8, 0x7c, 0xc6, 0x95, 0x95, +0x8b, 0x5c, 0x5a, 0xb9, 0xc6, 0xda, 0xf6, 0x51, +0xbc, 0xd6, 0x71, 0xa2, 0xd6, 0x04, 0xca, 0xf3, +0xab, 0x0b, 0x66, 0x17, 0x2f, 0xa8, 0x2d, 0x65, +0x0b, 0x4d, 0x7b, 0xfd, 0x1e, 0xd7, 0x6f, 0x64, +0xac, 0xac, 0xad, 0xd1, 0x6a, 0xb5, 0xe8, 0xb4, +0xdb, 0x4c, 0x76, 0x3a, 0x74, 0x26, 0x26, 0x68, +0xb7, 0x5b, 0x34, 0xe3, 0x06, 0x41, 0x39, 0x65, +0xdc, 0xf3, 0xcb, 0x6e, 0xab, 0x8e, 0x0b, 0xe0, +0x14, 0x37, 0xa9, 0xbc, 0x8c, 0x76, 0x1e, 0x51, +0xd9, 0x13, 0x50, 0x91, 0xb9, 0xd6, 0xf5, 0xa9, +0xeb, 0x88, 0x62, 0x5b, 0xda, 0x27, 0xf4, 0x7a, +0x3d, 0x56, 0x97, 0x16, 0xd8, 0x58, 0x78, 0x16, +0x7f, 0xf0, 0x02, 0x67, 0xe6, 0x76, 0x38, 0xf9, +0x50, 0xc0, 0xdc, 0x74, 0x8b, 0xb6, 0xaf, 0x88, +0x72, 0x83, 0x97, 0xba, 0xc0, 0xbd, 0x88, 0xcd, +0xb8, 0x1e, 0xe4, 0x36, 0xdb, 0xda, 0x75, 0xff, +0x94, 0x32, 0x95, 0x41, 0xac, 0x22, 0xb8, 0x0b, +0xb0, 0x0d, 0x8d, 0x9c, 0x69, 0xa3, 0x2e, 0xf7, +0x50, 0x69, 0xc1, 0xec, 0x7c, 0xd4, 0x0a, 0x03, +0x15, 0x24, 0xb7, 0x1a, 0x09, 0xb7, 0x2c, 0x7f, +0x3f, 0xaa, 0x07, 0x9a, 0xc0, 0x1c, 0x70, 0x06, +0xf8, 0xf1, 0xc1, 0xc8, 0xfc, 0xe8, 0xa7, 0x5f, +0x48, 0xf0, 0x83, 0x39, 0x1a, 0x71, 0x07, 0x91, +0x9c, 0xc1, 0x60, 0x99, 0xfc, 0x1b, 0xa4, 0xfa, +0xbd, 0x2b, 0x49, 0x6d, 0x9d, 0x1b, 0x02, 0x81, +0x0f, 0x47, 0x66, 0xdb, 0x34, 0x1b, 0x9a, 0x28, +0xf2, 0x68, 0xc6, 0x9a, 0x38, 0x86, 0x76, 0xcb, +0x63, 0x7e, 0xc6, 0x70, 0xdf, 0xd1, 0x9c, 0xeb, +0xab, 0xaf, 0xf2, 0xda, 0xca, 0x35, 0x6e, 0xae, +0x1d, 0x20, 0x0f, 0x8e, 0x11, 0x34, 0xa7, 0xf1, +0xc3, 0x46, 0xa5, 0x75, 0xef, 0x42, 0x7b, 0x65, +0x3b, 0x74, 0xfa, 0x9e, 0x47, 0x14, 0x46, 0x84, +0xa1, 0x2d, 0xb1, 0x2a, 0x4d, 0xbe, 0xc2, 0xb5, +0x8a, 0xf7, 0x46, 0x8e, 0x7a, 0xb5, 0x47, 0xe4, +0x07, 0x84, 0xa1, 0x9d, 0xef, 0x17, 0xf8, 0xe5, +0x10, 0x29, 0x05, 0x1a, 0xd7, 0xd3, 0xa0, 0xf4, +0x25, 0x80, 0xc9, 0x0b, 0xb2, 0x3c, 0x67, 0x30, +0x1a, 0x61, 0x5c, 0x3f, 0xc4, 0x51, 0x92, 0x30, +0xe8, 0xf7, 0x59, 0x5d, 0x5e, 0x62, 0x79, 0xe1, +0x12, 0x3b, 0x2b, 0x17, 0x68, 0x73, 0x85, 0xb3, +0x07, 0x06, 0x1c, 0x79, 0x28, 0x60, 0x76, 0xa2, +0x49, 0xc7, 0x83, 0xc8, 0x08, 0x5e, 0x52, 0xf2, +0x0b, 0xac, 0x63, 0x67, 0x54, 0x58, 0x04, 0xa8, +0xf2, 0x2c, 0x19, 0xef, 0x73, 0xb1, 0x61, 0xdf, +0xda, 0xed, 0x89, 0x02, 0xf3, 0xc0, 0x84, 0xb5, +0x12, 0x16, 0x87, 0x63, 0x24, 0xb9, 0xc7, 0xe5, +0xd7, 0x80, 0xbf, 0x8b, 0xea, 0x81, 0x37, 0x02, +0xff, 0x18, 0xd4, 0xdb, 0x7c, 0xbf, 0xd3, 0x6e, +0x34, 0x66, 0x95, 0xd6, 0x3e, 0x59, 0xda, 0x65, +0x94, 0xac, 0xdf, 0xb3, 0xac, 0xbf, 0xd7, 0x55, +0xb8, 0xd2, 0xe7, 0x99, 0x96, 0xcf, 0xa3, 0x67, +0x9a, 0x74, 0x5a, 0x1e, 0x41, 0x30, 0x9e, 0xf4, +0xe5, 0xfb, 0xd0, 0x88, 0x35, 0x13, 0x1d, 0x9f, +0x83, 0xb3, 0x86, 0x07, 0x8e, 0x17, 0xac, 0x6c, +0x2f, 0x73, 0x7d, 0x75, 0x89, 0x6b, 0x1b, 0x2d, +0x36, 0xb6, 0xe7, 0x20, 0x9c, 0xc7, 0x6f, 0x4c, +0xba, 0xe9, 0xe1, 0xb6, 0x9b, 0xb9, 0xc6, 0x02, +0x3f, 0x0c, 0x42, 0xc2, 0x20, 0x24, 0x8a, 0x22, +0xeb, 0x44, 0x72, 0xa3, 0xdc, 0x1a, 0x71, 0x4c, +0x33, 0x8e, 0x6d, 0x9d, 0x62, 0x1c, 0x5b, 0x04, +0x09, 0x6d, 0x27, 0xb3, 0xa0, 0x4a, 0x62, 0xf5, +0xaa, 0x8a, 0x5b, 0xed, 0x86, 0x4e, 0x8a, 0x08, +0xc6, 0xe5, 0xf0, 0x0f, 0x47, 0x23, 0xab, 0xc0, +0x6e, 0x6f, 0xb3, 0xbe, 0xba, 0xcc, 0x8d, 0x6b, +0x97, 0x58, 0x5d, 0xb8, 0x80, 0x1a, 0xbe, 0xc2, +0x5c, 0x7b, 0x8d, 0xb3, 0xa7, 0x15, 0xf3, 0xd3, +0x01, 0x93, 0x8d, 0x98, 0xa6, 0x12, 0x42, 0x23, +0xe8, 0x9c, 0xf1, 0xa0, 0x87, 0x42, 0x6c, 0x5a, +0x7d, 0xe6, 0x58, 0x7f, 0xb5, 0x5c, 0xce, 0x84, +0x11, 0x54, 0x62, 0x9c, 0x02, 0x38, 0x5e, 0x02, +0xc8, 0xe1, 0x06, 0xcc, 0x37, 0x50, 0x4f, 0x6f, +0xa0, 0x72, 0x41, 0x42, 0xcd, 0x4e, 0xbf, 0x18, +0xe5, 0xb9, 0xe4, 0x4a, 0xdd, 0x9d, 0x3a, 0x4b, +0xe8, 0x97, 0x54, 0x3f, 0x03, 0xdc, 0x07, 0xfc, +0x18, 0xf0, 0x0f, 0xb5, 0x0a, 0x4f, 0x44, 0xd1, +0x8c, 0x17, 0x86, 0x1d, 0x65, 0x4c, 0xce, 0x70, +0xb8, 0x4c, 0x96, 0x7d, 0x6b, 0xa8, 0xfe, 0xd6, +0x25, 0xcc, 0x74, 0x3c, 0x7e, 0xea, 0xcd, 0x53, +0x9c, 0x3f, 0x1c, 0x31, 0xa9, 0x21, 0x2c, 0xc4, +0x3e, 0x1c, 0xe7, 0xaf, 0xf4, 0x94, 0x42, 0xfb, +0x10, 0x06, 0x1e, 0xed, 0xa6, 0xc7, 0xec, 0x74, +0xc0, 0xc9, 0xc3, 0x86, 0xcd, 0x5e, 0xca, 0xca, +0xe6, 0x35, 0x16, 0x37, 0xae, 0xb1, 0xb2, 0xd3, +0x60, 0xb3, 0x37, 0x49, 0xa6, 0x67, 0xd1, 0xe1, +0x2c, 0x8d, 0xb8, 0x43, 0x14, 0xb4, 0x08, 0xa3, +0xa8, 0xda, 0x5a, 0x71, 0x4c, 0x14, 0x45, 0xc4, +0x0e, 0xf0, 0x8d, 0x46, 0x83, 0x46, 0x1c, 0x13, +0x46, 0x21, 0x51, 0x18, 0x11, 0x78, 0xbe, 0x4d, +0xe0, 0xac, 0x32, 0x98, 0xa9, 0x38, 0x89, 0x65, +0xf7, 0x42, 0x51, 0xe4, 0x74, 0x77, 0x6c, 0xb4, +0x72, 0xe9, 0xc6, 0x35, 0x6e, 0x5e, 0x7f, 0x89, +0x8d, 0xe5, 0x97, 0xd0, 0xe9, 0x35, 0xa6, 0xe2, +0x6d, 0x1e, 0x3e, 0x20, 0xcc, 0x4d, 0x6a, 0xa6, +0xe2, 0x90, 0xb6, 0x07, 0x0d, 0xc0, 0x2f, 0xcc, +0x38, 0x29, 0x54, 0x6c, 0x74, 0x50, 0x19, 0xb1, +0xdd, 0x55, 0x4a, 0x47, 0x9d, 0xda, 0xb3, 0x15, +0x4e, 0x1c, 0xe4, 0xfb, 0x68, 0xfd, 0x1d, 0x1f, +0x39, 0x37, 0x09, 0x57, 0x7a, 0xa8, 0x2d, 0x1b, +0x40, 0x22, 0x50, 0x74, 0x87, 0xc5, 0x30, 0x2f, +0x24, 0xf1, 0xb5, 0x92, 0xf4, 0x2e, 0xb0, 0xf2, +0x81, 0x08, 0x98, 0x02, 0x8e, 0x60, 0xa9, 0xfe, +0x1f, 0x81, 0x7a, 0x47, 0xe0, 0x77, 0xda, 0x8d, +0xc6, 0x4c, 0x4d, 0xc3, 0xdf, 0xc4, 0x98, 0xf4, +0x5b, 0x00, 0xe8, 0x5b, 0x97, 0xd6, 0xc2, 0x83, +0x27, 0x9b, 0xfc, 0xf4, 0x3b, 0x67, 0x79, 0xdb, +0x03, 0x2d, 0x4e, 0xcc, 0x04, 0x36, 0xd3, 0xb5, +0x30, 0x30, 0xb2, 0xe1, 0x65, 0x3c, 0x0d, 0x1e, +0x36, 0x04, 0xaa, 0x15, 0xa1, 0x86, 0x20, 0x54, +0xb4, 0x42, 0x9f, 0xa9, 0x96, 0xc7, 0x91, 0xb9, +0x80, 0xb3, 0xa9, 0xd0, 0x1b, 0x15, 0x6c, 0xf6, +0x56, 0x59, 0xdd, 0x5e, 0x66, 0x7d, 0x5b, 0xb3, +0x3d, 0x6c, 0x30, 0x58, 0x9f, 0x60, 0xb0, 0x3e, +0x49, 0xd4, 0x9c, 0x23, 0x6e, 0xcf, 0x90, 0x4f, +0x1e, 0x20, 0x9f, 0x98, 0x41, 0x8c, 0xc1, 0xd3, +0x8a, 0x28, 0x0a, 0xc9, 0x8b, 0x1c, 0x2f, 0xf7, +0x49, 0x49, 0x90, 0x22, 0x27, 0xcf, 0xb4, 0x4b, +0xda, 0x48, 0xc9, 0xf3, 0x9c, 0x24, 0x4d, 0x19, +0x0d, 0x7a, 0xac, 0xaf, 0xdd, 0x60, 0x6b, 0xed, +0x06, 0x5b, 0x6b, 0x0b, 0x24, 0xfd, 0x45, 0x24, +0x5d, 0xa2, 0xa1, 0xb7, 0x99, 0x99, 0x28, 0x38, +0x7d, 0x14, 0x26, 0x5b, 0x9a, 0x4e, 0xe8, 0xd1, +0xf2, 0x14, 0x91, 0xb2, 0x99, 0x73, 0x1e, 0xfb, +0x04, 0x9d, 0x4a, 0xed, 0xd5, 0xcd, 0x15, 0xaa, +0xd2, 0xa2, 0x64, 0x0c, 0x61, 0x19, 0xe6, 0x55, +0x9e, 0x85, 0xd2, 0x2e, 0xb6, 0xae, 0xc5, 0x8e, +0x07, 0x6a, 0x68, 0xe4, 0x91, 0x69, 0xd8, 0xc9, +0xd0, 0x57, 0x7a, 0xe3, 0xc6, 0x10, 0x81, 0x96, +0xcb, 0xd7, 0x87, 0xdb, 0xc3, 0xc4, 0x0c, 0x03, +0x5f, 0x19, 0x91, 0xbb, 0x9b, 0x81, 0x47, 0x81, +0xb3, 0xc0, 0x8f, 0x00, 0x3f, 0xa5, 0x75, 0x78, +0xbc, 0x11, 0xcd, 0xe8, 0xc0, 0xef, 0x60, 0xbe, +0xc5, 0xb2, 0xfe, 0xd6, 0x25, 0x34, 0x22, 0xcd, +0xdb, 0xbf, 0x67, 0x92, 0x9f, 0x79, 0xf7, 0x3c, +0xaf, 0x3f, 0xdb, 0x62, 0x7e, 0x26, 0xa4, 0xdd, +0xd0, 0x78, 0xb9, 0x41, 0x86, 0x85, 0xcd, 0x76, +0x29, 0x04, 0x8c, 0x41, 0x65, 0x50, 0x25, 0xa4, +0x78, 0x0a, 0xe5, 0x29, 0xb4, 0xa7, 0xf0, 0x94, +0x22, 0xf2, 0x15, 0x6d, 0x5f, 0x31, 0x1b, 0x6b, +0x8e, 0x4c, 0xfa, 0xa4, 0x07, 0x85, 0x51, 0x6e, +0x18, 0xa6, 0x19, 0xfd, 0x64, 0x95, 0xde, 0x68, +0x99, 0x9d, 0xfe, 0x25, 0x7a, 0x23, 0xe8, 0x2f, +0xc3, 0xda, 0x8d, 0x90, 0x15, 0x62, 0x0a, 0x9a, +0x78, 0x7e, 0x84, 0x51, 0x21, 0x60, 0x15, 0x61, +0x9b, 0xd8, 0x64, 0x50, 0xa4, 0x98, 0x22, 0xc5, +0x93, 0x21, 0xda, 0x0c, 0xf0, 0xf5, 0x88, 0x38, +0x32, 0x74, 0x9a, 0xc2, 0x99, 0x26, 0x74, 0x66, +0x14, 0x71, 0xa8, 0x88, 0x7d, 0x4d, 0xec, 0xf9, +0x84, 0x4a, 0x11, 0x60, 0xe3, 0x64, 0xd6, 0x8b, +0xec, 0x52, 0xcd, 0xdc, 0xb1, 0xbd, 0x65, 0xc7, +0xe6, 0x1d, 0x85, 0x8b, 0xcb, 0x9d, 0xd9, 0x95, +0xa0, 0x9c, 0x1a, 0xe8, 0xb9, 0xe2, 0x1b, 0x07, +0x78, 0xd7, 0xaf, 0xc1, 0x5a, 0x18, 0xb1, 0x42, +0x5e, 0x3f, 0x0d, 0x80, 0x7e, 0x7e, 0x0b, 0x55, +0x8e, 0x89, 0x07, 0x57, 0x19, 0x9c, 0x2d, 0x19, +0x61, 0x18, 0x78, 0xaa, 0x48, 0xee, 0x52, 0x1f, +0xe4, 0x03, 0x3f, 0x04, 0xfc, 0x0c, 0xa8, 0xb7, +0x86, 0x41, 0xa7, 0x15, 0x45, 0x4e, 0xd6, 0x67, +0x3d, 0x92, 0xd1, 0x3a, 0xe6, 0xeb, 0xd0, 0xf0, +0x2b, 0xc7, 0xc3, 0xbd, 0x7c, 0x56, 0x09, 0x87, +0x66, 0x43, 0x7e, 0xe2, 0xed, 0x33, 0xfc, 0xe8, +0x5b, 0x67, 0xb8, 0xef, 0x64, 0xcc, 0xcc, 0x74, +0x40, 0xdc, 0xf0, 0xd0, 0xbe, 0x02, 0xed, 0x23, +0xd3, 0xd8, 0x6e, 0xe4, 0x99, 0x81, 0xa4, 0x40, +0x0d, 0x0a, 0xc8, 0x5c, 0x59, 0x5a, 0x5a, 0x2a, +0x43, 0x56, 0x39, 0x53, 0xda, 0xb6, 0x34, 0xf5, +0x34, 0x04, 0x9e, 0x22, 0x0e, 0x14, 0x13, 0xa1, +0x87, 0x89, 0x6d, 0x67, 0xbb, 0xdc, 0x08, 0x79, +0x21, 0x64, 0x85, 0xed, 0x62, 0x96, 0xe5, 0x05, +0xb9, 0xe9, 0x92, 0x17, 0x5d, 0x8a, 0x02, 0x8a, +0x9a, 0x3f, 0xc1, 0x3a, 0x7c, 0x5c, 0xd3, 0x06, +0x0d, 0xbe, 0xb6, 0x43, 0x9c, 0x03, 0x0d, 0xbe, +0xb2, 0xd3, 0x39, 0x02, 0x47, 0xd9, 0xbe, 0x43, +0x18, 0xa5, 0x41, 0x79, 0xd4, 0x90, 0xb3, 0x6c, +0x19, 0x2f, 0x2e, 0x2b, 0xc6, 0x29, 0x76, 0x7b, +0x29, 0xbe, 0xfe, 0xb4, 0x52, 0x83, 0xf4, 0x33, +0x7b, 0xbf, 0x9e, 0xaa, 0x71, 0x09, 0x01, 0x63, +0xfb, 0x0b, 0x49, 0xa4, 0x91, 0xd7, 0x4d, 0x41, +0xd3, 0x47, 0xff, 0xf5, 0xba, 0x6d, 0xc7, 0x53, +0x5b, 0xd2, 0xf4, 0xe4, 0x85, 0x2b, 0xc3, 0x8b, +0x40, 0x3f, 0x77, 0xad, 0xd9, 0xee, 0x04, 0x0f, +0x1f, 0xf8, 0x05, 0xad, 0xc2, 0x53, 0x51, 0x34, +0xab, 0xc3, 0xb0, 0x83, 0x95, 0xf5, 0xab, 0x64, +0xd9, 0xce, 0x1d, 0xff, 0xb5, 0x44, 0x68, 0xfb, +0x90, 0x74, 0x15, 0x5d, 0x13, 0x71, 0xf6, 0xb3, +0x31, 0xb7, 0x2d, 0x4c, 0xf7, 0x35, 0x9c, 0x3f, +0x16, 0xf3, 0xbe, 0x77, 0xcd, 0xf1, 0x96, 0x47, +0xa7, 0x38, 0x76, 0x38, 0x62, 0x62, 0x32, 0x20, +0x0c, 0x35, 0xca, 0x73, 0x24, 0x51, 0x3e, 0x20, +0x5f, 0x41, 0xe8, 0x21, 0x13, 0xa1, 0x9b, 0x45, +0xe8, 0xfc, 0xe1, 0x59, 0x81, 0x4a, 0x8c, 0x0d, +0x8d, 0x66, 0x06, 0x55, 0xea, 0x0b, 0x99, 0xa0, +0xcb, 0xa6, 0x18, 0x16, 0x16, 0x36, 0x7b, 0xbd, +0xd4, 0x88, 0x3c, 0x10, 0x0d, 0x12, 0x68, 0xca, +0x5e, 0x17, 0xb7, 0x18, 0x8f, 0x0e, 0x01, 0x90, +0xb1, 0xc3, 0xad, 0xcc, 0x72, 0x53, 0x5a, 0xd9, +0xa6, 0x8e, 0x0e, 0xd0, 0xf8, 0xca, 0x4e, 0xe8, +0xf0, 0x94, 0x6b, 0x10, 0xe8, 0xbe, 0xa8, 0xc0, +0x71, 0x2e, 0x07, 0xc0, 0xbd, 0xb2, 0xbd, 0xf6, +0x68, 0x25, 0x75, 0xd3, 0x3e, 0x32, 0xdb, 0x52, +0x47, 0x02, 0xed, 0x90, 0xa6, 0xbc, 0x2a, 0x65, +0xe7, 0x0c, 0x84, 0x1e, 0xf2, 0xd0, 0x24, 0x34, +0x7d, 0xd4, 0x33, 0x1b, 0xd6, 0x39, 0xb4, 0xeb, +0xc1, 0x2a, 0x06, 0x4a, 0xf5, 0xbf, 0xf8, 0x7c, +0xf7, 0xa2, 0xef, 0x31, 0x54, 0xae, 0x19, 0x39, +0x77, 0x18, 0x1b, 0xe2, 0x87, 0xc1, 0xc4, 0x99, +0x28, 0xb2, 0xde, 0xbc, 0x3c, 0xef, 0x91, 0x24, +0xeb, 0x14, 0x45, 0xba, 0x0b, 0xc8, 0xf6, 0x01, +0xec, 0x8e, 0xa3, 0x6b, 0x37, 0xa6, 0xcd, 0x06, +0x5f, 0xc6, 0x8d, 0x0b, 0x4a, 0x97, 0x6a, 0xe9, +0x1d, 0x2b, 0xbf, 0xa7, 0xe4, 0x42, 0x13, 0x0d, +0xcd, 0x0f, 0x9c, 0x8b, 0x79, 0xef, 0x9b, 0x26, +0x79, 0xe8, 0x48, 0xc4, 0x01, 0x5f, 0x68, 0x7a, +0x56, 0xc4, 0x2b, 0x5d, 0xb3, 0x77, 0x6b, 0x4f, +0x5d, 0xf4, 0xf8, 0x3d, 0xf1, 0x35, 0x44, 0x0a, +0x74, 0x60, 0x11, 0xa2, 0x2c, 0x7c, 0xca, 0x5d, +0x62, 0x64, 0xe1, 0xb4, 0xe9, 0x14, 0x54, 0xa6, +0x5c, 0xc2, 0xa4, 0x41, 0x15, 0xc6, 0x4d, 0xeb, +0x30, 0x95, 0xbd, 0xed, 0x95, 0x60, 0x57, 0x25, +0xa9, 0x39, 0x6f, 0x42, 0xf9, 0x7b, 0xbe, 0x46, +0x3c, 0x85, 0xf8, 0xca, 0x3a, 0x59, 0x3c, 0x85, +0xb8, 0xa4, 0xd7, 0xaa, 0x1f, 0xb0, 0xf3, 0x08, +0x62, 0xac, 0x6c, 0x2e, 0x27, 0x82, 0x8c, 0x31, +0xa7, 0x0e, 0xf0, 0x1a, 0xf5, 0x1b, 0xb1, 0x19, +0xbc, 0xa5, 0x82, 0xa7, 0x95, 0x1d, 0xc7, 0x27, +0x52, 0x8d, 0x9e, 0x41, 0x63, 0x1f, 0x88, 0x08, +0xc4, 0x3e, 0xf2, 0xe0, 0xa4, 0x9d, 0x12, 0xfe, +0xec, 0x26, 0x6a, 0x6b, 0x1f, 0x23, 0xbf, 0xed, +0xcb, 0xc5, 0xc5, 0xd1, 0xd5, 0xad, 0x5e, 0x7e, +0xc3, 0xd3, 0x6a, 0x94, 0x66, 0x77, 0x8e, 0x04, +0x02, 0xf8, 0x71, 0xf3, 0x10, 0x62, 0x0a, 0x92, +0x64, 0x8d, 0x3c, 0xdb, 0xb6, 0x2e, 0x50, 0x5d, +0x4f, 0x80, 0xb4, 0x17, 0x3e, 0xde, 0xab, 0x6a, +0x3e, 0x9f, 0xe7, 0x8a, 0x1c, 0x6d, 0x8c, 0xbc, +0xc0, 0x94, 0xbe, 0x70, 0xa5, 0xaa, 0x66, 0xc8, +0x15, 0x12, 0x29, 0x38, 0x3a, 0xe5, 0xf1, 0x93, +0x8f, 0xb6, 0xf8, 0xa1, 0x87, 0xda, 0x9c, 0x9e, +0x0f, 0x99, 0x6a, 0xfb, 0x34, 0x3c, 0x85, 0x5e, +0x1d, 0xc1, 0x66, 0x8a, 0x4c, 0x06, 0x30, 0x15, +0xd8, 0xd6, 0xf3, 0xe5, 0xf4, 0x8b, 0x8a, 0x55, +0x2a, 0xc6, 0x64, 0xe8, 0xb6, 0x52, 0xb6, 0x6a, +0x65, 0x1d, 0x08, 0x0a, 0x44, 0x2b, 0x50, 0x21, +0xa8, 0x18, 0x08, 0x11, 0x27, 0xdb, 0x51, 0xba, +0xd2, 0x25, 0xc0, 0x80, 0x14, 0x40, 0x06, 0x92, +0x22, 0x24, 0x20, 0x23, 0x70, 0xd9, 0x38, 0x68, +0xfb, 0x91, 0x8a, 0x45, 0x54, 0x00, 0x16, 0xcb, +0x69, 0xca, 0xe3, 0x92, 0xb0, 0xca, 0x39, 0xb9, +0x35, 0xa0, 0x4b, 0x75, 0xd9, 0x8e, 0x2b, 0x38, +0x87, 0x12, 0x69, 0x61, 0x29, 0x37, 0x29, 0x5c, +0x53, 0x0d, 0x8d, 0x0a, 0x1c, 0x22, 0x39, 0x56, +0x8f, 0x12, 0x54, 0xc9, 0xf2, 0x15, 0x30, 0x15, +0x21, 0xf7, 0x4f, 0x40, 0x56, 0xa0, 0xbf, 0xba, +0x81, 0xea, 0xde, 0xc6, 0x04, 0x9f, 0x0e, 0xf8, +0xf8, 0x5f, 0xac, 0x3e, 0xd5, 0x1d, 0x98, 0xa5, +0x89, 0xa6, 0x4e, 0x93, 0x6c, 0xdc, 0x64, 0xf3, +0xb6, 0x08, 0x60, 0x8a, 0x01, 0x59, 0xba, 0x89, +0x31, 0x89, 0x6b, 0xea, 0x34, 0xae, 0xa0, 0x19, +0xa7, 0x52, 0xd9, 0x63, 0xad, 0x35, 0x41, 0x10, +0xb8, 0x8e, 0x5f, 0xd6, 0xce, 0x16, 0x67, 0xce, +0x18, 0xe3, 0x91, 0xab, 0xbc, 0xea, 0xcd, 0x23, +0x32, 0xee, 0x2c, 0x17, 0x68, 0x78, 0xdd, 0xd1, +0x80, 0x9f, 0x7a, 0x43, 0x93, 0x37, 0x9e, 0x8a, +0x39, 0x36, 0x1b, 0x32, 0xd1, 0xd4, 0xf8, 0xbe, +0xcd, 0xa1, 0xaf, 0xa8, 0x64, 0x3b, 0x83, 0xad, +0x14, 0x15, 0x6a, 0x64, 0x2a, 0xb2, 0x08, 0x11, +0xfb, 0x96, 0xbd, 0xaa, 0xbd, 0xdc, 0x81, 0x3d, +0x08, 0x51, 0xbe, 0x0e, 0x41, 0x35, 0x51, 0xaa, +0x01, 0x34, 0xec, 0x6b, 0x7c, 0x50, 0xbe, 0x15, +0x27, 0x36, 0x54, 0x87, 0xf5, 0xa5, 0x66, 0x20, +0x09, 0x4a, 0x02, 0x44, 0x3c, 0x90, 0xa1, 0x3d, +0x67, 0x6a, 0xbc, 0xbf, 0xc4, 0xde, 0x5b, 0x7e, +0xbb, 0x6e, 0x96, 0x39, 0xe0, 0xef, 0xa5, 0x72, +0xb0, 0x48, 0x97, 0x16, 0x36, 0x98, 0x33, 0x2c, +0xaa, 0xf4, 0x79, 0xe5, 0x97, 0x13, 0x3f, 0x4b, +0xe0, 0x2b, 0xd7, 0x71, 0xc5, 0x5d, 0xa2, 0x16, +0xab, 0x49, 0x1e, 0x8a, 0x91, 0x63, 0x4d, 0xd8, +0x4c, 0x50, 0x17, 0xbb, 0xf6, 0x3b, 0xf6, 0x13, +0x23, 0x0d, 0x4d, 0xdf, 0xd3, 0x83, 0x3f, 0xff, +0xe2, 0xe6, 0xe7, 0xb4, 0x62, 0xcb, 0x88, 0x75, +0x16, 0xdf, 0x2d, 0xe3, 0xc9, 0xcf, 0xb3, 0x35, +0x94, 0x32, 0xbb, 0x4a, 0x98, 0x94, 0x73, 0x40, +0xd4, 0x5f, 0x7b, 0xbe, 0x4f, 0x23, 0x8a, 0x1c, +0xe5, 0x7b, 0x55, 0x50, 0xa6, 0x4c, 0x92, 0x00, +0x1c, 0x52, 0x80, 0x32, 0x95, 0x7a, 0xc6, 0x54, +0x4b, 0xf1, 0xce, 0xf3, 0x11, 0xef, 0x3e, 0xd7, +0xe0, 0xec, 0xc1, 0x88, 0xb9, 0x8e, 0x4f, 0xb3, +0xa1, 0x1d, 0xb2, 0xa9, 0x5d, 0xc0, 0x54, 0xbe, +0x1a, 0x13, 0xfb, 0x46, 0x82, 0xac, 0x8f, 0x90, +0xd0, 0x83, 0x76, 0x80, 0x4c, 0x06, 0xa8, 0x76, +0x88, 0x44, 0x7a, 0x2c, 0x6b, 0x15, 0xe3, 0x29, +0x0b, 0x4a, 0x81, 0xf6, 0x41, 0x35, 0x1c, 0xf0, +0x63, 0x50, 0x0d, 0x50, 0x11, 0x10, 0xa0, 0xac, +0x31, 0xe6, 0x80, 0x63, 0x10, 0x72, 0x90, 0xcc, +0x69, 0x6e, 0xe5, 0xd3, 0x34, 0xc0, 0xc8, 0x02, +0xb3, 0x34, 0xbb, 0xa8, 0x01, 0xbb, 0xbc, 0xa9, +0x0a, 0xd9, 0xf6, 0xb0, 0x79, 0xb0, 0xc8, 0x93, +0x16, 0x16, 0x50, 0x83, 0xc2, 0x9a, 0x71, 0x6e, +0x12, 0x08, 0xbe, 0x1e, 0xe7, 0x60, 0x95, 0xba, +0x41, 0xf5, 0xa5, 0xee, 0x37, 0x8d, 0x58, 0x4d, +0xbf, 0xe5, 0x23, 0xc7, 0x9b, 0xd0, 0x09, 0x60, +0x61, 0x80, 0xbe, 0xde, 0x77, 0x73, 0x19, 0xc6, +0x12, 0xa6, 0x02, 0x3e, 0x20, 0x33, 0xa1, 0x7c, +0xfa, 0xb9, 0xee, 0xb3, 0xaf, 0xdc, 0x18, 0xbd, +0xd0, 0x08, 0x75, 0x2f, 0xc9, 0x2c, 0xe9, 0xdf, +0x2e, 0x13, 0xa8, 0x42, 0x00, 0x0b, 0x08, 0x9b, +0x8b, 0x57, 0x76, 0xc1, 0x2e, 0x29, 0xbf, 0x0c, +0x9b, 0x46, 0x51, 0x48, 0x23, 0x2a, 0xfd, 0xe4, +0xe5, 0xc4, 0x0b, 0x57, 0xe1, 0x52, 0xe4, 0x88, +0x28, 0x44, 0xac, 0xdd, 0xec, 0x6b, 0xec, 0x30, +0x66, 0x0d, 0x47, 0xa6, 0xe0, 0x3d, 0x6f, 0x88, +0x78, 0xfb, 0x23, 0x2d, 0x4e, 0xce, 0x47, 0x4c, +0x2a, 0x88, 0xc4, 0x12, 0xf4, 0x98, 0x85, 0xbb, +0x07, 0xa0, 0x6b, 0x7b, 0x85, 0x65, 0x8d, 0xa5, +0xf8, 0xe8, 0x67, 0xb0, 0x93, 0x22, 0x6a, 0x00, +0x91, 0x46, 0x62, 0x1f, 0x99, 0x0c, 0x91, 0x4e, +0x00, 0x91, 0x67, 0x1b, 0x56, 0x7a, 0x0a, 0x08, +0x51, 0x44, 0x58, 0xca, 0xb7, 0x9b, 0x22, 0x02, +0x15, 0xa0, 0xec, 0x74, 0x2b, 0x77, 0xdb, 0x05, +0x48, 0x8e, 0x28, 0xaf, 0x7a, 0x9a, 0x8a, 0x02, +0xdb, 0x0d, 0x27, 0x73, 0xd4, 0xbc, 0xdb, 0xf1, +0x62, 0x2f, 0xc4, 0xc9, 0xff, 0xf2, 0xb1, 0x3b, +0x0f, 0x9e, 0x4a, 0x0d, 0x32, 0xb0, 0x45, 0x99, +0x24, 0x06, 0x95, 0x5b, 0x3b, 0x4f, 0x69, 0x6c, +0xc1, 0xa6, 0xe8, 0x1a, 0xa5, 0x53, 0xd9, 0xf3, +0x96, 0xea, 0xc7, 0x48, 0x20, 0x08, 0x84, 0x1a, +0x33, 0x1b, 0xc1, 0xe1, 0xd8, 0x7e, 0xf7, 0x4b, +0xdb, 0xa8, 0xcd, 0xb4, 0xf6, 0x39, 0x87, 0x64, +0x32, 0x06, 0x3e, 0x91, 0x26, 0xeb, 0x04, 0xd9, +0x07, 0x3e, 0x7e, 0xed, 0xcf, 0x92, 0x4c, 0x6e, +0xcc, 0x74, 0x74, 0x32, 0xec, 0x72, 0x4f, 0x99, +0xcc, 0xbe, 0xe7, 0xf9, 0x4e, 0x8c, 0x8e, 0xeb, +0xd8, 0x4a, 0x04, 0xb0, 0x03, 0x8c, 0x1a, 0x44, +0x8d, 0x68, 0x9c, 0x50, 0xe9, 0x6e, 0xa4, 0x28, +0x0a, 0x32, 0x11, 0xb4, 0xd2, 0x18, 0x65, 0xe3, +0xdd, 0x9e, 0xd6, 0xa0, 0x35, 0x51, 0x00, 0x0f, +0x1f, 0x81, 0xf7, 0x3c, 0x1a, 0xf1, 0xc8, 0xa9, +0x06, 0x47, 0x66, 0x43, 0xda, 0x6d, 0x9f, 0xa0, +0xa1, 0x51, 0x99, 0x20, 0xa3, 0xc2, 0xca, 0xd2, +0x3d, 0x1c, 0xa0, 0x7e, 0x2c, 0xbb, 0xde, 0x57, +0x56, 0x8c, 0x3b, 0xd5, 0x5c, 0xf5, 0x33, 0x37, +0xb0, 0xca, 0x61, 0x53, 0xe8, 0x21, 0x0d, 0x1f, +0xe2, 0x04, 0x9a, 0x19, 0x12, 0x0b, 0x34, 0xb4, +0xcd, 0x69, 0xf0, 0x02, 0x0b, 0x08, 0xcf, 0xb7, +0xd4, 0xee, 0xf9, 0x20, 0x39, 0x4a, 0xa5, 0x20, +0x0a, 0x51, 0xa5, 0x48, 0xc8, 0x50, 0x64, 0x08, +0x01, 0x98, 0xcc, 0x3e, 0x64, 0xa7, 0x58, 0x52, +0x18, 0x54, 0x66, 0x90, 0xc4, 0xa0, 0x47, 0xd6, +0x39, 0xa3, 0x46, 0xd6, 0x24, 0xa5, 0xb0, 0x7a, +0x81, 0xf6, 0xb0, 0x4a, 0x69, 0xe0, 0xf4, 0x11, +0x71, 0x4a, 0x61, 0x09, 0x30, 0x85, 0x95, 0xef, +0x63, 0xb6, 0xc2, 0x2e, 0xaa, 0xd7, 0x20, 0xed, +0x10, 0x39, 0x1c, 0xdb, 0xa2, 0x9b, 0x95, 0x04, +0xbd, 0x38, 0x40, 0x8d, 0x0a, 0xf7, 0x1f, 0x0a, +0x94, 0xb1, 0xe9, 0x60, 0x7b, 0xc4, 0xba, 0xcc, +0x47, 0xf2, 0xd9, 0xe7, 0xbb, 0x4f, 0x7f, 0xfe, +0x42, 0xf7, 0xf3, 0x71, 0xa4, 0x37, 0x87, 0x89, +0xb1, 0xad, 0x3a, 0xee, 0x42, 0xfd, 0x00, 0xbe, +0xef, 0x59, 0x3f, 0x77, 0xd5, 0xee, 0xdc, 0xe5, +0xc2, 0x45, 0x61, 0x44, 0xd3, 0xf9, 0xcb, 0xcb, +0x61, 0x0b, 0x65, 0x2a, 0x53, 0x5e, 0xe4, 0x88, +0xcb, 0x0e, 0x2f, 0x31, 0xcc, 0x02, 0x1f, 0xa6, +0x1b, 0x86, 0x77, 0x3e, 0xa4, 0x79, 0xe7, 0xf9, +0x06, 0xa7, 0x0f, 0x45, 0xcc, 0x4c, 0xfa, 0xc4, +0x0d, 0x0f, 0xcf, 0xc3, 0x3e, 0x4c, 0x5f, 0xc1, +0x84, 0x5f, 0x95, 0x8e, 0x55, 0x72, 0xb3, 0xc6, +0xca, 0x65, 0x1f, 0x84, 0xd8, 0x25, 0x8f, 0xbd, +0xf1, 0x50, 0xa9, 0x8a, 0xab, 0x8f, 0x32, 0x18, +0x6e, 0xc1, 0xda, 0x16, 0x14, 0xd7, 0xed, 0x09, +0x2f, 0xb0, 0x9b, 0x0e, 0xc0, 0x6f, 0x38, 0x44, +0x6a, 0x38, 0x23, 0xb1, 0x40, 0x89, 0x41, 0x55, +0x7e, 0xd8, 0x02, 0xc8, 0x11, 0x29, 0x50, 0xb9, +0xa3, 0xb8, 0xd2, 0xb4, 0x2c, 0x5d, 0xb6, 0x8a, +0xb2, 0x17, 0xbc, 0x3d, 0x0e, 0x94, 0x55, 0x70, +0x4a, 0x1f, 0x42, 0x49, 0xdd, 0x22, 0xd5, 0x3d, +0x89, 0xc8, 0x2e, 0x2f, 0xde, 0x2d, 0x54, 0xaf, +0x41, 0xda, 0x3e, 0x32, 0x17, 0x59, 0x76, 0xdf, +0xcf, 0x51, 0x97, 0xba, 0xa8, 0x9d, 0x1c, 0x65, +0x4c, 0x4d, 0xbc, 0x88, 0xe5, 0x2e, 0x35, 0x98, +0x0a, 0x40, 0xc7, 0xa7, 0x17, 0x7a, 0xfd, 0xff, +0xf6, 0xc7, 0x37, 0xff, 0x60, 0x90, 0x98, 0x2b, +0x93, 0x2d, 0x3d, 0xd8, 0x19, 0x48, 0x15, 0xab, +0xb8, 0x2b, 0x02, 0x04, 0xe5, 0x80, 0x65, 0x57, +0x3e, 0xed, 0xfb, 0x3e, 0xcd, 0x66, 0x4c, 0x33, +0x6e, 0xda, 0xa8, 0x99, 0xb6, 0xb3, 0xf6, 0x4a, +0x96, 0x9f, 0x65, 0x59, 0x8d, 0x0b, 0x18, 0x67, +0x2d, 0x79, 0x68, 0x2d, 0x1c, 0x69, 0xe6, 0xbc, +0xfb, 0x94, 0xe1, 0xfb, 0xce, 0x46, 0x1c, 0x3f, +0x1a, 0x31, 0xd1, 0x09, 0x08, 0x23, 0x67, 0xdb, +0xd7, 0xbd, 0x61, 0x80, 0x34, 0x3c, 0x5b, 0x58, +0x92, 0x1a, 0xa4, 0x9c, 0x3b, 0x70, 0x1b, 0x6e, +0xb0, 0x3f, 0x22, 0xec, 0x83, 0x18, 0xec, 0x39, +0x8f, 0x80, 0xca, 0xac, 0xac, 0x97, 0x81, 0x7d, +0xf0, 0xc9, 0xf8, 0x23, 0xbb, 0x3c, 0x64, 0xa5, +0x99, 0x5b, 0xfe, 0x29, 0xed, 0xfc, 0xf2, 0x23, +0x25, 0x84, 0xf7, 0x7b, 0x5d, 0x4e, 0xbc, 0xa8, +0x53, 0xb7, 0x1a, 0x9f, 0x13, 0xe7, 0xfd, 0x2b, +0xb3, 0x90, 0xc5, 0x99, 0x90, 0xd2, 0xf0, 0x90, +0x99, 0x10, 0xda, 0x81, 0x2d, 0xed, 0x5e, 0xe8, +0xa3, 0x36, 0x52, 0xeb, 0xe8, 0xaa, 0xae, 0xc6, +0xcd, 0x16, 0x1c, 0x16, 0xe3, 0x78, 0x41, 0xf9, +0x4b, 0xbe, 0xc2, 0x1c, 0x6a, 0x98, 0xdf, 0x79, +0x62, 0xed, 0x63, 0x5f, 0xbe, 0xd8, 0x7b, 0xb2, +0x11, 0xaa, 0xf5, 0x24, 0x93, 0x5c, 0x84, 0xbb, +0x8f, 0x0c, 0x75, 0xcb, 0x2f, 0x9b, 0x1f, 0x69, +0x4f, 0x13, 0x45, 0x11, 0xed, 0x96, 0x1d, 0xdc, +0x14, 0x06, 0xb6, 0x83, 0x37, 0xa5, 0xa2, 0x97, +0xe7, 0x55, 0x6d, 0xbe, 0x9d, 0x74, 0x5d, 0x58, +0x0d, 0x5e, 0x7b, 0x34, 0x3d, 0xc3, 0x83, 0xd3, +0x19, 0xef, 0x3a, 0x25, 0x3c, 0x7c, 0x30, 0xe2, +0x70, 0x53, 0xd3, 0x1e, 0xe5, 0xf8, 0x6d, 0xbf, +0xf6, 0xb4, 0xd5, 0xf8, 0xc1, 0x96, 0xc8, 0xa0, +0x1c, 0x22, 0x44, 0x58, 0x76, 0x5b, 0x3a, 0x4e, +0x6e, 0x01, 0xfc, 0x18, 0x40, 0xb7, 0x9c, 0x63, +0x9f, 0x73, 0xf5, 0xf7, 0xa0, 0x56, 0x03, 0xad, +0x76, 0xed, 0x76, 0xad, 0xbd, 0xa2, 0xb2, 0x02, +0xb4, 0x8c, 0xf7, 0xa5, 0x02, 0x50, 0x6a, 0x61, +0xd5, 0xb8, 0xdc, 0x3d, 0x88, 0x20, 0xb5, 0x73, +0x25, 0x66, 0x3b, 0x6e, 0x80, 0xd6, 0x48, 0xec, +0x21, 0x93, 0xa1, 0xad, 0xa9, 0xcc, 0x0c, 0x6a, +0x69, 0x88, 0xda, 0x72, 0x80, 0x2f, 0xed, 0xc7, +0x52, 0xc1, 0xcc, 0xc4, 0xe6, 0x00, 0xee, 0xbd, +0x3e, 0x05, 0x72, 0x38, 0x96, 0x0b, 0x8b, 0xc9, +0xa5, 0x5f, 0xf9, 0xd0, 0xd2, 0xef, 0x1a, 0xc3, +0xb5, 0x38, 0xd6, 0xc3, 0xad, 0x9e, 0xc5, 0x12, +0x73, 0x8f, 0xfd, 0x09, 0x7d, 0xdf, 0xb7, 0xdd, +0xbb, 0x5a, 0xad, 0x26, 0xed, 0x76, 0x87, 0x38, +0x6e, 0x10, 0xf8, 0x41, 0x65, 0xca, 0x15, 0x85, +0xc1, 0xe4, 0x99, 0x53, 0xf8, 0x0a, 0x97, 0x1d, +0x5b, 0xd8, 0xa8, 0x96, 0x52, 0x66, 0x32, 0x2a, +0xf8, 0xa1, 0x93, 0xa9, 0x7a, 0xdb, 0x61, 0xad, +0x4e, 0x4d, 0xdb, 0xc0, 0x4c, 0x1c, 0x6a, 0x6b, +0x23, 0xaf, 0x8d, 0x6c, 0x3b, 0x99, 0xa9, 0x70, +0x7f, 0x4a, 0x76, 0xd5, 0xc4, 0x00, 0xe2, 0xa9, +0xca, 0xde, 0x56, 0x46, 0xc6, 0x72, 0xee, 0x76, +0xdc, 0xa0, 0x7e, 0xae, 0x3a, 0xde, 0x03, 0xe0, +0x92, 0x9c, 0xf7, 0x02, 0x7c, 0xef, 0x6b, 0xd9, +0xf3, 0x5e, 0x5d, 0xcd, 0x2e, 0x01, 0x59, 0x3a, +0x64, 0x60, 0x37, 0x80, 0xd5, 0x5e, 0x60, 0x97, +0x3f, 0x30, 0x96, 0xfb, 0xd6, 0xf3, 0xa8, 0xec, +0x80, 0xad, 0xa6, 0x6f, 0xad, 0x81, 0xa4, 0x40, +0x2d, 0x0f, 0x51, 0x3d, 0x5b, 0xcf, 0x5f, 0x8f, +0x0f, 0xa0, 0xac, 0x69, 0x4d, 0x3f, 0xb7, 0x9c, +0x41, 0xab, 0xb1, 0x57, 0xb0, 0xfc, 0x89, 0xb9, +0x48, 0x36, 0x60, 0xeb, 0xe7, 0x7f, 0xfd, 0xda, +0xaf, 0xdd, 0xdc, 0xc8, 0x9e, 0x9b, 0xee, 0x78, +0xdd, 0xde, 0xc0, 0x06, 0xd5, 0xef, 0x15, 0xf8, +0x00, 0x7e, 0xb3, 0xd9, 0x64, 0x62, 0xa2, 0x43, +0xbb, 0xdd, 0xb6, 0xe9, 0x51, 0x9e, 0xb3, 0xef, +0x4d, 0xd9, 0x90, 0xd8, 0x50, 0x14, 0x39, 0x69, +0x96, 0xba, 0x91, 0x25, 0x82, 0xd6, 0x5a, 0x80, +0xbc, 0xdb, 0xeb, 0xbd, 0x1c, 0x64, 0xdb, 0x37, +0x7f, 0xe0, 0xfc, 0xfc, 0xdb, 0x1e, 0x68, 0xeb, +0xb8, 0xa3, 0x20, 0xf0, 0x55, 0xad, 0x5b, 0xb5, +0xb2, 0xe5, 0xca, 0x49, 0x01, 0x33, 0x91, 0xed, +0x27, 0xb0, 0x17, 0x60, 0x95, 0x23, 0xc7, 0xdd, +0x60, 0x21, 0x48, 0x61, 0x6f, 0x54, 0x09, 0x63, +0x8d, 0x77, 0x3f, 0xd6, 0xaf, 0xd4, 0x6e, 0x20, +0xef, 0xc7, 0x11, 0xf6, 0xdb, 0xa3, 0x76, 0x81, +0x6a, 0xb7, 0x41, 0x5d, 0xbe, 0x54, 0xe3, 0xdf, +0xad, 0x2c, 0x82, 0xfa, 0x7b, 0xd4, 0x10, 0x61, +0xf7, 0x79, 0x11, 0xa9, 0x74, 0x15, 0x89, 0x3d, +0x6b, 0xa9, 0x04, 0xda, 0xde, 0xcb, 0x30, 0x47, +0xad, 0x27, 0x30, 0xb4, 0x8a, 0xb0, 0xaa, 0xe5, +0xf9, 0x55, 0xbf, 0x3d, 0x74, 0x1e, 0x42, 0xb0, +0xdf, 0x21, 0x6e, 0xa6, 0x50, 0xa9, 0x44, 0x4e, +0x05, 0x24, 0x93, 0x41, 0xf2, 0x9f, 0x7f, 0x67, +0xe1, 0xb7, 0xbe, 0xf4, 0x62, 0xef, 0x13, 0x9d, +0x58, 0x2f, 0xa7, 0x99, 0xa4, 0x59, 0x61, 0x59, +0xff, 0xbd, 0xc8, 0xfe, 0x0a, 0x01, 0x0e, 0x1e, +0x3c, 0x48, 0xbb, 0xdd, 0x22, 0x0a, 0x23, 0xdb, +0x68, 0x10, 0x45, 0x61, 0x0c, 0x69, 0x91, 0x52, +0x14, 0x05, 0x69, 0x96, 0x92, 0x8c, 0x12, 0xdb, +0x9a, 0x1c, 0xf0, 0x3c, 0x2d, 0x79, 0x9e, 0x6f, +0xac, 0x6d, 0x6e, 0xfe, 0xe5, 0xca, 0xda, 0xfa, +0x47, 0x90, 0xa2, 0xff, 0xa1, 0xaf, 0x84, 0x4b, +0xbf, 0xf8, 0xde, 0xc3, 0xef, 0x0b, 0xd2, 0x3c, +0x54, 0x59, 0x5d, 0x59, 0x72, 0xc0, 0x28, 0x80, +0xd5, 0x11, 0xf4, 0x7c, 0x98, 0x8d, 0xc6, 0xbd, +0x05, 0xeb, 0x9b, 0xc6, 0xb2, 0xc7, 0xd0, 0xdd, +0x64, 0x01, 0x92, 0x8f, 0x3d, 0x6f, 0x15, 0xa0, +0x2a, 0x16, 0xb9, 0x17, 0xf0, 0xbb, 0x45, 0x46, +0x45, 0x94, 0x7b, 0x91, 0x61, 0xcf, 0x92, 0xbd, +0x27, 0xeb, 0xac, 0xd6, 0xb9, 0x65, 0x77, 0x03, +0xbe, 0x4e, 0xfd, 0xee, 0x92, 0x2a, 0x6c, 0x52, +0x10, 0x38, 0x5f, 0x7e, 0xa0, 0x2d, 0xa5, 0x8b, +0xd8, 0xc0, 0xd5, 0x96, 0xeb, 0x9c, 0x92, 0xcb, +0x58, 0x09, 0xac, 0xdf, 0x3f, 0xd8, 0xa1, 0xdc, +0xbd, 0xcc, 0xe5, 0x40, 0xd4, 0x4c, 0x47, 0x67, +0x22, 0x2a, 0x0d, 0xb4, 0x7d, 0xb2, 0xd9, 0x28, +0xfb, 0x9f, 0x1f, 0x59, 0xf9, 0xe0, 0x6f, 0x7c, +0x62, 0xed, 0xf7, 0xb5, 0x56, 0xd7, 0xb4, 0x66, +0xd0, 0xeb, 0x5b, 0x37, 0x7c, 0xf1, 0x75, 0xb6, +0xa6, 0xf5, 0xe7, 0xe6, 0x66, 0x09, 0x83, 0xa0, +0x4a, 0x54, 0xc8, 0xf2, 0xc2, 0xe6, 0xb2, 0xe7, +0x99, 0xcd, 0x74, 0x19, 0x0e, 0xab, 0x01, 0xcb, +0x80, 0x19, 0x8e, 0x46, 0x57, 0x6e, 0xdc, 0x5c, +0xfa, 0xed, 0xad, 0x9d, 0x9d, 0x27, 0x80, 0x05, +0xc0, 0xfc, 0xc6, 0x67, 0x37, 0xd6, 0x8e, 0xcd, +0x86, 0xad, 0x9f, 0x7b, 0x6c, 0xf6, 0xc7, 0x03, +0x5d, 0x04, 0x55, 0xf2, 0x42, 0x8d, 0xd5, 0x2b, +0xa5, 0x6c, 0xb4, 0xeb, 0xe6, 0xd0, 0x72, 0x82, +0x99, 0x08, 0x62, 0x6f, 0x0c, 0xac, 0x5d, 0x72, +0x5c, 0xdb, 0x30, 0x55, 0xec, 0x1a, 0x2d, 0x16, +0x82, 0xe4, 0x66, 0xfc, 0xf0, 0xcc, 0x18, 0xe6, +0x75, 0x31, 0x20, 0x9a, 0x5b, 0x01, 0xbe, 0x0b, +0xf0, 0xfb, 0x88, 0x83, 0xfa, 0x2a, 0x29, 0x1d, +0x2a, 0x44, 0xab, 0x80, 0x5b, 0xd9, 0xf0, 0xb5, +0x2f, 0x50, 0xca, 0x2a, 0x8a, 0xd5, 0xa6, 0xc7, +0x9f, 0xcd, 0x2d, 0x30, 0x55, 0x5a, 0xd8, 0x18, +0x85, 0xf3, 0x40, 0x8f, 0x2f, 0x4a, 0xaa, 0x1d, +0x49, 0x61, 0x01, 0x5f, 0xc6, 0x04, 0x9c, 0x69, +0x38, 0xd6, 0x2b, 0x2c, 0xd2, 0x49, 0xd3, 0xc3, +0x1c, 0x88, 0x8a, 0x0f, 0x7c, 0x72, 0xed, 0xe3, +0xff, 0xe1, 0x0f, 0x16, 0xff, 0x57, 0x5e, 0xc8, +0xab, 0x53, 0x2d, 0xaf, 0xb7, 0xdd, 0xb7, 0xd3, +0x21, 0x6f, 0xd7, 0x0f, 0xf8, 0x4e, 0xcb, 0x6f, +0xb7, 0xda, 0xf6, 0xf7, 0x8c, 0x38, 0x36, 0x9f, +0x31, 0x4a, 0x46, 0x0c, 0xfa, 0x7d, 0x92, 0xc4, +0xce, 0xf9, 0xf3, 0x3c, 0x4f, 0x44, 0x24, 0xdb, +0xdc, 0xde, 0xfe, 0xf2, 0xc2, 0xe2, 0xcd, 0xdf, +0x1d, 0x8e, 0x46, 0x5f, 0x04, 0x6e, 0x28, 0xc5, +0x8e, 0xaf, 0x91, 0xbc, 0x90, 0xe4, 0x97, 0x3e, +0xb8, 0xf4, 0x2b, 0x0a, 0x8a, 0x9f, 0x7b, 0x6c, +0xf6, 0x1f, 0xf8, 0xda, 0x8c, 0x91, 0x40, 0x8f, +0xbd, 0x7b, 0x38, 0x33, 0x93, 0x91, 0x41, 0x16, +0x07, 0xd6, 0xcd, 0x3b, 0x1b, 0xba, 0xbe, 0x83, +0x7b, 0x64, 0x78, 0x29, 0x1e, 0x3c, 0x85, 0x84, +0xd8, 0xe0, 0x0f, 0x38, 0xfb, 0x5c, 0x50, 0x69, +0x61, 0x65, 0x67, 0xa9, 0x61, 0x97, 0x0f, 0xb3, +0xfc, 0xff, 0xfa, 0xda, 0x0f, 0x19, 0xf6, 0x43, +0x84, 0x4a, 0xde, 0xd7, 0xe1, 0x5c, 0x52, 0x6b, +0x99, 0x19, 0x84, 0xd5, 0x8f, 0x76, 0xc5, 0xf8, +0xb1, 0xdc, 0x22, 0x77, 0xc0, 0xce, 0x6b, 0x7a, +0x4c, 0xfd, 0x9a, 0xea, 0x9b, 0x08, 0x0c, 0x0b, +0xa4, 0x97, 0x5b, 0xc7, 0x91, 0x56, 0xa8, 0x40, +0x55, 0xc9, 0xa7, 0x15, 0x12, 0x94, 0xff, 0x3c, +0xe1, 0x93, 0x4f, 0x04, 0xd9, 0x1f, 0x7c, 0x66, +0xe3, 0x63, 0xbf, 0xf4, 0x7b, 0x37, 0x7e, 0xd9, +0x88, 0xbc, 0x30, 0xd9, 0xf4, 0xb6, 0x77, 0x06, +0x45, 0x61, 0xc4, 0x02, 0xff, 0x5e, 0xec, 0xfe, +0xbd, 0xcb, 0xfb, 0xfe, 0xb7, 0x7e, 0xdf, 0x2f, +0x22, 0x42, 0x92, 0x65, 0x8c, 0x46, 0x23, 0x7a, +0xfd, 0x3e, 0xfd, 0x5e, 0x9f, 0x34, 0xb5, 0x79, +0x00, 0x5a, 0x6b, 0xc9, 0xf2, 0x7c, 0x75, 0x69, +0x65, 0xe5, 0xc3, 0x0b, 0x8b, 0x37, 0x7f, 0x33, +0x4d, 0xd3, 0x2f, 0x03, 0x0b, 0x0a, 0xba, 0x02, +0xb9, 0x08, 0xa6, 0x11, 0xaa, 0x34, 0xcd, 0x64, +0xe7, 0xc9, 0x8b, 0xfd, 0x57, 0x8c, 0x10, 0xbd, +0xe9, 0x6c, 0xfb, 0x5c, 0xe0, 0x2b, 0x1f, 0x27, +0xde, 0x76, 0x01, 0xd4, 0x61, 0xb8, 0x2a, 0x95, +0xbe, 0x9d, 0xcc, 0x86, 0x42, 0x05, 0xcb, 0xfe, +0x7d, 0x3d, 0xa6, 0x82, 0xbd, 0x9b, 0xe7, 0xd8, +0x6b, 0xc3, 0x43, 0xda, 0x01, 0x32, 0x11, 0x20, +0xad, 0x10, 0x69, 0x05, 0x56, 0xb3, 0xf6, 0xb5, +0xf3, 0x20, 0xea, 0x5d, 0x4a, 0x61, 0x45, 0xd8, +0x75, 0xea, 0xad, 0x13, 0xca, 0x9e, 0x6b, 0x14, +0x8d, 0xd5, 0xda, 0xbd, 0xf1, 0xef, 0xda, 0x8c, +0x24, 0x77, 0x0d, 0x2e, 0x66, 0x42, 0xe9, 0x18, +0xab, 0x94, 0xd7, 0x1a, 0xbe, 0x54, 0x16, 0x41, +0xed, 0xf7, 0x04, 0xeb, 0xfb, 0xe8, 0x67, 0xb6, +0xa6, 0x3f, 0x71, 0x80, 0x77, 0x7e, 0x0d, 0x9c, +0xa1, 0x58, 0x95, 0x9d, 0x94, 0xcf, 0x6b, 0x32, +0x60, 0xd4, 0x0a, 0x92, 0xf7, 0x7f, 0x7c, 0xe5, +0xc3, 0xbf, 0xf0, 0x81, 0x85, 0xff, 0x3e, 0x4a, +0xe5, 0xf9, 0xc9, 0x96, 0xb7, 0xd5, 0x1d, 0x16, +0x45, 0x61, 0x9c, 0xdc, 0xff, 0x06, 0xba, 0x92, +0x03, 0xf8, 0x62, 0x84, 0x51, 0x92, 0xd0, 0xef, +0xf7, 0xe9, 0xf5, 0x7a, 0x96, 0xe5, 0xdb, 0x59, +0xf4, 0x02, 0xca, 0xf4, 0xfa, 0xbd, 0x8b, 0x57, +0xae, 0x2f, 0xfc, 0xf6, 0x4e, 0xb7, 0xfb, 0x19, +0x11, 0xb9, 0xa6, 0x94, 0xda, 0x12, 0x91, 0x51, +0xa9, 0x8f, 0x0a, 0x30, 0x4a, 0x25, 0x8f, 0x43, +0xb5, 0x35, 0x4c, 0xe5, 0xa5, 0xff, 0xfa, 0x91, +0x95, 0xf7, 0xaf, 0xee, 0xe4, 0xdd, 0x7f, 0xf7, +0xde, 0x43, 0x3f, 0x3b, 0xd3, 0xd0, 0x13, 0xe4, +0xb5, 0x46, 0x85, 0x75, 0x1f, 0xbe, 0xf3, 0x38, +0x96, 0x81, 0x1e, 0x36, 0x12, 0x3b, 0xf2, 0x2c, +0xf6, 0x91, 0xe9, 0x00, 0x3a, 0xa1, 0x1d, 0x46, +0x59, 0x02, 0x08, 0x65, 0x3d, 0x6d, 0x75, 0x4b, +0x40, 0x6b, 0xeb, 0x58, 0x2a, 0xfb, 0x12, 0x69, +0x85, 0x28, 0xeb, 0x0a, 0x56, 0x45, 0x00, 0x85, +0x47, 0xe9, 0x78, 0x11, 0x03, 0x2a, 0xcf, 0x00, +0x41, 0x4c, 0x0a, 0x26, 0x87, 0x9a, 0x13, 0x48, +0x54, 0x0e, 0xca, 0x70, 0x8b, 0x08, 0xa9, 0x2e, +0x40, 0xc6, 0x4a, 0x69, 0x7d, 0xdb, 0xa3, 0x77, +0xa8, 0xda, 0xeb, 0xea, 0x3b, 0x72, 0x63, 0x95, +0xba, 0x41, 0xee, 0xba, 0x78, 0x28, 0x94, 0xef, +0xc4, 0x45, 0x9d, 0x4b, 0x68, 0xa9, 0x79, 0x0b, +0x15, 0xf8, 0x20, 0x9d, 0x40, 0xb6, 0x85, 0xee, +0x2f, 0xff, 0xf1, 0xe2, 0x1f, 0xfd, 0xea, 0x9f, +0xae, 0x7c, 0x20, 0x37, 0xf2, 0x92, 0xa3, 0xfc, +0x3c, 0x77, 0x4a, 0x5f, 0xb1, 0xcf, 0xc4, 0xb3, +0x7b, 0x46, 0x80, 0xc1, 0x70, 0xc0, 0xce, 0xce, +0x0e, 0xbd, 0x7e, 0x9f, 0x34, 0x49, 0x10, 0x01, +0x4f, 0x7b, 0x22, 0x62, 0x46, 0xab, 0xeb, 0x1b, +0x5f, 0xb8, 0xba, 0xb0, 0xf0, 0x7b, 0xa3, 0xd1, +0xe8, 0xcb, 0xc0, 0xa2, 0x52, 0xaa, 0x2b, 0xb5, +0x74, 0x60, 0x93, 0xe7, 0xa0, 0x14, 0xda, 0xf3, +0x18, 0xa6, 0x92, 0xb7, 0x22, 0xb5, 0x35, 0xca, +0xe4, 0xc5, 0x0f, 0xfc, 0xd5, 0xc6, 0xff, 0xbe, +0xbe, 0x9e, 0x2d, 0xfc, 0xa7, 0x7f, 0x72, 0xe4, +0x5f, 0xde, 0x3f, 0x1f, 0x9e, 0xd0, 0x86, 0x5a, +0x37, 0x28, 0x77, 0x50, 0xf3, 0x05, 0xa0, 0x40, +0x05, 0xce, 0xf7, 0x9f, 0x0b, 0xb2, 0x34, 0x82, +0xe5, 0xc4, 0x6a, 0xd0, 0x93, 0x21, 0x32, 0x15, +0x5a, 0x5f, 0x81, 0xe7, 0x31, 0xa6, 0xd4, 0x72, +0x5f, 0xa3, 0x16, 0x15, 0x80, 0x8a, 0x51, 0x2a, +0x06, 0x1d, 0x43, 0x68, 0xe3, 0x00, 0x36, 0x18, +0x54, 0x3a, 0x03, 0xc4, 0x02, 0x5d, 0x32, 0x20, +0x05, 0x19, 0x81, 0x0c, 0x81, 0x21, 0x98, 0x81, +0x0d, 0x09, 0xef, 0x07, 0x68, 0x63, 0x2d, 0x23, +0x8b, 0x8b, 0xfb, 0x98, 0x7b, 0xa8, 0xf1, 0xfb, +0x85, 0xb8, 0xb4, 0xae, 0x12, 0xe8, 0xa6, 0x42, +0x58, 0x15, 0x52, 0xb3, 0x20, 0xdc, 0xf3, 0x28, +0x2d, 0x01, 0x63, 0x91, 0x40, 0x44, 0x59, 0x65, +0xb2, 0x13, 0xc8, 0xd5, 0x8d, 0xf4, 0xc6, 0xbf, +0xfd, 0xc0, 0xc2, 0xfb, 0x3f, 0xf6, 0xd4, 0xf6, +0x5f, 0x78, 0x5a, 0x5d, 0x99, 0x6a, 0x79, 0x3b, +0x3b, 0x83, 0x31, 0xe5, 0x7f, 0x33, 0xc0, 0x07, +0xf0, 0x4e, 0x9d, 0x3c, 0xf1, 0x8b, 0xbd, 0x5e, +0xcf, 0xcd, 0x9f, 0xd1, 0xa2, 0xb5, 0x92, 0x2c, +0xcb, 0xd7, 0x16, 0x16, 0x17, 0x3f, 0x78, 0x6d, +0x61, 0xe1, 0x03, 0x69, 0x96, 0x3d, 0x5d, 0x03, +0x7e, 0x01, 0xd6, 0xcc, 0x31, 0x79, 0xee, 0x2a, +0x66, 0xdc, 0xb0, 0x47, 0xad, 0x49, 0x0b, 0x24, +0xf2, 0x55, 0xaa, 0x94, 0xda, 0xb9, 0xb4, 0x94, +0x5c, 0xfb, 0xe4, 0x85, 0xee, 0xcb, 0x47, 0x67, +0xc2, 0xf9, 0xd3, 0x87, 0xa2, 0xc3, 0x9e, 0x87, +0x57, 0x01, 0x6d, 0x0f, 0xf0, 0x77, 0x1d, 0x7b, +0x96, 0x3a, 0x94, 0xa7, 0xac, 0x2f, 0xa4, 0x97, +0xa3, 0xd7, 0x13, 0xeb, 0x28, 0xa9, 0x14, 0x25, +0x76, 0x2b, 0x60, 0x0a, 0xd0, 0x1e, 0xe8, 0x18, +0x45, 0x0c, 0x6a, 0xbc, 0x29, 0x1a, 0x28, 0x15, +0xa1, 0x54, 0xe8, 0xb6, 0x00, 0x9b, 0x5d, 0xea, +0x32, 0x50, 0xc6, 0x36, 0x1d, 0x56, 0x99, 0xa8, +0xa7, 0xe7, 0x96, 0x08, 0x33, 0x16, 0x1d, 0x55, +0xee, 0x08, 0x62, 0xd3, 0xba, 0x0d, 0x6e, 0x8e, +0x72, 0x81, 0xda, 0xc9, 0x6d, 0x38, 0x7b, 0xcb, +0xb2, 0x78, 0x95, 0x8b, 0xbd, 0x0f, 0xdf, 0xb3, +0xfb, 0x52, 0xcf, 0x29, 0xef, 0xb9, 0xfa, 0xd2, +0x31, 0x12, 0x8b, 0x56, 0xd0, 0xf2, 0xc8, 0x1a, +0x7e, 0xf6, 0x99, 0xe7, 0xbb, 0x5f, 0xf9, 0x57, +0xbf, 0x7a, 0xf5, 0xbf, 0x7c, 0xf1, 0xa5, 0xfe, +0x47, 0xa3, 0x40, 0x5d, 0x8b, 0x43, 0xd5, 0xdb, +0x19, 0x1a, 0x57, 0x6e, 0xf8, 0xcd, 0x03, 0x1f, +0x40, 0xbd, 0xeb, 0xb1, 0xc7, 0x44, 0xc4, 0x4e, +0xef, 0x54, 0x8a, 0x7c, 0x6b, 0x67, 0xe7, 0xf9, +0x57, 0x2f, 0x5f, 0xf9, 0xad, 0x9d, 0x6e, 0xf7, +0x49, 0x60, 0x41, 0x29, 0xb5, 0x85, 0x48, 0x52, +0xb2, 0x7c, 0x53, 0x14, 0xfb, 0xca, 0x1b, 0xa5, +0x35, 0x9e, 0xeb, 0xd4, 0x15, 0xf9, 0x28, 0xa5, +0x54, 0x34, 0xca, 0x64, 0x2e, 0xf4, 0xd4, 0xd9, +0x7f, 0xf1, 0xf8, 0xec, 0xfb, 0xfe, 0xf5, 0xbb, +0x0f, 0xbc, 0xf7, 0xf0, 0x54, 0x30, 0x67, 0x83, +0x8c, 0x25, 0x12, 0xb8, 0x07, 0x7d, 0x1b, 0x84, +0xb8, 0x25, 0x26, 0xe0, 0x12, 0x32, 0xc4, 0x08, +0xe2, 0x6b, 0xeb, 0x45, 0x6c, 0xfa, 0x48, 0x2b, +0x80, 0x76, 0x0c, 0xf1, 0x04, 0xf8, 0x6d, 0xbb, +0x79, 0x2d, 0x94, 0xd7, 0x02, 0x15, 0xa2, 0x08, +0xa9, 0xc2, 0xbe, 0x2e, 0xf0, 0x63, 0xab, 0x99, +0x12, 0xa4, 0xa4, 0x7e, 0xe9, 0x23, 0xd2, 0x03, +0xe9, 0x43, 0x51, 0xe3, 0x02, 0x85, 0x8c, 0xbd, +0x94, 0x99, 0x8b, 0xf4, 0x8d, 0x0a, 0xd4, 0x30, +0x43, 0x0d, 0x5d, 0xae, 0x62, 0x79, 0xbe, 0xee, +0xe5, 0x94, 0x12, 0x59, 0x6a, 0xf6, 0xfd, 0x7e, +0xc7, 0xb5, 0xc8, 0x1e, 0xbe, 0x42, 0x22, 0x2d, +0x4b, 0x3b, 0xf9, 0xfa, 0xfb, 0x3f, 0xb6, 0xf2, +0xe1, 0xf7, 0x7f, 0x74, 0xf5, 0x0f, 0xfb, 0x23, +0xf3, 0x52, 0xbb, 0xa1, 0xd7, 0x04, 0x92, 0xc1, +0xc8, 0x54, 0xda, 0xfe, 0x37, 0x2a, 0xf3, 0x6f, +0x81, 0xdb, 0x0f, 0x3f, 0xfe, 0x98, 0x68, 0xad, +0xc5, 0x18, 0x33, 0x58, 0x5a, 0x59, 0xf9, 0xab, +0xd7, 0xae, 0x5e, 0xfb, 0xfd, 0x24, 0x49, 0xbe, +0x02, 0x2c, 0x29, 0xa5, 0x7a, 0x7b, 0x59, 0xfe, +0x9d, 0x9c, 0x0c, 0xf5, 0x12, 0x33, 0x4f, 0x43, +0xe8, 0xab, 0x20, 0xcb, 0xa5, 0x5d, 0x18, 0x8e, +0x3c, 0x7c, 0xac, 0xf1, 0xd6, 0x9f, 0xff, 0x89, +0xf9, 0x9f, 0x7d, 0xf7, 0x23, 0x13, 0x6f, 0x69, +0x84, 0x3a, 0x52, 0x9e, 0x52, 0xb7, 0xe3, 0x06, +0x52, 0x8a, 0x8a, 0x5d, 0x9e, 0xbf, 0xbd, 0x08, +0x22, 0x15, 0xd1, 0x5a, 0x16, 0x6d, 0x40, 0x34, +0xe2, 0xf9, 0x96, 0xf5, 0xfb, 0x11, 0x84, 0x31, +0x04, 0x4d, 0x1b, 0x08, 0x6a, 0xb4, 0x51, 0xca, +0x43, 0x3c, 0x0f, 0x82, 0x00, 0xc8, 0x11, 0x52, +0x6c, 0x46, 0xd0, 0xc8, 0x8a, 0x82, 0xb4, 0x07, +0xf9, 0x10, 0x4c, 0x6e, 0x0b, 0x31, 0x72, 0xd7, +0xeb, 0x30, 0x2b, 0xd3, 0xca, 0x1c, 0x42, 0x94, +0xd7, 0x57, 0x06, 0x86, 0xca, 0xb5, 0x0f, 0x90, +0xd5, 0xed, 0x00, 0xbe, 0x47, 0x0c, 0x48, 0xa0, +0x25, 0x31, 0x92, 0x7c, 0xe6, 0xb9, 0xee, 0x53, +0xff, 0xfe, 0x8f, 0x16, 0x7f, 0xeb, 0xb9, 0xcb, +0xc3, 0x2f, 0xf8, 0xbe, 0x5a, 0x8c, 0x43, 0xd5, +0x4b, 0x52, 0xc9, 0x12, 0x17, 0x1f, 0x28, 0xf2, +0xfc, 0x1b, 0xd2, 0xf6, 0x6f, 0x0b, 0xb3, 0xf7, +0xfc, 0xc8, 0xbb, 0x8b, 0x24, 0x4d, 0xd7, 0x2e, +0x5f, 0xbd, 0xf6, 0x7f, 0x16, 0x6f, 0xde, 0xfc, +0x93, 0xc2, 0x98, 0x4b, 0x4a, 0xa9, 0x65, 0x60, +0x28, 0x32, 0xee, 0x2f, 0x63, 0x6a, 0xa3, 0x59, +0xee, 0xb6, 0xbc, 0x20, 0x28, 0x3b, 0x8c, 0xd1, +0x08, 0x95, 0x02, 0x1a, 0xc3, 0x54, 0xa6, 0x7d, +0x8f, 0xd3, 0x3f, 0xf1, 0x86, 0xc9, 0x1f, 0xf9, +0x37, 0xef, 0x99, 0xff, 0xe9, 0xd7, 0x1d, 0x8f, +0xef, 0x0f, 0x02, 0xe5, 0xe3, 0x63, 0x95, 0x39, +0x7d, 0x1b, 0xaa, 0xbf, 0x5b, 0x30, 0xa8, 0x3a, +0xa6, 0x76, 0x42, 0xf6, 0x00, 0xc2, 0x9d, 0xac, +0x67, 0x80, 0xd6, 0x57, 0xfd, 0xbd, 0x52, 0x55, +0xd8, 0xfb, 0x3b, 0x6a, 0xcf, 0xe7, 0xf7, 0x66, +0x93, 0xd6, 0x7f, 0x0f, 0x19, 0xdb, 0xfc, 0x0e, +0xe0, 0x6a, 0x3f, 0x24, 0x70, 0x22, 0x2f, 0x13, +0xb2, 0x17, 0x17, 0x86, 0x97, 0x7f, 0xf9, 0x4f, +0x97, 0xff, 0xe8, 0x4f, 0xbe, 0xb4, 0xf5, 0xb1, +0xac, 0x90, 0xcb, 0xed, 0x58, 0x6f, 0x6a, 0xc5, +0xa8, 0x37, 0x34, 0x52, 0x56, 0x41, 0x7f, 0x3d, +0x30, 0xb8, 0xd7, 0xa5, 0xde, 0xf2, 0xe6, 0xef, +0xfd, 0xf2, 0x2b, 0x97, 0x2f, 0xff, 0xee, 0x4e, +0xb7, 0xf7, 0x79, 0x11, 0x59, 0x50, 0x4a, 0x6d, +0xdf, 0x0b, 0xcb, 0xbf, 0xeb, 0x17, 0x7b, 0x5e, +0xd9, 0x6c, 0xb2, 0xe4, 0x06, 0x7e, 0x9a, 0x4b, +0xab, 0x30, 0xcc, 0x4d, 0x36, 0xbd, 0x73, 0xef, +0x7d, 0xd3, 0xe4, 0x7b, 0xfe, 0xf9, 0x63, 0x73, +0x3f, 0x76, 0xee, 0x48, 0xe3, 0x44, 0x10, 0x2a, +0x9f, 0x40, 0x59, 0x33, 0xae, 0xae, 0x24, 0x56, +0x7b, 0x6e, 0x45, 0x04, 0x60, 0x5f, 0xee, 0x40, +0xfd, 0x7c, 0x5d, 0xce, 0xde, 0xc3, 0x45, 0xd7, +0x9f, 0x6d, 0xdd, 0xef, 0x5f, 0x3f, 0x77, 0x3b, +0xc0, 0xd7, 0xcf, 0xdd, 0xc2, 0xf2, 0xc5, 0x35, +0x79, 0xa8, 0x7d, 0x9f, 0x82, 0xcc, 0x48, 0x76, +0x71, 0x61, 0x74, 0xfd, 0xd7, 0x9e, 0x58, 0xfd, +0xc8, 0x87, 0xbe, 0xb8, 0xf5, 0x91, 0xad, 0x7e, +0x71, 0xd1, 0xf7, 0x58, 0x6f, 0x86, 0xba, 0x3f, +0xca, 0x4c, 0x9e, 0xba, 0xc7, 0x7e, 0x37, 0xce, +0xfb, 0xcd, 0x2c, 0xd5, 0x6c, 0xb7, 0xdf, 0x97, +0x66, 0xd9, 0x33, 0xc0, 0xb2, 0xd6, 0xba, 0x6f, +0x8c, 0xa9, 0xa0, 0xfd, 0xad, 0x60, 0x37, 0x25, +0x37, 0x00, 0x08, 0x3c, 0x94, 0xa7, 0x55, 0x90, +0x17, 0xd2, 0xce, 0x0d, 0xf3, 0x93, 0x4d, 0x7d, +0xe6, 0xbd, 0xdf, 0x3b, 0xf5, 0xee, 0x7f, 0xf6, +0xce, 0xd9, 0x1f, 0x3b, 0x77, 0xa4, 0x71, 0x22, +0x8c, 0x74, 0x48, 0xa8, 0x6d, 0x02, 0xbe, 0x2d, +0xa7, 0xb9, 0x33, 0xe0, 0x6f, 0x17, 0x05, 0xac, +0x03, 0xbb, 0xce, 0x19, 0xee, 0x84, 0x04, 0x52, +0x3b, 0x90, 0xbd, 0xef, 0xd7, 0x00, 0x59, 0xbe, +0xb7, 0xeb, 0x98, 0xbb, 0xc8, 0x7a, 0x19, 0x9b, +0x7b, 0x22, 0x92, 0xe4, 0x92, 0xbc, 0xb4, 0x30, +0xbc, 0xfa, 0x9b, 0x9f, 0x5c, 0xfb, 0xe8, 0x07, +0xbf, 0xb8, 0xf5, 0xc4, 0xf6, 0xa0, 0x78, 0x35, +0xf0, 0x58, 0x09, 0x7c, 0xd5, 0x13, 0x21, 0x1f, +0xa5, 0xae, 0x0b, 0xc1, 0xb7, 0x89, 0xea, 0xeb, +0x4b, 0xf9, 0x51, 0x74, 0x0a, 0x58, 0x55, 0x4a, +0x8d, 0x59, 0xbe, 0x73, 0x2c, 0x7c, 0xab, 0x7e, +0xb8, 0xce, 0x0d, 0x00, 0x42, 0x1f, 0xa5, 0x95, +0x0a, 0xd2, 0x5c, 0x5a, 0x46, 0x98, 0x6b, 0x86, +0xea, 0xd4, 0xe3, 0xe7, 0x3b, 0xef, 0xf8, 0xa7, +0xef, 0x9c, 0xfd, 0xe1, 0x37, 0x9e, 0x6e, 0x3e, +0x3c, 0xdd, 0xf6, 0xda, 0x84, 0x5a, 0xdb, 0xfa, +0x2f, 0xe7, 0x80, 0xb9, 0x2d, 0x22, 0x28, 0x6e, +0x11, 0x0d, 0xec, 0xf9, 0x0c, 0xdc, 0xfe, 0xf8, +0x16, 0x60, 0xef, 0xdd, 0xef, 0x43, 0xf1, 0xb0, +0x9b, 0xba, 0xa5, 0xfe, 0x3f, 0x35, 0x80, 0x97, +0x4a, 0xa4, 0x01, 0x31, 0x62, 0xb6, 0xfa, 0x45, +0xf7, 0xe9, 0xd7, 0xfa, 0x2f, 0xfc, 0xfa, 0x13, +0x6b, 0x1f, 0xfb, 0xf4, 0x73, 0xdd, 0xcf, 0x0d, +0x12, 0x73, 0xcd, 0xd3, 0xac, 0x45, 0x81, 0x1a, +0x88, 0x90, 0x8d, 0x32, 0xa9, 0x1e, 0xf9, 0xb7, +0x93, 0xea, 0xeb, 0x4b, 0xf9, 0x51, 0x14, 0x61, +0x47, 0x3f, 0x7e, 0x53, 0x2c, 0xff, 0x9e, 0x7e, +0x6c, 0x1f, 0x44, 0x50, 0xa8, 0x20, 0x2d, 0xa4, +0x29, 0xc2, 0xb4, 0x52, 0x1c, 0x7e, 0xdd, 0xb1, +0xc6, 0x23, 0x7f, 0xff, 0x0d, 0x13, 0xef, 0xf8, +0xc9, 0xbf, 0x37, 0xf5, 0xd6, 0xd3, 0xf3, 0xe1, +0xa1, 0x66, 0xec, 0x35, 0x08, 0x94, 0x22, 0xf4, +0x6c, 0x7e, 0x9d, 0x73, 0xfc, 0xec, 0x0b, 0xf8, +0x3d, 0xaf, 0xa5, 0x2e, 0x1e, 0xa8, 0x7d, 0x6e, +0xef, 0xda, 0x87, 0xe2, 0xd5, 0x2e, 0xa0, 0xb2, +0x1b, 0x19, 0xea, 0xc7, 0xa6, 0x86, 0x10, 0x95, +0xd5, 0x60, 0x37, 0x31, 0x22, 0xfd, 0x51, 0x31, +0xb8, 0xb4, 0x98, 0x2c, 0x7c, 0xf4, 0xe9, 0xed, +0xff, 0xfb, 0x91, 0xa7, 0xb6, 0x9f, 0xbc, 0x70, +0x6d, 0xf8, 0x9c, 0x08, 0x4b, 0xa1, 0xaf, 0xb6, +0x02, 0x4f, 0x0d, 0x0a, 0x23, 0x79, 0x92, 0xff, +0xcd, 0x03, 0xbe, 0x5c, 0xca, 0x77, 0x2d, 0xcc, +0x00, 0x8a, 0x2c, 0xbb, 0xe7, 0x4c, 0x92, 0x6f, +0x66, 0x69, 0xcf, 0x43, 0xd5, 0x10, 0xc1, 0xb7, +0x2d, 0x09, 0x3d, 0x11, 0x1a, 0x59, 0x41, 0x07, +0x98, 0x8e, 0x03, 0x75, 0xf4, 0x4d, 0xf7, 0x35, +0xbf, 0xe7, 0x47, 0x1f, 0x99, 0x78, 0xd3, 0x0f, +0x3e, 0xdc, 0x7e, 0xc3, 0xc9, 0x03, 0xe1, 0xe1, +0x76, 0xec, 0x35, 0x75, 0xa8, 0x3d, 0x02, 0x6d, +0x91, 0x21, 0xf4, 0xc6, 0x08, 0xe1, 0xac, 0x86, +0x5b, 0x02, 0x4b, 0xd5, 0x9d, 0x72, 0x9b, 0x17, +0x7b, 0xb8, 0xdc, 0x2d, 0x5c, 0xc0, 0x1e, 0xd4, +0xdd, 0xbc, 0xbb, 0xea, 0x05, 0x72, 0x71, 0xb9, +0x83, 0xd6, 0x14, 0x34, 0xb9, 0x14, 0x3b, 0x03, +0xd3, 0x7b, 0x6d, 0x79, 0xb4, 0xf0, 0x89, 0x67, +0x76, 0x9e, 0xfa, 0xd4, 0x73, 0xdd, 0xaf, 0x7c, +0xe5, 0x95, 0xfe, 0x73, 0x85, 0xe1, 0xa6, 0x52, +0x6c, 0x85, 0x9e, 0xea, 0x69, 0x4d, 0x52, 0x18, +0xc9, 0xb3, 0xbc, 0x92, 0x0a, 0xdf, 0x94, 0x3b, +0xf7, 0x9b, 0x59, 0x4a, 0xbb, 0x51, 0x69, 0xb7, +0xeb, 0x25, 0xfb, 0xed, 0x5c, 0x7b, 0x11, 0x41, +0x01, 0xa1, 0xaf, 0x94, 0x40, 0x60, 0x8c, 0x34, +0x72, 0x43, 0x1b, 0x98, 0xf4, 0x34, 0xf3, 0x8f, +0x9e, 0x8c, 0x1f, 0x7c, 0xe3, 0xe9, 0xe6, 0xeb, +0xdf, 0xf5, 0xfa, 0xce, 0x23, 0x0f, 0x1c, 0x8a, +0xce, 0x1c, 0x9c, 0x0c, 0x26, 0x9b, 0x0d, 0x1d, +0xeb, 0x40, 0x7b, 0xb8, 0xca, 0x9d, 0xdd, 0xa1, +0xd8, 0xba, 0xd8, 0x50, 0x63, 0xd3, 0xed, 0x4e, +0x8a, 0xc0, 0x5e, 0xc5, 0xad, 0xa6, 0xc0, 0x51, +0x46, 0x23, 0xab, 0x44, 0x51, 0x81, 0x42, 0xa4, +0xc8, 0x4d, 0xd1, 0x1b, 0x99, 0xc1, 0xd2, 0x56, +0xb6, 0x75, 0xf1, 0xc6, 0xe8, 0xd2, 0x27, 0x9e, +0xd9, 0x79, 0xf6, 0x6b, 0x57, 0x86, 0xcf, 0x5d, +0xb8, 0x36, 0xbc, 0x68, 0x84, 0x35, 0x60, 0x3b, +0xf0, 0xd4, 0xc0, 0xf7, 0x18, 0x01, 0x79, 0x92, +0x89, 0x8c, 0x99, 0x86, 0x6d, 0xe0, 0xf8, 0x37, +0x49, 0xf1, 0x7b, 0xd7, 0xbd, 0xe8, 0xc6, 0xdf, +0xf6, 0x55, 0x76, 0x25, 0x2d, 0xf3, 0x12, 0xc1, +0x12, 0xb5, 0xef, 0x29, 0x6d, 0x8c, 0xf8, 0x40, +0x23, 0x37, 0x34, 0x81, 0x36, 0x30, 0xd5, 0x08, +0xd4, 0xdc, 0x23, 0x27, 0xe2, 0x33, 0x27, 0xe6, +0x82, 0xfb, 0xbe, 0xff, 0x5c, 0xeb, 0xbe, 0xb3, +0x87, 0x1b, 0x27, 0x8e, 0xcd, 0x84, 0x87, 0xa7, +0x5a, 0x5e, 0x33, 0x0e, 0x75, 0x10, 0xfa, 0x3a, +0xd4, 0x9e, 0xf2, 0x28, 0x73, 0x11, 0x4b, 0x1d, +0xc2, 0xdb, 0x2d, 0x0e, 0xea, 0x49, 0x3d, 0xd5, +0xfb, 0xf5, 0x28, 0x5e, 0x25, 0xc3, 0x45, 0x0a, +0x23, 0x45, 0x9a, 0x4b, 0x36, 0x48, 0x4c, 0xb2, +0xd6, 0xcd, 0xbb, 0x37, 0x37, 0xb3, 0x9b, 0xcf, +0x5c, 0x1e, 0x5c, 0xf9, 0xea, 0xe5, 0xc1, 0xe5, +0x2b, 0xab, 0xe9, 0x2b, 0xcf, 0x5e, 0x1d, 0xbe, +0x66, 0x0c, 0x1b, 0xc0, 0x36, 0xd0, 0x0b, 0x7d, +0x35, 0x04, 0x12, 0x4f, 0x53, 0x24, 0x99, 0xec, +0x1a, 0x22, 0x66, 0x8a, 0x62, 0x97, 0x17, 0xf5, +0x6f, 0x73, 0x7d, 0x47, 0x20, 0x40, 0x7d, 0x29, +0xad, 0x2d, 0x67, 0xa8, 0x4d, 0xfd, 0x54, 0x80, +0xef, 0xa1, 0x8d, 0x2d, 0x36, 0xf2, 0x51, 0x84, +0x45, 0x41, 0x43, 0x20, 0xc6, 0x22, 0x45, 0x2b, +0x0a, 0xd4, 0xe4, 0xfd, 0x07, 0xc3, 0x43, 0xf3, +0x93, 0xc1, 0xfc, 0x54, 0xd3, 0x9b, 0x3f, 0x31, +0x17, 0xce, 0x3c, 0x78, 0xa4, 0x31, 0x3b, 0x37, +0xe9, 0x4f, 0x4f, 0x35, 0xbd, 0xc9, 0xd0, 0x57, +0xd1, 0x44, 0xec, 0x4d, 0xbb, 0x21, 0x18, 0xaa, +0x11, 0x28, 0x2f, 0x0a, 0xb4, 0x06, 0x61, 0x90, +0x4a, 0x91, 0xd9, 0x9e, 0xba, 0x92, 0x17, 0x26, +0xeb, 0x27, 0xa6, 0x3b, 0xcc, 0x64, 0xb0, 0x33, +0x34, 0x3b, 0x0b, 0x6b, 0xe9, 0xda, 0xcb, 0x37, +0x47, 0x9b, 0x8b, 0x1b, 0xd9, 0xda, 0xf6, 0xa0, +0x58, 0x5d, 0xdc, 0x48, 0x97, 0x5e, 0x5d, 0x4e, +0x97, 0x8d, 0xd0, 0x05, 0xfa, 0x40, 0x5f, 0xc1, +0x30, 0xf0, 0x55, 0x62, 0x44, 0x52, 0x4f, 0xa9, +0x4c, 0x10, 0x93, 0xed, 0x1e, 0x6d, 0x34, 0xee, +0x71, 0xf8, 0xb7, 0x48, 0xed, 0xfb, 0xad, 0xef, +0x38, 0x04, 0xa8, 0xaf, 0xfd, 0x38, 0x03, 0x50, +0xc5, 0x55, 0xb4, 0x42, 0x1b, 0xb1, 0x01, 0x5b, +0x81, 0x40, 0x84, 0xc0, 0x08, 0x01, 0x36, 0x74, +0xe4, 0x8a, 0x02, 0x09, 0xdd, 0xe6, 0xd7, 0xb7, +0xb9, 0x19, 0xfe, 0x17, 0x08, 0x00, 0x00, 0x00, +0xb7, 0x49, 0x44, 0x41, 0x54, 0x8e, 0xd7, 0x98, +0xeb, 0xf8, 0x91, 0x80, 0xdc, 0xd8, 0xc8, 0x86, +0xbd, 0x91, 0x49, 0xb1, 0xf5, 0x62, 0xae, 0x3a, +0xa4, 0xda, 0xd2, 0xfa, 0xe6, 0x69, 0x32, 0xad, +0xc8, 0x04, 0x72, 0x05, 0xb9, 0xd6, 0xca, 0xe4, +0x85, 0x58, 0x09, 0x5a, 0xbb, 0x76, 0x71, 0xd6, +0x40, 0x49, 0xed, 0xdf, 0xa9, 0xeb, 0x3b, 0x1a, +0x01, 0xea, 0xab, 0x6a, 0xd0, 0x58, 0x8e, 0x5e, +0xdb, 0x67, 0x2e, 0x70, 0x19, 0x61, 0x56, 0xae, +0x64, 0xdf, 0x48, 0xe5, 0xb0, 0xd5, 0x28, 0x5b, +0x20, 0x4c, 0x69, 0x43, 0xd4, 0x06, 0x7f, 0x38, +0x58, 0x89, 0x80, 0xd1, 0x36, 0xea, 0x6c, 0x0b, +0xb7, 0x6c, 0xeb, 0x40, 0x03, 0xb6, 0xde, 0xd5, +0x18, 0xdb, 0x9c, 0x63, 0x3f, 0x55, 0xa9, 0x6a, +0x64, 0x59, 0xb6, 0x81, 0xfd, 0x1b, 0xd6, 0xa7, +0xbe, 0xd1, 0xf5, 0x77, 0x06, 0x01, 0xf6, 0x5b, +0x15, 0x52, 0xd4, 0x10, 0x62, 0x3f, 0xc4, 0xb8, +0xed, 0xff, 0xbb, 0xfd, 0xd7, 0x03, 0xaa, 0x92, +0x9a, 0x2b, 0xa5, 0xf9, 0xef, 0x10, 0xb0, 0xf7, +0x5b, 0x7f, 0xa7, 0x11, 0xe0, 0x4e, 0x6b, 0x57, +0x4f, 0x9e, 0x3a, 0xb9, 0xdf, 0xe3, 0x2a, 0x81, +0xbb, 0xeb, 0xf5, 0x77, 0xd7, 0x77, 0xd7, 0x77, +0xd7, 0x77, 0xd7, 0xff, 0x57, 0xeb, 0xff, 0x01, +0x60, 0xf9, 0x19, 0x2a, 0x59, 0x8e, 0x97, 0x36, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *sql_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_sql_png = new wxImage(); + if (!img_sql_png || !img_sql_png->IsOk()) + { + wxMemoryInputStream img_sql_pngIS(sql_png_data, sizeof(sql_png_data)); + img_sql_png->LoadFile(img_sql_pngIS, wxBITMAP_TYPE_PNG); + } + return img_sql_png; +} +#define sql_png_img sql_png_img() + +static wxBitmap *sql_png_bmp() +{ + static wxBitmap *bmp_sql_png; + if (!bmp_sql_png || !bmp_sql_png->IsOk()) + bmp_sql_png = new wxBitmap(*sql_png_img); + return bmp_sql_png; +} +#define sql_png_bmp sql_png_bmp() + +static wxIcon *sql_png_ico() +{ + static wxIcon *ico_sql_png; + if (!ico_sql_png || !ico_sql_png->IsOk()) + { + ico_sql_png = new wxIcon(); + ico_sql_png->CopyFromBitmap(*sql_png_bmp); + } + return ico_sql_png; +} +#define sql_png_ico sql_png_ico() + +#endif // SQL_PNG_H diff --git a/include/images/statistics.png b/include/images/statistics.png new file mode 100644 index 0000000..1e163b0 Binary files /dev/null and b/include/images/statistics.png differ diff --git a/include/images/statistics.pngc b/include/images/statistics.pngc new file mode 100644 index 0000000..68dd021 --- /dev/null +++ b/include/images/statistics.pngc @@ -0,0 +1,141 @@ +#ifndef STATISTICS_PNG_H +#define STATISTICS_PNG_H + +static const unsigned char statistics_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x7a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa9, 0xc0, 0xda, 0x72, +0x98, 0xc2, 0x4b, 0x7b, 0xb1, 0x4c, 0x7d, 0xb3, +0x7c, 0xa3, 0xcc, 0x99, 0xbd, 0xe0, 0xa6, 0xcb, +0xec, 0xa5, 0xc9, 0xec, 0x97, 0xba, 0xde, 0x7a, +0xa1, 0xcb, 0x4b, 0x7c, 0xb3, 0xc8, 0xd7, 0xe7, +0x5c, 0x8a, 0xbb, 0x96, 0xbb, 0xde, 0x9b, 0xc8, +0xef, 0x89, 0xbd, 0xec, 0x81, 0xb7, 0xea, 0x7f, +0xb4, 0xe8, 0x84, 0xb6, 0xe8, 0x94, 0xbe, 0xeb, +0x91, 0xb4, 0xdb, 0x5b, 0x88, 0xbb, 0x96, 0xba, +0xde, 0x92, 0xc3, 0xee, 0x80, 0xb8, 0xea, 0x7b, +0xb3, 0xe9, 0x79, 0xb1, 0xe7, 0x77, 0xae, 0xe6, +0x75, 0xab, 0xe5, 0x76, 0xaa, 0xe4, 0x87, 0xb3, +0xe7, 0x90, 0xb2, 0xda, 0x4b, 0x7b, 0xb2, 0x7f, +0xb8, 0xea, 0x7b, 0xb3, 0xe8, 0x79, 0xb0, 0xe7, +0x73, 0xa8, 0xe3, 0x70, 0xa5, 0xe2, 0x71, 0xa4, +0xe2, 0x8d, 0xb4, 0xe6, 0x78, 0x9e, 0xca, 0x88, +0xbc, 0xeb, 0x7a, 0xb3, 0xe8, 0x77, 0xad, 0xe6, +0x74, 0xa9, 0xda, 0x72, 0xa7, 0xe3, 0x70, 0xa4, +0xe2, 0x6e, 0xa1, 0xe1, 0x6c, 0x9e, 0xdf, 0x78, +0xa4, 0xe1, 0x91, 0xb1, 0xdb, 0xa5, 0xca, 0xec, +0x80, 0xb6, 0xe9, 0x78, 0xb0, 0xe7, 0x76, 0xad, +0xe6, 0x74, 0xa9, 0xd9, 0x77, 0xa3, 0x2e, 0x70, +0x9e, 0x26, 0x70, 0x9e, 0x3a, 0x6f, 0x9e, 0x4b, +0x6e, 0x9d, 0x65, 0x6f, 0x9d, 0x70, 0x89, 0xae, +0x98, 0xa5, 0xc8, 0xeb, 0x7e, 0xb3, 0xe8, 0x74, +0xaa, 0xe4, 0x71, 0xa3, 0x93, 0xa0, 0xc1, 0x62, +0xd6, 0xea, 0x97, 0xc2, 0xde, 0x77, 0xbe, 0xd9, +0x7c, 0xb4, 0xd1, 0x76, 0xb2, 0xcf, 0x7c, 0x9d, +0xbf, 0x62, 0x5a, 0x89, 0x7a, 0x83, 0xb5, 0xe8, +0x70, 0xa4, 0xd5, 0x78, 0xa4, 0x30, 0xc7, 0xe2, +0x76, 0xb1, 0xd9, 0x44, 0xb2, 0xd8, 0x49, 0xb4, +0xd9, 0x54, 0xbd, 0xde, 0x6f, 0xbf, 0xd8, 0x90, +0x70, 0x9c, 0x52, 0x7a, 0xa0, 0xcb, 0x93, 0xbc, +0xea, 0x75, 0xa8, 0xe4, 0x6f, 0xa3, 0xe1, 0x6d, +0xa0, 0xe0, 0x6e, 0x9e, 0x63, 0xb6, 0xd2, 0x78, +0xb5, 0xda, 0x51, 0xab, 0xd5, 0x41, 0xac, 0xd6, +0x4a, 0xbd, 0xdf, 0x74, 0xa1, 0xc2, 0x69, 0x90, +0xb1, 0x8b, 0x91, 0xb3, 0xdb, 0x86, 0xb1, 0xe6, +0x70, 0xa2, 0xe1, 0x6b, 0x9d, 0xdf, 0x6b, 0x9b, +0xa5, 0x92, 0xb7, 0x52, 0xbe, 0xde, 0x6b, 0xad, +0xd6, 0x4c, 0xb7, 0xdc, 0x67, 0xb6, 0xd2, 0x80, +0x7d, 0xa7, 0x38, 0x5b, 0x87, 0xbb, 0x8f, 0xb1, +0xda, 0x8c, 0xb3, 0xe5, 0x77, 0xa4, 0xe0, 0x6d, +0x9b, 0xdc, 0x71, 0x9f, 0x28, 0xc9, 0xe2, 0x90, +0xc1, 0xe0, 0x7b, 0x89, 0xb0, 0x48, 0xb0, 0xc7, +0xb1, 0x78, 0x9d, 0xca, 0x90, 0xb0, 0xda, 0x99, +0xb7, 0xe4, 0x84, 0xaa, 0x83, 0x9d, 0xbf, 0x63, +0x72, 0x9a, 0x83, 0x9e, 0xb2, 0x87, 0xe4, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xbe, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x0a, 0x18, +0x99, 0x98, 0x99, 0x99, 0x18, 0x11, 0x7c, 0x16, +0x56, 0x36, 0x76, 0x0e, 0x4e, 0x2e, 0x6e, 0x28, +0x97, 0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, 0x48, +0x58, 0x44, 0x54, 0x8c, 0x07, 0x22, 0x2f, 0x2e, +0x21, 0x29, 0x25, 0x2d, 0x23, 0x2b, 0x27, 0xaf, +0xa0, 0x08, 0xd6, 0xcf, 0xca, 0xaf, 0xa4, 0xac, +0x22, 0x23, 0xab, 0xaa, 0xa6, 0xae, 0xa1, 0x09, +0x32, 0x87, 0x89, 0x4d, 0x4b, 0x5b, 0x45, 0x47, +0x57, 0x4f, 0xdf, 0xc0, 0xd0, 0xc8, 0x98, 0x09, +0x28, 0xc0, 0x6c, 0x62, 0x6a, 0x66, 0x6e, 0x61, +0x69, 0x65, 0x6d, 0x63, 0x6b, 0x67, 0xcf, 0x0c, +0x12, 0x70, 0x70, 0x34, 0x77, 0x72, 0x76, 0x71, +0x75, 0x73, 0xf7, 0xf0, 0xf4, 0xf2, 0x06, 0x69, +0xe1, 0xf4, 0x71, 0xd2, 0xf3, 0xf5, 0xf3, 0x0f, +0x08, 0x0c, 0x0a, 0x0e, 0x09, 0x05, 0x19, 0x1a, +0x16, 0x1e, 0x11, 0x19, 0x15, 0x1d, 0x13, 0x1b, +0x17, 0x9f, 0x90, 0x98, 0x04, 0xb2, 0x86, 0x3b, +0x39, 0x25, 0x35, 0x2d, 0x3d, 0x23, 0x33, 0x2b, +0x3b, 0x27, 0x17, 0xe2, 0xb2, 0xbc, 0xfc, 0x82, +0xc2, 0xa2, 0xe2, 0x92, 0xd2, 0x9c, 0xb2, 0x72, +0xa8, 0x53, 0x15, 0x2b, 0x2a, 0xab, 0xaa, 0x6b, +0x12, 0x73, 0xcb, 0x51, 0x3c, 0x57, 0x9b, 0x84, +0xdd, 0xe3, 0x00, 0xca, 0x32, 0x22, 0x67, 0xab, +0x15, 0xa0, 0xb1, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *statistics_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_statistics_png = new wxImage(); + if (!img_statistics_png || !img_statistics_png->IsOk()) + { + wxMemoryInputStream img_statistics_pngIS(statistics_png_data, sizeof(statistics_png_data)); + img_statistics_png->LoadFile(img_statistics_pngIS, wxBITMAP_TYPE_PNG); + } + return img_statistics_png; +} +#define statistics_png_img statistics_png_img() + +static wxBitmap *statistics_png_bmp() +{ + static wxBitmap *bmp_statistics_png; + if (!bmp_statistics_png || !bmp_statistics_png->IsOk()) + bmp_statistics_png = new wxBitmap(*statistics_png_img); + return bmp_statistics_png; +} +#define statistics_png_bmp statistics_png_bmp() + +static wxIcon *statistics_png_ico() +{ + static wxIcon *ico_statistics_png; + if (!ico_statistics_png || !ico_statistics_png->IsOk()) + { + ico_statistics_png = new wxIcon(); + ico_statistics_png->CopyFromBitmap(*statistics_png_bmp); + } + return ico_statistics_png; +} +#define statistics_png_ico statistics_png_ico() + +#endif // STATISTICS_PNG_H diff --git a/include/images/step.png b/include/images/step.png new file mode 100644 index 0000000..72f898a Binary files /dev/null and b/include/images/step.png differ diff --git a/include/images/step.pngc b/include/images/step.pngc new file mode 100644 index 0000000..3b580c1 --- /dev/null +++ b/include/images/step.pngc @@ -0,0 +1,98 @@ +#ifndef STEP_PNG_H +#define STEP_PNG_H + +static const unsigned char step_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x69, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x7e, 0x7f, 0x80, 0xff, +0xff, 0xff, 0xfd, 0xfe, 0xff, 0xf9, 0xfd, 0xfe, +0xf6, 0xfb, 0xfd, 0xf2, 0xfa, 0xfc, 0xed, 0xf8, +0xfc, 0xe9, 0xf6, 0xfb, 0xe4, 0xf4, 0xfa, 0xde, +0xf2, 0xf9, 0x1e, 0x50, 0xad, 0xd9, 0xf0, 0xf8, +0xd3, 0xed, 0xf6, 0xf2, 0x82, 0x82, 0xee, 0x7a, +0x7a, 0xe9, 0x6e, 0x6f, 0xe3, 0x60, 0x61, 0xdd, +0x51, 0x51, 0xd5, 0x41, 0x41, 0xce, 0x31, 0x31, +0xc8, 0x22, 0x22, 0xc2, 0x14, 0x14, 0xbd, 0x08, +0x08, 0xce, 0xeb, 0xf5, 0xc9, 0xe9, 0xf4, 0xb9, +0x00, 0x00, 0xc3, 0xe7, 0xf3, 0xbe, 0xe5, 0xf2, +0xba, 0xe3, 0xf1, 0xb5, 0xe1, 0xf1, 0xb1, 0xdf, +0xf0, 0xae, 0xde, 0xef, 0xaa, 0xdd, 0xee, 0xa8, +0xdc, 0xee, 0x71, 0xe5, 0x45, 0x7c, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x6f, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, +0x8f, 0x47, 0x12, 0x80, 0x20, 0x0c, 0x00, 0x01, +0x15, 0x4b, 0xc4, 0xde, 0x1b, 0xea, 0xff, 0x1f, +0xa9, 0x40, 0xe2, 0xa8, 0x7b, 0xdc, 0x85, 0x64, +0xc2, 0x18, 0xe3, 0x2f, 0x98, 0x81, 0x0b, 0xe1, +0xf9, 0x81, 0x0c, 0xa3, 0x38, 0x21, 0x01, 0x3e, +0x58, 0x52, 0x14, 0xd4, 0x53, 0x65, 0x45, 0x66, +0xc8, 0x8b, 0xb2, 0xaa, 0x9b, 0xb6, 0xeb, 0x8d, +0xe0, 0xd4, 0x87, 0x91, 0x4f, 0x56, 0x48, 0x88, +0xdc, 0x8c, 0x19, 0x05, 0xf5, 0x79, 0x71, 0xe2, +0xf9, 0x3f, 0xdd, 0xd8, 0x2d, 0xd4, 0xd7, 0x0d, +0xd7, 0x26, 0xa0, 0xdc, 0x0c, 0x8d, 0x82, 0xba, +0xde, 0x51, 0x28, 0x18, 0xdd, 0x8b, 0x03, 0x05, +0xf5, 0xe3, 0x44, 0xf1, 0xbf, 0xf6, 0xcb, 0x05, +0x92, 0x88, 0x09, 0x33, 0x39, 0x74, 0x34, 0xc3, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *step_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_step_png = new wxImage(); + if (!img_step_png || !img_step_png->IsOk()) + { + wxMemoryInputStream img_step_pngIS(step_png_data, sizeof(step_png_data)); + img_step_png->LoadFile(img_step_pngIS, wxBITMAP_TYPE_PNG); + } + return img_step_png; +} +#define step_png_img step_png_img() + +static wxBitmap *step_png_bmp() +{ + static wxBitmap *bmp_step_png; + if (!bmp_step_png || !bmp_step_png->IsOk()) + bmp_step_png = new wxBitmap(*step_png_img); + return bmp_step_png; +} +#define step_png_bmp step_png_bmp() + +static wxIcon *step_png_ico() +{ + static wxIcon *ico_step_png; + if (!ico_step_png || !ico_step_png->IsOk()) + { + ico_step_png = new wxIcon(); + ico_step_png->CopyFromBitmap(*step_png_bmp); + } + return ico_step_png; +} +#define step_png_ico step_png_ico() + +#endif // STEP_PNG_H diff --git a/include/images/stepInto.png b/include/images/stepInto.png new file mode 100644 index 0000000..49d729b Binary files /dev/null and b/include/images/stepInto.png differ diff --git a/include/images/stepInto.pngc b/include/images/stepInto.pngc new file mode 100644 index 0000000..43f04fa --- /dev/null +++ b/include/images/stepInto.pngc @@ -0,0 +1,76 @@ +#ifndef STEPINTO_PNG_H +#define STEPINTO_PNG_H + +static const unsigned char stepInto_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x02, 0x03, 0x00, 0x00, 0x00, 0x62, 0x9d, 0x17, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, +0x00, 0x00, 0x5d, 0x66, 0xef, 0x31, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x2b, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x00, 0x01, 0xd1, 0x50, +0x20, 0x21, 0x00, 0x62, 0x09, 0x70, 0xad, 0x5a, +0x01, 0x65, 0x39, 0x80, 0x58, 0x01, 0x20, 0xd9, +0x10, 0x20, 0x8b, 0x01, 0xc4, 0x62, 0x00, 0x89, +0x41, 0x00, 0x17, 0x9c, 0x85, 0x02, 0x00, 0x88, +0x8e, 0x08, 0xf2, 0x5b, 0xe2, 0xff, 0x38, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *stepInto_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_stepInto_png = new wxImage(); + if (!img_stepInto_png || !img_stepInto_png->IsOk()) + { + wxMemoryInputStream img_stepInto_pngIS(stepInto_png_data, sizeof(stepInto_png_data)); + img_stepInto_png->LoadFile(img_stepInto_pngIS, wxBITMAP_TYPE_PNG); + } + return img_stepInto_png; +} +#define stepInto_png_img stepInto_png_img() + +static wxBitmap *stepInto_png_bmp() +{ + static wxBitmap *bmp_stepInto_png; + if (!bmp_stepInto_png || !bmp_stepInto_png->IsOk()) + bmp_stepInto_png = new wxBitmap(*stepInto_png_img); + return bmp_stepInto_png; +} +#define stepInto_png_bmp stepInto_png_bmp() + +static wxIcon *stepInto_png_ico() +{ + static wxIcon *ico_stepInto_png; + if (!ico_stepInto_png || !ico_stepInto_png->IsOk()) + { + ico_stepInto_png = new wxIcon(); + ico_stepInto_png->CopyFromBitmap(*stepInto_png_bmp); + } + return ico_stepInto_png; +} +#define stepInto_png_ico stepInto_png_ico() + +#endif // STEPINTO_PNG_H diff --git a/include/images/stepOver.png b/include/images/stepOver.png new file mode 100644 index 0000000..1b1d702 Binary files /dev/null and b/include/images/stepOver.png differ diff --git a/include/images/stepOver.pngc b/include/images/stepOver.pngc new file mode 100644 index 0000000..a91a0de --- /dev/null +++ b/include/images/stepOver.pngc @@ -0,0 +1,76 @@ +#ifndef STEPOVER_PNG_H +#define STEPOVER_PNG_H + +static const unsigned char stepOver_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x02, 0x03, 0x00, 0x00, 0x00, 0x62, 0x9d, 0x17, +0xf2, 0x00, 0x00, 0x00, 0x09, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, +0x00, 0x00, 0x5d, 0x66, 0xef, 0x31, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x27, 0x49, 0x44, 0x41, 0x54, +0x08, 0xd7, 0x63, 0x60, 0x00, 0x01, 0xd1, 0x50, +0x20, 0x21, 0x00, 0x62, 0x09, 0x70, 0xad, 0x5a, +0x41, 0x88, 0xe5, 0x00, 0x62, 0x05, 0x80, 0xb4, +0x85, 0x80, 0x04, 0x41, 0x2c, 0x06, 0x07, 0x06, +0x08, 0x00, 0x00, 0x54, 0x8d, 0x08, 0x04, 0x4b, +0xf5, 0xb9, 0x07, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *stepOver_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_stepOver_png = new wxImage(); + if (!img_stepOver_png || !img_stepOver_png->IsOk()) + { + wxMemoryInputStream img_stepOver_pngIS(stepOver_png_data, sizeof(stepOver_png_data)); + img_stepOver_png->LoadFile(img_stepOver_pngIS, wxBITMAP_TYPE_PNG); + } + return img_stepOver_png; +} +#define stepOver_png_img stepOver_png_img() + +static wxBitmap *stepOver_png_bmp() +{ + static wxBitmap *bmp_stepOver_png; + if (!bmp_stepOver_png || !bmp_stepOver_png->IsOk()) + bmp_stepOver_png = new wxBitmap(*stepOver_png_img); + return bmp_stepOver_png; +} +#define stepOver_png_bmp stepOver_png_bmp() + +static wxIcon *stepOver_png_ico() +{ + static wxIcon *ico_stepOver_png; + if (!ico_stepOver_png || !ico_stepOver_png->IsOk()) + { + ico_stepOver_png = new wxIcon(); + ico_stepOver_png->CopyFromBitmap(*stepOver_png_bmp); + } + return ico_stepOver_png; +} +#define stepOver_png_ico stepOver_png_ico() + +#endif // STEPOVER_PNG_H diff --git a/include/images/steps.png b/include/images/steps.png new file mode 100644 index 0000000..51b86a7 Binary files /dev/null and b/include/images/steps.png differ diff --git a/include/images/steps.pngc b/include/images/steps.pngc new file mode 100644 index 0000000..69b25b9 --- /dev/null +++ b/include/images/steps.pngc @@ -0,0 +1,108 @@ +#ifndef STEPS_PNG_H +#define STEPS_PNG_H + +static const unsigned char steps_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x93, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xa5, 0xa5, 0xa5, 0xf2, +0x82, 0x82, 0xf1, 0x7f, 0x80, 0xef, 0x7c, 0x7c, +0xee, 0x78, 0x78, 0xec, 0x74, 0x74, 0xea, 0x6f, +0x70, 0xe8, 0x6a, 0x6b, 0xe5, 0x65, 0x65, 0xe3, +0x5f, 0x60, 0xe0, 0x5a, 0x5a, 0xde, 0x54, 0x54, +0xdb, 0x4d, 0x4e, 0xd8, 0x47, 0x47, 0xd5, 0x41, +0x41, 0xff, 0xff, 0xff, 0xfd, 0xfe, 0xff, 0xf9, +0xfd, 0xfe, 0xf6, 0xfb, 0xfd, 0xf2, 0xfa, 0xfc, +0xed, 0xf8, 0xfc, 0xe9, 0xf6, 0xfb, 0xe4, 0xf4, +0xfa, 0xde, 0xf2, 0xf9, 0xd9, 0xf0, 0xf8, 0xd3, +0x3b, 0x3b, 0x1e, 0x50, 0xad, 0xd3, 0xed, 0xf6, +0xd0, 0x35, 0x35, 0xce, 0xeb, 0xf5, 0xcd, 0x2e, +0x2f, 0xcb, 0x28, 0x29, 0xc9, 0xe9, 0xf4, 0xc3, +0xe7, 0xf3, 0xc8, 0x23, 0x23, 0xbe, 0xe5, 0xf2, +0xc6, 0x1d, 0x1d, 0xba, 0xe3, 0xf1, 0xc3, 0x18, +0x18, 0xc1, 0x13, 0x13, 0xb5, 0xe1, 0xf1, 0xb1, +0xdf, 0xf0, 0xbf, 0x0e, 0x0e, 0xae, 0xde, 0xef, +0xbd, 0x0a, 0x0a, 0xaa, 0xdd, 0xee, 0xbc, 0x06, +0x06, 0xba, 0x03, 0x03, 0x83, 0xd8, 0x51, 0xf7, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x01, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, +0x0d, 0x2c, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x90, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x65, 0xcf, 0x6d, 0x13, 0x42, 0x50, 0x14, +0x04, 0xe0, 0xbb, 0x21, 0x84, 0x4a, 0x92, 0xb8, +0x5e, 0x2a, 0xa4, 0x42, 0xfa, 0xff, 0xbf, 0xae, +0x9d, 0xcc, 0x9d, 0x3b, 0xd5, 0x7e, 0x7c, 0x76, +0xf6, 0xcc, 0x1c, 0x21, 0xf0, 0x15, 0x21, 0xc4, +0xc2, 0x30, 0xad, 0xa5, 0xed, 0xb8, 0x2b, 0xcf, +0x0f, 0xd6, 0x1b, 0x82, 0x81, 0x6d, 0xb8, 0x8b, +0xf6, 0xf1, 0x21, 0x39, 0xa6, 0xc8, 0x08, 0x26, +0x42, 0x19, 0xc9, 0x4f, 0x72, 0x14, 0x04, 0x0b, +0xaa, 0xcf, 0x4b, 0x54, 0x04, 0xbd, 0xcf, 0x8a, +0xea, 0x44, 0xb0, 0xa1, 0xfa, 0xf3, 0x05, 0x35, +0xc1, 0x41, 0x2c, 0x93, 0xf9, 0x46, 0x83, 0x96, +0xe0, 0x42, 0xf5, 0xcd, 0x15, 0x1d, 0x41, 0xef, +0xeb, 0xb6, 0xbb, 0x11, 0x3c, 0xa8, 0xfe, 0xfe, +0x40, 0x4f, 0xf0, 0x91, 0xca, 0x72, 0xbe, 0x31, +0x60, 0x24, 0x04, 0x50, 0xfd, 0xf0, 0xc4, 0x44, +0xd0, 0xfb, 0x7e, 0x9c, 0x5e, 0x84, 0xbf, 0x6f, +0x7f, 0xf2, 0x06, 0xf7, 0xe9, 0x10, 0x17, 0x85, +0xb3, 0x98, 0x76, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *steps_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_steps_png = new wxImage(); + if (!img_steps_png || !img_steps_png->IsOk()) + { + wxMemoryInputStream img_steps_pngIS(steps_png_data, sizeof(steps_png_data)); + img_steps_png->LoadFile(img_steps_pngIS, wxBITMAP_TYPE_PNG); + } + return img_steps_png; +} +#define steps_png_img steps_png_img() + +static wxBitmap *steps_png_bmp() +{ + static wxBitmap *bmp_steps_png; + if (!bmp_steps_png || !bmp_steps_png->IsOk()) + bmp_steps_png = new wxBitmap(*steps_png_img); + return bmp_steps_png; +} +#define steps_png_bmp steps_png_bmp() + +static wxIcon *steps_png_ico() +{ + static wxIcon *ico_steps_png; + if (!ico_steps_png || !ico_steps_png->IsOk()) + { + ico_steps_png = new wxIcon(); + ico_steps_png->CopyFromBitmap(*steps_png_bmp); + } + return ico_steps_png; +} +#define steps_png_ico steps_png_ico() + +#endif // STEPS_PNG_H diff --git a/include/images/stop.png b/include/images/stop.png new file mode 100644 index 0000000..bea28d9 Binary files /dev/null and b/include/images/stop.png differ diff --git a/include/images/stop.pngc b/include/images/stop.pngc new file mode 100644 index 0000000..b6e7927 --- /dev/null +++ b/include/images/stop.pngc @@ -0,0 +1,107 @@ +#ifndef STOP_PNG_H +#define STOP_PNG_H + +static const unsigned char stop_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xc3, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0x8d, 0x5f, 0xbf, +0x5e, 0x10, 0xe9, 0xd0, 0xa6, 0xe3, 0xc0, 0x86, +0xe4, 0xbf, 0x83, 0xe6, 0xbe, 0x7e, 0xe8, 0xbc, +0x7a, 0xe9, 0xba, 0x75, 0xec, 0xb9, 0x70, 0xf2, +0xc8, 0x8f, 0xe3, 0xc0, 0x85, 0xdc, 0xa9, 0x58, +0xde, 0xa7, 0x52, 0xe0, 0xa5, 0x4c, 0xe3, 0xa3, +0x46, 0xe6, 0xa0, 0x3f, 0xe9, 0x9e, 0x37, 0xf1, +0xb4, 0x64, 0xe5, 0xbf, 0x81, 0xe1, 0xa5, 0x4b, +0xe3, 0xa2, 0x45, 0xe6, 0xa0, 0x3e, 0xe9, 0x9d, +0x36, 0xec, 0x9b, 0x2f, 0xf3, 0xb2, 0x5d, 0xe6, +0xbd, 0x7d, 0xe1, 0xa5, 0x4a, 0xe4, 0xa2, 0x44, +0xe7, 0xa0, 0x3c, 0xea, 0x9d, 0x35, 0xed, 0x9a, +0x2e, 0xf0, 0x98, 0x26, 0xf5, 0xb0, 0x57, 0xe9, +0xbb, 0x77, 0xe4, 0xa2, 0x43, 0xe7, 0x9f, 0x3b, +0xea, 0x9d, 0x34, 0xed, 0x9a, 0x2d, 0xf0, 0x97, +0x25, 0xf3, 0x95, 0x1e, 0xf8, 0xad, 0x51, 0xec, +0xb9, 0x71, 0xe7, 0x9f, 0x3a, 0xea, 0x9c, 0x33, +0xed, 0x9a, 0x2b, 0xf0, 0x97, 0x24, 0xf3, 0x94, +0x1d, 0xf6, 0x92, 0x16, 0xfb, 0xac, 0x4c, 0xee, +0xb6, 0x6b, 0xeb, 0x9c, 0x32, 0xee, 0x99, 0x2a, +0xf1, 0x96, 0x23, 0xf4, 0x94, 0x1c, 0xf6, 0x92, +0x15, 0xf9, 0x8f, 0x0f, 0xfc, 0xaa, 0x47, 0xf4, +0xc7, 0x8b, 0xf2, 0xb3, 0x5f, 0xf5, 0xb0, 0x59, +0xf7, 0xaf, 0x54, 0xf9, 0xad, 0x4f, 0xfb, 0xab, +0x4a, 0xfe, 0xbd, 0x71, 0x9c, 0x0a, 0xd6, 0x59, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0x66, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x0b, +0x30, 0x32, 0x41, 0x01, 0x23, 0x54, 0x80, 0x89, +0x99, 0x85, 0x95, 0x8d, 0x9d, 0x83, 0x93, 0x8b, +0x09, 0x26, 0xc0, 0xcd, 0xc3, 0xcb, 0xc7, 0x2f, +0x20, 0x28, 0x04, 0x17, 0x10, 0xe6, 0x15, 0x11, +0x15, 0x13, 0x97, 0x90, 0x84, 0x0b, 0x48, 0x49, +0xcb, 0xc8, 0xca, 0xc9, 0x2b, 0x28, 0xc2, 0x05, +0x94, 0x94, 0x55, 0x54, 0xd5, 0xd4, 0x35, 0x34, +0xe1, 0x02, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, +0x06, 0x86, 0x70, 0x01, 0x23, 0x63, 0x13, 0x53, +0x33, 0x73, 0x0b, 0x4b, 0xb8, 0x80, 0x95, 0xb5, +0x8d, 0xad, 0x9d, 0xbd, 0xa5, 0x03, 0x13, 0x2e, +0x87, 0x91, 0x08, 0x00, 0xea, 0xbb, 0x08, 0xa8, +0x5b, 0xa9, 0x89, 0x69, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *stop_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_stop_png = new wxImage(); + if (!img_stop_png || !img_stop_png->IsOk()) + { + wxMemoryInputStream img_stop_pngIS(stop_png_data, sizeof(stop_png_data)); + img_stop_png->LoadFile(img_stop_pngIS, wxBITMAP_TYPE_PNG); + } + return img_stop_png; +} +#define stop_png_img stop_png_img() + +static wxBitmap *stop_png_bmp() +{ + static wxBitmap *bmp_stop_png; + if (!bmp_stop_png || !bmp_stop_png->IsOk()) + bmp_stop_png = new wxBitmap(*stop_png_img); + return bmp_stop_png; +} +#define stop_png_bmp stop_png_bmp() + +static wxIcon *stop_png_ico() +{ + static wxIcon *ico_stop_png; + if (!ico_stop_png || !ico_stop_png->IsOk()) + { + ico_stop_png = new wxIcon(); + ico_stop_png->CopyFromBitmap(*stop_png_bmp); + } + return ico_stop_png; +} +#define stop_png_ico stop_png_ico() + +#endif // STOP_PNG_H diff --git a/include/images/storedata.png b/include/images/storedata.png new file mode 100644 index 0000000..52da505 Binary files /dev/null and b/include/images/storedata.png differ diff --git a/include/images/storedata.pngc b/include/images/storedata.pngc new file mode 100644 index 0000000..d1023d6 --- /dev/null +++ b/include/images/storedata.pngc @@ -0,0 +1,124 @@ +#ifndef STOREDATA_PNG_H +#define STOREDATA_PNG_H + +static const unsigned char storedata_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x0e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x70, 0x92, 0xc5, 0x2c, +0x66, 0xbd, 0x9b, 0xd0, 0xe1, 0xf2, 0xf9, 0xfc, +0xe9, 0xf5, 0xfa, 0xe6, 0xf4, 0xfa, 0xe3, 0xf3, +0xf9, 0xde, 0xf1, 0xf9, 0xda, 0xf0, 0xf8, 0xe6, +0xf5, 0xfb, 0x9d, 0xc9, 0xe6, 0x7a, 0xbf, 0xd7, +0xb1, 0xb1, 0xb1, 0xcd, 0xec, 0xf7, 0x7d, 0xb6, +0xde, 0xe5, 0xf3, 0xfa, 0xd2, 0xec, 0xf6, 0xcb, +0xea, 0xf5, 0xc4, 0xe8, 0xf5, 0xbc, 0xe5, 0xf4, +0xb4, 0xe3, 0xf4, 0xad, 0xe1, 0xf3, 0xc5, 0xea, +0xf7, 0x7e, 0xb4, 0xe0, 0x7b, 0xbe, 0xd8, 0xbf, +0xe8, 0xf6, 0x7f, 0xb3, 0xe0, 0x7b, 0xbd, 0xd9, +0xe7, 0xf6, 0xfb, 0xd2, 0xee, 0xf8, 0xc8, 0xeb, +0xf7, 0xc4, 0xea, 0xf7, 0xc0, 0xe9, 0xf7, 0xbd, +0xe8, 0xf6, 0xd6, 0xf1, 0xfa, 0x7f, 0xb0, 0xe2, +0x7c, 0xbc, 0xda, 0x3b, 0x80, 0xc4, 0x3c, 0x7a, +0xc8, 0x80, 0xaf, 0xe3, 0x7c, 0xba, 0xda, 0x51, +0xa2, 0xcf, 0x51, 0xa0, 0xd1, 0x52, 0x9f, 0xd2, +0x52, 0x9d, 0xd3, 0x53, 0x9c, 0xd4, 0x53, 0x9a, +0xd5, 0x54, 0x99, 0xd6, 0x54, 0x97, 0xd7, 0x55, +0x95, 0xd8, 0x55, 0x94, 0xda, 0x80, 0xae, 0xe4, +0x7d, 0xb9, 0xdc, 0x52, 0x9e, 0xd2, 0x53, 0x9b, +0xd4, 0x54, 0x98, 0xd7, 0x54, 0x96, 0xd8, 0x55, +0x95, 0xd9, 0x55, 0x93, 0xda, 0x56, 0x92, 0xdb, +0x80, 0xad, 0xe5, 0x7d, 0xb7, 0xdd, 0x3c, 0x7c, +0xc6, 0x3d, 0x79, 0xc9, 0x56, 0x90, 0xdc, 0x81, +0xab, 0xe6, 0xe4, 0xf3, 0xf9, 0xdc, 0xf1, 0xf8, +0xe5, 0xf5, 0xfb, 0x56, 0x90, 0xdd, 0x57, 0x8f, +0xdd, 0x81, 0xaa, 0xe6, 0x94, 0xc1, 0xe4, 0x5e, +0xa0, 0xd8, 0xe7, 0xf4, 0xfa, 0xb6, 0xe4, 0xf4, +0xc7, 0xeb, 0xf7, 0x57, 0x8e, 0xde, 0x57, 0x8d, +0xde, 0x81, 0xa9, 0xe7, 0x94, 0xbe, 0xe6, 0xea, +0xf6, 0xfb, 0xd4, 0xef, 0xf8, 0xcb, 0xec, 0xf7, +0xc3, 0xea, 0xf7, 0xd8, 0xf1, 0xfa, 0x81, 0xaa, +0xe7, 0x82, 0xa9, 0xe7, 0xa1, 0xbd, 0xed, 0x07, +0x7f, 0x8b, 0xc1, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0xa5, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, +0xcf, 0xe5, 0x0e, 0xc2, 0x00, 0x0c, 0x04, 0x60, +0x76, 0x30, 0x1c, 0x86, 0xbb, 0x3b, 0x0c, 0x77, +0x77, 0x77, 0x97, 0xf7, 0x7f, 0x11, 0x46, 0x81, +0x84, 0xb0, 0xfb, 0xf9, 0xa5, 0x4d, 0x7b, 0x12, +0x89, 0x28, 0x0c, 0x7e, 0xc2, 0x08, 0x00, 0x29, +0x64, 0x2c, 0x2b, 0x57, 0x28, 0x55, 0x6a, 0x68, +0xf0, 0x02, 0x2d, 0x58, 0x1d, 0x45, 0x0f, 0xee, +0x03, 0x06, 0xa3, 0xc9, 0x6c, 0xb1, 0xda, 0xec, +0x70, 0x10, 0x38, 0xa1, 0x7c, 0x4f, 0xb8, 0xe0, +0x26, 0xf0, 0xc0, 0xeb, 0xd3, 0xfb, 0x03, 0xc1, +0x50, 0x18, 0x11, 0x82, 0x68, 0xec, 0x7b, 0x23, +0x9e, 0x20, 0x48, 0xa6, 0xf8, 0x74, 0x26, 0x9b, +0xcb, 0x17, 0x8a, 0xa5, 0x32, 0x41, 0x85, 0xaf, +0x66, 0x6a, 0xb9, 0x7a, 0xa3, 0xd9, 0x6a, 0x77, +0x08, 0xba, 0xd5, 0x1e, 0x2d, 0xf4, 0xdb, 0x83, +0x21, 0x01, 0x97, 0x15, 0x3e, 0x1b, 0x8d, 0x27, +0x98, 0xce, 0xe6, 0x04, 0x8b, 0x25, 0x56, 0x30, +0xaf, 0x37, 0xd8, 0xee, 0xf6, 0xa0, 0x2e, 0x07, +0x1c, 0x4f, 0xe7, 0xcb, 0x15, 0xb7, 0xfb, 0x03, +0xff, 0xed, 0x18, 0x71, 0xf9, 0x27, 0x79, 0x13, +0x12, 0x4f, 0xeb, 0x94, 0x1d, 0x51, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *storedata_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_storedata_png = new wxImage(); + if (!img_storedata_png || !img_storedata_png->IsOk()) + { + wxMemoryInputStream img_storedata_pngIS(storedata_png_data, sizeof(storedata_png_data)); + img_storedata_png->LoadFile(img_storedata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_storedata_png; +} +#define storedata_png_img storedata_png_img() + +static wxBitmap *storedata_png_bmp() +{ + static wxBitmap *bmp_storedata_png; + if (!bmp_storedata_png || !bmp_storedata_png->IsOk()) + bmp_storedata_png = new wxBitmap(*storedata_png_img); + return bmp_storedata_png; +} +#define storedata_png_bmp storedata_png_bmp() + +static wxIcon *storedata_png_ico() +{ + static wxIcon *ico_storedata_png; + if (!ico_storedata_png || !ico_storedata_png->IsOk()) + { + ico_storedata_png = new wxIcon(); + ico_storedata_png->CopyFromBitmap(*storedata_png_bmp); + } + return ico_storedata_png; +} +#define storedata_png_ico storedata_png_ico() + +#endif // STOREDATA_PNG_H diff --git a/include/images/synonym.png b/include/images/synonym.png new file mode 100644 index 0000000..aa2777c Binary files /dev/null and b/include/images/synonym.png differ diff --git a/include/images/synonym.pngc b/include/images/synonym.pngc new file mode 100644 index 0000000..12242fb --- /dev/null +++ b/include/images/synonym.pngc @@ -0,0 +1,104 @@ +#ifndef SYNONYM_PNG_H +#define SYNONYM_PNG_H + +static const unsigned char synonym_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xa8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9d, 0xc2, 0xce, 0x59, +0x97, 0xab, 0xc8, 0xfa, 0xff, 0xc1, 0xf8, 0xfe, +0xb8, 0xf5, 0xfd, 0xad, 0xf1, 0xfc, 0xa1, 0xed, +0xfa, 0x93, 0xe9, 0xf9, 0x85, 0xe4, 0xf7, 0x92, +0xb6, 0xba, 0xc7, 0xfa, 0xff, 0x6e, 0xb1, 0xe5, +0x35, 0x7f, 0xd3, 0x4f, 0xa6, 0xe1, 0x66, 0xd9, +0xf3, 0xc6, 0xfa, 0xff, 0xbe, 0xf7, 0xfe, 0xcb, +0xe7, 0xf6, 0xc4, 0xe2, 0xf4, 0xba, 0xdb, 0xf1, +0xaf, 0xd3, 0xee, 0xa4, 0xca, 0xeb, 0x55, 0xd4, +0xf1, 0x48, 0xcf, 0xf0, 0xc5, 0xf9, 0xff, 0x8a, +0xb4, 0xb9, 0xb3, 0xf3, 0xfc, 0x64, 0xad, 0xe3, +0x41, 0xa2, 0xdf, 0x46, 0xcf, 0xef, 0x3a, 0xcb, +0xee, 0x30, 0xc7, 0xed, 0xbb, 0xf6, 0xfd, 0xb1, +0xf3, 0xfc, 0xa5, 0xef, 0xfb, 0xbf, 0xdf, 0xf3, +0xb5, 0xd7, 0xf0, 0xa9, 0xcf, 0xec, 0x9e, 0xc6, +0xe9, 0x95, 0xc0, 0xe6, 0x38, 0xca, 0xee, 0x2e, +0xc7, 0xec, 0xaf, 0xf2, 0xfc, 0x77, 0xae, 0xb6, +0x96, 0xea, 0xf9, 0x57, 0xa9, 0xe2, 0x36, 0x9e, +0xde, 0x2d, 0xc6, 0xec, 0x77, 0xdf, 0xf5, 0x68, +0xda, 0xf3, 0x5a, 0xd6, 0xf2, 0x4c, 0xd1, 0xf0, +0x40, 0xcd, 0xef, 0x35, 0xc9, 0xed, 0x2b, 0xc6, +0xec, 0xcc, 0x03, 0xa5, 0x06, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x20, 0x1d, 0x30, 0x32, 0xc1, +0x01, 0x23, 0x58, 0x80, 0x89, 0x19, 0x08, 0x58, +0x58, 0xd9, 0xd8, 0x39, 0x38, 0x21, 0x22, 0x4c, +0xcc, 0x5c, 0xdc, 0x3c, 0xbc, 0x20, 0xc0, 0xc7, +0x0f, 0x16, 0x61, 0x62, 0x16, 0x10, 0xe4, 0x15, +0x12, 0x16, 0x11, 0x15, 0xe3, 0x15, 0x97, 0x00, +0x89, 0x30, 0x49, 0x4a, 0x49, 0xcb, 0x80, 0x55, +0xc8, 0xca, 0xc9, 0x2b, 0x30, 0x01, 0x05, 0x14, +0x95, 0x94, 0x79, 0x55, 0x54, 0xd5, 0xd4, 0x35, +0x78, 0x35, 0xb5, 0xc0, 0x2a, 0xb4, 0x75, 0x74, +0xf5, 0xc0, 0x2a, 0xf4, 0x0d, 0x20, 0x66, 0x00, +0x8d, 0x37, 0x34, 0x32, 0x36, 0x31, 0x35, 0x33, +0x87, 0xd8, 0x82, 0xe1, 0x0e, 0x2a, 0x00, 0x00, +0xc5, 0xaa, 0x07, 0x61, 0x1b, 0x7f, 0xec, 0x48, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *synonym_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_synonym_png = new wxImage(); + if (!img_synonym_png || !img_synonym_png->IsOk()) + { + wxMemoryInputStream img_synonym_pngIS(synonym_png_data, sizeof(synonym_png_data)); + img_synonym_png->LoadFile(img_synonym_pngIS, wxBITMAP_TYPE_PNG); + } + return img_synonym_png; +} +#define synonym_png_img synonym_png_img() + +static wxBitmap *synonym_png_bmp() +{ + static wxBitmap *bmp_synonym_png; + if (!bmp_synonym_png || !bmp_synonym_png->IsOk()) + bmp_synonym_png = new wxBitmap(*synonym_png_img); + return bmp_synonym_png; +} +#define synonym_png_bmp synonym_png_bmp() + +static wxIcon *synonym_png_ico() +{ + static wxIcon *ico_synonym_png; + if (!ico_synonym_png || !ico_synonym_png->IsOk()) + { + ico_synonym_png = new wxIcon(); + ico_synonym_png->CopyFromBitmap(*synonym_png_bmp); + } + return ico_synonym_png; +} +#define synonym_png_ico synonym_png_ico() + +#endif // SYNONYM_PNG_H diff --git a/include/images/synonyms.png b/include/images/synonyms.png new file mode 100644 index 0000000..7e5307f Binary files /dev/null and b/include/images/synonyms.png differ diff --git a/include/images/synonyms.pngc b/include/images/synonyms.pngc new file mode 100644 index 0000000..19db391 --- /dev/null +++ b/include/images/synonyms.pngc @@ -0,0 +1,100 @@ +#ifndef SYNONYMS_PNG_H +#define SYNONYMS_PNG_H + +static const unsigned char synonyms_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x7e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9d, 0xc2, 0xce, 0x59, +0x97, 0xab, 0xc8, 0xfa, 0xff, 0xc1, 0xf8, 0xfe, +0xb9, 0xf5, 0xfd, 0xae, 0xf2, 0xfc, 0xa3, 0xee, +0xfb, 0x86, 0xc0, 0xce, 0x75, 0xa9, 0xb9, 0xc3, +0xf9, 0xfe, 0xb7, 0xf5, 0xfd, 0xa8, 0xf0, 0xfb, +0x96, 0xea, 0xf9, 0x71, 0xb2, 0xe5, 0x35, 0x7f, +0xd3, 0x5b, 0xaa, 0xe2, 0x83, 0xe3, 0xf7, 0xcb, +0xe7, 0xf6, 0xc4, 0xe2, 0xf4, 0xb9, 0xda, 0xf1, +0xae, 0xd2, 0xed, 0x70, 0xdd, 0xf4, 0x62, 0xd8, +0xf3, 0x66, 0xae, 0xe4, 0x4b, 0xa5, 0xe1, 0x5d, +0xd6, 0xf2, 0x50, 0xd2, 0xf0, 0x43, 0xce, 0xef, +0xa2, 0xc9, 0xea, 0x98, 0xc1, 0xe7, 0x4b, 0xd0, +0xf0, 0x3f, 0xcc, 0xee, 0x58, 0xa9, 0xe2, 0x3c, +0xa0, 0xdf, 0x3a, 0xcb, 0xee, 0x76, 0xdf, 0xf5, +0x68, 0xda, 0xf3, 0x5a, 0xd6, 0xf2, 0x4d, 0xd1, +0xf0, 0x41, 0xcd, 0xef, 0x36, 0xc9, 0xed, 0x3e, +0x02, 0x05, 0x28, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x79, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x7d, +0xcf, 0xdb, 0x0e, 0x82, 0x30, 0x10, 0x04, 0xd0, +0x32, 0x15, 0x04, 0x11, 0xd7, 0x62, 0x51, 0x11, +0x94, 0xab, 0xb7, 0xff, 0xff, 0x41, 0xba, 0x16, +0xfa, 0x50, 0x13, 0xe6, 0x71, 0x72, 0xb2, 0x99, +0x15, 0xc2, 0x4f, 0x00, 0x9b, 0x60, 0x29, 0x20, +0xa5, 0xdc, 0x84, 0xd1, 0xd6, 0x35, 0x90, 0xf1, +0x6c, 0x92, 0xb9, 0xd8, 0x39, 0x63, 0x1b, 0xa4, +0x9e, 0xc1, 0xde, 0x33, 0xc8, 0xd8, 0x1c, 0xc8, +0xe4, 0xa8, 0xf8, 0x32, 0x14, 0x1b, 0xca, 0x4f, +0xba, 0xa0, 0xf3, 0xc5, 0x34, 0x66, 0x87, 0x31, +0x57, 0x16, 0xe5, 0xad, 0xaa, 0x21, 0xac, 0x21, +0x5d, 0xdc, 0x1f, 0xd4, 0xb4, 0xbf, 0x35, 0x6c, +0x3a, 0x16, 0xfd, 0xb0, 0xac, 0x83, 0x1a, 0x9f, +0xaf, 0xf7, 0xe7, 0xeb, 0xd6, 0xfe, 0xfd, 0xb3, +0x9a, 0x09, 0xa0, 0xee, 0x05, 0xe8, 0xc0, 0xe8, +0xac, 0xca, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *synonyms_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_synonyms_png = new wxImage(); + if (!img_synonyms_png || !img_synonyms_png->IsOk()) + { + wxMemoryInputStream img_synonyms_pngIS(synonyms_png_data, sizeof(synonyms_png_data)); + img_synonyms_png->LoadFile(img_synonyms_pngIS, wxBITMAP_TYPE_PNG); + } + return img_synonyms_png; +} +#define synonyms_png_img synonyms_png_img() + +static wxBitmap *synonyms_png_bmp() +{ + static wxBitmap *bmp_synonyms_png; + if (!bmp_synonyms_png || !bmp_synonyms_png->IsOk()) + bmp_synonyms_png = new wxBitmap(*synonyms_png_img); + return bmp_synonyms_png; +} +#define synonyms_png_bmp synonyms_png_bmp() + +static wxIcon *synonyms_png_ico() +{ + static wxIcon *ico_synonyms_png; + if (!ico_synonyms_png || !ico_synonyms_png->IsOk()) + { + ico_synonyms_png = new wxIcon(); + ico_synonyms_png->CopyFromBitmap(*synonyms_png_bmp); + } + return ico_synonyms_png; +} +#define synonyms_png_ico synonyms_png_ico() + +#endif // SYNONYMS_PNG_H diff --git a/include/images/table-repl-sm.png b/include/images/table-repl-sm.png new file mode 100644 index 0000000..967bd93 Binary files /dev/null and b/include/images/table-repl-sm.png differ diff --git a/include/images/table-repl-sm.pngc b/include/images/table-repl-sm.pngc new file mode 100644 index 0000000..579a13a --- /dev/null +++ b/include/images/table-repl-sm.pngc @@ -0,0 +1,129 @@ +#ifndef TABLE_REPL_SM_PNG_H +#define TABLE_REPL_SM_PNG_H + +static const unsigned char table_repl_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x32, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, +0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, 0x49, +0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, 0xeb, +0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, 0xab, +0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, 0xb3, +0xd5, 0xed, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, +0xdf, 0xdf, 0xdf, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, +0xe3, 0xe5, 0xe5, 0xe5, 0x87, 0xc0, 0xe7, 0x92, +0xaa, 0x43, 0xb0, 0xd6, 0x6f, 0xc8, 0xd1, 0xae, +0xe3, 0xe3, 0xdf, 0xa7, 0xa9, 0xa3, 0xd9, 0xdb, +0xd3, 0xac, 0xac, 0xac, 0xec, 0xec, 0xec, 0xee, +0xee, 0xee, 0xe9, 0xe9, 0xe9, 0x94, 0xae, 0x47, +0xb0, 0xdb, 0x74, 0xaa, 0xd7, 0x6e, 0x95, 0xa9, +0x4c, 0x8b, 0xa3, 0x3a, 0x8f, 0xb5, 0x46, 0xad, +0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, +0x48, 0x82, 0xbe, 0x37, 0x8a, 0xcf, 0x66, 0x93, +0x7a, 0x8d, 0xb7, 0x54, 0x97, 0xc9, 0x5a, 0x92, +0xc9, 0x58, 0x87, 0xb2, 0x3e, 0xe7, 0xe7, 0xe7, +0xeb, 0xeb, 0xeb, 0x73, 0xc6, 0xdf, 0x71, 0xc4, +0xde, 0x6e, 0xc0, 0xdd, 0x5d, 0xa3, 0xc9, 0x77, +0x9f, 0x4c, 0x8d, 0xc7, 0x55, 0x86, 0xc1, 0x4d, +0x7f, 0xad, 0x37, 0xef, 0xef, 0xef, 0xf1, 0xf1, +0xf1, 0xed, 0xed, 0xed, 0x70, 0xc3, 0xde, 0x6d, +0xbf, 0xdc, 0x54, 0x97, 0xc8, 0x67, 0x97, 0x77, +0x87, 0xc0, 0x4e, 0x81, 0xbc, 0x46, 0x7b, 0xb8, +0x41, 0x7a, 0xa9, 0x31, 0xb0, 0xb0, 0xb0, 0xb2, +0xb2, 0xb2, 0x6c, 0xbe, 0xdc, 0x52, 0x93, 0xc6, +0x57, 0x9c, 0xcb, 0x59, 0xa0, 0xca, 0xaf, 0xc0, +0xb6, 0xcd, 0xd3, 0xba, 0xce, 0xd4, 0xba, 0xcf, +0xd5, 0xbb, 0xf0, 0xf0, 0xf0, 0x6f, 0x9c, 0xcc, +0x65, 0x9d, 0xcc, 0x8b, 0xaf, 0xd6, 0x5d, 0x9a, +0xca, 0x5d, 0xa9, 0xd2, 0x52, 0x96, 0xc8, 0x69, +0xae, 0xe5, 0x6f, 0xc0, 0xf8, 0x28, 0x99, 0xe8, +0x5a, 0x92, 0xc6, 0x81, 0x48, 0xda, 0xd2, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0xa8, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x06, 0x30, +0x22, 0x01, 0x88, 0x00, 0x13, 0x33, 0x0b, 0x2b, +0x1b, 0x3b, 0x07, 0x07, 0x27, 0x17, 0x37, 0x44, +0x80, 0x87, 0x97, 0x8f, 0x5f, 0x40, 0x50, 0x48, +0x58, 0x44, 0x14, 0xaa, 0x82, 0x47, 0x0c, 0x24, +0x20, 0x2e, 0x21, 0x22, 0x09, 0x15, 0x90, 0x92, +0x96, 0x96, 0x91, 0x95, 0x93, 0x57, 0xe0, 0x50, +0x84, 0x08, 0x28, 0x29, 0xab, 0xa8, 0xaa, 0xa9, +0xcb, 0x6b, 0x68, 0x6a, 0x69, 0x43, 0x04, 0x74, +0x74, 0xf5, 0xf4, 0x0d, 0x0c, 0x15, 0x34, 0x8c, +0x8c, 0x4d, 0x80, 0x02, 0xa6, 0xa6, 0xa6, 0x66, +0xe6, 0x16, 0x96, 0x56, 0xd6, 0x1c, 0x36, 0xda, +0x26, 0xb6, 0x20, 0x01, 0x3b, 0x7b, 0x07, 0x47, +0x27, 0x67, 0x17, 0x57, 0x1b, 0x63, 0x37, 0x77, +0x0f, 0x90, 0x80, 0xa7, 0x97, 0xb7, 0x8f, 0xaf, +0x9f, 0x7f, 0x80, 0xb6, 0x71, 0x60, 0x90, 0x16, +0x48, 0x20, 0x38, 0x24, 0x34, 0x2c, 0x3c, 0x22, +0x32, 0xca, 0x56, 0xd3, 0x43, 0x2b, 0x1a, 0x28, +0x10, 0x13, 0x1b, 0x17, 0x9f, 0x90, 0x98, 0x94, +0x0c, 0x76, 0x47, 0x0a, 0xc4, 0x16, 0x86, 0xd4, +0x54, 0x3c, 0x3e, 0x05, 0x00, 0x3f, 0xf2, 0x19, +0x31, 0xc9, 0xd8, 0x4c, 0x62, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_repl_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_repl_sm_png = new wxImage(); + if (!img_table_repl_sm_png || !img_table_repl_sm_png->IsOk()) + { + wxMemoryInputStream img_table_repl_sm_pngIS(table_repl_sm_png_data, sizeof(table_repl_sm_png_data)); + img_table_repl_sm_png->LoadFile(img_table_repl_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_repl_sm_png; +} +#define table_repl_sm_png_img table_repl_sm_png_img() + +static wxBitmap *table_repl_sm_png_bmp() +{ + static wxBitmap *bmp_table_repl_sm_png; + if (!bmp_table_repl_sm_png || !bmp_table_repl_sm_png->IsOk()) + bmp_table_repl_sm_png = new wxBitmap(*table_repl_sm_png_img); + return bmp_table_repl_sm_png; +} +#define table_repl_sm_png_bmp table_repl_sm_png_bmp() + +static wxIcon *table_repl_sm_png_ico() +{ + static wxIcon *ico_table_repl_sm_png; + if (!ico_table_repl_sm_png || !ico_table_repl_sm_png->IsOk()) + { + ico_table_repl_sm_png = new wxIcon(); + ico_table_repl_sm_png->CopyFromBitmap(*table_repl_sm_png_bmp); + } + return ico_table_repl_sm_png; +} +#define table_repl_sm_png_ico table_repl_sm_png_ico() + +#endif // TABLE_REPL_SM_PNG_H diff --git a/include/images/table-repl.png b/include/images/table-repl.png new file mode 100644 index 0000000..2a082c6 Binary files /dev/null and b/include/images/table-repl.png differ diff --git a/include/images/table-repl.pngc b/include/images/table-repl.pngc new file mode 100644 index 0000000..a873c8e --- /dev/null +++ b/include/images/table-repl.pngc @@ -0,0 +1,149 @@ +#ifndef TABLE_REPL_PNG_H +#define TABLE_REPL_PNG_H + +static const unsigned char table_repl_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0xa1, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8d, +0xd0, 0xff, 0x92, 0xcf, 0xfb, 0xa2, 0xd3, 0xf5, +0xba, 0xd8, 0xed, 0xd1, 0xdf, 0xe9, 0xdf, 0xe3, +0xe7, 0xe5, 0xe6, 0xe7, 0xe6, 0xe6, 0xe6, 0xda, +0xe1, 0xe5, 0xac, 0xce, 0xe7, 0x63, 0xb1, 0xe8, +0x2e, 0x9b, 0xe8, 0x8b, 0xcf, 0xff, 0x85, 0xcc, +0xfe, 0x7e, 0xc8, 0xfc, 0x75, 0xc3, 0xfa, 0x6c, +0xbe, 0xf8, 0x61, 0xb8, 0xf6, 0x56, 0xb2, 0xf3, +0x4b, 0xac, 0xf0, 0x40, 0xa7, 0xee, 0x37, 0xa0, +0xec, 0x2d, 0x9c, 0xea, 0x26, 0x98, 0xe9, 0x85, +0xcc, 0xfd, 0x6b, 0xbe, 0xf8, 0x41, 0xa6, 0xee, +0x36, 0xa1, 0xec, 0x2e, 0x9c, 0xea, 0xb4, 0xd6, +0xee, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdf, +0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, +0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, +0xe5, 0x87, 0xbf, 0xe7, 0xe8, 0xe8, 0xe8, 0xe9, +0xe9, 0xe9, 0xb2, 0xc1, 0x7f, 0x9d, 0xbd, 0x53, +0x8d, 0xa9, 0x3a, 0xa9, 0xa9, 0xa9, 0xe4, 0xe4, +0xe4, 0xac, 0xac, 0xac, 0xec, 0xec, 0xec, 0xed, +0xed, 0xed, 0xef, 0xef, 0xef, 0xea, 0xea, 0xea, +0x90, 0xa9, 0x41, 0x9f, 0xc2, 0x56, 0xb2, 0xdc, +0x76, 0x91, 0xaf, 0x43, 0xa7, 0xb3, 0x82, 0xa6, +0xb8, 0x68, 0x8e, 0xad, 0x42, 0xa3, 0xb6, 0x62, +0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xeb, 0xeb, +0xeb, 0xd0, 0xd5, 0xbf, 0xaa, 0xbd, 0x77, 0xa9, +0xd6, 0x6e, 0x8e, 0xb2, 0x40, 0x92, 0xb2, 0x47, +0x90, 0xbd, 0x4c, 0x8e, 0xbd, 0x4b, 0x7e, 0x99, +0x22, 0x48, 0x82, 0xbe, 0x4d, 0x8a, 0xc1, 0x4c, +0x89, 0xc1, 0x58, 0x89, 0x8f, 0x9b, 0xcd, 0x60, +0x96, 0xcd, 0x5e, 0x8f, 0xc8, 0x56, 0x86, 0xb7, +0x43, 0xf0, 0xf0, 0xf0, 0xf2, 0xf2, 0xf2, 0xee, +0xee, 0xee, 0x73, 0xc6, 0xdf, 0x71, 0xc4, 0xde, +0x6e, 0xc1, 0xdd, 0x64, 0xb0, 0xd4, 0x54, 0x8a, +0xa4, 0x88, 0xb5, 0x42, 0x8a, 0xc5, 0x52, 0x84, +0xc0, 0x4b, 0x7f, 0xb2, 0x3c, 0xb1, 0xb1, 0xb1, +0xb2, 0xb2, 0xb2, 0x70, 0xc4, 0xde, 0x6e, 0xc0, +0xdd, 0x68, 0xb8, 0xd9, 0x52, 0x87, 0xa3, 0x81, +0xb8, 0x5d, 0x86, 0xc1, 0x4d, 0x81, 0xbe, 0x48, +0x7b, 0xba, 0x42, 0x79, 0xaf, 0x36, 0xf1, 0xf1, +0xf1, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, 0xf5, 0x63, +0xae, 0xd4, 0x67, 0xb7, 0xd9, 0x57, 0x9d, 0xcb, +0x55, 0x89, 0x9d, 0xa5, 0xb7, 0x6a, 0x8f, 0xa1, +0x54, 0xa4, 0xb7, 0x6a, 0x90, 0xa2, 0x55, 0xf6, +0xf6, 0xf6, 0xf8, 0xf8, 0xf8, 0x61, 0xac, 0xd3, +0x74, 0xa2, 0xcf, 0x50, 0x91, 0xc5, 0x5e, 0xab, +0xd3, 0x5a, 0xa5, 0xd0, 0x70, 0x94, 0xb9, 0xb5, +0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, +0xf7, 0xf7, 0xf7, 0x93, 0xb5, 0xd9, 0x63, 0x94, +0xc7, 0x39, 0x9b, 0xe3, 0x9a, 0xb9, 0xd9, 0x57, +0x97, 0xc9, 0x4e, 0x8d, 0xc4, 0x57, 0x9d, 0xcc, +0xab, 0xc3, 0xdb, 0x25, 0x96, 0xe6, 0x60, 0xa0, +0xd7, 0x56, 0x94, 0xc7, 0x6c, 0x9f, 0xd0, 0x35, +0x9a, 0xe4, 0x68, 0x2d, 0x4a, 0xf8, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xdd, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x60, 0x60, 0x44, 0x01, +0x0c, 0x40, 0x01, 0x26, 0x66, 0x16, 0x56, 0x36, +0x76, 0x0e, 0x4e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, +0x90, 0x00, 0x1f, 0xbf, 0x80, 0xa0, 0x90, 0xb0, +0x88, 0xa8, 0x98, 0xb8, 0x84, 0x24, 0x58, 0x05, +0x9f, 0x94, 0x80, 0xa0, 0x34, 0x50, 0x40, 0x46, +0x56, 0x0e, 0x22, 0x20, 0xaf, 0xa0, 0xa0, 0xa8, +0xa4, 0xac, 0xa2, 0xaa, 0xa6, 0xce, 0xa9, 0x01, +0x16, 0x40, 0xf0, 0x35, 0xb5, 0xc0, 0x02, 0xda, +0x3a, 0xba, 0x9a, 0x7a, 0xaa, 0xfa, 0x06, 0x86, +0x46, 0xc6, 0x26, 0x60, 0x01, 0x53, 0x33, 0x73, +0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x3b, +0x7b, 0xb0, 0x80, 0x83, 0xa3, 0x93, 0xb3, 0x8b, +0xab, 0x9b, 0xbb, 0x96, 0x89, 0xa1, 0x11, 0x23, +0x83, 0x87, 0xa7, 0x97, 0x97, 0x97, 0xb7, 0x8f, +0xaf, 0x9f, 0xbf, 0xbb, 0x71, 0x40, 0x60, 0x10, +0x50, 0x20, 0x38, 0x24, 0x34, 0x2c, 0x3c, 0x22, +0x32, 0x2a, 0xda, 0x3d, 0x26, 0x36, 0x36, 0x00, +0x28, 0x10, 0x17, 0x9f, 0x90, 0x98, 0x94, 0x9c, +0x92, 0x9a, 0xe6, 0x9e, 0x1e, 0x98, 0x91, 0x09, +0x14, 0x88, 0xcf, 0xca, 0xce, 0xc9, 0xcd, 0xcb, +0x2f, 0xc8, 0x2b, 0xcc, 0x2c, 0x2a, 0x2e, 0x02, +0x0a, 0x94, 0x94, 0x96, 0x95, 0x57, 0x54, 0xc6, +0x06, 0xa4, 0x57, 0x55, 0xd7, 0xd4, 0xd4, 0x32, +0x32, 0xd4, 0xd5, 0x37, 0x34, 0x36, 0x35, 0xb7, +0xb4, 0x82, 0xd4, 0x17, 0xd5, 0xd6, 0x82, 0xad, +0x6d, 0x6b, 0xef, 0xe8, 0xec, 0x82, 0x79, 0x1f, +0x00, 0x87, 0x5b, 0x32, 0xd2, 0x98, 0x92, 0x7c, +0x70, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_repl_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_repl_png = new wxImage(); + if (!img_table_repl_png || !img_table_repl_png->IsOk()) + { + wxMemoryInputStream img_table_repl_pngIS(table_repl_png_data, sizeof(table_repl_png_data)); + img_table_repl_png->LoadFile(img_table_repl_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_repl_png; +} +#define table_repl_png_img table_repl_png_img() + +static wxBitmap *table_repl_png_bmp() +{ + static wxBitmap *bmp_table_repl_png; + if (!bmp_table_repl_png || !bmp_table_repl_png->IsOk()) + bmp_table_repl_png = new wxBitmap(*table_repl_png_img); + return bmp_table_repl_png; +} +#define table_repl_png_bmp table_repl_png_bmp() + +static wxIcon *table_repl_png_ico() +{ + static wxIcon *ico_table_repl_png; + if (!ico_table_repl_png || !ico_table_repl_png->IsOk()) + { + ico_table_repl_png = new wxIcon(); + ico_table_repl_png->CopyFromBitmap(*table_repl_png_bmp); + } + return ico_table_repl_png; +} +#define table_repl_png_ico table_repl_png_ico() + +#endif // TABLE_REPL_PNG_H diff --git a/include/images/table-sm.png b/include/images/table-sm.png new file mode 100644 index 0000000..6a40e15 Binary files /dev/null and b/include/images/table-sm.png differ diff --git a/include/images/table-sm.pngc b/include/images/table-sm.pngc new file mode 100644 index 0000000..d44b7c5 --- /dev/null +++ b/include/images/table-sm.pngc @@ -0,0 +1,110 @@ +#ifndef TABLE_SM_PNG_H +#define TABLE_SM_PNG_H + +static const unsigned char table_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xb7, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, 0xc0, +0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, 0x49, +0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, 0xeb, +0x27, 0x99, 0xe9, 0x83, 0xcb, 0xfd, 0x4a, 0xab, +0xf0, 0x3d, 0xa4, 0xed, 0x28, 0x99, 0xe9, 0xb3, +0xd5, 0xed, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, +0xdf, 0xdf, 0xdf, 0xe2, 0xe2, 0xe2, 0xe3, 0xe3, +0xe3, 0xe5, 0xe5, 0xe5, 0x87, 0xc0, 0xe7, 0xa7, +0xa7, 0xa7, 0xe0, 0xe0, 0xe0, 0xac, 0xac, 0xac, +0xec, 0xec, 0xec, 0xee, 0xee, 0xee, 0xe9, 0xe9, +0xe9, 0xa6, 0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xe1, +0xe1, 0xe1, 0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, +0xea, 0xea, 0xea, 0xe7, 0xe7, 0xe7, 0xeb, 0xeb, +0xeb, 0xe8, 0xe8, 0xe8, 0xa9, 0xa9, 0xa9, 0xef, +0xef, 0xef, 0xf1, 0xf1, 0xf1, 0xed, 0xed, 0xed, +0xaa, 0xaa, 0xaa, 0xb0, 0xb0, 0xb0, 0xb2, 0xb2, +0xb2, 0xe4, 0xe4, 0xe4, 0xf0, 0xf0, 0xf0, 0x7b, +0xc6, 0xfb, 0x6f, 0xc0, 0xf8, 0x28, 0x99, 0xe8, +0x6c, 0x3a, 0xe1, 0xdf, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x8e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x8d, 0xcf, 0xc9, 0x12, 0x82, 0x30, 0x10, 0x04, +0x50, 0x70, 0x1d, 0x15, 0x5c, 0x71, 0x05, 0x92, +0x48, 0x20, 0xd1, 0x18, 0xc0, 0x28, 0xee, 0xfe, +0xff, 0x77, 0x59, 0xca, 0x50, 0xe5, 0x91, 0x3e, +0xbe, 0xea, 0x43, 0xb7, 0x65, 0xd5, 0x88, 0xfd, +0x97, 0x12, 0x1a, 0xcd, 0x56, 0xbb, 0xd3, 0x05, +0xe8, 0xf5, 0x07, 0x25, 0x38, 0xee, 0x70, 0x34, +0x9e, 0x4c, 0x67, 0xde, 0x1c, 0x1b, 0xce, 0xe2, +0x0b, 0xcb, 0x95, 0xb7, 0x46, 0xd8, 0xf8, 0x7e, +0x10, 0x12, 0xca, 0x60, 0x8b, 0xe0, 0x03, 0x44, +0x9c, 0xc6, 0x89, 0x90, 0x15, 0xec, 0xa2, 0xbd, +0x62, 0xf1, 0x41, 0xa7, 0x08, 0x41, 0xc8, 0x15, +0x81, 0x4c, 0xa6, 0x39, 0x42, 0x78, 0x94, 0x86, +0x66, 0xfa, 0x74, 0x2e, 0x10, 0xb8, 0x31, 0x17, +0x26, 0xf5, 0xf5, 0x26, 0x10, 0x14, 0xb9, 0x33, +0xc8, 0x93, 0x42, 0x3c, 0xaa, 0x1d, 0xee, 0xf3, +0xf5, 0xdb, 0xf1, 0xb6, 0xeb, 0x5c, 0xfd, 0x00, +0xaa, 0xbb, 0x0d, 0x11, 0xa3, 0xb9, 0xf3, 0x15, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, +0x2d, 0x30, 0x31, 0x2d, 0x32, 0x33, 0x54, 0x30, +0x33, 0x3a, 0x30, 0x33, 0x3a, 0x34, 0x34, 0x2b, +0x30, 0x36, 0x3a, 0x30, 0x30, 0x44, 0xd4, 0x3d, +0x9a, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_sm_png = new wxImage(); + if (!img_table_sm_png || !img_table_sm_png->IsOk()) + { + wxMemoryInputStream img_table_sm_pngIS(table_sm_png_data, sizeof(table_sm_png_data)); + img_table_sm_png->LoadFile(img_table_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_sm_png; +} +#define table_sm_png_img table_sm_png_img() + +static wxBitmap *table_sm_png_bmp() +{ + static wxBitmap *bmp_table_sm_png; + if (!bmp_table_sm_png || !bmp_table_sm_png->IsOk()) + bmp_table_sm_png = new wxBitmap(*table_sm_png_img); + return bmp_table_sm_png; +} +#define table_sm_png_bmp table_sm_png_bmp() + +static wxIcon *table_sm_png_ico() +{ + static wxIcon *ico_table_sm_png; + if (!ico_table_sm_png || !ico_table_sm_png->IsOk()) + { + ico_table_sm_png = new wxIcon(); + ico_table_sm_png->CopyFromBitmap(*table_sm_png_bmp); + } + return ico_table_sm_png; +} +#define table_sm_png_ico table_sm_png_ico() + +#endif // TABLE_SM_PNG_H diff --git a/include/images/table.png b/include/images/table.png new file mode 100644 index 0000000..37b2227 Binary files /dev/null and b/include/images/table.png differ diff --git a/include/images/table.pngc b/include/images/table.pngc new file mode 100644 index 0000000..3705f43 --- /dev/null +++ b/include/images/table.pngc @@ -0,0 +1,119 @@ +#ifndef TABLE_PNG_H +#define TABLE_PNG_H + +static const unsigned char table_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xd8, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8d, +0xd0, 0xff, 0x92, 0xcf, 0xfb, 0xa2, 0xd3, 0xf5, +0xba, 0xd8, 0xed, 0xd1, 0xdf, 0xe9, 0xdf, 0xe3, +0xe7, 0xe5, 0xe6, 0xe7, 0xe6, 0xe6, 0xe6, 0xda, +0xe1, 0xe5, 0xac, 0xce, 0xe7, 0x63, 0xb1, 0xe8, +0x2e, 0x9b, 0xe8, 0x8b, 0xcf, 0xff, 0x85, 0xcc, +0xfe, 0x7e, 0xc8, 0xfc, 0x75, 0xc3, 0xfa, 0x6c, +0xbe, 0xf8, 0x61, 0xb8, 0xf6, 0x56, 0xb2, 0xf3, +0x4b, 0xac, 0xf0, 0x40, 0xa7, 0xee, 0x37, 0xa0, +0xec, 0x2d, 0x9c, 0xea, 0x26, 0x98, 0xe9, 0x85, +0xcc, 0xfd, 0x6b, 0xbe, 0xf8, 0x41, 0xa6, 0xee, +0x36, 0xa1, 0xec, 0x2e, 0x9c, 0xea, 0xb4, 0xd6, +0xee, 0xdd, 0xdd, 0xdd, 0xde, 0xde, 0xde, 0xdf, +0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, +0xe2, 0xe2, 0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, +0xe5, 0x87, 0xbf, 0xe7, 0xe8, 0xe8, 0xe8, 0xe9, +0xe9, 0xe9, 0xe7, 0xe7, 0xe7, 0xa9, 0xa9, 0xa9, +0xe4, 0xe4, 0xe4, 0xac, 0xac, 0xac, 0xec, 0xec, +0xec, 0xed, 0xed, 0xed, 0xef, 0xef, 0xef, 0xea, +0xea, 0xea, 0xa7, 0xa7, 0xa7, 0xa8, 0xa8, 0xa8, +0xad, 0xad, 0xad, 0xaf, 0xaf, 0xaf, 0xeb, 0xeb, +0xeb, 0xf0, 0xf0, 0xf0, 0xf2, 0xf2, 0xf2, 0xee, +0xee, 0xee, 0xab, 0xab, 0xab, 0xb0, 0xb0, 0xb0, +0xb1, 0xb1, 0xb1, 0xb2, 0xb2, 0xb2, 0xf1, 0xf1, +0xf1, 0xf3, 0xf3, 0xf3, 0xf5, 0xf5, 0xf5, 0xb5, +0xb5, 0xb5, 0xf6, 0xf6, 0xf6, 0xf8, 0xf8, 0xf8, +0xb6, 0xb6, 0xb6, 0xb8, 0xb8, 0xb8, 0xf7, 0xf7, +0xf7, 0x73, 0xda, 0xb6, 0x7b, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xb0, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x55, 0xcf, 0xd7, 0x12, 0x82, 0x30, 0x10, +0x85, 0xe1, 0x60, 0x8f, 0x1d, 0x7b, 0x17, 0x0b, +0x20, 0x01, 0x43, 0x51, 0x21, 0xa0, 0x62, 0x41, +0xe1, 0xfd, 0xdf, 0x48, 0xdd, 0x38, 0x3a, 0xec, +0xdd, 0xf9, 0xe6, 0xbf, 0x59, 0x84, 0x84, 0xd4, +0x21, 0x84, 0x84, 0x4c, 0x36, 0x97, 0x2f, 0x14, +0x4b, 0x18, 0x97, 0x2b, 0xd5, 0xda, 0x07, 0xea, +0x8d, 0xa6, 0xd8, 0x6a, 0x77, 0xba, 0xbd, 0xfe, +0x60, 0x08, 0x45, 0x7d, 0xd4, 0x14, 0xc7, 0x6f, +0x98, 0x4c, 0x67, 0x1c, 0xe6, 0x92, 0xb4, 0x58, +0xae, 0xd6, 0xb2, 0xa2, 0xe2, 0x0d, 0xc0, 0x7f, +0x6b, 0x84, 0x03, 0xd6, 0x35, 0x43, 0xde, 0x52, +0xd3, 0xb2, 0x1d, 0x80, 0xc5, 0x6e, 0x6f, 0x18, +0x8a, 0x4a, 0x0f, 0xae, 0xeb, 0x01, 0x7c, 0x7b, +0x9d, 0x38, 0xa6, 0x05, 0xb0, 0x22, 0xc4, 0xa1, +0x58, 0x77, 0x6d, 0xe6, 0x07, 0x00, 0x6b, 0xe3, +0x48, 0xa9, 0x46, 0x4e, 0xe7, 0x30, 0x64, 0x00, +0xef, 0xd8, 0x33, 0xad, 0x80, 0x5d, 0xfc, 0xeb, +0x0d, 0x40, 0xb7, 0x19, 0x0b, 0x03, 0x76, 0xbf, +0x45, 0x8f, 0x08, 0x80, 0xc7, 0x97, 0xfb, 0x33, +0x8e, 0x13, 0x80, 0x5f, 0x1f, 0x25, 0x1c, 0xd2, +0xef, 0xbf, 0x00, 0xb2, 0x0f, 0x1b, 0x0f, 0xe3, +0x76, 0xaa, 0x7b, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *table_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_table_png = new wxImage(); + if (!img_table_png || !img_table_png->IsOk()) + { + wxMemoryInputStream img_table_pngIS(table_png_data, sizeof(table_png_data)); + img_table_png->LoadFile(img_table_pngIS, wxBITMAP_TYPE_PNG); + } + return img_table_png; +} +#define table_png_img table_png_img() + +static wxBitmap *table_png_bmp() +{ + static wxBitmap *bmp_table_png; + if (!bmp_table_png || !bmp_table_png->IsOk()) + bmp_table_png = new wxBitmap(*table_png_img); + return bmp_table_png; +} +#define table_png_bmp table_png_bmp() + +static wxIcon *table_png_ico() +{ + static wxIcon *ico_table_png; + if (!ico_table_png || !ico_table_png->IsOk()) + { + ico_table_png = new wxIcon(); + ico_table_png->CopyFromBitmap(*table_png_bmp); + } + return ico_table_png; +} +#define table_png_ico table_png_ico() + +#endif // TABLE_PNG_H diff --git a/include/images/tables.png b/include/images/tables.png new file mode 100644 index 0000000..680e864 Binary files /dev/null and b/include/images/tables.png differ diff --git a/include/images/tables.pngc b/include/images/tables.pngc new file mode 100644 index 0000000..473e2e8 --- /dev/null +++ b/include/images/tables.pngc @@ -0,0 +1,114 @@ +#ifndef TABLES_PNG_H +#define TABLES_PNG_H + +static const unsigned char tables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xbd, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x21, 0x95, 0xe7, 0x8a, +0xce, 0xfe, 0x94, 0xcf, 0xf9, 0xad, 0xd5, 0xf2, +0xca, 0xdc, 0xea, 0xde, 0xe3, 0xe7, 0xe6, 0xe7, +0xe7, 0xe6, 0xe6, 0xe6, 0xc5, 0xd8, 0xe6, 0x76, +0xb9, 0xe8, 0x30, 0x9c, 0xe8, 0x88, 0xcd, 0xfe, +0x52, 0xb0, 0xf2, 0xb3, 0xd5, 0xed, 0xdd, 0xdd, +0xdd, 0x83, 0xcb, 0xfe, 0x7a, 0xc6, 0xfb, 0x6f, +0xc0, 0xf9, 0x63, 0xb9, 0xf6, 0x56, 0xb2, 0xf3, +0x49, 0xab, 0xf0, 0x3d, 0xa5, 0xed, 0x31, 0x9e, +0xeb, 0x27, 0x99, 0xe9, 0xde, 0xde, 0xde, 0x83, +0xcb, 0xfd, 0x4a, 0xab, 0xf0, 0x3d, 0xa4, 0xed, +0x28, 0x99, 0xe9, 0xdf, 0xdf, 0xdf, 0xe2, 0xe2, +0xe2, 0xe3, 0xe3, 0xe3, 0xe5, 0xe5, 0xe5, 0x87, +0xc0, 0xe7, 0xe0, 0xe0, 0xe0, 0xa7, 0xa7, 0xa7, +0xac, 0xac, 0xac, 0xec, 0xec, 0xec, 0xee, 0xee, +0xee, 0xe9, 0xe9, 0xe9, 0xe1, 0xe1, 0xe1, 0xa6, +0xa6, 0xa6, 0xa8, 0xa8, 0xa8, 0xad, 0xad, 0xad, +0xaf, 0xaf, 0xaf, 0xea, 0xea, 0xea, 0x90, 0xca, +0xf3, 0xe7, 0xe7, 0xe7, 0xeb, 0xeb, 0xeb, 0xe8, +0xe8, 0xe8, 0xa9, 0xa9, 0xa9, 0xef, 0xef, 0xef, +0xf1, 0xf1, 0xf1, 0xed, 0xed, 0xed, 0xaa, 0xaa, +0xaa, 0xb0, 0xb0, 0xb0, 0xb2, 0xb2, 0xb2, 0xe4, +0xe4, 0xe4, 0xf0, 0xf0, 0xf0, 0x7b, 0xc6, 0xfb, +0x6f, 0xc0, 0xf8, 0x28, 0x99, 0xe8, 0xae, 0xfd, +0x25, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa5, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, +0xc7, 0x16, 0x82, 0x30, 0x10, 0x85, 0xe1, 0x8c, +0x35, 0x2a, 0x1a, 0xac, 0x88, 0x05, 0x88, 0xb4, +0x44, 0xa5, 0x89, 0x62, 0xf7, 0xfd, 0x1f, 0xcb, +0x0c, 0x2c, 0x3c, 0x32, 0xcb, 0xff, 0x7c, 0x8b, +0x3b, 0x04, 0x7e, 0x47, 0xca, 0x83, 0x46, 0xb3, +0xd5, 0xee, 0x74, 0x29, 0xed, 0xf5, 0x07, 0x55, +0xd0, 0x86, 0xff, 0x06, 0xb4, 0x9a, 0x81, 0x51, +0xcd, 0x00, 0xab, 0x19, 0x15, 0x94, 0xd1, 0xc7, +0x93, 0xe9, 0x6c, 0xbe, 0x30, 0x96, 0x40, 0xc0, +0x44, 0xb3, 0xc2, 0xb0, 0xde, 0x18, 0x5b, 0x15, +0x2c, 0x34, 0x8c, 0x99, 0x96, 0xed, 0x70, 0xba, +0x53, 0xc1, 0x45, 0x43, 0xa9, 0xe7, 0x3a, 0x7e, +0x10, 0x0a, 0x15, 0x24, 0x9a, 0xbd, 0x77, 0x90, +0xdc, 0x3f, 0x46, 0x31, 0x90, 0x24, 0x41, 0x63, +0xb9, 0xd2, 0xa6, 0xa9, 0x88, 0x33, 0xdc, 0x86, +0xe6, 0x24, 0x72, 0x27, 0x8d, 0xce, 0x97, 0x02, +0x03, 0x9a, 0x3c, 0xbf, 0x72, 0x11, 0xdd, 0xee, +0x61, 0xf5, 0x21, 0x48, 0xfb, 0xc1, 0x69, 0x16, +0x14, 0xe1, 0xb3, 0x0a, 0x89, 0xa6, 0xbf, 0xde, +0xe5, 0x8e, 0x0f, 0x7c, 0x01, 0x9f, 0x6d, 0x10, +0xb4, 0xc9, 0xf5, 0x15, 0xb2, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, +0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *tables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_tables_png = new wxImage(); + if (!img_tables_png || !img_tables_png->IsOk()) + { + wxMemoryInputStream img_tables_pngIS(tables_png_data, sizeof(tables_png_data)); + img_tables_png->LoadFile(img_tables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_tables_png; +} +#define tables_png_img tables_png_img() + +static wxBitmap *tables_png_bmp() +{ + static wxBitmap *bmp_tables_png; + if (!bmp_tables_png || !bmp_tables_png->IsOk()) + bmp_tables_png = new wxBitmap(*tables_png_img); + return bmp_tables_png; +} +#define tables_png_bmp tables_png_bmp() + +static wxIcon *tables_png_ico() +{ + static wxIcon *ico_tables_png; + if (!ico_tables_png || !ico_tables_png->IsOk()) + { + ico_tables_png = new wxIcon(); + ico_tables_png->CopyFromBitmap(*tables_png_bmp); + } + return ico_tables_png; +} +#define tables_png_ico tables_png_ico() + +#endif // TABLES_PNG_H diff --git a/include/images/tablespace.png b/include/images/tablespace.png new file mode 100644 index 0000000..4995c6c Binary files /dev/null and b/include/images/tablespace.png differ diff --git a/include/images/tablespace.pngc b/include/images/tablespace.pngc new file mode 100644 index 0000000..f903750 --- /dev/null +++ b/include/images/tablespace.pngc @@ -0,0 +1,92 @@ +#ifndef TABLESPACE_PNG_H +#define TABLESPACE_PNG_H + +static const unsigned char tablespace_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x51, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xe0, 0xca, 0x7e, 0xca, +0xa5, 0x24, 0xfa, 0xf7, 0x9a, 0xf9, 0xf6, 0x96, +0xf8, 0xf6, 0x91, 0xf7, 0xf5, 0x8c, 0xdd, 0xc6, +0x4f, 0xf6, 0xf4, 0x85, 0xdc, 0xc6, 0x4c, 0xe8, +0xdd, 0x64, 0xf5, 0xf4, 0x7e, 0xf9, 0xf6, 0x93, +0xe8, 0xdc, 0x60, 0xf3, 0xf3, 0x77, 0xf7, 0xf5, +0x89, 0xe7, 0xdc, 0x5a, 0xf2, 0xf2, 0x71, 0xe5, +0xdb, 0x54, 0xf1, 0xf2, 0x6b, 0xf2, 0xf3, 0x73, +0xe4, 0xdb, 0x4d, 0xda, 0xc4, 0x3f, 0xf1, 0xf2, +0x69, 0xe3, 0xda, 0x47, 0xd3, 0xb4, 0x49, 0xcc, +0xac, 0x1e, 0xdf, 0x01, 0x6f, 0xe3, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x60, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x8d, 0xcf, 0x47, 0x12, 0x80, 0x20, +0x0c, 0x05, 0x50, 0xf8, 0x2a, 0x16, 0x50, 0x2c, +0x58, 0xf0, 0xfe, 0x07, 0x15, 0x92, 0x58, 0x96, +0xbe, 0x5d, 0xfe, 0xa4, 0x4c, 0x94, 0xfa, 0x41, +0x23, 0xf9, 0x06, 0x28, 0x12, 0xe8, 0xb7, 0x2e, +0x49, 0x6e, 0xe3, 0x10, 0xd5, 0x83, 0x07, 0x61, +0x4c, 0x0d, 0x41, 0x2d, 0x68, 0x5a, 0xda, 0x92, +0x74, 0x94, 0xc0, 0xc2, 0x89, 0xde, 0xe5, 0x21, +0x0c, 0xf0, 0x62, 0xf4, 0x14, 0x4c, 0xb0, 0x62, +0xb6, 0x14, 0x2c, 0x08, 0x62, 0x0d, 0x74, 0x07, +0x1b, 0x76, 0x76, 0x20, 0xf2, 0xe1, 0xdb, 0x19, +0xff, 0xbc, 0x7a, 0x01, 0xd4, 0xf5, 0x04, 0xa7, +0x27, 0x0e, 0x5b, 0x26, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *tablespace_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_tablespace_png = new wxImage(); + if (!img_tablespace_png || !img_tablespace_png->IsOk()) + { + wxMemoryInputStream img_tablespace_pngIS(tablespace_png_data, sizeof(tablespace_png_data)); + img_tablespace_png->LoadFile(img_tablespace_pngIS, wxBITMAP_TYPE_PNG); + } + return img_tablespace_png; +} +#define tablespace_png_img tablespace_png_img() + +static wxBitmap *tablespace_png_bmp() +{ + static wxBitmap *bmp_tablespace_png; + if (!bmp_tablespace_png || !bmp_tablespace_png->IsOk()) + bmp_tablespace_png = new wxBitmap(*tablespace_png_img); + return bmp_tablespace_png; +} +#define tablespace_png_bmp tablespace_png_bmp() + +static wxIcon *tablespace_png_ico() +{ + static wxIcon *ico_tablespace_png; + if (!ico_tablespace_png || !ico_tablespace_png->IsOk()) + { + ico_tablespace_png = new wxIcon(); + ico_tablespace_png->CopyFromBitmap(*tablespace_png_bmp); + } + return ico_tablespace_png; +} +#define tablespace_png_ico tablespace_png_ico() + +#endif // TABLESPACE_PNG_H diff --git a/include/images/tablespaces.png b/include/images/tablespaces.png new file mode 100644 index 0000000..9b090e4 Binary files /dev/null and b/include/images/tablespaces.png differ diff --git a/include/images/tablespaces.pngc b/include/images/tablespaces.pngc new file mode 100644 index 0000000..fe84c8c --- /dev/null +++ b/include/images/tablespaces.pngc @@ -0,0 +1,86 @@ +#ifndef TABLESPACES_PNG_H +#define TABLESPACES_PNG_H + +static const unsigned char tablespaces_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x1e, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xca, 0xa5, 0x24, 0xe0, +0xca, 0x7e, 0xfa, 0xf7, 0x9a, 0xf9, 0xf6, 0x93, +0xf7, 0xf5, 0x89, 0xdd, 0xc6, 0x4e, 0xf5, 0xf4, +0x7e, 0xf2, 0xf3, 0x73, 0xf1, 0xf2, 0x69, 0x07, +0x4b, 0xd4, 0x10, 0x00, 0x00, 0x00, 0x01, 0x74, +0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, +0x69, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, +0x60, 0x80, 0x01, 0x46, 0x41, 0x21, 0x08, 0x43, +0xd8, 0xd8, 0x10, 0xc2, 0x14, 0x71, 0x71, 0x71, +0x71, 0x04, 0x31, 0x44, 0xc3, 0x04, 0x05, 0x13, +0x41, 0x0c, 0xf1, 0x42, 0x63, 0x63, 0x41, 0x41, +0x05, 0x06, 0x06, 0x89, 0x46, 0xa0, 0x9c, 0x8b, +0x00, 0x03, 0x83, 0xe4, 0xc4, 0xd0, 0x44, 0x41, +0x31, 0x20, 0x43, 0x51, 0xb0, 0x1c, 0xaa, 0x91, +0xb1, 0x03, 0xaa, 0x91, 0x71, 0xa6, 0x68, 0x68, +0x68, 0x68, 0x20, 0x50, 0x9f, 0xa0, 0x78, 0x79, +0x79, 0x79, 0x21, 0xc8, 0x04, 0x89, 0x8e, 0x8e, +0x8e, 0x46, 0x10, 0x43, 0x72, 0xe6, 0xcc, 0x99, +0x13, 0x21, 0xf6, 0x0a, 0x0a, 0x0a, 0xc0, 0x5d, +0x01, 0x00, 0x9c, 0x16, 0x13, 0x22, 0xd7, 0x8c, +0xfc, 0xa2, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x32, 0x33, +0x54, 0x30, 0x33, 0x3a, 0x30, 0x33, 0x3a, 0x31, +0x33, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, 0xc9, +0x93, 0x0d, 0x70, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *tablespaces_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_tablespaces_png = new wxImage(); + if (!img_tablespaces_png || !img_tablespaces_png->IsOk()) + { + wxMemoryInputStream img_tablespaces_pngIS(tablespaces_png_data, sizeof(tablespaces_png_data)); + img_tablespaces_png->LoadFile(img_tablespaces_pngIS, wxBITMAP_TYPE_PNG); + } + return img_tablespaces_png; +} +#define tablespaces_png_img tablespaces_png_img() + +static wxBitmap *tablespaces_png_bmp() +{ + static wxBitmap *bmp_tablespaces_png; + if (!bmp_tablespaces_png || !bmp_tablespaces_png->IsOk()) + bmp_tablespaces_png = new wxBitmap(*tablespaces_png_img); + return bmp_tablespaces_png; +} +#define tablespaces_png_bmp tablespaces_png_bmp() + +static wxIcon *tablespaces_png_ico() +{ + static wxIcon *ico_tablespaces_png; + if (!ico_tablespaces_png || !ico_tablespaces_png->IsOk()) + { + ico_tablespaces_png = new wxIcon(); + ico_tablespaces_png->CopyFromBitmap(*tablespaces_png_bmp); + } + return ico_tablespaces_png; +} +#define tablespaces_png_ico tablespaces_png_ico() + +#endif // TABLESPACES_PNG_H diff --git a/include/images/template.png b/include/images/template.png new file mode 100644 index 0000000..eb780bf Binary files /dev/null and b/include/images/template.png differ diff --git a/include/images/template.pngc b/include/images/template.pngc new file mode 100644 index 0000000..bf09c6d --- /dev/null +++ b/include/images/template.pngc @@ -0,0 +1,131 @@ +#ifndef TEMPLATE_PNG_H +#define TEMPLATE_PNG_H + +static const unsigned char template_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x4d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd1, 0xc7, 0x79, 0xce, +0xbd, 0x39, 0xff, 0xff, 0xd6, 0xff, 0xff, 0xd4, +0xfe, 0xfe, 0xd2, 0xfe, 0xfe, 0xd0, 0xfe, 0xfe, +0xcd, 0xfd, 0xfd, 0xca, 0xfd, 0xfd, 0xc7, 0xfc, +0xfc, 0xc4, 0x66, 0x66, 0x55, 0xff, 0xff, 0xd3, +0x66, 0x66, 0x53, 0xfe, 0xfe, 0xce, 0x65, 0x65, +0x51, 0xfd, 0xfd, 0xc8, 0x65, 0x65, 0x4f, 0xfc, +0xfc, 0xc1, 0x65, 0x65, 0x4c, 0xfb, 0xfb, 0xba, +0xfe, 0xfe, 0xd1, 0xfe, 0xfe, 0xcc, 0xfd, 0xfd, +0xc9, 0xfd, 0xfd, 0xc6, 0xfc, 0xfc, 0xc2, 0xfc, +0xfc, 0xbf, 0xfb, 0xfb, 0xbb, 0xfb, 0xfb, 0xb7, +0xfa, 0xfa, 0xb4, 0xfa, 0xfa, 0xb0, 0xfc, 0xfc, +0xc3, 0xfc, 0xfc, 0xc0, 0xfb, 0xfb, 0xbc, 0xfb, +0xfb, 0xb8, 0xfa, 0xfa, 0xb5, 0xfa, 0xfa, 0xb1, +0xf9, 0xf9, 0xad, 0x64, 0x64, 0x44, 0xf8, 0xf8, +0xa4, 0xfc, 0xfc, 0xbd, 0xfb, 0xfb, 0xb9, 0xfa, +0xfa, 0xb6, 0xfa, 0xfa, 0xb2, 0xf9, 0xf9, 0xae, +0xf9, 0xf9, 0xaa, 0xf8, 0xf8, 0xa5, 0xf8, 0xf8, +0xa1, 0xf7, 0xf7, 0x9d, 0xf6, 0xf6, 0x99, 0x64, +0x64, 0x48, 0xfa, 0xfa, 0xaf, 0xf9, 0xf9, 0xab, +0xf8, 0xf8, 0xa6, 0xf8, 0xf8, 0xa2, 0xf7, 0xf7, +0x9e, 0xf7, 0xf7, 0x9a, 0xf6, 0xf6, 0x96, 0x62, +0x62, 0x3a, 0xf5, 0xf5, 0x8d, 0xf9, 0xf9, 0xac, +0xf9, 0xf9, 0xa7, 0xf8, 0xf8, 0xa3, 0xf7, 0xf7, +0x9f, 0xf7, 0xf7, 0x9b, 0xf6, 0xf6, 0x97, 0xf6, +0xf6, 0x93, 0xf5, 0xf5, 0x8e, 0xf4, 0xf4, 0x8a, +0xf4, 0xf4, 0x86, 0xf3, 0xf3, 0x82, 0xf8, 0xf8, +0xa0, 0x63, 0x63, 0x3e, 0xf6, 0xf6, 0x98, 0xf6, +0xf6, 0x94, 0xf5, 0xf5, 0x8f, 0xf5, 0xf5, 0x8b, +0xf4, 0xf4, 0x87, 0xf4, 0xf4, 0x83, 0xf3, 0xf3, +0x80, 0x61, 0x61, 0x32, 0xf2, 0xf2, 0x78, 0xf6, +0xf6, 0x95, 0xf5, 0xf5, 0x90, 0xf5, 0xf5, 0x8c, +0xf4, 0xf4, 0x88, 0xf4, 0xf4, 0x84, 0xf3, 0xf3, +0x81, 0xf3, 0xf3, 0x7d, 0xf2, 0xf2, 0x79, 0xf2, +0xf2, 0x76, 0xf1, 0xf1, 0x73, 0xf1, 0xf1, 0x6f, +0xf4, 0xf4, 0x89, 0x62, 0x62, 0x35, 0xf2, 0xf2, +0x7a, 0x61, 0x61, 0x30, 0x60, 0x60, 0x2d, 0xf0, +0xf0, 0x6d, 0x60, 0x60, 0x2b, 0xf0, 0xf0, 0x68, +0xf3, 0xf3, 0x7f, 0xf2, 0xf2, 0x7b, 0xf1, 0xf1, +0x74, 0xf1, 0xf1, 0x71, 0xf1, 0xf1, 0x6e, 0xf0, +0xf0, 0x6b, 0xf0, 0xf0, 0x69, 0xef, 0xef, 0x66, +0xef, 0xef, 0x64, 0xef, 0xef, 0x63, 0x05, 0x7c, +0x09, 0x42, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0xa2, +0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, +0xc0, 0x00, 0x8c, 0x4c, 0x08, 0xc0, 0x08, 0x12, +0x60, 0x62, 0x06, 0x02, 0x16, 0x56, 0x36, 0x76, +0x0e, 0x4e, 0x2e, 0x26, 0x88, 0x00, 0x37, 0x0f, +0x2f, 0x1f, 0xbf, 0x80, 0xa0, 0x90, 0xb0, 0x08, +0x44, 0x40, 0x94, 0x4f, 0x4c, 0x5c, 0x42, 0x52, +0x4a, 0x5a, 0x46, 0x56, 0x0e, 0x22, 0xc0, 0x21, +0x28, 0xaf, 0xa0, 0xa8, 0xa4, 0xac, 0xa2, 0xaa, +0xa6, 0x0e, 0x11, 0x10, 0xd2, 0xd0, 0xd4, 0xd2, +0xd6, 0xd1, 0xd5, 0xd3, 0x37, 0x30, 0x84, 0x08, +0xc8, 0x18, 0x19, 0x9b, 0x98, 0x9a, 0x99, 0x5b, +0x58, 0x5a, 0x59, 0x43, 0x04, 0x6c, 0x6c, 0xed, +0xec, 0x1d, 0x1c, 0x9d, 0x9c, 0x5d, 0x5c, 0xdd, +0x20, 0x02, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, +0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x10, 0x81, 0xa0, +0xe0, 0x90, 0xd0, 0xb0, 0xf0, 0x88, 0xc8, 0xa8, +0xe8, 0x18, 0x88, 0x40, 0x6c, 0x9c, 0x5b, 0x40, +0x7c, 0x42, 0x74, 0x62, 0x52, 0x72, 0x0a, 0x44, +0x20, 0x35, 0x2d, 0x30, 0x3d, 0x23, 0x33, 0x2b, +0x3b, 0x27, 0x37, 0x8f, 0x09, 0xab, 0x5f, 0x08, +0x01, 0x00, 0x78, 0xe9, 0x19, 0xd6, 0xac, 0x53, +0x24, 0x0a, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *template_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_template_png = new wxImage(); + if (!img_template_png || !img_template_png->IsOk()) + { + wxMemoryInputStream img_template_pngIS(template_png_data, sizeof(template_png_data)); + img_template_png->LoadFile(img_template_pngIS, wxBITMAP_TYPE_PNG); + } + return img_template_png; +} +#define template_png_img template_png_img() + +static wxBitmap *template_png_bmp() +{ + static wxBitmap *bmp_template_png; + if (!bmp_template_png || !bmp_template_png->IsOk()) + bmp_template_png = new wxBitmap(*template_png_img); + return bmp_template_png; +} +#define template_png_bmp template_png_bmp() + +static wxIcon *template_png_ico() +{ + static wxIcon *ico_template_png; + if (!ico_template_png || !ico_template_png->IsOk()) + { + ico_template_png = new wxIcon(); + ico_template_png->CopyFromBitmap(*template_png_bmp); + } + return ico_template_png; +} +#define template_png_ico template_png_ico() + +#endif // TEMPLATE_PNG_H diff --git a/include/images/templates.png b/include/images/templates.png new file mode 100644 index 0000000..fabd47d Binary files /dev/null and b/include/images/templates.png differ diff --git a/include/images/templates.pngc b/include/images/templates.pngc new file mode 100644 index 0000000..f3df1c5 --- /dev/null +++ b/include/images/templates.pngc @@ -0,0 +1,120 @@ +#ifndef TEMPLATES_PNG_H +#define TEMPLATES_PNG_H + +static const unsigned char templates_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xf9, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xd1, 0xc7, 0x79, 0xce, +0xbd, 0x39, 0xff, 0xff, 0xd6, 0xff, 0xff, 0xd3, +0xfe, 0xfe, 0xd0, 0xfe, 0xfe, 0xcc, 0xfd, 0xfd, +0xc8, 0xfc, 0xfc, 0xc4, 0xfc, 0xfc, 0xbf, 0xff, +0xff, 0xd5, 0xa3, 0x99, 0x44, 0xfe, 0xfe, 0xce, +0xfd, 0xfd, 0xc5, 0xfb, 0xfb, 0xba, 0xf9, 0xf9, +0xad, 0x66, 0x66, 0x54, 0xfe, 0xfe, 0xcf, 0x66, +0x66, 0x51, 0xfd, 0xfd, 0xc7, 0x65, 0x65, 0x4e, +0xfc, 0xfc, 0xbe, 0x64, 0x64, 0x4a, 0xfa, 0xfa, +0xb3, 0xf8, 0xf8, 0xa0, 0xfd, 0xfd, 0xca, 0xfd, +0xfd, 0xc6, 0xfc, 0xfc, 0xc1, 0xfb, 0xfb, 0xbc, +0xfb, 0xfb, 0xb7, 0xfa, 0xfa, 0xb2, 0xf9, 0xf9, +0xac, 0xf8, 0xf8, 0xa6, 0xf6, 0xf6, 0x93, 0x65, +0x65, 0x4d, 0xfb, 0xfb, 0xbb, 0xfb, 0xfb, 0xb6, +0xfa, 0xfa, 0xb0, 0xf9, 0xf9, 0xaa, 0xf8, 0xf8, +0xa5, 0x63, 0x63, 0x40, 0xf6, 0xf6, 0x99, 0xf4, +0xf4, 0x86, 0xfa, 0xfa, 0xb4, 0xfa, 0xfa, 0xaf, +0xf9, 0xf9, 0xa9, 0xf8, 0xf8, 0xa3, 0xf7, 0xf7, +0x9d, 0xf6, 0xf6, 0x97, 0xf5, 0xf5, 0x91, 0xf5, +0xf5, 0x8c, 0x64, 0x64, 0x43, 0xf8, 0xf8, 0xa2, +0xf7, 0xf7, 0x9c, 0xf6, 0xf6, 0x96, 0xf5, 0xf5, +0x90, 0xf4, 0xf4, 0x8a, 0x62, 0x62, 0x35, 0xf3, +0xf3, 0x7f, 0xf7, 0xf7, 0x9a, 0xf6, 0xf6, 0x94, +0xf5, 0xf5, 0x8f, 0xf4, 0xf4, 0x89, 0xf3, 0xf3, +0x83, 0xf3, 0xf3, 0x7e, 0xf2, 0xf2, 0x79, 0xf1, +0xf1, 0x74, 0x62, 0x62, 0x38, 0xf4, 0xf4, 0x87, +0x61, 0x61, 0x34, 0xf3, 0xf3, 0x7d, 0x61, 0x61, +0x30, 0xf1, 0xf1, 0x73, 0x60, 0x60, 0x2c, 0xf0, +0xf0, 0x6b, 0xf3, 0xf3, 0x81, 0xf2, 0xf2, 0x7b, +0xf2, 0xf2, 0x76, 0xf1, 0xf1, 0x72, 0xf0, 0xf0, +0x6e, 0xf0, 0xf0, 0x6a, 0xef, 0xef, 0x66, 0xef, +0xef, 0x64, 0xda, 0xfa, 0x5f, 0x6a, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x97, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x63, 0x60, 0x64, 0x82, 0x01, 0x46, +0x06, 0x30, 0x60, 0x62, 0x66, 0x66, 0x66, 0x61, +0x65, 0x63, 0xe7, 0xe0, 0x64, 0x82, 0x0a, 0x70, +0x71, 0xa3, 0xaa, 0x61, 0xe2, 0x41, 0x53, 0xc3, +0xc4, 0x8b, 0xa6, 0x86, 0x89, 0x0f, 0x4d, 0x0d, +0x13, 0x3f, 0x48, 0x8d, 0x80, 0xa0, 0x90, 0xb0, +0x88, 0xa8, 0x98, 0x38, 0x48, 0x40, 0x02, 0xa4, +0x46, 0x52, 0x4a, 0x5a, 0x46, 0x56, 0x4e, 0x5e, +0x01, 0x24, 0xa0, 0x08, 0x52, 0xa3, 0xa4, 0xac, +0xa2, 0xaa, 0xa6, 0xae, 0xa1, 0x09, 0x12, 0xd0, +0x02, 0xa9, 0xd1, 0xd6, 0xd1, 0xd5, 0xd3, 0x37, +0x30, 0x34, 0x02, 0x0a, 0x00, 0x5d, 0x0a, 0x54, +0x63, 0x6c, 0x62, 0x6a, 0x66, 0x6e, 0x61, 0x69, +0x05, 0xb1, 0x18, 0xa8, 0xc6, 0xda, 0xc6, 0xd6, +0xce, 0xde, 0xc1, 0xd1, 0x09, 0x2c, 0x00, 0x52, +0xe3, 0xec, 0xe2, 0xea, 0xe6, 0xee, 0xe1, 0xe9, +0x05, 0x73, 0xbe, 0x96, 0xb7, 0x8f, 0xaf, 0x9f, +0x7f, 0x40, 0x60, 0x10, 0x54, 0x00, 0xc3, 0xc7, +0xc8, 0x00, 0x00, 0xf4, 0xde, 0x0f, 0xa0, 0xdc, +0xce, 0x0b, 0x76, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *templates_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_templates_png = new wxImage(); + if (!img_templates_png || !img_templates_png->IsOk()) + { + wxMemoryInputStream img_templates_pngIS(templates_png_data, sizeof(templates_png_data)); + img_templates_png->LoadFile(img_templates_pngIS, wxBITMAP_TYPE_PNG); + } + return img_templates_png; +} +#define templates_png_img templates_png_img() + +static wxBitmap *templates_png_bmp() +{ + static wxBitmap *bmp_templates_png; + if (!bmp_templates_png || !bmp_templates_png->IsOk()) + bmp_templates_png = new wxBitmap(*templates_png_img); + return bmp_templates_png; +} +#define templates_png_bmp templates_png_bmp() + +static wxIcon *templates_png_ico() +{ + static wxIcon *ico_templates_png; + if (!ico_templates_png || !ico_templates_png->IsOk()) + { + ico_templates_png = new wxIcon(); + ico_templates_png->CopyFromBitmap(*templates_png_bmp); + } + return ico_templates_png; +} +#define templates_png_ico templates_png_ico() + +#endif // TEMPLATES_PNG_H diff --git a/include/images/terminate_backend.png b/include/images/terminate_backend.png new file mode 100644 index 0000000..5634349 Binary files /dev/null and b/include/images/terminate_backend.png differ diff --git a/include/images/terminate_backend.pngc b/include/images/terminate_backend.pngc new file mode 100644 index 0000000..c4dee21 --- /dev/null +++ b/include/images/terminate_backend.pngc @@ -0,0 +1,90 @@ +#ifndef TERMINATE_BACKEND_PNG_H +#define TERMINATE_BACKEND_PNG_H + +static const unsigned char terminate_backend_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc6, 0x8d, 0x5f, 0xd5, +0x17, 0x17, 0xe9, 0xd0, 0xa6, 0xe3, 0xc0, 0x86, +0xe4, 0xbf, 0x83, 0xe6, 0xbe, 0x7e, 0xe8, 0xbc, +0x7a, 0xe9, 0xba, 0x75, 0xec, 0xb9, 0x70, 0xf2, +0xc8, 0x8f, 0xe3, 0xc0, 0x85, 0xf1, 0xb4, 0x64, +0xe5, 0xbf, 0x81, 0xf3, 0xb2, 0x5d, 0xe6, 0xbd, +0x7d, 0xf5, 0xb0, 0x57, 0xe9, 0xbb, 0x77, 0xf8, +0xad, 0x51, 0xec, 0xb9, 0x71, 0xfb, 0xac, 0x4c, +0xee, 0xb6, 0x6b, 0xfc, 0xaa, 0x47, 0xf4, 0xc7, +0x8b, 0xf2, 0xb3, 0x5f, 0xf5, 0xb0, 0x59, 0xf7, +0xaf, 0x54, 0xf9, 0xad, 0x4f, 0xfb, 0xab, 0x4a, +0xfe, 0xbd, 0x71, 0xbc, 0xa7, 0x14, 0xb6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x9d, 0xce, 0x37, 0x16, 0x80, +0x30, 0x10, 0x43, 0x41, 0xef, 0x02, 0x26, 0x63, +0xa2, 0xc9, 0xf7, 0xbf, 0x26, 0x85, 0x8c, 0x3a, +0x0a, 0xfc, 0xcb, 0x79, 0x2a, 0x64, 0x4c, 0x54, +0xa2, 0x21, 0x09, 0xa0, 0x49, 0x9a, 0xd9, 0xbc, +0x28, 0x2b, 0x7d, 0xa1, 0xc6, 0xa0, 0x21, 0xb4, +0x80, 0x8e, 0xe0, 0x00, 0x3d, 0x61, 0x00, 0x8c, +0x84, 0x09, 0x30, 0x13, 0x16, 0x80, 0x27, 0xac, +0xdb, 0x7e, 0x9c, 0x97, 0xbf, 0xf5, 0xeb, 0xd8, +0xcf, 0x1e, 0x14, 0x61, 0x02, 0x53, 0x9e, 0xb3, +0x53, 0xc1, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *terminate_backend_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_terminate_backend_png = new wxImage(); + if (!img_terminate_backend_png || !img_terminate_backend_png->IsOk()) + { + wxMemoryInputStream img_terminate_backend_pngIS(terminate_backend_png_data, sizeof(terminate_backend_png_data)); + img_terminate_backend_png->LoadFile(img_terminate_backend_pngIS, wxBITMAP_TYPE_PNG); + } + return img_terminate_backend_png; +} +#define terminate_backend_png_img terminate_backend_png_img() + +static wxBitmap *terminate_backend_png_bmp() +{ + static wxBitmap *bmp_terminate_backend_png; + if (!bmp_terminate_backend_png || !bmp_terminate_backend_png->IsOk()) + bmp_terminate_backend_png = new wxBitmap(*terminate_backend_png_img); + return bmp_terminate_backend_png; +} +#define terminate_backend_png_bmp terminate_backend_png_bmp() + +static wxIcon *terminate_backend_png_ico() +{ + static wxIcon *ico_terminate_backend_png; + if (!ico_terminate_backend_png || !ico_terminate_backend_png->IsOk()) + { + ico_terminate_backend_png = new wxIcon(); + ico_terminate_backend_png->CopyFromBitmap(*terminate_backend_png_bmp); + } + return ico_terminate_backend_png; +} +#define terminate_backend_png_ico terminate_backend_png_ico() + +#endif // TERMINATE_BACKEND_PNG_H diff --git a/include/images/textsearch.png b/include/images/textsearch.png new file mode 100644 index 0000000..7820b6b Binary files /dev/null and b/include/images/textsearch.png differ diff --git a/include/images/textsearch.pngc b/include/images/textsearch.pngc new file mode 100644 index 0000000..8bf4842 --- /dev/null +++ b/include/images/textsearch.pngc @@ -0,0 +1,143 @@ +#ifndef TEXTSEARCH_PNG_H +#define TEXTSEARCH_PNG_H + +static const unsigned char textsearch_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xaa, 0xb1, 0xb6, 0x8c, +0x98, 0xa0, 0xf7, 0xf9, 0xfa, 0xf2, 0xf6, 0xf8, +0xe8, 0xea, 0xec, 0xcc, 0xce, 0xce, 0xb8, 0xb9, +0xb9, 0xa6, 0xa6, 0xa6, 0xb0, 0xb1, 0xb2, 0xc2, +0xc5, 0xc6, 0xe1, 0xe6, 0xe7, 0xf3, 0xf8, 0xf9, +0x8d, 0x99, 0xa1, 0x51, 0x51, 0x51, 0x9a, 0xa6, +0xad, 0x86, 0xaf, 0xc5, 0x92, 0xc6, 0xe2, 0xa3, +0xda, 0xf7, 0x9e, 0xcc, 0xe5, 0x92, 0xb2, 0xc4, +0x87, 0x91, 0x97, 0xd2, 0xd8, 0xda, 0x8e, 0x9a, +0xa1, 0xe6, 0xea, 0xeb, 0x99, 0xa3, 0xa8, 0x77, +0xae, 0xca, 0x96, 0xd2, 0xf0, 0xbf, 0xe8, 0xfc, +0xc4, 0xeb, 0xfd, 0xbc, 0xe7, 0xfb, 0xa9, 0xdd, +0xf5, 0x88, 0xb4, 0xc8, 0x78, 0x82, 0x87, 0x8a, +0x94, 0x9b, 0xc7, 0xc9, 0xca, 0x7c, 0xa6, 0xbd, +0x92, 0xcf, 0xee, 0x48, 0x56, 0x5a, 0xd3, 0xf2, +0xfe, 0x4c, 0x57, 0x5c, 0xcb, 0xee, 0xf9, 0x44, +0x53, 0x58, 0x3a, 0x4e, 0x54, 0x75, 0x99, 0xaa, +0x7f, 0x85, 0x89, 0xac, 0xac, 0xad, 0x85, 0xbc, +0xd9, 0xd7, 0xf4, 0xfd, 0x4b, 0x57, 0x5a, 0xba, +0xe4, 0xef, 0x9b, 0xd5, 0xe6, 0x75, 0xae, 0xc5, +0x75, 0x78, 0x7a, 0xd2, 0xd2, 0xd2, 0x92, 0x92, +0x92, 0x9e, 0xd5, 0xf4, 0xd5, 0xf2, 0xfd, 0xd3, +0xf2, 0xfa, 0xcb, 0xed, 0xf6, 0xc1, 0xe9, 0xf2, +0xb1, 0xe0, 0xeb, 0x97, 0xd2, 0xe3, 0x73, 0xbb, +0xd7, 0x6f, 0x6f, 0x6f, 0xcf, 0xcf, 0xcf, 0x9e, +0x9f, 0xa0, 0x98, 0xc6, 0xdf, 0x41, 0x52, 0x55, +0xa3, 0xd9, 0xe5, 0x31, 0x49, 0x4f, 0x67, 0xa5, +0xbb, 0x6f, 0x72, 0x74, 0xb6, 0xba, 0xbb, 0x83, +0xa3, 0xb5, 0xac, 0xdf, 0xf6, 0xbe, 0xe7, 0xf5, +0xb4, 0xe1, 0xec, 0x90, 0xcf, 0xde, 0x2a, 0x45, +0x4d, 0x5e, 0x87, 0x97, 0x77, 0x7b, 0x7e, 0xd8, +0xe2, 0xe6, 0x75, 0x7f, 0x85, 0x9f, 0xd7, 0xef, +0xa2, 0xd8, 0xea, 0x8b, 0xcc, 0xde, 0x76, 0xbf, +0xd6, 0x5f, 0x95, 0xa9, 0x63, 0x6e, 0x73, 0x8a, +0x8e, 0x91, 0xd3, 0xd3, 0xd3, 0xd5, 0xd5, 0xd5, +0xe7, 0xef, 0xf2, 0x1b, 0x1b, 0x1b, 0x70, 0x7a, +0x7f, 0x71, 0x95, 0xa6, 0x78, 0xaf, 0xc6, 0x76, +0xbd, 0xd9, 0x7d, 0x7d, 0x7d, 0x99, 0x99, 0x99, +0xb3, 0xb3, 0xb3, 0xd6, 0xd6, 0xd6, 0xe7, 0xf0, +0xf3, 0xd6, 0xe5, 0xea, 0xc4, 0xd0, 0xd5, 0x7c, +0x7f, 0x81, 0x68, 0x69, 0x69, 0x91, 0x99, 0x9c, +0x98, 0x9f, 0xa1, 0x90, 0x90, 0x90, 0xf0, 0xf6, +0xf8, 0xe4, 0xee, 0xf2, 0xe2, 0xed, 0xf1, 0xe0, +0xea, 0xee, 0xdb, 0xe6, 0xe9, 0xd9, 0xe6, 0xe9, +0xd9, 0xe5, 0xe9, 0xb4, 0xb7, 0xb8, 0xbb, 0xbb, +0xbb, 0x8b, 0x97, 0x9f, 0x9a, 0x9c, 0x9e, 0xbd, +0xbd, 0xbd, 0x94, 0x94, 0x94, 0xaf, 0xaf, 0xaf, +0xab, 0xab, 0xab, 0x8f, 0x8f, 0x8f, 0x8c, 0x8c, +0x8c, 0xac, 0x78, 0xda, 0x0a, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0xcb, 0x49, 0x44, 0x41, 0x54, 0x18, +0xd3, 0x63, 0x60, 0x64, 0x82, 0x03, 0x46, 0x06, +0x10, 0x60, 0x62, 0x66, 0x61, 0x65, 0x63, 0xe7, +0xe0, 0xe4, 0xe2, 0xe6, 0xe1, 0x85, 0x08, 0xb0, +0xf0, 0xf1, 0x0b, 0x08, 0x0a, 0x09, 0x8b, 0x88, +0x8a, 0x89, 0x43, 0x04, 0x24, 0x24, 0xa5, 0xa4, +0x65, 0x64, 0xe5, 0xe4, 0x15, 0x14, 0x95, 0x20, +0x02, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, +0x5a, 0xda, 0x3a, 0xba, 0x10, 0x01, 0x3d, 0x7d, +0x39, 0x0d, 0x03, 0x43, 0x35, 0x23, 0x63, 0x13, +0x53, 0x33, 0xb0, 0x80, 0xb9, 0x85, 0xac, 0xa5, +0x95, 0xb5, 0x8d, 0xad, 0x9d, 0xbd, 0x83, 0x23, +0x58, 0xc0, 0xc9, 0x59, 0xc6, 0x50, 0xcd, 0xc6, +0xc5, 0xd5, 0xcd, 0xdd, 0x03, 0x22, 0xe0, 0xe9, +0xe5, 0xed, 0xa3, 0xe5, 0xab, 0xed, 0xe7, 0x1f, +0x10, 0x08, 0x11, 0x08, 0x0a, 0x16, 0x08, 0x09, +0x35, 0x0e, 0x0b, 0x8f, 0x88, 0x8c, 0x8a, 0x8e, +0x01, 0x09, 0xc4, 0xc6, 0xc5, 0x27, 0x24, 0x26, +0xb9, 0x07, 0x44, 0x26, 0xa7, 0xa4, 0xa6, 0x01, +0x45, 0x98, 0xd2, 0x33, 0x32, 0x25, 0xb3, 0xb2, +0x03, 0x73, 0x72, 0xf3, 0x52, 0xc1, 0x22, 0x4c, +0xf9, 0x05, 0x85, 0x45, 0xc5, 0x41, 0x41, 0x25, +0xa5, 0x65, 0xe6, 0xe5, 0x40, 0x11, 0x06, 0xb8, +0xe7, 0x2a, 0x2a, 0x2a, 0xcd, 0xab, 0xaa, 0x6b, +0x18, 0x90, 0x80, 0x59, 0x6d, 0x5d, 0x55, 0x1d, +0x03, 0xaa, 0x48, 0x3d, 0x07, 0x00, 0x52, 0x5b, +0x2a, 0x9b, 0x0f, 0x04, 0x31, 0xb5, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, +0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, +0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *textsearch_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_textsearch_png = new wxImage(); + if (!img_textsearch_png || !img_textsearch_png->IsOk()) + { + wxMemoryInputStream img_textsearch_pngIS(textsearch_png_data, sizeof(textsearch_png_data)); + img_textsearch_png->LoadFile(img_textsearch_pngIS, wxBITMAP_TYPE_PNG); + } + return img_textsearch_png; +} +#define textsearch_png_img textsearch_png_img() + +static wxBitmap *textsearch_png_bmp() +{ + static wxBitmap *bmp_textsearch_png; + if (!bmp_textsearch_png || !bmp_textsearch_png->IsOk()) + bmp_textsearch_png = new wxBitmap(*textsearch_png_img); + return bmp_textsearch_png; +} +#define textsearch_png_bmp textsearch_png_bmp() + +static wxIcon *textsearch_png_ico() +{ + static wxIcon *ico_textsearch_png; + if (!ico_textsearch_png || !ico_textsearch_png->IsOk()) + { + ico_textsearch_png = new wxIcon(); + ico_textsearch_png->CopyFromBitmap(*textsearch_png_bmp); + } + return ico_textsearch_png; +} +#define textsearch_png_ico textsearch_png_ico() + +#endif // TEXTSEARCH_PNG_H diff --git a/include/images/trigger.png b/include/images/trigger.png new file mode 100644 index 0000000..3b413e4 Binary files /dev/null and b/include/images/trigger.png differ diff --git a/include/images/trigger.pngc b/include/images/trigger.pngc new file mode 100644 index 0000000..2b171cf --- /dev/null +++ b/include/images/trigger.pngc @@ -0,0 +1,85 @@ +#ifndef TRIGGER_PNG_H +#define TRIGGER_PNG_H + +static const unsigned char trigger_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xca, 0xff, 0xf8, +0xfd, 0xff, 0xff, 0xc7, 0xff, 0xf8, 0x7d, 0xfb, +0xeb, 0x65, 0xe3, 0xd3, 0x4a, 0xc8, 0xb8, 0x34, +0xb2, 0xa2, 0x31, 0xaf, 0x9f, 0x42, 0xc0, 0xb0, +0x5b, 0xd9, 0xc9, 0xae, 0x42, 0xb9, 0xa6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x51, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x03, 0x46, +0x25, 0x45, 0x08, 0x83, 0xc9, 0xd8, 0x08, 0xca, +0x70, 0x71, 0x51, 0x80, 0x30, 0x42, 0x43, 0x83, +0x20, 0x8c, 0xb4, 0xb4, 0x34, 0xb0, 0x2a, 0xa6, +0xf2, 0xf2, 0xf2, 0x22, 0x01, 0x10, 0xa3, 0x03, +0x08, 0x40, 0xaa, 0x98, 0x66, 0xce, 0x9c, 0x39, +0x09, 0x2c, 0xb2, 0x6a, 0xd5, 0x2a, 0xb0, 0x36, +0xa6, 0xdd, 0xbb, 0x37, 0x09, 0x80, 0x19, 0x67, +0xce, 0x40, 0xcd, 0xb9, 0x7b, 0x09, 0x6a, 0x99, +0x92, 0x02, 0x03, 0x56, 0x00, 0x00, 0xea, 0x7f, +0x12, 0x4a, 0xdc, 0xb1, 0x97, 0xc5, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, +0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, +0x31, 0x2d, 0x32, 0x33, 0x54, 0x30, 0x33, 0x3a, +0x30, 0x33, 0x3a, 0x31, 0x33, 0x2b, 0x30, 0x36, +0x3a, 0x30, 0x30, 0xc9, 0x93, 0x0d, 0x70, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, +0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, +0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, +0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, +0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *trigger_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_trigger_png = new wxImage(); + if (!img_trigger_png || !img_trigger_png->IsOk()) + { + wxMemoryInputStream img_trigger_pngIS(trigger_png_data, sizeof(trigger_png_data)); + img_trigger_png->LoadFile(img_trigger_pngIS, wxBITMAP_TYPE_PNG); + } + return img_trigger_png; +} +#define trigger_png_img trigger_png_img() + +static wxBitmap *trigger_png_bmp() +{ + static wxBitmap *bmp_trigger_png; + if (!bmp_trigger_png || !bmp_trigger_png->IsOk()) + bmp_trigger_png = new wxBitmap(*trigger_png_img); + return bmp_trigger_png; +} +#define trigger_png_bmp trigger_png_bmp() + +static wxIcon *trigger_png_ico() +{ + static wxIcon *ico_trigger_png; + if (!ico_trigger_png || !ico_trigger_png->IsOk()) + { + ico_trigger_png = new wxIcon(); + ico_trigger_png->CopyFromBitmap(*trigger_png_bmp); + } + return ico_trigger_png; +} +#define trigger_png_ico trigger_png_ico() + +#endif // TRIGGER_PNG_H diff --git a/include/images/triggerbad.png b/include/images/triggerbad.png new file mode 100644 index 0000000..6cc2fe9 Binary files /dev/null and b/include/images/triggerbad.png differ diff --git a/include/images/triggerbad.pngc b/include/images/triggerbad.pngc new file mode 100644 index 0000000..caedb0e --- /dev/null +++ b/include/images/triggerbad.pngc @@ -0,0 +1,121 @@ +#ifndef TRIGGERBAD_PNG_H +#define TRIGGERBAD_PNG_H + +static const unsigned char triggerbad_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xf9, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xca, 0xff, 0xf8, +0xfd, 0xff, 0xff, 0xf7, 0xf8, 0xf8, 0xfa, 0xfa, +0xfb, 0xf8, 0xf7, 0xf8, 0xfc, 0xfe, 0xfe, 0xca, +0xea, 0xe7, 0xd7, 0x62, 0x62, 0xc5, 0x00, 0x00, +0xd0, 0x57, 0x59, 0xc4, 0xc4, 0xc8, 0xc6, 0xfd, +0xf6, 0x93, 0x94, 0xa1, 0xc5, 0x47, 0x4b, 0xdd, +0x69, 0x69, 0x43, 0x87, 0x99, 0xc5, 0x5b, 0x5d, +0xf6, 0x77, 0x77, 0xc4, 0x47, 0x4b, 0xa5, 0xa9, +0xb0, 0xbe, 0x3d, 0x42, 0xf1, 0x57, 0x57, 0x58, +0x7e, 0x8f, 0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, +0xf5, 0x6e, 0x6e, 0xbc, 0x3b, 0x40, 0xf1, 0x56, +0x56, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0x5e, +0x7b, 0x8c, 0xca, 0x51, 0x54, 0xf5, 0x6d, 0x6d, +0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, +0x55, 0xef, 0x4e, 0x4f, 0xee, 0x48, 0x48, 0x38, +0x8c, 0x9e, 0x98, 0xbe, 0xbc, 0xf3, 0x61, 0x61, +0xf1, 0x5b, 0x5b, 0xf0, 0x54, 0x54, 0xef, 0x4d, +0x4e, 0xee, 0x47, 0x47, 0x36, 0xaf, 0xa0, 0xa3, +0xc0, 0xbd, 0xda, 0x65, 0x65, 0xf0, 0x53, 0x54, +0xef, 0x4d, 0x4d, 0xee, 0x46, 0x46, 0xaa, 0x2c, +0x33, 0x8f, 0xc2, 0xbe, 0xd6, 0x62, 0x62, 0xf0, +0x53, 0x53, 0xef, 0x4c, 0x4c, 0xee, 0x45, 0x45, +0xec, 0x3e, 0x3f, 0xeb, 0x38, 0x38, 0x4d, 0x83, +0x94, 0xba, 0x44, 0x46, 0xf0, 0x52, 0x52, 0xef, +0x4b, 0x4b, 0xed, 0x44, 0x45, 0xeb, 0x37, 0x37, +0xea, 0x31, 0x31, 0xe9, 0x2b, 0x2b, 0x83, 0x6c, +0x7c, 0xf0, 0x51, 0x51, 0xee, 0x4a, 0x4a, 0xed, +0x43, 0x44, 0x99, 0x43, 0x4a, 0xe9, 0x2a, 0x2b, +0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, 0xed, 0x42, +0x43, 0xc4, 0x46, 0x4a, 0x99, 0x44, 0x4b, 0xe7, +0x1f, 0x20, 0xaf, 0xf9, 0x42, 0x9f, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0xa0, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x6d, 0xcd, 0xd5, 0x0e, 0xc2, 0x60, +0x0c, 0x05, 0xe0, 0x7f, 0x1d, 0xbe, 0x83, 0xbb, +0xcb, 0x70, 0xf7, 0xe1, 0x0e, 0xc3, 0xed, 0xfd, +0x1f, 0x86, 0x01, 0x5b, 0x32, 0x12, 0x7a, 0xd1, +0xa4, 0x5f, 0xda, 0x1e, 0xc6, 0xfe, 0x14, 0x47, +0x44, 0x9c, 0x1e, 0x88, 0xe7, 0x79, 0xfa, 0x01, +0x83, 0x52, 0x7a, 0x21, 0xa3, 0xc9, 0x6c, 0xb1, +0xea, 0x84, 0x6c, 0x02, 0xec, 0x0e, 0xa7, 0xcb, +0x0d, 0xcf, 0x17, 0xbc, 0x3e, 0xf8, 0x11, 0x08, +0x86, 0x10, 0x56, 0x25, 0x82, 0x68, 0x2c, 0x8e, +0x04, 0x92, 0xa9, 0x34, 0x3e, 0x90, 0x11, 0x91, +0xcd, 0xe5, 0x51, 0x28, 0x96, 0xd4, 0x8d, 0x72, +0x45, 0x40, 0xb5, 0x56, 0x6f, 0x34, 0xb5, 0x1f, +0xd4, 0x6a, 0x77, 0xd0, 0xed, 0xf5, 0x21, 0x69, +0x29, 0x83, 0x21, 0x46, 0xe3, 0xc9, 0x74, 0xa6, +0x6d, 0xcc, 0x17, 0x58, 0xae, 0xd6, 0xd8, 0x6c, +0x77, 0xaa, 0xc8, 0xd8, 0x1f, 0x8e, 0x38, 0xe1, +0x7c, 0xb9, 0x7e, 0x53, 0x64, 0x11, 0x37, 0xdc, +0xd9, 0x03, 0x4f, 0xed, 0x86, 0x49, 0x90, 0xe4, +0x77, 0x57, 0xe6, 0x17, 0x59, 0x1e, 0x10, 0xc8, +0x4e, 0x56, 0xd8, 0x80, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, 0x2d, +0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, 0x37, +0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xd3, 0xe6, 0xa8, 0x62, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x33, +0x2d, 0x30, 0x38, 0x54, 0x31, 0x32, 0x3a, 0x31, +0x37, 0x3a, 0x30, 0x39, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0xa2, 0xbb, 0x10, 0xde, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggerbad_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggerbad_png = new wxImage(); + if (!img_triggerbad_png || !img_triggerbad_png->IsOk()) + { + wxMemoryInputStream img_triggerbad_pngIS(triggerbad_png_data, sizeof(triggerbad_png_data)); + img_triggerbad_png->LoadFile(img_triggerbad_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggerbad_png; +} +#define triggerbad_png_img triggerbad_png_img() + +static wxBitmap *triggerbad_png_bmp() +{ + static wxBitmap *bmp_triggerbad_png; + if (!bmp_triggerbad_png || !bmp_triggerbad_png->IsOk()) + bmp_triggerbad_png = new wxBitmap(*triggerbad_png_img); + return bmp_triggerbad_png; +} +#define triggerbad_png_bmp triggerbad_png_bmp() + +static wxIcon *triggerbad_png_ico() +{ + static wxIcon *ico_triggerbad_png; + if (!ico_triggerbad_png || !ico_triggerbad_png->IsOk()) + { + ico_triggerbad_png = new wxIcon(); + ico_triggerbad_png->CopyFromBitmap(*triggerbad_png_bmp); + } + return ico_triggerbad_png; +} +#define triggerbad_png_ico triggerbad_png_ico() + +#endif // TRIGGERBAD_PNG_H diff --git a/include/images/triggerfunction.png b/include/images/triggerfunction.png new file mode 100644 index 0000000..2b8ba80 Binary files /dev/null and b/include/images/triggerfunction.png differ diff --git a/include/images/triggerfunction.pngc b/include/images/triggerfunction.pngc new file mode 100644 index 0000000..7457df2 --- /dev/null +++ b/include/images/triggerfunction.pngc @@ -0,0 +1,86 @@ +#ifndef TRIGGERFUNCTION_PNG_H +#define TRIGGERFUNCTION_PNG_H + +static const unsigned char triggerfunction_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xca, 0xff, 0xf8, +0xfd, 0xff, 0xff, 0xc7, 0xff, 0xf8, 0x7d, 0xfb, +0xeb, 0x65, 0xe3, 0xd3, 0x4a, 0xc8, 0xb8, 0x34, +0xb2, 0xa2, 0x31, 0xaf, 0x9f, 0x42, 0xc0, 0xb0, +0x5b, 0xd9, 0xc9, 0xae, 0x42, 0xb9, 0xa6, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x5b, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x80, 0x01, 0x46, +0x45, 0x10, 0x02, 0x02, 0x26, 0x23, 0x01, 0x20, +0x02, 0x31, 0x5c, 0x14, 0x81, 0x08, 0xc4, 0x08, +0x0d, 0x12, 0x0a, 0x0d, 0x02, 0x0a, 0x31, 0xa5, +0xa5, 0x29, 0xa5, 0xa5, 0x01, 0x85, 0x98, 0xca, +0xcb, 0x8b, 0x80, 0x48, 0x80, 0x81, 0xa9, 0x03, +0x0c, 0x14, 0x18, 0x98, 0x66, 0xce, 0x9c, 0x04, +0x44, 0x40, 0x91, 0x55, 0xab, 0x94, 0x56, 0xad, +0x02, 0xa9, 0xd9, 0xbd, 0x49, 0x68, 0xf7, 0x26, +0x90, 0xae, 0x33, 0x8a, 0x40, 0x04, 0x32, 0xe7, +0x92, 0x00, 0x10, 0x21, 0xdb, 0x85, 0x01, 0x00, +0xb7, 0x48, 0x18, 0x7d, 0xbf, 0x04, 0xc2, 0x0a, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggerfunction_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggerfunction_png = new wxImage(); + if (!img_triggerfunction_png || !img_triggerfunction_png->IsOk()) + { + wxMemoryInputStream img_triggerfunction_pngIS(triggerfunction_png_data, sizeof(triggerfunction_png_data)); + img_triggerfunction_png->LoadFile(img_triggerfunction_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggerfunction_png; +} +#define triggerfunction_png_img triggerfunction_png_img() + +static wxBitmap *triggerfunction_png_bmp() +{ + static wxBitmap *bmp_triggerfunction_png; + if (!bmp_triggerfunction_png || !bmp_triggerfunction_png->IsOk()) + bmp_triggerfunction_png = new wxBitmap(*triggerfunction_png_img); + return bmp_triggerfunction_png; +} +#define triggerfunction_png_bmp triggerfunction_png_bmp() + +static wxIcon *triggerfunction_png_ico() +{ + static wxIcon *ico_triggerfunction_png; + if (!ico_triggerfunction_png || !ico_triggerfunction_png->IsOk()) + { + ico_triggerfunction_png = new wxIcon(); + ico_triggerfunction_png->CopyFromBitmap(*triggerfunction_png_bmp); + } + return ico_triggerfunction_png; +} +#define triggerfunction_png_ico triggerfunction_png_ico() + +#endif // TRIGGERFUNCTION_PNG_H diff --git a/include/images/triggerfunctions.png b/include/images/triggerfunctions.png new file mode 100644 index 0000000..d310acb Binary files /dev/null and b/include/images/triggerfunctions.png differ diff --git a/include/images/triggerfunctions.pngc b/include/images/triggerfunctions.pngc new file mode 100644 index 0000000..41059ff --- /dev/null +++ b/include/images/triggerfunctions.pngc @@ -0,0 +1,89 @@ +#ifndef TRIGGERFUNCTIONS_PNG_H +#define TRIGGERFUNCTIONS_PNG_H + +static const unsigned char triggerfunctions_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x30, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xe0, 0xff, 0xfb, +0x78, 0xbe, 0xc7, 0x52, 0xa4, 0xb3, 0xed, 0xff, +0xfd, 0x7d, 0xbe, 0xc8, 0x92, 0xff, 0xf1, 0x3e, +0x99, 0xa9, 0x69, 0xe7, 0xd7, 0x47, 0xc5, 0xb5, +0x30, 0xae, 0x9e, 0x39, 0xb7, 0xa7, 0x56, 0xd4, +0xc4, 0xda, 0xce, 0x6c, 0xda, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x08, +0xd7, 0x63, 0x10, 0x12, 0x10, 0x12, 0x60, 0x00, +0x01, 0x65, 0x45, 0x65, 0x45, 0x30, 0x43, 0x25, +0x48, 0x25, 0x28, 0x01, 0xc4, 0x50, 0x57, 0xd6, +0x50, 0x56, 0x03, 0x31, 0x34, 0x41, 0x42, 0x0b, +0x80, 0x0c, 0x6d, 0x98, 0x90, 0x8e, 0xa6, 0x8a, +0x93, 0x8a, 0x13, 0x50, 0x95, 0xae, 0xb6, 0x7a, +0xb9, 0x7a, 0x39, 0x50, 0xa3, 0x9e, 0x8e, 0xe6, +0xcc, 0x99, 0x33, 0x27, 0x09, 0x30, 0xe8, 0xeb, +0x6a, 0xef, 0x06, 0x02, 0x05, 0x06, 0x21, 0x3d, +0x9d, 0x33, 0x67, 0xce, 0x1c, 0x02, 0x9a, 0xae, +0xaf, 0x7b, 0x57, 0xf7, 0x2e, 0xc8, 0x70, 0x21, +0xbd, 0x47, 0x7a, 0x8f, 0xc0, 0xd6, 0xe9, 0x2b, +0xea, 0x43, 0x6c, 0x83, 0xdb, 0x0f, 0x01, 0x00, +0x67, 0xa7, 0x18, 0x54, 0xdf, 0x8b, 0x90, 0xdd, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggerfunctions_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggerfunctions_png = new wxImage(); + if (!img_triggerfunctions_png || !img_triggerfunctions_png->IsOk()) + { + wxMemoryInputStream img_triggerfunctions_pngIS(triggerfunctions_png_data, sizeof(triggerfunctions_png_data)); + img_triggerfunctions_png->LoadFile(img_triggerfunctions_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggerfunctions_png; +} +#define triggerfunctions_png_img triggerfunctions_png_img() + +static wxBitmap *triggerfunctions_png_bmp() +{ + static wxBitmap *bmp_triggerfunctions_png; + if (!bmp_triggerfunctions_png || !bmp_triggerfunctions_png->IsOk()) + bmp_triggerfunctions_png = new wxBitmap(*triggerfunctions_png_img); + return bmp_triggerfunctions_png; +} +#define triggerfunctions_png_bmp triggerfunctions_png_bmp() + +static wxIcon *triggerfunctions_png_ico() +{ + static wxIcon *ico_triggerfunctions_png; + if (!ico_triggerfunctions_png || !ico_triggerfunctions_png->IsOk()) + { + ico_triggerfunctions_png = new wxIcon(); + ico_triggerfunctions_png->CopyFromBitmap(*triggerfunctions_png_bmp); + } + return ico_triggerfunctions_png; +} +#define triggerfunctions_png_ico triggerfunctions_png_ico() + +#endif // TRIGGERFUNCTIONS_PNG_H diff --git a/include/images/triggers.png b/include/images/triggers.png new file mode 100644 index 0000000..3c33940 Binary files /dev/null and b/include/images/triggers.png differ diff --git a/include/images/triggers.pngc b/include/images/triggers.pngc new file mode 100644 index 0000000..a229be0 --- /dev/null +++ b/include/images/triggers.pngc @@ -0,0 +1,88 @@ +#ifndef TRIGGERS_PNG_H +#define TRIGGERS_PNG_H + +static const unsigned char triggers_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x85, 0xbe, 0xc9, 0x2f, +0x91, 0xa3, 0x74, 0xf2, 0xe2, 0xe0, 0xff, 0xfb, +0x78, 0xbe, 0xc7, 0xed, 0xff, 0xfd, 0x92, 0xff, +0xf1, 0x69, 0xe7, 0xd7, 0x47, 0xc5, 0xb5, 0x30, +0xae, 0x9e, 0x39, 0xb7, 0xa7, 0x56, 0xd4, 0xc4, +0x62, 0xdf, 0x01, 0xa4, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x10, 0x52, 0x12, 0x60, 0x00, 0x03, 0x65, +0x63, 0x05, 0x08, 0x43, 0xc5, 0x55, 0x49, 0x11, +0xcc, 0x50, 0x4b, 0x32, 0x36, 0x02, 0x4b, 0xaa, +0x17, 0xb9, 0x04, 0x81, 0x95, 0x69, 0x34, 0xa5, +0x41, 0x94, 0x69, 0x4e, 0x2a, 0x57, 0x71, 0x71, +0x02, 0x0a, 0x69, 0x2d, 0xea, 0x50, 0x4b, 0x4b, +0x03, 0xaa, 0xd7, 0xde, 0x34, 0x53, 0xbd, 0xbc, +0xbc, 0x88, 0x81, 0x41, 0xe7, 0xd0, 0x2a, 0x8d, +0x8e, 0x8e, 0x0e, 0x05, 0x06, 0x21, 0xa5, 0xdd, +0x9a, 0x33, 0x67, 0x4e, 0x02, 0x2a, 0x62, 0x3a, +0xa3, 0xb5, 0x6a, 0x15, 0xc8, 0x4c, 0x46, 0x25, +0xed, 0xdd, 0x9b, 0x20, 0xb6, 0xe8, 0x9c, 0x81, +0x58, 0xc2, 0xc0, 0xa4, 0xc4, 0x80, 0x04, 0x00, +0x82, 0x8a, 0x18, 0x64, 0x25, 0x1c, 0x07, 0x64, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *triggers_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_triggers_png = new wxImage(); + if (!img_triggers_png || !img_triggers_png->IsOk()) + { + wxMemoryInputStream img_triggers_pngIS(triggers_png_data, sizeof(triggers_png_data)); + img_triggers_png->LoadFile(img_triggers_pngIS, wxBITMAP_TYPE_PNG); + } + return img_triggers_png; +} +#define triggers_png_img triggers_png_img() + +static wxBitmap *triggers_png_bmp() +{ + static wxBitmap *bmp_triggers_png; + if (!bmp_triggers_png || !bmp_triggers_png->IsOk()) + bmp_triggers_png = new wxBitmap(*triggers_png_img); + return bmp_triggers_png; +} +#define triggers_png_bmp triggers_png_bmp() + +static wxIcon *triggers_png_ico() +{ + static wxIcon *ico_triggers_png; + if (!ico_triggers_png || !ico_triggers_png->IsOk()) + { + ico_triggers_png = new wxIcon(); + ico_triggers_png->CopyFromBitmap(*triggers_png_bmp); + } + return ico_triggers_png; +} +#define triggers_png_ico triggers_png_ico() + +#endif // TRIGGERS_PNG_H diff --git a/include/images/type.png b/include/images/type.png new file mode 100644 index 0000000..6c16764 Binary files /dev/null and b/include/images/type.png differ diff --git a/include/images/type.pngc b/include/images/type.pngc new file mode 100644 index 0000000..ab654c7 --- /dev/null +++ b/include/images/type.pngc @@ -0,0 +1,85 @@ +#ifndef TYPE_PNG_H +#define TYPE_PNG_H + +static const unsigned char type_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x27, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9e, 0xe0, 0xc4, 0x5a, +0xcb, 0x9a, 0xd6, 0xff, 0xea, 0xce, 0xff, 0xe5, +0xc5, 0xff, 0xe1, 0xba, 0xff, 0xdb, 0xac, 0xff, +0xd3, 0x9e, 0xff, 0xcc, 0x90, 0xff, 0xc5, 0x82, +0xff, 0xbd, 0x77, 0xff, 0xb7, 0x6e, 0xff, 0xb3, +0x65, 0x03, 0x10, 0x6b, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x55, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, +0x63, 0x60, 0xc0, 0x04, 0x42, 0x4a, 0x40, 0xa0, +0x08, 0x64, 0x28, 0x1b, 0x03, 0x81, 0x11, 0x90, +0xa1, 0xe2, 0x02, 0x04, 0x4e, 0x40, 0x86, 0x6a, +0x28, 0x10, 0x04, 0x01, 0x19, 0x6a, 0x69, 0x40, +0x90, 0x04, 0x64, 0xa8, 0x97, 0x03, 0x41, 0x11, +0x90, 0xa1, 0xd1, 0x01, 0x04, 0x4d, 0x40, 0x86, +0xe6, 0x4c, 0x20, 0x98, 0x04, 0x64, 0x68, 0xad, +0x02, 0x82, 0x45, 0x40, 0x86, 0xf6, 0x6e, 0x20, +0xd8, 0x04, 0x64, 0xe8, 0x9c, 0x01, 0x82, 0x43, +0x30, 0x2b, 0x14, 0xb0, 0xd8, 0x0d, 0x00, 0xcb, +0xbc, 0x1b, 0xb1, 0xe0, 0x4d, 0x88, 0x44, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *type_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_type_png = new wxImage(); + if (!img_type_png || !img_type_png->IsOk()) + { + wxMemoryInputStream img_type_pngIS(type_png_data, sizeof(type_png_data)); + img_type_png->LoadFile(img_type_pngIS, wxBITMAP_TYPE_PNG); + } + return img_type_png; +} +#define type_png_img type_png_img() + +static wxBitmap *type_png_bmp() +{ + static wxBitmap *bmp_type_png; + if (!bmp_type_png || !bmp_type_png->IsOk()) + bmp_type_png = new wxBitmap(*type_png_img); + return bmp_type_png; +} +#define type_png_bmp type_png_bmp() + +static wxIcon *type_png_ico() +{ + static wxIcon *ico_type_png; + if (!ico_type_png || !ico_type_png->IsOk()) + { + ico_type_png = new wxIcon(); + ico_type_png->CopyFromBitmap(*type_png_bmp); + } + return ico_type_png; +} +#define type_png_ico type_png_ico() + +#endif // TYPE_PNG_H diff --git a/include/images/types.png b/include/images/types.png new file mode 100644 index 0000000..fb020d7 Binary files /dev/null and b/include/images/types.png differ diff --git a/include/images/types.pngc b/include/images/types.pngc new file mode 100644 index 0000000..6b5d965 --- /dev/null +++ b/include/images/types.pngc @@ -0,0 +1,86 @@ +#ifndef TYPES_PNG_H +#define TYPES_PNG_H + +static const unsigned char types_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x24, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x5a, 0xcb, 0x9a, 0xd6, +0xff, 0xea, 0xce, 0xff, 0xe5, 0x8a, 0xe0, 0xb9, +0xc2, 0xff, 0xdf, 0xb4, 0xff, 0xd8, 0xa6, 0xff, +0xd1, 0x96, 0xff, 0xc8, 0x87, 0xff, 0xc0, 0x79, +0xff, 0xb9, 0x6e, 0xff, 0xb3, 0xa2, 0x9e, 0xb9, +0x1d, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, +0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x5c, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x3d, 0xcd, 0x5b, +0x0d, 0x80, 0x30, 0x0c, 0x46, 0xe1, 0xce, 0x41, +0x61, 0x59, 0x77, 0x7b, 0xc3, 0x02, 0x0a, 0x10, +0x81, 0x05, 0x2c, 0x60, 0x01, 0x0b, 0x58, 0xc0, +0x02, 0xe6, 0x38, 0x0b, 0x8c, 0xef, 0xe9, 0xcf, +0x49, 0x9a, 0x8a, 0x1b, 0x20, 0x18, 0x27, 0x28, +0xc3, 0x2f, 0x5f, 0x0a, 0x3d, 0x59, 0x4f, 0xb1, +0xa7, 0x64, 0x7e, 0x86, 0x4a, 0x8e, 0x61, 0x85, +0x4a, 0x49, 0xb6, 0x41, 0xa5, 0xe6, 0xb8, 0x43, +0xc5, 0x95, 0x74, 0x80, 0xfb, 0x9a, 0x4f, 0x30, +0x5c, 0xb9, 0xd0, 0x9e, 0xd4, 0x1b, 0x6d, 0xfc, +0xff, 0x5f, 0x0f, 0x09, 0xd3, 0x15, 0xf2, 0x10, +0xf1, 0x85, 0x33, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *types_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_types_png = new wxImage(); + if (!img_types_png || !img_types_png->IsOk()) + { + wxMemoryInputStream img_types_pngIS(types_png_data, sizeof(types_png_data)); + img_types_png->LoadFile(img_types_pngIS, wxBITMAP_TYPE_PNG); + } + return img_types_png; +} +#define types_png_img types_png_img() + +static wxBitmap *types_png_bmp() +{ + static wxBitmap *bmp_types_png; + if (!bmp_types_png || !bmp_types_png->IsOk()) + bmp_types_png = new wxBitmap(*types_png_img); + return bmp_types_png; +} +#define types_png_bmp types_png_bmp() + +static wxIcon *types_png_ico() +{ + static wxIcon *ico_types_png; + if (!ico_types_png || !ico_types_png->IsOk()) + { + ico_types_png = new wxIcon(); + ico_types_png->CopyFromBitmap(*types_png_bmp); + } + return ico_types_png; +} +#define types_png_ico types_png_ico() + +#endif // TYPES_PNG_H diff --git a/include/images/uncheck.png b/include/images/uncheck.png new file mode 100644 index 0000000..b655bc7 Binary files /dev/null and b/include/images/uncheck.png differ diff --git a/include/images/uncheck.pngc b/include/images/uncheck.pngc new file mode 100644 index 0000000..c5e5d2d --- /dev/null +++ b/include/images/uncheck.pngc @@ -0,0 +1,122 @@ +#ifndef UNCHECK_PNG_H +#define UNCHECK_PNG_H + +static const unsigned char uncheck_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xf3, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xd2, 0xa1, 0xa5, +0xb9, 0x6e, 0xb0, 0xc1, 0x7f, 0xd5, 0xde, 0xbc, +0x71, 0x93, 0x17, 0x8f, 0xb6, 0x37, 0xa4, 0xcd, +0x4e, 0x9d, 0xc5, 0x47, 0xc7, 0xd3, 0xa4, 0x82, +0xa8, 0x2a, 0xac, 0xd8, 0x57, 0xb1, 0xdd, 0x5d, +0x87, 0xac, 0x2f, 0xcc, 0xd7, 0xad, 0xb5, 0xe3, +0x62, 0x7c, 0xa0, 0x23, 0xce, 0xd9, 0xb1, 0x8a, +0xb2, 0x31, 0x9c, 0xc7, 0x45, 0xa3, 0xcf, 0x4c, +0xac, 0xd7, 0x58, 0xc3, 0xf1, 0x70, 0x7f, 0xa3, +0x27, 0x87, 0xad, 0x2f, 0xb1, 0xde, 0x5c, 0x9e, +0xc7, 0x49, 0xdc, 0x64, 0x57, 0xc5, 0x00, 0x00, +0xd5, 0x5d, 0x3f, 0xd2, 0x5d, 0x3e, 0xbb, 0x3c, +0x14, 0xdd, 0x66, 0x62, 0xf6, 0x77, 0x77, 0xd1, +0x5b, 0x36, 0xf1, 0x57, 0x57, 0xdd, 0x69, 0x69, +0xf6, 0x76, 0x76, 0xf6, 0x72, 0x72, 0xf5, 0x6e, +0x6e, 0xef, 0x4f, 0x4f, 0xee, 0x48, 0x49, 0xaf, +0xc1, 0x7e, 0xdd, 0x67, 0x62, 0xf5, 0x6d, 0x6d, +0xf4, 0x68, 0x68, 0xf3, 0x62, 0x62, 0xf0, 0x55, +0x55, 0xdc, 0xe4, 0xc7, 0xf3, 0x61, 0x61, 0xf1, +0x5b, 0x5b, 0xf0, 0x53, 0x54, 0xef, 0x4d, 0x4e, +0xee, 0x47, 0x47, 0xd9, 0x62, 0x4a, 0xef, 0x4d, +0x4d, 0xd4, 0x5e, 0x46, 0xf0, 0x53, 0x53, 0xef, +0x4c, 0x4c, 0xee, 0x45, 0x45, 0xec, 0x3e, 0x3f, +0xeb, 0x38, 0x38, 0xf0, 0x52, 0x52, 0xef, 0x4b, +0x4b, 0xed, 0x44, 0x45, 0xeb, 0x37, 0x37, 0xea, +0x31, 0x31, 0xe9, 0x2b, 0x2b, 0xf0, 0x51, 0x51, +0xee, 0x4a, 0x4a, 0xed, 0x43, 0x44, 0xd0, 0x5a, +0x33, 0xe8, 0x25, 0x25, 0xe7, 0x20, 0x20, 0xd5, +0x5b, 0x4b, 0xed, 0x42, 0x43, 0xcb, 0x52, 0x2c, +0xe7, 0x1f, 0x20, 0xbc, 0x3e, 0x17, 0xca, 0x51, +0x3c, 0xdb, 0x67, 0x64, 0xec, 0x28, 0xa6, 0x31, +0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, +0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, +0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, +0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, +0x6b, 0x3e, 0x00, 0x00, 0x00, 0xad, 0x49, 0x44, +0x41, 0x54, 0x18, 0xd3, 0x4d, 0x8d, 0x57, 0x16, +0x82, 0x50, 0x10, 0x43, 0x47, 0x05, 0x0b, 0xa2, +0x62, 0x2f, 0xc4, 0x8a, 0x1d, 0x7b, 0xef, 0x0d, +0x15, 0xbb, 0xee, 0x7f, 0x35, 0x22, 0x4f, 0x3c, +0xe6, 0x6b, 0x92, 0xdc, 0x93, 0x21, 0xb2, 0x64, +0xb3, 0x3b, 0xe8, 0x4f, 0x1c, 0xef, 0x74, 0xb9, +0xff, 0x12, 0x8f, 0xe0, 0x15, 0x7d, 0xcc, 0xfb, +0x1d, 0x76, 0x1b, 0x71, 0x42, 0x40, 0x94, 0x82, +0xac, 0x0b, 0x85, 0x23, 0x4e, 0x9e, 0x8f, 0xc6, +0xe2, 0x5f, 0x6f, 0x10, 0x89, 0xa4, 0x37, 0x25, +0x23, 0x6d, 0xdc, 0x19, 0x64, 0x3f, 0x51, 0x50, +0x12, 0x73, 0xc8, 0xa3, 0x40, 0x04, 0x05, 0x45, +0x93, 0x8a, 0xa3, 0x54, 0xae, 0x80, 0x48, 0xa9, +0xd6, 0x60, 0x06, 0x75, 0x15, 0x8d, 0x66, 0x0b, +0x6d, 0xc3, 0x33, 0x82, 0x3a, 0x32, 0xba, 0xbd, +0xfe, 0x60, 0xc8, 0x36, 0x4c, 0x8d, 0xd0, 0x1f, +0x0f, 0x31, 0xf9, 0x79, 0x19, 0xd3, 0xd9, 0x7c, +0xb1, 0xfc, 0x11, 0x2a, 0x56, 0xeb, 0x0d, 0xb6, +0x3b, 0xcd, 0xda, 0xc0, 0xfe, 0x70, 0x84, 0x0e, +0xed, 0x74, 0x66, 0x5f, 0xe8, 0x82, 0x2b, 0x74, +0xba, 0xe1, 0x6e, 0x11, 0xf4, 0x30, 0x9b, 0x27, +0x5e, 0xf4, 0x06, 0xf8, 0xce, 0x13, 0x09, 0x57, +0x25, 0x1b, 0xb9, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, 0x30, +0x35, 0x54, 0x31, 0x38, 0x3a, 0x30, 0x39, 0x3a, +0x33, 0x32, 0x2b, 0x30, 0x36, 0x3a, 0x30, 0x30, +0xc7, 0x88, 0x36, 0x86, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, 0x2d, +0x30, 0x35, 0x54, 0x31, 0x38, 0x3a, 0x30, 0x39, +0x3a, 0x33, 0x32, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0xb6, 0xd5, 0x8e, 0x3a, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *uncheck_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_uncheck_png = new wxImage(); + if (!img_uncheck_png || !img_uncheck_png->IsOk()) + { + wxMemoryInputStream img_uncheck_pngIS(uncheck_png_data, sizeof(uncheck_png_data)); + img_uncheck_png->LoadFile(img_uncheck_pngIS, wxBITMAP_TYPE_PNG); + } + return img_uncheck_png; +} +#define uncheck_png_img uncheck_png_img() + +static wxBitmap *uncheck_png_bmp() +{ + static wxBitmap *bmp_uncheck_png; + if (!bmp_uncheck_png || !bmp_uncheck_png->IsOk()) + bmp_uncheck_png = new wxBitmap(*uncheck_png_img); + return bmp_uncheck_png; +} +#define uncheck_png_bmp uncheck_png_bmp() + +static wxIcon *uncheck_png_ico() +{ + static wxIcon *ico_uncheck_png; + if (!ico_uncheck_png || !ico_uncheck_png->IsOk()) + { + ico_uncheck_png = new wxIcon(); + ico_uncheck_png->CopyFromBitmap(*uncheck_png_bmp); + } + return ico_uncheck_png; +} +#define uncheck_png_ico uncheck_png_ico() + +#endif // UNCHECK_PNG_H diff --git a/include/images/unchecked.png b/include/images/unchecked.png new file mode 100644 index 0000000..7573ac7 Binary files /dev/null and b/include/images/unchecked.png differ diff --git a/include/images/unchecked.pngc b/include/images/unchecked.pngc new file mode 100644 index 0000000..2dd8371 --- /dev/null +++ b/include/images/unchecked.pngc @@ -0,0 +1,78 @@ +#ifndef UNCHECKED_PNG_H +#define UNCHECKED_PNG_H + +static const unsigned char unchecked_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x0f, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xff, +0xff, 0xff, 0x40, 0x40, 0x40, 0xd4, 0xd0, 0xc8, +0x11, 0xa7, 0xec, 0x07, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, +0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, 0x00, 0x00, +0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, +0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, 0x46, +0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x00, 0x26, 0x49, +0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xc0, +0x00, 0x8c, 0x82, 0x20, 0x20, 0x04, 0x64, 0x18, +0x83, 0x80, 0x13, 0x90, 0x61, 0xa4, 0x04, 0x04, +0xd4, 0x64, 0xb8, 0x80, 0x00, 0x90, 0xc1, 0xa4, +0x04, 0x06, 0x08, 0xcb, 0x01, 0x45, 0x44, 0x0c, +0xf5, 0xc7, 0x0f, 0x8b, 0x17, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x31, 0x32, 0x54, 0x31, 0x34, 0x3a, 0x30, +0x30, 0x3a, 0x34, 0x30, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x46, 0x22, 0x8f, 0xb1, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *unchecked_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_unchecked_png = new wxImage(); + if (!img_unchecked_png || !img_unchecked_png->IsOk()) + { + wxMemoryInputStream img_unchecked_pngIS(unchecked_png_data, sizeof(unchecked_png_data)); + img_unchecked_png->LoadFile(img_unchecked_pngIS, wxBITMAP_TYPE_PNG); + } + return img_unchecked_png; +} +#define unchecked_png_img unchecked_png_img() + +static wxBitmap *unchecked_png_bmp() +{ + static wxBitmap *bmp_unchecked_png; + if (!bmp_unchecked_png || !bmp_unchecked_png->IsOk()) + bmp_unchecked_png = new wxBitmap(*unchecked_png_img); + return bmp_unchecked_png; +} +#define unchecked_png_bmp unchecked_png_bmp() + +static wxIcon *unchecked_png_ico() +{ + static wxIcon *ico_unchecked_png; + if (!ico_unchecked_png || !ico_unchecked_png->IsOk()) + { + ico_unchecked_png = new wxIcon(); + ico_unchecked_png->CopyFromBitmap(*unchecked_png_bmp); + } + return ico_unchecked_png; +} +#define unchecked_png_ico unchecked_png_ico() + +#endif // UNCHECKED_PNG_H diff --git a/include/images/unique.png b/include/images/unique.png new file mode 100644 index 0000000..e828572 Binary files /dev/null and b/include/images/unique.png differ diff --git a/include/images/unique.pngc b/include/images/unique.pngc new file mode 100644 index 0000000..3614582 --- /dev/null +++ b/include/images/unique.pngc @@ -0,0 +1,97 @@ +#ifndef UNIQUE_PNG_H +#define UNIQUE_PNG_H + +static const unsigned char unique_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x81, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x83, 0xa5, 0xd8, 0x2c, +0x66, 0xbd, 0x8e, 0xad, 0xdc, 0x6e, 0xa1, 0xd2, +0x86, 0xc3, 0xdc, 0x9c, 0xcc, 0xe3, 0x4d, 0x83, +0xc8, 0x72, 0xb5, 0xd6, 0x57, 0xa9, 0xcf, 0x7c, +0xba, 0xdb, 0xa7, 0xd4, 0xe5, 0x8e, 0xc6, 0xde, +0x6a, 0xb2, 0xd5, 0x55, 0xa5, 0xd0, 0x7d, 0xb9, +0xdc, 0x69, 0xa4, 0xd4, 0x58, 0xa4, 0xd3, 0x7d, +0xb6, 0xdd, 0x3b, 0x71, 0xc2, 0x85, 0xb9, 0xde, +0x59, 0xa1, 0xd5, 0x7e, 0xb4, 0xdf, 0x64, 0x8f, +0xcf, 0x72, 0xa7, 0xd8, 0x5a, 0x9f, 0xd7, 0x7f, +0xb2, 0xe0, 0x85, 0xb6, 0xe0, 0x5b, 0x9c, 0xd9, +0x80, 0xb0, 0xe2, 0x76, 0xa5, 0xda, 0x5e, 0x9b, +0xdb, 0x80, 0xae, 0xe3, 0x6e, 0x9e, 0xda, 0x5e, +0x99, 0xdc, 0x76, 0xa6, 0xe3, 0xaa, 0xcb, 0xec, +0xa2, 0xc5, 0xea, 0x90, 0xb8, 0xe7, 0x83, 0xae, +0xe5, 0x8c, 0xb2, 0xe8, 0xa0, 0xbf, 0xec, 0xac, +0xc6, 0xef, 0x6e, 0x10, 0x68, 0x18, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, +0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, +0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, +0x00, 0x00, 0x00, 0x5c, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x8d, 0x8e, 0x35, 0x0e, 0xc0, 0x50, +0x0c, 0x43, 0x7f, 0x5d, 0x66, 0x66, 0x66, 0xb8, +0xff, 0x01, 0x2b, 0x75, 0x69, 0x32, 0x54, 0xaa, +0x37, 0x3f, 0x39, 0xb1, 0x85, 0xf8, 0x29, 0x09, +0x90, 0xa8, 0x97, 0x15, 0x55, 0x03, 0xf1, 0xd0, +0x0d, 0xd3, 0x22, 0x00, 0xb6, 0xe3, 0x7a, 0x3e, +0xd8, 0x83, 0x20, 0x8c, 0xe8, 0x89, 0x88, 0x93, +0x34, 0x63, 0x20, 0x2f, 0xca, 0x8a, 0x27, 0xea, +0xa6, 0xe5, 0x89, 0xae, 0x1f, 0x58, 0x2d, 0xc6, +0x69, 0xc6, 0x4b, 0xb0, 0xac, 0xdb, 0x7e, 0x9c, +0x17, 0x48, 0xed, 0x23, 0x36, 0xfe, 0x5b, 0x37, +0xa9, 0x13, 0x03, 0xea, 0x7a, 0x3c, 0xc8, 0x3c, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *unique_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_unique_png = new wxImage(); + if (!img_unique_png || !img_unique_png->IsOk()) + { + wxMemoryInputStream img_unique_pngIS(unique_png_data, sizeof(unique_png_data)); + img_unique_png->LoadFile(img_unique_pngIS, wxBITMAP_TYPE_PNG); + } + return img_unique_png; +} +#define unique_png_img unique_png_img() + +static wxBitmap *unique_png_bmp() +{ + static wxBitmap *bmp_unique_png; + if (!bmp_unique_png || !bmp_unique_png->IsOk()) + bmp_unique_png = new wxBitmap(*unique_png_img); + return bmp_unique_png; +} +#define unique_png_bmp unique_png_bmp() + +static wxIcon *unique_png_ico() +{ + static wxIcon *ico_unique_png; + if (!ico_unique_png || !ico_unique_png->IsOk()) + { + ico_unique_png = new wxIcon(); + ico_unique_png->CopyFromBitmap(*unique_png_bmp); + } + return ico_unique_png; +} +#define unique_png_ico unique_png_ico() + +#endif // UNIQUE_PNG_H diff --git a/include/images/up.png b/include/images/up.png new file mode 100644 index 0000000..9c0e0a7 Binary files /dev/null and b/include/images/up.png differ diff --git a/include/images/up.pngc b/include/images/up.pngc new file mode 100644 index 0000000..0cd6466 --- /dev/null +++ b/include/images/up.pngc @@ -0,0 +1,93 @@ +#ifndef UP_PNG_H +#define UP_PNG_H + +static const unsigned char up_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x08, +0x08, 0x03, 0x00, 0x00, 0x00, 0x15, 0xf8, 0x85, +0xfd, 0x00, 0x00, 0x00, 0x72, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x8b, 0xb1, 0x61, 0x5a, +0x9b, 0x13, 0xcc, 0xdf, 0xa3, 0xba, 0xd3, 0x81, +0xa5, 0xc5, 0x5a, 0xb6, 0xd1, 0x78, 0xba, 0xd3, +0x83, 0x9e, 0xc2, 0x4f, 0x96, 0xbc, 0x3d, 0x9b, +0xbf, 0x43, 0xb4, 0xcf, 0x70, 0xba, 0xd4, 0x83, +0x9f, 0xc2, 0x51, 0x96, 0xbd, 0x3e, 0x94, 0xbb, +0x38, 0x92, 0xb9, 0x31, 0x97, 0xbc, 0x38, 0xb1, +0xcd, 0x69, 0xba, 0xd4, 0x85, 0x9f, 0xc3, 0x53, +0x97, 0xbd, 0x40, 0x95, 0xbb, 0x39, 0x92, 0xba, +0x33, 0x90, 0xb8, 0x2c, 0x8e, 0xb7, 0x26, 0x94, +0xbb, 0x2f, 0xaf, 0xcc, 0x64, 0xce, 0xe0, 0xa7, +0xb2, 0xce, 0x71, 0xb0, 0xcd, 0x6c, 0xae, 0xcb, +0x67, 0xad, 0xcb, 0x62, 0xab, 0xc9, 0x5e, 0xaa, +0xc8, 0x5a, 0xa9, 0xc8, 0x56, 0xaf, 0xcc, 0x63, +0xc5, 0xda, 0x8d, 0xf4, 0x19, 0x1e, 0xf0, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x4a, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x45, 0xc9, 0x57, 0x0e, 0x80, +0x20, 0x00, 0x04, 0x51, 0x76, 0xc5, 0xde, 0x7b, +0xef, 0x7a, 0xff, 0x2b, 0x0a, 0x31, 0xca, 0xfc, +0xbd, 0x8c, 0x10, 0x3a, 0x10, 0xe2, 0x0f, 0xb4, +0x0c, 0x41, 0x69, 0x3b, 0x1f, 0x41, 0xd7, 0xf3, +0x83, 0xf0, 0x25, 0x18, 0xc5, 0x49, 0x9a, 0xe5, +0x85, 0x26, 0x58, 0x56, 0x75, 0xd3, 0x76, 0xfd, +0x30, 0x2a, 0x72, 0x92, 0xf3, 0xb2, 0x6e, 0xfb, +0x71, 0x5e, 0x37, 0xd5, 0x33, 0xe1, 0x01, 0x65, +0x4f, 0x02, 0xff, 0x59, 0xbc, 0x1a, 0xd1, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, +0x30, 0x31, 0x2d, 0x32, 0x35, 0x54, 0x31, 0x35, +0x3a, 0x30, 0x37, 0x3a, 0x33, 0x36, 0x2b, 0x30, +0x36, 0x3a, 0x30, 0x30, 0xbe, 0x1e, 0xd2, 0x9f, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x38, 0x54, 0x30, +0x31, 0x3a, 0x30, 0x33, 0x3a, 0x35, 0x39, 0x2b, +0x30, 0x36, 0x3a, 0x30, 0x30, 0x68, 0xc6, 0x93, +0x0c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *up_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_up_png = new wxImage(); + if (!img_up_png || !img_up_png->IsOk()) + { + wxMemoryInputStream img_up_pngIS(up_png_data, sizeof(up_png_data)); + img_up_png->LoadFile(img_up_pngIS, wxBITMAP_TYPE_PNG); + } + return img_up_png; +} +#define up_png_img up_png_img() + +static wxBitmap *up_png_bmp() +{ + static wxBitmap *bmp_up_png; + if (!bmp_up_png || !bmp_up_png->IsOk()) + bmp_up_png = new wxBitmap(*up_png_img); + return bmp_up_png; +} +#define up_png_bmp up_png_bmp() + +static wxIcon *up_png_ico() +{ + static wxIcon *ico_up_png; + if (!ico_up_png || !ico_up_png->IsOk()) + { + ico_up_png = new wxIcon(); + ico_up_png->CopyFromBitmap(*up_png_bmp); + } + return ico_up_png; +} +#define up_png_ico up_png_ico() + +#endif // UP_PNG_H diff --git a/include/images/user.png b/include/images/user.png new file mode 100644 index 0000000..ef54e88 Binary files /dev/null and b/include/images/user.png differ diff --git a/include/images/user.pngc b/include/images/user.pngc new file mode 100644 index 0000000..9a14786 --- /dev/null +++ b/include/images/user.pngc @@ -0,0 +1,114 @@ +#ifndef USER_PNG_H +#define USER_PNG_H + +static const unsigned char user_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0xcf, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x6a, +0x6a, 0x6a, 0xbd, 0xbd, 0xbd, 0x7e, 0x7a, 0x77, +0xb7, 0xae, 0xa7, 0xe4, 0xd8, 0xce, 0xe4, 0xd8, +0xd0, 0xb6, 0xae, 0xaa, 0x7e, 0x7a, 0x79, 0xd7, +0xcc, 0xc3, 0xf8, 0xea, 0xdf, 0xf8, 0xea, 0xe1, +0xf7, 0xea, 0xe2, 0xf7, 0xea, 0xe4, 0xd7, 0xcc, +0xc9, 0x7e, 0x7a, 0x7a, 0xf7, 0xea, 0xe6, 0xf7, +0xea, 0xe8, 0xb6, 0xae, 0xae, 0xf7, 0xea, 0xea, +0xe3, 0xd8, 0xda, 0xf7, 0xea, 0xec, 0xe3, 0xd8, +0xdb, 0xf7, 0xea, 0xee, 0xb6, 0xae, 0xb1, 0xd6, +0xcc, 0xd0, 0x7d, 0x7a, 0x7c, 0x5b, 0x5c, 0x5c, +0x5a, 0x5c, 0x5c, 0x6a, 0x6d, 0x6d, 0xa6, 0xb4, +0xb7, 0xb4, 0xc5, 0xc9, 0x87, 0x90, 0x93, 0x64, +0x67, 0x68, 0x63, 0x67, 0x68, 0x83, 0x8e, 0x93, +0xa8, 0xbf, 0xca, 0x99, 0xad, 0xb7, 0x65, 0x6b, +0x6d, 0x5a, 0x5a, 0x5a, 0xa3, 0xb0, 0xb3, 0xd4, +0xea, 0xf0, 0xd1, 0xe9, 0xf0, 0xce, 0xe7, 0xf0, +0xcb, 0xe6, 0xf1, 0xc7, 0xe4, 0xf1, 0xc4, 0xe3, +0xf1, 0xc1, 0xe1, 0xf1, 0xbd, 0xe0, 0xf1, 0x92, +0xa8, 0xb4, 0x58, 0x5a, 0x5b, 0x83, 0x8a, 0x8c, +0xba, 0xde, 0xf2, 0xb7, 0xdd, 0xf2, 0x77, 0x85, +0x8c, 0x94, 0x94, 0x94, 0xa5, 0xb3, 0xb7, 0xb4, +0xdc, 0xf2, 0x90, 0xaa, 0xb8, 0x6e, 0x6e, 0x6e, +0xbf, 0xd3, 0xd9, 0xb2, 0xdb, 0xf2, 0xa3, 0xc6, +0xdb, 0x58, 0x58, 0x58, 0xcc, 0xe5, 0xee, 0xb1, +0xda, 0xf2, 0xb0, 0xd8, 0xf0, 0x55, 0x55, 0x55, +0x05, 0xa5, 0xb0, 0x79, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x95, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x45, 0xcd, 0xe9, 0x12, 0xc1, 0x30, 0x14, 0x86, +0xe1, 0x24, 0xdd, 0x6d, 0x2d, 0x55, 0x55, 0x45, +0xed, 0xfb, 0xbe, 0x16, 0x45, 0x90, 0xfb, 0xbf, +0x26, 0x49, 0x4c, 0x8e, 0xef, 0xdf, 0xf3, 0xce, +0x9c, 0x39, 0x08, 0xc9, 0x61, 0x42, 0x30, 0xfa, +0x4f, 0xd3, 0x0d, 0xd3, 0xb2, 0x1d, 0x0d, 0x82, +0x9e, 0xcb, 0x17, 0x8a, 0x25, 0xd7, 0x53, 0xc6, +0x86, 0x70, 0xb9, 0xe2, 0xab, 0x2b, 0x62, 0x4a, +0x57, 0x03, 0xa2, 0x82, 0x25, 0x5d, 0x0b, 0x55, +0xc0, 0xb6, 0x74, 0x3d, 0x82, 0x47, 0x8e, 0x2b, +0xdc, 0x88, 0xe1, 0x4b, 0xd3, 0xf3, 0x83, 0x30, +0x8a, 0x5b, 0xca, 0xed, 0xa4, 0xd3, 0xed, 0xf5, +0x07, 0xc3, 0xd1, 0xf8, 0xe7, 0xc9, 0x74, 0x36, +0x5f, 0x2c, 0x57, 0xeb, 0xcd, 0x76, 0xb7, 0x97, +0xe1, 0xa0, 0x7c, 0x3c, 0x9d, 0x85, 0xd3, 0x0b, +0xf8, 0x7a, 0x4b, 0x79, 0xc8, 0xee, 0xe0, 0xc7, +0x33, 0xe3, 0x81, 0xbe, 0xc0, 0xef, 0x0f, 0xe5, +0x81, 0x51, 0x06, 0xa3, 0x0c, 0x7d, 0x01, 0x4f, +0x20, 0x16, 0x36, 0xab, 0xb5, 0xf2, 0xa8, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *user_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_user_png = new wxImage(); + if (!img_user_png || !img_user_png->IsOk()) + { + wxMemoryInputStream img_user_pngIS(user_png_data, sizeof(user_png_data)); + img_user_png->LoadFile(img_user_pngIS, wxBITMAP_TYPE_PNG); + } + return img_user_png; +} +#define user_png_img user_png_img() + +static wxBitmap *user_png_bmp() +{ + static wxBitmap *bmp_user_png; + if (!bmp_user_png || !bmp_user_png->IsOk()) + bmp_user_png = new wxBitmap(*user_png_img); + return bmp_user_png; +} +#define user_png_bmp user_png_bmp() + +static wxIcon *user_png_ico() +{ + static wxIcon *ico_user_png; + if (!ico_user_png || !ico_user_png->IsOk()) + { + ico_user_png = new wxIcon(); + ico_user_png->CopyFromBitmap(*user_png_bmp); + } + return ico_user_png; +} +#define user_png_ico user_png_ico() + +#endif // USER_PNG_H diff --git a/include/images/usermapping-sm.png b/include/images/usermapping-sm.png new file mode 100644 index 0000000..e768c9b Binary files /dev/null and b/include/images/usermapping-sm.png differ diff --git a/include/images/usermapping-sm.pngc b/include/images/usermapping-sm.pngc new file mode 100644 index 0000000..7d7bfff --- /dev/null +++ b/include/images/usermapping-sm.pngc @@ -0,0 +1,109 @@ +#ifndef USERMAPPING_SM_PNG_H +#define USERMAPPING_SM_PNG_H + +static const unsigned char usermapping_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcc, 0x50, 0x4c, 0x54, 0x45, 0xb6, 0xae, +0xb1, 0x99, 0x99, 0x99, 0x6a, 0x6a, 0x6a, 0xbd, +0xbd, 0xbd, 0x7e, 0x7a, 0x77, 0xb7, 0xae, 0xa7, +0xe4, 0xd8, 0xce, 0xe4, 0xd8, 0xd0, 0xb6, 0xae, +0xaa, 0x7e, 0x7a, 0x79, 0xd7, 0xcc, 0xc3, 0xf8, +0xea, 0xdf, 0xf8, 0xea, 0xe1, 0xf7, 0xea, 0xe2, +0xf7, 0xea, 0xe4, 0xd7, 0xcc, 0xc9, 0x7e, 0x7a, +0x7a, 0xf7, 0xea, 0xe6, 0xf7, 0xea, 0xe8, 0xb6, +0xae, 0xae, 0xf7, 0xea, 0xea, 0xe3, 0xd8, 0xda, +0xf7, 0xea, 0xec, 0xe3, 0xd8, 0xdb, 0xf7, 0xea, +0xee, 0xd6, 0xcc, 0xd0, 0x7d, 0x7a, 0x7c, 0x5b, +0x5c, 0x5c, 0x5a, 0x5c, 0x5c, 0x6a, 0x6d, 0x6d, +0xa6, 0xb4, 0xb7, 0xb4, 0xc5, 0xc9, 0x87, 0x90, +0x93, 0x64, 0x67, 0x68, 0x63, 0x67, 0x68, 0x83, +0x8e, 0x93, 0xa8, 0xbf, 0xca, 0x99, 0xad, 0xb7, +0x65, 0x6b, 0x6d, 0x5a, 0x5a, 0x5a, 0xa3, 0xb0, +0xb3, 0xd4, 0xea, 0xf0, 0xd1, 0xe9, 0xf0, 0xce, +0xe7, 0xf0, 0xcb, 0xe6, 0xf1, 0xc7, 0xe4, 0xf1, +0xc4, 0xe3, 0xf1, 0xc1, 0xe1, 0xf1, 0xbd, 0xe0, +0xf1, 0x92, 0xa8, 0xb4, 0x58, 0x5a, 0x5b, 0x83, +0x8a, 0x8c, 0xba, 0xde, 0xf2, 0xb7, 0xdd, 0xf2, +0x77, 0x85, 0x8c, 0x94, 0x94, 0x94, 0xa5, 0xb3, +0xb7, 0xb4, 0xdc, 0xf2, 0x90, 0xaa, 0xb8, 0x6e, +0x6e, 0x6e, 0xbf, 0xd3, 0xd9, 0xb2, 0xdb, 0xf2, +0xa3, 0xc6, 0xdb, 0x58, 0x58, 0x58, 0xcc, 0xe5, +0xee, 0xb1, 0xda, 0xf2, 0xb0, 0xd8, 0xf0, 0x55, +0x55, 0x55, 0x39, 0x8c, 0x3b, 0xab, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, +0x11, 0x11, 0x03, 0x0f, 0x0f, 0x7e, 0x57, 0x63, +0x00, 0x00, 0x00, 0xa6, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x45, 0xcd, 0xdb, 0x0e, 0xc2, 0x20, +0x0c, 0x80, 0x61, 0x60, 0x67, 0x4f, 0x9b, 0x53, +0xb1, 0x89, 0x51, 0x2f, 0x1d, 0xdb, 0xbc, 0x32, +0x8b, 0xa6, 0x1a, 0x46, 0xe0, 0xfd, 0xdf, 0xc9, +0xb2, 0xc8, 0xec, 0xdd, 0xff, 0x85, 0x16, 0xc6, +0xa6, 0xe1, 0x42, 0x70, 0xf6, 0x9f, 0x28, 0x4e, +0xd2, 0x2c, 0x2f, 0xa2, 0x19, 0xe2, 0xc5, 0x72, +0xb5, 0xde, 0x94, 0x55, 0x68, 0x9e, 0xf8, 0xde, +0xd6, 0xbb, 0xb0, 0x25, 0xd2, 0xa9, 0xf7, 0x07, +0x11, 0x20, 0x9b, 0x5a, 0x1e, 0x03, 0xf0, 0xdc, +0x37, 0xa2, 0xd5, 0xf8, 0x93, 0xa2, 0xac, 0x51, +0x03, 0x18, 0x00, 0x68, 0x26, 0x38, 0x55, 0xd4, +0x16, 0x91, 0x00, 0x7c, 0x9f, 0x2f, 0x57, 0xf4, +0x6d, 0xc1, 0x0e, 0x1e, 0x6e, 0x8d, 0x42, 0x4b, +0x3d, 0x00, 0x48, 0x30, 0x04, 0x0f, 0xd5, 0xa2, +0x92, 0x88, 0xda, 0x1a, 0x90, 0x04, 0xcf, 0x57, +0xdb, 0xa1, 0x02, 0x40, 0xf4, 0x87, 0x35, 0x63, +0xef, 0x4f, 0xd7, 0xd3, 0x73, 0xda, 0xa1, 0xab, +0x03, 0x7d, 0x3c, 0x9a, 0xfe, 0xde, 0xe8, 0xc1, +0x37, 0x92, 0x32, 0xe6, 0x46, 0xe7, 0x1c, 0xce, +0xf3, 0x05, 0x7d, 0x7a, 0x1a, 0xd2, 0x4e, 0x6c, +0x04, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *usermapping_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_usermapping_sm_png = new wxImage(); + if (!img_usermapping_sm_png || !img_usermapping_sm_png->IsOk()) + { + wxMemoryInputStream img_usermapping_sm_pngIS(usermapping_sm_png_data, sizeof(usermapping_sm_png_data)); + img_usermapping_sm_png->LoadFile(img_usermapping_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_usermapping_sm_png; +} +#define usermapping_sm_png_img usermapping_sm_png_img() + +static wxBitmap *usermapping_sm_png_bmp() +{ + static wxBitmap *bmp_usermapping_sm_png; + if (!bmp_usermapping_sm_png || !bmp_usermapping_sm_png->IsOk()) + bmp_usermapping_sm_png = new wxBitmap(*usermapping_sm_png_img); + return bmp_usermapping_sm_png; +} +#define usermapping_sm_png_bmp usermapping_sm_png_bmp() + +static wxIcon *usermapping_sm_png_ico() +{ + static wxIcon *ico_usermapping_sm_png; + if (!ico_usermapping_sm_png || !ico_usermapping_sm_png->IsOk()) + { + ico_usermapping_sm_png = new wxIcon(); + ico_usermapping_sm_png->CopyFromBitmap(*usermapping_sm_png_bmp); + } + return ico_usermapping_sm_png; +} +#define usermapping_sm_png_ico usermapping_sm_png_ico() + +#endif // USERMAPPING_SM_PNG_H diff --git a/include/images/usermapping.png b/include/images/usermapping.png new file mode 100644 index 0000000..e768c9b Binary files /dev/null and b/include/images/usermapping.png differ diff --git a/include/images/usermapping.pngc b/include/images/usermapping.pngc new file mode 100644 index 0000000..24375e0 --- /dev/null +++ b/include/images/usermapping.pngc @@ -0,0 +1,109 @@ +#ifndef USERMAPPING_PNG_H +#define USERMAPPING_PNG_H + +static const unsigned char usermapping_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xcc, 0x50, 0x4c, 0x54, 0x45, 0xb6, 0xae, +0xb1, 0x99, 0x99, 0x99, 0x6a, 0x6a, 0x6a, 0xbd, +0xbd, 0xbd, 0x7e, 0x7a, 0x77, 0xb7, 0xae, 0xa7, +0xe4, 0xd8, 0xce, 0xe4, 0xd8, 0xd0, 0xb6, 0xae, +0xaa, 0x7e, 0x7a, 0x79, 0xd7, 0xcc, 0xc3, 0xf8, +0xea, 0xdf, 0xf8, 0xea, 0xe1, 0xf7, 0xea, 0xe2, +0xf7, 0xea, 0xe4, 0xd7, 0xcc, 0xc9, 0x7e, 0x7a, +0x7a, 0xf7, 0xea, 0xe6, 0xf7, 0xea, 0xe8, 0xb6, +0xae, 0xae, 0xf7, 0xea, 0xea, 0xe3, 0xd8, 0xda, +0xf7, 0xea, 0xec, 0xe3, 0xd8, 0xdb, 0xf7, 0xea, +0xee, 0xd6, 0xcc, 0xd0, 0x7d, 0x7a, 0x7c, 0x5b, +0x5c, 0x5c, 0x5a, 0x5c, 0x5c, 0x6a, 0x6d, 0x6d, +0xa6, 0xb4, 0xb7, 0xb4, 0xc5, 0xc9, 0x87, 0x90, +0x93, 0x64, 0x67, 0x68, 0x63, 0x67, 0x68, 0x83, +0x8e, 0x93, 0xa8, 0xbf, 0xca, 0x99, 0xad, 0xb7, +0x65, 0x6b, 0x6d, 0x5a, 0x5a, 0x5a, 0xa3, 0xb0, +0xb3, 0xd4, 0xea, 0xf0, 0xd1, 0xe9, 0xf0, 0xce, +0xe7, 0xf0, 0xcb, 0xe6, 0xf1, 0xc7, 0xe4, 0xf1, +0xc4, 0xe3, 0xf1, 0xc1, 0xe1, 0xf1, 0xbd, 0xe0, +0xf1, 0x92, 0xa8, 0xb4, 0x58, 0x5a, 0x5b, 0x83, +0x8a, 0x8c, 0xba, 0xde, 0xf2, 0xb7, 0xdd, 0xf2, +0x77, 0x85, 0x8c, 0x94, 0x94, 0x94, 0xa5, 0xb3, +0xb7, 0xb4, 0xdc, 0xf2, 0x90, 0xaa, 0xb8, 0x6e, +0x6e, 0x6e, 0xbf, 0xd3, 0xd9, 0xb2, 0xdb, 0xf2, +0xa3, 0xc6, 0xdb, 0x58, 0x58, 0x58, 0xcc, 0xe5, +0xee, 0xb1, 0xda, 0xf2, 0xb0, 0xd8, 0xf0, 0x55, +0x55, 0x55, 0x39, 0x8c, 0x3b, 0xab, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, +0x11, 0x11, 0x03, 0x0f, 0x0f, 0x7e, 0x57, 0x63, +0x00, 0x00, 0x00, 0xa6, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x45, 0xcd, 0xdb, 0x0e, 0xc2, 0x20, +0x0c, 0x80, 0x61, 0x60, 0x67, 0x4f, 0x9b, 0x53, +0xb1, 0x89, 0x51, 0x2f, 0x1d, 0xdb, 0xbc, 0x32, +0x8b, 0xa6, 0x1a, 0x46, 0xe0, 0xfd, 0xdf, 0xc9, +0xb2, 0xc8, 0xec, 0xdd, 0xff, 0x85, 0x16, 0xc6, +0xa6, 0xe1, 0x42, 0x70, 0xf6, 0x9f, 0x28, 0x4e, +0xd2, 0x2c, 0x2f, 0xa2, 0x19, 0xe2, 0xc5, 0x72, +0xb5, 0xde, 0x94, 0x55, 0x68, 0x9e, 0xf8, 0xde, +0xd6, 0xbb, 0xb0, 0x25, 0xd2, 0xa9, 0xf7, 0x07, +0x11, 0x20, 0x9b, 0x5a, 0x1e, 0x03, 0xf0, 0xdc, +0x37, 0xa2, 0xd5, 0xf8, 0x93, 0xa2, 0xac, 0x51, +0x03, 0x18, 0x00, 0x68, 0x26, 0x38, 0x55, 0xd4, +0x16, 0x91, 0x00, 0x7c, 0x9f, 0x2f, 0x57, 0xf4, +0x6d, 0xc1, 0x0e, 0x1e, 0x6e, 0x8d, 0x42, 0x4b, +0x3d, 0x00, 0x48, 0x30, 0x04, 0x0f, 0xd5, 0xa2, +0x92, 0x88, 0xda, 0x1a, 0x90, 0x04, 0xcf, 0x57, +0xdb, 0xa1, 0x02, 0x40, 0xf4, 0x87, 0x35, 0x63, +0xef, 0x4f, 0xd7, 0xd3, 0x73, 0xda, 0xa1, 0xab, +0x03, 0x7d, 0x3c, 0x9a, 0xfe, 0xde, 0xe8, 0xc1, +0x37, 0x92, 0x32, 0xe6, 0x46, 0xe7, 0x1c, 0xce, +0xf3, 0x05, 0x7d, 0x7a, 0x1a, 0xd2, 0x4e, 0x6c, +0x04, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *usermapping_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_usermapping_png = new wxImage(); + if (!img_usermapping_png || !img_usermapping_png->IsOk()) + { + wxMemoryInputStream img_usermapping_pngIS(usermapping_png_data, sizeof(usermapping_png_data)); + img_usermapping_png->LoadFile(img_usermapping_pngIS, wxBITMAP_TYPE_PNG); + } + return img_usermapping_png; +} +#define usermapping_png_img usermapping_png_img() + +static wxBitmap *usermapping_png_bmp() +{ + static wxBitmap *bmp_usermapping_png; + if (!bmp_usermapping_png || !bmp_usermapping_png->IsOk()) + bmp_usermapping_png = new wxBitmap(*usermapping_png_img); + return bmp_usermapping_png; +} +#define usermapping_png_bmp usermapping_png_bmp() + +static wxIcon *usermapping_png_ico() +{ + static wxIcon *ico_usermapping_png; + if (!ico_usermapping_png || !ico_usermapping_png->IsOk()) + { + ico_usermapping_png = new wxIcon(); + ico_usermapping_png->CopyFromBitmap(*usermapping_png_bmp); + } + return ico_usermapping_png; +} +#define usermapping_png_ico usermapping_png_ico() + +#endif // USERMAPPING_PNG_H diff --git a/include/images/usermappings.png b/include/images/usermappings.png new file mode 100644 index 0000000..0e68c2b Binary files /dev/null and b/include/images/usermappings.png differ diff --git a/include/images/usermappings.pngc b/include/images/usermappings.pngc new file mode 100644 index 0000000..a08facb --- /dev/null +++ b/include/images/usermappings.pngc @@ -0,0 +1,114 @@ +#ifndef USERMAPPINGS_PNG_H +#define USERMAPPINGS_PNG_H + +static const unsigned char usermappings_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, +0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, +0x00, 0xe4, 0x50, 0x4c, 0x54, 0x45, 0xd3, 0x90, +0x95, 0x84, 0x84, 0x84, 0x5c, 0x5c, 0x5c, 0xbf, +0xbf, 0xbf, 0xa0, 0xa0, 0xa0, 0x86, 0x82, 0x7e, +0xcb, 0xc1, 0xb8, 0xf2, 0xe4, 0xdb, 0xcb, 0xc1, +0xbb, 0x92, 0x8d, 0x8b, 0x7a, 0x77, 0x74, 0xf4, +0xe6, 0xda, 0xf8, 0xea, 0xe0, 0xf8, 0xea, 0xe2, +0xf7, 0xea, 0xe4, 0xf3, 0xe6, 0xe2, 0x92, 0x8d, +0x8c, 0x93, 0x93, 0x93, 0xbd, 0xb4, 0xac, 0xf7, +0xea, 0xe6, 0xf7, 0xea, 0xe8, 0xca, 0xc1, 0xc1, +0x70, 0x70, 0x70, 0xde, 0xd3, 0xca, 0xf7, 0xea, +0xea, 0xf1, 0xe4, 0xe6, 0xb6, 0xb6, 0xb6, 0x9b, +0x95, 0x92, 0x98, 0x92, 0x92, 0x55, 0x55, 0x55, +0x9b, 0x9b, 0x9b, 0x64, 0x63, 0x62, 0xd3, 0xc9, +0xc6, 0xff, 0xff, 0xff, 0xfc, 0xfe, 0xfe, 0xf8, +0xfc, 0xfe, 0xf3, 0xfa, 0xfd, 0xed, 0xf8, 0xfc, +0xe7, 0xf5, 0xfa, 0xe1, 0xf3, 0xf9, 0xda, 0xf0, +0xf8, 0x56, 0x56, 0x56, 0x64, 0x63, 0x63, 0x9b, +0x95, 0x95, 0xdb, 0x93, 0x96, 0xc8, 0x00, 0x00, +0xd3, 0xed, 0xf6, 0x5c, 0x5d, 0x5e, 0x9a, 0xa5, +0xa8, 0xc7, 0xdc, 0xe1, 0x9b, 0xa9, 0xad, 0xcd, +0xeb, 0xf5, 0x97, 0xa2, 0xa5, 0xd3, 0xea, 0xf0, +0xd0, 0xe8, 0xf0, 0xcc, 0xe6, 0xf1, 0xd4, 0x5e, +0x60, 0xcf, 0x5c, 0x5f, 0xc6, 0xe8, 0xf4, 0xde, +0xde, 0xde, 0x6e, 0x72, 0x73, 0xc8, 0xe5, 0xf1, +0xd4, 0x99, 0x9f, 0xc0, 0xe5, 0xf3, 0xa8, 0xa8, +0xa8, 0x96, 0xa2, 0xa5, 0xc4, 0xe3, 0xf1, 0x1e, +0x50, 0xad, 0xba, 0xe3, 0xf1, 0x72, 0x72, 0x72, +0xbb, 0xcf, 0xd6, 0xc0, 0xe1, 0xf1, 0xb4, 0xe1, +0xf0, 0xb8, 0xb8, 0xb8, 0xaf, 0xdf, 0xef, 0xab, +0xdd, 0xef, 0xa1, 0x78, 0x54, 0x14, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x00, 0x88, 0x05, 0x1d, 0x48, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, +0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, +0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xdb, 0x04, +0x11, 0x11, 0x05, 0x22, 0x1c, 0xfb, 0xac, 0x90, +0x00, 0x00, 0x00, 0xb5, 0x49, 0x44, 0x41, 0x54, +0x18, 0xd3, 0x45, 0x8e, 0xd7, 0x0e, 0xc2, 0x30, +0x0c, 0x00, 0x53, 0xf6, 0xde, 0xa3, 0x0c, 0xb3, +0xdc, 0x94, 0xbd, 0x22, 0x28, 0x48, 0x05, 0x09, +0xb0, 0x98, 0xf9, 0xff, 0xff, 0xc1, 0x41, 0x05, +0xee, 0xed, 0x4e, 0xb6, 0x13, 0x21, 0x0c, 0x56, +0xc8, 0x0a, 0x8b, 0x3f, 0x91, 0x68, 0x2c, 0x9e, +0x48, 0x46, 0xfe, 0x21, 0x95, 0xce, 0x64, 0x73, +0xf9, 0xc2, 0xcf, 0x8b, 0x25, 0xf6, 0x72, 0xa5, +0x6a, 0x7d, 0x43, 0xad, 0x6e, 0xdc, 0x6e, 0x84, +0xbe, 0xa1, 0xd9, 0xca, 0x95, 0xdb, 0x10, 0xd0, +0x31, 0xa5, 0xdb, 0xab, 0x40, 0x7f, 0x80, 0x8e, +0x74, 0x87, 0x23, 0x30, 0x61, 0x3c, 0x99, 0x82, +0xf1, 0xd9, 0x5c, 0x69, 0xcd, 0xbe, 0x5c, 0xad, +0x15, 0xa0, 0x33, 0x9f, 0x69, 0xb4, 0x3d, 0xe4, +0xb0, 0xd9, 0x7a, 0x3b, 0x70, 0xe4, 0x5e, 0xa3, +0x26, 0x42, 0xe1, 0x1f, 0xd8, 0x8f, 0x20, 0x5d, +0x65, 0x5c, 0x4b, 0x71, 0x3a, 0xb3, 0x5f, 0xc0, +0x25, 0xfd, 0x22, 0x7a, 0xa0, 0x14, 0xd7, 0x1b, +0xfb, 0x1d, 0x86, 0xe4, 0xdb, 0x8a, 0xa3, 0x27, +0x9e, 0xd7, 0xcf, 0xfb, 0x23, 0xf2, 0x11, 0x15, +0xef, 0x04, 0x9f, 0x83, 0x05, 0x8f, 0xf3, 0x0d, +0x52, 0x41, 0xe8, 0xc0, 0x49, 0x3f, 0xc8, 0xf0, +0x06, 0x0e, 0x01, 0x1e, 0x9c, 0x6d, 0x34, 0x77, +0x91, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *usermappings_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_usermappings_png = new wxImage(); + if (!img_usermappings_png || !img_usermappings_png->IsOk()) + { + wxMemoryInputStream img_usermappings_pngIS(usermappings_png_data, sizeof(usermappings_png_data)); + img_usermappings_png->LoadFile(img_usermappings_pngIS, wxBITMAP_TYPE_PNG); + } + return img_usermappings_png; +} +#define usermappings_png_img usermappings_png_img() + +static wxBitmap *usermappings_png_bmp() +{ + static wxBitmap *bmp_usermappings_png; + if (!bmp_usermappings_png || !bmp_usermappings_png->IsOk()) + bmp_usermappings_png = new wxBitmap(*usermappings_png_img); + return bmp_usermappings_png; +} +#define usermappings_png_bmp usermappings_png_bmp() + +static wxIcon *usermappings_png_ico() +{ + static wxIcon *ico_usermappings_png; + if (!ico_usermappings_png || !ico_usermappings_png->IsOk()) + { + ico_usermappings_png = new wxIcon(); + ico_usermappings_png->CopyFromBitmap(*usermappings_png_bmp); + } + return ico_usermappings_png; +} +#define usermappings_png_ico usermappings_png_ico() + +#endif // USERMAPPINGS_PNG_H diff --git a/include/images/users.png b/include/images/users.png new file mode 100644 index 0000000..f5c20bf Binary files /dev/null and b/include/images/users.png differ diff --git a/include/images/users.pngc b/include/images/users.pngc new file mode 100644 index 0000000..461134e --- /dev/null +++ b/include/images/users.pngc @@ -0,0 +1,103 @@ +#ifndef USERS_PNG_H +#define USERS_PNG_H + +static const unsigned char users_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x87, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xc5, 0xc5, 0xc5, 0x7f, +0x7f, 0x7f, 0x8b, 0x87, 0x82, 0xd0, 0xc5, 0xbc, +0xd0, 0xc5, 0xbe, 0x8b, 0x87, 0x85, 0xf8, 0xea, +0xe1, 0xf7, 0xea, 0xe4, 0xcf, 0xc5, 0xc4, 0xf7, +0xea, 0xe8, 0xcf, 0xc5, 0xc7, 0xbf, 0xbf, 0xbf, +0x8b, 0x87, 0x88, 0x5b, 0x5c, 0x5c, 0x7d, 0x83, +0x84, 0x6f, 0x73, 0x74, 0x6e, 0x73, 0x74, 0x79, +0x81, 0x84, 0x5a, 0x5c, 0x5c, 0xb7, 0xb7, 0xb7, +0x8c, 0x95, 0x97, 0xd4, 0xea, 0xf0, 0xd0, 0xe8, +0xf0, 0xca, 0xe6, 0xf1, 0xc4, 0xe3, 0xf1, 0x72, +0x7c, 0x80, 0x6d, 0x6d, 0x6d, 0x9b, 0x9b, 0x9b, +0x80, 0x80, 0x80, 0xb4, 0xc4, 0xc8, 0x9a, 0xb1, +0xbc, 0x5b, 0x5b, 0x5b, 0xcc, 0xe3, 0xeb, 0xbe, +0xe0, 0xf1, 0x6d, 0x77, 0x7c, 0x74, 0x7a, 0x7b, +0x81, 0x90, 0x97, 0xa1, 0xa1, 0xa1, 0x55, 0x55, +0x55, 0x73, 0x79, 0x7b, 0x9f, 0xbb, 0xca, 0x9e, +0xb0, 0xb7, 0xb8, 0xde, 0xf2, 0xb1, 0xd7, 0xec, +0x6d, 0x89, 0xdf, 0x84, 0x00, 0x00, 0x00, 0x01, +0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, +0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, +0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, +0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, +0x00, 0x88, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, +0x4d, 0x8e, 0xd9, 0x16, 0x82, 0x30, 0x0c, 0x05, +0xd3, 0xc8, 0x0e, 0x0a, 0xca, 0x22, 0x55, 0x91, +0x02, 0x8a, 0xb8, 0xfc, 0xff, 0xf7, 0x91, 0x36, +0x08, 0xbd, 0x6f, 0x49, 0x66, 0xce, 0x0d, 0x00, +0x08, 0x44, 0x01, 0x56, 0xc4, 0xce, 0x71, 0x3d, +0x7b, 0x83, 0x8e, 0x1f, 0x84, 0x08, 0x1b, 0x89, +0x6e, 0x10, 0xc5, 0x68, 0x91, 0x89, 0x17, 0xc6, +0xfb, 0xc4, 0x22, 0x0f, 0x69, 0x76, 0x3c, 0xe5, +0x1b, 0x59, 0x94, 0xd5, 0xb9, 0x96, 0x97, 0x2b, +0xde, 0x16, 0xb2, 0xb9, 0xd3, 0xdc, 0x6a, 0x3f, +0x63, 0x52, 0x75, 0xb5, 0xec, 0x07, 0xed, 0x3f, +0xe8, 0xf2, 0x2c, 0x60, 0x54, 0x2f, 0x8a, 0xf6, +0x27, 0xba, 0xbc, 0x1b, 0xfe, 0xc5, 0x34, 0x7d, +0x64, 0xff, 0xfd, 0x29, 0x5e, 0x70, 0x13, 0x91, +0x6a, 0x34, 0x33, 0x37, 0x91, 0xff, 0x8f, 0x69, +0x5a, 0x7d, 0x58, 0x9a, 0x56, 0x9f, 0xc2, 0x4d, +0xec, 0xcf, 0x01, 0xba, 0x0c, 0xc2, 0xaa, 0xff, +0xb6, 0x16, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, +0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, +0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, +0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, +0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, +0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *users_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_users_png = new wxImage(); + if (!img_users_png || !img_users_png->IsOk()) + { + wxMemoryInputStream img_users_pngIS(users_png_data, sizeof(users_png_data)); + img_users_png->LoadFile(img_users_pngIS, wxBITMAP_TYPE_PNG); + } + return img_users_png; +} +#define users_png_img users_png_img() + +static wxBitmap *users_png_bmp() +{ + static wxBitmap *bmp_users_png; + if (!bmp_users_png || !bmp_users_png->IsOk()) + bmp_users_png = new wxBitmap(*users_png_img); + return bmp_users_png; +} +#define users_png_bmp users_png_bmp() + +static wxIcon *users_png_ico() +{ + static wxIcon *ico_users_png; + if (!ico_users_png || !ico_users_png->IsOk()) + { + ico_users_png = new wxIcon(); + ico_users_png->CopyFromBitmap(*users_png_bmp); + } + return ico_users_png; +} +#define users_png_ico users_png_ico() + +#endif // USERS_PNG_H diff --git a/include/images/vacuum.png b/include/images/vacuum.png new file mode 100644 index 0000000..8ace91e Binary files /dev/null and b/include/images/vacuum.png differ diff --git a/include/images/vacuum.pngc b/include/images/vacuum.pngc new file mode 100644 index 0000000..282512b --- /dev/null +++ b/include/images/vacuum.pngc @@ -0,0 +1,166 @@ +#ifndef VACUUM_PNG_H +#define VACUUM_PNG_H + +static const unsigned char vacuum_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x71, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x9a, 0x99, 0x95, 0x68, +0x68, 0x67, 0x5c, 0x5c, 0x5c, 0x86, 0x86, 0x83, +0xb8, 0xb7, 0xb0, 0xd3, 0xd2, 0xc9, 0x8f, 0x8e, +0x8b, 0x5d, 0x5d, 0x5d, 0xe7, 0xe7, 0xe7, 0xeb, +0xeb, 0xeb, 0xf1, 0xf1, 0xf1, 0xfb, 0xfb, 0xfb, +0xff, 0xff, 0xff, 0xc6, 0xc6, 0xc6, 0x60, 0x60, +0x60, 0xd2, 0xd1, 0xc8, 0xa2, 0xa2, 0xa2, 0xea, +0xea, 0xea, 0xdb, 0xdb, 0xdb, 0xe3, 0xe3, 0xe3, +0xf4, 0xf4, 0xf4, 0xfe, 0xfe, 0xfe, 0xc9, 0xc9, +0xc9, 0x5f, 0x5f, 0x5f, 0xd7, 0xd7, 0xd7, 0xe1, +0xe1, 0xe1, 0x64, 0x64, 0x64, 0xb6, 0xb5, 0xaf, +0xc6, 0xc5, 0xbe, 0xe0, 0xe0, 0xe0, 0xc8, 0xc8, +0xc8, 0x62, 0x62, 0x62, 0x70, 0x70, 0x70, 0xde, +0xde, 0xde, 0xef, 0xef, 0xef, 0xfd, 0xfd, 0xfd, +0x6c, 0x6c, 0x6c, 0xb7, 0xb6, 0xaf, 0x63, 0x63, +0x63, 0xc7, 0xc7, 0xc7, 0x86, 0x85, 0x82, 0xee, +0xee, 0xee, 0xed, 0xed, 0xed, 0xfc, 0xfc, 0xfc, +0x65, 0x65, 0x65, 0xc1, 0xc1, 0xc1, 0xf5, 0xf5, +0xf5, 0xfa, 0xfa, 0xfa, 0xf6, 0xf6, 0xf6, 0xba, +0xba, 0xb3, 0xc5, 0xc5, 0xc5, 0xdc, 0xdc, 0xdc, +0xbd, 0xbd, 0xbd, 0x71, 0x71, 0x71, 0x6f, 0x6f, +0x6f, 0xb5, 0xb5, 0xb5, 0x91, 0x91, 0x8d, 0x75, +0x75, 0x75, 0xf2, 0xf2, 0xf2, 0xe5, 0xe5, 0xe5, +0xda, 0xda, 0xda, 0xd5, 0xd5, 0xd5, 0xd6, 0xd6, +0xd6, 0xcd, 0xcd, 0xcd, 0x7e, 0x7e, 0x7e, 0xba, +0xba, 0xba, 0x90, 0x8f, 0x8b, 0x5e, 0x5e, 0x5e, +0xf3, 0xf3, 0xf3, 0xd9, 0xd9, 0xd9, 0xcb, 0xcb, +0xcb, 0xb4, 0xb4, 0xb4, 0xae, 0xae, 0xae, 0xb1, +0xb1, 0xb1, 0xb7, 0xb7, 0xb7, 0xca, 0xca, 0xca, +0x6b, 0x6b, 0x6b, 0xe9, 0xe9, 0xe9, 0xbf, 0xbf, +0xbf, 0xaf, 0xaf, 0xaf, 0xb0, 0xb0, 0xb0, 0xc4, +0xc4, 0xc4, 0xe4, 0xe4, 0xe4, 0x90, 0x90, 0x8c, +0xdd, 0xdd, 0xdd, 0xce, 0xce, 0xce, 0xb6, 0xb6, +0xb6, 0x8f, 0x8f, 0x8b, 0x7f, 0x7f, 0x7f, 0xcf, +0xcf, 0xcf, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, +0xdf, 0xdf, 0xdf, 0xf7, 0xf7, 0xf7, 0xd1, 0xd1, +0xd1, 0xf8, 0xf8, 0xf8, 0xd2, 0xd2, 0xd2, 0xf9, +0xf9, 0xf9, 0xe2, 0xe2, 0xe2, 0xd4, 0xd4, 0xd4, +0x95, 0x94, 0x90, 0xcf, 0xce, 0xc5, 0x8e, 0x8e, +0x8a, 0xf0, 0xf0, 0xf0, 0x67, 0x67, 0x66, 0x9a, +0x9a, 0x95, 0x91, 0x90, 0x8c, 0xa7, 0xa7, 0xa7, +0xe6, 0xe6, 0xe6, 0x99, 0x99, 0x94, 0xa7, 0xa7, +0xa1, 0x99, 0x99, 0x99, 0x84, 0x84, 0x84, 0x97, +0x97, 0x92, 0x7e, 0x7d, 0x7b, 0xd0, 0xd0, 0xd0, +0x9d, 0x9d, 0x98, 0x61, 0x61, 0x60, 0x68, 0x68, +0x68, 0xe8, 0xe8, 0xe8, 0xa0, 0xa0, 0xa0, 0xd4, +0xd3, 0xca, 0x65, 0xba, 0xd3, 0x02, 0x00, 0x00, +0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, +0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, +0x4b, 0x47, 0x44, 0x0d, 0xf6, 0xb4, 0x61, 0xf5, +0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, +0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, +0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x01, +0x82, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xc5, +0x91, 0xe9, 0x5b, 0x01, 0x51, 0x14, 0x87, 0xc7, +0x4c, 0x18, 0xcc, 0xd8, 0x8d, 0x30, 0x35, 0xa5, +0xa9, 0xc4, 0xd8, 0x42, 0x91, 0x65, 0xa8, 0x84, +0xd0, 0x62, 0x8b, 0x24, 0x52, 0x5a, 0x48, 0x4c, +0x4a, 0xcb, 0x5f, 0xdf, 0xcc, 0xd3, 0x27, 0x5c, +0x9f, 0xfd, 0x3e, 0xdd, 0xfb, 0xbc, 0xef, 0x3d, +0xe7, 0x3c, 0xf7, 0x40, 0xd0, 0x02, 0x22, 0x82, +0x11, 0x3e, 0x4b, 0xe2, 0x39, 0x58, 0x22, 0x45, +0x65, 0x72, 0x05, 0x86, 0x2b, 0x55, 0x6a, 0xb0, +0x20, 0xd5, 0x68, 0x75, 0x7a, 0x03, 0x61, 0x5c, +0x9e, 0x53, 0x41, 0x84, 0x6a, 0x4d, 0x66, 0x9e, +0x5b, 0x48, 0xfe, 0xb2, 0x02, 0x10, 0x60, 0x99, +0x6e, 0x55, 0x41, 0x50, 0x6b, 0x02, 0x17, 0xaf, +0x03, 0xaa, 0x20, 0x5a, 0xeb, 0x06, 0x4d, 0x6c, +0x6e, 0xf1, 0x47, 0x72, 0xdb, 0xb6, 0x03, 0x10, +0xec, 0x0e, 0x06, 0x67, 0x84, 0x01, 0x49, 0xa7, +0xcb, 0x8e, 0x00, 0x04, 0x37, 0x86, 0x7b, 0xbc, +0xc8, 0xae, 0x9a, 0xb4, 0xb8, 0x7c, 0x7e, 0x90, +0xc0, 0xe0, 0x98, 0x42, 0x1e, 0xd8, 0x53, 0xed, +0x07, 0x7c, 0x41, 0x80, 0x10, 0x3a, 0xc0, 0xb1, +0x70, 0x24, 0x1a, 0x63, 0xd9, 0x78, 0x22, 0x78, +0x68, 0x9e, 0x11, 0x8e, 0x8e, 0x31, 0x2c, 0x29, +0x3b, 0x49, 0x25, 0xd2, 0x99, 0xcc, 0x69, 0x36, +0x17, 0x81, 0xa7, 0x79, 0x9e, 0x61, 0x0c, 0x67, +0xba, 0xf8, 0x79, 0xfa, 0x22, 0x73, 0x99, 0x2d, +0x14, 0x51, 0xd1, 0x24, 0x2f, 0xe5, 0x19, 0xda, +0xad, 0x2d, 0x57, 0x5c, 0x57, 0x02, 0xa7, 0x8a, +0x1a, 0xe9, 0x24, 0xaf, 0xd6, 0x18, 0xda, 0x2b, +0xb7, 0x5e, 0xd7, 0x6f, 0x2a, 0xac, 0x29, 0xda, +0x28, 0xa2, 0x52, 0xc9, 0xe4, 0x7c, 0x35, 0x9a, +0xb8, 0x75, 0x34, 0x9a, 0xf5, 0x3a, 0x2b, 0x6c, +0x13, 0x81, 0xa7, 0xea, 0x57, 0x51, 0x0f, 0xd1, +0x72, 0x98, 0xef, 0x7c, 0x85, 0x68, 0x7e, 0x0a, +0xfd, 0xf7, 0x47, 0x19, 0xa2, 0x6d, 0xbf, 0x7f, +0xb0, 0x29, 0x4d, 0xf9, 0xce, 0x2c, 0x7e, 0x7c, +0x42, 0xf8, 0x0f, 0x7c, 0xd6, 0xc7, 0x28, 0x65, +0xf4, 0xa5, 0x0b, 0x78, 0xdf, 0x7b, 0xe5, 0x17, +0x90, 0xec, 0xb3, 0x46, 0xca, 0xef, 0x7c, 0x03, +0xf0, 0xc1, 0xb0, 0x65, 0xe4, 0xb8, 0x7a, 0x23, +0x47, 0xb1, 0xce, 0x77, 0x00, 0x87, 0x46, 0x1f, +0x38, 0x47, 0x92, 0x5c, 0x99, 0x2a, 0x5b, 0x3e, +0x41, 0x1c, 0x1a, 0xb7, 0x69, 0x41, 0xb0, 0x9a, +0x2c, 0x1d, 0x20, 0x87, 0x46, 0xcd, 0x56, 0x81, +0xe3, 0x12, 0xfd, 0xaf, 0x2e, 0x98, 0xf3, 0x33, +0x84, 0xbf, 0xf5, 0x0d, 0xfd, 0x4f, 0x09, 0x9a, +0x97, 0xd0, 0x30, 0x55, 0xa4, 0x86, 0xbd, 0xdf, +0xb9, 0x02, 0x34, 0x18, 0x8d, 0x47, 0x03, 0x68, +0x51, 0xf9, 0x03, 0xb1, 0xb0, 0x42, 0x04, 0x07, +0x11, 0x4b, 0x89, 0x00, 0x00, 0x00, 0x25, 0x74, +0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, +0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, +0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, +0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, +0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, +0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, +0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, 0x00, +0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, +0x82, +}; + +#include "wx/mstream.h" + +static wxImage *vacuum_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_vacuum_png = new wxImage(); + if (!img_vacuum_png || !img_vacuum_png->IsOk()) + { + wxMemoryInputStream img_vacuum_pngIS(vacuum_png_data, sizeof(vacuum_png_data)); + img_vacuum_png->LoadFile(img_vacuum_pngIS, wxBITMAP_TYPE_PNG); + } + return img_vacuum_png; +} +#define vacuum_png_img vacuum_png_img() + +static wxBitmap *vacuum_png_bmp() +{ + static wxBitmap *bmp_vacuum_png; + if (!bmp_vacuum_png || !bmp_vacuum_png->IsOk()) + bmp_vacuum_png = new wxBitmap(*vacuum_png_img); + return bmp_vacuum_png; +} +#define vacuum_png_bmp vacuum_png_bmp() + +static wxIcon *vacuum_png_ico() +{ + static wxIcon *ico_vacuum_png; + if (!ico_vacuum_png || !ico_vacuum_png->IsOk()) + { + ico_vacuum_png = new wxIcon(); + ico_vacuum_png->CopyFromBitmap(*vacuum_png_bmp); + } + return ico_vacuum_png; +} +#define vacuum_png_ico vacuum_png_ico() + +#endif // VACUUM_PNG_H diff --git a/include/images/variable.png b/include/images/variable.png new file mode 100644 index 0000000..046a088 Binary files /dev/null and b/include/images/variable.png differ diff --git a/include/images/variable.pngc b/include/images/variable.pngc new file mode 100644 index 0000000..925821d --- /dev/null +++ b/include/images/variable.pngc @@ -0,0 +1,83 @@ +#ifndef VARIABLE_PNG_H +#define VARIABLE_PNG_H + +static const unsigned char variable_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x18, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xf7, 0xc8, 0x86, 0xef, +0xa5, 0x39, 0xf7, 0xd6, 0xa4, 0xff, 0xef, 0xd6, +0xfb, 0xde, 0xb5, 0xff, 0xe2, 0xc5, 0xef, 0xb1, +0x56, 0xc1, 0xc8, 0x5f, 0xf3, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, +0x59, 0x73, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, +0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, 0x3e, 0x00, +0x00, 0x00, 0x56, 0x49, 0x44, 0x41, 0x54, 0x08, +0xd7, 0x63, 0x60, 0xc0, 0x04, 0x42, 0x4a, 0x40, +0xa0, 0x08, 0x64, 0x28, 0x0a, 0xbb, 0xb8, 0x18, +0x1a, 0x01, 0x19, 0xca, 0x4a, 0x26, 0x8e, 0x4a, +0x41, 0x40, 0x86, 0x9a, 0x90, 0x9a, 0x91, 0x62, +0x12, 0x88, 0x91, 0xa8, 0x5e, 0x24, 0x06, 0x62, +0xa8, 0x06, 0x17, 0xa9, 0x87, 0x82, 0xa4, 0x94, +0x8d, 0x8b, 0xd4, 0x8d, 0xc1, 0x8a, 0x0d, 0xd5, +0x8b, 0x84, 0x41, 0x0c, 0x45, 0x21, 0x10, 0x04, +0x31, 0x94, 0x04, 0x05, 0x95, 0xc0, 0x0c, 0x41, +0x20, 0x10, 0x82, 0x59, 0xa1, 0x80, 0xc5, 0x6e, +0x00, 0xb5, 0x30, 0x0c, 0x55, 0xe5, 0x87, 0xe5, +0xae, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, +0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, +0x2e, 0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, +0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, +0x6f, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, +0x31, 0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, +0x54, 0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, +0x36, 0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, +0x97, 0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, +0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *variable_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_variable_png = new wxImage(); + if (!img_variable_png || !img_variable_png->IsOk()) + { + wxMemoryInputStream img_variable_pngIS(variable_png_data, sizeof(variable_png_data)); + img_variable_png->LoadFile(img_variable_pngIS, wxBITMAP_TYPE_PNG); + } + return img_variable_png; +} +#define variable_png_img variable_png_img() + +static wxBitmap *variable_png_bmp() +{ + static wxBitmap *bmp_variable_png; + if (!bmp_variable_png || !bmp_variable_png->IsOk()) + bmp_variable_png = new wxBitmap(*variable_png_img); + return bmp_variable_png; +} +#define variable_png_bmp variable_png_bmp() + +static wxIcon *variable_png_ico() +{ + static wxIcon *ico_variable_png; + if (!ico_variable_png || !ico_variable_png->IsOk()) + { + ico_variable_png = new wxIcon(); + ico_variable_png->CopyFromBitmap(*variable_png_bmp); + } + return ico_variable_png; +} +#define variable_png_ico variable_png_ico() + +#endif // VARIABLE_PNG_H diff --git a/include/images/variables.png b/include/images/variables.png new file mode 100644 index 0000000..236bad7 Binary files /dev/null and b/include/images/variables.png differ diff --git a/include/images/variables.pngc b/include/images/variables.pngc new file mode 100644 index 0000000..2ad33c5 --- /dev/null +++ b/include/images/variables.pngc @@ -0,0 +1,88 @@ +#ifndef VARIABLES_PNG_H +#define VARIABLES_PNG_H + +static const unsigned char variables_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x04, 0x03, 0x00, 0x00, 0x00, 0xed, 0xdd, 0xe2, +0x52, 0x00, 0x00, 0x00, 0x2a, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xef, 0xa5, 0x39, 0xff, +0xef, 0xd6, 0xf7, 0xbd, 0x6f, 0xff, 0xe2, 0xc5, +0xfb, 0xde, 0xb5, 0xf7, 0xde, 0xad, 0xf7, 0xd6, +0xa4, 0xef, 0xa5, 0x42, 0xf7, 0xc8, 0x86, 0xef, +0xad, 0x4a, 0xef, 0xb5, 0x63, 0xef, 0xb1, 0x56, +0xef, 0xbd, 0x6b, 0xcd, 0x6c, 0x76, 0x1d, 0x00, +0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, +0x40, 0xe6, 0xd8, 0x66, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6b, 0x49, 0x44, 0x41, +0x54, 0x08, 0xd7, 0x63, 0x60, 0x14, 0x04, 0x02, +0x06, 0x20, 0x10, 0x52, 0x02, 0x02, 0x01, 0x10, +0xc3, 0x10, 0x2a, 0x24, 0x02, 0x13, 0x12, 0x85, +0x09, 0x89, 0x89, 0x88, 0x96, 0x2b, 0xa9, 0x95, +0x09, 0x30, 0x88, 0x8b, 0x8a, 0x36, 0x26, 0x65, +0xb4, 0x0a, 0x30, 0x48, 0x8a, 0x89, 0x54, 0x2c, +0x6f, 0x9c, 0x02, 0x64, 0x88, 0x8b, 0x46, 0x4a, +0x09, 0x87, 0x02, 0x19, 0x92, 0x62, 0x69, 0x0b, +0x97, 0xa7, 0x09, 0x30, 0x30, 0x4a, 0x8a, 0x57, +0x4b, 0xc9, 0x94, 0x03, 0xf5, 0x4b, 0x4a, 0x5e, +0x3c, 0xb9, 0x71, 0x27, 0x90, 0xc1, 0x28, 0x2b, +0x31, 0x73, 0x86, 0x2c, 0xc8, 0x12, 0xc9, 0x99, +0x40, 0x00, 0x62, 0xc0, 0xed, 0x87, 0x00, 0x00, +0x61, 0xf2, 0x15, 0xae, 0xd7, 0x6b, 0x2c, 0x79, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, +0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x30, 0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, +0xaa, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, +0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, +0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, +0x30, 0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, +0x32, 0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, +0x2b, 0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, +0x55, 0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, +0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *variables_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_variables_png = new wxImage(); + if (!img_variables_png || !img_variables_png->IsOk()) + { + wxMemoryInputStream img_variables_pngIS(variables_png_data, sizeof(variables_png_data)); + img_variables_png->LoadFile(img_variables_pngIS, wxBITMAP_TYPE_PNG); + } + return img_variables_png; +} +#define variables_png_img variables_png_img() + +static wxBitmap *variables_png_bmp() +{ + static wxBitmap *bmp_variables_png; + if (!bmp_variables_png || !bmp_variables_png->IsOk()) + bmp_variables_png = new wxBitmap(*variables_png_img); + return bmp_variables_png; +} +#define variables_png_bmp variables_png_bmp() + +static wxIcon *variables_png_ico() +{ + static wxIcon *ico_variables_png; + if (!ico_variables_png || !ico_variables_png->IsOk()) + { + ico_variables_png = new wxIcon(); + ico_variables_png->CopyFromBitmap(*variables_png_bmp); + } + return ico_variables_png; +} +#define variables_png_ico variables_png_ico() + +#endif // VARIABLES_PNG_H diff --git a/include/images/view-sm.png b/include/images/view-sm.png new file mode 100644 index 0000000..305a140 Binary files /dev/null and b/include/images/view-sm.png differ diff --git a/include/images/view-sm.pngc b/include/images/view-sm.pngc new file mode 100644 index 0000000..756f3cd --- /dev/null +++ b/include/images/view-sm.pngc @@ -0,0 +1,94 @@ +#ifndef VIEW_SM_PNG_H +#define VIEW_SM_PNG_H + +static const unsigned char view_sm_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xb6, 0xd6, 0x58, 0x9c, +0xc7, 0x1c, 0xcd, 0xe3, 0x8d, 0x9e, 0xc8, 0x20, +0xe2, 0xfc, 0x96, 0xe3, 0xf6, 0xa7, 0xe2, 0xee, +0xbe, 0xe4, 0xea, 0xd3, 0xe5, 0xe7, 0xde, 0xe7, +0xe7, 0xe5, 0xe6, 0xe6, 0xe6, 0xe2, 0xe5, 0xda, +0xd7, 0xe7, 0xa9, 0xb4, 0xd1, 0x5b, 0xe2, 0xff, +0x8b, 0xb7, 0xe9, 0x26, 0xff, 0xff, 0xff, 0xb7, +0xe8, 0x27, 0xdc, 0xec, 0xac, 0xb7, 0xe8, 0x26, +0xe1, 0xff, 0x8b, 0xcb, 0xf3, 0x56, 0xc7, 0xf0, +0x4b, 0xe0, 0xfe, 0x86, 0xdc, 0xfc, 0x7e, 0xd9, +0xfa, 0x75, 0xc7, 0xf1, 0x4b, 0xc3, 0xef, 0x40, +0xbe, 0xec, 0x36, 0xba, 0xea, 0x2e, 0x37, 0xfa, +0x6f, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x11, +0xe2, 0xb5, 0x3d, 0xba, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x58, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0x20, 0x02, 0x30, +0x32, 0xc1, 0x01, 0x33, 0x58, 0x80, 0x85, 0x95, +0x8d, 0x9d, 0x83, 0x93, 0x8b, 0x9b, 0x9b, 0x87, +0x97, 0x0f, 0x2c, 0xc0, 0xc4, 0x0f, 0x53, 0x20, +0xc0, 0x04, 0x13, 0x10, 0x04, 0x03, 0x64, 0x01, +0x90, 0xbc, 0x20, 0x93, 0x10, 0x92, 0x80, 0x30, +0x37, 0x90, 0x10, 0x81, 0x0a, 0x88, 0x02, 0xd9, +0x62, 0xe2, 0x48, 0x02, 0xd8, 0xb4, 0x40, 0x0c, +0x45, 0xa8, 0x40, 0xb7, 0x56, 0x42, 0x52, 0x4a, +0x4c, 0x5a, 0x46, 0x56, 0x0e, 0xaa, 0x82, 0x19, +0xdd, 0xe9, 0x04, 0x00, 0x00, 0x55, 0x66, 0x04, +0xb8, 0xcb, 0x08, 0xe4, 0xdf, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x31, +0x2d, 0x32, 0x33, 0x54, 0x30, 0x33, 0x3a, 0x30, +0x33, 0x3a, 0x34, 0x34, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x44, 0xd4, 0x3d, 0x9a, 0x00, 0x00, +0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, +0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, +0x79, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, +0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, +0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, +0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, +0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, +0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *view_sm_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_view_sm_png = new wxImage(); + if (!img_view_sm_png || !img_view_sm_png->IsOk()) + { + wxMemoryInputStream img_view_sm_pngIS(view_sm_png_data, sizeof(view_sm_png_data)); + img_view_sm_png->LoadFile(img_view_sm_pngIS, wxBITMAP_TYPE_PNG); + } + return img_view_sm_png; +} +#define view_sm_png_img view_sm_png_img() + +static wxBitmap *view_sm_png_bmp() +{ + static wxBitmap *bmp_view_sm_png; + if (!bmp_view_sm_png || !bmp_view_sm_png->IsOk()) + bmp_view_sm_png = new wxBitmap(*view_sm_png_img); + return bmp_view_sm_png; +} +#define view_sm_png_bmp view_sm_png_bmp() + +static wxIcon *view_sm_png_ico() +{ + static wxIcon *ico_view_sm_png; + if (!ico_view_sm_png || !ico_view_sm_png->IsOk()) + { + ico_view_sm_png = new wxIcon(); + ico_view_sm_png->CopyFromBitmap(*view_sm_png_bmp); + } + return ico_view_sm_png; +} +#define view_sm_png_ico view_sm_png_ico() + +#endif // VIEW_SM_PNG_H diff --git a/include/images/view.png b/include/images/view.png new file mode 100644 index 0000000..44116db Binary files /dev/null and b/include/images/view.png differ diff --git a/include/images/view.pngc b/include/images/view.pngc new file mode 100644 index 0000000..2316123 --- /dev/null +++ b/include/images/view.pngc @@ -0,0 +1,99 @@ +#ifndef VIEW_PNG_H +#define VIEW_PNG_H + +static const unsigned char view_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x75, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xcd, 0xe3, 0x8d, 0x9c, +0xc7, 0x1c, 0xe3, 0xff, 0x8d, 0xe1, 0xfb, 0x92, +0xe0, 0xf5, 0xa2, 0xe0, 0xed, 0xba, 0xe3, 0xe9, +0xd1, 0xe5, 0xe7, 0xdf, 0xe7, 0xe7, 0xe5, 0xe6, +0xe6, 0xe6, 0xe3, 0xe5, 0xda, 0xd8, 0xe7, 0xac, +0xc6, 0xe8, 0x63, 0xa1, 0xca, 0x29, 0xe2, 0xff, +0x8b, 0xb7, 0xe9, 0x26, 0xff, 0xff, 0xff, 0xb7, +0xe8, 0x27, 0xdb, 0xf3, 0x94, 0xe4, 0xe8, 0xd8, +0xdb, 0xe9, 0xb0, 0xd4, 0xf8, 0x6c, 0xd0, 0xf5, +0x61, 0xcb, 0xf3, 0x56, 0xc6, 0xf1, 0x4b, 0xd4, +0xf7, 0x6c, 0xd0, 0xf6, 0x61, 0xc7, 0xf1, 0x4b, +0xb7, 0xe8, 0x26, 0xe1, 0xff, 0x8b, 0xc7, 0xf0, +0x4b, 0xe0, 0xfe, 0x86, 0xdc, 0xfc, 0x7e, 0xd9, +0xfa, 0x75, 0xd5, 0xf8, 0x6b, 0xc3, 0xef, 0x40, +0xbe, 0xec, 0x36, 0xba, 0xea, 0x2e, 0xf5, 0x25, +0xaa, 0x61, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x11, +0xe2, 0xb5, 0x3d, 0xba, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6a, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x63, 0x60, 0xc0, 0x00, 0x8c, +0x4c, 0x48, 0x00, 0x24, 0xc0, 0xc4, 0xcc, 0xc2, +0xca, 0xc6, 0xce, 0xc1, 0xc9, 0xc5, 0xc5, 0xcd, +0xc3, 0xcb, 0x07, 0x12, 0xe0, 0x47, 0x28, 0x10, +0x60, 0x82, 0x08, 0x08, 0x42, 0x01, 0x42, 0x00, +0x22, 0x2f, 0xc8, 0x24, 0x04, 0x17, 0x10, 0x16, +0xe1, 0x12, 0x45, 0x11, 0x10, 0x13, 0x97, 0x90, +0x44, 0x11, 0x90, 0x92, 0x96, 0x90, 0x01, 0x52, +0xb2, 0x60, 0x01, 0x39, 0x90, 0x80, 0xb8, 0x84, +0x3c, 0x5c, 0x00, 0x9b, 0xa1, 0x30, 0x6b, 0x61, +0x2a, 0xd0, 0x1d, 0xa6, 0xa0, 0xa8, 0xa4, 0x2c, +0x2e, 0x21, 0xa3, 0xa2, 0xaa, 0x06, 0x56, 0x81, +0xe2, 0x39, 0x46, 0x4c, 0xcf, 0x03, 0x00, 0x8c, +0xb4, 0x07, 0x73, 0xfc, 0x3a, 0xf2, 0xd0, 0x00, +0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, +0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, +0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, +0x31, 0x32, 0x2d, 0x30, 0x31, 0x54, 0x32, 0x30, +0x3a, 0x34, 0x33, 0x3a, 0x34, 0x35, 0x2b, 0x30, +0x35, 0x3a, 0x30, 0x30, 0x9e, 0xee, 0x2e, 0xaa, +0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, +0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, +0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x30, +0x2d, 0x30, 0x39, 0x2d, 0x30, 0x31, 0x54, 0x32, +0x33, 0x3a, 0x34, 0x34, 0x3a, 0x30, 0x36, 0x2b, +0x30, 0x35, 0x3a, 0x30, 0x30, 0xca, 0x97, 0x55, +0xac, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, +0x44, 0xae, 0x42, 0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *view_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_view_png = new wxImage(); + if (!img_view_png || !img_view_png->IsOk()) + { + wxMemoryInputStream img_view_pngIS(view_png_data, sizeof(view_png_data)); + img_view_png->LoadFile(img_view_pngIS, wxBITMAP_TYPE_PNG); + } + return img_view_png; +} +#define view_png_img view_png_img() + +static wxBitmap *view_png_bmp() +{ + static wxBitmap *bmp_view_png; + if (!bmp_view_png || !bmp_view_png->IsOk()) + bmp_view_png = new wxBitmap(*view_png_img); + return bmp_view_png; +} +#define view_png_bmp view_png_bmp() + +static wxIcon *view_png_ico() +{ + static wxIcon *ico_view_png; + if (!ico_view_png || !ico_view_png->IsOk()) + { + ico_view_png = new wxIcon(); + ico_view_png->CopyFromBitmap(*view_png_bmp); + } + return ico_view_png; +} +#define view_png_ico view_png_ico() + +#endif // VIEW_PNG_H diff --git a/include/images/viewdata.png b/include/images/viewdata.png new file mode 100644 index 0000000..e98d20b Binary files /dev/null and b/include/images/viewdata.png differ diff --git a/include/images/viewdata.pngc b/include/images/viewdata.pngc new file mode 100644 index 0000000..65e570e --- /dev/null +++ b/include/images/viewdata.pngc @@ -0,0 +1,181 @@ +#ifndef VIEWDATA_PNG_H +#define VIEWDATA_PNG_H + +static const unsigned char viewdata_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x99, 0xbf, 0xd2, 0x51, +0x92, 0xb2, 0xf2, 0xf9, 0xfb, 0xe4, 0xf2, 0xf7, +0xe2, 0xf1, 0xf7, 0xdf, 0xf0, 0xf6, 0xde, 0xf0, +0xf6, 0xdc, 0xee, 0xf6, 0xdb, 0xee, 0xf6, 0xd9, +0xed, 0xf6, 0xd8, 0xed, 0xf5, 0xd6, 0xec, 0xf5, +0xd5, 0xeb, 0xf5, 0xd3, 0xea, 0xf5, 0xd0, 0xe8, +0xf5, 0xcc, 0xe7, 0xf5, 0xc8, 0xe5, 0xf4, 0xc6, +0xe4, 0xf4, 0xc5, 0xe3, 0xf4, 0xc3, 0xe2, 0xf4, +0xc0, 0xe1, 0xf4, 0xdf, 0xf0, 0xf9, 0xcf, 0xe8, +0xf1, 0xcc, 0xe7, 0xf1, 0xc9, 0xe5, 0xf0, 0xc6, +0xe4, 0xf0, 0xc4, 0xe3, 0xf0, 0xc3, 0xe2, 0xf0, +0xc0, 0xe1, 0xf0, 0xbe, 0xe0, 0xef, 0xbc, 0xdf, +0xef, 0xb8, 0xdd, 0xef, 0xb5, 0xdc, 0xef, 0xb2, +0xdb, 0xee, 0xb0, 0xda, 0xee, 0xad, 0xd8, 0xee, +0xab, 0xd7, 0xee, 0xa8, 0xd6, 0xed, 0xa4, 0xd4, +0xed, 0xa2, 0xd3, 0xed, 0x9e, 0xd1, 0xed, 0x9c, +0xd0, 0xed, 0x9a, 0xcf, 0xec, 0x96, 0xcd, 0xec, +0x93, 0xcc, 0xec, 0xbb, 0xdf, 0xf3, 0xe3, 0xf2, +0xf7, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, 0xe4, +0xe4, 0xe4, 0xf7, 0xf7, 0xf7, 0xd9, 0xd9, 0xd9, +0xa8, 0xd5, 0xed, 0x90, 0xca, 0xeb, 0xeb, 0xeb, +0xeb, 0xfb, 0xfb, 0xfb, 0xff, 0xff, 0xff, 0x8c, +0xc8, 0xeb, 0xfd, 0xfd, 0xfd, 0xc1, 0xe2, 0xf0, +0xa1, 0xd2, 0xed, 0x89, 0xc7, 0xeb, 0xb6, 0xdd, +0xf3, 0xba, 0xde, 0xef, 0xaf, 0xd9, 0xee, 0xaa, +0xd6, 0xee, 0xa7, 0xd5, 0xed, 0x98, 0xce, 0xec, +0x91, 0xcb, 0xec, 0x8f, 0xca, 0xeb, 0x85, 0xc5, +0xeb, 0xb4, 0xdb, 0xf2, 0x83, 0xc4, 0xea, 0xb2, +0xdb, 0xf2, 0x7f, 0xc2, 0xea, 0x94, 0xcc, 0xec, +0x7c, 0xc1, 0xea, 0xaf, 0xd9, 0xf2, 0xb9, 0xde, +0xef, 0x97, 0xce, 0xec, 0x8e, 0xc9, 0xeb, 0x88, +0xc6, 0xeb, 0x78, 0xbf, 0xea, 0xad, 0xd8, 0xf2, +0x76, 0xbe, 0xe9, 0xae, 0xd8, 0xee, 0x8a, 0xc8, +0xeb, 0x72, 0xbc, 0xe9, 0xaa, 0xd6, 0xf2, 0x70, +0xbb, 0xe9, 0xa8, 0xd6, 0xf2, 0xa8, 0xd6, 0xee, +0x90, 0xca, 0xec, 0x84, 0xc5, 0xeb, 0x81, 0xc3, +0xea, 0x7b, 0xc0, 0xea, 0x75, 0xbe, 0xe9, 0x6d, +0xba, 0xe9, 0xa5, 0xd5, 0xf1, 0x6a, 0xb8, 0xe8, +0x67, 0xb7, 0xe8, 0xa2, 0xd3, 0xf1, 0x66, 0xb6, +0xe8, 0xce, 0xe8, 0xf5, 0x9b, 0xd0, 0xec, 0x86, +0xc6, 0xeb, 0x74, 0xbd, 0xe9, 0x64, 0xb6, 0xe8, +0x61, 0xb4, 0xe8, 0xa0, 0xd2, 0xf1, 0x5f, 0xb3, +0xe7, 0x9e, 0xd1, 0xf1, 0xcb, 0xe6, 0xf4, 0x5d, +0xb2, 0xe7, 0x5b, 0xb1, 0xe7, 0x9c, 0xd0, 0xf1, +0x63, 0xb5, 0xe8, 0x58, 0xb0, 0xe7, 0x9a, 0xcf, +0xf1, 0x55, 0xaf, 0xe7, 0x97, 0xce, 0xf0, 0x52, +0xad, 0xe6, 0xbf, 0xe1, 0xf4, 0x9f, 0xd2, 0xf1, +0x9b, 0xd0, 0xf1, 0x96, 0xce, 0xf0, 0xcb, 0xe6, +0xf8, 0x1a, 0x34, 0x20, 0x33, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x39, 0xd7, 0x00, 0x95, 0x40, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x01, 0xec, +0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xa5, 0x93, +0xe9, 0x37, 0x6a, 0x51, 0x18, 0x87, 0x49, 0x91, +0xa9, 0xc1, 0x54, 0x9d, 0xdc, 0x8a, 0x3a, 0x2a, +0x27, 0xa1, 0x2e, 0x57, 0x51, 0x49, 0x85, 0x34, +0x50, 0x19, 0xca, 0x54, 0x34, 0xa1, 0x8b, 0xae, +0xe1, 0x56, 0xee, 0xc5, 0xbf, 0xee, 0xec, 0x77, +0xbf, 0xac, 0xed, 0x0b, 0xd6, 0xf2, 0x7e, 0x38, +0xeb, 0x77, 0xd6, 0x79, 0xd6, 0xfa, 0x3d, 0xfb, +0xdd, 0xeb, 0xb4, 0xb5, 0x7d, 0x3a, 0xed, 0x92, +0x0f, 0xa6, 0x5d, 0x04, 0x24, 0x1d, 0x52, 0xa9, +0x4c, 0x26, 0xeb, 0xec, 0x92, 0xcb, 0xbb, 0x7b, +0x7a, 0xfb, 0xfa, 0x15, 0x0a, 0xa5, 0x52, 0xa5, +0x52, 0xab, 0x07, 0x06, 0x87, 0x86, 0x47, 0x24, +0x04, 0x90, 0x6a, 0x34, 0x5a, 0xad, 0x4e, 0xc7, +0xe9, 0x47, 0x7f, 0x18, 0x8c, 0xa6, 0xb1, 0x71, +0xb3, 0x85, 0x9f, 0xb0, 0xda, 0xec, 0x93, 0x82, +0x63, 0xca, 0x09, 0xc0, 0xb4, 0x66, 0x66, 0xd6, +0xe5, 0xe6, 0x66, 0x66, 0x7f, 0xd2, 0x71, 0xb9, +0xe7, 0x20, 0xbb, 0xdc, 0xf3, 0x14, 0x90, 0x69, +0x7f, 0x2d, 0x78, 0x3c, 0x7a, 0xf2, 0xc0, 0xb1, +0x62, 0xf6, 0xbe, 0x02, 0x8b, 0xe2, 0xcb, 0xd2, +0xe2, 0xdb, 0x77, 0x8f, 0x0f, 0xb3, 0x3f, 0x00, +0x40, 0xa7, 0x8e, 0xe3, 0xf4, 0x4b, 0x06, 0xe3, +0xb2, 0xd8, 0x1f, 0xb4, 0xac, 0x84, 0xac, 0x3e, +0xbb, 0x10, 0x76, 0x44, 0x56, 0xbd, 0xfe, 0xb5, +0x75, 0x0a, 0x70, 0xc4, 0xc1, 0xc8, 0x38, 0x08, +0xe8, 0x10, 0xdd, 0x00, 0xa0, 0x0b, 0xea, 0x97, +0x19, 0x87, 0x30, 0xe6, 0x18, 0x05, 0xe4, 0xa3, +0xa4, 0xd2, 0xc4, 0x38, 0xc4, 0x31, 0x27, 0x92, +0x00, 0x74, 0x8b, 0xc7, 0xdf, 0x34, 0x8d, 0x99, +0x83, 0xfc, 0x4a, 0xc8, 0xe6, 0x9b, 0x14, 0xb6, +0xe2, 0x91, 0x94, 0x37, 0xbd, 0x16, 0x8d, 0x25, +0x32, 0xdb, 0x00, 0xf4, 0x18, 0x88, 0x83, 0x99, +0x71, 0x48, 0xa1, 0xc3, 0x0e, 0x05, 0x7a, 0x8d, +0xa4, 0x72, 0x97, 0x71, 0xd8, 0xc3, 0x9c, 0xcd, +0x01, 0xd0, 0x07, 0xf5, 0x3c, 0xe3, 0x90, 0xc6, +0xbc, 0x7f, 0x00, 0x40, 0xbf, 0xb8, 0xfe, 0x5d, +0xfe, 0x10, 0xd7, 0x7f, 0x94, 0xf2, 0xa7, 0x8f, +0xf3, 0xb1, 0x42, 0xe6, 0x24, 0xbb, 0x7f, 0x5a, +0x04, 0x40, 0x31, 0x4e, 0x1c, 0xac, 0x8c, 0x43, +0x1e, 0x1d, 0x4a, 0x08, 0x04, 0x49, 0xa5, 0x8d, +0x71, 0x48, 0x60, 0x2e, 0x57, 0x00, 0x50, 0x5a, +0x48, 0xa5, 0x9d, 0x71, 0x28, 0x60, 0xae, 0x52, +0xe0, 0x8c, 0x27, 0xeb, 0x3f, 0xa7, 0xeb, 0xbf, +0x88, 0xe6, 0x13, 0x85, 0x4c, 0x4d, 0xec, 0x2f, +0x95, 0x7f, 0x5f, 0x5e, 0x01, 0xa0, 0x0a, 0x11, +0x87, 0x30, 0xe3, 0x50, 0x43, 0x87, 0xeb, 0x3a, +0x00, 0x7f, 0xe0, 0xfa, 0xe3, 0x8c, 0x43, 0x16, +0xf3, 0x0d, 0x05, 0xd4, 0x70, 0xfd, 0x11, 0xc6, +0xe1, 0x14, 0xf3, 0xed, 0x1d, 0x00, 0x03, 0x76, +0x76, 0xfd, 0x3b, 0x35, 0xb1, 0xbe, 0x54, 0xbd, +0xbf, 0xbc, 0xbe, 0xb9, 0xfd, 0xdb, 0x00, 0x60, +0x50, 0x20, 0x0e, 0x5e, 0xc6, 0xa1, 0x8c, 0x0e, +0x4d, 0x0a, 0x0c, 0x39, 0x48, 0x65, 0x9a, 0x71, +0xa8, 0x62, 0x6e, 0xb6, 0x00, 0x18, 0x9e, 0x22, +0x95, 0xc7, 0x8c, 0xc3, 0x3d, 0xe6, 0x07, 0x0a, +0xfc, 0x7b, 0xb7, 0xfe, 0x52, 0x19, 0xfb, 0x9b, +0xcd, 0x07, 0x04, 0x46, 0x9c, 0xce, 0x40, 0x60, +0x7d, 0x23, 0x99, 0xdc, 0xce, 0xe5, 0x0e, 0x8a, +0xc5, 0x4a, 0xe5, 0xea, 0x7f, 0xbd, 0xfe, 0xd8, +0x68, 0xb4, 0x5a, 0x4f, 0xcf, 0x92, 0xaf, 0xfc, +0x9b, 0xdf, 0x9d, 0x17, 0x7b, 0xba, 0xaf, 0x67, +0x71, 0xaa, 0xfe, 0x56, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *viewdata_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_viewdata_png = new wxImage(); + if (!img_viewdata_png || !img_viewdata_png->IsOk()) + { + wxMemoryInputStream img_viewdata_pngIS(viewdata_png_data, sizeof(viewdata_png_data)); + img_viewdata_png->LoadFile(img_viewdata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_viewdata_png; +} +#define viewdata_png_img viewdata_png_img() + +static wxBitmap *viewdata_png_bmp() +{ + static wxBitmap *bmp_viewdata_png; + if (!bmp_viewdata_png || !bmp_viewdata_png->IsOk()) + bmp_viewdata_png = new wxBitmap(*viewdata_png_img); + return bmp_viewdata_png; +} +#define viewdata_png_bmp viewdata_png_bmp() + +static wxIcon *viewdata_png_ico() +{ + static wxIcon *ico_viewdata_png; + if (!ico_viewdata_png || !ico_viewdata_png->IsOk()) + { + ico_viewdata_png = new wxIcon(); + ico_viewdata_png->CopyFromBitmap(*viewdata_png_bmp); + } + return ico_viewdata_png; +} +#define viewdata_png_ico viewdata_png_ico() + +#endif // VIEWDATA_PNG_H diff --git a/include/images/viewfiltereddata.png b/include/images/viewfiltereddata.png new file mode 100644 index 0000000..3177d55 Binary files /dev/null and b/include/images/viewfiltereddata.png differ diff --git a/include/images/viewfiltereddata.pngc b/include/images/viewfiltereddata.pngc new file mode 100644 index 0000000..20094f2 --- /dev/null +++ b/include/images/viewfiltereddata.pngc @@ -0,0 +1,190 @@ +#ifndef VIEWFILTEREDDATA_PNG_H +#define VIEWFILTEREDDATA_PNG_H + +static const unsigned char viewfiltereddata_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, +0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xa4, 0x8a, +0xc6, 0x00, 0x00, 0x01, 0x80, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0x98, 0xbf, 0xd3, 0x51, +0x92, 0xb2, 0xf2, 0xf9, 0xfb, 0xe3, 0xf1, 0xf7, +0xdf, 0xf0, 0xf6, 0xda, 0xee, 0xf6, 0xd6, 0xec, +0xf5, 0xd5, 0xeb, 0xf5, 0xd2, 0xea, 0xf5, 0xcf, +0xe8, 0xf3, 0xcc, 0xe7, 0xf5, 0xc8, 0xe5, 0xf4, +0xc6, 0xe4, 0xf4, 0xc4, 0xe3, 0xf4, 0xc0, 0xe1, +0xf4, 0xdf, 0xf0, 0xf9, 0xcc, 0xe7, 0xf1, 0xc9, +0xe5, 0xf0, 0xc6, 0xe4, 0xf0, 0xc4, 0xe3, 0xf0, +0xc1, 0xe2, 0xf0, 0xbe, 0xe0, 0xf0, 0xba, 0xde, +0xef, 0xb6, 0xdc, 0xef, 0xb3, 0xdb, 0xee, 0xb0, +0xda, 0xee, 0xac, 0xd8, 0xee, 0xa8, 0xd6, 0xed, +0xa4, 0xd4, 0xed, 0xa1, 0xd2, 0xed, 0x9d, 0xd1, +0xed, 0x99, 0xcf, 0xec, 0x95, 0xcc, 0xec, 0x93, +0xcc, 0xec, 0xdb, 0xdb, 0xdb, 0xdc, 0xdc, 0xdc, +0xe4, 0xe4, 0xe4, 0xf7, 0xf7, 0xf7, 0xd9, 0xd9, +0xd9, 0x91, 0xcb, 0xec, 0xb9, 0xde, 0xf3, 0xeb, +0xeb, 0xeb, 0xfb, 0xfb, 0xfb, 0xff, 0xff, 0xff, +0x8b, 0xc8, 0xeb, 0xfd, 0xfd, 0xfd, 0x88, 0xc6, +0xeb, 0x8f, 0xc9, 0xeb, 0xb3, 0xdb, 0xf2, 0x84, +0xc4, 0xea, 0x7d, 0xc1, 0xea, 0xae, 0xd8, 0xf2, +0x79, 0xbf, 0xe9, 0x72, 0xbc, 0xe9, 0xa9, 0xd6, +0xf2, 0xa5, 0xd4, 0xf1, 0x97, 0xcc, 0xe8, 0x91, +0xc5, 0xe4, 0x89, 0xc2, 0xe3, 0x84, 0xbf, 0xe2, +0x7c, 0xbb, 0xe1, 0x75, 0xb8, 0xe2, 0x6f, 0xb6, +0xe0, 0x6b, 0xb4, 0xe1, 0xa1, 0xcf, 0xea, 0x50, +0x90, 0xaf, 0xd6, 0xd6, 0xd6, 0xd0, 0xd0, 0xd0, +0xc3, 0xc3, 0xc3, 0xb9, 0xb9, 0xb9, 0xb6, 0xb6, +0xb6, 0x71, 0xab, 0xcd, 0x53, 0x9c, 0xca, 0x4d, +0x8b, 0xa9, 0x95, 0x97, 0xb5, 0x78, 0x7a, 0xb4, +0x70, 0x73, 0xb4, 0xb9, 0xba, 0xd9, 0xce, 0xce, +0xd6, 0x81, 0x83, 0xbd, 0xf0, 0xf1, 0xf3, 0xf0, +0xe6, 0xff, 0xe5, 0xd8, 0xfb, 0xdd, 0xd3, 0xf4, +0xd9, 0xcd, 0xf2, 0xd3, 0xc9, 0xec, 0xd0, 0xc2, +0xec, 0xc9, 0xbc, 0xe7, 0xc5, 0xbc, 0xe1, 0xea, +0xe7, 0xf3, 0x70, 0x88, 0xb4, 0xd5, 0xbd, 0xfa, +0xcd, 0xb1, 0xf9, 0xc6, 0xaf, 0xee, 0xc3, 0xa7, +0xf2, 0xb7, 0x9c, 0xe8, 0xad, 0x92, 0xe1, 0xa6, +0x8b, 0xdb, 0x9e, 0x83, 0xd5, 0x96, 0x7c, 0xce, +0x90, 0x75, 0xc9, 0x99, 0x83, 0xcc, 0xca, 0xca, +0xca, 0x88, 0x8a, 0xa8, 0x5a, 0x7a, 0xaa, 0xbb, +0xa7, 0xe3, 0x88, 0xb5, 0xd2, 0x5d, 0x99, 0xbd, +0xab, 0x97, 0xd8, 0x8e, 0x73, 0xc8, 0x49, 0x92, +0xbf, 0x85, 0x6b, 0xc2, 0x54, 0xa1, 0xd2, 0x97, +0xcb, 0xec, 0xc3, 0xb5, 0xe1, 0x7d, 0x63, 0xbc, +0xb6, 0xa8, 0xd7, 0x51, 0xaa, 0xe2, 0x97, 0xce, +0xf0, 0x6f, 0x55, 0xb0, 0x6a, 0xb8, 0xe8, 0x62, +0xb0, 0xe1, 0xbb, 0xad, 0xdb, 0xaf, 0xa2, 0xd2, +0x98, 0xc7, 0xe5, 0xcb, 0xe6, 0xf8, 0xab, 0xad, +0xd3, 0x5a, 0x56, 0x7f, 0x12, 0x00, 0x00, 0x00, +0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, 0xe6, +0xd8, 0x66, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4b, +0x47, 0x44, 0x2c, 0xba, 0xdd, 0x71, 0xab, 0x00, +0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, +0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x00, +0x46, 0xc9, 0x6b, 0x3e, 0x00, 0x00, 0x02, 0x34, +0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x85, 0x93, +0xfb, 0x5b, 0xd2, 0x50, 0x18, 0xc7, 0x85, 0x04, +0xe4, 0x22, 0xc8, 0x1d, 0xb9, 0x0e, 0x74, 0x8b, +0xcb, 0x18, 0x57, 0x07, 0x81, 0xa0, 0x31, 0x07, +0x98, 0xad, 0x46, 0x02, 0xe6, 0x25, 0xb3, 0xa2, +0x40, 0x4b, 0xd3, 0x14, 0x85, 0xa2, 0xfc, 0xd7, +0xdb, 0x7b, 0x76, 0xe0, 0x59, 0xcf, 0xe3, 0x93, +0xdf, 0x1f, 0xce, 0xde, 0x3d, 0xe7, 0xb3, 0x7d, +0xbf, 0x7b, 0xdf, 0x9d, 0xb9, 0xb9, 0x47, 0xa5, +0x52, 0xff, 0x47, 0x2a, 0x09, 0x50, 0x3f, 0x99, +0x07, 0x69, 0x34, 0x1a, 0xad, 0x56, 0xab, 0xd3, +0x2d, 0xe8, 0xf5, 0x7a, 0x83, 0xd1, 0x68, 0x32, +0x2d, 0x9a, 0x2d, 0x96, 0x25, 0x35, 0x00, 0xf3, +0x06, 0x83, 0xd5, 0x6a, 0xb3, 0xd9, 0x1d, 0x4e, +0xa7, 0xcb, 0xed, 0xf6, 0x2c, 0x7b, 0x7d, 0x3e, +0x7f, 0x20, 0x18, 0x0a, 0x11, 0xe1, 0x88, 0x0b, +0x03, 0x2b, 0xab, 0x24, 0x65, 0x5f, 0x59, 0x7d, +0x2a, 0x8b, 0xa4, 0xfc, 0xa8, 0x26, 0xa9, 0x68, +0x4c, 0x06, 0xac, 0xf1, 0x04, 0x4d, 0x3b, 0x60, +0xc1, 0x0a, 0xe0, 0x3a, 0x39, 0x05, 0x18, 0xe9, +0xc6, 0xc9, 0xcc, 0xf6, 0xe9, 0x20, 0xae, 0x53, +0x32, 0xa0, 0xb1, 0xd9, 0x25, 0x7f, 0xb0, 0x07, +0x7f, 0x3f, 0xf8, 0x13, 0x44, 0x38, 0x9a, 0x4e, +0xa6, 0x52, 0x19, 0x19, 0xb0, 0x43, 0x06, 0xb7, +0x22, 0x03, 0x81, 0x33, 0x64, 0x31, 0x80, 0xec, +0xdd, 0x8a, 0x0c, 0x04, 0xae, 0x73, 0x32, 0xa0, +0x75, 0x80, 0xa5, 0x47, 0x91, 0x21, 0x8c, 0xeb, +0x5c, 0x5e, 0x06, 0xf0, 0xe7, 0x83, 0x7f, 0x10, +0xfc, 0x23, 0xe0, 0x9f, 0xcd, 0xe6, 0x72, 0x6b, +0x18, 0x70, 0x41, 0x06, 0xaf, 0x22, 0x43, 0x1a, +0x67, 0x60, 0x65, 0x40, 0x87, 0xec, 0x7d, 0x8a, +0x0c, 0x49, 0x5c, 0xb3, 0x05, 0x0c, 0x80, 0xa5, +0x0f, 0x16, 0x06, 0x89, 0xce, 0x26, 0xe4, 0x82, +0x2d, 0x22, 0x60, 0x61, 0xd6, 0x7e, 0xe2, 0x59, +0xa9, 0x54, 0x2e, 0xaf, 0xaf, 0x57, 0x2a, 0x95, +0x6a, 0x75, 0x63, 0x63, 0x73, 0xf3, 0x79, 0x0d, +0x00, 0xfd, 0x32, 0x64, 0x08, 0x48, 0xbe, 0xdc, +0x16, 0x5f, 0xaf, 0x37, 0xf8, 0xad, 0xa6, 0xb4, +0x36, 0xa4, 0xeb, 0xb6, 0xea, 0x05, 0x03, 0x80, +0x17, 0x2c, 0x83, 0xf1, 0x04, 0x43, 0x91, 0x3b, +0x2f, 0x85, 0x7f, 0xf5, 0x4a, 0x02, 0x0c, 0xc8, +0x3e, 0xc4, 0xd0, 0x09, 0xea, 0xb5, 0xd8, 0x7a, +0xb3, 0x2b, 0xa9, 0xdd, 0xe9, 0x74, 0xf7, 0xf6, +0xde, 0xee, 0x77, 0x0f, 0x44, 0x04, 0xe0, 0xf6, +0xa7, 0xcb, 0xcd, 0x43, 0x71, 0xf7, 0xe8, 0xdd, +0xf1, 0xfb, 0x93, 0x93, 0x0f, 0x1f, 0x3f, 0xf5, +0x3e, 0x7f, 0xd9, 0x17, 0xe1, 0x0d, 0x46, 0x3f, +0x64, 0x80, 0xfe, 0x73, 0xfd, 0xc6, 0x40, 0x6c, +0x1f, 0x29, 0xf6, 0x4f, 0x13, 0x00, 0xa0, 0xf1, +0x87, 0xa5, 0x85, 0xa1, 0xe2, 0xfd, 0x1d, 0xb1, +0x7d, 0x3c, 0xdb, 0x3f, 0x44, 0x21, 0x4d, 0x68, +0xfc, 0x51, 0xd4, 0x07, 0x44, 0x74, 0xce, 0xa6, +0xcf, 0x7f, 0x45, 0x9f, 0xb9, 0xa8, 0x68, 0xff, +0x5a, 0xb5, 0xf9, 0xed, 0x54, 0xec, 0x9e, 0xf7, +0x2e, 0x7a, 0xd2, 0xfe, 0xf7, 0x12, 0x02, 0xcc, +0x04, 0x64, 0x48, 0xca, 0xb3, 0xe0, 0x38, 0xbe, +0x3e, 0x10, 0xcf, 0x2e, 0x2e, 0xcf, 0xc5, 0x41, +0xff, 0xea, 0x07, 0xea, 0xa4, 0x19, 0xec, 0xe9, +0x14, 0xee, 0xbf, 0xd4, 0x0c, 0x5e, 0xb8, 0xbe, +0xbc, 0x19, 0x0a, 0x3c, 0x79, 0x7b, 0x87, 0x00, +0x4b, 0x04, 0xec, 0xb3, 0xd3, 0xff, 0x81, 0x69, +0x71, 0xc2, 0xf5, 0xcd, 0x68, 0x28, 0x70, 0xad, +0x29, 0x10, 0x4d, 0xa7, 0xe4, 0xf1, 0xb3, 0x2c, +0x3b, 0x1e, 0x8f, 0x7f, 0x5e, 0x09, 0xbf, 0x46, +0xa3, 0x89, 0xb0, 0x7d, 0x8b, 0x81, 0xa5, 0x58, +0x2c, 0xe6, 0xc9, 0x64, 0xf2, 0xf9, 0x7c, 0xa1, +0x50, 0x28, 0x16, 0x8b, 0xc1, 0xdf, 0xc2, 0x10, +0x80, 0x72, 0xf8, 0xee, 0x8f, 0xfa, 0xc1, 0xb3, +0x59, 0x13, 0x0e, 0x26, 0x13, 0x52, 0xa8, 0xe1, +0xb3, 0xf9, 0x80, 0xee, 0x61, 0x4c, 0xf7, 0x8f, +0x9f, 0x7b, 0xa4, 0xbf, 0x65, 0x37, 0x9e, 0x9f, +0xfc, 0xd9, 0x77, 0xd0, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x30, 0x2d, 0x31, 0x32, 0x2d, +0x30, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x34, 0x33, +0x3a, 0x34, 0x35, 0x2b, 0x30, 0x35, 0x3a, 0x30, +0x30, 0x9e, 0xee, 0x2e, 0xaa, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x30, 0x39, +0x2d, 0x30, 0x31, 0x54, 0x32, 0x33, 0x3a, 0x34, +0x34, 0x3a, 0x30, 0x36, 0x2b, 0x30, 0x35, 0x3a, +0x30, 0x30, 0xca, 0x97, 0x55, 0xac, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *viewfiltereddata_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_viewfiltereddata_png = new wxImage(); + if (!img_viewfiltereddata_png || !img_viewfiltereddata_png->IsOk()) + { + wxMemoryInputStream img_viewfiltereddata_pngIS(viewfiltereddata_png_data, sizeof(viewfiltereddata_png_data)); + img_viewfiltereddata_png->LoadFile(img_viewfiltereddata_pngIS, wxBITMAP_TYPE_PNG); + } + return img_viewfiltereddata_png; +} +#define viewfiltereddata_png_img viewfiltereddata_png_img() + +static wxBitmap *viewfiltereddata_png_bmp() +{ + static wxBitmap *bmp_viewfiltereddata_png; + if (!bmp_viewfiltereddata_png || !bmp_viewfiltereddata_png->IsOk()) + bmp_viewfiltereddata_png = new wxBitmap(*viewfiltereddata_png_img); + return bmp_viewfiltereddata_png; +} +#define viewfiltereddata_png_bmp viewfiltereddata_png_bmp() + +static wxIcon *viewfiltereddata_png_ico() +{ + static wxIcon *ico_viewfiltereddata_png; + if (!ico_viewfiltereddata_png || !ico_viewfiltereddata_png->IsOk()) + { + ico_viewfiltereddata_png = new wxIcon(); + ico_viewfiltereddata_png->CopyFromBitmap(*viewfiltereddata_png_bmp); + } + return ico_viewfiltereddata_png; +} +#define viewfiltereddata_png_ico viewfiltereddata_png_ico() + +#endif // VIEWFILTEREDDATA_PNG_H diff --git a/include/images/views.png b/include/images/views.png new file mode 100644 index 0000000..078d533 Binary files /dev/null and b/include/images/views.png differ diff --git a/include/images/views.pngc b/include/images/views.pngc new file mode 100644 index 0000000..265fdaa --- /dev/null +++ b/include/images/views.pngc @@ -0,0 +1,97 @@ +#ifndef VIEWS_PNG_H +#define VIEWS_PNG_H + +static const unsigned char views_png_data[] = { +0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, +0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, +0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, +0x08, 0x03, 0x00, 0x00, 0x00, 0x28, 0x2d, 0x0f, +0x53, 0x00, 0x00, 0x00, 0x5d, 0x50, 0x4c, 0x54, +0x45, 0x00, 0x00, 0x00, 0xcd, 0xe3, 0x8d, 0x9c, +0xc7, 0x1c, 0x9e, 0xc8, 0x20, 0xe2, 0xfc, 0x96, +0xe3, 0xf6, 0xa7, 0xe2, 0xee, 0xbe, 0xe4, 0xea, +0xd3, 0xe5, 0xe7, 0xde, 0xe7, 0xe7, 0xe5, 0xe6, +0xe6, 0xe6, 0xe2, 0xe5, 0xda, 0xd7, 0xe7, 0xa9, +0xb4, 0xd1, 0x5b, 0xe2, 0xff, 0x8b, 0xfe, 0xfe, +0xfe, 0xe1, 0xff, 0x8b, 0xb7, 0xe9, 0x26, 0xff, +0xff, 0xff, 0xb7, 0xe8, 0x27, 0xdc, 0xec, 0xac, +0xb7, 0xe8, 0x26, 0xcb, 0xf3, 0x56, 0xc7, 0xf0, +0x4b, 0xe0, 0xfe, 0x86, 0xdc, 0xfc, 0x7e, 0xd9, +0xfa, 0x75, 0xc7, 0xf1, 0x4b, 0xc3, 0xef, 0x40, +0xbe, 0xec, 0x36, 0xba, 0xea, 0x2e, 0x8a, 0x3c, +0xa3, 0xec, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, +0x4e, 0x53, 0x00, 0x40, 0xe6, 0xd8, 0x66, 0x00, +0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x12, +0x7b, 0xbc, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x09, +0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x00, 0x48, +0x00, 0x00, 0x00, 0x48, 0x00, 0x46, 0xc9, 0x6b, +0x3e, 0x00, 0x00, 0x00, 0x6f, 0x49, 0x44, 0x41, +0x54, 0x18, 0xd3, 0x55, 0x8f, 0x59, 0x12, 0x80, +0x20, 0x0c, 0x43, 0x35, 0xee, 0xa8, 0x88, 0xa8, +0xb8, 0x7b, 0xff, 0x63, 0x4a, 0x81, 0x41, 0x9b, +0x8f, 0x0e, 0x93, 0xbe, 0xb6, 0x21, 0x49, 0x11, +0x95, 0x26, 0xa4, 0x2c, 0x2f, 0xca, 0xaa, 0x6e, +0x84, 0x68, 0xbb, 0xde, 0x19, 0x90, 0xe0, 0x0c, +0xe4, 0x9f, 0x19, 0x1c, 0xc1, 0x19, 0x32, 0xd8, +0x1e, 0xa8, 0x3f, 0x33, 0xc2, 0x8f, 0x48, 0x68, +0xa7, 0x60, 0x10, 0xa3, 0xa9, 0xaf, 0x31, 0x7d, +0x04, 0x66, 0x61, 0xcb, 0x12, 0x0c, 0x65, 0xdf, +0x66, 0xf5, 0x86, 0x8d, 0x2e, 0xd9, 0x48, 0x48, +0x12, 0x96, 0x2e, 0x70, 0xe9, 0xd9, 0x59, 0xff, +0x9f, 0x6d, 0x3f, 0xcc, 0x79, 0xdd, 0x8f, 0x27, +0x88, 0x89, 0xd1, 0x5f, 0x3c, 0x33, 0x06, 0xdf, +0x95, 0x0d, 0xb0, 0x23, 0x00, 0x00, 0x00, 0x25, +0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, +0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, +0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x32, 0x2d, +0x32, 0x37, 0x54, 0x31, 0x34, 0x3a, 0x31, 0x39, +0x3a, 0x35, 0x35, 0x2b, 0x30, 0x36, 0x3a, 0x30, +0x30, 0x6f, 0xbe, 0x54, 0xb9, 0x00, 0x00, 0x00, +0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, +0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, +0x00, 0x32, 0x30, 0x31, 0x31, 0x2d, 0x30, 0x32, +0x2d, 0x32, 0x37, 0x54, 0x31, 0x34, 0x3a, 0x31, +0x39, 0x3a, 0x35, 0x35, 0x2b, 0x30, 0x36, 0x3a, +0x30, 0x30, 0x1e, 0xe3, 0xec, 0x05, 0x00, 0x00, +0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, +0x60, 0x82, +}; + +#include "wx/mstream.h" + +static wxImage *views_png_img() +{ + if (!wxImage::FindHandler(wxT("PNG file"))) + wxImage::AddHandler(new wxPNGHandler()); + static wxImage *img_views_png = new wxImage(); + if (!img_views_png || !img_views_png->IsOk()) + { + wxMemoryInputStream img_views_pngIS(views_png_data, sizeof(views_png_data)); + img_views_png->LoadFile(img_views_pngIS, wxBITMAP_TYPE_PNG); + } + return img_views_png; +} +#define views_png_img views_png_img() + +static wxBitmap *views_png_bmp() +{ + static wxBitmap *bmp_views_png; + if (!bmp_views_png || !bmp_views_png->IsOk()) + bmp_views_png = new wxBitmap(*views_png_img); + return bmp_views_png; +} +#define views_png_bmp views_png_bmp() + +static wxIcon *views_png_ico() +{ + static wxIcon *ico_views_png; + if (!ico_views_png || !ico_views_png->IsOk()) + { + ico_views_png = new wxIcon(); + ico_views_png->CopyFromBitmap(*views_png_bmp); + } + return ico_views_png; +} +#define views_png_ico views_png_ico() + +#endif // VIEWS_PNG_H diff --git a/include/libssh2/Win32/libssh2_config.h b/include/libssh2/Win32/libssh2_config.h new file mode 100644 index 0000000..6ac2ef4 --- /dev/null +++ b/include/libssh2/Win32/libssh2_config.h @@ -0,0 +1,47 @@ +#ifndef LIBSSH2_CONFIG_H +#define LIBSSH2_CONFIG_H + +#ifndef WIN32 +#define WIN32 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif /* _CRT_SECURE_NO_DEPRECATE */ +#include +#include +#include + +#ifdef __MINGW32__ +#define HAVE_UNISTD_H +#define HAVE_INTTYPES_H +#define HAVE_SYS_TIME_H +#define HAVE_GETTIMEOFDAY +#endif /* __MINGW32__ */ + +#define HAVE_LIBCRYPT32 +#define HAVE_WINSOCK2_H +#define HAVE_IOCTLSOCKET +#define HAVE_SELECT + +#ifdef _MSC_VER +#if _MSC_VER < 1900 +#define snprintf _snprintf +#if _MSC_VER < 1500 +#define vsnprintf _vsnprintf +#endif +#define strdup _strdup +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif +#else +#ifndef __MINGW32__ +#define strncasecmp strnicmp +#define strcasecmp stricmp +#endif /* __MINGW32__ */ +#endif /* _MSC_VER */ + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#define LIBSSH2_DH_GEX_NEW 1 + +#endif /* LIBSSH2_CONFIG_H */ + diff --git a/include/libssh2/blf.h b/include/libssh2/blf.h new file mode 100644 index 0000000..5b7c8aa --- /dev/null +++ b/include/libssh2/blf.h @@ -0,0 +1,89 @@ +#ifndef __LIBSSH2_BLF_H +#define __LIBSSH2_BLF_H +/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */ +/* + * Blowfish - a fast block cipher designed by Bruce Schneier + * + * Copyright 1997 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) + +/* Schneier specifies a maximum key length of 56 bytes. + * This ensures that every key bit affects every cipher + * bit. However, the subkeys can hold up to 72 bytes. + * Warning: For normal blowfish encryption only 56 bytes + * of the key affect all cipherbits. + */ + +#define BLF_N 16 /* Number of Subkeys */ +#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ +#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */ + +/* Blowfish context */ +typedef struct BlowfishContext { + uint32_t S[4][256]; /* S-Boxes */ + uint32_t P[BLF_N + 2]; /* Subkeys */ +} blf_ctx; + +/* Raw access to customized Blowfish + * blf_key is just: + * Blowfish_initstate( state ) + * Blowfish_expand0state( state, key, keylen ) + */ + +void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *); +void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *); +void Blowfish_initstate(blf_ctx *); +void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t); +void Blowfish_expandstate +(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t); + +/* Standard Blowfish */ + +void blf_key(blf_ctx *, const uint8_t *, uint16_t); +void blf_enc(blf_ctx *, uint32_t *, uint16_t); +void blf_dec(blf_ctx *, uint32_t *, uint16_t); + +void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t); +void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t); + +void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t); +void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t); + +/* Converts uint8_t to uint32_t */ +uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *); + +/* bcrypt with pbkd */ +int bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, + size_t saltlen, + uint8_t *key, size_t keylen, unsigned int rounds); + +#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */ +#endif /* __LIBSSH2_BLF_H */ diff --git a/include/libssh2/channel.h b/include/libssh2/channel.h new file mode 100644 index 0000000..dc0ee37 --- /dev/null +++ b/include/libssh2/channel.h @@ -0,0 +1,141 @@ +#ifndef __LIBSSH2_CHANNEL_H +#define __LIBSSH2_CHANNEL_H +/* Copyright (c) 2008-2010 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* + * _libssh2_channel_receive_window_adjust + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Always non-blocking. + */ +int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + uint32_t adjustment, + unsigned char force, + unsigned int *store); + +/* + * _libssh2_channel_flush + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid); + +/* + * _libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +int _libssh2_channel_free(LIBSSH2_CHANNEL *channel); + +int +_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode); + +/* + * _libssh2_channel_write + * + * Send data to a channel + */ +ssize_t +_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, + const unsigned char *buf, size_t buflen); + +/* + * _libssh2_channel_open + * + * Establish a generic session channel + */ +LIBSSH2_CHANNEL * +_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, + uint32_t channel_type_len, + uint32_t window_size, + uint32_t packet_size, + const unsigned char *message, size_t message_len); + + +/* + * _libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +int +_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, size_t request_len, + const char *message, size_t message_len); + +/* + * _libssh2_channel_read + * + * Read data from a channel + * + * It is important to not return 0 until the currently read channel is + * complete. If we read stuff from the wire but it was no payload data to fill + * in the buffer with, we MUST make sure to return PACKET_EAGAIN. + */ +ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + char *buf, size_t buflen); + +uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session); + +LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session, + uint32_t channel_id); + +size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, + int stream_id); + +int _libssh2_channel_close(LIBSSH2_CHANNEL * channel); + +/* + * _libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); + +#endif /* __LIBSSH2_CHANNEL_H */ + diff --git a/include/libssh2/comp.h b/include/libssh2/comp.h new file mode 100644 index 0000000..82ac2dc --- /dev/null +++ b/include/libssh2/comp.h @@ -0,0 +1,44 @@ +#ifndef __LIBSSH2_COMP_H +#define __LIBSSH2_COMP_H +/* Copyright (C) 2009-2010 by Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session); + +#endif /* __LIBSSH2_COMP_H */ diff --git a/include/libssh2/crypto.h b/include/libssh2/crypto.h new file mode 100644 index 0000000..c36dde1 --- /dev/null +++ b/include/libssh2/crypto.h @@ -0,0 +1,248 @@ +#ifndef __LIBSSH2_CRYPTO_H +#define __LIBSSH2_CRYPTO_H +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2010-2019 Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifdef LIBSSH2_OPENSSL +#include "openssl.h" +#endif + +#ifdef LIBSSH2_LIBGCRYPT +#include "libgcrypt.h" +#endif + +#ifdef LIBSSH2_WINCNG +#include "wincng.h" +#endif + +#ifdef LIBSSH2_OS400QC3 +#include "os400qc3.h" +#endif + +#ifdef LIBSSH2_MBEDTLS +#include "mbedtls.h" +#endif + +#define LIBSSH2_ED25519_KEY_LEN 32 +#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64 +#define LIBSSH2_ED25519_SIG_LEN 64 + +#if LIBSSH2_RSA +int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen); +int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); +int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len); +int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +#endif + +#if LIBSSH2_DSA +int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *x, unsigned long x_len); +int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); +int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len); +int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig); +int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +#endif + +#if LIBSSH2_ECDSA +int +_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx, + const unsigned char *k, + size_t k_len, + libssh2_curve_type type); +int +_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase); + +int +_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx, + const unsigned char *r, size_t r_len, + const unsigned char *s, size_t s_len, + const unsigned char *m, size_t m_len); + +int +_libssh2_ecdsa_create_key(LIBSSH2_SESSION *session, + _libssh2_ec_key **out_private_key, + unsigned char **out_public_key_octal, + size_t *out_public_key_octal_len, + libssh2_curve_type curve_type); + +int +_libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key, + const unsigned char *server_public_key, + size_t server_public_key_len); + +int +_libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx, + const unsigned char *hash, unsigned long hash_len, + unsigned char **signature, size_t *signature_len); + +int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx, + LIBSSH2_SESSION * session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); + +libssh2_curve_type +_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx); + +int +_libssh2_ecdsa_curve_type_from_name(const char *name, + libssh2_curve_type *out_type); + +#endif /* LIBSSH2_ECDSA */ + +#if LIBSSH2_ED25519 + +int +_libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_ed25519_ctx **ctx, + uint8_t **out_public_key, uint8_t **out_private_key); + +int +_libssh2_curve25519_gen_k(_libssh2_bn **k, + uint8_t private_key[LIBSSH2_ED25519_KEY_LEN], + uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]); + +int +_libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s, + size_t s_len, const uint8_t *m, size_t m_len); + +int +_libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx, + LIBSSH2_SESSION *session, + const char *filename, const uint8_t *passphrase); + +int +_libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx, + LIBSSH2_SESSION *session, + const unsigned char *raw_pub_key, + const uint8_t key_len); + +int +_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session, + uint8_t **out_sig, size_t *out_sig_len, + const uint8_t *message, size_t message_len); + +int +_libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); + +#endif /* LIBSSH2_ED25519 */ + + +int _libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, int encrypt); + +int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize); + +int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); + +int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); + +#endif /* __LIBSSH2_CRYPTO_H */ diff --git a/include/libssh2/libgcrypt.h b/include/libssh2/libgcrypt.h new file mode 100644 index 0000000..92b48b8 --- /dev/null +++ b/include/libssh2/libgcrypt.h @@ -0,0 +1,237 @@ +#ifndef __LIBSSH2_LIBGCRYPT_H +#define __LIBSSH2_LIBGCRYPT_H +/* + * Copyright (C) 2008, 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007, The Written Word, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include + +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 1 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 1 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 1 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 1 +#define LIBSSH2_ECDSA 0 +#define LIBSSH2_ED25519 0 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) + +#define _libssh2_random(buf, len) \ + (gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 1) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + +#define libssh2_sha1_ctx gcry_md_hd_t + +/* returns 0 in case of failure */ +#define libssh2_sha1_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0)) +#define libssh2_sha1_update(ctx, data, len) \ + gcry_md_write(ctx, (unsigned char *) data, len) +#define libssh2_sha1_final(ctx, out) \ + memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx) +#define libssh2_sha1(message, len, out) \ + gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len) + +#define libssh2_sha256_ctx gcry_md_hd_t + +#define libssh2_sha256_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0)) +#define libssh2_sha256_update(ctx, data, len) \ + gcry_md_write(ctx, (unsigned char *) data, len) +#define libssh2_sha256_final(ctx, out) \ + memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx) +#define libssh2_sha256(message, len, out) \ + gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len) + +#define libssh2_sha384_ctx gcry_md_hd_t + +#define libssh2_sha384_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0)) +#define libssh2_sha384_update(ctx, data, len) \ + gcry_md_write(ctx, (unsigned char *) data, len) +#define libssh2_sha384_final(ctx, out) \ + memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx) +#define libssh2_sha384(message, len, out) \ + gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len) + +#define libssh2_sha512_ctx gcry_md_hd_t + +#define libssh2_sha512_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0)) +#define libssh2_sha512_update(ctx, data, len) \ + gcry_md_write(ctx, (unsigned char *) data, len) +#define libssh2_sha512_final(ctx, out) \ + memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx) +#define libssh2_sha512(message, len, out) \ + gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len) + +#define libssh2_md5_ctx gcry_md_hd_t + +/* returns 0 in case of failure */ +#define libssh2_md5_init(ctx) \ + (GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0)) + +#define libssh2_md5_update(ctx, data, len) \ + gcry_md_write(ctx, (unsigned char *) data, len) +#define libssh2_md5_final(ctx, out) \ + memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx) +#define libssh2_md5(message, len, out) \ + gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len) + +#define libssh2_hmac_ctx gcry_md_hd_t +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey(*ctx, key, keylen) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey(*ctx, key, keylen) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey(*ctx, key, keylen) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey(*ctx, key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \ + gcry_md_setkey(*ctx, key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + gcry_md_write(ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, data) \ + memcpy(data, gcry_md_read(ctx, 0), \ + gcry_md_get_algo_dlen(gcry_md_get_algo(ctx))) +#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx); + +#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM) +#define libssh2_crypto_exit() + +#define libssh2_rsa_ctx struct gcry_sexp + +#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx) + +#define libssh2_dsa_ctx struct gcry_sexp + +#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx) + +#if LIBSSH2_ECDSA +#else +#define _libssh2_ec_key void +#endif + +#define _libssh2_cipher_type(name) int name +#define _libssh2_cipher_ctx gcry_cipher_hd_t + +#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m) +#define _libssh2_gcry_cipher(c) (c >> 8) +#define _libssh2_gcry_mode(m) (m & 0xFF) + +#define _libssh2_cipher_aes256ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes192ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes128ctr \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR) +#define _libssh2_cipher_aes256 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_aes192 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_aes128 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_blowfish \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_arcfour \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM) +#define _libssh2_cipher_cast5 \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC) +#define _libssh2_cipher_3des \ + _libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC) + + +#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx)) + +#define _libssh2_bn struct gcry_mpi +#define _libssh2_bn_ctx int +#define _libssh2_bn_ctx_new() 0 +#define _libssh2_bn_ctx_free(bnctx) ((void)0) +#define _libssh2_bn_init() gcry_mpi_new(0) +#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a + new bignum */ +#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val) +#define _libssh2_bn_from_bin(bn, len, val) \ + gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL) +#define _libssh2_bn_to_bin(bn, val) \ + gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn) +#define _libssh2_bn_bytes(bn) \ + (gcry_mpi_get_nbits (bn) / 8 + \ + ((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1)) +#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn) +#define _libssh2_bn_free(bn) gcry_mpi_release(bn) + +#define _libssh2_dh_ctx struct gcry_mpi * +#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) +#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ + _libssh2_dh_key_pair(dhctx, public, g, p, group_order) +#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ + _libssh2_dh_secret(dhctx, secret, f, p) +#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) +extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx); +extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, + int group_order); +extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p); +extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); + +#endif /* __LIBSSH2_LIBGCRYPT_H */ diff --git a/include/libssh2/libssh2.h b/include/libssh2/libssh2.h new file mode 100644 index 0000000..386bcc8 --- /dev/null +++ b/include/libssh2/libssh2.h @@ -0,0 +1,1346 @@ +/* Copyright (c) 2004-2009, Sara Golemon + * Copyright (c) 2009-2015 Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef LIBSSH2_H +#define LIBSSH2_H 1 + +#define LIBSSH2_COPYRIGHT "2004-2019 The libssh2 project and its contributors." + +/* We use underscore instead of dash when appending DEV in dev versions just + to make the BANNER define (used by src/session.c) be a valid SSH + banner. Release versions have no appended strings and may of course not + have dashes either. */ +#define LIBSSH2_VERSION "1.9.0_DEV" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBSSH2_VERSION_MAJOR 1 +#define LIBSSH2_VERSION_MINOR 9 +#define LIBSSH2_VERSION_PATCH 0 + +/* This is the numeric version of the libssh2 version number, meant for easier + parsing and comparions by programs. The LIBSSH2_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. +*/ +#define LIBSSH2_VERSION_NUM 0x010900 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in the source code repo, as the timestamp is + * properly set in the tarballs by the maketgz script. + * + * The format of the date should follow this template: + * + * "Mon Feb 12 11:35:33 UTC 2007" + */ +#define LIBSSH2_TIMESTAMP "DEV" + +#ifndef RC_INVOKED + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef _WIN32 +# include +# include +#endif + +#include +#include +#include +#include + +/* Allow alternate API prefix from CFLAGS or calling app */ +#ifndef LIBSSH2_API +# ifdef LIBSSH2_WIN32 +# ifdef _WINDLL +# ifdef LIBSSH2_LIBRARY +# define LIBSSH2_API __declspec(dllexport) +# else +# define LIBSSH2_API __declspec(dllimport) +# endif /* LIBSSH2_LIBRARY */ +# else +# define LIBSSH2_API +# endif +# else /* !LIBSSH2_WIN32 */ +# define LIBSSH2_API +# endif /* LIBSSH2_WIN32 */ +#endif /* LIBSSH2_API */ + +#ifdef HAVE_SYS_UIO_H +# include +#endif + +#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) +# include +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned long long uint64_t; +typedef long long int64_t; +#endif + +#ifdef _MSC_VER +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +typedef unsigned __int64 libssh2_uint64_t; +typedef __int64 libssh2_int64_t; +#if (!defined(HAVE_SSIZE_T) && !defined(ssize_t)) +typedef SSIZE_T ssize_t; +#define HAVE_SSIZE_T +#endif +#else +#include +typedef unsigned long long libssh2_uint64_t; +typedef long long libssh2_int64_t; +#endif + +#ifdef WIN32 +typedef SOCKET libssh2_socket_t; +#define LIBSSH2_INVALID_SOCKET INVALID_SOCKET +#else /* !WIN32 */ +typedef int libssh2_socket_t; +#define LIBSSH2_INVALID_SOCKET -1 +#endif /* WIN32 */ + +/* + * Determine whether there is small or large file support on windows. + */ + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define LIBSSH2_USE_WIN32_LARGE_FILES +# else +# define LIBSSH2_USE_WIN32_SMALL_FILES +# endif +#endif + +#if defined(__MINGW32__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) +# define LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(__WATCOMC__) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) +# define LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(__POCC__) +# undef LIBSSH2_USE_WIN32_LARGE_FILES +#endif + +#if defined(_WIN32) && !defined(LIBSSH2_USE_WIN32_LARGE_FILES) && \ + !defined(LIBSSH2_USE_WIN32_SMALL_FILES) +# define LIBSSH2_USE_WIN32_SMALL_FILES +#endif + +/* + * Large file (>2Gb) support using WIN32 functions. + */ + +#ifdef LIBSSH2_USE_WIN32_LARGE_FILES +# include +# include +# include +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%I64d" +typedef struct _stati64 libssh2_struct_stat; +typedef __int64 libssh2_struct_stat_size; +#endif + +/* + * Small file (<2Gb) support using WIN32 functions. + */ + +#ifdef LIBSSH2_USE_WIN32_SMALL_FILES +# include +# include +# ifndef _WIN32_WCE +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" +typedef struct _stat libssh2_struct_stat; +typedef off_t libssh2_struct_stat_size; +# endif +#endif + +#ifndef LIBSSH2_STRUCT_STAT_SIZE_FORMAT +# ifdef __VMS +/* We have to roll our own format here because %z is a C99-ism we don't + have. */ +# if __USE_OFF64_T || __USING_STD_STAT +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%Ld" +# else +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%d" +# endif +# else +# define LIBSSH2_STRUCT_STAT_SIZE_FORMAT "%zd" +# endif +typedef struct stat libssh2_struct_stat; +typedef off_t libssh2_struct_stat_size; +#endif + +/* Part of every banner, user specified or not */ +#define LIBSSH2_SSH_BANNER "SSH-2.0-libssh2_" LIBSSH2_VERSION + +#define LIBSSH2_SSH_DEFAULT_BANNER LIBSSH2_SSH_BANNER +#define LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF LIBSSH2_SSH_DEFAULT_BANNER "\r\n" + +/* Default generate and safe prime sizes for + diffie-hellman-group-exchange-sha1 */ +#define LIBSSH2_DH_GEX_MINGROUP 1024 +#define LIBSSH2_DH_GEX_OPTGROUP 1536 +#define LIBSSH2_DH_GEX_MAXGROUP 2048 + +/* Defaults for pty requests */ +#define LIBSSH2_TERM_WIDTH 80 +#define LIBSSH2_TERM_HEIGHT 24 +#define LIBSSH2_TERM_WIDTH_PX 0 +#define LIBSSH2_TERM_HEIGHT_PX 0 + +/* 1/4 second */ +#define LIBSSH2_SOCKET_POLL_UDELAY 250000 +/* 0.25 * 120 == 30 seconds */ +#define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 + +/* Maximum size to allow a payload to compress to, plays it safe by falling + short of spec limits */ +#define LIBSSH2_PACKET_MAXCOMP 32000 + +/* Maximum size to allow a payload to deccompress to, plays it safe by + allowing more than spec requires */ +#define LIBSSH2_PACKET_MAXDECOMP 40000 + +/* Maximum size for an inbound compressed payload, plays it safe by + overshooting spec limits */ +#define LIBSSH2_PACKET_MAXPAYLOAD 40000 + +/* Malloc callbacks */ +#define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) +#define LIBSSH2_REALLOC_FUNC(name) void *name(void *ptr, size_t count, \ + void **abstract) +#define LIBSSH2_FREE_FUNC(name) void name(void *ptr, void **abstract) + +typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT +{ + char *text; + unsigned int length; + unsigned char echo; +} LIBSSH2_USERAUTH_KBDINT_PROMPT; + +typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE +{ + char *text; + unsigned int length; +} LIBSSH2_USERAUTH_KBDINT_RESPONSE; + +/* 'publickey' authentication callback */ +#define LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC(name) \ + int name(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, \ + const unsigned char *data, size_t data_len, void **abstract) + +/* 'keyboard-interactive' authentication callback */ +#define LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC(name_) \ + void name_(const char *name, int name_len, const char *instruction, \ + int instruction_len, int num_prompts, \ + const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, \ + LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses, void **abstract) + +/* Callbacks for special SSH packets */ +#define LIBSSH2_IGNORE_FUNC(name) \ + void name(LIBSSH2_SESSION *session, const char *message, int message_len, \ + void **abstract) + +#define LIBSSH2_DEBUG_FUNC(name) \ + void name(LIBSSH2_SESSION *session, int always_display, const char *message, \ + int message_len, const char *language, int language_len, \ + void **abstract) + +#define LIBSSH2_DISCONNECT_FUNC(name) \ + void name(LIBSSH2_SESSION *session, int reason, const char *message, \ + int message_len, const char *language, int language_len, \ + void **abstract) + +#define LIBSSH2_PASSWD_CHANGEREQ_FUNC(name) \ + void name(LIBSSH2_SESSION *session, char **newpw, int *newpw_len, \ + void **abstract) + +#define LIBSSH2_MACERROR_FUNC(name) \ + int name(LIBSSH2_SESSION *session, const char *packet, int packet_len, \ + void **abstract) + +#define LIBSSH2_X11_OPEN_FUNC(name) \ + void name(LIBSSH2_SESSION *session, LIBSSH2_CHANNEL *channel, \ + const char *shost, int sport, void **abstract) + +#define LIBSSH2_CHANNEL_CLOSE_FUNC(name) \ + void name(LIBSSH2_SESSION *session, void **session_abstract, \ + LIBSSH2_CHANNEL *channel, void **channel_abstract) + +/* I/O callbacks */ +#define LIBSSH2_RECV_FUNC(name) \ + ssize_t name(libssh2_socket_t socket, \ + void *buffer, size_t length, \ + int flags, void **abstract) +#define LIBSSH2_SEND_FUNC(name) \ + ssize_t name(libssh2_socket_t socket, \ + const void *buffer, size_t length, \ + int flags, void **abstract) + +/* libssh2_session_callback_set() constants */ +#define LIBSSH2_CALLBACK_IGNORE 0 +#define LIBSSH2_CALLBACK_DEBUG 1 +#define LIBSSH2_CALLBACK_DISCONNECT 2 +#define LIBSSH2_CALLBACK_MACERROR 3 +#define LIBSSH2_CALLBACK_X11 4 +#define LIBSSH2_CALLBACK_SEND 5 +#define LIBSSH2_CALLBACK_RECV 6 + +/* libssh2_session_method_pref() constants */ +#define LIBSSH2_METHOD_KEX 0 +#define LIBSSH2_METHOD_HOSTKEY 1 +#define LIBSSH2_METHOD_CRYPT_CS 2 +#define LIBSSH2_METHOD_CRYPT_SC 3 +#define LIBSSH2_METHOD_MAC_CS 4 +#define LIBSSH2_METHOD_MAC_SC 5 +#define LIBSSH2_METHOD_COMP_CS 6 +#define LIBSSH2_METHOD_COMP_SC 7 +#define LIBSSH2_METHOD_LANG_CS 8 +#define LIBSSH2_METHOD_LANG_SC 9 + +/* flags */ +#define LIBSSH2_FLAG_SIGPIPE 1 +#define LIBSSH2_FLAG_COMPRESS 2 + +typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; +typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; +typedef struct _LIBSSH2_LISTENER LIBSSH2_LISTENER; +typedef struct _LIBSSH2_KNOWNHOSTS LIBSSH2_KNOWNHOSTS; +typedef struct _LIBSSH2_AGENT LIBSSH2_AGENT; + +typedef struct _LIBSSH2_POLLFD { + unsigned char type; /* LIBSSH2_POLLFD_* below */ + + union { + libssh2_socket_t socket; /* File descriptors -- examined with + system select() call */ + LIBSSH2_CHANNEL *channel; /* Examined by checking internal state */ + LIBSSH2_LISTENER *listener; /* Read polls only -- are inbound + connections waiting to be accepted? */ + } fd; + + unsigned long events; /* Requested Events */ + unsigned long revents; /* Returned Events */ +} LIBSSH2_POLLFD; + +/* Poll FD Descriptor Types */ +#define LIBSSH2_POLLFD_SOCKET 1 +#define LIBSSH2_POLLFD_CHANNEL 2 +#define LIBSSH2_POLLFD_LISTENER 3 + +/* Note: Win32 Doesn't actually have a poll() implementation, so some of these + values are faked with select() data */ +/* Poll FD events/revents -- Match sys/poll.h where possible */ +#define LIBSSH2_POLLFD_POLLIN 0x0001 /* Data available to be read or + connection available -- + All */ +#define LIBSSH2_POLLFD_POLLPRI 0x0002 /* Priority data available to + be read -- Socket only */ +#define LIBSSH2_POLLFD_POLLEXT 0x0002 /* Extended data available to + be read -- Channel only */ +#define LIBSSH2_POLLFD_POLLOUT 0x0004 /* Can may be written -- + Socket/Channel */ +/* revents only */ +#define LIBSSH2_POLLFD_POLLERR 0x0008 /* Error Condition -- Socket */ +#define LIBSSH2_POLLFD_POLLHUP 0x0010 /* HangUp/EOF -- Socket */ +#define LIBSSH2_POLLFD_SESSION_CLOSED 0x0010 /* Session Disconnect */ +#define LIBSSH2_POLLFD_POLLNVAL 0x0020 /* Invalid request -- Socket + Only */ +#define LIBSSH2_POLLFD_POLLEX 0x0040 /* Exception Condition -- + Socket/Win32 */ +#define LIBSSH2_POLLFD_CHANNEL_CLOSED 0x0080 /* Channel Disconnect */ +#define LIBSSH2_POLLFD_LISTENER_CLOSED 0x0080 /* Listener Disconnect */ + +#define HAVE_LIBSSH2_SESSION_BLOCK_DIRECTION +/* Block Direction Types */ +#define LIBSSH2_SESSION_BLOCK_INBOUND 0x0001 +#define LIBSSH2_SESSION_BLOCK_OUTBOUND 0x0002 + +/* Hash Types */ +#define LIBSSH2_HOSTKEY_HASH_MD5 1 +#define LIBSSH2_HOSTKEY_HASH_SHA1 2 +#define LIBSSH2_HOSTKEY_HASH_SHA256 3 + +/* Hostkey Types */ +#define LIBSSH2_HOSTKEY_TYPE_UNKNOWN 0 +#define LIBSSH2_HOSTKEY_TYPE_RSA 1 +#define LIBSSH2_HOSTKEY_TYPE_DSS 2 +#define LIBSSH2_HOSTKEY_TYPE_ECDSA_256 3 +#define LIBSSH2_HOSTKEY_TYPE_ECDSA_384 4 +#define LIBSSH2_HOSTKEY_TYPE_ECDSA_521 5 +#define LIBSSH2_HOSTKEY_TYPE_ED25519 6 + +/* Disconnect Codes (defined by SSH protocol) */ +#define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1 +#define SSH_DISCONNECT_PROTOCOL_ERROR 2 +#define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3 +#define SSH_DISCONNECT_RESERVED 4 +#define SSH_DISCONNECT_MAC_ERROR 5 +#define SSH_DISCONNECT_COMPRESSION_ERROR 6 +#define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7 +#define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8 +#define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9 +#define SSH_DISCONNECT_CONNECTION_LOST 10 +#define SSH_DISCONNECT_BY_APPLICATION 11 +#define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12 +#define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13 +#define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14 +#define SSH_DISCONNECT_ILLEGAL_USER_NAME 15 + +/* Error Codes (defined by libssh2) */ +#define LIBSSH2_ERROR_NONE 0 + +/* The library once used -1 as a generic error return value on numerous places + through the code, which subsequently was converted to + LIBSSH2_ERROR_SOCKET_NONE uses over time. As this is a generic error code, + the goal is to never ever return this code but instead make sure that a + more accurate and descriptive error code is used. */ +#define LIBSSH2_ERROR_SOCKET_NONE -1 + +#define LIBSSH2_ERROR_BANNER_RECV -2 +#define LIBSSH2_ERROR_BANNER_SEND -3 +#define LIBSSH2_ERROR_INVALID_MAC -4 +#define LIBSSH2_ERROR_KEX_FAILURE -5 +#define LIBSSH2_ERROR_ALLOC -6 +#define LIBSSH2_ERROR_SOCKET_SEND -7 +#define LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE -8 +#define LIBSSH2_ERROR_TIMEOUT -9 +#define LIBSSH2_ERROR_HOSTKEY_INIT -10 +#define LIBSSH2_ERROR_HOSTKEY_SIGN -11 +#define LIBSSH2_ERROR_DECRYPT -12 +#define LIBSSH2_ERROR_SOCKET_DISCONNECT -13 +#define LIBSSH2_ERROR_PROTO -14 +#define LIBSSH2_ERROR_PASSWORD_EXPIRED -15 +#define LIBSSH2_ERROR_FILE -16 +#define LIBSSH2_ERROR_METHOD_NONE -17 +#define LIBSSH2_ERROR_AUTHENTICATION_FAILED -18 +#define LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED \ + LIBSSH2_ERROR_AUTHENTICATION_FAILED +#define LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED -19 +#define LIBSSH2_ERROR_CHANNEL_OUTOFORDER -20 +#define LIBSSH2_ERROR_CHANNEL_FAILURE -21 +#define LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED -22 +#define LIBSSH2_ERROR_CHANNEL_UNKNOWN -23 +#define LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED -24 +#define LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED -25 +#define LIBSSH2_ERROR_CHANNEL_CLOSED -26 +#define LIBSSH2_ERROR_CHANNEL_EOF_SENT -27 +#define LIBSSH2_ERROR_SCP_PROTOCOL -28 +#define LIBSSH2_ERROR_ZLIB -29 +#define LIBSSH2_ERROR_SOCKET_TIMEOUT -30 +#define LIBSSH2_ERROR_SFTP_PROTOCOL -31 +#define LIBSSH2_ERROR_REQUEST_DENIED -32 +#define LIBSSH2_ERROR_METHOD_NOT_SUPPORTED -33 +#define LIBSSH2_ERROR_INVAL -34 +#define LIBSSH2_ERROR_INVALID_POLL_TYPE -35 +#define LIBSSH2_ERROR_PUBLICKEY_PROTOCOL -36 +#define LIBSSH2_ERROR_EAGAIN -37 +#define LIBSSH2_ERROR_BUFFER_TOO_SMALL -38 +#define LIBSSH2_ERROR_BAD_USE -39 +#define LIBSSH2_ERROR_COMPRESS -40 +#define LIBSSH2_ERROR_OUT_OF_BOUNDARY -41 +#define LIBSSH2_ERROR_AGENT_PROTOCOL -42 +#define LIBSSH2_ERROR_SOCKET_RECV -43 +#define LIBSSH2_ERROR_ENCRYPT -44 +#define LIBSSH2_ERROR_BAD_SOCKET -45 +#define LIBSSH2_ERROR_KNOWN_HOSTS -46 +#define LIBSSH2_ERROR_CHANNEL_WINDOW_FULL -47 +#define LIBSSH2_ERROR_KEYFILE_AUTH_FAILED -48 + +/* this is a define to provide the old (<= 1.2.7) name */ +#define LIBSSH2_ERROR_BANNER_NONE LIBSSH2_ERROR_BANNER_RECV + +/* Global API */ +#define LIBSSH2_INIT_NO_CRYPTO 0x0001 + +/* + * libssh2_init() + * + * Initialize the libssh2 functions. This typically initialize the + * crypto library. It uses a global state, and is not thread safe -- + * you must make sure this function is not called concurrently. + * + * Flags can be: + * 0: Normal initialize + * LIBSSH2_INIT_NO_CRYPTO: Do not initialize the crypto library (ie. + * OPENSSL_add_cipher_algoritms() for OpenSSL + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int libssh2_init(int flags); + +/* + * libssh2_exit() + * + * Exit the libssh2 functions and free's all memory used internal. + */ +LIBSSH2_API void libssh2_exit(void); + +/* + * libssh2_free() + * + * Deallocate memory allocated by earlier call to libssh2 functions. + */ +LIBSSH2_API void libssh2_free(LIBSSH2_SESSION *session, void *ptr); + +/* + * libssh2_session_supported_algs() + * + * Fills algs with a list of supported acryptographic algorithms. Returns a + * non-negative number (number of supported algorithms) on success or a + * negative number (an error code) on failure. + * + * NOTE: on success, algs must be deallocated (by calling libssh2_free) when + * not needed anymore + */ +LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, + int method_type, + const char ***algs); + +/* Session API */ +LIBSSH2_API LIBSSH2_SESSION * +libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract); +#define libssh2_session_init() libssh2_session_init_ex(NULL, NULL, NULL, NULL) + +LIBSSH2_API void **libssh2_session_abstract(LIBSSH2_SESSION *session); + +LIBSSH2_API void *libssh2_session_callback_set(LIBSSH2_SESSION *session, + int cbtype, void *callback); +LIBSSH2_API int libssh2_session_banner_set(LIBSSH2_SESSION *session, + const char *banner); +LIBSSH2_API int libssh2_banner_set(LIBSSH2_SESSION *session, + const char *banner); + +LIBSSH2_API int libssh2_session_startup(LIBSSH2_SESSION *session, int sock); +LIBSSH2_API int libssh2_session_handshake(LIBSSH2_SESSION *session, + libssh2_socket_t sock); +LIBSSH2_API int libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, + int reason, + const char *description, + const char *lang); +#define libssh2_session_disconnect(session, description) \ + libssh2_session_disconnect_ex((session), SSH_DISCONNECT_BY_APPLICATION, \ + (description), "") + +LIBSSH2_API int libssh2_session_free(LIBSSH2_SESSION *session); + +LIBSSH2_API const char *libssh2_hostkey_hash(LIBSSH2_SESSION *session, + int hash_type); + +LIBSSH2_API const char *libssh2_session_hostkey(LIBSSH2_SESSION *session, + size_t *len, int *type); + +LIBSSH2_API int libssh2_session_method_pref(LIBSSH2_SESSION *session, + int method_type, + const char *prefs); +LIBSSH2_API const char *libssh2_session_methods(LIBSSH2_SESSION *session, + int method_type); +LIBSSH2_API int libssh2_session_last_error(LIBSSH2_SESSION *session, + char **errmsg, + int *errmsg_len, int want_buf); +LIBSSH2_API int libssh2_session_last_errno(LIBSSH2_SESSION *session); +LIBSSH2_API int libssh2_session_set_last_error(LIBSSH2_SESSION* session, + int errcode, + const char *errmsg); +LIBSSH2_API int libssh2_session_block_directions(LIBSSH2_SESSION *session); + +LIBSSH2_API int libssh2_session_flag(LIBSSH2_SESSION *session, int flag, + int value); +LIBSSH2_API const char *libssh2_session_banner_get(LIBSSH2_SESSION *session); + +/* Userauth API */ +LIBSSH2_API char *libssh2_userauth_list(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len); +LIBSSH2_API int libssh2_userauth_authenticated(LIBSSH2_SESSION *session); + +LIBSSH2_API int +libssh2_userauth_password_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *password, + unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC + ((*passwd_change_cb))); + +#define libssh2_userauth_password(session, username, password) \ + libssh2_userauth_password_ex((session), (username), \ + (unsigned int)strlen(username), \ + (password), (unsigned int)strlen(password), NULL) + +LIBSSH2_API int +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *publickey, + const char *privatekey, + const char *passphrase); + +#define libssh2_userauth_publickey_fromfile(session, username, publickey, \ + privatekey, passphrase) \ + libssh2_userauth_publickey_fromfile_ex((session), (username), \ + (unsigned int)strlen(username), \ + (publickey), \ + (privatekey), (passphrase)) + +LIBSSH2_API int +libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + const unsigned char *pubkeydata, + size_t pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC + ((*sign_callback)), + void **abstract); + +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *hostname, + unsigned int hostname_len, + const char *local_username, + unsigned int local_username_len); + +#define libssh2_userauth_hostbased_fromfile(session, username, publickey, \ + privatekey, passphrase, hostname) \ + libssh2_userauth_hostbased_fromfile_ex((session), (username), \ + (unsigned int)strlen(username), \ + (publickey), \ + (privatekey), (passphrase), \ + (hostname), \ + (unsigned int)strlen(hostname), \ + (username), \ + (unsigned int)strlen(username)) + +LIBSSH2_API int +libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickeyfiledata, + size_t publickeyfiledata_len, + const char *privatekeyfiledata, + size_t privatekeyfiledata_len, + const char *passphrase); + +/* + * response_callback is provided with filled by library prompts array, + * but client must allocate and fill individual responses. Responses + * array is already allocated. Responses data will be freed by libssh2 + * after callback return, but before subsequent callback invocation. + */ +LIBSSH2_API int +libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION* session, + const char *username, + unsigned int username_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC( + (*response_callback))); + +#define libssh2_userauth_keyboard_interactive(session, username, \ + response_callback) \ + libssh2_userauth_keyboard_interactive_ex((session), (username), \ + (unsigned int)strlen(username), \ + (response_callback)) + +LIBSSH2_API int libssh2_poll(LIBSSH2_POLLFD *fds, unsigned int nfds, + long timeout); + +/* Channel API */ +#define LIBSSH2_CHANNEL_WINDOW_DEFAULT (2*1024*1024) +#define LIBSSH2_CHANNEL_PACKET_DEFAULT 32768 +#define LIBSSH2_CHANNEL_MINADJUST 1024 + +/* Extended Data Handling */ +#define LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL 0 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE 1 +#define LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE 2 + +#define SSH_EXTENDED_DATA_STDERR 1 + +/* Returned by any function that would block during a read/write operation */ +#define LIBSSH2CHANNEL_EAGAIN LIBSSH2_ERROR_EAGAIN + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *channel_type, + unsigned int channel_type_len, + unsigned int window_size, unsigned int packet_size, + const char *message, unsigned int message_len); + +#define libssh2_channel_open_session(session) \ + libssh2_channel_open_ex((session), "session", sizeof("session") - 1, \ + LIBSSH2_CHANNEL_WINDOW_DEFAULT, \ + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0) + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, + int port, const char *shost, int sport); +#define libssh2_channel_direct_tcpip(session, host, port) \ + libssh2_channel_direct_tcpip_ex((session), (host), (port), "127.0.0.1", 22) + +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, + int port, int *bound_port, + int queue_maxsize); +#define libssh2_channel_forward_listen(session, port) \ + libssh2_channel_forward_listen_ex((session), NULL, (port), NULL, 16) + +LIBSSH2_API int libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener); + +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener); + +LIBSSH2_API int libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, + const char *varname, + unsigned int varname_len, + const char *value, + unsigned int value_len); + +#define libssh2_channel_setenv(channel, varname, value) \ + libssh2_channel_setenv_ex((channel), (varname), \ + (unsigned int)strlen(varname), (value), \ + (unsigned int)strlen(value)) + +LIBSSH2_API int libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel); + +LIBSSH2_API int libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, + const char *term, + unsigned int term_len, + const char *modes, + unsigned int modes_len, + int width, int height, + int width_px, int height_px); +#define libssh2_channel_request_pty(channel, term) \ + libssh2_channel_request_pty_ex((channel), (term), \ + (unsigned int)strlen(term), \ + NULL, 0, \ + LIBSSH2_TERM_WIDTH, \ + LIBSSH2_TERM_HEIGHT, \ + LIBSSH2_TERM_WIDTH_PX, \ + LIBSSH2_TERM_HEIGHT_PX) + +LIBSSH2_API int libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, + int width, int height, + int width_px, + int height_px); +#define libssh2_channel_request_pty_size(channel, width, height) \ + libssh2_channel_request_pty_size_ex((channel), (width), (height), 0, 0) + +LIBSSH2_API int libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, + int single_connection, + const char *auth_proto, + const char *auth_cookie, + int screen_number); +#define libssh2_channel_x11_req(channel, screen_number) \ + libssh2_channel_x11_req_ex((channel), 0, NULL, NULL, (screen_number)) + +LIBSSH2_API int libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, + unsigned int request_len, + const char *message, + unsigned int message_len); +#define libssh2_channel_shell(channel) \ + libssh2_channel_process_startup((channel), "shell", sizeof("shell") - 1, \ + NULL, 0) +#define libssh2_channel_exec(channel, command) \ + libssh2_channel_process_startup((channel), "exec", sizeof("exec") - 1, \ + (command), (unsigned int)strlen(command)) +#define libssh2_channel_subsystem(channel, subsystem) \ + libssh2_channel_process_startup((channel), "subsystem", \ + sizeof("subsystem") - 1, (subsystem), \ + (unsigned int)strlen(subsystem)) + +LIBSSH2_API ssize_t libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, + int stream_id, char *buf, + size_t buflen); +#define libssh2_channel_read(channel, buf, buflen) \ + libssh2_channel_read_ex((channel), 0, (buf), (buflen)) +#define libssh2_channel_read_stderr(channel, buf, buflen) \ + libssh2_channel_read_ex((channel), SSH_EXTENDED_DATA_STDERR, (buf), (buflen)) + +LIBSSH2_API int libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, + int extended); + +LIBSSH2_API unsigned long +libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, + unsigned long *read_avail, + unsigned long *window_size_initial); +#define libssh2_channel_window_read(channel) \ + libssh2_channel_window_read_ex((channel), NULL, NULL) + +/* libssh2_channel_receive_window_adjust is DEPRECATED, do not use! */ +LIBSSH2_API unsigned long +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, + unsigned long adjustment, + unsigned char force); + +LIBSSH2_API int +libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, + unsigned long adjustment, + unsigned char force, + unsigned int *storewindow); + +LIBSSH2_API ssize_t libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, + int stream_id, const char *buf, + size_t buflen); + +#define libssh2_channel_write(channel, buf, buflen) \ + libssh2_channel_write_ex((channel), 0, (buf), (buflen)) +#define libssh2_channel_write_stderr(channel, buf, buflen) \ + libssh2_channel_write_ex((channel), SSH_EXTENDED_DATA_STDERR, \ + (buf), (buflen)) + +LIBSSH2_API unsigned long +libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, + unsigned long *window_size_initial); +#define libssh2_channel_window_write(channel) \ + libssh2_channel_window_write_ex((channel), NULL) + +LIBSSH2_API void libssh2_session_set_blocking(LIBSSH2_SESSION* session, + int blocking); +LIBSSH2_API int libssh2_session_get_blocking(LIBSSH2_SESSION* session); + +LIBSSH2_API void libssh2_channel_set_blocking(LIBSSH2_CHANNEL *channel, + int blocking); + +LIBSSH2_API void libssh2_session_set_timeout(LIBSSH2_SESSION* session, + long timeout); +LIBSSH2_API long libssh2_session_get_timeout(LIBSSH2_SESSION* session); + +/* libssh2_channel_handle_extended_data is DEPRECATED, do not use! */ +LIBSSH2_API void libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, + int ignore_mode); +LIBSSH2_API int libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, + int ignore_mode); + +/* libssh2_channel_ignore_extended_data() is defined below for BC with version + * 0.1 + * + * Future uses should use libssh2_channel_handle_extended_data() directly if + * LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE is passed, extended data will be read + * (FIFO) from the standard data channel + */ +/* DEPRECATED */ +#define libssh2_channel_ignore_extended_data(channel, ignore) \ + libssh2_channel_handle_extended_data((channel), \ + (ignore) ? \ + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE : \ + LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL) + +#define LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA -1 +#define LIBSSH2_CHANNEL_FLUSH_ALL -2 +LIBSSH2_API int libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, + int streamid); +#define libssh2_channel_flush(channel) libssh2_channel_flush_ex((channel), 0) +#define libssh2_channel_flush_stderr(channel) \ + libssh2_channel_flush_ex((channel), SSH_EXTENDED_DATA_STDERR) + +LIBSSH2_API int libssh2_channel_get_exit_status(LIBSSH2_CHANNEL* channel); +LIBSSH2_API int libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL* channel, + char **exitsignal, + size_t *exitsignal_len, + char **errmsg, + size_t *errmsg_len, + char **langtag, + size_t *langtag_len); +LIBSSH2_API int libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_close(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel); +LIBSSH2_API int libssh2_channel_free(LIBSSH2_CHANNEL *channel); + +/* libssh2_scp_recv is DEPRECATED, do not use! */ +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv(LIBSSH2_SESSION *session, + const char *path, + struct stat *sb); +/* Use libssh2_scp_recv2 for large (> 2GB) file support on windows */ +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_recv2(LIBSSH2_SESSION *session, + const char *path, + libssh2_struct_stat *sb); +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_scp_send_ex(LIBSSH2_SESSION *session, + const char *path, int mode, + size_t size, long mtime, + long atime); +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime); + +#define libssh2_scp_send(session, path, mode, size) \ + libssh2_scp_send_ex((session), (path), (mode), (size), 0, 0) + +LIBSSH2_API int libssh2_base64_decode(LIBSSH2_SESSION *session, char **dest, + unsigned int *dest_len, + const char *src, unsigned int src_len); + +LIBSSH2_API +const char *libssh2_version(int req_version_num); + +#define HAVE_LIBSSH2_KNOWNHOST_API 0x010101 /* since 1.1.1 */ +#define HAVE_LIBSSH2_VERSION_API 0x010100 /* libssh2_version since 1.1 */ + +struct libssh2_knownhost { + unsigned int magic; /* magic stored by the library */ + void *node; /* handle to the internal representation of this host */ + char *name; /* this is NULL if no plain text host name exists */ + char *key; /* key in base64/printable format */ + int typemask; +}; + +/* + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + * + */ +LIBSSH2_API LIBSSH2_KNOWNHOSTS * +libssh2_knownhost_init(LIBSSH2_SESSION *session); + +/* + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +/* host format (2 bits) */ +#define LIBSSH2_KNOWNHOST_TYPE_MASK 0xffff +#define LIBSSH2_KNOWNHOST_TYPE_PLAIN 1 +#define LIBSSH2_KNOWNHOST_TYPE_SHA1 2 /* always base64 encoded */ +#define LIBSSH2_KNOWNHOST_TYPE_CUSTOM 3 + +/* key format (2 bits) */ +#define LIBSSH2_KNOWNHOST_KEYENC_MASK (3<<16) +#define LIBSSH2_KNOWNHOST_KEYENC_RAW (1<<16) +#define LIBSSH2_KNOWNHOST_KEYENC_BASE64 (2<<16) + +/* type of key (4 bits) */ +#define LIBSSH2_KNOWNHOST_KEY_MASK (15<<18) +#define LIBSSH2_KNOWNHOST_KEY_SHIFT 18 +#define LIBSSH2_KNOWNHOST_KEY_RSA1 (1<<18) +#define LIBSSH2_KNOWNHOST_KEY_SSHRSA (2<<18) +#define LIBSSH2_KNOWNHOST_KEY_SSHDSS (3<<18) +#define LIBSSH2_KNOWNHOST_KEY_ECDSA_256 (4<<18) +#define LIBSSH2_KNOWNHOST_KEY_ECDSA_384 (5<<18) +#define LIBSSH2_KNOWNHOST_KEY_ECDSA_521 (6<<18) +#define LIBSSH2_KNOWNHOST_KEY_ED25519 (7<<18) +#define LIBSSH2_KNOWNHOST_KEY_UNKNOWN (15<<18) + +LIBSSH2_API int +libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, + const char *salt, + const char *key, size_t keylen, int typemask, + struct libssh2_knownhost **store); + +/* + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the key. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, + const char *salt, + const char *key, size_t keylen, + const char *comment, size_t commentlen, int typemask, + struct libssh2_knownhost **store); + +/* + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The type is the type/format of the given host name. + * + * plain - ascii "hostname.domain.tld" + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * + * 'knownhost' may be set to NULL if you don't care about that info. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_* values, see below + * + */ + +#define LIBSSH2_KNOWNHOST_CHECK_MATCH 0 +#define LIBSSH2_KNOWNHOST_CHECK_MISMATCH 1 +#define LIBSSH2_KNOWNHOST_CHECK_NOTFOUND 2 +#define LIBSSH2_KNOWNHOST_CHECK_FAILURE 3 + +LIBSSH2_API int +libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **knownhost); + +/* this function is identital to the above one, but also takes a port + argument that allows libssh2 to do a better check */ +LIBSSH2_API int +libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **knownhost); + +/* + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. The 'entry' struct is + * retrieved by a call to libssh2_knownhost_check(). + * + */ +LIBSSH2_API int +libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *entry); + +/* + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + * + */ +LIBSSH2_API void +libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts); + +/* + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. It makes libssh2 read this line. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + * + */ +LIBSSH2_API int +libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, + const char *line, size_t len, int type); + +/* + * libssh2_knownhost_readfile + * + * Add hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added hosts. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + */ + +#define LIBSSH2_KNOWNHOST_FILE_OPENSSH 1 + +LIBSSH2_API int +libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type); + +/* + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + * + */ +LIBSSH2_API int +libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *known, + char *buffer, size_t buflen, + size_t *outlen, /* the amount of written data */ + int type); + +/* + * libssh2_knownhost_writefile + * + * Write hosts+key pairs to a given file. + * + * This implementation currently only knows one 'type' (openssh), all others + * are reserved for future use. + */ + +LIBSSH2_API int +libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type); + +/* + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. Or pass a pointer to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + */ +LIBSSH2_API int +libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost **store, + struct libssh2_knownhost *prev); + +#define HAVE_LIBSSH2_AGENT_API 0x010202 /* since 1.2.2 */ + +struct libssh2_agent_publickey { + unsigned int magic; /* magic stored by the library */ + void *node; /* handle to the internal representation of key */ + unsigned char *blob; /* public key blob */ + size_t blob_len; /* length of the public key blob */ + char *comment; /* comment in printable format */ +}; + +/* + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + * + */ +LIBSSH2_API LIBSSH2_AGENT * +libssh2_agent_init(LIBSSH2_SESSION *session); + +/* + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_connect(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_list_identities() + * + * Request an ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_list_identities(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a pointer to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + */ +LIBSSH2_API int +libssh2_agent_get_identity(LIBSSH2_AGENT *agent, + struct libssh2_agent_publickey **store, + struct libssh2_agent_publickey *prev); + +/* + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_userauth(LIBSSH2_AGENT *agent, + const char *username, + struct libssh2_agent_publickey *identity); + +/* + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_disconnect(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + */ +LIBSSH2_API void +libssh2_agent_free(LIBSSH2_AGENT *agent); + +/* + * libssh2_agent_set_identity_path() + * + * Allows a custom agent identity socket path beyond SSH_AUTH_SOCK env + * + */ +LIBSSH2_API void +libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, + const char *path); + +/* + * libssh2_agent_get_identity_path() + * + * Returns the custom agent identity socket path if set + * + */ +LIBSSH2_API const char * +libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent); + +/* + * libssh2_keepalive_config() + * + * Set how often keepalive messages should be sent. WANT_REPLY + * indicates whether the keepalive messages should request a response + * from the server. INTERVAL is number of seconds that can pass + * without any I/O, use 0 (the default) to disable keepalives. To + * avoid some busy-loop corner-cases, if you specify an interval of 1 + * it will be treated as 2. + * + * Note that non-blocking applications are responsible for sending the + * keepalive messages using libssh2_keepalive_send(). + */ +LIBSSH2_API void libssh2_keepalive_config(LIBSSH2_SESSION *session, + int want_reply, + unsigned interval); + +/* + * libssh2_keepalive_send() + * + * Send a keepalive message if needed. SECONDS_TO_NEXT indicates how + * many seconds you can sleep after this call before you need to call + * it again. Returns 0 on success, or LIBSSH2_ERROR_SOCKET_SEND on + * I/O errors. + */ +LIBSSH2_API int libssh2_keepalive_send(LIBSSH2_SESSION *session, + int *seconds_to_next); + +/* NOTE NOTE NOTE + libssh2_trace() has no function in builds that aren't built with debug + enabled + */ +LIBSSH2_API int libssh2_trace(LIBSSH2_SESSION *session, int bitmask); +#define LIBSSH2_TRACE_TRANS (1<<1) +#define LIBSSH2_TRACE_KEX (1<<2) +#define LIBSSH2_TRACE_AUTH (1<<3) +#define LIBSSH2_TRACE_CONN (1<<4) +#define LIBSSH2_TRACE_SCP (1<<5) +#define LIBSSH2_TRACE_SFTP (1<<6) +#define LIBSSH2_TRACE_ERROR (1<<7) +#define LIBSSH2_TRACE_PUBLICKEY (1<<8) +#define LIBSSH2_TRACE_SOCKET (1<<9) + +typedef void (*libssh2_trace_handler_func)(LIBSSH2_SESSION*, + void *, + const char *, + size_t); +LIBSSH2_API int libssh2_trace_sethandler(LIBSSH2_SESSION *session, + void *context, + libssh2_trace_handler_func callback); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* !RC_INVOKED */ + +#endif /* LIBSSH2_H */ diff --git a/include/libssh2/libssh2_config.h b/include/libssh2/libssh2_config.h new file mode 100644 index 0000000..6ac2ef4 --- /dev/null +++ b/include/libssh2/libssh2_config.h @@ -0,0 +1,47 @@ +#ifndef LIBSSH2_CONFIG_H +#define LIBSSH2_CONFIG_H + +#ifndef WIN32 +#define WIN32 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif /* _CRT_SECURE_NO_DEPRECATE */ +#include +#include +#include + +#ifdef __MINGW32__ +#define HAVE_UNISTD_H +#define HAVE_INTTYPES_H +#define HAVE_SYS_TIME_H +#define HAVE_GETTIMEOFDAY +#endif /* __MINGW32__ */ + +#define HAVE_LIBCRYPT32 +#define HAVE_WINSOCK2_H +#define HAVE_IOCTLSOCKET +#define HAVE_SELECT + +#ifdef _MSC_VER +#if _MSC_VER < 1900 +#define snprintf _snprintf +#if _MSC_VER < 1500 +#define vsnprintf _vsnprintf +#endif +#define strdup _strdup +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif +#else +#ifndef __MINGW32__ +#define strncasecmp strnicmp +#define strcasecmp stricmp +#endif /* __MINGW32__ */ +#endif /* _MSC_VER */ + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#define LIBSSH2_DH_GEX_NEW 1 + +#endif /* LIBSSH2_CONFIG_H */ + diff --git a/include/libssh2/libssh2_config.h.in b/include/libssh2/libssh2_config.h.in new file mode 100644 index 0000000..6a52f0c --- /dev/null +++ b/include/libssh2/libssh2_config.h.in @@ -0,0 +1,223 @@ +/* src/libssh2_config.h.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARPA_INET_H + +/* disabled non-blocking sockets */ +#undef HAVE_DISABLED_NONBLOCKING + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `EVP_aes_128_ctr' function. */ +#undef HAVE_EVP_AES_128_CTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* use FIONBIO for non-blocking sockets */ +#undef HAVE_FIONBIO + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* use ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET + +/* use Ioctlsocket() for non-blocking sockets */ +#undef HAVE_IOCTLSOCKET_CASE + +/* Define if you have the gcrypt library. */ +#undef HAVE_LIBGCRYPT + +/* Define if you have the ssl library. */ +#undef HAVE_LIBSSL + +/* Define if you have the z library. */ +#undef HAVE_LIBZ + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#undef HAVE_LONGLONG + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* use O_NONBLOCK for non-blocking sockets */ +#undef HAVE_O_NONBLOCK + +/* Define to 1 if you have the `poll' function. */ +#undef HAVE_POLL + +/* Define to 1 if you have the select function. */ +#undef HAVE_SELECT + +/* use SO_NONBLOCK for non-blocking sockets */ +#undef HAVE_SO_NONBLOCK + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtoll' function. */ +#undef HAVE_STRTOLL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINDOWS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WINSOCK2_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WS2TCPIP_H + +/* to make a symbol visible */ +#undef LIBSSH2_API + +/* Enable "none" cipher -- NOT RECOMMENDED */ +#undef LIBSSH2_CRYPT_NONE + +/* Enable newer diffie-hellman-group-exchange-sha1 syntax */ +#undef LIBSSH2_DH_GEX_NEW + +/* Compile in zlib support */ +#undef LIBSSH2_HAVE_ZLIB + +/* Use libgcrypt */ +#undef LIBSSH2_LIBGCRYPT + +/* Enable "none" MAC -- NOT RECOMMENDED */ +#undef LIBSSH2_MAC_NONE + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */ +#undef NEED_REENTRANT + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif diff --git a/include/libssh2/libssh2_priv.h b/include/libssh2/libssh2_priv.h new file mode 100644 index 0000000..474698e --- /dev/null +++ b/include/libssh2/libssh2_priv.h @@ -0,0 +1,1149 @@ +#ifndef __LIBSSH2_PRIV_H +#define __LIBSSH2_PRIV_H +/* Copyright (c) 2004-2008, 2010, Sara Golemon + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#define LIBSSH2_LIBRARY +#include "libssh2_config.h" + +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#undef WIN32_LEAN_AND_MEAN +#endif + +#ifdef HAVE_WS2TCPIP_H +#include +#endif + +#include +#include + +/* The following CPP block should really only be in session.c and packet.c. + However, AIX have #define's for 'events' and 'revents' and we are using + those names in libssh2.h, so we need to include the AIX headers first, to + make sure all code is compiled with consistent names of these fields. + While arguable the best would to change libssh2.h to use other names, that + would break backwards compatibility. +*/ +#ifdef HAVE_POLL +# include +#else +# if defined(HAVE_SELECT) && !defined(WIN32) +# ifdef HAVE_SYS_SELECT_H +# include +# else +# include +# include +# endif +# endif +#endif + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#ifdef HAVE_SYS_SOCKET_H +# include +#endif +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_INTTYPES_H +#include +#endif + +#include "libssh2.h" +#include "libssh2_publickey.h" +#include "libssh2_sftp.h" +#include "misc.h" /* for the linked list stuff */ + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#ifdef _MSC_VER +/* "inline" keyword is valid only with C++ engine! */ +#define inline __inline +#endif + +/* Provide iovec / writev on WIN32 platform. */ +#ifdef WIN32 + +struct iovec { + size_t iov_len; + void *iov_base; +}; + +static inline int writev(int sock, struct iovec *iov, int nvecs) +{ + DWORD ret; + if(WSASend(sock, (LPWSABUF)iov, nvecs, &ret, 0, NULL, NULL) == 0) { + return ret; + } + return -1; +} + +#endif /* WIN32 */ + +#ifdef __OS400__ +/* Force parameter type. */ +#define send(s, b, l, f) send((s), (unsigned char *) (b), (l), (f)) +#endif + +#include "crypto.h" + +#ifdef HAVE_WINSOCK2_H + +#include +#include + +#endif + +#ifndef SIZE_MAX +#if _WIN64 +#define SIZE_MAX 0xFFFFFFFFFFFFFFFF +#else +#define SIZE_MAX 0xFFFFFFFF +#endif +#endif + +#ifndef UINT_MAX +#define UINT_MAX 0xFFFFFFFF +#endif + +/* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process packets with + * uncompressed payload length of 32768 bytes or less and + * total packet size of 35000 bytes or less (including length, + * padding length, payload, padding, and MAC.)." + */ +#define MAX_SSH_PACKET_LEN 35000 +#define MAX_SHA_DIGEST_LEN SHA512_DIGEST_LENGTH + +#define LIBSSH2_ALLOC(session, count) \ + session->alloc((count), &(session)->abstract) +#define LIBSSH2_CALLOC(session, count) _libssh2_calloc(session, count) +#define LIBSSH2_REALLOC(session, ptr, count) \ + ((ptr) ? session->realloc((ptr), (count), &(session)->abstract) : \ + session->alloc((count), &(session)->abstract)) +#define LIBSSH2_FREE(session, ptr) \ + session->free((ptr), &(session)->abstract) +#define LIBSSH2_IGNORE(session, data, datalen) \ + session->ssh_msg_ignore((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_DEBUG(session, always_display, message, message_len, \ + language, language_len) \ + session->ssh_msg_debug((session), (always_display), (message), \ + (message_len), (language), (language_len), \ + &(session)->abstract) +#define LIBSSH2_DISCONNECT(session, reason, message, message_len, \ + language, language_len) \ + session->ssh_msg_disconnect((session), (reason), (message), \ + (message_len), (language), (language_len), \ + &(session)->abstract) + +#define LIBSSH2_MACERROR(session, data, datalen) \ + session->macerror((session), (data), (datalen), &(session)->abstract) +#define LIBSSH2_X11_OPEN(channel, shost, sport) \ + channel->session->x11(((channel)->session), (channel), \ + (shost), (sport), (&(channel)->session->abstract)) + +#define LIBSSH2_CHANNEL_CLOSE(session, channel) \ + channel->close_cb((session), &(session)->abstract, \ + (channel), &(channel)->abstract) + +#define LIBSSH2_SEND_FD(session, fd, buffer, length, flags) \ + (session->send)(fd, buffer, length, flags, &session->abstract) +#define LIBSSH2_RECV_FD(session, fd, buffer, length, flags) \ + (session->recv)(fd, buffer, length, flags, &session->abstract) + +#define LIBSSH2_SEND(session, buffer, length, flags) \ + LIBSSH2_SEND_FD(session, session->socket_fd, buffer, length, flags) +#define LIBSSH2_RECV(session, buffer, length, flags) \ + LIBSSH2_RECV_FD(session, session->socket_fd, buffer, length, flags) + +typedef struct _LIBSSH2_KEX_METHOD LIBSSH2_KEX_METHOD; +typedef struct _LIBSSH2_HOSTKEY_METHOD LIBSSH2_HOSTKEY_METHOD; +typedef struct _LIBSSH2_CRYPT_METHOD LIBSSH2_CRYPT_METHOD; +typedef struct _LIBSSH2_COMP_METHOD LIBSSH2_COMP_METHOD; + +typedef struct _LIBSSH2_PACKET LIBSSH2_PACKET; + +typedef enum +{ + libssh2_NB_state_idle = 0, + libssh2_NB_state_allocated, + libssh2_NB_state_created, + libssh2_NB_state_sent, + libssh2_NB_state_sent1, + libssh2_NB_state_sent2, + libssh2_NB_state_sent3, + libssh2_NB_state_sent4, + libssh2_NB_state_sent5, + libssh2_NB_state_sent6, + libssh2_NB_state_sent7, + libssh2_NB_state_jump1, + libssh2_NB_state_jump2, + libssh2_NB_state_jump3, + libssh2_NB_state_jump4, + libssh2_NB_state_jump5, + libssh2_NB_state_end +} libssh2_nonblocking_states; + +typedef struct packet_require_state_t +{ + libssh2_nonblocking_states state; + time_t start; +} packet_require_state_t; + +typedef struct packet_requirev_state_t +{ + time_t start; +} packet_requirev_state_t; + +typedef struct kmdhgGPshakex_state_t +{ + libssh2_nonblocking_states state; + unsigned char *e_packet; + unsigned char *s_packet; + unsigned char *tmp; + unsigned char h_sig_comp[MAX_SHA_DIGEST_LEN]; + unsigned char c; + size_t e_packet_len; + size_t s_packet_len; + size_t tmp_len; + _libssh2_bn_ctx *ctx; + _libssh2_dh_ctx x; + _libssh2_bn *e; + _libssh2_bn *f; + _libssh2_bn *k; + unsigned char *f_value; + unsigned char *k_value; + unsigned char *h_sig; + size_t f_value_len; + size_t k_value_len; + size_t h_sig_len; + void *exchange_hash; + packet_require_state_t req_state; + libssh2_nonblocking_states burn_state; +} kmdhgGPshakex_state_t; + +typedef struct key_exchange_state_low_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + kmdhgGPshakex_state_t exchange_state; + _libssh2_bn *p; /* SSH2 defined value (p_value) */ + _libssh2_bn *g; /* SSH2 defined value (2) */ + unsigned char request[256]; /* Must fit EC_MAX_POINT_LEN + data */ + unsigned char *data; + size_t request_len; + size_t data_len; + _libssh2_ec_key *private_key; /* SSH2 ecdh private key */ + unsigned char *public_key_oct; /* SSH2 ecdh public key octal value */ + size_t public_key_oct_len; /* SSH2 ecdh public key octal value + length */ + unsigned char *curve25519_public_key; /* curve25519 public key, 32 + bytes */ + unsigned char *curve25519_private_key; /* curve25519 private key, 32 + bytes */ +} key_exchange_state_low_t; + +typedef struct key_exchange_state_t +{ + libssh2_nonblocking_states state; + packet_require_state_t req_state; + key_exchange_state_low_t key_state_low; + unsigned char *data; + size_t data_len; + unsigned char *oldlocal; + size_t oldlocal_len; +} key_exchange_state_t; + +#define FwdNotReq "Forward not requested" + +typedef struct packet_queue_listener_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(FwdNotReq) - 1)]; + unsigned char *host; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t port; + uint32_t sport; + uint32_t host_len; + uint32_t shost_len; + LIBSSH2_CHANNEL *channel; +} packet_queue_listener_state_t; + +#define X11FwdUnAvil "X11 Forward Unavailable" + +typedef struct packet_x11_open_state_t +{ + libssh2_nonblocking_states state; + unsigned char packet[17 + (sizeof(X11FwdUnAvil) - 1)]; + unsigned char *shost; + uint32_t sender_channel; + uint32_t initial_window_size; + uint32_t packet_size; + uint32_t sport; + uint32_t shost_len; + LIBSSH2_CHANNEL *channel; +} packet_x11_open_state_t; + +struct _LIBSSH2_PACKET +{ + struct list_node node; /* linked list header */ + + /* the raw unencrypted payload */ + unsigned char *data; + size_t data_len; + + /* Where to start reading data from, + * used for channel data that's been partially consumed */ + size_t data_head; +}; + +typedef struct _libssh2_channel_data +{ + /* Identifier */ + uint32_t id; + + /* Limits and restrictions */ + uint32_t window_size_initial, window_size, packet_size; + + /* Set to 1 when CHANNEL_CLOSE / CHANNEL_EOF sent/received */ + char close, eof, extended_data_ignore_mode; +} libssh2_channel_data; + +struct _LIBSSH2_CHANNEL +{ + struct list_node node; + + unsigned char *channel_type; + unsigned channel_type_len; + + /* channel's program exit status */ + int exit_status; + + /* channel's program exit signal (without the SIG prefix) */ + char *exit_signal; + + libssh2_channel_data local, remote; + /* Amount of bytes to be refunded to receive window (but not yet sent) */ + uint32_t adjust_queue; + /* Data immediately available for reading */ + uint32_t read_avail; + + LIBSSH2_SESSION *session; + + void *abstract; + LIBSSH2_CHANNEL_CLOSE_FUNC((*close_cb)); + + /* State variables used in libssh2_channel_setenv_ex() */ + libssh2_nonblocking_states setenv_state; + unsigned char *setenv_packet; + size_t setenv_packet_len; + unsigned char setenv_local_channel[4]; + packet_requirev_state_t setenv_packet_requirev_state; + + /* State variables used in libssh2_channel_request_pty_ex() + libssh2_channel_request_pty_size_ex() */ + libssh2_nonblocking_states reqPTY_state; + unsigned char reqPTY_packet[41 + 256]; + size_t reqPTY_packet_len; + unsigned char reqPTY_local_channel[4]; + packet_requirev_state_t reqPTY_packet_requirev_state; + + /* State variables used in libssh2_channel_x11_req_ex() */ + libssh2_nonblocking_states reqX11_state; + unsigned char *reqX11_packet; + size_t reqX11_packet_len; + unsigned char reqX11_local_channel[4]; + packet_requirev_state_t reqX11_packet_requirev_state; + + /* State variables used in libssh2_channel_process_startup() */ + libssh2_nonblocking_states process_state; + unsigned char *process_packet; + size_t process_packet_len; + unsigned char process_local_channel[4]; + packet_requirev_state_t process_packet_requirev_state; + + /* State variables used in libssh2_channel_flush_ex() */ + libssh2_nonblocking_states flush_state; + size_t flush_refund_bytes; + size_t flush_flush_bytes; + + /* State variables used in libssh2_channel_receive_window_adjust() */ + libssh2_nonblocking_states adjust_state; + unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) + + adjustment(4) */ + + /* State variables used in libssh2_channel_read_ex() */ + libssh2_nonblocking_states read_state; + + uint32_t read_local_id; + + /* State variables used in libssh2_channel_write_ex() */ + libssh2_nonblocking_states write_state; + unsigned char write_packet[13]; + size_t write_packet_len; + size_t write_bufwrite; + + /* State variables used in libssh2_channel_close() */ + libssh2_nonblocking_states close_state; + unsigned char close_packet[5]; + + /* State variables used in libssh2_channel_wait_closedeof() */ + libssh2_nonblocking_states wait_eof_state; + + /* State variables used in libssh2_channel_wait_closed() */ + libssh2_nonblocking_states wait_closed_state; + + /* State variables used in libssh2_channel_free() */ + libssh2_nonblocking_states free_state; + + /* State variables used in libssh2_channel_handle_extended_data2() */ + libssh2_nonblocking_states extData2_state; + + /* State variables used in libssh2_channel_request_auth_agent() */ + libssh2_nonblocking_states req_auth_agent_try_state; + libssh2_nonblocking_states req_auth_agent_state; + unsigned char req_auth_agent_packet[36]; + size_t req_auth_agent_packet_len; + unsigned char req_auth_agent_local_channel[4]; + packet_requirev_state_t req_auth_agent_requirev_state; +}; + +struct _LIBSSH2_LISTENER +{ + struct list_node node; /* linked list header */ + + LIBSSH2_SESSION *session; + + char *host; + int port; + + /* a list of CHANNELs for this listener */ + struct list_head queue; + + int queue_size; + int queue_maxsize; + + /* State variables used in libssh2_channel_forward_cancel() */ + libssh2_nonblocking_states chanFwdCncl_state; + unsigned char *chanFwdCncl_data; + size_t chanFwdCncl_data_len; +}; + +typedef struct _libssh2_endpoint_data +{ + unsigned char *banner; + + unsigned char *kexinit; + size_t kexinit_len; + + const LIBSSH2_CRYPT_METHOD *crypt; + void *crypt_abstract; + + const struct _LIBSSH2_MAC_METHOD *mac; + uint32_t seqno; + void *mac_abstract; + + const LIBSSH2_COMP_METHOD *comp; + void *comp_abstract; + + /* Method Preferences -- NULL yields "load order" */ + char *crypt_prefs; + char *mac_prefs; + char *comp_prefs; + char *lang_prefs; +} libssh2_endpoint_data; + +#define PACKETBUFSIZE (1024*16) + +struct transportpacket +{ + /* ------------- for incoming data --------------- */ + unsigned char buf[PACKETBUFSIZE]; + unsigned char init[5]; /* first 5 bytes of the incoming data stream, + still encrypted */ + size_t writeidx; /* at what array index we do the next write into + the buffer */ + size_t readidx; /* at what array index we do the next read from + the buffer */ + uint32_t packet_length; /* the most recent packet_length as read from the + network data */ + uint8_t padding_length; /* the most recent padding_length as read from the + network data */ + size_t data_num; /* How much of the total package that has been read + so far. */ + size_t total_num; /* How much a total package is supposed to be, in + number of bytes. A full package is + packet_length + padding_length + 4 + + mac_length. */ + unsigned char *payload; /* this is a pointer to a LIBSSH2_ALLOC() + area to which we write decrypted data */ + unsigned char *wptr; /* write pointer into the payload to where we + are currently writing decrypted data */ + + /* ------------- for outgoing data --------------- */ + unsigned char outbuf[MAX_SSH_PACKET_LEN]; /* area for the outgoing data */ + + int ototal_num; /* size of outbuf in number of bytes */ + const unsigned char *odata; /* original pointer to the data */ + size_t olen; /* original size of the data we stored in + outbuf */ + size_t osent; /* number of bytes already sent */ +}; + +struct _LIBSSH2_PUBLICKEY +{ + LIBSSH2_CHANNEL *channel; + uint32_t version; + + /* State variables used in libssh2_publickey_packet_receive() */ + libssh2_nonblocking_states receive_state; + unsigned char *receive_packet; + size_t receive_packet_len; + + /* State variables used in libssh2_publickey_add_ex() */ + libssh2_nonblocking_states add_state; + unsigned char *add_packet; + unsigned char *add_s; + + /* State variables used in libssh2_publickey_remove_ex() */ + libssh2_nonblocking_states remove_state; + unsigned char *remove_packet; + unsigned char *remove_s; + + /* State variables used in libssh2_publickey_list_fetch() */ + libssh2_nonblocking_states listFetch_state; + unsigned char *listFetch_s; + unsigned char listFetch_buffer[12]; + unsigned char *listFetch_data; + size_t listFetch_data_len; +}; + +#define LIBSSH2_SCP_RESPONSE_BUFLEN 256 + +struct flags { + int sigpipe; /* LIBSSH2_FLAG_SIGPIPE */ + int compress; /* LIBSSH2_FLAG_COMPRESS */ +}; + +struct _LIBSSH2_SESSION +{ + /* Memory management callbacks */ + void *abstract; + LIBSSH2_ALLOC_FUNC((*alloc)); + LIBSSH2_REALLOC_FUNC((*realloc)); + LIBSSH2_FREE_FUNC((*free)); + + /* Other callbacks */ + LIBSSH2_IGNORE_FUNC((*ssh_msg_ignore)); + LIBSSH2_DEBUG_FUNC((*ssh_msg_debug)); + LIBSSH2_DISCONNECT_FUNC((*ssh_msg_disconnect)); + LIBSSH2_MACERROR_FUNC((*macerror)); + LIBSSH2_X11_OPEN_FUNC((*x11)); + LIBSSH2_SEND_FUNC((*send)); + LIBSSH2_RECV_FUNC((*recv)); + + /* Method preferences -- NULL yields "load order" */ + char *kex_prefs; + char *hostkey_prefs; + + int state; + + /* Flag options */ + struct flags flag; + + /* Agreed Key Exchange Method */ + const LIBSSH2_KEX_METHOD *kex; + unsigned int burn_optimistic_kexinit:1; + + unsigned char *session_id; + uint32_t session_id_len; + + /* this is set to TRUE if a blocking API behavior is requested */ + int api_block_mode; + + /* Timeout used when blocking API behavior is active */ + long api_timeout; + + /* Server's public key */ + const LIBSSH2_HOSTKEY_METHOD *hostkey; + void *server_hostkey_abstract; + + /* Either set with libssh2_session_hostkey() (for server mode) + * Or read from server in (eg) KEXDH_INIT (for client mode) + */ + unsigned char *server_hostkey; + uint32_t server_hostkey_len; +#if LIBSSH2_MD5 + unsigned char server_hostkey_md5[MD5_DIGEST_LENGTH]; + int server_hostkey_md5_valid; +#endif /* ! LIBSSH2_MD5 */ + unsigned char server_hostkey_sha1[SHA_DIGEST_LENGTH]; + int server_hostkey_sha1_valid; + + unsigned char server_hostkey_sha256[SHA256_DIGEST_LENGTH]; + int server_hostkey_sha256_valid; + + /* (remote as source of data -- packet_read ) */ + libssh2_endpoint_data remote; + + /* (local as source of data -- packet_write ) */ + libssh2_endpoint_data local; + + /* Inbound Data linked list -- Sometimes the packet that comes in isn't the + packet we're ready for */ + struct list_head packets; + + /* Active connection channels */ + struct list_head channels; + + uint32_t next_channel; + + struct list_head listeners; /* list of LIBSSH2_LISTENER structs */ + + /* Actual I/O socket */ + libssh2_socket_t socket_fd; + int socket_state; + int socket_block_directions; + int socket_prev_blockstate; /* stores the state of the socket blockiness + when libssh2_session_startup() is called */ + + /* Error tracking */ + const char *err_msg; + int err_code; + int err_flags; + + /* struct members for packet-level reading */ + struct transportpacket packet; +#ifdef LIBSSH2DEBUG + int showmask; /* what debug/trace messages to display */ + libssh2_trace_handler_func tracehandler; /* callback to display trace + messages */ + void *tracehandler_context; /* context for the trace handler */ +#endif + + /* State variables used in libssh2_banner_send() */ + libssh2_nonblocking_states banner_TxRx_state; + char banner_TxRx_banner[256]; + ssize_t banner_TxRx_total_send; + + /* State variables used in libssh2_kexinit() */ + libssh2_nonblocking_states kexinit_state; + unsigned char *kexinit_data; + size_t kexinit_data_len; + + /* State variables used in libssh2_session_startup() */ + libssh2_nonblocking_states startup_state; + unsigned char *startup_data; + size_t startup_data_len; + unsigned char startup_service[sizeof("ssh-userauth") + 5 - 1]; + size_t startup_service_length; + packet_require_state_t startup_req_state; + key_exchange_state_t startup_key_state; + + /* State variables used in libssh2_session_free() */ + libssh2_nonblocking_states free_state; + + /* State variables used in libssh2_session_disconnect_ex() */ + libssh2_nonblocking_states disconnect_state; + unsigned char disconnect_data[256 + 13]; + size_t disconnect_data_len; + + /* State variables used in libssh2_packet_read() */ + libssh2_nonblocking_states readPack_state; + int readPack_encrypted; + + /* State variables used in libssh2_userauth_list() */ + libssh2_nonblocking_states userauth_list_state; + unsigned char *userauth_list_data; + size_t userauth_list_data_len; + packet_requirev_state_t userauth_list_packet_requirev_state; + + /* State variables used in libssh2_userauth_password_ex() */ + libssh2_nonblocking_states userauth_pswd_state; + unsigned char *userauth_pswd_data; + unsigned char userauth_pswd_data0; + size_t userauth_pswd_data_len; + char *userauth_pswd_newpw; + int userauth_pswd_newpw_len; + packet_requirev_state_t userauth_pswd_packet_requirev_state; + + /* State variables used in libssh2_userauth_hostbased_fromfile_ex() */ + libssh2_nonblocking_states userauth_host_state; + unsigned char *userauth_host_data; + size_t userauth_host_data_len; + unsigned char *userauth_host_packet; + size_t userauth_host_packet_len; + unsigned char *userauth_host_method; + size_t userauth_host_method_len; + unsigned char *userauth_host_s; + packet_requirev_state_t userauth_host_packet_requirev_state; + + /* State variables used in libssh2_userauth_publickey_fromfile_ex() */ + libssh2_nonblocking_states userauth_pblc_state; + unsigned char *userauth_pblc_data; + size_t userauth_pblc_data_len; + unsigned char *userauth_pblc_packet; + size_t userauth_pblc_packet_len; + unsigned char *userauth_pblc_method; + size_t userauth_pblc_method_len; + unsigned char *userauth_pblc_s; + unsigned char *userauth_pblc_b; + packet_requirev_state_t userauth_pblc_packet_requirev_state; + + /* State variables used in libssh2_userauth_keyboard_interactive_ex() */ + libssh2_nonblocking_states userauth_kybd_state; + unsigned char *userauth_kybd_data; + size_t userauth_kybd_data_len; + unsigned char *userauth_kybd_packet; + size_t userauth_kybd_packet_len; + unsigned int userauth_kybd_auth_name_len; + char *userauth_kybd_auth_name; + unsigned userauth_kybd_auth_instruction_len; + char *userauth_kybd_auth_instruction; + unsigned int userauth_kybd_num_prompts; + int userauth_kybd_auth_failure; + LIBSSH2_USERAUTH_KBDINT_PROMPT *userauth_kybd_prompts; + LIBSSH2_USERAUTH_KBDINT_RESPONSE *userauth_kybd_responses; + packet_requirev_state_t userauth_kybd_packet_requirev_state; + + /* State variables used in libssh2_channel_open_ex() */ + libssh2_nonblocking_states open_state; + packet_requirev_state_t open_packet_requirev_state; + LIBSSH2_CHANNEL *open_channel; + unsigned char *open_packet; + size_t open_packet_len; + unsigned char *open_data; + size_t open_data_len; + uint32_t open_local_channel; + + /* State variables used in libssh2_channel_direct_tcpip_ex() */ + libssh2_nonblocking_states direct_state; + unsigned char *direct_message; + size_t direct_host_len; + size_t direct_shost_len; + size_t direct_message_len; + + /* State variables used in libssh2_channel_forward_listen_ex() */ + libssh2_nonblocking_states fwdLstn_state; + unsigned char *fwdLstn_packet; + uint32_t fwdLstn_host_len; + uint32_t fwdLstn_packet_len; + packet_requirev_state_t fwdLstn_packet_requirev_state; + + /* State variables used in libssh2_publickey_init() */ + libssh2_nonblocking_states pkeyInit_state; + LIBSSH2_PUBLICKEY *pkeyInit_pkey; + LIBSSH2_CHANNEL *pkeyInit_channel; + unsigned char *pkeyInit_data; + size_t pkeyInit_data_len; + /* 19 = packet_len(4) + version_len(4) + "version"(7) + version_num(4) */ + unsigned char pkeyInit_buffer[19]; + size_t pkeyInit_buffer_sent; /* how much of buffer that has been sent */ + + /* State variables used in libssh2_packet_add() */ + libssh2_nonblocking_states packAdd_state; + LIBSSH2_CHANNEL *packAdd_channelp; /* keeper of the channel during EAGAIN + states */ + packet_queue_listener_state_t packAdd_Qlstn_state; + packet_x11_open_state_t packAdd_x11open_state; + + /* State variables used in fullpacket() */ + libssh2_nonblocking_states fullpacket_state; + int fullpacket_macstate; + size_t fullpacket_payload_len; + int fullpacket_packet_type; + + /* State variables used in libssh2_sftp_init() */ + libssh2_nonblocking_states sftpInit_state; + LIBSSH2_SFTP *sftpInit_sftp; + LIBSSH2_CHANNEL *sftpInit_channel; + unsigned char sftpInit_buffer[9]; /* sftp_header(5){excludes request_id} + + version_id(4) */ + int sftpInit_sent; /* number of bytes from the buffer that have been + sent */ + + /* State variables used in libssh2_scp_recv() / libssh_scp_recv2() */ + libssh2_nonblocking_states scpRecv_state; + unsigned char *scpRecv_command; + size_t scpRecv_command_len; + unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + size_t scpRecv_response_len; + long scpRecv_mode; +#if defined(HAVE_LONGLONG) && defined(HAVE_STRTOLL) + /* we have the type and we can parse such numbers */ + long long scpRecv_size; +#define scpsize_strtol strtoll +#elif defined(HAVE_STRTOI64) + __int64 scpRecv_size; +#define scpsize_strtol _strtoi64 +#else + long scpRecv_size; +#define scpsize_strtol strtol +#endif + long scpRecv_mtime; + long scpRecv_atime; + LIBSSH2_CHANNEL *scpRecv_channel; + + /* State variables used in libssh2_scp_send_ex() */ + libssh2_nonblocking_states scpSend_state; + unsigned char *scpSend_command; + size_t scpSend_command_len; + unsigned char scpSend_response[LIBSSH2_SCP_RESPONSE_BUFLEN]; + size_t scpSend_response_len; + LIBSSH2_CHANNEL *scpSend_channel; + + /* Keepalive variables used by keepalive.c. */ + int keepalive_interval; + int keepalive_want_reply; + time_t keepalive_last_sent; +}; + +/* session.state bits */ +#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001 +#define LIBSSH2_STATE_NEWKEYS 0x00000002 +#define LIBSSH2_STATE_AUTHENTICATED 0x00000004 +#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008 + +/* session.flag helpers */ +#ifdef MSG_NOSIGNAL +#define LIBSSH2_SOCKET_SEND_FLAGS(session) \ + (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) +#define LIBSSH2_SOCKET_RECV_FLAGS(session) \ + (((session)->flag.sigpipe) ? 0 : MSG_NOSIGNAL) +#else +/* If MSG_NOSIGNAL isn't defined we're SOL on blocking SIGPIPE */ +#define LIBSSH2_SOCKET_SEND_FLAGS(session) 0 +#define LIBSSH2_SOCKET_RECV_FLAGS(session) 0 +#endif + +/* --------- */ + +/* libssh2 extensible ssh api, ultimately I'd like to allow loading additional + methods via .so/.dll */ + +struct _LIBSSH2_KEX_METHOD +{ + const char *name; + + /* Key exchange, populates session->* and returns 0 on success, non-0 on + error */ + int (*exchange_keys) (LIBSSH2_SESSION * session, + key_exchange_state_low_t * key_state); + + long flags; +}; + +struct _LIBSSH2_HOSTKEY_METHOD +{ + const char *name; + unsigned long hash_len; + + int (*init) (LIBSSH2_SESSION * session, const unsigned char *hostkey_data, + size_t hostkey_data_len, void **abstract); + int (*initPEM) (LIBSSH2_SESSION * session, const char *privkeyfile, + unsigned const char *passphrase, void **abstract); + int (*initPEMFromMemory) (LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract); + int (*sig_verify) (LIBSSH2_SESSION * session, const unsigned char *sig, + size_t sig_len, const unsigned char *m, + size_t m_len, void **abstract); + int (*signv) (LIBSSH2_SESSION * session, unsigned char **signature, + size_t *signature_len, int veccount, + const struct iovec datavec[], void **abstract); + int (*encrypt) (LIBSSH2_SESSION * session, unsigned char **dst, + size_t *dst_len, const unsigned char *src, + size_t src_len, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); +}; + +struct _LIBSSH2_CRYPT_METHOD +{ + const char *name; + const char *pem_annotation; + + int blocksize; + + /* iv and key sizes (-1 for variable length) */ + int iv_len; + int secret_len; + + long flags; + + int (*init) (LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, unsigned char *iv, + int *free_iv, unsigned char *secret, int *free_secret, + int encrypt, void **abstract); + int (*crypt) (LIBSSH2_SESSION * session, unsigned char *block, + size_t blocksize, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); + + _libssh2_cipher_type(algo); +}; + +struct _LIBSSH2_COMP_METHOD +{ + const char *name; + int compress; /* 1 if it does compress, 0 if it doesn't */ + int use_in_auth; /* 1 if compression should be used in userauth */ + int (*init) (LIBSSH2_SESSION *session, int compress, void **abstract); + int (*comp) (LIBSSH2_SESSION *session, + unsigned char *dest, + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract); + int (*decomp) (LIBSSH2_SESSION *session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, + void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, int compress, void **abstract); +}; + +#ifdef LIBSSH2DEBUG +void _libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, + ...); +#else +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ + defined(__GNUC__) +/* C99 supported and also by older GCC */ +#define _libssh2_debug(x,y,z,...) do {} while (0) +#else +/* no gcc and not C99, do static and hopefully inline */ +static inline void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ + (void)session; + (void)context; + (void)format; +} +#endif +#endif + +#define LIBSSH2_SOCKET_UNKNOWN 1 +#define LIBSSH2_SOCKET_CONNECTED 0 +#define LIBSSH2_SOCKET_DISCONNECTED -1 + +/* Initial packet state, prior to MAC check */ +#define LIBSSH2_MAC_UNCONFIRMED 1 +/* When MAC type is "none" (proto initiation phase) all packets are deemed + "confirmed" */ +#define LIBSSH2_MAC_CONFIRMED 0 +/* Something very bad is going on */ +#define LIBSSH2_MAC_INVALID -1 + +/* Flags for _libssh2_error_flags */ +/* Error message is allocated on the heap */ +#define LIBSSH2_ERR_FLAG_DUP 1 + +/* SSH Packet Types -- Defined by internet draft */ +/* Transport Layer */ +#define SSH_MSG_DISCONNECT 1 +#define SSH_MSG_IGNORE 2 +#define SSH_MSG_UNIMPLEMENTED 3 +#define SSH_MSG_DEBUG 4 +#define SSH_MSG_SERVICE_REQUEST 5 +#define SSH_MSG_SERVICE_ACCEPT 6 + +#define SSH_MSG_KEXINIT 20 +#define SSH_MSG_NEWKEYS 21 + +/* diffie-hellman-group1-sha1 */ +#define SSH_MSG_KEXDH_INIT 30 +#define SSH_MSG_KEXDH_REPLY 31 + +/* diffie-hellman-group-exchange-sha1 and + diffie-hellman-group-exchange-sha256 */ +#define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30 +#define SSH_MSG_KEX_DH_GEX_REQUEST 34 +#define SSH_MSG_KEX_DH_GEX_GROUP 31 +#define SSH_MSG_KEX_DH_GEX_INIT 32 +#define SSH_MSG_KEX_DH_GEX_REPLY 33 + +/* ecdh */ +#define SSH2_MSG_KEX_ECDH_INIT 30 +#define SSH2_MSG_KEX_ECDH_REPLY 31 + +/* User Authentication */ +#define SSH_MSG_USERAUTH_REQUEST 50 +#define SSH_MSG_USERAUTH_FAILURE 51 +#define SSH_MSG_USERAUTH_SUCCESS 52 +#define SSH_MSG_USERAUTH_BANNER 53 + +/* "public key" method */ +#define SSH_MSG_USERAUTH_PK_OK 60 +/* "password" method */ +#define SSH_MSG_USERAUTH_PASSWD_CHANGEREQ 60 +/* "keyboard-interactive" method */ +#define SSH_MSG_USERAUTH_INFO_REQUEST 60 +#define SSH_MSG_USERAUTH_INFO_RESPONSE 61 + +/* Channels */ +#define SSH_MSG_GLOBAL_REQUEST 80 +#define SSH_MSG_REQUEST_SUCCESS 81 +#define SSH_MSG_REQUEST_FAILURE 82 + +#define SSH_MSG_CHANNEL_OPEN 90 +#define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 +#define SSH_MSG_CHANNEL_OPEN_FAILURE 92 +#define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 +#define SSH_MSG_CHANNEL_DATA 94 +#define SSH_MSG_CHANNEL_EXTENDED_DATA 95 +#define SSH_MSG_CHANNEL_EOF 96 +#define SSH_MSG_CHANNEL_CLOSE 97 +#define SSH_MSG_CHANNEL_REQUEST 98 +#define SSH_MSG_CHANNEL_SUCCESS 99 +#define SSH_MSG_CHANNEL_FAILURE 100 + +/* Error codes returned in SSH_MSG_CHANNEL_OPEN_FAILURE message + (see RFC4254) */ +#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1 +#define SSH_OPEN_CONNECT_FAILED 2 +#define SSH_OPEN_UNKNOWN_CHANNELTYPE 3 +#define SSH_OPEN_RESOURCE_SHORTAGE 4 + +ssize_t _libssh2_recv(libssh2_socket_t socket, void *buffer, + size_t length, int flags, void **abstract); +ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer, + size_t length, int flags, void **abstract); + +#define LIBSSH2_READ_TIMEOUT 60 /* generic timeout in seconds used when + waiting for more data to arrive */ + + +int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * state); + +/* Let crypt.c/hostkey.c expose their method structs */ +const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void); +const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void); + +/* misc.c */ +int _libssh2_bcrypt_pbkdf(const char *pass, + size_t passlen, + const uint8_t *salt, + size_t saltlen, + uint8_t *key, + size_t keylen, + unsigned int rounds); + +/* pem.c */ +int _libssh2_pem_parse(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const unsigned char *passphrase, + FILE * fp, unsigned char **data, unsigned int *datalen); +int _libssh2_pem_parse_memory(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const char *filedata, size_t filedata_len, + unsigned char **data, unsigned int *datalen); + /* OpenSSL keys */ +int +_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session, + const unsigned char *passphrase, + FILE * fp, struct string_buf **decrypted_buf); +int +_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session, + const unsigned char *passphrase, + const char *filedata, size_t filedata_len, + struct string_buf **decrypted_buf); + +int _libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen); +int _libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen); + +/* global.c */ +void _libssh2_init_if_needed(void); + + +#define ARRAY_SIZE(a) (sizeof ((a)) / sizeof ((a)[0])) + +/* define to output the libssh2_int64_t type in a *printf() */ +#if defined(__BORLANDC__) || defined(_MSC_VER) || defined(__MINGW32__) +#define LIBSSH2_INT64_T_FORMAT "I64d" +#else +#define LIBSSH2_INT64_T_FORMAT "lld" +#endif + +/* In Windows the default file mode is text but an application can override it. +Therefore we specify it explicitly. https://github.com/curl/curl/pull/258 +*/ +#if defined(WIN32) || defined(MSDOS) +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "wt" +#define FOPEN_APPENDTEXT "at" +#elif defined(__CYGWIN__) +/* Cygwin has specific behavior we need to address when WIN32 is not defined. +https://cygwin.com/cygwin-ug-net/using-textbinary.html +For write we want our output to have line endings of LF and be compatible with +other Cygwin utilities. For read we want to handle input that may have line +endings either CRLF or LF so 't' is appropriate. +*/ +#define FOPEN_READTEXT "rt" +#define FOPEN_WRITETEXT "w" +#define FOPEN_APPENDTEXT "a" +#else +#define FOPEN_READTEXT "r" +#define FOPEN_WRITETEXT "w" +#define FOPEN_APPENDTEXT "a" +#endif + +#endif /* __LIBSSH2_PRIV_H */ diff --git a/include/libssh2/libssh2_publickey.h b/include/libssh2/libssh2_publickey.h new file mode 100644 index 0000000..5dbdcf9 --- /dev/null +++ b/include/libssh2/libssh2_publickey.h @@ -0,0 +1,122 @@ +/* Copyright (c) 2004-2006, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* Note: This include file is only needed for using the + * publickey SUBSYSTEM which is not the same as publickey + * authentication. For authentication you only need libssh2.h + * + * For more information on the publickey subsystem, + * refer to IETF draft: secsh-publickey + */ + +#ifndef LIBSSH2_PUBLICKEY_H +#define LIBSSH2_PUBLICKEY_H 1 + +#include "libssh2.h" + +typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY; + +typedef struct _libssh2_publickey_attribute { + const char *name; + unsigned long name_len; + const char *value; + unsigned long value_len; + char mandatory; +} libssh2_publickey_attribute; + +typedef struct _libssh2_publickey_list { + unsigned char *packet; /* For freeing */ + + const unsigned char *name; + unsigned long name_len; + const unsigned char *blob; + unsigned long blob_len; + unsigned long num_attrs; + libssh2_publickey_attribute *attrs; /* free me */ +} libssh2_publickey_list; + +/* Generally use the first macro here, but if both name and value are string + literals, you can use _fast() to take advantage of preprocessing */ +#define libssh2_publickey_attribute(name, value, mandatory) \ + { (name), strlen(name), (value), strlen(value), (mandatory) }, +#define libssh2_publickey_attribute_fast(name, value, mandatory) \ + { (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) }, + +#ifdef __cplusplus +extern "C" { +#endif + +/* Publickey Subsystem */ +LIBSSH2_API LIBSSH2_PUBLICKEY * +libssh2_publickey_init(LIBSSH2_SESSION *session); + +LIBSSH2_API int +libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, + const unsigned char *name, + unsigned long name_len, + const unsigned char *blob, + unsigned long blob_len, char overwrite, + unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]); +#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \ + num_attrs, attrs) \ + libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \ + (overwrite), (num_attrs), (attrs)) + +LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey, + const unsigned char *name, + unsigned long name_len, + const unsigned char *blob, + unsigned long blob_len); +#define libssh2_publickey_remove(pkey, name, blob, blob_len) \ + libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len)) + +LIBSSH2_API int +libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey, + unsigned long *num_keys, + libssh2_publickey_list **pkey_list); +LIBSSH2_API void +libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey, + libssh2_publickey_list *pkey_list); + +LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef: LIBSSH2_PUBLICKEY_H */ diff --git a/include/libssh2/libssh2_sftp.h b/include/libssh2/libssh2_sftp.h new file mode 100644 index 0000000..476ea87 --- /dev/null +++ b/include/libssh2/libssh2_sftp.h @@ -0,0 +1,351 @@ +/* Copyright (c) 2004-2008, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#ifndef LIBSSH2_SFTP_H +#define LIBSSH2_SFTP_H 1 + +#include "libssh2.h" + +#ifndef WIN32 +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * Let's start with Version 3 (The version found in OpenSSH) and go from there + */ +#define LIBSSH2_SFTP_VERSION 3 + +typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP; +typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE; +typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES; +typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS; + +/* Flags for open_ex() */ +#define LIBSSH2_SFTP_OPENFILE 0 +#define LIBSSH2_SFTP_OPENDIR 1 + +/* Flags for rename_ex() */ +#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001 +#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002 +#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004 + +/* Flags for stat_ex() */ +#define LIBSSH2_SFTP_STAT 0 +#define LIBSSH2_SFTP_LSTAT 1 +#define LIBSSH2_SFTP_SETSTAT 2 + +/* Flags for symlink_ex() */ +#define LIBSSH2_SFTP_SYMLINK 0 +#define LIBSSH2_SFTP_READLINK 1 +#define LIBSSH2_SFTP_REALPATH 2 + +/* Flags for sftp_mkdir() */ +#define LIBSSH2_SFTP_DEFAULT_MODE -1 + +/* SFTP attribute flag bits */ +#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001 +#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002 +#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004 +#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008 +#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000 + +/* SFTP statvfs flag bits */ +#define LIBSSH2_SFTP_ST_RDONLY 0x00000001 +#define LIBSSH2_SFTP_ST_NOSUID 0x00000002 + +struct _LIBSSH2_SFTP_ATTRIBUTES { + /* If flags & ATTR_* bit is set, then the value in this struct will be + * meaningful Otherwise it should be ignored + */ + unsigned long flags; + + libssh2_uint64_t filesize; + unsigned long uid, gid; + unsigned long permissions; + unsigned long atime, mtime; +}; + +struct _LIBSSH2_SFTP_STATVFS { + libssh2_uint64_t f_bsize; /* file system block size */ + libssh2_uint64_t f_frsize; /* fragment size */ + libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */ + libssh2_uint64_t f_bfree; /* # free blocks */ + libssh2_uint64_t f_bavail; /* # free blocks for non-root */ + libssh2_uint64_t f_files; /* # inodes */ + libssh2_uint64_t f_ffree; /* # free inodes */ + libssh2_uint64_t f_favail; /* # free inodes for non-root */ + libssh2_uint64_t f_fsid; /* file system ID */ + libssh2_uint64_t f_flag; /* mount flags */ + libssh2_uint64_t f_namemax; /* maximum filename length */ +}; + +/* SFTP filetypes */ +#define LIBSSH2_SFTP_TYPE_REGULAR 1 +#define LIBSSH2_SFTP_TYPE_DIRECTORY 2 +#define LIBSSH2_SFTP_TYPE_SYMLINK 3 +#define LIBSSH2_SFTP_TYPE_SPECIAL 4 +#define LIBSSH2_SFTP_TYPE_UNKNOWN 5 +#define LIBSSH2_SFTP_TYPE_SOCKET 6 +#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7 +#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8 +#define LIBSSH2_SFTP_TYPE_FIFO 9 + +/* + * Reproduce the POSIX file modes here for systems that are not POSIX + * compliant. + * + * These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES" + */ +/* File type */ +#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */ +#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */ +#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */ +#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */ +#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */ +#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */ +#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */ +#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */ + +/* File mode */ +/* Read, write, execute/search by owner */ +#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */ +#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */ +#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */ +#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */ +/* Read, write, execute/search by group */ +#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */ +#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */ +#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */ +#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */ +/* Read, write, execute/search by others */ +#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */ +#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */ +#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */ +#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */ + +/* macros to check for specific file types, added in 1.2.5 */ +#define LIBSSH2_SFTP_S_ISLNK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK) +#define LIBSSH2_SFTP_S_ISREG(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG) +#define LIBSSH2_SFTP_S_ISDIR(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR) +#define LIBSSH2_SFTP_S_ISCHR(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR) +#define LIBSSH2_SFTP_S_ISBLK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK) +#define LIBSSH2_SFTP_S_ISFIFO(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO) +#define LIBSSH2_SFTP_S_ISSOCK(m) \ + (((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK) + +/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open()) + * Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */ +#define LIBSSH2_FXF_READ 0x00000001 +#define LIBSSH2_FXF_WRITE 0x00000002 +#define LIBSSH2_FXF_APPEND 0x00000004 +#define LIBSSH2_FXF_CREAT 0x00000008 +#define LIBSSH2_FXF_TRUNC 0x00000010 +#define LIBSSH2_FXF_EXCL 0x00000020 + +/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */ +#define LIBSSH2_FX_OK 0UL +#define LIBSSH2_FX_EOF 1UL +#define LIBSSH2_FX_NO_SUCH_FILE 2UL +#define LIBSSH2_FX_PERMISSION_DENIED 3UL +#define LIBSSH2_FX_FAILURE 4UL +#define LIBSSH2_FX_BAD_MESSAGE 5UL +#define LIBSSH2_FX_NO_CONNECTION 6UL +#define LIBSSH2_FX_CONNECTION_LOST 7UL +#define LIBSSH2_FX_OP_UNSUPPORTED 8UL +#define LIBSSH2_FX_INVALID_HANDLE 9UL +#define LIBSSH2_FX_NO_SUCH_PATH 10UL +#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11UL +#define LIBSSH2_FX_WRITE_PROTECT 12UL +#define LIBSSH2_FX_NO_MEDIA 13UL +#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14UL +#define LIBSSH2_FX_QUOTA_EXCEEDED 15UL +#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16UL /* Initial mis-spelling */ +#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16UL +#define LIBSSH2_FX_LOCK_CONFlICT 17UL /* Initial mis-spelling */ +#define LIBSSH2_FX_LOCK_CONFLICT 17UL +#define LIBSSH2_FX_DIR_NOT_EMPTY 18UL +#define LIBSSH2_FX_NOT_A_DIRECTORY 19UL +#define LIBSSH2_FX_INVALID_FILENAME 20UL +#define LIBSSH2_FX_LINK_LOOP 21UL + +/* Returned by any function that would block during a read/write operation */ +#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN + +/* SFTP API */ +LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session); +LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp); +LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp); +LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp); + +/* File / Directory Ops */ +LIBSSH2_API LIBSSH2_SFTP_HANDLE * +libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, + const char *filename, + unsigned int filename_len, + unsigned long flags, + long mode, int open_type); +#define libssh2_sftp_open(sftp, filename, flags, mode) \ + libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \ + (mode), LIBSSH2_SFTP_OPENFILE) +#define libssh2_sftp_opendir(sftp, path) \ + libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \ + LIBSSH2_SFTP_OPENDIR) + +LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle, + char *buffer, size_t buffer_maxlen); + +LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \ + char *buffer, size_t buffer_maxlen, + char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \ + libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \ + (attrs)) + +LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle, + const char *buffer, size_t count); +LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle); + +LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle); +#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle) +#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle) + +LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset); +LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, + libssh2_uint64_t offset); +#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0) + +LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle); +LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle); + +LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs, + int setstat); +#define libssh2_sftp_fstat(handle, attrs) \ + libssh2_sftp_fstat_ex((handle), (attrs), 0) +#define libssh2_sftp_fsetstat(handle, attrs) \ + libssh2_sftp_fstat_ex((handle), (attrs), 1) + +/* Miscellaneous Ops */ +LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, + const char *source_filename, + unsigned int srouce_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, + long flags); +#define libssh2_sftp_rename(sftp, sourcefile, destfile) \ + libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \ + (destfile), strlen(destfile), \ + LIBSSH2_SFTP_RENAME_OVERWRITE | \ + LIBSSH2_SFTP_RENAME_ATOMIC | \ + LIBSSH2_SFTP_RENAME_NATIVE) + +LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, + const char *filename, + unsigned int filename_len); +#define libssh2_sftp_unlink(sftp, filename) \ + libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename)) + +LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_STATVFS *st); + +LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, + const char *path, + size_t path_len, + LIBSSH2_SFTP_STATVFS *st); + +LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, long mode); +#define libssh2_sftp_mkdir(sftp, path, mode) \ + libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode)) + +LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len); +#define libssh2_sftp_rmdir(sftp, path) \ + libssh2_sftp_rmdir_ex((sftp), (path), strlen(path)) + +LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, + int stat_type, + LIBSSH2_SFTP_ATTRIBUTES *attrs); +#define libssh2_sftp_stat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \ + (attrs)) +#define libssh2_sftp_lstat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \ + (attrs)) +#define libssh2_sftp_setstat(sftp, path, attrs) \ + libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \ + (attrs)) + +LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, + const char *path, + unsigned int path_len, + char *target, + unsigned int target_len, + int link_type); +#define libssh2_sftp_symlink(sftp, orig, linkpath) \ + libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \ + strlen(linkpath), LIBSSH2_SFTP_SYMLINK) +#define libssh2_sftp_readlink(sftp, path, target, maxlen) \ + libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \ + LIBSSH2_SFTP_READLINK) +#define libssh2_sftp_realpath(sftp, path, target, maxlen) \ + libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \ + LIBSSH2_SFTP_REALPATH) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* LIBSSH2_SFTP_H */ diff --git a/include/libssh2/mac.h b/include/libssh2/mac.h new file mode 100644 index 0000000..46fce54 --- /dev/null +++ b/include/libssh2/mac.h @@ -0,0 +1,66 @@ +#ifndef __LIBSSH2_MAC_H +#define __LIBSSH2_MAC_H +/* Copyright (C) 2009-2010 by Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +struct _LIBSSH2_MAC_METHOD +{ + const char *name; + + /* The length of a given MAC packet */ + int mac_len; + + /* integrity key length */ + int key_len; + + /* Message Authentication Code Hashing algo */ + int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key, + void **abstract); + int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, const unsigned char *packet, + uint32_t packet_len, const unsigned char *addtl, + uint32_t addtl_len, void **abstract); + int (*dtor) (LIBSSH2_SESSION * session, void **abstract); +}; + +typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD; + +const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void); + +#endif /* __LIBSSH2_MAC_H */ diff --git a/include/libssh2/mbedtls.h b/include/libssh2/mbedtls.h new file mode 100644 index 0000000..7832c45 --- /dev/null +++ b/include/libssh2/mbedtls.h @@ -0,0 +1,451 @@ +#ifndef __LIBSSH2_MBEDTLS_H +#define __LIBSSH2_MBEDTLS_H +/* Copyright (c) 2016, Art + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Define which features are supported. */ +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 1 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 1 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 0 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 0 +#define LIBSSH2_ECDSA 0 +#define LIBSSH2_ED25519 0 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) + +#if LIBSSH2_ECDSA +#else +#define _libssh2_ec_key void +#endif + +/*******************************************************************/ +/* + * mbedTLS backend: Generic functions + */ + +#define libssh2_crypto_init() \ + _libssh2_mbedtls_init() +#define libssh2_crypto_exit() \ + _libssh2_mbedtls_free() + +#define _libssh2_random(buf, len) \ + _libssh2_mbedtls_random(buf, len) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + + +/*******************************************************************/ +/* + * mbedTLS backend: HMAC functions + */ + +#define libssh2_hmac_ctx mbedtls_md_context_t + +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_cleanup(pctx) \ + mbedtls_md_free(pctx) +#define libssh2_hmac_update(ctx, data, datalen) \ + mbedtls_md_hmac_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, hash) \ + mbedtls_md_hmac_finish(&ctx, hash) + +#define libssh2_hmac_sha1_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, key, keylen) +#define libssh2_hmac_md5_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, key, keylen) +#define libssh2_hmac_ripemd160_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen) +#define libssh2_hmac_sha256_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen) +#define libssh2_hmac_sha384_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, key, keylen) +#define libssh2_hmac_sha512_init(pctx, key, keylen) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen) + + +/*******************************************************************/ +/* + * mbedTLS backend: SHA1 functions + */ + +#define libssh2_sha1_ctx mbedtls_md_context_t + +#define libssh2_sha1_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0) +#define libssh2_sha1_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha1_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha1(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash) + +/*******************************************************************/ +/* + * mbedTLS backend: SHA256 functions + */ + +#define libssh2_sha256_ctx mbedtls_md_context_t + +#define libssh2_sha256_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0) +#define libssh2_sha256_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha256_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha256(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash) + + +/*******************************************************************/ +/* + * mbedTLS backend: SHA384 functions + */ + +#define libssh2_sha384_ctx mbedtls_md_context_t + +#define libssh2_sha384_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0) +#define libssh2_sha384_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha384_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha384(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash) + + +/*******************************************************************/ +/* + * mbedTLS backend: SHA512 functions + */ + +#define libssh2_sha512_ctx mbedtls_md_context_t + +#define libssh2_sha512_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0) +#define libssh2_sha512_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha512_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_sha512(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash) + + +/*******************************************************************/ +/* + * mbedTLS backend: MD5 functions + */ + +#define libssh2_md5_ctx mbedtls_md_context_t + +#define libssh2_md5_init(pctx) \ + _libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0) +#define libssh2_md5_update(ctx, data, datalen) \ + mbedtls_md_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_md5_final(ctx, hash) \ + _libssh2_mbedtls_hash_final(&ctx, hash) +#define libssh2_md5(data, datalen, hash) \ + _libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash) + +/*******************************************************************/ +/* + * mbedTLS backend: RSA structure + */ + +#define libssh2_rsa_ctx mbedtls_rsa_context + +#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) \ + _libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) + +#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ + _libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase) + +#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) \ + _libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) + +#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ + _libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) + +#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ + _libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) + +#define _libssh2_rsa_free(rsactx) \ + _libssh2_mbedtls_rsa_free(rsactx) + +/* + * mbedTLS backend: Key functions + */ + +#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ + _libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) +#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) \ + _libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) + + + /*******************************************************************/ +/* + * mbedTLS backend: Cipher Context structure + */ +#define _libssh2_cipher_ctx mbedtls_cipher_context_t + +#define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo + +#define _libssh2_cipher_aes256ctr MBEDTLS_CIPHER_AES_256_CTR +#define _libssh2_cipher_aes192ctr MBEDTLS_CIPHER_AES_192_CTR +#define _libssh2_cipher_aes128ctr MBEDTLS_CIPHER_AES_128_CTR +#define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC +#define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC +#define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC +#define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC +#define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128 +#define _libssh2_cipher_cast5 MBEDTLS_CIPHER_NULL +#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC + +/* + * mbedTLS backend: Cipher functions + */ + +#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ + _libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt) +#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \ + _libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen) +#define _libssh2_cipher_dtor(ctx) \ + _libssh2_mbedtls_cipher_dtor(ctx) + + +/*******************************************************************/ +/* + * mbedTLS backend: BigNumber Support + */ + +#define _libssh2_bn_ctx int /* not used */ +#define _libssh2_bn_ctx_new() 0 /* not used */ +#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ + +#define _libssh2_bn mbedtls_mpi + +#define _libssh2_bn_init() \ + _libssh2_mbedtls_bignum_init() +#define _libssh2_bn_init_from_bin() \ + _libssh2_mbedtls_bignum_init() +#define _libssh2_bn_set_word(bn, word) \ + mbedtls_mpi_lset(bn, word) +#define _libssh2_bn_from_bin(bn, len, bin) \ + mbedtls_mpi_read_binary(bn, bin, len) +#define _libssh2_bn_to_bin(bn, bin) \ + mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn)) +#define _libssh2_bn_bytes(bn) \ + mbedtls_mpi_size(bn) +#define _libssh2_bn_bits(bn) \ + mbedtls_mpi_bitlen(bn) +#define _libssh2_bn_free(bn) \ + _libssh2_mbedtls_bignum_free(bn) + + +/*******************************************************************/ +/* + * mbedTLS backend: Diffie-Hellman support. + */ + +#define _libssh2_dh_ctx mbedtls_mpi * +#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) +#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ + _libssh2_dh_key_pair(dhctx, public, g, p, group_order) +#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ + _libssh2_dh_secret(dhctx, secret, f, p) +#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) + + +/*******************************************************************/ +/* + * mbedTLS backend: forward declarations + */ +void +_libssh2_mbedtls_init(void); + +void +_libssh2_mbedtls_free(void); + +int +_libssh2_mbedtls_random(unsigned char *buf, int len); + +int +_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + unsigned char *iv, + unsigned char *secret, + int encrypt); +int +_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + int encrypt, + unsigned char *block, + size_t blocklen); +void +_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx); + +int +_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, + mbedtls_md_type_t mdtype, + const unsigned char *key, unsigned long keylen); + +int +_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash); +int +_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, + mbedtls_md_type_t mdtype, unsigned char *hash); + +_libssh2_bn * +_libssh2_mbedtls_bignum_init(void); + +void +_libssh2_mbedtls_bignum_free(_libssh2_bn *bn); + +int +_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen); + +int +_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase); + +int +_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +int +_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len); +int +_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +void +_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa); + +int +_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); +int +_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); + +extern void +_libssh2_dh_init(_libssh2_dh_ctx *dhctx); +extern int +_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order); +extern int +_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p); +extern void +_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); + +#endif /* __LIBSSH2_MBEDTLS_H */ diff --git a/include/libssh2/misc.h b/include/libssh2/misc.h new file mode 100644 index 0000000..5481e66 --- /dev/null +++ b/include/libssh2/misc.h @@ -0,0 +1,125 @@ +#ifndef __LIBSSH2_MISC_H +#define __LIBSSH2_MISC_H +/* Copyright (c) 2009-2019 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +struct list_head { + struct list_node *last; + struct list_node *first; +}; + +struct list_node { + struct list_node *next; + struct list_node *prev; + struct list_head *head; +}; + +struct string_buf { + unsigned char *data; + unsigned char *dataptr; + size_t len; +}; + +int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, + const char *errmsg, int errflags); +int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg); + +void _libssh2_list_init(struct list_head *head); + +/* add a node last in the list */ +void _libssh2_list_add(struct list_head *head, + struct list_node *entry); + +/* return the "first" node in the list this head points to */ +void *_libssh2_list_first(struct list_head *head); + +/* return the next node in the list */ +void *_libssh2_list_next(struct list_node *node); + +/* return the prev node in the list */ +void *_libssh2_list_prev(struct list_node *node); + +/* remove this node from the list */ +void _libssh2_list_remove(struct list_node *entry); + +size_t _libssh2_base64_encode(LIBSSH2_SESSION *session, + const char *inp, size_t insize, char **outptr); + +unsigned int _libssh2_ntohu32(const unsigned char *buf); +libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf); +void _libssh2_htonu32(unsigned char *buf, uint32_t val); +void _libssh2_store_u32(unsigned char **buf, uint32_t value); +void _libssh2_store_str(unsigned char **buf, const char *str, size_t len); +void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size); +void _libssh2_explicit_zero(void *buf, size_t size); + +struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session); +void _libssh2_string_buf_free(LIBSSH2_SESSION *session, + struct string_buf *buf); +int _libssh2_get_u32(struct string_buf *buf, uint32_t *out); +int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out); +int _libssh2_match_string(struct string_buf *buf, const char *match); +int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf, + size_t *outlen); +int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf, + unsigned char **outbuf, size_t *outlen); +int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf, + size_t *outlen); +int _libssh2_check_length(struct string_buf *buf, size_t requested_len); + +#if defined(LIBSSH2_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__) +/* provide a private one */ +#undef HAVE_GETTIMEOFDAY +int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp); +#define HAVE_LIBSSH2_GETTIMEOFDAY +#define LIBSSH2_GETTIMEOFDAY_WIN32 /* enable the win32 implementation */ +#else +#ifdef HAVE_GETTIMEOFDAY +#define _libssh2_gettimeofday(x,y) gettimeofday(x,y) +#define HAVE_LIBSSH2_GETTIMEOFDAY +#endif +#endif + +void _libssh2_xor_data(unsigned char *output, + const unsigned char *input1, + const unsigned char *input2, + size_t length); + +void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length); + +#endif /* _LIBSSH2_MISC_H */ diff --git a/include/libssh2/module.mk b/include/libssh2/module.mk new file mode 100644 index 0000000..e882048 --- /dev/null +++ b/include/libssh2/module.mk @@ -0,0 +1,35 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ Makefile fragment +# +####################################################################### + +if BUILD_SSH_TUNNEL + +pgadmin3_SOURCES += \ + include/libssh2/channel.h \ + include/libssh2/comp.h \ + include/libssh2/crypto.h \ + include/libssh2/libgcrypt.h \ + include/libssh2/libssh2.h \ + include/libssh2/libssh2_priv.h \ + include/libssh2/libssh2_publickey.h \ + include/libssh2/libssh2_sftp.h \ + include/libssh2/mac.h \ + include/libssh2/misc.h \ + include/libssh2/openssl.h \ + include/libssh2/packet.h \ + include/libssh2/session.h \ + include/libssh2/sftp.h \ + include/libssh2/transport.h \ + include/libssh2/userauth.h + +EXTRA_DIST += \ + include/libssh2/module.mk \ + include/libssh2/Win32/libssh2_config.h +endif diff --git a/include/libssh2/openssl.h b/include/libssh2/openssl.h new file mode 100644 index 0000000..f65192d --- /dev/null +++ b/include/libssh2/openssl.h @@ -0,0 +1,398 @@ +#ifndef __LIBSSH2_OPENSSL_H +#define __LIBSSH2_OPENSSL_H +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_MD5 +#include +#endif +#include +#include +#include +#include +#include + +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) +# define HAVE_OPAQUE_STRUCTS 1 +#endif + +#ifdef OPENSSL_NO_RSA +# define LIBSSH2_RSA 0 +#else +# define LIBSSH2_RSA 1 +#endif + +#ifdef OPENSSL_NO_DSA +# define LIBSSH2_DSA 0 +#else +# define LIBSSH2_DSA 1 +#endif + +#ifdef OPENSSL_NO_ECDSA +# define LIBSSH2_ECDSA 0 +#else +# define LIBSSH2_ECDSA 1 +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x10101000L && \ +!defined(LIBRESSL_VERSION_NUMBER) +# define LIBSSH2_ED25519 1 +#else +# define LIBSSH2_ED25519 0 +#endif + + +#ifdef OPENSSL_NO_MD5 +# define LIBSSH2_MD5 0 +#else +# define LIBSSH2_MD5 1 +#endif + +#ifdef OPENSSL_NO_RIPEMD +# define LIBSSH2_HMAC_RIPEMD 0 +#else +# define LIBSSH2_HMAC_RIPEMD 1 +#endif + +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#if OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES) +# define LIBSSH2_AES_CTR 1 +# define LIBSSH2_AES 1 +#else +# define LIBSSH2_AES_CTR 0 +# define LIBSSH2_AES 0 +#endif + +#ifdef OPENSSL_NO_BF +# define LIBSSH2_BLOWFISH 0 +#else +# define LIBSSH2_BLOWFISH 1 +#endif + +#ifdef OPENSSL_NO_RC4 +# define LIBSSH2_RC4 0 +#else +# define LIBSSH2_RC4 1 +#endif + +#ifdef OPENSSL_NO_CAST +# define LIBSSH2_CAST 0 +#else +# define LIBSSH2_CAST 1 +#endif + +#ifdef OPENSSL_NO_DES +# define LIBSSH2_3DES 0 +#else +# define LIBSSH2_3DES 1 +#endif + +#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) + +#define _libssh2_random(buf, len) RAND_bytes ((buf), (len)) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha1_ctx EVP_MD_CTX * +#else +#define libssh2_sha1_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_sha1_init(libssh2_sha1_ctx *ctx); +#define libssh2_sha1_init(x) _libssh2_sha1_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_sha1_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif +int _libssh2_sha1(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z) + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha256_ctx EVP_MD_CTX * +#else +#define libssh2_sha256_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_sha256_init(libssh2_sha256_ctx *ctx); +#define libssh2_sha256_init(x) _libssh2_sha256_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_sha256_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_sha256_update(ctx, data, len) \ + EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif +int _libssh2_sha256(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z) + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha384_ctx EVP_MD_CTX * +#else +#define libssh2_sha384_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_sha384_init(libssh2_sha384_ctx *ctx); +#define libssh2_sha384_init(x) _libssh2_sha384_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_sha384_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_sha384_update(ctx, data, len) \ + EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif +int _libssh2_sha384(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z) + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha512_ctx EVP_MD_CTX * +#else +#define libssh2_sha512_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_sha512_init(libssh2_sha512_ctx *ctx); +#define libssh2_sha512_init(x) _libssh2_sha512_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_sha512_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_sha512_update(ctx, data, len) \ + EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif +int _libssh2_sha512(const unsigned char *message, unsigned long len, + unsigned char *out); +#define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z) + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_md5_ctx EVP_MD_CTX * +#else +#define libssh2_md5_ctx EVP_MD_CTX +#endif + +/* returns 0 in case of failure */ +int _libssh2_md5_init(libssh2_md5_ctx *ctx); +#define libssh2_md5_init(x) _libssh2_md5_init(x) +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len) +#define libssh2_md5_final(ctx, out) do { \ + EVP_DigestFinal(ctx, out, NULL); \ + EVP_MD_CTX_free(ctx); \ + } while(0) +#else +#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len) +#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL) +#endif + +#ifdef HAVE_OPAQUE_STRUCTS +#define libssh2_hmac_ctx HMAC_CTX * +#define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new() +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_sha1(), NULL) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_md5(), NULL) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_ripemd160(), NULL) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_sha256(), NULL) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + HMAC_Init_ex(*(ctx), key, keylen, EVP_sha512(), NULL) + +#define libssh2_hmac_update(ctx, data, datalen) \ + HMAC_Update(ctx, data, datalen) +#define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL) +#define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx)) +#else +#define libssh2_hmac_ctx HMAC_CTX +#define libssh2_hmac_ctx_init(ctx) \ + HMAC_CTX_init(&ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha1(), NULL) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_md5(), NULL) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_ripemd160(), NULL) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha256(), NULL) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + HMAC_Init_ex(ctx, key, keylen, EVP_sha512(), NULL) + +#define libssh2_hmac_update(ctx, data, datalen) \ + HMAC_Update(&(ctx), data, datalen) +#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL) +#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx) +#endif + +extern void _libssh2_openssl_crypto_init(void); +extern void _libssh2_openssl_crypto_exit(void); +#define libssh2_crypto_init() _libssh2_openssl_crypto_init() +#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit() + +#define libssh2_rsa_ctx RSA + +#define _libssh2_rsa_free(rsactx) RSA_free(rsactx) + +#define libssh2_dsa_ctx DSA + +#define _libssh2_dsa_free(dsactx) DSA_free(dsactx) + +#if LIBSSH2_ECDSA +#define libssh2_ecdsa_ctx EC_KEY +#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx) +#define _libssh2_ec_key EC_KEY + +typedef enum { + LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1, + LIBSSH2_EC_CURVE_NISTP384 = NID_secp384r1, + LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1 +} +libssh2_curve_type; +#else +#define _libssh2_ec_key void +#endif /* LIBSSH2_ECDSA */ + +#if LIBSSH2_ED25519 +#define libssh2_ed25519_ctx EVP_PKEY +#define libssh2_x25519_ctx EVP_PKEY + +#define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx) +#define _libssh2_x25519_free(ctx) EVP_PKEY_free(ctx) +#endif /* ED25519 */ + +#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void) +#ifdef HAVE_OPAQUE_STRUCTS +#define _libssh2_cipher_ctx EVP_CIPHER_CTX * +#else +#define _libssh2_cipher_ctx EVP_CIPHER_CTX +#endif + +#define _libssh2_cipher_aes256 EVP_aes_256_cbc +#define _libssh2_cipher_aes192 EVP_aes_192_cbc +#define _libssh2_cipher_aes128 EVP_aes_128_cbc +#ifdef HAVE_EVP_AES_128_CTR +#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr +#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr +#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr +#else +#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr +#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr +#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr +#endif +#define _libssh2_cipher_blowfish EVP_bf_cbc +#define _libssh2_cipher_arcfour EVP_rc4 +#define _libssh2_cipher_cast5 EVP_cast5_cbc +#define _libssh2_cipher_3des EVP_des_ede3_cbc + +#ifdef HAVE_OPAQUE_STRUCTS +#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx)) +#else +#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx) +#endif + +#define _libssh2_bn BIGNUM +#define _libssh2_bn_ctx BN_CTX +#define _libssh2_bn_ctx_new() BN_CTX_new() +#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx) +#define _libssh2_bn_init() BN_new() +#define _libssh2_bn_init_from_bin() _libssh2_bn_init() +#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val) +#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn) +#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val) +#define _libssh2_bn_bytes(bn) BN_num_bytes(bn) +#define _libssh2_bn_bits(bn) BN_num_bits(bn) +#define _libssh2_bn_free(bn) BN_clear_free(bn) + +#define _libssh2_dh_ctx BIGNUM * +#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) +#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ + _libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) +#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ + _libssh2_dh_secret(dhctx, secret, f, p, bnctx) +#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) +extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx); +extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, + int group_order, + _libssh2_bn_ctx *bnctx); +extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p, + _libssh2_bn_ctx *bnctx); +extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); + +const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void); +const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void); +const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void); + +#endif /* __LIBSSH2_OPENSSL_H */ diff --git a/include/libssh2/os400qc3.h b/include/libssh2/os400qc3.h new file mode 100644 index 0000000..d915dc2 --- /dev/null +++ b/include/libssh2/os400qc3.h @@ -0,0 +1,391 @@ +#ifndef __LIBSSH2_OS400QC3_H +#define __LIBSSH2_OS400QC3_H +/* + * Copyright (C) 2015-2016 Patrick Monnerat, D+H + * Copyright (C) 2020 Patrick Monnerat . + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include +#include + +#include + + +/* Redefine character/string literals as always EBCDIC. */ +#undef Qc3_Alg_Token +#define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */ +#undef Qc3_Alg_Block_Cipher +#define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */ +#undef Qc3_Alg_Block_CipherAuth +#define Qc3_Alg_Block_CipherAuth \ + "\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */ +#undef Qc3_Alg_Stream_Cipher +#define Qc3_Alg_Stream_Cipher \ + "\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */ +#undef Qc3_Alg_Public_Key +#define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */ +#undef Qc3_Alg_Hash +#define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */ +#undef Qc3_Data +#define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */ +#undef Qc3_Array +#define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */ +#undef Qc3_Key_Token +#define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */ +#undef Qc3_Key_Parms +#define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */ +#undef Qc3_Key_KSLabel +#define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */ +#undef Qc3_Key_PKCS5 +#define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */ +#undef Qc3_Key_PEMCert +#define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */ +#undef Qc3_Key_CSLabel +#define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */ +#undef Qc3_Key_CSDN +#define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */ +#undef Qc3_Key_AppID +#define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */ + +#undef Qc3_ECB +#define Qc3_ECB '\xF0' /* '0' */ +#undef Qc3_CBC +#define Qc3_CBC '\xF1' /* '1' */ +#undef Qc3_OFB +#define Qc3_OFB '\xF2' /* '2' */ +#undef Qc3_CFB1Bit +#define Qc3_CFB1Bit '\xF3' /* '3' */ +#undef Qc3_CFB8Bit +#define Qc3_CFB8Bit '\xF4' /* '4' */ +#undef Qc3_CFB64Bit +#define Qc3_CFB64Bit '\xF5' /* '5' */ +#undef Qc3_CUSP +#define Qc3_CUSP '\xF6' /* '6' */ +#undef Qc3_CTR +#define Qc3_CTR '\xF7' /* '7' */ +#undef Qc3_CCM +#define Qc3_CCM '\xF8' /* '8' */ +#undef Qc3_No_Pad +#define Qc3_No_Pad '\xF0' /* '0' */ +#undef Qc3_Pad_Char +#define Qc3_Pad_Char '\xF1' /* '1' */ +#undef Qc3_Pad_Counter +#define Qc3_Pad_Counter '\xF2' /* '2' */ +#undef Qc3_PKCS1_00 +#define Qc3_PKCS1_00 '\xF0' /* '0' */ +#undef Qc3_PKCS1_01 +#define Qc3_PKCS1_01 '\xF1' /* '1' */ +#undef Qc3_PKCS1_02 +#define Qc3_PKCS1_02 '\xF2' /* '2' */ +#undef Qc3_ISO9796 +#define Qc3_ISO9796 '\xF3' /* '3' */ +#undef Qc3_Zero_Pad +#define Qc3_Zero_Pad '\xF4' /* '4' */ +#undef Qc3_ANSI_X931 +#define Qc3_ANSI_X931 '\xF5' /* '5' */ +#undef Qc3_OAEP +#define Qc3_OAEP '\xF6' /* '6' */ +#undef Qc3_Bin_String +#define Qc3_Bin_String '\xF0' /* '0' */ +#undef Qc3_BER_String +#define Qc3_BER_String '\xF1' /* '1' */ +#undef Qc3_MK_Struct +#define Qc3_MK_Struct '\xF3' /* '3' */ +#undef Qc3_KSLabel_Struct +#define Qc3_KSLabel_Struct '\xF4' /* '4' */ +#undef Qc3_PKCS5_Struct +#define Qc3_PKCS5_Struct '\xF5' /* '5' */ +#undef Qc3_PEMCert_String +#define Qc3_PEMCert_String '\xF6' /* '6' */ +#undef Qc3_CSLabel_String +#define Qc3_CSLabel_String '\xF7' /* '7' */ +#undef Qc3_CSDN_String +#define Qc3_CSDN_String '\xF8' /* '8' */ +#undef Qc3_Clear +#define Qc3_Clear '\xF0' /* '0' */ +#undef Qc3_Encrypted +#define Qc3_Encrypted '\xF1' /* '1' */ +#undef Qc3_MK_Encrypted +#define Qc3_MK_Encrypted '\xF2' /* '2' */ +#undef Qc3_Any_CSP +#define Qc3_Any_CSP '\xF0' /* '0' */ +#undef Qc3_Sfw_CSP +#define Qc3_Sfw_CSP '\xF1' /* '1' */ +#undef Qc3_Hdw_CSP +#define Qc3_Hdw_CSP '\xF2' /* '2' */ +#undef Qc3_Continue +#define Qc3_Continue '\xF0' /* '0' */ +#undef Qc3_Final +#define Qc3_Final '\xF1' /* '1' */ +#undef Qc3_MK_New +#define Qc3_MK_New '\xF0' /* '0' */ +#undef Qc3_MK_Current +#define Qc3_MK_Current '\xF1' /* '1' */ +#undef Qc3_MK_Old +#define Qc3_MK_Old '\xF2' /* '2' */ +#undef Qc3_MK_Pending +#define Qc3_MK_Pending '\xF3' /* '3' */ + + +/* Define which features are supported. */ +#define LIBSSH2_MD5 1 +#define LIBSSH2_HMAC_RIPEMD 0 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 0 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 0 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 0 +#define LIBSSH2_ECDSA 0 +#define LIBSSH2_ED25519 0 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA512_DIGEST_LENGTH 64 + +#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) + +#if LIBSSH2_ECDSA +#else +#define _libssh2_ec_key void +#endif + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: global handles structures. + * + *******************************************************************/ + +/* HMAC & private key algorithms support structure. */ +typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx; +struct _libssh2_os400qc3_crypto_ctx { + Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */ + Qc3_Format_KEYD0100_T key; /* Key. */ + _libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */ +}; + +typedef struct { /* Big number. */ + unsigned char * bignum; /* Number bits, little-endian. */ + unsigned int length; /* Length of bignum (# bytes). */ +} _libssh2_bn; + +typedef struct { /* Algorithm description. */ + char * fmt; /* Format of Qc3 structure. */ + int algo; /* Algorithm identifier. */ + unsigned char size; /* Block length. */ + unsigned char mode; /* Block mode. */ + int keylen; /* Key length. */ +} _libssh2_os400qc3_cipher_t; + +typedef struct { /* Diffie-Hellman context. */ + char token[8]; /* Context token. */ +} _libssh2_os400qc3_dh_ctx; + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: Define global types/codes. + * + *******************************************************************/ + +#define libssh2_crypto_init() +#define libssh2_crypto_exit() + +#define libssh2_sha1_ctx Qc3_Format_ALGD0100_T +#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T +#define libssh2_sha512_ctx Qc3_Format_ALGD0100_T +#define libssh2_md5_ctx Qc3_Format_ALGD0100_T +#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx +#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx + +#define libssh2_sha1_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA1) +#define libssh2_sha1_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_sha1_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_sha256_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA256) +#define libssh2_sha256_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_sha256_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_sha256(message, len, out) \ + libssh2_os400qc3_hash(message, len, out, \ + Qc3_SHA256) +#define libssh2_sha512_init(x) libssh2_os400qc3_hash_init(x, Qc3_SHA512) +#define libssh2_sha512_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_sha512_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_sha512(message, len, out) \ + libssh2_os400qc3_hash(message, len, out, \ + Qc3_SHA512) +#define libssh2_md5_init(x) libssh2_os400qc3_hash_init(x, Qc3_MD5) +#define libssh2_md5_update(ctx, data, len) \ + libssh2_os400qc3_hash_update(&(ctx), data, len) +#define libssh2_md5_final(ctx, out) \ + libssh2_os400qc3_hash_final(&(ctx), out) +#define libssh2_hmac_ctx_init(ctx) \ + memset((char *) &(ctx), 0, \ + sizeof(libssh2_hmac_ctx)) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_MD5, \ + MD5_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_SHA1, \ + SHA_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_SHA256, \ + SHA256_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + libssh2_os400qc3_hmac_init(ctx, Qc3_SHA512, \ + SHA512_DIGEST_LENGTH, \ + key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + libssh2_os400qc3_hmac_update(&(ctx), \ + data, datalen) +#define libssh2_hmac_final(ctx, data) \ + libssh2_os400qc3_hmac_final(&(ctx), data) +#define libssh2_hmac_cleanup(ctx) \ + _libssh2_os400qc3_crypto_dtor(ctx) + + +#define _libssh2_bn_ctx int /* Not used. */ + +#define _libssh2_bn_ctx_new() 0 +#define _libssh2_bn_ctx_free(bnctx) ((void) 0) + +#define _libssh2_bn_init_from_bin() _libssh2_bn_init() +#define _libssh2_bn_bytes(bn) ((bn)->length) + +#define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name +#define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ + Qc3_CBC, 16} +#define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 24, \ + Qc3_CBC, 24} +#define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 32, \ + Qc3_CBC, 32} +#define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \ + Qc3_CTR, 16} +#define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 24, \ + Qc3_CTR, 24} +#define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 32, \ + Qc3_CTR, 32} +#define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 0, \ + Qc3_CBC, 24} +#define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 0, 0, 16} + +#define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx) + +#define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx +#define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \ + free((char *) ctx)) +#define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \ + (len) * sizeof(struct iovec)) +#define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \ + _libssh2_os400qc3_rsa_sha1_signv(session, sig, siglen, \ + count, vector, ctx) + +#define _libssh2_dh_ctx _libssh2_os400qc3_dh_ctx +#define libssh2_dh_init(dhctx) _libssh2_os400qc3_dh_init(dhctx) +#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ + _libssh2_os400qc3_dh_key_pair(dhctx, public, g, p, group_order) +#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ + _libssh2_os400qc3_dh_secret(dhctx, secret, f, p) +#define libssh2_dh_dtor(dhctx) _libssh2_os400qc3_dh_dtor(dhctx) + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: Support procedure prototypes. + * + *******************************************************************/ + +extern _libssh2_bn * _libssh2_bn_init(void); +extern void _libssh2_bn_free(_libssh2_bn *bn); +extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn); +extern int _libssh2_bn_from_bin(_libssh2_bn *bn, int len, + const unsigned char *v); +extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val); +extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val); +extern void _libssh2_random(unsigned char *buf, int len); +extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x); +extern int libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, + unsigned int algo); +extern void libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, + const unsigned char *data, + int len); +extern void libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, + unsigned char *out); +extern int libssh2_os400qc3_hash(const unsigned char *message, + unsigned long len, unsigned char *out, + unsigned int algo); +extern void libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *x, + int algo, size_t minkeylen, + void *key, int keylen); +extern void libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, + const unsigned char *data, + int len); +extern void libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, + unsigned char *out); +extern int _libssh2_os400qc3_rsa_sha1_signv(LIBSSH2_SESSION *session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec vector[], + libssh2_rsa_ctx *ctx); +extern void _libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx); +extern int _libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx, + _libssh2_bn *public, + _libssh2_bn *g, + _libssh2_bn *p, int group_order); +extern int _libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx, + _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p); +extern void _libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx); + +#endif /* __LIBSSH2_OS400QC3_H */ + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/include/libssh2/packet.h b/include/libssh2/packet.h new file mode 100644 index 0000000..79018bc --- /dev/null +++ b/include/libssh2/packet.h @@ -0,0 +1,76 @@ +#ifndef __LIBSSH2_PACKET_H +#define __LIBSSH2_PACKET_H +/* + * Copyright (C) 2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +int _libssh2_packet_read(LIBSSH2_SESSION * session); + +int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len); + +int _libssh2_packet_askv(LIBSSH2_SESSION * session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len); +int _libssh2_packet_require(LIBSSH2_SESSION * session, + unsigned char packet_type, unsigned char **data, + size_t *data_len, int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_require_state_t * state); +int _libssh2_packet_requirev(LIBSSH2_SESSION *session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_requirev_state_t * state); +int _libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state); +int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long data_len); +int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate); + +#endif /* __LIBSSH2_PACKET_H */ diff --git a/include/libssh2/session.h b/include/libssh2/session.h new file mode 100644 index 0000000..9f8f2c7 --- /dev/null +++ b/include/libssh2/session.h @@ -0,0 +1,93 @@ +#ifndef __LIBSSH2_SESSION_H +#define __LIBSSH2_SESSION_H +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2010 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* Conveniance-macros to allow code like this; + + int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) ); + + int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) ); + + The point of course being to make sure that while in non-blocking mode + these always return no matter what the return code is, but in blocking mode + it blocks if EAGAIN is the reason for the return from the underlying + function. + +*/ +#define BLOCK_ADJUST(rc, sess, x) \ + do { \ + time_t entry_time = time(NULL); \ + do { \ + rc = x; \ + /* the order of the check below is important to properly deal with \ + the case when the 'sess' is freed */ \ + if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \ + break; \ + rc = _libssh2_wait_socket(sess, entry_time); \ + } while(!rc); \ + } while(0) + +/* + * For functions that returns a pointer, we need to check if the API is + * non-blocking and return immediately. If the pointer is non-NULL we return + * immediately. If the API is blocking and we get a NULL we check the errno + * and *only* if that is EAGAIN we loop and wait for socket action. + */ +#define BLOCK_ADJUST_ERRNO(ptr, sess, x) \ + do { \ + time_t entry_time = time(NULL); \ + int rc; \ + do { \ + ptr = x; \ + if(!sess->api_block_mode || \ + (ptr != NULL) || \ + (libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \ + break; \ + rc = _libssh2_wait_socket(sess, entry_time); \ + } while(!rc); \ + } while(0) + + +int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time); + +/* this is the lib-internal set blocking function */ +int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking); + +#endif /* __LIBSSH2_SESSION_H */ diff --git a/include/libssh2/sftp.h b/include/libssh2/sftp.h new file mode 100644 index 0000000..129b8f0 --- /dev/null +++ b/include/libssh2/sftp.h @@ -0,0 +1,238 @@ +#ifndef __LIBSSH2_SFTP_H +#define __LIBSSH2_SFTP_H +/* + * Copyright (C) 2010 - 2012 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +/* + * MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the + * amount of data sent in each FXP_WRITE packet + */ +#define MAX_SFTP_OUTGOING_SIZE 30000 + +/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ + * packets. + */ +#define MAX_SFTP_READ_SIZE 30000 + +struct sftp_pipeline_chunk { + struct list_node node; + libssh2_uint64_t offset; /* READ: offset at which to start reading + WRITE: not used */ + size_t len; /* WRITE: size of the data to write + READ: how many bytes that was asked for */ + size_t sent; + ssize_t lefttosend; /* if 0, the entire packet has been sent off */ + uint32_t request_id; + unsigned char packet[1]; /* data */ +}; + +struct sftp_zombie_requests { + struct list_node node; + uint32_t request_id; +}; + +#ifndef MIN +#define MIN(x,y) ((x)<(y)?(x):(y)) +#endif + +struct _LIBSSH2_SFTP_PACKET +{ + struct list_node node; /* linked list header */ + uint32_t request_id; + unsigned char *data; + size_t data_len; /* payload size */ +}; + +typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET; + +#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */ + +struct _LIBSSH2_SFTP_HANDLE +{ + struct list_node node; + + LIBSSH2_SFTP *sftp; + + char handle[SFTP_HANDLE_MAXLEN]; + size_t handle_len; + + enum { + LIBSSH2_SFTP_HANDLE_FILE, + LIBSSH2_SFTP_HANDLE_DIR + } handle_type; + + union _libssh2_sftp_handle_data + { + struct _libssh2_sftp_handle_file_data + { + libssh2_uint64_t offset; + libssh2_uint64_t offset_sent; + size_t acked; /* container for acked data that hasn't been + returned to caller yet, used for sftp_write */ + + /* 'data' is used by sftp_read() and is allocated data that has + been received already from the server but wasn't returned to + the caller yet. It is of size 'data_len' and 'data_left is the + number of bytes not yet returned, counted from the end of the + buffer. */ + unsigned char *data; + size_t data_len; + size_t data_left; + + char eof; /* we have read to the end */ + } file; + struct _libssh2_sftp_handle_dir_data + { + uint32_t names_left; + void *names_packet; + char *next_name; + size_t names_packet_len; + } dir; + } u; + + /* State variables used in libssh2_sftp_close_handle() */ + libssh2_nonblocking_states close_state; + uint32_t close_request_id; + unsigned char *close_packet; + + /* list of outstanding packets sent to server */ + struct list_head packet_list; + +}; + +struct _LIBSSH2_SFTP +{ + LIBSSH2_CHANNEL *channel; + + uint32_t request_id, version; + + struct list_head packets; + + /* List of FXP_READ responses to ignore because EOF already received. */ + struct list_head zombie_requests; + + /* a list of _LIBSSH2_SFTP_HANDLE structs */ + struct list_head sftp_handles; + + uint32_t last_errno; + + /* Holder for partial packet, use in libssh2_sftp_packet_read() */ + unsigned char partial_size[4]; /* buffer for size field */ + size_t partial_size_len; /* size field length */ + unsigned char *partial_packet; /* The data */ + uint32_t partial_len; /* Desired number of bytes */ + size_t partial_received; /* Bytes received so far */ + + /* Time that libssh2_sftp_packet_requirev() started reading */ + time_t requirev_start; + + /* State variables used in libssh2_sftp_open_ex() */ + libssh2_nonblocking_states open_state; + unsigned char *open_packet; + uint32_t open_packet_len; /* 32 bit on the wire */ + size_t open_packet_sent; + uint32_t open_request_id; + + /* State variable used in sftp_read() */ + libssh2_nonblocking_states read_state; + + /* State variable used in sftp_packet_read() */ + libssh2_nonblocking_states packet_state; + + /* State variable used in sftp_write() */ + libssh2_nonblocking_states write_state; + + /* State variables used in sftp_fsync() */ + libssh2_nonblocking_states fsync_state; + unsigned char *fsync_packet; + uint32_t fsync_request_id; + + /* State variables used in libssh2_sftp_readdir() */ + libssh2_nonblocking_states readdir_state; + unsigned char *readdir_packet; + uint32_t readdir_request_id; + + /* State variables used in libssh2_sftp_fstat_ex() */ + libssh2_nonblocking_states fstat_state; + unsigned char *fstat_packet; + uint32_t fstat_request_id; + + /* State variables used in libssh2_sftp_unlink_ex() */ + libssh2_nonblocking_states unlink_state; + unsigned char *unlink_packet; + uint32_t unlink_request_id; + + /* State variables used in libssh2_sftp_rename_ex() */ + libssh2_nonblocking_states rename_state; + unsigned char *rename_packet; + unsigned char *rename_s; + uint32_t rename_request_id; + + /* State variables used in libssh2_sftp_fstatvfs() */ + libssh2_nonblocking_states fstatvfs_state; + unsigned char *fstatvfs_packet; + uint32_t fstatvfs_request_id; + + /* State variables used in libssh2_sftp_statvfs() */ + libssh2_nonblocking_states statvfs_state; + unsigned char *statvfs_packet; + uint32_t statvfs_request_id; + + /* State variables used in libssh2_sftp_mkdir() */ + libssh2_nonblocking_states mkdir_state; + unsigned char *mkdir_packet; + uint32_t mkdir_request_id; + + /* State variables used in libssh2_sftp_rmdir() */ + libssh2_nonblocking_states rmdir_state; + unsigned char *rmdir_packet; + uint32_t rmdir_request_id; + + /* State variables used in libssh2_sftp_stat() */ + libssh2_nonblocking_states stat_state; + unsigned char *stat_packet; + uint32_t stat_request_id; + + /* State variables used in libssh2_sftp_symlink() */ + libssh2_nonblocking_states symlink_state; + unsigned char *symlink_packet; + uint32_t symlink_request_id; +}; + +#endif /* __LIBSSH2_SFTP_H */ diff --git a/include/libssh2/transport.h b/include/libssh2/transport.h new file mode 100644 index 0000000..7d395d0 --- /dev/null +++ b/include/libssh2/transport.h @@ -0,0 +1,86 @@ +#ifndef __LIBSSH2_TRANSPORT_H +#define __LIBSSH2_TRANSPORT_H +/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2009-2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file handles reading and writing to the SECSH transport layer. RFC4253. + */ + +#include "libssh2_priv.h" +#include "packet.h" + + +/* + * libssh2_transport_send + * + * Send a packet, encrypting it and adding a MAC code if necessary + * Returns 0 on success, non-zero on failure. + * + * The data is provided as _two_ data areas that are combined by this + * function. The 'data' part is sent immediately before 'data2'. 'data2' can + * be set to NULL (or data2_len to 0) to only use a single part. + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was + * not sent yet. If it does so, the caller should call this function again as + * soon as it is likely that more data can be sent, and this function MUST + * then be called with the same argument set (same data pointer and same + * data_len) until ERROR_NONE or failure is returned. + * + * This function DOES NOT call _libssh2_error() on any errors. + */ +int _libssh2_transport_send(LIBSSH2_SESSION *session, + const unsigned char *data, size_t data_len, + const unsigned char *data2, size_t data2_len); + +/* + * _libssh2_transport_read + * + * Collect a packet into the input brigade block only controls whether or not + * to wait for a packet to start. + * + * Returns packet type added to input brigade (PACKET_NONE if nothing added), + * or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full + * packet. + */ + +/* + * This function reads the binary stream as specified in chapter 6 of RFC4253 + * "The Secure Shell (SSH) Transport Layer Protocol" + */ +int _libssh2_transport_read(LIBSSH2_SESSION * session); + +#endif /* __LIBSSH2_TRANSPORT_H */ diff --git a/include/libssh2/userauth.h b/include/libssh2/userauth.h new file mode 100644 index 0000000..6b402dd --- /dev/null +++ b/include/libssh2/userauth.h @@ -0,0 +1,51 @@ +#ifndef __LIBSSH2_USERAUTH_H +#define __LIBSSH2_USERAUTH_H +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2009-2010 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +int +_libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const unsigned char *pubkeydata, + unsigned long pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC + ((*sign_callback)), + void *abstract); + +#endif /* __LIBSSH2_USERAUTH_H */ diff --git a/include/libssh2/wincng.h b/include/libssh2/wincng.h new file mode 100644 index 0000000..c817f09 --- /dev/null +++ b/include/libssh2/wincng.h @@ -0,0 +1,575 @@ +#ifndef __LIBSSH2_WINCNG_H +#define __LIBSSH2_WINCNG_H +/* + * Copyright (C) 2013-2020 Marc Hoersken + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* required for cross-compilation against the w64 mingw-runtime package */ +#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) +#undef _WIN32_WINNT +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + +#include +#include + + +#define LIBSSH2_MD5 1 + +#define LIBSSH2_HMAC_RIPEMD 0 +#define LIBSSH2_HMAC_SHA256 1 +#define LIBSSH2_HMAC_SHA512 1 + +#define LIBSSH2_AES 1 +#define LIBSSH2_AES_CTR 1 +#define LIBSSH2_BLOWFISH 0 +#define LIBSSH2_RC4 1 +#define LIBSSH2_CAST 0 +#define LIBSSH2_3DES 1 + +#define LIBSSH2_RSA 1 +#define LIBSSH2_DSA 1 +#define LIBSSH2_ECDSA 0 +#define LIBSSH2_ED25519 0 + +#define MD5_DIGEST_LENGTH 16 +#define SHA_DIGEST_LENGTH 20 +#define SHA256_DIGEST_LENGTH 32 +#define SHA512_DIGEST_LENGTH 64 + +#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1) + +#if LIBSSH2_ECDSA +#else +#define _libssh2_ec_key void +#endif + +/*******************************************************************/ +/* + * Windows CNG backend: Global context handles + */ + +struct _libssh2_wincng_ctx { + BCRYPT_ALG_HANDLE hAlgRNG; + BCRYPT_ALG_HANDLE hAlgHashMD5; + BCRYPT_ALG_HANDLE hAlgHashSHA1; + BCRYPT_ALG_HANDLE hAlgHashSHA256; + BCRYPT_ALG_HANDLE hAlgHashSHA512; + BCRYPT_ALG_HANDLE hAlgHmacMD5; + BCRYPT_ALG_HANDLE hAlgHmacSHA1; + BCRYPT_ALG_HANDLE hAlgHmacSHA256; + BCRYPT_ALG_HANDLE hAlgHmacSHA512; + BCRYPT_ALG_HANDLE hAlgRSA; + BCRYPT_ALG_HANDLE hAlgDSA; + BCRYPT_ALG_HANDLE hAlgAES_CBC; + BCRYPT_ALG_HANDLE hAlgAES_ECB; + BCRYPT_ALG_HANDLE hAlgRC4_NA; + BCRYPT_ALG_HANDLE hAlg3DES_CBC; +}; + +extern struct _libssh2_wincng_ctx _libssh2_wincng; + + +/*******************************************************************/ +/* + * Windows CNG backend: Generic functions + */ + +void _libssh2_wincng_init(void); +void _libssh2_wincng_free(void); + +#define libssh2_crypto_init() \ + _libssh2_wincng_init() +#define libssh2_crypto_exit() \ + _libssh2_wincng_free() + +#define _libssh2_random(buf, len) \ + _libssh2_wincng_random(buf, len) + +#define libssh2_prepare_iovec(vec, len) /* Empty. */ + + +/*******************************************************************/ +/* + * Windows CNG backend: Hash structure + */ + +typedef struct __libssh2_wincng_hash_ctx { + BCRYPT_HASH_HANDLE hHash; + unsigned char *pbHashObject; + unsigned long dwHashObject; + unsigned long cbHash; +} _libssh2_wincng_hash_ctx; + +/* + * Windows CNG backend: Hash functions + */ + +#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx +#define libssh2_sha1_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \ + SHA_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_sha1_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha1_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_sha1(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \ + hash, SHA_DIGEST_LENGTH) + +#define libssh2_sha256_ctx _libssh2_wincng_hash_ctx +#define libssh2_sha256_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \ + SHA256_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_sha256_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha256_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_sha256(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \ + hash, SHA256_DIGEST_LENGTH) + +#define libssh2_sha512_ctx _libssh2_wincng_hash_ctx +#define libssh2_sha512_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \ + SHA512_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_sha512_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_sha512_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_sha512(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \ + hash, SHA512_DIGEST_LENGTH) + +#define libssh2_md5_ctx _libssh2_wincng_hash_ctx +#define libssh2_md5_init(ctx) \ + (_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \ + MD5_DIGEST_LENGTH, NULL, 0) == 0) +#define libssh2_md5_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_md5_final(ctx, hash) \ + _libssh2_wincng_hash_final(&ctx, hash) +#define libssh2_md5(data, datalen, hash) \ + _libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashMD5, \ + hash, MD5_DIGEST_LENGTH) + +/* + * Windows CNG backend: HMAC functions + */ + +#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx +#define libssh2_hmac_ctx_init(ctx) +#define libssh2_hmac_sha1_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA1, \ + SHA_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_md5_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacMD5, \ + MD5_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_ripemd160_init(ctx, key, keylen) + /* not implemented */ +#define libssh2_hmac_sha256_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA256, \ + SHA256_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_sha512_init(ctx, key, keylen) \ + _libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHmacSHA512, \ + SHA512_DIGEST_LENGTH, key, keylen) +#define libssh2_hmac_update(ctx, data, datalen) \ + _libssh2_wincng_hash_update(&ctx, (unsigned char *) data, datalen) +#define libssh2_hmac_final(ctx, hash) \ + _libssh2_wincng_hmac_final(&ctx, hash) +#define libssh2_hmac_cleanup(ctx) \ + _libssh2_wincng_hmac_cleanup(ctx) + + +/*******************************************************************/ +/* + * Windows CNG backend: Key Context structure + */ + +typedef struct __libssh2_wincng_key_ctx { + BCRYPT_KEY_HANDLE hKey; + unsigned char *pbKeyObject; + unsigned long cbKeyObject; +} _libssh2_wincng_key_ctx; + + +/* + * Windows CNG backend: RSA functions + */ + +#define libssh2_rsa_ctx _libssh2_wincng_key_ctx +#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) \ + _libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \ + d, d_len, p, p_len, q, q_len, \ + e1, e1_len, e2, e2_len, c, c_len) +#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \ + _libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase) +#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) \ + _libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \ + filedata_len, passphrase) +#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \ + _libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) +#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \ + _libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) +#define _libssh2_rsa_free(rsactx) \ + _libssh2_wincng_rsa_free(rsactx) + +/* + * Windows CNG backend: DSA functions + */ + +#define libssh2_dsa_ctx _libssh2_wincng_key_ctx +#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \ + g, g_len, y, y_len, x, x_len) \ + _libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \ + g, g_len, y, y_len, x, x_len) +#define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \ + _libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase) +#define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \ + filedata_len, passphrase) \ + _libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \ + filedata_len, passphrase) +#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \ + _libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig) +#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \ + _libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len) +#define _libssh2_dsa_free(dsactx) \ + _libssh2_wincng_dsa_free(dsactx) + +/* + * Windows CNG backend: Key functions + */ + +#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \ + _libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) +#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) \ + _libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \ + pk, pk_len, pw) + + +/*******************************************************************/ +/* + * Windows CNG backend: Cipher Context structure + */ + +struct _libssh2_wincng_cipher_ctx { + BCRYPT_KEY_HANDLE hKey; + unsigned char *pbKeyObject; + unsigned char *pbIV; + unsigned char *pbCtr; + unsigned long dwKeyObject; + unsigned long dwIV; + unsigned long dwBlockLength; + unsigned long dwCtrLength; +}; + +#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx + +/* + * Windows CNG backend: Cipher Type structure + */ + +struct _libssh2_wincng_cipher_type { + BCRYPT_ALG_HANDLE *phAlg; + unsigned long dwKeyLength; + int useIV; /* TODO: Convert to bool when a C89 compatible bool type + is defined */ + int ctrMode; +}; + +#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type + +#define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 } +#define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 } +#define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 } +#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 } +#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 } +#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 } +#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 } +#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 } + +/* + * Windows CNG backend: Cipher functions + */ + +#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \ + _libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt) +#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \ + _libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen) +#define _libssh2_cipher_dtor(ctx) \ + _libssh2_wincng_cipher_dtor(ctx) + +/*******************************************************************/ +/* + * Windows CNG backend: BigNumber Context + */ + +#define _libssh2_bn_ctx int /* not used */ +#define _libssh2_bn_ctx_new() 0 /* not used */ +#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */ + + +/*******************************************************************/ +/* + * Windows CNG backend: BigNumber structure + */ + +struct _libssh2_wincng_bignum { + unsigned char *bignum; + unsigned long length; +}; + +#define _libssh2_bn struct _libssh2_wincng_bignum + +/* + * Windows CNG backend: BigNumber functions + */ + +_libssh2_bn *_libssh2_wincng_bignum_init(void); + +#define _libssh2_bn_init() \ + _libssh2_wincng_bignum_init() +#define _libssh2_bn_init_from_bin() \ + _libssh2_bn_init() +#define _libssh2_bn_set_word(bn, word) \ + _libssh2_wincng_bignum_set_word(bn, word) +#define _libssh2_bn_from_bin(bn, len, bin) \ + _libssh2_wincng_bignum_from_bin(bn, len, bin) +#define _libssh2_bn_to_bin(bn, bin) \ + _libssh2_wincng_bignum_to_bin(bn, bin) +#define _libssh2_bn_bytes(bn) bn->length +#define _libssh2_bn_bits(bn) \ + _libssh2_wincng_bignum_bits(bn) +#define _libssh2_bn_free(bn) \ + _libssh2_wincng_bignum_free(bn) + +/* + * Windows CNG backend: Diffie-Hellman support + */ + +#define _libssh2_dh_ctx struct _libssh2_wincng_bignum * +#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx) +#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \ + _libssh2_dh_key_pair(dhctx, public, g, p, group_order) +#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \ + _libssh2_dh_secret(dhctx, secret, f, p) +#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx) + +/*******************************************************************/ +/* + * Windows CNG backend: forward declarations + */ +void _libssh2_wincng_init(void); +void _libssh2_wincng_free(void); +int _libssh2_wincng_random(void *buf, int len); + +int +_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, + BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, + unsigned char *key, unsigned long keylen); +int +_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, + const unsigned char *data, unsigned long datalen); +int +_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash); +int +_libssh2_wincng_hash(unsigned char *data, unsigned long datalen, + BCRYPT_ALG_HANDLE hAlg, + unsigned char *hash, unsigned long hashlen); + +int +_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash); +void +_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx); + +int +_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len, + unsigned long flags); + +int +_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen); +int +_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase); +int +_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +int +_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len); +int +_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len); +void +_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa); + +#if LIBSSH2_DSA +int +_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *xdata, + unsigned long xlen); +int +_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase); +int +_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); +int +_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, + const unsigned char *sig_fixed, + const unsigned char *m, + unsigned long m_len); +int +_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig_fixed); +void +_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa); +#endif + +int +_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase); +int +_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase); + +int +_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + unsigned char *iv, + unsigned char *secret, + int encrypt); +int +_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + int encrypt, + unsigned char *block, + size_t blocklen); +void +_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx); + +_libssh2_bn * +_libssh2_wincng_bignum_init(void); +int +_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word); +unsigned long +_libssh2_wincng_bignum_bits(const _libssh2_bn *bn); +void +_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, + const unsigned char *bin); +void +_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin); +void +_libssh2_wincng_bignum_free(_libssh2_bn *bn); +extern void +_libssh2_dh_init(_libssh2_dh_ctx *dhctx); +extern int +_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order); +extern int +_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p); +extern void +_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx); + +#endif /* __LIBSSH2_WINCNG_H */ diff --git a/include/module.mk b/include/module.mk new file mode 100644 index 0000000..85a9382 --- /dev/null +++ b/include/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/copyright.h \ + include/pgAdmin3.h \ + include/postgres.h \ + include/precomp.h \ + include/svnversion.h \ + include/version.h + +EXTRA_DIST += \ + include/module.mk + +include include/agent/module.mk +include include/db/module.mk +include include/dd/module.mk +include include/dlg/module.mk +include include/debugger/module.mk +include include/ctl/module.mk +include include/frm/module.mk +include include/images/module.mk +include include/parser/module.mk +include include/pgscript/module.mk +include include/schema/module.mk +include include/slony/module.mk +include include/gqb/module.mk +include include/hotdraw/module.mk +include include/utils/module.mk +include include/ogl/module.mk +include include/libssh2/module.mk + diff --git a/include/ogl/basic.h b/include/ogl/basic.h new file mode 100644 index 0000000..9a17a70 --- /dev/null +++ b/include/ogl/basic.h @@ -0,0 +1,963 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basic.h - Basic OGL classes and definitions +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_BASIC_H_ +#define _OGL_BASIC_H_ + +#ifndef wxUSE_DEPRECATED +#define wxUSE_DEPRECATED 0 +#endif + +#if wxUSE_DEPRECATED +#include +#endif + +#define OGL_VERSION 2.0 + +#ifndef DEFAULT_MOUSE_TOLERANCE +#define DEFAULT_MOUSE_TOLERANCE 3 +#endif + +// Key identifiers +#define KEY_SHIFT 1 +#define KEY_CTRL 2 + +// Arrow styles + +#define ARROW_NONE 0 +#define ARROW_END 1 +#define ARROW_BOTH 2 +#define ARROW_MIDDLE 3 +#define ARROW_START 4 + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +// Types of formatting: can be combined in a bit list +#define FORMAT_NONE 0 +// Left justification +#define FORMAT_CENTRE_HORIZ 1 +// Centre horizontally +#define FORMAT_CENTRE_VERT 2 +// Centre vertically +#define FORMAT_SIZE_TO_CONTENTS 4 +// Resize shape to contents + +// Shadow mode +#define SHADOW_NONE 0 +#define SHADOW_LEFT 1 +#define SHADOW_RIGHT 2 + +/* + * Declare types + * + */ + +#define SHAPE_BASIC wxTYPE_USER + 1 +#define SHAPE_RECTANGLE wxTYPE_USER + 2 +#define SHAPE_ELLIPSE wxTYPE_USER + 3 +#define SHAPE_POLYGON wxTYPE_USER + 4 +#define SHAPE_CIRCLE wxTYPE_USER + 5 +#define SHAPE_LINE wxTYPE_USER + 6 +#define SHAPE_DIVIDED_RECTANGLE wxTYPE_USER + 8 +#define SHAPE_COMPOSITE wxTYPE_USER + 9 +#define SHAPE_CONTROL_POINT wxTYPE_USER + 10 +#define SHAPE_DRAWN wxTYPE_USER + 11 +#define SHAPE_DIVISION wxTYPE_USER + 12 +#define SHAPE_LABEL_OBJECT wxTYPE_USER + 13 +#define SHAPE_BITMAP wxTYPE_USER + 14 +#define SHAPE_DIVIDED_OBJECT_CONTROL_POINT wxTYPE_USER + 15 + +#define OBJECT_REGION wxTYPE_USER + 20 + +#define OP_CLICK_LEFT 1 +#define OP_CLICK_RIGHT 2 +#define OP_DRAG_LEFT 4 +#define OP_DRAG_RIGHT 8 + +#define OP_ALL (OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_LEFT | OP_DRAG_RIGHT) + +// Attachment modes +#define ATTACHMENT_MODE_NONE 0 +#define ATTACHMENT_MODE_EDGE 1 +#define ATTACHMENT_MODE_BRANCHING 2 + +// Sub-modes for branching attachment mode +#define BRANCHING_ATTACHMENT_NORMAL 1 +#define BRANCHING_ATTACHMENT_BLOB 2 + +class wxShapeTextLine; +class wxShapeCanvas; +class wxLineShape; +class wxControlPoint; +class wxShapeRegion; +class wxShape; + +#if wxUSE_PROLOGIO +class WXDLLEXPORT wxExpr; +class WXDLLEXPORT wxExprDatabase; +#endif + +// Round up +#define WXROUND(x) ( (long) (x + 0.5) ) + + +// logical function to use when drawing rubberband boxes, etc. +#define OGLRBLF wxINVERT + + + +class wxShapeEvtHandler: public wxObject, public wxClientDataContainer +{ + DECLARE_DYNAMIC_CLASS(wxShapeEvtHandler) + +public: + wxShapeEvtHandler(wxShapeEvtHandler *prev = NULL, wxShape *shape = NULL); + virtual ~wxShapeEvtHandler(); + + inline void SetShape(wxShape *sh) + { + m_handlerShape = sh; + } + inline wxShape *GetShape() const + { + return m_handlerShape; + } + + inline void SetPreviousHandler(wxShapeEvtHandler *handler) + { + m_previousHandler = handler; + } + inline wxShapeEvtHandler *GetPreviousHandler() const + { + return m_previousHandler; + } + + // This is called when the _shape_ is deleted. + virtual void OnDelete(); + virtual void OnDraw(wxDC &dc); + virtual void OnDrawContents(wxDC &dc); + virtual void OnDrawBranches(wxDC &dc, bool erase = FALSE); + virtual void OnMoveLinks(); + virtual void OnHighlight(wxDC &dc); + virtual void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnLeftDoubleClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnSize(double x, double y); + virtual bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + virtual void OnMovePost(double x, double y, double old_x, double old_y, bool display = TRUE); + + virtual void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + virtual void OnDrawControlPoints(wxDC &dc); + virtual void OnMoveLink(bool moveControlPoints = TRUE); + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + virtual void OnBeginSize(double WXUNUSED(w), double WXUNUSED(h)) { } + virtual void OnEndSize(double WXUNUSED(w), double WXUNUSED(h)) { } + + // Can override this to prevent or intercept line reordering. + virtual void OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering); + + // Creates a copy of this event handler. + wxShapeEvtHandler *CreateNewCopy(); + + // Does the copy - override for new event handlers which might store + // app-specific data. + virtual void CopyData(wxShapeEvtHandler &WXUNUSED(copy)) {}; + +private: + wxShapeEvtHandler *m_previousHandler; + wxShape *m_handlerShape; +}; + +class wxShape: public wxShapeEvtHandler +{ + DECLARE_ABSTRACT_CLASS(wxShape) + +public: + + wxShape(wxShapeCanvas *can = NULL); + virtual ~wxShape(); + virtual void GetBoundingBoxMax(double *width, double *height); + virtual void GetBoundingBoxMin(double *width, double *height) = 0; + virtual bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + inline wxShapeCanvas *GetCanvas() + { + return m_canvas; + } + virtual void SetCanvas(wxShapeCanvas *the_canvas); + virtual void AddToCanvas(wxShapeCanvas *the_canvas, wxShape *addAfter = NULL); + virtual void InsertInCanvas(wxShapeCanvas *the_canvas); + + virtual void RemoveFromCanvas(wxShapeCanvas *the_canvas); + inline double GetX() const + { + return m_xpos; + } + inline double GetY() const + { + return m_ypos; + } + inline void SetX(double x) + { + m_xpos = x; + } + inline void SetY(double y) + { + m_ypos = y; + } + + inline wxShape *GetParent() const + { + return m_parent; + } + inline void SetParent(wxShape *p) + { + m_parent = p; + } + wxShape *GetTopAncestor(); + inline wxList &GetChildren() + { + return m_children; + } + + virtual void OnDraw(wxDC &dc); + virtual void OnDrawContents(wxDC &dc); + virtual void OnMoveLinks(); + virtual void Unlink() { }; + void SetDrawHandles(bool drawH); + inline bool GetDrawHandles() + { + return m_drawHandles; + } + virtual void OnHighlight(wxDC &dc); + virtual void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnLeftDoubleClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys) = 0, int WXUNUSED(attachment) = 0) {} + virtual void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + virtual void OnSize(double x, double y); + virtual bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + virtual void OnMovePost(double x, double y, double old_x, double old_y, bool display = TRUE); + + virtual void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); + virtual void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + virtual void OnDrawControlPoints(wxDC &dc); + + virtual void OnBeginSize(double WXUNUSED(w), double WXUNUSED(h)) { } + virtual void OnEndSize(double WXUNUSED(w), double WXUNUSED(h)) { } + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); // Erase if draw false + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + virtual void MakeControlPoints(); + virtual void DeleteControlPoints(wxDC *dc = NULL); + virtual void ResetControlPoints(); + + // Remove any child shapes before deleting shape. Currently for benefit of line shape. + virtual void RemoveChildren() {} + + inline wxShapeEvtHandler *GetEventHandler() + { + return m_eventHandler; + } + inline void SetEventHandler(wxShapeEvtHandler *handler) + { + m_eventHandler = handler; + } + + // Mandatory control points, e.g. the divided line moving handles + // should appear even if a child of the 'selected' image + virtual void MakeMandatoryControlPoints(); + virtual void ResetMandatoryControlPoints(); + + inline virtual bool Recompute() + { + return TRUE; + }; + // Calculate size recursively, if size changes. Size might depend on children. + inline virtual void CalculateSize() { }; + virtual void Select(bool select = TRUE); + virtual void SetHighlight(bool hi = TRUE, bool recurse = FALSE); + inline virtual bool IsHighlighted() const + { + return m_highlighted; + }; + virtual bool Selected() const; + virtual bool AncestorSelected() const; + void SetSensitivityFilter(int sens = OP_ALL, bool recursive = FALSE); + int GetSensitivityFilter() const + { + return m_sensitivity; + } + void SetDraggable(bool drag, bool recursive = FALSE); + inline void SetFixedSize(bool x, bool y) + { + m_fixedWidth = x; + m_fixedHeight = y; + }; + inline void GetFixedSize(bool *x, bool *y) const + { + *x = m_fixedWidth; + *y = m_fixedHeight; + }; + inline bool GetFixedWidth() const + { + return m_fixedWidth; + } + inline bool GetFixedHeight() const + { + return m_fixedHeight; + } + inline void SetSpaceAttachments(bool sp) + { + m_spaceAttachments = sp; + }; + inline bool GetSpaceAttachments() const + { + return m_spaceAttachments; + }; + void SetShadowMode(int mode, bool redraw = FALSE); + inline int GetShadowMode() const + { + return m_shadowMode; + } + virtual bool HitTest(double x, double y, int *attachment, double *distance); + inline void SetCentreResize(bool cr) + { + m_centreResize = cr; + } + inline bool GetCentreResize() const + { + return m_centreResize; + } + inline void SetMaintainAspectRatio(bool ar) + { + m_maintainAspectRatio = ar; + } + inline bool GetMaintainAspectRatio() const + { + return m_maintainAspectRatio; + } + inline wxList &GetLines() const + { + return (wxList &) m_lines; + } + inline void SetDisableLabel(bool flag) + { + m_disableLabel = flag; + } + inline bool GetDisableLabel() const + { + return m_disableLabel; + } + inline void SetAttachmentMode(int mode) + { + m_attachmentMode = mode; + } + inline int GetAttachmentMode() const + { + return m_attachmentMode; + } + inline void SetId(long i) + { + m_id = i; + } + inline long GetId() const + { + return m_id; + } + + void SetPen(wxPen *pen); + void SetBrush(wxBrush *brush); + + virtual void Refresh(wxShapeCanvas *canvas = NULL); + virtual void Show(bool show); + virtual bool IsShown() const + { + return m_visible; + } + virtual void Move(double x1, double y1, bool display = TRUE); + virtual void Erase(); + virtual void Draw(wxDC &dc); + virtual void Flash(); + virtual void MoveLinks(); + virtual void DrawContents(wxDC &dc); // E.g. for drawing text label + virtual void SetSize(double x, double y, bool recursive = TRUE); + virtual void SetAttachmentSize(double x, double y); + void Attach(wxShapeCanvas *can); + void Detach(); + + inline virtual bool Constrain() + { + return FALSE; + } ; + + void AddLine(wxLineShape *line, wxShape *other, + int attachFrom = 0, int attachTo = 0, + // The line ordering + int positionFrom = -1, int positionTo = -1); + + // Return the zero-based position in m_lines of line. + int GetLinePosition(wxLineShape *line); + + void AddText(const wxString &string); + + inline wxPen *GetPen() const + { + return m_pen; + } + inline wxBrush *GetBrush() const + { + return m_brush; + } + + /* + * Region-specific functions (defaults to the default region + * for simple objects + */ + + // Set the default, single region size to be consistent + // with the object size + void SetDefaultRegionSize(); + virtual void FormatText(wxDC &dc, const wxString &s, int regionId = 0); + virtual void SetFormatMode(int mode, int regionId = 0); + virtual int GetFormatMode(int regionId = 0) const; + virtual void SetFont(wxFont *font, int regionId = 0); + virtual wxFont *GetFont(int regionId = 0) const; + virtual void SetTextColour(const wxString &colour, int regionId = 0); + virtual void SetTextColour(const wxColour &colour, int regionId = 0); + virtual wxString GetTextColour(int regionId = 0) const; + virtual wxColour GetActualTextColour(int regionId = 0) const; + virtual inline int GetNumberOfTextRegions() const + { + return m_regions.GetCount(); + } + virtual void SetRegionName(const wxString &name, int regionId = 0); + + // Get the name representing the region for this image alone. + // I.e. this image's region ids go from 0 to N-1. + // But the names might be "0.2.0", "0.2.1" etc. depending on position in composite. + // So the last digit represents the region Id, the others represent positions + // in composites. + virtual wxString GetRegionName(int regionId); + + // Gets the region corresponding to the name, or -1 if not found. + virtual int GetRegionId(const wxString &name); + + // Construct names for regions, unique even for children of a composite. + virtual void NameRegions(const wxString &parentName = wxEmptyString); + + // Get list of regions + inline wxList &GetRegions() const + { + return (wxList &) m_regions; + } + + virtual void AddRegion(wxShapeRegion *region); + + virtual void ClearRegions(); + + // Assign new ids to this image and children (if composite) + void AssignNewIds(); + + // Returns actual image (same as 'this' if non-composite) and region id + // for given region name. + virtual wxShape *FindRegion(const wxString ®ionName, int *regionId); + + // Finds all region names for this image (composite or simple). + // Supply empty string list. + virtual void FindRegionNames(wxStringList &list); + + virtual void ClearText(int regionId = 0); + void RemoveLine(wxLineShape *line); + +#if wxUSE_PROLOGIO + // I/O + virtual void WriteAttributes(wxExpr *clause); + virtual void ReadAttributes(wxExpr *clause); + + // In case the object has constraints it needs to read in in a different pass + inline virtual void ReadConstraints(wxExpr *WXUNUSED(clause), wxExprDatabase *WXUNUSED(database)) { }; + virtual void WriteRegions(wxExpr *clause); + virtual void ReadRegions(wxExpr *clause); +#endif + + // Attachment code + virtual bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + virtual int GetNumberOfAttachments() const; + virtual wxList &GetAttachments() + { + return m_attachmentPoints; + } + + virtual bool AttachmentIsValid(int attachment) const; + + // Only get the attachment position at the _edge_ of the shape, ignoring + // branching mode. This is used e.g. to indicate the edge of interest, not the point + // on the attachment branch. + virtual bool GetAttachmentPositionEdge(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + + // Assuming the attachment lies along a vertical or horizontal line, + // calculate the position on that point. + virtual wxRealPoint CalcSimpleAttachment(const wxRealPoint &pt1, const wxRealPoint &pt2, + int nth, int noArcs, wxLineShape *line); + + // Returns TRUE if pt1 <= pt2 in the sense that one point comes before another on an + // edge of the shape. + // attachmentPoint is the attachment point (= side) in question. + virtual bool AttachmentSortTest(int attachmentPoint, const wxRealPoint &pt1, const wxRealPoint &pt2); + + virtual void DrawLinks(wxDC &dc, int attachment = -1, bool recurse = FALSE); + + virtual bool MoveLineToNewAttachment(wxLineShape *to_move, + double x, double y); + + // Reorders the lines coming into the node image at this attachment + // position, in the order in which they appear in linesToSort. + virtual void SortLines(int attachment, wxList &linesToSort); + + // Apply an attachment ordering change + void ApplyAttachmentOrdering(wxList &ordering); + + // Can override this to prevent or intercept line reordering. + virtual void OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering); + + //// New banching attachment code, 24/9/98 + + // + // |________| + // | <- root + // | <- neck + // shoulder1 ->---------<- shoulder2 + // | | | | |<- stem + // <- branching attachment point N-1 + + // This function gets the root point at the given attachment. + virtual wxRealPoint GetBranchingAttachmentRoot(int attachment); + + // This function gets information about where branching connections go (calls GetBranchingAttachmentRoot) + virtual bool GetBranchingAttachmentInfo(int attachment, wxRealPoint &root, wxRealPoint &neck, + wxRealPoint &shoulder1, wxRealPoint &shoulder2); + + // n is the number of the adjoining line, from 0 to N-1 where N is the number of lines + // at this attachment point. + // attachmentPoint is where the arc meets the stem, and stemPoint is where the stem meets the + // shoulder. + virtual bool GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint &attachmentPoint, + wxRealPoint &stemPoint); + + // Get the number of lines at this attachment position. + virtual int GetAttachmentLineCount(int attachment) const; + + // Draw the branches (not the actual arcs though) + virtual void OnDrawBranches(wxDC &dc, int attachment, bool erase = FALSE); + virtual void OnDrawBranches(wxDC &dc, bool erase = FALSE); + + // Branching attachment settings + inline void SetBranchNeckLength(int len) + { + m_branchNeckLength = len; + } + inline int GetBranchNeckLength() const + { + return m_branchNeckLength; + } + + inline void SetBranchStemLength(int len) + { + m_branchStemLength = len; + } + inline int GetBranchStemLength() const + { + return m_branchStemLength; + } + + inline void SetBranchSpacing(int len) + { + m_branchSpacing = len; + } + inline int GetBranchSpacing() const + { + return m_branchSpacing; + } + + // Further detail on branching style, e.g. blobs on interconnections + inline void SetBranchStyle(long style) + { + m_branchStyle = style; + } + inline long GetBranchStyle() const + { + return m_branchStyle; + } + + // Rotate the standard attachment point from physical (0 is always North) + // to logical (0 -> 1 if rotated by 90 degrees) + virtual int PhysicalToLogicalAttachment(int physicalAttachment) const; + + // Rotate the standard attachment point from logical + // to physical (0 is always North) + virtual int LogicalToPhysicalAttachment(int logicalAttachment) const; + + // This is really to distinguish between lines and other images. + // For lines, want to pass drag to canvas, since lines tend to prevent + // dragging on a canvas (they get in the way.) + virtual bool Draggable() const + { + return TRUE; + } + + // Returns TRUE if image is a descendant of this image + bool HasDescendant(wxShape *image); + + // Creates a copy of this shape. + wxShape *CreateNewCopy(bool resetMapping = TRUE, bool recompute = TRUE); + + // Does the copying for this object + virtual void Copy(wxShape ©); + + // Does the copying for this object, including copying event + // handler data if any. Calls the virtual Copy function. + void CopyWithHandler(wxShape ©); + + // Rotate about the given axis by the given amount in radians. + virtual void Rotate(double x, double y, double theta); + virtual double GetRotation() const + { + return m_rotation; + } + virtual void SetRotation(double rotation) + { + m_rotation = rotation; + } + + void ClearAttachments(); + + // Recentres all the text regions for this object + void Recentre(wxDC &dc); + + // Clears points from a list of wxRealPoints + void ClearPointList(wxList &list); + + // Return pen or brush of the right colour for the background + wxPen GetBackgroundPen(); + wxBrush GetBackgroundBrush(); + + +protected: + wxShapeEvtHandler *m_eventHandler; + bool m_formatted; + double m_xpos, m_ypos; + wxPen *m_pen; + wxBrush *m_brush; + wxFont *m_font; + wxColour m_textColour; + wxString m_textColourName; + wxShapeCanvas *m_canvas; + wxList m_lines; + wxList m_text; + wxList m_controlPoints; + wxList m_regions; + wxList m_attachmentPoints; + bool m_visible; + bool m_disableLabel; + long m_id; + bool m_selected; + bool m_highlighted; // Different from selected: user-defined highlighting, + // e.g. thick border. + double m_rotation; + int m_sensitivity; + bool m_draggable; + int m_attachmentMode; // 0 for no attachments, 1 if using normal attachments, + // 2 for branching attachments + bool m_spaceAttachments; // TRUE if lines at one side should be spaced + bool m_fixedWidth; + bool m_fixedHeight; + bool m_centreResize; // Default is to resize keeping the centre constant (TRUE) + bool m_drawHandles; // Don't draw handles if FALSE, usually TRUE + wxList m_children; // In case it's composite + wxShape *m_parent; // In case it's a child + int m_formatMode; + int m_shadowMode; + wxBrush *m_shadowBrush; + int m_shadowOffsetX; + int m_shadowOffsetY; + int m_textMarginX; // Gap between text and border + int m_textMarginY; + wxString m_regionName; + bool m_maintainAspectRatio; + int m_branchNeckLength; + int m_branchStemLength; + int m_branchSpacing; + long m_branchStyle; +}; + +class wxPolygonShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxPolygonShape) +public: + wxPolygonShape(); + ~wxPolygonShape(); + + // Takes a list of wxRealPoints; each point is an OFFSET from the centre. + // Deletes user's points in destructor. + // If points is NULL, simply creates both empty lists. + virtual void Create(wxList *points); + virtual void ClearPoints(); + + void GetBoundingBoxMin(double *w, double *h); + void CalculateBoundingBox(); + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + bool HitTest(double x, double y, int *attachment, double *distance); + void SetSize(double x, double y, bool recursive = TRUE); + void OnDraw(wxDC &dc); + void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + // A polygon should have a control point at each vertex, + // with the option of moving the control points individually + // to change the shape. + void MakeControlPoints(); + void ResetControlPoints(); + + // If we've changed the shape, must make the original + // points match the working points + void UpdateOriginalPoints(); + + // Add a control point after the given point + virtual void AddPolygonPoint(int pos = 0); + + // Delete a control point + virtual void DeletePolygonPoint(int pos = 0); + + // Recalculates the centre of the polygon + virtual void CalculatePolygonCentre(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + int GetNumberOfAttachments() const; + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + bool AttachmentIsValid(int attachment) const; + // Does the copying for this object + void Copy(wxShape ©); + + inline wxList *GetPoints() + { + return m_points; + } + inline wxList *GetOriginalPoints() + { + return m_originalPoints; + } + + // Rotate about the given axis by the given amount in radians + virtual void Rotate(double x, double y, double theta); + + double GetOriginalWidth() const + { + return m_originalWidth; + } + double GetOriginalHeight() const + { + return m_originalHeight; + } + + void SetOriginalWidth(double w) + { + m_originalWidth = w; + } + void SetOriginalHeight(double h) + { + m_originalHeight = h; + } + +private: + wxList *m_points; + wxList *m_originalPoints; + double m_boundWidth; + double m_boundHeight; + double m_originalWidth; + double m_originalHeight; +}; + +class wxRectangleShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxRectangleShape) +public: + wxRectangleShape(double w = 0.0, double h = 0.0); + void GetBoundingBoxMin(double *w, double *h); + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + void OnDraw(wxDC &dc); + void SetSize(double x, double y, bool recursive = TRUE); + void SetCornerRadius(double rad); // If > 0, rounded corners + double GetCornerRadius() const + { + return m_cornerRadius; + } + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + int GetNumberOfAttachments() const; + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + // Does the copying for this object + void Copy(wxShape ©); + + inline double GetWidth() const + { + return m_width; + } + inline double GetHeight() const + { + return m_height; + } + inline void SetWidth(double w) + { + m_width = w; + } + inline void SetHeight(double h) + { + m_height = h; + } + +protected: + double m_width; + double m_height; + double m_cornerRadius; +}; + +class wxTextShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxTextShape) +public: + wxTextShape(double width = 0.0, double height = 0.0); + + void OnDraw(wxDC &dc); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); +#endif + + // Does the copying for this object + void Copy(wxShape ©); +}; + +class wxEllipseShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxEllipseShape) +public: + wxEllipseShape(double w = 0.0, double h = 0.0); + + void GetBoundingBoxMin(double *w, double *h); + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + + void OnDraw(wxDC &dc); + void SetSize(double x, double y, bool recursive = TRUE); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + int GetNumberOfAttachments() const; + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + + // Does the copying for this object + void Copy(wxShape ©); + + inline double GetWidth() const + { + return m_width; + } + inline double GetHeight() const + { + return m_height; + } + + inline void SetWidth(double w) + { + m_width = w; + } + inline void SetHeight(double h) + { + m_height = h; + } + +protected: + double m_width; + double m_height; +}; + +class wxCircleShape: public wxEllipseShape +{ + DECLARE_DYNAMIC_CLASS(wxCircleShape) +public: + wxCircleShape(double w = 0.0); + + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + // Does the copying for this object + void Copy(wxShape ©); +}; + +#endif +// _OGL_BASIC_H_ diff --git a/include/ogl/basicp.h b/include/ogl/basicp.h new file mode 100644 index 0000000..acc7116 --- /dev/null +++ b/include/ogl/basicp.h @@ -0,0 +1,305 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basicp.h - Private OGL classes and definitions +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_BASICP_H_ +#define _OGL_BASICP_H_ + +#define CONTROL_POINT_SIZE 6 + +class wxShapeTextLine: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxShapeTextLine) +public: + wxShapeTextLine(double the_x = 0.0, double the_y = 0.0, const wxString &the_line = wxEmptyString); + ~wxShapeTextLine(); + + inline double GetX() const + { + return m_x; + } + inline double GetY() const + { + return m_y; + } + + inline void SetX(double x) + { + m_x = x; + } + inline void SetY(double y) + { + m_y = y; + } + + inline void SetText(const wxString &text) + { + m_line = text; + } + inline wxString GetText() const + { + return m_line; + } + +protected: + wxString m_line; + double m_x; + double m_y; +}; + +//class wxShape; +class wxControlPoint: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxControlPoint) + + friend class wxShapeEvtHandler; + friend class wxShape; + +public: + wxControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, double size = 0.0, double the_xoffset = 0.0, + double the_yoffset = 0.0, int the_type = 0); + ~wxControlPoint(); + + void OnDraw(wxDC &dc); + void OnErase(wxDC &dc); + void OnDrawContents(wxDC &dc); + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + int GetNumberOfAttachments() const; + + inline void SetEraseObject(bool er) + { + m_eraseObject = er; + } + +public: + int m_type; + double m_xoffset; + double m_yoffset; + wxShape *m_shape; + wxCursor *m_oldCursor; + bool m_eraseObject; // If TRUE, erases object before dragging handle. + + /* + * Store original top-left, bottom-right coordinates + * in case we're doing non-vertical resizing. + */ + static double sm_controlPointDragStartX; + static double sm_controlPointDragStartY; + static double sm_controlPointDragStartWidth; + static double sm_controlPointDragStartHeight; + static double sm_controlPointDragEndWidth; + static double sm_controlPointDragEndHeight; + static double sm_controlPointDragPosX; + static double sm_controlPointDragPosY; +}; + +class wxPolygonShape; +class wxPolygonControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxPolygonControlPoint) + friend class wxPolygonShape; +public: + wxPolygonControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, double size = 0.0, wxRealPoint *vertex = NULL, + double the_xoffset = 0.0, double the_yoffset = 0.0); + ~wxPolygonControlPoint(); + + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + // Calculate what new size would be, at end of resize + virtual void CalculateNewSize(double x, double y); + + // Get new size + inline wxRealPoint GetNewSize() const + { + return m_newSize; + }; + +public: + wxRealPoint *m_polygonVertex; + wxRealPoint m_originalSize; + double m_originalDistance; + wxRealPoint m_newSize; +}; + +/* + * Object regions. + * Every shape has one or more text regions with various + * properties. Not all of a region's properties will be used + * by a shape. + * + */ + +class wxShapeRegion: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxShapeRegion) + +public: + // Constructor + wxShapeRegion(); + // Copy constructor + wxShapeRegion(wxShapeRegion ®ion); + // Destructor + ~wxShapeRegion(); + + // Accessors + inline void SetText(const wxString &s) + { + m_regionText = s; /* m_formattedText.Append(new wxShapeTextLine(0,0,s)); */ + } + void SetFont(wxFont *f); + void SetMinSize(double w, double h); + void SetSize(double w, double h); + void SetPosition(double x, double y); + void SetProportions(double x, double y); + void SetFormatMode(int mode); + inline void SetName(const wxString &s) + { + m_regionName = s; + }; + void SetColour(const wxString &col); // Text colour + void SetColour(const wxColour &col); // Text colour + + inline wxString GetText() const + { + return m_regionText; + } + inline wxFont *GetFont() const + { + return m_font; + } + inline void GetMinSize(double *x, double *y) const + { + *x = m_minWidth; + *y = m_minHeight; + } + inline void GetProportion(double *x, double *y) const + { + *x = m_regionProportionX; + *y = m_regionProportionY; + } + inline void GetSize(double *x, double *y) const + { + *x = m_width; + *y = m_height; + } + inline void GetPosition(double *xp, double *yp) const + { + *xp = m_x; + *yp = m_y; + } + inline int GetFormatMode() const + { + return m_formatMode; + } + inline wxString GetName() const + { + return m_regionName; + } + inline wxString GetColour() const + { + return m_textColour; + } + const wxColour &GetActualColourObject(); + inline wxList &GetFormattedText() + { + return m_formattedText; + } + inline wxString GetPenColour() const + { + return m_penColour; + } + inline int GetPenStyle() const + { + return m_penStyle; + } + inline void SetPenStyle(int style) + { + m_penStyle = style; + m_actualPenObject = NULL; + } + void SetPenColour(const wxString &col); + wxPen *GetActualPen(); + inline double GetWidth() const + { + return m_width; + } + inline double GetHeight() const + { + return m_height; + } + + void ClearText(); + +public: + wxString m_regionText; + wxList m_formattedText; // List of wxShapeTextLines + wxFont *m_font; + double m_minHeight; // If zero, hide region. + double m_minWidth; // If zero, hide region. + double m_width; + double m_height; + double m_x; + double m_y; + + double m_regionProportionX; // Proportion of total object size; + // -1.0 indicates equal proportion + double m_regionProportionY; // Proportion of total object size; + // -1.0 indicates equal proportion + + int m_formatMode; // FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT | FORMAT_NONE + wxString m_regionName; + wxString m_textColour; + wxColour m_actualColourObject; // For speed purposes + + // New members for specifying divided rectangle division colour/style 30/6/94 + wxString m_penColour; + int m_penStyle; + wxPen *m_actualPenObject; + +}; + +/* + * User-defined attachment point + */ + +class wxAttachmentPoint: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxAttachmentPoint) + +public: + inline wxAttachmentPoint() + { + m_id = 0; + m_x = 0.0; + m_y = 0.0; + } + inline wxAttachmentPoint(int id, double x, double y) + { + m_id = id; + m_x = x; + m_y = y; + } + +public: + int m_id; // Identifier + double m_x; // x offset from centre of object + double m_y; // y offset from centre of object +}; + +#endif +// _OGL_BASICP_H_ diff --git a/include/ogl/bmpshape.h b/include/ogl/bmpshape.h new file mode 100644 index 0000000..304fa7e --- /dev/null +++ b/include/ogl/bmpshape.h @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// bmpshape.h - wxBitmapShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_BITMAP_H_ +#define _OGL_BITMAP_H_ + +#include "wx/bitmap.h" + +class wxBitmapShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxBitmapShape) +public: + wxBitmapShape(); + ~wxBitmapShape(); + + void OnDraw(wxDC &dc); + +#if wxUSE_PROLOGIO + // I/O + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + // Does the copying for this object + void Copy(wxShape ©); + + void SetSize(double w, double h, bool recursive = TRUE); + inline wxBitmap &GetBitmap() const + { + return (wxBitmap &) m_bitmap; + } + void SetBitmap(const wxBitmap &bm); + inline void SetFilename(const wxString &f) + { + m_filename = f; + }; + inline wxString GetFilename() const + { + return m_filename; + } + +private: + wxBitmap m_bitmap; + wxString m_filename; +}; + +#endif +// _OGL_BITMAP_H_ + + diff --git a/include/ogl/canvas.h b/include/ogl/canvas.h new file mode 100644 index 0000000..9bc6ef6 --- /dev/null +++ b/include/ogl/canvas.h @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// canvas.h - wxShapeCanvas +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_CANVAS_H_ +#define _OGL_CANVAS_H_ + +// Drag states +#define NoDragging 0 +#define StartDraggingLeft 1 +#define ContinueDraggingLeft 2 +#define StartDraggingRight 3 +#define ContinueDraggingRight 4 + +#ifdef __WXMSW__ +#define OGL_USE_BUFFERED_PAINT 1 +#else +#define OGL_USE_BUFFERED_PAINT 0 +#endif + + +extern const wxChar *wxShapeCanvasNameStr; + +// When drag_count reaches 0, process drag message + +class wxDiagram; + +class wxShapeCanvas: public wxScrolledWindow +{ + DECLARE_DYNAMIC_CLASS(wxShapeCanvas) +public: + wxShapeCanvas(wxWindow *parent = NULL, wxWindowID id = -1, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize, + long style = wxBORDER | wxRETAINED, + const wxString &name = wxShapeCanvasNameStr); + ~wxShapeCanvas(); + + inline void SetDiagram(wxDiagram *diag) + { + m_shapeDiagram = diag; + } + inline wxDiagram *GetDiagram() const + { + return m_shapeDiagram; + } + + virtual void OnLeftClick(double x, double y, int keys = 0); + virtual void OnRightClick(double x, double y, int keys = 0); + + virtual void OnDragLeft(bool draw, double x, double y, int keys = 0); // Erase if draw false + virtual void OnBeginDragLeft(double x, double y, int keys = 0); + virtual void OnEndDragLeft(double x, double y, int keys = 0); + + virtual void OnDragRight(bool draw, double x, double y, int keys = 0); // Erase if draw false + virtual void OnBeginDragRight(double x, double y, int keys = 0); + virtual void OnEndDragRight(double x, double y, int keys = 0); + + // Find object for mouse click, of given wxClassInfo (NULL for any type). + // If notImage is non-NULL, don't find an object that is equal to or a descendant of notImage + virtual wxShape *FindShape(double x, double y, int *attachment, wxClassInfo *info = NULL, wxShape *notImage = NULL); + wxShape *FindFirstSensitiveShape(double x, double y, int *new_attachment, int op); + wxShape *FindFirstSensitiveShape1(wxShape *image, int op); + + // Redirect to wxDiagram object + virtual void AddShape(wxShape *object, wxShape *addAfter = NULL); + virtual void InsertShape(wxShape *object); + virtual void RemoveShape(wxShape *object); + virtual bool GetQuickEditMode(); + virtual void Redraw(wxDC &dc); + void Snap(double *x, double *y); + + // Returns the current scroll position + wxPoint GetCurrentPixelScrollPosition(); + + void ResetDragState() + { + m_dragState = NoDragging; + } + +#if OGL_USE_BUFFERED_PAINT + /// Recreate buffer bitmap if necessary + bool RecreateBuffer(const wxSize &size = wxDefaultSize); +#endif + + virtual void DrawBackground(wxDC &dc, bool transformed = FALSE); + + // Events + void OnPaint(wxPaintEvent &event); + void OnMouseEvent(wxMouseEvent &event); + void OnEraseBackground(wxEraseEvent &event); + +protected: + wxDiagram *m_shapeDiagram; + int m_dragState; + double m_oldDragX, m_oldDragY; // Previous drag coordinates + double m_firstDragX, m_firstDragY; // INITIAL drag coordinates + bool m_checkTolerance; // Whether to check drag tolerance + wxShape *m_draggedShape; + int m_draggedAttachment; + +#if OGL_USE_BUFFERED_PAINT + /// Buffer bitmap + wxBitmap m_bufferBitmap; +#endif + + DECLARE_EVENT_TABLE() +}; + +#endif +// _OGL_CANVAS_H_ diff --git a/include/ogl/composit.h b/include/ogl/composit.h new file mode 100644 index 0000000..481e153 --- /dev/null +++ b/include/ogl/composit.h @@ -0,0 +1,294 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// composit.h - wxCompositeShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_COMPOSIT_H_ +#define _OGL_COMPOSIT_H_ + +class wxDivisionShape; +class wxOGLConstraint; + +/* + * A composite object is an invisible rectangle surrounding all children + * + */ + +class wxCompositeShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxCompositeShape) +public: + + wxCompositeShape(); + ~wxCompositeShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + bool OnMovePre(double x, double y, double oldX, double oldY, bool display = TRUE); + void OnDragLeft(bool draw, double x, double y, int keys, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys, int attachment = 0); + + void OnRightClick(double x, double y, int keys, int attachment = 0); + + void SetSize(double w, double h, bool recursive = TRUE); + + // Returns TRUE if it settled down + bool Recompute(); + + // New members + void AddChild(wxShape *child, wxShape *addAfter = NULL); + void RemoveChild(wxShape *child); + + wxOGLConstraint *AddConstraint(wxOGLConstraint *constraint); + wxOGLConstraint *AddConstraint(int type, wxShape *constraining, wxList &constrained); + wxOGLConstraint *AddConstraint(int type, wxShape *constraining, wxShape *constrained); + + void DeleteConstraint(wxOGLConstraint *constraint); + + // Delete constraints that involve this child. + void DeleteConstraintsInvolvingChild(wxShape *child); + + // Remove the image from any constraints involving it, but DON'T + // remove any constraints. + void RemoveChildFromConstraints(wxShape *child); + + // Find constraint, also returning actual composite the constraint was in, + // in case it had to find it recursively. + wxOGLConstraint *FindConstraint(long id, wxCompositeShape **actualComposite = NULL); + + // Returns TRUE if something changed + bool Constrain(); + + // Make this composite into a container by creating one wxDivisionShape + void MakeContainer(); + + // Calculates size and position of composite object based on children + void CalculateSize(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); + // In case the object has constraints it needs to read in in a different pass + void ReadConstraints(wxExpr *clause, wxExprDatabase *database); +#endif + // Does the copying for this object + void Copy(wxShape ©); + + virtual wxDivisionShape *OnCreateDivision(); + + // Finds the image used to visualize a container. This is any child + // of the composite that is not in the divisions list. + wxShape *FindContainerImage(); + + // Returns TRUE if division is a descendant of this container + bool ContainsDivision(wxDivisionShape *division); + + inline wxList &GetDivisions() const + { + return (wxList &) m_divisions; + } + inline wxList &GetConstraints() const + { + return (wxList &) m_constraints; + } + +protected: + double m_oldX; + double m_oldY; + wxList m_constraints; + wxList m_divisions; // In case it's a container +}; + +/* + * A division object is a composite with special properties, + * to be used for containment. It's a subdivision of a container. + * A containing node image consists of a composite with a main child shape + * such as rounded rectangle, plus a list of division objects. + * It needs to be a composite because a division contains pieces + * of diagram. + * NOTE a container has at least one wxDivisionShape for consistency. + * This can be subdivided, so it turns into two objects, then each of + * these can be subdivided, etc. + */ +#define DIVISION_SIDE_NONE 0 +#define DIVISION_SIDE_LEFT 1 +#define DIVISION_SIDE_TOP 2 +#define DIVISION_SIDE_RIGHT 3 +#define DIVISION_SIDE_BOTTOM 4 + +class wxDivisionShape: public wxCompositeShape +{ + DECLARE_DYNAMIC_CLASS(wxDivisionShape) +public: + + wxDivisionShape(); + ~wxDivisionShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + bool OnMovePre(double x, double y, double oldX, double oldY, bool display = TRUE); + void OnDragLeft(bool draw, double x, double y, int keys, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys, int attachment = 0); + + void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + + // Don't want this kind of composite to resize its subdiagrams, so + // override composite's SetSize. + void SetSize(double w, double h, bool recursive = TRUE); + + // Similarly for calculating size: it's fixed at whatever SetSize + // set it to, not in terms of children. + void CalculateSize(); + + void MakeControlPoints(); + void ResetControlPoints(); + void MakeMandatoryControlPoints(); + void ResetMandatoryControlPoints(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + // Does the copying for this object + void Copy(wxShape ©); + + // Divide horizontally (wxHORIZONTAL) or vertically (wxVERTICAL) + bool Divide(int direction); + + // Resize adjoining divisions at the given side. If test is TRUE, + // just see whether it's possible for each adjoining region, + // returning FALSE if it's not. + bool ResizeAdjoining(int side, double newPos, bool test); + + // Adjust a side, returning FALSE if it's not physically possible. + bool AdjustLeft(double left, bool test); + bool AdjustTop(double top, bool test); + bool AdjustRight(double right, bool test); + bool AdjustBottom(double bottom, bool test); + + // Edit style of left or top side + void EditEdge(int side); + + // Popup menu + void PopupMenu(double x, double y); + + inline void SetLeftSide(wxDivisionShape *shape) + { + m_leftSide = shape; + } + inline void SetTopSide(wxDivisionShape *shape) + { + m_topSide = shape; + } + inline void SetRightSide(wxDivisionShape *shape) + { + m_rightSide = shape; + } + inline void SetBottomSide(wxDivisionShape *shape) + { + m_bottomSide = shape; + } + inline wxDivisionShape *GetLeftSide() const + { + return m_leftSide; + } + inline wxDivisionShape *GetTopSide() const + { + return m_topSide; + } + inline wxDivisionShape *GetRightSide() const + { + return m_rightSide; + } + inline wxDivisionShape *GetBottomSide() const + { + return m_bottomSide; + } + + inline void SetHandleSide(int side) + { + m_handleSide = side; + } + inline int GetHandleSide() const + { + return m_handleSide; + } + + inline void SetLeftSidePen(wxPen *pen) + { + m_leftSidePen = pen; + } + inline wxPen *GetLeftSidePen() const + { + return m_leftSidePen; + } + inline void SetTopSidePen(wxPen *pen) + { + m_topSidePen = pen; + } + inline wxPen *GetTopSidePen() const + { + return m_topSidePen; + } + + void SetLeftSideColour(const wxString &colour); + void SetTopSideColour(const wxString &colour); + void SetLeftSideStyle(const wxString &style); + void SetTopSideStyle(const wxString &style); + + inline wxString GetLeftSideColour() const + { + return m_leftSideColour; + } + inline wxString GetTopSideColour() const + { + return m_topSideColour; + } + inline wxString GetLeftSideStyle() const + { + return m_leftSideStyle; + } + inline wxString GetTopSideStyle() const + { + return m_topSideStyle; + } + +protected: + // Adjoining divisions. NULL indicates edge + // of container, and that side shouldn't be + // drawn. + wxDivisionShape *m_leftSide; + wxDivisionShape *m_rightSide; + wxDivisionShape *m_topSide; + wxDivisionShape *m_bottomSide; + + int m_handleSide; // Side at which handle is legal + + wxPen *m_leftSidePen; + wxPen *m_topSidePen; + wxString m_leftSideColour; + wxString m_topSideColour; + wxString m_leftSideStyle; + wxString m_topSideStyle; +}; + + +#define DIVISION_MENU_SPLIT_HORIZONTALLY 1 +#define DIVISION_MENU_SPLIT_VERTICALLY 2 +#define DIVISION_MENU_EDIT_LEFT_EDGE 3 +#define DIVISION_MENU_EDIT_TOP_EDGE 4 +#define DIVISION_MENU_EDIT_RIGHT_EDGE 5 +#define DIVISION_MENU_EDIT_BOTTOM_EDGE 6 +#define DIVISION_MENU_DELETE_ALL 7 + +#endif +// _OGL_COMPOSIT_H_ diff --git a/include/ogl/constrnt.h b/include/ogl/constrnt.h new file mode 100644 index 0000000..e3990b7 --- /dev/null +++ b/include/ogl/constrnt.h @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// constrnt.h - OGL constraint definitions +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_CONSTRNT_H_ +#define _OGL_CONSTRNT_H_ + +/* + * OGL Constraints + * + */ + +class wxOGLConstraintType: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxOGLConstraintType) +public: + wxOGLConstraintType(int type = 0, const wxString &name = wxEmptyString, + const wxString &phrase = wxEmptyString); + ~wxOGLConstraintType(); + +public: + int m_type; // E.g. gyCONSTRAINT_CENTRED_VERTICALLY + wxString m_name; // E.g. "Centre vertically" + wxString m_phrase; // E.g. "centred vertically with respect to", "left of" + +}; + +extern wxList *wxOGLConstraintTypes; + +#define gyCONSTRAINT_CENTRED_VERTICALLY 1 +#define gyCONSTRAINT_CENTRED_HORIZONTALLY 2 +#define gyCONSTRAINT_CENTRED_BOTH 3 +#define gyCONSTRAINT_LEFT_OF 4 +#define gyCONSTRAINT_RIGHT_OF 5 +#define gyCONSTRAINT_ABOVE 6 +#define gyCONSTRAINT_BELOW 7 +#define gyCONSTRAINT_ALIGNED_TOP 8 +#define gyCONSTRAINT_ALIGNED_BOTTOM 9 +#define gyCONSTRAINT_ALIGNED_LEFT 10 +#define gyCONSTRAINT_ALIGNED_RIGHT 11 + +// Like aligned, but with the objects centred on the respective edge +// of the reference object. +#define gyCONSTRAINT_MIDALIGNED_TOP 12 +#define gyCONSTRAINT_MIDALIGNED_BOTTOM 13 +#define gyCONSTRAINT_MIDALIGNED_LEFT 14 +#define gyCONSTRAINT_MIDALIGNED_RIGHT 15 + +class wxOGLConstraint: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxOGLConstraint) +public: + wxOGLConstraint() + { + m_xSpacing = 0.0; + m_ySpacing = 0.0; + m_constraintType = 0; + m_constraintName = wxEmptyString; + m_constraintId = 0; + m_constrainingObject = NULL; + } + wxOGLConstraint(int type, wxShape *constraining, wxList &constrained); + ~wxOGLConstraint(); + + // Returns TRUE if anything changed + bool Evaluate(); + inline void SetSpacing(double x, double y) + { + m_xSpacing = x; + m_ySpacing = y; + }; + bool Equals(double a, double b); + + double m_xSpacing; + double m_ySpacing; + int m_constraintType; + wxString m_constraintName; + long m_constraintId; + wxShape *m_constrainingObject; + wxList m_constrainedObjects; + +}; + +void OGLInitializeConstraintTypes(); +void OGLCleanUpConstraintTypes(); + +#endif +// _OGL_CONSTRNT_H_ diff --git a/include/ogl/divided.h b/include/ogl/divided.h new file mode 100644 index 0000000..b8443ad --- /dev/null +++ b/include/ogl/divided.h @@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// divided.h - wxDividedShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_DIVIDED_H_ +#define _OGL_DIVIDED_H_ + +/* + * Definition of a region + * + */ + +/* + * Box divided into horizontal regions + * + */ + +extern wxFont *g_oglNormalFont; +class wxDividedShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxDividedShape) + +public: + wxDividedShape(double w = 0.0, double h = 0.0); + ~wxDividedShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + + void SetSize(double w, double h, bool recursive = TRUE); + + void MakeControlPoints(); + void ResetControlPoints(); + + void MakeMandatoryControlPoints(); + void ResetMandatoryControlPoints(); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + void Copy(wxShape ©); + + // Set all region sizes according to proportions and + // this object total size + void SetRegionSizes(); + + // Edit region colours/styles + void EditRegions(); + + // Attachment points correspond to regions in the divided box + bool GetAttachmentPosition(int attachment, double *x, double *y, + int nth = 0, int no_arcs = 1, wxLineShape *line = NULL); + bool AttachmentIsValid(int attachment) const; + int GetNumberOfAttachments() const; + + // Invoke editor on CTRL-right click + void OnRightClick(double x, double y, int keys = 0, int attachment = 0); +}; + +#endif +// _OGL_DIVIDED_H_ + diff --git a/include/ogl/drawn.h b/include/ogl/drawn.h new file mode 100644 index 0000000..c874793 --- /dev/null +++ b/include/ogl/drawn.h @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// drawn.h - wxDrawnShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_DRAWN_H_ +#define _OGL_DRAWN_H_ + +#define oglMETAFLAGS_OUTLINE 1 +#define oglMETAFLAGS_ATTACHMENTS 2 + +class wxDrawnShape; +class wxPseudoMetaFile: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxPseudoMetaFile) +public: + wxPseudoMetaFile(); + wxPseudoMetaFile(wxPseudoMetaFile &mf); + ~wxPseudoMetaFile(); + + void Draw(wxDC &dc, double xoffset, double yoffset); + +#if wxUSE_PROLOGIO + void WriteAttributes(wxExpr *clause, int whichAngle); + void ReadAttributes(wxExpr *clause, int whichAngle); +#endif + + void Clear(); + + void Copy(wxPseudoMetaFile ©); + + void Scale(double sx, double sy); + void ScaleTo(double w, double h); // Scale to fit size + void Translate(double x, double y); + + // Rotate about the given axis by theta radians from the x axis. + void Rotate(double x, double y, double theta); + + bool LoadFromMetaFile(const wxString &filename, double *width, double *height); + + void GetBounds(double *minX, double *minY, double *maxX, double *maxY); + + // Calculate size from current operations + void CalculateSize(wxDrawnShape *shape); + + inline wxList &GetOutlineColours() const + { + return (wxList &) m_outlineColours; + } + inline wxList &GetFillColours() const + { + return (wxList &) m_fillColours; + } + inline void SetRotateable(bool rot) + { + m_rotateable = rot; + } + inline bool GetRotateable() const + { + return m_rotateable; + } + + inline void SetSize(double w, double h) + { + m_width = w; + m_height = h; + } + + inline void SetFillBrush(wxBrush *brush) + { + m_fillBrush = brush; + } + inline wxBrush *GetFillBrush() const + { + return m_fillBrush; + } + + inline void SetOutlinePen(wxPen *pen) + { + m_outlinePen = pen; + } + inline wxPen *GetOutlinePen() const + { + return m_outlinePen; + } + + inline void SetOutlineOp(int op) + { + m_outlineOp = op; + } + inline int GetOutlineOp() const + { + return m_outlineOp; + } + + inline wxList &GetOps() const + { + return (wxList &) m_ops; + } + + // Is this a valid (non-empty) metafile? + inline bool IsValid() const + { + return (m_ops.GetCount() > 0); + } + +public: + /// Set of functions for drawing into a pseudo metafile. + /// They use integers, but doubles are used internally for accuracy + /// when scaling. + + virtual void DrawLine(const wxPoint &pt1, const wxPoint &pt2); + virtual void DrawRectangle(const wxRect &rect); + virtual void DrawRoundedRectangle(const wxRect &rect, double radius); + virtual void DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt); + virtual void DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle); + virtual void DrawEllipse(const wxRect &rect); + virtual void DrawPoint(const wxPoint &pt); + virtual void DrawText(const wxString &text, const wxPoint &pt); + virtual void DrawLines(int n, wxPoint pts[]); + // flags: + // oglMETAFLAGS_OUTLINE: will be used for drawing the outline and + // also drawing lines/arrows at the circumference. + // oglMETAFLAGS_ATTACHMENTS: will be used for initialising attachment points at + // the vertices (perhaps a rare case...) + virtual void DrawPolygon(int n, wxPoint pts[], int flags = 0); + virtual void DrawSpline(int n, wxPoint pts[]); + + virtual void SetClippingRect(const wxRect &rect); + virtual void DestroyClippingRect(); + + virtual void SetPen(wxPen *pen, bool isOutline = FALSE); // TODO: eventually, just store GDI object attributes, not actual + virtual void SetBrush(wxBrush *brush, bool isFill = FALSE); // pens/brushes etc. + virtual void SetFont(wxFont *font); + virtual void SetTextColour(const wxColour &colour); + virtual void SetBackgroundColour(const wxColour &colour); + virtual void SetBackgroundMode(int mode); + +public: + bool m_rotateable; + double m_width; + double m_height; + wxList m_ops; // List of drawing operations (see drawnp.h) + wxList m_gdiObjects; // List of pens, brushes and fonts for this object. + int m_outlineOp; // The op representing the outline, if any + + // Pen/brush specifying outline/fill colours + // to override operations. + wxPen *m_outlinePen; + wxBrush *m_fillBrush; + wxList m_outlineColours; // List of the GDI operations that comprise the outline + wxList m_fillColours; // List of the GDI operations that fill the shape + double m_currentRotation; +}; + +#define oglDRAWN_ANGLE_0 0 +#define oglDRAWN_ANGLE_90 1 +#define oglDRAWN_ANGLE_180 2 +#define oglDRAWN_ANGLE_270 3 + +class wxDrawnShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxDrawnShape) +public: + wxDrawnShape(); + ~wxDrawnShape(); + + void OnDraw(wxDC &dc); + +#if wxUSE_PROLOGIO + // I/O + void WriteAttributes(wxExpr *clause); + void ReadAttributes(wxExpr *clause); +#endif + + // Does the copying for this object + void Copy(wxShape ©); + + void Scale(double sx, double sy); + void Translate(double x, double y); + // Rotate about the given axis by theta radians from the x axis. + void Rotate(double x, double y, double theta); + + // Get current rotation + inline double GetRotation() const + { + return m_rotation; + } + + void SetSize(double w, double h, bool recursive = TRUE); + bool LoadFromMetaFile(const wxString &filename); + + inline void SetSaveToFile(bool save) + { + m_saveToFile = save; + } + inline wxPseudoMetaFile &GetMetaFile(int which = 0) const + { + return (wxPseudoMetaFile &) m_metafiles[which]; + } + + void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + + // Get the perimeter point using the special outline op, if there is one, + // otherwise use default wxRectangleShape scheme + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3); + + /// Set of functions for drawing into a pseudo metafile. + /// They use integers, but doubles are used internally for accuracy + /// when scaling. + + virtual void DrawLine(const wxPoint &pt1, const wxPoint &pt2); + virtual void DrawRectangle(const wxRect &rect); + virtual void DrawRoundedRectangle(const wxRect &rect, double radius); + virtual void DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt); + virtual void DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle); + virtual void DrawEllipse(const wxRect &rect); + virtual void DrawPoint(const wxPoint &pt); + virtual void DrawText(const wxString &text, const wxPoint &pt); + virtual void DrawLines(int n, wxPoint pts[]); + virtual void DrawPolygon(int n, wxPoint pts[], int flags = 0); + virtual void DrawSpline(int n, wxPoint pts[]); + + virtual void SetClippingRect(const wxRect &rect); + virtual void DestroyClippingRect(); + + virtual void SetDrawnPen(wxPen *pen, bool isOutline = FALSE); // TODO: eventually, just store GDI object attributes, not actual + virtual void SetDrawnBrush(wxBrush *brush, bool isFill = FALSE); // pens/brushes etc. + virtual void SetDrawnFont(wxFont *font); + virtual void SetDrawnTextColour(const wxColour &colour); + virtual void SetDrawnBackgroundColour(const wxColour &colour); + virtual void SetDrawnBackgroundMode(int mode); + + // Set the width/height according to the shapes in the metafile. + // Call this after drawing into the shape. + inline void CalculateSize() + { + m_metafiles[m_currentAngle].CalculateSize(this); + } + + inline void DrawAtAngle(int angle) + { + m_currentAngle = angle; + }; + + inline int GetAngle() const + { + return m_currentAngle; + } + +// Implementation +protected: + // Which metafile do we use now? Based on current rotation and validity + // of metafiles. + int DetermineMetaFile(double rotation); + +private: + // One metafile for each 90 degree rotation (or just a single one). + wxPseudoMetaFile m_metafiles[4]; + + // Don't save all wxDrawnShape metafiles to file: sometimes + // we take the metafile data from a symbol library. + bool m_saveToFile; + + // Which angle are we using/drawing into? + int m_currentAngle; +}; + +#endif +// _DRAWN_H_ + diff --git a/include/ogl/drawnp.h b/include/ogl/drawnp.h new file mode 100644 index 0000000..ea77f20 --- /dev/null +++ b/include/ogl/drawnp.h @@ -0,0 +1,220 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// drawnp.h - Private header for wxDrawnShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_DRAWNP_H_ +#define _OGL_DRAWNP_H_ + +/* + * Drawing operations + * + */ + +#define DRAWOP_SET_PEN 1 +#define DRAWOP_SET_BRUSH 2 +#define DRAWOP_SET_FONT 3 +#define DRAWOP_SET_TEXT_COLOUR 4 +#define DRAWOP_SET_BK_COLOUR 5 +#define DRAWOP_SET_BK_MODE 6 +#define DRAWOP_SET_CLIPPING_RECT 7 +#define DRAWOP_DESTROY_CLIPPING_RECT 8 + +/* +#define DRAWOP_CREATE_PEN 10 +#define DRAWOP_CREATE_BRUSH 11 +#define DRAWOP_CREATE_FONT 12 +*/ + +#define DRAWOP_DRAW_LINE 20 +#define DRAWOP_DRAW_POLYLINE 21 +#define DRAWOP_DRAW_POLYGON 22 +#define DRAWOP_DRAW_RECT 23 +#define DRAWOP_DRAW_ROUNDED_RECT 24 +#define DRAWOP_DRAW_ELLIPSE 25 +#define DRAWOP_DRAW_POINT 26 +#define DRAWOP_DRAW_ARC 27 +#define DRAWOP_DRAW_TEXT 28 +#define DRAWOP_DRAW_SPLINE 29 +#define DRAWOP_DRAW_ELLIPTIC_ARC 30 + +/* + * Base, virtual class + * + */ + +class wxDrawOp: public wxObject +{ +public: + inline wxDrawOp(int theOp) + { + m_op = theOp; + } + inline ~wxDrawOp() {} + inline virtual void Scale(double xScale, double yScale) {}; + inline virtual void Translate(double x, double y) {}; + inline virtual void Rotate(double x, double y, double theta, double sinTheta, double cosTheta) {}; + virtual void Do(wxDC &dc, double xoffset, double yoffset) = 0; + virtual wxDrawOp *Copy(wxPseudoMetaFile *newImage) = 0; +#if wxUSE_PROLOGIO + virtual wxExpr *WriteExpr(wxPseudoMetaFile *image) = 0; + virtual void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr) = 0; +#endif + inline int GetOp() const + { + return m_op; + } + + // Draw an outline using the current operation. By default, return FALSE (not drawn) + virtual bool OnDrawOutline(wxDC &dc, double x, double y, double w, double h, + double oldW, double oldH) + { + return FALSE; + } + + // Get the perimeter point using this data + virtual bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3, + double xOffset, double yOffset, + int attachmentMode) + { + return FALSE; + } + +protected: + int m_op; + +}; + +/* + * Set font, brush, text colour + * + */ + +class wxOpSetGDI: public wxDrawOp +{ +public: + wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode = 0); + void Do(wxDC &dc, double xoffset, double yoffset); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + +public: + int m_mode; + int m_gdiIndex; + wxPseudoMetaFile *m_image; + unsigned char m_r; + unsigned char m_g; + unsigned char m_b; +}; + +/* + * Set/destroy clipping + * + */ + +class wxOpSetClipping: public wxDrawOp +{ +public: + wxOpSetClipping(int theOp, double theX1, double theY1, double theX2, double theY2); + void Do(wxDC &dc, double xoffset, double yoffset); + void Scale(double xScale, double yScale); + void Translate(double x, double y); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + +public: + double m_x1; + double m_y1; + double m_x2; + double m_y2; +}; + +/* + * Draw line, rectangle, rounded rectangle, ellipse, point, arc, text + * + */ + +class wxOpDraw: public wxDrawOp +{ +public: + wxOpDraw(int theOp, double theX1, double theY1, double theX2, double theY2, + double radius = 0.0, wxChar *s = NULL); + ~wxOpDraw(); + void Do(wxDC &dc, double xoffset, double yoffset); + void Scale(double scaleX, double scaleY); + void Translate(double x, double y); + void Rotate(double x, double y, double theta, double sinTheta, double cosTheta); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + +public: + double m_x1; + double m_y1; + double m_x2; + double m_y2; + double m_x3; + double m_y3; + double m_radius; + wxChar *m_textString; + +}; + +/* + * Draw polyline, spline, polygon + * + */ + +class wxOpPolyDraw: public wxDrawOp +{ +public: + wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints); + ~wxOpPolyDraw(); + void Do(wxDC &dc, double xoffset, double yoffset); + void Scale(double scaleX, double scaleY); + void Translate(double x, double y); + void Rotate(double x, double y, double theta, double sinTheta, double cosTheta); + wxDrawOp *Copy(wxPseudoMetaFile *newImage); +#if wxUSE_PROLOGIO + wxExpr *WriteExpr(wxPseudoMetaFile *image); + void ReadExpr(wxPseudoMetaFile *image, wxExpr *expr); +#endif + + // Draw an outline using the current operation. + virtual bool OnDrawOutline(wxDC &dc, double x, double y, double w, double h, + double oldW, double oldH); + + // Get the perimeter point using this data + bool GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3, + double xOffset, double yOffset, + int attachmentMode); + +public: + wxRealPoint *m_points; + int m_noPoints; + +}; + +#endif +// _OGL_DRAWNP_H_ + + diff --git a/include/ogl/lines.h b/include/ogl/lines.h new file mode 100644 index 0000000..8333a45 --- /dev/null +++ b/include/ogl/lines.h @@ -0,0 +1,403 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// lines.h - wxLineShape +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_LINES_H_ +#define _OGL_LINES_H_ + +class wxLabelShape; +class wxPseudoMetaFile; +class wxLineControlPoint; +/* + * Arcs with multiple arrowheads + * + */ + +// Types of arrowhead +// (i) Built-in +#define ARROW_HOLLOW_CIRCLE 1 +#define ARROW_FILLED_CIRCLE 2 +#define ARROW_ARROW 3 +#define ARROW_SINGLE_OBLIQUE 4 +#define ARROW_DOUBLE_OBLIQUE 5 +// (ii) Custom +#define ARROW_METAFILE 20 + +// Position of arrow on line +#define ARROW_POSITION_START 0 +#define ARROW_POSITION_END 1 +#define ARROW_POSITION_MIDDLE 2 + +// Line alignment flags +// Vertical by default +#define LINE_ALIGNMENT_HORIZ 1 +#define LINE_ALIGNMENT_VERT 0 +#define LINE_ALIGNMENT_TO_NEXT_HANDLE 2 +#define LINE_ALIGNMENT_NONE 0 + +class wxArrowHead: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxArrowHead) + +public: + wxArrowHead(WXTYPE type = 0, int end = 0, double size = 0.0, double dist = 0.0, const wxString &name = wxEmptyString, wxPseudoMetaFile *mf = NULL, + long arrowId = -1); + ~wxArrowHead(); + wxArrowHead(wxArrowHead &toCopy); + + inline WXTYPE _GetType() const + { + return m_arrowType; + } + inline int GetPosition() const + { + return m_arrowEnd; + } + inline void SetPosition(int pos) + { + m_arrowEnd = pos; + } + inline double GetXOffset() const + { + return m_xOffset; + } + inline double GetYOffset() const + { + return m_yOffset; + } + inline double GetSpacing() const + { + return m_spacing; + } + inline double GetSize() const + { + return m_arrowSize; + } + inline wxString GetName() const + { + return m_arrowName; + } + inline void SetXOffset(double x) + { + m_xOffset = x; + } + inline void SetYOffset(double y) + { + m_yOffset = y; + } + inline wxPseudoMetaFile *GetMetaFile() const + { + return m_metaFile; + } + inline long GetId() const + { + return m_id; + } + inline int GetArrowEnd() const + { + return m_arrowEnd; + } + inline double GetArrowSize() const + { + return m_arrowSize; + } + void SetSize(double size); + inline void SetSpacing(double sp) + { + m_spacing = sp; + } + +protected: + WXTYPE m_arrowType; + int m_arrowEnd; // Position on line + double m_xOffset; // Distance from arc start or end, w.r.t. point on arrowhead + // nearest start or end. If zero, use default spacing. + double m_yOffset; // vertical offset (w.r.t. a horizontal line). Normally zero. + double m_spacing; // Spacing from the last arrowhead + double m_arrowSize; // Length of arrowhead + wxString m_arrowName; // Name of arrow + bool m_saveToFile; // TRUE if we want to save custom arrowheads to file. + wxPseudoMetaFile *m_metaFile; // Pseudo metafile if this is a custom arrowhead + long m_id; // identifier +}; + +// Line object +class wxLabelShape; +class wxLineShape: public wxShape +{ + DECLARE_DYNAMIC_CLASS(wxLineShape) + +public: + wxLineShape(); + ~wxLineShape(); + + // Called when a connected object has moved, to move the link to + // correct position + // moveControlPoints must be disabled when a control point is being + // dragged. + void OnMoveLink(bool moveControlPoints = TRUE); + bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + void OnDrawControlPoints(wxDC &dc); + virtual bool OnMoveControlPoint(int WXUNUSED(which), double WXUNUSED(x), double WXUNUSED(y)) + { + return FALSE; + } + virtual bool OnMoveMiddleControlPoint(wxLineControlPoint *lpt, const wxRealPoint &pt); + virtual bool OnLabelMovePre(wxLabelShape *labelShape, double x, double y, double old_x, double old_y, bool display); + void OnDrawOutline(wxDC &dc, double x, double y, double w, double h); + void GetBoundingBoxMin(double *w, double *h); + void FormatText(wxDC &dc, const wxString &s, int regionId = 0); + virtual void SetEnds(double x1, double y1, double x2, double y2); + virtual void GetEnds(double *x1, double *y1, double *x2, double *y2); + inline virtual wxShape *GetFrom() + { + return m_from; + } + inline virtual wxShape *GetTo() + { + return m_to; + } + inline virtual int GetAttachmentFrom() + { + return m_attachmentFrom; + } + inline virtual int GetAttachmentTo() + { + return m_attachmentTo; + } + + virtual void SetFrom(wxShape *object); + virtual void SetTo(wxShape *object); + virtual void DrawArrows(wxDC &dc); + + // Finds the x, y points at the two ends of the line. + // This function can be used by e.g. line-routing routines to + // get the actual points on the two node images where the lines will be drawn + // to/from. + void FindLineEndPoints(double *fromX, double *fromY, double *toX, double *toY); + + // Format one region at this position + void DrawRegion(wxDC &dc, wxShapeRegion *region, double x, double y); + + // Get the reference point for a label. Region x and y + // are offsets from this. + // position is 0 (middle), 1 (start), 2 (end) + void GetLabelPosition(int position, double *x, double *y); + + // Can override this to create a different class of label shape + virtual wxLabelShape *OnCreateLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); + + // Straighten verticals and horizontals + virtual void Straighten(); + + // Not implemented + inline void SetMaintainStraightLines(bool flag) + { + m_maintainStraightLines = flag; + } + inline bool GetMaintainStraightLines() const + { + return m_maintainStraightLines; + } + + virtual void SetCanvas(wxShapeCanvas *the_canvas); + + // Make handle control points + void MakeControlPoints(); + void ResetControlPoints(); + + // Make a given number of control points + virtual void MakeLineControlPoints(int n); + virtual wxNode *InsertLineControlPoint(); + virtual bool DeleteLineControlPoint(); + virtual void Initialise(); + inline wxList *GetLineControlPoints() + { + return m_lineControlPoints; + } + + // Remove any child shapes before deleting shape. + virtual void RemoveChildren(); + + // Override dragging behaviour - don't want to be able to drag lines! + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + // Control points ('handles') redirect control to the actual shape, to make it easier + // to override sizing behaviour. + virtual void OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + virtual void OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys = 0, int attachment = 0); + + // Override select, to create/delete temporary label-moving objects + void Select(bool select = TRUE); + + // Set to spline (TRUE) or line (FALSE) + inline void SetSpline(bool spl) + { + m_isSpline = spl; + } + inline bool IsSpline() const + { + return m_isSpline; + } + + void Unlink(); + void SetAttachments(int from_attach, int to_attach); + inline void SetAttachmentFrom(int attach) + { + m_attachmentFrom = attach; + } + inline void SetAttachmentTo(int attach) + { + m_attachmentTo = attach; + } + + bool HitTest(double x, double y, int *attachment, double *distance); + +#if wxUSE_PROLOGIO + // I/O + virtual void WriteAttributes(wxExpr *clause); + virtual void ReadAttributes(wxExpr *clause); +#endif + + virtual void FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming); + + // Find which position we're talking about at this (x, y). + // Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END + int FindLinePosition(double x, double y); + + // This is really to distinguish between lines and other images. + // For lines, want to pass drag to canvas, since lines tend to prevent + // dragging on a canvas (they get in the way.) + virtual bool Draggable() const + { + return FALSE; + } + + // Does the copying for this object + void Copy(wxShape ©); + + // Add an arrowhead. + wxArrowHead *AddArrow(WXTYPE type, int end = ARROW_POSITION_END, + double arrowSize = 10.0, double xOffset = 0.0, + const wxString &name = wxEmptyString, + wxPseudoMetaFile *mf = NULL, long arrowId = -1); + + // Add an arrowhead in the position indicated by the reference + // list of arrowheads, which contains all legal arrowheads for this + // line, in the correct order. + // E.g. reference list: a b c d e + // Current line list: a d + // Add c, then line list is: a c d + // If no legal arrowhead position, return FALSE. + // Assume reference list is for one end only, since it potentially defines + // the ordering for any one of the 3 positions. So we don't check + // the reference list for arrowhead position. + bool AddArrowOrdered(wxArrowHead *arrow, wxList &referenceList, int end); + + // Delete arrowhead(s) + void ClearArrowsAtPosition(int end = -1); + bool ClearArrow(const wxString &name); + wxArrowHead *FindArrowHead(int position, const wxString &name); + wxArrowHead *FindArrowHead(long arrowId); + bool DeleteArrowHead(int position, const wxString &name); + bool DeleteArrowHead(long arrowId); + void DrawArrow(wxDC &dc, wxArrowHead *arrow, double xOffset, bool proportionalOffset); + inline void SetIgnoreOffsets(bool ignore) + { + m_ignoreArrowOffsets = ignore; + } + inline wxList &GetArrows() const + { + return (wxList &) m_arcArrows; + } + + // Find horizontal width for drawing a line with + // arrows in minimum space. Assume arrows at + // END only + double FindMinimumWidth(); + + // Set alignment flags. ALIGNMENT NOT IMPLEMENTED. + void SetAlignmentOrientation(bool isEnd, bool isHoriz); + void SetAlignmentType(bool isEnd, int alignType); + bool GetAlignmentOrientation(bool isEnd); + int GetAlignmentType(bool isEnd); + int GetAlignmentStart() const + { + return m_alignmentStart; + } + int GetAlignmentEnd() const + { + return m_alignmentEnd; + } + void SetAlignmentStart(int alignStart) + { + m_alignmentStart = alignStart; + } + void SetAlignmentEnd(int alignEnd) + { + m_alignmentEnd = alignEnd; + } + + // Find next control point in line after the start/end point + // (depending on whether the node object is at start or end) + wxRealPoint *GetNextControlPoint(wxShape *nodeObject); + inline bool IsEnd(wxShape *nodeObject) const + { + return (m_to == nodeObject); + } + +private: + bool m_erasing; // flag to say whether we're erasing or drawing + // this line (really so metafiles can draw a + // blank rectangle) + bool m_ignoreArrowOffsets; // Don't always want to draw arrowhead offsets + // because they may not work on tool palettes (for example) + bool m_isSpline; + bool m_maintainStraightLines; + +protected: + // Temporary list of line segment orientations + // so we know what direction the line is supposed to be dog-legging + // in. The values are integer: 0 for vertical, 1 for horizontal. + wxList m_lineOrientations; + + // Temporary pointers for start, middle and end label editing objects + // (active only when the line is selected) + wxLabelShape *m_labelObjects[3]; + + // These define the segmented line - not to be confused with temporary control + // points which appear when object is selected (although in this case they'll + // probably be the same) + wxList *m_lineControlPoints; + + double m_arrowSpacing; // Separation between adjacent arrows + + wxShape *m_to; + wxShape *m_from; + + int m_attachmentTo; // Attachment point at one end + int m_attachmentFrom; // Attachment point at other end + + // Alignment flags + int m_alignmentStart; + int m_alignmentEnd; + + wxList m_arcArrows; + +}; + +#endif +// _OGL_LINES_H_ diff --git a/include/ogl/linesp.h b/include/ogl/linesp.h new file mode 100644 index 0000000..25518b4 --- /dev/null +++ b/include/ogl/linesp.h @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// linesp.h - Lines private header file +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_LINESP_H_ +#define _OGL_LINESP_H_ + +class wxLineShape; +class wxLineControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxLineControlPoint) + friend class wxLineShape; +public: + + wxLineControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, double size = 0.0, + double x = 0.0, double y = 0.0, int the_type = 0); + ~wxLineControlPoint(); + + void OnDraw(wxDC &dc); + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + + // Obsolete (left-dragging now moves attachment point to new relative position OR new + // attachment id) +#if 0 + void OnDragRight(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragRight(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragRight(double x, double y, int keys = 0, int attachment = 0); +#endif + +public: + + int m_type; + wxRealPoint *m_point; // Line point + wxRealPoint m_originalPos; + +}; + +/* + * Temporary arc label object + */ + +class wxLabelShape: public wxRectangleShape +{ + DECLARE_DYNAMIC_CLASS(wxLabelShape) + +public: + wxLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, double w = 0.0, double h = 0.0); + ~wxLabelShape(); + + void OnDraw(wxDC &dc); + void OnDrawContents(wxDC &dc); + void OnLeftClick(double x, double y, int keys = 0, int attachment = 0); + void OnRightClick(double x, double y, int keys = 0, int attachment = 0); + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); + bool OnMovePre(double x, double y, double old_x, double old_y, bool display = TRUE); + +public: + wxLineShape *m_lineShape; + wxShapeRegion *m_shapeRegion; + +}; + +/* + * Get the point on the given line (x1, y1) (x2, y2) + * distance 'length' along from the end, + * returned values in x and y + */ + +void GetPointOnLine(double x1, double y1, double x2, double y2, + double length, double *x, double *y); + +#endif +// _OGL_LINESP_H_ + diff --git a/include/ogl/mfutils.h b/include/ogl/mfutils.h new file mode 100644 index 0000000..9e5bdfb --- /dev/null +++ b/include/ogl/mfutils.h @@ -0,0 +1,418 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// mfutils.h - Metafile utilities: reading a placeable metafile independently of Windows. +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _MFUTILS_H_ +#define _MFUTILS_H_ + +#include + +#ifndef GetRValue +#define GetRValue(rgb) ((unsigned char)(rgb)) +#define GetGValue(rgb) ((unsigned char)(((int)(rgb)) >> 8)) +#define GetBValue(rgb) ((unsigned char)((rgb)>>16)) +#endif + +/* Metafile Functions */ +// some compilers have them in their include files + +#ifndef META_SETBKCOLOR +#define META_SETBKCOLOR 0x0201 +#endif +#ifndef META_SETBKMODE +#define META_SETBKMODE 0x0102 +#endif +#ifndef META_SETMAPMODE +#define META_SETMAPMODE 0x0103 +#endif +#ifndef META_SETROP2 +#define META_SETROP2 0x0104 +#endif +#ifndef META_SETRELABS +#define META_SETRELABS 0x0105 +#endif +#ifndef META_SETPOLYFILLMODE +#define META_SETPOLYFILLMODE 0x0106 +#endif +#ifndef META_SETSTRETCHBLTMODE +#define META_SETSTRETCHBLTMODE 0x0107 +#endif +#ifndef META_SETTEXTCHAREXTRA +#define META_SETTEXTCHAREXTRA 0x0108 +#endif +#ifndef META_SETTEXTCOLOR +#define META_SETTEXTCOLOR 0x0209 +#endif +#ifndef META_SETTEXTJUSTIFICATION +#define META_SETTEXTJUSTIFICATION 0x020A +#endif +#ifndef META_SETWINDOWORG +#define META_SETWINDOWORG 0x020B +#endif +#ifndef META_SETWINDOWEXT +#define META_SETWINDOWEXT 0x020C +#endif +#ifndef META_SETVIEWPORTORG +#define META_SETVIEWPORTORG 0x020D +#endif +#ifndef META_SETVIEWPORTEXT +#define META_SETVIEWPORTEXT 0x020E +#endif +#ifndef META_OFFSETWINDOWORG +#define META_OFFSETWINDOWORG 0x020F +#endif +#ifndef META_SCALEWINDOWEXT +#define META_SCALEWINDOWEXT 0x0410 +#endif +#ifndef META_OFFSETVIEWPORTORG +#define META_OFFSETVIEWPORTORG 0x0211 +#endif +#ifndef META_SCALEVIEWPORTEXT +#define META_SCALEVIEWPORTEXT 0x0412 +#endif +#ifndef META_LINETO +#define META_LINETO 0x0213 +#endif +#ifndef META_MOVETO +#define META_MOVETO 0x0214 +#endif +#ifndef META_EXCLUDECLIPRECT +#define META_EXCLUDECLIPRECT 0x0415 +#endif +#ifndef META_INTERSECTCLIPRECT +#define META_INTERSECTCLIPRECT 0x0416 +#endif +#ifndef META_ARC +#define META_ARC 0x0817 +#endif +#ifndef META_ELLIPSE +#define META_ELLIPSE 0x0418 +#endif +#ifndef META_FLOODFILL +#define META_FLOODFILL 0x0419 +#endif +#ifndef META_PIE +#define META_PIE 0x081A +#endif +#ifndef META_RECTANGLE +#define META_RECTANGLE 0x041B +#endif +#ifndef META_ROUNDRECT +#define META_ROUNDRECT 0x061C +#endif +#ifndef META_PATBLT +#define META_PATBLT 0x061D +#endif +#ifndef META_SAVEDC +#define META_SAVEDC 0x001E +#endif +#ifndef META_SETPIXEL +#define META_SETPIXEL 0x041F +#endif +#ifndef META_OFFSETCLIPRGN +#define META_OFFSETCLIPRGN 0x0220 +#endif +#ifndef META_TEXTOUT +#define META_TEXTOUT 0x0521 +#endif +#ifndef META_BITBLT +#define META_BITBLT 0x0922 +#endif +#ifndef META_STRETCHBLT +#define META_STRETCHBLT 0x0B23 +#endif +#ifndef META_POLYGON +#define META_POLYGON 0x0324 +#endif +#ifndef META_POLYLINE +#define META_POLYLINE 0x0325 +#endif +#ifndef META_ESCAPE +#define META_ESCAPE 0x0626 +#endif +#ifndef META_RESTOREDC +#define META_RESTOREDC 0x0127 +#endif +#ifndef META_FILLREGION +#define META_FILLREGION 0x0228 +#endif +#ifndef META_FRAMEREGION +#define META_FRAMEREGION 0x0429 +#endif +#ifndef META_INVERTREGION +#define META_INVERTREGION 0x012A +#endif +#ifndef META_PAINTREGION +#define META_PAINTREGION 0x012B +#endif +#ifndef META_SELECTCLIPREGION +#define META_SELECTCLIPREGION 0x012C +#endif +#ifndef META_SELECTOBJECT +#define META_SELECTOBJECT 0x012D +#endif +#ifndef META_SETTEXTALIGN +#define META_SETTEXTALIGN 0x012E +#endif +#ifndef META_DRAWTEXT +#define META_DRAWTEXT 0x062F +#endif + +#ifndef META_CHORD +#define META_CHORD 0x0830 +#endif +#ifndef META_SETMAPPERFLAGS +#define META_SETMAPPERFLAGS 0x0231 +#endif +#ifndef META_EXTTEXTOUT +#define META_EXTTEXTOUT 0x0a32 +#endif +#ifndef META_SETDIBTODEV +#define META_SETDIBTODEV 0x0d33 +#endif +#ifndef META_SELECTPALETTE +#define META_SELECTPALETTE 0x0234 +#endif +#ifndef META_REALIZEPALETTE +#define META_REALIZEPALETTE 0x0035 +#endif +#ifndef META_ANIMATEPALETTE +#define META_ANIMATEPALETTE 0x0436 +#endif +#ifndef META_SETPALENTRIES +#define META_SETPALENTRIES 0x0037 +#endif +#ifndef META_POLYPOLYGON +#define META_POLYPOLYGON 0x0538 +#endif +#ifndef META_RESIZEPALETTE +#define META_RESIZEPALETTE 0x0139 +#endif + +#ifndef META_DIBBITBLT +#define META_DIBBITBLT 0x0940 +#endif +#ifndef META_DIBSTRETCHBLT +#define META_DIBSTRETCHBLT 0x0b41 +#endif +#ifndef META_DIBCREATEPATTERNBRUSH +#define META_DIBCREATEPATTERNBRUSH 0x0142 +#endif +#ifndef META_STRETCHDIB +#define META_STRETCHDIB 0x0f43 +#endif + +#ifndef META_EXTFLOODFILL +#define META_EXTFLOODFILL 0x0548 +#endif + +#ifndef META_RESETDC +#define META_RESETDC 0x014C +#endif +#ifndef META_STARTDOC +#define META_STARTDOC 0x014D +#endif +#ifndef META_STARTPAGE +#define META_STARTPAGE 0x004F +#endif +#ifndef META_ENDPAGE +#define META_ENDPAGE 0x0050 +#endif +#ifndef META_ABORTDOC +#define META_ABORTDOC 0x0052 +#endif +#ifndef META_ENDDOC +#define META_ENDDOC 0x005E +#endif + +#ifndef META_DELETEOBJECT +#define META_DELETEOBJECT 0x01f0 +#endif + +#ifndef META_CREATEPALETTE +#define META_CREATEPALETTE 0x00f7 +#endif +#ifndef META_CREATEBRUSH +#define META_CREATEBRUSH 0x00F8 +#endif +#ifndef META_CREATEPATTERNBRUSH +#define META_CREATEPATTERNBRUSH 0x01F9 +#endif +#ifndef META_CREATEPENINDIRECT +#define META_CREATEPENINDIRECT 0x02FA +#endif +#ifndef META_CREATEFONTINDIRECT +#define META_CREATEFONTINDIRECT 0x02FB +#endif +#ifndef META_CREATEBRUSHINDIRECT +#define META_CREATEBRUSHINDIRECT 0x02FC +#endif +#ifndef META_CREATEBITMAPINDIRECT +#define META_CREATEBITMAPINDIRECT 0x02FD +#endif +#ifndef META_CREATEBITMAP +#define META_CREATEBITMAP 0x06FE +#endif +#ifndef META_CREATEREGION +#define META_CREATEREGION 0x06FF +#endif + +/* Background Modes */ +#ifndef TRANSPARENT +#define TRANSPARENT 1 +#endif +#ifndef OPAQUE +#define OPAQUE 2 +#endif + +/* Pen Styles */ +#ifndef PS_SOLID +#define PS_SOLID 0 +#endif +#ifndef PS_DASH +#define PS_DASH 1 +#endif +#ifndef PS_DOT +#define PS_DOT 2 +#endif +#ifndef PS_DASHDOT +#define PS_DASHDOT 3 +#endif +#ifndef PS_DASHDOTDOT +#define PS_DASHDOTDOT 4 +#endif +#ifndef PS_NULL +#define PS_NULL 5 +#endif +#ifndef PS_INSIDEFRAME +#define PS_INSIDEFRAME 6 +#endif + +/* PitchAndFamily family values (high 4 bits) */ +#ifndef FF_DONTCARE +#define FF_DONTCARE 0x00 +#endif +#ifndef FF_ROMAN +#define FF_ROMAN 0x10 +#endif +#ifndef FF_SWISS +#define FF_SWISS 0x20 +#endif +#ifndef FF_MODERN +#define FF_MODERN 0x30 +#endif +#ifndef FF_SCRIPT +#define FF_SCRIPT 0x40 +#endif +#ifndef FF_DECORATIVE +#define FF_DECORATIVE 0x50 +#endif + +/* Brush Styles */ +#ifndef BS_SOLID +#define BS_SOLID 0 +#endif +#ifndef BS_NULL +#define BS_NULL 1 +#endif +#ifndef BS_HOLLOW +#define BS_HOLLOW BS_NULL +#endif +#ifndef BS_HATCHED +#define BS_HATCHED 2 +#endif +#ifndef BS_PATTERN +#define BS_PATTERN 3 +#endif +#ifndef BS_INDEXED +#define BS_INDEXED 4 +#endif +#ifndef BS_DIBPATTERN +#define BS_DIBPATTERN 5 +#endif + +/* Hatch Styles */ +#ifndef HS_HORIZONTAL +#define HS_HORIZONTAL 0 +#endif +#ifndef HS_VERTICAL +#define HS_VERTICAL 1 +#endif +#ifndef HS_FDIAGONAL +#define HS_FDIAGONAL 2 +#endif +#ifndef HS_BDIAGONAL +#define HS_BDIAGONAL 3 +#endif +#ifndef HS_CROSS +#define HS_CROSS 4 +#endif +#ifndef HS_DIAGCROSS +#define HS_DIAGCROSS 5 +#endif + +class wxMetaRecord: public wxObject +{ +public: + int metaFunction; + long param1; + long param2; + long param3; + long param4; + long param5; + long param6; + long param7; + long param8; + wxChar *stringParam; + wxRealPoint *points; + + wxMetaRecord(int fun) + { + metaFunction = fun; + points = NULL; + stringParam = NULL; + param1 = 0; + } + ~wxMetaRecord(void); +}; + +class wxXMetaFile: public wxObject +{ +public: + double lastX; + double lastY; + bool ok; + + double left; + double top; + double right; + double bottom; + + wxList metaRecords; + wxList gdiObjects; // List of wxMetaRecord objects created with Create..., + // referenced by position in list by SelectObject + wxXMetaFile(const wxChar *file = NULL); + ~wxXMetaFile(void); + + // After this is called, the metafile cannot be used for anything + // since it is now owned by the clipboard. + bool SetClipboard(int width = 0, int height = 0); + + bool Play(wxDC *dc); + inline bool Ok(void) const + { + return ok; + } + bool ReadFile(const wxChar *file); +}; + +#endif +// _MFUTILS_H_ diff --git a/include/ogl/misc.h b/include/ogl/misc.h new file mode 100644 index 0000000..20c0972 --- /dev/null +++ b/include/ogl/misc.h @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.h - Miscellaneous utilities for OGL +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_MISC_H_ +#define _OGL_MISC_H_ + +// List to use when copying objects; may need to associate elements of new objects +// with elements of old objects, e.g. when copying constraint.s +extern wxList oglObjectCopyMapping; + +/* + * TEXT FORMATTING FUNCTIONS + * + */ + +// Centres the given list of wxShapeTextLine strings in the given box +// (changing the positions in situ). Doesn't actually draw into the DC. +void oglCentreText(wxDC &dc, wxList *text, double m_xpos, double m_ypos, + double width, double height, + int formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT); + +// Given a string, returns a list of strings that fit within the given +// width of box. Height is ignored. +wxArrayString *oglFormatText(wxDC &dc, const wxString &text, double width, double height, int formatMode = 0); + +// Centres the list of wxShapeTextLine strings, doesn't clip. +// Doesn't actually draw into the DC. +void oglCentreTextNoClipping(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height); + +// Gets the maximum width and height of the given list of wxShapeTextLines. +void oglGetCentredTextExtent(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + double *actual_width, double *actual_height); + +// Actually draw the preformatted list of wxShapeTextLines. +void oglDrawFormattedText(wxDC &context, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + int formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT); + +// Give it a list of points, finds the centre. +void oglFindPolylineCentroid(wxList *points, double *x, double *y); + +void oglCheckLineIntersection(double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4, + double *ratio1, double *ratio2); + +void oglFindEndForPolyline(double n, double xvec[], double yvec[], + double x1, double y1, double x2, double y2, double *x3, double *y3); + + +void oglFindEndForBox(double width, double height, + double x1, double y1, // Centre of box (possibly) + double x2, double y2, // other end of line + double *x3, double *y3); // End on box edge + +void oglFindEndForCircle(double radius, + double x1, double y1, // Centre of circle + double x2, double y2, // Other end of line + double *x3, double *y3); + +void oglGetArrowPoints(double x1, double y1, double x2, double y2, + double length, double width, + double *tip_x, double *tip_y, + double *side1_x, double *side1_y, + double *side2_x, double *side2_y); + +/* + * Given an ellipse and endpoints of a line, returns the point at which + * the line touches the ellipse in values x4, y4. + * This function assumes that the centre of the ellipse is at x1, y1, and the + * ellipse has a width of a1 and a height of b1. It also assumes you are + * wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3. + * This function calculates the x,y coordinates of the intersection point of + * the arc with the ellipse. + * Author: Ian Harrison + */ + +void oglDrawArcToEllipse(double x1, double y1, double a1, double b1, double x2, double y2, double x3, double y3, + double *x4, double *y4); + +bool oglRoughlyEqual(double val1, double val2, double tol = 0.00001); + +extern wxFont *g_oglNormalFont; +extern wxPen *g_oglBlackPen; +extern wxPen *g_oglWhiteBackgroundPen; +extern wxPen *g_oglTransparentPen; +extern wxBrush *g_oglWhiteBackgroundBrush; +extern wxPen *g_oglBlackForegroundPen; + +extern wxFont *oglMatchFont(int point_size); + +extern wxString oglColourToHex(const wxColour &colour); +extern wxColour oglHexToColour(const wxString &hex); +extern void oglDecToHex(unsigned int dec, char *buf); +extern unsigned int oglHexToDec(char *buf); + + +#endif +// _OGL_MISC_H_ diff --git a/include/ogl/module.mk b/include/ogl/module.mk new file mode 100644 index 0000000..c5bcf94 --- /dev/null +++ b/include/ogl/module.mk @@ -0,0 +1,32 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/ogl/basic.h \ + include/ogl/bmpshape.h \ + include/ogl/composit.h \ + include/ogl/divided.h \ + include/ogl/drawnp.h \ + include/ogl/linesp.h \ + include/ogl/misc.h \ + include/ogl/ogl.h \ + include/ogl/basicp.h \ + include/ogl/canvas.h \ + include/ogl/constrnt.h \ + include/ogl/drawn.h \ + include/ogl/lines.h \ + include/ogl/mfutils.h \ + include/ogl/ogldiag.h + +EXTRA_DIST += \ + include/ogl/module.mk \ + include/ogl/README + diff --git a/include/ogl/ogl.h b/include/ogl/ogl.h new file mode 100644 index 0000000..e06ff79 --- /dev/null +++ b/include/ogl/ogl.h @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ogl.h - OGL main include +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_OGL_H_ +#define _OGL_OGL_H_ + +#include "ogl/basic.h" // Basic shapes +#include "ogl/basicp.h" +#include "ogl/lines.h" // Lines and splines +#include "ogl/linesp.h" +#include "ogl/divided.h" // Vertically-divided rectangle +#include "ogl/composit.h" // Composite images +#include "ogl/canvas.h" // wxShapeCanvas for displaying objects +#include "ogl/ogldiag.h" // wxDiagram + +#include "ogl/bmpshape.h" +#include "ogl/constrnt.h" +#include "ogl/drawn.h" +#include "ogl/drawnp.h" +#include "ogl/mfutils.h" +#include "ogl/misc.h" + +// TODO: replace with wxModule implementation +extern void wxOGLInitialize(); +extern void wxOGLCleanUp(); + +#endif +// _OGL_OGL_H_ diff --git a/include/ogl/ogldiag.h b/include/ogl/ogldiag.h new file mode 100644 index 0000000..5824ed6 --- /dev/null +++ b/include/ogl/ogldiag.h @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ogldiag.h - OGL - wxDiagram class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef _OGL_OGLDIAG_H_ +#define _OGL_OGLDIAG_H_ + +#include "ogl/basic.h" + +#if wxUSE_PROLOGIO +#include +#endif + + +class wxDiagram: public wxObject +{ + DECLARE_DYNAMIC_CLASS(wxDiagram) + +public: + + wxDiagram(); + virtual ~wxDiagram(); + + void SetCanvas(wxShapeCanvas *can); + + inline wxShapeCanvas *GetCanvas() const + { + return m_diagramCanvas; + } + + virtual void Redraw(wxDC &dc); + virtual void Clear(wxDC &dc); + virtual void DrawOutline(wxDC &dc, double x1, double y1, double x2, double y2); + + // Add object to end of object list (if addAfter is NULL) + // or just after addAfter. + virtual void AddShape(wxShape *object, wxShape *addAfter = NULL); + + // Add object to front of object list + virtual void InsertShape(wxShape *object); + + void SetSnapToGrid(bool snap); + void SetGridSpacing(double spacing); + inline double GetGridSpacing() const + { + return m_gridSpacing; + } + inline bool GetSnapToGrid() const + { + return m_snapToGrid; + } + void Snap(double *x, double *y); + + inline void SetQuickEditMode(bool qem) + { + m_quickEditMode = qem; + } + inline bool GetQuickEditMode() const + { + return m_quickEditMode; + } + + virtual void RemoveShape(wxShape *object); + virtual void RemoveAllShapes(); + virtual void DeleteAllShapes(); + virtual void ShowAll(bool show); + + // Find a shape by its id + wxShape *FindShape(long id) const; + + inline void SetMouseTolerance(int tol) + { + m_mouseTolerance = tol; + } + inline int GetMouseTolerance() const + { + return m_mouseTolerance; + } + inline wxList *GetShapeList() const + { + return m_shapeList; + } + inline int GetCount() const + { + return m_shapeList->GetCount(); + } + + // Make sure all text that should be centred, is centred. + void RecentreAll(wxDC &dc); + +#if wxUSE_PROLOGIO + virtual bool SaveFile(const wxString &filename); + virtual bool LoadFile(const wxString &filename); + + virtual void ReadNodes(wxExprDatabase &database); + virtual void ReadLines(wxExprDatabase &database); + virtual void ReadContainerGeometry(wxExprDatabase &database); + + // Allow for modifying file + virtual bool OnDatabaseLoad(wxExprDatabase &db); + virtual bool OnDatabaseSave(wxExprDatabase &db); + virtual bool OnShapeSave(wxExprDatabase &db, wxShape &shape, wxExpr &expr); + virtual bool OnShapeLoad(wxExprDatabase &db, wxShape &shape, wxExpr &expr); + virtual bool OnHeaderSave(wxExprDatabase &db, wxExpr &expr); + virtual bool OnHeaderLoad(wxExprDatabase &db, wxExpr &expr); +#endif + +protected: + wxShapeCanvas *m_diagramCanvas; + bool m_quickEditMode; + bool m_snapToGrid; + double m_gridSpacing; + int m_mouseTolerance; + wxList *m_shapeList; +}; + +class wxLineCrossing: public wxObject +{ +public: + wxLineCrossing() + { + m_lineShape1 = NULL; + m_lineShape2 = NULL; + } + wxRealPoint m_pt1; // First line + wxRealPoint m_pt2; + wxRealPoint m_pt3; // Second line + wxRealPoint m_pt4; + wxRealPoint m_intersect; + wxLineShape *m_lineShape1; + wxLineShape *m_lineShape2; +}; + +class wxLineCrossings: public wxObject +{ +public: + wxLineCrossings(); + ~wxLineCrossings(); + + void FindCrossings(wxDiagram &diagram); + void DrawCrossings(wxDiagram &diagram, wxDC &dc); + void ClearCrossings(); + +public: + wxList m_crossings; +}; + +#endif +// _OGL_OGLDIAG_H_ diff --git a/include/parser/keywords.h b/include/parser/keywords.h new file mode 100644 index 0000000..7fe9872 --- /dev/null +++ b/include/parser/keywords.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------- + * + * keywords.h + * lexical token lookup for reserved words in postgres SQL + * + * + * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL: pgsql/src/include/parser/keywords.h,v 1.21 2006/03/05 15:58:57 momjian Exp $ + * + *------------------------------------------------------------------------- + */ + +/////////////////////////////////////////////////////////////////////////// +// +// pgAdmin note: This file is based on src/include/parser/keywords.h from +// PostgreSQL, but with the token code entry removed. +// +// This file is under the BSD licence, per PostgreSQL. +/////////////////////////////////////////////////////////////////////////// + +#ifndef KEYWORDS_H +#define KEYWORDS_H + +/* Keyword categories --- should match lists in gram.y */ +#define UNRESERVED_KEYWORD 0 +#define COL_NAME_KEYWORD 1 +#define TYPE_FUNC_NAME_KEYWORD 2 +#define RESERVED_KEYWORD 3 + +typedef struct ScanKeyword +{ + const char *name; /* in lower case */ + int category; /* see codes above */ +} ScanKeyword; + +extern const ScanKeyword *ScanKeywordLookup(const char *text); + +extern const ScanKeyword ScanKeywords[]; +extern const ScanKeyword ScanKeywordsExtra[]; +extern const int NumScanKeywords; +extern const int NumScanKeywordsExtra; +#endif /* KEYWORDS_H */ diff --git a/include/parser/module.mk b/include/parser/module.mk new file mode 100644 index 0000000..eca48e3 --- /dev/null +++ b/include/parser/module.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/parser/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/parser/keywords.h + +EXTRA_DIST += \ + include/parser/module.mk diff --git a/include/pgAdmin3.h b/include/pgAdmin3.h new file mode 100644 index 0000000..8b28e7c --- /dev/null +++ b/include/pgAdmin3.h @@ -0,0 +1,262 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAdmin3.h - The main application header +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGADMIN3_H +#define PGADMIN3_H +#include "../utils/diff_match_patch.h" + + +// wxWindows headers +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#endif + +#include "utils/misc.h" +#include +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlListView.h" +#include "ctl/ctlComboBox.h" +#include +#include +#include "dlg/dlgClasses.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "utils/factory.h" + +#include "precomp.h" + +// App headers +#include "utils/sysSettings.h" + +#ifdef __WXMSW__ +#else +#include "config.h" +#undef VERSION +#endif + +// Check the wxWidgets config +#if !wxCHECK_VERSION(2, 8, 0) +#error wxWidgets 2.8.0 or higher is required to compile this version of pgAdmin. +#endif + +#if !wxUSE_UNICODE +#error wxWidgets must be compiled with Unicode support to build pgAdmin. +#endif + +// Supported server minimum and maximum values. +const short SERVER_MIN_VERSION_N = 0x0804; +const wxString SERVER_MIN_VERSION_T = wxT("8.4"); +const short SERVER_MAX_VERSION_N = 0x0D00; +const wxString SERVER_MAX_VERSION_T = wxT("13"); +// Supported Greenplum Database and Greenplum HAWQ minimum and maximum values. +const short GP_MIN_VERSION_N = 0x0802; +const wxString GP_MIN_VERSION_T = wxT("8.2"); +const short GP_MAX_VERSION_N = 0x0803; +const wxString GP_MAX_VERSION_T = wxT("8.3"); + +// The registry file +#ifndef __WXMSW__ +#define REGISTRY_FILE wxT("/etc/postgres-reg.ini") +#endif + +// Some redefines for modern Microsoft compilers +#if defined(_MSC_VER) +#define creat _creat +#define close _close +#define mkdir _mkdir +#define sprintf _sprintf +#define snprintf _snprintf +#define strcat _strcat +#define strdup _strdup +#define stricmp _stricmp +#define strincmp _strincmp +#endif + +extern wxPathList path; // The search path +extern wxString loadPath; // Where the program is loaded from +extern wxString docPath; // Where docs are stored +extern wxString uiPath; // Where ui data is stored +extern wxString i18nPath; // Where i18n data is stored +extern wxString pluginsDir; // The plugins ini file directory +extern wxString settingsIni; // The default settings file + +extern sysSettings *settings; // The settings manager + +extern frmMain *winMain; // The main app window + +extern wxLocale *locale; // Application locale +extern wxArrayInt existingLangs; // Language IDs +extern wxArrayString existingLangNames; // Language Names + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +class CSSHTunnelThread; +extern CSSHTunnelThread *pgadminTunnelThread; // SSH Tunneling Thread Object +#endif + +// Helper app paths - PG +extern wxString pgBackupExecutable; +extern wxString pgBackupAllExecutable; +extern wxString pgRestoreExecutable; + +// Helper app paths - EDB +extern wxString edbBackupExecutable; +extern wxString edbBackupAllExecutable; +extern wxString edbRestoreExecutable; + +// Helper app paths - Greenplum +extern wxString gpBackupExecutable; +extern wxString gpBackupAllExecutable; +extern wxString gpRestoreExecutable; + +// +// Support for additional functions included in the EnterpriseDB +// version of libpq. These are enable via runtime loading of the +// functions on Windows, and a configure time macro on other +// platforms (EDB_LIBPQ). +// +// Currently, these are only use to support EDB callable statements +// so the debugger can grab OUT/INOUT parameters from EDB stored +// procedures. +// +#ifdef __WXMSW__ +// Dynamically loaded PQgetOutResult +typedef PGresult *(*PQGETOUTRESULT)(PGconn *); +extern PQGETOUTRESULT PQiGetOutResult; +#define PQiGetOutResult (PQiGetOutResult) + +// Dynamically loaded PQprepareOut +typedef PGresult *(*PQPREPAREOUT)(PGconn *, const char *, const char *, int, const Oid *, const int *); +extern PQPREPAREOUT PQiPrepareOut; +#define PQiPrepareOut (PQiPrepareOut) + +// Dynamically loaded PQsendQueryPreparedOut +typedef int (*PQSENDQUERYPREPAREDOUT)(PGconn *, const char *, int, const char *const *, const int *, const int *, int); +extern PQSENDQUERYPREPAREDOUT PQiSendQueryPreparedOut; +#define PQiSendQueryPreparedOut (PQiSendQueryPreparedOut) + +#else +#ifdef EDB_LIBPQ +#define PQiGetOutResult PQgetOutResult +#define PQiPrepareOut PQprepareOut +#define PQiSendQueryPreparedOut PQsendQueryPreparedOut +#endif +#endif + +// Simple hash map used as an ad-hoc data cache +WX_DECLARE_STRING_HASH_MAP(wxString, cacheMap); + +// Class declarations +class pgAdmin3 : public wxApp +{ +public: + virtual bool OnInit(); + virtual int OnExit(); + +#ifdef __WXMAC__ + void MacOpenFile(const wxString &fileName); +#endif + +private: + wxString LocatePath(const wxString &pathToFind, const bool isFile); + wxString GenerateHelpPath(const wxString &file, const wxString ¤t, wxPathList stdPaths, wxPathList dbmsPaths); + bool LoadAllXrc(const wxString dir); + +#ifdef __WXMAC__ + wxString macFileToOpen; +#endif + +protected: + void InitAppPaths(); + void InitXtraPaths(); + void InitHelp(); + void InitLogger(); + void InitNetwork(); + void InitXml(); + +#ifdef __WXMSW__ + void InitLibpq(); +#endif + +}; + +class pgAppearanceFactory +{ +public: + pgAppearanceFactory(); + + void SetIcons(wxDialog *dlg); + void SetIcons(wxTopLevelWindow *dlg); + wxIcon GetSmallIconImage(); + wxIcon GetBigIconImage(); + wxBitmap GetSplashImage() + { + return wxBitmap(splash_image); + }; + wxFont GetSplashTextFont(); + wxColour GetSplashTextColour() + { + return splash_text_colour; + }; + long GetSplashTextOffset() + { + return splash_pos_offset; + }; + wxPoint GetSplashTextPos() + { + return wxPoint(splash_pos_x, splash_pos_y); + }; + wxString GetShortAppName() + { + return short_appname; + }; + wxString GetLongAppName() + { + return long_appname; + }; + wxString GetWebsiteUrl() + { + return website_url; + }; + wxColour GetReportKeyColour() + { + return report_key_colour; + }; + bool GetHideEnterprisedbHelp() + { + return hide_enterprisedb_help; + }; + bool GetHideGreenplumHelp() + { + return hide_greenplum_help; + }; + bool IsBranded() + { + return is_branded; + }; + +private: + wxString long_appname, short_appname, website_url, icon; + wxImage large_icon, small_icon, splash_image; + long splash_font_size, splash_pos_x, splash_pos_y, splash_pos_offset; + wxColor splash_text_colour, report_key_colour; + bool hide_enterprisedb_help, hide_greenplum_help, is_branded; +}; + +extern pgAppearanceFactory *appearanceFactory; + + +#endif // PGADMIN3_H diff --git a/include/pgscript/FlexLexer.h b/include/pgscript/FlexLexer.h new file mode 100644 index 0000000..9535812 --- /dev/null +++ b/include/pgscript/FlexLexer.h @@ -0,0 +1,223 @@ +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" +{ + + struct yy_buffer_state; + typedef int yy_state_type; + + class FlexLexer + { + public: + virtual ~FlexLexer() { } + + const char *YYText() + { + return yytext; + } + int YYLeng() + { + return yyleng; + } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state * new_buffer ) = 0; + virtual struct yy_buffer_state * + yy_create_buffer( FLEX_STD istream * s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state * b ) = 0; + virtual void yyrestart( FLEX_STD istream * s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream * new_in, FLEX_STD ostream *new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream *new_in = 0, + FLEX_STD ostream *new_out = 0 ) = 0; + + int lineno() const + { + return yylineno; + } + + int debug() const + { + return yy_flex_debug; + } + void set_debug( int flag ) + { + yy_flex_debug = flag; + } + + protected: + char *yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" + }; + +} +#endif + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex man page. +#define yyFlexLexerOnce + +extern "C++" +{ + + class yyFlexLexer : public FlexLexer + { + public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream *arg_yyin = 0, FLEX_STD ostream *arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state * new_buffer ); + struct yy_buffer_state * yy_create_buffer( FLEX_STD istream * s, int size ); + void yy_delete_buffer( struct yy_buffer_state * b ); + void yyrestart( FLEX_STD istream * s ); + + void yypush_buffer_state( struct yy_buffer_state * new_buffer ); + void yypop_buffer_state(void); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream * new_in, FLEX_STD ostream * new_out ); + + protected: + virtual int LexerInput( char *buf, int max_size ); + virtual void LexerOutput( const char *buf, int size ); + virtual void LexerError( const char *msg ); + + void yyunput( int c, char *buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state * b, FLEX_STD istream * s ); + void yy_flush_buffer( struct yy_buffer_state * b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream *yyin; // input source for default LexerInput + FLEX_STD ostream *yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char *yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state **yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char *yy_last_accepting_cpos; + + yy_state_type *yy_state_buf; + yy_state_type *yy_state_ptr; + + char *yy_full_match; + int *yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; + }; + +} + +#endif diff --git a/include/pgscript/exceptions/module.mk b/include/pgscript/exceptions/module.mk new file mode 100644 index 0000000..0f866e8 --- /dev/null +++ b/include/pgscript/exceptions/module.mk @@ -0,0 +1,24 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/exceptions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/exceptions/pgsArithmeticException.h \ + include/pgscript/exceptions/pgsAssertException.h \ + include/pgscript/exceptions/pgsBreakException.h \ + include/pgscript/exceptions/pgsCastException.h \ + include/pgscript/exceptions/pgsContinueException.h \ + include/pgscript/exceptions/pgsException.h \ + include/pgscript/exceptions/pgsInterruptException.h \ + include/pgscript/exceptions/pgsParameterException.h + +EXTRA_DIST += \ + include/pgscript/exceptions/module.mk + diff --git a/include/pgscript/exceptions/pgsArithmeticException.h b/include/pgscript/exceptions/pgsArithmeticException.h new file mode 100644 index 0000000..ca3ddd6 --- /dev/null +++ b/include/pgscript/exceptions/pgsArithmeticException.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSARITHMETICEXCEPTION_H_ +#define PGSARITHMETICEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsArithmeticException : public pgsException +{ + +protected: + + const wxString m_left; + const wxString m_right; + +public: + + pgsArithmeticException(const wxString &left, const wxString &right); + + virtual ~pgsArithmeticException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSARITHMETICEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsAssertException.h b/include/pgscript/exceptions/pgsAssertException.h new file mode 100644 index 0000000..18832eb --- /dev/null +++ b/include/pgscript/exceptions/pgsAssertException.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSERTEXCEPTION_H_ +#define PGSASSERTEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsAssertException : public pgsException +{ + +protected: + + const wxString m_message; + +public: + + pgsAssertException(const wxString &message); + + virtual ~pgsAssertException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSASSERTEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsBreakException.h b/include/pgscript/exceptions/pgsBreakException.h new file mode 100644 index 0000000..695795d --- /dev/null +++ b/include/pgscript/exceptions/pgsBreakException.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSBREAKEXCEPTION_H_ +#define PGSBREAKEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsBreakException : public pgsException +{ + +public: + + pgsBreakException(); + + virtual ~pgsBreakException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSBREAKEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsCastException.h b/include/pgscript/exceptions/pgsCastException.h new file mode 100644 index 0000000..e4a5888 --- /dev/null +++ b/include/pgscript/exceptions/pgsCastException.h @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCASTEXCEPTION_H_ +#define PGSCASTEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsCastException : public pgsException +{ + +protected: + + const wxString m_value; + const wxString m_type; + +public: + + pgsCastException(const wxString &value, const wxString &type); + + virtual ~pgsCastException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSCASTEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsContinueException.h b/include/pgscript/exceptions/pgsContinueException.h new file mode 100644 index 0000000..227c334 --- /dev/null +++ b/include/pgscript/exceptions/pgsContinueException.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCONTINUEEXCEPTION_H_ +#define PGSCONTINUEEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsContinueException : public pgsException +{ + +public: + + pgsContinueException(); + + virtual ~pgsContinueException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSCONTINUEEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsException.h b/include/pgscript/exceptions/pgsException.h new file mode 100644 index 0000000..f67f34c --- /dev/null +++ b/include/pgscript/exceptions/pgsException.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXCEPTION_H_ +#define PGSEXCEPTION_H_ + +#include "pgscript/pgScript.h" + +class pgsException +{ + +protected: + + pgsException(); + +public: + + virtual ~pgsException(); + + virtual const wxString message() const = 0; + +}; + +#endif /*PGSEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsInterruptException.h b/include/pgscript/exceptions/pgsInterruptException.h new file mode 100644 index 0000000..e133de2 --- /dev/null +++ b/include/pgscript/exceptions/pgsInterruptException.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSINTERRUPTEXCEPTION_H_ +#define PGSINTERRUPTEXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsInterruptException : public pgsException +{ + +public: + + pgsInterruptException(); + + virtual ~pgsInterruptException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSINTERRUPTEXCEPTION_H_*/ diff --git a/include/pgscript/exceptions/pgsParameterException.h b/include/pgscript/exceptions/pgsParameterException.h new file mode 100644 index 0000000..3faecdb --- /dev/null +++ b/include/pgscript/exceptions/pgsParameterException.h @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPARAMETEREXCEPTION_H_ +#define PGSPARAMETEREXCEPTION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/exceptions/pgsException.h" + +class pgsParameterException : public pgsException +{ + +protected: + + const wxString m_message; + +public: + + pgsParameterException(const wxString &message = wxT("unknown")); + + virtual ~pgsParameterException(); + + virtual const wxString message() const; + +}; + +#endif /*PGSPARAMETEREXCEPTION_H_*/ diff --git a/include/pgscript/expressions/module.mk b/include/pgscript/expressions/module.mk new file mode 100644 index 0000000..c66766c --- /dev/null +++ b/include/pgscript/expressions/module.mk @@ -0,0 +1,54 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/expressions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/expressions/pgsAnd.h \ + include/pgscript/expressions/pgsAssign.h \ + include/pgscript/expressions/pgsAssignToRecord.h \ + include/pgscript/expressions/pgsCast.h \ + include/pgscript/expressions/pgsColumns.h \ + include/pgscript/expressions/pgsDifferent.h \ + include/pgscript/expressions/pgsEqual.h \ + include/pgscript/expressions/pgsExecute.h \ + include/pgscript/expressions/pgsExpression.h \ + include/pgscript/expressions/pgsExpressions.h \ + include/pgscript/expressions/pgsGenDate.h \ + include/pgscript/expressions/pgsGenDateTime.h \ + include/pgscript/expressions/pgsGenDictionary.h \ + include/pgscript/expressions/pgsGenInt.h \ + include/pgscript/expressions/pgsGenReal.h \ + include/pgscript/expressions/pgsGenReference.h \ + include/pgscript/expressions/pgsGenRegex.h \ + include/pgscript/expressions/pgsGenString.h \ + include/pgscript/expressions/pgsGenTime.h \ + include/pgscript/expressions/pgsGreater.h \ + include/pgscript/expressions/pgsGreaterEqual.h \ + include/pgscript/expressions/pgsIdent.h \ + include/pgscript/expressions/pgsIdentRecord.h \ + include/pgscript/expressions/pgsLines.h \ + include/pgscript/expressions/pgsLower.h \ + include/pgscript/expressions/pgsLowerEqual.h \ + include/pgscript/expressions/pgsMinus.h \ + include/pgscript/expressions/pgsModulo.h \ + include/pgscript/expressions/pgsNegate.h \ + include/pgscript/expressions/pgsNot.h \ + include/pgscript/expressions/pgsOperation.h \ + include/pgscript/expressions/pgsOr.h \ + include/pgscript/expressions/pgsOver.h \ + include/pgscript/expressions/pgsParenthesis.h \ + include/pgscript/expressions/pgsPlus.h \ + include/pgscript/expressions/pgsRemoveLine.h \ + include/pgscript/expressions/pgsTimes.h \ + include/pgscript/expressions/pgsTrim.h + +EXTRA_DIST += \ + include/pgscript/expressions/module.mk + diff --git a/include/pgscript/expressions/pgsAnd.h b/include/pgscript/expressions/pgsAnd.h new file mode 100644 index 0000000..4f76087 --- /dev/null +++ b/include/pgscript/expressions/pgsAnd.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSAND_H_ +#define PGSAND_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsAnd : public pgsOperation +{ + +public: + + pgsAnd(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsAnd(); + + virtual pgsExpression *clone() const; + + pgsAnd(const pgsAnd &that); + + pgsAnd &operator =(const pgsAnd &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSAND_H_*/ diff --git a/include/pgscript/expressions/pgsAssign.h b/include/pgscript/expressions/pgsAssign.h new file mode 100644 index 0000000..848762d --- /dev/null +++ b/include/pgscript/expressions/pgsAssign.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSIGN_H_ +#define PGSASSIGN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsAssign : public pgsExpression +{ + +protected: + + wxString m_name; + const pgsExpression *m_var; + +public: + + pgsAssign(const wxString &name, const pgsExpression *var); + + virtual ~pgsAssign(); + + pgsAssign(const pgsAssign &that); + + pgsAssign &operator=(const pgsAssign &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSASSIGN_H_*/ diff --git a/include/pgscript/expressions/pgsAssignToRecord.h b/include/pgscript/expressions/pgsAssignToRecord.h new file mode 100644 index 0000000..27a7e76 --- /dev/null +++ b/include/pgscript/expressions/pgsAssignToRecord.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSIGNTORECORD_H_ +#define PGSASSIGNTORECORD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsAssign.h" + +class pgsAssignToRecord : public pgsAssign +{ + +private: + + const pgsExpression *m_line; + const pgsExpression *m_column; + +public: + + pgsAssignToRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column, const pgsExpression *var); + + virtual ~pgsAssignToRecord(); + + pgsAssignToRecord(const pgsAssignToRecord &that); + + pgsAssignToRecord &operator=(const pgsAssignToRecord &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSASSIGNTORECORD_H_*/ diff --git a/include/pgscript/expressions/pgsCast.h b/include/pgscript/expressions/pgsCast.h new file mode 100644 index 0000000..a2f3903 --- /dev/null +++ b/include/pgscript/expressions/pgsCast.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCAST_H_ +#define PGSCAST_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsCast : public pgsExpression +{ + +private: + + int m_cast_type; + + const pgsExpression *m_var; + +public: + + pgsCast(const int &cast_type, const pgsExpression *var); + + virtual ~pgsCast(); + + virtual pgsExpression *clone() const; + + pgsCast(const pgsCast &that); + + pgsCast &operator=(const pgsCast &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSCAST_H_*/ diff --git a/include/pgscript/expressions/pgsColumns.h b/include/pgscript/expressions/pgsColumns.h new file mode 100644 index 0000000..40abe3a --- /dev/null +++ b/include/pgscript/expressions/pgsColumns.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCOLUMNS_H_ +#define PGSCOLUMNS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsColumns : public pgsExpression +{ + +private: + + wxString m_name; + +public: + + pgsColumns(const wxString &name); + + virtual ~pgsColumns(); + + /* pgsColumns(const pgsColumns & that); */ + + /* pgsColumns & operator=(const pgsColumns & that); */ + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSCOLUMNS_H_*/ diff --git a/include/pgscript/expressions/pgsDifferent.h b/include/pgscript/expressions/pgsDifferent.h new file mode 100644 index 0000000..4c31e7e --- /dev/null +++ b/include/pgscript/expressions/pgsDifferent.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDIFFERENT_H_ +#define PGSDIFFERENT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsDifferent : public pgsOperation +{ + +public: + + pgsDifferent(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsDifferent(); + + virtual pgsExpression *clone() const; + + pgsDifferent(const pgsDifferent &that); + + pgsDifferent &operator =(const pgsDifferent &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSDIFFERENT_H_*/ diff --git a/include/pgscript/expressions/pgsEqual.h b/include/pgscript/expressions/pgsEqual.h new file mode 100644 index 0000000..30c9211 --- /dev/null +++ b/include/pgscript/expressions/pgsEqual.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEQUAL_H_ +#define PGSEQUAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsEqual : public pgsOperation +{ + +private: + + bool m_case_sensitive; + +public: + + pgsEqual(const pgsExpression *left, const pgsExpression *right, + bool case_sensitive = true); + + virtual ~pgsEqual(); + + virtual pgsExpression *clone() const; + + pgsEqual(const pgsEqual &that); + + pgsEqual &operator =(const pgsEqual &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSEQUAL_H_*/ diff --git a/include/pgscript/expressions/pgsExecute.h b/include/pgscript/expressions/pgsExecute.h new file mode 100644 index 0000000..ec78797 --- /dev/null +++ b/include/pgscript/expressions/pgsExecute.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXECUTE_H_ +#define PGSEXECUTE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsOutputStream; +class pgsThread; + +class pgsExecute : public pgsExpression +{ + +private: + + wxString m_query; + + pgsOutputStream *m_cout; + + pgsThread *m_app; + +public: + + pgsExecute(const wxString &query, pgsOutputStream *cout = 0, + pgsThread *app = 0); + + virtual ~pgsExecute(); + + /* pgsExecute(const pgsExecute & that); */ + + pgsExecute &operator=(const pgsExecute &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSEXECUTE_H_*/ diff --git a/include/pgscript/expressions/pgsExpression.h b/include/pgscript/expressions/pgsExpression.h new file mode 100644 index 0000000..2663386 --- /dev/null +++ b/include/pgscript/expressions/pgsExpression.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXPRESSION_H_ +#define PGSEXPRESSION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsCopiedPtr.h" + +class pgsProgram; +class pgsVariable; + +WX_DECLARE_STRING_HASH_MAP(pgsCopiedPtr, pgsVarMap); +typedef pgsCopiedPtr pgsOperand; + +class pgsExpression +{ + +protected: + + pgsExpression(); + +public: + + virtual ~pgsExpression(); + + virtual pgsExpression *clone() const = 0; + + /* pgsExpression(const pgsExpression & that); */ + + /* pgsExpression & operator =(const pgsExpression & that); */ + +public: + + virtual wxString value() const = 0; + + virtual pgsOperand eval(pgsVarMap &vars) const = 0; + +}; + +#endif /*PGSEXPRESSION_H_*/ diff --git a/include/pgscript/expressions/pgsExpressions.h b/include/pgscript/expressions/pgsExpressions.h new file mode 100644 index 0000000..06d8a5a --- /dev/null +++ b/include/pgscript/expressions/pgsExpressions.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXPRESSIONS_H_ +#define PGSEXPRESSIONS_H_ + +#include "pgsAnd.h" +#include "pgsAssign.h" +#include "pgsAssignToRecord.h" +#include "pgsCast.h" +#include "pgsColumns.h" +#include "pgsDifferent.h" +#include "pgsEqual.h" +#include "pgsExecute.h" +#include "pgsExpression.h" +#include "pgsGenDate.h" +#include "pgsGenDateTime.h" +#include "pgsGenDictionary.h" +#include "pgsGenInt.h" +#include "pgsGenReal.h" +#include "pgsGenReference.h" +#include "pgsGenRegex.h" +#include "pgsGenString.h" +#include "pgsGenTime.h" +#include "pgsGreater.h" +#include "pgsGreaterEqual.h" +#include "pgsIdent.h" +#include "pgsIdentRecord.h" +#include "pgsLines.h" +#include "pgsLower.h" +#include "pgsLowerEqual.h" +#include "pgsMinus.h" +#include "pgsModulo.h" +#include "pgsNegate.h" +#include "pgsNot.h" +#include "pgsOperation.h" +#include "pgsOr.h" +#include "pgsOver.h" +#include "pgsParenthesis.h" +#include "pgsPlus.h" +#include "pgsRemoveLine.h" +#include "pgsTimes.h" +#include "pgsTrim.h" + +#endif /*PGSEXPRESSIONS_H_*/ diff --git a/include/pgscript/expressions/pgsGenDate.h b/include/pgscript/expressions/pgsGenDate.h new file mode 100644 index 0000000..6ba20a5 --- /dev/null +++ b/include/pgscript/expressions/pgsGenDate.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENDATE_H_ +#define PGSGENDATE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenDate : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenDate(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenDate(); + + virtual pgsExpression *clone() const; + + pgsGenDate(const pgsGenDate &that); + + pgsGenDate &operator =(const pgsGenDate &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENDATE_H_*/ diff --git a/include/pgscript/expressions/pgsGenDateTime.h b/include/pgscript/expressions/pgsGenDateTime.h new file mode 100644 index 0000000..29be538 --- /dev/null +++ b/include/pgscript/expressions/pgsGenDateTime.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENDATETIME_H_ +#define PGSGENDATETIME_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenDateTime : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenDateTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenDateTime(); + + virtual pgsExpression *clone() const; + + pgsGenDateTime(const pgsGenDateTime &that); + + pgsGenDateTime &operator =(const pgsGenDateTime &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENDATETIME_H_*/ diff --git a/include/pgscript/expressions/pgsGenDictionary.h b/include/pgscript/expressions/pgsGenDictionary.h new file mode 100644 index 0000000..fe1936f --- /dev/null +++ b/include/pgscript/expressions/pgsGenDictionary.h @@ -0,0 +1,49 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENDICTIONARY_H_ +#define PGSGENDICTIONARY_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenDictionary : public pgsExpression +{ + +private: + + const pgsExpression *m_file_path; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + const pgsExpression *m_wx_conv; + +public: + + pgsGenDictionary(const pgsExpression *file_path, + const pgsExpression *sequence, + const pgsExpression *seed, const pgsExpression *wx_conv); + + virtual ~pgsGenDictionary(); + + virtual pgsExpression *clone() const; + + pgsGenDictionary(const pgsGenDictionary &that); + + pgsGenDictionary &operator =(const pgsGenDictionary &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENDICTIONARY_H_*/ diff --git a/include/pgscript/expressions/pgsGenInt.h b/include/pgscript/expressions/pgsGenInt.h new file mode 100644 index 0000000..915684f --- /dev/null +++ b/include/pgscript/expressions/pgsGenInt.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENINT_H_ +#define PGSGENINT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenInt : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenInt(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenInt(); + + virtual pgsExpression *clone() const; + + pgsGenInt(const pgsGenInt &that); + + pgsGenInt &operator =(const pgsGenInt &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENINT_H_*/ diff --git a/include/pgscript/expressions/pgsGenReal.h b/include/pgscript/expressions/pgsGenReal.h new file mode 100644 index 0000000..8bec0f1 --- /dev/null +++ b/include/pgscript/expressions/pgsGenReal.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENREAL_H_ +#define PGSGENREAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenReal : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_precision; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenReal(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *precision, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenReal(); + + virtual pgsExpression *clone() const; + + pgsGenReal(const pgsGenReal &that); + + pgsGenReal &operator =(const pgsGenReal &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENREAL_H_*/ diff --git a/include/pgscript/expressions/pgsGenReference.h b/include/pgscript/expressions/pgsGenReference.h new file mode 100644 index 0000000..b44eca9 --- /dev/null +++ b/include/pgscript/expressions/pgsGenReference.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENREFERENCE_H_ +#define PGSGENREFERENCE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsThread; + +class pgsGenReference : public pgsExpression +{ + +private: + + const pgsExpression *m_table; + const pgsExpression *m_column; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + + pgsThread *m_app; + +public: + + pgsGenReference(const pgsExpression *table, const pgsExpression *column, + const pgsExpression *sequence, const pgsExpression *seed, + pgsThread *app = 0); + + virtual ~pgsGenReference(); + + virtual pgsExpression *clone() const; + + pgsGenReference(const pgsGenReference &that); + + pgsGenReference &operator =(const pgsGenReference &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENREFERENCE_H_*/ diff --git a/include/pgscript/expressions/pgsGenRegex.h b/include/pgscript/expressions/pgsGenRegex.h new file mode 100644 index 0000000..ec2192d --- /dev/null +++ b/include/pgscript/expressions/pgsGenRegex.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENREGEX_H_ +#define PGSGENREGEX_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenRegex : public pgsExpression +{ + +private: + + const pgsExpression *m_regex; + const pgsExpression *m_seed; + +public: + + pgsGenRegex(const pgsExpression *regex, const pgsExpression *seed); + + virtual ~pgsGenRegex(); + + virtual pgsExpression *clone() const; + + pgsGenRegex(const pgsGenRegex &that); + + pgsGenRegex &operator =(const pgsGenRegex &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENREGEX_H_*/ diff --git a/include/pgscript/expressions/pgsGenString.h b/include/pgscript/expressions/pgsGenString.h new file mode 100644 index 0000000..5307efc --- /dev/null +++ b/include/pgscript/expressions/pgsGenString.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENSTRING_H_ +#define PGSGENSTRING_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenString : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_nb_words; + const pgsExpression *m_seed; + +public: + + pgsGenString(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *nb_words, const pgsExpression *seed); + + virtual ~pgsGenString(); + + virtual pgsExpression *clone() const; + + pgsGenString(const pgsGenString &that); + + pgsGenString &operator =(const pgsGenString &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENSTRING_H_*/ diff --git a/include/pgscript/expressions/pgsGenTime.h b/include/pgscript/expressions/pgsGenTime.h new file mode 100644 index 0000000..fab6eca --- /dev/null +++ b/include/pgscript/expressions/pgsGenTime.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENTIME_H_ +#define PGSGENTIME_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsGenTime : public pgsExpression +{ + +private: + + const pgsExpression *m_min; + const pgsExpression *m_max; + const pgsExpression *m_sequence; + const pgsExpression *m_seed; + +public: + + pgsGenTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed); + + virtual ~pgsGenTime(); + + virtual pgsExpression *clone() const; + + pgsGenTime(const pgsGenTime &that); + + pgsGenTime &operator =(const pgsGenTime &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGENTIME_H_*/ diff --git a/include/pgscript/expressions/pgsGreater.h b/include/pgscript/expressions/pgsGreater.h new file mode 100644 index 0000000..90f8900 --- /dev/null +++ b/include/pgscript/expressions/pgsGreater.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGREATER_H_ +#define PGSGREATER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsGreater : public pgsOperation +{ + +public: + + pgsGreater(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsGreater(); + + virtual pgsExpression *clone() const; + + pgsGreater(const pgsGreater &that); + + pgsGreater &operator =(const pgsGreater &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGREATER_H_*/ diff --git a/include/pgscript/expressions/pgsGreaterEqual.h b/include/pgscript/expressions/pgsGreaterEqual.h new file mode 100644 index 0000000..ddd6c38 --- /dev/null +++ b/include/pgscript/expressions/pgsGreaterEqual.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGREATEREQUAL_H_ +#define PGSGREATEREQUAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsGreaterEqual : public pgsOperation +{ + +public: + + pgsGreaterEqual(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsGreaterEqual(); + + virtual pgsExpression *clone() const; + + pgsGreaterEqual(const pgsGreaterEqual &that); + + pgsGreaterEqual &operator =(const pgsGreaterEqual &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSGREATEREQUAL_H_*/ diff --git a/include/pgscript/expressions/pgsIdent.h b/include/pgscript/expressions/pgsIdent.h new file mode 100644 index 0000000..aeb11e2 --- /dev/null +++ b/include/pgscript/expressions/pgsIdent.h @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSIDENT_H_ +#define PGSIDENT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsIdent : public pgsExpression +{ + +protected: + + wxString m_name; + +public: + + pgsIdent(const wxString &name); + + virtual ~pgsIdent(); + + /* pgsIdent(const pgsIdent & that); */ + + /* pgsIdent & operator=(const pgsIdent & that); */ + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + static const wxString m_now; + +}; + +#endif /*PGSIDENT_H_*/ diff --git a/include/pgscript/expressions/pgsIdentRecord.h b/include/pgscript/expressions/pgsIdentRecord.h new file mode 100644 index 0000000..1257470 --- /dev/null +++ b/include/pgscript/expressions/pgsIdentRecord.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSIDENTRECORD_H_ +#define PGSIDENTRECORD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsIdent.h" + +class pgsIdentRecord : public pgsIdent +{ + +private: + + const pgsExpression *m_line; + const pgsExpression *m_column; + +public: + + pgsIdentRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column = 0); + + virtual ~pgsIdentRecord(); + + pgsIdentRecord(const pgsIdentRecord &that); + + pgsIdentRecord &operator=(const pgsIdentRecord &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSIDENTRECORD_H_*/ diff --git a/include/pgscript/expressions/pgsLines.h b/include/pgscript/expressions/pgsLines.h new file mode 100644 index 0000000..f92eb4f --- /dev/null +++ b/include/pgscript/expressions/pgsLines.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSLINES_H_ +#define PGSLINES_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsLines : public pgsExpression +{ + +private: + + wxString m_name; + +public: + + pgsLines(const wxString &name); + + virtual ~pgsLines(); + + /* pgsLines(const pgsLines & that); */ + + /* pgsLines & operator=(const pgsLines & that); */ + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSLINES_H_*/ diff --git a/include/pgscript/expressions/pgsLower.h b/include/pgscript/expressions/pgsLower.h new file mode 100644 index 0000000..2aea0cf --- /dev/null +++ b/include/pgscript/expressions/pgsLower.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSLOWER_H_ +#define PGSLOWER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsLower : public pgsOperation +{ + +public: + + pgsLower(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsLower(); + + virtual pgsExpression *clone() const; + + pgsLower(const pgsLower &that); + + pgsLower &operator =(const pgsLower &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSLOWER_H_*/ diff --git a/include/pgscript/expressions/pgsLowerEqual.h b/include/pgscript/expressions/pgsLowerEqual.h new file mode 100644 index 0000000..186eec0 --- /dev/null +++ b/include/pgscript/expressions/pgsLowerEqual.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSLOWEREQUAL_H_ +#define PGSLOWEREQUAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsLowerEqual : public pgsOperation +{ + +public: + + pgsLowerEqual(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsLowerEqual(); + + virtual pgsExpression *clone() const; + + pgsLowerEqual(const pgsLowerEqual &that); + + pgsLowerEqual &operator =(const pgsLowerEqual &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSLOWEREQUAL_H_*/ diff --git a/include/pgscript/expressions/pgsMinus.h b/include/pgscript/expressions/pgsMinus.h new file mode 100644 index 0000000..4210c90 --- /dev/null +++ b/include/pgscript/expressions/pgsMinus.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSMINUS_H_ +#define PGSMINUS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsMinus : public pgsOperation +{ + +public: + + pgsMinus(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsMinus(); + + virtual pgsExpression *clone() const; + + pgsMinus(const pgsMinus &that); + + pgsMinus &operator =(const pgsMinus &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSMINUS_H_*/ diff --git a/include/pgscript/expressions/pgsModulo.h b/include/pgscript/expressions/pgsModulo.h new file mode 100644 index 0000000..45d8ca7 --- /dev/null +++ b/include/pgscript/expressions/pgsModulo.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSMODULO_H_ +#define PGSMODULO_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsModulo : public pgsOperation +{ + +public: + + pgsModulo(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsModulo(); + + virtual pgsExpression *clone() const; + + pgsModulo(const pgsModulo &that); + + pgsModulo &operator =(const pgsModulo &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSMODULO_H_*/ diff --git a/include/pgscript/expressions/pgsNegate.h b/include/pgscript/expressions/pgsNegate.h new file mode 100644 index 0000000..7e2db2c --- /dev/null +++ b/include/pgscript/expressions/pgsNegate.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNEGATE_H_ +#define PGSNEGATE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsNegate : public pgsOperation +{ + +public: + + pgsNegate(const pgsExpression *left); + + virtual ~pgsNegate(); + + virtual pgsExpression *clone() const; + + pgsNegate(const pgsNegate &that); + + pgsNegate &operator =(const pgsNegate &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSNEGATE_H_*/ diff --git a/include/pgscript/expressions/pgsNot.h b/include/pgscript/expressions/pgsNot.h new file mode 100644 index 0000000..359dc28 --- /dev/null +++ b/include/pgscript/expressions/pgsNot.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNOT_H_ +#define PGSNOT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsNot : public pgsOperation +{ + +public: + + pgsNot(const pgsExpression *left); + + virtual ~pgsNot(); + + virtual pgsExpression *clone() const; + + pgsNot(const pgsNot &that); + + pgsNot &operator =(const pgsNot &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSNOT_H_*/ diff --git a/include/pgscript/expressions/pgsOperation.h b/include/pgscript/expressions/pgsOperation.h new file mode 100644 index 0000000..4abe71d --- /dev/null +++ b/include/pgscript/expressions/pgsOperation.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOPERATION_H_ +#define PGSOPERATION_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsOperation : public pgsExpression +{ + +protected: + + const pgsExpression *m_left; + const pgsExpression *m_right; + +public: + + pgsOperation(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsOperation(); + + virtual pgsExpression *clone() const = 0; + + pgsOperation(const pgsOperation &that); + + pgsOperation &operator =(const pgsOperation &that); + + virtual wxString value() const = 0; + + virtual pgsOperand eval(pgsVarMap &vars) const = 0; + +}; + +#endif /*PGSOPERATION_H_*/ diff --git a/include/pgscript/expressions/pgsOr.h b/include/pgscript/expressions/pgsOr.h new file mode 100644 index 0000000..b1b7026 --- /dev/null +++ b/include/pgscript/expressions/pgsOr.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOR_H_ +#define PGSOR_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsOr : public pgsOperation +{ + +public: + + pgsOr(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsOr(); + + virtual pgsExpression *clone() const; + + pgsOr(const pgsOr &that); + + pgsOr &operator =(const pgsOr &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSOR_H_*/ diff --git a/include/pgscript/expressions/pgsOver.h b/include/pgscript/expressions/pgsOver.h new file mode 100644 index 0000000..0ae9a8f --- /dev/null +++ b/include/pgscript/expressions/pgsOver.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOVER_H_ +#define PGSOVER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsOver : public pgsOperation +{ + +public: + + pgsOver(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsOver(); + + virtual pgsExpression *clone() const; + + pgsOver(const pgsOver &that); + + pgsOver &operator =(const pgsOver &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSOVER_H_*/ diff --git a/include/pgscript/expressions/pgsParenthesis.h b/include/pgscript/expressions/pgsParenthesis.h new file mode 100644 index 0000000..38ae645 --- /dev/null +++ b/include/pgscript/expressions/pgsParenthesis.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPARENTHESIS_H_ +#define PGSPARENTHESIS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsParenthesis : public pgsOperation +{ + +public: + + pgsParenthesis(const pgsExpression *left); + + virtual ~pgsParenthesis(); + + virtual pgsExpression *clone() const; + + pgsParenthesis(const pgsParenthesis &that); + + pgsParenthesis &operator =(const pgsParenthesis &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSPARENTHESIS_H_*/ diff --git a/include/pgscript/expressions/pgsPlus.h b/include/pgscript/expressions/pgsPlus.h new file mode 100644 index 0000000..a06ac09 --- /dev/null +++ b/include/pgscript/expressions/pgsPlus.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPLUS_H_ +#define PGSPLUS_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsPlus : public pgsOperation +{ + +public: + + pgsPlus(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsPlus(); + + virtual pgsExpression *clone() const; + + pgsPlus(const pgsPlus &that); + + pgsPlus &operator =(const pgsPlus &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSPLUS_H_*/ diff --git a/include/pgscript/expressions/pgsRemoveLine.h b/include/pgscript/expressions/pgsRemoveLine.h new file mode 100644 index 0000000..b133772 --- /dev/null +++ b/include/pgscript/expressions/pgsRemoveLine.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSREMOVELINE_H_ +#define PGSREMOVELINE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsRemoveLine : public pgsExpression +{ + +private: + + wxString m_rec; + const pgsExpression *m_line; + +public: + + pgsRemoveLine(const wxString &rec, const pgsExpression *line); + + virtual ~pgsRemoveLine(); + + pgsRemoveLine(const pgsRemoveLine &that); + + pgsRemoveLine &operator=(const pgsRemoveLine &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSREMOVELINE_H_*/ diff --git a/include/pgscript/expressions/pgsTimes.h b/include/pgscript/expressions/pgsTimes.h new file mode 100644 index 0000000..817690a --- /dev/null +++ b/include/pgscript/expressions/pgsTimes.h @@ -0,0 +1,38 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTIMES_H_ +#define PGSTIMES_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsOperation.h" + +class pgsTimes : public pgsOperation +{ + +public: + + pgsTimes(const pgsExpression *left, const pgsExpression *right); + + virtual ~pgsTimes(); + + virtual pgsExpression *clone() const; + + pgsTimes(const pgsTimes &that); + + pgsTimes &operator =(const pgsTimes &that); + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSTIMES_H_*/ diff --git a/include/pgscript/expressions/pgsTrim.h b/include/pgscript/expressions/pgsTrim.h new file mode 100644 index 0000000..79d541e --- /dev/null +++ b/include/pgscript/expressions/pgsTrim.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTRIM_H_ +#define PGSTRIM_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsTrim : public pgsExpression +{ + +private: + + const pgsExpression *m_exp; + +public: + + pgsTrim(const pgsExpression *exp); + + virtual ~pgsTrim(); + + pgsTrim(const pgsTrim &that); + + pgsTrim &operator=(const pgsTrim &that); + + virtual pgsExpression *clone() const; + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +}; + +#endif /*PGSTRIM_H_*/ diff --git a/include/pgscript/generators/module.mk b/include/pgscript/generators/module.mk new file mode 100644 index 0000000..11108c4 --- /dev/null +++ b/include/pgscript/generators/module.mk @@ -0,0 +1,27 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/generators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/generators/pgsDateGen.h \ + include/pgscript/generators/pgsDateTimeGen.h \ + include/pgscript/generators/pgsDictionaryGen.h \ + include/pgscript/generators/pgsIntegerGen.h \ + include/pgscript/generators/pgsNumberGen.h \ + include/pgscript/generators/pgsObjectGen.h \ + include/pgscript/generators/pgsRealGen.h \ + include/pgscript/generators/pgsReferenceGen.h \ + include/pgscript/generators/pgsRegexGen.h \ + include/pgscript/generators/pgsStringGen.h \ + include/pgscript/generators/pgsTimeGen.h + +EXTRA_DIST += \ + include/pgscript/generators/module.mk + diff --git a/include/pgscript/generators/pgsDateGen.h b/include/pgscript/generators/pgsDateGen.h new file mode 100644 index 0000000..e88edf3 --- /dev/null +++ b/include/pgscript/generators/pgsDateGen.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDATEGEN_H_ +#define PGSDATEGEN_H_ + +#include "pgscript/pgScript.h" +#include +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsDateGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxDateTime m_min; + wxDateTime m_max; + int m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsDateGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsDateGen(); + + virtual pgsDateGen *clone(); + + /* pgsDateGen & operator =(const pgsDateGen & that); */ + + /* pgsDateGen(const pgsDateGen & that); */ + +}; + +#endif /*PGSDATEGEN_H_*/ diff --git a/include/pgscript/generators/pgsDateTimeGen.h b/include/pgscript/generators/pgsDateTimeGen.h new file mode 100644 index 0000000..add132b --- /dev/null +++ b/include/pgscript/generators/pgsDateTimeGen.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDATETIMEGEN_H_ +#define PGSDATETIMEGEN_H_ + +#include "pgscript/pgScript.h" +#include +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsDateTimeGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxDateTime m_min; + wxDateTime m_max; + wxLongLong m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsDateTimeGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsDateTimeGen(); + + virtual pgsDateTimeGen *clone(); + + /* pgsDateTimeGen & operator =(const pgsDateTimeGen & that); */ + + /* pgsDateTimeGen(const pgsDateTimeGen & that); */ + +}; + +#endif /*PGSDATETIMEGEN_H_*/ diff --git a/include/pgscript/generators/pgsDictionaryGen.h b/include/pgscript/generators/pgsDictionaryGen.h new file mode 100644 index 0000000..4dbb72c --- /dev/null +++ b/include/pgscript/generators/pgsDictionaryGen.h @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDICTIONARYGEN_H_ +#define PGSDICTIONARYGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsDictionaryGen : public pgsObjectGen +{ + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxString m_file_path; + wxCSConv m_conv; + + long m_nb_lines; + + pgsRandomizer m_randomizer; + +public: + + pgsDictionaryGen(const wxString &file_path, const bool &sequence = false, + const long &seed = wxDateTime::GetTimeNow(), wxCSConv conv = wxConvLocal); + + virtual wxString random(); + + virtual ~pgsDictionaryGen(); + + virtual pgsDictionaryGen *clone(); + + /* pgsDictionaryGen(const pgsDictionaryGen & that); */ + + const long &nb_lines() const; + +private: + + pgsDictionaryGen &operator =(const pgsDictionaryGen &that); + +private: + + long count_lines(); + + wxString get_line(long line_nb); + +}; + +#endif /*PGSDICTIONARYGEN_H_*/ diff --git a/include/pgscript/generators/pgsIntegerGen.h b/include/pgscript/generators/pgsIntegerGen.h new file mode 100644 index 0000000..c46b339 --- /dev/null +++ b/include/pgscript/generators/pgsIntegerGen.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSINTEGERGEN_H_ +#define PGSINTEGERGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsNumberGen.h" +#include "pgscript/generators/pgsObjectGen.h" +#include "pgscript/utilities/pgsCopiedPtr.h" + +class pgsIntegerGen : public pgsObjectGen +{ + +private: + + class pgsSequentialIntGen : public pgsNumberGen + { + + private: + + MAPM m_state; + MAPM m_m; + + static const MAPM arg_a; + static const MAPM arg_c; + + MAPM m_remainder; + + pgsVectorMapm m_buffer; + + public: + + pgsSequentialIntGen(const MAPM &range, const long &seed); + + virtual MAPM random(); + + virtual ~pgsSequentialIntGen(); + + virtual pgsNumberGen *clone(); + + /* pgsSequentialIntGen & operator =(const pgsSequentialIntGen & that); */ + + /* pgsSequentialIntGen(const pgsSequentialIntGen & that); */ + }; + + class pgsNormalIntGen : public pgsNumberGen + { + + private: + + MAPM m_state; + MAPM m_top; + + static const MAPM arg_a; + static const MAPM arg_c; + static const MAPM arg_m; + + public: + + pgsNormalIntGen(const MAPM &range, const long &seed); + + virtual MAPM random(); + + virtual ~pgsNormalIntGen(); + + virtual pgsNumberGen *clone(); + + /* pgsNormalIntGen & operator =(const pgsNormalIntGen & that); */ + + /* pgsNormalIntGen(const pgsNormalIntGen & that); */ + }; + + friend class pgsRealGen; + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + MAPM m_min; + MAPM m_max; + MAPM m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsIntegerGen(const MAPM &min, const MAPM &max, + const bool &sequence = false, const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + long random_long(); + + virtual ~pgsIntegerGen(); + + virtual pgsIntegerGen *clone(); + + /* pgsIntegerGen & operator =(const pgsIntegerGen & that); */ + + /* pgsIntegerGen(const pgsIntegerGen & that); */ +}; + +#endif /*PGSINTEGERGEN_H_*/ diff --git a/include/pgscript/generators/pgsNumberGen.h b/include/pgscript/generators/pgsNumberGen.h new file mode 100644 index 0000000..492e154 --- /dev/null +++ b/include/pgscript/generators/pgsNumberGen.h @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNUMBERGEN_H_ +#define PGSNUMBERGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsMapm.h" + +class pgsNumberGen +{ + +protected: + + MAPM m_range; + + static const int BUFFER_SIZE = 1000; + + pgsNumberGen(const MAPM &range); + +public: + + virtual ~pgsNumberGen(); + + virtual MAPM random() = 0; + + virtual pgsNumberGen *clone() = 0; + + /* pgsNumberGen & operator =(const pgsNumberGen & that); */ + + /* pgsNumberGen(const pgsNumberGen & that); */ +}; + +#endif /*PGSNUMBERGEN_H_*/ diff --git a/include/pgscript/generators/pgsObjectGen.h b/include/pgscript/generators/pgsObjectGen.h new file mode 100644 index 0000000..5c2e0ee --- /dev/null +++ b/include/pgscript/generators/pgsObjectGen.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOBJECTGEN_H_ +#define PGSOBJECTGEN_H_ + +#include "pgscript/pgScript.h" +#include + +class pgsObjectGen +{ + +protected: + + long m_seed; + + pgsObjectGen(const long &seed = wxDateTime::GetTimeNow()); + + /* pgsObjectGen & operator =(const pgsObjectGen & that); */ + + /* pgsObjectGen(const pgsObjectGen & that); */ + +public: + + virtual ~pgsObjectGen(); + + virtual wxString random() = 0; + + virtual pgsObjectGen *clone() = 0; + +}; + +#endif /*PGSOBJECTGEN_H_*/ diff --git a/include/pgscript/generators/pgsRealGen.h b/include/pgscript/generators/pgsRealGen.h new file mode 100644 index 0000000..83ec305 --- /dev/null +++ b/include/pgscript/generators/pgsRealGen.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef RANDREAL_H_ +#define RANDREAL_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsRealGen : public pgsObjectGen +{ + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + MAPM m_min; + MAPM m_max; + MAPM m_range; + + bool m_sequence; + + MAPM m_pow; + MAPM m_int_max; + + pgsRandomizer m_randomizer; + +public: + + /** + * Builds a new real number generator. Precision cannot be greater that 255. + */ + pgsRealGen(const MAPM &min, const MAPM &max, const UCHAR &precision, + const bool &sequence = false, const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsRealGen(); + + virtual pgsRealGen *clone(); + + /* pgsRealGen & operator =(const pgsRealGen & that); */ + + /* pgsRealGen(const pgsRealGen & that); */ +}; + +#endif /*RANDREAL_H_*/ diff --git a/include/pgscript/generators/pgsReferenceGen.h b/include/pgscript/generators/pgsReferenceGen.h new file mode 100644 index 0000000..ac786d6 --- /dev/null +++ b/include/pgscript/generators/pgsReferenceGen.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSREFERENCEGEN_H_ +#define PGSREFERENCEGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsThread; + +class pgsReferenceGen : public pgsObjectGen +{ + +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + pgsThread *m_app; + wxString m_table; + wxString m_column; + bool m_sequence; + + MAPM m_nb_rows; + + pgsRandomizer m_randomizer; + +public: + + pgsReferenceGen(pgsThread *app, const wxString &table, const wxString &column, + const bool &sequence = false, const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsReferenceGen(); + + virtual pgsReferenceGen *clone(); + + /* pgsReferenceGen & operator =(const pgsReferenceGen & that); */ + + /* pgsReferenceGen(const pgsReferenceGen & that); */ +}; + +#endif /*PGSREFERENCEGEN_H_*/ diff --git a/include/pgscript/generators/pgsRegexGen.h b/include/pgscript/generators/pgsRegexGen.h new file mode 100644 index 0000000..d799236 --- /dev/null +++ b/include/pgscript/generators/pgsRegexGen.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSREGEXGEN_H_ +#define PGSREGEXGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsObjectGen.h" +#include "pgscript/generators/pgsStringGen.h" + +WX_DECLARE_OBJARRAY(pgsStringGen, pgsVectorStringGen); + +class pgsRegexGen : public pgsObjectGen +{ + +private: + + class pgsRegex + { + + private: + + pgsVectorChar m_characters; + + long m_first; + long m_second; + + public: + + pgsRegex(const pgsVectorChar &characters, const long &first, + const long &second); + + pgsRegex(); + + ~pgsRegex(); + + pgsRegex *clone(); + + /* pgsRegex & operator =(const pgsRegex & that); */ + + /* pgsRegex(const pgsRegex & that); */ + + void set_characters(const pgsVectorChar &characters); + + void add_character(const wxChar &c); + + void set_first(const long &first); + + void set_second(const long &second); + + const pgsVectorChar &get_characters() const; + + const long &get_first() const; + + const long &get_second() const; + + }; + +private: + + wxString m_regex; + + bool m_valid; + + pgsVectorStringGen m_string_gens; + +public: + + pgsRegexGen(const wxString ®ex, const long &seed = wxDateTime::GetTimeNow()); + + virtual wxString random(); + + virtual ~pgsRegexGen(); + + virtual pgsRegexGen *clone(); + + /* pgsRegexGen & operator =(const pgsRegexGen & that); */ + + /* pgsRegexGen(const pgsRegexGen & that); */ + + const bool &is_valid() const; + + const pgsVectorStringGen &string_gens() const; + + size_t string_gens_size() const; + +private: + + static wxString espace_xml_char(const wxChar &c); + + static wxString char_range(const wxChar &b, const wxChar &c); + +}; + +#endif /*PGSREGEXGEN_H_*/ diff --git a/include/pgscript/generators/pgsStringGen.h b/include/pgscript/generators/pgsStringGen.h new file mode 100644 index 0000000..3f783c1 --- /dev/null +++ b/include/pgscript/generators/pgsStringGen.h @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTRINGGEN_H_ +#define PGSSTRINGGEN_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsIntegerGen.h" + +WX_DECLARE_OBJARRAY(wxChar, pgsVectorChar); + +class pgsStringGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + pgsRandomizer m_w_size_randomizer; + pgsRandomizer m_letter_randomizer; + + UCHAR m_nb_words; + + pgsVectorChar m_characters; + +public: + + pgsStringGen(USHORT w_size_min, USHORT w_size_max = 0, const UCHAR &nb_words = 1, + const long &seed = wxDateTime::GetTimeNow(), + pgsVectorChar characters = pgsVectorChar()); + + virtual wxString random(); + + virtual ~pgsStringGen(); + + virtual pgsStringGen *clone(); + + /* pgsStringGen & operator =(const pgsStringGen & that); */ + + /* pgsStringGen(const pgsStringGen & that); */ + +private: + + void init_characters(); + +}; + +#endif /*PGSSTRINGGEN_H_*/ diff --git a/include/pgscript/generators/pgsTimeGen.h b/include/pgscript/generators/pgsTimeGen.h new file mode 100644 index 0000000..fe7645b --- /dev/null +++ b/include/pgscript/generators/pgsTimeGen.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTIMEGEN_H_ +#define PGSTIMEGEN_H_ + +#include "pgscript/pgScript.h" +#include +#include "pgscript/generators/pgsIntegerGen.h" + +class pgsTimeGen : public pgsObjectGen +{ +private: + + typedef pgsCopiedPtr pgsRandomizer; // Needs a clone() method + + wxDateTime m_min; + wxDateTime m_max; + wxLongLong m_range; + + bool m_sequence; + + pgsRandomizer m_randomizer; + +public: + + pgsTimeGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed = wxDateTime::GetTimeNow()); + + bool is_sequence() const; + + virtual wxString random(); + + virtual ~pgsTimeGen(); + + virtual pgsTimeGen *clone(); + + /* pgsTimeGen & operator =(const pgsTimeGen & that); */ + + /* pgsTimeGen(const pgsTimeGen & that); */ + +}; + +#endif /*PGSTIMEGEN_H_*/ diff --git a/include/pgscript/location.hh b/include/pgscript/location.hh new file mode 100644 index 0000000..9cacc15 --- /dev/null +++ b/include/pgscript/location.hh @@ -0,0 +1,145 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Locations for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file location.hh + ** Define the pgscript::location class. + */ + +#ifndef BISON_LOCATION_HH +# define BISON_LOCATION_HH + +# include +# include +# include "position.hh" + +namespace pgscript +{ + + /// Abstract a location. + class location + { + public: + + /// Construct a location. + location () + : begin (), end () + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + begin.initialize (fn); + end = begin; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// Reset initial location to final location. + inline void step () + { + begin = end; + } + + /// Extend the current location to the COUNT next columns. + inline void columns (unsigned int count = 1) + { + end += count; + } + + /// Extend the current location to the COUNT next lines. + inline void lines (unsigned int count = 1) + { + end.lines (count); + } + /** \} */ + + + public: + /// Beginning of the located region. + position begin; + /// End of the located region. + position end; + }; + + /// Join two location objects to create a location. + inline const location operator+ (const location& begin, const location& end) + { + location res = begin; + res.end = end.end; + return res; + } + + /// Add two location objects. + inline const location operator+ (const location& begin, unsigned int width) + { + location res = begin; + res.columns (width); + return res; + } + + /// Add and assign a location. + inline location& operator+= (location& res, unsigned int width) + { + res.columns (width); + return res; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param loc a reference to the location to redirect + ** + ** Avoid duplicate information. + */ + inline std::ostream& operator<< (std::ostream& ostr, const location& loc) + { + position last = loc.end - 1; + ostr << loc.begin; + if (last.filename + && (!loc.begin.filename + || *loc.begin.filename != *last.filename)) + ostr << '-' << last; + else if (loc.begin.line != last.line) + ostr << '-' << last.line << '.' << last.column; + else if (loc.begin.column != last.column) + ostr << '-' << last.column; + return ostr; + } + +} + +#endif // not BISON_LOCATION_HH diff --git a/include/pgscript/module.mk b/include/pgscript/module.mk new file mode 100644 index 0000000..950c670 --- /dev/null +++ b/include/pgscript/module.mk @@ -0,0 +1,29 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/location.hh \ + include/pgscript/parser.tab.hh \ + include/pgscript/position.hh \ + include/pgscript/stack.hh \ + include/pgscript/FlexLexer.h \ + include/pgscript/pgsApplication.h \ + include/pgscript/pgScript.h + +EXTRA_DIST += \ + include/pgscript/module.mk + +include include/pgscript/exceptions/module.mk +include include/pgscript/expressions/module.mk +include include/pgscript/generators/module.mk +include include/pgscript/objects/module.mk +include include/pgscript/statements/module.mk +include include/pgscript/utilities/module.mk diff --git a/include/pgscript/objects/module.mk b/include/pgscript/objects/module.mk new file mode 100644 index 0000000..208271a --- /dev/null +++ b/include/pgscript/objects/module.mk @@ -0,0 +1,22 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/objects/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/objects/pgsGenerator.h \ + include/pgscript/objects/pgsNumber.h \ + include/pgscript/objects/pgsObjects.h \ + include/pgscript/objects/pgsRecord.h \ + include/pgscript/objects/pgsString.h \ + include/pgscript/objects/pgsVariable.h + +EXTRA_DIST += \ + include/pgscript/objects/module.mk + diff --git a/include/pgscript/objects/pgsGenerator.h b/include/pgscript/objects/pgsGenerator.h new file mode 100644 index 0000000..eb43da1 --- /dev/null +++ b/include/pgscript/objects/pgsGenerator.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSGENERATOR_H_ +#define PGSGENERATOR_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/generators/pgsObjectGen.h" +#include "pgscript/objects/pgsVariable.h" +#include "pgscript/utilities/pgsSharedPtr.h" + +class pgsNumber; +class pgsRecord; +class pgsString; + +class pgsGenerator : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + typedef pgsSharedPtr pgsRandomizer; + + mutable pgsRandomizer m_randomizer; + +public: + + pgsGenerator(const pgsTypes &generator_type, pgsObjectGen *randomizer); + + virtual ~pgsGenerator(); + + virtual pgsVariable *clone() const; + + /* pgsGenerator(const pgsGenerator & that); */ + + /* pgsGenerator & operator =(const pgsGenerator & that); */ + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +protected: + + pgsOperand operand() const; + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSGENERATOR_H_*/ diff --git a/include/pgscript/objects/pgsNumber.h b/include/pgscript/objects/pgsNumber.h new file mode 100644 index 0000000..34131fc --- /dev/null +++ b/include/pgscript/objects/pgsNumber.h @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSNUMBER_H_ +#define PGSNUMBER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +class pgsRecord; +class pgsString; + +/** + * A pgsNumber represents either a number or a string. If the data (a string) + * matches with a regular expression that represents a number then it is a + * number otherwise it is a string. The difference between a string stored + * in this object and a string stored in pgsString is that a string in pgsNumber + * cannot be concatenated with another one in pgsPlus. + */ +class pgsNumber : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + wxString m_data; + +public: + + explicit pgsNumber(const wxString &data, const bool &is_real = pgsInt); + + virtual ~pgsNumber(); + + virtual pgsVariable *clone() const; + + pgsNumber(const pgsNumber &that); + + pgsNumber &operator =(const pgsNumber &that); + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + bool is_valid() const; + + static pgsTypes num_type(const wxString &num); + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSNUMBER_H_*/ diff --git a/include/pgscript/objects/pgsObjects.h b/include/pgscript/objects/pgsObjects.h new file mode 100644 index 0000000..2cdd0dc --- /dev/null +++ b/include/pgscript/objects/pgsObjects.h @@ -0,0 +1,20 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSOBJECTS_H_ +#define PGSOBJECTS_H_ + +#include "pgsGenerator.h" +#include "pgsNumber.h" +#include "pgsRecord.h" +#include "pgsString.h" +#include "pgsVariable.h" + +#endif /*PGSOBJECTS_H_*/ diff --git a/include/pgscript/objects/pgsRecord.h b/include/pgscript/objects/pgsRecord.h new file mode 100644 index 0000000..9f4010e --- /dev/null +++ b/include/pgscript/objects/pgsRecord.h @@ -0,0 +1,155 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSRECORD_H_ +#define PGSRECORD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +WX_DECLARE_OBJARRAY(pgsOperand, pgsVectorRecordLine); +WX_DECLARE_OBJARRAY(pgsVectorRecordLine, pgsVectorRecord); + +class pgsNumber; +class pgsString; + +class pgsRecord : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + pgsVectorRecord m_record; + + wxArrayString m_columns; + +public: + + explicit pgsRecord(const USHORT &nb_columns); + + virtual ~pgsRecord(); + + virtual pgsVariable *clone() const; + + /* pgsRecord(const pgsRecord & that); */ + + /* pgsRecord & operator =(const pgsRecord & that); */ + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + USHORT count_lines() const; + + USHORT count_columns() const; + + /** + * Inserts a new element at line.column. If there is something then + * it is deleted before inserting the new element. + */ + bool insert(const USHORT &line, const USHORT &column, + pgsOperand value); + + /** + * Retrieves the element at line.column. If it does not exist it + * returns an empty string. + */ + pgsOperand get(const USHORT &line, + const USHORT &column) const; + + pgsOperand get_line(const USHORT &line) const; + + /** + * Sets the name of a column. If the index is too high or if the name + * already exists then false is returned. + */ + bool set_column_name(const USHORT &column, wxString name); + + /** + * Gets the index of a given column. If this column does not exist then it + * returns count_columns() (the number of columns) which means that this value + * is unusable. So if get_column(...) == count_colums() an error occurred. + */ + USHORT get_column(wxString name) const; + + bool remove_line(const USHORT &line); + +private: + + bool newline(); + + bool valid() const; + +public: + + bool operator==(const pgsRecord &rhs) const; + + bool operator!=(const pgsRecord &rhs) const; + + bool operator<(const pgsRecord &rhs) const; + + bool operator>(const pgsRecord &rhs) const; + + bool operator<=(const pgsRecord &rhs) const; + + bool operator>=(const pgsRecord &rhs) const; + + bool almost_equal(const pgsRecord &rhs) const; + +private: + + bool records_equal(const pgsRecord &lhs, const pgsRecord &rhs, + bool case_sensitive = true) const; + + bool lines_equal(const pgsVectorRecordLine &lhs, + const pgsVectorRecordLine &rhs, bool case_sensitive = true) const; + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSRECORD_H_*/ diff --git a/include/pgscript/objects/pgsString.h b/include/pgscript/objects/pgsString.h new file mode 100644 index 0000000..fbe4a9c --- /dev/null +++ b/include/pgscript/objects/pgsString.h @@ -0,0 +1,85 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTRING_H_ +#define PGSSTRING_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +class pgsRecord; +class pgsString; + +class pgsString : public pgsVariable +{ + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const; + + virtual pgsOperand pgs_not() const; + + virtual bool pgs_is_true() const; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const; + +protected: + + wxString m_data; + +public: + + explicit pgsString(const wxString &data); + + virtual ~pgsString(); + + virtual pgsVariable *clone() const; + + /* pgsString(const pgsString & that); */ + + /* pgsString & operator =(const pgsString & that); */ + +public: + + virtual wxString value() const; + + virtual pgsOperand eval(pgsVarMap &vars) const; + +public: + + virtual pgsNumber number() const; + + virtual pgsRecord record() const; + + virtual pgsString string() const; + +}; + +#endif /*PGSSTRING_H_*/ diff --git a/include/pgscript/objects/pgsVariable.h b/include/pgscript/objects/pgsVariable.h new file mode 100644 index 0000000..89db031 --- /dev/null +++ b/include/pgscript/objects/pgsVariable.h @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSVARIABLE_H_ +#define PGSVARIABLE_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsMapm.h" +#include "pgscript/expressions/pgsExpression.h" + +class pgsNumber; +class pgsRecord; +class pgsString; + +class pgsVariable : public pgsExpression +{ + + friend pgsOperand operator+(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator-(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator*(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator/(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator%(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator==(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator!=(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator<(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator>(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator<=(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator>=(const pgsVariable &lhs, const pgsVariable &rhs); + + friend pgsOperand operator!(const pgsVariable &lhs); + + friend pgsOperand operator&=(const pgsVariable &lhs, const pgsVariable &rhs); + +public: + + virtual pgsOperand pgs_plus(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_minus(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_times(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_over(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_modulo(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_equal(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_different(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_greater(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_lower(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_lower_equal(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_greater_equal(const pgsVariable &rhs) const = 0; + + virtual pgsOperand pgs_not() const = 0; + + virtual bool pgs_is_true() const = 0; + + virtual pgsOperand pgs_almost_equal(const pgsVariable &rhs) const = 0; + +public: + + enum pgsTypes + { + pgsTReal, pgsTInt, pgsTString, pgsTRecord + }; + +protected: + + pgsVariable(const pgsTypes &type); + + pgsTypes m_type; + +public: + + virtual ~pgsVariable(); + + virtual pgsVariable *clone() const = 0; + + /* pgsVariable(const pgsVariable & that); */ + + /* pgsVariable & operator =(const pgsVariable & that); */ + + static MAPM num(const pgsOperand &var); + + static MAPM num(const wxString &var); + +public: + + virtual wxString value() const = 0; + + virtual pgsOperand eval(pgsVarMap &vars) const = 0; + +public: + + bool is_number() const; + + bool is_integer() const; + + bool is_real() const; + + bool is_string() const; + + bool is_record() const; + + const pgsTypes &type() const; + +public: + + virtual pgsNumber number() const = 0; + + virtual pgsRecord record() const = 0; + + virtual pgsString string() const = 0; + +}; + +#endif /*PGSVARIABLE_H_*/ diff --git a/include/pgscript/parser.tab.hh b/include/pgscript/parser.tab.hh new file mode 100644 index 0000000..f93f5d4 --- /dev/null +++ b/include/pgscript/parser.tab.hh @@ -0,0 +1,403 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C++ LALR(1) parser skeleton written by Akim Demaille. */ + +#ifndef PARSER_HEADER_H +# define PARSER_HEADER_H + +#include +#include +#include "stack.hh" + +namespace pgscript +{ + class position; + class location; +} + +/* First part of user declarations. */ +#line 1 "pgscript/pgsParser.yy" + /*** C/C++ Declarations ***/ + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStatements.h" +#include "pgscript/expressions/pgsExpressions.h" +#include "pgscript/objects/pgsObjects.h" +#include "pgscript/utilities/pgsContext.h" + + + +/* Line 35 of lalr1.cc. */ +#line 73 "pgscript/parser.tab.hh" + +#include "location.hh" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 1 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ +do { \ + if (N) \ + { \ + (Current).begin = (Rhs)[1].begin; \ + (Current).end = (Rhs)[N].end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = (Rhs)[0].end; \ + } \ +} while (false) +#endif + +namespace pgscript +{ + + /// A Bison parser. + class pgsParser + { + public: + /// Symbol semantic values. +#ifndef YYSTYPE + union semantic_type +#line 106 "pgscript/pgsParser.yy" +{ + const wxString * str; + int integer; + pgsExpression * expr; + pgsStmt * stmt; + pgsStmtList * stmt_list; +} +/* Line 35 of lalr1.cc. */ +#line 133 "pgscript/parser.tab.hh" + ; +#else + typedef YYSTYPE semantic_type; +#endif + /// Symbol locations. + typedef location location_type; + /// Tokens. + struct token + { + /* Tokens. */ + enum yytokentype { + PGS_END = 0, + PGS_WHILE = 258, + PGS_BREAK = 259, + PGS_RETURN = 260, + PGS_CONTINUE = 261, + PGS_IF = 262, + PGS_ELSE = 263, + PGS_WAITFOR = 264, + PGS_AS = 265, + PGS_OPEN = 266, + PGS_CLOSE = 267, + PGS_ASSERT = 268, + PGS_PRINT = 269, + PGS_LOG = 270, + PGS_CNT_COLUMNS = 271, + PGS_CNT_LINES = 272, + PGS_TRIM = 273, + PGS_RM_LINE = 274, + PGS_CAST = 275, + PGS_RECORD = 276, + PGS_INTEGER = 277, + PGS_REAL = 278, + PGS_STRING = 279, + PGS_REGEX = 280, + PGS_FILE = 281, + PGS_DATE = 282, + PGS_TIME = 283, + PGS_DATE_TIME = 284, + PGS_REFERENCE = 285, + PGS_LE_OP = 286, + PGS_GE_OP = 287, + PGS_EQ_OP = 288, + PGS_AE_OP = 289, + PGS_NE_OP = 290, + PGS_AND_OP = 291, + PGS_OR_OP = 292, + PGS_NOT_OP = 293, + PGS_UNKNOWN = 294, + PGS_SET_ASSIGN = 295, + PGS_DECLARE_ASSGN = 296, + PGS_ABORT = 297, + PGS_ALTER = 298, + PGS_ANALYZE = 299, + PGS_BEGIN = 300, + PGS_CHECKPOINT = 301, + PGS_CLOSE_ST = 302, + PGS_CLUSTER = 303, + PGS_COMMENT = 304, + PGS_COMMIT = 305, + PGS_COPY = 306, + PGS_CREATE = 307, + PGS_DEALLOCATE = 308, + PGS_DECLARE = 309, + PGS_DELETE = 310, + PGS_DISCARD = 311, + PGS_DROP = 312, + PGS_END_ST = 313, + PGS_EXECUTE = 314, + PGS_EXPLAIN = 315, + PGS_FETCH = 316, + PGS_GRANT = 317, + PGS_INSERT = 318, + PGS_LISTEN = 319, + PGS_LOAD = 320, + PGS_LOCK = 321, + PGS_MOVE = 322, + PGS_NOTIFY = 323, + PGS_PREPARE = 324, + PGS_REASSIGN = 325, + PGS_REINDEX = 326, + PGS_RELEASE = 327, + PGS_RESET = 328, + PGS_REVOKE = 329, + PGS_ROLLBACK = 330, + PGS_SAVEPOINT = 331, + PGS_SELECT = 332, + PGS_SET = 333, + PGS_SHOW = 334, + PGS_START = 335, + PGS_TRUNCATE = 336, + PGS_UNLISTEN = 337, + PGS_UPDATE = 338, + PGS_VACUUM = 339, + PGS_VALUES = 340, + PGS_IDENTIFIER = 341, + PGS_VAL_INT = 342, + PGS_VAL_REAL = 343, + PGS_VAL_STR = 344 + }; + + }; + /// Token type. + typedef token::yytokentype token_type; + + /// Build a parser object. + pgsParser (class pgsDriver & driver_yyarg); + virtual ~pgsParser (); + + /// Parse. + /// \returns 0 iff parsing succeeded. + virtual int parse (); + + /// The current debugging stream. + std::ostream& debug_stream () const; + /// Set the current debugging stream. + void set_debug_stream (std::ostream &); + + /// Type for debugging levels. + typedef int debug_level_type; + /// The current debugging level. + debug_level_type debug_level () const; + /// Set the current debugging level. + void set_debug_level (debug_level_type l); + + private: + /// Report a syntax error. + /// \param loc where the syntax error is found. + /// \param msg a description of the syntax error. + virtual void error (const location_type& loc, const std::string& msg); + + /// Generate an error message. + /// \param state the state where the error occurred. + /// \param tok the look-ahead token. + virtual std::string yysyntax_error_ (int yystate, int tok); + +#if YYDEBUG + /// \brief Report a symbol value on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); + /// \brief Report a symbol on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); +#endif /* ! YYDEBUG */ + + + /// State numbers. + typedef int state_type; + /// State stack type. + typedef stack state_stack_type; + /// Semantic value stack type. + typedef stack semantic_stack_type; + /// location stack type. + typedef stack location_stack_type; + + /// The state stack. + state_stack_type yystate_stack_; + /// The semantic value stack. + semantic_stack_type yysemantic_stack_; + /// The location stack. + location_stack_type yylocation_stack_; + + /// Internal symbol numbers. + typedef unsigned char token_number_type; + /* Tables. */ + /// For a state, the index in \a yytable_ of its portion. + static const short int yypact_[]; + static const signed char yypact_ninf_; + + /// For a state, default rule to reduce. + /// Unless\a yytable_ specifies something else to do. + /// Zero means the default is an error. + static const unsigned char yydefact_[]; + + static const short int yypgoto_[]; + static const short int yydefgoto_[]; + + /// What to do in a state. + /// \a yytable_[yypact_[s]]: what to do in state \a s. + /// - if positive, shift that token. + /// - if negative, reduce the rule which number is the opposite. + /// - if zero, do what YYDEFACT says. + static const unsigned short int yytable_[]; + static const signed char yytable_ninf_; + + static const short int yycheck_[]; + + /// For a state, its accessing symbol. + static const unsigned char yystos_[]; + + /// For a rule, its LHS. + static const unsigned char yyr1_[]; + /// For a rule, its RHS length. + static const unsigned char yyr2_[]; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /// For a symbol, its name in clear. + static const char* const yytname_[]; +#endif + +#if YYERROR_VERBOSE + /// Convert the symbol name \a n to a form suitable for a diagnostic. + virtual std::string yytnamerr_ (const char *n); +#endif + +#if YYDEBUG + /// A type to store symbol numbers and -1. + typedef short int rhs_number_type; + /// A `-1'-separated list of the rules' RHS. + static const rhs_number_type yyrhs_[]; + /// For each rule, the index of the first RHS symbol in \a yyrhs_. + static const unsigned short int yyprhs_[]; + /// For each rule, its source line number. + static const unsigned short int yyrline_[]; + /// For each scanner token number, its symbol number. + static const unsigned short int yytoken_number_[]; + /// Report on the debug stream that the rule \a r is going to be reduced. + virtual void yy_reduce_print_ (int r); + /// Print the state stack on the debug stream. + virtual void yystack_print_ (); +#endif + + /// Convert a scanner token number \a t to a symbol number. + token_number_type yytranslate_ (int t); + + /// \brief Reclaim the memory associated to a symbol. + /// \param yymsg Why this token is reclaimed. + /// \param yytype The symbol type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + inline void yydestruct_ (const char* yymsg, + int yytype, + semantic_type* yyvaluep, + location_type* yylocationp); + + /// Pop \a n symbols the three stacks. + inline void yypop_ (unsigned int n = 1); + + /* Constants. */ + static const int yyeof_; + /* LAST_ -- Last index in TABLE_. */ + static const int yylast_; + static const int yynnts_; + static const int yyempty_; + static const int yyfinal_; + static const int yyterror_; + static const int yyerrcode_; + static const int yyntokens_; + static const unsigned int yyuser_token_number_max_; + static const token_number_type yyundef_token_; + + /* Debugging. */ + int yydebug_; + std::ostream* yycdebug_; + + + /* User arguments. */ + class pgsDriver & driver; + }; +} + + +#endif /* ! defined PARSER_HEADER_H */ diff --git a/include/pgscript/pgScript.h b/include/pgscript/pgScript.h new file mode 100644 index 0000000..c7eb297 --- /dev/null +++ b/include/pgscript/pgScript.h @@ -0,0 +1,45 @@ +#ifndef PGSNITTEST_H_ +#define PGSNITTEST_H_ + +/*** TYPEDEFS ***/ + +typedef unsigned char UCHAR; +typedef unsigned short int USHORT; + +/*** DEFINES ***/ + +#define pgsReal true +#define pgsInt false + +/*** PGADMIN ***/ + +#include "pgAdmin3.h" + +/*** INCLUDES ***/ + +#if defined(HAVE_CONFIG_H) && defined(PGSCLI) +#include "config.h" +#endif + +#include + +/*** OUTPUT ***/ + +#include +#define pgsOutputStream wxTextOutputStream + +const wxString PGSOUTPGSCRIPT (wxT("[PGSCRIPT ] ")); +const wxString PGSOUTEXCEPTION(wxT("[EXCEPTION] ")); +const wxString PGSOUTQUERY (wxT("[QUERY ] ")); +const wxString PGSOUTWARNING (wxT("[WARNING ] ")); +const wxString PGSOUTERROR (wxT("[ERROR ] ")); + +/*** LOGGING ***/ + +#include "utils/sysLogger.h" + +/*** MEMORY LEAK DETECTION ***/ + +#include "pgscript/utilities/pgsAlloc.h" + +#endif /*PGSNITTEST_H_*/ diff --git a/include/pgscript/pgsApplication.h b/include/pgscript/pgsApplication.h new file mode 100644 index 0000000..7e3e950 --- /dev/null +++ b/include/pgscript/pgsApplication.h @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSAPP_H_ +#define PGSAPP_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsThread.h" + +class pgsApplication +{ + +public: + + static const int default_port = 5432; + +private: + + /** Global symbol table shared between different runs. */ + pgsVarMap m_vars; + + /** In order to have only one thread at once. */ + wxSemaphore m_mutex; + + /** Protects stream accesses. */ + wxSemaphore m_stream; + + /** Connection to the database. */ + pgConn *m_connection; + + /** Is m_connection provided in the constructor or has it been created. */ + bool m_defined_conn; + + /** Detached thread running a pgScript (parses a file or a string). */ + pgsThread *m_thread; + + /** pgAdmin specific: post an event to this window when m_thread is done. */ + wxWindow *m_caller; + + /** pgAdmin specific: post this event when m_thread is done. */ + long m_event_id; + + /** Location of the last error if there was one. */ + int m_last_error_line; + +public: + + /** Creates an application and creates a connection. */ + pgsApplication(const wxString &host, const wxString &database, + const wxString &user, const wxString &password, int port = default_port); + + /** Creates an application and uses an existing connection. This connection + * is not deleted when the application is deleted. */ + pgsApplication(pgConn *connection); + + /** Deletes custom connection if one was created (first constructor). */ + ~pgsApplication(); + + /** Parses a file by creating a new thread. */ + bool ParseFile(const wxString &file, pgsOutputStream &out, + wxMBConv *conv = &wxConvLocal); + + /** Parses a string by creating a new thread. */ + bool ParseString(const wxString &string, pgsOutputStream &out); + + /** Is m_thread running? */ + bool IsRunning(); + + /** If m_thread is running then wait for it to terminate. */ + void Wait(); + + /** If m_thread is running then delete it. */ + void Terminate(); + + /** Called by m_thread when the thread is finished: IsRunning() becomes + * false and m_event_id is pushed into the event queue if m_caller exists. */ + void Complete(); + + /** Uses a new database connection instead of the previous one. If the + * previous one was user-defined then it is deleted otherwise it is just + * replaced with the new one. */ + void SetConnection(pgConn *conn); + + /** Deletes everything in the symbol table. */ + void ClearSymbols(); + +#if !defined(PGSCLI) + /** Used in pgAdmin integration for sending an event to the caller when the + * thread is finishing its task. */ + void SetCaller(wxWindow *caller, long event_id); +#endif // PGSCLI + + /** Tells whether the database connection is valid. */ + bool IsConnectionValid() const; + + /** Gets a lock on the output stream. */ + void LockOutput(); + + /** Releases the lock on the output stream. */ + void UnlockOutput(); + + /** Was there an error? */ + bool errorOccurred() const; + + /** Get the position (line) of the last error. */ + int errorLine() const; + +private: + + /** Common method for parse_file & parse_string: runs the thread. */ + bool RunThread(); + +private: + + pgsApplication(const pgsApplication &that); + + pgsApplication &operator=(const pgsApplication &that); + +}; + +#endif /*PGSAPP_H_*/ diff --git a/include/pgscript/position.hh b/include/pgscript/position.hh new file mode 100644 index 0000000..2172ab5 --- /dev/null +++ b/include/pgscript/position.hh @@ -0,0 +1,142 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Positions for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file position.hh + ** Define the pgscript::position class. + */ + +#ifndef BISON_POSITION_HH +# define BISON_POSITION_HH + +# include +# include + +namespace pgscript +{ + /// Abstract a position. + class position + { + public: + + /// Construct a position. + position () + : filename (0), line (1), column (0) + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + filename = fn; + line = 1; + column = 0; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// (line related) Advance to the COUNT next lines. + inline void lines (int count = 1) + { + column = 0; + line += count; + } + + /// (column related) Advance to the COUNT next columns. + inline void columns (int count = 1) + { + int leftmost = 0; + int current = column; + if (leftmost <= current + count) + column += count; + else + column = 0; + } + /** \} */ + + public: + /// File name to which this position refers. + std::string* filename; + /// Current line number. + unsigned int line; + /// Current column number. + unsigned int column; + }; + + /// Add and assign a position. + inline const position& + operator+= (position& res, const int width) + { + res.columns (width); + return res; + } + + /// Add two position objects. + inline const position + operator+ (const position& begin, const int width) + { + position res = begin; + return res += width; + } + + /// Add and assign a position. + inline const position& + operator-= (position& res, const int width) + { + return res += -width; + } + + /// Add two position objects. + inline const position + operator- (const position& begin, const int width) + { + return begin + -width; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param pos a reference to the position to redirect + */ + inline std::ostream& + operator<< (std::ostream& ostr, const position& pos) + { + if (pos.filename) + ostr << *pos.filename << ':'; + return ostr << pos.line << '.' << pos.column; + } + +} +#endif // not BISON_POSITION_HH diff --git a/include/pgscript/stack.hh b/include/pgscript/stack.hh new file mode 100644 index 0000000..5b62318 --- /dev/null +++ b/include/pgscript/stack.hh @@ -0,0 +1,152 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Stack handling for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef BISON_STACK_HH +# define BISON_STACK_HH + +/* The Sun compiler defines _T, which conflicts with wxWidgets, so + we must un-define it if needed. */ +#if defined(__SUNPRO_CC) +#ifdef _T +#undef _T +#define _T_is_defined +#endif +#endif /*__SUNPRO_CC */ + +#include + +namespace pgscript +{ + template > + class stack + { + public: + + // Hide our reversed order. + typedef typename S::reverse_iterator iterator; + typedef typename S::const_reverse_iterator const_iterator; + + stack () : seq_ () + { + } + + stack (unsigned int n) : seq_ (n) + { + } + + inline + T& + operator [] (unsigned int i) + { + return seq_[i]; + } + + inline + const T& + operator [] (unsigned int i) const + { + return seq_[i]; + } + + inline + void + push (const T& t) + { + seq_.push_front (t); + } + + inline + void + pop (unsigned int n = 1) + { + for (; n; --n) + seq_.pop_front (); + } + + inline + unsigned int + height () const + { + return seq_.size (); + } + + inline const_iterator begin () const { return seq_.rbegin (); } + inline const_iterator end () const { return seq_.rend (); } + + private: + + S seq_; + }; + + /// Present a slice of the top of a stack. + template > + class slice + { + public: + + slice (const S& stack, + unsigned int range) : stack_ (stack), + range_ (range) + { + } + + inline + const T& + operator [] (unsigned int i) const + { + return stack_[range_ - i]; + } + + private: + + const S& stack_; + unsigned int range_; + }; +} + +/* Redefine _T if we un-defined it for the Sun compiler. */ +#if defined(__SUNPRO_CC) +#ifdef _T_is_defined +#undef _T_is_defined +/* we need to define it back only if _T already was defined. */ +#if !wxUSE_UNICODE +#define _T(x) x +#else /* Unicode */ +/* use wxCONCAT_HELPER so that x could be expanded if it's a macro */ +#define _T(x) wxCONCAT_HELPER(L, x) +#endif /* ASCII/Unicode */ +#endif /* T_is_defined */ +#endif /*__SUNPRO_CC */ + +#endif // not BISON_STACK_HH diff --git a/include/pgscript/statements/module.mk b/include/pgscript/statements/module.mk new file mode 100644 index 0000000..fc260f8 --- /dev/null +++ b/include/pgscript/statements/module.mk @@ -0,0 +1,28 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/statements/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/statements/pgsAssertStmt.h \ + include/pgscript/statements/pgsBreakStmt.h \ + include/pgscript/statements/pgsContinueStmt.h \ + include/pgscript/statements/pgsDeclareRecordStmt.h \ + include/pgscript/statements/pgsExpressionStmt.h \ + include/pgscript/statements/pgsIfStmt.h \ + include/pgscript/statements/pgsPrintStmt.h \ + include/pgscript/statements/pgsProgram.h \ + include/pgscript/statements/pgsStatements.h \ + include/pgscript/statements/pgsStmt.h \ + include/pgscript/statements/pgsStmtList.h \ + include/pgscript/statements/pgsWhileStmt.h + +EXTRA_DIST += \ + include/pgscript/statements/module.mk + diff --git a/include/pgscript/statements/pgsAssertStmt.h b/include/pgscript/statements/pgsAssertStmt.h new file mode 100644 index 0000000..bf7d6ca --- /dev/null +++ b/include/pgscript/statements/pgsAssertStmt.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSASSERTSTMT_H_ +#define PGSASSERTSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsAssertStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_cond; + +public: + + pgsAssertStmt(const pgsExpression *cond, pgsThread *app = 0); + + virtual ~pgsAssertStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsAssertStmt(const pgsAssertStmt &that); + + pgsAssertStmt &operator=(const pgsAssertStmt &that); + +}; + +#endif /*PGSASSERTSTMT_H_*/ diff --git a/include/pgscript/statements/pgsBreakStmt.h b/include/pgscript/statements/pgsBreakStmt.h new file mode 100644 index 0000000..73a4921 --- /dev/null +++ b/include/pgscript/statements/pgsBreakStmt.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSBREAKSTMT_H_ +#define PGSBREAKSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsBreakStmt : public pgsStmt +{ + +public: + + pgsBreakStmt(pgsThread *app = 0); + + virtual ~pgsBreakStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsBreakStmt(const pgsBreakStmt &that); + + pgsBreakStmt &operator=(const pgsBreakStmt &that); + +}; + +#endif /*PGSBREAKSTMT_H_*/ diff --git a/include/pgscript/statements/pgsContinueStmt.h b/include/pgscript/statements/pgsContinueStmt.h new file mode 100644 index 0000000..b66aa6b --- /dev/null +++ b/include/pgscript/statements/pgsContinueStmt.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCONTINUESTMT_H_ +#define PGSCONTINUESTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsContinueStmt : public pgsStmt +{ + +public: + + pgsContinueStmt(pgsThread *app = 0); + + virtual ~pgsContinueStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsContinueStmt(const pgsContinueStmt &that); + + pgsContinueStmt &operator=(const pgsContinueStmt &that); + +}; + +#endif /*PGSCONTINUESTMT_H_*/ diff --git a/include/pgscript/statements/pgsDeclareRecordStmt.h b/include/pgscript/statements/pgsDeclareRecordStmt.h new file mode 100644 index 0000000..4284202 --- /dev/null +++ b/include/pgscript/statements/pgsDeclareRecordStmt.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDECLARERECORDSTMT_H_ +#define PGSDECLARERECORDSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsDeclareRecordStmt : public pgsStmt +{ + +private: + + const wxString m_rec; + const wxArrayString m_columns; + +public: + + pgsDeclareRecordStmt(const wxString &rec, + const wxArrayString &columns, pgsThread *app = 0); + + virtual ~pgsDeclareRecordStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsDeclareRecordStmt(const pgsDeclareRecordStmt &that); + + pgsDeclareRecordStmt &operator=(const pgsDeclareRecordStmt &that); + +}; + +#endif /*PGSDECLARERECORDSTMT_H_*/ diff --git a/include/pgscript/statements/pgsExpressionStmt.h b/include/pgscript/statements/pgsExpressionStmt.h new file mode 100644 index 0000000..5866b66 --- /dev/null +++ b/include/pgscript/statements/pgsExpressionStmt.h @@ -0,0 +1,40 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSEXPRESSIONSTMT_H_ +#define PGSEXPRESSIONSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsExpressionStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_var; + +public: + + pgsExpressionStmt(const pgsExpression *var, pgsThread *app = 0); + + virtual ~pgsExpressionStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsExpressionStmt(const pgsExpressionStmt &that); + + pgsExpressionStmt &operator=(const pgsExpressionStmt &that); + +}; + +#endif /*PGSEXPRESSIONSTMT_H_*/ diff --git a/include/pgscript/statements/pgsIfStmt.h b/include/pgscript/statements/pgsIfStmt.h new file mode 100644 index 0000000..7193453 --- /dev/null +++ b/include/pgscript/statements/pgsIfStmt.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSIFSTMT_H_ +#define PGSIFSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsIfStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_cond; + const pgsStmt *m_stmt_list_if; + const pgsStmt *m_stmt_list_else; + +public: + + pgsIfStmt(const pgsExpression *cond, const pgsStmt *stmt_list_if, + const pgsStmt *stmt_list_else, pgsThread *app = 0); + + virtual ~pgsIfStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsIfStmt(const pgsIfStmt &that); + + pgsIfStmt &operator=(const pgsIfStmt &that); + +}; + +#endif /*PGSIFSTMT_H_*/ diff --git a/include/pgscript/statements/pgsPrintStmt.h b/include/pgscript/statements/pgsPrintStmt.h new file mode 100644 index 0000000..431756f --- /dev/null +++ b/include/pgscript/statements/pgsPrintStmt.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPRINTSTMT_H_ +#define PGSPRINTSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsPrintStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_var; + + pgsOutputStream &m_cout; + +public: + + pgsPrintStmt(const pgsExpression *var, pgsOutputStream &cout, + pgsThread *app = 0); + + virtual ~pgsPrintStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsPrintStmt(const pgsPrintStmt &that); + + pgsPrintStmt &operator=(const pgsPrintStmt &that); + +}; + +#endif /*PGSPRINTSTMT_H_*/ diff --git a/include/pgscript/statements/pgsProgram.h b/include/pgscript/statements/pgsProgram.h new file mode 100644 index 0000000..9f20b9a --- /dev/null +++ b/include/pgscript/statements/pgsProgram.h @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSPROGRAM_H_ +#define PGSPROGRAM_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +#include + +class pgsStmtList; + +class pgsProgram +{ + +private: + + pgsVarMap &m_vars; + +public: + + pgsProgram(pgsVarMap &vars); + + ~pgsProgram(); + + void dump(); + + static void dump(const pgsVarMap &vars); + + void eval(pgsStmtList *stmt_list); + +private: + + pgsProgram(const pgsProgram &that); + + pgsProgram &operator=(const pgsProgram &that); + +}; + +#endif /*PGSPROGRAM_H_*/ diff --git a/include/pgscript/statements/pgsStatements.h b/include/pgscript/statements/pgsStatements.h new file mode 100644 index 0000000..24c4878 --- /dev/null +++ b/include/pgscript/statements/pgsStatements.h @@ -0,0 +1,26 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTATEMENTS_H_ +#define PGSSTATEMENTS_H_ + +#include "pgsAssertStmt.h" +#include "pgsBreakStmt.h" +#include "pgsContinueStmt.h" +#include "pgsDeclareRecordStmt.h" +#include "pgsExpressionStmt.h" +#include "pgsIfStmt.h" +#include "pgsPrintStmt.h" +#include "pgsProgram.h" +#include "pgsStmt.h" +#include "pgsStmtList.h" +#include "pgsWhileStmt.h" + +#endif /*PGSSTATEMENTS_H_*/ diff --git a/include/pgscript/statements/pgsStmt.h b/include/pgscript/statements/pgsStmt.h new file mode 100644 index 0000000..5522748 --- /dev/null +++ b/include/pgscript/statements/pgsStmt.h @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTMT_H_ +#define PGSSTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +class pgsThread; + +class pgsStmt +{ + +private: + + unsigned int m_line; + +protected: + + pgsThread *m_app; + +public: + + pgsStmt(pgsThread *app = 0); + + virtual ~pgsStmt(); + + void set_position(int line); + + int line() const; + + virtual void eval(pgsVarMap &vars) const = 0; + +private: + + pgsStmt(const pgsStmt &that); + + pgsStmt &operator=(const pgsStmt &that); + +}; + +#endif /*PGSSTMT_H_*/ diff --git a/include/pgscript/statements/pgsStmtList.h b/include/pgscript/statements/pgsStmtList.h new file mode 100644 index 0000000..a697710 --- /dev/null +++ b/include/pgscript/statements/pgsStmtList.h @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSTMTLIST_H_ +#define PGSSTMTLIST_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +WX_DECLARE_LIST(pgsStmt, pgsListStmt); + +class pgsStmtList : public pgsStmt +{ + +private: + + pgsListStmt m_stmt_list; + + pgsOutputStream &m_cout; + +public: + + static bool m_exception_thrown; + +public: + + pgsStmtList(pgsOutputStream &cout, pgsThread *app = 0); + + virtual ~pgsStmtList(); + + virtual void eval(pgsVarMap &vars) const; + + void insert_front(pgsStmt *stmt); + + void insert_back(pgsStmt *stmt); + +private: + + pgsStmtList(const pgsStmtList &that); + + pgsStmtList &operator=(const pgsStmtList &that); + +}; + +#endif /*PGSSTMTLIST_H_*/ diff --git a/include/pgscript/statements/pgsWhileStmt.h b/include/pgscript/statements/pgsWhileStmt.h new file mode 100644 index 0000000..f1f6e12 --- /dev/null +++ b/include/pgscript/statements/pgsWhileStmt.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSWHILESTMT_H_ +#define PGSWHILESTMT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmt.h" + +class pgsWhileStmt : public pgsStmt +{ + +private: + + const pgsExpression *m_cond; + const pgsStmt *m_stmt_list; + +public: + + pgsWhileStmt(const pgsExpression *cond, const pgsStmt *stmt_list, + pgsThread *app = 0); + + virtual ~pgsWhileStmt(); + + virtual void eval(pgsVarMap &vars) const; + +private: + + pgsWhileStmt(const pgsWhileStmt &that); + + pgsWhileStmt &operator=(const pgsWhileStmt &that); + +}; + +#endif /*PGSWHILESTMT_H_*/ diff --git a/include/pgscript/utilities/mapm-lib/license.txt b/include/pgscript/utilities/mapm-lib/license.txt new file mode 100644 index 0000000..a441a7a --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/license.txt @@ -0,0 +1,13 @@ + +/* + * THIS FILE HAS BEEN MODIFIED FROM THE OFFICIAL MAPM DISTRIBUTION + * BY 'Mickael Deloison/pgScript' on 2008/02/26. + * + * THIS FILE IS ORIGINALLY FROM MAPM VERSION 4.9.5. + * + * .... OPTIONAL: a brief description of file changes here .... + */ + +... start of MAPM original file ... + + diff --git a/include/pgscript/utilities/mapm-lib/m_apm.h b/include/pgscript/utilities/mapm-lib/m_apm.h new file mode 100644 index 0000000..8690080 --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/m_apm.h @@ -0,0 +1,767 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + + +/* + * M_APM - m_apm.h + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This is the header file that the user will include. + * + */ + +#undef sprintf +#undef strcat + +#ifndef M__APM__INCLUDED +#define M__APM__INCLUDED + +#ifdef __cplusplus +/* Comment this line out if you've compiled the library as C++. */ +#define APM_CONVERT_FROM_C +#endif + +#ifdef APM_CONVERT_FROM_C +extern "C" { +#endif + +typedef unsigned char UCHAR; + +typedef struct +{ + UCHAR *m_apm_data; + long m_apm_id; + int m_apm_refcount; /* <- used only by C++ MAPM class */ + int m_apm_malloclength; + int m_apm_datalength; + int m_apm_exponent; + int m_apm_sign; +} M_APM_struct; + +typedef M_APM_struct *M_APM; + + +#define MAPM_LIB_VERSION \ + "MAPM Library Version 4.9.5 Copyright (C) 1999-2007, Michael C. Ring" +#define MAPM_LIB_SHORT_VERSION "4.9.5" + + +/* + * convienient predefined constants + */ + +extern M_APM MM_Zero; +extern M_APM MM_One; +extern M_APM MM_Two; +extern M_APM MM_Three; +extern M_APM MM_Four; +extern M_APM MM_Five; +extern M_APM MM_Ten; + +extern M_APM MM_PI; +extern M_APM MM_HALF_PI; +extern M_APM MM_2_PI; +extern M_APM MM_E; + +extern M_APM MM_LOG_E_BASE_10; +extern M_APM MM_LOG_10_BASE_E; +extern M_APM MM_LOG_2_BASE_E; +extern M_APM MM_LOG_3_BASE_E; + + +/* + * function prototypes + */ + +extern M_APM m_apm_init(void); +extern void m_apm_free(M_APM); +extern void m_apm_free_all_mem(void); +extern void m_apm_trim_mem_usage(void); +extern char *m_apm_lib_version(char *); +extern char *m_apm_lib_short_version(char *); + +extern void m_apm_set_string(M_APM, const char *); +extern void m_apm_set_double(M_APM, double); +extern void m_apm_set_long(M_APM, long); + +extern void m_apm_to_string(char *, int, M_APM); +extern void m_apm_to_fixpt_string(char *, int, M_APM); +extern void m_apm_to_fixpt_stringex(char *, int, M_APM, char, char, int); +extern char *m_apm_to_fixpt_stringexp(int, M_APM, char, char, int); +extern void m_apm_to_integer_string(char *, M_APM); + +extern void m_apm_absolute_value(M_APM, M_APM); +extern void m_apm_negate(M_APM, M_APM); +extern void m_apm_copy(M_APM, M_APM); +extern void m_apm_round(M_APM, int, M_APM); +extern int m_apm_compare(M_APM, M_APM); +extern int m_apm_sign(M_APM); +extern int m_apm_exponent(M_APM); +extern int m_apm_significant_digits(M_APM); +extern int m_apm_is_integer(M_APM); +extern int m_apm_is_even(M_APM); +extern int m_apm_is_odd(M_APM); + +extern void m_apm_gcd(M_APM, M_APM, M_APM); +extern void m_apm_lcm(M_APM, M_APM, M_APM); + +extern void m_apm_add(M_APM, M_APM, M_APM); +extern void m_apm_subtract(M_APM, M_APM, M_APM); +extern void m_apm_multiply(M_APM, M_APM, M_APM); +extern void m_apm_divide(M_APM, int, M_APM, M_APM); +extern void m_apm_integer_divide(M_APM, M_APM, M_APM); +extern void m_apm_integer_div_rem(M_APM, M_APM, M_APM, M_APM); +extern void m_apm_reciprocal(M_APM, int, M_APM); +extern void m_apm_factorial(M_APM, M_APM); +extern void m_apm_floor(M_APM, M_APM); +extern void m_apm_ceil(M_APM, M_APM); +extern void m_apm_get_random(M_APM); +extern void m_apm_set_random_seed(char *); + +extern void m_apm_sqrt(M_APM, int, M_APM); +extern void m_apm_cbrt(M_APM, int, M_APM); +extern void m_apm_log(M_APM, int, M_APM); +extern void m_apm_log10(M_APM, int, M_APM); +extern void m_apm_exp(M_APM, int, M_APM); +extern void m_apm_pow(M_APM, int, M_APM, M_APM); +extern void m_apm_integer_pow(M_APM, int, M_APM, int); +extern void m_apm_integer_pow_nr(M_APM, M_APM, int); + +extern void m_apm_sin_cos(M_APM, M_APM, int, M_APM); +extern void m_apm_sin(M_APM, int, M_APM); +extern void m_apm_cos(M_APM, int, M_APM); +extern void m_apm_tan(M_APM, int, M_APM); +extern void m_apm_arcsin(M_APM, int, M_APM); +extern void m_apm_arccos(M_APM, int, M_APM); +extern void m_apm_arctan(M_APM, int, M_APM); +extern void m_apm_arctan2(M_APM, int, M_APM, M_APM); + +extern void m_apm_sinh(M_APM, int, M_APM); +extern void m_apm_cosh(M_APM, int, M_APM); +extern void m_apm_tanh(M_APM, int, M_APM); +extern void m_apm_arcsinh(M_APM, int, M_APM); +extern void m_apm_arccosh(M_APM, int, M_APM); +extern void m_apm_arctanh(M_APM, int, M_APM); + +extern void m_apm_cpp_precision(int); /* only for C++ wrapper */ + +/* more intuitive alternate names for the ARC functions ... */ + +#define m_apm_asin m_apm_arcsin +#define m_apm_acos m_apm_arccos +#define m_apm_atan m_apm_arctan +#define m_apm_atan2 m_apm_arctan2 + +#define m_apm_asinh m_apm_arcsinh +#define m_apm_acosh m_apm_arccosh +#define m_apm_atanh m_apm_arctanh + +#ifdef APM_CONVERT_FROM_C +} /* End extern "C" bracket */ +#endif + +#ifdef __cplusplus /*<- Hides the class below from C compilers */ + +/* + This class lets you use M_APM's a bit more intuitively with + C++'s operator and function overloading, constructors, etc. + + Added 3/24/2000 by Orion Sky Lawlor, olawlor@acm.org +*/ + +extern +#ifdef APM_CONVERT_FROM_C +"C" +#endif +int MM_cpp_min_precision; + + +class MAPM +{ +protected: + + /* + The M_APM structure here is implemented as a reference- + counted, copy-on-write data structure-- this makes copies + very fast, but that's why it's so ugly. A MAPM object is + basically just a wrapper around a (possibly shared) + M_APM_struct myVal. + */ + + + M_APM myVal; /* My M_APM structure */ + void create(void) + { + myVal = makeNew(); + } + void destroy(void) + { + unref(myVal); + myVal = NULL; + } + void copyFrom(M_APM Nval) + { + M_APM oldVal = myVal; + myVal = Nval; + ref(myVal); + unref(oldVal); + } + static M_APM makeNew(void) + { + M_APM val = m_apm_init(); + /* refcount initialized to 1 by 'm_apm_init' */ + return val; + } + static void ref(M_APM val) + { + val->m_apm_refcount++; + } + static void unref(M_APM val) + { + val->m_apm_refcount--; + if (val->m_apm_refcount == 0) + m_apm_free(val); + } + + /* This routine is called to get a private (mutable) + copy of our current value. */ + M_APM val(void) + { + if (myVal->m_apm_refcount == 1) + /* Return my private myVal */ + return myVal; + + /* Otherwise, our copy of myVal is shared-- + we need to make a new private copy. + */ + M_APM oldVal = myVal; + myVal = makeNew(); + m_apm_copy(myVal, oldVal); + unref(oldVal); + return myVal; + } + + /*BAD: C M_APM routines doesn't use "const" where they should-- + hence we have to cast to a non-const type here (FIX THIS!). + + (in due time.... MCR) + */ + M_APM cval(void) const + { + return (M_APM)myVal; + } + /* This is the default number of digits to use for + 1-ary functions like sin, cos, tan, etc. + It's the larger of my digits and cpp_min_precision. + */ + int myDigits(void) const + { + int maxd = m_apm_significant_digits(cval()); + if (maxd < MM_cpp_min_precision) maxd = MM_cpp_min_precision; + return maxd; + } + /* This is the default number of digits to use for + 2-ary functions like divide, atan2, etc. + It's the larger of my digits, his digits, and cpp_min_precision. + */ + int digits(const MAPM &otherVal) const + { + int maxd = myDigits(); + int his = m_apm_significant_digits(otherVal.cval()); + if (maxd < his) maxd = his; + return maxd; + } +public: + /* Constructors: */ + MAPM(void) /* Default constructor (takes no value) */ + { + create(); + } + MAPM(const MAPM &m) /* Copy constructor */ + { + myVal = (M_APM)m.cval(); + ref(myVal); + } + MAPM(M_APM m) /* M_APM constructor (refcount starts at one) */ + { + myVal = (M_APM)m; + ref(myVal); + } + MAPM(const char *s) /* Constructor from string */ + { + create(); + m_apm_set_string(val(), (char *)s); + } + MAPM(double d) /* Constructor from double-precision float */ + { + create(); + m_apm_set_double(val(), d); + } + MAPM(int l) /* Constructor from int */ + { + create(); + m_apm_set_long(val(), l); + } + MAPM(long l) /* Constructor from long int */ + { + create(); + m_apm_set_long(val(), l); + } + /* Destructor */ + ~MAPM() + { + destroy(); + } + + /* Extracting string descriptions: */ + void toString(char *dest, int decimalPlaces) const + { + m_apm_to_string(dest, decimalPlaces, cval()); + } + void toFixPtString(char *dest, int decimalPlaces) const + { + m_apm_to_fixpt_string(dest, decimalPlaces, cval()); + } + void toFixPtStringEx(char *dest, int dp, char a, char b, int c) const + { + m_apm_to_fixpt_stringex(dest, dp, cval(), a, b, c); + } + char *toFixPtStringExp(int dp, char a, char b, int c) const + { + return(m_apm_to_fixpt_stringexp(dp, cval(), a, b, c)); + } + void toIntegerString(char *dest) const + { + m_apm_to_integer_string(dest, cval()); + } + + /* Basic operators: */ + MAPM &operator=(const MAPM &m) /* Assigment operator */ + { + copyFrom((M_APM)m.cval()); + return *this; + } + MAPM &operator=(const char *s) /* Assigment operator */ + { + m_apm_set_string(val(), (char *)s); + return *this; + } + MAPM &operator=(double d) /* Assigment operator */ + { + m_apm_set_double(val(), d); + return *this; + } + MAPM &operator=(int l) /* Assigment operator */ + { + m_apm_set_long(val(), l); + return *this; + } + MAPM &operator=(long l) /* Assigment operator */ + { + m_apm_set_long(val(), l); + return *this; + } + MAPM operator++() /* Prefix increment operator */ + { + return *this = *this + MM_One; + } + MAPM operator--() /* Prefix decrement operator */ + { + return *this = *this - MM_One; + } + const MAPM operator++(int) /* Postfix increment operator */ + { + MAPM old = *this; + ++(*this); /* Call prefix increment */ + return old; + } + const MAPM operator--(int) /* Postfix decrement operator */ + { + MAPM old = *this; + --(*this); /* Call prefix decrement */ + return old; + } + + /* Comparison operators */ + int operator==(const MAPM &m) const /* Equality operator */ + { + return m_apm_compare(cval(), m.cval()) == 0; + } + int operator!=(const MAPM &m) const /* Inequality operator */ + { + return m_apm_compare(cval(), m.cval()) != 0; + } + int operator<(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) < 0; + } + int operator<=(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) <= 0; + } + int operator>(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) > 0; + } + int operator>=(const MAPM &m) const + { + return m_apm_compare(cval(), m.cval()) >= 0; + } + + /* Basic arithmetic operators */ + friend MAPM operator+(const MAPM &a, const MAPM &b); + friend MAPM operator-(const MAPM &a, const MAPM &b); + friend MAPM operator*(const MAPM &a, const MAPM &b) + { + MAPM ret; + m_apm_multiply(ret.val(), a.cval(), b.cval()); + return ret; + } + friend MAPM operator%(const MAPM &a, const MAPM &b) + { + MAPM quot, ret; + m_apm_integer_div_rem(quot.val(), ret.val(), + a.cval(), b.cval()); + return ret; + } + + /* Default division keeps larger of cpp_min_precision, numerator + digits of precision, or denominator digits of precision. */ + friend MAPM operator/(const MAPM &a, const MAPM &b) + { + return a.divide(b, a.digits(b)); + } + + MAPM divide(const MAPM &m, int toDigits) const + { + MAPM ret; + m_apm_divide(ret.val(), toDigits, cval(), + m.cval()); + return ret; + } + MAPM divide(const MAPM &m) const + { + return divide(m, digits(m)); + } + + /* Assignment arithmetic operators */ + MAPM &operator+=(const MAPM &m) + { + *this = *this + m; + return *this; + } + MAPM &operator-=(const MAPM &m) + { + *this = *this - m; + return *this; + } + MAPM &operator*=(const MAPM &m) + { + *this = *this * m; + return *this; + } + MAPM &operator/=(const MAPM &m) + { + *this = *this / m; + return *this; + } + MAPM &operator%=(const MAPM &m) + { + *this = *this % m; + return *this; + } + + /* Extracting/setting simple information: */ + int sign(void) const + { + return m_apm_sign(cval()); + } + int exponent(void) const + { + return m_apm_exponent(cval()); + } + int significant_digits(void) const + { + return m_apm_significant_digits(cval()); + } + int is_integer(void) const + { + return m_apm_is_integer(cval()); + } + int is_even(void) const + { + return m_apm_is_even(cval()); + } + int is_odd(void) const + { + return m_apm_is_odd(cval()); + } + + /* Functions: */ + MAPM abs(void) const + { + MAPM ret; + m_apm_absolute_value(ret.val(), cval()); + return ret; + } + MAPM neg(void) const + { + MAPM ret; + m_apm_negate(ret.val(), cval()); + return ret; + } + MAPM round(int toDigits) const + { + MAPM ret; + m_apm_round(ret.val(), toDigits, cval()); + return ret; + } + MAPM operator-(void) const + { + return neg(); + } + + /* I got tired of typing the various declarations for a simple + 1-ary real-to-real function on MAPM's; hence this define: + The digits-free versions return my digits of precision or + cpp_min_precision, whichever is bigger. + */ + +#define MAPM_1aryFunc(func) \ + MAPM func(int toDigits) const\ + {MAPM ret;m_apm_##func(ret.val(),toDigits,cval());return ret;}\ + MAPM func(void) const {return func(myDigits());} + + MAPM_1aryFunc(sqrt) + MAPM_1aryFunc(cbrt) + MAPM_1aryFunc(log) + MAPM_1aryFunc(exp) + MAPM_1aryFunc(log10) + MAPM_1aryFunc(sin) + MAPM_1aryFunc(asin) + MAPM_1aryFunc(cos) + MAPM_1aryFunc(acos) + MAPM_1aryFunc(tan) + MAPM_1aryFunc(atan) + MAPM_1aryFunc(sinh) + MAPM_1aryFunc(asinh) + MAPM_1aryFunc(cosh) + MAPM_1aryFunc(acosh) + MAPM_1aryFunc(tanh) + MAPM_1aryFunc(atanh) +#undef MAPM_1aryFunc + + void sincos(MAPM &sinR, MAPM &cosR, int toDigits) + { + m_apm_sin_cos(sinR.val(), cosR.val(), toDigits, cval()); + } + void sincos(MAPM &sinR, MAPM &cosR) + { + sincos(sinR, cosR, myDigits()); + } + MAPM pow(const MAPM &m, int toDigits) const + { + MAPM ret; + m_apm_pow(ret.val(), toDigits, cval(), + m.cval()); + return ret; + } + MAPM pow(const MAPM &m) const + { + return pow(m, digits(m)); + } + MAPM atan2(const MAPM &x, int toDigits) const + { + MAPM ret; + m_apm_arctan2(ret.val(), toDigits, cval(), + x.cval()); + return ret; + } + MAPM atan2(const MAPM &x) const + { + return atan2(x, digits(x)); + } + + MAPM gcd(const MAPM &m) const + { + MAPM ret; + m_apm_gcd(ret.val(), cval(), m.cval()); + return ret; + } + + MAPM lcm(const MAPM &m) const + { + MAPM ret; + m_apm_lcm(ret.val(), cval(), m.cval()); + return ret; + } + + static MAPM random(void) + { + MAPM ret; + m_apm_get_random(ret.val()); + return ret; + } + + MAPM floor(void) const + { + MAPM ret; + m_apm_floor(ret.val(), cval()); + return ret; + } + MAPM ceil(void) const + { + MAPM ret; + m_apm_ceil(ret.val(), cval()); + return ret; + } + + /* Functions defined only on integers: */ + MAPM factorial(void) const + { + MAPM ret; + m_apm_factorial(ret.val(), cval()); + return ret; + } + MAPM ipow_nr(int p) const + { + MAPM ret; + m_apm_integer_pow_nr(ret.val(), + cval(), p); + return ret; + } + MAPM ipow(int p, int toDigits) const + { + MAPM ret; + m_apm_integer_pow(ret.val(), + toDigits, cval(), p); + return ret; + } + MAPM ipow(int p) const + { + return ipow(p, myDigits()); + } + MAPM integer_divide(const MAPM &denom) const + { + MAPM ret; + m_apm_integer_divide(ret.val(), cval(), + denom.cval()); + return ret; + } + void integer_div_rem(const MAPM &denom, MAPM ", MAPM &rem) const + { + m_apm_integer_div_rem(quot.val(), rem.val(), cval(), + denom.cval()); + } + MAPM div(const MAPM &denom) const + { + return integer_divide(denom); + } + MAPM rem(const MAPM &denom) const + { + MAPM ret, ignored; + integer_div_rem(denom, ignored, ret); + return ret; + } +}; + +/* math.h-style functions: */ + +inline MAPM fabs(const MAPM &m) +{ + return m.abs(); +} +inline MAPM factorial(const MAPM &m) +{ + return m.factorial(); +} +inline MAPM floor(const MAPM &m) +{ + return m.floor(); +} +inline MAPM ceil(const MAPM &m) +{ + return m.ceil(); +} +inline MAPM get_random(void) +{ + return MAPM::random(); +} + +/* I got tired of typing the various declarations for a simple + 1-ary real-to-real function on MAPM's; hence this define: +*/ +#define MAPM_1aryFunc(func) \ + inline MAPM func(const MAPM &m) {return m.func();} \ + inline MAPM func(const MAPM &m,int toDigits) {return m.func(toDigits);} + +/* Define a big block of simple functions: */ +MAPM_1aryFunc(sqrt) +MAPM_1aryFunc(cbrt) +MAPM_1aryFunc(log) +MAPM_1aryFunc(exp) +MAPM_1aryFunc(log10) +MAPM_1aryFunc(sin) +MAPM_1aryFunc(asin) +MAPM_1aryFunc(cos) +MAPM_1aryFunc(acos) +MAPM_1aryFunc(tan) +MAPM_1aryFunc(atan) +MAPM_1aryFunc(sinh) +MAPM_1aryFunc(asinh) +MAPM_1aryFunc(cosh) +MAPM_1aryFunc(acosh) +MAPM_1aryFunc(tanh) +MAPM_1aryFunc(atanh) +#undef MAPM_1aryFunc + +/* Computes x to the power y */ +inline MAPM pow(const MAPM &x, const MAPM &y, int toDigits) +{ + return x.pow(y, toDigits); +} +inline MAPM pow(const MAPM &x, const MAPM &y) +{ + return x.pow(y); +} +inline MAPM atan2(const MAPM &y, const MAPM &x, int toDigits) +{ + return y.atan2(x, toDigits); +} +inline MAPM atan2(const MAPM &y, const MAPM &x) +{ + return y.atan2(x); +} +inline MAPM gcd(const MAPM &u, const MAPM &v) +{ + return u.gcd(v); +} +inline MAPM lcm(const MAPM &u, const MAPM &v) +{ + return u.lcm(v); +} +#endif +#endif diff --git a/include/pgscript/utilities/mapm-lib/m_apm_lc.h b/include/pgscript/utilities/mapm-lib/m_apm_lc.h new file mode 100644 index 0000000..e1cbf01 --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/m_apm_lc.h @@ -0,0 +1,271 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + + +/* + * M_APM - m_apm_lc.h + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This is the local header file needed to build the library + * + */ + +#ifndef M__APM_LOCAL_INC +#define M__APM_LOCAL_INC + +#include +#include +#include +#include +#include "m_apm.h" + +/* + * this supports older (and maybe newer?) Borland compilers. + * these Borland compilers define __MSDOS__ + */ + +#ifndef MSDOS +#ifdef __MSDOS__ +#define MSDOS +#endif +#endif + +/* + * this supports some newer Borland compilers (i.e., v5.5). + */ + +#ifndef MSDOS +#ifdef __BORLANDC__ +#define MSDOS +#endif +#endif + +/* + * this supports the LCC-WIN32 compiler + */ + +#ifndef MSDOS +#ifdef __LCC__ +#define MSDOS +#endif +#endif + +/* + * this supports Micro$oft Visual C++ and also possibly older + * straight C compilers as well. + */ + +#ifndef MSDOS +#ifdef _MSC_VER +#define MSDOS +#endif +#endif + +/* + * this supports the Metrowerks CodeWarrior 7.0 compiler (I think...) + */ + +#ifndef MSDOS +#ifdef __MWERKS__ +#define MSDOS +#endif +#endif + +/* + * this supports the MINGW 32 compiler + */ + +#ifndef MSDOS +#ifdef __MINGW_H +#define MSDOS +#endif +#endif + +/* + * this supports the Open Watcom 1.0 compiler + */ + +#ifndef MSDOS +#ifdef __WATCOMC__ +#define MSDOS +#endif +#endif + +/* + * this supports the Digital Mars compiler + */ + +#ifndef MSDOS +#ifdef __DMC__ +#define MSDOS +#endif +#endif + +/* + * this supports National Instruments LabWindows CVI + */ + +#ifndef _HAVE_NI_LABWIN_CVI_ +#ifdef _CVI_ +#define _HAVE_NI_LABWIN_CVI_ +#endif +#endif + +/* + * If for some reason (RAM limitations, slow floating point, whatever) + * you do NOT want to use the FFT multiply algorithm, un-comment the + * #define below, delete mapm_fft.c and remove mapm_fft from the build. + */ + +/* #define NO_FFT_MULTIPLY */ + +/* + * use your own memory management functions if desired. + * re-define MAPM_* below to point to your functions. + * an example is shown below. + */ + +/* +extern void *memory_allocate(unsigned int); +extern void *memory_reallocate(void *, unsigned int); +extern void memory_free(void *); + +#define MAPM_MALLOC memory_allocate +#define MAPM_REALLOC memory_reallocate +#define MAPM_FREE memory_free +*/ + +/* default: use the standard C library memory functions ... */ + +#define MAPM_MALLOC malloc +#define MAPM_REALLOC realloc +#define MAPM_FREE free + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define M_APM_IDENT 0x6BCC9AE5 +#define M_APM_RETURN 0 +#define M_APM_FATAL 1 + +/* number of digits in the global constants, PI, E, etc */ + +#define VALID_DECIMAL_PLACES 128 + +extern int MM_lc_PI_digits; +extern int MM_lc_log_digits; + +/* + * constants not in m_apm.h + */ + +extern M_APM MM_0_5; +extern M_APM MM_0_85; +extern M_APM MM_5x_125R; +extern M_APM MM_5x_64R; +extern M_APM MM_5x_256R; +extern M_APM MM_5x_Eight; +extern M_APM MM_5x_Sixteen; +extern M_APM MM_5x_Twenty; +extern M_APM MM_lc_PI; +extern M_APM MM_lc_HALF_PI; +extern M_APM MM_lc_2_PI; +extern M_APM MM_lc_log2; +extern M_APM MM_lc_log10; +extern M_APM MM_lc_log10R; + +/* + * prototypes for internal functions + */ + +#ifndef NO_FFT_MULTIPLY +extern void M_free_all_fft(void); +#endif + +extern void M_init_trig_globals(void); +extern void M_free_all_add(void); +extern void M_free_all_div(void); +extern void M_free_all_exp(void); +extern void M_free_all_pow(void); +extern void M_free_all_rnd(void); +extern void M_free_all_set(void); +extern void M_free_all_cnst(void); +extern void M_free_all_fmul(void); +extern void M_free_all_stck(void); +extern void M_free_all_util(void); + +extern int M_exp_compute_nn(int *, M_APM, M_APM); +extern void M_raw_exp(M_APM, int, M_APM); +extern void M_raw_sin(M_APM, int, M_APM); +extern void M_raw_cos(M_APM, int, M_APM); +extern void M_5x_sin(M_APM, int, M_APM); +extern void M_4x_cos(M_APM, int, M_APM); +extern void M_5x_do_it(M_APM, int, M_APM); +extern void M_4x_do_it(M_APM, int, M_APM); + +extern M_APM M_get_stack_var(void); +extern void M_restore_stack(int); +extern int M_get_sizeof_int(void); + +extern void M_apm_sdivide(M_APM, int, M_APM, M_APM); +extern void M_cos_to_sin(M_APM, int, M_APM); +extern void M_limit_angle_to_pi(M_APM, int, M_APM); +extern void M_log_near_1(M_APM, int, M_APM); +extern void M_get_sqrt_guess(M_APM, M_APM); +extern void M_get_cbrt_guess(M_APM, M_APM); +extern void M_get_log_guess(M_APM, M_APM); +extern void M_get_asin_guess(M_APM, M_APM); +extern void M_get_acos_guess(M_APM, M_APM); +extern void M_arcsin_near_0(M_APM, int, M_APM); +extern void M_arccos_near_0(M_APM, int, M_APM); +extern void M_arctan_near_0(M_APM, int, M_APM); +extern void M_arctan_large_input(M_APM, int, M_APM); +extern void M_log_basic_iteration(M_APM, int, M_APM); +extern void M_log_solve_cubic(M_APM, int, M_APM); +extern void M_check_log_places(int); +extern void M_log_AGM_R_func(M_APM, int, M_APM, M_APM); +extern void M_init_util_data(void); +extern void M_get_div_rem_addr(UCHAR **, UCHAR **); +extern void M_get_div_rem(int, UCHAR *, UCHAR *); +extern void M_get_div_rem_10(int, UCHAR *, UCHAR *); +extern void M_apm_normalize(M_APM); +extern void M_apm_scale(M_APM, int); +extern void M_apm_pad(M_APM, int); +extern void M_long_2_ascii(char *, long); +extern void M_check_PI_places(int); +extern void M_calculate_PI_AGM(M_APM, int); +extern void M_set_to_zero(M_APM); +extern int M_strposition(char *, char *); +extern char *M_lowercase(char *); +extern void M_apm_log_error_msg(int, const char *); +extern void M_apm_round_fixpt(M_APM, int, M_APM); + +#endif diff --git a/include/pgscript/utilities/mapm-lib/module.mk b/include/pgscript/utilities/mapm-lib/module.mk new file mode 100644 index 0000000..2bf702e --- /dev/null +++ b/include/pgscript/utilities/mapm-lib/module.mk @@ -0,0 +1,18 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/utilities/mapm-lib/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/utilities/mapm-lib/m_apm.h \ + include/pgscript/utilities/mapm-lib/m_apm_lc.h + +EXTRA_DIST += \ + include/pgscript/utilities/mapm-lib/module.mk \ + include/pgscript/utilities/mapm-lib/license.txt diff --git a/include/pgscript/utilities/module.mk b/include/pgscript/utilities/module.mk new file mode 100644 index 0000000..14d3043 --- /dev/null +++ b/include/pgscript/utilities/module.mk @@ -0,0 +1,26 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/pgscript/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/pgscript/utilities/pgsAlloc.h \ + include/pgscript/utilities/pgsContext.h \ + include/pgscript/utilities/pgsCopiedPtr.h \ + include/pgscript/utilities/pgsDriver.h \ + include/pgscript/utilities/pgsMapm.h \ + include/pgscript/utilities/pgsScanner.h \ + include/pgscript/utilities/pgsSharedPtr.h \ + include/pgscript/utilities/pgsThread.h \ + include/pgscript/utilities/pgsUtilities.h + +EXTRA_DIST += \ + include/pgscript/utilities/module.mk + +include include/pgscript/utilities/mapm-lib/module.mk diff --git a/include/pgscript/utilities/pgsAlloc.h b/include/pgscript/utilities/pgsAlloc.h new file mode 100644 index 0000000..8e3d1eb --- /dev/null +++ b/include/pgscript/utilities/pgsAlloc.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSALLOC_H +#define PGSALLOC_H + +#if defined(PGSDEBUG) + +#include // malloc and free +#include // std::bad_alloc +#include + +struct pgsMallocInfo +{ + const void *ptr; + size_t size; + wxString filename; + size_t line_nb; +}; + +WX_DECLARE_VOIDPTR_HASH_MAP(pgsMallocInfo, pgsMallocInfoMap); + +class pgsAlloc +{ + +protected: + + pgsAlloc(); + + pgsMallocInfoMap m_malloc_info; + +private: + + void add_malloc(const pgsMallocInfo &malloc_info); + + void rm_malloc(const void *ptr); + +public: + + void *pmalloc(size_t size, const char *filename, size_t line_nb); + + void dump(); + + void pfree(void *ptr); + + static pgsAlloc &instance(); + +}; + +void *operator new(size_t size) throw (std::bad_alloc); +void *operator new[](size_t size) throw (std::bad_alloc); +void *operator new(size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc); +void *operator new[](size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc); +void operator delete(void *ptr) throw (); +void operator delete[](void *ptr) throw (); + +#define pnew new(__FILE__, __LINE__) + +#else + +#define pnew new + +#endif // PGSDEBUG + +#define pdelete(x) if ((x) != 0) { delete x; x = 0; } +#define pdeletea(x) if ((x) != 0) { delete[] x; x = 0; } + +#endif /*PGSALLOC_H_*/ diff --git a/include/pgscript/utilities/pgsContext.h b/include/pgscript/utilities/pgsContext.h new file mode 100644 index 0000000..398170f --- /dev/null +++ b/include/pgscript/utilities/pgsContext.h @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCONTEXT_H_ +#define PGSCONTEXT_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStmtList.h" + +WX_DECLARE_LIST(pgsExpression, pgsListExpression); + +class pgsThread; + +/** pgsContext is kind of a util class used during script parsing. + * It is used in pgsParser.yy. Some members are made public because they need + * to be easily available in order to be passed to some other objects. */ +class pgsContext +{ + +private: + + wxArrayString m_columns; + + /** List of temporary expressions or variables. */ + pgsListExpression m_vars; + + /** List of temporary statements. */ + pgsListStmt m_stmts; + +public: + + /** For writing to the output. */ + pgsOutputStream &m_cout; + +public: + + ////////////////////////////// + // Constructor & destructor // + ////////////////////////////// + + pgsContext(pgsOutputStream &cout); + + ~pgsContext(); + + /////////////////////////////// + // Methods generating values // + /////////////////////////////// + + /** Generates a pgsNumber with value '0' and put it on stack. */ + pgsVariable *zero(); + + /** Generates a pgsNumber with value '0' and put it on stack. */ + pgsVariable *one(); + + /** Generates a pgsNumber with value now() and put it on stack. */ + pgsVariable *seed(); + + /** Generates a pgsString with the locale encoding and put it on stack. */ + pgsVariable *encoding(); + + /** Generates an empty statement list and put it on stack. */ + pgsStmtList *stmt_list(pgsThread *app = 0); + + //////////////////////////////////////////////// + // For managing a new record declaration list // + //////////////////////////////////////////////// + + /** Adds a column name to the column list. */ + void add_column(const wxString &column); + + /** Retrieves the column list. */ + const wxArrayString &columns(); + + /** Clears the column list. */ + void clear_columns(); + + + ///////////////////////////////////////////// + // For managing stacks of temporary values // + ///////////////////////////////////////////// + + /** Adds a pgsExpression on stack. */ + void push_var(pgsExpression *var); + + /** Removes the last pgsExpression on stack. */ + void pop_var(); + + /** Gives the number of pgsExpression on stack. */ + size_t size_vars() const; + + /** Adds a pgsStmt on stack. */ + void push_stmt(pgsStmt *stmt); + + /** Removes the last pgsStmt on stack. */ + void pop_stmt(); + + /** Gives the number of pgsStmt on stack. */ + size_t size_stmts() const; + + /** When an error occurs in the parser this method must be called in order + * to free the memory (i.e the temporary pgsExpression & pgsStmt). */ + void clear_stacks(); + +private: + + pgsContext(const pgsContext &that); + + pgsContext &operator=(const pgsContext &that); + +}; + +#endif /*PGSCONTEXT_H_*/ diff --git a/include/pgscript/utilities/pgsCopiedPtr.h b/include/pgscript/utilities/pgsCopiedPtr.h new file mode 100644 index 0000000..e5c3995 --- /dev/null +++ b/include/pgscript/utilities/pgsCopiedPtr.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSCOPIEDPTR_H_ +#define PGSCOPIEDPTR_H_ + +#include + +template class pgsCopiedPtr +{ + +private: + + T *p; + +public: + + pgsCopiedPtr(T *p) : + p(p) + { + + } + + pgsCopiedPtr() : + p(0) + { + + } + + pgsCopiedPtr(const pgsCopiedPtr &that) : + p(that.p == 0 ? 0 : that.p->clone()) + { + + } + + ~pgsCopiedPtr() + { + pdelete(p); + } + + pgsCopiedPtr &operator =(pgsCopiedPtr that) + { + std::swap(p, that.p); + return (*this); + } + + T &operator *() + { + return *p; + } + + const T &operator *() const + { + return *p; + } + + T *operator ->() + { + return p; + } + + const T *operator ->() const + { + return p; + } + + const T *get() const + { + return p; + } +}; + +#endif /*PGSCOPIEDPTR_H_*/ diff --git a/include/pgscript/utilities/pgsDriver.h b/include/pgscript/utilities/pgsDriver.h new file mode 100644 index 0000000..e7c637b --- /dev/null +++ b/include/pgscript/utilities/pgsDriver.h @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSDRIVER_H_ +#define PGSDRIVER_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/utilities/pgsScanner.h" +#include "pgscript/parser.tab.hh" + +// Forward declaration +class pgsContext; + +// Forward declaration +class pgsProgram; + +// Forward declaration +class pgsThread; + +/** The pgscript namespace is used to encapsulate the three parser classes + * pgscript::pgsParser, pgscript::pgsScanner and pgscript::pgsDriver */ +namespace pgscript +{ + +/** The pgsDriver class brings together all components. It creates an instance of + * the pgsParser and pgsScanner classes and connects them. Then the input stream is + * fed into the scanner object and the parser gets its token + * sequence. Furthermore the driver object is available in the grammar rules as + * a parameter. Therefore the driver class contains a reference to the + * structure into which the parsed data is saved. */ +class pgsDriver +{ +public: + /// Construct a new parser driver context + pgsDriver(class pgsContext &_context, class pgsProgram &_program, + class pgsThread &_thread); + + /// Destroy parser + ~pgsDriver(); + + /// Enable debug output in the flex scanner + bool trace_scanning; + + /// Enable debug output in the bison parser + bool trace_parsing; + + /** Invoke the scanner and parser for a stream. + * @param in input stream + * @return true if successfully parsed + */ + bool parse_stream(std::istream &in); + + /** Invoke the scanner and parser on an input string. + * @param input input string + * @return true if successfully parsed + */ + bool parse_string(const wxString &input); + + /** Invoke the scanner and parser on a file. Use parse_stream with a + * std::ifstream if detection of file reading errors is required. + * @param filename input file name + * @param conv multi-byte string converter + * @return true if successfully parsed + */ + bool parse_file(const wxString &filename, wxMBConv &conv = wxConvLocal); + + // To demonstrate pure handling of parse errors, instead of + // simply dumping them on the standard error output, we will pass + // them to the driver using the following two member functions. + + /** Error handling with associated line number. This can be modified to + * output the error e.g. to a dialog box. */ + void error(const class location &l, const wxString &m); + + /** Pointer to the current lexer instance, this is used to connect the + * parser to the scanner. It is used in the yylex macro. */ + class pgsScanner *lexer; + + /** Reference to the context filled during parsing of the expressions. */ + class pgsContext &context; + + /** Contains the list of statements to execute. */ + class pgsProgram &program; + + /** The thread in which this driver is included. */ + class pgsThread &thread; +}; + +} // namespace pgscript + +#endif // PGSDRIVER_H_ diff --git a/include/pgscript/utilities/pgsMapm.h b/include/pgscript/utilities/pgsMapm.h new file mode 100644 index 0000000..8c26af4 --- /dev/null +++ b/include/pgscript/utilities/pgsMapm.h @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSMAPMLIB_H_ +#define PGSMAPMLIB_H_ + +#include "pgscript/pgScript.h" +#include "mapm-lib/m_apm.h" + +WX_DECLARE_OBJARRAY(MAPM, pgsVectorMapm); + +class pgsMapm +{ + +public: + + static wxString pgs_mapm_str(const MAPM &m, const bool &as_int = false); + + static MAPM pgs_mapm_round(const MAPM &m); + + static wxString pgs_mapm_str_fixed(const MAPM &m); + + static wxString pgs_mapm_str_float(const MAPM &m); + + static MAPM pgs_str_mapm(const wxString &s); + +}; + +#endif /*PGSMAPMLIB_H_*/ diff --git a/include/pgscript/utilities/pgsScanner.h b/include/pgscript/utilities/pgsScanner.h new file mode 100644 index 0000000..87a7fa7 --- /dev/null +++ b/include/pgscript/utilities/pgsScanner.h @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSCANNER_H_ +#define PGSSCANNER_H_ + +// Flex expects the signature of yylex to be defined in the macro YY_DECL, and +// the C++ parser expects it to be declared. We can factor both as follows. + +#ifndef YY_DECL + +#define YY_DECL \ + pgscript::pgsParser::token_type \ + pgscript::pgsScanner::lex( \ + pgscript::pgsParser::semantic_type* yylval, \ + pgscript::pgsParser::location_type* yylloc \ + ) +#endif + +#ifndef __FLEX_LEXER_H +#define yyFlexLexer pgsFlexLexer +#include "pgscript/FlexLexer.h" +#undef yyFlexLexer +#endif + +#include "pgscript/parser.tab.hh" +#include +#include +#include + +namespace pgscript +{ + +/** pgsScanner is a derived class to add some extra function to the scanner + * class. Flex itself creates a class named yyFlexLexer, which is renamed using + * macros to pgsFlexLexer. However we change the context of the generated + * yylex() function to be contained within the pgsScanner class. This is required + * because the yylex() defined in pgsFlexLexer has no parameters. */ +class pgsScanner : public pgsFlexLexer +{ +public: + /** Create a new scanner object. The streams arg_yyin and arg_yyout default + * to cin and cout, but that assignment is only made when initializing in + * yylex(). */ + pgsScanner(wxMBConv &conv, std::istream *arg_yyin = 0, + std::ostream *arg_yyout = 0); + + /** Required for virtual functions */ + virtual ~pgsScanner(); + + /** This is the main lexing function. It is generated by flex according to + * the macro declaration YY_DECL above. The generated bison parser then + * calls this virtual function to fetch new tokens. */ + virtual pgsParser::token_type lex(pgsParser::semantic_type *yylval, + pgsParser::location_type *yylloc); + + /** Enable debug output (via arg_yyout) if compiled into the scanner. */ + void set_debug(bool b); + +private: + + /** Corrects column count because of multi-byte UTF8 characters. */ + int columns(const char &c); + + /** To count parenthesis. */ + int m_parent; + + std::string query, dollar, str; + + int comment_caller, string_caller; + + pgscript::pgsParser::token_type query_token; + + wxMBConv &m_conv; + +}; + +} // namespace pgscript + +#endif // PGSSCANNER_H_ diff --git a/include/pgscript/utilities/pgsSharedPtr.h b/include/pgscript/utilities/pgsSharedPtr.h new file mode 100644 index 0000000..543e68b --- /dev/null +++ b/include/pgscript/utilities/pgsSharedPtr.h @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSSHAREDPTR_H_ +#define PGSSHAREDPTR_H_ + +template class pgsSharedPtr +{ + +private: + + struct count + { + long c; + + T *q; + + count(T *q) : + c(1), q(q) + { + + } + + ~count() + { + pdelete(q); + } + }; + + count *p; + +public: + + pgsSharedPtr(T *q) : + p(pnew count(q)) + { + + } + + pgsSharedPtr() : + p(pnew count(0)) + { + + } + + pgsSharedPtr(const pgsSharedPtr &that) : + p(that.p) + { + ++p->c; + } + + ~pgsSharedPtr() + { + if (!--p->c) + { + pdelete(p); + } + } + + pgsSharedPtr &operator =(pgsSharedPtr that) + { + std::swap(p, that.p); + return (*this); + } + + T &operator *() + { + return *(p->q); + } + + const T &operator *() const + { + return *(p->q); + } + + T *operator ->() + { + return p->q; + } + + const T *operator ->() const + { + return p->q; + } + + const T *get() const + { + return p->q; + } +}; + +#endif /*PGSSHAREDPTR_H_*/ diff --git a/include/pgscript/utilities/pgsThread.h b/include/pgscript/utilities/pgsThread.h new file mode 100644 index 0000000..2445f32 --- /dev/null +++ b/include/pgscript/utilities/pgsThread.h @@ -0,0 +1,92 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSTHREAD_H_ +#define PGSTHREAD_H_ + +#include "pgscript/pgScript.h" +#include "pgscript/objects/pgsVariable.h" + +#include + +class pgConn; +class pgsApplication; +class pgsStmtList; + +class pgsThread : public wxThread +{ + +private: + + /** Symbol table (memory variables). */ + pgsVarMap &m_vars; + + /** In order to have only one thread at once. */ + wxSemaphore &m_mutex; + + /** Connection to the database. */ + pgConn *m_connection; + + /** Either the file to parse or the string. */ + wxString m_data; + + /** Where to write the output. */ + pgsOutputStream &m_out; + + /** The calling application. */ + pgsApplication &m_app; + + /** If set it is the encoding used in the file to parse. */ + wxMBConv *m_conv; + + /** Location of the last error if there was one otherwise -1 */ + int m_last_error_line; + +public: + + /** Parses a file with the provided encoding. */ + pgsThread(pgsVarMap &vars, wxSemaphore &mutex, pgConn *connection, + const wxString &file, pgsOutputStream &out, + pgsApplication &app, wxMBConv *conv); + + /** Parses a wxString. */ + pgsThread(pgsVarMap &vars, wxSemaphore &mutex, pgConn *connection, + const wxString &string, pgsOutputStream &out, pgsApplication &app); + + /** Destructor. */ + ~pgsThread(); + + /** Thread main code. */ + virtual void *Entry(); + + /** Retrieves the connection to the database. */ + pgConn *connection(); + + /** Gets a lock on the output stream. */ + void LockOutput(); + + /** Releases the lock on the output stream. */ + void UnlockOutput(); + + /** Set the position (line) of the last error. */ + void last_error_line(int line); + + /** Get the position (line) of the last error. */ + int last_error_line() const; + +private: + + pgsThread(const pgsThread &that); + + pgsThread &operator=(const pgsThread &that); + +}; + +#endif /*PGSTHREAD_H_*/ diff --git a/include/pgscript/utilities/pgsUtilities.h b/include/pgscript/utilities/pgsUtilities.h new file mode 100644 index 0000000..689b0d3 --- /dev/null +++ b/include/pgscript/utilities/pgsUtilities.h @@ -0,0 +1,27 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef PGSUTILITIES_H_ +#define PGSUTILITIES_H_ + +#include "pgscript/pgScript.h" + +class pgsUtilities +{ + +public: + + static wxString uniform_line_returns(wxString s); + static wxString escape_quotes(wxString s); + static wxString unescape_quotes(wxString s); + +}; + +#endif /*PGSUTILITIES_H_*/ diff --git a/include/postgres.h b/include/postgres.h new file mode 100644 index 0000000..f3ef6d5 --- /dev/null +++ b/include/postgres.h @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// postgres.h - dummy include +// +////////////////////////////////////////////////////////////////////////// + + +#include + +#define lengthof(array) (sizeof (array) / sizeof ((array)[0])) +#define endof(array) (&array[lengthof(array)]) + + + +// to suppress much stuff in parse.h +#define YYTOKENTYPE +#define YYSTYPE int + + +#define NAMEDATALEN 32 diff --git a/include/precomp.h b/include/precomp.h new file mode 100644 index 0000000..f8d305a --- /dev/null +++ b/include/precomp.h @@ -0,0 +1,250 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// precomp.h - All header files for compilers supporting precompiled headers +// +////////////////////////////////////////////////////////////////////////// + +#ifdef WX_PRECOMP + +#include "copyright.h" +#include "pgAdmin3.h" +#include "version.h" + +#include "agent/dlgJob.h" +#include "agent/dlgSchedule.h" +#include "agent/dlgStep.h" +#include "agent/pgaJob.h" +#include "agent/pgaSchedule.h" +#include "agent/pgaStep.h" + +#include "ctl/calbox.h" +#include "ctl/ctlAuiNotebook.h" +#include "ctl/ctlCheckTreeView.h" +#include "ctl/ctlColourPicker.h" +#include "ctl/ctlComboBox.h" +#include "ctl/ctlListView.h" +#include "ctl/ctlSecurityPanel.h" +#include "ctl/ctlSQLBox.h" +#include "ctl/ctlSQLGrid.h" +#include "ctl/ctlSQLResult.h" +#include "ctl/ctlTree.h" +#include "ctl/explainCanvas.h" +#include "ctl/timespin.h" +#include "ctl/wxgridsel.h" +#include "ctl/xh_calb.h" +#include "ctl/xh_ctlcombo.h" +#include "ctl/xh_ctlchecktreeview.h" +#include "ctl/xh_ctlcolourpicker.h" +#include "ctl/xh_ctltree.h" +#include "ctl/xh_sqlbox.h" +#include "ctl/xh_timespin.h" + +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "db/pgQueryResultEvent.h" +#include "db/pgSet.h" + +#include "debugger/ctlMessageWindow.h" +#include "debugger/ctlResultGrid.h" +#include "debugger/ctlStackWindow.h" +#include "debugger/ctlTabWindow.h" +#include "debugger/ctlVarWindow.h" +#include "debugger/dbgBreakPoint.h" +#include "debugger/dbgConst.h" +#include "debugger/dbgController.h" +#include "debugger/dbgModel.h" +#include "debugger/dbgTargetInfo.h" +#include "debugger/debugger.h" +#include "debugger/dlgDirectDbg.h" +#include "debugger/frmDebugger.h" + +#include "dlg/dlgAddFavourite.h" +#include "dlg/dlgAggregate.h" +#include "dlg/dlgCast.h" +#include "dlg/dlgCheck.h" +#include "dlg/dlgClasses.h" +#include "dlg/dlgColumn.h" +#include "dlg/dlgConnect.h" +#include "dlg/dlgConversion.h" +#include "dlg/dlgDatabase.h" +#include "dlg/dlgDomain.h" +#include "dlg/dlgEditGridOptions.h" +#include "dlg/dlgFindReplace.h" +#include "dlg/dlgForeignDataWrapper.h" +#include "dlg/dlgForeignKey.h" +#include "dlg/dlgForeignServer.h" +#include "dlg/dlgFunction.h" +#include "dlg/dlgGroup.h" +#include "dlg/dlgHbaConfig.h" +#include "dlg/dlgIndex.h" +#include "dlg/dlgIndexConstraint.h" +#include "dlg/dlgLanguage.h" +#include "dlg/dlgMainConfig.h" +#include "dlg/dlgManageFavourites.h" +#include "dlg/dlgManageMacros.h" +#include "dlg/dlgOperator.h" +#include "dlg/dlgPackage.h" +#include "dlg/dlgPgpassConfig.h" +#include "dlg/dlgProperty.h" +#include "dlg/dlgRole.h" +#include "dlg/dlgRule.h" +#include "dlg/dlgSchema.h" +#include "dlg/dlgSelectConnection.h" +#include "dlg/dlgSelectDatabase.h" +#include "dlg/dlgSequence.h" +#include "dlg/dlgServer.h" +#include "dlg/dlgSynonym.h" +#include "dlg/dlgTable.h" +#include "dlg/dlgTablespace.h" +#include "dlg/dlgTextSearchConfiguration.h" +#include "dlg/dlgTextSearchDictionary.h" +#include "dlg/dlgTextSearchTemplate.h" +#include "dlg/dlgTextSearchParser.h" +#include "dlg/dlgTrigger.h" +#include "dlg/dlgType.h" +#include "dlg/dlgUser.h" +#include "dlg/dlgUserMapping.h" +#include "dlg/dlgView.h" +#include "dlg/dlgExtTable.h" + +#include "frm/frmAbout.h" +#include "frm/frmBackup.h" +#include "frm/frmConfig.h" +#include "frm/frmEditGrid.h" +#include "frm/frmExport.h" +#include "frm/frmGrantWizard.h" +#include "frm/frmHbaConfig.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMainConfig.h" +#include "frm/frmMaintenance.h" +#include "frm/frmOptions.h" +#include "frm/frmPassword.h" +#include "frm/frmPgpassConfig.h" +#include "frm/frmQuery.h" +#include "frm/frmReport.h" +#include "frm/frmRestore.h" +#include "frm/frmSplash.h" +#include "frm/frmStatus.h" +#include "frm/menu.h" + +#include "ogl/basic.h" +#include "ogl/basicp.h" +#include "ogl/bmpshape.h" +#include "ogl/canvas.h" +#include "ogl/composit.h" +#include "ogl/constrnt.h" +#include "ogl/divided.h" +#include "ogl/drawn.h" +#include "ogl/drawnp.h" +#include "ogl/lines.h" +#include "ogl/linesp.h" +#include "ogl/mfutils.h" +#include "ogl/misc.h" +#include "ogl/ogl.h" +#include "ogl/ogldiag.h" + +#include "gqb/gqbArrayCollection.h" +#include "gqb/gqbBrowser.h" +#include "gqb/gqbCollection.h" +#include "gqb/gqbCollectionBase.h" +#include "gqb/gqbColumn.h" +#include "gqb/gqbDatabase.h" +#include "gqb/gqbEvents.h" +#include "gqb/gqbGraphBehavior.h" +#include "gqb/gqbGraphSimple.h" +#include "gqb/gqbGridOrderTable.h" +#include "gqb/gqbGridProjTable.h" +#include "gqb/gqbGridRestTable.h" +#include "gqb/gqbModel.h" +#include "gqb/gqbObject.h" +#include "gqb/gqbObjectCollection.h" +#include "gqb/gqbQueryObjs.h" +#include "gqb/gqbSchema.h" +#include "gqb/gqbTable.h" +#include "gqb/gqbViewController.h" +#include "gqb/gqbViewPanels.h" + +#include "schema/edbPackage.h" +#include "schema/edbPackageFunction.h" +#include "schema/edbPackageVariable.h" +#include "schema/edbSynonym.h" +#include "schema/pgAggregate.h" +#include "schema/pgCast.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgCheck.h" +#include "schema/pgCollection.h" +#include "schema/pgColumn.h" +#include "schema/pgConstraints.h" +#include "schema/pgConversion.h" +#include "schema/pgDatabase.h" +#include "schema/pgDatatype.h" +#include "schema/pgDomain.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgForeignKey.h" +#include "schema/pgForeignServer.h" +#include "schema/pgFunction.h" +#include "schema/pgGroup.h" +#include "schema/pgIndex.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgLanguage.h" +#include "schema/pgObject.h" +#include "schema/pgOperator.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgRole.h" +#include "schema/pgRule.h" +#include "schema/pgSchema.h" +#include "schema/pgSequence.h" +#include "schema/pgServer.h" +#include "schema/pgTable.h" +#include "schema/pgTablespace.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgTrigger.h" +#include "schema/pgType.h" +#include "schema/pgUser.h" +#include "schema/pgUserMapping.h" +#include "schema/pgView.h" +#include "schema/gpExtTable.h" +#include "schema/gpPartition.h" +#include "schema/gpResQueue.h" + +#include "slony/dlgRepCluster.h" +#include "slony/dlgRepListen.h" +#include "slony/dlgRepNode.h" +#include "slony/dlgRepPath.h" +#include "slony/dlgRepProperty.h" +#include "slony/dlgRepSequence.h" +#include "slony/dlgRepSet.h" +#include "slony/dlgRepSubscription.h" +#include "slony/dlgRepTable.h" +#include "slony/slCluster.h" +#include "slony/slListen.h" +#include "slony/slNode.h" +#include "slony/slPath.h" +#include "slony/slSequence.h" +#include "slony/slSet.h" +#include "slony/slSubscription.h" +#include "slony/slTable.h" + +#include "utils/csvfiles.h" +#include "utils/factory.h" +#include "utils/favourites.h" +#include "utils/macros.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "utils/pgconfig.h" +#include "utils/pgfeatures.h" +#include "utils/sysLogger.h" +#include "utils/sysProcess.h" +#include "utils/sysSettings.h" +#include "utils/utffile.h" + +#endif diff --git a/include/pro_scheduler/pgproJob.h b/include/pro_scheduler/pgproJob.h new file mode 100644 index 0000000..45a4846 --- /dev/null +++ b/include/pro_scheduler/pgproJob.h @@ -0,0 +1,251 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgaJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGPROJOB_H +#define PGPROJOB_H + +#include "schema/pgServer.h" + + +class pgproJobFactory : public pgServerObjFactory +{ +public: + pgproJobFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetDisabledId() + { + return disabledId; + } + int GetRunId() + { + return runId; + } + +protected: + int disabledId,runId; +}; +extern pgproJobFactory projobFactory; + +class pgproJob : public pgServerObject +{ +public: + pgproJob(const wxString &newName = wxT("")); + void SetEnabled(ctlTree *browser, const bool b); + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetTranslatedMessage(int kindOfMessage) const; + wxString GetSql(ctlTree *browser); + + wxString GetCrontab() const + { + return crontab; + } + void iSetCrontab(const wxString &s) + { + crontab = s; + } + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + wxDateTime GetFinished() const + { + return finished; + } + void iSetFinished(const wxDateTime &d) + { + finished = d; + } + wxDateTime GetChanged() const + { + return changed; + } + void iSetChanged(const wxDateTime &d) + { + changed = d; + } + wxDateTime GetNextrun() const + { + return nextrun; + } + void iSetNextrun(const wxDateTime &d) + { + nextrun = d; + } + wxDateTime GetStarted() const + { + return lastrun; + } + void iSetStarted(const wxDateTime &d) + { + lastrun = d; + } + wxString GetMessage() const + { + return message; + } + void iSetMessage(const wxString &s) + { + message = s; + } + wxString GetStatus() const + { + return status; + } + void iSetStatus(const wxString &s) + { + status = s; + } + wxString GetRunAs() const + { + return runas; + } + void iSetRunAs(const wxString &s) + { + runas = s; + } + + wxString GetTryName() const + { + return tryname; + } + void iSetTryName(const wxString &s) + { + tryname = s; + } + + wxString GetRule() const + { + return rule; + } + void iSetRule(const wxString &s) + { + rule = s; + } + wxString GetCommands() const + { + return commands; + } + void iSetCommands(const wxString &s) + { + commands = s; + } + long GetRecId() const + { + return recId; + } + void iSetRecId(const long l) + { + recId = l; + } + bool RunNow(); + + wxMenu *GetNewMenu(); + bool CanCreate() + { + return false; + } + bool CanView() + { + return true; + } + bool CanEdit() + { + return false; + } + bool CanDrop() + { + return true; + } + bool WantDummyChild() + { + return false; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pgagent-jobs"); + } + +private: + bool enabled; + wxDateTime finished, changed, nextrun, lastrun; + wxString message, crontab, runas, commands,status,rule,tryname; + long recId; +}; + + +class pgproJobObject : public pgServerObject +{ +public: + pgproJobObject(pgproJob *job, pgaFactory &factory, const wxString &newName); + virtual pgproJob *GetJob() + { + return job; + } + + bool CanCreate() + { + return job->CanCreate(); + } + bool CanView() + { + return false; + } + bool CanEdit() + { + return job->CanEdit(); + } + bool CanDrop() + { + return job->CanDrop(); + } + +protected: + pgproJob *job; +}; + + +class pgproJobCollection : public pgServerObjCollection +{ +public: + pgproJobCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class enabledisableJobFactory : public contextActionFactory +{ +public: + enabledisableJobFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + + +class prorunNowFactory : public contextActionFactory +{ +public: + prorunNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/edbPackage.h b/include/schema/edbPackage.h new file mode 100644 index 0000000..63ca359 --- /dev/null +++ b/include/schema/edbPackage.h @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackage.h - EnterpriseDB Package class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPACKAGE_H +#define EDBPACKAGE_H + + +// App headers +#include "pgDatabase.h" +#include "pgSchema.h" + +class pgCollection; + +class edbPackageFactory : public pgSchemaObjFactory +{ +public: + edbPackageFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern edbPackageFactory packageFactory; + + +class edbPackage : public pgSchemaObject +{ +public: + edbPackage(pgSchema *newSchema, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool GetSystemObject() const + { + return GetOid() <= GetConnection()->GetLastSystemOID(); + } + + void iSetHeader(const wxString &data) + { + header = data; + }; + wxString GetHeader() + { + return header; + }; + void iSetBody(const wxString &data) + { + body = data; + }; + wxString GetBody() + { + return body; + }; + + wxString GetHeaderInner(); + wxString GetBodyInner(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool IsUpToDate(); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/packages-create"); + } +private: + wxString GetInner(const wxString &def); + + long numProcedures, numFunctions, numVariables; + wxString body, header; +}; + +class edbPackageObject : public pgSchemaObject +{ +public: + edbPackageObject(edbPackage *newPackage, pgaFactory &factory, const wxString &newName = wxT("")) + : pgSchemaObject(newPackage->GetSchema(), factory, newName) + { + package = newPackage; + } + virtual edbPackage *GetPackage() const + { + return package; + } + OID GetPackageOid() const + { + return package->GetOid(); + } + wxString GetPackageOidStr() const + { + return NumToStr(package->GetOid()) + wxT("::oid"); + } + + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + bool CanDrop() + { + return false; + } + bool CanDropCascaded() + { + return false; + } + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +protected: + edbPackage *package; +}; + +class edbPackageCollection : public pgSchemaObjCollection +{ +public: + edbPackageCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class edbPackageObjCollection : public pgSchemaObjCollection +{ +public: + edbPackageObjCollection(pgaFactory *factory, edbPackage *_package) + : pgSchemaObjCollection(factory, _package->GetSchema()) + { + iSetOid(_package->GetOid()); + package = _package; + } + virtual edbPackage *GetPackage() const + { + return package; + } + + virtual bool CanCreate() + { + return false; + } + +protected: + edbPackage *package; +}; + +class edbPackageObjFactory : public pgSchemaObjFactory +{ +public: + edbPackageObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgSchemaObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +#endif diff --git a/include/schema/edbPackageFunction.h b/include/schema/edbPackageFunction.h new file mode 100644 index 0000000..ecfb4da --- /dev/null +++ b/include/schema/edbPackageFunction.h @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageFunction.h - EnterpriseDB Package member function +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPACKAGEFUNCTION_H +#define EDBPACKAGEFUNCTION_H + +#include "edbPackage.h" + +class pgCollection; +class edbPackageFunction; + +class edbPackageFunctionFactory : public edbPackageObjFactory +{ +public: + edbPackageFunctionFactory(const wxChar *tn = 0, const wxChar *ns = 0, const wxChar *nls = 0, wxImage *img = 0); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) + { + return 0; + }; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); + + edbPackageFunction *AppendFunctions(pgObject *obj, edbPackage *package, ctlTree *browser, const wxString &restriction); +}; +extern edbPackageFunctionFactory packageFunctionFactory; + + +class edbPackageFunction : public edbPackageObject +{ +public: + edbPackageFunction(edbPackage *newPackage, const wxString &newName = wxT("")); + edbPackageFunction(edbPackage *newPackage, pgaFactory &factory, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetSql(ctlTree *browser); + + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + virtual bool GetIsProcedure() const + { + return false; + } + + wxString GetFullName(); + wxString GetArgListWithNames(); + wxString GetArgSigList(); + + wxArrayString &GetArgNamesArray() + { + return argNamesArray; + } + void iAddArgName(const wxString &s) + { + argNamesArray.Add(s); + } + wxArrayString &GetArgTypesArray() + { + return argTypesArray; + } + void iAddArgType(const wxString &s) + { + argTypesArray.Add(s); + } + wxArrayString &GetArgModesArray() + { + return argModesArray; + } + void iAddArgMode(const wxString &s) + { + argModesArray.Add(s); + } + wxArrayString &GetArgDefsArray() + { + return argDefsArray; + } + void iAddArgDef(const wxString &s) + { + argDefsArray.Add(s); + } + + wxString GetReturnType() const + { + return returnType; + } + void iSetReturnType(const wxString &s) + { + returnType = s; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetVisibility() const + { + return visibility; + } + void iSetVisibility(const wxString &s) + { + visibility = s; + } + long GetArgCount() const + { + return argCount; + } + void iSetArgCount(long ac) + { + argCount = ac; + } + + bool CanCreate() + { + return false; + } + +private: + long argCount; + wxArrayString argNamesArray, argTypesArray, argModesArray, argDefsArray; + wxString returnType, source, visibility; +}; + +class edbPackageFunctionCollection : public edbPackageObjCollection +{ +public: + edbPackageFunctionCollection(pgaFactory *factory, edbPackage *pkg); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class edbPackageProcedureFactory : public edbPackageFunctionFactory +{ +public: + edbPackageProcedureFactory(); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern edbPackageProcedureFactory packageProcedureFactory; + + +class edbPackageProcedure : public edbPackageFunction +{ +public: + edbPackageProcedure(edbPackage *newPackage, const wxString &newName = wxT("")); + wxString GetFullName(); + + bool GetIsProcedure() const + { + return true; + } + + wxString GetSql(ctlTree *browser); +}; + + +#endif diff --git a/include/schema/edbPackageVariable.h b/include/schema/edbPackageVariable.h new file mode 100644 index 0000000..910bc7c --- /dev/null +++ b/include/schema/edbPackageVariable.h @@ -0,0 +1,78 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageVariable.h - EnterpriseDB Package variable +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPACKAGEVARIABLE_H +#define EDBPACKAGEVARIABLE_H + +#include "edbPackage.h" +class pgCollection; +class edbPackageVariable; + +class edbPackageVariableFactory : public edbPackageObjFactory +{ +public: + edbPackageVariableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) + { + return 0; + }; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern edbPackageVariableFactory packageVariableFactory; + + +class edbPackageVariable : public edbPackageObject +{ +public: + edbPackageVariable(edbPackage *newPackage, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetSql(ctlTree *browser); + + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + wxString GetDataType() const + { + return dataType; + } + void iSetDataType(const wxString &s) + { + dataType = s; + } + wxString GetVisibility() const + { + return visibility; + } + void iSetVisibility(const wxString &s) + { + visibility = s; + } + + bool CanCreate() + { + return false; + } + +private: + wxString dataType, visibility; +}; + +class edbPackageVariableCollection : public edbPackageObjCollection +{ +public: + edbPackageVariableCollection(pgaFactory *factory, edbPackage *pkg); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/edbPrivateSynonym.h b/include/schema/edbPrivateSynonym.h new file mode 100644 index 0000000..038c585 --- /dev/null +++ b/include/schema/edbPrivateSynonym.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPrivateSynonym.h PostgreSQL Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBPRIVATESYNONYM_H +#define EDBPRIVATESYNONYM_H + +#include "schema/pgSchema.h" + + +class edbPrivateSynonymFactory : public pgSchemaObjFactory +{ +public: + edbPrivateSynonymFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +private: +}; +extern edbPrivateSynonymFactory edbPrivFactory; + +class edbPrivateSynonym : public pgSchemaObject +{ +public: + edbPrivateSynonym(pgSchema *newSchema, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + virtual wxString GetSql(ctlTree *browser); + + bool DropObject(wxFrame *, ctlTree *, bool); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool GetSystemObject() const + { + return GetSchema()->GetSystemObject(); + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createpubsynonym"); + } + + wxString GetTargetType() const + { + return targetType; + } + void iSetTargetType(const wxString &s) + { + targetType = s; + } + wxString GetTargetSchema() const + { + return targetSchema; + } + void iSetTargetSchema(const wxString &s) + { + targetSchema = s; + } + wxString GetTargetObject() const + { + return targetObject; + } + void iSetTargetObject(const wxString &s) + { + targetObject = s; + } + +private: + wxString targetType, targetSchema, targetObject; + bool isPublic; +}; + +class edbPrivateSynonymCollection : public pgSchemaObjCollection +{ +public: + edbPrivateSynonymCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/edbResourceGroup.h b/include/schema/edbResourceGroup.h new file mode 100644 index 0000000..3fd2fcc --- /dev/null +++ b/include/schema/edbResourceGroup.h @@ -0,0 +1,71 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbResourceGroup.h - Resource Group (only used for PPAS 9.4) +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBRESOURCEGROUP_H +#define EDBRESOURCEGROUP_H + +#include "pgServer.h" + +class edbResourceGroupFactory : public pgServerObjFactory +{ +public: + edbResourceGroupFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +extern edbResourceGroupFactory resourceGroupFactory; + + +// Class declarations +class edbResourceGroup : public pgServerObject +{ +public: + edbResourceGroup(const wxString &newName = wxT("")); + ~edbResourceGroup(); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + double GetCPURateLimit() const + { + return cpuRateLimit; + } + void iSetCPURateLimit(const double b) + { + cpuRateLimit = b; + } + double GetDirtyRateLimit() const + { + return dirtyRateLimit; + } + void iSetDirtyRateLimit(const double b) + { + dirtyRateLimit = b; + } + +private: + double cpuRateLimit, dirtyRateLimit; +}; + +class edbResourceGroupCollection : public pgServerObjCollection +{ +public: + edbResourceGroupCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/edbSynonym.h b/include/schema/edbSynonym.h new file mode 100644 index 0000000..b65ac0e --- /dev/null +++ b/include/schema/edbSynonym.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbSynonym.h - EnterpriseDB Synonym class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef EDBSYNONYM_H +#define EDBSYNONYM_H + + +// App headers +#include "pgDatabase.h" + +class pgCollection; +class edbSynonymFactory : public pgDatabaseObjFactory +{ +public: + edbSynonymFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern edbSynonymFactory synonymFactory; + + +class edbSynonym : public pgDatabaseObject +{ +public: + edbSynonym(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool GetSystemObject() const + { + return false; + } + wxString GetTargetType() const + { + return targetType; + } + void iSetTargetType(const wxString &s) + { + targetType = s; + } + wxString GetTargetSchema() const + { + return targetSchema; + } + void iSetTargetSchema(const wxString &s) + { + targetSchema = s; + } + wxString GetTargetObject() const + { + return targetObject; + } + void iSetTargetObject(const wxString &s) + { + targetObject = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createpubsynonym"); + } + +private: + wxString targetType, targetSchema, targetObject; +}; + +class edbSynonymCollection : public pgDatabaseObjCollection +{ +public: + edbSynonymCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +#endif diff --git a/include/schema/gpExtTable.h b/include/schema/gpExtTable.h new file mode 100644 index 0000000..fb89ebd --- /dev/null +++ b/include/schema/gpExtTable.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpExtTable.h Greenplum External Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef gpExtTable_H +#define gpExtTable_H + +#include "pgSchema.h" + +class pgCollection; + +class gpExtTableFactory : public pgSchemaObjFactory +{ +public: + gpExtTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; +extern gpExtTableFactory extTableFactory; + + +class gpExtTable : public pgSchemaObject +{ +public: + gpExtTable(pgSchema *newSchema, const wxString &newName = wxT("")); + ~gpExtTable(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanView() + { + return true; + } + bool WantDummyChild() + { + return false; + } + + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + void ShowHint(frmMain *form, bool force); + bool GetCanHint() + { + return true; + }; + + bool IsUpToDate(); + //wxString GetFormattedDefinition(); + +private: + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); +}; + +class gpExtTableCollection : public pgSchemaObjCollection +{ +public: + gpExtTableCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/gpPartition.h b/include/schema/gpPartition.h new file mode 100644 index 0000000..b58a5f6 --- /dev/null +++ b/include/schema/gpPartition.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpPartition.h Greenplum Partitioned Table Partition +// +////////////////////////////////////////////////////////////////////////// + +#ifndef gpPartition_H +#define gpPartition_H + +#include "pgSchema.h" +#include "pgTable.h" + + + +class gpPartitionFactory : public pgTableObjFactory +{ +public: + gpPartitionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) ; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + virtual void AppendMenu(wxMenu *menu); +}; + +extern gpPartitionFactory partitionFactory; + +class gpPartition : public pgTable +{ +public: + gpPartition(pgSchema *newSchema, const wxString &newName = wxT("")); + ~gpPartition(); + bool CanCreate(); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetPartitionName() + { + return partitionname; + } + void iSetPartitionName(const wxString &pn) + { + partitionname = pn; + } + +private: + wxString partitionname; +}; + + +class gpPartitionObject : public pgTableObject +{ +public: + gpPartitionObject(gpPartition *newTable, pgaFactory &factory, const wxString &newName = wxT("")) + : pgTableObject(newTable, factory, newName) { }; + virtual gpPartition *GetTable() const + { + return dynamic_cast(table); + } + OID GetTableOid() const + { + return table->GetOid(); + } + wxString GetTableOidStr() const + { + return NumToStr(table->GetOid()) + wxT("::oid"); + } +}; + + +class gpPartitionCollection : public pgTableCollection +{ +public: + gpPartitionCollection(pgaFactory *factory, gpPartition *_table); + virtual bool CanCreate() + { + return false; + }; +}; + + +class gpPartitionObjCollection : public pgTableObjCollection +{ +public: + gpPartitionObjCollection(pgaFactory *factory, gpPartition *_table) + : pgTableObjCollection(factory, (pgTable *)_table ) { }; + virtual pgTable *GetTable() const + { + return table; + } + virtual bool CanCreate(); +}; + + + +#endif diff --git a/include/schema/gpResQueue.h b/include/schema/gpResQueue.h new file mode 100644 index 0000000..7851940 --- /dev/null +++ b/include/schema/gpResQueue.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpResQueue.h - Greenplum Resource Queue +// +////////////////////////////////////////////////////////////////////////// + +#ifndef gpResQueue_H +#define gpResQueue_H + +#include "pgServer.h" + + + +class gpResQueueFactory : public pgServerObjFactory +{ +public: + gpResQueueFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + pgCollection *CreateCollection(pgObject *obj); +}; + +extern gpResQueueFactory resQueueFactory; + + + + +// Class declarations +class gpResQueue : public pgServerObject +{ + +protected: + gpResQueue(pgaFactory &factory, const wxString &newName = wxT("")); + +public: + gpResQueue(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + double GetCountLimit() const + { + return countlimit; + } + double GetCostLimit() const + { + return costlimit; + } + bool GetOvercommit() const + { + return overcommit; + } + double GetIgnoreCostLimit() const + { + return ignorecostlimit; + } + + void iSetCountLimit(double newVal) + { + countlimit = newVal; + } + void iSetCostLimit(double newVal) + { + costlimit = newVal; + } + void iSetOvercommit(bool newVal) + { + overcommit = newVal; + } + void iSetIgnoreCostLimit(double newVal) + { + ignorecostlimit = newVal; + } + + // Tree object creation + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + // virtual methods + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } +private: + wxArrayString queuesIn; + double countlimit, costlimit, ignorecostlimit; + bool overcommit; + +}; + +class gpResQueueCollection : public pgServerObjCollection +{ +public: + gpResQueueCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/module.mk b/include/schema/module.mk new file mode 100644 index 0000000..b36a8c5 --- /dev/null +++ b/include/schema/module.mk @@ -0,0 +1,68 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/schema/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/schema/edbPackage.h \ + include/schema/edbPackageFunction.h \ + include/schema/edbPackageVariable.h \ + include/schema/edbSynonym.h \ + include/schema/edbPrivateSynonym.h \ + include/schema/pgAggregate.h \ + include/schema/pgCatalogObject.h \ + include/schema/pgCast.h \ + include/schema/pgCheck.h \ + include/schema/pgCollation.h \ + include/schema/pgCollection.h \ + include/schema/pgColumn.h \ + include/schema/pgConstraints.h \ + include/schema/pgConversion.h \ + include/schema/pgDatabase.h \ + include/schema/pgDatatype.h \ + include/schema/pgDomain.h \ + include/schema/pgEventTrigger.h \ + include/schema/pgExtension.h \ + include/schema/pgForeignDataWrapper.h \ + include/schema/pgForeignKey.h \ + include/schema/pgForeignServer.h \ + include/schema/pgForeignTable.h \ + include/schema/pgFunction.h \ + include/schema/pgGroup.h \ + include/schema/pgIndex.h \ + include/schema/pgIndexConstraint.h \ + include/schema/pgLanguage.h \ + include/schema/pgObject.h \ + include/schema/pgOperator.h \ + include/schema/pgOperatorClass.h \ + include/schema/pgOperatorFamily.h \ + include/schema/pgRole.h \ + include/schema/pgRule.h \ + include/schema/pgSchema.h \ + include/schema/pgSequence.h \ + include/schema/pgServer.h \ + include/schema/pgTable.h \ + include/schema/pgTablespace.h \ + include/schema/pgTextSearchConfiguration.h \ + include/schema/pgTextSearchDictionary.h \ + include/schema/pgTextSearchParser.h \ + include/schema/pgTextSearchTemplate.h \ + include/schema/pgTrigger.h \ + include/schema/pgType.h \ + include/schema/pgUser.h \ + include/schema/pgUserMapping.h \ + include/schema/pgView.h \ + include/schema/gpExtTable.h \ + include/schema/gpResQueue.h \ + include/schema/gpPartition.h \ + include/schema/edbResourceGroup.h + +EXTRA_DIST += \ + include/schema/module.mk + diff --git a/include/schema/pgAggregate.h b/include/schema/pgAggregate.h new file mode 100644 index 0000000..8b87ce9 --- /dev/null +++ b/include/schema/pgAggregate.h @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAggregate.h - Aggregate class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGAGGREGATE_H +#define PGAGGREGATE_H + +#include "pgSchema.h" + +class pgCollection; +class pgAggregateFactory : public pgSchemaObjFactory +{ +public: + pgAggregateFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgAggregateFactory aggregateFactory; + +class pgAggregate : public pgSchemaObject +{ +public: + pgAggregate(pgSchema *newSchema, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + wxString GetQuotedFullName(); + wxString GetFullName(); + + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + + wxArrayString &GetInputTypesArray() + { + return inputTypes; + } + void iAddInputType(const wxString &s) + { + inputTypes.Add(s); + } + wxString GetInputTypesList(); + + wxString GetStateType() + { + return stateType; + } + void iSetStateType(const wxString &s) + { + stateType = s; + } + wxString GetFinalType() + { + return finalType; + } + void iSetFinalType(const wxString &s) + { + finalType = s; + } + wxString GetStateFunction() + { + return stateFunction; + } + void iSetStateFunction(const wxString &s) + { + stateFunction = s; + } + wxString GetFinalFunction() + { + return finalFunction; + } + void iSetFinalFunction(const wxString &s) + { + finalFunction = s; + } + wxString GetInitialCondition() + { + return initialCondition; + } + void iSetInitialCondition(const wxString &s) + { + initialCondition = s; + } + wxString GetSortOp() + { + return sortOp; + } + void iSetSortOp(const wxString &s) + { + sortOp = s; + } + wxString GetQuotedSortOp() + { + return quotedSortOp; + } + void iSetQuotedSortOp(const wxString &s) + { + quotedSortOp = s; + } + +private: + wxArrayString inputTypes; + wxString stateType, finalType, sortOp, quotedSortOp, + stateFunction, finalFunction, initialCondition; +}; + +class pgAggregateCollection : public pgSchemaObjCollection +{ +public: + pgAggregateCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCast.h b/include/schema/pgCast.h new file mode 100644 index 0000000..3c988e2 --- /dev/null +++ b/include/schema/pgCast.h @@ -0,0 +1,153 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCast.h PostgreSQL Cast +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCAST_H +#define PGCAST_H + + +// App headers +#include "pgDatabase.h" + +class pgCollection; +class pgCastFactory : public pgDatabaseObjFactory +{ +public: + pgCastFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgCastFactory castFactory; + + +class pgCast : public pgDatabaseObject +{ +public: + pgCast(const wxString &newName = wxT("")); + ~pgCast(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool CanDropCascaded() + { + return true; + } + + bool GetSystemObject() const + { + return GetOid() <= GetConnection()->GetLastSystemOID(); + } + wxString GetSourceType() const + { + return sourceType; + } + void iSetSourceType(const wxString &s) + { + sourceType = s; + } + wxString GetTargetType() const + { + return targetType; + } + void iSetTargetType(const wxString &s) + { + targetType = s; + } + wxString GetSourceNamespace() const + { + return sourceNamespace; + } + void iSetSourceNamespace(const wxString &s) + { + sourceNamespace = s; + } + wxString GetTargetNamespace() const + { + return targetNamespace; + } + void iSetTargetNamespace(const wxString &s) + { + targetNamespace = s; + } + OID GetSourceTypeOid() const + { + return sourceTypeOid; + } + void iSetSourceTypeOid(const OID o) + { + sourceTypeOid = o; + } + OID GetTargetTypeOid() const + { + return targetTypeOid; + } + void iSetTargetTypeOid(const OID o) + { + targetTypeOid = o; + } + wxString GetCastFunction() const + { + return castFunction; + } + void iSetCastFunction(const wxString &s) + { + castFunction = s; + } + wxString GetCastNamespace() const + { + return castNamespace; + } + void iSetCastNamespace(const wxString &s) + { + castNamespace = s; + } + + wxString GetCastContext() const + { + return castContext; + } + void iSetCastContext(const wxString &s) + { + castContext = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString sourceType, sourceNamespace, targetType, targetNamespace, + castFunction, castContext, castNamespace; + OID sourceTypeOid, targetTypeOid; +}; + +class pgCastCollection : public pgDatabaseObjCollection +{ +public: + pgCastCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCatalogObject.h b/include/schema/pgCatalogObject.h new file mode 100644 index 0000000..84db5cd --- /dev/null +++ b/include/schema/pgCatalogObject.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCatalogObject.h - EnterpriseDB catalog class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCATALOGOBJECT_H +#define PGCATALOGOBJECT_H + +#include "pgSchema.h" + +class pgCatalogObjectFactory : public pgSchemaObjFactory +{ +public: + pgCatalogObjectFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) + { + return NULL; + }; + virtual pgObject *CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgCatalogObjectFactory catalogObjectFactory; + + +// Class declarations +class pgCatalogObject : public pgSchemaObject +{ +public: + pgCatalogObject(pgSchema *newSchema, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + +private: + +}; + +class pgCatalogObjectCollection : public pgSchemaObjCollection +{ +public: + pgCatalogObjectCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCheck.h b/include/schema/pgCheck.h new file mode 100644 index 0000000..57b0f6a --- /dev/null +++ b/include/schema/pgCheck.h @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCheck.h PostgreSQL Check +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCHECK_H +#define PGCHECK_H + +// App headers +#include "pgTable.h" +#include "pgConstraints.h" + + + +class pgCheckFactory : public pgSchemaObjFactory +{ +public: + pgCheckFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgCheckFactory checkFactory; + + +class pgCheck : public pgSchemaObject +{ +public: + pgCheck(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgCheck(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetObjectName() const + { + return objectName; + } + void iSetObjectName(const wxString &s) + { + objectName = s; + } + wxString GetObjectSchema() const + { + return objectSchema; + } + void iSetObjectSchema(const wxString &s) + { + objectSchema = s; + } + wxString GetObjectKind() const + { + return objectKind; + } + void iSetObjectKind(const wxString &s) + { + objectKind = s; + } + wxString GetDefinition() const + { + return definition; + } + void iSetDefinition(const wxString &s) + { + definition = s; + } + bool GetNoInherit() const + { + return noinherit; + } + void iSetNoInherit(const bool b) + { + noinherit = b; + } + bool GetValid() const + { + return valid; + } + void iSetValid(const bool b) + { + valid = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetConstraint(); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + void Validate(frmMain *form); + +private: + wxString definition, objectKind, objectName, objectSchema; + bool noinherit, valid; +}; + +class pgCheckCollection : public pgSchemaObjCollection +{ +public: + pgCheckCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class validateCheckFactory : public contextActionFactory +{ +public: + validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgCollation.h b/include/schema/pgCollation.h new file mode 100644 index 0000000..40593cb --- /dev/null +++ b/include/schema/pgCollation.h @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollation.h PostgreSQL Collation +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCOLLATION_H +#define PGCOLLATION_H + +#include "pgSchema.h" + +class pgCollection; + +class pgCollationFactory : public pgSchemaObjFactory +{ +public: + pgCollationFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgCollationFactory collationFactory; + + +class pgCollation : public pgSchemaObject +{ +public: + pgCollation(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgCollation(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetLcCollate() const + { + return lccollate; + } + void iSetLcCollate(const wxString &s) + { + lccollate = s; + } + wxString GetLcCtype() const + { + return lcctype; + } + void iSetLcCtype(const wxString &s) + { + lcctype = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString lccollate, lcctype; +}; + +class pgCollationCollection : public pgSchemaObjCollection +{ +public: + pgCollationCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgCollection.h b/include/schema/pgCollection.h new file mode 100644 index 0000000..58a31b2 --- /dev/null +++ b/include/schema/pgCollection.h @@ -0,0 +1,111 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollection.h - Simple object for use with 'collection' nodes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCOLLECTION_H +#define PGCOLLECTION_H + +// App headers +#include "pgAdmin3.h" +#include "pgObject.h" + +class pgServer; +class pgDatabase; +class pgaJob; +class pgSchema; +class pgForeignDataWrapper; +class pgForeignServer; +class pgUserMapping; +class pgproJob; + +// Class declarations +class pgCollection : public pgObject +{ +public: + pgCollection(pgaFactory *factory); + + virtual bool IsCollection() const + { + return true; + } + bool IsCollectionForType(const int type); + bool IsCollectionFor(pgObject *obj); + + pgServer *GetServer() const + { + return server; + } + pgDatabase *GetDatabase() const + { + return database; + } + pgSchema *GetSchema() const + { + return schema; + } + pgForeignDataWrapper *GetForeignDataWrapper() const + { + return fdw; + } + pgForeignServer *GetForeignServer() const + { + return fsrv; + } + pgUserMapping *GetUserMapping() const + { + return um; + } + pgaJob *GetJob() const + { + return job; + } + pgproJob *GetproJob() const + { + return projob; + } + + int GetIconId(); + pgaFactory *GetItemFactory() + { + if (factory) return ((pgaCollectionFactory *)factory)->GetItemFactory(); + else return NULL; + } + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowList(const wxString &name, ctlTree *browser, ctlListView *properties); + void ShowList(ctlTree *browser, ctlListView *properties); + void UpdateChildCount(ctlTree *browser, int substract = 0); + pgObject *FindChild(ctlTree *browser, const int index); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +protected: + pgServer *server; + pgDatabase *database; + pgSchema *schema; + pgaJob *job; + pgForeignDataWrapper *fdw; + pgForeignServer *fsrv; + pgUserMapping *um; + pgproJob *projob; +}; + + +#endif diff --git a/include/schema/pgColumn.h b/include/schema/pgColumn.h new file mode 100644 index 0000000..103b921 --- /dev/null +++ b/include/schema/pgColumn.h @@ -0,0 +1,334 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgColumn.h PostgreSQL Column +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCOLUMN_H +#define PGCOLUMN_H + +// App headers +#include "pgTable.h" + +WX_DECLARE_STRING_HASH_MAP(wxString, inheritHashMap); + +class pgCollection; + +class pgColumnFactory : public pgTableObjFactory +{ +public: + pgColumnFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgColumnFactory columnFactory; + +class pgColumn : public pgTableObject +{ +public: + pgColumn(pgTable *newTable, const wxString &newName = wxT("")); + ~pgColumn(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + + wxString GetDefinition(); + + bool IsReferenced(); + + wxString GetRawTypename() const + { + return rawTypename; + } + void iSetRawTypename(const wxString &s) + { + rawTypename = s; + } + wxString GetVarTypename() const + { + return varTypename; + } + void iSetVarTypename(const wxString &s) + { + varTypename = s; + } + wxString GetQuotedTypename() const + { + return quotedTypename; + } + void iSetQuotedTypename(const wxString &s) + { + quotedTypename = s; + } + wxString GetDefault() const + { + return defaultVal; + } + void iSetDefault(const wxString &s) + { + defaultVal = s; + } + long GetColNumber() const + { + return colNumber; + } + void iSetColNumber(const long l) + { + colNumber = l; + } + long GetLength() const + { + return length; + } + void iSetLength(const long l) + { + length = l; + } + long GetPrecision() const + { + return precision; + } + void iSetPrecision(const long l) + { + precision = l; + } + long GetStatistics() const + { + return statistics; + } + void iSetStatistics(const long l) + { + statistics = l; + } + bool GetIsPK() const + { + return isPK; + } + bool GetIsFK() const + { + return isFK; + } + bool GetNotNull() const + { + return notNull; + } + void iSetNotNull(const bool b) + { + notNull = b; + } + bool GetIsArray() const + { + return isArray; + } + void iSetIsArray(const bool b) + { + isArray = b; + } + long GetTyplen() const + { + return typlen; + } + void iSetTyplen(const long l) + { + typlen = l; + } + long GetTypmod() const + { + return typmod; + } + void iSetTypmod(const long l) + { + typmod = l; + } + wxString GetTableName() const + { + return tableName; + } + void iSetTableName(const wxString &s) + { + tableName = s; + } + wxString GetQuotedFullTable() const + { + return quotedFullTable; + } + void iSetQuotedFullTable(const wxString &s) + { + quotedFullTable = s; + } + wxString GetDefaultStorage() const + { + return defaultStorage; + } + void iSetDefaultStorage(const wxString &s) + { + defaultStorage = s; + } + wxString GetStorage() const + { + return storage; + } + void iSetStorage(const wxString &s) + { + storage = s; + } + long GetInheritedCount() const + { + return inheritedCount; + } + void iSetInheritedCount(const long l) + { + inheritedCount = l; + } + wxString GetInheritedTableName() const + { + return inheritedTableName; + } + void iSetInheritedTableName(const wxString &s) + { + inheritedTableName = s; + } + bool GetIsLocal() const + { + return isLocal; + } + void iSetIsLocal(const bool b) + { + isLocal = b; + } + OID GetAttTypId() const + { + return attTypId; + } + void iSetAttTypId(const OID o) + { + attTypId = o; + } + long GetAttstattarget() const + { + return attstattarget; + } + void iSetAttstattarget(const long l) + { + attstattarget = l; + } + wxString GetSerialSequence() const + { + return serialSequence; + } + void iSetSerialSequence(const wxString &s) + { + serialSequence = s; + } + wxString GetSerialSchema() const + { + return serialSchema; + } + void iSetSerialSchema(const wxString &s) + { + serialSchema = s; + } + wxString GetGenerated() const + { + return generated; + } + void iSetGenerated(const wxString &s) + { + generated = s; + } + wxString GetIdentity() const + { + return identity; + } + void iSetIdentity(const wxString &s) + { + identity = s; + } + void iSetPkCols(const wxString &s) + { + pkCols = s; + } + void iSetIsFK(const bool b) + { + isFK = b; + } + wxArrayString &GetVariables() + { + return variables; + } + wxString GetCollation() const + { + return collation; + } + void iSetCollation(const wxString &s) + { + collation = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool GetSystemObject() const + { + return colNumber < 0; + } + wxString GetSql(ctlTree *browser); + wxString GetCommentSql(); + wxString GetStorageSql(); + wxString GetAttstattargetSql(); + wxString GetVariablesSql(); + wxString GetPrivileges(); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + + virtual bool CanDrop() + { + return inheritedCount == 0 && pgSchemaObject::CanDrop() && GetSchema()->GetMetaType() != PGM_CATALOG && GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != GP_EXTTABLE; + } + virtual bool CanCreate() + { + return GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != GP_EXTTABLE && GetSchema()->GetMetaType() != PGM_CATALOG; + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString varTypename, quotedTypename, defaultVal, tableName, quotedFullTable, defaultStorage, storage, rawTypename; + wxString serialSequence, serialSchema, pkCols, inheritedTableName, collation, generated, identity; + long colNumber, length, precision, statistics, attstattarget; + long typlen, typmod, inheritedCount; + bool isPK, isFK, notNull, isArray, isLocal; + OID attTypId; + int isReferenced; + wxArrayString variables; +}; + +class pgColumnCollection : public pgTableObjCollection +{ +public: + pgColumnCollection(pgaFactory *factory, pgTable *tbl); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgConstraints.h b/include/schema/pgConstraints.h new file mode 100644 index 0000000..c38b2dc --- /dev/null +++ b/include/schema/pgConstraints.h @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConstraints.h - Constraint collection +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __CONSTRAINTS_H +#define __CONSTRAINTS_H + +#include "pgTable.h" +#include "pgDomain.h" + + +class pgConstraintCollection : public pgSchemaObjCollection +{ +public: + pgConstraintCollection(pgaFactory *factory, pgSchema *schema); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + bool CanCreate() + { + return true; + } + wxMenu *GetNewMenu(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane); + wxString GetTranslatedMessage(int kindOfMessage) const; + + pgTable *table; + pgDomain *domain; +}; + + +class pgConstraintFactory : public pgSchemaObjFactory +{ +public: + pgConstraintFactory(); + virtual dlgProperty *CreateDialog(class frmMain *, class pgObject *, class pgObject *) + { + return 0; + } + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgConstraintFactory constraintFactory; +extern pgaCollectionFactory constraintCollectionFactory; + +#endif diff --git a/include/schema/pgConversion.h b/include/schema/pgConversion.h new file mode 100644 index 0000000..a6e3011 --- /dev/null +++ b/include/schema/pgConversion.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConversion.h PostgreSQL Conversion +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGCONVERSION_H +#define PGCONVERSION_H + +#include "pgSchema.h" + +class pgCollection; + +class pgConversionFactory : public pgSchemaObjFactory +{ +public: + pgConversionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgConversionFactory conversionFactory; + + +class pgConversion : public pgSchemaObject +{ +public: + pgConversion(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgConversion(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetProc() const + { + return proc; + } + void iSetProc(const wxString &s) + { + proc = s; + } + wxString GetProcNamespace() const + { + return procNamespace; + } + void iSetProcNamespace(const wxString &s) + { + procNamespace = s; + } + wxString GetForEncoding() const + { + return forEncoding; + } + void iSetForEncoding(const wxString &s) + { + forEncoding = s; + } + wxString GetToEncoding() const + { + return toEncoding; + } + void iSetToEncoding(const wxString &s) + { + toEncoding = s; + } + bool GetDefaultConversion() const + { + return defaultConversion; + } + void iSetDefaultConversion(const bool b) + { + defaultConversion = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString proc, procNamespace, forEncoding, toEncoding; + bool defaultConversion; +}; + +class pgConversionCollection : public pgSchemaObjCollection +{ +public: + pgConversionCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgDatabase.h b/include/schema/pgDatabase.h new file mode 100644 index 0000000..dfc9fda --- /dev/null +++ b/include/schema/pgDatabase.h @@ -0,0 +1,360 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatabase.h - PostgreSQL Database +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGDATABASE_H +#define PGDATABASE_H + +#include "pgServer.h" + +class pgDatabaseFactory : public pgServerObjFactory +{ +public: + pgDatabaseFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return WantSmallIcon() ? smallClosedId : closedId; + } +protected: + int closedId, smallClosedId; +}; + +extern pgDatabaseFactory databaseFactory; + + +// Class declarations +class pgDatabase : public pgServerObject +{ +public: + pgDatabase(const wxString &newName = wxT("")); + ~pgDatabase(); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + static wxString GetDefaultPrivileges(const wxChar &cType, wxString strDefPrivs, const wxString &strSchema); + + pgDatabase *GetDatabase() const + { + return (pgDatabase *)this; + } + bool BackendMinimumVersion(int major, int minor) + { + return connection()->BackendMinimumVersion(major, minor); + } + bool BackendMinimumVersion(int major, int minor, int patch) + { + return connection()->BackendMinimumVersion(major, minor, patch); + } + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowHint(frmMain *form, bool force); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql, bool reportError = true); + void UpdateDefaultSchema(); + + pgConn *CreateConn(const wxString &applicationname) + { + return server->CreateConn(GetName(), GetOid(), applicationname); + } + + wxString GetPrettyOption() const + { + return prettyOption; + } + + bool GetCreatePrivilege() const + { + return createPrivilege; + } + void iSetCreatePrivilege(const bool b) + { + createPrivilege = b; + } + + // Default Privileges on ALL + wxString GetDefPrivsOnTables() + { + return m_defPrivsOnTables; + } + wxString GetDefPrivsOnSequences() + { + return m_defPrivsOnSeqs; + } + wxString GetDefPrivsOnFunctions() + { + return m_defPrivsOnFuncs; + } + wxString GetDefPrivsOnTypes() + { + return m_defPrivsOnTypes; + } + + wxString GetPath() const + { + return path; + }; + void iSetPath(const wxString &newVal) + { + path = newVal; + } + wxString GetTablespace() const + { + return tablespace; + }; + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + }; + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxString GetDefaultTablespace() const + { + return defaultTablespace; + }; + void iSetDefaultTablespace(const wxString &newVal) + { + defaultTablespace = newVal; + } + wxString GetEncoding() const + { + return encoding; + } + void iSetEncoding(const wxString &newVal) + { + encoding = newVal; + } + wxString GetSchemaRestriction() + { + return schemaRestriction; + } + void iSetSchemaRestriction(const wxString &s) + { + schemaRestriction = s; + } + wxString GetCollate() const + { + return collate; + } + void iSetCollate( const wxString &newVal) + { + collate = newVal; + } + wxString GetCType() const + { + return ctype; + } + void iSetCType( const wxString &newVal) + { + ctype = newVal; + } + long GetConnectionLimit() + { + return connectionLimit; + } + void iSetConnectionLimit(long newVal) + { + connectionLimit = newVal; + } + + wxArrayString &GetVariables() + { + return variables; + } + bool GetAllowConnections() const + { + return allowConnections; + } + void iSetAllowConnections(bool newVal) + { + allowConnections = newVal; + } + wxString GetSearchPath() const + { + return searchPath; + } + wxString GetSchemaPrefix(const wxString &schemaname) const; + wxString GetQuotedSchemaPrefix(const wxString &schemaname) const; + wxString GetDefaultSchema() + { + return defaultSchema; + }; + bool GetConnected() + { + return connected; + } + bool GetSystemObject() const; + long GetMissingFKs() const + { + return missingFKs; + } + wxArrayString GetSlonyClusters(ctlTree *browser); + + + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanCreate(); + bool CanMaintenance() + { + return connected; + } + bool CanBackup() + { + return connected; + } + bool CanRestore() + { + return connected; + } + bool GetCanHint(); + bool RequireDropConfirm() + { + return true; + } + pgConn *connection(); + int Connect(); + void Disconnect(); + void CheckAlive(); + void AppendSchemaChange(const wxString &sql); + wxString GetSchemaChanges() + { + return schemaChanges; + } + void ClearSchemaChanges() + { + schemaChanges = wxEmptyString; + } + + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool CanDebugPlpgsql(); + bool CanDebugEdbspl(); + +private: + pgConn *conn; + bool connected; + bool useServerConnection; + wxString searchPath, path, tablespace, defaultTablespace, encoding, collate, ctype; + wxString prettyOption, defaultSchema; + bool allowConnections, createPrivilege; + long missingFKs; + long connectionLimit; + wxArrayString variables; + + wxString schemaChanges; + wxString schemaRestriction; + wxString m_defPrivsOnTables, m_defPrivsOnSeqs, m_defPrivsOnFuncs, m_defPrivsOnTypes; + + int canDebugPlpgsql, canDebugEdbspl; + + OID tablespaceOid; +}; + +class pgDatabaseCollection : public pgServerObjCollection +{ +public: + pgDatabaseCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + + +//////////////////////////////////////////////// + +class pgDatabaseObjFactory : public pgServerObjFactory +{ +public: + pgDatabaseObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgServerObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class disconnectDatabaseFactory : public contextActionFactory +{ +public: + disconnectDatabaseFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +// Object that lives in a database +class pgDatabaseObject : public pgObject +{ +public: + pgDatabaseObject(pgaFactory &factory, const wxString &newName = wxEmptyString) : pgObject(factory, newName) {} + pgDatabaseObject(int newType, const wxString &newName) : pgObject(newType, newName) {} + + void iSetDatabase(pgDatabase *newDatabase) + { + database = newDatabase; + } + pgDatabase *GetDatabase() const + { + return database; + } + pgServer *GetServer() const; + + void DisplayStatistics(ctlListView *statistics, const wxString &query); + + // compiles a prefix from the schema name with '.', if necessary + wxString GetSchemaPrefix(const wxString &schemaname) const; + wxString GetQuotedSchemaPrefix(const wxString &schemaname) const; + + bool CanDrop(); + bool CanEdit() + { + return true; + } + bool CanCreate(); + +protected: + pgDatabase *database; +}; + + +// collection of pgDatabaseObject +class pgDatabaseObjCollection : public pgCollection +{ +public: + pgDatabaseObjCollection(pgaFactory *factory, pgDatabase *db); + bool CanCreate(); +}; + + + +#endif diff --git a/include/schema/pgDatatype.h b/include/schema/pgDatatype.h new file mode 100644 index 0000000..78efa4a --- /dev/null +++ b/include/schema/pgDatatype.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatatype.h - PostgreSQL Datatypes +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __DATATYPE_INC +#define __DATATYPE_INC + +#include + +// App headers + +#include "db/pgSet.h" +#include "db/pgConn.h" + +class pgDatabase; + +class pgDatatype +{ +public: + pgDatatype(const wxString &nsp, const wxString &typname, bool isduplicate, long numdims = 0, long typmod = -1); + wxString Name() const + { + return name; + }; + wxString LengthString() const + { + return length; + } + wxString Array() const + { + return array; + } + wxString FullName() const; + wxString QuotedFullName() const; + wxString GetSchemaPrefix(pgDatabase *db) const; + wxString GetQuotedSchemaPrefix(pgDatabase *db) const; + long Length() const + { + return len; + } + long Precision() const + { + return prec; + } + static long GetTypmod(const wxString &name, const wxString &len, const wxString &prec); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString schema; + wxString name; + wxString length; + wxString array; + long len, prec; + bool needSchema; +}; + + +class DatatypeReader +{ +public: + DatatypeReader(pgDatabase *db, bool withDomains = true, bool addSerials = false); + DatatypeReader(pgDatabase *db, const wxString &condition, bool addSerials = false); + ~DatatypeReader() + { + if (set) delete set; + } + bool HasMore() const + { + return set && !set->Eof(); + } + void MoveNext() + { + if (set) set->MoveNext(); + } + + bool IsDomain() const; + bool IsVarlen() const; + bool MaySpecifyLength() const; + bool MaySpecifyPrecision() const; + pgDatatype GetDatatype() const; + wxString GetTypename() const; + wxString GetSchema() const; + wxString GetSchemaPrefix() const; + wxString GetQuotedSchemaPrefix() const; + wxString GetOidStr() const; + OID GetOid() const; + +private: + pgSet *set; + pgDatabase *database; + void init(pgDatabase *db, const wxString &condition, bool addSerials = false); +}; + +#endif diff --git a/include/schema/pgDomain.h b/include/schema/pgDomain.h new file mode 100644 index 0000000..e8a5f31 --- /dev/null +++ b/include/schema/pgDomain.h @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDomain.h PostgreSQL Domain +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGDOMAIN_H +#define PGDOMAIN_H + +#include "pgSchema.h" + +class pgCollection; + +class pgDomainFactory : public pgSchemaObjFactory +{ +public: + pgDomainFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgDomainFactory domainFactory; + + +class pgDomain : public pgSchemaObject +{ +public: + pgDomain(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgDomain(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetBasetype() const + { + return basetype; + } + void iSetBasetype(const wxString &s) + { + basetype = s; + } + wxString GetQuotedBasetype() const + { + return quotedBasetype; + } + void iSetQuotedBasetype(const wxString &s) + { + quotedBasetype = s; + } + wxString GetCollation() const + { + return collation; + } + void iSetCollation(const wxString &s) + { + collation = s; + } + wxString GetQuotedCollation() const + { + return quotedCollation; + } + void iSetQuotedCollation(const wxString &s) + { + quotedCollation = s; + } + void iSetIsDup(bool b) + { + isDup = b; + } + long GetLength() const + { + return length; + } + void iSetLength(long l) + { + length = l; + } + long GetPrecision() const + { + return precision; + } + void iSetPrecision(long l) + { + precision = l; + } + wxString GetCheck() const + { + return check; + } + void iSetCheck(const wxString &s) + { + check = s; + } + wxString GetDefault() const + { + return defaultVal; + } + void iSetDefault(const wxString &s) + { + defaultVal = s; + } + bool GetNotNull() const + { + return notNull; + } + void iSetNotNull(bool b) + { + notNull = b; + } + long GetDimensions() const + { + return dimensions; + } + void iSetDimensions(long l) + { + dimensions = l; + } + wxString GetDelimiter() const + { + return delimiter; + } + void iSetDelimiter(const wxString &s) + { + delimiter = s; + } + OID GetBasetypeOid() const + { + return basetypeOid; + } + void iSetBasetypeOid(OID d) + { + basetypeOid = d; + } + OID GetCollationOid() const + { + return collationOid; + } + void iSetCollationOid(OID d) + { + collationOid = d; + } + long GetTyplen() const + { + return typlen; + } + void iSetTyplen(const long l) + { + typlen = l; + } + long GetTypmod() const + { + return typmod; + } + void iSetTypmod(const long l) + { + typmod = l; + } + bool GetValid() const + { + return constraintvalid; + } + void iSetValid(const bool b) + { + constraintvalid = b; + } + wxString GetCheckConstraintName() const + { + return checkconstraintname; + } + void iSetCheckConstraintName(const wxString &s) + { + checkconstraintname = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxMenu *GetNewMenu(); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + void Validate(frmMain *form); + +private: + wxString basetype, quotedBasetype, defaultVal, delimiter, check, collation, quotedCollation, checkconstraintname; + long length, precision, dimensions; + long typlen, typmod; + bool notNull, isDup, constraintvalid; + OID basetypeOid, collationOid; +}; + +class pgDomainCollection : public pgSchemaObjCollection +{ +public: + pgDomainCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class validateDomainCheckFactory : public contextActionFactory +{ +public: + validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgEventTrigger.h b/include/schema/pgEventTrigger.h new file mode 100644 index 0000000..2293ea4 --- /dev/null +++ b/include/schema/pgEventTrigger.h @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgEventTrigger.h PostgreSQL Event Trigger +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGEVENTTRIGGER_H +#define PGEVENTTRIGGER_H + +#include "pgDatabase.h" + +class pgCollection; +class pgFunction; + +class pgEventTriggerFactory : public pgDatabaseObjFactory +{ +public: + pgEventTriggerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + virtual ~pgEventTriggerFactory() {}; + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; + +extern pgEventTriggerFactory eventTriggerFactory; + +class pgEventTrigger : public pgDatabaseObject +{ +public: + pgEventTrigger(const wxString &newName = wxT("")); + ~pgEventTrigger(); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool IsUpToDate(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + int GetIconId(); + + wxString GetFunction() const + { + return function; + } + void iSetFunction(const wxString &s) + { + function = s ; + } + wxString GetWhen() const + { + return when; + } + void iSetWhen(const wxString &s) + { + when = s; + } + OID GetFunctionOid() const + { + return functionOid; + } + void iSetFunctionOid(const OID d) + { + functionOid = d; + } + OID GetSchemaOid() const + { + return schemaOid; + } + void iSetSchemaOid(const OID d) + { + schemaOid = d; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetLanguage() const + { + return language; + } + void iSetLanguage(const wxString &s) + { + language = s; + } + wxString GetEventName() const + { + return eventName; + } + wxString GetEnableStatus() const + { + return enableStatus; + } + void iSetEnableStatus(const wxString &s) + { + enableStatus = s; + } + void iSetEventName(const wxString &s) + { + eventName = s; + } + + bool GetEnabled() const + { + return enabled; + } + void iSetEnabled(const bool b) + { + enabled = b; + } + void SetEnabled(ctlTree *browser, const bool b); + void SetDirty(); + +private: + wxString function, when, language, source, eventName, enableStatus; + OID functionOid, schemaOid; + bool enabled; + pgFunction *eventTriggerFunction; + pgSchema *eventTriggerFunctionSchema; +}; + +class pgEventTriggerCollection : public pgDatabaseObjCollection +{ +public: + pgEventTriggerCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class enabledisableEventTriggerFactory : public contextActionFactory +{ +public: + enabledisableEventTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +#endif \ No newline at end of file diff --git a/include/schema/pgExtension.h b/include/schema/pgExtension.h new file mode 100644 index 0000000..8f2a649 --- /dev/null +++ b/include/schema/pgExtension.h @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgExtension.h PostgreSQL Extension +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGEXTENSION_H +#define PGEXTENSION_H + +#include "pgDatabase.h" + +class pgCollection; +class pgExtensionFactory : public pgDatabaseObjFactory +{ +public: + pgExtensionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgExtensionFactory extensionFactory; + +class pgExtension : public pgDatabaseObject +{ +public: + pgExtension(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + + wxString GetSchemaStr() const + { + return schema; + } + void iSetSchemaStr(const wxString &s) + { + schema = s; + } + wxString GetVersion() const + { + return version; + } + void iSetVersion(const wxString &s) + { + version = s; + } + bool GetIsRelocatable() const + { + return isrelocatable; + } + void iSetIsRelocatable(const bool b) + { + isrelocatable = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +private: + wxString schema, version; + bool isrelocatable; +}; + +class pgExtensionCollection : public pgDatabaseObjCollection +{ +public: + pgExtensionCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgForeignDataWrapper.h b/include/schema/pgForeignDataWrapper.h new file mode 100644 index 0000000..ebc59ce --- /dev/null +++ b/include/schema/pgForeignDataWrapper.h @@ -0,0 +1,152 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignDataWrapper.h PostgreSQL Foreign Data Wrapper +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNDATAWRAPPER_H +#define PGFOREIGNDATAWRAPPER_H + +#include "pgDatabase.h" + +class pgCollection; +class pgForeignDataWrapperFactory : public pgDatabaseObjFactory +{ +public: + pgForeignDataWrapperFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgForeignDataWrapperFactory foreignDataWrapperFactory; + +class pgForeignDataWrapper : public pgDatabaseObject +{ +public: + pgForeignDataWrapper(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + wxMenu *GetNewMenu(); + + wxString GetHandlerProc() const + { + return handlerProc; + } + void iSetHandlerProc(const wxString &s) + { + handlerProc = s; + } + wxString GetValidatorProc() const + { + return validatorProc; + } + void iSetValidatorProc(const wxString &s) + { + validatorProc = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString handlerProc, validatorProc, options; +}; + +class pgForeignDataWrapperObjFactory : public pgDatabaseObjFactory +{ +public: + pgForeignDataWrapperObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +class pgForeignDataWrapperCollection : public pgDatabaseObjCollection +{ +public: + pgForeignDataWrapperCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +// Object that lives in a foreign data wrapper +class pgForeignDataWrapperObject : public pgDatabaseObject +{ +public: + pgForeignDataWrapperObject(pgForeignDataWrapper *newForeignDataWrapper, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgDatabaseObject(factory, newName) + { + SetForeignDataWrapper(newForeignDataWrapper); + } + pgForeignDataWrapperObject(pgForeignDataWrapper *newForeignDataWrapper, int newType, const wxString &newName = wxT("")) : pgDatabaseObject(newType, newName) + { + SetForeignDataWrapper(newForeignDataWrapper); + } + + bool CanDrop(); + bool CanEdit() + { + return true; + } + bool CanCreate(); + + void SetForeignDataWrapper(pgForeignDataWrapper *newForeignDataWrapper); + virtual pgForeignDataWrapper *GetForeignDataWrapper() const + { + return fdw; + } + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql); + + +protected: + virtual void SetContextInfo(frmMain *form); + + pgForeignDataWrapper *fdw; +}; + + + +// collection of pgForeignDataWrapperObject +class pgForeignDataWrapperObjCollection : public pgCollection +{ +public: + pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *newfdw); + wxString GetTranslatedMessage(int kindOfMessage) const; + virtual bool CanCreate(); +}; + +#endif diff --git a/include/schema/pgForeignKey.h b/include/schema/pgForeignKey.h new file mode 100644 index 0000000..a55ca51 --- /dev/null +++ b/include/schema/pgForeignKey.h @@ -0,0 +1,225 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignKey.h PostgreSQL ForeignKey +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNKEY_H +#define PGFOREIGNKEY_H + +#include "pgIndex.h" + +class pgForeignKeyFactory : public pgSchemaObjFactory +{ +public: + pgForeignKeyFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgForeignKeyFactory foreignKeyFactory; + +class pgForeignKey : public pgSchemaObject +{ +public: + pgForeignKey(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgForeignKey(); + + int GetIconId(); + + wxString GetDefinition(); + wxString GetFullName(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetOnUpdate() const + { + return onUpdate; + } + void iSetOnUpdate(const wxString &s) + { + onUpdate = s; + } + wxString GetOnDelete() const + { + return onDelete; + } + void iSetOnDelete(const wxString &s) + { + onDelete = s; + } + + wxString GetFkTable() const + { + return fkTable; + } + void iSetFkTable(const wxString &s) + { + fkTable = s; + } + wxString GetFkSchema() const + { + return fkSchema; + } + void iSetFkSchema(const wxString &s) + { + fkSchema = s; + } + wxString GetReferences() const + { + return references; + } + void iSetReferences(const wxString &s) + { + references = s; + } + wxString GetRefSchema() const + { + return refSchema; + } + void iSetRefSchema(const wxString &s) + { + refSchema = s; + } + wxString GetConkey() const + { + return conkey; + } + void iSetConkey(const wxString &s) + { + conkey = s; + } + wxString GetConfkey() const + { + return confkey; + } + void iSetConfkey(const wxString &s) + { + confkey = s; + } + bool GetDeferrable() const + { + return deferrable; + } + void iSetDeferrable(const bool b) + { + deferrable = b; + } + bool GetDeferred() const + { + return deferred; + } + void iSetDeferred(const bool b) + { + deferred = b; + } + wxString GetMatch() const + { + return match; + } + void iSetMatch(const wxString &s) + { + match = s; + } + bool GetValid() const + { + return valid; + } + void iSetValid(const bool b) + { + valid = b; + } + wxString GetRelTableOidStr() const + { + return NumToStr(relTableOid) + wxT("::oid"); + } + OID GetRelTableOid() const + { + return relTableOid; + } + void iSetRelTableOid(const OID d) + { + relTableOid = d; + } + + wxString GetFkColumns() const + { + return fkColumns; + } + wxString GetRefColumns() const + { + return refColumns; + } + wxString GetQuotedFkColumns() const + { + return quotedFkColumns; + } + wxString GetQuotedRefColumns() const + { + return quotedRefColumns; + } + wxString GetCoveringIndex() const + { + return coveringIndex; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetConstraint(); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + void Validate(frmMain *form); + +private: + wxString onUpdate, onDelete, conkey, confkey, + fkTable, fkSchema, references, refSchema; + wxString fkColumns, refColumns, quotedFkColumns, quotedRefColumns, coveringIndex, match; + bool deferrable, deferred, valid; + OID relTableOid; +}; + +class pgForeignKeyCollection : public pgSchemaObjCollection +{ +public: + pgForeignKeyCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class validateForeignKeyFactory : public contextActionFactory +{ +public: + validateForeignKeyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgForeignServer.h b/include/schema/pgForeignServer.h new file mode 100644 index 0000000..52c3571 --- /dev/null +++ b/include/schema/pgForeignServer.h @@ -0,0 +1,145 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignServer.h PostgreSQL Foreign Server +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNSERVER_H +#define PGFOREIGNSERVER_H + +#include "pgForeignDataWrapper.h" + +class pgCollection; +class pgForeignServerFactory : public pgForeignDataWrapperObjFactory +{ +public: + pgForeignServerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgForeignServerFactory foreignServerFactory; + + +class pgForeignServer : public pgForeignDataWrapperObject +{ +public: + pgForeignServer(pgForeignDataWrapper *newForeignDataWrapper, const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + wxMenu *GetNewMenu(); + bool CanDropCascaded() + { + return true; + } + bool CanCreate() + { + return true; + } + wxString GetType() const + { + return type; + } + void iSetType(const wxString &s) + { + type = s; + } + wxString GetVersion() const + { + return version; + } + void iSetVersion(const wxString &s) + { + version = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString type, version, options; +}; + + +class pgForeignServerObjFactory : public pgForeignDataWrapperObjFactory +{ +public: + pgForeignServerObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgForeignDataWrapperObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +// Object that lives in a foreign server +class pgForeignServerObject : public pgForeignDataWrapperObject +{ +public: + pgForeignServerObject(pgForeignServer *newForeignServer, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgForeignDataWrapperObject(newForeignServer->GetForeignDataWrapper(), factory, newName) + { + SetForeignServer(newForeignServer); + } + pgForeignServerObject(pgForeignServer *newForeignServer, int newType, const wxString &newName = wxT("")) : pgForeignDataWrapperObject(newForeignServer->GetForeignDataWrapper(), newType, newName) + { + SetForeignServer(newForeignServer); + } + + bool CanDrop(); + bool CanEdit() + { + return true; + } + bool CanCreate(); + + void SetForeignServer(pgForeignServer *newForeignServer); + virtual pgForeignServer *GetForeignServer() const + { + return srv; + } + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql); + + +protected: + virtual void SetContextInfo(frmMain *form); + + pgForeignServer *srv; +}; + + +class pgForeignServerObjCollection : public pgCollection +{ +public: + pgForeignServerObjCollection(pgaFactory *factory, pgForeignServer *newsrv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgForeignTable.h b/include/schema/pgForeignTable.h new file mode 100644 index 0000000..26210aa --- /dev/null +++ b/include/schema/pgForeignTable.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignTable.h PostgreSQL Foreign Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFOREIGNTABLE_H +#define PGFOREIGNTABLE_H + +#include "pgSchema.h" + +class pgForeignTableFactory : public pgSchemaObjFactory +{ +public: + pgForeignTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgForeignTableFactory foreignTableFactory; + +class pgForeignTable : public pgSchemaObject +{ +public: + pgForeignTable(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgForeignTable(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + wxString GetForeignServer() const + { + return foreignserver; + } + void iSetForeignServer(const wxString &s) + { + foreignserver = s; + } + const wxArrayString &GetOptionsArray() + { + return optionsArray; + } + wxString GetOptionsList() const + { + return options; + } + void iSetOptions(const wxString &s); + const wxArrayString &GetTypesArray() + { + return typesArray; + } + wxString GetTypesList() const + { + return typesList; + } + wxString GetQuotedTypesList() const + { + return quotedTypesList; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool CanView() + { + return true; + } + +private: + wxString foreignserver, options, typesList, quotedTypesList; + wxArrayString typesArray; + wxArrayString optionsArray; +}; + +class pgForeignTableCollection : public pgSchemaObjCollection +{ +public: + pgForeignTableCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgFunction.h b/include/schema/pgFunction.h new file mode 100644 index 0000000..31f3c08 --- /dev/null +++ b/include/schema/pgFunction.h @@ -0,0 +1,355 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgFunction.h PostgreSQL Function +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGFUNCTION_H +#define PGFUNCTION_H + +#include "pgSchema.h" + +class pgFunction; + +class pgFunctionFactory : public pgSchemaObjFactory +{ +public: + pgFunctionFactory(const wxChar *tn = 0, const wxChar *ns = 0, const wxChar *nls = 0, wxImage *img = 0); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + pgFunction *AppendFunctions(pgObject *obj, pgSchema *schema, ctlTree *browser, const wxString &restriction); +}; + + +extern pgFunctionFactory functionFactory; + +class pgFunction : public pgSchemaObject +{ +public: + pgFunction(pgSchema *newSchema, const wxString &newName = wxT("")); + pgFunction(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + void ShowStatistics(frmMain *form, ctlListView *statistics); + + virtual bool GetIsProcedure() const + { + return false; + } + + wxString GetFullName(); + wxString GetArgListWithNames(bool multiline = false); + wxString GetArgSigList(const bool forScript = false); + + wxArrayString &GetArgNamesArray() + { + return argNamesArray; + } + void iAddArgName(const wxString &s) + { + argNamesArray.Add(s); + } + wxArrayString &GetArgTypesArray() + { + return argTypesArray; + } + void iAddArgType(const wxString &s) + { + argTypesArray.Add(s); + } + wxArrayString &GetArgModesArray() + { + return argModesArray; + } + void iAddArgMode(const wxString &s) + { + argModesArray.Add(s); + } + wxArrayString &GetArgDefsArray() + { + return argDefsArray; + } + void iAddArgDef(const wxString &s) + { + argDefsArray.Add(s); + } + + wxString GetReturnType() const + { + return returnType; + } + void iSetReturnType(const wxString &s) + { + returnType = s; + } + wxString GetLanguage() const + { + return language; + } + void iSetLanguage(const wxString &s) + { + language = s; + } + wxString GetVolatility() const + { + return volatility; + } + void iSetVolatility(const wxString &s) + { + volatility = s; + } + wxString GetParallel() const + { + return parallel; + } + void iSetParallel(const wxString &s) + { + parallel = s; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetBin() const + { + return bin; + } + void iSetBin(const wxString &s) + { + bin = s; + } + long GetArgCount() const + { + return argCount; + } + void iSetArgCount(long ac) + { + argCount = ac; + } + void iSetArgDefValCount(long ac) + { + argDefValCount = ac; + } + long GetArgDefValCount() + { + return argDefValCount; + } + long GetCost() const + { + return cost; + } + void iSetCost(long c) + { + cost = c; + } + long GetRows() const + { + return rows; + } + void iSetRows(long r) + { + rows = r; + } + bool GetReturnAsSet() const + { + return returnAsSet; + } + void iSetReturnAsSet(bool b) + { + returnAsSet = b; + } + bool GetSecureDefiner() const + { + return secureDefiner; + } + void iSetSecureDefiner(bool b) + { + secureDefiner = b; + } + bool GetIsStrict() const + { + return isStrict; + } + void iSetIsStrict(bool b) + { + isStrict = b; + } + bool GetIsWindow() const + { + return isWindow; + } + void iSetIsWindow(bool b) + { + isWindow = b; + } + long GetProcType() + { + return procType; + } + void iSetProcType(long l) + { + procType = l; + } + wxArrayString &GetConfigList() + { + return configList; + } + bool GetIsLeakProof() const + { + return isLeakProof; + } + void iSetIsLeakProof(bool b) + { + isLeakProof = b; + } + + bool CanRestore() + { + return true; + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createfunction"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetSelectSql(ctlTree *browser); + + bool ResetStats(); + + void ShowHint(frmMain *form, bool force); + bool GetCanHint() + { + return true; + }; + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool IsUpToDate(); + +protected: + pgFunction(pgSchema *newSchema, int newType, const wxString &newName = wxT("")); + +private: + wxString returnType, language, volatility, parallel, source, bin; + wxArrayString argNamesArray, argTypesArray, argModesArray, argDefsArray; + bool returnAsSet, secureDefiner, isStrict, isWindow, isLeakProof; + long argCount, cost, rows, argDefValCount, procType; + wxArrayString configList; +}; + + +class pgFunctionCollection : public pgSchemaObjCollection +{ +public: + pgFunctionCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + + +class pgTriggerFunctionFactory : public pgFunctionFactory +{ +public: + pgTriggerFunctionFactory(); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgTriggerFunctionFactory triggerFunctionFactory; + + +class pgTriggerFunction : public pgFunction +{ +public: + pgTriggerFunction(pgSchema *newSchema, const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + static pgObject *ReadObjects(pgCollection *collection, ctlTree *browser); +}; + + +class pgTriggerFunctionCollection : public pgSchemaObjCollection +{ +public: + pgTriggerFunctionCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgProcedureFactory : public pgFunctionFactory +{ +public: + pgProcedureFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgProcedureFactory procedureFactory; + + +class pgProcedure : public pgFunction +{ +public: + pgProcedure(pgSchema *newSchema, const wxString &newName = wxT("")); + wxString GetFullName(); + wxString GetTranslatedMessage(int kindOfMessage) const; + static pgObject *ReadObjects(pgCollection *collection, ctlTree *browser); + bool GetIsProcedure() const + { + return true; + } + + wxString GetSql(ctlTree *browser); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetExecSql(ctlTree *browser); + + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createprocedure"); + } +}; + + +class resetFunctionStatsFactory : public contextActionFactory +{ +public: + resetFunctionStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class pgProcedureCollection : public pgSchemaObjCollection +{ +public: + pgProcedureCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +#endif diff --git a/include/schema/pgGroup.h b/include/schema/pgGroup.h new file mode 100644 index 0000000..62ab888 --- /dev/null +++ b/include/schema/pgGroup.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgGroup.h - PostgreSQL Group +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGGROUP_H +#define PGGROUP_H + +#include "pgServer.h" + + +class pgGroupFactory : public pgServerObjFactory +{ +public: + pgGroupFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgGroupFactory groupFactory; + + +// Class declarations +class pgGroup : public pgServerObject +{ +public: + pgGroup(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + // Group Specific + long GetGroupId() const + { + return groupId; + } + void iSetGroupId(const long l) + { + groupId = l; + } + long GetMemberCount() const + { + return memberCount; + } + void iSetMemberCount(const long l) + { + memberCount = l; + } + wxString GetMemberIds() const + { + return memberIds; + } + void iSetMemberIds(const wxString &s) + { + memberIds = s; + } + wxString GetMembers() const + { + return members; + } + void iSetMembers(const wxString &s) + { + members = s; + } + wxArrayString &GetUsersIn() + { + return usersIn; + } + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + long groupId, memberCount; + wxString memberIds, members, quotedMembers; + wxArrayString usersIn; +}; + +class pgGroupCollection : public pgServerObjCollection +{ +public: + pgGroupCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgIndex.h b/include/schema/pgIndex.h new file mode 100644 index 0000000..2ee1553 --- /dev/null +++ b/include/schema/pgIndex.h @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndex.h PostgreSQL Index +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGINDEX_H +#define PGINDEX_H + +#include "pgTable.h" +#include + + + + +class pgIndexBase : public pgSchemaObject +{ +protected: + pgIndexBase(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxT("")); + +public: + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetProcArgs() const + { + return procArgs; + } + wxString GetQuotedTypedColumns() const + { + return quotedTypedColumns; + } + wxString GetTypedColumns() const + { + return typedColumns; + } + wxString GetOperatorClasses() const + { + return operatorClasses; + } + wxString GetQuotedColumns() const + { + return quotedColumns; + } + wxString GetColumns() const + { + return columns; + } + wxArrayString GetColumnList() const + { + return columnList; + } + + wxString GetColumnNumbers() const + { + return columnNumbers; + } + void iSetColumnNumbers(const wxString &s) + { + columnNumbers = s; + } + wxString GetConstraint() const + { + return constraint; + } + void iSetConstraint(const wxString &s) + { + constraint = s; + } + wxString GetIndexType() const + { + return indexType; + } + void iSetIndexType(const wxString &s) + { + indexType = s; + } + long GetColumnCount() const + { + return columnCount; + } + void iSetColumnCount(const long l) + { + columnCount = l; + } + bool GetIsUnique() const + { + return isUnique; + } + void iSetIsUnique(const bool b) + { + isUnique = b; + } + bool GetIsExclude() const + { + return isExclude; + } + void iSetIsExclude(const bool b) + { + isExclude = b; + } + bool GetIsPrimary() const + { + return isPrimary; + } + void iSetIsPrimary(const bool b) + { + isPrimary = b; + } + bool GetIsClustered() const + { + return isClustered; + } + void iSetIsClustered(const bool b) + { + isClustered = b; + } + bool GetIsValid() const + { + return isValid; + } + void iSetIsValid(const bool b) + { + isValid = b; + } + wxString GetIdxTable() const + { + return idxTable; + } + void iSetIdxTable(const wxString &s) + { + idxTable = s; + } + wxString GetRelOptions() const + { + return reloptions; + } + void iSetRelOptions(const wxString &s) + { + reloptions = s; + } + wxString GetIdxSchema() const + { + return idxSchema; + } + void iSetIdxSchema(const wxString &s) + { + idxSchema = s; + } + OID GetRelTableOid() const + { + return relTableOid; + } + void iSetRelTableOid(const OID d) + { + relTableOid = d; + } + wxString GetTablespace() const + { + return tablespace; + }; + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + }; + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + + wxString GetProcName() const + { + return procName; + } + void iSetProcName(const wxString &s) + { + procName = s; + } + wxString GetProcNamespace() const + { + return procNamespace; + } + void iSetProcNamespace(const wxString &s) + { + procNamespace = s; + } + + bool GetDeferrable() const + { + return deferrable; + } + void iSetDeferrable(const bool b) + { + deferrable = b; + } + bool GetDeferred() const + { + return deferred; + } + void iSetDeferred(const bool b) + { + deferred = b; + } + + void iSetOperatorClassList(const wxString &s) + { + operatorClassList = s; + } + void iSetProcArgTypeList(const wxString &s) + { + procArgTypeList = s; + } + + const wxArrayString &GetOrdersArray() + { + return ordersArray; + } + + const wxArrayString &GetNullsArray() + { + return nullsArray; + } + + const wxArrayString &GetOpClassesArray() + { + return opclassesArray; + } + + const wxArrayString &GetCollationsArray() + { + return collationsArray; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetCreate(); + bool CanRestore() + { + return true; + } + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool CanMaintenance() + { + return true; + } + bool GetShowExtendedStatistics() + { + return showExtendedStatistics; + } + void iSetShowExtendedStatistics(bool b) + { + showExtendedStatistics = b; + } + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool HasPgstatindex(); + +protected: + void ReadColumnDetails(); + +private: + wxString columnNumbers, columns, quotedColumns, indexType, idxTable, reloptions, idxSchema, constraint, tablespace; + wxString procName, procNamespace, procArgs, procArgTypeList, typedColumns, quotedTypedColumns, operatorClasses, operatorClassList; + long columnCount; + wxArrayString columnList, ordersArray, nullsArray, opclassesArray, collationsArray; + bool isUnique, isPrimary, isExclude, isClustered, isValid; + bool deferrable, deferred, showExtendedStatistics; + OID relTableOid, tablespaceOid; + wxString fillFactor; +}; + + +class pgIndex : public pgIndexBase +{ +public: + pgIndex(pgSchema *newSchema, const wxString &newName = wxT("")); +}; + + +class pgIndexBaseFactory : public pgSchemaObjFactory +{ +public: + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +protected: + pgIndexBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img = 0) : pgSchemaObjFactory(tn, ns, nls, img) {} +}; + +class pgIndexFactory : public pgIndexBaseFactory +{ +public: + pgIndexFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgIndexFactory indexFactory; + +class pgIndexBaseCollection : public pgSchemaObjCollection +{ +public: + pgIndexBaseCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + + +class executePgstatindexFactory : public contextActionFactory +{ +public: + executePgstatindexFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgIndexConstraint.h b/include/schema/pgIndexConstraint.h new file mode 100644 index 0000000..d0ac414 --- /dev/null +++ b/include/schema/pgIndexConstraint.h @@ -0,0 +1,113 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndexConstraint.h PostgreSQL Index Constraint: PK, Unique +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __PG_INDEXCONSTRAINT +#define __PG_INDEXCONSTRAINT + +#include "pgIndex.h" + +class pgIndexConstraint : public pgIndexBase +{ +public: + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browse, bool cascadedr); + wxString GetDefinition(); + wxString GetCreate(); + wxString GetSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-altertable"); + } + OID GetConstraintOid() + { + return constraintOid; + } + void iSetConstraintOid(const OID o) + { + constraintOid = o; + } + +protected: + pgIndexConstraint(pgSchema *newSchema, pgaFactory &factory, const wxString &newName) + : pgIndexBase(newSchema, factory, newName) {} + +private: + OID constraintOid; +}; + + +class pgPrimaryKeyFactory : public pgIndexBaseFactory +{ +public: + pgPrimaryKeyFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgPrimaryKeyFactory primaryKeyFactory; + +class pgPrimaryKey : public pgIndexConstraint +{ +public: + pgPrimaryKey(pgSchema *newSchema, const wxString &newName = wxT("")) + : pgIndexConstraint(newSchema, primaryKeyFactory, newName) {} + + wxString GetTranslatedMessage(int kindOfMessage) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool CanCreate() + { + return false; + } +}; + + +class pgUniqueFactory : public pgIndexBaseFactory +{ +public: + pgUniqueFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgUniqueFactory uniqueFactory; + +class pgUnique : public pgIndexConstraint +{ +public: + pgUnique(pgSchema *newSchema, const wxString &newName = wxT("")) + : pgIndexConstraint(newSchema, uniqueFactory, newName) {} + + wxString GetTranslatedMessage(int kindOfMessage) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); +}; + + +class pgExcludeFactory : public pgIndexBaseFactory +{ +public: + pgExcludeFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgExcludeFactory excludeFactory; + +class pgExclude : public pgIndexConstraint +{ +public: + pgExclude(pgSchema *newSchema, const wxString &newName = wxT("")) + : pgIndexConstraint(newSchema, excludeFactory, newName) {} + + wxString GetTranslatedMessage(int kindOfMessage) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); +}; + + +#endif diff --git a/include/schema/pgLanguage.h b/include/schema/pgLanguage.h new file mode 100644 index 0000000..4e61f7d --- /dev/null +++ b/include/schema/pgLanguage.h @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgLanguage.h - Language class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGLANGUAGE_H +#define PGLANGUAGE_H + +#include "pgDatabase.h" + +class pgCollection; +class pgLanguageFactory : public pgDatabaseObjFactory +{ +public: + pgLanguageFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgLanguageFactory languageFactory; + +class pgLanguage : public pgDatabaseObject +{ +public: + pgLanguage(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool CanDropCascaded() + { + return true; + } + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + wxString GetHandlerProc() const + { + return handlerProc; + } + void iSetHandlerProc(const wxString &s) + { + handlerProc = s; + } + wxString GetInlineProc() const + { + return inlineProc; + } + void iSetInlineProc(const wxString &s) + { + inlineProc = s; + } + wxString GetValidatorProc() const + { + return validatorProc; + } + void iSetValidatorProc(const wxString &s) + { + validatorProc = s; + } + bool GetTrusted() const + { + return trusted; + } + void iSetTrusted(const bool b) + { + trusted = b; + } + +private: + wxString handlerProc, inlineProc, validatorProc; + bool trusted; +}; + +class pgLanguageCollection : public pgDatabaseObjCollection +{ +public: + pgLanguageCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgObject.h b/include/schema/pgObject.h new file mode 100644 index 0000000..da7cd24 --- /dev/null +++ b/include/schema/pgObject.h @@ -0,0 +1,393 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgObject.h - PostgreSQL base object class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGOBJECT_H +#define PGOBJECT_H + +class ctlTree; +class ctlSQLBox; +class ctlListView; +class frmMain; +class frmReport; +class pgDatabase; +class pgSchema; +class pgCollection; +class pgConn; +class pgSet; +class pgServer; +class pgTable; +class pgaJob; + + +class pgTypes +{ +public: + wxChar *typName; + long typeIcon; + wxChar *newString; + wxChar *newLongString; +}; + + +class pgaFactory; + + +enum +{ + RETRIEVINGDETAILS = 1, + REFRESHINGDETAILS, + BACKUPGLOBALS, + GRANTWIZARDTITLE, + MAINTENANCEDIALOGTITLE, + BACKUPSERVERTITLE, + BACKUPTITLE, + RESTORETITLE, + CANNOTDROPSYSTEM, + DROPINCLUDINGDEPS, + DROPEXCLUDINGDEPS, + DROPCASCADETITLE, + DROPTITLE, + PROPERTIESREPORT, + PROPERTIES, + DDLREPORT, + DDL, + DATADICTIONNARYREPORT, + STATISTICSREPORT, + OBJSTATISTICS, + DEPENDENCIESREPORT, + DEPENDENCIES, + DEPENDENTSREPORT, + DEPENDENTS, + OBJECTSLISTREPORT +}; + + +// Class declarations +class pgObject : public wxTreeItemData +{ +protected: + pgObject(int newType, const wxString &newName = wxEmptyString); + pgObject(pgaFactory &factory, const wxString &newName = wxEmptyString); + +public: + /* + * Except column level privileges, column will be always an empty + * string in any case + */ + static wxString GetPrivileges(const wxString &allPattern, + const wxString &acl, const wxString &grantObject, + const wxString &user, const wxString &column = wxT("")); + + static wxString GetDefaultPrivileges(const wxString &strType, const wxString &strSupportedPrivs, + const wxString &strSchema, const wxString &strOrigDefPrivs, + const wxString &strNewDefPrivs, const wxString &strRole); + static wxString GetPrivilegeName(wxChar privilege); + static bool findUserPrivs(wxString &, wxString &, wxString &); + + static int GetTypeId(const wxString &typname); + + pgaFactory *GetFactory() + { + return factory; + } + bool IsCreatedBy(pgaFactory &f) const + { + return &f == factory; + } + bool IsCreatedBy(pgaFactory *f) const + { + return f == factory; + } + int GetType() const; + int GetMetaType() const; + wxString GetTypeName() const; + wxString GetTranslatedTypeName() const; + virtual wxString GetTranslatedMessage(int kindOfMessage) const; + virtual int GetIconId(); + bool UpdateIcon(ctlTree *browser); + + virtual void ShowProperties() const {}; + virtual pgDatabase *GetDatabase() const + { + return 0; + } + virtual pgServer *GetServer() const + { + return 0; + } + virtual pgSchema *GetSchema() const + { + return 0; + } + virtual pgTable *GetTable() const + { + return 0; + } + virtual pgaJob *GetJob() const + { + return 0; + } + void iSetName(const wxString &newVal) + { + name = newVal; + } + wxString GetName() const + { + return name; + } + OID GetOid() const + { + return oid; + } + wxString GetOidStr() const + { + return NumToStr(oid) + wxT("::oid"); + } + void iSetOid(const OID newVal) + { + oid = newVal; + } + void iSetXid(const OID x) + { + xid = x; + }; + OID GetXid() + { + return xid; + }; + wxString GetOwner() const + { + return owner; + } + void iSetOwner(const wxString &newVal) + { + owner = newVal; + } + wxString GetComment() const + { + return comment; + } + void iSetComment(const wxString &newVal) + { + comment = newVal; + } + wxString GetAcl() const + { + return acl; + } + void iSetAcl(const wxString &newVal) + { + acl = newVal; + } + virtual bool GetSystemObject() const + { + return false; + } + virtual bool IsCollection() const + { + return false; + } + virtual void ShowHint(frmMain *form, bool force) {} + + void ShowTree(frmMain *form, ctlTree *browser, ctlListView *properties, ctlSQLBox *sqlPane); + + wxTreeItemId AppendBrowserItem(ctlTree *browser, pgObject *object); + + virtual wxString GetHelpPage(bool forCreate) const; + virtual wxString GetFullName() + { + return name; + } + virtual wxString GetIdentifier() const + { + return name; + } + virtual wxString GetQuotedIdentifier() const + { + return qtIdent(name); + } + virtual wxString GetDisplayName() + { + return GetFullName(); + }; + void iSetProviders(const wxString &newVal) + { + providers = newVal; + } + wxString GetProviders() const + { + return providers; + } + void iSetLabels(const wxString &newVal) + { + labels = newVal; + } + wxString GetLabels() const + { + return labels; + } + wxArrayString GetProviderLabelArray(); + wxString GetSeqLabelsSql(); + + virtual wxMenu *GetNewMenu(); + + virtual wxString GetSql(ctlTree *browser) + { + return wxT(""); + } + /* + * Except column level privileges, column will be always an empty + * string in any case + */ + wxString GetGrant(const wxString &allPattern, const wxString &grantFor = wxT(""), const wxString &column = wxT("")); + wxString GetCommentSql(); + wxString GetOwnerSql(int major, int minor, wxString objname = wxEmptyString, wxString objtype = wxEmptyString); + pgConn *GetConnection() const; + + virtual void SetDirty() + { + sql = wxT(""); + expandedKids = false; + needReread = true; + } + virtual wxString GetFullIdentifier() const + { + return GetName(); + } + virtual wxString GetQuotedFullIdentifier() const + { + return qtIdent(name); + } + + virtual void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0) = 0; + virtual void ShowStatistics(frmMain *form, ctlListView *statistics); + virtual void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); + virtual void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + virtual pgObject *Refresh(ctlTree *browser, const wxTreeItemId item) + { + return this; + } + virtual bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded = false) + { + return false; + } + virtual bool EditObject(wxFrame *frame, ctlTree *browser) + { + return false; + } + + virtual bool NeedCascadedDrop() + { + return false; + } + virtual bool CanCreate() + { + return false; + } + virtual bool CanView() + { + return false; + } + virtual bool CanEdit() + { + return false; + } + virtual bool CanDrop() + { + return false; + } + virtual bool CanDropCascaded() + { + return false; + } + virtual bool CanMaintenance() + { + return false; + } + virtual bool RequireDropConfirm() + { + return false; + } + virtual bool WantDummyChild() + { + return false; + } + virtual bool CanBackup() + { + return false; + } + virtual bool CanBackupGlobals() + { + return false; + } + virtual bool CanRestore() + { + return false; + } + virtual bool GetCanHint() + { + return false; + } + virtual bool HasStats() + { + return false; + } + virtual bool HasDepends() + { + return false; + } + virtual bool HasReferences() + { + return false; + } + + wxString qtDbString(const wxString &str); + + void SetWindowPtr(dlgProperty *dlgprop); + wxString GetSqlReCreate(frmMain *form, pgObject *obj); + dlgProperty *GetWindowPtr() + { + return dlg; + } + + bool CheckOpenDialogs(ctlTree *browser, wxTreeItemId node); + +protected: + void CreateList3Columns(ctlListView *properties, const wxString &left = _("Object"), const wxString &middle = _("Owner"), const wxString &right = _("Value")); + void CreateListColumns(ctlListView *properties, const wxString &left = _("Property"), const wxString &right = _("Value")); + + void AppendMenu(wxMenu *menu, int type = -1); + virtual void SetContextInfo(frmMain *form) {} + + bool expandedKids, needReread; + wxString sql; + bool hintShown; + pgaFactory *factory; + +private: + /* + * Except column level privileges, column will be always an empty + * string in any case + */ + static void AppendRight(wxString &rights, const wxString &acl, wxChar c, const wxChar *rightName, const wxString &column = wxEmptyString); + static wxString GetPrivilegeGrant(const wxString &allPattern, const wxString &acl, const wxString &grantObject, const wxString &user, const wxString &column); + void ShowDependency(pgDatabase *db, ctlListView *list, const wxString &query, const wxString &clsOrder); + wxString name, owner, schema, comment, acl; + int type; + OID oid, xid; + wxString providers, labels; + dlgProperty *dlg; + + friend class pgaFactory; +}; + +#endif + diff --git a/include/schema/pgOperator.h b/include/schema/pgOperator.h new file mode 100644 index 0000000..09204f7 --- /dev/null +++ b/include/schema/pgOperator.h @@ -0,0 +1,218 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperator.h PostgreSQL Operator +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_OPERATOR_H +#define PG_OPERATOR_H + + +#include "pgSchema.h" + + +class pgOperatorFactory : public pgSchemaObjFactory +{ +public: + pgOperatorFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgOperatorFactory operatorFactory; + +class pgOperator : public pgSchemaObject +{ +public: + pgOperator(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgOperator(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + virtual wxString GetQuotedIdentifier() const + { + return GetName(); + } + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetFullName(); + wxString GetOperands() const; + wxString GetLeftType() const + { + return leftType; + } + void iSetLeftType(const wxString &s) + { + leftType = s; + } + wxString GetRightType() const + { + return rightType; + } + void iSetRightType(const wxString &s) + { + rightType = s; + } + OID GetLeftTypeOid() const + { + return leftTypeOid; + } + void iSetLeftTypeOid(const OID o) + { + leftTypeOid = o; + } + OID GetRightTypeOid() const + { + return rightTypeOid; + } + void iSetRightTypeOid(const OID o) + { + rightTypeOid = o; + } + wxString GetResultType() + { + return resultType; + } + void iSetResultType(const wxString &s) + { + resultType = s; + } + wxString GetOperatorFunction() const + { + return operatorFunction; + } + void iSetOperatorFunction(const wxString &s) + { + operatorFunction = s; + } + wxString GetJoinFunction() const + { + return joinFunction; + } + void iSetJoinFunction(const wxString &s) + { + joinFunction = s; + } + wxString GetRestrictFunction() const + { + return restrictFunction; + } + void iSetRestrictFunction(const wxString &s) + { + restrictFunction = s; + } + wxString GetCommutator() const + { + return commutator; + } + void iSetCommutator(const wxString &s) + { + commutator = s; + } + wxString GetNegator() const + { + return negator; + } + void iSetNegator(const wxString &s) + { + negator = s; + } + wxString GetKind() const + { + return kind; + } + void iSetKind(const wxString &s) + { + kind = s; + } + wxString GetLeftSortOperator() const + { + return leftSortOperator; + } + void iSetLeftSortOperator(const wxString &s) + { + leftSortOperator = s; + } + wxString GetRightSortOperator() const + { + return rightSortOperator; + } + void iSetRightSortOperator(const wxString &s) + { + rightSortOperator = s; + } + wxString GetLessOperator() const + { + return lessOperator; + } + void iSetLessOperator(const wxString &s) + { + lessOperator = s; + } + wxString GetGreaterOperator() const + { + return greaterOperator; + } + void iSetGreaterOperator(const wxString &s) + { + greaterOperator = s; + } + bool GetHashJoins() const + { + return hashJoins; + } + void iSetHashJoins(bool b) + { + hashJoins = b; + } + bool GetMergeJoins() const + { + return mergeJoins; + } + void iSetMergeJoins(bool b) + { + mergeJoins = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString leftType, rightType, resultType, + operatorFunction, joinFunction, restrictFunction, + commutator, negator, kind, + leftSortOperator, rightSortOperator, lessOperator, greaterOperator; + OID leftTypeOid, rightTypeOid; + bool hashJoins, mergeJoins; +}; + +class pgOperatorCollection : public pgSchemaObjCollection +{ +public: + pgOperatorCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgOperatorClass.h b/include/schema/pgOperatorClass.h new file mode 100644 index 0000000..8a18d47 --- /dev/null +++ b/include/schema/pgOperatorClass.h @@ -0,0 +1,140 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorClass.h PostgreSQL OperatorClass +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGOPERATORCLASS_H +#define PGOPERATORCLASS_H + +#include "pgSchema.h" + +class pgCollection; +class pgOperatorClassFactory : public pgSchemaObjFactory +{ +public: + pgOperatorClassFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgOperatorClassFactory operatorClassFactory; + + +class pgOperatorClass : public pgSchemaObject +{ +public: + pgOperatorClass(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgOperatorClass(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetFullName() + { + return GetName() + wxT("(") + GetAccessMethod() + wxT(")"); + } + wxString GetAccessMethod() const + { + return accessMethod; + } + void iSetAccessMethod(const wxString &s) + { + accessMethod = s; + } + + wxArrayString GetOperators() + { + return operators; + } + wxArrayString GetFunctions() + { + return functions; + } + wxArrayString GetQuotedFunctions() + { + return quotedFunctions; + } + wxString GetInType() const + { + return inType; + } + void iSetInType(const wxString &s) + { + inType = s; + } + wxString GetKeyType() const + { + return keyType; + } + void iSetKeyType(const wxString &s) + { + keyType = s; + } + wxString GetSql(ctlTree *browser); + bool GetOpcDefault() const + { + return opcDefault; + } + void iSetOpcDefault(const bool b) + { + opcDefault = b; + } + wxString GetFamily() const + { + return opFamily; + } + void iSetFamily(const wxString &s) + { + opFamily = s; + } + + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createopclass"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString inType, keyType, accessMethod, opFamily ; + wxArrayString operators; + wxArrayString functions, quotedFunctions; + wxArrayString functionOids; + bool opcDefault; +}; + +class pgOperatorClassCollection : public pgSchemaObjCollection +{ +public: + pgOperatorClassCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgOperatorFamily.h b/include/schema/pgOperatorFamily.h new file mode 100644 index 0000000..3b2b974 --- /dev/null +++ b/include/schema/pgOperatorFamily.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorFamily.h PostgreSQL OperatorFamily +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGOPERATORFAMILY_H +#define PGOPERATORFAMILY_H + +#include "pgSchema.h" + +class pgCollection; +class pgOperatorFamilyFactory : public pgSchemaObjFactory +{ +public: + pgOperatorFamilyFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgOperatorFamilyFactory operatorFamilyFactory; + + +class pgOperatorFamily : public pgSchemaObject +{ +public: + pgOperatorFamily(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgOperatorFamily(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetFullName() + { + return GetName() + wxT("(") + GetAccessMethod() + wxT(")"); + } + wxString GetAccessMethod() const + { + return accessMethod; + } + void iSetAccessMethod(const wxString &s) + { + accessMethod = s; + } + wxString GetSql(ctlTree *browser); + + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return false; + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createopfamily"); + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString accessMethod; +}; + +class pgOperatorFamilyCollection : public pgSchemaObjCollection +{ +public: + pgOperatorFamilyCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgPartition.h b/include/schema/pgPartition.h new file mode 100644 index 0000000..0eb6564 --- /dev/null +++ b/include/schema/pgPartition.h @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgPartition.h Greenplum Partitioned Table Partition +// +////////////////////////////////////////////////////////////////////////// + +#ifndef pgPartition_H +#define pgPartition_H + +#include "pgSchema.h" +#include "pgTable.h" + + + +class pgPartitionFactory : public pgTableObjFactory +{ +public: + pgPartitionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) ; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + virtual void AppendMenu(wxMenu *menu); +}; + +extern pgPartitionFactory pg_partitionFactory; + +class pgPartition : public pgTable +{ +public: + pgPartition(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgPartition(); + bool CanCreate(); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + wxString GetPartitionName() + { + return partitionname; + } + void iSetPartitionName(const wxString &pn) + { + partitionname = pn; + } + +private: + wxString partitionname; +}; + + +class pgPartitionObject : public pgTableObject +{ +public: + pgPartitionObject(pgPartition *newTable, pgaFactory &factory, const wxString &newName = wxT("")) + : pgTableObject(newTable, factory, newName) { }; + virtual pgPartition *GetTable() const + { + return dynamic_cast(table); + } + OID GetTableOid() const + { + return table->GetOid(); + } + wxString GetTableOidStr() const + { + return NumToStr(table->GetOid()) + wxT("::oid"); + } +}; + + +class pgPartitionCollection : public pgTableCollection +{ +public: + pgPartitionCollection(pgaFactory *factory, pgPartition *_table); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + virtual bool CanCreate() + { + return false; + }; +}; + + +class pgPartitionObjCollection : public pgTableObjCollection +{ +public: + pgPartitionObjCollection(pgaFactory *factory, pgPartition *_table) + : pgTableObjCollection(factory, (pgTable *)_table ) { }; + virtual pgTable *GetTable() const + { + return table; + } + virtual bool CanCreate(); +}; + + + +#endif diff --git a/include/schema/pgPublication.h b/include/schema/pgPublication.h new file mode 100644 index 0000000..e1ce300 --- /dev/null +++ b/include/schema/pgPublication.h @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgExtension.h PostgreSQL Extension +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGPUBLICATION_H +#define PGPUBLICATION_H + +#include "pgDatabase.h" + +class pgCollection; +class pgPublicationFactory : public pgDatabaseObjFactory +{ +public: + pgPublicationFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgPublicationFactory publicationFactory; + +class pgPublication : public pgDatabaseObject +{ +public: + pgPublication(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + + wxString GetTablesStr() const + { + return tables; + } + void iSetTablesStr(const wxString &s) + { + tables = s; + } + wxString GetVersion() const + { + return version; + } + void iSetVersion(const wxString &s) + { + version = s; + } + bool GetIsAll() const + { + return all; + } + void iSetIsAll(const bool b) + { + all = b; + } + bool GetIsIns() const + { + return ins; + } + void iSetIsIns(const bool b) + { + ins = b; + } + bool GetIsUpd() const + { + return upd; + } + void iSetIsUpd(const bool b) + { + upd = b; + } + bool GetIsDel() const + { + return del; + } + wxString GetStrOper() const + { + wxString s = wxT(""); + if (GetIsIns()) s += wxT("insert"); + if (GetIsUpd()&&(!s.IsEmpty())) s += wxT(", "); + if (GetIsUpd()) s += wxT("update"); + if (GetIsDel()&&(!s.IsEmpty())) s += wxT(", "); + if (GetIsDel()) s += wxT("delete"); + return s; + } + void iSetIsDel(const bool b) + { + del = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +private: + wxString tables, version; + bool all,ins,upd,del; +}; + +class pgPublicationCollection : public pgDatabaseObjCollection +{ +public: + pgPublicationCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgRole.h b/include/schema/pgRole.h new file mode 100644 index 0000000..e895e06 --- /dev/null +++ b/include/schema/pgRole.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRole.h - PostgreSQL Role +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGROLE_H +#define PGROLE_H + +#include "pgServer.h" + + +#define PGROLE_ADMINOPTION wxT("(*)") +#define PGROLE_ADMINOPTION_LEN 3 + + +class pgRoleBaseFactory : public pgServerObjFactory +{ +public: + pgRoleBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img = 0); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr); +}; + +class pgLoginRoleFactory : public pgRoleBaseFactory +{ +public: + pgLoginRoleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class pgGroupRoleFactory : public pgRoleBaseFactory +{ +public: + pgGroupRoleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +extern pgLoginRoleFactory loginRoleFactory; +extern pgGroupRoleFactory groupRoleFactory; + + +// Class declarations +class pgRole : public pgServerObject +{ +protected: + pgRole(pgaFactory &factory, const wxString &newName = wxT("")); + +public: + int GetIconId(); + + + // Role Specific + wxDateTime GetAccountExpires() const + { + return accountExpires; + } + void iSetAccountExpires(const wxDateTime &dt) + { + accountExpires = dt; + } + wxString GetPassword() const + { + return password; + } + void iSetPassword(const wxString &s) + { + password = s; + } + void iSetInherits(const bool b) + { + inherits = b; + } + bool GetInherits() const + { + return inherits; + } + void iSetCanLogin(const bool b) + { + canLogin = b; + } + bool GetCanLogin() const + { + return canLogin; + } + bool GetCreateDatabase() const + { + return createDatabase; + } + void iSetCreateDatabase(const bool b) + { + createDatabase = b; + } + bool GetCreateRole() const + { + return createRole; + } + void iSetCreateRole(const bool b) + { + createRole = b; + } + bool GetSuperuser() const + { + return superuser; + } + void iSetSuperuser(const bool b) + { + superuser = b; + } + bool GetUpdateCatalog() const + { + return updateCatalog; + } + void iSetUpdateCatalog(const bool b) + { + updateCatalog = b; + } + bool GetReplication() const + { + return replication; + } + void iSetReplication(const bool b) + { + replication = b; + } + wxString GetRolQueueName() const + { + return rolqueuename; + } + void iSetRolQueueName(const wxString &newVal) + { + rolqueuename = newVal; + } + long GetConnectionLimit() const + { + return connectionLimit; + } + void iSetConnectionLimit(long newVal) + { + connectionLimit = newVal; + } + void iSetIsValidInfinity(const bool b) + { + isValidInfinity = b; + } + wxArrayString &GetRolesIn() + { + return rolesIn; + } + wxArrayString &GetVariables() + { + return variables; + } + + void ReassignDropOwnedTo(frmMain *form); + + // Tree object creation + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where); + + // virtual methods + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool GetIsValidInfinity() + { + return isValidInfinity; + } +private: + wxString password; + wxString rolqueuename; + wxDateTime accountExpires; + bool superuser, createDatabase, createRole, updateCatalog, inherits, canLogin, replication, isValidInfinity; + long connectionLimit; + wxArrayString rolesIn; + wxArrayString variables; +}; + + + +class pgLoginRole : public pgRole +{ +public: + pgLoginRole(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgGroupRole : public pgRole +{ +public: + pgGroupRole(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class pgLoginRoleCollection : public pgServerObjCollection +{ +public: + pgLoginRoleCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgGroupRoleCollection : public pgServerObjCollection +{ +public: + pgGroupRoleCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class reassignDropOwnedFactory : public contextActionFactory +{ +public: + reassignDropOwnedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgRule.h b/include/schema/pgRule.h new file mode 100644 index 0000000..ba612aa --- /dev/null +++ b/include/schema/pgRule.h @@ -0,0 +1,183 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRule.h PostgreSQL Rule +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGRULE_H +#define PGRULE_H + + +#include "pgSchema.h" + +class pgRuleObject : public pgSchemaObject +{ +public: + pgRuleObject(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgSchemaObject(newSchema, factory, newName) {} + + wxString GetFormattedDefinition(); + wxString GetDefinition() const + { + return definition; + } + void iSetDefinition(const wxString &s) + { + definition = s; + } + +protected: + wxString definition; +}; + + + +//////////////////////////////////////////////////////////7 + + +class pgRuleFactory : public pgSchemaObjFactory +{ +public: + pgRuleFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgRuleFactory ruleFactory; + + +class pgRule : public pgRuleObject +{ +public: + pgRule(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgRule(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetEvent() const + { + return event; + } + void iSetEvent(const wxString &s) + { + event = s; + } + wxString GetCondition() const + { + return condition; + } + void iSetCondition(const wxString &s) + { + condition = s; + } + wxString GetAction() const + { + return action; + } + void iSetAction(const wxString &s) + { + action = s; + } + bool GetDoInstead() const + { + return doInstead; + } + void iSetDoInstead(const bool b) + { + doInstead = b; + } + bool GetEnabled() const + { + return enabled; + } + void SetEnabled(ctlTree *browser, const bool b); + void iSetEnabled(const bool b) + { + enabled = b; + } + wxString GetQuotedFullTable() const + { + return quotedFullTable; + } + void iSetQuotedFullTable(const wxString &s) + { + quotedFullTable = s; + } + void iSetParentIsTable(const bool b) + { + parentistable = b; + } + bool GetParentIsTable() + { + return parentistable; + } + + bool GetSystemObject() const + { + return GetName() == wxT("_RETURN"); + } + bool CanDrop() + { + return !GetSystemObject() && GetSchema()->CanDrop(); + } + bool CanCreate() + { + return GetSchema()->CanCreate(); + } + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } +private: + wxString event, condition, action, quotedFullTable; + bool doInstead, enabled, parentistable; +}; + +class pgRuleCollection : public pgSchemaObjCollection +{ +public: + pgRuleCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class enabledisableRuleFactory : public contextActionFactory +{ +public: + enabledisableRuleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgSchema.h b/include/schema/pgSchema.h new file mode 100644 index 0000000..daa3f81 --- /dev/null +++ b/include/schema/pgSchema.h @@ -0,0 +1,286 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSchema.h PostgreSQL Schema +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSCHEMA_H +#define PGSCHEMA_H + +#include "pgDatabase.h" + + +enum +{ + SCHEMATYP_SYSTEM = 0, + SCHEMATYP_TEMP, + SCHEMATYP_USERSYS, + SCHEMATYP_NORMAL +}; + +class pgSchemaBaseFactory : public pgDatabaseObjFactory +{ +public: + pgSchemaBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; + +class pgSchemaFactory : public pgSchemaBaseFactory +{ +public: + pgSchemaFactory(); + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class pgCatalogFactory : public pgSchemaBaseFactory +{ +public: + pgCatalogFactory(); + virtual pgCollection *CreateCollection(pgObject *obj); + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return true; + } +}; + +extern pgSchemaFactory schemaFactory; +extern pgCatalogFactory catalogFactory; + + +class pgSchemaBase : public pgDatabaseObject +{ +public: + pgSchemaBase(pgaFactory &factory, const wxString &newName = wxT("")); + + wxString GetPrefix() const + { + return database->GetSchemaPrefix(GetName()); + } + wxString GetQuotedPrefix() const + { + return database->GetQuotedSchemaPrefix(GetName()); + } + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + static pgObject *ReadObjects(pgCollection *collection, ctlTree *browser); + bool CanDropCascaded() + { + return GetMetaType() != PGM_CATALOG; + } + + long GetSchemaTyp() const + { + return schemaTyp; + } + void iSetSchemaTyp(const long l) + { + schemaTyp = l; + } + bool GetCreatePrivilege() const + { + return createPrivilege; + } + void iSetCreatePrivilege(const bool b) + { + createPrivilege = b; + } + bool GetSystemObject() const + { + return schemaTyp <= SCHEMATYP_TEMP; + } + + bool CanBackup() + { + return true; + } + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + bool CanRestore() + { + return GetConnection()->BackendMinimumVersion(8, 1); + } + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + // Default Privileges on Schema + void iSetDefPrivsOnTables(const wxString &privs) + { + m_defPrivsOnTables = privs; + } + void iSetDefPrivsOnSeqs(const wxString &privs) + { + m_defPrivsOnSeqs = privs; + } + void iSetDefPrivsOnFuncs(const wxString &privs) + { + m_defPrivsOnFuncs = privs; + } + void iSetDefPrivsOnTypes(const wxString &privs) + { + m_defPrivsOnTypes = privs; + } + + wxString GetDefPrivsOnTables() + { + return m_defPrivsOnTables; + } + wxString GetDefPrivsOnSequences() + { + return m_defPrivsOnSeqs; + } + wxString GetDefPrivsOnFunctions() + { + return m_defPrivsOnFuncs; + } + wxString GetDefPrivsOnTypes() + { + return m_defPrivsOnTypes; + } + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +protected: + wxString m_defPrivsOnTables, m_defPrivsOnSeqs, m_defPrivsOnFuncs, m_defPrivsOnTypes; + +private: + long schemaTyp; + bool createPrivilege; +}; + +class pgSchema : public pgSchemaBase +{ +public: + pgSchema(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class pgCatalog : public pgSchemaBase +{ +public: + pgCatalog(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + virtual wxString GetDisplayName(); + bool CanCreate() + { + return false; + } + bool CanEdit() + { + return true; + } +}; + +///////////////////////////////////////////////////// + +class pgSchemaObjFactory : public pgDatabaseObjFactory +{ +public: + pgSchemaObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +// Object that lives in a schema +class pgSchemaObject : public pgDatabaseObject +{ +public: + pgSchemaObject(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgDatabaseObject(factory, newName) + { + SetSchema(newSchema); + } + pgSchemaObject(pgSchema *newSchema, int newType, const wxString &newName = wxT("")) : pgDatabaseObject(newType, newName) + { + SetSchema(newSchema); + } + + bool GetSystemObject() const; + + bool CanDrop(); + bool CanEdit() + { + return schema->GetMetaType() != PGM_CATALOG; + } + bool CanCreate(); + + void SetSchema(pgSchema *newSchema); + void UpdateSchema(ctlTree *browser, OID schemaOid); + virtual pgSchema *GetSchema() const + { + return schema; + } + pgSet *ExecuteSet(const wxString &sql); + wxString ExecuteScalar(const wxString &sql); + bool ExecuteVoid(const wxString &sql); + virtual wxString GetFullIdentifier() const; + virtual wxString GetQuotedFullIdentifier() const; + + +protected: + virtual void SetContextInfo(frmMain *form); + + pgSchema *schema; +}; + + +class pgSchemaCollection : public pgDatabaseObjCollection +{ +public: + pgSchemaCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class pgCatalogCollection : public pgDatabaseObjCollection +{ +public: + pgCatalogCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +// collection of pgSchemaObject +class pgSchemaObjCollection : public pgCollection +{ +public: + pgSchemaObjCollection(pgaFactory *factory, pgSchema *sch); + virtual bool CanCreate(); +}; + +// collection of pgSchemaObject +class pgCatalogObjCollection : public pgCollection +{ +public: + pgCatalogObjCollection(pgaFactory *factory, pgSchema *sch); +}; + + +#endif diff --git a/include/schema/pgSequence.h b/include/schema/pgSequence.h new file mode 100644 index 0000000..da1d620 --- /dev/null +++ b/include/schema/pgSequence.h @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSequence.h PostgreSQL Sequence +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSEQUENCE_H +#define PGSEQUENCE_H + + +#include "pgSchema.h" + +class pgSequenceFactory : public pgSchemaObjFactory +{ +public: + pgSequenceFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetReplicatedIconId() + { + return replicatedIconId; + } +private: + int replicatedIconId; +}; +extern pgSequenceFactory sequenceFactory; + +class pgSequence : public pgSchemaObject +{ +public: + pgSequence(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgSequence(); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + void UpdateValues(); + wxLongLong GetLastValue() const + { + return lastValue; + } + wxLongLong GetNextValue() const + { + return nextValue; + } + wxLongLong GetMinValue() const + { + return minValue; + } + wxLongLong GetMaxValue() const + { + return maxValue; + } + wxLongLong GetCacheValue() const + { + return cacheValue; + } + wxLongLong GetIncrement() const + { + return increment; + } + bool GetCycled() const + { + return cycled; + } + bool GetCalled() const + { + return called; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxLongLong lastValue, nextValue, minValue, maxValue, cacheValue, increment; + bool cycled, called, isReplicated; +}; + +class pgSequenceCollection : public pgSchemaObjCollection +{ +public: + pgSequenceCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgServer.h b/include/schema/pgServer.h new file mode 100644 index 0000000..edf5e96 --- /dev/null +++ b/include/schema/pgServer.h @@ -0,0 +1,709 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgServer.h - PostgreSQL Server +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSERVER_H +#define PGSERVER_H + +#include "db/pgConn.h" +#include "pgCollection.h" + +class frmMain; +class pgServer; + +class pgServerFactory : public pgaFactory +{ +public: + pgServerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return WantSmallIcon() ? smallClosedId : closedId; + } + +protected: + int closedId, smallClosedId; +}; +extern pgServerFactory serverFactory; +#define DEFAULT_SSH_PORT 22 + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +class CSSHTunnelThread; +#endif + +class pgServer : public pgObject +{ +public: + pgServer(const wxString &newServer = wxT(""), const wxString &newHostAddr = wxT(""), const wxString &newDescription = wxT(""), + const wxString &newService = wxT(""), const wxString &newDatabase = wxT(""), const wxString &newUsername = wxT(""), int newPort = 5432, + bool storePwd = false, const wxString &newRolename = wxT(""), bool restore = true, int sslMode = 0, + const wxString &colour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX), const wxString &group = wxEmptyString, + bool sshTunnel = false, const wxString &newTunnelHost = wxEmptyString, const wxString &newTunnelUserName = wxEmptyString, bool authModePwd = true, + const wxString &newTunnelPassword = wxEmptyString, const wxString &newPublicKey = wxEmptyString, const wxString &newIdentityFile = wxEmptyString, + const int &sshPort = DEFAULT_SSH_PORT); + ~pgServer(); + int GetIconId(); + + wxString GetTypeName() const + { + return wxT("Server"); + } + wxString GetTranslatedMessage(int kindOfMessage) const; + int Connect(frmMain *form, bool askPassword = true, const wxString &pwd = wxEmptyString, bool forceStorePassword = false, bool askTunnelPassword = false); + bool Disconnect(frmMain *form); + void StorePassword(); + bool GetPasswordIsStored(); + void InvalidatePassword() + { + passwordValid = false; + } + + bool StartService(); + bool StopService(); + bool GetServerRunning(); + bool GetServerControllable(); + bool ReloadConfiguration(); + bool IsReplayPaused(); + bool PauseReplay(); + bool ResumeReplay(); + bool AddNamedRestorePoint(); + + pgServer *GetServer() const; + + wxString GetIdentifier() const; + wxString GetVersionString(); + wxString GetVersionNumber(); + OID GetLastSystemOID(); + wxString GetHostAddr() const + { + return hostaddr; + } + wxString GetService() const + { + return service; + } + wxString GetDatabaseName() const + { + return database; + } + wxString GetUsername() const + { + return username; + } + wxString GetPassword() const + { + return (password == wxEmptyString ? conn->GetPassword() : password); + } + bool GetStorePwd() const + { + return storePwd; + } + wxString GetRolename() const + { + return rolename; + } + bool GetRestore() const + { + return restore; + } + wxString GetLastError() const; + + bool GetDiscovered() const + { + return discovered; + } + void iSetDiscovered(const bool b) + { + discovered = b; + } + wxString GetServiceID() const + { + return serviceId; + } + void iSetServiceID(const wxString &s); + wxString GetDiscoveryID() const + { + return discoveryId; + } + void iSetDiscoveryID(const wxString &s) + { + discoveryId = s; + } + + bool GetCreatePrivilege() const + { + return createPrivilege; + } + void iSetCreatePrivilege(const bool b) + { + createPrivilege = b; + } + bool GetSuperUser() const + { + return superUser; + } + void iSetSuperUser(const bool b) + { + superUser = b; + } + bool GetCreateRole() const + { + return createRole; + } + void iSetCreateRole(const bool b) + { + createRole = b; + } + + bool GetInRecovery() const + { + return inRecovery; + } + void iSetInRecovery(const bool b) + { + inRecovery = b; + } + bool GetReplayPaused() const + { + return replayPaused; + } + void SetReplayPaused(const bool b) + { + replayPaused = b; + } + wxDateTime GetConfLoadedSince() + { + return confLoadedSince; + } + void iSetConfLoadedSince(const wxDateTime &d) + { + confLoadedSince = d; + } + wxString GetReceiveLoc() const + { + return receiveLoc; + } + void iSetReceiveLoc(const wxString &s) + { + receiveLoc = s; + } + wxString GetReplayLoc() const + { + return replayLoc; + } + void iSetReplayLoc(const wxString &s) + { + replayLoc = s; + } + wxString GetReplayTimestamp() const + { + return replayTimestamp; + } + void iSetReplayTimestamp(const wxString &s) + { + replayTimestamp = s; + } + + pgConn *CreateConn(wxString dbName = wxEmptyString, OID oid = 0, wxString applicationname = wxEmptyString); + + wxString GetLastDatabase() const + { + return lastDatabase; + } + void iSetLastDatabase(const wxString &s) + { + lastDatabase = s; + } + wxString GetLastSchema() const + { + return lastSchema; + } + void iSetLastSchema(const wxString &s) + { + lastSchema = s; + } + wxString GetDescription() const + { + return description; + } + void iSetDescription(const wxString &s) + { + description = s; + } + void iSetHostAddr(const wxString &s) + { + hostaddr = s; + } + + wxString GetDbRestriction() const + { + return dbRestriction; + } + void iSetDbRestriction(const wxString &s) + { + dbRestriction = s; + } + + long GetServerIndex() const + { + return serverIndex; + } + void iSetServerIndex(long l) + { + serverIndex = l; + } + wxString GetFullName(); + wxString GetFullIdentifier(); + int GetPort() const + { + return port; + } + int GetSSL() const + { + return ssl; + } + bool GetConnected() const + { + return connected; + } + void iSetService(const wxString &newVal) + { + service = newVal; + } + void iSetDatabase(const wxString &newVal) + { + database = newVal; + } + void iSetPort(int newval) + { + port = newval; + } + void iSetSSL(int newval) + { + ssl = newval; + } + void iSetUsername(const wxString &newVal) + { + username = newVal; + } + void iSetPassword(const wxString &newVal) + { + password = newVal; + } + void iSetStorePwd(const bool b) + { + storePwd = b; + } + void iSetRolename(const wxString &newVal) + { + rolename = newVal; + } + void iSetRestore(const bool b) + { + restore = b; + } + bool SetPassword(const wxString &newVal); + wxDateTime GetUpSince() + { + return upSince; + } + void iSetUpSince(const wxDateTime &d) + { + upSince = d; + } + void iSetColour(const wxString &s) + { + colour = s; + } + wxString GetColour() + { + return colour; + } + + void iSetGroup(const wxString &s) + { + group = s; + } + wxString GetGroup() + { + return group; + } + + bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv) + { + return conn->HasPrivilege(objTyp, objName, priv); + } + bool ExecuteVoid(const wxString &sql) + { + return conn->ExecuteVoid(sql); + } + wxString ExecuteScalar(const wxString &sql) + { + return conn->ExecuteScalar(sql); + } + pgSet *ExecuteSet(const wxString &sql) + { + return conn->ExecuteSet(sql); + } + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowHint(frmMain *form, bool force); + void ShowStatistics(frmMain *form, ctlListView *statistics); + wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/managing-databases"); + } + wxMenu *GetNewMenu(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) + { + return true; + } + bool GetCanHint(); + bool CanEdit() + { + return true; + } + bool CanDrop() + { + return true; + } + bool CanBackupGlobals() + { + return true; + } + bool HasStats() + { + return true; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + + pgConn *connection() + { + return conn; + } + + wxString GetSSLCert() const + { + return sslcert; + } + void SetSSLCert(const wxString &s) + { + sslcert = s; + } + wxString GetSSLKey() const + { + return sslkey; + } + void SetSSLKey(const wxString &s) + { + sslkey = s; + } + wxString GetSSLRootCert() const + { + return sslrootcert; + } + void SetSSLRootCert(const wxString &s) + { + sslrootcert = s; + } + wxString GetSSLCrl() const + { + return sslcrl; + } + void SetSSLCrl(const wxString &s) + { + sslcrl = s; + } + + bool GetSSLCompression() const + { + return sslcompression; + } + void iSetSSLCompression(const bool b) + { + sslcompression = b; + } + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + //SSH Tunnel + bool GetSSHTunnel() const + { + return sshTunnel; + } + void iSetSSHTunnel(const bool b) + { + sshTunnel = b; + } + bool GetAuthModePwd() const + { + return authModePwd; + } + void iSetAuthModePwd(const bool b) + { + authModePwd = b; + } + wxString GetLocalListenHost() const + { + return local_listenhost; + } + void SetLocalListenHost(const wxString &s) + { + local_listenhost = s; + } + int GetLocalListenPort() const + { + return local_listenport; + } + void SetLocalListenPort(int newVal) + { + local_listenport = newVal; + } + wxString GetTunnelHost() const + { + return tunnelHost; + } + void SetTunnelHost(const wxString &s) + { + tunnelHost = s; + } + wxString GetTunnelUserName() const + { + return tunnelUserName; + } + void SetTunnelUserName(const wxString &s) + { + tunnelUserName = s; + } + wxString GetTunnelPassword() const + { + return tunnelPassword; + } + void SetTunnelPassword(const wxString &s) + { + tunnelPassword = s; + } + wxString GetPublicKeyFile() const + { + return publicKeyFile; + } + void SetPublicKeyFile(const wxString &s) + { + publicKeyFile = s; + } + wxString GetIdentityFile() const + { + return identityFile; + } + void SetIdentityFile(const wxString &s) + { + identityFile = s; + } + int GetTunnelPort() const + { + return tunnelPort; + } + void iSetTunnelPort(const int newval) + { + tunnelPort = newval; + } +#endif + + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where = wxEmptyString); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + +private: + wxString passwordFilename(); + + pgConn *conn; + long serverIndex; + bool connected, passwordValid, autovacuumRunning; + wxString service, hostaddr, database, username, password, rolename, ver, error; + wxString lastDatabase, lastSchema, description, serviceId, discoveryId; + wxDateTime upSince; + int port, ssl; + bool storePwd, restore, discovered, createPrivilege, superUser, createRole; + OID lastSystemOID; + OID dbOid; + wxString versionNum; + wxString dbRestriction; + wxString colour; + wxString group; + wxString sslcert, sslkey, sslrootcert, sslcrl; + bool sslcompression; + bool sshTunnel; + + bool inRecovery, replayPaused; + wxString receiveLoc, replayLoc, replayTimestamp; + wxDateTime confLoadedSince; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + bool createSSHTunnel(); + + //SSH Tunnel + CSSHTunnelThread *tunnelObj; + bool authModePwd; + int local_listenport; + int tunnelPort; + wxString tunnelHost, tunnelUserName, tunnelPassword, publicKeyFile, identityFile, local_listenhost; +#endif + +#ifdef WIN32 + SC_HANDLE scmHandle; + SC_HANDLE serviceHandle; + wxArrayString GetDependentServices(SC_HANDLE handle); +#endif +}; + + +// collection of pgServer +class pgServerCollection : public pgCollection +{ +public: + pgServerCollection(pgaFactory *factory); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0) {}; +}; + + +/////////////////////////////////////////////// + + +class pgServerObjFactory : public pgaFactory +{ +public: + pgServerObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgaFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +// Object that lives under a server +class pgServerObject : public pgObject +{ +public: + pgServerObject(pgaFactory &factory, const wxString &newName = wxEmptyString) : pgObject(factory, newName) {} + pgServerObject(int newType, const wxString &newName) : pgObject(newType, newName) {} + + void iSetServer(pgServer *s) + { + server = s; + } + pgServer *GetServer() const + { + return server; + } + + void FillOwned(ctlTree *browser, ctlListView *referencedBy, const wxArrayString &dblist, const wxString &query); + + bool CanCreate(); + bool CanDrop(); + bool CanEdit() + { + return true; + } + +protected: + pgServer *server; +}; + + +// collection of pgServerObject +class pgServerObjCollection : public pgCollection +{ +public: + pgServerObjCollection(pgaFactory *factory, pgServer *server); + bool CanCreate(); +}; + +class addServerFactory : public actionFactory +{ +public: + addServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class startServiceFactory : public contextActionFactory +{ +public: + startServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class stopServiceFactory : public contextActionFactory +{ +public: + stopServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class connectServerFactory : public contextActionFactory +{ +public: + connectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class disconnectServerFactory : public contextActionFactory +{ +public: + disconnectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class reloadconfServiceFactory : public contextActionFactory +{ +public: + reloadconfServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class pausereplayServiceFactory : public contextActionFactory +{ +public: + pausereplayServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class resumereplayServiceFactory : public contextActionFactory +{ +public: + resumereplayServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class addnamedrestorepointServiceFactory : public contextActionFactory +{ +public: + addnamedrestorepointServiceFactory (menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgSubscription.h b/include/schema/pgSubscription.h new file mode 100644 index 0000000..a5d250c --- /dev/null +++ b/include/schema/pgSubscription.h @@ -0,0 +1,121 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgExtension.h PostgreSQL Extension +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGSUBSCRIPTION_H +#define PGSUBSCRIPTION_H + +#include "pgDatabase.h" + +class pgCollection; +class pgSubscriptionFactory : public pgDatabaseObjFactory +{ +public: + pgSubscriptionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgSubscriptionFactory subscriptionFactory; + +class pgSubscription : public pgDatabaseObject +{ +public: + pgSubscription(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + + wxString GetPubStr() const + { + return publications; + } + void iSetPubStr(const wxString &s) + { + publications = s; + } + wxString GetConnInfo() const + { + return conninfo; + } + void iSetSlotName(const wxString &s) { + slotname = s; + } + wxString GetSlotName() const + { + return slotname; + } + void iSetConnInfo(const wxString &s) + { + conninfo = s; + } + bool GetIsEnabled() const + { + return enabled; + } + void iSetIsEnabled(const bool b) + { + enabled = b; + } + wxString GetIsSyncCommit() const + { + return subsynccommit; + } + void iSetIsSyncCommit(const wxString &s) + { + subsynccommit = s; + } + wxString GetStrOper() const + { + wxString s = wxT(""); + s += wxT("enabled = ")+BoolToStr(GetIsEnabled()); + s += wxT(", synchronous_commit = ")+ subsynccommit; + s += wxT(", slot_name = "); + if (slotname.IsEmpty()) s += wxT("NONE"); + else s += wxT("'")+slotname+wxT("'"); + + //s += wxT(", slot_name = ")+ !slotname.IsEmpty() ? wxT("'")+slotname+wxT("'") : wxT("NONE"); + return s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return false; + } + bool HasReferences() + { + return false; + } + +private: + wxString conninfo,publications,slotname,subname,subsynccommit; + bool enabled; +}; + +class pgSubscriptionCollection : public pgDatabaseObjCollection +{ +public: + pgSubscriptionCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTable.h b/include/schema/pgTable.h new file mode 100644 index 0000000..f1f53a6 --- /dev/null +++ b/include/schema/pgTable.h @@ -0,0 +1,748 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTable.h PostgreSQL Table +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTABLE_H +#define PGTABLE_H + +#include "pgSchema.h" + + +enum +{ + REPLICATIONSTATUS_NONE = 0, + REPLICATIONSTATUS_SUBSCRIBED, + REPLICATIONSTATUS_REPLICATED, + REPLICATIONSTATUS_MULTIPLY_PUBLISHED +}; + + +class pgTableFactory : public pgSchemaObjFactory +{ +public: + pgTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetReplicatedIconId() + { + return replicatedIconId; + } + int GetPartitionsIconId() + { + return partitionsIconId; + } +private: + int replicatedIconId; + int partitionsIconId; +}; +extern pgTableFactory tableFactory; + +class slSet; +class pgTable : public pgSchemaObject +{ +public: + pgTable(pgSchema *newSchema, const wxString &newName = wxT("")); + pgTable(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxT("")); + ~pgTable(); + wxString GetTranslatedMessage(int kindOfMessage) const; + int GetIconId(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowHint(frmMain *form, bool force); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + int GetReplicationStatus(ctlTree *browser, wxString *clusterName = 0, long *setId = 0); + + bool GetHasOids() const + { + return hasOids; + } + void iSetHasOids(bool b) + { + hasOids = b; + } + bool GetUnlogged() const + { + return unlogged; + } + void iSetUnlogged(bool b) + { + unlogged = b; + } + wxString GetPrimaryKey() const + { + return primaryKey; + } + void iSetPrimaryKey(const wxString &s) + { + primaryKey = s; + } + wxString GetQuotedPrimaryKey() const + { + return quotedPrimaryKey; + } + void iSetQuotedPrimaryKey(const wxString &s) + { + quotedPrimaryKey = s; + } + wxString GetPrimaryKeyColNumbers() const + { + return primaryKeyColNumbers; + } + void iSetPrimaryKeyColNumbers(const wxString &s) + { + primaryKeyColNumbers = s; + } + wxString GetPrimaryKeyName() const + { + return primaryKeyName; + } + void iSetPrimaryKeyName(const wxString &s) + { + primaryKeyName = s; + } + wxString GetDistributionColNumbers() const + { + return distributionColNumbers; // for Greenplum + } + void iSetDistributionColNumbers(const wxString &s) + { + distributionColNumbers = s; // for Greenplum + if (s.Length() > 0) distributionIsRandom = false; + } + void iSetDistributionIsRandom() + { + distributionIsRandom = true; + } + double GetEstimatedRows() const + { + return estimatedRows; + } + void iSetEstimatedRows(const double d) + { + estimatedRows = d; + } + wxString GetTablespace() const + { + return tablespace; + }; + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + wxString GetRatio() const + { + return ratio; + }; + void iSetRatio(const wxString &newVal) + { + if (newVal==wxT("NaN")) ratio=wxEmptyString; else ratio = newVal; + + } + OID GetTablespaceOid() const + { + return tablespaceOid; + }; + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + wxString GetOfType() const + { + return ofType; + }; + void iSetOfType(const wxString &newVal) + { + ofType = newVal; + } + OID GetOfTypeOid() const + { + return ofTypeOid; + }; + void iSetOfTypeOid(const OID newVal) + { + ofTypeOid = newVal; + } + wxULongLong GetRows() const + { + return rows; + } + long GetInheritedTableCount() + { + if (inheritedTableCount < 0) UpdateInheritance(); + return inheritedTableCount; + } + wxString GetInheritedTables() + { + GetInheritedTableCount(); + return inheritedTables; + } + wxString GetQuotedInheritedTables() + { + GetInheritedTableCount(); + return quotedInheritedTables; + } + wxArrayString GetInheritedTablesOidList() + { + GetInheritedTableCount(); + return inheritedTablesOidList; + } + wxArrayString GetQuotedInheritedTablesList() + { + GetInheritedTableCount(); + return quotedInheritedTablesList; + } + wxString GetCoveringIndex(ctlTree *browser, const wxString &collist); + pgCollection *GetColumnCollection(ctlTree *browser); + pgCollection *GetConstraintCollection(ctlTree *browser); + bool GetHasSubclass() const + { + return hasSubclass; + } + void iSetHasSubclass(bool b) + { + hasSubclass = b; + } + void iSetIsReplicated(bool b) + { + isReplicated = b; + } + bool GetIsReplicated() const + { + return isReplicated; + } + void iSetTriggerCount(long l) + { + triggerCount = l; + } + int GetTriggerCount() const + { + return triggerCount; + } + bool EnableTriggers(const bool b); + void UpdateRows(); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool Truncate(bool cascaded); + bool ResetStats(); + bool CanView() + { + return true; + } + bool CanMaintenance() + { + return true; + } + bool CanBackup() + { + return true; + } + bool CanRestore() + { + return true; + } + bool WantDummyChild() + { + return true; + } + bool GetCanHint(); + bool GetShowExtendedStatistics() + { + return showExtendedStatistics; + } + void iSetShowExtendedStatistics(bool b) + { + showExtendedStatistics = b; + } + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + wxString GetAppendOnly() + { + return appendOnly; + } + void iSetAppendOnly(const wxString &s) + { + appendOnly = s; + } + wxString GetCompressLevel() + { + return compressLevel; + } + void iSetCompressLevel(const wxString &s) + { + compressLevel = s; + } + wxString GetOrientation() + { + return orientation; + } + void iSetOrientation(const wxString &s) + { + orientation = s; + } + wxString GetCompressType() + { + return compresstype; + } + void iSetCompressType(const wxString &s) + { + compresstype = s; + }; + wxString GetBlocksize() + { + return blocksize; + } + void iSetBlocksize(const wxString &s) + { + blocksize = s; + }; + wxString GetChecksum() + { + return checksum; + } + void iSetChecksum(const wxString &s) + { + checksum = s; + }; + wxString GetPartitionDef() + { + return partitionDef; + } + void iSetPartitionDef(const wxString &s) + { + partitionDef = s; + } + wxString GetPartKeyDef() + { + return partkeydef; + } + void iSetPartKeyDef(const wxString &s) + { + partkeydef = s; + } + wxString GetPartExp() + { + return partexp; + } + void iSetPartExp(const wxString &s) + { + partexp = s; + } + void iSetStatExt(const wxString &s) + { + statext = s; + } + wxString GetStatExt() + { + return statext; + } + + bool GetIsPartitioned() const + { + return isPartitioned || partitionDef.Length() > 0; + } + void iSetIsPartitioned(bool b) + { + isPartitioned = b; + } + + bool GetCustomAutoVacuumEnabled() + { + return !reloptions.IsEmpty(); + } + wxString GetRelOptions() + { + return reloptions; + } + void iSetRelOptions(const wxString &s) + { + reloptions = s; + } + int GetAutoVacuumEnabled() + { + return autovacuum_enabled; + } + void iSetAutoVacuumEnabled(int i) + { + autovacuum_enabled = i; + } + wxString GetAutoVacuumVacuumThreshold() + { + return autovacuum_vacuum_threshold; + } + void iSetAutoVacuumVacuumThreshold(const wxString &s) + { + autovacuum_vacuum_threshold = s; + } + wxString GetAutoVacuumVacuumScaleFactor() + { + return autovacuum_vacuum_scale_factor; + } + void iSetAutoVacuumVacuumScaleFactor(const wxString &s) + { + autovacuum_vacuum_scale_factor = s; + } + wxString GetAutoVacuumAnalyzeThreshold() + { + return autovacuum_analyze_threshold; + } + void iSetAutoVacuumAnalyzeThreshold(const wxString &s) + { + autovacuum_analyze_threshold = s; + } + wxString GetAutoVacuumAnalyzeScaleFactor() + { + return autovacuum_analyze_scale_factor; + } + void iSetAutoVacuumAnalyzeScaleFactor(const wxString &s) + { + autovacuum_analyze_scale_factor = s; + } + wxString GetAutoVacuumVacuumCostDelay() + { + return autovacuum_vacuum_cost_delay; + } + void iSetAutoVacuumVacuumCostDelay(const wxString &s) + { + autovacuum_vacuum_cost_delay = s; + } + wxString GetAutoVacuumVacuumCostLimit() + { + return autovacuum_vacuum_cost_limit; + } + void iSetAutoVacuumVacuumCostLimit(const wxString &s) + { + autovacuum_vacuum_cost_limit = s; + } + wxString GetAutoVacuumFreezeMinAge() + { + return autovacuum_freeze_min_age; + } + void iSetAutoVacuumFreezeMinAge(const wxString &s) + { + autovacuum_freeze_min_age = s; + } + wxString GetAutoVacuumFreezeMaxAge() + { + return autovacuum_freeze_max_age; + } + void iSetAutoVacuumFreezeMaxAge(const wxString &s) + { + autovacuum_freeze_max_age = s; + } + wxString GetAutoVacuumFreezeTableAge() + { + return autovacuum_freeze_table_age; + } + void iSetAutoVacuumFreezeTableAge(const wxString &s) + { + autovacuum_freeze_table_age = s; + } + bool GetHasToastTable() + { + return hasToastTable; + } + void iSetHasToastTable(bool b) + { + hasToastTable = b; + } + + /* TOAST TABLE autovacuum settings */ + bool GetToastCustomAutoVacuumEnabled() + { + return !toast_reloptions.IsEmpty(); + } + wxString GetToastRelOptions() + { + return toast_reloptions; + } + void iSetToastRelOptions(const wxString &s) + { + toast_reloptions = s; + } + int GetToastAutoVacuumEnabled() + { + return toast_autovacuum_enabled; + } + void iSetToastAutoVacuumEnabled(int i) + { + toast_autovacuum_enabled = i; + } + wxString GetToastAutoVacuumVacuumThreshold() + { + return toast_autovacuum_vacuum_threshold; + } + void iSetToastAutoVacuumVacuumThreshold(const wxString &s) + { + toast_autovacuum_vacuum_threshold = s; + } + wxString GetToastAutoVacuumVacuumScaleFactor() + { + return toast_autovacuum_vacuum_scale_factor; + } + void iSetToastAutoVacuumVacuumScaleFactor(const wxString &s) + { + toast_autovacuum_vacuum_scale_factor = s; + } + wxString GetToastAutoVacuumVacuumCostDelay() + { + return toast_autovacuum_vacuum_cost_delay; + } + void iSetToastAutoVacuumVacuumCostDelay(const wxString &s) + { + toast_autovacuum_vacuum_cost_delay = s; + } + wxString GetToastAutoVacuumVacuumCostLimit() + { + return toast_autovacuum_vacuum_cost_limit; + } + void iSetToastAutoVacuumVacuumCostLimit(const wxString &s) + { + toast_autovacuum_vacuum_cost_limit = s; + } + wxString GetToastAutoVacuumFreezeMinAge() + { + return toast_autovacuum_freeze_min_age; + } + void iSetToastAutoVacuumFreezeMinAge(const wxString &s) + { + toast_autovacuum_freeze_min_age = s; + } + wxString GetToastAutoVacuumFreezeMaxAge() + { + return toast_autovacuum_freeze_max_age; + } + void iSetToastAutoVacuumFreezeMaxAge(const wxString &s) + { + toast_autovacuum_freeze_max_age = s; + } + wxString GetToastAutoVacuumFreezeTableAge() + { + return toast_autovacuum_freeze_table_age; + } + void iSetToastAutoVacuumFreezeTableAge(const wxString &s) + { + toast_autovacuum_freeze_table_age = s; + } + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + bool HasPgstattuple(); + + virtual wxMenu *GetNewMenu(); + virtual wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + wxString GetInsertSql(ctlTree *browser); + wxString GetUpdateSql(ctlTree *browser); + wxString GetDeleteSql(ctlTree *browser); + wxString GetHelpPage(bool forCreate) const; + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + void iSetTriggersEnabled(ctlTree *browser, bool enable); + +private: + void UpdateInheritance(); + bool GetVacuumHint(); + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); + void AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory); + void AppendStuffNoSql(wxString &sql, ctlTree *browser, pgaFactory &factory); + + void Init(); + + wxULongLong rows; + double estimatedRows; + + bool hasToastTable; + /* + * Three possible values: + * 0 - Disabled + * 1 - Enabled + * 2 - GUC Setting + */ + int autovacuum_enabled, toast_autovacuum_enabled; + wxString reloptions, toast_reloptions; + + wxString fillFactor, autovacuum_vacuum_threshold, + autovacuum_vacuum_scale_factor, autovacuum_analyze_threshold, + autovacuum_analyze_scale_factor, autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, autovacuum_freeze_min_age, + autovacuum_freeze_max_age, autovacuum_freeze_table_age; + wxString appendOnly; + wxString compressLevel; + wxString orientation; // "row" or "column" + wxString compresstype; + wxString blocksize; + wxString checksum; + wxString partkeydef; // partition feature 10 version + wxString partexp; // partition feature 10 version + wxString partitionDef; + wxString statext; + bool isPartitioned; + bool hasOids, unlogged, hasSubclass, rowsCounted, isReplicated, showExtendedStatistics, distributionIsRandom; + + wxString toast_fillFactor, toast_autovacuum_vacuum_threshold, + toast_autovacuum_vacuum_scale_factor, toast_autovacuum_vacuum_cost_delay, + toast_autovacuum_vacuum_cost_limit, toast_autovacuum_freeze_min_age, + toast_autovacuum_freeze_max_age, toast_autovacuum_freeze_table_age; + + long inheritedTableCount, triggerCount; + wxString quotedInheritedTables, inheritedTables, primaryKey, quotedPrimaryKey, + primaryKeyName, primaryKeyColNumbers, tablespace, ratio, + distributionColNumbers, ofType; + wxArrayString quotedInheritedTablesList, inheritedTablesOidList; + + slSet *replicationSet; + OID tablespaceOid; + OID ofTypeOid; +}; + + +class pgTableObject : public pgSchemaObject +{ +public: + pgTableObject(pgTable *newTable, pgaFactory &factory, const wxString &newName = wxT("")) + : pgSchemaObject(newTable->GetSchema(), factory, newName) + { + table = newTable; + } + virtual pgTable *GetTable() const + { + return table; + } + OID GetTableOid() const + { + return table->GetOid(); + } + wxString GetTableOidStr() const + { + return NumToStr(table->GetOid()) + wxT("::oid"); + } + +protected: + pgTable *table; +}; + + +class pgTableCollection : public pgSchemaObjCollection +{ +public: + pgTableCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + +class pgTableObjCollection : public pgSchemaObjCollection +{ +public: + pgTableObjCollection(pgaFactory *factory, pgTable *_table) + : pgSchemaObjCollection(factory, _table->GetSchema()) + { + iSetOid(_table->GetOid()); + table = _table; + } + virtual pgTable *GetTable() const + { + return table; + } + bool CanCreate(); + +protected: + pgTable *table; +}; + +class pgTableObjFactory : public pgSchemaObjFactory +{ +public: + pgTableObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgSchemaObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class countRowsFactory : public contextActionFactory +{ +public: + countRowsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class executePgstattupleFactory : public contextActionFactory +{ +public: + executePgstattupleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +class disableAllTriggersFactory : public contextActionFactory +{ +public: + disableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class enableAllTriggersFactory : public contextActionFactory +{ +public: + enableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class truncateFactory : public contextActionFactory +{ +public: + truncateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class truncateCascadedFactory : public contextActionFactory +{ +public: + truncateCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class resetTableStatsFactory : public contextActionFactory +{ +public: + resetTableStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgTablespace.h b/include/schema/pgTablespace.h new file mode 100644 index 0000000..e095028 --- /dev/null +++ b/include/schema/pgTablespace.h @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTablespace.h - PostgreSQL Tablespace +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTABLESPACE_H +#define PGTABLESPACE_H + + +#include "pgServer.h" + +class pgTablespaceFactory : public pgServerObjFactory +{ +public: + pgTablespaceFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTablespaceFactory tablespaceFactory; + + +class pgTablespace : public pgServerObject +{ +public: + pgTablespace(const wxString &newName = wxT("")); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where = wxEmptyString); + + wxString GetLocation() const + { + return location; + }; + void iSetLocation(const wxString &newVal) + { + location = newVal; + } + wxArrayString &GetVariables() + { + return variables; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool RequireDropConfirm() + { + return true; + } + pgConn *connection(); + + wxString GetSql(ctlTree *browser); + void MoveTablespace(frmMain *form); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return true; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString location; + wxArrayString variables; +}; + + +class pgTablespaceCollection : public pgServerObjCollection +{ +public: + pgTablespaceCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + +class moveTablespaceFactory : public contextActionFactory +{ +public: + moveTablespaceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/schema/pgTextSearchConfiguration.h b/include/schema/pgTextSearchConfiguration.h new file mode 100644 index 0000000..1d116ae --- /dev/null +++ b/include/schema/pgTextSearchConfiguration.h @@ -0,0 +1,109 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchConfiguration.h PostgreSQL Text Search Configuration +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSCONFIGURATION_H +#define PG_TSCONFIGURATION_H + + +#include "pgSchema.h" + + +class pgTextSearchConfigurationFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchConfigurationFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchConfigurationFactory textSearchConfigurationFactory; + +class pgTextSearchConfiguration : public pgSchemaObject +{ +public: + pgTextSearchConfiguration(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchConfiguration(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetParser() const + { + return parser; + } + void iSetParser(const wxString &s) + { + parser = s; + } + wxString GetCopy() const + { + return copy; + } + void iSetCopy(const wxString &s) + { + copy = s; + } + OID GetParserOid() const + { + return parserOid; + } + void iSetParserOid(const OID o) + { + parserOid = o; + } + wxString GetParserOidStr() const + { + return NumToStr(GetParserOid()) + wxT("::oid"); + } + wxArrayString &GetTokens() + { + return tokens; + } + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsconfig"); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString parser, copy; + OID parserOid; + wxArrayString tokens; +}; + +class pgTextSearchConfigurationCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchConfigurationCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTextSearchDictionary.h b/include/schema/pgTextSearchDictionary.h new file mode 100644 index 0000000..7b6a696 --- /dev/null +++ b/include/schema/pgTextSearchDictionary.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchDictionary.h PostgreSQL Text Search Dictionary +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSDICTIONARY_H +#define PG_TSDICTIONARY_H + + +#include "pgSchema.h" + + +class pgTextSearchDictionaryFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchDictionaryFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchDictionaryFactory textSearchDictionaryFactory; + +class pgTextSearchDictionary : public pgSchemaObject +{ +public: + pgTextSearchDictionary(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchDictionary(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetTemplate() const + { + return tmpl; + } + void iSetTemplate(const wxString &s) + { + tmpl = s; + } + wxString GetOptions() const + { + return options; + } + void iSetOptions(const wxString &s) + { + options = s; + } + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsdictionary"); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString tmpl, options; +}; + +class pgTextSearchDictionaryCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchDictionaryCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTextSearchParser.h b/include/schema/pgTextSearchParser.h new file mode 100644 index 0000000..ae46c40 --- /dev/null +++ b/include/schema/pgTextSearchParser.h @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchParser.h PostgreSQL Text Search Parser +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSPARSER_H +#define PG_TSPARSER_H + + +#include "pgSchema.h" + + +class pgTextSearchParserFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchParserFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchParserFactory textSearchParserFactory; + +class pgTextSearchParser : public pgSchemaObject +{ +public: + pgTextSearchParser(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchParser(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtsparser"); + } + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetStart() const + { + return start; + } + void iSetStart(const wxString &s) + { + start = s; + } + wxString GetGettoken() const + { + return gettoken; + } + void iSetGettoken(const wxString &s) + { + gettoken = s; + } + wxString GetEnd() const + { + return end; + } + void iSetEnd(const wxString &s) + { + end = s; + } + wxString GetLextypes() const + { + return lextypes; + } + void iSetLextypes(const wxString &s) + { + lextypes = s; + } + wxString GetHeadline() const + { + return headline; + } + void iSetHeadline(const wxString &s) + { + headline = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString start, gettoken, end, lextypes, headline; +}; + +class pgTextSearchParserCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchParserCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTextSearchTemplate.h b/include/schema/pgTextSearchTemplate.h new file mode 100644 index 0000000..8ebda16 --- /dev/null +++ b/include/schema/pgTextSearchTemplate.h @@ -0,0 +1,91 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchTemplate.h PostgreSQL Text Search Template +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PG_TSTEMPLATE_H +#define PG_TSTEMPLATE_H + + +#include "pgSchema.h" + + +class pgTextSearchTemplateFactory : public pgSchemaObjFactory +{ +public: + pgTextSearchTemplateFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTextSearchTemplateFactory textSearchTemplateFactory; + +class pgTextSearchTemplate : public pgSchemaObject +{ +public: + pgTextSearchTemplate(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTextSearchTemplate(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + virtual wxString GetHelpPage(bool forCreate) const + { + return wxT("pg/sql-createtstemplate"); + } + bool CanDropCascaded() + { + return GetSchema()->GetMetaType() != PGM_CATALOG; + } + + wxString GetInit() const + { + return init; + } + void iSetInit(const wxString &s) + { + init = s; + } + wxString GetLexize() const + { + return lexize; + } + void iSetLexize(const wxString &s) + { + lexize = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString init, lexize; +}; + +class pgTextSearchTemplateCollection : public pgSchemaObjCollection +{ +public: + pgTextSearchTemplateCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgTrigger.h b/include/schema/pgTrigger.h new file mode 100644 index 0000000..ec36666 --- /dev/null +++ b/include/schema/pgTrigger.h @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTrigger.h PostgreSQL Trigger +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTRIGGER_H +#define PGTRIGGER_H + +#include "pgTable.h" + +class pgFunction; + +class pgTriggerObject : public pgSchemaObject +{ +public: + pgTriggerObject(pgSchema *newSchema, pgaFactory &factory, const wxString &newName = wxEmptyString) : pgSchemaObject(newSchema, factory, newName) {} + + wxString GetFormattedDefinition(); + wxString GetDefinition() const + { + return definition; + } + void iSetDefinition(const wxString &s) + { + definition = s; + } + +protected: + wxString definition; +}; + + + +class pgTriggerFactory : public pgSchemaObjFactory +{ +public: + pgTriggerFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + + int GetClosedIconId() + { + return closedId; + } + +protected: + int closedId; +}; +extern pgTriggerFactory triggerFactory; + + +class pgTrigger : public pgTriggerObject +{ +public: + pgTrigger(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgTrigger(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + wxString GetFireWhen() const; + wxString GetEvent() const; + wxString GetForEach() const; + wxString GetFunction() const + { + return function; + } + void iSetFunction(const wxString &s) + { + function = s; + } + void iSetArguments(const wxString &s) + { + arguments = s; + } + wxString GetArguments() const + { + return arguments; + } + void iSetWhen(const wxString &s) + { + when = s; + } + wxString GetWhen() const + { + return when; + } + bool GetIsConstraint() const + { + return isconstraint; + } + void SetIsConstraint(const bool b) + { + isconstraint = b; + } + bool GetDeferrable() const + { + return deferrable; + } + void iSetDeferrable(const bool b) + { + deferrable = b; + } + bool GetDeferred() const + { + return deferred; + } + void iSetDeferred(const bool b) + { + deferred = b; + } + wxString GetLanguage() const + { + return language; + } + void iSetLanguage(const wxString &s) + { + language = s; + } + wxString GetSource() const + { + return source; + } + void iSetSource(const wxString &s) + { + source = s; + } + wxString GetReferences() const + { + return references; + } + void iSetReferences(const wxString &s) + { + references = s; + } + + long GetTriggerType() const + { + return triggerType; + } + void iSetTriggerType(const long l) + { + triggerType = l; + } + bool GetEnabled() const + { + return enabled; + } + void SetEnabled(ctlTree *browser, const bool b); + void iSetEnabled(const bool b) + { + enabled = b; + } + void iSetTriggerFunction(pgFunction *fkt) + { + triggerFunction = fkt; + } + wxString GetQuotedFullTable() const + { + return quotedFullTable; + } + void iSetQuotedFullTable(const wxString &s) + { + quotedFullTable = s; + } + OID GetFunctionOid() const + { + return functionOid; + } + void iSetFunctionOid(const OID d) + { + functionOid = d; + } + OID GetRelationOid() const + { + return relationOid; + } + void iSetRelationOid(const OID d) + { + relationOid = d; + } + wxString GetQuotedColumns() const + { + return quotedColumns; + } + wxString GetColumns() const + { + return columns; + } + wxArrayString GetColumnList() const + { + return columnList; + } + long GetColumnCount() const + { + return columnCount; + } + void iSetColumnCount(const long l) + { + columnCount = l; + } + void iSetParentIsTable(const bool b) + { + parentistable = b; + } + bool GetParentIsTable() + { + return parentistable; + } + + void SetDirty(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + bool CanRestore() + { + return true; + } + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + bool IsUpToDate(); + +protected: + void ReadColumnDetails(); + +private: + wxString function, quotedFullTable, arguments, when, language, source, columns, quotedColumns,references; + wxArrayString columnList; + long columnCount; + OID functionOid, relationOid; + long triggerType; + bool enabled, parentistable, isconstraint, deferrable, deferred; + pgFunction *triggerFunction; +}; + + +class pgTriggerCollection : public pgSchemaObjCollection +{ +public: + pgTriggerCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +class enabledisableTriggerFactory : public contextActionFactory +{ +public: + enabledisableTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); + bool CheckChecked(pgObject *obj); +}; + +#endif diff --git a/include/schema/pgType.h b/include/schema/pgType.h new file mode 100644 index 0000000..9d7461c --- /dev/null +++ b/include/schema/pgType.h @@ -0,0 +1,347 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgType.h PostgreSQL Type +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGTYPE_H +#define PGTYPE_H + +#include "pgSchema.h" + +// Note: This must match the radio buttons on dlgType +enum TYPE_CLASS +{ + TYPE_COMPOSITE = 0, + TYPE_ENUM, + TYPE_EXTERNAL, + TYPE_RANGE +}; + +class pgTypeFactory : public pgSchemaObjFactory +{ +public: + pgTypeFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgTypeFactory typeFactory; + +class pgType : public pgSchemaObject +{ +public: + pgType(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgType(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + wxString GetAlias() const + { + return alias; + } + void iSetAlias(const wxString &s) + { + alias = s; + } + wxString GetInputFunction() const + { + return inputFunction; + } + void iSetInputFunction(const wxString &s) + { + inputFunction = s; + } + wxString GetOutputFunction() const + { + return outputFunction; + } + void iSetOutputFunction(const wxString &s) + { + outputFunction = s; + } + wxString GetReceiveFunction() const + { + return receiveFunction; + } + void iSetReceiveFunction(const wxString &s) + { + receiveFunction = s; + } + wxString GetSendFunction() const + { + return sendFunction; + } + void iSetSendFunction(const wxString &s) + { + sendFunction = s; + } + wxString GetTypmodinFunction() const + { + return typmodinFunction; + } + void iSetTypmodinFunction(const wxString &s) + { + typmodinFunction = s; + } + wxString GetTypmodoutFunction() const + { + return typmodoutFunction; + } + void iSetTypmodoutFunction(const wxString &s) + { + typmodoutFunction = s; + } + wxString GetAnalyzeFunction() const + { + return analyzeFunction; + } + void iSetAnalyzeFunction(const wxString &s) + { + analyzeFunction = s; + } + wxString GetCategory() const + { + return category; + } + void iSetCategory(const wxString &s) + { + category = s; + } + bool GetPrefered() const + { + return prefered; + } + void iSetPrefered(const bool b) + { + prefered = b; + } + wxString GetDefault() const + { + return defaultVal; + } + void iSetDefault(const wxString &s) + { + defaultVal = s; + } + wxString GetElement() + { + return element; + } + void iSetElement(const wxString &s) + { + element = s; + } + wxString GetDelimiter() const + { + return delimiter; + } + void iSetDelimiter(const wxString &s) + { + delimiter = s; + } + wxString GetAlignment() const + { + return alignment; + } + void iSetAlignment(const wxString &s) + { + alignment = s; + } + wxString GetStorage() const + { + return storage; + } + void iSetStorage(const wxString &s) + { + storage = s; + } + long GetInternalLength() const + { + return internalLength; + } + void iSetInternalLength(const long l) + { + internalLength = l; + } + bool GetPassedByValue() const + { + return passedByValue; + } + void iSetPassedByValue(const bool b) + { + passedByValue = b; + } + int GetTypeClass() const + { + return typeClass; + } + void iSetTypeClass(const int c) + { + typeClass = c; + } + bool GetIsRecordType() const + { + return isRecordType; + } + void iSetIsRecordType(const bool b) + { + isRecordType = b; + } + bool GetCollatable() const + { + return collatable; + } + void iSetCollatable(const bool b) + { + collatable = b; + } + void iSetRelOid(const OID d) + { + relOid = d; + } + const wxArrayString &GetTypesArray() + { + return typesArray; + } + const wxArrayString &GetCollationsArray() + { + return collationsArray; + } + const wxArrayString &GetLabelArray() + { + return labelArray; + } + wxString GetTypesList() const + { + return typesList; + } + wxString GetQuotedTypesList() const + { + return quotedTypesList; + } + wxString GetLabelList() const + { + return labelList; + } + wxString GetQuotedLabelList() const + { + return quotedLabelList; + } + bool GetSystemObject() const + { + return pgSchemaObject::GetSystemObject() || isRecordType; + } + OID GetSubtypeFunction() const + { + return rngsubtype; + } + void iSetSubtypeFunction(const OID d) + { + rngsubtype = d; + } + wxString GetSubtypeFunctionStr() const + { + return rngsubtypestr; + } + void iSetSubtypeFunctionStr(const wxString s) + { + rngsubtypestr = s; + } + OID GetCollationFunction() const + { + return rngcollation; + } + void iSetCollationFunction(const OID d) + { + rngcollation = d; + } + wxString GetCollationFunctionStr() const + { + return rngcollationstr; + } + void iSetCollationFunctionStr(const wxString s) + { + rngcollationstr = s; + } + OID GetSubtypeOpClassFunction() const + { + return rngsubopc; + } + void iSetSubtypeOpClassFunction(const OID d) + { + rngsubopc = d; + } + wxString GetSubtypeOpClassFunctionStr() const + { + return rngsubopcstr; + } + void iSetSubtypeOpClassFunctionStr(const wxString s) + { + rngsubopcstr = s; + } + wxString GetCanonical() const + { + return rngcanonical; + } + void iSetCanonical(const wxString s) + { + rngcanonical = s; + } + wxString GetSubtypeDiff() const + { + return rngsubdiff; + } + void iSetSubtypeDiff(const wxString s) + { + rngsubdiff = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString alias, inputFunction, outputFunction, defaultVal, element, delimiter, alignment, storage, + typesList, quotedTypesList, labelList, quotedLabelList, sendFunction, receiveFunction, + typmodinFunction, typmodoutFunction, analyzeFunction, category; + wxArrayString typesArray, labelArray, collationsArray; + long internalLength; + int typeClass; + bool passedByValue, isRecordType, collatable, prefered; + int rngsubtype, rngcollation, rngsubopc; + wxString rngsubtypestr, rngcollationstr, rngsubopcstr, rngcanonical, rngsubdiff; + OID relOid; +}; + +class pgTypeCollection : public pgSchemaObjCollection +{ +public: + pgTypeCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgUser.h b/include/schema/pgUser.h new file mode 100644 index 0000000..69b22ff --- /dev/null +++ b/include/schema/pgUser.h @@ -0,0 +1,135 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUser.h - PostgreSQL User +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGUSER_H +#define PGUSER_H + +#include "pgServer.h" + +class pgUserFactory : public pgServerObjFactory +{ +public: + pgUserFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgUserFactory userFactory; + + +// Class declarations +class pgUser : public pgServerObject +{ +public: + pgUser(const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + // User Specific + bool GetSystemObject() const + { + return userId < 100; + } + long GetUserId() const + { + return userId; + } + void iSetUserId(const long l) + { + userId = l; + } + wxDateTime GetAccountExpires() const + { + return accountExpires; + } + void iSetAccountExpires(const wxDateTime &dt) + { + accountExpires = dt; + } + wxString GetPassword() const + { + return password; + } + void iSetPassword(const wxString &s) + { + password = s; + } + bool GetCreateDatabase() const + { + return createDatabase; + } + void iSetCreateDatabase(const bool b) + { + createDatabase = b; + } + bool GetSuperuser() const + { + return superuser; + } + void iSetSuperuser(const bool b) + { + superuser = b; + } + bool GetUpdateCatalog() const + { + return updateCatalog; + } + void iSetUpdateCatalog(const bool b) + { + updateCatalog = b; + } + wxArrayString &GetGroupsIn() + { + return groupsIn; + } + wxArrayString &GetConfigList() + { + return configList; + } + + + // Tree object creation + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where); + + // virtual methods + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString password; + wxDateTime accountExpires; + bool createDatabase, superuser, updateCatalog; + wxArrayString groupsIn; + wxArrayString configList; + long userId; +}; + +class pgUserCollection : public pgServerObjCollection +{ +public: + pgUserCollection(pgaFactory *factory, pgServer *sv); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgUserMapping.h b/include/schema/pgUserMapping.h new file mode 100644 index 0000000..1ec508e --- /dev/null +++ b/include/schema/pgUserMapping.h @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUserMapping.h PostgreSQL User Mapping +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGUSERMAPPING_H +#define PGUSERMAPPING_H + +#include "pgForeignServer.h" + +class pgCollection; +class pgUserMappingFactory : public pgForeignServerObjFactory +{ +public: + pgUserMappingFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); +}; +extern pgUserMappingFactory userMappingFactory; + + +class pgUserMapping : public pgForeignServerObject +{ +public: + pgUserMapping(pgForeignServer *newForeignServer, const wxString &newName = wxT("")); + wxString GetTranslatedMessage(int kindOfMessage) const; + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return true; + } + bool CanCreate() + { + return true; + } + + wxString GetUsr() const + { + return user; + } + void iSetUsr(const wxString &s) + { + user = s; + } + wxString GetOptions() const + { + return options; + } + wxString GetCreateOptions(); + void iSetOptions(const wxString &s) + { + options = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + +private: + wxString user, options; +}; + +class pgUserMappingObjFactory : public pgForeignServerObjFactory +{ +public: + pgUserMappingObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) + : pgForeignServerObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +class pgUserMappingCollection : public pgCollection +{ +public: + pgUserMappingCollection(pgaFactory *factory, pgUserMapping *um); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif diff --git a/include/schema/pgView.h b/include/schema/pgView.h new file mode 100644 index 0000000..0dd14b7 --- /dev/null +++ b/include/schema/pgView.h @@ -0,0 +1,401 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgView.h PostgreSQL View +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGVIEW_H +#define PGVIEW_H + +#include "pgRule.h" + +class pgCollection; + +class pgViewFactory : public pgSchemaObjFactory +{ +public: + pgViewFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetMaterializedIconId() + { + return WantSmallIcon() ? smallMaterializedId : materializedId; + } + +protected: + int materializedId, smallMaterializedId; + +}; +extern pgViewFactory viewFactory; + + +class pgView : public pgRuleObject +{ +public: + pgView(pgSchema *newSchema, const wxString &newName = wxT("")); + ~pgView(); + + int GetIconId(); + + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + bool CanDropCascaded() + { + return !GetSystemObject() && pgSchemaObject::CanDrop(); + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + bool CanCreate() + { + return GetSchema()->CanCreate(); + } + bool CanView() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + bool HasInsertRule() + { + return hasInsertRule; + } + bool HasUpdateRule() + { + return hasUpdateRule; + } + bool HasDeleteRule() + { + return hasDeleteRule; + } + wxString GetSecurityBarrier() + { + return security_barrier; + } + void iSetSecurityBarrier(const wxString &s) + { + security_barrier = s; + } + + wxString GetTablespace() const + { + return tablespace; + } + void iSetTablespace(const wxString &newVal) + { + tablespace = newVal; + } + OID GetTablespaceOid() const + { + return tablespaceOid; + } + void iSetTablespaceOid(const OID newVal) + { + tablespaceOid = newVal; + } + + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + wxString GetSelectSql(ctlTree *browser); + wxString GetInsertSql(ctlTree *browser); + wxString GetUpdateSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + void RefreshMatView(bool concurrently); + + bool HasStats() + { + return false; + } + bool HasDepends() + { + return true; + } + bool HasReferences() + { + return true; + } + + void ShowHint(frmMain *form, bool force); + bool GetCanHint() + { + return true; + }; + + bool IsUpToDate(); + + wxString GetFillFactor() + { + return fillFactor; + } + void iSetFillFactor(const wxString &s) + { + fillFactor = s; + } + + wxString GetIsPopulated() + { + return isPopulated; + } + void iSetIsPopulated(const wxString &s) + { + isPopulated = s; + } + + wxString GetCheckOption() + { + return check_option; + } + void iSetCheckOption(const wxString &s) + { + check_option = s; + } + + bool GetCustomAutoVacuumEnabled() + { + return !reloptions.IsEmpty(); + } + wxString GetRelOptions() + { + return reloptions; + } + void iSetRelOptions(const wxString &s) + { + reloptions = s; + } + int GetAutoVacuumEnabled() + { + return autovacuum_enabled; + } + void iSetAutoVacuumEnabled(int i) + { + autovacuum_enabled = i; + } + wxString GetAutoVacuumVacuumThreshold() + { + return autovacuum_vacuum_threshold; + } + void iSetAutoVacuumVacuumThreshold(const wxString &s) + { + autovacuum_vacuum_threshold = s; + } + wxString GetAutoVacuumVacuumScaleFactor() + { + return autovacuum_vacuum_scale_factor; + } + void iSetAutoVacuumVacuumScaleFactor(const wxString &s) + { + autovacuum_vacuum_scale_factor = s; + } + wxString GetAutoVacuumAnalyzeThreshold() + { + return autovacuum_analyze_threshold; + } + void iSetAutoVacuumAnalyzeThreshold(const wxString &s) + { + autovacuum_analyze_threshold = s; + } + wxString GetAutoVacuumAnalyzeScaleFactor() + { + return autovacuum_analyze_scale_factor; + } + void iSetAutoVacuumAnalyzeScaleFactor(const wxString &s) + { + autovacuum_analyze_scale_factor = s; + } + wxString GetAutoVacuumVacuumCostDelay() + { + return autovacuum_vacuum_cost_delay; + } + void iSetAutoVacuumVacuumCostDelay(const wxString &s) + { + autovacuum_vacuum_cost_delay = s; + } + wxString GetAutoVacuumVacuumCostLimit() + { + return autovacuum_vacuum_cost_limit; + } + void iSetAutoVacuumVacuumCostLimit(const wxString &s) + { + autovacuum_vacuum_cost_limit = s; + } + wxString GetAutoVacuumFreezeMinAge() + { + return autovacuum_freeze_min_age; + } + void iSetAutoVacuumFreezeMinAge(const wxString &s) + { + autovacuum_freeze_min_age = s; + } + wxString GetAutoVacuumFreezeMaxAge() + { + return autovacuum_freeze_max_age; + } + void iSetAutoVacuumFreezeMaxAge(const wxString &s) + { + autovacuum_freeze_max_age = s; + } + wxString GetAutoVacuumFreezeTableAge() + { + return autovacuum_freeze_table_age; + } + void iSetAutoVacuumFreezeTableAge(const wxString &s) + { + autovacuum_freeze_table_age = s; + } + bool GetHasToastTable() + { + return hasToastTable; + } + void iSetHasToastTable(bool b) + { + hasToastTable = b; + } + + /* TOAST TABLE autovacuum settings */ + bool GetToastCustomAutoVacuumEnabled() + { + return !toast_reloptions.IsEmpty(); + } + wxString GetToastRelOptions() + { + return toast_reloptions; + } + void iSetToastRelOptions(const wxString &s) + { + toast_reloptions = s; + } + int GetToastAutoVacuumEnabled() + { + return toast_autovacuum_enabled; + } + void iSetToastAutoVacuumEnabled(int i) + { + toast_autovacuum_enabled = i; + } + wxString GetToastAutoVacuumVacuumThreshold() + { + return toast_autovacuum_vacuum_threshold; + } + void iSetToastAutoVacuumVacuumThreshold(const wxString &s) + { + toast_autovacuum_vacuum_threshold = s; + } + wxString GetToastAutoVacuumVacuumScaleFactor() + { + return toast_autovacuum_vacuum_scale_factor; + } + void iSetToastAutoVacuumVacuumScaleFactor(const wxString &s) + { + toast_autovacuum_vacuum_scale_factor = s; + } + wxString GetToastAutoVacuumVacuumCostDelay() + { + return toast_autovacuum_vacuum_cost_delay; + } + void iSetToastAutoVacuumVacuumCostDelay(const wxString &s) + { + toast_autovacuum_vacuum_cost_delay = s; + } + wxString GetToastAutoVacuumVacuumCostLimit() + { + return toast_autovacuum_vacuum_cost_limit; + } + void iSetToastAutoVacuumVacuumCostLimit(const wxString &s) + { + toast_autovacuum_vacuum_cost_limit = s; + } + wxString GetToastAutoVacuumFreezeMinAge() + { + return toast_autovacuum_freeze_min_age; + } + void iSetToastAutoVacuumFreezeMinAge(const wxString &s) + { + toast_autovacuum_freeze_min_age = s; + } + wxString GetToastAutoVacuumFreezeMaxAge() + { + return toast_autovacuum_freeze_max_age; + } + void iSetToastAutoVacuumFreezeMaxAge(const wxString &s) + { + toast_autovacuum_freeze_max_age = s; + } + wxString GetToastAutoVacuumFreezeTableAge() + { + return toast_autovacuum_freeze_table_age; + } + void iSetToastAutoVacuumFreezeTableAge(const wxString &s) + { + toast_autovacuum_freeze_table_age = s; + } + + void iSetMaterializedView(const bool matView) + { + materializedView = matView; + } + + bool GetMaterializedView() const + { + return materializedView; + } + +private: + wxString GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM); + void AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory); + bool IsMaterializedView(ctlTree *browser); + bool hasInsertRule, hasUpdateRule, hasDeleteRule, materializedView; + wxString security_barrier; + + int autovacuum_enabled, toast_autovacuum_enabled; + wxString reloptions, toast_reloptions; + + wxString fillFactor, autovacuum_vacuum_threshold, + autovacuum_vacuum_scale_factor, autovacuum_analyze_threshold, + autovacuum_analyze_scale_factor, autovacuum_vacuum_cost_delay, + autovacuum_vacuum_cost_limit, autovacuum_freeze_min_age, + autovacuum_freeze_max_age, autovacuum_freeze_table_age; + + wxString toast_fillFactor, toast_autovacuum_vacuum_threshold, + toast_autovacuum_vacuum_scale_factor, toast_autovacuum_vacuum_cost_delay, + toast_autovacuum_vacuum_cost_limit, toast_autovacuum_freeze_min_age, + toast_autovacuum_freeze_max_age, toast_autovacuum_freeze_table_age; + + wxString tablespace, isPopulated, check_option; + bool hasToastTable; + OID tablespaceOid; + +}; + +class pgViewCollection : public pgSchemaObjCollection +{ +public: + pgViewCollection(pgaFactory *factory, pgSchema *sch); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +class refreshMatViewFactory : public contextActionFactory +{ +public: + refreshMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +class refreshConcurrentlyMatViewFactory : public contextActionFactory +{ +public: + refreshConcurrentlyMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif diff --git a/include/slony/dlgRepCluster.h b/include/slony/dlgRepCluster.h new file mode 100644 index 0000000..e0c6d65 --- /dev/null +++ b/include/slony/dlgRepCluster.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepCluster.h - Slony-I cluster property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPCLUSTERPROP +#define __DLG_REPCLUSTERPROP + +#include "dlg/dlgProperty.h" + + +class slCluster; +class sysProcess; +class wxProcessEvent; + +class dlgRepClusterBase : public dlgProperty +{ +public: + dlgRepClusterBase(pgaFactory *factory, frmMain *frame, const wxString &dlgName, slCluster *cl, pgDatabase *obj); + ~dlgRepClusterBase(); + pgObject *GetObject(); + int Go(bool modal); + +private: + virtual void OnChangeCluster(wxCommandEvent &ev) = 0; + +protected: + void OnChangeServer(wxCommandEvent &ev); + void OnChangeDatabase(wxCommandEvent &ev); + + bool AddScript(wxString &sql, const wxString &filename); + slCluster *cluster; + wxTreeItemId servers; + pgServer *remoteServer; + pgConn *remoteConn; + wxString remoteVersion; + wxString createScript; + + DECLARE_EVENT_TABLE() +}; + + +class dlgRepCluster : public dlgRepClusterBase +{ +public: + dlgRepCluster(pgaFactory *factory, frmMain *frame, slCluster *cl, pgDatabase *obj); + int Go(bool modal); + wxString GetHelpPage() const; + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + +private: + void OnOK(wxCommandEvent &ev); + void OnChangeJoin(wxCommandEvent &ev); + void OnChangeCluster(wxCommandEvent &ev); + void OnEndProcess(wxProcessEvent &event); + + bool CopyTable(pgConn *from, pgConn *to, const wxString &table); + sysProcess *process; + + bool SlonyMaximumVersion(const wxString &series, long minor); + + wxArrayLong usedNodes; + wxString clusterBackup; + wxString slonyVersion; + + + DECLARE_EVENT_TABLE() +}; + + + +class dlgRepClusterUpgrade : public dlgRepClusterBase +{ +public: + dlgRepClusterUpgrade(pgaFactory *factory, frmMain *frame, slCluster *cl); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-install#upgrade"); + } + + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + +private: + void OnChangeCluster(wxCommandEvent &ev); + + wxString version; + wxString sql; + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/slony/dlgRepListen.h b/include/slony/dlgRepListen.h new file mode 100644 index 0000000..d1395f9 --- /dev/null +++ b/include/slony/dlgRepListen.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepListen.h - Slony-I listen property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPLISTENPROP +#define __DLG_REPLISTENPROP + +#include "slony/dlgRepProperty.h" + +class slNode; +class slListen; + +class dlgRepListen : public dlgRepProperty +{ +public: + dlgRepListen(pgaFactory *factory, frmMain *frame, slListen *l, slNode *n); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-path#listen"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + slListen *listen; + slNode *node; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepNode.h b/include/slony/dlgRepNode.h new file mode 100644 index 0000000..67f6d45 --- /dev/null +++ b/include/slony/dlgRepNode.h @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepNode.h - Slony-I Node property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPNODEPROP +#define __DLG_REPNODEPROP + +#include "slony/dlgRepProperty.h" + + +class slCluster; +class slNode; + +class dlgRepNode : public dlgRepProperty +{ +public: + dlgRepNode(pgaFactory *factory, frmMain *frame, slNode *node, slCluster *c); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-install#node"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + slNode *node; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/slony/dlgRepPath.h b/include/slony/dlgRepPath.h new file mode 100644 index 0000000..5aceed8 --- /dev/null +++ b/include/slony/dlgRepPath.h @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepPath.h - Slony-I path property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPPATHPROP +#define __DLG_REPPATHPROP + +#include "slony/dlgRepProperty.h" + +class slNode; +class slPath; + +class dlgRepPath : public dlgRepProperty +{ +public: + dlgRepPath(pgaFactory *factory, frmMain *frame, slPath *p, slNode *n); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-path"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + slPath *path; + slNode *node; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepProperty.h b/include/slony/dlgRepProperty.h new file mode 100644 index 0000000..bd3ab23 --- /dev/null +++ b/include/slony/dlgRepProperty.h @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSet.h - Slony-I property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPPROP +#define __DLG_REPPROP + +#include "dlg/dlgProperty.h" + +class slCluster; + +class dlgRepProperty : public dlgProperty +{ +public: + dlgRepProperty(pgaFactory *f, frmMain *frame, slCluster *c, const wxString &resName); + +protected: + slCluster *cluster; +}; + + +#endif diff --git a/include/slony/dlgRepSequence.h b/include/slony/dlgRepSequence.h new file mode 100644 index 0000000..9bbe14c --- /dev/null +++ b/include/slony/dlgRepSequence.h @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSequence.h - Slony-I sequence property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPSEQUENCEPROP +#define __DLG_REPSEQUENCEPROP + +#include "slony/dlgRepProperty.h" + +class slSet; +class slSequence; + +class dlgRepSequence : public dlgRepProperty +{ +public: + dlgRepSequence(pgaFactory *factory, frmMain *frame, slSequence *tab, slSet *s); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set#sequence"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + void OnChangeSel(wxCommandEvent &ev); + + slSequence *sequence; + slSet *set; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepSet.h b/include/slony/dlgRepSet.h new file mode 100644 index 0000000..302fd12 --- /dev/null +++ b/include/slony/dlgRepSet.h @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSet.h - Slony-I Set property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPSETPROP +#define __DLG_REPSETPROP + +#include "slony/dlgRepProperty.h" + +class slCluster; +class slSet; + +class dlgRepSet : public dlgRepProperty +{ +public: + dlgRepSet(pgaFactory *factory, frmMain *frame, slSet *set, slCluster *c); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject() + { + return (pgObject *)set; + } + +private: + slSet *set; + + DECLARE_EVENT_TABLE() +}; + + +class dlgRepSetMerge : public dlgRepProperty +{ +public: + dlgRepSetMerge(pgaFactory *factory, frmMain *frame, slSet *set); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-functions"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *GetObject() + { + return (pgObject *)set; + } + pgObject *CreateObject(pgCollection *collection) + { + return 0; + } + +private: + slSet *set; + + DECLARE_EVENT_TABLE() +}; + +class dlgRepSetMove : public dlgRepProperty +{ +public: + dlgRepSetMove(pgaFactory *f, frmMain *frame, slSet *set); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-functions"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *GetObject() + { + return (pgObject *)set; + } + pgObject *CreateObject(pgCollection *collection) + { + return 0; + } + +private: + slSet *set; + + DECLARE_EVENT_TABLE() +}; + +#endif diff --git a/include/slony/dlgRepSubscription.h b/include/slony/dlgRepSubscription.h new file mode 100644 index 0000000..c734f6c --- /dev/null +++ b/include/slony/dlgRepSubscription.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSubscription.h - Slony-I Subscription property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPSUBSCPROP +#define __DLG_REPSUBSCPROP + +#include "slony/dlgRepProperty.h" + +class slSubscription; +class slSet; + +class dlgRepSubscription : public dlgRepProperty +{ +public: + dlgRepSubscription(pgaFactory *factory, frmMain *frame, slSubscription *sub, slSet *s); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set#subscription"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + slSubscription *subscription; + slSet *set; + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/dlgRepTable.h b/include/slony/dlgRepTable.h new file mode 100644 index 0000000..65b3c67 --- /dev/null +++ b/include/slony/dlgRepTable.h @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepTable.h - Slony-I table property +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __DLG_REPTABLEPROP +#define __DLG_REPTABLEPROP + +#include "slony/dlgRepProperty.h" + +class slSet; +class slTable; + +class dlgRepTable : public dlgRepProperty +{ +public: + dlgRepTable(pgaFactory *factory, frmMain *frame, slTable *tab, slSet *s); + int Go(bool modal); + wxString GetHelpPage() const + { + return wxT("slony-set#table"); + } + + void CheckChange(); + wxString GetSql(); + pgObject *CreateObject(pgCollection *collection); + pgObject *GetObject(); + +private: + + slTable *table; + slSet *set; + long lastTableSelection; + + void LoadTrigger(OID relid); + + void OnChangeTable(wxCommandEvent &ev); + void OnChangeTableSel(wxCommandEvent &ev); + + DECLARE_EVENT_TABLE() +}; + + +#endif diff --git a/include/slony/module.mk b/include/slony/module.mk new file mode 100644 index 0000000..b1fff4c --- /dev/null +++ b/include/slony/module.mk @@ -0,0 +1,33 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/slony/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/slony/dlgRepCluster.h \ + include/slony/dlgRepListen.h \ + include/slony/dlgRepNode.h \ + include/slony/dlgRepPath.h \ + include/slony/dlgRepProperty.h \ + include/slony/dlgRepSequence.h \ + include/slony/dlgRepSet.h \ + include/slony/dlgRepSubscription.h \ + include/slony/dlgRepTable.h \ + include/slony/slCluster.h \ + include/slony/slListen.h \ + include/slony/slNode.h \ + include/slony/slPath.h \ + include/slony/slSequence.h \ + include/slony/slSet.h \ + include/slony/slSubscription.h \ + include/slony/slTable.h + +EXTRA_DIST += \ + include/slony/module.mk + diff --git a/include/slony/slCluster.h b/include/slony/slCluster.h new file mode 100644 index 0000000..d15407f --- /dev/null +++ b/include/slony/slCluster.h @@ -0,0 +1,226 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slCluster.h PostgreSQL Slony-I Cluster +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLCLUSTER_H +#define SLCLUSTER_H + +#include "schema/pgDatabase.h" + +class frmMain; +class RemoteConn; +class slNode; + + +WX_DECLARE_OBJARRAY(RemoteConn, RemoteConnArray); + + +class pgaSlClusterFactory : public pgDatabaseObjFactory +{ +public: + pgaSlClusterFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern pgaSlClusterFactory slClusterFactory; + + +class slCluster : public pgDatabaseObject +{ +public: + slCluster(const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + static pgObject *ReadObjects(pgCollection *coll, ctlTree *browser); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool ClusterMinimumVersion(int major, int minor); + + void iSetSchemaPrefix(const wxString &s) + { + schemaPrefix = s; + } + wxString GetSchemaPrefix() const + { + return schemaPrefix; + } + void iSetLocalNodeID(long l) + { + localNodeID = l; + } + long GetLocalNodeID() + { + return localNodeID; + } + void iSetLocalNodeName(const wxString &s) + { + localNodeName = s; + } + wxString GetLocalNodeName() const + { + return localNodeName; + } + void iSetAdminNodeID(long l) + { + adminNodeID = l; + } + long GetAdminNodeID() + { + return adminNodeID; + } + void iSetAdminNodeName(const wxString &s) + { + adminNodeName = s; + } + wxString GetAdminNodeName() const + { + return adminNodeName; + } + void iSetClusterVersion(const wxString &s) + { + clusterVersion = s; + } + wxString GetClusterVersion() const + { + return clusterVersion; + } + long GetSlonPid(); + + slNode *GetLocalNode(ctlTree *browser); + + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + pgConn *GetNodeConn(frmMain *form, long nodeId, bool create = true); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + wxString schemaPrefix; + wxString localNodeName, adminNodeName; + wxString clusterVersion; + long localNodeID, adminNodeID; + slNode *localNode; + + RemoteConnArray remoteConns; +}; + + +class slClusterCollection : public pgDatabaseObjCollection +{ +public: + slClusterCollection(pgaFactory *factory, pgDatabase *db); + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +// Slony-I object +class slObject : public pgDatabaseObject +{ +public: + slObject(slCluster *_slCluster, pgaFactory &factory, const wxString &newName = wxT("")); + slCluster *GetCluster() + { + return cluster; + } + + void iSetSlId(long i) + { + slId = i; + } + long GetSlId() const + { + return slId; + } + +private: + slCluster *cluster; + long slId; +}; + + +// Collection of Slony-I objects +class slObjCollection : public pgDatabaseObjCollection +{ +public: + slObjCollection(pgaFactory *factory, slCluster *_cluster); + + slCluster *GetCluster() + { + return cluster; + } + long GetSlId() const + { + return slId; + } + void iSetSlId(long l) + { + slId = l; + } + +private: + slCluster *cluster; + long slId; +}; + +class slObjFactory : public pgDatabaseObjFactory +{ +public: + slObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class clusterActionFactory : public contextActionFactory +{ +public: + clusterActionFactory(menuFactoryList *list) : contextActionFactory(list) {} + bool CheckEnable(pgObject *obj); +}; + + +class slonyRestartFactory : public clusterActionFactory +{ +public: + slonyRestartFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class slonyUpgradeFactory : public clusterActionFactory +{ +public: + slonyUpgradeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); +}; + + +class slonyFailoverFactory : public clusterActionFactory +{ +public: + slonyFailoverFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +#endif + + diff --git a/include/slony/slListen.h b/include/slony/slListen.h new file mode 100644 index 0000000..ad729a7 --- /dev/null +++ b/include/slony/slListen.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slListen.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLLISTEN_H +#define SLLISTEN_H + +#include "slony/slNode.h" + + +class slListenFactory : public slNodeObjFactory +{ +public: + slListenFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slListenFactory listenFactory; + + +class slListen : public slNodeObject +{ +public: + slListen(slNode *n, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + long GetProviderId() const + { + return providerId; + } + void iSetProviderId(long l) + { + providerId = l; + } + wxString GetProviderName() const + { + return providerName; + } + void iSetProviderName(const wxString &s) + { + providerName = s; + } + wxString GetOriginName() const + { + return originName; + } + void iSetOriginName(const wxString &s) + { + originName = s; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + long providerId; + wxString providerName, originName; +}; + +class slListenCollection : public slNodeObjCollection +{ +public: + slListenCollection(pgaFactory *factory, slNode *nd) : slNodeObjCollection(factory, nd) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/slony/slNode.h b/include/slony/slNode.h new file mode 100644 index 0000000..bef1d3c --- /dev/null +++ b/include/slony/slNode.h @@ -0,0 +1,155 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slNode.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLNODE_H +#define SLNODE_H + +#include "slony/slCluster.h" + + +class slNodeFactory : public slObjFactory +{ +public: + slNodeFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetLocalIconId() + { + return localIconId; + } + int GetDisabledIconId() + { + return disabledIconId; + } + +private: + int localIconId, disabledIconId; +}; +extern slNodeFactory nodeFactory; + + +class slNode : public slObject +{ +public: + slNode(slCluster *_cluster, const wxString &newName = wxT("")); + + int GetIconId(); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + void ShowStatistics(frmMain *form, ctlListView *statistics); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool CanDrop(); + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + long GetOutstandingAcks(); + bool CheckAcksAndContinue(wxFrame *frame); + + bool GetActive() const + { + return active; + } + void iSetActive(bool b) + { + active = b; + } + bool GetSpool() const + { + return spool; + } + void iSetSpool(bool b) + { + spool = b; + } + wxString GetConnInfo() const + { + return connInfo; + } + void iSetConnInfo(const wxString s) + { + connInfo = s; + } + long GetPid() + { + return pid; + } + bool WaitForEvent(long evNode); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool active, spool; + long pid; + wxString connInfo; +}; + + +class slNodeCollection : public slObjCollection +{ +public: + slNodeCollection(pgaFactory *factory, slCluster *cl) : slObjCollection(factory, cl) {} + wxString GetTranslatedMessage(int kindOfMessage) const; + void ShowStatistics(frmMain *form, ctlListView *statistics); +}; + +////////////////////////////////////////// + +// Object under a Slony-I node +class slNodeObject : public slObject +{ +public: + slNodeObject(slNode *n, pgaFactory &factory, const wxString &newName = wxT("")); + slNode *GetNode() const + { + return node; + } + +private: + slNode *node; +}; + +// Collection of node objects +class slNodeObjCollection : public slObjCollection +{ +public: + slNodeObjCollection(pgaFactory *factory, slNode *n); + slNode *GetNode() + { + return node; + } + +private: + slNode *node; +}; + + +class slNodeObjFactory : public slObjFactory +{ +public: + slNodeObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img = 0) : slObjFactory(tn, ns, nls, img) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + + +#endif + diff --git a/include/slony/slPath.h b/include/slony/slPath.h new file mode 100644 index 0000000..ea5713a --- /dev/null +++ b/include/slony/slPath.h @@ -0,0 +1,75 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slPath.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLPATH_H +#define SLPATH_H + + +#include "slony/slNode.h" + + +class slPathFactory : public slNodeObjFactory +{ +public: + slPathFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slPathFactory pathFactory; + + +class slPath : public slNodeObject +{ +public: + slPath(slNode *n, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + static pgObject *ReadObjects(slNodeCollection *coll, ctlTree *browser); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + void iSetConnInfo(const wxString &s) + { + connInfo = s; + } + wxString GetConnInfo() const + { + return connInfo; + } + void iSetConnRetry(long l) + { + connRetry = l; + } + long GetConnRetry() + { + return connRetry; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + long connRetry; + wxString connInfo; +}; + +class slPathCollection : public slNodeObjCollection +{ +public: + slPathCollection(pgaFactory *factory, slNode *nd) : slNodeObjCollection(factory, nd) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + + +#endif + diff --git a/include/slony/slSequence.h b/include/slony/slSequence.h new file mode 100644 index 0000000..6cff281 --- /dev/null +++ b/include/slony/slSequence.h @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSequence.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLSEQUENCE_H +#define SLSEQUENCE_H + +#include "schema/pgDatabase.h" +#include "slony/slSet.h" + +class slSlSequenceFactory : public slSetObjFactory +{ +public: + slSlSequenceFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slSlSequenceFactory slSequenceFactory; + + +class slSequence : public slSetObject +{ +public: + slSequence(slSet *set, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool GetActive() const + { + return active; + } + void iSetActive(bool b) + { + active = b; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool active; +}; + +class slSlSequenceCollection : public slSetObjCollection +{ +public: + slSlSequenceCollection(pgaFactory *factory, slSet *set) : slSetObjCollection(factory, set) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/slony/slSet.h b/include/slony/slSet.h new file mode 100644 index 0000000..c1b412f --- /dev/null +++ b/include/slony/slSet.h @@ -0,0 +1,189 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSet.h PostgreSQL Slony-I Set +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLSET_H +#define SLSET_H + +#include "slony/slCluster.h" + + +class slSetFactory : public slObjFactory +{ +public: + slSetFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetExportedIconId() + { + return exportedIconId; + } + +protected: + int exportedIconId; +}; +extern slSetFactory setFactory; + + +class slSet : public slObject +{ +public: + slSet(slCluster *_cluster, const wxString &newName = wxT("")); + + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool CanDrop(); + bool RequireDropConfirm() + { + return true; + } + bool WantDummyChild() + { + return true; + } + + long GetOriginId() const + { + return originId; + } + void iSetOriginId(long l) + { + originId = l; + } + wxString GetOriginNode() const + { + return originNode; + } + void iSetOriginNode(const wxString s) + { + originNode = s; + } + long GetSubscriptionCount() + { + return subscriptionCount; + } + void iSetSubscriptionCount(long l) + { + subscriptionCount = l; + } + + wxString GetLockXXID(); + bool Lock(); + bool Unlock(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxMenu *GetNewMenu(); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + + void ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh); + void ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh); + void ShowStatistics(pgCollection *collection, ctlListView *statistics); + +private: + long subscriptionCount; + long originId; + wxString originNode; +}; + + +class slSetCollection : public slObjCollection +{ +public: + slSetCollection(pgaFactory *factory, slCluster *cl) : slObjCollection(factory, cl) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +// Object in a Slony-I set +class slSetObject : public slObject +{ +public: + slSetObject(slSet *s, pgaFactory &factory, const wxString &newName = wxT("")); + slSet *GetSet() + { + return set; + } + + bool CanDrop(); + bool CanCreate(); + +private: + slSet *set; +}; + + +// Collection of set objects +class slSubscription; +class slSetObjCollection : public slObjCollection +{ +public: + slSetObjCollection(pgaFactory *factory, slSet *_set); + bool CanCreate(); + + slSet *GetSet() + { + return set; + } + +private: + slSet *set; + slSubscription *subscription; +}; + + +class slSetObjFactory : public slObjFactory +{ +public: + slSetObjFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm = 0) : slObjFactory(tn, ns, nls, img, imgSm) {} + virtual pgCollection *CreateCollection(pgObject *obj); +}; + +class slonyMoveSetFactory : public contextActionFactory +{ +public: + slonyMoveSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class slonyMergeSetFactory : public contextActionFactory +{ +public: + slonyMergeSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class slonyLockSetFactory : public contextActionFactory +{ +public: + slonyLockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + + +class slonyUnlockSetFactory : public contextActionFactory +{ +public: + slonyUnlockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar); + wxWindow *StartDialog(frmMain *form, pgObject *obj); + bool CheckEnable(pgObject *obj); +}; + +#endif + + diff --git a/include/slony/slSubscription.h b/include/slony/slSubscription.h new file mode 100644 index 0000000..4784f5c --- /dev/null +++ b/include/slony/slSubscription.h @@ -0,0 +1,132 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSubscription.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLSUBSCRIPTION_H +#define SLSUBSCRIPTION_H + +#include "slony/slSet.h" + + +class slSubscriptionFactory : public slSetObjFactory +{ +public: + slSubscriptionFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); + int GetExportedIconId() + { + return exportedIconId; + } + +protected: + int exportedIconId; +}; +extern slSubscriptionFactory slsubscriptionFactory; + + +class slSubscription : public slSetObject +{ +public: + slSubscription(slSet *set, const wxString &newName = wxT("")); + + int GetIconId(); + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool WantDummyChild(); + bool RequireDropConfirm() + { + return true; + } + + bool GetActive() const + { + return active; + } + void iSetActive(bool b) + { + active = b; + } + bool GetForward() const + { + return forward; + } + void iSetForward(bool b) + { + forward = b; + } + wxString GetProviderNode() const + { + return providerNode; + } + void iSetProviderNode(const wxString &s) + { + providerNode = s; + } + wxString GetReceiverNode() const + { + return receiverNode; + } + void iSetReceiverNode(const wxString &s) + { + receiverNode = s; + } + long GetProviderId() const + { + return providerId; + } + void iSetProviderId(long l) + { + providerId = l; + } + long GetReceiverId() const + { + return receiverId; + } + void iSetReceiverId(long l) + { + receiverId = l; + } + bool GetIsSubscribed() + { + return isSubscribed; + } + void iSetIsSubscribed(bool b) + { + isSubscribed = b; + } + + + + bool CanCreate(); + bool CanDrop(); + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool active, forward, isSubscribed; + long providerId, receiverId; + wxString providerNode, receiverNode; +}; + +class slSubscriptionCollection : public slSetObjCollection +{ +public: + slSubscriptionCollection(pgaFactory *factory, slSet *set) : slSetObjCollection(factory, set) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/slony/slTable.h b/include/slony/slTable.h new file mode 100644 index 0000000..a6298f3 --- /dev/null +++ b/include/slony/slTable.h @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slTable.h PostgreSQL Slony-I Node +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SLTABLE_H +#define SLTABLE_H + +#include "slony/slSet.h" + +class slSlTableFactory : public slSetObjFactory +{ +public: + slSlTableFactory(); + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + virtual pgCollection *CreateCollection(pgObject *obj); +}; +extern slSlTableFactory slTableFactory; + + +class slTable : public slSetObject +{ +public: + slTable(slSet *set, const wxString &newName = wxT("")); + + void ShowTreeDetail(ctlTree *browser, frmMain *form = 0, ctlListView *properties = 0, ctlSQLBox *sqlPane = 0); + + wxString GetTranslatedMessage(int kindOfMessage) const; + + bool GetAltered() const + { + return altered; + } + void iSetAltered(bool b) + { + altered = b; + } + wxString GetIndexName() const + { + return indexName; + } + void iSetIndexName(const wxString s) + { + indexName = s; + } + const wxArrayString &GetTriggers() + { + return triggers; + } + + bool DropObject(wxFrame *frame, ctlTree *browser, bool cascaded); + wxString GetSql(ctlTree *browser); + pgObject *Refresh(ctlTree *browser, const wxTreeItemId item); + +private: + bool altered; + wxString indexName; + wxArrayString triggers; +}; + +class slSlTableCollection : public slSetObjCollection +{ +public: + slSlTableCollection(pgaFactory *factory, slSet *set) : slSetObjCollection(factory, set) {} + wxString GetTranslatedMessage(int kindOfMessage) const; +}; + +#endif + diff --git a/include/utils/csvfiles.h b/include/utils/csvfiles.h new file mode 100644 index 0000000..c9c7ef6 --- /dev/null +++ b/include/utils/csvfiles.h @@ -0,0 +1,53 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// csvfiles.h - CSV file parsing +// +////////////////////////////////////////////////////////////////////////// + +#ifndef CSVFILES_H +#define CSVFILES_H + +// PostgreSQL and GPDB now support CSV format logs. +// So, we need a way to parse the CSV files into lines, and lines into tokens (fields). + +#include + +class CSVTokenizer : public wxObject +{ +public: + CSVTokenizer(const wxString &str): m_string(str), m_pos(0) { } + + bool HasMoreTokens() const; + + // Get the next token (CSV field). Will return empty string if !HasMoreTokens() + wxString GetNextToken(); + +protected: + + const wxString m_string; // the string we tokenize into fields + size_t m_pos; // the current position in m_string +}; + +class CSVLineTokenizer : public wxObject +{ +public: + CSVLineTokenizer(const wxString &str): m_string(str), m_pos(0) { } + + bool HasMoreLines() const; + + // Get the next line. Will return empty string if !HasMoreLines(). + // partial is set "true" if the last line returned was not a complete + // line (no newline char at end). + wxString GetNextLine(bool &partial); + +protected: + + const wxString m_string; // the string we tokenize into lines + size_t m_pos; // the current position in m_string +}; +#endif diff --git a/include/utils/factory.h b/include/utils/factory.h new file mode 100644 index 0000000..d5b62e5 --- /dev/null +++ b/include/utils/factory.h @@ -0,0 +1,237 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// factory.h - Object classes factory +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FACTORY_H +#define FACTORY_H + +// wxWindows headers +#include + +#include "frm/menu.h" + +#ifdef WIN32 +#ifndef __GNUC__ +#pragma warning(disable:4183) +#endif +#endif + +class pgObject; +class frmMain; +class dlgProperty; +class ctlTree; +class pgCollection; +class pgSchema; +class pgaCollectionFactory; + + +class pgaFactory +{ +public: + virtual dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) = 0; + virtual pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString) + { + return 0; + } + virtual pgCollection *CreateCollection(pgObject *obj) = 0; + virtual bool IsCollection() + { + return false; + } + virtual void AppendMenu(wxMenu *menu); + bool IsCollectionFor(pgaFactory &f) + { + return f.GetCollectionFactory() == (pgaCollectionFactory *)this; + } + bool WantSmallIcon(); + + static pgaFactory *GetFactory(int id); + static pgaFactory *GetFactory(const wxString &name); + static pgaFactory *GetFactoryByMetaType(const int type); + int GetId() + { + return id; + } + int GetMetaType(); + wxChar *GetTypeName() + { + return typeName; + } + wxChar *GetNewString() + { + return newString; + } + wxChar *GetNewLongString() + { + return newLongString; + } + pgaCollectionFactory *GetCollectionFactory() + { + return collectionFactory; + } + + int GetIconId(); + static void RegisterMenu(wxWindow *w, wxObjectEventFunction func); + const wxImage &GetImage() const + { + return image; + } + + static void RealizeImages(); + +protected: + pgaFactory(const wxChar *tn = 0, const wxChar *ns = 0, const wxChar *nls = 0, wxImage *img = 0, wxImage *imgSm = 0); + + int addIcon(wxImage *img); + + int id, metaType; + wxChar *typeName; + wxChar *newString, *newLongString; + int iconId, smallIconId; + wxImage image; + + pgaCollectionFactory *collectionFactory; + friend class pgaCollectionFactory; +}; + + +class pgaCollectionFactory : public pgaFactory +{ +public: + pgaCollectionFactory(pgaFactory *f, const wxChar *tn = 0, wxImage *img = 0, wxImage *imgSm = 0); + wxChar *GetItemTypeName() + { + return itemFactory->GetTypeName(); + } + pgaFactory *GetItemFactory() + { + return itemFactory; + } + pgObject *CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr = wxEmptyString); + +protected: + virtual bool IsCollection() + { + return true; + } + dlgProperty *CreateDialog(frmMain *frame, pgObject *node, pgObject *parent); + virtual pgCollection *CreateCollection(pgObject *obj) + { + return 0; + }; + + pgaFactory *itemFactory; +}; + + +class actionFactory; +class menuFactory; +class menuFactoryList : public wxArrayPtrVoid +{ +public: + ~menuFactoryList(); + + void CheckMenu(pgObject *obj, wxMenuBar *menubar, ctlMenuToolbar *toolbar); + void AppendEnabledMenus(wxMenuBar *menuBar, wxMenu *treeContextMenu); + actionFactory *GetFactory(int id, bool actionOnly = true); + void RegisterMenu(wxWindow *w, wxObjectEventFunction func); + void EnableSubmenu(wxMenuBar *menubar, int id); + +private: + void Add(menuFactory *f) + { + wxArrayPtrVoid::Add(f); + } + friend class menuFactory; +}; + + +class menuFactory +{ +public: + virtual ~menuFactory(); + virtual bool IsAction() + { + return false; + } + virtual bool IsSubmenu() + { + return false; + } + +protected: + menuFactory(menuFactoryList *list); +}; + + +class actionFactory : public menuFactory +{ +public: + virtual bool IsAction() + { + return true; + } + virtual wxWindow *StartDialog(frmMain *form, pgObject *obj) = 0; + virtual bool CheckEnable(pgObject *obj) + { + return true; + } + virtual bool CheckChecked(pgObject *obj) + { + return true; + } + bool GetContext() + { + return context; + } + int GetId() + { + return id; + } + +protected: + actionFactory(menuFactoryList *list); + + int id; + bool context; + + friend class menuFactoryList; +}; + + +class contextActionFactory : public actionFactory +{ +protected: + contextActionFactory(menuFactoryList *list) : actionFactory(list) + { + context = true; + } +}; + +class submenuFactory : public contextActionFactory +{ +public: + submenuFactory(menuFactoryList *list) : contextActionFactory(list) {}; + wxWindow *StartDialog(frmMain *form, pgObject *obj) + { + return 0; + }; + virtual bool IsSubmenu() + { + return true; + } +}; + +class separatorFactory : public menuFactory +{ +public: + separatorFactory(menuFactoryList *list) : menuFactory(list) {} +}; +#endif diff --git a/include/utils/favourites.h b/include/utils/favourites.h new file mode 100644 index 0000000..5fb4666 --- /dev/null +++ b/include/utils/favourites.h @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// favourites.h - Query favourites +// +////////////////////////////////////////////////////////////////////////// + +#ifndef FAVOURITES_H +#define FAVOURITES_H + +#include +#include + +#include +#include + +class queryFavouriteItem +{ +public: + queryFavouriteItem(const wxString newtitle, const wxString newcontents); + + wxString GetTitle() + { + return title; + }; + void SetTitle(const wxString &newtitle) + { + if (!newtitle.IsEmpty()) title = newtitle; + }; + + int GetId() + { + return id; + }; + wxString GetContents() + { + return contents; + }; + + wxTreeItemId &GetTreeId() + { + return treeid; + }; + void SetTreeId(const wxTreeItemId &newtreeid) + { + treeid = newtreeid; + }; + + void AppendToMenu(wxMenu *menu, int newid); +protected: + int id; + wxString title, contents; + wxTreeItemId treeid; +}; + + +WX_DEFINE_ARRAY_PTR(queryFavouriteItem *, queryFavouriteArray); +class queryFavouriteFolder : public queryFavouriteItem +{ +public: + queryFavouriteFolder(wxString title = wxT("")); + queryFavouriteFolder(xmlTextReaderPtr reader, wxString title); + + int AppendAllToMenu(wxMenu *menu, int startid); + void AppendAllToTree(wxTreeCtrl *tree, const wxTreeItemId &parent, bool onlyfolders); + bool DeleteTreeItem(const wxTreeItemId &treeitem); + + queryFavouriteItem *FindFavourite(int id); + queryFavouriteItem *FindFavourite(const wxString &title); + queryFavouriteItem *FindTreeItem(const wxTreeItemId &treeitem); + + void AddNewFavourite(const wxString &title, const wxString &contents); + queryFavouriteFolder *AddNewFolder(const wxString &title); + + bool ContainsFolder(const wxString &title); + + void saveFolder(xmlTextWriterPtr writer); + + ~queryFavouriteFolder(); +protected: + queryFavouriteArray favourites; +}; + +class queryFavouriteFileProvider +{ +public: + static queryFavouriteFolder *LoadFavourites(bool emptyonfailure = false); + static void SaveFavourites(queryFavouriteFolder *favourites); +}; + +#endif diff --git a/include/utils/macros.h b/include/utils/macros.h new file mode 100644 index 0000000..91be0ca --- /dev/null +++ b/include/utils/macros.h @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// macros.h - Query SQL macros +// +////////////////////////////////////////////////////////////////////////// + +#ifndef MACROS_H +#define MACROS_H + +#include +#include + +#include +#include + +class queryMacroItem +{ +public: + queryMacroItem(const wxString newKey, const wxString newTitle, const wxString newQuery, const int newId = -1); + + wxString GetKey() + { + return key; + }; + wxString GetName() + { + return name; + }; + wxString GetQuery() + { + return query; + }; + int GetId() + { + return id; + }; + + void AppendToMenu(wxMenu *menu, int newId); + void Update(const wxString &newName, const wxString &newQuery); + +protected: + int id; + wxString key, name, query; +}; + +WX_DEFINE_ARRAY_PTR(queryMacroItem *, queryMacroArray); +class queryMacroList +{ +public: + queryMacroList() {}; + queryMacroList(xmlTextReaderPtr reader); + + int AppendAllToMenu(wxMenu *menu, int startId); + + queryMacroItem *FindMacro(int id); + queryMacroItem *FindMacro(const wxString &key); + queryMacroItem *GetItem(int i); + void AddNewMacro(const wxString &key, const wxString &name, const wxString &query); + void AddOrUpdateMacro(const wxString &key, const wxString &name, const wxString &query); + bool DelMacro(int id); + int Count(); + bool DelMacro(const wxString &key); + + void saveList(xmlTextWriterPtr writer); + + ~queryMacroList(); +protected: + queryMacroArray macros; +}; + +class queryMacroFileProvider +{ +public: + static queryMacroList *LoadMacros(bool emptyOnFailure = false); + static void SaveMacros(queryMacroList *macros); + static queryMacroList *LoadAutoReplace(bool emptyOnFailure = false); + static void SaveAutoReplace(queryMacroList *macros); +}; + +#endif /* MACROS_H */ + diff --git a/include/utils/misc.h b/include/utils/misc.h new file mode 100644 index 0000000..d3d8926 --- /dev/null +++ b/include/utils/misc.h @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.h - Miscellaneous Utilties +// +////////////////////////////////////////////////////////////////////////// + +#ifndef MISC_H +#define MISC_H + +#include +#include +#include + +#include "utils/misc.h" + +class wxImageList; +extern wxImageList *imageList; + +class wxHelpControllerBase; + +#define __(str) wxT(str) + +typedef unsigned long OID; +#define SSH_MAX_PASSWORD_LEN 256 + +// we dont have an appropriate wxLongLong method +#ifdef __WIN32__ +#define atolonglong _atoi64 +#else +#ifdef __WXMAC__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#ifdef __FreeBSD__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#define atolonglong atoll +#endif +#endif +#endif + +#ifdef __WXMSW__ +#define END_OF_LINE wxT("\r\n") +#else +#define END_OF_LINE wxT("\n") +#endif + +#if !defined(PGSCLI) + +#define wxCookieType wxTreeItemIdValue + +class sysSettings; +extern sysSettings *settings; + +#undef wxStaticCast +#define wxStaticCast(obj, className) ((className *)(obj)) + +// making life easier +#define CTRL(id, typ) (XRCCTRL(*this, id, typ)) + +#define CTRL_STATIC(id) (XRCCTRL(*this, id, wxStaticText)) +#define CTRL_STATICBOX(id) (XRCCTRL(*this, id, wxStaticBox)) +#define CTRL_TEXT(id) (XRCCTRL(*this, id, wxTextCtrl)) +#define CTRL_TEXTNUMERIC(id) ((wxTextNumericCtrl*)(XRCCTRL(*this, id, wxTextCtrl))) +#define CTRL_LISTBOX(id) (XRCCTRL(*this, id, wxListBox)) +#define CTRL_LISTCTRL(id) (XRCCTRL(*this, id, wxListCtrl)) +#define CTRL_COMBOBOX(id) ((ctlComboBoxFix*)(XRCCTRL(*this, id, wxComboBox))) +#define CTRL_COMBOBOX1(id) (XRCCTRL(*this, id, wxComboBox)) +#define CTRL_LISTVIEW(id) ((ctlListView*)(XRCCTRL(*this, id, wxListCtrl))) +#define CTRL_COMBOBOX2(id) (XRCCTRL(*this, id, ctlComboBox)) +#define CTRL_CHOICE(id) (XRCCTRL(*this, id, wxChoice)) +#define CTRL_CHECKBOX(id) (XRCCTRL(*this, id, wxCheckBox)) +#define CTRL_RADIOBOX(id) (XRCCTRL(*this, id, wxRadioBox)) +#define CTRL_BUTTON(id) (XRCCTRL(*this, id, wxButton)) +#define CTRL_CALENDAR(id) (XRCCTRL(*this, id, wxCalendarBox)) +#define CTRL_TIME(id) (XRCCTRL(*this, id, wxTimeSpinCtrl)) +#define CTRL_FLEXGRIDSIZER(id) (XRCCTRL(*this, id, wxFlexGridSizer)) +#define CTRL_PANEL(id) (XRCCTRL(*this, id, wxPanel)) +#define CTRL_SLIDER(id) (XRCCTRL(*this, id, wxSlider)) +#define CTRL_SQLBOX(id) (XRCCTRL(*this, id, ctlSQLBox)) +#define CTRL_RADIOBUTTON(id) (XRCCTRL(*this, id, wxRadioButton)) +#define CTRL_NOTEBOOK(id) (XRCCTRL(*this, id, wxNotebook)) +#define CTRL_SPIN(id) (XRCCTRL(*this, id, wxSpinCtrl)) +#define CTRL_CHECKLISTBOX(id) (XRCCTRL(*this, id, wxCheckListBox)) +#define CTRL_DATEPICK(id) (XRCCTRL(*this, id, wxDatePickerCtrl)) +#define CTRL_TREE(id) (XRCCTRL(*this, id, ctlTree)) +#define CTRL_COLOURPICKER(id) (XRCCTRL(*this, id, ctlColourPicker)) +#define CTRL_DIRPICKER(id) (XRCCTRL(*this, id, wxDirPickerCtrl)) +#define CTRL_FILEPICKER(id) (XRCCTRL(*this, id, wxFilePickerCtrl)) +#define CTRL_FONTPICKER(id) (XRCCTRL(*this, id, wxFontPickerCtrl)) +#define CTRL_CHECKTREEVIEW(id) (XRCCTRL(*this, id, ctlCheckTreeView)) +#define CTRL_GAUGE(id) (XRCCTRL(*this, id, wxGauge)) + +#endif // PGSCLI + +// Conversions +wxString BoolToStr(bool value); // english; used for config values +wxString DateToAnsiStr(const wxDateTime &datetime); + +bool StrToBool(const wxString &value); // english +long StrToLong(const wxString &value); +double StrToDouble(const wxString &value); +wxLongLong StrToLongLong(const wxString &value); +wxDateTime StrToDateTime(const wxString &value); +OID StrToOid(const wxString &value); + +wxString generate_spaces(int length); + +// nls aware +wxString BoolToYesNo(bool value); +wxString NumToStr(long value); +wxString NumToStr(double value); +wxString NumToStr(OID value); +wxString NumToStr(wxLongLong value); +wxString DateToStr(const wxDateTime &datetime); +wxString ElapsedTimeToStr(wxLongLong msec); + + +// Quoting +wxString qtConnString(const wxString &value); // connection strings always have single quotes escaped with backslash + +#if !defined(PGSCLI) + +// check if size/pos have reasonable values +void CheckOnScreen(wxWindow *win, wxPoint &pos, wxSize &size, const int w0 = 100, const int h0 = 70); + +// compile ID and Name into one string +wxString IdAndName(long id, const wxString &name); + +// Quoting +wxString qtDbStringDollar(const wxString &value); +wxString qtStrip(const wxString &value); // remove \" + + +// string build helper +void AppendIfFilled(wxString &str, const wxString &delimiter, const wxString &what); + +// Create keyword list from PostgreSQL list +void FillKeywords(wxString &str); + +// Recreate a 9.0 datconfig +wxString TransformToNewDatconfig(const wxString &list); + +// Fill array, splitting the string separated by commas (maybe quoted elements) +void FillArray(wxArrayString &array, const wxString &str); + + +// splitting of strings, obeying quotes +class queryTokenizer : public wxStringTokenizer +{ +public: + queryTokenizer(const wxString &str, const wxChar delim = (wxChar)' '); + wxString GetNextToken(); +private: + char delimiter; +}; + +// Get an array from a comma(,) separated list +bool getArrayFromCommaSeparatedList(const wxString &str, wxArrayString &res); + +// File handling including encoding according to sysSettings if format<0, +// 0-> local charset, 1->utf8 +wxString FileRead(const wxString &filename, int format = -1); +bool FileWrite(const wxString &filename, const wxString &data, int format = -1); + +typedef enum +{ + HELP_PGADMIN, + HELP_POSTGRESQL, + HELP_ENTERPRISEDB, + HELP_GREENPLUM, + HELP_SLONY +} HelpType; + +wxString CleanHelpPath(const wxString &path); +bool HelpPathValid(const wxString &path); +void DisplayHelp(const wxString &helpTopic, const HelpType helpType); +void DisplayPgAdminHelp(const wxString &helpTopic); +void DisplayExternalHelp(const wxString &helpTopic, const wxString &docPath, wxHelpControllerBase *helpCtl, const bool init); + +#ifndef WIN32 +wxString ExecProcess(const wxString &cmd); +int ExecProcess(const wxString &command, wxArrayString &result); +#endif + +wxString GetHtmlEntity(const wxChar ch); +wxString HtmlEntities(const wxString &str); + +wxString firstLineOnly(const wxString &str); + +bool pgAppMinimumVersion(const wxString &cmd, const int majorVer, const int minorVer); +bool isPgApp(const wxString &app); +bool isEdbApp(const wxString &app); +bool isGpApp(const wxString &app); + +enum +{ + EDB_PACKAGE, + EDB_PACKAGEFUNCTION, + EDB_PACKAGEVARIABLE, + EDB_SYNONYM, + + PGM_CATALOG, + PGM_CATALOGOBJECT, + PGM_CHECK, + PGM_COLUMN, + PGM_CONSTRAINT, + PGM_DATABASE, + PGM_DOMAIN, + PGM_EXCLUDE, + PGM_FOREIGNKEY, + PGM_FOREIGNSERVER, + PGM_FOREIGNTABLE, + PGM_USERMAPPING, + PGM_FUNCTION, + PGM_INDEX, + PGM_OPCLASS, + PGM_OPFAMILY, + PGM_PRIMARYKEY, + PGM_ROLE, + PGM_RULE, + PGM_SCHEMA, + PGM_SERVER, + PGM_SEQUENCE, + PGM_TABLE, + PGM_TABLESPACE, + PGM_TRIGGER, + PGM_UNKNOWN, + PGM_UNIQUE, + PGM_VIEW, + + GP_EXTTABLE, + GP_RESOURCE_QUEUE, + GP_PARTITION, + + PG_PARTITION, + PGM_PROJOB, + + PGM_JOB, + PGM_SCHEDULE, + PGM_STEP, + + SLM_LISTEN, + SLM_NODE, + SLM_PATH, + SLM_SEQUENCE, + SLM_SET, + SLM_SUBSCRIPTION, + SLM_TABLE, + + PGM_LANGUAGE, + PGM_EVENTTRIGGER +}; + + +enum // depends on pgaFactory::addImage order! +{ + PGICON_PROPERTY, + PGICON_STATISTICS, + PGICON_PUBLIC +}; + +// File/directory name cleanup +wxString sanitizePath(const wxString &path); +wxString commandLineCleanOption(const wxString &option, bool schemaObject = false); +#endif // PGSCLI + +// Quoting +wxString qtIdent(const wxString &value); // add " if necessary +wxString qtTypeIdent(const wxString &value); // add " if necessary + +#endif + diff --git a/include/utils/module.mk b/include/utils/module.mk new file mode 100644 index 0000000..69483c3 --- /dev/null +++ b/include/utils/module.mk @@ -0,0 +1,34 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/include/utild/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + include/utils/csvfiles.h \ + include/utils/factory.h \ + include/utils/favourites.h \ + include/utils/misc.h \ + include/utils/pgfeatures.h \ + include/utils/pgDefs.h \ + include/utils/pgconfig.h \ + include/utils/registry.h \ + include/utils/sysLogger.h \ + include/utils/sysProcess.h \ + include/utils/sysSettings.h \ + include/utils/utffile.h \ + include/utils/macros.h + +if BUILD_SSH_TUNNEL +pgadmin3_SOURCES += \ + include/utils/sshTunnel.h +endif + +EXTRA_DIST += \ + include/utils/module.mk + diff --git a/include/utils/pgDefs.h b/include/utils/pgDefs.h new file mode 100644 index 0000000..5bfc48a --- /dev/null +++ b/include/utils/pgDefs.h @@ -0,0 +1,80 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDefs.h PostgreSQL constants +// +////////////////////////////////////////////////////////////////////////// + +#ifndef PGDEFS_H +#define PGDEFS_H + +#define PGOID_SCHEMA_CATALOG 11L +#define PGOID_SCHEMA_TOAST 99L +#define PGOID_SCHEMA_PUBLIC 2200L + +#define PGOID_CLASS_PG_AUTHID 1260L + +#define PGOID_TYPE_SERIAL -42L +#define PGOID_TYPE_SERIAL8 -43L +#define PGOID_TYPE_SERIAL2 -44L +#define PGOID_TYPE_BOOL 16L +#define PGOID_TYPE_BYTEA 17L +#define PGOID_TYPE_CHAR 18L +#define PGOID_TYPE_NAME 19L +#define PGOID_TYPE_INT8 20L +#define PGOID_TYPE_INT2 21L +#define PGOID_TYPE_INT4 23L +#define PGOID_TYPE_TEXT 25L +#define PGOID_TYPE_OID 26L +#define PGOID_TYPE_TID 27L +#define PGOID_TYPE_XID 28L +#define PGOID_TYPE_CID 29L +#define PGOID_TYPE_FLOAT4 700L +#define PGOID_TYPE_FLOAT8 701L +#define PGOID_TYPE_MONEY 790L +#define PGOID_TYPE_CHAR_ARRAY 1002L +#define PGOID_TYPE_TEXT_ARRAY 1009L +#define PGOID_TYPE_BPCHAR_ARRAY 1014L +#define PGOID_TYPE_VARCHAR_ARRAY 1015L +#define PGOID_TYPE_BPCHAR 1042L +#define PGOID_TYPE_VARCHAR 1043L +#define PGOID_TYPE_DATE 1082L +#define PGOID_TYPE_TIME 1083L +#define PGOID_TYPE_TIMESTAMP 1114L +#define PGOID_TYPE_TIMESTAMP_ARRAY 1115L +#define PGOID_TYPE_TIME_ARRAY 1183L +#define PGOID_TYPE_TIMESTAMPTZ 1184L +#define PGOID_TYPE_TIMESTAMPTZ_ARRAY 1185L +#define PGOID_TYPE_INTERVAL 1186L +#define PGOID_TYPE_INTERVAL_ARRAY 1187L +#define PGOID_TYPE_NUMERIC_ARRAY 1231L +#define PGOID_TYPE_TIMETZ 1266L +#define PGOID_TYPE_TIMETZ_ARRAY 1270L +#define PGOID_TYPE_BIT 1560L +#define PGOID_TYPE_BIT_ARRAY 1561L +#define PGOID_TYPE_VARBIT 1562L +#define PGOID_TYPE_VARBIT_ARRAY 1563L +#define PGOID_TYPE_NUMERIC 1700L +#define PGOID_TYPE_CSTRING 2275L +#define PGOID_TYPE_ANY 2276L +#define PGOID_TYPE_VOID 2278L +#define PGOID_TYPE_TRIGGER 2279L +#define PGOID_TYPE_LANGUAGE_HANDLER 2280L +#define PGOID_TYPE_INTERNAL 2281L +#define PGOID_TYPE_HANDLER 3115L + + +// These constants come from pgsql/src/include/catalog/pg_trigger.h +#define TRIGGER_TYPE_ROW (1 << 0) +#define TRIGGER_TYPE_BEFORE (1 << 1) +#define TRIGGER_TYPE_INSERT (1 << 2) +#define TRIGGER_TYPE_DELETE (1 << 3) +#define TRIGGER_TYPE_UPDATE (1 << 4) +#define TRIGGER_TYPE_TRUNCATE (1 << 5) +#define TRIGGER_TYPE_INSTEAD (1 << 6) + +#endif diff --git a/include/utils/pgconfig.h b/include/utils/pgconfig.h new file mode 100644 index 0000000..719c069 --- /dev/null +++ b/include/utils/pgconfig.h @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgconfig.h - backend configuration classes +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __PGCONFIG +#define __PGCONFIG + +#include + + +class pgSet; +class pgConn; + +class pgSettingItem; + +class pgConfigLine +{ +public: + pgConfigLine() + { + item = 0; + isComment = false; + } + + pgConfigLine(pgConfigLine *line); + + bool Differs(pgConfigLine *line); + wxString GetNewText(); + + pgSettingItem *item; + wxString value; + wxString comment; + bool isComment; +}; + +class pgConfigOrgLine : public pgConfigLine +{ +public: + pgConfigOrgLine(const wxString str) : pgConfigLine() + { + text = str; + } + pgConfigOrgLine(pgConfigLine *line); + wxString GetNewText(); + + wxString text; + wxString commentIndent; +}; + +class pgHbaConfigLine +{ +public: + pgHbaConfigLine(const wxString &line = wxEmptyString); + wxString GetText(); + const wxChar *GetConnectType(); + const wxChar *GetMethod(); + void Init(const wxString &line); + + enum pgHbaConnectType + { + PGC_LOCAL = 0, + PGC_HOST, + PGC_HOSTSSL, + PGC_HOSTNOSSL, + PGC_INVALIDCONF + }; + enum pgHbaMethod + { + PGC_TRUST = 0, + PGC_REJECT, + PGC_MD5, + PGC_CRYPT, + PGC_PASSWORD, + PGC_KRB4, + PGC_KRB5, + PGC_IDENT, + PGC_PAM, + PGC_LDAP, + PGC_GSS, + PGC_SSPI, + PGC_CERT, + PGC_PEER, + PGC_RADIUS, + PGC_INVALIDMETHOD + }; + + wxString text; + wxString database, user, ipaddress, option; + pgHbaConnectType connectType; + pgHbaMethod method; + + long item; + + bool isValid; + bool isComment; + bool changed; +}; + +class pgPassConfigLine +{ +public: + pgPassConfigLine(const wxString &line = wxEmptyString); + wxString GetText(); + void Init(const wxString &line); + + wxString text; + wxString hostname, port, database, username, password; + + long item; + + bool isComment; +}; + + +class pgSettingItem +{ +public: + enum pgConfigType + { + PGC_BOOL = 0, + PGC_INT, + PGC_REAL, + PGC_STRING + }; + + enum pgConfigContext + { + PGC_INTERNAL = 0, + PGC_POSTMASTER, + PGC_SIGHUP, + PGC_BACKEND, + PGC_SUSET, + PGC_USERLIMIT, + PGC_USERSET, + PGC_UNKNOWNCONTEXT + }; + + enum pgConfigSource + { + PGC_DEFAULT = 0, + PGC_ENVIRONMENT, + PGC_FILE, + PGC_ARGV, + PGC_UNPRIV, + PGC_DATABASE, + PGC_USER, + PGC_CLIENT, + PGC_OVERRIDE, + PGC_INTERACTIVE, + PGC_TEST, + PGC_SESSION, + PGC_UNKNOWNSOURCE + }; + + pgSettingItem() + { + orgLine = 0; + newLine = 0; + source = PGC_UNKNOWNSOURCE; + context = PGC_UNKNOWNCONTEXT; + } + ~pgSettingItem() + { + if (newLine) delete newLine; + } + + void SetType(const wxString &str); + void SetContext(const wxString &str); + void SetSource(const wxString &str); + wxString GetActiveValue(); + + wxString name; + wxString category; + wxString short_desc; + wxString extra_desc; + wxString value; + pgConfigType type; + pgConfigContext context; + pgConfigSource source; + + wxString min_val, max_val; + + pgConfigLine *newLine; + pgConfigOrgLine *orgLine; +}; + + + +WX_DECLARE_HASH_MAP(wxString, pgSettingItem *, wxStringHash, wxStringEqual, pgSettingItemHashmap); +WX_DECLARE_HASH_MAP(wxString, wxArrayString *, wxStringHash, wxStringEqual, pgCategoryHashmap); + +class pgSettingReader +{ +public: + virtual bool IsValid() = 0; + virtual pgSettingItem *GetNextItem() = 0; + virtual ~pgSettingReader() {} +}; + + +class pgSettingFileReader : public pgSettingReader +{ + wxString columnNames; + wxString buffer; + wxChar *bp; + +public: + pgSettingFileReader(bool localized); + ~pgSettingFileReader(); + virtual bool IsValid() + { + return !buffer.IsEmpty(); + } + virtual pgSettingItem *GetNextItem(); +}; + + +class pgSettingDbReader : public pgSettingReader +{ + pgSet *set; + +public: + pgSettingDbReader(pgConn *conn); + ~pgSettingDbReader(); + + virtual bool IsValid() + { + return set != NULL; + } + virtual pgSettingItem *GetNextItem(); +}; + +#endif diff --git a/include/utils/pgfeatures.h b/include/utils/pgfeatures.h new file mode 100644 index 0000000..0e68e38 --- /dev/null +++ b/include/utils/pgfeatures.h @@ -0,0 +1,31 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgfeatures.h PostgreSQL features constants +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __FEATURE_H +#define __FEATURE_H + +enum +{ + FEATURE_INITIALIZED = 0, + FEATURE_SIZE, + FEATURE_FILEREAD, + FEATURE_ROTATELOG, + FEATURE_POSTMASTER_STARTTIME, + FEATURE_TERMINATE_BACKEND, + FEATURE_RELOAD_CONF, + FEATURE_PGSTATTUPLE, + FEATURE_PGSTATINDEX, + FEATURE_FUNCTION_DEFAULTS, + FEATURE_LAST +}; + +#endif diff --git a/include/utils/registry.h b/include/utils/registry.h new file mode 100644 index 0000000..8e4e2bc --- /dev/null +++ b/include/utils/registry.h @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// registry.h - Windows Registry Reader for both 32 and 64 mode +// +////////////////////////////////////////////////////////////////////////// + +#ifndef __PGREG_WINREGISTRY_H__ +#define __PGREG_WINREGISTRY_H__ + +#ifdef __WXMSW__ + +#include + +class pgRegKey +{ + +public: + enum PGREGWOWMODE + { + /* + * Read/Write 32 bit registry for 32 bit applications, + * Read/Write 64 bit registry for 64 bit applications + */ + PGREG_WOW_DEFAULT, + /* Read/Write 32 bit registry */ + PGREG_WOW32, + /* Read/Write 64 bit registry on 64 bit windows */ + PGREG_WOW64 + }; + + enum PGREGACCESSMODE + { + /* READ ONLY */ + PGREG_READ, + /* READ & Write */ + PGREG_WRITE + }; + +public: + static pgRegKey *OpenRegKey(HKEY root, const wxString &subkey, PGREGACCESSMODE accessmode = PGREG_READ, PGREGWOWMODE wowMode = PGREG_WOW_DEFAULT); + ~pgRegKey(); + + static bool KeyExists(HKEY root, const wxString &subKey, PGREGWOWMODE wowMode = PGREG_WOW_DEFAULT); + + bool GetKeyInfo(size_t *pnSubKeys, // number of subkeys + size_t *pnMaxKeyLen, // max len of subkey name + size_t *pnValues, // number of values + size_t *pnMaxValueLen) const; + + bool QueryValue(const wxString &strVal, LPDWORD pVal) const; + bool QueryValue(const wxString &strVal, wxString &pVal) const; + bool QueryValue(const wxString &strVal, LPBYTE &pVal, DWORD &len) const; + + bool GetFirstValue(wxString &strVal, long &lindex) const; + bool GetNextValue(wxString &strVal, long &lindex) const; + bool HasValue(const wxString &strVal); + + bool GetFirstKey(pgRegKey *&pkey, long &lindex) const; + bool GetNextKey(pgRegKey *&pkey, long &lindex) const; + bool HasKey(const wxString &strKey) const; + + DWORD GetValueType(const wxString &strVal) const; + + wxString ToString() const; + wxString GetKeyName() const; + +private: + pgRegKey(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode); + pgRegKey(const pgRegKey &keyParent, const wxString &strKey); + + void Init(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode); + void Close(); + + HKEY m_hRoot; + HKEY m_hKey; + wxString m_strName; + DWORD m_wowMode; + PGREGACCESSMODE m_accessMode; + +}; + +#endif // __WXMSW__ +#endif // __PGREG_WINREGISTRY_H__ + diff --git a/include/utils/sshTunnel.h b/include/utils/sshTunnel.h new file mode 100644 index 0000000..c78b742 --- /dev/null +++ b/include/utils/sshTunnel.h @@ -0,0 +1,119 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sshTunnel.h - Used to create SSH Tunnels +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef __SSH_TUNNELING +#define __SSH_TUNNELING + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include "utils/misc.h" + +struct _LIBSSH2_CHANNEL; +struct _LIBSSH2_SESSION; +struct _LIBSSH2_USERAUTH_KBDINT_PROMPT; +struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE; + +enum enAuthenticationMethod +{ + AUTH_NONE = 0, + AUTH_PASSWORD, + AUTH_KEYBOARD_INTERACTIVE, + AUTH_PUBLICKEY = 4 +}; + +void LogSSHTunnelErrors(const wxString &msg, const int &id, struct _LIBSSH2_SESSION *session = NULL); +static wxMutex g_SSHThreadMutex; + +WX_DECLARE_HASH_SET( int, wxIntegerHash, wxIntegerEqual, subThreadSDSet); +static subThreadSDSet g_setSocketDescriptor; + +class CSSHTunnelThread : + public wxThread +{ +public: + CSSHTunnelThread(const wxString tunnelhost, const wxString remote_desthost, const unsigned int remote_destport, + const wxString username, const wxString password, const wxString publickey, const wxString privatekey, + const enAuthenticationMethod &enAuthMethod, const unsigned int tunnelPort = 22); + virtual ~CSSHTunnelThread(void); + virtual void *Entry(); + bool Initialize(); + void Cleanup(); + + wxString GetLocalListenIP() const + { + return m_local_listenip; + } + + unsigned int GetLocalListenPort() const + { + return m_local_listenport; + } + +private: + bool resolveDNS(const char *host, wxArrayString &arrIPAddress); + static void keyboard_interactive(const char *name, int name_len, const char *instr, int instr_len, + int num_prompts, const struct _LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE *res, void **abstract); + bool IsHostKeyVerified(const wxString &newHostKey); + + int m_listensock, m_sock; + struct sockaddr_in m_sin; + socklen_t m_sinlen; + struct _LIBSSH2_SESSION *m_session; + static char m_keyboard_interactive_pwd[SSH_MAX_PASSWORD_LEN]; + + wxString m_publickey; + wxString m_privatekey; + wxString m_username; + wxString m_password; + wxString m_tunnelhost; + wxString m_local_listenip; + wxString m_remote_desthost; + unsigned int m_local_listenport; + unsigned int m_remote_destport; + unsigned int m_tunnelPort; + enAuthenticationMethod m_enAuthMethod; +}; + +class CSubThread : + public wxThread +{ +public: + CSubThread(const struct sockaddr_in sin, const wxString remote_desthost, const unsigned int remote_destport, + struct _LIBSSH2_SESSION *session, int forwardsock); + virtual ~CSubThread(void); + virtual void *Entry(); + +private: + struct sockaddr_in m_sin; + wxString m_remote_desthost; + unsigned int m_remote_destport; + struct _LIBSSH2_SESSION *m_subThreadSession; + struct _LIBSSH2_CHANNEL *m_channel; + int m_forwardsock; +}; + +#endif diff --git a/include/utils/sysLogger.h b/include/utils/sysLogger.h new file mode 100644 index 0000000..a69aad9 --- /dev/null +++ b/include/utils/sysLogger.h @@ -0,0 +1,77 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysLogger.h - Log handling class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SYSLOGGER_H +#define SYSLOGGER_H + +// wxWindows headers +#include + +// App headers + +enum LOG_LEVEL +{ + LOG_NONE = 0, + LOG_ERRORS = 1, + LOG_NOTICE = 2, + LOG_SQL = 3, + LOG_DEBUG = 4 +}; + +// Class declarations +class sysLogger : public wxLog +{ +public: +#if wxCHECK_VERSION(2, 9, 0) + void DoLogTextAtLevel(wxLogLevel level, const wxString &msg); +#else + virtual void DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp); +#endif + + static wxLogLevel logLevel; + static wxString logFile; + +private: + void WriteLog(const wxString &msg); + bool SilenceMessage(const wxString &msg); +}; + +#define wxLOG_Notice (wxLOG_User+1) +#define wxLOG_Sql (wxLOG_User+2) +#define wxLOG_QuietError (wxLOG_User+3) +#define wxLOG_Script (wxLOG_User+4) +#define wxLOG_ScriptVerbose (wxLOG_User+5) + +#if wxCHECK_VERSION(2, 9, 0) + +#define wxLogNotice wxDO_LOG(Notice) +#define wxLogSql wxDO_LOG(Sql) +#define wxLogQuietError wxDO_LOG(QuietError) +#define wxLogScript wxDO_LOG(Script) +#define wxLogScriptVerbose wxDO_LOG(ScriptVerbose) + +#else + +#define DECLARE_INT_LOG_FUNCTION(level) \ +extern void wxVLog##level(const wxChar *szFormat, va_list argptr); \ +extern void wxLog##level(const wxChar *szFormat, ...) + +DECLARE_INT_LOG_FUNCTION(Notice); +DECLARE_INT_LOG_FUNCTION(Sql); +DECLARE_INT_LOG_FUNCTION(QuietError); +DECLARE_INT_LOG_FUNCTION(Script); +DECLARE_INT_LOG_FUNCTION(ScriptVerbose); + +#endif + + +#endif // SYSLOGGER_H + diff --git a/include/utils/sysProcess.h b/include/utils/sysProcess.h new file mode 100644 index 0000000..6e44555 --- /dev/null +++ b/include/utils/sysProcess.h @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysProcess.h - External process +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SYSPROCESS_H +#define SYSPROCESS_H + +#include +#include "wx/process.h" +#include + +class sysProcess : public wxProcess +{ +public: + sysProcess(wxEvtHandler *evh, wxMBConv &conv = wxConvLibc); + + bool Run(const wxString &exec); + void Abort(); + void SetEnvironment(const wxArrayString &environment); + wxString ReadInputStream(); + wxString ReadErrorStream(); + void WriteOutputStream(const wxString &out); + + static sysProcess *Create(const wxString &exec, wxEvtHandler *evh = 0, wxArrayString *env = 0, wxMBConv &conv = wxConvLibc); + +private: + int pid; + wxMBConv &m_conv; + void OnTerminate(int pid, int status) const; + wxString ReadStream(wxInputStream *input); +}; + + + +#endif diff --git a/include/utils/sysSettings.h b/include/utils/sysSettings.h new file mode 100644 index 0000000..3221a21 --- /dev/null +++ b/include/utils/sysSettings.h @@ -0,0 +1,878 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysSettings.h - Settings handling class +// +////////////////////////////////////////////////////////////////////////// + +#ifndef SYSSETTINGS_H +#define SYSSETTINGS_H + +#include "utils/sysLogger.h" + +// wxWindows headers +#include +#include +#include + +// Class declarations +class sysSettings : private wxConfig +{ +public: + sysSettings(const wxString &name); + ~sysSettings(); + // Display options + bool GetDisplayOption(const wxString &objtype, bool GetDefault = false); + void SetDisplayOption(const wxString &objtype, bool display); + + void FlushChanges() + { + wxConfig::Flush(); + } + + // Log + wxString GetLogFile(); + void SetLogFile(const wxString &newval) + { + Write(wxT("LogFile"), newval); + sysLogger::logFile = newval; + } + int GetLogLevel() const + { + int i; + Read(wxT("LogLevel"), &i, LOG_ERRORS); + return i; + } + void SetLogLevel(const int newval) + { + WriteInt(wxT("LogLevel"), newval); + sysLogger::logLevel = newval; + } + + // Last connection + wxString GetLastDescription() const + { + wxString s; + Read(wxT("LastDescription"), &s, wxT("PostgreSQL Server")); + return s; + } + void SetLastDescription(const wxString &newval) + { + Write(wxT("LastDescription"), newval); + } + wxString GetLastServer() const + { + wxString s; + Read(wxT("LastServer"), &s, wxT("localhost")); + return s; + } + void SetLastServer(const wxString &newval) + { + Write(wxT("LastServer"), newval); + } + wxString GetLastDatabase() const + { + wxString s; + Read(wxT("LastDatabase"), &s, wxT("postgres")); + return s; + } + void SetLastDatabase(const wxString &newval) + { + Write(wxT("LastDatabase"), newval); + } + wxString GetLastUsername() const + { + wxString s; + Read(wxT("LastUsername"), &s, wxT("postgres")); + return s; + } + void SetLastUsername(const wxString &newval) + { + Write(wxT("LastUsername"), newval); + } + int GetLastPort() const + { + int i; + Read(wxT("LastPort"), &i, 5432); + return i; + } + void SetLastPort(const int newval) + { + WriteInt(wxT("LastPort"), newval); + } + int GetLastSSL() const + { + int i; + Read(wxT("LastSSL"), &i, 0); + return i; + } + void SetLastSSL(const int newval) + { + WriteInt(wxT("LastSSL"), newval); + } + + // Helper paths + wxString GetSlonyPath() const + { + wxString s; + Read(wxT("SlonyPath"), &s, wxEmptyString); + return s; + } + void SetSlonyPath(const wxString &newval) + { + Write(wxT("SlonyPath"), newval); + } + wxString GetPostgresqlPath() const + { + wxString s; + Read(wxT("PostgreSQLPath"), &s, wxEmptyString); + return s; + } + void SetPostgresqlPath(const wxString &newval) + { + Write(wxT("PostgreSQLPath"), newval); + } + wxString GetEnterprisedbPath() const + { + wxString s; + Read(wxT("EnterpriseDBPath"), &s, wxEmptyString); + return s; + } + void SetEnterprisedbPath(const wxString &newval) + { + Write(wxT("EnterpriseDBPath"), newval); + } + wxString GetGPDBPath() const + { + wxString s; + Read(wxT("GreenplumDBPath"), &s, wxEmptyString); + return s; + } + void SetGPDBPath(const wxString &newval) + { + Write(wxT("GreenplumDBPath"), newval); + } + + // Help paths + wxString GetSlonyHelpPath(); + void SetSlonyHelpPath(const wxString &newval) + { + Write(wxT("SlonyHelpPath"), newval); + } + wxString GetPgHelpPath(); + void SetPgHelpPath(const wxString &newval) + { + Write(wxT("PostgreSQLHelpPath"), newval); + } + wxString GetEdbHelpPath(); + void SetEdbHelpPath(const wxString &newval) + { + Write(wxT("EnterpriseDBHelpPath"), newval); + } + wxString GetGpHelpPath(); + void SetGpHelpPath(const wxString &newval) + { + Write(wxT("GreenplumDBHelpPath"), newval); + } + + // Copy options + wxString GetCopyQuoteChar() const + { + wxString s; + Read(wxT("Copy/QuoteChar"), &s, wxT("\"")); + return s; + } + void SetCopyQuoteChar(const wxString &newval) + { + Write(wxT("Copy/QuoteChar"), newval); + } + wxString GetCopyColSeparator() const + { + wxString s; + Read(wxT("Copy/ColSeparator"), &s, wxT(";")); + return s; + } + void SetCopyColSeparator(const wxString &newval) + { + Write(wxT("Copy/ColSeparator"), newval); + } + int GetCopyQuoting(); // 0=none 1=string 2=all + void SetCopyQuoting(const int i); + + // Export options + wxString GetExportQuoteChar() const + { + wxString s; + Read(wxT("Export/QuoteChar"), &s, wxT("\"")); + return s; + } + void SetExportQuoteChar(const wxString &newval) + { + Write(wxT("Export/QuoteChar"), newval); + } + wxString GetExportColSeparator() const + { + wxString s; + Read(wxT("Export/ColSeparator"), &s, wxT(";")); + return s; + } + void SetExportColSeparator(const wxString &newval) + { + Write(wxT("Export/ColSeparator"), newval); + } + wxString GetExportRowSeparator(); + void SetExportRowSeparator(const wxString &s); + int GetExportQuoting(); // 0=none 1=string 2=all + void SetExportQuoting(const int i); + bool GetExportUnicode() const + { + bool b; + Read(wxT("Export/Unicode"), &b, true); + return b; + } + void SetExportUnicode(const bool newval) + { + WriteBool(wxT("Export/Unicode"), newval); + } + bool GetWriteBOM() const + { + bool b; + Read(wxT("Export/WriteBOM"), &b, true); + return b; + } + void SetWriteBOM(const bool newval) + { + WriteBool(wxT("Export/WriteBOM"), newval); + } + + // Explain options + bool GetExplainVerbose() const + { + bool b; + Read(wxT("frmQuery/ExplainVerbose"), &b, false); + return b; + } + void SetExplainVerbose(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainVerbose"), newval); + } + bool GetExplainCosts() const + { + bool b; + Read(wxT("frmQuery/ExplainCosts"), &b, true); + return b; + } + void SetExplainCosts(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainCosts"), newval); + } + bool GetExplainBuffers() const + { + bool b; + Read(wxT("frmQuery/ExplainBuffers"), &b, false); + return b; + } + void SetExplainBuffers(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainBuffers"), newval); + } + bool GetExplainTiming() const + { + bool b; + Read(wxT("frmQuery/ExplainTiming"), &b, true); + return b; + } + void SetExplainTiming(const bool newval) + { + WriteBool(wxT("frmQuery/ExplainTiming"), newval); + } + + // Display options + wxString GetSystemSchemas() const + { + wxString s; + Read(wxT("SystemSchemas"), &s, wxEmptyString); + return s; + } + void SetSystemSchemas(const wxString &newval) + { + Write(wxT("SystemSchemas"), newval); + } + bool GetShowUsersForPrivileges() const + { + bool b; + Read(wxT("ShowUsersForPrivileges"), &b, false); + return b; + } + void SetShowUsersForPrivileges(const bool newval) + { + WriteBool(wxT("ShowUsersForPrivileges"), newval); + } + bool GetShowSystemObjects() const + { + bool b; + Read(wxT("ShowSystemObjects"), &b, false); + return b; + } + void SetShowSystemObjects(const bool newval) + { + WriteBool(wxT("ShowSystemObjects"), newval); + } + + // Editor options + bool GetSpacesForTabs() const + { + bool b; + Read(wxT("SpacesForTabs"), &b, false); + return b; + } + void SetSpacesForTabs(const bool newval) + { + WriteBool(wxT("SpacesForTabs"), newval); + } + long GetIndentSpaces() const + { + long l; + Read(wxT("IndentSpaces"), &l, 0L); + return l; + } + void SetIndentSpaces(const long newval) + { + WriteLong(wxT("IndentSpaces"), newval); + } + bool GetIndicateNull() const + { + bool b; + Read(wxT("frmQuery/IndicateNull"), &b, false); + return b; + } + void SetIndicateNull(const bool newval) + { + WriteBool(wxT("frmQuery/IndicateNull"), newval); + } + wxString GetThousandsSeparator() const + { + wxString s; + Read(wxT("frmQuery/ThousandsSeparator"), &s, wxEmptyString); + return s; + } + void SetThousandsSeparator(const wxString &newval) + { + Write(wxT("frmQuery/ThousandsSeparator"), newval); + } + bool GetAutoRollback() const + { + bool b; + Read(wxT("frmQuery/AutoRollback"), &b, false); + return b; + } + bool GetAutoSelectQuery() const + { + bool b; + Read(wxT("frmQuery/AutoSelectQuery"), &b, false); + return b; + } + void SetAutoRollback(const bool newval) + { + WriteBool(wxT("frmQuery/AutoRollback"), newval); + } + bool GetAutoCommit() const + { + bool b; + Read(wxT("frmQuery/AutoCommit"), &b, true); + return b; + } + void SetAutoCommit(const bool newval) + { + WriteBool(wxT("frmQuery/AutoCommit"), newval); + } + wxString GetDecimalMark() const + { + wxString s; + Read(wxT("DecimalMark"), &s, wxEmptyString); + return s; + } + void SetDecimalMark(const wxString &newval) + { + Write(wxT("DecimalMark"), newval); + } + bool GetColumnNames() const + { + bool b; + Read(wxT("ColumnNames"), &b, false); + return b; + } + void SetColumnNames(const bool newval) + { + WriteBool(wxT("ColumnNames"), newval); + } + bool GetLineNumber() const + { + bool b; + Read(wxT("ShowLineNumber"), &b, false); + return b; + } + void SetLineNumber(const bool newval) + { + WriteBool(wxT("ShowLineNumber"), newval); + } + bool GetUnicodeFile() const + { + bool b; + Read(wxT("WriteUnicodeFile"), &b, true); + return b; + } + void SetUnicodeFile(const bool newval) + { + WriteBool(wxT("WriteUnicodeFile"), newval); + } + wxFont GetSystemFont(); + void SetSystemFont(const wxFont &font); + wxFont GetSQLFont(); + void SetSQLFont(const wxFont &font); + wxFont GetDDFont(); + void SetDDFont(const wxFont &font); + int GetLineEndingType() const + { + int i; + int defval = 2; +#ifdef __WXMSW__ + defval = 0; /* SC_EOL_CRLF in Scintilla.h */ +#else + defval = 2; /* SC_EOL_LF in Scintilla.h */ +#endif + Read(wxT("LineEndingType"), &i, defval); + return i; + } + void SetLineEndingType(const int newval) + { + WriteInt(wxT("LineEndingType"), newval); + } + wxString GetFavouritesFile(); + void SetFavouritesFile(const wxString &newval) + { + Write(wxT("FavouritesFile"), newval); + } + wxString GetMacrosFile(); + wxString GetAutoReplaceFile(); + void SetAutoReplaceFile(const wxString &newval) + { + Write(wxT("AutoReplaceFile"), newval); + } + void SetMacrosFile(const wxString &newval) + { + Write(wxT("MacrosFile"), newval); + } + wxString GetExtFormatCmd() + { + wxString s; + Read(wxT("ExtFormatCmd"), &s, wxEmptyString); + return s; + } + void SetExtFormatCmd(const wxString &newval) + { + Write(wxT("ExtFormatCmd"), newval); + } + long GetExtFormatTimeout() const + { + long l; + Read(wxT("ExtFormatTimeout"), &l, 3000L); + return l; + } + void SetExtFormatTimeout(const long newval) + { + WriteLong(wxT("ExtFormatTimeout"), newval); + } + wxString GetHistoryFile(); + void SetHistoryFile(const wxString &newval) + { + Write(wxT("History/File"), newval); + } + long GetHistoryMaxQueries() const + { + long l; + Read(wxT("History/MaxQueries"), &l, 10L); + return l; + } + void SetHistoryMaxQueries(const long newval) + { + WriteLong(wxT("History/MaxQueries"), newval); + } + long GetHistoryMaxQuerySize() const + { + long l; + Read(wxT("History/MaxQuerySize"), &l, 1024L); + return l; + } + void SetHistoryMaxQuerySize(const long newval) + { + WriteLong(wxT("History/MaxQuerySize"), newval); + } + + // Custom Colours options + wxString GetCustomColour(int index) const + { + wxString s; + Read(wxT("CustomColour") + NumToStr((long) index), &s, wxT("#ffffff")); + return s; + } + void SetCustomColour(int index, const wxString &newval) + { + Write(wxT("CustomColour") + NumToStr((long) index), newval); + } + + // Status Colours options + wxString GetIdleProcessColour() const + { + wxString s; + Read(wxT("IdleProcessColour"), &s, wxT("#5fa4d9")); + return s; + } + void SetIdleProcessColour(const wxString &newval) + { + Write(wxT("IdleProcessColour"), newval); + } + wxString GetActiveProcessColour() const + { + wxString s; + Read(wxT("ActiveProcessColour"), &s, wxT("#5fd95f")); + return s; + } + void SetActiveProcessColour(const wxString &newval) + { + Write(wxT("ActiveProcessColour"), newval); + } + wxString GetSlowProcessColour() const + { + wxString s; + Read(wxT("SlowProcessColour"), &s, wxT("#d9a75f")); + return s; + } + void SetSlowProcessColour(const wxString &newval) + { + Write(wxT("SlowProcessColour"), newval); + } + wxString GetBlockedProcessColour() const + { + wxString s; + Read(wxT("BlockedProcessColour"), &s, wxT("#d96e5f")); + return s; + } + void SetBlockedProcessColour(const wxString &newval) + { + Write(wxT("BlockedProcessColour"), newval); + } + wxString GetBlockedbyProcessColour() const + { + wxString s; + Read(wxT("BlockedbyProcessColour"), &s, wxT("#FFF200")); + return s; + } + void SetBlockedbyProcessColour(const wxString &newval) + { + Write(wxT("BlockedbyProcessColour"), newval); + } + + // SQL Editor Colours options + bool GetSQLBoxUseSystemBackground() const + { + bool b; + Read(wxT("ctlSQLBox/UseSystemBackground"), &b, true); + return b; + } + void SetSQLBoxUseSystemBackground(const bool newval) + { + WriteBool(wxT("ctlSQLBox/UseSystemBackground"), newval); + } + bool GetSQLBoxUseSystemForeground() const + { + bool b; + Read(wxT("ctlSQLBox/UseSystemForeground"), &b, true); + return b; + } + void SetSQLBoxUseSystemForeground(const bool newval) + { + WriteBool(wxT("ctlSQLBox/UseSystemForeground"), newval); + } + + wxString GetSQLBoxColourBackground() const + { + wxString s; + Read(wxT("ctlSQLBox/ColourBackground"), &s, wxT("#ffffff")); + return s; + } + void SetSQLBoxColourBackground(const wxString &newval) + { + Write(wxT("ctlSQLBox/ColourBackground"), newval); + } + wxString GetSQLBoxColourForeground() const + { + wxString s; + Read(wxT("ctlSQLBox/ColourForeground"), &s, wxT("#000000")); + return s; + } + void SetSQLBoxColourForeground(const wxString &newval) + { + Write(wxT("ctlSQLBox/ColourForeground"), newval); + } + + wxString GetSQLColourCaret() const + { + wxString s; + Read(wxT("ctlSQLBox/ColourCaret"), &s, wxT("#000000")); + return s; + } + void SetSQLColourCaret(const wxString &newval) + { + Write(wxT("ctlSQLBox/ColourCaret"), newval); + } + + wxString GetSQLBoxColour(int index) const + { + wxString s; + Read(wxString::Format(wxT("ctlSQLBox/Colour%i"), index), &s, getDefaultElementColor(index)); + return s; + } + void SetSQLBoxColour(int index, const wxString &newval) + { + Write(wxString::Format(wxT("ctlSQLBox/Colour%i"), index), newval); + } + + wxString GetSQLMarginBackgroundColour() const + { + wxString s; + Read(wxT("ctlSQLBox/MarginBackgroundColour"), &s, wxT("#dddddd")); + return s; + } + void SetSQLMarginBackgroundColour(const wxString &newval) + { + Write(wxT("ctlSQLBox/MarginBackgroundColour"), newval); + } + bool GetSQLKeywordsInUppercase() const + { + bool b; + Read(wxT("KeywordsInUppercase"), &b, false); + return b; + } + void SetSQLKeywordsInUppercase(const bool newval) + { + WriteBool(wxT("KeywordsInUppercase"), newval); + } + + // Misc options + long GetAutoRowCountThreshold() const + { + long l; + Read(wxT("AutoRowCount"), &l, 2000L); + return l; + } + void SetAutoRowCountThreshold(const long newval) + { + WriteLong(wxT("AutoRowCount"), newval); + } + bool GetStickySql() const + { + bool b; + Read(wxT("StickySql"), &b, false); + return b; + } + void SetStickySql(const bool newval) + { + WriteBool(wxT("StickySql"), newval); + } + bool GetDoubleClickProperties() const + { + bool b; + Read(wxT("DoubleClickProperties"), &b, false); + return b; + } + void SetDoubleClickProperties(const bool newval) + { + WriteBool(wxT("DoubleClickProperties"), newval); + } + long GetMaxServerLogSize() const + { + long l; + Read(wxT("MaxServerLogSize"), &l, 100000L); + return l; + } + void SetMaxServerLogSize(const long newval) + { + WriteLong(wxT("MaxServerLogSize"), newval); + } + bool GetSuppressGuruHints() const + { + bool b; + Read(wxT("SuppressGuruHints"), &b, false); + return b; + } + void SetSuppressGuruHints(const bool newval) + { + WriteBool(wxT("SuppressGuruHints"), newval); + } + long GetMaxRows() const + { + long l; + Read(wxT("frmQuery/MaxRows"), &l, 100L); + return l; + } + void SetMaxRows(const long newval) + { + WriteLong(wxT("frmQuery/MaxRows"), newval); + } + long GetMaxColSize() const + { + long l; + Read(wxT("frmQuery/MaxColSize"), &l, 256L); + return l; + } + void SetMaxColSize(const long newval) + { + WriteLong(wxT("frmQuery/MaxColSize"), newval); + } + bool GetAskSaveConfirmation() const + { + bool b; + Read(wxT("AskSaveConfirmation"), &b, true); + return b; + } + void SetAskSaveConfirmation(const bool newval) + { + WriteBool(wxT("AskSaveConfirmation"), newval); + } + bool GetConfirmDelete() const + { + bool b; + Read(wxT("ConfirmDelete"), &b, true); + return b; + } + void SetConfirmDelete(const bool newval) + { + WriteBool(wxT("ConfirmDelete"), newval); + } + wxString GetCanonicalLanguageName(); + wxLanguage GetCanonicalLanguage() const + { + int i; + Read(wxT("LanguageId"), &i, wxLANGUAGE_UNKNOWN); + return (wxLanguage)i; + } + void SetCanonicalLanguage(const wxLanguage &lang); + bool GetIgnoreVersion() const + { + bool b; + Read(wxT("IgnoreVersion"), &b, false); + return b; + } + void SetIgnoreVersion(const bool newval) + { + WriteBool(wxT("IgnoreVersion"), newval); + } + + int GetRefreshOnClick() const + { + int i; + Read(wxT("RefreshOnClick"), &i, 0); + return i; + } + void SetRefreshOnClick(const int newval) + { + WriteInt(wxT("RefreshOnClick"), newval); + } + + bool GetShowNotices() const + { + bool b; + Read(wxT("ShowNotices"), &b, false); + return b; + } + void SetShowNotices(const bool newval) + { + WriteBool(wxT("ShowNotices"), newval); + } + bool GetASUTPstyle() const + { + bool b; + Read(wxT("ASUTPstyle"), &b, false); + return b; + } + void SetASUTPstyle(const bool newval) + { + WriteBool(wxT("ASUTPstyle"), newval); + } + + + wxString GetOptionsLastTreeItem() const + { + wxString s; + Read(wxT("OptionsLastTreeItem"), &s, wxEmptyString); + return s; + } + void SetOptionsLastTreeItem(const wxString &newval) + { + Write(wxT("OptionsLastTreeItem"), newval); + } + + + // Functions for storing settings + bool Write(const wxString &key, const wxString &value) + { + return wxConfig::Write(key, value); + } + bool WriteLong(const wxString &key, long value) + { + return wxConfig::Write(key, value); + } + bool WriteInt(const wxString &key, int value) + { + return wxConfig::Write(key, value); + } + bool WriteBool(const wxString &key, bool value); + bool WritePoint(const wxString &key, const wxPoint &value); + bool WriteSize(const wxString &key, const wxSize &value); + bool WriteSizePoint(const wxString &key, const wxSize &size, const wxPoint &point) + { + WritePoint(key, point); + WriteSize(key, size); + return true; + } + + // Functions for reading settings + bool Read(const wxString &key, wxString *str, const wxString &defaultVal) const; + bool Read(const wxString &key, bool *str, bool defaultVal) const; + bool Read(const wxString &key, int *i, int defaultVal) const; + bool Read(const wxString &key, long *l, long defaultVal) const; + wxString Read(const wxString &key, const wxString &defaultVal) const; + long Read(const wxString &key, long defaultVal) const; + wxPoint Read(const wxString &key, const wxPoint &defaultVal) const; + wxSize Read(const wxString &key, const wxSize &defaultVal) const; + + enum configFileName + { + PGPASS + }; + static wxString GetConfigFile(configFileName cfgname); + +private: + static const wxString &getDefaultElementColor(int index) + { + static const wxString colors[] = + { + wxT("#808080"), wxT("#007f00"), wxT("#007f00"), wxT("#7f7f7f"), + wxT("#007f7f"), wxT("#00007f"), wxT("#7f007f"), wxT("#7f007f"), + wxT("#007f7f"), wxT("#7f7f7f"), wxT("#000000"), wxT("#000000") + }; + return colors[index]; + } + + bool moveStringValue(const wxChar *oldKey, const wxChar *newKey, int index = -1); + bool moveLongValue(const wxChar *oldKey, const wxChar *newKey, int index = -1); + + wxFileConfig *defaultSettings; +}; + +#endif diff --git a/include/utils/utffile.h b/include/utils/utffile.h new file mode 100644 index 0000000..43130de --- /dev/null +++ b/include/utils/utffile.h @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// utffile.h - file io with BOM interpretation +// +////////////////////////////////////////////////////////////////////////// + + +#ifndef _WX_UTFFILEH__ +#define _WX_UTFFILEH__ + +#include "wx/wx.h" +#include "wx/font.h" +#include "wx/file.h" + +class wxUtfFile : public wxFile +{ +public: + wxUtfFile(); + wxUtfFile(const wxChar *szFileName, OpenMode mode = read, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + wxUtfFile(int fd, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + + bool Create(const wxChar *szFileName, bool bOverwrite = false, int access = wxS_DEFAULT, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + bool Open(const wxChar *szFileName, OpenMode mode = read, int access = wxS_DEFAULT, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + void Attach(int fd, wxFontEncoding encoding = wxFONTENCODING_DEFAULT); + + wxFontEncoding GetEncoding(); + + off_t Seek(off_t ofs, wxSeekMode mode = wxFromStart); + off_t SeekEnd(off_t ofs = 0) + { + return Seek(ofs, wxFromEnd); + } + off_t Tell() const + { + return wxFile::Tell() - m_bomOffset; + } + off_t Length() const + { + return wxFile::Length() - m_bomOffset; + } + + off_t Read(wxString &str, off_t nCount = (off_t) - 1); + bool Write(const wxString &str); + +protected: + + void WriteBOM(); + void DetermineConversion(wxFontEncoding encoding); + bool EvalBOM(wxFontEncoding encoding); + + wxMBConv *m_conversion; + wxFontEncoding m_encoding; + off_t m_bomOffset; + wxString m_strFileName; +}; + +#endif // _WX_UTFFILEH__ diff --git a/include/version.h b/include/version.h new file mode 100644 index 0000000..7af7e0a --- /dev/null +++ b/include/version.h @@ -0,0 +1,44 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// version.h - pgAdmin version info +// +////////////////////////////////////////////////////////////////////////// + +#ifndef VERSION_H +#define VERSION_H + +// Application Versions +#define VERSION_STR wxT("1.25.0 Dev ASUTP version with support PG12") +#define VERSION_NUM 1,25,0,0 +#define VERSION_PACKAGE 1.25.0-dev + +#define PRERELEASE 1 +// #define BUILD "..." + +#ifdef RC_INVOKED + +#define wxT(str) str +#define _(str) str + +#include "winver.h" +#ifdef __WXDEBUG__ +#define VER_DEBUG VS_FF_DEBUG +#else +#define VER_DEBUG 0 +#endif + +#if PRERELEASE +#define VER_PRERELEASE VS_FF_PRERELEASE +#else +#define VER_PRERELEASE 0 +#endif +#endif +#define VERSION_WITH_DATE wxT("Version ") VERSION_STR wxT(" (") __TDATE__ wxT(")") +#define VERSION_WITHOUT_DATE wxT("Version ") VERSION_STR + +#endif diff --git a/libssh2/agent.c b/libssh2/agent.c new file mode 100644 index 0000000..c9efe30 --- /dev/null +++ b/libssh2/agent.c @@ -0,0 +1,862 @@ +/* + * Copyright (c) 2009 by Daiki Ueno + * Copyright (C) 2010-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" +#include +#ifdef HAVE_SYS_UN_H +#include +#else +/* Use the existence of sys/un.h as a test if Unix domain socket is + supported. winsock*.h define PF_UNIX/AF_UNIX but do not actually + support them. */ +#undef PF_UNIX +#endif +#include "userauth.h" +#include "session.h" + +/* Requests from client to agent for protocol 1 key operations */ +#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1 +#define SSH_AGENTC_RSA_CHALLENGE 3 +#define SSH_AGENTC_ADD_RSA_IDENTITY 7 +#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8 +#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9 +#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24 + +/* Requests from client to agent for protocol 2 key operations */ +#define SSH2_AGENTC_REQUEST_IDENTITIES 11 +#define SSH2_AGENTC_SIGN_REQUEST 13 +#define SSH2_AGENTC_ADD_IDENTITY 17 +#define SSH2_AGENTC_REMOVE_IDENTITY 18 +#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19 +#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25 + +/* Key-type independent requests from client to agent */ +#define SSH_AGENTC_ADD_SMARTCARD_KEY 20 +#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21 +#define SSH_AGENTC_LOCK 22 +#define SSH_AGENTC_UNLOCK 23 +#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26 + +/* Generic replies from agent to client */ +#define SSH_AGENT_FAILURE 5 +#define SSH_AGENT_SUCCESS 6 + +/* Replies from agent to client for protocol 1 key operations */ +#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2 +#define SSH_AGENT_RSA_RESPONSE 4 + +/* Replies from agent to client for protocol 2 key operations */ +#define SSH2_AGENT_IDENTITIES_ANSWER 12 +#define SSH2_AGENT_SIGN_RESPONSE 14 + +/* Key constraint identifiers */ +#define SSH_AGENT_CONSTRAIN_LIFETIME 1 +#define SSH_AGENT_CONSTRAIN_CONFIRM 2 + +/* non-blocking mode on agent connection is not yet implemented, but + for future use. */ +typedef enum { + agent_NB_state_init = 0, + agent_NB_state_request_created, + agent_NB_state_request_length_sent, + agent_NB_state_request_sent, + agent_NB_state_response_length_received, + agent_NB_state_response_received +} agent_nonblocking_states; + +typedef struct agent_transaction_ctx { + unsigned char *request; + size_t request_len; + unsigned char *response; + size_t response_len; + agent_nonblocking_states state; +} *agent_transaction_ctx_t; + +typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent); +typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent, + agent_transaction_ctx_t transctx); +typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent); + +struct agent_publickey { + struct list_node node; + + /* this is the struct we expose externally */ + struct libssh2_agent_publickey external; +}; + +struct agent_ops { + agent_connect_func connect; + agent_transact_func transact; + agent_disconnect_func disconnect; +}; + +struct _LIBSSH2_AGENT +{ + LIBSSH2_SESSION *session; /* the session this "belongs to" */ + + libssh2_socket_t fd; + + struct agent_ops *ops; + + struct agent_transaction_ctx transctx; + struct agent_publickey *identity; + struct list_head head; /* list of public keys */ + + char *identity_agent_path; /* Path to a custom identity agent socket */ +}; + +#ifdef PF_UNIX +static int +agent_connect_unix(LIBSSH2_AGENT *agent) +{ + const char *path; + struct sockaddr_un s_un; + + path = agent->identity_agent_path; + if(!path) { + path = getenv("SSH_AUTH_SOCK"); + if(!path) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "no auth sock variable"); + } + + agent->fd = socket(PF_UNIX, SOCK_STREAM, 0); + if(agent->fd < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_SOCKET, + "failed creating socket"); + + s_un.sun_family = AF_UNIX; + strncpy(s_un.sun_path, path, sizeof s_un.sun_path); + s_un.sun_path[sizeof(s_un.sun_path)-1] = 0; /* make sure there's a trailing + zero */ + if(connect(agent->fd, (struct sockaddr*)(&s_un), sizeof s_un) != 0) { + close(agent->fd); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed connecting with agent"); + } + + return LIBSSH2_ERROR_NONE; +} + +static int +agent_transact_unix(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) +{ + unsigned char buf[4]; + int rc; + + /* Send the length of the request */ + if(transctx->state == agent_NB_state_request_created) { + _libssh2_htonu32(buf, transctx->request_len); + rc = LIBSSH2_SEND_FD(agent->session, agent->fd, buf, sizeof buf, 0); + if(rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + else if(rc < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent send failed"); + transctx->state = agent_NB_state_request_length_sent; + } + + /* Send the request body */ + if(transctx->state == agent_NB_state_request_length_sent) { + rc = LIBSSH2_SEND_FD(agent->session, agent->fd, transctx->request, + transctx->request_len, 0); + if(rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + else if(rc < 0) + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent send failed"); + transctx->state = agent_NB_state_request_sent; + } + + /* Receive the length of a response */ + if(transctx->state == agent_NB_state_request_sent) { + rc = LIBSSH2_RECV_FD(agent->session, agent->fd, buf, sizeof buf, 0); + if(rc < 0) { + if(rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV, + "agent recv failed"); + } + transctx->response_len = _libssh2_ntohu32(buf); + transctx->response = LIBSSH2_ALLOC(agent->session, + transctx->response_len); + if(!transctx->response) + return LIBSSH2_ERROR_ALLOC; + + transctx->state = agent_NB_state_response_length_received; + } + + /* Receive the response body */ + if(transctx->state == agent_NB_state_response_length_received) { + rc = LIBSSH2_RECV_FD(agent->session, agent->fd, transctx->response, + transctx->response_len, 0); + if(rc < 0) { + if(rc == -EAGAIN) + return LIBSSH2_ERROR_EAGAIN; + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND, + "agent recv failed"); + } + transctx->state = agent_NB_state_response_received; + } + + return 0; +} + +static int +agent_disconnect_unix(LIBSSH2_AGENT *agent) +{ + int ret; + ret = close(agent->fd); + if(ret != -1) + agent->fd = LIBSSH2_INVALID_SOCKET; + else + return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT, + "failed closing the agent socket"); + return LIBSSH2_ERROR_NONE; +} + +struct agent_ops agent_ops_unix = { + agent_connect_unix, + agent_transact_unix, + agent_disconnect_unix +}; +#endif /* PF_UNIX */ + +#ifdef WIN32 +/* Code to talk to Pageant was taken from PuTTY. + * + * Portions copyright Robert de Bath, Joris van Rantwijk, Delian + * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas + * Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, + * Markus Kuhn, Colin Watson, and CORE SDI S.A. + */ +#define PAGEANT_COPYDATA_ID 0x804e50ba /* random goop */ +#define PAGEANT_MAX_MSGLEN 8192 + +static int +agent_connect_pageant(LIBSSH2_AGENT *agent) +{ + HWND hwnd; + hwnd = FindWindowA("Pageant", "Pageant"); + if(!hwnd) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed connecting agent"); + agent->fd = 0; /* Mark as the connection has been established */ + return LIBSSH2_ERROR_NONE; +} + +static int +agent_transact_pageant(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx) +{ + HWND hwnd; + char mapname[23]; + HANDLE filemap; + unsigned char *p; + unsigned char *p2; + int id; + COPYDATASTRUCT cds; + + if(!transctx || 4 + transctx->request_len > PAGEANT_MAX_MSGLEN) + return _libssh2_error(agent->session, LIBSSH2_ERROR_INVAL, + "illegal input"); + + hwnd = FindWindowA("Pageant", "Pageant"); + if(!hwnd) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "found no pageant"); + + snprintf(mapname, sizeof(mapname), + "PageantRequest%08x%c", (unsigned)GetCurrentThreadId(), '\0'); + filemap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, + 0, PAGEANT_MAX_MSGLEN, mapname); + + if(filemap == NULL || filemap == INVALID_HANDLE_VALUE) + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed setting up pageant filemap"); + + p2 = p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0); + if(p == NULL || p2 == NULL) { + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "failed to open pageant filemap for writing"); + } + + _libssh2_store_str(&p2, (const char *)transctx->request, + transctx->request_len); + + cds.dwData = PAGEANT_COPYDATA_ID; + cds.cbData = 1 + strlen(mapname); + cds.lpData = mapname; + + id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds); + if(id > 0) { + transctx->response_len = _libssh2_ntohu32(p); + if(transctx->response_len > PAGEANT_MAX_MSGLEN) { + UnmapViewOfFile(p); + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL, + "agent setup fail"); + } + transctx->response = LIBSSH2_ALLOC(agent->session, + transctx->response_len); + if(!transctx->response) { + UnmapViewOfFile(p); + CloseHandle(filemap); + return _libssh2_error(agent->session, LIBSSH2_ERROR_ALLOC, + "agent malloc"); + } + memcpy(transctx->response, p + 4, transctx->response_len); + } + + UnmapViewOfFile(p); + CloseHandle(filemap); + return 0; +} + +static int +agent_disconnect_pageant(LIBSSH2_AGENT *agent) +{ + agent->fd = LIBSSH2_INVALID_SOCKET; + return 0; +} + +struct agent_ops agent_ops_pageant = { + agent_connect_pageant, + agent_transact_pageant, + agent_disconnect_pageant +}; +#endif /* WIN32 */ + +static struct { + const char *name; + struct agent_ops *ops; +} supported_backends[] = { +#ifdef WIN32 + {"Pageant", &agent_ops_pageant}, +#endif /* WIN32 */ +#ifdef PF_UNIX + {"Unix", &agent_ops_unix}, +#endif /* PF_UNIX */ + {NULL, NULL} +}; + +static int +agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + LIBSSH2_AGENT *agent = (LIBSSH2_AGENT *) (*abstract); + agent_transaction_ctx_t transctx = &agent->transctx; + struct agent_publickey *identity = agent->identity; + ssize_t len = 1 + 4 + identity->external.blob_len + 4 + data_len + 4; + ssize_t method_len; + unsigned char *s; + int rc; + + /* Create a request to sign the data */ + if(transctx->state == agent_NB_state_init) { + s = transctx->request = LIBSSH2_ALLOC(session, len); + if(!transctx->request) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "out of memory"); + + *s++ = SSH2_AGENTC_SIGN_REQUEST; + /* key blob */ + _libssh2_store_str(&s, (const char *)identity->external.blob, + identity->external.blob_len); + /* data */ + _libssh2_store_str(&s, (const char *)data, data_len); + + /* flags */ + _libssh2_store_u32(&s, 0); + + transctx->request_len = s - transctx->request; + transctx->state = agent_NB_state_request_created; + } + + /* Make sure to be re-called as a result of EAGAIN. */ + if(*transctx->request != SSH2_AGENTC_SIGN_REQUEST) + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "illegal request"); + + if(!agent->ops) + /* if no agent has been connected, bail out */ + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "agent not connected"); + + rc = agent->ops->transact(agent, transctx); + if(rc) { + goto error; + } + LIBSSH2_FREE(session, transctx->request); + transctx->request = NULL; + + len = transctx->response_len; + s = transctx->response; + len--; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + if(*s != SSH2_AGENT_SIGN_RESPONSE) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s++; + + /* Skip the entire length of the signature */ + len -= 4; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s += 4; + + /* Skip signing method */ + len -= 4; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + method_len = _libssh2_ntohu32(s); + s += 4; + len -= method_len; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s += method_len; + + /* Read the signature */ + len -= 4; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + *sig_len = _libssh2_ntohu32(s); + s += 4; + len -= *sig_len; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + + *sig = LIBSSH2_ALLOC(session, *sig_len); + if(!*sig) { + rc = LIBSSH2_ERROR_ALLOC; + goto error; + } + memcpy(*sig, s, *sig_len); + + error: + LIBSSH2_FREE(session, transctx->request); + transctx->request = NULL; + + LIBSSH2_FREE(session, transctx->response); + transctx->response = NULL; + + return _libssh2_error(session, rc, "agent sign failure"); +} + +static int +agent_list_identities(LIBSSH2_AGENT *agent) +{ + agent_transaction_ctx_t transctx = &agent->transctx; + ssize_t len, num_identities; + unsigned char *s; + int rc; + unsigned char c = SSH2_AGENTC_REQUEST_IDENTITIES; + + /* Create a request to list identities */ + if(transctx->state == agent_NB_state_init) { + transctx->request = &c; + transctx->request_len = 1; + transctx->state = agent_NB_state_request_created; + } + + /* Make sure to be re-called as a result of EAGAIN. */ + if(*transctx->request != SSH2_AGENTC_REQUEST_IDENTITIES) + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "illegal agent request"); + + if(!agent->ops) + /* if no agent has been connected, bail out */ + return _libssh2_error(agent->session, LIBSSH2_ERROR_BAD_USE, + "agent not connected"); + + rc = agent->ops->transact(agent, transctx); + if(rc) { + LIBSSH2_FREE(agent->session, transctx->response); + transctx->response = NULL; + return rc; + } + transctx->request = NULL; + + len = transctx->response_len; + s = transctx->response; + len--; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + if(*s != SSH2_AGENT_IDENTITIES_ANSWER) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + s++; + + /* Read the length of identities */ + len -= 4; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + num_identities = _libssh2_ntohu32(s); + s += 4; + + while(num_identities--) { + struct agent_publickey *identity; + ssize_t comment_len; + + /* Read the length of the blob */ + len -= 4; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + goto error; + } + identity = LIBSSH2_ALLOC(agent->session, sizeof *identity); + if(!identity) { + rc = LIBSSH2_ERROR_ALLOC; + goto error; + } + identity->external.blob_len = _libssh2_ntohu32(s); + s += 4; + + /* Read the blob */ + len -= identity->external.blob_len; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity); + goto error; + } + + identity->external.blob = LIBSSH2_ALLOC(agent->session, + identity->external.blob_len); + if(!identity->external.blob) { + rc = LIBSSH2_ERROR_ALLOC; + LIBSSH2_FREE(agent->session, identity); + goto error; + } + memcpy(identity->external.blob, s, identity->external.blob_len); + s += identity->external.blob_len; + + /* Read the length of the comment */ + len -= 4; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + comment_len = _libssh2_ntohu32(s); + s += 4; + + /* Read the comment */ + len -= comment_len; + if(len < 0) { + rc = LIBSSH2_ERROR_AGENT_PROTOCOL; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + + identity->external.comment = LIBSSH2_ALLOC(agent->session, + comment_len + 1); + if(!identity->external.comment) { + rc = LIBSSH2_ERROR_ALLOC; + LIBSSH2_FREE(agent->session, identity->external.blob); + LIBSSH2_FREE(agent->session, identity); + goto error; + } + identity->external.comment[comment_len] = '\0'; + memcpy(identity->external.comment, s, comment_len); + s += comment_len; + + _libssh2_list_add(&agent->head, &identity->node); + } + error: + LIBSSH2_FREE(agent->session, transctx->response); + transctx->response = NULL; + + return _libssh2_error(agent->session, rc, + "agent list id failed"); +} + +static void +agent_free_identities(LIBSSH2_AGENT *agent) +{ + struct agent_publickey *node; + struct agent_publickey *next; + + for(node = _libssh2_list_first(&agent->head); node; node = next) { + next = _libssh2_list_next(&node->node); + LIBSSH2_FREE(agent->session, node->external.blob); + LIBSSH2_FREE(agent->session, node->external.comment); + LIBSSH2_FREE(agent->session, node); + } + _libssh2_list_init(&agent->head); +} + +#define AGENT_PUBLICKEY_MAGIC 0x3bdefed2 +/* + * agent_publickey_to_external() + * + * Copies data from the internal to the external representation struct. + * + */ +static struct libssh2_agent_publickey * +agent_publickey_to_external(struct agent_publickey *node) +{ + struct libssh2_agent_publickey *ext = &node->external; + + ext->magic = AGENT_PUBLICKEY_MAGIC; + ext->node = node; + + return ext; +} + +/* + * libssh2_agent_init + * + * Init an ssh-agent handle. Returns the pointer to the handle. + * + */ +LIBSSH2_API LIBSSH2_AGENT * +libssh2_agent_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_AGENT *agent; + + agent = LIBSSH2_CALLOC(session, sizeof *agent); + if(!agent) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for agent connection"); + return NULL; + } + agent->fd = LIBSSH2_INVALID_SOCKET; + agent->session = session; + agent->identity_agent_path = NULL; + _libssh2_list_init(&agent->head); + + return agent; +} + +/* + * libssh2_agent_connect() + * + * Connect to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_connect(LIBSSH2_AGENT *agent) +{ + int i, rc = -1; + for(i = 0; supported_backends[i].name; i++) { + agent->ops = supported_backends[i].ops; + rc = (agent->ops->connect)(agent); + if(!rc) + return 0; + } + return rc; +} + +/* + * libssh2_agent_list_identities() + * + * Request ssh-agent to list identities. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_list_identities(LIBSSH2_AGENT *agent) +{ + memset(&agent->transctx, 0, sizeof agent->transctx); + /* Abandon the last fetched identities */ + agent_free_identities(agent); + return agent_list_identities(agent); +} + +/* + * libssh2_agent_get_identity() + * + * Traverse the internal list of public keys. Pass NULL to 'prev' to get + * the first one. Or pass a pointer to the previously returned one to get the + * next. + * + * Returns: + * 0 if a fine public key was stored in 'store' + * 1 if end of public keys + * [negative] on errors + */ +LIBSSH2_API int +libssh2_agent_get_identity(LIBSSH2_AGENT *agent, + struct libssh2_agent_publickey **ext, + struct libssh2_agent_publickey *oprev) +{ + struct agent_publickey *node; + if(oprev && oprev->node) { + /* we have a starting point */ + struct agent_publickey *prev = oprev->node; + + /* get the next node in the list */ + node = _libssh2_list_next(&prev->node); + } + else + node = _libssh2_list_first(&agent->head); + + if(!node) + /* no (more) node */ + return 1; + + *ext = agent_publickey_to_external(node); + + return 0; +} + +/* + * libssh2_agent_userauth() + * + * Do publickey user authentication with the help of ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_userauth(LIBSSH2_AGENT *agent, + const char *username, + struct libssh2_agent_publickey *identity) +{ + void *abstract = agent; + int rc; + + if(agent->session->userauth_pblc_state == libssh2_NB_state_idle) { + memset(&agent->transctx, 0, sizeof agent->transctx); + agent->identity = identity->node; + } + + BLOCK_ADJUST(rc, agent->session, + _libssh2_userauth_publickey(agent->session, username, + strlen(username), + identity->blob, + identity->blob_len, + agent_sign, + &abstract)); + return rc; +} + +/* + * libssh2_agent_disconnect() + * + * Close a connection to an ssh-agent. + * + * Returns 0 if succeeded, or a negative value for error. + */ +LIBSSH2_API int +libssh2_agent_disconnect(LIBSSH2_AGENT *agent) +{ + if(agent->ops && agent->fd != LIBSSH2_INVALID_SOCKET) + return agent->ops->disconnect(agent); + return 0; +} + +/* + * libssh2_agent_free() + * + * Free an ssh-agent handle. This function also frees the internal + * collection of public keys. + */ +LIBSSH2_API void +libssh2_agent_free(LIBSSH2_AGENT *agent) +{ + /* Allow connection freeing when the socket has lost its connection */ + if(agent->fd != LIBSSH2_INVALID_SOCKET) { + libssh2_agent_disconnect(agent); + } + + if(agent->identity_agent_path != NULL) + LIBSSH2_FREE(agent->session, agent->identity_agent_path); + + agent_free_identities(agent); + LIBSSH2_FREE(agent->session, agent); +} + +/* + * libssh2_agent_set_identity_path() + * + * Allows a custom agent socket path beyond SSH_AUTH_SOCK env + * + */ +LIBSSH2_API void +libssh2_agent_set_identity_path(LIBSSH2_AGENT *agent, const char *path) +{ + if(agent->identity_agent_path) { + LIBSSH2_FREE(agent->session, agent->identity_agent_path); + agent->identity_agent_path = NULL; + } + + if(path) { + size_t path_len = strlen(path); + if(path_len < SIZE_MAX - 1) { + char *path_buf = LIBSSH2_ALLOC(agent->session, path_len + 1); + memcpy(path_buf, path, path_len); + path_buf[path_len] = '\0'; + agent->identity_agent_path = path_buf; + } + } +} + +/* + * libssh2_agent_get_identity_path() + * + * Returns the custom agent socket path if set + * + */ +LIBSSH2_API const char *libssh2_agent_get_identity_path(LIBSSH2_AGENT *agent) +{ + return agent->identity_agent_path; +} diff --git a/libssh2/bcrypt_pbkdf.c b/libssh2/bcrypt_pbkdf.c new file mode 100644 index 0000000..f9a9758 --- /dev/null +++ b/libssh2/bcrypt_pbkdf.c @@ -0,0 +1,180 @@ +/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */ +/* + * Copyright (c) 2013 Ted Unangst + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef HAVE_BCRYPT_PBKDF + +#include "libssh2_priv.h" +#include +#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif + +#include "blf.h" + +#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b)) + +/* + * pkcs #5 pbkdf2 implementation using the "bcrypt" hash + * + * The bcrypt hash function is derived from the bcrypt password hashing + * function with the following modifications: + * 1. The input password and salt are preprocessed with SHA512. + * 2. The output length is expanded to 256 bits. + * 3. Subsequently the magic string to be encrypted is lengthened and modified + * to "OxychromaticBlowfishSwatDynamite" + * 4. The hash function is defined to perform 64 rounds of initial state + * expansion. (More rounds are performed by iterating the hash.) + * + * Note that this implementation pulls the SHA512 operations into the caller + * as a performance optimization. + * + * One modification from official pbkdf2. Instead of outputting key material + * linearly, we mix it. pbkdf2 has a known weakness where if one uses it to + * generate (i.e.) 512 bits of key material for use as two 256 bit keys, an + * attacker can merely run once through the outer loop below, but the user + * always runs it twice. Shuffling output bytes requires computing the + * entirety of the key material to assemble any subkey. This is something a + * wise caller could do; we just do it for you. + */ + +#define BCRYPT_BLOCKS 8 +#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4) + +static void +bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out) +{ + blf_ctx state; + uint8_t ciphertext[BCRYPT_HASHSIZE] = + "OxychromaticBlowfishSwatDynamite"; + uint32_t cdata[BCRYPT_BLOCKS]; + int i; + uint16_t j; + size_t shalen = SHA512_DIGEST_LENGTH; + + /* key expansion */ + Blowfish_initstate(&state); + Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen); + for(i = 0; i < 64; i++) { + Blowfish_expand0state(&state, sha2salt, shalen); + Blowfish_expand0state(&state, sha2pass, shalen); + } + + /* encryption */ + j = 0; + for(i = 0; i < BCRYPT_BLOCKS; i++) + cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext), + &j); + for(i = 0; i < 64; i++) + blf_enc(&state, cdata, sizeof(cdata) / sizeof(uint64_t)); + + /* copy out */ + for(i = 0; i < BCRYPT_BLOCKS; i++) { + out[4 * i + 3] = (cdata[i] >> 24) & 0xff; + out[4 * i + 2] = (cdata[i] >> 16) & 0xff; + out[4 * i + 1] = (cdata[i] >> 8) & 0xff; + out[4 * i + 0] = cdata[i] & 0xff; + } + + /* zap */ + _libssh2_explicit_zero(ciphertext, sizeof(ciphertext)); + _libssh2_explicit_zero(cdata, sizeof(cdata)); + _libssh2_explicit_zero(&state, sizeof(state)); +} + +int +bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt, + size_t saltlen, + uint8_t *key, size_t keylen, unsigned int rounds) +{ + uint8_t sha2pass[SHA512_DIGEST_LENGTH]; + uint8_t sha2salt[SHA512_DIGEST_LENGTH]; + uint8_t out[BCRYPT_HASHSIZE]; + uint8_t tmpout[BCRYPT_HASHSIZE]; + uint8_t *countsalt; + size_t i, j, amt, stride; + uint32_t count; + size_t origkeylen = keylen; + libssh2_sha512_ctx ctx; + + /* nothing crazy */ + if(rounds < 1) + return -1; + if(passlen == 0 || saltlen == 0 || keylen == 0 || + keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20) + return -1; + countsalt = calloc(1, saltlen + 4); + if(countsalt == NULL) + return -1; + stride = (keylen + sizeof(out) - 1) / sizeof(out); + amt = (keylen + stride - 1) / stride; + + memcpy(countsalt, salt, saltlen); + + /* collapse password */ + libssh2_sha512_init(&ctx); + libssh2_sha512_update(ctx, pass, passlen); + libssh2_sha512_final(ctx, sha2pass); + + /* generate key, sizeof(out) at a time */ + for(count = 1; keylen > 0; count++) { + countsalt[saltlen + 0] = (count >> 24) & 0xff; + countsalt[saltlen + 1] = (count >> 16) & 0xff; + countsalt[saltlen + 2] = (count >> 8) & 0xff; + countsalt[saltlen + 3] = count & 0xff; + + /* first round, salt is salt */ + libssh2_sha512_init(&ctx); + libssh2_sha512_update(ctx, countsalt, saltlen + 4); + libssh2_sha512_final(ctx, sha2salt); + + bcrypt_hash(sha2pass, sha2salt, tmpout); + memcpy(out, tmpout, sizeof(out)); + + for(i = 1; i < rounds; i++) { + /* subsequent rounds, salt is previous output */ + libssh2_sha512_init(&ctx); + libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)); + libssh2_sha512_final(ctx, sha2salt); + + bcrypt_hash(sha2pass, sha2salt, tmpout); + for(j = 0; j < sizeof(out); j++) + out[j] ^= tmpout[j]; + } + + /* + * pbkdf2 deviation: output the key material non-linearly. + */ + amt = MINIMUM(amt, keylen); + for(i = 0; i < amt; i++) { + size_t dest = i * stride + (count - 1); + if(dest >= origkeylen) { + break; + } + key[dest] = out[i]; + } + keylen -= i; + } + + /* zap */ + _libssh2_explicit_zero(out, sizeof(out)); + free(countsalt); + + return 0; +} +#endif /* HAVE_BCRYPT_PBKDF */ diff --git a/libssh2/blowfish.c b/libssh2/blowfish.c new file mode 100644 index 0000000..4aefc66 --- /dev/null +++ b/libssh2/blowfish.c @@ -0,0 +1,697 @@ +/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */ +/* + * Blowfish block cipher for OpenBSD + * Copyright 1997 Niels Provos + * All rights reserved. + * + * Implementation advice by David Mazieres . + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Niels Provos. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code is derived from section 14.3 and the given source + * in section V of Applied Cryptography, second edition. + * Blowfish is an unpatented fast block cipher designed by + * Bruce Schneier. + */ + + +#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \ + !defined(HAVE_BLOWFISH_EXPAND0STATE) || \ + !defined(HAVE_BLF_ENC)) + +#if 0 +#include /* used for debugging */ +#include +#endif + +#include + +#include "libssh2.h" +#include "blf.h" + +#undef inline +#ifdef __GNUC__ +#define inline __inline +#else /* !__GNUC__ */ +#define inline +#endif /* !__GNUC__ */ + +/* Function for Feistel Networks */ + +#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \ + + (s)[0x100 + (((x)>>16)&0xFF)]) \ + ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ + + (s)[0x300 + ( (x) &0xFF)]) + +#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) + +void +Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr) +{ + uint32_t Xl; + uint32_t Xr; + uint32_t *s = c->S[0]; + uint32_t *p = c->P; + + Xl = *xl; + Xr = *xr; + + Xl ^= p[0]; + BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2); + BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4); + BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6); + BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8); + BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10); + BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12); + BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14); + BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16); + + *xl = Xr ^ p[17]; + *xr = Xl; +} + +void +Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr) +{ + uint32_t Xl; + uint32_t Xr; + uint32_t *s = c->S[0]; + uint32_t *p = c->P; + + Xl = *xl; + Xr = *xr; + + Xl ^= p[17]; + BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15); + BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13); + BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11); + BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9); + BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7); + BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5); + BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3); + BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1); + + *xl = Xr ^ p[0]; + *xr = Xl; +} + +void +Blowfish_initstate(blf_ctx *c) +{ + /* P-box and S-box tables initialized with digits of Pi */ + + static const blf_ctx initstate = + { { + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, + { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, + { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, + { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} + }, + { + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b + } }; + + *c = initstate; +} + +uint32_t +Blowfish_stream2word(const uint8_t *data, uint16_t databytes, + uint16_t *current) +{ + uint8_t i; + uint16_t j; + uint32_t temp; + + temp = 0x00000000; + j = *current; + + for(i = 0; i < 4; i++, j++) { + if(j >= databytes) + j = 0; + temp = (temp << 8) | data[j]; + } + + *current = j; + return temp; +} + +void +Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes) +{ + uint16_t i; + uint16_t j; + uint16_t k; + uint32_t temp; + uint32_t datal; + uint32_t datar; + + j = 0; + for(i = 0; i < BLF_N + 2; i++) { + /* Extract 4 int8 to 1 int32 from keystream */ + temp = Blowfish_stream2word(key, keybytes, &j); + c->P[i] = c->P[i] ^ temp; + } + + j = 0; + datal = 0x00000000; + datar = 0x00000000; + for(i = 0; i < BLF_N + 2; i += 2) { + Blowfish_encipher(c, &datal, &datar); + + c->P[i] = datal; + c->P[i + 1] = datar; + } + + for(i = 0; i < 4; i++) { + for(k = 0; k < 256; k += 2) { + Blowfish_encipher(c, &datal, &datar); + + c->S[i][k] = datal; + c->S[i][k + 1] = datar; + } + } +} + + +void +Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes, + const uint8_t *key, uint16_t keybytes) +{ + uint16_t i; + uint16_t j; + uint16_t k; + uint32_t temp; + uint32_t datal; + uint32_t datar; + + j = 0; + for(i = 0; i < BLF_N + 2; i++) { + /* Extract 4 int8 to 1 int32 from keystream */ + temp = Blowfish_stream2word(key, keybytes, &j); + c->P[i] = c->P[i] ^ temp; + } + + j = 0; + datal = 0x00000000; + datar = 0x00000000; + for(i = 0; i < BLF_N + 2; i += 2) { + datal ^= Blowfish_stream2word(data, databytes, &j); + datar ^= Blowfish_stream2word(data, databytes, &j); + Blowfish_encipher(c, &datal, &datar); + + c->P[i] = datal; + c->P[i + 1] = datar; + } + + for(i = 0; i < 4; i++) { + for(k = 0; k < 256; k += 2) { + datal ^= Blowfish_stream2word(data, databytes, &j); + datar ^= Blowfish_stream2word(data, databytes, &j); + Blowfish_encipher(c, &datal, &datar); + + c->S[i][k] = datal; + c->S[i][k + 1] = datar; + } + } + +} + +void +blf_key(blf_ctx *c, const uint8_t *k, uint16_t len) +{ + /* Initialize S-boxes and subkeys with Pi */ + Blowfish_initstate(c); + + /* Transform S-boxes and subkeys with key */ + Blowfish_expand0state(c, k, len); +} + +void +blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks) +{ + uint32_t *d; + uint16_t i; + + d = data; + for(i = 0; i < blocks; i++) { + Blowfish_encipher(c, d, d + 1); + d += 2; + } +} + +void +blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks) +{ + uint32_t *d; + uint16_t i; + + d = data; + for(i = 0; i < blocks; i++) { + Blowfish_decipher(c, d, d + 1); + d += 2; + } +} + +void +blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len) +{ + uint32_t l, r; + uint32_t i; + + for(i = 0; i < len; i += 8) { + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_encipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + data += 8; + } +} + +void +blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len) +{ + uint32_t l, r; + uint32_t i; + + for(i = 0; i < len; i += 8) { + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_decipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + data += 8; + } +} + +void +blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len) +{ + uint32_t l, r; + uint32_t i, j; + + for(i = 0; i < len; i += 8) { + for(j = 0; j < 8; j++) + data[j] ^= iv[j]; + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_encipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + iv = data; + data += 8; + } +} + +void +blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len) +{ + uint32_t l, r; + uint8_t *iv; + uint32_t i, j; + + iv = data + len - 16; + data = data + len - 8; + for(i = len - 8; i >= 8; i -= 8) { + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_decipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + for(j = 0; j < 8; j++) + data[j] ^= iv[j]; + iv -= 8; + data -= 8; + } + l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; + r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; + Blowfish_decipher(c, &l, &r); + data[0] = l >> 24 & 0xff; + data[1] = l >> 16 & 0xff; + data[2] = l >> 8 & 0xff; + data[3] = l & 0xff; + data[4] = r >> 24 & 0xff; + data[5] = r >> 16 & 0xff; + data[6] = r >> 8 & 0xff; + data[7] = r & 0xff; + for(j = 0; j < 8; j++) + data[j] ^= iva[j]; +} + +#if 0 +void +report(uint32_t data[], uint16_t len) +{ + uint16_t i; + for(i = 0; i < len; i += 2) + printf("Block %0hd: %08lx %08lx.\n", + i / 2, data[i], data[i + 1]); +} +void +main(void) +{ + + blf_ctx c; + char key[] = "AAAAA"; + char key2[] = "abcdefghijklmnopqrstuvwxyz"; + + uint32_t data[10]; + uint32_t data2[] = + {0x424c4f57l, 0x46495348l}; + + uint16_t i; + + /* First test */ + for(i = 0; i < 10; i++) + data[i] = i; + + blf_key(&c, (uint8_t *) key, 5); + blf_enc(&c, data, 5); + blf_dec(&c, data, 1); + blf_dec(&c, data + 2, 4); + printf("Should read as 0 - 9.\n"); + report(data, 10); + + /* Second test */ + blf_key(&c, (uint8_t *) key2, strlen(key2)); + blf_enc(&c, data2, 1); + printf("\nShould read as: 0x324ed0fe 0xf413a203.\n"); + report(data2, 2); + blf_dec(&c, data2, 1); + report(data2, 2); +} +#endif + +#endif /* !defined(HAVE_BCRYPT_PBKDF) && \ + (!defined(HAVE_BLOWFISH_INITSTATE) || \ + !defined(HAVE_BLOWFISH_EXPAND0STATE) || \ + '!defined(HAVE_BLF_ENC)) */ diff --git a/libssh2/channel.c b/libssh2/channel.c new file mode 100644 index 0000000..55a16e9 --- /dev/null +++ b/libssh2/channel.c @@ -0,0 +1,2891 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2005 Mikhail Gusarov + * Copyright (c) 2008-2019 by Daniel Stenberg + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef HAVE_INTTYPES_H +#include +#endif +#include + +#include "channel.h" +#include "transport.h" +#include "packet.h" +#include "session.h" + +/* + * _libssh2_channel_nextid + * + * Determine the next channel ID we can use at our end + */ +uint32_t +_libssh2_channel_nextid(LIBSSH2_SESSION * session) +{ + uint32_t id = session->next_channel; + LIBSSH2_CHANNEL *channel; + + channel = _libssh2_list_first(&session->channels); + + while(channel) { + if(channel->local.id > id) { + id = channel->local.id; + } + channel = _libssh2_list_next(&channel->node); + } + + /* This is a shortcut to avoid waiting for close packets on channels we've + * forgotten about, This *could* be a problem if we request and close 4 + * billion or so channels in too rapid succession for the remote end to + * respond, but the worst case scenario is that some data meant for + * another channel Gets picked up by the new one.... Pretty unlikely all + * told... + */ + session->next_channel = id + 1; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Allocated new channel ID#%lu", + id); + return id; +} + +/* + * _libssh2_channel_locate + * + * Locate a channel pointer by number + */ +LIBSSH2_CHANNEL * +_libssh2_channel_locate(LIBSSH2_SESSION *session, uint32_t channel_id) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_LISTENER *l; + + for(channel = _libssh2_list_first(&session->channels); + channel; + channel = _libssh2_list_next(&channel->node)) { + if(channel->local.id == channel_id) + return channel; + } + + /* We didn't find the channel in the session, let's then check its + listeners since each listener may have its own set of pending channels + */ + for(l = _libssh2_list_first(&session->listeners); l; + l = _libssh2_list_next(&l->node)) { + for(channel = _libssh2_list_first(&l->queue); + channel; + channel = _libssh2_list_next(&channel->node)) { + if(channel->local.id == channel_id) + return channel; + } + } + + return NULL; +} + +/* + * _libssh2_channel_open + * + * Establish a generic session channel + */ +LIBSSH2_CHANNEL * +_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type, + uint32_t channel_type_len, + uint32_t window_size, + uint32_t packet_size, + const unsigned char *message, + size_t message_len) +{ + static const unsigned char reply_codes[3] = { + SSH_MSG_CHANNEL_OPEN_CONFIRMATION, + SSH_MSG_CHANNEL_OPEN_FAILURE, + 0 + }; + unsigned char *s; + int rc; + + if(session->open_state == libssh2_NB_state_idle) { + session->open_channel = NULL; + session->open_packet = NULL; + session->open_data = NULL; + /* 17 = packet_type(1) + channel_type_len(4) + sender_channel(4) + + * window_size(4) + packet_size(4) */ + session->open_packet_len = channel_type_len + 17; + session->open_local_channel = _libssh2_channel_nextid(session); + + /* Zero the whole thing out */ + memset(&session->open_packet_requirev_state, 0, + sizeof(session->open_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Opening Channel - win %d pack %d", window_size, + packet_size); + session->open_channel = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if(!session->open_channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate space for channel data"); + return NULL; + } + session->open_channel->channel_type_len = channel_type_len; + session->open_channel->channel_type = + LIBSSH2_ALLOC(session, channel_type_len); + if(!session->open_channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating memory for channel type name"); + LIBSSH2_FREE(session, session->open_channel); + session->open_channel = NULL; + return NULL; + } + memcpy(session->open_channel->channel_type, channel_type, + channel_type_len); + + /* REMEMBER: local as in locally sourced */ + session->open_channel->local.id = session->open_local_channel; + session->open_channel->remote.window_size = window_size; + session->open_channel->remote.window_size_initial = window_size; + session->open_channel->remote.packet_size = packet_size; + session->open_channel->session = session; + + _libssh2_list_add(&session->channels, + &session->open_channel->node); + + s = session->open_packet = + LIBSSH2_ALLOC(session, session->open_packet_len); + if(!session->open_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate temporary space for packet"); + goto channel_error; + } + *(s++) = SSH_MSG_CHANNEL_OPEN; + _libssh2_store_str(&s, channel_type, channel_type_len); + _libssh2_store_u32(&s, session->open_local_channel); + _libssh2_store_u32(&s, window_size); + _libssh2_store_u32(&s, packet_size); + + /* Do not copy the message */ + + session->open_state = libssh2_NB_state_created; + } + + if(session->open_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + session->open_packet, + session->open_packet_len, + message, message_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending channel-open request"); + return NULL; + } + else if(rc) { + _libssh2_error(session, rc, + "Unable to send channel-open request"); + goto channel_error; + } + + session->open_state = libssh2_NB_state_sent; + } + + if(session->open_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->open_data, + &session->open_data_len, 1, + session->open_packet + 5 + + channel_type_len, 4, + &session->open_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + return NULL; + } + else if(rc) { + _libssh2_error(session, rc, "Unexpected error"); + goto channel_error; + } + + if(session->open_data_len < 1) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet size"); + goto channel_error; + } + + if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { + + if(session->open_data_len < 17) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet size"); + goto channel_error; + } + + session->open_channel->remote.id = + _libssh2_ntohu32(session->open_data + 5); + session->open_channel->local.window_size = + _libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.window_size_initial = + _libssh2_ntohu32(session->open_data + 9); + session->open_channel->local.packet_size = + _libssh2_ntohu32(session->open_data + 13); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Connection Established - ID: %lu/%lu win: %lu/%lu" + " pack: %lu/%lu", + session->open_channel->local.id, + session->open_channel->remote.id, + session->open_channel->local.window_size, + session->open_channel->remote.window_size, + session->open_channel->local.packet_size, + session->open_channel->remote.packet_size); + LIBSSH2_FREE(session, session->open_packet); + session->open_packet = NULL; + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + + session->open_state = libssh2_NB_state_idle; + return session->open_channel; + } + + if(session->open_data[0] == SSH_MSG_CHANNEL_OPEN_FAILURE) { + unsigned int reason_code = + _libssh2_ntohu32(session->open_data + 5); + switch(reason_code) { + case SSH_OPEN_ADMINISTRATIVELY_PROHIBITED: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure " + "(administratively prohibited)"); + break; + case SSH_OPEN_CONNECT_FAILED: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (connect failed)"); + break; + case SSH_OPEN_UNKNOWN_CHANNELTYPE: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (unknown channel type)"); + break; + case SSH_OPEN_RESOURCE_SHORTAGE: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure (resource shortage)"); + break; + default: + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Channel open failure"); + } + } + } + + channel_error: + + if(session->open_data) { + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + } + if(session->open_packet) { + LIBSSH2_FREE(session, session->open_packet); + session->open_packet = NULL; + } + if(session->open_channel) { + unsigned char channel_id[4]; + LIBSSH2_FREE(session, session->open_channel->channel_type); + + _libssh2_list_remove(&session->open_channel->node); + + /* Clear out packets meant for this channel */ + _libssh2_htonu32(channel_id, session->open_channel->local.id); + while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, + &session->open_data, + &session->open_data_len, 1, + channel_id, 4) >= 0) + || + (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, + &session->open_data, + &session->open_data_len, 1, + channel_id, 4) >= 0)) { + LIBSSH2_FREE(session, session->open_data); + session->open_data = NULL; + } + + LIBSSH2_FREE(session, session->open_channel); + session->open_channel = NULL; + } + + session->open_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_channel_open_ex + * + * Establish a generic session channel + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_open_ex(LIBSSH2_SESSION *session, const char *type, + unsigned int type_len, + unsigned int window_size, unsigned int packet_size, + const char *msg, unsigned int msg_len) +{ + LIBSSH2_CHANNEL *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + _libssh2_channel_open(session, type, type_len, + window_size, packet_size, + (unsigned char *)msg, + msg_len)); + return ptr; +} + +/* + * libssh2_channel_direct_tcpip_ex + * + * Tunnel TCP/IP connect through the SSH session to direct host/port + */ +static LIBSSH2_CHANNEL * +channel_direct_tcpip(LIBSSH2_SESSION * session, const char *host, + int port, const char *shost, int sport) +{ + LIBSSH2_CHANNEL *channel; + unsigned char *s; + + if(session->direct_state == libssh2_NB_state_idle) { + session->direct_host_len = strlen(host); + session->direct_shost_len = strlen(shost); + /* host_len(4) + port(4) + shost_len(4) + sport(4) */ + session->direct_message_len = + session->direct_host_len + session->direct_shost_len + 16; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting direct-tcpip session from %s:%d to %s:%d", + shost, sport, host, port); + + s = session->direct_message = + LIBSSH2_ALLOC(session, session->direct_message_len); + if(!session->direct_message) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "direct-tcpip connection"); + return NULL; + } + _libssh2_store_str(&s, host, session->direct_host_len); + _libssh2_store_u32(&s, port); + _libssh2_store_str(&s, shost, session->direct_shost_len); + _libssh2_store_u32(&s, sport); + } + + channel = + _libssh2_channel_open(session, "direct-tcpip", + sizeof("direct-tcpip") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, + session->direct_message, + session->direct_message_len); + + if(!channel && + libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { + /* The error code is still set to LIBSSH2_ERROR_EAGAIN, set our state + to created to avoid re-creating the package on next invoke */ + session->direct_state = libssh2_NB_state_created; + return NULL; + } + /* by default we set (keep?) idle state... */ + session->direct_state = libssh2_NB_state_idle; + + LIBSSH2_FREE(session, session->direct_message); + session->direct_message = NULL; + + return channel; +} + +/* + * libssh2_channel_direct_tcpip_ex + * + * Tunnel TCP/IP connect through the SSH session to direct host/port + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_direct_tcpip_ex(LIBSSH2_SESSION *session, const char *host, + int port, const char *shost, int sport) +{ + LIBSSH2_CHANNEL *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + channel_direct_tcpip(session, host, port, + shost, sport)); + return ptr; +} + +/* + * channel_forward_listen + * + * Bind a port on the remote host and listen for connections + */ +static LIBSSH2_LISTENER * +channel_forward_listen(LIBSSH2_SESSION * session, const char *host, + int port, int *bound_port, int queue_maxsize) +{ + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_REQUEST_SUCCESS, SSH_MSG_REQUEST_FAILURE, 0 }; + int rc; + + if(!host) + host = "0.0.0.0"; + + if(session->fwdLstn_state == libssh2_NB_state_idle) { + session->fwdLstn_host_len = strlen(host); + /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + + port(4) */ + session->fwdLstn_packet_len = + session->fwdLstn_host_len + (sizeof("tcpip-forward") - 1) + 14; + + /* Zero the whole thing out */ + memset(&session->fwdLstn_packet_requirev_state, 0, + sizeof(session->fwdLstn_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting tcpip-forward session for %s:%d", host, + port); + + s = session->fwdLstn_packet = + LIBSSH2_ALLOC(session, session->fwdLstn_packet_len); + if(!session->fwdLstn_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for setenv packet"); + return NULL; + } + + *(s++) = SSH_MSG_GLOBAL_REQUEST; + _libssh2_store_str(&s, "tcpip-forward", sizeof("tcpip-forward") - 1); + *(s++) = 0x01; /* want_reply */ + + _libssh2_store_str(&s, host, session->fwdLstn_host_len); + _libssh2_store_u32(&s, port); + + session->fwdLstn_state = libssh2_NB_state_created; + } + + if(session->fwdLstn_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + session->fwdLstn_packet, + session->fwdLstn_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending global-request packet for " + "forward listen request"); + return NULL; + } + else if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward " + "listen request"); + LIBSSH2_FREE(session, session->fwdLstn_packet); + session->fwdLstn_packet = NULL; + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + LIBSSH2_FREE(session, session->fwdLstn_packet); + session->fwdLstn_packet = NULL; + + session->fwdLstn_state = libssh2_NB_state_sent; + } + + if(session->fwdLstn_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 0, NULL, 0, + &session->fwdLstn_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block"); + return NULL; + } + else if(rc || (data_len < 1)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown"); + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + + if(data[0] == SSH_MSG_REQUEST_SUCCESS) { + LIBSSH2_LISTENER *listener; + + listener = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_LISTENER)); + if(!listener) + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for listener queue"); + else { + listener->host = + LIBSSH2_ALLOC(session, session->fwdLstn_host_len + 1); + if(!listener->host) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for listener queue"); + LIBSSH2_FREE(session, listener); + listener = NULL; + } + else { + listener->session = session; + memcpy(listener->host, host, session->fwdLstn_host_len); + listener->host[session->fwdLstn_host_len] = 0; + if(data_len >= 5 && !port) { + listener->port = _libssh2_ntohu32(data + 1); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Dynamic tcpip-forward port " + "allocated: %d", + listener->port); + } + else + listener->port = port; + + listener->queue_size = 0; + listener->queue_maxsize = queue_maxsize; + + /* append this to the parent's list of listeners */ + _libssh2_list_add(&session->listeners, &listener->node); + + if(bound_port) { + *bound_port = listener->port; + } + } + } + + LIBSSH2_FREE(session, data); + session->fwdLstn_state = libssh2_NB_state_idle; + return listener; + } + else if(data[0] == SSH_MSG_REQUEST_FAILURE) { + LIBSSH2_FREE(session, data); + _libssh2_error(session, LIBSSH2_ERROR_REQUEST_DENIED, + "Unable to complete request for forward-listen"); + session->fwdLstn_state = libssh2_NB_state_idle; + return NULL; + } + } + + session->fwdLstn_state = libssh2_NB_state_idle; + + return NULL; +} + +/* + * libssh2_channel_forward_listen_ex + * + * Bind a port on the remote host and listen for connections + */ +LIBSSH2_API LIBSSH2_LISTENER * +libssh2_channel_forward_listen_ex(LIBSSH2_SESSION *session, const char *host, + int port, int *bound_port, int queue_maxsize) +{ + LIBSSH2_LISTENER *ptr; + + if(!session) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, + channel_forward_listen(session, host, port, bound_port, + queue_maxsize)); + return ptr; +} + +/* + * _libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +{ + LIBSSH2_SESSION *session = listener->session; + LIBSSH2_CHANNEL *queued; + unsigned char *packet, *s; + size_t host_len = strlen(listener->host); + /* 14 = packet_type(1) + request_len(4) + want_replay(1) + host_len(4) + + port(4) */ + size_t packet_len = + host_len + 14 + sizeof("cancel-tcpip-forward") - 1; + int rc; + int retcode = 0; + + if(listener->chanFwdCncl_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Cancelling tcpip-forward session for %s:%d", + listener->host, listener->port); + + s = packet = LIBSSH2_ALLOC(session, packet_len); + if(!packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for setenv packet"); + return LIBSSH2_ERROR_ALLOC; + } + + *(s++) = SSH_MSG_GLOBAL_REQUEST; + _libssh2_store_str(&s, "cancel-tcpip-forward", + sizeof("cancel-tcpip-forward") - 1); + *(s++) = 0x00; /* want_reply */ + + _libssh2_store_str(&s, listener->host, host_len); + _libssh2_store_u32(&s, listener->port); + + listener->chanFwdCncl_state = libssh2_NB_state_created; + } + else { + packet = listener->chanFwdCncl_data; + } + + if(listener->chanFwdCncl_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, packet, packet_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending forward request"); + listener->chanFwdCncl_data = packet; + return rc; + } + else if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send global-request packet for forward " + "listen request"); + /* set the state to something we don't check for, for the + unfortunate situation where we get an EAGAIN further down + when trying to bail out due to errors! */ + listener->chanFwdCncl_state = libssh2_NB_state_sent; + retcode = LIBSSH2_ERROR_SOCKET_SEND; + } + LIBSSH2_FREE(session, packet); + + listener->chanFwdCncl_state = libssh2_NB_state_sent; + } + + queued = _libssh2_list_first(&listener->queue); + while(queued) { + LIBSSH2_CHANNEL *next = _libssh2_list_next(&queued->node); + + rc = _libssh2_channel_free(queued); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + queued = next; + } + LIBSSH2_FREE(session, listener->host); + + /* remove this entry from the parent's list of listeners */ + _libssh2_list_remove(&listener->node); + + LIBSSH2_FREE(session, listener); + + return retcode; +} + +/* + * libssh2_channel_forward_cancel + * + * Stop listening on a remote port and free the listener + * Toss out any pending (un-accept()ed) connections + * + * Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error + */ +LIBSSH2_API int +libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener) +{ + int rc; + + if(!listener) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, listener->session, + _libssh2_channel_forward_cancel(listener)); + return rc; +} + +/* + * channel_forward_accept + * + * Accept a connection + */ +static LIBSSH2_CHANNEL * +channel_forward_accept(LIBSSH2_LISTENER *listener) +{ + int rc; + + do { + rc = _libssh2_transport_read(listener->session); + } while(rc > 0); + + if(_libssh2_list_first(&listener->queue)) { + LIBSSH2_CHANNEL *channel = _libssh2_list_first(&listener->queue); + + /* detach channel from listener's queue */ + _libssh2_list_remove(&channel->node); + + listener->queue_size--; + + /* add channel to session's channel list */ + _libssh2_list_add(&channel->session->channels, &channel->node); + + return channel; + } + + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(listener->session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for packet"); + } + else + _libssh2_error(listener->session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Channel not found"); + return NULL; +} + +/* + * libssh2_channel_forward_accept + * + * Accept a connection + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_channel_forward_accept(LIBSSH2_LISTENER *listener) +{ + LIBSSH2_CHANNEL *ptr; + + if(!listener) + return NULL; + + BLOCK_ADJUST_ERRNO(ptr, listener->session, + channel_forward_accept(listener)); + return ptr; + +} + +/* + * channel_setenv + * + * Set an environment variable prior to requesting a shell/program/subsystem + */ +static int channel_setenv(LIBSSH2_CHANNEL *channel, + const char *varname, unsigned int varname_len, + const char *value, unsigned int value_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s, *data; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + size_t data_len; + int rc; + + if(channel->setenv_state == libssh2_NB_state_idle) { + /* 21 = packet_type(1) + channel_id(4) + request_len(4) + + * request(3)"env" + want_reply(1) + varname_len(4) + value_len(4) */ + channel->setenv_packet_len = varname_len + value_len + 21; + + /* Zero the whole thing out */ + memset(&channel->setenv_packet_requirev_state, 0, + sizeof(channel->setenv_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Setting remote environment variable: %s=%s on " + "channel %lu/%lu", + varname, value, channel->local.id, channel->remote.id); + + s = channel->setenv_packet = + LIBSSH2_ALLOC(session, channel->setenv_packet_len); + if(!channel->setenv_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for setenv packet"); + } + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, "env", sizeof("env") - 1); + *(s++) = 0x01; + _libssh2_store_str(&s, varname, varname_len); + _libssh2_store_str(&s, value, value_len); + + channel->setenv_state = libssh2_NB_state_created; + } + + if(channel->setenv_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + channel->setenv_packet, + channel->setenv_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending setenv request"); + return rc; + } + else if(rc) { + LIBSSH2_FREE(session, channel->setenv_packet); + channel->setenv_packet = NULL; + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel-request packet for " + "setenv request"); + } + LIBSSH2_FREE(session, channel->setenv_packet); + channel->setenv_packet = NULL; + + _libssh2_htonu32(channel->setenv_local_channel, channel->local.id); + + channel->setenv_state = libssh2_NB_state_sent; + } + + if(channel->setenv_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->setenv_local_channel, 4, + &channel-> + setenv_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if(rc) { + channel->setenv_state = libssh2_NB_state_idle; + return rc; + } + else if(data_len < 1) { + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet size"); + } + + if(data[0] == SSH_MSG_CHANNEL_SUCCESS) { + LIBSSH2_FREE(session, data); + channel->setenv_state = libssh2_NB_state_idle; + return 0; + } + + LIBSSH2_FREE(session, data); + } + + channel->setenv_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel-setenv"); +} + +/* + * libssh2_channel_setenv_ex + * + * Set an environment variable prior to requesting a shell/program/subsystem + */ +LIBSSH2_API int +libssh2_channel_setenv_ex(LIBSSH2_CHANNEL *channel, + const char *varname, unsigned int varname_len, + const char *value, unsigned int value_len) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_setenv(channel, varname, varname_len, + value, value_len)); + return rc; +} + +/* + * channel_request_pty + * Duh... Request a PTY + */ +static int channel_request_pty(LIBSSH2_CHANNEL *channel, + const char *term, unsigned int term_len, + const char *modes, unsigned int modes_len, + int width, int height, + int width_px, int height_px) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if(channel->reqPTY_state == libssh2_NB_state_idle) { + /* 41 = packet_type(1) + channel(4) + pty_req_len(4) + "pty_req"(7) + + * want_reply(1) + term_len(4) + width(4) + height(4) + width_px(4) + + * height_px(4) + modes_len(4) */ + if(term_len + modes_len > 256) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "term + mode lengths too large"); + } + + channel->reqPTY_packet_len = term_len + modes_len + 41; + + /* Zero the whole thing out */ + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Allocating tty on channel %lu/%lu", channel->local.id, + channel->remote.id); + + s = channel->reqPTY_packet; + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)"pty-req", sizeof("pty-req") - 1); + + *(s++) = 0x01; + + _libssh2_store_str(&s, term, term_len); + _libssh2_store_u32(&s, width); + _libssh2_store_u32(&s, height); + _libssh2_store_u32(&s, width_px); + _libssh2_store_u32(&s, height_px); + _libssh2_store_str(&s, modes, modes_len); + + channel->reqPTY_state = libssh2_NB_state_created; + } + + if(channel->reqPTY_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqPTY_packet, + channel->reqPTY_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending pty request"); + return rc; + } + else if(rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send pty-request packet"); + } + _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); + + channel->reqPTY_state = libssh2_NB_state_sent; + } + + if(channel->reqPTY_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->reqPTY_local_channel, 4, + &channel->reqPTY_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc || data_len < 1) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Failed to require the PTY package"); + } + + code = data[0]; + + LIBSSH2_FREE(session, data); + channel->reqPTY_state = libssh2_NB_state_idle; + + if(code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for " + "channel request-pty"); +} + +/** + * channel_request_auth_agent + * The actual re-entrant method which requests an auth agent. + * */ +static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel, + const char *request_str, + int request_str_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if(channel->req_auth_agent_state == libssh2_NB_state_idle) { + /* Only valid options are "auth-agent-req" and + * "auth-agent-req_at_openssh.com" so we make sure it is not + * actually longer than the longest possible. */ + if(request_str_len > 26) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "request_str length too large"); + } + + /* + * Length: 24 or 36 = packet_type(1) + channel(4) + req_len(4) + + * request_str (variable) + want_reply (1) */ + channel->req_auth_agent_packet_len = 10 + request_str_len; + + /* Zero out the requireev state to reset */ + memset(&channel->req_auth_agent_requirev_state, 0, + sizeof(channel->req_auth_agent_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting auth agent on channel %lu/%lu", + channel->local.id, channel->remote.id); + + /* + * byte SSH_MSG_CHANNEL_REQUEST + * uint32 recipient channel + * string "auth-agent-req" + * boolean want reply + * */ + s = channel->req_auth_agent_packet; + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)request_str, request_str_len); + *(s++) = 0x01; + + channel->req_auth_agent_state = libssh2_NB_state_created; + } + + if(channel->req_auth_agent_state == libssh2_NB_state_created) { + /* Send the packet, we can use sizeof() on the packet because it + * is always completely filled; there are no variable length fields. */ + rc = _libssh2_transport_send(session, channel->req_auth_agent_packet, + channel->req_auth_agent_packet_len, + NULL, 0); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending auth-agent request"); + } + else if(rc) { + channel->req_auth_agent_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send auth-agent request"); + } + _libssh2_htonu32(channel->req_auth_agent_local_channel, + channel->local.id); + channel->req_auth_agent_state = libssh2_NB_state_sent; + } + + if(channel->req_auth_agent_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + + rc = _libssh2_packet_requirev( + session, reply_codes, &data, &data_len, 1, + channel->req_auth_agent_local_channel, + 4, &channel->req_auth_agent_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + channel->req_auth_agent_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Failed to request auth-agent"); + } + + code = data[0]; + + LIBSSH2_FREE(session, data); + channel->req_auth_agent_state = libssh2_NB_state_idle; + + if(code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for auth-agent"); +} + +/** + * libssh2_channel_request_auth_agent + * Requests that agent forwarding be enabled for the session. The + * request must be sent over a specific channel, which starts the agent + * listener on the remote side. Once the channel is closed, the agent + * listener continues to exist. + * */ +LIBSSH2_API int +libssh2_channel_request_auth_agent(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + /* The current RFC draft for agent forwarding says you're supposed to + * send "auth-agent-req," but most SSH servers out there right now + * actually expect "auth-agent-req@openssh.com", so we try that + * first. */ + if(channel->req_auth_agent_try_state == libssh2_NB_state_idle) { + BLOCK_ADJUST(rc, channel->session, + channel_request_auth_agent(channel, + "auth-agent-req@openssh.com", + 26)); + + /* If we failed (but not with EAGAIN), then we move onto + * the next step to try another request type. */ + if(rc != 0 && rc != LIBSSH2_ERROR_EAGAIN) + channel->req_auth_agent_try_state = libssh2_NB_state_sent; + } + + if(channel->req_auth_agent_try_state == libssh2_NB_state_sent) { + BLOCK_ADJUST(rc, channel->session, + channel_request_auth_agent(channel, + "auth-agent-req", 14)); + + /* If we failed without an EAGAIN, then move on with this + * state machine. */ + if(rc != 0 && rc != LIBSSH2_ERROR_EAGAIN) + channel->req_auth_agent_try_state = libssh2_NB_state_sent1; + } + + /* If things are good, reset the try state. */ + if(rc == 0) + channel->req_auth_agent_try_state = libssh2_NB_state_idle; + + return rc; +} + +/* + * libssh2_channel_request_pty_ex + * Duh... Request a PTY + */ +LIBSSH2_API int +libssh2_channel_request_pty_ex(LIBSSH2_CHANNEL *channel, const char *term, + unsigned int term_len, const char *modes, + unsigned int modes_len, int width, int height, + int width_px, int height_px) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_request_pty(channel, term, term_len, modes, + modes_len, width, height, + width_px, height_px)); + return rc; +} + +static int +channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width, + int height, int width_px, int height_px) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + int rc; + int retcode = LIBSSH2_ERROR_PROTO; + + if(channel->reqPTY_state == libssh2_NB_state_idle) { + channel->reqPTY_packet_len = 39; + + /* Zero the whole thing out */ + memset(&channel->reqPTY_packet_requirev_state, 0, + sizeof(channel->reqPTY_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "changing tty size on channel %lu/%lu", + channel->local.id, + channel->remote.id); + + s = channel->reqPTY_packet; + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, (char *)"window-change", + sizeof("window-change") - 1); + *(s++) = 0x00; /* Don't reply */ + _libssh2_store_u32(&s, width); + _libssh2_store_u32(&s, height); + _libssh2_store_u32(&s, width_px); + _libssh2_store_u32(&s, height_px); + + channel->reqPTY_state = libssh2_NB_state_created; + } + + if(channel->reqPTY_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqPTY_packet, + channel->reqPTY_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending window-change request"); + return rc; + } + else if(rc) { + channel->reqPTY_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send window-change packet"); + } + _libssh2_htonu32(channel->reqPTY_local_channel, channel->local.id); + retcode = LIBSSH2_ERROR_NONE; + } + + channel->reqPTY_state = libssh2_NB_state_idle; + return retcode; +} + +LIBSSH2_API int +libssh2_channel_request_pty_size_ex(LIBSSH2_CHANNEL *channel, int width, + int height, int width_px, int height_px) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_request_pty_size(channel, width, height, width_px, + height_px)); + return rc; +} + +/* Keep this an even number */ +#define LIBSSH2_X11_RANDOM_COOKIE_LEN 32 + +/* + * channel_x11_req + * Request X11 forwarding + */ +static int +channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection, + const char *auth_proto, const char *auth_cookie, + int screen_number) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + size_t proto_len = + auth_proto ? strlen(auth_proto) : (sizeof("MIT-MAGIC-COOKIE-1") - 1); + size_t cookie_len = + auth_cookie ? strlen(auth_cookie) : LIBSSH2_X11_RANDOM_COOKIE_LEN; + int rc; + + if(channel->reqX11_state == libssh2_NB_state_idle) { + /* 30 = packet_type(1) + channel(4) + x11_req_len(4) + "x11-req"(7) + + * want_reply(1) + single_cnx(1) + proto_len(4) + cookie_len(4) + + * screen_num(4) */ + channel->reqX11_packet_len = proto_len + cookie_len + 30; + + /* Zero the whole thing out */ + memset(&channel->reqX11_packet_requirev_state, 0, + sizeof(channel->reqX11_packet_requirev_state)); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Requesting x11-req for channel %lu/%lu: single=%d " + "proto=%s cookie=%s screen=%d", + channel->local.id, channel->remote.id, + single_connection, + auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", + auth_cookie ? auth_cookie : "", screen_number); + + s = channel->reqX11_packet = + LIBSSH2_ALLOC(session, channel->reqX11_packet_len); + if(!channel->reqX11_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for pty-request"); + } + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, "x11-req", sizeof("x11-req") - 1); + + *(s++) = 0x01; /* want_reply */ + *(s++) = single_connection ? 0x01 : 0x00; + + _libssh2_store_str(&s, auth_proto ? auth_proto : "MIT-MAGIC-COOKIE-1", + proto_len); + + _libssh2_store_u32(&s, cookie_len); + if(auth_cookie) { + memcpy(s, auth_cookie, cookie_len); + } + else { + int i; + /* note: the extra +1 below is necessary since the sprintf() + loop will always write 3 bytes so the last one will write + the trailing zero at the LIBSSH2_X11_RANDOM_COOKIE_LEN/2 + border */ + unsigned char buffer[(LIBSSH2_X11_RANDOM_COOKIE_LEN / 2) + 1]; + + _libssh2_random(buffer, LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); + for(i = 0; i < (LIBSSH2_X11_RANDOM_COOKIE_LEN / 2); i++) { + snprintf((char *)&s[i*2], 3, "%02X", buffer[i]); + } + } + s += cookie_len; + + _libssh2_store_u32(&s, screen_number); + channel->reqX11_state = libssh2_NB_state_created; + } + + if(channel->reqX11_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->reqX11_packet, + channel->reqX11_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending X11-req packet"); + return rc; + } + if(rc) { + LIBSSH2_FREE(session, channel->reqX11_packet); + channel->reqX11_packet = NULL; + channel->reqX11_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send x11-req packet"); + } + LIBSSH2_FREE(session, channel->reqX11_packet); + channel->reqX11_packet = NULL; + + _libssh2_htonu32(channel->reqX11_local_channel, channel->local.id); + + channel->reqX11_state = libssh2_NB_state_sent; + } + + if(channel->reqX11_state == libssh2_NB_state_sent) { + size_t data_len; + unsigned char *data; + unsigned char code; + + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->reqX11_local_channel, 4, + &channel->reqX11_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc || data_len < 1) { + channel->reqX11_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "waiting for x11-req response packet"); + } + + code = data[0]; + LIBSSH2_FREE(session, data); + channel->reqX11_state = libssh2_NB_state_idle; + + if(code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for channel x11-req"); +} + +/* + * libssh2_channel_x11_req_ex + * Request X11 forwarding + */ +LIBSSH2_API int +libssh2_channel_x11_req_ex(LIBSSH2_CHANNEL *channel, int single_connection, + const char *auth_proto, const char *auth_cookie, + int screen_number) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + channel_x11_req(channel, single_connection, auth_proto, + auth_cookie, screen_number)); + return rc; +} + + +/* + * _libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +int +_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *request, size_t request_len, + const char *message, size_t message_len) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char *s; + static const unsigned char reply_codes[3] = + { SSH_MSG_CHANNEL_SUCCESS, SSH_MSG_CHANNEL_FAILURE, 0 }; + int rc; + + if(channel->process_state == libssh2_NB_state_end) { + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "Channel can not be reused"); + } + + if(channel->process_state == libssh2_NB_state_idle) { + /* 10 = packet_type(1) + channel(4) + request_len(4) + want_reply(1) */ + channel->process_packet_len = request_len + 10; + + /* Zero the whole thing out */ + memset(&channel->process_packet_requirev_state, 0, + sizeof(channel->process_packet_requirev_state)); + + if(message) + channel->process_packet_len += + 4; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "starting request(%s) on channel %lu/%lu, message=%s", + request, channel->local.id, channel->remote.id, + message ? message : ""); + s = channel->process_packet = + LIBSSH2_ALLOC(session, channel->process_packet_len); + if(!channel->process_packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for channel-process request"); + + *(s++) = SSH_MSG_CHANNEL_REQUEST; + _libssh2_store_u32(&s, channel->remote.id); + _libssh2_store_str(&s, request, request_len); + *(s++) = 0x01; + + if(message) + _libssh2_store_u32(&s, message_len); + + channel->process_state = libssh2_NB_state_created; + } + + if(channel->process_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, + channel->process_packet, + channel->process_packet_len, + (unsigned char *)message, message_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending channel request"); + return rc; + } + else if(rc) { + LIBSSH2_FREE(session, channel->process_packet); + channel->process_packet = NULL; + channel->process_state = libssh2_NB_state_end; + return _libssh2_error(session, rc, + "Unable to send channel request"); + } + LIBSSH2_FREE(session, channel->process_packet); + channel->process_packet = NULL; + + _libssh2_htonu32(channel->process_local_channel, channel->local.id); + + channel->process_state = libssh2_NB_state_sent; + } + + if(channel->process_state == libssh2_NB_state_sent) { + unsigned char *data; + size_t data_len; + unsigned char code; + rc = _libssh2_packet_requirev(session, reply_codes, &data, &data_len, + 1, channel->process_local_channel, 4, + &channel->process_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc || data_len < 1) { + channel->process_state = libssh2_NB_state_end; + return _libssh2_error(session, rc, + "Failed waiting for channel success"); + } + + code = data[0]; + LIBSSH2_FREE(session, data); + channel->process_state = libssh2_NB_state_end; + + if(code == SSH_MSG_CHANNEL_SUCCESS) + return 0; + } + + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED, + "Unable to complete request for " + "channel-process-startup"); +} + +/* + * libssh2_channel_process_startup + * + * Primitive for libssh2_channel_(shell|exec|subsystem) + */ +LIBSSH2_API int +libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel, + const char *req, unsigned int req_len, + const char *msg, unsigned int msg_len) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_process_startup(channel, req, req_len, + msg, msg_len)); + return rc; +} + + +/* + * libssh2_channel_set_blocking + * + * Set a channel's BEHAVIOR blocking on or off. The socket will remain non- + * blocking. + */ +LIBSSH2_API void +libssh2_channel_set_blocking(LIBSSH2_CHANNEL * channel, int blocking) +{ + if(channel) + (void) _libssh2_session_set_blocking(channel->session, blocking); +} + +/* + * _libssh2_channel_flush + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +int +_libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid) +{ + if(channel->flush_state == libssh2_NB_state_idle) { + LIBSSH2_PACKET *packet = + _libssh2_list_first(&channel->session->packets); + channel->flush_refund_bytes = 0; + channel->flush_flush_bytes = 0; + + while(packet) { + unsigned char packet_type; + LIBSSH2_PACKET *next = _libssh2_list_next(&packet->node); + + if(packet->data_len < 1) { + packet = next; + _libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR, + "Unexpected packet length"); + continue; + } + + packet_type = packet->data[0]; + + if(((packet_type == SSH_MSG_CHANNEL_DATA) + || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && ((packet->data_len >= 5) + && (_libssh2_ntohu32(packet->data + 1) + == channel->local.id))) { + /* It's our channel at least */ + int packet_stream_id; + + if(packet_type == SSH_MSG_CHANNEL_DATA) { + packet_stream_id = 0; + } + else if(packet->data_len >= 9) { + packet_stream_id = _libssh2_ntohu32(packet->data + 5); + } + else { + channel->flush_state = libssh2_NB_state_idle; + return _libssh2_error(channel->session, + LIBSSH2_ERROR_PROTO, + "Unexpected packet length"); + } + + if((streamid == LIBSSH2_CHANNEL_FLUSH_ALL) + || ((packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA) + && ((streamid == LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA) + || (streamid == packet_stream_id))) + || ((packet_type == SSH_MSG_CHANNEL_DATA) + && (streamid == 0))) { + size_t bytes_to_flush = packet->data_len - + packet->data_head; + + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Flushing %d bytes of data from stream " + "%lu on channel %lu/%lu", + bytes_to_flush, packet_stream_id, + channel->local.id, channel->remote.id); + + /* It's one of the streams we wanted to flush */ + channel->flush_refund_bytes += packet->data_len - 13; + channel->flush_flush_bytes += bytes_to_flush; + + LIBSSH2_FREE(channel->session, packet->data); + + /* remove this packet from the parent's list */ + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(channel->session, packet); + } + } + packet = next; + } + + channel->flush_state = libssh2_NB_state_created; + } + + channel->read_avail -= channel->flush_flush_bytes; + channel->remote.window_size -= channel->flush_flush_bytes; + + if(channel->flush_refund_bytes) { + int rc = + _libssh2_channel_receive_window_adjust(channel, + channel->flush_refund_bytes, + 1, NULL); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + channel->flush_state = libssh2_NB_state_idle; + + return channel->flush_flush_bytes; +} + +/* + * libssh2_channel_flush_ex + * + * Flush data from one (or all) stream + * Returns number of bytes flushed, or negative on failure + */ +LIBSSH2_API int +libssh2_channel_flush_ex(LIBSSH2_CHANNEL *channel, int stream) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_flush(channel, stream)); + return rc; +} + +/* + * libssh2_channel_get_exit_status + * + * Return the channel's program exit status. Note that the actual protocol + * provides the full 32bit this function returns. We cannot abuse it to + * return error values in case of errors so we return a zero if channel is + * NULL. + */ +LIBSSH2_API int +libssh2_channel_get_exit_status(LIBSSH2_CHANNEL *channel) +{ + if(!channel) + return 0; + + return channel->exit_status; +} + +/* + * libssh2_channel_get_exit_signal + * + * Get exit signal (without leading "SIG"), error message, and language + * tag into newly allocated buffers of indicated length. Caller can + * use NULL pointers to indicate that the value should not be set. The + * *_len variables are set if they are non-NULL even if the + * corresponding string parameter is NULL. Returns LIBSSH2_ERROR_NONE + * on success, or an API error code. + */ +LIBSSH2_API int +libssh2_channel_get_exit_signal(LIBSSH2_CHANNEL *channel, + char **exitsignal, + size_t *exitsignal_len, + char **errmsg, + size_t *errmsg_len, + char **langtag, + size_t *langtag_len) +{ + size_t namelen = 0; + + if(channel) { + LIBSSH2_SESSION *session = channel->session; + + if(channel->exit_signal) { + namelen = strlen(channel->exit_signal); + if(exitsignal) { + *exitsignal = LIBSSH2_ALLOC(session, namelen + 1); + if(!*exitsignal) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for signal name"); + } + memcpy(*exitsignal, channel->exit_signal, namelen); + (*exitsignal)[namelen] = '\0'; + } + if(exitsignal_len) + *exitsignal_len = namelen; + } + else { + if(exitsignal) + *exitsignal = NULL; + if(exitsignal_len) + *exitsignal_len = 0; + } + + /* TODO: set error message and language tag */ + + if(errmsg) + *errmsg = NULL; + + if(errmsg_len) + *errmsg_len = 0; + + if(langtag) + *langtag = NULL; + + if(langtag_len) + *langtag_len = 0; + } + + return LIBSSH2_ERROR_NONE; +} + +/* + * _libssh2_channel_receive_window_adjust + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Calls _libssh2_error() ! + */ +int +_libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel, + uint32_t adjustment, + unsigned char force, + unsigned int *store) +{ + int rc; + + if(store) + *store = channel->remote.window_size; + + if(channel->adjust_state == libssh2_NB_state_idle) { + if(!force + && (adjustment + channel->adjust_queue < + LIBSSH2_CHANNEL_MINADJUST)) { + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Queueing %lu bytes for receive window adjustment " + "for channel %lu/%lu", + adjustment, channel->local.id, channel->remote.id); + channel->adjust_queue += adjustment; + return 0; + } + + if(!adjustment && !channel->adjust_queue) { + return 0; + } + + adjustment += channel->adjust_queue; + channel->adjust_queue = 0; + + /* Adjust the window based on the block we just freed */ + channel->adjust_adjust[0] = SSH_MSG_CHANNEL_WINDOW_ADJUST; + _libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id); + _libssh2_htonu32(&channel->adjust_adjust[5], adjustment); + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Adjusting window %lu bytes for data on " + "channel %lu/%lu", + adjustment, channel->local.id, channel->remote.id); + + channel->adjust_state = libssh2_NB_state_created; + } + + rc = _libssh2_transport_send(channel->session, channel->adjust_adjust, 9, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(channel->session, rc, + "Would block sending window adjust"); + return rc; + } + else if(rc) { + channel->adjust_queue = adjustment; + return _libssh2_error(channel->session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send transfer-window adjustment " + "packet, deferring"); + } + else { + channel->remote.window_size += adjustment; + } + + channel->adjust_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_receive_window_adjust + * + * DEPRECATED + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Returns the new size of the receive window (as understood by remote end). + * Note that it might return EAGAIN too which is highly stupid. + * + */ +LIBSSH2_API unsigned long +libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel, + unsigned long adj, + unsigned char force) +{ + unsigned int window; + int rc; + + if(!channel) + return (unsigned long)LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, adj, + force, &window)); + + /* stupid - but this is how it was made to work before and this is just + kept for backwards compatibility */ + return rc ? (unsigned long)rc : window; +} + +/* + * libssh2_channel_receive_window_adjust2 + * + * Adjust the receive window for a channel by adjustment bytes. If the amount + * to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the + * adjustment amount will be queued for a later packet. + * + * Stores the new size of the receive window in the data 'window' points to. + * + * Returns the "normal" error code: 0 for success, negative for failure. + */ +LIBSSH2_API int +libssh2_channel_receive_window_adjust2(LIBSSH2_CHANNEL *channel, + unsigned long adj, + unsigned char force, + unsigned int *window) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, adj, force, + window)); + return rc; +} + +int +_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode) +{ + if(channel->extData2_state == libssh2_NB_state_idle) { + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Setting channel %lu/%lu handle_extended_data" + " mode to %d", + channel->local.id, channel->remote.id, ignore_mode); + channel->remote.extended_data_ignore_mode = (char)ignore_mode; + + channel->extData2_state = libssh2_NB_state_created; + } + + if(channel->extData2_state == libssh2_NB_state_idle) { + if(ignore_mode == LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) { + int rc = + _libssh2_channel_flush(channel, + LIBSSH2_CHANNEL_FLUSH_EXTENDED_DATA); + if(LIBSSH2_ERROR_EAGAIN == rc) + return rc; + } + } + + channel->extData2_state = libssh2_NB_state_idle; + return 0; +} + +/* + * libssh2_channel_handle_extended_data2() + * + */ +LIBSSH2_API int +libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel, + int mode) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_extended_data(channel, + mode)); + return rc; +} + +/* + * libssh2_channel_handle_extended_data + * + * DEPRECATED DO NOTE USE! + * + * How should extended data look to the calling app? Keep it in separate + * channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the + * standard data? [everything via _read()]? (MERGE) Ignore it entirely [toss + * out packets as they come in]? (IGNORE) + */ +LIBSSH2_API void +libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel, + int ignore_mode) +{ + (void)libssh2_channel_handle_extended_data2(channel, ignore_mode); +} + + + +/* + * _libssh2_channel_read + * + * Read data from a channel + * + * It is important to not return 0 until the currently read channel is + * complete. If we read stuff from the wire but it was no payload data to fill + * in the buffer with, we MUST make sure to return LIBSSH2_ERROR_EAGAIN. + * + * The receive window must be maintained (enlarged) by the user of this + * function. + */ +ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id, + char *buf, size_t buflen) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + size_t bytes_read = 0; + size_t bytes_want; + int unlink_packet; + LIBSSH2_PACKET *read_packet; + LIBSSH2_PACKET *read_next; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "channel_read() wants %d bytes from channel %lu/%lu " + "stream #%d", + (int) buflen, channel->local.id, channel->remote.id, + stream_id); + + /* expand the receiving window first if it has become too narrow */ + if((channel->read_state == libssh2_NB_state_jump1) || + (channel->remote.window_size < + channel->remote.window_size_initial / 4 * 3 + buflen) ) { + + uint32_t adjustment = channel->remote.window_size_initial + buflen - + channel->remote.window_size; + if(adjustment < LIBSSH2_CHANNEL_MINADJUST) + adjustment = LIBSSH2_CHANNEL_MINADJUST; + + /* the actual window adjusting may not finish so we need to deal with + this special state here */ + channel->read_state = libssh2_NB_state_jump1; + rc = _libssh2_channel_receive_window_adjust(channel, adjustment, + 0, NULL); + if(rc) + return rc; + + channel->read_state = libssh2_NB_state_idle; + } + + /* Process all pending incoming packets. Tests prove that this way + produces faster transfers. */ + do { + rc = _libssh2_transport_read(session); + } while(rc > 0); + + if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) + return _libssh2_error(session, rc, "transport read"); + + read_packet = _libssh2_list_first(&session->packets); + while(read_packet && (bytes_read < buflen)) { + /* previously this loop condition also checked for + !channel->remote.close but we cannot let it do this: + + We may have a series of packets to read that are still pending even + if a close has been received. Acknowledging the close too early + makes us flush buffers prematurely and loose data. + */ + + LIBSSH2_PACKET *readpkt = read_packet; + + /* In case packet gets destroyed during this iteration */ + read_next = _libssh2_list_next(&readpkt->node); + + if(readpkt->data_len < 5) { + read_packet = read_next; + _libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR, + "Unexpected packet length"); + continue; + } + + channel->read_local_id = + _libssh2_ntohu32(readpkt->data + 1); + + /* + * Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if((stream_id + && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (readpkt->data_len >= 9) + && (stream_id == (int) _libssh2_ntohu32(readpkt->data + 5))) + || (!stream_id && (readpkt->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == channel->read_local_id)) + || (!stream_id + && (readpkt->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == channel->read_local_id) + && (channel->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { + + /* figure out much more data we want to read */ + bytes_want = buflen - bytes_read; + unlink_packet = FALSE; + + if(bytes_want >= (readpkt->data_len - readpkt->data_head)) { + /* we want more than this node keeps, so adjust the number and + delete this node after the copy */ + bytes_want = readpkt->data_len - readpkt->data_head; + unlink_packet = TRUE; + } + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "channel_read() got %d of data from %lu/%lu/%d%s", + bytes_want, channel->local.id, + channel->remote.id, stream_id, + unlink_packet?" [ul]":""); + + /* copy data from this struct to the target buffer */ + memcpy(&buf[bytes_read], + &readpkt->data[readpkt->data_head], bytes_want); + + /* advance pointer and counter */ + readpkt->data_head += bytes_want; + bytes_read += bytes_want; + + /* if drained, remove from list */ + if(unlink_packet) { + /* detach readpkt from session->packets list */ + _libssh2_list_remove(&readpkt->node); + + LIBSSH2_FREE(session, readpkt->data); + LIBSSH2_FREE(session, readpkt); + } + } + + /* check the next struct in the chain */ + read_packet = read_next; + } + + if(!bytes_read) { + /* If the channel is already at EOF or even closed, we need to signal + that back. We may have gotten that info while draining the incoming + transport layer until EAGAIN so we must not be fooled by that + return code. */ + if(channel->remote.eof || channel->remote.close) + return 0; + else if(rc != LIBSSH2_ERROR_EAGAIN) + return 0; + + /* if the transport layer said EAGAIN then we say so as well */ + return _libssh2_error(session, rc, "would block"); + } + + channel->read_avail -= bytes_read; + channel->remote.window_size -= bytes_read; + + return bytes_read; +} + +/* + * libssh2_channel_read_ex + * + * Read data from a channel (blocking or non-blocking depending on set state) + * + * When this is done non-blocking, it is important to not return 0 until the + * currently read channel is complete. If we read stuff from the wire but it + * was no payload data to fill in the buffer with, we MUST make sure to return + * LIBSSH2_ERROR_EAGAIN. + * + * This function will first make sure there's a receive window enough to + * receive a full buffer's wort of contents. An application may choose to + * adjust the receive window more to increase transfer performance. + */ +LIBSSH2_API ssize_t +libssh2_channel_read_ex(LIBSSH2_CHANNEL *channel, int stream_id, char *buf, + size_t buflen) +{ + int rc; + unsigned long recv_window; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); + + if(buflen > recv_window) { + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_receive_window_adjust(channel, buflen, + 1, NULL)); + } + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_read(channel, stream_id, buf, buflen)); + return rc; +} + +/* + * _libssh2_channel_packet_data_len + * + * Return the size of the data block of the current packet, or 0 if there + * isn't a packet. + */ +size_t +_libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel, int stream_id) +{ + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_PACKET *read_packet; + LIBSSH2_PACKET *next_packet; + uint32_t read_local_id; + + read_packet = _libssh2_list_first(&session->packets); + if(read_packet == NULL) + return 0; + + while(read_packet) { + + next_packet = _libssh2_list_next(&read_packet->node); + + if(read_packet->data_len < 5) { + read_packet = next_packet; + _libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR, + "Unexpected packet length"); + continue; + } + + read_local_id = _libssh2_ntohu32(read_packet->data + 1); + + /* + * Either we asked for a specific extended data stream + * (and data was available), + * or the standard stream (and data was available), + * or the standard stream with extended_data_merge + * enabled and data was available + */ + if((stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (read_packet->data_len >= 9) + && (stream_id == (int) _libssh2_ntohu32(read_packet->data + 5))) + || + (!stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_DATA) + && (channel->local.id == read_local_id)) + || + (!stream_id + && (read_packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA) + && (channel->local.id == read_local_id) + && (channel->remote.extended_data_ignore_mode + == LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE))) { + return (read_packet->data_len - read_packet->data_head); + } + + read_packet = next_packet; + } + + return 0; +} + +/* + * _libssh2_channel_write + * + * Send data to a channel. Note that if this returns EAGAIN, the caller must + * call this function again with the SAME input arguments. + * + * Returns: number of bytes sent, or if it returns a negative number, that is + * the error code! + */ +ssize_t +_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id, + const unsigned char *buf, size_t buflen) +{ + int rc = 0; + LIBSSH2_SESSION *session = channel->session; + ssize_t wrote = 0; /* counter for this specific this call */ + + /* In theory we could split larger buffers into several smaller packets + * but it turns out to be really hard and nasty to do while still offering + * the API/prototype. + * + * Instead we only deal with the first 32K in this call and for the parent + * function to call it again with the remainder! 32K is a conservative + * limit based on the text in RFC4253 section 6.1. + */ + if(buflen > 32700) + buflen = 32700; + + if(channel->write_state == libssh2_NB_state_idle) { + unsigned char *s = channel->write_packet; + + _libssh2_debug(channel->session, LIBSSH2_TRACE_CONN, + "Writing %d bytes on channel %lu/%lu, stream #%d", + (int) buflen, channel->local.id, channel->remote.id, + stream_id); + + if(channel->local.close) + return _libssh2_error(channel->session, + LIBSSH2_ERROR_CHANNEL_CLOSED, + "We've already closed this channel"); + else if(channel->local.eof) + return _libssh2_error(channel->session, + LIBSSH2_ERROR_CHANNEL_EOF_SENT, + "EOF has already been received, " + "data might be ignored"); + + /* drain the incoming flow first, mostly to make sure we get all + * pending window adjust packets */ + do + rc = _libssh2_transport_read(session); + while(rc > 0); + + if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { + return _libssh2_error(channel->session, rc, + "Failure while draining incoming flow"); + } + + if(channel->local.window_size <= 0) { + /* there's no room for data so we stop */ + + /* Waiting on the socket to be writable would be wrong because we + * would be back here immediately, but a readable socket might + * herald an incoming window adjustment. + */ + session->socket_block_directions = LIBSSH2_SESSION_BLOCK_INBOUND; + + return (rc == LIBSSH2_ERROR_EAGAIN?rc:0); + } + + channel->write_bufwrite = buflen; + + *(s++) = stream_id ? SSH_MSG_CHANNEL_EXTENDED_DATA : + SSH_MSG_CHANNEL_DATA; + _libssh2_store_u32(&s, channel->remote.id); + if(stream_id) + _libssh2_store_u32(&s, stream_id); + + /* Don't exceed the remote end's limits */ + /* REMEMBER local means local as the SOURCE of the data */ + if(channel->write_bufwrite > channel->local.window_size) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Splitting write block due to %lu byte " + "window_size on %lu/%lu/%d", + channel->local.window_size, channel->local.id, + channel->remote.id, stream_id); + channel->write_bufwrite = channel->local.window_size; + } + if(channel->write_bufwrite > channel->local.packet_size) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Splitting write block due to %lu byte " + "packet_size on %lu/%lu/%d", + channel->local.packet_size, channel->local.id, + channel->remote.id, stream_id); + channel->write_bufwrite = channel->local.packet_size; + } + /* store the size here only, the buffer is passed in as-is to + _libssh2_transport_send() */ + _libssh2_store_u32(&s, channel->write_bufwrite); + channel->write_packet_len = s - channel->write_packet; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Sending %d bytes on channel %lu/%lu, stream_id=%d", + (int) channel->write_bufwrite, channel->local.id, + channel->remote.id, stream_id); + + channel->write_state = libssh2_NB_state_created; + } + + if(channel->write_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->write_packet, + channel->write_packet_len, + buf, channel->write_bufwrite); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, rc, + "Unable to send channel data"); + } + else if(rc) { + channel->write_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send channel data"); + } + /* Shrink local window size */ + channel->local.window_size -= channel->write_bufwrite; + + wrote += channel->write_bufwrite; + + /* Since _libssh2_transport_write() succeeded, we must return + now to allow the caller to provide the next chunk of data. + + We cannot move on to send the next piece of data that may + already have been provided in this same function call, as we + risk getting EAGAIN for that and we can't return information + both about sent data as well as EAGAIN. So, by returning short + now, the caller will call this function again with new data to + send */ + + channel->write_state = libssh2_NB_state_idle; + + return wrote; + } + + return LIBSSH2_ERROR_INVAL; /* reaching this point is really bad */ +} + +/* + * libssh2_channel_write_ex + * + * Send data to a channel + */ +LIBSSH2_API ssize_t +libssh2_channel_write_ex(LIBSSH2_CHANNEL *channel, int stream_id, + const char *buf, size_t buflen) +{ + ssize_t rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, + _libssh2_channel_write(channel, stream_id, + (unsigned char *)buf, buflen)); + return rc; +} + +/* + * channel_send_eof + * + * Send EOF on channel + */ +static int channel_send_eof(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char packet[5]; /* packet_type(1) + channelno(4) */ + int rc; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Sending EOF on channel %lu/%lu", + channel->local.id, channel->remote.id); + packet[0] = SSH_MSG_CHANNEL_EOF; + _libssh2_htonu32(packet + 1, channel->remote.id); + rc = _libssh2_transport_send(session, packet, 5, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending EOF"); + return rc; + } + else if(rc) { + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send EOF on channel"); + } + channel->local.eof = 1; + + return 0; +} + +/* + * libssh2_channel_send_eof + * + * Send EOF on channel + */ +LIBSSH2_API int +libssh2_channel_send_eof(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_send_eof(channel)); + return rc; +} + +/* + * libssh2_channel_eof + * + * Read channel's eof status + */ +LIBSSH2_API int +libssh2_channel_eof(LIBSSH2_CHANNEL * channel) +{ + LIBSSH2_SESSION *session; + LIBSSH2_PACKET *packet; + LIBSSH2_PACKET *next_packet; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + session = channel->session; + packet = _libssh2_list_first(&session->packets); + + while(packet) { + + next_packet = _libssh2_list_next(&packet->node); + + if(packet->data_len < 1) { + packet = next_packet; + _libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR, + "Unexpected packet length"); + continue; + } + + if(((packet->data[0] == SSH_MSG_CHANNEL_DATA) + || (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && ((packet->data_len >= 5) + && (channel->local.id == _libssh2_ntohu32(packet->data + 1)))) { + /* There's data waiting to be read yet, mask the EOF status */ + return 0; + } + packet = next_packet; + } + + return channel->remote.eof; +} + +/* + * channel_wait_eof + * + * Awaiting channel EOF + */ +static int channel_wait_eof(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + + if(channel->wait_eof_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Awaiting EOF for channel %lu/%lu", channel->local.id, + channel->remote.id); + + channel->wait_eof_state = libssh2_NB_state_created; + } + + /* + * While channel is not eof, read more packets from the network. + * Either the EOF will be set or network timeout will occur. + */ + do { + if(channel->remote.eof) { + break; + } + + if((channel->remote.window_size == channel->read_avail) && + session->api_block_mode) + return _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_WINDOW_FULL, + "Receiving channel window " + "has been exhausted"); + + rc = _libssh2_transport_read(session); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc < 0) { + channel->wait_eof_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "_libssh2_transport_read() bailed out!"); + } + } while(1); + + channel->wait_eof_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_wait_eof + * + * Awaiting channel EOF + */ +LIBSSH2_API int +libssh2_channel_wait_eof(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_wait_eof(channel)); + return rc; +} + +int _libssh2_channel_close(LIBSSH2_CHANNEL * channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc = 0; + + if(channel->local.close) { + /* Already closed, act like we sent another close, + * even though we didn't... shhhhhh */ + channel->close_state = libssh2_NB_state_idle; + return 0; + } + + if(!channel->local.eof) { + rc = channel_send_eof(channel); + if(rc) { + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + _libssh2_error(session, rc, + "Unable to send EOF, but closing channel anyway"); + } + } + + /* ignore if we have received a remote eof or not, as it is now too + late for us to wait for it. Continue closing! */ + + if(channel->close_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu", + channel->local.id, channel->remote.id); + + channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE; + _libssh2_htonu32(channel->close_packet + 1, channel->remote.id); + + channel->close_state = libssh2_NB_state_created; + } + + if(channel->close_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, channel->close_packet, 5, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, rc, + "Would block sending close-channel"); + return rc; + + } + else if(rc) { + _libssh2_error(session, rc, + "Unable to send close-channel request, " + "but closing anyway"); + /* skip waiting for the response and fall through to + LIBSSH2_CHANNEL_CLOSE below */ + + } + else + channel->close_state = libssh2_NB_state_sent; + } + + if(channel->close_state == libssh2_NB_state_sent) { + /* We must wait for the remote SSH_MSG_CHANNEL_CLOSE message */ + + while(!channel->remote.close && !rc && + (session->socket_state != LIBSSH2_SOCKET_DISCONNECTED)) + rc = _libssh2_transport_read(session); + } + + if(rc != LIBSSH2_ERROR_EAGAIN) { + /* set the local close state first when we're perfectly confirmed to + not do any more EAGAINs */ + channel->local.close = 1; + + /* We call the callback last in this function to make it keep the local + data as long as EAGAIN is returned. */ + if(channel->close_cb) { + LIBSSH2_CHANNEL_CLOSE(session, channel); + } + + channel->close_state = libssh2_NB_state_idle; + } + + /* return 0 or an error */ + return rc >= 0 ? 0 : rc; +} + +/* + * libssh2_channel_close + * + * Close a channel + */ +LIBSSH2_API int +libssh2_channel_close(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_close(channel) ); + return rc; +} + +/* + * channel_wait_closed + * + * Awaiting channel close after EOF + */ +static int channel_wait_closed(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + int rc; + + if(!channel->remote.eof) { + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "libssh2_channel_wait_closed() invoked when " + "channel is not in EOF state"); + } + + if(channel->wait_closed_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Awaiting close of channel %lu/%lu", channel->local.id, + channel->remote.id); + + channel->wait_closed_state = libssh2_NB_state_created; + } + + /* + * While channel is not closed, read more packets from the network. + * Either the channel will be closed or network timeout will occur. + */ + if(!channel->remote.close) { + do { + rc = _libssh2_transport_read(session); + if(channel->remote.close) + /* it is now closed, move on! */ + break; + } while(rc > 0); + if(rc < 0) + return rc; + } + + channel->wait_closed_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_channel_wait_closed + * + * Awaiting channel close after EOF + */ +LIBSSH2_API int +libssh2_channel_wait_closed(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, channel_wait_closed(channel)); + return rc; +} + +/* + * _libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +int _libssh2_channel_free(LIBSSH2_CHANNEL *channel) +{ + LIBSSH2_SESSION *session = channel->session; + unsigned char channel_id[4]; + unsigned char *data; + size_t data_len; + int rc; + + assert(session); + + if(channel->free_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Freeing channel %lu/%lu resources", channel->local.id, + channel->remote.id); + + channel->free_state = libssh2_NB_state_created; + } + + /* Allow channel freeing even when the socket has lost its connection */ + if(!channel->local.close + && (session->socket_state == LIBSSH2_SOCKET_CONNECTED)) { + rc = _libssh2_channel_close(channel); + + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + /* ignore all other errors as they otherwise risk blocking the channel + free from happening */ + } + + channel->free_state = libssh2_NB_state_idle; + + if(channel->exit_signal) { + LIBSSH2_FREE(session, channel->exit_signal); + } + + /* + * channel->remote.close *might* not be set yet, Well... + * We've sent the close packet, what more do you want? + * Just let packet_add ignore it when it finally arrives + */ + + /* Clear out packets meant for this channel */ + _libssh2_htonu32(channel_id, channel->local.id); + while((_libssh2_packet_ask(session, SSH_MSG_CHANNEL_DATA, &data, + &data_len, 1, channel_id, 4) >= 0) + || + (_libssh2_packet_ask(session, SSH_MSG_CHANNEL_EXTENDED_DATA, &data, + &data_len, 1, channel_id, 4) >= 0)) { + LIBSSH2_FREE(session, data); + } + + /* free "channel_type" */ + if(channel->channel_type) { + LIBSSH2_FREE(session, channel->channel_type); + } + + /* Unlink from channel list */ + _libssh2_list_remove(&channel->node); + + /* + * Make sure all memory used in the state variables are free + */ + if(channel->setenv_packet) { + LIBSSH2_FREE(session, channel->setenv_packet); + } + if(channel->reqX11_packet) { + LIBSSH2_FREE(session, channel->reqX11_packet); + } + if(channel->process_packet) { + LIBSSH2_FREE(session, channel->process_packet); + } + + LIBSSH2_FREE(session, channel); + + return 0; +} + +/* + * libssh2_channel_free + * + * Make sure a channel is closed, then remove the channel from the session + * and free its resource(s) + * + * Returns 0 on success, negative on failure + */ +LIBSSH2_API int +libssh2_channel_free(LIBSSH2_CHANNEL *channel) +{ + int rc; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, channel->session, _libssh2_channel_free(channel)); + return rc; +} +/* + * libssh2_channel_window_read_ex + * + * Check the status of the read window. Returns the number of bytes which the + * remote end may send without overflowing the window limit read_avail (if + * passed) will be populated with the number of bytes actually available to be + * read window_size_initial (if passed) will be populated with the + * window_size_initial as defined by the channel_open request + */ +LIBSSH2_API unsigned long +libssh2_channel_window_read_ex(LIBSSH2_CHANNEL *channel, + unsigned long *read_avail, + unsigned long *window_size_initial) +{ + if(!channel) + return 0; /* no channel, no window! */ + + if(window_size_initial) { + *window_size_initial = channel->remote.window_size_initial; + } + + if(read_avail) { + size_t bytes_queued = 0; + LIBSSH2_PACKET *next_packet; + LIBSSH2_PACKET *packet = + _libssh2_list_first(&channel->session->packets); + + while(packet) { + unsigned char packet_type; + next_packet = _libssh2_list_next(&packet->node); + + if(packet->data_len < 1) { + packet = next_packet; + _libssh2_debug(channel->session, LIBSSH2_TRACE_ERROR, + "Unexpected packet length"); + continue; + } + + packet_type = packet->data[0]; + + if(((packet_type == SSH_MSG_CHANNEL_DATA) + || (packet_type == SSH_MSG_CHANNEL_EXTENDED_DATA)) + && ((packet->data_len >= 5) + && (_libssh2_ntohu32(packet->data + 1) == + channel->local.id))) { + bytes_queued += packet->data_len - packet->data_head; + } + + packet = next_packet; + } + + *read_avail = bytes_queued; + } + + return channel->remote.window_size; +} + +/* + * libssh2_channel_window_write_ex + * + * Check the status of the write window Returns the number of bytes which may + * be safely written on the channel without blocking window_size_initial (if + * passed) will be populated with the size of the initial window as defined by + * the channel_open request + */ +LIBSSH2_API unsigned long +libssh2_channel_window_write_ex(LIBSSH2_CHANNEL *channel, + unsigned long *window_size_initial) +{ + if(!channel) + return 0; /* no channel, no window! */ + + if(window_size_initial) { + /* For locally initiated channels this is very often 0, so it's not + * *that* useful as information goes */ + *window_size_initial = channel->local.window_size_initial; + } + + return channel->local.window_size; +} diff --git a/libssh2/comp.c b/libssh2/comp.c new file mode 100644 index 0000000..fec82a7 --- /dev/null +++ b/libssh2/comp.c @@ -0,0 +1,376 @@ +/* Copyright (c) 2004-2007, 2019, Sara Golemon + * Copyright (c) 2010-2014, Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#ifdef LIBSSH2_HAVE_ZLIB +# include +#endif + +#include "comp.h" + +/* ******** + * none * + ******** */ + +/* + * comp_method_none_comp + * + * Minimalist compression: Absolutely none + */ +static int +comp_method_none_comp(LIBSSH2_SESSION *session, + unsigned char *dest, + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract) +{ + (void) session; + (void) abstract; + (void) dest; + (void) dest_len; + (void) src; + (void) src_len; + + return 0; +} + +/* + * comp_method_none_decomp + * + * Minimalist decompression: Absolutely none + */ +static int +comp_method_none_decomp(LIBSSH2_SESSION * session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, void **abstract) +{ + (void) session; + (void) payload_limit; + (void) abstract; + *dest = (unsigned char *) src; + *dest_len = src_len; + return 0; +} + + + +static const LIBSSH2_COMP_METHOD comp_method_none = { + "none", + 0, /* not really compressing */ + 0, /* isn't used in userauth, go figure */ + NULL, + comp_method_none_comp, + comp_method_none_decomp, + NULL +}; + +#ifdef LIBSSH2_HAVE_ZLIB +/* ******** + * zlib * + ******** */ + +/* Memory management wrappers + * Yes, I realize we're doing a callback to a callback, + * Deal... + */ + +static voidpf +comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size) +{ + LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; + + return (voidpf) LIBSSH2_ALLOC(session, items * size); +} + +static void +comp_method_zlib_free(voidpf opaque, voidpf address) +{ + LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque; + + LIBSSH2_FREE(session, address); +} + + + +/* libssh2_comp_method_zlib_init + * All your bandwidth are belong to us (so save some) + */ +static int +comp_method_zlib_init(LIBSSH2_SESSION * session, int compr, + void **abstract) +{ + z_stream *strm; + int status; + + strm = LIBSSH2_CALLOC(session, sizeof(z_stream)); + if(!strm) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "zlib compression/decompression"); + } + + strm->opaque = (voidpf) session; + strm->zalloc = (alloc_func) comp_method_zlib_alloc; + strm->zfree = (free_func) comp_method_zlib_free; + if(compr) { + /* deflate */ + status = deflateInit(strm, Z_DEFAULT_COMPRESSION); + } + else { + /* inflate */ + status = inflateInit(strm); + } + + if(status != Z_OK) { + LIBSSH2_FREE(session, strm); + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib error %d", status); + return LIBSSH2_ERROR_COMPRESS; + } + *abstract = strm; + + return LIBSSH2_ERROR_NONE; +} + +/* + * libssh2_comp_method_zlib_comp + * + * Compresses source to destination. Without allocation. + */ +static int +comp_method_zlib_comp(LIBSSH2_SESSION *session, + unsigned char *dest, + + /* dest_len is a pointer to allow this function to + update it with the final actual size used */ + size_t *dest_len, + const unsigned char *src, + size_t src_len, + void **abstract) +{ + z_stream *strm = *abstract; + int out_maxlen = *dest_len; + int status; + + strm->next_in = (unsigned char *) src; + strm->avail_in = src_len; + strm->next_out = dest; + strm->avail_out = out_maxlen; + + status = deflate(strm, Z_PARTIAL_FLUSH); + + if((status == Z_OK) && (strm->avail_out > 0)) { + *dest_len = out_maxlen - strm->avail_out; + return 0; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib compression error %d, avail_out", + status, strm->avail_out); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure"); +} + +/* + * libssh2_comp_method_zlib_decomp + * + * Decompresses source to destination. Allocates the output memory. + */ +static int +comp_method_zlib_decomp(LIBSSH2_SESSION * session, + unsigned char **dest, + size_t *dest_len, + size_t payload_limit, + const unsigned char *src, + size_t src_len, void **abstract) +{ + z_stream *strm = *abstract; + /* A short-term alloc of a full data chunk is better than a series of + reallocs */ + char *out; + size_t out_maxlen = src_len; + + if(src_len <= SIZE_MAX / 4) + out_maxlen = src_len * 4; + else + out_maxlen = payload_limit; + + /* If strm is null, then we have not yet been initialized. */ + if(strm == NULL) + return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS, + "decompression uninitialized");; + + /* In practice they never come smaller than this */ + if(out_maxlen < 25) + out_maxlen = 25; + + if(out_maxlen > payload_limit) + out_maxlen = payload_limit; + + strm->next_in = (unsigned char *) src; + strm->avail_in = src_len; + strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen); + out = (char *) strm->next_out; + strm->avail_out = out_maxlen; + if(!strm->next_out) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate decompression buffer"); + + /* Loop until it's all inflated or hit error */ + for(;;) { + int status; + size_t out_ofs; + char *newout; + + status = inflate(strm, Z_PARTIAL_FLUSH); + + if(status == Z_OK) { + if(strm->avail_out > 0) + /* status is OK and the output buffer has not been exhausted + so we're done */ + break; + } + else if(status == Z_BUF_ERROR) { + /* the input data has been exhausted so we are done */ + break; + } + else { + /* error state */ + LIBSSH2_FREE(session, out); + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unhandled zlib error %d", status); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "decompression failure"); + } + + if(out_maxlen > payload_limit || out_maxlen > SIZE_MAX / 2) { + LIBSSH2_FREE(session, out); + return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, + "Excessive growth in decompression phase"); + } + + /* If we get here we need to grow the output buffer and try again */ + out_ofs = out_maxlen - strm->avail_out; + out_maxlen *= 2; + newout = LIBSSH2_REALLOC(session, out, out_maxlen); + if(!newout) { + LIBSSH2_FREE(session, out); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to expand decompression buffer"); + } + out = newout; + strm->next_out = (unsigned char *) out + out_ofs; + strm->avail_out = out_maxlen - out_ofs; + } + + *dest = (unsigned char *) out; + *dest_len = out_maxlen - strm->avail_out; + + return 0; +} + + +/* libssh2_comp_method_zlib_dtor + * All done, no more compression for you + */ +static int +comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract) +{ + z_stream *strm = *abstract; + + if(strm) { + if(compr) + deflateEnd(strm); + else + inflateEnd(strm); + LIBSSH2_FREE(session, strm); + } + + *abstract = NULL; + return 0; +} + +static const LIBSSH2_COMP_METHOD comp_method_zlib = { + "zlib", + 1, /* yes, this compresses */ + 1, /* do compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; + +static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = { + "zlib@openssh.com", + 1, /* yes, this compresses */ + 0, /* don't use compression during userauth */ + comp_method_zlib_init, + comp_method_zlib_comp, + comp_method_zlib_decomp, + comp_method_zlib_dtor, +}; +#endif /* LIBSSH2_HAVE_ZLIB */ + +/* If compression is enabled by the API, then this array is used which then + may allow compression if zlib is available at build time */ +static const LIBSSH2_COMP_METHOD *comp_methods[] = { +#ifdef LIBSSH2_HAVE_ZLIB + &comp_method_zlib, + &comp_method_zlib_openssh, +#endif /* LIBSSH2_HAVE_ZLIB */ + &comp_method_none, + NULL +}; + +/* If compression is disabled by the API, then this array is used */ +static const LIBSSH2_COMP_METHOD *no_comp_methods[] = { + &comp_method_none, + NULL +}; + +const LIBSSH2_COMP_METHOD ** +_libssh2_comp_methods(LIBSSH2_SESSION *session) +{ + if(session->flag.compress) + return comp_methods; + else + return no_comp_methods; +} diff --git a/libssh2/crypt.c b/libssh2/crypt.c new file mode 100644 index 0000000..8d493b4 --- /dev/null +++ b/libssh2/crypt.c @@ -0,0 +1,349 @@ +/* Copyright (c) 2009, 2010 Simon Josefsson + * Copyright (c) 2004-2007, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_CRYPT_NONE + +/* crypt_none_crypt + * Minimalist cipher: VERY secure *wink* + */ +static int +crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf, + void **abstract) +{ + /* Do nothing to the data! */ + return 0; +} + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = { + "none", + "DEK-Info: NONE", + 8, /* blocksize (SSH2 defines minimum blocksize as 8) */ + 0, /* iv_len */ + 0, /* secret_len */ + 0, /* flags */ + NULL, + crypt_none_crypt, + NULL +}; +#endif /* LIBSSH2_CRYPT_NONE */ + +struct crypt_ctx +{ + int encrypt; + _libssh2_cipher_type(algo); + _libssh2_cipher_ctx h; +}; + +static int +crypt_init(LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) +{ + struct crypt_ctx *ctx = LIBSSH2_ALLOC(session, + sizeof(struct crypt_ctx)); + if(!ctx) + return LIBSSH2_ERROR_ALLOC; + + ctx->encrypt = encrypt; + ctx->algo = method->algo; + if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) { + LIBSSH2_FREE(session, ctx); + return -1; + } + *abstract = ctx; + *free_iv = 1; + *free_secret = 1; + return 0; +} + +static int +crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block, + size_t blocksize, void **abstract) +{ + struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; + (void) session; + return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, + blocksize); +} + +static int +crypt_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + struct crypt_ctx **cctx = (struct crypt_ctx **) abstract; + if(cctx && *cctx) { + _libssh2_cipher_dtor(&(*cctx)->h); + LIBSSH2_FREE(session, *cctx); + *abstract = NULL; + } + return 0; +} + +#if LIBSSH2_AES_CTR +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = { + "aes128-ctr", + "", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes128ctr +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = { + "aes192-ctr", + "", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes192ctr +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = { + "aes256-ctr", + "", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256ctr +}; +#endif + +#if LIBSSH2_AES +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = { + "aes128-cbc", + "DEK-Info: AES-128-CBC", + 16, /* blocksize */ + 16, /* initial value length */ + 16, /* secret length -- 16*8 == 128bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes128 +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = { + "aes192-cbc", + "DEK-Info: AES-192-CBC", + 16, /* blocksize */ + 16, /* initial value length */ + 24, /* secret length -- 24*8 == 192bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes192 +}; + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = { + "aes256-cbc", + "DEK-Info: AES-256-CBC", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256 +}; + +/* rijndael-cbc@lysator.liu.se == aes256-cbc */ +static const LIBSSH2_CRYPT_METHOD + libssh2_crypt_method_rijndael_cbc_lysator_liu_se = { + "rijndael-cbc@lysator.liu.se", + "DEK-Info: AES-256-CBC", + 16, /* blocksize */ + 16, /* initial value length */ + 32, /* secret length -- 32*8 == 256bit */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_aes256 +}; +#endif /* LIBSSH2_AES */ + +#if LIBSSH2_BLOWFISH +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = { + "blowfish-cbc", + "", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_blowfish +}; +#endif /* LIBSSH2_BLOWFISH */ + +#if LIBSSH2_RC4 +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = { + "arcfour", + "DEK-Info: RC4", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_arcfour +}; + +static int +crypt_init_arcfour128(LIBSSH2_SESSION * session, + const LIBSSH2_CRYPT_METHOD * method, + unsigned char *iv, int *free_iv, + unsigned char *secret, int *free_secret, + int encrypt, void **abstract) +{ + int rc; + + rc = crypt_init(session, method, iv, free_iv, secret, free_secret, + encrypt, abstract); + if(rc == 0) { + struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract; + unsigned char block[8]; + size_t discard = 1536; + for(; discard; discard -= 8) + _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block, + method->blocksize); + } + + return rc; +} + +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = { + "arcfour128", + "", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init_arcfour128, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_arcfour +}; +#endif /* LIBSSH2_RC4 */ + +#if LIBSSH2_CAST +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = { + "cast128-cbc", + "", + 8, /* blocksize */ + 8, /* initial value length */ + 16, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_cast5 +}; +#endif /* LIBSSH2_CAST */ + +#if LIBSSH2_3DES +static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = { + "3des-cbc", + "DEK-Info: DES-EDE3-CBC", + 8, /* blocksize */ + 8, /* initial value length */ + 24, /* secret length */ + 0, /* flags */ + &crypt_init, + &crypt_encrypt, + &crypt_dtor, + _libssh2_cipher_3des +}; +#endif + +static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = { +#if LIBSSH2_AES_CTR + &libssh2_crypt_method_aes128_ctr, + &libssh2_crypt_method_aes192_ctr, + &libssh2_crypt_method_aes256_ctr, +#endif /* LIBSSH2_AES */ +#if LIBSSH2_AES + &libssh2_crypt_method_aes256_cbc, + &libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */ + &libssh2_crypt_method_aes192_cbc, + &libssh2_crypt_method_aes128_cbc, +#endif /* LIBSSH2_AES */ +#if LIBSSH2_BLOWFISH + &libssh2_crypt_method_blowfish_cbc, +#endif /* LIBSSH2_BLOWFISH */ +#if LIBSSH2_RC4 + &libssh2_crypt_method_arcfour128, + &libssh2_crypt_method_arcfour, +#endif /* LIBSSH2_RC4 */ +#if LIBSSH2_CAST + &libssh2_crypt_method_cast128_cbc, +#endif /* LIBSSH2_CAST */ +#if LIBSSH2_3DES + &libssh2_crypt_method_3des_cbc, +#endif /* LIBSSH2_DES */ +#ifdef LIBSSH2_CRYPT_NONE + &libssh2_crypt_method_none, +#endif + NULL +}; + +/* Expose to kex.c */ +const LIBSSH2_CRYPT_METHOD ** +libssh2_crypt_methods(void) +{ + return _libssh2_crypt_methods; +} diff --git a/libssh2/global.c b/libssh2/global.c new file mode 100644 index 0000000..6828984 --- /dev/null +++ b/libssh2/global.c @@ -0,0 +1,78 @@ +/* Copyright (c) 2010 Lars Nordin + * Copyright (C) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +static int _libssh2_initialized = 0; +static int _libssh2_init_flags = 0; + +LIBSSH2_API int +libssh2_init(int flags) +{ + if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) { + libssh2_crypto_init(); + } + + _libssh2_initialized++; + _libssh2_init_flags |= flags; + + return 0; +} + +LIBSSH2_API void +libssh2_exit(void) +{ + if(_libssh2_initialized == 0) + return; + + _libssh2_initialized--; + + if(_libssh2_initialized == 0 && + !(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) { + libssh2_crypto_exit(); + } + + return; +} + +void +_libssh2_init_if_needed(void) +{ + if(_libssh2_initialized == 0) + (void)libssh2_init (0); +} diff --git a/libssh2/hostkey.c b/libssh2/hostkey.c new file mode 100644 index 0000000..1631aae --- /dev/null +++ b/libssh2/hostkey.c @@ -0,0 +1,1129 @@ +/* Copyright (c) 2004-2006, Sara Golemon + * Copyright (c) 2009-2019 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#if LIBSSH2_RSA +/* *********** + * ssh-rsa * + *********** */ + +static int hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_rsa_init + * + * Initialize the server hostkey working area with e/n pair + */ +static int +hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + unsigned char *e, *n; + size_t e_len, n_len; + struct string_buf buf; + + if(*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + if(hostkey_data_len < 19) { + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, + "host key length too short"); + return -1; + } + + buf.data = (unsigned char *)hostkey_data; + buf.dataptr = buf.data; + buf.len = hostkey_data_len; + + if(_libssh2_match_string(&buf, "ssh-rsa")) + return -1; + + if(_libssh2_get_string(&buf, &e, &e_len)) + return -1; + + if(_libssh2_get_string(&buf, &n, &n_len)) + return -1; + + if(_libssh2_rsa_new(&rsactx, e, e_len, n, n_len, NULL, 0, + NULL, 0, NULL, 0, NULL, 0, NULL, 0, NULL, 0)) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_rsa_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + int ret; + + if(*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_rsa_new_private(&rsactx, session, privkeyfile, passphrase); + if(ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_initPEMFromMemory + * + * Load a Private Key from a memory + */ +static int +hostkey_method_ssh_rsa_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_rsa_ctx *rsactx; + int ret; + + if(*abstract) { + hostkey_method_ssh_rsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_rsa_new_private_frommemory(&rsactx, session, + privkeyfiledata, + privkeyfiledata_len, passphrase); + if(ret) { + return -1; + } + + *abstract = rsactx; + + return 0; +} + +/* + * hostkey_method_ssh_rsa_sign + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_rsa_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + (void) session; + + /* Skip past keyname_len(4) + keyname(7){"ssh-rsa"} + signature_len(4) */ + if(sig_len < 15) + return -1; + + sig += 15; + sig_len -= 15; + return _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len); +} + +/* + * hostkey_method_ssh_rsa_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + +#ifdef _libssh2_rsa_sha1_signv + return _libssh2_rsa_sha1_signv(session, signature, signature_len, + veccount, datavec, rsactx); +#else + int ret; + int i; + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); + + ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH, + signature, signature_len); + if(ret) { + return -1; + } + + return 0; +#endif +} + +/* + * hostkey_method_ssh_rsa_dtor + * + * Shutdown the hostkey + */ +static int +hostkey_method_ssh_rsa_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_rsa_ctx *rsactx = (libssh2_rsa_ctx *) (*abstract); + (void) session; + + _libssh2_rsa_free(rsactx); + + *abstract = NULL; + + return 0; +} + +#ifdef OPENSSL_NO_MD5 +#define MD5_DIGEST_LENGTH 16 +#endif + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_rsa = { + "ssh-rsa", + MD5_DIGEST_LENGTH, + hostkey_method_ssh_rsa_init, + hostkey_method_ssh_rsa_initPEM, + hostkey_method_ssh_rsa_initPEMFromMemory, + hostkey_method_ssh_rsa_sig_verify, + hostkey_method_ssh_rsa_signv, + NULL, /* encrypt */ + hostkey_method_ssh_rsa_dtor, +}; +#endif /* LIBSSH2_RSA */ + +#if LIBSSH2_DSA +/* *********** + * ssh-dss * + *********** */ + +static int hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_dss_init + * + * Initialize the server hostkey working area with p/q/g/y set + */ +static int +hostkey_method_ssh_dss_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + unsigned char *p, *q, *g, *y; + size_t p_len, q_len, g_len, y_len; + struct string_buf buf; + + if(*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + if(hostkey_data_len < 27) { + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, + "host key length too short"); + return -1; + } + + buf.data = (unsigned char *)hostkey_data; + buf.dataptr = buf.data; + buf.len = hostkey_data_len; + + if(_libssh2_match_string(&buf, "ssh-dss")) + return -1; + + if(_libssh2_get_string(&buf, &p, &p_len)) + return -1; + + if(_libssh2_get_string(&buf, &q, &q_len)) + return -1; + + if(_libssh2_get_string(&buf, &g, &g_len)) + return -1; + + if(_libssh2_get_string(&buf, &y, &y_len)) + return -1; + + if(_libssh2_dsa_new(&dsactx, p, p_len, q, q_len, + g, g_len, y, y_len, NULL, 0)) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * hostkey_method_ssh_dss_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_dss_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + int ret; + + if(*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_dsa_new_private(&dsactx, session, privkeyfile, passphrase); + if(ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * hostkey_method_ssh_dss_initPEMFromMemory + * + * Load a Private Key from memory + */ +static int +hostkey_method_ssh_dss_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_dsa_ctx *dsactx; + int ret; + + if(*abstract) { + hostkey_method_ssh_dss_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_dsa_new_private_frommemory(&dsactx, session, + privkeyfiledata, + privkeyfiledata_len, passphrase); + if(ret) { + return -1; + } + + *abstract = dsactx; + + return 0; +} + +/* + * libssh2_hostkey_method_ssh_dss_sign + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_dss_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + + /* Skip past keyname_len(4) + keyname(7){"ssh-dss"} + signature_len(4) */ + if(sig_len != 55) { + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid DSS signature length"); + } + + sig += 15; + sig_len -= 15; + + return _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len); +} + +/* + * hostkey_method_ssh_dss_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_sha1_ctx ctx; + int i; + + *signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH); + if(!*signature) { + return -1; + } + + *signature_len = 2 * SHA_DIGEST_LENGTH; + + libssh2_sha1_init(&ctx); + for(i = 0; i < veccount; i++) { + libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len); + } + libssh2_sha1_final(ctx, hash); + + if(_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) { + LIBSSH2_FREE(session, *signature); + return -1; + } + + return 0; +} + +/* + * libssh2_hostkey_method_ssh_dss_dtor + * + * Shutdown the hostkey method + */ +static int +hostkey_method_ssh_dss_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_dsa_ctx *dsactx = (libssh2_dsa_ctx *) (*abstract); + (void) session; + + _libssh2_dsa_free(dsactx); + + *abstract = NULL; + + return 0; +} + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_dss = { + "ssh-dss", + MD5_DIGEST_LENGTH, + hostkey_method_ssh_dss_init, + hostkey_method_ssh_dss_initPEM, + hostkey_method_ssh_dss_initPEMFromMemory, + hostkey_method_ssh_dss_sig_verify, + hostkey_method_ssh_dss_signv, + NULL, /* encrypt */ + hostkey_method_ssh_dss_dtor, +}; +#endif /* LIBSSH2_DSA */ + +#if LIBSSH2_ECDSA + +/* *********** + * ecdsa-sha2-nistp256/384/521 * + *********** */ + +static int +hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_ecdsa_init + * + * Initialize the server hostkey working area with e/n pair + */ +static int +hostkey_method_ssh_ecdsa_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + libssh2_ecdsa_ctx *ecdsactx = NULL; + unsigned char *type_str, *domain, *public_key; + size_t key_len, len; + libssh2_curve_type type; + struct string_buf buf; + + if(abstract != NULL && *abstract) { + hostkey_method_ssh_ecdsa_dtor(session, abstract); + *abstract = NULL; + } + + if(hostkey_data_len < 39) { + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, + "host key length too short"); + return -1; + } + + buf.data = (unsigned char *)hostkey_data; + buf.dataptr = buf.data; + buf.len = hostkey_data_len; + + if(_libssh2_get_string(&buf, &type_str, &len) || len != 19) + return -1; + + if(strncmp((char *) type_str, "ecdsa-sha2-nistp256", 19) == 0) { + type = LIBSSH2_EC_CURVE_NISTP256; + } + else if(strncmp((char *) type_str, "ecdsa-sha2-nistp384", 19) == 0) { + type = LIBSSH2_EC_CURVE_NISTP384; + } + else if(strncmp((char *) type_str, "ecdsa-sha2-nistp521", 19) == 0) { + type = LIBSSH2_EC_CURVE_NISTP521; + } + else { + return -1; + } + + if(_libssh2_get_string(&buf, &domain, &len) || len != 8) + return -1; + + if(type == LIBSSH2_EC_CURVE_NISTP256 && + strncmp((char *)domain, "nistp256", 8) != 0) { + return -1; + } + else if(type == LIBSSH2_EC_CURVE_NISTP384 && + strncmp((char *)domain, "nistp384", 8) != 0) { + return -1; + } + else if(type == LIBSSH2_EC_CURVE_NISTP521 && + strncmp((char *)domain, "nistp521", 8) != 0) { + return -1; + } + + /* public key */ + if(_libssh2_get_string(&buf, &public_key, &key_len)) + return -1; + + if(_libssh2_ecdsa_curve_name_with_octal_new(&ecdsactx, public_key, + key_len, type)) + return -1; + + if(abstract != NULL) + *abstract = ecdsactx; + + return 0; +} + +/* + * hostkey_method_ssh_ecdsa_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_ecdsa_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_ecdsa_ctx *ec_ctx = NULL; + int ret; + + if(abstract != NULL && *abstract) { + hostkey_method_ssh_ecdsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_ecdsa_new_private(&ec_ctx, session, + privkeyfile, passphrase); + + if(abstract != NULL) + *abstract = ec_ctx; + + return ret; +} + +/* + * hostkey_method_ssh_ecdsa_initPEMFromMemory + * + * Load a Private Key from memory + */ +static int +hostkey_method_ssh_ecdsa_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_ecdsa_ctx *ec_ctx = NULL; + int ret; + + if(abstract != NULL && *abstract) { + hostkey_method_ssh_ecdsa_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_ecdsa_new_private_frommemory(&ec_ctx, session, + privkeyfiledata, + privkeyfiledata_len, + passphrase); + if(ret) { + return -1; + } + + if(abstract != NULL) + *abstract = ec_ctx; + + return 0; +} + +/* + * hostkey_method_ecdsa_sig_verify + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + unsigned char *r, *s, *name; + size_t r_len, s_len, name_len; + uint32_t len; + struct string_buf buf; + libssh2_ecdsa_ctx *ctx = (libssh2_ecdsa_ctx *) (*abstract); + + (void) session; + + if(sig_len < 35) + return -1; + + /* keyname_len(4) + keyname(19){"ecdsa-sha2-nistp256"} + + signature_len(4) */ + buf.data = (unsigned char *)sig; + buf.dataptr = buf.data; + buf.len = sig_len; + + if(_libssh2_get_string(&buf, &name, &name_len) || name_len != 19) + return -1; + + if(_libssh2_get_u32(&buf, &len) != 0 || len < 8) + return -1; + + if(_libssh2_get_string(&buf, &r, &r_len)) + return -1; + + if(_libssh2_get_string(&buf, &s, &s_len)) + return -1; + + return _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len); +} + + +#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \ + { \ + unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ + libssh2_sha##digest_type##_ctx ctx; \ + int i; \ + libssh2_sha##digest_type##_init(&ctx); \ + for(i = 0; i < veccount; i++) { \ + libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \ + datavec[i].iov_len); \ + } \ + libssh2_sha##digest_type##_final(ctx, hash); \ + ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \ + SHA##digest_type##_DIGEST_LENGTH, \ + signature, signature_len); \ + } + + +/* + * hostkey_method_ecdsa_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_ecdsa_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_ecdsa_ctx *ec_ctx = (libssh2_ecdsa_ctx *) (*abstract); + libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_ctx); + int ret = 0; + + if(type == LIBSSH2_EC_CURVE_NISTP256) { + LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(256); + } + else if(type == LIBSSH2_EC_CURVE_NISTP384) { + LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(384); + } + else if(type == LIBSSH2_EC_CURVE_NISTP521) { + LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(512); + } + else { + return -1; + } + + return ret; +} + +/* + * hostkey_method_ssh_ecdsa_dtor + * + * Shutdown the hostkey by freeing EC_KEY context + */ +static int +hostkey_method_ssh_ecdsa_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_ecdsa_ctx *keyctx = (libssh2_ecdsa_ctx *) (*abstract); + (void) session; + + if(keyctx != NULL) + _libssh2_ecdsa_free(keyctx); + + *abstract = NULL; + + return 0; +} + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp256 = { + "ecdsa-sha2-nistp256", + SHA256_DIGEST_LENGTH, + hostkey_method_ssh_ecdsa_init, + hostkey_method_ssh_ecdsa_initPEM, + hostkey_method_ssh_ecdsa_initPEMFromMemory, + hostkey_method_ssh_ecdsa_sig_verify, + hostkey_method_ssh_ecdsa_signv, + NULL, /* encrypt */ + hostkey_method_ssh_ecdsa_dtor, +}; + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp384 = { + "ecdsa-sha2-nistp384", + SHA384_DIGEST_LENGTH, + hostkey_method_ssh_ecdsa_init, + hostkey_method_ssh_ecdsa_initPEM, + hostkey_method_ssh_ecdsa_initPEMFromMemory, + hostkey_method_ssh_ecdsa_sig_verify, + hostkey_method_ssh_ecdsa_signv, + NULL, /* encrypt */ + hostkey_method_ssh_ecdsa_dtor, +}; + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ecdsa_ssh_nistp521 = { + "ecdsa-sha2-nistp521", + SHA512_DIGEST_LENGTH, + hostkey_method_ssh_ecdsa_init, + hostkey_method_ssh_ecdsa_initPEM, + hostkey_method_ssh_ecdsa_initPEMFromMemory, + hostkey_method_ssh_ecdsa_sig_verify, + hostkey_method_ssh_ecdsa_signv, + NULL, /* encrypt */ + hostkey_method_ssh_ecdsa_dtor, +}; + +#endif /* LIBSSH2_ECDSA */ + +#if LIBSSH2_ED25519 + +/* *********** + * ed25519 * + *********** */ + +static int hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, + void **abstract); + +/* + * hostkey_method_ssh_ed25519_init + * + * Initialize the server hostkey working area with e/n pair + */ +static int +hostkey_method_ssh_ed25519_init(LIBSSH2_SESSION * session, + const unsigned char *hostkey_data, + size_t hostkey_data_len, + void **abstract) +{ + const unsigned char *s; + unsigned long len, key_len; + libssh2_ed25519_ctx *ctx = NULL; + + if(*abstract) { + hostkey_method_ssh_ed25519_dtor(session, abstract); + *abstract = NULL; + } + + if(hostkey_data_len < 19) { + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, + "host key length too short"); + return -1; + } + + s = hostkey_data; + len = _libssh2_ntohu32(s); + s += 4; + + if(len != 11 || strncmp((char *) s, "ssh-ed25519", 11) != 0) { + return -1; + } + + s += 11; + + /* public key */ + key_len = _libssh2_ntohu32(s); + s += 4; + + if(_libssh2_ed25519_new_public(&ctx, session, s, key_len) != 0) { + return -1; + } + + *abstract = ctx; + + return 0; +} + +/* + * hostkey_method_ssh_ed25519_initPEM + * + * Load a Private Key from a PEM file + */ +static int +hostkey_method_ssh_ed25519_initPEM(LIBSSH2_SESSION * session, + const char *privkeyfile, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_ed25519_ctx *ec_ctx = NULL; + int ret; + + if(*abstract) { + hostkey_method_ssh_ed25519_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_ed25519_new_private(&ec_ctx, session, + privkeyfile, passphrase); + if(ret) { + return -1; + } + + *abstract = ec_ctx; + + return ret; +} + +/* + * hostkey_method_ssh_ed25519_initPEMFromMemory + * + * Load a Private Key from memory + */ +static int +hostkey_method_ssh_ed25519_initPEMFromMemory(LIBSSH2_SESSION * session, + const char *privkeyfiledata, + size_t privkeyfiledata_len, + unsigned const char *passphrase, + void **abstract) +{ + libssh2_ed25519_ctx *ed_ctx = NULL; + int ret; + + if(abstract != NULL && *abstract) { + hostkey_method_ssh_ed25519_dtor(session, abstract); + *abstract = NULL; + } + + ret = _libssh2_ed25519_new_private_frommemory(&ed_ctx, session, + privkeyfiledata, + privkeyfiledata_len, + passphrase); + if(ret) { + return -1; + } + + if(abstract != NULL) + *abstract = ed_ctx; + + return 0; +} + +/* + * hostkey_method_ssh_ed25519_sig_verify + * + * Verify signature created by remote + */ +static int +hostkey_method_ssh_ed25519_sig_verify(LIBSSH2_SESSION * session, + const unsigned char *sig, + size_t sig_len, + const unsigned char *m, + size_t m_len, void **abstract) +{ + libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract); + (void) session; + + if(sig_len < 19) + return -1; + + /* Skip past keyname_len(4) + keyname(11){"ssh-ed25519"} + + signature_len(4) */ + sig += 19; + sig_len -= 19; + + if(sig_len != LIBSSH2_ED25519_SIG_LEN) + return -1; + + return _libssh2_ed25519_verify(ctx, sig, sig_len, m, m_len); +} + +/* + * hostkey_method_ssh_ed25519_signv + * + * Construct a signature from an array of vectors + */ +static int +hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec datavec[], + void **abstract) +{ + libssh2_ed25519_ctx *ctx = (libssh2_ed25519_ctx *) (*abstract); + + if(veccount != 1) { + return -1; + } + + return _libssh2_ed25519_sign(ctx, session, signature, signature_len, + datavec[0].iov_base, datavec[0].iov_len); +} + + +/* + * hostkey_method_ssh_ed25519_dtor + * + * Shutdown the hostkey by freeing key context + */ +static int +hostkey_method_ssh_ed25519_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + libssh2_ed25519_ctx *keyctx = (libssh2_ed25519_ctx*) (*abstract); + (void) session; + + if(keyctx) + _libssh2_ed25519_free(keyctx); + + *abstract = NULL; + + return 0; +} + +static const LIBSSH2_HOSTKEY_METHOD hostkey_method_ssh_ed25519 = { + "ssh-ed25519", + SHA256_DIGEST_LENGTH, + hostkey_method_ssh_ed25519_init, + hostkey_method_ssh_ed25519_initPEM, + hostkey_method_ssh_ed25519_initPEMFromMemory, + hostkey_method_ssh_ed25519_sig_verify, + hostkey_method_ssh_ed25519_signv, + NULL, /* encrypt */ + hostkey_method_ssh_ed25519_dtor, +}; + +#endif /*LIBSSH2_ED25519*/ + + +static const LIBSSH2_HOSTKEY_METHOD *hostkey_methods[] = { +#if LIBSSH2_ECDSA + &hostkey_method_ecdsa_ssh_nistp256, + &hostkey_method_ecdsa_ssh_nistp384, + &hostkey_method_ecdsa_ssh_nistp521, +#endif +#if LIBSSH2_ED25519 + &hostkey_method_ssh_ed25519, +#endif +#if LIBSSH2_RSA + &hostkey_method_ssh_rsa, +#endif /* LIBSSH2_RSA */ +#if LIBSSH2_DSA + &hostkey_method_ssh_dss, +#endif /* LIBSSH2_DSA */ + NULL +}; + +const LIBSSH2_HOSTKEY_METHOD ** +libssh2_hostkey_methods(void) +{ + return hostkey_methods; +} + +/* + * libssh2_hostkey_hash + * + * Returns hash signature + * Returned buffer should NOT be freed + * Length of buffer is determined by hash type + * i.e. MD5 == 16, SHA1 == 20, SHA256 == 32 + */ +LIBSSH2_API const char * +libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type) +{ + switch(hash_type) { +#if LIBSSH2_MD5 + case LIBSSH2_HOSTKEY_HASH_MD5: + return (session->server_hostkey_md5_valid) + ? (char *) session->server_hostkey_md5 + : NULL; + break; +#endif /* LIBSSH2_MD5 */ + case LIBSSH2_HOSTKEY_HASH_SHA1: + return (session->server_hostkey_sha1_valid) + ? (char *) session->server_hostkey_sha1 + : NULL; + break; + case LIBSSH2_HOSTKEY_HASH_SHA256: + return (session->server_hostkey_sha256_valid) + ? (char *) session->server_hostkey_sha256 + : NULL; + break; + default: + return NULL; + } +} + +static int hostkey_type(const unsigned char *hostkey, size_t len) +{ + static const unsigned char rsa[] = { + 0, 0, 0, 0x07, 's', 's', 'h', '-', 'r', 's', 'a' + }; + static const unsigned char dss[] = { + 0, 0, 0, 0x07, 's', 's', 'h', '-', 'd', 's', 's' + }; + static const unsigned char ecdsa_256[] = { + 0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-', + 'n', 'i', 's', 't', 'p', '2', '5', '6' + }; + static const unsigned char ecdsa_384[] = { + 0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-', + 'n', 'i', 's', 't', 'p', '3', '8', '4' + }; + static const unsigned char ecdsa_521[] = { + 0, 0, 0, 0x13, 'e', 'c', 'd', 's', 'a', '-', 's', 'h', 'a', '2', '-', + 'n', 'i', 's', 't', 'p', '5', '2', '1' + }; + static const unsigned char ed25519[] = { + 0, 0, 0, 0x0b, 's', 's', 'h', '-', 'e', 'd', '2', '5', '5', '1', '9' + }; + + if(len < 11) + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; + + if(!memcmp(rsa, hostkey, 11)) + return LIBSSH2_HOSTKEY_TYPE_RSA; + + if(!memcmp(dss, hostkey, 11)) + return LIBSSH2_HOSTKEY_TYPE_DSS; + + if(len < 15) + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; + + if(!memcmp(ed25519, hostkey, 15)) + return LIBSSH2_HOSTKEY_TYPE_ED25519; + + if(len < 23) + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; + + if(!memcmp(ecdsa_256, hostkey, 23)) + return LIBSSH2_HOSTKEY_TYPE_ECDSA_256; + + if(!memcmp(ecdsa_384, hostkey, 23)) + return LIBSSH2_HOSTKEY_TYPE_ECDSA_384; + + if(!memcmp(ecdsa_521, hostkey, 23)) + return LIBSSH2_HOSTKEY_TYPE_ECDSA_521; + + return LIBSSH2_HOSTKEY_TYPE_UNKNOWN; +} + +/* + * libssh2_session_hostkey() + * + * Returns the server key and length. + * + */ +LIBSSH2_API const char * +libssh2_session_hostkey(LIBSSH2_SESSION *session, size_t *len, int *type) +{ + if(session->server_hostkey_len) { + if(len) + *len = session->server_hostkey_len; + if(type) + *type = hostkey_type(session->server_hostkey, + session->server_hostkey_len); + return (char *) session->server_hostkey; + } + if(len) + *len = 0; + return NULL; +} diff --git a/libssh2/keepalive.c b/libssh2/keepalive.c new file mode 100644 index 0000000..2151b17 --- /dev/null +++ b/libssh2/keepalive.c @@ -0,0 +1,100 @@ +/* Copyright (C) 2010 Simon Josefsson + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" +#include "transport.h" /* _libssh2_transport_write */ + +/* Keep-alive stuff. */ + +LIBSSH2_API void +libssh2_keepalive_config (LIBSSH2_SESSION *session, + int want_reply, + unsigned interval) +{ + if(interval == 1) + session->keepalive_interval = 2; + else + session->keepalive_interval = interval; + session->keepalive_want_reply = want_reply ? 1 : 0; +} + +LIBSSH2_API int +libssh2_keepalive_send (LIBSSH2_SESSION *session, + int *seconds_to_next) +{ + time_t now; + + if(!session->keepalive_interval) { + if(seconds_to_next) + *seconds_to_next = 0; + return 0; + } + + now = time(NULL); + + if(session->keepalive_last_sent + session->keepalive_interval <= now) { + /* Format is + "SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */ + unsigned char keepalive_data[] + = "\x50\x00\x00\x00\x15keepalive@libssh2.orgW"; + size_t len = sizeof(keepalive_data) - 1; + int rc; + + keepalive_data[len - 1] = + (unsigned char)session->keepalive_want_reply; + + rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0); + /* Silently ignore PACKET_EAGAIN here: if the write buffer is + already full, sending another keepalive is not useful. */ + if(rc && rc != LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keepalive message"); + return rc; + } + + session->keepalive_last_sent = now; + if(seconds_to_next) + *seconds_to_next = session->keepalive_interval; + } + else if(seconds_to_next) { + *seconds_to_next = (int) (session->keepalive_last_sent - now) + + session->keepalive_interval; + } + + return 0; +} diff --git a/libssh2/kex.c b/libssh2/kex.c new file mode 100644 index 0000000..b225a2f --- /dev/null +++ b/libssh2/kex.c @@ -0,0 +1,4453 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010-2019, Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#include "transport.h" +#include "comp.h" +#include "mac.h" + +/* TODO: Switch this to an inline and handle alloc() failures */ +/* Helper macro called from + kex_method_diffie_hellman_group1_sha1_key_exchange */ +#define LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(value, reqlen, version) \ + { \ + libssh2_sha1_ctx hash; \ + unsigned long len = 0; \ + if(!(value)) { \ + value = LIBSSH2_ALLOC(session, reqlen + SHA_DIGEST_LENGTH); \ + } \ + if(value) \ + while(len < (unsigned long)reqlen) { \ + libssh2_sha1_init(&hash); \ + libssh2_sha1_update(hash, exchange_state->k_value, \ + exchange_state->k_value_len); \ + libssh2_sha1_update(hash, exchange_state->h_sig_comp, \ + SHA_DIGEST_LENGTH); \ + if(len > 0) { \ + libssh2_sha1_update(hash, value, len); \ + } \ + else { \ + libssh2_sha1_update(hash, (version), 1); \ + libssh2_sha1_update(hash, session->session_id, \ + session->session_id_len); \ + } \ + libssh2_sha1_final(hash, (value) + len); \ + len += SHA_DIGEST_LENGTH; \ + } \ + } \ + + +#define LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(value, reqlen, version) \ + { \ + if(type == LIBSSH2_EC_CURVE_NISTP256) { \ + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, value, reqlen, version); \ + } \ + else if(type == LIBSSH2_EC_CURVE_NISTP384) { \ + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(384, value, reqlen, version); \ + } \ + else if(type == LIBSSH2_EC_CURVE_NISTP521) { \ + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, value, reqlen, version); \ + } \ + } \ + + +#define LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(digest_type, value, \ + reqlen, version) \ +{ \ + libssh2_sha##digest_type##_ctx hash; \ + unsigned long len = 0; \ + if(!(value)) { \ + value = LIBSSH2_ALLOC(session, \ + reqlen + SHA##digest_type##_DIGEST_LENGTH); \ + } \ + if(value) \ + while(len < (unsigned long)reqlen) { \ + libssh2_sha##digest_type##_init(&hash); \ + libssh2_sha##digest_type##_update(hash, \ + exchange_state->k_value, \ + exchange_state->k_value_len); \ + libssh2_sha##digest_type##_update(hash, \ + exchange_state->h_sig_comp, \ + SHA##digest_type##_DIGEST_LENGTH); \ + if(len > 0) { \ + libssh2_sha##digest_type##_update(hash, value, len); \ + } \ + else { \ + libssh2_sha##digest_type##_update(hash, (version), 1); \ + libssh2_sha##digest_type##_update(hash, session->session_id, \ + session->session_id_len); \ + } \ + libssh2_sha##digest_type##_final(hash, (value) + len); \ + len += SHA##digest_type##_DIGEST_LENGTH; \ + } \ +} + + +/* + * diffie_hellman_sha1 + * + * Diffie Hellman Key Exchange, Group Agnostic + */ +static int diffie_hellman_sha1(LIBSSH2_SESSION *session, + _libssh2_bn *g, + _libssh2_bn *p, + int group_order, + unsigned char packet_type_init, + unsigned char packet_type_reply, + unsigned char *midhash, + unsigned long midhash_len, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + libssh2_sha1_ctx exchange_hash_ctx; + + if(exchange_state->state == libssh2_NB_state_idle) { + /* Setup initial values */ + exchange_state->e_packet = NULL; + exchange_state->s_packet = NULL; + exchange_state->k_value = NULL; + exchange_state->ctx = _libssh2_bn_ctx_new(); + libssh2_dh_init(&exchange_state->x); + exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ + exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from + server) mod p */ + exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod + p */ + + /* Zero the whole thing out */ + memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); + + /* Generate x and e */ + rc = libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, + group_order, exchange_state->ctx); + if(rc) + goto clean_exit; + + /* Send KEX init */ + /* packet_type(1) + String Length(4) + leading 0(1) */ + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; + if(_libssh2_bn_bits(exchange_state->e) % 8) { + /* Leading 00 not needed */ + exchange_state->e_packet_len--; + } + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + if(!exchange_state->e_packet) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory error"); + goto clean_exit; + } + exchange_state->e_packet[0] = packet_type_init; + _libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); + if(_libssh2_bn_bits(exchange_state->e) % 8) { + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); + } + else { + exchange_state->e_packet[5] = 0; + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", + (int) packet_type_init); + exchange_state->state = libssh2_NB_state_created; + } + + if(exchange_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, exchange_state->e_packet, + exchange_state->e_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send KEX init message"); + goto clean_exit; + } + exchange_state->state = libssh2_NB_state_sent; + } + + if(exchange_state->state == libssh2_NB_state_sent) { + if(session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially + * sent by the server. That guess turned out to be wrong so we + * need to silently ignore it */ + int burn_type; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Waiting for badly guessed KEX packet " + "(to be ignored)"); + burn_type = + _libssh2_packet_burn(session, &exchange_state->burn_state); + if(burn_type == LIBSSH2_ERROR_EAGAIN) { + return burn_type; + } + else if(burn_type <= 0) { + /* Failed to receive a packet */ + ret = burn_type; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Burnt packet of type: %02x", + (unsigned int) burn_type); + } + + exchange_state->state = libssh2_NB_state_sent1; + } + + if(exchange_state->state == libssh2_NB_state_sent1) { + /* Wait for KEX reply */ + struct string_buf buf; + size_t host_key_len; + + rc = _libssh2_packet_require(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if(rc) { + ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply"); + goto clean_exit; + } + + /* Parse KEXDH_REPLY */ + if(exchange_state->s_packet_len < 5) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet length"); + goto clean_exit; + } + + buf.data = exchange_state->s_packet; + buf.len = exchange_state->s_packet_len; + buf.dataptr = buf.data; + buf.dataptr++; /* advance past type */ + + if(session->server_hostkey) + LIBSSH2_FREE(session, session->server_hostkey); + + if(_libssh2_copy_string(session, &buf, &(session->server_hostkey), + &host_key_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Could not copy host key"); + goto clean_exit; + } + + session->server_hostkey_len = (uint32_t)host_key_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if(libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if(libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + { + libssh2_sha256_ctx fingerprint_ctx; + + if(libssh2_sha256_init(&fingerprint_ctx)) { + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256); + session->server_hostkey_sha256_valid = TRUE; + } + else { + session->server_hostkey_sha256_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char *base64Fingerprint = NULL; + _libssh2_base64_encode(session, + (const char *) + session->server_hostkey_sha256, + SHA256_DIGEST_LENGTH, &base64Fingerprint); + if(base64Fingerprint != NULL) { + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA256 Fingerprint: %s", + base64Fingerprint); + LIBSSH2_FREE(session, base64Fingerprint); + } + } +#endif /* LIBSSH2DEBUG */ + + + if(session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + if(_libssh2_get_string(&buf, &(exchange_state->f_value), + &(exchange_state->f_value_len))) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to get f value"); + goto clean_exit; + } + + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + + if(_libssh2_get_string(&buf, &(exchange_state->h_sig), + &(exchange_state->h_sig_len))) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to get h sig"); + goto clean_exit; + } + + /* Compute the shared secret */ + libssh2_dh_secret(&exchange_state->x, exchange_state->k, + exchange_state->f, p, exchange_state->ctx); + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if(_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if(!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if(_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } + else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + exchange_state->exchange_hash = (void *)&exchange_hash_ctx; + libssh2_sha1_init(&exchange_hash_ctx); + + if(session->local.banner) { + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->local.banner, + strlen((char *) session->local.banner) - 2); + } + else { + _libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + (const unsigned char *) + LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } + + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->remote.banner, + strlen((char *) session->remote.banner)); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); + + if(packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ +#ifdef LIBSSH2_DH_GEX_NEW + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 12); +#else + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); +#endif + } + + if(midhash) { + libssh2_sha1_update(exchange_hash_ctx, midhash, + midhash_len); + } + + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + _libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha1_update(exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha1_final(exchange_hash_ctx, + exchange_state->h_sig_comp); + + if(session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->h_sig_comp, + 20, &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message"); + exchange_state->c = SSH_MSG_NEWKEYS; + + exchange_state->state = libssh2_NB_state_sent2; + } + + if(exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent3; + } + + if(exchange_state->state == libssh2_NB_state_sent3) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if(!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA_DIGEST_LENGTH); + if(!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for " + "SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + SHA_DIGEST_LENGTH); + session->session_id_len = SHA_DIGEST_LENGTH; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if(session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if(session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, + session->local.crypt-> + iv_len, + (const unsigned char *) + "A"); + if(!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, + session->local.crypt-> + secret_len, + (const unsigned char *) + "C"); + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if(session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if(session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv, + session->remote.crypt-> + iv_len, + (const unsigned char *) + "B"); + if(!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret, + session->remote.crypt-> + secret_len, + (const unsigned char *) + "D"); + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if(session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if(session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, + session->local.mac-> + key_len, + (const unsigned char *) + "E"); + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if(session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if(session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key, + session->remote.mac-> + key_len, + (const unsigned char *) + "F"); + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if(session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if(session->local.comp && session->local.comp->init) { + if(session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if(session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if(session->remote.comp && session->remote.comp->init) { + if(session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + + clean_exit: + libssh2_dh_dtor(&exchange_state->x); + _libssh2_bn_free(exchange_state->e); + exchange_state->e = NULL; + _libssh2_bn_free(exchange_state->f); + exchange_state->f = NULL; + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + _libssh2_bn_ctx_free(exchange_state->ctx); + exchange_state->ctx = NULL; + + if(exchange_state->e_packet) { + LIBSSH2_FREE(session, exchange_state->e_packet); + exchange_state->e_packet = NULL; + } + + if(exchange_state->s_packet) { + LIBSSH2_FREE(session, exchange_state->s_packet); + exchange_state->s_packet = NULL; + } + + if(exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + + +/* + * diffie_hellman_sha256 + * + * Diffie Hellman Key Exchange, Group Agnostic + */ +static int diffie_hellman_sha256(LIBSSH2_SESSION *session, + _libssh2_bn *g, + _libssh2_bn *p, + int group_order, + unsigned char packet_type_init, + unsigned char packet_type_reply, + unsigned char *midhash, + unsigned long midhash_len, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + libssh2_sha256_ctx exchange_hash_ctx; + + if(exchange_state->state == libssh2_NB_state_idle) { + /* Setup initial values */ + exchange_state->e_packet = NULL; + exchange_state->s_packet = NULL; + exchange_state->k_value = NULL; + exchange_state->ctx = _libssh2_bn_ctx_new(); + libssh2_dh_init(&exchange_state->x); + exchange_state->e = _libssh2_bn_init(); /* g^x mod p */ + exchange_state->f = _libssh2_bn_init_from_bin(); /* g^(Random from + server) mod p */ + exchange_state->k = _libssh2_bn_init(); /* The shared secret: f^x mod + p */ + + /* Zero the whole thing out */ + memset(&exchange_state->req_state, 0, sizeof(packet_require_state_t)); + + /* Generate x and e */ + rc = libssh2_dh_key_pair(&exchange_state->x, exchange_state->e, g, p, + group_order, exchange_state->ctx); + if(rc) + goto clean_exit; + + /* Send KEX init */ + /* packet_type(1) + String Length(4) + leading 0(1) */ + exchange_state->e_packet_len = + _libssh2_bn_bytes(exchange_state->e) + 6; + if(_libssh2_bn_bits(exchange_state->e) % 8) { + /* Leading 00 not needed */ + exchange_state->e_packet_len--; + } + + exchange_state->e_packet = + LIBSSH2_ALLOC(session, exchange_state->e_packet_len); + if(!exchange_state->e_packet) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory error"); + goto clean_exit; + } + exchange_state->e_packet[0] = packet_type_init; + _libssh2_htonu32(exchange_state->e_packet + 1, + exchange_state->e_packet_len - 5); + if(_libssh2_bn_bits(exchange_state->e) % 8) { + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 5); + } + else { + exchange_state->e_packet[5] = 0; + _libssh2_bn_to_bin(exchange_state->e, + exchange_state->e_packet + 6); + } + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d", + (int) packet_type_init); + exchange_state->state = libssh2_NB_state_created; + } + + if(exchange_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, exchange_state->e_packet, + exchange_state->e_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send KEX init message"); + goto clean_exit; + } + exchange_state->state = libssh2_NB_state_sent; + } + + if(exchange_state->state == libssh2_NB_state_sent) { + if(session->burn_optimistic_kexinit) { + /* The first KEX packet to come along will be the guess initially + * sent by the server. That guess turned out to be wrong so we + * need to silently ignore it */ + int burn_type; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Waiting for badly guessed KEX packet " + "(to be ignored)"); + burn_type = + _libssh2_packet_burn(session, &exchange_state->burn_state); + if(burn_type == LIBSSH2_ERROR_EAGAIN) { + return burn_type; + } + else if(burn_type <= 0) { + /* Failed to receive a packet */ + ret = burn_type; + goto clean_exit; + } + session->burn_optimistic_kexinit = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Burnt packet of type: %02x", + (unsigned int) burn_type); + } + + exchange_state->state = libssh2_NB_state_sent1; + } + + if(exchange_state->state == libssh2_NB_state_sent1) { + /* Wait for KEX reply */ + struct string_buf buf; + size_t host_key_len; + + rc = _libssh2_packet_require(session, packet_type_reply, + &exchange_state->s_packet, + &exchange_state->s_packet_len, 0, NULL, + 0, &exchange_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + if(rc) { + ret = _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting for KEX reply"); + goto clean_exit; + } + + /* Parse KEXDH_REPLY */ + if(exchange_state->s_packet_len < 5) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet length"); + goto clean_exit; + } + + buf.data = exchange_state->s_packet; + buf.len = exchange_state->s_packet_len; + buf.dataptr = buf.data; + buf.dataptr++; /* advance past type */ + + if(session->server_hostkey) + LIBSSH2_FREE(session, session->server_hostkey); + + if(_libssh2_copy_string(session, &buf, &(session->server_hostkey), + &host_key_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Could not copy host key"); + goto clean_exit; + } + + session->server_hostkey_len = (uint32_t)host_key_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if(libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if(libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + { + libssh2_sha256_ctx fingerprint_ctx; + + if(libssh2_sha256_init(&fingerprint_ctx)) { + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256); + session->server_hostkey_sha256_valid = TRUE; + } + else { + session->server_hostkey_sha256_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char *base64Fingerprint = NULL; + _libssh2_base64_encode(session, + (const char *) + session->server_hostkey_sha256, + SHA256_DIGEST_LENGTH, &base64Fingerprint); + if(base64Fingerprint != NULL) { + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA256 Fingerprint: %s", + base64Fingerprint); + LIBSSH2_FREE(session, base64Fingerprint); + } + } +#endif /* LIBSSH2DEBUG */ + + if(session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + if(_libssh2_get_string(&buf, &(exchange_state->f_value), + &(exchange_state->f_value_len))) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to get f value"); + goto clean_exit; + } + + _libssh2_bn_from_bin(exchange_state->f, exchange_state->f_value_len, + exchange_state->f_value); + + if(_libssh2_get_string(&buf, &(exchange_state->h_sig), + &(exchange_state->h_sig_len))) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to get h sig"); + goto clean_exit; + } + + /* Compute the shared secret */ + libssh2_dh_secret(&exchange_state->x, exchange_state->k, + exchange_state->f, p, exchange_state->ctx); + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if(_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if(!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if(_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } + else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + exchange_state->exchange_hash = (void *)&exchange_hash_ctx; + libssh2_sha256_init(&exchange_hash_ctx); + + if(session->local.banner) { + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->local.banner) - 2); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->local.banner, + strlen((char *) session->local.banner) - 2); + } + else { + _libssh2_htonu32(exchange_state->h_sig_comp, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + (const unsigned char *) + LIBSSH2_SSH_DEFAULT_BANNER, + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); + } + + _libssh2_htonu32(exchange_state->h_sig_comp, + strlen((char *) session->remote.banner)); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->remote.banner, + strlen((char *) session->remote.banner)); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->local.kexinit_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->local.kexinit, + session->local.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->remote.kexinit_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->remote.kexinit, + session->remote.kexinit_len); + + _libssh2_htonu32(exchange_state->h_sig_comp, + session->server_hostkey_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + session->server_hostkey, + session->server_hostkey_len); + + if(packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) { + /* diffie-hellman-group-exchange hashes additional fields */ +#ifdef LIBSSH2_DH_GEX_NEW + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 4, + LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(exchange_state->h_sig_comp + 8, + LIBSSH2_DH_GEX_MAXGROUP); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 12); +#else + _libssh2_htonu32(exchange_state->h_sig_comp, + LIBSSH2_DH_GEX_OPTGROUP); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); +#endif + } + + if(midhash) { + libssh2_sha256_update(exchange_hash_ctx, midhash, + midhash_len); + } + + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->e_packet + 1, + exchange_state->e_packet_len - 1); + + _libssh2_htonu32(exchange_state->h_sig_comp, + exchange_state->f_value_len); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->h_sig_comp, 4); + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->f_value, + exchange_state->f_value_len); + + libssh2_sha256_update(exchange_hash_ctx, + exchange_state->k_value, + exchange_state->k_value_len); + + libssh2_sha256_final(exchange_hash_ctx, + exchange_state->h_sig_comp); + + if(session->hostkey-> + sig_verify(session, exchange_state->h_sig, + exchange_state->h_sig_len, exchange_state->h_sig_comp, + SHA256_DIGEST_LENGTH, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sending NEWKEYS message"); + exchange_state->c = SSH_MSG_NEWKEYS; + + exchange_state->state = libssh2_NB_state_sent2; + } + + if(exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent3; + } + + if(exchange_state->state == libssh2_NB_state_sent3) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if(!session->session_id) { + session->session_id = LIBSSH2_ALLOC(session, SHA256_DIGEST_LENGTH); + if(!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for " + "SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + SHA256_DIGEST_LENGTH); + session->session_id_len = SHA256_DIGEST_LENGTH; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if(session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if(session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv, + session->local.crypt-> + iv_len, + (const unsigned char *)"A"); + if(!iv) { + ret = -1; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret, + session->local.crypt-> + secret_len, + (const unsigned char *)"C"); + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if(session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if(session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv, + session->remote.crypt-> + iv_len, + (const unsigned char *)"B"); + if(!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret, + session->remote.crypt-> + secret_len, + (const unsigned char *)"D"); + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if(session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if(session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key, + session->local.mac-> + key_len, + (const unsigned char *)"E"); + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if(session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if(session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key, + session->remote.mac-> + key_len, + (const unsigned char *)"F"); + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if(session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if(session->local.comp && session->local.comp->init) { + if(session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if(session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if(session->remote.comp && session->remote.comp->init) { + if(session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + + clean_exit: + libssh2_dh_dtor(&exchange_state->x); + _libssh2_bn_free(exchange_state->e); + exchange_state->e = NULL; + _libssh2_bn_free(exchange_state->f); + exchange_state->f = NULL; + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + _libssh2_bn_ctx_free(exchange_state->ctx); + exchange_state->ctx = NULL; + + if(exchange_state->e_packet) { + LIBSSH2_FREE(session, exchange_state->e_packet); + exchange_state->e_packet = NULL; + } + + if(exchange_state->s_packet) { + LIBSSH2_FREE(session, exchange_state->s_packet); + exchange_state->s_packet = NULL; + } + + if(exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + + + +/* kex_method_diffie_hellman_group1_sha1_key_exchange + * Diffie-Hellman Group1 (Actually Group2) Key Exchange using SHA1 + */ +static int +kex_method_diffie_hellman_group1_sha1_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + static const unsigned char p_value[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + + int ret; + + if(key_state->state == libssh2_NB_state_idle) { + /* g == 2 */ + key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value + (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + + /* Initialize P and G */ + _libssh2_bn_set_word(key_state->g, 2); + _libssh2_bn_from_bin(key_state->p, 128, p_value); + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group1 Key Exchange"); + + key_state->state = libssh2_NB_state_created; + } + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, 128, + SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, + NULL, 0, &key_state->exchange_state); + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + key_state->state = libssh2_NB_state_idle; + + return ret; +} + + + +/* kex_method_diffie_hellman_group14_key_exchange + * Diffie-Hellman Group14 Key Exchange with hash function callback + */ +typedef int (*diffie_hellman_hash_func_t)(LIBSSH2_SESSION *, + _libssh2_bn *, + _libssh2_bn *, + int, + unsigned char, + unsigned char, + unsigned char *, + unsigned long, + kmdhgGPshakex_state_t *); +static int +kex_method_diffie_hellman_group14_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state, + diffie_hellman_hash_func_t + hashfunc) +{ + static const unsigned char p_value[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + int ret; + + if(key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init_from_bin(); /* SSH2 defined value + (p_value) */ + key_state->g = _libssh2_bn_init(); /* SSH2 defined value (2) */ + + /* g == 2 */ + /* Initialize P and G */ + _libssh2_bn_set_word(key_state->g, 2); + _libssh2_bn_from_bin(key_state->p, 256, p_value); + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group14 Key Exchange"); + + key_state->state = libssh2_NB_state_created; + } + ret = hashfunc(session, key_state->g, key_state->p, + 256, SSH_MSG_KEXDH_INIT, SSH_MSG_KEXDH_REPLY, + NULL, 0, &key_state->exchange_state); + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + + return ret; +} + + + +/* kex_method_diffie_hellman_group14_sha1_key_exchange + * Diffie-Hellman Group14 Key Exchange using SHA1 + */ +static int +kex_method_diffie_hellman_group14_sha1_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + return kex_method_diffie_hellman_group14_key_exchange(session, key_state, + diffie_hellman_sha1); +} + + + +/* kex_method_diffie_hellman_group14_sha256_key_exchange + * Diffie-Hellman Group14 Key Exchange using SHA256 + */ +static int +kex_method_diffie_hellman_group14_sha256_key_exchange(LIBSSH2_SESSION *session, + key_exchange_state_low_t + * key_state) +{ + return kex_method_diffie_hellman_group14_key_exchange(session, key_state, + diffie_hellman_sha256); +} + + + +/* kex_method_diffie_hellman_group_exchange_sha1_key_exchange + * Diffie-Hellman Group Exchange Key Exchange using SHA1 + * Negotiates random(ish) group for secret derivation + */ +static int +kex_method_diffie_hellman_group_exchange_sha1_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + int ret = 0; + int rc; + + if(key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init_from_bin(); + key_state->g = _libssh2_bn_init_from_bin(); + /* Ask for a P and G pair */ +#ifdef LIBSSH2_DH_GEX_NEW + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); + key_state->request_len = 13; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange " + "(New Method)"); +#else + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); + key_state->request_len = 5; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange " + "(Old Method)"); +#endif + + key_state->state = libssh2_NB_state_created; + } + + if(key_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send Group Exchange Request"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent; + } + + if(key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for GEX_GROUP reply"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if(key_state->state == libssh2_NB_state_sent1) { + size_t p_len, g_len; + unsigned char *p, *g; + struct string_buf buf; + + if(key_state->data_len < 9) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected key length"); + goto dh_gex_clean_exit; + } + + buf.data = key_state->data; + buf.dataptr = buf.data; + buf.len = key_state->data_len; + + buf.dataptr++; /* increment to big num */ + + if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected value"); + goto dh_gex_clean_exit; + } + + if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected value"); + goto dh_gex_clean_exit; + } + + _libssh2_bn_from_bin(key_state->p, p_len, p); + _libssh2_bn_from_bin(key_state->g, g_len, g); + + ret = diffie_hellman_sha1(session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, + SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, + key_state->data_len - 1, + &key_state->exchange_state); + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + + dh_gex_clean_exit: + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + + return ret; +} + + + +/* kex_method_diffie_hellman_group_exchange_sha256_key_exchange + * Diffie-Hellman Group Exchange Key Exchange using SHA256 + * Negotiates random(ish) group for secret derivation + */ +static int +kex_method_diffie_hellman_group_exchange_sha256_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + int ret = 0; + int rc; + + if(key_state->state == libssh2_NB_state_idle) { + key_state->p = _libssh2_bn_init(); + key_state->g = _libssh2_bn_init(); + /* Ask for a P and G pair */ +#ifdef LIBSSH2_DH_GEX_NEW + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_MINGROUP); + _libssh2_htonu32(key_state->request + 5, LIBSSH2_DH_GEX_OPTGROUP); + _libssh2_htonu32(key_state->request + 9, LIBSSH2_DH_GEX_MAXGROUP); + key_state->request_len = 13; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange " + "(New Method SHA256)"); +#else + key_state->request[0] = SSH_MSG_KEX_DH_GEX_REQUEST_OLD; + _libssh2_htonu32(key_state->request + 1, LIBSSH2_DH_GEX_OPTGROUP); + key_state->request_len = 5; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating Diffie-Hellman Group-Exchange " + "(Old Method SHA256)"); +#endif + + key_state->state = libssh2_NB_state_created; + } + + if(key_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send " + "Group Exchange Request SHA256"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent; + } + + if(key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_packet_require(session, SSH_MSG_KEX_DH_GEX_GROUP, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for GEX_GROUP reply SHA256"); + goto dh_gex_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if(key_state->state == libssh2_NB_state_sent1) { + unsigned char *p, *g; + size_t p_len, g_len; + struct string_buf buf; + + if(key_state->data_len < 9) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected key length"); + goto dh_gex_clean_exit; + } + + buf.data = key_state->data; + buf.dataptr = buf.data; + buf.len = key_state->data_len; + + buf.dataptr++; /* increment to big num */ + + if(_libssh2_get_bignum_bytes(&buf, &p, &p_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected value"); + goto dh_gex_clean_exit; + } + + if(_libssh2_get_bignum_bytes(&buf, &g, &g_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected value"); + goto dh_gex_clean_exit; + } + + _libssh2_bn_from_bin(key_state->p, p_len, p); + _libssh2_bn_from_bin(key_state->g, g_len, g); + + ret = diffie_hellman_sha256(session, key_state->g, key_state->p, p_len, + SSH_MSG_KEX_DH_GEX_INIT, + SSH_MSG_KEX_DH_GEX_REPLY, + key_state->data + 1, + key_state->data_len - 1, + &key_state->exchange_state); + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + + dh_gex_clean_exit: + key_state->state = libssh2_NB_state_idle; + _libssh2_bn_free(key_state->g); + key_state->g = NULL; + _libssh2_bn_free(key_state->p); + key_state->p = NULL; + + return ret; +} + + +#if LIBSSH2_ECDSA + +/* kex_session_ecdh_curve_type + * returns the EC curve type by name used in key exchange + */ + +static int +kex_session_ecdh_curve_type(const char *name, libssh2_curve_type *out_type) +{ + int ret = 0; + libssh2_curve_type type; + + if(name == NULL) + return -1; + + if(strcmp(name, "ecdh-sha2-nistp256") == 0) + type = LIBSSH2_EC_CURVE_NISTP256; + else if(strcmp(name, "ecdh-sha2-nistp384") == 0) + type = LIBSSH2_EC_CURVE_NISTP384; + else if(strcmp(name, "ecdh-sha2-nistp521") == 0) + type = LIBSSH2_EC_CURVE_NISTP521; + else { + ret = -1; + } + + if(ret == 0 && out_type) { + *out_type = type; + } + + return ret; +} + + +/* LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY + * + * Macro that create and verifies EC SHA hash with a given digest bytes + * + * Payload format: + * + * string V_C, client's identification string (CR and LF excluded) + * string V_S, server's identification string (CR and LF excluded) + * string I_C, payload of the client's SSH_MSG_KEXINIT + * string I_S, payload of the server's SSH_MSG_KEXINIT + * string K_S, server's public host key + * string Q_C, client's ephemeral public key octet string + * string Q_S, server's ephemeral public key octet string + * mpint K, shared secret + * + */ + +#define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \ +{ \ + libssh2_sha##digest_type##_ctx ctx; \ + exchange_state->exchange_hash = (void *)&ctx; \ + libssh2_sha##digest_type##_init(&ctx); \ + if(session->local.banner) { \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + strlen((char *) session->local.banner) - 2); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + (char *) session->local.banner, \ + strlen((char *) \ + session->local.banner) \ + - 2); \ + } \ + else { \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + LIBSSH2_SSH_DEFAULT_BANNER, \ + sizeof(LIBSSH2_SSH_DEFAULT_BANNER) \ + - 1); \ + } \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + strlen((char *) session->remote.banner)); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->remote.banner, \ + strlen((char *) \ + session->remote.banner)); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + session->local.kexinit_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->local.kexinit, \ + session->local.kexinit_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + session->remote.kexinit_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->remote.kexinit, \ + session->remote.kexinit_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + session->server_hostkey_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + session->server_hostkey, \ + session->server_hostkey_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + public_key_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + public_key, \ + public_key_len); \ + \ + _libssh2_htonu32(exchange_state->h_sig_comp, \ + server_public_key_len); \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->h_sig_comp, 4); \ + libssh2_sha##digest_type##_update(ctx, \ + server_public_key, \ + server_public_key_len); \ + \ + libssh2_sha##digest_type##_update(ctx, \ + exchange_state->k_value, \ + exchange_state->k_value_len); \ + \ + libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \ + \ + if(session->hostkey-> \ + sig_verify(session, exchange_state->h_sig, \ + exchange_state->h_sig_len, exchange_state->h_sig_comp, \ + SHA##digest_type##_DIGEST_LENGTH, \ + &session->server_hostkey_abstract)) { \ + rc = -1; \ + } \ +} \ + + +/* ecdh_sha2_nistp + * Elliptic Curve Diffie Hellman Key Exchange + */ + +static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type, + unsigned char *data, size_t data_len, + unsigned char *public_key, + size_t public_key_len, _libssh2_ec_key *private_key, + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + + if(data_len < 5) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Host key data is too short"); + return ret; + } + + if(exchange_state->state == libssh2_NB_state_idle) { + + /* Setup initial values */ + exchange_state->k = _libssh2_bn_init(); + + exchange_state->state = libssh2_NB_state_created; + } + + if(exchange_state->state == libssh2_NB_state_created) { + /* parse INIT reply data */ + + /* host key K_S */ + unsigned char *s = data + 1; /* Advance past packet type */ + unsigned char *server_public_key; + size_t server_public_key_len; + size_t host_sig_len; + + session->server_hostkey_len = + _libssh2_ntohu32((const unsigned char *)s); + s += 4; + + session->server_hostkey = LIBSSH2_ALLOC(session, + session->server_hostkey_len); + if(!session->server_hostkey) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for a copy " + "of the host key"); + goto clean_exit; + } + + memcpy(session->server_hostkey, s, session->server_hostkey_len); + s += session->server_hostkey_len; + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if(libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if(libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + /* SHA256 */ + { + libssh2_sha256_ctx fingerprint_ctx; + + if(libssh2_sha256_init(&fingerprint_ctx)) { + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256); + session->server_hostkey_sha256_valid = TRUE; + } + else { + session->server_hostkey_sha256_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char *base64Fingerprint = NULL; + _libssh2_base64_encode(session, + (const char *) + session->server_hostkey_sha256, + SHA256_DIGEST_LENGTH, &base64Fingerprint); + if(base64Fingerprint != NULL) { + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA256 Fingerprint: %s", + base64Fingerprint); + LIBSSH2_FREE(session, base64Fingerprint); + } + } +#endif /* LIBSSH2DEBUG */ + + if(session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + /* server public key Q_S */ + server_public_key_len = _libssh2_ntohu32((const unsigned char *)s); + s += 4; + + server_public_key = s; + s += server_public_key_len; + + /* server signature */ + host_sig_len = _libssh2_ntohu32((const unsigned char *)s); + s += 4; + + exchange_state->h_sig = s; + exchange_state->h_sig_len = host_sig_len; + s += host_sig_len; + + /* Compute the shared secret K */ + rc = _libssh2_ecdh_gen_k(&exchange_state->k, private_key, + server_public_key, server_public_key_len); + if(rc != 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, + "Unable to create ECDH shared secret"); + goto clean_exit; + } + + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if(_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if(!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if(_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } + else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + /* verify hash */ + + switch(type) { + case LIBSSH2_EC_CURVE_NISTP256: + LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256); + break; + + case LIBSSH2_EC_CURVE_NISTP384: + LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(384); + break; + case LIBSSH2_EC_CURVE_NISTP521: + LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(512); + break; + } + + if(rc != 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + exchange_state->c = SSH_MSG_NEWKEYS; + exchange_state->state = libssh2_NB_state_sent; + } + + if(exchange_state->state == libssh2_NB_state_sent) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent2; + } + + if(exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + + /* The first key exchange has been performed, + switch to active crypt/comp/mac mode */ + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) + for this packet type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if(!session->session_id) { + + size_t digest_length = 0; + + if(type == LIBSSH2_EC_CURVE_NISTP256) + digest_length = SHA256_DIGEST_LENGTH; + else if(type == LIBSSH2_EC_CURVE_NISTP384) + digest_length = SHA384_DIGEST_LENGTH; + else if(type == LIBSSH2_EC_CURVE_NISTP521) + digest_length = SHA512_DIGEST_LENGTH; + else{ + ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, + "Unknown SHA digest for EC curve"); + goto clean_exit; + + } + session->session_id = LIBSSH2_ALLOC(session, digest_length); + if(!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for " + "SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + digest_length); + session->session_id_len = digest_length; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if(session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if(session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(iv, + session->local.crypt-> + iv_len, "A"); + if(!iv) { + ret = -1; + goto clean_exit; + } + + LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(secret, + session->local.crypt-> + secret_len, "C"); + + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if(session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if(session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(iv, + session->remote.crypt-> + iv_len, "B"); + + if(!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(secret, + session->remote.crypt-> + secret_len, "D"); + + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if(session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if(session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(key, + session->local.mac-> + key_len, "E"); + + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if(session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if(session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(key, + session->remote.mac-> + key_len, "F"); + + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if(session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if(session->local.comp && session->local.comp->init) { + if(session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if(session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if(session->remote.comp && session->remote.comp->init) { + if(session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + + } + +clean_exit: + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + + if(exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + +/* kex_method_ecdh_key_exchange + * + * Elliptic Curve Diffie Hellman Key Exchange + * supports SHA256/384/512 hashes based on negotated ecdh method + * + */ + +static int +kex_method_ecdh_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + int ret = 0; + int rc = 0; + unsigned char *s; + libssh2_curve_type type; + + if(key_state->state == libssh2_NB_state_idle) { + + key_state->public_key_oct = NULL; + key_state->state = libssh2_NB_state_created; + } + + if(key_state->state == libssh2_NB_state_created) { + rc = kex_session_ecdh_curve_type(session->kex->name, &type); + + if(rc != 0) { + ret = _libssh2_error(session, -1, + "Unknown KEX nistp curve type"); + goto ecdh_clean_exit; + } + + rc = _libssh2_ecdsa_create_key(session, &key_state->private_key, + &key_state->public_key_oct, + &key_state->public_key_oct_len, type); + + if(rc != 0) { + ret = _libssh2_error(session, rc, + "Unable to create private key"); + goto ecdh_clean_exit; + } + + key_state->request[0] = SSH2_MSG_KEX_ECDH_INIT; + s = key_state->request + 1; + _libssh2_store_str(&s, (const char *)key_state->public_key_oct, + key_state->public_key_oct_len); + key_state->request_len = key_state->public_key_oct_len + 5; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating ECDH SHA2 NISTP256"); + + key_state->state = libssh2_NB_state_sent; + } + + if(key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send ECDH_INIT"); + goto ecdh_clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if(key_state->state == libssh2_NB_state_sent1) { + rc = _libssh2_packet_require(session, SSH2_MSG_KEX_ECDH_REPLY, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for ECDH_REPLY reply"); + goto ecdh_clean_exit; + } + + key_state->state = libssh2_NB_state_sent2; + } + + if(key_state->state == libssh2_NB_state_sent2) { + + (void)kex_session_ecdh_curve_type(session->kex->name, &type); + + ret = ecdh_sha2_nistp(session, type, key_state->data, + key_state->data_len, + (unsigned char *)key_state->public_key_oct, + key_state->public_key_oct_len, + key_state->private_key, + &key_state->exchange_state); + + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + +ecdh_clean_exit: + + if(key_state->public_key_oct) { + LIBSSH2_FREE(session, key_state->public_key_oct); + key_state->public_key_oct = NULL; + } + + if(key_state->private_key) { + _libssh2_ecdsa_free(key_state->private_key); + key_state->private_key = NULL; + } + + key_state->state = libssh2_NB_state_idle; + + return ret; +} + +#endif /*LIBSSH2_ECDSA*/ + + +#if LIBSSH2_ED25519 + +/* curve25519_sha256 + * Elliptic Curve Key Exchange + */ + +static int +curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data, + size_t data_len, + unsigned char public_key[LIBSSH2_ED25519_KEY_LEN], + unsigned char private_key[LIBSSH2_ED25519_KEY_LEN], + kmdhgGPshakex_state_t *exchange_state) +{ + int ret = 0; + int rc; + int public_key_len = LIBSSH2_ED25519_KEY_LEN; + + if(data_len < 5) { + return _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Data is too short"); + } + + if(exchange_state->state == libssh2_NB_state_idle) { + + /* Setup initial values */ + exchange_state->k = _libssh2_bn_init(); + + exchange_state->state = libssh2_NB_state_created; + } + + if(exchange_state->state == libssh2_NB_state_created) { + /* parse INIT reply data */ + unsigned char *server_public_key, *server_host_key; + size_t server_public_key_len, hostkey_len; + struct string_buf buf; + + if(data_len < 5) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected key length"); + goto clean_exit; + } + + buf.data = data; + buf.len = data_len; + buf.dataptr = buf.data; + buf.dataptr++; /* advance past packet type */ + + if(_libssh2_get_string(&buf, &server_host_key, &hostkey_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected key length"); + goto clean_exit; + } + + session->server_hostkey_len = (uint32_t)hostkey_len; + session->server_hostkey = LIBSSH2_ALLOC(session, + session->server_hostkey_len); + if(!session->server_hostkey) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for a copy " + "of the host key"); + goto clean_exit; + } + + memcpy(session->server_hostkey, server_host_key, + session->server_hostkey_len); + +#if LIBSSH2_MD5 + { + libssh2_md5_ctx fingerprint_ctx; + + if(libssh2_md5_init(&fingerprint_ctx)) { + libssh2_md5_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_md5_final(fingerprint_ctx, + session->server_hostkey_md5); + session->server_hostkey_md5_valid = TRUE; + } + else { + session->server_hostkey_md5_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[50], *fprint = fingerprint; + int i; + for(i = 0; i < 16; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_md5[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's MD5 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ +#endif /* ! LIBSSH2_MD5 */ + + { + libssh2_sha1_ctx fingerprint_ctx; + + if(libssh2_sha1_init(&fingerprint_ctx)) { + libssh2_sha1_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha1_final(fingerprint_ctx, + session->server_hostkey_sha1); + session->server_hostkey_sha1_valid = TRUE; + } + else { + session->server_hostkey_sha1_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char fingerprint[64], *fprint = fingerprint; + int i; + + for(i = 0; i < 20; i++, fprint += 3) { + snprintf(fprint, 4, "%02x:", session->server_hostkey_sha1[i]); + } + *(--fprint) = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA1 Fingerprint: %s", fingerprint); + } +#endif /* LIBSSH2DEBUG */ + + /* SHA256 */ + { + libssh2_sha256_ctx fingerprint_ctx; + + if(libssh2_sha256_init(&fingerprint_ctx)) { + libssh2_sha256_update(fingerprint_ctx, session->server_hostkey, + session->server_hostkey_len); + libssh2_sha256_final(fingerprint_ctx, + session->server_hostkey_sha256); + session->server_hostkey_sha256_valid = TRUE; + } + else { + session->server_hostkey_sha256_valid = FALSE; + } + } +#ifdef LIBSSH2DEBUG + { + char *base64Fingerprint = NULL; + _libssh2_base64_encode(session, + (const char *) + session->server_hostkey_sha256, + SHA256_DIGEST_LENGTH, &base64Fingerprint); + if(base64Fingerprint != NULL) { + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server's SHA256 Fingerprint: %s", + base64Fingerprint); + LIBSSH2_FREE(session, base64Fingerprint); + } + } +#endif /* LIBSSH2DEBUG */ + + if(session->hostkey->init(session, session->server_hostkey, + session->server_hostkey_len, + &session->server_hostkey_abstract)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unable to initialize hostkey importer"); + goto clean_exit; + } + + /* server public key Q_S */ + if(_libssh2_get_string(&buf, &server_public_key, + &server_public_key_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected key length"); + goto clean_exit; + } + + if(server_public_key_len != LIBSSH2_ED25519_KEY_LEN) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unexpected curve25519 server " + "public key length"); + goto clean_exit; + } + + /* server signature */ + if(_libssh2_get_string(&buf, &exchange_state->h_sig, + &(exchange_state->h_sig_len))) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_INIT, + "Unexpected curve25519 server sig length"); + goto clean_exit; + } + + /* Compute the shared secret K */ + rc = _libssh2_curve25519_gen_k(&exchange_state->k, private_key, + server_public_key); + if(rc != 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_KEX_FAILURE, + "Unable to create ECDH shared secret"); + goto clean_exit; + } + + exchange_state->k_value_len = _libssh2_bn_bytes(exchange_state->k) + 5; + if(_libssh2_bn_bits(exchange_state->k) % 8) { + /* don't need leading 00 */ + exchange_state->k_value_len--; + } + exchange_state->k_value = + LIBSSH2_ALLOC(session, exchange_state->k_value_len); + if(!exchange_state->k_value) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate buffer for K"); + goto clean_exit; + } + _libssh2_htonu32(exchange_state->k_value, + exchange_state->k_value_len - 4); + if(_libssh2_bn_bits(exchange_state->k) % 8) { + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 4); + } + else { + exchange_state->k_value[4] = 0; + _libssh2_bn_to_bin(exchange_state->k, exchange_state->k_value + 5); + } + + /*/ verify hash */ + LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256); + + if(rc != 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_HOSTKEY_SIGN, + "Unable to verify hostkey signature"); + goto clean_exit; + } + + exchange_state->c = SSH_MSG_NEWKEYS; + exchange_state->state = libssh2_NB_state_sent; + } + + if(exchange_state->state == libssh2_NB_state_sent) { + rc = _libssh2_transport_send(session, &exchange_state->c, 1, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send NEWKEYS message"); + goto clean_exit; + } + + exchange_state->state = libssh2_NB_state_sent2; + } + + if(exchange_state->state == libssh2_NB_state_sent2) { + rc = _libssh2_packet_require(session, SSH_MSG_NEWKEYS, + &exchange_state->tmp, + &exchange_state->tmp_len, 0, NULL, 0, + &exchange_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, "Timed out waiting for NEWKEYS"); + goto clean_exit; + } + + /* The first key exchange has been performed, switch to active + crypt/comp/mac mode */ + + session->state |= LIBSSH2_STATE_NEWKEYS; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Received NEWKEYS message"); + + /* This will actually end up being just packet_type(1) for this packet + type anyway */ + LIBSSH2_FREE(session, exchange_state->tmp); + + if(!session->session_id) { + + size_t digest_length = SHA256_DIGEST_LENGTH; + session->session_id = LIBSSH2_ALLOC(session, digest_length); + if(!session->session_id) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allxcocate buffer for " + "SHA digest"); + goto clean_exit; + } + memcpy(session->session_id, exchange_state->h_sig_comp, + digest_length); + session->session_id_len = digest_length; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "session_id calculated"); + } + + /* Cleanup any existing cipher */ + if(session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + + /* Calculate IV/Secret/Key for each direction */ + if(session->local.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv, + session->local.crypt-> + iv_len, "A"); + if(!iv) { + ret = -1; + goto clean_exit; + } + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret, + session->local.crypt-> + secret_len, "C"); + + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->local.crypt-> + init(session, session->local.crypt, iv, &free_iv, secret, + &free_secret, 1, &session->local.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->local.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->local.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server IV and Key calculated"); + + if(session->remote.crypt->dtor) { + /* Cleanup any existing cipher */ + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + + if(session->remote.crypt->init) { + unsigned char *iv = NULL, *secret = NULL; + int free_iv = 0, free_secret = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, iv, + session->remote.crypt-> + iv_len, "B"); + + if(!iv) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, secret, + session->remote.crypt-> + secret_len, "D"); + + if(!secret) { + LIBSSH2_FREE(session, iv); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + if(session->remote.crypt-> + init(session, session->remote.crypt, iv, &free_iv, secret, + &free_secret, 0, &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, iv); + LIBSSH2_FREE(session, secret); + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + + if(free_iv) { + _libssh2_explicit_zero(iv, session->remote.crypt->iv_len); + LIBSSH2_FREE(session, iv); + } + + if(free_secret) { + _libssh2_explicit_zero(secret, + session->remote.crypt->secret_len); + LIBSSH2_FREE(session, secret); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client IV and Key calculated"); + + if(session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + if(session->local.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key, + session->local.mac-> + key_len, "E"); + + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->local.mac->init(session, key, &free_key, + &session->local.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->local.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server HMAC Key calculated"); + + if(session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + if(session->remote.mac->init) { + unsigned char *key = NULL; + int free_key = 0; + + LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(256, key, + session->remote.mac-> + key_len, "F"); + + if(!key) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + session->remote.mac->init(session, key, &free_key, + &session->remote.mac_abstract); + + if(free_key) { + _libssh2_explicit_zero(key, session->remote.mac->key_len); + LIBSSH2_FREE(session, key); + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client HMAC Key calculated"); + + /* Initialize compression for each direction */ + + /* Cleanup any existing compression */ + if(session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + + if(session->local.comp && session->local.comp->init) { + if(session->local.comp->init(session, 1, + &session->local.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Client to Server compression initialized"); + + if(session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + + if(session->remote.comp && session->remote.comp->init) { + if(session->remote.comp->init(session, 0, + &session->remote.comp_abstract)) { + ret = LIBSSH2_ERROR_KEX_FAILURE; + goto clean_exit; + } + } + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Server to Client compression initialized"); + } + +clean_exit: + _libssh2_bn_free(exchange_state->k); + exchange_state->k = NULL; + + if(exchange_state->k_value) { + LIBSSH2_FREE(session, exchange_state->k_value); + exchange_state->k_value = NULL; + } + + exchange_state->state = libssh2_NB_state_idle; + + return ret; +} + +/* kex_method_curve25519_key_exchange + * + * Elliptic Curve X25519 Key Exchange with SHA256 hash + * + */ + +static int +kex_method_curve25519_key_exchange +(LIBSSH2_SESSION * session, key_exchange_state_low_t * key_state) +{ + int ret = 0; + int rc = 0; + + if(key_state->state == libssh2_NB_state_idle) { + + key_state->public_key_oct = NULL; + key_state->state = libssh2_NB_state_created; + } + + if(key_state->state == libssh2_NB_state_created) { + unsigned char *s = NULL; + + rc = strcmp(session->kex->name, "curve25519-sha256@libssh.org"); + if(rc != 0) + rc = strcmp(session->kex->name, "curve25519-sha256"); + + if(rc != 0) { + ret = _libssh2_error(session, -1, + "Unknown KEX curve25519 curve type"); + goto clean_exit; + } + + rc = _libssh2_curve25519_new(session, NULL, + &key_state->curve25519_public_key, + &key_state->curve25519_private_key); + + if(rc != 0) { + ret = _libssh2_error(session, rc, + "Unable to create private key"); + goto clean_exit; + } + + key_state->request[0] = SSH2_MSG_KEX_ECDH_INIT; + s = key_state->request + 1; + _libssh2_store_str(&s, (const char *)key_state->curve25519_public_key, + LIBSSH2_ED25519_KEY_LEN); + key_state->request_len = LIBSSH2_ED25519_KEY_LEN + 5; + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, + "Initiating curve25519 SHA2"); + + key_state->state = libssh2_NB_state_sent; + } + + if(key_state->state == libssh2_NB_state_sent) { + rc = _libssh2_transport_send(session, key_state->request, + key_state->request_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Unable to send ECDH_INIT"); + goto clean_exit; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if(key_state->state == libssh2_NB_state_sent1) { + rc = _libssh2_packet_require(session, SSH2_MSG_KEX_ECDH_REPLY, + &key_state->data, &key_state->data_len, + 0, NULL, 0, &key_state->req_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + ret = _libssh2_error(session, rc, + "Timeout waiting for ECDH_REPLY reply"); + goto clean_exit; + } + + key_state->state = libssh2_NB_state_sent2; + } + + if(key_state->state == libssh2_NB_state_sent2) { + + ret = curve25519_sha256(session, key_state->data, key_state->data_len, + key_state->curve25519_public_key, + key_state->curve25519_private_key, + &key_state->exchange_state); + + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + + LIBSSH2_FREE(session, key_state->data); + } + +clean_exit: + + if(key_state->curve25519_public_key) { + _libssh2_explicit_zero(key_state->curve25519_public_key, + LIBSSH2_ED25519_KEY_LEN); + LIBSSH2_FREE(session, key_state->curve25519_public_key); + key_state->curve25519_public_key = NULL; + } + + if(key_state->curve25519_private_key) { + _libssh2_explicit_zero(key_state->curve25519_private_key, + LIBSSH2_ED25519_KEY_LEN); + LIBSSH2_FREE(session, key_state->curve25519_private_key); + key_state->curve25519_private_key = NULL; + } + + key_state->state = libssh2_NB_state_idle; + + return ret; +} + + +#endif /*LIBSSH2_ED25519*/ + + +#define LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY 0x0001 +#define LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY 0x0002 + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group1_sha1 = { + "diffie-hellman-group1-sha1", + kex_method_diffie_hellman_group1_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha1 = { + "diffie-hellman-group14-sha1", + kex_method_diffie_hellman_group14_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD kex_method_diffie_helman_group14_sha256 = { + "diffie-hellman-group14-sha256", + kex_method_diffie_hellman_group14_sha256_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_diffie_helman_group_exchange_sha1 = { + "diffie-hellman-group-exchange-sha1", + kex_method_diffie_hellman_group_exchange_sha1_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_diffie_helman_group_exchange_sha256 = { + "diffie-hellman-group-exchange-sha256", + kex_method_diffie_hellman_group_exchange_sha256_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +#if LIBSSH2_ECDSA +static const LIBSSH2_KEX_METHOD +kex_method_ecdh_sha2_nistp256 = { + "ecdh-sha2-nistp256", + kex_method_ecdh_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_ecdh_sha2_nistp384 = { + "ecdh-sha2-nistp384", + kex_method_ecdh_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; + +static const LIBSSH2_KEX_METHOD +kex_method_ecdh_sha2_nistp521 = { + "ecdh-sha2-nistp521", + kex_method_ecdh_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; +#endif + +#if LIBSSH2_ED25519 +static const LIBSSH2_KEX_METHOD +kex_method_ssh_curve25519_sha256_libssh = { + "curve25519-sha256@libssh.org", + kex_method_curve25519_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; +static const LIBSSH2_KEX_METHOD +kex_method_ssh_curve25519_sha256 = { + "curve25519-sha256", + kex_method_curve25519_key_exchange, + LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY, +}; +#endif + +static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = { +#if LIBSSH2_ECDSA + &kex_method_ecdh_sha2_nistp256, + &kex_method_ecdh_sha2_nistp384, + &kex_method_ecdh_sha2_nistp521, +#endif +#if LIBSSH2_ED25519 + &kex_method_ssh_curve25519_sha256, + &kex_method_ssh_curve25519_sha256_libssh, +#endif + &kex_method_diffie_helman_group14_sha256, + &kex_method_diffie_helman_group_exchange_sha256, + &kex_method_diffie_helman_group_exchange_sha1, + &kex_method_diffie_helman_group14_sha1, + &kex_method_diffie_helman_group1_sha1, + NULL +}; + +typedef struct _LIBSSH2_COMMON_METHOD +{ + const char *name; +} LIBSSH2_COMMON_METHOD; + +/* kex_method_strlen + * Calculate the length of a particular method list's resulting string + * Includes SUM(strlen() of each individual method plus 1 (for coma)) - 1 + * (because the last coma isn't used) + * Another sign of bad coding practices gone mad. Pretend you don't see this. + */ +static size_t +kex_method_strlen(LIBSSH2_COMMON_METHOD ** method) +{ + size_t len = 0; + + if(!method || !*method) { + return 0; + } + + while(*method && (*method)->name) { + len += strlen((*method)->name) + 1; + method++; + } + + return len - 1; +} + + + +/* kex_method_list + * Generate formatted preference list in buf + */ +static size_t +kex_method_list(unsigned char *buf, size_t list_strlen, + LIBSSH2_COMMON_METHOD ** method) +{ + _libssh2_htonu32(buf, list_strlen); + buf += 4; + + if(!method || !*method) { + return 4; + } + + while(*method && (*method)->name) { + int mlen = strlen((*method)->name); + memcpy(buf, (*method)->name, mlen); + buf += mlen; + *(buf++) = ','; + method++; + } + + return list_strlen + 4; +} + + + +#define LIBSSH2_METHOD_PREFS_LEN(prefvar, defaultvar) \ + ((prefvar) ? strlen(prefvar) : \ + kex_method_strlen((LIBSSH2_COMMON_METHOD**)(defaultvar))) + +#define LIBSSH2_METHOD_PREFS_STR(buf, prefvarlen, prefvar, defaultvar) \ + if(prefvar) { \ + _libssh2_htonu32((buf), (prefvarlen)); \ + buf += 4; \ + memcpy((buf), (prefvar), (prefvarlen)); \ + buf += (prefvarlen); \ + } \ + else { \ + buf += kex_method_list((buf), (prefvarlen), \ + (LIBSSH2_COMMON_METHOD**)(defaultvar)); \ + } + +/* kexinit + * Send SSH_MSG_KEXINIT packet + */ +static int kexinit(LIBSSH2_SESSION * session) +{ + /* 62 = packet_type(1) + cookie(16) + first_packet_follows(1) + + reserved(4) + length longs(40) */ + size_t data_len = 62; + size_t kex_len, hostkey_len = 0; + size_t crypt_cs_len, crypt_sc_len; + size_t comp_cs_len, comp_sc_len; + size_t mac_cs_len, mac_sc_len; + size_t lang_cs_len, lang_sc_len; + unsigned char *data, *s; + int rc; + + if(session->kexinit_state == libssh2_NB_state_idle) { + kex_len = + LIBSSH2_METHOD_PREFS_LEN(session->kex_prefs, libssh2_kex_methods); + hostkey_len = + LIBSSH2_METHOD_PREFS_LEN(session->hostkey_prefs, + libssh2_hostkey_methods()); + crypt_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.crypt_prefs, + libssh2_crypt_methods()); + crypt_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.crypt_prefs, + libssh2_crypt_methods()); + mac_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.mac_prefs, + _libssh2_mac_methods()); + mac_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.mac_prefs, + _libssh2_mac_methods()); + comp_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.comp_prefs, + _libssh2_comp_methods(session)); + comp_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.comp_prefs, + _libssh2_comp_methods(session)); + lang_cs_len = + LIBSSH2_METHOD_PREFS_LEN(session->local.lang_prefs, NULL); + lang_sc_len = + LIBSSH2_METHOD_PREFS_LEN(session->remote.lang_prefs, NULL); + + data_len += kex_len + hostkey_len + crypt_cs_len + crypt_sc_len + + comp_cs_len + comp_sc_len + mac_cs_len + mac_sc_len + + lang_cs_len + lang_sc_len; + + s = data = LIBSSH2_ALLOC(session, data_len); + if(!data) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory"); + } + + *(s++) = SSH_MSG_KEXINIT; + + _libssh2_random(s, 16); + s += 16; + + /* Ennumerating through these lists twice is probably (certainly?) + inefficient from a CPU standpoint, but it saves multiple + malloc/realloc calls */ + LIBSSH2_METHOD_PREFS_STR(s, kex_len, session->kex_prefs, + libssh2_kex_methods); + LIBSSH2_METHOD_PREFS_STR(s, hostkey_len, session->hostkey_prefs, + libssh2_hostkey_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_cs_len, session->local.crypt_prefs, + libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, crypt_sc_len, session->remote.crypt_prefs, + libssh2_crypt_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_cs_len, session->local.mac_prefs, + _libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, mac_sc_len, session->remote.mac_prefs, + _libssh2_mac_methods()); + LIBSSH2_METHOD_PREFS_STR(s, comp_cs_len, session->local.comp_prefs, + _libssh2_comp_methods(session)); + LIBSSH2_METHOD_PREFS_STR(s, comp_sc_len, session->remote.comp_prefs, + _libssh2_comp_methods(session)); + LIBSSH2_METHOD_PREFS_STR(s, lang_cs_len, session->local.lang_prefs, + NULL); + LIBSSH2_METHOD_PREFS_STR(s, lang_sc_len, session->remote.lang_prefs, + NULL); + + /* No optimistic KEX packet follows */ + /* Deal with optimistic packets + * session->flags |= KEXINIT_OPTIMISTIC + * session->flags |= KEXINIT_METHODSMATCH + */ + *(s++) = 0; + + /* Reserved == 0 */ + _libssh2_htonu32(s, 0); + +#ifdef LIBSSH2DEBUG + { + /* Funnily enough, they'll all "appear" to be '\0' terminated */ + unsigned char *p = data + 21; /* type(1) + cookie(16) + len(4) */ + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent KEX: %s", p); + p += kex_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent HOSTKEY: %s", p); + p += hostkey_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_CS: %s", p); + p += crypt_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent CRYPT_SC: %s", p); + p += crypt_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_CS: %s", p); + p += mac_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent MAC_SC: %s", p); + p += mac_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_CS: %s", p); + p += comp_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent COMP_SC: %s", p); + p += comp_sc_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_CS: %s", p); + p += lang_cs_len + 4; + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Sent LANG_SC: %s", p); + p += lang_sc_len + 4; + } +#endif /* LIBSSH2DEBUG */ + + session->kexinit_state = libssh2_NB_state_created; + } + else { + data = session->kexinit_data; + data_len = session->kexinit_data_len; + /* zap the variables to ensure there is NOT a double free later */ + session->kexinit_data = NULL; + session->kexinit_data_len = 0; + } + + rc = _libssh2_transport_send(session, data, data_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + session->kexinit_data = data; + session->kexinit_data_len = data_len; + return rc; + } + else if(rc) { + LIBSSH2_FREE(session, data); + session->kexinit_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send KEXINIT packet to remote host"); + + } + + if(session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + + session->local.kexinit = data; + session->local.kexinit_len = data_len; + + session->kexinit_state = libssh2_NB_state_idle; + + return 0; +} + +/* kex_agree_instr + * Kex specific variant of strstr() + * Needle must be precede by BOL or ',', and followed by ',' or EOL + */ +static unsigned char * +kex_agree_instr(unsigned char *haystack, unsigned long haystack_len, + const unsigned char *needle, unsigned long needle_len) +{ + unsigned char *s; + + /* Haystack too short to bother trying */ + if(haystack_len < needle_len) { + return NULL; + } + + /* Needle at start of haystack */ + if((strncmp((char *) haystack, (char *) needle, needle_len) == 0) && + (needle_len == haystack_len || haystack[needle_len] == ',')) { + return haystack; + } + + s = haystack; + /* Search until we run out of comas or we run out of haystack, + whichever comes first */ + while((s = (unsigned char *) strchr((char *) s, ',')) + && ((haystack_len - (s - haystack)) > needle_len)) { + s++; + /* Needle at X position */ + if((strncmp((char *) s, (char *) needle, needle_len) == 0) && + (((s - haystack) + needle_len) == haystack_len + || s[needle_len] == ',')) { + return s; + } + } + + return NULL; +} + + + +/* kex_get_method_by_name + */ +static const LIBSSH2_COMMON_METHOD * +kex_get_method_by_name(const char *name, size_t name_len, + const LIBSSH2_COMMON_METHOD ** methodlist) +{ + while(*methodlist) { + if((strlen((*methodlist)->name) == name_len) && + (strncmp((*methodlist)->name, name, name_len) == 0)) { + return *methodlist; + } + methodlist++; + } + return NULL; +} + + + +/* kex_agree_hostkey + * Agree on a Hostkey which works with this kex + */ +static int kex_agree_hostkey(LIBSSH2_SESSION * session, + unsigned long kex_flags, + unsigned char *hostkey, unsigned long hostkey_len) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkeyp = libssh2_hostkey_methods(); + unsigned char *s; + + if(session->hostkey_prefs) { + s = (unsigned char *) session->hostkey_prefs; + + while(s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) { + const LIBSSH2_HOSTKEY_METHOD *method = + (const LIBSSH2_HOSTKEY_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + hostkeyp); + + if(!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + /* So far so good, but does it suit our purposes? (Encrypting + vs Signing) */ + if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == + 0) || (method->encrypt)) { + /* Either this hostkey can do encryption or this kex just + doesn't require it */ + if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) + == 0) || (method->sig_verify)) { + /* Either this hostkey can do signing or this kex just + doesn't require it */ + session->hostkey = method; + return 0; + } + } + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) { + s = kex_agree_instr(hostkey, hostkey_len, + (unsigned char *) (*hostkeyp)->name, + strlen((*hostkeyp)->name)); + if(s) { + /* So far so good, but does it suit our purposes? (Encrypting vs + Signing) */ + if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_ENC_HOSTKEY) == 0) || + ((*hostkeyp)->encrypt)) { + /* Either this hostkey can do encryption or this kex just + doesn't require it */ + if(((kex_flags & LIBSSH2_KEX_METHOD_FLAG_REQ_SIGN_HOSTKEY) == + 0) || ((*hostkeyp)->sig_verify)) { + /* Either this hostkey can do signing or this kex just + doesn't require it */ + session->hostkey = *hostkeyp; + return 0; + } + } + } + hostkeyp++; + } + + return -1; +} + + + +/* kex_agree_kex_hostkey + * Agree on a Key Exchange method and a hostkey encoding type + */ +static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex, + unsigned long kex_len, unsigned char *hostkey, + unsigned long hostkey_len) +{ + const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods; + unsigned char *s; + + if(session->kex_prefs) { + s = (unsigned char *) session->kex_prefs; + + while(s && *s) { + unsigned char *q, *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + q = kex_agree_instr(kex, kex_len, s, method_len); + if(q) { + const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + kexp); + + if(!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if(kex_agree_hostkey(session, method->flags, hostkey, + hostkey_len) == 0) { + session->kex = method; + if(session->burn_optimistic_kexinit && (kex == q)) { + /* Server sent an optimistic packet, and client agrees + * with preference cancel burning the first KEX_INIT + * packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while(*kexp && (*kexp)->name) { + s = kex_agree_instr(kex, kex_len, + (unsigned char *) (*kexp)->name, + strlen((*kexp)->name)); + if(s) { + /* We've agreed on a key exchange method, + * Can we agree on a hostkey that works with this kex? + */ + if(kex_agree_hostkey(session, (*kexp)->flags, hostkey, + hostkey_len) == 0) { + session->kex = *kexp; + if(session->burn_optimistic_kexinit && (kex == s)) { + /* Server sent an optimistic packet, and client agrees + * with preference cancel burning the first KEX_INIT + * packet that comes in */ + session->burn_optimistic_kexinit = 0; + } + return 0; + } + } + kexp++; + } + return -1; +} + + + +/* kex_agree_crypt + * Agree on a cipher algo + */ +static int kex_agree_crypt(LIBSSH2_SESSION * session, + libssh2_endpoint_data *endpoint, + unsigned char *crypt, + unsigned long crypt_len) +{ + const LIBSSH2_CRYPT_METHOD **cryptp = libssh2_crypt_methods(); + unsigned char *s; + + (void) session; + + if(endpoint->crypt_prefs) { + s = (unsigned char *) endpoint->crypt_prefs; + + while(s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if(kex_agree_instr(crypt, crypt_len, s, method_len)) { + const LIBSSH2_CRYPT_METHOD *method = + (const LIBSSH2_CRYPT_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + cryptp); + + if(!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->crypt = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while(*cryptp && (*cryptp)->name) { + s = kex_agree_instr(crypt, crypt_len, + (unsigned char *) (*cryptp)->name, + strlen((*cryptp)->name)); + if(s) { + endpoint->crypt = *cryptp; + return 0; + } + cryptp++; + } + + return -1; +} + + + +/* kex_agree_mac + * Agree on a message authentication hash + */ +static int kex_agree_mac(LIBSSH2_SESSION * session, + libssh2_endpoint_data * endpoint, unsigned char *mac, + unsigned long mac_len) +{ + const LIBSSH2_MAC_METHOD **macp = _libssh2_mac_methods(); + unsigned char *s; + (void) session; + + if(endpoint->mac_prefs) { + s = (unsigned char *) endpoint->mac_prefs; + + while(s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if(kex_agree_instr(mac, mac_len, s, method_len)) { + const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + macp); + + if(!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->mac = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while(*macp && (*macp)->name) { + s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name, + strlen((*macp)->name)); + if(s) { + endpoint->mac = *macp; + return 0; + } + macp++; + } + + return -1; +} + + + +/* kex_agree_comp + * Agree on a compression scheme + */ +static int kex_agree_comp(LIBSSH2_SESSION *session, + libssh2_endpoint_data *endpoint, unsigned char *comp, + unsigned long comp_len) +{ + const LIBSSH2_COMP_METHOD **compp = _libssh2_comp_methods(session); + unsigned char *s; + (void) session; + + if(endpoint->comp_prefs) { + s = (unsigned char *) endpoint->comp_prefs; + + while(s && *s) { + unsigned char *p = (unsigned char *) strchr((char *) s, ','); + size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s)); + + if(kex_agree_instr(comp, comp_len, s, method_len)) { + const LIBSSH2_COMP_METHOD *method = + (const LIBSSH2_COMP_METHOD *) + kex_get_method_by_name((char *) s, method_len, + (const LIBSSH2_COMMON_METHOD **) + compp); + + if(!method) { + /* Invalid method -- Should never be reached */ + return -1; + } + + endpoint->comp = method; + return 0; + } + + s = p ? p + 1 : NULL; + } + return -1; + } + + while(*compp && (*compp)->name) { + s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name, + strlen((*compp)->name)); + if(s) { + endpoint->comp = *compp; + return 0; + } + compp++; + } + + return -1; +} + + +/* TODO: When in server mode we need to turn this logic on its head + * The Client gets to make the final call on "agreed methods" + */ + +/* kex_agree_methods + * Decide which specific method to use of the methods offered by each party + */ +static int kex_agree_methods(LIBSSH2_SESSION * session, unsigned char *data, + unsigned data_len) +{ + unsigned char *kex, *hostkey, *crypt_cs, *crypt_sc, *comp_cs, *comp_sc, + *mac_cs, *mac_sc; + size_t kex_len, hostkey_len, crypt_cs_len, crypt_sc_len, comp_cs_len; + size_t comp_sc_len, mac_cs_len, mac_sc_len; + struct string_buf buf; + + if(data_len < 17) + return -1; + + buf.data = (unsigned char *)data; + buf.len = data_len; + buf.dataptr = buf.data; + buf.dataptr++; /* advance past packet type */ + + /* Skip cookie, don't worry, it's preserved in the kexinit field */ + buf.dataptr += 16; + + /* Locate each string */ + if(_libssh2_get_string(&buf, &kex, &kex_len)) + return -1; + if(_libssh2_get_string(&buf, &hostkey, &hostkey_len)) + return -1; + if(_libssh2_get_string(&buf, &crypt_cs, &crypt_cs_len)) + return -1; + if(_libssh2_get_string(&buf, &crypt_sc, &crypt_sc_len)) + return -1; + if(_libssh2_get_string(&buf, &mac_cs, &mac_cs_len)) + return -1; + if(_libssh2_get_string(&buf, &mac_sc, &mac_sc_len)) + return -1; + if(_libssh2_get_string(&buf, &comp_cs, &comp_cs_len)) + return -1; + if(_libssh2_get_string(&buf, &comp_sc, &comp_sc_len)) + return -1; + + /* If the server sent an optimistic packet, assume that it guessed wrong. + * If the guess is determined to be right (by kex_agree_kex_hostkey) + * This flag will be reset to zero so that it's not ignored */ + if(_libssh2_check_length(&buf, 1)) { + session->burn_optimistic_kexinit = *(buf.dataptr++); + } + else { + return -1; + } + + /* Next uint32 in packet is all zeros (reserved) */ + + if(kex_agree_kex_hostkey(session, kex, kex_len, hostkey, hostkey_len)) { + return -1; + } + + if(kex_agree_crypt(session, &session->local, crypt_cs, crypt_cs_len) + || kex_agree_crypt(session, &session->remote, crypt_sc, + crypt_sc_len)) { + return -1; + } + + if(kex_agree_mac(session, &session->local, mac_cs, mac_cs_len) || + kex_agree_mac(session, &session->remote, mac_sc, mac_sc_len)) { + return -1; + } + + if(kex_agree_comp(session, &session->local, comp_cs, comp_cs_len) || + kex_agree_comp(session, &session->remote, comp_sc, comp_sc_len)) { + return -1; + } + +#if 0 + if(libssh2_kex_agree_lang(session, &session->local, lang_cs, lang_cs_len) + || libssh2_kex_agree_lang(session, &session->remote, lang_sc, + lang_sc_len)) { + return -1; + } +#endif + + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on KEX method: %s", + session->kex->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on HOSTKEY method: %s", + session->hostkey->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_CS method: %s", + session->local.crypt->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on CRYPT_SC method: %s", + session->remote.crypt->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_CS method: %s", + session->local.mac->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on MAC_SC method: %s", + session->remote.mac->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_CS method: %s", + session->local.comp->name); + _libssh2_debug(session, LIBSSH2_TRACE_KEX, "Agreed on COMP_SC method: %s", + session->remote.comp->name); + + return 0; +} + + + +/* _libssh2_kex_exchange + * Exchange keys + * Returns 0 on success, non-zero on failure + * + * Returns some errors without _libssh2_error() + */ +int +_libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange, + key_exchange_state_t * key_state) +{ + int rc = 0; + int retcode; + + session->state |= LIBSSH2_STATE_KEX_ACTIVE; + + if(key_state->state == libssh2_NB_state_idle) { + /* Prevent loop in packet_add() */ + session->state |= LIBSSH2_STATE_EXCHANGING_KEYS; + + if(reexchange) { + session->kex = NULL; + + if(session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, + &session->server_hostkey_abstract); + } + session->hostkey = NULL; + } + + key_state->state = libssh2_NB_state_created; + } + + if(!session->kex || !session->hostkey) { + if(key_state->state == libssh2_NB_state_created) { + /* Preserve in case of failure */ + key_state->oldlocal = session->local.kexinit; + key_state->oldlocal_len = session->local.kexinit_len; + + session->local.kexinit = NULL; + + key_state->state = libssh2_NB_state_sent; + } + + if(key_state->state == libssh2_NB_state_sent) { + retcode = kexinit(session); + if(retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } + else if(retcode) { + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; + } + + key_state->state = libssh2_NB_state_sent1; + } + + if(key_state->state == libssh2_NB_state_sent1) { + retcode = + _libssh2_packet_require(session, SSH_MSG_KEXINIT, + &key_state->data, + &key_state->data_len, 0, NULL, 0, + &key_state->req_state); + if(retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } + else if(retcode) { + if(session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + session->local.kexinit = key_state->oldlocal; + session->local.kexinit_len = key_state->oldlocal_len; + key_state->state = libssh2_NB_state_idle; + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + return -1; + } + + if(session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + session->remote.kexinit = key_state->data; + session->remote.kexinit_len = key_state->data_len; + + if(kex_agree_methods(session, key_state->data, + key_state->data_len)) + rc = LIBSSH2_ERROR_KEX_FAILURE; + + key_state->state = libssh2_NB_state_sent2; + } + } + else { + key_state->state = libssh2_NB_state_sent2; + } + + if(rc == 0 && session->kex) { + if(key_state->state == libssh2_NB_state_sent2) { + retcode = session->kex->exchange_keys(session, + &key_state->key_state_low); + if(retcode == LIBSSH2_ERROR_EAGAIN) { + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + return retcode; + } + else if(retcode) { + rc = _libssh2_error(session, + LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE, + "Unrecoverable error exchanging keys"); + } + } + } + + /* Done with kexinit buffers */ + if(session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + session->local.kexinit = NULL; + } + if(session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + session->remote.kexinit = NULL; + } + + session->state &= ~LIBSSH2_STATE_KEX_ACTIVE; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + + key_state->state = libssh2_NB_state_idle; + + return rc; +} + + + +/* libssh2_session_method_pref + * Set preferred method + */ +LIBSSH2_API int +libssh2_session_method_pref(LIBSSH2_SESSION * session, int method_type, + const char *prefs) +{ + char **prefvar, *s, *newprefs; + int prefs_len = strlen(prefs); + const LIBSSH2_COMMON_METHOD **mlist; + + switch(method_type) { + case LIBSSH2_METHOD_KEX: + prefvar = &session->kex_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods; + break; + + case LIBSSH2_METHOD_HOSTKEY: + prefvar = &session->hostkey_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_CS: + prefvar = &session->local.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_SC: + prefvar = &session->remote.crypt_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_MAC_CS: + prefvar = &session->local.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_MAC_SC: + prefvar = &session->remote.mac_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_COMP_CS: + prefvar = &session->local.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + case LIBSSH2_METHOD_COMP_SC: + prefvar = &session->remote.comp_prefs; + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + case LIBSSH2_METHOD_LANG_CS: + prefvar = &session->local.lang_prefs; + mlist = NULL; + break; + + case LIBSSH2_METHOD_LANG_SC: + prefvar = &session->remote.lang_prefs; + mlist = NULL; + break; + + default: + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "Invalid parameter specified for method_type"); + } + + s = newprefs = LIBSSH2_ALLOC(session, prefs_len + 1); + if(!newprefs) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocated space for method preferences"); + } + memcpy(s, prefs, prefs_len + 1); + + while(s && *s && mlist) { + char *p = strchr(s, ','); + int method_len = p ? (p - s) : (int) strlen(s); + + if(!kex_get_method_by_name(s, method_len, mlist)) { + /* Strip out unsupported method */ + if(p) { + memcpy(s, p + 1, strlen(s) - method_len); + } + else { + if(s > newprefs) { + *(--s) = '\0'; + } + else { + *s = '\0'; + } + } + } + else { + s = p ? (p + 1) : NULL; + } + } + + if(!*newprefs) { + LIBSSH2_FREE(session, newprefs); + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "The requested method(s) are not currently " + "supported"); + } + + if(*prefvar) { + LIBSSH2_FREE(session, *prefvar); + } + *prefvar = newprefs; + + return 0; +} + +/* + * libssh2_session_supported_algs() + * returns a number of returned algorithms (a positive number) on success, + * a negative number on failure + */ + +LIBSSH2_API int libssh2_session_supported_algs(LIBSSH2_SESSION* session, + int method_type, + const char ***algs) +{ + unsigned int i; + unsigned int j; + unsigned int ialg; + const LIBSSH2_COMMON_METHOD **mlist; + + /* to prevent coredumps due to dereferencing of NULL */ + if(NULL == algs) + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "algs must not be NULL"); + + switch(method_type) { + case LIBSSH2_METHOD_KEX: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_kex_methods; + break; + + case LIBSSH2_METHOD_HOSTKEY: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_hostkey_methods(); + break; + + case LIBSSH2_METHOD_CRYPT_CS: + case LIBSSH2_METHOD_CRYPT_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) libssh2_crypt_methods(); + break; + + case LIBSSH2_METHOD_MAC_CS: + case LIBSSH2_METHOD_MAC_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) _libssh2_mac_methods(); + break; + + case LIBSSH2_METHOD_COMP_CS: + case LIBSSH2_METHOD_COMP_SC: + mlist = (const LIBSSH2_COMMON_METHOD **) + _libssh2_comp_methods(session); + break; + + default: + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unknown method type"); + } /* switch */ + + /* weird situation */ + if(NULL == mlist) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "No algorithm found"); + + /* + mlist is looped through twice. The first time to find the number od + supported algorithms (needed to allocate the proper size of array) and + the second time to actually copy the pointers. Typically this function + will not be called often (typically at the beginning of a session) and + the number of algorithms (i.e. niumber of iterations in one loop) will + not be high (typically it will not exceed 20) for quite a long time. + + So double looping really shouldn't be an issue and it is definitely a + better solution than reallocation several times. + */ + + /* count the number of supported algorithms */ + for(i = 0, ialg = 0; NULL != mlist[i]; i++) { + /* do not count fields with NULL name */ + if(mlist[i]->name) + ialg++; + } + + /* weird situation, no algorithm found */ + if(0 == ialg) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "No algorithm found"); + + /* allocate buffer */ + *algs = (const char **) LIBSSH2_ALLOC(session, ialg*sizeof(const char *)); + if(NULL == *algs) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Memory allocation failed"); + } + /* Past this point *algs must be deallocated in case of an error!! */ + + /* copy non-NULL pointers only */ + for(i = 0, j = 0; NULL != mlist[i] && j < ialg; i++) { + if(NULL == mlist[i]->name) { + /* maybe a weird situation but if it occurs, do not include NULL + pointers */ + continue; + } + + /* note that [] has higher priority than * (dereferencing) */ + (*algs)[j++] = mlist[i]->name; + } + + /* correct number of pointers copied? (test the code above) */ + if(j != ialg) { + /* deallocate buffer */ + LIBSSH2_FREE(session, (void *)*algs); + *algs = NULL; + + return _libssh2_error(session, LIBSSH2_ERROR_BAD_USE, + "Internal error"); + } + + return ialg; +} diff --git a/libssh2/knownhost.c b/libssh2/knownhost.c new file mode 100644 index 0000000..77798fb --- /dev/null +++ b/libssh2/knownhost.c @@ -0,0 +1,1271 @@ +/* + * Copyright (c) 2009-2019 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" + +struct known_host { + struct list_node node; + char *name; /* points to the name or the hash (allocated) */ + size_t name_len; /* needed for hashed data */ + int port; /* if non-zero, a specific port this key is for on this + host */ + int typemask; /* plain, sha1, custom, ... */ + char *salt; /* points to binary salt (allocated) */ + size_t salt_len; /* size of salt */ + char *key; /* the (allocated) associated key. This is kept base64 + encoded in memory. */ + char *key_type_name; /* the (allocated) key type name */ + size_t key_type_len; /* size of key_type_name */ + char *comment; /* the (allocated) optional comment text, may be + NULL */ + size_t comment_len; /* the size of comment */ + + /* this is the struct we expose externally */ + struct libssh2_knownhost external; +}; + +struct _LIBSSH2_KNOWNHOSTS +{ + LIBSSH2_SESSION *session; /* the session this "belongs to" */ + struct list_head head; +}; + +static void free_host(LIBSSH2_SESSION *session, struct known_host *entry) +{ + if(entry) { + if(entry->comment) + LIBSSH2_FREE(session, entry->comment); + if(entry->key_type_name) + LIBSSH2_FREE(session, entry->key_type_name); + if(entry->key) + LIBSSH2_FREE(session, entry->key); + if(entry->salt) + LIBSSH2_FREE(session, entry->salt); + if(entry->name) + LIBSSH2_FREE(session, entry->name); + LIBSSH2_FREE(session, entry); + } +} + +/* + * libssh2_knownhost_init + * + * Init a collection of known hosts. Returns the pointer to a collection. + * + */ +LIBSSH2_API LIBSSH2_KNOWNHOSTS * +libssh2_knownhost_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_KNOWNHOSTS *knh = + LIBSSH2_ALLOC(session, sizeof(struct _LIBSSH2_KNOWNHOSTS)); + + if(!knh) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for known-hosts " + "collection"); + return NULL; + } + + knh->session = session; + + _libssh2_list_init(&knh->head); + + return knh; +} + +#define KNOWNHOST_MAGIC 0xdeadcafe +/* + * knownhost_to_external() + * + * Copies data from the internal to the external representation struct. + * + */ +static struct libssh2_knownhost *knownhost_to_external(struct known_host *node) +{ + struct libssh2_knownhost *ext = &node->external; + + ext->magic = KNOWNHOST_MAGIC; + ext->node = node; + ext->name = ((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == + LIBSSH2_KNOWNHOST_TYPE_PLAIN)? node->name:NULL; + ext->key = node->key; + ext->typemask = node->typemask; + + return ext; +} + +static int +knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, + const char *comment, size_t commentlen, + int typemask, struct libssh2_knownhost **store) +{ + struct known_host *entry; + size_t hostlen = strlen(host); + int rc; + char *ptr; + unsigned int ptrlen; + + /* make sure we have a key type set */ + if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK)) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "No key type set"); + + entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host)); + if(!entry) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for known host " + "entry"); + + entry->typemask = typemask; + + switch(entry->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { + case LIBSSH2_KNOWNHOST_TYPE_PLAIN: + case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: + entry->name = LIBSSH2_ALLOC(hosts->session, hostlen + 1); + if(!entry->name) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for host name"); + goto error; + } + memcpy(entry->name, host, hostlen + 1); + entry->name_len = hostlen; + break; + case LIBSSH2_KNOWNHOST_TYPE_SHA1: + rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen, + host, hostlen); + if(rc) + goto error; + entry->name = ptr; + entry->name_len = ptrlen; + + rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen, + salt, strlen(salt)); + if(rc) + goto error; + entry->salt = ptr; + entry->salt_len = ptrlen; + break; + default: + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unknown host name type"); + goto error; + } + + if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) { + /* the provided key is base64 encoded already */ + if(!keylen) + keylen = strlen(key); + entry->key = LIBSSH2_ALLOC(hosts->session, keylen + 1); + if(!entry->key) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for key"); + goto error; + } + memcpy(entry->key, key, keylen + 1); + entry->key[keylen] = 0; /* force a terminating zero trailer */ + } + else { + /* key is raw, we base64 encode it and store it as such */ + size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, + &ptr); + if(!nlen) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded key"); + goto error; + } + + entry->key = ptr; + } + + if(key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) == + LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) { + entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len + 1); + if(!entry->key_type_name) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for key type"); + goto error; + } + memcpy(entry->key_type_name, key_type_name, key_type_len); + entry->key_type_name[key_type_len] = 0; + entry->key_type_len = key_type_len; + } + + if(comment) { + entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen + 1); + if(!entry->comment) { + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for comment"); + goto error; + } + memcpy(entry->comment, comment, commentlen + 1); + entry->comment[commentlen] = 0; /* force a terminating zero trailer */ + entry->comment_len = commentlen; + } + else { + entry->comment = NULL; + } + + /* add this new host to the big list of known hosts */ + _libssh2_list_add(&hosts->head, &entry->node); + + if(store) + *store = knownhost_to_external(entry); + + return LIBSSH2_ERROR_NONE; + error: + free_host(hosts->session, entry); + return rc; +} + +/* + * libssh2_knownhost_add + * + * Add a host and its associated key to the collection of known hosts. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key, size_t keylen, + int typemask, struct libssh2_knownhost **store) +{ + return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, NULL, + 0, typemask, store); +} + + +/* + * libssh2_knownhost_addc + * + * Add a host and its associated key to the collection of known hosts. + * + * Takes a comment argument that may be NULL. A NULL comment indicates + * there is no comment and the entry will end directly after the key + * when written out to a file. An empty string "" comment will indicate an + * empty comment which will cause a single space to be written after the key. + * + * The 'type' argument specifies on what format the given host and keys are: + * + * plain - ascii "hostname.domain.tld" + * sha1 - SHA1( ) base64-encoded! + * custom - another hash + * + * If 'sha1' is selected as type, the salt must be provided to the salt + * argument. This too base64 encoded. + * + * The SHA-1 hash is what OpenSSH can be told to use in known_hosts files. If + * a custom type is used, salt is ignored and you must provide the host + * pre-hashed when checking for it in the libssh2_knownhost_check() function. + * + * The keylen parameter may be omitted (zero) if the key is provided as a + * NULL-terminated base64-encoded string. + */ + +LIBSSH2_API int +libssh2_knownhost_addc(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, const char *salt, + const char *key, size_t keylen, + const char *comment, size_t commentlen, + int typemask, struct libssh2_knownhost **store) +{ + return knownhost_add(hosts, host, salt, NULL, 0, key, keylen, + comment, commentlen, typemask, store); +} + +/* + * knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +static int +knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + struct known_host *node; + struct known_host *badkey = NULL; + int type = typemask & LIBSSH2_KNOWNHOST_TYPE_MASK; + char *keyalloc = NULL; + int rc = LIBSSH2_KNOWNHOST_CHECK_NOTFOUND; + char hostbuff[270]; /* most host names can't be longer than like 256 */ + const char *host; + int numcheck; /* number of host combos to check */ + int match = 0; + + if(type == LIBSSH2_KNOWNHOST_TYPE_SHA1) + /* we can't work with a sha1 as given input */ + return LIBSSH2_KNOWNHOST_CHECK_MISMATCH; + + /* if a port number is given, check for a '[host]:port' first before the + plain 'host' */ + if(port >= 0) { + int len = snprintf(hostbuff, sizeof(hostbuff), "[%s]:%d", hostp, port); + if(len < 0 || len >= (int)sizeof(hostbuff)) { + _libssh2_error(hosts->session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Known-host write buffer too small"); + return LIBSSH2_KNOWNHOST_CHECK_FAILURE; + } + host = hostbuff; + numcheck = 2; /* check both combos, start with this */ + } + else { + host = hostp; + numcheck = 1; /* only check this host version */ + } + + if(!(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64)) { + /* we got a raw key input, convert it to base64 for the checks below */ + size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen, + &keyalloc); + if(!nlen) { + _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for base64-encoded " + "key"); + return LIBSSH2_KNOWNHOST_CHECK_FAILURE; + } + + /* make the key point to this */ + key = keyalloc; + } + + do { + node = _libssh2_list_first(&hosts->head); + while(node) { + switch(node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) { + case LIBSSH2_KNOWNHOST_TYPE_PLAIN: + if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) + match = !strcmp(host, node->name); + break; + case LIBSSH2_KNOWNHOST_TYPE_CUSTOM: + if(type == LIBSSH2_KNOWNHOST_TYPE_CUSTOM) + match = !strcmp(host, node->name); + break; + case LIBSSH2_KNOWNHOST_TYPE_SHA1: + if(type == LIBSSH2_KNOWNHOST_TYPE_PLAIN) { + /* when we have the sha1 version stored, we can use a + plain input to produce a hash to compare with the + stored hash. + */ + unsigned char hash[SHA_DIGEST_LENGTH]; + libssh2_hmac_ctx ctx; + libssh2_hmac_ctx_init(ctx); + + if(SHA_DIGEST_LENGTH != node->name_len) { + /* the name hash length must be the sha1 size or + we can't match it */ + break; + } + libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt, + node->salt_len); + libssh2_hmac_update(ctx, (unsigned char *)host, + strlen(host)); + libssh2_hmac_final(ctx, hash); + libssh2_hmac_cleanup(&ctx); + + if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH)) + /* this is a node we're interested in */ + match = 1; + } + break; + default: /* unsupported type */ + break; + } + if(match) { + int host_key_type = typemask & LIBSSH2_KNOWNHOST_KEY_MASK; + int known_key_type = + node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK; + /* match on key type as follows: + - never match on an unknown key type + - if key_type is set to zero, ignore it an match always + - otherwise match when both key types are equal + */ + if(host_key_type != LIBSSH2_KNOWNHOST_KEY_UNKNOWN && + (host_key_type == 0 || + host_key_type == known_key_type)) { + /* host name and key type match, now compare the keys */ + if(!strcmp(key, node->key)) { + /* they match! */ + if(ext) + *ext = knownhost_to_external(node); + badkey = NULL; + rc = LIBSSH2_KNOWNHOST_CHECK_MATCH; + break; + } + else { + /* remember the first node that had a host match but a + failed key match since we continue our search from + here */ + if(!badkey) + badkey = node; + } + } + match = 0; /* don't count this as a match anymore */ + } + node = _libssh2_list_next(&node->node); + } + host = hostp; + } while(!match && --numcheck); + + if(badkey) { + /* key mismatch */ + if(ext) + *ext = knownhost_to_external(badkey); + rc = LIBSSH2_KNOWNHOST_CHECK_MISMATCH; + } + + if(keyalloc) + LIBSSH2_FREE(hosts->session, keyalloc); + + return rc; +} + +/* + * libssh2_knownhost_check + * + * Check a host and its associated key against the collection of known hosts. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +LIBSSH2_API int +libssh2_knownhost_check(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + return knownhost_check(hosts, hostp, -1, key, keylen, + typemask, ext); +} + +/* + * libssh2_knownhost_checkp + * + * Check a host+port and its associated key against the collection of known + * hosts. + * + * Note that if 'port' is specified as greater than zero, the check function + * will be able to check for a dedicated key for this particular host+port + * combo, and if 'port' is negative it only checks for the generic host key. + * + * The typemask is the type/format of the given host name and key + * + * plain - ascii "hostname.domain.tld" + * sha1 - NOT SUPPORTED AS INPUT + * custom - prehashed base64 encoded. Note that this cannot use any salts. + * + * Returns: + * + * LIBSSH2_KNOWNHOST_CHECK_FAILURE + * LIBSSH2_KNOWNHOST_CHECK_NOTFOUND + * LIBSSH2_KNOWNHOST_CHECK_MATCH + * LIBSSH2_KNOWNHOST_CHECK_MISMATCH + */ +LIBSSH2_API int +libssh2_knownhost_checkp(LIBSSH2_KNOWNHOSTS *hosts, + const char *hostp, int port, + const char *key, size_t keylen, + int typemask, + struct libssh2_knownhost **ext) +{ + return knownhost_check(hosts, hostp, port, key, keylen, + typemask, ext); +} + + +/* + * libssh2_knownhost_del + * + * Remove a host from the collection of known hosts. + * + */ +LIBSSH2_API int +libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *entry) +{ + struct known_host *node; + + /* check that this was retrieved the right way or get out */ + if(!entry || (entry->magic != KNOWNHOST_MAGIC)) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "Invalid host information"); + + /* get the internal node pointer */ + node = entry->node; + + /* unlink from the list of all hosts */ + _libssh2_list_remove(&node->node); + + /* clear the struct now since the memory in which it is allocated is + about to be freed! */ + memset(entry, 0, sizeof(struct libssh2_knownhost)); + + /* free all resources */ + free_host(hosts->session, node); + + return 0; +} + +/* + * libssh2_knownhost_free + * + * Free an entire collection of known hosts. + * + */ +LIBSSH2_API void +libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts) +{ + struct known_host *node; + struct known_host *next; + + for(node = _libssh2_list_first(&hosts->head); node; node = next) { + next = _libssh2_list_next(&node->node); + free_host(hosts->session, node); + } + LIBSSH2_FREE(hosts->session, hosts); +} + + +/* old style plain text: [name]([,][name])* + + for the sake of simplicity, we add them as separate hosts with the same + key +*/ +static int oldstyle_hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, int key_type, + const char *comment, size_t commentlen) +{ + int rc = 0; + size_t namelen = 0; + const char *name = host + hostlen; + + if(hostlen < 1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(no host names)"); + + while(name > host) { + --name; + ++namelen; + + /* when we get the the start or see a comma coming up, add the host + name to the collection */ + if((name == host) || (*(name-1) == ',')) { + + char hostbuf[256]; + + /* make sure we don't overflow the buffer */ + if(namelen >= sizeof(hostbuf)-1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpected length)"); + + /* copy host name to the temp buffer and zero terminate */ + memcpy(hostbuf, name, namelen); + hostbuf[namelen] = 0; + + rc = knownhost_add(hosts, hostbuf, NULL, + key_type_name, key_type_len, + key, keylen, + comment, commentlen, + key_type | LIBSSH2_KNOWNHOST_TYPE_PLAIN | + LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); + if(rc) + return rc; + + if(name > host) { + namelen = 0; + --name; /* skip comma */ + } + } + } + + return rc; +} + +/* |1|[salt]|[hash] */ +static int hashed_hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key_type_name, size_t key_type_len, + const char *key, size_t keylen, int key_type, + const char *comment, size_t commentlen) +{ + const char *p; + char saltbuf[32]; + char hostbuf[256]; + + const char *salt = &host[3]; /* skip the magic marker */ + hostlen -= 3; /* deduct the marker */ + + /* this is where the salt starts, find the end of it */ + for(p = salt; *p && (*p != '|'); p++) + ; + + if(*p == '|') { + const char *hash = NULL; + size_t saltlen = p - salt; + if(saltlen >= (sizeof(saltbuf)-1)) /* weird length */ + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpectedly long salt)"); + + memcpy(saltbuf, salt, saltlen); + saltbuf[saltlen] = 0; /* zero terminate */ + salt = saltbuf; /* point to the stack based buffer */ + + hash = p + 1; /* the host hash is after the separator */ + + /* now make the host point to the hash */ + host = hash; + hostlen -= saltlen + 1; /* deduct the salt and separator */ + + /* check that the lengths seem sensible */ + if(hostlen >= sizeof(hostbuf)-1) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(unexpected length)"); + + memcpy(hostbuf, host, hostlen); + hostbuf[hostlen] = 0; + + return knownhost_add(hosts, hostbuf, salt, + key_type_name, key_type_len, + key, keylen, + comment, commentlen, + key_type | LIBSSH2_KNOWNHOST_TYPE_SHA1 | + LIBSSH2_KNOWNHOST_KEYENC_BASE64, NULL); + } + else + return 0; /* XXX: This should be an error, shouldn't it? */ +} + +/* + * hostline() + * + * Parse a single known_host line pre-split into host and key. + * + * The key part may include an optional comment which will be parsed here + * for ssh-rsa and ssh-dsa keys. Comments in other key types aren't handled. + * + * The function assumes new-lines have already been removed from the arguments. + */ +static int hostline(LIBSSH2_KNOWNHOSTS *hosts, + const char *host, size_t hostlen, + const char *key, size_t keylen) +{ + const char *comment = NULL; + const char *key_type_name = NULL; + size_t commentlen = 0; + size_t key_type_len = 0; + int key_type; + + /* make some checks that the lengths seem sensible */ + if(keylen < 20) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line " + "(key too short)"); + + switch(key[0]) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + key_type = LIBSSH2_KNOWNHOST_KEY_RSA1; + + /* Note that the old-style keys (RSA1) aren't truly base64, but we + * claim it is for now since we can get away with strcmp()ing the + * entire anything anyway! We need to check and fix these to make them + * work properly. + */ + break; + + default: + key_type_name = key; + while(keylen && *key && + (*key != ' ') && (*key != '\t')) { + key++; + keylen--; + } + key_type_len = key - key_type_name; + + if(!strncmp(key_type_name, "ssh-dss", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_SSHDSS; + else if(!strncmp(key_type_name, "ssh-rsa", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_SSHRSA; + else if(!strncmp(key_type_name, "ecdsa-sha2-nistp256", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_256; + else if(!strncmp(key_type_name, "ecdsa-sha2-nistp384", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_384; + else if(!strncmp(key_type_name, "ecdsa-sha2-nistp521", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_ECDSA_521; + else if(!strncmp(key_type_name, "ssh-ed25519", key_type_len)) + key_type = LIBSSH2_KNOWNHOST_KEY_ED25519; + else + key_type = LIBSSH2_KNOWNHOST_KEY_UNKNOWN; + + /* skip whitespaces */ + while((*key ==' ') || (*key == '\t')) { + key++; + keylen--; + } + + comment = key; + commentlen = keylen; + + /* move over key */ + while(commentlen && *comment && + (*comment != ' ') && (*comment != '\t')) { + comment++; + commentlen--; + } + + /* reduce key by comment length */ + keylen -= commentlen; + + /* Distinguish empty comment (a space) from no comment (no space) */ + if(commentlen == 0) + comment = NULL; + + /* skip whitespaces */ + while(commentlen && *comment && + ((*comment ==' ') || (*comment == '\t'))) { + comment++; + commentlen--; + } + break; + } + + /* Figure out host format */ + if((hostlen >2) && memcmp(host, "|1|", 3)) { + /* old style plain text: [name]([,][name])* + + for the sake of simplicity, we add them as separate hosts with the + same key + */ + return oldstyle_hostline(hosts, host, hostlen, key_type_name, + key_type_len, key, keylen, key_type, + comment, commentlen); + } + else { + /* |1|[salt]|[hash] */ + return hashed_hostline(hosts, host, hostlen, key_type_name, + key_type_len, key, keylen, key_type, + comment, commentlen); + } +} + +/* + * libssh2_knownhost_readline() + * + * Pass in a line of a file of 'type'. + * + * LIBSSH2_KNOWNHOST_FILE_OPENSSH is the only supported type. + * + * OpenSSH line format: + * + * + * + * Where the two parts can be created like: + * + * can be either + * or + * + * consists of + * [name] optionally followed by [,name] one or more times + * + * consists of + * |1||hash + * + * can be one of: + * [RSA bits] [e] [n as a decimal number] + * 'ssh-dss' [base64-encoded-key] + * 'ssh-rsa' [base64-encoded-key] + * + */ +LIBSSH2_API int +libssh2_knownhost_readline(LIBSSH2_KNOWNHOSTS *hosts, + const char *line, size_t len, int type) +{ + const char *cp; + const char *hostp; + const char *keyp; + size_t hostlen; + size_t keylen; + int rc; + + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + cp = line; + + /* skip leading whitespaces */ + while(len && ((*cp == ' ') || (*cp == '\t'))) { + cp++; + len--; + } + + if(!len || !*cp || (*cp == '#') || (*cp == '\n')) + /* comment or empty line */ + return LIBSSH2_ERROR_NONE; + + /* the host part starts here */ + hostp = cp; + + /* move over the host to the separator */ + while(len && *cp && (*cp != ' ') && (*cp != '\t')) { + cp++; + len--; + } + + hostlen = cp - hostp; + + /* the key starts after the whitespaces */ + while(len && *cp && ((*cp == ' ') || (*cp == '\t'))) { + cp++; + len--; + } + + if(!*cp || !len) /* illegal line */ + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Failed to parse known_hosts line"); + + keyp = cp; /* the key starts here */ + keylen = len; + + /* check if the line (key) ends with a newline and if so kill it */ + while(len && *cp && (*cp != '\n')) { + cp++; + len--; + } + + /* zero terminate where the newline is */ + if(*cp == '\n') + keylen--; /* don't include this in the count */ + + /* deal with this one host+key line */ + rc = hostline(hosts, hostp, hostlen, keyp, keylen); + if(rc) + return rc; /* failed */ + + return LIBSSH2_ERROR_NONE; /* success */ +} + +/* + * libssh2_knownhost_readfile + * + * Read hosts+key pairs from a given file. + * + * Returns a negative value for error or number of successfully added hosts. + * + */ + +LIBSSH2_API int +libssh2_knownhost_readfile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type) +{ + FILE *file; + int num = 0; + char buf[4092]; + + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + file = fopen(filename, FOPEN_READTEXT); + if(file) { + while(fgets(buf, sizeof(buf), file)) { + if(libssh2_knownhost_readline(hosts, buf, strlen(buf), type)) { + num = _libssh2_error(hosts->session, LIBSSH2_ERROR_KNOWN_HOSTS, + "Failed to parse known hosts file"); + break; + } + num++; + } + fclose(file); + } + else + return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Failed to open file"); + + return num; +} + +/* + * knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. The 'outlen' field + * will then contain the size libssh2 wanted to store, which then is the + * smallest sufficient buffer it would require. + * + */ +static int +knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct known_host *node, + char *buf, size_t buflen, + size_t *outlen, int type) +{ + size_t required_size; + + const char *key_type_name; + size_t key_type_len; + + /* we only support this single file type for now, bail out on all other + attempts */ + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + switch(node->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) { + case LIBSSH2_KNOWNHOST_KEY_RSA1: + key_type_name = NULL; + key_type_len = 0; + break; + case LIBSSH2_KNOWNHOST_KEY_SSHRSA: + key_type_name = "ssh-rsa"; + key_type_len = 7; + break; + case LIBSSH2_KNOWNHOST_KEY_SSHDSS: + key_type_name = "ssh-dss"; + key_type_len = 7; + break; + case LIBSSH2_KNOWNHOST_KEY_ECDSA_256: + key_type_name = "ecdsa-sha2-nistp256"; + key_type_len = 19; + break; + case LIBSSH2_KNOWNHOST_KEY_ECDSA_384: + key_type_name = "ecdsa-sha2-nistp384"; + key_type_len = 19; + break; + case LIBSSH2_KNOWNHOST_KEY_ECDSA_521: + key_type_name = "ecdsa-sha2-nistp521"; + key_type_len = 19; + break; + case LIBSSH2_KNOWNHOST_KEY_ED25519: + key_type_name = "ssh-ed25519"; + key_type_len = 11; + break; + case LIBSSH2_KNOWNHOST_KEY_UNKNOWN: + key_type_name = node->key_type_name; + if(key_type_name) { + key_type_len = node->key_type_len; + break; + } + /* otherwise fallback to default and error */ + /* FALL-THROUGH */ + default: + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host entry"); + } + + /* When putting together the host line there are three aspects to consider: + - Hashed (SHA1) or unhashed hostname + - key name or no key name (RSA1) + - comment or no comment + + This means there are 2^3 different formats: + ("|1|%s|%s %s %s %s\n", salt, hashed_host, key_name, key, comment) + ("|1|%s|%s %s %s\n", salt, hashed_host, key_name, key) + ("|1|%s|%s %s %s\n", salt, hashed_host, key, comment) + ("|1|%s|%s %s\n", salt, hashed_host, key) + ("%s %s %s %s\n", host, key_name, key, comment) + ("%s %s %s\n", host, key_name, key) + ("%s %s %s\n", host, key, comment) + ("%s %s\n", host, key) + + Even if the buffer is too small, we have to set outlen to the number of + characters the complete line would have taken. We also don't write + anything to the buffer unless we are sure we can write everything to the + buffer. */ + + required_size = strlen(node->key); + + if(key_type_len) + required_size += key_type_len + 1; /* ' ' = 1 */ + if(node->comment) + required_size += node->comment_len + 1; /* ' ' = 1 */ + + if((node->typemask & LIBSSH2_KNOWNHOST_TYPE_MASK) == + LIBSSH2_KNOWNHOST_TYPE_SHA1) { + char *namealloc; + size_t name_base64_len; + char *saltalloc; + size_t salt_base64_len; + + name_base64_len = _libssh2_base64_encode(hosts->session, node->name, + node->name_len, &namealloc); + if(!name_base64_len) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded host name"); + + salt_base64_len = _libssh2_base64_encode(hosts->session, + node->salt, node->salt_len, + &saltalloc); + if(!salt_base64_len) { + LIBSSH2_FREE(hosts->session, namealloc); + return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "base64-encoded salt"); + } + + required_size += salt_base64_len + name_base64_len + 7; + /* |1| + | + ' ' + \n + \0 = 7 */ + + if(required_size <= buflen) { + if(node->comment && key_type_len) + snprintf(buf, buflen, "|1|%s|%s %s %s %s\n", saltalloc, + namealloc, key_type_name, node->key, node->comment); + else if(node->comment) + snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, + node->key, node->comment); + else if(key_type_len) + snprintf(buf, buflen, "|1|%s|%s %s %s\n", saltalloc, namealloc, + key_type_name, node->key); + else + snprintf(buf, buflen, "|1|%s|%s %s\n", saltalloc, namealloc, + node->key); + } + + LIBSSH2_FREE(hosts->session, namealloc); + LIBSSH2_FREE(hosts->session, saltalloc); + } + else { + required_size += node->name_len + 3; + /* ' ' + '\n' + \0 = 3 */ + + if(required_size <= buflen) { + if(node->comment && key_type_len) + snprintf(buf, buflen, "%s %s %s %s\n", node->name, + key_type_name, node->key, node->comment); + else if(node->comment) + snprintf(buf, buflen, "%s %s %s\n", node->name, node->key, + node->comment); + else if(key_type_len) + snprintf(buf, buflen, "%s %s %s\n", node->name, key_type_name, + node->key); + else + snprintf(buf, buflen, "%s %s\n", node->name, node->key); + } + } + + /* we report the full length of the data with the trailing zero excluded */ + *outlen = required_size-1; + + if(required_size <= buflen) + return LIBSSH2_ERROR_NONE; + else + return _libssh2_error(hosts->session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Known-host write buffer too small"); +} + +/* + * libssh2_knownhost_writeline() + * + * Ask libssh2 to convert a known host to an output line for storage. + * + * Note that this function returns LIBSSH2_ERROR_BUFFER_TOO_SMALL if the given + * output buffer is too small to hold the desired output. + */ +LIBSSH2_API int +libssh2_knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost *known, + char *buffer, size_t buflen, + size_t *outlen, /* the amount of written data */ + int type) +{ + struct known_host *node; + + if(known->magic != KNOWNHOST_MAGIC) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL, + "Invalid host information"); + + node = known->node; + + return knownhost_writeline(hosts, node, buffer, buflen, outlen, type); +} + +/* + * libssh2_knownhost_writefile() + * + * Write hosts+key pairs to the given file. + */ +LIBSSH2_API int +libssh2_knownhost_writefile(LIBSSH2_KNOWNHOSTS *hosts, + const char *filename, int type) +{ + struct known_host *node; + FILE *file; + int rc = LIBSSH2_ERROR_NONE; + char buffer[4092]; + + /* we only support this single file type for now, bail out on all other + attempts */ + if(type != LIBSSH2_KNOWNHOST_FILE_OPENSSH) + return _libssh2_error(hosts->session, + LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unsupported type of known-host information " + "store"); + + file = fopen(filename, FOPEN_WRITETEXT); + if(!file) + return _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Failed to open file"); + + for(node = _libssh2_list_first(&hosts->head); + node; + node = _libssh2_list_next(&node->node)) { + size_t wrote = 0; + size_t nwrote; + rc = knownhost_writeline(hosts, node, buffer, sizeof(buffer), &wrote, + type); + if(rc) + break; + + nwrote = fwrite(buffer, 1, wrote, file); + if(nwrote != wrote) { + /* failed to write the whole thing, bail out */ + rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_FILE, + "Write failed"); + break; + } + } + fclose(file); + + return rc; +} + + +/* + * libssh2_knownhost_get() + * + * Traverse the internal list of known hosts. Pass NULL to 'prev' to get + * the first one. + * + * Returns: + * 0 if a fine host was stored in 'store' + * 1 if end of hosts + * [negative] on errors + */ +LIBSSH2_API int +libssh2_knownhost_get(LIBSSH2_KNOWNHOSTS *hosts, + struct libssh2_knownhost **ext, + struct libssh2_knownhost *oprev) +{ + struct known_host *node; + if(oprev && oprev->node) { + /* we have a starting point */ + struct known_host *prev = oprev->node; + + /* get the next node in the list */ + node = _libssh2_list_next(&prev->node); + + } + else + node = _libssh2_list_first(&hosts->head); + + if(!node) + /* no (more) node */ + return 1; + + *ext = knownhost_to_external(node); + + return 0; +} diff --git a/libssh2/libgcrypt.c b/libssh2/libgcrypt.c new file mode 100644 index 0000000..0aff176 --- /dev/null +++ b/libssh2/libgcrypt.c @@ -0,0 +1,667 @@ +/* Copyright (C) 2008, 2009, Simon Josefsson + * Copyright (C) 2006, 2007, The Written Word, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_LIBGCRYPT /* compile only if we build with libgcrypt */ + +#include + +int +_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + int rc; + (void) e1data; + (void) e1len; + (void) e2data; + (void) e2len; + + if(ddata) { + rc = gcry_sexp_build + (rsa, NULL, + "(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))", + nlen, ndata, elen, edata, dlen, ddata, plen, pdata, + qlen, qdata, coefflen, coeffdata); + } + else { + rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))", + nlen, ndata, elen, edata); + } + if(rc) { + *rsa = NULL; + return -1; + } + + return 0; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; + + libssh2_sha1(m, m_len, hash); + + rc = gcry_sexp_build(&s_hash, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + SHA_DIGEST_LENGTH, hash); + if(rc != 0) { + return -1; + } + + rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig); + if(rc != 0) { + gcry_sexp_release(s_hash); + return -1; + } + + rc = gcry_pk_verify(s_sig, s_hash, rsa); + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + + return (rc == 0) ? 0 : -1; +} + +int +_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, unsigned long x_len) +{ + int rc; + + if(x_len) { + rc = gcry_sexp_build + (dsactx, NULL, + "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", + p_len, p, q_len, q, g_len, g, y_len, y, x_len, x); + } + else { + rc = gcry_sexp_build(dsactx, NULL, + "(public-key(dsa(p%b)(q%b)(g%b)(y%b)))", + p_len, p, q_len, q, g_len, g, y_len, y); + } + + if(rc) { + *dsactx = NULL; + return -1; + } + + return 0; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + FILE *fp; + unsigned char *data, *save_data; + unsigned int datalen; + int ret; + unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff; + unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen; + + fp = fopen(filename, FOPEN_READTEXT); + if(!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + passphrase, + fp, &data, &datalen); + fclose(fp); + if(ret) { + return -1; + } + + save_data = data; + + if(_libssh2_pem_decode_sequence(&data, &datalen)) { + ret = -1; + goto fail; + } +/* First read Version field (should be 0). */ + ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); + if(ret != 0 || (nlen != 1 && *n != '\0')) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen); + if(ret != 0) { + ret = -1; + goto fail; + } + + if(_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen, + q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) { + ret = -1; + goto fail; + } + + ret = 0; + + fail: + LIBSSH2_FREE(session, save_data); + return ret; +} + +int +_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + FILE *fp; + unsigned char *data, *save_data; + unsigned int datalen; + int ret; + unsigned char *p, *q, *g, *y, *x; + unsigned int plen, qlen, glen, ylen, xlen; + + fp = fopen(filename, FOPEN_READTEXT); + if(!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, + "-----BEGIN DSA PRIVATE KEY-----", + "-----END DSA PRIVATE KEY-----", + passphrase, + fp, &data, &datalen); + fclose(fp); + if(ret) { + return -1; + } + + save_data = data; + + if(_libssh2_pem_decode_sequence(&data, &datalen)) { + ret = -1; + goto fail; + } + +/* First read Version field (should be 0). */ + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if(ret != 0 || (plen != 1 && *p != '\0')) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen); + if(ret != 0) { + ret = -1; + goto fail; + } + + ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen); + if(ret != 0) { + ret = -1; + goto fail; + } + + if(datalen != 0) { + ret = -1; + goto fail; + } + + if(_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) { + ret = -1; + goto fail; + } + + ret = 0; + + fail: + LIBSSH2_FREE(session, save_data); + return ret; +} + +int +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, size_t *signature_len) +{ + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int rc; + const char *tmp; + size_t size; + + if(hash_len != SHA_DIGEST_LENGTH) { + return -1; + } + + if(gcry_sexp_build(&data, NULL, + "(data (flags pkcs1) (hash sha1 %b))", + hash_len, hash)) { + return -1; + } + + rc = gcry_pk_sign(&sig_sexp, data, rsactx); + + gcry_sexp_release(data); + + if(rc != 0) { + return -1; + } + + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if(!data) { + return -1; + } + + tmp = gcry_sexp_nth_data(data, 1, &size); + if(!tmp) { + gcry_sexp_release(data); + return -1; + } + + if(tmp[0] == '\0') { + tmp++; + size--; + } + + *signature = LIBSSH2_ALLOC(session, size); + if(!*signature) { + gcry_sexp_release(data); + return -1; + } + memcpy(*signature, tmp, size); + *signature_len = size; + + gcry_sexp_release(data); + + return rc; +} + +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *sig) +{ + unsigned char zhash[SHA_DIGEST_LENGTH + 1]; + gcry_sexp_t sig_sexp; + gcry_sexp_t data; + int ret; + const char *tmp; + size_t size; + + if(hash_len != SHA_DIGEST_LENGTH) { + return -1; + } + + memcpy(zhash + 1, hash, hash_len); + zhash[0] = 0; + + if(gcry_sexp_build(&data, NULL, "(data (value %b))", + hash_len + 1, zhash)) { + return -1; + } + + ret = gcry_pk_sign(&sig_sexp, data, dsactx); + + gcry_sexp_release(data); + + if(ret != 0) { + return -1; + } + + memset(sig, 0, 40); + +/* Extract R. */ + + data = gcry_sexp_find_token(sig_sexp, "r", 0); + if(!data) + goto err; + + tmp = gcry_sexp_nth_data(data, 1, &size); + if(!tmp) + goto err; + + if(tmp[0] == '\0') { + tmp++; + size--; + } + + if(size < 1 || size > 20) + goto err; + + memcpy(sig + (20 - size), tmp, size); + + gcry_sexp_release(data); + +/* Extract S. */ + + data = gcry_sexp_find_token(sig_sexp, "s", 0); + if(!data) + goto err; + + tmp = gcry_sexp_nth_data(data, 1, &size); + if(!tmp) + goto err; + + if(tmp[0] == '\0') { + tmp++; + size--; + } + + if(size < 1 || size > 20) + goto err; + + memcpy(sig + 20 + (20 - size), tmp, size); + goto out; + + err: + ret = -1; + + out: + if(sig_sexp) { + gcry_sexp_release(sig_sexp); + } + if(data) { + gcry_sexp_release(data); + } + return ret; +} + +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH + 1]; + gcry_sexp_t s_sig, s_hash; + int rc = -1; + + libssh2_sha1(m, m_len, hash + 1); + hash[0] = 0; + + if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))", + SHA_DIGEST_LENGTH + 1, hash)) { + return -1; + } + + if(gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))", + 20, sig, 20, sig + 20)) { + gcry_sexp_release(s_hash); + return -1; + } + + rc = gcry_pk_verify(s_sig, s_hash, dsactx); + gcry_sexp_release(s_sig); + gcry_sexp_release(s_hash); + + return (rc == 0) ? 0 : -1; +} + +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ + int ret; + int cipher = _libssh2_gcry_cipher(algo); + int mode = _libssh2_gcry_mode(algo); + int keylen = gcry_cipher_get_algo_keylen(cipher); + + (void) encrypt; + + ret = gcry_cipher_open(h, cipher, mode, 0); + if(ret) { + return -1; + } + + ret = gcry_cipher_setkey(*h, secret, keylen); + if(ret) { + gcry_cipher_close(*h); + return -1; + } + + if(mode != GCRY_CIPHER_MODE_STREAM) { + int blklen = gcry_cipher_get_algo_blklen(cipher); + if(mode == GCRY_CIPHER_MODE_CTR) + ret = gcry_cipher_setctr(*h, iv, blklen); + else + ret = gcry_cipher_setiv(*h, iv, blklen); + if(ret) { + gcry_cipher_close(*h); + return -1; + } + } + + return 0; +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blklen) +{ + int cipher = _libssh2_gcry_cipher(algo); + int ret; + + if(encrypt) { + ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen); + } + else { + ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen); + } + return ret; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract public key from private " + "key in memory: " + "Method unimplemented in libgcrypt backend"); +} + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to extract public key from private key file: " + "Method unimplemented in libgcrypt backend"); +} + +void _libssh2_init_aes_ctr(void) +{ + /* no implementation */ +} + +void +_libssh2_dh_init(_libssh2_dh_ctx *dhctx) +{ + *dhctx = gcry_mpi_new(0); /* Random from client */ +} + +int +_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order) +{ + /* Generate x and e */ + gcry_mpi_randomize(*dhctx, group_order * 8 - 1, GCRY_WEAK_RANDOM); + gcry_mpi_powm(public, g, *dhctx, p); + return 0; +} + +int +_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p) +{ + /* Compute the shared secret */ + gcry_mpi_powm(secret, f, *dhctx, p); + return 0; +} + +void +_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) +{ + gcry_mpi_release(*dhctx); + *dhctx = NULL; +} + +#endif /* LIBSSH2_LIBGCRYPT */ diff --git a/libssh2/mac.c b/libssh2/mac.c new file mode 100644 index 0000000..5ac71df --- /dev/null +++ b/libssh2/mac.c @@ -0,0 +1,414 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "mac.h" + +#ifdef LIBSSH2_MAC_NONE +/* mac_none_MAC + * Minimalist MAC: No MAC + */ +static int +mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, const unsigned char *packet, + uint32_t packet_len, const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + return 0; +} + + + + +static LIBSSH2_MAC_METHOD mac_method_none = { + "none", + 0, + 0, + NULL, + mac_none_MAC, + NULL +}; +#endif /* LIBSSH2_MAC_NONE */ + +/* mac_method_common_init + * Initialize simple mac methods + */ +static int +mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key, + int *free_key, void **abstract) +{ + *abstract = key; + *free_key = 0; + (void) session; + + return 0; +} + + + +/* mac_method_common_dtor + * Cleanup simple mac methods + */ +static int +mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract) +{ + if(*abstract) { + LIBSSH2_FREE(session, *abstract); + } + *abstract = NULL; + + return 0; +} + + + +#if LIBSSH2_HMAC_SHA512 +/* mac_method_hmac_sha512_hash + * Calculate hash using full sha512 value + */ +static int +mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha512_init(&ctx, *abstract, 64); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if(addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = { + "hmac-sha2-512", + 64, + 64, + mac_method_common_init, + mac_method_hmac_sha2_512_hash, + mac_method_common_dtor, +}; +#endif + + + +#if LIBSSH2_HMAC_SHA256 +/* mac_method_hmac_sha256_hash + * Calculate hash using full sha256 value + */ +static int +mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha256_init(&ctx, *abstract, 32); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if(addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = { + "hmac-sha2-256", + 32, + 32, + mac_method_common_init, + mac_method_hmac_sha2_256_hash, + mac_method_common_dtor, +}; +#endif + + + + +/* mac_method_hmac_sha1_hash + * Calculate hash using full sha1 value + */ +static int +mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_sha1_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if(addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = { + "hmac-sha1", + 20, + 20, + mac_method_common_init, + mac_method_hmac_sha1_hash, + mac_method_common_dtor, +}; + +/* mac_method_hmac_sha1_96_hash + * Calculate hash using first 96 bits of sha1 value + */ +static int +mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + unsigned char temp[SHA_DIGEST_LENGTH]; + + mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract); + memcpy(buf, (char *) temp, 96 / 8); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = { + "hmac-sha1-96", + 12, + 20, + mac_method_common_init, + mac_method_hmac_sha1_96_hash, + mac_method_common_dtor, +}; + +#if LIBSSH2_MD5 +/* mac_method_hmac_md5_hash + * Calculate hash using full md5 value + */ +static int +mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf, + uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_md5_init(&ctx, *abstract, 16); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if(addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = { + "hmac-md5", + 16, + 16, + mac_method_common_init, + mac_method_hmac_md5_hash, + mac_method_common_dtor, +}; + +/* mac_method_hmac_md5_96_hash + * Calculate hash using first 96 bits of md5 value + */ +static int +mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, void **abstract) +{ + unsigned char temp[MD5_DIGEST_LENGTH]; + mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len, + addtl, addtl_len, abstract); + memcpy(buf, (char *) temp, 96 / 8); + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = { + "hmac-md5-96", + 12, + 16, + mac_method_common_init, + mac_method_hmac_md5_96_hash, + mac_method_common_dtor, +}; +#endif /* LIBSSH2_MD5 */ + +#if LIBSSH2_HMAC_RIPEMD +/* mac_method_hmac_ripemd160_hash + * Calculate hash using ripemd160 value + */ +static int +mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session, + unsigned char *buf, uint32_t seqno, + const unsigned char *packet, + uint32_t packet_len, + const unsigned char *addtl, + uint32_t addtl_len, + void **abstract) +{ + libssh2_hmac_ctx ctx; + unsigned char seqno_buf[4]; + (void) session; + + _libssh2_htonu32(seqno_buf, seqno); + + libssh2_hmac_ctx_init(ctx); + libssh2_hmac_ripemd160_init(&ctx, *abstract, 20); + libssh2_hmac_update(ctx, seqno_buf, 4); + libssh2_hmac_update(ctx, packet, packet_len); + if(addtl && addtl_len) { + libssh2_hmac_update(ctx, addtl, addtl_len); + } + libssh2_hmac_final(ctx, buf); + libssh2_hmac_cleanup(&ctx); + + return 0; +} + + + +static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = { + "hmac-ripemd160", + 20, + 20, + mac_method_common_init, + mac_method_hmac_ripemd160_hash, + mac_method_common_dtor, +}; + +static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = { + "hmac-ripemd160@openssh.com", + 20, + 20, + mac_method_common_init, + mac_method_hmac_ripemd160_hash, + mac_method_common_dtor, +}; +#endif /* LIBSSH2_HMAC_RIPEMD */ + +static const LIBSSH2_MAC_METHOD *mac_methods[] = { +#if LIBSSH2_HMAC_SHA256 + &mac_method_hmac_sha2_256, +#endif +#if LIBSSH2_HMAC_SHA512 + &mac_method_hmac_sha2_512, +#endif + &mac_method_hmac_sha1, + &mac_method_hmac_sha1_96, +#if LIBSSH2_MD5 + &mac_method_hmac_md5, + &mac_method_hmac_md5_96, +#endif +#if LIBSSH2_HMAC_RIPEMD + &mac_method_hmac_ripemd160, + &mac_method_hmac_ripemd160_openssh_com, +#endif /* LIBSSH2_HMAC_RIPEMD */ +#ifdef LIBSSH2_MAC_NONE + &mac_method_none, +#endif /* LIBSSH2_MAC_NONE */ + NULL +}; + +const LIBSSH2_MAC_METHOD ** +_libssh2_mac_methods(void) +{ + return mac_methods; +} diff --git a/libssh2/mbedtls.c b/libssh2/mbedtls.c new file mode 100644 index 0000000..128eee4 --- /dev/null +++ b/libssh2/mbedtls.c @@ -0,0 +1,733 @@ +/* Copyright (c) 2016, Art + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_MBEDTLS /* compile only if we build with mbedtls */ + +/*******************************************************************/ +/* + * mbedTLS backend: Global context handles + */ + +static mbedtls_entropy_context _libssh2_mbedtls_entropy; +static mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg; + +/*******************************************************************/ +/* + * mbedTLS backend: Generic functions + */ + +void +_libssh2_mbedtls_init(void) +{ + int ret; + + mbedtls_entropy_init(&_libssh2_mbedtls_entropy); + mbedtls_ctr_drbg_init(&_libssh2_mbedtls_ctr_drbg); + + ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg, + mbedtls_entropy_func, + &_libssh2_mbedtls_entropy, NULL, 0); + if(ret != 0) + mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); +} + +void +_libssh2_mbedtls_free(void) +{ + mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); + mbedtls_entropy_free(&_libssh2_mbedtls_entropy); +} + +int +_libssh2_mbedtls_random(unsigned char *buf, int len) +{ + int ret; + ret = mbedtls_ctr_drbg_random(&_libssh2_mbedtls_ctr_drbg, buf, len); + return ret == 0 ? 0 : -1; +} + +static void +_libssh2_mbedtls_safe_free(void *buf, int len) +{ +#ifndef LIBSSH2_CLEAR_MEMORY + (void)len; +#endif + + if(!buf) + return; + +#ifdef LIBSSH2_CLEAR_MEMORY + if(len > 0) + memset(buf, 0, len); +#endif + + mbedtls_free(buf); +} + +int +_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + unsigned char *iv, + unsigned char *secret, + int encrypt) +{ + const mbedtls_cipher_info_t *cipher_info; + int ret, op; + + if(!ctx) + return -1; + + op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; + + cipher_info = mbedtls_cipher_info_from_type(algo); + if(!cipher_info) + return -1; + + mbedtls_cipher_init(ctx); + ret = mbedtls_cipher_setup(ctx, cipher_info); + if(!ret) + ret = mbedtls_cipher_setkey(ctx, secret, cipher_info->key_bitlen, op); + + if(!ret) + ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size); + + return ret == 0 ? 0 : -1; +} + +int +_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, + unsigned char *block, + size_t blocklen) +{ + int ret; + unsigned char *output; + size_t osize, olen, finish_olen; + + (void) encrypt; + (void) algo; + + osize = blocklen + mbedtls_cipher_get_block_size(ctx); + + output = (unsigned char *)mbedtls_calloc(osize, sizeof(char)); + if(output) { + ret = mbedtls_cipher_reset(ctx); + + if(!ret) + ret = mbedtls_cipher_update(ctx, block, blocklen, output, &olen); + + if(!ret) + ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen); + + if(!ret) { + olen += finish_olen; + memcpy(block, output, olen); + } + + _libssh2_mbedtls_safe_free(output, osize); + } + else + ret = -1; + + return ret == 0 ? 0 : -1; +} + +void +_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) +{ + mbedtls_cipher_free(ctx); +} + + +int +_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, + mbedtls_md_type_t mdtype, + const unsigned char *key, unsigned long keylen) +{ + const mbedtls_md_info_t *md_info; + int ret, hmac; + + md_info = mbedtls_md_info_from_type(mdtype); + if(!md_info) + return 0; + + hmac = key == NULL ? 0 : 1; + + mbedtls_md_init(ctx); + ret = mbedtls_md_setup(ctx, md_info, hmac); + if(!ret) { + if(hmac) + ret = mbedtls_md_hmac_starts(ctx, key, keylen); + else + ret = mbedtls_md_starts(ctx); + } + + return ret == 0 ? 1 : 0; +} + +int +_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) +{ + int ret; + + ret = mbedtls_md_finish(ctx, hash); + mbedtls_md_free(ctx); + + return ret == 0 ? 0 : -1; +} + +int +_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, + mbedtls_md_type_t mdtype, unsigned char *hash) +{ + const mbedtls_md_info_t *md_info; + int ret; + + md_info = mbedtls_md_info_from_type(mdtype); + if(!md_info) + return 0; + + ret = mbedtls_md(md_info, data, datalen, hash); + + return ret == 0 ? 0 : -1; +} + +/*******************************************************************/ +/* + * mbedTLS backend: BigNumber functions + */ + +_libssh2_bn * +_libssh2_mbedtls_bignum_init(void) +{ + _libssh2_bn *bignum; + + bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn)); + if(bignum) { + mbedtls_mpi_init(bignum); + } + + return bignum; +} + +void +_libssh2_mbedtls_bignum_free(_libssh2_bn *bn) +{ + if(bn) { + mbedtls_mpi_free(bn); + mbedtls_free(bn); + } +} + +static int +_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom) +{ + size_t len; + int err; + int i; + + if(!bn || bits <= 0) + return -1; + + len = (bits + 7) >> 3; + err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random, + &_libssh2_mbedtls_ctr_drbg); + if(err) + return -1; + + /* Zero unused bits above the most significant bit*/ + for(i = len*8 - 1; bits <= i; --i) { + err = mbedtls_mpi_set_bit(bn, i, 0); + if(err) + return -1; + } + + /* If `top` is -1, the most significant bit of the random number can be + zero. If top is 0, the most significant bit of the random number is + set to 1, and if top is 1, the two most significant bits of the number + will be set to 1, so that the product of two such random numbers will + always have 2*bits length. + */ + for(i = 0; i <= top; ++i) { + err = mbedtls_mpi_set_bit(bn, bits-i-1, 1); + if(err) + return -1; + } + + /* make odd by setting first bit in least significant byte */ + if(bottom) { + err = mbedtls_mpi_set_bit(bn, 0, 1); + if(err) + return -1; + } + + return 0; +} + + +/*******************************************************************/ +/* + * mbedTLS backend: RSA functions + */ + +int +_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen) +{ + int ret; + libssh2_rsa_ctx *ctx; + + ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); + if(ctx != NULL) { + mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0); + } + else + return -1; + + /* !checksrc! disable ASSIGNWITHINCONDITION 1 */ + if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0) { + ret = -1; + } + + if(!ret) { + ctx->len = mbedtls_mpi_size(&(ctx->N)); + } + + if(!ret && ddata) { + /* !checksrc! disable ASSIGNWITHINCONDITION 1 */ + if((ret = mbedtls_mpi_read_binary(&(ctx->D), ddata, dlen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->P), pdata, plen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->Q), qdata, qlen) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 || + (ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) ) + != 0) { + ret = -1; + } + ret = mbedtls_rsa_check_privkey(ctx); + } + else if(!ret) { + ret = mbedtls_rsa_check_pubkey(ctx); + } + + if(ret && ctx) { + _libssh2_mbedtls_rsa_free(ctx); + ctx = NULL; + } + *rsa = ctx; + return ret; +} + +int +_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase) +{ + int ret; + mbedtls_pk_context pkey; + mbedtls_rsa_context *pk_rsa; + + *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx)); + if(*rsa == NULL) + return -1; + + mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0); + mbedtls_pk_init(&pkey); + + ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase); + if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { + mbedtls_pk_free(&pkey); + mbedtls_rsa_free(*rsa); + LIBSSH2_FREE(session, *rsa); + *rsa = NULL; + return -1; + } + + pk_rsa = mbedtls_pk_rsa(pkey); + mbedtls_rsa_copy(*rsa, pk_rsa); + mbedtls_pk_free(&pkey); + + return 0; +} + +int +_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + int ret; + mbedtls_pk_context pkey; + mbedtls_rsa_context *pk_rsa; + void *filedata_nullterm; + size_t pwd_len; + + *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); + if(*rsa == NULL) + return -1; + + /* + mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" + private-key from memory will fail if the last byte is not a null byte + */ + filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1); + if(filedata_nullterm == NULL) { + return -1; + } + memcpy(filedata_nullterm, filedata, filedata_len); + + mbedtls_pk_init(&pkey); + + pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0; + ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm, + filedata_len + 1, + passphrase, pwd_len); + _libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len); + + if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { + mbedtls_pk_free(&pkey); + mbedtls_rsa_free(*rsa); + LIBSSH2_FREE(session, *rsa); + *rsa = NULL; + return -1; + } + + pk_rsa = mbedtls_pk_rsa(pkey); + mbedtls_rsa_copy(*rsa, pk_rsa); + mbedtls_pk_free(&pkey); + + return 0; +} + +int +_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + int ret; + + ret = _libssh2_mbedtls_hash(m, m_len, MBEDTLS_MD_SHA1, hash); + if(ret) + return -1; /* failure */ + + ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, + MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, + hash, sig); + + return (ret == 0) ? 0 : -1; +} + +int +_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len) +{ + int ret; + unsigned char *sig; + unsigned int sig_len; + + (void)hash_len; + + sig_len = rsa->len; + sig = LIBSSH2_ALLOC(session, sig_len); + if(!sig) { + return -1; + } + + ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, + MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, + hash, sig); + if(ret) { + LIBSSH2_FREE(session, sig); + return -1; + } + + *signature = sig; + *signature_len = sig_len; + + return (ret == 0) ? 0 : -1; +} + +void +_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *ctx) +{ + mbedtls_rsa_free(ctx); + mbedtls_free(ctx); +} + +static unsigned char * +gen_publickey_from_rsa(LIBSSH2_SESSION *session, + mbedtls_rsa_context *rsa, + size_t *keylen) +{ + int e_bytes, n_bytes; + unsigned long len; + unsigned char *key; + unsigned char *p; + + e_bytes = mbedtls_mpi_size(&rsa->E); + n_bytes = mbedtls_mpi_size(&rsa->N); + + /* Key form is "ssh-rsa" + e + n. */ + len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; + + key = LIBSSH2_ALLOC(session, len); + if(!key) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-rsa", 7); + p += 7; + + _libssh2_htonu32(p, e_bytes); + p += 4; + mbedtls_mpi_write_binary(&rsa->E, p, e_bytes); + + _libssh2_htonu32(p, n_bytes); + p += 4; + mbedtls_mpi_write_binary(&rsa->N, p, n_bytes); + + *keylen = (size_t)(p - key); + return key; +} + +static int +_libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + mbedtls_pk_context *pkey) +{ + unsigned char *key = NULL, *mth = NULL; + size_t keylen = 0, mthlen = 0; + int ret; + mbedtls_rsa_context *rsa; + + if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA) { + mbedtls_pk_free(pkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Key type not supported"); + } + + /* write method */ + mthlen = 7; + mth = LIBSSH2_ALLOC(session, mthlen); + if(mth) { + memcpy(mth, "ssh-rsa", mthlen); + } + else { + ret = -1; + } + + rsa = mbedtls_pk_rsa(*pkey); + key = gen_publickey_from_rsa(session, rsa, &keylen); + if(key == NULL) { + ret = -1; + } + + /* write output */ + if(ret) { + if(mth) + LIBSSH2_FREE(session, mth); + if(key) + LIBSSH2_FREE(session, key); + } + else { + *method = mth; + *method_len = mthlen; + *pubkeydata = key; + *pubkeydata_len = keylen; + } + + return ret; +} + +int +_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + mbedtls_pk_context pkey; + char buf[1024]; + int ret; + + mbedtls_pk_init(&pkey); + ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase); + if(ret != 0) { + mbedtls_strerror(ret, (char *)buf, sizeof(buf)); + mbedtls_pk_free(&pkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); + } + + ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, + pubkeydata, pubkeydata_len, &pkey); + + mbedtls_pk_free(&pkey); + + return ret; +} + +int +_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + mbedtls_pk_context pkey; + char buf[1024]; + int ret; + void *privatekeydata_nullterm; + size_t pwd_len; + + /* + mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" + private-key from memory will fail if the last byte is not a null byte + */ + privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1); + if(privatekeydata_nullterm == NULL) { + return -1; + } + memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len); + + mbedtls_pk_init(&pkey); + + pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0; + ret = mbedtls_pk_parse_key(&pkey, + (unsigned char *)privatekeydata_nullterm, + privatekeydata_len + 1, + (const unsigned char *)passphrase, pwd_len); + _libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len); + + if(ret != 0) { + mbedtls_strerror(ret, (char *)buf, sizeof(buf)); + mbedtls_pk_free(&pkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); + } + + ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, + pubkeydata, pubkeydata_len, &pkey); + + mbedtls_pk_free(&pkey); + + return ret; +} + +void _libssh2_init_aes_ctr(void) +{ + /* no implementation */ +} + + +/*******************************************************************/ +/* + * mbedTLS backend: Diffie-Hellman functions + */ + +void +_libssh2_dh_init(_libssh2_dh_ctx *dhctx) +{ + *dhctx = _libssh2_mbedtls_bignum_init(); /* Random from client */ +} + +int +_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order) +{ + /* Generate x and e */ + _libssh2_mbedtls_bignum_random(*dhctx, group_order * 8 - 1, 0, -1); + mbedtls_mpi_exp_mod(public, g, *dhctx, p, NULL); + return 0; +} + +int +_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p) +{ + /* Compute the shared secret */ + mbedtls_mpi_exp_mod(secret, f, *dhctx, p, NULL); + return 0; +} + +void +_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) +{ + _libssh2_mbedtls_bignum_free(*dhctx); + *dhctx = NULL; +} + +#endif /* LIBSSH2_MBEDTLS */ diff --git a/libssh2/misc.c b/libssh2/misc.c new file mode 100644 index 0000000..594b2d1 --- /dev/null +++ b/libssh2/misc.c @@ -0,0 +1,872 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2019 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "misc.h" +#include "blf.h" + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#if defined(HAVE_DECL_SECUREZEROMEMORY) && HAVE_DECL_SECUREZEROMEMORY +#ifdef HAVE_WINDOWS_H +#include +#endif +#endif + +#include +#include + +int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode, + const char *errmsg, int errflags) +{ + if(session->err_flags & LIBSSH2_ERR_FLAG_DUP) + LIBSSH2_FREE(session, (char *)session->err_msg); + + session->err_code = errcode; + session->err_flags = 0; + + if((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) { + size_t len = strlen(errmsg); + char *copy = LIBSSH2_ALLOC(session, len + 1); + if(copy) { + memcpy(copy, errmsg, len + 1); + session->err_flags = LIBSSH2_ERR_FLAG_DUP; + session->err_msg = copy; + } + else + /* Out of memory: this code path is very unlikely */ + session->err_msg = "former error forgotten (OOM)"; + } + else + session->err_msg = errmsg; + +#ifdef LIBSSH2DEBUG + if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode) + /* if this is EAGAIN and we're in non-blocking mode, don't generate + a debug output for this */ + return errcode; + _libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code, + session->err_msg); +#endif + + return errcode; +} + +int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg) +{ + return _libssh2_error_flags(session, errcode, errmsg, 0); +} + +#ifdef WIN32 +static int wsa2errno(void) +{ + switch(WSAGetLastError()) { + case WSAEWOULDBLOCK: + return EAGAIN; + + case WSAENOTSOCK: + return EBADF; + + case WSAEINTR: + return EINTR; + + default: + /* It is most important to ensure errno does not stay at EAGAIN + * when a different error occurs so just set errno to a generic + * error */ + return EIO; + } +} +#endif + +/* _libssh2_recv + * + * Replacement for the standard recv, return -errno on failure. + */ +ssize_t +_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length, + int flags, void **abstract) +{ + ssize_t rc; + + (void) abstract; + + rc = recv(sock, buffer, length, flags); +#ifdef WIN32 + if(rc < 0) + return -wsa2errno(); +#else + if(rc < 0) { + /* Sometimes the first recv() function call sets errno to ENOENT on + Solaris and HP-UX */ + if(errno == ENOENT) + return -EAGAIN; +#ifdef EWOULDBLOCK /* For VMS and other special unixes */ + else if(errno == EWOULDBLOCK) + return -EAGAIN; +#endif + else + return -errno; + } +#endif + return rc; +} + +/* _libssh2_send + * + * Replacement for the standard send, return -errno on failure. + */ +ssize_t +_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length, + int flags, void **abstract) +{ + ssize_t rc; + + (void) abstract; + + rc = send(sock, buffer, length, flags); +#ifdef WIN32 + if(rc < 0) + return -wsa2errno(); +#else + if(rc < 0) { +#ifdef EWOULDBLOCK /* For VMS and other special unixes */ + if(errno == EWOULDBLOCK) + return -EAGAIN; +#endif + return -errno; + } +#endif + return rc; +} + +/* libssh2_ntohu32 + */ +unsigned int +_libssh2_ntohu32(const unsigned char *buf) +{ + return (((unsigned int)buf[0] << 24) + | ((unsigned int)buf[1] << 16) + | ((unsigned int)buf[2] << 8) + | ((unsigned int)buf[3])); +} + + +/* _libssh2_ntohu64 + */ +libssh2_uint64_t +_libssh2_ntohu64(const unsigned char *buf) +{ + unsigned long msl, lsl; + + msl = ((libssh2_uint64_t)buf[0] << 24) | ((libssh2_uint64_t)buf[1] << 16) + | ((libssh2_uint64_t)buf[2] << 8) | (libssh2_uint64_t)buf[3]; + lsl = ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16) + | ((libssh2_uint64_t)buf[6] << 8) | (libssh2_uint64_t)buf[7]; + + return ((libssh2_uint64_t)msl <<32) | lsl; +} + +/* _libssh2_htonu32 + */ +void +_libssh2_htonu32(unsigned char *buf, uint32_t value) +{ + buf[0] = (value >> 24) & 0xFF; + buf[1] = (value >> 16) & 0xFF; + buf[2] = (value >> 8) & 0xFF; + buf[3] = value & 0xFF; +} + +/* _libssh2_store_u32 + */ +void _libssh2_store_u32(unsigned char **buf, uint32_t value) +{ + _libssh2_htonu32(*buf, value); + *buf += sizeof(uint32_t); +} + +/* _libssh2_store_str + */ +void _libssh2_store_str(unsigned char **buf, const char *str, size_t len) +{ + _libssh2_store_u32(buf, (uint32_t)len); + if(len) { + memcpy(*buf, str, len); + *buf += len; + } +} + +/* Base64 Conversion */ + +static const short base64_reverse_table[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +/* libssh2_base64_decode + * + * Decode a base64 chunk and store it into a newly alloc'd buffer + */ +LIBSSH2_API int +libssh2_base64_decode(LIBSSH2_SESSION *session, char **data, + unsigned int *datalen, const char *src, + unsigned int src_len) +{ + unsigned char *s, *d; + short v; + int i = 0, len = 0; + + *data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1); + d = (unsigned char *) *data; + if(!d) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for base64 decoding"); + } + + for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) { + v = base64_reverse_table[*s]; + if(v < 0) + continue; + switch(i % 4) { + case 0: + d[len] = (unsigned char)(v << 2); + break; + case 1: + d[len++] |= v >> 4; + d[len] = (unsigned char)(v << 4); + break; + case 2: + d[len++] |= v >> 2; + d[len] = (unsigned char)(v << 6); + break; + case 3: + d[len++] |= v; + break; + } + i++; + } + if((i % 4) == 1) { + /* Invalid -- We have a byte which belongs exclusively to a partial + octet */ + LIBSSH2_FREE(session, *data); + *data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64"); + } + + *datalen = len; + return 0; +} + +/* ---- Base64 Encoding/Decoding Table --- */ +static const char table64[]= + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/* + * _libssh2_base64_encode() + * + * Returns the length of the newly created base64 string. The third argument + * is a pointer to an allocated area holding the base64 data. If something + * went wrong, 0 is returned. + * + */ +size_t _libssh2_base64_encode(LIBSSH2_SESSION *session, + const char *inp, size_t insize, char **outptr) +{ + unsigned char ibuf[3]; + unsigned char obuf[4]; + int i; + int inputparts; + char *output; + char *base64data; + const char *indata = inp; + + *outptr = NULL; /* set to NULL in case of failure before we reach the + end */ + + if(0 == insize) + insize = strlen(indata); + + base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4); + if(NULL == output) + return 0; + + while(insize > 0) { + for(i = inputparts = 0; i < 3; i++) { + if(insize > 0) { + inputparts++; + ibuf[i] = *indata; + indata++; + insize--; + } + else + ibuf[i] = 0; + } + + obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2); + obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \ + ((ibuf[1] & 0xF0) >> 4)); + obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \ + ((ibuf[2] & 0xC0) >> 6)); + obuf[3] = (unsigned char) (ibuf[2] & 0x3F); + + switch(inputparts) { + case 1: /* only one byte read */ + snprintf(output, 5, "%c%c==", + table64[obuf[0]], + table64[obuf[1]]); + break; + case 2: /* two bytes read */ + snprintf(output, 5, "%c%c%c=", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]]); + break; + default: + snprintf(output, 5, "%c%c%c%c", + table64[obuf[0]], + table64[obuf[1]], + table64[obuf[2]], + table64[obuf[3]]); + break; + } + output += 4; + } + *output = 0; + *outptr = base64data; /* make it return the actual data memory */ + + return strlen(base64data); /* return the length of the new data */ +} +/* ---- End of Base64 Encoding ---- */ + +LIBSSH2_API void +libssh2_free(LIBSSH2_SESSION *session, void *ptr) +{ + LIBSSH2_FREE(session, ptr); +} + +#ifdef LIBSSH2DEBUG +#include + +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) +{ + session->showmask = bitmask; + return 0; +} + +LIBSSH2_API int +libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context, + libssh2_trace_handler_func callback) +{ + session->tracehandler = callback; + session->tracehandler_context = handler_context; + return 0; +} + +void +_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...) +{ + char buffer[1536]; + int len, msglen, buflen = sizeof(buffer); + va_list vargs; + struct timeval now; + static int firstsec; + static const char *const contexts[] = { + "Unknown", + "Transport", + "Key Ex", + "Userauth", + "Conn", + "SCP", + "SFTP", + "Failure Event", + "Publickey", + "Socket", + }; + const char *contexttext = contexts[0]; + unsigned int contextindex; + + if(!(session->showmask & context)) { + /* no such output asked for */ + return; + } + + /* Find the first matching context string for this message */ + for(contextindex = 0; contextindex < ARRAY_SIZE(contexts); + contextindex++) { + if((context & (1 << contextindex)) != 0) { + contexttext = contexts[contextindex]; + break; + } + } + + _libssh2_gettimeofday(&now, NULL); + if(!firstsec) { + firstsec = now.tv_sec; + } + now.tv_sec -= firstsec; + + len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ", + (int)now.tv_sec, (int)now.tv_usec, contexttext); + + if(len >= buflen) + msglen = buflen - 1; + else { + buflen -= len; + msglen = len; + va_start(vargs, format); + len = vsnprintf(buffer + msglen, buflen, format, vargs); + va_end(vargs); + msglen += len < buflen ? len : buflen - 1; + } + + if(session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, buffer, + msglen); + else + fprintf(stderr, "%s\n", buffer); +} + +#else +LIBSSH2_API int +libssh2_trace(LIBSSH2_SESSION * session, int bitmask) +{ + (void) session; + (void) bitmask; + return 0; +} + +LIBSSH2_API int +libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context, + libssh2_trace_handler_func callback) +{ + (void) session; + (void) handler_context; + (void) callback; + return 0; +} +#endif + +/* init the list head */ +void _libssh2_list_init(struct list_head *head) +{ + head->first = head->last = NULL; +} + +/* add a node to the list */ +void _libssh2_list_add(struct list_head *head, + struct list_node *entry) +{ + /* store a pointer to the head */ + entry->head = head; + + /* we add this entry at the "top" so it has no next */ + entry->next = NULL; + + /* make our prev point to what the head thinks is last */ + entry->prev = head->last; + + /* and make head's last be us now */ + head->last = entry; + + /* make sure our 'prev' node points to us next */ + if(entry->prev) + entry->prev->next = entry; + else + head->first = entry; +} + +/* return the "first" node in the list this head points to */ +void *_libssh2_list_first(struct list_head *head) +{ + return head->first; +} + +/* return the next node in the list */ +void *_libssh2_list_next(struct list_node *node) +{ + return node->next; +} + +/* return the prev node in the list */ +void *_libssh2_list_prev(struct list_node *node) +{ + return node->prev; +} + +/* remove this node from the list */ +void _libssh2_list_remove(struct list_node *entry) +{ + if(entry->prev) + entry->prev->next = entry->next; + else + entry->head->first = entry->next; + + if(entry->next) + entry->next->prev = entry->prev; + else + entry->head->last = entry->prev; +} + +#if 0 +/* insert a node before the given 'after' entry */ +void _libssh2_list_insert(struct list_node *after, /* insert before this */ + struct list_node *entry) +{ + /* 'after' is next to 'entry' */ + bentry->next = after; + + /* entry's prev is then made to be the prev after current has */ + entry->prev = after->prev; + + /* the node that is now before 'entry' was previously before 'after' + and must be made to point to 'entry' correctly */ + if(entry->prev) + entry->prev->next = entry; + else + /* there was no node before this, so we make sure we point the head + pointer to this node */ + after->head->first = entry; + + /* after's prev entry points back to entry */ + after->prev = entry; + + /* after's next entry is still the same as before */ + + /* entry's head is the same as after's */ + entry->head = after->head; +} + +#endif + +/* this define is defined in misc.h for the correct platforms */ +#ifdef LIBSSH2_GETTIMEOFDAY_WIN32 +/* + * gettimeofday + * Implementation according to: + * The Open Group Base Specifications Issue 6 + * IEEE Std 1003.1, 2004 Edition + */ + +/* + * THIS SOFTWARE IS NOT COPYRIGHTED + * + * This source code is offered for use in the public domain. You may + * use, modify or distribute it freely. + * + * This code is distributed in the hope that it will be useful but + * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY + * DISCLAIMED. This includes but is not limited to warranties of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Contributed by: + * Danny Smith + */ + +/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ +#define _W32_FT_OFFSET (116444736000000000) + +int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp) +{ + union { + unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */ + FILETIME ft; + } _now; + (void)tzp; + if(tp) { + GetSystemTimeAsFileTime(&_now.ft); + tp->tv_usec = (long)((_now.ns100 / 10) % 1000000); + tp->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000); + } + /* Always return 0 as per Open Group Base Specifications Issue 6. + Do not set errno on error. */ + return 0; +} + + +#endif + +void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size) +{ + void *p = LIBSSH2_ALLOC(session, size); + if(p) { + memset(p, 0, size); + } + return p; +} + +/* XOR operation on buffers input1 and input2, result in output. + It is safe to use an input buffer as the output buffer. */ +void _libssh2_xor_data(unsigned char *output, + const unsigned char *input1, + const unsigned char *input2, + size_t length) +{ + size_t i; + + for(i = 0; i < length; i++) + *output++ = *input1++ ^ *input2++; +} + +/* Increments an AES CTR buffer to prepare it for use with the + next AES block. */ +void _libssh2_aes_ctr_increment(unsigned char *ctr, + size_t length) +{ + unsigned char *pc; + unsigned int val, carry; + + pc = ctr + length - 1; + carry = 1; + + while(pc >= ctr) { + val = (unsigned int)*pc + carry; + *pc-- = val & 0xFF; + carry = val >> 8; + } +} + +#ifdef WIN32 +static void * (__cdecl * const volatile memset_libssh)(void *, int, size_t) = + memset; +#else +static void * (* const volatile memset_libssh)(void *, int, size_t) = memset; +#endif + +void _libssh2_explicit_zero(void *buf, size_t size) +{ +#if defined(HAVE_DECL_SECUREZEROMEMORY) && HAVE_DECL_SECUREZEROMEMORY + SecureZeroMemory(buf, size); + (void)memset_libssh; /* Silence unused variable warning */ +#elif defined(HAVE_MEMSET_S) + (void)memset_s(buf, size, 0, size); + (void)memset_libssh; /* Silence unused variable warning */ +#else + memset_libssh(buf, 0, size); +#endif +} + +/* String buffer */ + +struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session) +{ + struct string_buf *ret; + + ret = _libssh2_calloc(session, sizeof(*ret)); + if(ret == NULL) + return NULL; + + return ret; +} + +void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf) +{ + if(buf == NULL) + return; + + if(buf->data != NULL) + LIBSSH2_FREE(session, buf->data); + + LIBSSH2_FREE(session, buf); + buf = NULL; +} + +int _libssh2_get_u32(struct string_buf *buf, uint32_t *out) +{ + if(!_libssh2_check_length(buf, 4)) { + return -1; + } + + *out = _libssh2_ntohu32(buf->dataptr); + buf->dataptr += 4; + return 0; +} + +int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out) +{ + if(!_libssh2_check_length(buf, 8)) { + return -1; + } + + *out = _libssh2_ntohu64(buf->dataptr); + buf->dataptr += 8; + return 0; +} + +int _libssh2_match_string(struct string_buf *buf, const char *match) +{ + unsigned char *out; + size_t len = 0; + if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) || + strncmp((char *)out, match, strlen(match)) != 0) { + return -1; + } + return 0; +} + +int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf, + size_t *outlen) +{ + uint32_t data_len; + if(_libssh2_get_u32(buf, &data_len) != 0) { + return -1; + } + if(!_libssh2_check_length(buf, data_len)) { + return -1; + } + *outbuf = buf->dataptr; + buf->dataptr += data_len; + + if(outlen) + *outlen = (size_t)data_len; + + return 0; +} + +int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf, + unsigned char **outbuf, size_t *outlen) +{ + size_t str_len; + unsigned char *str; + + if(_libssh2_get_string(buf, &str, &str_len)) { + return -1; + } + + *outbuf = LIBSSH2_ALLOC(session, str_len); + if(*outbuf) { + memcpy(*outbuf, str, str_len); + } + else { + return -1; + } + + if(outlen) + *outlen = str_len; + + return 0; +} + +int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf, + size_t *outlen) +{ + uint32_t data_len; + uint32_t bn_len; + unsigned char *bnptr; + + if(_libssh2_get_u32(buf, &data_len)) { + return -1; + } + if(!_libssh2_check_length(buf, data_len)) { + return -1; + } + + bn_len = data_len; + bnptr = buf->dataptr; + + /* trim leading zeros */ + while(bn_len > 0 && *bnptr == 0x00) { + bn_len--; + bnptr++; + } + + *outbuf = bnptr; + buf->dataptr += data_len; + + if(outlen) + *outlen = (size_t)bn_len; + + return 0; +} + +/* Given the current location in buf, _libssh2_check_length ensures + callers can read the next len number of bytes out of the buffer + before reading the buffer content */ + +int _libssh2_check_length(struct string_buf *buf, size_t len) +{ + unsigned char *endp = &buf->data[buf->len]; + size_t left = endp - buf->dataptr; + return ((len <= left) && (left <= buf->len)); +} + +/* Wrappers */ + +int _libssh2_bcrypt_pbkdf(const char *pass, + size_t passlen, + const uint8_t *salt, + size_t saltlen, + uint8_t *key, + size_t keylen, + unsigned int rounds) +{ + /* defined in bcrypt_pbkdf.c */ + return bcrypt_pbkdf(pass, + passlen, + salt, + saltlen, + key, + keylen, + rounds); +} diff --git a/libssh2/module.mk b/libssh2/module.mk new file mode 100644 index 0000000..34a3f0e --- /dev/null +++ b/libssh2/module.mk @@ -0,0 +1,40 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/libssh2 Makefile fragment +# +####################################################################### + +if BUILD_SSH_TUNNEL + +pgadmin3_SOURCES += \ + libssh2/agent.c \ + libssh2/channel.c \ + libssh2/comp.c \ + libssh2/crypt.c \ + libssh2/global.c \ + libssh2/hostkey.c \ + libssh2/keepalive.c \ + libssh2/kex.c \ + libssh2/knownhost.c \ + libssh2/libgcrypt.c \ + libssh2/mac.c \ + libssh2/misc.c \ + libssh2/openssl.c \ + libssh2/packet.c \ + libssh2/pem.c \ + libssh2/publickey.c \ + libssh2/scp.c \ + libssh2/session.c \ + libssh2/sftp.c \ + libssh2/transport.c \ + libssh2/userauth.c \ + libssh2/version.c + +EXTRA_DIST += \ + libssh2/module.mk +endif diff --git a/libssh2/openssl.c b/libssh2/openssl.c new file mode 100644 index 0000000..9d3b8c7 --- /dev/null +++ b/libssh2/openssl.c @@ -0,0 +1,3294 @@ +/* Copyright (C) 2009, 2010 Simon Josefsson + * Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved. + * Copyright (c) 2004-2006, Sara Golemon + * + * Author: Simon Josefsson + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_OPENSSL /* compile only if we build with openssl */ + +#include +#include "misc.h" + +#ifndef EVP_MAX_BLOCK_LENGTH +#define EVP_MAX_BLOCK_LENGTH 32 +#endif + +int +read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session, + const char *key_type, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase); + +static unsigned char * +write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes) +{ + unsigned char *p = buf; + + /* Left space for bn size which will be written below. */ + p += 4; + + *p = 0; + BN_bn2bin(bn, p + 1); + if(!(*(p + 1) & 0x80)) { + memmove(p, p + 1, --bn_bytes); + } + _libssh2_htonu32(p - 4, bn_bytes); /* Post write bn size. */ + + return p + bn_bytes; +} + +int +_libssh2_rsa_new(libssh2_rsa_ctx ** rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + BIGNUM * e; + BIGNUM * n; + BIGNUM * d = 0; + BIGNUM * p = 0; + BIGNUM * q = 0; + BIGNUM * dmp1 = 0; + BIGNUM * dmq1 = 0; + BIGNUM * iqmp = 0; + + e = BN_new(); + BN_bin2bn(edata, elen, e); + + n = BN_new(); + BN_bin2bn(ndata, nlen, n); + + if(ddata) { + d = BN_new(); + BN_bin2bn(ddata, dlen, d); + + p = BN_new(); + BN_bin2bn(pdata, plen, p); + + q = BN_new(); + BN_bin2bn(qdata, qlen, q); + + dmp1 = BN_new(); + BN_bin2bn(e1data, e1len, dmp1); + + dmq1 = BN_new(); + BN_bin2bn(e2data, e2len, dmq1); + + iqmp = BN_new(); + BN_bin2bn(coeffdata, coefflen, iqmp); + } + + *rsa = RSA_new(); +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_key(*rsa, n, e, d); +#else + (*rsa)->e = e; + (*rsa)->n = n; + (*rsa)->d = d; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_factors(*rsa, p, q); +#else + (*rsa)->p = p; + (*rsa)->q = q; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_crt_params(*rsa, dmp1, dmq1, iqmp); +#else + (*rsa)->dmp1 = dmp1; + (*rsa)->dmq1 = dmq1; + (*rsa)->iqmp = iqmp; +#endif + return 0; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsactx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + int ret; + + if(_libssh2_sha1(m, m_len, hash)) + return -1; /* failure */ + ret = RSA_verify(NID_sha1, hash, SHA_DIGEST_LENGTH, + (unsigned char *) sig, sig_len, rsactx); + return (ret == 1) ? 0 : -1; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx, + const unsigned char *p, + unsigned long p_len, + const unsigned char *q, + unsigned long q_len, + const unsigned char *g, + unsigned long g_len, + const unsigned char *y, + unsigned long y_len, + const unsigned char *x, unsigned long x_len) +{ + BIGNUM * p_bn; + BIGNUM * q_bn; + BIGNUM * g_bn; + BIGNUM * pub_key; + BIGNUM * priv_key = NULL; + + p_bn = BN_new(); + BN_bin2bn(p, p_len, p_bn); + + q_bn = BN_new(); + BN_bin2bn(q, q_len, q_bn); + + g_bn = BN_new(); + BN_bin2bn(g, g_len, g_bn); + + pub_key = BN_new(); + BN_bin2bn(y, y_len, pub_key); + + if(x_len) { + priv_key = BN_new(); + BN_bin2bn(x, x_len, priv_key); + } + + *dsactx = DSA_new(); + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_set0_pqg(*dsactx, p_bn, q_bn, g_bn); +#else + (*dsactx)->p = p_bn; + (*dsactx)->g = g_bn; + (*dsactx)->q = q_bn; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_set0_key(*dsactx, pub_key, priv_key); +#else + (*dsactx)->pub_key = pub_key; + (*dsactx)->priv_key = priv_key; +#endif + return 0; +} + +int +_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx, + const unsigned char *sig, + const unsigned char *m, unsigned long m_len) +{ + unsigned char hash[SHA_DIGEST_LENGTH]; + DSA_SIG * dsasig; + BIGNUM * r; + BIGNUM * s; + int ret = -1; + + r = BN_new(); + BN_bin2bn(sig, 20, r); + s = BN_new(); + BN_bin2bn(sig + 20, 20, s); + + dsasig = DSA_SIG_new(); +#ifdef HAVE_OPAQUE_STRUCTS + DSA_SIG_set0(dsasig, r, s); +#else + dsasig->r = r; + dsasig->s = s; +#endif + if(!_libssh2_sha1(m, m_len, hash)) + /* _libssh2_sha1() succeeded */ + ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, dsasig, dsactx); + + DSA_SIG_free(dsasig); + + return (ret == 1) ? 0 : -1; +} +#endif /* LIBSSH_DSA */ + +#if LIBSSH2_ECDSA + +/* _libssh2_ecdsa_get_curve_type + * + * returns key curve type that maps to libssh2_curve_type + * + */ + +libssh2_curve_type +_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx) +{ + const EC_GROUP *group = EC_KEY_get0_group(ec_ctx); + return EC_GROUP_get_curve_name(group); +} + +/* _libssh2_ecdsa_curve_type_from_name + * + * returns 0 for success, key curve type that maps to libssh2_curve_type + * + */ + +int +_libssh2_ecdsa_curve_type_from_name(const char *name, + libssh2_curve_type *out_type) +{ + int ret = 0; + libssh2_curve_type type; + + if(name == NULL || strlen(name) != 19) + return -1; + + if(strcmp(name, "ecdsa-sha2-nistp256") == 0) + type = LIBSSH2_EC_CURVE_NISTP256; + else if(strcmp(name, "ecdsa-sha2-nistp384") == 0) + type = LIBSSH2_EC_CURVE_NISTP384; + else if(strcmp(name, "ecdsa-sha2-nistp521") == 0) + type = LIBSSH2_EC_CURVE_NISTP521; + else { + ret = -1; + } + + if(ret == 0 && out_type) { + *out_type = type; + } + + return ret; +} + +/* _libssh2_ecdsa_curve_name_with_octal_new + * + * Creates a new public key given an octal string, length and type + * + */ + +int +_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx, + const unsigned char *k, + size_t k_len, libssh2_curve_type curve) +{ + + int ret = 0; + const EC_GROUP *ec_group = NULL; + EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve); + EC_POINT *point = NULL; + + if(ec_key) { + ec_group = EC_KEY_get0_group(ec_key); + point = EC_POINT_new(ec_group); + ret = EC_POINT_oct2point(ec_group, point, k, k_len, NULL); + ret = EC_KEY_set_public_key(ec_key, point); + + if(point != NULL) + EC_POINT_free(point); + + if(ec_ctx != NULL) + *ec_ctx = ec_key; + } + + return (ret == 1) ? 0 : -1; +} + +#define LIBSSH2_ECDSA_VERIFY(digest_type) \ +{ \ + unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \ + libssh2_sha##digest_type(m, m_len, hash); \ + ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH, \ + ecdsa_sig, ec_key); \ + \ +} + +int +_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx, + const unsigned char *r, size_t r_len, + const unsigned char *s, size_t s_len, + const unsigned char *m, size_t m_len) +{ + int ret = 0; + EC_KEY *ec_key = (EC_KEY*)ctx; + libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_key); + +#ifdef HAVE_OPAQUE_STRUCTS + ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new(); + BIGNUM *pr = BN_new(); + BIGNUM *ps = BN_new(); + + BN_bin2bn(r, r_len, pr); + BN_bin2bn(s, s_len, ps); + ECDSA_SIG_set0(ecdsa_sig, pr, ps); + +#else + ECDSA_SIG ecdsa_sig_; + ECDSA_SIG *ecdsa_sig = &ecdsa_sig_; + ecdsa_sig_.r = BN_new(); + BN_bin2bn(r, r_len, ecdsa_sig_.r); + ecdsa_sig_.s = BN_new(); + BN_bin2bn(s, s_len, ecdsa_sig_.s); +#endif + + if(type == LIBSSH2_EC_CURVE_NISTP256) { + LIBSSH2_ECDSA_VERIFY(256); + } + else if(type == LIBSSH2_EC_CURVE_NISTP384) { + LIBSSH2_ECDSA_VERIFY(384); + } + else if(type == LIBSSH2_EC_CURVE_NISTP521) { + LIBSSH2_ECDSA_VERIFY(512); + } + +#ifdef HAVE_OPAQUE_STRUCTS + if(ecdsa_sig) + ECDSA_SIG_free(ecdsa_sig); +#else + BN_clear_free(ecdsa_sig_.s); + BN_clear_free(ecdsa_sig_.r); +#endif + + return (ret == 1) ? 0 : -1; +} + +#endif /* LIBSSH2_ECDSA */ + +int +_libssh2_cipher_init(_libssh2_cipher_ctx * h, + _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *h = EVP_CIPHER_CTX_new(); + return !EVP_CipherInit(*h, algo(), secret, iv, encrypt); +#else + EVP_CIPHER_CTX_init(h); + return !EVP_CipherInit(h, algo(), secret, iv, encrypt); +#endif +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize) +{ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; + int ret; + (void) algo; + (void) encrypt; + +#ifdef HAVE_OPAQUE_STRUCTS + ret = EVP_Cipher(*ctx, buf, block, blocksize); +#else + ret = EVP_Cipher(ctx, buf, block, blocksize); +#endif + if(ret == 1) { + memcpy(block, buf, blocksize); + } + return ret == 1 ? 0 : 1; +} + +#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) + +#include +#include + +typedef struct +{ + AES_KEY key; + EVP_CIPHER_CTX *aes_ctx; + unsigned char ctr[AES_BLOCK_SIZE]; +} aes_ctr_ctx; + +static EVP_CIPHER * aes_128_ctr_cipher = NULL; +static EVP_CIPHER * aes_192_ctr_cipher = NULL; +static EVP_CIPHER * aes_256_ctr_cipher = NULL; + +static int +aes_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) /* init key */ +{ + /* + * variable "c" is leaked from this scope, but is later freed + * in aes_ctr_cleanup + */ + aes_ctr_ctx *c; + const EVP_CIPHER *aes_cipher; + (void) enc; + + switch(EVP_CIPHER_CTX_key_length(ctx)) { + case 16: + aes_cipher = EVP_aes_128_ecb(); + break; + case 24: + aes_cipher = EVP_aes_192_ecb(); + break; + case 32: + aes_cipher = EVP_aes_256_ecb(); + break; + default: + return 0; + } + + c = malloc(sizeof(*c)); + if(c == NULL) + return 0; + +#ifdef HAVE_OPAQUE_STRUCTS + c->aes_ctx = EVP_CIPHER_CTX_new(); +#else + c->aes_ctx = malloc(sizeof(EVP_CIPHER_CTX)); +#endif + if(c->aes_ctx == NULL) { + free(c); + return 0; + } + + if(EVP_EncryptInit(c->aes_ctx, aes_cipher, key, NULL) != 1) { +#ifdef HAVE_OPAQUE_STRUCTS + EVP_CIPHER_CTX_free(c->aes_ctx); +#else + free(c->aes_ctx); +#endif + free(c); + return 0; + } + + EVP_CIPHER_CTX_set_padding(c->aes_ctx, 0); + + memcpy(c->ctr, iv, AES_BLOCK_SIZE); + + EVP_CIPHER_CTX_set_app_data(ctx, c); + + return 1; +} + +static int +aes_ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, + size_t inl) /* encrypt/decrypt data */ +{ + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + unsigned char b1[AES_BLOCK_SIZE]; + int outlen = 0; + + if(inl != 16) /* libssh2 only ever encrypt one block */ + return 0; + + if(c == NULL) { + return 0; + } + +/* + To encrypt a packet P=P1||P2||...||Pn (where P1, P2, ..., Pn are each + blocks of length L), the encryptor first encrypts with + to obtain a block B1. The block B1 is then XORed with P1 to generate + the ciphertext block C1. The counter X is then incremented +*/ + + if(EVP_EncryptUpdate(c->aes_ctx, b1, &outlen, + c->ctr, AES_BLOCK_SIZE) != 1) { + return 0; + } + + _libssh2_xor_data(out, in, b1, AES_BLOCK_SIZE); + _libssh2_aes_ctr_increment(c->ctr, AES_BLOCK_SIZE); + + return 1; +} + +static int +aes_ctr_cleanup(EVP_CIPHER_CTX *ctx) /* cleanup ctx */ +{ + aes_ctr_ctx *c = EVP_CIPHER_CTX_get_app_data(ctx); + + if(c == NULL) { + return 1; + } + + if(c->aes_ctx != NULL) { +#ifdef HAVE_OPAQUE_STRUCTS + EVP_CIPHER_CTX_free(c->aes_ctx); +#else + _libssh2_cipher_dtor(c->aes_ctx); + free(c->aes_ctx); +#endif + } + + free(c); + + return 1; +} + +static const EVP_CIPHER * +make_ctr_evp (size_t keylen, EVP_CIPHER **aes_ctr_cipher, int type) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *aes_ctr_cipher = EVP_CIPHER_meth_new(type, 16, keylen); + if(*aes_ctr_cipher) { + EVP_CIPHER_meth_set_iv_length(*aes_ctr_cipher, 16); + EVP_CIPHER_meth_set_init(*aes_ctr_cipher, aes_ctr_init); + EVP_CIPHER_meth_set_do_cipher(*aes_ctr_cipher, aes_ctr_do_cipher); + EVP_CIPHER_meth_set_cleanup(*aes_ctr_cipher, aes_ctr_cleanup); + } +#else + (*aes_ctr_cipher)->nid = type; + (*aes_ctr_cipher)->block_size = 16; + (*aes_ctr_cipher)->key_len = keylen; + (*aes_ctr_cipher)->iv_len = 16; + (*aes_ctr_cipher)->init = aes_ctr_init; + (*aes_ctr_cipher)->do_cipher = aes_ctr_do_cipher; + (*aes_ctr_cipher)->cleanup = aes_ctr_cleanup; +#endif + + return *aes_ctr_cipher; +} + +const EVP_CIPHER * +_libssh2_EVP_aes_128_ctr(void) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return !aes_128_ctr_cipher ? + make_ctr_evp(16, &aes_128_ctr_cipher, NID_aes_128_ctr) : + aes_128_ctr_cipher; +#else + static EVP_CIPHER aes_ctr_cipher; + if(!aes_128_ctr_cipher) { + aes_128_ctr_cipher = &aes_ctr_cipher; + make_ctr_evp(16, &aes_128_ctr_cipher, 0); + } + return aes_128_ctr_cipher; +#endif +} + +const EVP_CIPHER * +_libssh2_EVP_aes_192_ctr(void) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return !aes_192_ctr_cipher ? + make_ctr_evp(24, &aes_192_ctr_cipher, NID_aes_192_ctr) : + aes_192_ctr_cipher; +#else + static EVP_CIPHER aes_ctr_cipher; + if(!aes_192_ctr_cipher) { + aes_192_ctr_cipher = &aes_ctr_cipher; + make_ctr_evp(24, &aes_192_ctr_cipher, 0); + } + return aes_192_ctr_cipher; +#endif +} + +const EVP_CIPHER * +_libssh2_EVP_aes_256_ctr(void) +{ +#ifdef HAVE_OPAQUE_STRUCTS + return !aes_256_ctr_cipher ? + make_ctr_evp(32, &aes_256_ctr_cipher, NID_aes_256_ctr) : + aes_256_ctr_cipher; +#else + static EVP_CIPHER aes_ctr_cipher; + if(!aes_256_ctr_cipher) { + aes_256_ctr_cipher = &aes_ctr_cipher; + make_ctr_evp(32, &aes_256_ctr_cipher, 0); + } + return aes_256_ctr_cipher; +#endif +} + +#endif /* LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) */ + +void _libssh2_openssl_crypto_init(void) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \ + !defined(LIBRESSL_VERSION_NUMBER) +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); +#endif +#else + OpenSSL_add_all_algorithms(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); + ENGINE_register_all_complete(); +#endif +#endif +#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) + aes_128_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_128_ctr(); + aes_192_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_192_ctr(); + aes_256_ctr_cipher = (EVP_CIPHER *) _libssh2_EVP_aes_256_ctr(); +#endif +} + +void _libssh2_openssl_crypto_exit(void) +{ +#if LIBSSH2_AES_CTR && !defined(HAVE_EVP_AES_128_CTR) +#ifdef HAVE_OPAQUE_STRUCTS + if(aes_128_ctr_cipher) { + EVP_CIPHER_meth_free(aes_128_ctr_cipher); + } + + if(aes_192_ctr_cipher) { + EVP_CIPHER_meth_free(aes_192_ctr_cipher); + } + + if(aes_256_ctr_cipher) { + EVP_CIPHER_meth_free(aes_256_ctr_cipher); + } +#endif + + aes_128_ctr_cipher = NULL; + aes_192_ctr_cipher = NULL; + aes_256_ctr_cipher = NULL; +#endif +} + +/* TODO: Optionally call a passphrase callback specified by the + * calling program + */ +static int +passphrase_cb(char *buf, int size, int rwflag, char *passphrase) +{ + int passphrase_len = strlen(passphrase); + (void) rwflag; + + if(passphrase_len > (size - 1)) { + passphrase_len = size - 1; + } + memcpy(buf, passphrase, passphrase_len); + buf[passphrase_len] = '\0'; + + return passphrase_len; +} + +typedef void * (*pem_read_bio_func)(BIO *, void **, pem_password_cb *, + void *u); + +static int +read_private_key_from_memory(void **key_ctx, + pem_read_bio_func read_private_key, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + BIO * bp; + + *key_ctx = NULL; + + bp = BIO_new_mem_buf((char *)filedata, filedata_len); + if(!bp) { + return -1; + } + *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, + (void *) passphrase); + + BIO_free(bp); + return (*key_ctx) ? 0 : -1; +} + + + +static int +read_private_key_from_file(void **key_ctx, + pem_read_bio_func read_private_key, + const char *filename, + unsigned const char *passphrase) +{ + BIO * bp; + + *key_ctx = NULL; + + bp = BIO_new_file(filename, "r"); + if(!bp) { + return -1; + } + + *key_ctx = read_private_key(bp, NULL, (pem_password_cb *) passphrase_cb, + (void *) passphrase); + + BIO_free(bp); + return (*key_ctx) ? 0 : -1; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + int rc; + + pem_read_bio_func read_rsa = + (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; + + _libssh2_init_if_needed(); + + rc = read_private_key_from_memory((void **) rsa, read_rsa, + filedata, filedata_len, passphrase); + + if(rc) { + rc = read_openssh_private_key_from_memory((void **)rsa, session, + "ssh-rsa", filedata, filedata_len, passphrase); + } + +return rc; +} + +static unsigned char * +gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa, + size_t *key_len) +{ + int e_bytes, n_bytes; + unsigned long len; + unsigned char *key; + unsigned char *p; + const BIGNUM * e; + const BIGNUM * n; +#ifdef HAVE_OPAQUE_STRUCTS + RSA_get0_key(rsa, &n, &e, NULL); +#else + e = rsa->e; + n = rsa->n; +#endif + e_bytes = BN_num_bytes(e) + 1; + n_bytes = BN_num_bytes(n) + 1; + + /* Key form is "ssh-rsa" + e + n. */ + len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; + + key = LIBSSH2_ALLOC(session, len); + if(key == NULL) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-rsa", 7); + p += 7; + + p = write_bn(p, e, e_bytes); + p = write_bn(p, n, n_bytes); + + *key_len = (size_t)(p - key); + return key; +} + +static int +gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + RSA* rsa = NULL; + unsigned char *key; + unsigned char *method_buf = NULL; + size_t key_len; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from RSA private key envelope"); + + rsa = EVP_PKEY_get1_RSA(pk); + if(rsa == NULL) { + /* Assume memory allocation error... what else could it be ? */ + goto __alloc_error; + } + + method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-rsa. */ + if(method_buf == NULL) { + goto __alloc_error; + } + + key = gen_publickey_from_rsa(session, rsa, &key_len); + if(key == NULL) { + goto __alloc_error; + } + RSA_free(rsa); + + memcpy(method_buf, "ssh-rsa", 7); + *method = method_buf; + *method_len = 7; + *pubkeydata = key; + *pubkeydata_len = key_len; + return 0; + + __alloc_error: + if(rsa != NULL) { + RSA_free(rsa); + } + if(method_buf != NULL) { + LIBSSH2_FREE(session, method_buf); + } + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} + +static int _libssh2_rsa_new_additional_parameters(RSA *rsa) +{ + BN_CTX *ctx = NULL; + BIGNUM *aux = NULL; + BIGNUM *dmp1 = NULL; + BIGNUM *dmq1 = NULL; + const BIGNUM *p = NULL; + const BIGNUM *q = NULL; + const BIGNUM *d = NULL; + int rc = 0; + +#ifdef HAVE_OPAQUE_STRUCTS + RSA_get0_key(rsa, NULL, NULL, &d); + RSA_get0_factors(rsa, &p, &q); +#else + d = (*rsa).d; + p = (*rsa).p; + q = (*rsa).q; +#endif + + ctx = BN_CTX_new(); + if(ctx == NULL) + return -1; + + aux = BN_new(); + if(aux == NULL) { + rc = -1; + goto out; + } + + dmp1 = BN_new(); + if(dmp1 == NULL) { + rc = -1; + goto out; + } + + dmq1 = BN_new(); + if(dmq1 == NULL) { + rc = -1; + goto out; + } + + if((BN_sub(aux, q, BN_value_one()) == 0) || + (BN_mod(dmq1, d, aux, ctx) == 0) || + (BN_sub(aux, p, BN_value_one()) == 0) || + (BN_mod(dmp1, d, aux, ctx) == 0)) { + rc = -1; + goto out; + } + +#ifdef HAVE_OPAQUE_STRUCTS + RSA_set0_crt_params(rsa, dmp1, dmq1, NULL); +#else + (*rsa).dmp1 = dmp1; + (*rsa).dmq1 = dmq1; +#endif + +out: + if(aux) + BN_clear_free(aux); + BN_CTX_free(ctx); + + if(rc != 0) { + if(dmp1) + BN_clear_free(dmp1); + if(dmq1) + BN_clear_free(dmq1); + } + + return rc; +} + +static int +gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session, + struct string_buf *decrypted, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + libssh2_rsa_ctx **rsa_ctx) +{ + int rc = 0; + size_t nlen, elen, dlen, plen, qlen, coefflen, commentlen; + unsigned char *n, *e, *d, *p, *q, *coeff, *comment; + RSA *rsa = NULL; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing RSA keys from private key data"); + + /* public key data */ + if(_libssh2_get_bignum_bytes(decrypted, &n, &nlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no n"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &e, &elen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no e"); + return -1; + } + + /* private key data */ + if(_libssh2_get_bignum_bytes(decrypted, &d, &dlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no d"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &coeff, &coefflen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no coeff"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no p"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no q"); + return -1; + } + + if(_libssh2_get_string(decrypted, &comment, &commentlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "RSA no comment"); + return -1; + } + + if((rc = _libssh2_rsa_new(&rsa, e, elen, n, nlen, d, dlen, p, plen, + q, qlen, NULL, 0, NULL, 0, + coeff, coefflen)) != 0) { + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Could not create RSA private key"); + goto fail; + } + + if(rsa != NULL) + rc = _libssh2_rsa_new_additional_parameters(rsa); + + if(rsa != NULL && pubkeydata != NULL && method != NULL) { + EVP_PKEY *pk = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(pk, rsa); + + rc = gen_publickey_from_rsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, + pk); + + if(pk) + EVP_PKEY_free(pk); + } + + if(rsa_ctx != NULL) + *rsa_ctx = rsa; + else + RSA_free(rsa); + + return rc; + +fail: + + if(rsa != NULL) + RSA_free(rsa); + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} + +static int +_libssh2_rsa_new_openssh_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase) +{ + FILE *fp; + int rc; + unsigned char *buf = NULL; + struct string_buf *decrypted = NULL; + + if(session == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Session is required"); + return -1; + } + + _libssh2_init_if_needed(); + + fp = fopen(filename, "r"); + if(!fp) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open OpenSSH RSA private key file"); + return -1; + } + + rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); + fclose(fp); + if(rc) { + return rc; + } + + /* We have a new key file, now try and parse it using supported types */ + rc = _libssh2_get_string(decrypted, &buf, NULL); + + if(rc != 0 || buf == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Public key type in decrypted key data not found"); + return -1; + } + + if(strcmp("ssh-rsa", (const char *)buf) == 0) { + rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted, + NULL, 0, + NULL, 0, rsa); + } + else { + rc = -1; + } + + if(decrypted) + _libssh2_string_buf_free(session, decrypted); + + return rc; +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + int rc; + + pem_read_bio_func read_rsa = + (pem_read_bio_func) &PEM_read_bio_RSAPrivateKey; + + _libssh2_init_if_needed(); + + rc = read_private_key_from_file((void **) rsa, read_rsa, + filename, passphrase); + + if(rc) { + rc = _libssh2_rsa_new_openssh_private(rsa, session, + filename, passphrase); + } + + return rc; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + int rc; + + pem_read_bio_func read_dsa = + (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; + + _libssh2_init_if_needed(); + + rc = read_private_key_from_memory((void **)dsa, read_dsa, + filedata, filedata_len, passphrase); + + if(rc) { + rc = read_openssh_private_key_from_memory((void **)dsa, session, + "ssh-dsa", filedata, filedata_len, passphrase); + } + + return rc; +} + +static unsigned char * +gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa, + size_t *key_len) +{ + int p_bytes, q_bytes, g_bytes, k_bytes; + unsigned long len; + unsigned char *key; + unsigned char *p; + + const BIGNUM * p_bn; + const BIGNUM * q; + const BIGNUM * g; + const BIGNUM * pub_key; +#ifdef HAVE_OPAQUE_STRUCTS + DSA_get0_pqg(dsa, &p_bn, &q, &g); +#else + p_bn = dsa->p; + q = dsa->q; + g = dsa->g; +#endif + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_get0_key(dsa, &pub_key, NULL); +#else + pub_key = dsa->pub_key; +#endif + p_bytes = BN_num_bytes(p_bn) + 1; + q_bytes = BN_num_bytes(q) + 1; + g_bytes = BN_num_bytes(g) + 1; + k_bytes = BN_num_bytes(pub_key) + 1; + + /* Key form is "ssh-dss" + p + q + g + pub_key. */ + len = 4 + 7 + 4 + p_bytes + 4 + q_bytes + 4 + g_bytes + 4 + k_bytes; + + key = LIBSSH2_ALLOC(session, len); + if(key == NULL) { + return NULL; + } + + /* Process key encoding. */ + p = key; + + _libssh2_htonu32(p, 7); /* Key type. */ + p += 4; + memcpy(p, "ssh-dss", 7); + p += 7; + + p = write_bn(p, p_bn, p_bytes); + p = write_bn(p, q, q_bytes); + p = write_bn(p, g, g_bytes); + p = write_bn(p, pub_key, k_bytes); + + *key_len = (size_t)(p - key); + return key; +} + +static int +gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + DSA* dsa = NULL; + unsigned char *key; + unsigned char *method_buf = NULL; + size_t key_len; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from DSA private key envelope"); + + dsa = EVP_PKEY_get1_DSA(pk); + if(dsa == NULL) { + /* Assume memory allocation error... what else could it be ? */ + goto __alloc_error; + } + + method_buf = LIBSSH2_ALLOC(session, 7); /* ssh-dss. */ + if(method_buf == NULL) { + goto __alloc_error; + } + + key = gen_publickey_from_dsa(session, dsa, &key_len); + if(key == NULL) { + goto __alloc_error; + } + DSA_free(dsa); + + memcpy(method_buf, "ssh-dss", 7); + *method = method_buf; + *method_len = 7; + *pubkeydata = key; + *pubkeydata_len = key_len; + return 0; + + __alloc_error: + if(dsa != NULL) { + DSA_free(dsa); + } + if(method_buf != NULL) { + LIBSSH2_FREE(session, method_buf); + } + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} + +static int +gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session, + struct string_buf *decrypted, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + libssh2_dsa_ctx **dsa_ctx) +{ + int rc = 0; + size_t plen, qlen, glen, pub_len, priv_len; + unsigned char *p, *q, *g, *pub_key, *priv_key; + DSA *dsa = NULL; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing DSA keys from private key data"); + + if(_libssh2_get_bignum_bytes(decrypted, &p, &plen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "DSA no p"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &q, &qlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "DSA no q"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &g, &glen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "DSA no g"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &pub_key, &pub_len)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "DSA no public key"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &priv_key, &priv_len)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "DSA no private key"); + return -1; + } + + rc = _libssh2_dsa_new(&dsa, p, plen, q, qlen, g, glen, pub_key, pub_len, + priv_key, priv_len); + if(rc != 0) { + _libssh2_debug(session, + LIBSSH2_ERROR_PROTO, + "Could not create DSA private key"); + goto fail; + } + + if(dsa != NULL && pubkeydata != NULL && method != NULL) { + EVP_PKEY *pk = EVP_PKEY_new(); + EVP_PKEY_set1_DSA(pk, dsa); + + rc = gen_publickey_from_dsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, + pk); + + if(pk) + EVP_PKEY_free(pk); + } + + if(dsa_ctx != NULL) + *dsa_ctx = dsa; + else + DSA_free(dsa); + + return rc; + +fail: + + if(dsa != NULL) + DSA_free(dsa); + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); +} + +static int +_libssh2_dsa_new_openssh_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase) +{ + FILE *fp; + int rc; + unsigned char *buf = NULL; + struct string_buf *decrypted = NULL; + + if(session == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Session is required"); + return -1; + } + + _libssh2_init_if_needed(); + + fp = fopen(filename, "r"); + if(!fp) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open OpenSSH DSA private key file"); + return -1; + } + + rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); + fclose(fp); + if(rc) { + return rc; + } + + /* We have a new key file, now try and parse it using supported types */ + rc = _libssh2_get_string(decrypted, &buf, NULL); + + if(rc != 0 || buf == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Public key type in decrypted key data not found"); + return -1; + } + + if(strcmp("ssh-dss", (const char *)buf) == 0) { + rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted, + NULL, 0, + NULL, 0, dsa); + } + else { + rc = -1; + } + + if(decrypted) + _libssh2_string_buf_free(session, decrypted); + + return rc; +} + +int +_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + int rc; + + pem_read_bio_func read_dsa = + (pem_read_bio_func) &PEM_read_bio_DSAPrivateKey; + + _libssh2_init_if_needed(); + + rc = read_private_key_from_file((void **) dsa, read_dsa, + filename, passphrase); + + if(rc) { + rc = _libssh2_dsa_new_openssh_private(dsa, session, + filename, passphrase); + } + + return rc; +} + +#endif /* LIBSSH_DSA */ + +#if LIBSSH2_ECDSA + +int +_libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx, + LIBSSH2_SESSION * session, + const char *filedata, size_t filedata_len, + unsigned const char *passphrase) +{ + int rc; + + pem_read_bio_func read_ec = + (pem_read_bio_func) &PEM_read_bio_ECPrivateKey; + + _libssh2_init_if_needed(); + + rc = read_private_key_from_memory((void **) ec_ctx, read_ec, + filedata, filedata_len, passphrase); + + if(rc) { + rc = read_openssh_private_key_from_memory((void **)ec_ctx, session, + "ssh-ecdsa", filedata, + filedata_len, passphrase); + } + + return rc; +} + +#endif /* LIBSSH2_ECDSA */ + + +#if LIBSSH2_ED25519 + +int +_libssh2_curve25519_new(LIBSSH2_SESSION *session, libssh2_x25519_ctx **out_ctx, + unsigned char **out_public_key, + unsigned char **out_private_key) +{ + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *pctx = NULL; + PKCS8_PRIV_KEY_INFO *info = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_PUBKEY *pubkey = NULL; + libssh2_ed25519_ctx *ctx = NULL; + const unsigned char *pkcs, *priv, *pub; + int privLen, pubLen, pkcsLen; + int rc = -1; + + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_X25519, NULL); + if(pctx == NULL) + return -1; + + EVP_PKEY_keygen_init(pctx); + EVP_PKEY_keygen(pctx, &key); + info = EVP_PKEY2PKCS8(key); + + if(info == NULL || !PKCS8_pkey_get0(NULL, &pkcs, &pkcsLen, NULL, info)) + goto cleanExit; + + oct = d2i_ASN1_OCTET_STRING(NULL, &pkcs, pkcsLen); + if(oct == NULL) { + goto cleanExit; + } + + priv = ASN1_STRING_get0_data(oct); + privLen = ASN1_STRING_length(oct); + + if(privLen != LIBSSH2_ED25519_KEY_LEN) + goto cleanExit; + + pubkey = X509_PUBKEY_new(); + if(pubkey == NULL || !X509_PUBKEY_set(&pubkey, key)) + goto cleanExit; + + if(!X509_PUBKEY_get0_param(NULL, &pub, &pubLen, NULL, pubkey)) + goto cleanExit; + + if(pubLen != LIBSSH2_ED25519_KEY_LEN) + goto cleanExit; + + if(out_private_key != NULL) { + *out_private_key = LIBSSH2_ALLOC(session, LIBSSH2_ED25519_KEY_LEN); + if(*out_private_key == NULL) + goto cleanExit; + + memcpy(*out_private_key, priv, LIBSSH2_ED25519_KEY_LEN); + } + + if(out_public_key != NULL) { + *out_public_key = LIBSSH2_ALLOC(session, LIBSSH2_ED25519_KEY_LEN); + if(*out_public_key == NULL) + goto cleanExit; + + memcpy(*out_public_key, pub, LIBSSH2_ED25519_KEY_LEN); + } + + if(out_ctx != NULL) { + ctx = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, priv, + LIBSSH2_ED25519_KEY_LEN); + if(!ctx) + goto cleanExit; + + *out_ctx = ctx; + } + + /* success */ + rc = 0; + +cleanExit: + + if(info) + PKCS8_PRIV_KEY_INFO_free(info); + if(pctx) + EVP_PKEY_CTX_free(pctx); + if(oct) + ASN1_OCTET_STRING_free(oct); + if(pubkey) + X509_PUBKEY_free(pubkey); + if(key) + EVP_PKEY_free(key); + + return rc; +} + + +static int +gen_publickey_from_ed_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + const char methodName[] = "ssh-ed25519"; + unsigned char *methodBuf = NULL; + size_t rawKeyLen = 0; + unsigned char *keyBuf = NULL; + size_t bufLen = 0; + unsigned char *bufPos = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Computing public key from ED private key envelope"); + + methodBuf = LIBSSH2_ALLOC(session, sizeof(methodName) - 1); + if(!methodBuf) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); + goto fail; + } + memcpy(methodBuf, methodName, sizeof(methodName) - 1); + + if(EVP_PKEY_get_raw_public_key(pk, NULL, &rawKeyLen) != 1) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "EVP_PKEY_get_raw_public_key failed"); + goto fail; + } + + /* Key form is: type_len(4) + type(11) + pub_key_len(4) + pub_key(32). */ + bufLen = 4 + sizeof(methodName) - 1 + 4 + rawKeyLen; + bufPos = keyBuf = LIBSSH2_ALLOC(session, bufLen); + if(!keyBuf) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); + goto fail; + } + + _libssh2_store_str(&bufPos, methodName, sizeof(methodName) - 1); + _libssh2_store_u32(&bufPos, rawKeyLen); + + if(EVP_PKEY_get_raw_public_key(pk, bufPos, &rawKeyLen) != 1) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "EVP_PKEY_get_raw_public_key failed"); + goto fail; + } + + *method = methodBuf; + *method_len = sizeof(methodName) - 1; + *pubkeydata = keyBuf; + *pubkeydata_len = bufLen; + return 0; + +fail: + if(methodBuf) + LIBSSH2_FREE(session, methodBuf); + if(keyBuf) + LIBSSH2_FREE(session, keyBuf); + return -1; +} + + +static int +gen_publickey_from_ed25519_openssh_priv_data(LIBSSH2_SESSION *session, + struct string_buf *decrypted, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + libssh2_ed25519_ctx **out_ctx) +{ + libssh2_ed25519_ctx *ctx = NULL; + unsigned char *method_buf = NULL; + unsigned char *key = NULL; + int i, ret = 0; + unsigned char *pub_key, *priv_key, *buf; + size_t key_len = 0, tmp_len = 0; + unsigned char *p; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing ED25519 keys from private key data"); + + if(_libssh2_get_string(decrypted, &pub_key, &tmp_len) || + tmp_len != LIBSSH2_ED25519_KEY_LEN) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Wrong public key length"); + return -1; + } + + if(_libssh2_get_string(decrypted, &priv_key, &tmp_len) || + tmp_len != LIBSSH2_ED25519_PRIVATE_KEY_LEN) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Wrong private key length"); + ret = -1; + goto clean_exit; + } + + /* first 32 bytes of priv_key is the private key, the last 32 bytes are + the public key */ + ctx = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, + (const unsigned char *)priv_key, + LIBSSH2_ED25519_KEY_LEN); + + /* comment */ + if(_libssh2_get_string(decrypted, &buf, &tmp_len)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unable to read comment"); + ret = -1; + goto clean_exit; + } + + if(tmp_len > 0) { + unsigned char *comment = LIBSSH2_CALLOC(session, tmp_len + 1); + if(comment != NULL) { + memcpy(comment, buf, tmp_len); + memcpy(comment + tmp_len, "\0", 1); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Key comment: %s", + comment); + + LIBSSH2_FREE(session, comment); + } + } + + /* Padding */ + i = 1; + while(decrypted->dataptr < decrypted->data + decrypted->len) { + if(*decrypted->dataptr != i) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Wrong padding"); + ret = -1; + goto clean_exit; + } + i++; + decrypted->dataptr++; + } + + if(ret == 0) { + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from ED25519 " + "private key envelope"); + + method_buf = LIBSSH2_ALLOC(session, 11); /* ssh-ed25519. */ + if(method_buf == NULL) { + goto clean_exit; + } + + /* Key form is: type_len(4) + type(11) + pub_key_len(4) + + pub_key(32). */ + key_len = LIBSSH2_ED25519_KEY_LEN + 19; + key = LIBSSH2_CALLOC(session, key_len); + if(key == NULL) { + goto clean_exit; + } + + p = key; + + _libssh2_store_str(&p, "ssh-ed25519", 11); + _libssh2_store_str(&p, (const char *)pub_key, LIBSSH2_ED25519_KEY_LEN); + + memcpy(method_buf, "ssh-ed25519", 11); + + if(method != NULL) + *method = method_buf; + else + LIBSSH2_FREE(session, method_buf); + + if(method_len != NULL) + *method_len = 11; + + if(pubkeydata != NULL) + *pubkeydata = key; + else + LIBSSH2_FREE(session, key); + + if(pubkeydata_len != NULL) + *pubkeydata_len = key_len; + + if(out_ctx != NULL) + *out_ctx = ctx; + else if(ctx != NULL) + _libssh2_ed25519_free(ctx); + + return 0; + } + +clean_exit: + + if(ctx) + _libssh2_ed25519_free(ctx); + + if(method_buf) + LIBSSH2_FREE(session, method_buf); + + if(key) + LIBSSH2_FREE(session, key); + + return -1; +} + +int +_libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx, + LIBSSH2_SESSION * session, + const char *filename, const uint8_t *passphrase) +{ + int rc; + FILE *fp; + unsigned char *buf; + struct string_buf *decrypted = NULL; + libssh2_ed25519_ctx *ctx = NULL; + + if(session == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Session is required"); + return -1; + } + + _libssh2_init_if_needed(); + + fp = fopen(filename, "r"); + if(!fp) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open ED25519 private key file"); + return -1; + } + + rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); + fclose(fp); + if(rc) { + return rc; + } + + /* We have a new key file, now try and parse it using supported types */ + rc = _libssh2_get_string(decrypted, &buf, NULL); + + if(rc != 0 || buf == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Public key type in decrypted key data not found"); + return -1; + } + + if(strcmp("ssh-ed25519", (const char *)buf) == 0) { + rc = gen_publickey_from_ed25519_openssh_priv_data(session, + decrypted, + NULL, + NULL, + NULL, + NULL, + &ctx); + } + else { + rc = -1; + } + + if(decrypted) + _libssh2_string_buf_free(session, decrypted); + + if(rc == 0) { + if(ed_ctx != NULL) + *ed_ctx = ctx; + else if(ctx != NULL) + _libssh2_ed25519_free(ctx); + } + + return rc; +} + +int +_libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx ** ed_ctx, + LIBSSH2_SESSION * session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + libssh2_ed25519_ctx *ctx = NULL; + + _libssh2_init_if_needed(); + + if(read_private_key_from_memory((void **)&ctx, + (pem_read_bio_func) + &PEM_read_bio_PrivateKey, + filedata, filedata_len, passphrase) == 0) { + if(EVP_PKEY_id(ctx) != EVP_PKEY_ED25519) { + _libssh2_ed25519_free(ctx); + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Private key is not an ED25519 key"); + } + + *ed_ctx = ctx; + return 0; + } + + return read_openssh_private_key_from_memory((void **)ed_ctx, session, + "ssh-ed25519", + filedata, filedata_len, + passphrase); +} + +int +_libssh2_ed25519_new_public(libssh2_ed25519_ctx ** ed_ctx, + LIBSSH2_SESSION * session, + const unsigned char *raw_pub_key, + const uint8_t key_len) +{ + libssh2_ed25519_ctx *ctx = NULL; + + if(ed_ctx == NULL) + return -1; + + ctx = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, + raw_pub_key, key_len); + if(!ctx) + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "could not create ED25519 public key"); + + if(ed_ctx != NULL) + *ed_ctx = ctx; + else if(ctx) + _libssh2_ed25519_free(ctx); + + return 0; +} +#endif /* LIBSSH2_ED25519 */ + + +int +_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session, + libssh2_rsa_ctx * rsactx, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, size_t *signature_len) +{ + int ret; + unsigned char *sig; + unsigned int sig_len; + + sig_len = RSA_size(rsactx); + sig = LIBSSH2_ALLOC(session, sig_len); + + if(!sig) { + return -1; + } + + ret = RSA_sign(NID_sha1, hash, hash_len, sig, &sig_len, rsactx); + + if(!ret) { + LIBSSH2_FREE(session, sig); + return -1; + } + + *signature = sig; + *signature_len = sig_len; + + return 0; +} + +#if LIBSSH2_DSA +int +_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx, + const unsigned char *hash, + unsigned long hash_len, unsigned char *signature) +{ + DSA_SIG *sig; + const BIGNUM * r; + const BIGNUM * s; + int r_len, s_len; + (void) hash_len; + + sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx); + if(!sig) { + return -1; + } + +#ifdef HAVE_OPAQUE_STRUCTS + DSA_SIG_get0(sig, &r, &s); +#else + r = sig->r; + s = sig->s; +#endif + r_len = BN_num_bytes(r); + if(r_len < 1 || r_len > 20) { + DSA_SIG_free(sig); + return -1; + } + s_len = BN_num_bytes(s); + if(s_len < 1 || s_len > 20) { + DSA_SIG_free(sig); + return -1; + } + + memset(signature, 0, 40); + + BN_bn2bin(r, signature + (20 - r_len)); + BN_bn2bin(s, signature + 20 + (20 - s_len)); + + DSA_SIG_free(sig); + + return 0; +} +#endif /* LIBSSH_DSA */ + +#if LIBSSH2_ECDSA + +int +_libssh2_ecdsa_sign(LIBSSH2_SESSION * session, libssh2_ecdsa_ctx * ec_ctx, + const unsigned char *hash, unsigned long hash_len, + unsigned char **signature, size_t *signature_len) +{ + int r_len, s_len; + int rc = 0; + size_t out_buffer_len = 0; + unsigned char *sp; + const BIGNUM *pr = NULL, *ps = NULL; + unsigned char *temp_buffer = NULL; + unsigned char *out_buffer = NULL; + + ECDSA_SIG *sig = ECDSA_do_sign(hash, hash_len, ec_ctx); + if(sig == NULL) + return -1; +#ifdef HAVE_OPAQUE_STRUCTS + ECDSA_SIG_get0(sig, &pr, &ps); +#else + pr = sig->r; + ps = sig->s; +#endif + + r_len = BN_num_bytes(pr) + 1; + s_len = BN_num_bytes(ps) + 1; + + temp_buffer = malloc(r_len + s_len + 8); + if(temp_buffer == NULL) { + rc = -1; + goto clean_exit; + } + + sp = temp_buffer; + sp = write_bn(sp, pr, r_len); + sp = write_bn(sp, ps, s_len); + + out_buffer_len = (size_t)(sp - temp_buffer); + + out_buffer = LIBSSH2_CALLOC(session, out_buffer_len); + if(out_buffer == NULL) { + rc = -1; + goto clean_exit; + } + + memcpy(out_buffer, temp_buffer, out_buffer_len); + + *signature = out_buffer; + *signature_len = out_buffer_len; + +clean_exit: + + if(temp_buffer != NULL) + free(temp_buffer); + + if(sig) + ECDSA_SIG_free(sig); + + return rc; +} +#endif /* LIBSSH2_ECDSA */ + +int +_libssh2_sha1_init(libssh2_sha1_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if(*ctx == NULL) + return 0; + + if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha1"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha1")); +#endif +} + +int +_libssh2_sha1(const unsigned char *message, unsigned long len, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + EVP_MD_CTX * ctx = EVP_MD_CTX_new(); + + if(ctx == NULL) + return 1; /* error */ + + if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha1"))) { + EVP_DigestUpdate(ctx, message, len); + EVP_DigestFinal(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return 0; /* success */ + } + EVP_MD_CTX_free(ctx); +#else + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha1"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } +#endif + return 1; /* error */ +} + +int +_libssh2_sha256_init(libssh2_sha256_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if(*ctx == NULL) + return 0; + + if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha256"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha256")); +#endif +} + +int +_libssh2_sha256(const unsigned char *message, unsigned long len, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + EVP_MD_CTX * ctx = EVP_MD_CTX_new(); + + if(ctx == NULL) + return 1; /* error */ + + if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha256"))) { + EVP_DigestUpdate(ctx, message, len); + EVP_DigestFinal(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return 0; /* success */ + } + EVP_MD_CTX_free(ctx); +#else + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha256"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } +#endif + return 1; /* error */ +} + +int +_libssh2_sha384_init(libssh2_sha384_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if(*ctx == NULL) + return 0; + + if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha384"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha384")); +#endif +} + +int +_libssh2_sha384(const unsigned char *message, unsigned long len, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + EVP_MD_CTX * ctx = EVP_MD_CTX_new(); + + if(ctx == NULL) + return 1; /* error */ + + if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha384"))) { + EVP_DigestUpdate(ctx, message, len); + EVP_DigestFinal(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return 0; /* success */ + } + EVP_MD_CTX_free(ctx); +#else + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha384"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } +#endif + return 1; /* error */ +} + +int +_libssh2_sha512_init(libssh2_sha512_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if(*ctx == NULL) + return 0; + + if(EVP_DigestInit(*ctx, EVP_get_digestbyname("sha512"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("sha512")); +#endif +} + +int +_libssh2_sha512(const unsigned char *message, unsigned long len, + unsigned char *out) +{ +#ifdef HAVE_OPAQUE_STRUCTS + EVP_MD_CTX * ctx = EVP_MD_CTX_new(); + + if(ctx == NULL) + return 1; /* error */ + + if(EVP_DigestInit(ctx, EVP_get_digestbyname("sha512"))) { + EVP_DigestUpdate(ctx, message, len); + EVP_DigestFinal(ctx, out, NULL); + EVP_MD_CTX_free(ctx); + return 0; /* success */ + } + EVP_MD_CTX_free(ctx); +#else + EVP_MD_CTX ctx; + + EVP_MD_CTX_init(&ctx); + if(EVP_DigestInit(&ctx, EVP_get_digestbyname("sha512"))) { + EVP_DigestUpdate(&ctx, message, len); + EVP_DigestFinal(&ctx, out, NULL); + return 0; /* success */ + } +#endif + return 1; /* error */ +} + +int +_libssh2_md5_init(libssh2_md5_ctx *ctx) +{ +#ifdef HAVE_OPAQUE_STRUCTS + *ctx = EVP_MD_CTX_new(); + + if(*ctx == NULL) + return 0; + + if(EVP_DigestInit(*ctx, EVP_get_digestbyname("md5"))) + return 1; + + EVP_MD_CTX_free(*ctx); + *ctx = NULL; + + return 0; +#else + EVP_MD_CTX_init(ctx); + return EVP_DigestInit(ctx, EVP_get_digestbyname("md5")); +#endif +} + +#if LIBSSH2_ECDSA + +static int +gen_publickey_from_ec_evp(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + EVP_PKEY *pk) +{ + int rc = 0; + EC_KEY *ec = NULL; + unsigned char *p; + unsigned char *method_buf = NULL; + unsigned char *key; + size_t key_len = 0; + unsigned char *octal_value = NULL; + size_t octal_len; + const EC_POINT *public_key; + const EC_GROUP *group; + BN_CTX *bn_ctx; + libssh2_curve_type type; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from EC private key envelope"); + + bn_ctx = BN_CTX_new(); + if(bn_ctx == NULL) + return -1; + + ec = EVP_PKEY_get1_EC_KEY(pk); + if(ec == NULL) { + rc = -1; + goto clean_exit; + } + + public_key = EC_KEY_get0_public_key(ec); + group = EC_KEY_get0_group(ec); + type = _libssh2_ecdsa_get_curve_type(ec); + + method_buf = LIBSSH2_ALLOC(session, 19); + if(method_buf == NULL) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "out of memory"); + } + + if(type == LIBSSH2_EC_CURVE_NISTP256) + memcpy(method_buf, "ecdsa-sha2-nistp256", 19); + else if(type == LIBSSH2_EC_CURVE_NISTP384) + memcpy(method_buf, "ecdsa-sha2-nistp384", 19); + else if(type == LIBSSH2_EC_CURVE_NISTP521) + memcpy(method_buf, "ecdsa-sha2-nistp521", 19); + else { + _libssh2_debug(session, + LIBSSH2_TRACE_ERROR, + "Unsupported EC private key type"); + rc = -1; + goto clean_exit; + } + + /* get length */ + octal_len = EC_POINT_point2oct(group, public_key, + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, bn_ctx); + if(octal_len > EC_MAX_POINT_LEN) { + rc = -1; + goto clean_exit; + } + + octal_value = malloc(octal_len); + if(octal_value == NULL) { + rc = -1; + goto clean_exit; + } + + /* convert to octal */ + if(EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, + octal_value, octal_len, bn_ctx) != octal_len) { + rc = -1; + goto clean_exit; + } + + /* Key form is: type_len(4) + type(19) + domain_len(4) + domain(8) + + pub_key_len(4) + pub_key(~65). */ + key_len = 4 + 19 + 4 + 8 + 4 + octal_len; + key = LIBSSH2_ALLOC(session, key_len); + if(key == NULL) { + rc = -1; + goto clean_exit; + } + + /* Process key encoding. */ + p = key; + + /* Key type */ + _libssh2_store_str(&p, (const char *)method_buf, 19); + + /* Name domain */ + _libssh2_store_str(&p, (const char *)method_buf + 11, 8); + + /* Public key */ + _libssh2_store_str(&p, (const char *)octal_value, octal_len); + + *method = method_buf; + *method_len = 19; + *pubkeydata = key; + *pubkeydata_len = key_len; + +clean_exit: + + if(ec != NULL) + EC_KEY_free(ec); + + if(bn_ctx != NULL) { + BN_CTX_free(bn_ctx); + } + + if(octal_value != NULL) + free(octal_value); + + if(rc == 0) + return 0; + + if(method_buf != NULL) + LIBSSH2_FREE(session, method_buf); + + return -1; +} + +static int +gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session, + libssh2_curve_type curve_type, + struct string_buf *decrypted, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + libssh2_ecdsa_ctx **ec_ctx) +{ + int rc = 0; + size_t curvelen, exponentlen, pointlen; + unsigned char *curve, *exponent, *point_buf; + EC_KEY *ec_key = NULL; + BIGNUM *bn_exponent; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing ECDSA keys from private key data"); + + if(_libssh2_get_string(decrypted, &curve, &curvelen) || + curvelen == 0) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "ECDSA no curve"); + return -1; + } + + if(_libssh2_get_string(decrypted, &point_buf, &pointlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "ECDSA no point"); + return -1; + } + + if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "ECDSA no exponent"); + return -1; + } + + if((rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key, point_buf, + pointlen, curve_type)) != 0) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "ECDSA could not create key"); + goto fail; + } + + bn_exponent = BN_new(); + if(bn_exponent == NULL) { + rc = -1; + goto fail; + } + + BN_bin2bn(exponent, exponentlen, bn_exponent); + rc = (EC_KEY_set_private_key(ec_key, bn_exponent) != 1); + + if(rc == 0 && ec_key != NULL && pubkeydata != NULL && method != NULL) { + EVP_PKEY *pk = EVP_PKEY_new(); + EVP_PKEY_set1_EC_KEY(pk, ec_key); + + rc = gen_publickey_from_ec_evp(session, method, method_len, + pubkeydata, pubkeydata_len, + pk); + + if(pk) + EVP_PKEY_free(pk); + } + + if(ec_ctx != NULL) + *ec_ctx = ec_key; + else + EC_KEY_free(ec_key); + + return rc; + +fail: + + if(ec_key != NULL) + EC_KEY_free(ec_key); + + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for private key data"); + + +} + +static int +_libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx ** ec_ctx, + LIBSSH2_SESSION * session, + const char *filename, + unsigned const char *passphrase) +{ + FILE *fp; + int rc; + unsigned char *buf = NULL; + libssh2_curve_type type; + struct string_buf *decrypted = NULL; + + if(session == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Session is required"); + return -1; + } + + _libssh2_init_if_needed(); + + fp = fopen(filename, "r"); + if(!fp) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open OpenSSH ECDSA private key file"); + return -1; + } + + rc = _libssh2_openssh_pem_parse(session, passphrase, fp, &decrypted); + fclose(fp); + if(rc) { + return rc; + } + + /* We have a new key file, now try and parse it using supported types */ + rc = _libssh2_get_string(decrypted, &buf, NULL); + + if(rc != 0 || buf == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Public key type in decrypted key data not found"); + return -1; + } + + rc = _libssh2_ecdsa_curve_type_from_name((const char *)buf, &type); + + if(rc == 0) { + rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type, + decrypted, NULL, 0, + NULL, 0, ec_ctx); + } + else { + rc = -1; + } + + if(decrypted) + _libssh2_string_buf_free(session, decrypted); + + return rc; +} + +int +_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx, + LIBSSH2_SESSION * session, + const char *filename, unsigned const char *passphrase) +{ + int rc; + + pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey; + + _libssh2_init_if_needed(); + + rc = read_private_key_from_file((void **) ec_ctx, read_ec, + filename, passphrase); + + if(rc) { + return _libssh2_ecdsa_new_openssh_private(ec_ctx, session, + filename, passphrase); + } + + return rc; +} + +/* + * _libssh2_ecdsa_create_key + * + * Creates a local private key based on input curve + * and returns octal value and octal length + * + */ + +int +_libssh2_ecdsa_create_key(LIBSSH2_SESSION *session, + _libssh2_ec_key **out_private_key, + unsigned char **out_public_key_octal, + size_t *out_public_key_octal_len, + libssh2_curve_type curve_type) +{ + int ret = 1; + size_t octal_len = 0; + unsigned char octal_value[EC_MAX_POINT_LEN]; + const EC_POINT *public_key = NULL; + EC_KEY *private_key = NULL; + const EC_GROUP *group = NULL; + + /* create key */ + BN_CTX *bn_ctx = BN_CTX_new(); + if(!bn_ctx) + return -1; + + private_key = EC_KEY_new_by_curve_name(curve_type); + group = EC_KEY_get0_group(private_key); + + EC_KEY_generate_key(private_key); + public_key = EC_KEY_get0_public_key(private_key); + + /* get length */ + octal_len = EC_POINT_point2oct(group, public_key, + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, bn_ctx); + if(octal_len > EC_MAX_POINT_LEN) { + ret = -1; + goto clean_exit; + } + + /* convert to octal */ + if(EC_POINT_point2oct(group, public_key, POINT_CONVERSION_UNCOMPRESSED, + octal_value, octal_len, bn_ctx) != octal_len) { + ret = -1; + goto clean_exit; + } + + if(out_private_key != NULL) + *out_private_key = private_key; + + if(out_public_key_octal) { + *out_public_key_octal = LIBSSH2_ALLOC(session, octal_len); + if(*out_public_key_octal == NULL) { + ret = -1; + goto clean_exit; + } + + memcpy(*out_public_key_octal, octal_value, octal_len); + } + + if(out_public_key_octal_len != NULL) + *out_public_key_octal_len = octal_len; + +clean_exit: + + if(bn_ctx) + BN_CTX_free(bn_ctx); + + return (ret == 1) ? 0 : -1; +} + +/* _libssh2_ecdh_gen_k + * + * Computes the shared secret K given a local private key, + * remote public key and length + */ + +int +_libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key, + const unsigned char *server_public_key, size_t server_public_key_len) +{ + int ret = 0; + int rc; + size_t secret_len; + unsigned char *secret = NULL; + const EC_GROUP *private_key_group; + EC_POINT *server_public_key_point; + + BN_CTX *bn_ctx = BN_CTX_new(); + + if(!bn_ctx) + return -1; + + if(k == NULL) + return -1; + + private_key_group = EC_KEY_get0_group(private_key); + + server_public_key_point = EC_POINT_new(private_key_group); + if(server_public_key_point == NULL) + return -1; + + rc = EC_POINT_oct2point(private_key_group, server_public_key_point, + server_public_key, server_public_key_len, bn_ctx); + if(rc != 1) { + ret = -1; + goto clean_exit; + } + + secret_len = (EC_GROUP_get_degree(private_key_group) + 7) / 8; + secret = malloc(secret_len); + if(!secret) { + ret = -1; + goto clean_exit; + } + + secret_len = ECDH_compute_key(secret, secret_len, server_public_key_point, + private_key, NULL); + + if(secret_len <= 0 || secret_len > EC_MAX_POINT_LEN) { + ret = -1; + goto clean_exit; + } + + BN_bin2bn(secret, secret_len, *k); + +clean_exit: + + if(server_public_key_point != NULL) + EC_POINT_free(server_public_key_point); + + if(bn_ctx != NULL) + BN_CTX_free(bn_ctx); + + if(secret != NULL) + free(secret); + + return ret; +} + + +#endif /* LIBSSH2_ECDSA */ + +#if LIBSSH2_ED25519 + +int +_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session, + uint8_t **out_sig, size_t *out_sig_len, + const uint8_t *message, size_t message_len) +{ + int rc = -1; + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + size_t sig_len = 0; + unsigned char *sig = NULL; + + if(md_ctx != NULL) { + if(EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, ctx) != 1) + goto clean_exit; + if(EVP_DigestSign(md_ctx, NULL, &sig_len, message, message_len) != 1) + goto clean_exit; + + if(sig_len != LIBSSH2_ED25519_SIG_LEN) + goto clean_exit; + + sig = LIBSSH2_CALLOC(session, sig_len); + if(sig == NULL) + goto clean_exit; + + rc = EVP_DigestSign(md_ctx, sig, &sig_len, message, message_len); + } + + if(rc == 1) { + *out_sig = sig; + *out_sig_len = sig_len; + } + else { + *out_sig_len = 0; + *out_sig = NULL; + LIBSSH2_FREE(session, sig); + } + +clean_exit: + + if(md_ctx) + EVP_MD_CTX_free(md_ctx); + + return (rc == 1 ? 0 : -1); +} + +int +_libssh2_curve25519_gen_k(_libssh2_bn **k, + uint8_t private_key[LIBSSH2_ED25519_KEY_LEN], + uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]) +{ + int rc = -1; + unsigned char out_shared_key[LIBSSH2_ED25519_KEY_LEN]; + EVP_PKEY *peer_key = NULL, *server_key = NULL; + EVP_PKEY_CTX *server_key_ctx = NULL; + BN_CTX *bn_ctx = NULL; + size_t out_len = 0; + + if(k == NULL || *k == NULL) + return -1; + + bn_ctx = BN_CTX_new(); + if(bn_ctx == NULL) + return -1; + + peer_key = EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, NULL, + server_public_key, + LIBSSH2_ED25519_KEY_LEN); + + server_key = EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, NULL, + private_key, + LIBSSH2_ED25519_KEY_LEN); + + if(peer_key == NULL || server_key == NULL) { + goto cleanExit; + } + + server_key_ctx = EVP_PKEY_CTX_new(server_key, NULL); + if(server_key_ctx == NULL) { + goto cleanExit; + } + + rc = EVP_PKEY_derive_init(server_key_ctx); + if(rc <= 0) goto cleanExit; + + rc = EVP_PKEY_derive_set_peer(server_key_ctx, peer_key); + if(rc <= 0) goto cleanExit; + + rc = EVP_PKEY_derive(server_key_ctx, NULL, &out_len); + if(rc <= 0) goto cleanExit; + + if(out_len != LIBSSH2_ED25519_KEY_LEN) { + rc = -1; + goto cleanExit; + } + + rc = EVP_PKEY_derive(server_key_ctx, out_shared_key, &out_len); + + if(rc == 1 && out_len == LIBSSH2_ED25519_KEY_LEN) { + BN_bin2bn(out_shared_key, LIBSSH2_ED25519_KEY_LEN, *k); + } + else { + rc = -1; + } + +cleanExit: + + if(server_key_ctx) + EVP_PKEY_CTX_free(server_key_ctx); + if(peer_key) + EVP_PKEY_free(peer_key); + if(server_key) + EVP_PKEY_free(server_key); + if(bn_ctx != NULL) + BN_CTX_free(bn_ctx); + + return (rc == 1) ? 0 : -1; +} + + +int +_libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s, + size_t s_len, const uint8_t *m, size_t m_len) +{ + int ret = -1; + + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + if(NULL == md_ctx) + return -1; + + ret = EVP_DigestVerifyInit(md_ctx, NULL, NULL, NULL, ctx); + if(ret != 1) + goto clean_exit; + + ret = EVP_DigestVerify(md_ctx, s, s_len, m, m_len); + + clean_exit: + + EVP_MD_CTX_free(md_ctx); + + return (ret == 1) ? 0 : -1; +} + +#endif /* LIBSSH2_ED25519 */ + +static int +_libssh2_pub_priv_openssh_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + FILE *fp; + unsigned char *buf = NULL; + struct string_buf *decrypted = NULL; + int rc = 0; + + if(session == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Session is required"); + return -1; + } + + _libssh2_init_if_needed(); + + fp = fopen(privatekey, "r"); + if(!fp) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open private key file"); + return -1; + } + + rc = _libssh2_openssh_pem_parse(session, (const unsigned char *)passphrase, + fp, &decrypted); + fclose(fp); + if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Not an OpenSSH key file"); + return rc; + } + + /* We have a new key file, now try and parse it using supported types */ + rc = _libssh2_get_string(decrypted, &buf, NULL); + + if(rc != 0 || buf == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Public key type in decrypted key data not found"); + return -1; + } + + rc = -1; + +#if LIBSSH2_ED25519 + if(strcmp("ssh-ed25519", (const char *)buf) == 0) { + rc = gen_publickey_from_ed25519_openssh_priv_data(session, decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + NULL); + } +#endif +#if LIBSSH2_RSA + if(strcmp("ssh-rsa", (const char *)buf) == 0) { + rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + NULL); + } +#endif +#if LIBSSH2_DSA + if(strcmp("ssh-dss", (const char *)buf) == 0) { + rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + NULL); + } +#endif +#if LIBSSH2_ECDSA + { + libssh2_curve_type type; + + if(_libssh2_ecdsa_curve_type_from_name((const char *)buf, + &type) == 0) { + rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type, + decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + NULL); + } + } +#endif + + if(decrypted) + _libssh2_string_buf_free(session, decrypted); + + if(rc != 0) { + _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unsupported OpenSSH key type"); + } + + return rc; +} + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ + int st; + BIO* bp; + EVP_PKEY* pk; + int pktype; + int rc; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from private key file: %s", + privatekey); + + bp = BIO_new_file(privatekey, "r"); + if(bp == NULL) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key from private key " + "file: Unable to open private key file"); + } + + BIO_reset(bp); + pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase); + BIO_free(bp); + + if(pk == NULL) { + + /* Try OpenSSH format */ + rc = _libssh2_pub_priv_openssh_keyfile(session, + method, + method_len, + pubkeydata, pubkeydata_len, + privatekey, passphrase); + if(rc != 0) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Wrong passphrase or invalid/unrecognized " + "private key file format"); + } + + return 0; + } + +#ifdef HAVE_OPAQUE_STRUCTS + pktype = EVP_PKEY_id(pk); +#else + pktype = pk->type; +#endif + + switch(pktype) { +#if LIBSSH2_ED25519 + case EVP_PKEY_ED25519 : + st = gen_publickey_from_ed_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH2_ED25519 */ + case EVP_PKEY_RSA : + st = gen_publickey_from_rsa_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; + +#if LIBSSH2_DSA + case EVP_PKEY_DSA : + st = gen_publickey_from_dsa_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH_DSA */ + +#if LIBSSH2_ECDSA + case EVP_PKEY_EC : + st = gen_publickey_from_ec_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; +#endif + + default : + st = _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Unsupported private key file format"); + break; + } + + EVP_PKEY_free(pk); + return st; +} + +static int +_libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session, + void **key_ctx, + const char *key_type, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + unsigned const char *passphrase) +{ + int rc; + unsigned char *buf = NULL; + struct string_buf *decrypted = NULL; + + if(key_ctx != NULL) + *key_ctx = NULL; + + if(session == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Session is required"); + return -1; + } + + if(key_type != NULL && (strlen(key_type) > 11 || strlen(key_type) < 7)) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "type is invalid"); + return -1; + } + + _libssh2_init_if_needed(); + + rc = _libssh2_openssh_pem_parse_memory(session, passphrase, + privatekeydata, + privatekeydata_len, &decrypted); + + if(rc) { + return rc; + } + + /* We have a new key file, now try and parse it using supported types */ + rc = _libssh2_get_string(decrypted, &buf, NULL); + + if(rc != 0 || buf == NULL) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Public key type in decrypted key data not found"); + return -1; + } + + rc = -1; + +#if LIBSSH2_ED25519 + if(strcmp("ssh-ed25519", (const char *)buf) == 0) { + if(key_type == NULL || strcmp("ssh-ed25519", key_type) == 0) { + rc = gen_publickey_from_ed25519_openssh_priv_data(session, + decrypted, + method, + method_len, + pubkeydata, + pubkeydata_len, + (libssh2_ed25519_ctx**)key_ctx); + } + } +#endif +#if LIBSSH2_RSA + if(strcmp("ssh-rsa", (const char *)buf) == 0) { + if(key_type == NULL || strcmp("ssh-rsa", key_type) == 0) { + rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + (libssh2_rsa_ctx**)key_ctx); + } + } +#endif +#if LIBSSH2_DSA + if(strcmp("ssh-dss", (const char *)buf) == 0) { + if(key_type == NULL || strcmp("ssh-dss", key_type) == 0) { + rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + (libssh2_dsa_ctx**)key_ctx); + } + } +#endif +#if LIBSSH2_ECDSA +{ + libssh2_curve_type type; + + if(_libssh2_ecdsa_curve_type_from_name((const char *)buf, &type) == 0) { + if(key_type == NULL || strcmp("ssh-ecdsa", key_type) == 0) { + rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type, + decrypted, + method, method_len, + pubkeydata, + pubkeydata_len, + (libssh2_ecdsa_ctx**)key_ctx); + } + } +} +#endif + + if(decrypted) + _libssh2_string_buf_free(session, decrypted); + + return rc; +} + +int +read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session, + const char *key_type, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + return _libssh2_pub_priv_openssh_keyfilememory(session, key_ctx, key_type, + NULL, NULL, NULL, NULL, + filedata, filedata_len, + passphrase); +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + int st; + BIO* bp; + EVP_PKEY* pk; + int pktype; + + _libssh2_debug(session, + LIBSSH2_TRACE_AUTH, + "Computing public key from private key."); + + bp = BIO_new_mem_buf((char *)privatekeydata, privatekeydata_len); + if(!bp) { + return -1; + } + + BIO_reset(bp); + pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase); + BIO_free(bp); + + if(pk == NULL) { + /* Try OpenSSH format */ + st = _libssh2_pub_priv_openssh_keyfilememory(session, NULL, NULL, + method, + method_len, + pubkeydata, + pubkeydata_len, + privatekeydata, + privatekeydata_len, + (unsigned const char *)passphrase); + if(st != 0) { + return _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Wrong passphrase or invalid/unrecognized " + "private key file format"); + } + + return 0; + } + +#ifdef HAVE_OPAQUE_STRUCTS + pktype = EVP_PKEY_id(pk); +#else + pktype = pk->type; +#endif + + switch(pktype) { +#if LIBSSH2_ED25519 + case EVP_PKEY_ED25519 : + st = gen_publickey_from_ed_evp( + session, method, method_len, pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH2_ED25519 */ + case EVP_PKEY_RSA : + st = gen_publickey_from_rsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#if LIBSSH2_DSA + case EVP_PKEY_DSA : + st = gen_publickey_from_dsa_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH_DSA */ +#if LIBSSH2_ECDSA + case EVP_PKEY_EC : + st = gen_publickey_from_ec_evp(session, method, method_len, + pubkeydata, pubkeydata_len, pk); + break; +#endif /* LIBSSH2_ECDSA */ + default : + st = _libssh2_error(session, + LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key file: " + "Unsupported private key file format"); + break; + } + + EVP_PKEY_free(pk); + return st; +} + +void +_libssh2_dh_init(_libssh2_dh_ctx *dhctx) +{ + *dhctx = BN_new(); /* Random from client */ +} + +int +_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order, + _libssh2_bn_ctx *bnctx) +{ + /* Generate x and e */ + BN_rand(*dhctx, group_order * 8 - 1, 0, -1); + BN_mod_exp(public, g, *dhctx, p, bnctx); + return 0; +} + +int +_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p, + _libssh2_bn_ctx *bnctx) +{ + /* Compute the shared secret */ + BN_mod_exp(secret, f, *dhctx, p, bnctx); + return 0; +} + +void +_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) +{ + BN_clear_free(*dhctx); + *dhctx = NULL; +} + +#endif /* LIBSSH2_OPENSSL */ diff --git a/libssh2/os400qc3.c b/libssh2/os400qc3.c new file mode 100644 index 0000000..bf5acda --- /dev/null +++ b/libssh2/os400qc3.c @@ -0,0 +1,2411 @@ +/* + * Copyright (C) 2015-2016 Patrick Monnerat, D+H + * Copyright (C) 2020 Patrick Monnerat . + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_OS400QC3 /* compile only if we build with OS/400 QC3 library */ + +#ifdef HAVE_STDLIB_H +#include +#endif + +#include +#include +#include +#include + +#include + + +#ifdef OS400_DEBUG +/* In debug mode, all system library errors cause an exception. */ +#define set_EC_length(ec, length) ((ec).Bytes_Provided = \ + (ec).Bytes_Available = 0) +#else +#define set_EC_length(ec, length) ((ec).Bytes_Provided = (length)) +#endif + + +/* Ensure va_list operations are not on an array. */ +typedef struct { + va_list list; +} valiststr; + + +typedef int (*loadkeyproc)(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata); + +/* Public key extraction data. */ +typedef struct { + const char * method; + const unsigned char * data; + unsigned int length; +} loadpubkeydata; + + +/* Support for ASN.1 elements. */ + +typedef struct { + char * header; /* Pointer to header byte. */ + char * beg; /* Pointer to element data. */ + char * end; /* Pointer to 1st byte after element. */ + unsigned char class; /* ASN.1 element class. */ + unsigned char tag; /* ASN.1 element tag. */ + unsigned char constructed; /* Element is constructed. */ +} asn1Element; + +#define ASN1_INTEGER 2 +#define ASN1_BIT_STRING 3 +#define ASN1_OCTET_STRING 4 +#define ASN1_NULL 5 +#define ASN1_OBJ_ID 6 +#define ASN1_SEQ 16 + +#define ASN1_CONSTRUCTED 0x20 + +/* rsaEncryption OID: 1.2.840.113549.1.1.1 */ +static unsigned char OID_rsaEncryption[] = + {9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 1, 1}; +static int sshrsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, + asn1Element *params, asn1Element *key, + const char *method); + +#if LIBSSH2_DSA != 0 +/* dsaEncryption OID: 1.2.840.10040.4.1 */ +static unsigned char OID_dsaEncryption[] = + {7, 40 + 2, 0x86, 0x48, 0xCE, 0x38, 4, 1}; +static int sshdsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, + asn1Element *params, asn1Element *key, + const char *method); +#endif + +static unsigned char OID_dhKeyAgreement[] = + {9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 1, 3, 1}; + + +/* PKCS#5 support. */ + +typedef struct pkcs5params pkcs5params; +struct pkcs5params { + int cipher; /* Encryption cipher. */ + int blocksize; /* Cipher block size. */ + char mode; /* Block encryption mode. */ + char padopt; /* Pad option. */ + char padchar; /* Pad character. */ + int (*kdf)(LIBSSH2_SESSION *session, char **dk, + const unsigned char *passphrase, pkcs5params *pkcs5); + int hash; /* KDF hash algorithm. */ + size_t hashlen; /* KDF hash digest length. */ + char * salt; /* Salt. */ + size_t saltlen; /* Salt length. */ + char * iv; /* Initialization vector. */ + size_t ivlen; /* Initialization vector length. */ + int itercount; /* KDF iteration count. */ + int dklen; /* Derived key length (#bytes). */ + int effkeysize; /* RC2 effective key size (#bits) or 0. */ +}; + +typedef struct pkcs5algo pkcs5algo; +struct pkcs5algo { + const unsigned char * oid; + int (*parse)(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); + int cipher; /* Encryption cipher. */ + size_t blocksize; /* Cipher block size. */ + char mode; /* Block encryption mode. */ + char padopt; /* Pad option. */ + char padchar; /* Pad character. */ + size_t keylen; /* Key length (#bytes). */ + int hash; /* Hash algorithm. */ + size_t hashlen; /* Hash digest length. */ + size_t saltlen; /* Salt length. */ + size_t ivlen; /* Initialisation vector length. */ + int effkeysize; /* RC2 effective key size (#bits) or 0. */ +}; + +/* id-PBES2 OID: 1.2.840.113549.1.5.13 */ +static const unsigned char OID_id_PBES2[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D +}; +static int parse_pbes2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo PBES2 = { + OID_id_PBES2, parse_pbes2, 0, 0, '\0', '\0', '\0', 0, + 0, 0, 0, 0, 0 +}; + +/* id-PBKDF2 OID: 1.2.840.113549.1.5.12 */ +static const unsigned char OID_id_PBKDF2[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C +}; +static int parse_pbkdf2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo PBKDF2 = { + OID_id_PBKDF2, parse_pbkdf2, 0, 0, '\0', '\0', '\0', + SHA_DIGEST_LENGTH, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 8, 0 +}; + +/* id-hmacWithSHA1 OID: 1.2.840.113549.2.7 */ +static const unsigned char OID_id_hmacWithSHA1[] = { + 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x07 +}; +static int parse_hmacWithSHA1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo hmacWithSHA1 = { + OID_id_hmacWithSHA1, parse_hmacWithSHA1, 0, 0, '\0', '\0', '\0', + SHA_DIGEST_LENGTH, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 8, 0 +}; + +/* desCBC OID: 1.3.14.3.2.7 */ +static const unsigned char OID_desCBC[] = {5, 40 + 3, 0x0E, 0x03, 0x02, 0x07}; +static int parse_iv(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo desCBC = { + OID_desCBC, parse_iv, Qc3_DES, 8, Qc3_CBC, Qc3_Pad_Counter, + '\0', 8, 0, 0, 8, 8, 0 +}; + +/* des-EDE3-CBC OID: 1.2.840.113549.3.7 */ +static const unsigned char OID_des_EDE3_CBC[] = { + 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07 +}; +static const pkcs5algo des_EDE3_CBC = { + OID_des_EDE3_CBC, parse_iv, Qc3_TDES, 8, Qc3_CBC, Qc3_Pad_Counter, + '\0', 24, 0, 0, 8, 8, 0 +}; + +/* rc2CBC OID: 1.2.840.113549.3.2 */ +static const unsigned char OID_rc2CBC[] = { + 8, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x02 +}; +static int parse_rc2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo rc2CBC = { + OID_rc2CBC, parse_rc2, Qc3_RC2, 8, Qc3_CBC, Qc3_Pad_Counter, + '\0', 0, 0, 0, 8, 0, 32 +}; + +/* pbeWithMD5AndDES-CBC OID: 1.2.840.113549.1.5.3 */ +static const unsigned char OID_pbeWithMD5AndDES_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x03 +}; +static int parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param); +static const pkcs5algo pbeWithMD5AndDES_CBC = { + OID_pbeWithMD5AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 8, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 0 +}; + +/* pbeWithMD5AndRC2-CBC OID: 1.2.840.113549.1.5.6 */ +static const unsigned char OID_pbeWithMD5AndRC2_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x06 +}; +static const pkcs5algo pbeWithMD5AndRC2_CBC = { + OID_pbeWithMD5AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 0, Qc3_MD5, MD5_DIGEST_LENGTH, 8, 0, 64 +}; + +/* pbeWithSHA1AndDES-CBC OID: 1.2.840.113549.1.5.10 */ +static const unsigned char OID_pbeWithSHA1AndDES_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0A +}; +static const pkcs5algo pbeWithSHA1AndDES_CBC = { + OID_pbeWithSHA1AndDES_CBC, parse_pbes1, Qc3_DES, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 8, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 0, 0 +}; + +/* pbeWithSHA1AndRC2-CBC OID: 1.2.840.113549.1.5.11 */ +static const unsigned char OID_pbeWithSHA1AndRC2_CBC[] = { + 9, 40 + 2, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0B +}; +static const pkcs5algo pbeWithSHA1AndRC2_CBC = { + OID_pbeWithSHA1AndRC2_CBC, parse_pbes1, Qc3_RC2, 8, Qc3_CBC, + Qc3_Pad_Counter, '\0', 0, Qc3_SHA1, SHA_DIGEST_LENGTH, 8, 0, 64 +}; + +/* rc5-CBC-PAD OID: 1.2.840.113549.3.9: RC5 not implemented in Qc3. */ +/* pbeWithMD2AndDES-CBC OID: 1.2.840.113549.1.5.1: MD2 not implemented. */ +/* pbeWithMD2AndRC2-CBC OID: 1.2.840.113549.1.5.4: MD2 not implemented. */ + +static const pkcs5algo * pbestable[] = { + &pbeWithMD5AndDES_CBC, + &pbeWithMD5AndRC2_CBC, + &pbeWithSHA1AndDES_CBC, + &pbeWithSHA1AndRC2_CBC, + &PBES2, + NULL +}; + +static const pkcs5algo * pbkdf2table[] = { + &PBKDF2, + NULL +}; + +static const pkcs5algo * pbes2enctable[] = { + &desCBC, + &des_EDE3_CBC, + &rc2CBC, + NULL +}; + +static const pkcs5algo * kdf2prftable[] = { + &hmacWithSHA1, + NULL +}; + + +/* Public key extraction support. */ +static struct { + unsigned char *oid; + int (*sshpubkey)(LIBSSH2_SESSION *session, char **pubkey, + asn1Element *params, asn1Element *key, + const char *method); + const char * method; +} pka[] = { +#if LIBSSH2_RSA != 0 + { OID_rsaEncryption, sshrsapubkey, "ssh-rsa" }, +#endif +#if LIBSSH2_DSA != 0 + { OID_dsaEncryption, sshdsapubkey, "ssh-dss" }, +#endif + { NULL, NULL, NULL } +}; + +/* Define ASCII strings. */ +static const char beginencprivkeyhdr[] = + "-----BEGIN ENCRYPTED PRIVATE KEY-----"; +static const char endencprivkeyhdr[] = "-----END ENCRYPTED PRIVATE KEY-----"; +static const char beginprivkeyhdr[] = "-----BEGIN PRIVATE KEY-----"; +static const char endprivkeyhdr[] = "-----END PRIVATE KEY-----"; +static const char beginrsaprivkeyhdr[] = "-----BEGIN RSA PRIVATE KEY-----"; +static const char endrsaprivkeyhdr[] = "-----END RSA PRIVATE KEY-----"; +static const char fopenrmode[] = "r"; +static const char fopenrbmode[] = "rb"; + + +/* The rest of character literals in this module are in EBCDIC. */ +#pragma convert(37) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static Qc3_Format_KEYD0100_T nulltoken = {""}; + +static int zero = 0; +static int rsaprivate[] = { Qc3_RSA_Private }; +static char anycsp[] = { Qc3_Any_CSP }; +static char binstring[] = { Qc3_Bin_String }; +static char berstring[] = { Qc3_BER_String }; +static char qc3clear[] = { Qc3_Clear }; + +static const Qus_EC_t ecnull = {0}; /* Error causes an exception. */ + +static asn1Element lastbytebitcount = { + (char *) &zero, NULL, (char *) &zero + 1 +}; + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: ASN.1 support. + * + *******************************************************************/ + +static char * +getASN1Element(asn1Element *elem, char *beg, char *end) +{ + unsigned char b; + unsigned long len; + asn1Element lelem; + + /* Get a single ASN.1 element into `elem', parse ASN.1 string at `beg' + * ending at `end'. + * Returns a pointer in source string after the parsed element, or NULL + * if an error occurs. + */ + + if(beg >= end || !*beg) + return NULL; + + /* Process header byte. */ + elem->header = beg; + b = (unsigned char) *beg++; + elem->constructed = (b & 0x20) != 0; + elem->class = (b >> 6) & 3; + b &= 0x1F; + if(b == 0x1F) + return NULL; /* Long tag values not supported here. */ + elem->tag = b; + + /* Process length. */ + if(beg >= end) + return NULL; + b = (unsigned char) *beg++; + if(!(b & 0x80)) + len = b; + else if(!(b &= 0x7F)) { + /* Unspecified length. Since we have all the data, we can determine the + * effective length by skipping element until an end element is + * found. + */ + if(!elem->constructed) + return NULL; + elem->beg = beg; + while(beg < end && *beg) { + beg = getASN1Element(&lelem, beg, end); + if(!beg) + return NULL; + } + if(beg >= end) + return NULL; + elem->end = beg; + return beg + 1; + } + else if(beg + b > end) + return NULL; /* Does not fit in source. */ + else { + /* Get long length. */ + len = 0; + do { + if(len & 0xFF000000L) + return NULL; /* Lengths > 32 bits are not supported. */ + len = (len << 8) | (unsigned char) *beg++; + } while(--b); + } + if((unsigned long) (end - beg) < len) + return NULL; /* Element data does not fit in source. */ + elem->beg = beg; + elem->end = beg + len; + return elem->end; +} + +static asn1Element * +asn1_new(unsigned int type, unsigned int length) +{ + asn1Element *e; + unsigned int hdrl = 2; + unsigned int i; + unsigned char *buf; + + e = (asn1Element *) malloc(sizeof *e); + + if(e) { + if(length >= 0x80) + for(i = length; i; i >>= 8) + hdrl++; + + buf = (unsigned char *) malloc(hdrl + length); + + if(buf) { + e->header = buf; + e->beg = buf + hdrl; + e->end = e->beg + length; + e->class = (type >> 6) & 0x03; + e->tag = type & 0x1F; + e->constructed = (type >> 5) & 0x01; + e->header[0] = type; + + if(length < 0x80) + e->header[1] = length; + else { + e->header[1] = (hdrl - 2) | 0x80; + do { + e->header[--hdrl] = length; + length >>= 8; + } while(length); + } + } + else { + free((char *) e); + e = NULL; + } + } + + return e; +} + +static asn1Element * +asn1_new_from_bytes(const unsigned char *data, unsigned int length) +{ + asn1Element *e; + asn1Element te; + + getASN1Element(&te, + (unsigned char *) data, (unsigned char *) data + length); + e = asn1_new(te.tag, te.end - te.beg); + + if(e) + memcpy(e->header, data, e->end - e->header); + + return e; +} + +static void +asn1delete(asn1Element *e) +{ + if(e) { + if(e->header) + free((char *) e->header); + free((char *) e); + } +} + +static asn1Element * +asn1uint(_libssh2_bn *bn) +{ + asn1Element *e; + int bits; + int length; + unsigned char *p; + + if(!bn) + return NULL; + + bits = _libssh2_bn_bits(bn); + length = (bits + 8) >> 3; + e = asn1_new(ASN1_INTEGER, length); + + if(e) { + p = e->beg; + if(!(bits & 0x07)) + *p++ = 0; + _libssh2_bn_to_bin(bn, p); + } + + return e; +} + +static asn1Element * +asn1containerv(unsigned int type, valiststr args) +{ + valiststr va; + asn1Element *e; + asn1Element *p; + unsigned char *bp; + unsigned int length = 0; + + memcpy((char *) &va, (char *) &args, sizeof args); + while((p = va_arg(va.list, asn1Element *))) + length += p->end - p->header; + va_end(va.list); + e = asn1_new(type, length); + if(e) { + bp = e->beg; + while((p = va_arg(args.list, asn1Element *))) { + memcpy(bp, p->header, p->end - p->header); + bp += p->end - p->header; + } + } + return e; +} + +/* VARARGS1 */ +static asn1Element * +asn1container(unsigned int type, ...) +{ + valiststr va; + asn1Element *e; + + va_start(va.list, type); + e = asn1containerv(type, va); + va_end(va.list); + return e; +} + +static asn1Element * +asn1bytes(unsigned int type, const unsigned char *bytes, unsigned int length) +{ + asn1Element *e; + + e = asn1_new(type, length); + if(e && length) + memcpy(e->beg, bytes, length); + return e; +} + +static asn1Element * +rsapublickey(_libssh2_bn *e, _libssh2_bn *m) +{ + asn1Element *publicexponent; + asn1Element *modulus; + asn1Element *rsapubkey; + + /* Build a PKCS#1 RSAPublicKey. */ + + modulus = asn1uint(m); + publicexponent = asn1uint(e); + rsapubkey = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + modulus, publicexponent, NULL); + asn1delete(modulus); + asn1delete(publicexponent); + + if(!modulus || !publicexponent) { + asn1delete(rsapubkey); + rsapubkey = NULL; + } + + return rsapubkey; +} + +static asn1Element * +rsaprivatekey(_libssh2_bn *e, _libssh2_bn *m, _libssh2_bn *d, + _libssh2_bn *p, _libssh2_bn *q, + _libssh2_bn *exp1, _libssh2_bn *exp2, _libssh2_bn *coeff) +{ + asn1Element *version; + asn1Element *modulus; + asn1Element *publicexponent; + asn1Element *privateexponent; + asn1Element *prime1; + asn1Element *prime2; + asn1Element *exponent1; + asn1Element *exponent2; + asn1Element *coefficient; + asn1Element *rsaprivkey; + + /* Build a PKCS#1 RSAPrivateKey. */ + version = asn1bytes(ASN1_INTEGER, "\0", 1); + modulus = asn1uint(m); + publicexponent = asn1uint(e); + privateexponent = asn1uint(d); + prime1 = asn1uint(p); + prime2 = asn1uint(q); + exponent1 = asn1uint(exp1); + exponent2 = asn1uint(exp2); + coefficient = asn1uint(coeff); + rsaprivkey = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, version, modulus, + publicexponent, privateexponent, prime1, prime2, + exponent1, exponent2, coefficient, NULL); + asn1delete(version); + asn1delete(modulus); + asn1delete(publicexponent); + asn1delete(privateexponent); + asn1delete(prime1); + asn1delete(prime2); + asn1delete(exponent1); + asn1delete(exponent2); + asn1delete(coefficient); + + if(!version || !modulus || !publicexponent || !privateexponent || + !prime1 || !prime2 || !exponent1 || !exponent2 || !coefficient) { + asn1delete(rsaprivkey); + rsaprivkey = NULL; + } + + return rsaprivkey; +} + +static asn1Element * +subjectpublickeyinfo(asn1Element *pubkey, const unsigned char *algo, + asn1Element *parameters) +{ + asn1Element *subjpubkey; + asn1Element *algorithm; + asn1Element *algorithmid; + asn1Element *subjpubkeyinfo; + unsigned int algosize = *algo++; + + algorithm = asn1bytes(ASN1_OBJ_ID, algo, algosize); + algorithmid = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + algorithm, parameters, NULL); + subjpubkey = asn1container(ASN1_BIT_STRING, &lastbytebitcount, + pubkey, NULL); + subjpubkeyinfo = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + algorithmid, subjpubkey, NULL); + asn1delete(algorithm); + asn1delete(algorithmid); + asn1delete(subjpubkey); + if(!algorithm || !algorithmid || !subjpubkey) { + asn1delete(subjpubkeyinfo); + subjpubkeyinfo = NULL; + } + return subjpubkeyinfo; +} + +static asn1Element * +rsasubjectpublickeyinfo(asn1Element *pubkey) +{ + asn1Element *parameters; + asn1Element *subjpubkeyinfo; + + parameters = asn1bytes(ASN1_NULL, NULL, 0); + subjpubkeyinfo = subjectpublickeyinfo(pubkey, + OID_rsaEncryption, parameters); + asn1delete(parameters); + if(!parameters) { + asn1delete(subjpubkeyinfo); + subjpubkeyinfo = NULL; + } + return subjpubkeyinfo; +} + +static asn1Element * +privatekeyinfo(asn1Element *privkey, const unsigned char *algo, + asn1Element *parameters) +{ + asn1Element *version; + asn1Element *privatekey; + asn1Element *algorithm; + asn1Element *privatekeyalgorithm; + asn1Element *privkeyinfo; + unsigned int algosize = *algo++; + + /* Build a PKCS#8 PrivateKeyInfo. */ + version = asn1bytes(ASN1_INTEGER, "\0", 1); + algorithm = asn1bytes(ASN1_OBJ_ID, algo, algosize); + privatekeyalgorithm = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + algorithm, parameters, NULL); + privatekey = asn1container(ASN1_OCTET_STRING, privkey, NULL); + privkeyinfo = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, version, + privatekeyalgorithm, privatekey, NULL); + asn1delete(version); + asn1delete(algorithm); + asn1delete(privatekeyalgorithm); + if(!version || !algorithm || !privatekeyalgorithm) { + asn1delete(privkeyinfo); + privkeyinfo = NULL; + } + return privkeyinfo; +} + +static asn1Element * +rsaprivatekeyinfo(asn1Element *privkey) +{ + asn1Element *parameters; + asn1Element *privkeyinfo; + + parameters = asn1bytes(ASN1_NULL, NULL, 0); + privkeyinfo = privatekeyinfo(privkey, OID_rsaEncryption, parameters); + asn1delete(parameters); + if(!parameters) { + asn1delete(privkeyinfo); + privkeyinfo = NULL; + } + return privkeyinfo; +} + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: big numbers support. + * + *******************************************************************/ + + +_libssh2_bn * +_libssh2_bn_init(void) +{ + _libssh2_bn *bignum; + + bignum = (_libssh2_bn *) malloc(sizeof *bignum); + if(bignum) { + bignum->bignum = NULL; + bignum->length = 0; + } + + return bignum; +} + +void +_libssh2_bn_free(_libssh2_bn *bn) +{ + if(bn) { + if(bn->bignum) { +#ifdef LIBSSH2_CLEAR_MEMORY + if(bn->length) + memset((char *) bn->bignum, 0, bn->length); +#endif + free(bn->bignum); + } + + free((char *) bn); + } +} + +static int +_libssh2_bn_resize(_libssh2_bn *bn, size_t newlen) +{ + unsigned char *bignum; + + if(!bn) + return -1; + if(newlen == bn->length) + return 0; + + if(!bn->bignum) + bignum = (unsigned char *) malloc(newlen); + else { +#ifdef LIBSSH2_CLEAR_MEMORY + if(newlen < bn->length) + memset((char *) bn->bignum + newlen, 0, bn->length - newlen); +#endif + if(!newlen) { + free((char *) bn->bignum); + bn->bignum = NULL; + bn->length = 0; + return 0; + } + bignum = (unsigned char *) realloc((char *) bn->bignum, newlen); + } + + if(!bignum) + return -1; + + if(newlen > bn->length) + memset((char *) bignum + bn->length, 0, newlen - bn->length); + + bn->bignum = bignum; + bn->length = newlen; + return 0; +} + +unsigned long +_libssh2_bn_bits(_libssh2_bn *bn) +{ + unsigned int i; + unsigned char b; + + if(bn && bn->bignum) { + for(i = bn->length; i--;) + b = bn->bignum[i]; + if(b) { + i *= 8; + do { + i++; + } while(b >>= 1); + return i; + } + } + + return 0; +} + +int +_libssh2_bn_from_bin(_libssh2_bn *bn, int len, const unsigned char *val) +{ + int i; + + if(!bn || (len && !val)) + return -1; + + for(; len && !*val; len--) + val++; + + if(_libssh2_bn_resize(bn, len)) + return -1; + + for(i = len; i--;) + bn->bignum[i] = *val++; + + return 0; +} + +int +_libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val) +{ + val = htonl(val); + return _libssh2_bn_from_bin(bn, sizeof val, (unsigned char *) &val); +} + +int +_libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val) +{ + int i; + + if(!bn || !val) + return -1; + + for(i = bn->length; i--;) + *val++ = bn->bignum[i]; + + return 0; +} + +static int +_libssh2_bn_from_bn(_libssh2_bn *to, _libssh2_bn *from) +{ + int i; + + if(!to || !from) + return -1; + + if(_libssh2_bn_resize(to, from->length)) + return -1; + + for(i = to->length; i--;) + to->bignum[i] = from->bignum[i]; + + return 0; +} + +void +_libssh2_random(unsigned char *buf, int len) +{ + Qc3GenPRNs(buf, len, + Qc3PRN_TYPE_NORMAL, Qc3PRN_NO_PARITY, (char *) &ecnull); +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: crypto context support. + * + *******************************************************************/ + +static _libssh2_os400qc3_crypto_ctx * +libssh2_init_crypto_ctx(_libssh2_os400qc3_crypto_ctx *ctx) +{ + if(!ctx) + ctx = (_libssh2_os400qc3_crypto_ctx *) malloc(sizeof *ctx); + + if(ctx) { + memset((char *) ctx, 0, sizeof *ctx); + ctx->hash.Final_Op_Flag = Qc3_Continue; + } + + return ctx; +} + +static int +null_token(const char *token) +{ + return !memcmp(token, nulltoken.Key_Context_Token, + sizeof nulltoken.Key_Context_Token); +} + +void +_libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x) +{ + if(!x) + return; + if(!null_token(x->hash.Alg_Context_Token)) { + Qc3DestroyAlgorithmContext(x->hash.Alg_Context_Token, + (char *) &ecnull); + memset(x->hash.Alg_Context_Token, 0, sizeof x->hash.Alg_Context_Token); + } + if(!null_token(x->key.Key_Context_Token)) { + Qc3DestroyKeyContext(x->key.Key_Context_Token, (char *) &ecnull); + memset(x->key.Key_Context_Token, 0, sizeof x->key.Key_Context_Token); + } + if(x->kek) { + _libssh2_os400qc3_crypto_dtor(x->kek); + free((char *) x->kek); + x->kek = NULL; + } +} + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: hash algorithms support. + * + *******************************************************************/ + +int +libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x, unsigned int algorithm) +{ + Qc3_Format_ALGD0500_T algd; + Qus_EC_t errcode; + + if(!x) + return 0; + + memset((char *) x, 0, sizeof *x); + x->Final_Op_Flag = Qc3_Continue; + algd.Hash_Alg = algorithm; + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Hash, + x->Alg_Context_Token, &errcode); + return errcode.Bytes_Available? 0: 1; +} + +void +libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx, + const unsigned char *data, int len) +{ + char dummy[64]; + + ctx->Final_Op_Flag = Qc3_Continue; + Qc3CalculateHash((char *) data, &len, Qc3_Data, (char *) ctx, + Qc3_Alg_Token, anycsp, NULL, dummy, (char *) &ecnull); +} + +void +libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx, unsigned char *out) +{ + char data; + + ctx->Final_Op_Flag = Qc3_Final; + Qc3CalculateHash(&data, &zero, Qc3_Data, (char *) ctx, Qc3_Alg_Token, + anycsp, NULL, (char *) out, (char *) &ecnull); + Qc3DestroyAlgorithmContext(ctx->Alg_Context_Token, (char *) &ecnull); + memset(ctx->Alg_Context_Token, 0, sizeof ctx->Alg_Context_Token); +} + +int +libssh2_os400qc3_hash(const unsigned char *message, unsigned long len, + unsigned char *out, unsigned int algo) +{ + Qc3_Format_ALGD0100_T ctx; + + if(!libssh2_os400qc3_hash_init(&ctx, algo)) + return 1; + + libssh2_os400qc3_hash_update(&ctx, message, len); + libssh2_os400qc3_hash_final(&ctx, out); + return 0; +} + +void +libssh2_os400qc3_hmac_init(_libssh2_os400qc3_crypto_ctx *ctx, + int algo, size_t minkeylen, void *key, int keylen) +{ + if(keylen < minkeylen) { + char *lkey = alloca(minkeylen); + + /* Pad key with zeroes if too short. */ + if(!lkey) + return; + memcpy(lkey, (char *) key, keylen); + memset(lkey + keylen, 0, minkeylen - keylen); + key = (void *) lkey; + keylen = minkeylen; + } + libssh2_os400qc3_hash_init(&ctx->hash, algo); + Qc3CreateKeyContext((char *) key, &keylen, binstring, &algo, qc3clear, + NULL, NULL, ctx->key.Key_Context_Token, + (char *) &ecnull); +} + +void +libssh2_os400qc3_hmac_update(_libssh2_os400qc3_crypto_ctx *ctx, + unsigned char *data, int len) +{ + char dummy[64]; + + ctx->hash.Final_Op_Flag = Qc3_Continue; + Qc3CalculateHMAC((char *) data, &len, Qc3_Data, (char *) &ctx->hash, + Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, + anycsp, NULL, dummy, (char *) &ecnull); +} + +void +libssh2_os400qc3_hmac_final(_libssh2_os400qc3_crypto_ctx *ctx, + unsigned char *out) +{ + char data; + + ctx->hash.Final_Op_Flag = Qc3_Final; + Qc3CalculateHMAC((char *) data, &zero, Qc3_Data, (char *) &ctx->hash, + Qc3_Alg_Token, ctx->key.Key_Context_Token, Qc3_Key_Token, + anycsp, NULL, (char *) out, (char *) &ecnull); +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: cipher algorithms support. + * + *******************************************************************/ + +int +_libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), + unsigned char *iv, unsigned char *secret, int encrypt) +{ + Qc3_Format_ALGD0200_T algd; + Qus_EC_t errcode; + + (void) encrypt; + + if(!h) + return -1; + + libssh2_init_crypto_ctx(h); + algd.Block_Cipher_Alg = algo.algo; + algd.Block_Length = algo.size; + algd.Mode = algo.mode; + algd.Pad_Option = Qc3_No_Pad; + algd.Pad_Character = 0; + algd.Reserved = 0; + algd.MAC_Length = 0; + algd.Effective_Key_Size = 0; + memset(algd.Init_Vector, 0, sizeof algd.Init_Vector); + if(algo.mode != Qc3_ECB && algo.size) + memcpy(algd.Init_Vector, iv, algo.size); + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, algo.fmt, + h->hash.Alg_Context_Token, &errcode); + if(errcode.Bytes_Available) + return -1; + Qc3CreateKeyContext((char *) secret, &algo.keylen, binstring, + &algo.algo, qc3clear, NULL, NULL, + h->key.Key_Context_Token, (char *) &errcode); + if(errcode.Bytes_Available) { + _libssh2_os400qc3_crypto_dtor(h); + return -1; + } + + return 0; +} + +int +_libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(algo), + int encrypt, unsigned char *block, size_t blocksize) +{ + Qus_EC_t errcode; + int outlen; + int blksize = blocksize; + + (void) algo; + + set_EC_length(errcode, sizeof errcode); + if(encrypt) + Qc3EncryptData((char *) block, &blksize, Qc3_Data, + ctx->hash.Alg_Context_Token, Qc3_Alg_Token, + ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, + (char *) block, &blksize, &outlen, (char *) &errcode); + else + Qc3DecryptData((char *) block, &blksize, + ctx->hash.Alg_Context_Token, Qc3_Alg_Token, + ctx->key.Key_Context_Token, Qc3_Key_Token, anycsp, NULL, + (char *) block, &blksize, &outlen, (char *) &errcode); + + return errcode.Bytes_Available? -1: 0; +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: RSA support. + * + *******************************************************************/ + +int +_libssh2_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, unsigned long elen, + const unsigned char *ndata, unsigned long nlen, + const unsigned char *ddata, unsigned long dlen, + const unsigned char *pdata, unsigned long plen, + const unsigned char *qdata, unsigned long qlen, + const unsigned char *e1data, unsigned long e1len, + const unsigned char *e2data, unsigned long e2len, + const unsigned char *coeffdata, unsigned long coefflen) +{ + libssh2_rsa_ctx *ctx; + _libssh2_bn *e = _libssh2_bn_init_from_bin(); + _libssh2_bn *n = _libssh2_bn_init_from_bin(); + _libssh2_bn *d = NULL; + _libssh2_bn *p = NULL; + _libssh2_bn *q = NULL; + _libssh2_bn *e1 = NULL; + _libssh2_bn *e2 = NULL; + _libssh2_bn *coeff = NULL; + asn1Element *key = NULL; + asn1Element *structkey = NULL; + Qc3_Format_ALGD0400_T algd; + Qus_EC_t errcode; + int keytype; + int ret = 0; + int i; + + ctx = libssh2_init_crypto_ctx(NULL); + if(!ctx) + ret = -1; + if(!ret) { + _libssh2_bn_from_bin(e, elen, edata); + _libssh2_bn_from_bin(n, nlen, ndata); + if(!e || !n) + ret = -1; + } + if(!ret && ddata) { + /* Private key. */ + d = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(d, dlen, ddata); + p = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(p, plen, pdata); + q = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(q, qlen, qdata); + e1 = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(e1, e1len, e1data); + e2 = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(e2, e2len, e2data); + coeff = _libssh2_bn_init_from_bin(); + _libssh2_bn_from_bin(coeff, coefflen, coeffdata); + if(!d || !p || !q ||!e1 || !e2 || !coeff) + ret = -1; + + if(!ret) { + /* Build a PKCS#8 private key. */ + key = rsaprivatekey(e, n, d, p, q, e1, e2, coeff); + structkey = rsaprivatekeyinfo(key); + } + keytype = Qc3_RSA_Private; + } + else if(!ret) { + key = rsapublickey(e, n); + structkey = rsasubjectpublickeyinfo(key); + keytype = Qc3_RSA_Public; + } + if(!key || !structkey) + ret = -1; + + set_EC_length(errcode, sizeof errcode); + + if(!ret) { + /* Create the algorithm context. */ + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_PKCS1_01; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = Qc3_SHA1; + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Public_Key, + ctx->hash.Alg_Context_Token, &errcode); + if(errcode.Bytes_Available) + ret = -1; + ctx->hash.Final_Op_Flag = Qc3_Continue; + } + + /* Create the key context. */ + if(!ret) { + i = structkey->end - structkey->header; + Qc3CreateKeyContext(structkey->header, &i, berstring, &keytype, + qc3clear, NULL, NULL, ctx->key.Key_Context_Token, + (char *) &errcode); + if(errcode.Bytes_Available) + ret = -1; + } + + _libssh2_bn_free(e); + _libssh2_bn_free(n); + _libssh2_bn_free(d); + _libssh2_bn_free(p); + _libssh2_bn_free(q); + _libssh2_bn_free(e1); + _libssh2_bn_free(e2); + _libssh2_bn_free(coeff); + asn1delete(key); + asn1delete(structkey); + if(ret && ctx) { + _libssh2_rsa_free(ctx); + ctx = NULL; + } + *rsa = ctx; + return ret; +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: Diffie-Hellman support. + * + *******************************************************************/ + +void +_libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx) +{ + memset((char *) dhctx, 0, sizeof *dhctx); +} + +int +_libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order) +{ + asn1Element *prime; + asn1Element *base; + asn1Element *dhparameter; + asn1Element *dhkeyagreement; + asn1Element *pkcs3; + int pkcs3len; + char *pubkey; + int pubkeysize; + int pubkeylen; + Qus_EC_t errcode; + + (void) group_order; + + /* Build the PKCS#3 structure. */ + + base = asn1uint(g); + prime = asn1uint(p); + dhparameter = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + prime, base, NULL); + asn1delete(base); + asn1delete(prime); + dhkeyagreement = asn1bytes(ASN1_OBJ_ID, + OID_dhKeyAgreement + 1, OID_dhKeyAgreement[0]); + pkcs3 = asn1container(ASN1_SEQ | ASN1_CONSTRUCTED, + dhkeyagreement, dhparameter, NULL); + asn1delete(dhkeyagreement); + asn1delete(dhparameter); + if(!base || !prime || !dhparameter || + !dhkeyagreement || !dhparameter || !pkcs3) { + asn1delete(pkcs3); + return -1; + } + pkcs3len = pkcs3->end - pkcs3->header; + pubkeysize = (_libssh2_bn_bits(p) + 7) >> 3; + pubkey = alloca(pubkeysize); + set_EC_length(errcode, sizeof errcode); + Qc3GenDHKeyPair((char *) pkcs3->header, &pkcs3len, anycsp, NULL, + dhctx->token, pubkey, &pubkeysize, &pubkeylen, &errcode); + asn1delete(pkcs3); + if(errcode.Bytes_Available) + return -1; + return _libssh2_bn_from_bin(public, pubkeylen, (unsigned char *) pubkey); +} + +int +_libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p) +{ + char *pubkey; + int pubkeysize; + char *secretbuf; + int secretbufsize; + int secretbuflen; + Qus_EC_t errcode; + + pubkeysize = (_libssh2_bn_bits(f) + 7) >> 3; + pubkey = alloca(pubkeysize); + _libssh2_bn_to_bin(f, pubkey); + secretbufsize = (_libssh2_bn_bits(p) + 7) >> 3; + secretbuf = alloca(pubkeysize); + set_EC_length(errcode, sizeof errcode); + Qc3CalculateDHSecretKey(dhctx->token, pubkey, &pubkeysize, + secretbuf, &secretbufsize, &secretbuflen, + &errcode); + if(errcode.Bytes_Available) + return -1; + return _libssh2_bn_from_bin(secret, + secretbuflen, (unsigned char *) secretbuf); +} + +void +_libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx) +{ + if(!null_token(dhctx->token)) { + Qc3DestroyAlgorithmContext(dhctx->token, (char *) &ecnull); + memset((char *) dhctx, 0, sizeof *dhctx); + } +} + + +/******************************************************************* + * + * OS/400 QC3 crypto-library backend: PKCS#5 supplement. + * + *******************************************************************/ + +static int +oidcmp(const asn1Element *e, const unsigned char *oid) +{ + int i = e->end - e->beg - *oid++; + + if(*e->header != ASN1_OBJ_ID) + return -2; + if(!i) + i = memcmp(e->beg, oid, oid[-1]); + return i; +} + +static int +asn1getword(asn1Element *e, unsigned long *v) +{ + unsigned long a; + const unsigned char *cp; + + if(*e->header != ASN1_INTEGER) + return -1; + for(cp = e->beg; cp < e->end && !*cp; cp++) + ; + if(e->end - cp > sizeof a) + return -1; + for(a = 0; cp < e->end; cp++) + a = (a << 8) | *cp; + *v = a; + return 0; +} + +static int +pbkdf1(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, + pkcs5params *pkcs5) +{ + int i; + Qc3_Format_ALGD0100_T hctx; + int len = pkcs5->saltlen; + char *data = (char *) pkcs5->salt; + + *dk = NULL; + if(pkcs5->dklen > pkcs5->hashlen) + return -1; + + /* Allocate the derived key buffer. */ + *dk = LIBSSH2_ALLOC(session, pkcs5->hashlen); + if(!*dk) + return -1; + + /* Initial hash. */ + libssh2_os400qc3_hash_init(&hctx, pkcs5->hash); + libssh2_os400qc3_hash_update(&hctx, passphrase, strlen(passphrase)); + hctx.Final_Op_Flag = Qc3_Final; + Qc3CalculateHash((char *) pkcs5->salt, &len, Qc3_Data, (char *) &hctx, + Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); + + /* Iterate. */ + len = pkcs5->hashlen; + for(i = 1; i < pkcs5->itercount; i++) + Qc3CalculateHash((char *) *dk, &len, Qc3_Data, (char *) &hctx, + Qc3_Alg_Token, anycsp, NULL, *dk, (char *) &ecnull); + + /* Special stuff for PBES1: split derived key into 8-byte key and 8-byte + initialization vector. */ + pkcs5->dklen = 8; + pkcs5->ivlen = 8; + pkcs5->iv = *dk + 8; + + /* Clean-up and exit. */ + Qc3DestroyAlgorithmContext(hctx.Alg_Context_Token, (char *) &ecnull); + return 0; +} + +static int +pbkdf2(LIBSSH2_SESSION *session, char **dk, const unsigned char *passphrase, + pkcs5params *pkcs5) +{ + size_t i; + size_t k; + int j; + int l; + uint32_t ni; + unsigned long long t; + char *mac; + char *buf; + _libssh2_os400qc3_crypto_ctx hctx; + + *dk = NULL; + t = ((unsigned long long) pkcs5->dklen + pkcs5->hashlen - 1) / + pkcs5->hashlen; + if(t > 0xFFFFFFFF) + return -1; + mac = alloca(pkcs5->hashlen); + if(!mac) + return -1; + + /* Allocate the derived key buffer. */ + l = t; + buf = LIBSSH2_ALLOC(session, l * pkcs5->hashlen); + if(!buf) + return -1; + *dk = buf; + + /* Create an HMAC context for our computations. */ + libssh2_os400qc3_hmac_init(&hctx, pkcs5->hash, pkcs5->hashlen, + (void *) passphrase, strlen(passphrase)); + + /* Process each hLen-size blocks. */ + for(i = 1; i <= l; i++) { + ni = htonl(i); + libssh2_os400qc3_hmac_update(&hctx, pkcs5->salt, pkcs5->saltlen); + libssh2_os400qc3_hmac_update(&hctx, (char *) &ni, sizeof ni); + libssh2_os400qc3_hmac_final(&hctx, mac); + memcpy(buf, mac, pkcs5->hashlen); + for(j = 1; j < pkcs5->itercount; j++) { + libssh2_os400qc3_hmac_update(&hctx, mac, pkcs5->hashlen); + libssh2_os400qc3_hmac_final(&hctx, mac); + for(k = 0; k < pkcs5->hashlen; k++) + buf[k] ^= mac[k]; + } + buf += pkcs5->hashlen; + } + + /* Computation done. Release HMAC context. */ + _libssh2_os400qc3_crypto_dtor(&hctx); + return 0; +} + +static int +parse_pkcs5_algorithm(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + asn1Element *algid, pkcs5algo **algotable) +{ + asn1Element oid; + asn1Element param; + char *cp; + + cp = getASN1Element(&oid, algid->beg, algid->end); + if(!cp || *oid.header != ASN1_OBJ_ID) + return -1; + param.header = NULL; + if(cp < algid->end) + cp = getASN1Element(¶m, cp, algid->end); + if(cp != algid->end) + return -1; + for(; *algotable; algotable++) + if(!oidcmp(&oid, (*algotable)->oid)) + return (*(*algotable)->parse)(session, pkcs5, *algotable, + param.header? ¶m: NULL); + return -1; +} + +static int +parse_pbes2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element keyDerivationFunc; + asn1Element encryptionScheme; + char *cp; + + if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&keyDerivationFunc, param->beg, param->end); + if(!cp || *keyDerivationFunc.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if(getASN1Element(&encryptionScheme, cp, param->end) != param->end || + *encryptionScheme.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if(parse_pkcs5_algorithm(session, pkcs5, &encryptionScheme, pbes2enctable)) + return -1; + if(parse_pkcs5_algorithm(session, pkcs5, &keyDerivationFunc, pbkdf2table)) + return -1; + return 0; +} + +static int +parse_pbkdf2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element salt; + asn1Element iterationCount; + asn1Element keyLength; + asn1Element prf; + unsigned long itercount; + char *cp; + + if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&salt, param->beg, param->end); + /* otherSource not supported. */ + if(!cp || *salt.header != ASN1_OCTET_STRING) + return -1; + cp = getASN1Element(&iterationCount, cp, param->end); + if(!cp || *iterationCount.header != ASN1_INTEGER) + return -1; + keyLength.header = prf.header = NULL; + if(cp < param->end) { + cp = getASN1Element(&prf, cp, param->end); + if(!cp) + return -1; + if(*prf.header == ASN1_INTEGER) { + keyLength = prf; + prf.header = NULL; + if(cp < param->end) + cp = getASN1Element(&prf, cp, param->end); + } + if(cp != param->end) + return -1; + } + pkcs5->hash = algo->hash; + pkcs5->hashlen = algo->hashlen; + if(prf.header) { + if(*prf.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if(parse_pkcs5_algorithm(session, pkcs5, &prf, kdf2prftable)) + return -1; + } + pkcs5->saltlen = salt.end - salt.beg; + pkcs5->salt = salt.beg; + if(asn1getword(&iterationCount, &itercount) || + !itercount || itercount > 100000) + return -1; + pkcs5->itercount = itercount; + pkcs5->kdf = pbkdf2; + return 0; +} + +static int +parse_hmacWithSHA1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + if(!param || *param->header != ASN1_NULL) + return -1; + pkcs5->hash = algo->hash; + pkcs5->hashlen = algo->hashlen; + return 0; +} + +static int +parse_iv(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + if(!param || *param->header != ASN1_OCTET_STRING || + param->end - param->beg != algo->ivlen) + return -1; + pkcs5->cipher = algo->cipher; + pkcs5->blocksize = algo->blocksize; + pkcs5->mode = algo->mode; + pkcs5->padopt = algo->padopt; + pkcs5->padchar = algo->padchar; + pkcs5->dklen = algo->keylen; + pkcs5->ivlen = algo->ivlen; + pkcs5->iv = param->beg; + return 0; +} + +static int +parse_rc2(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element iv; + unsigned long effkeysize; + char *cp; + + if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&iv, param->beg, param->end); + if(!cp) + return -1; + effkeysize = algo->effkeysize; + if(*iv.header == ASN1_INTEGER) { + if(asn1getword(&iv, &effkeysize) || effkeysize > 1024) + return -1; + + cp = getASN1Element(&iv, cp, param->end); + if(effkeysize < 256) + switch(effkeysize) { + case 160: + effkeysize = 40; + case 120: + effkeysize = 64; + case 58: + effkeysize = 128; + break; + default: + return -1; + } + } + if(effkeysize > 1024 || cp != param->end || + *iv.header != ASN1_OCTET_STRING || iv.end - iv.beg != algo->ivlen) + return -1; + pkcs5->cipher = algo->cipher; + pkcs5->blocksize = algo->blocksize; + pkcs5->mode = algo->mode; + pkcs5->padopt = algo->padopt; + pkcs5->padchar = algo->padchar; + pkcs5->ivlen = algo->ivlen; + pkcs5->iv = iv.beg; + pkcs5->effkeysize = effkeysize; + pkcs5->dklen = (effkeysize + 8 - 1) / 8; + return 0; +} + +static int +parse_pbes1(LIBSSH2_SESSION *session, pkcs5params *pkcs5, + pkcs5algo *algo, asn1Element *param) +{ + asn1Element salt; + asn1Element iterationCount; + unsigned long itercount; + char *cp; + + if(!param || *param->header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + + cp = getASN1Element(&salt, param->beg, param->end); + if(!cp || *salt.header != ASN1_OCTET_STRING || + salt.end - salt.beg != algo->saltlen) + return -1; + if(getASN1Element(&iterationCount, cp, param->end) != param->end || + *iterationCount.header != ASN1_INTEGER) + return -1; + if(asn1getword(&iterationCount, &itercount) || + !itercount || itercount > 100000) + return -1; + pkcs5->cipher = algo->cipher; + pkcs5->blocksize = algo->blocksize; + pkcs5->mode = algo->mode; + pkcs5->padopt = algo->padopt; + pkcs5->padchar = algo->padchar; + pkcs5->hash = algo->hash; + pkcs5->hashlen = algo->hashlen; + pkcs5->dklen = 16; + pkcs5->saltlen = algo->saltlen; + pkcs5->effkeysize = algo->effkeysize; + pkcs5->salt = salt.beg; + pkcs5->kdf = pbkdf1; + pkcs5->itercount = itercount; + return 0; +} + +static int +pkcs8kek(LIBSSH2_SESSION *session, _libssh2_os400qc3_crypto_ctx **ctx, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, asn1Element *privkeyinfo) +{ + asn1Element encprivkeyinfo; + asn1Element pkcs5alg; + pkcs5params pkcs5; + size_t pplen; + char *cp; + unsigned long t; + int i; + char *dk = NULL; + Qc3_Format_ALGD0200_T algd; + Qus_EC_t errcode; + + /* Determine if the PKCS#8 data is encrypted and, if so, set-up a + key encryption key and algorithm in context. + Return 1 if encrypted, 0, if not, -1 if error. */ + + *ctx = NULL; + privkeyinfo->beg = (char *) data; + privkeyinfo->end = privkeyinfo->beg + datalen; + + /* If no passphrase is given, it cannot be an encrypted key. */ + if(!passphrase || !*passphrase) + return 0; + + /* Parse PKCS#8 data, checking if ASN.1 format is PrivateKeyInfo or + EncryptedPrivateKeyInfo. */ + if(getASN1Element(&encprivkeyinfo, privkeyinfo->beg, privkeyinfo->end) != + (char *) data + datalen || + *encprivkeyinfo.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&pkcs5alg, encprivkeyinfo.beg, encprivkeyinfo.end); + if(!cp) + return -1; + + switch(*pkcs5alg.header) { + case ASN1_INTEGER: /* Version. */ + return 0; /* This is a PrivateKeyInfo --> not encrypted. */ + case ASN1_SEQ | ASN1_CONSTRUCTED: /* AlgorithIdentifier. */ + break; /* This is an EncryptedPrivateKeyInfo --> encrypted. */ + default: + return -1; /* Unrecognized: error. */ + } + + /* Get the encrypted key data. */ + if(getASN1Element(privkeyinfo, cp, encprivkeyinfo.end) != + encprivkeyinfo.end || *privkeyinfo->header != ASN1_OCTET_STRING) + return -1; + + /* PKCS#5: parse the PBES AlgorithmIdentifier and recursively get all + encryption parameters. */ + memset((char *) &pkcs5, 0, sizeof pkcs5); + if(parse_pkcs5_algorithm(session, &pkcs5, &pkcs5alg, pbestable)) + return -1; + + /* Compute the derived key. */ + if((*pkcs5.kdf)(session, &dk, passphrase, &pkcs5)) + return -1; + + /* Prepare the algorithm descriptor. */ + memset((char *) &algd, 0, sizeof algd); + algd.Block_Cipher_Alg = pkcs5.cipher; + algd.Block_Length = pkcs5.blocksize; + algd.Mode = pkcs5.mode; + algd.Pad_Option = pkcs5.padopt; + algd.Pad_Character = pkcs5.padchar; + algd.Effective_Key_Size = pkcs5.effkeysize; + memcpy(algd.Init_Vector, pkcs5.iv, pkcs5.ivlen); + + /* Create the key and algorithm context tokens. */ + *ctx = libssh2_init_crypto_ctx(NULL); + if(!*ctx) { + LIBSSH2_FREE(session, dk); + return -1; + } + libssh2_init_crypto_ctx(*ctx); + set_EC_length(errcode, sizeof errcode); + Qc3CreateKeyContext(dk, &pkcs5.dklen, binstring, &algd.Block_Cipher_Alg, + qc3clear, NULL, NULL, (*ctx)->key.Key_Context_Token, + (char *) &errcode); + LIBSSH2_FREE(session, dk); + if(errcode.Bytes_Available) { + free((char *) *ctx); + *ctx = NULL; + return -1; + } + + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Block_Cipher, + (*ctx)->hash.Alg_Context_Token, &errcode); + if(errcode.Bytes_Available) { + Qc3DestroyKeyContext((*ctx)->key.Key_Context_Token, (char *) &ecnull); + free((char *) *ctx); + *ctx = NULL; + return -1; + } + return 1; /* Tell it's encrypted. */ +} + +static int +rsapkcs8privkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + libssh2_rsa_ctx *ctx = (libssh2_rsa_ctx *) loadkeydata; + char keyform = Qc3_Clear; + char *kek = NULL; + char *kea = NULL; + _libssh2_os400qc3_crypto_ctx *kekctx; + asn1Element pki; + int pkilen; + Qus_EC_t errcode; + + switch(pkcs8kek(session, &kekctx, data, datalen, passphrase, &pki)) { + case 1: + keyform = Qc3_Encrypted; + kek = kekctx->key.Key_Context_Token; + kea = kekctx->hash.Alg_Context_Token; + case 0: + break; + default: + return -1; + } + + set_EC_length(errcode, sizeof errcode); + pkilen = pki.end - pki.beg; + Qc3CreateKeyContext((unsigned char *) pki.beg, &pkilen, berstring, + rsaprivate, &keyform, kek, kea, + ctx->key.Key_Context_Token, (char *) &errcode); + if(errcode.Bytes_Available) { + if(kekctx) + _libssh2_os400qc3_crypto_dtor(kekctx); + return -1; + } + ctx->kek = kekctx; + return 0; +} + +static char * +storewithlength(char *p, const char *data, int length) +{ + _libssh2_htonu32(p, length); + if(length) + memcpy(p + 4, data, length); + return p + 4 + length; +} + +static int +sshrsapubkey(LIBSSH2_SESSION *session, char **sshpubkey, + asn1Element *params, asn1Element *key, const char *method) +{ + int methlen = strlen(method); + asn1Element keyseq; + asn1Element m; + asn1Element e; + int len; + char *cp; + + if(getASN1Element(&keyseq, key->beg + 1, key->end) != key->end || + *keyseq.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if(!getASN1Element(&m, keyseq.beg, keyseq.end) || + *m.header != ASN1_INTEGER) + return -1; + if(getASN1Element(&e, m.end, keyseq.end) != keyseq.end || + *e.header != ASN1_INTEGER) + return -1; + len = 4 + methlen + 4 + (e.end - e.beg) + 4 + (m.end - m.beg); + cp = LIBSSH2_ALLOC(session, len); + if(!cp) + return -1; + *sshpubkey = cp; + cp = storewithlength(cp, method, methlen); + cp = storewithlength(cp, e.beg, e.end - e.beg); + cp = storewithlength(cp, m.beg, m.end - m.beg); + return len; +} + +static int +rsapkcs8pubkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + loadpubkeydata *p = (loadpubkeydata *) loadkeydata; + char *buf; + int len; + char *cp; + int i; + char keyform = Qc3_Clear; + char *kek = NULL; + char *kea = NULL; + _libssh2_os400qc3_crypto_ctx *kekctx; + asn1Element subjpubkeyinfo; + asn1Element algorithmid; + asn1Element algorithm; + asn1Element subjpubkey; + asn1Element parameters; + asn1Element pki; + int pkilen; + Qus_EC_t errcode; + + buf = alloca(datalen); + if(!buf) + return -1; + + switch(pkcs8kek(session, &kekctx, data, datalen, passphrase, &pki)) { + case 1: + keyform = Qc3_Encrypted; + kek = kekctx->key.Key_Context_Token; + kea = kekctx->hash.Alg_Context_Token; + case 0: + break; + default: + return -1; + } + + set_EC_length(errcode, sizeof errcode); + pkilen = pki.end - pki.beg; + Qc3ExtractPublicKey(pki.beg, &pkilen, berstring, &keyform, + kek, kea, buf, (int *) &datalen, &len, &errcode); + _libssh2_os400qc3_crypto_dtor(kekctx); + if(errcode.Bytes_Available) + return -1; + /* Get the algorithm OID and key data from SubjectPublicKeyInfo. */ + if(getASN1Element(&subjpubkeyinfo, buf, buf + len) != buf + len || + *subjpubkeyinfo.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + cp = getASN1Element(&algorithmid, subjpubkeyinfo.beg, subjpubkeyinfo.end); + if(!cp || *algorithmid.header != (ASN1_SEQ | ASN1_CONSTRUCTED)) + return -1; + if(!getASN1Element(&algorithm, algorithmid.beg, algorithmid.end) || + *algorithm.header != ASN1_OBJ_ID) + return -1; + if(getASN1Element(&subjpubkey, cp, subjpubkeyinfo.end) != + subjpubkeyinfo.end || *subjpubkey.header != ASN1_BIT_STRING) + return -1; + /* Check for supported algorithm. */ + for(i = 0; pka[i].oid; i++) + if(!oidcmp(&algorithm, pka[i].oid)) { + len = (*pka[i].sshpubkey)(session, &p->data, &algorithmid, + &subjpubkey, pka[i].method); + if(len < 0) + return -1; + p->length = len; + p->method = pka[i].method; + return 0; + } + return -1; /* Algorithm not supported. */ +} + +static int +pkcs1topkcs8(LIBSSH2_SESSION *session, + const unsigned char **data8, unsigned int *datalen8, + const unsigned char *data1, unsigned int datalen1) +{ + asn1Element *prvk; + asn1Element *pkcs8; + unsigned char *data; + + *data8 = NULL; + *datalen8 = 0; + if(datalen1 < 2) + return -1; + prvk = asn1_new_from_bytes(data1, datalen1); + if(!prvk) + return -1; + pkcs8 = rsaprivatekeyinfo(prvk); + asn1delete(prvk); + if(!prvk) { + asn1delete(pkcs8); + pkcs8 = NULL; + } + if(!pkcs8) + return -1; + data = (unsigned char *) LIBSSH2_ALLOC(session, + pkcs8->end - pkcs8->header); + if(!data) { + asn1delete(pkcs8); + return -1; + } + *data8 = data; + *datalen8 = pkcs8->end - pkcs8->header; + memcpy((char *) data, (char *) pkcs8->header, *datalen8); + asn1delete(pkcs8); + return 0; +} + +static int +rsapkcs1privkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + const unsigned char *data8; + unsigned int datalen8; + int ret; + + if(pkcs1topkcs8(session, &data8, &datalen8, data, datalen)) + return -1; + ret = rsapkcs8privkey(session, data8, datalen8, passphrase, loadkeydata); + LIBSSH2_FREE(session, (char *) data8); + return ret; +} + +static int +rsapkcs1pubkey(LIBSSH2_SESSION *session, + const unsigned char *data, unsigned int datalen, + const unsigned char *passphrase, void *loadkeydata) +{ + const unsigned char *data8; + unsigned int datalen8; + int ret; + + if(pkcs1topkcs8(session, &data8, &datalen8, data, datalen)) + return -1; + ret = rsapkcs8pubkey(session, data8, datalen8, passphrase, loadkeydata); + LIBSSH2_FREE(session, (char *) data8); + return ret; +} + +static int +try_pem_load(LIBSSH2_SESSION *session, FILE *fp, + const unsigned char *passphrase, + const char *header, const char *trailer, + loadkeyproc proc, void *loadkeydata) +{ + unsigned char *data = NULL; + unsigned int datalen = 0; + int c; + int ret; + + fseek(fp, 0L, SEEK_SET); + for(;;) { + ret = _libssh2_pem_parse(session, header, trailer, + passphrase, + fp, &data, &datalen); + + if(!ret) { + ret = (*proc)(session, data, datalen, passphrase, loadkeydata); + if(!ret) + return 0; + } + + if(data) { + LIBSSH2_FREE(session, data); + data = NULL; + } + c = getc(fp); + + if(c == EOF) + break; + + ungetc(c, fp); + } + + return -1; +} + +static int +load_rsa_private_file(LIBSSH2_SESSION *session, const char *filename, + unsigned const char *passphrase, + loadkeyproc proc1, loadkeyproc proc8, void *loadkeydata) +{ + FILE *fp = fopen(filename, fopenrmode); + unsigned char *data = NULL; + size_t datalen = 0; + int ret; + long filesize; + + if(!fp) + return -1; + + /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. + --> PKCS#8 EncryptedPrivateKeyInfo */ + ret = try_pem_load(session, fp, passphrase, beginencprivkeyhdr, + endencprivkeyhdr, proc8, loadkeydata); + + /* Try with "PRIVATE KEY" PEM armor. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + if(ret) + ret = try_pem_load(session, fp, passphrase, beginprivkeyhdr, + endprivkeyhdr, proc8, loadkeydata); + + /* Try with "RSA PRIVATE KEY" PEM armor. + --> PKCS#1 RSAPrivateKey */ + if(ret) + ret = try_pem_load(session, fp, passphrase, beginrsaprivkeyhdr, + endrsaprivkeyhdr, proc1, loadkeydata); + fclose(fp); + + if(ret) { + /* Try DER encoding. */ + fp = fopen(filename, fopenrbmode); + fseek(fp, 0L, SEEK_END); + filesize = ftell(fp); + + if(filesize <= 32768) { /* Limit to a reasonable size. */ + datalen = filesize; + data = (unsigned char *) alloca(datalen); + if(data) { + fseek(fp, 0L, SEEK_SET); + fread(data, datalen, 1, fp); + + /* Try as PKCS#8 DER data. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + ret = (*proc8)(session, data, datalen, passphrase, + loadkeydata); + + /* Try as PKCS#1 DER data. + --> PKCS#1 RSAPrivateKey */ + if(ret) + ret = (*proc1)(session, data, datalen, passphrase, + loadkeydata); + } + } + fclose(fp); + } + + return ret; +} + +int +_libssh2_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, + const char *filename, unsigned const char *passphrase) +{ + libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL); + int ret; + Qc3_Format_ALGD0400_T algd; + Qus_EC_t errcode; + + if(!ctx) + return -1; + ret = load_rsa_private_file(session, filename, passphrase, + rsapkcs1privkey, rsapkcs8privkey, + (void *) ctx); + if(!ret) { + /* Create the algorithm context. */ + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_PKCS1_01; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = Qc3_SHA1; + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Public_Key, + ctx->hash.Alg_Context_Token, &errcode); + if(errcode.Bytes_Available) + ret = -1; + } + if(ret) { + _libssh2_os400qc3_crypto_dtor(ctx); + ctx = NULL; + } + *rsa = ctx; + return ret; +} + +int +_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, size_t *method_len, + unsigned char **pubkeydata, size_t *pubkeydata_len, + const char *privatekey, const char *passphrase) + +{ + loadpubkeydata p; + int ret; + + *method = NULL; + *method_len = 0; + *pubkeydata = NULL; + *pubkeydata_len = 0; + + ret = load_rsa_private_file(session, privatekey, passphrase, + rsapkcs1pubkey, rsapkcs8pubkey, (void *) &p); + if(!ret) { + *method_len = strlen(p.method); + *method = LIBSSH2_ALLOC(session, *method_len); + if(*method) + memcpy((char *) *method, p.method, *method_len); + else + ret = -1; + } + + if(ret) { + if(*method) + LIBSSH2_FREE(session, *method); + if(p.data) + LIBSSH2_FREE(session, (void *) p.data); + *method = NULL; + *method_len = 0; + } + else { + *pubkeydata = (unsigned char *) p.data; + *pubkeydata_len = p.length; + } + + return ret; +} + +int +_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ + libssh2_rsa_ctx *ctx = libssh2_init_crypto_ctx(NULL); + unsigned char *data = NULL; + unsigned int datalen = 0; + int ret; + Qc3_Format_ALGD0400_T algd; + Qus_EC_t errcode; + + if(!ctx) + return -1; + + /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. + --> PKCS#8 EncryptedPrivateKeyInfo */ + ret = _libssh2_pem_parse_memory(session, + beginencprivkeyhdr, endencprivkeyhdr, + filedata, filedata_len, &data, &datalen); + + /* Try with "PRIVATE KEY" PEM armor. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + if(ret) + ret = _libssh2_pem_parse_memory(session, + beginprivkeyhdr, endprivkeyhdr, + filedata, filedata_len, + &data, &datalen); + + if(!ret) { + /* Process PKCS#8. */ + ret = rsapkcs8privkey(session, + data, datalen, passphrase, (void *) &ctx); + } + else { + /* Try with "RSA PRIVATE KEY" PEM armor. + --> PKCS#1 RSAPrivateKey */ + ret = _libssh2_pem_parse_memory(session, + beginrsaprivkeyhdr, endrsaprivkeyhdr, + filedata, filedata_len, + &data, &datalen); + if(!ret) + ret = rsapkcs1privkey(session, + data, datalen, passphrase, (void *) &ctx); + } + + if(ret) { + /* Try as PKCS#8 DER data. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + ret = rsapkcs8privkey(session, filedata, filedata_len, + passphrase, (void *) &ctx); + + /* Try as PKCS#1 DER data. + --> PKCS#1 RSAPrivateKey */ + if(ret) + ret = rsapkcs1privkey(session, filedata, filedata_len, + passphrase, (void *) &ctx); + } + + if(data) + LIBSSH2_FREE(session, data); + + if(!ret) { + /* Create the algorithm context. */ + algd.Public_Key_Alg = Qc3_RSA; + algd.PKA_Block_Format = Qc3_PKCS1_01; + memset(algd.Reserved, 0, sizeof algd.Reserved); + algd.Signing_Hash_Alg = Qc3_SHA1; + set_EC_length(errcode, sizeof errcode); + Qc3CreateAlgorithmContext((char *) &algd, Qc3_Alg_Public_Key, + ctx->hash.Alg_Context_Token, &errcode); + if(errcode.Bytes_Available) + ret = -1; + } + + if(ret) { + _libssh2_os400qc3_crypto_dtor(ctx); + ctx = NULL; + } + + *rsa = ctx; + return ret; +} + +int +_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + loadpubkeydata p; + unsigned char *data = NULL; + unsigned int datalen = 0; + const char *meth; + int ret; + + *method = NULL; + *method_len = 0; + *pubkeydata = NULL; + *pubkeydata_len = 0; + + /* Try with "ENCRYPTED PRIVATE KEY" PEM armor. + --> PKCS#8 EncryptedPrivateKeyInfo */ + ret = _libssh2_pem_parse_memory(session, + beginencprivkeyhdr, endencprivkeyhdr, + privatekeydata, privatekeydata_len, + &data, &datalen); + + /* Try with "PRIVATE KEY" PEM armor. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + if(ret) + ret = _libssh2_pem_parse_memory(session, + beginprivkeyhdr, endprivkeyhdr, + privatekeydata, privatekeydata_len, + &data, &datalen); + + if(!ret) { + /* Process PKCS#8. */ + ret = rsapkcs8pubkey(session, + data, datalen, passphrase, (void *) &p); + } + else { + /* Try with "RSA PRIVATE KEY" PEM armor. + --> PKCS#1 RSAPrivateKey */ + ret = _libssh2_pem_parse_memory(session, + beginrsaprivkeyhdr, endrsaprivkeyhdr, + privatekeydata, privatekeydata_len, + &data, &datalen); + if(!ret) + ret = rsapkcs1pubkey(session, + data, datalen, passphrase, (void *) &p); + } + + if(ret) { + /* Try as PKCS#8 DER data. + --> PKCS#8 PrivateKeyInfo or EncryptedPrivateKeyInfo */ + ret = rsapkcs8pubkey(session, privatekeydata, privatekeydata_len, + passphrase, (void *) &p); + + /* Try as PKCS#1 DER data. + --> PKCS#1 RSAPrivateKey */ + if(ret) + ret = rsapkcs1pubkey(session, privatekeydata, privatekeydata_len, + passphrase, (void *) &p); + } + + if(data) + LIBSSH2_FREE(session, data); + + if(!ret) { + *method_len = strlen(p.method); + *method = LIBSSH2_ALLOC(session, *method_len); + if(*method) + memcpy((char *) *method, p.method, *method_len); + else + ret = -1; + } + if(ret) { + if(*method) + LIBSSH2_FREE(session, *method); + if(p.data) + LIBSSH2_FREE(session, (void *) p.data); + *method = NULL; + *method_len = 0; + } + else { + *pubkeydata = (unsigned char *) p.data; + *pubkeydata_len = p.length; + } + + return ret; +} + +int +_libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, unsigned long sig_len, + const unsigned char *m, unsigned long m_len) +{ + Qus_EC_t errcode; + int slen = sig_len; + int mlen = m_len; + + set_EC_length(errcode, sizeof errcode); + Qc3VerifySignature((char *) sig, &slen, (char *) m, &mlen, Qc3_Data, + rsa->hash.Alg_Context_Token, Qc3_Alg_Token, + rsa->key.Key_Context_Token, Qc3_Key_Token, anycsp, + NULL, (char *) &errcode); + return errcode.Bytes_Available? -1: 0; +} + +int +_libssh2_os400qc3_rsa_sha1_signv(LIBSSH2_SESSION *session, + unsigned char **signature, + size_t *signature_len, + int veccount, + const struct iovec vector[], + libssh2_rsa_ctx *ctx) +{ + Qus_EC_t errcode; + int siglen; + unsigned char *sig; + char sigbuf[8192]; + int sigbufsize = sizeof sigbuf; + + ctx->hash.Final_Op_Flag = Qc3_Final; + set_EC_length(errcode, sizeof errcode); + Qc3CalculateSignature((char *) vector, &veccount, Qc3_Array, + (char *) &ctx->hash, Qc3_Alg_Token, + (char *) &ctx->key, Qc3_Key_Token, + anycsp, NULL, sigbuf, &sigbufsize, &siglen, + (char *) &errcode); + ctx->hash.Final_Op_Flag = Qc3_Continue; + if(errcode.Bytes_Available) + return -1; + sig = LIBSSH2_ALLOC(session, siglen); + if(!sig) + return -1; + memcpy((char *) sig, sigbuf, siglen); + *signature = sig; + *signature_len = siglen; + return 0; +} + +#endif /* LIBSSH2_OS400QC3 */ + +/* vim: set expandtab ts=4 sw=4: */ diff --git a/libssh2/packet.c b/libssh2/packet.c new file mode 100644 index 0000000..9897f77 --- /dev/null +++ b/libssh2/packet.c @@ -0,0 +1,1336 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2005,2006 Mikhail Gusarov + * Copyright (c) 2009-2014 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_INTTYPES_H +#include +#endif + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#include + +#include "transport.h" +#include "channel.h" +#include "packet.h" + +/* + * libssh2_packet_queue_listener + * + * Queue a connection request for a listener + */ +static inline int +packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long datalen, + packet_queue_listener_state_t *listen_state) +{ + /* + * Look for a matching listener + */ + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof(FwdNotReq) - 1); + unsigned char *p; + LIBSSH2_LISTENER *listn = _libssh2_list_first(&session->listeners); + char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; + int rc; + + if(listen_state->state == libssh2_NB_state_idle) { + unsigned long offset = (sizeof("forwarded-tcpip") - 1) + 5; + size_t temp_len = 0; + struct string_buf buf; + buf.data = data; + buf.dataptr = buf.data; + buf.len = datalen; + + if(datalen < offset) { + return _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, + "Unexpected packet size"); + } + + buf.dataptr += offset; + + if(_libssh2_get_u32(&buf, &(listen_state->sender_channel))) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting channel"); + } + if(_libssh2_get_u32(&buf, &(listen_state->initial_window_size))) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting window size"); + } + if(_libssh2_get_u32(&buf, &(listen_state->packet_size))) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting packet"); + } + if(_libssh2_get_string(&buf, &(listen_state->host), &temp_len)) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting host"); + } + listen_state->host_len = (uint32_t)temp_len; + + if(_libssh2_get_u32(&buf, &(listen_state->port))) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting port"); + } + if(_libssh2_get_string(&buf, &(listen_state->shost), &temp_len)) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting shost"); + } + listen_state->shost_len = (uint32_t)temp_len; + + if(_libssh2_get_u32(&buf, &(listen_state->sport))) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short extracting sport"); + } + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Remote received connection from %s:%ld to %s:%ld", + listen_state->shost, listen_state->sport, + listen_state->host, listen_state->port); + + listen_state->state = libssh2_NB_state_allocated; + } + + if(listen_state->state != libssh2_NB_state_sent) { + while(listn) { + if((listn->port == (int) listen_state->port) && + (strlen(listn->host) == listen_state->host_len) && + (memcmp (listn->host, listen_state->host, + listen_state->host_len) == 0)) { + /* This is our listener */ + LIBSSH2_CHANNEL *channel = NULL; + listen_state->channel = NULL; + + if(listen_state->state == libssh2_NB_state_allocated) { + if(listn->queue_maxsize && + (listn->queue_maxsize <= listn->queue_size)) { + /* Queue is full */ + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Listener queue full, ignoring"); + listen_state->state = libssh2_NB_state_sent; + break; + } + + channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if(!channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a channel for " + "new connection"); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + listen_state->state = libssh2_NB_state_sent; + break; + } + listen_state->channel = channel; + + channel->session = session; + channel->channel_type_len = sizeof("forwarded-tcpip") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, + channel-> + channel_type_len + + 1); + if(!channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a channel for new" + " connection"); + LIBSSH2_FREE(session, channel); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + listen_state->state = libssh2_NB_state_sent; + break; + } + memcpy(channel->channel_type, "forwarded-tcpip", + channel->channel_type_len + 1); + + channel->remote.id = listen_state->sender_channel; + channel->remote.window_size_initial = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = + LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = _libssh2_channel_nextid(session); + channel->local.window_size_initial = + listen_state->initial_window_size; + channel->local.window_size = + listen_state->initial_window_size; + channel->local.packet_size = listen_state->packet_size; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Connection queued: channel %lu/%lu " + "win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, + channel->remote.window_size, + channel->local.packet_size, + channel->remote.packet_size); + + p = listen_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + _libssh2_store_u32(&p, channel->remote.id); + _libssh2_store_u32(&p, channel->local.id); + _libssh2_store_u32(&p, + channel->remote.window_size_initial); + _libssh2_store_u32(&p, channel->remote.packet_size); + + listen_state->state = libssh2_NB_state_created; + } + + if(listen_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, listen_state->packet, + 17, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc) { + listen_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Unable to send channel " + "open confirmation"); + } + + /* Link the channel into the end of the queue list */ + if(listen_state->channel) { + _libssh2_list_add(&listn->queue, + &listen_state->channel->node); + listn->queue_size++; + } + + listen_state->state = libssh2_NB_state_idle; + return 0; + } + } + + listn = _libssh2_list_next(&listn->node); + } + + listen_state->state = libssh2_NB_state_sent; + } + + /* We're not listening to you */ + p = listen_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + _libssh2_store_u32(&p, listen_state->sender_channel); + _libssh2_store_u32(&p, failure_code); + _libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1); + _libssh2_htonu32(p, 0); + + rc = _libssh2_transport_send(session, listen_state->packet, + packet_len, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + listen_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, "Unable to send open failure"); + + } + listen_state->state = libssh2_NB_state_idle; + return 0; +} + +/* + * packet_x11_open + * + * Accept a forwarded X11 connection + */ +static inline int +packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data, + unsigned long datalen, + packet_x11_open_state_t *x11open_state) +{ + int failure_code = SSH_OPEN_CONNECT_FAILED; + /* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */ + unsigned long packet_len = 17 + (sizeof(X11FwdUnAvil) - 1); + unsigned char *p; + LIBSSH2_CHANNEL *channel = x11open_state->channel; + int rc; + + if(x11open_state->state == libssh2_NB_state_idle) { + + unsigned long offset = (sizeof("x11") - 1) + 5; + size_t temp_len = 0; + struct string_buf buf; + buf.data = data; + buf.dataptr = buf.data; + buf.len = datalen; + + if(datalen < offset) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "unexpected data length"); + failure_code = SSH_OPEN_CONNECT_FAILED; + goto x11_exit; + } + + buf.dataptr += offset; + + if(_libssh2_get_u32(&buf, &(x11open_state->sender_channel))) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "unexpected sender channel size"); + failure_code = SSH_OPEN_CONNECT_FAILED; + goto x11_exit; + } + if(_libssh2_get_u32(&buf, &(x11open_state->initial_window_size))) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "unexpected window size"); + failure_code = SSH_OPEN_CONNECT_FAILED; + goto x11_exit; + } + if(_libssh2_get_u32(&buf, &(x11open_state->packet_size))) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "unexpected window size"); + failure_code = SSH_OPEN_CONNECT_FAILED; + goto x11_exit; + } + if(_libssh2_get_string(&buf, &(x11open_state->shost), &temp_len)) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "unexpected host size"); + failure_code = SSH_OPEN_CONNECT_FAILED; + goto x11_exit; + } + x11open_state->shost_len = (uint32_t)temp_len; + + if(_libssh2_get_u32(&buf, &(x11open_state->sport))) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "unexpected port size"); + failure_code = SSH_OPEN_CONNECT_FAILED; + goto x11_exit; + } + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "X11 Connection Received from %s:%ld on channel %lu", + x11open_state->shost, x11open_state->sport, + x11open_state->sender_channel); + + x11open_state->state = libssh2_NB_state_allocated; + } + + if(session->x11) { + if(x11open_state->state == libssh2_NB_state_allocated) { + channel = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_CHANNEL)); + if(!channel) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "allocate a channel for new connection"); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + goto x11_exit; + } + + channel->session = session; + channel->channel_type_len = sizeof("x11") - 1; + channel->channel_type = LIBSSH2_ALLOC(session, + channel->channel_type_len + + 1); + if(!channel->channel_type) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "allocate a channel for new connection"); + LIBSSH2_FREE(session, channel); + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + goto x11_exit; + } + memcpy(channel->channel_type, "x11", + channel->channel_type_len + 1); + + channel->remote.id = x11open_state->sender_channel; + channel->remote.window_size_initial = + LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.window_size = LIBSSH2_CHANNEL_WINDOW_DEFAULT; + channel->remote.packet_size = LIBSSH2_CHANNEL_PACKET_DEFAULT; + + channel->local.id = _libssh2_channel_nextid(session); + channel->local.window_size_initial = + x11open_state->initial_window_size; + channel->local.window_size = x11open_state->initial_window_size; + channel->local.packet_size = x11open_state->packet_size; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "X11 Connection established: channel %lu/%lu " + "win %lu/%lu packet %lu/%lu", + channel->local.id, channel->remote.id, + channel->local.window_size, + channel->remote.window_size, + channel->local.packet_size, + channel->remote.packet_size); + p = x11open_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_CONFIRMATION; + _libssh2_store_u32(&p, channel->remote.id); + _libssh2_store_u32(&p, channel->local.id); + _libssh2_store_u32(&p, channel->remote.window_size_initial); + _libssh2_store_u32(&p, channel->remote.packet_size); + + x11open_state->state = libssh2_NB_state_created; + } + + if(x11open_state->state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, x11open_state->packet, 17, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + x11open_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send channel open " + "confirmation"); + } + + /* Link the channel into the session */ + _libssh2_list_add(&session->channels, &channel->node); + + /* + * Pass control to the callback, they may turn right around and + * free the channel, or actually use it + */ + LIBSSH2_X11_OPEN(channel, (char *)x11open_state->shost, + x11open_state->sport); + + x11open_state->state = libssh2_NB_state_idle; + return 0; + } + } + else + failure_code = SSH_OPEN_RESOURCE_SHORTAGE; + /* fall-trough */ + x11_exit: + p = x11open_state->packet; + *(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE; + _libssh2_store_u32(&p, x11open_state->sender_channel); + _libssh2_store_u32(&p, failure_code); + _libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1); + _libssh2_htonu32(p, 0); + + rc = _libssh2_transport_send(session, x11open_state->packet, packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + x11open_state->state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, "Unable to send open failure"); + } + x11open_state->state = libssh2_NB_state_idle; + return 0; +} + +/* + * _libssh2_packet_add + * + * Create a new packet and attach it to the brigade. Called from the transport + * layer when it has received a packet. + * + * The input pointer 'data' is pointing to allocated data that this function + * is asked to deal with so on failure OR success, it must be freed fine. + * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN. + * + * This function will always be called with 'datalen' greater than zero. + */ +int +_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, + size_t datalen, int macstate) +{ + int rc = 0; + unsigned char *message = NULL; + unsigned char *language = NULL; + size_t message_len = 0; + size_t language_len = 0; + LIBSSH2_CHANNEL *channelp = NULL; + size_t data_head = 0; + unsigned char msg = data[0]; + + switch(session->packAdd_state) { + case libssh2_NB_state_idle: + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Packet type %d received, length=%d", + (int) msg, (int) datalen); + + if((macstate == LIBSSH2_MAC_INVALID) && + (!session->macerror || + LIBSSH2_MACERROR(session, (char *) data, datalen))) { + /* Bad MAC input, but no callback set or non-zero return from the + callback */ + + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_INVALID_MAC, + "Invalid MAC received"); + } + session->packAdd_state = libssh2_NB_state_allocated; + break; + case libssh2_NB_state_jump1: + goto libssh2_packet_add_jump_point1; + case libssh2_NB_state_jump2: + goto libssh2_packet_add_jump_point2; + case libssh2_NB_state_jump3: + goto libssh2_packet_add_jump_point3; + case libssh2_NB_state_jump4: + goto libssh2_packet_add_jump_point4; + case libssh2_NB_state_jump5: + goto libssh2_packet_add_jump_point5; + default: /* nothing to do */ + break; + } + + if(session->packAdd_state == libssh2_NB_state_allocated) { + /* A couple exceptions to the packet adding rule: */ + switch(msg) { + + /* + byte SSH_MSG_DISCONNECT + uint32 reason code + string description in ISO-10646 UTF-8 encoding [RFC3629] + string language tag [RFC3066] + */ + + case SSH_MSG_DISCONNECT: + if(datalen >= 5) { + uint32_t reason = 0; + struct string_buf buf; + buf.data = (unsigned char *)data; + buf.dataptr = buf.data; + buf.len = datalen; + buf.dataptr++; /* advance past type */ + + _libssh2_get_u32(&buf, &reason); + _libssh2_get_string(&buf, &message, &message_len); + _libssh2_get_string(&buf, &language, &language_len); + + if(session->ssh_msg_disconnect) { + LIBSSH2_DISCONNECT(session, reason, (const char *)message, + message_len, (const char *)language, + language_len); + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Disconnect(%d): %s(%s)", reason, + message, language); + } + + LIBSSH2_FREE(session, data); + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + session->packAdd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT, + "socket disconnect"); + /* + byte SSH_MSG_IGNORE + string data + */ + + case SSH_MSG_IGNORE: + if(datalen >= 2) { + if(session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, (char *) data + 1, datalen - 1); + } + } + else if(session->ssh_msg_ignore) { + LIBSSH2_IGNORE(session, "", 0); + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_DEBUG + boolean always_display + string message in ISO-10646 UTF-8 encoding [RFC3629] + string language tag [RFC3066] + */ + + case SSH_MSG_DEBUG: + if(datalen >= 2) { + int always_display = data[1]; + + if(datalen >= 6) { + struct string_buf buf; + buf.data = (unsigned char *)data; + buf.dataptr = buf.data; + buf.len = datalen; + buf.dataptr += 2; /* advance past type & always display */ + + _libssh2_get_string(&buf, &message, &message_len); + _libssh2_get_string(&buf, &language, &language_len); + } + + if(session->ssh_msg_debug) { + LIBSSH2_DEBUG(session, always_display, + (const char *)message, + message_len, (const char *)language, + language_len); + } + } + + /* + * _libssh2_debug will actually truncate this for us so + * that it's not an inordinate about of data + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Debug Packet: %s", message); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_GLOBAL_REQUEST + string request name in US-ASCII only + boolean want reply + .... request-specific data follows + */ + + case SSH_MSG_GLOBAL_REQUEST: + if(datalen >= 5) { + uint32_t len = 0; + unsigned char want_reply = 0; + len = _libssh2_ntohu32(data + 1); + if((len <= (UINT_MAX - 6)) && (datalen >= (6 + len))) { + want_reply = data[5 + len]; + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "Received global request type %.*s (wr %X)", + len, data + 5, want_reply); + } + + + if(want_reply) { + static const unsigned char packet = + SSH_MSG_REQUEST_FAILURE; + libssh2_packet_add_jump_point5: + session->packAdd_state = libssh2_NB_state_jump5; + rc = _libssh2_transport_send(session, &packet, 1, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_EXTENDED_DATA + uint32 recipient channel + uint32 data_type_code + string data + */ + + case SSH_MSG_CHANNEL_EXTENDED_DATA: + /* streamid(4) */ + data_head += 4; + + /* fall-through */ + + /* + byte SSH_MSG_CHANNEL_DATA + uint32 recipient channel + string data + */ + + case SSH_MSG_CHANNEL_DATA: + /* packet_type(1) + channelno(4) + datalen(4) */ + data_head += 9; + + if(datalen >= data_head) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + + if(!channelp) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_UNKNOWN, + "Packet received for unknown channel"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } +#ifdef LIBSSH2DEBUG + { + uint32_t stream_id = 0; + if(msg == SSH_MSG_CHANNEL_EXTENDED_DATA) + stream_id = _libssh2_ntohu32(data + 5); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "%d bytes packet_add() for %lu/%lu/%lu", + (int) (datalen - data_head), + channelp->local.id, + channelp->remote.id, + stream_id); + } +#endif + if((channelp->remote.extended_data_ignore_mode == + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE) && + (msg == SSH_MSG_CHANNEL_EXTENDED_DATA)) { + /* Pretend we didn't receive this */ + LIBSSH2_FREE(session, data); + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Ignoring extended data and refunding %d bytes", + (int) (datalen - 13)); + if(channelp->read_avail + datalen - data_head >= + channelp->remote.window_size) + datalen = channelp->remote.window_size - + channelp->read_avail + data_head; + + channelp->remote.window_size -= datalen - data_head; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "shrinking window size by %lu bytes to %lu, " + "read_avail %lu", + datalen - data_head, + channelp->remote.window_size, + channelp->read_avail); + + session->packAdd_channelp = channelp; + + /* Adjust the window based on the block we just freed */ + libssh2_packet_add_jump_point1: + session->packAdd_state = libssh2_NB_state_jump1; + rc = _libssh2_channel_receive_window_adjust(session-> + packAdd_channelp, + datalen - 13, + 1, NULL); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + + /* + * REMEMBER! remote means remote as source of data, + * NOT remote window! + */ + if(channelp->remote.packet_size < (datalen - data_head)) { + /* + * Spec says we MAY ignore bytes sent beyond + * packet_size + */ + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "Packet contains more data than we offered" + " to receive, truncating"); + datalen = channelp->remote.packet_size + data_head; + } + if(channelp->remote.window_size <= channelp->read_avail) { + /* + * Spec says we MAY ignore bytes sent beyond + * window_size + */ + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "The current receive window is full," + " data ignored"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + /* Reset EOF status */ + channelp->remote.eof = 0; + + if(channelp->read_avail + datalen - data_head > + channelp->remote.window_size) { + _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED, + "Remote sent more data than current " + "window allows, truncating"); + datalen = channelp->remote.window_size - + channelp->read_avail + data_head; + } + + /* Update the read_avail counter. The window size will be + * updated once the data is actually read from the queue + * from an upper layer */ + channelp->read_avail += datalen - data_head; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "increasing read_avail by %lu bytes to %lu/%lu", + (long)(datalen - data_head), + (long)channelp->read_avail, + (long)channelp->remote.window_size); + + break; + + /* + byte SSH_MSG_CHANNEL_EOF + uint32 recipient channel + */ + + case SSH_MSG_CHANNEL_EOF: + if(datalen >= 5) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if(!channelp) + /* We may have freed already, just quietly ignore this... */ + ; + else { + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "EOF received for channel %lu/%lu", + channelp->local.id, + channelp->remote.id); + channelp->remote.eof = 1; + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_REQUEST + uint32 recipient channel + string request type in US-ASCII characters only + boolean want reply + .... type-specific data follows + */ + + case SSH_MSG_CHANNEL_REQUEST: + if(datalen >= 9) { + uint32_t channel = _libssh2_ntohu32(data + 1); + uint32_t len = _libssh2_ntohu32(data + 5); + unsigned char want_reply = 1; + + if((len + 9) < datalen) + want_reply = data[len + 9]; + + _libssh2_debug(session, + LIBSSH2_TRACE_CONN, + "Channel %d received request type %.*s (wr %X)", + channel, len, data + 9, want_reply); + + if(len == sizeof("exit-status") - 1 + && (sizeof("exit-status") - 1 + 9) <= datalen + && !memcmp("exit-status", data + 9, + sizeof("exit-status") - 1)) { + + /* we've got "exit-status" packet. Set the session value */ + if(datalen >= 20) + channelp = + _libssh2_channel_locate(session, channel); + + if(channelp && (sizeof("exit-status") + 13) <= datalen) { + channelp->exit_status = + _libssh2_ntohu32(data + 9 + sizeof("exit-status")); + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Exit status %lu received for " + "channel %lu/%lu", + channelp->exit_status, + channelp->local.id, + channelp->remote.id); + } + + } + else if(len == sizeof("exit-signal") - 1 + && (sizeof("exit-signal") - 1 + 9) <= datalen + && !memcmp("exit-signal", data + 9, + sizeof("exit-signal") - 1)) { + /* command terminated due to signal */ + if(datalen >= 20) + channelp = _libssh2_channel_locate(session, channel); + + if(channelp && (sizeof("exit-signal") + 13) <= datalen) { + /* set signal name (without SIG prefix) */ + uint32_t namelen = + _libssh2_ntohu32(data + 9 + sizeof("exit-signal")); + + if(namelen <= UINT_MAX - 1) { + channelp->exit_signal = + LIBSSH2_ALLOC(session, namelen + 1); + } + else { + channelp->exit_signal = NULL; + } + + if(!channelp->exit_signal) + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "memory for signal name"); + else if((sizeof("exit-signal") + 13 + namelen <= + datalen)) { + memcpy(channelp->exit_signal, + data + 13 + sizeof("exit-signal"), namelen); + channelp->exit_signal[namelen] = '\0'; + /* TODO: save error message and language tag */ + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Exit signal %s received for " + "channel %lu/%lu", + channelp->exit_signal, + channelp->local.id, + channelp->remote.id); + } + } + } + + + if(want_reply) { + unsigned char packet[5]; + libssh2_packet_add_jump_point4: + session->packAdd_state = libssh2_NB_state_jump4; + packet[0] = SSH_MSG_CHANNEL_FAILURE; + memcpy(&packet[1], data + 1, 4); + rc = _libssh2_transport_send(session, packet, 5, NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + + /* + byte SSH_MSG_CHANNEL_CLOSE + uint32 recipient channel + */ + + case SSH_MSG_CHANNEL_CLOSE: + if(datalen >= 5) + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if(!channelp) { + /* We may have freed already, just quietly ignore this... */ + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + } + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Close received for channel %lu/%lu", + channelp->local.id, + channelp->remote.id); + + channelp->remote.close = 1; + channelp->remote.eof = 1; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + + /* + byte SSH_MSG_CHANNEL_OPEN + string "session" + uint32 sender channel + uint32 initial window size + uint32 maximum packet size + */ + + case SSH_MSG_CHANNEL_OPEN: + if(datalen < 17) + ; + else if((datalen >= (sizeof("forwarded-tcpip") + 4)) && + ((sizeof("forwarded-tcpip") - 1) == + _libssh2_ntohu32(data + 1)) + && + (memcmp(data + 5, "forwarded-tcpip", + sizeof("forwarded-tcpip") - 1) == 0)) { + + /* init the state struct */ + memset(&session->packAdd_Qlstn_state, 0, + sizeof(session->packAdd_Qlstn_state)); + + libssh2_packet_add_jump_point2: + session->packAdd_state = libssh2_NB_state_jump2; + rc = packet_queue_listener(session, data, datalen, + &session->packAdd_Qlstn_state); + } + else if((datalen >= (sizeof("x11") + 4)) && + ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) && + (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) { + + /* init the state struct */ + memset(&session->packAdd_x11open_state, 0, + sizeof(session->packAdd_x11open_state)); + + libssh2_packet_add_jump_point3: + session->packAdd_state = libssh2_NB_state_jump3; + rc = packet_x11_open(session, data, datalen, + &session->packAdd_x11open_state); + } + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return rc; + + /* + byte SSH_MSG_CHANNEL_WINDOW_ADJUST + uint32 recipient channel + uint32 bytes to add + */ + case SSH_MSG_CHANNEL_WINDOW_ADJUST: + if(datalen < 9) + ; + else { + uint32_t bytestoadd = _libssh2_ntohu32(data + 5); + channelp = + _libssh2_channel_locate(session, + _libssh2_ntohu32(data + 1)); + if(channelp) { + channelp->local.window_size += bytestoadd; + + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Window adjust for channel %lu/%lu, " + "adding %lu bytes, new window_size=%lu", + channelp->local.id, + channelp->remote.id, + bytestoadd, + channelp->local.window_size); + } + } + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return 0; + default: + break; + } + + session->packAdd_state = libssh2_NB_state_sent; + } + + if(session->packAdd_state == libssh2_NB_state_sent) { + LIBSSH2_PACKET *packetp = + LIBSSH2_ALLOC(session, sizeof(LIBSSH2_PACKET)); + if(!packetp) { + _libssh2_debug(session, LIBSSH2_ERROR_ALLOC, + "memory for packet"); + LIBSSH2_FREE(session, data); + session->packAdd_state = libssh2_NB_state_idle; + return LIBSSH2_ERROR_ALLOC; + } + packetp->data = data; + packetp->data_len = datalen; + packetp->data_head = data_head; + + _libssh2_list_add(&session->packets, &packetp->node); + + session->packAdd_state = libssh2_NB_state_sent1; + } + + if((msg == SSH_MSG_KEXINIT && + !(session->state & LIBSSH2_STATE_EXCHANGING_KEYS)) || + (session->packAdd_state == libssh2_NB_state_sent2)) { + if(session->packAdd_state == libssh2_NB_state_sent1) { + /* + * Remote wants new keys + * Well, it's already in the brigade, + * let's just call back into ourselves + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Renegotiating Keys"); + + session->packAdd_state = libssh2_NB_state_sent2; + } + + /* + * The KEXINIT message has been added to the queue. The packAdd and + * readPack states need to be reset because _libssh2_kex_exchange + * (eventually) calls upon _libssh2_transport_read to read the rest of + * the key exchange conversation. + */ + session->readPack_state = libssh2_NB_state_idle; + session->packet.total_num = 0; + session->packAdd_state = libssh2_NB_state_idle; + session->fullpacket_state = libssh2_NB_state_idle; + + memset(&session->startup_key_state, 0, sizeof(key_exchange_state_t)); + + /* + * If there was a key reexchange failure, let's just hope we didn't + * send NEWKEYS yet, otherwise remote will drop us like a rock + */ + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->packAdd_state = libssh2_NB_state_idle; + return 0; +} + +/* + * _libssh2_packet_ask + * + * Scan the brigade for a matching packet type, optionally poll the socket for + * a packet first + */ +int +_libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, const unsigned char *match_buf, + size_t match_len) +{ + LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets); + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Looking for packet of type: %d", (int) packet_type); + + while(packet) { + if(packet->data[0] == packet_type + && (packet->data_len >= (match_ofs + match_len)) + && (!match_buf || + (memcmp(packet->data + match_ofs, match_buf, + match_len) == 0))) { + *data = packet->data; + *data_len = packet->data_len; + + /* unlink struct from session->packets */ + _libssh2_list_remove(&packet->node); + + LIBSSH2_FREE(session, packet); + + return 0; + } + packet = _libssh2_list_next(&packet->node); + } + return -1; +} + +/* + * libssh2_packet_askv + * + * Scan for any of a list of packet types in the brigade, optionally poll the + * socket for a packet first + */ +int +_libssh2_packet_askv(LIBSSH2_SESSION * session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len) +{ + int i, packet_types_len = strlen((char *) packet_types); + + for(i = 0; i < packet_types_len; i++) { + if(0 == _libssh2_packet_ask(session, packet_types[i], data, + data_len, match_ofs, + match_buf, match_len)) { + return 0; + } + } + + return -1; +} + +/* + * _libssh2_packet_require + * + * Loops _libssh2_transport_read() until the packet requested is available + * SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause a bailout + * + * Returns negative on error + * Returns 0 when it has taken care of the requested packet. + */ +int +_libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, + size_t match_len, + packet_require_state_t *state) +{ + if(state->start == 0) { + if(_libssh2_packet_ask(session, packet_type, data, data_len, + match_ofs, match_buf, + match_len) == 0) { + /* A packet was available in the packet brigade */ + return 0; + } + + state->start = time(NULL); + } + + while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + int ret = _libssh2_transport_read(session); + if(ret == LIBSSH2_ERROR_EAGAIN) + return ret; + else if(ret < 0) { + state->start = 0; + /* an error which is not just because of blocking */ + return ret; + } + else if(ret == packet_type) { + /* Be lazy, let packet_ask pull it out of the brigade */ + ret = _libssh2_packet_ask(session, packet_type, data, data_len, + match_ofs, match_buf, match_len); + state->start = 0; + return ret; + } + else if(ret == 0) { + /* nothing available, wait until data arrives or we time out */ + long left = LIBSSH2_READ_TIMEOUT - (long)(time(NULL) - + state->start); + + if(left <= 0) { + state->start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + return -1; /* no packet available yet */ + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* + * _libssh2_packet_burn + * + * Loops _libssh2_transport_read() until any packet is available and promptly + * discards it. + * Used during KEX exchange to discard badly guessed KEX_INIT packets + */ +int +_libssh2_packet_burn(LIBSSH2_SESSION * session, + libssh2_nonblocking_states * state) +{ + unsigned char *data; + size_t data_len; + unsigned char i, all_packets[255]; + int ret; + + if(*state == libssh2_NB_state_idle) { + for(i = 1; i < 255; i++) { + all_packets[i - 1] = i; + } + all_packets[254] = 0; + + if(_libssh2_packet_askv(session, all_packets, &data, &data_len, 0, + NULL, 0) == 0) { + i = data[0]; + /* A packet was available in the packet brigade, burn it */ + LIBSSH2_FREE(session, data); + return i; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Blocking until packet becomes available to burn"); + *state = libssh2_NB_state_created; + } + + while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + ret = _libssh2_transport_read(session); + if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + else if(ret < 0) { + *state = libssh2_NB_state_idle; + return ret; + } + else if(ret == 0) { + /* FIXME: this might busyloop */ + continue; + } + + /* Be lazy, let packet_ask pull it out of the brigade */ + if(0 == + _libssh2_packet_ask(session, (unsigned char)ret, + &data, &data_len, 0, NULL, 0)) { + /* Smoke 'em if you got 'em */ + LIBSSH2_FREE(session, data); + *state = libssh2_NB_state_idle; + return ret; + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* + * _libssh2_packet_requirev + * + * Loops _libssh2_transport_read() until one of a list of packet types + * requested is available. SSH_DISCONNECT or a SOCKET_DISCONNECTED will cause + * a bailout. packet_types is a null terminated list of packet_type numbers + */ + +int +_libssh2_packet_requirev(LIBSSH2_SESSION *session, + const unsigned char *packet_types, + unsigned char **data, size_t *data_len, + int match_ofs, + const unsigned char *match_buf, size_t match_len, + packet_requirev_state_t * state) +{ + if(_libssh2_packet_askv(session, packet_types, data, data_len, match_ofs, + match_buf, match_len) == 0) { + /* One of the packets listed was available in the packet brigade */ + state->start = 0; + return 0; + } + + if(state->start == 0) { + state->start = time(NULL); + } + + while(session->socket_state != LIBSSH2_SOCKET_DISCONNECTED) { + int ret = _libssh2_transport_read(session); + if((ret < 0) && (ret != LIBSSH2_ERROR_EAGAIN)) { + state->start = 0; + return ret; + } + if(ret <= 0) { + long left = LIBSSH2_READ_TIMEOUT - + (long)(time(NULL) - state->start); + + if(left <= 0) { + state->start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + else if(ret == LIBSSH2_ERROR_EAGAIN) { + return ret; + } + } + + if(strchr((char *) packet_types, ret)) { + /* Be lazy, let packet_ask pull it out of the brigade */ + return _libssh2_packet_askv(session, packet_types, data, + data_len, match_ofs, match_buf, + match_len); + } + } + + /* Only reached if the socket died */ + state->start = 0; + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + diff --git a/libssh2/pem.c b/libssh2/pem.c new file mode 100644 index 0000000..53f58c2 --- /dev/null +++ b/libssh2/pem.c @@ -0,0 +1,902 @@ +/* Copyright (C) 2007 The Written Word, Inc. + * Copyright (C) 2008, Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +static int +readline(char *line, int line_size, FILE * fp) +{ + size_t len; + + if(!line) { + return -1; + } + if(!fgets(line, line_size, fp)) { + return -1; + } + + if(*line) { + len = strlen(line); + if(len > 0 && line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + } + + if(*line) { + len = strlen(line); + if(len > 0 && line[len - 1] == '\r') { + line[len - 1] = '\0'; + } + } + + return 0; +} + +static int +readline_memory(char *line, size_t line_size, + const char *filedata, size_t filedata_len, + size_t *filedata_offset) +{ + size_t off, len; + + off = *filedata_offset; + + for(len = 0; off + len < filedata_len && len < line_size - 1; len++) { + if(filedata[off + len] == '\n' || + filedata[off + len] == '\r') { + break; + } + } + + if(len) { + memcpy(line, filedata + off, len); + *filedata_offset += len; + } + + line[len] = '\0'; + *filedata_offset += 1; + + return 0; +} + +#define LINE_SIZE 128 + +static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED"; + +static unsigned char hex_decode(char digit) +{ + return (digit >= 'A') ? 0xA + (digit - 'A') : (digit - '0'); +} + +int +_libssh2_pem_parse(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const unsigned char *passphrase, + FILE * fp, unsigned char **data, unsigned int *datalen) +{ + char line[LINE_SIZE]; + unsigned char iv[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + int ret; + const LIBSSH2_CRYPT_METHOD *method = NULL; + + do { + *line = '\0'; + + if(readline(line, LINE_SIZE, fp)) { + return -1; + } + } + while(strcmp(line, headerbegin) != 0); + + if(readline(line, LINE_SIZE, fp)) { + return -1; + } + + if(passphrase && + memcmp(line, crypt_annotation, strlen(crypt_annotation)) == 0) { + const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method; + int i; + + if(readline(line, LINE_SIZE, fp)) { + ret = -1; + goto out; + } + + all_methods = libssh2_crypt_methods(); + while((cur_method = *all_methods++)) { + if(*cur_method->pem_annotation && + memcmp(line, cur_method->pem_annotation, + strlen(cur_method->pem_annotation)) == 0) { + method = cur_method; + memcpy(iv, line + strlen(method->pem_annotation) + 1, + 2*method->iv_len); + } + } + + /* None of the available crypt methods were able to decrypt the key */ + if(method == NULL) + return -1; + + /* Decode IV from hex */ + for(i = 0; i < method->iv_len; ++i) { + iv[i] = hex_decode(iv[2*i]) << 4; + iv[i] |= hex_decode(iv[2*i + 1]); + } + + /* skip to the next line */ + if(readline(line, LINE_SIZE, fp)) { + ret = -1; + goto out; + } + } + + do { + if(*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if(!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if(readline(line, LINE_SIZE, fp)) { + ret = -1; + goto out; + } + } while(strcmp(line, headerend) != 0); + + if(!b64data) { + return -1; + } + + if(libssh2_base64_decode(session, (char **) data, datalen, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + if(method) { + /* Set up decryption */ + int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0; + int blocksize = method->blocksize; + void *abstract; + unsigned char secret[2*MD5_DIGEST_LENGTH]; + libssh2_md5_ctx fingerprint_ctx; + + /* Perform key derivation (PBKDF1/MD5) */ + if(!libssh2_md5_init(&fingerprint_ctx)) { + ret = -1; + goto out; + } + libssh2_md5_update(fingerprint_ctx, passphrase, + strlen((char *)passphrase)); + libssh2_md5_update(fingerprint_ctx, iv, 8); + libssh2_md5_final(fingerprint_ctx, secret); + if(method->secret_len > MD5_DIGEST_LENGTH) { + if(!libssh2_md5_init(&fingerprint_ctx)) { + ret = -1; + goto out; + } + libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH); + libssh2_md5_update(fingerprint_ctx, passphrase, + strlen((char *)passphrase)); + libssh2_md5_update(fingerprint_ctx, iv, 8); + libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH); + } + + /* Initialize the decryption */ + if(method->init(session, method, iv, &free_iv, secret, + &free_secret, 0, &abstract)) { + _libssh2_explicit_zero((char *)secret, sizeof(secret)); + LIBSSH2_FREE(session, data); + ret = -1; + goto out; + } + + if(free_secret) { + _libssh2_explicit_zero((char *)secret, sizeof(secret)); + } + + /* Do the actual decryption */ + if((*datalen % blocksize) != 0) { + _libssh2_explicit_zero((char *)secret, sizeof(secret)); + method->dtor(session, &abstract); + _libssh2_explicit_zero(*data, *datalen); + LIBSSH2_FREE(session, *data); + ret = -1; + goto out; + } + + while(len_decrypted <= (int)*datalen - blocksize) { + if(method->crypt(session, *data + len_decrypted, blocksize, + &abstract)) { + ret = LIBSSH2_ERROR_DECRYPT; + _libssh2_explicit_zero((char *)secret, sizeof(secret)); + method->dtor(session, &abstract); + _libssh2_explicit_zero(*data, *datalen); + LIBSSH2_FREE(session, *data); + goto out; + } + + len_decrypted += blocksize; + } + + /* Account for padding */ + padding = (*data)[*datalen - 1]; + memset(&(*data)[*datalen-padding], 0, padding); + *datalen -= padding; + + /* Clean up */ + _libssh2_explicit_zero((char *)secret, sizeof(secret)); + method->dtor(session, &abstract); + } + + ret = 0; + out: + if(b64data) { + _libssh2_explicit_zero(b64data, b64datalen); + LIBSSH2_FREE(session, b64data); + } + return ret; +} + +int +_libssh2_pem_parse_memory(LIBSSH2_SESSION * session, + const char *headerbegin, + const char *headerend, + const char *filedata, size_t filedata_len, + unsigned char **data, unsigned int *datalen) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + size_t off = 0; + int ret; + + do { + *line = '\0'; + + if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + return -1; + } + } + while(strcmp(line, headerbegin) != 0); + + *line = '\0'; + + do { + if(*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if(!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + ret = -1; + goto out; + } + } while(strcmp(line, headerend) != 0); + + if(!b64data) { + return -1; + } + + if(libssh2_base64_decode(session, (char **) data, datalen, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + ret = 0; + out: + if(b64data) { + _libssh2_explicit_zero(b64data, b64datalen); + LIBSSH2_FREE(session, b64data); + } + return ret; +} + +/* OpenSSH formatted keys */ +#define AUTH_MAGIC "openssh-key-v1" +#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----" +#define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----" + +static int +_libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session, + const unsigned char *passphrase, + const char *b64data, size_t b64datalen, + struct string_buf **decrypted_buf) +{ + const LIBSSH2_CRYPT_METHOD *method = NULL; + struct string_buf decoded, decrypted, kdf_buf; + unsigned char *ciphername = NULL; + unsigned char *kdfname = NULL; + unsigned char *kdf = NULL; + unsigned char *buf = NULL; + unsigned char *salt = NULL; + uint32_t nkeys, check1, check2; + uint32_t rounds = 0; + unsigned char *key = NULL; + unsigned char *key_part = NULL; + unsigned char *iv_part = NULL; + unsigned char *f = NULL; + unsigned int f_len = 0; + int ret = 0, keylen = 0, ivlen = 0, total_len = 0; + size_t kdf_len = 0, tmp_len = 0, salt_len = 0; + + if(decrypted_buf) + *decrypted_buf = NULL; + + /* decode file */ + if(libssh2_base64_decode(session, (char **)&f, &f_len, + b64data, b64datalen)) { + ret = -1; + goto out; + } + + /* Parse the file */ + decoded.data = (unsigned char *)f; + decoded.dataptr = (unsigned char *)f; + decoded.len = f_len; + + if(decoded.len < strlen(AUTH_MAGIC)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key too short"); + goto out; + } + + if(strncmp((char *) decoded.dataptr, AUTH_MAGIC, + strlen(AUTH_MAGIC)) != 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "key auth magic mismatch"); + goto out; + } + + decoded.dataptr += strlen(AUTH_MAGIC) + 1; + + if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) || + tmp_len == 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "ciphername is missing"); + goto out; + } + + if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) || + tmp_len == 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "kdfname is missing"); + goto out; + } + + if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "kdf is missing"); + goto out; + } + else { + kdf_buf.data = kdf; + kdf_buf.dataptr = kdf; + kdf_buf.len = kdf_len; + } + + if((passphrase == NULL || strlen((const char *)passphrase) == 0) && + strcmp((const char *)ciphername, "none") != 0) { + /* passphrase required */ + ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED; + goto out; + } + + if(strcmp((const char *)kdfname, "none") != 0 && + strcmp((const char *)kdfname, "bcrypt") != 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "unknown cipher"); + goto out; + } + + if(!strcmp((const char *)kdfname, "none") && + strcmp((const char *)ciphername, "none") != 0) { + ret =_libssh2_error(session, LIBSSH2_ERROR_PROTO, + "invalid format"); + goto out; + } + + if(_libssh2_get_u32(&decoded, &nkeys) != 0 || nkeys != 1) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Multiple keys are unsupported"); + goto out; + } + + /* unencrypted public key */ + + if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid private key; " + "expect embedded public key"); + goto out; + } + + if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Private key data not found"); + goto out; + } + + /* decode encrypted private key */ + decrypted.data = decrypted.dataptr = buf; + decrypted.len = tmp_len; + + if(ciphername && strcmp((const char *)ciphername, "none") != 0) { + const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method; + + all_methods = libssh2_crypt_methods(); + while((cur_method = *all_methods++)) { + if(*cur_method->name && + memcmp(ciphername, cur_method->name, + strlen(cur_method->name)) == 0) { + method = cur_method; + } + } + + /* None of the available crypt methods were able to decrypt the key */ + + if(method == NULL) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "No supported cipher found"); + goto out; + } + } + + if(method) { + int free_iv = 0, free_secret = 0, len_decrypted = 0; + int blocksize; + void *abstract = NULL; + + keylen = method->secret_len; + ivlen = method->iv_len; + total_len = keylen + ivlen; + + key = LIBSSH2_CALLOC(session, total_len); + if(key == NULL) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Could not alloc key"); + goto out; + } + + if(strcmp((const char *)kdfname, "bcrypt") == 0 && + passphrase != NULL) { + if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) || + (_libssh2_get_u32(&kdf_buf, &rounds) != 0) ) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "kdf contains unexpected values"); + LIBSSH2_FREE(session, key); + goto out; + } + + if(_libssh2_bcrypt_pbkdf((const char *)passphrase, + strlen((const char *)passphrase), + salt, salt_len, key, + keylen + ivlen, rounds) < 0) { + ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT, + "invalid format"); + LIBSSH2_FREE(session, key); + goto out; + } + } + else { + ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED, + "bcrypted without passphrase"); + LIBSSH2_FREE(session, key); + goto out; + } + + /* Set up decryption */ + blocksize = method->blocksize; + + key_part = LIBSSH2_CALLOC(session, keylen); + if(key_part == NULL) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Could not alloc key part"); + goto out; + } + + iv_part = LIBSSH2_CALLOC(session, ivlen); + if(iv_part == NULL) { + ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Could not alloc iv part"); + goto out; + } + + memcpy(key_part, key, keylen); + memcpy(iv_part, key + keylen, ivlen); + + /* Initialize the decryption */ + if(method->init(session, method, iv_part, &free_iv, key_part, + &free_secret, 0, &abstract)) { + ret = LIBSSH2_ERROR_DECRYPT; + goto out; + } + + /* Do the actual decryption */ + if((decrypted.len % blocksize) != 0) { + method->dtor(session, &abstract); + ret = LIBSSH2_ERROR_DECRYPT; + goto out; + } + + while((size_t)len_decrypted <= decrypted.len - blocksize) { + if(method->crypt(session, decrypted.data + len_decrypted, + blocksize, + &abstract)) { + ret = LIBSSH2_ERROR_DECRYPT; + method->dtor(session, &abstract); + goto out; + } + + len_decrypted += blocksize; + } + + /* No padding */ + + method->dtor(session, &abstract); + } + + /* Check random bytes match */ + + if(_libssh2_get_u32(&decrypted, &check1) != 0 || + _libssh2_get_u32(&decrypted, &check2) != 0 || + check1 != check2) { + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Private key unpack failed (correct password?)"); + ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED; + goto out; + } + + if(decrypted_buf != NULL) { + /* copy data to out-going buffer */ + struct string_buf *out_buf = _libssh2_string_buf_new(session); + if(!out_buf) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "decrypted struct"); + goto out; + } + + out_buf->data = LIBSSH2_CALLOC(session, decrypted.len); + if(out_buf->data == NULL) { + ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "decrypted struct"); + _libssh2_string_buf_free(session, out_buf); + goto out; + } + memcpy(out_buf->data, decrypted.data, decrypted.len); + out_buf->dataptr = out_buf->data + + (decrypted.dataptr - decrypted.data); + out_buf->len = decrypted.len; + + *decrypted_buf = out_buf; + } + +out: + + /* Clean up */ + if(key) { + _libssh2_explicit_zero(key, total_len); + LIBSSH2_FREE(session, key); + } + if(key_part) { + _libssh2_explicit_zero(key_part, keylen); + LIBSSH2_FREE(session, key_part); + } + if(iv_part) { + _libssh2_explicit_zero(iv_part, ivlen); + LIBSSH2_FREE(session, iv_part); + } + if(f) { + _libssh2_explicit_zero(f, f_len); + LIBSSH2_FREE(session, f); + } + + return ret; +} + +int +_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session, + const unsigned char *passphrase, + FILE * fp, struct string_buf **decrypted_buf) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + int ret = 0; + + /* read file */ + + do { + *line = '\0'; + + if(readline(line, LINE_SIZE, fp)) { + return -1; + } + } + while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0); + + if(readline(line, LINE_SIZE, fp)) { + return -1; + } + + do { + if(*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if(!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if(readline(line, LINE_SIZE, fp)) { + ret = -1; + goto out; + } + } while(strcmp(line, OPENSSH_HEADER_END) != 0); + + if(!b64data) { + return -1; + } + + ret = _libssh2_openssh_pem_parse_data(session, + passphrase, + (const char *)b64data, + (size_t)b64datalen, + decrypted_buf); + + if(b64data) { + _libssh2_explicit_zero(b64data, b64datalen); + LIBSSH2_FREE(session, b64data); + } + +out: + + return ret; +} + +int +_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session, + const unsigned char *passphrase, + const char *filedata, size_t filedata_len, + struct string_buf **decrypted_buf) +{ + char line[LINE_SIZE]; + char *b64data = NULL; + unsigned int b64datalen = 0; + size_t off = 0; + int ret; + + if(filedata == NULL || filedata_len <= 0) { + return -1; + } + + do { + + *line = '\0'; + + if(off >= filedata_len) { + return -1; + } + + if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + return -1; + } + } + while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0); + + *line = '\0'; + + do { + if (*line) { + char *tmp; + size_t linelen; + + linelen = strlen(line); + tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen); + if(!tmp) { + ret = -1; + goto out; + } + memcpy(tmp + b64datalen, line, linelen); + b64data = tmp; + b64datalen += linelen; + } + + *line = '\0'; + + if(off >= filedata_len) { + ret = -1; + goto out; + } + + if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) { + ret = -1; + goto out; + } + } while(strcmp(line, OPENSSH_HEADER_END) != 0); + + if(!b64data) { + return -1; + } + + ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data, + b64datalen, decrypted_buf); + +out: + if(b64data) { + _libssh2_explicit_zero(b64data, b64datalen); + LIBSSH2_FREE(session, b64data); + } + return ret; + +} + +static int +read_asn1_length(const unsigned char *data, + unsigned int datalen, unsigned int *len) +{ + unsigned int lenlen; + int nextpos; + + if(datalen < 1) { + return -1; + } + *len = data[0]; + + if(*len >= 0x80) { + lenlen = *len & 0x7F; + *len = data[1]; + if(1 + lenlen > datalen) { + return -1; + } + if(lenlen > 1) { + *len <<= 8; + *len |= data[2]; + } + } + else { + lenlen = 0; + } + + nextpos = 1 + lenlen; + if(lenlen > 2 || 1 + lenlen + *len > datalen) { + return -1; + } + + return nextpos; +} + +int +_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen) +{ + unsigned int len; + int lenlen; + + if(*datalen < 1) { + return -1; + } + + if((*data)[0] != '\x30') { + return -1; + } + + (*data)++; + (*datalen)--; + + lenlen = read_asn1_length(*data, *datalen, &len); + if(lenlen < 0 || lenlen + len != *datalen) { + return -1; + } + + *data += lenlen; + *datalen -= lenlen; + + return 0; +} + +int +_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen, + unsigned char **i, unsigned int *ilen) +{ + unsigned int len; + int lenlen; + + if(*datalen < 1) { + return -1; + } + + if((*data)[0] != '\x02') { + return -1; + } + + (*data)++; + (*datalen)--; + + lenlen = read_asn1_length(*data, *datalen, &len); + if(lenlen < 0 || lenlen + len > *datalen) { + return -1; + } + + *data += lenlen; + *datalen -= lenlen; + + *i = *data; + *ilen = len; + + *data += len; + *datalen -= len; + + return 0; +} diff --git a/libssh2/publickey.c b/libssh2/publickey.c new file mode 100644 index 0000000..f26c632 --- /dev/null +++ b/libssh2/publickey.c @@ -0,0 +1,1278 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2010-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include "libssh2_publickey.h" +#include "channel.h" +#include "session.h" + +#define LIBSSH2_PUBLICKEY_VERSION 2 + +/* Numericised response codes -- Not IETF, just local representation */ +#define LIBSSH2_PUBLICKEY_RESPONSE_STATUS 0 +#define LIBSSH2_PUBLICKEY_RESPONSE_VERSION 1 +#define LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY 2 + +typedef struct _LIBSSH2_PUBLICKEY_CODE_LIST +{ + int code; + const char *name; + int name_len; +} LIBSSH2_PUBLICKEY_CODE_LIST; + +static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_response_codes[] = +{ + {LIBSSH2_PUBLICKEY_RESPONSE_STATUS, "status", sizeof("status") - 1}, + {LIBSSH2_PUBLICKEY_RESPONSE_VERSION, "version", sizeof("version") - 1}, + {LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY, "publickey", + sizeof("publickey") - 1}, + {0, NULL, 0} +}; + +/* PUBLICKEY status codes -- IETF defined */ +#define LIBSSH2_PUBLICKEY_SUCCESS 0 +#define LIBSSH2_PUBLICKEY_ACCESS_DENIED 1 +#define LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED 2 +#define LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED 3 +#define LIBSSH2_PUBLICKEY_KEY_NOT_FOUND 4 +#define LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED 5 +#define LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT 6 +#define LIBSSH2_PUBLICKEY_GENERAL_FAILURE 7 +#define LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED 8 + +#define LIBSSH2_PUBLICKEY_STATUS_CODE_MAX 8 + +static const LIBSSH2_PUBLICKEY_CODE_LIST publickey_status_codes[] = { + {LIBSSH2_PUBLICKEY_SUCCESS, "success", sizeof("success") - 1}, + {LIBSSH2_PUBLICKEY_ACCESS_DENIED, "access denied", + sizeof("access denied") - 1}, + {LIBSSH2_PUBLICKEY_STORAGE_EXCEEDED, "storage exceeded", + sizeof("storage exceeded") - 1}, + {LIBSSH2_PUBLICKEY_VERSION_NOT_SUPPORTED, "version not supported", + sizeof("version not supported") - 1}, + {LIBSSH2_PUBLICKEY_KEY_NOT_FOUND, "key not found", + sizeof("key not found") - 1}, + {LIBSSH2_PUBLICKEY_KEY_NOT_SUPPORTED, "key not supported", + sizeof("key not supported") - 1}, + {LIBSSH2_PUBLICKEY_KEY_ALREADY_PRESENT, "key already present", + sizeof("key already present") - 1}, + {LIBSSH2_PUBLICKEY_GENERAL_FAILURE, "general failure", + sizeof("general failure") - 1}, + {LIBSSH2_PUBLICKEY_REQUEST_NOT_SUPPORTED, "request not supported", + sizeof("request not supported") - 1}, + {0, NULL, 0} +}; + +/* + * publickey_status_error + * + * Format an error message from a status code + */ +static void +publickey_status_error(const LIBSSH2_PUBLICKEY *pkey, + LIBSSH2_SESSION *session, int status) +{ + const char *msg; + + /* GENERAL_FAILURE got remapped between version 1 and 2 */ + if(status == 6 && pkey && pkey->version == 1) { + status = 7; + } + + if(status < 0 || status > LIBSSH2_PUBLICKEY_STATUS_CODE_MAX) { + msg = "unknown"; + } + else { + msg = publickey_status_codes[status].name; + } + + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, msg); +} + +/* + * publickey_packet_receive + * + * Read a packet from the subsystem + */ +static int +publickey_packet_receive(LIBSSH2_PUBLICKEY * pkey, + unsigned char **data, size_t *data_len) +{ + LIBSSH2_CHANNEL *channel = pkey->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char buffer[4]; + int rc; + *data = NULL; /* default to nothing returned */ + *data_len = 0; + + if(pkey->receive_state == libssh2_NB_state_idle) { + rc = _libssh2_channel_read(channel, 0, (char *) buffer, 4); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc != 4) { + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid response from publickey subsystem"); + } + + pkey->receive_packet_len = _libssh2_ntohu32(buffer); + pkey->receive_packet = + LIBSSH2_ALLOC(session, pkey->receive_packet_len); + if(!pkey->receive_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate publickey response " + "buffer"); + } + + pkey->receive_state = libssh2_NB_state_sent; + } + + if(pkey->receive_state == libssh2_NB_state_sent) { + rc = _libssh2_channel_read(channel, 0, (char *) pkey->receive_packet, + pkey->receive_packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc != (int)pkey->receive_packet_len) { + LIBSSH2_FREE(session, pkey->receive_packet); + pkey->receive_packet = NULL; + pkey->receive_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for publickey subsystem " + "response packet"); + } + + *data = pkey->receive_packet; + *data_len = pkey->receive_packet_len; + } + + pkey->receive_state = libssh2_NB_state_idle; + + return 0; +} + +/* publickey_response_id + * + * Translate a string response name to a numeric code + * Data will be incremented by 4 + response_len on success only + */ +static int +publickey_response_id(unsigned char **pdata, size_t data_len) +{ + size_t response_len; + unsigned char *data = *pdata; + const LIBSSH2_PUBLICKEY_CODE_LIST *codes = publickey_response_codes; + + if(data_len < 4) { + /* Malformed response */ + return -1; + } + response_len = _libssh2_ntohu32(data); + data += 4; + data_len -= 4; + if(data_len < response_len) { + /* Malformed response */ + return -1; + } + + while(codes->name) { + if((unsigned long)codes->name_len == response_len && + strncmp(codes->name, (char *) data, response_len) == 0) { + *pdata = data + response_len; + return codes->code; + } + codes++; + } + + return -1; +} + +/* publickey_response_success + * + * Generic helper routine to wait for success response and nothing else + */ +static int +publickey_response_success(LIBSSH2_PUBLICKEY * pkey) +{ + LIBSSH2_SESSION *session = pkey->channel->session; + unsigned char *data, *s; + size_t data_len; + int response; + + while(1) { + int rc = publickey_packet_receive(pkey, &data, &data_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + } + + if(data_len < 4) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Publickey response too small"); + } + + s = data; + response = publickey_response_id(&s, data_len); + + switch(response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status = 0; + + if(data_len < 8) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Publickey response too small"); + } + + status = _libssh2_ntohu32(s); + + LIBSSH2_FREE(session, data); + + if(status == LIBSSH2_PUBLICKEY_SUCCESS) + return 0; + + publickey_status_error(pkey, session, status); + return -1; + } + default: + LIBSSH2_FREE(session, data); + if(response < 0) { + return _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response"); + } + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response"); + data = NULL; + } + } + /* never reached, but include `return` to silence compiler warnings */ + return -1; +} + +/* ***************** + * Publickey API * + ***************** */ + +/* + * publickey_init + * + * Startup the publickey subsystem + */ +static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session) +{ + int response; + int rc; + + if(session->pkeyInit_state == libssh2_NB_state_idle) { + session->pkeyInit_data = NULL; + session->pkeyInit_pkey = NULL; + session->pkeyInit_channel = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Initializing publickey subsystem"); + + session->pkeyInit_state = libssh2_NB_state_allocated; + } + + if(session->pkeyInit_state == libssh2_NB_state_allocated) { + + session->pkeyInit_channel = + _libssh2_channel_open(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if(!session->pkeyInit_channel) { + if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) + /* The error state is already set, so leave it */ + return NULL; + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel"); + goto err_exit; + } + + session->pkeyInit_state = libssh2_NB_state_sent; + } + + if(session->pkeyInit_state == libssh2_NB_state_sent) { + rc = _libssh2_channel_process_startup(session->pkeyInit_channel, + "subsystem", + sizeof("subsystem") - 1, + "publickey", + sizeof("publickey") - 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickey subsystem"); + return NULL; + } + else if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request publickey subsystem"); + goto err_exit; + } + + session->pkeyInit_state = libssh2_NB_state_sent1; + } + + if(session->pkeyInit_state == libssh2_NB_state_sent1) { + unsigned char *s; + rc = _libssh2_channel_extended_data(session->pkeyInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting publickey subsystem"); + return NULL; + } + + session->pkeyInit_pkey = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_PUBLICKEY)); + if(!session->pkeyInit_pkey) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new publickey structure"); + goto err_exit; + } + session->pkeyInit_pkey->channel = session->pkeyInit_channel; + session->pkeyInit_pkey->version = 0; + + s = session->pkeyInit_buffer; + _libssh2_htonu32(s, 4 + (sizeof("version") - 1) + 4); + s += 4; + _libssh2_htonu32(s, sizeof("version") - 1); + s += 4; + memcpy(s, "version", sizeof("version") - 1); + s += sizeof("version") - 1; + _libssh2_htonu32(s, LIBSSH2_PUBLICKEY_VERSION); + + session->pkeyInit_buffer_sent = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey advertising version %d support", + (int) LIBSSH2_PUBLICKEY_VERSION); + + session->pkeyInit_state = libssh2_NB_state_sent2; + } + + if(session->pkeyInit_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_write(session->pkeyInit_channel, 0, + session->pkeyInit_buffer, + 19 - session->pkeyInit_buffer_sent); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending publickey version packet"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, rc, + "Unable to send publickey version packet"); + goto err_exit; + } + session->pkeyInit_buffer_sent += rc; + if(session->pkeyInit_buffer_sent < 19) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Need to be called again to complete this"); + return NULL; + } + + session->pkeyInit_state = libssh2_NB_state_sent3; + } + + if(session->pkeyInit_state == libssh2_NB_state_sent3) { + while(1) { + unsigned char *s; + rc = publickey_packet_receive(session->pkeyInit_pkey, + &session->pkeyInit_data, + &session->pkeyInit_data_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from " + "publickey subsystem"); + return NULL; + } + else if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + goto err_exit; + } + + s = session->pkeyInit_data; + if((response = + publickey_response_id(&s, session->pkeyInit_data_len)) < 0) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response code"); + goto err_exit; + } + + if(session->pkeyInit_data_len < 4) { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Public key init data too small"); + goto err_exit; + } + + switch(response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error */ + { + unsigned long status, descr_len, lang_len; + + if(session->pkeyInit_data_len >= 8) { + status = _libssh2_ntohu32(s); + s += 4; + descr_len = _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Public key init data too small"); + goto err_exit; + } + + if(s + descr_len + 4 <= + session->pkeyInit_data + session->pkeyInit_data_len) { + /* description starts here */ + s += descr_len; + lang_len = _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Public key init data too small"); + goto err_exit; + } + + if(s + lang_len <= + session->pkeyInit_data + session->pkeyInit_data_len) { + /* lang starts here */ + s += lang_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Public key init data too small"); + goto err_exit; + } + + if(s > + session->pkeyInit_data + session->pkeyInit_data_len) { + _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet"); + goto err_exit; + } + + publickey_status_error(NULL, session, status); + + goto err_exit; + } + + case LIBSSH2_PUBLICKEY_RESPONSE_VERSION: + /* What we want */ + session->pkeyInit_pkey->version = _libssh2_ntohu32(s); + if(session->pkeyInit_pkey->version > + LIBSSH2_PUBLICKEY_VERSION) { + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Truncate remote publickey version " + "from %lu", + session->pkeyInit_pkey->version); + session->pkeyInit_pkey->version = + LIBSSH2_PUBLICKEY_VERSION; + } + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Enabling publickey subsystem version %lu", + session->pkeyInit_pkey->version); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + session->pkeyInit_state = libssh2_NB_state_idle; + return session->pkeyInit_pkey; + + default: + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response, " + "ignoring"); + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + } + } + } + + /* Never reached except by direct goto */ + err_exit: + session->pkeyInit_state = libssh2_NB_state_sent4; + if(session->pkeyInit_channel) { + rc = _libssh2_channel_close(session->pkeyInit_channel); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block closing channel"); + return NULL; + } + } + if(session->pkeyInit_pkey) { + LIBSSH2_FREE(session, session->pkeyInit_pkey); + session->pkeyInit_pkey = NULL; + } + if(session->pkeyInit_data) { + LIBSSH2_FREE(session, session->pkeyInit_data); + session->pkeyInit_data = NULL; + } + session->pkeyInit_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_publickey_init + * + * Startup the publickey subsystem + */ +LIBSSH2_API LIBSSH2_PUBLICKEY * +libssh2_publickey_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_PUBLICKEY *ptr; + + BLOCK_ADJUST_ERRNO(ptr, session, + publickey_init(session)); + return ptr; +} + + + +/* + * libssh2_publickey_add_ex + * + * Add a new public key entry + */ +LIBSSH2_API int +libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey, const unsigned char *name, + unsigned long name_len, const unsigned char *blob, + unsigned long blob_len, char overwrite, + unsigned long num_attrs, + const libssh2_publickey_attribute attrs[]) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + /* 19 = packet_len(4) + add_len(4) + "add"(3) + name_len(4) + {name} + blob_len(4) + {blob} */ + unsigned long i, packet_len = 19 + name_len + blob_len; + unsigned char *comment = NULL; + unsigned long comment_len = 0; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if(pkey->add_state == libssh2_NB_state_idle) { + pkey->add_packet = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, "Adding %s publickey", + name); + + if(pkey->version == 1) { + for(i = 0; i < num_attrs; i++) { + /* Search for a comment attribute */ + if(attrs[i].name_len == (sizeof("comment") - 1) && + strncmp(attrs[i].name, "comment", + sizeof("comment") - 1) == 0) { + comment = (unsigned char *) attrs[i].value; + comment_len = attrs[i].value_len; + break; + } + } + packet_len += 4 + comment_len; + } + else { + packet_len += 5; /* overwrite(1) + attribute_count(4) */ + for(i = 0; i < num_attrs; i++) { + packet_len += 9 + attrs[i].name_len + attrs[i].value_len; + /* name_len(4) + value_len(4) + mandatory(1) */ + } + } + + pkey->add_packet = LIBSSH2_ALLOC(session, packet_len); + if(!pkey->add_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey \"add\" packet"); + } + + pkey->add_s = pkey->add_packet; + _libssh2_htonu32(pkey->add_s, packet_len - 4); + pkey->add_s += 4; + _libssh2_htonu32(pkey->add_s, sizeof("add") - 1); + pkey->add_s += 4; + memcpy(pkey->add_s, "add", sizeof("add") - 1); + pkey->add_s += sizeof("add") - 1; + if(pkey->version == 1) { + _libssh2_htonu32(pkey->add_s, comment_len); + pkey->add_s += 4; + if(comment) { + memcpy(pkey->add_s, comment, comment_len); + pkey->add_s += comment_len; + } + + _libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + _libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; + } + else { + /* Version == 2 */ + + _libssh2_htonu32(pkey->add_s, name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, name, name_len); + pkey->add_s += name_len; + _libssh2_htonu32(pkey->add_s, blob_len); + pkey->add_s += 4; + memcpy(pkey->add_s, blob, blob_len); + pkey->add_s += blob_len; + *(pkey->add_s++) = overwrite ? 0x01 : 0; + _libssh2_htonu32(pkey->add_s, num_attrs); + pkey->add_s += 4; + for(i = 0; i < num_attrs; i++) { + _libssh2_htonu32(pkey->add_s, attrs[i].name_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].name, attrs[i].name_len); + pkey->add_s += attrs[i].name_len; + _libssh2_htonu32(pkey->add_s, attrs[i].value_len); + pkey->add_s += 4; + memcpy(pkey->add_s, attrs[i].value, attrs[i].value_len); + pkey->add_s += attrs[i].value_len; + *(pkey->add_s++) = attrs[i].mandatory ? 0x01 : 0; + } + } + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"add\" packet: " + "type=%s blob_len=%ld num_attrs=%ld", + name, blob_len, num_attrs); + + pkey->add_state = libssh2_NB_state_created; + } + + if(pkey->add_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, pkey->add_packet, + (pkey->add_s - pkey->add_packet)); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((pkey->add_s - pkey->add_packet) != rc) { + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey add packet"); + } + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + + pkey->add_state = libssh2_NB_state_sent; + } + + rc = publickey_response_success(pkey); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + + pkey->add_state = libssh2_NB_state_idle; + + return rc; +} + +/* libssh2_publickey_remove_ex + * Remove an existing publickey so that authentication can no longer be + * performed using it + */ +LIBSSH2_API int +libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY * pkey, + const unsigned char *name, unsigned long name_len, + const unsigned char *blob, unsigned long blob_len) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + /* 22 = packet_len(4) + remove_len(4) + "remove"(6) + name_len(4) + {name} + + blob_len(4) + {blob} */ + unsigned long packet_len = 22 + name_len + blob_len; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if(pkey->remove_state == libssh2_NB_state_idle) { + pkey->remove_packet = NULL; + + pkey->remove_packet = LIBSSH2_ALLOC(session, packet_len); + if(!pkey->remove_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey \"remove\" packet"); + } + + pkey->remove_s = pkey->remove_packet; + _libssh2_htonu32(pkey->remove_s, packet_len - 4); + pkey->remove_s += 4; + _libssh2_htonu32(pkey->remove_s, sizeof("remove") - 1); + pkey->remove_s += 4; + memcpy(pkey->remove_s, "remove", sizeof("remove") - 1); + pkey->remove_s += sizeof("remove") - 1; + _libssh2_htonu32(pkey->remove_s, name_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, name, name_len); + pkey->remove_s += name_len; + _libssh2_htonu32(pkey->remove_s, blob_len); + pkey->remove_s += 4; + memcpy(pkey->remove_s, blob, blob_len); + pkey->remove_s += blob_len; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"remove\" packet: " + "type=%s blob_len=%ld", + name, blob_len); + + pkey->remove_state = libssh2_NB_state_created; + } + + if(pkey->remove_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, pkey->remove_packet, + (pkey->remove_s - pkey->remove_packet)); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((pkey->remove_s - pkey->remove_packet) != rc) { + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + pkey->remove_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey remove packet"); + } + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + + pkey->remove_state = libssh2_NB_state_sent; + } + + rc = publickey_response_success(pkey); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + + pkey->remove_state = libssh2_NB_state_idle; + + return rc; +} + +/* libssh2_publickey_list_fetch + * Fetch a list of supported public key from a server + */ +LIBSSH2_API int +libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY * pkey, unsigned long *num_keys, + libssh2_publickey_list ** pkey_list) +{ + LIBSSH2_CHANNEL *channel; + LIBSSH2_SESSION *session; + libssh2_publickey_list *list = NULL; + unsigned long buffer_len = 12, keys = 0, max_keys = 0, i; + /* 12 = packet_len(4) + list_len(4) + "list"(4) */ + int response; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + channel = pkey->channel; + session = channel->session; + + if(pkey->listFetch_state == libssh2_NB_state_idle) { + pkey->listFetch_data = NULL; + + pkey->listFetch_s = pkey->listFetch_buffer; + _libssh2_htonu32(pkey->listFetch_s, buffer_len - 4); + pkey->listFetch_s += 4; + _libssh2_htonu32(pkey->listFetch_s, sizeof("list") - 1); + pkey->listFetch_s += 4; + memcpy(pkey->listFetch_s, "list", sizeof("list") - 1); + pkey->listFetch_s += sizeof("list") - 1; + + _libssh2_debug(session, LIBSSH2_TRACE_PUBLICKEY, + "Sending publickey \"list\" packet"); + + pkey->listFetch_state = libssh2_NB_state_created; + } + + if(pkey->listFetch_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, + pkey->listFetch_buffer, + (pkey->listFetch_s - + pkey->listFetch_buffer)); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((pkey->listFetch_s - pkey->listFetch_buffer) != rc) { + pkey->listFetch_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send publickey list packet"); + } + + pkey->listFetch_state = libssh2_NB_state_sent; + } + + while(1) { + rc = publickey_packet_receive(pkey, &pkey->listFetch_data, + &pkey->listFetch_data_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, + "Timeout waiting for response from " + "publickey subsystem"); + goto err_exit; + } + + pkey->listFetch_s = pkey->listFetch_data; + if((response = + publickey_response_id(&pkey->listFetch_s, + pkey->listFetch_data_len)) < 0) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Invalid publickey subsystem response code"); + goto err_exit; + } + + switch(response) { + case LIBSSH2_PUBLICKEY_RESPONSE_STATUS: + /* Error, or processing complete */ + { + unsigned long status, descr_len, lang_len; + + if(pkey->listFetch_s + 8 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + status = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + descr_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + descr_len + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + /* description starts at pkey->listFetch_s */ + pkey->listFetch_s += descr_len; + lang_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + lang_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + /* lang starts at pkey->listFetch_s */ + pkey->listFetch_s += lang_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s > + pkey->listFetch_data + pkey->listFetch_data_len) { + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Malformed publickey subsystem packet"); + goto err_exit; + } + + if(status == LIBSSH2_PUBLICKEY_SUCCESS) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + *pkey_list = list; + *num_keys = keys; + pkey->listFetch_state = libssh2_NB_state_idle; + return 0; + } + + publickey_status_error(pkey, session, status); + goto err_exit; + } + case LIBSSH2_PUBLICKEY_RESPONSE_PUBLICKEY: + /* What we want */ + if(keys >= max_keys) { + libssh2_publickey_list *newlist; + /* Grow the key list if necessary */ + max_keys += 8; + newlist = + LIBSSH2_REALLOC(session, list, + (max_keys + + 1) * sizeof(libssh2_publickey_list)); + if(!newlist) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey list"); + goto err_exit; + } + list = newlist; + } + if(pkey->version == 1) { + unsigned long comment_len; + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + comment_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(comment_len) { + list[keys].num_attrs = 1; + list[keys].attrs = + LIBSSH2_ALLOC(session, + sizeof(libssh2_publickey_attribute)); + if(!list[keys].attrs) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey attributes"); + goto err_exit; + } + list[keys].attrs[0].name = "comment"; + list[keys].attrs[0].name_len = sizeof("comment") - 1; + list[keys].attrs[0].value = (char *) pkey->listFetch_s; + list[keys].attrs[0].value_len = comment_len; + list[keys].attrs[0].mandatory = 0; + + pkey->listFetch_s += comment_len; + } + else { + list[keys].num_attrs = 0; + list[keys].attrs = NULL; + } + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + list[keys].name_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + list[keys].blob_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + } + else { + /* Version == 2 */ + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].name_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + list[keys].name_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].name = pkey->listFetch_s; + pkey->listFetch_s += list[keys].name_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].blob_len = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + list[keys].blob_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].blob = pkey->listFetch_s; + pkey->listFetch_s += list[keys].blob_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].num_attrs = _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(list[keys].num_attrs) { + list[keys].attrs = + LIBSSH2_ALLOC(session, + list[keys].num_attrs * + sizeof(libssh2_publickey_attribute)); + if(!list[keys].attrs) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "publickey attributes"); + goto err_exit; + } + for(i = 0; i < list[keys].num_attrs; i++) { + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].attrs[i].name_len = + _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + list[keys].attrs[i].name_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].attrs[i].name = + (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].name_len; + } + else { + _libssh2_error(session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + 4 <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].attrs[i].value_len = + _libssh2_ntohu32(pkey->listFetch_s); + pkey->listFetch_s += 4; + } + else { + _libssh2_error(session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + if(pkey->listFetch_s + + list[keys].attrs[i].value_len <= + pkey->listFetch_data + pkey->listFetch_data_len) { + list[keys].attrs[i].value = + (char *) pkey->listFetch_s; + pkey->listFetch_s += list[keys].attrs[i].value_len; + } + else { + _libssh2_error(session, + LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "ListFetch data too short"); + goto err_exit; + } + + /* actually an ignored value */ + list[keys].attrs[i].mandatory = 0; + } + } + else { + list[keys].attrs = NULL; + } + } + /* To be FREEd in libssh2_publickey_list_free() */ + list[keys].packet = pkey->listFetch_data; + keys++; + + list[keys].packet = NULL; /* Terminate the list */ + pkey->listFetch_data = NULL; + break; + default: + /* Unknown/Unexpected */ + _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_PROTOCOL, + "Unexpected publickey subsystem response"); + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + } + + /* Only reached via explicit goto */ + err_exit: + if(pkey->listFetch_data) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + if(list) { + libssh2_publickey_list_free(pkey, list); + } + pkey->listFetch_state = libssh2_NB_state_idle; + return -1; +} + +/* libssh2_publickey_list_free + * Free a previously fetched list of public keys + */ +LIBSSH2_API void +libssh2_publickey_list_free(LIBSSH2_PUBLICKEY * pkey, + libssh2_publickey_list * pkey_list) +{ + LIBSSH2_SESSION *session; + libssh2_publickey_list *p = pkey_list; + + if(!pkey || !p) + return; + + session = pkey->channel->session; + + while(p->packet) { + if(p->attrs) { + LIBSSH2_FREE(session, p->attrs); + } + LIBSSH2_FREE(session, p->packet); + p++; + } + + LIBSSH2_FREE(session, pkey_list); +} + +/* libssh2_publickey_shutdown + * Shutdown the publickey subsystem + */ +LIBSSH2_API int +libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey) +{ + LIBSSH2_SESSION *session; + int rc; + + if(!pkey) + return LIBSSH2_ERROR_BAD_USE; + + session = pkey->channel->session; + + /* + * Make sure all memory used in the state variables are free + */ + if(pkey->receive_packet) { + LIBSSH2_FREE(session, pkey->receive_packet); + pkey->receive_packet = NULL; + } + if(pkey->add_packet) { + LIBSSH2_FREE(session, pkey->add_packet); + pkey->add_packet = NULL; + } + if(pkey->remove_packet) { + LIBSSH2_FREE(session, pkey->remove_packet); + pkey->remove_packet = NULL; + } + if(pkey->listFetch_data) { + LIBSSH2_FREE(session, pkey->listFetch_data); + pkey->listFetch_data = NULL; + } + + rc = _libssh2_channel_free(pkey->channel); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + LIBSSH2_FREE(session, pkey); + return 0; +} diff --git a/libssh2/scp.c b/libssh2/scp.c new file mode 100644 index 0000000..a9d2db5 --- /dev/null +++ b/libssh2/scp.c @@ -0,0 +1,1145 @@ +/* Copyright (c) 2009-2019 by Daniel Stenberg + * Copyright (c) 2004-2008, Sara Golemon + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#include + +#include "channel.h" +#include "session.h" + + +/* Max. length of a quoted string after libssh2_shell_quotearg() processing */ +#define _libssh2_shell_quotedsize(s) (3 * strlen(s) + 2) + +/* + This function quotes a string in a way suitable to be used with a + shell, e.g. the file name + one two + becomes + 'one two' + + The resulting output string is crafted in a way that makes it usable + with the two most common shell types: Bourne Shell derived shells + (sh, ksh, ksh93, bash, zsh) and C-Shell derivates (csh, tcsh). + + The following special cases are handled: + o If the string contains an apostrophy itself, the apostrophy + character is written in quotation marks, e.g. "'". + The shell cannot handle the syntax 'doesn\'t', so we close the + current argument word, add the apostrophe in quotation marks "", + and open a new argument word instead (_ indicate the input + string characters): + _____ _ _ + 'doesn' "'" 't' + + Sequences of apostrophes are combined in one pair of quotation marks: + a'''b + becomes + _ ___ _ + 'a'"'''"'b' + + o If the string contains an exclamation mark (!), the C-Shell + interprets it as an event number. Using \! (not within quotation + marks or single quotation marks) is a mechanism understood by + both Bourne Shell and C-Shell. + + If a quotation was already started, the argument word is closed + first: + a!b + + become + _ _ _ + 'a'\!'b' + + The result buffer must be large enough for the expanded result. A + bad case regarding expansion is alternating characters and + apostrophes: + + a'b'c'd' (length 8) gets converted to + 'a'"'"'b'"'"'c'"'"'d'"'" (length 24) + + This is the worst case. + + Maximum length of the result: + 1 + 6 * (length(input) + 1) / 2) + 1 + + => 3 * length(input) + 2 + + Explanation: + o leading apostrophe + o one character / apostrophe pair (two characters) can get + represented as 6 characters: a' -> a'"'"' + o String terminator (+1) + + A result buffer three times the size of the input buffer + 2 + characters should be safe. + + References: + o csh-compatible quotation (special handling for '!' etc.), see + http://www.grymoire.com/Unix/Csh.html#toc-uh-10 + + Return value: + Length of the resulting string (not counting the terminating '\0'), + or 0 in case of errors, e.g. result buffer too small + + Note: this function could possible be used elsewhere within libssh2, but + until then it is kept static and in this source file. +*/ + +static unsigned +shell_quotearg(const char *path, unsigned char *buf, + unsigned bufsize) +{ + const char *src; + unsigned char *dst, *endp; + + /* + * Processing States: + * UQSTRING: unquoted string: ... -- used for quoting exclamation + * marks. This is the initial state + * SQSTRING: single-quoted-string: '... -- any character may follow + * QSTRING: quoted string: "... -- only apostrophes may follow + */ + enum { UQSTRING, SQSTRING, QSTRING } state = UQSTRING; + + endp = &buf[bufsize]; + src = path; + dst = buf; + while(*src && dst < endp - 1) { + + switch(*src) { + /* + * Special handling for apostrophe. + * An apostrophe is always written in quotation marks, e.g. + * ' -> "'". + */ + + case '\'': + switch(state) { + case UQSTRING: /* Unquoted string */ + if(dst + 1 >= endp) + return 0; + *dst++ = '"'; + break; + case QSTRING: /* Continue quoted string */ + break; + case SQSTRING: /* Close single quoted string */ + if(dst + 2 >= endp) + return 0; + *dst++ = '\''; + *dst++ = '"'; + break; + default: + break; + } + state = QSTRING; + break; + + /* + * Special handling for exclamation marks. CSH interprets + * exclamation marks even when quoted with apostrophes. We convert + * it to the plain string \!, because both Bourne Shell and CSH + * interpret that as a verbatim exclamation mark. + */ + + case '!': + switch(state) { + case UQSTRING: + if(dst + 1 >= endp) + return 0; + *dst++ = '\\'; + break; + case QSTRING: + if(dst + 2 >= endp) + return 0; + *dst++ = '"'; /* Closing quotation mark */ + *dst++ = '\\'; + break; + case SQSTRING: /* Close single quoted string */ + if(dst + 2 >= endp) + return 0; + *dst++ = '\''; + *dst++ = '\\'; + break; + default: + break; + } + state = UQSTRING; + break; + + /* + * Ordinary character: prefer single-quoted string + */ + + default: + switch(state) { + case UQSTRING: + if(dst + 1 >= endp) + return 0; + *dst++ = '\''; + break; + case QSTRING: + if(dst + 2 >= endp) + return 0; + *dst++ = '"'; /* Closing quotation mark */ + *dst++ = '\''; + break; + case SQSTRING: /* Continue single quoted string */ + break; + default: + break; + } + state = SQSTRING; /* Start single-quoted string */ + break; + } + + if(dst + 1 >= endp) + return 0; + *dst++ = *src++; + } + + switch(state) { + case UQSTRING: + break; + case QSTRING: /* Close quoted string */ + if(dst + 1 >= endp) + return 0; + *dst++ = '"'; + break; + case SQSTRING: /* Close single quoted string */ + if(dst + 1 >= endp) + return 0; + *dst++ = '\''; + break; + default: + break; + } + + if(dst + 1 >= endp) + return 0; + *dst = '\0'; + + /* The result cannot be larger than 3 * strlen(path) + 2 */ + /* assert((dst - buf) <= (3 * (src - path) + 2)); */ + + return dst - buf; +} + +/* + * scp_recv + * + * Open a channel and request a remote file via SCP + * + */ +static LIBSSH2_CHANNEL * +scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb) +{ + int cmd_len; + int rc; + int tmp_err_code; + const char *tmp_err_msg; + + if(session->scpRecv_state == libssh2_NB_state_idle) { + session->scpRecv_mode = 0; + session->scpRecv_size = 0; + session->scpRecv_mtime = 0; + session->scpRecv_atime = 0; + + session->scpRecv_command_len = + _libssh2_shell_quotedsize(path) + sizeof("scp -f ") + (sb?1:0); + + session->scpRecv_command = + LIBSSH2_ALLOC(session, session->scpRecv_command_len); + + if(!session->scpRecv_command) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for " + "SCP session"); + return NULL; + } + + snprintf((char *)session->scpRecv_command, + session->scpRecv_command_len, + "scp -%sf ", sb?"p":""); + + cmd_len = strlen((char *)session->scpRecv_command); + cmd_len += shell_quotearg(path, + &session->scpRecv_command[cmd_len], + session->scpRecv_command_len - cmd_len); + + /* the command to exec should _not_ be NUL-terminated */ + session->scpRecv_command_len = cmd_len; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "Opening channel for SCP receive"); + + session->scpRecv_state = libssh2_NB_state_created; + } + + if(session->scpRecv_state == libssh2_NB_state_created) { + /* Allocate a channel */ + session->scpRecv_channel = + _libssh2_channel_open(session, "session", + sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, + 0); + if(!session->scpRecv_channel) { + if(libssh2_session_last_errno(session) != + LIBSSH2_ERROR_EAGAIN) { + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + session->scpRecv_state = libssh2_NB_state_idle; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + return NULL; + } + + session->scpRecv_state = libssh2_NB_state_sent; + } + + if(session->scpRecv_state == libssh2_NB_state_sent) { + /* Request SCP for the desired file */ + rc = _libssh2_channel_process_startup(session->scpRecv_channel, "exec", + sizeof("exec") - 1, + (char *)session->scpRecv_command, + session->scpRecv_command_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup"); + return NULL; + } + else if(rc) { + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + goto scp_recv_error; + } + LIBSSH2_FREE(session, session->scpRecv_command); + session->scpRecv_command = NULL; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sending initial wakeup"); + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent1; + } + + if(session->scpRecv_state == libssh2_NB_state_sent1) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending initial wakeup"); + return NULL; + } + else if(rc != 1) { + goto scp_recv_error; + } + + /* Parse SCP response */ + session->scpRecv_response_len = 0; + + session->scpRecv_state = libssh2_NB_state_sent2; + } + + if((session->scpRecv_state == libssh2_NB_state_sent2) + || (session->scpRecv_state == libssh2_NB_state_sent3)) { + while(sb && (session->scpRecv_response_len < + LIBSSH2_SCP_RESPONSE_BUFLEN)) { + unsigned char *s, *p; + + if(session->scpRecv_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_read(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response"); + return NULL; + } + else if(rc < 0) { + /* error, give up */ + _libssh2_error(session, rc, "Failed reading SCP response"); + goto scp_recv_error; + } + else if(rc == 0) + goto scp_recv_empty_channel; + + session->scpRecv_response_len++; + + if(session->scpRecv_response[0] != 'T') { + size_t err_len; + char *err_msg; + + /* there can be + 01 for warnings + 02 for errors + + The following string MUST be newline terminated + */ + err_len = + _libssh2_channel_packet_data_len(session-> + scpRecv_channel, 0); + err_msg = LIBSSH2_ALLOC(session, err_len + 1); + if(!err_msg) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed to get memory "); + goto scp_recv_error; + } + + /* Read the remote error message */ + (void)_libssh2_channel_read(session->scpRecv_channel, 0, + err_msg, err_len); + /* If it failed for any reason, we ignore it anyway. */ + + /* zero terminate the error */ + err_msg[err_len] = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "got %02x %s", session->scpRecv_response[0], + err_msg); + + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Failed to recv file"); + + LIBSSH2_FREE(session, err_msg); + goto scp_recv_error; + } + + if((session->scpRecv_response_len > 1) && + ((session-> + scpRecv_response[session->scpRecv_response_len - 1] < + '0') + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] > + '9')) + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + ' ') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response"); + goto scp_recv_error; + } + + if((session->scpRecv_response_len < 9) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if(session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response from " + "SCP server"); + goto scp_recv_error; + } + /* Way too short to be an SCP response, or not done yet, + short circuit */ + continue; + } + + /* We're guaranteed not to go under response_len == 0 by the + logic above */ + while((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) + session->scpRecv_response_len--; + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; + + if(session->scpRecv_response_len < 8) { + /* EOL came too soon */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "too short"); + goto scp_recv_error; + } + + s = session->scpRecv_response + 1; + + p = (unsigned char *) strchr((char *) s, ' '); + if(!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "malformed mtime"); + goto scp_recv_error; + } + + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_mtime = strtol((char *) s, NULL, 10); + + s = (unsigned char *) strchr((char *) p, ' '); + if(!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "malformed mtime.usec"); + goto scp_recv_error; + } + + /* Ignore mtime.usec */ + s++; + p = (unsigned char *) strchr((char *) s, ' '); + if(!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "too short or malformed"); + goto scp_recv_error; + } + + *p = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_atime = strtol((char *) s, NULL, 10); + + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent3; + } + + if(session->scpRecv_state == libssh2_NB_state_sent3) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting to send SCP ACK"); + return NULL; + } + else if(rc != 1) { + goto scp_recv_error; + } + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "mtime = %ld, atime = %ld", + session->scpRecv_mtime, session->scpRecv_atime); + + /* We *should* check that atime.usec is valid, but why let + that stop use? */ + break; + } + } + + session->scpRecv_state = libssh2_NB_state_sent4; + } + + if(session->scpRecv_state == libssh2_NB_state_sent4) { + session->scpRecv_response_len = 0; + + session->scpRecv_state = libssh2_NB_state_sent5; + } + + if((session->scpRecv_state == libssh2_NB_state_sent5) + || (session->scpRecv_state == libssh2_NB_state_sent6)) { + while(session->scpRecv_response_len < LIBSSH2_SCP_RESPONSE_BUFLEN) { + char *s, *p, *e = NULL; + + if(session->scpRecv_state == libssh2_NB_state_sent5) { + rc = _libssh2_channel_read(session->scpRecv_channel, 0, + (char *) session-> + scpRecv_response + + session->scpRecv_response_len, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for SCP response"); + return NULL; + } + else if(rc < 0) { + /* error, bail out*/ + _libssh2_error(session, rc, "Failed reading SCP response"); + goto scp_recv_error; + } + else if(rc == 0) + goto scp_recv_empty_channel; + + session->scpRecv_response_len++; + + if(session->scpRecv_response[0] != 'C') { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server"); + goto scp_recv_error; + } + + if((session->scpRecv_response_len > 1) && + (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\r') + && (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n') + && + (session-> + scpRecv_response[session->scpRecv_response_len - 1] + < 32)) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid data in SCP response"); + goto scp_recv_error; + } + + if((session->scpRecv_response_len < 7) + || (session-> + scpRecv_response[session->scpRecv_response_len - 1] != + '\n')) { + if(session->scpRecv_response_len == + LIBSSH2_SCP_RESPONSE_BUFLEN) { + /* You had your chance */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unterminated response " + "from SCP server"); + goto scp_recv_error; + } + /* Way too short to be an SCP response, or not done yet, + short circuit */ + continue; + } + + /* We're guaranteed not to go under response_len == 0 by the + logic above */ + while((session-> + scpRecv_response[session->scpRecv_response_len - 1] == + '\r') + || (session-> + scpRecv_response[session->scpRecv_response_len - + 1] == '\n')) { + session->scpRecv_response_len--; + } + session->scpRecv_response[session->scpRecv_response_len] = + '\0'; + + if(session->scpRecv_response_len < 6) { + /* EOL came too soon */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "too short"); + goto scp_recv_error; + } + + s = (char *) session->scpRecv_response + 1; + + p = strchr(s, ' '); + if(!p || ((p - s) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "malformed mode"); + goto scp_recv_error; + } + + *(p++) = '\0'; + /* Make sure we don't get fooled by leftover values */ + + session->scpRecv_mode = strtol(s, &e, 8); + if(e && *e) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "invalid mode"); + goto scp_recv_error; + } + + s = strchr(p, ' '); + if(!s || ((s - p) <= 0)) { + /* No spaces or space in the wrong spot */ + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "too short or malformed"); + goto scp_recv_error; + } + + *s = '\0'; + /* Make sure we don't get fooled by leftover values */ + session->scpRecv_size = scpsize_strtol(p, &e, 10); + if(e && *e) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid response from SCP server, " + "invalid size"); + goto scp_recv_error; + } + + /* SCP ACK */ + session->scpRecv_response[0] = '\0'; + + session->scpRecv_state = libssh2_NB_state_sent6; + } + + if(session->scpRecv_state == libssh2_NB_state_sent6) { + rc = _libssh2_channel_write(session->scpRecv_channel, 0, + session->scpRecv_response, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SCP ACK"); + return NULL; + } + else if(rc != 1) { + goto scp_recv_error; + } + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "mode = 0%lo size = %ld", session->scpRecv_mode, + session->scpRecv_size); + + /* We *should* check that basename is valid, but why let that + stop us? */ + break; + } + } + + session->scpRecv_state = libssh2_NB_state_sent7; + } + + if(sb) { + memset(sb, 0, sizeof(libssh2_struct_stat)); + + sb->st_mtime = session->scpRecv_mtime; + sb->st_atime = session->scpRecv_atime; + sb->st_size = session->scpRecv_size; + sb->st_mode = (unsigned short)session->scpRecv_mode; + } + + session->scpRecv_state = libssh2_NB_state_idle; + return session->scpRecv_channel; + + scp_recv_empty_channel: + /* the code only jumps here as a result of a zero read from channel_read() + so we check EOF status to avoid getting stuck in a loop */ + if(libssh2_channel_eof(session->scpRecv_channel)) + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unexpected channel close"); + else + return session->scpRecv_channel; + /* fall-through */ + scp_recv_error: + tmp_err_code = session->err_code; + tmp_err_msg = session->err_msg; + while(libssh2_channel_free(session->scpRecv_channel) == + LIBSSH2_ERROR_EAGAIN); + session->err_code = tmp_err_code; + session->err_msg = tmp_err_msg; + session->scpRecv_channel = NULL; + session->scpRecv_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_scp_recv + * + * DEPRECATED + * + * Open a channel and request a remote file via SCP. This receives files + * larger than 2 GB, but is unable to report the proper size on platforms + * where the st_size member of struct stat is limited to 2 GB (e.g. windows). + * + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat * sb) +{ + LIBSSH2_CHANNEL *ptr; + + /* scp_recv uses libssh2_struct_stat, so pass one if the caller gave us a + struct to populate... */ + libssh2_struct_stat sb_intl; + libssh2_struct_stat *sb_ptr; + memset(&sb_intl, 0, sizeof(sb_intl)); + sb_ptr = sb ? &sb_intl : NULL; + + BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb_ptr)); + + /* ...and populate the caller's with as much info as fits. */ + if(sb) { + memset(sb, 0, sizeof(struct stat)); + + sb->st_mtime = sb_intl.st_mtime; + sb->st_atime = sb_intl.st_atime; + sb->st_size = (off_t)sb_intl.st_size; + sb->st_mode = sb_intl.st_mode; + } + + return ptr; +} + +/* + * libssh2_scp_recv2 + * + * Open a channel and request a remote file via SCP. This supports files > 2GB + * on platforms that support it. + * + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_recv2(LIBSSH2_SESSION *session, const char *path, + libssh2_struct_stat *sb) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, scp_recv(session, path, sb)); + return ptr; +} + +/* + * scp_send() + * + * Send a file using SCP + * + */ +static LIBSSH2_CHANNEL * +scp_send(LIBSSH2_SESSION * session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime) +{ + int cmd_len; + int rc; + int tmp_err_code; + const char *tmp_err_msg; + + if(session->scpSend_state == libssh2_NB_state_idle) { + session->scpSend_command_len = + _libssh2_shell_quotedsize(path) + sizeof("scp -t ") + + ((mtime || atime)?1:0); + + session->scpSend_command = + LIBSSH2_ALLOC(session, session->scpSend_command_len); + + if(!session->scpSend_command) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a command buffer for " + "SCP session"); + return NULL; + } + + snprintf((char *)session->scpSend_command, + session->scpSend_command_len, + "scp -%st ", (mtime || atime)?"p":""); + + cmd_len = strlen((char *)session->scpSend_command); + cmd_len += shell_quotearg(path, + &session->scpSend_command[cmd_len], + session->scpSend_command_len - cmd_len); + + /* the command to exec should _not_ be NUL-terminated */ + session->scpSend_command_len = cmd_len; + + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "Opening channel for SCP send"); + /* Allocate a channel */ + + session->scpSend_state = libssh2_NB_state_created; + } + + if(session->scpSend_state == libssh2_NB_state_created) { + session->scpSend_channel = + _libssh2_channel_open(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + if(!session->scpSend_channel) { + if(libssh2_session_last_errno(session) != LIBSSH2_ERROR_EAGAIN) { + /* previous call set libssh2_session_last_error(), pass it + through */ + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + session->scpSend_state = libssh2_NB_state_idle; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + return NULL; + } + + session->scpSend_state = libssh2_NB_state_sent; + } + + if(session->scpSend_state == libssh2_NB_state_sent) { + /* Request SCP for the desired file */ + rc = _libssh2_channel_process_startup(session->scpSend_channel, "exec", + sizeof("exec") - 1, + (char *)session->scpSend_command, + session->scpSend_command_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting SCP startup"); + return NULL; + } + else if(rc) { + /* previous call set libssh2_session_last_error(), pass it + through */ + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unknown error while getting error string"); + goto scp_send_error; + } + LIBSSH2_FREE(session, session->scpSend_command); + session->scpSend_command = NULL; + + session->scpSend_state = libssh2_NB_state_sent1; + } + + if(session->scpSend_state == libssh2_NB_state_sent1) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response from remote"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, rc, "SCP failure"); + goto scp_send_error; + } + else if(!rc) + /* remain in the same state */ + goto scp_send_empty_channel; + else if(session->scpSend_response[0] != 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote"); + goto scp_send_error; + } + if(mtime || atime) { + /* Send mtime and atime to be used for file */ + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "T%ld 0 %ld 0\n", + (long)mtime, (long)atime); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", + session->scpSend_response); + } + + session->scpSend_state = libssh2_NB_state_sent2; + } + + /* Send mtime and atime to be used for file */ + if(mtime || atime) { + if(session->scpSend_state == libssh2_NB_state_sent2) { + rc = _libssh2_channel_write(session->scpSend_channel, 0, + session->scpSend_response, + session->scpSend_response_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending time data for SCP file"); + return NULL; + } + else if(rc != (int)session->scpSend_response_len) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send time data for SCP file"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent3; + } + + if(session->scpSend_state == libssh2_NB_state_sent3) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, rc, "SCP failure"); + goto scp_send_error; + } + else if(!rc) + /* remain in the same state */ + goto scp_send_empty_channel; + else if(session->scpSend_response[0] != 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid SCP ACK response"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent4; + } + } + else { + if(session->scpSend_state == libssh2_NB_state_sent2) { + session->scpSend_state = libssh2_NB_state_sent4; + } + } + + if(session->scpSend_state == libssh2_NB_state_sent4) { + /* Send mode, size, and basename */ + const char *base = strrchr(path, '/'); + if(base) + base++; + else + base = path; + + session->scpSend_response_len = + snprintf((char *) session->scpSend_response, + LIBSSH2_SCP_RESPONSE_BUFLEN, "C0%o %" + LIBSSH2_INT64_T_FORMAT " %s\n", mode, + size, base); + _libssh2_debug(session, LIBSSH2_TRACE_SCP, "Sent %s", + session->scpSend_response); + + session->scpSend_state = libssh2_NB_state_sent5; + } + + if(session->scpSend_state == libssh2_NB_state_sent5) { + rc = _libssh2_channel_write(session->scpSend_channel, 0, + session->scpSend_response, + session->scpSend_response_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block send core file data for SCP file"); + return NULL; + } + else if(rc != (int)session->scpSend_response_len) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send core file data for SCP file"); + goto scp_send_error; + } + + session->scpSend_state = libssh2_NB_state_sent6; + } + + if(session->scpSend_state == libssh2_NB_state_sent6) { + /* Wait for ACK */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + (char *) session->scpSend_response, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for response"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Invalid ACK response from remote"); + goto scp_send_error; + } + else if(rc == 0) + goto scp_send_empty_channel; + + else if(session->scpSend_response[0] != 0) { + size_t err_len; + char *err_msg; + + err_len = + _libssh2_channel_packet_data_len(session->scpSend_channel, 0); + err_msg = LIBSSH2_ALLOC(session, err_len + 1); + if(!err_msg) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "failed to get memory"); + goto scp_send_error; + } + + /* Read the remote error message */ + rc = _libssh2_channel_read(session->scpSend_channel, 0, + err_msg, err_len); + if(rc > 0) { + err_msg[err_len] = 0; + _libssh2_debug(session, LIBSSH2_TRACE_SCP, + "got %02x %s", session->scpSend_response[0], + err_msg); + } + LIBSSH2_FREE(session, err_msg); + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "failed to send file"); + goto scp_send_error; + } + } + + session->scpSend_state = libssh2_NB_state_idle; + return session->scpSend_channel; + + scp_send_empty_channel: + /* the code only jumps here as a result of a zero read from channel_read() + so we check EOF status to avoid getting stuck in a loop */ + if(libssh2_channel_eof(session->scpSend_channel)) { + _libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL, + "Unexpected channel close"); + } + else + return session->scpSend_channel; + /* fall-through */ + scp_send_error: + tmp_err_code = session->err_code; + tmp_err_msg = session->err_msg; + while(libssh2_channel_free(session->scpSend_channel) == + LIBSSH2_ERROR_EAGAIN); + session->err_code = tmp_err_code; + session->err_msg = tmp_err_msg; + session->scpSend_channel = NULL; + session->scpSend_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_scp_send_ex + * + * Send a file using SCP. Old API. + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send_ex(LIBSSH2_SESSION *session, const char *path, int mode, + size_t size, long mtime, long atime) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + scp_send(session, path, mode, size, + (time_t)mtime, (time_t)atime)); + return ptr; +} + +/* + * libssh2_scp_send64 + * + * Send a file using SCP + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_scp_send64(LIBSSH2_SESSION *session, const char *path, int mode, + libssh2_int64_t size, time_t mtime, time_t atime) +{ + LIBSSH2_CHANNEL *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + scp_send(session, path, mode, size, mtime, atime)); + return ptr; +} diff --git a/libssh2/session.c b/libssh2/session.c new file mode 100644 index 0000000..256eb99 --- /dev/null +++ b/libssh2/session.c @@ -0,0 +1,1832 @@ +/* Copyright (c) 2004-2007 Sara Golemon + * Copyright (c) 2009-2015 by Daniel Stenberg + * Copyright (c) 2010 Simon Josefsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#ifdef HAVE_GETTIMEOFDAY +#include +#endif +#ifdef HAVE_ALLOCA_H +#include +#endif + +#include "transport.h" +#include "session.h" +#include "channel.h" +#include "mac.h" +#include "misc.h" + +/* libssh2_default_alloc + */ +static +LIBSSH2_ALLOC_FUNC(libssh2_default_alloc) +{ + (void) abstract; + return malloc(count); +} + +/* libssh2_default_free + */ +static +LIBSSH2_FREE_FUNC(libssh2_default_free) +{ + (void) abstract; + free(ptr); +} + +/* libssh2_default_realloc + */ +static +LIBSSH2_REALLOC_FUNC(libssh2_default_realloc) +{ + (void) abstract; + return realloc(ptr, count); +} + +/* + * banner_receive + * + * Wait for a hello from the remote host + * Allocate a buffer and store the banner in session->remote.banner + * Returns: 0 on success, LIBSSH2_ERROR_EAGAIN if read would block, negative + * on failure + */ +static int +banner_receive(LIBSSH2_SESSION * session) +{ + int ret; + int banner_len; + + if(session->banner_TxRx_state == libssh2_NB_state_idle) { + banner_len = 0; + + session->banner_TxRx_state = libssh2_NB_state_created; + } + else { + banner_len = session->banner_TxRx_total_send; + } + + while((banner_len < (int) sizeof(session->banner_TxRx_banner)) && + ((banner_len == 0) + || (session->banner_TxRx_banner[banner_len - 1] != '\n'))) { + char c = '\0'; + + /* no incoming block yet! */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; + + ret = LIBSSH2_RECV(session, &c, 1, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if(ret < 0) { + if(session->api_block_mode || (ret != -EAGAIN)) + /* ignore EAGAIN when non-blocking */ + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error recving %d bytes: %d", 1, -ret); + } + else + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Recved %d bytes banner", ret); + + if(ret < 0) { + if(ret == -EAGAIN) { + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_INBOUND; + session->banner_TxRx_total_send = banner_len; + return LIBSSH2_ERROR_EAGAIN; + } + + /* Some kinda error */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_SOCKET_RECV; + } + + if(ret == 0) { + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + return LIBSSH2_ERROR_SOCKET_DISCONNECT; + } + + if(c == '\0') { + /* NULLs are not allowed in SSH banners */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_BANNER_RECV; + } + + session->banner_TxRx_banner[banner_len++] = c; + } + + while(banner_len && + ((session->banner_TxRx_banner[banner_len - 1] == '\n') || + (session->banner_TxRx_banner[banner_len - 1] == '\r'))) { + banner_len--; + } + + /* From this point on, we are done here */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + + if(!banner_len) + return LIBSSH2_ERROR_BANNER_RECV; + + if(session->remote.banner) + LIBSSH2_FREE(session, session->remote.banner); + + session->remote.banner = LIBSSH2_ALLOC(session, banner_len + 1); + if(!session->remote.banner) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Error allocating space for remote banner"); + } + memcpy(session->remote.banner, session->banner_TxRx_banner, banner_len); + session->remote.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Received Banner: %s", + session->remote.banner); + return LIBSSH2_ERROR_NONE; +} + +/* + * banner_send + * + * Send the default banner, or the one set via libssh2_setopt_string + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block - and if it does so, you + * should call this function again as soon as it is likely that more data can + * be sent, and this function should then be called with the same argument set + * (same data pointer and same data_len) until zero or failure is returned. + */ +static int +banner_send(LIBSSH2_SESSION * session) +{ + char *banner = (char *) LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF; + int banner_len = sizeof(LIBSSH2_SSH_DEFAULT_BANNER_WITH_CRLF) - 1; + ssize_t ret; +#ifdef LIBSSH2DEBUG + char banner_dup[256]; +#endif + + if(session->banner_TxRx_state == libssh2_NB_state_idle) { + if(session->local.banner) { + /* setopt_string will have given us our \r\n characters */ + banner_len = strlen((char *) session->local.banner); + banner = (char *) session->local.banner; + } +#ifdef LIBSSH2DEBUG + /* Hack and slash to avoid sending CRLF in debug output */ + if(banner_len < 256) { + memcpy(banner_dup, banner, banner_len - 2); + banner_dup[banner_len - 2] = '\0'; + } + else { + memcpy(banner_dup, banner, 255); + banner[255] = '\0'; + } + + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Sending Banner: %s", + banner_dup); +#endif + + session->banner_TxRx_state = libssh2_NB_state_created; + } + + /* no outgoing block yet! */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; + + ret = LIBSSH2_SEND(session, + banner + session->banner_TxRx_total_send, + banner_len - session->banner_TxRx_total_send, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if(ret < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", + banner_len - session->banner_TxRx_total_send, -ret); + else + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Sent %d/%d bytes at %p+%d", ret, + banner_len - session->banner_TxRx_total_send, + banner, session->banner_TxRx_total_send); + + if(ret != (banner_len - session->banner_TxRx_total_send)) { + if(ret >= 0 || ret == -EAGAIN) { + /* the whole packet could not be sent, save the what was */ + session->socket_block_directions = + LIBSSH2_SESSION_BLOCK_OUTBOUND; + if(ret > 0) + session->banner_TxRx_total_send += ret; + return LIBSSH2_ERROR_EAGAIN; + } + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + return LIBSSH2_ERROR_SOCKET_RECV; + } + + /* Set the state back to idle */ + session->banner_TxRx_state = libssh2_NB_state_idle; + session->banner_TxRx_total_send = 0; + + return 0; +} + +/* + * session_nonblock() sets the given socket to either blocking or + * non-blocking mode based on the 'nonblock' boolean argument. This function + * is copied from the libcurl sources with permission. + */ +static int +session_nonblock(libssh2_socket_t sockfd, /* operate on this */ + int nonblock /* TRUE or FALSE */ ) +{ +#undef SETBLOCK +#define SETBLOCK 0 +#ifdef HAVE_O_NONBLOCK + /* most recent unix versions */ + int flags; + + flags = fcntl(sockfd, F_GETFL, 0); + if(nonblock) + return fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + else + return fcntl(sockfd, F_SETFL, flags & (~O_NONBLOCK)); +#undef SETBLOCK +#define SETBLOCK 1 +#endif + +#if defined(HAVE_FIONBIO) && (SETBLOCK == 0) + /* older unix versions and VMS*/ + int flags; + + flags = nonblock; + return ioctl(sockfd, FIONBIO, &flags); +#undef SETBLOCK +#define SETBLOCK 2 +#endif + +#if defined(HAVE_IOCTLSOCKET) && (SETBLOCK == 0) + /* Windows? */ + unsigned long flags; + flags = nonblock; + + return ioctlsocket(sockfd, FIONBIO, &flags); +#undef SETBLOCK +#define SETBLOCK 3 +#endif + +#if defined(HAVE_IOCTLSOCKET_CASE) && (SETBLOCK == 0) + /* presumably for Amiga */ + return IoctlSocket(sockfd, FIONBIO, (long) nonblock); +#undef SETBLOCK +#define SETBLOCK 4 +#endif + +#if defined(HAVE_SO_NONBLOCK) && (SETBLOCK == 0) + /* BeOS */ + long b = nonblock ? 1 : 0; + return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); +#undef SETBLOCK +#define SETBLOCK 5 +#endif + +#ifdef HAVE_DISABLED_NONBLOCKING + return 0; /* returns success */ +#undef SETBLOCK +#define SETBLOCK 6 +#endif + +#if(SETBLOCK == 0) +#error "no non-blocking method was found/used/set" +#endif +} + +/* + * get_socket_nonblocking() + * + * gets the given blocking or non-blocking state of the socket. + */ +static int +get_socket_nonblocking(int sockfd) +{ /* operate on this */ +#undef GETBLOCK +#define GETBLOCK 0 +#ifdef HAVE_O_NONBLOCK + /* most recent unix versions */ + int flags = fcntl(sockfd, F_GETFL, 0); + + if(flags == -1) { + /* Assume blocking on error */ + return 1; + } + return (flags & O_NONBLOCK); +#undef GETBLOCK +#define GETBLOCK 1 +#endif + +#if defined(WSAEWOULDBLOCK) && (GETBLOCK == 0) + /* Windows? */ + unsigned int option_value; + socklen_t option_len = sizeof(option_value); + + if(getsockopt + (sockfd, SOL_SOCKET, SO_ERROR, (void *) &option_value, &option_len)) { + /* Assume blocking on error */ + return 1; + } + return (int) option_value; +#undef GETBLOCK +#define GETBLOCK 2 +#endif + +#if defined(HAVE_SO_NONBLOCK) && (GETBLOCK == 0) + /* BeOS */ + long b; + if(getsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b))) { + /* Assume blocking on error */ + return 1; + } + return (int) b; +#undef GETBLOCK +#define GETBLOCK 5 +#endif + +#if defined(SO_STATE) && defined(__VMS) && (GETBLOCK == 0) + + /* VMS TCP/IP Services */ + + size_t sockstat = 0; + int callstat = 0; + size_t size = sizeof(int); + + callstat = getsockopt(sockfd, SOL_SOCKET, SO_STATE, + (char *)&sockstat, &size); + if(callstat == -1) return 0; + if((sockstat&SS_NBIO) != 0) return 1; + return 0; + +#undef GETBLOCK +#define GETBLOCK 6 +#endif + +#ifdef HAVE_DISABLED_NONBLOCKING + return 1; /* returns blocking */ +#undef GETBLOCK +#define GETBLOCK 7 +#endif + +#if(GETBLOCK == 0) +#error "no non-blocking method was found/used/get" +#endif +} + +/* libssh2_session_banner_set + * Set the local banner to use in the server handshake. + */ +LIBSSH2_API int +libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner) +{ + size_t banner_len = banner ? strlen(banner) : 0; + + if(session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + session->local.banner = NULL; + } + + if(!banner_len) + return 0; + + session->local.banner = LIBSSH2_ALLOC(session, banner_len + 3); + if(!session->local.banner) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for local banner"); + } + + memcpy(session->local.banner, banner, banner_len); + + /* first zero terminate like this so that the debug output is nice */ + session->local.banner[banner_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting local Banner: %s", + session->local.banner); + session->local.banner[banner_len++] = '\r'; + session->local.banner[banner_len++] = '\n'; + session->local.banner[banner_len] = '\0'; + + return 0; +} + +/* libssh2_banner_set + * Set the local banner. DEPRECATED VERSION + */ +LIBSSH2_API int +libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner) +{ + return libssh2_session_banner_set(session, banner); +} + +/* + * libssh2_session_init_ex + * + * Allocate and initialize a libssh2 session structure. Allows for malloc + * callbacks in case the calling program has its own memory manager It's + * allowable (but unadvisable) to define some but not all of the malloc + * callbacks An additional pointer value may be optionally passed to be sent + * to the callbacks (so they know who's asking) + */ +LIBSSH2_API LIBSSH2_SESSION * +libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)), + LIBSSH2_FREE_FUNC((*my_free)), + LIBSSH2_REALLOC_FUNC((*my_realloc)), void *abstract) +{ + LIBSSH2_ALLOC_FUNC((*local_alloc)) = libssh2_default_alloc; + LIBSSH2_FREE_FUNC((*local_free)) = libssh2_default_free; + LIBSSH2_REALLOC_FUNC((*local_realloc)) = libssh2_default_realloc; + LIBSSH2_SESSION *session; + + if(my_alloc) { + local_alloc = my_alloc; + } + if(my_free) { + local_free = my_free; + } + if(my_realloc) { + local_realloc = my_realloc; + } + + session = local_alloc(sizeof(LIBSSH2_SESSION), &abstract); + if(session) { + memset(session, 0, sizeof(LIBSSH2_SESSION)); + session->alloc = local_alloc; + session->free = local_free; + session->realloc = local_realloc; + session->send = _libssh2_send; + session->recv = _libssh2_recv; + session->abstract = abstract; + session->api_timeout = 0; /* timeout-free API by default */ + session->api_block_mode = 1; /* blocking API by default */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "New session resource allocated"); + _libssh2_init_if_needed(); + } + return session; +} + +/* + * libssh2_session_callback_set + * + * Set (or reset) a callback function + * Returns the prior address + * + * ALERT: this function relies on that we can typecast function pointers + * to void pointers, which isn't allowed in ISO C! + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +LIBSSH2_API void * +libssh2_session_callback_set(LIBSSH2_SESSION * session, + int cbtype, void *callback) +{ + void *oldcb; + + switch(cbtype) { + case LIBSSH2_CALLBACK_IGNORE: + oldcb = session->ssh_msg_ignore; + session->ssh_msg_ignore = callback; + return oldcb; + + case LIBSSH2_CALLBACK_DEBUG: + oldcb = session->ssh_msg_debug; + session->ssh_msg_debug = callback; + return oldcb; + + case LIBSSH2_CALLBACK_DISCONNECT: + oldcb = session->ssh_msg_disconnect; + session->ssh_msg_disconnect = callback; + return oldcb; + + case LIBSSH2_CALLBACK_MACERROR: + oldcb = session->macerror; + session->macerror = callback; + return oldcb; + + case LIBSSH2_CALLBACK_X11: + oldcb = session->x11; + session->x11 = callback; + return oldcb; + + case LIBSSH2_CALLBACK_SEND: + oldcb = session->send; + session->send = callback; + return oldcb; + + case LIBSSH2_CALLBACK_RECV: + oldcb = session->recv; + session->recv = callback; + return oldcb; + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Setting Callback %d", + cbtype); + + return NULL; +} +#pragma GCC diagnostic pop + +/* + * _libssh2_wait_socket() + * + * Utility function that waits for action on the socket. Returns 0 when ready + * to run again or error on timeout. + */ +int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time) +{ + int rc; + int seconds_to_next; + int dir; + int has_timeout; + long ms_to_next = 0; + long elapsed_ms; + + /* since libssh2 often sets EAGAIN internally before this function is + called, we can decrease some amount of confusion in user programs by + resetting the error code in this function to reduce the risk of EAGAIN + being stored as error when a blocking function has returned */ + session->err_code = LIBSSH2_ERROR_NONE; + + rc = libssh2_keepalive_send(session, &seconds_to_next); + if(rc) + return rc; + + ms_to_next = seconds_to_next * 1000; + + /* figure out what to wait for */ + dir = libssh2_session_block_directions(session); + + if(!dir) { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Nothing to wait for in wait_socket"); + /* To avoid that we hang below just because there's nothing set to + wait for, we timeout on 1 second to also avoid busy-looping + during this condition */ + ms_to_next = 1000; + } + + if(session->api_timeout > 0 && + (seconds_to_next == 0 || + ms_to_next > session->api_timeout)) { + time_t now = time(NULL); + elapsed_ms = (long)(1000*difftime(now, start_time)); + if(elapsed_ms > session->api_timeout) { + return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "API timeout expired"); + } + ms_to_next = (session->api_timeout - elapsed_ms); + has_timeout = 1; + } + else if(ms_to_next > 0) { + has_timeout = 1; + } + else + has_timeout = 0; + +#ifdef HAVE_POLL + { + struct pollfd sockets[1]; + + sockets[0].fd = session->socket_fd; + sockets[0].events = 0; + sockets[0].revents = 0; + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) + sockets[0].events |= POLLIN; + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) + sockets[0].events |= POLLOUT; + + rc = poll(sockets, 1, has_timeout?ms_to_next: -1); + } +#else + { + fd_set rfd; + fd_set wfd; + fd_set *writefd = NULL; + fd_set *readfd = NULL; + struct timeval tv; + + tv.tv_sec = ms_to_next / 1000; + tv.tv_usec = (ms_to_next - tv.tv_sec*1000) * 1000; + + if(dir & LIBSSH2_SESSION_BLOCK_INBOUND) { + FD_ZERO(&rfd); + FD_SET(session->socket_fd, &rfd); + readfd = &rfd; + } + + if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) { + FD_ZERO(&wfd); + FD_SET(session->socket_fd, &wfd); + writefd = &wfd; + } + + rc = select(session->socket_fd + 1, readfd, writefd, NULL, + has_timeout ? &tv : NULL); + } +#endif + if(rc == 0) { + return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Timed out waiting on socket"); + } + if(rc < 0) { + return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT, + "Error waiting on socket"); + } + + return 0; /* ready to try again */ +} + +static int +session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock) +{ + int rc; + + if(session->startup_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "session_startup for socket %d", sock); + if(LIBSSH2_INVALID_SOCKET == sock) { + /* Did we forget something? */ + return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET, + "Bad socket provided"); + } + session->socket_fd = sock; + + session->socket_prev_blockstate = + !get_socket_nonblocking(session->socket_fd); + + if(session->socket_prev_blockstate) { + /* If in blocking state change to non-blocking */ + rc = session_nonblock(session->socket_fd, 1); + if(rc) { + return _libssh2_error(session, rc, + "Failed changing socket's " + "blocking state to non-blocking"); + } + } + + session->startup_state = libssh2_NB_state_created; + } + + if(session->startup_state == libssh2_NB_state_created) { + rc = banner_send(session); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc) { + return _libssh2_error(session, rc, + "Failed sending banner"); + } + session->startup_state = libssh2_NB_state_sent; + session->banner_TxRx_state = libssh2_NB_state_idle; + } + + if(session->startup_state == libssh2_NB_state_sent) { + do { + rc = banner_receive(session); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc) + return _libssh2_error(session, rc, + "Failed getting banner"); + } while(strncmp("SSH-", (char *)session->remote.banner, 4)); + + session->startup_state = libssh2_NB_state_sent1; + } + + if(session->startup_state == libssh2_NB_state_sent1) { + rc = _libssh2_kex_exchange(session, 0, &session->startup_key_state); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc) + return _libssh2_error(session, rc, + "Unable to exchange encryption keys"); + + session->startup_state = libssh2_NB_state_sent2; + } + + if(session->startup_state == libssh2_NB_state_sent2) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Requesting userauth service"); + + /* Request the userauth service */ + session->startup_service[0] = SSH_MSG_SERVICE_REQUEST; + _libssh2_htonu32(session->startup_service + 1, + sizeof("ssh-userauth") - 1); + memcpy(session->startup_service + 5, "ssh-userauth", + sizeof("ssh-userauth") - 1); + + session->startup_state = libssh2_NB_state_sent3; + } + + if(session->startup_state == libssh2_NB_state_sent3) { + rc = _libssh2_transport_send(session, session->startup_service, + sizeof("ssh-userauth") + 5 - 1, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc) { + return _libssh2_error(session, rc, + "Unable to ask for ssh-userauth service"); + } + + session->startup_state = libssh2_NB_state_sent4; + } + + if(session->startup_state == libssh2_NB_state_sent4) { + rc = _libssh2_packet_require(session, SSH_MSG_SERVICE_ACCEPT, + &session->startup_data, + &session->startup_data_len, 0, NULL, 0, + &session->startup_req_state); + if(rc) + return rc; + + if(session->startup_data_len < 5) { + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet length"); + } + + session->startup_service_length = + _libssh2_ntohu32(session->startup_data + 1); + + + if((session->startup_service_length != (sizeof("ssh-userauth") - 1)) + || strncmp("ssh-userauth", (char *) session->startup_data + 5, + session->startup_service_length)) { + LIBSSH2_FREE(session, session->startup_data); + session->startup_data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Invalid response received from server"); + } + LIBSSH2_FREE(session, session->startup_data); + session->startup_data = NULL; + + session->startup_state = libssh2_NB_state_idle; + + return 0; + } + + /* just for safety return some error */ + return LIBSSH2_ERROR_INVAL; +} + +/* + * libssh2_session_handshake() + * + * session: LIBSSH2_SESSION struct allocated and owned by the calling program + * sock: *must* be populated with an opened and connected socket. + * + * Returns: 0 on success, or non-zero on failure + */ +LIBSSH2_API int +libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock) +{ + int rc; + + BLOCK_ADJUST(rc, session, session_startup(session, sock) ); + + return rc; +} + +/* + * libssh2_session_startup() + * + * DEPRECATED. Use libssh2_session_handshake() instead! This function is not + * portable enough. + * + * session: LIBSSH2_SESSION struct allocated and owned by the calling program + * sock: *must* be populated with an opened and connected socket. + * + * Returns: 0 on success, or non-zero on failure + */ +LIBSSH2_API int +libssh2_session_startup(LIBSSH2_SESSION *session, int sock) +{ + return libssh2_session_handshake(session, (libssh2_socket_t) sock); +} + +/* + * libssh2_session_free + * + * Frees the memory allocated to the session + * Also closes and frees any channels attached to this session + */ +static int +session_free(LIBSSH2_SESSION *session) +{ + int rc; + LIBSSH2_PACKET *pkg; + LIBSSH2_CHANNEL *ch; + LIBSSH2_LISTENER *l; + int packets_left = 0; + + if(session->free_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Freeing session resource", + session->remote.banner); + + session->free_state = libssh2_NB_state_created; + } + + if(session->free_state == libssh2_NB_state_created) { + while((ch = _libssh2_list_first(&session->channels))) { + + rc = _libssh2_channel_free(ch); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->free_state = libssh2_NB_state_sent; + } + + if(session->free_state == libssh2_NB_state_sent) { + while((l = _libssh2_list_first(&session->listeners))) { + rc = _libssh2_channel_forward_cancel(l); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + + session->free_state = libssh2_NB_state_sent1; + } + + if(session->state & LIBSSH2_STATE_NEWKEYS) { + /* hostkey */ + if(session->hostkey && session->hostkey->dtor) { + session->hostkey->dtor(session, &session->server_hostkey_abstract); + } + + /* Client to Server */ + /* crypt */ + if(session->local.crypt && session->local.crypt->dtor) { + session->local.crypt->dtor(session, + &session->local.crypt_abstract); + } + /* comp */ + if(session->local.comp && session->local.comp->dtor) { + session->local.comp->dtor(session, 1, + &session->local.comp_abstract); + } + /* mac */ + if(session->local.mac && session->local.mac->dtor) { + session->local.mac->dtor(session, &session->local.mac_abstract); + } + + /* Server to Client */ + /* crypt */ + if(session->remote.crypt && session->remote.crypt->dtor) { + session->remote.crypt->dtor(session, + &session->remote.crypt_abstract); + } + /* comp */ + if(session->remote.comp && session->remote.comp->dtor) { + session->remote.comp->dtor(session, 0, + &session->remote.comp_abstract); + } + /* mac */ + if(session->remote.mac && session->remote.mac->dtor) { + session->remote.mac->dtor(session, &session->remote.mac_abstract); + } + + /* session_id */ + if(session->session_id) { + LIBSSH2_FREE(session, session->session_id); + } + } + + /* Free banner(s) */ + if(session->remote.banner) { + LIBSSH2_FREE(session, session->remote.banner); + } + if(session->local.banner) { + LIBSSH2_FREE(session, session->local.banner); + } + + /* Free preference(s) */ + if(session->kex_prefs) { + LIBSSH2_FREE(session, session->kex_prefs); + } + if(session->hostkey_prefs) { + LIBSSH2_FREE(session, session->hostkey_prefs); + } + + if(session->local.kexinit) { + LIBSSH2_FREE(session, session->local.kexinit); + } + if(session->local.crypt_prefs) { + LIBSSH2_FREE(session, session->local.crypt_prefs); + } + if(session->local.mac_prefs) { + LIBSSH2_FREE(session, session->local.mac_prefs); + } + if(session->local.comp_prefs) { + LIBSSH2_FREE(session, session->local.comp_prefs); + } + if(session->local.lang_prefs) { + LIBSSH2_FREE(session, session->local.lang_prefs); + } + + if(session->remote.kexinit) { + LIBSSH2_FREE(session, session->remote.kexinit); + } + if(session->remote.crypt_prefs) { + LIBSSH2_FREE(session, session->remote.crypt_prefs); + } + if(session->remote.mac_prefs) { + LIBSSH2_FREE(session, session->remote.mac_prefs); + } + if(session->remote.comp_prefs) { + LIBSSH2_FREE(session, session->remote.comp_prefs); + } + if(session->remote.lang_prefs) { + LIBSSH2_FREE(session, session->remote.lang_prefs); + } + + /* + * Make sure all memory used in the state variables are free + */ + if(session->kexinit_data) { + LIBSSH2_FREE(session, session->kexinit_data); + } + if(session->startup_data) { + LIBSSH2_FREE(session, session->startup_data); + } + if(session->userauth_list_data) { + LIBSSH2_FREE(session, session->userauth_list_data); + } + if(session->userauth_pswd_data) { + LIBSSH2_FREE(session, session->userauth_pswd_data); + } + if(session->userauth_pswd_newpw) { + LIBSSH2_FREE(session, session->userauth_pswd_newpw); + } + if(session->userauth_host_packet) { + LIBSSH2_FREE(session, session->userauth_host_packet); + } + if(session->userauth_host_method) { + LIBSSH2_FREE(session, session->userauth_host_method); + } + if(session->userauth_host_data) { + LIBSSH2_FREE(session, session->userauth_host_data); + } + if(session->userauth_pblc_data) { + LIBSSH2_FREE(session, session->userauth_pblc_data); + } + if(session->userauth_pblc_packet) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + } + if(session->userauth_pblc_method) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + } + if(session->userauth_kybd_data) { + LIBSSH2_FREE(session, session->userauth_kybd_data); + } + if(session->userauth_kybd_packet) { + LIBSSH2_FREE(session, session->userauth_kybd_packet); + } + if(session->userauth_kybd_auth_instruction) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); + } + if(session->open_packet) { + LIBSSH2_FREE(session, session->open_packet); + } + if(session->open_data) { + LIBSSH2_FREE(session, session->open_data); + } + if(session->direct_message) { + LIBSSH2_FREE(session, session->direct_message); + } + if(session->fwdLstn_packet) { + LIBSSH2_FREE(session, session->fwdLstn_packet); + } + if(session->pkeyInit_data) { + LIBSSH2_FREE(session, session->pkeyInit_data); + } + if(session->scpRecv_command) { + LIBSSH2_FREE(session, session->scpRecv_command); + } + if(session->scpSend_command) { + LIBSSH2_FREE(session, session->scpSend_command); + } + if(session->sftpInit_sftp) { + LIBSSH2_FREE(session, session->sftpInit_sftp); + } + + /* Free payload buffer */ + if(session->packet.total_num) { + LIBSSH2_FREE(session, session->packet.payload); + } + + /* Cleanup all remaining packets */ + while((pkg = _libssh2_list_first(&session->packets))) { + packets_left++; + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "packet left with id %d", pkg->data[0]); + /* unlink the node */ + _libssh2_list_remove(&pkg->node); + + /* free */ + LIBSSH2_FREE(session, pkg->data); + LIBSSH2_FREE(session, pkg); + } + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Extra packets left %d", packets_left); + + if(session->socket_prev_blockstate) { + /* if the socket was previously blocking, put it back so */ + rc = session_nonblock(session->socket_fd, 0); + if(rc) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "unable to reset socket's blocking state"); + } + } + + if(session->server_hostkey) { + LIBSSH2_FREE(session, session->server_hostkey); + } + + /* error string */ + if(session->err_msg && + ((session->err_flags & LIBSSH2_ERR_FLAG_DUP) != 0)) { + LIBSSH2_FREE(session, (char *)session->err_msg); + } + + LIBSSH2_FREE(session, session); + + return 0; +} + +/* + * libssh2_session_free + * + * Frees the memory allocated to the session + * Also closes and frees any channels attached to this session + */ +LIBSSH2_API int +libssh2_session_free(LIBSSH2_SESSION * session) +{ + int rc; + + BLOCK_ADJUST(rc, session, session_free(session) ); + + return rc; +} + +/* + * libssh2_session_disconnect_ex + */ +static int +session_disconnect(LIBSSH2_SESSION *session, int reason, + const char *description, + const char *lang) +{ + unsigned char *s; + unsigned long descr_len = 0, lang_len = 0; + int rc; + + if(session->disconnect_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, + "Disconnecting: reason=%d, desc=%s, lang=%s", reason, + description, lang); + if(description) + descr_len = strlen(description); + + if(lang) + lang_len = strlen(lang); + + if(descr_len > 256) + return _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "too long description"); + + /* 13 = packet_type(1) + reason code(4) + descr_len(4) + lang_len(4) */ + session->disconnect_data_len = descr_len + lang_len + 13; + + s = session->disconnect_data; + + *(s++) = SSH_MSG_DISCONNECT; + _libssh2_store_u32(&s, reason); + _libssh2_store_str(&s, description, descr_len); + /* store length only, lang is sent separately */ + _libssh2_store_u32(&s, lang_len); + + session->disconnect_state = libssh2_NB_state_created; + } + + rc = _libssh2_transport_send(session, session->disconnect_data, + session->disconnect_data_len, + (unsigned char *)lang, lang_len); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + + session->disconnect_state = libssh2_NB_state_idle; + + return 0; +} + +/* + * libssh2_session_disconnect_ex + */ +LIBSSH2_API int +libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason, + const char *desc, const char *lang) +{ + int rc; + session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS; + BLOCK_ADJUST(rc, session, + session_disconnect(session, reason, desc, lang)); + + return rc; +} + +/* libssh2_session_methods + * + * Return the currently active methods for method_type + * + * NOTE: Currently lang_cs and lang_sc are ALWAYS set to empty string + * regardless of actual negotiation Strings should NOT be freed + */ +LIBSSH2_API const char * +libssh2_session_methods(LIBSSH2_SESSION * session, int method_type) +{ + /* All methods have char *name as their first element */ + const LIBSSH2_KEX_METHOD *method = NULL; + + switch(method_type) { + case LIBSSH2_METHOD_KEX: + method = session->kex; + break; + + case LIBSSH2_METHOD_HOSTKEY: + method = (LIBSSH2_KEX_METHOD *) session->hostkey; + break; + + case LIBSSH2_METHOD_CRYPT_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.crypt; + break; + + case LIBSSH2_METHOD_CRYPT_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.crypt; + break; + + case LIBSSH2_METHOD_MAC_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.mac; + break; + + case LIBSSH2_METHOD_MAC_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.mac; + break; + + case LIBSSH2_METHOD_COMP_CS: + method = (LIBSSH2_KEX_METHOD *) session->local.comp; + break; + + case LIBSSH2_METHOD_COMP_SC: + method = (LIBSSH2_KEX_METHOD *) session->remote.comp; + break; + + case LIBSSH2_METHOD_LANG_CS: + return ""; + + case LIBSSH2_METHOD_LANG_SC: + return ""; + + default: + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "Invalid parameter specified for method_type"); + return NULL; + } + + if(!method) { + _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No method negotiated"); + return NULL; + } + + return method->name; +} + +/* libssh2_session_abstract + * Retrieve a pointer to the abstract property + */ +LIBSSH2_API void ** +libssh2_session_abstract(LIBSSH2_SESSION * session) +{ + return &session->abstract; +} + +/* libssh2_session_last_error + * + * Returns error code and populates an error string into errmsg If want_buf is + * non-zero then the string placed into errmsg must be freed by the calling + * program. Otherwise it is assumed to be owned by libssh2 + */ +LIBSSH2_API int +libssh2_session_last_error(LIBSSH2_SESSION * session, char **errmsg, + int *errmsg_len, int want_buf) +{ + size_t msglen = 0; + + /* No error to report */ + if(!session->err_code) { + if(errmsg) { + if(want_buf) { + *errmsg = LIBSSH2_ALLOC(session, 1); + if(*errmsg) { + **errmsg = 0; + } + } + else { + *errmsg = (char *) ""; + } + } + if(errmsg_len) { + *errmsg_len = 0; + } + return 0; + } + + if(errmsg) { + const char *error = session->err_msg ? session->err_msg : ""; + + msglen = strlen(error); + + if(want_buf) { + /* Make a copy so the calling program can own it */ + *errmsg = LIBSSH2_ALLOC(session, msglen + 1); + if(*errmsg) { + memcpy(*errmsg, error, msglen); + (*errmsg)[msglen] = 0; + } + } + else + *errmsg = (char *)error; + } + + if(errmsg_len) { + *errmsg_len = msglen; + } + + return session->err_code; +} + +/* libssh2_session_last_errno + * + * Returns error code + */ +LIBSSH2_API int +libssh2_session_last_errno(LIBSSH2_SESSION * session) +{ + return session->err_code; +} + +/* libssh2_session_set_last_error + * + * Sets the internal error code for the session. + * + * This function is available specifically to be used by high level + * language wrappers (i.e. Python or Perl) that may extend the library + * features while still relying on its error reporting mechanism. + */ +LIBSSH2_API int +libssh2_session_set_last_error(LIBSSH2_SESSION* session, + int errcode, + const char *errmsg) +{ + return _libssh2_error_flags(session, errcode, errmsg, + LIBSSH2_ERR_FLAG_DUP); +} + +/* Libssh2_session_flag + * + * Set/Get session flags + * + * Return error code. + */ +LIBSSH2_API int +libssh2_session_flag(LIBSSH2_SESSION * session, int flag, int value) +{ + switch(flag) { + case LIBSSH2_FLAG_SIGPIPE: + session->flag.sigpipe = value; + break; + case LIBSSH2_FLAG_COMPRESS: + session->flag.compress = value; + break; + default: + /* unknown flag */ + return LIBSSH2_ERROR_INVAL; + } + + return LIBSSH2_ERROR_NONE; +} + +/* _libssh2_session_set_blocking + * + * Set a session's blocking mode on or off, return the previous status when + * this function is called. Note this function does not alter the state of the + * actual socket involved. + */ +int +_libssh2_session_set_blocking(LIBSSH2_SESSION *session, int blocking) +{ + int bl = session->api_block_mode; + _libssh2_debug(session, LIBSSH2_TRACE_CONN, + "Setting blocking mode %s", blocking?"ON":"OFF"); + session->api_block_mode = blocking; + + return bl; +} + +/* libssh2_session_set_blocking + * + * Set a channel's blocking mode on or off, similar to a socket's + * fcntl(fd, F_SETFL, O_NONBLOCK); type command + */ +LIBSSH2_API void +libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking) +{ + (void) _libssh2_session_set_blocking(session, blocking); +} + +/* libssh2_session_get_blocking + * + * Returns a session's blocking mode on or off + */ +LIBSSH2_API int +libssh2_session_get_blocking(LIBSSH2_SESSION * session) +{ + return session->api_block_mode; +} + + +/* libssh2_session_set_timeout + * + * Set a session's timeout (in msec) for blocking mode, + * or 0 to disable timeouts. + */ +LIBSSH2_API void +libssh2_session_set_timeout(LIBSSH2_SESSION * session, long timeout) +{ + session->api_timeout = timeout; +} + +/* libssh2_session_get_timeout + * + * Returns a session's timeout, or 0 if disabled + */ +LIBSSH2_API long +libssh2_session_get_timeout(LIBSSH2_SESSION * session) +{ + return session->api_timeout; +} + +/* + * libssh2_poll_channel_read + * + * Returns 0 if no data is waiting on channel, + * non-0 if data is available + */ +LIBSSH2_API int +libssh2_poll_channel_read(LIBSSH2_CHANNEL *channel, int extended) +{ + LIBSSH2_SESSION *session; + LIBSSH2_PACKET *packet; + + if(!channel) + return LIBSSH2_ERROR_BAD_USE; + + session = channel->session; + packet = _libssh2_list_first(&session->packets); + + while(packet) { + if(packet->data_len < 5) { + return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Packet too small"); + } + + if(channel->local.id == _libssh2_ntohu32(packet->data + 1)) { + if(extended == 1 && + (packet->data[0] == SSH_MSG_CHANNEL_EXTENDED_DATA + || packet->data[0] == SSH_MSG_CHANNEL_DATA)) { + return 1; + } + else if(extended == 0 && + packet->data[0] == SSH_MSG_CHANNEL_DATA) { + return 1; + } + /* else - no data of any type is ready to be read */ + } + packet = _libssh2_list_next(&packet->node); + } + + return 0; +} + +/* + * poll_channel_write + * + * Returns 0 if writing to channel would block, + * non-0 if data can be written without blocking + */ +static inline int +poll_channel_write(LIBSSH2_CHANNEL * channel) +{ + return channel->local.window_size ? 1 : 0; +} + +/* poll_listener_queued + * + * Returns 0 if no connections are waiting to be accepted + * non-0 if one or more connections are available + */ +static inline int +poll_listener_queued(LIBSSH2_LISTENER * listener) +{ + return _libssh2_list_first(&listener->queue) ? 1 : 0; +} + +/* + * libssh2_poll + * + * Poll sockets, channels, and listeners for activity + */ +LIBSSH2_API int +libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout) +{ + long timeout_remaining; + unsigned int i, active_fds; +#ifdef HAVE_POLL + LIBSSH2_SESSION *session = NULL; +#ifdef HAVE_ALLOCA + struct pollfd *sockets = alloca(sizeof(struct pollfd) * nfds); +#else + struct pollfd sockets[256]; + + if(nfds > 256) + /* systems without alloca use a fixed-size array, this can be fixed if + we really want to, at least if the compiler is a C99 capable one */ + return -1; +#endif + /* Setup sockets for polling */ + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch(fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + sockets[i].fd = fds[i].fd.socket; + sockets[i].events = fds[i].events; + sockets[i].revents = 0; + break; + + case LIBSSH2_POLLFD_CHANNEL: + sockets[i].fd = fds[i].fd.channel->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if(!session) + session = fds[i].fd.channel->session; + break; + + case LIBSSH2_POLLFD_LISTENER: + sockets[i].fd = fds[i].fd.listener->session->socket_fd; + sockets[i].events = POLLIN; + sockets[i].revents = 0; + if(!session) + session = fds[i].fd.listener->session; + break; + + default: + if(session) + _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()"); + return -1; + } + } +#elif defined(HAVE_SELECT) + LIBSSH2_SESSION *session = NULL; + libssh2_socket_t maxfd = 0; + fd_set rfds, wfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + for(i = 0; i < nfds; i++) { + fds[i].revents = 0; + switch(fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if(fds[i].events & LIBSSH2_POLLFD_POLLIN) { + FD_SET(fds[i].fd.socket, &rfds); + if(fds[i].fd.socket > maxfd) + maxfd = fds[i].fd.socket; + } + if(fds[i].events & LIBSSH2_POLLFD_POLLOUT) { + FD_SET(fds[i].fd.socket, &wfds); + if(fds[i].fd.socket > maxfd) + maxfd = fds[i].fd.socket; + } + break; + + case LIBSSH2_POLLFD_CHANNEL: + FD_SET(fds[i].fd.channel->session->socket_fd, &rfds); + if(fds[i].fd.channel->session->socket_fd > maxfd) + maxfd = fds[i].fd.channel->session->socket_fd; + if(!session) + session = fds[i].fd.channel->session; + break; + + case LIBSSH2_POLLFD_LISTENER: + FD_SET(fds[i].fd.listener->session->socket_fd, &rfds); + if(fds[i].fd.listener->session->socket_fd > maxfd) + maxfd = fds[i].fd.listener->session->socket_fd; + if(!session) + session = fds[i].fd.listener->session; + break; + + default: + if(session) + _libssh2_error(session, LIBSSH2_ERROR_INVALID_POLL_TYPE, + "Invalid descriptor passed to libssh2_poll()"); + return -1; + } + } +#else + /* No select() or poll() + * no sockets structure to setup + */ + + timeout = 0; +#endif /* HAVE_POLL or HAVE_SELECT */ + + timeout_remaining = timeout; + do { +#if defined(HAVE_POLL) || defined(HAVE_SELECT) + int sysret; +#endif + + active_fds = 0; + + for(i = 0; i < nfds; i++) { + if(fds[i].events != fds[i].revents) { + switch(fds[i].type) { + case LIBSSH2_POLLFD_CHANNEL: + if((fds[i].events & LIBSSH2_POLLFD_POLLIN) && + /* Want to be ready for read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { + /* Not yet known to be ready for read */ + fds[i].revents |= + libssh2_poll_channel_read(fds[i].fd.channel, + 0) ? + LIBSSH2_POLLFD_POLLIN : 0; + } + if((fds[i].events & LIBSSH2_POLLFD_POLLEXT) && + /* Want to be ready for extended read */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLEXT) == 0)) { + /* Not yet known to be ready for extended read */ + fds[i].revents |= + libssh2_poll_channel_read(fds[i].fd.channel, + 1) ? + LIBSSH2_POLLFD_POLLEXT : 0; + } + if((fds[i].events & LIBSSH2_POLLFD_POLLOUT) && + /* Want to be ready for write */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLOUT) == 0)) { + /* Not yet known to be ready for write */ + fds[i].revents |= + poll_channel_write(fds[i].fd. channel) ? + LIBSSH2_POLLFD_POLLOUT : 0; + } + if(fds[i].fd.channel->remote.close + || fds[i].fd.channel->local.close) { + fds[i].revents |= LIBSSH2_POLLFD_CHANNEL_CLOSED; + } + if(fds[i].fd.channel->session->socket_state == + LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= + LIBSSH2_POLLFD_CHANNEL_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + + case LIBSSH2_POLLFD_LISTENER: + if((fds[i].events & LIBSSH2_POLLFD_POLLIN) && + /* Want a connection */ + ((fds[i].revents & LIBSSH2_POLLFD_POLLIN) == 0)) { + /* No connections known of yet */ + fds[i].revents |= + poll_listener_queued(fds[i].fd. listener) ? + LIBSSH2_POLLFD_POLLIN : 0; + } + if(fds[i].fd.listener->session->socket_state == + LIBSSH2_SOCKET_DISCONNECTED) { + fds[i].revents |= + LIBSSH2_POLLFD_LISTENER_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + break; + } + } + if(fds[i].revents) { + active_fds++; + } + } + + if(active_fds) { + /* Don't block on the sockets if we have channels/listeners which + are ready */ + timeout_remaining = 0; + } +#ifdef HAVE_POLL + +#ifdef HAVE_LIBSSH2_GETTIMEOFDAY + { + struct timeval tv_begin, tv_end; + + _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL); + sysret = poll(sockets, nfds, timeout_remaining); + _libssh2_gettimeofday((struct timeval *) &tv_end, NULL); + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + } +#else + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = poll(sockets, nfds, timeout_remaining); + timeout_remaining = 0; +#endif /* HAVE_GETTIMEOFDAY */ + + if(sysret > 0) { + for(i = 0; i < nfds; i++) { + switch(fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + fds[i].revents = sockets[i].revents; + sockets[i].revents = 0; /* In case we loop again, be + nice */ + if(fds[i].revents) { + active_fds++; + } + break; + case LIBSSH2_POLLFD_CHANNEL: + if(sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while(_libssh2_transport_read(fds[i].fd. + channel->session) + > 0); + } + if(sockets[i].revents & POLLHUP) { + fds[i].revents |= + LIBSSH2_POLLFD_CHANNEL_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + case LIBSSH2_POLLFD_LISTENER: + if(sockets[i].events & POLLIN) { + /* Spin session until no data available */ + while(_libssh2_transport_read(fds[i].fd. + listener->session) + > 0); + } + if(sockets[i].revents & POLLHUP) { + fds[i].revents |= + LIBSSH2_POLLFD_LISTENER_CLOSED | + LIBSSH2_POLLFD_SESSION_CLOSED; + } + sockets[i].revents = 0; + break; + } + } + } +#elif defined(HAVE_SELECT) + tv.tv_sec = timeout_remaining / 1000; + tv.tv_usec = (timeout_remaining % 1000) * 1000; +#ifdef HAVE_LIBSSH2_GETTIMEOFDAY + { + struct timeval tv_begin, tv_end; + + _libssh2_gettimeofday((struct timeval *) &tv_begin, NULL); + sysret = select(maxfd + 1, &rfds, &wfds, NULL, &tv); + _libssh2_gettimeofday((struct timeval *) &tv_end, NULL); + + timeout_remaining -= (tv_end.tv_sec - tv_begin.tv_sec) * 1000; + timeout_remaining -= (tv_end.tv_usec - tv_begin.tv_usec) / 1000; + } +#else + /* If the platform doesn't support gettimeofday, + * then just make the call non-blocking and walk away + */ + sysret = select(maxfd + 1, &rfds, &wfds, NULL, &tv); + timeout_remaining = 0; +#endif + + if(sysret > 0) { + for(i = 0; i < nfds; i++) { + switch(fds[i].type) { + case LIBSSH2_POLLFD_SOCKET: + if(FD_ISSET(fds[i].fd.socket, &rfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLIN; + } + if(FD_ISSET(fds[i].fd.socket, &wfds)) { + fds[i].revents |= LIBSSH2_POLLFD_POLLOUT; + } + if(fds[i].revents) { + active_fds++; + } + break; + + case LIBSSH2_POLLFD_CHANNEL: + if(FD_ISSET(fds[i].fd.channel->session->socket_fd, + &rfds)) { + /* Spin session until no data available */ + while(_libssh2_transport_read(fds[i].fd. + channel->session) + > 0); + } + break; + + case LIBSSH2_POLLFD_LISTENER: + if(FD_ISSET + (fds[i].fd.listener->session->socket_fd, &rfds)) { + /* Spin session until no data available */ + while(_libssh2_transport_read(fds[i].fd. + listener->session) + > 0); + } + break; + } + } + } +#endif /* else no select() or poll() -- timeout (and by extension + * timeout_remaining) will be equal to 0 */ + } while((timeout_remaining > 0) && !active_fds); + + return active_fds; +} + +/* + * libssh2_session_block_directions + * + * Get blocked direction when a function returns LIBSSH2_ERROR_EAGAIN + * Returns LIBSSH2_SOCKET_BLOCK_INBOUND if recv() blocked + * or LIBSSH2_SOCKET_BLOCK_OUTBOUND if send() blocked + */ +LIBSSH2_API int +libssh2_session_block_directions(LIBSSH2_SESSION *session) +{ + return session->socket_block_directions; +} + +/* libssh2_session_banner_get + * Get the remote banner (server ID string) + */ + +LIBSSH2_API const char * +libssh2_session_banner_get(LIBSSH2_SESSION *session) +{ + /* to avoid a coredump when session is NULL */ + if(NULL == session) + return NULL; + + if(NULL == session->remote.banner) + return NULL; + + return (const char *) session->remote.banner; +} diff --git a/libssh2/sftp.c b/libssh2/sftp.c new file mode 100644 index 0000000..ac7ee01 --- /dev/null +++ b/libssh2/sftp.c @@ -0,0 +1,3755 @@ +/* Copyright (c) 2004-2008, Sara Golemon + * Copyright (c) 2007 Eli Fant + * Copyright (c) 2009-2019 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include + +#include "libssh2_priv.h" +#include "libssh2_sftp.h" +#include "channel.h" +#include "session.h" +#include "sftp.h" + +/* Note: Version 6 was documented at the time of writing + * However it was marked as "DO NOT IMPLEMENT" due to pending changes + * + * This release of libssh2 implements Version 5 with automatic downgrade + * based on server's declaration + */ + +/* SFTP packet types */ +#define SSH_FXP_INIT 1 +#define SSH_FXP_VERSION 2 +#define SSH_FXP_OPEN 3 +#define SSH_FXP_CLOSE 4 +#define SSH_FXP_READ 5 +#define SSH_FXP_WRITE 6 +#define SSH_FXP_LSTAT 7 +#define SSH_FXP_FSTAT 8 +#define SSH_FXP_SETSTAT 9 +#define SSH_FXP_FSETSTAT 10 +#define SSH_FXP_OPENDIR 11 +#define SSH_FXP_READDIR 12 +#define SSH_FXP_REMOVE 13 +#define SSH_FXP_MKDIR 14 +#define SSH_FXP_RMDIR 15 +#define SSH_FXP_REALPATH 16 +#define SSH_FXP_STAT 17 +#define SSH_FXP_RENAME 18 +#define SSH_FXP_READLINK 19 +#define SSH_FXP_SYMLINK 20 +#define SSH_FXP_STATUS 101 +#define SSH_FXP_HANDLE 102 +#define SSH_FXP_DATA 103 +#define SSH_FXP_NAME 104 +#define SSH_FXP_ATTRS 105 +#define SSH_FXP_EXTENDED 200 +#define SSH_FXP_EXTENDED_REPLY 201 + +/* S_IFREG */ +#define LIBSSH2_SFTP_ATTR_PFILETYPE_FILE 0100000 +/* S_IFDIR */ +#define LIBSSH2_SFTP_ATTR_PFILETYPE_DIR 0040000 + +#define SSH_FXE_STATVFS_ST_RDONLY 0x00000001 +#define SSH_FXE_STATVFS_ST_NOSUID 0x00000002 + +/* This is the maximum packet length to accept, as larger than this indicate + some kind of server problem. */ +#define LIBSSH2_SFTP_PACKET_MAXLEN (256 * 1024) + +static int sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len); +static void sftp_packet_flush(LIBSSH2_SFTP *sftp); + +/* sftp_attrsize + * Size that attr with this flagset will occupy when turned into a bin struct + */ +static int sftp_attrsize(unsigned long flags) +{ + return (4 + /* flags(4) */ + ((flags & LIBSSH2_SFTP_ATTR_SIZE) ? 8 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_UIDGID) ? 8 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) ? 4 : 0) + + ((flags & LIBSSH2_SFTP_ATTR_ACMODTIME) ? 8 : 0)); + /* atime + mtime as u32 */ +} + +/* _libssh2_store_u64 + */ +static void _libssh2_store_u64(unsigned char **ptr, libssh2_uint64_t value) +{ + uint32_t msl = (uint32_t)(value >> 32); + unsigned char *buf = *ptr; + + buf[0] = (unsigned char)((msl >> 24) & 0xFF); + buf[1] = (unsigned char)((msl >> 16) & 0xFF); + buf[2] = (unsigned char)((msl >> 8) & 0xFF); + buf[3] = (unsigned char)( msl & 0xFF); + + buf[4] = (unsigned char)((value >> 24) & 0xFF); + buf[5] = (unsigned char)((value >> 16) & 0xFF); + buf[6] = (unsigned char)((value >> 8) & 0xFF); + buf[7] = (unsigned char)( value & 0xFF); + + *ptr += 8; +} + +/* + * Search list of zombied FXP_READ request IDs. + * + * Returns NULL if ID not in list. + */ +static struct sftp_zombie_requests * +find_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + struct sftp_zombie_requests *zombie = + _libssh2_list_first(&sftp->zombie_requests); + + while(zombie) { + if(zombie->request_id == request_id) + break; + else + zombie = _libssh2_list_next(&zombie->node); + } + + return zombie; +} + +static void +remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + + struct sftp_zombie_requests *zombie = find_zombie_request(sftp, + request_id); + if(zombie) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Removing request ID %ld from the list of " + "zombie requests", + request_id); + + _libssh2_list_remove(&zombie->node); + LIBSSH2_FREE(session, zombie); + } +} + +static int +add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + + struct sftp_zombie_requests *zombie; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Marking request ID %ld as a zombie request", request_id); + + zombie = LIBSSH2_ALLOC(sftp->channel->session, + sizeof(struct sftp_zombie_requests)); + if(!zombie) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for zombie request ID"); + else { + zombie->request_id = request_id; + _libssh2_list_add(&sftp->zombie_requests, &zombie->node); + return LIBSSH2_ERROR_NONE; + } +} + +/* + * sftp_packet_add + * + * Add a packet to the SFTP packet brigade + */ +static int +sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data, + size_t data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SFTP_PACKET *packet; + uint32_t request_id; + + if(data_len < 5) { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Received packet type %d (len %d)", + (int) data[0], data_len); + + /* + * Experience shows that if we mess up EAGAIN handling somewhere or + * otherwise get out of sync with the channel, this is where we first get + * a wrong byte and if so we need to bail out at once to aid tracking the + * problem better. + */ + + switch(data[0]) { + case SSH_FXP_INIT: + case SSH_FXP_VERSION: + case SSH_FXP_OPEN: + case SSH_FXP_CLOSE: + case SSH_FXP_READ: + case SSH_FXP_WRITE: + case SSH_FXP_LSTAT: + case SSH_FXP_FSTAT: + case SSH_FXP_SETSTAT: + case SSH_FXP_FSETSTAT: + case SSH_FXP_OPENDIR: + case SSH_FXP_READDIR: + case SSH_FXP_REMOVE: + case SSH_FXP_MKDIR: + case SSH_FXP_RMDIR: + case SSH_FXP_REALPATH: + case SSH_FXP_STAT: + case SSH_FXP_RENAME: + case SSH_FXP_READLINK: + case SSH_FXP_SYMLINK: + case SSH_FXP_STATUS: + case SSH_FXP_HANDLE: + case SSH_FXP_DATA: + case SSH_FXP_NAME: + case SSH_FXP_ATTRS: + case SSH_FXP_EXTENDED: + case SSH_FXP_EXTENDED_REPLY: + break; + default: + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Out of sync with the world"); + } + + request_id = _libssh2_ntohu32(&data[1]); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Received packet id %d", + request_id); + + /* Don't add the packet if it answers a request we've given up on. */ + if((data[0] == SSH_FXP_STATUS || data[0] == SSH_FXP_DATA) + && find_zombie_request(sftp, request_id)) { + + /* If we get here, the file ended before the response arrived. We + are no longer interested in the request so we discard it */ + + LIBSSH2_FREE(session, data); + + remove_zombie_request(sftp, request_id); + return LIBSSH2_ERROR_NONE; + } + + packet = LIBSSH2_ALLOC(session, sizeof(LIBSSH2_SFTP_PACKET)); + if(!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate datablock for SFTP packet"); + } + + packet->data = data; + packet->data_len = data_len; + packet->request_id = request_id; + + _libssh2_list_add(&sftp->packets, &packet->node); + + return LIBSSH2_ERROR_NONE; +} + +/* + * sftp_packet_read + * + * Frame an SFTP packet off the channel + */ +static int +sftp_packet_read(LIBSSH2_SFTP *sftp) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + unsigned char *packet = NULL; + ssize_t rc; + unsigned long recv_window; + int packet_type; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "recv packet"); + + switch(sftp->packet_state) { + case libssh2_NB_state_sent: /* EAGAIN from window adjusting */ + sftp->packet_state = libssh2_NB_state_idle; + + packet = sftp->partial_packet; + goto window_adjust; + + case libssh2_NB_state_sent1: /* EAGAIN from channel read */ + sftp->packet_state = libssh2_NB_state_idle; + + packet = sftp->partial_packet; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "partial read cont, len: %lu", sftp->partial_len); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "partial read cont, already recvd: %lu", + sftp->partial_received); + /* fall-through */ + default: + if(!packet) { + /* only do this if there's not already a packet buffer allocated + to use */ + + /* each packet starts with a 32 bit length field */ + rc = _libssh2_channel_read(channel, 0, + (char *)&sftp->partial_size[ + sftp->partial_size_len], + 4 - sftp->partial_size_len); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc < 0) + return _libssh2_error(session, rc, "channel read"); + + sftp->partial_size_len += rc; + + if(4 != sftp->partial_size_len) + /* we got a short read for the length part */ + return LIBSSH2_ERROR_EAGAIN; + + sftp->partial_len = _libssh2_ntohu32(sftp->partial_size); + /* make sure we don't proceed if the packet size is unreasonably + large */ + if(sftp->partial_len > LIBSSH2_SFTP_PACKET_MAXLEN) { + libssh2_channel_flush(channel); + sftp->partial_size_len = 0; + return _libssh2_error(session, + LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED, + "SFTP packet too large"); + } + + if(sftp->partial_len == 0) + return _libssh2_error(session, + LIBSSH2_ERROR_ALLOC, + "Unable to allocate empty SFTP packet"); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Data begin - Packet Length: %lu", + sftp->partial_len); + packet = LIBSSH2_ALLOC(session, sftp->partial_len); + if(!packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate SFTP packet"); + sftp->partial_size_len = 0; + sftp->partial_received = 0; /* how much of the packet already + received */ + sftp->partial_packet = packet; + + window_adjust: + recv_window = libssh2_channel_window_read_ex(channel, NULL, NULL); + + if(sftp->partial_len > recv_window) { + /* ask for twice the data amount we need at once */ + rc = _libssh2_channel_receive_window_adjust(channel, + sftp->partial_len + * 2, + 1, NULL); + /* store the state so that we continue with the correct + operation at next invoke */ + sftp->packet_state = (rc == LIBSSH2_ERROR_EAGAIN)? + libssh2_NB_state_sent: + libssh2_NB_state_idle; + + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + } + } + + /* Read as much of the packet as we can */ + while(sftp->partial_len > sftp->partial_received) { + rc = _libssh2_channel_read(channel, 0, + (char *)&packet[sftp->partial_received], + sftp->partial_len - + sftp->partial_received); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + /* + * We received EAGAIN, save what we have and return EAGAIN to + * the caller. Set 'partial_packet' so that this function + * knows how to continue on the next invoke. + */ + sftp->packet_state = libssh2_NB_state_sent1; + return rc; + } + else if(rc < 0) { + LIBSSH2_FREE(session, packet); + sftp->partial_packet = NULL; + return _libssh2_error(session, rc, + "Error waiting for SFTP packet"); + } + sftp->partial_received += rc; + } + + sftp->partial_packet = NULL; + + /* sftp_packet_add takes ownership of the packet and might free it + so we take a copy of the packet type before we call it. */ + packet_type = packet[0]; + rc = sftp_packet_add(sftp, packet, sftp->partial_len); + if(rc) { + LIBSSH2_FREE(session, packet); + return rc; + } + else { + return packet_type; + } + } + /* WON'T REACH */ +} +/* + * sftp_packetlist_flush + * + * Remove all pending packets in the packet_list and the corresponding one(s) + * in the SFTP packet brigade. + */ +static void sftp_packetlist_flush(LIBSSH2_SFTP_HANDLE *handle) +{ + struct sftp_pipeline_chunk *chunk; + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_SESSION *session = sftp->channel->session; + + /* remove pending packets, if any */ + chunk = _libssh2_list_first(&handle->packet_list); + while(chunk) { + unsigned char *data; + size_t data_len; + int rc; + struct sftp_pipeline_chunk *next = _libssh2_list_next(&chunk->node); + + rc = sftp_packet_ask(sftp, SSH_FXP_STATUS, + chunk->request_id, &data, &data_len); + if(rc) + rc = sftp_packet_ask(sftp, SSH_FXP_DATA, + chunk->request_id, &data, &data_len); + + if(!rc) + /* we found a packet, free it */ + LIBSSH2_FREE(session, data); + else if(chunk->sent) + /* there was no incoming packet for this request, mark this + request as a zombie if it ever sent the request */ + add_zombie_request(sftp, chunk->request_id); + + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + chunk = next; + } +} + + +/* + * sftp_packet_ask() + * + * Checks if there's a matching SFTP packet available. + */ +static int +sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); + + if(!packet) + return -1; + + /* Special consideration when getting VERSION packet */ + + while(packet) { + if((packet->data[0] == packet_type) && + ((packet_type == SSH_FXP_VERSION) || + (packet->request_id == request_id))) { + + /* Match! Fetch the data */ + *data = packet->data; + *data_len = packet->data_len; + + /* unlink and free this struct */ + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(session, packet); + + return 0; + } + /* check next struct in the list */ + packet = _libssh2_list_next(&packet->node); + } + return -1; +} + +/* sftp_packet_require + * A la libssh2_packet_require + */ +static int +sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type, + uint32_t request_id, unsigned char **data, + size_t *data_len, size_t required_size) +{ + LIBSSH2_SESSION *session = sftp->channel->session; + int rc; + + if(data == NULL || data_len == NULL || required_size == 0) { + return LIBSSH2_ERROR_BAD_USE; + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld", + (int) packet_type, request_id); + + if(sftp_packet_ask(sftp, packet_type, request_id, data, data_len) == 0) { + /* The right packet was available in the packet brigade */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d", + (int) packet_type); + + if (*data_len < required_size) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + + return LIBSSH2_ERROR_NONE; + } + + while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + rc = sftp_packet_read(sftp); + if(rc < 0) + return rc; + + /* data was read, check the queue again */ + if(!sftp_packet_ask(sftp, packet_type, request_id, data, data_len)) { + /* The right packet was available in the packet brigade */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d", + (int) packet_type); + + if (*data_len < required_size) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + + return LIBSSH2_ERROR_NONE; + } + } + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* sftp_packet_requirev + * Require one of N possible responses + */ +static int +sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses, + const unsigned char *valid_responses, + uint32_t request_id, unsigned char **data, + size_t *data_len, size_t required_size) +{ + int i; + int rc; + + if(data == NULL || data_len == NULL || required_size == 0) { + return LIBSSH2_ERROR_BAD_USE; + } + + /* If no timeout is active, start a new one */ + if(sftp->requirev_start == 0) + sftp->requirev_start = time(NULL); + + while(sftp->channel->session->socket_state == LIBSSH2_SOCKET_CONNECTED) { + for(i = 0; i < num_valid_responses; i++) { + if(sftp_packet_ask(sftp, valid_responses[i], request_id, + data, data_len) == 0) { + /* + * Set to zero before all returns to say + * the timeout is not active + */ + sftp->requirev_start = 0; + + if (*data_len < required_size) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + + return LIBSSH2_ERROR_NONE; + } + } + + rc = sftp_packet_read(sftp); + if((rc < 0) && (rc != LIBSSH2_ERROR_EAGAIN)) { + sftp->requirev_start = 0; + return rc; + } + else if(rc <= 0) { + /* prevent busy-looping */ + long left = + LIBSSH2_READ_TIMEOUT - + (long)(time(NULL) - sftp->requirev_start); + + if(left <= 0) { + sftp->requirev_start = 0; + return LIBSSH2_ERROR_TIMEOUT; + } + else if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + } + } + + sftp->requirev_start = 0; + + /* Only reached if the socket died */ + return LIBSSH2_ERROR_SOCKET_DISCONNECT; +} + +/* sftp_attr2bin + * Populate attributes into an SFTP block + */ +static ssize_t +sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs) +{ + unsigned char *s = p; + uint32_t flag_mask = + LIBSSH2_SFTP_ATTR_SIZE | LIBSSH2_SFTP_ATTR_UIDGID | + LIBSSH2_SFTP_ATTR_PERMISSIONS | LIBSSH2_SFTP_ATTR_ACMODTIME; + + /* TODO: When we add SFTP4+ functionality flag_mask can get additional + bits */ + + if(!attrs) { + _libssh2_htonu32(s, 0); + return 4; + } + + _libssh2_store_u32(&s, attrs->flags & flag_mask); + + if(attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + _libssh2_store_u64(&s, attrs->filesize); + } + + if(attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + _libssh2_store_u32(&s, attrs->uid); + _libssh2_store_u32(&s, attrs->gid); + } + + if(attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + _libssh2_store_u32(&s, attrs->permissions); + } + + if(attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + _libssh2_store_u32(&s, attrs->atime); + _libssh2_store_u32(&s, attrs->mtime); + } + + return (s - p); +} + +/* sftp_bin2attr + */ +static int +sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES *attrs, const unsigned char *p, + size_t data_len) +{ + struct string_buf buf; + uint32_t flags = 0; + buf.data = (unsigned char *)p; + buf.dataptr = buf.data; + buf.len = data_len; + + if(_libssh2_get_u32(&buf, &flags) != 0) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + attrs->flags = flags; + + if(attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) { + if(_libssh2_get_u64(&buf, &(attrs->filesize)) != 0) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + } + + if(attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) { + uint32_t uid = 0; + uint32_t gid = 0; + if(_libssh2_get_u32(&buf, &uid) != 0 || + _libssh2_get_u32(&buf, &gid) != 0) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + attrs->uid = uid; + attrs->gid = gid; + } + + if(attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) { + uint32_t permissions; + if(_libssh2_get_u32(&buf, &permissions) != 0) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + attrs->permissions = permissions; + } + + if(attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) { + uint32_t atime; + uint32_t mtime; + if(_libssh2_get_u32(&buf, &atime) != 0 || + _libssh2_get_u32(&buf, &mtime) != 0) { + return LIBSSH2_ERROR_BUFFER_TOO_SMALL; + } + attrs->atime = atime; + attrs->mtime = mtime; + } + + return (buf.dataptr - buf.data); +} + +/* ************ + * SFTP API * + ************ */ + +LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor); + +/* libssh2_sftp_dtor + * Shutdown an SFTP stream when the channel closes + */ +LIBSSH2_CHANNEL_CLOSE_FUNC(libssh2_sftp_dtor) +{ + LIBSSH2_SFTP *sftp = (LIBSSH2_SFTP *) (*channel_abstract); + + (void) session_abstract; + (void) channel; + + /* Free the partial packet storage for sftp_packet_read */ + if(sftp->partial_packet) { + LIBSSH2_FREE(session, sftp->partial_packet); + } + + /* Free the packet storage for _libssh2_sftp_packet_readdir */ + if(sftp->readdir_packet) { + LIBSSH2_FREE(session, sftp->readdir_packet); + } + + LIBSSH2_FREE(session, sftp); +} + +/* + * sftp_init + * + * Startup an SFTP session + */ +static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session) +{ + unsigned char *data; + size_t data_len; + ssize_t rc; + LIBSSH2_SFTP *sftp_handle; + struct string_buf buf; + unsigned char *endp; + + if(session->sftpInit_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Initializing SFTP subsystem"); + + /* + * The 'sftpInit_sftp' and 'sftpInit_channel' struct fields within the + * session struct are only to be used during the setup phase. As soon + * as the SFTP session is created they are cleared and can thus be + * re-used again to allow any amount of SFTP handles per sessions. + * + * Note that you MUST NOT try to call libssh2_sftp_init() again to get + * another handle until the previous call has finished and either + * successfully made a handle or failed and returned error (not + * including *EAGAIN). + */ + + assert(session->sftpInit_sftp == NULL); + session->sftpInit_sftp = NULL; + session->sftpInit_state = libssh2_NB_state_created; + } + + sftp_handle = session->sftpInit_sftp; + + if(session->sftpInit_state == libssh2_NB_state_created) { + session->sftpInit_channel = + _libssh2_channel_open(session, "session", sizeof("session") - 1, + LIBSSH2_CHANNEL_WINDOW_DEFAULT, + LIBSSH2_CHANNEL_PACKET_DEFAULT, NULL, 0); + if(!session->sftpInit_channel) { + if(libssh2_session_last_errno(session) == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block starting up channel"); + } + else { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to startup channel"); + session->sftpInit_state = libssh2_NB_state_idle; + } + return NULL; + } + + session->sftpInit_state = libssh2_NB_state_sent; + } + + if(session->sftpInit_state == libssh2_NB_state_sent) { + int ret = _libssh2_channel_process_startup(session->sftpInit_channel, + "subsystem", + sizeof("subsystem") - 1, + "sftp", + strlen("sftp")); + if(ret == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block to request SFTP subsystem"); + return NULL; + } + else if(ret) { + _libssh2_error(session, LIBSSH2_ERROR_CHANNEL_FAILURE, + "Unable to request SFTP subsystem"); + goto sftp_init_error; + } + + session->sftpInit_state = libssh2_NB_state_sent1; + } + + if(session->sftpInit_state == libssh2_NB_state_sent1) { + rc = _libssh2_channel_extended_data(session->sftpInit_channel, + LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting handle extended data"); + return NULL; + } + + sftp_handle = + session->sftpInit_sftp = + LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP)); + if(!sftp_handle) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate a new SFTP structure"); + goto sftp_init_error; + } + sftp_handle->channel = session->sftpInit_channel; + sftp_handle->request_id = 0; + + _libssh2_htonu32(session->sftpInit_buffer, 5); + session->sftpInit_buffer[4] = SSH_FXP_INIT; + _libssh2_htonu32(session->sftpInit_buffer + 5, LIBSSH2_SFTP_VERSION); + session->sftpInit_sent = 0; /* nothing's sent yet */ + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Sending FXP_INIT packet advertising " + "version %d support", + (int) LIBSSH2_SFTP_VERSION); + + session->sftpInit_state = libssh2_NB_state_sent2; + } + + if(session->sftpInit_state == libssh2_NB_state_sent2) { + /* sent off what's left of the init buffer to send */ + rc = _libssh2_channel_write(session->sftpInit_channel, 0, + session->sftpInit_buffer + + session->sftpInit_sent, + 9 - session->sftpInit_sent); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending SSH_FXP_INIT"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SSH_FXP_INIT"); + goto sftp_init_error; + } + else { + /* add up the number of bytes sent */ + session->sftpInit_sent += rc; + + if(session->sftpInit_sent == 9) + /* move on */ + session->sftpInit_state = libssh2_NB_state_sent3; + + /* if less than 9, we remain in this state to send more later on */ + } + } + + rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION, + 0, &data, &data_len, 5); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block receiving SSH_FXP_VERSION"); + return NULL; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid SSH_FXP_VERSION response"); + goto sftp_init_error; + } + else if(rc) { + _libssh2_error(session, rc, + "Timeout waiting for response from SFTP subsystem"); + goto sftp_init_error; + } + + buf.data = data; + buf.dataptr = buf.data + 1; + buf.len = data_len; + endp = &buf.data[data_len]; + + if(_libssh2_get_u32(&buf, &(sftp_handle->version)) != 0) { + LIBSSH2_FREE(session, data); + rc = LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto sftp_init_error; + } + + if(sftp_handle->version > LIBSSH2_SFTP_VERSION) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Truncating remote SFTP version from %lu", + sftp_handle->version); + sftp_handle->version = LIBSSH2_SFTP_VERSION; + } + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Enabling SFTP version %lu compatibility", + sftp_handle->version); + while(buf.dataptr < endp) { + unsigned char *extname, *extdata; + + if(_libssh2_get_string(&buf, &extname, NULL)) { + LIBSSH2_FREE(session, data); + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short when extracting extname"); + goto sftp_init_error; + } + + if(_libssh2_get_string(&buf, &extdata, NULL)) { + LIBSSH2_FREE(session, data); + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "Data too short when extracting extdata"); + goto sftp_init_error; + } + } + LIBSSH2_FREE(session, data); + + /* Make sure that when the channel gets closed, the SFTP service is shut + down too */ + sftp_handle->channel->abstract = sftp_handle; + sftp_handle->channel->close_cb = libssh2_sftp_dtor; + + session->sftpInit_state = libssh2_NB_state_idle; + + /* clear the sftp and channel pointers in this session struct now */ + session->sftpInit_sftp = NULL; + session->sftpInit_channel = NULL; + + _libssh2_list_init(&sftp_handle->sftp_handles); + + return sftp_handle; + + sftp_init_error: + while(_libssh2_channel_free(session->sftpInit_channel) == + LIBSSH2_ERROR_EAGAIN); + session->sftpInit_channel = NULL; + if(session->sftpInit_sftp) { + LIBSSH2_FREE(session, session->sftpInit_sftp); + session->sftpInit_sftp = NULL; + } + session->sftpInit_state = libssh2_NB_state_idle; + return NULL; +} + +/* + * libssh2_sftp_init + * + * Startup an SFTP session + */ +LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session) +{ + LIBSSH2_SFTP *ptr; + + if(!session) + return NULL; + + if(!(session->state & LIBSSH2_STATE_AUTHENTICATED)) { + _libssh2_error(session, LIBSSH2_ERROR_INVAL, + "session not authenticated yet"); + return NULL; + } + + BLOCK_ADJUST_ERRNO(ptr, session, sftp_init(session)); + return ptr; +} + +/* + * sftp_shutdown + * + * Shuts down the SFTP subsystem + */ +static int +sftp_shutdown(LIBSSH2_SFTP *sftp) +{ + int rc; + LIBSSH2_SESSION *session = sftp->channel->session; + /* + * Make sure all memory used in the state variables are free + */ + if(sftp->partial_packet) { + LIBSSH2_FREE(session, sftp->partial_packet); + sftp->partial_packet = NULL; + } + if(sftp->open_packet) { + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + } + if(sftp->readdir_packet) { + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + } + if(sftp->fstat_packet) { + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + } + if(sftp->unlink_packet) { + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + } + if(sftp->rename_packet) { + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + } + if(sftp->fstatvfs_packet) { + LIBSSH2_FREE(session, sftp->fstatvfs_packet); + sftp->fstatvfs_packet = NULL; + } + if(sftp->statvfs_packet) { + LIBSSH2_FREE(session, sftp->statvfs_packet); + sftp->statvfs_packet = NULL; + } + if(sftp->mkdir_packet) { + LIBSSH2_FREE(session, sftp->mkdir_packet); + sftp->mkdir_packet = NULL; + } + if(sftp->rmdir_packet) { + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + } + if(sftp->stat_packet) { + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + } + if(sftp->symlink_packet) { + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + } + if(sftp->fsync_packet) { + LIBSSH2_FREE(session, sftp->fsync_packet); + sftp->fsync_packet = NULL; + } + + sftp_packet_flush(sftp); + + /* TODO: We should consider walking over the sftp_handles list and kill + * any remaining sftp handles ... */ + + rc = _libssh2_channel_free(sftp->channel); + + return rc; +} + +/* libssh2_sftp_shutdown + * Shutsdown the SFTP subsystem + */ +LIBSSH2_API int +libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, sftp_shutdown(sftp)); + return rc; +} + +/* ******************************* + * SFTP File and Directory Ops * + ******************************* */ + +/* sftp_open + */ +static LIBSSH2_SFTP_HANDLE * +sftp_open(LIBSSH2_SFTP *sftp, const char *filename, + size_t filename_len, uint32_t flags, long mode, + int open_type) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_HANDLE *fp; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + LIBSSH2_SFTP_ATTR_PERMISSIONS, 0, 0, 0, 0, 0, 0 + }; + unsigned char *s; + ssize_t rc; + int open_file = (open_type == LIBSSH2_SFTP_OPENFILE)?1:0; + + if(sftp->open_state == libssh2_NB_state_idle) { + /* packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) + + flags(4) */ + sftp->open_packet_len = filename_len + 13 + + (open_file? (4 + + sftp_attrsize(LIBSSH2_SFTP_ATTR_PERMISSIONS)) : 0); + + /* surprise! this starts out with nothing sent */ + sftp->open_packet_sent = 0; + s = sftp->open_packet = LIBSSH2_ALLOC(session, sftp->open_packet_len); + if(!sftp->open_packet) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_OPEN or " + "FXP_OPENDIR packet"); + return NULL; + } + /* Filetype in SFTP 3 and earlier */ + attrs.permissions = mode | + (open_file ? LIBSSH2_SFTP_ATTR_PFILETYPE_FILE : + LIBSSH2_SFTP_ATTR_PFILETYPE_DIR); + + _libssh2_store_u32(&s, sftp->open_packet_len - 4); + *(s++) = open_file? SSH_FXP_OPEN : SSH_FXP_OPENDIR; + sftp->open_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->open_request_id); + _libssh2_store_str(&s, filename, filename_len); + + if(open_file) { + _libssh2_store_u32(&s, flags); + s += sftp_attr2bin(s, &attrs); + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Sending %s open request", + open_file? "file" : "directory"); + + sftp->open_state = libssh2_NB_state_created; + } + + if(sftp->open_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->open_packet+ + sftp->open_packet_sent, + sftp->open_packet_len - + sftp->open_packet_sent); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block sending FXP_OPEN or " + "FXP_OPENDIR command"); + return NULL; + } + else if(rc < 0) { + _libssh2_error(session, rc, "Unable to send FXP_OPEN*"); + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + sftp->open_state = libssh2_NB_state_idle; + return NULL; + } + + /* bump the sent counter and remain in this state until the whole + data is off */ + sftp->open_packet_sent += rc; + + if(sftp->open_packet_len == sftp->open_packet_sent) { + LIBSSH2_FREE(session, sftp->open_packet); + sftp->open_packet = NULL; + + sftp->open_state = libssh2_NB_state_sent; + } + } + + if(sftp->open_state == libssh2_NB_state_sent) { + size_t data_len; + unsigned char *data; + static const unsigned char fopen_responses[2] = + { SSH_FXP_HANDLE, SSH_FXP_STATUS }; + rc = sftp_packet_requirev(sftp, 2, fopen_responses, + sftp->open_request_id, &data, + &data_len, 1); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block waiting for status message"); + return NULL; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Response too small"); + return NULL; + } + sftp->open_state = libssh2_NB_state_idle; + if(rc) { + _libssh2_error(session, rc, "Timeout waiting for status message"); + return NULL; + } + + /* OPEN can basically get STATUS or HANDLE back, where HANDLE implies + a fine response while STATUS means error. It seems though that at + times we get an SSH_FX_OK back in a STATUS, followed the "real" + HANDLE so we need to properly deal with that. */ + if(data[0] == SSH_FXP_STATUS) { + int badness = 1; + + if(data_len < 9) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_STATUS"); + LIBSSH2_FREE(session, data); + return NULL; + } + + sftp->last_errno = _libssh2_ntohu32(data + 5); + + if(LIBSSH2_FX_OK == sftp->last_errno) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "got HANDLE FXOK!"); + + LIBSSH2_FREE(session, data); + + /* silly situation, but check for a HANDLE */ + rc = sftp_packet_require(sftp, SSH_FXP_HANDLE, + sftp->open_request_id, &data, + &data_len, 10); + if(rc == LIBSSH2_ERROR_EAGAIN) { + /* go back to sent state and wait for something else */ + sftp->open_state = libssh2_NB_state_sent; + return NULL; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_HANDLE"); + return NULL; + } + else if(!rc) + /* we got the handle so this is not a bad situation */ + badness = 0; + } + + if(badness) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Failed opening remote file"); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "got FXP_STATUS %d", + sftp->last_errno); + LIBSSH2_FREE(session, data); + return NULL; + } + } + + if(data_len < 10) { + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Too small FXP_HANDLE"); + LIBSSH2_FREE(session, data); + return NULL; + } + + fp = LIBSSH2_CALLOC(session, sizeof(LIBSSH2_SFTP_HANDLE)); + if(!fp) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate new SFTP handle structure"); + LIBSSH2_FREE(session, data); + return NULL; + } + fp->handle_type = open_file ? LIBSSH2_SFTP_HANDLE_FILE : + LIBSSH2_SFTP_HANDLE_DIR; + + fp->handle_len = _libssh2_ntohu32(data + 5); + if(fp->handle_len > SFTP_HANDLE_MAXLEN) + /* SFTP doesn't allow handles longer than 256 characters */ + fp->handle_len = SFTP_HANDLE_MAXLEN; + + if(fp->handle_len > (data_len - 9)) + /* do not reach beyond the end of the data we got */ + fp->handle_len = data_len - 9; + + memcpy(fp->handle, data + 9, fp->handle_len); + + LIBSSH2_FREE(session, data); + + /* add this file handle to the list kept in the sftp session */ + _libssh2_list_add(&sftp->sftp_handles, &fp->node); + + fp->sftp = sftp; /* point to the parent struct */ + + fp->u.file.offset = 0; + fp->u.file.offset_sent = 0; + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Open command successful"); + return fp; + } + return NULL; +} + +/* libssh2_sftp_open_ex + */ +LIBSSH2_API LIBSSH2_SFTP_HANDLE * +libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp, const char *filename, + unsigned int filename_len, unsigned long flags, long mode, + int open_type) +{ + LIBSSH2_SFTP_HANDLE *hnd; + + if(!sftp) + return NULL; + + BLOCK_ADJUST_ERRNO(hnd, sftp->channel->session, + sftp_open(sftp, filename, filename_len, flags, mode, + open_type)); + return hnd; +} + +/* + * sftp_read + * + * Read from an SFTP file handle + * + */ +static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer, + size_t buffer_size) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t count = 0; + struct sftp_pipeline_chunk *chunk; + struct sftp_pipeline_chunk *next; + ssize_t rc; + struct _libssh2_sftp_handle_file_data *filep = + &handle->u.file; + size_t bytes_in_buffer = 0; + char *sliding_bufferp = buffer; + + /* This function can be interrupted in three different places where it + might need to wait for data from the network. It returns EAGAIN to + allow non-blocking clients to do other work but these client are + expected to call this function again (possibly many times) to finish + the operation. + + The tricky part is that if we previously aborted a sftp_read due to + EAGAIN, we must continue at the same spot to continue the previously + interrupted operation. This is done using a state machine to record + what phase of execution we were at. The state is stored in + sftp->read_state. + + libssh2_NB_state_idle: The first phase is where we prepare multiple + FXP_READ packets to do optimistic read-ahead. We send off as many as + possible in the second phase without waiting for a response to each + one; this is the key to fast reads. But we may have to adjust the + channel window size to do this which may interrupt this function while + waiting. The state machine saves the phase as libssh2_NB_state_idle so + it returns here on the next call. + + libssh2_NB_state_sent: The second phase is where we send the FXP_READ + packets. Writing them to the channel can be interrupted with EAGAIN + but the state machine ensures we skip the first phase on the next call + and resume sending. + + libssh2_NB_state_sent2: In the third phase (indicated by ) we read the + data from the responses that have arrived so far. Reading can be + interrupted with EAGAIN but the state machine ensures we skip the first + and second phases on the next call and resume sending. + */ + + switch(sftp->read_state) { + case libssh2_NB_state_idle: + + /* Some data may already have been read from the server in the + previous call but didn't fit in the buffer at the time. If so, we + return that now as we can't risk being interrupted later with data + partially written to the buffer. */ + if(filep->data_left) { + size_t copy = MIN(buffer_size, filep->data_left); + + memcpy(buffer, &filep->data[ filep->data_len - filep->data_left], + copy); + + filep->data_left -= copy; + filep->offset += copy; + + if(!filep->data_left) { + LIBSSH2_FREE(session, filep->data); + filep->data = NULL; + } + + return copy; + } + + if(filep->eof) { + return 0; + } + else { + /* We allow a number of bytes being requested at any given time + without having been acked - until we reach EOF. */ + + /* Number of bytes asked for that haven't been acked yet */ + size_t already = (size_t)(filep->offset_sent - filep->offset); + + size_t max_read_ahead = buffer_size*4; + unsigned long recv_window; + + if(max_read_ahead > LIBSSH2_CHANNEL_WINDOW_DEFAULT*4) + max_read_ahead = LIBSSH2_CHANNEL_WINDOW_DEFAULT*4; + + /* if the buffer_size passed in now is smaller than what has + already been sent, we risk getting count become a very large + number */ + if(max_read_ahead > already) + count = max_read_ahead - already; + + /* 'count' is how much more data to ask for, and 'already' is how + much data that already has been asked for but not yet returned. + Specifically, 'count' means how much data that have or will be + asked for by the nodes that are already added to the linked + list. Some of those read requests may not actually have been + sent off successfully yet. + + If 'already' is very large it should be perfectly fine to have + count set to 0 as then we don't have to ask for more data + (right now). + + buffer_size*4 is just picked more or less out of the air. The + idea is that when reading SFTP from a remote server, we send + away multiple read requests guessing that the client will read + more than only this 'buffer_size' amount of memory. So we ask + for maximum buffer_size*4 amount of data so that we can return + them very fast in subsequent calls. + */ + + recv_window = libssh2_channel_window_read_ex(sftp->channel, + NULL, NULL); + if(max_read_ahead > recv_window) { + /* more data will be asked for than what the window currently + allows, expand it! */ + + rc = _libssh2_channel_receive_window_adjust(sftp->channel, + max_read_ahead*8, + 1, NULL); + /* if this returns EAGAIN, we will get back to this function + at next call */ + assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->data_left); + assert(rc != LIBSSH2_ERROR_EAGAIN || !filep->eof); + if(rc) + return rc; + } + } + + while(count > 0) { + unsigned char *s; + + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + + handle_len(4) + offset(8) + count(4) */ + uint32_t packet_len = (uint32_t)handle->handle_len + 25; + uint32_t request_id; + + uint32_t size = count; + if(size < buffer_size) + size = buffer_size; + if(size > MAX_SFTP_READ_SIZE) + size = MAX_SFTP_READ_SIZE; + + chunk = LIBSSH2_ALLOC(session, packet_len + + sizeof(struct sftp_pipeline_chunk)); + if(!chunk) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for FXP_WRITE"); + + chunk->offset = filep->offset_sent; + chunk->len = size; + chunk->lefttosend = packet_len; + chunk->sent = 0; + + s = chunk->packet; + + _libssh2_store_u32(&s, packet_len - 4); + *s++ = SSH_FXP_READ; + request_id = sftp->request_id++; + chunk->request_id = request_id; + _libssh2_store_u32(&s, request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + _libssh2_store_u64(&s, filep->offset_sent); + filep->offset_sent += size; /* advance offset at once */ + _libssh2_store_u32(&s, size); + + /* add this new entry LAST in the list */ + _libssh2_list_add(&handle->packet_list, &chunk->node); + count -= MIN(size, count); /* deduct the size we used, as we might + * have to create more packets */ + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "read request id %d sent (offset: %d, size: %d)", + request_id, (int)chunk->offset, (int)chunk->len); + } + /* FALL-THROUGH */ + case libssh2_NB_state_sent: + + sftp->read_state = libssh2_NB_state_idle; + + /* move through the READ packets that haven't been sent and send as + many as possible - remember that we don't block */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) { + + rc = _libssh2_channel_write(channel, 0, + &chunk->packet[chunk->sent], + chunk->lefttosend); + if(rc < 0) { + sftp->read_state = libssh2_NB_state_sent; + return rc; + } + + /* remember where to continue sending the next time */ + chunk->lefttosend -= rc; + chunk->sent += rc; + + if(chunk->lefttosend) { + /* We still have data left to send for this chunk. + * If there is at least one completely sent chunk, + * we can get out of this loop and start reading. */ + if(chunk != _libssh2_list_first(&handle->packet_list)) { + break; + } + else { + continue; + } + } + } + + /* move on to the next chunk with data to send */ + chunk = _libssh2_list_next(&chunk->node); + } + /* FALL-THROUGH */ + + case libssh2_NB_state_sent2: + + sftp->read_state = libssh2_NB_state_idle; + + /* + * Count all ACKed packets and act on the contents of them. + */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + unsigned char *data; + size_t data_len; + uint32_t rc32; + static const unsigned char read_responses[2] = { + SSH_FXP_DATA, SSH_FXP_STATUS + }; + + if(chunk->lefttosend) { + /* if the chunk still has data left to send, we shouldn't wait + for an ACK for it just yet */ + if(bytes_in_buffer > 0) { + return bytes_in_buffer; + } + else { + /* we should never reach this point */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "sftp_read() internal error"); + } + } + + rc = sftp_packet_requirev(sftp, 2, read_responses, + chunk->request_id, &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) { + /* do not return EAGAIN if we have already + * written data into the buffer */ + return bytes_in_buffer; + } + + if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Response too small"); + } + else if(rc < 0) { + sftp->read_state = libssh2_NB_state_sent2; + return rc; + } + + /* + * We get DATA or STATUS back. STATUS can be error, or it is + * FX_EOF when we reach the end of the file. + */ + + switch(data[0]) { + case SSH_FXP_STATUS: + /* remove the chunk we just processed */ + + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + + /* we must remove all outstanding READ requests, as either we + got an error or we're at end of file */ + sftp_packetlist_flush(handle); + + rc32 = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if(rc32 == LIBSSH2_FX_EOF) { + filep->eof = TRUE; + return bytes_in_buffer; + } + else { + sftp->last_errno = rc32; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP READ error"); + } + break; + + case SSH_FXP_DATA: + if(chunk->offset != filep->offset) { + /* This could happen if the server returns less bytes than + requested, which shouldn't happen for normal files. See: + https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02 + #section-6.4 + */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Read Packet At Unexpected Offset"); + } + + rc32 = _libssh2_ntohu32(data + 5); + if(rc32 > (data_len - 9)) + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol badness"); + + if(rc32 > chunk->len) { + /* A chunk larger than we requested was returned to us. + This is a protocol violation and we don't know how to + deal with it. Bail out! */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP_READ response too big"); + } + + if(rc32 != chunk->len) { + /* a short read does not imply end of file, but we must + adjust the offset_sent since it was advanced with a + full chunk->len before */ + filep->offset_sent -= (chunk->len - rc32); + } + + if((bytes_in_buffer + rc32) > buffer_size) { + /* figure out the overlap amount */ + filep->data_left = (bytes_in_buffer + rc32) - buffer_size; + + /* getting the full packet would overflow the buffer, so + only get the correct amount and keep the remainder */ + rc32 = (uint32_t)buffer_size - bytes_in_buffer; + + /* store data to keep for next call */ + filep->data = data; + filep->data_len = data_len; + } + else + filep->data_len = 0; + + /* copy the received data from the received FXP_DATA packet to + the buffer at the correct index */ + memcpy(sliding_bufferp, data + 9, rc32); + filep->offset += rc32; + bytes_in_buffer += rc32; + sliding_bufferp += rc32; + + if(filep->data_len == 0) + /* free the allocated data if not stored to keep */ + LIBSSH2_FREE(session, data); + + /* remove the chunk we just processed keeping track of the + * next one in case we need it */ + next = _libssh2_list_next(&chunk->node); + _libssh2_list_remove(&chunk->node); + LIBSSH2_FREE(session, chunk); + + /* check if we have space left in the buffer + * and either continue to the next chunk or stop + */ + if(bytes_in_buffer < buffer_size) { + chunk = next; + } + else { + chunk = NULL; + } + + break; + default: + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol badness: unrecognised " + "read request response"); + } + } + + if(bytes_in_buffer > 0) + return bytes_in_buffer; + + break; + + default: + assert(!"State machine error; unrecognised read state"); + } + + /* we should never reach this point */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "sftp_read() internal error"); +} + +/* libssh2_sftp_read + * Read from an SFTP file handle + */ +LIBSSH2_API ssize_t +libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, + size_t buffer_maxlen) +{ + ssize_t rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_read(hnd, buffer, buffer_maxlen)); + return rc; +} + +/* sftp_readdir + * Read from an SFTP directory handle + */ +static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + uint32_t num_names; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 13; + unsigned char *s, *data; + static const unsigned char read_responses[2] = { + SSH_FXP_NAME, SSH_FXP_STATUS }; + ssize_t retcode; + + if(sftp->readdir_state == libssh2_NB_state_idle) { + if(handle->u.dir.names_left) { + /* + * A prior request returned more than one directory entry, + * feed it back from the buffer + */ + LIBSSH2_SFTP_ATTRIBUTES attrs_dummy; + size_t real_longentry_len; + size_t real_filename_len; + size_t filename_len; + size_t longentry_len; + size_t names_packet_len = handle->u.dir.names_packet_len; + int attr_len = 0; + + if(names_packet_len >= 4) { + s = (unsigned char *) handle->u.dir.next_name; + real_filename_len = _libssh2_ntohu32(s); + s += 4; + names_packet_len -= 4; + } + else { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + filename_len = real_filename_len; + if(filename_len >= buffer_maxlen) { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + if(buffer_maxlen >= filename_len && names_packet_len >= + filename_len) { + memcpy(buffer, s, filename_len); + buffer[filename_len] = '\0'; /* zero terminate */ + s += real_filename_len; + names_packet_len -= real_filename_len; + } + else { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + if(names_packet_len >= 4) { + real_longentry_len = _libssh2_ntohu32(s); + s += 4; + names_packet_len -= 4; + } + else { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + if(longentry && (longentry_maxlen>1)) { + longentry_len = real_longentry_len; + + if(longentry_len >= longentry_maxlen || + longentry_len > names_packet_len) { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + memcpy(longentry, s, longentry_len); + longentry[longentry_len] = '\0'; /* zero terminate */ + } + + if(real_longentry_len <= names_packet_len) { + s += real_longentry_len; + names_packet_len -= real_longentry_len; + } + else { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + if(attrs) + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + + attr_len = sftp_bin2attr(attrs ? attrs : &attrs_dummy, s, + names_packet_len); + + if(attr_len >= 0) { + s += attr_len; + names_packet_len -= attr_len; + } + else { + filename_len = (size_t)LIBSSH2_ERROR_BUFFER_TOO_SMALL; + goto end; + } + + handle->u.dir.next_name = (char *) s; + handle->u.dir.names_packet_len = names_packet_len; + end: + + if((--handle->u.dir.names_left) == 0) + LIBSSH2_FREE(session, handle->u.dir.names_packet); + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "libssh2_sftp_readdir_ex() return %d", + filename_len); + return (ssize_t)filename_len; + } + + /* Request another entry(entries?) */ + + s = sftp->readdir_packet = LIBSSH2_ALLOC(session, packet_len); + if(!sftp->readdir_packet) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "FXP_READDIR packet"); + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_READDIR; + sftp->readdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->readdir_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->readdir_state = libssh2_NB_state_created; + } + + if(sftp->readdir_state == libssh2_NB_state_created) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Reading entries from directory handle"); + retcode = _libssh2_channel_write(channel, 0, sftp->readdir_packet, + packet_len); + if(retcode == LIBSSH2_ERROR_EAGAIN) { + return retcode; + } + else if((ssize_t)packet_len != retcode) { + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + + LIBSSH2_FREE(session, sftp->readdir_packet); + sftp->readdir_packet = NULL; + + sftp->readdir_state = libssh2_NB_state_sent; + } + + retcode = sftp_packet_requirev(sftp, 2, read_responses, + sftp->readdir_request_id, &data, + &data_len, 9); + if(retcode == LIBSSH2_ERROR_EAGAIN) + return retcode; + else if(retcode == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Status message too short"); + } + else if(retcode) { + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, retcode, + "Timeout waiting for status message"); + } + + if(data[0] == SSH_FXP_STATUS) { + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if(retcode == LIBSSH2_FX_EOF) { + sftp->readdir_state = libssh2_NB_state_idle; + return 0; + } + else { + sftp->last_errno = retcode; + sftp->readdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + sftp->readdir_state = libssh2_NB_state_idle; + + num_names = _libssh2_ntohu32(data + 5); + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%lu entries returned", + num_names); + if(!num_names) { + LIBSSH2_FREE(session, data); + return 0; + } + + handle->u.dir.names_left = num_names; + handle->u.dir.names_packet = data; + handle->u.dir.next_name = (char *) data + 9; + handle->u.dir.names_packet_len = data_len - 9; + + /* use the name popping mechanism from the start of the function */ + return sftp_readdir(handle, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs); +} + +/* libssh2_sftp_readdir_ex + * Read from an SFTP directory handle + */ +LIBSSH2_API int +libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *hnd, char *buffer, + size_t buffer_maxlen, char *longentry, + size_t longentry_maxlen, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_readdir(hnd, buffer, buffer_maxlen, longentry, + longentry_maxlen, attrs)); + return rc; +} + +/* + * sftp_write + * + * Write data to an SFTP handle. Returns the number of bytes written, or + * a negative error code. + * + * We recommend sending very large data buffers to this function! + * + * Concept: + * + * - Detect how much of the given buffer that was already sent in a previous + * call by inspecting the linked list of outgoing chunks. Make sure to skip + * passed the data that has already been taken care of. + * + * - Split all (new) outgoing data in chunks no larger than N. + * + * - Each N bytes chunk gets created as a separate SFTP packet. + * + * - Add all created outgoing packets to the linked list. + * + * - Walk through the list and send the chunks that haven't been sent, + * as many as possible until EAGAIN. Some of the chunks may have been put + * in the list in a previous invoke. + * + * - For all the chunks in the list that have been completely sent off, check + * for ACKs. If a chunk has been ACKed, it is removed from the linked + * list and the "acked" counter gets increased with that data amount. + * + * - Return TOTAL bytes acked so far. + * + * Caveats: + * - be careful: we must not return a higher number than what was given! + * + * TODO: + * Introduce an option that disables this sort of "speculative" ahead writing + * as there's a risk that it will do harm to some app. + */ + +static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer, + size_t count) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + uint32_t retcode; + uint32_t packet_len; + unsigned char *s, *data; + ssize_t rc; + struct sftp_pipeline_chunk *chunk; + struct sftp_pipeline_chunk *next; + size_t acked = 0; + size_t org_count = count; + size_t already; + + switch(sftp->write_state) { + default: + case libssh2_NB_state_idle: + + /* Number of bytes sent off that haven't been acked and therefore we + will get passed in here again. + + Also, add up the number of bytes that actually already have been + acked but we haven't been able to return as such yet, so we will + get that data as well passed in here again. + */ + already = (size_t) (handle->u.file.offset_sent - + handle->u.file.offset)+ + handle->u.file.acked; + + if(count >= already) { + /* skip the part already made into packets */ + buffer += already; + count -= already; + } + else + /* there is more data already fine than what we got in this call */ + count = 0; + + sftp->write_state = libssh2_NB_state_idle; + while(count) { + /* TODO: Possibly this should have some logic to prevent a very + very small fraction to be left but lets ignore that for now */ + uint32_t size = MIN(MAX_SFTP_OUTGOING_SIZE, count); + uint32_t request_id; + + /* 25 = packet_len(4) + packet_type(1) + request_id(4) + + handle_len(4) + offset(8) + count(4) */ + packet_len = handle->handle_len + size + 25; + + chunk = LIBSSH2_ALLOC(session, packet_len + + sizeof(struct sftp_pipeline_chunk)); + if(!chunk) + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "malloc fail for FXP_WRITE"); + + chunk->len = size; + chunk->sent = 0; + chunk->lefttosend = packet_len; + + s = chunk->packet; + _libssh2_store_u32(&s, packet_len - 4); + + *(s++) = SSH_FXP_WRITE; + request_id = sftp->request_id++; + chunk->request_id = request_id; + _libssh2_store_u32(&s, request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + _libssh2_store_u64(&s, handle->u.file.offset_sent); + handle->u.file.offset_sent += size; /* advance offset at once */ + _libssh2_store_str(&s, buffer, size); + + /* add this new entry LAST in the list */ + _libssh2_list_add(&handle->packet_list, &chunk->node); + + buffer += size; + count -= size; /* deduct the size we used, as we might have + to create more packets */ + } + + /* move through the WRITE packets that haven't been sent and send as + many as possible - remember that we don't block */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) { + rc = _libssh2_channel_write(channel, 0, + &chunk->packet[chunk->sent], + chunk->lefttosend); + if(rc < 0) + /* remain in idle state */ + return rc; + + /* remember where to continue sending the next time */ + chunk->lefttosend -= rc; + chunk->sent += rc; + + if(chunk->lefttosend) + /* data left to send, get out of loop */ + break; + } + + /* move on to the next chunk with data to send */ + chunk = _libssh2_list_next(&chunk->node); + } + + /* fall-through */ + case libssh2_NB_state_sent: + + sftp->write_state = libssh2_NB_state_idle; + /* + * Count all ACKed packets + */ + chunk = _libssh2_list_first(&handle->packet_list); + + while(chunk) { + if(chunk->lefttosend) + /* if the chunk still has data left to send, we shouldn't wait + for an ACK for it just yet */ + break; + + else if(acked) + /* if we have sent data that is acked, we must return that + info before we call a function that might return EAGAIN */ + break; + + /* we check the packets in order */ + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + chunk->request_id, &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP write packet too short"); + } + else if(rc < 0) { + if(rc == LIBSSH2_ERROR_EAGAIN) + sftp->write_state = libssh2_NB_state_sent; + return rc; + } + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + sftp->last_errno = retcode; + if(retcode == LIBSSH2_FX_OK) { + acked += chunk->len; /* number of payload data that was acked + here */ + + /* we increase the offset value for all acks */ + handle->u.file.offset += chunk->len; + + next = _libssh2_list_next(&chunk->node); + + _libssh2_list_remove(&chunk->node); /* remove from list */ + LIBSSH2_FREE(session, chunk); /* free memory */ + + chunk = next; + } + else { + /* flush all pending packets from the outgoing list */ + sftp_packetlist_flush(handle); + + /* since we return error now, the application will not get any + outstanding data acked, so we need to rewind the offset to + where the application knows it has reached with acked + data */ + handle->u.file.offset -= handle->u.file.acked; + + /* then reset the offset_sent to be the same as the offset */ + handle->u.file.offset_sent = handle->u.file.offset; + + /* clear the acked counter since we can have no pending data to + ack after an error */ + handle->u.file.acked = 0; + + /* the server returned an error for that written chunk, + propagate this back to our parent function */ + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "FXP write failed"); + } + } + break; + } + + /* if there were acked data in a previous call that wasn't returned then, + add that up and try to return it all now. This can happen if the app + first sends a huge buffer of data, and then in a second call it sends a + smaller one. */ + acked += handle->u.file.acked; + + if(acked) { + ssize_t ret = MIN(acked, org_count); + /* we got data acked so return that amount, but no more than what + was asked to get sent! */ + + /* store the remainder. 'ret' is always equal to or less than 'acked' + here */ + handle->u.file.acked = acked - ret; + + return ret; + } + + else + return 0; /* nothing was acked, and no EAGAIN was received! */ +} + +/* libssh2_sftp_write + * Write data to a file handle + */ +LIBSSH2_API ssize_t +libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *hnd, const char *buffer, + size_t count) +{ + ssize_t rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_write(hnd, buffer, count)); + return rc; + +} + +static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + /* 34 = packet_len(4) + packet_type(1) + request_id(4) + + string_len(4) + strlen("fsync@openssh.com")(17) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 34; + size_t data_len; + unsigned char *packet, *s, *data; + ssize_t rc; + uint32_t retcode; + + if(sftp->fsync_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Issuing fsync command"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if(!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->fsync_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fsync_request_id); + _libssh2_store_str(&s, "fsync@openssh.com", 17); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->fsync_state = libssh2_NB_state_created; + } + else { + packet = sftp->fsync_packet; + } + + if(sftp->fsync_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->fsync_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->fsync_packet = NULL; + + if(rc < 0) { + sftp->fsync_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->fsync_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->fsync_request_id, &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP fsync packet too short"); + } + else if(rc) { + sftp->fsync_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + sftp->fsync_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if(retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "fsync failed"); + } + + return 0; +} + +/* libssh2_sftp_fsync + * Commit data on the handle to disk. + */ +LIBSSH2_API int +libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *hnd) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_fsync(hnd)); + return rc; +} + + +/* + * sftp_fstat + * + * Get or Set stat on a file + */ +static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle, + LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = + handle->handle_len + 13 + (setstat ? sftp_attrsize(attrs->flags) : 0); + unsigned char *s, *data; + static const unsigned char fstat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + ssize_t rc; + + if(sftp->fstat_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Issuing %s command", + setstat ? "set-stat" : "stat"); + s = sftp->fstat_packet = LIBSSH2_ALLOC(session, packet_len); + if(!sftp->fstat_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "FSTAT/FSETSTAT packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = setstat ? SSH_FXP_FSETSTAT : SSH_FXP_FSTAT; + sftp->fstat_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fstat_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + if(setstat) { + s += sftp_attr2bin(s, attrs); + } + + sftp->fstat_state = libssh2_NB_state_created; + } + + if(sftp->fstat_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->fstat_packet, + packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + sftp->fstat_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + (setstat ? "Unable to send FXP_FSETSTAT" + : "Unable to send FXP_FSTAT command")); + } + LIBSSH2_FREE(session, sftp->fstat_packet); + sftp->fstat_packet = NULL; + + sftp->fstat_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, fstat_responses, + sftp->fstat_request_id, &data, + &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP fstat packet too short"); + } + else if(rc) { + sftp->fstat_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Timeout waiting for status message"); + } + + sftp->fstat_state = libssh2_NB_state_idle; + + if(data[0] == SSH_FXP_STATUS) { + uint32_t retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if(retcode == LIBSSH2_FX_OK) { + return 0; + } + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + if(sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) { + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Attributes too short in SFTP fstat"); + } + + LIBSSH2_FREE(session, data); + + return 0; +} + +/* libssh2_sftp_fstat_ex + * Get or Set stat on a file + */ +LIBSSH2_API int +libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *hnd, + LIBSSH2_SFTP_ATTRIBUTES *attrs, int setstat) +{ + int rc; + if(!hnd || !attrs) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, + sftp_fstat(hnd, attrs, setstat)); + return rc; +} + + +/* libssh2_sftp_seek64 + * Set the read/write pointer to an arbitrary position within the file + */ +LIBSSH2_API void +libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle, libssh2_uint64_t offset) +{ + if(!handle) + return; + if(handle->u.file.offset == offset && handle->u.file.offset_sent == offset) + return; + + handle->u.file.offset = handle->u.file.offset_sent = offset; + /* discard all pending requests and currently read data */ + sftp_packetlist_flush(handle); + + /* free the left received buffered data */ + if(handle->u.file.data_left) { + LIBSSH2_FREE(handle->sftp->channel->session, handle->u.file.data); + handle->u.file.data_left = handle->u.file.data_len = 0; + handle->u.file.data = NULL; + } + + /* reset EOF to False */ + handle->u.file.eof = FALSE; +} + +/* libssh2_sftp_seek + * Set the read/write pointer to an arbitrary position within the file + */ +LIBSSH2_API void +libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset) +{ + libssh2_sftp_seek64(handle, (libssh2_uint64_t)offset); +} + +/* libssh2_sftp_tell + * Return the current read/write pointer's offset + */ +LIBSSH2_API size_t +libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle) +{ + if(!handle) + return 0; /* no handle, no size */ + + /* NOTE: this may very well truncate the size if it is larger than what + size_t can hold, so libssh2_sftp_tell64() is really the function you + should use */ + return (size_t)(handle->u.file.offset); +} + +/* libssh2_sftp_tell64 + * Return the current read/write pointer's offset + */ +LIBSSH2_API libssh2_uint64_t +libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle) +{ + if(!handle) + return 0; /* no handle, no size */ + + return handle->u.file.offset; +} + +/* + * Flush all remaining incoming SFTP packets and zombies. + */ +static void sftp_packet_flush(LIBSSH2_SFTP *sftp) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_PACKET *packet = _libssh2_list_first(&sftp->packets); + struct sftp_zombie_requests *zombie = + _libssh2_list_first(&sftp->zombie_requests); + + while(packet) { + LIBSSH2_SFTP_PACKET *next; + + /* check next struct in the list */ + next = _libssh2_list_next(&packet->node); + _libssh2_list_remove(&packet->node); + LIBSSH2_FREE(session, packet->data); + LIBSSH2_FREE(session, packet); + + packet = next; + } + + while(zombie) { + /* figure out the next node */ + struct sftp_zombie_requests *next = _libssh2_list_next(&zombie->node); + /* unlink the current one */ + _libssh2_list_remove(&zombie->node); + /* free the memory */ + LIBSSH2_FREE(session, zombie); + zombie = next; + } + +} + +/* sftp_close_handle + * + * Close a file or directory handle. + * Also frees handle resource and unlinks it from the SFTP structure. + * The handle is no longer usable after return of this function, unless + * the return value is LIBSSH2_ERROR_EAGAIN in which case this function + * should be called again. + */ +static int +sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + handle_len(4) */ + uint32_t packet_len = handle->handle_len + 13; + unsigned char *s, *data = NULL; + int rc = 0; + + if(handle->close_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Closing handle"); + s = handle->close_packet = LIBSSH2_ALLOC(session, packet_len); + if(!handle->close_packet) { + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_CLOSE " + "packet"); + } + else { + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_CLOSE; + handle->close_request_id = sftp->request_id++; + _libssh2_store_u32(&s, handle->close_request_id); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + handle->close_state = libssh2_NB_state_created; + } + } + + if(handle->close_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, handle->close_packet, + packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((ssize_t)packet_len != rc) { + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_CLOSE command"); + } + else + handle->close_state = libssh2_NB_state_sent; + + LIBSSH2_FREE(session, handle->close_packet); + handle->close_packet = NULL; + } + + if(handle->close_state == libssh2_NB_state_sent) { + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + handle->close_request_id, &data, + &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + data = NULL; + _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Packet too short in FXP_CLOSE command"); + } + else if(rc) { + _libssh2_error(session, rc, + "Error waiting for status message"); + } + + handle->close_state = libssh2_NB_state_sent1; + } + + if(!data) { + /* if it reaches this point with data unset, something unwanted + happened for which we should have set an error code */ + assert(rc); + + } + else { + int retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if(retcode != LIBSSH2_FX_OK) { + sftp->last_errno = retcode; + handle->close_state = libssh2_NB_state_idle; + rc = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + /* remove this handle from the parent's list */ + _libssh2_list_remove(&handle->node); + + if(handle->handle_type == LIBSSH2_SFTP_HANDLE_DIR) { + if(handle->u.dir.names_left) + LIBSSH2_FREE(session, handle->u.dir.names_packet); + } + else if(handle->handle_type == LIBSSH2_SFTP_HANDLE_FILE) { + if(handle->u.file.data) + LIBSSH2_FREE(session, handle->u.file.data); + } + + sftp_packetlist_flush(handle); + sftp->read_state = libssh2_NB_state_idle; + + handle->close_state = libssh2_NB_state_idle; + + LIBSSH2_FREE(session, handle); + + return rc; +} + +/* libssh2_sftp_close_handle + * + * Close a file or directory handle + * Also frees handle resource and unlinks it from the SFTP structure + */ +LIBSSH2_API int +libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *hnd) +{ + int rc; + if(!hnd) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, hnd->sftp->channel->session, sftp_close_handle(hnd)); + return rc; +} + +/* sftp_unlink + * Delete a file from the remote server + */ +static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename, + size_t filename_len) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + filename_len(4) */ + uint32_t packet_len = filename_len + 13; + unsigned char *s, *data; + int rc; + + if(sftp->unlink_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Unlinking %s", filename); + s = sftp->unlink_packet = LIBSSH2_ALLOC(session, packet_len); + if(!sftp->unlink_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_REMOVE " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_REMOVE; + sftp->unlink_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->unlink_request_id); + _libssh2_store_str(&s, filename, filename_len); + sftp->unlink_state = libssh2_NB_state_created; + } + + if(sftp->unlink_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->unlink_packet, + packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + sftp->unlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_REMOVE command"); + } + LIBSSH2_FREE(session, sftp->unlink_packet); + sftp->unlink_packet = NULL; + + sftp->unlink_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->unlink_request_id, &data, + &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP unlink packet too short"); + } + else if(rc) { + sftp->unlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->unlink_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if(retcode == LIBSSH2_FX_OK) { + return 0; + } + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* libssh2_sftp_unlink_ex + * Delete a file from the remote server + */ +LIBSSH2_API int +libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp, const char *filename, + unsigned int filename_len) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_unlink(sftp, filename, filename_len)); + return rc; +} + +/* + * sftp_rename + * + * Rename a file on the remote server + */ +static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename, + unsigned int source_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, long flags) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + uint32_t packet_len = + source_filename_len + dest_filename_len + 17 + (sftp->version >= + 5 ? 4 : 0); + /* packet_len(4) + packet_type(1) + request_id(4) + + source_filename_len(4) + dest_filename_len(4) + flags(4){SFTP5+) */ + unsigned char *data; + ssize_t rc; + + if(sftp->version < 2) { + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support RENAME"); + } + + if(sftp->rename_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Renaming %s to %s", + source_filename, dest_filename); + sftp->rename_s = sftp->rename_packet = + LIBSSH2_ALLOC(session, packet_len); + if(!sftp->rename_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RENAME " + "packet"); + } + + _libssh2_store_u32(&sftp->rename_s, packet_len - 4); + *(sftp->rename_s++) = SSH_FXP_RENAME; + sftp->rename_request_id = sftp->request_id++; + _libssh2_store_u32(&sftp->rename_s, sftp->rename_request_id); + _libssh2_store_str(&sftp->rename_s, source_filename, + source_filename_len); + _libssh2_store_str(&sftp->rename_s, dest_filename, dest_filename_len); + + if(sftp->version >= 5) + _libssh2_store_u32(&sftp->rename_s, flags); + + sftp->rename_state = libssh2_NB_state_created; + } + + if(sftp->rename_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->rename_packet, + sftp->rename_s - sftp->rename_packet); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if((ssize_t)packet_len != rc) { + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + sftp->rename_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RENAME command"); + } + LIBSSH2_FREE(session, sftp->rename_packet); + sftp->rename_packet = NULL; + + sftp->rename_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rename_request_id, &data, + &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP rename packet too short"); + } + else if(rc) { + sftp->rename_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->rename_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + sftp->last_errno = retcode; + + /* now convert the SFTP error code to libssh2 return code or error + message */ + switch(retcode) { + case LIBSSH2_FX_OK: + retcode = LIBSSH2_ERROR_NONE; + break; + + case LIBSSH2_FX_FILE_ALREADY_EXISTS: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "File already exists and " + "SSH_FXP_RENAME_OVERWRITE not specified"); + break; + + case LIBSSH2_FX_OP_UNSUPPORTED: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Operation Not Supported"); + break; + + default: + retcode = _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + break; + } + + return retcode; +} + +/* libssh2_sftp_rename_ex + * Rename a file on the remote server + */ +LIBSSH2_API int +libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp, const char *source_filename, + unsigned int source_filename_len, + const char *dest_filename, + unsigned int dest_filename_len, long flags) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_rename(sftp, source_filename, source_filename_len, + dest_filename, dest_filename_len, flags)); + return rc; +} + +/* + * sftp_fstatvfs + * + * Get file system statistics + */ +static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) +{ + LIBSSH2_SFTP *sftp = handle->sftp; + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + + handle_len (4) */ + /* 20 = strlen ("fstatvfs@openssh.com") */ + uint32_t packet_len = handle->handle_len + 20 + 17; + unsigned char *packet, *s, *data; + ssize_t rc; + unsigned int flag; + static const unsigned char responses[2] = + { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; + + if(sftp->fstatvfs_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Getting file system statistics"); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if(!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->fstatvfs_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->fstatvfs_request_id); + _libssh2_store_str(&s, "fstatvfs@openssh.com", 20); + _libssh2_store_str(&s, handle->handle, handle->handle_len); + + sftp->fstatvfs_state = libssh2_NB_state_created; + } + else { + packet = sftp->fstatvfs_packet; + } + + if(sftp->fstatvfs_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->fstatvfs_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->fstatvfs_packet = NULL; + + if(rc < 0) { + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->fstatvfs_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id, + &data, &data_len, 9); + + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP rename packet too short"); + } + else if(rc) { + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + if(data[0] == SSH_FXP_STATUS) { + int retcode = _libssh2_ntohu32(data + 5); + sftp->fstatvfs_state = libssh2_NB_state_idle; + LIBSSH2_FREE(session, data); + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + + if(data_len < 93) { + LIBSSH2_FREE(session, data); + sftp->fstatvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error: short response"); + } + + sftp->fstatvfs_state = libssh2_NB_state_idle; + + st->f_bsize = _libssh2_ntohu64(data + 5); + st->f_frsize = _libssh2_ntohu64(data + 13); + st->f_blocks = _libssh2_ntohu64(data + 21); + st->f_bfree = _libssh2_ntohu64(data + 29); + st->f_bavail = _libssh2_ntohu64(data + 37); + st->f_files = _libssh2_ntohu64(data + 45); + st->f_ffree = _libssh2_ntohu64(data + 53); + st->f_favail = _libssh2_ntohu64(data + 61); + st->f_fsid = _libssh2_ntohu64(data + 69); + flag = (unsigned int)_libssh2_ntohu64(data + 77); + st->f_namemax = _libssh2_ntohu64(data + 85); + + st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) + ? LIBSSH2_SFTP_ST_RDONLY : 0; + st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) + ? LIBSSH2_SFTP_ST_NOSUID : 0; + + LIBSSH2_FREE(session, data); + return 0; +} + +/* libssh2_sftp_fstatvfs + * Get filesystem space and inode utilization (requires fstatvfs@openssh.com + * support on the server) + */ +LIBSSH2_API int +libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st) +{ + int rc; + if(!handle || !st) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, handle->sftp->channel->session, + sftp_fstatvfs(handle, st)); + return rc; +} + +/* + * sftp_statvfs + * + * Get file system statistics + */ +static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, LIBSSH2_SFTP_STATVFS *st) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 17 = packet_len(4) + packet_type(1) + request_id(4) + ext_len(4) + + path_len (4) */ + /* 19 = strlen ("statvfs@openssh.com") */ + uint32_t packet_len = path_len + 19 + 17; + unsigned char *packet, *s, *data; + ssize_t rc; + unsigned int flag; + static const unsigned char responses[2] = + { SSH_FXP_EXTENDED_REPLY, SSH_FXP_STATUS }; + + if(sftp->statvfs_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Getting file system statistics of %s", path); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if(!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_EXTENDED " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_EXTENDED; + sftp->statvfs_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->statvfs_request_id); + _libssh2_store_str(&s, "statvfs@openssh.com", 19); + _libssh2_store_str(&s, path, path_len); + + sftp->statvfs_state = libssh2_NB_state_created; + } + else { + packet = sftp->statvfs_packet; + } + + if(sftp->statvfs_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN || + (0 <= rc && rc < (ssize_t)packet_len)) { + sftp->statvfs_packet = packet; + return LIBSSH2_ERROR_EAGAIN; + } + + LIBSSH2_FREE(session, packet); + sftp->statvfs_packet = NULL; + + if(rc < 0) { + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + sftp->statvfs_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id, + &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP fstat packet too short"); + } + else if(rc) { + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP EXTENDED REPLY"); + } + + if(data[0] == SSH_FXP_STATUS) { + int retcode = _libssh2_ntohu32(data + 5); + sftp->statvfs_state = libssh2_NB_state_idle; + LIBSSH2_FREE(session, data); + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + + if(data_len < 93) { + LIBSSH2_FREE(session, data); + sftp->statvfs_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error: short response"); + } + + sftp->statvfs_state = libssh2_NB_state_idle; + + st->f_bsize = _libssh2_ntohu64(data + 5); + st->f_frsize = _libssh2_ntohu64(data + 13); + st->f_blocks = _libssh2_ntohu64(data + 21); + st->f_bfree = _libssh2_ntohu64(data + 29); + st->f_bavail = _libssh2_ntohu64(data + 37); + st->f_files = _libssh2_ntohu64(data + 45); + st->f_ffree = _libssh2_ntohu64(data + 53); + st->f_favail = _libssh2_ntohu64(data + 61); + st->f_fsid = _libssh2_ntohu64(data + 69); + flag = (unsigned int)_libssh2_ntohu64(data + 77); + st->f_namemax = _libssh2_ntohu64(data + 85); + + st->f_flag = (flag & SSH_FXE_STATVFS_ST_RDONLY) + ? LIBSSH2_SFTP_ST_RDONLY : 0; + st->f_flag |= (flag & SSH_FXE_STATVFS_ST_NOSUID) + ? LIBSSH2_SFTP_ST_NOSUID : 0; + + LIBSSH2_FREE(session, data); + return 0; +} + +/* libssh2_sftp_statvfs_ex + * Get filesystem space and inode utilization (requires statvfs@openssh.com + * support on the server) + */ +LIBSSH2_API int +libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path, + size_t path_len, LIBSSH2_SFTP_STATVFS *st) +{ + int rc; + if(!sftp || !st) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, sftp_statvfs(sftp, path, path_len, + st)); + return rc; +} + + +/* + * sftp_mkdir + * + * Create an SFTP directory + */ +static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, long mode) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + LIBSSH2_SFTP_ATTRIBUTES attrs = { + 0, 0, 0, 0, 0, 0, 0 + }; + size_t data_len; + int retcode; + ssize_t packet_len; + unsigned char *packet, *s, *data; + int rc; + + if(mode != LIBSSH2_SFTP_DEFAULT_MODE) { + /* Filetype in SFTP 3 and earlier */ + attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; + attrs.permissions = mode | LIBSSH2_SFTP_ATTR_PFILETYPE_DIR; + } + + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + packet_len = path_len + 13 + sftp_attrsize(attrs.flags); + + if(sftp->mkdir_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, + "Creating directory %s with mode 0%lo", path, mode); + s = packet = LIBSSH2_ALLOC(session, packet_len); + if(!packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_MKDIR " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_MKDIR; + sftp->mkdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->mkdir_request_id); + _libssh2_store_str(&s, path, path_len); + + s += sftp_attr2bin(s, &attrs); + + sftp->mkdir_state = libssh2_NB_state_created; + } + else { + packet = sftp->mkdir_packet; + } + + if(sftp->mkdir_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, packet, packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + sftp->mkdir_packet = packet; + return rc; + } + if(packet_len != rc) { + LIBSSH2_FREE(session, packet); + sftp->mkdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "_libssh2_channel_write() failed"); + } + LIBSSH2_FREE(session, packet); + sftp->mkdir_state = libssh2_NB_state_sent; + sftp->mkdir_packet = NULL; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id, + &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP mkdir packet too short"); + } + else if(rc) { + sftp->mkdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->mkdir_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if(retcode == LIBSSH2_FX_OK) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "OK!"); + return 0; + } + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* + * libssh2_sftp_mkdir_ex + * + * Create an SFTP directory + */ +LIBSSH2_API int +libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, long mode) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_mkdir(sftp, path, path_len, mode)); + return rc; +} + +/* sftp_rmdir + * Remove a directory + */ +static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + int retcode; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = path_len + 13; + unsigned char *s, *data; + int rc; + + if(sftp->rmdir_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Removing directory: %s", + path); + s = sftp->rmdir_packet = LIBSSH2_ALLOC(session, packet_len); + if(!sftp->rmdir_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_RMDIR " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + *(s++) = SSH_FXP_RMDIR; + sftp->rmdir_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->rmdir_request_id); + _libssh2_store_str(&s, path, path_len); + + sftp->rmdir_state = libssh2_NB_state_created; + } + + if(sftp->rmdir_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->rmdir_packet, + packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(packet_len != rc) { + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + sftp->rmdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send FXP_RMDIR command"); + } + LIBSSH2_FREE(session, sftp->rmdir_packet); + sftp->rmdir_packet = NULL; + + sftp->rmdir_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_require(sftp, SSH_FXP_STATUS, + sftp->rmdir_request_id, &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP rmdir packet too short"); + } + else if(rc) { + sftp->rmdir_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Error waiting for FXP STATUS"); + } + + sftp->rmdir_state = libssh2_NB_state_idle; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + + if(retcode == LIBSSH2_FX_OK) { + return 0; + } + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } +} + +/* libssh2_sftp_rmdir_ex + * Remove a directory + */ +LIBSSH2_API int +libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_rmdir(sftp, path, path_len)); + return rc; +} + +/* sftp_stat + * Stat a file or symbolic link + */ +static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, int stat_type, + LIBSSH2_SFTP_ATTRIBUTES * attrs) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((stat_type == + LIBSSH2_SFTP_SETSTAT) ? sftp_attrsize(attrs->flags) : 0); + unsigned char *s, *data; + static const unsigned char stat_responses[2] = + { SSH_FXP_ATTRS, SSH_FXP_STATUS }; + int rc; + + if(sftp->stat_state == libssh2_NB_state_idle) { + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s", + (stat_type == LIBSSH2_SFTP_SETSTAT) ? "Set-statting" : + (stat_type == + LIBSSH2_SFTP_LSTAT ? "LStatting" : "Statting"), path); + s = sftp->stat_packet = LIBSSH2_ALLOC(session, packet_len); + if(!sftp->stat_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for FXP_*STAT " + "packet"); + } + + _libssh2_store_u32(&s, packet_len - 4); + + switch(stat_type) { + case LIBSSH2_SFTP_SETSTAT: + *(s++) = SSH_FXP_SETSTAT; + break; + + case LIBSSH2_SFTP_LSTAT: + *(s++) = SSH_FXP_LSTAT; + break; + + case LIBSSH2_SFTP_STAT: + default: + *(s++) = SSH_FXP_STAT; + } + sftp->stat_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->stat_request_id); + _libssh2_store_str(&s, path, path_len); + + if(stat_type == LIBSSH2_SFTP_SETSTAT) + s += sftp_attr2bin(s, attrs); + + sftp->stat_state = libssh2_NB_state_created; + } + + if(sftp->stat_state == libssh2_NB_state_created) { + rc = _libssh2_channel_write(channel, 0, sftp->stat_packet, packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return rc; + } + else if(packet_len != rc) { + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + sftp->stat_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send STAT/LSTAT/SETSTAT command"); + } + LIBSSH2_FREE(session, sftp->stat_packet); + sftp->stat_packet = NULL; + + sftp->stat_state = libssh2_NB_state_sent; + } + + rc = sftp_packet_requirev(sftp, 2, stat_responses, + sftp->stat_request_id, &data, &data_len, 9); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP stat packet too short"); + } + else if(rc) { + sftp->stat_state = libssh2_NB_state_idle; + return _libssh2_error(session, rc, + "Timeout waiting for status message"); + } + + sftp->stat_state = libssh2_NB_state_idle; + + if(data[0] == SSH_FXP_STATUS) { + int retcode; + + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if(retcode == LIBSSH2_FX_OK) { + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + return 0; + } + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + if(sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) { + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Attributes too short in SFTP fstat"); + } + + LIBSSH2_FREE(session, data); + + return 0; +} + +/* libssh2_sftp_stat_ex + * Stat a file or symbolic link + */ +LIBSSH2_API int +libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, int stat_type, + LIBSSH2_SFTP_ATTRIBUTES *attrs) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_stat(sftp, path, path_len, stat_type, attrs)); + return rc; +} + +/* sftp_symlink + * Read or set a symlink + */ +static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, char *target, + unsigned int target_len, int link_type) +{ + LIBSSH2_CHANNEL *channel = sftp->channel; + LIBSSH2_SESSION *session = channel->session; + size_t data_len, link_len; + /* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */ + ssize_t packet_len = + path_len + 13 + + ((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0); + unsigned char *s, *data; + static const unsigned char link_responses[2] = + { SSH_FXP_NAME, SSH_FXP_STATUS }; + int retcode; + + if((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) { + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Server does not support SYMLINK or READLINK"); + } + + if(sftp->symlink_state == libssh2_NB_state_idle) { + s = sftp->symlink_packet = LIBSSH2_ALLOC(session, packet_len); + if(!sftp->symlink_packet) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "SYMLINK/READLINK/REALPATH packet"); + } + + _libssh2_debug(session, LIBSSH2_TRACE_SFTP, "%s %s on %s", + (link_type == + LIBSSH2_SFTP_SYMLINK) ? "Creating" : "Reading", + (link_type == + LIBSSH2_SFTP_REALPATH) ? "realpath" : "symlink", path); + + _libssh2_store_u32(&s, packet_len - 4); + + switch(link_type) { + case LIBSSH2_SFTP_REALPATH: + *(s++) = SSH_FXP_REALPATH; + break; + + case LIBSSH2_SFTP_SYMLINK: + *(s++) = SSH_FXP_SYMLINK; + break; + + case LIBSSH2_SFTP_READLINK: + default: + *(s++) = SSH_FXP_READLINK; + } + sftp->symlink_request_id = sftp->request_id++; + _libssh2_store_u32(&s, sftp->symlink_request_id); + _libssh2_store_str(&s, path, path_len); + + if(link_type == LIBSSH2_SFTP_SYMLINK) + _libssh2_store_str(&s, target, target_len); + + sftp->symlink_state = libssh2_NB_state_created; + } + + if(sftp->symlink_state == libssh2_NB_state_created) { + ssize_t rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet, + packet_len); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + else if(packet_len != rc) { + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + sftp->symlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send SYMLINK/READLINK command"); + } + LIBSSH2_FREE(session, sftp->symlink_packet); + sftp->symlink_packet = NULL; + + sftp->symlink_state = libssh2_NB_state_sent; + } + + retcode = sftp_packet_requirev(sftp, 2, link_responses, + sftp->symlink_request_id, &data, + &data_len, 9); + if(retcode == LIBSSH2_ERROR_EAGAIN) + return retcode; + else if(retcode == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP symlink packet too short"); + } + else if(retcode) { + sftp->symlink_state = libssh2_NB_state_idle; + return _libssh2_error(session, retcode, + "Error waiting for status message"); + } + + sftp->symlink_state = libssh2_NB_state_idle; + + if(data[0] == SSH_FXP_STATUS) { + retcode = _libssh2_ntohu32(data + 5); + LIBSSH2_FREE(session, data); + if(retcode == LIBSSH2_FX_OK) + return LIBSSH2_ERROR_NONE; + else { + sftp->last_errno = retcode; + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP Protocol Error"); + } + } + + if(_libssh2_ntohu32(data + 5) < 1) { + LIBSSH2_FREE(session, data); + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "Invalid READLINK/REALPATH response, " + "no name entries"); + } + + if(data_len < 13) { + if(data_len > 0) { + LIBSSH2_FREE(session, data); + } + return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, + "SFTP stat packet too short"); + } + + /* this reads a u32 and stores it into a signed 32bit value */ + link_len = _libssh2_ntohu32(data + 9); + if(link_len < target_len) { + memcpy(target, data + 13, link_len); + target[link_len] = 0; + retcode = (int)link_len; + } + else + retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL; + LIBSSH2_FREE(session, data); + + return retcode; +} + +/* libssh2_sftp_symlink_ex + * Read or set a symlink + */ +LIBSSH2_API int +libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp, const char *path, + unsigned int path_len, char *target, + unsigned int target_len, int link_type) +{ + int rc; + if(!sftp) + return LIBSSH2_ERROR_BAD_USE; + BLOCK_ADJUST(rc, sftp->channel->session, + sftp_symlink(sftp, path, path_len, target, target_len, + link_type)); + return rc; +} + +/* libssh2_sftp_last_error + * Returns the last error code reported by SFTP + */ +LIBSSH2_API unsigned long +libssh2_sftp_last_error(LIBSSH2_SFTP *sftp) +{ + if(!sftp) + return 0; + + return sftp->last_errno; +} + +/* libssh2_sftp_get_channel + * Return the channel of sftp, then caller can control the channel's behavior. + */ +LIBSSH2_API LIBSSH2_CHANNEL * +libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp) +{ + if(!sftp) + return NULL; + + return sftp->channel; +} diff --git a/libssh2/transport.c b/libssh2/transport.c new file mode 100644 index 0000000..11e5614 --- /dev/null +++ b/libssh2/transport.c @@ -0,0 +1,917 @@ +/* Copyright (C) 2007 The Written Word, Inc. All rights reserved. + * Copyright (C) 2009-2010 by Daniel Stenberg + * Author: Daniel Stenberg + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file handles reading and writing to the SECSH transport layer. RFC4253. + */ + +#include "libssh2_priv.h" +#include +#include +#include +#ifdef LIBSSH2DEBUG +#include +#endif + +#include + +#include "transport.h" +#include "mac.h" + +#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */ +#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */ + +#ifdef LIBSSH2DEBUG +#define UNPRINTABLE_CHAR '.' +static void +debugdump(LIBSSH2_SESSION * session, + const char *desc, const unsigned char *ptr, size_t size) +{ + size_t i; + size_t c; + unsigned int width = 0x10; + char buffer[256]; /* Must be enough for width*4 + about 30 or so */ + size_t used; + static const char *hex_chars = "0123456789ABCDEF"; + + if(!(session->showmask & LIBSSH2_TRACE_TRANS)) { + /* not asked for, bail out */ + return; + } + + used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n", + desc, (int) size); + if(session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, + buffer, used); + else + fprintf(stderr, "%s", buffer); + + for(i = 0; i < size; i += width) { + + used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i); + + /* hex not disabled, show it */ + for(c = 0; c < width; c++) { + if(i + c < size) { + buffer[used++] = hex_chars[(ptr[i + c] >> 4) & 0xF]; + buffer[used++] = hex_chars[ptr[i + c] & 0xF]; + } + else { + buffer[used++] = ' '; + buffer[used++] = ' '; + } + + buffer[used++] = ' '; + if((width/2) - 1 == c) + buffer[used++] = ' '; + } + + buffer[used++] = ':'; + buffer[used++] = ' '; + + for(c = 0; (c < width) && (i + c < size); c++) { + buffer[used++] = isprint(ptr[i + c]) ? + ptr[i + c] : UNPRINTABLE_CHAR; + } + buffer[used++] = '\n'; + buffer[used] = 0; + + if(session->tracehandler) + (session->tracehandler)(session, session->tracehandler_context, + buffer, used); + else + fprintf(stderr, "%s", buffer); + } +} +#else +#define debugdump(a,x,y,z) +#endif + + +/* decrypt() decrypts 'len' bytes from 'source' to 'dest'. + * + * returns 0 on success and negative on failure + */ + +static int +decrypt(LIBSSH2_SESSION * session, unsigned char *source, + unsigned char *dest, int len) +{ + struct transportpacket *p = &session->packet; + int blocksize = session->remote.crypt->blocksize; + + /* if we get called with a len that isn't an even number of blocksizes + we risk losing those extra bytes */ + assert((len % blocksize) == 0); + + while(len >= blocksize) { + if(session->remote.crypt->crypt(session, source, blocksize, + &session->remote.crypt_abstract)) { + LIBSSH2_FREE(session, p->payload); + return LIBSSH2_ERROR_DECRYPT; + } + + /* if the crypt() function would write to a given address it + wouldn't have to memcpy() and we could avoid this memcpy() + too */ + memcpy(dest, source, blocksize); + + len -= blocksize; /* less bytes left */ + dest += blocksize; /* advance write pointer */ + source += blocksize; /* advance read pointer */ + } + return LIBSSH2_ERROR_NONE; /* all is fine */ +} + +/* + * fullpacket() gets called when a full packet has been received and properly + * collected. + */ +static int +fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ ) +{ + unsigned char macbuf[MAX_MACSIZE]; + struct transportpacket *p = &session->packet; + int rc; + int compressed; + + if(session->fullpacket_state == libssh2_NB_state_idle) { + session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED; + session->fullpacket_payload_len = p->packet_length - 1; + + if(encrypted) { + + /* Calculate MAC hash */ + session->remote.mac->hash(session, macbuf, /* store hash here */ + session->remote.seqno, + p->init, 5, + p->payload, + session->fullpacket_payload_len, + &session->remote.mac_abstract); + + /* Compare the calculated hash with the MAC we just read from + * the network. The read one is at the very end of the payload + * buffer. Note that 'payload_len' here is the packet_length + * field which includes the padding but not the MAC. + */ + if(memcmp(macbuf, p->payload + session->fullpacket_payload_len, + session->remote.mac->mac_len)) { + session->fullpacket_macstate = LIBSSH2_MAC_INVALID; + } + } + + session->remote.seqno++; + + /* ignore the padding */ + session->fullpacket_payload_len -= p->padding_length; + + /* Check for and deal with decompression */ + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if(compressed && session->remote.comp_abstract) { + /* + * The buffer for the decompression (remote.comp_abstract) is + * initialised in time when it is needed so as long it is NULL we + * cannot decompress. + */ + + unsigned char *data; + size_t data_len; + rc = session->remote.comp->decomp(session, + &data, &data_len, + LIBSSH2_PACKET_MAXDECOMP, + p->payload, + session->fullpacket_payload_len, + &session->remote.comp_abstract); + LIBSSH2_FREE(session, p->payload); + if(rc) + return rc; + + p->payload = data; + session->fullpacket_payload_len = data_len; + } + + session->fullpacket_packet_type = p->payload[0]; + + debugdump(session, "libssh2_transport_read() plain", + p->payload, session->fullpacket_payload_len); + + session->fullpacket_state = libssh2_NB_state_created; + } + + if(session->fullpacket_state == libssh2_NB_state_created) { + rc = _libssh2_packet_add(session, p->payload, + session->fullpacket_payload_len, + session->fullpacket_macstate); + if(rc == LIBSSH2_ERROR_EAGAIN) + return rc; + if(rc) { + session->fullpacket_state = libssh2_NB_state_idle; + return rc; + } + } + + session->fullpacket_state = libssh2_NB_state_idle; + + return session->fullpacket_packet_type; +} + + +/* + * _libssh2_transport_read + * + * Collect a packet into the input queue. + * + * Returns packet type added to input queue (0 if nothing added), or a + * negative error number. + */ + +/* + * This function reads the binary stream as specified in chapter 6 of RFC4253 + * "The Secure Shell (SSH) Transport Layer Protocol" + * + * DOES NOT call _libssh2_error() for ANY error case. + */ +int _libssh2_transport_read(LIBSSH2_SESSION * session) +{ + int rc; + struct transportpacket *p = &session->packet; + int remainbuf; + int remainpack; + int numbytes; + int numdecrypt; + unsigned char block[MAX_BLOCKSIZE]; + int blocksize; + int encrypted = 1; + + /* default clear the bit */ + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND; + + /* + * All channels, systems, subsystems, etc eventually make it down here + * when looking for more incoming data. If a key exchange is going on + * (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will + * ONLY send key exchange related traffic. In non-blocking mode, there is + * a chance to break out of the kex_exchange function with an EAGAIN + * status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is + * active, then we must redirect to the key exchange. However, if + * kex_exchange is active (as in it is the one that calls this execution + * of packet_read, then don't redirect, as that would be an infinite loop! + */ + + if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS && + !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { + + /* Whoever wants a packet won't get anything until the key re-exchange + * is done! + */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" + " key re-exchange from _libssh2_transport_read"); + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if(rc) + return rc; + } + + /* + * =============================== NOTE =============================== + * I know this is very ugly and not a really good use of "goto", but + * this case statement would be even uglier to do it any other way + */ + if(session->readPack_state == libssh2_NB_state_jump1) { + session->readPack_state = libssh2_NB_state_idle; + encrypted = session->readPack_encrypted; + goto libssh2_transport_read_point1; + } + + do { + if(session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) { + return LIBSSH2_ERROR_NONE; + } + + if(session->state & LIBSSH2_STATE_NEWKEYS) { + blocksize = session->remote.crypt->blocksize; + } + else { + encrypted = 0; /* not encrypted */ + blocksize = 5; /* not strictly true, but we can use 5 here to + make the checks below work fine still */ + } + + /* read/use a whole big chunk into a temporary area stored in + the LIBSSH2_SESSION struct. We will decrypt data from that + buffer into the packet buffer so this temp one doesn't have + to be able to keep a whole SSH packet, just be large enough + so that we can read big chunks from the network layer. */ + + /* how much data there is remaining in the buffer to deal with + before we should read more from the network */ + remainbuf = p->writeidx - p->readidx; + + /* if remainbuf turns negative we have a bad internal error */ + assert(remainbuf >= 0); + + if(remainbuf < blocksize) { + /* If we have less than a blocksize left, it is too + little data to deal with, read more */ + ssize_t nread; + + /* move any remainder to the start of the buffer so + that we can do a full refill */ + if(remainbuf) { + memmove(p->buf, &p->buf[p->readidx], remainbuf); + p->readidx = 0; + p->writeidx = remainbuf; + } + else { + /* nothing to move, just zero the indexes */ + p->readidx = p->writeidx = 0; + } + + /* now read a big chunk from the network into the temp buffer */ + nread = + LIBSSH2_RECV(session, &p->buf[remainbuf], + PACKETBUFSIZE - remainbuf, + LIBSSH2_SOCKET_RECV_FLAGS(session)); + if(nread <= 0) { + /* check if this is due to EAGAIN and return the special + return code if so, error out normally otherwise */ + if((nread < 0) && (nread == -EAGAIN)) { + session->socket_block_directions |= + LIBSSH2_SESSION_BLOCK_INBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error recving %d bytes (got %d)", + PACKETBUFSIZE - remainbuf, -nread); + return LIBSSH2_ERROR_SOCKET_RECV; + } + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Recved %d/%d bytes to %p+%d", nread, + PACKETBUFSIZE - remainbuf, p->buf, remainbuf); + + debugdump(session, "libssh2_transport_read() raw", + &p->buf[remainbuf], nread); + /* advance write pointer */ + p->writeidx += nread; + + /* update remainbuf counter */ + remainbuf = p->writeidx - p->readidx; + } + + /* how much data to deal with from the buffer */ + numbytes = remainbuf; + + if(!p->total_num) { + size_t total_num; + + /* No payload package area allocated yet. To know the + size of this payload, we need to decrypt the first + blocksize data. */ + + if(numbytes < blocksize) { + /* we can't act on anything less than blocksize, but this + check is only done for the initial block since once we have + got the start of a block we can in fact deal with fractions + */ + session->socket_block_directions |= + LIBSSH2_SESSION_BLOCK_INBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + + if(encrypted) { + rc = decrypt(session, &p->buf[p->readidx], block, blocksize); + if(rc != LIBSSH2_ERROR_NONE) { + return rc; + } + /* save the first 5 bytes of the decrypted package, to be + used in the hash calculation later down. */ + memcpy(p->init, block, 5); + } + else { + /* the data is plain, just copy it verbatim to + the working block buffer */ + memcpy(block, &p->buf[p->readidx], blocksize); + } + + /* advance the read pointer */ + p->readidx += blocksize; + + /* we now have the initial blocksize bytes decrypted, + * and we can extract packet and padding length from it + */ + p->packet_length = _libssh2_ntohu32(block); + if(p->packet_length < 1) { + return LIBSSH2_ERROR_DECRYPT; + } + else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + + p->padding_length = block[4]; + if(p->padding_length > p->packet_length - 1) { + return LIBSSH2_ERROR_DECRYPT; + } + + + /* total_num is the number of bytes following the initial + (5 bytes) packet length and padding length fields */ + total_num = + p->packet_length - 1 + + (encrypted ? session->remote.mac->mac_len : 0); + + /* RFC4253 section 6.1 Maximum Packet Length says: + * + * "All implementations MUST be able to process + * packets with uncompressed payload length of 32768 + * bytes or less and total packet size of 35000 bytes + * or less (including length, padding length, payload, + * padding, and MAC.)." + */ + if(total_num > LIBSSH2_PACKET_MAXPAYLOAD || total_num == 0) { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + + /* Get a packet handle put data into. We get one to + hold all data, including padding and MAC. */ + p->payload = LIBSSH2_ALLOC(session, total_num); + if(!p->payload) { + return LIBSSH2_ERROR_ALLOC; + } + p->total_num = total_num; + /* init write pointer to start of payload buffer */ + p->wptr = p->payload; + + if(blocksize > 5) { + /* copy the data from index 5 to the end of + the blocksize from the temporary buffer to + the start of the decrypted buffer */ + if(blocksize - 5 <= (int) total_num) { + memcpy(p->wptr, &block[5], blocksize - 5); + p->wptr += blocksize - 5; /* advance write pointer */ + } + else { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + } + + /* init the data_num field to the number of bytes of + the package read so far */ + p->data_num = p->wptr - p->payload; + + /* we already dealt with a blocksize worth of data */ + numbytes -= blocksize; + } + + /* how much there is left to add to the current payload + package */ + remainpack = p->total_num - p->data_num; + + if(numbytes > remainpack) { + /* if we have more data in the buffer than what is going into this + particular packet, we limit this round to this packet only */ + numbytes = remainpack; + } + + if(encrypted) { + /* At the end of the incoming stream, there is a MAC, + and we don't want to decrypt that since we need it + "raw". We MUST however decrypt the padding data + since it is used for the hash later on. */ + int skip = session->remote.mac->mac_len; + + /* if what we have plus numbytes is bigger than the + total minus the skip margin, we should lower the + amount to decrypt even more */ + if((p->data_num + numbytes) > (p->total_num - skip)) { + numdecrypt = (p->total_num - skip) - p->data_num; + } + else { + int frac; + numdecrypt = numbytes; + frac = numdecrypt % blocksize; + if(frac) { + /* not an aligned amount of blocks, + align it */ + numdecrypt -= frac; + /* and make it no unencrypted data + after it */ + numbytes = 0; + } + } + } + else { + /* unencrypted data should not be decrypted at all */ + numdecrypt = 0; + } + + /* if there are bytes to decrypt, do that */ + if(numdecrypt > 0) { + /* now decrypt the lot */ + rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt); + if(rc != LIBSSH2_ERROR_NONE) { + p->total_num = 0; /* no packet buffer available */ + return rc; + } + + /* advance the read pointer */ + p->readidx += numdecrypt; + /* advance write pointer */ + p->wptr += numdecrypt; + /* increase data_num */ + p->data_num += numdecrypt; + + /* bytes left to take care of without decryption */ + numbytes -= numdecrypt; + } + + /* if there are bytes to copy that aren't decrypted, simply + copy them as-is to the target buffer */ + if(numbytes > 0) { + + if(numbytes <= (int)(p->total_num - (p->wptr - p->payload))) { + memcpy(p->wptr, &p->buf[p->readidx], numbytes); + } + else { + return LIBSSH2_ERROR_OUT_OF_BOUNDARY; + } + + /* advance the read pointer */ + p->readidx += numbytes; + /* advance write pointer */ + p->wptr += numbytes; + /* increase data_num */ + p->data_num += numbytes; + } + + /* now check how much data there's left to read to finish the + current packet */ + remainpack = p->total_num - p->data_num; + + if(!remainpack) { + /* we have a full packet */ + libssh2_transport_read_point1: + rc = fullpacket(session, encrypted); + if(rc == LIBSSH2_ERROR_EAGAIN) { + + if(session->packAdd_state != libssh2_NB_state_idle) { + /* fullpacket only returns LIBSSH2_ERROR_EAGAIN if + * libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If + * that returns LIBSSH2_ERROR_EAGAIN but the packAdd_state + * is idle, then the packet has been added to the brigade, + * but some immediate action that was taken based on the + * packet type (such as key re-exchange) is not yet + * complete. Clear the way for a new packet to be read + * in. + */ + session->readPack_encrypted = encrypted; + session->readPack_state = libssh2_NB_state_jump1; + } + + return rc; + } + + p->total_num = 0; /* no packet buffer available */ + + return rc; + } + } while(1); /* loop */ + + return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */ +} + +static int +send_existing(LIBSSH2_SESSION *session, const unsigned char *data, + size_t data_len, ssize_t *ret) +{ + ssize_t rc; + ssize_t length; + struct transportpacket *p = &session->packet; + + if(!p->olen) { + *ret = 0; + return LIBSSH2_ERROR_NONE; + } + + /* send as much as possible of the existing packet */ + if((data != p->odata) || (data_len != p->olen)) { + /* When we are about to complete the sending of a packet, it is vital + that the caller doesn't try to send a new/different packet since + we don't add this one up until the previous one has been sent. To + make the caller really notice his/hers flaw, we return error for + this case */ + return LIBSSH2_ERROR_BAD_USE; + } + + *ret = 1; /* set to make our parent return */ + + /* number of bytes left to send */ + length = p->ototal_num - p->osent; + + rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if(rc < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", length, -rc); + else { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Sent %d/%d bytes at %p+%d", rc, length, p->outbuf, + p->osent); + debugdump(session, "libssh2_transport_write send()", + &p->outbuf[p->osent], rc); + } + + if(rc == length) { + /* the remainder of the package was sent */ + p->ototal_num = 0; + p->olen = 0; + /* we leave *ret set so that the parent returns as we MUST return back + a send success now, so that we don't risk sending EAGAIN later + which then would confuse the parent function */ + return LIBSSH2_ERROR_NONE; + + } + else if(rc < 0) { + /* nothing was sent */ + if(rc != -EAGAIN) + /* send failure! */ + return LIBSSH2_ERROR_SOCKET_SEND; + + session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; + return LIBSSH2_ERROR_EAGAIN; + } + + p->osent += rc; /* we sent away this much data */ + + return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE; +} + +/* + * libssh2_transport_send + * + * Send a packet, encrypting it and adding a MAC code if necessary + * Returns 0 on success, non-zero on failure. + * + * The data is provided as _two_ data areas that are combined by this + * function. The 'data' part is sent immediately before 'data2'. 'data2' may + * be set to NULL to only use a single part. + * + * Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was + * not sent yet. If it does so, the caller should call this function again as + * soon as it is likely that more data can be sent, and this function MUST + * then be called with the same argument set (same data pointer and same + * data_len) until ERROR_NONE or failure is returned. + * + * This function DOES NOT call _libssh2_error() on any errors. + */ +int _libssh2_transport_send(LIBSSH2_SESSION *session, + const unsigned char *data, size_t data_len, + const unsigned char *data2, size_t data2_len) +{ + int blocksize = + (session->state & LIBSSH2_STATE_NEWKEYS) ? + session->local.crypt->blocksize : 8; + int padding_length; + size_t packet_length; + int total_length; +#ifdef RANDOM_PADDING + int rand_max; + int seed = data[0]; /* FIXME: make this random */ +#endif + struct transportpacket *p = &session->packet; + int encrypted; + int compressed; + ssize_t ret; + int rc; + const unsigned char *orgdata = data; + size_t orgdata_len = data_len; + + /* + * If the last read operation was interrupted in the middle of a key + * exchange, we must complete that key exchange before continuing to write + * further data. + * + * See the similar block in _libssh2_transport_read for more details. + */ + if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS && + !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) { + /* Don't write any new packets if we're still in the middle of a key + * exchange. */ + _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the" + " key re-exchange from _libssh2_transport_send"); + rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state); + if(rc) + return rc; + } + + debugdump(session, "libssh2_transport_write plain", data, data_len); + if(data2) + debugdump(session, "libssh2_transport_write plain2", data2, data2_len); + + /* FIRST, check if we have a pending write to complete. send_existing + only sanity-check data and data_len and not data2 and data2_len!! */ + rc = send_existing(session, data, data_len, &ret); + if(rc) + return rc; + + session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND; + + if(ret) + /* set by send_existing if data was sent */ + return rc; + + encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0; + + compressed = + session->local.comp != NULL && + session->local.comp->compress && + ((session->state & LIBSSH2_STATE_AUTHENTICATED) || + session->local.comp->use_in_auth); + + if(encrypted && compressed && session->local.comp_abstract) { + /* the idea here is that these function must fail if the output gets + larger than what fits in the assigned buffer so thus they don't + check the input size as we don't know how much it compresses */ + size_t dest_len = MAX_SSH_PACKET_LEN-5-256; + size_t dest2_len = dest_len; + + /* compress directly to the target buffer */ + rc = session->local.comp->comp(session, + &p->outbuf[5], &dest_len, + data, data_len, + &session->local.comp_abstract); + if(rc) + return rc; /* compression failure */ + + if(data2 && data2_len) { + /* compress directly to the target buffer right after where the + previous call put data */ + dest2_len -= dest_len; + + rc = session->local.comp->comp(session, + &p->outbuf[5 + dest_len], + &dest2_len, + data2, data2_len, + &session->local.comp_abstract); + } + else + dest2_len = 0; + if(rc) + return rc; /* compression failure */ + + data_len = dest_len + dest2_len; /* use the combined length */ + } + else { + if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100)) + /* too large packet, return error for this until we make this + function split it up and send multiple SSH packets */ + return LIBSSH2_ERROR_INVAL; + + /* copy the payload data */ + memcpy(&p->outbuf[5], data, data_len); + if(data2 && data2_len) + memcpy(&p->outbuf[5 + data_len], data2, data2_len); + data_len += data2_len; /* use the combined length */ + } + + + /* RFC4253 says: Note that the length of the concatenation of + 'packet_length', 'padding_length', 'payload', and 'random padding' + MUST be a multiple of the cipher block size or 8, whichever is + larger. */ + + /* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */ + + packet_length = data_len + 1 + 4; /* 1 is for padding_length field + 4 for the packet_length field */ + + /* at this point we have it all except the padding */ + + /* first figure out our minimum padding amount to make it an even + block size */ + padding_length = blocksize - (packet_length % blocksize); + + /* if the padding becomes too small we add another blocksize worth + of it (taken from the original libssh2 where it didn't have any + real explanation) */ + if(padding_length < 4) { + padding_length += blocksize; + } +#ifdef RANDOM_PADDING + /* FIXME: we can add padding here, but that also makes the packets + bigger etc */ + + /* now we can add 'blocksize' to the padding_length N number of times + (to "help thwart traffic analysis") but it must be less than 255 in + total */ + rand_max = (255 - padding_length) / blocksize + 1; + padding_length += blocksize * (seed % rand_max); +#endif + + packet_length += padding_length; + + /* append the MAC length to the total_length size */ + total_length = + packet_length + (encrypted ? session->local.mac->mac_len : 0); + + /* store packet_length, which is the size of the whole packet except + the MAC and the packet_length field itself */ + _libssh2_htonu32(p->outbuf, packet_length - 4); + /* store padding_length */ + p->outbuf[4] = (unsigned char)padding_length; + + /* fill the padding area with random junk */ + _libssh2_random(p->outbuf + 5 + data_len, padding_length); + + if(encrypted) { + size_t i; + + /* Calculate MAC hash. Put the output at index packet_length, + since that size includes the whole packet. The MAC is + calculated on the entire unencrypted packet, including all + fields except the MAC field itself. */ + session->local.mac->hash(session, p->outbuf + packet_length, + session->local.seqno, p->outbuf, + packet_length, NULL, 0, + &session->local.mac_abstract); + + /* Encrypt the whole packet data, one block size at a time. + The MAC field is not encrypted. */ + for(i = 0; i < packet_length; i += session->local.crypt->blocksize) { + unsigned char *ptr = &p->outbuf[i]; + if(session->local.crypt->crypt(session, ptr, + session->local.crypt->blocksize, + &session->local.crypt_abstract)) + return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */ + } + } + + session->local.seqno++; + + ret = LIBSSH2_SEND(session, p->outbuf, total_length, + LIBSSH2_SOCKET_SEND_FLAGS(session)); + if(ret < 0) + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, + "Error sending %d bytes: %d", total_length, -ret); + else { + _libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p", + ret, total_length, p->outbuf); + debugdump(session, "libssh2_transport_write send()", p->outbuf, ret); + } + + if(ret != total_length) { + if(ret >= 0 || ret == -EAGAIN) { + /* the whole packet could not be sent, save the rest */ + session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND; + p->odata = orgdata; + p->olen = orgdata_len; + p->osent = ret <= 0 ? 0 : ret; + p->ototal_num = total_length; + return LIBSSH2_ERROR_EAGAIN; + } + return LIBSSH2_ERROR_SOCKET_SEND; + } + + /* the whole thing got sent away */ + p->odata = NULL; + p->olen = 0; + + return LIBSSH2_ERROR_NONE; /* all is good */ +} diff --git a/libssh2/userauth.c b/libssh2/userauth.c new file mode 100644 index 0000000..d5dbaa4 --- /dev/null +++ b/libssh2/userauth.c @@ -0,0 +1,2110 @@ +/* Copyright (c) 2004-2007, Sara Golemon + * Copyright (c) 2005 Mikhail Gusarov + * Copyright (c) 2009-2014 by Daniel Stenberg + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#include +#include + +#include + +/* Needed for struct iovec on some platforms */ +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#include "transport.h" +#include "session.h" +#include "userauth.h" + +/* libssh2_userauth_list + * + * List authentication methods + * Will yield successful login if "none" happens to be allowable for this user + * Not a common configuration for any SSH server though + * username should be NULL, or a null terminated string + */ +static char *userauth_list(LIBSSH2_SESSION *session, const char *username, + unsigned int username_len) +{ + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + /* packet_type(1) + username_len(4) + service_len(4) + + service(14)"ssh-connection" + method_len(4) = 27 */ + unsigned long methods_len; + unsigned char *s; + int rc; + + if(session->userauth_list_state == libssh2_NB_state_idle) { + /* Zero the whole thing out */ + memset(&session->userauth_list_packet_requirev_state, 0, + sizeof(session->userauth_list_packet_requirev_state)); + + session->userauth_list_data_len = username_len + 27; + + s = session->userauth_list_data = + LIBSSH2_ALLOC(session, session->userauth_list_data_len); + if(!session->userauth_list_data) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for userauth_list"); + return NULL; + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", 14); + _libssh2_store_u32(&s, 4); /* send "none" separately */ + + session->userauth_list_state = libssh2_NB_state_created; + } + + if(session->userauth_list_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_list_data, + session->userauth_list_data_len, + (unsigned char *)"none", 4); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + return NULL; + } + /* now free the packet that was sent */ + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + + if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-none request"); + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + session->userauth_list_state = libssh2_NB_state_sent; + } + + if(session->userauth_list_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_list_data, + &session->userauth_list_data_len, 0, + NULL, 0, + &session->userauth_list_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + return NULL; + } + else if(rc || (session->userauth_list_data_len < 1)) { + _libssh2_error(session, rc, "Failed getting response"); + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + if(session->userauth_list_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + /* Wow, who'dve thought... */ + _libssh2_error(session, LIBSSH2_ERROR_NONE, "No error"); + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_list_state = libssh2_NB_state_idle; + return NULL; + } + + if(session->userauth_list_data_len < 5) { + LIBSSH2_FREE(session, session->userauth_list_data); + session->userauth_list_data = NULL; + _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet size"); + return NULL; + } + + methods_len = _libssh2_ntohu32(session->userauth_list_data + 1); + if(methods_len >= session->userauth_list_data_len - 5) { + _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, + "Unexpected userauth list size"); + return NULL; + } + + /* Do note that the memory areas overlap! */ + memmove(session->userauth_list_data, session->userauth_list_data + 5, + methods_len); + session->userauth_list_data[methods_len] = '\0'; + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Permitted auth methods: %s", + session->userauth_list_data); + } + + session->userauth_list_state = libssh2_NB_state_idle; + return (char *) session->userauth_list_data; +} + +/* libssh2_userauth_list + * + * List authentication methods + * Will yield successful login if "none" happens to be allowable for this user + * Not a common configuration for any SSH server though + * username should be NULL, or a null terminated string + */ +LIBSSH2_API char * +libssh2_userauth_list(LIBSSH2_SESSION * session, const char *user, + unsigned int user_len) +{ + char *ptr; + BLOCK_ADJUST_ERRNO(ptr, session, + userauth_list(session, user, user_len)); + return ptr; +} + +/* + * libssh2_userauth_authenticated + * + * Returns: 0 if not yet authenticated + * 1 if already authenticated + */ +LIBSSH2_API int +libssh2_userauth_authenticated(LIBSSH2_SESSION * session) +{ + return (session->state & LIBSSH2_STATE_AUTHENTICATED)?1:0; +} + + + +/* userauth_password + * Plain ol' login + */ +static int +userauth_password(LIBSSH2_SESSION *session, + const char *username, unsigned int username_len, + const unsigned char *password, unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC((*passwd_change_cb))) +{ + unsigned char *s; + static const unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ, 0 + }; + int rc; + + if(session->userauth_pswd_state == libssh2_NB_state_idle) { + /* Zero the whole thing out */ + memset(&session->userauth_pswd_packet_requirev_state, 0, + sizeof(session->userauth_pswd_packet_requirev_state)); + + /* + * 40 = packet_type(1) + username_len(4) + service_len(4) + + * service(14)"ssh-connection" + method_len(4) + method(8)"password" + + * chgpwdbool(1) + password_len(4) */ + session->userauth_pswd_data_len = username_len + 40; + + session->userauth_pswd_data0 = + (unsigned char) ~SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; + + /* TODO: remove this alloc with a fixed buffer in the session + struct */ + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, session->userauth_pswd_data_len); + if(!session->userauth_pswd_data) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "userauth-password request"); + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); + _libssh2_store_str(&s, "password", sizeof("password") - 1); + *s++ = '\0'; + _libssh2_store_u32(&s, password_len); + /* 'password' is sent separately */ + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting to login using password authentication"); + + session->userauth_pswd_state = libssh2_NB_state_created; + } + + if(session->userauth_pswd_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_pswd_data, + session->userauth_pswd_data_len, + password, password_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block writing password request"); + } + + /* now free the sent packet */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + + if(rc) { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-password request"); + } + + session->userauth_pswd_state = libssh2_NB_state_sent; + } + + password_response: + + if((session->userauth_pswd_state == libssh2_NB_state_sent) + || (session->userauth_pswd_state == libssh2_NB_state_sent1) + || (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + if(session->userauth_pswd_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pswd_data, + &session->userauth_pswd_data_len, + 0, NULL, 0, + &session-> + userauth_pswd_packet_requirev_state); + + if(rc) { + if(rc != LIBSSH2_ERROR_EAGAIN) + session->userauth_pswd_state = libssh2_NB_state_idle; + + return _libssh2_error(session, rc, + "Waiting for password response"); + } + else if(session->userauth_pswd_data_len < 1) { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet size"); + } + + if(session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password authentication successful"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pswd_state = libssh2_NB_state_idle; + return 0; + } + else if(session->userauth_pswd_data[0] == + SSH_MSG_USERAUTH_FAILURE) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password authentication failed"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed " + "(username/password)"); + } + + session->userauth_pswd_newpw = NULL; + session->userauth_pswd_newpw_len = 0; + + session->userauth_pswd_state = libssh2_NB_state_sent1; + } + + if(session->userauth_pswd_data_len < 1) { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PROTO, + "Unexpected packet size"); + } + + if((session->userauth_pswd_data[0] == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) + || (session->userauth_pswd_data0 == + SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)) { + session->userauth_pswd_data0 = SSH_MSG_USERAUTH_PASSWD_CHANGEREQ; + + if((session->userauth_pswd_state == libssh2_NB_state_sent1) || + (session->userauth_pswd_state == libssh2_NB_state_sent2)) { + if(session->userauth_pswd_state == libssh2_NB_state_sent1) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Password change required"); + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + } + if(passwd_change_cb) { + if(session->userauth_pswd_state == + libssh2_NB_state_sent1) { + passwd_change_cb(session, + &session->userauth_pswd_newpw, + &session->userauth_pswd_newpw_len, + &session->abstract); + if(!session->userauth_pswd_newpw) { + return _libssh2_error(session, + LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password expired, and " + "callback failed"); + } + + /* basic data_len + newpw_len(4) */ + if(username_len + password_len + 44 <= UINT_MAX) { + session->userauth_pswd_data_len = + username_len + password_len + 44; + s = session->userauth_pswd_data = + LIBSSH2_ALLOC(session, + session->userauth_pswd_data_len); + } + else { + s = session->userauth_pswd_data = NULL; + session->userauth_pswd_data_len = 0; + } + + if(!session->userauth_pswd_data) { + LIBSSH2_FREE(session, + session->userauth_pswd_newpw); + session->userauth_pswd_newpw = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for userauth password " + "change request"); + } + + *(s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", + sizeof("ssh-connection") - 1); + _libssh2_store_str(&s, "password", + sizeof("password") - 1); + *s++ = 0x01; + _libssh2_store_str(&s, (char *)password, password_len); + _libssh2_store_u32(&s, + session->userauth_pswd_newpw_len); + /* send session->userauth_pswd_newpw separately */ + + session->userauth_pswd_state = libssh2_NB_state_sent2; + } + + if(session->userauth_pswd_state == + libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, + session->userauth_pswd_data, + session->userauth_pswd_data_len, + (unsigned char *) + session->userauth_pswd_newpw, + session->userauth_pswd_newpw_len); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, + LIBSSH2_ERROR_EAGAIN, + "Would block waiting"); + } + + /* free the allocated packets again */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + LIBSSH2_FREE(session, session->userauth_pswd_newpw); + session->userauth_pswd_newpw = NULL; + + if(rc) { + return _libssh2_error(session, + LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth " + "password-change request"); + } + + /* + * Ugliest use of goto ever. Blame it on the + * askN => requirev migration. + */ + session->userauth_pswd_state = libssh2_NB_state_sent; + goto password_response; + } + } + } + else { + session->userauth_pswd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PASSWORD_EXPIRED, + "Password Expired, and no callback " + "specified"); + } + } + } + + /* FAILURE */ + LIBSSH2_FREE(session, session->userauth_pswd_data); + session->userauth_pswd_data = NULL; + session->userauth_pswd_state = libssh2_NB_state_idle; + + return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed"); +} + +/* + * libssh2_userauth_password_ex + * + * Plain ol' login + */ + +LIBSSH2_API int +libssh2_userauth_password_ex(LIBSSH2_SESSION *session, const char *username, + unsigned int username_len, const char *password, + unsigned int password_len, + LIBSSH2_PASSWD_CHANGEREQ_FUNC + ((*passwd_change_cb))) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_password(session, username, username_len, + (unsigned char *)password, password_len, + passwd_change_cb)); + return rc; +} + +static int +memory_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *pubkeyfiledata, + size_t pubkeyfiledata_len) +{ + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = pubkeyfiledata_len; + unsigned int tmp_len; + + if(pubkeyfiledata_len <= 1) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public key file"); + } + + pubkey = LIBSSH2_ALLOC(session, pubkeyfiledata_len); + if(!pubkey) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key data"); + } + + memcpy(pubkey, pubkeyfiledata, pubkeyfiledata_len); + + /* + * Remove trailing whitespace + */ + while(pubkey_len && isspace(pubkey[pubkey_len - 1])) + pubkey_len--; + + if(!pubkey_len) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Missing public key data"); + } + + sp1 = memchr(pubkey, ' ', pubkey_len); + if(sp1 == NULL) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid public key data"); + } + + sp1++; + + sp2 = memchr(sp1, ' ', pubkey_len - (sp1 - pubkey)); + if(sp2 == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } + + if(libssh2_base64_decode(session, (char **) &tmp, &tmp_len, + (char *) sp1, sp2 - sp1)) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid key data, not base64 encoded"); + } + + /* Wasting some bytes here (okay, more than some), but since it's likely + * to be freed soon anyway, we'll just avoid the extra free/alloc and call + * it a wash + */ + *method = pubkey; + *method_len = sp1 - pubkey - 1; + + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; + + return 0; +} + +/* + * file_read_publickey + * + * Read a public key from an id_???.pub style file + * + * Returns an allocated string containing the decoded key in *pubkeydata + * on success. + * Returns an allocated string containing the key method (e.g. "ssh-dss") + * in method on success. + */ +static int +file_read_publickey(LIBSSH2_SESSION * session, unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *pubkeyfile) +{ + FILE *fd; + char c; + unsigned char *pubkey = NULL, *sp1, *sp2, *tmp; + size_t pubkey_len = 0, sp_len; + unsigned int tmp_len; + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading public key file: %s", + pubkeyfile); + /* Read Public Key */ + fd = fopen(pubkeyfile, FOPEN_READTEXT); + if(!fd) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to open public key file"); + } + while(!feof(fd) && 1 == fread(&c, 1, 1, fd) && c != '\r' && c != '\n') { + pubkey_len++; + } + rewind(fd); + + if(pubkey_len <= 1) { + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public key file"); + } + + pubkey = LIBSSH2_ALLOC(session, pubkey_len); + if(!pubkey) { + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for public key data"); + } + if(fread(pubkey, 1, pubkey_len, fd) != pubkey_len) { + LIBSSH2_FREE(session, pubkey); + fclose(fd); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to read public key from file"); + } + fclose(fd); + /* + * Remove trailing whitespace + */ + while(pubkey_len && isspace(pubkey[pubkey_len - 1])) { + pubkey_len--; + } + + if(!pubkey_len) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Missing public key data"); + } + + sp1 = memchr(pubkey, ' ', pubkey_len); + if(sp1 == NULL) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid public key data"); + } + + sp1++; + + sp_len = sp1 > pubkey ? (sp1 - pubkey) : 0; + sp2 = memchr(sp1, ' ', pubkey_len - sp_len); + if(sp2 == NULL) { + /* Assume that the id string is missing, but that it's okay */ + sp2 = pubkey + pubkey_len; + } + + if(libssh2_base64_decode(session, (char **) &tmp, &tmp_len, + (char *) sp1, sp2 - sp1)) { + LIBSSH2_FREE(session, pubkey); + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid key data, not base64 encoded"); + } + + /* Wasting some bytes here (okay, more than some), but since it's likely + * to be freed soon anyway, we'll just avoid the extra free/alloc and call + * it a wash */ + *method = pubkey; + *method_len = sp1 - pubkey - 1; + + *pubkeydata = tmp; + *pubkeydata_len = tmp_len; + + return 0; +} + +static int +memory_read_privatekey(LIBSSH2_SESSION * session, + const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, + void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfiledata, size_t privkeyfiledata_len, + const char *passphrase) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = + libssh2_hostkey_methods(); + + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while(*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if((*hostkey_methods_avail)->initPEMFromMemory + && strncmp((*hostkey_methods_avail)->name, (const char *) method, + method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if(!*hostkey_method) { + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key"); + } + + if((*hostkey_method)-> + initPEMFromMemory(session, privkeyfiledata, privkeyfiledata_len, + (unsigned char *) passphrase, + hostkey_abstract)) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file"); + } + + return 0; +} + +/* libssh2_file_read_privatekey + * Read a PEM encoded private key from an id_??? style file + */ +static int +file_read_privatekey(LIBSSH2_SESSION * session, + const LIBSSH2_HOSTKEY_METHOD ** hostkey_method, + void **hostkey_abstract, + const unsigned char *method, int method_len, + const char *privkeyfile, const char *passphrase) +{ + const LIBSSH2_HOSTKEY_METHOD **hostkey_methods_avail = + libssh2_hostkey_methods(); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, "Loading private key file: %s", + privkeyfile); + *hostkey_method = NULL; + *hostkey_abstract = NULL; + while(*hostkey_methods_avail && (*hostkey_methods_avail)->name) { + if((*hostkey_methods_avail)->initPEM + && strncmp((*hostkey_methods_avail)->name, (const char *) method, + method_len) == 0) { + *hostkey_method = *hostkey_methods_avail; + break; + } + hostkey_methods_avail++; + } + if(!*hostkey_method) { + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NONE, + "No handler for specified private key"); + } + + if((*hostkey_method)-> + initPEM(session, privkeyfile, (unsigned char *) passphrase, + hostkey_abstract)) { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to initialize private key from file"); + } + + return 0; +} + +struct privkey_file { + const char *filename; + const char *passphrase; +}; + +static int +sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + struct privkey_file *pk_file = (struct privkey_file *) (*abstract); + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *hostkey_abstract; + struct iovec datavec; + int rc; + + rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract, + session->userauth_pblc_method, + session->userauth_pblc_method_len, + pk_file->filename, + strlen(pk_file->filename), + pk_file->passphrase); + if(rc) + return rc; + + libssh2_prepare_iovec(&datavec, 1); + datavec.iov_base = (void *)data; + datavec.iov_len = data_len; + + if(privkeyobj->signv(session, sig, sig_len, 1, &datavec, + &hostkey_abstract)) { + if(privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return -1; + } + + if(privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return 0; +} + +static int +sign_fromfile(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, + const unsigned char *data, size_t data_len, void **abstract) +{ + struct privkey_file *privkey_file = (struct privkey_file *) (*abstract); + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + void *hostkey_abstract; + struct iovec datavec; + int rc; + + rc = file_read_privatekey(session, &privkeyobj, &hostkey_abstract, + session->userauth_pblc_method, + session->userauth_pblc_method_len, + privkey_file->filename, + privkey_file->passphrase); + if(rc) + return rc; + + libssh2_prepare_iovec(&datavec, 1); + datavec.iov_base = (void *)data; + datavec.iov_len = data_len; + + if(privkeyobj->signv(session, sig, sig_len, 1, &datavec, + &hostkey_abstract)) { + if(privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return -1; + } + + if(privkeyobj->dtor) { + privkeyobj->dtor(session, &hostkey_abstract); + } + return 0; +} + + + +/* userauth_hostbased_fromfile + * Authenticate using a keypair found in the named files + */ +static int +userauth_hostbased_fromfile(LIBSSH2_SESSION *session, + const char *username, size_t username_len, + const char *publickey, const char *privatekey, + const char *passphrase, const char *hostname, + size_t hostname_len, + const char *local_username, + size_t local_username_len) +{ + int rc; + +#if !LIBSSH2_RSA + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "RSA is not supported by crypto backend"); +#endif + + if(session->userauth_host_state == libssh2_NB_state_idle) { + const LIBSSH2_HOSTKEY_METHOD *privkeyobj; + unsigned char *pubkeydata = NULL; + unsigned char *sig = NULL; + size_t pubkeydata_len = 0; + size_t sig_len = 0; + void *abstract; + unsigned char buf[5]; + struct iovec datavec[4]; + + /* Zero the whole thing out */ + memset(&session->userauth_host_packet_requirev_state, 0, + sizeof(session->userauth_host_packet_requirev_state)); + + if(publickey) { + rc = file_read_publickey(session, &session->userauth_host_method, + &session->userauth_host_method_len, + &pubkeydata, &pubkeydata_len, publickey); + if(rc) + /* Note: file_read_publickey() calls _libssh2_error() */ + return rc; + } + else { + /* Compute public key from private key. */ + rc = _libssh2_pub_priv_keyfile(session, + &session->userauth_host_method, + &session->userauth_host_method_len, + &pubkeydata, &pubkeydata_len, + privatekey, passphrase); + if(rc) + /* libssh2_pub_priv_keyfile calls _libssh2_error() */ + return rc; + } + + /* + * 52 = packet_type(1) + username_len(4) + servicename_len(4) + + * service_name(14)"ssh-connection" + authmethod_len(4) + + * authmethod(9)"hostbased" + method_len(4) + pubkeydata_len(4) + + * hostname_len(4) + local_username_len(4) + */ + session->userauth_host_packet_len = + username_len + session->userauth_host_method_len + hostname_len + + local_username_len + pubkeydata_len + 52; + + /* + * Preallocate space for an overall length, method name again, + * and the signature, which won't be any larger than the size of + * the publickeydata itself + */ + session->userauth_host_s = session->userauth_host_packet = + LIBSSH2_ALLOC(session, + session->userauth_host_packet_len + 4 + + (4 + session->userauth_host_method_len) + + (4 + pubkeydata_len)); + if(!session->userauth_host_packet) { + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, pubkeydata); + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory"); + } + + *(session->userauth_host_s++) = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&session->userauth_host_s, username, username_len); + _libssh2_store_str(&session->userauth_host_s, "ssh-connection", 14); + _libssh2_store_str(&session->userauth_host_s, "hostbased", 9); + _libssh2_store_str(&session->userauth_host_s, + (const char *)session->userauth_host_method, + session->userauth_host_method_len); + _libssh2_store_str(&session->userauth_host_s, (const char *)pubkeydata, + pubkeydata_len); + LIBSSH2_FREE(session, pubkeydata); + _libssh2_store_str(&session->userauth_host_s, hostname, hostname_len); + _libssh2_store_str(&session->userauth_host_s, local_username, + local_username_len); + + rc = file_read_privatekey(session, &privkeyobj, &abstract, + session->userauth_host_method, + session->userauth_host_method_len, + privatekey, passphrase); + if(rc) { + /* Note: file_read_privatekey() calls _libssh2_error() */ + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + return rc; + } + + _libssh2_htonu32(buf, session->session_id_len); + libssh2_prepare_iovec(datavec, 4); + datavec[0].iov_base = (void *)buf; + datavec[0].iov_len = 4; + datavec[1].iov_base = (void *)session->session_id; + datavec[1].iov_len = session->session_id_len; + datavec[2].iov_base = (void *)session->userauth_host_packet; + datavec[2].iov_len = session->userauth_host_packet_len; + + if(privkeyobj && privkeyobj->signv && + privkeyobj->signv(session, &sig, &sig_len, 3, + datavec, &abstract)) { + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + if(privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + return -1; + } + + if(privkeyobj && privkeyobj->dtor) { + privkeyobj->dtor(session, &abstract); + } + + if(sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, session->userauth_host_packet, + session->userauth_host_packet_len + 4 + + (4 + session->userauth_host_method_len) + + (4 + sig_len)); /* PK sigblob */ + if(!newpacket) { + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for " + "userauth-hostbased packet"); + } + session->userauth_host_packet = newpacket; + } + + session->userauth_host_s = + session->userauth_host_packet + session->userauth_host_packet_len; + + _libssh2_store_u32(&session->userauth_host_s, + 4 + session->userauth_host_method_len + + 4 + sig_len); + _libssh2_store_str(&session->userauth_host_s, + (const char *)session->userauth_host_method, + session->userauth_host_method_len); + LIBSSH2_FREE(session, session->userauth_host_method); + session->userauth_host_method = NULL; + + _libssh2_store_str(&session->userauth_host_s, (const char *)sig, + sig_len); + LIBSSH2_FREE(session, sig); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting hostbased authentication"); + + session->userauth_host_state = libssh2_NB_state_created; + } + + if(session->userauth_host_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_host_packet, + session->userauth_host_s - + session->userauth_host_packet, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + else if(rc) { + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + session->userauth_host_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-hostbased request"); + } + LIBSSH2_FREE(session, session->userauth_host_packet); + session->userauth_host_packet = NULL; + + session->userauth_host_state = libssh2_NB_state_sent; + } + + if(session->userauth_host_state == libssh2_NB_state_sent) { + static const unsigned char reply_codes[3] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, 0 }; + size_t data_len; + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_host_data, + &data_len, 0, NULL, 0, + &session-> + userauth_host_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + + session->userauth_host_state = libssh2_NB_state_idle; + if(rc || data_len < 1) { + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Auth failed"); + } + + if(session->userauth_host_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Hostbased authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, session->userauth_host_data); + session->userauth_host_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + return 0; + } + } + + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_host_data); + session->userauth_host_data = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid signature for supplied public key, or bad " + "username/public key combination"); +} + +/* libssh2_userauth_hostbased_fromfile_ex + * Authenticate using a keypair found in the named files + */ +LIBSSH2_API int +libssh2_userauth_hostbased_fromfile_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + const char *publickey, + const char *privatekey, + const char *passphrase, + const char *host, + unsigned int host_len, + const char *localuser, + unsigned int localuser_len) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_hostbased_fromfile(session, user, user_len, + publickey, privatekey, + passphrase, host, host_len, + localuser, localuser_len)); + return rc; +} + + + +int +_libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *username, + unsigned int username_len, + const unsigned char *pubkeydata, + unsigned long pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC + ((*sign_callback)), + void *abstract) +{ + unsigned char reply_codes[4] = + { SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, + SSH_MSG_USERAUTH_PK_OK, 0 + }; + int rc; + unsigned char *s; + + if(session->userauth_pblc_state == libssh2_NB_state_idle) { + + /* + * The call to _libssh2_ntohu32 later relies on pubkeydata having at + * least 4 valid bytes containing the length of the method name. + */ + if(pubkeydata_len < 4) + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key, too short"); + + /* Zero the whole thing out */ + memset(&session->userauth_pblc_packet_requirev_state, 0, + sizeof(session->userauth_pblc_packet_requirev_state)); + + /* + * As an optimisation, userauth_publickey_fromfile reuses a + * previously allocated copy of the method name to avoid an extra + * allocation/free. + * For other uses, we allocate and populate it here. + */ + if(!session->userauth_pblc_method) { + session->userauth_pblc_method_len = _libssh2_ntohu32(pubkeydata); + + if(session->userauth_pblc_method_len > pubkeydata_len - 4) + /* the method length simply cannot be longer than the entire + passed in data, so we use this to detect crazy input + data */ + return _libssh2_error(session, + LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key"); + + session->userauth_pblc_method = + LIBSSH2_ALLOC(session, session->userauth_pblc_method_len); + if(!session->userauth_pblc_method) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory " + "for public key data"); + } + memcpy(session->userauth_pblc_method, pubkeydata + 4, + session->userauth_pblc_method_len); + } + /* + * The length of the method name read from plaintext prefix in the + * file must match length embedded in the key. + * TODO: The data should match too but we don't check that. Should we? + */ + else if(session->userauth_pblc_method_len != + _libssh2_ntohu32(pubkeydata)) + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid public key"); + + /* + * 45 = packet_type(1) + username_len(4) + servicename_len(4) + + * service_name(14)"ssh-connection" + authmethod_len(4) + + * authmethod(9)"publickey" + sig_included(1)'\0' + algmethod_len(4) + + * publickey_len(4) + */ + session->userauth_pblc_packet_len = + username_len + session->userauth_pblc_method_len + pubkeydata_len + + 45; + + /* + * Preallocate space for an overall length, method name again, and the + * signature, which won't be any larger than the size of the + * publickeydata itself. + * + * Note that the 'pubkeydata_len' extra bytes allocated here will not + * be used in this first send, but will be used in the later one where + * this same allocation is re-used. + */ + s = session->userauth_pblc_packet = + LIBSSH2_ALLOC(session, + session->userauth_pblc_packet_len + 4 + + (4 + session->userauth_pblc_method_len) + + (4 + pubkeydata_len)); + if(!session->userauth_pblc_packet) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Out of memory"); + } + + *s++ = SSH_MSG_USERAUTH_REQUEST; + _libssh2_store_str(&s, username, username_len); + _libssh2_store_str(&s, "ssh-connection", 14); + _libssh2_store_str(&s, "publickey", 9); + + session->userauth_pblc_b = s; + /* Not sending signature with *this* packet */ + *s++ = 0; + + _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, + session->userauth_pblc_method_len); + _libssh2_store_str(&s, (const char *)pubkeydata, pubkeydata_len); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting publickey authentication"); + + session->userauth_pblc_state = libssh2_NB_state_created; + } + + if(session->userauth_pblc_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_pblc_packet, + session->userauth_pblc_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + else if(rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request"); + } + + session->userauth_pblc_state = libssh2_NB_state_sent; + } + + if(session->userauth_pblc_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, + NULL, 0, + &session-> + userauth_pblc_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + else if(rc || (session->userauth_pblc_data_len < 1)) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Waiting for USERAUTH response"); + } + + if(session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Pubkey authentication prematurely successful"); + /* + * God help any SSH server that allows an UNVERIFIED + * public key to validate the user + */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pblc_state = libssh2_NB_state_idle; + return 0; + } + + if(session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_FAILURE) { + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Username/PublicKey combination invalid"); + } + + /* Semi-Success! */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + + *session->userauth_pblc_b = 0x01; + session->userauth_pblc_state = libssh2_NB_state_sent1; + } + + if(session->userauth_pblc_state == libssh2_NB_state_sent1) { + unsigned char *buf; + unsigned char *sig; + size_t sig_len; + + s = buf = LIBSSH2_ALLOC(session, 4 + session->session_id_len + + session->userauth_pblc_packet_len); + if(!buf) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "userauth-publickey signed data"); + } + + _libssh2_store_str(&s, (const char *)session->session_id, + session->session_id_len); + + memcpy(s, session->userauth_pblc_packet, + session->userauth_pblc_packet_len); + s += session->userauth_pblc_packet_len; + + rc = sign_callback(session, &sig, &sig_len, buf, s - buf, abstract); + LIBSSH2_FREE(session, buf); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + else if(rc) { + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Callback returned error"); + } + + /* + * If this function was restarted, pubkeydata_len might still be 0 + * which will cause an unnecessary but harmless realloc here. + */ + if(sig_len > pubkeydata_len) { + unsigned char *newpacket; + /* Should *NEVER* happen, but...well.. better safe than sorry */ + newpacket = LIBSSH2_REALLOC(session, + session->userauth_pblc_packet, + session->userauth_pblc_packet_len + 4 + + (4 + session->userauth_pblc_method_len) + + (4 + sig_len)); /* PK sigblob */ + if(!newpacket) { + LIBSSH2_FREE(session, sig); + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Failed allocating additional space for " + "userauth-publickey packet"); + } + session->userauth_pblc_packet = newpacket; + } + + s = session->userauth_pblc_packet + session->userauth_pblc_packet_len; + session->userauth_pblc_b = NULL; + + _libssh2_store_u32(&s, + 4 + session->userauth_pblc_method_len + 4 + + sig_len); + _libssh2_store_str(&s, (const char *)session->userauth_pblc_method, + session->userauth_pblc_method_len); + + LIBSSH2_FREE(session, session->userauth_pblc_method); + session->userauth_pblc_method = NULL; + + _libssh2_store_str(&s, (const char *)sig, sig_len); + LIBSSH2_FREE(session, sig); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting publickey authentication -- phase 2"); + + session->userauth_pblc_s = s; + session->userauth_pblc_state = libssh2_NB_state_sent2; + } + + if(session->userauth_pblc_state == libssh2_NB_state_sent2) { + rc = _libssh2_transport_send(session, session->userauth_pblc_packet, + session->userauth_pblc_s - + session->userauth_pblc_packet, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + else if(rc) { + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-publickey request"); + } + LIBSSH2_FREE(session, session->userauth_pblc_packet); + session->userauth_pblc_packet = NULL; + + session->userauth_pblc_state = libssh2_NB_state_sent3; + } + + /* PK_OK is no longer valid */ + reply_codes[2] = 0; + + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_pblc_data, + &session->userauth_pblc_data_len, 0, NULL, 0, + &session->userauth_pblc_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block requesting userauth list"); + } + else if(rc || session->userauth_pblc_data_len < 1) { + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Waiting for publickey USERAUTH response"); + } + + if(session->userauth_pblc_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Publickey authentication successful"); + /* We are us and we've proved it. */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_pblc_state = libssh2_NB_state_idle; + return 0; + } + + /* This public key is not allowed for this user on this server */ + LIBSSH2_FREE(session, session->userauth_pblc_data); + session->userauth_pblc_data = NULL; + session->userauth_pblc_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED, + "Invalid signature for supplied public key, or bad " + "username/public key combination"); +} + + /* + * userauth_publickey_frommemory + * Authenticate using a keypair from memory + */ +static int +userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickeydata, + size_t publickeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ + unsigned char *pubkeydata = NULL; + size_t pubkeydata_len = 0; + struct privkey_file privkey_file; + void *abstract = &privkey_file; + int rc; + +#if !LIBSSH2_RSA + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "RSA is not supported by crypto backend"); +#endif + + privkey_file.filename = privatekeydata; + privkey_file.passphrase = passphrase; + + if(session->userauth_pblc_state == libssh2_NB_state_idle) { + if(publickeydata_len && publickeydata) { + rc = memory_read_publickey(session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + publickeydata, publickeydata_len); + if(rc) + return rc; + } + else if(privatekeydata_len && privatekeydata) { + /* Compute public key from private key. */ + if(_libssh2_pub_priv_keyfilememory(session, + &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + privatekeydata, privatekeydata_len, + passphrase)) + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to extract public key " + "from private key."); + } + else { + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Invalid data in public and private key."); + } + } + + rc = _libssh2_userauth_publickey(session, username, username_len, + pubkeydata, pubkeydata_len, + sign_frommemory, &abstract); + if(pubkeydata) + LIBSSH2_FREE(session, pubkeydata); + + return rc; +} + +/* + * userauth_publickey_fromfile + * Authenticate using a keypair found in the named files + */ +static int +userauth_publickey_fromfile(LIBSSH2_SESSION *session, + const char *username, + size_t username_len, + const char *publickey, + const char *privatekey, + const char *passphrase) +{ + unsigned char *pubkeydata = NULL; + size_t pubkeydata_len = 0; + struct privkey_file privkey_file; + void *abstract = &privkey_file; + int rc; + +#if !LIBSSH2_RSA + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "RSA is not supported by crypto backend"); +#endif + + privkey_file.filename = privatekey; + privkey_file.passphrase = passphrase; + + if(session->userauth_pblc_state == libssh2_NB_state_idle) { + if(publickey) { + rc = file_read_publickey(session, &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, publickey); + if(rc) + return rc; + } + else { + /* Compute public key from private key. */ + rc = _libssh2_pub_priv_keyfile(session, + &session->userauth_pblc_method, + &session->userauth_pblc_method_len, + &pubkeydata, &pubkeydata_len, + privatekey, passphrase); + + /* _libssh2_pub_priv_keyfile calls _libssh2_error() */ + if(rc) + return rc; + } + } + + rc = _libssh2_userauth_publickey(session, username, username_len, + pubkeydata, pubkeydata_len, + sign_fromfile, &abstract); + if(pubkeydata) + LIBSSH2_FREE(session, pubkeydata); + + return rc; +} + +/* libssh2_userauth_publickey_frommemory + * Authenticate using a keypair from memory + */ +LIBSSH2_API int +libssh2_userauth_publickey_frommemory(LIBSSH2_SESSION *session, + const char *user, + size_t user_len, + const char *publickeyfiledata, + size_t publickeyfiledata_len, + const char *privatekeyfiledata, + size_t privatekeyfiledata_len, + const char *passphrase) +{ + int rc; + + if(NULL == passphrase) + /* if given a NULL pointer, make it point to a zero-length + string to save us from having to check this all over */ + passphrase = ""; + + BLOCK_ADJUST(rc, session, + userauth_publickey_frommemory(session, user, user_len, + publickeyfiledata, + publickeyfiledata_len, + privatekeyfiledata, + privatekeyfiledata_len, + passphrase)); + return rc; +} + +/* libssh2_userauth_publickey_fromfile_ex + * Authenticate using a keypair found in the named files + */ +LIBSSH2_API int +libssh2_userauth_publickey_fromfile_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + const char *publickey, + const char *privatekey, + const char *passphrase) +{ + int rc; + + if(NULL == passphrase) + /* if given a NULL pointer, make it point to a zero-length + string to save us from having to check this all over */ + passphrase = ""; + + BLOCK_ADJUST(rc, session, + userauth_publickey_fromfile(session, user, user_len, + publickey, privatekey, + passphrase)); + return rc; +} + +/* libssh2_userauth_publickey_ex + * Authenticate using an external callback function + */ +LIBSSH2_API int +libssh2_userauth_publickey(LIBSSH2_SESSION *session, + const char *user, + const unsigned char *pubkeydata, + size_t pubkeydata_len, + LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC + ((*sign_callback)), + void **abstract) +{ + int rc; + + if(!session) + return LIBSSH2_ERROR_BAD_USE; + + BLOCK_ADJUST(rc, session, + _libssh2_userauth_publickey(session, user, strlen(user), + pubkeydata, pubkeydata_len, + sign_callback, abstract)); + return rc; +} + + + +/* + * userauth_keyboard_interactive + * + * Authenticate using a challenge-response authentication + */ +static int +userauth_keyboard_interactive(LIBSSH2_SESSION * session, + const char *username, + unsigned int username_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC + ((*response_callback))) +{ + unsigned char *s; + int rc; + + static const unsigned char reply_codes[4] = { + SSH_MSG_USERAUTH_SUCCESS, + SSH_MSG_USERAUTH_FAILURE, SSH_MSG_USERAUTH_INFO_REQUEST, 0 + }; + unsigned int language_tag_len; + unsigned int i; + + if(session->userauth_kybd_state == libssh2_NB_state_idle) { + session->userauth_kybd_auth_name = NULL; + session->userauth_kybd_auth_instruction = NULL; + session->userauth_kybd_num_prompts = 0; + session->userauth_kybd_auth_failure = 1; + session->userauth_kybd_prompts = NULL; + session->userauth_kybd_responses = NULL; + + /* Zero the whole thing out */ + memset(&session->userauth_kybd_packet_requirev_state, 0, + sizeof(session->userauth_kybd_packet_requirev_state)); + + session->userauth_kybd_packet_len = + 1 /* byte SSH_MSG_USERAUTH_REQUEST */ + + 4 + username_len /* string user name (ISO-10646 UTF-8, as + defined in [RFC-3629]) */ + + 4 + 14 /* string service name (US-ASCII) */ + + 4 + 20 /* string "keyboard-interactive" (US-ASCII) */ + + 4 + 0 /* string language tag (as defined in + [RFC-3066]) */ + + 4 + 0 /* string submethods (ISO-10646 UTF-8) */ + ; + + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + if(!s) { + return _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive authentication"); + } + + *s++ = SSH_MSG_USERAUTH_REQUEST; + + /* user name */ + _libssh2_store_str(&s, username, username_len); + + /* service name */ + _libssh2_store_str(&s, "ssh-connection", sizeof("ssh-connection") - 1); + + /* "keyboard-interactive" */ + _libssh2_store_str(&s, "keyboard-interactive", + sizeof("keyboard-interactive") - 1); + /* language tag */ + _libssh2_store_u32(&s, 0); + + /* submethods */ + _libssh2_store_u32(&s, 0); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Attempting keyboard-interactive authentication"); + + session->userauth_kybd_state = libssh2_NB_state_created; + } + + if(session->userauth_kybd_state == libssh2_NB_state_created) { + rc = _libssh2_transport_send(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + else if(rc) { + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send keyboard-interactive" + " request"); + } + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + + session->userauth_kybd_state = libssh2_NB_state_sent; + } + + for(;;) { + if(session->userauth_kybd_state == libssh2_NB_state_sent) { + rc = _libssh2_packet_requirev(session, reply_codes, + &session->userauth_kybd_data, + &session->userauth_kybd_data_len, + 0, NULL, 0, + &session-> + userauth_kybd_packet_requirev_state); + if(rc == LIBSSH2_ERROR_EAGAIN) { + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + } + else if(rc || session->userauth_kybd_data_len < 1) { + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Waiting for keyboard " + "USERAUTH response"); + } + + if(session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_SUCCESS) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive " + "authentication successful"); + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->state |= LIBSSH2_STATE_AUTHENTICATED; + session->userauth_kybd_state = libssh2_NB_state_idle; + return 0; + } + + if(session->userauth_kybd_data[0] == SSH_MSG_USERAUTH_FAILURE) { + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive authentication failed"); + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + session->userauth_kybd_state = libssh2_NB_state_idle; + return _libssh2_error(session, + LIBSSH2_ERROR_AUTHENTICATION_FAILED, + "Authentication failed " + "(keyboard-interactive)"); + } + + /* server requested PAM-like conversation */ + s = session->userauth_kybd_data + 1; + + if(session->userauth_kybd_data_len >= 5) { + /* string name (ISO-10646 UTF-8) */ + session->userauth_kybd_auth_name_len = _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "to get length"); + goto cleanup; + } + + if(session->userauth_kybd_auth_name_len) { + session->userauth_kybd_auth_name = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_name_len); + if(!session->userauth_kybd_auth_name) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive 'name' " + "request field"); + goto cleanup; + } + if(s + session->userauth_list_data_len <= + session->userauth_kybd_data + + session->userauth_kybd_data_len) { + memcpy(session->userauth_kybd_auth_name, s, + session->userauth_kybd_auth_name_len); + s += session->userauth_kybd_auth_name_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "for auth name"); + goto cleanup; + } + } + + if(s + 4 <= session->userauth_kybd_data + + session->userauth_kybd_data_len) { + /* string instruction (ISO-10646 UTF-8) */ + session->userauth_kybd_auth_instruction_len = + _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "for auth instruction length"); + goto cleanup; + } + + if(session->userauth_kybd_auth_instruction_len) { + session->userauth_kybd_auth_instruction = + LIBSSH2_ALLOC(session, + session->userauth_kybd_auth_instruction_len); + if(!session->userauth_kybd_auth_instruction) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive 'instruction' " + "request field"); + goto cleanup; + } + if(s + session->userauth_kybd_auth_instruction_len <= + session->userauth_kybd_data + + session->userauth_kybd_data_len) { + memcpy(session->userauth_kybd_auth_instruction, s, + session->userauth_kybd_auth_instruction_len); + s += session->userauth_kybd_auth_instruction_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "for auth instruction"); + goto cleanup; + } + } + + if(s + 4 <= session->userauth_kybd_data + + session->userauth_kybd_data_len) { + /* string language tag (as defined in [RFC-3066]) */ + language_tag_len = _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "for auth language tag length"); + goto cleanup; + } + + if(s + language_tag_len <= session->userauth_kybd_data + + session->userauth_kybd_data_len) { + /* ignoring this field as deprecated */ + s += language_tag_len; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "for auth language tag"); + goto cleanup; + } + + if(s + 4 <= session->userauth_kybd_data + + session->userauth_kybd_data_len) { + /* int num-prompts */ + session->userauth_kybd_num_prompts = _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too small" + "for auth num keyboard prompts"); + goto cleanup; + } + + if(session->userauth_kybd_num_prompts > 100) { + _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY, + "Too many replies for " + "keyboard-interactive prompts"); + goto cleanup; + } + + if(session->userauth_kybd_num_prompts) { + session->userauth_kybd_prompts = + LIBSSH2_CALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) * + session->userauth_kybd_num_prompts); + if(!session->userauth_kybd_prompts) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive prompts array"); + goto cleanup; + } + + session->userauth_kybd_responses = + LIBSSH2_CALLOC(session, + sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) * + session->userauth_kybd_num_prompts); + if(!session->userauth_kybd_responses) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive responses array"); + goto cleanup; + } + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + if(s + 4 <= session->userauth_kybd_data + + session->userauth_kybd_data_len) { + /* string prompt[1] (ISO-10646 UTF-8) */ + session->userauth_kybd_prompts[i].length = + _libssh2_ntohu32(s); + s += 4; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too " + "small for auth keyboard " + "prompt length"); + goto cleanup; + } + + session->userauth_kybd_prompts[i].text = + LIBSSH2_CALLOC(session, + session->userauth_kybd_prompts[i]. + length); + if(!session->userauth_kybd_prompts[i].text) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for " + "keyboard-interactive prompt message"); + goto cleanup; + } + + if(s + session->userauth_kybd_prompts[i].length <= + session->userauth_kybd_data + + session->userauth_kybd_data_len) { + memcpy(session->userauth_kybd_prompts[i].text, s, + session->userauth_kybd_prompts[i].length); + s += session->userauth_kybd_prompts[i].length; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too " + "small for auth keyboard prompt"); + goto cleanup; + } + if(s < session->userauth_kybd_data + + session->userauth_kybd_data_len) { + /* boolean echo[1] */ + session->userauth_kybd_prompts[i].echo = *s++; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL, + "userauth keyboard data buffer too " + "small for auth keyboard prompt echo"); + goto cleanup; + } + } + } + + response_callback(session->userauth_kybd_auth_name, + session->userauth_kybd_auth_name_len, + session->userauth_kybd_auth_instruction, + session->userauth_kybd_auth_instruction_len, + session->userauth_kybd_num_prompts, + session->userauth_kybd_prompts, + session->userauth_kybd_responses, + &session->abstract); + + _libssh2_debug(session, LIBSSH2_TRACE_AUTH, + "Keyboard-interactive response callback function" + " invoked"); + + session->userauth_kybd_packet_len = + 1 /* byte SSH_MSG_USERAUTH_INFO_RESPONSE */ + + 4 /* int num-responses */ + ; + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + /* string response[1] (ISO-10646 UTF-8) */ + if(session->userauth_kybd_responses[i].length <= + (SIZE_MAX - 4 - session->userauth_kybd_packet_len) ) { + session->userauth_kybd_packet_len += + 4 + session->userauth_kybd_responses[i].length; + } + else { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-" + "interactive response packet"); + goto cleanup; + } + } + + /* A new userauth_kybd_data area is to be allocated, free the + former one. */ + LIBSSH2_FREE(session, session->userauth_kybd_data); + + session->userauth_kybd_data = s = + LIBSSH2_ALLOC(session, session->userauth_kybd_packet_len); + if(!s) { + _libssh2_error(session, LIBSSH2_ERROR_ALLOC, + "Unable to allocate memory for keyboard-" + "interactive response packet"); + goto cleanup; + } + + *s = SSH_MSG_USERAUTH_INFO_RESPONSE; + s++; + _libssh2_store_u32(&s, session->userauth_kybd_num_prompts); + + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + _libssh2_store_str(&s, + session->userauth_kybd_responses[i].text, + session->userauth_kybd_responses[i].length); + } + + session->userauth_kybd_state = libssh2_NB_state_sent1; + } + + if(session->userauth_kybd_state == libssh2_NB_state_sent1) { + rc = _libssh2_transport_send(session, session->userauth_kybd_data, + session->userauth_kybd_packet_len, + NULL, 0); + if(rc == LIBSSH2_ERROR_EAGAIN) + return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, + "Would block"); + if(rc) { + _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND, + "Unable to send userauth-keyboard-interactive" + " request"); + goto cleanup; + } + + session->userauth_kybd_auth_failure = 0; + } + + cleanup: + /* + * It's safe to clean all the data here, because unallocated pointers + * are filled by zeroes + */ + + LIBSSH2_FREE(session, session->userauth_kybd_data); + session->userauth_kybd_data = NULL; + + if(session->userauth_kybd_prompts) { + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + LIBSSH2_FREE(session, session->userauth_kybd_prompts[i].text); + session->userauth_kybd_prompts[i].text = NULL; + } + } + + if(session->userauth_kybd_responses) { + for(i = 0; i < session->userauth_kybd_num_prompts; i++) { + LIBSSH2_FREE(session, + session->userauth_kybd_responses[i].text); + session->userauth_kybd_responses[i].text = NULL; + } + } + + if(session->userauth_kybd_prompts) { + LIBSSH2_FREE(session, session->userauth_kybd_prompts); + session->userauth_kybd_prompts = NULL; + } + if(session->userauth_kybd_responses) { + LIBSSH2_FREE(session, session->userauth_kybd_responses); + session->userauth_kybd_responses = NULL; + } + if(session->userauth_kybd_auth_name) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_name); + session->userauth_kybd_auth_name = NULL; + } + if(session->userauth_kybd_auth_instruction) { + LIBSSH2_FREE(session, session->userauth_kybd_auth_instruction); + session->userauth_kybd_auth_instruction = NULL; + } + + if(session->userauth_kybd_auth_failure) { + session->userauth_kybd_state = libssh2_NB_state_idle; + return -1; + } + + session->userauth_kybd_state = libssh2_NB_state_sent; + } +} + +/* + * libssh2_userauth_keyboard_interactive_ex + * + * Authenticate using a challenge-response authentication + */ +LIBSSH2_API int +libssh2_userauth_keyboard_interactive_ex(LIBSSH2_SESSION *session, + const char *user, + unsigned int user_len, + LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC + ((*response_callback))) +{ + int rc; + BLOCK_ADJUST(rc, session, + userauth_keyboard_interactive(session, user, user_len, + response_callback)); + return rc; +} diff --git a/libssh2/version.c b/libssh2/version.c new file mode 100644 index 0000000..408f83a --- /dev/null +++ b/libssh2/version.c @@ -0,0 +1,54 @@ +/* Copyright (C) 2009 Daniel Stenberg. All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + */ + +#include "libssh2_priv.h" + +/* + libssh2_version() can be used like this: + + if (!libssh2_version(LIBSSH2_VERSION_NUM)) { + fprintf (stderr, "Runtime libssh2 version too old!\n"); + exit(1); + } +*/ +LIBSSH2_API +const char *libssh2_version(int req_version_num) +{ + if(req_version_num <= LIBSSH2_VERSION_NUM) + return LIBSSH2_VERSION; + return NULL; /* this is not a suitable library! */ +} diff --git a/libssh2/wincng.c b/libssh2/wincng.c new file mode 100644 index 0000000..04a4f81 --- /dev/null +++ b/libssh2/wincng.c @@ -0,0 +1,2166 @@ +/* + * Copyright (C) 2013-2015 Marc Hoersken + * All rights reserved. + * + * Redistribution and use in source and binary forms, + * with or without modification, are permitted provided + * that the following conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the copyright holder nor the names + * of any other contributors may be used to endorse or + * promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#include "libssh2_priv.h" + +#ifdef LIBSSH2_WINCNG /* compile only if we build with wincng */ + +/* required for cross-compilation against the w64 mingw-runtime package */ +#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) +#undef _WIN32_WINNT +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 +#endif + +/* specify the required libraries for dependencies using MSVC */ +#ifdef _MSC_VER +#pragma comment(lib, "bcrypt.lib") +#ifdef HAVE_LIBCRYPT32 +#pragma comment(lib, "crypt32.lib") +#endif +#endif + +#include +#include +#include +#include "misc.h" + +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_LIBCRYPT32 +#include +#endif + +#define PEM_RSA_HEADER "-----BEGIN RSA PRIVATE KEY-----" +#define PEM_RSA_FOOTER "-----END RSA PRIVATE KEY-----" +#define PEM_DSA_HEADER "-----BEGIN DSA PRIVATE KEY-----" +#define PEM_DSA_FOOTER "-----END DSA PRIVATE KEY-----" + + +/*******************************************************************/ +/* + * Windows CNG backend: Missing definitions (for MinGW[-w64]) + */ +#ifndef BCRYPT_SUCCESS +#define BCRYPT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#endif + +#ifndef BCRYPT_RNG_ALGORITHM +#define BCRYPT_RNG_ALGORITHM L"RNG" +#endif + +#ifndef BCRYPT_MD5_ALGORITHM +#define BCRYPT_MD5_ALGORITHM L"MD5" +#endif + +#ifndef BCRYPT_SHA1_ALGORITHM +#define BCRYPT_SHA1_ALGORITHM L"SHA1" +#endif + +#ifndef BCRYPT_SHA256_ALGORITHM +#define BCRYPT_SHA256_ALGORITHM L"SHA256" +#endif + +#ifndef BCRYPT_SHA512_ALGORITHM +#define BCRYPT_SHA512_ALGORITHM L"SHA512" +#endif + +#ifndef BCRYPT_RSA_ALGORITHM +#define BCRYPT_RSA_ALGORITHM L"RSA" +#endif + +#ifndef BCRYPT_DSA_ALGORITHM +#define BCRYPT_DSA_ALGORITHM L"DSA" +#endif + +#ifndef BCRYPT_AES_ALGORITHM +#define BCRYPT_AES_ALGORITHM L"AES" +#endif + +#ifndef BCRYPT_RC4_ALGORITHM +#define BCRYPT_RC4_ALGORITHM L"RC4" +#endif + +#ifndef BCRYPT_3DES_ALGORITHM +#define BCRYPT_3DES_ALGORITHM L"3DES" +#endif + +#ifndef BCRYPT_ALG_HANDLE_HMAC_FLAG +#define BCRYPT_ALG_HANDLE_HMAC_FLAG 0x00000008 +#endif + +#ifndef BCRYPT_DSA_PUBLIC_BLOB +#define BCRYPT_DSA_PUBLIC_BLOB L"DSAPUBLICBLOB" +#endif + +#ifndef BCRYPT_DSA_PUBLIC_MAGIC +#define BCRYPT_DSA_PUBLIC_MAGIC 0x42505344 /* DSPB */ +#endif + +#ifndef BCRYPT_DSA_PRIVATE_BLOB +#define BCRYPT_DSA_PRIVATE_BLOB L"DSAPRIVATEBLOB" +#endif + +#ifndef BCRYPT_DSA_PRIVATE_MAGIC +#define BCRYPT_DSA_PRIVATE_MAGIC 0x56505344 /* DSPV */ +#endif + +#ifndef BCRYPT_RSAPUBLIC_BLOB +#define BCRYPT_RSAPUBLIC_BLOB L"RSAPUBLICBLOB" +#endif + +#ifndef BCRYPT_RSAPUBLIC_MAGIC +#define BCRYPT_RSAPUBLIC_MAGIC 0x31415352 /* RSA1 */ +#endif + +#ifndef BCRYPT_RSAFULLPRIVATE_BLOB +#define BCRYPT_RSAFULLPRIVATE_BLOB L"RSAFULLPRIVATEBLOB" +#endif + +#ifndef BCRYPT_RSAFULLPRIVATE_MAGIC +#define BCRYPT_RSAFULLPRIVATE_MAGIC 0x33415352 /* RSA3 */ +#endif + +#ifndef BCRYPT_KEY_DATA_BLOB +#define BCRYPT_KEY_DATA_BLOB L"KeyDataBlob" +#endif + +#ifndef BCRYPT_MESSAGE_BLOCK_LENGTH +#define BCRYPT_MESSAGE_BLOCK_LENGTH L"MessageBlockLength" +#endif + +#ifndef BCRYPT_NO_KEY_VALIDATION +#define BCRYPT_NO_KEY_VALIDATION 0x00000008 +#endif + +#ifndef BCRYPT_BLOCK_PADDING +#define BCRYPT_BLOCK_PADDING 0x00000001 +#endif + +#ifndef BCRYPT_PAD_NONE +#define BCRYPT_PAD_NONE 0x00000001 +#endif + +#ifndef BCRYPT_PAD_PKCS1 +#define BCRYPT_PAD_PKCS1 0x00000002 +#endif + +#ifndef BCRYPT_PAD_OAEP +#define BCRYPT_PAD_OAEP 0x00000004 +#endif + +#ifndef BCRYPT_PAD_PSS +#define BCRYPT_PAD_PSS 0x00000008 +#endif + +#ifndef CRYPT_STRING_ANY +#define CRYPT_STRING_ANY 0x00000007 +#endif + +#ifndef LEGACY_RSAPRIVATE_BLOB +#define LEGACY_RSAPRIVATE_BLOB L"CAPIPRIVATEBLOB" +#endif + +#ifndef PKCS_RSA_PRIVATE_KEY +#define PKCS_RSA_PRIVATE_KEY (LPCSTR)43 +#endif + + +/*******************************************************************/ +/* + * Windows CNG backend: Generic functions + */ + +struct _libssh2_wincng_ctx _libssh2_wincng; + +void +_libssh2_wincng_init(void) +{ + int ret; + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRNG, + BCRYPT_RNG_ALGORITHM, NULL, 0); + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashMD5, + BCRYPT_MD5_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA1, + BCRYPT_SHA1_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA256, + BCRYPT_SHA256_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHashSHA512, + BCRYPT_SHA512_ALGORITHM, NULL, 0); + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacMD5, + BCRYPT_MD5_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA1, + BCRYPT_SHA1_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA256, + BCRYPT_SHA256_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgHmacSHA512, + BCRYPT_SHA512_ALGORITHM, NULL, + BCRYPT_ALG_HANDLE_HMAC_FLAG); + + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRSA, + BCRYPT_RSA_ALGORITHM, NULL, 0); + (void)BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgDSA, + BCRYPT_DSA_ALGORITHM, NULL, 0); + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_CBC, + BCRYPT_AES_ALGORITHM, NULL, 0); + if(BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_CBC, + BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_CBC, + sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + if(!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); + } + } + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgAES_ECB, + BCRYPT_AES_ALGORITHM, NULL, 0); + if(BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlgAES_ECB, + BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_ECB, + sizeof(BCRYPT_CHAIN_MODE_ECB), 0); + if(!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_ECB, 0); + } + } + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlgRC4_NA, + BCRYPT_RC4_ALGORITHM, NULL, 0); + if(BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlgRC4_NA, + BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_NA, + sizeof(BCRYPT_CHAIN_MODE_NA), 0); + if(!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); + } + } + + ret = BCryptOpenAlgorithmProvider(&_libssh2_wincng.hAlg3DES_CBC, + BCRYPT_3DES_ALGORITHM, NULL, 0); + if(BCRYPT_SUCCESS(ret)) { + ret = BCryptSetProperty(_libssh2_wincng.hAlg3DES_CBC, + BCRYPT_CHAINING_MODE, + (PBYTE)BCRYPT_CHAIN_MODE_CBC, + sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + if(!BCRYPT_SUCCESS(ret)) { + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, + 0); + } + } +} + +void +_libssh2_wincng_free(void) +{ + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRNG, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashMD5, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA1, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA256, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHashSHA512, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacMD5, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA1, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA256, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgHmacSHA512, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRSA, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgDSA, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgAES_CBC, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlgRC4_NA, 0); + (void)BCryptCloseAlgorithmProvider(_libssh2_wincng.hAlg3DES_CBC, 0); + + memset(&_libssh2_wincng, 0, sizeof(_libssh2_wincng)); +} + +int +_libssh2_wincng_random(void *buf, int len) +{ + int ret; + + ret = BCryptGenRandom(_libssh2_wincng.hAlgRNG, buf, len, 0); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +static void +_libssh2_wincng_safe_free(void *buf, int len) +{ +#ifndef LIBSSH2_CLEAR_MEMORY + (void)len; +#endif + + if(!buf) + return; + +#ifdef LIBSSH2_CLEAR_MEMORY + if(len > 0) + SecureZeroMemory(buf, len); +#endif + + free(buf); +} + + +/*******************************************************************/ +/* + * Windows CNG backend: Hash functions + */ + +int +_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx, + BCRYPT_ALG_HANDLE hAlg, unsigned long hashlen, + unsigned char *key, unsigned long keylen) +{ + BCRYPT_HASH_HANDLE hHash; + unsigned char *pbHashObject; + unsigned long dwHashObject, dwHash, cbData; + int ret; + + ret = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, + (unsigned char *)&dwHash, + sizeof(dwHash), + &cbData, 0); + if((!BCRYPT_SUCCESS(ret)) || dwHash != hashlen) { + return -1; + } + + ret = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, + (unsigned char *)&dwHashObject, + sizeof(dwHashObject), + &cbData, 0); + if(!BCRYPT_SUCCESS(ret)) { + return -1; + } + + pbHashObject = malloc(dwHashObject); + if(!pbHashObject) { + return -1; + } + + + ret = BCryptCreateHash(hAlg, &hHash, + pbHashObject, dwHashObject, + key, keylen, 0); + if(!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(pbHashObject, dwHashObject); + return -1; + } + + + ctx->hHash = hHash; + ctx->pbHashObject = pbHashObject; + ctx->dwHashObject = dwHashObject; + ctx->cbHash = dwHash; + + return 0; +} + +int +_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx, + const unsigned char *data, unsigned long datalen) +{ + int ret; + + ret = BCryptHashData(ctx->hHash, (unsigned char *)data, datalen, 0); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +int +_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash) +{ + int ret; + + ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); + + BCryptDestroyHash(ctx->hHash); + ctx->hHash = NULL; + + _libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject); + ctx->pbHashObject = NULL; + ctx->dwHashObject = 0; + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +int +_libssh2_wincng_hash(unsigned char *data, unsigned long datalen, + BCRYPT_ALG_HANDLE hAlg, + unsigned char *hash, unsigned long hashlen) +{ + _libssh2_wincng_hash_ctx ctx; + int ret; + + ret = _libssh2_wincng_hash_init(&ctx, hAlg, hashlen, NULL, 0); + if(!ret) { + ret = _libssh2_wincng_hash_update(&ctx, data, datalen); + ret |= _libssh2_wincng_hash_final(&ctx, hash); + } + + return ret; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: HMAC functions + */ + +int +_libssh2_wincng_hmac_final(_libssh2_wincng_hash_ctx *ctx, + unsigned char *hash) +{ + int ret; + + ret = BCryptFinishHash(ctx->hHash, hash, ctx->cbHash, 0); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_hmac_cleanup(_libssh2_wincng_hash_ctx *ctx) +{ + BCryptDestroyHash(ctx->hHash); + ctx->hHash = NULL; + + _libssh2_wincng_safe_free(ctx->pbHashObject, ctx->dwHashObject); + ctx->pbHashObject = NULL; + ctx->dwHashObject = 0; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: Key functions + */ + +int +_libssh2_wincng_key_sha1_verify(_libssh2_wincng_key_ctx *ctx, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len, + unsigned long flags) +{ + BCRYPT_PKCS1_PADDING_INFO paddingInfoPKCS1; + void *pPaddingInfo; + unsigned char *data, *hash; + unsigned long datalen, hashlen; + int ret; + + datalen = m_len; + data = malloc(datalen); + if(!data) { + return -1; + } + + hashlen = SHA_DIGEST_LENGTH; + hash = malloc(hashlen); + if(!hash) { + free(data); + return -1; + } + + memcpy(data, m, datalen); + + ret = _libssh2_wincng_hash(data, datalen, + _libssh2_wincng.hAlgHashSHA1, + hash, hashlen); + + _libssh2_wincng_safe_free(data, datalen); + + if(ret) { + _libssh2_wincng_safe_free(hash, hashlen); + return -1; + } + + datalen = sig_len; + data = malloc(datalen); + if(!data) { + _libssh2_wincng_safe_free(hash, hashlen); + return -1; + } + + if(flags & BCRYPT_PAD_PKCS1) { + paddingInfoPKCS1.pszAlgId = BCRYPT_SHA1_ALGORITHM; + pPaddingInfo = &paddingInfoPKCS1; + } + else + pPaddingInfo = NULL; + + memcpy(data, sig, datalen); + + ret = BCryptVerifySignature(ctx->hKey, pPaddingInfo, + hash, hashlen, data, datalen, flags); + + _libssh2_wincng_safe_free(hash, hashlen); + _libssh2_wincng_safe_free(data, datalen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +#ifdef HAVE_LIBCRYPT32 +static int +_libssh2_wincng_load_pem(LIBSSH2_SESSION *session, + const char *filename, + const char *passphrase, + const char *headerbegin, + const char *headerend, + unsigned char **data, + unsigned int *datalen) +{ + FILE *fp; + int ret; + + fp = fopen(filename, FOPEN_READTEXT); + if(!fp) { + return -1; + } + + ret = _libssh2_pem_parse(session, headerbegin, headerend, + passphrase, + fp, data, datalen); + + fclose(fp); + + return ret; +} + +static int +_libssh2_wincng_load_private(LIBSSH2_SESSION *session, + const char *filename, + const char *passphrase, + unsigned char **ppbEncoded, + unsigned long *pcbEncoded, + int tryLoadRSA, int tryLoadDSA) +{ + unsigned char *data = NULL; + unsigned int datalen = 0; + int ret = -1; + + if(ret && tryLoadRSA) { + ret = _libssh2_wincng_load_pem(session, filename, passphrase, + PEM_RSA_HEADER, PEM_RSA_FOOTER, + &data, &datalen); + } + + if(ret && tryLoadDSA) { + ret = _libssh2_wincng_load_pem(session, filename, passphrase, + PEM_DSA_HEADER, PEM_DSA_FOOTER, + &data, &datalen); + } + + if(!ret) { + *ppbEncoded = data; + *pcbEncoded = datalen; + } + + return ret; +} + +static int +_libssh2_wincng_load_private_memory(LIBSSH2_SESSION *session, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase, + unsigned char **ppbEncoded, + unsigned long *pcbEncoded, + int tryLoadRSA, int tryLoadDSA) +{ + unsigned char *data = NULL; + unsigned int datalen = 0; + int ret = -1; + + (void)passphrase; + + if(ret && tryLoadRSA) { + ret = _libssh2_pem_parse_memory(session, + PEM_RSA_HEADER, PEM_RSA_FOOTER, + privatekeydata, privatekeydata_len, + &data, &datalen); + } + + if(ret && tryLoadDSA) { + ret = _libssh2_pem_parse_memory(session, + PEM_DSA_HEADER, PEM_DSA_FOOTER, + privatekeydata, privatekeydata_len, + &data, &datalen); + } + + if(!ret) { + *ppbEncoded = data; + *pcbEncoded = datalen; + } + + return ret; +} + +static int +_libssh2_wincng_asn_decode(unsigned char *pbEncoded, + unsigned long cbEncoded, + LPCSTR lpszStructType, + unsigned char **ppbDecoded, + unsigned long *pcbDecoded) +{ + unsigned char *pbDecoded = NULL; + unsigned long cbDecoded = 0; + int ret; + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + lpszStructType, + pbEncoded, cbEncoded, 0, NULL, + NULL, &cbDecoded); + if(!ret) { + return -1; + } + + pbDecoded = malloc(cbDecoded); + if(!pbDecoded) { + return -1; + } + + ret = CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, + lpszStructType, + pbEncoded, cbEncoded, 0, NULL, + pbDecoded, &cbDecoded); + if(!ret) { + _libssh2_wincng_safe_free(pbDecoded, cbDecoded); + return -1; + } + + + *ppbDecoded = pbDecoded; + *pcbDecoded = cbDecoded; + + return 0; +} + +static int +_libssh2_wincng_bn_ltob(unsigned char *pbInput, + unsigned long cbInput, + unsigned char **ppbOutput, + unsigned long *pcbOutput) +{ + unsigned char *pbOutput; + unsigned long cbOutput, index, offset, length; + + if(cbInput < 1) { + return 0; + } + + offset = 0; + length = cbInput - 1; + cbOutput = cbInput; + if(pbInput[length] & (1 << 7)) { + offset++; + cbOutput += offset; + } + + pbOutput = (unsigned char *)malloc(cbOutput); + if(!pbOutput) { + return -1; + } + + pbOutput[0] = 0; + for(index = 0; ((index + offset) < cbOutput) + && (index < cbInput); index++) { + pbOutput[index + offset] = pbInput[length - index]; + } + + + *ppbOutput = pbOutput; + *pcbOutput = cbOutput; + + return 0; +} + +static int +_libssh2_wincng_asn_decode_bn(unsigned char *pbEncoded, + unsigned long cbEncoded, + unsigned char **ppbDecoded, + unsigned long *pcbDecoded) +{ + unsigned char *pbDecoded = NULL, *pbInteger; + unsigned long cbDecoded = 0, cbInteger; + int ret; + + ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, + X509_MULTI_BYTE_UINT, + &pbInteger, &cbInteger); + if(!ret) { + ret = _libssh2_wincng_bn_ltob(((PCRYPT_DATA_BLOB)pbInteger)->pbData, + ((PCRYPT_DATA_BLOB)pbInteger)->cbData, + &pbDecoded, &cbDecoded); + if(!ret) { + *ppbDecoded = pbDecoded; + *pcbDecoded = cbDecoded; + } + _libssh2_wincng_safe_free(pbInteger, cbInteger); + } + + return ret; +} + +static int +_libssh2_wincng_asn_decode_bns(unsigned char *pbEncoded, + unsigned long cbEncoded, + unsigned char ***prpbDecoded, + unsigned long **prcbDecoded, + unsigned long *pcbCount) +{ + PCRYPT_DER_BLOB pBlob; + unsigned char *pbDecoded, **rpbDecoded; + unsigned long cbDecoded, *rcbDecoded, index, length; + int ret; + + ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, + X509_SEQUENCE_OF_ANY, + &pbDecoded, &cbDecoded); + if(!ret) { + length = ((PCRYPT_DATA_BLOB)pbDecoded)->cbData; + + rpbDecoded = malloc(sizeof(PBYTE) * length); + if(rpbDecoded) { + rcbDecoded = malloc(sizeof(DWORD) * length); + if(rcbDecoded) { + for(index = 0; index < length; index++) { + pBlob = &((PCRYPT_DER_BLOB) + ((PCRYPT_DATA_BLOB)pbDecoded)->pbData)[index]; + ret = _libssh2_wincng_asn_decode_bn(pBlob->pbData, + pBlob->cbData, + &rpbDecoded[index], + &rcbDecoded[index]); + if(ret) + break; + } + + if(!ret) { + *prpbDecoded = rpbDecoded; + *prcbDecoded = rcbDecoded; + *pcbCount = length; + } + else { + for(length = 0; length < index; length++) { + _libssh2_wincng_safe_free(rpbDecoded[length], + rcbDecoded[length]); + rpbDecoded[length] = NULL; + rcbDecoded[length] = 0; + } + free(rpbDecoded); + free(rcbDecoded); + } + } + else { + free(rpbDecoded); + ret = -1; + } + } + else { + ret = -1; + } + + _libssh2_wincng_safe_free(pbDecoded, cbDecoded); + } + + return ret; +} +#endif /* HAVE_LIBCRYPT32 */ + +static unsigned long +_libssh2_wincng_bn_size(const unsigned char *bignum, + unsigned long length) +{ + unsigned long offset; + + if(!bignum) + return 0; + + length--; + + offset = 0; + while(!(*(bignum + offset)) && (offset < length)) + offset++; + + length++; + + return length - offset; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: RSA functions + */ + +int +_libssh2_wincng_rsa_new(libssh2_rsa_ctx **rsa, + const unsigned char *edata, + unsigned long elen, + const unsigned char *ndata, + unsigned long nlen, + const unsigned char *ddata, + unsigned long dlen, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *e1data, + unsigned long e1len, + const unsigned char *e2data, + unsigned long e2len, + const unsigned char *coeffdata, + unsigned long coefflen) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_RSAKEY_BLOB *rsakey; + LPCWSTR lpszBlobType; + unsigned char *key; + unsigned long keylen, offset, mlen, p1len = 0, p2len = 0; + int ret; + + mlen = max(_libssh2_wincng_bn_size(ndata, nlen), + _libssh2_wincng_bn_size(ddata, dlen)); + offset = sizeof(BCRYPT_RSAKEY_BLOB); + keylen = offset + elen + mlen; + if(ddata && dlen > 0) { + p1len = max(_libssh2_wincng_bn_size(pdata, plen), + _libssh2_wincng_bn_size(e1data, e1len)); + p2len = max(_libssh2_wincng_bn_size(qdata, qlen), + _libssh2_wincng_bn_size(e2data, e2len)); + keylen += p1len * 3 + p2len * 2 + mlen; + } + + key = malloc(keylen); + if(!key) { + return -1; + } + + memset(key, 0, keylen); + + + /* https://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ + rsakey = (BCRYPT_RSAKEY_BLOB *)key; + rsakey->BitLength = mlen * 8; + rsakey->cbPublicExp = elen; + rsakey->cbModulus = mlen; + + memcpy(key + offset, edata, elen); + offset += elen; + + if(nlen < mlen) + memcpy(key + offset + mlen - nlen, ndata, nlen); + else + memcpy(key + offset, ndata + nlen - mlen, mlen); + + if(ddata && dlen > 0) { + offset += mlen; + + if(plen < p1len) + memcpy(key + offset + p1len - plen, pdata, plen); + else + memcpy(key + offset, pdata + plen - p1len, p1len); + offset += p1len; + + if(qlen < p2len) + memcpy(key + offset + p2len - qlen, qdata, qlen); + else + memcpy(key + offset, qdata + qlen - p2len, p2len); + offset += p2len; + + if(e1len < p1len) + memcpy(key + offset + p1len - e1len, e1data, e1len); + else + memcpy(key + offset, e1data + e1len - p1len, p1len); + offset += p1len; + + if(e2len < p2len) + memcpy(key + offset + p2len - e2len, e2data, e2len); + else + memcpy(key + offset, e2data + e2len - p2len, p2len); + offset += p2len; + + if(coefflen < p1len) + memcpy(key + offset + p1len - coefflen, coeffdata, coefflen); + else + memcpy(key + offset, coeffdata + coefflen - p1len, p1len); + offset += p1len; + + if(dlen < mlen) + memcpy(key + offset + mlen - dlen, ddata, dlen); + else + memcpy(key + offset, ddata + dlen - mlen, mlen); + + lpszBlobType = BCRYPT_RSAFULLPRIVATE_BLOB; + rsakey->Magic = BCRYPT_RSAFULLPRIVATE_MAGIC; + rsakey->cbPrime1 = p1len; + rsakey->cbPrime2 = p2len; + } + else { + lpszBlobType = BCRYPT_RSAPUBLIC_BLOB; + rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; + rsakey->cbPrime1 = 0; + rsakey->cbPrime2 = 0; + } + + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, lpszBlobType, + &hKey, key, keylen, 0); + if(!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + + *rsa = malloc(sizeof(libssh2_rsa_ctx)); + if(!(*rsa)) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + (*rsa)->hKey = hKey; + (*rsa)->pbKeyObject = key; + (*rsa)->cbKeyObject = keylen; + + return 0; +} + +#ifdef HAVE_LIBCRYPT32 +static int +_libssh2_wincng_rsa_new_private_parse(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + unsigned char *pbEncoded, + unsigned long cbEncoded) +{ + BCRYPT_KEY_HANDLE hKey; + unsigned char *pbStructInfo; + unsigned long cbStructInfo; + int ret; + + (void)session; + + ret = _libssh2_wincng_asn_decode(pbEncoded, cbEncoded, + PKCS_RSA_PRIVATE_KEY, + &pbStructInfo, &cbStructInfo); + + _libssh2_wincng_safe_free(pbEncoded, cbEncoded); + + if(ret) { + return -1; + } + + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, + LEGACY_RSAPRIVATE_BLOB, &hKey, + pbStructInfo, cbStructInfo, 0); + if(!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(pbStructInfo, cbStructInfo); + return -1; + } + + + *rsa = malloc(sizeof(libssh2_rsa_ctx)); + if(!(*rsa)) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(pbStructInfo, cbStructInfo); + return -1; + } + + (*rsa)->hKey = hKey; + (*rsa)->pbKeyObject = pbStructInfo; + (*rsa)->cbKeyObject = cbStructInfo; + + return 0; +} +#endif /* HAVE_LIBCRYPT32 */ + +int +_libssh2_wincng_rsa_new_private(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + (void)session; + + ret = _libssh2_wincng_load_private(session, filename, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 1, 0); + if(ret) { + return -1; + } + + return _libssh2_wincng_rsa_new_private_parse(rsa, session, + pbEncoded, cbEncoded); +#else + (void)rsa; + (void)filename; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to load RSA key from private key file: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + (void)session; + + ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 1, 0); + if(ret) { + return -1; + } + + return _libssh2_wincng_rsa_new_private_parse(rsa, session, + pbEncoded, cbEncoded); +#else + (void)rsa; + (void)filedata; + (void)filedata_len; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_rsa_sha1_verify(libssh2_rsa_ctx *rsa, + const unsigned char *sig, + unsigned long sig_len, + const unsigned char *m, + unsigned long m_len) +{ + return _libssh2_wincng_key_sha1_verify(rsa, sig, sig_len, m, m_len, + BCRYPT_PAD_PKCS1); +} + +int +_libssh2_wincng_rsa_sha1_sign(LIBSSH2_SESSION *session, + libssh2_rsa_ctx *rsa, + const unsigned char *hash, + size_t hash_len, + unsigned char **signature, + size_t *signature_len) +{ + BCRYPT_PKCS1_PADDING_INFO paddingInfo; + unsigned char *data, *sig; + unsigned long cbData, datalen, siglen; + int ret; + + datalen = (unsigned long)hash_len; + data = malloc(datalen); + if(!data) { + return -1; + } + + paddingInfo.pszAlgId = BCRYPT_SHA1_ALGORITHM; + + memcpy(data, hash, datalen); + + ret = BCryptSignHash(rsa->hKey, &paddingInfo, + data, datalen, NULL, 0, + &cbData, BCRYPT_PAD_PKCS1); + if(BCRYPT_SUCCESS(ret)) { + siglen = cbData; + sig = LIBSSH2_ALLOC(session, siglen); + if(sig) { + ret = BCryptSignHash(rsa->hKey, &paddingInfo, + data, datalen, sig, siglen, + &cbData, BCRYPT_PAD_PKCS1); + if(BCRYPT_SUCCESS(ret)) { + *signature_len = siglen; + *signature = sig; + } + else { + LIBSSH2_FREE(session, sig); + } + } + else + ret = STATUS_NO_MEMORY; + } + + _libssh2_wincng_safe_free(data, datalen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa) +{ + if(!rsa) + return; + + BCryptDestroyKey(rsa->hKey); + rsa->hKey = NULL; + + _libssh2_wincng_safe_free(rsa->pbKeyObject, rsa->cbKeyObject); + _libssh2_wincng_safe_free(rsa, sizeof(libssh2_rsa_ctx)); +} + + +/*******************************************************************/ +/* + * Windows CNG backend: DSA functions + */ + +#if LIBSSH2_DSA +int +_libssh2_wincng_dsa_new(libssh2_dsa_ctx **dsa, + const unsigned char *pdata, + unsigned long plen, + const unsigned char *qdata, + unsigned long qlen, + const unsigned char *gdata, + unsigned long glen, + const unsigned char *ydata, + unsigned long ylen, + const unsigned char *xdata, + unsigned long xlen) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_DSA_KEY_BLOB *dsakey; + LPCWSTR lpszBlobType; + unsigned char *key; + unsigned long keylen, offset, length; + int ret; + + length = max(max(_libssh2_wincng_bn_size(pdata, plen), + _libssh2_wincng_bn_size(gdata, glen)), + _libssh2_wincng_bn_size(ydata, ylen)); + offset = sizeof(BCRYPT_DSA_KEY_BLOB); + keylen = offset + length * 3; + if(xdata && xlen > 0) + keylen += 20; + + key = malloc(keylen); + if(!key) { + return -1; + } + + memset(key, 0, keylen); + + + /* https://msdn.microsoft.com/library/windows/desktop/aa833126.aspx */ + dsakey = (BCRYPT_DSA_KEY_BLOB *)key; + dsakey->cbKey = length; + + memset(dsakey->Count, -1, sizeof(dsakey->Count)); + memset(dsakey->Seed, -1, sizeof(dsakey->Seed)); + + if(qlen < 20) + memcpy(dsakey->q + 20 - qlen, qdata, qlen); + else + memcpy(dsakey->q, qdata + qlen - 20, 20); + + if(plen < length) + memcpy(key + offset + length - plen, pdata, plen); + else + memcpy(key + offset, pdata + plen - length, length); + offset += length; + + if(glen < length) + memcpy(key + offset + length - glen, gdata, glen); + else + memcpy(key + offset, gdata + glen - length, length); + offset += length; + + if(ylen < length) + memcpy(key + offset + length - ylen, ydata, ylen); + else + memcpy(key + offset, ydata + ylen - length, length); + + if(xdata && xlen > 0) { + offset += length; + + if(xlen < 20) + memcpy(key + offset + 20 - xlen, xdata, xlen); + else + memcpy(key + offset, xdata + xlen - 20, 20); + + lpszBlobType = BCRYPT_DSA_PRIVATE_BLOB; + dsakey->dwMagic = BCRYPT_DSA_PRIVATE_MAGIC; + } + else { + lpszBlobType = BCRYPT_DSA_PUBLIC_BLOB; + dsakey->dwMagic = BCRYPT_DSA_PUBLIC_MAGIC; + } + + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgDSA, NULL, lpszBlobType, + &hKey, key, keylen, 0); + if(!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + + *dsa = malloc(sizeof(libssh2_dsa_ctx)); + if(!(*dsa)) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(key, keylen); + return -1; + } + + (*dsa)->hKey = hKey; + (*dsa)->pbKeyObject = key; + (*dsa)->cbKeyObject = keylen; + + return 0; +} + +#ifdef HAVE_LIBCRYPT32 +static int +_libssh2_wincng_dsa_new_private_parse(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + unsigned char *pbEncoded, + unsigned long cbEncoded) +{ + unsigned char **rpbDecoded; + unsigned long *rcbDecoded, index, length; + int ret; + + (void)session; + + ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, + &rpbDecoded, &rcbDecoded, &length); + + _libssh2_wincng_safe_free(pbEncoded, cbEncoded); + + if(ret) { + return -1; + } + + + if(length == 6) { + ret = _libssh2_wincng_dsa_new(dsa, + rpbDecoded[1], rcbDecoded[1], + rpbDecoded[2], rcbDecoded[2], + rpbDecoded[3], rcbDecoded[3], + rpbDecoded[4], rcbDecoded[4], + rpbDecoded[5], rcbDecoded[5]); + } + else { + ret = -1; + } + + for(index = 0; index < length; index++) { + _libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]); + rpbDecoded[index] = NULL; + rcbDecoded[index] = 0; + } + + free(rpbDecoded); + free(rcbDecoded); + + return ret; +} +#endif /* HAVE_LIBCRYPT32 */ + +int +_libssh2_wincng_dsa_new_private(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filename, + const unsigned char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private(session, filename, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 0, 1); + if(ret) { + return -1; + } + + return _libssh2_wincng_dsa_new_private_parse(dsa, session, + pbEncoded, cbEncoded); +#else + (void)dsa; + (void)filename; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to load DSA key from private key file: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_dsa_new_private_frommemory(libssh2_dsa_ctx **dsa, + LIBSSH2_SESSION *session, + const char *filedata, + size_t filedata_len, + unsigned const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private_memory(session, filedata, filedata_len, + (const char *)passphrase, + &pbEncoded, &cbEncoded, 0, 1); + if(ret) { + return -1; + } + + return _libssh2_wincng_dsa_new_private_parse(dsa, session, + pbEncoded, cbEncoded); +#else + (void)dsa; + (void)filedata; + (void)filedata_len; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract private key from memory: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_dsa_sha1_verify(libssh2_dsa_ctx *dsa, + const unsigned char *sig_fixed, + const unsigned char *m, + unsigned long m_len) +{ + return _libssh2_wincng_key_sha1_verify(dsa, sig_fixed, 40, m, m_len, 0); +} + +int +_libssh2_wincng_dsa_sha1_sign(libssh2_dsa_ctx *dsa, + const unsigned char *hash, + unsigned long hash_len, + unsigned char *sig_fixed) +{ + unsigned char *data, *sig; + unsigned long cbData, datalen, siglen; + int ret; + + datalen = hash_len; + data = malloc(datalen); + if(!data) { + return -1; + } + + memcpy(data, hash, datalen); + + ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, + NULL, 0, &cbData, 0); + if(BCRYPT_SUCCESS(ret)) { + siglen = cbData; + if(siglen == 40) { + sig = malloc(siglen); + if(sig) { + ret = BCryptSignHash(dsa->hKey, NULL, data, datalen, + sig, siglen, &cbData, 0); + if(BCRYPT_SUCCESS(ret)) { + memcpy(sig_fixed, sig, siglen); + } + + _libssh2_wincng_safe_free(sig, siglen); + } + else + ret = STATUS_NO_MEMORY; + } + else + ret = STATUS_NO_MEMORY; + } + + _libssh2_wincng_safe_free(data, datalen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa) +{ + if(!dsa) + return; + + BCryptDestroyKey(dsa->hKey); + dsa->hKey = NULL; + + _libssh2_wincng_safe_free(dsa->pbKeyObject, dsa->cbKeyObject); + _libssh2_wincng_safe_free(dsa, sizeof(libssh2_dsa_ctx)); +} +#endif + + +/*******************************************************************/ +/* + * Windows CNG backend: Key functions + */ + +#ifdef HAVE_LIBCRYPT32 +static unsigned long +_libssh2_wincng_pub_priv_write(unsigned char *key, + unsigned long offset, + const unsigned char *bignum, + const unsigned long length) +{ + _libssh2_htonu32(key + offset, length); + offset += 4; + + memcpy(key + offset, bignum, length); + offset += length; + + return offset; +} + +static int +_libssh2_wincng_pub_priv_keyfile_parse(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + unsigned char *pbEncoded, + unsigned long cbEncoded) +{ + unsigned char **rpbDecoded; + unsigned long *rcbDecoded; + unsigned char *key = NULL, *mth = NULL; + unsigned long keylen = 0, mthlen = 0; + unsigned long index, offset, length; + int ret; + + ret = _libssh2_wincng_asn_decode_bns(pbEncoded, cbEncoded, + &rpbDecoded, &rcbDecoded, &length); + + _libssh2_wincng_safe_free(pbEncoded, cbEncoded); + + if(ret) { + return -1; + } + + + if(length == 9) { /* private RSA key */ + mthlen = 7; + mth = LIBSSH2_ALLOC(session, mthlen); + if(mth) { + memcpy(mth, "ssh-rsa", mthlen); + } + else { + ret = -1; + } + + + keylen = 4 + mthlen + 4 + rcbDecoded[2] + 4 + rcbDecoded[1]; + key = LIBSSH2_ALLOC(session, keylen); + if(key) { + offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[2], + rcbDecoded[2]); + + _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[1], + rcbDecoded[1]); + } + else { + ret = -1; + } + + } + else if(length == 6) { /* private DSA key */ + mthlen = 7; + mth = LIBSSH2_ALLOC(session, mthlen); + if(mth) { + memcpy(mth, "ssh-dss", mthlen); + } + else { + ret = -1; + } + + keylen = 4 + mthlen + 4 + rcbDecoded[1] + 4 + rcbDecoded[2] + + 4 + rcbDecoded[3] + 4 + rcbDecoded[4]; + key = LIBSSH2_ALLOC(session, keylen); + if(key) { + offset = _libssh2_wincng_pub_priv_write(key, 0, mth, mthlen); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[1], + rcbDecoded[1]); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[2], + rcbDecoded[2]); + + offset = _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[3], + rcbDecoded[3]); + + _libssh2_wincng_pub_priv_write(key, offset, + rpbDecoded[4], + rcbDecoded[4]); + } + else { + ret = -1; + } + + } + else { + ret = -1; + } + + + for(index = 0; index < length; index++) { + _libssh2_wincng_safe_free(rpbDecoded[index], rcbDecoded[index]); + rpbDecoded[index] = NULL; + rcbDecoded[index] = 0; + } + + free(rpbDecoded); + free(rcbDecoded); + + + if(ret) { + if(mth) + LIBSSH2_FREE(session, mth); + if(key) + LIBSSH2_FREE(session, key); + } + else { + *method = mth; + *method_len = mthlen; + *pubkeydata = key; + *pubkeydata_len = keylen; + } + + return ret; +} +#endif /* HAVE_LIBCRYPT32 */ + +int +_libssh2_wincng_pub_priv_keyfile(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekey, + const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private(session, privatekey, passphrase, + &pbEncoded, &cbEncoded, 1, 1); + if(ret) { + return -1; + } + + return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len, + pubkeydata, pubkeydata_len, + pbEncoded, cbEncoded); +#else + (void)method; + (void)method_len; + (void)pubkeydata; + (void)pubkeydata_len; + (void)privatekey; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_FILE, + "Unable to load public key from private key file: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +int +_libssh2_wincng_pub_priv_keyfilememory(LIBSSH2_SESSION *session, + unsigned char **method, + size_t *method_len, + unsigned char **pubkeydata, + size_t *pubkeydata_len, + const char *privatekeydata, + size_t privatekeydata_len, + const char *passphrase) +{ +#ifdef HAVE_LIBCRYPT32 + unsigned char *pbEncoded; + unsigned long cbEncoded; + int ret; + + ret = _libssh2_wincng_load_private_memory(session, privatekeydata, + privatekeydata_len, passphrase, + &pbEncoded, &cbEncoded, 1, 1); + if(ret) { + return -1; + } + + return _libssh2_wincng_pub_priv_keyfile_parse(session, method, method_len, + pubkeydata, pubkeydata_len, + pbEncoded, cbEncoded); +#else + (void)method; + (void)method_len; + (void)pubkeydata_len; + (void)pubkeydata; + (void)privatekeydata; + (void)privatekeydata_len; + (void)passphrase; + + return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED, + "Unable to extract public key from private key in memory: " + "Method unsupported in Windows CNG backend"); +#endif /* HAVE_LIBCRYPT32 */ +} + +/*******************************************************************/ +/* + * Windows CNG backend: Cipher functions + */ + +int +_libssh2_wincng_cipher_init(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + unsigned char *iv, + unsigned char *secret, + int encrypt) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_KEY_DATA_BLOB_HEADER *header; + unsigned char *pbKeyObject, *pbIV, *key, *pbCtr, *pbIVCopy; + unsigned long dwKeyObject, dwIV, dwCtrLength, dwBlockLength, + cbData, keylen; + int ret; + + (void)encrypt; + + ret = BCryptGetProperty(*type.phAlg, BCRYPT_OBJECT_LENGTH, + (unsigned char *)&dwKeyObject, + sizeof(dwKeyObject), + &cbData, 0); + if(!BCRYPT_SUCCESS(ret)) { + return -1; + } + + ret = BCryptGetProperty(*type.phAlg, BCRYPT_BLOCK_LENGTH, + (unsigned char *)&dwBlockLength, + sizeof(dwBlockLength), + &cbData, 0); + if(!BCRYPT_SUCCESS(ret)) { + return -1; + } + + pbKeyObject = malloc(dwKeyObject); + if(!pbKeyObject) { + return -1; + } + + + keylen = sizeof(BCRYPT_KEY_DATA_BLOB_HEADER) + type.dwKeyLength; + key = malloc(keylen); + if(!key) { + free(pbKeyObject); + return -1; + } + + + header = (BCRYPT_KEY_DATA_BLOB_HEADER *)key; + header->dwMagic = BCRYPT_KEY_DATA_BLOB_MAGIC; + header->dwVersion = BCRYPT_KEY_DATA_BLOB_VERSION1; + header->cbKeyData = type.dwKeyLength; + + memcpy(key + sizeof(BCRYPT_KEY_DATA_BLOB_HEADER), + secret, type.dwKeyLength); + + ret = BCryptImportKey(*type.phAlg, NULL, BCRYPT_KEY_DATA_BLOB, &hKey, + pbKeyObject, dwKeyObject, key, keylen, 0); + + _libssh2_wincng_safe_free(key, keylen); + + if(!BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); + return -1; + } + + pbIV = NULL; + pbCtr = NULL; + dwIV = 0; + dwCtrLength = 0; + + if(type.useIV || type.ctrMode) { + pbIVCopy = malloc(dwBlockLength); + if(!pbIVCopy) { + BCryptDestroyKey(hKey); + _libssh2_wincng_safe_free(pbKeyObject, dwKeyObject); + return -1; + } + memcpy(pbIVCopy, iv, dwBlockLength); + + if(type.ctrMode) { + pbCtr = pbIVCopy; + dwCtrLength = dwBlockLength; + } + else if(type.useIV) { + pbIV = pbIVCopy; + dwIV = dwBlockLength; + } + } + + ctx->hKey = hKey; + ctx->pbKeyObject = pbKeyObject; + ctx->pbIV = pbIV; + ctx->pbCtr = pbCtr; + ctx->dwKeyObject = dwKeyObject; + ctx->dwIV = dwIV; + ctx->dwBlockLength = dwBlockLength; + ctx->dwCtrLength = dwCtrLength; + + return 0; +} +int +_libssh2_wincng_cipher_crypt(_libssh2_cipher_ctx *ctx, + _libssh2_cipher_type(type), + int encrypt, + unsigned char *block, + size_t blocklen) +{ + unsigned char *pbOutput, *pbInput; + unsigned long cbOutput, cbInput; + int ret; + + (void)type; + + cbInput = (unsigned long)blocklen; + + if(type.ctrMode) { + pbInput = ctx->pbCtr; + } + else { + pbInput = block; + } + + if(encrypt || type.ctrMode) { + ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL, + ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); + } + else { + ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL, + ctx->pbIV, ctx->dwIV, NULL, 0, &cbOutput, 0); + } + if(BCRYPT_SUCCESS(ret)) { + pbOutput = malloc(cbOutput); + if(pbOutput) { + if(encrypt || type.ctrMode) { + ret = BCryptEncrypt(ctx->hKey, pbInput, cbInput, NULL, + ctx->pbIV, ctx->dwIV, + pbOutput, cbOutput, &cbOutput, 0); + } + else { + ret = BCryptDecrypt(ctx->hKey, pbInput, cbInput, NULL, + ctx->pbIV, ctx->dwIV, + pbOutput, cbOutput, &cbOutput, 0); + } + if(BCRYPT_SUCCESS(ret)) { + if(type.ctrMode) { + _libssh2_xor_data(block, block, pbOutput, blocklen); + _libssh2_aes_ctr_increment(ctx->pbCtr, ctx->dwCtrLength); + } + else { + memcpy(block, pbOutput, cbOutput); + } + } + + _libssh2_wincng_safe_free(pbOutput, cbOutput); + } + else + ret = STATUS_NO_MEMORY; + } + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +void +_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx) +{ + BCryptDestroyKey(ctx->hKey); + ctx->hKey = NULL; + + _libssh2_wincng_safe_free(ctx->pbKeyObject, ctx->dwKeyObject); + ctx->pbKeyObject = NULL; + ctx->dwKeyObject = 0; + + _libssh2_wincng_safe_free(ctx->pbIV, ctx->dwBlockLength); + ctx->pbIV = NULL; + ctx->dwBlockLength = 0; + + _libssh2_wincng_safe_free(ctx->pbCtr, ctx->dwCtrLength); + ctx->pbCtr = NULL; + ctx->dwCtrLength = 0; +} + + +/*******************************************************************/ +/* + * Windows CNG backend: BigNumber functions + */ + +_libssh2_bn * +_libssh2_wincng_bignum_init(void) +{ + _libssh2_bn *bignum; + + bignum = (_libssh2_bn *)malloc(sizeof(_libssh2_bn)); + if(bignum) { + bignum->bignum = NULL; + bignum->length = 0; + } + + return bignum; +} + +static int +_libssh2_wincng_bignum_resize(_libssh2_bn *bn, unsigned long length) +{ + unsigned char *bignum; + + if(!bn) + return -1; + + if(length == bn->length) + return 0; + +#ifdef LIBSSH2_CLEAR_MEMORY + if(bn->bignum && bn->length > 0 && length < bn->length) { + SecureZeroMemory(bn->bignum + length, bn->length - length); + } +#endif + + bignum = realloc(bn->bignum, length); + if(!bignum) + return -1; + + bn->bignum = bignum; + bn->length = length; + + return 0; +} + +static int +_libssh2_wincng_bignum_rand(_libssh2_bn *rnd, int bits, int top, int bottom) +{ + unsigned char *bignum; + unsigned long length; + + if(!rnd) + return -1; + + length = (unsigned long) (ceil(((double)bits) / 8.0) * + sizeof(unsigned char)); + if(_libssh2_wincng_bignum_resize(rnd, length)) + return -1; + + bignum = rnd->bignum; + + if(_libssh2_wincng_random(bignum, length)) + return -1; + + /* calculate significant bits in most significant byte */ + bits %= 8; + + /* fill most significant byte with zero padding */ + bignum[0] &= (1 << (8 - bits)) - 1; + + /* set some special last bits in most significant byte */ + if(top == 0) + bignum[0] |= (1 << (7 - bits)); + else if(top == 1) + bignum[0] |= (3 << (6 - bits)); + + /* make odd by setting first bit in least significant byte */ + if(bottom) + bignum[length - 1] |= 1; + + return 0; +} + +static int +_libssh2_wincng_bignum_mod_exp(_libssh2_bn *r, + _libssh2_bn *a, + _libssh2_bn *p, + _libssh2_bn *m) +{ + BCRYPT_KEY_HANDLE hKey; + BCRYPT_RSAKEY_BLOB *rsakey; + unsigned char *key, *bignum; + unsigned long keylen, offset, length; + int ret; + + if(!r || !a || !p || !m) + return -1; + + offset = sizeof(BCRYPT_RSAKEY_BLOB); + keylen = offset + p->length + m->length; + + key = malloc(keylen); + if(!key) + return -1; + + + /* https://msdn.microsoft.com/library/windows/desktop/aa375531.aspx */ + rsakey = (BCRYPT_RSAKEY_BLOB *)key; + rsakey->Magic = BCRYPT_RSAPUBLIC_MAGIC; + rsakey->BitLength = m->length * 8; + rsakey->cbPublicExp = p->length; + rsakey->cbModulus = m->length; + rsakey->cbPrime1 = 0; + rsakey->cbPrime2 = 0; + + memcpy(key + offset, p->bignum, p->length); + offset += p->length; + + memcpy(key + offset, m->bignum, m->length); + + ret = BCryptImportKeyPair(_libssh2_wincng.hAlgRSA, NULL, + BCRYPT_RSAPUBLIC_BLOB, &hKey, key, keylen, 0); + if(BCRYPT_SUCCESS(ret)) { + ret = BCryptEncrypt(hKey, a->bignum, a->length, NULL, NULL, 0, + NULL, 0, &length, BCRYPT_PAD_NONE); + if(BCRYPT_SUCCESS(ret)) { + if(!_libssh2_wincng_bignum_resize(r, length)) { + length = max(a->length, length); + bignum = malloc(length); + if(bignum) { + offset = length - a->length; + memset(bignum, 0, offset); + memcpy(bignum + offset, a->bignum, a->length); + + ret = BCryptEncrypt(hKey, bignum, length, NULL, NULL, 0, + r->bignum, r->length, &offset, + BCRYPT_PAD_NONE); + + _libssh2_wincng_safe_free(bignum, length); + + if(BCRYPT_SUCCESS(ret)) { + _libssh2_wincng_bignum_resize(r, offset); + } + } + else + ret = STATUS_NO_MEMORY; + } + else + ret = STATUS_NO_MEMORY; + } + + BCryptDestroyKey(hKey); + } + + _libssh2_wincng_safe_free(key, keylen); + + return BCRYPT_SUCCESS(ret) ? 0 : -1; +} + +int +_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, unsigned long word) +{ + unsigned long offset, number, bits, length; + + if(!bn) + return -1; + + bits = 0; + number = word; + while(number >>= 1) + bits++; + bits++; + + length = (unsigned long) (ceil(((double)bits) / 8.0) * + sizeof(unsigned char)); + if(_libssh2_wincng_bignum_resize(bn, length)) + return -1; + + for(offset = 0; offset < length; offset++) + bn->bignum[offset] = (word >> (offset * 8)) & 0xff; + + return 0; +} + +unsigned long +_libssh2_wincng_bignum_bits(const _libssh2_bn *bn) +{ + unsigned char number; + unsigned long offset, length, bits; + + if(!bn || !bn->bignum || !bn->length) + return 0; + + offset = 0; + length = bn->length - 1; + while(!bn->bignum[offset] && offset < length) + offset++; + + bits = (length - offset) * 8; + number = bn->bignum[offset]; + while(number >>= 1) + bits++; + bits++; + + return bits; +} + +void +_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, unsigned long len, + const unsigned char *bin) +{ + unsigned char *bignum; + unsigned long offset, length, bits; + + if(!bn || !bin || !len) + return; + + if(_libssh2_wincng_bignum_resize(bn, len)) + return; + + memcpy(bn->bignum, bin, len); + + bits = _libssh2_wincng_bignum_bits(bn); + length = (unsigned long) (ceil(((double)bits) / 8.0) * + sizeof(unsigned char)); + + offset = bn->length - length; + if(offset > 0) { + memmove(bn->bignum, bn->bignum + offset, length); + +#ifdef LIBSSH2_CLEAR_MEMORY + SecureZeroMemory(bn->bignum + length, offset); +#endif + + bignum = realloc(bn->bignum, length); + if(bignum) { + bn->bignum = bignum; + bn->length = length; + } + } +} + +void +_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin) +{ + if(bin && bn && bn->bignum && bn->length > 0) { + memcpy(bin, bn->bignum, bn->length); + } +} + +void +_libssh2_wincng_bignum_free(_libssh2_bn *bn) +{ + if(bn) { + if(bn->bignum) { + _libssh2_wincng_safe_free(bn->bignum, bn->length); + bn->bignum = NULL; + } + bn->length = 0; + _libssh2_wincng_safe_free(bn, sizeof(_libssh2_bn)); + } +} + + +/* + * Windows CNG backend: Diffie-Hellman support. + */ + +void +_libssh2_dh_init(_libssh2_dh_ctx *dhctx) +{ + *dhctx = _libssh2_wincng_bignum_init(); /* Random from client */ +} + +int +_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, + _libssh2_bn *g, _libssh2_bn *p, int group_order) +{ + /* Generate x and e */ + if(_libssh2_wincng_bignum_rand(*dhctx, group_order * 8 - 1, 0, -1)) + return -1; + if(_libssh2_wincng_bignum_mod_exp(public, g, *dhctx, p)) + return -1; + return 0; +} + +int +_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, + _libssh2_bn *f, _libssh2_bn *p) +{ + /* Compute the shared secret */ + return _libssh2_wincng_bignum_mod_exp(secret, f, *dhctx, p); +} + +void +_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) +{ + _libssh2_wincng_bignum_free(*dhctx); + *dhctx = NULL; +} + +#endif /* LIBSSH2_WINCNG */ diff --git a/ogl/basic.cpp b/ogl/basic.cpp new file mode 100644 index 0000000..d4ef7cd --- /dev/null +++ b/ogl/basic.cpp @@ -0,0 +1,3217 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basic.cpp - Basic OGL classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +IMPLEMENT_DYNAMIC_CLASS(wxShapeTextLine, wxObject) +IMPLEMENT_DYNAMIC_CLASS(wxAttachmentPoint, wxObject) + +wxShapeTextLine::wxShapeTextLine(double the_x, double the_y, const wxString &the_line) +{ + m_x = the_x; + m_y = the_y; + m_line = the_line; +} + +wxShapeTextLine::~wxShapeTextLine() +{ +} + +IMPLEMENT_ABSTRACT_CLASS(wxShapeEvtHandler, wxObject) + +wxShapeEvtHandler::wxShapeEvtHandler(wxShapeEvtHandler *prev, wxShape *shape) +{ + m_previousHandler = prev; + m_handlerShape = shape; +} + +wxShapeEvtHandler::~wxShapeEvtHandler() +{ +} + +// Creates a copy of this event handler. +wxShapeEvtHandler *wxShapeEvtHandler::CreateNewCopy() +{ + wxShapeEvtHandler *newObject = (wxShapeEvtHandler *) GetClassInfo()->CreateObject(); + + wxASSERT( (newObject != NULL) ); + wxASSERT( (newObject->IsKindOf(CLASSINFO(wxShapeEvtHandler))) ); + + newObject->m_previousHandler = newObject; + + CopyData(*newObject); + + return newObject; +} + + +void wxShapeEvtHandler::OnDelete() +{ + if (this != GetShape()) + delete this; +} + +void wxShapeEvtHandler::OnDraw(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnDraw(dc); +} + +void wxShapeEvtHandler::OnMoveLinks() +{ + if (m_previousHandler) + m_previousHandler->OnMoveLinks(); +} + +void wxShapeEvtHandler::OnMoveLink(bool moveControlPoints) +{ + if (m_previousHandler) + m_previousHandler->OnMoveLink(moveControlPoints); +} + +void wxShapeEvtHandler::OnDrawContents(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnDrawContents(dc); +} + +void wxShapeEvtHandler::OnDrawBranches(wxDC &dc, bool erase) +{ + if (m_previousHandler) + m_previousHandler->OnDrawBranches(dc, erase); +} + +void wxShapeEvtHandler::OnSize(double x, double y) +{ + if (m_previousHandler) + m_previousHandler->OnSize(x, y); +} + +bool wxShapeEvtHandler::OnMovePre(double x, double y, double old_x, double old_y, bool display) +{ + if (m_previousHandler) + return m_previousHandler->OnMovePre(x, y, old_x, old_y, display); + else + return TRUE; +} + +void wxShapeEvtHandler::OnMovePost(double x, double y, double old_x, double old_y, bool display) +{ + if (m_previousHandler) + m_previousHandler->OnMovePost(x, y, old_x, old_y, display); +} + +void wxShapeEvtHandler::OnHighlight(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnHighlight(dc); +} + +void wxShapeEvtHandler::OnLeftClick(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnLeftClick(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnLeftDoubleClick(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnLeftDoubleClick(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnRightClick(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnRightClick(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnDragLeft(draw, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnBeginDragLeft(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnEndDragLeft(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnDragRight(bool draw, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnDragRight(draw, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnBeginDragRight(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnBeginDragRight(x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnEndDragRight(double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnEndDragRight(x, y, keys, attachment); +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxShapeEvtHandler::OnSizingDragLeft(wxControlPoint *pt, bool draw, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnSizingDragLeft(pt, draw, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnSizingBeginDragLeft(pt, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int keys, int attachment) +{ + if (m_previousHandler) + m_previousHandler->OnSizingEndDragLeft(pt, x, y, keys, attachment); +} + +void wxShapeEvtHandler::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + if (m_previousHandler) + m_previousHandler->OnDrawOutline(dc, x, y, w, h); +} + +void wxShapeEvtHandler::OnDrawControlPoints(wxDC &dc) +{ + if (m_previousHandler) + m_previousHandler->OnDrawControlPoints(dc); +} + +// Can override this to prevent or intercept line reordering. +void wxShapeEvtHandler::OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering) +{ + if (m_previousHandler) + m_previousHandler->OnChangeAttachment(attachment, line, ordering); +} + +IMPLEMENT_ABSTRACT_CLASS(wxShape, wxShapeEvtHandler) + +wxShape::wxShape(wxShapeCanvas *can) +{ + m_eventHandler = this; + SetShape(this); + m_id = 0; + m_formatted = FALSE; + m_canvas = can; + m_xpos = 0.0; + m_ypos = 0.0; + m_pen = g_oglBlackPen; + m_brush = (wxBrush *) wxWHITE_BRUSH; + m_font = g_oglNormalFont; + m_textColour = * wxBLACK; + m_textColourName = wxT("BLACK"); + m_visible = FALSE; + m_selected = FALSE; + m_attachmentMode = ATTACHMENT_MODE_NONE; + m_spaceAttachments = TRUE; + m_disableLabel = FALSE; + m_fixedWidth = FALSE; + m_fixedHeight = FALSE; + m_drawHandles = TRUE; + m_sensitivity = OP_ALL; + m_draggable = TRUE; + m_parent = NULL; + m_formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT; + m_shadowMode = SHADOW_NONE; + m_shadowOffsetX = 6; + m_shadowOffsetY = 6; + m_shadowBrush = (wxBrush *) wxBLACK_BRUSH; + m_textMarginX = 5; + m_textMarginY = 5; + m_regionName = wxT("0"); + m_centreResize = TRUE; + m_maintainAspectRatio = FALSE; + m_highlighted = FALSE; + m_rotation = 0.0; + m_branchNeckLength = 10; + m_branchStemLength = 10; + m_branchSpacing = 10; + m_branchStyle = BRANCHING_ATTACHMENT_NORMAL; + + // Set up a default region. Much of the above will be put into + // the region eventually (the duplication is for compatibility) + wxShapeRegion *region = new wxShapeRegion; + m_regions.Append(region); + region->SetName(wxT("0")); + region->SetFont(g_oglNormalFont); + region->SetFormatMode(FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT); + region->SetColour(wxString(wxT("BLACK"))); +} + +wxShape::~wxShape() +{ + if (m_parent) + m_parent->GetChildren().DeleteObject(this); + + ClearText(); + ClearRegions(); + ClearAttachments(); + + if (m_canvas) + m_canvas->RemoveShape(this); + + GetEventHandler()->OnDelete(); +} + +void wxShape::SetHighlight(bool hi, bool recurse) +{ + m_highlighted = hi; + if (recurse) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->SetHighlight(hi, recurse); + node = node->GetNext(); + } + } +} + +void wxShape::SetSensitivityFilter(int sens, bool recursive) +{ + if (sens & OP_DRAG_LEFT) + m_draggable = TRUE; + else + m_draggable = FALSE; + + m_sensitivity = sens; + if (recursive) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *obj = (wxShape *)node->GetData(); + obj->SetSensitivityFilter(sens, TRUE); + node = node->GetNext(); + } + } +} + +void wxShape::SetDraggable(bool drag, bool recursive) +{ + m_draggable = drag; + if (m_draggable) + m_sensitivity |= OP_DRAG_LEFT; + else if (m_sensitivity & OP_DRAG_LEFT) + m_sensitivity = m_sensitivity - OP_DRAG_LEFT; + + if (recursive) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *obj = (wxShape *)node->GetData(); + obj->SetDraggable(drag, TRUE); + node = node->GetNext(); + } + } +} + +void wxShape::SetDrawHandles(bool drawH) +{ + m_drawHandles = drawH; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *obj = (wxShape *)node->GetData(); + obj->SetDrawHandles(drawH); + node = node->GetNext(); + } +} + +void wxShape::SetShadowMode(int mode, bool redraw) +{ + if (redraw && GetCanvas()) + { + Refresh(); + + m_shadowMode = mode; + + Refresh(); + } + else + { + m_shadowMode = mode; + } +} + +void wxShape::Refresh(wxShapeCanvas *canvas) +{ + if (!canvas) + canvas = m_canvas; + if (canvas) + { + double w, h; + GetBoundingBoxMax(& w, & h); + double x1 = (double)(GetX() - w / 2.0) - canvas->GetCurrentPixelScrollPosition().x; + double y1 = (double)(GetY() - h / 2.0) - canvas->GetCurrentPixelScrollPosition().y; + canvas->RefreshRect(wxRect(WXROUND(x1), WXROUND(y1), WXROUND(w), WXROUND(h))); + } +} + +void wxShape::SetCanvas(wxShapeCanvas *theCanvas) +{ + m_canvas = theCanvas; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->SetCanvas(theCanvas); + node = node->GetNext(); + } +} + +void wxShape::AddToCanvas(wxShapeCanvas *theCanvas, wxShape *addAfter) +{ + theCanvas->AddShape(this, addAfter); + wxNode *node = m_children.GetFirst(); + wxShape *lastImage = this; + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->AddToCanvas(theCanvas, lastImage); + lastImage = object; + + node = node->GetNext(); + } +} + +// Insert at front of canvas +void wxShape::InsertInCanvas(wxShapeCanvas *theCanvas) +{ + theCanvas->InsertShape(this); + wxNode *node = m_children.GetFirst(); + wxShape *lastImage = this; + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->AddToCanvas(theCanvas, lastImage); + lastImage = object; + + node = node->GetNext(); + } +} + +void wxShape::RemoveFromCanvas(wxShapeCanvas *theCanvas) +{ + if (Selected()) + Select(FALSE); + theCanvas->RemoveShape(this); + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->RemoveFromCanvas(theCanvas); + + node = node->GetNext(); + } +} + +void wxShape::ClearAttachments() +{ + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + delete point; + node = node->GetNext(); + } + m_attachmentPoints.Clear(); +} + +void wxShape::ClearText(int regionId) +{ + if (regionId == 0) + { + m_text.DeleteContents(TRUE); + m_text.Clear(); + m_text.DeleteContents(FALSE); + } + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->ClearText(); +} + +void wxShape::ClearRegions() +{ + wxNode *node = m_regions.GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + wxNode *next = node->GetNext(); + delete region; + delete node; + node = next; + } +} + +void wxShape::AddRegion(wxShapeRegion *region) +{ + m_regions.Append(region); +} + +void wxShape::SetDefaultRegionSize() +{ + wxNode *node = m_regions.GetFirst(); + if (!node) return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + double w, h; + GetBoundingBoxMin(&w, &h); + region->SetSize(w, h); +} + +bool wxShape::HitTest(double x, double y, int *attachment, double *distance) +{ +// if (!sensitive) +// return FALSE; + + double width = 0.0, height = 0.0; + GetBoundingBoxMin(&width, &height); + if (fabs(width) < 4.0) width = 4.0; + if (fabs(height) < 4.0) height = 4.0; + + width += (double)4.0; + height += (double)4.0; // Allowance for inaccurate mousing + + double left = (double)(m_xpos - (width / 2.0)); + double top = (double)(m_ypos - (height / 2.0)); + double right = (double)(m_xpos + (width / 2.0)); + double bottom = (double)(m_ypos + (height / 2.0)); + + int nearest_attachment = 0; + + // If within the bounding box, check the attachment points + // within the object. + + if (x >= left && x <= right && y >= top && y <= bottom) + { + int n = GetNumberOfAttachments(); + double nearest = 999999.0; + + // GetAttachmentPosition[Edge] takes a logical attachment position, + // i.e. if it's rotated through 90%, position 0 is East-facing. + + for (int i = 0; i < n; i++) + { + double xp, yp; + if (GetAttachmentPositionEdge(i, &xp, &yp)) + { + double l = (double)sqrt(((xp - x) * (xp - x)) + + ((yp - y) * (yp - y))); + + if (l < nearest) + { + nearest = l; + nearest_attachment = i; + } + } + } + *attachment = nearest_attachment; + *distance = nearest; + return TRUE; + } + else return FALSE; +} + +// Format a text string according to the region size, adding +// strings with positions to region text list + +static bool GraphicsInSizeToContents = FALSE; // Infinite recursion elimination +void wxShape::FormatText(wxDC &dc, const wxString &s, int i) +{ + double w, h; + ClearText(i); + + if (m_regions.GetCount() < 1) + return; + wxNode *node = m_regions.Item(i); + if (!node) + return; + + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + // region->SetText(s); // don't set the formatted text yet, it will be done below + region->m_regionText = s; + dc.SetFont(* region->GetFont()); + + region->GetSize(&w, &h); + + wxArrayString *stringList = oglFormatText(dc, s, (w - 2 * m_textMarginX), (h - 2 * m_textMarginY), region->GetFormatMode()); + size_t j; + for (j = 0; j < stringList->GetCount(); j++) + { + const wxString &s = (*stringList)[j]; + wxShapeTextLine *line = new wxShapeTextLine(0.0, 0.0, s); + region->GetFormattedText().Append((wxObject *)line); + } + delete stringList; + double actualW = w; + double actualH = h; + // Don't try to resize an object with more than one image (this case should be dealt + // with by overriden handlers) + if ((region->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS) && + (region->GetFormattedText().GetCount() > 0) && + (m_regions.GetCount() == 1) && !GraphicsInSizeToContents) + { + oglGetCentredTextExtent(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w, h, &actualW, &actualH); + if ((actualW + 2 * m_textMarginX != w ) || (actualH + 2 * m_textMarginY != h)) + { + // If we are a descendant of a composite, must make sure the composite gets + // resized properly + wxShape *topAncestor = GetTopAncestor(); + + if (topAncestor != this) + { + // Make sure we don't recurse infinitely + GraphicsInSizeToContents = TRUE; + + wxCompositeShape *composite = (wxCompositeShape *)topAncestor; + // composite->Erase(dc); + SetSize(actualW + 2 * m_textMarginX, actualH + 2 * m_textMarginY); + Move(m_xpos, m_ypos); + composite->CalculateSize(); + if (composite->Selected()) + { + composite->DeleteControlPoints(& dc); + composite->MakeControlPoints(); + composite->MakeMandatoryControlPoints(); + } + // Where infinite recursion might happen if we didn't stop it + composite->Draw(dc); + + GraphicsInSizeToContents = FALSE; + } + else + { + // Erase(dc); + SetSize(actualW + 2 * m_textMarginX, actualH + 2 * m_textMarginY); + Move(m_xpos, m_ypos); + } + SetSize(actualW + 2 * m_textMarginX, actualH + 2 * m_textMarginY); + Move(m_xpos, m_ypos); + // EraseContents(dc); + } + } + region->GetSize(&actualW, &actualH); + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, actualW - 2 * m_textMarginX, actualH - 2 * m_textMarginY, region->GetFormatMode()); + m_formatted = TRUE; +} + +void wxShape::Recentre(wxDC &dc) +{ + double w, h; + GetBoundingBoxMin(&w, &h); + + int noRegions = m_regions.GetCount(); + for (int i = 0; i < noRegions; i++) + { + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w - 2 * m_textMarginX, h - 2 * m_textMarginY, region->GetFormatMode()); + } + } +} + +bool wxShape::GetPerimeterPoint(double WXUNUSED(x1), double WXUNUSED(y1), + double WXUNUSED(x2), double WXUNUSED(y2), + double *WXUNUSED(x3), double *WXUNUSED(y3)) +{ + return FALSE; +} + +void wxShape::SetPen(wxPen *the_pen) +{ + m_pen = the_pen; +} + +void wxShape::SetBrush(wxBrush *the_brush) +{ + m_brush = the_brush; +} + +// Get the top-most (non-division) ancestor, or self +wxShape *wxShape::GetTopAncestor() +{ + if (!GetParent()) + return this; + + if (GetParent()->IsKindOf(CLASSINFO(wxDivisionShape))) + return this; + else return GetParent()->GetTopAncestor(); +} + +/* + * Region functions + * + */ +void wxShape::SetFont(wxFont *the_font, int regionId) +{ + m_font = the_font; + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetFont(the_font); +} + +wxFont *wxShape::GetFont(int n) const +{ + wxNode *node = m_regions.Item(n); + if (!node) + return NULL; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetFont(); +} + +void wxShape::SetFormatMode(int mode, int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetFormatMode(mode); +} + +int wxShape::GetFormatMode(int regionId) const +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return 0; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetFormatMode(); +} + +void wxShape::SetTextColour(const wxString &the_colour, int regionId) +{ + m_textColour = wxTheColourDatabase->Find(the_colour); + m_textColourName = the_colour; + + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetColour(the_colour); +} + +void wxShape::SetTextColour(const wxColour &the_colour, int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetColour(the_colour); +} + +wxString wxShape::GetTextColour(int regionId) const +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return wxEmptyString; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetColour(); +} + +wxColour wxShape::GetActualTextColour(int regionId) const +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return wxColour(); + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetActualColourObject(); +} + +void wxShape::SetRegionName(const wxString &name, int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetName(name); +} + +wxString wxShape::GetRegionName(int regionId) +{ + wxNode *node = m_regions.Item(regionId); + if (!node) + return wxEmptyString; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + return region->GetName(); +} + +int wxShape::GetRegionId(const wxString &name) +{ + wxNode *node = m_regions.GetFirst(); + int i = 0; + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + if (region->GetName() == name) + return i; + node = node->GetNext(); + i ++; + } + return -1; +} + +// Name all m_regions in all subimages recursively. +void wxShape::NameRegions(const wxString &parentName) +{ + int n = GetNumberOfTextRegions(); + wxString buff; + for (int i = 0; i < n; i++) + { + if (parentName.Length() > 0) + buff << parentName << wxT(".") << i; + else + buff << i; + SetRegionName(buff, i); + } + wxNode *node = m_children.GetFirst(); + int j = 0; + while (node) + { + buff.Empty(); + wxShape *child = (wxShape *)node->GetData(); + if (parentName.Length() > 0) + buff << parentName << wxT(".") << j; + else + buff << j; + child->NameRegions(buff); + node = node->GetNext(); + j ++; + } +} + +// Get a region by name, possibly looking recursively into composites. +wxShape *wxShape::FindRegion(const wxString &name, int *regionId) +{ + int id = GetRegionId(name); + if (id > -1) + { + *regionId = id; + return this; + } + + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + wxShape *actualImage = child->FindRegion(name, regionId); + if (actualImage) + return actualImage; + node = node->GetNext(); + } + return NULL; +} + +// Finds all region names for this image (composite or simple). +// Supply empty string list. +void wxShape::FindRegionNames(wxStringList &list) +{ + int n = GetNumberOfTextRegions(); + for (int i = 0; i < n; i++) + { + wxString name(GetRegionName(i)); + list.Add(name); + } + + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->FindRegionNames(list); + node = node->GetNext(); + } +} + +void wxShape::AssignNewIds() +{ +// if (m_id == 0) + m_id = wxNewId(); + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->AssignNewIds(); + node = node->GetNext(); + } +} + +void wxShape::OnDraw(wxDC &WXUNUSED(dc)) +{ +} + +void wxShape::OnMoveLinks() +{ + // Want to set the ends of all attached links + // to point to/from this object + + wxNode *current = m_lines.GetFirst(); + while (current) + { + wxLineShape *line = (wxLineShape *)current->GetData(); + line->GetEventHandler()->OnMoveLink(); + current = current->GetNext(); + } +} + + +void wxShape::OnDrawContents(wxDC &dc) +{ + double bound_x, bound_y; + GetBoundingBoxMin(&bound_x, &bound_y); + if (m_regions.GetCount() < 1) return; + + if (m_pen) dc.SetPen(* m_pen); + + wxShapeRegion *region = (wxShapeRegion *)m_regions.GetFirst()->GetData(); + if (region->GetFont()) dc.SetFont(* region->GetFont()); + + dc.SetTextForeground(region->GetActualColourObject()); + dc.SetBackgroundMode(wxTRANSPARENT); + if (!m_formatted) + { + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, bound_x - 2 * m_textMarginX, bound_y - 2 * m_textMarginY, region->GetFormatMode()); + m_formatted = TRUE; + } + if (!GetDisableLabel()) + { + oglDrawFormattedText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, bound_x - 2 * m_textMarginX, bound_y - 2 * m_textMarginY, region->GetFormatMode()); + } +} + +void wxShape::DrawContents(wxDC &dc) +{ + GetEventHandler()->OnDrawContents(dc); +} + +void wxShape::OnSize(double WXUNUSED(x), double WXUNUSED(y)) +{ +} + +bool wxShape::OnMovePre(double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display)) +{ + return TRUE; +} + +void wxShape::OnMovePost(double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display)) +{ +} + +void wxShape::DrawLinks(wxDC &dc, int attachment, bool recurse) +{ + if (!m_visible) + return; + + wxNode *current = m_lines.GetFirst(); + while (current) + { + wxLineShape *line = (wxLineShape *)current->GetData(); + if (attachment == -1 || + (line->GetTo() == this && line->GetAttachmentTo() == attachment) || + (line->GetFrom() == this && line->GetAttachmentFrom() == attachment)) + line->Draw(dc); + current = current->GetNext(); + } + if (recurse) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->DrawLinks(dc, attachment, recurse); + node = node->GetNext(); + } + } +} + +// Returns TRUE if pt1 <= pt2 in the sense that one point comes before another on an +// edge of the shape. +// attachmentPoint is the attachment point (= side) in question. + +// This is the default, rectangular implementation. +bool wxShape::AttachmentSortTest(int attachmentPoint, const wxRealPoint &pt1, const wxRealPoint &pt2) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachmentPoint); + switch (physicalAttachment) + { + case 0: + case 2: + { + return (pt1.x <= pt2.x) ; + } + case 1: + case 3: + { + return (pt1.y <= pt2.y) ; + } + } + + return FALSE; +} + +bool wxShape::MoveLineToNewAttachment(wxLineShape *to_move, + double x, double y) +{ + if (GetAttachmentMode() == ATTACHMENT_MODE_NONE) + return FALSE; + + int newAttachment, oldAttachment; + double distance; + + // Is (x, y) on this object? If so, find the new attachment point + // the user has moved the point to + bool hit = HitTest(x, y, &newAttachment, &distance); + if (!hit) + return FALSE; + + // EraseLinks(); + + if (to_move->GetTo() == this) + oldAttachment = to_move->GetAttachmentTo(); + else + oldAttachment = to_move->GetAttachmentFrom(); + + // The links in a new ordering. + wxList newOrdering; + + // First, add all links to the new list. + wxNode *node = m_lines.GetFirst(); + while (node) + { + newOrdering.Append(node->GetData()); + node = node->GetNext(); + } + + // Delete the line object from the list of links; we're going to move + // it to another position in the list + newOrdering.DeleteObject(to_move); + + double old_x = (double) - 99999.9; + double old_y = (double) - 99999.9; + + node = newOrdering.GetFirst(); + bool found = FALSE; + + while (!found && node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + if ((line->GetTo() == this && oldAttachment == line->GetAttachmentTo()) || + (line->GetFrom() == this && oldAttachment == line->GetAttachmentFrom())) + { + double startX, startY, endX, endY; + double xp, yp; + line->GetEnds(&startX, &startY, &endX, &endY); + if (line->GetTo() == this) + { + xp = endX; + yp = endY; + } + else + { + xp = startX; + yp = startY; + } + + wxRealPoint thisPoint(xp, yp); + wxRealPoint lastPoint(old_x, old_y); + wxRealPoint newPoint(x, y); + + if (AttachmentSortTest(newAttachment, newPoint, thisPoint) && AttachmentSortTest(newAttachment, lastPoint, newPoint)) + { + found = TRUE; + newOrdering.Insert(node, to_move); + } + + old_x = xp; + old_y = yp; + } + node = node->GetNext(); + } + + if (!found) + newOrdering.Append(to_move); + + GetEventHandler()->OnChangeAttachment(newAttachment, to_move, newOrdering); + + return TRUE; +} + +void wxShape::OnChangeAttachment(int attachment, wxLineShape *line, wxList &ordering) +{ + if (line->GetTo() == this) + line->SetAttachmentTo(attachment); + else + line->SetAttachmentFrom(attachment); + + ApplyAttachmentOrdering(ordering); + + MoveLinks(); + + GetCanvas()->Refresh(); +} + +// Reorders the lines according to the given list. +void wxShape::ApplyAttachmentOrdering(wxList &linesToSort) +{ + // This is a temporary store of all the lines. + wxList linesStore; + + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + linesStore.Append(line); + node = node->GetNext();; + } + + m_lines.Clear(); + + node = linesToSort.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + if (linesStore.Member(line)) + { + // Done this one + linesStore.DeleteObject(line); + m_lines.Append(line); + } + node = node->GetNext(); + } + + // Now add any lines that haven't been listed in linesToSort. + node = linesStore.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + m_lines.Append(line); + node = node->GetNext(); + } +} + +// Reorders the lines coming into the node image at this attachment +// position, in the order in which they appear in linesToSort. +// Any remaining lines not in the list will be added to the end. +void wxShape::SortLines(int attachment, wxList &linesToSort) +{ + // This is a temporary store of all the lines at this attachment + // point. We'll tick them off as we've processed them. + wxList linesAtThisAttachment; + + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + wxNode *next = node->GetNext(); + if ((line->GetTo() == this && line->GetAttachmentTo() == attachment) || + (line->GetFrom() == this && line->GetAttachmentFrom() == attachment)) + { + linesAtThisAttachment.Append(line); + delete node; + node = next; + } + else node = node->GetNext(); + } + + node = linesToSort.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + if (linesAtThisAttachment.Member(line)) + { + // Done this one + linesAtThisAttachment.DeleteObject(line); + m_lines.Append(line); + } + node = node->GetNext(); + } + + // Now add any lines that haven't been listed in linesToSort. + node = linesAtThisAttachment.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + m_lines.Append(line); + node = node->GetNext(); + } +} + +void wxShape::OnHighlight(wxDC &WXUNUSED(dc)) +{ +} + +void wxShape::OnLeftClick(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_CLICK_LEFT) != OP_CLICK_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnLeftClick(x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnRightClick(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_CLICK_RIGHT) != OP_CLICK_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment); + } + return; + } +} + +double DragOffsetX = 0.0; +double DragOffsetY = 0.0; + +void wxShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment); + } + return; + } + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + double xx, yy; + xx = x + DragOffsetX; + yy = y + DragOffsetY; + + m_canvas->Snap(&xx, &yy); +// m_xpos = xx; m_ypos = yy; + double w, h; + GetBoundingBoxMax(&w, &h); + GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h); +} + +void wxShape::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment); + } + return; + } + + DragOffsetX = m_xpos - x; + DragOffsetY = m_ypos - y; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + double xx, yy; + xx = x + DragOffsetX; + yy = y + DragOffsetY; + m_canvas->Snap(&xx, &yy); +// m_xpos = xx; m_ypos = yy; + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + double w, h; + GetBoundingBoxMax(&w, &h); + GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h); + m_canvas->CaptureMouse(); +} + +void wxShape::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_canvas->ReleaseMouse(); + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment); + } + return; + } + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(wxCOPY); + + double xx = x + DragOffsetX; + double yy = y + DragOffsetY; + m_canvas->Snap(&xx, &yy); +// canvas->Snap(&m_xpos, &m_ypos); + + // New policy: erase shape at end of drag. + // Erase(dc); + + Move(xx, yy); + m_canvas->Refresh(); +} + +void wxShape::OnDragRight(bool draw, double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnDragRight(draw, x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnBeginDragRight(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnBeginDragRight(x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnEndDragRight(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_RIGHT) != OP_DRAG_RIGHT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnEndDragRight(x, y, keys, attachment); + } + return; + } +} + +void wxShape::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + double top_left_x = (double)(x - w / 2.0); + double top_left_y = (double)(y - h / 2.0); + double top_right_x = (double)(top_left_x + w); + double top_right_y = (double)top_left_y; + double bottom_left_x = (double)top_left_x; + double bottom_left_y = (double)(top_left_y + h); + double bottom_right_x = (double)top_right_x; + double bottom_right_y = (double)bottom_left_y; + + wxPoint points[5]; + points[0].x = WXROUND(top_left_x); + points[0].y = WXROUND(top_left_y); + points[1].x = WXROUND(top_right_x); + points[1].y = WXROUND(top_right_y); + points[2].x = WXROUND(bottom_right_x); + points[2].y = WXROUND(bottom_right_y); + points[3].x = WXROUND(bottom_left_x); + points[3].y = WXROUND(bottom_left_y); + points[4].x = WXROUND(top_left_x); + points[4].y = WXROUND(top_left_y); + + dc.DrawLines(5, points); +} + +void wxShape::Attach(wxShapeCanvas *can) +{ + m_canvas = can; +} + +void wxShape::Detach() +{ + m_canvas = NULL; +} + +void wxShape::Move(double x, double y, bool display) +{ + double old_x = m_xpos; + double old_y = m_ypos; + + if (!GetEventHandler()->OnMovePre(x, y, old_x, old_y, display)) + { +// m_xpos = old_x; +// m_ypos = old_y; + return; + } + + m_xpos = x; + m_ypos = y; + + ResetControlPoints(); + + if (display) + Refresh(); + + MoveLinks(); + + GetEventHandler()->OnMovePost(x, y, old_x, old_y, display); +} + +void wxShape::MoveLinks() +{ + GetEventHandler()->OnMoveLinks(); +} + + +void wxShape::Draw(wxDC &dc) +{ + if (m_visible) + { + GetEventHandler()->OnDraw(dc); + GetEventHandler()->OnDrawContents(dc); + GetEventHandler()->OnDrawControlPoints(dc); + GetEventHandler()->OnDrawBranches(dc); + } +} + +void wxShape::Flash() +{ + if (GetCanvas()) + { + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + Draw(dc); + dc.SetLogicalFunction(wxCOPY); + Draw(dc); + } +} + +void wxShape::Show(bool show) +{ + m_visible = show; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *image = (wxShape *)node->GetData(); + image->Show(show); + node = node->GetNext(); + } +} + +void wxShape::Erase() +{ + Refresh(); +} + +void wxShape::AddText(const wxString &string) +{ + wxNode *node = m_regions.GetFirst(); + if (!node) + return; + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->ClearText(); + wxShapeTextLine *new_line = + new wxShapeTextLine(0.0, 0.0, string); + region->GetFormattedText().Append(new_line); + + m_formatted = FALSE; +} + +void wxShape::SetSize(double x, double y, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(x, y); + SetDefaultRegionSize(); +} + +void wxShape::SetAttachmentSize(double w, double h) +{ + double scaleX; + double scaleY; + double width, height; + GetBoundingBoxMin(&width, &height); + if (width == 0.0) + scaleX = 1.0; + else scaleX = w / width; + if (height == 0.0) + scaleY = 1.0; + else scaleY = h / height; + + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + point->m_x = (double)(point->m_x * scaleX); + point->m_y = (double)(point->m_y * scaleY); + node = node->GetNext(); + } +} + +// Add line FROM this object +void wxShape::AddLine(wxLineShape *line, wxShape *other, + int attachFrom, int attachTo, + // The line ordering + int positionFrom, int positionTo) +{ + if (positionFrom == -1) + { + if (!m_lines.Member(line)) + m_lines.Append(line); + } + else + { + // Don't preserve old ordering if we have new ordering instructions + m_lines.DeleteObject(line); + if (positionFrom < (int) m_lines.GetCount()) + { + wxNode *node = m_lines.Item(positionFrom); + m_lines.Insert(node, line); + } + else + m_lines.Append(line); + } + + if (positionTo == -1) + { + if (!other->m_lines.Member(line)) + other->m_lines.Append(line); + } + else + { + // Don't preserve old ordering if we have new ordering instructions + other->m_lines.DeleteObject(line); + if (positionTo < (int) other->m_lines.GetCount()) + { + wxNode *node = other->m_lines.Item(positionTo); + other->m_lines.Insert(node, line); + } + else + other->m_lines.Append(line); + } +#if 0 + // Wrong: doesn't preserve ordering of shape already linked + m_lines.DeleteObject(line); + other->m_lines.DeleteObject(line); + + if (positionFrom == -1) + m_lines.Append(line); + else + { + if (positionFrom < m_lines.GetCount()) + { + wxNode *node = m_lines.Item(positionFrom); + m_lines.Insert(node, line); + } + else + m_lines.Append(line); + } + + if (positionTo == -1) + other->m_lines.Append(line); + else + { + if (positionTo < other->m_lines.GetCount()) + { + wxNode *node = other->m_lines.Item(positionTo); + other->m_lines.Insert(node, line); + } + else + other->m_lines.Append(line); + } +#endif + + line->SetFrom(this); + line->SetTo(other); + line->SetAttachments(attachFrom, attachTo); +} + +void wxShape::RemoveLine(wxLineShape *line) +{ + if (line->GetFrom() == this) + line->GetTo()->m_lines.DeleteObject(line); + else + line->GetFrom()->m_lines.DeleteObject(line); + + m_lines.DeleteObject(line); +} + +#if wxUSE_PROLOGIO +void wxShape::WriteAttributes(wxExpr *clause) +{ + clause->AddAttributeValueString(wxT("type"), GetClassInfo()->GetClassName()); + clause->AddAttributeValue(wxT("id"), m_id); + + if (m_pen) + { + int penWidth = m_pen->GetWidth(); + int penStyle = m_pen->GetStyle(); + if (penWidth != 1) + clause->AddAttributeValue(wxT("pen_width"), (long)penWidth); + if (penStyle != wxSOLID) + clause->AddAttributeValue(wxT("pen_style"), (long)penStyle); + + wxString penColour = wxTheColourDatabase->FindName(m_pen->GetColour()); + if (penColour == wxEmptyString) + { + wxString hex(oglColourToHex(m_pen->GetColour())); + hex = wxString(wxT("#")) + hex; + clause->AddAttributeValueString(wxT("pen_colour"), hex); + } + else if (penColour != wxT("BLACK")) + clause->AddAttributeValueString(wxT("pen_colour"), penColour); + } + + if (m_brush) + { + wxString brushColour = wxTheColourDatabase->FindName(m_brush->GetColour()); + + if (brushColour == wxEmptyString) + { + wxString hex(oglColourToHex(m_brush->GetColour())); + hex = wxString(wxT("#")) + hex; + clause->AddAttributeValueString(wxT("brush_colour"), hex); + } + else if (brushColour != wxT("WHITE")) + clause->AddAttributeValueString(wxT("brush_colour"), brushColour); + + if (m_brush->GetStyle() != wxSOLID) + clause->AddAttributeValue(wxT("brush_style"), (long)m_brush->GetStyle()); + } + + // Output line ids + + int n_lines = m_lines.GetCount(); + if (n_lines > 0) + { + wxExpr *list = new wxExpr(wxExprList); + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxShape *line = (wxShape *)node->GetData(); + wxExpr *id_expr = new wxExpr(line->GetId()); + list->Append(id_expr); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("arcs"), list); + } + + // Miscellaneous members + if (m_attachmentMode != 0) + clause->AddAttributeValue(wxT("use_attachments"), (long)m_attachmentMode); + if (m_sensitivity != OP_ALL) + clause->AddAttributeValue(wxT("sensitivity"), (long)m_sensitivity); + if (!m_spaceAttachments) + clause->AddAttributeValue(wxT("space_attachments"), (long)m_spaceAttachments); + if (m_fixedWidth) + clause->AddAttributeValue(wxT("fixed_width"), (long)m_fixedWidth); + if (m_fixedHeight) + clause->AddAttributeValue(wxT("fixed_height"), (long)m_fixedHeight); + if (m_shadowMode != SHADOW_NONE) + clause->AddAttributeValue(wxT("shadow_mode"), (long)m_shadowMode); + if (m_centreResize != TRUE) + clause->AddAttributeValue(wxT("centre_resize"), (long)0); + clause->AddAttributeValue(wxT("maintain_aspect_ratio"), (long) m_maintainAspectRatio); + if (m_highlighted != FALSE) + clause->AddAttributeValue(wxT("hilite"), (long)m_highlighted); + + if (m_parent) // For composite objects + clause->AddAttributeValue(wxT("parent"), (long)m_parent->GetId()); + + if (m_rotation != 0.0) + clause->AddAttributeValue(wxT("rotation"), m_rotation); + + if (!this->IsKindOf(CLASSINFO(wxLineShape))) + { + clause->AddAttributeValue(wxT("neck_length"), (long) m_branchNeckLength); + clause->AddAttributeValue(wxT("stem_length"), (long) m_branchStemLength); + clause->AddAttributeValue(wxT("branch_spacing"), (long) m_branchSpacing); + clause->AddAttributeValue(wxT("branch_style"), (long) m_branchStyle); + } + + // Write user-defined attachment points, if any + if (m_attachmentPoints.GetCount() > 0) + { + wxExpr *attachmentList = new wxExpr(wxExprList); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + wxExpr *pointExpr = new wxExpr(wxExprList); + pointExpr->Append(new wxExpr((long)point->m_id)); + pointExpr->Append(new wxExpr(point->m_x)); + pointExpr->Append(new wxExpr(point->m_y)); + attachmentList->Append(pointExpr); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("user_attachments"), attachmentList); + } + + // Write text regions + WriteRegions(clause); +} + +void wxShape::WriteRegions(wxExpr *clause) +{ + // Output regions as region1 = (...), region2 = (...), etc + // and formatted text as text1 = (...), text2 = (...) etc. + int regionNo = 1; + wxChar regionNameBuf[20]; + wxChar textNameBuf[20]; + wxNode *node = m_regions.GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + wxSprintf(regionNameBuf, wxT("region%d"), regionNo); + wxSprintf(textNameBuf, wxT("text%d"), regionNo); + + // Original text and region attributes: + // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY + // formatMode fontSize fontFamily fontStyle fontWeight textColour) + wxExpr *regionExpr = new wxExpr(wxExprList); + regionExpr->Append(new wxExpr(wxExprString, region->m_regionName)); + regionExpr->Append(new wxExpr(wxExprString, region->m_regionText)); + + regionExpr->Append(new wxExpr(region->m_x)); + regionExpr->Append(new wxExpr(region->m_y)); + regionExpr->Append(new wxExpr(region->GetWidth())); + regionExpr->Append(new wxExpr(region->GetHeight())); + + regionExpr->Append(new wxExpr(region->m_minWidth)); + regionExpr->Append(new wxExpr(region->m_minHeight)); + regionExpr->Append(new wxExpr(region->m_regionProportionX)); + regionExpr->Append(new wxExpr(region->m_regionProportionY)); + + regionExpr->Append(new wxExpr((long)region->m_formatMode)); + + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetPointSize() : 10))); + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetFamily() : wxDEFAULT))); + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetStyle() : wxDEFAULT))); + regionExpr->Append(new wxExpr((long)(region->m_font ? region->m_font->GetWeight() : wxNORMAL))); + regionExpr->Append(new wxExpr(wxExprString, region->m_textColour)); + + // New members for pen colour/style + regionExpr->Append(new wxExpr(wxExprString, region->m_penColour)); + regionExpr->Append(new wxExpr((long)region->m_penStyle)); + + // Formatted text: + // text1 = ((x y string) (x y string) ...) + wxExpr *textExpr = new wxExpr(wxExprList); + + wxNode *textNode = region->m_formattedText.GetFirst(); + while (textNode) + { + wxShapeTextLine *line = (wxShapeTextLine *)textNode->GetData(); + wxExpr *list2 = new wxExpr(wxExprList); + list2->Append(new wxExpr(line->GetX())); + list2->Append(new wxExpr(line->GetY())); + list2->Append(new wxExpr(wxExprString, line->GetText())); + textExpr->Append(list2); + textNode = textNode->GetNext(); + } + + // Now add both attributes to the clause + clause->AddAttributeValue(regionNameBuf, regionExpr); + clause->AddAttributeValue(textNameBuf, textExpr); + + node = node->GetNext(); + regionNo ++; + } +} + +void wxShape::ReadAttributes(wxExpr *clause) +{ + clause->GetAttributeValue(wxT("id"), m_id); + wxRegisterId(m_id); + + clause->GetAttributeValue(wxT("x"), m_xpos); + clause->GetAttributeValue(wxT("y"), m_ypos); + + // Input text strings (FOR COMPATIBILITY WITH OLD FILES ONLY. SEE REGION CODE BELOW.) + ClearText(); + wxExpr *strings = clause->AttributeValue(wxT("text")); + if (strings && strings->Type() == wxExprList) + { + m_formatted = TRUE; // Assume text is formatted unless we prove otherwise + wxExpr *node = strings->value.first; + while (node) + { + wxExpr *string_expr = node; + double the_x = 0.0; + double the_y = 0.0; + wxString the_string = wxEmptyString; + + // string_expr can either be a string, or a list of + // 3 elements: x, y, and string. + if (string_expr->Type() == wxExprString) + { + the_string = string_expr->StringValue(); + m_formatted = FALSE; + } + else if (string_expr->Type() == wxExprList) + { + wxExpr *first = string_expr->value.first; + wxExpr *second = first ? first->next : (wxExpr *) NULL; + wxExpr *third = second ? second->next : (wxExpr *) NULL; + + if (first && second && third && + (first->Type() == wxExprReal || first->Type() == wxExprInteger) && + (second->Type() == wxExprReal || second->Type() == wxExprInteger) && + third->Type() == wxExprString) + { + if (first->Type() == wxExprReal) + the_x = first->RealValue(); + else the_x = (double)first->IntegerValue(); + + if (second->Type() == wxExprReal) + the_y = second->RealValue(); + else the_y = (double)second->IntegerValue(); + + the_string = third->StringValue(); + } + } + wxShapeTextLine *line = + new wxShapeTextLine(the_x, the_y, the_string); + m_text.Append(line); + + node = node->next; + } + } + + wxString pen_string = wxEmptyString; + wxString brush_string = wxEmptyString; + int pen_width = 1; + int pen_style = wxSOLID; + int brush_style = wxSOLID; + m_attachmentMode = ATTACHMENT_MODE_NONE; + + clause->GetAttributeValue(wxT("pen_colour"), pen_string); + clause->GetAttributeValue(wxT("text_colour"), m_textColourName); + + SetTextColour(m_textColourName); + + clause->GetAttributeValue(wxT("region_name"), m_regionName); + + clause->GetAttributeValue(wxT("brush_colour"), brush_string); + clause->GetAttributeValue(wxT("pen_width"), pen_width); + clause->GetAttributeValue(wxT("pen_style"), pen_style); + clause->GetAttributeValue(wxT("brush_style"), brush_style); + + int iVal = (int) m_attachmentMode; + clause->GetAttributeValue(wxT("use_attachments"), iVal); + m_attachmentMode = iVal; + + clause->GetAttributeValue(wxT("sensitivity"), m_sensitivity); + + iVal = (int) m_spaceAttachments; + clause->GetAttributeValue(wxT("space_attachments"), iVal); + m_spaceAttachments = (iVal != 0); + + iVal = (int) m_fixedWidth; + clause->GetAttributeValue(wxT("fixed_width"), iVal); + m_fixedWidth = (iVal != 0); + + iVal = (int) m_fixedHeight; + clause->GetAttributeValue(wxT("fixed_height"), iVal); + m_fixedHeight = (iVal != 0); + + clause->GetAttributeValue(wxT("format_mode"), m_formatMode); + clause->GetAttributeValue(wxT("shadow_mode"), m_shadowMode); + + iVal = m_branchNeckLength; + clause->GetAttributeValue(wxT("neck_length"), iVal); + m_branchNeckLength = iVal; + + iVal = m_branchStemLength; + clause->GetAttributeValue(wxT("stem_length"), iVal); + m_branchStemLength = iVal; + + iVal = m_branchSpacing; + clause->GetAttributeValue(wxT("branch_spacing"), iVal); + m_branchSpacing = iVal; + + clause->GetAttributeValue(wxT("branch_style"), m_branchStyle); + + iVal = (int) m_centreResize; + clause->GetAttributeValue(wxT("centre_resize"), iVal); + m_centreResize = (iVal != 0); + + iVal = (int) m_maintainAspectRatio; + clause->GetAttributeValue(wxT("maintain_aspect_ratio"), iVal); + m_maintainAspectRatio = (iVal != 0); + + iVal = (int) m_highlighted; + clause->GetAttributeValue(wxT("hilite"), iVal); + m_highlighted = (iVal != 0); + + clause->GetAttributeValue(wxT("rotation"), m_rotation); + + if (pen_string == wxEmptyString) + pen_string = wxT("BLACK"); + if (brush_string == wxEmptyString) + brush_string = wxT("WHITE"); + + if (pen_string.GetChar(0) == '#') + { + wxColour col(oglHexToColour(pen_string.After('#'))); + m_pen = wxThePenList->FindOrCreatePen(col, pen_width, pen_style); + } + else + m_pen = wxThePenList->FindOrCreatePen(pen_string, pen_width, pen_style); + + if (!m_pen) + m_pen = wxBLACK_PEN; + + if (brush_string.GetChar(0) == '#') + { + wxColour col(oglHexToColour(brush_string.After('#'))); + m_brush = wxTheBrushList->FindOrCreateBrush(col, brush_style); + } + else + m_brush = wxTheBrushList->FindOrCreateBrush(brush_string, brush_style); + + if (!m_brush) + m_brush = wxWHITE_BRUSH; + + int point_size = 10; + clause->GetAttributeValue(wxT("point_size"), point_size); + SetFont(oglMatchFont(point_size)); + + // Read user-defined attachment points, if any + wxExpr *attachmentList = clause->AttributeValue(wxT("user_attachments")); + if (attachmentList) + { + wxExpr *pointExpr = attachmentList->GetFirst(); + while (pointExpr) + { + wxExpr *idExpr = pointExpr->Nth(0); + wxExpr *xExpr = pointExpr->Nth(1); + wxExpr *yExpr = pointExpr->Nth(2); + if (idExpr && xExpr && yExpr) + { + wxAttachmentPoint *point = new wxAttachmentPoint; + point->m_id = (int)idExpr->IntegerValue(); + point->m_x = xExpr->RealValue(); + point->m_y = yExpr->RealValue(); + m_attachmentPoints.Append((wxObject *)point); + } + pointExpr = pointExpr->GetNext(); + } + } + + // Read text regions + ReadRegions(clause); +} + +void wxShape::ReadRegions(wxExpr *clause) +{ + ClearRegions(); + + // region1 = (regionName regionText x y width height minWidth minHeight proportionX proportionY + // formatMode fontSize fontFamily fontStyle fontWeight textColour) + int regionNo = 1; + wxChar regionNameBuf[20]; + wxChar textNameBuf[20]; + + wxExpr *regionExpr; + wxExpr *textExpr = NULL; + wxSprintf(regionNameBuf, wxT("region%d"), regionNo); + wxSprintf(textNameBuf, wxT("text%d"), regionNo); + + m_formatted = TRUE; // Assume text is formatted unless we prove otherwise + + while ((regionExpr = clause->AttributeValue(regionNameBuf)) != NULL) + { + /* + * Get the region information + * + */ + + wxString regionName = wxEmptyString; + wxString regionText = wxEmptyString; + double x = 0.0; + double y = 0.0; + double width = 0.0; + double height = 0.0; + double minWidth = 5.0; + double minHeight = 5.0; + double m_regionProportionX = -1.0; + double m_regionProportionY = -1.0; + int formatMode = FORMAT_NONE; + int fontSize = 10; + int fontFamily = wxSWISS; + int fontStyle = wxNORMAL; + int fontWeight = wxNORMAL; + wxString regionTextColour = wxEmptyString; + wxString penColour = wxEmptyString; + int penStyle = wxSOLID; + + if (regionExpr->Type() == wxExprList) + { + wxExpr *nameExpr = regionExpr->Nth(0); + wxExpr *textExpr = regionExpr->Nth(1); + wxExpr *xExpr = regionExpr->Nth(2); + wxExpr *yExpr = regionExpr->Nth(3); + wxExpr *widthExpr = regionExpr->Nth(4); + wxExpr *heightExpr = regionExpr->Nth(5); + wxExpr *minWidthExpr = regionExpr->Nth(6); + wxExpr *minHeightExpr = regionExpr->Nth(7); + wxExpr *propXExpr = regionExpr->Nth(8); + wxExpr *propYExpr = regionExpr->Nth(9); + wxExpr *formatExpr = regionExpr->Nth(10); + wxExpr *sizeExpr = regionExpr->Nth(11); + wxExpr *familyExpr = regionExpr->Nth(12); + wxExpr *styleExpr = regionExpr->Nth(13); + wxExpr *weightExpr = regionExpr->Nth(14); + wxExpr *colourExpr = regionExpr->Nth(15); + wxExpr *penColourExpr = regionExpr->Nth(16); + wxExpr *penStyleExpr = regionExpr->Nth(17); + + regionName = nameExpr->StringValue(); + regionText = textExpr->StringValue(); + + x = xExpr->RealValue(); + y = yExpr->RealValue(); + + width = widthExpr->RealValue(); + height = heightExpr->RealValue(); + + minWidth = minWidthExpr->RealValue(); + minHeight = minHeightExpr->RealValue(); + + m_regionProportionX = propXExpr->RealValue(); + m_regionProportionY = propYExpr->RealValue(); + + formatMode = (int) formatExpr->IntegerValue(); + fontSize = (int)sizeExpr->IntegerValue(); + fontFamily = (int)familyExpr->IntegerValue(); + fontStyle = (int)styleExpr->IntegerValue(); + fontWeight = (int)weightExpr->IntegerValue(); + + if (colourExpr) + { + regionTextColour = colourExpr->StringValue(); + } + else + regionTextColour = wxT("BLACK"); + + if (penColourExpr) + penColour = penColourExpr->StringValue(); + if (penStyleExpr) + penStyle = (int)penStyleExpr->IntegerValue(); + } + wxFont *font = wxTheFontList->FindOrCreateFont(fontSize, fontFamily, fontStyle, fontWeight); + + wxShapeRegion *region = new wxShapeRegion; + region->SetProportions(m_regionProportionX, m_regionProportionY); + region->SetFont(font); + region->SetSize(width, height); + region->SetPosition(x, y); + region->SetMinSize(minWidth, minHeight); + region->SetFormatMode(formatMode); + region->SetPenStyle(penStyle); + if (penColour != wxEmptyString) + region->SetPenColour(penColour); + + region->m_textColour = regionTextColour; + region->m_regionText = regionText; + region->m_regionName = regionName; + + m_regions.Append(region); + + /* + * Get the formatted text strings + * + */ + textExpr = clause->AttributeValue(textNameBuf); + if (textExpr && (textExpr->Type() == wxExprList)) + { + wxExpr *node = textExpr->value.first; + while (node) + { + wxExpr *string_expr = node; + double the_x = 0.0; + double the_y = 0.0; + wxString the_string = wxEmptyString; + + // string_expr can either be a string, or a list of + // 3 elements: x, y, and string. + if (string_expr->Type() == wxExprString) + { + the_string = string_expr->StringValue(); + m_formatted = FALSE; + } + else if (string_expr->Type() == wxExprList) + { + wxExpr *first = string_expr->value.first; + wxExpr *second = first ? first->next : (wxExpr *) NULL; + wxExpr *third = second ? second->next : (wxExpr *) NULL; + + if (first && second && third && + (first->Type() == wxExprReal || first->Type() == wxExprInteger) && + (second->Type() == wxExprReal || second->Type() == wxExprInteger) && + third->Type() == wxExprString) + { + if (first->Type() == wxExprReal) + the_x = first->RealValue(); + else the_x = (double)first->IntegerValue(); + + if (second->Type() == wxExprReal) + the_y = second->RealValue(); + else the_y = (double)second->IntegerValue(); + + the_string = third->StringValue(); + } + } + if (the_string) + { + wxShapeTextLine *line = + new wxShapeTextLine(the_x, the_y, the_string); + region->m_formattedText.Append(line); + } + node = node->next; + } + } + + regionNo ++; + wxSprintf(regionNameBuf, wxT("region%d"), regionNo); + wxSprintf(textNameBuf, wxT("text%d"), regionNo); + } + + // Compatibility: check for no regions (old file). + // Lines and divided rectangles must deal with this compatibility + // theirselves. Composites _may_ not have any regions anyway. + if ((m_regions.GetCount() == 0) && + !this->IsKindOf(CLASSINFO(wxLineShape)) && !this->IsKindOf(CLASSINFO(wxDividedShape)) && + !this->IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxShapeRegion *newRegion = new wxShapeRegion; + newRegion->SetName(wxT("0")); + m_regions.Append((wxObject *)newRegion); + if (m_text.GetCount() > 0) + { + newRegion->ClearText(); + wxNode *node = m_text.GetFirst(); + while (node) + { + wxShapeTextLine *textLine = (wxShapeTextLine *)node->GetData(); + wxNode *next = node->GetNext(); + newRegion->GetFormattedText().Append((wxObject *)textLine); + delete node; + node = next; + } + } + } +} + +#endif + +void wxShape::Copy(wxShape ©) +{ + copy.m_id = m_id; + copy.m_xpos = m_xpos; + copy.m_ypos = m_ypos; + copy.m_pen = m_pen; + copy.m_brush = m_brush; + copy.m_textColour = m_textColour; + copy.m_centreResize = m_centreResize; + copy.m_maintainAspectRatio = m_maintainAspectRatio; + copy.m_attachmentMode = m_attachmentMode; + copy.m_spaceAttachments = m_spaceAttachments; + copy.m_highlighted = m_highlighted; + copy.m_rotation = m_rotation; + copy.m_textColourName = m_textColourName; + copy.m_regionName = m_regionName; + + copy.m_sensitivity = m_sensitivity; + copy.m_draggable = m_draggable; + copy.m_fixedWidth = m_fixedWidth; + copy.m_fixedHeight = m_fixedHeight; + copy.m_formatMode = m_formatMode; + copy.m_drawHandles = m_drawHandles; + + copy.m_visible = m_visible; + copy.m_shadowMode = m_shadowMode; + copy.m_shadowOffsetX = m_shadowOffsetX; + copy.m_shadowOffsetY = m_shadowOffsetY; + copy.m_shadowBrush = m_shadowBrush; + + copy.m_branchNeckLength = m_branchNeckLength; + copy.m_branchStemLength = m_branchStemLength; + copy.m_branchSpacing = m_branchSpacing; + + // Copy text regions + copy.ClearRegions(); + wxNode *node = m_regions.GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + wxShapeRegion *newRegion = new wxShapeRegion(*region); + copy.m_regions.Append(newRegion); + node = node->GetNext(); + } + + // Copy attachments + copy.ClearAttachments(); + node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + wxAttachmentPoint *newPoint = new wxAttachmentPoint; + newPoint->m_id = point->m_id; + newPoint->m_x = point->m_x; + newPoint->m_y = point->m_y; + copy.m_attachmentPoints.Append((wxObject *)newPoint); + node = node->GetNext(); + } + + // Copy lines + copy.m_lines.Clear(); + node = m_lines.GetFirst(); + while (node) + { + wxLineShape *line = (wxLineShape *) node->GetData(); + copy.m_lines.Append(line); + node = node->GetNext(); + } +} + +// Create and return a new, fully copied object. +wxShape *wxShape::CreateNewCopy(bool resetMapping, bool recompute) +{ + if (resetMapping) + oglObjectCopyMapping.Clear(); + + wxShape *newObject = (wxShape *) GetClassInfo()->CreateObject(); + + wxASSERT( (newObject != NULL) ); + wxASSERT( (newObject->IsKindOf(CLASSINFO(wxShape))) ); + + Copy(*newObject); + + if (GetEventHandler() != this) + { + wxShapeEvtHandler *newHandler = GetEventHandler()->CreateNewCopy(); + newObject->SetEventHandler(newHandler); + newObject->SetPreviousHandler(NULL); + newHandler->SetPreviousHandler(newObject); + newHandler->SetShape(newObject); + } + + if (recompute) + newObject->Recompute(); + return newObject; +} + +// Does the copying for this object, including copying event +// handler data if any. Calls the virtual Copy function. +void wxShape::CopyWithHandler(wxShape ©) +{ + Copy(copy); + + if (GetEventHandler() != this) + { + wxASSERT( copy.GetEventHandler() != NULL ); + wxASSERT( copy.GetEventHandler() != (©) ); + wxASSERT( GetEventHandler()->GetClassInfo() == copy.GetEventHandler()->GetClassInfo() ); + GetEventHandler()->CopyData(* (copy.GetEventHandler())); + } +} + + +// Default - make 6 control points +void wxShape::MakeControlPoints() +{ + double maxX, maxY, minX, minY; + + GetBoundingBoxMax(&maxX, &maxY); + GetBoundingBoxMin(&minX, &minY); + + double widthMin = (double)(minX + CONTROL_POINT_SIZE + 2); + double heightMin = (double)(minY + CONTROL_POINT_SIZE + 2); + + // Offsets from main object + double top = (double)(- (heightMin / 2.0)); + double bottom = (double)(heightMin / 2.0 + (maxY - minY)); + double left = (double)(- (widthMin / 2.0)); + double right = (double)(widthMin / 2.0 + (maxX - minX)); + + wxControlPoint *control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, top, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, top, + CONTROL_POINT_VERTICAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, top, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, 0, + CONTROL_POINT_HORIZONTAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, right, bottom, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, 0, bottom, + CONTROL_POINT_VERTICAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, bottom, + CONTROL_POINT_DIAGONAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + control = new wxControlPoint(m_canvas, this, CONTROL_POINT_SIZE, left, 0, + CONTROL_POINT_HORIZONTAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + +} + +void wxShape::MakeMandatoryControlPoints() +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->MakeMandatoryControlPoints(); + node = node->GetNext(); + } +} + +void wxShape::ResetMandatoryControlPoints() +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->ResetMandatoryControlPoints(); + node = node->GetNext(); + } +} + +void wxShape::ResetControlPoints() +{ + ResetMandatoryControlPoints(); + + if (m_controlPoints.GetCount() < 1) + return; + + double maxX, maxY, minX, minY; + + GetBoundingBoxMax(&maxX, &maxY); + GetBoundingBoxMin(&minX, &minY); + + double widthMin = (double)(minX + CONTROL_POINT_SIZE + 2); + double heightMin = (double)(minY + CONTROL_POINT_SIZE + 2); + + // Offsets from main object + double top = (double)(- (heightMin / 2.0)); + double bottom = (double)(heightMin / 2.0 + (maxY - minY)); + double left = (double)(- (widthMin / 2.0)); + double right = (double)(widthMin / 2.0 + (maxX - minX)); + + wxNode *node = m_controlPoints.GetFirst(); + wxControlPoint *control = (wxControlPoint *)node->GetData(); + control->m_xoffset = left; + control->m_yoffset = top; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = 0; + control->m_yoffset = top; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = right; + control->m_yoffset = top; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = right; + control->m_yoffset = 0; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = right; + control->m_yoffset = bottom; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = 0; + control->m_yoffset = bottom; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = left; + control->m_yoffset = bottom; + + node = node->GetNext(); + control = (wxControlPoint *)node->GetData(); + control->m_xoffset = left; + control->m_yoffset = 0; +} + +void wxShape::DeleteControlPoints(wxDC *dc) +{ + wxNode *node = m_controlPoints.GetFirst(); + while (node) + { + wxControlPoint *control = (wxControlPoint *)node->GetData(); + control->Refresh(); + m_canvas->RemoveShape(control); + delete control; + delete node; + node = m_controlPoints.GetFirst(); + } + // Children of divisions are contained objects, + // so stop here + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->DeleteControlPoints(dc); + node = node->GetNext(); + } + } +} + +void wxShape::OnDrawControlPoints(wxDC &dc) +{ + if (!m_drawHandles) + return; + + dc.SetBrush(* wxBLACK_BRUSH); + dc.SetPen(* wxBLACK_PEN); + + wxNode *node = m_controlPoints.GetFirst(); + while (node) + { + wxControlPoint *control = (wxControlPoint *)node->GetData(); + control->Draw(dc); + node = node->GetNext(); + } + // Children of divisions are contained objects, + // so stop here. + // This test bypasses the type facility for speed + // (critical when drawing) + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->GetEventHandler()->OnDrawControlPoints(dc); + node = node->GetNext(); + } + } +} + +void wxShape::Select(bool select) +{ + m_selected = select; + if (select) + { + MakeControlPoints(); + // Children of divisions are contained objects, + // so stop here + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + child->MakeMandatoryControlPoints(); + node = node->GetNext(); + } + } + } + if (!select) + { + DeleteControlPoints(); + if (!IsKindOf(CLASSINFO(wxDivisionShape))) + { + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + node = node->GetNext(); + } + } + } + Refresh(); +} + +bool wxShape::Selected() const +{ + return m_selected; +} + +bool wxShape::AncestorSelected() const +{ + if (m_selected) return TRUE; + if (!GetParent()) + return FALSE; + else + return GetParent()->AncestorSelected(); +} + +int wxShape::GetNumberOfAttachments() const +{ + // Should return the MAXIMUM attachment point id here, + // so higher-level functions can iterate through all attachments, + // even if they're not contiguous. + if (m_attachmentPoints.GetCount() == 0) + return 4; + else + { + int maxN = 3; + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id > maxN) + maxN = point->m_id; + node = node->GetNext(); + } + return maxN + 1;; + } +} + +bool wxShape::AttachmentIsValid(int attachment) const +{ + if (m_attachmentPoints.GetCount() == 0) + { + return ((attachment >= 0) && (attachment < 4)) ; + } + + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id == attachment) + return TRUE; + node = node->GetNext(); + } + return FALSE; +} + +bool wxShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + if (m_attachmentMode == ATTACHMENT_MODE_NONE) + { + *x = m_xpos; + *y = m_ypos; + return TRUE; + } + else if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING) + { + wxRealPoint pt, stemPt; + GetBranchingAttachmentPoint(attachment, nth, pt, stemPt); + *x = pt.x; + *y = pt.y; + return TRUE; + } + else if (m_attachmentMode == ATTACHMENT_MODE_EDGE) + { + if (m_attachmentPoints.GetCount() > 0) + { + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id == attachment) + { + *x = (double)(m_xpos + point->m_x); + *y = (double)(m_ypos + point->m_y); + return TRUE; + } + node = node->GetNext(); + } + *x = m_xpos; + *y = m_ypos; + return FALSE; + } + else + { + // Assume is rectangular + double w, h; + GetBoundingBoxMax(&w, &h); + double top = (double)(m_ypos + h / 2.0); + double bottom = (double)(m_ypos - h / 2.0); + double left = (double)(m_xpos - w / 2.0); + double right = (double)(m_xpos + w / 2.0); + + /* bool isEnd = */ + (line && line->IsEnd(this)); + + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + // Simplified code + switch (physicalAttachment) + { + case 0: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(right, bottom), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + case 1: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(right, bottom), wxRealPoint(right, top), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + case 2: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, top), wxRealPoint(right, top), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + case 3: + { + wxRealPoint pt = CalcSimpleAttachment(wxRealPoint(left, bottom), wxRealPoint(left, top), + nth, no_arcs, line); + + *x = pt.x; + *y = pt.y; + break; + } + default: + { + return FALSE; + } + } + return TRUE; + } + } + return FALSE; +} + +void wxShape::GetBoundingBoxMax(double *w, double *h) +{ + double ww, hh; + GetBoundingBoxMin(&ww, &hh); + if (m_shadowMode != SHADOW_NONE) + { + ww += m_shadowOffsetX; + hh += m_shadowOffsetY; + } + *w = ww; + *h = hh; +} + +// Returns TRUE if image is a descendant of this composite +bool wxShape::HasDescendant(wxShape *image) +{ + if (image == this) + return TRUE; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + bool ans = child->HasDescendant(image); + if (ans) + return TRUE; + node = node->GetNext(); + } + return FALSE; +} + +// Clears points from a list of wxRealPoints, and clears list +void wxShape::ClearPointList(wxList &list) +{ + wxNode *node = list.GetFirst(); + while (node) + { + wxRealPoint *pt = (wxRealPoint *) node->GetData(); + delete pt; + + node = node->GetNext(); + } + list.Clear(); +} + +// Assuming the attachment lies along a vertical or horizontal line, +// calculate the position on that point. +wxRealPoint wxShape::CalcSimpleAttachment(const wxRealPoint &pt1, const wxRealPoint &pt2, + int nth, int noArcs, wxLineShape *line) +{ + bool isEnd = (line && line->IsEnd(this)); + + // Are we horizontal or vertical? + bool isHorizontal = (oglRoughlyEqual(pt1.y, pt2.y) == TRUE); + + double x, y; + + if (isHorizontal) + { + wxRealPoint firstPoint, secondPoint; + if (pt1.x > pt2.x) + { + firstPoint = pt2; + secondPoint = pt1; + } + else + { + firstPoint = pt1; + secondPoint = pt2; + } + + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->x < firstPoint.x) + x = firstPoint.x; + else if (point->x > secondPoint.x) + x = secondPoint.x; + else + x = point->x; + } + else + x = firstPoint.x + (nth + 1) * (secondPoint.x - firstPoint.x) / (noArcs + 1); + } + else x = (secondPoint.x - firstPoint.x) / 2.0; // Midpoint + + y = pt1.y; + } + else + { + wxASSERT( oglRoughlyEqual(pt1.x, pt2.x) == TRUE ); + + wxRealPoint firstPoint, secondPoint; + if (pt1.y > pt2.y) + { + firstPoint = pt2; + secondPoint = pt1; + } + else + { + firstPoint = pt1; + secondPoint = pt2; + } + + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->y < firstPoint.y) + y = firstPoint.y; + else if (point->y > secondPoint.y) + y = secondPoint.y; + else + y = point->y; + } + else + y = firstPoint.y + (nth + 1) * (secondPoint.y - firstPoint.y) / (noArcs + 1); + } + else y = (secondPoint.y - firstPoint.y) / 2.0; // Midpoint + + x = pt1.x; + } + + return wxRealPoint(x, y); +} + +// Return the zero-based position in m_lines of line. +int wxShape::GetLinePosition(wxLineShape *line) +{ + for (size_t i = 0; i < m_lines.GetCount(); i++) + if ((wxLineShape *) (m_lines.Item(i)->GetData()) == line) + return i; + + return 0; +} + +// +// |________| +// | <- root +// | <- neck +// shoulder1 ->---------<- shoulder2 +// | | | | | +// <- branching attachment point N-1 + +// This function gets information about where branching connections go. +// Returns FALSE if there are no lines at this attachment. +bool wxShape::GetBranchingAttachmentInfo(int attachment, wxRealPoint &root, wxRealPoint &neck, + wxRealPoint &shoulder1, wxRealPoint &shoulder2) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + // Number of lines at this attachment. + int lineCount = GetAttachmentLineCount(attachment); + + if (lineCount == 0) + return FALSE; + + int totalBranchLength = m_branchSpacing * (lineCount - 1); + + root = GetBranchingAttachmentRoot(attachment); + + // Assume that we have attachment points 0 to 3: top, right, bottom, left. + switch (physicalAttachment) + { + case 0: + { + neck.x = GetX(); + neck.y = root.y - m_branchNeckLength; + + shoulder1.x = root.x - (totalBranchLength / 2.0) ; + shoulder2.x = root.x + (totalBranchLength / 2.0) ; + + shoulder1.y = neck.y; + shoulder2.y = neck.y; + break; + } + case 1: + { + neck.x = root.x + m_branchNeckLength; + neck.y = root.y; + + shoulder1.x = neck.x ; + shoulder2.x = neck.x ; + + shoulder1.y = neck.y - (totalBranchLength / 2.0) ; + shoulder2.y = neck.y + (totalBranchLength / 2.0) ; + break; + } + case 2: + { + neck.x = GetX(); + neck.y = root.y + m_branchNeckLength; + + shoulder1.x = root.x - (totalBranchLength / 2.0) ; + shoulder2.x = root.x + (totalBranchLength / 2.0) ; + + shoulder1.y = neck.y; + shoulder2.y = neck.y; + break; + } + case 3: + { + neck.x = root.x - m_branchNeckLength; + neck.y = root.y ; + + shoulder1.x = neck.x ; + shoulder2.x = neck.x ; + + shoulder1.y = neck.y - (totalBranchLength / 2.0) ; + shoulder2.y = neck.y + (totalBranchLength / 2.0) ; + break; + } + default: + { + wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentInfo.") ); + break; + } + } + return TRUE; +} + +// n is the number of the adjoining line, from 0 to N-1 where N is the number of lines +// at this attachment point. +// Get the attachment point where the arc joins the stem, and also the point where the +// the stem meets the shoulder. +bool wxShape::GetBranchingAttachmentPoint(int attachment, int n, wxRealPoint &pt, wxRealPoint &stemPt) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + wxRealPoint root, neck, shoulder1, shoulder2; + GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2); + + // Assume that we have attachment points 0 to 3: top, right, bottom, left. + switch (physicalAttachment) + { + case 0: + { + pt.y = neck.y - m_branchStemLength; + pt.x = shoulder1.x + n * m_branchSpacing; + + stemPt.x = pt.x; + stemPt.y = neck.y; + break; + } + case 2: + { + pt.y = neck.y + m_branchStemLength; + pt.x = shoulder1.x + n * m_branchSpacing; + + stemPt.x = pt.x; + stemPt.y = neck.y; + break; + } + case 1: + { + pt.x = neck.x + m_branchStemLength; + pt.y = shoulder1.y + n * m_branchSpacing; + + stemPt.x = neck.x; + stemPt.y = pt.y; + break; + } + case 3: + { + pt.x = neck.x - m_branchStemLength; + pt.y = shoulder1.y + n * m_branchSpacing; + + stemPt.x = neck.x; + stemPt.y = pt.y; + break; + } + default: + { + wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentPoint.") ); + break; + } + } + + return TRUE; +} + +// Get the number of lines at this attachment position. +int wxShape::GetAttachmentLineCount(int attachment) const +{ + int count = 0; + wxNode *node = m_lines.GetFirst(); + while (node) + { + wxLineShape *lineShape = (wxLineShape *) node->GetData(); + if ((lineShape->GetFrom() == this) && (lineShape->GetAttachmentFrom() == attachment)) + count ++; + else if ((lineShape->GetTo() == this) && (lineShape->GetAttachmentTo() == attachment)) + count ++; + + node = node->GetNext(); + } + return count; +} + +// This function gets the root point at the given attachment. +wxRealPoint wxShape::GetBranchingAttachmentRoot(int attachment) +{ + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + wxRealPoint root; + + double width, height; + GetBoundingBoxMax(& width, & height); + + // Assume that we have attachment points 0 to 3: top, right, bottom, left. + switch (physicalAttachment) + { + case 0: + { + root.x = GetX() ; + root.y = GetY() - height / 2.0; + break; + } + case 1: + { + root.x = GetX() + width / 2.0; + root.y = GetY() ; + break; + } + case 2: + { + root.x = GetX() ; + root.y = GetY() + height / 2.0; + break; + } + case 3: + { + root.x = GetX() - width / 2.0; + root.y = GetY() ; + break; + } + default: + { + wxFAIL_MSG( wxT("Unrecognised attachment point in GetBranchingAttachmentRoot.") ); + break; + } + } + return root; +} + +// Draw or erase the branches (not the actual arcs though) +void wxShape::OnDrawBranches(wxDC &dc, int attachment, bool erase) +{ + if (erase) + { + Refresh(); + return; + } + + int count = GetAttachmentLineCount(attachment); + if (count == 0) + return; + + wxRealPoint root, neck, shoulder1, shoulder2; + GetBranchingAttachmentInfo(attachment, root, neck, shoulder1, shoulder2); + +#if 0 + if (erase) + { + dc.SetPen(*wxWHITE_PEN); + dc.SetBrush(*wxWHITE_BRUSH); + } + else +#endif + { + dc.SetPen(*wxBLACK_PEN); + dc.SetBrush(*wxBLACK_BRUSH); + } + + // Draw neck + dc.DrawLine((long) root.x, (long) root.y, (long) neck.x, (long) neck.y); + + if (count > 1) + { + // Draw shoulder-to-shoulder line + dc.DrawLine((long) shoulder1.x, (long) shoulder1.y, (long) shoulder2.x, (long) shoulder2.y); + } + // Draw all the little branches + int i; + for (i = 0; i < count; i++) + { + wxRealPoint pt, stemPt; + GetBranchingAttachmentPoint(attachment, i, pt, stemPt); + dc.DrawLine((long) stemPt.x, (long) stemPt.y, (long) pt.x, (long) pt.y); + + if ((GetBranchStyle() & BRANCHING_ATTACHMENT_BLOB) && (count > 1)) + { + long blobSize = 6; +// dc.DrawEllipse((long) (stemPt.x + 0.5 - (blobSize/2.0)), (long) (stemPt.y + 0.5 - (blobSize/2.0)), blobSize, blobSize); + dc.DrawEllipse((long) (stemPt.x - (blobSize / 2.0)), (long) (stemPt.y - (blobSize / 2.0)), blobSize, blobSize); + } + } +} + +// Draw or erase the branches (not the actual arcs though) +void wxShape::OnDrawBranches(wxDC &dc, bool erase) +{ + if (m_attachmentMode != ATTACHMENT_MODE_BRANCHING) + return; + + int count = GetNumberOfAttachments(); + int i; + for (i = 0; i < count; i++) + OnDrawBranches(dc, i, erase); +} + +// Only get the attachment position at the _edge_ of the shape, ignoring +// branching mode. This is used e.g. to indicate the edge of interest, not the point +// on the attachment branch. +bool wxShape::GetAttachmentPositionEdge(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + int oldMode = m_attachmentMode; + + // Calculate as if to edge, not branch + if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING) + m_attachmentMode = ATTACHMENT_MODE_EDGE; + bool success = GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + m_attachmentMode = oldMode; + + return success; +} + +// Rotate the standard attachment point from physical (0 is always North) +// to logical (0 -> 1 if rotated by 90 degrees) +int wxShape::PhysicalToLogicalAttachment(int physicalAttachment) const +{ + const double pi = 3.1415926535897932384626433832795 ; + int i; + if (oglRoughlyEqual(GetRotation(), 0.0)) + { + i = physicalAttachment; + } + else if (oglRoughlyEqual(GetRotation(), (pi / 2.0))) + { + i = physicalAttachment - 1; + } + else if (oglRoughlyEqual(GetRotation(), pi)) + { + i = physicalAttachment - 2; + } + else if (oglRoughlyEqual(GetRotation(), (3.0 * pi / 2.0))) + { + i = physicalAttachment - 3; + } + else + // Can't handle -- assume the same. + return physicalAttachment; + + if (i < 0) + i += 4; + + return i; +} + +// Rotate the standard attachment point from logical +// to physical (0 is always North) +int wxShape::LogicalToPhysicalAttachment(int logicalAttachment) const +{ + const double pi = 3.1415926535897932384626433832795 ; + int i; + if (oglRoughlyEqual(GetRotation(), 0.0)) + { + i = logicalAttachment; + } + else if (oglRoughlyEqual(GetRotation(), (pi / 2.0))) + { + i = logicalAttachment + 1; + } + else if (oglRoughlyEqual(GetRotation(), pi)) + { + i = logicalAttachment + 2; + } + else if (oglRoughlyEqual(GetRotation(), (3.0 * pi / 2.0))) + { + i = logicalAttachment + 3; + } + else + // Can't handle -- assume the same. + return logicalAttachment; + + if (i > 3) + i -= 4; + + return i; +} + +void wxShape::Rotate(double WXUNUSED(x), double WXUNUSED(y), double theta) +{ + const double pi = 3.1415926535897932384626433832795 ; + m_rotation = theta; + if (m_rotation < 0.0) + { + m_rotation += 2 * pi; + } + else if (m_rotation > 2 * pi) + { + m_rotation -= 2 * pi; + } +} + + +wxPen wxShape::GetBackgroundPen() +{ + if (GetCanvas()) + { + wxColour c = GetCanvas()->GetBackgroundColour(); + return wxPen(c, 1, wxSOLID); + } + return * g_oglWhiteBackgroundPen; +} + + +wxBrush wxShape::GetBackgroundBrush() +{ + if (GetCanvas()) + { + wxColour c = GetCanvas()->GetBackgroundColour(); + return wxBrush(c, wxSOLID); + } + return * g_oglWhiteBackgroundBrush; +} + diff --git a/ogl/basic2.cpp b/ogl/basic2.cpp new file mode 100644 index 0000000..78d0541 --- /dev/null +++ b/ogl/basic2.cpp @@ -0,0 +1,1880 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// basic2.cpp - Basic OGL classes (2) +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +// Two stage construction: need to call Create +IMPLEMENT_DYNAMIC_CLASS(wxPolygonShape, wxShape) + +wxPolygonShape::wxPolygonShape() +{ + m_points = NULL; + m_originalPoints = NULL; +} + +void wxPolygonShape::Create(wxList *the_points) +{ + ClearPoints(); + + if (!the_points) + { + m_originalPoints = new wxList; + m_points = new wxList; + } + else + { + m_originalPoints = the_points; + + // Duplicate the list of points + m_points = new wxList; + + wxNode *node = the_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + m_points->Append((wxObject *) new_point); + node = node->GetNext(); + } + CalculateBoundingBox(); + m_originalWidth = m_boundWidth; + m_originalHeight = m_boundHeight; + SetDefaultRegionSize(); + } +} + +wxPolygonShape::~wxPolygonShape() +{ + ClearPoints(); +} + +void wxPolygonShape::ClearPoints() +{ + if (m_points) + { + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + delete point; + delete node; + node = m_points->GetFirst(); + } + delete m_points; + m_points = NULL; + } + if (m_originalPoints) + { + wxNode *node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + delete point; + delete node; + node = m_originalPoints->GetFirst(); + } + delete m_originalPoints; + m_originalPoints = NULL; + } +} + + +// Width and height. Centre of object is centre of box. +void wxPolygonShape::GetBoundingBoxMin(double *width, double *height) +{ + *width = m_boundWidth; + *height = m_boundHeight; +} + +void wxPolygonShape::CalculateBoundingBox() +{ + // Calculate bounding box at construction (and presumably resize) time + double left = 10000; + double right = -10000; + double top = 10000; + double bottom = -10000; + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x < left) left = point->x; + if (point->x > right) right = point->x; + + if (point->y < top) top = point->y; + if (point->y > bottom) bottom = point->y; + + node = node->GetNext(); + } + m_boundWidth = right - left; + m_boundHeight = bottom - top; +} + +// Recalculates the centre of the polygon, and +// readjusts the point offsets accordingly. +// Necessary since the centre of the polygon +// is expected to be the real centre of the bounding +// box. +void wxPolygonShape::CalculatePolygonCentre() +{ + double left = 10000; + double right = -10000; + double top = 10000; + double bottom = -10000; + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x < left) left = point->x; + if (point->x > right) right = point->x; + + if (point->y < top) top = point->y; + if (point->y > bottom) bottom = point->y; + + node = node->GetNext(); + } + double bwidth = right - left; + double bheight = bottom - top; + + double newCentreX = (double)(left + (bwidth / 2.0)); + double newCentreY = (double)(top + (bheight / 2.0)); + + node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + point->x -= newCentreX; + point->y -= newCentreY; + node = node->GetNext(); + } + m_xpos += newCentreX; + m_ypos += newCentreY; +} + +bool PolylineHitTest(double n, double xvec[], double yvec[], + double x1, double y1, double x2, double y2) +{ + bool isAHit = FALSE; + int i; + double lastx = xvec[0]; + double lasty = yvec[0]; + + double min_ratio = 1.0; + double line_ratio; + double other_ratio; + + for (i = 1; i < n; i++) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i], + &line_ratio, &other_ratio); + if (line_ratio != 1.0) + isAHit = TRUE; + lastx = xvec[i]; + lasty = yvec[i]; + + if (line_ratio < min_ratio) + min_ratio = line_ratio; + } + + // Do last (implicit) line if last and first doubles are not identical + if (!(xvec[0] == lastx && yvec[0] == lasty)) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0], + &line_ratio, &other_ratio); + if (line_ratio != 1.0) + isAHit = TRUE; + + } + return isAHit; +} + +bool wxPolygonShape::HitTest(double x, double y, int *attachment, double *distance) +{ + // Imagine four lines radiating from this point. If all of these lines hit the polygon, + // we're inside it, otherwise we're not. Obviously we'd need more radiating lines + // to be sure of correct results for very strange (concave) shapes. + double endPointsX[4]; + double endPointsY[4]; + // North + endPointsX[0] = x; + endPointsY[0] = (double)(y - 1000.0); + // East + endPointsX[1] = (double)(x + 1000.0); + endPointsY[1] = y; + // South + endPointsX[2] = x; + endPointsY[2] = (double)(y + 1000.0); + // West + endPointsX[3] = (double)(x - 1000.0); + endPointsY[3] = y; + + // Store polygon points in an array + int np = m_points->GetCount(); + double *xpoints = new double[np]; + double *ypoints = new double[np]; + wxNode *node = m_points->GetFirst(); + int i = 0; + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + xpoints[i] = point->x + m_xpos; + ypoints[i] = point->y + m_ypos; + node = node->GetNext(); + i ++; + } + + // We assume it's inside the polygon UNLESS one or more + // lines don't hit the outline. + bool isContained = TRUE; + + int noPoints = 4; + for (i = 0; i < noPoints; i++) + { + if (!PolylineHitTest(np, xpoints, ypoints, x, y, endPointsX[i], endPointsY[i])) + isContained = FALSE; + } + /* + if (isContained) + ClipsErrorFunction("It's a hit!\n"); + else + ClipsErrorFunction("No hit.\n"); + */ + delete[] xpoints; + delete[] ypoints; + + if (!isContained) + return FALSE; + + int nearest_attachment = 0; + + // If a hit, check the attachment points within the object. + int n = GetNumberOfAttachments(); + double nearest = 999999.0; + + for (i = 0; i < n; i++) + { + double xp, yp; + if (GetAttachmentPositionEdge(i, &xp, &yp)) + { + double l = (double)sqrt(((xp - x) * (xp - x)) + + ((yp - y) * (yp - y))); + if (l < nearest) + { + nearest = l; + nearest_attachment = i; + } + } + } + *attachment = nearest_attachment; + *distance = nearest; + return TRUE; +} + +// Really need to be able to reset the shape! Otherwise, if the +// points ever go to zero, we've lost it, and can't resize. +void wxPolygonShape::SetSize(double new_width, double new_height, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(new_width, new_height); + + // Multiply all points by proportion of new size to old size + double x_proportion = (double)(fabs(new_width / m_originalWidth)); + double y_proportion = (double)(fabs(new_height / m_originalHeight)); + + wxNode *node = m_points->GetFirst(); + wxNode *original_node = m_originalPoints->GetFirst(); + while (node && original_node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *original_point = (wxRealPoint *)original_node->GetData(); + + point->x = (original_point->x * x_proportion); + point->y = (original_point->y * y_proportion); + + node = node->GetNext(); + original_node = original_node->GetNext(); + } + +// CalculateBoundingBox(); + m_boundWidth = (double)fabs(new_width); + m_boundHeight = (double)fabs(new_height); + SetDefaultRegionSize(); +} + +// Make the original points the same as the working points +void wxPolygonShape::UpdateOriginalPoints() +{ + if (!m_originalPoints) m_originalPoints = new wxList; + wxNode *original_node = m_originalPoints->GetFirst(); + while (original_node) + { + wxNode *next_node = original_node->GetNext(); + wxRealPoint *original_point = (wxRealPoint *)original_node->GetData(); + delete original_point; + delete original_node; + + original_node = next_node; + } + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *original_point = new wxRealPoint(point->x, point->y); + m_originalPoints->Append((wxObject *) original_point); + + node = node->GetNext(); + } + CalculateBoundingBox(); + m_originalWidth = m_boundWidth; + m_originalHeight = m_boundHeight; +} + +void wxPolygonShape::AddPolygonPoint(int pos) +{ + wxNode *node = m_points->Item(pos); + if (!node) node = m_points->GetFirst(); + wxRealPoint *firstPoint = (wxRealPoint *)node->GetData(); + + wxNode *node2 = m_points->Item(pos + 1); + if (!node2) node2 = m_points->GetFirst(); + wxRealPoint *secondPoint = (wxRealPoint *)node2->GetData(); + + double x = (double)((secondPoint->x - firstPoint->x) / 2.0 + firstPoint->x); + double y = (double)((secondPoint->y - firstPoint->y) / 2.0 + firstPoint->y); + wxRealPoint *point = new wxRealPoint(x, y); + + if (pos >= (int) (m_points->GetCount() - 1)) + m_points->Append((wxObject *) point); + else + m_points->Insert(node2, (wxObject *) point); + + UpdateOriginalPoints(); + + if (m_selected) + { + DeleteControlPoints(); + MakeControlPoints(); + } +} + +void wxPolygonShape::DeletePolygonPoint(int pos) +{ + wxNode *node = m_points->Item(pos); + if (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + delete point; + delete node; + UpdateOriginalPoints(); + if (m_selected) + { + DeleteControlPoints(); + MakeControlPoints(); + } + } +} + +// Assume (x1, y1) is centre of box (most generally, line end at box) +bool wxPolygonShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) +{ + int n = m_points->GetCount(); + + // First check for situation where the line is vertical, + // and we would want to connect to a point on that vertical -- + // oglFindEndForPolyline can't cope with this (the arrow + // gets drawn to the wrong place). + if ((m_attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2)) + { + // Look for the point we'd be connecting to. This is + // a heuristic... + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x == 0.0) + { + if ((y2 > y1) && (point->y > 0.0)) + { + *x3 = point->x + m_xpos; + *y3 = point->y + m_ypos; + return TRUE; + } + else if ((y2 < y1) && (point->y < 0.0)) + { + *x3 = point->x + m_xpos; + *y3 = point->y + m_ypos; + return TRUE; + } + } + node = node->GetNext(); + } + } + + double *xpoints = new double[n]; + double *ypoints = new double[n]; + + wxNode *node = m_points->GetFirst(); + int i = 0; + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + xpoints[i] = point->x + m_xpos; + ypoints[i] = point->y + m_ypos; + node = node->GetNext(); + i ++; + } + + oglFindEndForPolyline(n, xpoints, ypoints, + x1, y1, x2, y2, x3, y3); + + delete[] xpoints; + delete[] ypoints; + + return TRUE; +} + +void wxPolygonShape::OnDraw(wxDC &dc) +{ + int n = m_points->GetCount(); + wxPoint *intPoints = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = (wxRealPoint *) m_points->Item(i)->GetData(); + intPoints[i].x = WXROUND(point->x); + intPoints[i].y = WXROUND(point->y); + } + + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + + dc.DrawPolygon(n, intPoints, WXROUND(m_xpos + m_shadowOffsetX), WXROUND(m_ypos + m_shadowOffsetY)); + } + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + if (m_brush) + dc.SetBrush(* m_brush); + dc.DrawPolygon(n, intPoints, WXROUND(m_xpos), WXROUND(m_ypos)); + + delete[] intPoints; +} + +void wxPolygonShape::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + dc.SetBrush(* wxTRANSPARENT_BRUSH); + // Multiply all points by proportion of new size to old size + double x_proportion = (double)(fabs(w / m_originalWidth)); + double y_proportion = (double)(fabs(h / m_originalHeight)); + + int n = m_originalPoints->GetCount(); + wxPoint *intPoints = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = (wxRealPoint *) m_originalPoints->Item(i)->GetData(); + intPoints[i].x = WXROUND(x_proportion * point->x); + intPoints[i].y = WXROUND(y_proportion * point->y); + } + dc.DrawPolygon(n, intPoints, WXROUND(x), WXROUND(y)); + delete[] intPoints; +} + +// Make as many control points as there are vertices. +void wxPolygonShape::MakeControlPoints() +{ + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxPolygonControlPoint *control = new wxPolygonControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + point, point->x, point->y); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + node = node->GetNext(); + } +} + +void wxPolygonShape::ResetControlPoints() +{ + wxNode *node = m_points->GetFirst(); + wxNode *controlPointNode = m_controlPoints.GetFirst(); + while (node && controlPointNode) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxPolygonControlPoint *controlPoint = (wxPolygonControlPoint *)controlPointNode->GetData(); + + controlPoint->m_xoffset = point->x; + controlPoint->m_yoffset = point->y; + controlPoint->m_polygonVertex = point; + + node = node->GetNext(); + controlPointNode = controlPointNode->GetNext(); + } +} + + +#if wxUSE_PROLOGIO +void wxPolygonShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + + clause->AddAttributeValue(wxT("x"), m_xpos); + clause->AddAttributeValue(wxT("y"), m_ypos); + + // Make a list of lists for the coordinates + wxExpr *list = new wxExpr(wxExprList); + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxExpr *point_list = new wxExpr(wxExprList); + wxExpr *x_expr = new wxExpr((double)point->x); + wxExpr *y_expr = new wxExpr((double)point->y); + + point_list->Append(x_expr); + point_list->Append(y_expr); + list->Append(point_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("points"), list); + + // Save the original (unscaled) points + list = new wxExpr(wxExprList); + node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxExpr *point_list = new wxExpr(wxExprList); + wxExpr *x_expr = new wxExpr((double) point->x); + wxExpr *y_expr = new wxExpr((double) point->y); + point_list->Append(x_expr); + point_list->Append(y_expr); + list->Append(point_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("m_originalPoints"), list); +} + +void wxPolygonShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + + // Read a list of lists + m_points = new wxList; + m_originalPoints = new wxList; + + wxExpr *points_list = NULL; + clause->AssignAttributeValue(wxT("points"), &points_list); + + // If no points_list, don't crash!! Assume a diamond instead. + double the_height = 100.0; + double the_width = 100.0; + if (!points_list) + { + wxRealPoint *point = new wxRealPoint(0.0, (-the_height / 2)); + m_points->Append((wxObject *) point); + + point = new wxRealPoint((the_width / 2), 0.0); + m_points->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (the_height / 2)); + m_points->Append((wxObject *) point); + + point = new wxRealPoint((-the_width / 2), 0.0); + m_points->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (-the_height / 2)); + m_points->Append((wxObject *) point); + } + else + { + wxExpr *node = points_list->value.first; + + while (node) + { + wxExpr *xexpr = node->value.first; + long x = xexpr->IntegerValue(); + + wxExpr *yexpr = xexpr->next; + long y = yexpr->IntegerValue(); + + wxRealPoint *point = new wxRealPoint((double)x, (double)y); + m_points->Append((wxObject *) point); + + node = node->next; + } + } + + points_list = NULL; + clause->AssignAttributeValue(wxT("m_originalPoints"), &points_list); + + // If no points_list, don't crash!! Assume a diamond instead. + if (!points_list) + { + wxRealPoint *point = new wxRealPoint(0.0, (-the_height / 2)); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint((the_width / 2), 0.0); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (the_height / 2)); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint((-the_width / 2), 0.0); + m_originalPoints->Append((wxObject *) point); + + point = new wxRealPoint(0.0, (-the_height / 2)); + m_originalPoints->Append((wxObject *) point); + + m_originalWidth = the_width; + m_originalHeight = the_height; + } + else + { + wxExpr *node = points_list->value.first; + double min_x = 1000; + double min_y = 1000; + double max_x = -1000; + double max_y = -1000; + while (node) + { + wxExpr *xexpr = node->value.first; + long x = xexpr->IntegerValue(); + + wxExpr *yexpr = xexpr->next; + long y = yexpr->IntegerValue(); + + wxRealPoint *point = new wxRealPoint((double)x, (double)y); + m_originalPoints->Append((wxObject *) point); + + if (x < min_x) + min_x = (double)x; + if (y < min_y) + min_y = (double)y; + if (x > max_x) + max_x = (double)x; + if (y > max_y) + max_y = (double)y; + + node = node->next; + } + m_originalWidth = max_x - min_x; + m_originalHeight = max_y - min_y; + } + + CalculateBoundingBox(); +} +#endif + +void wxPolygonShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxPolygonShape)) ); + + wxPolygonShape &polyCopy = (wxPolygonShape &) copy; + + polyCopy.ClearPoints(); + + polyCopy.m_points = new wxList; + polyCopy.m_originalPoints = new wxList; + + wxNode *node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + polyCopy.m_points->Append((wxObject *) new_point); + node = node->GetNext(); + } + node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + polyCopy.m_originalPoints->Append((wxObject *) new_point); + node = node->GetNext(); + } + polyCopy.m_boundWidth = m_boundWidth; + polyCopy.m_boundHeight = m_boundHeight; + polyCopy.m_originalWidth = m_originalWidth; + polyCopy.m_originalHeight = m_originalHeight; +} + +int wxPolygonShape::GetNumberOfAttachments() const +{ + int maxN = (m_points ? (m_points->GetCount() - 1) : 0); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id > maxN) + maxN = point->m_id; + node = node->GetNext(); + } + return maxN + 1;; +} + +bool wxPolygonShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + if ((m_attachmentMode == ATTACHMENT_MODE_EDGE) && m_points && attachment < (int) m_points->GetCount()) + { + wxRealPoint *point = (wxRealPoint *)m_points->Item(attachment)->GetData(); + *x = point->x + m_xpos; + *y = point->y + m_ypos; + return TRUE; + } + else + { + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + } +} + +bool wxPolygonShape::AttachmentIsValid(int attachment) const +{ + if (!m_points) + return FALSE; + + if ((attachment >= 0) && (attachment < (int) m_points->GetCount())) + return TRUE; + + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id == attachment) + return TRUE; + node = node->GetNext(); + } + return FALSE; +} + +// Rotate about the given axis by the given amount in radians +void wxPolygonShape::Rotate(double x, double y, double theta) +{ + double actualTheta = theta - m_rotation; + + // Rotate attachment points + double sinTheta = (double)sin(actualTheta); + double cosTheta = (double)cos(actualTheta); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + double x1 = point->m_x; + double y1 = point->m_y; + point->m_x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->m_y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + + node = m_points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + double x1 = point->x; + double y1 = point->y; + point->x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + node = m_originalPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + double x1 = point->x; + double y1 = point->y; + point->x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + + m_rotation = theta; + + CalculatePolygonCentre(); + CalculateBoundingBox(); + ResetControlPoints(); +} + +// Rectangle object + +IMPLEMENT_DYNAMIC_CLASS(wxRectangleShape, wxShape) + +wxRectangleShape::wxRectangleShape(double w, double h) +{ + m_width = w; + m_height = h; + m_cornerRadius = 0.0; + SetDefaultRegionSize(); +} + +void wxRectangleShape::OnDraw(wxDC &dc) +{ + double x1 = (double)(m_xpos - m_width / 2.0); + double y1 = (double)(m_ypos - m_height / 2.0); + + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + + if (m_cornerRadius != 0.0) + dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), + WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height)); + } + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + if (m_brush) + dc.SetBrush(* m_brush); + + if (m_cornerRadius != 0.0) + dc.DrawRoundedRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height)); +} + +void wxRectangleShape::GetBoundingBoxMin(double *the_width, double *the_height) +{ + *the_width = m_width; + *the_height = m_height; +} + +void wxRectangleShape::SetSize(double x, double y, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(x, y); + m_width = (double)wxMax(x, 1.0); + m_height = (double)wxMax(y, 1.0); + SetDefaultRegionSize(); +} + +void wxRectangleShape::SetCornerRadius(double rad) +{ + m_cornerRadius = rad; +} + +// Assume (x1, y1) is centre of box (most generally, line end at box) +bool wxRectangleShape::GetPerimeterPoint(double WXUNUSED(x1), double WXUNUSED(y1), + double x2, double y2, + double *x3, double *y3) +{ + double bound_x, bound_y; + GetBoundingBoxMax(&bound_x, &bound_y); + oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3); + + return TRUE; +} + +#if wxUSE_PROLOGIO +void wxRectangleShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + clause->AddAttributeValue(wxT("x"), m_xpos); + clause->AddAttributeValue(wxT("y"), m_ypos); + + clause->AddAttributeValue(wxT("width"), m_width); + clause->AddAttributeValue(wxT("height"), m_height); + if (m_cornerRadius != 0.0) + clause->AddAttributeValue(wxT("corner"), m_cornerRadius); +} + +void wxRectangleShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + clause->AssignAttributeValue(wxT("width"), &m_width); + clause->AssignAttributeValue(wxT("height"), &m_height); + clause->AssignAttributeValue(wxT("corner"), &m_cornerRadius); + + // In case we're reading an old file, set the region's size + if (m_regions.GetCount() == 1) + { + wxShapeRegion *region = (wxShapeRegion *)m_regions.GetFirst()->GetData(); + region->SetSize(m_width, m_height); + } +} +#endif + +void wxRectangleShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxRectangleShape)) ); + + wxRectangleShape &rectCopy = (wxRectangleShape &) copy; + rectCopy.m_width = m_width; + rectCopy.m_height = m_height; + rectCopy.m_cornerRadius = m_cornerRadius; +} + +int wxRectangleShape::GetNumberOfAttachments() const +{ + return wxShape::GetNumberOfAttachments(); +} + + +// There are 4 attachment points on a rectangle - 0 = top, 1 = right, 2 = bottom, +// 3 = left. +bool wxRectangleShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); +} + +// Text object (no box) + +IMPLEMENT_DYNAMIC_CLASS(wxTextShape, wxRectangleShape) + +wxTextShape::wxTextShape(double width, double height): + wxRectangleShape(width, height) +{ +} + +void wxTextShape::OnDraw(wxDC &WXUNUSED(dc)) +{ +} + +void wxTextShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); +} + +#if wxUSE_PROLOGIO +void wxTextShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); +} +#endif + +// Ellipse object + +IMPLEMENT_DYNAMIC_CLASS(wxEllipseShape, wxShape) + +wxEllipseShape::wxEllipseShape(double w, double h) +{ + m_width = w; + m_height = h; + SetDefaultRegionSize(); +} + +void wxEllipseShape::GetBoundingBoxMin(double *w, double *h) +{ + *w = m_width; + *h = m_height; +} + +bool wxEllipseShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) +{ + double bound_x, bound_y; + GetBoundingBoxMax(&bound_x, &bound_y); + +// oglFindEndForBox(bound_x, bound_y, m_xpos, m_ypos, x2, y2, x3, y3); + oglDrawArcToEllipse(m_xpos, m_ypos, bound_x, bound_y, x2, y2, x1, y1, x3, y3); + + return TRUE; +} + +void wxEllipseShape::OnDraw(wxDC &dc) +{ + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + dc.DrawEllipse((long) ((m_xpos - GetWidth() / 2) + m_shadowOffsetX), + (long) ((m_ypos - GetHeight() / 2) + m_shadowOffsetY), + (long) GetWidth(), (long) GetHeight()); + } + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + if (m_brush) + dc.SetBrush(* m_brush); + dc.DrawEllipse((long) (m_xpos - GetWidth() / 2), (long) (m_ypos - GetHeight() / 2), (long) GetWidth(), (long) GetHeight()); +} + +void wxEllipseShape::SetSize(double x, double y, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(x, y); + m_width = x; + m_height = y; + SetDefaultRegionSize(); +} + +#if wxUSE_PROLOGIO +void wxEllipseShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + clause->AddAttributeValue(wxT("x"), m_xpos); + clause->AddAttributeValue(wxT("y"), m_ypos); + + clause->AddAttributeValue(wxT("width"), m_width); + clause->AddAttributeValue(wxT("height"), m_height); +} + +void wxEllipseShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + clause->AssignAttributeValue(wxT("width"), &m_width); + clause->AssignAttributeValue(wxT("height"), &m_height); + + // In case we're reading an old file, set the region's size + if (m_regions.GetCount() == 1) + { + wxShapeRegion *region = (wxShapeRegion *)m_regions.GetFirst()->GetData(); + region->SetSize(m_width, m_height); + } +} +#endif + +void wxEllipseShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxEllipseShape)) ); + + wxEllipseShape &ellipseCopy = (wxEllipseShape &) copy; + + ellipseCopy.m_width = m_width; + ellipseCopy.m_height = m_height; +} + +int wxEllipseShape::GetNumberOfAttachments() const +{ + return wxShape::GetNumberOfAttachments(); +} + +// There are 4 attachment points on an ellipse - 0 = top, 1 = right, 2 = bottom, +// 3 = left. +bool wxEllipseShape::GetAttachmentPosition(int attachment, double *x, double *y, + int nth, int no_arcs, wxLineShape *line) +{ + if (m_attachmentMode == ATTACHMENT_MODE_BRANCHING) + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + + if (m_attachmentMode != ATTACHMENT_MODE_NONE) + { + double top = (double)(m_ypos + m_height / 2.0); + double bottom = (double)(m_ypos - m_height / 2.0); + double left = (double)(m_xpos - m_width / 2.0); + double right = (double)(m_xpos + m_width / 2.0); + + int physicalAttachment = LogicalToPhysicalAttachment(attachment); + + switch (physicalAttachment) + { + case 0: + { + if (m_spaceAttachments) + *x = left + (nth + 1) * m_width / (no_arcs + 1); + else *x = m_xpos; + *y = top; + // We now have the point on the bounding box: but get the point on the ellipse + // by imagining a vertical line from (*x, m_ypos - m_height- 500) to (*x, m_ypos) intersecting + // the ellipse. + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos - m_height - 500), *x, m_ypos, x, y); + break; + } + case 1: + { + *x = right; + if (m_spaceAttachments) + *y = bottom + (nth + 1) * m_height / (no_arcs + 1); + else *y = m_ypos; + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos + m_width + 500), *y, m_xpos, *y, x, y); + break; + } + case 2: + { + if (m_spaceAttachments) + *x = left + (nth + 1) * m_width / (no_arcs + 1); + else *x = m_xpos; + *y = bottom; + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, *x, (double)(m_ypos + m_height + 500), *x, m_ypos, x, y); + break; + } + case 3: + { + *x = left; + if (m_spaceAttachments) + *y = bottom + (nth + 1) * m_height / (no_arcs + 1); + else *y = m_ypos; + oglDrawArcToEllipse(m_xpos, m_ypos, m_width, m_height, (double)(m_xpos - m_width - 500), *y, m_xpos, *y, x, y); + break; + } + default: + { + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs, line); + } + } + return TRUE; + } + else + { + *x = m_xpos; + *y = m_ypos; + return TRUE; + } +} + + +// Circle object +IMPLEMENT_DYNAMIC_CLASS(wxCircleShape, wxEllipseShape) + +wxCircleShape::wxCircleShape(double diameter): wxEllipseShape(diameter, diameter) +{ + SetMaintainAspectRatio(TRUE); +} + +void wxCircleShape::Copy(wxShape ©) +{ + wxEllipseShape::Copy(copy); +} + +bool wxCircleShape::GetPerimeterPoint(double WXUNUSED(x1), double WXUNUSED(y1), + double x2, double y2, + double *x3, double *y3) +{ + oglFindEndForCircle(m_width / 2, + m_xpos, m_ypos, // Centre of circle + x2, y2, // Other end of line + x3, y3); + + return TRUE; +} + +// Control points + +double wxControlPoint::sm_controlPointDragStartX = 0.0; +double wxControlPoint::sm_controlPointDragStartY = 0.0; +double wxControlPoint::sm_controlPointDragStartWidth = 0.0; +double wxControlPoint::sm_controlPointDragStartHeight = 0.0; +double wxControlPoint::sm_controlPointDragEndWidth = 0.0; +double wxControlPoint::sm_controlPointDragEndHeight = 0.0; +double wxControlPoint::sm_controlPointDragPosX = 0.0; +double wxControlPoint::sm_controlPointDragPosY = 0.0; + +IMPLEMENT_DYNAMIC_CLASS(wxControlPoint, wxRectangleShape) + +wxControlPoint::wxControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type): wxRectangleShape(size, size) +{ + m_canvas = theCanvas; + m_shape = object; + m_xoffset = the_xoffset; + m_yoffset = the_yoffset; + m_type = the_type; + SetPen(g_oglBlackForegroundPen); + SetBrush((wxBrush *) wxBLACK_BRUSH); + m_oldCursor = NULL; + m_visible = TRUE; + m_eraseObject = TRUE; +} + +wxControlPoint::~wxControlPoint() +{ +} + +// Don't even attempt to draw any text - waste of time! +void wxControlPoint::OnDrawContents(wxDC &WXUNUSED(dc)) +{ +} + +void wxControlPoint::OnDraw(wxDC &dc) +{ + m_xpos = m_shape->GetX() + m_xoffset; + m_ypos = m_shape->GetY() + m_yoffset; + wxRectangleShape::OnDraw(dc); +} + +// Implement resizing of canvas object +void wxControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment); +} + +void wxControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment); +} + +void wxControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment); +} + +int wxControlPoint::GetNumberOfAttachments() const +{ + return 1; +} + +bool wxControlPoint::GetAttachmentPosition(int WXUNUSED(attachment), double *x, double *y, + int WXUNUSED(nth), int WXUNUSED(no_arcs), wxLineShape *WXUNUSED(line)) +{ + *x = m_xpos; + *y = m_ypos; + return TRUE; +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxShape::OnSizingDragLeft(wxControlPoint *pt, bool WXUNUSED(draw), double x, double y, int keys, int WXUNUSED(attachment)) +{ + double bound_x; + double bound_y; + this->GetBoundingBoxMin(&bound_x, &bound_y); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + if (this->GetCentreResize()) + { + // Maintain the same centre point. + double new_width = (double)(2.0 * fabs(x - this->GetX())); + double new_height = (double)(2.0 * fabs(y - this->GetY())); + + // Constrain sizing according to what control point you're dragging + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + if (GetMaintainAspectRatio()) + { + new_height = bound_y * (new_width / bound_x); + } + else + new_height = bound_y; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + if (GetMaintainAspectRatio()) + { + new_width = bound_x * (new_height / bound_y); + } + else + new_width = bound_x; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT)) + new_height = bound_y * (new_width / bound_x); + + if (this->GetFixedWidth()) + new_width = bound_x; + + if (this->GetFixedHeight()) + new_height = bound_y; + + pt->sm_controlPointDragEndWidth = new_width; + pt->sm_controlPointDragEndHeight = new_height; + + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + new_width, new_height); + } + else + { + // Don't maintain the same centre point! + double newX1 = wxMin(pt->sm_controlPointDragStartX, x); + double newY1 = wxMin(pt->sm_controlPointDragStartY, y); + double newX2 = wxMax(pt->sm_controlPointDragStartX, x); + double newY2 = wxMax(pt->sm_controlPointDragStartY, y); + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + newY1 = pt->sm_controlPointDragStartY; + newY2 = newY1 + pt->sm_controlPointDragStartHeight; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + newX1 = pt->sm_controlPointDragStartX; + newX2 = newX1 + pt->sm_controlPointDragStartWidth; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && ((keys & KEY_SHIFT) || GetMaintainAspectRatio())) + { + double newH = (double)((newX2 - newX1) * (pt->sm_controlPointDragStartHeight / pt->sm_controlPointDragStartWidth)); + if (GetY() > pt->sm_controlPointDragStartY) + newY2 = (double)(newY1 + newH); + else + newY1 = (double)(newY2 - newH); + } + double newWidth = (double)(newX2 - newX1); + double newHeight = (double)(newY2 - newY1); + + if (pt->m_type == CONTROL_POINT_VERTICAL && GetMaintainAspectRatio()) + { + newWidth = bound_x * (newHeight / bound_y) ; + } + + if (pt->m_type == CONTROL_POINT_HORIZONTAL && GetMaintainAspectRatio()) + { + newHeight = bound_y * (newWidth / bound_x) ; + } + + pt->sm_controlPointDragPosX = (double)(newX1 + (newWidth / 2.0)); + pt->sm_controlPointDragPosY = (double)(newY1 + (newHeight / 2.0)); + if (this->GetFixedWidth()) + newWidth = bound_x; + + if (this->GetFixedHeight()) + newHeight = bound_y; + + pt->sm_controlPointDragEndWidth = newWidth; + pt->sm_controlPointDragEndHeight = newHeight; + this->GetEventHandler()->OnDrawOutline(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY, newWidth, newHeight); + } +} + +void wxShape::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int keys, int WXUNUSED(attachment)) +{ + m_canvas->CaptureMouse(); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + /* + if (pt->m_eraseObject) + this->Erase(dc); + */ + + dc.SetLogicalFunction(OGLRBLF); + + double bound_x; + double bound_y; + this->GetBoundingBoxMin(&bound_x, &bound_y); + + // Choose the 'opposite corner' of the object as the stationary + // point in case this is non-centring resizing. + if (pt->GetX() < this->GetX()) + pt->sm_controlPointDragStartX = (double)(this->GetX() + (bound_x / 2.0)); + else + pt->sm_controlPointDragStartX = (double)(this->GetX() - (bound_x / 2.0)); + + if (pt->GetY() < this->GetY()) + pt->sm_controlPointDragStartY = (double)(this->GetY() + (bound_y / 2.0)); + else + pt->sm_controlPointDragStartY = (double)(this->GetY() - (bound_y / 2.0)); + + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + pt->sm_controlPointDragStartY = (double)(this->GetY() - (bound_y / 2.0)); + else if (pt->m_type == CONTROL_POINT_VERTICAL) + pt->sm_controlPointDragStartX = (double)(this->GetX() - (bound_x / 2.0)); + + // We may require the old width and height. + pt->sm_controlPointDragStartWidth = bound_x; + pt->sm_controlPointDragStartHeight = bound_y; + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + if (this->GetCentreResize()) + { + double new_width = (double)(2.0 * fabs(x - this->GetX())); + double new_height = (double)(2.0 * fabs(y - this->GetY())); + + // Constrain sizing according to what control point you're dragging + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + if (GetMaintainAspectRatio()) + { + new_height = bound_y * (new_width / bound_x); + } + else + new_height = bound_y; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + if (GetMaintainAspectRatio()) + { + new_width = bound_x * (new_height / bound_y); + } + else + new_width = bound_x; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && (keys & KEY_SHIFT)) + new_height = bound_y * (new_width / bound_x); + + if (this->GetFixedWidth()) + new_width = bound_x; + + if (this->GetFixedHeight()) + new_height = bound_y; + + pt->sm_controlPointDragEndWidth = new_width; + pt->sm_controlPointDragEndHeight = new_height; + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + new_width, new_height); + } + else + { + // Don't maintain the same centre point! + double newX1 = wxMin(pt->sm_controlPointDragStartX, x); + double newY1 = wxMin(pt->sm_controlPointDragStartY, y); + double newX2 = wxMax(pt->sm_controlPointDragStartX, x); + double newY2 = wxMax(pt->sm_controlPointDragStartY, y); + if (pt->m_type == CONTROL_POINT_HORIZONTAL) + { + newY1 = pt->sm_controlPointDragStartY; + newY2 = newY1 + pt->sm_controlPointDragStartHeight; + } + else if (pt->m_type == CONTROL_POINT_VERTICAL) + { + newX1 = pt->sm_controlPointDragStartX; + newX2 = newX1 + pt->sm_controlPointDragStartWidth; + } + else if (pt->m_type == CONTROL_POINT_DIAGONAL && ((keys & KEY_SHIFT) || GetMaintainAspectRatio())) + { + double newH = (double)((newX2 - newX1) * (pt->sm_controlPointDragStartHeight / pt->sm_controlPointDragStartWidth)); + if (pt->GetY() > pt->sm_controlPointDragStartY) + newY2 = (double)(newY1 + newH); + else + newY1 = (double)(newY2 - newH); + } + double newWidth = (double)(newX2 - newX1); + double newHeight = (double)(newY2 - newY1); + + if (pt->m_type == CONTROL_POINT_VERTICAL && GetMaintainAspectRatio()) + { + newWidth = bound_x * (newHeight / bound_y) ; + } + + if (pt->m_type == CONTROL_POINT_HORIZONTAL && GetMaintainAspectRatio()) + { + newHeight = bound_y * (newWidth / bound_x) ; + } + + pt->sm_controlPointDragPosX = (double)(newX1 + (newWidth / 2.0)); + pt->sm_controlPointDragPosY = (double)(newY1 + (newHeight / 2.0)); + if (this->GetFixedWidth()) + newWidth = bound_x; + + if (this->GetFixedHeight()) + newHeight = bound_y; + + pt->sm_controlPointDragEndWidth = newWidth; + pt->sm_controlPointDragEndHeight = newHeight; + this->GetEventHandler()->OnDrawOutline(dc, pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY, newWidth, newHeight); + } +} + +void wxShape::OnSizingEndDragLeft(wxControlPoint *pt, double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + m_canvas->ReleaseMouse(); + this->Recompute(); + this->ResetControlPoints(); + + this->Erase(); + /* + if (!pt->m_eraseObject) + this->Show(FALSE); + */ + + this->SetSize(pt->sm_controlPointDragEndWidth, pt->sm_controlPointDragEndHeight); + + // The next operation could destroy this control point (it does for label objects, + // via formatting the text), so save all values we're going to use, or + // we'll be accessing garbage. + wxShape *theObject = this; + wxShapeCanvas *theCanvas = m_canvas; + bool eraseIt = pt->m_eraseObject; + + if (theObject->GetCentreResize()) + theObject->Move(theObject->GetX(), theObject->GetY()); + else + theObject->Move(pt->sm_controlPointDragPosX, pt->sm_controlPointDragPosY); + + /* + if (!eraseIt) + theObject->Show(TRUE); + */ + + double width, height; + theObject->GetBoundingBoxMax(&width, &height); + theObject->GetEventHandler()->OnEndSize(width, height); + + theCanvas->Refresh(); +} + + + +// Polygon control points + +IMPLEMENT_DYNAMIC_CLASS(wxPolygonControlPoint, wxControlPoint) + +wxPolygonControlPoint::wxPolygonControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, + wxRealPoint *vertex, double the_xoffset, double the_yoffset): + wxControlPoint(theCanvas, object, size, the_xoffset, the_yoffset, 0) +{ + m_polygonVertex = vertex; + m_originalDistance = 0.0; +} + +wxPolygonControlPoint::~wxPolygonControlPoint() +{ +} + +// Calculate what new size would be, at end of resize +void wxPolygonControlPoint::CalculateNewSize(double x, double y) +{ + double bound_x; + double bound_y; + GetShape()->GetBoundingBoxMin(&bound_x, &bound_y); + + double dist = (double)sqrt((x - m_shape->GetX()) * (x - m_shape->GetX()) + + (y - m_shape->GetY()) * (y - m_shape->GetY())); + + m_newSize.x = (double)(dist / this->m_originalDistance) * this->m_originalSize.x; + m_newSize.y = (double)(dist / this->m_originalDistance) * this->m_originalSize.y; +} + + +// Implement resizing polygon or moving the vertex. +void wxPolygonControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment); +} + +void wxPolygonControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment); +} + +void wxPolygonControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment); +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxPolygonShape::OnSizingDragLeft(wxControlPoint *pt, bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxPolygonControlPoint *ppt = (wxPolygonControlPoint *) pt; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + +#if 0 // keys & KEY_CTRL) + { + // TODO: mend this code. Currently we rely on altering the + // actual points, but we should assume we're not, as per + // the normal sizing case. + m_canvas->Snap(&x, &y); + + // Move point + ppt->m_polygonVertex->x = x - this->GetX(); + ppt->m_polygonVertex->y = y - this->GetY(); + ppt->SetX(x); + ppt->SetY(y); + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->CalculatePolygonCentre(); + } +#else + { + ppt->CalculateNewSize(x, y); + } +#endif + + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + ppt->GetNewSize().x, ppt->GetNewSize().y); +} + +void wxPolygonShape::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxPolygonControlPoint *ppt = (wxPolygonControlPoint *) pt; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + this->Erase(); + + dc.SetLogicalFunction(OGLRBLF); + + double bound_x; + double bound_y; + this->GetBoundingBoxMin(&bound_x, &bound_y); + + double dist = (double)sqrt((x - this->GetX()) * (x - this->GetX()) + + (y - this->GetY()) * (y - this->GetY())); + ppt->m_originalDistance = dist; + ppt->m_originalSize.x = bound_x; + ppt->m_originalSize.y = bound_y; + + if (ppt->m_originalDistance == 0.0) ppt->m_originalDistance = (double) 0.0001; + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + +#if 0 // keys & KEY_CTRL) + { + // TODO: mend this code. Currently we rely on altering the + // actual points, but we should assume we're not, as per + // the normal sizing case. + m_canvas->Snap(&x, &y); + + // Move point + ppt->m_polygonVertex->x = x - this->GetX(); + ppt->m_polygonVertex->y = y - this->GetY(); + ppt->SetX(x); + ppt->SetY(y); + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->CalculatePolygonCentre(); + } +#else + { + ppt->CalculateNewSize(x, y); + } +#endif + + this->GetEventHandler()->OnDrawOutline(dc, this->GetX(), this->GetY(), + ppt->GetNewSize().x, ppt->GetNewSize().y); + + m_canvas->CaptureMouse(); +} + +void wxPolygonShape::OnSizingEndDragLeft(wxControlPoint *pt, double WXUNUSED(x), double WXUNUSED(y), int keys, int WXUNUSED(attachment)) +{ + wxPolygonControlPoint *ppt = (wxPolygonControlPoint *) pt; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + m_canvas->ReleaseMouse(); + dc.SetLogicalFunction(wxCOPY); + + // If we're changing shape, must reset the original points + if (keys & KEY_CTRL) + { + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->UpdateOriginalPoints(); + } + else + { + SetSize(ppt->GetNewSize().x, ppt->GetNewSize().y); + } + + ((wxPolygonShape *)this)->CalculateBoundingBox(); + ((wxPolygonShape *)this)->CalculatePolygonCentre(); + + this->Recompute(); + this->ResetControlPoints(); + this->Move(this->GetX(), this->GetY()); + m_canvas->Refresh(); +} + +/* + * Object region + * + */ +IMPLEMENT_DYNAMIC_CLASS(wxShapeRegion, wxObject) + +wxShapeRegion::wxShapeRegion() +{ + m_regionText = wxEmptyString; + m_font = g_oglNormalFont; + m_minHeight = 5.0; + m_minWidth = 5.0; + m_width = 0.0; + m_height = 0.0; + m_x = 0.0; + m_y = 0.0; + + m_regionProportionX = -1.0; + m_regionProportionY = -1.0; + m_formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT; + m_regionName = wxEmptyString; + m_textColour = wxT("BLACK"); + m_penColour = wxT("BLACK"); + m_penStyle = wxSOLID; + m_actualPenObject = NULL; +} + +wxShapeRegion::wxShapeRegion(wxShapeRegion ®ion) +{ + m_regionText = region.m_regionText; + m_regionName = region.m_regionName; + m_textColour = region.m_textColour; + + m_font = region.m_font; + m_minHeight = region.m_minHeight; + m_minWidth = region.m_minWidth; + m_width = region.m_width; + m_height = region.m_height; + m_x = region.m_x; + m_y = region.m_y; + + m_regionProportionX = region.m_regionProportionX; + m_regionProportionY = region.m_regionProportionY; + m_formatMode = region.m_formatMode; + m_actualColourObject = region.GetActualColourObject(); + m_actualPenObject = NULL; + m_penStyle = region.m_penStyle; + m_penColour = region.m_penColour; + + ClearText(); + wxNode *node = region.m_formattedText.GetFirst(); + while (node) + { + wxShapeTextLine *line = (wxShapeTextLine *)node->GetData(); + wxShapeTextLine *new_line = + new wxShapeTextLine(line->GetX(), line->GetY(), line->GetText()); + m_formattedText.Append(new_line); + node = node->GetNext(); + } +} + +wxShapeRegion::~wxShapeRegion() +{ + ClearText(); +} + +void wxShapeRegion::ClearText() +{ + wxNode *node = m_formattedText.GetFirst(); + while (node) + { + wxShapeTextLine *line = (wxShapeTextLine *)node->GetData(); + wxNode *next = node->GetNext(); + delete line; + delete node; + node = next; + } +} + +void wxShapeRegion::SetFont(wxFont *f) +{ + m_font = f; +} + +void wxShapeRegion::SetMinSize(double w, double h) +{ + m_minWidth = w; + m_minHeight = h; +} + +void wxShapeRegion::SetSize(double w, double h) +{ + m_width = w; + m_height = h; +} + +void wxShapeRegion::SetPosition(double xp, double yp) +{ + m_x = xp; + m_y = yp; +} + +void wxShapeRegion::SetProportions(double xp, double yp) +{ + m_regionProportionX = xp; + m_regionProportionY = yp; +} + +void wxShapeRegion::SetFormatMode(int mode) +{ + m_formatMode = mode; +} + +void wxShapeRegion::SetColour(const wxString &col) +{ + m_textColour = col; + m_actualColourObject = wxColour(); +} + +void wxShapeRegion::SetColour(const wxColour &col) +{ + m_actualColourObject = col; +} + +const wxColour &wxShapeRegion::GetActualColourObject() +{ + if (!m_actualColourObject.IsOk()) + m_actualColourObject = wxTheColourDatabase->Find(GetColour()); + if (!m_actualColourObject.IsOk()) + m_actualColourObject = * wxBLACK; + return m_actualColourObject; +} + +void wxShapeRegion::SetPenColour(const wxString &col) +{ + m_penColour = col; + m_actualPenObject = NULL; +} + +// Returns NULL if the pen is invisible +// (different to pen being transparent; indicates that +// region boundary should not be drawn.) +wxPen *wxShapeRegion::GetActualPen() +{ + if (m_actualPenObject) + return m_actualPenObject; + + if (!m_penColour) return NULL; + if (m_penColour == wxT("Invisible")) + return NULL; + m_actualPenObject = wxThePenList->FindOrCreatePen(m_penColour, 1, m_penStyle); + return m_actualPenObject; +} + + diff --git a/ogl/bmpshape.cpp b/ogl/bmpshape.cpp new file mode 100644 index 0000000..e005044 --- /dev/null +++ b/ogl/bmpshape.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// bmpshape.cpp - Bitmap shape class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +/* + * Bitmap object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxBitmapShape, wxRectangleShape) + +wxBitmapShape::wxBitmapShape(): wxRectangleShape(100.0, 50.0) +{ + m_filename = wxEmptyString; +} + +wxBitmapShape::~wxBitmapShape() +{ +} + +void wxBitmapShape::OnDraw(wxDC &dc) +{ + if (!m_bitmap.Ok()) + return; + + double x, y; + x = WXROUND(m_xpos - m_bitmap.GetWidth() / 2.0); + y = WXROUND(m_ypos - m_bitmap.GetHeight() / 2.0); + dc.DrawBitmap(m_bitmap, (int) x, (int) y, true); +} + +void wxBitmapShape::SetSize(double w, double h, bool WXUNUSED(recursive)) +{ + if (m_bitmap.Ok()) + { + w = m_bitmap.GetWidth(); + h = m_bitmap.GetHeight(); + } + + SetAttachmentSize(w, h); + + m_width = w; + m_height = h; + SetDefaultRegionSize(); +} + +#if wxUSE_PROLOGIO +void wxBitmapShape::WriteAttributes(wxExpr *clause) +{ + // Can't really save the bitmap; so instantiate the bitmap + // at a higher level in the application, from a symbol library. + wxRectangleShape::WriteAttributes(clause); + clause->AddAttributeValueString(wxT("filename"), m_filename); +} + +void wxBitmapShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); + clause->GetAttributeValue(wxT("filename"), m_filename); +} +#endif + +// Does the copying for this object +void wxBitmapShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxBitmapShape)) ) ; + + wxBitmapShape &bitmapCopy = (wxBitmapShape &) copy; + + bitmapCopy.m_bitmap = m_bitmap; + bitmapCopy.SetFilename(m_filename); +} + +void wxBitmapShape::SetBitmap(const wxBitmap &bm) +{ + m_bitmap = bm; + if (m_bitmap.Ok()) + SetSize(m_bitmap.GetWidth(), m_bitmap.GetHeight()); +} + + diff --git a/ogl/canvas.cpp b/ogl/canvas.cpp new file mode 100644 index 0000000..0ca8f59 --- /dev/null +++ b/ogl/canvas.cpp @@ -0,0 +1,574 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// canvas.cpp - Shape canvas class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "wx/dcbuffer.h" +#include "ogl/ogl.h" + +#define CONTROL_POINT_SIZE 6 + +// Control point types +// Rectangle and most other shapes +#define CONTROL_POINT_VERTICAL 1 +#define CONTROL_POINT_HORIZONTAL 2 +#define CONTROL_POINT_DIAGONAL 3 + +// Line +#define CONTROL_POINT_ENDPOINT_TO 4 +#define CONTROL_POINT_ENDPOINT_FROM 5 +#define CONTROL_POINT_LINE 6 + +IMPLEMENT_DYNAMIC_CLASS(wxShapeCanvas, wxScrolledWindow) + +BEGIN_EVENT_TABLE(wxShapeCanvas, wxScrolledWindow) + EVT_PAINT(wxShapeCanvas::OnPaint) + EVT_ERASE_BACKGROUND(wxShapeCanvas::OnEraseBackground) + EVT_MOUSE_EVENTS(wxShapeCanvas::OnMouseEvent) +END_EVENT_TABLE() + +const wxChar *wxShapeCanvasNameStr = wxT("shapeCanvas"); + +// Object canvas +wxShapeCanvas::wxShapeCanvas(wxWindow *parent, wxWindowID id, + const wxPoint &pos, + const wxSize &size, + long style, + const wxString &name): + wxScrolledWindow(parent, id, pos, size, style | wxVSCROLL | wxHSCROLL, name) +{ + m_shapeDiagram = NULL; + m_dragState = NoDragging; + m_draggedShape = NULL; + m_oldDragX = 0; + m_oldDragY = 0; + m_firstDragX = 0; + m_firstDragY = 0; + m_checkTolerance = TRUE; + +#if OGL_USE_BUFFERED_PAINT + RecreateBuffer(size); +#endif + +} + +wxShapeCanvas::~wxShapeCanvas() +{ + if(m_shapeDiagram) + delete m_shapeDiagram; +} + +#if OGL_USE_BUFFERED_PAINT +/// Recreate buffer bitmap if necessary +bool wxShapeCanvas::RecreateBuffer(const wxSize &size) +{ + wxSize sz = size; + if (sz == wxDefaultSize) + sz = GetClientSize(); + + if (sz.x < 1 || sz.y < 1) + return false; + + if (!m_bufferBitmap.Ok() || m_bufferBitmap.GetWidth() < sz.x || m_bufferBitmap.GetHeight() < sz.y) + m_bufferBitmap = wxBitmap(sz.x, sz.y); + return m_bufferBitmap.Ok(); +} +#endif + +void wxShapeCanvas::OnPaint(wxPaintEvent &WXUNUSED(event)) +{ +#if OGL_USE_BUFFERED_PAINT + RecreateBuffer(); + wxBufferedPaintDC dc(this, m_bufferBitmap); +#else + wxPaintDC dc(this); +#endif + + PrepareDC(dc); + + DrawBackground(dc, true); + + if (GetDiagram()) + GetDiagram()->Redraw(dc); + + // Necessary or it unscales again if there's a zoom level + dc.SetUserScale(1.0, 1.0); +} + +// Draws the background +void wxShapeCanvas::DrawBackground(wxDC &dc, bool transformed) +{ + dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID)); + dc.Clear(); +} + +void wxShapeCanvas::OnEraseBackground(wxEraseEvent &event) +{ +} + +void wxShapeCanvas::OnMouseEvent(wxMouseEvent &event) +{ + wxClientDC dc(this); + PrepareDC(dc); + + wxPoint logPos(event.GetLogicalPosition(dc)); + + double x, y; + x = (double) logPos.x; + y = (double) logPos.y; + + int keys = 0; + if (event.ShiftDown()) + keys = keys | KEY_SHIFT; + if (event.ControlDown()) + keys = keys | KEY_CTRL; + + bool dragging = event.Dragging(); + + // Check if we're within the tolerance for mouse movements. + // If we're very close to the position we started dragging + // from, this may not be an intentional drag at all. + if (dragging) + { + int dx = abs(dc.LogicalToDeviceX((long) (x - m_firstDragX))); + int dy = abs(dc.LogicalToDeviceY((long) (y - m_firstDragY))); + if (m_checkTolerance && (dx <= GetDiagram()->GetMouseTolerance()) && (dy <= GetDiagram()->GetMouseTolerance())) + { + return; + } + else + // If we've ignored the tolerance once, then ALWAYS ignore + // tolerance in this drag, even if we come back within + // the tolerance range. + m_checkTolerance = FALSE; + } + + // Dragging - note that the effect of dragging is left entirely up + // to the object, so no movement is done unless explicitly done by + // object. + if (dragging && m_draggedShape && m_dragState == StartDraggingLeft) + { + m_dragState = ContinueDraggingLeft; + + // If the object isn't m_draggable, transfer message to canvas + if (m_draggedShape->Draggable()) + m_draggedShape->GetEventHandler()->OnBeginDragLeft((double)x, (double)y, keys, m_draggedAttachment); + else + { + m_draggedShape = NULL; + OnBeginDragLeft((double)x, (double)y, keys); + } + + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && m_draggedShape && m_dragState == ContinueDraggingLeft) + { + // Continue dragging + m_draggedShape->GetEventHandler()->OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + m_draggedShape->GetEventHandler()->OnDragLeft(TRUE, (double)x, (double)y, keys, m_draggedAttachment); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.LeftUp() && m_draggedShape && m_dragState == ContinueDraggingLeft) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + m_draggedShape->GetEventHandler()->OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + + m_draggedShape->GetEventHandler()->OnEndDragLeft((double)x, (double)y, keys, m_draggedAttachment); + m_draggedShape = NULL; + } + else if (dragging && m_draggedShape && m_dragState == StartDraggingRight) + { + m_dragState = ContinueDraggingRight; + + if (m_draggedShape->Draggable()) + m_draggedShape->GetEventHandler()->OnBeginDragRight((double)x, (double)y, keys, m_draggedAttachment); + else + { + m_draggedShape = NULL; + OnBeginDragRight((double)x, (double)y, keys); + } + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && m_draggedShape && m_dragState == ContinueDraggingRight) + { + // Continue dragging + m_draggedShape->GetEventHandler()->OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + m_draggedShape->GetEventHandler()->OnDragRight(TRUE, (double)x, (double)y, keys, m_draggedAttachment); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.RightUp() && m_draggedShape && m_dragState == ContinueDraggingRight) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + m_draggedShape->GetEventHandler()->OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys, m_draggedAttachment); + + m_draggedShape->GetEventHandler()->OnEndDragRight((double)x, (double)y, keys, m_draggedAttachment); + m_draggedShape = NULL; + } + + // All following events sent to canvas, not object + else if (dragging && !m_draggedShape && m_dragState == StartDraggingLeft) + { + m_dragState = ContinueDraggingLeft; + OnBeginDragLeft((double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && !m_draggedShape && m_dragState == ContinueDraggingLeft) + { + // Continue dragging + OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys); + OnDragLeft(TRUE, (double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.LeftUp() && !m_draggedShape && m_dragState == ContinueDraggingLeft) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + OnDragLeft(FALSE, m_oldDragX, m_oldDragY, keys); + OnEndDragLeft((double)x, (double)y, keys); + m_draggedShape = NULL; + } + else if (dragging && !m_draggedShape && m_dragState == StartDraggingRight) + { + m_dragState = ContinueDraggingRight; + OnBeginDragRight((double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (dragging && !m_draggedShape && m_dragState == ContinueDraggingRight) + { + // Continue dragging + OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys); + OnDragRight(TRUE, (double)x, (double)y, keys); + m_oldDragX = x; + m_oldDragY = y; + } + else if (event.RightUp() && !m_draggedShape && m_dragState == ContinueDraggingRight) + { + m_dragState = NoDragging; + m_checkTolerance = TRUE; + + OnDragRight(FALSE, m_oldDragX, m_oldDragY, keys); + OnEndDragRight((double)x, (double)y, keys); + m_draggedShape = NULL; + } + + // Non-dragging events + else if (event.IsButton()) + { + m_checkTolerance = TRUE; + + // Find the nearest object + int attachment = 0; + wxShape *nearest_object = FindShape(x, y, &attachment); + if (nearest_object) // Object event + { + if (event.LeftDown()) + { + m_draggedShape = nearest_object; + m_draggedAttachment = attachment; + m_dragState = StartDraggingLeft; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.LeftUp()) + { + // N.B. Only register a click if the same object was + // identified for down *and* up. + if (nearest_object == m_draggedShape) + nearest_object->GetEventHandler()->OnLeftClick((double)x, (double)y, keys, attachment); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + else if (event.LeftDClick()) + { + nearest_object->GetEventHandler()->OnLeftDoubleClick((double)x, (double)y, keys, attachment); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + else if (event.RightDown()) + { + m_draggedShape = nearest_object; + m_draggedAttachment = attachment; + m_dragState = StartDraggingRight; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.RightUp()) + { + if (nearest_object == m_draggedShape) + nearest_object->GetEventHandler()->OnRightClick((double)x, (double)y, keys, attachment); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + } + else // Canvas event (no nearest object) + { + if (event.LeftDown()) + { + m_draggedShape = NULL; + m_dragState = StartDraggingLeft; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.LeftUp()) + { + OnLeftClick((double)x, (double)y, keys); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + else if (event.RightDown()) + { + m_draggedShape = NULL; + m_dragState = StartDraggingRight; + m_firstDragX = x; + m_firstDragY = y; + } + else if (event.RightUp()) + { + OnRightClick((double)x, (double)y, keys); + + m_draggedShape = NULL; + m_dragState = NoDragging; + } + } + } +} + +/* + * Try to find a sensitive object, working up the hierarchy of composites. + * + */ +wxShape *wxShapeCanvas::FindFirstSensitiveShape(double x, double y, int *new_attachment, int op) +{ + wxShape *image = FindShape(x, y, new_attachment); + if (!image) return NULL; + + wxShape *actualImage = FindFirstSensitiveShape1(image, op); + if (actualImage) + { + double dist; + // Find actual attachment + actualImage->HitTest(x, y, new_attachment, &dist); + } + return actualImage; +} + +wxShape *wxShapeCanvas::FindFirstSensitiveShape1(wxShape *image, int op) +{ + if (image->GetSensitivityFilter() & op) + return image; + if (image->GetParent()) + return FindFirstSensitiveShape1(image->GetParent(), op); + return NULL; +} + +// Helper function: TRUE if 'contains' wholly contains 'contained'. +static bool WhollyContains(wxShape *contains, wxShape *contained) +{ + double xp1, yp1, xp2, yp2; + double w1, h1, w2, h2; + double left1, top1, right1, bottom1, left2, top2, right2, bottom2; + + xp1 = contains->GetX(); + yp1 = contains->GetY(); + xp2 = contained->GetX(); + yp2 = contained->GetY(); + contains->GetBoundingBoxMax(&w1, &h1); + contained->GetBoundingBoxMax(&w2, &h2); + + left1 = (double)(xp1 - (w1 / 2.0)); + top1 = (double)(yp1 - (h1 / 2.0)); + right1 = (double)(xp1 + (w1 / 2.0)); + bottom1 = (double)(yp1 + (h1 / 2.0)); + + left2 = (double)(xp2 - (w2 / 2.0)); + top2 = (double)(yp2 - (h2 / 2.0)); + right2 = (double)(xp2 + (w2 / 2.0)); + bottom2 = (double)(yp2 + (h2 / 2.0)); + + return ((left1 <= left2) && (top1 <= top2) && (right1 >= right2) && (bottom1 >= bottom2)); +} + +wxShape *wxShapeCanvas::FindShape(double x, double y, int *attachment, wxClassInfo *info, wxShape *notObject) +{ + double nearest = 100000.0; + int nearest_attachment = 0; + wxShape *nearest_object = NULL; + + // Go backward through the object list, since we want: + // (a) to have the control points drawn LAST to overlay + // the other objects + // (b) to find the control points FIRST if they exist + + wxNode *current = GetDiagram()->GetShapeList()->GetLast(); + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + + double dist; + int temp_attachment; + + // First pass for lines, which might be inside a container, so we + // want lines to take priority over containers. This first loop + // could fail if we clickout side a line, so then we'll + // try other shapes. + if (object->IsShown() && + object->IsKindOf(CLASSINFO(wxLineShape)) && + object->HitTest(x, y, &temp_attachment, &dist) && + ((info == NULL) || object->IsKindOf(info)) && + (!notObject || !notObject->HasDescendant(object))) + { + // A line is trickier to spot than a normal object. + // For a line, since it's the diagonal of the box + // we use for the hit test, we may have several + // lines in the box and therefore we need to be able + // to specify the nearest point to the centre of the line + // as our hit criterion, to give the user some room for + // manouevre. + if (dist < nearest) + { + nearest = dist; + nearest_object = object; + nearest_attachment = temp_attachment; + } + } + if (current) + current = current->GetPrevious(); + } + + current = GetDiagram()->GetShapeList()->GetLast(); + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + double dist; + int temp_attachment; + + // On second pass, only ever consider non-composites or divisions. If children want to pass + // up control to the composite, that's up to them. + if (object->IsShown() && (object->IsKindOf(CLASSINFO(wxDivisionShape)) || !object->IsKindOf(CLASSINFO(wxCompositeShape))) + && object->HitTest(x, y, &temp_attachment, &dist) && ((info == NULL) || object->IsKindOf(info)) && + (!notObject || !notObject->HasDescendant(object))) + { + if (!object->IsKindOf(CLASSINFO(wxLineShape))) + { + // If we've hit a container, and we have already found a line in the + // first pass, then ignore the container in case the line is in the container. + // Check for division in case line straddles divisions (i.e. is not wholly contained). + if (!nearest_object || !(object->IsKindOf(CLASSINFO(wxDivisionShape)) || WhollyContains(object, nearest_object))) + { + nearest_object = object; + nearest_attachment = temp_attachment; + current = NULL; + } + } + } + if (current) + current = current->GetPrevious(); + } + + *attachment = nearest_attachment; + return nearest_object; +} + +/* + * Higher-level events called by OnEvent + * + */ + +void wxShapeCanvas::OnLeftClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnRightClick(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnBeginDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnEndDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnDragRight(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnBeginDragRight(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::OnEndDragRight(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys)) +{ +} + +void wxShapeCanvas::AddShape(wxShape *object, wxShape *addAfter) +{ + GetDiagram()->AddShape(object, addAfter); +} +void wxShapeCanvas::InsertShape(wxShape *object) +{ + GetDiagram()->InsertShape(object); +} +void wxShapeCanvas::RemoveShape(wxShape *object) +{ + GetDiagram()->RemoveShape(object); +} +bool wxShapeCanvas::GetQuickEditMode() +{ + return GetDiagram()->GetQuickEditMode(); +} +void wxShapeCanvas::Redraw(wxDC &dc) +{ + GetDiagram()->Redraw(dc); +} +void wxShapeCanvas::Snap(double *x, double *y) +{ + GetDiagram()->Snap(x, y); +} + +// Returns the current scroll position +wxPoint wxShapeCanvas::GetCurrentPixelScrollPosition() +{ + int pixelsPerUnitX, pixelsPerUnitY; + GetScrollPixelsPerUnit(& pixelsPerUnitX, & pixelsPerUnitY); + + int posX, posY; + GetViewStart(& posX, & posY); + + wxPoint pt(pixelsPerUnitX * posX, pixelsPerUnitY * posY); + return pt; +} diff --git a/ogl/composit.cpp b/ogl/composit.cpp new file mode 100644 index 0000000..6205d36 --- /dev/null +++ b/ogl/composit.cpp @@ -0,0 +1,1757 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// composit.cpp - Composite OGL class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +#if wxUSE_PROLOGIO +// Sometimes, objects need to access the whole database to +// construct themselves. +wxExprDatabase *GlobalwxExprDatabase = NULL; +#endif + +/* + * Division control point + */ + +class wxDivisionControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxDivisionControlPoint) +public: + wxDivisionControlPoint() {} + wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type); + ~wxDivisionControlPoint(); + + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDivisionControlPoint, wxControlPoint) + +/* + * Composite object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxCompositeShape, wxRectangleShape) + +wxCompositeShape::wxCompositeShape(): wxRectangleShape(10.0, 10.0) +{ +// selectable = FALSE; + m_oldX = m_xpos; + m_oldY = m_ypos; +} + +wxCompositeShape::~wxCompositeShape() +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + delete constraint; + node = node->GetNext(); + } + node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + wxNode *next = node->GetNext(); + object->Unlink(); + delete object; + node = next; + } +} + +void wxCompositeShape::OnDraw(wxDC &dc) +{ + double x1 = (double)(m_xpos - m_width / 2.0); + double y1 = (double)(m_ypos - m_height / 2.0); + + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + dc.SetBrush(* m_shadowBrush); + dc.SetPen(* g_oglTransparentPen); + + if (m_cornerRadius != 0.0) + dc.DrawRoundedRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), + WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1 + m_shadowOffsetX), WXROUND(y1 + m_shadowOffsetY), WXROUND(m_width), WXROUND(m_height)); + } +} + +void wxCompositeShape::OnDrawContents(wxDC &dc) +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->Draw(dc); + object->DrawLinks(dc); + node = node->GetNext(); + } + wxShape::OnDrawContents(dc); +} + +bool wxCompositeShape::OnMovePre(double x, double y, double oldx, double oldy, bool display) +{ + double diffX = x - oldx; + double diffY = y - oldy; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + + object->Move(object->GetX() + diffX, object->GetY() + diffY, display); + + node = node->GetNext(); + } + return TRUE; +} + +static double objectStartX = 0.0; +static double objectStartY = 0.0; + +void wxCompositeShape::OnDragLeft(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + double xx = x; + double yy = y; + m_canvas->Snap(&xx, &yy); + double offsetX = xx - objectStartX; + double offsetY = yy - objectStartY; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight()); +// wxShape::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxCompositeShape::OnBeginDragLeft(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + objectStartX = x; + objectStartY = y; + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + Erase(); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + m_canvas->CaptureMouse(); + + double xx = x; + double yy = y; + m_canvas->Snap(&xx, &yy); + double offsetX = xx - objectStartX; + double offsetY = yy - objectStartY; + + GetEventHandler()->OnDrawOutline(dc, GetX() + offsetX, GetY() + offsetY, GetWidth(), GetHeight()); + +// wxShape::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxCompositeShape::OnEndDragLeft(double x, double y, int keys, int WXUNUSED(attachment)) +{ +// wxShape::OnEndDragLeft(x, y, keys, attachment); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + m_canvas->ReleaseMouse(); + + if (!m_draggable) + { + if (m_parent) m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, 0); + return; + } + + dc.SetLogicalFunction(wxCOPY); + double xx = x; + double yy = y; + m_canvas->Snap(&xx, &yy); + double offsetX = xx - objectStartX; + double offsetY = yy - objectStartY; + + Move(GetX() + offsetX, GetY() + offsetY); + + if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc); +} + +void wxCompositeShape::OnRightClick(double x, double y, int keys, int WXUNUSED(attachment)) +{ + // If we get a ctrl-right click, this means send the message to + // the division, so we can invoke a user interface for dealing with regions. + if (keys & KEY_CTRL) + { + wxNode *node = m_divisions.GetFirst(); + while (node) + { + wxDivisionShape *division = (wxDivisionShape *)node->GetData(); + wxNode *next = node->GetNext(); + int attach = 0; + double dist = 0.0; + if (division->HitTest(x, y, &attach, &dist)) + { + division->GetEventHandler()->OnRightClick(x, y, keys, attach); + node = NULL; + } + if (node) + node = next; + } + } +} + +void wxCompositeShape::SetSize(double w, double h, bool recursive) +{ + SetAttachmentSize(w, h); + + double xScale = (double)(w / (wxMax(1.0, GetWidth()))); + double yScale = (double)(h / (wxMax(1.0, GetHeight()))); + + m_width = w; + m_height = h; + + if (!recursive) return; + + wxNode *node = m_children.GetFirst(); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + double xBound, yBound; + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + + // Scale the position first + double newX = (double)(((object->GetX() - GetX()) * xScale) + GetX()); + double newY = (double)(((object->GetY() - GetY()) * yScale) + GetY()); + object->Show(FALSE); + object->Move(newX, newY); + object->Show(TRUE); + + // Now set the scaled size + object->GetBoundingBoxMin(&xBound, &yBound); + object->SetSize(object->GetFixedWidth() ? xBound : xScale * xBound, + object->GetFixedHeight() ? yBound : yScale * yBound); + + node = node->GetNext(); + } + SetDefaultRegionSize(); +} + +void wxCompositeShape::AddChild(wxShape *child, wxShape *addAfter) +{ + m_children.Append(child); + child->SetParent(this); + if (m_canvas) + { + // Ensure we add at the right position + if (addAfter) + child->RemoveFromCanvas(m_canvas); + child->AddToCanvas(m_canvas, addAfter); + } +} + +void wxCompositeShape::RemoveChild(wxShape *child) +{ + m_children.DeleteObject(child); + m_divisions.DeleteObject(child); + RemoveChildFromConstraints(child); + child->SetParent(NULL); +} + +void wxCompositeShape::DeleteConstraintsInvolvingChild(wxShape *child) +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + wxNode *nextNode = node->GetNext(); + + if ((constraint->m_constrainingObject == child) || + constraint->m_constrainedObjects.Member(child)) + { + delete constraint; + delete node; + } + node = nextNode; + } +} + +void wxCompositeShape::RemoveChildFromConstraints(wxShape *child) +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + wxNode *nextNode = node->GetNext(); + + if (constraint->m_constrainedObjects.Member(child)) + constraint->m_constrainedObjects.DeleteObject(child); + if (constraint->m_constrainingObject == child) + constraint->m_constrainingObject = NULL; + + // Delete the constraint if no participants left + if (!constraint->m_constrainingObject) + { + delete constraint; + delete node; + } + + node = nextNode; + } +} + +void wxCompositeShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxCompositeShape)) ) ; + + wxCompositeShape &compositeCopy = (wxCompositeShape &) copy; + + // Associate old and new copies for compositeCopying constraints and division geometry + oglObjectCopyMapping.Append((long)this, &compositeCopy); + + // Copy the children + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + wxShape *newObject = object->CreateNewCopy(FALSE, FALSE); + if (newObject->GetId() == 0) + newObject->SetId(wxNewId()); + + newObject->SetParent(&compositeCopy); + compositeCopy.m_children.Append(newObject); + + // Some m_children may be divisions + if (m_divisions.Member(object)) + compositeCopy.m_divisions.Append(newObject); + + oglObjectCopyMapping.Append((long)object, newObject); + + node = node->GetNext(); + } + + // Copy the constraints + node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + + wxShape *newConstraining = (wxShape *)(oglObjectCopyMapping.Find((long)constraint->m_constrainingObject)->GetData()); + + wxList newConstrainedList; + wxNode *node2 = constraint->m_constrainedObjects.GetFirst(); + while (node2) + { + wxShape *constrainedObject = (wxShape *)node2->GetData(); + wxShape *newConstrained = (wxShape *)(oglObjectCopyMapping.Find((long)constrainedObject)->GetData()); + newConstrainedList.Append(newConstrained); + node2 = node2->GetNext(); + } + + wxOGLConstraint *newConstraint = new wxOGLConstraint(constraint->m_constraintType, newConstraining, + newConstrainedList); + newConstraint->m_constraintId = constraint->m_constraintId; + if (!constraint->m_constraintName.IsEmpty()) + { + newConstraint->m_constraintName = constraint->m_constraintName; + } + newConstraint->SetSpacing(constraint->m_xSpacing, constraint->m_ySpacing); + compositeCopy.m_constraints.Append(newConstraint); + + node = node->GetNext(); + } + + // Now compositeCopy the division geometry + node = m_divisions.GetFirst(); + while (node) + { + wxDivisionShape *division = (wxDivisionShape *)node->GetData(); + wxNode *node1 = oglObjectCopyMapping.Find((long)division); + wxNode *leftNode = NULL; + wxNode *topNode = NULL; + wxNode *rightNode = NULL; + wxNode *bottomNode = NULL; + if (division->GetLeftSide()) + leftNode = oglObjectCopyMapping.Find((long)division->GetLeftSide()); + if (division->GetTopSide()) + topNode = oglObjectCopyMapping.Find((long)division->GetTopSide()); + if (division->GetRightSide()) + rightNode = oglObjectCopyMapping.Find((long)division->GetRightSide()); + if (division->GetBottomSide()) + bottomNode = oglObjectCopyMapping.Find((long)division->GetBottomSide()); + if (node1) + { + wxDivisionShape *newDivision = (wxDivisionShape *)node1->GetData(); + if (leftNode) + newDivision->SetLeftSide((wxDivisionShape *)leftNode->GetData()); + if (topNode) + newDivision->SetTopSide((wxDivisionShape *)topNode->GetData()); + if (rightNode) + newDivision->SetRightSide((wxDivisionShape *)rightNode->GetData()); + if (bottomNode) + newDivision->SetBottomSide((wxDivisionShape *)bottomNode->GetData()); + } + node = node->GetNext(); + } +} + +wxOGLConstraint *wxCompositeShape::AddConstraint(wxOGLConstraint *constraint) +{ + m_constraints.Append(constraint); + if (constraint->m_constraintId == 0) + constraint->m_constraintId = wxNewId(); + return constraint; +} + +wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxList &constrained) +{ + wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, constrained); + if (constraint->m_constraintId == 0) + constraint->m_constraintId = wxNewId(); + m_constraints.Append(constraint); + return constraint; +} + +wxOGLConstraint *wxCompositeShape::AddConstraint(int type, wxShape *constraining, wxShape *constrained) +{ + wxList l; + l.Append(constrained); + wxOGLConstraint *constraint = new wxOGLConstraint(type, constraining, l); + if (constraint->m_constraintId == 0) + constraint->m_constraintId = wxNewId(); + m_constraints.Append(constraint); + return constraint; +} + +wxOGLConstraint *wxCompositeShape::FindConstraint(long cId, wxCompositeShape **actualComposite) +{ + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + if (constraint->m_constraintId == cId) + { + if (actualComposite) + *actualComposite = this; + return constraint; + } + node = node->GetNext(); + } + // If not found, try children. + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + if (child->IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxOGLConstraint *constraint = ((wxCompositeShape *)child)->FindConstraint(cId, actualComposite); + if (constraint) + { + if (actualComposite) + *actualComposite = (wxCompositeShape *)child; + return constraint; + } + } + node = node->GetNext(); + } + return NULL; +} + +void wxCompositeShape::DeleteConstraint(wxOGLConstraint *constraint) +{ + m_constraints.DeleteObject(constraint); + delete constraint; +} + +void wxCompositeShape::CalculateSize() +{ + double maxX = (double) - 999999.9; + double maxY = (double) - 999999.9; + double minX = (double) 999999.9; + double minY = (double) 999999.9; + + double w, h; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + + // Recalculate size of composite objects because may not conform + // to size it was set to - depends on the children. + object->CalculateSize(); + + object->GetBoundingBoxMax(&w, &h); + if ((object->GetX() + (w / 2.0)) > maxX) + maxX = (double)(object->GetX() + (w / 2.0)); + if ((object->GetX() - (w / 2.0)) < minX) + minX = (double)(object->GetX() - (w / 2.0)); + if ((object->GetY() + (h / 2.0)) > maxY) + maxY = (double)(object->GetY() + (h / 2.0)); + if ((object->GetY() - (h / 2.0)) < minY) + minY = (double)(object->GetY() - (h / 2.0)); + + node = node->GetNext(); + } + m_width = maxX - minX; + m_height = maxY - minY; + m_xpos = (double)(m_width / 2.0 + minX); + m_ypos = (double)(m_height / 2.0 + minY); +} + +bool wxCompositeShape::Recompute() +{ + int noIterations = 0; + bool changed = TRUE; + while (changed && (noIterations < 500)) + { + changed = Constrain(); + noIterations ++; + } + /* + #ifdef wx_x + if (changed) + cerr << "Warning: constraint algorithm failed after 500 iterations.\n"; + #endif + */ + return (!changed); +} + +bool wxCompositeShape::Constrain() +{ + CalculateSize(); + + bool changed = FALSE; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + if (object->Constrain()) + changed = TRUE; + node = node->GetNext(); + } + + node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + if (constraint->Evaluate()) changed = TRUE; + node = node->GetNext(); + } + return changed; +} + +#if wxUSE_PROLOGIO +void wxCompositeShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); + +// clause->AddAttributeValue("selectable", (long)selectable); + + // Output constraints as constraint1 = (...), constraint2 = (...), etc. + int constraintNo = 1; + wxChar m_constraintNameBuf[20]; + wxNode *node = m_constraints.GetFirst(); + while (node) + { + wxOGLConstraint *constraint = (wxOGLConstraint *)node->GetData(); + wxSprintf(m_constraintNameBuf, wxT("constraint%d"), constraintNo); + + // Each constraint is stored in the form + // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList) + wxExpr *constraintExpr = new wxExpr(wxExprList); + constraintExpr->Append(new wxExpr((long)constraint->m_constraintType)); + constraintExpr->Append(new wxExpr(wxExprString, constraint->m_constraintName)); + constraintExpr->Append(new wxExpr(constraint->m_constraintId)); + constraintExpr->Append(new wxExpr(constraint->m_xSpacing)); + constraintExpr->Append(new wxExpr(constraint->m_ySpacing)); + constraintExpr->Append(new wxExpr(constraint->m_constrainingObject->GetId())); + + wxExpr *objectList = new wxExpr(wxExprList); + wxNode *node1 = constraint->m_constrainedObjects.GetFirst(); + while (node1) + { + wxShape *obj = (wxShape *)node1->GetData(); + objectList->Append(new wxExpr(obj->GetId())); + node1 = node1->GetNext(); + } + constraintExpr->Append(objectList); + + clause->AddAttributeValue(m_constraintNameBuf, constraintExpr); + + node = node->GetNext(); + constraintNo ++; + } + + // Write the ids of all the child images + wxExpr *childrenExpr = new wxExpr(wxExprList); + node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + childrenExpr->Append(new wxExpr(child->GetId())); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("children"), childrenExpr); + + // Write the ids of all the division images + if (m_divisions.GetCount() > 0) + { + wxExpr *divisionsExpr = new wxExpr(wxExprList); + node = m_divisions.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + divisionsExpr->Append(new wxExpr(child->GetId())); + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("divisions"), divisionsExpr); + } +} + +// Problem. Child images are always written AFTER the parent +// so as to be able to link up to parent. So we may not be able +// to find the constraint participants until we've read everything +// in. Need to have another pass for composites. +void wxCompositeShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); + +// clause->GetAttributeValue("selectable", selectable); +} + +void wxCompositeShape::ReadConstraints(wxExpr *clause, wxExprDatabase *database) +{ + // Constraints are output as constraint1 = (...), constraint2 = (...), etc. + int constraintNo = 1; + wxChar m_constraintNameBuf[20]; + bool haveConstraints = TRUE; + + while (haveConstraints) + { + wxSprintf(m_constraintNameBuf, wxT("constraint%d"), constraintNo); + wxExpr *constraintExpr = NULL; + clause->GetAttributeValue(m_constraintNameBuf, &constraintExpr); + if (!constraintExpr) + { + haveConstraints = FALSE; + break; + } + wxString cName = wxEmptyString; + wxShape *m_constrainingObject = NULL; + wxList m_constrainedObjects; + + // Each constraint is stored in the form + // (type name id xspacing yspacing m_constrainingObjectId constrainedObjectIdList) + + wxExpr *typeExpr = constraintExpr->Nth(0); + wxExpr *nameExpr = constraintExpr->Nth(1); + wxExpr *idExpr = constraintExpr->Nth(2); + wxExpr *xExpr = constraintExpr->Nth(3); + wxExpr *yExpr = constraintExpr->Nth(4); + wxExpr *constrainingExpr = constraintExpr->Nth(5); + wxExpr *constrainedExpr = constraintExpr->Nth(6); + + int cType = (int)typeExpr->IntegerValue(); + double cXSpacing = xExpr->RealValue(); + double cYSpacing = yExpr->RealValue(); + cName = nameExpr->StringValue(); + long cId = idExpr->IntegerValue(); + + wxExpr *objExpr1 = database->HashFind(wxT("node_image"), constrainingExpr->IntegerValue()); + if (objExpr1 && objExpr1->GetClientData()) + m_constrainingObject = (wxShape *)objExpr1->GetClientData(); + else + wxLogFatalError(wxT("Object graphics error: Couldn't find constraining image of composite.")); + + int i = 0; + wxExpr *currentIdExpr = constrainedExpr->Nth(i); + while (currentIdExpr) + { + long currentId = currentIdExpr->IntegerValue(); + wxExpr *objExpr2 = database->HashFind(wxT("node_image"), currentId); + if (objExpr2 && objExpr2->GetClientData()) + { + m_constrainedObjects.Append((wxShape *)objExpr2->GetClientData()); + } + else + { + wxLogFatalError(wxT("Object graphics error: Couldn't find constrained image of composite.")); + } + + i ++; + currentIdExpr = constrainedExpr->Nth(i); + } + wxOGLConstraint *newConstraint = AddConstraint(cType, m_constrainingObject, m_constrainedObjects); + newConstraint->SetSpacing(cXSpacing, cYSpacing); + newConstraint->m_constraintId = cId; + newConstraint->m_constraintName = cName; + constraintNo ++; + } +} +#endif + +// Make this composite into a container by creating one wxDivisionShape +void wxCompositeShape::MakeContainer() +{ + wxDivisionShape *division = OnCreateDivision(); + m_divisions.Append(division); + AddChild(division); + + division->SetSize(m_width, m_height); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + division->Move(GetX(), GetY()); + Recompute(); + division->Show(TRUE); +} + +wxDivisionShape *wxCompositeShape::OnCreateDivision() +{ + return new wxDivisionShape; +} + +wxShape *wxCompositeShape::FindContainerImage() +{ + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + if (!m_divisions.Member(child)) + return child; + node = node->GetNext(); + } + return NULL; +} + +// Returns TRUE if division is a descendant of this container +bool wxCompositeShape::ContainsDivision(wxDivisionShape *division) +{ + if (m_divisions.Member(division)) + return TRUE; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *child = (wxShape *)node->GetData(); + if (child->IsKindOf(CLASSINFO(wxCompositeShape))) + { + bool ans = ((wxCompositeShape *)child)->ContainsDivision(division); + if (ans) + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +/* + * Division object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxDivisionShape, wxCompositeShape) + +wxDivisionShape::wxDivisionShape() +{ + SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT); + SetCentreResize(FALSE); + SetAttachmentMode(TRUE); + m_leftSide = NULL; + m_rightSide = NULL; + m_topSide = NULL; + m_bottomSide = NULL; + m_handleSide = DIVISION_SIDE_NONE; + m_leftSidePen = (wxPen *) wxBLACK_PEN; + m_topSidePen = (wxPen *) wxBLACK_PEN; + m_leftSideColour = wxT("BLACK"); + m_topSideColour = wxT("BLACK"); + m_leftSideStyle = wxT("Solid"); + m_topSideStyle = wxT("Solid"); + ClearRegions(); +} + +wxDivisionShape::~wxDivisionShape() +{ +} + +void wxDivisionShape::OnDraw(wxDC &dc) +{ + dc.SetBrush(* wxTRANSPARENT_BRUSH); + dc.SetBackgroundMode(wxTRANSPARENT); + + double x1 = (double)(GetX() - (GetWidth() / 2.0)); + double y1 = (double)(GetY() - (GetHeight() / 2.0)); + double x2 = (double)(GetX() + (GetWidth() / 2.0)); + double y2 = (double)(GetY() + (GetHeight() / 2.0)); + + // Should subtract 1 pixel if drawing under Windows +#ifdef __WXMSW__ + y2 -= (double)1.0; +#endif + + if (m_leftSide) + { + dc.SetPen(* m_leftSidePen); + dc.DrawLine(WXROUND(x1), WXROUND(y2), WXROUND(x1), WXROUND(y1)); + } + if (m_topSide) + { + dc.SetPen(* m_topSidePen); + dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y1)); + } + + // For testing purposes, draw a rectangle so we know + // how big the division is. +// SetBrush(* wxCYAN_BRUSH); +// wxRectangleShape::OnDraw(dc); +} + +void wxDivisionShape::OnDrawContents(wxDC &dc) +{ + wxCompositeShape::OnDrawContents(dc); +} + +bool wxDivisionShape::OnMovePre(double x, double y, double oldx, double oldy, bool display) +{ + double diffX = x - oldx; + double diffY = y - oldy; + wxNode *node = m_children.GetFirst(); + while (node) + { + wxShape *object = (wxShape *)node->GetData(); + object->Erase(); + object->Move(object->GetX() + diffX, object->GetY() + diffY, display); + node = node->GetNext(); + } + return TRUE; +} + +void wxDivisionShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment); + } + return; + } + wxShape::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxDivisionShape::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment); + } + return; + } + + wxShape::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxDivisionShape::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_canvas->ReleaseMouse(); + if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT) + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment); + } + return; + } + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(wxCOPY); +#endif + + m_canvas->Snap(&m_xpos, &m_ypos); + GetEventHandler()->OnMovePre(x, y, m_oldX, m_oldY); + + ResetControlPoints(); + MoveLinks(); + + if (m_canvas) + m_canvas->Refresh(); +} + +void wxDivisionShape::SetSize(double w, double h, bool recursive) +{ + m_width = w; + m_height = h; + wxRectangleShape::SetSize(w, h, recursive); +} + +void wxDivisionShape::CalculateSize() +{ +} + +void wxDivisionShape::Copy(wxShape ©) +{ + wxCompositeShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxDivisionShape)) ) ; + + wxDivisionShape &divisionCopy = (wxDivisionShape &) copy; + + divisionCopy.m_leftSideStyle = m_leftSideStyle; + divisionCopy.m_topSideStyle = m_topSideStyle; + divisionCopy.m_leftSideColour = m_leftSideColour; + divisionCopy.m_topSideColour = m_topSideColour; + + divisionCopy.m_leftSidePen = m_leftSidePen; + divisionCopy.m_topSidePen = m_topSidePen; + divisionCopy.m_handleSide = m_handleSide; + + // Division geometry copying is handled at the wxCompositeShape level. +} + +#if wxUSE_PROLOGIO +void wxDivisionShape::WriteAttributes(wxExpr *clause) +{ + wxCompositeShape::WriteAttributes(clause); + + if (m_leftSide) + clause->AddAttributeValue(wxT("left_side"), (long)m_leftSide->GetId()); + if (m_topSide) + clause->AddAttributeValue(wxT("top_side"), (long)m_topSide->GetId()); + if (m_rightSide) + clause->AddAttributeValue(wxT("right_side"), (long)m_rightSide->GetId()); + if (m_bottomSide) + clause->AddAttributeValue(wxT("bottom_side"), (long)m_bottomSide->GetId()); + + clause->AddAttributeValue(wxT("handle_side"), (long)m_handleSide); + clause->AddAttributeValueString(wxT("left_colour"), m_leftSideColour); + clause->AddAttributeValueString(wxT("top_colour"), m_topSideColour); + clause->AddAttributeValueString(wxT("left_style"), m_leftSideStyle); + clause->AddAttributeValueString(wxT("top_style"), m_topSideStyle); +} + +void wxDivisionShape::ReadAttributes(wxExpr *clause) +{ + wxCompositeShape::ReadAttributes(clause); + + clause->GetAttributeValue(wxT("handle_side"), m_handleSide); + clause->GetAttributeValue(wxT("left_colour"), m_leftSideColour); + clause->GetAttributeValue(wxT("top_colour"), m_topSideColour); + clause->GetAttributeValue(wxT("left_style"), m_leftSideStyle); + clause->GetAttributeValue(wxT("top_style"), m_topSideStyle); +} +#endif + +// Experimental +void wxDivisionShape::OnRightClick(double x, double y, int keys, int attachment) +{ + if (keys & KEY_CTRL) + { + PopupMenu(x, y); + } + /* + else if (keys & KEY_SHIFT) + { + if (m_leftSide || m_topSide || m_rightSide || m_bottomSide) + { + if (Selected()) + { + Select(FALSE); + GetParent()->Draw(dc); + } + else + Select(TRUE); + } + } + */ + else + { + attachment = 0; + double dist; + if (m_parent) + { + m_parent->HitTest(x, y, &attachment, &dist); + m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment); + } + return; + } +} + + +// Divide wxHORIZONTALly or wxVERTICALly +bool wxDivisionShape::Divide(int direction) +{ + // Calculate existing top-left, bottom-right + double x1 = (double)(GetX() - (GetWidth() / 2.0)); + double y1 = (double)(GetY() - (GetHeight() / 2.0)); + wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent(); + double oldWidth = GetWidth(); + double oldHeight = GetHeight(); + if (Selected()) + Select(FALSE); + + //wxClientDC dc(GetCanvas()); + //GetCanvas()->PrepareDC(dc); + + if (direction == wxVERTICAL) + { + // Dividing vertically means notionally putting a horizontal line through it. + // Break existing piece into two. + double newXPos1 = GetX(); + double newYPos1 = (double)(y1 + (GetHeight() / 4.0)); + double newXPos2 = GetX(); + double newYPos2 = (double)(y1 + (3.0 * GetHeight() / 4.0)); + wxDivisionShape *newDivision = compositeParent->OnCreateDivision(); + newDivision->Show(TRUE); + + // Erase(); + + // Anything adjoining the bottom of this division now adjoins the + // bottom of the new division. + wxNode *node = compositeParent->GetDivisions().GetFirst(); + while (node) + { + wxDivisionShape *obj = (wxDivisionShape *)node->GetData(); + if (obj->GetTopSide() == this) + obj->SetTopSide(newDivision); + node = node->GetNext(); + } + newDivision->SetTopSide(this); + newDivision->SetBottomSide(m_bottomSide); + newDivision->SetLeftSide(m_leftSide); + newDivision->SetRightSide(m_rightSide); + m_bottomSide = newDivision; + + compositeParent->GetDivisions().Append(newDivision); + + // CHANGE: Need to insert this division at start of divisions in the object + // list, because e.g.: + // 1) Add division + // 2) Add contained object + // 3) Add division + // Division is now receiving mouse events _before_ the contained object, + // because it was added last (on top of all others) + + // Add after the image that visualizes the container + compositeParent->AddChild(newDivision, compositeParent->FindContainerImage()); + + m_handleSide = DIVISION_SIDE_BOTTOM; + newDivision->SetHandleSide(DIVISION_SIDE_TOP); + + SetSize(oldWidth, (double)(oldHeight / 2.0)); + Move(newXPos1, newYPos1); + + newDivision->SetSize(oldWidth, (double)(oldHeight / 2.0)); + newDivision->Move(newXPos2, newYPos2); + } + else + { + // Dividing horizontally means notionally putting a vertical line through it. + // Break existing piece into two. + double newXPos1 = (double)(x1 + (GetWidth() / 4.0)); + double newYPos1 = GetY(); + double newXPos2 = (double)(x1 + (3.0 * GetWidth() / 4.0)); + double newYPos2 = GetY(); + wxDivisionShape *newDivision = compositeParent->OnCreateDivision(); + newDivision->Show(TRUE); + + // Erase(dc); + + // Anything adjoining the left of this division now adjoins the + // left of the new division. + wxNode *node = compositeParent->GetDivisions().GetFirst(); + while (node) + { + wxDivisionShape *obj = (wxDivisionShape *)node->GetData(); + if (obj->GetLeftSide() == this) + obj->SetLeftSide(newDivision); + node = node->GetNext(); + } + newDivision->SetTopSide(m_topSide); + newDivision->SetBottomSide(m_bottomSide); + newDivision->SetLeftSide(this); + newDivision->SetRightSide(m_rightSide); + m_rightSide = newDivision; + + compositeParent->GetDivisions().Append(newDivision); + compositeParent->AddChild(newDivision, compositeParent->FindContainerImage()); + + m_handleSide = DIVISION_SIDE_RIGHT; + newDivision->SetHandleSide(DIVISION_SIDE_LEFT); + + SetSize((double)(oldWidth / 2.0), oldHeight); + Move(newXPos1, newYPos1); + + newDivision->SetSize((double)(oldWidth / 2.0), oldHeight); + newDivision->Move(newXPos2, newYPos2); + } + if (compositeParent->Selected()) + { + compositeParent->DeleteControlPoints(); + compositeParent->MakeControlPoints(); + compositeParent->MakeMandatoryControlPoints(); + } + // compositeParent->Draw(dc); + + if (GetCanvas()) + GetCanvas()->Refresh(); + return TRUE; +} + +// Make one control point for every visible line +void wxDivisionShape::MakeControlPoints() +{ + MakeMandatoryControlPoints(); +} + +void wxDivisionShape::MakeMandatoryControlPoints() +{ + double maxX, maxY; + + GetBoundingBoxMax(&maxX, &maxY); + double x = 0.0 , y = 0.0; + int direction = 0; + /* + if (m_leftSide) + { + x = (double)(-maxX/2.0); + y = 0.0; + wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y, + CONTROL_POINT_HORIZONTAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + } + if (m_topSide) + { + x = 0.0; + y = (double)(-maxY/2.0); + wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y, + CONTROL_POINT_VERTICAL); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + } + */ + switch (m_handleSide) + { + case DIVISION_SIDE_LEFT: + { + x = (double)(-maxX / 2.0); + y = 0.0; + direction = CONTROL_POINT_HORIZONTAL; + break; + } + case DIVISION_SIDE_TOP: + { + x = 0.0; + y = (double)(-maxY / 2.0); + direction = CONTROL_POINT_VERTICAL; + break; + } + case DIVISION_SIDE_RIGHT: + { + x = (double)(maxX / 2.0); + y = 0.0; + direction = CONTROL_POINT_HORIZONTAL; + break; + } + case DIVISION_SIDE_BOTTOM: + { + x = 0.0; + y = (double)(maxY / 2.0); + direction = CONTROL_POINT_VERTICAL; + break; + } + default: + break; + } + if (m_handleSide != DIVISION_SIDE_NONE) + { + wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y, + direction); + m_canvas->AddShape(control); + m_controlPoints.Append(control); + } +} + +void wxDivisionShape::ResetControlPoints() +{ + ResetMandatoryControlPoints(); +} + +void wxDivisionShape::ResetMandatoryControlPoints() +{ + if (m_controlPoints.GetCount() < 1) + return; + + double maxX, maxY; + + GetBoundingBoxMax(&maxX, &maxY); + /* + wxNode *node = m_controlPoints.GetFirst(); + while (node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + if (control->type == CONTROL_POINT_HORIZONTAL) + { + control->xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0; + } + else if (control->type == CONTROL_POINT_VERTICAL) + { + control->xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0); + } + node = node->GetNext(); + } + */ + wxNode *node = m_controlPoints.GetFirst(); + if ((m_handleSide == DIVISION_SIDE_LEFT) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = (double)(-maxX / 2.0); + control->m_yoffset = 0.0; + } + + if ((m_handleSide == DIVISION_SIDE_TOP) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = 0.0; + control->m_yoffset = (double)(-maxY / 2.0); + } + + if ((m_handleSide == DIVISION_SIDE_RIGHT) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = (double)(maxX / 2.0); + control->m_yoffset = 0.0; + } + + if ((m_handleSide == DIVISION_SIDE_BOTTOM) && node) + { + wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData(); + control->m_xoffset = 0.0; + control->m_yoffset = (double)(maxY / 2.0); + } +} + +// Adjust a side, returning FALSE if it's not physically possible. +bool wxDivisionShape::AdjustLeft(double left, bool test) +{ + double x2 = (double)(GetX() + (GetWidth() / 2.0)); + + if (left >= x2) + return FALSE; + if (test) + return TRUE; + + double newW = x2 - left; + double newX = (double)(left + newW / 2.0); + SetSize(newW, GetHeight()); + + Move(newX, GetY()); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +bool wxDivisionShape::AdjustTop(double top, bool test) +{ + double y2 = (double)(GetY() + (GetHeight() / 2.0)); + + if (top >= y2) + return FALSE; + if (test) + return TRUE; + + double newH = y2 - top; + double newY = (double)(top + newH / 2.0); + SetSize(GetWidth(), newH); + + Move(GetX(), newY); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +bool wxDivisionShape::AdjustRight(double right, bool test) +{ + double x1 = (double)(GetX() - (GetWidth() / 2.0)); + + if (right <= x1) + return FALSE; + if (test) + return TRUE; + + double newW = right - x1; + double newX = (double)(x1 + newW / 2.0); + SetSize(newW, GetHeight()); + + Move(newX, GetY()); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +bool wxDivisionShape::AdjustBottom(double bottom, bool test) +{ + double y1 = (double)(GetY() - (GetHeight() / 2.0)); + + if (bottom <= y1) + return FALSE; + if (test) + return TRUE; + + double newH = bottom - y1; + double newY = (double)(y1 + newH / 2.0); + SetSize(GetWidth(), newH); + + Move(GetX(), newY); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +wxDivisionControlPoint::wxDivisionControlPoint(wxShapeCanvas *the_canvas, wxShape *object, double size, double the_xoffset, double the_yoffset, int the_type): + wxControlPoint(the_canvas, object, size, the_xoffset, the_yoffset, the_type) +{ + SetEraseObject(FALSE); +} + +wxDivisionControlPoint::~wxDivisionControlPoint() +{ +} + +static double originalX = 0.0; +static double originalY = 0.0; +static double originalW = 0.0; +static double originalH = 0.0; + +// Implement resizing of canvas object +void wxDivisionControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + wxControlPoint::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxDivisionControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + wxDivisionShape *division = (wxDivisionShape *)m_shape; + originalX = division->GetX(); + originalY = division->GetY(); + originalW = division->GetWidth(); + originalH = division->GetHeight(); + + wxControlPoint::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxDivisionControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + wxControlPoint::OnEndDragLeft(x, y, keys, attachment); + + wxDivisionShape *division = (wxDivisionShape *)m_shape; + wxCompositeShape *divisionParent = (wxCompositeShape *)division->GetParent(); + + // Need to check it's within the bounds of the parent composite. + double x1 = (double)(divisionParent->GetX() - (divisionParent->GetWidth() / 2.0)); + double y1 = (double)(divisionParent->GetY() - (divisionParent->GetHeight() / 2.0)); + double x2 = (double)(divisionParent->GetX() + (divisionParent->GetWidth() / 2.0)); + double y2 = (double)(divisionParent->GetY() + (divisionParent->GetHeight() / 2.0)); + + // Need to check it has not made the division zero or negative width/height + double dx1 = (double)(division->GetX() - (division->GetWidth() / 2.0)); + double dy1 = (double)(division->GetY() - (division->GetHeight() / 2.0)); + double dx2 = (double)(division->GetX() + (division->GetWidth() / 2.0)); + double dy2 = (double)(division->GetY() + (division->GetHeight() / 2.0)); + + bool success = TRUE; + switch (division->GetHandleSide()) + { + case DIVISION_SIDE_LEFT: + { + if ((x <= x1) || (x >= x2) || (x >= dx2)) + success = FALSE; + // Try it out first... + else if (!division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_LEFT, x, FALSE); + + break; + } + case DIVISION_SIDE_TOP: + { + if ((y <= y1) || (y >= y2) || (y >= dy2)) + success = FALSE; + else if (!division->ResizeAdjoining(DIVISION_SIDE_TOP, y, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_TOP, y, FALSE); + + break; + } + case DIVISION_SIDE_RIGHT: + { + if ((x <= x1) || (x >= x2) || (x <= dx1)) + success = FALSE; + else if (!division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_RIGHT, x, FALSE); + + break; + } + case DIVISION_SIDE_BOTTOM: + { + if ((y <= y1) || (y >= y2) || (y <= dy1)) + success = FALSE; + else if (!division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, TRUE)) + success = FALSE; + else + division->ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, FALSE); + + break; + } + } + if (!success) + { + division->SetSize(originalW, originalH); + division->Move(originalX, originalY); + } + + if (GetCanvas()) + GetCanvas()->Refresh(); + +} + +/* Resize adjoining divisions. + * + Behaviour should be as follows: + If right edge moves, find all objects whose left edge + adjoins this object, and move left edge accordingly. + If left..., move ... right. + If top..., move ... bottom. + If bottom..., move top. + If size goes to zero or end position is other side of start position, + resize to original size and return. + */ +bool wxDivisionShape::ResizeAdjoining(int side, double newPos, bool test) +{ + wxCompositeShape *divisionParent = (wxCompositeShape *)GetParent(); + wxNode *node = divisionParent->GetDivisions().GetFirst(); + while (node) + { + wxDivisionShape *division = (wxDivisionShape *)node->GetData(); + switch (side) + { + case DIVISION_SIDE_LEFT: + { + if (division->m_rightSide == this) + { + bool success = division->AdjustRight(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + case DIVISION_SIDE_TOP: + { + if (division->m_bottomSide == this) + { + bool success = division->AdjustBottom(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + case DIVISION_SIDE_RIGHT: + { + if (division->m_leftSide == this) + { + bool success = division->AdjustLeft(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + case DIVISION_SIDE_BOTTOM: + { + if (division->m_topSide == this) + { + bool success = division->AdjustTop(newPos, test); + if (!success && test) + return FALSE; + } + break; + } + default: + break; + } + node = node->GetNext(); + } + + return TRUE; +} + +/* + * Popup menu for editing divisions + * + */ +class OGLPopupDivisionMenu : public wxMenu +{ +public: + OGLPopupDivisionMenu() : wxMenu() + { + Append(DIVISION_MENU_SPLIT_HORIZONTALLY, wxT("Split horizontally")); + Append(DIVISION_MENU_SPLIT_VERTICALLY, wxT("Split vertically")); + AppendSeparator(); + Append(DIVISION_MENU_EDIT_LEFT_EDGE, wxT("Edit left edge")); + Append(DIVISION_MENU_EDIT_TOP_EDGE, wxT("Edit top edge")); + } + + void OnMenu(wxCommandEvent &event); + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(OGLPopupDivisionMenu, wxMenu) + EVT_MENU_RANGE(DIVISION_MENU_SPLIT_HORIZONTALLY, + DIVISION_MENU_EDIT_BOTTOM_EDGE, + OGLPopupDivisionMenu::OnMenu) +END_EVENT_TABLE() + + +void OGLPopupDivisionMenu::OnMenu(wxCommandEvent &event) +{ + wxDivisionShape *division = (wxDivisionShape *)GetClientData(); + switch (event.GetInt()) + { + case DIVISION_MENU_SPLIT_HORIZONTALLY: + { + division->Divide(wxHORIZONTAL); + break; + } + case DIVISION_MENU_SPLIT_VERTICALLY: + { + division->Divide(wxVERTICAL); + break; + } + case DIVISION_MENU_EDIT_LEFT_EDGE: + { + division->EditEdge(DIVISION_SIDE_LEFT); + break; + } + case DIVISION_MENU_EDIT_TOP_EDGE: + { + division->EditEdge(DIVISION_SIDE_TOP); + break; + } + default: + break; + } +} + +void wxDivisionShape::EditEdge(int WXUNUSED(side)) +{ + wxMessageBox(wxT("EditEdge() not implemented"), wxT("OGL"), wxOK); + +#if 0 + wxBeginBusyCursor(); + + wxPen *currentPen = NULL; + char **pColour = NULL; + char **pStyle = NULL; + if (side == DIVISION_SIDE_LEFT) + { + currentPen = m_leftSidePen; + pColour = &m_leftSideColour; + pStyle = &m_leftSideStyle; + } + else + { + currentPen = m_topSidePen; + pColour = &m_topSideColour; + pStyle = &m_topSideStyle; + } + + GraphicsForm *form = new GraphicsForm("Containers"); + int lineWidth = currentPen->GetWidth(); + + form->Add(wxMakeFormShort("Width", &lineWidth, wxFORM_DEFAULT, NULL, NULL, wxVERTICAL, + 150)); + form->Add(wxMakeFormString("Colour", pColour, wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "BLACK" , + "BLUE" , + "BROWN" , + "CORAL" , + "CYAN" , + "DARK GREY" , + "DARK GREEN" , + "DIM GREY" , + "GREY" , + "GREEN" , + "LIGHT BLUE" , + "LIGHT GREY" , + "MAGENTA" , + "MAROON" , + "NAVY" , + "ORANGE" , + "PURPLE" , + "RED" , + "TURQUOISE" , + "VIOLET" , + "WHITE" , + "YELLOW" , + NULL), + NULL), NULL, wxVERTICAL, 150)); + form->Add(wxMakeFormString("Style", pStyle, wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "Solid" , + "Short Dash" , + "Long Dash" , + "Dot" , + "Dot Dash" , + NULL), + NULL), NULL, wxVERTICAL, 100)); + + wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Division properties", 10, 10, 500, 500); + if (GraphicsLabelFont) + dialog->SetLabelFont(GraphicsLabelFont); + if (GraphicsButtonFont) + dialog->SetButtonFont(GraphicsButtonFont); + + form->AssociatePanel(dialog); + form->dialog = dialog; + + dialog->Fit(); + dialog->Centre(wxBOTH); + + wxEndBusyCursor(); + dialog->Show(TRUE); + + int lineStyle = wxSOLID; + if (*pStyle) + { + if (strcmp(*pStyle, "Solid") == 0) + lineStyle = wxSOLID; + else if (strcmp(*pStyle, "Dot") == 0) + lineStyle = wxDOT; + else if (strcmp(*pStyle, "Short Dash") == 0) + lineStyle = wxSHORT_DASH; + else if (strcmp(*pStyle, "Long Dash") == 0) + lineStyle = wxLONG_DASH; + else if (strcmp(*pStyle, "Dot Dash") == 0) + lineStyle = wxDOT_DASH; + } + + wxPen *newPen = wxThePenList->FindOrCreatePen(*pColour, lineWidth, lineStyle); + if (!pen) + pen = wxBLACK_PEN; + if (side == DIVISION_SIDE_LEFT) + m_leftSidePen = newPen; + else + m_topSidePen = newPen; + + // Need to draw whole image again + wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent(); + compositeParent->Draw(dc); +#endif +} + +// Popup menu +void wxDivisionShape::PopupMenu(double x, double y) +{ + wxMenu *oglPopupDivisionMenu = new OGLPopupDivisionMenu; + + oglPopupDivisionMenu->SetClientData((void *)this); + if (m_leftSide) + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, TRUE); + else + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_LEFT_EDGE, FALSE); + if (m_topSide) + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, TRUE); + else + oglPopupDivisionMenu->Enable(DIVISION_MENU_EDIT_TOP_EDGE, FALSE); + + int x1, y1; + m_canvas->GetViewStart(&x1, &y1); + + int unit_x, unit_y; + m_canvas->GetScrollPixelsPerUnit(&unit_x, &unit_y); + + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + int mouse_x = (int)(dc.LogicalToDeviceX((long)(x - x1 * unit_x))); + int mouse_y = (int)(dc.LogicalToDeviceY((long)(y - y1 * unit_y))); + + m_canvas->PopupMenu(oglPopupDivisionMenu, mouse_x, mouse_y); + delete oglPopupDivisionMenu; +} + +void wxDivisionShape::SetLeftSideColour(const wxString &colour) +{ + m_leftSideColour = colour; +} + +void wxDivisionShape::SetTopSideColour(const wxString &colour) +{ + m_topSideColour = colour; +} + +void wxDivisionShape::SetLeftSideStyle(const wxString &style) +{ + m_leftSideStyle = style; +} + +void wxDivisionShape::SetTopSideStyle(const wxString &style) +{ + m_topSideStyle = style; +} + diff --git a/ogl/constrnt.cpp b/ogl/constrnt.cpp new file mode 100644 index 0000000..0d90461 --- /dev/null +++ b/ogl/constrnt.cpp @@ -0,0 +1,606 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// constrnt.cpp - OGL Constraint classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + + +wxList *wxOGLConstraintTypes = NULL; + +/* + * Constraint type + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraintType, wxObject) + +wxOGLConstraintType::wxOGLConstraintType(int theType, const wxString &theName, const wxString &thePhrase) +{ + m_type = theType; + m_name = theName; + m_phrase = thePhrase; +} + +wxOGLConstraintType::~wxOGLConstraintType() +{ +} + +void OGLInitializeConstraintTypes() +{ + if (!wxOGLConstraintTypes) + return; + + wxOGLConstraintTypes = new wxList(wxKEY_INTEGER); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY, + new wxOGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, wxT("Centre vertically"), wxT("centred vertically w.r.t."))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY, + new wxOGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, wxT("Centre horizontally"), wxT("centred horizontally w.r.t."))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH, + new wxOGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, wxT("Centre"), wxT("centred w.r.t."))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF, + new wxOGLConstraintType(gyCONSTRAINT_LEFT_OF, wxT("Left of"), wxT("left of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF, + new wxOGLConstraintType(gyCONSTRAINT_RIGHT_OF, wxT("Right of"), wxT("right of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ABOVE, + new wxOGLConstraintType(gyCONSTRAINT_ABOVE, wxT("Above"), wxT("above"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_BELOW, + new wxOGLConstraintType(gyCONSTRAINT_BELOW, wxT("Below"), wxT("below"))); + + // Alignment + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, wxT("Top-aligned"), wxT("aligned to the top of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, wxT("Bottom-aligned"), wxT("aligned to the bottom of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, wxT("Left-aligned"), wxT("aligned to the left of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT, + new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, wxT("Right-aligned"), wxT("aligned to the right of"))); + + // Mid-alignment + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, wxT("Top-midaligned"), wxT("centred on the top of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, wxT("Bottom-midaligned"), wxT("centred on the bottom of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, wxT("Left-midaligned"), wxT("centred on the left of"))); + + wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT, + new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, wxT("Right-midaligned"), wxT("centred on the right of"))); +} + +void OGLCleanUpConstraintTypes() +{ + if (!wxOGLConstraintTypes) + return; + + wxNode *node = wxOGLConstraintTypes->GetFirst(); + while (node) + { + wxOGLConstraintType *ct = (wxOGLConstraintType *) node->GetData(); + delete ct; + node = node->GetNext(); + } + delete wxOGLConstraintTypes; + wxOGLConstraintTypes = NULL; +} + +/* + * Constraint Stuff + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraint, wxObject) + +wxOGLConstraint::wxOGLConstraint(int type, wxShape *constraining, wxList &constrained) +{ + m_xSpacing = 0.0; + m_ySpacing = 0.0; + + m_constraintType = type; + m_constrainingObject = constraining; + + m_constraintId = 0; + m_constraintName = wxT("noname"); + + wxNode *node = constrained.GetFirst(); + while (node) + { + m_constrainedObjects.Append(node->GetData()); + node = node->GetNext(); + } +} + +wxOGLConstraint::~wxOGLConstraint() +{ +} + +bool wxOGLConstraint::Equals(double a, double b) +{ + double marg = 0.5; + + bool eq = ((b <= a + marg) && (b >= a - marg)); + return eq; +} + +// Return TRUE if anything changed +bool wxOGLConstraint::Evaluate() +{ + double maxWidth, maxHeight, minWidth, minHeight, x, y; + m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight); + m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight); + x = m_constrainingObject->GetX(); + y = m_constrainingObject->GetY(); + + switch (m_constraintType) + { + case gyCONSTRAINT_CENTRED_VERTICALLY: + { + int n = m_constrainedObjects.GetCount(); + double totalObjectHeight = 0.0; + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + totalObjectHeight += height2; + node = node->GetNext(); + } + double startY; + double spacingY; + // Check if within the constraining object... + if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight) + { + spacingY = (double)((minHeight - totalObjectHeight) / (n + 1)); + startY = (double)(y - (minHeight / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingY = m_ySpacing; + startY = (double)(y - ((totalObjectHeight + (n + 1) * spacingY) / 2.0)); + } + + // Now position the objects + bool changed = FALSE; + node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + startY += (double)(spacingY + (height2 / 2.0)); + if (!Equals(startY, constrainedObject->GetY())) + { + constrainedObject->Move(constrainedObject->GetX(), startY, FALSE); + changed = TRUE; + } + startY += (double)(height2 / 2.0); + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_CENTRED_HORIZONTALLY: + { + int n = m_constrainedObjects.GetCount(); + double totalObjectWidth = 0.0; + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + totalObjectWidth += width2; + node = node->GetNext(); + } + double startX; + double spacingX; + // Check if within the constraining object... + if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth) + { + spacingX = (double)((minWidth - totalObjectWidth) / (n + 1)); + startX = (double)(x - (minWidth / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingX = m_xSpacing; + startX = (double)(x - ((totalObjectWidth + (n + 1) * spacingX) / 2.0)); + } + + // Now position the objects + bool changed = FALSE; + node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + startX += (double)(spacingX + (width2 / 2.0)); + if (!Equals(startX, constrainedObject->GetX())) + { + constrainedObject->Move(startX, constrainedObject->GetY(), FALSE); + changed = TRUE; + } + startX += (double)(width2 / 2.0); + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_CENTRED_BOTH: + { + int n = m_constrainedObjects.GetCount(); + double totalObjectWidth = 0.0; + double totalObjectHeight = 0.0; + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + totalObjectWidth += width2; + totalObjectHeight += height2; + node = node->GetNext(); + } + double startX; + double spacingX; + double startY; + double spacingY; + + // Check if within the constraining object... + if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth) + { + spacingX = (double)((minWidth - totalObjectWidth) / (n + 1)); + startX = (double)(x - (minWidth / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingX = m_xSpacing; + startX = (double)(x - ((totalObjectWidth + (n + 1) * spacingX) / 2.0)); + } + + // Check if within the constraining object... + if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight) + { + spacingY = (double)((minHeight - totalObjectHeight) / (n + 1)); + startY = (double)(y - (minHeight / 2.0)); + } + // Otherwise, use default spacing + else + { + spacingY = m_ySpacing; + startY = (double)(y - ((totalObjectHeight + (n + 1) * spacingY) / 2.0)); + } + + // Now position the objects + bool changed = FALSE; + node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + startX += (double)(spacingX + (width2 / 2.0)); + startY += (double)(spacingY + (height2 / 2.0)); + + if ((!Equals(startX, constrainedObject->GetX())) || (!Equals(startY, constrainedObject->GetY()))) + { + constrainedObject->Move(startX, startY, FALSE); + changed = TRUE; + } + + startX += (double)(width2 / 2.0); + startY += (double)(height2 / 2.0); + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_LEFT_OF: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x - (minWidth / 2.0) - (width2 / 2.0) - m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_RIGHT_OF: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x + (minWidth / 2.0) + (width2 / 2.0) + m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ABOVE: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y - (minHeight / 2.0) - (height2 / 2.0) - m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_BELOW: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y + (minHeight / 2.0) + (height2 / 2.0) + m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ALIGNED_LEFT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x - (minWidth / 2.0) + (width2 / 2.0) + m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ALIGNED_RIGHT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double x3 = (double)(x + (minWidth / 2.0) - (width2 / 2.0) - m_xSpacing); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; +#if 0 + // two returned values ? + return FALSE; +#endif + } + case gyCONSTRAINT_ALIGNED_TOP: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y - (minHeight / 2.0) + (height2 / 2.0) + m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_ALIGNED_BOTTOM: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double width2, height2; + constrainedObject->GetBoundingBoxMax(&width2, &height2); + + double y3 = (double)(y + (minHeight / 2.0) - (height2 / 2.0) - m_ySpacing); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_MIDALIGNED_LEFT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double x3 = (double)(x - (minWidth / 2.0)); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_MIDALIGNED_RIGHT: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double x3 = (double)(x + (minWidth / 2.0)); + if (!Equals(x3, constrainedObject->GetX())) + { + changed = TRUE; + constrainedObject->Move(x3, constrainedObject->GetY(), FALSE); + } + + node = node->GetNext(); + } + return changed; +#if 0 + // two returned values ? + return FALSE; +#endif + } + case gyCONSTRAINT_MIDALIGNED_TOP: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double y3 = (double)(y - (minHeight / 2.0)); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } + case gyCONSTRAINT_MIDALIGNED_BOTTOM: + { + bool changed = FALSE; + + wxNode *node = m_constrainedObjects.GetFirst(); + while (node) + { + wxShape *constrainedObject = (wxShape *)node->GetData(); + + double y3 = (double)(y + (minHeight / 2.0)); + if (!Equals(y3, constrainedObject->GetY())) + { + changed = TRUE; + constrainedObject->Move(constrainedObject->GetX(), y3, FALSE); + } + + node = node->GetNext(); + } + return changed; + } +#if 0 + // default value handled in main function body + default: + return FALSE; +#endif + } + + return FALSE; +} + diff --git a/ogl/divided.cpp b/ogl/divided.cpp new file mode 100644 index 0000000..a141cee --- /dev/null +++ b/ogl/divided.cpp @@ -0,0 +1,714 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// divided.cpp - wxDividedShape class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +static wxChar * +oglCopystring (const wxChar *s) +{ + if (s == NULL) s = wxEmptyString; + size_t len = wxStrlen (s) + 1; + + wxChar *news = new wxChar[len]; + memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest + + return news; +} + +class wxDividedShapeControlPoint: public wxControlPoint +{ + DECLARE_DYNAMIC_CLASS(wxDividedShapeControlPoint) +private: + int regionId; +public: + wxDividedShapeControlPoint() + { + regionId = 0; + } + wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, int region, + double size, double the_xoffset, double the_yoffset, int the_type); + ~wxDividedShapeControlPoint(); + + void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0); + void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0); + void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0); +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDividedShapeControlPoint, wxControlPoint) + +/* + * Divided object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxDividedShape, wxRectangleShape) + +wxDividedShape::wxDividedShape(double w, double h): wxRectangleShape(w, h) +{ + ClearRegions(); +} + +wxDividedShape::~wxDividedShape() +{ +} + +void wxDividedShape::OnDraw(wxDC &dc) +{ + wxRectangleShape::OnDraw(dc); +} + +void wxDividedShape::OnDrawContents(wxDC &dc) +{ + double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0); + double currentY = (double)(m_ypos - (m_height / 2.0)); + double maxY = (double)(m_ypos + (m_height / 2.0)); + + double leftX = (double)(m_xpos - (m_width / 2.0)); + double rightX = (double)(m_xpos + (m_width / 2.0)); + + if (m_pen) dc.SetPen(* m_pen); + + if (m_textColour.IsOk()) dc.SetTextForeground(m_textColour); + +#ifdef __WXMSW__ + // For efficiency, don't do this under X - doesn't make + // any visible difference for our purposes. + if (m_brush) + dc.SetTextBackground(m_brush->GetColour()); +#endif + /* + if (!formatted) + { + FormatRegionText(); + formatted = TRUE; + } + */ + if (GetDisableLabel()) return; + + double xMargin = 2; + double yMargin = 2; + dc.SetBackgroundMode(wxTRANSPARENT); + + wxNode *node = GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + dc.SetFont(* region->GetFont()); + dc.SetTextForeground(region->GetActualColourObject()); + + double proportion = + region->m_regionProportionY < 0.0 ? defaultProportion : region->m_regionProportionY; + + double y = currentY + m_height * proportion; + double actualY = maxY < y ? maxY : y; + + double centreX = m_xpos; + double centreY = (double)(currentY + (actualY - currentY) / 2.0); + + oglDrawFormattedText(dc, ®ion->m_formattedText, + (double)(centreX), (double)(centreY), (double)(m_width - 2 * xMargin), (double)(actualY - currentY - 2 * yMargin), + region->m_formatMode); + if ((y <= maxY) && (node->GetNext())) + { + wxPen *regionPen = region->GetActualPen(); + if (regionPen) + { + dc.SetPen(* regionPen); + dc.DrawLine(WXROUND(leftX), WXROUND(y), WXROUND(rightX), WXROUND(y)); + } + } + + currentY = actualY; + + node = node->GetNext(); + } +} + +void wxDividedShape::SetSize(double w, double h, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(w, h); + m_width = w; + m_height = h; + SetRegionSizes(); +} + +void wxDividedShape::SetRegionSizes() +{ + if (GetRegions().GetCount() == 0) + return; + + double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0); + double currentY = (double)(m_ypos - (m_height / 2.0)); + double maxY = (double)(m_ypos + (m_height / 2.0)); + +// double leftX = (double)(m_xpos - (m_width / 2.0)); +// double rightX = (double)(m_xpos + (m_width / 2.0)); + + wxNode *node = GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + double proportion = + region->m_regionProportionY <= 0.0 ? defaultProportion : region->m_regionProportionY; + + double sizeY = (double)proportion * m_height; + double y = currentY + sizeY; + double actualY = maxY < y ? maxY : y; + + double centreY = (double)(currentY + (actualY - currentY) / 2.0); + + region->SetSize(m_width, sizeY); + region->SetPosition(0.0, (double)(centreY - m_ypos)); + currentY = actualY; + node = node->GetNext(); + } +} + +// Attachment points correspond to regions in the divided box +bool wxDividedShape::GetAttachmentPosition(int attachment, double *x, double *y, int nth, int no_arcs, + wxLineShape *line) +{ + int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2; + if ((GetAttachmentMode() == ATTACHMENT_MODE_NONE) || (attachment >= totalNumberAttachments)) + { + return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs); + } + + int n = GetRegions().GetCount(); + bool isEnd = (line && line->IsEnd(this)); + + double left = (double)(m_xpos - m_width / 2.0); + double right = (double)(m_xpos + m_width / 2.0); + double top = (double)(m_ypos - m_height / 2.0); + double bottom = (double)(m_ypos + m_height / 2.0); + + // Zero is top, n+1 is bottom. + if (attachment == 0) + { + *y = top; + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->x < left) + *x = left; + else if (point->x > right) + *x = right; + else + *x = point->x; + } + else + *x = left + (nth + 1) * m_width / (no_arcs + 1); + } + else + *x = m_xpos; + } + else if (attachment == (n + 1)) + { + *y = bottom; + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->x < left) + *x = left; + else if (point->x > right) + *x = right; + else + *x = point->x; + } + else + *x = left + (nth + 1) * m_width / (no_arcs + 1); + } + else + *x = m_xpos; + } + // Left or right. + else + { + bool isLeft = !(attachment < (n + 1)); + int i = (isLeft) ? (totalNumberAttachments - attachment - 1) : (attachment - 1); + wxNode *node = GetRegions().Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + if (isLeft) + *x = left; + else + *x = right; + + // Calculate top and bottom of region + top = (double)((m_ypos + region->m_y) - (region->m_height / 2.0)); + bottom = (double)((m_ypos + region->m_y) + (region->m_height / 2.0)); + + // Assuming we can trust the absolute size and + // position of these regions... + if (m_spaceAttachments) + { + if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE)) + { + // Align line according to the next handle along + wxRealPoint *point = line->GetNextControlPoint(this); + if (point->y < bottom) + *y = bottom; + else if (point->y > top) + *y = top; + else + *y = point->y; + } + else +// *y = (double)(((m_ypos + region->m_y) - (region->m_height/2.0)) + (nth + 1)*region->m_height/(no_arcs+1)); + *y = (double)(top + (nth + 1) * region->m_height / (no_arcs + 1)); + } + else + *y = (double)(m_ypos + region->m_y); + } + else + { + *x = m_xpos; + *y = m_ypos; + return FALSE; + } + } + return TRUE; +} + +int wxDividedShape::GetNumberOfAttachments() const +{ + // There are two attachments for each region (left and right), + // plus one on the top and one on the bottom. + int n = (GetRegions().GetCount() * 2) + 2; + + int maxN = n - 1; + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + if (point->m_id > maxN) + maxN = point->m_id; + node = node->GetNext(); + } + return maxN + 1; +} + +bool wxDividedShape::AttachmentIsValid(int attachment) const +{ + int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2; + if (attachment >= totalNumberAttachments) + { + return wxShape::AttachmentIsValid(attachment); + } + else if (attachment >= 0) + return TRUE; + else + return FALSE; +} + +void wxDividedShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); +} + +// Region operations + +void wxDividedShape::MakeControlPoints() +{ + wxRectangleShape::MakeControlPoints(); + + MakeMandatoryControlPoints(); +} + +void wxDividedShape::MakeMandatoryControlPoints() +{ + double currentY = (double)(GetY() - (m_height / 2.0)); + double maxY = (double)(GetY() + (m_height / 2.0)); + + wxNode *node = GetRegions().GetFirst(); + int i = 0; + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + double proportion = region->m_regionProportionY; + + double y = currentY + m_height * proportion; + double actualY = (double)(maxY < y ? maxY : y); + + if (node->GetNext()) + { + wxDividedShapeControlPoint *controlPoint = + new wxDividedShapeControlPoint(m_canvas, this, i, CONTROL_POINT_SIZE, 0.0, (double)(actualY - GetY()), 0); + m_canvas->AddShape(controlPoint); + m_controlPoints.Append(controlPoint); + } + currentY = actualY; + i ++; + node = node->GetNext(); + } +} + +void wxDividedShape::ResetControlPoints() +{ + // May only have the region handles, (n - 1) of them. + if (m_controlPoints.GetCount() > (GetRegions().GetCount() - 1)) + wxRectangleShape::ResetControlPoints(); + + ResetMandatoryControlPoints(); +} + +void wxDividedShape::ResetMandatoryControlPoints() +{ + double currentY = (double)(GetY() - (m_height / 2.0)); + double maxY = (double)(GetY() + (m_height / 2.0)); + + wxNode *node = m_controlPoints.GetFirst(); + int i = 0; + while (node) + { + wxControlPoint *controlPoint = (wxControlPoint *)node->GetData(); + if (controlPoint->IsKindOf(CLASSINFO(wxDividedShapeControlPoint))) + { + wxNode *node1 = GetRegions().Item(i); + wxShapeRegion *region = (wxShapeRegion *)node1->GetData(); + + double proportion = region->m_regionProportionY; + + double y = currentY + m_height * proportion; + double actualY = (double)(maxY < y ? maxY : y); + + controlPoint->m_xoffset = 0.0; + controlPoint->m_yoffset = (double)(actualY - GetY()); + currentY = actualY; + i ++; + } + node = node->GetNext(); + } +} + +#if wxUSE_PROLOGIO +void wxDividedShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); +} + +void wxDividedShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); +} +#endif + +/* + * Edit the division colour/style + * + */ + +void wxDividedShape::EditRegions() +{ + wxMessageBox(wxT("EditRegions() is unimplemented."), wxT("OGL"), wxOK); + + // TODO +#if 0 + if (GetRegions().GetCount() < 2) + return; + + wxBeginBusyCursor(); + + GraphicsForm *form = new GraphicsForm("Divided nodes"); + // Need an array to store all the style strings, + // since they need to be converted to integers + char **styleStrings = new char *[GetRegions().GetCount()]; + for (int j = 0; j < GetRegions().GetCount(); j++) + styleStrings[j] = NULL; + + int i = 0; + wxNode *node = GetRegions().GetFirst(); + while (node && node->GetNext()) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + char buf[50]; + sprintf(buf, "Region %d", (i + 1)); + form->Add(wxMakeFormMessage(buf)); + form->Add(wxMakeFormNewLine()); + + form->Add(wxMakeFormString("Colour", ®ion->penColour, wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "Invisible" , + "BLACK" , + "BLUE" , + "BROWN" , + "CORAL" , + "CYAN" , + "DARK GREY" , + "DARK GREEN" , + "DIM GREY" , + "GREY" , + "GREEN" , + "LIGHT BLUE" , + "LIGHT GREY" , + "MAGENTA" , + "MAROON" , + "NAVY" , + "ORANGE" , + "PURPLE" , + "RED" , + "TURQUOISE" , + "VIOLET" , + "WHITE" , + "YELLOW" , + NULL), + NULL), NULL, wxVERTICAL, 150)); + + char *styleString = NULL; + switch (region->penStyle) + { + case wxSHORT_DASH: + styleString = "Short Dash"; + break; + case wxLONG_DASH: + styleString = "Long Dash"; + break; + case wxDOT: + styleString = "Dot"; + break; + case wxDOT_DASH: + styleString = "Dot Dash"; + break; + case wxSOLID: + default: + styleString = "Solid"; + break; + } + styleStrings[i] = oglCopystring(styleString); + form->Add(wxMakeFormString("Style", &(styleStrings[i]), wxFORM_CHOICE, + new wxList(wxMakeConstraintStrings( + "Solid" , + "Short Dash" , + "Long Dash" , + "Dot" , + "Dot Dash" , + NULL), + NULL), NULL, wxVERTICAL, 100)); + node = node->GetNext(); + i ++; + if (node && node->GetNext()) + form->Add(wxMakeFormNewLine()); + } + wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Divided object properties", 10, 10, 500, 500); + if (GraphicsLabelFont) + dialog->SetLabelFont(GraphicsLabelFont); + if (GraphicsButtonFont) + dialog->SetButtonFont(GraphicsButtonFont); + form->AssociatePanel(dialog); + form->dialog = dialog; + + dialog->Fit(); + dialog->Centre(wxBOTH); + + wxEndBusyCursor(); + + dialog->Show(TRUE); + + node = GetRegions().GetFirst(); + i = 0; + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + if (styleStrings[i]) + { + if (strcmp(styleStrings[i], "Solid") == 0) + region->penStyle = wxSOLID; + else if (strcmp(styleStrings[i], "Dot") == 0) + region->penStyle = wxDOT; + else if (strcmp(styleStrings[i], "Short Dash") == 0) + region->penStyle = wxSHORT_DASH; + else if (strcmp(styleStrings[i], "Long Dash") == 0) + region->penStyle = wxLONG_DASH; + else if (strcmp(styleStrings[i], "Dot Dash") == 0) + region->penStyle = wxDOT_DASH; + delete[] styleStrings[i]; + } + region->m_actualPenObject = NULL; + node = node->GetNext(); + i ++; + } + delete[] styleStrings; + Draw(dc); +#endif +} + +void wxDividedShape::OnRightClick(double x, double y, int keys, int attachment) +{ + if (keys & KEY_CTRL) + { + EditRegions(); + } + else + { + wxRectangleShape::OnRightClick(x, y, keys, attachment); + } +} + +wxDividedShapeControlPoint::wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, + int region, double size, double the_m_xoffset, double the_m_yoffset, int the_type): + wxControlPoint(the_canvas, object, size, the_m_xoffset, the_m_yoffset, the_type) +{ + regionId = region; +} + +wxDividedShapeControlPoint::~wxDividedShapeControlPoint() +{ +} + +// Implement resizing of divided object division +void wxDividedShapeControlPoint::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + wxDividedShape *dividedObject = (wxDividedShape *)m_shape; + double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0)); + double y1 = y; + double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0)); + double y2 = y; + dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2)); +} + +void wxDividedShapeControlPoint::OnBeginDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + wxDividedShape *dividedObject = (wxDividedShape *)m_shape; + dc.SetLogicalFunction(OGLRBLF); + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0)); + double y1 = y; + double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0)); + double y2 = y; + dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2)); + m_canvas->CaptureMouse(); +} + +void wxDividedShapeControlPoint::OnEndDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + wxDividedShape *dividedObject = (wxDividedShape *)m_shape; + wxNode *node = dividedObject->GetRegions().Item(regionId); + if (!node) + return; + + wxShapeRegion *thisRegion = (wxShapeRegion *)node->GetData(); + wxShapeRegion *nextRegion = NULL; // Region below this one + + dc.SetLogicalFunction(wxCOPY); + + m_canvas->ReleaseMouse(); + + // Find the old top and bottom of this region, + // and calculate the new proportion for this region + // if legal. + + double currentY = (double)(dividedObject->GetY() - (dividedObject->GetHeight() / 2.0)); + double maxY = (double)(dividedObject->GetY() + (dividedObject->GetHeight() / 2.0)); + + // Save values + double thisRegionTop = 0.0; +#if 0 + // this variable is not readed later + double thisRegionBottom = 0.0; +#endif + double nextRegionBottom = 0.0; + + node = dividedObject->GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + + double proportion = region->m_regionProportionY; + double yy = currentY + (dividedObject->GetHeight() * proportion); + double actualY = (double)(maxY < yy ? maxY : yy); + + if (region == thisRegion) + { + thisRegionTop = currentY; +#if 0 + // no need for assignment if value is not used later + thisRegionBottom = actualY; +#endif + if (node->GetNext()) + nextRegion = (wxShapeRegion *)node->GetNext()->GetData(); + } + if (region == nextRegion) + { + nextRegionBottom = actualY; + } + + currentY = actualY; + node = node->GetNext(); + } + if (!nextRegion) + return; + + // Check that we haven't gone above this region or below + // next region. + if ((y <= thisRegionTop) || (y >= nextRegionBottom)) + return; + + // dividedObject->EraseLinks(dc); + + // Now calculate the new proportions of this region and the next region. + double thisProportion = (double)((y - thisRegionTop) / dividedObject->GetHeight()); + double nextProportion = (double)((nextRegionBottom - y) / dividedObject->GetHeight()); + thisRegion->SetProportions(0.0, thisProportion); + nextRegion->SetProportions(0.0, nextProportion); + m_yoffset = (double)(y - dividedObject->GetY()); + + // Now reformat text + int i = 0; + node = dividedObject->GetRegions().GetFirst(); + while (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + if (!region->GetText().IsEmpty()) + { + wxChar *s = oglCopystring(region->GetText()); + dividedObject->FormatText(dc, s, i); + delete[] s; + } + node = node->GetNext(); + i++; + } + dividedObject->SetRegionSizes(); + dividedObject->GetEventHandler()->OnMoveLinks(); + + if (GetCanvas()) + GetCanvas()->Refresh(); +} + diff --git a/ogl/drawn.cpp b/ogl/drawn.cpp new file mode 100644 index 0000000..db239c0 --- /dev/null +++ b/ogl/drawn.cpp @@ -0,0 +1,2498 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// drawn.cpp - wxDrawnShape +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include "ogl/ogl.h" + +static wxChar * +oglCopystring (const wxChar *s) +{ + if (s == NULL) s = wxEmptyString; + size_t len = wxStrlen (s) + 1; + + wxChar *news = new wxChar[len]; + memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest + + return news; +} + +#include + +#if 0 +static void IntToHex(unsigned int dec, wxChar *buf); +static unsigned long HexToInt(wxChar *buf); +#endif + +extern wxChar *oglBuffer; + +#define gyTYPE_PEN 40 +#define gyTYPE_BRUSH 41 +#define gyTYPE_FONT 42 + +/* + * Drawn object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxDrawnShape, wxRectangleShape) + +wxDrawnShape::wxDrawnShape(): wxRectangleShape(100.0, 50.0) +{ + m_saveToFile = TRUE; + m_currentAngle = oglDRAWN_ANGLE_0; +} + +wxDrawnShape::~wxDrawnShape() +{ +} + +void wxDrawnShape::OnDraw(wxDC &dc) +{ + // Pass pen and brush in case we have force outline + // and fill colours + if (m_shadowMode != SHADOW_NONE) + { + if (m_shadowBrush) + m_metafiles[m_currentAngle].m_fillBrush = m_shadowBrush; + m_metafiles[m_currentAngle].m_outlinePen = g_oglTransparentPen; + m_metafiles[m_currentAngle].Draw(dc, m_xpos + m_shadowOffsetX, m_ypos + m_shadowOffsetY); + } + + m_metafiles[m_currentAngle].m_outlinePen = m_pen; + m_metafiles[m_currentAngle].m_fillBrush = m_brush; + m_metafiles[m_currentAngle].Draw(dc, m_xpos, m_ypos); +} + +void wxDrawnShape::SetSize(double w, double h, bool WXUNUSED(recursive)) +{ + SetAttachmentSize(w, h); + + double scaleX; + double scaleY; + if (GetWidth() == 0.0) + scaleX = 1.0; + else scaleX = w / GetWidth(); + if (GetHeight() == 0.0) + scaleY = 1.0; + else scaleY = h / GetHeight(); + + for (int i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + m_metafiles[i].Scale(scaleX, scaleY); + } + m_width = w; + m_height = h; + SetDefaultRegionSize(); +} + +void wxDrawnShape::Scale(double sx, double sy) +{ + int i; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + { + m_metafiles[i].Scale(sx, sy); + m_metafiles[i].CalculateSize(this); + } + } +} + +void wxDrawnShape::Translate(double x, double y) +{ + int i; + for (i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + { + m_metafiles[i].Translate(x, y); + m_metafiles[i].CalculateSize(this); + } + } +} + +// theta is absolute rotation from the zero position +void wxDrawnShape::Rotate(double x, double y, double theta) +{ + m_currentAngle = DetermineMetaFile(theta); + + if (m_currentAngle == 0) + { + // Rotate metafile + if (!m_metafiles[0].GetRotateable()) + return; + + m_metafiles[0].Rotate(x, y, theta); + } + + double actualTheta = theta - m_rotation; + + // Rotate attachment points + double sinTheta = (double)sin(actualTheta); + double cosTheta = (double)cos(actualTheta); + wxNode *node = m_attachmentPoints.GetFirst(); + while (node) + { + wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData(); + double x1 = point->m_x; + double y1 = point->m_y; + point->m_x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + point->m_y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + node = node->GetNext(); + } + m_rotation = theta; + + m_metafiles[m_currentAngle].CalculateSize(this); +} + +// Which metafile do we use now? Based on current rotation and validity +// of metafiles. + +int wxDrawnShape::DetermineMetaFile(double rotation) +{ + double tolerance = 0.0001; + const double pi = 3.1415926535897932384626433832795 ; + double angle1 = 0.0; + double angle2 = pi / 2.0; + double angle3 = pi; + double angle4 = 3.0 * pi / 2.0; + + int whichMetafile = 0; + + if (oglRoughlyEqual(rotation, angle1, tolerance)) + { + whichMetafile = 0; + } + else if (oglRoughlyEqual(rotation, angle2, tolerance)) + { + whichMetafile = 1; + } + else if (oglRoughlyEqual(rotation, angle3, tolerance)) + { + whichMetafile = 2; + } + else if (oglRoughlyEqual(rotation, angle4, tolerance)) + { + whichMetafile = 3; + } + + if ((whichMetafile > 0) && !m_metafiles[whichMetafile].IsValid()) + whichMetafile = 0; + + return whichMetafile; +} + +void wxDrawnShape::OnDrawOutline(wxDC &dc, double x, double y, double w, double h) +{ + if (m_metafiles[m_currentAngle].GetOutlineOp() != -1) + { + wxNode *node = m_metafiles[m_currentAngle].GetOps().Item(m_metafiles[m_currentAngle].GetOutlineOp()); + wxASSERT (node != NULL); + wxDrawOp *op = (wxDrawOp *) node->GetData(); + + if (op->OnDrawOutline(dc, x, y, w, h, m_width, m_height)) + return; + } + + // Default... just use a rectangle + wxRectangleShape::OnDrawOutline(dc, x, y, w, h); +} + +// Get the perimeter point using the special outline op, if there is one, +// otherwise use default wxRectangleShape scheme +bool wxDrawnShape::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3) +{ + if (m_metafiles[m_currentAngle].GetOutlineOp() != -1) + { + wxNode *node = m_metafiles[m_currentAngle].GetOps().Item(m_metafiles[m_currentAngle].GetOutlineOp()); + wxASSERT (node != NULL); + wxDrawOp *op = (wxDrawOp *) node->GetData(); + + if (op->GetPerimeterPoint(x1, y1, x2, y2, x3, y3, GetX(), GetY(), GetAttachmentMode())) + return TRUE; + } + + // Default... just use a rectangle + return wxRectangleShape::GetPerimeterPoint(x1, y1, x2, y2, x3, y3); +} + +#if wxUSE_PROLOGIO +void wxDrawnShape::WriteAttributes(wxExpr *clause) +{ + wxRectangleShape::WriteAttributes(clause); + + clause->AddAttributeValue(wxT("current_angle"), (long)m_currentAngle); + clause->AddAttributeValue(wxT("save_metafile"), (long)m_saveToFile); + if (m_saveToFile) + { + for (int i = 0; i < 4; i++) + { + if (m_metafiles[i].IsValid()) + m_metafiles[i].WriteAttributes(clause, i); + } + } +} + +void wxDrawnShape::ReadAttributes(wxExpr *clause) +{ + wxRectangleShape::ReadAttributes(clause); + + int iVal = (int) m_saveToFile; + clause->GetAttributeValue(wxT("save_metafile"), iVal); + clause->GetAttributeValue(wxT("current_angle"), m_currentAngle); + m_saveToFile = (iVal != 0); + + if (m_saveToFile) + { + for (int i = 0; i < 4; i++) + { + m_metafiles[i].ReadAttributes(clause, i); + } + } +} +#endif + +// Does the copying for this object +void wxDrawnShape::Copy(wxShape ©) +{ + wxRectangleShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxDrawnShape)) ) ; + + wxDrawnShape &drawnCopy = (wxDrawnShape &) copy; + + for (int i = 0; i < 4; i++) + { + m_metafiles[i].Copy(drawnCopy.m_metafiles[i]); + } + drawnCopy.m_saveToFile = m_saveToFile; + drawnCopy.m_currentAngle = m_currentAngle; +} + +bool wxDrawnShape::LoadFromMetaFile(const wxString &filename) +{ + return m_metafiles[0].LoadFromMetaFile(filename, &m_width, &m_height); +} + +// Set of functions for drawing into a pseudo metafile. +// They use integers, but doubles are used internally for accuracy +// when scaling. + +void wxDrawnShape::DrawLine(const wxPoint &pt1, const wxPoint &pt2) +{ + m_metafiles[m_currentAngle].DrawLine(pt1, pt2); +} + +void wxDrawnShape::DrawRectangle(const wxRect &rect) +{ + m_metafiles[m_currentAngle].DrawRectangle(rect); +} + +void wxDrawnShape::DrawRoundedRectangle(const wxRect &rect, double radius) +{ + m_metafiles[m_currentAngle].DrawRoundedRectangle(rect, radius); +} + +void wxDrawnShape::DrawEllipse(const wxRect &rect) +{ + m_metafiles[m_currentAngle].DrawEllipse(rect); +} + +void wxDrawnShape::DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt) +{ + m_metafiles[m_currentAngle].DrawArc(centrePt, startPt, endPt); +} + +void wxDrawnShape::DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle) +{ + m_metafiles[m_currentAngle].DrawEllipticArc(rect, startAngle, endAngle); +} + +void wxDrawnShape::DrawPoint(const wxPoint &pt) +{ + m_metafiles[m_currentAngle].DrawPoint(pt); +} + +void wxDrawnShape::DrawText(const wxString &text, const wxPoint &pt) +{ + m_metafiles[m_currentAngle].DrawText(text, pt); +} + +void wxDrawnShape::DrawLines(int n, wxPoint pts[]) +{ + m_metafiles[m_currentAngle].DrawLines(n, pts); +} + +void wxDrawnShape::DrawPolygon(int n, wxPoint pts[], int flags) +{ + if (flags & oglMETAFLAGS_ATTACHMENTS) + { + ClearAttachments(); + int i; + for (i = 0; i < n; i++) + m_attachmentPoints.Append(new wxAttachmentPoint(i, pts[i].x, pts[i].y)); + } + m_metafiles[m_currentAngle].DrawPolygon(n, pts, flags); +} + +void wxDrawnShape::DrawSpline(int n, wxPoint pts[]) +{ + m_metafiles[m_currentAngle].DrawSpline(n, pts); +} + +void wxDrawnShape::SetClippingRect(const wxRect &rect) +{ + m_metafiles[m_currentAngle].SetClippingRect(rect); +} + +void wxDrawnShape::DestroyClippingRect() +{ + m_metafiles[m_currentAngle].DestroyClippingRect(); +} + +void wxDrawnShape::SetDrawnPen(wxPen *pen, bool isOutline) +{ + m_metafiles[m_currentAngle].SetPen(pen, isOutline); +} + +void wxDrawnShape::SetDrawnBrush(wxBrush *brush, bool isFill) +{ + m_metafiles[m_currentAngle].SetBrush(brush, isFill); +} + +void wxDrawnShape::SetDrawnFont(wxFont *font) +{ + m_metafiles[m_currentAngle].SetFont(font); +} + +void wxDrawnShape::SetDrawnTextColour(const wxColour &colour) +{ + m_metafiles[m_currentAngle].SetTextColour(colour); +} + +void wxDrawnShape::SetDrawnBackgroundColour(const wxColour &colour) +{ + m_metafiles[m_currentAngle].SetBackgroundColour(colour); +} + +void wxDrawnShape::SetDrawnBackgroundMode(int mode) +{ + m_metafiles[m_currentAngle].SetBackgroundMode(mode); +} + + +/* + * Individual operations + * + */ + +/* + * Set font, brush, text colour + * + */ + +wxOpSetGDI::wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode): + wxDrawOp(theOp) +{ + m_gdiIndex = theGdiIndex; + m_image = theImage; + m_mode = theMode; +} + +void wxOpSetGDI::Do(wxDC &dc, double WXUNUSED(xoffset), double WXUNUSED(yoffset)) +{ + switch (m_op) + { + case DRAWOP_SET_PEN: + { + // Check for overriding this operation for outline + // colour + if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex)) + { + if (m_image->m_outlinePen) + dc.SetPen(* m_image->m_outlinePen); + } + else + { + wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex); + if (node) + { + wxPen *pen = (wxPen *)node->GetData(); + if (pen) + dc.SetPen(* pen); + } + } + break; + } + case DRAWOP_SET_BRUSH: + { + // Check for overriding this operation for outline or fill + // colour + if (m_image->m_outlineColours.Member((wxObject *)m_gdiIndex)) + { + // Need to construct a brush to match the outline pen's colour + if (m_image->m_outlinePen) + { + wxBrush *br = wxTheBrushList->FindOrCreateBrush(m_image->m_outlinePen->GetColour(), wxSOLID); + if (br) + dc.SetBrush(* br); + } + } + else if (m_image->m_fillColours.Member((wxObject *)m_gdiIndex)) + { + if (m_image->m_fillBrush) + { + dc.SetBrush(* m_image->m_fillBrush); + } + } + else + { + wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex); + if (node) + { + wxBrush *brush = (wxBrush *)node->GetData(); + if (brush) + dc.SetBrush(* brush); + } + } + break; + } + case DRAWOP_SET_FONT: + { + wxNode *node = m_image->m_gdiObjects.Item(m_gdiIndex); + if (node) + { + wxFont *font = (wxFont *)node->GetData(); + if (font) + dc.SetFont(* font); + } + break; + } + case DRAWOP_SET_TEXT_COLOUR: + { + wxColour col(m_r, m_g, m_b); + dc.SetTextForeground(col); + break; + } + case DRAWOP_SET_BK_COLOUR: + { + wxColour col(m_r, m_g, m_b); + dc.SetTextBackground(col); + break; + } + case DRAWOP_SET_BK_MODE: + { + dc.SetBackgroundMode(m_mode); + break; + } + default: + break; + } +} + +wxDrawOp *wxOpSetGDI::Copy(wxPseudoMetaFile *newImage) +{ + wxOpSetGDI *newOp = new wxOpSetGDI(m_op, newImage, m_gdiIndex, m_mode); + newOp->m_r = m_r; + newOp->m_g = m_g; + newOp->m_b = m_b; + return newOp; +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpSetGDI::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + switch (m_op) + { + case DRAWOP_SET_PEN: + case DRAWOP_SET_BRUSH: + case DRAWOP_SET_FONT: + { + expr->Append(new wxExpr((long)m_gdiIndex)); + break; + } + case DRAWOP_SET_TEXT_COLOUR: + case DRAWOP_SET_BK_COLOUR: + { + expr->Append(new wxExpr((long)m_r)); + expr->Append(new wxExpr((long)m_g)); + expr->Append(new wxExpr((long)m_b)); + break; + } + case DRAWOP_SET_BK_MODE: + { + expr->Append(new wxExpr((long)m_mode)); + break; + } + default: + break; + } + return expr; +} + +void wxOpSetGDI::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + switch (m_op) + { + case DRAWOP_SET_PEN: + case DRAWOP_SET_BRUSH: + case DRAWOP_SET_FONT: + { + m_gdiIndex = (int)expr->Nth(1)->IntegerValue(); + break; + } + case DRAWOP_SET_TEXT_COLOUR: + case DRAWOP_SET_BK_COLOUR: + { + m_r = (unsigned char)expr->Nth(1)->IntegerValue(); + m_g = (unsigned char)expr->Nth(2)->IntegerValue(); + m_b = (unsigned char)expr->Nth(3)->IntegerValue(); + break; + } + case DRAWOP_SET_BK_MODE: + { + m_mode = (int)expr->Nth(1)->IntegerValue(); + break; + } + default: + break; + } +} +#endif + +/* + * Set/destroy clipping + * + */ + +wxOpSetClipping::wxOpSetClipping(int theOp, double theX1, double theY1, + double theX2, double theY2): wxDrawOp(theOp) +{ + m_x1 = theX1; + m_y1 = theY1; + m_x2 = theX2; + m_y2 = theY2; +} + +wxDrawOp *wxOpSetClipping::Copy(wxPseudoMetaFile *WXUNUSED(newImage)) +{ + wxOpSetClipping *newOp = new wxOpSetClipping(m_op, m_x1, m_y1, m_x2, m_y2); + return newOp; +} + +void wxOpSetClipping::Do(wxDC &dc, double xoffset, double yoffset) +{ + switch (m_op) + { + case DRAWOP_SET_CLIPPING_RECT: + { + dc.SetClippingRegion((long)(m_x1 + xoffset), (long)(m_y1 + yoffset), (long)(m_x2 + xoffset), (long)(m_y2 + yoffset)); + break; + } + case DRAWOP_DESTROY_CLIPPING_RECT: + { + dc.DestroyClippingRegion(); + break; + } + default: + break; + } +} + +void wxOpSetClipping::Scale(double xScale, double yScale) +{ + m_x1 *= xScale; + m_y1 *= yScale; + m_x2 *= xScale; + m_y2 *= yScale; +} + +void wxOpSetClipping::Translate(double x, double y) +{ + m_x1 += x; + m_y1 += y; +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpSetClipping::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + switch (m_op) + { + case DRAWOP_SET_CLIPPING_RECT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + break; + } + default: + break; + } + return expr; +} + +void wxOpSetClipping::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + switch (m_op) + { + case DRAWOP_SET_CLIPPING_RECT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + break; + } + default: + break; + } +} +#endif + +/* + * Draw line, rectangle, rounded rectangle, ellipse, point, arc, text + * + */ + +wxOpDraw::wxOpDraw(int theOp, double theX1, double theY1, double theX2, double theY2, + double theRadius, wxChar *s) : wxDrawOp(theOp) +{ + m_x1 = theX1; + m_y1 = theY1; + m_x2 = theX2; + m_y2 = theY2; + m_x3 = 0.0; + m_y3 = 0.0; + m_radius = theRadius; + if (s) m_textString = oglCopystring(s); + else m_textString = NULL; +} + +wxOpDraw::~wxOpDraw() +{ + if (m_textString) delete[] m_textString; +} + +wxDrawOp *wxOpDraw::Copy(wxPseudoMetaFile *WXUNUSED(newImage)) +{ + wxOpDraw *newOp = new wxOpDraw(m_op, m_x1, m_y1, m_x2, m_y2, m_radius, m_textString); + newOp->m_x3 = m_x3; + newOp->m_y3 = m_y3; + return newOp; +} + +void wxOpDraw::Do(wxDC &dc, double xoffset, double yoffset) +{ + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + dc.DrawLine(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2 + xoffset), WXROUND(m_y2 + yoffset)); + break; + } + case DRAWOP_DRAW_RECT: + { + dc.DrawRectangle(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2), WXROUND(m_y2)); + break; + } + case DRAWOP_DRAW_ROUNDED_RECT: + { + dc.DrawRoundedRectangle(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2), WXROUND(m_y2), m_radius); + break; + } + case DRAWOP_DRAW_ELLIPSE: + { + dc.DrawEllipse(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), WXROUND(m_x2), WXROUND(m_y2)); + break; + } + case DRAWOP_DRAW_ARC: + { + dc.DrawArc(WXROUND(m_x2 + xoffset), WXROUND(m_y2 + yoffset), + WXROUND(m_x3 + xoffset), WXROUND(m_y3 + yoffset), + WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset)); + break; + } + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + const double pi = 3.1415926535897932384626433832795 ; + + // Convert back to degrees + dc.DrawEllipticArc( + WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset), + WXROUND(m_x2), WXROUND(m_y2), + WXROUND(m_x3 * (360.0 / (2.0 * pi))), WXROUND(m_y3 * (360.0 / (2.0 * pi)))); + break; + } + case DRAWOP_DRAW_POINT: + { + dc.DrawPoint(WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset)); + break; + } + case DRAWOP_DRAW_TEXT: + { + dc.DrawText(m_textString, WXROUND(m_x1 + xoffset), WXROUND(m_y1 + yoffset)); + break; + } + default: + break; + } +} + +void wxOpDraw::Scale(double scaleX, double scaleY) +{ + m_x1 *= scaleX; + m_y1 *= scaleY; + m_x2 *= scaleX; + m_y2 *= scaleY; + + if (m_op != DRAWOP_DRAW_ELLIPTIC_ARC) + { + m_x3 *= scaleX; + m_y3 *= scaleY; + } + + m_radius *= scaleX; +} + +void wxOpDraw::Translate(double x, double y) +{ + m_x1 += x; + m_y1 += y; + + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + m_x2 += x; + m_y2 += y; + break; + } + case DRAWOP_DRAW_ARC: + { + m_x2 += x; + m_y2 += y; + m_x3 += x; + m_y3 += y; + break; + } + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + break; + } + default: + break; + } +} + +void wxOpDraw::Rotate(double x, double y, double theta, double sinTheta, double cosTheta) +{ + double newX1 = m_x1 * cosTheta - m_y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY1 = m_x1 * sinTheta + m_y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + switch (m_op) + { + case DRAWOP_DRAW_LINE: + { + double newX2 = m_x2 * cosTheta - m_y2 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY2 = m_x2 * sinTheta + m_y2 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + m_x1 = newX1; + m_y1 = newY1; + m_x2 = newX2; + m_y2 = newY2; + break; + } + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + // Assume only 0, 90, 180, 270 degree rotations. + // oldX1, oldY1 represents the top left corner. Find the + // bottom right, and rotate that. Then the width/height is the difference + // between x/y values. + double oldBottomRightX = m_x1 + m_x2; + double oldBottomRightY = m_y1 + m_y2; + double newBottomRightX = oldBottomRightX * cosTheta - oldBottomRightY * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newBottomRightY = oldBottomRightX * sinTheta + oldBottomRightY * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + // Now find the new top-left, bottom-right coordinates. + double minX = wxMin(newX1, newBottomRightX); + double minY = wxMin(newY1, newBottomRightY); + double maxX = wxMax(newX1, newBottomRightX); + double maxY = wxMax(newY1, newBottomRightY); + + m_x1 = minX; + m_y1 = minY; + m_x2 = maxX - minX; // width + m_y2 = maxY - minY; // height + + if (m_op == DRAWOP_DRAW_ELLIPTIC_ARC) + { + // Add rotation to angles + m_x3 += theta; + m_y3 += theta; + } + + break; + } + case DRAWOP_DRAW_ARC: + { + double newX2 = m_x2 * cosTheta - m_y2 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY2 = m_x2 * sinTheta + m_y2 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + double newX3 = m_x3 * cosTheta - m_y3 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + double newY3 = m_x3 * sinTheta + m_y3 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + + m_x1 = newX1; + m_y1 = newY1; + m_x2 = newX2; + m_y2 = newY2; + m_x3 = newX3; + m_y3 = newY3; + + break; + } + default: + break; + } +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpDraw::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + switch (m_op) + { + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ELLIPSE: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + break; + } + case DRAWOP_DRAW_ROUNDED_RECT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + expr->Append(new wxExpr(m_radius)); + break; + } + case DRAWOP_DRAW_POINT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + break; + } + case DRAWOP_DRAW_TEXT: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(wxExprString, m_textString)); + break; + } + case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + expr->Append(new wxExpr(m_x1)); + expr->Append(new wxExpr(m_y1)); + expr->Append(new wxExpr(m_x2)); + expr->Append(new wxExpr(m_y2)); + expr->Append(new wxExpr(m_x3)); + expr->Append(new wxExpr(m_y3)); + break; + } + default: + { + break; + } + } + return expr; +} + +void wxOpDraw::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + switch (m_op) + { + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ELLIPSE: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + break; + } + case DRAWOP_DRAW_ROUNDED_RECT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + m_radius = expr->Nth(5)->RealValue(); + break; + } + case DRAWOP_DRAW_POINT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + break; + } + case DRAWOP_DRAW_TEXT: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + wxString str(expr->Nth(3)->StringValue()); + m_textString = oglCopystring(str); + break; + } + case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_ELLIPTIC_ARC: + { + m_x1 = expr->Nth(1)->RealValue(); + m_y1 = expr->Nth(2)->RealValue(); + m_x2 = expr->Nth(3)->RealValue(); + m_y2 = expr->Nth(4)->RealValue(); + m_x3 = expr->Nth(5)->RealValue(); + m_y3 = expr->Nth(6)->RealValue(); + break; + } + default: + { + break; + } + } +} +#endif + +/* + * Draw polygon, polyline, spline + * + */ + +wxOpPolyDraw::wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints): wxDrawOp(theOp) +{ + m_noPoints = n; + m_points = thePoints; +} + +wxOpPolyDraw::~wxOpPolyDraw() +{ + delete[] m_points; +} + +wxDrawOp *wxOpPolyDraw::Copy(wxPseudoMetaFile *WXUNUSED(newImage)) +{ + wxRealPoint *newPoints = new wxRealPoint[m_noPoints]; + for (int i = 0; i < m_noPoints; i++) + { + newPoints[i].x = m_points[i].x; + newPoints[i].y = m_points[i].y; + } + wxOpPolyDraw *newOp = new wxOpPolyDraw(m_op, m_noPoints, newPoints); + return newOp; +} + +void wxOpPolyDraw::Do(wxDC &dc, double xoffset, double yoffset) +{ + switch (m_op) + { + case DRAWOP_DRAW_POLYLINE: + { + wxPoint *actualPoints = new wxPoint[m_noPoints]; + int i; + for (i = 0; i < m_noPoints; i++) + { + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); + } + + dc.DrawLines(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset)); + + delete[] actualPoints; + break; + } + case DRAWOP_DRAW_POLYGON: + { + wxPoint *actualPoints = new wxPoint[m_noPoints]; + int i; + for (i = 0; i < m_noPoints; i++) + { + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); + } + + dc.DrawPolygon(m_noPoints, actualPoints, WXROUND(xoffset), WXROUND(yoffset)); + + delete[] actualPoints; + break; + } + case DRAWOP_DRAW_SPLINE: + { + wxPoint *actualPoints = new wxPoint[m_noPoints]; + int i; + for (i = 0; i < m_noPoints; i++) + { + actualPoints[i].x = WXROUND(m_points[i].x); + actualPoints[i].y = WXROUND(m_points[i].y); + } + + dc.DrawSpline(m_noPoints, actualPoints); // no offsets in DrawSpline // , xoffset, yoffset); + + delete[] actualPoints; + break; + } + default: + break; + } +} + +void wxOpPolyDraw::Scale(double scaleX, double scaleY) +{ + for (int i = 0; i < m_noPoints; i++) + { + m_points[i].x *= scaleX; + m_points[i].y *= scaleY; + } +} + +void wxOpPolyDraw::Translate(double x, double y) +{ + for (int i = 0; i < m_noPoints; i++) + { + m_points[i].x += x; + m_points[i].y += y; + } +} + +void wxOpPolyDraw::Rotate(double x, double y, double WXUNUSED(theta), double sinTheta, double cosTheta) +{ + for (int i = 0; i < m_noPoints; i++) + { + double x1 = m_points[i].x; + double y1 = m_points[i].y; + m_points[i].x = x1 * cosTheta - y1 * sinTheta + x * (1.0 - cosTheta) + y * sinTheta; + m_points[i].y = x1 * sinTheta + y1 * cosTheta + y * (1.0 - cosTheta) + x * sinTheta; + } +} + +#if wxUSE_PROLOGIO +wxExpr *wxOpPolyDraw::WriteExpr(wxPseudoMetaFile *WXUNUSED(image)) +{ + wxExpr *expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)m_op)); + expr->Append(new wxExpr((long)m_noPoints)); + +// char buf1[9]; + wxChar buf2[5]; + wxChar buf3[5]; + + oglBuffer[0] = 0; + + /* + * Store each coordinate pair in a hex string to save space. + * E.g. "1B9080CD". 4 hex digits per coordinate pair. + * + */ + + for (int i = 0; i < m_noPoints; i++) + { + long signedX = (long)(m_points[i].x * 100.0); + long signedY = (long)(m_points[i].y * 100.0); + + // Scale to 0 -> 64K + long unSignedX = (long)(signedX + 32767.0); + long unSignedY = (long)(signedY + 32767.0); + +// IntToHex((unsigned int)signedX, buf2); +// IntToHex((unsigned int)signedY, buf3); + IntToHex((int)unSignedX, buf2); + IntToHex((int)unSignedY, buf3); + + // Don't overrun the buffer + if ((i * 8) < 3000) + { + wxStrcat(oglBuffer, buf2); + wxStrcat(oglBuffer, buf3); + } + } + expr->Append(new wxExpr(wxExprString, oglBuffer)); + return expr; +} + +void wxOpPolyDraw::ReadExpr(wxPseudoMetaFile *WXUNUSED(image), wxExpr *expr) +{ + m_noPoints = (int)expr->Nth(1)->IntegerValue(); + + wxChar buf1[5]; + wxChar buf2[5]; + + m_points = new wxRealPoint[m_noPoints]; + int i = 0; + int bufPtr = 0; + wxString hexString = expr->Nth(2)->StringValue(); + while (i < m_noPoints) + { + buf1[0] = hexString[(size_t)bufPtr]; + buf1[1] = hexString[(size_t)(bufPtr + 1)]; + buf1[2] = hexString[(size_t)(bufPtr + 2)]; + buf1[3] = hexString[(size_t)(bufPtr + 3)]; + buf1[4] = 0; + + buf2[0] = hexString[(size_t)(bufPtr + 4)]; + buf2[1] = hexString[(size_t)(bufPtr + 5)]; + buf2[2] = hexString[(size_t)(bufPtr + 6)]; + buf2[3] = hexString[(size_t)(bufPtr + 7)]; + buf2[4] = 0; + + bufPtr += 8; + +// int signedX = (signed int)HexToInt(buf1); +// int signedY = (signed int)HexToInt(buf2); + long unSignedX = HexToInt(buf1); + long unSignedY = HexToInt(buf2); + // Scale -32K -> +32K + long signedX = unSignedX - 32767; + long signedY = unSignedY - 32767; +#if defined(__WXMSW__) && 0 + int testX = (signed int)unSignedX; + int testY = (signed int)unSignedY; +#endif + + m_points[i].x = (double)(signedX / 100.0); + m_points[i].y = (double)(signedY / 100.0); + + i ++; + } +} +#endif + +// Draw an outline using the current operation. +bool wxOpPolyDraw::OnDrawOutline(wxDC &dc, double x, double y, double w, double h, double oldW, double oldH) +{ + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + // Multiply all points by proportion of new size to old size + double x_proportion = (double)(fabs(w / oldW)); + double y_proportion = (double)(fabs(h / oldH)); + + int n = m_noPoints; + wxPoint *intPoints = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + intPoints[i].x = WXROUND (x_proportion * m_points[i].x); + intPoints[i].y = WXROUND (y_proportion * m_points[i].y); + } + dc.DrawPolygon(n, intPoints, (long) x, (long) y); + delete[] intPoints; + return TRUE; +} + +// Assume (x1, y1) is centre of box (most generally, line end at box) +bool wxOpPolyDraw::GetPerimeterPoint(double x1, double y1, + double x2, double y2, + double *x3, double *y3, + double xOffset, double yOffset, + int attachmentMode) +{ + int n = m_noPoints; + + // First check for situation where the line is vertical, + // and we would want to connect to a point on that vertical -- + // oglFindEndForPolyline can't cope with this (the arrow + // gets drawn to the wrong place). + if ((attachmentMode == ATTACHMENT_MODE_NONE) && (x1 == x2)) + { + // Look for the point we'd be connecting to. This is + // a heuristic... + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = & (m_points[i]); + if (point->x == 0.0) + { + if ((y2 > y1) && (point->y > 0.0)) + { + *x3 = point->x + xOffset; + *y3 = point->y + yOffset; + return TRUE; + } + else if ((y2 < y1) && (point->y < 0.0)) + { + *x3 = point->x + xOffset; + *y3 = point->y + yOffset; + return TRUE; + } + } + } + } + + double *xpoints = new double[n]; + double *ypoints = new double[n]; + + for (int i = 0; i < n; i++) + { + wxRealPoint *point = & (m_points[i]); + xpoints[i] = point->x + xOffset; + ypoints[i] = point->y + yOffset; + } + + oglFindEndForPolyline(n, xpoints, ypoints, + x1, y1, x2, y2, x3, y3); + + delete[] xpoints; + delete[] ypoints; + + return TRUE; +} + + +/* + * Utilities + * + */ + +#if 0 +static char hexArray[] = +{ + wxT('0'), wxT('1'), wxT('2'), wxT('3'), wxT('4'), wxT('5'), wxT('6'), wxT('7'), + wxT('8'), wxT('9'), wxT('A'), wxT('B'), wxT('C'), wxT('D'), wxT('E'), wxT('F') +}; + +// Convert unsigned 16-bit integer to 4-character hex string +static void IntToHex(unsigned int dec, wxChar *buf) +{ + int digit1 = (int)(dec / 4096); + int digit2 = (int)((dec - (digit1 * 4096)) / 256); + int digit3 = (int)((dec - (digit1 * 4096) - (digit2 * 256)) / 16); + int digit4 = dec - (digit1 * 4096 + digit2 * 256 + digit3 * 16); + + buf[0] = hexArray[digit1]; + buf[1] = hexArray[digit2]; + buf[2] = hexArray[digit3]; + buf[3] = hexArray[digit4]; + buf[4] = 0; +} +#endif + +#if 0 +// One hex digit to decimal number +static int HexToInt1(wxChar hex) +{ + switch (hex) + { + case wxT('0'): + return 0; + case wxT('1'): + return 1; + case wxT('2'): + return 2; + case wxT('3'): + return 3; + case wxT('4'): + return 4; + case wxT('5'): + return 5; + case wxT('6'): + return 6; + case wxT('7'): + return 7; + case wxT('8'): + return 8; + case wxT('9'): + return 9; + case wxT('A'): + return 10; + case wxT('B'): + return 11; + case wxT('C'): + return 12; + case wxT('D'): + return 13; + case wxT('E'): + return 14; + case wxT('F'): + return 15; +#if 0 + // handling this default outside switch removes warning under Borland + default: + return 0; +#endif + } + + return 0; +} + +// 4-digit hex string to unsigned integer +static unsigned long HexToInt(wxChar *buf) +{ + long d1 = (long)(HexToInt1(buf[0]) * 4096.0) ; + long d2 = (long)(HexToInt1(buf[1]) * 256.0) ; + long d3 = (long)(HexToInt1(buf[2]) * 16.0) ; + long d4 = (long)(HexToInt1(buf[3])) ; + unsigned long n = (long)(d1 + d2 + d3 + d4) ; + return n; +} +#endif + +/* + * wxPseudo meta-file + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxPseudoMetaFile, wxObject) + +wxPseudoMetaFile::wxPseudoMetaFile() +{ + m_currentRotation = 0; + m_rotateable = TRUE; + m_width = 0.0; + m_height = 0.0; + m_outlinePen = NULL; + m_fillBrush = NULL; + m_outlineOp = -1; +} + +wxPseudoMetaFile::wxPseudoMetaFile(wxPseudoMetaFile &mf) +{ + mf.Copy(*this); +} + +wxPseudoMetaFile::~wxPseudoMetaFile() +{ + Clear(); +} + +void wxPseudoMetaFile::Clear() +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + delete op; + node = node->GetNext(); + } + m_ops.Clear(); + m_gdiObjects.Clear(); + m_outlineColours.Clear(); + m_fillColours.Clear(); + m_outlineOp = -1; +} + +void wxPseudoMetaFile::Draw(wxDC &dc, double xoffset, double yoffset) +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Do(dc, xoffset, yoffset); + node = node->GetNext(); + } +} + +void wxPseudoMetaFile::Scale(double sx, double sy) +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Scale(sx, sy); + node = node->GetNext(); + } + m_width *= sx; + m_height *= sy; +} + +void wxPseudoMetaFile::Translate(double x, double y) +{ + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Translate(x, y); + node = node->GetNext(); + } +} + +void wxPseudoMetaFile::Rotate(double x, double y, double theta) +{ + double theta1 = theta - m_currentRotation; + if (theta1 == 0.0) return; + double cosTheta = (double)cos(theta1); + double sinTheta = (double)sin(theta1); + + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + op->Rotate(x, y, theta, sinTheta, cosTheta); + node = node->GetNext(); + } + m_currentRotation = theta; +} + +#if wxUSE_PROLOGIO +void wxPseudoMetaFile::WriteAttributes(wxExpr *clause, int whichAngle) +{ + wxString widthStr; + widthStr.Printf(wxT("meta_width%d"), whichAngle); + + wxString heightStr; + heightStr.Printf(wxT("meta_height%d"), whichAngle); + + wxString outlineStr; + outlineStr.Printf(wxT("outline_op%d"), whichAngle); + + wxString rotateableStr; + rotateableStr.Printf(wxT("meta_rotateable%d"), whichAngle); + + // Write width and height + clause->AddAttributeValue(widthStr, m_width); + clause->AddAttributeValue(heightStr, m_height); + clause->AddAttributeValue(rotateableStr, (long)m_rotateable); + clause->AddAttributeValue(outlineStr, (long)m_outlineOp); + + // Write GDI objects + wxChar buf[50]; + int i = 1; + wxNode *node = m_gdiObjects.GetFirst(); + while (node) + { + wxSprintf(buf, wxT("gdi%d_%d"), whichAngle, i); + wxObject *obj = (wxObject *)node->GetData(); + wxExpr *expr = NULL; + if (obj) + { + if (obj->IsKindOf(CLASSINFO(wxPen))) + { + wxPen *thePen = (wxPen *)obj; + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)gyTYPE_PEN)); + expr->Append(new wxExpr((long)thePen->GetWidth())); + expr->Append(new wxExpr((long)thePen->GetStyle())); + expr->Append(new wxExpr((long)thePen->GetColour().Red())); + expr->Append(new wxExpr((long)thePen->GetColour().Green())); + expr->Append(new wxExpr((long)thePen->GetColour().Blue())); + } + else if (obj->IsKindOf(CLASSINFO(wxBrush))) + { + wxBrush *theBrush = (wxBrush *)obj; + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)gyTYPE_BRUSH)); + expr->Append(new wxExpr((long)theBrush->GetStyle())); + expr->Append(new wxExpr((long)theBrush->GetColour().Red())); + expr->Append(new wxExpr((long)theBrush->GetColour().Green())); + expr->Append(new wxExpr((long)theBrush->GetColour().Blue())); + } + else if (obj->IsKindOf(CLASSINFO(wxFont))) + { + wxFont *theFont = (wxFont *)obj; + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)gyTYPE_FONT)); + expr->Append(new wxExpr((long)theFont->GetPointSize())); + expr->Append(new wxExpr((long)theFont->GetFamily())); + expr->Append(new wxExpr((long)theFont->GetStyle())); + expr->Append(new wxExpr((long)theFont->GetWeight())); + expr->Append(new wxExpr((long)theFont->GetUnderlined())); + } + } + else + { + // If no recognised GDI object, append a place holder anyway. + expr = new wxExpr(wxExprList); + expr->Append(new wxExpr((long)0)); + } + + if (expr) + { + clause->AddAttributeValue(buf, expr); + i ++; + } + node = node->GetNext(); + } + + // Write drawing operations + i = 1; + node = m_ops.GetFirst(); + while (node) + { + wxSprintf(buf, wxT("op%d_%d"), whichAngle, i); + wxDrawOp *op = (wxDrawOp *)node->GetData(); + wxExpr *expr = op->WriteExpr(this); + if (expr) + { + clause->AddAttributeValue(buf, expr); + i ++; + } + node = node->GetNext(); + } + + // Write outline and fill GDI op lists (if any) + if (m_outlineColours.GetCount() > 0) + { + wxExpr *outlineExpr = new wxExpr(wxExprList); + node = m_outlineColours.GetFirst(); + while (node) + { + outlineExpr->Append(new wxExpr((long)node->GetData())); + node = node->GetNext(); + } + wxString outlineObjectsStr; + outlineObjectsStr.Printf(wxT("outline_objects%d"), whichAngle); + + clause->AddAttributeValue(outlineObjectsStr, outlineExpr); + } + if (m_fillColours.GetCount() > 0) + { + wxExpr *fillExpr = new wxExpr(wxExprList); + node = m_fillColours.GetFirst(); + while (node) + { + fillExpr->Append(new wxExpr((long)node->GetData())); + node = node->GetNext(); + } + wxString fillObjectsStr; + fillObjectsStr.Printf(wxT("fill_objects%d"), whichAngle); + + clause->AddAttributeValue(fillObjectsStr, fillExpr); + } + +} + +void wxPseudoMetaFile::ReadAttributes(wxExpr *clause, int whichAngle) +{ + wxString widthStr; + widthStr.Printf(wxT("meta_width%d"), whichAngle); + + wxString heightStr; + heightStr.Printf(wxT("meta_height%d"), whichAngle); + + wxString outlineStr; + outlineStr.Printf(wxT("outline_op%d"), whichAngle); + + wxString rotateableStr; + rotateableStr.Printf(wxT("meta_rotateable%d"), whichAngle); + + clause->GetAttributeValue(widthStr, m_width); + clause->GetAttributeValue(heightStr, m_height); + clause->GetAttributeValue(outlineStr, m_outlineOp); + + int iVal = (int) m_rotateable; + clause->GetAttributeValue(rotateableStr, iVal); + m_rotateable = (iVal != 0); + + // Read GDI objects + wxChar buf[50]; + int i = 1; + bool keepGoing = TRUE; + while (keepGoing) + { + wxSprintf(buf, wxT("gdi%d_%d"), whichAngle, i); + wxExpr *expr = NULL; + clause->GetAttributeValue(buf, &expr); + if (!expr) + { + keepGoing = FALSE; + } + else + { + wxExpr *idExpr = expr->Nth(0); + switch (idExpr->IntegerValue()) + { + case gyTYPE_PEN: + { + int penWidth = (int)expr->Nth(1)->IntegerValue(); + int penStyle = (int)expr->Nth(2)->IntegerValue(); + int penRed = (int)expr->Nth(3)->IntegerValue(); + int penGreen = (int)expr->Nth(4)->IntegerValue(); + int penBlue = (int)expr->Nth(5)->IntegerValue(); + wxColour col(penRed, penGreen, penBlue); + wxPen *p = wxThePenList->FindOrCreatePen(col, penWidth, penStyle); + if (!p) + p = wxBLACK_PEN; + m_gdiObjects.Append(p); + break; + } + case gyTYPE_BRUSH: + { + int brushStyle = (int)expr->Nth(1)->IntegerValue(); + int brushRed = (int)expr->Nth(2)->IntegerValue(); + int brushGreen = (int)expr->Nth(3)->IntegerValue(); + int brushBlue = (int)expr->Nth(4)->IntegerValue(); + wxColour col(brushRed, brushGreen, brushBlue); + wxBrush *b = wxTheBrushList->FindOrCreateBrush(col, brushStyle); + if (!b) + b = wxWHITE_BRUSH; + m_gdiObjects.Append(b); + break; + } + case gyTYPE_FONT: + { + int fontPointSize = (int)expr->Nth(1)->IntegerValue(); + int fontFamily = (int)expr->Nth(2)->IntegerValue(); + int fontStyle = (int)expr->Nth(3)->IntegerValue(); + int fontWeight = (int)expr->Nth(4)->IntegerValue(); + int fontUnderlined = (int)expr->Nth(5)->IntegerValue(); + m_gdiObjects.Append(wxTheFontList->FindOrCreateFont(fontPointSize, + fontFamily, fontStyle, fontWeight, (fontUnderlined != 0))); + break; + } + default: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + } + i ++; + } + } + + // Now read in the operations + keepGoing = TRUE; + i = 1; + while (keepGoing) + { + wxSprintf(buf, wxT("op%d_%d"), whichAngle, i); + wxExpr *expr = NULL; + clause->GetAttributeValue(buf, &expr); + if (!expr) + { + keepGoing = FALSE; + } + else + { + wxExpr *idExpr = expr->Nth(0); + int opId = (int)idExpr->IntegerValue(); + switch (opId) + { + case DRAWOP_SET_PEN: + case DRAWOP_SET_BRUSH: + case DRAWOP_SET_FONT: + case DRAWOP_SET_TEXT_COLOUR: + case DRAWOP_SET_BK_COLOUR: + case DRAWOP_SET_BK_MODE: + { + wxOpSetGDI *theOp = new wxOpSetGDI(opId, this, 0); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + + case DRAWOP_SET_CLIPPING_RECT: + case DRAWOP_DESTROY_CLIPPING_RECT: + { + wxOpSetClipping *theOp = new wxOpSetClipping(opId, 0.0, 0.0, 0.0, 0.0); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPSE: + case DRAWOP_DRAW_POINT: + case DRAWOP_DRAW_ARC: + case DRAWOP_DRAW_TEXT: + { + wxOpDraw *theOp = new wxOpDraw(opId, 0.0, 0.0, 0.0, 0.0); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + case DRAWOP_DRAW_SPLINE: + case DRAWOP_DRAW_POLYLINE: + case DRAWOP_DRAW_POLYGON: + { + wxOpPolyDraw *theOp = new wxOpPolyDraw(opId, 0, NULL); + theOp->ReadExpr(this, expr); + m_ops.Append(theOp); + break; + } + default: + break; + } + } + i ++; + } + + wxString outlineObjectsStr; + outlineObjectsStr.Printf(wxT("outline_objects%d"), whichAngle); + + // Now read in the list of outline and fill operations, if any + wxExpr *expr1 = clause->AttributeValue(outlineObjectsStr); + if (expr1) + { + wxExpr *eachExpr = expr1->GetFirst(); + while (eachExpr) + { + m_outlineColours.Append((wxObject *)eachExpr->IntegerValue()); + eachExpr = eachExpr->GetNext(); + } + } + + wxString fillObjectsStr; + fillObjectsStr.Printf(wxT("fill_objects%d"), whichAngle); + + expr1 = clause->AttributeValue(fillObjectsStr); + if (expr1) + { + wxExpr *eachExpr = expr1->GetFirst(); + while (eachExpr) + { + m_fillColours.Append((wxObject *)eachExpr->IntegerValue()); + eachExpr = eachExpr->GetNext(); + } + } +} +#endif + +// Does the copying for this object +void wxPseudoMetaFile::Copy(wxPseudoMetaFile ©) +{ + copy.Clear(); + + copy.m_currentRotation = m_currentRotation; + copy.m_width = m_width; + copy.m_height = m_height; + copy.m_rotateable = m_rotateable; + copy.m_fillBrush = m_fillBrush; + copy.m_outlinePen = m_outlinePen; + copy.m_outlineOp = m_outlineOp; + + // Copy the GDI objects + wxNode *node = m_gdiObjects.GetFirst(); + while (node) + { + wxObject *obj = (wxObject *)node->GetData(); + copy.m_gdiObjects.Append(obj); + node = node->GetNext(); + } + + // Copy the operations + node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + copy.m_ops.Append(op->Copy(©)); + node = node->GetNext(); + } + + // Copy the outline/fill operations + node = m_outlineColours.GetFirst(); + while (node) + { + copy.m_outlineColours.Append((wxObject *)node->GetData()); + node = node->GetNext(); + } + node = m_fillColours.GetFirst(); + while (node) + { + copy.m_fillColours.Append((wxObject *)node->GetData()); + node = node->GetNext(); + } +} + +/* + * Pass size of existing image; scale height to + * fit width and return new width and height. + * + */ + +bool wxPseudoMetaFile::LoadFromMetaFile(const wxString &filename, double *rwidth, double *rheight) +{ + if (!wxFileExists(filename)) + return FALSE; + + wxXMetaFile *metaFile = new wxXMetaFile; + + if (!metaFile->ReadFile(filename)) + { + delete metaFile; + return FALSE; + } + + double lastX = 0.0; + double lastY = 0.0; + + // Convert from metafile records to wxDrawnShape records + wxNode *node = metaFile->metaRecords.GetFirst(); + while (node) + { + wxMetaRecord *record = (wxMetaRecord *)node->GetData(); + switch (record->metaFunction) + { + case META_SETBKCOLOR: + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0); + op->m_r = (unsigned char)record->param1; + op->m_g = (unsigned char)record->param2; + op->m_b = (unsigned char)record->param3; + m_ops.Append(op); + break; + } + case META_SETBKMODE: + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, (int)record->param1); + m_ops.Append(op); + break; + } + case META_SETMAPMODE: + { + break; + } +// case META_SETROP2: +// case META_SETRELABS: +// case META_SETPOLYFILLMODE: +// case META_SETSTRETCHBLTMODE: +// case META_SETTEXTCHAREXTRA: + case META_SETTEXTCOLOR: + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0); + op->m_r = (unsigned char)record->param1; + op->m_g = (unsigned char)record->param2; + op->m_b = (unsigned char)record->param3; + m_ops.Append(op); + break; + } +// case META_SETTEXTJUSTIFICATION: +// case META_SETWINDOWORG: +// case META_SETWINDOWEXT: +// case META_SETVIEWPORTORG: +// case META_SETVIEWPORTEXT: +// case META_OFFSETWINDOWORG: +// case META_SCALEWINDOWEXT: +// case META_OFFSETVIEWPORTORG: +// case META_SCALEVIEWPORTEXT: + case META_LINETO: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_LINE, (double)lastX, (double)lastY, + (double)record->param1, (double)record->param2); + m_ops.Append(op); + break; + } + case META_MOVETO: + { + lastX = (double)record->param1; + lastY = (double)record->param2; + break; + } + case META_EXCLUDECLIPRECT: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT); + rec->param4 = getshort(handle); // m_y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + */ + break; + } + case META_INTERSECTCLIPRECT: + { + /* + rec->param4 = getshort(handle); // m_y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + */ + break; + } +// case META_ARC: // DO!!! + case META_ELLIPSE: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ELLIPSE, + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2)); + m_ops.Append(op); + break; + } +// case META_FLOODFILL: +// case META_PIE: // DO!!! + case META_RECTANGLE: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_RECT, + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2)); + m_ops.Append(op); + break; + } + case META_ROUNDRECT: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT, + (double)record->param1, (double)record->param2, + (double)(record->param3 - record->param1), + (double)(record->param4 - record->param2), (double)record->param5); + m_ops.Append(op); + break; + } +// case META_PATBLT: +// case META_SAVEDC: + case META_SETPIXEL: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_POINT, + (double)record->param1, (double)record->param2, + 0.0, 0.0); + +// SHOULD SET THE COLOUR - SET PEN? +// rec->param3 = getint(handle); // COLORREF + m_ops.Append(op); + break; + } +// case META_OFFSETCLIPRGN: + case META_TEXTOUT: + { + wxOpDraw *op = new wxOpDraw(DRAWOP_DRAW_TEXT, + (double)record->param1, (double)record->param2, + 0.0, 0.0, 0.0, record->stringParam); + m_ops.Append(op); + break; + } +// case META_BITBLT: +// case META_STRETCHBLT: + case META_POLYGON: + { + int n = (int)record->param1; + wxRealPoint *newPoints = new wxRealPoint[n]; + for (int i = 0; i < n; i++) + { + newPoints[i].x = record->points[i].x; + newPoints[i].y = record->points[i].y; + } + + wxOpPolyDraw *op = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, newPoints); + m_ops.Append(op); + break; + } + case META_POLYLINE: + { + int n = (int)record->param1; + wxRealPoint *newPoints = new wxRealPoint[n]; + for (int i = 0; i < n; i++) + { + newPoints[i].x = record->points[i].x; + newPoints[i].y = record->points[i].y; + } + + wxOpPolyDraw *op = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, newPoints); + m_ops.Append(op); + break; + } +// case META_ESCAPE: +// case META_RESTOREDC: +// case META_FILLREGION: +// case META_FRAMEREGION: +// case META_INVERTREGION: +// case META_PAINTREGION: +// case META_SELECTCLIPREGION: // DO THIS! + case META_SELECTOBJECT: + { + // The pen, brush etc. has already been created when the metafile + // was read in, so we don't create it - we set it. + wxNode *recNode = metaFile->gdiObjects.Item((int)record->param2); + if (recNode) + { + wxMetaRecord *gdiRec = (wxMetaRecord *)recNode->GetData(); + if (gdiRec && (gdiRec->param1 != 0)) + { + wxObject *obj = (wxObject *)gdiRec->param1; + if (obj->IsKindOf(CLASSINFO(wxPen))) + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_PEN, this, (int)record->param2); + m_ops.Append(op); + } + else if (obj->IsKindOf(CLASSINFO(wxBrush))) + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, (int)record->param2); + m_ops.Append(op); + } + else if (obj->IsKindOf(CLASSINFO(wxFont))) + { + wxOpSetGDI *op = new wxOpSetGDI(DRAWOP_SET_FONT, this, (int)record->param2); + m_ops.Append(op); + } + } + } + break; + } +// case META_SETTEXTALIGN: +// case META_DRAWTEXT: +// case META_CHORD: +// case META_SETMAPPERFLAGS: +// case META_EXTTEXTOUT: +// case META_SETDIBTODEV: +// case META_SELECTPALETTE: +// case META_REALIZEPALETTE: +// case META_ANIMATEPALETTE: +// case META_SETPALENTRIES: +// case META_POLYPOLYGON: +// case META_RESIZEPALETTE: +// case META_DIBBITBLT: +// case META_DIBSTRETCHBLT: + case META_DIBCREATEPATTERNBRUSH: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } +// case META_STRETCHDIB: +// case META_EXTFLOODFILL: +// case META_RESETDC: +// case META_STARTDOC: +// case META_STARTPAGE: +// case META_ENDPAGE: +// case META_ABORTDOC: +// case META_ENDDOC: +// case META_DELETEOBJECT: // DO!! + case META_CREATEPALETTE: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEBRUSH: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEPATTERNBRUSH: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEPENINDIRECT: + { + // The pen is created when the metafile is read in. + // We keep track of all the GDI objects needed for this + // image so when reading the wxDrawnShape from file, + // we can read in all the GDI objects, then refer + // to them by an index starting from zero thereafter. + m_gdiObjects.Append((wxObject *)record->param1); + break; + } + case META_CREATEFONTINDIRECT: + { + m_gdiObjects.Append((wxObject *)record->param1); + break; + } + case META_CREATEBRUSHINDIRECT: + { + // Don't have to do anything here: the pen is created + // when the metafile is read in. + m_gdiObjects.Append((wxObject *)record->param1); + break; + } + case META_CREATEBITMAPINDIRECT: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEBITMAP: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + case META_CREATEREGION: + { + // Place holder + m_gdiObjects.Append(NULL); + break; + } + default: + { + break; + } + } + node = node->GetNext(); + } + double actualWidth = (double)fabs(metaFile->right - metaFile->left); + double actualHeight = (double)fabs(metaFile->bottom - metaFile->top); + + double initialScaleX = 1.0; + double initialScaleY = 1.0; + + double xoffset, yoffset; + + // Translate so origin is at centre of rectangle + if (metaFile->bottom > metaFile->top) + yoffset = - (double)((metaFile->bottom - metaFile->top) / 2.0); + else + yoffset = - (double)((metaFile->top - metaFile->bottom) / 2.0); + + if (metaFile->right > metaFile->left) + xoffset = - (double)((metaFile->right - metaFile->left) / 2.0); + else + xoffset = - (double)((metaFile->left - metaFile->right) / 2.0); + + Translate(xoffset, yoffset); + + // Scale to a reasonable size (take the width of this wxDrawnShape + // as a guide) + if (actualWidth != 0.0) + { + initialScaleX = (double)((*rwidth) / actualWidth); + initialScaleY = initialScaleX; + (*rheight) = initialScaleY * actualHeight; + } + Scale(initialScaleX, initialScaleY); + + m_width = (actualWidth * initialScaleX); + m_height = *rheight; + + delete metaFile; + return TRUE; +} + +// Scale to fit size +void wxPseudoMetaFile::ScaleTo(double w, double h) +{ + double scaleX = (double)(w / m_width); + double scaleY = (double)(h / m_height); + + // Do the scaling + Scale(scaleX, scaleY); +} + +void wxPseudoMetaFile::GetBounds(double *boundMinX, double *boundMinY, double *boundMaxX, double *boundMaxY) +{ + double maxX = (double) - 99999.9; + double maxY = (double) - 99999.9; + double minX = (double) 99999.9; + double minY = (double) 99999.9; + + wxNode *node = m_ops.GetFirst(); + while (node) + { + wxDrawOp *op = (wxDrawOp *)node->GetData(); + switch (op->GetOp()) + { + case DRAWOP_DRAW_LINE: + case DRAWOP_DRAW_RECT: + case DRAWOP_DRAW_ROUNDED_RECT: + case DRAWOP_DRAW_ELLIPSE: + case DRAWOP_DRAW_POINT: + case DRAWOP_DRAW_TEXT: + { + wxOpDraw *opDraw = (wxOpDraw *)op; + if (opDraw->m_x1 < minX) minX = opDraw->m_x1; + if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1; + if (opDraw->m_y1 < minY) minY = opDraw->m_y1; + if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1; + if (op->GetOp() == DRAWOP_DRAW_LINE) + { + if (opDraw->m_x2 < minX) minX = opDraw->m_x2; + if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2; + if (opDraw->m_y2 < minY) minY = opDraw->m_y2; + if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2; + } + else if (op->GetOp() == DRAWOP_DRAW_RECT || + op->GetOp() == DRAWOP_DRAW_ROUNDED_RECT || + op->GetOp() == DRAWOP_DRAW_ELLIPSE) + { + if ((opDraw->m_x1 + opDraw->m_x2) < minX) minX = (opDraw->m_x1 + opDraw->m_x2); + if ((opDraw->m_x1 + opDraw->m_x2) > maxX) maxX = (opDraw->m_x1 + opDraw->m_x2); + if ((opDraw->m_y1 + opDraw->m_y2) < minY) minY = (opDraw->m_y1 + opDraw->m_y2); + if ((opDraw->m_y1 + opDraw->m_y2) > maxY) maxY = (opDraw->m_y1 + opDraw->m_y2); + } + break; + } + case DRAWOP_DRAW_ARC: + { + // TODO: don't yet know how to calculate the bounding box + // for an arc. So pretend it's a line; to get a correct + // bounding box, draw a blank rectangle first, of the correct + // size. + wxOpDraw *opDraw = (wxOpDraw *)op; + if (opDraw->m_x1 < minX) minX = opDraw->m_x1; + if (opDraw->m_x1 > maxX) maxX = opDraw->m_x1; + if (opDraw->m_y1 < minY) minY = opDraw->m_y1; + if (opDraw->m_y1 > maxY) maxY = opDraw->m_y1; + if (opDraw->m_x2 < minX) minX = opDraw->m_x2; + if (opDraw->m_x2 > maxX) maxX = opDraw->m_x2; + if (opDraw->m_y2 < minY) minY = opDraw->m_y2; + if (opDraw->m_y2 > maxY) maxY = opDraw->m_y2; + break; + } + case DRAWOP_DRAW_POLYLINE: + case DRAWOP_DRAW_POLYGON: + case DRAWOP_DRAW_SPLINE: + { + wxOpPolyDraw *poly = (wxOpPolyDraw *)op; + for (int i = 0; i < poly->m_noPoints; i++) + { + if (poly->m_points[i].x < minX) minX = poly->m_points[i].x; + if (poly->m_points[i].x > maxX) maxX = poly->m_points[i].x; + if (poly->m_points[i].y < minY) minY = poly->m_points[i].y; + if (poly->m_points[i].y > maxY) maxY = poly->m_points[i].y; + } + break; + } + default: + break; + } + node = node->GetNext(); + } + + *boundMinX = minX; + *boundMinY = minY; + *boundMaxX = maxX; + *boundMaxY = maxY; + /* + *w = (double)fabs(maxX - minX); + *h = (double)fabs(maxY - minY); + */ +} + +// Calculate size from current operations +void wxPseudoMetaFile::CalculateSize(wxDrawnShape *shape) +{ + double boundMinX, boundMinY, boundMaxX, boundMaxY; + + GetBounds(& boundMinX, & boundMinY, & boundMaxX, & boundMaxY); + + SetSize(boundMaxX - boundMinX, boundMaxY - boundMinY); + + if (shape) + { + shape->SetWidth(m_width); + shape->SetHeight(m_height); + } +} + +// Set of functions for drawing into a pseudo metafile. +// They use integers, but doubles are used internally for accuracy +// when scaling. + +void wxPseudoMetaFile::DrawLine(const wxPoint &pt1, const wxPoint &pt2) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_LINE, + (double) pt1.x, (double) pt1.y, (double) pt2.x, (double) pt2.y); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawRectangle(const wxRect &rect) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawRoundedRectangle(const wxRect &rect, double radius) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ROUNDED_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + theOp->m_radius = radius; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawEllipse(const wxRect &rect) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPSE, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawArc(const wxPoint ¢rePt, const wxPoint &startPt, const wxPoint &endPt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ARC, + (double) centrePt.x, (double) centrePt.y, (double) startPt.x, (double) startPt.y); + + theOp->m_x3 = (double) endPt.x; + theOp->m_y3 = (double) endPt.y; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawEllipticArc(const wxRect &rect, double startAngle, double endAngle) +{ + const double pi = 3.1415926535897932384626433832795 ; + + double startAngleRadians = startAngle * (pi * 2.0 / 360.0); + double endAngleRadians = endAngle * (pi * 2.0 / 360.0); + + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_ELLIPTIC_ARC, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); + + theOp->m_x3 = startAngleRadians; + theOp->m_y3 = endAngleRadians; + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawPoint(const wxPoint &pt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_POINT, + (double) pt.x, (double) pt.y, 0.0, 0.0); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawText(const wxString &text, const wxPoint &pt) +{ + wxOpDraw *theOp = new wxOpDraw(DRAWOP_DRAW_TEXT, + (double) pt.x, (double) pt.y, 0.0, 0.0); + + theOp->m_textString = oglCopystring(text); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawLines(int n, wxPoint pts[]) +{ + wxRealPoint *realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw *theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYLINE, n, realPoints); + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::DrawPolygon(int n, wxPoint pts[], int flags) +{ + wxRealPoint *realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw *theOp = new wxOpPolyDraw(DRAWOP_DRAW_POLYGON, n, realPoints); + m_ops.Append(theOp); + + if (flags & oglMETAFLAGS_OUTLINE) + m_outlineOp = (m_ops.GetCount() - 1); +} + +void wxPseudoMetaFile::DrawSpline(int n, wxPoint pts[]) +{ + wxRealPoint *realPoints = new wxRealPoint[n]; + int i; + for (i = 0; i < n; i++) + { + realPoints[i].x = pts[i].x; + realPoints[i].y = pts[i].y; + } + wxOpPolyDraw *theOp = new wxOpPolyDraw(DRAWOP_DRAW_SPLINE, n, realPoints); + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetClippingRect(const wxRect &rect) +{ + /* wxOpSetClipping* theOp = */ new wxOpSetClipping(DRAWOP_SET_CLIPPING_RECT, + (double) rect.x, (double) rect.y, (double) rect.width, (double) rect.height); +} + +void wxPseudoMetaFile::DestroyClippingRect() +{ + wxOpSetClipping *theOp = new wxOpSetClipping(DRAWOP_DESTROY_CLIPPING_RECT, + 0.0, 0.0, 0.0, 0.0); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetPen(wxPen *pen, bool isOutline) +{ + m_gdiObjects.Append(pen); + int n = m_gdiObjects.GetCount(); + + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_PEN, this, n - 1); + + m_ops.Append(theOp); + + if (isOutline) + { + m_outlineColours.Append((wxObject *) (n - 1)); + } +} + +void wxPseudoMetaFile::SetBrush(wxBrush *brush, bool isFill) +{ + m_gdiObjects.Append(brush); + int n = m_gdiObjects.GetCount(); + + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_BRUSH, this, n - 1); + + m_ops.Append(theOp); + + if (isFill) + { + m_fillColours.Append((wxObject *) (n - 1)); + } +} + +void wxPseudoMetaFile::SetFont(wxFont *font) +{ + m_gdiObjects.Append(font); + int n = m_gdiObjects.GetCount(); + + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_FONT, this, n - 1); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetTextColour(const wxColour &colour) +{ + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_TEXT_COLOUR, this, 0); + theOp->m_r = colour.Red(); + theOp->m_g = colour.Green(); + theOp->m_b = colour.Blue(); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetBackgroundColour(const wxColour &colour) +{ + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_BK_COLOUR, this, 0); + theOp->m_r = colour.Red(); + theOp->m_g = colour.Green(); + theOp->m_b = colour.Blue(); + + m_ops.Append(theOp); +} + +void wxPseudoMetaFile::SetBackgroundMode(int mode) +{ + wxOpSetGDI *theOp = new wxOpSetGDI(DRAWOP_SET_BK_MODE, this, 0, mode); + + m_ops.Append(theOp); +} + diff --git a/ogl/lines.cpp b/ogl/lines.cpp new file mode 100644 index 0000000..a13a0c6 --- /dev/null +++ b/ogl/lines.cpp @@ -0,0 +1,2498 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// lines.cpp - wxLineShape +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include + +#include "ogl/ogl.h" + + +// Line shape +IMPLEMENT_DYNAMIC_CLASS(wxLineShape, wxShape) + +wxLineShape::wxLineShape() +{ + m_sensitivity = OP_CLICK_LEFT | OP_CLICK_RIGHT; + m_draggable = FALSE; + m_attachmentTo = 0; + m_attachmentFrom = 0; + /* + m_actualTextWidth = 0.0; + m_actualTextHeight = 0.0; + */ + m_from = NULL; + m_to = NULL; + m_erasing = FALSE; + m_arrowSpacing = 5.0; // For the moment, don't bother saving this to file. + m_ignoreArrowOffsets = FALSE; + m_isSpline = FALSE; + m_maintainStraightLines = FALSE; + m_alignmentStart = 0; + m_alignmentEnd = 0; + + m_lineControlPoints = NULL; + + // Clear any existing regions (created in an earlier constructor) + // and make the three line regions. + ClearRegions(); + wxShapeRegion *newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Middle")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Start")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("End")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + for (int i = 0; i < 3; i++) + m_labelObjects[i] = NULL; +} + +wxLineShape::~wxLineShape() +{ + if (m_lineControlPoints) + { + ClearPointList(*m_lineControlPoints); + delete m_lineControlPoints; + } + ClearArrowsAtPosition(-1); + + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + if (m_labelObjects[i]->Selected() && m_canvas) + m_labelObjects[i]->Select(FALSE); + if (m_canvas) + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + delete m_labelObjects[i]; + m_labelObjects[i] = NULL; + } + } +} + +// Remove any child shapes before deleting shape. +void wxLineShape::RemoveChildren() +{ + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + if (m_labelObjects[i]->Selected() && m_canvas) + m_labelObjects[i]->Select(FALSE); + if (m_canvas) + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + } + } +} + +void wxLineShape::SetCanvas(wxShapeCanvas *the_canvas) +{ + wxShape::SetCanvas(the_canvas); + + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + m_labelObjects[i]->SetCanvas(the_canvas); + } + } +} + +void wxLineShape::MakeLineControlPoints(int n) +{ + if (m_lineControlPoints) + { + ClearPointList(*m_lineControlPoints); + delete m_lineControlPoints; + } + m_lineControlPoints = new wxList; + + for (int i = 0; i < n; i++) + { + wxRealPoint *point = new wxRealPoint(-999, -999); + m_lineControlPoints->Append((wxObject *) point); + } +} + +wxNode *wxLineShape::InsertLineControlPoint() +{ + Refresh(); + + wxNode *last = m_lineControlPoints->GetLast(); + wxNode *second_last = last->GetPrevious(); + wxRealPoint *last_point = (wxRealPoint *)last->GetData(); + wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData(); + + // Choose a point half way between the last and penultimate points + double line_x = ((last_point->x + second_last_point->x) / 2); + double line_y = ((last_point->y + second_last_point->y) / 2); + + wxRealPoint *point = new wxRealPoint(line_x, line_y); + wxNode *node = m_lineControlPoints->Insert(last, (wxObject *) point); + + Refresh(); + + return node; +} + +bool wxLineShape::DeleteLineControlPoint() +{ + if (m_lineControlPoints->GetCount() < 3) + return FALSE; + + wxNode *last = m_lineControlPoints->GetLast(); + wxNode *second_last = last->GetPrevious(); + + wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData(); + delete second_last_point; + delete second_last; + + return TRUE; +} + +void wxLineShape::Initialise() +{ + if (m_lineControlPoints) + { + // Just move the first and last control points + wxNode *first = m_lineControlPoints->GetFirst(); + wxRealPoint *first_point = (wxRealPoint *)first->GetData(); + + wxNode *last = m_lineControlPoints->GetLast(); + wxRealPoint *last_point = (wxRealPoint *)last->GetData(); + + // If any of the line points are at -999, we must + // initialize them by placing them half way between the first + // and the last. + wxNode *node = first->GetNext(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + if (point->x == -999) + { + double x1, y1, x2, y2; + if (first_point->x < last_point->x) + { + x1 = first_point->x; + x2 = last_point->x; + } + else + { + x2 = first_point->x; + x1 = last_point->x; + } + + if (first_point->y < last_point->y) + { + y1 = first_point->y; + y2 = last_point->y; + } + else + { + y2 = first_point->y; + y1 = last_point->y; + } + + point->x = ((x2 - x1) / 2 + x1); + point->y = ((y2 - y1) / 2 + y1); + } + node = node->GetNext(); + } + } +} + +// Format a text string according to the region size, adding +// strings with positions to region text list +void wxLineShape::FormatText(wxDC &dc, const wxString &s, int i) +{ + double w, h; + ClearText(i); + + if (m_regions.GetCount() < 1) + return; + wxNode *node = m_regions.Item(i); + if (!node) + return; + + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->SetText(s); + dc.SetFont(* region->GetFont()); + + region->GetSize(&w, &h); + // Initialize the size if zero + if (((w == 0) || (h == 0)) && (s.Length() > 0)) + { + w = 100; + h = 50; + region->SetSize(w, h); + } + + wxArrayString *string_list = oglFormatText(dc, s, (w - 5), (h - 5), region->GetFormatMode()); + size_t j; + for (j = 0; j < string_list->GetCount(); j++) + { + const wxString &s = (*string_list)[j]; + wxShapeTextLine *line = new wxShapeTextLine(0.0, 0.0, s); + region->GetFormattedText().Append((wxObject *)line); + } + delete string_list; + double actualW = w; + double actualH = h; + if (region->GetFormatMode() & FORMAT_SIZE_TO_CONTENTS) + { + oglGetCentredTextExtent(dc, &(region->GetFormattedText()), m_xpos, m_ypos, w, h, &actualW, &actualH); + if ((actualW != w ) || (actualH != h)) + { + double xx, yy; + GetLabelPosition(i, &xx, &yy); + if (m_labelObjects[i]) + { + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->SetSize(actualW, actualH); + } + + region->SetSize(actualW, actualH); + + if (m_labelObjects[i]) + { + m_labelObjects[i]->Select(TRUE); + m_labelObjects[i]->Draw(dc); + } + } + } + oglCentreText(dc, &(region->GetFormattedText()), m_xpos, m_ypos, actualW, actualH, region->GetFormatMode()); + m_formatted = TRUE; +} + +void wxLineShape::DrawRegion(wxDC &dc, wxShapeRegion *region, double x, double y) +{ + if (GetDisableLabel()) + return; + + double w, h; + double xx, yy; + region->GetSize(&w, &h); + + // Get offset from x, y + region->GetPosition(&xx, &yy); + + double xp = xx + x; + double yp = yy + y; + + // First, clear a rectangle for the text IF there is any + if (region->GetFormattedText().GetCount() > 0) + { + dc.SetPen(GetBackgroundPen()); + dc.SetBrush(GetBackgroundBrush()); + + // Now draw the text + if (region->GetFont()) dc.SetFont(* region->GetFont()); + + dc.DrawRectangle((long)(xp - w / 2.0), (long)(yp - h / 2.0), (long)w, (long)h); + + if (m_pen) dc.SetPen(* m_pen); + dc.SetTextForeground(region->GetActualColourObject()); + +#ifdef __WXMSW__ + dc.SetTextBackground(GetBackgroundBrush().GetColour()); +#endif + + oglDrawFormattedText(dc, &(region->GetFormattedText()), xp, yp, w, h, region->GetFormatMode()); + } +} + +// Get the reference point for a label. Region x and y +// are offsets from this. +// position is 0, 1, 2 +void wxLineShape::GetLabelPosition(int position, double *x, double *y) +{ + switch (position) + { + case 0: + { + // Want to take the middle section for the label + int n = m_lineControlPoints->GetCount(); + int half_way = (int)(n / 2); + + // Find middle of this line + wxNode *node = m_lineControlPoints->Item(half_way - 1); + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxNode *next_node = node->GetNext(); + wxRealPoint *next_point = (wxRealPoint *)next_node->GetData(); + + double dx = (next_point->x - point->x); + double dy = (next_point->y - point->y); + *x = (double)(point->x + dx / 2.0); + *y = (double)(point->y + dy / 2.0); + break; + } + case 1: + { + wxNode *node = m_lineControlPoints->GetFirst(); + *x = ((wxRealPoint *)node->GetData())->x; + *y = ((wxRealPoint *)node->GetData())->y; + break; + } + case 2: + { + wxNode *node = m_lineControlPoints->GetLast(); + *x = ((wxRealPoint *)node->GetData())->x; + *y = ((wxRealPoint *)node->GetData())->y; + break; + } + default: + break; + } +} + +/* + * Find whether line is supposed to be vertical or horizontal and + * make it so. + * + */ +void GraphicsStraightenLine(wxRealPoint *point1, wxRealPoint *point2) +{ + double dx = point2->x - point1->x; + double dy = point2->y - point1->y; + + if (dx == 0.0) + return; + else if (fabs(dy / dx) > 1.0) + { + point2->x = point1->x; + } + else point2->y = point1->y; +} + +void wxLineShape::Straighten() +{ + if (!m_lineControlPoints || m_lineControlPoints->GetCount() < 3) + return; + + Refresh(); + + wxNode *first_point_node = m_lineControlPoints->GetFirst(); + wxNode *last_point_node = m_lineControlPoints->GetLast(); + wxNode *second_last_point_node = last_point_node->GetPrevious(); + + wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData(); + wxRealPoint *second_last_point = (wxRealPoint *)second_last_point_node->GetData(); + + GraphicsStraightenLine(last_point, second_last_point); + + wxNode *node = first_point_node; + while (node && (node != second_last_point_node)) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *next_point = (wxRealPoint *)(node->GetNext()->GetData()); + + GraphicsStraightenLine(point, next_point); + node = node->GetNext(); + } + + Refresh(); +} + + +void wxLineShape::Unlink() +{ + if (m_to) + m_to->GetLines().DeleteObject(this); + if (m_from) + m_from->GetLines().DeleteObject(this); + m_to = NULL; + m_from = NULL; +} + +void wxLineShape::SetEnds(double x1, double y1, double x2, double y2) +{ + // Find centre point + wxNode *first_point_node = m_lineControlPoints->GetFirst(); + wxNode *last_point_node = m_lineControlPoints->GetLast(); + wxRealPoint *first_point = (wxRealPoint *)first_point_node->GetData(); + wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData(); + + first_point->x = x1; + first_point->y = y1; + last_point->x = x2; + last_point->y = y2; + + m_xpos = (double)((x1 + x2) / 2.0); + m_ypos = (double)((y1 + y2) / 2.0); +} + +// Get absolute positions of ends +void wxLineShape::GetEnds(double *x1, double *y1, double *x2, double *y2) +{ + wxNode *first_point_node = m_lineControlPoints->GetFirst(); + wxNode *last_point_node = m_lineControlPoints->GetLast(); + wxRealPoint *first_point = (wxRealPoint *)first_point_node->GetData(); + wxRealPoint *last_point = (wxRealPoint *)last_point_node->GetData(); + + *x1 = first_point->x; + *y1 = first_point->y; + *x2 = last_point->x; + *y2 = last_point->y; +} + +void wxLineShape::SetAttachments(int from_attach, int to_attach) +{ + m_attachmentFrom = from_attach; + m_attachmentTo = to_attach; +} + +bool wxLineShape::HitTest(double x, double y, int *attachment, double *distance) +{ + if (!m_lineControlPoints) + return FALSE; + + // Look at label regions in case mouse is over a label + bool inLabelRegion = FALSE; + for (int i = 0; i < 3; i ++) + { + wxNode *regionNode = m_regions.Item(i); + if (regionNode) + { + wxShapeRegion *region = (wxShapeRegion *)regionNode->GetData(); + if (region->m_formattedText.GetCount() > 0) + { + double xp, yp, cx, cy, cw, ch; + GetLabelPosition(i, &xp, &yp); + // Offset region from default label position + region->GetPosition(&cx, &cy); + region->GetSize(&cw, &ch); + cx += xp; + cy += yp; + double rLeft = (double)(cx - (cw / 2.0)); + double rTop = (double)(cy - (ch / 2.0)); + double rRight = (double)(cx + (cw / 2.0)); + double rBottom = (double)(cy + (ch / 2.0)); + if (x > rLeft && x < rRight && y > rTop && y < rBottom) + { + inLabelRegion = TRUE; + i = 3; + } + } + } + } + + wxNode *node = m_lineControlPoints->GetFirst(); + + while (node && node->GetNext()) + { + wxRealPoint *point1 = (wxRealPoint *)node->GetData(); + wxRealPoint *point2 = (wxRealPoint *)node->GetNext()->GetData(); + + // For inaccurate mousing allow 8 pixel corridor + int extra = 4; + + double dx = point2->x - point1->x; + double dy = point2->y - point1->y; + double seg_len = sqrt(dx * dx + dy * dy); + double distance_from_seg = + seg_len * ((x - point1->x) * dy - (y - point1->y) * dx) / (dy * dy + dx * dx); + double distance_from_prev = + seg_len * ((y - point1->y) * dy + (x - point1->x) * dx) / (dy * dy + dx * dx); + + if ((fabs(distance_from_seg) < extra && + distance_from_prev >= 0 && distance_from_prev <= seg_len) + || inLabelRegion) + { + *attachment = 0; + *distance = distance_from_seg; + return TRUE; + } + + node = node->GetNext(); + } + return FALSE; +} + +void wxLineShape::DrawArrows(wxDC &dc) +{ + // Distance along line of each arrow: space them out evenly. + double startArrowPos = 0.0; + double endArrowPos = 0.0; + double middleArrowPos = 0.0; + + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + switch (arrow->GetArrowEnd()) + { + case ARROW_POSITION_START: + { + if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets) + // If specified, x offset is proportional to line length + DrawArrow(dc, arrow, arrow->GetXOffset(), TRUE); + else + { + DrawArrow(dc, arrow, startArrowPos, FALSE); // Absolute distance + startArrowPos += arrow->GetSize() + arrow->GetSpacing(); + } + break; + } + case ARROW_POSITION_END: + { + if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets) + DrawArrow(dc, arrow, arrow->GetXOffset(), TRUE); + else + { + DrawArrow(dc, arrow, endArrowPos, FALSE); + endArrowPos += arrow->GetSize() + arrow->GetSpacing(); + } + break; + } + case ARROW_POSITION_MIDDLE: + { + arrow->SetXOffset(middleArrowPos); + if ((arrow->GetXOffset() != 0.0) && !m_ignoreArrowOffsets) + DrawArrow(dc, arrow, arrow->GetXOffset(), TRUE); + else + { + DrawArrow(dc, arrow, middleArrowPos, FALSE); + middleArrowPos += arrow->GetSize() + arrow->GetSpacing(); + } + break; + } + } + node = node->GetNext(); + } +} + +void wxLineShape::DrawArrow(wxDC &dc, wxArrowHead *arrow, double xOffset, bool proportionalOffset) +{ + wxNode *first_line_node = m_lineControlPoints->GetFirst(); + wxRealPoint *first_line_point = (wxRealPoint *)first_line_node->GetData(); + wxNode *second_line_node = first_line_node->GetNext(); + wxRealPoint *second_line_point = (wxRealPoint *)second_line_node->GetData(); + + wxNode *last_line_node = m_lineControlPoints->GetLast(); + wxRealPoint *last_line_point = (wxRealPoint *)last_line_node->GetData(); + wxNode *second_last_line_node = last_line_node->GetPrevious(); + wxRealPoint *second_last_line_point = (wxRealPoint *)second_last_line_node->GetData(); + + // Position where we want to start drawing + double positionOnLineX, positionOnLineY; + + // Position of start point of line, at the end of which we draw the arrow. + double startPositionX = 0.0 , startPositionY = 0.0; + + switch (arrow->GetPosition()) + { + case ARROW_POSITION_START: + { + // If we're using a proportional offset, calculate just where this will + // be on the line. + double realOffset = xOffset; + if (proportionalOffset) + { + double totalLength = + (double)sqrt((second_line_point->x - first_line_point->x) * (second_line_point->x - first_line_point->x) + + (second_line_point->y - first_line_point->y) * (second_line_point->y - first_line_point->y)); + realOffset = (double)(xOffset * totalLength); + } + GetPointOnLine(second_line_point->x, second_line_point->y, + first_line_point->x, first_line_point->y, + realOffset, &positionOnLineX, &positionOnLineY); + startPositionX = second_line_point->x; + startPositionY = second_line_point->y; + break; + } + case ARROW_POSITION_END: + { + // If we're using a proportional offset, calculate just where this will + // be on the line. + double realOffset = xOffset; + if (proportionalOffset) + { + double totalLength = + (double)sqrt((second_last_line_point->x - last_line_point->x) * (second_last_line_point->x - last_line_point->x) + + (second_last_line_point->y - last_line_point->y) * (second_last_line_point->y - last_line_point->y)); + realOffset = (double)(xOffset * totalLength); + } + GetPointOnLine(second_last_line_point->x, second_last_line_point->y, + last_line_point->x, last_line_point->y, + realOffset, &positionOnLineX, &positionOnLineY); + startPositionX = second_last_line_point->x; + startPositionY = second_last_line_point->y; + break; + } + case ARROW_POSITION_MIDDLE: + { + // Choose a point half way between the last and penultimate points + double x = ((last_line_point->x + second_last_line_point->x) / 2); + double y = ((last_line_point->y + second_last_line_point->y) / 2); + + // If we're using a proportional offset, calculate just where this will + // be on the line. + double realOffset = xOffset; + if (proportionalOffset) + { + double totalLength = + (double)sqrt((second_last_line_point->x - x) * (second_last_line_point->x - x) + + (second_last_line_point->y - y) * (second_last_line_point->y - y)); + realOffset = (double)(xOffset * totalLength); + } + + GetPointOnLine(second_last_line_point->x, second_last_line_point->y, + x, y, realOffset, &positionOnLineX, &positionOnLineY); + startPositionX = second_last_line_point->x; + startPositionY = second_last_line_point->y; + break; + } + } + + /* + * Add yOffset to arrow, if any + */ + + const double myPi = (double) 3.14159265; + // The translation that the y offset may give + double deltaX = 0.0; + double deltaY = 0.0; + if ((arrow->GetYOffset() != 0.0) && !m_ignoreArrowOffsets) + { + /* + |(x4, y4) + |d + | + (x1, y1)--------------(x3, y3)------------------(x2, y2) + x4 = x3 - d * sin(theta) + y4 = y3 + d * cos(theta) + + Where theta = tan(-1) of (y3-y1)/(x3-x1) + */ + double x1 = startPositionX; + double y1 = startPositionY; + double x3 = positionOnLineX; + double y3 = positionOnLineY; + double d = -arrow->GetYOffset(); // Negate so +offset is above line + + double theta; + if (x3 == x1) + theta = (double)(myPi / 2.0); + else + theta = (double)atan((y3 - y1) / (x3 - x1)); + + double x4 = (double)(x3 - (d * sin(theta))); + double y4 = (double)(y3 + (d * cos(theta))); + + deltaX = x4 - positionOnLineX; + deltaY = y4 - positionOnLineY; + } + + switch (arrow->_GetType()) + { + case ARROW_ARROW: + { + double arrowLength = arrow->GetSize(); + double arrowWidth = (double)(arrowLength / 3.0); + + double tip_x, tip_y, side1_x, side1_y, side2_x, side2_y; + oglGetArrowPoints(startPositionX + deltaX, startPositionY + deltaY, + positionOnLineX + deltaX, positionOnLineY + deltaY, + arrowLength, arrowWidth, &tip_x, &tip_y, + &side1_x, &side1_y, &side2_x, &side2_y); + + wxPoint points[4]; + points[0].x = (int) tip_x; + points[0].y = (int) tip_y; + points[1].x = (int) side1_x; + points[1].y = (int) side1_y; + points[2].x = (int) side2_x; + points[2].y = (int) side2_y; + points[3].x = (int) tip_x; + points[3].y = (int) tip_y; + + dc.SetPen(* m_pen); + dc.SetBrush(* m_brush); + dc.DrawPolygon(4, points); + break; + } + case ARROW_HOLLOW_CIRCLE: + case ARROW_FILLED_CIRCLE: + { + // Find point on line of centre of circle, which is a radius away + // from the end position + double diameter = (double)(arrow->GetSize()); + double x, y; + GetPointOnLine(startPositionX + deltaX, startPositionY + deltaY, + positionOnLineX + deltaX, positionOnLineY + deltaY, + (double)(diameter / 2.0), + &x, &y); + + // Convert ellipse centre to top-left coordinates + double x1 = (double)(x - (diameter / 2.0)); + double y1 = (double)(y - (diameter / 2.0)); + + dc.SetPen(* m_pen); + if (arrow->_GetType() == ARROW_HOLLOW_CIRCLE) + dc.SetBrush(GetBackgroundBrush()); + else + dc.SetBrush(* m_brush); + + dc.DrawEllipse((long) x1, (long) y1, (long) diameter, (long) diameter); + break; + } + case ARROW_SINGLE_OBLIQUE: + { + break; + } + case ARROW_METAFILE: + { + if (arrow->GetMetaFile()) + { + // Find point on line of centre of object, which is a half-width away + // from the end position + /* + * width + * <-- start pos <-----><-- positionOnLineX + * _____ + * --------------| x | <-- e.g. rectangular arrowhead + * ----- + */ + double x, y; + GetPointOnLine(startPositionX, startPositionY, + positionOnLineX, positionOnLineY, + (double)(arrow->GetMetaFile()->m_width / 2.0), + &x, &y); + + // Calculate theta for rotating the metafile. + /* + | + | o(x2, y2) 'o' represents the arrowhead. + | / + | / + | /theta + | /(x1, y1) + |______________________ + */ + double theta = 0.0; + double x1 = startPositionX; + double y1 = startPositionY; + double x2 = positionOnLineX; + double y2 = positionOnLineY; + + if ((x1 == x2) && (y1 == y2)) + theta = 0.0; + + else if ((x1 == x2) && (y1 > y2)) + theta = (double)(3.0 * myPi / 2.0); + + else if ((x1 == x2) && (y2 > y1)) + theta = (double)(myPi / 2.0); + + else if ((x2 > x1) && (y2 >= y1)) + theta = (double)atan((y2 - y1) / (x2 - x1)); + + else if (x2 < x1) + theta = (double)(myPi + atan((y2 - y1) / (x2 - x1))); + + else if ((x2 > x1) && (y2 < y1)) + theta = (double)(2 * myPi + atan((y2 - y1) / (x2 - x1))); + + else + { + wxLogFatalError(wxT("Unknown arrowhead rotation case in lines.cc")); + } + + // Rotate about the centre of the object, then place + // the object on the line. + if (arrow->GetMetaFile()->GetRotateable()) + arrow->GetMetaFile()->Rotate(0.0, 0.0, theta); + + if (m_erasing) + { + // If erasing, just draw a rectangle. + double minX, minY, maxX, maxY; + arrow->GetMetaFile()->GetBounds(&minX, &minY, &maxX, &maxY); + // Make erasing rectangle slightly bigger or you get droppings. + int extraPixels = 4; + dc.DrawRectangle((long)(deltaX + x + minX - (extraPixels / 2.0)), (long)(deltaY + y + minY - (extraPixels / 2.0)), + (long)(maxX - minX + extraPixels), (long)(maxY - minY + extraPixels)); + } + else + arrow->GetMetaFile()->Draw(dc, x + deltaX, y + deltaY); + } + break; + } + default: + { + } + } +} + +void wxLineShape::GetBoundingBoxMin(double *w, double *h) +{ + double x1 = 10000; + double y1 = 10000; + double x2 = -10000; + double y2 = -10000; + + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + + if (point->x < x1) x1 = point->x; + if (point->y < y1) y1 = point->y; + if (point->x > x2) x2 = point->x; + if (point->y > y2) y2 = point->y; + + node = node->GetNext(); + } + *w = (double)(x2 - x1); + *h = (double)(y2 - y1); +} + +/* + * For a node image of interest, finds the position of this arc + * amongst all the arcs which are attached to THIS SIDE of the node image, + * and the number of same. + */ +void wxLineShape::FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming) +{ + int n = -1; + int num = 0; + wxNode *node = image->GetLines().GetFirst(); + int this_attachment; + if (image == m_to) + this_attachment = m_attachmentTo; + else + this_attachment = m_attachmentFrom; + + // Find number of lines going into/out of this particular attachment point + while (node) + { + wxLineShape *line = (wxLineShape *)node->GetData(); + + if (line->m_from == image) + { + // This is the nth line attached to 'image' + if ((line == this) && !incoming) + n = num; + + // Increment num count if this is the same side (attachment number) + if (line->m_attachmentFrom == this_attachment) + num ++; + } + + if (line->m_to == image) + { + // This is the nth line attached to 'image' + if ((line == this) && incoming) + n = num; + + // Increment num count if this is the same side (attachment number) + if (line->m_attachmentTo == this_attachment) + num ++; + } + + node = node->GetNext(); + } + *nth = n; + *no_arcs = num; +} + +void wxLineShape::OnDrawOutline(wxDC &dc, double WXUNUSED(x), double WXUNUSED(y), double WXUNUSED(w), double WXUNUSED(h)) +{ + wxPen *old_pen = m_pen; + wxBrush *old_brush = m_brush; + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + SetPen(& dottedPen); + SetBrush( (wxBrush *) wxTRANSPARENT_BRUSH ); + + GetEventHandler()->OnDraw(dc); + + if (old_pen) SetPen(old_pen); + else SetPen(NULL); + if (old_brush) SetBrush(old_brush); + else SetBrush(NULL); +} + +bool wxLineShape::OnMovePre(double x, double y, double old_x, double old_y, bool WXUNUSED(display)) +{ + double x_offset = x - old_x; + double y_offset = y - old_y; + + if (m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0)) + { + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + point->x += x_offset; + point->y += y_offset; + node = node->GetNext(); + } + + } + + // Move temporary label rectangles if necessary + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i] && m_labelObjects[i]->Selected()) + { + double xp, yp, xr, yr; + GetLabelPosition(i, &xp, &yp); + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + region->GetPosition(&xr, &yr); + } + else + { + xr = 0.0; + yr = 0.0; + } + + m_labelObjects[i]->Move(xp + xr, yp + yr); + } + } + return TRUE; +} + +void wxLineShape::OnMoveLink(bool moveControlPoints) +{ + if (!m_from || !m_to) + return; + + if (m_lineControlPoints->GetCount() > 2) + Initialise(); + + // Do each end - nothing in the middle. User has to move other points + // manually if necessary. + double end_x, end_y; + double other_end_x, other_end_y; + + FindLineEndPoints(&end_x, &end_y, &other_end_x, &other_end_y); + + wxNode *first = m_lineControlPoints->GetFirst(); + wxNode *last = m_lineControlPoints->GetLast(); + + /* This is redundant, surely? Done by SetEnds. + first_point->x = end_x; first_point->y = end_y; + last_point->x = other_end_x; last_point->y = other_end_y; + */ + + double oldX = m_xpos; + double oldY = m_ypos; + + SetEnds(end_x, end_y, other_end_x, other_end_y); + + // Do a second time, because one may depend on the other. + FindLineEndPoints(&end_x, &end_y, &other_end_x, &other_end_y); + SetEnds(end_x, end_y, other_end_x, other_end_y); + + // Try to move control points with the arc + double x_offset = m_xpos - oldX; + double y_offset = m_ypos - oldY; + +// if (moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0)) + // Only move control points if it's a self link. And only works if attachment mode is ON. + if ((m_from == m_to) && (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) && moveControlPoints && m_lineControlPoints && !(x_offset == 0.0 && y_offset == 0.0)) + { + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + if ((node != m_lineControlPoints->GetFirst()) && (node != m_lineControlPoints->GetLast())) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + point->x += x_offset; + point->y += y_offset; + } + node = node->GetNext(); + } + } + + Move(m_xpos, m_ypos); +} + +// Finds the x, y points at the two ends of the line. +// This function can be used by e.g. line-routing routines to +// get the actual points on the two node images where the lines will be drawn +// to/from. +void wxLineShape::FindLineEndPoints(double *fromX, double *fromY, double *toX, double *toY) +{ + if (!m_from || !m_to) + return; + + // Do each end - nothing in the middle. User has to move other points + // manually if necessary. + double end_x, end_y; + double other_end_x, other_end_y; + + wxNode *first = m_lineControlPoints->GetFirst(); + wxNode *last = m_lineControlPoints->GetLast(); + + wxNode *second = first->GetNext(); + wxRealPoint *second_point = (wxRealPoint *)second->GetData(); + + wxNode *second_last = last->GetPrevious(); + wxRealPoint *second_last_point = (wxRealPoint *)second_last->GetData(); + + if (m_lineControlPoints->GetCount() > 2) + { + if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_from, &nth, &no_arcs, FALSE); // Not incoming + m_from->GetAttachmentPosition(m_attachmentFrom, &end_x, &end_y, nth, no_arcs, this); + } + else + (void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(), + (double)second_point->x, (double)second_point->y, + &end_x, &end_y); + + if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_to, &nth, &no_arcs, TRUE); // Incoming + m_to->GetAttachmentPosition(m_attachmentTo, &other_end_x, &other_end_y, nth, no_arcs, this); + } + else + (void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(), + (double)second_last_point->x, (double)second_last_point->y, + &other_end_x, &other_end_y); + } + else + { + double fromX = m_from->GetX(); + double fromY = m_from->GetY(); + double toX = m_to->GetX(); + double toY = m_to->GetY(); + + if (m_from->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_from, &nth, &no_arcs, FALSE); + m_from->GetAttachmentPosition(m_attachmentFrom, &end_x, &end_y, nth, no_arcs, this); + fromX = end_x; + fromY = end_y; + } + + if (m_to->GetAttachmentMode() != ATTACHMENT_MODE_NONE) + { + int nth, no_arcs; + FindNth(m_to, &nth, &no_arcs, TRUE); + m_to->GetAttachmentPosition(m_attachmentTo, &other_end_x, &other_end_y, nth, no_arcs, this); + toX = other_end_x; + toY = other_end_y; + } + + if (m_from->GetAttachmentMode() == ATTACHMENT_MODE_NONE) + (void) m_from->GetPerimeterPoint(m_from->GetX(), m_from->GetY(), + toX, toY, + &end_x, &end_y); + + if (m_to->GetAttachmentMode() == ATTACHMENT_MODE_NONE) + (void) m_to->GetPerimeterPoint(m_to->GetX(), m_to->GetY(), + fromX, fromY, + &other_end_x, &other_end_y); + } + *fromX = end_x; + *fromY = end_y; + *toX = other_end_x; + *toY = other_end_y; +} + +void wxLineShape::OnDraw(wxDC &dc) +{ + if (m_lineControlPoints) + { + if (m_pen) + dc.SetPen(* m_pen); + if (m_brush) + dc.SetBrush(* m_brush); + + int n = m_lineControlPoints->GetCount(); + wxPoint *points = new wxPoint[n]; + int i; + for (i = 0; i < n; i++) + { + wxRealPoint *point = (wxRealPoint *) m_lineControlPoints->Item(i)->GetData(); + points[i].x = WXROUND(point->x); + points[i].y = WXROUND(point->y); + } + + if (m_isSpline) + dc.DrawSpline(n, points); + else + dc.DrawLines(n, points); + +#ifdef __WXMSW__ + // For some reason, last point isn't drawn under Windows. + dc.DrawPoint(points[n - 1]); +#endif + + delete[] points; + + + // Problem with pen - if not a solid pen, does strange things + // to the arrowhead. So make (get) a new pen that's solid. + if (m_pen && (m_pen->GetStyle() != wxSOLID)) + { + wxPen *solid_pen = + wxThePenList->FindOrCreatePen(m_pen->GetColour(), 1, wxSOLID); + if (solid_pen) + dc.SetPen(* solid_pen); + } + DrawArrows(dc); + } +} + +void wxLineShape::OnDrawControlPoints(wxDC &dc) +{ + if (!m_drawHandles) + return; + + // Draw temporary label rectangles if necessary + if (Selected()) + { + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i] && m_labelObjects[i]->IsShown()) + m_labelObjects[i]->Draw(dc); + } + } + wxShape::OnDrawControlPoints(dc); +} + +void wxLineShape::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ +} + +void wxLineShape::OnBeginDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ +} + +void wxLineShape::OnEndDragLeft(double WXUNUSED(x), double WXUNUSED(y), int WXUNUSED(keys), int WXUNUSED(attachment)) +{ +} + +/* +void wxLineShape::SetArrowSize(double length, double width) +{ + arrow_length = length; + arrow_width = width; +} + +void wxLineShape::SetStartArrow(int style) +{ + start_style = style; +} + +void wxLineShape::SetMiddleArrow(int style) +{ + middle_style = style; +} + +void wxLineShape::SetEndArrow(int style) +{ + end_style = style; +} +*/ + +void wxLineShape::OnDrawContents(wxDC &dc) +{ + if (GetDisableLabel()) + return; + + for (int i = 0; i < 3; i++) + { + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + double x, y; + GetLabelPosition(i, &x, &y); + DrawRegion(dc, region, x, y); + } + } +} + +void wxLineShape::SetTo(wxShape *object) +{ + m_to = object; +} + +void wxLineShape::SetFrom(wxShape *object) +{ + m_from = object; +} + +void wxLineShape::MakeControlPoints() +{ + if (m_canvas && m_lineControlPoints) + { + wxNode *first = m_lineControlPoints->GetFirst(); + wxNode *last = m_lineControlPoints->GetLast(); + wxRealPoint *first_point = (wxRealPoint *)first->GetData(); + wxRealPoint *last_point = (wxRealPoint *)last->GetData(); + + wxLineControlPoint *control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + first_point->x, first_point->y, + CONTROL_POINT_ENDPOINT_FROM); + control->m_point = first_point; + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + + wxNode *node = first->GetNext(); + while (node != last) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + + control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + point->x, point->y, + CONTROL_POINT_LINE); + control->m_point = point; + + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + node = node->GetNext(); + } + control = new wxLineControlPoint(m_canvas, this, CONTROL_POINT_SIZE, + last_point->x, last_point->y, + CONTROL_POINT_ENDPOINT_TO); + control->m_point = last_point; + m_canvas->AddShape(control); + m_controlPoints.Append(control); + + } + +} + +void wxLineShape::ResetControlPoints() +{ + if (m_canvas && m_lineControlPoints && m_controlPoints.GetCount() > 0) + { + wxNode *node = m_controlPoints.GetFirst(); + wxNode *control_node = m_lineControlPoints->GetFirst(); + while (node && control_node) + { + wxRealPoint *point = (wxRealPoint *)control_node->GetData(); + wxLineControlPoint *control = (wxLineControlPoint *)node->GetData(); + control->SetX(point->x); + control->SetY(point->y); + + node = node->GetNext(); + control_node = control_node->GetNext(); + } + } +} + +#if wxUSE_PROLOGIO +void wxLineShape::WriteAttributes(wxExpr *clause) +{ + wxShape::WriteAttributes(clause); + + if (m_from) + clause->AddAttributeValue(wxT("from"), m_from->GetId()); + if (m_to) + clause->AddAttributeValue(wxT("to"), m_to->GetId()); + + if (m_attachmentTo != 0) + clause->AddAttributeValue(wxT("attachment_to"), (long)m_attachmentTo); + if (m_attachmentFrom != 0) + clause->AddAttributeValue(wxT("attachment_from"), (long)m_attachmentFrom); + + if (m_alignmentStart != 0) + clause->AddAttributeValue(wxT("align_start"), (long)m_alignmentStart); + if (m_alignmentEnd != 0) + clause->AddAttributeValue(wxT("align_end"), (long)m_alignmentEnd); + + clause->AddAttributeValue(wxT("is_spline"), (long)m_isSpline); + if (m_maintainStraightLines) + clause->AddAttributeValue(wxT("keep_lines_straight"), (long)m_maintainStraightLines); + + // Make a list of lists for the (sp)line controls + wxExpr *list = new wxExpr(wxExprList); + wxNode *node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxExpr *point_list = new wxExpr(wxExprList); + wxExpr *x_expr = new wxExpr((double) point->x); + wxExpr *y_expr = new wxExpr((double) point->y); + point_list->Append(x_expr); + point_list->Append(y_expr); + list->Append(point_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("controls"), list); + + // Write arc arrows in new OGL format, if there are any. + // This is a list of lists. Each sublist comprises: + // (arrowType arrowEnd xOffset arrowSize) + if (m_arcArrows.GetCount() > 0) + { + wxExpr *arrow_list = new wxExpr(wxExprList); + node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *head = (wxArrowHead *)node->GetData(); + wxExpr *head_list = new wxExpr(wxExprList); + head_list->Append(new wxExpr((long)head->_GetType())); + head_list->Append(new wxExpr((long)head->GetArrowEnd())); + head_list->Append(new wxExpr(head->GetXOffset())); + head_list->Append(new wxExpr(head->GetArrowSize())); + head_list->Append(new wxExpr(wxExprString, head->GetName())); + head_list->Append(new wxExpr(head->GetId())); + + // New members of wxArrowHead + head_list->Append(new wxExpr(head->GetYOffset())); + head_list->Append(new wxExpr(head->GetSpacing())); + + arrow_list->Append(head_list); + + node = node->GetNext(); + } + clause->AddAttributeValue(wxT("arrows"), arrow_list); + } +} + +void wxLineShape::ReadAttributes(wxExpr *clause) +{ + wxShape::ReadAttributes(clause); + + int iVal = (int) m_isSpline; + clause->AssignAttributeValue(wxT("is_spline"), &iVal); + m_isSpline = (iVal != 0); + + iVal = (int) m_maintainStraightLines; + clause->AssignAttributeValue(wxT("keep_lines_straight"), &iVal); + m_maintainStraightLines = (iVal != 0); + + clause->AssignAttributeValue(wxT("align_start"), &m_alignmentStart); + clause->AssignAttributeValue(wxT("align_end"), &m_alignmentEnd); + + // Compatibility: check for no regions. + if (m_regions.GetCount() == 0) + { + wxShapeRegion *newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Middle")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + if (m_text.GetCount() > 0) + { + newRegion->ClearText(); + wxNode *node = m_text.GetFirst(); + while (node) + { + wxShapeTextLine *textLine = (wxShapeTextLine *)node->GetData(); + wxNode *next = node->GetNext(); + newRegion->GetFormattedText().Append((wxObject *)textLine); + delete node; + node = next; + } + } + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("Start")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + + newRegion = new wxShapeRegion; + newRegion->SetName(wxT("End")); + newRegion->SetSize(150, 50); + m_regions.Append((wxObject *)newRegion); + } + + m_attachmentTo = 0; + m_attachmentFrom = 0; + + clause->AssignAttributeValue(wxT("attachment_to"), &m_attachmentTo); + clause->AssignAttributeValue(wxT("attachment_from"), &m_attachmentFrom); + + wxExpr *line_list = NULL; + + // When image is created, there are default control points. Override + // them if there are some in the file. + clause->AssignAttributeValue(wxT("controls"), &line_list); + + if (line_list) + { + // Read a list of lists for the spline controls + if (m_lineControlPoints) + { + ClearPointList(*m_lineControlPoints); + } + else + m_lineControlPoints = new wxList; + + wxExpr *node = line_list->value.first; + + while (node) + { + wxExpr *xexpr = node->value.first; + double x = xexpr->RealValue(); + + wxExpr *yexpr = xexpr->next; + double y = yexpr->RealValue(); + + wxRealPoint *point = new wxRealPoint(x, y); + m_lineControlPoints->Append((wxObject *) point); + + node = node->next; + } + } + + // Read arrow list, for new OGL code + wxExpr *arrow_list = NULL; + + clause->AssignAttributeValue(wxT("arrows"), &arrow_list); + if (arrow_list) + { + wxExpr *node = arrow_list->value.first; + + while (node) + { + WXTYPE arrowType = ARROW_ARROW; + int arrowEnd = 0; + double xOffset = 0.0; + double arrowSize = 0.0; + wxString arrowName; + long arrowId = -1; + + wxExpr *type_expr = node->Nth(0); + wxExpr *end_expr = node->Nth(1); + wxExpr *dist_expr = node->Nth(2); + wxExpr *size_expr = node->Nth(3); + wxExpr *name_expr = node->Nth(4); + wxExpr *id_expr = node->Nth(5); + + // New members of wxArrowHead + wxExpr *yOffsetExpr = node->Nth(6); + wxExpr *spacingExpr = node->Nth(7); + + if (type_expr) + arrowType = (int)type_expr->IntegerValue(); + if (end_expr) + arrowEnd = (int)end_expr->IntegerValue(); + if (dist_expr) + xOffset = dist_expr->RealValue(); + if (size_expr) + arrowSize = size_expr->RealValue(); + if (name_expr) + arrowName = name_expr->StringValue(); + if (id_expr) + arrowId = id_expr->IntegerValue(); + + if (arrowId == -1) + arrowId = wxNewId(); + else + wxRegisterId(arrowId); + + wxArrowHead *arrowHead = AddArrow(arrowType, arrowEnd, arrowSize, xOffset, arrowName, NULL, arrowId); + if (yOffsetExpr) + arrowHead->SetYOffset(yOffsetExpr->RealValue()); + if (spacingExpr) + arrowHead->SetSpacing(spacingExpr->RealValue()); + + node = node->next; + } + } +} +#endif + +void wxLineShape::Copy(wxShape ©) +{ + wxShape::Copy(copy); + + wxASSERT( copy.IsKindOf(CLASSINFO(wxLineShape)) ); + + wxLineShape &lineCopy = (wxLineShape &) copy; + + lineCopy.m_to = m_to; + lineCopy.m_from = m_from; + lineCopy.m_attachmentTo = m_attachmentTo; + lineCopy.m_attachmentFrom = m_attachmentFrom; + lineCopy.m_isSpline = m_isSpline; + lineCopy.m_alignmentStart = m_alignmentStart; + lineCopy.m_alignmentEnd = m_alignmentEnd; + lineCopy.m_maintainStraightLines = m_maintainStraightLines; + lineCopy.m_lineOrientations.Clear(); + + wxNode *node = m_lineOrientations.GetFirst(); + while (node) + { + lineCopy.m_lineOrientations.Append(node->GetData()); + node = node->GetNext(); + } + + if (lineCopy.m_lineControlPoints) + { + ClearPointList(*lineCopy.m_lineControlPoints); + delete lineCopy.m_lineControlPoints; + } + + lineCopy.m_lineControlPoints = new wxList; + + node = m_lineControlPoints->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + wxRealPoint *new_point = new wxRealPoint(point->x, point->y); + lineCopy.m_lineControlPoints->Append((wxObject *) new_point); + node = node->GetNext(); + } + + // Copy arrows + lineCopy.ClearArrowsAtPosition(-1); + node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + lineCopy.m_arcArrows.Append(new wxArrowHead(*arrow)); + node = node->GetNext(); + } +} + +// Override select, to create/delete temporary label-moving objects +void wxLineShape::Select(bool select) +{ + wxShape::Select(select); + if (select) + { + for (int i = 0; i < 3; i++) + { + wxNode *node = m_regions.Item(i); + if (node) + { + wxShapeRegion *region = (wxShapeRegion *)node->GetData(); + if (region->m_formattedText.GetCount() > 0) + { + double w, h, x, y, xx, yy; + region->GetSize(&w, &h); + region->GetPosition(&x, &y); + GetLabelPosition(i, &xx, &yy); +#if 0 + if (m_labelObjects[i]) + { + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + delete m_labelObjects[i]; + } +#endif + if (!m_labelObjects[i]) + { + m_labelObjects[i] = OnCreateLabelShape(this, region, w, h); + } + m_labelObjects[i]->AddToCanvas(m_canvas); + m_labelObjects[i]->Show(TRUE); + m_labelObjects[i]->Move((double)(x + xx), (double)(y + yy)); + m_labelObjects[i]->Select(TRUE); + } + } + } + } + else + { + for (int i = 0; i < 3; i++) + { + if (m_labelObjects[i]) + { + // Don't delete the shape, it might be mentioned in a command + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->Show(false); + m_labelObjects[i]->RemoveFromCanvas(m_canvas); +#if 0 + m_labelObjects[i]->Select(FALSE); + m_labelObjects[i]->RemoveFromCanvas(m_canvas); + delete m_labelObjects[i]; + m_labelObjects[i] = NULL; +#endif + } + } + } + Refresh(); +} + +/* + * Line control point + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxLineControlPoint, wxControlPoint) + +wxLineControlPoint::wxLineControlPoint(wxShapeCanvas *theCanvas, wxShape *object, double size, double x, double y, int the_type): + wxControlPoint(theCanvas, object, size, x, y, the_type) +{ + m_xpos = x; + m_ypos = y; + m_type = the_type; + m_point = NULL; +} + +wxLineControlPoint::~wxLineControlPoint() +{ +} + +void wxLineControlPoint::OnDraw(wxDC &dc) +{ + wxRectangleShape::OnDraw(dc); +} + +// Implement movement of Line point +void wxLineControlPoint::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingDragLeft(this, draw, x, y, keys, attachment); +} + +void wxLineControlPoint::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingBeginDragLeft(this, x, y, keys, attachment); +} + +void wxLineControlPoint::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + m_shape->GetEventHandler()->OnSizingEndDragLeft(this, x, y, keys, attachment); +} + +// Control points ('handles') redirect control to the actual shape, to make it easier +// to override sizing behaviour. +void wxLineShape::OnSizingDragLeft(wxControlPoint *pt, bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxLineControlPoint *lpt = (wxLineControlPoint *) pt; + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + dc.SetLogicalFunction(OGLRBLF); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); +#endif + + if (lpt->m_type == CONTROL_POINT_LINE) + { + m_canvas->Snap(&x, &y); + + lpt->SetX(x); + lpt->SetY(y); + lpt->m_point->x = x; + lpt->m_point->y = y; + +#if 0 + wxLineShape *lineShape = (wxLineShape *)this; + + wxPen *old_pen = lineShape->GetPen(); + wxBrush *old_brush = lineShape->GetBrush(); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + lineShape->SetPen(& dottedPen); + lineShape->SetBrush((wxBrush *) wxTRANSPARENT_BRUSH); + + lineShape->SetPen(old_pen); + lineShape->SetBrush(old_brush); +#endif + } + + GetEventHandler()->OnMoveLink(FALSE); + + + if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM || lpt->m_type == CONTROL_POINT_ENDPOINT_TO) + { +// lpt->SetX(x); lpt->SetY(y); + } + + if (GetCanvas()) + GetCanvas()->Refresh(); + +} + +void wxLineShape::OnSizingBeginDragLeft(wxControlPoint *pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxLineControlPoint *lpt = (wxLineControlPoint *) pt; + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); +#endif + + wxLineShape *lineShape = (wxLineShape *)this; + if (lpt->m_type == CONTROL_POINT_LINE) + { + lpt->m_originalPos = * (lpt->m_point); + m_canvas->Snap(&x, &y); +#if 0 + this->Erase(); + + // Redraw start and end objects because we've left holes + // when erasing the line + lineShape->GetFrom()->OnDraw(dc); + lineShape->GetFrom()->OnDrawContents(dc); + lineShape->GetTo()->OnDraw(dc); + lineShape->GetTo()->OnDrawContents(dc); + + this->SetDisableLabel(TRUE); + dc.SetLogicalFunction(OGLRBLF); +#endif + + lpt->m_xpos = x; + lpt->m_ypos = y; + lpt->m_point->x = x; + lpt->m_point->y = y; + +#if 0 + wxPen *old_pen = lineShape->GetPen(); + wxBrush *old_brush = lineShape->GetBrush(); + + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + lineShape->SetPen(& dottedPen); + lineShape->SetBrush((wxBrush *) wxTRANSPARENT_BRUSH); +#endif + + lineShape->GetEventHandler()->OnMoveLink(FALSE); + +#if 0 + lineShape->SetPen(old_pen); + lineShape->SetBrush(old_brush); +#endif + } + + if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM || lpt->m_type == CONTROL_POINT_ENDPOINT_TO) + { + m_canvas->SetCursor(wxCursor(wxCURSOR_BULLSEYE)); + lpt->m_oldCursor = (wxCursor *) wxSTANDARD_CURSOR; + } + if (GetCanvas()) + GetCanvas()->Refresh(); +} + +void wxLineShape::OnSizingEndDragLeft(wxControlPoint *pt, double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment)) +{ + wxLineControlPoint *lpt = (wxLineControlPoint *) pt; + +#if 0 + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); +#endif + + this->SetDisableLabel(FALSE); + wxLineShape *lineShape = (wxLineShape *)this; + + if (lpt->m_type == CONTROL_POINT_LINE) + { + m_canvas->Snap(&x, &y); + + wxRealPoint pt = wxRealPoint(x, y); + + // Move the control point back to where it was; + // MoveControlPoint will move it to the new position + // if it decides it wants. We only moved the position + // during user feedback so we could redraw the line + // as it changed shape. + lpt->m_xpos = lpt->m_originalPos.x; + lpt->m_ypos = lpt->m_originalPos.y; + lpt->m_point->x = lpt->m_originalPos.x; + lpt->m_point->y = lpt->m_originalPos.y; + + OnMoveMiddleControlPoint(lpt, pt); + } + if (lpt->m_type == CONTROL_POINT_ENDPOINT_FROM) + { + if (lpt->m_oldCursor) + m_canvas->SetCursor(* lpt->m_oldCursor); + +// this->Erase(dc); + +// lpt->m_xpos = x; lpt->m_ypos = y; + + if (lineShape->GetFrom()) + { + lineShape->GetFrom()->MoveLineToNewAttachment(lineShape, x, y); + } + } + if (lpt->m_type == CONTROL_POINT_ENDPOINT_TO) + { + if (lpt->m_oldCursor) + m_canvas->SetCursor(* lpt->m_oldCursor); + +// lpt->m_xpos = x; lpt->m_ypos = y; + + if (lineShape->GetTo()) + { + lineShape->GetTo()->MoveLineToNewAttachment(lineShape, x, y); + } + } + + // Needed? +#if 0 + int i = 0; + for (i = 0; i < lineShape->GetLineControlPoints()->GetCount(); i++) + if (((wxRealPoint *)(lineShape->GetLineControlPoints()->Item(i)->GetData())) == lpt->m_point) + break; + + // N.B. in OnMoveControlPoint, an event handler in Hardy could have deselected + // the line and therefore deleted 'this'. -> GPF, intermittently. + // So assume at this point that we've been blown away. + + lineShape->OnMoveControlPoint(i + 1, x, y); +#endif + + if (GetCanvas()) + GetCanvas()->Refresh(); + +} + +// This is called only when a non-end control point is moved. +bool wxLineShape::OnMoveMiddleControlPoint(wxLineControlPoint *lpt, const wxRealPoint &pt) +{ + lpt->m_xpos = pt.x; + lpt->m_ypos = pt.y; + lpt->m_point->x = pt.x; + lpt->m_point->y = pt.y; + + GetEventHandler()->OnMoveLink(); + + if (GetCanvas()) + GetCanvas()->Refresh(); + + return TRUE; +} + +// Implement movement of endpoint to a new attachment +// OBSOLETE: done by dragging with the left button. + +#if 0 +void wxLineControlPoint::OnDragRight(bool draw, double x, double y, int keys, int attachment) +{ + if (m_type == CONTROL_POINT_ENDPOINT_FROM || m_type == CONTROL_POINT_ENDPOINT_TO) + { + m_xpos = x; + m_ypos = y; + } +} + +void wxLineControlPoint::OnBeginDragRight(double x, double y, int keys, int attachment) +{ + wxLineShape *lineShape = (wxLineShape *)m_shape; + if (m_type == CONTROL_POINT_ENDPOINT_FROM || m_type == CONTROL_POINT_ENDPOINT_TO) + { + lineShape->GetEventHandler()->OnDraw(dc); + if (m_type == CONTROL_POINT_ENDPOINT_FROM) + { + lineShape->GetFrom()->GetEventHandler()->OnDraw(dc); + lineShape->GetFrom()->GetEventHandler()->OnDrawContents(dc); + } + else + { + lineShape->GetTo()->GetEventHandler()->OnDraw(dc); + lineShape->GetTo()->GetEventHandler()->OnDrawContents(dc); + } + m_canvas->SetCursor(wxCursor(wxCURSOR_BULLSEYE)); + m_oldCursor = wxSTANDARD_CURSOR; + } + + if (GetCanvas()) + GetCanvas()->Refresh(); +} + +void wxLineControlPoint::OnEndDragRight(double x, double y, int keys, int attachment) +{ + wxLineShape *lineShape = (wxLineShape *)m_shape; + if (m_type == CONTROL_POINT_ENDPOINT_FROM) + { + if (m_oldCursor) + m_canvas->SetCursor(m_oldCursor); + + m_xpos = x; + m_ypos = y; + + if (lineShape->GetFrom()) + { + int new_attachment; + double distance; + + if (lineShape->GetFrom()->HitTest(x, y, &new_attachment, &distance)) + lineShape->SetAttachments(new_attachment, lineShape->GetAttachmentTo()); + + lineShape->GetFrom()->MoveLinks(); + } + } + if (m_type == CONTROL_POINT_ENDPOINT_TO) + { + if (m_oldCursor) + m_canvas->SetCursor(m_oldCursor); + m_shape->Erase(dc); + + m_xpos = x; + m_ypos = y; + + if (lineShape->GetTo()) + { + int new_attachment; + double distance; + if (lineShape->GetTo()->HitTest(x, y, &new_attachment, &distance)) + lineShape->SetAttachments(lineShape->GetAttachmentFrom(), new_attachment); + + lineShape->GetTo()->MoveLinks(); + } + } + int i = 0; + for (i = 0; i < lineShape->GetLineControlPoints()->GetCount(); i++) + if (((wxRealPoint *)(lineShape->GetLineControlPoints()->Item(i)->GetData())) == m_point) + break; + lineShape->OnMoveControlPoint(i + 1, x, y); + if (GetCanvas()) + GetCanvas()->Refresh(); +} +#endif + +/* + * Get the point on the given line (x1, y1) (x2, y2) + * distance 'length' along from the end, + * returned values in x and y + */ + +void GetPointOnLine(double x1, double y1, double x2, double y2, + double length, double *x, double *y) +{ + double l = (double)sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + if (l < 0.01) + l = (double) 0.01; + + double i_bar = (x2 - x1) / l; + double j_bar = (y2 - y1) / l; + + *x = (- length * i_bar) + x2; + *y = (- length * j_bar) + y2; +} + +wxArrowHead *wxLineShape::AddArrow(WXTYPE type, int end, double size, double xOffset, + const wxString &name, wxPseudoMetaFile *mf, long arrowId) +{ + wxArrowHead *arrow = new wxArrowHead(type, end, size, xOffset, name, mf, arrowId); + m_arcArrows.Append(arrow); + return arrow; +} + +/* + * Add arrowhead at a particular position in the arrowhead list. + */ +bool wxLineShape::AddArrowOrdered(wxArrowHead *arrow, wxList &referenceList, int end) +{ + wxNode *refNode = referenceList.GetFirst(); + wxNode *currNode = m_arcArrows.GetFirst(); + wxString targetName(arrow->GetName()); + if (!refNode) return FALSE; + + // First check whether we need to insert in front of list, + // because this arrowhead is the first in the reference + // list and should therefore be first in the current list. + wxArrowHead *refArrow = (wxArrowHead *)refNode->GetData(); + if (refArrow->GetName() == targetName) + { + m_arcArrows.Insert(arrow); + return TRUE; + } + + wxArrowHead *currArrow = (wxArrowHead *)currNode->GetData(); + while (refNode && currNode) + { + refArrow = (wxArrowHead *)refNode->GetData(); + + // Matching: advance current arrow pointer + if ((currArrow->GetArrowEnd() == end) && + (currArrow->GetName() == refArrow->GetName())) + { + currNode = currNode->GetNext(); // Could be NULL now + if (currNode) + currArrow = (wxArrowHead *)currNode->GetData(); + } + + // Check if we're at the correct position in the + // reference list + if (targetName == refArrow->GetName()) + { + if (currNode) + m_arcArrows.Insert(currNode, arrow); + else + m_arcArrows.Append(arrow); + return TRUE; + } + refNode = refNode->GetNext(); + } + m_arcArrows.Append(arrow); + return TRUE; +} + +void wxLineShape::ClearArrowsAtPosition(int end) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + wxNode *next = node->GetNext(); + switch (end) + { + case -1: + { + delete arrow; + delete node; + break; + } + case ARROW_POSITION_START: + { + if (arrow->GetArrowEnd() == ARROW_POSITION_START) + { + delete arrow; + delete node; + } + break; + } + case ARROW_POSITION_END: + { + if (arrow->GetArrowEnd() == ARROW_POSITION_END) + { + delete arrow; + delete node; + } + break; + } + case ARROW_POSITION_MIDDLE: + { + if (arrow->GetArrowEnd() == ARROW_POSITION_MIDDLE) + { + delete arrow; + delete node; + } + break; + } + } + node = next; + } +} + +bool wxLineShape::ClearArrow(const wxString &name) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (arrow->GetName() == name) + { + delete arrow; + delete node; + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +/* + * Finds an arrowhead at the given position (if -1, any position) + * + */ + +wxArrowHead *wxLineShape::FindArrowHead(int position, const wxString &name) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (((position == -1) || (position == arrow->GetArrowEnd())) && + (arrow->GetName() == name)) + return arrow; + node = node->GetNext(); + } + return NULL; +} + +wxArrowHead *wxLineShape::FindArrowHead(long arrowId) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (arrowId == arrow->GetId()) + return arrow; + node = node->GetNext(); + } + return NULL; +} + +/* + * Deletes an arrowhead at the given position (if -1, any position) + * + */ + +bool wxLineShape::DeleteArrowHead(int position, const wxString &name) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (((position == -1) || (position == arrow->GetArrowEnd())) && + (arrow->GetName() == name)) + { + delete arrow; + delete node; + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +// Overloaded DeleteArrowHead: pass arrowhead id. +bool wxLineShape::DeleteArrowHead(long id) +{ + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrow = (wxArrowHead *)node->GetData(); + if (arrow->GetId() == id) + { + delete arrow; + delete node; + return TRUE; + } + node = node->GetNext(); + } + return FALSE; +} + +/* + * Calculate the minimum width a line + * occupies, for the purposes of drawing lines in tools. + * + */ + +double wxLineShape::FindMinimumWidth() +{ + double minWidth = 0.0; + wxNode *node = m_arcArrows.GetFirst(); + while (node) + { + wxArrowHead *arrowHead = (wxArrowHead *)node->GetData(); + minWidth += arrowHead->GetSize(); + if (node->GetNext()) + minWidth += arrowHead->GetSpacing(); + + node = node->GetNext(); + } + // We have ABSOLUTE minimum now. So + // scale it to give it reasonable aesthetics + // when drawing with line. + if (minWidth > 0.0) + minWidth = (double)(minWidth * 1.4); + else + minWidth = 20.0; + + SetEnds(0.0, 0.0, minWidth, 0.0); + Initialise(); + + return minWidth; +} + +// Find which position we're talking about at this (x, y). +// Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END +int wxLineShape::FindLinePosition(double x, double y) +{ + double startX, startY, endX, endY; + GetEnds(&startX, &startY, &endX, &endY); + + // Find distances from centre, start and end. The smallest wins. + double centreDistance = (double)(sqrt((x - m_xpos) * (x - m_xpos) + (y - m_ypos) * (y - m_ypos))); + double startDistance = (double)(sqrt((x - startX) * (x - startX) + (y - startY) * (y - startY))); + double endDistance = (double)(sqrt((x - endX) * (x - endX) + (y - endY) * (y - endY))); + + if (centreDistance < startDistance && centreDistance < endDistance) + return ARROW_POSITION_MIDDLE; + else if (startDistance < endDistance) + return ARROW_POSITION_START; + else + return ARROW_POSITION_END; +} + +// Set alignment flags +void wxLineShape::SetAlignmentOrientation(bool isEnd, bool isHoriz) +{ + if (isEnd) + { + if (isHoriz && ((m_alignmentEnd & LINE_ALIGNMENT_HORIZ) != LINE_ALIGNMENT_HORIZ)) + m_alignmentEnd |= LINE_ALIGNMENT_HORIZ; + else if (!isHoriz && ((m_alignmentEnd & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ)) + m_alignmentEnd -= LINE_ALIGNMENT_HORIZ; + } + else + { + if (isHoriz && ((m_alignmentStart & LINE_ALIGNMENT_HORIZ) != LINE_ALIGNMENT_HORIZ)) + m_alignmentStart |= LINE_ALIGNMENT_HORIZ; + else if (!isHoriz && ((m_alignmentStart & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ)) + m_alignmentStart -= LINE_ALIGNMENT_HORIZ; + } +} + +void wxLineShape::SetAlignmentType(bool isEnd, int alignType) +{ + if (isEnd) + { + if (alignType == LINE_ALIGNMENT_TO_NEXT_HANDLE) + { + if ((m_alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE) != LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentEnd |= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } + else if ((m_alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE) == LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentEnd -= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } + else + { + if (alignType == LINE_ALIGNMENT_TO_NEXT_HANDLE) + { + if ((m_alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE) != LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentStart |= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } + else if ((m_alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE) == LINE_ALIGNMENT_TO_NEXT_HANDLE) + m_alignmentStart -= LINE_ALIGNMENT_TO_NEXT_HANDLE; + } +} + +bool wxLineShape::GetAlignmentOrientation(bool isEnd) +{ + if (isEnd) + return ((m_alignmentEnd & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ); + else + return ((m_alignmentStart & LINE_ALIGNMENT_HORIZ) == LINE_ALIGNMENT_HORIZ); +} + +int wxLineShape::GetAlignmentType(bool isEnd) +{ + if (isEnd) + return (m_alignmentEnd & LINE_ALIGNMENT_TO_NEXT_HANDLE); + else + return (m_alignmentStart & LINE_ALIGNMENT_TO_NEXT_HANDLE); +} + +wxRealPoint *wxLineShape::GetNextControlPoint(wxShape *nodeObject) +{ + int n = m_lineControlPoints->GetCount(); + int nn; + if (m_to == nodeObject) + { + // Must be END of line, so we want (n - 1)th control point. + // But indexing ends at n-1, so subtract 2. + nn = n - 2; + } + else nn = 1; + wxNode *node = m_lineControlPoints->Item(nn); + if (node) + { + return (wxRealPoint *)node->GetData(); + } + else + return FALSE; +} + +/* + * Arrowhead + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxArrowHead, wxObject) + +wxArrowHead::wxArrowHead(WXTYPE type, int end, double size, double dist, const wxString &name, + wxPseudoMetaFile *mf, long arrowId) +{ + m_arrowType = type; + m_arrowEnd = end; + m_arrowSize = size; + m_xOffset = dist; + m_yOffset = 0.0; + m_spacing = 5.0; + + m_arrowName = name; + m_metaFile = mf; + m_id = arrowId; + if (m_id == -1) + m_id = wxNewId(); +} + +wxArrowHead::wxArrowHead(wxArrowHead &toCopy) +{ + m_arrowType = toCopy.m_arrowType; + m_arrowEnd = toCopy.GetArrowEnd(); + m_arrowSize = toCopy.m_arrowSize; + m_xOffset = toCopy.m_xOffset; + m_yOffset = toCopy.m_yOffset; + m_spacing = toCopy.m_spacing; + m_arrowName = toCopy.m_arrowName ; + if (toCopy.m_metaFile) + m_metaFile = new wxPseudoMetaFile(*(toCopy.m_metaFile)); + else + m_metaFile = NULL; + m_id = wxNewId(); +} + +wxArrowHead::~wxArrowHead() +{ + if (m_metaFile) delete m_metaFile; +} + +void wxArrowHead::SetSize(double size) +{ + m_arrowSize = size; + if ((m_arrowType == ARROW_METAFILE) && m_metaFile) + { + double oldWidth = m_metaFile->m_width; + if (oldWidth == 0.0) + return; + + double scale = (double)(size / oldWidth); + if (scale != 1.0) + m_metaFile->Scale(scale, scale); + } +} + +// Can override this to create a different class of label shape +wxLabelShape *wxLineShape::OnCreateLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h) +{ + return new wxLabelShape(parent, region, w, h); +} + +/* + * Label object + * + */ + +IMPLEMENT_DYNAMIC_CLASS(wxLabelShape, wxRectangleShape) + +wxLabelShape::wxLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h): wxRectangleShape(w, h) +{ + m_lineShape = parent; + m_shapeRegion = region; + SetPen(wxThePenList->FindOrCreatePen(wxColour(0, 0, 0), 1, wxDOT)); +} + +wxLabelShape::~wxLabelShape() +{ +} + +void wxLabelShape::OnDraw(wxDC &dc) +{ + if (m_lineShape && !m_lineShape->GetDrawHandles()) + return; + + double x1 = (double)(m_xpos - m_width / 2.0); + double y1 = (double)(m_ypos - m_height / 2.0); + + if (m_pen) + { + if (m_pen->GetWidth() == 0) + dc.SetPen(* g_oglTransparentPen); + else + dc.SetPen(* m_pen); + } + dc.SetBrush(* wxTRANSPARENT_BRUSH); + + if (m_cornerRadius > 0.0) + dc.DrawRoundedRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height), m_cornerRadius); + else + dc.DrawRectangle(WXROUND(x1), WXROUND(y1), WXROUND(m_width), WXROUND(m_height)); +} + +void wxLabelShape::OnDrawContents(wxDC &WXUNUSED(dc)) +{ +} + +void wxLabelShape::OnDragLeft(bool draw, double x, double y, int keys, int attachment) +{ + wxRectangleShape::OnDragLeft(draw, x, y, keys, attachment); +} + +void wxLabelShape::OnBeginDragLeft(double x, double y, int keys, int attachment) +{ + wxRectangleShape::OnBeginDragLeft(x, y, keys, attachment); +} + +void wxLabelShape::OnEndDragLeft(double x, double y, int keys, int attachment) +{ + wxRectangleShape::OnEndDragLeft(x, y, keys, attachment); +} + +bool wxLabelShape::OnMovePre(double x, double y, double old_x, double old_y, bool display) +{ + return m_lineShape->OnLabelMovePre(this, x, y, old_x, old_y, display); +} + +bool wxLineShape::OnLabelMovePre(wxLabelShape *labelShape, double x, double y, double WXUNUSED(old_x), double WXUNUSED(old_y), bool WXUNUSED(display)) +{ + labelShape->m_shapeRegion->SetSize(labelShape->GetWidth(), labelShape->GetHeight()); + + // Find position in line's region list + int i = 0; + wxNode *node = GetRegions().GetFirst(); + while (node) + { + if (labelShape->m_shapeRegion == (wxShapeRegion *)node->GetData()) + node = NULL; + else + { + node = node->GetNext(); + i ++; + } + } + double xx, yy; + GetLabelPosition(i, &xx, &yy); + // Set the region's offset, relative to the default position for + // each region. + labelShape->m_shapeRegion->SetPosition((double)(x - xx), (double)(y - yy)); + + labelShape->SetX(x); + labelShape->SetY(y); + + // Need to reformat to fit region. + if (!labelShape->m_shapeRegion->GetText().IsEmpty()) + { + wxClientDC dc(GetCanvas()); + GetCanvas()->PrepareDC(dc); + + wxString s(labelShape->m_shapeRegion->GetText()); + labelShape->FormatText(dc, s, i); + // DrawRegion(dc, labelShape->m_shapeRegion, xx, yy); + } + return TRUE; +} + +// Divert left and right clicks to line object +void wxLabelShape::OnLeftClick(double x, double y, int keys, int attachment) +{ + m_lineShape->GetEventHandler()->OnLeftClick(x, y, keys, attachment); +} + +void wxLabelShape::OnRightClick(double x, double y, int keys, int attachment) +{ + m_lineShape->GetEventHandler()->OnRightClick(x, y, keys, attachment); +} + diff --git a/ogl/mfutils.cpp b/ogl/mfutils.cpp new file mode 100644 index 0000000..81ca969 --- /dev/null +++ b/ogl/mfutils.cpp @@ -0,0 +1,1087 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// mfutils.cpp - Metafile utillities +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include + +#include "ogl/ogl.h" + +#include + +static char _buf[1024]; // a temp buffer to use inplace of wxBuffer, which is deprecated. + +// 16-bit unsigned integer +static unsigned int getshort(FILE *fp) +{ + int c, c1; + c = getc(fp); + c1 = getc(fp); + unsigned int res = ((unsigned int) c) + (((unsigned int) c1) << 8); + return res; +} + +// 16-bit signed integer +static int getsignedshort(FILE *fp) +{ + int c, c1; + c = getc(fp); + c1 = getc(fp); +#if 0 + // this is not used value, no need to execute it + int testRes = ((unsigned int) c) + (((unsigned int) c1) << 8); +#endif + unsigned long res1 = ((unsigned int) c) + (((unsigned int) c1) << 8); + int res; + if (res1 > 32767) + res = (int)(res1 - 65536); + else + res = (int)(res1); + return res; +} + +// 32-bit integer +static long getint(FILE *fp) +{ + int c, c1, c2, c3; + c = getc(fp); + c1 = getc(fp); + c2 = getc(fp); + c3 = getc(fp); + long res = (long)((long) c) + + (((long) c1) << 8) + + (((long) c2) << 16) + + (((long) c3) << 24); + return res; +} + + +/* Placeable metafile header +struct mfPLACEABLEHEADER { + DWORD key; // 32-bit + HANDLE hmf; // 16-bit + RECT bbox; // 4x16 bit + WORD inch; // 16-bit + DWORD reserved; // 32-bit + WORD checksum; // 16-bit +}; +*/ + +wxMetaRecord::~wxMetaRecord(void) +{ + if (points) delete[] points; + if (stringParam) delete[] stringParam; +} + +wxXMetaFile::wxXMetaFile(const wxChar *file) +{ + ok = FALSE; + top = 0.0; + bottom = 0.0; + left = 0.0; + right = 0.0; + + if (file) + ok = ReadFile(file); +} + +/* + Handle table gdiObjects + ------------ ---------- + [0] wxPen + [1]----param2--- wxBrush + [2] | wxFont + [3] | -> wxPen + + The handle table works as follows. + When a GDI object is created whilst reading in the + metafile, the (e.g.) createpen record is added to the + first free entry in the handle table. The createpen + record's param1 is a pointer to the actual wxPen, and + its param2 is the index into the gdiObjects list, which only + grows and never shrinks (unlike the handle table.) + + When SelectObject(index) is found, the index in the file + refers to the position in the handle table. BUT we then + set param2 to be the position of the wxPen in gdiObjects, + i.e. to param2 of the CreatePen record, itself found in + the handle table. + + When an object is deleted, the entry in the handletable is + NULLed but the gdiObjects entry is not removed (no point, and + allows us to create all GDI objects in advance of playing the + metafile). +*/ + + +static wxMetaRecord *HandleTable[100]; +static int HandleTableSize = 0; + +void DeleteMetaRecordHandle(int index) +{ + HandleTable[index] = NULL; +} + +int AddMetaRecordHandle(wxMetaRecord *record) +{ + for (int i = 0; i < HandleTableSize; i++) + if (!HandleTable[i]) + { + HandleTable[i] = record; + return i; + } + // No free spaces in table, so append. + + HandleTable[HandleTableSize] = record; + HandleTableSize ++; + return (HandleTableSize - 1); +} + +bool wxXMetaFile::ReadFile(const wxChar *file) +{ + HandleTableSize = 0; + + FILE *handle = wxFopen(file, wxT("rb")); + if (!handle) return FALSE; + + // Read placeable metafile header, if any + long key = getint(handle); + + if (key == (long) 0x9AC6CDD7) + { + /* long hmf = */ getshort(handle); + int iLeft, iTop, iRight, iBottom; + iLeft = getsignedshort(handle); + iTop = getsignedshort(handle); + iRight = getsignedshort(handle); + iBottom = getsignedshort(handle); + + left = (double)iLeft; + top = (double)iTop; + right = (double)iRight; + bottom = (double)iBottom; + + /* int inch = */ + getshort(handle); + /* long reserved = */ + getint(handle); + /* int checksum = */ + getshort(handle); + /* + double widthInUnits = (double)right - left; + double heightInUnits = (double)bottom - top; + *width = (int)((widthInUnits*1440.0)/inch); + *height = (int)((heightInUnits*1440.0)/inch); + */ + } + else rewind(handle); + + // Read METAHEADER + int mtType = getshort(handle); + + if (mtType != 1 && mtType != 2) + { + fclose(handle); + return FALSE; + } + + /* int mtHeaderSize = */ getshort(handle); + int mtVersion = getshort(handle); + + if (mtVersion != 0x0300 && mtVersion != 0x0100) + { + fclose(handle); + return FALSE; + } + + /* long mtSize = */ getint(handle); + /* int mtNoObjects = */ + getshort(handle); + /* long mtMaxRecord = */ + getint(handle); + /* int mtNoParameters = */ + getshort(handle); + + while (!feof(handle)) + { + long rdSize = getint(handle); // 4 bytes + int rdFunction = getshort(handle); // 2 bytes + if (feof(handle)) + break; + + switch (rdFunction) + { + case META_SETBKCOLOR: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETBKCOLOR); + long colorref = getint(handle); // COLORREF + rec->param1 = GetRValue(colorref); + rec->param2 = GetGValue(colorref); + rec->param3 = GetBValue(colorref); + metaRecords.Append(rec); + break; + } + case META_SETBKMODE: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETBKMODE); + rec->param1 = getshort(handle); // Background mode + if (rec->param1 == OPAQUE) rec->param1 = wxSOLID; + else rec->param1 = wxTRANSPARENT; + metaRecords.Append(rec); + break; + } + case META_SETMAPMODE: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETMAPMODE); + rec->param1 = getshort(handle); + metaRecords.Append(rec); + break; + } +// case META_SETROP2: +// case META_SETRELABS: +// case META_SETPOLYFILLMODE: +// case META_SETSTRETCHBLTMODE: +// case META_SETTEXTCHAREXTRA: + case META_SETTEXTCOLOR: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETTEXTCOLOR); + long colorref = getint(handle); // COLORREF + rec->param1 = GetRValue(colorref); + rec->param2 = GetGValue(colorref); + rec->param3 = GetBValue(colorref); + metaRecords.Append(rec); + break; + } +// case META_SETTEXTJUSTIFICATION: + case META_SETWINDOWORG: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWORG); + rec->param2 = getshort(handle); + rec->param1 = getshort(handle); + metaRecords.Append(rec); + break; + } + case META_SETWINDOWEXT: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWEXT); + rec->param2 = getshort(handle); + rec->param1 = getshort(handle); + metaRecords.Append(rec); + break; + } +// case META_SETVIEWPORTORG: +// case META_SETVIEWPORTEXT: +// case META_OFFSETWINDOWORG: +// case META_SCALEWINDOWEXT: +// case META_OFFSETVIEWPORTORG: +// case META_SCALEVIEWPORTEXT: + case META_LINETO: + { + wxMetaRecord *rec = new wxMetaRecord(META_LINETO); + rec->param1 = getshort(handle); // x1 + rec->param2 = getshort(handle); // y1 + metaRecords.Append(rec); + break; + } + case META_MOVETO: + { + wxMetaRecord *rec = new wxMetaRecord(META_MOVETO); + rec->param1 = getshort(handle); // x1 + rec->param2 = getshort(handle); // y1 + metaRecords.Append(rec); + break; + } + case META_EXCLUDECLIPRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } + case META_INTERSECTCLIPRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_INTERSECTCLIPRECT); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } +// case META_ARC: // DO!!! + case META_ELLIPSE: + { + wxMetaRecord *rec = new wxMetaRecord(META_ELLIPSE); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } +// case META_FLOODFILL: +// case META_PIE: // DO!!! + case META_RECTANGLE: + { + wxMetaRecord *rec = new wxMetaRecord(META_RECTANGLE); + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } + case META_ROUNDRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_ROUNDRECT); + rec->param6 = getshort(handle); // width + rec->param5 = getshort(handle); // height + rec->param4 = getshort(handle); // y2 + rec->param3 = getshort(handle); // x2 + rec->param2 = getshort(handle); // y1 + rec->param1 = getshort(handle); // x1 + metaRecords.Append(rec); + break; + } +// case META_PATBLT: +// case META_SAVEDC: + case META_SETPIXEL: + { + wxMetaRecord *rec = new wxMetaRecord(META_SETPIXEL); + rec->param1 = getshort(handle); // x1 + rec->param2 = getshort(handle); // y1 + rec->param3 = getint(handle); // COLORREF + metaRecords.Append(rec); + break; + } +// case META_OFFSETCLIPRGN: + case META_TEXTOUT: + { + wxMetaRecord *rec = new wxMetaRecord(META_TEXTOUT); + int count = getshort(handle); + rec->stringParam = new wxChar[count + 1]; + fread((void *)rec->stringParam, sizeof(wxChar), count, handle); + rec->stringParam[count] = 0; + rec->param2 = getshort(handle); // Y + rec->param1 = getshort(handle); // X + metaRecords.Append(rec); + break; + } + /* + case META_EXTTEXTOUT: + { + wxMetaRecord *rec = new wxMetaRecord(META_EXTTEXTOUT); + int cellSpacing = getshort(handle); + int count = getshort(handle); + rec->stringParam = new char[count+1]; + fread((void *)rec->stringParam, sizeof(char), count, handle); + rec->stringParam[count] = 0; + // Rectangle + int rectY2 = getshort(handle); + int rectX2 = getshort(handle); + int rectY1 = getshort(handle); + int rectX1 = getshort(handle); + int rectType = getshort(handle); + rec->param2 = getshort(handle); // Y + rec->param1 = getshort(handle); // X + metaRecords.Append(rec); + break; + } + */ +// case META_BITBLT: +// case META_STRETCHBLT: + case META_POLYGON: + { + wxMetaRecord *rec = new wxMetaRecord(META_POLYGON); + rec->param1 = getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + + metaRecords.Append(rec); + break; + } + case META_POLYLINE: + { + wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE); + rec->param1 = (long)getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + + metaRecords.Append(rec); + break; + } +// case META_ESCAPE: +// case META_RESTOREDC: +// case META_FILLREGION: +// case META_FRAMEREGION: +// case META_INVERTREGION: +// case META_PAINTREGION: +// case META_SELECTCLIPREGION: // DO THIS! + case META_SELECTOBJECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT); + rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list + metaRecords.Append(rec); + // param2 gives the index into gdiObjects, which is different from + // the index into the handle table. + rec->param2 = HandleTable[(int)rec->param1]->param2; + break; + } +// case META_SETTEXTALIGN: +// case META_DRAWTEXT: +// case META_CHORD: +// case META_SETMAPPERFLAGS: +// case META_EXTTEXTOUT: +// case META_SETDIBTODEV: +// case META_SELECTPALETTE: +// case META_REALIZEPALETTE: +// case META_ANIMATEPALETTE: +// case META_SETPALENTRIES: +// case META_POLYPOLYGON: +// case META_RESIZEPALETTE: +// case META_DIBBITBLT: +// case META_DIBSTRETCHBLT: + case META_DIBCREATEPATTERNBRUSH: + { + wxMetaRecord *rec = new wxMetaRecord(META_DIBCREATEPATTERNBRUSH); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } +// case META_STRETCHDIB: +// case META_EXTFLOODFILL: +// case META_RESETDC: +// case META_STARTDOC: +// case META_STARTPAGE: +// case META_ENDPAGE: +// case META_ABORTDOC: +// case META_ENDDOC: + case META_DELETEOBJECT: + { + int index = getshort(handle); + DeleteMetaRecordHandle(index); + break; + } + case META_CREATEPALETTE: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBRUSH: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSH); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEPATTERNBRUSH: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPATTERNBRUSH); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEPENINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPENINDIRECT); + int msStyle = getshort(handle); // Style: 2 bytes + int x = getshort(handle); // X: 2 bytes + /* int y = */ + getshort(handle); // Y: 2 bytes + long colorref = getint(handle); // COLORREF 4 bytes + + int style; + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxThePenList->FindOrCreatePen(colour, x, style); + metaRecords.Append(rec); + gdiObjects.Append(rec); + + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + + // For some reason, the size of this record is sometimes 9 words!!! + // instead of the usual 8. So read 2 characters extra. + if (rdSize == 9) + { + (void) getshort(handle); + } + break; + } + case META_CREATEFONTINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEFONTINDIRECT); + int lfHeight = getshort(handle); // 2 bytes + /* int lfWidth = */ + getshort(handle); // 2 bytes + /* int lfEsc = */ + getshort(handle); // 2 bytes + /* int lfOrient = */ + getshort(handle); // 2 bytes + int lfWeight = getshort(handle); // 2 bytes + char lfItalic = getc(handle); // 1 byte + char lfUnderline = getc(handle); // 1 byte + /* char lfStrikeout = */ + getc(handle); // 1 byte + /* char lfCharSet = */ + getc(handle); // 1 byte + /* char lfOutPrecision = */ + getc(handle); // 1 byte + /* char lfClipPrecision = */ + getc(handle); // 1 byte + /* char lfQuality = */ + getc(handle); // 1 byte + char lfPitchAndFamily = getc(handle); // 1 byte (18th) + char lfFacename[32]; + // Read the rest of the record, which is total record size + // minus the number of bytes already read (18 record, 6 metarecord + // header) + fread((void *)lfFacename, sizeof(char), (int)((2 * rdSize) - 18 - 6), handle); + + int family; + if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_ROMAN) + family = wxROMAN; + else if (lfPitchAndFamily & FF_SWISS) + family = wxSWISS; + else if (lfPitchAndFamily & FF_DECORATIVE) + family = wxDECORATIVE; + else + family = wxDEFAULT; + + int weight; + if (lfWeight == 300) + weight = wxLIGHT; + else if (lfWeight == 400) + weight = wxNORMAL; + else if (lfWeight == 900) + weight = wxBOLD; + else weight = wxNORMAL; + + int style; + if (lfItalic != 0) + style = wxITALIC; + else + style = wxNORMAL; + + // About how many pixels per inch??? + int logPixelsY = 100; + int pointSize = (int)(lfHeight * 72.0 / logPixelsY); + + wxFont *theFont = + wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (lfUnderline != 0)); + + rec->param1 = (long) theFont; + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBRUSHINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSHINDIRECT); + int msStyle = getshort(handle); // Style: 2 bytes + long colorref = getint(handle); // COLORREF: 4 bytes + int hatchStyle = getshort(handle); // Hatch style 2 bytes + + int style; + switch (msStyle) + { + case BS_HATCHED: + { + switch (hatchStyle) + { + case HS_BDIAGONAL: + style = wxBDIAGONAL_HATCH; + break; + case HS_DIAGCROSS: + style = wxCROSSDIAG_HATCH; + break; + case HS_FDIAGONAL: + style = wxFDIAGONAL_HATCH; + break; + case HS_HORIZONTAL: + style = wxHORIZONTAL_HATCH; + break; + case HS_VERTICAL: + style = wxVERTICAL_HATCH; + break; + default: + case HS_CROSS: + style = wxCROSS_HATCH; + break; + } + break; + } + case BS_SOLID: + default: + style = wxSOLID; + break; + } + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(colour, style); + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBITMAPINDIRECT: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAPINDIRECT); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEBITMAP: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAP); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + case META_CREATEREGION: + { + wxMetaRecord *rec = new wxMetaRecord(META_CREATEREGION); + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + + metaRecords.Append(rec); + gdiObjects.Append(rec); + AddMetaRecordHandle(rec); + rec->param2 = (long)(gdiObjects.GetCount() - 1); + break; + } + default: + { + fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle); + break; + } + } + } + fclose(handle); + return TRUE; +} + +wxXMetaFile::~wxXMetaFile(void) +{ + wxNode *node = metaRecords.GetFirst(); + while (node) + { + wxMetaRecord *rec = (wxMetaRecord *)node->GetData(); + delete rec; + wxNode *next = node->GetNext(); + delete node; + node = next; + } +} + +bool wxXMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height)) +{ + return FALSE; +} + +bool wxXMetaFile::Play(wxDC *dc) +{ + wxNode *node = metaRecords.GetFirst(); + while (node) + { + wxMetaRecord *rec = (wxMetaRecord *)node->GetData(); + int rdFunction = rec->metaFunction; + + switch (rdFunction) + { + case META_SETBKCOLOR: + { + break; + } + case META_SETBKMODE: + { + break; + } + case META_SETMAPMODE: + { + break; + } +// case META_SETROP2: +// case META_SETRELABS: +// case META_SETPOLYFILLMODE: +// case META_SETSTRETCHBLTMODE: +// case META_SETTEXTCHAREXTRA: + case META_SETTEXTCOLOR: + { + break; + } +// case META_SETTEXTJUSTIFICATION: + case META_SETWINDOWORG: + { + break; + } + case META_SETWINDOWEXT: + { + break; + } +// case META_SETVIEWPORTORG: +// case META_SETVIEWPORTEXT: +// case META_OFFSETWINDOWORG: +// case META_SCALEWINDOWEXT: +// case META_OFFSETVIEWPORTORG: +// case META_SCALEVIEWPORTEXT: + case META_LINETO: + { + long x1 = rec->param1; + long y1 = rec->param2; + dc->DrawLine((long) lastX, (long) lastY, x1, y1); + break; + } + case META_MOVETO: + { + lastX = (double)rec->param1; + lastY = (double)rec->param2; + break; + } + case META_EXCLUDECLIPRECT: + { + break; + } + case META_INTERSECTCLIPRECT: + { + break; + } +// case META_ARC: // DO!!! + case META_ELLIPSE: + { + break; + } +// case META_FLOODFILL: +// case META_PIE: // DO!!! + case META_RECTANGLE: + { + dc->DrawRectangle((long)rec->param1, (long)rec->param2, + (long)rec->param3 - rec->param1, + (long)rec->param4 - rec->param2); + break; + } + case META_ROUNDRECT: + { + dc->DrawRoundedRectangle((long)rec->param1, (long)rec->param2, + (long)rec->param3 - rec->param1, + (long)rec->param4 - rec->param2, + (long)rec->param5); + break; + } +// case META_PATBLT: +// case META_SAVEDC: + case META_SETPIXEL: + { +// rec->param1 = getshort(handle); // x1 +// rec->param2 = getshort(handle); // y1 +// rec->param3 = getint(handle); // COLORREF + break; + } +// case META_OFFSETCLIPRGN: + case META_TEXTOUT: + { + /* + int count = getshort(handle); + rec->stringParam = new char[count+1]; + fread((void *)rec->stringParam, sizeof(char), count, handle); + rec->stringParam[count] = 0; + rec->param2 = getshort(handle); // Y + rec->param1 = getshort(handle); // X + */ + break; + } +// case META_BITBLT: +// case META_STRETCHBLT: + case META_POLYGON: + { + /* + rec->param1 = getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + */ + break; + } + case META_POLYLINE: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE); + rec->param1 = (long)getshort(handle); + rec->points = new wxRealPoint[(int)rec->param1]; + for (int i = 0; i < rec->param1; i++) + { + rec->points[i].x = getshort(handle); + rec->points[i].y = getshort(handle); + } + */ + break; + } +// case META_ESCAPE: +// case META_RESTOREDC: +// case META_FILLREGION: +// case META_FRAMEREGION: +// case META_INVERTREGION: +// case META_PAINTREGION: +// case META_SELECTCLIPREGION: // DO THIS! + case META_SELECTOBJECT: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT); + rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list + */ + break; + } +// case META_SETTEXTALIGN: +// case META_DRAWTEXT: +// case META_CHORD: +// case META_SETMAPPERFLAGS: +// case META_EXTTEXTOUT: +// case META_SETDIBTODEV: +// case META_SELECTPALETTE: +// case META_REALIZEPALETTE: +// case META_ANIMATEPALETTE: +// case META_SETPALENTRIES: +// case META_POLYPOLYGON: +// case META_RESIZEPALETTE: +// case META_DIBBITBLT: +// case META_DIBSTRETCHBLT: + case META_DIBCREATEPATTERNBRUSH: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } +// case META_STRETCHDIB: +// case META_EXTFLOODFILL: +// case META_RESETDC: +// case META_STARTDOC: +// case META_STARTPAGE: +// case META_ENDPAGE: +// case META_ABORTDOC: +// case META_ENDDOC: +// case META_DELETEOBJECT: // DO!! + case META_CREATEPALETTE: + { + /* + wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE); + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEBRUSH: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEPATTERNBRUSH: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEPENINDIRECT: + { + /* + int msStyle = getshort(handle); // Style: 2 bytes + int x = getshort(handle); // X: 2 bytes + int y = getshort(handle); // Y: 2 bytes + int colorref = getint(handle); // COLORREF 4 bytes + + int style; + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxThePenList->FindOrCreatePen(&colour, x, style); + */ + break; + } + case META_CREATEFONTINDIRECT: + { + /* + int lfHeight = getshort(handle); + int lfWidth = getshort(handle); + int lfEsc = getshort(handle); + int lfOrient = getshort(handle); + int lfWeight = getshort(handle); + char lfItalic = getc(handle); + char lfUnderline = getc(handle); + char lfStrikeout = getc(handle); + char lfCharSet = getc(handle); + char lfOutPrecision = getc(handle); + char lfClipPrecision = getc(handle); + char lfQuality = getc(handle); + char lfPitchAndFamily = getc(handle); + char lfFacename[32]; + fread((void *)lfFacename, sizeof(char), 32, handle); + + int family; + if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_MODERN) + family = wxMODERN; + else if (lfPitchAndFamily & FF_ROMAN) + family = wxROMAN; + else if (lfPitchAndFamily & FF_SWISS) + family = wxSWISS; + else if (lfPitchAndFamily & FF_DECORATIVE) + family = wxDECORATIVE; + else + family = wxDEFAULT; + + int weight; + if (lfWeight == 300) + weight = wxLIGHT; + else if (lfWeight == 400) + weight = wxNORMAL; + else if (lfWeight == 900) + weight = wxBOLD; + else weight = wxNORMAL; + + int style; + if ((bool)lfItalic) + style = wxITALIC; + else + style = wxNORMAL; + + // About how many pixels per inch??? + int logPixelsY = 100; + int pointSize = (int)(lfHeight*72.0/logPixelsY); + + wxFont *theFont = + wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (bool)lfUnderline); + + rec->param1 = (long)theFont; + */ + break; + } + case META_CREATEBRUSHINDIRECT: + { + /* + int msStyle = getshort(handle); // Style: 2 bytes + int colorref = getint(handle); // COLORREF: 4 bytes + int hatchStyle = getshort(handle); // Hatch style 2 bytes + + int style; + if (msStyle == PS_DOT) + style = wxDOT; + else if (msStyle == PS_DASH) + style = wxSHORT_DASH; + else if (msStyle == PS_NULL) + style = wxTRANSPARENT; + else style = wxSOLID; + + wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref)); + rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(&colour, wxSOLID); + */ + break; + } + case META_CREATEBITMAPINDIRECT: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEBITMAP: + { + /* + fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle); + */ + break; + } + case META_CREATEREGION: + { + dc->DestroyClippingRegion(); + /* + rec->param1 = getshort(handle); // Style: 2 bytes + */ + break; + } + default: + { + break; + } + } + node = node->GetNext(); + } + return TRUE; +} + diff --git a/ogl/module.mk b/ogl/module.mk new file mode 100644 index 0000000..d83b850 --- /dev/null +++ b/ogl/module.mk @@ -0,0 +1,30 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/ogl/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + ogl/basic.cpp \ + ogl/bmpshape.cpp \ + ogl/composit.cpp \ + ogl/divided.cpp \ + ogl/lines.cpp \ + ogl/oglmisc.cpp \ + ogl/basic2.cpp \ + ogl/canvas.cpp \ + ogl/constrnt.cpp \ + ogl/drawn.cpp \ + ogl/mfutils.cpp \ + ogl/ogldiag.cpp + +EXTRA_DIST += \ + ogl/module.mk \ + ogl/README + + diff --git a/ogl/ogldiag.cpp b/ogl/ogldiag.cpp new file mode 100644 index 0000000..6719469 --- /dev/null +++ b/ogl/ogldiag.cpp @@ -0,0 +1,736 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// ogldiag.cpp - wxDiagram +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +IMPLEMENT_DYNAMIC_CLASS(wxDiagram, wxObject) + +// Object canvas +wxDiagram::wxDiagram() +{ + m_diagramCanvas = NULL; + m_quickEditMode = FALSE; + m_snapToGrid = TRUE; + m_gridSpacing = 5.0; + m_shapeList = new wxList; + m_mouseTolerance = DEFAULT_MOUSE_TOLERANCE; +} + +wxDiagram::~wxDiagram() +{ + if (m_shapeList) + delete m_shapeList; +} + +void wxDiagram::SetSnapToGrid(bool snap) +{ + m_snapToGrid = snap; +} + +void wxDiagram::SetGridSpacing(double spacing) +{ + m_gridSpacing = spacing; +} + +void wxDiagram::Snap(double *x, double *y) +{ + if (m_snapToGrid) + { + *x = m_gridSpacing * ((int)(*x / m_gridSpacing + 0.5)); + *y = m_gridSpacing * ((int)(*y / m_gridSpacing + 0.5)); + } +} + + +void wxDiagram::Redraw(wxDC &dc) +{ + if (m_shapeList) + { + if (GetCanvas()) + GetCanvas()->SetCursor(* wxHOURGLASS_CURSOR); + wxNode *current = m_shapeList->GetFirst(); + + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + if (!object->GetParent()) + object->Draw(dc); + + current = current->GetNext(); + } + if (GetCanvas()) + GetCanvas()->SetCursor(* wxSTANDARD_CURSOR); + } +} + +void wxDiagram::Clear(wxDC &dc) +{ + dc.Clear(); +} + +// Insert object after addAfter, or at end of list. +void wxDiagram::AddShape(wxShape *object, wxShape *addAfter) +{ + wxNode *nodeAfter = NULL; + + + if (addAfter) + { +#if wxCHECK_VERSION(2, 9, 0) + nodeAfter = m_shapeList->Find(addAfter); +#else + nodeAfter = m_shapeList->Member(addAfter); +#endif + } + + if (!m_shapeList->Member(object)) + { + if (nodeAfter) + { + if (nodeAfter->GetNext()) + m_shapeList->Insert(nodeAfter->GetNext(), object); + else + m_shapeList->Append(object); + } + else + m_shapeList->Append(object); + object->SetCanvas(GetCanvas()); + } +} + +void wxDiagram::InsertShape(wxShape *object) +{ + m_shapeList->Insert(object); + object->SetCanvas(GetCanvas()); +} + +void wxDiagram::RemoveShape(wxShape *object) +{ + m_shapeList->DeleteObject(object); + object->RemoveChildren(); +} + +// Should this delete the actual objects too? I think not. +void wxDiagram::RemoveAllShapes() +{ + m_shapeList->Clear(); +} + +void wxDiagram::DeleteAllShapes() +{ + wxNode *node = m_shapeList->GetFirst(); + while (node) + { + wxShape *shape = (wxShape *)node->GetData(); + if (!shape->GetParent()) + { + RemoveShape(shape); + delete shape; + node = m_shapeList->GetFirst(); + } + else + node = node->GetNext(); + } +} + +void wxDiagram::ShowAll(bool show) +{ + wxNode *current = m_shapeList->GetFirst(); + + while (current) + { + wxShape *object = (wxShape *)current->GetData(); + object->Show(show); + + current = current->GetNext(); + } +} + +void wxDiagram::DrawOutline(wxDC &dc, double x1, double y1, double x2, double y2) +{ + wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT); + dc.SetPen(dottedPen); + dc.SetBrush((* wxTRANSPARENT_BRUSH)); + + wxPoint points[5]; + + points[0].x = (int) x1; + points[0].y = (int) y1; + + points[1].x = (int) x2; + points[1].y = (int) y1; + + points[2].x = (int) x2; + points[2].y = (int) y2; + + points[3].x = (int) x1; + points[3].y = (int) y2; + + points[4].x = (int) x1; + points[4].y = (int) y1; + dc.DrawLines(5, points); +} + +// Make sure all text that should be centred, is centred. +void wxDiagram::RecentreAll(wxDC &dc) +{ + wxNode *object_node = m_shapeList->GetFirst(); + while (object_node) + { + wxShape *obj = (wxShape *)object_node->GetData(); + obj->Recentre(dc); + object_node = object_node->GetNext(); + } +} + +// Input/output +#if wxUSE_PROLOGIO +bool wxDiagram::SaveFile(const wxString &filename) +{ + wxBeginBusyCursor(); + + wxExprDatabase *database = new wxExprDatabase; + + // First write the diagram type + wxExpr *header = new wxExpr(wxT("diagram")); + OnHeaderSave(*database, *header); + + database->Append(header); + + wxNode *node = m_shapeList->GetFirst(); + while (node) + { + wxShape *shape = (wxShape *)node->GetData(); + + if (!shape->IsKindOf(CLASSINFO(wxControlPoint))) + { + wxExpr *expr; + if (shape->IsKindOf(CLASSINFO(wxLineShape))) + expr = new wxExpr(wxT("line")); + else + expr = new wxExpr(wxT("shape")); + + OnShapeSave(*database, *shape, *expr); + } + node = node->GetNext(); + } + OnDatabaseSave(*database); + + wxString tempFile; + wxGetTempFileName(wxT("diag"), tempFile); + FILE *file = fopen(tempFile.mb_str(wxConvFile), "w"); + if (! file) + { + wxEndBusyCursor(); + delete database; + return FALSE; + } + + database->Write(file); + fclose(file); + delete database; + + /* + // Save backup + if (FileExists(filename)) + { + char buf[400]; + #ifdef __X__ + sprintf(buf, "%s.bak", filename); + #endif + #ifdef __WXMSW__ + sprintf(buf, "_diagram.bak"); + #endif + if (FileExists(buf)) wxRemoveFile(buf); + if (!wxRenameFile(filename, buf)) + { + wxCopyFile(filename, buf); + wxRemoveFile(filename); + } + } + */ + + // Copy the temporary file to the correct filename + if (!wxRenameFile(tempFile, filename)) + { + wxCopyFile(tempFile, filename); + wxRemoveFile(tempFile); + } + + wxEndBusyCursor(); + return TRUE; +} + +bool wxDiagram::LoadFile(const wxString &filename) +{ + wxBeginBusyCursor(); + + wxExprDatabase database(wxExprInteger, wxT("id")); + if (!database.Read(filename)) + { + wxEndBusyCursor(); + return FALSE; + } + + DeleteAllShapes(); + + database.BeginFind(); + wxExpr *header = database.FindClauseByFunctor(wxT("diagram")); + + if (header) + OnHeaderLoad(database, *header); + + // Scan through all clauses and register the ids + wxNode *node = database.GetFirst(); + while (node) + { + wxExpr *clause = (wxExpr *)node->GetData(); + long id = -1; + clause->GetAttributeValue(wxT("id"), id); + wxRegisterId(id); + node = node->GetNext(); + } + + ReadNodes(database); + ReadContainerGeometry(database); + ReadLines(database); + + OnDatabaseLoad(database); + + wxEndBusyCursor(); + + return TRUE; +} + +void wxDiagram::ReadNodes(wxExprDatabase &database) +{ + // Find and create the node images + database.BeginFind(); + wxExpr *clause = database.FindClauseByFunctor(wxT("shape")); + while (clause) + { + wxChar *type = NULL; + long parentId = -1; + + clause->AssignAttributeValue(wxT("type"), &type); + clause->AssignAttributeValue(wxT("parent"), &parentId); + wxClassInfo *classInfo = wxClassInfo::FindClass(type); + if (classInfo) + { + wxShape *shape = (wxShape *)classInfo->CreateObject(); + OnShapeLoad(database, *shape, *clause); + + shape->SetCanvas(GetCanvas()); + shape->Show(TRUE); + + m_shapeList->Append(shape); + + // If child of composite, link up + if (parentId > -1) + { + wxExpr *parentExpr = database.HashFind(wxT("shape"), parentId); + if (parentExpr && parentExpr->GetClientData()) + { + wxShape *parent = (wxShape *)parentExpr->GetClientData(); + shape->SetParent(parent); + parent->GetChildren().Append(shape); + } + } + + clause->SetClientData(shape); + } + if (type) + delete[] type; + + clause = database.FindClauseByFunctor(wxT("shape")); + } + return; +} + +void wxDiagram::ReadLines(wxExprDatabase &database) +{ + database.BeginFind(); + wxExpr *clause = database.FindClauseByFunctor(wxT("line")); + while (clause) + { + wxString type; + long parentId = -1; + + clause->GetAttributeValue(wxT("type"), type); + clause->GetAttributeValue(wxT("parent"), parentId); + wxClassInfo *classInfo = wxClassInfo::FindClass(type); + if (classInfo) + { + wxLineShape *shape = (wxLineShape *)classInfo->CreateObject(); + shape->Show(TRUE); + + OnShapeLoad(database, *shape, *clause); + shape->SetCanvas(GetCanvas()); + + long image_to = -1; + long image_from = -1; + clause->GetAttributeValue(wxT("to"), image_to); + clause->GetAttributeValue(wxT("from"), image_from); + + wxExpr *image_to_expr = database.HashFind(wxT("shape"), image_to); + + if (!image_to_expr) + { + // Error + } + wxExpr *image_from_expr = database.HashFind(wxT("shape"), image_from); + + if (!image_from_expr) + { + // Error + } + + if (image_to_expr && image_from_expr) + { + wxShape *image_to_object = (wxShape *)image_to_expr->GetClientData(); + wxShape *image_from_object = (wxShape *)image_from_expr->GetClientData(); + + if (image_to_object && image_from_object) + { + image_from_object->AddLine(shape, image_to_object, shape->GetAttachmentFrom(), shape->GetAttachmentTo()); + } + } + clause->SetClientData(shape); + + m_shapeList->Append(shape); + } + + clause = database.FindClauseByFunctor(wxT("line")); + } +} + +// Containers have divisions that reference adjoining divisions, +// so we need a separate pass to link everything up. +// Also used by Symbol Library. +void wxDiagram::ReadContainerGeometry(wxExprDatabase &database) +{ + database.BeginFind(); + wxExpr *clause = database.FindClauseByFunctor(wxT("shape")); + while (clause) + { + wxShape *image = (wxShape *)clause->GetClientData(); + if (image && image->IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxCompositeShape *composite = (wxCompositeShape *)image; + wxExpr *divisionExpr = NULL; + + // Find the list of divisions in the composite + clause->GetAttributeValue(wxT("divisions"), &divisionExpr); + if (divisionExpr) + { + int i = 0; + wxExpr *idExpr = divisionExpr->Nth(i); + while (idExpr) + { + long divisionId = idExpr->IntegerValue(); + wxExpr *childExpr = database.HashFind(wxT("shape"), divisionId); + if (childExpr && childExpr->GetClientData()) + { + wxDivisionShape *child = (wxDivisionShape *)childExpr->GetClientData(); + composite->GetDivisions().Append(child); + + // Find the adjoining shapes + long leftSideId = -1; + long topSideId = -1; + long rightSideId = -1; + long bottomSideId = -1; + childExpr->GetAttributeValue(wxT("left_side"), leftSideId); + childExpr->GetAttributeValue(wxT("top_side"), topSideId); + childExpr->GetAttributeValue(wxT("right_side"), rightSideId); + childExpr->GetAttributeValue(wxT("bottom_side"), bottomSideId); + if (leftSideId > -1) + { + wxExpr *leftExpr = database.HashFind(wxT("shape"), leftSideId); + if (leftExpr && leftExpr->GetClientData()) + { + wxDivisionShape *leftSide = (wxDivisionShape *)leftExpr->GetClientData(); + child->SetLeftSide(leftSide); + } + } + if (topSideId > -1) + { + wxExpr *topExpr = database.HashFind(wxT("shape"), topSideId); + if (topExpr && topExpr->GetClientData()) + { + wxDivisionShape *topSide = (wxDivisionShape *)topExpr->GetClientData(); + child->SetTopSide(topSide); + } + } + if (rightSideId > -1) + { + wxExpr *rightExpr = database.HashFind(wxT("shape"), rightSideId); + if (rightExpr && rightExpr->GetClientData()) + { + wxDivisionShape *rightSide = (wxDivisionShape *)rightExpr->GetClientData(); + child->SetRightSide(rightSide); + } + } + if (bottomSideId > -1) + { + wxExpr *bottomExpr = database.HashFind(wxT("shape"), bottomSideId); + if (bottomExpr && bottomExpr->GetClientData()) + { + wxDivisionShape *bottomSide = (wxDivisionShape *)bottomExpr->GetClientData(); + child->SetBottomSide(bottomSide); + } + } + } + i ++; + idExpr = divisionExpr->Nth(i); + } + } + } + + clause = database.FindClauseByFunctor(wxT("shape")); + } +} + +// Allow for modifying file +bool wxDiagram::OnDatabaseLoad(wxExprDatabase &WXUNUSED(db)) +{ + return TRUE; +} + +bool wxDiagram::OnDatabaseSave(wxExprDatabase &WXUNUSED(db)) +{ + return TRUE; +} + +bool wxDiagram::OnShapeSave(wxExprDatabase &db, wxShape &shape, wxExpr &expr) +{ + shape.WriteAttributes(&expr); + db.Append(&expr); + + if (shape.IsKindOf(CLASSINFO(wxCompositeShape))) + { + wxNode *node = shape.GetChildren().GetFirst(); + while (node) + { + wxShape *childShape = (wxShape *)node->GetData(); + wxExpr *childExpr = new wxExpr(wxT("shape")); + OnShapeSave(db, *childShape, *childExpr); + node = node->GetNext(); + } + } + + return TRUE; +} + +bool wxDiagram::OnShapeLoad(wxExprDatabase &WXUNUSED(db), wxShape &shape, wxExpr &expr) +{ + shape.ReadAttributes(&expr); + return TRUE; +} + +bool wxDiagram::OnHeaderSave(wxExprDatabase &WXUNUSED(db), wxExpr &WXUNUSED(expr)) +{ + return TRUE; +} + +bool wxDiagram::OnHeaderLoad(wxExprDatabase &WXUNUSED(db), wxExpr &WXUNUSED(expr)) +{ + return TRUE; +} + +#endif + +void wxDiagram::SetCanvas(wxShapeCanvas *can) +{ + m_diagramCanvas = can; +} + +// Find a shape by its id +wxShape *wxDiagram::FindShape(long id) const +{ + wxNode *node = GetShapeList()->GetFirst(); + while (node) + { + wxShape *shape = (wxShape *) node->GetData(); + if (shape->GetId() == id) + return shape; + node = node->GetNext(); + } + return NULL; +} + + +//// Crossings classes + +wxLineCrossings::wxLineCrossings() +{ +} + +wxLineCrossings::~wxLineCrossings() +{ + ClearCrossings(); +} + +void wxLineCrossings::FindCrossings(wxDiagram &diagram) +{ + ClearCrossings(); + wxNode *node1 = diagram.GetShapeList()->GetFirst(); + while (node1) + { + wxShape *shape1 = (wxShape *) node1->GetData(); + if (shape1->IsKindOf(CLASSINFO(wxLineShape))) + { + wxLineShape *lineShape1 = (wxLineShape *) shape1; + // Iterate through the segments + wxList *pts1 = lineShape1->GetLineControlPoints(); + size_t i; + for (i = 0; i < (pts1->GetCount() - 1); i++) + { + wxRealPoint *pt1_a = (wxRealPoint *) (pts1->Item(i)->GetData()); + wxRealPoint *pt1_b = (wxRealPoint *) (pts1->Item(i + 1)->GetData()); + + // Now we iterate through the segments again + + wxNode *node2 = diagram.GetShapeList()->GetFirst(); + while (node2) + { + wxShape *shape2 = (wxShape *) node2->GetData(); + + // Assume that the same line doesn't cross itself + if (shape2->IsKindOf(CLASSINFO(wxLineShape)) && (shape1 != shape2)) + { + wxLineShape *lineShape2 = (wxLineShape *) shape2; + // Iterate through the segments + wxList *pts2 = lineShape2->GetLineControlPoints(); + int j; + for (j = 0; j < (int) (pts2->GetCount() - 1); j++) + { + wxRealPoint *pt2_a = (wxRealPoint *) (pts2->Item(j)->GetData()); + wxRealPoint *pt2_b = (wxRealPoint *) (pts2->Item(j + 1)->GetData()); + + // Now let's see if these two segments cross. + double ratio1, ratio2; + oglCheckLineIntersection(pt1_a->x, pt1_a->y, pt1_b->x, pt1_b->y, + pt2_a->x, pt2_a->y, pt2_b->x, pt2_b->y, + & ratio1, & ratio2); + + if ((ratio1 < 1.0) && (ratio1 > -1.0)) + { + // Intersection! + wxLineCrossing *crossing = new wxLineCrossing; + crossing->m_intersect.x = (pt1_a->x + (pt1_b->x - pt1_a->x) * ratio1); + crossing->m_intersect.y = (pt1_a->y + (pt1_b->y - pt1_a->y) * ratio1); + + crossing->m_pt1 = * pt1_a; + crossing->m_pt2 = * pt1_b; + crossing->m_pt3 = * pt2_a; + crossing->m_pt4 = * pt2_b; + + crossing->m_lineShape1 = lineShape1; + crossing->m_lineShape2 = lineShape2; + + m_crossings.Append(crossing); + } + } + } + node2 = node2->GetNext(); + } + } + } + + node1 = node1->GetNext(); + } +} + +void wxLineCrossings::DrawCrossings(wxDiagram &WXUNUSED(diagram), wxDC &dc) +{ + dc.SetBrush(*wxTRANSPARENT_BRUSH); + + long arcWidth = 8; + + wxNode *node = m_crossings.GetFirst(); + while (node) + { + wxLineCrossing *crossing = (wxLineCrossing *) node->GetData(); +// dc.DrawEllipse((long) (crossing->m_intersect.x - (arcWidth/2.0) + 0.5), (long) (crossing->m_intersect.y - (arcWidth/2.0) + 0.5), +// arcWidth, arcWidth); + + + // Let's do some geometry to find the points on either end of the arc. + /* + + (x1, y1) + |\ + | \ + | \ + | \ + | \ + | |\ c c1 + | a | \ + | \ + | - x <-- centre of arc + a1 | b |\ + | | \ c2 + | a2 | \ + | - \ + | b2 \ + | \ + |_______________\ (x2, y2) + b1 + + */ + + double a1 = wxMax(crossing->m_pt1.y, crossing->m_pt2.y) - wxMin(crossing->m_pt1.y, crossing->m_pt2.y) ; + double b1 = wxMax(crossing->m_pt1.x, crossing->m_pt2.x) - wxMin(crossing->m_pt1.x, crossing->m_pt2.x) ; + double c1 = sqrt( (a1 * a1) + (b1 * b1) ); + + double c = arcWidth / 2.0; + double a = c * a1 / c1 ; + double b = c * b1 / c1 ; + + // I'm not sure this is right, since we don't know which direction we should be going in - need + // to know which way the line slopes and choose the sign appropriately. + double arcX1 = crossing->m_intersect.x - b; + double arcY1 = crossing->m_intersect.y - a; + + double arcX2 = crossing->m_intersect.x + b; + double arcY2 = crossing->m_intersect.y + a; + + dc.SetPen(*wxBLACK_PEN); + dc.DrawArc( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2, + (long) crossing->m_intersect.x, (long) crossing->m_intersect.y); + + dc.SetPen(*wxWHITE_PEN); + dc.DrawLine( (long) arcX1, (long) arcY1, (long) arcX2, (long) arcY2 ); + + node = node->GetNext(); + } +} + +void wxLineCrossings::ClearCrossings() +{ + wxNode *node = m_crossings.GetFirst(); + while (node) + { + wxLineCrossing *crossing = (wxLineCrossing *) node->GetData(); + delete crossing; + node = node->GetNext(); + } + m_crossings.Clear(); +} + diff --git a/ogl/oglmisc.cpp b/ogl/oglmisc.cpp new file mode 100644 index 0000000..fa932bd --- /dev/null +++ b/ogl/oglmisc.cpp @@ -0,0 +1,911 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Portions Copyright (C) 1998 - 2011, Julian Smart +// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.cpp - Miscellaneous OGL support functions +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include +#include +#include + +#include "ogl/ogl.h" + + +wxFont *g_oglNormalFont; +wxPen *g_oglBlackPen; +wxPen *g_oglWhiteBackgroundPen; +wxPen *g_oglTransparentPen; +wxBrush *g_oglWhiteBackgroundBrush; +wxPen *g_oglBlackForegroundPen; +wxCursor *g_oglBullseyeCursor = NULL; + +wxChar *oglBuffer = NULL; + +wxList oglObjectCopyMapping(wxKEY_INTEGER); + + + +void wxOGLInitialize() +{ + g_oglBullseyeCursor = new wxCursor(wxCURSOR_BULLSEYE); + + g_oglNormalFont = new wxFont(10, wxSWISS, wxNORMAL, wxNORMAL); + + g_oglBlackPen = new wxPen(wxT("BLACK"), 1, wxSOLID); + + g_oglWhiteBackgroundPen = new wxPen(wxT("WHITE"), 1, wxSOLID); + g_oglTransparentPen = new wxPen(wxT("WHITE"), 1, wxTRANSPARENT); + g_oglWhiteBackgroundBrush = new wxBrush(wxT("WHITE"), wxSOLID); + g_oglBlackForegroundPen = new wxPen(wxT("BLACK"), 1, wxSOLID); + + OGLInitializeConstraintTypes(); + + // Initialize big buffer used when writing images + oglBuffer = new wxChar[3000]; + +} + +void wxOGLCleanUp() +{ + if (oglBuffer) + { + delete[] oglBuffer; + oglBuffer = NULL; + } + oglBuffer = NULL; + + if (g_oglBullseyeCursor) + { + delete g_oglBullseyeCursor; + g_oglBullseyeCursor = NULL; + } + + if (g_oglNormalFont) + { + delete g_oglNormalFont; + g_oglNormalFont = NULL; + } + if (g_oglBlackPen) + { + delete g_oglBlackPen; + g_oglBlackPen = NULL; + } + if (g_oglWhiteBackgroundPen) + { + delete g_oglWhiteBackgroundPen; + g_oglWhiteBackgroundPen = NULL; + } + if (g_oglTransparentPen) + { + delete g_oglTransparentPen; + g_oglTransparentPen = NULL; + } + if (g_oglWhiteBackgroundBrush) + { + delete g_oglWhiteBackgroundBrush; + g_oglWhiteBackgroundBrush = NULL; + } + if (g_oglBlackForegroundPen) + { + delete g_oglBlackForegroundPen; + g_oglBlackForegroundPen = NULL; + } + + OGLCleanUpConstraintTypes(); +} + +wxFont *oglMatchFont(int point_size) +{ + wxFont *font = wxTheFontList->FindOrCreateFont(point_size, wxSWISS, wxNORMAL, wxNORMAL); +#if 0 + switch (point_size) + { + case 4: + font = swiss_font_4; + break; + case 6: + font = swiss_font_6; + break; + case 8: + font = swiss_font_8; + break; + case 12: + font = swiss_font_12; + break; + case 14: + font = swiss_font_14; + break; + case 18: + font = swiss_font_18; + break; + case 24: + font = swiss_font_24; + break; + default: + case 10: + font = swiss_font_10; + break; + } +#endif + return font; +} + +int FontSizeDialog(wxFrame *parent, int old_size) +{ + if (old_size <= 0) + old_size = 10; + wxString buf; + buf << old_size; + wxString ans = wxGetTextFromUser(wxT("Enter point size"), wxT("Font size"), buf, parent); + if (ans.Length() == 0) + return 0; + + long new_size = 0; + ans.ToLong(&new_size); + if ((new_size <= 0) || (new_size > 40)) + { + wxMessageBox(wxT("Invalid point size!"), wxT("Error"), wxOK); + return 0; + } + return new_size; + /* + char *strings[8]; + strings[0] = "4"; + strings[1] = "6"; + strings[2] = "8"; + strings[3] = "10"; + strings[4] = "12"; + strings[5] = "14"; + strings[6] = "18"; + strings[7] = "24"; + char *ans = wxGetSingleChoice("Choose", "Choose a font size", 8, strings, parent); + if (ans) + { + int size; + sscanf(ans, "%d", &size); + return oglMatchFont(size); + } + else return NULL; + */ +} + +// Centre a list of strings in the given box. xOffset and yOffset are the +// the positions that these lines should be relative to, and this might be +// the same as m_xpos, m_ypos, but might be zero if formatting from left-justifying. +void oglCentreText(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + int formatMode) +{ + int n = text_list->GetCount(); + + if (!text_list || (n == 0)) + return; + + // First, get maximum dimensions of box enclosing text +#if wxCHECK_VERSION(2, 9, 0) + wxCoord char_height = 0; + wxCoord max_width = 0; + wxCoord current_width = 0; +#else + long char_height = 0; + long max_width = 0; + long current_width = 0; +#endif + + // Store text extents for speed + double *widths = new double[n]; + + wxNode *current = text_list->GetFirst(); + int i = 0; + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + dc.GetTextExtent(line->GetText(), ¤t_width, &char_height); + widths[i] = current_width; + + if (current_width > max_width) + max_width = current_width; + current = current->GetNext(); + i ++; + } + + double max_height = n * char_height; + + double xoffset, yoffset, xOffset, yOffset; + + if (formatMode & FORMAT_CENTRE_VERT) + { + if (max_height < height) + yoffset = (double)(m_ypos - (height / 2.0) + (height - max_height) / 2.0); + else + yoffset = (double)(m_ypos - (height / 2.0)); + yOffset = m_ypos; + } + else + { + yoffset = 0.0; + yOffset = 0.0; + } + + if (formatMode & FORMAT_CENTRE_HORIZ) + { + xoffset = (double)(m_xpos - width / 2.0); + xOffset = m_xpos; + } + else + { + xoffset = 0.0; + xOffset = 0.0; + } + + current = text_list->GetFirst(); + i = 0; + + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + + double x; + if ((formatMode & FORMAT_CENTRE_HORIZ) && (widths[i] < width)) + x = (double)((width - widths[i]) / 2.0 + xoffset); + else + x = xoffset; + double y = (double)(i * char_height + yoffset); + + line->SetX( x - xOffset ); + line->SetY( y - yOffset ); + current = current->GetNext(); + i ++; + } + + delete[] widths; +} + +// Centre a list of strings in the given box +void oglCentreTextNoClipping(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height) +{ + int n = text_list->GetCount(); + + if (!text_list || (n == 0)) + return; + + // First, get maximum dimensions of box enclosing text + +#if wxCHECK_VERSION(2, 9, 0) + wxCoord char_height = 0; + wxCoord max_width = 0; + wxCoord current_width = 0; +#else + long char_height = 0; + long max_width = 0; + long current_width = 0; +#endif + + // Store text extents for speed + double *widths = new double[n]; + + wxNode *current = text_list->GetFirst(); + int i = 0; + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + dc.GetTextExtent(line->GetText(), ¤t_width, &char_height); + widths[i] = current_width; + + if (current_width > max_width) + max_width = current_width; + current = current->GetNext(); + i ++; + } + + double max_height = n * char_height; + + double yoffset = (double)(m_ypos - (height / 2.0) + (height - max_height) / 2.0); + + double xoffset = (double)(m_xpos - width / 2.0); + + current = text_list->GetFirst(); + i = 0; + + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + + double x = (double)((width - widths[i]) / 2.0 + xoffset); + double y = (double)(i * char_height + yoffset); + + line->SetX( x - m_xpos ); + line->SetY( y - m_ypos ); + current = current->GetNext(); + i ++; + } + delete[] widths; +} + +void oglGetCentredTextExtent(wxDC &dc, wxList *text_list, + double WXUNUSED(m_xpos), double WXUNUSED(m_ypos), double WXUNUSED(width), double WXUNUSED(height), + double *actual_width, double *actual_height) +{ + int n = text_list->GetCount(); + + if (!text_list || (n == 0)) + { + *actual_width = 0; + *actual_height = 0; + return; + } + + // First, get maximum dimensions of box enclosing text +#if wxCHECK_VERSION(2, 9, 0) + wxCoord char_height = 0; + wxCoord max_width = 0; + wxCoord current_width = 0; +#else + long char_height = 0; + long max_width = 0; + long current_width = 0; +#endif + + wxNode *current = text_list->GetFirst(); + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + dc.GetTextExtent(line->GetText(), ¤t_width, &char_height); + + if (current_width > max_width) + max_width = current_width; + current = current->GetNext(); + } + + *actual_height = n * char_height; + *actual_width = max_width; +} + +// Format a string to a list of strings that fit in the given box. +// Interpret %n and 10 or 13 as a new line. +wxArrayString *oglFormatText(wxDC &dc, const wxString &text, double width, double WXUNUSED(height), int formatMode) +{ + // First, parse the string into a list of words + wxArrayString word_list; + + // Make new lines into NULL strings at this point + int i = 0; + int len = text.Length(); + wxString word; + // word.Alloc(30); // Seems to be a bug in string allocation that causes assertion when first appending + bool end_word = FALSE; + bool new_line = FALSE; + while (i < len) + { + switch ((wxChar)text[i]) + { + case wxT('%'): + { + i ++; + if (i == len) + { + word += wxT('%'); + } + else + { + if (text[i] == wxT('n')) + { + new_line = TRUE; + end_word = TRUE; + i++; + } + else + { + word += wxT('%'); + word += text[i]; + i ++; + } + } + break; + } + case 10: + { + new_line = TRUE; + end_word = TRUE; + i++; + break; + } + case 13: + { + new_line = TRUE; + end_word = TRUE; + i++; + } + case wxT(' '): + { + end_word = TRUE; + i ++; + break; + } + default: + { + word += text[i]; + i ++; + break; + } + } + if (i == len) end_word = TRUE; + if (end_word) + { + word_list.Add(word); + word.Empty(); + end_word = FALSE; + } + if (new_line) + { + word_list.Add(wxT("\n")); + new_line = FALSE; + } + } + // Now, make a list of strings which can fit in the box + wxArrayString *string_list = new wxArrayString ; + + wxString buffer; + +#if wxCHECK_VERSION(2, 9, 0) + wxCoord x, y; +#else + long x, y; +#endif + + size_t k; + for (k = 0; k < word_list.GetCount(); k++) + { + wxString oldBuffer(buffer); + + const wxString &s = word_list[k]; + if (s == wxT("\n")) + { + // FORCE NEW LINE + // if (buffer.Length() > 0) + string_list->Add(buffer); + + buffer.Empty(); + } + else + { + if (buffer.Length() != 0) + buffer += wxT(" "); + + buffer += s; + dc.GetTextExtent(buffer, &x, &y); + + // Don't fit within the bounding box if we're fitting shape to contents + if ((x > width) && !(formatMode & FORMAT_SIZE_TO_CONTENTS)) + { + // Deal with first word being wider than box + if (oldBuffer.Length() > 0) + string_list->Add(oldBuffer); + + buffer.Empty(); + buffer += s; + } + } + } + + if (buffer.Length() != 0) + string_list->Add(buffer); + + return string_list; +} + +void oglDrawFormattedText(wxDC &dc, wxList *text_list, + double m_xpos, double m_ypos, double width, double height, + int formatMode) +{ + double xoffset, yoffset; + if (formatMode & FORMAT_CENTRE_HORIZ) + xoffset = m_xpos; + else + xoffset = (double)(m_xpos - (width / 2.0)); + + if (formatMode & FORMAT_CENTRE_VERT) + yoffset = m_ypos; + else + yoffset = (double)(m_ypos - (height / 2.0)); + + dc.SetClippingRegion( + (long)(m_xpos - width / 2.0), (long)(m_ypos - height / 2.0), + (long)width + 1, (long)height + 1); + + wxNode *current = text_list->GetFirst(); + while (current) + { + wxShapeTextLine *line = (wxShapeTextLine *)current->GetData(); + + dc.DrawText(line->GetText(), WXROUND(xoffset + line->GetX()), WXROUND(yoffset + line->GetY())); + current = current->GetNext(); + } + + dc.DestroyClippingRegion(); +} + +/* + * Find centroid given list of points comprising polyline + * + */ + +void oglFindPolylineCentroid(wxList *points, double *x, double *y) +{ + double xcount = 0; + double ycount = 0; + + wxNode *node = points->GetFirst(); + while (node) + { + wxRealPoint *point = (wxRealPoint *)node->GetData(); + xcount += point->x; + ycount += point->y; + node = node->GetNext(); + } + + *x = (xcount / points->GetCount()); + *y = (ycount / points->GetCount()); +} + +/* + * Check that (x1, y1) -> (x2, y2) hits (x3, y3) -> (x4, y4). + * If so, ratio1 gives the proportion along the first line + * that the intersection occurs (or something like that). + * Used by functions below. + * + */ +void oglCheckLineIntersection(double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4, + double *ratio1, double *ratio2) +{ + double denominator_term = (y4 - y3) * (x2 - x1) - (y2 - y1) * (x4 - x3); + double numerator_term = (x3 - x1) * (y4 - y3) + (x4 - x3) * (y1 - y3); + + double line_constant; + double length_ratio = 1.0; + double k_line = 1.0; + + // Check for parallel lines + if ((denominator_term < 0.005) && (denominator_term > -0.005)) + line_constant = -1.0; + else + line_constant = numerator_term / denominator_term; + + // Check for intersection + if ((line_constant < 1.0) && (line_constant > 0.0)) + { + // Now must check that other line hits + if (((y4 - y3) < 0.005) && ((y4 - y3) > -0.005)) + k_line = ((x1 - x3) + line_constant * (x2 - x1)) / (x4 - x3); + else + k_line = ((y1 - y3) + line_constant * (y2 - y1)) / (y4 - y3); + + if ((k_line >= 0.0) && (k_line < 1.0)) + length_ratio = line_constant; + else + k_line = 1.0; + } + *ratio1 = length_ratio; + *ratio2 = k_line; +} + +/* + * Find where (x1, y1) -> (x2, y2) hits one of the lines in xvec, yvec. + * (*x3, *y3) is the point where it hits. + * + */ +void oglFindEndForPolyline(double n, double xvec[], double yvec[], + double x1, double y1, double x2, double y2, double *x3, double *y3) +{ + int i; + double lastx = xvec[0]; + double lasty = yvec[0]; + + double min_ratio = 1.0; + double line_ratio; + double other_ratio; + + for (i = 1; i < n; i++) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i], + &line_ratio, &other_ratio); + lastx = xvec[i]; + lasty = yvec[i]; + + if (line_ratio < min_ratio) + min_ratio = line_ratio; + } + + // Do last (implicit) line if last and first doubles are not identical + if (!(xvec[0] == lastx && yvec[0] == lasty)) + { + oglCheckLineIntersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0], + &line_ratio, &other_ratio); + + if (line_ratio < min_ratio) + min_ratio = line_ratio; + } + + *x3 = (x1 + (x2 - x1) * min_ratio); + *y3 = (y1 + (y2 - y1) * min_ratio); + +} + +/* + * Find where the line hits the box. + * + */ + +void oglFindEndForBox(double width, double height, + double x1, double y1, // Centre of box (possibly) + double x2, double y2, // other end of line + double *x3, double *y3) // End on box edge +{ + double xvec[5]; + double yvec[5]; + + xvec[0] = (double)(x1 - width / 2.0); + yvec[0] = (double)(y1 - height / 2.0); + xvec[1] = (double)(x1 - width / 2.0); + yvec[1] = (double)(y1 + height / 2.0); + xvec[2] = (double)(x1 + width / 2.0); + yvec[2] = (double)(y1 + height / 2.0); + xvec[3] = (double)(x1 + width / 2.0); + yvec[3] = (double)(y1 - height / 2.0); + xvec[4] = (double)(x1 - width / 2.0); + yvec[4] = (double)(y1 - height / 2.0); + + oglFindEndForPolyline(5, xvec, yvec, x2, y2, x1, y1, x3, y3); +} + +/* + * Find where the line hits the circle. + * + */ + +void oglFindEndForCircle(double radius, + double x1, double y1, // Centre of circle + double x2, double y2, // Other end of line + double *x3, double *y3) +{ + double H = (double)sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + if (H == 0.0) + { + *x3 = x1; + *y3 = y1; + } + else + { + *y3 = radius * (y2 - y1) / H + y1; + *x3 = radius * (x2 - x1) / H + x1; + } +} + +/* + * Given the line (x1, y1) -> (x2, y2), and an arrow size of given length and width, + * return the position of the tip of the arrow and the left and right vertices of the arrow. + * + */ + +void oglGetArrowPoints(double x1, double y1, double x2, double y2, + double length, double width, + double *tip_x, double *tip_y, + double *side1_x, double *side1_y, + double *side2_x, double *side2_y) +{ + double l = (double)sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); + + if (l < 0.01) + l = (double) 0.01; + + double i_bar = (x2 - x1) / l; + double j_bar = (y2 - y1) / l; + + double x3 = (- length * i_bar) + x2; + double y3 = (- length * j_bar) + y2; + + *side1_x = width * (-j_bar) + x3; + *side1_y = width * i_bar + y3; + + *side2_x = -width * (-j_bar) + x3; + *side2_y = -width * i_bar + y3; + + *tip_x = x2; + *tip_y = y2; +} + +/* + * Given an ellipse and endpoints of a line, returns the point at which + * the line touches the ellipse in values x4, y4. + * This function assumes that the centre of the ellipse is at x1, y1, and the + * ellipse has a width of width1 and a height of height1. It also assumes you are + * wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3. + * This function calculates the x,y coordinates of the intersection point of + * the arc with the ellipse. + * Author: Ian Harrison + */ + +void oglDrawArcToEllipse(double x1, double y1, double width1, double height1, double x2, double y2, double x3, double y3, + double *x4, double *y4) +{ + double a1 = (double)(width1 / 2.0); + double b1 = (double)(height1 / 2.0); + + // These are required to give top left x and y coordinates for DrawEllipse +// double top_left_x1 = (double)(x1 - a1); +// double top_left_y1 = (double)(y1 - b1); + /* + // Check for vertical line + if (fabs(x2 - x3) < 0.05) + { + *x4 = x3; + if (y2 < y3) + *y4 = (double)(y1 - b1); + else + *y4 = (double)(y1 + b1); + return; + } + */ + // Check that x2 != x3 + if (fabs(x2 - x3) < 0.05) + { + *x4 = x2; + if (y3 > y2) + *y4 = (double)(y1 - sqrt((b1 * b1 - (((x2 - x1) * (x2 - x1)) * (b1 * b1) / (a1 * a1))))); + else + *y4 = (double)(y1 + sqrt((b1 * b1 - (((x2 - x1) * (x2 - x1)) * (b1 * b1) / (a1 * a1))))); + return; + } + + // Calculate the x and y coordinates of the point where arc intersects ellipse + + double A, B, C, D, E, F, G, H, K; + double ellipse1_x, ellipse1_y; + + A = (double)(1 / (a1 * a1)); + B = (double)((y3 - y2) * (y3 - y2)) / ((x3 - x2) * (x3 - x2) * b1 * b1); + C = (double)(2 * (y3 - y2) * (y2 - y1)) / ((x3 - x2) * b1 * b1); + D = (double)((y2 - y1) * (y2 - y1)) / (b1 * b1); + E = (double)(A + B); + F = (double)(C - (2 * A * x1) - (2 * B * x2)); + G = (double)((A * x1 * x1) + (B * x2 * x2) - (C * x2) + D - 1); + H = (double)((y3 - y2) / (x3 - x2)); + K = (double)((F * F) - (4 * E * G)); + + if (K >= 0) + // In this case the line intersects the ellipse, so calculate intersection + { + if(x2 >= x1) + { + ellipse1_x = (double)(((F * -1) + sqrt(K)) / (2 * E)); + ellipse1_y = (double)((H * (ellipse1_x - x2)) + y2); + } + else + { + ellipse1_x = (double)(((F * -1) - sqrt(K)) / (2 * E)); + ellipse1_y = (double)((H * (ellipse1_x - x2)) + y2); + } + } + else + // in this case, arc does not intersect ellipse, so just draw arc + { + ellipse1_x = x3; + ellipse1_y = y3; + } + *x4 = ellipse1_x; + *y4 = ellipse1_y; + + /* + // Draw a little circle (radius = 2) at the end of the arc where it hits + // the ellipse . + + double circle_x = ellipse1_x - 2.0; + double circle_y = ellipse1_y - 2.0; + m_canvas->DrawEllipse(circle_x, circle_y, 4.0, 4.0); + */ +} + +// Update a list item from a list of strings +void UpdateListBox(wxListBox *item, wxList *list) +{ + item->Clear(); + if (!list) + return; + + wxNode *node = list->GetFirst(); + while (node) + { + wxChar *s = (wxChar *)node->GetData(); + item->Append(s); + node = node->GetNext(); + } +} + +bool oglRoughlyEqual(double val1, double val2, double tol) +{ + return ( (val1 < (val2 + tol)) && (val1 > (val2 - tol)) && + (val2 < (val1 + tol)) && (val2 > (val1 - tol))); +} + +/* + * Hex<->Dec conversion + */ + +// Array used in DecToHex conversion routine. +static wxChar sg_HexArray[] = { wxT('0'), wxT('1'), wxT('2'), wxT('3'), + wxT('4'), wxT('5'), wxT('6'), wxT('7'), + wxT('8'), wxT('9'), wxT('A'), wxT('B'), + wxT('C'), wxT('D'), wxT('E'), wxT('F') + }; + +// Convert 2-digit hex number to decimal +unsigned int oglHexToDec(wxChar *buf) +{ + int firstDigit, secondDigit; + + if (buf[0] >= wxT('A')) + firstDigit = buf[0] - wxT('A') + 10; + else + firstDigit = buf[0] - wxT('0'); + + if (buf[1] >= wxT('A')) + secondDigit = buf[1] - wxT('A') + 10; + else + secondDigit = buf[1] - wxT('0'); + + return firstDigit * 16 + secondDigit; +} + +// Convert decimal integer to 2-character hex string +void oglDecToHex(unsigned int dec, wxChar *buf) +{ + int firstDigit = (int)(dec / 16.0); + int secondDigit = (int)(dec - (firstDigit * 16.0)); + buf[0] = sg_HexArray[firstDigit]; + buf[1] = sg_HexArray[secondDigit]; + buf[2] = 0; +} + +// 3-digit hex to wxColour +wxColour oglHexToColour(const wxString &hex) +{ + if (hex.Length() == 6) + { + long r, g, b; + r = g = b = 0; + hex.Mid(0, 2).ToLong(&r, 16); + hex.Mid(2, 2).ToLong(&g, 16); + hex.Mid(4, 2).ToLong(&b, 16); + return wxColour(r, g, b); + } + else + return wxColour(0, 0, 0); +} + +// RGB to 3-digit hex +wxString oglColourToHex(const wxColour &colour) +{ + wxChar buf[7]; + unsigned int red = colour.Red(); + unsigned int green = colour.Green(); + unsigned int blue = colour.Blue(); + + oglDecToHex(red, buf); + oglDecToHex(green, buf + 2); + oglDecToHex(blue, buf + 4); + + return wxString(buf); +} + + diff --git a/pgAdmin3.cpp b/pgAdmin3.cpp new file mode 100644 index 0000000..0bac68c --- /dev/null +++ b/pgAdmin3.cpp @@ -0,0 +1,2047 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAdmin3.cpp - The application +// +////////////////////////////////////////////////////////////////////////// +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// wxOGL +#include + +// Windows headers +#ifdef __WXMSW__ +#include +#endif + +// Linux headers +#ifdef __LINUX__ +#include +#endif + +#ifdef __WXGTK__ +#include +#endif + +// App headers +#include "copyright.h" +#include "version.h" +#include "utils/misc.h" +#include "utils/sysSettings.h" +#include "schema/pgServer.h" +#include "frm/frmMain.h" +#include "frm/frmConfig.h" +#include "frm/frmQuery.h" +#include "frm/frmStatus.h" +#ifdef DATABASEDESIGNER +#include "frm/frmDatabaseDesigner.h" +#endif +#include "frm/frmSplash.h" +#include "dlg/dlgSelectConnection.h" +#include "db/pgConn.h" +#include "utils/sysLogger.h" +#include "utils/registry.h" +#include "frm/frmHint.h" + +#include "ctl/xh_calb.h" +#include "ctl/xh_timespin.h" +#include "ctl/xh_sqlbox.h" +#include "ctl/xh_ctlcombo.h" +#include "ctl/xh_ctltree.h" +#include "ctl/xh_ctlchecktreeview.h" +#include "ctl/xh_ctlcolourpicker.h" + +#define DOC_DIR wxT("/docs") +#define UI_DIR wxT("/ui") +#define I18N_DIR wxT("/i18n") +#define BRANDING_DIR wxT("/branding") +#define PLUGINS_DIR wxT("/plugins.d") +#define SETTINGS_INI wxT("/settings.ini") + +// Globals +frmMain *winMain = 0; +wxThread *updateThread = 0; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#include "utils/sshTunnel.h" +CSSHTunnelThread *pgadminTunnelThread = 0; +#endif + +sysSettings *settings; +wxArrayInt existingLangs; +wxArrayString existingLangNames; +wxLocale *locale = 0; +pgAppearanceFactory *appearanceFactory = 0; + +wxString pgBackupExecutable; // complete filename of PostgreSQL's pg_dump, pg_dumpall and pg_restore, if available +wxString pgBackupAllExecutable; +wxString pgRestoreExecutable; + +wxString edbBackupExecutable; // complete filename of EnterpriseDB's pg_dump, pg_dumpall and pg_restore, if available +wxString edbBackupAllExecutable; +wxString edbRestoreExecutable; + +wxString gpBackupExecutable; // complete filename of Greenplum's pg_dump, pg_dumpall and pg_restore, if available +wxString gpBackupAllExecutable; +wxString gpRestoreExecutable; + +wxString loadPath; // Where the program is loaded from +wxString dataDir; // The program data directory +wxString docPath; // Where docs are stored +wxString uiPath; // Where ui data is stored +wxString i18nPath; // Where i18n data is stored +wxString brandingPath; // Where branding data is stored +wxString pluginsDir; // The plugins ini file directory +wxString settingsIni; // The settings.ini file + +wxLog *logger; + +bool dialogTestMode = false; + +#define LANG_FILE wxT("pgadmin3.lng") + +IMPLEMENT_APP(pgAdmin3) + +#ifdef __WXMSW__ +// Dynamically loaded EDB functions +PQGETOUTRESULT PQiGetOutResult; +PQPREPAREOUT PQiPrepareOut; +PQSENDQUERYPREPAREDOUT PQiSendQueryPreparedOut; +#endif + +#ifdef __WXGTK__ + +class pgRendererNative : public wxDelegateRendererNative +{ +public: + pgRendererNative() : wxDelegateRendererNative(wxRendererNative::GetDefault()) {} + + void DrawTreeItemButton(wxWindow *win, wxDC &dc, const wxRect &rect, int flags) + { + GetGeneric().DrawTreeItemButton(win, dc, rect, flags); + } +}; + +#endif +#define CTL_LB 100 +class frmDlgTest : public wxFrame +{ +public: + frmDlgTest(); +private: + void OnSelect(wxCommandEvent &ev); + wxListBox *dlgList; + DECLARE_EVENT_TABLE() +}; + + +BEGIN_EVENT_TABLE(frmDlgTest, wxFrame) + EVT_LISTBOX_DCLICK(CTL_LB, frmDlgTest::OnSelect) +END_EVENT_TABLE(); + + +frmDlgTest::frmDlgTest() : wxFrame(0, -1, wxT("pgAdmin III Translation test mode")) +{ + dlgList = new wxListBox(this, CTL_LB, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_SORT); + + // unfortunately, the MemoryFS has no search functions implemented + // so we can't extract the names in the EMBED_XRC case + + wxDir dir(uiPath); + wxString filename; + + bool found = dir.GetFirst(&filename, wxT("*.xrc")); + while (found) + { + dlgList->Append(filename.Left(filename.Length() - 4)); + found = dir.GetNext(&filename); + } + if (!dlgList->GetCount()) + { + dlgList->Append(wxT("No xrc files in directory")); + dlgList->Append(uiPath); + dlgList->Disable(); + } +} + + +void frmDlgTest::OnSelect(wxCommandEvent &ev) +{ + wxString dlgName = dlgList->GetStringSelection(); + if (!dlgName.IsEmpty()) + { + pgDialog *dlg = new pgDialog; + dlg->SetFont(settings->GetSystemFont()); + dlg->LoadResource(this, dlgName); + dlg->SetTitle(dlgName); + dlg->Show(); + } +} + + +// The Application! +bool pgAdmin3::OnInit() +{ + // Force logging off until we're ready + wxLog *seLog = new wxLogStderr(); + wxLog::SetActiveTarget(seLog); + + // Setup the basic paths for the app installation. Required by settings! + InitAppPaths(); + + // Load the Settings +#ifdef __WXMSW__ + settings = new sysSettings(wxT("pgAdmin III")); +#else + settings = new sysSettings(wxT("pgadmin3")); +#endif + + // Setup additional helper paths etc. Requires settings! + InitXtraPaths(); + + locale = new wxLocale(); + locale->AddCatalogLookupPathPrefix(i18nPath); + + wxLanguage langId = (wxLanguage)settings->Read(wxT("LanguageId"), wxLANGUAGE_DEFAULT); + if (locale->Init(langId)) + { +#ifdef __LINUX__ + { + wxLogNull noLog; + locale->AddCatalog(wxT("fileutils")); + } +#endif + locale->AddCatalog(wxT("pgadmin3")); + } + +#ifdef DATABASEDESIGNER + //Initialize Font + hdFontAttribute::InitFont(); +#endif + + long langCount = 0; + const wxLanguageInfo *langInfo; + + wxString langfile = FileRead(i18nPath + wxT("/") LANG_FILE, 1); + + if (!langfile.IsEmpty()) + { + wxStringTokenizer tk(langfile, wxT("\n\r")); + + while (tk.HasMoreTokens()) + { + wxString line = tk.GetNextToken().Strip(wxString::both); + if (line.IsEmpty() || line.StartsWith(wxT("#"))) + continue; + + wxString englishName = line.BeforeFirst(',').Trim(true); + wxString translatedName = line.AfterFirst(',').Trim(false); + + langInfo = wxLocale::FindLanguageInfo(englishName); + if (langInfo) + { + if (langInfo->CanonicalName == wxT("en_US") || + (!langInfo->CanonicalName.IsEmpty() && + wxDir::Exists(i18nPath + wxT("/") + langInfo->CanonicalName))) + { + existingLangs.Add(langInfo->Language); + existingLangNames.Add(translatedName); + langCount++; + } + } + } + } + + static const wxCmdLineEntryDesc cmdLineDesc[] = + { +#if wxCHECK_VERSION(2, 9, 0) + // wxCmdLineEntryDesc is one of the few places in 2.9 where wxT()s have any effect...they break the build + {wxCMD_LINE_SWITCH, "v", "version", _("show the version, and quit"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_SWITCH, "h", "help", _("show this help message, and quit"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, + {wxCMD_LINE_OPTION, "s", "server", _("auto-connect to specified server"), wxCMD_LINE_VAL_STRING}, + {wxCMD_LINE_SWITCH, "S", "serverstatus", _("open server status window"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_OPTION, "Sc", "serverstatusconnect", _("connect server status window to database"), wxCMD_LINE_VAL_STRING}, + {wxCMD_LINE_SWITCH, "q", "query", _("open query tool"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_OPTION, "qc", "queryconnect", _("connect query tool to database"), wxCMD_LINE_VAL_STRING}, +#ifdef DATABASEDESIGNER + {wxCMD_LINE_SWITCH, "d", "designer", _("open designer window"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_OPTION, "dc", "designerconnectconnect", _("connect designer window to database"), wxCMD_LINE_VAL_STRING}, +#endif + {wxCMD_LINE_OPTION, "f", "file", _("file to load into the query tool in -q or -qc mode"), wxCMD_LINE_VAL_STRING}, + {wxCMD_LINE_OPTION, "cm", NULL, _("edit main configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_OPTION, "ch", NULL, _("edit HBA configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_OPTION, "cp", NULL, _("edit pgpass configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_OPTION, "c", NULL, _("edit configuration files in cluster directory"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_SWITCH, "t", NULL, _("dialog translation test mode"), wxCMD_LINE_VAL_NONE}, +#else + {wxCMD_LINE_SWITCH, wxT("v"), wxT("version"), _("show the version, and quit"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_SWITCH, wxT("h"), wxT("help"), _("show the help message, and quit"), wxCMD_LINE_VAL_NONE, wxCMD_LINE_OPTION_HELP }, + {wxCMD_LINE_OPTION, wxT("s"), wxT("server"), _("auto-connect to specified server"), wxCMD_LINE_VAL_STRING}, + {wxCMD_LINE_SWITCH, wxT("S"), wxT("serverstatus"), _("open server status window"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_OPTION, wxT("Sc"), wxT("serverstatusconnect"), _("connect server status window to database"), wxCMD_LINE_VAL_STRING}, + {wxCMD_LINE_SWITCH, wxT("q"), wxT("query"), _("open query tool"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_OPTION, wxT("qc"), wxT("queryconnect"), _("connect query tool to database"), wxCMD_LINE_VAL_STRING}, +#ifdef DATABASEDESIGNER + {wxCMD_LINE_SWITCH, wxT("d"), wxT("designer"), _("open designer window"), wxCMD_LINE_VAL_NONE}, + {wxCMD_LINE_OPTION, wxT("dc"), wxT("designerconnectconnect"), _("connect designer window to database"), wxCMD_LINE_VAL_STRING}, +#endif + {wxCMD_LINE_OPTION, wxT("f"), wxT("file"), _("file to load into the query tool in -q or -qc mode"), wxCMD_LINE_VAL_STRING}, + {wxCMD_LINE_OPTION, wxT("cm"), NULL, _("edit main configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_OPTION, wxT("ch"), NULL, _("edit HBA configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_OPTION, wxT("cp"), NULL, _("edit pgpass configuration file"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_OPTION, wxT("c"), NULL, _("edit configuration files in cluster directory"), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_MULTIPLE}, + {wxCMD_LINE_SWITCH, wxT("t"), NULL, _("dialog translation test mode"), wxCMD_LINE_VAL_NONE}, +#endif + {wxCMD_LINE_NONE} + + }; + + frmConfig::tryMode configMode = frmConfig::NONE; + wxString configFile; + + wxCmdLineParser cmdParser(cmdLineDesc, argc, argv); + if (cmdParser.Parse() != 0) + return false; + + if ( + (cmdParser.Found(wxT("q")) && cmdParser.Found(wxT("qc"))) + || (cmdParser.Found(wxT("S")) && cmdParser.Found(wxT("Sc"))) +#ifdef DATABASEDESIGNER + || (cmdParser.Found(wxT("d")) && cmdParser.Found(wxT("dc"))) +#endif + ) + { + cmdParser.Usage(); + return false; + } + + if (cmdParser.Found(wxT("cm"), &configFile)) + configMode = frmConfig::MAINFILE; + else if (cmdParser.Found(wxT("ch"), &configFile)) + configMode = frmConfig::HBAFILE; + else if (cmdParser.Found(wxT("cp"), &configFile)) + configMode = frmConfig::PGPASSFILE; + else if (cmdParser.Found(wxT("c"), &configFile)) + configMode = frmConfig::ANYFILE; + + if (cmdParser.Found(wxT("t"))) + dialogTestMode = true; + + // Setup the image handlers and appearance factory before we do any GUI or config stuff + ::wxInitAllImageHandlers(); + + appearanceFactory = new pgAppearanceFactory(); + + if (cmdParser.Found(wxT("v"))) + { + wxPrintf(wxT("%s %s\n"), appearanceFactory->GetLongAppName().c_str(), VERSION_STR); + return false; + } + + // Setup logging + InitLogger(); + + wxString msg; + msg << wxT("# ") << appearanceFactory->GetLongAppName() << wxT(" Version ") << VERSION_STR << wxT(" Startup"); + wxLogInfo(wxT("##############################################################")); + wxLogInfo(wxT("%s"), msg.c_str()); + wxLogInfo(wxT("##############################################################")); + +#ifdef PG_SSL + wxLogInfo(wxT("Compiled with dynamically linked SSL support")); +#endif + +#ifdef __WXDEBUG__ + wxLogInfo(wxT("Running a DEBUG build.")); +#else + wxLogInfo(wxT("Running a RELEASE build.")); +#endif + + // Log the path info + wxLogInfo(wxT("i18n path : %s"), i18nPath.c_str()); + wxLogInfo(wxT("UI path : %s"), uiPath.c_str()); + wxLogInfo(wxT("Doc path : %s"), docPath.c_str()); + wxLogInfo(wxT("Branding path : %s"), brandingPath.c_str()); + wxLogInfo(wxT("Plugins path : %s"), pluginsDir.c_str()); + wxLogInfo(wxT("Settings INI : %s"), settingsIni.c_str()); + + wxLogInfo(wxT("PG pg_dump : %s"), pgBackupExecutable.c_str()); + wxLogInfo(wxT("PG pg_dumpall : %s"), pgBackupAllExecutable.c_str()); + wxLogInfo(wxT("PG pg_restore : %s"), pgRestoreExecutable.c_str()); + + wxLogInfo(wxT("EDB pg_dump : %s"), edbBackupExecutable.c_str()); + wxLogInfo(wxT("EDB pg_dumpall: %s"), edbBackupAllExecutable.c_str()); + wxLogInfo(wxT("EDB pg_restore: %s"), edbRestoreExecutable.c_str()); + + wxLogInfo(wxT("Greenplum pg_dump : %s"), gpBackupExecutable.c_str()); + wxLogInfo(wxT("Greenplum pg_dumpall: %s"), gpBackupAllExecutable.c_str()); + wxLogInfo(wxT("Greenplum pg_restore: %s"), gpRestoreExecutable.c_str()); + +#ifdef __WXGTK__ + static pgRendererNative *renderer = new pgRendererNative(); + wxRendererNative::Get(); + wxRendererNative::Set(renderer); +#endif + +#ifdef __LINUX__ + signal(SIGPIPE, SIG_IGN); +#endif + + // Show the splash screen + // NOTE: We must *always* do this as in -q and -qc modes + // the splash screen becomes the top level window and + // allows the logon dialogs to be displayed!! + frmSplash *winSplash = new frmSplash((wxFrame *)NULL); + if (!winSplash) + wxLogError(__("Couldn't create the splash screen!")); + else + { + SetTopWindow(winSplash); + winSplash->Show(); + winSplash->Update(); + wxTheApp->Yield(true); + } + + // Startup the windows sockets if required + InitNetwork(); + + wxFileSystem::AddHandler(new wxZipFSHandler); + + // Setup the XML resources + wxXmlResource::Get()->InitAllHandlers(); + wxXmlResource::Get()->AddHandler(new wxCalendarBoxXmlHandler); + wxXmlResource::Get()->AddHandler(new wxTimeSpinXmlHandler); + wxXmlResource::Get()->AddHandler(new ctlSQLBoxXmlHandler); + wxXmlResource::Get()->AddHandler(new ctlComboBoxXmlHandler); + wxXmlResource::Get()->AddHandler(new ctlTreeXmlHandler); + wxXmlResource::Get()->AddHandler(new ctlCheckTreeViewXmlHandler); + wxXmlResource::Get()->AddHandler(new ctlColourPickerXmlHandler); + + InitXml(); + + wxOGLInitialize(); + + // Set some defaults + SetAppName(appearanceFactory->GetLongAppName()); + + // Setup the help paths + InitHelp(); + wxLogInfo(wxT("PG Help : %s"), settings->GetPgHelpPath().c_str()); + wxLogInfo(wxT("EDB Help : %s"), settings->GetEdbHelpPath().c_str()); + wxLogInfo(wxT("Greenplum Help: %s"), settings->GetGpHelpPath().c_str()); + wxLogInfo(wxT("Slony Help : %s"), settings->GetSlonyHelpPath().c_str()); + +#ifndef __WXDEBUG__ + wxTheApp->Yield(true); + wxSleep(2); +#endif + +#ifdef __WXMSW__ + // Attempt to dynamically load PGgetOutResult from libpq. this + // is only present in EDB versions. + InitLibpq(); +#endif + + if (configMode) + { + if (configMode == frmConfig::ANYFILE && wxDir::Exists(configFile)) + { + wxLogInfo(wxT("Starting in ANYFILE config editor mode, in directory: %s"), configFile.c_str()); + frmConfig::Create(appearanceFactory->GetLongAppName(), configFile + wxT("/pg_hba.conf"), frmConfig::HBAFILE); + frmConfig::Create(appearanceFactory->GetLongAppName(), configFile + wxT("/postgresql.conf"), frmConfig::MAINFILE); + } + else + { + wxLogInfo(wxT("Starting in config editor mode, file: %s"), configFile.c_str()); + frmConfig::Create(appearanceFactory->GetLongAppName(), configFile, configMode); + } + if (winSplash) + { + winSplash->Close(); + delete winSplash; + winSplash = 0; + } + } + + else + { + if (dialogTestMode) + { + wxLogInfo(wxT("Starting in dialog test mode.")); + wxFrame *dtf = new frmDlgTest(); + dtf->Show(); + SetTopWindow(dtf); + } + + else if ((cmdParser.Found(wxT("S")) || cmdParser.Found(wxT("Sc"))) && !cmdParser.Found(wxT("s"))) + { + // -S specified, but not -s. Open the server status window but do *not* open the main window + pgConn *conn = NULL; + wxString connstr; + wxString applicationname = appearanceFactory->GetLongAppName() + _(" - Server Status"); + + if (cmdParser.Found(wxT("S"))) + { + wxLogInfo(wxT("Starting in server status mode (-S)."), configFile.c_str()); + + winSplash->Show(false); + dlgSelectConnection dlg(NULL, NULL); + dlg.CenterOnParent(); + + int rc = dlg.Go(conn, NULL); + if (rc != wxID_OK) + return false; + bool dummyRes; + conn = dlg.CreateConn(applicationname, dummyRes); + } + else if (cmdParser.Found(wxT("Sc"), &connstr)) + { + wxLogInfo(wxT("Starting in server status connect mode (-Sc)."), configFile.c_str()); + wxString host, database, username, rolename, tmps; + int sslmode = 0, port = 0; + wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK); + while (tkn.HasMoreTokens()) + { + wxString str = tkn.GetNextToken(); + if (str.StartsWith(wxT("hostaddr="), &host)) + continue; + if (str.StartsWith(wxT("host="), &host)) + continue; + if (str.StartsWith(wxT("dbname="), &database)) + continue; + if (str.StartsWith(wxT("user="), &username)) + continue; + if (str.StartsWith(wxT("role="), &rolename)) + continue; + if (str.StartsWith(wxT("port="), &tmps)) + { + port = StrToLong(tmps); + continue; + } + if (str.StartsWith(wxT("sslmode="), &tmps)) + { + if (!tmps.Cmp(wxT("require"))) + sslmode = 1; + else if (!tmps.Cmp(wxT("prefer"))) + sslmode = 2; + else if (!tmps.Cmp(wxT("allow"))) + sslmode = 3; + else if (!tmps.Cmp(wxT("disable"))) + sslmode = 4; + else if (!tmps.Cmp(wxT("verify-ca"))) + sslmode = 5; + else if (!tmps.Cmp(wxT("verify-full"))) + sslmode = 6; + else + { + wxMessageBox(_("Unknown SSL mode: ") + tmps); + return false; + } + continue; + } + wxMessageBox(_("Unknown token in connection string: ") + str); + return false; + } + winSplash->Show(false); + dlgSelectConnection dlg(NULL, NULL); + dlg.CenterOnParent(); + conn = dlg.CreateConn(host, database, username, port, rolename, sslmode, applicationname); + } + else + { + /* Can't happen.. */ + return false; + } + if (!conn) + return false; + + wxString txt = _("Server Status - ") + conn->GetName(); + frmStatus *fq = new frmStatus(NULL, txt, conn); + fq->Go(); + } + +#ifdef DATABASEDESIGNER + else if ((cmdParser.Found(wxT("d")) || cmdParser.Found(wxT("dc"))) && !cmdParser.Found(wxT("s"))) + { + // -d specified, but not -s. Open the designer window but do *not* open the main window + pgConn *conn = NULL; + wxString connstr; + wxString applicationname = _("pgAdmin - Database designer"); + + if (cmdParser.Found(wxT("d"))) + { + wxLogInfo(wxT("Starting in designer mode (-d)."), configFile.c_str()); + + winSplash->Show(false); + dlgSelectConnection dlg(NULL, NULL); + dlg.CenterOnParent(); + + int rc = dlg.Go(conn, NULL); + if (rc != wxID_OK) + return false; + bool dummyRes; + conn = dlg.CreateConn(applicationname, dummyRes); + } + else if (cmdParser.Found(wxT("dc"), &connstr)) + { + wxLogInfo(wxT("Starting in database designer connect mode (-dc)."), configFile.c_str()); + wxString host, database, username, rolename, tmps; + int sslmode = 0, port = 0; + wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK); + while (tkn.HasMoreTokens()) + { + wxString str = tkn.GetNextToken(); + if (str.StartsWith(wxT("hostaddr="), &host)) + continue; + if (str.StartsWith(wxT("host="), &host)) + continue; + if (str.StartsWith(wxT("dbname="), &database)) + continue; + if (str.StartsWith(wxT("user="), &username)) + continue; + if (str.StartsWith(wxT("role="), &rolename)) + continue; + if (str.StartsWith(wxT("port="), &tmps)) + { + port = StrToLong(tmps); + continue; + } + if (str.StartsWith(wxT("sslmode="), &tmps)) + { + if (!tmps.Cmp(wxT("require"))) + sslmode = 1; + else if (!tmps.Cmp(wxT("prefer"))) + sslmode = 2; + else if (!tmps.Cmp(wxT("allow"))) + sslmode = 3; + else if (!tmps.Cmp(wxT("disable"))) + sslmode = 4; + else if (!tmps.Cmp(wxT("verify-ca"))) + sslmode = 5; + else if (!tmps.Cmp(wxT("verify-full"))) + sslmode = 6; + else + { + wxMessageBox(_("Unknown SSL mode: ") + tmps); + return false; + } + continue; + } + wxMessageBox(_("Unknown token in connection string: ") + str); + return false; + } + winSplash->Show(false); + dlgSelectConnection dlg(NULL, NULL); + dlg.CenterOnParent(); + conn = dlg.CreateConn(host, database, username, port, rolename, sslmode, applicationname); + } + else + { + /* Can't happen.. */ + return false; + } + if (!conn) + return false; + + frmDatabaseDesigner *fq = new frmDatabaseDesigner(NULL, wxEmptyString, conn); + fq->Go(); + } +#endif + +#ifdef __WXMAC__ + else if (((cmdParser.Found(wxT("q")) || cmdParser.Found(wxT("qc"))) && !cmdParser.Found(wxT("s"))) || !macFileToOpen.IsEmpty()) +#else + else if ((cmdParser.Found(wxT("q")) || cmdParser.Found(wxT("qc"))) && !cmdParser.Found(wxT("s"))) +#endif + { + // -q specified, but not -s. Open a query tool but do *not* open the main window + pgConn *conn = NULL; + wxString connstr; + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Query Tool"); + +#ifdef __WXMAC__ + if (cmdParser.Found(wxT("q")) || !macFileToOpen.IsEmpty()) +#else + if (cmdParser.Found(wxT("q"))) +#endif + { + wxLogInfo(wxT("Starting in query tool mode (-q)."), configFile.c_str()); + + winSplash->Show(false); + dlgSelectConnection dlg(NULL, NULL); + dlg.CenterOnParent(); + + int rc = dlg.Go(conn, NULL); + if (rc != wxID_OK) + return false; + bool dummyRes; + conn = dlg.CreateConn(applicationname, dummyRes); + } + else if (cmdParser.Found(wxT("qc"), &connstr)) + { + wxLogInfo(wxT("Starting in query tool connect mode (-qc)."), configFile.c_str()); + wxString host, database, username, rolename, tmps; + int sslmode = 0, port = 0; + wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK); + while (tkn.HasMoreTokens()) + { + wxString str = tkn.GetNextToken(); + if (str.StartsWith(wxT("hostaddr="), &host)) + continue; + if (str.StartsWith(wxT("host="), &host)) + continue; + if (str.StartsWith(wxT("dbname="), &database)) + continue; + if (str.StartsWith(wxT("user="), &username)) + continue; + if (str.StartsWith(wxT("role="), &rolename)) + continue; + if (str.StartsWith(wxT("port="), &tmps)) + { + port = StrToLong(tmps); + continue; + } + if (str.StartsWith(wxT("sslmode="), &tmps)) + { + if (!tmps.Cmp(wxT("require"))) + sslmode = 1; + else if (!tmps.Cmp(wxT("prefer"))) + sslmode = 2; + else if (!tmps.Cmp(wxT("allow"))) + sslmode = 3; + else if (!tmps.Cmp(wxT("disable"))) + sslmode = 4; + else if (!tmps.Cmp(wxT("verify-ca"))) + sslmode = 5; + else if (!tmps.Cmp(wxT("verify-full"))) + sslmode = 6; + else + { + wxMessageBox(_("Unknown SSL mode: ") + tmps); + return false; + } + continue; + } + wxMessageBox(_("Unknown token in connection string: ") + str); + return false; + } + winSplash->Show(false); + dlgSelectConnection dlg(NULL, NULL); + dlg.CenterOnParent(); + conn = dlg.CreateConn(host, database, username, port, rolename, sslmode, applicationname); + } + else + { + /* Can't happen.. */ + return false; + } + if (!conn) + return false; + + wxString fn; +#ifdef __WXMAC__ + if (!macFileToOpen.IsEmpty()) + { + wxLogInfo(wxT("Mac file launch: %s."), macFileToOpen.c_str()); + fn = macFileToOpen; + } + else + cmdParser.Found(wxT("f"), &fn); +#else + cmdParser.Found(wxT("f"), &fn); +#endif + if (!fn.IsEmpty()) + { + wxLogInfo(wxT("Auto-loading file: %s"), fn.c_str()); + } + frmQuery *fq = new frmQuery(NULL, wxEmptyString, conn, wxEmptyString, fn); + fq->Go(); + } + else + { + // Create & show the main form + winMain = new frmMain(appearanceFactory->GetLongAppName()); + + if (!winMain) + wxLogFatalError(__("Couldn't create the main window!")); + + winMain->Show(); + SetTopWindow(winMain); + + wxString str; + if (cmdParser.Found(wxT("s"), &str)) + { + pgServer *srv = winMain->ConnectToServer(str, !cmdParser.Found(wxT("q"))); + if (srv && cmdParser.Found(wxT("q"))) + { + pgConn *conn; + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Query Tool"); + conn = srv->CreateConn(wxEmptyString, 0, applicationname); + if (conn) + { + wxString fn; + cmdParser.Found(wxT("f"), &fn); + if (!fn.IsEmpty()) + { + wxLogInfo(wxT("Auto-loading file: %s"), fn.c_str()); + } + frmQuery *fq = new frmQuery(winMain, wxEmptyString, conn, wxEmptyString, fn); + fq->Go(); + winMain->AddFrame(fq); + } + } + } + } + + SetExitOnFrameDelete(true); + + if (winSplash) + { + winSplash->Close(); + delete winSplash; + winSplash = 0; + } + } + + return true; +} + +// Not the Application! +int pgAdmin3::OnExit() +{ + if (updateThread) + { + updateThread->Delete(); + delete updateThread; + } + + // Delete the settings object to ensure settings are saved. + delete settings; + +#ifdef __WXMSW__ + WSACleanup(); +#endif + + wxTheClipboard->Flush(); + + return 1; +} + +// On the Mac, this function is called before Init, if the finder launches the app +// via a registered filetype. Grab the filename here, and test for it in Init. +#ifdef __WXMAC__ +void pgAdmin3::MacOpenFile(const wxString &fileName) +{ + macFileToOpen = fileName; +} +#endif + +// Setup the paths for the application itself +void pgAdmin3::InitAppPaths() +{ + i18nPath = LocatePath(I18N_DIR, false); + docPath = LocatePath(DOC_DIR, false); + uiPath = LocatePath(UI_DIR, false); + brandingPath = LocatePath(BRANDING_DIR, false); + pluginsDir = LocatePath(PLUGINS_DIR, false); + settingsIni = LocatePath(SETTINGS_INI, true); +} + +// Setup the paths for the helper apps etc. +void pgAdmin3::InitXtraPaths() +{ + ////////////////////////////////// + // Now setup the app helper paths + ////////////////////////////////// + + // Windows-only path prefixes +#ifdef __WXMSW__ + wxString programFiles = wxGetenv(wxT("ProgramFiles")); + wxString programFilesX86 = wxGetenv(wxT("ProgramFiles(x86)")); + + // If we install a 32-bit pgAdmin in a 64-bit machine, + // We will be getting the both values as "Drive:\Program Files(x86)". + // Since, all 32-bit applications return "ProgramFiles" as ProgramFiles(x86). + // In that case, we need can get the actual programFiles value, + // by reading the key "ProgramFilesDir" in location "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion". + // + if (::wxIsPlatform64Bit() && programFiles == programFilesX86) + { + // Don't want to lost the exisisting behaviour. + // + wxString tmp = programFiles; + programFiles = wxEmptyString; + + pgRegKey::PGREGWOWMODE wowMode = pgRegKey::PGREG_WOW64; + pgRegKey *pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"), pgRegKey::PGREG_READ, wowMode); + + if (!(pgKey && pgKey->QueryValue(wxT("ProgramFilesDir"), programFiles))) + { + programFiles = tmp; + } + + if(pgKey) + { + delete pgKey; + pgKey = NULL; + } + } +#endif + + // First, check and invalidate the paths if they're no good. +#ifdef __WXMSW__ + if (!isPgApp(settings->GetPostgresqlPath() + wxT("\\pg_dump.exe"))) + settings->SetPostgresqlPath(wxEmptyString); + + if (!isEdbApp(settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"))) + settings->SetEnterprisedbPath(wxEmptyString); + + if (!isGpApp(settings->GetGPDBPath() + wxT("\\pg_dump.exe"))) + settings->SetGPDBPath(wxEmptyString); +#else + if (!isPgApp(settings->GetPostgresqlPath() + wxT("/pg_dump"))) + settings->SetPostgresqlPath(wxEmptyString); + + if (!isEdbApp(settings->GetEnterprisedbPath() + wxT("/pg_dump"))) + settings->SetEnterprisedbPath(wxEmptyString); + + if (!isGpApp(settings->GetGPDBPath() + wxT("/pg_dump"))) + settings->SetGPDBPath(wxEmptyString); +#endif + + // Now, if either path is empty, start a search for helpers + // If we find apps, record the appropriate path *only* if it's + // not already set + if (settings->GetPostgresqlPath().IsEmpty() || settings->GetEnterprisedbPath().IsEmpty()) + { + wxPathList path; + + // Look in the app directory for things first + path.Add(loadPath); + +#ifdef __WXMSW__ + + // Look for a path 'hint' on Windows. This registry setting may + // be set by the Win32 PostgreSQL installer which will generally + // install pg_dump et al. in the PostgreSQL bindir rather than + // the pgAdmin directory. + wxRegKey hintKey(wxT("HKEY_LOCAL_MACHINE\\Software\\pgAdmin III")); + if (hintKey.HasValue(wxT("Helper Path"))) + { + wxString hintPath; + hintKey.QueryValue(wxT("Helper Path"), hintPath); + path.Add(hintPath); + } + +#else +#ifdef __WXMAC__ + + if (wxDir::Exists(dataDir)) + path.Add(dataDir) ; + +#endif +#endif + + path.AddEnvList(wxT("PATH")); + +#ifdef __WXMSW__ + wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe")); +#else + wxFileName tmp = path.FindValidPath(wxT("pg_dump")); +#endif + + if (tmp.FileExists()) + { + if (isPgApp(tmp.GetFullPath()) && settings->GetPostgresqlPath().IsEmpty()) + settings->SetPostgresqlPath(tmp.GetPath()); + else if (isEdbApp(tmp.GetFullPath()) && settings->GetEnterprisedbPath().IsEmpty()) + settings->SetEnterprisedbPath(tmp.GetPath()); + + } + } + + if (settings->GetGPDBPath().IsEmpty()) + { + wxPathList path; + +#ifdef __WXMSW__ + + wxString GPhint = wxString(getenv( "GPHOME_CLIENTS" ), wxConvUTF8 ); + + if (GPhint.Length() > 1) + { + path.Add(GPhint + wxT("\\bin")); + path.Add(GPhint + wxT("\\lib")); + path.Add(GPhint); + } + + GPhint = wxString(getenv( "GPHOME" ), wxConvUTF8 ); + + if (GPhint.Length() > 1) + { + path.Add(GPhint + wxT("\\bin")); + path.Add(GPhint + wxT("\\lib")); + path.Add(GPhint); + } + +#endif + // Look in the app directory for things + path.Add(loadPath); + +#ifdef __WXMAC__ + + if (wxDir::Exists(dataDir)) + path.Add(dataDir) ; +#endif + path.AddEnvList(wxT("PATH")); + +#ifdef __WXMSW__ + wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe")); +#else + wxFileName tmp = path.FindValidPath(wxT("pg_dump")); +#endif + + if (tmp.FileExists()) + { + if (isGpApp(tmp.GetFullPath()) && settings->GetGPDBPath().IsEmpty()) + settings->SetGPDBPath(tmp.GetPath()); + } + } + + // Now, if either path is still empty, try a less intelligent search for each + + // PostgreSQL + if (settings->GetPostgresqlPath().IsEmpty()) + { + wxPathList path; + +#ifdef __WXMSW__ + path.Add(wxT("C:\\PostgresPlus\\8.3\\bin")); + + if (!programFiles.IsEmpty()) + { + path.Add(programFiles + wxT("\\PostgreSQL\\9.5\\bin")); + path.Add(programFiles + wxT("\\PostgreSQL\\9.4\\bin")); + path.Add(programFiles + wxT("\\PostgreSQL\\9.3\\bin")); + path.Add(programFiles + wxT("\\PostgreSQL\\9.2\\bin")); + path.Add(programFiles + wxT("\\PostgreSQL\\9.1\\bin")); + path.Add(programFiles + wxT("\\PostgreSQL\\9.0\\bin")); + path.Add(programFiles + wxT("\\PostgreSQL\\8.4\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\9.0SS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\8.4SS\\bin")); + } + + if (!programFilesX86.IsEmpty()) + { + path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.5\\bin")); + path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.4\\bin")); + path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.3\\bin")); + path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.2\\bin")); + path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.1\\bin")); + path.Add(programFilesX86 + wxT("\\PostgreSQL\\9.0\\bin")); + path.Add(programFilesX86 + wxT("\\PostgreSQL\\8.4\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.0SS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\8.4SS\\bin")); + } + + wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe")); +#else + // Mac paths + path.Add(wxT("/Library/PostgreSQL/9.5/bin")); + path.Add(wxT("/Library/PostgreSQL/9.4/bin")); + path.Add(wxT("/Library/PostgreSQL/9.3/bin")); + path.Add(wxT("/Library/PostgreSQL/9.2/bin")); + path.Add(wxT("/Library/PostgreSQL/9.1/bin")); + path.Add(wxT("/Library/PostgreSQL/9.0/bin")); + path.Add(wxT("/Library/PostgreSQL/8.4/bin")); + path.Add(wxT("/Library/PostgresPlus/9.0SS/bin")); + path.Add(wxT("/Library/PostgresPlus/8.4SS/bin")); + + // Generic Unix paths + path.Add(wxT("/opt/PostgreSQL/9.5/bin")); + path.Add(wxT("/opt/PostgreSQL/9.4/bin")); + path.Add(wxT("/opt/PostgreSQL/9.3/bin")); + path.Add(wxT("/opt/PostgreSQL/9.2/bin")); + path.Add(wxT("/opt/PostgreSQL/9.1/bin")); + path.Add(wxT("/opt/PostgreSQL/9.0/bin")); + path.Add(wxT("/opt/PostgreSQL/8.4/bin")); + path.Add(wxT("/opt/PostgresPlus/9.0SS/bin")); + path.Add(wxT("/opt/PostgresPlus/8.4SS/bin")); + path.Add(wxT("/usr/local/pgsql/bin")); + path.Add(wxT("/usr/local/bin")); + path.Add(wxT("/usr/bin")); + path.Add(wxT("/opt/local/pgsql/bin")); + path.Add(wxT("/opt/local/bin")); + path.Add(wxT("/opt/bin")); + + wxFileName tmp = path.FindValidPath(wxT("pg_dump")); +#endif + + if (tmp.FileExists()) + { + if (isPgApp(tmp.GetFullPath())) + settings->SetPostgresqlPath(tmp.GetPath()); + } + } + + // EnterpriseDB + if (settings->GetEnterprisedbPath().IsEmpty()) + { + wxPathList path; + +#ifdef __WXMSW__ + if (!programFiles.IsEmpty()) + { + path.Add(programFiles + wxT("\\PostgresPlus\\9.5AS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\9.4AS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\9.3AS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\9.2AS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\9.1AS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\9.0AS\\bin")); + path.Add(programFiles + wxT("\\PostgresPlus\\8.4AS\\bin")); + } + + if (!programFilesX86.IsEmpty()) + { + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.5AS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.4AS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.3AS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.2AS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.1AS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\9.0AS\\bin")); + path.Add(programFilesX86 + wxT("\\PostgresPlus\\8.4AS\\bin")); + } + + wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe")); +#else + // Mac paths + path.Add(wxT("/Library/PostgresPlus/9.5AS/bin")); + path.Add(wxT("/Library/PostgresPlus/9.4AS/bin")); + path.Add(wxT("/Library/PostgresPlus/9.3AS/bin")); + path.Add(wxT("/Library/PostgresPlus/9.2AS/bin")); + path.Add(wxT("/Library/PostgresPlus/9.1AS/bin")); + path.Add(wxT("/Library/PostgresPlus/9.0AS/bin")); + path.Add(wxT("/Library/PostgresPlus/8.4AS/bin")); + + // Generic Unix paths + path.Add(wxT("/opt/PostgresPlus/9.5AS/bin")); + path.Add(wxT("/opt/PostgresPlus/9.4AS/bin")); + path.Add(wxT("/opt/PostgresPlus/9.3AS/bin")); + path.Add(wxT("/opt/PostgresPlus/9.2AS/bin")); + path.Add(wxT("/opt/PostgresPlus/9.1AS/bin")); + path.Add(wxT("/opt/PostgresPlus/9.0AS/bin")); + path.Add(wxT("/opt/PostgresPlus/8.4AS/bin")); + path.Add(wxT("/usr/local/enterpriseDB/bin")); + path.Add(wxT("/usr/local/enterprisedb/bin")); + path.Add(wxT("/usr/local/edb/bin")); + path.Add(wxT("/usr/local/bin")); + path.Add(wxT("/usr/bin")); + path.Add(wxT("/opt/local/enterpriseDB/bin")); + path.Add(wxT("/opt/local/enterprisedb/bin")); + path.Add(wxT("/opt/local/edb/bin")); + path.Add(wxT("/opt/local/bin")); + + wxFileName tmp = path.FindValidPath(wxT("pg_dump")); +#endif + + if (tmp.FileExists()) + { + if (isEdbApp(tmp.GetFullPath())) + settings->SetEnterprisedbPath(tmp.GetPath()); + } + } + + // Greenplum + if (settings->GetGPDBPath().IsEmpty()) + { + wxPathList path; + +#ifdef __WXMSW__ + // Ugly... Greenplum client releases have no predictable numbers, because the path is the server version + if (!programFiles.IsEmpty()) + { + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-5.0\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.4\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.3\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.2\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.1\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.0\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.3\\bin")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.2\\bin")); + + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-5.0\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.4\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.3\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.2\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.1\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-4.0\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.3\\lib")); + path.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.2\\lib")); + } + + if (!programFilesX86.IsEmpty()) + { + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-5.0\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.4\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.3\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.2\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.1\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.0\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.3\\bin")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.2\\bin")); + + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-5.0\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.4\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.3\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.2\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.1\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-4.0\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.3\\lib")); + path.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.2\\lib")); + } + + + wxFileName tmp = path.FindValidPath(wxT("pg_dump.exe")); +#else + // Mac paths + + // Generic Unix paths + + path.Add(wxT("/usr/local/greenplum-clients-5.0/bin")); + path.Add(wxT("/opt/local/greenplum-clients-5.0/bin")); + path.Add(wxT("/usr/local/greenplum-clients-4.4/bin")); + path.Add(wxT("/opt/local/greenplum-clients-4.4/bin")); + path.Add(wxT("/usr/local/greenplum-clients-4.3/bin")); + path.Add(wxT("/opt/local/greenplum-clients-4.3/bin")); + path.Add(wxT("/usr/local/greenplum-clients-4.2/bin")); + path.Add(wxT("/opt/local/greenplum-clients-4.2/bin")); + path.Add(wxT("/usr/local/greenplum-clients-4.1/bin")); + path.Add(wxT("/opt/local/greenplum-clients-4.1/bin")); + path.Add(wxT("/usr/local/greenplum-clients-4.0/bin")); + path.Add(wxT("/opt/local/greenplum-clients-4.0/bin")); + path.Add(wxT("/usr/local/greenplum-clients-3.3/bin")); + path.Add(wxT("/opt/local/greenplum-clients-3.3/bin")); + path.Add(wxT("/usr/local/greenplum-clients-3.2/bin")); + path.Add(wxT("/opt/local/greenplum-clients-3.2/bin")); + + path.Add(wxT("/usr/local/greenplum-clients-5.0/lib")); + path.Add(wxT("/opt/local/greenplum-clients-5.0/lib")); + path.Add(wxT("/usr/local/greenplum-clients-4.4/lib")); + path.Add(wxT("/opt/local/greenplum-clients-4.4/lib")); + path.Add(wxT("/usr/local/greenplum-clients-4.3/lib")); + path.Add(wxT("/opt/local/greenplum-clients-4.3/lib")); + path.Add(wxT("/usr/local/greenplum-clients-4.2/lib")); + path.Add(wxT("/opt/local/greenplum-clients-4.2/lib")); + path.Add(wxT("/usr/local/greenplum-clients-4.1/lib")); + path.Add(wxT("/opt/local/greenplum-clients-4.1/lib")); + path.Add(wxT("/usr/local/greenplum-clients-4.0/lib")); + path.Add(wxT("/opt/local/greenplum-clients-4.0/lib")); + path.Add(wxT("/usr/local/greenplum-clients-3.3/lib")); + path.Add(wxT("/opt/local/greenplum-clients-3.3/lib")); + path.Add(wxT("/usr/local/greenplum-clients-3.2/lib")); + path.Add(wxT("/opt/local/greenplum-clients-3.2/lib")); + + + wxFileName tmp = path.FindValidPath(wxT("pg_dump")); +#endif + + if (tmp.FileExists()) + { + if (isGpApp(tmp.GetFullPath())) + settings->SetGPDBPath(tmp.GetPath()); + } + } + + // Now setup and verify the paths for each individual helper +#if defined(__WXMSW__) + pgBackupExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dump.exe"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("\\pg_dumpall.exe"); + pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("\\pg_restore.exe"); + + edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dump.exe"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_dumpall.exe"); + edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("\\pg_restore.exe"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("\\pg_dump.exe"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("\\pg_dumpall.exe"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("\\pg_restore.exe"); +#else + pgBackupExecutable = settings->GetPostgresqlPath() + wxT("/pg_dump"); + pgBackupAllExecutable = settings->GetPostgresqlPath() + wxT("/pg_dumpall"); + pgRestoreExecutable = settings->GetPostgresqlPath() + wxT("/pg_restore"); + + edbBackupExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dump"); + edbBackupAllExecutable = settings->GetEnterprisedbPath() + wxT("/pg_dumpall"); + edbRestoreExecutable = settings->GetEnterprisedbPath() + wxT("/pg_restore"); + + gpBackupExecutable = settings->GetGPDBPath() + wxT("/pg_dump"); + gpBackupAllExecutable = settings->GetGPDBPath() + wxT("/pg_dumpall"); + gpRestoreExecutable = settings->GetGPDBPath() + wxT("/pg_restore"); +#endif + + if (!isPgApp(pgBackupExecutable)) + pgBackupExecutable = wxEmptyString; + if (!isPgApp(pgBackupAllExecutable)) + pgBackupAllExecutable = wxEmptyString; + if (!isPgApp(pgRestoreExecutable)) + pgRestoreExecutable = wxEmptyString; + + if (!isEdbApp(edbBackupExecutable)) + edbBackupExecutable = wxEmptyString; + if (!isEdbApp(edbBackupAllExecutable)) + edbBackupAllExecutable = wxEmptyString; + if (!isEdbApp(edbRestoreExecutable)) + edbRestoreExecutable = wxEmptyString; + + if (!isGpApp(gpBackupExecutable)) + gpBackupExecutable = wxEmptyString; + if (!isGpApp(gpBackupAllExecutable)) + gpBackupAllExecutable = wxEmptyString; + if (!isGpApp(gpRestoreExecutable)) + gpRestoreExecutable = wxEmptyString; +} + +wxString pgAdmin3::LocatePath(const wxString &pathToFind, const bool isFile) +{ + loadPath = wxPathOnly(argv[0]); + + if (loadPath.IsEmpty()) + loadPath = wxT("."); + + loadPath = sanitizePath(loadPath); + +#if defined(__WXMSW__) + + // Search for the right paths. We check the following locations: + // + // 1) ./xxx - Running as a standalone install + // 2) ../pgAdmin/xxx - Running in a pgInstaller 8.1 installation + // (with the .exe and dlls in the main bin dir) + // 3) ../xxx or ../../xxx - Running in a development environment + + if (!isFile) + { + if (wxDir::Exists(loadPath + pathToFind)) + return sanitizePath(loadPath + pathToFind); + else if (wxDir::Exists(loadPath + wxT("/../pgAdmin III") + pathToFind)) + return sanitizePath(loadPath + wxT("/../pgAdmin III") + pathToFind); + else if (wxDir::Exists(loadPath + wxT("/..") + pathToFind)) + return sanitizePath(loadPath + wxT("/..") + pathToFind); + else if (wxDir::Exists(loadPath + wxT("/../..") + pathToFind)) + return sanitizePath(loadPath + wxT("/../..") + pathToFind); + else + return wxEmptyString; + } + else + { + if (wxFile::Exists(loadPath + pathToFind)) + return sanitizePath(loadPath + pathToFind); + else if (wxFile::Exists(loadPath + wxT("/../pgAdmin III") + pathToFind)) + return sanitizePath(loadPath + wxT("/../pgAdmin III") + pathToFind); + else if (wxFile::Exists(loadPath + wxT("/..") + pathToFind)) + return sanitizePath(loadPath + wxT("/..") + pathToFind); + else if (wxFile::Exists(loadPath + wxT("/../..") + pathToFind)) + return sanitizePath(loadPath + wxT("/../..") + pathToFind); + else + return wxEmptyString; + } + +#else + +#ifdef __WXMAC__ +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdPaths = wxStandardPaths::Get(); +#else + // When using wxStandardPaths on OSX, wx default to the unix, + // not to the mac variants. Therefore, we request wxStandardPathsCF + // directly. + wxStandardPathsCF stdPaths; +#endif + dataDir = stdPaths.GetDataDir(); + +#else // other *ixes + +// Data path (defined by configure under Unix). +#ifndef DATA_DIR +#define DATA_DIR "./" +#endif + + dataDir = wxString::FromAscii(DATA_DIR); +#endif + + // On unix systems, the search path is as follows: + // + // 1) DATADIR/xxx - DATADIR being defined by configure + // 2) ./../share/pgadmin3/xxx - The default 'make install' layout, but allowing for relocation + // 3) ./xxx - Windows-style standalone install + // 4) ./../xxx - Unix-style standalone install (with binaries in a bin directory) + + if (!isFile) + { + if (wxDir::Exists(dataDir + pathToFind)) + return sanitizePath(dataDir + pathToFind); + else if (wxDir::Exists(loadPath + wxT("/../share/pgadmin3") + pathToFind)) + return sanitizePath(loadPath + wxT("/../share/pgadmin3") + pathToFind); + else if (wxDir::Exists(loadPath + pathToFind)) + return sanitizePath(loadPath + pathToFind); + else if (wxDir::Exists(loadPath + wxT("/..") + pathToFind)) + return sanitizePath(loadPath + wxT("/..") + pathToFind); + else + return wxEmptyString; + } + else + { + if (wxFile::Exists(dataDir + pathToFind)) + return sanitizePath(dataDir + pathToFind); + else if (wxFile::Exists(loadPath + wxT("/../share/pgadmin3") + pathToFind)) + return sanitizePath(loadPath + wxT("/../share/pgadmin3") + pathToFind); + else if (wxFile::Exists(loadPath + pathToFind)) + return sanitizePath(loadPath + pathToFind); + else if (wxFile::Exists(loadPath + wxT("/..") + pathToFind)) + return sanitizePath(loadPath + wxT("/..") + pathToFind); + else + return wxEmptyString; + } + +#endif +} + +void pgAdmin3::InitHelp() +{ + // Windows-only path prefixes +#ifdef __WXMSW__ + wxString programFiles = wxGetenv(wxT("ProgramFiles")); + wxString programFilesX86 = wxGetenv(wxT("ProgramFiles(x86)")); +#endif + + // Search for external docs. As Windows and *nix etc + // are likely to be very different, we'll #ifdef them all. + wxPathList stdPaths, noPaths, pgPaths, edbPaths, gpPaths, slonyPaths; + wxString sep = wxFileName::GetPathSeparator(); + + stdPaths.Add(docPath + sep + settings->GetCanonicalLanguageName()); + stdPaths.Add(docPath + sep + wxT("en_US")); + stdPaths.Add(docPath); + +#ifdef __WXMSW__ + if (!programFiles.IsEmpty()) + { + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.4\\doc")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.4\\doc\\html")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.3\\doc")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.3\\doc\\html")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.2\\doc")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.2\\doc\\html")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.1\\doc")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.1\\doc\\html")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.0\\doc")); + pgPaths.Add(programFiles + wxT("\\PostgreSQL\\8.0\\doc\\html")); + } + + if (!programFilesX86.IsEmpty()) + { + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.4\\doc")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.4\\doc\\html")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.3\\doc")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.3\\doc\\html")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.2\\doc")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.2\\doc\\html")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.1\\doc")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.1\\doc\\html")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.0\\doc")); + pgPaths.Add(programFilesX86 + wxT("\\PostgreSQL\\8.0\\doc\\html")); + } + + // Note that EDB docs are online from 8.3. + edbPaths.Add(wxT("C:\\EnterpriseDB\\8.2\\dbserver\\doc")); + edbPaths.Add(wxT("C:\\EnterpriseDB\\8.2\\dbserver\\doc\\html")); + edbPaths.Add(wxT("C:\\EnterpriseDB\\8.1\\dbserver\\doc")); + edbPaths.Add(wxT("C:\\EnterpriseDB\\8.1\\dbserver\\doc\\html")); + edbPaths.Add(wxT("C:\\EnterpriseDB\\8.0\\dbserver\\doc")); + edbPaths.Add(wxT("C:\\EnterpriseDB\\8.0\\dbserver\\doc\\html")); + + wxString GPhint = wxString(getenv( "GPHOME_CLIENTS" ), wxConvUTF8 ); + + if (GPhint.Length() > 1) + { + gpPaths.Add(GPhint + wxT("\\docs")); + gpPaths.Add(GPhint); + } + + GPhint = wxString(getenv( "GPHOME" ), wxConvUTF8 ); + + if (GPhint.Length() > 1) + { + gpPaths.Add(GPhint + wxT("\\docs")); + gpPaths.Add(GPhint); + } + + if (!programFiles.IsEmpty()) + { + gpPaths.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.3\\docs")); + gpPaths.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.2\\docs")); + gpPaths.Add(programFiles + wxT("\\Greenplum\\greenplum-clients-3.1.1.1\\docs")); + } + + if (!programFilesX86.IsEmpty()) + { + gpPaths.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.3\\docs")); + gpPaths.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.2\\docs")); + gpPaths.Add(programFilesX86 + wxT("\\Greenplum\\greenplum-clients-3.1.1.1\\docs")); + } + ; + + +#else + pgPaths.Add(wxT("/usr/local/pgsql/doc")); + pgPaths.Add(wxT("/usr/local/pgsql/doc/html")); + pgPaths.Add(wxT("/usr/local/doc/postgresql")); + pgPaths.Add(wxT("/usr/local/doc/postgresql/html")); + pgPaths.Add(wxT("/usr/doc/postgresql")); + pgPaths.Add(wxT("/usr/doc/postgresql/html")); + pgPaths.Add(wxT("/opt/local/pgsql/doc")); + pgPaths.Add(wxT("/opt/local/pgsql/doc/html")); + pgPaths.Add(wxT("/opt/local/doc/postgresql")); + pgPaths.Add(wxT("/opt/local/doc/postgresql/html")); + pgPaths.Add(wxT("/opt/doc/postgresql")); + pgPaths.Add(wxT("/opt/doc/postgresql/html")); + + edbPaths.Add(wxT("/usr/local/enterpriseDB/doc")); + edbPaths.Add(wxT("/usr/local/enterpriseDB/doc/html")); + edbPaths.Add(wxT("/usr/local/enterprisedb/doc")); + edbPaths.Add(wxT("/usr/local/enterprisedb/doc/html")); + edbPaths.Add(wxT("/usr/local/edb/doc")); + edbPaths.Add(wxT("/usr/local/edb/doc/html")); + edbPaths.Add(wxT("/opt/local/enterpriseDB/doc")); + edbPaths.Add(wxT("/opt/local/enterpriseDB/doc/html")); + edbPaths.Add(wxT("/opt/local/enterprisedb/doc")); + edbPaths.Add(wxT("/opt/local/enterprisedb/doc/html")); + edbPaths.Add(wxT("/opt/local/edb/doc")); + edbPaths.Add(wxT("/opt/local/edb/doc/html")); + + wxArrayString gpFoundDirs; + wxString pgDirname1 = wxString(wxT("/usr/local")); + wxDir gpDir1(pgDirname1); + if ( gpDir1.IsOpened() ) + { + wxString gpfilename; + bool pgcont = gpDir1.GetFirst(&gpfilename, wxT("greenplum-clients*"), wxDIR_DIRS); + while ( pgcont ) + { + gpFoundDirs.Add(wxString(pgDirname1 + wxT("/") + gpfilename)); + pgcont = gpDir1.GetNext(&gpfilename); + } + } + + wxString pgDirname2 = wxString(wxT("/opt/local")); + wxDir gpDir2(pgDirname2); + if ( gpDir2.IsOpened() ) + { + wxString gpfilename; + bool pgcont = gpDir2.GetFirst(&gpfilename, wxT("greenplum-clients*"), wxDIR_DIRS); + while ( pgcont ) + { + gpFoundDirs.Add(wxString(pgDirname2 + wxT("/") + gpfilename)); + pgcont = gpDir2.GetNext(&gpfilename); + } + } + + // make sure that the highest version number comes first + gpFoundDirs.Sort(true); + for (wxArrayString::iterator iter = gpFoundDirs.begin(); iter != gpFoundDirs.end(); ++iter) + { + wxLogMessage(*iter); + pgPaths.Add(wxString(*iter)); + pgPaths.Add(wxString(*iter) + wxT("/html")); + pgPaths.Add(wxString(*iter) + wxT("/docs")); + } + +#endif + + // Slony will be installed into one of the DBMS directories + slonyPaths.Add(pgPaths); + slonyPaths.Add(edbPaths); + slonyPaths.Add(gpPaths); + + // First look for a chm, then a zip, then an hhp file. For PostgreSQL + // and EnterpriseDB we'll then look for an index.html. No point for + // Slony as we'd most likely find the DBMS's help. + + wxString pgHelpPath = settings->GetPgHelpPath(); + wxString edbHelpPath = settings->GetEdbHelpPath(); + wxString gpHelpPath = settings->GetGpHelpPath(); + wxString slonyHelpPath = settings->GetSlonyHelpPath(); + +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + pgHelpPath = GenerateHelpPath(wxT("PostgreSQL.chm"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("postgresql.chm"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("postgres.chm"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("pgsql.chm"), pgHelpPath, stdPaths, pgPaths); + + edbHelpPath = GenerateHelpPath(wxT("EnterpriseDB.chm"), edbHelpPath, stdPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("enterprisedb.chm"), edbHelpPath, stdPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("edb.chm"), edbHelpPath, stdPaths, edbPaths); + + gpHelpPath = GenerateHelpPath(wxT("Greenplum.chm"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPDB.chm"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPSQL.zip"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPClientToolsWin.pdf"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPClientTools.pdf"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPUserGuide.pdf"), gpHelpPath, stdPaths, gpPaths); + + slonyHelpPath = GenerateHelpPath(wxT("Slony-I.chm"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony-i.chm"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony1.chm"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony.chm"), slonyHelpPath, stdPaths, slonyPaths); +#endif + + pgHelpPath = GenerateHelpPath(wxT("PostgreSQL.zip"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("postgresql.zip"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("postgres.zip"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("pgsql.zip"), pgHelpPath, stdPaths, pgPaths); + + edbHelpPath = GenerateHelpPath(wxT("EnterpriseDB.zip"), edbHelpPath, stdPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("enterprisedb.zip"), edbHelpPath, stdPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("edb.zip"), edbHelpPath, stdPaths, edbPaths); + + gpHelpPath = GenerateHelpPath(wxT("Greenplum.zip"), gpHelpPath, stdPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPSQL.zip"), gpHelpPath, stdPaths, gpPaths); + + slonyHelpPath = GenerateHelpPath(wxT("Slony-I.zip"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony-i.zip"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony1.zip"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony.zip"), slonyHelpPath, stdPaths, slonyPaths); + + pgHelpPath = GenerateHelpPath(wxT("PostgreSQL.hhp"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("postgresql.hhp"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("postgres.hhp"), pgHelpPath, stdPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("pgsql.hhp"), pgHelpPath, stdPaths, pgPaths); + + edbHelpPath = GenerateHelpPath(wxT("EnterpriseDB.hhp"), edbHelpPath, stdPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("enterprisedb.hhp"), edbHelpPath, stdPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("edb.hhp"), edbHelpPath, stdPaths, edbPaths); + + gpHelpPath = GenerateHelpPath(wxT("Greenplum.hhp"), gpHelpPath, stdPaths, gpPaths); + + slonyHelpPath = GenerateHelpPath(wxT("Slony-I.hhp"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony-i.hhp"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony1.hhp"), slonyHelpPath, stdPaths, slonyPaths); + slonyHelpPath = GenerateHelpPath(wxT("slony.hhp"), slonyHelpPath, stdPaths, slonyPaths); + + pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths); + pgHelpPath = GenerateHelpPath(wxT("index.html"), pgHelpPath, noPaths, pgPaths); + + edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths); + edbHelpPath = GenerateHelpPath(wxT("index.html"), edbHelpPath, noPaths, edbPaths); + + gpHelpPath = GenerateHelpPath(wxT("index.html"), gpHelpPath, noPaths, gpPaths); + gpHelpPath = GenerateHelpPath(wxT("GPUserGuide.pdf"), gpHelpPath, stdPaths, gpPaths); + + // If either path ends in index.html, remove the filename because we + // just want the path. In this case, we should also add file:/// on + // non-Windows platforms. + if (pgHelpPath.EndsWith(wxT("index.html"))) + { + pgHelpPath = pgHelpPath.Left(pgHelpPath.Length() - 10); +#ifndef __WXMSW__ + pgHelpPath = wxT("file:///") + pgHelpPath; +#endif + } + + if (edbHelpPath.EndsWith(wxT("index.html"))) + { + edbHelpPath = edbHelpPath.Left(edbHelpPath.Length() - 10); +#ifndef __WXMSW__ + edbHelpPath = wxT("file:///") + edbHelpPath; +#endif + } + + if (gpHelpPath.EndsWith(wxT("index.html"))) + { + gpHelpPath = gpHelpPath.Left(gpHelpPath.Length() - 10); +#ifndef __WXMSW__ + gpHelpPath = wxT("file:///") + gpHelpPath; +#endif + } + + // Last resorts - if we still have no help by now, use the websites! + if (pgHelpPath.IsEmpty()) + pgHelpPath = wxT("http://www.postgresql.org/docs/current/static/"); + if (edbHelpPath.IsEmpty()) + edbHelpPath = wxT("http://www.enterprisedb.com/docs/en/current/server/"); + if (gpHelpPath.IsEmpty()) + gpHelpPath = wxT("http://gpdb.docs.pivotal.io/"); + if (slonyHelpPath.IsEmpty()) + slonyHelpPath = wxT("http://www.slony.info/documentation/"); + + // OK, so set the values + if (settings->GetPgHelpPath().IsEmpty()) + settings->SetPgHelpPath(pgHelpPath); + if (settings->GetEdbHelpPath().IsEmpty()) + settings->SetEdbHelpPath(edbHelpPath); + if (settings->GetGpHelpPath().IsEmpty()) + settings->SetGpHelpPath(gpHelpPath); + if (settings->GetSlonyHelpPath().IsEmpty()) + settings->SetSlonyHelpPath(slonyHelpPath); +} + +wxString pgAdmin3::GenerateHelpPath(const wxString &file, const wxString ¤t, wxPathList stdPaths, wxPathList dbmsPaths) +{ + // If we already have a value, don't change it. + if (!current.IsEmpty()) + return current; + + if (!stdPaths.FindValidPath(file).IsEmpty()) + return stdPaths.FindValidPath(file); + + if (!dbmsPaths.FindValidPath(file).IsEmpty()) + return dbmsPaths.FindValidPath(file); + + return wxEmptyString; +} + +void pgAdmin3::InitXml() +{ +#define chkXRC(id) XRCID(#id) == id + wxASSERT_MSG( + chkXRC(wxID_OK) && + chkXRC(wxID_CANCEL) && + chkXRC(wxID_HELP) && + chkXRC(wxID_APPLY) && + chkXRC(wxID_ADD) && + chkXRC(wxID_STOP) && + chkXRC(wxID_REMOVE) && + chkXRC(wxID_REFRESH) && + chkXRC(wxID_CLOSE), + wxT("XRC ID not correctly assigned.")); + // if this assert fires, some event table uses XRCID(...) instead of wxID_... directly + +#ifdef EMBED_XRC + wxLogInfo(__("Using embedded XRC data.")); + + // resources are loaded from memory + extern void InitXmlResource(); + InitXmlResource(); + +#else + wxLogInfo(__("Using external XRC files.")); + + // for debugging, dialog resources are read from file + wxXmlResource::Get()->Load(uiPath + wxT("/*.xrc")); +#endif + +} + + +void pgAdmin3::InitLogger() +{ + sysLogger::logFile = settings->GetLogFile(); + sysLogger::logLevel = settings->GetLogLevel(); + + logger = new sysLogger(); + wxLog::SetVerbose(true); + wxLog::SetActiveTarget(logger); + wxLog::Resume(); +} + + +void pgAdmin3::InitNetwork() +{ + // Startup the windows sockets if required +#ifdef __WXMSW__ + WSADATA wsaData; + if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) + { + wxLogFatalError(__("Cannot initialise the networking subsystem!")); + } +#endif + wxSocketBase::Initialize(); + + pgConn::ExamineLibpqVersion(); +} + +#include "images/pgAdmin3-16.pngc" +#include "images/pgAdmin3-32.pngc" +#include "images/splash.pngc" + +pgAppearanceFactory::pgAppearanceFactory() +{ + is_branded = false; + + // Setup the default branding options +#ifdef __WIN32__ + splash_font_size = 8; +#else +#ifdef __WXMAC__ + splash_font_size = 11; +#else + splash_font_size = 9; +#endif +#endif + + splash_pos_x = 128; + splash_pos_y = 281; + splash_pos_offset = 15; + + large_icon = *pgAdmin3_32_png_img; + small_icon = *pgAdmin3_16_png_img; + splash_image = *splash_png_img; + + splash_text_colour = wxColour(255, 255, 255); + report_key_colour = wxColour(0, 154, 206); + + long_appname = wxT("pgAdmin III"); + short_appname = wxT("pgadmin3"); + website_url = wxT("http://www.pgadmin.org/"); + + hide_enterprisedb_help = false; + hide_greenplum_help = false; + + // Attempt to overload branding information + wxFileName brIni(brandingPath + wxT("/branding.ini")); + if (brIni.FileExists()) + { + wxString brCfg = FileRead(brIni.GetFullPath()); + + wxStringTokenizer tkz(brCfg, wxT("\r\n")); + + while(tkz.HasMoreTokens()) + { + wxString token = tkz.GetNextToken(); + + if (token.Trim() == wxEmptyString || token.StartsWith(wxT(";"))) + continue; + + if (token.Lower().StartsWith(wxT("largeicon="))) + { + large_icon = wxImage(brandingPath + wxT("/") + token.AfterFirst('=').Trim()); + if (!large_icon.IsOk()) + large_icon = *pgAdmin3_32_png_img; + else + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("smallicon="))) + { + small_icon = wxImage(brandingPath + wxT("/") + token.AfterFirst('=').Trim()); + if (!small_icon.IsOk()) + small_icon = *pgAdmin3_16_png_img; + else + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("splashimage="))) + { + splash_image = wxImage(brandingPath + wxT("/") + token.AfterFirst('=').Trim()); + if (!splash_image.IsOk()) + splash_image = *splash_png_img; + else + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("icon="))) + { + icon = token.AfterFirst('=').Trim(); + is_branded = true; + } +#ifdef __WIN32__ + else if (token.Lower().StartsWith(wxT("splashfontsizewin="))) +#else +#ifdef __WXMAC__ + else if (token.Lower().StartsWith(wxT("splashfontsizemac="))) +#else + else if (token.Lower().StartsWith(wxT("splashfontsizegtk="))) +#endif +#endif + { + token.AfterFirst('=').Trim().ToLong(&splash_font_size); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("splashposx="))) + { + token.AfterFirst('=').Trim().ToLong(&splash_pos_x); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("splashposy="))) + { + token.AfterFirst('=').Trim().ToLong(&splash_pos_y); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("splashposoffset="))) + { + token.AfterFirst('=').Trim().ToLong(&splash_pos_offset); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("splashtextcolour="))) + { + splash_text_colour = wxColor(token.AfterFirst('=').Trim()); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("shortappname="))) + { + short_appname = token.AfterFirst('=').Trim(); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("longappname="))) + { + long_appname = token.AfterFirst('=').Trim(); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("websiteurl="))) + { + website_url = token.AfterFirst('=').Trim(); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("reportkeycolour="))) + { + report_key_colour = wxColor(token.AfterFirst('=').Trim()); + is_branded = true; + } + else if (token.Lower().StartsWith(wxT("hideenterprisedbhelp="))) + { + if (token.AfterFirst('=').Trim() == wxT("1")) + { + hide_enterprisedb_help = true; + is_branded = true; + } + } + else if (token.Lower().StartsWith(wxT("hidegreenplumhelp="))) + { + if (token.AfterFirst('=').Trim() == wxT("1")) + { + hide_greenplum_help = true; + is_branded = true; + } + } + } + } + +#ifdef __WXMSW__ + + // Set the MUI cache value for the grouped task bar title, + // otherwise we get the value from the resources which is + // definitely not what we want in branded mode! + wxRegKey *pRegKey = new wxRegKey(wxT("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache")); + if(!pRegKey->Exists()) + pRegKey->Create(); + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &paths = wxStandardPaths::Get(); +#else + wxStandardPaths paths; +#endif + //wxString tmp; + //tmp.Printf(wxT("%s"), long_appname); + pRegKey->SetValue(paths.GetExecutablePath(), GetLongAppName()); + delete pRegKey; + + // Reset the image for the task bar group. This can only by + // set per-exe name unfortunately. If we don't find an icon, + // remove the registry value. + wxString icon_path = brandingPath + wxT("\\") + icon; + + + pRegKey = new wxRegKey(wxT("HKEY_CURRENT_USER\\Software\\Classes\\Applications\\") + wxFileName(paths.GetExecutablePath()).GetFullName()); + if(!pRegKey->Exists()) + pRegKey->Create(); + + if (wxFile::Exists(icon_path)) + { + pRegKey->SetValue(wxT("TaskbarGroupIcon"), icon_path); + } + else + { + if (pRegKey->HasValue(wxT("TaskbarGroupIcon"))) + pRegKey->DeleteValue(wxT("TaskbarGroupIcon")); + } + delete pRegKey; +#endif +} + +void pgAppearanceFactory::SetIcons(wxDialog *dlg) +{ + wxIconBundle icons; + icons.AddIcon(GetSmallIconImage()); + icons.AddIcon(GetBigIconImage()); + dlg->SetIcons(icons); +} + +void pgAppearanceFactory::SetIcons(wxTopLevelWindow *dlg) +{ + wxIconBundle icons; + icons.AddIcon(GetSmallIconImage()); + icons.AddIcon(GetBigIconImage()); + dlg->SetIcons(icons); +} + +wxIcon pgAppearanceFactory::GetSmallIconImage() +{ + wxIcon icon; + icon.CopyFromBitmap(wxBitmap(small_icon)); + return icon; +} + +wxIcon pgAppearanceFactory::GetBigIconImage() +{ + wxIcon icon; + icon.CopyFromBitmap(wxBitmap(large_icon)); + return icon; +} + +wxFont pgAppearanceFactory::GetSplashTextFont() +{ + wxFont fnt(*wxNORMAL_FONT); + fnt.SetPointSize(splash_font_size); + return fnt; +} + +//////////////////////////////////////////////////////////////////////////////// +// InitLibpq() +// +// Dynamically load EDB-specific functions from libpq + +#ifdef __WXMSW__ +void pgAdmin3::InitLibpq() +{ + HINSTANCE hinstLib; + + // Get a handle to the DLL module. + hinstLib = LoadLibrary(TEXT("libpq")); + + // If the handle is valid, try to get the function address. + if (hinstLib != NULL) + { + PQiGetOutResult = (PQGETOUTRESULT) GetProcAddress(hinstLib, "PQgetOutResult"); + PQiPrepareOut = (PQPREPAREOUT) GetProcAddress(hinstLib, "PQprepareOut"); + PQiSendQueryPreparedOut = (PQSENDQUERYPREPAREDOUT) GetProcAddress(hinstLib, "PQsendQueryPreparedOut"); + + // If the function address is valid, call the function. + if (PQiGetOutResult != NULL) + wxLogInfo(wxT("Using runtime dynamically linked EDB libpq functions.")); + else + wxLogInfo(wxT("EDB libpq functions are not available.")); + } +} +#endif + diff --git a/pgAdmin3.rc b/pgAdmin3.rc new file mode 100644 index 0000000..6a9c3eb --- /dev/null +++ b/pgAdmin3.rc @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAdmin3.rc - win32 Resources +// +////////////////////////////////////////////////////////////////////////// + +#if defined(_WIN32_WCE) +#undef _WIN32_WCE +#endif + +#include +#include +#include "include/version.h" +#include "include/copyright.h" + +// Icon (Don't remove the aaa prefix - it makes it the default icon!) +aaaPGADMIN3 ICON DISCARDABLE "include/images/pgAdmin3.ico" +SQL ICON DISCARDABLE "include/images/sql.ico" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VERSION_NUM +PRODUCTVERSION VERSION_NUM +FILEFLAGSMASK VER_DEBUG|VER_PRERELEASE +FILEFLAGS VER_DEBUG|VER_PRERELEASE +FILEOS VOS__WINDOWS32 +FILETYPE VFT_APP +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "FileVersion", VERSION_STR, "\0" + VALUE "File Version", VERSION_STR, "\0" + VALUE "FileDescription", "pgAdmin III - PostgreSQL Tools", "\0" + VALUE "LegalCopyright", COPYRIGHT_WIN32, "\0" + VALUE "LegalTrademarks", LICENSE, "\0" + VALUE "InternalName", "pgadmin3", "\0" + VALUE "OriginalFilename","pgadmin3.exe", "\0" + VALUE "ProductName", "pgAdmin III", "\0" + VALUE "ProductVersion", VERSION_STR, "\0" +#ifdef BUILD + VALUE "Build", BUILD, "\0" +#endif + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04E4 + END +END + diff --git a/pgAdmin3.vcxproj b/pgAdmin3.vcxproj new file mode 100644 index 0000000..617ae5e --- /dev/null +++ b/pgAdmin3.vcxproj @@ -0,0 +1,2295 @@ + + + + + Debug_(3.0) + Win32 + + + Debug_(3.0) + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release_(3.0) + Win32 + + + Release_(3.0) + x64 + + + Release + Win32 + + + Release + x64 + + + + {5C2D73BA-1F24-48F8-8233-85F5D672AA6A} + pgAdmin3 + 10.0 + + + + Application + false + Unicode + v110 + + + Application + false + Unicode + v110 + + + Application + false + Unicode + v100 + + + Application + false + Unicode + v110 + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v120_xp + + + Application + false + Unicode + v142 + + + Application + false + Unicode + v110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Release\ + .\Release\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + .\Debug\ + .\Debug\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Configuration)\ + $(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + $(Configuration)\ + $(Configuration)\ + true + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + false + false + .\wxwidgets\include;$(IncludePath) + $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);wxwidgets\lib + + + + Extracting source code repository version + ver_svn.bat + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/pgAdmin3.tlb + + + + + MaxSpeed + AnySuitable + $(OPENSSL)/include;$(WXWIN)/lib/vc_lib;$(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/include/libssh2;$(PROJECTDIR)/include/libssh2/Win32;D:\PostgreSQL\postgresql-10.1\src\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Use + pgadmin3.h + .\Release/pgAdmin3.pch + All + .\Release/ + .\Release/ + .\Release/ + true + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase28u.lib;wxbase28u_xml.lib;wxbase28u_net.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxmsw28u_html.lib;wxmsw28u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw28u_stc.lib;wxmsw28u_xrc.lib;wxexpat.lib;libeay32md.lib;libeay32.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;%(AdditionalDependencies) + .\Release/pgAdmin3.exe + true + $(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_dll;$(PGBUILD)/openssl/lib;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrtd.lib;%(IgnoreSpecificDefaultLibraries) + true + .\Release/pgAdmin3.pdb + true + .\Release/pgAdmin3.map + Windows + false + + + + + true + .\Release/pgAdmin3.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/pgAdmin3.tlb + + + + + MaxSpeed + AnySuitable + $(OPENSSL)/include;$(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/include/libssh2;$(PROJECTDIR)/include/libssh2/Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Use + pgadmin3.h + .\Release/pgAdmin3.pch + All + .\Release/ + .\Release/ + .\Release/ + true + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase28u.lib;wxbase28u_xml.lib;wxbase28u_net.lib;wxmsw28u_adv.lib;wxmsw28u_core.lib;wxmsw28u_html.lib;wxmsw28u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw28u_stc.lib;wxmsw28u_xrc.lib;wxexpat.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;%(AdditionalDependencies) + .\Release/pgAdmin3.exe + true + $(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrtd.lib;%(IgnoreSpecificDefaultLibraries) + true + .\Release/pgAdmin3.pdb + true + .\Release/pgAdmin3.map + Windows + false + + + MachineX64 + + + true + .\Release/pgAdmin3.bsc + + + + + Extracting source code repository version + ver_svn.bat + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/pgAdmin3.tlb + + + + + Disabled + $(OPENSSL)/include;$(WXWIN)/lib/vc_dll/mswud/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/include/libssh2;$(PROJECTDIR)/include/libssh2/Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;PG_SSL;HAVE_CONNINFO_PARSE;LIBSSH2_OPENSSL;%(PreprocessorDefinitions) + true + MultiThreadedDebugDLL + Use + pgadmin3.h + .\Debug/pgAdmin3.pch + All + .\Debug/ + .\Debug/ + .\Debug/ + true + .\Debug/ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase28ud.lib;wxbase28ud_xml.lib;wxbase28ud_net.lib;wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxmsw28ud_html.lib;wxmsw28ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw28ud_stc.lib;wxmsw28ud_xrc.lib;wxexpatd.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies) + .\Debug/pgAdmin3.exe + true + $(OPENSSL)/lib;$(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + true + .\Debug/pgAdmin3.pdb + true + .\Debug/pgAdmin3.map + Windows + false + false + + + MachineX86 + + + true + .\Debug/pgAdmin3.bsc + + + + + Extracting subversion repository version + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/pgAdmin3.tlb + + + + + Disabled + $(OPENSSL)\include;$(WXWIN)\lib\vc_dll\mswud;$(WXWIN)\include;$(WXWIN)\contrib\include;$(PGDIR)\include;$(PGBUILD)\include\;$(PGBUILD)\libxml2\include\;$(PGBUILD)\libxslt\include\;$(PGBUILD)\iconv\include\;$(PROJECTDIR)\include;$(PGDIR)\include\server;$(PROJECTDIR)\include\libssh2;$(PROJECTDIR)\include\libssh2\Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDebugDLL + Use + pgadmin3.h + .\Debug/pgAdmin3.pch + All + .\Debug/ + .\Debug/ + .\Debug/ + true + .\Debug/ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase28ud.lib;wxbase28ud_xml.lib;wxbase28ud_net.lib;wxmsw28ud_adv.lib;wxmsw28ud_core.lib;wxmsw28ud_html.lib;wxmsw28ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw28ud_stc.lib;wxmsw28ud_xrc.lib;wxexpatd.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies) + .\Debug/pgAdmin3.exe + true + $(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + true + .\Debug/pgAdmin3.pdb + true + .\Debug/pgAdmin3.map + Windows + false + false + + + MachineX64 + + + true + .\Debug/pgAdmin3.bsc + + + + + Extracting source code repository version + ver_svn.bat + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/pgAdmin3.tlb + + + + + Disabled + $(WXWIN)/lib/vc_dll/mswud/;$(wxwin)/include/msvc;$(WXWIN)/include;$(OPENSSL)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/include/libssh2;$(PROJECTDIR)/include/libssh2/Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0500;STRICT;wxUSE_UNICODE=1;wxMSVC_VERSION_AUTO;UNICODE;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDebugDLL + Use + pgadmin3.h + $(Configuration)\pgAdmin3.pch + All + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + true + $(Configuration)\ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase30ud.lib;wxbase30ud_xml.lib;wxbase30ud_net.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxmsw30ud_html.lib;wxmsw30ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw30ud_stc.lib;wxmsw30ud_xrc.lib;wxexpatd.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies) + $(Configuration)\pgAdmin3.exe + true + $(OPENSSL)/lib;$(wxwin)/lib/vc110_dll;$(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + true + $(Configuration)\pgAdmin3.pdb + true + $(Configuration)\pgAdmin3.map + Windows + false + false + + + MachineX86 + + + true + $(Configuration)\pgAdmin3.bsc + + + + + Extracting subversion repository version + ver_svn.bat + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/pgAdmin3.tlb + + + + + Disabled + $(OPENSSL)/include;$(WXWIN)/lib/vc_dll/mswud/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/include/libssh2;$(PROJECTDIR)/include/libssh2/Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;WIN32;_DEBUG;_WINDOWS;__WINDOWS__;__WXMSW__;WXUSINGDLL;DEBUG=1;__WXDEBUG__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;wxUSE_UNICODE=1;UNICODE;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDebugDLL + Use + pgadmin3.h + .\Debug/pgAdmin3.pch + All + .\Debug/ + .\Debug/ + .\Debug/ + true + .\Debug/ + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase30ud.lib;wxbase30ud_xml.lib;wxbase30ud_net.lib;wxmsw30ud_adv.lib;wxmsw30ud_core.lib;wxmsw30ud_html.lib;wxmsw30ud_aui.lib;wxregexud.lib;wxpngd.lib;wxzlibd.lib;wxjpegd.lib;wxtiffd.lib;wxmsw30ud_stc.lib;wxmsw30ud_xrc.lib;wxexpatd.lib;libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;oleaut32.lib;ole32.lib;shell32.lib;odbc32.lib;%(AdditionalDependencies) + .\Debug/pgAdmin3.exe + true + $(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrt.lib;%(IgnoreSpecificDefaultLibraries) + true + .\Debug/pgAdmin3.pdb + true + .\Debug/pgAdmin3.map + Windows + false + false + + + MachineX64 + + + true + .\Debug/pgAdmin3.bsc + + + + + Extracting source code repository version + ver_svn.bat + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/pgAdmin3.tlb + + + + + MaxSpeed + AnySuitable + $(WXWIN)/lib/vc_dll/mswud/;$(wxwin)/include/msvc;$(wxwin)/include;$(OPENSSL)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/include/libssh2;$(PROJECTDIR)/include/libssh2/Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;wxMSVC_VERSION_AUTO;UNICODE;EMBED_XRC;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Use + pgadmin3.h + $(Configuration)\pgAdmin3.pch + All + $(Configuration)\ + $(Configuration)\ + $(Configuration)\ + true + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + libeay32MD.lib;libpq.lib;libxml2.lib;libxslt.lib;iconv.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;%(AdditionalDependencies) + $(Configuration)\pgAdmin3.exe + true + $(OPENSSL)/lib;$(wxwin)/lib/vc110_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrtd.lib;%(IgnoreSpecificDefaultLibraries) + true + $(Configuration)\pgAdmin3.pdb + true + $(Configuration)\pgAdmin3.map + Windows + false + + + MachineX86 + + + true + $(Configuration)\pgAdmin3.bsc + + + false + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/pgAdmin3.tlb + + + + + MaxSpeed + AnySuitable + $(OPENSSL)/include;$(WXWIN)/lib/vc_dll/mswu/;$(WXWIN)/include;$(WXWIN)/contrib/include;$(PGDIR)/include;$(PGBUILD)/include/;$(PGBUILD)/libxml2/include/;$(PGBUILD)/libxslt/include/;$(PGBUILD)/iconv/include/;$(PROJECTDIR)/include;$(PGDIR)/include/server;$(PROJECTDIR)/../libssh2/include;$(PROJECTDIR)/include/libssh2/Win32;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_DEPRECATE=1;HAVE_OPENSSL_CRYPTO;LIBSSH2_OPENSSL;NDEBUG;WIN32;_WINDOWS;__WINDOWS__;__WIN95__;__WIN32__;WINVER=0x0400;STRICT;__WXMSW__;WXUSINGDLL;wxUSE_UNICODE=1;UNICODE;EMBED_XRC;PG_SSL;HAVE_CONNINFO_PARSE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + Use + pgadmin3.h + .\Release/pgAdmin3.pch + All + .\Release/ + .\Release/ + .\Release/ + true + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0809 + $(WXWIN)/include;%(AdditionalIncludeDirectories) + + + wxbase30u.lib;wxbase30u_xml.lib;wxbase30u_net.lib;wxmsw30u_adv.lib;wxmsw30u_core.lib;wxmsw30u_html.lib;wxmsw30u_aui.lib;wxregexu.lib;wxpng.lib;wxzlib.lib;wxjpeg.lib;wxtiff.lib;wxmsw30u_stc.lib;wxmsw30u_xrc.lib;wxexpat.lib;libpq.lib;comctl32.lib;rpcrt4.lib;wsock32.lib;winmm.lib;libssl64MD.lib;libcrypto64MD.lib;libiconv.lib;libxml2.lib;libssh2.lib;libxslt.lib;%(AdditionalDependencies) + true + $(PROJECTDIR)/../libssh2/src/Release;$(OPENSSL)/lib/VC;$(WXWIN)/lib/vc_x64_dll;$(PGDIR)/lib;$(PGBUILD)/lib;$(PGBUILD)/libxml2/lib;$(PGBUILD)/libxslt/lib;$(PGBUILD)/iconv/lib;%(AdditionalLibraryDirectories) + libcd.lib;libcid.lib;msvcrtd.lib;%(IgnoreSpecificDefaultLibraries) + true + .\Release/pgAdmin3.pdb + true + .\Release/pgAdmin3.map + Windows + false + + + MachineX64 + + + true + .\Release/pgAdmin3.bsc + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + Use + + + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + Create + $(IntDir)%(Filename)1.obj + $(IntDir)%(Filename)1.xdc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pgAdmin3.vcxproj.filters b/pgAdmin3.vcxproj.filters new file mode 100644 index 0000000..a5c6d8f --- /dev/null +++ b/pgAdmin3.vcxproj.filters @@ -0,0 +1,4442 @@ + + + + + {29d12a68-5623-40b8-b480-224efa6720ce} + *.cpp + + + {722af890-61ca-44cf-af1b-b17487f78f7c} + + + {b4711a6d-480f-4a6a-8f8a-cbc41a802336} + + + {a3d5e8ea-cb43-448c-a51a-18fd4d223dd9} + + + {ff19d9e8-f67b-4fe0-be02-69589832a941} + + + {9744a466-c06d-4fef-85e0-be4a27630deb} + + + {d8a57bb3-01aa-4ef3-94b6-1f2e5c3f07fc} + + + {efe4d829-5e1e-40ae-8413-85400cf8aff3} + + + {931b2f66-4823-4d4b-a328-6975433316d9} + + + {1d98451c-d3b1-40a4-abd3-0592146ff0fa} + + + {3feb5747-6682-4dbf-b082-abb2c794f70e} + + + {2c3cdfd8-8827-4ac7-8dc6-ee3f72f057e8} + + + {1d95fb56-f4c0-4205-b804-318d60bf8558} + + + {3b1b313d-6070-4d95-97fe-046a49b624ad} + + + {bede4cef-3b80-46aa-90ea-76ec261f03d5} + + + {f9761488-73e8-4f6b-b9e3-55b8cbb6a3a2} + + + {8c168e54-f1c4-44ee-85d0-4daec103d4f3} + + + {df42f3fa-0ac8-4d56-b9c4-1913d5a2c2f0} + + + {9cc76601-f308-4f0b-82be-71f838b858ea} + + + {9ee05a7a-1c91-43e2-a6cf-65837ad81162} + + + {685491dc-ad16-4121-94df-ba1ae331c95a} + + + {3c9dc817-cc28-4bc1-aa75-a9b5ff563a60} + + + {ec385f56-5a98-47d9-834a-23ddee4662d3} + + + {e6836e8e-e9b4-4d31-bf2d-53bec570bb0a} + + + {5a6cbaf8-e21d-4721-a511-f348f06d5b43} + + + {14d6562a-41a3-4626-943f-2312193634cb} + + + {0e4a3fb0-dd45-4c7b-813c-b4ceaf66280f} + + + {7d6c4241-1d80-4d6d-bb74-77eb1f97a5bc} + + + {8303ba8b-33ee-46ba-9ea6-55408815381d} + + + {9d006cc1-5afd-4497-8237-26e619952c47} + + + {287ed0c1-9708-46eb-96a7-7fb9f31013b6} + + + {e6be15c5-878e-4919-8cbb-e5fb0cbbf6a9} + + + {6f6ac2df-13ba-4b4d-8380-1a82a4a3e0b2} + + + {7b58f0d3-eaa9-4f43-80d4-0962a35e45f2} + + + {4c63ed7e-71d0-436a-b3fd-c7241f69369c} + + + {731ece13-da12-4792-868a-454029f103d9} + + + {31655133-e359-4e58-8486-8b6a509d7801} + + + {a5ffb000-00dd-47a1-906c-491faff00c2e} + + + {42c50033-eebe-4dee-b2ef-6ade6560a444} + + + {cd2ecb72-ced4-492e-8196-b855bb03939d} + + + {e1243dab-46ce-46ad-b949-18a040ae84cc} + + + {978d5148-e038-457c-b332-7db2ff0979fc} + + + {50055ec9-0424-4d82-9ce8-5e77b0dbfa8c} + + + {73c21a26-f48b-4333-b321-c31a2b161e89} + + + {df9631db-f808-4c98-acc0-cce1b9d4ac5f} + + + {c0a6ed32-2b3e-4f8a-aa48-5d12472536ec} + + + {e5220fd8-f837-4fbe-ac01-ef346e8b2d22} + + + {d8a57bb3-01aa-4ef3-94b6-1f2e5c3f07fc} + + + {2c3cdfd8-8827-4fef-8dc6-ee3f72f057e8} + + + {8c168e54-f1c4-8dc6-85d0-4daec103d4f3} + + + {df42f3fa-0ac8-4d56-b9c4-1913d5a2c2f0} + + + {9cc76601-f308-4f0b-82be-1913d5a2c2f0} + + + {9ee05a7a-1c91-43e2-c06d-65837ad81162} + + + {685491dc-ad16-4121-4bc1-ba1ae331c95a} + + + {3c9dc817-cc28-4bc1-4121-a9b5ff563a60} + + + {ec385f56-5a98-cc28-834a-23ddee4662d3} + + + {e6836e8e-e9b4-834a-bf2d-53bec570bb0a} + + + {5a6cbaf8-e51d-4721-a511-f348f06d5b43} + + + {14d6562a-41a3-4346-943f-2312193634cb} + + + {0e4d3fb0-dd45-4c7b-813c-b4ceaf66280f} + + + {7d6c4241-1d80-4d6d-ee74-77eb1f97a5bc} + + + {8303ba8b-33bb-46ba-9ea6-55408815381d} + + + {9d006cc1-5abd-4497-8237-26e619952c47} + + + {287ed0c1-2508-46eb-96a7-7fb9f31013b6} + + + {e6be15c5-873a-4919-8cbb-e5fb0cbbf6a9} + + + {6f6ac2df-13ba-4b4d-8321-1a82a4a3e0b2} + + + {7b58f0d3-eaa9-4f23-40d4-0962a35e45f2} + + + {4c63ed7e-71d0-562a-b3fd-c7241f69369c} + + + {731ece13-cb12-4792-868a-454029f103d9} + + + {31655331-e359-4e58-8486-8b6a509d7801} + + + {a5ffb112-00dd-47a1-906c-491faff00c2e} + + + {42c54433-eebe-4dee-b2ef-6ade6560a444} + + + {cd2ecb72-ced4-492e-8196-b855bb03429d} + + + {e1243dab-46ce-46ad-b949-18a181ae84cc} + + + {978d5153-e038-457c-b332-7db2ff0979fc} + + + {50123ec9-0424-4d82-9ce8-5e77b0dbfa8c} + + + {73c56a26-f48b-4333-b321-c31a2b161e89} + + + {df9631db-f808-4c98-acc0-aab1b9d4ac5f} + + + {c0a6ed25-2b3e-4f8a-aa48-5d12472536ec} + + + {e5220fd8-f837-4fbe-ac01-ef346e8b2d22} + + + {d4220fd8-f837-4fbe-ac01-ef346e8b2d22} + + + {1468162d-5854-4146-8baf-9dd27a8e80fa} + + + {bc8bb60a-46b2-4f26-b86f-f711fcc2a385} + + + + + agent + + + agent + + + agent + + + agent + + + agent + + + agent + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + ctl + + + db + + + db + + + db + + + db + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + dlg + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + frm + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + schema + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + slony + + + ui + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + utils + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + debugger + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + gqb + + + pgscript + + + pgscript + + + pgscript + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\exceptions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\expressions + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\generators + + + pgscript\objects + + + pgscript\objects + + + pgscript\objects + + + pgscript\objects + + + pgscript\objects + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\statements + + + pgscript\utilities + + + pgscript\utilities + + + pgscript\utilities + + + pgscript\utilities + + + pgscript\utilities + + + pgscript\utilities + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + pgscript\utilities\m_apm + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + ogl + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures + + + dd\dditems\figures\xml + + + dd\dditems\handles + + + dd\dditems\handles + + + dd\dditems\handles + + + dd\dditems\handles + + + dd\dditems\handles + + + dd\dditems\handles + + + dd\dditems\locators + + + dd\dditems\locators + + + dd\dditems\locators + + + dd\dditems\locators + + + dd\dditems\locators + + + dd\dditems\locators + + + dd\dditems\tools + + + dd\dditems\tools + + + dd\dditems\utilities + + + dd\dditems\utilities + + + dd\dditems\utilities + + + dd\ddmodel + + + dd\ddmodel + + + dd\ddmodel + + + dd\ddmodel + + + dd\ddmodel + + + dd\ddmodel + + + dd\ddmodel + + + hotdraw\connectors + + + hotdraw\connectors + + + hotdraw\connectors + + + hotdraw\connectors + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures + + + hotdraw\figures\defaultAttributes + + + hotdraw\figures\defaultAttributes + + + hotdraw\figures\defaultAttributes + + + hotdraw\figures\defaultAttributes + + + hotdraw\figures\xml + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\handles + + + hotdraw\locators + + + hotdraw\locators + + + hotdraw\main + + + hotdraw\main + + + hotdraw\main + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\tools + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + hotdraw\utilities + + + + + utils + + + schema + + + dlg + + + dlg + + + schema + + + schema + + + schema + + + pro_scheduler + + + utils + + + + + agent + + + ctl + + + db + + + dlg + + + frm + + + include + + + include\utils + + + include\ctl + + + include\images + + + include\images + + + include\images + + + include\parser + + + include\agent + + + include\slony + + + include\dlg + + + include\frm + + + include\schema + + + include\db + + + include\gqb + + + include\pgscript + + + include\pgscript + + + include\pgscript + + + include\pgscript + + + include\pgscript\exceptions + + + include\pgscript\expressions + + + include\pgscript\generators + + + include\pgscript\objects + + + include\pgscript\statements + + + include\pgscript\utilities + + + include\pgscript\utilities\m_apm + + + include\pgscript\utilities\m_apm + + + include\ogl + + + include\ogl + + + include\dd + + + include\dd\dditems + + + include\dd\dditems\figures + + + include\dd\dditems\figures\xml + + + include\dd\dditems\handles + + + include\dd\dditems\locators + + + include\dd\dditems\tools + + + include\dd\dditems\utilities + + + include\dd\ddmodel + + + include\hotdraw + + + include\hotdraw\connectors + + + include\hotdraw\figures + + + include\hotdraw\figures\defaultAttributes + + + include\hotdraw\handles + + + include\hotdraw\locators + + + include\hotdraw\main + + + include\hotdraw\tools + + + include\hotdraw\utilities + + + schema + + + slony + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + ui + + + utils + + + utils + + + utils + + + gqb + + + pgscript + + + pgscript + + + pgscript + + + pgscript + + + pgscript + + + pgscript\exceptions + + + pgscript\expressions + + + pgscript\generators + + + pgscript\objects + + + pgscript\statements + + + pgscript\utilities + + + pgscript\utilities\m_apm + + + ogl + + + ogl + + + dd + + + dd\dditems + + + dd\dditems\figures + + + dd\dditems\handles + + + dd\dditems\locators + + + dd\dditems\tools + + + dd\dditems\utilities + + + dd\ddmodel + + + hotdraw + + + hotdraw\connectors + + + hotdraw\figures + + + hotdraw\figures\defaultAttributes + + + hotdraw\figures\xml + + + hotdraw\handles + + + hotdraw\locators + + + hotdraw\main + + + hotdraw\tools + + + hotdraw\utilities + + + + + + + ui + + + ui + + + + + include + + + include + + + include + + + include + + + include + + + include + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\utils + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\ctl + + + include\parser + + + include\agent + + + include\agent + + + include\agent + + + include\agent + + + include\agent + + + include\agent + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\slony + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\dlg + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\frm + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\schema + + + include\db + + + include\db + + + include\db + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\debugger + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\gqb + + + include\pgscript + + + include\pgscript + + + include\pgscript + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\exceptions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\expressions + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\generators + + + include\pgscript\objects + + + include\pgscript\objects + + + include\pgscript\objects + + + include\pgscript\objects + + + include\pgscript\objects + + + include\pgscript\objects + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\statements + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities + + + include\pgscript\utilities\m_apm + + + include\pgscript\utilities\m_apm + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\ogl + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures + + + include\dd\dditems\figures\xml + + + include\dd\dditems\handles + + + include\dd\dditems\handles + + + include\dd\dditems\handles + + + include\dd\dditems\handles + + + include\dd\dditems\handles + + + include\dd\dditems\handles + + + include\dd\dditems\locators + + + include\dd\dditems\locators + + + include\dd\dditems\locators + + + include\dd\dditems\locators + + + include\dd\dditems\locators + + + include\dd\dditems\locators + + + include\dd\dditems\tools + + + include\dd\dditems\tools + + + include\dd\dditems\utilities + + + include\dd\dditems\utilities + + + include\dd\dditems\utilities + + + include\dd\dditems\utilities + + + include\dd\ddmodel + + + include\dd\ddmodel + + + include\dd\ddmodel + + + include\dd\ddmodel + + + include\dd\ddmodel + + + include\dd\ddmodel + + + include\dd\ddmodel + + + include\hotdraw\connectors + + + include\hotdraw\connectors + + + include\hotdraw\connectors + + + include\hotdraw\connectors + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures + + + include\hotdraw\figures\defaultAttributes + + + include\hotdraw\figures\defaultAttributes + + + include\hotdraw\figures\defaultAttributes + + + include\hotdraw\figures\defaultAttributes + + + include\hotdraw\figures\xml + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\handles + + + include\hotdraw\locators + + + include\hotdraw\locators + + + include\hotdraw\main + + + include\hotdraw\main + + + include\hotdraw\main + + + include\hotdraw\main + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\tools + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\hotdraw\utilities + + + include\utils + + + include\schema + + + include\dlg + + + include\dlg + + + include\db + + + include\schema + + + include\schema + + + include\schema + + + include\pro_scheduler + + + utils + + + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + include\images + + + + + + \ No newline at end of file diff --git a/pgAdmin3.vcxproj.user b/pgAdmin3.vcxproj.user new file mode 100644 index 0000000..437c493 --- /dev/null +++ b/pgAdmin3.vcxproj.user @@ -0,0 +1,16 @@ + + + + WXWIN=D:\PostgreSQL\pgadmin3-deps\wxWidgets + WindowsLocalDebugger + + + $(ProjectDir)\Release + WindowsLocalDebugger + Auto + + + -s mi -q + WindowsLocalDebugger + + \ No newline at end of file diff --git a/pgscript/exceptions/module.mk b/pgscript/exceptions/module.mk new file mode 100644 index 0000000..7dfa269 --- /dev/null +++ b/pgscript/exceptions/module.mk @@ -0,0 +1,24 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/exceptions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/exceptions/pgsArithmeticException.cpp \ + pgscript/exceptions/pgsAssertException.cpp \ + pgscript/exceptions/pgsBreakException.cpp \ + pgscript/exceptions/pgsCastException.cpp \ + pgscript/exceptions/pgsContinueException.cpp \ + pgscript/exceptions/pgsException.cpp \ + pgscript/exceptions/pgsInterruptException.cpp \ + pgscript/exceptions/pgsParameterException.cpp + +EXTRA_DIST += \ + pgscript/exceptions/module.mk + diff --git a/pgscript/exceptions/pgsArithmeticException.cpp b/pgscript/exceptions/pgsArithmeticException.cpp new file mode 100644 index 0000000..4d2d15f --- /dev/null +++ b/pgscript/exceptions/pgsArithmeticException.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsArithmeticException.h" + +pgsArithmeticException::pgsArithmeticException(const wxString &left, const wxString &right) : + pgsException(), m_left(left), m_right(right) +{ + +} + +pgsArithmeticException::~pgsArithmeticException() +{ + +} + +const wxString pgsArithmeticException::message() const +{ + return wxString() << PGSOUTEXCEPTION << + wxString::Format(_("Arithmetic Exception - Operation impossible between '%s' and '%s'"), + m_left.c_str(), m_right.c_str()); +} diff --git a/pgscript/exceptions/pgsAssertException.cpp b/pgscript/exceptions/pgsAssertException.cpp new file mode 100644 index 0000000..e33d35c --- /dev/null +++ b/pgscript/exceptions/pgsAssertException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsAssertException.h" + +pgsAssertException::pgsAssertException(const wxString &message) : + m_message(message) +{ + +} + +pgsAssertException::~pgsAssertException() +{ + +} + +const wxString pgsAssertException::message() const +{ + return wxString() << PGSOUTEXCEPTION << _("Assert Exception - ") << m_message; +} diff --git a/pgscript/exceptions/pgsBreakException.cpp b/pgscript/exceptions/pgsBreakException.cpp new file mode 100644 index 0000000..9179c35 --- /dev/null +++ b/pgscript/exceptions/pgsBreakException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsBreakException.h" + +pgsBreakException::pgsBreakException() : + pgsException() +{ + +} + +pgsBreakException::~pgsBreakException() +{ + +} + +const wxString pgsBreakException::message() const +{ + return wxT("BREAK"); +} diff --git a/pgscript/exceptions/pgsCastException.cpp b/pgscript/exceptions/pgsCastException.cpp new file mode 100644 index 0000000..7c537c4 --- /dev/null +++ b/pgscript/exceptions/pgsCastException.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsCastException.h" + +pgsCastException::pgsCastException(const wxString &value, const wxString &type) : + pgsException(), m_value(value), m_type(type) +{ + +} + +pgsCastException::~pgsCastException() +{ + +} + +const wxString pgsCastException::message() const +{ + return wxString() << PGSOUTEXCEPTION << + wxString::Format(_("Cast Exception - Cannot convert '%s' to '%s'"), + m_value.c_str(), m_type.c_str()); +} diff --git a/pgscript/exceptions/pgsContinueException.cpp b/pgscript/exceptions/pgsContinueException.cpp new file mode 100644 index 0000000..fdfd4e6 --- /dev/null +++ b/pgscript/exceptions/pgsContinueException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsContinueException.h" + +pgsContinueException::pgsContinueException() : + pgsException() +{ + +} + +pgsContinueException::~pgsContinueException() +{ + +} + +const wxString pgsContinueException::message() const +{ + return wxT("CONTINUE"); +} diff --git a/pgscript/exceptions/pgsException.cpp b/pgscript/exceptions/pgsException.cpp new file mode 100644 index 0000000..3649cd3 --- /dev/null +++ b/pgscript/exceptions/pgsException.cpp @@ -0,0 +1,22 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsException.h" + +pgsException::pgsException() +{ + +} + +pgsException::~pgsException() +{ + +} diff --git a/pgscript/exceptions/pgsInterruptException.cpp b/pgscript/exceptions/pgsInterruptException.cpp new file mode 100644 index 0000000..89445b4 --- /dev/null +++ b/pgscript/exceptions/pgsInterruptException.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/exceptions/pgsInterruptException.h" + +pgsInterruptException::pgsInterruptException() : + pgsException() +{ + +} + +pgsInterruptException::~pgsInterruptException() +{ + +} + +const wxString pgsInterruptException::message() const +{ + return wxString() << PGSOUTEXCEPTION << _("pgScript interrupted"); +} diff --git a/pgscript/exceptions/pgsParameterException.cpp b/pgscript/exceptions/pgsParameterException.cpp new file mode 100644 index 0000000..5a653a5 --- /dev/null +++ b/pgscript/exceptions/pgsParameterException.cpp @@ -0,0 +1,35 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "pgscript/exceptions/pgsParameterException.h" + +pgsParameterException::pgsParameterException(const wxString &message) : + pgsException(), m_message(message) +{ + +} + +pgsParameterException::~pgsParameterException() +{ + +} + +const wxString pgsParameterException::message() const +{ + wxString message(m_message); + message.Replace(wxT("\n"), wxT("\n") + generate_spaces(PGSOUTEXCEPTION.Length())); + message.Prepend(wxT(">> ")); + message.Prepend(generate_spaces(PGSOUTEXCEPTION.Length())); + return wxString() << PGSOUTEXCEPTION << + wxString::Format(_("Parameter Exception - Some parameters are invalid:\n%s"), + message.c_str()); +} diff --git a/pgscript/expressions/module.mk b/pgscript/expressions/module.mk new file mode 100644 index 0000000..54f43ba --- /dev/null +++ b/pgscript/expressions/module.mk @@ -0,0 +1,53 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/expressions/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/expressions/pgsAnd.cpp \ + pgscript/expressions/pgsAssign.cpp \ + pgscript/expressions/pgsAssignToRecord.cpp \ + pgscript/expressions/pgsCast.cpp \ + pgscript/expressions/pgsColumns.cpp \ + pgscript/expressions/pgsDifferent.cpp \ + pgscript/expressions/pgsEqual.cpp \ + pgscript/expressions/pgsExecute.cpp \ + pgscript/expressions/pgsExpression.cpp \ + pgscript/expressions/pgsGenDate.cpp \ + pgscript/expressions/pgsGenDateTime.cpp \ + pgscript/expressions/pgsGenDictionary.cpp \ + pgscript/expressions/pgsGenInt.cpp \ + pgscript/expressions/pgsGenReal.cpp \ + pgscript/expressions/pgsGenReference.cpp \ + pgscript/expressions/pgsGenRegex.cpp \ + pgscript/expressions/pgsGenString.cpp \ + pgscript/expressions/pgsGenTime.cpp \ + pgscript/expressions/pgsGreater.cpp \ + pgscript/expressions/pgsGreaterEqual.cpp \ + pgscript/expressions/pgsIdent.cpp \ + pgscript/expressions/pgsIdentRecord.cpp \ + pgscript/expressions/pgsLines.cpp \ + pgscript/expressions/pgsLower.cpp \ + pgscript/expressions/pgsLowerEqual.cpp \ + pgscript/expressions/pgsMinus.cpp \ + pgscript/expressions/pgsModulo.cpp \ + pgscript/expressions/pgsNegate.cpp \ + pgscript/expressions/pgsNot.cpp \ + pgscript/expressions/pgsOperation.cpp \ + pgscript/expressions/pgsOr.cpp \ + pgscript/expressions/pgsOver.cpp \ + pgscript/expressions/pgsParenthesis.cpp \ + pgscript/expressions/pgsPlus.cpp \ + pgscript/expressions/pgsRemoveLine.cpp \ + pgscript/expressions/pgsTimes.cpp \ + pgscript/expressions/pgsTrim.cpp + +EXTRA_DIST += \ + pgscript/expressions/module.mk + diff --git a/pgscript/expressions/pgsAnd.cpp b/pgscript/expressions/pgsAnd.cpp new file mode 100644 index 0000000..d1d2d4b --- /dev/null +++ b/pgscript/expressions/pgsAnd.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsAnd.h" + +#include "pgscript/objects/pgsNumber.h" + +pgsAnd::pgsAnd(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsAnd::~pgsAnd() +{ + +} + +pgsExpression *pgsAnd::clone() const +{ + return pnew pgsAnd(*this); +} + +pgsAnd::pgsAnd(const pgsAnd &that) : + pgsOperation(that) +{ + +} + +pgsAnd &pgsAnd::operator =(const pgsAnd &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + + return (*this); +} + +wxString pgsAnd::value() const +{ + return wxString() << m_left->value() << wxT(" AND ") << m_right->value(); +} + +pgsOperand pgsAnd::eval(pgsVarMap &vars) const +{ + return pnew pgsNumber(wxString() << (m_left->eval(vars)->pgs_is_true() + && m_right->eval(vars)->pgs_is_true()), pgsInt); +} diff --git a/pgscript/expressions/pgsAssign.cpp b/pgscript/expressions/pgsAssign.cpp new file mode 100644 index 0000000..a4f0b12 --- /dev/null +++ b/pgscript/expressions/pgsAssign.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsAssign.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsAssign::pgsAssign(const wxString &name, const pgsExpression *var) : + pgsExpression(), m_name(name), m_var(var) +{ + +} + +pgsAssign::~pgsAssign() +{ + pdelete(m_var); +} + +pgsExpression *pgsAssign::clone() const +{ + return pnew pgsAssign(*this); +} + +pgsAssign::pgsAssign(const pgsAssign &that) : + pgsExpression(that), m_name(that.m_name) +{ + m_var = that.m_var->clone(); +} + +pgsAssign &pgsAssign::operator =(const pgsAssign &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_name = that.m_name; + pdelete(m_var); + m_var = that.m_var->clone(); + } + return (*this); +} + +wxString pgsAssign::value() const +{ + return wxString() << wxT("SET ") << m_name << wxT(" = ") << m_var->value(); +} + +pgsOperand pgsAssign::eval(pgsVarMap &vars) const +{ + vars[m_name] = m_var->eval(vars); + return vars[m_name]; +} diff --git a/pgscript/expressions/pgsAssignToRecord.cpp b/pgscript/expressions/pgsAssignToRecord.cpp new file mode 100644 index 0000000..a0c1faf --- /dev/null +++ b/pgscript/expressions/pgsAssignToRecord.cpp @@ -0,0 +1,138 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsAssignToRecord.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/expressions/pgsIdentRecord.h" +#include "pgscript/objects/pgsRecord.h" + +pgsAssignToRecord::pgsAssignToRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column, const pgsExpression *var) : + pgsAssign(name, var), m_line(line), m_column(column) +{ + +} + +pgsAssignToRecord::~pgsAssignToRecord() +{ + pdelete(m_line); + pdelete(m_column); +} + +pgsExpression *pgsAssignToRecord::clone() const +{ + return pnew pgsAssignToRecord(*this); +} + +pgsAssignToRecord::pgsAssignToRecord(const pgsAssignToRecord &that) : + pgsAssign(that) +{ + m_line = that.m_line->clone(); + m_column = that.m_column->clone(); +} + +pgsAssignToRecord &pgsAssignToRecord::operator =(const pgsAssignToRecord &that) +{ + if (this != &that) + { + pgsAssign::operator=(that); + pdelete(m_line); + pdelete(m_column); + m_line = that.m_line->clone(); + m_column = that.m_column->clone(); + } + return (*this); +} + +wxString pgsAssignToRecord::value() const +{ + return wxString() << wxT("SET ") << m_name << wxT("[") << m_line->value() + << wxT("]") << wxT("[") << m_column->value() << wxT("]") + << wxT(" = ") << m_var->value(); +} + +pgsOperand pgsAssignToRecord::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) + { + // Get the operand as a record + pgsRecord &rec = dynamic_cast(*vars[m_name]); + + // Get the value to assign + pgsOperand var(m_var->eval(vars)); + + if (!var->is_record()) + { + // Evaluate parameters + pgsOperand line(m_line->eval(vars)); + pgsOperand column(m_column->eval(vars)); + if (line->is_integer()) + { + long aux_line; + line->value().ToLong(&aux_line); + + if (column->is_integer() || column->is_string()) + { + bool success = false; + + if (column->is_integer()) + { + long aux_column; + column->value().ToLong(&aux_column); + if (aux_column < rec.count_columns()) + { + success = rec.insert(aux_line, aux_column, var); + } + } + else if (column->is_string()) + { + USHORT aux_column = rec.get_column(column->value()); + if (aux_column < rec.count_columns()) + { + success = rec.insert(aux_line, aux_column, var); + } + } + + if (success == false) + { + throw pgsParameterException(wxString() << wxT("An error ") + << wxT("occurred in record affectation: ") << value() + << wxT("\n") << wxT("One possible reason is a ") + << wxT("column index out of range")); + } + } + + else + { + throw pgsParameterException(wxString() << column->value() + << wxT(" is not a valid column number/name")); + } + } + else + { + throw pgsParameterException(wxString() << line->value() + << wxT(" is not a valid line number")); + } + } + else + { + throw pgsParameterException(wxString() << wxT("Cannot assign a record") + << wxT(" into a record: right member is a record")); + } + } + else + { + throw pgsParameterException(wxString() << m_name << wxT(" is not a record")); + } + + return pgsIdentRecord(m_name, m_line->clone(), m_column->clone()).eval(vars); +} diff --git a/pgscript/expressions/pgsCast.cpp b/pgscript/expressions/pgsCast.cpp new file mode 100644 index 0000000..e930c49 --- /dev/null +++ b/pgscript/expressions/pgsCast.cpp @@ -0,0 +1,100 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsCast.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/objects/pgsNumber.h" + +#include "pgscript/parser.tab.hh" +typedef pgscript::pgsParser::token token; + +pgsCast::pgsCast(const int &cast_type, const pgsExpression *var) : + pgsExpression(), m_cast_type(cast_type), m_var(var) +{ + +} + +pgsCast::~pgsCast() +{ + pdelete(m_var); +} + +pgsExpression *pgsCast::clone() const +{ + return pnew pgsCast(*this); +} + +pgsCast::pgsCast(const pgsCast &that) : + pgsExpression(that), m_cast_type(that.m_cast_type) +{ + m_var = that.m_var->clone(); +} + +pgsCast &pgsCast::operator =(const pgsCast &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_cast_type = that.m_cast_type; + pdelete(m_var); + m_var = that.m_var->clone(); + } + return (*this); +} + +wxString pgsCast::value() const +{ + wxString cast_type; + + switch (m_cast_type) + { + case token::PGS_INTEGER: + cast_type = wxT("integer"); + break; + case token::PGS_REAL: + cast_type = wxT("real"); + break; + case token::PGS_RECORD: + cast_type = wxT("record"); + break; + case token::PGS_STRING: + cast_type = wxT("string"); + break; + default: + cast_type = wxT("unknown"); + break; + } + return wxString() << wxT("CAST (") << m_var->value() << wxT(" AS ") + << cast_type.Upper() << wxT(") "); +} + +pgsOperand pgsCast::eval(pgsVarMap &vars) const +{ + pgsOperand var = m_var->eval(vars); + MAPM num; + + switch (m_cast_type) + { + case token::PGS_INTEGER: + num = pgsMapm::pgs_str_mapm(var->number().value()); + num = pgsMapm::pgs_mapm_round(num); + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num, true), pgsInt); + case token::PGS_REAL: + return pnew pgsNumber(var->number().value(), pgsReal); + case token::PGS_RECORD: + return var->record().clone(); + case token::PGS_STRING: + return var->string().clone(); + default: + return var->clone(); + } +} diff --git a/pgscript/expressions/pgsColumns.cpp b/pgscript/expressions/pgsColumns.cpp new file mode 100644 index 0000000..1226c94 --- /dev/null +++ b/pgscript/expressions/pgsColumns.cpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsColumns.h" + +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" + +pgsColumns::pgsColumns(const wxString &name) : + pgsExpression(), m_name(name) +{ + +} + +pgsColumns::~pgsColumns() +{ + +} + +pgsExpression *pgsColumns::clone() const +{ + return pnew pgsColumns(*this); +} + +wxString pgsColumns::value() const +{ + return wxString() << wxT("COLUMNS(") << m_name << wxT(")"); +} + +pgsOperand pgsColumns::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end()) + { + if (vars[m_name]->is_record()) + { + const pgsRecord &rec = dynamic_cast(*vars[m_name]); + return pnew pgsNumber(wxString() << rec.count_columns(), pgsInt); + } + else + { + // Not a record: 1 line and 1 column + return pnew pgsNumber(wxT("1"), pgsInt); + } + } + else + { + // Does not exist: 0 line and 0 column + return pnew pgsNumber(wxT("0"), pgsInt); + } +} diff --git a/pgscript/expressions/pgsDifferent.cpp b/pgscript/expressions/pgsDifferent.cpp new file mode 100644 index 0000000..5e44ffd --- /dev/null +++ b/pgscript/expressions/pgsDifferent.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsDifferent.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsDifferent::pgsDifferent(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsDifferent::~pgsDifferent() +{ + +} + +pgsExpression *pgsDifferent::clone() const +{ + return pnew pgsDifferent(*this); +} + +pgsDifferent::pgsDifferent(const pgsDifferent &that) : + pgsOperation(that) +{ + +} + +pgsDifferent &pgsDifferent::operator =(const pgsDifferent &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsDifferent::value() const +{ + return wxString() << m_left->value() << wxT(" <> ") << m_right->value(); +} + +pgsOperand pgsDifferent::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left != *right); +} diff --git a/pgscript/expressions/pgsEqual.cpp b/pgscript/expressions/pgsEqual.cpp new file mode 100644 index 0000000..d071583 --- /dev/null +++ b/pgscript/expressions/pgsEqual.cpp @@ -0,0 +1,65 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsEqual.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsEqual::pgsEqual(const pgsExpression *left, const pgsExpression *right, + bool case_sensitive) : + pgsOperation(left, right), m_case_sensitive(case_sensitive) +{ + +} + +pgsEqual::~pgsEqual() +{ + +} + +pgsExpression *pgsEqual::clone() const +{ + return pnew pgsEqual(*this); +} + +pgsEqual::pgsEqual(const pgsEqual &that) : + pgsOperation(that), m_case_sensitive(that.m_case_sensitive) +{ + +} + +pgsEqual &pgsEqual::operator =(const pgsEqual &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + const pgsEqual *p = dynamic_cast(&that); + m_case_sensitive = (p != 0) ? + p->m_case_sensitive : true; + } + return (*this); +} + +wxString pgsEqual::value() const +{ + return wxString() << m_left->value() << (m_case_sensitive ? wxT(" = ") + : wxT(" ~= ")) << m_right->value(); +} + +pgsOperand pgsEqual::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (m_case_sensitive ? (*left == *right) : (*left &= *right)); +} diff --git a/pgscript/expressions/pgsExecute.cpp b/pgscript/expressions/pgsExecute.cpp new file mode 100644 index 0000000..d6ac015 --- /dev/null +++ b/pgscript/expressions/pgsExecute.cpp @@ -0,0 +1,230 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsExecute.h" + +#include +#include "db/pgConn.h" +#include "db/pgQueryThread.h" +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/utilities/pgsUtilities.h" +#include "pgscript/utilities/pgsThread.h" + +pgsExecute::pgsExecute(const wxString &query, pgsOutputStream *cout, + pgsThread *app) : + pgsExpression(), m_query(query), m_cout(cout), m_app(app) +{ + +} + +pgsExecute::~pgsExecute() +{ + +} + +pgsExpression *pgsExecute::clone() const +{ + return pnew pgsExecute(*this); +} + +pgsExecute &pgsExecute::operator=(const pgsExecute &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_query = that.m_query; + m_app = that.m_app; + m_query = that.m_query; + } + return (*this); +} + +wxString pgsExecute::value() const +{ + return m_query; +} + +pgsOperand pgsExecute::eval(pgsVarMap &vars) const +{ + // Copy statement locally + wxString stmt(m_query); + + // Build regular expressions + wxRegEx identifier(wxT("([^\\])(@[a-zA-Z0-9_#@]+)")); + wxRegEx escaped(wxT("\\\\(@|\\\\)")); // Backslash followed by @ or backslash + wxASSERT(identifier.IsValid() && escaped.IsValid()); + + // Replace variables in statement + while (identifier.Matches(stmt)) + { + wxString var = identifier.GetMatch(stmt, 2); + wxString chr = identifier.GetMatch(stmt, 1); + if (vars.find(var) != vars.end()) + { + wxString res = vars[var]->eval(vars)->value(); + identifier.ReplaceFirst(&stmt, chr + pgsUtilities::escape_quotes(res)); + } + else + { + identifier.ReplaceFirst(&stmt, chr + wxT("\\\\") + var); + } + } + escaped.ReplaceAll(&stmt, wxT("\\1")); + + // Perform operations only if we have a valid connection + if (m_app != 0 && m_app->connection() != 0 && !m_app->TestDestroy()) + { + pgQueryThread thread(m_app->connection(), stmt); + + if (thread.Create() == wxTHREAD_NO_ERROR) + { + if (thread.Run() == wxTHREAD_NO_ERROR) + { + while (true) + { + if (m_app->TestDestroy()) // wxThread::TestDestroy() + { + thread.Delete(); + break; + } + else if (thread.IsRunning()) + { + m_app->Yield(); + m_app->Sleep(20); + } + else + { + thread.Wait(); + break; + } + } + + if (thread.ReturnCode() != PGRES_COMMAND_OK + && thread.ReturnCode() != PGRES_TUPLES_OK) + { + if (m_cout != 0) + { + m_app->LockOutput(); + + (*m_cout) << PGSOUTWARNING; + wxString message(stmt + wxT("\n") + thread + .GetMessagesAndClear().Strip(wxString::both)); + wxRegEx multilf(wxT("(\n)+")); + multilf.ReplaceAll(&message, wxT("\n")); + message.Replace(wxT("\n"), wxT("\n") + + generate_spaces(PGSOUTWARNING.Length())); + (*m_cout) << message << wxT("\n"); + + m_app->UnlockOutput(); + } + } + else if (!m_app->TestDestroy()) + { + if (m_cout != 0) + { + m_app->LockOutput(); + + (*m_cout) << PGSOUTQUERY; + wxString message(thread.GetMessagesAndClear() + .Strip(wxString::both)); + if (!message.IsEmpty()) + message = stmt + wxT("\n") + message; + else + message = stmt; + wxRegEx multilf(wxT("(\n)+")); + multilf.ReplaceAll(&message, wxT("\n")); + message.Replace(wxT("\n"), wxT("\n") + + generate_spaces(PGSOUTQUERY.Length())); + (*m_cout) << message << wxT("\n"); + + m_app->UnlockOutput(); + } + + pgsRecord *rec = 0; + + if (thread.DataValid()) + { + pgSet *set = thread.DataSet(); + set->MoveFirst(); + rec = pnew pgsRecord(set->NumCols()); + wxArrayLong columns_int; // List of columns that contain integers + wxArrayLong columns_real; // List of columns that contain reals + for (long i = 0; i < set->NumCols(); i++) + { + rec->set_column_name(i, set->ColName(i)); + wxString col_type = set->ColType(i); + if (!col_type.CmpNoCase(wxT("bigint")) + || !col_type.CmpNoCase(wxT("smallint")) + || !col_type.CmpNoCase(wxT("integer"))) + { + columns_int.Add(i); + } + else if (!col_type.CmpNoCase(wxT("real")) + || !col_type.CmpNoCase(wxT("double precision")) + || !col_type.CmpNoCase(wxT("money")) + || !col_type.CmpNoCase(wxT("numeric"))) + { + columns_real.Add(i); + } + } + size_t line = 0; + while (!set->Eof()) + { + for (long i = 0; i < set->NumCols(); i++) + { + wxString value = set->GetVal(i); + + if (columns_int.Index(i) != wxNOT_FOUND + && pgsNumber::num_type(value) == pgsNumber::pgsTInt) + { + rec->insert(line, i, pnew pgsNumber(value, pgsInt)); + } + else if (columns_real.Index(i) != wxNOT_FOUND + && pgsNumber::num_type(value) == pgsNumber::pgsTReal) + { + rec->insert(line, i, pnew pgsNumber(value, pgsReal)); + } + else + { + rec->insert(line, i, pnew pgsString(value)); + } + } + set->MoveNext(); + ++line; + } + } + else + { + rec = pnew pgsRecord(1); + rec->insert(0, 0, pnew pgsNumber(wxT("1"))); + } + + return rec; + } + } + else + { + wxLogError(wxT("PGSCRIPT: Cannot run query thread for the query:\n%s"), + m_query.c_str()); + } + } + else + { + wxLogError(wxT("PGSCRIPT: Cannot create query thread for the query:\n%s"), + m_query.c_str()); + } + } + + // This must return a record whatever happens + return pnew pgsRecord(1); +} diff --git a/pgscript/expressions/pgsExpression.cpp b/pgscript/expressions/pgsExpression.cpp new file mode 100644 index 0000000..876cdba --- /dev/null +++ b/pgscript/expressions/pgsExpression.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsExpression.h" +#include "pgscript/objects/pgsVariable.h" + +pgsExpression::pgsExpression() +{ + +} + +pgsExpression::~pgsExpression() +{ + +} diff --git a/pgscript/expressions/pgsGenDate.cpp b/pgscript/expressions/pgsGenDate.cpp new file mode 100644 index 0000000..a393639 --- /dev/null +++ b/pgscript/expressions/pgsGenDate.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenDate.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDateGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenDate::pgsGenDate(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenDate::~pgsGenDate() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenDate::clone() const +{ + return pnew pgsGenDate(*this); +} + +pgsGenDate::pgsGenDate(const pgsGenDate &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenDate &pgsGenDate::operator =(const pgsGenDate &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenDate::value() const +{ + return wxString() << wxT("date[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenDate::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_string() && max->is_string() && sequence->is_integer() + && seed->is_integer()) + { + wxDateTime aux_min, aux_max; + if (aux_min.ParseDate(min->value()) != 0 && aux_max.ParseDate(max->value()) != 0 + && aux_min.IsValid() && aux_max.IsValid()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsDateGen(aux_min, aux_max, aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin and/or max dates are not valid")); + } + } + else + { + // Deal with errors + if (!min->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a string")); + } + else if (!max->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenDateTime.cpp b/pgscript/expressions/pgsGenDateTime.cpp new file mode 100644 index 0000000..cb77897 --- /dev/null +++ b/pgscript/expressions/pgsGenDateTime.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenDateTime.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDateTimeGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenDateTime::pgsGenDateTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenDateTime::~pgsGenDateTime() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenDateTime::clone() const +{ + return pnew pgsGenDateTime(*this); +} + +pgsGenDateTime::pgsGenDateTime(const pgsGenDateTime &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenDateTime &pgsGenDateTime::operator =(const pgsGenDateTime &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenDateTime::value() const +{ + return wxString() << wxT("date_time[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenDateTime::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_string() && max->is_string() && sequence->is_integer() + && seed->is_integer()) + { + wxDateTime aux_min, aux_max; + if (aux_min.ParseDateTime(min->value()) != 0 && aux_max.ParseDateTime(max->value()) != 0 + && aux_min.IsValid() && aux_max.IsValid()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsDateTimeGen(aux_min, aux_max, aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin and/or max datetimes are not valid")); + } + } + else + { + // Deal with errors + if (!min->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a string")); + } + else if (!max->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenDictionary.cpp b/pgscript/expressions/pgsGenDictionary.cpp new file mode 100644 index 0000000..4847fea --- /dev/null +++ b/pgscript/expressions/pgsGenDictionary.cpp @@ -0,0 +1,126 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenDictionary.h" + +#include +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDictionaryGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenDictionary::pgsGenDictionary(const pgsExpression *file_path, const pgsExpression *sequence, + const pgsExpression *seed, const pgsExpression *wx_conv) : + pgsExpression(), m_file_path(file_path), m_sequence(sequence), m_seed(seed), + m_wx_conv(wx_conv) +{ + +} + +pgsGenDictionary::~pgsGenDictionary() +{ + pdelete(m_file_path); + pdelete(m_sequence); + pdelete(m_seed); + pdelete(m_wx_conv); +} + +pgsExpression *pgsGenDictionary::clone() const +{ + return pnew pgsGenDictionary(*this); +} + +pgsGenDictionary::pgsGenDictionary(const pgsGenDictionary &that) : + pgsExpression(that) +{ + m_file_path = that.m_file_path->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_wx_conv = that.m_wx_conv->clone(); +} + +pgsGenDictionary &pgsGenDictionary::operator =(const pgsGenDictionary &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_file_path); + pdelete(m_sequence); + pdelete(m_seed); + pdelete(m_wx_conv); + m_file_path = that.m_file_path->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_wx_conv = that.m_wx_conv->clone(); + } + return (*this); +} + +wxString pgsGenDictionary::value() const +{ + return wxString() << wxT("file[ file = ") << m_file_path->value() << wxT(" sequence = ") + << m_sequence->value() << wxT(" seed = ") << m_seed->value() + << wxT(" encoding = ") << m_wx_conv->value() << wxT(" ]"); +} + +pgsOperand pgsGenDictionary::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand file_path(m_file_path->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + pgsOperand wx_conv(m_wx_conv->eval(vars)); + + // Check parameters and create the generator + if (file_path->is_string() && sequence->is_integer() && seed->is_integer() + && wx_conv->is_string()) + { + wxFileName file(file_path->value()); + if (file.FileExists() && file.IsFileReadable()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsDictionaryGen(file_path->value(), aux_sequence != 0, + aux_seed, wxCSConv(wx_conv->value()))); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nFile <") << file_path->value() + << wxT("> does not exist")); + } + } + else + { + // Deal with errors + if (!file_path->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nfile should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else if (!seed->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nencoding should be a string")); + } + } +} diff --git a/pgscript/expressions/pgsGenInt.cpp b/pgscript/expressions/pgsGenInt.cpp new file mode 100644 index 0000000..ddefb11 --- /dev/null +++ b/pgscript/expressions/pgsGenInt.cpp @@ -0,0 +1,114 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenInt.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsDictionaryGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenInt::pgsGenInt(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenInt::~pgsGenInt() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenInt::clone() const +{ + return pnew pgsGenInt(*this); +} + +pgsGenInt::pgsGenInt(const pgsGenInt &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenInt &pgsGenInt::operator =(const pgsGenInt &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenInt::value() const +{ + return wxString() << wxT("integer[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenInt::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_integer() && max->is_integer() && sequence->is_integer() + && seed->is_integer()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTInt, + pnew pgsIntegerGen(pgsVariable::num(min), pgsVariable::num(max), + aux_sequence != 0, aux_seed)); + } + else + { + // Deal with errors + if (!min->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be an integer")); + } + else if (!max->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be an integer")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenReal.cpp b/pgscript/expressions/pgsGenReal.cpp new file mode 100644 index 0000000..22a5153 --- /dev/null +++ b/pgscript/expressions/pgsGenReal.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenReal.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsRealGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenReal::pgsGenReal(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *precision, const pgsExpression *sequence, + const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_precision(precision), + m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenReal::~pgsGenReal() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_precision); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenReal::clone() const +{ + return pnew pgsGenReal(*this); +} + +pgsGenReal::pgsGenReal(const pgsGenReal &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_precision = that.m_precision->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenReal &pgsGenReal::operator =(const pgsGenReal &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_precision); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_precision = that.m_precision->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenReal::value() const +{ + return wxString() << wxT("real[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" precision = ") << m_precision->value() + << wxT(" sequence = ") << m_sequence->value() << wxT(" seed = ") + << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenReal::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand precision(m_precision->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_number() && max->is_number() && sequence->is_integer() + && seed->is_integer() && precision->is_integer()) + { + long aux_sequence, aux_seed, aux_precision; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + precision->value().ToLong(&aux_precision); + return pnew pgsGenerator(pgsVariable::pgsTReal, + pnew pgsRealGen(pgsVariable::num(min), pgsVariable::num(max), aux_precision, + aux_sequence != 0, aux_seed)); + } + else + { + // Deal with errors + if (!min->is_number()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a number")); + } + else if (!max->is_number()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a number")); + } + else if (!precision->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nprecision should be an integer")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenReference.cpp b/pgscript/expressions/pgsGenReference.cpp new file mode 100644 index 0000000..73a170c --- /dev/null +++ b/pgscript/expressions/pgsGenReference.cpp @@ -0,0 +1,131 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenReference.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsReferenceGen.h" +#include "pgscript/expressions/pgsExecute.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenReference::pgsGenReference(const pgsExpression *table, const pgsExpression *column, + const pgsExpression *sequence, const pgsExpression *seed, pgsThread *app) : + pgsExpression(), m_table(table), m_column(column), m_sequence(sequence), + m_seed(seed), m_app(app) +{ + +} + +pgsGenReference::~pgsGenReference() +{ + pdelete(m_table); + pdelete(m_column); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenReference::clone() const +{ + return pnew pgsGenReference(*this); +} + +pgsGenReference::pgsGenReference(const pgsGenReference &that) : + pgsExpression(that) +{ + m_table = that.m_table->clone(); + m_column = that.m_column->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_app = that.m_app; +} + +pgsGenReference &pgsGenReference::operator =(const pgsGenReference &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_table); + pdelete(m_column); + pdelete(m_sequence); + pdelete(m_seed); + m_table = that.m_table->clone(); + m_column = that.m_column->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + m_app = that.m_app; + } + return (*this); +} + +wxString pgsGenReference::value() const +{ + return wxString() << wxT("reference[ table = ") << m_table->value() + << wxT(" column = ") << m_column->value() << wxT(" sequence = ") + << m_sequence->value() << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenReference::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand table(m_table->eval(vars)); + pgsOperand column(m_column->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (table->is_string() && !table->value().IsEmpty() && column->is_string() + && !column->value().IsEmpty() && sequence->is_integer() + && seed->is_integer()) + { + // Check wheter the table and the column do exist + pgsOperand result = pgsExecute(wxString() << wxT("SELECT 1 FROM ") + << table->value() << wxT(" WHERE ") << column->value() + << wxT(" = ") << column->value(), 0, m_app).eval(vars); + if (result->pgs_is_true()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsReferenceGen(m_app, table->value(), + column->value(), aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\ntable/column does not exist")); + } + } + else + { + // Deal with errors + if (!table->is_string() || table->value().IsEmpty()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\ntable should be a non-empty string")); + } + else if (!column->is_string() || column->value().IsEmpty()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\ncolumn should be a non-empty string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenRegex.cpp b/pgscript/expressions/pgsGenRegex.cpp new file mode 100644 index 0000000..1d4a9dd --- /dev/null +++ b/pgscript/expressions/pgsGenRegex.cpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenRegex.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsRegexGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenRegex::pgsGenRegex(const pgsExpression *regex, const pgsExpression *seed) : + pgsExpression(), m_regex(regex), m_seed(seed) +{ + +} + +pgsGenRegex::~pgsGenRegex() +{ + pdelete(m_regex); + pdelete(m_seed); +} + +pgsExpression *pgsGenRegex::clone() const +{ + return pnew pgsGenRegex(*this); +} + +pgsGenRegex::pgsGenRegex(const pgsGenRegex &that) : + pgsExpression(that) +{ + m_regex = that.m_regex->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenRegex &pgsGenRegex::operator =(const pgsGenRegex &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_regex); + pdelete(m_seed); + m_regex = that.m_regex->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenRegex::value() const +{ + return wxString() << wxT("string[ regex = ") << m_regex->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenRegex::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand regex(m_regex->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (regex->is_string() && seed->is_integer()) + { + long aux_seed; + seed->value().ToLong(&aux_seed); + pgsRegexGen *gen = pnew pgsRegexGen(regex->value(), aux_seed); + if (!gen->is_valid()) + { + pdelete(gen); + throw pgsParameterException(wxString() << value() + << wxT(":\nregex is not a valid regular expression")); + } + else + { + return pnew pgsGenerator(pgsVariable::pgsTString, gen); + } + } + else + { + // Deal with errors + if (!regex->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nregex should be a string")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenString.cpp b/pgscript/expressions/pgsGenString.cpp new file mode 100644 index 0000000..b8ffb9a --- /dev/null +++ b/pgscript/expressions/pgsGenString.cpp @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenString.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsStringGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenString::pgsGenString(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *nb_words, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_nb_words(nb_words), m_seed(seed) +{ + +} + +pgsGenString::~pgsGenString() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_nb_words); + pdelete(m_seed); +} + +pgsExpression *pgsGenString::clone() const +{ + return pnew pgsGenString(*this); +} + +pgsGenString::pgsGenString(const pgsGenString &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_nb_words = that.m_nb_words->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenString &pgsGenString::operator =(const pgsGenString &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_nb_words); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_nb_words = that.m_nb_words->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenString::value() const +{ + return wxString() << wxT("string[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" nb_words = ") << m_nb_words->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenString::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand nb_words(m_nb_words->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_integer() && max->is_integer() && nb_words->is_integer() + && seed->is_integer()) + { + long aux_min, aux_max, aux_nb_words, aux_seed; + min->value().ToLong(&aux_min); + max->value().ToLong(&aux_max); + nb_words->value().ToLong(&aux_nb_words); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsStringGen(aux_min, aux_max, aux_nb_words, aux_seed)); + } + else + { + // Deal with errors + if (!min->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be an integer")); + } + else if (!max->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be an integer")); + } + else if (!nb_words->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nnb_words should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGenTime.cpp b/pgscript/expressions/pgsGenTime.cpp new file mode 100644 index 0000000..3a6aaa5 --- /dev/null +++ b/pgscript/expressions/pgsGenTime.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGenTime.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/generators/pgsTimeGen.h" +#include "pgscript/objects/pgsGenerator.h" + +pgsGenTime::pgsGenTime(const pgsExpression *min, const pgsExpression *max, + const pgsExpression *sequence, const pgsExpression *seed) : + pgsExpression(), m_min(min), m_max(max), m_sequence(sequence), m_seed(seed) +{ + +} + +pgsGenTime::~pgsGenTime() +{ + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); +} + +pgsExpression *pgsGenTime::clone() const +{ + return pnew pgsGenTime(*this); +} + +pgsGenTime::pgsGenTime(const pgsGenTime &that) : + pgsExpression(that) +{ + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); +} + +pgsGenTime &pgsGenTime::operator =(const pgsGenTime &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_min); + pdelete(m_max); + pdelete(m_sequence); + pdelete(m_seed); + m_min = that.m_min->clone(); + m_max = that.m_max->clone(); + m_sequence = that.m_sequence->clone(); + m_seed = that.m_seed->clone(); + } + return (*this); +} + +wxString pgsGenTime::value() const +{ + return wxString() << wxT("time[ min = ") << m_min->value() << wxT(" max = ") + << m_max->value() << wxT(" sequence = ") << m_sequence->value() + << wxT(" seed = ") << m_seed->value() << wxT(" ]"); +} + +pgsOperand pgsGenTime::eval(pgsVarMap &vars) const +{ + // Evaluate parameters + pgsOperand min(m_min->eval(vars)); + pgsOperand max(m_max->eval(vars)); + pgsOperand sequence(m_sequence->eval(vars)); + pgsOperand seed(m_seed->eval(vars)); + + // Check parameters and create the generator + if (min->is_string() && max->is_string() && sequence->is_integer() + && seed->is_integer()) + { + wxDateTime aux_min, aux_max; + if (aux_min.ParseTime(min->value()) != 0 && aux_max.ParseTime(max->value()) != 0 + && aux_min.IsValid() && aux_max.IsValid()) + { + long aux_sequence, aux_seed; + sequence->value().ToLong(&aux_sequence); + seed->value().ToLong(&aux_seed); + return pnew pgsGenerator(pgsVariable::pgsTString, + pnew pgsTimeGen(aux_min, aux_max, aux_sequence != 0, aux_seed)); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin and/or max times are not valid")); + } + } + else + { + // Deal with errors + if (!min->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmin should be a string")); + } + else if (!max->is_string()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nmax should be a string")); + } + else if (!sequence->is_integer()) + { + throw pgsParameterException(wxString() << value() + << wxT(":\nsequence should be an integer")); + } + else + { + throw pgsParameterException(wxString() << value() + << wxT(":\nseed should be an integer")); + } + } +} diff --git a/pgscript/expressions/pgsGreater.cpp b/pgscript/expressions/pgsGreater.cpp new file mode 100644 index 0000000..fcfc942 --- /dev/null +++ b/pgscript/expressions/pgsGreater.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGreater.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsGreater::pgsGreater(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsGreater::~pgsGreater() +{ + +} + +pgsExpression *pgsGreater::clone() const +{ + return pnew pgsGreater(*this); +} + +pgsGreater::pgsGreater(const pgsGreater &that) : + pgsOperation(that) +{ + +} + +pgsGreater &pgsGreater::operator =(const pgsGreater &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsGreater::value() const +{ + return wxString() << m_left->value() << wxT(" > ") << m_right->value(); +} + +pgsOperand pgsGreater::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left > *right); +} diff --git a/pgscript/expressions/pgsGreaterEqual.cpp b/pgscript/expressions/pgsGreaterEqual.cpp new file mode 100644 index 0000000..ba07f58 --- /dev/null +++ b/pgscript/expressions/pgsGreaterEqual.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsGreaterEqual.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsGreaterEqual::pgsGreaterEqual(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsGreaterEqual::~pgsGreaterEqual() +{ + +} + +pgsExpression *pgsGreaterEqual::clone() const +{ + return pnew pgsGreaterEqual(*this); +} + +pgsGreaterEqual::pgsGreaterEqual(const pgsGreaterEqual &that) : + pgsOperation(that) +{ + +} + +pgsGreaterEqual &pgsGreaterEqual::operator =(const pgsGreaterEqual &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsGreaterEqual::value() const +{ + return wxString() << m_left->value() << wxT(" >= ") << m_right->value(); +} + +pgsOperand pgsGreaterEqual::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left >= *right); +} diff --git a/pgscript/expressions/pgsIdent.cpp b/pgscript/expressions/pgsIdent.cpp new file mode 100644 index 0000000..19d9f60 --- /dev/null +++ b/pgscript/expressions/pgsIdent.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsIdent.h" + +#include +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsString.h" + +const wxString pgsIdent::m_now = wxT("@NOW"); + +pgsIdent::pgsIdent(const wxString &name) : + pgsExpression(), m_name(name) +{ + +} + +pgsIdent::~pgsIdent() +{ + +} + +pgsExpression *pgsIdent::clone() const +{ + return pnew pgsIdent(*this); +} + +wxString pgsIdent::value() const +{ + return m_name; +} + +pgsOperand pgsIdent::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end()) + { + return vars[m_name]; + } + else if (m_name == m_now) + { + time_t now = wxDateTime::GetTimeNow(); + return pnew pgsNumber(wxString() << now); + } + else + { + return pnew pgsString(wxT("")); + } +} diff --git a/pgscript/expressions/pgsIdentRecord.cpp b/pgscript/expressions/pgsIdentRecord.cpp new file mode 100644 index 0000000..5571d70 --- /dev/null +++ b/pgscript/expressions/pgsIdentRecord.cpp @@ -0,0 +1,103 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsIdentRecord.h" + +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" + +pgsIdentRecord::pgsIdentRecord(const wxString &name, const pgsExpression *line, + const pgsExpression *column) : + pgsIdent(name), m_line(line), m_column(column) +{ + +} + +pgsIdentRecord::~pgsIdentRecord() +{ + pdelete(m_line); + pdelete(m_column); +} + +pgsExpression *pgsIdentRecord::clone() const +{ + return pnew pgsIdentRecord(*this); +} + +pgsIdentRecord::pgsIdentRecord(const pgsIdentRecord &that) : + pgsIdent(that) +{ + m_line = that.m_line->clone(); + m_column = that.m_column != 0 ? that.m_column->clone() : 0; +} + +pgsIdentRecord &pgsIdentRecord::operator=(const pgsIdentRecord &that) +{ + if (this != &that) + { + pgsIdent::operator=(that); + pdelete(m_line); + pdelete(m_column); + m_line = that.m_line->clone(); + m_column = that.m_column != 0 ? that.m_column->clone() : 0; + } + return (*this); +} + +wxString pgsIdentRecord::value() const +{ + wxString result; + result << m_name << wxT("[") << m_line->value() << wxT("]"); + if (m_column != 0) + { + result << wxT("[") << m_column->value() << wxT("]"); + } + return result; +} + +pgsOperand pgsIdentRecord::eval(pgsVarMap &vars) const +{ + // Check whether the variable is a record + if (vars.find(m_name) != vars.end() && vars[m_name]->is_record()) + { + // Get the operand as a record + const pgsRecord &rec = dynamic_cast(*vars[m_name]); + + // Evaluate parameters + pgsOperand line(m_line->eval(vars)); + if (line->is_integer()) + { + long aux_line; + line->value().ToLong(&aux_line); + + if (m_column != 0) + { + pgsOperand column(m_column->eval(vars)); + if (column->is_integer()) + { + long aux_column; + column->value().ToLong(&aux_column); + return rec.get(aux_line, aux_column); + } + else if (column->is_string()) + { + return rec.get(aux_line, rec.get_column(column->value())); + } + } + else + { + return rec.get_line(aux_line); + } + } + } + + return pnew pgsString(wxT("")); +} diff --git a/pgscript/expressions/pgsLines.cpp b/pgscript/expressions/pgsLines.cpp new file mode 100644 index 0000000..2bdc021 --- /dev/null +++ b/pgscript/expressions/pgsLines.cpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsLines.h" + +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" + +pgsLines::pgsLines(const wxString &name) : + pgsExpression(), m_name(name) +{ + +} + +pgsLines::~pgsLines() +{ + +} + +pgsExpression *pgsLines::clone() const +{ + return pnew pgsLines(*this); +} + +wxString pgsLines::value() const +{ + return wxString() << wxT("LINES(") << m_name << wxT(")"); +} + +pgsOperand pgsLines::eval(pgsVarMap &vars) const +{ + if (vars.find(m_name) != vars.end()) + { + if (vars[m_name]->is_record()) + { + const pgsRecord &rec = dynamic_cast(*vars[m_name]); + return pnew pgsNumber(wxString() << rec.count_lines(), pgsInt); + } + else + { + // Not a record: 1 line and 1 column + return pnew pgsNumber(wxT("1"), pgsInt); + } + } + else + { + // Does not exist: 0 line and 0 column + return pnew pgsNumber(wxT("0"), pgsInt); + } +} diff --git a/pgscript/expressions/pgsLower.cpp b/pgscript/expressions/pgsLower.cpp new file mode 100644 index 0000000..8702a9c --- /dev/null +++ b/pgscript/expressions/pgsLower.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsLower.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsLower::pgsLower(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsLower::~pgsLower() +{ + +} + +pgsExpression *pgsLower::clone() const +{ + return pnew pgsLower(*this); +} + +pgsLower::pgsLower(const pgsLower &that) : + pgsOperation(that) +{ + +} + +pgsLower &pgsLower::operator =(const pgsLower &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsLower::value() const +{ + return wxString() << m_left->value() << wxT(" < ") << m_right->value(); +} + +pgsOperand pgsLower::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left < *right); +} diff --git a/pgscript/expressions/pgsLowerEqual.cpp b/pgscript/expressions/pgsLowerEqual.cpp new file mode 100644 index 0000000..c2fac92 --- /dev/null +++ b/pgscript/expressions/pgsLowerEqual.cpp @@ -0,0 +1,61 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsLowerEqual.h" +#include "pgscript/objects/pgsRecord.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsLowerEqual::pgsLowerEqual(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsLowerEqual::~pgsLowerEqual() +{ + +} + +pgsExpression *pgsLowerEqual::clone() const +{ + return pnew pgsLowerEqual(*this); +} + +pgsLowerEqual::pgsLowerEqual(const pgsLowerEqual &that) : + pgsOperation(that) +{ + +} + +pgsLowerEqual &pgsLowerEqual::operator =(const pgsLowerEqual &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsLowerEqual::value() const +{ + return wxString() << m_left->value() << wxT(" <= ") << m_right->value(); +} + +pgsOperand pgsLowerEqual::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left <= *right); +} diff --git a/pgscript/expressions/pgsMinus.cpp b/pgscript/expressions/pgsMinus.cpp new file mode 100644 index 0000000..8b65011 --- /dev/null +++ b/pgscript/expressions/pgsMinus.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsMinus.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsMinus::pgsMinus(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsMinus::~pgsMinus() +{ + +} + +pgsExpression *pgsMinus::clone() const +{ + return pnew pgsMinus(*this); +} + +pgsMinus::pgsMinus(const pgsMinus &that) : + pgsOperation(that) +{ + +} + +pgsMinus &pgsMinus::operator =(const pgsMinus &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsMinus::value() const +{ + return wxString() << m_left->value() << wxT(" - ") << m_right->value(); +} + +pgsOperand pgsMinus::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left - *right); +} diff --git a/pgscript/expressions/pgsModulo.cpp b/pgscript/expressions/pgsModulo.cpp new file mode 100644 index 0000000..f7aa9b6 --- /dev/null +++ b/pgscript/expressions/pgsModulo.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsModulo.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsModulo::pgsModulo(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsModulo::~pgsModulo() +{ + +} + +pgsExpression *pgsModulo::clone() const +{ + return pnew pgsModulo(*this); +} + +pgsModulo::pgsModulo(const pgsModulo &that) : + pgsOperation(that) +{ + +} + +pgsModulo &pgsModulo::operator =(const pgsModulo &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsModulo::value() const +{ + return wxString() << m_left->value() << wxT(" % ") << m_right->value(); +} + +pgsOperand pgsModulo::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left % *right); +} diff --git a/pgscript/expressions/pgsNegate.cpp b/pgscript/expressions/pgsNegate.cpp new file mode 100644 index 0000000..9c2b987 --- /dev/null +++ b/pgscript/expressions/pgsNegate.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsNegate.h" + +#include "pgscript/objects/pgsNumber.h" + +pgsNegate::pgsNegate(const pgsExpression *left) : + pgsOperation(left, 0) +{ + +} + +pgsNegate::~pgsNegate() +{ + +} + +pgsExpression *pgsNegate::clone() const +{ + return pnew pgsNegate(*this); +} + +pgsNegate::pgsNegate(const pgsNegate &that) : + pgsOperation(that) +{ + +} + +pgsNegate &pgsNegate::operator =(const pgsNegate &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsNegate::value() const +{ + return wxString() << wxT("-") << m_left->value(); +} + +pgsOperand pgsNegate::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(pnew pgsNumber(wxT("0"), pgsInt)); + pgsOperand right(m_left->eval(vars)); + + // Return the result + return (*left - *right); +} diff --git a/pgscript/expressions/pgsNot.cpp b/pgscript/expressions/pgsNot.cpp new file mode 100644 index 0000000..a7b29fa --- /dev/null +++ b/pgscript/expressions/pgsNot.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsNot.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsNot::pgsNot(const pgsExpression *left) : + pgsOperation(left, 0) +{ + +} + +pgsNot::~pgsNot() +{ + +} + +pgsExpression *pgsNot::clone() const +{ + return pnew pgsNot(*this); +} + +pgsNot::pgsNot(const pgsNot &that) : + pgsOperation(that) +{ + +} + +pgsNot &pgsNot::operator =(const pgsNot &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsNot::value() const +{ + return wxString() << wxT("NOT ") << m_left->value(); +} + +pgsOperand pgsNot::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + + // Return the result + return (!(*left)); +} diff --git a/pgscript/expressions/pgsOperation.cpp b/pgscript/expressions/pgsOperation.cpp new file mode 100644 index 0000000..6bfb56e --- /dev/null +++ b/pgscript/expressions/pgsOperation.cpp @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsOperation.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsOperation::pgsOperation(const pgsExpression *left, const pgsExpression *right) : + pgsExpression(), m_left(left), m_right(right) +{ + +} + +pgsOperation::~pgsOperation() +{ + pdelete(m_left); + pdelete(m_right); +} + +pgsOperation::pgsOperation(const pgsOperation &that) : + pgsExpression(that) +{ + m_left = that.m_left->clone(); + m_right = that.m_right != 0 ? that.m_right->clone() : 0; +} + +pgsOperation &pgsOperation::operator =(const pgsOperation &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_left); + pdelete(m_right); + m_left = that.m_left->clone(); + m_right = that.m_right != 0 ? that.m_right->clone() : 0; + } + return (*this); +} diff --git a/pgscript/expressions/pgsOr.cpp b/pgscript/expressions/pgsOr.cpp new file mode 100644 index 0000000..f2c8234 --- /dev/null +++ b/pgscript/expressions/pgsOr.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsOr.h" + +#include "pgscript/objects/pgsNumber.h" + +pgsOr::pgsOr(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsOr::~pgsOr() +{ + +} + +pgsExpression *pgsOr::clone() const +{ + return pnew pgsOr(*this); +} + +pgsOr::pgsOr(const pgsOr &that) : + pgsOperation(that) +{ + +} + +pgsOr &pgsOr::operator =(const pgsOr &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsOr::value() const +{ + return wxString() << m_left->value() << wxT(" OR ") << m_right->value(); +} + +pgsOperand pgsOr::eval(pgsVarMap &vars) const +{ + return pnew pgsNumber(wxString() << (m_left->eval(vars)->pgs_is_true() + || m_right->eval(vars)->pgs_is_true()), pgsInt); +} diff --git a/pgscript/expressions/pgsOver.cpp b/pgscript/expressions/pgsOver.cpp new file mode 100644 index 0000000..5905581 --- /dev/null +++ b/pgscript/expressions/pgsOver.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsOver.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsOver::pgsOver(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsOver::~pgsOver() +{ + +} + +pgsExpression *pgsOver::clone() const +{ + return pnew pgsOver(*this); +} + +pgsOver::pgsOver(const pgsOver &that) : + pgsOperation(that) +{ + +} + +pgsOver &pgsOver::operator =(const pgsOver &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsOver::value() const +{ + return wxString() << m_left->value() << wxT(" / ") << m_right->value(); +} + +pgsOperand pgsOver::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left / *right); +} diff --git a/pgscript/expressions/pgsParenthesis.cpp b/pgscript/expressions/pgsParenthesis.cpp new file mode 100644 index 0000000..7474104 --- /dev/null +++ b/pgscript/expressions/pgsParenthesis.cpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsParenthesis.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsParenthesis::pgsParenthesis(const pgsExpression *left) : + pgsOperation(left, 0) +{ + +} + +pgsParenthesis::~pgsParenthesis() +{ + +} + +pgsExpression *pgsParenthesis::clone() const +{ + return pnew pgsParenthesis(*this); +} + +pgsParenthesis::pgsParenthesis(const pgsParenthesis &that) : + pgsOperation(that) +{ + +} + +pgsParenthesis &pgsParenthesis::operator =(const pgsParenthesis &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsParenthesis::value() const +{ + return wxString() << wxT("(") << m_left->value() << wxT(")"); +} + +pgsOperand pgsParenthesis::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + + // Return the result + return left; +} diff --git a/pgscript/expressions/pgsPlus.cpp b/pgscript/expressions/pgsPlus.cpp new file mode 100644 index 0000000..20c73c8 --- /dev/null +++ b/pgscript/expressions/pgsPlus.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsPlus.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsPlus::pgsPlus(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsPlus::~pgsPlus() +{ + +} + +pgsExpression *pgsPlus::clone() const +{ + return pnew pgsPlus(*this); +} + +pgsPlus::pgsPlus(const pgsPlus &that) : + pgsOperation(that) +{ + +} + +pgsPlus &pgsPlus::operator =(const pgsPlus &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsPlus::value() const +{ + return wxString() << m_left->value() << wxT(" + ") << m_right->value(); +} + +pgsOperand pgsPlus::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left + *right); +} diff --git a/pgscript/expressions/pgsRemoveLine.cpp b/pgscript/expressions/pgsRemoveLine.cpp new file mode 100644 index 0000000..38a23e0 --- /dev/null +++ b/pgscript/expressions/pgsRemoveLine.cpp @@ -0,0 +1,89 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsRemoveLine.h" + +#include "pgscript/exceptions/pgsParameterException.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" + +pgsRemoveLine::pgsRemoveLine(const wxString &rec, const pgsExpression *line) : + pgsExpression(), m_rec(rec), m_line(line) +{ + +} + +pgsRemoveLine::~pgsRemoveLine() +{ + pdelete(m_line); +} + +pgsExpression *pgsRemoveLine::clone() const +{ + return pnew pgsRemoveLine(*this); +} + +pgsRemoveLine::pgsRemoveLine(const pgsRemoveLine &that) : + pgsExpression(that), m_rec(that.m_rec) +{ + m_line = that.m_line->clone(); +} + +pgsRemoveLine &pgsRemoveLine::operator =(const pgsRemoveLine &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + m_rec = that.m_rec; + pdelete(m_line); + m_line = that.m_line->clone(); + } + return (*this); +} + +wxString pgsRemoveLine::value() const +{ + return wxString() << wxT("RMLINE(") << m_rec << wxT("[") + << m_line->value() << wxT("])"); +} + +pgsOperand pgsRemoveLine::eval(pgsVarMap &vars) const +{ + if (vars.find(m_rec) != vars.end() && vars[m_rec]->is_record()) + { + pgsRecord &rec = dynamic_cast(*vars[m_rec]); + + // Evaluate parameter + pgsOperand line(m_line->eval(vars)); + if (line->is_integer()) + { + long aux_line; + line->value().ToLong(&aux_line); + + if (!rec.remove_line(aux_line)) + { + throw pgsParameterException(wxString() << wxT("an error ") + << wxT("occurred while executing ") << value()); + } + } + else + { + throw pgsParameterException(wxString() << line->value() + << wxT(" is not a valid line number")); + } + + return vars[m_rec]; + } + else + { + throw pgsParameterException(wxString() << m_rec << wxT(" is not a record")); + } +} diff --git a/pgscript/expressions/pgsTimes.cpp b/pgscript/expressions/pgsTimes.cpp new file mode 100644 index 0000000..83ba59e --- /dev/null +++ b/pgscript/expressions/pgsTimes.cpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsTimes.h" + +#include "pgscript/objects/pgsVariable.h" + +pgsTimes::pgsTimes(const pgsExpression *left, const pgsExpression *right) : + pgsOperation(left, right) +{ + +} + +pgsTimes::~pgsTimes() +{ + +} + +pgsExpression *pgsTimes::clone() const +{ + return pnew pgsTimes(*this); +} + +pgsTimes::pgsTimes(const pgsTimes &that) : + pgsOperation(that) +{ + +} + +pgsTimes &pgsTimes::operator =(const pgsTimes &that) +{ + if (this != &that) + { + pgsOperation::operator=(that); + } + return (*this); +} + +wxString pgsTimes::value() const +{ + return wxString() << m_left->value() << wxT(" * ") << m_right->value(); +} + +pgsOperand pgsTimes::eval(pgsVarMap &vars) const +{ + // Evaluate operands + pgsOperand left(m_left->eval(vars)); + pgsOperand right(m_right->eval(vars)); + + // Return the result + return (*left **right); +} diff --git a/pgscript/expressions/pgsTrim.cpp b/pgscript/expressions/pgsTrim.cpp new file mode 100644 index 0000000..f824ff3 --- /dev/null +++ b/pgscript/expressions/pgsTrim.cpp @@ -0,0 +1,57 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/expressions/pgsTrim.h" + +#include "pgscript/objects/pgsString.h" + +pgsTrim::pgsTrim(const pgsExpression *exp) : + pgsExpression(), m_exp(exp) +{ + +} + +pgsTrim::~pgsTrim() +{ + pdelete(m_exp); +} + +pgsTrim::pgsTrim(const pgsTrim &that) : + pgsExpression(that) +{ + m_exp = that.m_exp->clone(); +} + +pgsTrim &pgsTrim::operator=(const pgsTrim &that) +{ + if (this != &that) + { + pgsExpression::operator=(that); + pdelete(m_exp); + m_exp = that.m_exp->clone(); + } + return (*this); +} + +pgsExpression *pgsTrim::clone() const +{ + return pnew pgsTrim(*this); +} + +wxString pgsTrim::value() const +{ + return wxString() << wxT("TRIM(") << m_exp->value() << wxT(")"); +} + +pgsOperand pgsTrim::eval(pgsVarMap &vars) const +{ + return pnew pgsString(m_exp->eval(vars)->value().Strip(wxString::both)); +} diff --git a/pgscript/generators/module.mk b/pgscript/generators/module.mk new file mode 100644 index 0000000..1b83871 --- /dev/null +++ b/pgscript/generators/module.mk @@ -0,0 +1,27 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/generators/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/generators/pgsDateGen.cpp \ + pgscript/generators/pgsDateTimeGen.cpp \ + pgscript/generators/pgsDictionaryGen.cpp \ + pgscript/generators/pgsIntegerGen.cpp \ + pgscript/generators/pgsNumberGen.cpp \ + pgscript/generators/pgsObjectGen.cpp \ + pgscript/generators/pgsRealGen.cpp \ + pgscript/generators/pgsReferenceGen.cpp \ + pgscript/generators/pgsRegexGen.cpp \ + pgscript/generators/pgsStringGen.cpp \ + pgscript/generators/pgsTimeGen.cpp + +EXTRA_DIST += \ + pgscript/generators/module.mk + diff --git a/pgscript/generators/pgsDateGen.cpp b/pgscript/generators/pgsDateGen.cpp new file mode 100644 index 0000000..a0bfbeb --- /dev/null +++ b/pgscript/generators/pgsDateGen.cpp @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsDateGen.h" + +pgsDateGen::pgsDateGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed) : + pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max), + m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min), + m_range(m_max.Subtract(m_min).GetDays()), m_sequence(sequence) +{ + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, m_range, is_sequence(), + m_seed)); +} + +bool pgsDateGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsDateGen::random() +{ + wxDateSpan date_span(0, 0, 0, m_randomizer->random_long()); + wxDateTime aux_min(m_min); + aux_min.Add(date_span); + wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min)); + wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max)); + return aux_min.FormatISODate(); +} + +pgsDateGen::~pgsDateGen() +{ + +} + +pgsDateGen *pgsDateGen::clone() +{ + return pnew pgsDateGen(*this); +} diff --git a/pgscript/generators/pgsDateTimeGen.cpp b/pgscript/generators/pgsDateTimeGen.cpp new file mode 100644 index 0000000..76098fc --- /dev/null +++ b/pgscript/generators/pgsDateTimeGen.cpp @@ -0,0 +1,62 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsDateTimeGen.h" + +#include + +pgsDateTimeGen::pgsDateTimeGen(wxDateTime min, wxDateTime max, + const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max), + m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min), + m_range(m_max.Subtract(m_min).GetSeconds()), m_sequence(sequence) +{ + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, std::string(m_range + .ToString().mb_str()).c_str(), is_sequence(), m_seed)); +} + +bool pgsDateTimeGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsDateTimeGen::random() +{ + // Get a random number representing seconds + MAPM result = pgsMapm::pgs_str_mapm(m_randomizer->random()), quot, rem; + + // Use hours and seconds for avoiding overflows of seconds + result.integer_div_rem(3600, quot, rem); + long hours, seconds; + pgsMapm::pgs_mapm_str(quot, true).ToLong(&hours); + pgsMapm::pgs_mapm_str(rem, true).ToLong(&seconds); + wxTimeSpan time_span(hours, 0, seconds, 0); + + // Add the TimeSpan to the MinDate + wxDateTime aux_min(m_min); + aux_min.Add(time_span); + + // Post conditions + wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min)); + wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max)); + + return aux_min.Format(wxT("%Y-%m-%d %H:%M:%S")); +} + +pgsDateTimeGen::~pgsDateTimeGen() +{ + +} + +pgsDateTimeGen *pgsDateTimeGen::clone() +{ + return pnew pgsDateTimeGen(*this); +} diff --git a/pgscript/generators/pgsDictionaryGen.cpp b/pgscript/generators/pgsDictionaryGen.cpp new file mode 100644 index 0000000..a339c72 --- /dev/null +++ b/pgscript/generators/pgsDictionaryGen.cpp @@ -0,0 +1,99 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsDictionaryGen.h" + +#include +#include +#include + +pgsDictionaryGen::pgsDictionaryGen(const wxString &file_path, + const bool &sequence, const long &seed, wxCSConv conv) : + pgsObjectGen(seed), m_file_path(file_path), m_conv(conv) +{ + m_nb_lines = this->count_lines(); + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(1, m_nb_lines, + sequence, seed)); +} + +wxString pgsDictionaryGen::random() +{ + return this->get_line(m_randomizer->random_long()); +} + +pgsDictionaryGen::~pgsDictionaryGen() +{ + +} + +pgsDictionaryGen *pgsDictionaryGen::clone() +{ + return pnew pgsDictionaryGen(*this); +} + +const long &pgsDictionaryGen::nb_lines() const +{ + return m_nb_lines; +} + +long pgsDictionaryGen::count_lines() +{ + long result = 0; + + wxFileName file_path(m_file_path); + if (file_path.FileExists() && file_path.IsFileReadable()) + { + wxFFileInputStream input(m_file_path); + if (input.IsOk()) + { +#if wxUSE_UNICODE + wxTextInputStream text(input, wxT(" \t"), m_conv); +#else + wxTextInputStream text(input, wxT(" \t")); +#endif + wxString line; + while (!(line = text.ReadLine()).IsEmpty() && !input.Eof()) + { + ++result; + } + } + } + + if (result < 0) result = 0; + wxASSERT(result >= 0); + return result; +} + +wxString pgsDictionaryGen::get_line(long line_nb) +{ + long current_line = 1; + + if (m_nb_lines > 0) + { + wxFFileInputStream input(m_file_path); + if (input.IsOk()) + { +#if wxUSE_UNICODE + wxTextInputStream text(input, wxT(" \t"), m_conv); +#else + wxTextInputStream text(input, wxT(" \t")); +#endif + while (current_line < line_nb && !input.Eof()) + { + text.ReadLine(); + ++current_line; + } + return text.ReadLine(); + } + } + + return wxString(); +} diff --git a/pgscript/generators/pgsIntegerGen.cpp b/pgscript/generators/pgsIntegerGen.cpp new file mode 100644 index 0000000..def1fbc --- /dev/null +++ b/pgscript/generators/pgsIntegerGen.cpp @@ -0,0 +1,174 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsIntegerGen.h" + +pgsIntegerGen::pgsSequentialIntGen::pgsSequentialIntGen(const MAPM &range, + const long &seed) : + pgsNumberGen(range), m_state(seed), m_m(2), m_remainder(m_range) +{ + MAPM _2 = 2; + while (m_m < m_range) + { + m_m = m_m * _2; + } + m_buffer.Alloc(BUFFER_SIZE); +} + +MAPM pgsIntegerGen::pgsSequentialIntGen::random() +{ + // Bufferizer BUFFER_SIZE values in the vector + if (m_buffer.GetCount() == 0) + { + // Calculate the number of elements to bufferize + MAPM min = wxMin(m_remainder, MAPM(BUFFER_SIZE)); + + // Generate those elements + for (MAPM i = 0; i < min; i = i + 1) + { + do + { + m_state = (m_state * arg_a); + m_state = (m_state + arg_c) % m_m; + } + while (m_state >= m_range); + m_buffer.Add(m_state); + m_remainder -= 1; + } + + class pgsRandInt + { + + private: + + long m_state; + + public: + + pgsRandInt(long n) + : m_state(n) + { + + } + + long rand() + { + m_state = (1103515245L * m_state + 12345L) % 2147483647L; + return m_state; + } + + }; + + // Shuffle the vector of generated values + pgsRandInt rand_int(BUFFER_SIZE); + for (size_t i = 0; i < m_buffer.GetCount(); i++) + { + size_t r = i + (rand_int.rand() % (m_buffer.GetCount() - i)); + const MAPM a = m_buffer.Item(i); + m_buffer.Item(i) = m_buffer.Item(r); + m_buffer.Item(r) = a; + } + } + + if (m_remainder == 0) + { + m_remainder = m_range; + } + + // Take the last bufferized value + MAPM data = m_buffer.Last(); + m_buffer.RemoveAt(m_buffer.GetCount() - 1); + + // Return random value + return data; +} + +pgsIntegerGen::pgsSequentialIntGen::~pgsSequentialIntGen() +{ + +} + +pgsNumberGen *pgsIntegerGen::pgsSequentialIntGen::clone() +{ + return pnew pgsIntegerGen::pgsSequentialIntGen(*this); +} + +const MAPM pgsIntegerGen::pgsSequentialIntGen::arg_a = 5; +const MAPM pgsIntegerGen::pgsSequentialIntGen::arg_c = 1; + +pgsIntegerGen::pgsNormalIntGen::pgsNormalIntGen(const MAPM &range, + const long &seed) : + pgsNumberGen(range), m_state(seed), m_top(arg_m - 1) +{ + for (int i = 0; i < 10; i++) + random(); // Beginning of the sequence is garbage +} + +MAPM pgsIntegerGen::pgsNormalIntGen::random() +{ + m_state = (m_state * arg_a); + m_state = (m_state + arg_c) % arg_m; + return (m_state * m_range).div(m_top); +} + +pgsIntegerGen::pgsNormalIntGen::~pgsNormalIntGen() +{ + +} + +pgsNumberGen *pgsIntegerGen::pgsNormalIntGen::clone() +{ + return pnew pgsIntegerGen::pgsNormalIntGen(*this); +} + +const MAPM pgsIntegerGen::pgsNormalIntGen::arg_a = 16807L; +const MAPM pgsIntegerGen::pgsNormalIntGen::arg_c = 0; +const MAPM pgsIntegerGen::pgsNormalIntGen::arg_m = 2147483647L; + +pgsIntegerGen::pgsIntegerGen(const MAPM &min, const MAPM &max, + const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)), + m_range(m_max - m_min + 1), m_sequence(sequence) +{ + m_randomizer = is_sequence() + ? pgsRandomizer(pnew pgsSequentialIntGen(m_range, m_seed)) + : pgsRandomizer(pnew pgsNormalIntGen(m_range, m_seed)); +} + +bool pgsIntegerGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsIntegerGen::random() +{ + MAPM data = m_randomizer->random(); + data = data + m_min; + wxASSERT(data >= m_min && data <= m_max); + return pgsMapm::pgs_mapm_str(data); +} + +long pgsIntegerGen::random_long() +{ + long result; + random().ToLong(&result); + return result; +} + +pgsIntegerGen::~pgsIntegerGen() +{ + +} + +pgsIntegerGen *pgsIntegerGen::clone() +{ + return pnew pgsIntegerGen(*this); +} diff --git a/pgscript/generators/pgsNumberGen.cpp b/pgscript/generators/pgsNumberGen.cpp new file mode 100644 index 0000000..17bc446 --- /dev/null +++ b/pgscript/generators/pgsNumberGen.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsNumberGen.h" + +pgsNumberGen::pgsNumberGen(const MAPM &range) : + m_range(range) +{ + +} + +pgsNumberGen::~pgsNumberGen() +{ + +} diff --git a/pgscript/generators/pgsObjectGen.cpp b/pgscript/generators/pgsObjectGen.cpp new file mode 100644 index 0000000..1ec431f --- /dev/null +++ b/pgscript/generators/pgsObjectGen.cpp @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsObjectGen.h" + +pgsObjectGen::pgsObjectGen(const long &seed) : + m_seed(seed == 0 ? 1 : seed) +{ + +} + +pgsObjectGen::~pgsObjectGen() +{ + +} diff --git a/pgscript/generators/pgsRealGen.cpp b/pgscript/generators/pgsRealGen.cpp new file mode 100644 index 0000000..fcaabd3 --- /dev/null +++ b/pgscript/generators/pgsRealGen.cpp @@ -0,0 +1,48 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsRealGen.h" + +pgsRealGen::pgsRealGen(const MAPM &min, const MAPM &max, + const UCHAR &precision, const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_min(wxMin(min, max)), m_max(wxMax(min, max)), + m_range(m_max - m_min), m_sequence(sequence) +{ + m_pow = MAPM(10).pow(MAPM(precision)); + m_int_max = pgsMapm::pgs_mapm_round(m_range * m_pow) + 1; + + m_randomizer = is_sequence() + ? pgsRandomizer(pnew pgsIntegerGen::pgsSequentialIntGen(m_int_max, m_seed)) + : pgsRandomizer(pnew pgsIntegerGen::pgsNormalIntGen(m_int_max, m_seed)); +} + +bool pgsRealGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsRealGen::random() +{ + MAPM data = m_randomizer->random() / m_pow; + data = data + m_min; + wxASSERT(data >= m_min && data <= m_max); + return pgsMapm::pgs_mapm_str(data); +} + +pgsRealGen::~pgsRealGen() +{ + +} + +pgsRealGen *pgsRealGen::clone() +{ + return pnew pgsRealGen(*this); +} diff --git a/pgscript/generators/pgsReferenceGen.cpp b/pgscript/generators/pgsReferenceGen.cpp new file mode 100644 index 0000000..ab0dc04 --- /dev/null +++ b/pgscript/generators/pgsReferenceGen.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsReferenceGen.h" + +#include "pgscript/expressions/pgsExecute.h" +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/utilities/pgsThread.h" + +pgsReferenceGen::pgsReferenceGen(pgsThread *app, const wxString &table, + const wxString &column, const bool &sequence, const long &seed) : + pgsObjectGen(seed), m_app(app), m_table(table), m_column(column), + m_sequence(sequence) +{ + // We need an empty symbol table for calling pgsExecute.eval(...) + pgsVarMap vars; + + // Count the number of lines in the table + pgsOperand result = pgsExecute(wxString() << wxT("SELECT count(*) FROM ") + << m_table, 0, m_app).eval(vars); + wxASSERT(result->is_record()); + wxString value = result->value(); + if (!value.IsEmpty()) + { + m_nb_rows = pgsMapm::pgs_str_mapm(result->number().value()); + } + else + { + m_nb_rows = 0; + } + wxLogScriptVerbose(wxT("REFGEN: Number of rows in %s: %s"), m_table.c_str(), + pgsMapm::pgs_mapm_str(m_nb_rows).c_str()); + + // Create an integer generator with that number of lines + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, m_nb_rows - 1, + is_sequence(), m_seed)); +} + +bool pgsReferenceGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsReferenceGen::random() +{ + // We need an empty symbol table for calling pgsExecute.eval(...) + pgsVarMap vars; + + // Choose one line + pgsOperand result = pgsExecute(wxString() << wxT("SELECT ") << m_column + << wxT(" FROM ") << m_table << wxT(" LIMIT 1 OFFSET ") + << m_randomizer->random(), 0, m_app).eval(vars); + wxASSERT(result->is_record()); + + // Return the result as a single value + return dynamic_cast(*result).get(0, 0)->value(); +} + +pgsReferenceGen::~pgsReferenceGen() +{ + +} + +pgsReferenceGen *pgsReferenceGen::clone() +{ + return pnew pgsReferenceGen(*this); +} diff --git a/pgscript/generators/pgsRegexGen.cpp b/pgscript/generators/pgsRegexGen.cpp new file mode 100644 index 0000000..f5bb050 --- /dev/null +++ b/pgscript/generators/pgsRegexGen.cpp @@ -0,0 +1,309 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsRegexGen.h" + +#include +#include +#include + +#include +WX_DEFINE_OBJARRAY(pgsVectorStringGen); + +pgsRegexGen::pgsRegex::pgsRegex(const pgsVectorChar &characters, + const long &first, const long &second) : + m_characters(characters), m_first(wxMin(first, second)), + m_second(wxMax(first, second)) +{ + +} + +pgsRegexGen::pgsRegex::pgsRegex() : + m_characters(pgsVectorChar()), m_first(0), m_second(0) +{ + +} + +pgsRegexGen::pgsRegex::~pgsRegex() +{ + +} + +pgsRegexGen::pgsRegex *pgsRegexGen::pgsRegex::clone() +{ + return pnew pgsRegexGen::pgsRegex(*this); +} + +void pgsRegexGen::pgsRegex::set_characters(const pgsVectorChar &characters) +{ + m_characters = characters; +} + +void pgsRegexGen::pgsRegex::add_character(const wxChar &c) +{ + m_characters.Add(c); +} + +void pgsRegexGen::pgsRegex::set_first(const long &first) +{ + m_first = first; + m_second = first; +} + +void pgsRegexGen::pgsRegex::set_second(const long &second) +{ + long first = m_first; + m_first = wxMin(first, second); + m_second = wxMax(first, second); +} + +const pgsVectorChar &pgsRegexGen::pgsRegex::get_characters() const +{ + return m_characters; +} + +const long &pgsRegexGen::pgsRegex::get_first() const +{ + return m_first; +} + +const long &pgsRegexGen::pgsRegex::get_second() const +{ + return m_second; +} + +pgsRegexGen::pgsRegexGen(const wxString ®ex, const long &seed) : + pgsObjectGen(seed), m_regex(regex), m_valid(true), m_string_gens(pgsVectorStringGen()) +{ + wxLogScriptVerbose(wxT("REGEXGEN: %s"), m_regex.c_str()); + + // Transform regular expression into XML structure + bool escape = false, first_regex = true, list = false; + wxString result = wxT("\n"); + size_t i = 0; + while (i < m_regex.Length()) + { + if (escape) + { + if (list == true) + { + result.Append(espace_xml_char(m_regex[i])); + } + else + { + if (!first_regex) + result.Append(wxT(" \n")); + else + first_regex = false; + result.Append(wxT(" \n ")); + result.Append(espace_xml_char(m_regex[i])); + result.Append(wxT("\n")); + } + escape = false; + } + else if (list == true && m_regex[i] == wxT('-')) + { + if ((i + 1) < m_regex.Length()) + { + result.Append(char_range(m_regex[i - 1], m_regex[i + 1])); + } + } + else if (m_regex[i] == wxT('[')) + { + if (!first_regex) + result.Append(wxT(" \n")); + else + first_regex = false; + result.Append(wxT(" \n ")); + list = true; + } + else if (m_regex[i] == wxT(']')) + { + result.Append(wxT("\n")); + list = false; + } + else if (m_regex[i] == wxT('{')) + { + result.Append(wxT(" ")); + list = true; + } + else if (m_regex[i] == wxT('}')) + { + result.Append(wxT("\n")); + list = false; + } + else if (m_regex[i] == wxT('\\')) + { + escape = true; + } + else + { + if (list == true) + { + result.Append(espace_xml_char(m_regex[i])); + } + else + { + if (!first_regex) + result.Append(wxT(" \n")); + else + first_regex = false; + result.Append(wxT(" \n ")); + result.Append(espace_xml_char(m_regex[i])); + result.Append(wxT("\n")); + } + } + + ++i; + } + if (result != wxT("\n")) + result.Append(wxT(" \n")); + result.Append(wxT("\n")); + + wxLogScriptVerbose(wxT("REGEXGEN: %s"), result.c_str()); + + // Load this XML structure with the wxXmlDocument from wxWidgets + wxStringInputStream input(result); + wxXmlDocument doc; + if (!doc.Load(input, wxT("UTF-8"), wxXMLDOC_KEEP_WHITESPACE_NODES)) + { + m_valid = false; + } + else + { + // Start processing the XML file + if (doc.GetRoot()->GetName() != wxT("regexpressions")) + { + m_valid = false; + } + else + { + // Go through XML nodes + wxXmlNode *xml_regexpressions = doc.GetRoot()->GetChildren(); + while (xml_regexpressions && m_valid) + { + if (xml_regexpressions->GetName() == wxT("regex")) + { + wxXmlNode *xml_regex = xml_regexpressions->GetChildren(); + + pgsRegex regex; + regex.set_first(1); + + while (xml_regex && m_valid) + { + if (xml_regex->GetName() == wxT("characters")) + { + wxString content = xml_regex->GetNodeContent(); + for (size_t i = 0; i < content.Length(); i++) + { + regex.add_character(content[i]); + } + } + else if (xml_regex->GetName() == wxT("range")) + { + wxString content = xml_regex->GetNodeContent(); + wxRegEx ex(wxT("^([0-9]+)(,([0-9]+))?$")); + wxASSERT(ex.IsValid()); + if (ex.Matches(content)) + { + long min; + ex.GetMatch(content, 1).ToLong(&min); + regex.set_first(min); + wxString smax = ex.GetMatch(content, 3); + if (!smax.IsEmpty()) + { + long max; + smax.ToLong(&max); + regex.set_second(max); + } + } + else + { + // m_valid = false; + } + } + + xml_regex = xml_regex->GetNext(); + } + + m_string_gens.Add(pgsStringGen(regex.get_first(), + regex.get_second(), 1, seed, + regex.get_characters())); + } + + xml_regexpressions = xml_regexpressions->GetNext(); + } + } + } +} + +wxString pgsRegexGen::random() +{ + wxString result; + for (size_t i = 0; i < string_gens_size(); i++) + { + result.Append(m_string_gens.Item(i).random()); + } + return result; +} + +const pgsVectorStringGen &pgsRegexGen::string_gens() const +{ + return m_string_gens; +} + +size_t pgsRegexGen::string_gens_size() const +{ + return m_string_gens.size(); +} + +const bool &pgsRegexGen::is_valid() const +{ + return m_valid; +} + +wxString pgsRegexGen::espace_xml_char(const wxChar &c) +{ + if (c == wxT('<')) + return wxT("<"); + else if (c == wxT('&')) + return wxT("&"); + else if (c == wxT('>')) + return wxT(">"); + else if (c == wxT('"')) + return wxT("""); + else if (c == wxT('\'')) + return wxT("'"); + else return wxString(c); +} + +wxString pgsRegexGen::char_range(const wxChar &b, const wxChar &c) +{ + wxChar min = wxMin(b, c); + ++min; + wxChar max = wxMax(b, c); + wxString result; + for (wxChar i = min; i < max; i++) + { + result.Append(espace_xml_char(i)); + } + return result; +} + +pgsRegexGen::~pgsRegexGen() +{ + +} + +pgsRegexGen *pgsRegexGen::clone() +{ + return pnew pgsRegexGen(*this); +} diff --git a/pgscript/generators/pgsStringGen.cpp b/pgscript/generators/pgsStringGen.cpp new file mode 100644 index 0000000..7e0188d --- /dev/null +++ b/pgscript/generators/pgsStringGen.cpp @@ -0,0 +1,83 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsStringGen.h" + +#include +WX_DEFINE_OBJARRAY(pgsVectorChar); + +pgsStringGen::pgsStringGen(USHORT w_size_min, USHORT w_size_max, + const UCHAR &nb_words, const long &seed, pgsVectorChar characters) : + pgsObjectGen(seed), m_nb_words(nb_words), m_characters(characters) +{ + init_characters(); // Initialize vector if it is empty + + const USHORT w_size_aux = w_size_min; + w_size_min = wxMin(w_size_aux, w_size_max); + w_size_max = wxMax(w_size_aux, w_size_max); + + size_t char_count = m_characters.GetCount(); + m_w_size_randomizer = pgsRandomizer(pnew pgsIntegerGen(w_size_min, + w_size_max, false, seed)); + m_letter_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, + wx_static_cast(long, char_count) - 1, false, seed)); +} + +wxString pgsStringGen::random() +{ + wxString str_result; + long w_size; + + for (UCHAR i = 0; i < m_nb_words; i++) + { + w_size = m_w_size_randomizer->random_long(); + for (long j = 0; j < w_size; j++) + { + str_result.Append(m_characters + .Item(m_letter_randomizer->random_long()), 1); + } + if (w_size > 0 && m_nb_words != (i + 1)) + { + str_result.Append(wxT(' '), 1); + } + } + + return str_result; +} + +pgsStringGen::~pgsStringGen() +{ + +} + +void pgsStringGen::init_characters() +{ + if (m_characters.size() == 0) + { + for (char c = '0'; c <= '9'; c++) + { + m_characters.push_back(c); + } + for (char c = 'A'; c <= 'Z'; c++) + { + m_characters.push_back(c); + } + for (char c = 'a'; c <= 'z'; c++) + { + m_characters.push_back(c); + } + } +} + +pgsStringGen *pgsStringGen::clone() +{ + return pnew pgsStringGen(*this); +} diff --git a/pgscript/generators/pgsTimeGen.cpp b/pgscript/generators/pgsTimeGen.cpp new file mode 100644 index 0000000..e933cba --- /dev/null +++ b/pgscript/generators/pgsTimeGen.cpp @@ -0,0 +1,52 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/generators/pgsTimeGen.h" + +#include + +pgsTimeGen::pgsTimeGen(wxDateTime min, wxDateTime max, const bool &sequence, + const long &seed) : + pgsObjectGen(seed), m_min(min.IsEarlierThan(max) || min.IsEqualTo(max) ? min : max), + m_max(max.IsLaterThan(min) || max.IsEqualTo(min) ? max : min), + m_range(m_max.Subtract(m_min).GetSeconds()), m_sequence(sequence) +{ + m_min.SetYear(1970); // We know this date is not a DST date + m_min.SetMonth(wxDateTime::Jan); + m_min.SetDay(1); + m_randomizer = pgsRandomizer(pnew pgsIntegerGen(0, std::string(m_range + .ToString().mb_str()).c_str(), is_sequence(), m_seed)); +} + +bool pgsTimeGen::is_sequence() const +{ + return m_sequence; +} + +wxString pgsTimeGen::random() +{ + wxTimeSpan time_span(0, 0, m_randomizer->random_long(), 0); + wxDateTime aux_min(m_min); + aux_min.Add(time_span); + wxASSERT(aux_min.IsLaterThan(m_min) || aux_min.IsEqualTo(m_min)); + wxASSERT(aux_min.IsEarlierThan(m_max) || aux_min.IsEqualTo(m_max)); + return aux_min.FormatISOTime(); +} + +pgsTimeGen::~pgsTimeGen() +{ + +} + +pgsTimeGen *pgsTimeGen::clone() +{ + return pnew pgsTimeGen(*this); +} diff --git a/pgscript/lex.pgs.cc b/pgscript/lex.pgs.cc new file mode 100644 index 0000000..0b69f03 --- /dev/null +++ b/pgscript/lex.pgs.cc @@ -0,0 +1,2696 @@ +#include "pgAdmin3.h" + + +#line 2 "pgscript/lex.pgs.cc" + +#line 4 "pgscript/lex.pgs.cc" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 33 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + + /* The c++ scanner is a mess. The FlexLexer.h header file relies on the + * following macro. This is required in order to pass the c++-multiple-scanners + * test in the regression suite. We get reports that it breaks inheritance. + * We will address this in a future release of flex, or omit the C++ scanner + * altogether. + */ + #define yyFlexLexer pgsFlexLexer + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ +#include +#include +#include +#include +/* end standard C++ headers. */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + + std::istream* yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +void *pgsalloc (yy_size_t ); +void *pgsrealloc (void *,yy_size_t ); +void pgsfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +#define yytext_ptr yytext + +#include "pgscript/FlexLexer.h" + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 137 +#define YY_END_OF_BUFFER 138 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[444] = + { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 114, 111, 113, 112, 61, 64, 50, 51, 59, + 58, 55, 57, 54, 60, 35, 49, 46, 62, 43, + 63, 34, 52, 53, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 114, 114, 47, 48, 114, 130, 129, 128, 130, + 122, 121, 120, 122, 115, 118, 119, 122, 122, 117, + 126, 125, 124, 126, 136, 135, 134, 133, 136, 111, + 48, 0, 36, 2, 38, 35, 0, 53, 47, 52, + 41, 45, 42, 34, 0, 0, 0, 11, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 13, 0, 8, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 44, 127, + 0, 116, 3, 0, 123, 131, 132, 0, 1, 0, + 36, 0, 0, 37, 0, 0, 0, 39, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 103, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 0, 0, 38, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 0, 75, 0, 26, + 0, 0, 0, 0, 81, 9, 0, 0, 0, 0, + 25, 0, 0, 0, 0, 0, 90, 91, 92, 0, + 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 104, 0, 0, + 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 36, 65, 66, 0, 0, 32, 5, 0, 71, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 87, 0, 0, 16, 0, + 0, 0, 14, 0, 0, 0, 24, 0, 0, 98, + 0, 0, 0, 0, 0, 0, 30, 105, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, + 0, 0, 0, 74, 0, 76, 0, 0, 0, 79, + 0, 0, 0, 0, 0, 88, 0, 89, 93, 0, + 0, 20, 0, 0, 0, 6, 99, 18, 0, 0, + 102, 23, 0, 0, 108, 109, 110, 0, 67, 0, + 0, 0, 72, 15, 73, 0, 0, 0, 78, 80, + + 0, 0, 84, 85, 21, 94, 0, 0, 96, 97, + 0, 0, 0, 0, 10, 0, 0, 0, 7, 28, + 0, 0, 0, 83, 95, 0, 100, 0, 106, 107, + 0, 0, 0, 0, 31, 82, 29, 101, 68, 69, + 70, 77, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 4, 5, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 6, 7, 8, 1, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 20, 21, + 22, 23, 1, 24, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 6, 37, 38, 39, 40, 41, 42, + 6, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 25, 26, 27, 1, 6, 1, 28, 29, 30, 31, + + 32, 33, 34, 35, 36, 6, 37, 38, 39, 40, + 41, 42, 6, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 1, 53, 54, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[55] = + { 0, + 1, 1, 2, 1, 1, 3, 4, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, + 1, 1, 1, 3, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[453] = + { 0, + 0, 0, 52, 53, 63, 81, 56, 64, 76, 84, + 507, 508, 58, 508, 508, 483, 508, 508, 508, 508, + 508, 508, 490, 486, 491, 79, 479, 508, 86, 508, + 479, 0, 508, 508, 74, 72, 78, 92, 85, 90, + 34, 67, 91, 459, 458, 455, 454, 97, 105, 103, + 101, 468, 114, 508, 508, 473, 508, 508, 508, 477, + 508, 508, 508, 486, 508, 508, 508, 477, 479, 508, + 508, 508, 508, 483, 508, 508, 508, 480, 0, 143, + 508, 485, 99, 508, 112, 135, 139, 508, 508, 508, + 508, 508, 508, 0, 446, 441, 127, 441, 450, 451, + + 438, 449, 115, 124, 448, 434, 140, 434, 436, 432, + 444, 127, 429, 435, 508, 444, 508, 127, 133, 146, + 424, 425, 508, 143, 152, 431, 430, 420, 146, 425, + 155, 426, 156, 426, 432, 151, 426, 425, 508, 508, + 453, 508, 508, 452, 508, 508, 508, 455, 508, 188, + 175, 195, 439, 438, 412, 422, 415, 508, 420, 415, + 422, 404, 418, 403, 402, 399, 405, 398, 392, 413, + 408, 401, 400, 405, 406, 393, 402, 431, 402, 393, + 400, 397, 388, 395, 394, 393, 379, 392, 385, 389, + 384, 377, 378, 38, 376, 384, 383, 374, 381, 380, + + 365, 369, 373, 370, 375, 374, 403, 356, 360, 366, + 369, 361, 359, 362, 369, 350, 349, 349, 355, 374, + 373, 196, 372, 371, 343, 344, 336, 342, 344, 346, + 508, 345, 349, 335, 340, 168, 342, 508, 332, 331, + 337, 346, 328, 344, 508, 508, 185, 325, 342, 334, + 508, 323, 324, 332, 321, 332, 508, 508, 508, 330, + 334, 316, 508, 316, 316, 315, 308, 325, 327, 309, + 310, 315, 311, 321, 307, 318, 192, 508, 302, 306, + 508, 508, 315, 300, 298, 296, 309, 307, 307, 320, + 319, 508, 508, 285, 290, 332, 508, 291, 508, 300, + + 291, 290, 284, 288, 295, 290, 284, 281, 291, 279, + 278, 279, 274, 282, 508, 508, 272, 284, 508, 275, + 264, 270, 508, 276, 280, 278, 508, 277, 264, 508, + 267, 274, 273, 276, 262, 257, 508, 508, 267, 272, + 254, 266, 258, 252, 254, 508, 262, 508, 193, 252, + 249, 247, 245, 508, 243, 508, 249, 257, 254, 508, + 254, 256, 240, 250, 241, 508, 237, 508, 508, 247, + 244, 508, 237, 227, 243, 508, 508, 508, 244, 237, + 508, 508, 227, 239, 508, 508, 508, 227, 508, 220, + 199, 203, 508, 508, 508, 205, 204, 207, 232, 508, + + 192, 194, 508, 508, 508, 508, 189, 198, 508, 508, + 189, 185, 192, 183, 508, 194, 178, 180, 508, 508, + 174, 203, 174, 508, 508, 185, 508, 170, 508, 508, + 172, 128, 115, 116, 508, 508, 508, 508, 508, 508, + 508, 508, 508, 241, 245, 249, 253, 96, 255, 257, + 261, 265 + } ; + +static yyconst flex_int16_t yy_def[453] = + { 0, + 443, 1, 444, 444, 445, 445, 446, 446, 447, 447, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 448, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 449, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 450, 443, 443, 443, 443, 451, 443, + 443, 452, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 448, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 449, 443, 443, 450, 443, 443, 443, 452, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 0, 443, 443, 443, 443, 443, 443, 443, + 443, 443 + } ; + +static yyconst flex_int16_t yy_nxt[563] = + { 0, + 12, 13, 14, 13, 15, 12, 12, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 12, 34, 35, 36, 37, + 38, 39, 40, 41, 12, 42, 12, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 12, 12, + 12, 54, 55, 56, 58, 58, 59, 59, 72, 80, + 73, 80, 74, 60, 60, 62, 72, 63, 73, 64, + 74, 65, 66, 67, 115, 263, 116, 68, 76, 69, + 77, 264, 70, 62, 78, 63, 76, 64, 77, 65, + 66, 67, 78, 89, 85, 68, 86, 69, 94, 117, + + 70, 79, 95, 99, 90, 101, 118, 91, 92, 79, + 87, 96, 102, 97, 100, 103, 83, 98, 104, 106, + 105, 113, 110, 107, 111, 114, 119, 108, 125, 151, + 150, 120, 128, 112, 109, 126, 129, 127, 132, 130, + 134, 137, 135, 152, 80, 133, 80, 442, 138, 131, + 85, 153, 86, 153, 157, 164, 154, 158, 179, 441, + 165, 166, 167, 168, 440, 169, 87, 172, 180, 173, + 184, 185, 186, 188, 192, 189, 187, 174, 193, 194, + 216, 195, 209, 206, 196, 197, 247, 198, 217, 199, + 207, 212, 151, 277, 349, 200, 201, 210, 202, 302, + + 220, 213, 220, 303, 422, 221, 222, 223, 290, 223, + 290, 439, 224, 291, 438, 337, 437, 436, 434, 433, + 432, 431, 430, 429, 428, 427, 435, 426, 425, 311, + 424, 423, 312, 422, 421, 420, 419, 390, 418, 417, + 391, 57, 57, 57, 57, 61, 61, 61, 61, 71, + 71, 71, 71, 75, 75, 75, 75, 141, 141, 144, + 144, 147, 416, 147, 147, 148, 148, 148, 148, 415, + 414, 413, 412, 411, 410, 409, 408, 407, 406, 405, + 404, 403, 402, 401, 400, 399, 398, 397, 396, 395, + 394, 393, 392, 389, 388, 387, 386, 385, 384, 383, + + 382, 381, 380, 379, 378, 377, 376, 375, 374, 373, + 372, 371, 370, 369, 368, 367, 366, 365, 364, 363, + 362, 361, 360, 359, 358, 357, 356, 355, 354, 353, + 352, 351, 350, 349, 348, 347, 291, 291, 346, 345, + 344, 343, 342, 341, 340, 339, 338, 336, 335, 334, + 333, 332, 331, 330, 329, 328, 327, 326, 325, 324, + 323, 322, 321, 320, 319, 318, 317, 316, 315, 314, + 313, 310, 309, 308, 307, 306, 305, 304, 301, 300, + 299, 298, 297, 296, 295, 294, 293, 292, 224, 224, + 221, 221, 289, 288, 287, 286, 285, 284, 283, 282, + + 281, 280, 279, 278, 277, 276, 275, 274, 273, 272, + 271, 270, 269, 268, 267, 266, 265, 262, 261, 260, + 259, 258, 257, 256, 255, 254, 253, 252, 251, 250, + 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, + 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, + 229, 228, 227, 226, 225, 154, 154, 149, 145, 142, + 219, 218, 215, 214, 211, 208, 205, 204, 203, 191, + 190, 183, 182, 181, 178, 177, 176, 175, 171, 170, + 163, 162, 161, 160, 159, 156, 155, 149, 146, 145, + 143, 82, 142, 140, 139, 136, 124, 123, 122, 121, + + 93, 88, 84, 83, 82, 81, 443, 11, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443 + } ; + +static yyconst flex_int16_t yy_chk[563] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 4, 3, 4, 7, 13, + 7, 13, 7, 3, 4, 5, 8, 5, 8, 5, + 8, 5, 5, 5, 41, 194, 41, 5, 9, 5, + 9, 194, 5, 6, 9, 6, 10, 6, 10, 6, + 6, 6, 10, 29, 26, 6, 26, 6, 448, 42, + + 6, 9, 35, 36, 29, 37, 42, 29, 29, 10, + 26, 35, 37, 35, 36, 37, 83, 35, 37, 38, + 37, 40, 39, 38, 39, 40, 43, 38, 48, 85, + 83, 43, 49, 39, 38, 48, 49, 48, 50, 49, + 51, 53, 51, 85, 80, 50, 80, 434, 53, 49, + 86, 87, 86, 87, 97, 103, 87, 97, 112, 433, + 103, 104, 104, 104, 432, 104, 86, 107, 112, 107, + 118, 118, 119, 120, 124, 120, 119, 107, 124, 125, + 136, 125, 131, 129, 125, 125, 247, 125, 136, 125, + 129, 133, 151, 277, 349, 125, 125, 131, 125, 236, + + 150, 133, 150, 236, 422, 150, 151, 152, 222, 152, + 222, 431, 152, 222, 428, 277, 426, 423, 421, 418, + 417, 416, 414, 413, 412, 411, 422, 408, 407, 247, + 402, 401, 247, 399, 398, 397, 396, 349, 392, 391, + 349, 444, 444, 444, 444, 445, 445, 445, 445, 446, + 446, 446, 446, 447, 447, 447, 447, 449, 449, 450, + 450, 451, 390, 451, 451, 452, 452, 452, 452, 388, + 384, 383, 380, 379, 375, 374, 373, 371, 370, 367, + 365, 364, 363, 362, 361, 359, 358, 357, 355, 353, + 352, 351, 350, 347, 345, 344, 343, 342, 341, 340, + + 339, 336, 335, 334, 333, 332, 331, 329, 328, 326, + 325, 324, 322, 321, 320, 318, 317, 314, 313, 312, + 311, 310, 309, 308, 307, 306, 305, 304, 303, 302, + 301, 300, 298, 296, 295, 294, 291, 290, 289, 288, + 287, 286, 285, 284, 283, 280, 279, 276, 275, 274, + 273, 272, 271, 270, 269, 268, 267, 266, 265, 264, + 262, 261, 260, 256, 255, 254, 253, 252, 250, 249, + 248, 244, 243, 242, 241, 240, 239, 237, 235, 234, + 233, 232, 230, 229, 228, 227, 226, 225, 224, 223, + 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, + + 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, + 201, 200, 199, 198, 197, 196, 195, 193, 192, 191, + 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, + 180, 179, 178, 177, 176, 175, 174, 173, 172, 171, + 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, + 160, 159, 157, 156, 155, 154, 153, 148, 144, 141, + 138, 137, 135, 134, 132, 130, 128, 127, 126, 122, + 121, 116, 114, 113, 111, 110, 109, 108, 106, 105, + 102, 101, 100, 99, 98, 96, 95, 82, 78, 74, + 69, 68, 64, 60, 56, 52, 47, 46, 45, 44, + + 31, 27, 25, 24, 23, 16, 11, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "pgscript/pgsScanner.ll" +#line 6 "pgscript/pgsScanner.ll" + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/parser.tab.hh" +#include "pgscript/utilities/pgsScanner.h" + +/* Import the parser's token type into a local typedef */ +typedef pgscript::pgsParser::token token; +typedef pgscript::pgsParser::token_type token_type; + +/* Work around an incompatibility in flex (at least versions 2.5.31 through + * 2.5.33): it generates code that does not conform to C89. See Debian bug + * 333231 . */ +#undef yywrap +#define yywrap() 1 + +/* By default yylex returns int, we use token_type. Unfortunately yyterminate + * by default returns 0, which is not of token_type. */ +#define yyterminate() return token::PGS_END + +/* This disables inclusion of unistd.h, which is not available under Visual C++ + * on Win32. The C++ scanner uses STL streams instead. */ +#define YY_NO_UNISTD_H + +/*** Flex Declarations and Options ***/ +/* Enable C++ scanner class generation */ +/* Change the name of the scanner class. Results in "pgsFlexLexer" */ +/* Case insensitive */ +/* The manual says "somewhat more optimized" */ +/* Prevent isatty warning in VC++ */ +/* For using start conditions */ +/* No support for include files is planned */ +/* The following paragraph suffices to track locations accurately. Each time + * yylex is invoked, the begin position is moved onto the end position. */ +#line 66 "pgscript/pgsScanner.ll" +#define YY_USER_ACTION yylloc->columns(yyleng); + + + + +#line 732 "pgscript/lex.pgs.cc" + +#define INITIAL 0 +#define SC_COMMENT 1 +#define SC_QUERY 2 +#define SC_DOLLAR 3 +#define SC_STRING 4 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +#define ECHO LexerOutput( yytext, yyleng ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +\ + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) LexerError( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +#define YY_DECL int yyFlexLexer::yylex() +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 74 "pgscript/pgsScanner.ll" + + + /* Code to place at the beginning of yylex() */ + + // Reset location + yylloc->step(); + + +#line 845 "pgscript/lex.pgs.cc" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = & std::cin; + + if ( ! yyout ) + yyout = & std::cout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 443 ); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ +(yy_c_buf_p) = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 82 "pgscript/pgsScanner.ll" +{ /* Ignore SQL comment */ } + YY_BREAK +case 2: +YY_RULE_SETUP +#line 83 "pgscript/pgsScanner.ll" +{ comment_caller = INITIAL; BEGIN(SC_COMMENT); } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 84 "pgscript/pgsScanner.ll" +{ comment_caller = SC_QUERY; BEGIN(SC_COMMENT); } + YY_BREAK + +case 4: +YY_RULE_SETUP +#line 87 "pgscript/pgsScanner.ll" +{ return token::PGS_WHILE; } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 88 "pgscript/pgsScanner.ll" +{ return token::PGS_BREAK; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 89 "pgscript/pgsScanner.ll" +{ return token::PGS_RETURN; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 90 "pgscript/pgsScanner.ll" +{ return token::PGS_CONTINUE; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 91 "pgscript/pgsScanner.ll" +{ return token::PGS_IF; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 92 "pgscript/pgsScanner.ll" +{ return token::PGS_ELSE; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 93 "pgscript/pgsScanner.ll" +{ return token::PGS_WAITFOR; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 94 "pgscript/pgsScanner.ll" +{ return token::PGS_AS; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 96 "pgscript/pgsScanner.ll" +{ return token::PGS_ASSERT; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 97 "pgscript/pgsScanner.ll" +{ /* Ignore it */ } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 98 "pgscript/pgsScanner.ll" +{ return token::PGS_PRINT; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 100 "pgscript/pgsScanner.ll" +{ return token::PGS_CNT_COLUMNS; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 101 "pgscript/pgsScanner.ll" +{ return token::PGS_CNT_LINES; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 102 "pgscript/pgsScanner.ll" +{ return token::PGS_TRIM; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 103 "pgscript/pgsScanner.ll" +{ return token::PGS_RM_LINE; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 104 "pgscript/pgsScanner.ll" +{ return token::PGS_CAST; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 106 "pgscript/pgsScanner.ll" +{ return token::PGS_RECORD; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 108 "pgscript/pgsScanner.ll" +{ return token::PGS_INTEGER; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 109 "pgscript/pgsScanner.ll" +{ return token::PGS_REAL; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 110 "pgscript/pgsScanner.ll" +{ return token::PGS_STRING; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 111 "pgscript/pgsScanner.ll" +{ return token::PGS_REGEX; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 112 "pgscript/pgsScanner.ll" +{ return token::PGS_FILE; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 113 "pgscript/pgsScanner.ll" +{ return token::PGS_DATE; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 114 "pgscript/pgsScanner.ll" +{ return token::PGS_TIME; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 115 "pgscript/pgsScanner.ll" +{ return token::PGS_DATE_TIME; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 116 "pgscript/pgsScanner.ll" +{ return token::PGS_REFERENCE; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 119 "pgscript/pgsScanner.ll" +{ unput('@'); yylloc->end.columns(-1); + return token::PGS_SET_ASSIGN; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 121 "pgscript/pgsScanner.ll" +{ unput('@'); yylloc->end.columns(-1); + return token::PGS_DECLARE_ASSGN; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 124 "pgscript/pgsScanner.ll" +{ /* Block opening */ return token::PGS_OPEN; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 125 "pgscript/pgsScanner.ll" +{ /* Block closing */ return token::PGS_CLOSE; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 127 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_IDENTIFIER; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 130 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_INT; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 133 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 135 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 137 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 140 "pgscript/pgsScanner.ll" +{ return token::PGS_AND_OP; } + YY_BREAK +case 40: +YY_RULE_SETUP +#line 141 "pgscript/pgsScanner.ll" +{ return token::PGS_OR_OP; } + YY_BREAK +case 41: +YY_RULE_SETUP +#line 142 "pgscript/pgsScanner.ll" +{ return token::PGS_LE_OP; } + YY_BREAK +case 42: +YY_RULE_SETUP +#line 143 "pgscript/pgsScanner.ll" +{ return token::PGS_GE_OP; } + YY_BREAK +case 43: +YY_RULE_SETUP +#line 144 "pgscript/pgsScanner.ll" +{ return token::PGS_EQ_OP; } + YY_BREAK +case 44: +YY_RULE_SETUP +#line 145 "pgscript/pgsScanner.ll" +{ return token::PGS_AE_OP; } + YY_BREAK +case 45: +YY_RULE_SETUP +#line 146 "pgscript/pgsScanner.ll" +{ return token::PGS_NE_OP; } + YY_BREAK +case 46: +YY_RULE_SETUP +#line 147 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ';'); } + YY_BREAK +case 47: +YY_RULE_SETUP +#line 148 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '{'); } + YY_BREAK +case 48: +YY_RULE_SETUP +#line 149 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '}'); } + YY_BREAK +case 49: +YY_RULE_SETUP +#line 150 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ':'); } + YY_BREAK +case 50: +YY_RULE_SETUP +#line 151 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '('); } + YY_BREAK +case 51: +YY_RULE_SETUP +#line 152 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ')'); } + YY_BREAK +case 52: +YY_RULE_SETUP +#line 153 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '['); } + YY_BREAK +case 53: +YY_RULE_SETUP +#line 154 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ']'); } + YY_BREAK +case 54: +YY_RULE_SETUP +#line 155 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '.'); } + YY_BREAK +case 55: +YY_RULE_SETUP +#line 156 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, ','); } + YY_BREAK +case 56: +YY_RULE_SETUP +#line 157 "pgscript/pgsScanner.ll" +{ return token::PGS_NOT_OP; } + YY_BREAK +case 57: +YY_RULE_SETUP +#line 158 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '-'); } + YY_BREAK +case 58: +YY_RULE_SETUP +#line 159 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '+'); } + YY_BREAK +case 59: +YY_RULE_SETUP +#line 160 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '*'); } + YY_BREAK +case 60: +YY_RULE_SETUP +#line 161 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '/'); } + YY_BREAK +case 61: +YY_RULE_SETUP +#line 162 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '%'); } + YY_BREAK +case 62: +YY_RULE_SETUP +#line 163 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '<'); } + YY_BREAK +case 63: +YY_RULE_SETUP +#line 164 "pgscript/pgsScanner.ll" +{ return wx_static_cast(token_type, '>'); } + YY_BREAK +case 64: +YY_RULE_SETUP +#line 166 "pgscript/pgsScanner.ll" +{ string_caller = INITIAL; BEGIN(SC_STRING); } + YY_BREAK +case 65: +YY_RULE_SETUP +#line 168 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ABORT; + BEGIN(SC_QUERY); } + YY_BREAK +case 66: +YY_RULE_SETUP +#line 170 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ALTER; + BEGIN(SC_QUERY); } + YY_BREAK +case 67: +YY_RULE_SETUP +#line 172 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ANALYZE; + BEGIN(SC_QUERY); } + YY_BREAK +case 68: +YY_RULE_SETUP +#line 174 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } + YY_BREAK +case 69: +YY_RULE_SETUP +#line 176 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } + YY_BREAK +case 70: +YY_RULE_SETUP +#line 178 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CHECKPOINT; + BEGIN(SC_QUERY); } + YY_BREAK +case 71: +YY_RULE_SETUP +#line 180 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CLOSE_ST; + BEGIN(SC_QUERY); } + YY_BREAK +case 72: +YY_RULE_SETUP +#line 182 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CLUSTER; + BEGIN(SC_QUERY); } + YY_BREAK +case 73: +YY_RULE_SETUP +#line 184 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_COMMENT; + BEGIN(SC_QUERY); } + YY_BREAK +case 74: +YY_RULE_SETUP +#line 186 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_COMMIT; + BEGIN(SC_QUERY); } + YY_BREAK +case 75: +YY_RULE_SETUP +#line 188 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_COPY; + BEGIN(SC_QUERY); } + YY_BREAK +case 76: +YY_RULE_SETUP +#line 190 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_CREATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 77: +YY_RULE_SETUP +#line 192 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DEALLOCATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 78: +YY_RULE_SETUP +#line 194 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DECLARE; + BEGIN(SC_QUERY); } + YY_BREAK +case 79: +YY_RULE_SETUP +#line 196 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DELETE; + BEGIN(SC_QUERY); } + YY_BREAK +case 80: +YY_RULE_SETUP +#line 198 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DISCARD; + BEGIN(SC_QUERY); } + YY_BREAK +case 81: +YY_RULE_SETUP +#line 200 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_DROP; + BEGIN(SC_QUERY); } + YY_BREAK +case 82: +YY_RULE_SETUP +#line 202 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } + YY_BREAK +case 83: +YY_RULE_SETUP +#line 204 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } + YY_BREAK +case 84: +YY_RULE_SETUP +#line 206 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_EXECUTE; + BEGIN(SC_QUERY); } + YY_BREAK +case 85: +YY_RULE_SETUP +#line 208 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_EXPLAIN; + BEGIN(SC_QUERY); } + YY_BREAK +case 86: +YY_RULE_SETUP +#line 210 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_FETCH; + BEGIN(SC_QUERY); } + YY_BREAK +case 87: +YY_RULE_SETUP +#line 212 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_GRANT; + BEGIN(SC_QUERY); } + YY_BREAK +case 88: +YY_RULE_SETUP +#line 214 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_INSERT; + BEGIN(SC_QUERY); } + YY_BREAK +case 89: +YY_RULE_SETUP +#line 216 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_LISTEN; + BEGIN(SC_QUERY); } + YY_BREAK +case 90: +YY_RULE_SETUP +#line 218 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_LOAD; + BEGIN(SC_QUERY); } + YY_BREAK +case 91: +YY_RULE_SETUP +#line 220 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_LOCK; + BEGIN(SC_QUERY); } + YY_BREAK +case 92: +YY_RULE_SETUP +#line 222 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_MOVE; + BEGIN(SC_QUERY); } + YY_BREAK +case 93: +YY_RULE_SETUP +#line 224 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_NOTIFY; + BEGIN(SC_QUERY); } + YY_BREAK +case 94: +YY_RULE_SETUP +#line 226 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_PREPARE; + BEGIN(SC_QUERY); } + YY_BREAK +case 95: +YY_RULE_SETUP +#line 228 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_REASSIGN; + BEGIN(SC_QUERY); } + YY_BREAK +case 96: +YY_RULE_SETUP +#line 230 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_REINDEX; + BEGIN(SC_QUERY); } + YY_BREAK +case 97: +YY_RULE_SETUP +#line 232 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_RELEASE; + BEGIN(SC_QUERY); } + YY_BREAK +case 98: +YY_RULE_SETUP +#line 234 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_RESET; + BEGIN(SC_QUERY); } + YY_BREAK +case 99: +YY_RULE_SETUP +#line 236 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_REVOKE; + BEGIN(SC_QUERY); } + YY_BREAK +case 100: +YY_RULE_SETUP +#line 238 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_ROLLBACK; + BEGIN(SC_QUERY); } + YY_BREAK +case 101: +YY_RULE_SETUP +#line 240 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SAVEPOINT; + BEGIN(SC_QUERY); } + YY_BREAK +case 102: +YY_RULE_SETUP +#line 242 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SELECT; + BEGIN(SC_QUERY); } + YY_BREAK +case 103: +YY_RULE_SETUP +#line 244 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SET; + BEGIN(SC_QUERY); } + YY_BREAK +case 104: +YY_RULE_SETUP +#line 246 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_SHOW; + BEGIN(SC_QUERY); } + YY_BREAK +case 105: +YY_RULE_SETUP +#line 248 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_START; + BEGIN(SC_QUERY); } + YY_BREAK +case 106: +YY_RULE_SETUP +#line 250 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_TRUNCATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 107: +YY_RULE_SETUP +#line 252 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_UNLISTEN; + BEGIN(SC_QUERY); } + YY_BREAK +case 108: +YY_RULE_SETUP +#line 254 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_UPDATE; + BEGIN(SC_QUERY); } + YY_BREAK +case 109: +YY_RULE_SETUP +#line 256 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_VACUUM; + BEGIN(SC_QUERY); } + YY_BREAK +case 110: +YY_RULE_SETUP +#line 258 "pgscript/pgsScanner.ll" +{ query += yytext; query_token = token::PGS_VALUES; + BEGIN(SC_QUERY); } + YY_BREAK +case 111: +YY_RULE_SETUP +#line 261 "pgscript/pgsScanner.ll" +{ } + YY_BREAK +case 112: +YY_RULE_SETUP +#line 262 "pgscript/pgsScanner.ll" +{ yylloc->step(); } + YY_BREAK +case 113: +/* rule 113 can match eol */ +YY_RULE_SETUP +#line 263 "pgscript/pgsScanner.ll" +{ yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case 114: +YY_RULE_SETUP +#line 264 "pgscript/pgsScanner.ll" +{ return token::PGS_UNKNOWN; } + YY_BREAK + + +case 115: +YY_RULE_SETUP +#line 268 "pgscript/pgsScanner.ll" +{ query += yytext; string_caller = SC_QUERY; BEGIN(SC_STRING); } + YY_BREAK +case 116: +YY_RULE_SETUP +#line 269 "pgscript/pgsScanner.ll" +{ query += yytext; dollar = yytext; BEGIN(SC_DOLLAR); } + YY_BREAK +case 117: +YY_RULE_SETUP +#line 270 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(';'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; } + YY_BREAK +case 118: +YY_RULE_SETUP +#line 273 "pgscript/pgsScanner.ll" +{ ++m_parent; query += yytext; } + YY_BREAK +case 119: +YY_RULE_SETUP +#line 274 "pgscript/pgsScanner.ll" +{ + --m_parent; + if (m_parent == -1) + { + yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(')'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; + } + else + { + query += yytext; + } + } + YY_BREAK +case 120: +YY_RULE_SETUP +#line 287 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->step(); } + YY_BREAK +case 121: +/* rule 121 can match eol */ +YY_RULE_SETUP +#line 288 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case YY_STATE_EOF(SC_QUERY): +#line 289 "pgscript/pgsScanner.ll" +{ yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } + YY_BREAK +case 122: +YY_RULE_SETUP +#line 291 "pgscript/pgsScanner.ll" +{ yylloc->columns(columns(*yytext)); query += yytext; } + YY_BREAK + + +case 123: +YY_RULE_SETUP +#line 295 "pgscript/pgsScanner.ll" +{ query += yytext; + if (std::string(yytext) == dollar) BEGIN(SC_QUERY); } + YY_BREAK +case 124: +YY_RULE_SETUP +#line 297 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->step(); } + YY_BREAK +case 125: +/* rule 125 can match eol */ +YY_RULE_SETUP +#line 298 "pgscript/pgsScanner.ll" +{ query += yytext; yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case YY_STATE_EOF(SC_DOLLAR): +#line 299 "pgscript/pgsScanner.ll" +{ query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } + YY_BREAK +case 126: +YY_RULE_SETUP +#line 301 "pgscript/pgsScanner.ll" +{ yylloc->columns(columns(*yytext)); query += yytext; } + YY_BREAK + + +case 127: +YY_RULE_SETUP +#line 305 "pgscript/pgsScanner.ll" +{ BEGIN(comment_caller); } + YY_BREAK +case 128: +YY_RULE_SETUP +#line 306 "pgscript/pgsScanner.ll" +{ yylloc->step(); } + YY_BREAK +case 129: +/* rule 129 can match eol */ +YY_RULE_SETUP +#line 307 "pgscript/pgsScanner.ll" +{ yylloc->lines(yyleng); yylloc->step(); } + YY_BREAK +case 130: +YY_RULE_SETUP +#line 308 "pgscript/pgsScanner.ll" +{ yylloc->columns(columns(*yytext)); } + YY_BREAK + + +case 131: +YY_RULE_SETUP +#line 312 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += "'"; + } + YY_BREAK +case 132: +YY_RULE_SETUP +#line 318 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += *(yytext + 1); + yylloc->columns(columns(*(yytext + 1))); + } + YY_BREAK +case 133: +YY_RULE_SETUP +#line 325 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + { + query += yytext; + BEGIN(string_caller); + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } + YY_BREAK +case 134: +YY_RULE_SETUP +#line 339 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->step(); + } + YY_BREAK +case 135: +/* rule 135 can match eol */ +YY_RULE_SETUP +#line 346 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->lines(yyleng); yylloc->step(); + } + YY_BREAK +case YY_STATE_EOF(SC_STRING): +#line 353 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + { + query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } + YY_BREAK +case 136: +YY_RULE_SETUP +#line 367 "pgscript/pgsScanner.ll" +{ + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->columns(columns(*yytext)); + } + YY_BREAK + +case 137: +YY_RULE_SETUP +#line 376 "pgscript/pgsScanner.ll" +ECHO; + YY_BREAK +#line 1764 "pgscript/lex.pgs.cc" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(SC_COMMENT): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) +{ + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 0; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = NULL; + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + + yy_state_buf = 0; + +} + +yyFlexLexer::~yyFlexLexer() +{ + delete [] yy_state_buf; + pgsfree(yy_start_stack ); + yy_delete_buffer( YY_CURRENT_BUFFER ); +} + +void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) +{ + if ( new_in ) + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + } + + if ( new_out ) + yyout = new_out; +} + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif +{ + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif +} + +void yyFlexLexer::LexerOutput( const char* buf, int size ) +{ + (void) yyout->write( buf, size ); +} + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +int yyFlexLexer::yy_get_next_buffer() +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + pgsrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + yy_state_type yyFlexLexer::yy_get_previous_state() +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 444 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 443); + + return yy_is_jam ? 0 : yy_current_state; +} + + void yyFlexLexer::yyunput( int c, register char* yy_bp) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + + int yyFlexLexer::yyinput() +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyFlexLexer::yyrestart( std::istream* input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + + void yyFlexLexer::yy_load_buffer_state() +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) pgsalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) pgsalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + pgsfree((void *) b->yy_ch_buf ); + + pgsfree((void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yyFlexLexer::yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +void yyFlexLexer::yyensure_buffer_stack(void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)pgsalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)pgsrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + + void yyFlexLexer::yy_push_state( int new_state ) +{ + if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) + { + yy_size_t new_size; + + (yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = (yy_start_stack_depth) * sizeof( int ); + + if ( ! (yy_start_stack) ) + (yy_start_stack) = (int *) pgsalloc(new_size ); + + else + (yy_start_stack) = (int *) pgsrealloc((void *) (yy_start_stack),new_size ); + + if ( ! (yy_start_stack) ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; + + BEGIN(new_state); +} + + void yyFlexLexer::yy_pop_state() +{ + if ( --(yy_start_stack_ptr) < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); +} + + int yyFlexLexer::yy_top_state() +{ + return (yy_start_stack)[(yy_start_stack_ptr) - 1]; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +void yyFlexLexer::LexerError( yyconst char msg[] ) +{ + std::cerr << msg << std::endl; + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *pgsalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *pgsrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void pgsfree (void * ptr ) +{ + free( (char *) ptr ); /* see pgsrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 376 "pgscript/pgsScanner.ll" + + + +namespace pgscript +{ + +pgsScanner::pgsScanner(wxMBConv & conv, std::istream * in, std::ostream * out) : + pgsFlexLexer(in, out), m_parent(0), m_conv(conv) +{ + +} + +pgsScanner::~pgsScanner() +{ + +} + +void pgsScanner::set_debug(bool b) +{ + yy_flex_debug = b; +} + +int pgsScanner::columns(const char & c) +{ + if ((c & 0xF0) == 0xF0) // 4 bytes + return -3; + else if ((c & 0xE0) == 0xE0) // 3 bytes + return -2; + else if ((c & 0xC0) == 0xC0) // 2 bytes + return -1; + else return 0; +} + +} + +/* This implementation of pgsFlexLexer::yylex() is required to fill the + * vtable of the class pgsFlexLexer. We define the scanner's main yylex + * function via YY_DECL to reside in the pgsScanner class instead. */ + +#ifdef yylex +#undef yylex +#endif + +int pgsFlexLexer::yylex() +{ + return 0; +} + diff --git a/pgscript/module.mk b/pgscript/module.mk new file mode 100644 index 0000000..6c1ebcb --- /dev/null +++ b/pgscript/module.mk @@ -0,0 +1,29 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/pgsApplication.cpp \ + pgscript/lex.pgs.cc \ + pgscript/parser.tab.cc + +EXTRA_DIST += \ + pgscript/module.mk \ + pgscript/parser.sh \ + pgscript/pgsParser.yy \ + pgscript/pgsScanner.ll \ + pgscript/README + +include pgscript/exceptions/module.mk +include pgscript/expressions/module.mk +include pgscript/generators/module.mk +include pgscript/objects/module.mk +include pgscript/statements/module.mk +include pgscript/utilities/module.mk diff --git a/pgscript/objects/module.mk b/pgscript/objects/module.mk new file mode 100644 index 0000000..bea2f2b --- /dev/null +++ b/pgscript/objects/module.mk @@ -0,0 +1,21 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/objects/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/objects/pgsGenerator.cpp \ + pgscript/objects/pgsNumber.cpp \ + pgscript/objects/pgsRecord.cpp \ + pgscript/objects/pgsString.cpp \ + pgscript/objects/pgsVariable.cpp + +EXTRA_DIST += \ + pgscript/objects/module.mk + diff --git a/pgscript/objects/pgsGenerator.cpp b/pgscript/objects/pgsGenerator.cpp new file mode 100644 index 0000000..8f4eaaf --- /dev/null +++ b/pgscript/objects/pgsGenerator.cpp @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsGenerator.h" + +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/exceptions/pgsCastException.h" + +pgsGenerator::pgsGenerator(const pgsTypes &generator_type, + pgsObjectGen *randomizer) : + pgsVariable(generator_type), m_randomizer(randomizer) +{ + +} + +pgsGenerator::~pgsGenerator() +{ + +} + +pgsVariable *pgsGenerator::clone() const +{ + return pnew pgsGenerator(*this); +} + +wxString pgsGenerator::value() const +{ + return m_randomizer->random(); +} + +pgsOperand pgsGenerator::operand() const +{ + switch (type()) + { + case pgsTInt: + return pnew pgsNumber(value(), pgsInt); + case pgsTReal: + return pnew pgsNumber(value(), pgsReal); + default: + return pnew pgsString(value()); + } +} + +pgsOperand pgsGenerator::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +pgsOperand pgsGenerator::pgs_plus(const pgsVariable &rhs) const +{ + return *operand() + rhs; +} + +pgsOperand pgsGenerator::pgs_minus(const pgsVariable &rhs) const +{ + return *operand() - rhs; +} + +pgsOperand pgsGenerator::pgs_times(const pgsVariable &rhs) const +{ + return *operand() * rhs; +} + +pgsOperand pgsGenerator::pgs_over(const pgsVariable &rhs) const +{ + return *operand() / rhs; +} + +pgsOperand pgsGenerator::pgs_modulo(const pgsVariable &rhs) const +{ + return *operand() % rhs; +} + +pgsOperand pgsGenerator::pgs_equal(const pgsVariable &rhs) const +{ + return *operand() == rhs; +} + +pgsOperand pgsGenerator::pgs_different(const pgsVariable &rhs) const +{ + return *operand() != rhs; +} + +pgsOperand pgsGenerator::pgs_greater(const pgsVariable &rhs) const +{ + return *operand() > rhs; +} + +pgsOperand pgsGenerator::pgs_lower(const pgsVariable &rhs) const +{ + return *operand() < rhs; +} + +pgsOperand pgsGenerator::pgs_lower_equal(const pgsVariable &rhs) const +{ + return *operand() <= rhs; +} + +pgsOperand pgsGenerator::pgs_greater_equal(const pgsVariable &rhs) const +{ + return *operand() >= rhs; +} + +pgsOperand pgsGenerator::pgs_not() const +{ + return !(*operand()); +} + +bool pgsGenerator::pgs_is_true() const +{ + return operand()->pgs_is_true(); +} + +pgsOperand pgsGenerator::pgs_almost_equal(const pgsVariable &rhs) const +{ + return *operand() &= rhs; +} + +pgsNumber pgsGenerator::number() const +{ + wxString data = value().Strip(wxString::both); + pgsTypes type = pgsNumber::num_type(data); + switch (type) + { + case pgsTInt: + return pgsNumber(data, pgsInt); + case pgsTReal: + return pgsNumber(data, pgsReal); + default: + throw pgsCastException(data, wxT("number")); + } +} + +pgsRecord pgsGenerator::record() const +{ + pgsRecord rec(1); + rec.insert(0, 0, operand()); + return rec; +} + +pgsString pgsGenerator::string() const +{ + return pgsString(value()); +} diff --git a/pgscript/objects/pgsNumber.cpp b/pgscript/objects/pgsNumber.cpp new file mode 100644 index 0000000..3ab6e00 --- /dev/null +++ b/pgscript/objects/pgsNumber.cpp @@ -0,0 +1,286 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsNumber.h" + +#include +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/exceptions/pgsArithmeticException.h" +#include "pgscript/exceptions/pgsCastException.h" + +#define PGS_INTEGER_FORM_1 wxT("^[+-]?[0-9]+$") +#define PGS_REAL_FORM_1 wxT("^[+-]?[0-9]+[Ee][+-]?[0-9]+$") +#define PGS_REAL_FORM_2 wxT("^[+-]?[0-9]*[.][0-9]+([Ee][+-]?[0-9]+)?$") +#define PGS_REAL_FORM_3 wxT("^[+-]?[0-9]+[.][0-9]*([Ee][+-]?[0-9]+)?$") + +pgsNumber::pgsNumber(const wxString &data, const bool &is_real) : + pgsVariable(!is_real ? pgsVariable::pgsTInt : pgsVariable::pgsTReal), + m_data(data.Strip(wxString::both)) +{ + wxASSERT(is_valid()); +} + +bool pgsNumber::is_valid() const +{ + pgsTypes type = num_type(m_data); + return (type == pgsTInt) || (type == pgsTReal && is_real()); +} + +pgsNumber::~pgsNumber() +{ + +} + +pgsNumber::pgsNumber(const pgsNumber &that) : + pgsVariable(that), m_data(that.m_data) +{ + wxASSERT(is_valid()); +} + +pgsNumber &pgsNumber::operator =(const pgsNumber &that) +{ + if (this != &that) + { + pgsVariable::operator=(that); + m_data = that.m_data; + } + + wxASSERT(is_valid()); + + return (*this); +} + +pgsVariable *pgsNumber::clone() const +{ + return pnew pgsNumber(*this); +} + +wxString pgsNumber::value() const +{ + return m_data; +} + +pgsOperand pgsNumber::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +pgsVariable::pgsTypes pgsNumber::num_type(const wxString &num) +{ + if (wxRegEx(PGS_INTEGER_FORM_1).Matches(num)) + { + return pgsTInt; + } + else if (( wxRegEx(PGS_REAL_FORM_1).Matches(num) + || wxRegEx(PGS_REAL_FORM_2).Matches(num) + || wxRegEx(PGS_REAL_FORM_3).Matches(num))) + { + return pgsTReal; + } + else + { + return pgsTString; + } +} + +pgsOperand pgsNumber::pgs_plus(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + + num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_minus(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + - num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_times(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + * num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_over(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + if (num(rhs.value()) != 0) + { + if (is_real() || rhs.is_real()) + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + / num(rhs.value())), is_real() || rhs.is_real()); + else + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + .div(num(rhs.value()))), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_modulo(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + if (num(rhs.value()) != 0) + { + return pnew pgsNumber(pgsMapm::pgs_mapm_str(num(m_data) + % num(rhs.value())), is_real() || rhs.is_real()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_equal(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) == num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_different(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) != num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_greater(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) > num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_lower(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) < num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_lower_equal(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) <= num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_greater_equal(const pgsVariable &rhs) const +{ + if (rhs.is_number()) + { + return pnew pgsNumber(num(m_data) >= num(rhs.value()) + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsNumber::pgs_not() const +{ + return pnew pgsNumber(num(m_data) == 0 ? wxT("1") : wxT("0")); +} + +bool pgsNumber::pgs_is_true() const +{ + return (num(m_data) != 0 ? true : false); +} + +pgsOperand pgsNumber::pgs_almost_equal(const pgsVariable &rhs) const +{ + return pgs_equal(rhs); +} + +pgsNumber pgsNumber::number() const +{ + return pgsNumber(*this); +} + +pgsRecord pgsNumber::record() const +{ + pgsRecord rec(1);; + rec.insert(0, 0, this->clone()); + return rec; +} + +pgsString pgsNumber::string() const +{ + return pgsString(m_data); +} diff --git a/pgscript/objects/pgsRecord.cpp b/pgscript/objects/pgsRecord.cpp new file mode 100644 index 0000000..5815923 --- /dev/null +++ b/pgscript/objects/pgsRecord.cpp @@ -0,0 +1,509 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsRecord.h" + +#include "pgscript/expressions/pgsEqual.h" +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/exceptions/pgsArithmeticException.h" +#include "pgscript/exceptions/pgsCastException.h" + +#include + +WX_DEFINE_OBJARRAY(pgsVectorRecordLine); +WX_DEFINE_OBJARRAY(pgsVectorRecord); + +pgsRecord::pgsRecord(const USHORT &nb_columns) : + pgsVariable(pgsVariable::pgsTRecord) +{ + m_columns.SetCount(nb_columns); +} + +pgsRecord::~pgsRecord() +{ + +} + +pgsVariable *pgsRecord::clone() const +{ + return pnew pgsRecord(*this); +} + +wxString pgsRecord::value() const +{ + wxString data; + pgsVarMap vars; + + // Go through each line and enclose it into braces + for (USHORT i = 0; i < count_lines(); i++) + { + data += wxT("("); + + // Go through each column and separate them with commas + for (USHORT j = 0; j < count_columns(); j++) + { + wxString elm(m_record[i][j]->eval(vars)->value()); + if (!m_record[i][j]->is_number()) + { + elm.Replace(wxT("\\"), wxT("\\\\")); + elm.Replace(wxT("\""), wxT("\\\"")); + elm = wxT("\"") + elm + wxT("\""); + } + data += elm + (j != count_columns() - 1 ? wxT(",") : wxT("")); + } + + data += (i == count_lines() - 1) ? wxT(")") : wxT(")\n"); + } + + // Return the string representation of the record + return data; +} + +pgsOperand pgsRecord::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +USHORT pgsRecord::count_lines() const +{ + return m_record.GetCount(); +} + +USHORT pgsRecord::count_columns() const +{ + return m_columns.GetCount(); +} + +bool pgsRecord::insert(const USHORT &line, const USHORT &column, + pgsOperand value) +{ + // Add lines to match the line number provided + for (USHORT i = count_lines(); i <= line; i++) + { + newline(); + } + + // Cannot insert if column is invalid + if (column >= count_columns()) + { + return false; + } + // Insert the value at line.column + else + { + m_record[line][column] = value; + return true; + } +} + +pgsOperand pgsRecord::get(const USHORT &line, + const USHORT &column) const +{ + if (line < count_lines() && column < count_columns()) + { + return m_record[line][column]; + } + else + { + return pnew pgsString(wxT("")); + } +} + +pgsOperand pgsRecord::get_line(const USHORT &line) const +{ + if (line < count_lines()) + { + pgsRecord *rec = pnew pgsRecord(count_columns()); + rec->m_columns = this->m_columns; + rec->newline(); + rec->m_record[0] = this->m_record[line]; + return rec; + } + else + { + return pnew pgsRecord(0); + } +} + +bool pgsRecord::set_column_name(const USHORT &column, wxString name) +{ + // Column number must be valid + if (column >= count_columns()) + { + return false; + } + + // Column name must not exist + // Column name must not be empty + name = name.Strip(wxString::both).Lower(); + if (m_columns.Index(name) != wxNOT_FOUND || name.IsEmpty()) + { + return false; + } + + // Set the column name + m_columns[column] = name; + + return true; +} + +USHORT pgsRecord::get_column(wxString name) const +{ + name = name.Strip(wxString::both).Lower(); + if (name.IsEmpty()) + { + return count_columns(); + } + for (USHORT i = 0; i < count_columns(); i++) + { + if (m_columns[i] == name) + return i; + } + return count_columns(); +} + +bool pgsRecord::remove_line(const USHORT &line) +{ + if (line < count_lines()) + { + m_record.RemoveAt(line); + return true; + } + return false; +} + +bool pgsRecord::newline() +{ + // Insert a line + m_record.Add(pgsVectorRecordLine()); + // Initialize each column of the line with an empty string + for (USHORT i = 0; i < count_columns(); i++) + { + m_record.Last().Add(pnew pgsString(wxT(""))); + } + return true; +} + +bool pgsRecord::valid() const +{ + return true; +} + +bool pgsRecord::operator==(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() != rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, true); +} + +bool pgsRecord::operator!=(const pgsRecord &rhs) const +{ + return !(*this == rhs); +} + +bool pgsRecord::operator<(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() >= rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, true); +} + +bool pgsRecord::operator>(const pgsRecord &rhs) const +{ + return (rhs < *this); +} + +bool pgsRecord::operator<=(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() > rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, true); +} + +bool pgsRecord::operator>=(const pgsRecord &rhs) const +{ + return (rhs <= *this); +} + +bool pgsRecord::almost_equal(const pgsRecord &rhs) const +{ + // Test the number of lines + if (this->count_lines() != rhs.count_lines()) + { + return false; + } + + return records_equal(*this, rhs, false); +} + +bool pgsRecord::records_equal(const pgsRecord &lhs, const pgsRecord &rhs, + bool case_sensitive) const +{ + // Test the number of columns + if (lhs.count_columns() != rhs.count_columns()) + { + return false; + } + + // Test each line + wxArrayInt seen; + for (USHORT i = 0; i < lhs.count_lines(); i++) + { + bool result = false; + + // Test if the line of lhs matches with an unseen line of rhs + for (USHORT j = 0; result == false && j < rhs.count_lines(); j++) + { + int k = wx_static_cast(int, j); + if (seen.Index(k) == wxNOT_FOUND + && lines_equal(lhs.m_record[i], rhs.m_record[j], + case_sensitive)) + { + result = true; + seen.push_back(k); + } + else + { + // This is not OK... Continue with the next element + continue; + } + } + + if (result == false) + { + return false; + } + else + { + continue; + } + } + + return true; // End of the test +} + +bool pgsRecord::lines_equal(const pgsVectorRecordLine &lhs, + const pgsVectorRecordLine &rhs, bool case_sensitive) const +{ + pgsVarMap vars; + + // Both lines must have the same number of columns + if (lhs.GetCount() != rhs.GetCount()) + { + return false; + } + + // Test each element (column) of the line + for (USHORT j = 0; j < wx_static_cast(USHORT, lhs.GetCount()); j++) + { + // Test if the two elements are equal + pgsEqual test(lhs[j]->string().clone(), rhs[j]->string().clone(), + case_sensitive); + if (test.eval(vars)->value() == wxT("1")) + { + // lhs == rhs: continue + continue; + } + else + { + // lhs != rhs: lines are not equal + return false; + } + } + + return true; +} + +pgsOperand pgsRecord::pgs_plus(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_minus(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_times(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_over(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_modulo(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(value(), rhs.value()); +} + +pgsOperand pgsRecord::pgs_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this == rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_different(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this != rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_greater(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this > rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_lower(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this < rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_lower_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this <= rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_greater_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(*this >= rhs_op ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsOperand pgsRecord::pgs_not() const +{ + if (pgs_is_true()) + { + // A record with no line is false + return pnew pgsRecord(count_columns()); + } + else + { + // A record with at least one line is true + pgsRecord *copy = pnew pgsRecord(*this); + copy->newline(); + return copy; // Insert one line and return the record + } +} + +bool pgsRecord::pgs_is_true() const +{ + return (count_lines() > 0 ? true : false); +} + +pgsOperand pgsRecord::pgs_almost_equal(const pgsVariable &rhs) const +{ + if (rhs.is_record()) + { + const pgsRecord &rhs_op = dynamic_cast(rhs); + return pnew pgsNumber(this->almost_equal(rhs_op) ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(value(), rhs.value()); + } +} + +pgsNumber pgsRecord::number() const +{ + wxString data = value().Strip(wxString::both); + + if (data.StartsWith(wxT("("))) + { + data = data.Mid(1); + } + + if (data.EndsWith(wxT(")"))) + { + data = data.Mid(0, data.Len() - 1); + } + + pgsTypes type = pgsNumber::num_type(data); + switch (type) + { + case pgsTInt: + return pgsNumber(data, pgsInt); + case pgsTReal: + return pgsNumber(data, pgsReal); + default: + throw pgsCastException(data, wxT("number")); + } +} + +pgsRecord pgsRecord::record() const +{ + return pgsRecord(*this); +} + +pgsString pgsRecord::string() const +{ + return pgsString(value()); +} diff --git a/pgscript/objects/pgsString.cpp b/pgscript/objects/pgsString.cpp new file mode 100644 index 0000000..a6cde77 --- /dev/null +++ b/pgscript/objects/pgsString.cpp @@ -0,0 +1,290 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsString.h" + +#include +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsRecord.h" +#include "pgscript/exceptions/pgsArithmeticException.h" +#include "pgscript/exceptions/pgsCastException.h" + +pgsString::pgsString(const wxString &data) : + pgsVariable(pgsVariable::pgsTString), m_data(data) +{ + +} + +pgsString::~pgsString() +{ + +} + +pgsVariable *pgsString::clone() const +{ + return pnew pgsString(*this); +} + +wxString pgsString::value() const +{ + return m_data; +} + +pgsOperand pgsString::eval(pgsVarMap &vars) const +{ + return this->clone(); +} + +pgsOperand pgsString::pgs_plus(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsString(m_data + rhs.value()); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_minus(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_times(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_over(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_modulo(const pgsVariable &rhs) const +{ + throw pgsArithmeticException(m_data, rhs.value()); +} + +pgsOperand pgsString::pgs_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data == rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_different(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data != rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_greater(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data > rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_lower(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data < rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_lower_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data <= rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_greater_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data >= rhs.value() ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsOperand pgsString::pgs_not() const +{ + wxString data = m_data.Strip(wxString::both); + return pnew pgsString(data.IsEmpty() ? wxT("1") : wxT("")); +} + +bool pgsString::pgs_is_true() const +{ + wxString data = m_data.Strip(wxString::both); + return (!data.IsEmpty() ? true : false); +} + +pgsOperand pgsString::pgs_almost_equal(const pgsVariable &rhs) const +{ + if (rhs.is_string()) + { + return pnew pgsNumber(m_data.CmpNoCase(rhs.value()) == 0 + ? wxT("1") : wxT("0")); + } + else + { + throw pgsArithmeticException(m_data, rhs.value()); + } +} + +pgsNumber pgsString::number() const +{ + wxString data = m_data.Strip(wxString::both); + pgsTypes type = pgsNumber::num_type(data); + switch (type) + { + case pgsTInt: + return pgsNumber(data, pgsInt); + case pgsTReal: + return pgsNumber(data, pgsReal); + default: + throw pgsCastException(data, wxT("number")); + } +} + +pgsRecord pgsString::record() const +{ + pgsRecord *rec = 0; + + // Try to find the representation of a record in the string + { + wxString element(wxT("(\"([^\"\\\\]|\\\\.)*\")|((-|[a-zA-Z0-9\\+\\.])+)")); + wxString data(m_data); + wxRegEx regex1(wxString() << wxT("^[[:space:]]*\\([[:space:]]*(") + << element << wxT(")[[:space:]]*([,][[:space:]]*(") + << element << wxT(")[[:space:]]*)*\\)"), wxRE_DEFAULT | wxRE_ICASE); + + // Find each line + size_t line_nb = 0, nb_of_columns = 0; + bool count_columns = true; + while (regex1.Matches(data)) + { + // Process that line: find each element + wxString line(regex1.GetMatch(data)); + wxRegEx regex2(element); + size_t column_nb = 0; + while (regex2.Matches(line)) + { + if (count_columns == true) + { + ++nb_of_columns; + } + else + { + if (column_nb < nb_of_columns && rec != 0) + { + wxString value(regex2.GetMatch(line)); + if (value.StartsWith(wxT("\"")) + && value.EndsWith(wxT("\""))) + { + // This is a string + value = value.Mid(1, value.Len() - 2); + value.Replace(wxT("\\\""), wxT("\"")); + value.Replace(wxT("\\\\"), wxT("\\")); + rec->insert(line_nb, column_nb, + pnew pgsString(value)); + } + else + { + // This is a number or a string + pgsTypes type = pgsNumber::num_type(value); + switch (type) + { + case pgsTInt: + rec->insert(line_nb, column_nb, + pnew pgsNumber(value, pgsInt)); + break; + case pgsTReal: + rec->insert(line_nb, column_nb, + pnew pgsNumber(value, pgsReal)); + break; + default: + rec->insert(line_nb, column_nb, + pnew pgsString(value)); + break; + } + } + } + ++column_nb; + } + + regex2.ReplaceFirst(&line, wxT("")); + } + + // If it is the first loop we want to process this line a + // second time because the first one was meant to count + // the number of columns + if (count_columns == true) + { + count_columns = false; + rec = pnew pgsRecord(nb_of_columns); + } + else + { + regex1.ReplaceFirst(&data, wxT("")); + ++line_nb; + } + } + } + + // Process the case + if (rec == 0) + { + rec = pnew pgsRecord(1); + rec->insert(0, 0, this->clone()); + } + + pgsRecord ret_val(*rec); + pdelete(rec); + return ret_val; +} + +pgsString pgsString::string() const +{ + return pgsString(*this); +} diff --git a/pgscript/objects/pgsVariable.cpp b/pgscript/objects/pgsVariable.cpp new file mode 100644 index 0000000..1e72f21 --- /dev/null +++ b/pgscript/objects/pgsVariable.cpp @@ -0,0 +1,128 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/objects/pgsVariable.h" + +pgsVariable::pgsVariable(const pgsTypes &type) : + pgsExpression(), m_type(type) +{ + +} + +pgsVariable::~pgsVariable() +{ + +} + +MAPM pgsVariable::num(const pgsOperand &var) +{ + return pgsMapm::pgs_str_mapm(var->value()); +} + +MAPM pgsVariable::num(const wxString &var) +{ + return pgsMapm::pgs_str_mapm(var); +} + +bool pgsVariable::is_number() const +{ + return is_integer() || is_real(); +} + +bool pgsVariable::is_integer() const +{ + return m_type == pgsTInt; +} + +bool pgsVariable::is_real() const +{ + return m_type == pgsTReal; +} + +bool pgsVariable::is_string() const +{ + return m_type == pgsTString; +} + +bool pgsVariable::is_record() const +{ + return m_type == pgsTRecord; +} + +const pgsVariable::pgsTypes &pgsVariable::type() const +{ + return m_type; +} + +pgsOperand operator+(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_plus(rhs); +} + +pgsOperand operator-(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_minus(rhs); +} + +pgsOperand operator*(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_times(rhs); +} + +pgsOperand operator/(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_over(rhs); +} + +pgsOperand operator%(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_modulo(rhs); +} + +pgsOperand operator==(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_equal(rhs); +} + +pgsOperand operator!=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_different(rhs); +} + +pgsOperand operator<(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_lower(rhs); +} + +pgsOperand operator>(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_greater(rhs); +} + +pgsOperand operator<=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_lower_equal(rhs); +} + +pgsOperand operator>=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_greater_equal(rhs); +} + +pgsOperand operator!(const pgsVariable &lhs) +{ + return lhs.pgs_not(); +} + +pgsOperand operator&=(const pgsVariable &lhs, const pgsVariable &rhs) +{ + return lhs.pgs_almost_equal(rhs); +} diff --git a/pgscript/parser.sh b/pgscript/parser.sh new file mode 100644 index 0000000..d89d4fe --- /dev/null +++ b/pgscript/parser.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# parser.sh - Runs Flex and Bison and processes the generated files +# +####################################################################### + +# Directory containing pgScript includes (relative to the src directory) +INCLUDEDIR="include/pgscript" +# Directory containing pgScript sources (relative to the src directory) +SOURCEDIR="pgscript" +# Headers generated by Bison that need to be moved to ${INCLUDEDIR} +FILESTOMOVE=( "location.hh" "parser.tab.hh" "position.hh" "stack.hh" ) + +# Flex destination +LEXER="pgscript/lex.pgs.cc" +# A temporary file +AUX="pgscript/auxfile" +# Bison destination +PARSER="pgscript/parser.tab.cc" + +####################################################################### + +# Find the current directory +THISDIR=`dirname $0` +PREVDIR="$PWD" + +# Go to the directory on top of the script directory +echo -n "cd ${THISDIR}/.. ... " +cd "${THISDIR}/.." +echo "done" +pwd +echo "" + +# Generate Bison file +echo -n "+ Generating Bison output... " +bison -o"${PARSER}" "${SOURCEDIR}/pgsParser.yy" +echo "done" + +# Generate Flex file +echo -n "+ Generating Flex output... " +flex -o"${LEXER}" "${SOURCEDIR}/pgsScanner.ll" +echo "done" + +# Add pgAdmin3.h include at the beginning and change to +# "pgscript/FlexLexer.h" for the Flex output +echo -n "+ Processing Flex output... " +cat "${LEXER}" | awk 'BEGIN {print "#include \"pgAdmin3.h\"\n\n"}{print $0}' \ + | sed -e 's//"pgscript\/FlexLexer\.h"/g' > "${AUX}" +mv -f "${AUX}" "${LEXER}" +echo "done" + +# Add pgAdmin3.h include at the beginning and a pragma and change +# "parser.tab.hh" to "pgscript/parser.tab.hh" to the Bison output +echo -n "+ Processing Bison output... " +cat "${PARSER}" | awk 'BEGIN {print "#include \"pgAdmin3.h\"\n#if _MSC_VER > 1000\n#pragma warning(disable: 4800)\n#endif\n"}{print $0}' | \ + sed -e 's/"parser.tab.hh"/"pgscript\/parser\.tab\.hh"/g' > "${AUX}" +sleep 1 +mv -f "${AUX}" "${PARSER}" +echo "done" + +# Move Bison include files to the include directory +echo + "Moving Bison header files... " +for file in ${FILESTOMOVE[@]} +do + echo " + mv ${SOURCEDIR}/${file} ${INCLUDEDIR}/${file}" + mv "${SOURCEDIR}/${file}" "${INCLUDEDIR}/${file}" +done +echo "... done" + +# Go back to the previous directory +echo "" +echo -n "cd $PREVDIR ... " +cd "$PREVDIR" +echo "done" diff --git a/pgscript/parser.tab.cc b/pgscript/parser.tab.cc new file mode 100644 index 0000000..cb3fbf4 --- /dev/null +++ b/pgscript/parser.tab.cc @@ -0,0 +1,2703 @@ +#include "pgAdmin3.h" +#if _MSC_VER > 1000 +#pragma warning(disable: 4800) +#endif + +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +// Take the name prefix into account. +#define yylex pgscriptlex + +#include "pgscript/parser.tab.hh" + +/* User implementation prologue. */ +#line 251 "pgscript/pgsParser.yy" + + +#include "pgscript/utilities/pgsDriver.h" +#include "pgscript/utilities/pgsScanner.h" + +/* This "connects" the bison parser in the driver to the flex scanner class + * object. It defines the yylex() function call to pull the next token from the + * current lexer object of the driver context. */ +#undef yylex +#define yylex driver.lexer->lex + + + +/* Line 317 of lalr1.cc. */ +#line 57 "pgscript/parser.tab.cc" + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* FIXME: INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#define YYUSE(e) ((void) (e)) + +/* A pseudo ostream that takes yydebug_ into account. */ +# define YYCDEBUG \ + for (bool yydebugcond_ = yydebug_; yydebugcond_; yydebugcond_ = false) \ + (*yycdebug_) + +/* Enable debugging if requested. */ +#if YYDEBUG + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug_) \ + { \ + *yycdebug_ << Title << ' '; \ + yy_symbol_print_ ((Type), (Value), (Location)); \ + *yycdebug_ << std::endl; \ + } \ +} while (false) + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug_) \ + yy_reduce_print_ (Rule); \ +} while (false) + +# define YY_STACK_PRINT() \ +do { \ + if (yydebug_) \ + yystack_print_ (); \ +} while (false) + +#else /* !YYDEBUG */ + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_REDUCE_PRINT(Rule) +# define YY_STACK_PRINT() + +#endif /* !YYDEBUG */ + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + +namespace pgscript +{ +#if YYERROR_VERBOSE + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + std::string + pgsParser::yytnamerr_ (const char *yystr) + { + if (*yystr == '"') + { + std::string yyr = ""; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } + + return yystr; + } + +#endif + + /// Build a parser object. + pgsParser::pgsParser (class pgsDriver & driver_yyarg) + : yydebug_ (false), + yycdebug_ (&std::cerr), + driver (driver_yyarg) + { + } + + pgsParser::~pgsParser () + { + } + +#if YYDEBUG + /*--------------------------------. + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + + inline void + pgsParser::yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yyvaluep); + switch (yytype) + { + default: + break; + } + } + + + void + pgsParser::yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") + << ' ' << yytname_[yytype] << " (" + << *yylocationp << ": "; + yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); + *yycdebug_ << ')'; + } +#endif /* ! YYDEBUG */ + + void + pgsParser::yydestruct_ (const char* yymsg, + int yytype, semantic_type* yyvaluep, location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yymsg); + YYUSE (yyvaluep); + + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + case 42: /* "\"ABORT\"" */ +#line 167 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 217 "pgscript/parser.tab.cc" + break; + case 43: /* "\"ALTER\"" */ +#line 168 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 222 "pgscript/parser.tab.cc" + break; + case 44: /* "\"ANALYZE\"" */ +#line 169 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 227 "pgscript/parser.tab.cc" + break; + case 45: /* "\"BEGIN\"" */ +#line 170 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 232 "pgscript/parser.tab.cc" + break; + case 46: /* "\"CHECKPOINT\"" */ +#line 171 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 237 "pgscript/parser.tab.cc" + break; + case 47: /* "\"CLOSE\"" */ +#line 172 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 242 "pgscript/parser.tab.cc" + break; + case 48: /* "\"CLUSTER\"" */ +#line 173 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 247 "pgscript/parser.tab.cc" + break; + case 49: /* "\"COMMENT\"" */ +#line 174 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 252 "pgscript/parser.tab.cc" + break; + case 50: /* "\"COMMIT\"" */ +#line 175 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 257 "pgscript/parser.tab.cc" + break; + case 51: /* "\"COPY\"" */ +#line 176 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 262 "pgscript/parser.tab.cc" + break; + case 52: /* "\"CREATE\"" */ +#line 177 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 267 "pgscript/parser.tab.cc" + break; + case 53: /* "\"DEALLOCATE\"" */ +#line 178 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 272 "pgscript/parser.tab.cc" + break; + case 54: /* "\"DECLARE\"" */ +#line 179 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 277 "pgscript/parser.tab.cc" + break; + case 55: /* "\"DELETE\"" */ +#line 180 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 282 "pgscript/parser.tab.cc" + break; + case 56: /* "\"DISCARD\"" */ +#line 181 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 287 "pgscript/parser.tab.cc" + break; + case 57: /* "\"DROP\"" */ +#line 182 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 292 "pgscript/parser.tab.cc" + break; + case 58: /* "\"END\"" */ +#line 183 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 297 "pgscript/parser.tab.cc" + break; + case 59: /* "\"EXECUTE\"" */ +#line 184 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 302 "pgscript/parser.tab.cc" + break; + case 60: /* "\"EXPLAIN\"" */ +#line 185 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 307 "pgscript/parser.tab.cc" + break; + case 61: /* "\"FETCH\"" */ +#line 186 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 312 "pgscript/parser.tab.cc" + break; + case 62: /* "\"GRANT\"" */ +#line 187 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 317 "pgscript/parser.tab.cc" + break; + case 63: /* "\"INSERT\"" */ +#line 188 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 322 "pgscript/parser.tab.cc" + break; + case 64: /* "\"LISTEN\"" */ +#line 189 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 327 "pgscript/parser.tab.cc" + break; + case 65: /* "\"LOAD\"" */ +#line 190 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 332 "pgscript/parser.tab.cc" + break; + case 66: /* "\"LOCK\"" */ +#line 191 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 337 "pgscript/parser.tab.cc" + break; + case 67: /* "\"MOVE\"" */ +#line 192 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 342 "pgscript/parser.tab.cc" + break; + case 68: /* "\"NOTIFY\"" */ +#line 193 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 347 "pgscript/parser.tab.cc" + break; + case 69: /* "\"PREPARE\"" */ +#line 194 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 352 "pgscript/parser.tab.cc" + break; + case 70: /* "\"REASSIGN\"" */ +#line 195 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 357 "pgscript/parser.tab.cc" + break; + case 71: /* "\"REINDEX\"" */ +#line 196 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 362 "pgscript/parser.tab.cc" + break; + case 72: /* "\"RELEASE\"" */ +#line 197 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 367 "pgscript/parser.tab.cc" + break; + case 73: /* "\"RESET\"" */ +#line 198 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 372 "pgscript/parser.tab.cc" + break; + case 74: /* "\"REVOKE\"" */ +#line 199 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 377 "pgscript/parser.tab.cc" + break; + case 75: /* "\"ROLLBACK\"" */ +#line 200 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 382 "pgscript/parser.tab.cc" + break; + case 76: /* "\"SAVEPOINT\"" */ +#line 201 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 387 "pgscript/parser.tab.cc" + break; + case 77: /* "\"SELECT\"" */ +#line 202 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 392 "pgscript/parser.tab.cc" + break; + case 78: /* "\"SET\"" */ +#line 203 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 397 "pgscript/parser.tab.cc" + break; + case 79: /* "\"SHOW\"" */ +#line 204 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 402 "pgscript/parser.tab.cc" + break; + case 80: /* "\"START\"" */ +#line 205 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 407 "pgscript/parser.tab.cc" + break; + case 81: /* "\"TRUNCATE\"" */ +#line 206 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 412 "pgscript/parser.tab.cc" + break; + case 82: /* "\"UNLISTEN\"" */ +#line 207 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 417 "pgscript/parser.tab.cc" + break; + case 83: /* "\"UPDATE\"" */ +#line 208 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 422 "pgscript/parser.tab.cc" + break; + case 84: /* "\"VACUUM\"" */ +#line 209 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 427 "pgscript/parser.tab.cc" + break; + case 85: /* "\"VALUES\"" */ +#line 210 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 432 "pgscript/parser.tab.cc" + break; + case 86: /* "\"IDENTIFIER\"" */ +#line 212 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 437 "pgscript/parser.tab.cc" + break; + case 87: /* "\"INTEGER VALUE\"" */ +#line 213 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 442 "pgscript/parser.tab.cc" + break; + case 88: /* "\"REAL VALUE\"" */ +#line 214 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 447 "pgscript/parser.tab.cc" + break; + case 89: /* "\"STRING VALUE\"" */ +#line 215 "pgscript/pgsParser.yy" + { pdelete((yyvaluep->str)); }; +#line 452 "pgscript/parser.tab.cc" + break; + + default: + break; + } + } + + void + pgsParser::yypop_ (unsigned int n) + { + yystate_stack_.pop (n); + yysemantic_stack_.pop (n); + yylocation_stack_.pop (n); + } + + std::ostream& + pgsParser::debug_stream () const + { + return *yycdebug_; + } + + void + pgsParser::set_debug_stream (std::ostream& o) + { + yycdebug_ = &o; + } + + + pgsParser::debug_level_type + pgsParser::debug_level () const + { + return yydebug_; + } + + void + pgsParser::set_debug_level (debug_level_type l) + { + yydebug_ = l; + } + + + int + pgsParser::parse () + { + /// Look-ahead and look-ahead in internal form. + int yychar = yyempty_; + int yytoken = 0; + + /* State. */ + int yyn; + int yylen = 0; + int yystate = 0; + + /* Error handling. */ + int yynerrs_ = 0; + int yyerrstatus_ = 0; + + /// Semantic value of the look-ahead. + semantic_type yylval; + /// Location of the look-ahead. + location_type yylloc; + /// The locations where the error started and ended. + location yyerror_range[2]; + + /// $$. + semantic_type yyval; + /// @$. + location_type yyloc; + + int yyresult; + + YYCDEBUG << "Starting parse" << std::endl; + + + /* User initialization code. */ + #line 43 "pgscript/pgsParser.yy" +{ + // Initialize the initial location object + yylloc.begin.filename = yylloc.end.filename; +} + /* Line 547 of yacc.c. */ +#line 534 "pgscript/parser.tab.cc" + /* Initialize the stacks. The initial state will be pushed in + yynewstate, since the latter expects the semantical and the + location values to have been already stored, initialize these + stacks with a primary value. */ + yystate_stack_ = state_stack_type (0); + yysemantic_stack_ = semantic_stack_type (0); + yylocation_stack_ = location_stack_type (0); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* New state. */ + yynewstate: + yystate_stack_.push (yystate); + YYCDEBUG << "Entering state " << yystate << std::endl; + goto yybackup; + + /* Backup. */ + yybackup: + + /* Try to take a decision without look-ahead. */ + yyn = yypact_[yystate]; + if (yyn == yypact_ninf_) + goto yydefault; + + /* Read a look-ahead token. */ + if (yychar == yyempty_) + { + YYCDEBUG << "Reading a token: "; + yychar = yylex (&yylval, &yylloc); + } + + + /* Convert token to internal form. */ + if (yychar <= yyeof_) + { + yychar = yytoken = yyeof_; + YYCDEBUG << "Now at end of input." << std::endl; + } + else + { + yytoken = yytranslate_ (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + goto yydefault; + + /* Reduce or error. */ + yyn = yytable_[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == yytable_ninf_) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Accept? */ + if (yyn == yyfinal_) + goto yyacceptlab; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != yyeof_) + yychar = yyempty_; + + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus_) + --yyerrstatus_; + + yystate = yyn; + goto yynewstate; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + yydefault: + yyn = yydefact_[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + yyreduce: + yylen = yyr2_[yyn]; + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + if (yylen) + yyval = yysemantic_stack_[yylen - 1]; + else + yyval = yysemantic_stack_[0]; + + { + slice slice (yylocation_stack_, yylen); + YYLLOC_DEFAULT (yyloc, slice, yylen); + } + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 268 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsIdentRecord(*((yysemantic_stack_[(7) - (1)].str)), (yysemantic_stack_[(7) - (3)].expr), (yysemantic_stack_[(7) - (6)].expr)); + pdelete((yysemantic_stack_[(7) - (1)].str)); + driver.context.pop_var(); driver.context.pop_var(); // $3 & $6 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 3: +#line 275 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsIdentRecord(*((yysemantic_stack_[(4) - (1)].str)), (yysemantic_stack_[(4) - (3)].expr)); + pdelete((yysemantic_stack_[(4) - (1)].str)); + driver.context.pop_var(); // $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 4: +#line 282 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsLines(*((yysemantic_stack_[(4) - (3)].str))); + pdelete((yysemantic_stack_[(4) - (3)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 5: +#line 288 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsColumns(*((yysemantic_stack_[(4) - (3)].str))); + pdelete((yysemantic_stack_[(4) - (3)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 6: +#line 294 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsTrim((yysemantic_stack_[(4) - (3)].expr)); + driver.context.pop_var(); // $3 + driver.context.push_var((yyval.expr)); // assert + ;} + break; + + case 7: +#line 300 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsIdent(*((yysemantic_stack_[(1) - (1)].str))); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 8: +#line 306 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNumber(*((yysemantic_stack_[(1) - (1)].str)), pgsInt); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 9: +#line 312 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNumber(*((yysemantic_stack_[(1) - (1)].str)), pgsReal); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 10: +#line 318 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsString(*((yysemantic_stack_[(1) - (1)].str))); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 11: +#line 323 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsExecute(*((yysemantic_stack_[(3) - (2)].str)), &driver.context.m_cout, + &(driver.thread)); + pdelete((yysemantic_stack_[(3) - (2)].str)); + driver.context.push_var((yyval.expr)); // SQL Expression statement + ;} + break; + + case 12: +#line 329 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 13: +#line 330 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsParenthesis((yysemantic_stack_[(3) - (2)].expr)); + driver.context.pop_var(); // $2 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 14: +#line 338 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 15: +#line 339 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(2) - (2)].expr); ;} + break; + + case 16: +#line 340 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNegate((yysemantic_stack_[(2) - (2)].expr)); + driver.context.pop_var(); // $2 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 17: +#line 346 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsNot((yysemantic_stack_[(2) - (2)].expr)); + driver.context.pop_var(); // $2 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 18: +#line 354 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 19: +#line 356 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsCast((yysemantic_stack_[(6) - (5)].integer), (yysemantic_stack_[(6) - (3)].expr)); + driver.context.pop_var(); // $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 20: +#line 364 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_INTEGER; ;} + break; + + case 21: +#line 365 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_REAL; ;} + break; + + case 22: +#line 366 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_STRING; ;} + break; + + case 23: +#line 367 "pgscript/pgsParser.yy" + { (yyval.integer) = pgscript::pgsParser::token::PGS_RECORD; ;} + break; + + case 24: +#line 371 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 25: +#line 373 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsTimes((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 26: +#line 380 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsOver((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 27: +#line 387 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsModulo((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 28: +#line 396 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 29: +#line 398 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsPlus((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 30: +#line 405 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsMinus((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 31: +#line 414 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 32: +#line 416 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsLower((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 33: +#line 423 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGreater((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 34: +#line 430 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsLowerEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 35: +#line 437 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGreaterEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 36: +#line 446 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 37: +#line 448 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 38: +#line 455 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsEqual((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr), false); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 39: +#line 462 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsDifferent((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 40: +#line 471 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 41: +#line 473 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsAnd((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 42: +#line 482 "pgscript/pgsParser.yy" + { (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); ;} + break; + + case 43: +#line 484 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsOr((yysemantic_stack_[(3) - (1)].expr), (yysemantic_stack_[(3) - (3)].expr)); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var((yyval.expr)); + ;} + break; + + case 44: +#line 493 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("%s"), (yysemantic_stack_[(1) - (1)].expr)->value().c_str()); + (yyval.expr) = (yysemantic_stack_[(1) - (1)].expr); + ;} + break; + + case 45: +#line 501 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenInt((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 46: +#line 509 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenInt((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 47: +#line 516 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenInt((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 48: +#line 523 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReal((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 49: +#line 532 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReal((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 50: +#line 540 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReal((yysemantic_stack_[(12) - (3)].expr), (yysemantic_stack_[(12) - (5)].expr), (yysemantic_stack_[(12) - (7)].expr), (yysemantic_stack_[(12) - (9)].expr), (yysemantic_stack_[(12) - (11)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 51: +#line 548 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenString((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.one(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 52: +#line 556 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenString((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 53: +#line 563 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenString((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 54: +#line 570 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenRegex((yysemantic_stack_[(4) - (3)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 55: +#line 576 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenRegex((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 56: +#line 582 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(4) - (3)].expr), driver.context.zero(), + driver.context.seed(), driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 57: +#line 590 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.seed(), + driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 58: +#line 598 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 59: +#line 605 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDictionary((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 60: +#line 612 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDate((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 61: +#line 620 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDate((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 62: +#line 627 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDate((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 63: +#line 634 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenTime((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 64: +#line 642 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenTime((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 65: +#line 649 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenTime((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 66: +#line 656 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDateTime((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 67: +#line 664 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDateTime((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 68: +#line 671 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenDateTime((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 69: +#line 678 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReference((yysemantic_stack_[(6) - (3)].expr), (yysemantic_stack_[(6) - (5)].expr), driver.context.zero(), + driver.context.seed(), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 70: +#line 686 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReference((yysemantic_stack_[(8) - (3)].expr), (yysemantic_stack_[(8) - (5)].expr), (yysemantic_stack_[(8) - (7)].expr), driver.context.seed(), + &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 71: +#line 694 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsGenReference((yysemantic_stack_[(10) - (3)].expr), (yysemantic_stack_[(10) - (5)].expr), (yysemantic_stack_[(10) - (7)].expr), (yysemantic_stack_[(10) - (9)].expr), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var((yyval.expr)); + ;} + break; + + case 72: +#line 703 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(1) - (1)].stmt); ;} + break; + + case 73: +#line 704 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(1) - (1)].stmt); ;} + break; + + case 74: +#line 705 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(1) - (1)].stmt); ;} + break; + + case 75: +#line 706 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 76: +#line 707 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 77: +#line 708 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 78: +#line 709 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 79: +#line 710 "pgscript/pgsParser.yy" + { (yyval.stmt) = (yysemantic_stack_[(2) - (1)].stmt); ;} + break; + + case 80: +#line 714 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $1 + (yyval.stmt_list) = driver.context.stmt_list(&(driver.thread)); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(1) - (1)].stmt)); + ;} + break; + + case 81: +#line 719 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $2 + (yyval.stmt_list) = (yysemantic_stack_[(2) - (1)].stmt_list); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(2) - (2)].stmt)); + ;} + break; + + case 82: +#line 727 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("BEGIN END")); + (yyval.stmt) = driver.context.stmt_list(&(driver.thread)); + ;} + break; + + case 83: +#line 732 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("BEGIN ... END")); + (yyval.stmt) = (yysemantic_stack_[(3) - (2)].stmt_list); + ;} + break; + + case 84: +#line 739 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("%s"), (yysemantic_stack_[(1) - (1)].expr)->value().c_str()); + (yyval.stmt) = pnew pgsExpressionStmt((yysemantic_stack_[(1) - (1)].expr), &(driver.thread)); + driver.context.pop_var(); // $1 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 85: +#line 749 "pgscript/pgsParser.yy" + { + (yyval.expr) = pnew pgsExecute(*((yysemantic_stack_[(1) - (1)].str)), &driver.context.m_cout, + &(driver.thread)); + pdelete((yysemantic_stack_[(1) - (1)].str)); + driver.context.push_var((yyval.expr)); // pgsExecute + ;} + break; + + case 86: +#line 758 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 87: +#line 759 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 88: +#line 760 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 89: +#line 761 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 90: +#line 762 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 91: +#line 763 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 92: +#line 764 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 93: +#line 765 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 94: +#line 766 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 95: +#line 767 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 96: +#line 768 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 97: +#line 769 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 98: +#line 770 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 99: +#line 771 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 100: +#line 772 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 101: +#line 773 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 102: +#line 774 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 103: +#line 775 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 104: +#line 776 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 105: +#line 777 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 106: +#line 778 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 107: +#line 779 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 108: +#line 780 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 109: +#line 781 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 110: +#line 782 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 111: +#line 783 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 112: +#line 784 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 113: +#line 785 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 114: +#line 786 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 115: +#line 787 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 116: +#line 788 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 117: +#line 789 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 118: +#line 790 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 119: +#line 791 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 120: +#line 792 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 121: +#line 793 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 122: +#line 794 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 123: +#line 795 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 124: +#line 796 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 125: +#line 797 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 126: +#line 798 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 127: +#line 799 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 128: +#line 800 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 129: +#line 801 "pgscript/pgsParser.yy" + { (yyval.str) = (yysemantic_stack_[(1) - (1)].str); ;} + break; + + case 130: +#line 806 "pgscript/pgsParser.yy" + { + (yyval.stmt) = (yysemantic_stack_[(2) - (2)].stmt_list); + ;} + break; + + case 131: +#line 812 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $1 + (yyval.stmt_list) = driver.context.stmt_list(&(driver.thread)); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(1) - (1)].stmt)); + + ;} + break; + + case 132: +#line 819 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $3 + (yyval.stmt_list) = (yysemantic_stack_[(3) - (1)].stmt_list); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(3) - (3)].stmt)); + ;} + break; + + case 133: +#line 827 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("DECLARE %s"), (yysemantic_stack_[(1) - (1)].str)->c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssign(*((yysemantic_stack_[(1) - (1)].str)), + pnew pgsString(wxT(""))), &(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(1) - (1)].str)); + ;} + break; + + case 134: +#line 838 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("DECLARE %s"), (yysemantic_stack_[(4) - (1)].str)->c_str()); + + (yyval.stmt) = pnew pgsDeclareRecordStmt(*((yysemantic_stack_[(4) - (1)].str)), driver.context.columns(), + &(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsDeclareRecordStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + driver.context.clear_columns(); + pdelete((yysemantic_stack_[(4) - (1)].str)); + ;} + break; + + case 135: +#line 853 "pgscript/pgsParser.yy" + { + (yyval.stmt) = (yysemantic_stack_[(2) - (2)].stmt_list); + ;} + break; + + case 136: +#line 859 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $1 + (yyval.stmt_list) = driver.context.stmt_list(&(driver.thread)); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(1) - (1)].stmt)); + ;} + break; + + case 137: +#line 865 "pgscript/pgsParser.yy" + { + driver.context.pop_stmt(); // $3 + (yyval.stmt_list) = (yysemantic_stack_[(3) - (1)].stmt_list); + (yyval.stmt_list)->insert_back((yysemantic_stack_[(3) - (3)].stmt)); + ;} + break; + + case 138: +#line 874 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("SET %s = %s"), (yysemantic_stack_[(3) - (1)].str)->c_str(), + (yysemantic_stack_[(3) - (3)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssign(*((yysemantic_stack_[(3) - (1)].str)), (yysemantic_stack_[(3) - (3)].expr)), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(3) - (1)].str)); + ;} + break; + + case 139: +#line 887 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("SET %s[%s][%s] = %s"), + (yysemantic_stack_[(9) - (1)].str)->c_str(), (yysemantic_stack_[(9) - (3)].expr)->value().c_str(), + (yysemantic_stack_[(9) - (6)].expr)->value().c_str(), (yysemantic_stack_[(9) - (9)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssignToRecord(*((yysemantic_stack_[(9) - (1)].str)), + (yysemantic_stack_[(9) - (3)].expr), (yysemantic_stack_[(9) - (6)].expr), (yysemantic_stack_[(9) - (9)].expr)), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); // $3 & $6 & $9 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(9) - (1)].str)); + ;} + break; + + case 140: +#line 902 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("SET %s = %s"), (yysemantic_stack_[(3) - (1)].str)->c_str(), + (yysemantic_stack_[(3) - (3)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsAssign(*((yysemantic_stack_[(3) - (1)].str)), (yysemantic_stack_[(3) - (3)].expr)), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(3) - (1)].str)); + ;} + break; + + case 141: +#line 918 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("IF %s"), (yysemantic_stack_[(3) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsIfStmt((yysemantic_stack_[(3) - (2)].expr), (yysemantic_stack_[(3) - (3)].stmt), driver.context + .stmt_list(&(driver.thread)), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // stmt_list + driver.context.push_stmt((yyval.stmt)); // pgsIfStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 142: +#line 930 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("IF %s"), (yysemantic_stack_[(5) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsIfStmt((yysemantic_stack_[(5) - (2)].expr), (yysemantic_stack_[(5) - (3)].stmt), (yysemantic_stack_[(5) - (5)].stmt), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // $5 + driver.context.push_stmt((yyval.stmt)); // pgsIfStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 143: +#line 944 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("WHILE %s"), (yysemantic_stack_[(3) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsWhileStmt((yysemantic_stack_[(3) - (2)].expr), (yysemantic_stack_[(3) - (3)].stmt), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.push_stmt((yyval.stmt)); // pgsWhileStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 144: +#line 956 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("BREAK")); + + (yyval.stmt) = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsBreakStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 145: +#line 963 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("RETURN")); + + (yyval.stmt) = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsBreakStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 146: +#line 970 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("CONTINUE")); + + (yyval.stmt) = pnew pgsContinueStmt(&(driver.thread)); + driver.context.push_stmt((yyval.stmt)); // pgsContinueStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 147: +#line 981 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("PRINT %s"), (yysemantic_stack_[(2) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsPrintStmt((yysemantic_stack_[(2) - (2)].expr), driver.context.m_cout, + &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt((yyval.stmt)); // pgsPrintStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 148: +#line 991 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("ASSERT %s"), (yysemantic_stack_[(2) - (2)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsAssertStmt((yysemantic_stack_[(2) - (2)].expr), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt((yyval.stmt)); // pgsAssertStmt + (yyval.stmt)->set_position(yyloc.begin.line); + ;} + break; + + case 149: +#line 1000 "pgscript/pgsParser.yy" + { + wxLogScriptVerbose(wxT("RMLINE %s[%s]"), (yysemantic_stack_[(7) - (3)].str)->c_str(), + (yysemantic_stack_[(7) - (5)].expr)->value().c_str()); + + (yyval.stmt) = pnew pgsExpressionStmt(pnew pgsRemoveLine(*((yysemantic_stack_[(7) - (3)].str)), (yysemantic_stack_[(7) - (5)].expr)), + &(driver.thread)); + driver.context.pop_var(); // $5 + driver.context.push_stmt((yyval.stmt)); // pgsExpressionStmt + (yyval.stmt)->set_position(yyloc.begin.line); + + pdelete((yysemantic_stack_[(7) - (3)].str)); + ;} + break; + + case 150: +#line 1015 "pgscript/pgsParser.yy" + { + driver.context.add_column(*(yysemantic_stack_[(1) - (1)].str)); + pdelete((yysemantic_stack_[(1) - (1)].str)); + ;} + break; + + case 151: +#line 1020 "pgscript/pgsParser.yy" + { + driver.context.add_column(*(yysemantic_stack_[(3) - (3)].str)); + pdelete((yysemantic_stack_[(3) - (3)].str)); + ;} + break; + + case 153: +#line 1028 "pgscript/pgsParser.yy" + { + driver.program.eval((yysemantic_stack_[(2) - (1)].stmt_list)); + + driver.context.pop_stmt(); + pdelete((yysemantic_stack_[(2) - (1)].stmt_list)); // delete root statement $1 + ;} + break; + + + /* Line 675 of lalr1.cc. */ +#line 1866 "pgscript/parser.tab.cc" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); + + yypop_ (yylen); + yylen = 0; + YY_STACK_PRINT (); + + yysemantic_stack_.push (yyval); + yylocation_stack_.push (yyloc); + + /* Shift the result of the reduction. */ + yyn = yyr1_[yyn]; + yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; + if (0 <= yystate && yystate <= yylast_ + && yycheck_[yystate] == yystate_stack_[0]) + yystate = yytable_[yystate]; + else + yystate = yydefgoto_[yyn - yyntokens_]; + goto yynewstate; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus_) + { + ++yynerrs_; + error (yylloc, yysyntax_error_ (yystate, yytoken)); + } + + yyerror_range[0] = yylloc; + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= yyeof_) + { + /* Return failure if at end of input. */ + if (yychar == yyeof_) + YYABORT; + } + else + { + yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); + yychar = yyempty_; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + + /*---------------------------------------------------. + | yyerrorlab -- error raised explicitly by YYERROR. | + `---------------------------------------------------*/ + yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (false) + goto yyerrorlab; + + yyerror_range[0] = yylocation_stack_[yylen - 1]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yypop_ (yylen); + yylen = 0; + yystate = yystate_stack_[0]; + goto yyerrlab1; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: + yyerrstatus_ = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact_[yystate]; + if (yyn != yypact_ninf_) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yystate_stack_.height () == 1) + YYABORT; + + yyerror_range[0] = yylocation_stack_[0]; + yydestruct_ ("Error: popping", + yystos_[yystate], + &yysemantic_stack_[0], &yylocation_stack_[0]); + yypop_ (); + yystate = yystate_stack_[0]; + YY_STACK_PRINT (); + } + + if (yyn == yyfinal_) + goto yyacceptlab; + + yyerror_range[1] = yylloc; + // Using YYLLOC is tempting, but would change the location of + // the look-ahead. YYLOC is available though. + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yyloc); + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], + &yysemantic_stack_[0], &yylocation_stack_[0]); + + yystate = yyn; + goto yynewstate; + + /* Accept. */ + yyacceptlab: + yyresult = 0; + goto yyreturn; + + /* Abort. */ + yyabortlab: + yyresult = 1; + goto yyreturn; + + yyreturn: + if (yychar != yyeof_ && yychar != yyempty_) + yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + yypop_ (yylen); + while (yystate_stack_.height () != 1) + { + yydestruct_ ("Cleanup: popping", + yystos_[yystate_stack_[0]], + &yysemantic_stack_[0], + &yylocation_stack_[0]); + yypop_ (); + } + + return yyresult; + } + + // Generate an error message. + std::string + pgsParser::yysyntax_error_ (int yystate, int tok) + { + std::string res; + YYUSE (yystate); +#if YYERROR_VERBOSE + int yyn = yypact_[yystate]; + if (yypact_ninf_ < yyn && yyn <= yylast_) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + int count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + ++count; + + // FIXME: This method of building the message is not compatible + // with internationalization. It should work like yacc.c does it. + // That is, first build a string that looks like this: + // "syntax error, unexpected %s or %s or %s" + // Then, invoke YY_ on this string. + // Finally, use the string as a format to output + // yytname_[tok], etc. + // Until this gets fixed, this message appears in English only. + res = "syntax error, unexpected "; + res += yytnamerr_ (yytname_[tok]); + if (count < 5) + { + count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + { + res += (!count++) ? ", expecting " : " or "; + res += yytnamerr_ (yytname_[x]); + } + } + } + else +#endif + res = YY_("syntax error"); + return res; + } + + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + const signed char pgsParser::yypact_ninf_ = -93; + const short int + pgsParser::yypact_[] = + { + 284, -93, 6, -93, -93, -93, 6, 453, 6, 6, + -88, -76, -61, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, -93, -93, + -93, -93, -93, -93, -93, -93, -93, -93, 370, -93, + -65, -93, -93, -56, -45, -93, -93, -44, -28, 73, + 12, 13, 23, 27, 37, 42, 44, 50, 63, 65, + 66, 67, 68, 6, 0, -93, -93, -93, -11, 6, + 6, -93, -93, -93, 51, -74, 7, 117, 120, 124, + 619, -93, 619, -93, 536, -93, -93, 76, -25, 62, + -93, 61, 69, -93, -93, -93, -93, -93, -93, -93, + -93, -93, 79, 80, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, -93, 6, 74, 75, -93, + -93, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, -93, 161, -93, 81, 689, + 6, -76, 86, -61, 82, 83, 84, 163, 77, 78, + 85, -53, -52, 87, 89, 90, 91, 92, -93, -93, + -93, -93, -93, 51, 51, -74, -74, -74, -74, 7, + 7, 7, 117, 120, 619, 6, -93, -93, 93, -93, + -93, 34, -93, -93, -93, -93, 64, 6, 6, 6, + -93, 6, -93, 6, 6, 6, 6, 6, 95, -93, + 96, 103, 88, -93, -93, -93, -93, -93, 101, -51, + 94, -42, 104, -38, -37, -31, -22, -21, 6, 105, + 6, -93, -93, -93, 6, 6, -93, 6, -93, -93, + 6, -93, 6, -93, 6, -93, 6, -93, 6, 108, + -93, 109, -4, -2, 9, 10, 15, 16, 38, 39, + -93, 147, -93, 6, -93, 6, -93, 6, -93, 6, + -93, 6, -93, 6, -93, 6, -93, 6, 6, 111, + 40, 113, 119, 121, 122, 123, 125, -93, -93, -93, + 6, -93, -93, -93, -93, -93, -93, 126, -93 + }; + + /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ + const unsigned char + pgsParser::yydefact_[] = + { + 0, 152, 0, 144, 145, 146, 0, 0, 0, 0, + 0, 0, 0, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 80, 0, 72, + 0, 84, 85, 0, 0, 73, 74, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 8, 9, 10, 0, 0, + 0, 14, 18, 24, 28, 31, 36, 40, 42, 44, + 0, 12, 0, 82, 0, 148, 147, 0, 0, 135, + 136, 133, 130, 131, 153, 81, 75, 78, 79, 77, + 76, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 17, 0, 0, 0, 15, + 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 143, 141, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 11, 13, + 25, 26, 27, 29, 30, 34, 35, 32, 33, 37, + 38, 39, 41, 43, 0, 0, 138, 140, 0, 137, + 150, 0, 132, 5, 4, 6, 0, 0, 0, 0, + 54, 0, 56, 0, 0, 0, 0, 0, 3, 142, + 0, 0, 0, 134, 23, 20, 21, 22, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 151, 19, 45, 0, 0, 51, 0, 55, 57, + 0, 60, 0, 63, 0, 66, 0, 69, 0, 0, + 149, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 46, 0, 48, 0, 52, 0, 58, 0, + 61, 0, 64, 0, 67, 0, 70, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 139, 47, 49, + 0, 53, 59, 62, 65, 68, 71, 0, 50 + }; + + /* YYPGOTO[NTERM-NUM]. */ + const short int + pgsParser::yypgoto_[] = + { + -93, -93, -93, -29, -93, -92, -3, -83, 28, 59, + -93, -6, -93, -57, 175, -93, -93, 58, -93, -93, + -93, 33, -93, -93, 60, -93, -93, -93, -93, -93, + -93 + }; + + /* YYDEFGOTO[NTERM-NUM]. */ + const short int + pgsParser::yydefgoto_[] = + { + -1, 91, 92, 93, 228, 94, 95, 96, 97, 98, + 99, 100, 101, 57, 58, 59, 60, 61, 62, 63, + 112, 113, 64, 109, 110, 65, 66, 67, 68, 201, + 69 + }; + + /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. */ + const signed char pgsParser::yytable_ninf_ = -1; + const unsigned short int + pgsParser::yytable_[] = + { + 102, 115, 105, 106, 107, 70, 71, 72, 159, 73, + 108, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 144, 145, 70, 71, 72, 111, 73, 83, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 116, 146, 147, + 210, 212, 243, 155, 83, 156, 117, 115, 211, 213, + 244, 246, 183, 184, 135, 249, 251, 118, 119, 247, + 139, 140, 253, 250, 252, 160, 137, 189, 190, 191, + 254, 255, 257, 121, 120, 84, 85, 86, 87, 256, + 258, 88, 138, 89, 90, 224, 225, 226, 227, 272, + 136, 274, 84, 85, 86, 87, 167, 273, 88, 275, + 89, 90, 276, 278, 122, 123, 148, 149, 280, 282, + 277, 279, 180, 181, 182, 124, 281, 283, 166, 125, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 126, + 177, 284, 286, 299, 127, 222, 128, 219, 223, 285, + 287, 300, 129, 185, 186, 187, 188, 141, 142, 143, + 150, 151, 152, 196, 198, 130, 153, 131, 132, 133, + 134, 154, 158, 161, 162, 164, 165, 178, 179, 194, + 163, 195, 200, 206, 241, 203, 204, 205, 207, 208, + 288, 192, 104, 218, 221, 238, 209, 239, 214, 220, + 215, 216, 217, 240, 242, 245, 202, 248, 260, 270, + 271, 229, 230, 231, 298, 232, 301, 233, 234, 235, + 236, 237, 302, 193, 303, 304, 305, 197, 306, 308, + 0, 199, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 261, 0, 0, 0, 262, 263, + 0, 264, 0, 0, 265, 0, 266, 0, 267, 0, + 268, 0, 269, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 289, 0, 290, + 0, 291, 0, 292, 0, 293, 0, 294, 0, 295, + 0, 296, 297, 0, 1, 0, 0, 2, 3, 4, + 5, 6, 0, 0, 307, 7, 0, 8, 9, 0, + 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 114, 0, 0, 2, 3, 4, 5, 6, 0, 0, + 0, 7, 0, 8, 9, 0, 0, 0, 0, 10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 2, 3, 4, 5, + 6, 0, 0, 0, 7, 103, 8, 9, 0, 0, + 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 2, + 3, 4, 5, 6, 0, 0, 0, 7, 157, 8, + 9, 0, 0, 0, 0, 10, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 2, 3, 4, 5, 6, 0, 0, 0, + 7, 0, 8, 9, 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 70, 71, 72, 0, 73, + 0, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, + 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 84, 85, 86, 87, 0, + 0, 88, 0, 89, 90 + }; + + /* YYCHECK. */ + const short int + pgsParser::yycheck_[] = + { + 6, 58, 8, 9, 92, 16, 17, 18, 33, 20, + 86, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 94, 95, 16, 17, 18, 86, 20, 38, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 102, 31, 32, + 93, 93, 93, 100, 38, 102, 102, 104, 101, 101, + 101, 93, 144, 145, 83, 93, 93, 102, 102, 101, + 89, 90, 93, 101, 101, 90, 77, 150, 151, 152, + 101, 93, 93, 0, 102, 86, 87, 88, 89, 101, + 101, 92, 88, 94, 95, 21, 22, 23, 24, 93, + 90, 93, 86, 87, 88, 89, 125, 101, 92, 101, + 94, 95, 93, 93, 92, 92, 99, 100, 93, 93, + 101, 101, 141, 142, 143, 92, 101, 101, 124, 92, + 126, 127, 128, 129, 130, 131, 132, 133, 134, 92, + 136, 93, 93, 93, 92, 101, 92, 194, 104, 101, + 101, 101, 92, 146, 147, 148, 149, 96, 97, 98, + 33, 34, 35, 159, 160, 92, 36, 92, 92, 92, + 92, 37, 86, 101, 103, 86, 86, 93, 93, 8, + 101, 90, 86, 10, 86, 93, 93, 93, 101, 101, + 33, 153, 7, 91, 91, 90, 101, 91, 101, 195, + 101, 101, 101, 90, 93, 101, 163, 93, 93, 91, + 91, 207, 208, 209, 93, 211, 93, 213, 214, 215, + 216, 217, 93, 154, 93, 93, 93, 159, 93, 93, + -1, 161, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 238, -1, 240, -1, -1, -1, 244, 245, + -1, 247, -1, -1, 250, -1, 252, -1, 254, -1, + 256, -1, 258, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 273, -1, 275, + -1, 277, -1, 279, -1, 281, -1, 283, -1, 285, + -1, 287, 288, -1, 0, -1, -1, 3, 4, 5, + 6, 7, -1, -1, 300, 11, -1, 13, 14, -1, + -1, -1, -1, 19, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 0, -1, -1, 3, 4, 5, 6, 7, -1, -1, + -1, 11, -1, 13, 14, -1, -1, -1, -1, 19, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 3, 4, 5, 6, + 7, -1, -1, -1, 11, 12, 13, 14, -1, -1, + -1, -1, 19, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 3, + 4, 5, 6, 7, -1, -1, -1, 11, 12, 13, + 14, -1, -1, -1, -1, 19, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 3, 4, 5, 6, 7, -1, -1, -1, + 11, -1, 13, 14, -1, -1, -1, -1, 19, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 16, 17, 18, -1, 20, + -1, 22, 23, 24, 25, 26, 27, 28, 29, 30, + -1, -1, -1, -1, -1, -1, -1, 38, -1, -1, + -1, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, -1, + -1, 92, -1, 94, 95 + }; + + /* STOS_[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ + const unsigned char + pgsParser::yystos_[] = + { + 0, 0, 3, 4, 5, 6, 7, 11, 13, 14, + 19, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 118, 119, 120, + 121, 122, 123, 124, 127, 130, 131, 132, 133, 135, + 16, 17, 18, 20, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 38, 86, 87, 88, 89, 92, 94, + 95, 106, 107, 108, 110, 111, 112, 113, 114, 115, + 116, 117, 116, 12, 119, 116, 116, 92, 86, 128, + 129, 86, 125, 126, 0, 118, 102, 102, 102, 102, + 102, 0, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 108, 90, 77, 116, 108, + 108, 96, 97, 98, 94, 95, 31, 32, 99, 100, + 33, 34, 35, 36, 37, 118, 118, 12, 86, 33, + 90, 101, 103, 101, 86, 86, 116, 108, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 93, 93, + 108, 108, 108, 110, 110, 111, 111, 111, 111, 112, + 112, 112, 113, 114, 8, 90, 116, 122, 116, 129, + 86, 134, 126, 93, 93, 93, 10, 101, 101, 101, + 93, 101, 93, 101, 101, 101, 101, 101, 91, 118, + 116, 91, 101, 104, 21, 22, 23, 24, 109, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 90, 91, + 90, 86, 93, 93, 101, 101, 93, 101, 93, 93, + 101, 93, 101, 93, 101, 93, 101, 93, 101, 116, + 93, 116, 116, 116, 116, 116, 116, 116, 116, 116, + 91, 91, 93, 101, 93, 101, 93, 101, 93, 101, + 93, 101, 93, 101, 93, 101, 93, 101, 33, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 93, 93, + 101, 93, 93, 93, 93, 93, 93, 116, 93 + }; + +#if YYDEBUG + /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding + to YYLEX-NUM. */ + const unsigned short int + pgsParser::yytoken_number_[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 91, 93, 40, 41, 43, 45, 42, 47, 37, 60, + 62, 44, 59, 123, 125 + }; +#endif + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ + const unsigned char + pgsParser::yyr1_[] = + { + 0, 105, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 107, 107, 107, 107, 108, 108, + 109, 109, 109, 109, 110, 110, 110, 110, 111, 111, + 111, 112, 112, 112, 112, 112, 113, 113, 113, 113, + 114, 114, 115, 115, 116, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 118, 118, 118, 118, 118, 118, 118, 118, + 119, 119, 120, 120, 121, 122, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 124, 125, 125, 126, 126, 127, 128, 128, 129, 129, + 129, 130, 130, 131, 132, 132, 132, 133, 133, 133, + 134, 134, 135, 135 + }; + + /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ + const unsigned char + pgsParser::yyr2_[] = + { + 0, 2, 7, 4, 4, 4, 4, 1, 1, 1, + 1, 3, 1, 3, 1, 2, 2, 2, 1, 6, + 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, + 3, 1, 3, 3, 3, 3, 1, 3, 3, 3, + 1, 3, 1, 3, 1, 6, 8, 10, 8, 10, + 12, 6, 8, 10, 4, 6, 4, 6, 8, 10, + 6, 8, 10, 6, 8, 10, 6, 8, 10, 6, + 8, 10, 1, 1, 1, 2, 2, 2, 2, 2, + 1, 2, 2, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 3, 1, 4, 2, 1, 3, 3, 9, + 3, 3, 5, 3, 1, 1, 1, 2, 2, 7, + 1, 3, 1, 2 + }; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a yyntokens_, nonterminals. */ + const char* + const pgsParser::yytname_[] = + { + "\"END OF FILE\"", "error", "$undefined", "\"WHILE\"", "\"BREAK\"", + "\"RETURN\"", "\"CONTINUE\"", "\"IF\"", "\"ELSE\"", "\"WAITFOR\"", + "\"AS\"", "\"BEGIN (BLOCK)\"", "\"END (BLOCK)\"", "\"ASSERT\"", + "\"PRINT\"", "\"LOG\"", "\"COLUMNS\"", "\"LINES\"", "\"TRIM\"", + "\"RMLINE\"", "\"CAST\"", "\"RECORD\"", "\"INTEGER\"", "\"REAL\"", + "\"STRING\"", "\"REGEX\"", "\"FILE\"", "\"DATE\"", "\"TIME\"", + "\"DATETIME\"", "\"REFERENCE\"", "\"<=\"", "\">=\"", "\"=\"", "\"~=\"", + "\"<>\"", "\"AND\"", "\"OR\"", "\"NOT\"", "\"character\"", + "\"SET @VARIABLE\"", "\"DECLARE @VARIABLE\"", "\"ABORT\"", "\"ALTER\"", + "\"ANALYZE\"", "\"BEGIN\"", "\"CHECKPOINT\"", "\"CLOSE\"", "\"CLUSTER\"", + "\"COMMENT\"", "\"COMMIT\"", "\"COPY\"", "\"CREATE\"", "\"DEALLOCATE\"", + "\"DECLARE\"", "\"DELETE\"", "\"DISCARD\"", "\"DROP\"", "\"END\"", + "\"EXECUTE\"", "\"EXPLAIN\"", "\"FETCH\"", "\"GRANT\"", "\"INSERT\"", + "\"LISTEN\"", "\"LOAD\"", "\"LOCK\"", "\"MOVE\"", "\"NOTIFY\"", + "\"PREPARE\"", "\"REASSIGN\"", "\"REINDEX\"", "\"RELEASE\"", "\"RESET\"", + "\"REVOKE\"", "\"ROLLBACK\"", "\"SAVEPOINT\"", "\"SELECT\"", "\"SET\"", + "\"SHOW\"", "\"START\"", "\"TRUNCATE\"", "\"UNLISTEN\"", "\"UPDATE\"", + "\"VACUUM\"", "\"VALUES\"", "\"IDENTIFIER\"", "\"INTEGER VALUE\"", + "\"REAL VALUE\"", "\"STRING VALUE\"", "'['", "']'", "'('", "')'", "'+'", + "'-'", "'*'", "'/'", "'%'", "'<'", "'>'", "','", "';'", "'{'", "'}'", + "$accept", "postfix_expression", "unary_expression", "cast_expression", + "type_name", "multiplicative_expression", "additive_expression", + "relational_expression", "equality_expression", "logical_and_expression", + "logical_or_expression", "expression", "random_generator", "statement", + "statement_list", "compound_statement", "sql_statement", + "sql_expression", "sql_query", "declaration_statement", + "declaration_list", "declaration_element", "assign_statement", + "assign_list", "assign_element", "selection_statement", + "iteration_statement", "jump_statement", "procedure_statement", + "record_declaration_list", "translation_unit", 0 + }; +#endif + +#if YYDEBUG + /* YYRHS -- A `-1'-separated list of the rules' RHS. */ + const pgsParser::rhs_number_type + pgsParser::yyrhs_[] = + { + 135, 0, -1, 86, 90, 116, 91, 90, 116, 91, + -1, 86, 90, 116, 91, -1, 17, 92, 86, 93, + -1, 16, 92, 86, 93, -1, 18, 92, 116, 93, + -1, 86, -1, 87, -1, 88, -1, 89, -1, 92, + 77, 93, -1, 117, -1, 92, 116, 93, -1, 106, + -1, 94, 108, -1, 95, 108, -1, 38, 108, -1, + 107, -1, 20, 92, 108, 10, 109, 93, -1, 22, + -1, 23, -1, 24, -1, 21, -1, 108, -1, 110, + 96, 108, -1, 110, 97, 108, -1, 110, 98, 108, + -1, 110, -1, 111, 94, 110, -1, 111, 95, 110, + -1, 111, -1, 112, 99, 111, -1, 112, 100, 111, + -1, 112, 31, 111, -1, 112, 32, 111, -1, 112, + -1, 113, 33, 112, -1, 113, 34, 112, -1, 113, + 35, 112, -1, 113, -1, 114, 36, 113, -1, 114, + -1, 115, 37, 114, -1, 115, -1, 22, 92, 116, + 101, 116, 93, -1, 22, 92, 116, 101, 116, 101, + 116, 93, -1, 22, 92, 116, 101, 116, 101, 116, + 101, 116, 93, -1, 23, 92, 116, 101, 116, 101, + 116, 93, -1, 23, 92, 116, 101, 116, 101, 116, + 101, 116, 93, -1, 23, 92, 116, 101, 116, 101, + 116, 101, 116, 101, 116, 93, -1, 24, 92, 116, + 101, 116, 93, -1, 24, 92, 116, 101, 116, 101, + 116, 93, -1, 24, 92, 116, 101, 116, 101, 116, + 101, 116, 93, -1, 25, 92, 116, 93, -1, 25, + 92, 116, 101, 116, 93, -1, 26, 92, 116, 93, + -1, 26, 92, 116, 101, 116, 93, -1, 26, 92, + 116, 101, 116, 101, 116, 93, -1, 26, 92, 116, + 101, 116, 101, 116, 101, 116, 93, -1, 27, 92, + 116, 101, 116, 93, -1, 27, 92, 116, 101, 116, + 101, 116, 93, -1, 27, 92, 116, 101, 116, 101, + 116, 101, 116, 93, -1, 28, 92, 116, 101, 116, + 93, -1, 28, 92, 116, 101, 116, 101, 116, 93, + -1, 28, 92, 116, 101, 116, 101, 116, 101, 116, + 93, -1, 29, 92, 116, 101, 116, 93, -1, 29, + 92, 116, 101, 116, 101, 116, 93, -1, 29, 92, + 116, 101, 116, 101, 116, 101, 116, 93, -1, 30, + 92, 116, 101, 116, 93, -1, 30, 92, 116, 101, + 116, 101, 116, 93, -1, 30, 92, 116, 101, 116, + 101, 116, 101, 116, 93, -1, 120, -1, 130, -1, + 131, -1, 121, 102, -1, 133, 102, -1, 132, 102, + -1, 124, 102, -1, 127, 102, -1, 118, -1, 119, + 118, -1, 11, 12, -1, 11, 119, 12, -1, 122, + -1, 123, -1, 42, -1, 43, -1, 44, -1, 45, + -1, 46, -1, 47, -1, 48, -1, 49, -1, 50, + -1, 51, -1, 52, -1, 53, -1, 54, -1, 55, + -1, 56, -1, 57, -1, 58, -1, 59, -1, 60, + -1, 61, -1, 62, -1, 63, -1, 64, -1, 65, + -1, 66, -1, 67, -1, 68, -1, 69, -1, 70, + -1, 71, -1, 72, -1, 73, -1, 74, -1, 75, + -1, 76, -1, 77, -1, 78, -1, 79, -1, 80, + -1, 81, -1, 82, -1, 83, -1, 84, -1, 85, + -1, 41, 125, -1, 126, -1, 125, 101, 126, -1, + 86, -1, 86, 103, 134, 104, -1, 40, 128, -1, + 129, -1, 128, 101, 129, -1, 86, 33, 116, -1, + 86, 90, 116, 91, 90, 116, 91, 33, 116, -1, + 86, 33, 122, -1, 7, 116, 118, -1, 7, 116, + 118, 8, 118, -1, 3, 116, 118, -1, 4, -1, + 5, -1, 6, -1, 14, 116, -1, 13, 116, -1, + 19, 92, 86, 90, 116, 91, 93, -1, 86, -1, + 134, 101, 86, -1, 0, -1, 119, 0, -1 + }; + + /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ + const unsigned short int + pgsParser::yyprhs_[] = + { + 0, 0, 3, 11, 16, 21, 26, 31, 33, 35, + 37, 39, 43, 45, 49, 51, 54, 57, 60, 62, + 69, 71, 73, 75, 77, 79, 83, 87, 91, 93, + 97, 101, 103, 107, 111, 115, 119, 121, 125, 129, + 133, 135, 139, 141, 145, 147, 154, 163, 174, 183, + 194, 207, 214, 223, 234, 239, 246, 251, 258, 267, + 278, 285, 294, 305, 312, 321, 332, 339, 348, 359, + 366, 375, 386, 388, 390, 392, 395, 398, 401, 404, + 407, 409, 412, 415, 419, 421, 423, 425, 427, 429, + 431, 433, 435, 437, 439, 441, 443, 445, 447, 449, + 451, 453, 455, 457, 459, 461, 463, 465, 467, 469, + 471, 473, 475, 477, 479, 481, 483, 485, 487, 489, + 491, 493, 495, 497, 499, 501, 503, 505, 507, 509, + 511, 514, 516, 520, 522, 527, 530, 532, 536, 540, + 550, 554, 558, 564, 568, 570, 572, 574, 577, 580, + 588, 590, 594, 596 + }; + + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + const unsigned short int + pgsParser::yyrline_[] = + { + 0, 267, 267, 274, 281, 287, 293, 299, 305, 311, + 317, 323, 329, 330, 338, 339, 340, 345, 354, 355, + 364, 365, 366, 367, 371, 372, 379, 386, 396, 397, + 404, 414, 415, 422, 429, 436, 446, 447, 454, 461, + 471, 472, 482, 483, 493, 500, 508, 515, 522, 531, + 539, 547, 555, 562, 569, 575, 581, 589, 597, 604, + 611, 619, 626, 633, 641, 648, 655, 663, 670, 677, + 685, 693, 703, 704, 705, 706, 707, 708, 709, 710, + 714, 719, 727, 731, 739, 749, 758, 759, 760, 761, + 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, + 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, + 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, + 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, + 805, 812, 818, 827, 837, 852, 859, 864, 873, 886, + 901, 917, 929, 943, 956, 963, 970, 980, 990, 999, + 1015, 1019, 1027, 1028 + }; + + // Print the state stack on the debug stream. + void + pgsParser::yystack_print_ () + { + *yycdebug_ << "Stack now"; + for (state_stack_type::const_iterator i = yystate_stack_.begin (); + i != yystate_stack_.end (); ++i) + *yycdebug_ << ' ' << *i; + *yycdebug_ << std::endl; + } + + // Report on the debug stream that the rule \a yyrule is going to be reduced. + void + pgsParser::yy_reduce_print_ (int yyrule) + { + unsigned int yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + /* Print the symbols being reduced, and their result. */ + *yycdebug_ << "Reducing stack by rule " << yyrule - 1 + << " (line " << yylno << "), "; + /* The symbols being reduced. */ + for (int yyi = 0; yyi < yynrhs; yyi++) + YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", + yyrhs_[yyprhs_[yyrule] + yyi], + &(yysemantic_stack_[(yynrhs) - (yyi + 1)]), + &(yylocation_stack_[(yynrhs) - (yyi + 1)])); + } +#endif // YYDEBUG + + /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + pgsParser::token_number_type + pgsParser::yytranslate_ (int t) + { + static + const token_number_type + translate_table[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 98, 2, 2, + 92, 93, 96, 94, 101, 95, 2, 97, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, + 99, 2, 100, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 90, 2, 91, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 103, 2, 104, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89 + }; + if ((unsigned int) t <= yyuser_token_number_max_) + return translate_table[t]; + else + return yyundef_token_; + } + + const int pgsParser::yyeof_ = 0; + const int pgsParser::yylast_ = 784; + const int pgsParser::yynnts_ = 31; + const int pgsParser::yyempty_ = -2; + const int pgsParser::yyfinal_ = 121; + const int pgsParser::yyterror_ = 1; + const int pgsParser::yyerrcode_ = 256; + const int pgsParser::yyntokens_ = 105; + + const unsigned int pgsParser::yyuser_token_number_max_ = 344; + const pgsParser::token_number_type pgsParser::yyundef_token_ = 2; + +} // namespace pgscript + +#line 1036 "pgscript/pgsParser.yy" + /*** Additional Code ***/ + +void pgscript::pgsParser::error(const pgsParser::location_type & l, + const std::string & m) +{ + wxLogScriptVerbose(wxT("EXPR STACK SIZE = %u"), driver.context.size_vars()); + wxLogScriptVerbose(wxT("STMT STACK SIZE = %u"), driver.context.size_stmts()); + driver.context.clear_stacks(); + driver.error(l, wxString(m.c_str(), wxConvUTF8)); +} + diff --git a/pgscript/pgsApplication.cpp b/pgscript/pgsApplication.cpp new file mode 100644 index 0000000..6d2a615 --- /dev/null +++ b/pgscript/pgsApplication.cpp @@ -0,0 +1,215 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/pgsApplication.h" + +#include "db/pgConn.h" +#include "pgscript/expressions/pgsAssign.h" +#include "pgscript/expressions/pgsIdent.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/utilities/pgsThread.h" + +pgsApplication::pgsApplication(const wxString &host, const wxString &database, + const wxString &user, const wxString &password, int port) : + m_mutex(1, 1), m_stream(1, 1), m_connection(pnew pgConn(host, wxEmptyString, wxEmptyString, database, user, + password, port)), m_defined_conn(true), m_thread(0), m_caller(0) +{ + if (m_connection->GetStatus() != PGCONN_OK) + { + wxLogError(wxT("PGSCRIPT: Cannot connect to database %s:%d/%s with ") + wxT("credentials '%s'/'%s'"), host.c_str(), port, database.c_str(), + user.c_str(), password.c_str()); + } + + wxLogScript(wxT("Application created")); +} + +pgsApplication::pgsApplication(pgConn *connection) : + m_mutex(1, 1), m_stream(1, 1), m_connection(connection), + m_defined_conn(false), m_thread(0), m_caller(0) +{ + wxLogScript(wxT("Application created")); +} + +pgsApplication::~pgsApplication() +{ + if (m_defined_conn) + { + pdelete(m_connection); + } + + wxLogScript(wxT("Application destroyed")); +} + +bool pgsApplication::ParseFile(const wxString &file, pgsOutputStream &out, + wxMBConv *conv) +{ + if (!IsRunning()) + { + m_last_error_line = -1; + m_thread = new pgsThread(m_vars, m_mutex, m_connection, + file, out, *this, conv); + return RunThread(); + } + else + { + return false; + } +} + +bool pgsApplication::ParseString(const wxString &string, + pgsOutputStream &out) +{ + if (!IsRunning()) + { + m_last_error_line = -1; + m_thread = new pgsThread(m_vars, m_mutex, m_connection, + string, out, *this); + return RunThread(); + } + else + { + return false; + } +} + +bool pgsApplication::RunThread() +{ + bool created = false; + + if (m_thread != 0 && m_thread->Create() == wxTHREAD_NO_ERROR) + { + m_thread->SetPriority(WXTHREAD_MIN_PRIORITY); + + if (m_thread->Run() == wxTHREAD_NO_ERROR) + { + created = true; + } + } + + if (created) + { + wxLogScript(wxT("Running...")); + return true; + } + else + { + wxLogError(wxT("PGSCRIPT: Thread error")); + pdelete(m_thread); + return false; + } +} + +bool pgsApplication::IsRunning() +{ + if (m_mutex.TryWait() == wxSEMA_NO_ERROR) + { + m_mutex.Post(); + return false; + } + else + { + return true; + } +} + +void pgsApplication::Wait() +{ + if (IsRunning()) + { + wxLogScript(wxT("Waiting for pgScript")); + m_mutex.Wait(); + m_mutex.Post(); + } +} + +void pgsApplication::Terminate() +{ + if (IsRunning()) + { + wxLogScript(wxT("Deleting pgScript")); + m_thread->Delete(); + } +} + +void pgsApplication::Complete() +{ + // If last_error_line() == -1 then there was no error + // Else get the line number where the error occurred + m_last_error_line = m_thread->last_error_line(); + +#if !defined(PGSCLI) + if (m_caller != 0) + { + wxCommandEvent resultEvent(wxEVT_COMMAND_MENU_SELECTED, m_event_id); + +#if wxCHECK_VERSION(2, 9, 0) + m_caller->GetEventHandler()->AddPendingEvent(resultEvent); +#else + m_caller->AddPendingEvent(resultEvent); +#endif + } +#endif // PGSCLI + + wxLogScript(wxT("Execution completed")); +} + +void pgsApplication::SetConnection(pgConn *conn) +{ + if (m_defined_conn) + { + pdelete(m_connection); + m_defined_conn = false; + } + + m_connection = conn; +} + +void pgsApplication::ClearSymbols() +{ + if (!IsRunning()) + { + m_vars.clear(); + } +} + +#if !defined(PGSCLI) +void pgsApplication::SetCaller(wxWindow *caller, long event_id) +{ + m_caller = caller; + m_event_id = event_id; +} +#endif // PGSCLI + +bool pgsApplication::IsConnectionValid() const +{ + return (m_connection->GetStatus() == PGCONN_OK); +} + +void pgsApplication::LockOutput() +{ + m_stream.Wait(); +} + +void pgsApplication::UnlockOutput() +{ + m_stream.Post(); +} + +bool pgsApplication::errorOccurred() const +{ + return (m_last_error_line != -1); +} + +int pgsApplication::errorLine() const +{ + return m_last_error_line; +} diff --git a/pgscript/pgsParser.yy b/pgscript/pgsParser.yy new file mode 100644 index 0000000..15e0391 --- /dev/null +++ b/pgscript/pgsParser.yy @@ -0,0 +1,1045 @@ +%{ /*** C/C++ Declarations ***/ + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/statements/pgsStatements.h" +#include "pgscript/expressions/pgsExpressions.h" +#include "pgscript/objects/pgsObjects.h" +#include "pgscript/utilities/pgsContext.h" + +%} + +/*** YACC/Bison declarations ***/ + +/* Require bison 2.3 or later */ +%require "2.3" + +/* Start symbol is named "start" */ +%start translation_unit + +/* Write out a header file containing the token defines */ +%defines + +/* Use newer C++ skeleton file */ +%skeleton "lalr1.cc" + +/* Namespace to enclose parser in */ +%name-prefix="pgscript" + +/* Set the parser's class identifier */ +%define "parser_class_name" "pgsParser" + +/* Keep track of the current position within the input */ +%locations +%initial-action +{ + // Initialize the initial location object + @$.begin.filename = @$.end.filename; +}; + +/* The driver is passed by reference to the parser and to the scanner. This + * provides a simple but effective pure interface, not relying on global + * variables. */ +%parse-param { class pgsDriver & driver } + +/* Verbose error messages */ +%error-verbose + +%token PGS_END 0 "END OF FILE" + +%token PGS_WHILE "WHILE" +%token PGS_BREAK "BREAK" +%token PGS_RETURN "RETURN" +%token PGS_CONTINUE "CONTINUE" +%token PGS_IF "IF" +%token PGS_ELSE "ELSE" +%token PGS_WAITFOR "WAITFOR" +%token PGS_AS "AS" + +%token PGS_OPEN "BEGIN (BLOCK)" +%token PGS_CLOSE "END (BLOCK)" + +%token PGS_ASSERT "ASSERT" +%token PGS_PRINT "PRINT" +%token PGS_LOG "LOG" + +%token PGS_CNT_COLUMNS "COLUMNS" +%token PGS_CNT_LINES "LINES" +%token PGS_TRIM "TRIM" +%token PGS_RM_LINE "RMLINE" +%token PGS_CAST "CAST" + +%token PGS_RECORD "RECORD" + +%token PGS_INTEGER "INTEGER" +%token PGS_REAL "REAL" +%token PGS_STRING "STRING" +%token PGS_REGEX "REGEX" +%token PGS_FILE "FILE" +%token PGS_DATE "DATE" +%token PGS_TIME "TIME" +%token PGS_DATE_TIME "DATETIME" +%token PGS_REFERENCE "REFERENCE" + +%token PGS_LE_OP "<=" +%token PGS_GE_OP ">=" +%token PGS_EQ_OP "=" +%token PGS_AE_OP "~=" +%token PGS_NE_OP "<>" +%token PGS_AND_OP "AND" +%token PGS_OR_OP "OR" +%token PGS_NOT_OP "NOT" + +%token PGS_UNKNOWN "character" + +%right PGS_ELSE + +%union +{ + const wxString * str; + int integer; + pgsExpression * expr; + pgsStmt * stmt; + pgsStmtList * stmt_list; +} + +%token PGS_SET_ASSIGN "SET @VARIABLE" +%token PGS_DECLARE_ASSGN "DECLARE @VARIABLE" + +%token PGS_ABORT "ABORT" +%token PGS_ALTER "ALTER" +%token PGS_ANALYZE "ANALYZE" +%token PGS_BEGIN "BEGIN" +%token PGS_CHECKPOINT "CHECKPOINT" +%token PGS_CLOSE_ST "CLOSE" +%token PGS_CLUSTER "CLUSTER" +%token PGS_COMMENT "COMMENT" +%token PGS_COMMIT "COMMIT" +%token PGS_COPY "COPY" +%token PGS_CREATE "CREATE" +%token PGS_DEALLOCATE "DEALLOCATE" +%token PGS_DECLARE "DECLARE" +%token PGS_DELETE "DELETE" +%token PGS_DISCARD "DISCARD" +%token PGS_DROP "DROP" +%token PGS_END_ST "END" +%token PGS_EXECUTE "EXECUTE" +%token PGS_EXPLAIN "EXPLAIN" +%token PGS_FETCH "FETCH" +%token PGS_GRANT "GRANT" +%token PGS_INSERT "INSERT" +%token PGS_LISTEN "LISTEN" +%token PGS_LOAD "LOAD" +%token PGS_LOCK "LOCK" +%token PGS_MOVE "MOVE" +%token PGS_NOTIFY "NOTIFY" +%token PGS_PREPARE "PREPARE" +%token PGS_REASSIGN "REASSIGN" +%token PGS_REINDEX "REINDEX" +%token PGS_RELEASE "RELEASE" +%token PGS_RESET "RESET" +%token PGS_REVOKE "REVOKE" +%token PGS_ROLLBACK "ROLLBACK" +%token PGS_SAVEPOINT "SAVEPOINT" +%token PGS_SELECT "SELECT" +%token PGS_SET "SET" +%token PGS_SHOW "SHOW" +%token PGS_START "START" +%token PGS_TRUNCATE "TRUNCATE" +%token PGS_UNLISTEN "UNLISTEN" +%token PGS_UPDATE "UPDATE" +%token PGS_VACUUM "VACUUM" +%token PGS_VALUES "VALUES" + +%token PGS_IDENTIFIER "IDENTIFIER" +%token PGS_VAL_INT "INTEGER VALUE" +%token PGS_VAL_REAL "REAL VALUE" +%token PGS_VAL_STR "STRING VALUE" + +%destructor { pdelete($$); } PGS_ABORT +%destructor { pdelete($$); } PGS_ALTER +%destructor { pdelete($$); } PGS_ANALYZE +%destructor { pdelete($$); } PGS_BEGIN +%destructor { pdelete($$); } PGS_CHECKPOINT +%destructor { pdelete($$); } PGS_CLOSE_ST +%destructor { pdelete($$); } PGS_CLUSTER +%destructor { pdelete($$); } PGS_COMMENT +%destructor { pdelete($$); } PGS_COMMIT +%destructor { pdelete($$); } PGS_COPY +%destructor { pdelete($$); } PGS_CREATE +%destructor { pdelete($$); } PGS_DEALLOCATE +%destructor { pdelete($$); } PGS_DECLARE +%destructor { pdelete($$); } PGS_DELETE +%destructor { pdelete($$); } PGS_DISCARD +%destructor { pdelete($$); } PGS_DROP +%destructor { pdelete($$); } PGS_END_ST +%destructor { pdelete($$); } PGS_EXECUTE +%destructor { pdelete($$); } PGS_EXPLAIN +%destructor { pdelete($$); } PGS_FETCH +%destructor { pdelete($$); } PGS_GRANT +%destructor { pdelete($$); } PGS_INSERT +%destructor { pdelete($$); } PGS_LISTEN +%destructor { pdelete($$); } PGS_LOAD +%destructor { pdelete($$); } PGS_LOCK +%destructor { pdelete($$); } PGS_MOVE +%destructor { pdelete($$); } PGS_NOTIFY +%destructor { pdelete($$); } PGS_PREPARE +%destructor { pdelete($$); } PGS_REASSIGN +%destructor { pdelete($$); } PGS_REINDEX +%destructor { pdelete($$); } PGS_RELEASE +%destructor { pdelete($$); } PGS_RESET +%destructor { pdelete($$); } PGS_REVOKE +%destructor { pdelete($$); } PGS_ROLLBACK +%destructor { pdelete($$); } PGS_SAVEPOINT +%destructor { pdelete($$); } PGS_SELECT +%destructor { pdelete($$); } PGS_SET +%destructor { pdelete($$); } PGS_SHOW +%destructor { pdelete($$); } PGS_START +%destructor { pdelete($$); } PGS_TRUNCATE +%destructor { pdelete($$); } PGS_UNLISTEN +%destructor { pdelete($$); } PGS_UPDATE +%destructor { pdelete($$); } PGS_VACUUM +%destructor { pdelete($$); } PGS_VALUES + +%destructor { pdelete($$); } PGS_IDENTIFIER +%destructor { pdelete($$); } PGS_VAL_INT +%destructor { pdelete($$); } PGS_VAL_REAL +%destructor { pdelete($$); } PGS_VAL_STR + +%type postfix_expression +%type unary_expression +%type cast_expression +%type multiplicative_expression +%type additive_expression +%type relational_expression +%type equality_expression +%type logical_and_expression +%type logical_or_expression +%type expression +%type random_generator +%type sql_expression + +%type sql_query +%type type_name + +%type statement + +%type compound_statement +%type sql_statement +%type selection_statement +%type iteration_statement +%type procedure_statement +%type jump_statement +%type declaration_statement +%type assign_statement + +%type declaration_list +%type assign_list +%type declaration_element +%type assign_element + +%type statement_list + +%{ + +#include "pgscript/utilities/pgsDriver.h" +#include "pgscript/utilities/pgsScanner.h" + +/* This "connects" the bison parser in the driver to the flex scanner class + * object. It defines the yylex() function call to pull the next token from the + * current lexer object of the driver context. */ +#undef yylex +#define yylex driver.lexer->lex + +%} + +%% /*** Grammar Rules ***/ + +postfix_expression + : PGS_IDENTIFIER '[' expression ']' '[' expression ']' + { + $$ = pnew pgsIdentRecord(*($1), $3, $6); + pdelete($1); + driver.context.pop_var(); driver.context.pop_var(); // $3 & $6 + driver.context.push_var($$); + } + | PGS_IDENTIFIER '[' expression ']' + { + $$ = pnew pgsIdentRecord(*($1), $3); + pdelete($1); + driver.context.pop_var(); // $3 + driver.context.push_var($$); + } + | PGS_CNT_LINES '(' PGS_IDENTIFIER ')' + { + $$ = pnew pgsLines(*($3)); + pdelete($3); + driver.context.push_var($$); + } + | PGS_CNT_COLUMNS '(' PGS_IDENTIFIER ')' + { + $$ = pnew pgsColumns(*($3)); + pdelete($3); + driver.context.push_var($$); + } + | PGS_TRIM '(' expression ')' + { + $$ = pnew pgsTrim($3); + driver.context.pop_var(); // $3 + driver.context.push_var($$); // assert + } + | PGS_IDENTIFIER + { + $$ = pnew pgsIdent(*($1)); + pdelete($1); + driver.context.push_var($$); + } + | PGS_VAL_INT + { + $$ = pnew pgsNumber(*($1), pgsInt); + pdelete($1); + driver.context.push_var($$); + } + | PGS_VAL_REAL + { + $$ = pnew pgsNumber(*($1), pgsReal); + pdelete($1); + driver.context.push_var($$); + } + | PGS_VAL_STR + { + $$ = pnew pgsString(*($1)); + pdelete($1); + driver.context.push_var($$); + } + | '(' PGS_SELECT ')' { + $$ = pnew pgsExecute(*($2), &driver.context.m_cout, + &(driver.thread)); + pdelete($2); + driver.context.push_var($$); // SQL Expression statement + } + | random_generator { $$ = $1; } + | '(' expression ')' { + $$ = pnew pgsParenthesis($2); + driver.context.pop_var(); // $2 + driver.context.push_var($$); + } + ; + +unary_expression + : postfix_expression { $$ = $1; } + | '+' cast_expression { $$ = $2; } + | '-' cast_expression { + $$ = pnew pgsNegate($2); + driver.context.pop_var(); // $2 + driver.context.push_var($$); + } + | PGS_NOT_OP cast_expression + { + $$ = pnew pgsNot($2); + driver.context.pop_var(); // $2 + driver.context.push_var($$); + } + ; + +cast_expression + : unary_expression { $$ = $1; } + | PGS_CAST '(' cast_expression PGS_AS type_name ')' + { + $$ = pnew pgsCast($5, $3); + driver.context.pop_var(); // $3 + driver.context.push_var($$); + } + ; + +type_name + : PGS_INTEGER { $$ = pgscript::pgsParser::token::PGS_INTEGER; } + | PGS_REAL { $$ = pgscript::pgsParser::token::PGS_REAL; } + | PGS_STRING { $$ = pgscript::pgsParser::token::PGS_STRING; } + | PGS_RECORD { $$ = pgscript::pgsParser::token::PGS_RECORD; } + ; + +multiplicative_expression + : cast_expression { $$ = $1; } + | multiplicative_expression '*' cast_expression + { + $$ = pnew pgsTimes($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | multiplicative_expression '/' cast_expression + { + $$ = pnew pgsOver($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | multiplicative_expression '%' cast_expression + { + $$ = pnew pgsModulo($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +additive_expression + : multiplicative_expression { $$ = $1; } + | additive_expression '+' multiplicative_expression + { + $$ = pnew pgsPlus($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | additive_expression '-' multiplicative_expression + { + $$ = pnew pgsMinus($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +relational_expression + : additive_expression { $$ = $1; } + | relational_expression '<' additive_expression + { + $$ = pnew pgsLower($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | relational_expression '>' additive_expression + { + $$ = pnew pgsGreater($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | relational_expression PGS_LE_OP additive_expression + { + $$ = pnew pgsLowerEqual($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | relational_expression PGS_GE_OP additive_expression + { + $$ = pnew pgsGreaterEqual($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +equality_expression + : relational_expression { $$ = $1; } + | equality_expression PGS_EQ_OP relational_expression + { + $$ = pnew pgsEqual($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | equality_expression PGS_AE_OP relational_expression + { + $$ = pnew pgsEqual($1, $3, false); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + | equality_expression PGS_NE_OP relational_expression + { + $$ = pnew pgsDifferent($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +logical_and_expression + : equality_expression { $$ = $1; } + | logical_and_expression PGS_AND_OP equality_expression + { + $$ = pnew pgsAnd($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +logical_or_expression + : logical_and_expression { $$ = $1; } + | logical_or_expression PGS_OR_OP logical_and_expression + { + $$ = pnew pgsOr($1, $3); + driver.context.pop_var(); + driver.context.pop_var(); // $1 & $3 + driver.context.push_var($$); + } + ; + +expression + : logical_or_expression { + wxLogScriptVerbose(wxT("%s"), $1->value().c_str()); + $$ = $1; + } + ; + +random_generator + : PGS_INTEGER '(' expression ',' expression ')' + { + $$ = pnew pgsGenInt($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_INTEGER '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenInt($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_INTEGER '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenInt($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REAL '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReal($3, $5, $7, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REAL '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReal($3, $5, $7, $9, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REAL '(' expression ',' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReal($3, $5, $7, $9, $11); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_STRING '(' expression ',' expression ')' + { + $$ = pnew pgsGenString($3, $5, driver.context.one(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_STRING '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenString($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_STRING '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenString($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REGEX '(' expression ')' + { + $$ = pnew pgsGenRegex($3, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REGEX '(' expression ',' expression ')' + { + $$ = pnew pgsGenRegex($3, $5); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ')' + { + $$ = pnew pgsGenDictionary($3, driver.context.zero(), + driver.context.seed(), driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ',' expression ')' + { + $$ = pnew pgsGenDictionary($3, $5, driver.context.seed(), + driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDictionary($3, $5, $7, driver.context.encoding()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_FILE '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDictionary($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE '(' expression ',' expression ')' + { + $$ = pnew pgsGenDate($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDate($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDate($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_TIME '(' expression ',' expression ')' + { + $$ = pnew pgsGenTime($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_TIME '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenTime($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_TIME '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenTime($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE_TIME '(' expression ',' expression ')' + { + $$ = pnew pgsGenDateTime($3, $5, driver.context.zero(), + driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE_TIME '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDateTime($3, $5, $7, driver.context.seed()); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_DATE_TIME '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenDateTime($3, $5, $7, $9); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REFERENCE '(' expression ',' expression ')' + { + $$ = pnew pgsGenReference($3, $5, driver.context.zero(), + driver.context.seed(), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REFERENCE '(' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReference($3, $5, $7, driver.context.seed(), + &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + | PGS_REFERENCE '(' expression ',' expression ',' expression ',' expression ')' + { + $$ = pnew pgsGenReference($3, $5, $7, $9, &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.push_var($$); + } + ; + +statement + : compound_statement { $$ = $1; } + | selection_statement { $$ = $1; } + | iteration_statement { $$ = $1; } + | sql_statement ';' { $$ = $1; } + | procedure_statement ';' { $$ = $1; } + | jump_statement ';' { $$ = $1; } + | declaration_statement ';' { $$ = $1; } + | assign_statement ';' { $$ = $1; } + ; + +statement_list + : statement { + driver.context.pop_stmt(); // $1 + $$ = driver.context.stmt_list(&(driver.thread)); + $$->insert_back($1); + } + | statement_list statement { + driver.context.pop_stmt(); // $2 + $$ = $1; + $$->insert_back($2); + } + ; + +compound_statement + : PGS_OPEN PGS_CLOSE { + wxLogScriptVerbose(wxT("BEGIN END")); + $$ = driver.context.stmt_list(&(driver.thread)); + } + | PGS_OPEN statement_list PGS_CLOSE + { + wxLogScriptVerbose(wxT("BEGIN ... END")); + $$ = $2; + } + ; + +sql_statement + : sql_expression { + wxLogScriptVerbose(wxT("%s"), $1->value().c_str()); + $$ = pnew pgsExpressionStmt($1, &(driver.thread)); + driver.context.pop_var(); // $1 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + } + ; + +sql_expression + : sql_query { + $$ = pnew pgsExecute(*($1), &driver.context.m_cout, + &(driver.thread)); + pdelete($1); + driver.context.push_var($$); // pgsExecute + } + ; + +sql_query + : PGS_ABORT { $$ = $1; } + | PGS_ALTER { $$ = $1; } + | PGS_ANALYZE { $$ = $1; } + | PGS_BEGIN { $$ = $1; } + | PGS_CHECKPOINT { $$ = $1; } + | PGS_CLOSE_ST { $$ = $1; } + | PGS_CLUSTER { $$ = $1; } + | PGS_COMMENT { $$ = $1; } + | PGS_COMMIT { $$ = $1; } + | PGS_COPY { $$ = $1; } + | PGS_CREATE { $$ = $1; } + | PGS_DEALLOCATE { $$ = $1; } + | PGS_DECLARE { $$ = $1; } + | PGS_DELETE { $$ = $1; } + | PGS_DISCARD { $$ = $1; } + | PGS_DROP { $$ = $1; } + | PGS_END_ST { $$ = $1; } + | PGS_EXECUTE { $$ = $1; } + | PGS_EXPLAIN { $$ = $1; } + | PGS_FETCH { $$ = $1; } + | PGS_GRANT { $$ = $1; } + | PGS_INSERT { $$ = $1; } + | PGS_LISTEN { $$ = $1; } + | PGS_LOAD { $$ = $1; } + | PGS_LOCK { $$ = $1; } + | PGS_MOVE { $$ = $1; } + | PGS_NOTIFY { $$ = $1; } + | PGS_PREPARE { $$ = $1; } + | PGS_REASSIGN { $$ = $1; } + | PGS_REINDEX { $$ = $1; } + | PGS_RELEASE { $$ = $1; } + | PGS_RESET { $$ = $1; } + | PGS_REVOKE { $$ = $1; } + | PGS_ROLLBACK { $$ = $1; } + | PGS_SAVEPOINT { $$ = $1; } + | PGS_SELECT { $$ = $1; } + | PGS_SET { $$ = $1; } + | PGS_SHOW { $$ = $1; } + | PGS_START { $$ = $1; } + | PGS_TRUNCATE { $$ = $1; } + | PGS_UNLISTEN { $$ = $1; } + | PGS_UPDATE { $$ = $1; } + | PGS_VACUUM { $$ = $1; } + | PGS_VALUES { $$ = $1; } + ; + +declaration_statement + : PGS_DECLARE_ASSGN declaration_list + { + $$ = $2; + } + ; + +declaration_list + : declaration_element { + driver.context.pop_stmt(); // $1 + $$ = driver.context.stmt_list(&(driver.thread)); + $$->insert_back($1); + + } + | declaration_list ',' declaration_element + { + driver.context.pop_stmt(); // $3 + $$ = $1; + $$->insert_back($3); + } + ; + +declaration_element + : PGS_IDENTIFIER { + wxLogScriptVerbose(wxT("DECLARE %s"), $1->c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssign(*($1), + pnew pgsString(wxT(""))), &(driver.thread)); + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + | PGS_IDENTIFIER '{' record_declaration_list '}' + { + wxLogScriptVerbose(wxT("DECLARE %s"), $1->c_str()); + + $$ = pnew pgsDeclareRecordStmt(*($1), driver.context.columns(), + &(driver.thread)); + driver.context.push_stmt($$); // pgsDeclareRecordStmt + $$->set_position(yyloc.begin.line); + + driver.context.clear_columns(); + pdelete($1); + } + ; + +assign_statement + : PGS_SET_ASSIGN assign_list + { + $$ = $2; + } + ; + +assign_list + : assign_element { + driver.context.pop_stmt(); // $1 + $$ = driver.context.stmt_list(&(driver.thread)); + $$->insert_back($1); + } + | assign_list ',' assign_element + { + driver.context.pop_stmt(); // $3 + $$ = $1; + $$->insert_back($3); + } + ; + +assign_element + : PGS_IDENTIFIER PGS_EQ_OP expression + { + wxLogScriptVerbose(wxT("SET %s = %s"), $1->c_str(), + $3->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssign(*($1), $3), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + | PGS_IDENTIFIER '[' expression ']' '[' expression ']' PGS_EQ_OP expression + { + wxLogScriptVerbose(wxT("SET %s[%s][%s] = %s"), + $1->c_str(), $3->value().c_str(), + $6->value().c_str(), $9->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssignToRecord(*($1), + $3, $6, $9), &(driver.thread)); + driver.context.pop_var(); driver.context.pop_var(); + driver.context.pop_var(); // $3 & $6 & $9 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + | PGS_IDENTIFIER PGS_EQ_OP sql_expression + { + wxLogScriptVerbose(wxT("SET %s = %s"), $1->c_str(), + $3->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsAssign(*($1), $3), + &(driver.thread)); + driver.context.pop_var(); // $3 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($1); + } + ; + +selection_statement + : PGS_IF expression statement %prec PGS_ELSE + { + wxLogScriptVerbose(wxT("IF %s"), $2->value().c_str()); + + $$ = pnew pgsIfStmt($2, $3, driver.context + .stmt_list(&(driver.thread)), &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // stmt_list + driver.context.push_stmt($$); // pgsIfStmt + $$->set_position(yyloc.begin.line); + } + | PGS_IF expression statement PGS_ELSE statement + { + wxLogScriptVerbose(wxT("IF %s"), $2->value().c_str()); + + $$ = pnew pgsIfStmt($2, $3, $5, &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.pop_stmt(); // $5 + driver.context.push_stmt($$); // pgsIfStmt + $$->set_position(yyloc.begin.line); + } + ; + +iteration_statement + : PGS_WHILE expression statement + { + wxLogScriptVerbose(wxT("WHILE %s"), $2->value().c_str()); + + $$ = pnew pgsWhileStmt($2, $3, &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.pop_stmt(); // $3 + driver.context.push_stmt($$); // pgsWhileStmt + $$->set_position(yyloc.begin.line); + } + ; + +jump_statement + : PGS_BREAK { + wxLogScriptVerbose(wxT("BREAK")); + + $$ = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt($$); // pgsBreakStmt + $$->set_position(yyloc.begin.line); + } + | PGS_RETURN { + wxLogScriptVerbose(wxT("RETURN")); + + $$ = pnew pgsBreakStmt(&(driver.thread)); + driver.context.push_stmt($$); // pgsBreakStmt + $$->set_position(yyloc.begin.line); + } + | PGS_CONTINUE { + wxLogScriptVerbose(wxT("CONTINUE")); + + $$ = pnew pgsContinueStmt(&(driver.thread)); + driver.context.push_stmt($$); // pgsContinueStmt + $$->set_position(yyloc.begin.line); + } + ; + +procedure_statement + : PGS_PRINT expression + { + wxLogScriptVerbose(wxT("PRINT %s"), $2->value().c_str()); + + $$ = pnew pgsPrintStmt($2, driver.context.m_cout, + &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt($$); // pgsPrintStmt + $$->set_position(yyloc.begin.line); + } + | PGS_ASSERT expression + { + wxLogScriptVerbose(wxT("ASSERT %s"), $2->value().c_str()); + + $$ = pnew pgsAssertStmt($2, &(driver.thread)); + driver.context.pop_var(); // $2 + driver.context.push_stmt($$); // pgsAssertStmt + $$->set_position(yyloc.begin.line); + } + | PGS_RM_LINE '(' PGS_IDENTIFIER '[' expression ']' ')' + { + wxLogScriptVerbose(wxT("RMLINE %s[%s]"), $3->c_str(), + $5->value().c_str()); + + $$ = pnew pgsExpressionStmt(pnew pgsRemoveLine(*($3), $5), + &(driver.thread)); + driver.context.pop_var(); // $5 + driver.context.push_stmt($$); // pgsExpressionStmt + $$->set_position(yyloc.begin.line); + + pdelete($3); + } + ; + +record_declaration_list + : PGS_IDENTIFIER { + driver.context.add_column(*$1); + pdelete($1); + } + | record_declaration_list ',' PGS_IDENTIFIER + { + driver.context.add_column(*$3); + pdelete($3); + } + ; + +translation_unit + : PGS_END + | statement_list PGS_END { + driver.program.eval($1); + + driver.context.pop_stmt(); + pdelete($1); // delete root statement $1 + } + ; + +%% /*** Additional Code ***/ + +void pgscript::pgsParser::error(const pgsParser::location_type & l, + const std::string & m) +{ + wxLogScriptVerbose(wxT("EXPR STACK SIZE = %u"), driver.context.size_vars()); + wxLogScriptVerbose(wxT("STMT STACK SIZE = %u"), driver.context.size_stmts()); + driver.context.clear_stacks(); + driver.error(l, wxString(m.c_str(), wxConvUTF8)); +} diff --git a/pgscript/pgsScanner.ll b/pgscript/pgsScanner.ll new file mode 100644 index 0000000..8449902 --- /dev/null +++ b/pgscript/pgsScanner.ll @@ -0,0 +1,421 @@ +L [a-zA-Z_@#] +D [0-9] +E [e-eE-E][+-]?{D}+ + +%{ /*** C/C++ Declarations ***/ + +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + +#include "pgscript/pgScript.h" +#include "pgscript/parser.tab.hh" +#include "pgscript/utilities/pgsScanner.h" + +/* Import the parser's token type into a local typedef */ +typedef pgscript::pgsParser::token token; +typedef pgscript::pgsParser::token_type token_type; + +/* Work around an incompatibility in flex (at least versions 2.5.31 through + * 2.5.33): it generates code that does not conform to C89. See Debian bug + * 333231 . */ +#undef yywrap +#define yywrap() 1 + +/* By default yylex returns int, we use token_type. Unfortunately yyterminate + * by default returns 0, which is not of token_type. */ +#define yyterminate() return token::PGS_END + +/* This disables inclusion of unistd.h, which is not available under Visual C++ + * on Win32. The C++ scanner uses STL streams instead. */ +#define YY_NO_UNISTD_H + +%} + +/*** Flex Declarations and Options ***/ + +/* Enable C++ scanner class generation */ +%option c++ + +/* Change the name of the scanner class. Results in "pgsFlexLexer" */ +%option prefix="pgs" + +/* Case insensitive */ +%option case-insensitive + +/* The manual says "somewhat more optimized" */ +%option batch + +/* Prevent isatty warning in VC++ */ +%option never-interactive + +/* For using start conditions */ +%option stack + +/* No support for include files is planned */ +%option noyywrap + +/* The following paragraph suffices to track locations accurately. Each time + * yylex is invoked, the begin position is moved onto the end position. */ +%{ +#define YY_USER_ACTION yylloc->columns(yyleng); +%} + +%x SC_COMMENT +%x SC_QUERY +%x SC_DOLLAR +%x SC_STRING + +%% /*** Regular Expressions Part ***/ + + /* Code to place at the beginning of yylex() */ +%{ + // Reset location + yylloc->step(); +%} + +"--".*$ { /* Ignore SQL comment */ } +"/*" { comment_caller = INITIAL; BEGIN(SC_COMMENT); } +"/*" { comment_caller = SC_QUERY; BEGIN(SC_COMMENT); } + +{ +"WHILE" { return token::PGS_WHILE; } +"BREAK" { return token::PGS_BREAK; } +"RETURN" { return token::PGS_RETURN; } +"CONTINUE" { return token::PGS_CONTINUE; } +"IF" { return token::PGS_IF; } +"ELSE" { return token::PGS_ELSE; } +"WAITFOR" { return token::PGS_WAITFOR; } +"AS" { return token::PGS_AS; } + +"ASSERT" { return token::PGS_ASSERT; } +"GO" { /* Ignore it */ } +"PRINT" { return token::PGS_PRINT; } + +"COLUMNS" { return token::PGS_CNT_COLUMNS; } +"LINES" { return token::PGS_CNT_LINES; } +"TRIM" { return token::PGS_TRIM; } +"RMLINE" { return token::PGS_RM_LINE; } +"CAST" { return token::PGS_CAST; } + +"RECORD" { return token::PGS_RECORD; } + +"INTEGER" { return token::PGS_INTEGER; } +"REAL" { return token::PGS_REAL; } +"STRING" { return token::PGS_STRING; } +"REGEX" { return token::PGS_REGEX; } +"FILE" { return token::PGS_FILE; } +"DATE" { return token::PGS_DATE; } +"TIME" { return token::PGS_TIME; } +"DATETIME" { return token::PGS_DATE_TIME; } +"REFERENCE" { return token::PGS_REFERENCE; } + + +"SET"[ \t]+"@" { unput('@'); yylloc->end.columns(-1); + return token::PGS_SET_ASSIGN; } +"DECLARE"[ \t]+"@" { unput('@'); yylloc->end.columns(-1); + return token::PGS_DECLARE_ASSGN; } + +"BEGIN" { /* Block opening */ return token::PGS_OPEN; } +"END" { /* Block closing */ return token::PGS_CLOSE; } + +"@"({L}|{D})* { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_IDENTIFIER; } + +{D}+ { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_INT; } + +{D}*"."{D}+({E})? { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } +{D}+{E} { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } +{D}+"."{D}*({E})? { yylval->str = pnew wxString(yytext, m_conv); + return token::PGS_VAL_REAL; } + +"AND" { return token::PGS_AND_OP; } +"OR" { return token::PGS_OR_OP; } +"<=" { return token::PGS_LE_OP; } +">=" { return token::PGS_GE_OP; } +"=" { return token::PGS_EQ_OP; } +"~=" { return token::PGS_AE_OP; } +"<>" { return token::PGS_NE_OP; } +";" { return wx_static_cast(token_type, ';'); } +("{"|"<%") { return wx_static_cast(token_type, '{'); } +("}"|"%>") { return wx_static_cast(token_type, '}'); } +":" { return wx_static_cast(token_type, ':'); } +"(" { return wx_static_cast(token_type, '('); } +")" { return wx_static_cast(token_type, ')'); } +("["|"<:") { return wx_static_cast(token_type, '['); } +("]"|":>") { return wx_static_cast(token_type, ']'); } +"." { return wx_static_cast(token_type, '.'); } +"," { return wx_static_cast(token_type, ','); } +"NOT" { return token::PGS_NOT_OP; } +"-" { return wx_static_cast(token_type, '-'); } +"+" { return wx_static_cast(token_type, '+'); } +"*" { return wx_static_cast(token_type, '*'); } +"/" { return wx_static_cast(token_type, '/'); } +"%" { return wx_static_cast(token_type, '%'); } +"<" { return wx_static_cast(token_type, '<'); } +">" { return wx_static_cast(token_type, '>'); } + +"'" { string_caller = INITIAL; BEGIN(SC_STRING); } + +"ABORT" { query += yytext; query_token = token::PGS_ABORT; + BEGIN(SC_QUERY); } +"ALTER" { query += yytext; query_token = token::PGS_ALTER; + BEGIN(SC_QUERY); } +"ANALYZE" { query += yytext; query_token = token::PGS_ANALYZE; + BEGIN(SC_QUERY); } +"BEGIN"[ \t]+"TRAN" { query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } +"BEGIN"[ \t]+"WORK" { query += yytext; query_token = token::PGS_BEGIN; + BEGIN(SC_QUERY); } +"CHECKPOINT" { query += yytext; query_token = token::PGS_CHECKPOINT; + BEGIN(SC_QUERY); } +"CLOSE" { query += yytext; query_token = token::PGS_CLOSE_ST; + BEGIN(SC_QUERY); } +"CLUSTER" { query += yytext; query_token = token::PGS_CLUSTER; + BEGIN(SC_QUERY); } +"COMMENT" { query += yytext; query_token = token::PGS_COMMENT; + BEGIN(SC_QUERY); } +"COMMIT" { query += yytext; query_token = token::PGS_COMMIT; + BEGIN(SC_QUERY); } +"COPY" { query += yytext; query_token = token::PGS_COPY; + BEGIN(SC_QUERY); } +"CREATE" { query += yytext; query_token = token::PGS_CREATE; + BEGIN(SC_QUERY); } +"DEALLOCATE" { query += yytext; query_token = token::PGS_DEALLOCATE; + BEGIN(SC_QUERY); } +"DECLARE" { query += yytext; query_token = token::PGS_DECLARE; + BEGIN(SC_QUERY); } +"DELETE" { query += yytext; query_token = token::PGS_DELETE; + BEGIN(SC_QUERY); } +"DISCARD" { query += yytext; query_token = token::PGS_DISCARD; + BEGIN(SC_QUERY); } +"DROP" { query += yytext; query_token = token::PGS_DROP; + BEGIN(SC_QUERY); } +"END"[ \t]+"TRANS" { query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } +"END"[ \t]+"WORK" { query += yytext; query_token = token::PGS_END_ST; + BEGIN(SC_QUERY); } +"EXECUTE" { query += yytext; query_token = token::PGS_EXECUTE; + BEGIN(SC_QUERY); } +"EXPLAIN" { query += yytext; query_token = token::PGS_EXPLAIN; + BEGIN(SC_QUERY); } +"FETCH" { query += yytext; query_token = token::PGS_FETCH; + BEGIN(SC_QUERY); } +"GRANT" { query += yytext; query_token = token::PGS_GRANT; + BEGIN(SC_QUERY); } +"INSERT" { query += yytext; query_token = token::PGS_INSERT; + BEGIN(SC_QUERY); } +"LISTEN" { query += yytext; query_token = token::PGS_LISTEN; + BEGIN(SC_QUERY); } +"LOAD" { query += yytext; query_token = token::PGS_LOAD; + BEGIN(SC_QUERY); } +"LOCK" { query += yytext; query_token = token::PGS_LOCK; + BEGIN(SC_QUERY); } +"MOVE" { query += yytext; query_token = token::PGS_MOVE; + BEGIN(SC_QUERY); } +"NOTIFY" { query += yytext; query_token = token::PGS_NOTIFY; + BEGIN(SC_QUERY); } +"PREPARE" { query += yytext; query_token = token::PGS_PREPARE; + BEGIN(SC_QUERY); } +"REASSIGN" { query += yytext; query_token = token::PGS_REASSIGN; + BEGIN(SC_QUERY); } +"REINDEX" { query += yytext; query_token = token::PGS_REINDEX; + BEGIN(SC_QUERY); } +"RELEASE" { query += yytext; query_token = token::PGS_RELEASE; + BEGIN(SC_QUERY); } +"RESET" { query += yytext; query_token = token::PGS_RESET; + BEGIN(SC_QUERY); } +"REVOKE" { query += yytext; query_token = token::PGS_REVOKE; + BEGIN(SC_QUERY); } +"ROLLBACK" { query += yytext; query_token = token::PGS_ROLLBACK; + BEGIN(SC_QUERY); } +"SAVEPOINT" { query += yytext; query_token = token::PGS_SAVEPOINT; + BEGIN(SC_QUERY); } +"SELECT" { query += yytext; query_token = token::PGS_SELECT; + BEGIN(SC_QUERY); } +"SET" { query += yytext; query_token = token::PGS_SET; + BEGIN(SC_QUERY); } +"SHOW" { query += yytext; query_token = token::PGS_SHOW; + BEGIN(SC_QUERY); } +"START" { query += yytext; query_token = token::PGS_START; + BEGIN(SC_QUERY); } +"TRUNCATE" { query += yytext; query_token = token::PGS_TRUNCATE; + BEGIN(SC_QUERY); } +"UNLISTEN" { query += yytext; query_token = token::PGS_UNLISTEN; + BEGIN(SC_QUERY); } +"UPDATE" { query += yytext; query_token = token::PGS_UPDATE; + BEGIN(SC_QUERY); } +"VACUUM" { query += yytext; query_token = token::PGS_VACUUM; + BEGIN(SC_QUERY); } +"VALUES" { query += yytext; query_token = token::PGS_VALUES; + BEGIN(SC_QUERY); } + +[ \t\v\f]+ { } +\r { yylloc->step(); } +\n { yylloc->lines(yyleng); yylloc->step(); } +. { return token::PGS_UNKNOWN; } +} + +{ +"'" { query += yytext; string_caller = SC_QUERY; BEGIN(SC_STRING); } +\$({L}|{D})*\$ { query += yytext; dollar = yytext; BEGIN(SC_DOLLAR); } +";" { yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(';'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; } +"(" { ++m_parent; query += yytext; } +")" { + --m_parent; + if (m_parent == -1) + { + yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); unput(')'); yylloc->end.columns(-1); + BEGIN(INITIAL); m_parent = 0; return query_token; + } + else + { + query += yytext; + } + } +\r { query += yytext; yylloc->step(); } +\n { query += yytext; yylloc->lines(yyleng); yylloc->step(); } +<> { yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } +. { yylloc->columns(columns(*yytext)); query += yytext; } +} + +{ +\$({L}|{D})*\$ { query += yytext; + if (std::string(yytext) == dollar) BEGIN(SC_QUERY); } +\r { query += yytext; yylloc->step(); } +\n { query += yytext; yylloc->lines(yyleng); yylloc->step(); } +<> { query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; } +. { yylloc->columns(columns(*yytext)); query += yytext; } +} + +{ +"*/" { BEGIN(comment_caller); } +\r { yylloc->step(); } +\n { yylloc->lines(yyleng); yylloc->step(); } +. { yylloc->columns(columns(*yytext)); } +} + +{ +"''" { + if (string_caller == SC_QUERY) + query += yytext; + else + str += "'"; + } +\\. { + if (string_caller == SC_QUERY) + query += yytext; + else + str += *(yytext + 1); + yylloc->columns(columns(*(yytext + 1))); + } +"'" { + if (string_caller == SC_QUERY) + { + query += yytext; + BEGIN(string_caller); + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } +\r { + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->step(); + } +\n { + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->lines(yyleng); yylloc->step(); + } +<> { + if (string_caller == SC_QUERY) + { + query += yytext; yylval->str = pnew wxString(query.c_str(), m_conv); + query.clear(); m_parent = 0; return query_token; + } + else + { + yylval->str = pnew wxString(str.c_str(), m_conv); + str.clear(); + BEGIN(string_caller); + return token::PGS_VAL_STR; + } + } +. { + if (string_caller == SC_QUERY) + query += yytext; + else + str += yytext; + yylloc->columns(columns(*yytext)); + } +} + +%% /*** Additional Code ***/ + +namespace pgscript +{ + +pgsScanner::pgsScanner(wxMBConv & conv, std::istream * in, std::ostream * out) : + pgsFlexLexer(in, out), m_parent(0), m_conv(conv) +{ + +} + +pgsScanner::~pgsScanner() +{ + +} + +void pgsScanner::set_debug(bool b) +{ + yy_flex_debug = b; +} + +int pgsScanner::columns(const char & c) +{ + if ((c & 0xF0) == 0xF0) // 4 bytes + return -3; + else if ((c & 0xE0) == 0xE0) // 3 bytes + return -2; + else if ((c & 0xC0) == 0xC0) // 2 bytes + return -1; + else return 0; +} + +} + +/* This implementation of pgsFlexLexer::yylex() is required to fill the + * vtable of the class pgsFlexLexer. We define the scanner's main yylex + * function via YY_DECL to reside in the pgsScanner class instead. */ + +#ifdef yylex +#undef yylex +#endif + +int pgsFlexLexer::yylex() +{ + return 0; +} diff --git a/pgscript/statements/module.mk b/pgscript/statements/module.mk new file mode 100644 index 0000000..c5754d8 --- /dev/null +++ b/pgscript/statements/module.mk @@ -0,0 +1,27 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/statements/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/statements/pgsAssertStmt.cpp \ + pgscript/statements/pgsBreakStmt.cpp \ + pgscript/statements/pgsContinueStmt.cpp \ + pgscript/statements/pgsDeclareRecordStmt.cpp \ + pgscript/statements/pgsExpressionStmt.cpp \ + pgscript/statements/pgsIfStmt.cpp \ + pgscript/statements/pgsPrintStmt.cpp \ + pgscript/statements/pgsProgram.cpp \ + pgscript/statements/pgsStmt.cpp \ + pgscript/statements/pgsStmtList.cpp \ + pgscript/statements/pgsWhileStmt.cpp + +EXTRA_DIST += \ + pgscript/statements/module.mk + diff --git a/pgscript/statements/pgsAssertStmt.cpp b/pgscript/statements/pgsAssertStmt.cpp new file mode 100644 index 0000000..e86f9f7 --- /dev/null +++ b/pgscript/statements/pgsAssertStmt.cpp @@ -0,0 +1,34 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsAssertStmt.h" + +#include "pgscript/exceptions/pgsAssertException.h" + +pgsAssertStmt::pgsAssertStmt(const pgsExpression *cond, pgsThread *app) : + pgsStmt(app), m_cond(cond) +{ + +} + +pgsAssertStmt::~pgsAssertStmt() +{ + pdelete(m_cond); +} + +void pgsAssertStmt::eval(pgsVarMap &vars) const +{ + pgsOperand result = m_cond->eval(vars); + if (!result->pgs_is_true()) + { + throw pgsAssertException(m_cond->value()); + } +} diff --git a/pgscript/statements/pgsBreakStmt.cpp b/pgscript/statements/pgsBreakStmt.cpp new file mode 100644 index 0000000..c7057cf --- /dev/null +++ b/pgscript/statements/pgsBreakStmt.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsBreakStmt.h" + +#include "pgscript/exceptions/pgsBreakException.h" + +pgsBreakStmt::pgsBreakStmt(pgsThread *app) : + pgsStmt(app) +{ + +} + +pgsBreakStmt::~pgsBreakStmt() +{ + +} + +void pgsBreakStmt::eval(pgsVarMap &vars) const +{ + throw pgsBreakException(); +} diff --git a/pgscript/statements/pgsContinueStmt.cpp b/pgscript/statements/pgsContinueStmt.cpp new file mode 100644 index 0000000..2e716b5 --- /dev/null +++ b/pgscript/statements/pgsContinueStmt.cpp @@ -0,0 +1,30 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsContinueStmt.h" + +#include "pgscript/exceptions/pgsContinueException.h" + +pgsContinueStmt::pgsContinueStmt(pgsThread *app) : + pgsStmt(app) +{ + +} + +pgsContinueStmt::~pgsContinueStmt() +{ + +} + +void pgsContinueStmt::eval(pgsVarMap &vars) const +{ + throw pgsContinueException(); +} diff --git a/pgscript/statements/pgsDeclareRecordStmt.cpp b/pgscript/statements/pgsDeclareRecordStmt.cpp new file mode 100644 index 0000000..c3d54b1 --- /dev/null +++ b/pgscript/statements/pgsDeclareRecordStmt.cpp @@ -0,0 +1,36 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsDeclareRecordStmt.h" + +#include "pgscript/objects/pgsRecord.h" + +pgsDeclareRecordStmt::pgsDeclareRecordStmt(const wxString &rec, + const wxArrayString &columns, pgsThread *app) : + pgsStmt(app), m_rec(rec), m_columns(columns) +{ + +} + +pgsDeclareRecordStmt::~pgsDeclareRecordStmt() +{ + +} + +void pgsDeclareRecordStmt::eval(pgsVarMap &vars) const +{ + pgsRecord *rec = pnew pgsRecord(m_columns.size()); + for (size_t i = 0; i < m_columns.GetCount(); i++) + { + rec->set_column_name(i, m_columns.Item(i)); + } + vars[m_rec] = rec; +} diff --git a/pgscript/statements/pgsExpressionStmt.cpp b/pgscript/statements/pgsExpressionStmt.cpp new file mode 100644 index 0000000..85e8a7f --- /dev/null +++ b/pgscript/statements/pgsExpressionStmt.cpp @@ -0,0 +1,28 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsExpressionStmt.h" + +pgsExpressionStmt::pgsExpressionStmt(const pgsExpression *var, pgsThread *app) : + pgsStmt(app), m_var(var) +{ + +} + +pgsExpressionStmt::~pgsExpressionStmt() +{ + pdelete(m_var) +} + +void pgsExpressionStmt::eval(pgsVarMap &vars) const +{ + m_var->eval(vars); +} diff --git a/pgscript/statements/pgsIfStmt.cpp b/pgscript/statements/pgsIfStmt.cpp new file mode 100644 index 0000000..6b95095 --- /dev/null +++ b/pgscript/statements/pgsIfStmt.cpp @@ -0,0 +1,39 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsIfStmt.h" + +pgsIfStmt::pgsIfStmt(const pgsExpression *cond, const pgsStmt *stmt_list_if, + const pgsStmt *stmt_list_else, pgsThread *app) : + pgsStmt(app), m_cond(cond), m_stmt_list_if(stmt_list_if), + m_stmt_list_else(stmt_list_else) +{ + +} + +pgsIfStmt::~pgsIfStmt() +{ + pdelete(m_cond); + pdelete(m_stmt_list_if); + pdelete(m_stmt_list_else); +} + +void pgsIfStmt::eval(pgsVarMap &vars) const +{ + if (m_cond->eval(vars)->pgs_is_true()) + { + m_stmt_list_if->eval(vars); + } + else + { + m_stmt_list_else->eval(vars); + } +} diff --git a/pgscript/statements/pgsPrintStmt.cpp b/pgscript/statements/pgsPrintStmt.cpp new file mode 100644 index 0000000..662ad67 --- /dev/null +++ b/pgscript/statements/pgsPrintStmt.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsPrintStmt.h" + +#include "pgscript/exceptions/pgsException.h" +#include "pgscript/utilities/pgsThread.h" +#include "pgscript/utilities/pgsUtilities.h" + +pgsPrintStmt::pgsPrintStmt(const pgsExpression *var, pgsOutputStream &cout, + pgsThread *app) : + pgsStmt(app), m_var(var), m_cout(cout) +{ + +} + +pgsPrintStmt::~pgsPrintStmt() +{ + pdelete(m_var); +} + +void pgsPrintStmt::eval(pgsVarMap &vars) const +{ + if (m_app != 0) + { + m_app->LockOutput(); + } + + try + { + m_cout << PGSOUTPGSCRIPT << wx_static_cast(const wxString, + m_var->eval(vars)->value()) << wxT("\n"); + } + catch (const pgsException &) + { + if (m_app != 0) + { + m_app->UnlockOutput(); + } + + throw; + } + + if (m_app != 0) + { + m_app->UnlockOutput(); + } +} diff --git a/pgscript/statements/pgsProgram.cpp b/pgscript/statements/pgsProgram.cpp new file mode 100644 index 0000000..744634f --- /dev/null +++ b/pgscript/statements/pgsProgram.cpp @@ -0,0 +1,63 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsProgram.h" + +#include "pgscript/exceptions/pgsException.h" +#include "pgscript/statements/pgsStmtList.h" + +pgsProgram::pgsProgram(pgsVarMap &vars) : + m_vars(vars) +{ + +} + +pgsProgram::~pgsProgram() +{ + +} + +void pgsProgram::dump() +{ + dump(m_vars); +} + +void pgsProgram::dump(const pgsVarMap &vars) +{ + pgsVarMap::const_iterator it; + for (it = vars.begin(); it != vars.end(); it++) + { + wxLogMessage(wxString() << it->first << wxT(" -> ") + << it->second->value()); + } +} + +void pgsProgram::eval(pgsStmtList *stmt_list) +{ + wxLogScript(wxT("Entering program")); + + try + { + stmt_list->eval(m_vars); + } + catch (const pgsException &) + { + + } + catch (const std::exception &) + { + + } + + pgsStmtList::m_exception_thrown = false; + + wxLogScript(wxT("Leaving program")); +} diff --git a/pgscript/statements/pgsStmt.cpp b/pgscript/statements/pgsStmt.cpp new file mode 100644 index 0000000..4a29d91 --- /dev/null +++ b/pgscript/statements/pgsStmt.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsStmt.h" + +pgsStmt::pgsStmt(pgsThread *app) : + m_line(0), m_app(app) +{ + +} + +pgsStmt::~pgsStmt() +{ + +} + +void pgsStmt::set_position(int line) +{ + m_line = line; +} + +int pgsStmt::line() const +{ + return m_line; +} diff --git a/pgscript/statements/pgsStmtList.cpp b/pgscript/statements/pgsStmtList.cpp new file mode 100644 index 0000000..121702f --- /dev/null +++ b/pgscript/statements/pgsStmtList.cpp @@ -0,0 +1,115 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsStmtList.h" + +#include +#include "pgscript/exceptions/pgsBreakException.h" +#include "pgscript/exceptions/pgsContinueException.h" +#include "pgscript/exceptions/pgsInterruptException.h" +#include "pgscript/utilities/pgsThread.h" +#include "pgscript/utilities/pgsUtilities.h" + +#include +WX_DEFINE_LIST(pgsListStmt); + +bool pgsStmtList::m_exception_thrown = false; + +pgsStmtList::pgsStmtList(pgsOutputStream &cout, pgsThread *app) : + pgsStmt(app), m_cout(cout) +{ + +} + +pgsStmtList::~pgsStmtList() +{ + pgsListStmt::iterator it; + for (it = m_stmt_list.begin(); it != m_stmt_list.end(); it++) + { + pdelete(*it); + } +} + +void pgsStmtList::eval(pgsVarMap &vars) const +{ + pgsListStmt::const_iterator it; + for (it = m_stmt_list.begin(); it != m_stmt_list.end(); it++) + { + pgsStmt *current = *it; + + try + { + current->eval(vars); + + if (m_app != 0 && m_app->TestDestroy()) + throw pgsInterruptException(); + } + catch (const pgsException &e) + { + if (!m_exception_thrown && (typeid(e) != typeid(pgsBreakException)) + && (typeid(e) != typeid(pgsContinueException))) + { + if (m_app != 0) + { + m_app->LockOutput(); + m_app->last_error_line(current->line()); + } + + m_cout << wx_static_cast(const wxString, e.message()) + << wxT(" on line ") << current->line() << wxT("\n"); + m_exception_thrown = true; + + if (m_app != 0) + { + m_app->UnlockOutput(); + } + } + throw; + } + catch (const std::exception &e) + { + if (!m_exception_thrown) + { + if (m_app != 0) + { + m_app->LockOutput(); + m_app->last_error_line(current->line()); + } + + m_cout << PGSOUTERROR << _("Unknown exception:\n") + << wx_static_cast(const wxString, + wxString(e.what(), wxConvUTF8)); + m_exception_thrown = true; + + if (m_app != 0) + { + m_app->UnlockOutput(); + } + } + throw; + } + + if (m_app != 0) + { + m_app->Yield(); + } + } +} + +void pgsStmtList::insert_front(pgsStmt *stmt) +{ + m_stmt_list.push_front(stmt); +} + +void pgsStmtList::insert_back(pgsStmt *stmt) +{ + m_stmt_list.push_back(stmt); +} diff --git a/pgscript/statements/pgsWhileStmt.cpp b/pgscript/statements/pgsWhileStmt.cpp new file mode 100644 index 0000000..996b75a --- /dev/null +++ b/pgscript/statements/pgsWhileStmt.cpp @@ -0,0 +1,56 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/statements/pgsWhileStmt.h" + +#include "pgscript/exceptions/pgsBreakException.h" +#include "pgscript/exceptions/pgsContinueException.h" +#include "pgscript/exceptions/pgsInterruptException.h" +#include "pgscript/utilities/pgsThread.h" + +pgsWhileStmt::pgsWhileStmt(const pgsExpression *cond, const pgsStmt *stmt_list, + pgsThread *app) : + pgsStmt(app), m_cond(cond), m_stmt_list(stmt_list) +{ + +} + +pgsWhileStmt::~pgsWhileStmt() +{ + pdelete(m_cond); + pdelete(m_stmt_list); +} + +void pgsWhileStmt::eval(pgsVarMap &vars) const +{ +loop: + if (m_cond->eval(vars)->pgs_is_true()) + { + try + { + m_stmt_list->eval(vars); + } + catch (const pgsBreakException &) + { + goto end; + } + catch (const pgsContinueException &) + { + + } + if (m_app != 0 && m_app->TestDestroy()) + throw pgsInterruptException(); + + goto loop; + } +end: + ; +} diff --git a/pgscript/utilities/m_apm/mapm5sin.cpp b/pgscript/utilities/m_apm/mapm5sin.cpp new file mode 100644 index 0000000..c111c52 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm5sin.cpp @@ -0,0 +1,154 @@ + +/* + * M_APM - mapm5sin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions that implement the sin (5x) + * and cos (4x) multiple angle relations + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void M_5x_sin(M_APM r, int places, M_APM x) +{ + M_APM tmp8, tmp9; + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_multiply(tmp9, x, MM_5x_125R); /* 1 / (5*5*5) */ + M_raw_sin(tmp8, (places + 6), tmp9); + M_5x_do_it(tmp9, (places + 4), tmp8); + M_5x_do_it(tmp8, (places + 4), tmp9); + M_5x_do_it(r, places, tmp8); + + M_restore_stack(2); +} +/****************************************************************************/ +void M_4x_cos(M_APM r, int places, M_APM x) +{ + M_APM tmp8, tmp9; + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + /* + * if |x| >= 1.0 use multiple angle identity 4 times + * if |x| < 1.0 use multiple angle identity 3 times + */ + + if (x->m_apm_exponent > 0) + { + m_apm_multiply(tmp9, x, MM_5x_256R); /* 1 / (4*4*4*4) */ + M_raw_cos(tmp8, (places + 8), tmp9); + M_4x_do_it(tmp9, (places + 8), tmp8); + M_4x_do_it(tmp8, (places + 6), tmp9); + M_4x_do_it(tmp9, (places + 4), tmp8); + M_4x_do_it(r, places, tmp9); + } + else + { + m_apm_multiply(tmp9, x, MM_5x_64R); /* 1 / (4*4*4) */ + M_raw_cos(tmp8, (places + 6), tmp9); + M_4x_do_it(tmp9, (places + 4), tmp8); + M_4x_do_it(tmp8, (places + 4), tmp9); + M_4x_do_it(r, places, tmp8); + } + + M_restore_stack(2); +} +/****************************************************************************/ +/* + * calculate the multiple angle identity for sin (5x) + * + * sin (5x) == 16 * sin^5 (x) - 20 * sin^3 (x) + 5 * sin(x) + */ +void M_5x_do_it(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, tmp1, t2, t3, t5; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + t2 = M_get_stack_var(); + t3 = M_get_stack_var(); + t5 = M_get_stack_var(); + + m_apm_multiply(tmp1, xx, xx); + m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */ + + m_apm_multiply(tmp1, t2, xx); + m_apm_round(t3, (places + 4), tmp1); /* x ^ 3 */ + + m_apm_multiply(t5, t2, t3); /* x ^ 5 */ + + m_apm_multiply(tmp0, xx, MM_Five); + m_apm_multiply(tmp1, t5, MM_5x_Sixteen); + m_apm_add(t2, tmp0, tmp1); + m_apm_multiply(tmp1, t3, MM_5x_Twenty); + m_apm_subtract(tmp0, t2, tmp1); + + m_apm_round(rr, places, tmp0); + M_restore_stack(5); +} +/****************************************************************************/ +/* + * calculate the multiple angle identity for cos (4x) + * + * cos (4x) == 8 * [ cos^4 (x) - cos^2 (x) ] + 1 + */ +void M_4x_do_it(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, tmp1, t2, t4; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + t2 = M_get_stack_var(); + t4 = M_get_stack_var(); + + m_apm_multiply(tmp1, xx, xx); + m_apm_round(t2, (places + 4), tmp1); /* x ^ 2 */ + m_apm_multiply(t4, t2, t2); /* x ^ 4 */ + + m_apm_subtract(tmp0, t4, t2); + m_apm_multiply(tmp1, tmp0, MM_5x_Eight); + m_apm_add(tmp0, MM_One, tmp1); + m_apm_round(rr, places, tmp0); + M_restore_stack(4); +} +/****************************************************************************/ +/* + * compute r = sqrt(1 - a ^ 2). + */ +void M_cos_to_sin(M_APM r, int places, M_APM a) +{ + M_APM tmp1, tmp2; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_multiply(tmp1, a, a); + m_apm_subtract(tmp2, MM_One, tmp1); + m_apm_sqrt(r, places, tmp2); + M_restore_stack(2); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_add.cpp b/pgscript/utilities/m_apm/mapm_add.cpp new file mode 100644 index 0000000..12c4bc5 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_add.cpp @@ -0,0 +1,329 @@ + +/* + * M_APM - mapm_add.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions that implement the sin (5x) + * and cos (4x) multiple angle relations + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM M_work1 = NULL; +static M_APM M_work2 = NULL; +static int M_add_firsttime = TRUE; + +/****************************************************************************/ +void M_free_all_add() +{ + if (M_add_firsttime == FALSE) + { + m_apm_free(M_work1); + m_apm_free(M_work2); + M_add_firsttime = TRUE; + } +} +/****************************************************************************/ +void m_apm_add(M_APM r, M_APM a, M_APM b) +{ + int j, carry, sign, aexp, bexp, adigits, bdigits; + + if (M_add_firsttime) + { + M_add_firsttime = FALSE; + M_work1 = m_apm_init(); + M_work2 = m_apm_init(); + } + + if (a->m_apm_sign == 0) + { + m_apm_copy(r, b); + return; + } + + if (b->m_apm_sign == 0) + { + m_apm_copy(r, a); + return; + } + + if (a->m_apm_sign == 1 && b->m_apm_sign == -1) + { + b->m_apm_sign = 1; + m_apm_subtract(r, a, b); + b->m_apm_sign = -1; + return; + } + + if (a->m_apm_sign == -1 && b->m_apm_sign == 1) + { + a->m_apm_sign = 1; + m_apm_subtract(r, b, a); + a->m_apm_sign = -1; + return; + } + + sign = a->m_apm_sign; /* signs are the same, result will be same */ + + aexp = a->m_apm_exponent; + bexp = b->m_apm_exponent; + + m_apm_copy(M_work1, a); + m_apm_copy(M_work2, b); + + /* + * scale by at least 1 factor of 10 in case the MSB carrys + */ + + if (aexp == bexp) + { + M_apm_scale(M_work1, 2); /* shift 2 digits == 1 byte for efficiency */ + M_apm_scale(M_work2, 2); + } + else + { + if (aexp > bexp) + { + M_apm_scale(M_work1, 2); + M_apm_scale(M_work2, (aexp + 2 - bexp)); + } + else /* aexp < bexp */ + { + M_apm_scale(M_work2, 2); + M_apm_scale(M_work1, (bexp + 2 - aexp)); + } + } + + adigits = M_work1->m_apm_datalength; + bdigits = M_work2->m_apm_datalength; + + if (adigits >= bdigits) + { + m_apm_copy(r, M_work1); + j = (bdigits + 1) >> 1; + carry = 0; + + while (TRUE) + { + j--; + r->m_apm_data[j] += carry + M_work2->m_apm_data[j]; + + if (r->m_apm_data[j] >= 100) + { + r->m_apm_data[j] -= 100; + carry = 1; + } + else + carry = 0; + + if (j == 0) + break; + } + } + else + { + m_apm_copy(r, M_work2); + j = (adigits + 1) >> 1; + carry = 0; + + while (TRUE) + { + j--; + r->m_apm_data[j] += carry + M_work1->m_apm_data[j]; + + if (r->m_apm_data[j] >= 100) + { + r->m_apm_data[j] -= 100; + carry = 1; + } + else + carry = 0; + + if (j == 0) + break; + } + } + + r->m_apm_sign = sign; + + M_apm_normalize(r); +} +/****************************************************************************/ +void m_apm_subtract(M_APM r, M_APM a, M_APM b) +{ + int itmp, j, flag, icompare, sign, aexp, bexp, + borrow, adigits, bdigits; + + if (M_add_firsttime) + { + M_add_firsttime = FALSE; + M_work1 = m_apm_init(); + M_work2 = m_apm_init(); + } + + if (b->m_apm_sign == 0) + { + m_apm_copy(r, a); + return; + } + + if (a->m_apm_sign == 0) + { + m_apm_copy(r, b); + r->m_apm_sign = -(r->m_apm_sign); + return; + } + + if (a->m_apm_sign == 1 && b->m_apm_sign == -1) + { + b->m_apm_sign = 1; + m_apm_add(r, a, b); + b->m_apm_sign = -1; + return; + } + + if (a->m_apm_sign == -1 && b->m_apm_sign == 1) + { + b->m_apm_sign = -1; + m_apm_add(r, a, b); + b->m_apm_sign = 1; + return; + } + + /* now, the signs are the same */ + /* make a positive working copy */ + + m_apm_absolute_value(M_work1, a); + m_apm_absolute_value(M_work2, b); + + /* are they the same?? if so, the result is zero */ + + if ((icompare = m_apm_compare(M_work1, M_work2)) == 0) + { + M_set_to_zero(r); + return; + } + + if (icompare == 1) /* |a| > |b| (do A-B) */ + { + flag = TRUE; + sign = a->m_apm_sign; + } + else /* |b| > |a| (do B-A) */ + { + flag = FALSE; + sign = -(a->m_apm_sign); + } + + aexp = M_work1->m_apm_exponent; + bexp = M_work2->m_apm_exponent; + + if (aexp > bexp) + M_apm_scale(M_work2, (aexp - bexp)); + + if (aexp < bexp) + M_apm_scale(M_work1, (bexp - aexp)); + + adigits = M_work1->m_apm_datalength; + bdigits = M_work2->m_apm_datalength; + + if (adigits > bdigits) + M_apm_pad(M_work2, adigits); + + if (adigits < bdigits) + M_apm_pad(M_work1, bdigits); + + if (flag) /* perform A-B, M_work1 - M_work2 */ + { + m_apm_copy(r, M_work1); + j = (r->m_apm_datalength + 1) >> 1; + borrow = 0; + + while (TRUE) + { + j--; + itmp = (int)r->m_apm_data[j] - ((int)M_work2->m_apm_data[j] + borrow); + + if (itmp >= 0) + { + r->m_apm_data[j] = (UCHAR)itmp; + borrow = 0; + } + else + { + r->m_apm_data[j] = (UCHAR)(100 + itmp); + borrow = 1; + } + + if (j == 0) + break; + } + } + else /* perform B-A, M_work2 - M_work1 */ + { + m_apm_copy(r, M_work2); + j = (r->m_apm_datalength + 1) >> 1; + borrow = 0; + + while (TRUE) + { + j--; + itmp = (int)r->m_apm_data[j] - ((int)M_work1->m_apm_data[j] + borrow); + + if (itmp >= 0) + { + r->m_apm_data[j] = (UCHAR)itmp; + borrow = 0; + } + else + { + r->m_apm_data[j] = (UCHAR)(100 + itmp); + borrow = 1; + } + + if (j == 0) + break; + } + } + + r->m_apm_sign = sign; + + M_apm_normalize(r); +} +/****************************************************************************/ + +#ifdef __cplusplus + +MAPM operator+(const MAPM &a, const MAPM &b) +{ + MAPM ret; + m_apm_add(ret.val(), a.cval(), b.cval()); + return ret; +} +MAPM operator-(const MAPM &a, const MAPM &b) +{ + MAPM ret; + m_apm_subtract(ret.val(), a.cval(), b.cval()); + return ret; +} + +#endif diff --git a/pgscript/utilities/m_apm/mapm_cpi.cpp b/pgscript/utilities/m_apm/mapm_cpi.cpp new file mode 100644 index 0000000..4204699 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_cpi.cpp @@ -0,0 +1,161 @@ + +/* + * M_APM - mapm_cpi.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the PI related functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * check if our local copy of PI is precise enough + * for our purpose. if not, calculate PI so it's + * as precise as desired, accurate to 'places' decimal + * places. + */ +void M_check_PI_places(int places) +{ + int dplaces; + + dplaces = places + 2; + + if (dplaces > MM_lc_PI_digits) + { + MM_lc_PI_digits = dplaces + 2; + + /* compute PI using the AGM (see right below) */ + + M_calculate_PI_AGM(MM_lc_PI, (dplaces + 5)); + + m_apm_multiply(MM_lc_HALF_PI, MM_0_5, MM_lc_PI); + m_apm_multiply(MM_lc_2_PI, MM_Two, MM_lc_PI); + } +} +/****************************************************************************/ +/* + * Calculate PI using the AGM (Arithmetic-Geometric Mean) + * + * Init : A0 = 1 + * B0 = 1 / sqrt(2) + * Sum = 1 + * + * Iterate: n = 1... + * + * + * A = 0.5 * [ A + B ] + * n n-1 n-1 + * + * + * B = sqrt [ A * B ] + * n n-1 n-1 + * + * + * + * C = 0.5 * [ A - B ] + * n n-1 n-1 + * + * + * 2 n+1 + * Sum = Sum - C * 2 + * n + * + * + * At the end when C is 'small enough' : + * n + * + * 2 + * PI = 4 * A / Sum + * n+1 + * + * -OR- + * + * 2 + * PI = ( A + B ) / Sum + * n n + * + */ +void M_calculate_PI_AGM(M_APM outv, int places) +{ + M_APM tmp1, tmp2, a0, b0, c0, a1, b1, sum, pow_2; + int dplaces, nn; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + a0 = M_get_stack_var(); + b0 = M_get_stack_var(); + c0 = M_get_stack_var(); + a1 = M_get_stack_var(); + b1 = M_get_stack_var(); + sum = M_get_stack_var(); + pow_2 = M_get_stack_var(); + + dplaces = places + 16; + + m_apm_copy(a0, MM_One); + m_apm_copy(sum, MM_One); + m_apm_copy(pow_2, MM_Four); + m_apm_sqrt(b0, dplaces, MM_0_5); /* sqrt(0.5) */ + + while (TRUE) + { + m_apm_add(tmp1, a0, b0); + m_apm_multiply(a1, MM_0_5, tmp1); + + m_apm_multiply(tmp1, a0, b0); + m_apm_sqrt(b1, dplaces, tmp1); + + m_apm_subtract(tmp1, a0, b0); + m_apm_multiply(c0, MM_0_5, tmp1); + + /* + * the net 'PI' calculated from this iteration will + * be accurate to ~4 X the value of (c0)'s exponent. + * this was determined experimentally. + */ + + nn = -4 * c0->m_apm_exponent; + + m_apm_multiply(tmp1, c0, c0); + m_apm_multiply(tmp2, tmp1, pow_2); + m_apm_subtract(tmp1, sum, tmp2); + m_apm_round(sum, dplaces, tmp1); + + if (nn >= dplaces) + break; + + m_apm_copy(a0, a1); + m_apm_copy(b0, b1); + + m_apm_multiply(tmp1, pow_2, MM_Two); + m_apm_copy(pow_2, tmp1); + } + + m_apm_add(tmp1, a1, b1); + m_apm_multiply(tmp2, tmp1, tmp1); + m_apm_divide(tmp1, dplaces, tmp2, sum); + m_apm_round(outv, places, tmp1); + + M_restore_stack(9); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_div.cpp b/pgscript/utilities/m_apm/mapm_div.cpp new file mode 100644 index 0000000..cd5ee24 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_div.cpp @@ -0,0 +1,300 @@ + +/* + * M_APM - mapm_div.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the basic division functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM M_div_worka; +static M_APM M_div_workb; +static M_APM M_div_tmp7; +static M_APM M_div_tmp8; +static M_APM M_div_tmp9; + +static int M_div_firsttime = TRUE; + +/****************************************************************************/ +void M_free_all_div() +{ + if (M_div_firsttime == FALSE) + { + m_apm_free(M_div_worka); + m_apm_free(M_div_workb); + m_apm_free(M_div_tmp7); + m_apm_free(M_div_tmp8); + m_apm_free(M_div_tmp9); + + M_div_firsttime = TRUE; + } +} +/****************************************************************************/ +void m_apm_integer_div_rem(M_APM qq, M_APM rr, M_APM aa, M_APM bb) +{ + m_apm_integer_divide(qq, aa, bb); + m_apm_multiply(M_div_tmp7, qq, bb); + m_apm_subtract(rr, aa, M_div_tmp7); +} +/****************************************************************************/ +void m_apm_integer_divide(M_APM rr, M_APM aa, M_APM bb) +{ + /* + * we must use this divide function since the + * faster divide function using the reciprocal + * will round the result (possibly changing + * nnm.999999... --> nn(m+1).0000 which would + * invalidate the 'integer_divide' goal). + */ + + M_apm_sdivide(rr, 4, aa, bb); + + if (rr->m_apm_exponent <= 0) /* result is 0 */ + { + M_set_to_zero(rr); + } + else + { + if (rr->m_apm_datalength > rr->m_apm_exponent) + { + rr->m_apm_datalength = rr->m_apm_exponent; + M_apm_normalize(rr); + } + } +} +/****************************************************************************/ +void M_apm_sdivide(M_APM r, int places, M_APM a, M_APM b) +{ + int j, k, m, b0, sign, nexp, indexr, icompare, iterations; + long trial_numer; + void *vp; + + if (M_div_firsttime) + { + M_div_firsttime = FALSE; + + M_div_worka = m_apm_init(); + M_div_workb = m_apm_init(); + M_div_tmp7 = m_apm_init(); + M_div_tmp8 = m_apm_init(); + M_div_tmp9 = m_apm_init(); + } + + sign = a->m_apm_sign * b->m_apm_sign; + + if (sign == 0) /* one number is zero, result is zero */ + { + if (b->m_apm_sign == 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'M_apm_sdivide\', Divide by 0"); + } + + M_set_to_zero(r); + return; + } + + /* + * Knuth step D1. Since base = 100, base / 2 = 50. + * (also make the working copies positive) + */ + + if (b->m_apm_data[0] >= 50) + { + m_apm_absolute_value(M_div_worka, a); + m_apm_absolute_value(M_div_workb, b); + } + else /* 'normal' step D1 */ + { + k = 100 / (b->m_apm_data[0] + 1); + m_apm_set_long(M_div_tmp9, (long)k); + + m_apm_multiply(M_div_worka, M_div_tmp9, a); + m_apm_multiply(M_div_workb, M_div_tmp9, b); + + M_div_worka->m_apm_sign = 1; + M_div_workb->m_apm_sign = 1; + } + + /* setup trial denominator for step D3 */ + + b0 = 100 * (int)M_div_workb->m_apm_data[0]; + + if (M_div_workb->m_apm_datalength >= 3) + b0 += M_div_workb->m_apm_data[1]; + + nexp = M_div_worka->m_apm_exponent - M_div_workb->m_apm_exponent; + + if (nexp > 0) + iterations = nexp + places + 1; + else + iterations = places + 1; + + k = (iterations + 1) >> 1; /* required size of result, in bytes */ + + if (k > r->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(r->m_apm_data, (k + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_sdivide\', Out of memory"); + } + + r->m_apm_malloclength = k + 28; + r->m_apm_data = (UCHAR *)vp; + } + + /* clear the exponent in the working copies */ + + M_div_worka->m_apm_exponent = 0; + M_div_workb->m_apm_exponent = 0; + + /* if numbers are equal, ratio == 1.00000... */ + + if ((icompare = m_apm_compare(M_div_worka, M_div_workb)) == 0) + { + iterations = 1; + r->m_apm_data[0] = 10; + nexp++; + } + else /* ratio not 1, do the real division */ + { + if (icompare == 1) /* numerator > denominator */ + { + nexp++; /* to adjust the final exponent */ + M_div_worka->m_apm_exponent += 1; /* multiply numerator by 10 */ + } + else /* numerator < denominator */ + { + M_div_worka->m_apm_exponent += 2; /* multiply numerator by 100 */ + } + + indexr = 0; + m = 0; + + while (TRUE) + { + /* + * Knuth step D3. Only use the 3rd -> 6th digits if the number + * actually has that many digits. + */ + + trial_numer = 10000L * (long)M_div_worka->m_apm_data[0]; + + if (M_div_worka->m_apm_datalength >= 5) + { + trial_numer += 100 * M_div_worka->m_apm_data[1] + + M_div_worka->m_apm_data[2]; + } + else + { + if (M_div_worka->m_apm_datalength >= 3) + trial_numer += 100 * M_div_worka->m_apm_data[1]; + } + + j = (int)(trial_numer / b0); + + /* + * Since the library 'normalizes' all the results, we need + * to look at the exponent of the number to decide if we + * have a lead in 0n or 00. + */ + + if ((k = 2 - M_div_worka->m_apm_exponent) > 0) + { + while (TRUE) + { + j /= 10; + if (--k == 0) + break; + } + } + + if (j == 100) /* qhat == base ?? */ + j = 99; /* if so, decrease by 1 */ + + m_apm_set_long(M_div_tmp8, (long)j); + m_apm_multiply(M_div_tmp7, M_div_tmp8, M_div_workb); + + /* + * Compare our q-hat (j) against the desired number. + * j is either correct, 1 too large, or 2 too large + * per Theorem B on pg 272 of Art of Compter Programming, + * Volume 2, 3rd Edition. + * + * The above statement is only true if using the 2 leading + * digits of the numerator and the leading digit of the + * denominator. Since we are using the (3) leading digits + * of the numerator and the (2) leading digits of the + * denominator, we eliminate the case where our q-hat is + * 2 too large, (and q-hat being 1 too large is quite remote). + */ + + if (m_apm_compare(M_div_tmp7, M_div_worka) == 1) + { + j--; + m_apm_subtract(M_div_tmp8, M_div_tmp7, M_div_workb); + m_apm_copy(M_div_tmp7, M_div_tmp8); + } + + /* + * Since we know q-hat is correct, step D6 is unnecessary. + * + * Store q-hat, step D5. Since D6 is unnecessary, we can + * do D5 before D4 and decide if we are done. + */ + + r->m_apm_data[indexr++] = (UCHAR)j; /* j == 'qhat' */ + m += 2; + + if (m >= iterations) + break; + + /* step D4 */ + + m_apm_subtract(M_div_tmp9, M_div_worka, M_div_tmp7); + + /* + * if the subtraction yields zero, the division is exact + * and we are done early. + */ + + if (M_div_tmp9->m_apm_sign == 0) + { + iterations = m; + break; + } + + /* multiply by 100 and re-save */ + M_div_tmp9->m_apm_exponent += 2; + m_apm_copy(M_div_worka, M_div_tmp9); + } + } + + r->m_apm_sign = sign; + r->m_apm_exponent = nexp; + r->m_apm_datalength = iterations; + + M_apm_normalize(r); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_exp.cpp b/pgscript/utilities/m_apm/mapm_exp.cpp new file mode 100644 index 0000000..d2710e8 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_exp.cpp @@ -0,0 +1,294 @@ + +/* + * M_APM - mapm_exp.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the EXP function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM MM_exp_log2R; +static M_APM MM_exp_512R; +static int MM_firsttime1 = TRUE; + +/****************************************************************************/ +void M_free_all_exp() +{ + if (MM_firsttime1 == FALSE) + { + m_apm_free(MM_exp_log2R); + m_apm_free(MM_exp_512R); + + MM_firsttime1 = TRUE; + } +} +/****************************************************************************/ +void m_apm_exp(M_APM r, int places, M_APM x) +{ + M_APM tmp7, tmp8, tmp9; + int dplaces, nn, ii; + + if (MM_firsttime1) + { + MM_firsttime1 = FALSE; + + MM_exp_log2R = m_apm_init(); + MM_exp_512R = m_apm_init(); + + m_apm_set_string(MM_exp_log2R, "1.44269504089"); /* ~ 1 / log(2) */ + m_apm_set_string(MM_exp_512R, "1.953125E-3"); /* 1 / 512 */ + } + + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + if (x->m_apm_sign == 0) /* if input == 0, return '1' */ + { + m_apm_copy(r, MM_One); + M_restore_stack(3); + return; + } + + if (x->m_apm_exponent <= -3) /* already small enough so call _raw directly */ + { + M_raw_exp(tmp9, (places + 6), x); + m_apm_round(r, places, tmp9); + M_restore_stack(3); + return; + } + + /* + From David H. Bailey's MPFUN Fortran package : + + exp (t) = (1 + r + r^2 / 2! + r^3 / 3! + r^4 / 4! ...) ^ q * 2 ^ n + + where q = 256, r = t' / q, t' = t - n Log(2) and where n is chosen so + that -0.5 Log(2) < t' <= 0.5 Log(2). Reducing t mod Log(2) and + dividing by 256 insures that -0.001 < r <= 0.001, which accelerates + convergence in the above series. + + I use q = 512 and also limit how small 'r' can become. The 'r' used + here is limited in magnitude from 1.95E-4 < |r| < 1.35E-3. Forcing + 'r' into a narrow range keeps the algorithm 'well behaved'. + + ( the range is [0.1 / 512] to [log(2) / 512] ) + */ + + if (M_exp_compute_nn(&nn, tmp7, x) != 0) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_exp\', Input too large, Overflow"); + + M_set_to_zero(r); + M_restore_stack(3); + return; + } + + dplaces = places + 8; + + /* check to make sure our log(2) is accurate enough */ + + M_check_log_places(dplaces); + + m_apm_multiply(tmp8, tmp7, MM_lc_log2); + m_apm_subtract(tmp7, x, tmp8); + + /* + * guarantee that |tmp7| is between 0.1 and 0.9999999.... + * (in practice, the upper limit only reaches log(2), 0.693... ) + */ + + while (TRUE) + { + if (tmp7->m_apm_sign != 0) + { + if (tmp7->m_apm_exponent == 0) + break; + } + + if (tmp7->m_apm_sign >= 0) + { + nn++; + m_apm_subtract(tmp8, tmp7, MM_lc_log2); + m_apm_copy(tmp7, tmp8); + } + else + { + nn--; + m_apm_add(tmp8, tmp7, MM_lc_log2); + m_apm_copy(tmp7, tmp8); + } + } + + m_apm_multiply(tmp9, tmp7, MM_exp_512R); + + /* perform the series expansion ... */ + + M_raw_exp(tmp8, dplaces, tmp9); + + /* + * raise result to the 512 power + * + * note : x ^ 512 = (((x ^ 2) ^ 2) ^ 2) ... 9 times + */ + + ii = 9; + + while (TRUE) + { + m_apm_multiply(tmp9, tmp8, tmp8); + m_apm_round(tmp8, dplaces, tmp9); + + if (--ii == 0) + break; + } + + /* now compute 2 ^ N */ + + m_apm_integer_pow(tmp7, dplaces, MM_Two, nn); + + m_apm_multiply(tmp9, tmp7, tmp8); + m_apm_round(r, places, tmp9); + + M_restore_stack(3); /* restore the 3 locals we used here */ +} +/****************************************************************************/ +/* + compute int *n = round_to_nearest_int(a / log(2)) + M_APM b = MAPM version of *n + + returns 0: OK + -1, 1: failure +*/ +int M_exp_compute_nn(int *n, M_APM b, M_APM a) +{ + M_APM tmp0, tmp1; + void *vp; + char *cp, sbuf[48]; + int kk; + + *n = 0; + vp = NULL; + cp = sbuf; + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + + /* find 'n' and convert it to a normal C int */ + /* we just need an approx 1/log(2) for this calculation */ + + m_apm_multiply(tmp1, a, MM_exp_log2R); + + /* round to the nearest int */ + + if (tmp1->m_apm_sign >= 0) + { + m_apm_add(tmp0, tmp1, MM_0_5); + m_apm_floor(tmp1, tmp0); + } + else + { + m_apm_subtract(tmp0, tmp1, MM_0_5); + m_apm_ceil(tmp1, tmp0); + } + + kk = tmp1->m_apm_exponent; + if (kk >= 42) + { + if ((vp = (void *)MAPM_MALLOC((kk + 16) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_exp_compute_nn\', Out of memory"); + } + + cp = (char *)vp; + } + + m_apm_to_integer_string(cp, tmp1); + *n = atoi(cp); + + m_apm_set_long(b, (long)(*n)); + + kk = m_apm_compare(b, tmp1); + + if (vp != NULL) + MAPM_FREE(vp); + + M_restore_stack(2); + return(kk); +} +/****************************************************************************/ +/* + calculate the exponential function using the following series : + + x^2 x^3 x^4 x^5 + exp(x) == 1 + x + --- + --- + --- + --- ... + 2! 3! 4! 5! + +*/ +void M_raw_exp(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, digit, term; + int tolerance, local_precision, prev_exp; + long m1; + + tmp0 = M_get_stack_var(); + term = M_get_stack_var(); + digit = M_get_stack_var(); + + local_precision = places + 8; + tolerance = -(places + 4); + prev_exp = 0; + + m_apm_add(rr, MM_One, xx); + m_apm_copy(term, xx); + + m1 = 2L; + + while (TRUE) + { + m_apm_set_long(digit, m1); + m_apm_multiply(tmp0, term, xx); + m_apm_divide(term, local_precision, tmp0, digit); + m_apm_add(tmp0, rr, term); + m_apm_copy(rr, tmp0); + + if ((term->m_apm_exponent < tolerance) || (term->m_apm_sign == 0)) + break; + + if (m1 != 2L) + { + local_precision = local_precision + term->m_apm_exponent - prev_exp; + + if (local_precision < 20) + local_precision = 20; + } + + prev_exp = term->m_apm_exponent; + m1++; + } + + M_restore_stack(3); /* restore the 3 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_fam.cpp b/pgscript/utilities/m_apm/mapm_fam.cpp new file mode 100644 index 0000000..5dac8c1 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_fam.cpp @@ -0,0 +1,55 @@ + +/* + * M_APM - mapm_fam.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the free all memory and similiar functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_free_all_mem() +{ + M_free_all_add(); /* call each module which has statically declared data */ + M_free_all_div(); + M_free_all_exp(); + +#ifndef NO_FFT_MULTIPLY + M_free_all_fft(); +#endif + + M_free_all_pow(); + M_free_all_rnd(); + M_free_all_set(); + M_free_all_cnst(); + M_free_all_fmul(); + M_free_all_stck(); + M_free_all_util(); +} +/****************************************************************************/ +void m_apm_trim_mem_usage() +{ + m_apm_free_all_mem(); + m_apm_free(m_apm_init()); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_fft.cpp b/pgscript/utilities/m_apm/mapm_fft.cpp new file mode 100644 index 0000000..248403c --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_fft.cpp @@ -0,0 +1,953 @@ + +/* + * M_APM - mapm_fft.c + * + * This FFT (Fast Fourier Transform) is from Takuya OOURA + * + * Copyright(C) 1996-1999 Takuya OOURA + * email: ooura@mmm.t.u-tokyo.ac.jp + * + * See full FFT documentation below ... (MCR) + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the FFT based FAST MULTIPLICATION function + * as well as its support functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +#ifndef MM_PI_2 +#define MM_PI_2 1.570796326794896619231321691639751442098584699687 +#endif + +#ifndef WR5000 /* cos(MM_PI_2*0.5000) */ +#define WR5000 0.707106781186547524400844362104849039284835937688 +#endif + +#ifndef RDFT_LOOP_DIV /* control of the RDFT's speed & tolerance */ +#define RDFT_LOOP_DIV 64 +#endif + +extern void M_fast_mul_fft(UCHAR *, UCHAR *, UCHAR *, int); + +extern void M_rdft(int, int, double *); +extern void M_bitrv2(int, double *); +extern void M_cftfsub(int, double *); +extern void M_cftbsub(int, double *); +extern void M_rftfsub(int, double *); +extern void M_rftbsub(int, double *); +extern void M_cft1st(int, double *); +extern void M_cftmdl(int, int, double *); + +static double *M_aa_array, *M_bb_array; +static int M_size = -1; + +static char *M_fft_error_msg = (char *)"\'M_fast_mul_fft\', Out of memory"; + +/****************************************************************************/ +void M_free_all_fft() +{ + if (M_size > 0) + { + MAPM_FREE(M_aa_array); + MAPM_FREE(M_bb_array); + M_size = -1; + } +} +/****************************************************************************/ +/* + * multiply 'uu' by 'vv' with nbytes each + * yielding a 2*nbytes result in 'ww'. + * each byte contains a base 100 'digit', + * i.e.: range from 0-99. + * + * MSB LSB + * + * uu,vv [0] [1] [2] ... [N-1] + * ww [0] [1] [2] ... [2N-1] + */ + +void M_fast_mul_fft(UCHAR *ww, UCHAR *uu, UCHAR *vv, int nbytes) +{ + int mflag, i, j, nn2, nn; + double carry, nnr, dtemp, *a, *b; + UCHAR *w0; + unsigned long ul; + + if (M_size < 0) /* if first time in, setup working arrays */ + { + if (M_get_sizeof_int() == 2) /* if still using 16 bit compilers */ + M_size = 516; + else + M_size = 8200; + + M_aa_array = (double *)MAPM_MALLOC(M_size * sizeof(double)); + M_bb_array = (double *)MAPM_MALLOC(M_size * sizeof(double)); + + if ((M_aa_array == NULL) || (M_bb_array == NULL)) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_fft_error_msg); + } + } + + nn = nbytes; + nn2 = nbytes >> 1; + + if (nn > M_size) + { + mflag = TRUE; + + a = (double *)MAPM_MALLOC((nn + 8) * sizeof(double)); + b = (double *)MAPM_MALLOC((nn + 8) * sizeof(double)); + + if ((a == NULL) || (b == NULL)) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_fft_error_msg); + } + } + else + { + mflag = FALSE; + + a = M_aa_array; + b = M_bb_array; + } + + /* + * convert normal base 100 MAPM numbers to base 10000 + * for the FFT operation. + */ + + i = 0; + for (j = 0; j < nn2; j++) + { + a[j] = (double)((int)uu[i] * 100 + uu[i + 1]); + b[j] = (double)((int)vv[i] * 100 + vv[i + 1]); + i += 2; + } + + /* zero fill the second half of the arrays */ + + for (j = nn2; j < nn; j++) + { + a[j] = 0.0; + b[j] = 0.0; + } + + /* perform the forward Fourier transforms for both numbers */ + + M_rdft(nn, 1, a); + M_rdft(nn, 1, b); + + /* perform the convolution ... */ + + b[0] *= a[0]; + b[1] *= a[1]; + + for (j = 3; j <= nn; j += 2) + { + dtemp = b[j - 1]; + b[j - 1] = dtemp * a[j - 1] - b[j] * a[j]; + b[j] = dtemp * a[j] + b[j] * a[j - 1]; + } + + /* perform the inverse transform on the result */ + + M_rdft(nn, -1, b); + + /* perform a final pass to release all the carries */ + /* we are still in base 10000 at this point */ + + carry = 0.0; + j = nn; + nnr = 2.0 / (double)nn; + + while (1) + { + dtemp = b[--j] * nnr + carry + 0.5; + ul = (unsigned long)(dtemp * 1.0E-4); + carry = (double)ul; + b[j] = dtemp - carry * 10000.0; + + if (j == 0) + break; + } + + /* copy result to our destination after converting back to base 100 */ + + w0 = ww; + M_get_div_rem((int)ul, w0, (w0 + 1)); + + for (j = 0; j <= (nn - 2); j++) + { + w0 += 2; + M_get_div_rem((int)b[j], w0, (w0 + 1)); + } + + if (mflag) + { + MAPM_FREE(b); + MAPM_FREE(a); + } +} +/****************************************************************************/ + +/* + * The following info is from Takuya OOURA's documentation : + * + * NOTE : MAPM only uses the 'RDFT' function (as well as the + * functions RDFT calls). All the code from here down + * in this file is from Takuya OOURA. The only change I + * made was to add 'M_' in front of all the functions + * I used. This was to guard against any possible + * name collisions in the future. + * + * MCR 06 July 2000 + * + * + * General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package + * + * Description: + * A package to calculate Discrete Fourier/Cosine/Sine Transforms of + * 1-dimensional sequences of length 2^N. + * + * fft4g_h.c : FFT Package in C - Simple Version I (radix 4,2) + * + * rdft: Real Discrete Fourier Transform + * + * Method: + * -------- rdft -------- + * A method with a following butterfly operation appended to "cdft". + * In forward transform : + * A[k] = sum_j=0^n-1 a[j]*W(n)^(j*k), 0<=k<=n/2, + * W(n) = exp(2*pi*i/n), + * this routine makes an array x[] : + * x[j] = a[2*j] + i*a[2*j+1], 0<=j RDFT + R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 + I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0 IRDFT (excluding scale) + a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k + rdft(n, 1, a); + + rdft(n, -1, a); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + + output data + a[2*k] = R[k], 0<=k + input data + a[2*j] = R[j], 0<=j= 0) + { + if (n > 4) + { + M_bitrv2(n, a); + M_cftfsub(n, a); + M_rftfsub(n, a); + } + else if (n == 4) + { + M_cftfsub(n, a); + } + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } + else + { + a[1] = 0.5 * (a[0] - a[1]); + a[0] -= a[1]; + if (n > 4) + { + M_rftbsub(n, a); + M_bitrv2(n, a); + M_cftbsub(n, a); + } + else if (n == 4) + { + M_cftfsub(n, a); + } + } +} + + + +void M_bitrv2(int n, double *a) +{ + int j0, k0, j1, k1, l, m, i, j, k; + double xr, xi, yr, yi; + + l = n >> 2; + m = 2; + while (m < l) + { + l >>= 1; + m <<= 1; + } + if (m == l) + { + j0 = 0; + for (k0 = 0; k0 < m; k0 += 2) + { + k = k0; + for (j = j0; j < j0 + k0; j += 2) + { + xr = a[j]; + xi = a[j + 1]; + yr = a[k]; + yi = a[k + 1]; + a[j] = yr; + a[j + 1] = yi; + a[k] = xr; + a[k + 1] = xi; + j1 = j + m; + k1 = k + 2 * m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m; + k1 -= m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m; + k1 += 2 * m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + for (i = n >> 1; i > (k ^= i); i >>= 1); + } + j1 = j0 + k0 + m; + k1 = j1 + m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + for (i = n >> 1; i > (j0 ^= i); i >>= 1); + } + } + else + { + j0 = 0; + for (k0 = 2; k0 < m; k0 += 2) + { + for (i = n >> 1; i > (j0 ^= i); i >>= 1); + k = k0; + for (j = j0; j < j0 + k0; j += 2) + { + xr = a[j]; + xi = a[j + 1]; + yr = a[k]; + yi = a[k + 1]; + a[j] = yr; + a[j + 1] = yi; + a[k] = xr; + a[k + 1] = xi; + j1 = j + m; + k1 = k + m; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + for (i = n >> 1; i > (k ^= i); i >>= 1); + } + } + } +} + + + +void M_cftfsub(int n, double *a) +{ + int j, j1, j2, j3, l; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n > 8) + { + M_cft1st(n, a); + l = 8; + while ((l << 2) < n) + { + M_cftmdl(n, l, a); + l <<= 2; + } + } + if ((l << 2) == n) + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + } + else + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = a[j + 1] - a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] += a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + + +void M_cftbsub(int n, double *a) +{ + int j, j1, j2, j3, l; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if (n > 8) + { + M_cft1st(n, a); + l = 8; + while ((l << 2) < n) + { + M_cftmdl(n, l, a); + l <<= 2; + } + } + if ((l << 2) == n) + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = -a[j + 1] - a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = -a[j + 1] + a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i + x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i - x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i + x3r; + } + } + else + { + for (j = 0; j < l; j += 2) + { + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = -a[j + 1] + a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] = -a[j + 1] - a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} + + + +void M_cft1st(int n, double *a) +{ + int j, kj, kr; + double ew, wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[2]; + x0i = a[1] + a[3]; + x1r = a[0] - a[2]; + x1i = a[1] - a[3]; + x2r = a[4] + a[6]; + x2i = a[5] + a[7]; + x3r = a[4] - a[6]; + x3i = a[5] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + wn4r = WR5000; + x0r = a[8] + a[10]; + x0i = a[9] + a[11]; + x1r = a[8] - a[10]; + x1i = a[9] - a[11]; + x2r = a[12] + a[14]; + x2i = a[13] + a[15]; + x3r = a[12] - a[14]; + x3i = a[13] - a[15]; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[12] = x2i - x0i; + a[13] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[10] = wn4r * (x0r - x0i); + a[11] = wn4r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[14] = wn4r * (x0i - x0r); + a[15] = wn4r * (x0i + x0r); + ew = MM_PI_2 / n; + kr = 0; + for (j = 16; j < n; j += 16) + { + for (kj = n >> 2; kj > (kr ^= kj); kj >>= 1); + wk1r = cos(ew * kr); + wk1i = sin(ew * kr); + wk2r = 1 - 2 * wk1i * wk1i; + wk2i = 2 * wk1i * wk1r; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + x0r = a[j] + a[j + 2]; + x0i = a[j + 1] + a[j + 3]; + x1r = a[j] - a[j + 2]; + x1i = a[j + 1] - a[j + 3]; + x2r = a[j + 4] + a[j + 6]; + x2i = a[j + 5] + a[j + 7]; + x3r = a[j + 4] - a[j + 6]; + x3i = a[j + 5] - a[j + 7]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 4] = wk2r * x0r - wk2i * x0i; + a[j + 5] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 2] = wk1r * x0r - wk1i * x0i; + a[j + 3] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 6] = wk3r * x0r - wk3i * x0i; + a[j + 7] = wk3r * x0i + wk3i * x0r; + x0r = wn4r * (wk1r - wk1i); + wk1i = wn4r * (wk1r + wk1i); + wk1r = x0r; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + x0r = a[j + 8] + a[j + 10]; + x0i = a[j + 9] + a[j + 11]; + x1r = a[j + 8] - a[j + 10]; + x1i = a[j + 9] - a[j + 11]; + x2r = a[j + 12] + a[j + 14]; + x2i = a[j + 13] + a[j + 15]; + x3r = a[j + 12] - a[j + 14]; + x3i = a[j + 13] - a[j + 15]; + a[j + 8] = x0r + x2r; + a[j + 9] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 12] = -wk2i * x0r - wk2r * x0i; + a[j + 13] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 10] = wk1r * x0r - wk1i * x0i; + a[j + 11] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 14] = wk3r * x0r - wk3i * x0i; + a[j + 15] = wk3r * x0i + wk3i * x0r; + } +} + + + +void M_cftmdl(int n, int l, double *a) +{ + int j, j1, j2, j3, k, kj, kr, m, m2; + double ew, wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + m = l << 2; + for (j = 0; j < l; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + wn4r = WR5000; + for (j = m; j < l + m; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x2i - x0i; + a[j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wn4r * (x0r - x0i); + a[j1 + 1] = wn4r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3] = wn4r * (x0i - x0r); + a[j3 + 1] = wn4r * (x0i + x0r); + } + ew = MM_PI_2 / n; + kr = 0; + m2 = 2 * m; + for (k = m2; k < n; k += m2) + { + for (kj = n >> 2; kj > (kr ^= kj); kj >>= 1); + wk1r = cos(ew * kr); + wk1i = sin(ew * kr); + wk2r = 1 - 2 * wk1i * wk1i; + wk2i = 2 * wk1i * wk1r; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for (j = k; j < l + k; j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = wk2r * x0r - wk2i * x0i; + a[j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + x0r = wn4r * (wk1r - wk1i); + wk1i = wn4r * (wk1r + wk1i); + wk1r = x0r; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + for (j = k + m; j < l + (k + m); j += 2) + { + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = -wk2i * x0r - wk2r * x0i; + a[j2 + 1] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } +} + + + +void M_rftfsub(int n, double *a) +{ + int i, i0, j, k; + double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; + + ec = 2 * MM_PI_2 / n; + wkr = 0; + wki = 0; + wdi = cos(ec); + wdr = sin(ec); + wdi *= wdr; + wdr *= wdr; + w1r = 1 - 2 * wdr; + w1i = 2 * wdi; + ss = 2 * w1i; + i = n >> 1; + while (1) + { + i0 = i - 4 * RDFT_LOOP_DIV; + if (i0 < 4) + { + i0 = 4; + } + for (j = i - 4; j >= i0; j -= 4) + { + k = n - j; + xr = a[j + 2] - a[k - 2]; + xi = a[j + 3] + a[k - 1]; + yr = wdr * xr - wdi * xi; + yi = wdr * xi + wdi * xr; + a[j + 2] -= yr; + a[j + 3] -= yi; + a[k - 2] += yr; + a[k - 1] -= yi; + wkr += ss * wdi; + wki += ss * (0.5 - wdr); + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + wdr += ss * wki; + wdi += ss * (0.5 - wkr); + } + if (i0 == 4) + { + break; + } + wkr = 0.5 * sin(ec * i0); + wki = 0.5 * cos(ec * i0); + wdr = 0.5 - (wkr * w1r - wki * w1i); + wdi = wkr * w1i + wki * w1r; + wkr = 0.5 - wkr; + i = i0; + } + xr = a[2] - a[n - 2]; + xi = a[3] + a[n - 1]; + yr = wdr * xr - wdi * xi; + yi = wdr * xi + wdi * xr; + a[2] -= yr; + a[3] -= yi; + a[n - 2] += yr; + a[n - 1] -= yi; +} + + + +void M_rftbsub(int n, double *a) +{ + int i, i0, j, k; + double ec, w1r, w1i, wkr, wki, wdr, wdi, ss, xr, xi, yr, yi; + + ec = 2 * MM_PI_2 / n; + wkr = 0; + wki = 0; + wdi = cos(ec); + wdr = sin(ec); + wdi *= wdr; + wdr *= wdr; + w1r = 1 - 2 * wdr; + w1i = 2 * wdi; + ss = 2 * w1i; + i = n >> 1; + a[i + 1] = -a[i + 1]; + while (1) + { + i0 = i - 4 * RDFT_LOOP_DIV; + if (i0 < 4) + { + i0 = 4; + } + for (j = i - 4; j >= i0; j -= 4) + { + k = n - j; + xr = a[j + 2] - a[k - 2]; + xi = a[j + 3] + a[k - 1]; + yr = wdr * xr + wdi * xi; + yi = wdr * xi - wdi * xr; + a[j + 2] -= yr; + a[j + 3] = yi - a[j + 3]; + a[k - 2] += yr; + a[k - 1] = yi - a[k - 1]; + wkr += ss * wdi; + wki += ss * (0.5 - wdr); + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] = yi - a[j + 1]; + a[k] += yr; + a[k + 1] = yi - a[k + 1]; + wdr += ss * wki; + wdi += ss * (0.5 - wkr); + } + if (i0 == 4) + { + break; + } + wkr = 0.5 * sin(ec * i0); + wki = 0.5 * cos(ec * i0); + wdr = 0.5 - (wkr * w1r - wki * w1i); + wdi = wkr * w1i + wki * w1r; + wkr = 0.5 - wkr; + i = i0; + } + xr = a[2] - a[n - 2]; + xi = a[3] + a[n - 1]; + yr = wdr * xr + wdi * xi; + yi = wdr * xi - wdi * xr; + a[2] -= yr; + a[3] = yi - a[3]; + a[n - 2] += yr; + a[n - 1] = yi - a[n - 1]; + a[1] = -a[1]; +} + diff --git a/pgscript/utilities/m_apm/mapm_flr.cpp b/pgscript/utilities/m_apm/mapm_flr.cpp new file mode 100644 index 0000000..7bae5ae --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_flr.cpp @@ -0,0 +1,120 @@ + +/* + * M_APM - mapm_flr.c + * + * Copyright (C) 2001 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the floor and ceil functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/* + * input floor ceil + * ----- ------ ------ + * 329.0 329.0 329.0 + * -837.0 -837.0 -837.0 + * 372.64 372.0 373.0 + * -237.52 -238.0 -237.0 + */ + +/****************************************************************************/ +/* + * return the nearest integer <= input + */ +void m_apm_floor(M_APM bb, M_APM aa) +{ + M_APM mtmp; + + m_apm_copy(bb, aa); + + if (m_apm_is_integer(bb)) /* if integer, we're done */ + return; + + if (bb->m_apm_exponent <= 0) /* if |bb| < 1, result is -1 or 0 */ + { + if (bb->m_apm_sign < 0) + m_apm_negate(bb, MM_One); + else + M_set_to_zero(bb); + + return; + } + + if (bb->m_apm_sign < 0) + { + mtmp = M_get_stack_var(); + m_apm_negate(mtmp, bb); + + mtmp->m_apm_datalength = mtmp->m_apm_exponent; + M_apm_normalize(mtmp); + + m_apm_add(bb, mtmp, MM_One); + bb->m_apm_sign = -1; + M_restore_stack(1); + } + else + { + bb->m_apm_datalength = bb->m_apm_exponent; + M_apm_normalize(bb); + } +} +/****************************************************************************/ +/* + * return the nearest integer >= input + */ +void m_apm_ceil(M_APM bb, M_APM aa) +{ + M_APM mtmp; + + m_apm_copy(bb, aa); + + if (m_apm_is_integer(bb)) /* if integer, we're done */ + return; + + if (bb->m_apm_exponent <= 0) /* if |bb| < 1, result is 0 or 1 */ + { + if (bb->m_apm_sign < 0) + M_set_to_zero(bb); + else + m_apm_copy(bb, MM_One); + + return; + } + + if (bb->m_apm_sign < 0) + { + bb->m_apm_datalength = bb->m_apm_exponent; + M_apm_normalize(bb); + } + else + { + mtmp = M_get_stack_var(); + m_apm_copy(mtmp, bb); + + mtmp->m_apm_datalength = mtmp->m_apm_exponent; + M_apm_normalize(mtmp); + + m_apm_add(bb, mtmp, MM_One); + M_restore_stack(1); + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_fpf.cpp b/pgscript/utilities/m_apm/mapm_fpf.cpp new file mode 100644 index 0000000..4f7fe40 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_fpf.cpp @@ -0,0 +1,415 @@ + +/* + * M_APM - mapm_fpf.c + * + * Copyright (C) 2001 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Fixed Point Formatting functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" +#include + +/****************************************************************************/ +char *m_apm_to_fixpt_stringexp(int dplaces, M_APM atmp, + char ch_radx, char ch_sep, int ct_sep) +{ + int places, xp, dl, ii; + char *cpr; + + places = dplaces; + + dl = atmp->m_apm_datalength; + xp = atmp->m_apm_exponent; + + if (places < 0) /* show ALL digits */ + { + if (xp < 0) + ii = dl - xp; + else + { + if (dl > xp) + ii = dl; + else + ii = xp; + } + } + else + { + ii = places; + + if (xp > 0) + ii += xp; + } + + if (ct_sep != 0 && ch_sep != 0 && xp > 0) + ii += xp / ct_sep; + + if ((cpr = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL) + return(NULL); + + m_apm_to_fixpt_stringex(cpr, places, atmp, ch_radx, ch_sep, ct_sep); + + return(cpr); +} +/****************************************************************************/ +void m_apm_to_fixpt_stringex(char *s, int dplaces, M_APM atmp, + char ch_radix, char ch_sep, int count_sep) +{ + M_APM btmp; + char ch, *cpd, *cps; + int ii, jj, kk, ct, dl, xp, no_sep_flg, places; + + btmp = M_get_stack_var(); + places = dplaces; + cpd = s; + no_sep_flg = FALSE; + + m_apm_absolute_value(btmp, atmp); /* do conversion of positive number */ + + if (ch_sep == 0 || count_sep == 0) /* no separator char OR count */ + no_sep_flg = TRUE; + + /* determine how much memory to get for the temp string */ + + dl = btmp->m_apm_datalength; + xp = btmp->m_apm_exponent; + + if (places < 0) /* show ALL digits */ + { + if (xp < 0) + ii = dl - xp; + else + { + if (dl > xp) + ii = dl; + else + ii = xp; + } + } + else + { + ii = places; + + if (xp > 0) + ii += xp; + } + + if ((cps = (char *)MAPM_MALLOC((ii + 32) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'m_apm_to_fixpt_stringex\', Out of memory"); + } + + m_apm_to_fixpt_string(cps, places, btmp); + + /* + * the converted string may be all 'zero', 0.0000... + * if so and the original number is negative, + * do NOT set the '-' sign of our output string. + */ + + if (atmp->m_apm_sign == -1) /* if input number negative */ + { + kk = 0; + jj = 0; + + while (TRUE) + { + ch = cps[kk++]; + if ((ch == '\0') || (jj != 0)) + break; + + if (isdigit((int)ch)) + { + if (ch != '0') + jj = 1; + } + } + + if (jj) + *cpd++ = '-'; + } + + ct = M_strposition(cps, (char *) "."); /* find the default (.) radix char */ + + if (ct == -1) /* if not found .. */ + { + strcat(cps, "."); /* add one */ + ct = M_strposition(cps, (char *) "."); /* and then find it */ + } + + if (places == 0) /* int format, terminate at radix char */ + cps[ct] = '\0'; + else + cps[ct] = ch_radix; /* assign the radix char */ + + /* + * if the number is small enough to not have any separator char's ... + */ + + if (ct <= count_sep) + no_sep_flg = TRUE; + + if (no_sep_flg) + { + strcpy(cpd, cps); + } + else + { + jj = 0; + kk = count_sep; + ii = ct / count_sep; + + if ((ii = ct - ii * count_sep) == 0) + ii = count_sep; + + while (TRUE) /* write out the first 1,2 */ + { + /* (up to count_sep) digits */ + *cpd++ = cps[jj++]; + + if (--ii == 0) + break; + } + + while (TRUE) /* write rest of the string */ + { + if (kk == count_sep) /* write a new separator char */ + { + if (jj != ct) /* unless we're at the radix */ + { + *cpd++ = ch_sep; /* note that this also disables */ + kk = 0; /* the separator char AFTER */ + } /* the radix char */ + } + + if ((*cpd++ = cps[jj++]) == '\0') + break; + + kk++; + } + } + + MAPM_FREE(cps); + M_restore_stack(1); +} +/****************************************************************************/ +void m_apm_to_fixpt_string(char *ss, int dplaces, M_APM mtmp) +{ + M_APM ctmp; + void *vp; + int places, i2, ii, jj, kk, xp, dl, numb; + UCHAR *ucp, numdiv, numrem; + char *cpw, *cpd, sbuf[128]; + + ctmp = M_get_stack_var(); + vp = NULL; + cpd = ss; + places = dplaces; + + /* just want integer portion if places == 0 */ + + if (places == 0) + { + if (mtmp->m_apm_sign >= 0) + m_apm_add(ctmp, mtmp, MM_0_5); + else + m_apm_subtract(ctmp, mtmp, MM_0_5); + + m_apm_to_integer_string(cpd, ctmp); + + M_restore_stack(1); + return; + } + + if (places > 0) + M_apm_round_fixpt(ctmp, places, mtmp); + else + m_apm_copy(ctmp, mtmp); /* show ALL digits */ + + if (ctmp->m_apm_sign == 0) /* result is 0 */ + { + if (places < 0) + { + cpd[0] = '0'; /* "0.0" */ + cpd[1] = '.'; + cpd[2] = '0'; + cpd[3] = '\0'; + } + else + { + memset(cpd, '0', (places + 2)); /* pre-load string with all '0' */ + cpd[1] = '.'; + cpd[places + 2] = '\0'; + } + + M_restore_stack(1); + return; + } + + xp = ctmp->m_apm_exponent; + dl = ctmp->m_apm_datalength; + numb = (dl + 1) >> 1; + + if (places < 0) + { + if (dl > xp) + jj = dl + 16; + else + jj = xp + 16; + } + else + { + jj = places + 16; + + if (xp > 0) + jj += xp; + } + + if (jj > 112) + { + if ((vp = (void *)MAPM_MALLOC((jj + 16) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'m_apm_to_fixpt_string\', Out of memory"); + } + + cpw = (char *)vp; + } + else + { + cpw = sbuf; + } + + /* + * at this point, the number is non-zero and the output + * string will contain at least 1 significant digit. + */ + + if (ctmp->m_apm_sign == -1) /* negative number */ + { + *cpd++ = '-'; + } + + ucp = ctmp->m_apm_data; + ii = 0; + + /* convert MAPM num to ASCII digits and store in working char array */ + + while (TRUE) + { + M_get_div_rem_10((int)(*ucp++), &numdiv, &numrem); + + cpw[ii++] = numdiv + '0'; + cpw[ii++] = numrem + '0'; + + if (--numb == 0) + break; + } + + i2 = ii; /* save for later */ + + if (places < 0) /* show ALL digits */ + { + places = dl - xp; + + if (places < 1) + places = 1; + } + + /* pad with trailing zeros if needed */ + + kk = xp + places + 2 - ii; + + if (kk > 0) + memset(&cpw[ii], '0', kk); + + if (xp > 0) /* |num| >= 1, NO lead-in "0.nnn" */ + { + ii = xp + places + 1; + jj = 0; + + for (kk = 0; kk < ii; kk++) + { + if (kk == xp) + cpd[jj++] = '.'; + + cpd[jj++] = cpw[kk]; + } + + cpd[ii] = '\0'; + } + else /* |num| < 1, have lead-in "0.nnn" */ + { + jj = 2 - xp; + ii = 2 + places; + memset(cpd, '0', (ii + 1)); /* pre-load string with all '0' */ + cpd[1] = '.'; /* assign decimal point */ + + for (kk = 0; kk < i2; kk++) + { + cpd[jj++] = cpw[kk]; + } + + cpd[ii] = '\0'; + } + + if (vp != NULL) + MAPM_FREE(vp); + + M_restore_stack(1); +} +/****************************************************************************/ +void M_apm_round_fixpt(M_APM btmp, int places, M_APM atmp) +{ + int xp, ii; + + xp = atmp->m_apm_exponent; + ii = xp + places - 1; + + M_set_to_zero(btmp); /* assume number is too small so the net result is 0 */ + + if (ii >= 0) + { + m_apm_round(btmp, ii, atmp); + } + else + { + if (ii == -1) /* next digit is significant which may round up */ + { + if (atmp->m_apm_data[0] >= 50) /* digit >= 5, round up */ + { + m_apm_copy(btmp, atmp); + btmp->m_apm_data[0] = 10; + btmp->m_apm_exponent += 1; + btmp->m_apm_datalength = 1; + M_apm_normalize(btmp); + } + } + } +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapm_gcd.cpp b/pgscript/utilities/m_apm/mapm_gcd.cpp new file mode 100644 index 0000000..d3d136a --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_gcd.cpp @@ -0,0 +1,260 @@ + +/* + * M_APM - mapm_gcd.c + * + * Copyright (C) 2001 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the GCD and LCM functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * From Knuth, The Art of Computer Programming: + * + * This is the binary GCD algorithm as described + * in the book (Algorithm B) + */ +void m_apm_gcd(M_APM r, M_APM u, M_APM v) +{ + M_APM tmpM, tmpN, tmpT, tmpU, tmpV; + int kk, kr, mm; + long pow_2; + + /* 'is_integer' will return 0 || 1 */ + + if ((m_apm_is_integer(u) + m_apm_is_integer(v)) != 2) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_gcd\', Non-integer input"); + + M_set_to_zero(r); + return; + } + + if (u->m_apm_sign == 0) + { + m_apm_absolute_value(r, v); + return; + } + + if (v->m_apm_sign == 0) + { + m_apm_absolute_value(r, u); + return; + } + + tmpM = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmpT = M_get_stack_var(); + tmpU = M_get_stack_var(); + tmpV = M_get_stack_var(); + + m_apm_absolute_value(tmpU, u); + m_apm_absolute_value(tmpV, v); + + /* Step B1 */ + + kk = 0; + + while (TRUE) + { + mm = 1; + if (m_apm_is_odd(tmpU)) + break; + + mm = 0; + if (m_apm_is_odd(tmpV)) + break; + + m_apm_multiply(tmpN, MM_0_5, tmpU); + m_apm_copy(tmpU, tmpN); + + m_apm_multiply(tmpN, MM_0_5, tmpV); + m_apm_copy(tmpV, tmpN); + + kk++; + } + + /* Step B2 */ + + if (mm) + { + m_apm_negate(tmpT, tmpV); + goto B4; + } + + m_apm_copy(tmpT, tmpU); + + /* Step: */ + +B3: + + m_apm_multiply(tmpN, MM_0_5, tmpT); + m_apm_copy(tmpT, tmpN); + + /* Step: */ + +B4: + + if (m_apm_is_even(tmpT)) + goto B3; + + /* Step B5 */ + + if (tmpT->m_apm_sign == 1) + m_apm_copy(tmpU, tmpT); + else + m_apm_negate(tmpV, tmpT); + + /* Step B6 */ + + m_apm_subtract(tmpT, tmpU, tmpV); + + if (tmpT->m_apm_sign != 0) + goto B3; + + /* + * result = U * 2 ^ kk + */ + + if (kk == 0) + m_apm_copy(r, tmpU); + else + { + if (kk == 1) + m_apm_multiply(r, tmpU, MM_Two); + + if (kk == 2) + m_apm_multiply(r, tmpU, MM_Four); + + if (kk >= 3) + { + mm = kk / 28; + kr = kk % 28; + pow_2 = 1L << kr; + + if (mm == 0) + { + m_apm_set_long(tmpN, pow_2); + m_apm_multiply(r, tmpU, tmpN); + } + else + { + m_apm_copy(tmpN, MM_One); + m_apm_set_long(tmpM, 0x10000000L); /* 2 ^ 28 */ + + while (TRUE) + { + m_apm_multiply(tmpT, tmpN, tmpM); + m_apm_copy(tmpN, tmpT); + + if (--mm == 0) + break; + } + + if (kr == 0) + { + m_apm_multiply(r, tmpU, tmpN); + } + else + { + m_apm_set_long(tmpM, pow_2); + m_apm_multiply(tmpT, tmpN, tmpM); + m_apm_multiply(r, tmpU, tmpT); + } + } + } + } + + M_restore_stack(5); +} +/****************************************************************************/ +/* + * u * v + * LCM(u,v) = ------------ + * GCD(u,v) + */ + +void m_apm_lcm(M_APM r, M_APM u, M_APM v) +{ + M_APM tmpN, tmpG; + + tmpN = M_get_stack_var(); + tmpG = M_get_stack_var(); + + m_apm_multiply(tmpN, u, v); + m_apm_gcd(tmpG, u, v); + m_apm_integer_divide(r, tmpN, tmpG); + + M_restore_stack(2); +} +/****************************************************************************/ + +#ifdef BIG_COMMENT_BLOCK + +/* + * traditional GCD included for reference + * (also useful for testing ...) + */ + +/* + * From Knuth, The Art of Computer Programming: + * + * To compute GCD(u,v) + * + * A1: + * if (v == 0) return (u) + * A2: + * t = u mod v + * u = v + * v = t + * goto A1 + */ +void m_apm_gcd_traditional(M_APM r, M_APM u, M_APM v) +{ + M_APM tmpD, tmpN, tmpU, tmpV; + + tmpD = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmpU = M_get_stack_var(); + tmpV = M_get_stack_var(); + + m_apm_absolute_value(tmpU, u); + m_apm_absolute_value(tmpV, v); + + while (TRUE) + { + if (tmpV->m_apm_sign == 0) + break; + + m_apm_integer_div_rem(tmpD, tmpN, tmpU, tmpV); + m_apm_copy(tmpU, tmpV); + m_apm_copy(tmpV, tmpN); + } + + m_apm_copy(r, tmpU); + M_restore_stack(4); +} +/****************************************************************************/ + +#endif + diff --git a/pgscript/utilities/m_apm/mapm_lg2.cpp b/pgscript/utilities/m_apm/mapm_lg2.cpp new file mode 100644 index 0000000..8810650 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_lg2.cpp @@ -0,0 +1,152 @@ + +/* + * M_APM - mapm_lg2.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the iterative function to compute the LOG + * This is an internal function to the library and is not intended + * to be called directly by the user. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ + +/* + * compute rr = log(nn) + * + * input is assumed to not exceed the exponent range of a normal + * 'C' double ( |exponent| must be < 308) + */ + +/****************************************************************************/ +void M_log_solve_cubic(M_APM rr, int places, M_APM nn) +{ + M_APM tmp0, tmp1, tmp2, tmp3, guess; + int ii, maxp, tolerance, local_precision; + + guess = M_get_stack_var(); + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + M_get_log_guess(guess, nn); + + tolerance = -(places + 4); + maxp = places + 16; + local_precision = 18; + + /* Use the following iteration to solve for log : + + exp(X) - N + X = X - 2 * ------------ + n+1 exp(X) + N + + + this is a cubically convergent algorithm + (each iteration yields 3X more digits) + */ + + ii = 0; + + while (TRUE) + { + m_apm_exp(tmp1, local_precision, guess); + + m_apm_subtract(tmp3, tmp1, nn); + m_apm_add(tmp2, tmp1, nn); + + m_apm_divide(tmp1, local_precision, tmp3, tmp2); + m_apm_multiply(tmp0, MM_Two, tmp1); + m_apm_subtract(tmp3, guess, tmp0); + + if (ii != 0) + { + if (((3 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0)) + break; + } + + m_apm_round(guess, local_precision, tmp3); + + local_precision *= 3; + + if (local_precision > maxp) + local_precision = maxp; + + ii = 1; + } + + m_apm_round(rr, places, tmp3); + M_restore_stack(5); +} +/****************************************************************************/ +/* + * find log(N) + * + * if places < 360 + * solve with cubically convergent algorithm above + * + * else + * + * let 'X' be 'close' to the solution (we use ~110 decimal places) + * + * let Y = N * exp(-X) - 1 + * + * then + * + * log(N) = X + log(1 + Y) + * + * since 'Y' will be small, we can use the efficient log_near_1 algorithm. + * + */ +void M_log_basic_iteration(M_APM rr, int places, M_APM nn) +{ + M_APM tmp0, tmp1, tmp2, tmpX; + + if (places < 360) + { + M_log_solve_cubic(rr, places, nn); + } + else + { + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmpX = M_get_stack_var(); + + M_log_solve_cubic(tmpX, 110, nn); + + m_apm_negate(tmp0, tmpX); + m_apm_exp(tmp1, (places + 8), tmp0); + m_apm_multiply(tmp2, tmp1, nn); + m_apm_subtract(tmp1, tmp2, MM_One); + + M_log_near_1(tmp0, (places - 104), tmp1); + + m_apm_add(tmp1, tmpX, tmp0); + m_apm_round(rr, places, tmp1); + + M_restore_stack(4); + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_lg3.cpp b/pgscript/utilities/m_apm/mapm_lg3.cpp new file mode 100644 index 0000000..1059e18 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_lg3.cpp @@ -0,0 +1,204 @@ + +/* + * M_APM - mapm_lg3.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the function to compute log(2), log(10), + * and 1/log(10) to the desired precision using an AGM algorithm. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/* + * using the 'R' function (defined below) for 'N' decimal places : + * + * + * -N -N + * log(2) = R(1, 0.5 * 10 ) - R(1, 10 ) + * + * + * -N -N + * log(10) = R(1, 0.1 * 10 ) - R(1, 10 ) + * + * + * In general: + * + * -N -N + * log(x) = R(1, 10 / x) - R(1, 10 ) + * + * + * I found this on a web site which went into considerable detail + * on the history of log(2). This formula is algebraically identical + * to the formula specified in J. Borwein and P. Borwein's book + * "PI and the AGM". (reference algorithm 7.2) + */ + +/****************************************************************************/ +/* + * check if our local copy of log(2) & log(10) is precise + * enough for our purpose. if not, calculate them so it's + * as precise as desired, accurate to at least 'places'. + */ +void M_check_log_places(int places) +{ + M_APM tmp6, tmp7, tmp8, tmp9; + int dplaces; + + dplaces = places + 4; + + if (dplaces > MM_lc_log_digits) + { + MM_lc_log_digits = dplaces + 4; + + tmp6 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + dplaces += 6 + (int)log10((double)places); + + m_apm_copy(tmp7, MM_One); + tmp7->m_apm_exponent = -places; + + M_log_AGM_R_func(tmp8, dplaces, MM_One, tmp7); + + m_apm_multiply(tmp6, tmp7, MM_0_5); + + M_log_AGM_R_func(tmp9, dplaces, MM_One, tmp6); + + m_apm_subtract(MM_lc_log2, tmp9, tmp8); /* log(2) */ + + tmp7->m_apm_exponent -= 1; /* divide by 10 */ + + M_log_AGM_R_func(tmp9, dplaces, MM_One, tmp7); + + m_apm_subtract(MM_lc_log10, tmp9, tmp8); /* log(10) */ + m_apm_reciprocal(MM_lc_log10R, dplaces, MM_lc_log10); /* 1 / log(10) */ + + M_restore_stack(4); + } +} +/****************************************************************************/ + +/* + * define a notation for a function 'R' : + * + * + * + * 1 + * R (a0, b0) = ------------------------------ + * + * ---- + * \ + * \ n-1 2 2 + * 1 - | 2 * (a - b ) + * / n n + * / + * ---- + * n >= 0 + * + * + * where a, b are the classic AGM iteration : + * + * + * a = 0.5 * (a + b ) + * n+1 n n + * + * + * b = sqrt(a * b ) + * n+1 n n + * + * + * + * define a variable 'c' for more efficient computation : + * + * 2 2 2 + * c = 0.5 * (a - b ) , c = a - b + * n+1 n n n n n + * + */ + +/****************************************************************************/ +void M_log_AGM_R_func(M_APM rr, int places, M_APM aa, M_APM bb) +{ + M_APM tmp1, tmp2, tmp3, tmp4, tmpC2, sum, pow_2, tmpA0, tmpB0; + int tolerance, dplaces; + + tmpA0 = M_get_stack_var(); + tmpB0 = M_get_stack_var(); + tmpC2 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + tmp4 = M_get_stack_var(); + sum = M_get_stack_var(); + pow_2 = M_get_stack_var(); + + tolerance = places + 8; + dplaces = places + 16; + + m_apm_copy(tmpA0, aa); + m_apm_copy(tmpB0, bb); + m_apm_copy(pow_2, MM_0_5); + + m_apm_multiply(tmp1, aa, aa); /* 0.5 * [ a ^ 2 - b ^ 2 ] */ + m_apm_multiply(tmp2, bb, bb); + m_apm_subtract(tmp3, tmp1, tmp2); + m_apm_multiply(sum, MM_0_5, tmp3); + + while (TRUE) + { + m_apm_subtract(tmp1, tmpA0, tmpB0); /* C n+1 = 0.5 * [ An - Bn ] */ + m_apm_multiply(tmp4, MM_0_5, tmp1); /* C n+1 */ + m_apm_multiply(tmpC2, tmp4, tmp4); /* C n+1 ^ 2 */ + + /* do the AGM */ + + m_apm_add(tmp1, tmpA0, tmpB0); + m_apm_multiply(tmp3, MM_0_5, tmp1); + + m_apm_multiply(tmp2, tmpA0, tmpB0); + m_apm_sqrt(tmpB0, dplaces, tmp2); + + m_apm_round(tmpA0, dplaces, tmp3); + + /* end AGM */ + + m_apm_multiply(tmp2, MM_Two, pow_2); + m_apm_copy(pow_2, tmp2); + + m_apm_multiply(tmp1, tmpC2, pow_2); + m_apm_add(tmp3, sum, tmp1); + + if ((tmp1->m_apm_sign == 0) || + ((-2 * tmp1->m_apm_exponent) > tolerance)) + break; + + m_apm_round(sum, dplaces, tmp3); + } + + m_apm_subtract(tmp4, MM_One, tmp3); + m_apm_reciprocal(rr, places, tmp4); + + M_restore_stack(9); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_lg4.cpp b/pgscript/utilities/m_apm/mapm_lg4.cpp new file mode 100644 index 0000000..a037f43 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_lg4.cpp @@ -0,0 +1,93 @@ + +/* + * M_APM - mapm_lg4.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the LOG_NEAR_1 function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + calculate log (1 + x) with the following series: + + x + y = ----- ( |y| < 1 ) + x + 2 + + + [ 1 + y ] y^3 y^5 y^7 + log [-------] = 2 * [ y + --- + --- + --- ... ] + [ 1 - y ] 3 5 7 + +*/ +void M_log_near_1(M_APM rr, int places, M_APM xx) +{ + M_APM tmp0, tmp1, tmp2, tmpS, term; + int tolerance, dplaces, local_precision; + long m1; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmpS = M_get_stack_var(); + term = M_get_stack_var(); + + tolerance = xx->m_apm_exponent - (places + 6); + dplaces = (places + 12) - xx->m_apm_exponent; + + m_apm_add(tmp0, xx, MM_Two); + m_apm_divide(tmpS, (dplaces + 6), xx, tmp0); + + m_apm_copy(term, tmpS); + m_apm_multiply(tmp0, tmpS, tmpS); + m_apm_round(tmp2, (dplaces + 6), tmp0); + + m1 = 3L; + + while (TRUE) + { + m_apm_multiply(tmp0, term, tmp2); + + if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0)) + break; + + local_precision = dplaces + tmp0->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m_apm_set_long(tmp1, m1); + m_apm_round(term, local_precision, tmp0); + m_apm_divide(tmp0, local_precision, term, tmp1); + m_apm_add(tmp1, tmpS, tmp0); + m_apm_copy(tmpS, tmp1); + m1 += 2; + } + + m_apm_multiply(tmp0, MM_Two, tmpS); + m_apm_round(rr, places, tmp0); + + M_restore_stack(5); /* restore the 5 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_log.cpp b/pgscript/utilities/m_apm/mapm_log.cpp new file mode 100644 index 0000000..9066120 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_log.cpp @@ -0,0 +1,138 @@ + +/* + * M_APM - mapm_log.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the LOG and LOG10 functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + Calls the LOG function. The formula used is : + + log10(x) = A * log(x) where A = log (e) [0.43429448190325...] + 10 +*/ +void m_apm_log10(M_APM rr, int places, M_APM aa) +{ + int dplaces; + M_APM tmp8, tmp9; + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + dplaces = places + 4; + M_check_log_places(dplaces + 45); + + m_apm_log(tmp9, dplaces, aa); + m_apm_multiply(tmp8, tmp9, MM_lc_log10R); + m_apm_round(rr, places, tmp8); + M_restore_stack(2); /* restore the 2 locals we used here */ +} +/****************************************************************************/ +void m_apm_log(M_APM r, int places, M_APM a) +{ + M_APM tmp0, tmp1, tmp2; + int mexp, dplaces; + + if (a->m_apm_sign <= 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_log\', Negative argument"); + M_set_to_zero(r); + return; + } + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + dplaces = places + 8; + + /* + * if the input is real close to 1, use the series expansion + * to compute the log. + * + * 0.9999 < a < 1.0001 + */ + + mexp = a->m_apm_exponent; + + if (mexp == 0 || mexp == 1) + { + m_apm_subtract(tmp0, a, MM_One); + + if (tmp0->m_apm_sign == 0) /* is input exactly 1 ?? */ + { + /* if so, result is 0 */ + M_set_to_zero(r); + M_restore_stack(3); + return; + } + + if (tmp0->m_apm_exponent <= -4) + { + M_log_near_1(r, places, tmp0); + M_restore_stack(3); + return; + } + } + + /* make sure our log(10) is accurate enough for this calculation */ + /* (and log(2) which is called from M_log_basic_iteration) */ + + M_check_log_places(dplaces + 25); + + if (abs(mexp) <= 3) + { + M_log_basic_iteration(r, places, a); + } + else + { + /* + * use log (x * y) = log(x) + log(y) + * + * here we use y = exponent of our base 10 number. + * + * let 'C' = log(10) = 2.3025850929940.... + * + * then log(x * y) = log(x) + ( C * base_10_exponent ) + */ + + m_apm_copy(tmp2, a); + + mexp = tmp2->m_apm_exponent - 2; + tmp2->m_apm_exponent = 2; /* force number between 10 & 100 */ + + M_log_basic_iteration(tmp0, dplaces, tmp2); + + m_apm_set_long(tmp1, (long)mexp); + m_apm_multiply(tmp2, tmp1, MM_lc_log10); + m_apm_add(tmp1, tmp2, tmp0); + + m_apm_round(r, places, tmp1); + } + + M_restore_stack(3); /* restore the 3 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_mul.cpp b/pgscript/utilities/m_apm/mapm_mul.cpp new file mode 100644 index 0000000..3ace4f8 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_mul.cpp @@ -0,0 +1,131 @@ + +/* + * M_APM - mapm_mul.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains basic multiplication function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +extern void M_fast_multiply(M_APM, M_APM, M_APM); + +/****************************************************************************/ +void m_apm_multiply(M_APM r, M_APM a, M_APM b) +{ + int ai, itmp, sign, nexp, ii, jj, indexa, indexb, index0, numdigits; + UCHAR *cp, *cpr, *cp_div, *cp_rem; + void *vp; + + sign = a->m_apm_sign * b->m_apm_sign; + nexp = a->m_apm_exponent + b->m_apm_exponent; + + if (sign == 0) /* one number is zero, result is zero */ + { + M_set_to_zero(r); + return; + } + + numdigits = a->m_apm_datalength + b->m_apm_datalength; + indexa = (a->m_apm_datalength + 1) >> 1; + indexb = (b->m_apm_datalength + 1) >> 1; + + /* + * If we are multiplying 2 'big' numbers, use the fast algorithm. + * + * This is a **very** approx break even point between this algorithm + * and the FFT multiply. Note that different CPU's, operating systems, + * and compiler's may yield a different break even point. This point + * (~96 decimal digits) is how the test came out on the author's system. + */ + + if (indexa >= 48 && indexb >= 48) + { + M_fast_multiply(r, a, b); + return; + } + + ii = (numdigits + 1) >> 1; /* required size of result, in bytes */ + + if (ii > r->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(r->m_apm_data, (ii + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_multiply\', Out of memory"); + } + + r->m_apm_malloclength = ii + 28; + r->m_apm_data = (UCHAR *)vp; + } + + M_get_div_rem_addr(&cp_div, &cp_rem); + + index0 = indexa + indexb; + cp = r->m_apm_data; + memset(cp, 0, index0); + ii = indexa; + + while (TRUE) + { + index0--; + cpr = cp + index0; + jj = indexb; + ai = (int)a->m_apm_data[--ii]; + + while (TRUE) + { + itmp = ai * b->m_apm_data[--jj]; + + *(cpr - 1) += cp_div[itmp]; + *cpr += cp_rem[itmp]; + + if (*cpr >= 100) + { + *cpr -= 100; + *(cpr - 1) += 1; + } + + cpr--; + + if (*cpr >= 100) + { + *cpr -= 100; + *(cpr - 1) += 1; + } + + if (jj == 0) + break; + } + + if (ii == 0) + break; + } + + r->m_apm_sign = sign; + r->m_apm_exponent = nexp; + r->m_apm_datalength = numdigits; + + M_apm_normalize(r); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_pow.cpp b/pgscript/utilities/m_apm/mapm_pow.cpp new file mode 100644 index 0000000..cf0a22f --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_pow.cpp @@ -0,0 +1,147 @@ + +/* + * M_APM - mapm_pow.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the POW function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static M_APM M_last_xx_input; +static M_APM M_last_xx_log; +static int M_last_log_digits; +static int M_size_flag = 0; + +/****************************************************************************/ +void M_free_all_pow() +{ + if (M_size_flag != 0) + { + m_apm_free(M_last_xx_input); + m_apm_free(M_last_xx_log); + M_size_flag = 0; + } +} +/****************************************************************************/ +/* + Calculate the POW function by calling EXP : + + Y A + X = e where A = Y * log(X) +*/ +void m_apm_pow(M_APM rr, int places, M_APM xx, M_APM yy) +{ + int iflag, pflag; + char sbuf[64]; + M_APM tmp8, tmp9; + + /* if yy == 0, return 1 */ + + if (yy->m_apm_sign == 0) + { + m_apm_copy(rr, MM_One); + return; + } + + /* if xx == 0, return 0 */ + + if (xx->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + if (M_size_flag == 0) /* init locals on first call */ + { + M_size_flag = M_get_sizeof_int(); + M_last_log_digits = 0; + M_last_xx_input = m_apm_init(); + M_last_xx_log = m_apm_init(); + } + + /* + * if 'yy' is a small enough integer, call the more + * efficient _integer_pow function. + */ + + if (m_apm_is_integer(yy)) + { + iflag = FALSE; + + if (M_size_flag == 2) /* 16 bit compilers */ + { + if (yy->m_apm_exponent <= 4) + iflag = TRUE; + } + else /* >= 32 bit compilers */ + { + if (yy->m_apm_exponent <= 7) + iflag = TRUE; + } + + if (iflag) + { + m_apm_to_integer_string(sbuf, yy); + m_apm_integer_pow(rr, places, xx, atoi(sbuf)); + return; + } + } + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + /* + * If parameter 'X' is the same this call as it + * was the previous call, re-use the saved log + * calculation from last time. + */ + + pflag = FALSE; + + if (M_last_log_digits >= places) + { + if (m_apm_compare(xx, M_last_xx_input) == 0) + pflag = TRUE; + } + + if (pflag) + { + m_apm_round(tmp9, (places + 8), M_last_xx_log); + } + else + { + m_apm_log(tmp9, (places + 8), xx); + + M_last_log_digits = places + 2; + + /* save the 'X' input value and the log calculation */ + + m_apm_copy(M_last_xx_input, xx); + m_apm_copy(M_last_xx_log, tmp9); + } + + m_apm_multiply(tmp8, tmp9, yy); + m_apm_exp(rr, places, tmp8); + M_restore_stack(2); /* restore the 2 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_rcp.cpp b/pgscript/utilities/m_apm/mapm_rcp.cpp new file mode 100644 index 0000000..0709a12 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_rcp.cpp @@ -0,0 +1,168 @@ + +/* + * M_APM - mapm_rcp.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the fast division and reciprocal functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_divide(M_APM rr, int places, M_APM aa, M_APM bb) +{ + M_APM tmp0, tmp1; + int sn, nexp, dplaces; + + sn = aa->m_apm_sign * bb->m_apm_sign; + + if (sn == 0) /* one number is zero, result is zero */ + { + if (bb->m_apm_sign == 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_divide\', Divide by 0"); + } + + M_set_to_zero(rr); + return; + } + + /* + * Use the original 'Knuth' method for smaller divides. On the + * author's system, this was the *approx* break even point before + * the reciprocal method used below became faster. + */ + + if (places < 250) + { + M_apm_sdivide(rr, places, aa, bb); + return; + } + + /* mimic the decimal place behavior of the original divide */ + + nexp = aa->m_apm_exponent - bb->m_apm_exponent; + + if (nexp > 0) + dplaces = nexp + places; + else + dplaces = places; + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + + m_apm_reciprocal(tmp0, (dplaces + 8), bb); + m_apm_multiply(tmp1, tmp0, aa); + m_apm_round(rr, dplaces, tmp1); + + M_restore_stack(2); +} +/****************************************************************************/ +void m_apm_reciprocal(M_APM rr, int places, M_APM aa) +{ + M_APM last_x, guess, tmpN, tmp1, tmp2; + char sbuf[32]; + int ii, bflag, dplaces, nexp, tolerance; + + if (aa->m_apm_sign == 0) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_reciprocal\', Input = 0"); + + M_set_to_zero(rr); + return; + } + + last_x = M_get_stack_var(); + guess = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_absolute_value(tmpN, aa); + + /* + normalize the input number (make the exponent 0) so + the 'guess' below will not over/under flow on large + magnitude exponents. + */ + + nexp = aa->m_apm_exponent; + tmpN->m_apm_exponent -= nexp; + + m_apm_to_string(sbuf, 15, tmpN); + m_apm_set_double(guess, (1.0 / atof(sbuf))); + + tolerance = places + 4; + dplaces = places + 16; + bflag = FALSE; + + m_apm_negate(last_x, MM_Ten); + + /* Use the following iteration to calculate the reciprocal : + + + X = X * [ 2 - N * X ] + n+1 + */ + + ii = 0; + + while (TRUE) + { + m_apm_multiply(tmp1, tmpN, guess); + m_apm_subtract(tmp2, MM_Two, tmp1); + m_apm_multiply(tmp1, tmp2, guess); + + if (bflag) + break; + + m_apm_round(guess, dplaces, tmp1); + + /* force at least 2 iterations so 'last_x' has valid data */ + + if (ii != 0) + { + m_apm_subtract(tmp2, guess, last_x); + + if (tmp2->m_apm_sign == 0) + break; + + /* + * if we are within a factor of 4 on the error term, + * we will be accurate enough after the *next* iteration + * is complete. + */ + + if ((-4 * tmp2->m_apm_exponent) > tolerance) + bflag = TRUE; + } + + m_apm_copy(last_x, guess); + ii++; + } + + m_apm_round(rr, places, tmp1); + rr->m_apm_exponent -= nexp; + rr->m_apm_sign = aa->m_apm_sign; + M_restore_stack(5); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_rnd.cpp b/pgscript/utilities/m_apm/mapm_rnd.cpp new file mode 100644 index 0000000..66ca0fa --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_rnd.cpp @@ -0,0 +1,360 @@ + +/* + * M_APM - mapm_rnd.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Random Number Generator function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +#ifndef _HAVE_NI_LABWIN_CVI_ +#ifdef MSDOS +#include +#include +#else +#include +extern void M_get_microsec(unsigned long *, long *); +#endif +#endif + +#ifdef _HAVE_NI_LABWIN_CVI_ +#include +#include +#include +#endif + +extern void M_reverse_string(char *); +extern void M_get_rnd_seed(M_APM); + +static M_APM M_rnd_aa; +static M_APM M_rnd_mm; +static M_APM M_rnd_XX; +static M_APM M_rtmp0; +static M_APM M_rtmp1; + +static int M_firsttime2 = TRUE; + +/* + Used Knuth's The Art of Computer Programming, Volume 2 as + the basis. Assuming the random number is X, compute + (where all the math is performed on integers) : + + X = (a * X + c) MOD m + + From Knuth: + + 'm' should be large, at least 2^30 : we use 1.0E+15 + + 'a' should be between .01m and .99m and not have a simple + pattern. 'a' should not have any large factors in common + with 'm' and (since 'm' is a power of 10) if 'a' MOD 200 + = 21 then all 'm' different possible values will be + generated before 'X' starts to repeat. + + We use 'a' = 716805947629621. + + This is a prime number and also meets 'a' MOD 200 = 21. + Commented out below are many potential multipliers that + are all prime and meet 'a' MOD 200 = 21. + + There are few restrictions on 'c' except 'c' can have no + factor in common with 'm', hence we set 'c' = 'a'. + + On the first call, the system time is used to initialize X. +*/ + +/* + * the following constants are all potential multipliers. they are + * all prime numbers that also meet the criteria of NUM mod 200 = 21. + */ + +/* +439682071525421 439682071528421 439682071529221 439682071529821 +439682071530421 439682071532021 439682071538821 439682071539421 +439682071540021 439682071547021 439682071551221 439682071553821 +439682071555421 439682071557221 439682071558021 439682071558621 +439682071559821 439652381461621 439652381465221 439652381465621 +439652381466421 439652381467421 439652381468621 439652381470021 +439652381471221 439652381477021 439652381484221 439652381488421 +439652381491021 439652381492021 439652381494021 439652381496821 +617294387035621 617294387038621 617294387039221 617294387044421 +617294387045221 617294387048621 617294387051621 617294387051821 +617294387053621 617294387058421 617294387064221 617294387065621 +617294387068621 617294387069221 617294387069821 617294387070421 +617294387072021 617294387072621 617294387073821 617294387076821 +649378126517621 649378126517821 649378126518221 649378126520821 +649378126523821 649378126525621 649378126526621 649378126528421 +649378126529621 649378126530821 649378126532221 649378126533221 +649378126535221 649378126539421 649378126543621 649378126546021 +649378126546421 649378126549421 649378126550821 649378126555021 +649378126557421 649378126560221 649378126561621 649378126562021 +649378126564621 649378126565821 672091582360421 672091582364221 +672091582364621 672091582367021 672091582368421 672091582369021 +672091582370821 672091582371421 672091582376821 672091582380821 +716805243983221 716805243984821 716805947623621 716805947624621 +716805947629021 716805947629621 716805947630621 716805947633621 +716805947634221 716805947635021 716805947635621 716805947642221 +*/ + +/****************************************************************************/ +void M_free_all_rnd() +{ + if (M_firsttime2 == FALSE) + { + m_apm_free(M_rnd_aa); + m_apm_free(M_rnd_mm); + m_apm_free(M_rnd_XX); + m_apm_free(M_rtmp0); + m_apm_free(M_rtmp1); + + M_firsttime2 = TRUE; + } +} +/****************************************************************************/ +void m_apm_set_random_seed(char *ss) +{ + M_APM btmp; + + if (M_firsttime2) + { + btmp = M_get_stack_var(); + m_apm_get_random(btmp); + M_restore_stack(1); + } + + m_apm_set_string(M_rnd_XX, ss); +} +/****************************************************************************/ +/* + * compute X = (a * X + c) MOD m where c = a + */ +void m_apm_get_random(M_APM mrnd) +{ + + if (M_firsttime2) /* use the system time as the initial seed value */ + { + M_firsttime2 = FALSE; + + M_rnd_aa = m_apm_init(); + M_rnd_XX = m_apm_init(); + M_rnd_mm = m_apm_init(); + M_rtmp0 = m_apm_init(); + M_rtmp1 = m_apm_init(); + + /* set the multiplier M_rnd_aa and M_rnd_mm */ + + m_apm_set_string(M_rnd_aa, "716805947629621"); + m_apm_set_string(M_rnd_mm, "1.0E15"); + + M_get_rnd_seed(M_rnd_XX); + } + + m_apm_multiply(M_rtmp0, M_rnd_XX, M_rnd_aa); + m_apm_add(M_rtmp1, M_rtmp0, M_rnd_aa); + m_apm_integer_div_rem(M_rtmp0, M_rnd_XX, M_rtmp1, M_rnd_mm); + m_apm_copy(mrnd, M_rnd_XX); + mrnd->m_apm_exponent -= 15; +} +/****************************************************************************/ +void M_reverse_string(char *s) +{ + int ct; + char ch, *p1, *p2; + + if ((ct = strlen(s)) <= 1) + return; + + p1 = s; + p2 = s + ct - 1; + ct /= 2; + + while (TRUE) + { + ch = *p1; + *p1++ = *p2; + *p2-- = ch; + + if (--ct == 0) + break; + } +} +/****************************************************************************/ + +#ifndef _HAVE_NI_LABWIN_CVI_ + +#ifdef MSDOS + +/****************************************************************************/ +/* + * for DOS / Win 9x/NT systems : use 'ftime' + */ +void M_get_rnd_seed(M_APM mm) +{ + int millisec; + time_t timestamp; + unsigned long ul; + char ss[32], buf1[48], buf2[32]; + struct timeb timebuffer; + M_APM atmp; + + atmp = M_get_stack_var(); + + ftime(&timebuffer); + + millisec = (int)timebuffer.millitm; + timestamp = timebuffer.time; + ul = (unsigned long)(timestamp / 7); + ul += timestamp + 537; + strcpy(ss, ctime(×tamp)); /* convert to string and copy to ss */ + + sprintf(buf1, "%d", (millisec / 10)); + sprintf(buf2, "%lu", ul); + + ss[0] = ss[18]; + ss[1] = ss[17]; + ss[2] = ss[15]; + ss[3] = ss[14]; + ss[4] = ss[12]; + ss[5] = ss[11]; + ss[6] = ss[9]; + ss[7] = ss[23]; + ss[8] = ss[20]; + ss[9] = '\0'; + + M_reverse_string(buf2); + strcat(buf1, buf2); + strcat(buf1, ss); + + m_apm_set_string(atmp, buf1); + atmp->m_apm_exponent = 15; + m_apm_integer_divide(mm, atmp, MM_One); + + M_restore_stack(1); +} +/****************************************************************************/ + +#else + +/****************************************************************************/ +/* + * for unix systems : use 'gettimeofday' + */ +void M_get_rnd_seed(M_APM mm) +{ + unsigned long sec3; + long usec3; + char buf1[32], buf2[32]; + M_APM atmp; + + atmp = M_get_stack_var(); + M_get_microsec(&sec3, &usec3); + + sprintf(buf1, "%ld", usec3); + sprintf(buf2, "%lu", sec3); + M_reverse_string(buf2); + strcat(buf1, buf2); + + m_apm_set_string(atmp, buf1); + atmp->m_apm_exponent = 15; + m_apm_integer_divide(mm, atmp, MM_One); + + M_restore_stack(1); +} +/****************************************************************************/ +void M_get_microsec(unsigned long *sec, long *usec) +{ + struct timeval time_now; /* current time for elapsed time check */ + struct timezone time_zone; /* time zone for gettimeofday call */ + + gettimeofday(&time_now, &time_zone); /* get current time */ + + *sec = time_now.tv_sec; + *usec = time_now.tv_usec; +} +/****************************************************************************/ + +#endif +#endif + +#ifdef _HAVE_NI_LABWIN_CVI_ + +/****************************************************************************/ +/* + * for National Instruments LabWindows CVI + */ + +void M_get_rnd_seed(M_APM mm) +{ + double timer0; + int millisec; + char *cvi_time, *cvi_date, buf1[64], buf2[32]; + M_APM atmp; + + atmp = M_get_stack_var(); + + cvi_date = DateStr(); + cvi_time = TimeStr(); + timer0 = Timer(); + + /* + * note that Timer() is not syncronized to TimeStr(), + * but we don't care here since we are just looking + * for a random source of digits. + */ + + millisec = (int)(0.01 + 1000.0 * (timer0 - floor(timer0))); + + sprintf(buf1, "%d", millisec); + + buf2[0] = cvi_time[6]; /* time format: "HH:MM:SS" */ + buf2[1] = cvi_time[7]; + buf2[2] = cvi_time[3]; + buf2[3] = cvi_time[4]; + buf2[4] = cvi_time[0]; + buf2[5] = cvi_time[1]; + + buf2[6] = cvi_date[3]; /* date format: "MM-DD-YYYY" */ + buf2[7] = cvi_date[4]; + buf2[8] = cvi_date[0]; + buf2[9] = cvi_date[1]; + buf2[10] = cvi_date[8]; + buf2[11] = cvi_date[9]; + buf2[12] = cvi_date[7]; + + buf2[13] = '4'; + buf2[14] = '7'; + buf2[15] = '\0'; + + strcat(buf1, buf2); + + m_apm_set_string(atmp, buf1); + atmp->m_apm_exponent = 15; + m_apm_integer_divide(mm, atmp, MM_One); + + M_restore_stack(1); +} + +#endif + +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapm_set.cpp b/pgscript/utilities/m_apm/mapm_set.cpp new file mode 100644 index 0000000..914c775 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_set.cpp @@ -0,0 +1,357 @@ + +/* + * M_APM - mapm_set.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions necessary to get C 'longs' and + * 'strings' into the MAPM number system. It also contains the function + * to get a string from a MAPM number. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static char *M_buf = NULL; +static int M_lbuf = 0; +static const char *M_set_string_error_msg = "\'m_apm_set_string\', Out of memory"; + +/****************************************************************************/ +void M_free_all_set() +{ + if (M_lbuf != 0) + { + MAPM_FREE(M_buf); + M_buf = NULL; + M_lbuf = 0; + } +} +/****************************************************************************/ +void m_apm_set_long(M_APM atmp, long mm) +{ + int len, ii, nbytes; + char *p, *buf, ch, buf2[64]; + + /* if zero, return right away */ + + if (mm == 0) + { + M_set_to_zero(atmp); + return; + } + + M_long_2_ascii(buf2, mm); /* convert long -> ascii in base 10 */ + buf = buf2; + + if (mm < 0) + { + atmp->m_apm_sign = -1; + buf++; /* get past '-' sign */ + } + else + { + atmp->m_apm_sign = 1; + } + + len = strlen(buf); + atmp->m_apm_exponent = len; + + /* least significant nibble of ODD data-length must be 0 */ + + if ((len & 1) != 0) + { + buf[len] = '0'; + } + + /* remove any trailing '0' ... */ + + while (TRUE) + { + if (buf[--len] != '0') + break; + } + + atmp->m_apm_datalength = ++len; + + nbytes = (len + 1) >> 1; + p = buf; + + for (ii = 0; ii < nbytes; ii++) + { + ch = *p++ - '0'; + atmp->m_apm_data[ii] = 10 * ch + *p++ - '0'; + } +} +/****************************************************************************/ +void m_apm_set_string(M_APM ctmp, const char *s_in) +{ + char ch, *cp, *s, *p; + void *vp; + int i, j, zflag, exponent, sign; + + if (M_lbuf == 0) + { + M_lbuf = 256; + if ((M_buf = (char *)MAPM_MALLOC(256)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg); + } + } + + if ((i = strlen(s_in)) > (M_lbuf - 4)) + { + M_lbuf = i + 32; + if ((vp = MAPM_REALLOC(M_buf, M_lbuf)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg); + } + + M_buf = (char *)vp; + } + + s = M_buf; + strcpy(s, s_in); + + /* default == zero ... */ + + M_set_to_zero(ctmp); + + p = s; + + while (TRUE) + { + if (*p == ' ' || *p == '\t') + p++; + else + break; + } + + if (*p == '\0') + return; + + sign = 1; /* assume number is positive */ + + if (*p == '+') /* scan by optional '+' sign */ + p++; + else + { + if (*p == '-') /* check if number negative */ + { + sign = -1; + p++; + } + } + + M_lowercase(p); /* convert string to lowercase */ + exponent = 0; /* default */ + + if ((cp = strstr(p, "e")) != NULL) + { + exponent = atoi(cp + sizeof(char)); + *cp = '\0'; /* erase the exponent now */ + } + + j = M_strposition(p, (char *) "."); /* is there a decimal point ?? */ + if (j == -1) + { + strcat(p, "."); /* if not, append one */ + j = M_strposition(p, (char *) "."); /* now find it ... */ + } + + if (j > 0) /* normalize number and adjust exponent */ + { + exponent += j; + memmove((p + 1), p, (j * sizeof(char))); + } + + p++; /* scan past implied decimal point now in column 1 (index 0) */ + + i = strlen(p); + ctmp->m_apm_datalength = i; + + if ((i & 1) != 0) /* if odd number of digits, append a '0' to make it even */ + strcat(p, "0"); + + j = strlen(p) >> 1; /* number of bytes in encoded M_APM number */ + + /* do we need more memory to hold this number */ + + if (j > ctmp->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (j + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_set_string_error_msg); + } + + ctmp->m_apm_malloclength = j + 28; + ctmp->m_apm_data = (UCHAR *)vp; + } + + zflag = TRUE; + + for (i = 0; i < j; i++) + { + ch = *p++ - '0'; + if ((ch = (10 * ch + *p++ - '0')) != 0) + zflag = FALSE; + + if (((int)ch & 0xFF) >= 100) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_set_string\', Non-digit char found in parse"); + + M_apm_log_error_msg(M_APM_RETURN, "Text ="); + M_apm_log_error_msg(M_APM_RETURN, s_in); + + M_set_to_zero(ctmp); + return; + } + + ctmp->m_apm_data[i] = ch; + ctmp->m_apm_data[i + 1] = 0; + } + + ctmp->m_apm_exponent = exponent; + ctmp->m_apm_sign = sign; + + if (zflag) + { + ctmp->m_apm_exponent = 0; + ctmp->m_apm_sign = 0; + ctmp->m_apm_datalength = 1; + } + else + { + M_apm_normalize(ctmp); + } + + /* + * if our local temp string is getting too big, + * release it's memory and start over next time. + * (this 1000 byte threshold is quite arbitrary, + * it may be more efficient in your app to make + * this number bigger). + */ + + if (M_lbuf > 1000) + { + MAPM_FREE(M_buf); + M_buf = NULL; + M_lbuf = 0; + } +} +/****************************************************************************/ +void m_apm_to_string(char *s, int places, M_APM mtmp) +{ + M_APM ctmp; + char *cp; + int i, index, first, max_i, num_digits, dec_places; + UCHAR numdiv, numrem; + + ctmp = M_get_stack_var(); + dec_places = places; + + if (dec_places < 0) + m_apm_copy(ctmp, mtmp); + else + m_apm_round(ctmp, dec_places, mtmp); + + if (ctmp->m_apm_sign == 0) + { + if (dec_places < 0) + strcpy(s, "0.0E+0"); + else + { + strcpy(s, "0"); + + if (dec_places > 0) + strcat(s, "."); + + for (i = 0; i < dec_places; i++) + strcat(s, "0"); + + strcat(s, "E+0"); + } + + M_restore_stack(1); + return; + } + + max_i = (ctmp->m_apm_datalength + 1) >> 1; + + if (dec_places < 0) + num_digits = ctmp->m_apm_datalength; + else + num_digits = dec_places + 1; + + cp = s; + + if (ctmp->m_apm_sign == -1) + *cp++ = '-'; + + first = TRUE; + + i = 0; + index = 0; + + while (TRUE) + { + if (index >= max_i) + { + numdiv = 0; + numrem = 0; + } + else + M_get_div_rem_10((int)ctmp->m_apm_data[index], &numdiv, &numrem); + + index++; + + *cp++ = numdiv + '0'; + + if (++i == num_digits) + break; + + if (first) + { + first = FALSE; + *cp++ = '.'; + } + + *cp++ = numrem + '0'; + + if (++i == num_digits) + break; + } + + i = ctmp->m_apm_exponent - 1; + if (i >= 0) + sprintf(cp, "E+%d", i); + else + sprintf(cp, "E%d", i); + + M_restore_stack(1); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapm_sin.cpp b/pgscript/utilities/m_apm/mapm_sin.cpp new file mode 100644 index 0000000..8d26f05 --- /dev/null +++ b/pgscript/utilities/m_apm/mapm_sin.cpp @@ -0,0 +1,140 @@ + +/* + * M_APM - mapm_sin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the top level (user callable) SIN / COS / TAN + * functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_sin(M_APM r, int places, M_APM a) +{ + M_APM tmp3; + + tmp3 = M_get_stack_var(); + M_limit_angle_to_pi(tmp3, (places + 6), a); + M_5x_sin(r, places, tmp3); + M_restore_stack(1); +} +/****************************************************************************/ +void m_apm_cos(M_APM r, int places, M_APM a) +{ + M_APM tmp3; + + tmp3 = M_get_stack_var(); + M_limit_angle_to_pi(tmp3, (places + 6), a); + M_4x_cos(r, places, tmp3); + M_restore_stack(1); +} +/****************************************************************************/ +void m_apm_sin_cos(M_APM sinv, M_APM cosv, int places, M_APM aa) +{ + M_APM tmp5, tmp6, tmp7; + + tmp5 = M_get_stack_var(); + tmp6 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + + M_limit_angle_to_pi(tmp5, (places + 6), aa); + M_4x_cos(tmp7, (places + 6), tmp5); + + /* + * compute sin(x) = sqrt(1 - cos(x) ^ 2). + * + * note that the sign of 'sin' will always be positive after the + * sqrt call. we need to adjust the sign based on what quadrant + * the original angle is in. + */ + + M_cos_to_sin(tmp6, (places + 6), tmp7); + if (tmp6->m_apm_sign != 0) + tmp6->m_apm_sign = tmp5->m_apm_sign; + + m_apm_round(sinv, places, tmp6); + m_apm_round(cosv, places, tmp7); + M_restore_stack(3); +} +/****************************************************************************/ +void m_apm_tan(M_APM r, int places, M_APM a) +{ + M_APM tmps, tmpc, tmp0; + + tmps = M_get_stack_var(); + tmpc = M_get_stack_var(); + tmp0 = M_get_stack_var(); + + m_apm_sin_cos(tmps, tmpc, (places + 4), a); + + /* tan(x) = sin(x) / cos(x) */ + + m_apm_divide(tmp0, (places + 4), tmps, tmpc); + m_apm_round(r, places, tmp0); + M_restore_stack(3); +} +/****************************************************************************/ +void M_limit_angle_to_pi(M_APM rr, int places, M_APM aa) +{ + M_APM tmp7, tmp8, tmp9; + + M_check_PI_places(places); + + tmp9 = M_get_stack_var(); + m_apm_copy(tmp9, MM_lc_PI); + + if (m_apm_compare(aa, tmp9) == 1) /* > PI */ + { + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + + m_apm_add(tmp7, aa, tmp9); + m_apm_integer_divide(tmp9, tmp7, MM_lc_2_PI); + m_apm_multiply(tmp8, tmp9, MM_lc_2_PI); + m_apm_subtract(tmp9, aa, tmp8); + m_apm_round(rr, places, tmp9); + + M_restore_stack(3); + return; + } + + tmp9->m_apm_sign = -1; + if (m_apm_compare(aa, tmp9) == -1) /* < -PI */ + { + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + + m_apm_add(tmp7, aa, tmp9); + m_apm_integer_divide(tmp9, tmp7, MM_lc_2_PI); + m_apm_multiply(tmp8, tmp9, MM_lc_2_PI); + m_apm_subtract(tmp9, aa, tmp8); + m_apm_round(rr, places, tmp9); + + M_restore_stack(3); + return; + } + + m_apm_copy(rr, aa); + M_restore_stack(1); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmasin.cpp b/pgscript/utilities/m_apm/mapmasin.cpp new file mode 100644 index 0000000..1b50e30 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmasin.cpp @@ -0,0 +1,430 @@ + +/* + * M_APM - mapmasin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the 'ARC' family of functions; ARC-SIN, ARC-COS, + * ARC-TAN, and ARC-TAN2. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_arctan2(M_APM rr, int places, M_APM yy, M_APM xx) +{ + M_APM tmp5, tmp6, tmp7; + int ix, iy; + + iy = yy->m_apm_sign; + ix = xx->m_apm_sign; + + if (ix == 0) /* x == 0 */ + { + if (iy == 0) /* y == 0 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arctan2\', Both Inputs = 0"); + M_set_to_zero(rr); + return; + } + + M_check_PI_places(places); + m_apm_round(rr, places, MM_lc_HALF_PI); + rr->m_apm_sign = iy; + return; + } + + if (iy == 0) + { + if (ix == 1) + { + M_set_to_zero(rr); + } + else + { + M_check_PI_places(places); + m_apm_round(rr, places, MM_lc_PI); + } + + return; + } + + /* + * the special cases have been handled, now do the real work + */ + + tmp5 = M_get_stack_var(); + tmp6 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + + m_apm_divide(tmp6, (places + 6), yy, xx); + m_apm_arctan(tmp5, (places + 6), tmp6); + + if (ix == 1) /* 'x' is positive */ + { + m_apm_round(rr, places, tmp5); + } + else /* 'x' is negative */ + { + M_check_PI_places(places); + + if (iy == 1) /* 'y' is positive */ + { + m_apm_add(tmp7, tmp5, MM_lc_PI); + m_apm_round(rr, places, tmp7); + } + else /* 'y' is negative */ + { + m_apm_subtract(tmp7, tmp5, MM_lc_PI); + m_apm_round(rr, places, tmp7); + } + } + + M_restore_stack(3); +} +/****************************************************************************/ +/* + Calculate arctan using the identity : + + x + arctan (x) == arcsin [ --------------- ] + sqrt(1 + x^2) + +*/ +void m_apm_arctan(M_APM rr, int places, M_APM xx) +{ + M_APM tmp8, tmp9; + + if (xx->m_apm_sign == 0) /* input == 0 ?? */ + { + M_set_to_zero(rr); + return; + } + + if (xx->m_apm_exponent <= -4) /* input close to 0 ?? */ + { + M_arctan_near_0(rr, places, xx); + return; + } + + if (xx->m_apm_exponent >= 4) /* large input */ + { + M_arctan_large_input(rr, places, xx); + return; + } + + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_multiply(tmp9, xx, xx); + m_apm_add(tmp8, tmp9, MM_One); + m_apm_sqrt(tmp9, (places + 6), tmp8); + m_apm_divide(tmp8, (places + 6), xx, tmp9); + m_apm_arcsin(rr, places, tmp8); + M_restore_stack(2); +} +/****************************************************************************/ +/* + + for large input values use : + + arctan(x) = (PI / 2) - arctan(1 / |x|) + + and sign of result = sign of original input + +*/ +void M_arctan_large_input(M_APM rr, int places, M_APM xx) +{ + M_APM tmp1, tmp2; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + M_check_PI_places(places); + + m_apm_divide(tmp1, (places + 6), MM_One, xx); /* 1 / xx */ + tmp1->m_apm_sign = 1; /* make positive */ + m_apm_arctan(tmp2, (places + 6), tmp1); + m_apm_subtract(tmp1, MM_lc_HALF_PI, tmp2); + m_apm_round(rr, places, tmp1); + + rr->m_apm_sign = xx->m_apm_sign; /* fix final sign */ + + M_restore_stack(2); +} +/****************************************************************************/ +void m_apm_arcsin(M_APM r, int places, M_APM x) +{ + M_APM tmp0, tmp1, tmp2, tmp3, current_x; + int ii, maxiter, maxp, tolerance, local_precision; + + current_x = M_get_stack_var(); + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + m_apm_absolute_value(tmp0, x); + + ii = m_apm_compare(tmp0, MM_One); + + if (ii == 1) /* |x| > 1 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arcsin\', |Argument| > 1"); + M_set_to_zero(r); + M_restore_stack(5); + return; + } + + if (ii == 0) /* |x| == 1, arcsin = +/- PI / 2 */ + { + M_check_PI_places(places); + m_apm_round(r, places, MM_lc_HALF_PI); + r->m_apm_sign = x->m_apm_sign; + + M_restore_stack(5); + return; + } + + if (m_apm_compare(tmp0, MM_0_85) == 1) /* check if > 0.85 */ + { + M_cos_to_sin(tmp2, (places + 4), x); + m_apm_arccos(r, places, tmp2); + r->m_apm_sign = x->m_apm_sign; + + M_restore_stack(5); + return; + } + + if (x->m_apm_sign == 0) /* input == 0 ?? */ + { + M_set_to_zero(r); + M_restore_stack(5); + return; + } + + if (x->m_apm_exponent <= -4) /* input close to 0 ?? */ + { + M_arcsin_near_0(r, places, x); + M_restore_stack(5); + return; + } + + tolerance = -(places + 4); + maxp = places + 8 - x->m_apm_exponent; + local_precision = 20 - x->m_apm_exponent; + + /* + * compute the maximum number of iterations + * that should be needed to calculate to + * the desired accuracy. [ constant below ~= 1 / log(2) ] + */ + + maxiter = (int)(log((double)(places + 2)) * 1.442695) + 3; + + if (maxiter < 5) + maxiter = 5; + + M_get_asin_guess(current_x, x); + + /* Use the following iteration to solve for arc-sin : + + sin(X) - N + X = X - ------------ + n+1 cos(X) + */ + + ii = 0; + + while (TRUE) + { + M_4x_cos(tmp1, local_precision, current_x); + + M_cos_to_sin(tmp2, local_precision, tmp1); + if (tmp2->m_apm_sign != 0) + tmp2->m_apm_sign = current_x->m_apm_sign; + + m_apm_subtract(tmp3, tmp2, x); + m_apm_divide(tmp0, local_precision, tmp3, tmp1); + + m_apm_subtract(tmp2, current_x, tmp0); + m_apm_copy(current_x, tmp2); + + if (ii != 0) + { + if (((2 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0)) + break; + } + + if (++ii == maxiter) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_arcsin\', max iteration count reached"); + break; + } + + local_precision *= 2; + + if (local_precision > maxp) + local_precision = maxp; + } + + m_apm_round(r, places, current_x); + M_restore_stack(5); +} +/****************************************************************************/ +void m_apm_arccos(M_APM r, int places, M_APM x) +{ + M_APM tmp0, tmp1, tmp2, tmp3, current_x; + int ii, maxiter, maxp, tolerance, local_precision; + + current_x = M_get_stack_var(); + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + m_apm_absolute_value(tmp0, x); + + ii = m_apm_compare(tmp0, MM_One); + + if (ii == 1) /* |x| > 1 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arccos\', |Argument| > 1"); + M_set_to_zero(r); + M_restore_stack(5); + return; + } + + if (ii == 0) /* |x| == 1, arccos = 0, PI */ + { + if (x->m_apm_sign == 1) + { + M_set_to_zero(r); + } + else + { + M_check_PI_places(places); + m_apm_round(r, places, MM_lc_PI); + } + + M_restore_stack(5); + return; + } + + if (m_apm_compare(tmp0, MM_0_85) == 1) /* check if > 0.85 */ + { + M_cos_to_sin(tmp2, (places + 4), x); + + if (x->m_apm_sign == 1) + { + m_apm_arcsin(r, places, tmp2); + } + else + { + M_check_PI_places(places); + m_apm_arcsin(tmp3, (places + 4), tmp2); + m_apm_subtract(tmp1, MM_lc_PI, tmp3); + m_apm_round(r, places, tmp1); + } + + M_restore_stack(5); + return; + } + + if (x->m_apm_sign == 0) /* input == 0 ?? */ + { + M_check_PI_places(places); + m_apm_round(r, places, MM_lc_HALF_PI); + M_restore_stack(5); + return; + } + + if (x->m_apm_exponent <= -4) /* input close to 0 ?? */ + { + M_arccos_near_0(r, places, x); + M_restore_stack(5); + return; + } + + tolerance = -(places + 4); + maxp = places + 8; + local_precision = 18; + + /* + * compute the maximum number of iterations + * that should be needed to calculate to + * the desired accuracy. [ constant below ~= 1 / log(2) ] + */ + + maxiter = (int)(log((double)(places + 2)) * 1.442695) + 3; + + if (maxiter < 5) + maxiter = 5; + + M_get_acos_guess(current_x, x); + + /* Use the following iteration to solve for arc-cos : + + cos(X) - N + X = X + ------------ + n+1 sin(X) + */ + + ii = 0; + + while (TRUE) + { + M_4x_cos(tmp1, local_precision, current_x); + + M_cos_to_sin(tmp2, local_precision, tmp1); + if (tmp2->m_apm_sign != 0) + tmp2->m_apm_sign = current_x->m_apm_sign; + + m_apm_subtract(tmp3, tmp1, x); + m_apm_divide(tmp0, local_precision, tmp3, tmp2); + + m_apm_add(tmp2, current_x, tmp0); + m_apm_copy(current_x, tmp2); + + if (ii != 0) + { + if (((2 * tmp0->m_apm_exponent) < tolerance) || (tmp0->m_apm_sign == 0)) + break; + } + + if (++ii == maxiter) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_arccos\', max iteration count reached"); + break; + } + + local_precision *= 2; + + if (local_precision > maxp) + local_precision = maxp; + } + + m_apm_round(r, places, current_x); + M_restore_stack(5); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmasn0.cpp b/pgscript/utilities/m_apm/mapmasn0.cpp new file mode 100644 index 0000000..688ea5e --- /dev/null +++ b/pgscript/utilities/m_apm/mapmasn0.cpp @@ -0,0 +1,157 @@ + +/* + * M_APM - mapmasn0.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the 'ARC' family of functions; ARC-SIN, + * ARC-COS, ARC-TAN when the input arg is very close to 0 (zero). + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + Calculate arcsin using the identity : + + x + arcsin (x) == arctan [ --------------- ] + sqrt(1 - x^2) + +*/ +void M_arcsin_near_0(M_APM rr, int places, M_APM aa) +{ + M_APM tmp5, tmp6; + + tmp5 = M_get_stack_var(); + tmp6 = M_get_stack_var(); + + M_cos_to_sin(tmp5, (places + 8), aa); + m_apm_divide(tmp6, (places + 8), aa, tmp5); + M_arctan_near_0(rr, places, tmp6); + + M_restore_stack(2); +} +/****************************************************************************/ +/* + Calculate arccos using the identity : + + arccos (x) == PI / 2 - arcsin (x) + +*/ +void M_arccos_near_0(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + M_check_PI_places(places); + M_arcsin_near_0(tmp1, (places + 4), aa); + m_apm_subtract(tmp2, MM_lc_HALF_PI, tmp1); + m_apm_round(rr, places, tmp2); + + M_restore_stack(2); +} +/****************************************************************************/ +/* + calculate arctan (x) with the following series: + + x^3 x^5 x^7 x^9 + arctan (x) = x - --- + --- - --- + --- ... + 3 5 7 9 + +*/ +void M_arctan_near_0(M_APM rr, int places, M_APM aa) +{ + M_APM tmp0, tmp2, tmpR, tmpS, digit, term; + int tolerance, dplaces, local_precision; + long m1; + + tmp0 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmpR = M_get_stack_var(); + tmpS = M_get_stack_var(); + term = M_get_stack_var(); + digit = M_get_stack_var(); + + tolerance = aa->m_apm_exponent - (places + 4); + dplaces = (places + 8) - aa->m_apm_exponent; + + m_apm_copy(term, aa); + m_apm_copy(tmpS, aa); + m_apm_multiply(tmp0, aa, aa); + m_apm_round(tmp2, (dplaces + 8), tmp0); + + m1 = 1L; + + while (TRUE) + { + /* + * do the subtraction term + */ + + m_apm_multiply(tmp0, term, tmp2); + + if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0)) + { + m_apm_round(rr, places, tmpS); + break; + } + + local_precision = dplaces + tmp0->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m1 += 2; + m_apm_set_long(digit, m1); + m_apm_round(term, local_precision, tmp0); + m_apm_divide(tmp0, local_precision, term, digit); + m_apm_subtract(tmpR, tmpS, tmp0); + + /* + * do the addition term + */ + + m_apm_multiply(tmp0, term, tmp2); + + if ((tmp0->m_apm_exponent < tolerance) || (tmp0->m_apm_sign == 0)) + { + m_apm_round(rr, places, tmpR); + break; + } + + local_precision = dplaces + tmp0->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m1 += 2; + m_apm_set_long(digit, m1); + m_apm_round(term, local_precision, tmp0); + m_apm_divide(tmp0, local_precision, term, digit); + m_apm_add(tmpS, tmpR, tmp0); + } + + M_restore_stack(6); /* restore the 6 locals we used here */ +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmcbrt.cpp b/pgscript/utilities/m_apm/mapmcbrt.cpp new file mode 100644 index 0000000..505b4a5 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmcbrt.cpp @@ -0,0 +1,129 @@ + +/* + * M_APM - mapmcbrt.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the CBRT (cube root) function. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_cbrt(M_APM rr, int places, M_APM aa) +{ + M_APM last_x, guess, tmpN, tmp7, tmp8, tmp9; + int ii, nexp, bflag, tolerance, maxp, local_precision; + + /* result is 0 if input is 0 */ + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + last_x = M_get_stack_var(); + guess = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + /* compute the cube root of the positive number, we'll fix the sign later */ + + m_apm_absolute_value(tmpN, aa); + + /* + normalize the input number (make the exponent near 0) so + the 'guess' function will not over/under flow on large + magnitude exponents. + */ + + nexp = aa->m_apm_exponent / 3; + tmpN->m_apm_exponent -= 3 * nexp; + + M_get_cbrt_guess(guess, tmpN); + + tolerance = places + 4; + maxp = places + 16; + bflag = FALSE; + local_precision = 14; + + m_apm_negate(last_x, MM_Ten); + + /* Use the following iteration to calculate 1 / cbrt(N) : + + 4 + X = [ 4 * X - N * X ] / 3 + n+1 + */ + + ii = 0; + + while (TRUE) + { + m_apm_multiply(tmp8, guess, guess); + m_apm_multiply(tmp7, tmp8, tmp8); + m_apm_round(tmp8, local_precision, tmp7); + m_apm_multiply(tmp9, tmpN, tmp8); + + m_apm_multiply(tmp8, MM_Four, guess); + m_apm_subtract(tmp7, tmp8, tmp9); + m_apm_divide(guess, local_precision, tmp7, MM_Three); + + if (bflag) + break; + + /* force at least 2 iterations so 'last_x' has valid data */ + + if (ii != 0) + { + m_apm_subtract(tmp8, guess, last_x); + + if (tmp8->m_apm_sign == 0) + break; + + if ((-4 * tmp8->m_apm_exponent) > tolerance) + bflag = TRUE; + } + + local_precision *= 2; + + if (local_precision > maxp) + local_precision = maxp; + + m_apm_copy(last_x, guess); + ii = 1; + } + + /* final cbrt = N * guess ^ 2 */ + + m_apm_multiply(tmp9, guess, guess); + m_apm_multiply(tmp8, tmp9, tmpN); + m_apm_round(rr, places, tmp8); + + rr->m_apm_exponent += nexp; + rr->m_apm_sign = aa->m_apm_sign; + M_restore_stack(6); +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmcnst.cpp b/pgscript/utilities/m_apm/mapmcnst.cpp new file mode 100644 index 0000000..2e09deb --- /dev/null +++ b/pgscript/utilities/m_apm/mapmcnst.cpp @@ -0,0 +1,291 @@ + +/* + * M_APM - mapmcnst.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains declarations and initializes the constants + * used throughout the library. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +int MM_lc_PI_digits = 0; +int MM_lc_log_digits; +int MM_cpp_min_precision; /* only used in C++ wrapper */ + +M_APM MM_Zero = NULL; +M_APM MM_One = NULL; +M_APM MM_Two = NULL; +M_APM MM_Three = NULL; +M_APM MM_Four = NULL; +M_APM MM_Five = NULL; +M_APM MM_Ten = NULL; +M_APM MM_0_5 = NULL; +M_APM MM_E = NULL; +M_APM MM_PI = NULL; +M_APM MM_HALF_PI = NULL; +M_APM MM_2_PI = NULL; +M_APM MM_lc_PI = NULL; +M_APM MM_lc_HALF_PI = NULL; +M_APM MM_lc_2_PI = NULL; +M_APM MM_lc_log2 = NULL; +M_APM MM_lc_log10 = NULL; +M_APM MM_lc_log10R = NULL; +M_APM MM_0_85 = NULL; +M_APM MM_5x_125R = NULL; +M_APM MM_5x_64R = NULL; +M_APM MM_5x_256R = NULL; +M_APM MM_5x_Eight = NULL; +M_APM MM_5x_Sixteen = NULL; +M_APM MM_5x_Twenty = NULL; +M_APM MM_LOG_E_BASE_10 = NULL; +M_APM MM_LOG_10_BASE_E = NULL; +M_APM MM_LOG_2_BASE_E = NULL; +M_APM MM_LOG_3_BASE_E = NULL; + + +static char MM_cnst_PI[] = + "3.1415926535897932384626433832795028841971693993751058209749445923078\ +1640628620899862803482534211706798214808651328230664709384460955"; + +static char MM_cnst_E[] = + "2.7182818284590452353602874713526624977572470936999595749669676277240\ +76630353547594571382178525166427427466391932003059921817413596629"; + +static char MM_cnst_log_2[] = + "0.6931471805599453094172321214581765680755001343602552541206800094933\ +93621969694715605863326996418687542001481020570685733685520235758"; + +static char MM_cnst_log_3[] = + "1.0986122886681096913952452369225257046474905578227494517346943336374\ +9429321860896687361575481373208878797002906595786574236800422593"; + +static char MM_cnst_log_10[] = + "2.3025850929940456840179914546843642076011014886287729760333279009675\ +7260967735248023599720508959829834196778404228624863340952546508"; + +static char MM_cnst_1_log_10[] = + "0.4342944819032518276511289189166050822943970058036665661144537831658\ +64649208870774729224949338431748318706106744766303733641679287159"; + +/* + * the following constants have ~520 digits each, if needed + */ + +/* +static char MM_cnst_PI[] = +"3.1415926535897932384626433832795028841971693993751058209749445923078\ +164062862089986280348253421170679821480865132823066470938446095505822\ +317253594081284811174502841027019385211055596446229489549303819644288\ +109756659334461284756482337867831652712019091456485669234603486104543\ +266482133936072602491412737245870066063155881748815209209628292540917\ +153643678925903600113305305488204665213841469519415116094330572703657\ +595919530921861173819326117931051185480744623799627495673518857527248\ +91227938183011949129833673362440656643"; + +static char MM_cnst_E[] = +"2.7182818284590452353602874713526624977572470936999595749669676277240\ +766303535475945713821785251664274274663919320030599218174135966290435\ +729003342952605956307381323286279434907632338298807531952510190115738\ +341879307021540891499348841675092447614606680822648001684774118537423\ +454424371075390777449920695517027618386062613313845830007520449338265\ +602976067371132007093287091274437470472306969772093101416928368190255\ +151086574637721112523897844250569536967707854499699679468644549059879\ +3163688923009879312773617821542499923"; + +static char MM_cnst_log_2[] = +"0.6931471805599453094172321214581765680755001343602552541206800094933\ +936219696947156058633269964186875420014810205706857336855202357581305\ +570326707516350759619307275708283714351903070386238916734711233501153\ +644979552391204751726815749320651555247341395258829504530070953263666\ +426541042391578149520437404303855008019441706416715186447128399681717\ +845469570262716310645461502572074024816377733896385506952606683411372\ +738737229289564935470257626520988596932019650585547647033067936544325\ +47632744951250406069438147104689946506"; + +static char MM_cnst_log_3[] = +"1.0986122886681096913952452369225257046474905578227494517346943336374\ +942932186089668736157548137320887879700290659578657423680042259305198\ +210528018707672774106031627691833813671793736988443609599037425703167\ +959115211455919177506713470549401667755802222031702529468975606901065\ +215056428681380363173732985777823669916547921318181490200301038236301\ +222486527481982259910974524908964580534670088459650857484441190188570\ +876474948670796130858294116021661211840014098255143919487688936798494\ +3022557315353296853452952514592138765"; + +static char MM_cnst_log_10[] = +"2.3025850929940456840179914546843642076011014886287729760333279009675\ +726096773524802359972050895982983419677840422862486334095254650828067\ +566662873690987816894829072083255546808437998948262331985283935053089\ +653777326288461633662222876982198867465436674744042432743651550489343\ +149393914796194044002221051017141748003688084012647080685567743216228\ +355220114804663715659121373450747856947683463616792101806445070648000\ +277502684916746550586856935673420670581136429224554405758925724208241\ +31469568901675894025677631135691929203"; + +static char MM_cnst_1_log_10[] = +"0.4342944819032518276511289189166050822943970058036665661144537831658\ +646492088707747292249493384317483187061067447663037336416792871589639\ +065692210646628122658521270865686703295933708696588266883311636077384\ +905142844348666768646586085135561482123487653435434357317253835622281\ +395603048646652366095539377356176323431916710991411597894962993512457\ +934926357655469077671082419150479910989674900103277537653570270087328\ +550951731440674697951899513594088040423931518868108402544654089797029\ +86328682876262414401345704354613292060"; +*/ + + +/****************************************************************************/ +char *m_apm_lib_version(char *v) +{ + strcpy(v, MAPM_LIB_VERSION); + return(v); +} +/****************************************************************************/ +char *m_apm_lib_short_version(char *v) +{ + strcpy(v, MAPM_LIB_SHORT_VERSION); + return(v); +} +/****************************************************************************/ +void M_free_all_cnst() +{ + if (MM_lc_PI_digits != 0) + { + m_apm_free(MM_Zero); + m_apm_free(MM_One); + m_apm_free(MM_Two); + m_apm_free(MM_Three); + m_apm_free(MM_Four); + m_apm_free(MM_Five); + m_apm_free(MM_Ten); + m_apm_free(MM_0_5); + m_apm_free(MM_LOG_2_BASE_E); + m_apm_free(MM_LOG_3_BASE_E); + m_apm_free(MM_E); + m_apm_free(MM_PI); + m_apm_free(MM_HALF_PI); + m_apm_free(MM_2_PI); + m_apm_free(MM_lc_PI); + m_apm_free(MM_lc_HALF_PI); + m_apm_free(MM_lc_2_PI); + m_apm_free(MM_lc_log2); + m_apm_free(MM_lc_log10); + m_apm_free(MM_lc_log10R); + m_apm_free(MM_0_85); + m_apm_free(MM_5x_125R); + m_apm_free(MM_5x_64R); + m_apm_free(MM_5x_256R); + m_apm_free(MM_5x_Eight); + m_apm_free(MM_5x_Sixteen); + m_apm_free(MM_5x_Twenty); + m_apm_free(MM_LOG_E_BASE_10); + m_apm_free(MM_LOG_10_BASE_E); + + MM_lc_PI_digits = 0; + } +} +/****************************************************************************/ +void M_init_trig_globals() +{ + MM_lc_PI_digits = VALID_DECIMAL_PLACES; + MM_lc_log_digits = VALID_DECIMAL_PLACES; + MM_cpp_min_precision = 30; + + MM_Zero = m_apm_init(); + MM_One = m_apm_init(); + MM_Two = m_apm_init(); + MM_Three = m_apm_init(); + MM_Four = m_apm_init(); + MM_Five = m_apm_init(); + MM_Ten = m_apm_init(); + MM_0_5 = m_apm_init(); + MM_LOG_2_BASE_E = m_apm_init(); + MM_LOG_3_BASE_E = m_apm_init(); + MM_E = m_apm_init(); + MM_PI = m_apm_init(); + MM_HALF_PI = m_apm_init(); + MM_2_PI = m_apm_init(); + MM_lc_PI = m_apm_init(); + MM_lc_HALF_PI = m_apm_init(); + MM_lc_2_PI = m_apm_init(); + MM_lc_log2 = m_apm_init(); + MM_lc_log10 = m_apm_init(); + MM_lc_log10R = m_apm_init(); + MM_0_85 = m_apm_init(); + MM_5x_125R = m_apm_init(); + MM_5x_64R = m_apm_init(); + MM_5x_256R = m_apm_init(); + MM_5x_Eight = m_apm_init(); + MM_5x_Sixteen = m_apm_init(); + MM_5x_Twenty = m_apm_init(); + MM_LOG_E_BASE_10 = m_apm_init(); + MM_LOG_10_BASE_E = m_apm_init(); + + m_apm_set_string(MM_One, "1"); + m_apm_set_string(MM_Two, "2"); + m_apm_set_string(MM_Three, "3"); + m_apm_set_string(MM_Four, "4"); + m_apm_set_string(MM_Five, "5"); + m_apm_set_string(MM_Ten, "10"); + m_apm_set_string(MM_0_5, "0.5"); + m_apm_set_string(MM_0_85, "0.85"); + + m_apm_set_string(MM_5x_125R, "8.0E-3"); + m_apm_set_string(MM_5x_64R, "1.5625E-2"); + m_apm_set_string(MM_5x_256R, "3.90625E-3"); + m_apm_set_string(MM_5x_Eight, "8"); + m_apm_set_string(MM_5x_Sixteen, "16"); + m_apm_set_string(MM_5x_Twenty, "20"); + + m_apm_set_string(MM_LOG_2_BASE_E, MM_cnst_log_2); + m_apm_set_string(MM_LOG_3_BASE_E, MM_cnst_log_3); + m_apm_set_string(MM_LOG_10_BASE_E, MM_cnst_log_10); + m_apm_set_string(MM_LOG_E_BASE_10, MM_cnst_1_log_10); + + m_apm_set_string(MM_lc_log2, MM_cnst_log_2); + m_apm_set_string(MM_lc_log10, MM_cnst_log_10); + m_apm_set_string(MM_lc_log10R, MM_cnst_1_log_10); + + m_apm_set_string(MM_E, MM_cnst_E); + m_apm_set_string(MM_PI, MM_cnst_PI); + m_apm_multiply(MM_HALF_PI, MM_PI, MM_0_5); + m_apm_multiply(MM_2_PI, MM_PI, MM_Two); + + m_apm_copy(MM_lc_PI, MM_PI); + m_apm_copy(MM_lc_HALF_PI, MM_HALF_PI); + m_apm_copy(MM_lc_2_PI, MM_2_PI); +} +/****************************************************************************/ +void m_apm_cpp_precision(int digits) +{ + if (MM_lc_PI_digits == 0) + { + m_apm_free(m_apm_init()); + } + + if (digits >= 2) + MM_cpp_min_precision = digits; + else + MM_cpp_min_precision = 2; +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmfact.cpp b/pgscript/utilities/m_apm/mapmfact.cpp new file mode 100644 index 0000000..b9c535c --- /dev/null +++ b/pgscript/utilities/m_apm/mapmfact.cpp @@ -0,0 +1,244 @@ + +/* + * M_APM - mapmfact.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the FACTORIAL function. + * + */ + +/* + * Brief explanation of the factorial algorithm. + * ---------------------------------------------- + * + * The old algorithm simply multiplied N * (N-1) * (N-2) etc, until + * the number counted down to '2'. So one term of the multiplication + * kept getting bigger while multiplying by the next number in the + * sequence. + * + * The new algorithm takes advantage of the fast multiplication + * algorithm. The "ideal" setup for fast multiplication is when + * both numbers have approx the same number of significant digits + * and the number of digits is very near (but not over) an exact + * power of 2. + * + * So, we will multiply N * (N-1) * (N-2), etc until the number of + * significant digits is approx 256. + * + * Store this temp product into an array. + * + * Then we will multiply the next sequence until the number of + * significant digits is approx 256. + * + * Store this temp product into the next element of the array. + * + * Continue until we've counted down to 2. + * + * We now have an array of numbers with approx the same number + * of digits (except for the last element, depending on where it + * ended.) Now multiply each of the array elements together to + * get the final product. + * + * The array multiplies are done as follows (assume we used 11 + * array elements for this example, indicated by [0] - [10] ) : + * + * initial iter-1 iter-2 iter-3 iter-4 + * + * [0] + * * -> [0] + * [1] + * * -> [0] + * + * [2] + * * -> [1] + * [3] + * * -> [0] + * + * [4] + * * -> [2] + * [5] + * + * * -> [1] + * + * [6] + * * -> [3] * -> [0] + * [7] + * + * + * [8] + * * -> [4] + * [9] + * * -> [2] -> [1] + * + * + * [10] -> [5] + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/* define size of local array for temp storage */ + +#define NDIM 32 + +/****************************************************************************/ +void m_apm_factorial(M_APM moutput, M_APM minput) +{ + int ii, nmul, ndigits, nd, jj, kk, mm, ct; + M_APM array[NDIM]; + M_APM iprod1, iprod2, tmp1, tmp2; + + /* return 1 for any input <= 1 */ + + if (m_apm_compare(minput, MM_One) <= 0) + { + m_apm_copy(moutput, MM_One); + return; + } + + ct = 0; + mm = NDIM - 2; + ndigits = 256; + nd = ndigits - 20; + tmp1 = m_apm_init(); + tmp2 = m_apm_init(); + iprod1 = m_apm_init(); + iprod2 = m_apm_init(); + array[0] = m_apm_init(); + + m_apm_copy(tmp2, minput); + + /* loop until multiply count-down has reached '2' */ + + while (TRUE) + { + m_apm_copy(iprod1, MM_One); + + /* + * loop until the number of significant digits in this + * partial result is slightly less than 256 + */ + + while (TRUE) + { + m_apm_multiply(iprod2, iprod1, tmp2); + + m_apm_subtract(tmp1, tmp2, MM_One); + + m_apm_multiply(iprod1, iprod2, tmp1); + + /* + * I know, I know. There just isn't a *clean* way + * to break out of 2 nested loops. + */ + + if (m_apm_compare(tmp1, MM_Two) <= 0) + goto PHASE2; + + m_apm_subtract(tmp2, tmp1, MM_One); + + if (iprod1->m_apm_datalength > nd) + break; + } + + if (ct == (NDIM - 1)) + { + /* + * if the array has filled up, start multiplying + * some of the partial products now. + */ + + m_apm_copy(tmp1, array[mm]); + m_apm_multiply(array[mm], iprod1, tmp1); + + if (mm == 0) + { + mm = NDIM - 2; + ndigits = ndigits << 1; + nd = ndigits - 20; + } + else + mm--; + } + else + { + /* + * store this partial product in the array + * and allocate the next array element + */ + + m_apm_copy(array[ct], iprod1); + array[++ct] = m_apm_init(); + } + } + +PHASE2: + + m_apm_copy(array[ct], iprod1); + + kk = ct; + + while (kk != 0) + { + ii = 0; + jj = 0; + nmul = (kk + 1) >> 1; + + while (TRUE) + { + /* must use tmp var when ii,jj point to same element */ + + if (ii == 0) + { + m_apm_copy(tmp1, array[ii]); + m_apm_multiply(array[jj], tmp1, array[ii + 1]); + } + else + m_apm_multiply(array[jj], array[ii], array[ii + 1]); + + if (++jj == nmul) + break; + + ii += 2; + } + + if ((kk & 1) == 0) + { + jj = kk >> 1; + m_apm_copy(array[jj], array[kk]); + } + + kk = kk >> 1; + } + + m_apm_copy(moutput, array[0]); + + for (ii = 0; ii <= ct; ii++) + { + m_apm_free(array[ii]); + } + + m_apm_free(tmp1); + m_apm_free(tmp2); + m_apm_free(iprod1); + m_apm_free(iprod2); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmfmul.cpp b/pgscript/utilities/m_apm/mapmfmul.cpp new file mode 100644 index 0000000..6601c06 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmfmul.cpp @@ -0,0 +1,685 @@ + +/* + * M_APM - mapmfmul.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This file contains the divide-and-conquer FAST MULTIPLICATION + * function as well as its support functions. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static int M_firsttimef = TRUE; + +/* + * specify the max size the FFT routine can handle + * (in MAPM, #digits = 2 * #bytes) + * + * this number *must* be an exact power of 2. + * + * **WORST** case input numbers (all 9's) has shown that + * the FFT math will overflow if the #define here is + * >= 1048576. On my system, 524,288 worked OK. I will + * factor down another factor of 2 to safeguard against + * other computers have less precise floating point math. + * If you are confident in your system, 524288 will + * theoretically work fine. + * + * the define here allows the FFT algorithm to multiply two + * 524,288 digit numbers yielding a 1,048,576 digit result. + */ + +#define MAX_FFT_BYTES 262144 + +/* + * the Divide-and-Conquer multiplication kicks in when the size of + * the numbers exceed the capability of the FFT (#define just above). + * + * #bytes D&C call depth + * ------ -------------- + * 512K 1 + * 1M 2 + * 2M 3 + * 4M 4 + * ... ... + * 2.1990E+12 23 + * + * the following stack sizes are sized to meet the + * above 2.199E+12 example, though I wouldn't want to + * wait for it to finish... + * + * Each call requires 7 stack variables to be saved so + * we need a stack depth of 23 * 7 + PAD. (we use 164) + * + * For 'exp_stack', 3 integers also are required to be saved + * for each recursive call so we need a stack depth of + * 23 * 3 + PAD. (we use 72) + * + * + * If the FFT multiply is disabled, resize the arrays + * as follows: + * + * the following stack sizes are sized to meet the + * worst case expected assuming we are multiplying + * numbers with 2.14E+9 (2 ^ 31) digits. + * + * For sizeof(int) == 4 (32 bits) there may be up to 32 recursive + * calls. Each call requires 7 stack variables so we need a + * stack depth of 32 * 7 + PAD. (we use 240) + * + * For 'exp_stack', 3 integers also are required to be saved + * for each recursive call so we need a stack depth of + * 32 * 3 + PAD. (we use 100) + */ + +#ifdef NO_FFT_MULTIPLY +#define M_STACK_SIZE 240 +#define M_ISTACK_SIZE 100 +#else +#define M_STACK_SIZE 164 +#define M_ISTACK_SIZE 72 +#endif + +static int exp_stack[M_ISTACK_SIZE]; +static int exp_stack_ptr; + +static UCHAR *mul_stack_data[M_STACK_SIZE]; +static int mul_stack_data_size[M_STACK_SIZE]; +static int M_mul_stack_ptr; + +static UCHAR *fmul_a1, *fmul_a0, *fmul_a9, *fmul_b1, *fmul_b0, + *fmul_b9, *fmul_t0; + +static int size_flag, bit_limit, stmp, itmp, mii; + +static M_APM M_ain; +static M_APM M_bin; + +static const char *M_stack_ptr_error_msg = "\'M_get_stack_ptr\', Out of memory"; + +extern void M_fast_multiply(M_APM, M_APM, M_APM); +extern void M_fmul_div_conq(UCHAR *, UCHAR *, UCHAR *, int); +extern void M_fmul_add(UCHAR *, UCHAR *, int, int); +extern int M_fmul_subtract(UCHAR *, UCHAR *, UCHAR *, int); +extern void M_fmul_split(UCHAR *, UCHAR *, UCHAR *, int); +extern int M_next_power_of_2(int); +extern int M_get_stack_ptr(int); +extern void M_push_mul_int(int); +extern int M_pop_mul_int(void); + +#ifdef NO_FFT_MULTIPLY +extern void M_4_byte_multiply(UCHAR *, UCHAR *, UCHAR *); +#else +extern void M_fast_mul_fft(UCHAR *, UCHAR *, UCHAR *, int); +#endif + +/* + * the following algorithm is used in this fast multiply routine + * (sometimes called the divide-and-conquer technique.) + * + * assume we have 2 numbers (a & b) with 2N digits. + * + * let : a = (2^N) * A1 + A0 , b = (2^N) * B1 + B0 + * + * where 'A1' is the 'most significant half' of 'a' and + * 'A0' is the 'least significant half' of 'a'. Same for + * B1 and B0. + * + * Now use the identity : + * + * 2N N N N + * ab = (2 + 2 ) A1B1 + 2 (A1-A0)(B0-B1) + (2 + 1)A0B0 + * + * + * The original problem of multiplying 2 (2N) digit numbers has + * been reduced to 3 multiplications of N digit numbers plus some + * additions, subtractions, and shifts. + * + * The fast multiplication algorithm used here uses the above + * identity in a recursive process. This algorithm results in + * O(n ^ 1.585) growth. + */ + + +/****************************************************************************/ +void M_free_all_fmul() +{ + int k; + + if (M_firsttimef == FALSE) + { + m_apm_free(M_ain); + m_apm_free(M_bin); + + for (k = 0; k < M_STACK_SIZE; k++) + { + if (mul_stack_data_size[k] != 0) + { + MAPM_FREE(mul_stack_data[k]); + } + } + + M_firsttimef = TRUE; + } +} +/****************************************************************************/ +void M_push_mul_int(int val) +{ + exp_stack[++exp_stack_ptr] = val; +} +/****************************************************************************/ +int M_pop_mul_int() +{ + return(exp_stack[exp_stack_ptr--]); +} +/****************************************************************************/ +void M_fmul_split(UCHAR *x1, UCHAR *x0, UCHAR *xin, int nbytes) +{ + memcpy(x1, xin, nbytes); + memcpy(x0, (xin + nbytes), nbytes); +} +/****************************************************************************/ +void M_fast_multiply(M_APM rr, M_APM aa, M_APM bb) +{ + void *vp; + int ii, k, nexp, sign; + + if (M_firsttimef) + { + M_firsttimef = FALSE; + + for (k = 0; k < M_STACK_SIZE; k++) + mul_stack_data_size[k] = 0; + + size_flag = M_get_sizeof_int(); + bit_limit = 8 * size_flag + 1; + + M_ain = m_apm_init(); + M_bin = m_apm_init(); + } + + exp_stack_ptr = -1; + M_mul_stack_ptr = -1; + + m_apm_copy(M_ain, aa); + m_apm_copy(M_bin, bb); + + sign = M_ain->m_apm_sign * M_bin->m_apm_sign; + nexp = M_ain->m_apm_exponent + M_bin->m_apm_exponent; + + if (M_ain->m_apm_datalength >= M_bin->m_apm_datalength) + ii = M_ain->m_apm_datalength; + else + ii = M_bin->m_apm_datalength; + + ii = (ii + 1) >> 1; + ii = M_next_power_of_2(ii); + + /* Note: 'ii' must be >= 4 here. this is guaranteed + by the caller: m_apm_multiply + */ + + k = 2 * ii; /* required size of result, in bytes */ + + M_apm_pad(M_ain, k); /* fill out the data so the number of */ + M_apm_pad(M_bin, k); /* bytes is an exact power of 2 */ + + if (k > rr->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(rr->m_apm_data, (k + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_fast_multiply\', Out of memory"); + } + + rr->m_apm_malloclength = k + 28; + rr->m_apm_data = (UCHAR *)vp; + } + +#ifdef NO_FFT_MULTIPLY + + M_fmul_div_conq(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); +#else + + /* + * if the numbers are *really* big, use the divide-and-conquer + * routine first until the numbers are small enough to be handled + * by the FFT algorithm. If the numbers are already small enough, + * call the FFT multiplication now. + * + * Note that 'ii' here is (and must be) an exact power of 2. + */ + + if (size_flag == 2) /* if still using 16 bit compilers .... */ + { + M_fast_mul_fft(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); + } + else /* >= 32 bit compilers */ + { + if (ii > (MAX_FFT_BYTES + 2)) + { + M_fmul_div_conq(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); + } + else + { + M_fast_mul_fft(rr->m_apm_data, M_ain->m_apm_data, + M_bin->m_apm_data, ii); + } + } + +#endif + + rr->m_apm_sign = sign; + rr->m_apm_exponent = nexp; + rr->m_apm_datalength = 4 * ii; + + M_apm_normalize(rr); +} +/****************************************************************************/ +/* + * This is the recursive function to perform the multiply. The + * design intent here is to have no local variables. Any local + * data that needs to be saved is saved on one of the two stacks. + */ +void M_fmul_div_conq(UCHAR *rr, UCHAR *aa, UCHAR *bb, int sz) +{ + +#ifdef NO_FFT_MULTIPLY + + if (sz == 4) /* multiply 4x4 yielding an 8 byte result */ + { + M_4_byte_multiply(rr, aa, bb); + return; + } + +#else + + /* + * if the numbers are now small enough, let the FFT algorithm + * finish up. + */ + + if (sz == MAX_FFT_BYTES) + { + M_fast_mul_fft(rr, aa, bb, sz); + return; + } + +#endif + + memset(rr, 0, (2 * sz)); /* zero out the result */ + mii = sz >> 1; + + itmp = M_get_stack_ptr(mii); + M_push_mul_int(itmp); + + fmul_a1 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(mii); + fmul_a0 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(2 * sz); + fmul_a9 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(mii); + fmul_b1 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(mii); + fmul_b0 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(2 * sz); + fmul_b9 = mul_stack_data[itmp]; + + itmp = M_get_stack_ptr(2 * sz); + fmul_t0 = mul_stack_data[itmp]; + + M_fmul_split(fmul_a1, fmul_a0, aa, mii); + M_fmul_split(fmul_b1, fmul_b0, bb, mii); + + stmp = M_fmul_subtract(fmul_a9, fmul_a1, fmul_a0, mii); + stmp *= M_fmul_subtract(fmul_b9, fmul_b0, fmul_b1, mii); + + M_push_mul_int(stmp); + M_push_mul_int(mii); + + M_fmul_div_conq(fmul_t0, fmul_a0, fmul_b0, mii); + + mii = M_pop_mul_int(); + stmp = M_pop_mul_int(); + itmp = M_pop_mul_int(); + + M_push_mul_int(itmp); + M_push_mul_int(stmp); + M_push_mul_int(mii); + + /* to restore all stack variables ... + fmul_a1 = mul_stack_data[itmp]; + fmul_a0 = mul_stack_data[itmp+1]; + fmul_a9 = mul_stack_data[itmp+2]; + fmul_b1 = mul_stack_data[itmp+3]; + fmul_b0 = mul_stack_data[itmp+4]; + fmul_b9 = mul_stack_data[itmp+5]; + fmul_t0 = mul_stack_data[itmp+6]; + */ + + fmul_a1 = mul_stack_data[itmp]; + fmul_b1 = mul_stack_data[itmp + 3]; + fmul_t0 = mul_stack_data[itmp + 6]; + + memcpy((rr + sz), fmul_t0, sz); /* first 'add', result is now zero */ + /* so we just copy in the bytes */ + M_fmul_add(rr, fmul_t0, mii, sz); + + M_fmul_div_conq(fmul_t0, fmul_a1, fmul_b1, mii); + + mii = M_pop_mul_int(); + stmp = M_pop_mul_int(); + itmp = M_pop_mul_int(); + + M_push_mul_int(itmp); + M_push_mul_int(stmp); + M_push_mul_int(mii); + + fmul_a9 = mul_stack_data[itmp + 2]; + fmul_b9 = mul_stack_data[itmp + 5]; + fmul_t0 = mul_stack_data[itmp + 6]; + + M_fmul_add(rr, fmul_t0, 0, sz); + M_fmul_add(rr, fmul_t0, mii, sz); + + if (stmp != 0) + M_fmul_div_conq(fmul_t0, fmul_a9, fmul_b9, mii); + + mii = M_pop_mul_int(); + stmp = M_pop_mul_int(); + itmp = M_pop_mul_int(); + + fmul_t0 = mul_stack_data[itmp + 6]; + + /* + * if the sign of (A1 - A0)(B0 - B1) is positive, ADD to + * the result. if it is negative, SUBTRACT from the result. + */ + + if (stmp < 0) + { + fmul_a9 = mul_stack_data[itmp + 2]; + fmul_b9 = mul_stack_data[itmp + 5]; + + memset(fmul_b9, 0, (2 * sz)); + memcpy((fmul_b9 + mii), fmul_t0, sz); + M_fmul_subtract(fmul_a9, rr, fmul_b9, (2 * sz)); + memcpy(rr, fmul_a9, (2 * sz)); + } + + if (stmp > 0) + M_fmul_add(rr, fmul_t0, mii, sz); + + M_mul_stack_ptr -= 7; +} +/****************************************************************************/ +/* + * special addition function for use with the fast multiply operation + */ +void M_fmul_add(UCHAR *r, UCHAR *a, int offset, int sz) +{ + int i, j; + UCHAR carry; + + carry = 0; + j = offset + sz; + i = sz; + + while (TRUE) + { + r[--j] += carry + a[--i]; + + if (r[j] >= 100) + { + r[j] -= 100; + carry = 1; + } + else + carry = 0; + + if (i == 0) + break; + } + + if (carry) + { + while (TRUE) + { + r[--j] += 1; + + if (r[j] < 100) + break; + + r[j] -= 100; + } + } +} +/****************************************************************************/ +/* + * special subtraction function for use with the fast multiply operation + */ +int M_fmul_subtract(UCHAR *r, UCHAR *a, UCHAR *b, int sz) +{ + int k, jtmp, sflag, nb, borrow; + + nb = sz; + sflag = 0; /* sign flag: assume the numbers are equal */ + + /* + * find if a > b (so we perform a-b) + * or a < b (so we perform b-a) + */ + + for (k = 0; k < nb; k++) + { + if (a[k] < b[k]) + { + sflag = -1; + break; + } + + if (a[k] > b[k]) + { + sflag = 1; + break; + } + } + + if (sflag == 0) + { + memset(r, 0, nb); /* zero out the result */ + } + else + { + k = nb; + borrow = 0; + + while (TRUE) + { + k--; + + if (sflag == 1) + jtmp = (int)a[k] - ((int)b[k] + borrow); + else + jtmp = (int)b[k] - ((int)a[k] + borrow); + + if (jtmp >= 0) + { + r[k] = (UCHAR)jtmp; + borrow = 0; + } + else + { + r[k] = (UCHAR)(100 + jtmp); + borrow = 1; + } + + if (k == 0) + break; + } + } + + return(sflag); +} +/****************************************************************************/ +int M_next_power_of_2(int n) +{ + int ct, k; + + if (n <= 2) + return(n); + + k = 2; + ct = 0; + + while (TRUE) + { + if (k >= n) + break; + + k = k << 1; + + if (++ct == bit_limit) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'M_next_power_of_2\', ERROR :sizeof(int) too small ??"); + } + } + + return(k); +} +/****************************************************************************/ +int M_get_stack_ptr(int sz) +{ + int i, k; + UCHAR *cp; + + k = ++M_mul_stack_ptr; + + /* if size is 0, just need to malloc and return */ + if (mul_stack_data_size[k] == 0) + { + if ((i = sz) < 16) + i = 16; + + if ((cp = (UCHAR *)MAPM_MALLOC(i + 4)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_ptr_error_msg); + } + + mul_stack_data[k] = cp; + mul_stack_data_size[k] = i; + } + else /* it has been malloc'ed, see if it's big enough */ + { + if (sz > mul_stack_data_size[k]) + { + cp = mul_stack_data[k]; + + if ((cp = (UCHAR *)MAPM_REALLOC(cp, (sz + 4))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_ptr_error_msg); + } + + mul_stack_data[k] = cp; + mul_stack_data_size[k] = sz; + } + } + + return(k); +} +/****************************************************************************/ + +#ifdef NO_FFT_MULTIPLY + +/* + * multiply a 4 byte number by a 4 byte number + * yielding an 8 byte result. each byte contains + * a base 100 'digit', i.e.: range from 0-99. + * + * MSB LSB + * + * a,b [0] [1] [2] [3] + * result [0] ..... [7] + */ + +void M_4_byte_multiply(UCHAR *r, UCHAR *a, UCHAR *b) +{ + int jj; + unsigned int *ip, t1, rr[8]; + + memset(rr, 0, (8 * sizeof(int))); /* zero out result */ + jj = 3; + ip = rr + 5; + + /* + * loop for one number [b], un-roll the inner 'loop' [a] + * + * accumulate partial sums in UINT array, release carries + * and convert back to base 100 at the end + */ + + while (1) + { + t1 = (unsigned int)b[jj]; + ip += 2; + + *ip-- += t1 * a[3]; + *ip-- += t1 * a[2]; + *ip-- += t1 * a[1]; + *ip += t1 * a[0]; + + if (jj-- == 0) + break; + } + + jj = 7; + + while (1) + { + t1 = rr[jj] / 100; + r[jj] = (UCHAR)(rr[jj] - 100 * t1); + + if (jj == 0) + break; + + rr[--jj] += t1; + } +} + +#endif + +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmgues.cpp b/pgscript/utilities/m_apm/mapmgues.cpp new file mode 100644 index 0000000..e36c85b --- /dev/null +++ b/pgscript/utilities/m_apm/mapmgues.cpp @@ -0,0 +1,147 @@ + +/* + * M_APM - mapmgues.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the functions that generate the initial + * 'guesses' for the sqrt, cbrt, log, arcsin, and arccos functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void M_get_sqrt_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); /* sqrt algorithm actually finds 1/sqrt */ + m_apm_set_double(r, (1.0 / sqrt(dd))); +} +/****************************************************************************/ +/* + * for cbrt, log, asin, and acos we induce an error of 10 ^ -5. + * this enables the iterative routine to be more efficient + * by knowing exactly how accurate the initial guess is. + * + * this also prevents some corner conditions where the iterative + * functions may terminate too soon. + */ +/****************************************************************************/ +void M_get_cbrt_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + dd = log(dd) / 3.0; /* cbrt algorithm actually finds 1/cbrt */ + m_apm_set_double(r, (1.00001 / exp(dd))); +} +/****************************************************************************/ +void M_get_log_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + m_apm_set_double(r, (1.00001 * log(dd))); /* induce error of 10 ^ -5 */ +} +/****************************************************************************/ +/* + * the implementation of the asin & acos functions + * guarantee that 'a' is always < 0.85, so it is + * safe to multiply by a number > 1 + */ +void M_get_asin_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + m_apm_set_double(r, (1.00001 * asin(dd))); /* induce error of 10 ^ -5 */ +} +/****************************************************************************/ +void M_get_acos_guess(M_APM r, M_APM a) +{ + char buf[48]; + double dd; + + m_apm_to_string(buf, 15, a); + dd = atof(buf); + m_apm_set_double(r, (1.00001 * acos(dd))); /* induce error of 10 ^ -5 */ +} +/****************************************************************************/ +/* + convert a C 'double' into an M_APM value. +*/ +void m_apm_set_double(M_APM atmp, double dd) +{ + char *cp, *p, *ps, buf[64]; + + if (dd == 0.0) /* special case for 0 exactly */ + M_set_to_zero(atmp); + else + { + sprintf(buf, "%.14E", dd); + + if ((cp = strstr(buf, "E")) == NULL) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_set_double\', Invalid double input (likely a NAN or +/- INF)"); + + M_set_to_zero(atmp); + return; + } + + if (atoi(cp + sizeof(char)) == 0) + *cp = '\0'; + + p = cp; + + while (TRUE) + { + p--; + if (*p == '0' || *p == '.') + *p = ' '; + else + break; + } + + ps = buf; + p = buf; + + while (TRUE) + { + if ((*p = *ps) == '\0') + break; + + if (*ps++ != ' ') + p++; + } + + m_apm_set_string(atmp, buf); + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmhasn.cpp b/pgscript/utilities/m_apm/mapmhasn.cpp new file mode 100644 index 0000000..27dd518 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmhasn.cpp @@ -0,0 +1,132 @@ + +/* + * M_APM - mapmhasn.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Inverse Hyperbolic SIN, COS, & TAN functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * arcsinh(x) == log [ x + sqrt(x^2 + 1) ] + * + * also, use arcsinh(-x) == -arcsinh(x) + */ +void m_apm_arcsinh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp0, tmp1, tmp2; + + /* result is 0 if input is 0 */ + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + tmp0 = M_get_stack_var(); + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_absolute_value(tmp0, aa); + m_apm_multiply(tmp1, tmp0, tmp0); + m_apm_add(tmp2, tmp1, MM_One); + m_apm_sqrt(tmp1, (places + 6), tmp2); + m_apm_add(tmp2, tmp0, tmp1); + m_apm_log(rr, places, tmp2); + + rr->m_apm_sign = aa->m_apm_sign; /* fix final sign */ + + M_restore_stack(3); +} +/****************************************************************************/ +/* + * arccosh(x) == log [ x + sqrt(x^2 - 1) ] + * + * x >= 1.0 + */ +void m_apm_arccosh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2; + int ii; + + ii = m_apm_compare(aa, MM_One); + + if (ii == -1) /* x < 1 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arccosh\', Argument < 1"); + M_set_to_zero(rr); + return; + } + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + + m_apm_multiply(tmp1, aa, aa); + m_apm_subtract(tmp2, tmp1, MM_One); + m_apm_sqrt(tmp1, (places + 6), tmp2); + m_apm_add(tmp2, aa, tmp1); + m_apm_log(rr, places, tmp2); + + M_restore_stack(2); +} +/****************************************************************************/ +/* + * arctanh(x) == 0.5 * log [ (1 + x) / (1 - x) ] + * + * |x| < 1.0 + */ +void m_apm_arctanh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3; + int ii, local_precision; + + tmp1 = M_get_stack_var(); + + m_apm_absolute_value(tmp1, aa); + + ii = m_apm_compare(tmp1, MM_One); + + if (ii >= 0) /* |x| >= 1.0 */ + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_arctanh\', |Argument| >= 1"); + M_set_to_zero(rr); + M_restore_stack(1); + return; + } + + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + local_precision = places + 8; + + m_apm_add(tmp1, MM_One, aa); + m_apm_subtract(tmp2, MM_One, aa); + m_apm_divide(tmp3, local_precision, tmp1, tmp2); + m_apm_log(tmp2, local_precision, tmp3); + m_apm_multiply(tmp1, tmp2, MM_0_5); + m_apm_round(rr, places, tmp1); + + M_restore_stack(3); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmhsin.cpp b/pgscript/utilities/m_apm/mapmhsin.cpp new file mode 100644 index 0000000..cb6eeee --- /dev/null +++ b/pgscript/utilities/m_apm/mapmhsin.cpp @@ -0,0 +1,100 @@ + +/* + * M_APM - mapmhsin.c + * + * Copyright (C) 2000 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Hyperbolic SIN, COS, & TAN functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + * sinh(x) == 0.5 * [ exp(x) - exp(-x) ] + */ +void m_apm_sinh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3; + int local_precision; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + local_precision = places + 4; + + m_apm_exp(tmp1, local_precision, aa); + m_apm_reciprocal(tmp2, local_precision, tmp1); + m_apm_subtract(tmp3, tmp1, tmp2); + m_apm_multiply(tmp1, tmp3, MM_0_5); + m_apm_round(rr, places, tmp1); + + M_restore_stack(3); +} +/****************************************************************************/ +/* + * cosh(x) == 0.5 * [ exp(x) + exp(-x) ] + */ +void m_apm_cosh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3; + int local_precision; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + + local_precision = places + 4; + + m_apm_exp(tmp1, local_precision, aa); + m_apm_reciprocal(tmp2, local_precision, tmp1); + m_apm_add(tmp3, tmp1, tmp2); + m_apm_multiply(tmp1, tmp3, MM_0_5); + m_apm_round(rr, places, tmp1); + + M_restore_stack(3); +} +/****************************************************************************/ +/* + * tanh(x) == [ exp(x) - exp(-x) ] / [ exp(x) + exp(-x) ] + */ +void m_apm_tanh(M_APM rr, int places, M_APM aa) +{ + M_APM tmp1, tmp2, tmp3, tmp4; + int local_precision; + + tmp1 = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp3 = M_get_stack_var(); + tmp4 = M_get_stack_var(); + + local_precision = places + 4; + + m_apm_exp(tmp1, local_precision, aa); + m_apm_reciprocal(tmp2, local_precision, tmp1); + m_apm_subtract(tmp3, tmp1, tmp2); + m_apm_add(tmp4, tmp1, tmp2); + m_apm_divide(tmp1, local_precision, tmp3, tmp4); + m_apm_round(rr, places, tmp1); + + M_restore_stack(4); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmipwr.cpp b/pgscript/utilities/m_apm/mapmipwr.cpp new file mode 100644 index 0000000..a43d73a --- /dev/null +++ b/pgscript/utilities/m_apm/mapmipwr.cpp @@ -0,0 +1,98 @@ + +/* + * M_APM - mapmipwr.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the Integer Power function. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_integer_pow(M_APM rr, int places, M_APM aa, int mexp) +{ + M_APM tmp0, tmpy, tmpz; + int nexp, ii, signflag, local_precision; + + if (mexp == 0) + { + m_apm_copy(rr, MM_One); + return; + } + else + { + if (mexp > 0) + { + signflag = 0; + nexp = mexp; + } + else + { + signflag = 1; + nexp = -mexp; + } + } + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + tmp0 = M_get_stack_var(); + tmpy = M_get_stack_var(); + tmpz = M_get_stack_var(); + + local_precision = places + 8; + + m_apm_copy(tmpy, MM_One); + m_apm_copy(tmpz, aa); + + while (TRUE) + { + ii = nexp & 1; + nexp = nexp >> 1; + + if (ii != 0) /* exponent -was- odd */ + { + m_apm_multiply(tmp0, tmpy, tmpz); + m_apm_round(tmpy, local_precision, tmp0); + + if (nexp == 0) + break; + } + + m_apm_multiply(tmp0, tmpz, tmpz); + m_apm_round(tmpz, local_precision, tmp0); + } + + if (signflag) + { + m_apm_reciprocal(rr, places, tmpy); + } + else + { + m_apm_round(rr, places, tmpy); + } + + M_restore_stack(3); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmistr.cpp b/pgscript/utilities/m_apm/mapmistr.cpp new file mode 100644 index 0000000..e3c289a --- /dev/null +++ b/pgscript/utilities/m_apm/mapmistr.cpp @@ -0,0 +1,112 @@ + +/* + * M_APM - mapmistr.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains M_APM -> integer string function + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_to_integer_string(char *s, M_APM mtmp) +{ + void *vp; + UCHAR *ucp, numdiv, numrem; + char *cp, *p, sbuf[128]; + int ct, dl, numb, ii; + + vp = NULL; + ct = mtmp->m_apm_exponent; + dl = mtmp->m_apm_datalength; + + /* + * if |input| < 1, result is "0" + */ + + if (ct <= 0 || mtmp->m_apm_sign == 0) + { + s[0] = '0'; + s[1] = '\0'; + return; + } + + if (ct > 112) + { + if ((vp = (void *)MAPM_MALLOC((ct + 32) * sizeof(char))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, + "\'m_apm_to_integer_string\', Out of memory"); + } + + cp = (char *)vp; + } + else + { + cp = sbuf; + } + + p = cp; + ii = 0; + + /* handle a negative number */ + + if (mtmp->m_apm_sign == -1) + { + ii = 1; + *p++ = '-'; + } + + /* get num-bytes of data (#digits / 2) to use in the string */ + + if (ct > dl) + numb = (dl + 1) >> 1; + else + numb = (ct + 1) >> 1; + + ucp = mtmp->m_apm_data; + + while (TRUE) + { + M_get_div_rem_10((int)(*ucp++), &numdiv, &numrem); + + *p++ = numdiv + '0'; + *p++ = numrem + '0'; + + if (--numb == 0) + break; + } + + /* pad with trailing zeros if the exponent > datalength */ + + if (ct > dl) + memset(p, '0', (ct + 1 - dl)); + + cp[ct + ii] = '\0'; + strcpy(s, cp); + + if (vp != NULL) + MAPM_FREE(vp); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmpwr2.cpp b/pgscript/utilities/m_apm/mapmpwr2.cpp new file mode 100644 index 0000000..bf2a504 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmpwr2.cpp @@ -0,0 +1,107 @@ + +/* + * M_APM - mapmpwr2.c + * + * Copyright (C) 2002 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This file contains the Integer Power function and the result + * is NOT ROUNDED. The exponent must be an integer >= zero. + * + * This will typically be used in an application where full integer + * precision is required to be maintained. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_integer_pow_nr(M_APM rr, M_APM aa, int mexp) +{ + M_APM tmp0, tmpy, tmpz; + int nexp, ii; + + if (mexp == 0) + { + m_apm_copy(rr, MM_One); + return; + } + else + { + if (mexp < 0) + { + M_apm_log_error_msg(M_APM_RETURN, + "\'m_apm_integer_pow_nr\', Negative exponent"); + + M_set_to_zero(rr); + return; + } + } + + if (mexp == 1) + { + m_apm_copy(rr, aa); + return; + } + + if (mexp == 2) + { + m_apm_multiply(rr, aa, aa); + return; + } + + nexp = mexp; + + if (aa->m_apm_sign == 0) + { + M_set_to_zero(rr); + return; + } + + tmp0 = M_get_stack_var(); + tmpy = M_get_stack_var(); + tmpz = M_get_stack_var(); + + m_apm_copy(tmpy, MM_One); + m_apm_copy(tmpz, aa); + + while (TRUE) + { + ii = nexp & 1; + nexp = nexp >> 1; + + if (ii != 0) /* exponent -was- odd */ + { + m_apm_multiply(tmp0, tmpy, tmpz); + + if (nexp == 0) + break; + + m_apm_copy(tmpy, tmp0); + } + + m_apm_multiply(tmp0, tmpz, tmpz); + m_apm_copy(tmpz, tmp0); + } + + m_apm_copy(rr, tmp0); + + M_restore_stack(3); +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmrsin.cpp b/pgscript/utilities/m_apm/mapmrsin.cpp new file mode 100644 index 0000000..5c0d62c --- /dev/null +++ b/pgscript/utilities/m_apm/mapmrsin.cpp @@ -0,0 +1,164 @@ + +/* + * M_APM - mapmrsin.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the basic series expansion functions for + * the SIN / COS functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +/* + x^3 x^5 x^7 x^9 + sin(x) = x - --- + --- - --- + --- ... + 3! 5! 7! 9! +*/ +void M_raw_sin(M_APM rr, int places, M_APM xx) +{ + M_APM sum, term, tmp2, tmp7, tmp8; + int tolerance, flag, local_precision, dplaces; + long m1, m2; + + sum = M_get_stack_var(); + term = M_get_stack_var(); + tmp2 = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + + m_apm_copy(sum, xx); + m_apm_copy(term, xx); + m_apm_multiply(tmp8, xx, xx); + m_apm_round(tmp2, (places + 6), tmp8); + + dplaces = (places + 8) - xx->m_apm_exponent; + tolerance = xx->m_apm_exponent - (places + 4); + + m1 = 2L; + flag = 0; + + while (TRUE) + { + m_apm_multiply(tmp8, term, tmp2); + + if ((tmp8->m_apm_exponent < tolerance) || (tmp8->m_apm_sign == 0)) + break; + + local_precision = dplaces + term->m_apm_exponent; + + if (local_precision < 20) + local_precision = 20; + + m2 = m1 * (m1 + 1); + m_apm_set_long(tmp7, m2); + + m_apm_divide(term, local_precision, tmp8, tmp7); + + if (flag == 0) + { + m_apm_subtract(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + else + { + m_apm_add(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + + m1 += 2; + flag = 1 - flag; + } + + m_apm_round(rr, places, sum); + M_restore_stack(5); +} +/****************************************************************************/ +/* + x^2 x^4 x^6 x^8 + cos(x) = 1 - --- + --- - --- + --- ... + 2! 4! 6! 8! +*/ +void M_raw_cos(M_APM rr, int places, M_APM xx) +{ + M_APM sum, term, tmp7, tmp8, tmp9; + int tolerance, flag, local_precision, prev_exp; + long m1, m2; + + sum = M_get_stack_var(); + term = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_copy(sum, MM_One); + m_apm_copy(term, MM_One); + + m_apm_multiply(tmp8, xx, xx); + m_apm_round(tmp9, (places + 6), tmp8); + + local_precision = places + 8; + tolerance = -(places + 4); + prev_exp = 0; + + m1 = 1L; + flag = 0; + + while (TRUE) + { + m2 = m1 * (m1 + 1); + m_apm_set_long(tmp7, m2); + + m_apm_multiply(tmp8, term, tmp9); + m_apm_divide(term, local_precision, tmp8, tmp7); + + if (flag == 0) + { + m_apm_subtract(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + else + { + m_apm_add(tmp7, sum, term); + m_apm_copy(sum, tmp7); + } + + if ((term->m_apm_exponent < tolerance) || (term->m_apm_sign == 0)) + break; + + if (m1 != 1L) + { + local_precision = local_precision + term->m_apm_exponent - prev_exp; + + if (local_precision < 20) + local_precision = 20; + } + + prev_exp = term->m_apm_exponent; + + m1 += 2; + flag = 1 - flag; + } + + m_apm_round(rr, places, sum); + M_restore_stack(5); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmsqrt.cpp b/pgscript/utilities/m_apm/mapmsqrt.cpp new file mode 100644 index 0000000..ed9d835 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmsqrt.cpp @@ -0,0 +1,130 @@ + +/* + * M_APM - mapmsqrt.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the SQRT function. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void m_apm_sqrt(M_APM rr, int places, M_APM aa) +{ + M_APM last_x, guess, tmpN, tmp7, tmp8, tmp9; + int ii, bflag, nexp, tolerance, dplaces; + + if (aa->m_apm_sign <= 0) + { + if (aa->m_apm_sign == -1) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_sqrt\', Negative argument"); + } + + M_set_to_zero(rr); + return; + } + + last_x = M_get_stack_var(); + guess = M_get_stack_var(); + tmpN = M_get_stack_var(); + tmp7 = M_get_stack_var(); + tmp8 = M_get_stack_var(); + tmp9 = M_get_stack_var(); + + m_apm_copy(tmpN, aa); + + /* + normalize the input number (make the exponent near 0) so + the 'guess' function will not over/under flow on large + magnitude exponents. + */ + + nexp = aa->m_apm_exponent / 2; + tmpN->m_apm_exponent -= 2 * nexp; + + M_get_sqrt_guess(guess, tmpN); /* actually gets 1/sqrt guess */ + + tolerance = places + 4; + dplaces = places + 16; + bflag = FALSE; + + m_apm_negate(last_x, MM_Ten); + + /* Use the following iteration to calculate 1 / sqrt(N) : + + X = 0.5 * X * [ 3 - N * X^2 ] + n+1 + */ + + ii = 0; + + while (TRUE) + { + m_apm_multiply(tmp9, tmpN, guess); + m_apm_multiply(tmp8, tmp9, guess); + m_apm_round(tmp7, dplaces, tmp8); + m_apm_subtract(tmp9, MM_Three, tmp7); + m_apm_multiply(tmp8, tmp9, guess); + m_apm_multiply(tmp9, tmp8, MM_0_5); + + if (bflag) + break; + + m_apm_round(guess, dplaces, tmp9); + + /* force at least 2 iterations so 'last_x' has valid data */ + + if (ii != 0) + { + m_apm_subtract(tmp7, guess, last_x); + + if (tmp7->m_apm_sign == 0) + break; + + /* + * if we are within a factor of 4 on the error term, + * we will be accurate enough after the *next* iteration + * is complete. (note that the sign of the exponent on + * the error term will be a negative number). + */ + + if ((-4 * tmp7->m_apm_exponent) > tolerance) + bflag = TRUE; + } + + m_apm_copy(last_x, guess); + ii++; + } + + /* + * multiply by the starting number to get the final + * sqrt and then adjust the exponent since we found + * the sqrt of the normalized number. + */ + + m_apm_multiply(tmp8, tmp9, tmpN); + m_apm_round(rr, places, tmp8); + rr->m_apm_exponent += nexp; + + M_restore_stack(6); +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/mapmstck.cpp b/pgscript/utilities/m_apm/mapmstck.cpp new file mode 100644 index 0000000..1eb567e --- /dev/null +++ b/pgscript/utilities/m_apm/mapmstck.cpp @@ -0,0 +1,108 @@ + +/* + * M_APM - mapmstck.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains the stack implementation for using + * local M_APM variables. + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static int M_stack_ptr = -1; +static int M_last_init = -1; +static int M_stack_size = 0; + +static const char *M_stack_err_msg = "\'M_get_stack_var\', Out of memory"; + +static M_APM *M_stack_array; + +/****************************************************************************/ +void M_free_all_stck() +{ + int k; + + if (M_last_init >= 0) + { + for (k = 0; k <= M_last_init; k++) + m_apm_free(M_stack_array[k]); + + M_stack_ptr = -1; + M_last_init = -1; + M_stack_size = 0; + + MAPM_FREE(M_stack_array); + } +} +/****************************************************************************/ +M_APM M_get_stack_var() +{ + void *vp; + + if (++M_stack_ptr > M_last_init) + { + if (M_stack_size == 0) + { + M_stack_size = 18; + if ((vp = MAPM_MALLOC(M_stack_size * sizeof(M_APM))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_err_msg); + } + + M_stack_array = (M_APM *)vp; + } + + if ((M_last_init + 4) >= M_stack_size) + { + M_stack_size += 12; + if ((vp = MAPM_REALLOC(M_stack_array, + (M_stack_size * sizeof(M_APM)))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_stack_err_msg); + } + + M_stack_array = (M_APM *)vp; + } + + M_stack_array[M_stack_ptr] = m_apm_init(); + M_stack_array[M_stack_ptr + 1] = m_apm_init(); + M_stack_array[M_stack_ptr + 2] = m_apm_init(); + M_stack_array[M_stack_ptr + 3] = m_apm_init(); + + M_last_init = M_stack_ptr + 3; + + /* printf("M_last_init = %d \n",M_last_init); */ + } + + return(M_stack_array[M_stack_ptr]); +} +/****************************************************************************/ +void M_restore_stack(int count) +{ + M_stack_ptr -= count; +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmutil.cpp b/pgscript/utilities/m_apm/mapmutil.cpp new file mode 100644 index 0000000..33cde26 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmutil.cpp @@ -0,0 +1,475 @@ + +/* + * M_APM - mapmutil.c + * + * Copyright (C) 1999 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * + * This file contains various utility functions needed by the + * library in addition to some basic user callable functions. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +static UCHAR *M_mul_div = NULL; +static UCHAR *M_mul_rem = NULL; + +static UCHAR M_mul_div_10[100]; +static UCHAR M_mul_rem_10[100]; + +static int M_util_firsttime = TRUE; +static int M_firsttime3 = TRUE; + +static M_APM M_work_0_5; + +static const char *M_init_error_msg = "\'m_apm_init\', Out of memory"; + +/****************************************************************************/ +M_APM m_apm_init() +{ + M_APM atmp; + + if (M_firsttime3) + { + M_firsttime3 = FALSE; + M_init_util_data(); + M_init_trig_globals(); + } + + if ((atmp = (M_APM)MAPM_MALLOC(sizeof(M_APM_struct))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_init_error_msg); + } + + atmp->m_apm_id = M_APM_IDENT; + atmp->m_apm_malloclength = 80; + atmp->m_apm_datalength = 1; + atmp->m_apm_refcount = 1; /* not for us, for MAPM C++ class */ + atmp->m_apm_exponent = 0; + atmp->m_apm_sign = 0; + + if ((atmp->m_apm_data = (UCHAR *)MAPM_MALLOC(84)) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, M_init_error_msg); + } + + atmp->m_apm_data[0] = 0; + return(atmp); +} +/****************************************************************************/ +void m_apm_free(M_APM atmp) +{ + if (atmp->m_apm_id == M_APM_IDENT) + { + atmp->m_apm_id = 0x0FFFFFF0L; + MAPM_FREE(atmp->m_apm_data); + MAPM_FREE(atmp); + } + else + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_free\', Invalid M_APM variable"); + } +} +/****************************************************************************/ +void M_free_all_util() +{ + if (M_util_firsttime == FALSE) + { + m_apm_free(M_work_0_5); + M_util_firsttime = TRUE; + } + + if (M_firsttime3 == FALSE) + { + MAPM_FREE(M_mul_div); + MAPM_FREE(M_mul_rem); + + M_mul_div = NULL; + M_mul_rem = NULL; + M_firsttime3 = TRUE; + } +} +/****************************************************************************/ +/* + * just a dummy wrapper to keep some compilers from complaining + */ +int M_get_sizeof_int() +{ + return(sizeof(int)); +} +/****************************************************************************/ +void M_init_util_data() +{ + int k; + UCHAR ndiv, nrem; + + if (M_mul_div != NULL) + return; + + M_mul_div = (UCHAR *)MAPM_MALLOC(10000 * sizeof(UCHAR)); + M_mul_rem = (UCHAR *)MAPM_MALLOC(10000 * sizeof(UCHAR)); + + if (M_mul_div == NULL || M_mul_rem == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_init_util_data\', Out of memory"); + } + + ndiv = 0; + nrem = 0; + + for (k = 0; k < 100; k++) + { + M_mul_div_10[k] = ndiv; + M_mul_rem_10[k] = nrem; + + if (++nrem == 10) + { + nrem = 0; + ndiv++; + } + } + + ndiv = 0; + nrem = 0; + + for (k = 0; k < 10000; k++) + { + M_mul_div[k] = ndiv; + M_mul_rem[k] = nrem; + + if (++nrem == 100) + { + nrem = 0; + ndiv++; + } + } +} +/****************************************************************************/ +void M_get_div_rem_addr(UCHAR **ndivp, UCHAR **nremp) +{ + *ndivp = M_mul_div; + *nremp = M_mul_rem; +} +/****************************************************************************/ +void M_get_div_rem(int tbl_lookup, UCHAR *ndiv, UCHAR *nrem) +{ + *ndiv = M_mul_div[tbl_lookup]; + *nrem = M_mul_rem[tbl_lookup]; +} +/****************************************************************************/ +void M_get_div_rem_10(int tbl_lookup, UCHAR *ndiv, UCHAR *nrem) +{ + *ndiv = M_mul_div_10[tbl_lookup]; + *nrem = M_mul_rem_10[tbl_lookup]; +} +/****************************************************************************/ +void m_apm_round(M_APM btmp, int places, M_APM atmp) +{ + int ii; + + if (M_util_firsttime) + { + M_util_firsttime = FALSE; + + M_work_0_5 = m_apm_init(); + m_apm_set_string(M_work_0_5, "5"); + } + + ii = places + 1; + + if (atmp->m_apm_datalength <= ii) + { + m_apm_copy(btmp, atmp); + return; + } + + M_work_0_5->m_apm_exponent = atmp->m_apm_exponent - ii; + + if (atmp->m_apm_sign > 0) + m_apm_add(btmp, atmp, M_work_0_5); + else + m_apm_subtract(btmp, atmp, M_work_0_5); + + btmp->m_apm_datalength = ii; + M_apm_normalize(btmp); +} +/****************************************************************************/ +void M_apm_normalize(M_APM atmp) +{ + int i, index, datalength, exponent; + UCHAR *ucp, numdiv, numrem, numrem2; + + if (atmp->m_apm_sign == 0) + return; + + datalength = atmp->m_apm_datalength; + exponent = atmp->m_apm_exponent; + + /* make sure trailing bytes/chars are 0 */ + /* the following function will adjust the 'datalength' */ + /* we want the original value and will fix it later */ + + M_apm_pad(atmp, (datalength + 3)); + + while (TRUE) /* remove lead-in '0' if any */ + { + M_get_div_rem_10((int)atmp->m_apm_data[0], &numdiv, &numrem); + + if (numdiv >= 1) /* number is normalized, done here */ + break; + + index = (datalength + 1) >> 1; + + if (numrem == 0) /* both nibbles are 0, we can move full bytes */ + { + i = 0; + ucp = atmp->m_apm_data; + + while (TRUE) /* find out how many '00' bytes we can move */ + { + if (*ucp != 0) + break; + + ucp++; + i++; + } + + memmove(atmp->m_apm_data, ucp, (index + 1 - i)); + datalength -= 2 * i; + exponent -= 2 * i; + } + else + { + for (i = 0; i < index; i++) + { + M_get_div_rem_10((int)atmp->m_apm_data[i + 1], &numdiv, &numrem2); + atmp->m_apm_data[i] = 10 * numrem + numdiv; + numrem = numrem2; + } + + datalength--; + exponent--; + } + } + + while (TRUE) /* remove trailing '0' if any */ + { + index = ((datalength + 1) >> 1) - 1; + + if ((datalength & 1) == 0) /* back-up full bytes at a time if the */ + { + /* current length is an even number */ + ucp = atmp->m_apm_data + index; + if (*ucp == 0) + { + while (TRUE) + { + datalength -= 2; + index--; + ucp--; + + if (*ucp != 0) + break; + } + } + } + + M_get_div_rem_10((int)atmp->m_apm_data[index], &numdiv, &numrem); + + if (numrem != 0) /* last digit non-zero, all done */ + break; + + if ((datalength & 1) != 0) /* if odd, then first char must be non-zero */ + { + if (numdiv != 0) + break; + } + + if (datalength == 1) + { + atmp->m_apm_sign = 0; + exponent = 0; + break; + } + + datalength--; + } + + atmp->m_apm_datalength = datalength; + atmp->m_apm_exponent = exponent; +} +/****************************************************************************/ +void M_apm_scale(M_APM ctmp, int count) +{ + int ii, numb, ct; + UCHAR *chp, numdiv, numdiv2, numrem; + void *vp; + + ct = count; + + ii = (ctmp->m_apm_datalength + ct + 1) >> 1; + if (ii > ctmp->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (ii + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_scale\', Out of memory"); + } + + ctmp->m_apm_malloclength = ii + 28; + ctmp->m_apm_data = (UCHAR *)vp; + } + + if ((ct & 1) != 0) /* move odd number first */ + { + ct--; + chp = ctmp->m_apm_data; + ii = ((ctmp->m_apm_datalength + 1) >> 1) - 1; + + if ((ctmp->m_apm_datalength & 1) == 0) + { + /* + * original datalength is even: + * + * uv wx yz becomes --> 0u vw xy z0 + */ + + numdiv = 0; + + while (TRUE) + { + M_get_div_rem_10((int)chp[ii], &numdiv2, &numrem); + + chp[ii + 1] = 10 * numrem + numdiv; + numdiv = numdiv2; + + if (ii == 0) + break; + + ii--; + } + + chp[0] = numdiv2; + } + else + { + /* + * original datalength is odd: + * + * uv wx y0 becomes --> 0u vw xy + */ + + M_get_div_rem_10((int)chp[ii], &numdiv2, &numrem); + + if (ii == 0) + { + chp[0] = numdiv2; + } + else + { + while (TRUE) + { + M_get_div_rem_10((int)chp[ii - 1], &numdiv, &numrem); + + chp[ii] = 10 * numrem + numdiv2; + numdiv2 = numdiv; + + if (--ii == 0) + break; + } + + chp[0] = numdiv; + } + } + + ctmp->m_apm_exponent++; + ctmp->m_apm_datalength++; + } + + /* ct is even here */ + + if (ct > 0) + { + numb = (ctmp->m_apm_datalength + 1) >> 1; + ii = ct >> 1; + + memmove((ctmp->m_apm_data + ii), ctmp->m_apm_data, numb); + memset(ctmp->m_apm_data, 0, ii); + + ctmp->m_apm_datalength += ct; + ctmp->m_apm_exponent += ct; + } +} +/****************************************************************************/ +void M_apm_pad(M_APM ctmp, int new_length) +{ + int num1, numb, ct; + UCHAR numdiv, numrem; + void *vp; + + ct = new_length; + if (ctmp->m_apm_datalength >= ct) + return; + + numb = (ct + 1) >> 1; + if (numb > ctmp->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(ctmp->m_apm_data, (numb + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'M_apm_pad\', Out of memory"); + } + + ctmp->m_apm_malloclength = numb + 28; + ctmp->m_apm_data = (UCHAR *)vp; + } + + num1 = (ctmp->m_apm_datalength + 1) >> 1; + + if ((ctmp->m_apm_datalength & 1) != 0) + { + M_get_div_rem_10((int)ctmp->m_apm_data[num1 - 1], &numdiv, &numrem); + ctmp->m_apm_data[num1 - 1] = 10 * numdiv; + } + + memset((ctmp->m_apm_data + num1), 0, (numb - num1)); + ctmp->m_apm_datalength = ct; +} +/****************************************************************************/ + +/* + debug_dsp(cc) + M_APM cc; + { +static char buffer[8192]; + +m_apm_to_string(buffer, -1, cc); +printf("(dsp func) = [%s]\n",buffer); + + } +*/ + diff --git a/pgscript/utilities/m_apm/mapmutl1.cpp b/pgscript/utilities/m_apm/mapmutl1.cpp new file mode 100644 index 0000000..815a581 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmutl1.cpp @@ -0,0 +1,47 @@ + +/* + * M_APM - mapmutl1.c + * + * Copyright (C) 2003 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + + * + * This file contains the utility function 'M_apm_log_error_msg' + * + * This is the only function in this file so a user can supply + * their own custom version easily without changing the base library. + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +void M_apm_log_error_msg(int fatal, const char *message) +{ + if (fatal) + { + fprintf(stderr, "MAPM Error: %s\n", message); + exit(100); + } + else + { + fprintf(stderr, "MAPM Warning: %s\n", message); + } +} +/****************************************************************************/ + diff --git a/pgscript/utilities/m_apm/mapmutl2.cpp b/pgscript/utilities/m_apm/mapmutl2.cpp new file mode 100644 index 0000000..93e6c94 --- /dev/null +++ b/pgscript/utilities/m_apm/mapmutl2.cpp @@ -0,0 +1,329 @@ + +/* + * M_APM - mapmutl2.c + * + * Copyright (C) 2002 - 2007 Michael C. Ring + * + * Permission to use, copy, and distribute this software and its + * documentation for any purpose with or without fee is hereby granted, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + * + * Permission to modify the software is granted. Permission to distribute + * the modified code is granted. Modifications are to be distributed by + * using the file 'license.txt' as a template to modify the file header. + * 'license.txt' is available in the official MAPM distribution. + * + * This software is provided "as is" without express or implied warranty. + */ + +/* + * This file contains various utility functions + * + */ + +#include "pgAdmin3.h" +#include "pgscript/utilities/mapm-lib/m_apm_lc.h" + +/****************************************************************************/ +int m_apm_sign(M_APM atmp) +{ + return(atmp->m_apm_sign); +} +/****************************************************************************/ +int m_apm_exponent(M_APM atmp) +{ + if (atmp->m_apm_sign == 0) + return(0); + else + return(atmp->m_apm_exponent - 1); +} +/****************************************************************************/ +int m_apm_significant_digits(M_APM atmp) +{ + return(atmp->m_apm_datalength); +} +/****************************************************************************/ +int m_apm_is_integer(M_APM atmp) +{ + if (atmp->m_apm_sign == 0) + return(1); + + if (atmp->m_apm_exponent >= atmp->m_apm_datalength) + return(1); + else + return(0); +} +/****************************************************************************/ +int m_apm_is_even(M_APM aa) +{ + int ii, jj; + + if (aa->m_apm_sign == 0) + return(1); + + ii = aa->m_apm_datalength; + jj = aa->m_apm_exponent; + + if (jj < ii) + { + M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_is_even\', Non-integer input"); + return(0); + } + + if (jj > ii) + return(1); + + ii = ((ii + 1) >> 1) - 1; + ii = (int)aa->m_apm_data[ii]; + + if ((jj & 1) != 0) /* exponent is odd */ + ii = ii / 10; + + if ((ii & 1) == 0) + return(1); + else + return(0); +} +/****************************************************************************/ +int m_apm_is_odd(M_APM bb) +{ + if (m_apm_is_even(bb)) + return(0); + else + return(1); +} +/****************************************************************************/ +void M_set_to_zero(M_APM z) +{ + z->m_apm_datalength = 1; + z->m_apm_sign = 0; + z->m_apm_exponent = 0; + z->m_apm_data[0] = 0; +} +/****************************************************************************/ +void m_apm_negate(M_APM d, M_APM s) +{ + m_apm_copy(d, s); + if (d->m_apm_sign != 0) + d->m_apm_sign = -(d->m_apm_sign); +} +/****************************************************************************/ +void m_apm_absolute_value(M_APM d, M_APM s) +{ + m_apm_copy(d, s); + if (d->m_apm_sign != 0) + d->m_apm_sign = 1; +} +/****************************************************************************/ +void m_apm_copy(M_APM dest, M_APM src) +{ + int j; + void *vp; + + j = (src->m_apm_datalength + 1) >> 1; + if (j > dest->m_apm_malloclength) + { + if ((vp = MAPM_REALLOC(dest->m_apm_data, (j + 32))) == NULL) + { + /* fatal, this does not return */ + + M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_copy\', Out of memory"); + } + + dest->m_apm_malloclength = j + 28; + dest->m_apm_data = (UCHAR *)vp; + } + + dest->m_apm_datalength = src->m_apm_datalength; + dest->m_apm_exponent = src->m_apm_exponent; + dest->m_apm_sign = src->m_apm_sign; + + memcpy(dest->m_apm_data, src->m_apm_data, j); +} +/****************************************************************************/ +int m_apm_compare(M_APM ltmp, M_APM rtmp) +{ + int llen, rlen, lsign, rsign, i, j, lexp, rexp; + + llen = ltmp->m_apm_datalength; + rlen = rtmp->m_apm_datalength; + + lsign = ltmp->m_apm_sign; + rsign = rtmp->m_apm_sign; + + lexp = ltmp->m_apm_exponent; + rexp = rtmp->m_apm_exponent; + + if (rsign == 0) + return(lsign); + + if (lsign == 0) + return(-rsign); + + if (lsign == -rsign) + return(lsign); + + /* signs are the same, check the exponents */ + + if (lexp > rexp) + goto E1; + + if (lexp < rexp) + goto E2; + + /* signs and exponents are the same, check the data */ + + if (llen < rlen) + j = (llen + 1) >> 1; + else + j = (rlen + 1) >> 1; + + for (i = 0; i < j; i++) + { + if (ltmp->m_apm_data[i] > rtmp->m_apm_data[i]) + goto E1; + + if (ltmp->m_apm_data[i] < rtmp->m_apm_data[i]) + goto E2; + } + + if (llen == rlen) + return(0); + else + { + if (llen > rlen) + goto E1; + else + goto E2; + } + +E1: + + if (lsign == 1) + return(1); + else + return(-1); + +E2: + + if (lsign == 1) + return(-1); + else + return(1); +} +/****************************************************************************/ +/* + * + * convert a signed long int to ASCII in base 10 + * + */ +void M_long_2_ascii(char *output, long input) +{ + long t, m; + int i, j; + char *p, tbuf[64]; + + m = input; + p = output; + i = 0; + t = 2147000000L; /* something < 2^31 */ + + if ((m > t) || (m < -t)) /* handle the bigger numbers with 'sprintf'. */ + { + /* let them worry about wrap-around problems */ + sprintf(p, "%ld", m); /* at 'LONG_MIN', etc. */ + } + else + { + if (m < 0) /* handle the sign */ + { + *p++ = '-'; + m = -m; + } + + while (TRUE) /* build the digits in reverse order */ + { + t = m / 10; + j = (int)(m - (10 * t)); + tbuf[i++] = (char)(j + '0'); + m = t; + + if (t == 0) + break; + } + + while (TRUE) /* fill output string in the correct order */ + { + *p++ = tbuf[--i]; + if (i == 0) + break; + } + + *p = '\0'; + } +} +/****************************************************************************/ +/* + * this function will convert a string to lowercase + */ +char *M_lowercase(char *s) +{ + char *p; + + p = s; + + while (TRUE) + { + if (*p >= 'A' && *p <= 'Z') + *p += 'a' - 'A'; + + if (*p++ == '\0') break; + } + return(s); +} +/****************************************************************************/ +/* returns char position of first occurrence of s2 in s1 + or -1 if no match found +*/ +int M_strposition(char *s1, char *s2) +{ + register char ch1, ch2; + char *p0, *p1, *p2; + int ct; + + ct = -1; + p0 = s1; + + if (*s2 == '\0') return(-1); + + while (TRUE) + { + ct++; + p1 = p0; + p2 = s2; + ch2 = *p2; + + while (TRUE) /* scan until first char matches */ + { + if ((ch1 = *p1) == '\0') return(-1); + if (ch1 == ch2) break; + p1++; + ct++; + } + + p2++; /* check remainder of 2 strings */ + p1++; + p0 = p1; + + while (TRUE) + { + if ((ch2 = *p2) == '\0') return(ct); + if (*p1 != ch2) break; + p1++; + p2++; + } + } +} +/****************************************************************************/ diff --git a/pgscript/utilities/m_apm/module.mk b/pgscript/utilities/m_apm/module.mk new file mode 100644 index 0000000..2ab8737 --- /dev/null +++ b/pgscript/utilities/m_apm/module.mk @@ -0,0 +1,54 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/utilities/m_apm/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/utilities/m_apm/mapm5sin.cpp \ + pgscript/utilities/m_apm/mapmasin.cpp \ + pgscript/utilities/m_apm/mapmasn0.cpp \ + pgscript/utilities/m_apm/mapmcbrt.cpp \ + pgscript/utilities/m_apm/mapmcnst.cpp \ + pgscript/utilities/m_apm/mapmfact.cpp \ + pgscript/utilities/m_apm/mapmfmul.cpp \ + pgscript/utilities/m_apm/mapmgues.cpp \ + pgscript/utilities/m_apm/mapmhasn.cpp \ + pgscript/utilities/m_apm/mapmhsin.cpp \ + pgscript/utilities/m_apm/mapmipwr.cpp \ + pgscript/utilities/m_apm/mapmistr.cpp \ + pgscript/utilities/m_apm/mapmpwr2.cpp \ + pgscript/utilities/m_apm/mapmrsin.cpp \ + pgscript/utilities/m_apm/mapmsqrt.cpp \ + pgscript/utilities/m_apm/mapmstck.cpp \ + pgscript/utilities/m_apm/mapmutil.cpp \ + pgscript/utilities/m_apm/mapmutl1.cpp \ + pgscript/utilities/m_apm/mapmutl2.cpp \ + pgscript/utilities/m_apm/mapm_add.cpp \ + pgscript/utilities/m_apm/mapm_cpi.cpp \ + pgscript/utilities/m_apm/mapm_div.cpp \ + pgscript/utilities/m_apm/mapm_exp.cpp \ + pgscript/utilities/m_apm/mapm_fam.cpp \ + pgscript/utilities/m_apm/mapm_fft.cpp \ + pgscript/utilities/m_apm/mapm_flr.cpp \ + pgscript/utilities/m_apm/mapm_fpf.cpp \ + pgscript/utilities/m_apm/mapm_gcd.cpp \ + pgscript/utilities/m_apm/mapm_lg2.cpp \ + pgscript/utilities/m_apm/mapm_lg3.cpp \ + pgscript/utilities/m_apm/mapm_lg4.cpp \ + pgscript/utilities/m_apm/mapm_log.cpp \ + pgscript/utilities/m_apm/mapm_mul.cpp \ + pgscript/utilities/m_apm/mapm_pow.cpp \ + pgscript/utilities/m_apm/mapm_rcp.cpp \ + pgscript/utilities/m_apm/mapm_rnd.cpp \ + pgscript/utilities/m_apm/mapm_set.cpp \ + pgscript/utilities/m_apm/mapm_sin.cpp + +EXTRA_DIST += \ + pgscript/utilities/m_apm/module.mk + diff --git a/pgscript/utilities/module.mk b/pgscript/utilities/module.mk new file mode 100644 index 0000000..72ca07c --- /dev/null +++ b/pgscript/utilities/module.mk @@ -0,0 +1,23 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/pgscript/utilities/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + pgscript/utilities/pgsAlloc.cpp \ + pgscript/utilities/pgsContext.cpp \ + pgscript/utilities/pgsDriver.cpp \ + pgscript/utilities/pgsMapm.cpp \ + pgscript/utilities/pgsThread.cpp \ + pgscript/utilities/pgsUtilities.cpp + +EXTRA_DIST += \ + pgscript/utilities/module.mk + +include pgscript/utilities/m_apm/module.mk diff --git a/pgscript/utilities/pgsAlloc.cpp b/pgscript/utilities/pgsAlloc.cpp new file mode 100644 index 0000000..96f324f --- /dev/null +++ b/pgscript/utilities/pgsAlloc.cpp @@ -0,0 +1,123 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" + +#if defined(PGSDEBUG) + +#include "pgscript/utilities/pgsAlloc.h" +#include +#include + +#undef new +#undef delete + +pgsAlloc::pgsAlloc() +{ + +} + +void pgsAlloc::add_malloc(const pgsMallocInfo &malloc_info) +{ + m_malloc_info[malloc_info.ptr] = malloc_info; +} + +void pgsAlloc::rm_malloc(const void *ptr) +{ + if (m_malloc_info.size() != 0) + { + pgsMallocInfoMap::iterator it = m_malloc_info.find(ptr); + if (it != m_malloc_info.end()) + { + m_malloc_info.erase(it); + } + } +} + +void pgsAlloc::dump() +{ + pgsMallocInfoMap::const_iterator it = m_malloc_info.begin(); + for (it = m_malloc_info.begin(); it != m_malloc_info.end(); it++) + { + const pgsMallocInfo &info = it->second; + + wxLogError(wxString() << info.filename << wxT(":") + << info.line_nb << wxT(" - ") << (int) info.ptr + << wxT(" of size ") << info.size); + } +} + +void *pgsAlloc::pmalloc(size_t size, const char *filename, size_t line_nb) +{ + // Nothing to do if there is nothing to allocate + if (size == 0) return 0; + + void *ptr = 0; + ptr = malloc(size); + + // Add allocation in the allocation map + pgsMallocInfo malloc_info; + malloc_info.ptr = ptr; + malloc_info.size = size; + malloc_info.filename = wxString(filename, wxConvFile); + malloc_info.line_nb = line_nb; + this->add_malloc(malloc_info); + + return ptr; +} + +void pgsAlloc::pfree(void *ptr) +{ + // Remove information from the map if this piece of data exists + this->rm_malloc(ptr); + + // Delete the data + free(ptr); +} + +pgsAlloc &pgsAlloc::instance() +{ + static pgsAlloc x; + return x; +} + +void *operator new(size_t size) throw (std::bad_alloc) +{ + return malloc(size); +} + +void *operator new[](size_t size) throw (std::bad_alloc) +{ + return malloc(size); +} + +void *operator new(size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc) +{ + return pgsAlloc::instance().pmalloc(size, filename, line_nb); +} + +void *operator new[](size_t size, const char *filename, size_t line_nb) +throw (std::bad_alloc) +{ + return pgsAlloc::instance().pmalloc(size, filename, line_nb); +} + +void operator delete(void *ptr) throw() +{ + pgsAlloc::instance().pfree(ptr); +} + +void operator delete[](void *ptr) throw() +{ + pgsAlloc::instance().pfree(ptr); +} + +#endif diff --git a/pgscript/utilities/pgsContext.cpp b/pgscript/utilities/pgsContext.cpp new file mode 100644 index 0000000..6de0147 --- /dev/null +++ b/pgscript/utilities/pgsContext.cpp @@ -0,0 +1,134 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsContext.h" + +#include +#include +#include +#include "pgscript/objects/pgsNumber.h" +#include "pgscript/objects/pgsString.h" +#include "pgscript/statements/pgsExpressionStmt.h" + +#include +WX_DEFINE_LIST(pgsListExpression); + +pgsContext::pgsContext(pgsOutputStream &cout) : + m_cout(cout) +{ + +} + +pgsContext::~pgsContext() +{ + +} + +pgsVariable *pgsContext::zero() +{ + pgsVariable *zero = pnew pgsNumber(wxT("0")); + push_var(zero); + return zero; +} + +pgsVariable *pgsContext::one() +{ + pgsVariable *one = pnew pgsNumber(wxT("1")); + push_var(one); + return one; +} + +pgsVariable *pgsContext::seed() +{ + pgsVariable *seed = pnew pgsNumber(wxString() << wxDateTime::GetTimeNow()); + push_var(seed); + return seed; +} + +pgsVariable *pgsContext::encoding() +{ + pgsVariable *encoding = pnew pgsString(wxLocale::GetSystemEncodingName()); + push_var(encoding); + return encoding; +} + +pgsStmtList *pgsContext::stmt_list(pgsThread *app) +{ + pgsStmtList *stmt_list = pnew pgsStmtList(m_cout, app); + push_stmt(stmt_list); + return stmt_list; +} + +void pgsContext::add_column(const wxString &column) +{ + m_columns.Add(column); +} + +const wxArrayString &pgsContext::columns() +{ + return m_columns; +} + +void pgsContext::clear_columns() +{ + m_columns.Clear(); +} + +void pgsContext::push_var(pgsExpression *var) +{ + wxLogScriptVerbose(wxT("PUSH EXPR %s"), var->value().c_str()); + m_vars.push_back(var); +} + +void pgsContext::pop_var() +{ + wxLogScriptVerbose(wxT("POP EXPR %s"), m_vars.back()->value().c_str()); + m_vars.pop_back(); +} + +size_t pgsContext::size_vars() const +{ + return m_vars.GetCount(); +} + +void pgsContext::push_stmt(pgsStmt *stmt) +{ + wxLogScriptVerbose(wxT("PUSH STMT %s"), wxString(typeid(*stmt).name(), + wxConvUTF8).c_str()); + m_stmts.push_back(stmt); +} + +void pgsContext::pop_stmt() +{ + wxLogScriptVerbose(wxT("POP STMT %s"), wxString(typeid(*(m_stmts.back())) + .name(), wxConvUTF8).c_str()); + m_stmts.pop_back(); +} + +size_t pgsContext::size_stmts() const +{ + return m_stmts.GetCount(); +} + +void pgsContext::clear_stacks() +{ + while (!m_vars.empty()) + { + pdelete(m_vars.back()); + m_vars.pop_back(); + } + + while (!m_stmts.empty()) + { + pdelete(m_stmts.back()); + m_stmts.pop_back(); + } +} diff --git a/pgscript/utilities/pgsDriver.cpp b/pgscript/utilities/pgsDriver.cpp new file mode 100644 index 0000000..4d04765 --- /dev/null +++ b/pgscript/utilities/pgsDriver.cpp @@ -0,0 +1,81 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsDriver.h" +#include "pgscript/utilities/pgsThread.h" +#include "pgscript/utilities/pgsUtilities.h" + +#include +#include + +namespace pgscript +{ + +pgsDriver::pgsDriver(class pgsContext &_context, class pgsProgram &_program, + class pgsThread &_thread) : + trace_scanning(false), trace_parsing(false), context(_context), + program(_program), thread(_thread) +{ + wxLogScript(wxT("Driver created")); +} + +pgsDriver::~pgsDriver() +{ + wxLogScript(wxT("Driver destroyed")); +} + +bool pgsDriver::parse_stream(std::istream &in) +{ + pgsScanner scanner(wxConvUTF8, &in); + scanner.set_debug(trace_scanning); + this->lexer = &scanner; + + pgsParser parser(*this); + parser.set_debug_level(trace_parsing); + return (parser.parse() == 0); +} + +bool pgsDriver::parse_file(const wxString &filename, wxMBConv &conv) +{ + wxFileName file_path(filename); + if (file_path.FileExists() && file_path.IsFileReadable()) + { + wxFFile file(filename); + wxString input; + file.ReadAll(&input, conv); + return parse_string(input); + } + else + { + wxLogError(wxT("PGSCRIPT: File %s does not exist"), filename.c_str()); + return false; + } +} + +bool pgsDriver::parse_string(const wxString &input) +{ + std::istringstream iss(std::string(input.mb_str(wxConvUTF8))); + return parse_stream(iss); +} + +void pgsDriver::error(const class location &l, const wxString &m) +{ + std::ostringstream oss; + oss << l; + thread.last_error_line(l.begin.line); + thread.LockOutput(); + context.m_cout << PGSOUTERROR + << wx_static_cast(const wxString, wxString(oss.str() + .c_str(), wxConvUTF8)) << wxT(": ") << m << wxT("\n"); + thread.UnlockOutput(); +} + +} // namespace pgscript diff --git a/pgscript/utilities/pgsMapm.cpp b/pgscript/utilities/pgsMapm.cpp new file mode 100644 index 0000000..a0189bc --- /dev/null +++ b/pgscript/utilities/pgsMapm.cpp @@ -0,0 +1,76 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsMapm.h" +#include +#include +#include + +#include +WX_DEFINE_OBJARRAY(pgsVectorMapm); + +wxString pgsMapm::pgs_mapm_str(const MAPM &m, const bool &as_int) +{ + if (m.is_integer() || as_int) + { + wxString str = pgs_mapm_str_fixed(m); + str = str.substr(0, str.find_last_of('.')); // Remove .0 at the end of an integer + return str; + } + else + { + return pgs_mapm_str_float(m); + } +} + +MAPM pgsMapm::pgs_mapm_round(const MAPM &m) +{ + return MAPM(pgs_mapm_str(m, true).mb_str()); +} + +wxString pgsMapm::pgs_mapm_str_fixed(const MAPM &m) +{ + char *const res = m.toFixPtStringExp(-1, '.', ' ', INT_MAX); + wxString str(res, wxConvUTF8); + free(res); + return str; +} + +wxString pgsMapm::pgs_mapm_str_float(const MAPM &m) +{ + int str_len = m.significant_digits(); + + { + wxStringOutputStream sos; + wxTextOutputStream tos(sos); + tos << abs(m.exponent()); + str_len += sos.GetString().Length(); + } + + { + wxStringOutputStream sos; + wxTextOutputStream tos(sos); + tos << str_len; + str_len = m.significant_digits() + 10 + sos.GetString().Length(); + } + + char *res = pnew char[str_len]; + m.toString(res, -1); + wxString result(res, wxConvUTF8); + pdeletea(res); + + return result; +} + +MAPM pgsMapm::pgs_str_mapm(const wxString &s) +{ + return std::string(s.mb_str()).c_str(); +} diff --git a/pgscript/utilities/pgsThread.cpp b/pgscript/utilities/pgsThread.cpp new file mode 100644 index 0000000..d79a4cc --- /dev/null +++ b/pgscript/utilities/pgsThread.cpp @@ -0,0 +1,94 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsThread.h" + +#include "pgscript/pgsApplication.h" +#include "pgscript/statements/pgsProgram.h" +#include "pgscript/utilities/pgsContext.h" +#include "pgscript/utilities/pgsDriver.h" + +pgsThread::pgsThread(pgsVarMap &vars, wxSemaphore &mutex, + pgConn *connection, const wxString &file, pgsOutputStream &out, + pgsApplication &app, wxMBConv *conv) : + wxThread(wxTHREAD_DETACHED), m_vars(vars), m_mutex(mutex), + m_connection(connection), m_data(file), m_out(out), + m_app(app), m_conv(conv), m_last_error_line(-1) +{ + wxLogScript(wxT("Starting thread")); + m_mutex.Wait(); +} + +pgsThread::pgsThread(pgsVarMap &vars, wxSemaphore &mutex, + pgConn *connection, const wxString &string, pgsOutputStream &out, + pgsApplication &app) : + wxThread(wxTHREAD_DETACHED), m_vars(vars), m_mutex(mutex), + m_connection(connection), m_data(string), m_out(out), + m_app(app), m_conv(0), m_last_error_line(-1) +{ + wxLogScript(wxT("Starting thread")); + m_mutex.Wait(); +} + +pgsThread::~pgsThread() +{ + wxLogScript(wxT("Finishing thread")); + m_app.Complete(); + m_mutex.Post(); + wxLogScript(wxT("Thread finished")); +} + +void *pgsThread::Entry() +{ + pgsProgram program(m_vars); + pgsContext context(m_out); + pgscript::pgsDriver driver(context, program, *this); + + if (m_conv) + { + wxLogScript(wxT("Parsing file")); + driver.parse_file(m_data, *m_conv); + wxLogScript(wxT("File parsed")); + } + else + { + wxLogScript(wxT("Parsing string")); + driver.parse_string(m_data); + wxLogScript(wxT("String parsed")); + } + + return 0; +} + +pgConn *pgsThread::connection() +{ + return m_connection; +} + +void pgsThread::LockOutput() +{ + m_app.LockOutput(); +} + +void pgsThread::UnlockOutput() +{ + m_app.UnlockOutput(); +} + +void pgsThread::last_error_line(int line) +{ + m_last_error_line = line; +} + +int pgsThread::last_error_line() const +{ + return m_last_error_line; +} diff --git a/pgscript/utilities/pgsUtilities.cpp b/pgscript/utilities/pgsUtilities.cpp new file mode 100644 index 0000000..f765c46 --- /dev/null +++ b/pgscript/utilities/pgsUtilities.cpp @@ -0,0 +1,33 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgScript - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////////////////// + + +#include "pgAdmin3.h" +#include "pgscript/utilities/pgsUtilities.h" + +wxString pgsUtilities::uniform_line_returns(wxString s) +{ + s.Replace(wxT("\r\n"), wxT("\n")); + s.Replace(wxT("\r"), wxT("\n")); + return s; +} + +wxString pgsUtilities::escape_quotes(wxString s) +{ + s.Replace(wxT("\\"), wxT("\\\\")); + s.Replace(wxT("'"), wxT("''")); + return s; +} + +wxString pgsUtilities::unescape_quotes(wxString s) +{ + s.Replace(wxT("''"), wxT("'")); + s.Replace(wxT("\\'"), wxT("'")); + return s; +} diff --git a/precomp.cpp b/precomp.cpp new file mode 100644 index 0000000..f110652 --- /dev/null +++ b/precomp.cpp @@ -0,0 +1,18 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// precomp.cpp - precompiled header +// +////////////////////////////////////////////////////////////////////////// + +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#endif + +#include + +#include "pgAdmin3.h" diff --git a/pro_scheduler/pgproJob.cpp b/pro_scheduler/pgproJob.cpp new file mode 100644 index 0000000..1b664b9 --- /dev/null +++ b/pro_scheduler/pgproJob.cpp @@ -0,0 +1,462 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgproJob.h - PostgreSQL Agent Job +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgObject.h" +#include "schema/pgCollection.h" +#include "schema/pgDatabase.h" +#include "pro_scheduler/pgproJob.h" + +pgproJob::pgproJob(const wxString &newName) + : pgServerObject(projobFactory, newName) +{ +} + +wxString pgproJob::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pro_scheduler job"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pro_scheduler job"); + break; + case PROPERTIESREPORT: + message = _("pro_scheduler job properties report"); + break; + case PROPERTIES: + message = _("pgAgent job properties"); + break; + case DDLREPORT: + message = _("pro_scheduler job DDL report"); + break; + case DEPENDENCIESREPORT: + message = _("pro_scheduler job dependencies report"); + break; + case DEPENDENCIES: + message = _("pro_scheduler job dependencies"); + break; + case DEPENDENTSREPORT: + message = _("pro_scheduler job dependents report"); + break; + case DEPENDENTS: + message = _("pro_scheduler job dependents"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop job \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop job?"); + break; + } + + if (!message.IsEmpty() && !(kindOfMessage == DROPEXCLUDINGDEPS || kindOfMessage == DROPTITLE)) + message += wxT(" - ") + GetName(); + + return message; +} + +int pgproJob::GetIconId() +{ + if (GetEnabled()) + if (GetStatus()==wxT("working")) return projobFactory.GetRunId(); + else + return projobFactory.GetIconId(); + else + return projobFactory.GetDisabledId(); +} + + +wxMenu *pgproJob::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (1) // check priv. + { + //stepFactory.AppendMenu(menu); + //scheduleFactory.AppendMenu(menu); + } + return menu; +} +wxString pgproJob::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- pro_scheduler job: ") + GetName() + wxT("\n\n"); + sql += wxT("-- SELECT schedule.set_job_attributes( ") + NumToStr(GetRecId()) + wxT(", { });\n\n"); + sql += wxT("SELECT schedule.create_job(")+GetConnection()->qtDbString(GetRule())+wxT(");"); + } + return sql; +} + + +bool pgproJob::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("select schedule.drop_job(") + NumToStr(GetRecId())+wxT(")")); +} + + +void pgproJob::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child objects to Job.")); + + //browser->AppendCollection(this, scheduleFactory); + //browser->AppendCollection(this, stepFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetTryName()); + properties->AppendItem(_("ID"), GetRecId()); + properties->AppendYesNoItem(_("Enabled"), GetEnabled()); + //properties->AppendItem(_("Host agent"), GetHostAgent()); + // properties->AppendItem(_("Job class"), GetJobclass()); + properties->AppendItem(_("Started"), GetStarted()); + properties->AppendItem(_("Finished"), GetFinished()); + properties->AppendItem(_("Result"), GetStatus()); + properties->AppendItem(_("Crontab"), GetCrontab()); + //properties->AppendItem(_("Last result"), GetLastresult()); + properties->AppendItem(_("Runas"), GetRunAs()); + properties->AppendItem(_("Message"), GetMessage()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgproJob::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *job = 0; + + pgObject *obj = browser->GetObject(browser->GetItemParent(item)); + if (obj && obj->IsCollection()) + job = projobFactory.CreateObjects((pgCollection *)obj, 0, wxT("\n WHERE c.id=") + NumToStr(GetRecId())); + GetIconId(); + UpdateIcon(browser); + return job; +} + + + +pgObject *pgproJobFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgproJob *job = 0; + wxString sql= wxT("with last_job as (select cron,max(started) started from schedule.get_log() b group by cron), a as (select cron,scheduled_at,started,finished,status,message from schedule.get_active_jobs()), lastj as (select b.cron,") + wxT("coalesce((select scheduled_at from a where a.cron=b.cron),b.scheduled_at) scheduled_at") + wxT(",coalesce((select started from a where a.cron=b.cron),b.started) started") + wxT(",case when (select status from a where a.cron=b.cron)='working' then null else b.finished end finished") + wxT(",coalesce((select status from a where a.cron=b.cron),b.status) status") + wxT(",coalesce((select message from a where a.cron=b.cron),b.message) message") + wxT(" from schedule.get_log() b,last_job where b.cron=last_job.cron and b.started=last_job.started") + wxT(") select j.crontab cron,* from (select c.*,null stop,l.* from schedule.get_cron() c left join lastj l on c.id=l.cron) c") + wxT(" join lateral (select crontab from jsonb_to_record(c.rule) as (d int[],h int[],wd int[],m int[],crontab text,mi int[]) ) j on true") + wxT("") + wxT("") + wxT(" ") + restriction; + + if (!collection->GetConnection()->IsSuperuser()) { + size_t a=sql.Replace(wxT("get_log()"),wxT("get_user_log()")); + a=sql.Replace(wxT("get_cron()"),wxT("get_user_cron()")); + } + + pgSet *jobs = collection->GetConnection()->ExecuteSet(sql); + + + if (jobs) + { + int nCols = jobs->NumCols(); + while (!jobs->Eof()) + { + wxString status; + status=jobs->GetVal(wxT("status")); + if (status.IsNull()) status = _("Not run"); + + wxString name=jobs->GetVal(wxT("name"))+wxT("(")+jobs->GetVal(wxT("id"))+wxT(")"); + job = new pgproJob(name); + job->iSetStatus(status); + job->iSetTryName(jobs->GetVal(wxT("name"))); + job->iSetServer(collection->GetServer()); + job->iSetRecId(jobs->GetLong(wxT("id"))); + job->iSetComment(jobs->GetVal(wxT("comments"))); + + job->iSetEnabled(jobs->GetBool(wxT("active"))); + + wxString tmp; + tmp = jobs->GetVal(wxT("commands")); + if (tmp.find('{',0)==0) { tmp=wxT("[")+tmp.Mid(1,tmp.Len()-2)+wxT("]"); } + //tmp.Replace(wxT("{"), wxT("["),false); + //tmp.Replace(wxT("}"), wxT("]")); + + + job->iSetCommands(tmp); + job->iSetRunAs(jobs->GetVal(wxT("run_as"))); + job->iSetStarted(jobs->GetDateTime(wxT("started"))); + + job->iSetFinished(jobs->GetDateTime(wxT("finished"))); + job->iSetCrontab(jobs->GetVal(wxT("crontab"))); + //job->iSetNextrun(jobs->GetDateTime(wxT("jobnextrun"))); + + + job->iSetMessage(jobs->GetVal(wxT("message"))); + tmp=wxT(""); + int columnCount=0; + for (int col = 0 ; col < nCols ; col++) + { + wxString colname=jobs->ColName(col); + wxString vl=jobs->GetVal(col); + if (vl.IsEmpty()) continue; + if (colname==wxT("id") + ||colname==wxT("node") + ||colname==wxT("rule") + ||colname==wxT("owner")) continue; + + if (colname==wxT("broken")) break; + if (columnCount) + { + tmp += wxT(", "); + } + if (colname==wxT("commands")) vl=vl.Mid(1,vl.Length()-2); + else vl=wxT("\"")+vl+wxT("\""); + + tmp += wxT("\"")+colname+wxT("\"")+wxT(": ")+vl; + columnCount++; + } + job->iSetRule(wxT("{")+tmp+wxT("}")); + if (browser) + { + browser->AppendObject(collection, job); + jobs->MoveNext(); + } + else + break; + } + + delete jobs; + } + return job; +} + +void pgproJob::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT jlgid") + wxT(", jlgstatus") + wxT(", jlgstart") + wxT(", jlgduration") + wxT(", (jlgstart + jlgduration) AS endtime") + wxT(" FROM pgagent.pga_joblog\n") + wxT(" WHERE jlgjobid = ") + NumToStr(GetRecId()) + + wxT(" ORDER BY jlgstart DESC") + + wxT(" LIMIT ") + NumToStr(settings->GetMaxRows()); + + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for job %s"), GetFullIdentifier().c_str()); + wxString bu=GetConnection()->ExecuteScalar(wxT("select coalesce((select pg_table_is_visible(oid) from pg_class where relname='pg_log'),false)")); + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Log_time"), 95); + statistics->AddColumn(_("Critical"), 30); + statistics->AddColumn(_("Message"), 300); + statistics->AddColumn(_("Stage"), 40); + if ((bu==wxT("f"))||(!settings->GetASUTPstyle())||(DateToAnsiStr(GetStarted()).IsEmpty())) return ; + + wxString wxDTend = DateToAnsiStr(GetFinished()); + if (wxDTend.IsEmpty()) wxDTend=DateToAnsiStr(wxDateTime::Now()); + sql=wxT("select log_time,detail critical,message,application_name from pg_log l where l.log_time>'") + DateToAnsiStr(GetStarted())+ + wxT("'::timestamp - interval '1min' and l.log_time<='")+ wxDTend + + wxT("'::timestamp + interval '1min' and hint='")+GetTryName()+wxT("'"); + + pgSet *stats = GetConnection()->ExecuteSet(sql); + wxString critical; + wxDateTime startTime; + wxDateTime endTime; + + if (stats) + { + while (!stats->Eof()) + { + startTime.ParseDateTime(stats->GetVal(0)); + //endTime.ParseDateTime(stats->GetVal(4)); + critical=stats->GetVal(1); + long pos = statistics->AppendItem(DateToStr(startTime), critical, stats->GetVal(2)); + statistics->SetItem(pos, 3, stats->GetVal(3)); + //statistics->SetItem(pos, 4, stats->GetVal(3)); + + stats->MoveNext(); + } + delete stats; + } + } +} + +bool pgproJob::RunNow() +{ + //if (!GetConnection()->ExecuteVoid(wxT("select schedule.drop_job(") + NumToStr(GetRecId())+wxT(")"))) return false; + + return true; +} + + +pgproJobCollection::pgproJobCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgproJobCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on pgAgent jobs"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing pgAgent jobs"); + break; + case OBJECTSLISTREPORT: + message = _("pgAgent jobs list report"); + break; + } + + return message; +} +void pgproJob::SetEnabled(ctlTree *browser, const bool b) +{ + if (GetRecId() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("select schedule."); + if (enabled && !b) + sql += wxT("deactivate_job("); + else if (!enabled && b) + sql += wxT("activate_job("); + + sql += NumToStr(GetRecId())+wxT(")"); + GetConnection()->ExecuteVoid(sql); + } + enabled = b; + UpdateIcon(browser); +} + +dlgProperty *pgproJobFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; +} + + +///////////////////////////// + + +#include "images/job.pngc" +#include "images/jobs.pngc" +#include "images/jobdisabled.pngc" +#include "images/jobrun.pngc" + +pgproJobFactory::pgproJobFactory() + : pgServerObjFactory(__("pgAgent Job"), __("New Job"), __("Create a new Job."), job_png_img) +{ + metaType = PGM_PROJOB; + disabledId = addIcon(jobdisabled_png_img); + runId = addIcon(jobrun_png_img); + +} + + +pgCollection *pgproJobFactory::CreateCollection(pgObject *obj) +{ + return new pgproJobCollection(GetCollectionFactory(), (pgServer *)obj); +} + + +pgproJobFactory projobFactory; +static pgaCollectionFactory cf(&projobFactory, __("Jobs"), jobs_png_img); + +prorunNowFactory::prorunNowFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Run now"), _("Reschedule the job to run now.")); +} + + +wxWindow *prorunNowFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgproJob *)(obj))->RunNow()) + { + wxLogError(_("Failed to reschedule the job.")); + } + + form->Refresh(obj); + + return 0; +} + + +bool prorunNowFactory::CheckEnable(pgObject *obj) +{ + if (obj) + { + if (obj->GetMetaType() == PGM_PROJOB && !obj->IsCollection()) + return true; + } + return false; +} +enabledisableJobFactory::enabledisableJobFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Enabled?"), _("Âêëþ÷èòü èëè âûêëþ÷èòü çàäàíèå."), wxITEM_CHECK); +} + +wxWindow *enabledisableJobFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgproJob *)obj)->SetEnabled(form->GetBrowser(), !((pgproJob *)obj)->GetEnabled()); + //((pgproJob *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + //form->GetBrowser()->DeleteChildren(item); + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + //form->GetSqlPane()->SetReadOnly(false); + //form->GetSqlPane()->SetText(((pgproJob *)obj)->GetSql(form->GetBrowser())); + //form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + +bool enabledisableJobFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(projobFactory); +} + +bool enabledisableJobFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(projobFactory) && ((pgproJob *)obj)->GetEnabled(); +} diff --git a/schema/edbPackage.cpp b/schema/edbPackage.cpp new file mode 100644 index 0000000..1078430 --- /dev/null +++ b/schema/edbPackage.cpp @@ -0,0 +1,355 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackage.cpp - EnterpriseDB Package class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbPackage.h" +#include "schema/edbPackageFunction.h" +#include "schema/edbPackageVariable.h" + +edbPackage::edbPackage(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, packageFactory, newName) +{ +} + +wxString edbPackage::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop package cascaded?"); + break; + case DROPTITLE: + message = _("Drop package?"); + break; + case PROPERTIESREPORT: + message = _("Package properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Package properties"); + break; + case DDLREPORT: + message = _("Package DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Package DDL"); + break; + } + + return message; +} + + +bool edbPackage::IsUpToDate() +{ + pgConn *conn = GetDatabase()->GetConnection(); + if (!conn) + return false; + + wxString sql; + if(conn->EdbMinimumVersion(8, 2)) + sql = wxT("SELECT xmin FROM pg_namespace WHERE oid = ") + this->GetOidStr(); + else + sql = wxT("SELECT xmin FROM edb_package WHERE oid = ") + this->GetOidStr(); + + if (conn->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool edbPackage::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP PACKAGE ") + GetQuotedFullIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + +wxString edbPackage::GetSql(ctlTree *browser) +{ + wxString qtName = GetQuotedFullIdentifier(); + + if (sql.IsNull()) + { + sql = wxT("-- Package: ") + qtName + wxT("\n\n") + wxT("-- DROP PACKAGE ") + qtName; + + sql += wxT(";\n\n"); + sql += wxT("CREATE OR REPLACE PACKAGE ") + qtName + wxT("\nIS\n"); + sql += GetHeaderInner(); + sql += wxT("\nEND ") + qtIdent(GetName()) + wxT(";\n\n"); + + if (!GetBodyInner().Trim().IsEmpty()) + { + sql += wxT("CREATE OR REPLACE PACKAGE BODY ") + qtName + wxT("\nIS\n"); + sql += GetBodyInner(); + sql += wxT("\nEND ") + qtIdent(GetName()) + wxT(";\n\n"); + } + + sql += GetGrant(wxT("X"), wxT("PACKAGE ") + qtName); + + sql += wxT("\n"); + } + + return sql; +} + +wxString edbPackage::GetHeaderInner() +{ + return GetInner(GetHeader()); +} + +wxString edbPackage::GetBodyInner() +{ + return GetInner(GetBody()); +} + +wxString edbPackage::GetInner(const wxString &def) +{ + long start = 0, end = 0; + + wxStringTokenizer tkz(def, wxT("\t\r\n ")); + + // Find the opening AS/IF keyword + while ( tkz.HasMoreTokens() ) + { + wxString token = tkz.GetNextToken(); + if (token.Lower() == wxT("as") || token.Lower() == wxT("is")) + { + start = tkz.GetPosition(); + break; + } + } + + // Find the closing END keyword + wxString tmp = def; + tmp.Replace(wxT("\n"), wxT(" ")); + tmp.Replace(wxT("\r"), wxT(" ")); + tmp.Replace(wxT("\t"), wxT(" ")); + + int e1 = tmp.Lower().rfind(wxT(" end;")); + int e2 = tmp.Lower().rfind(wxT(" end ")); + + end = (e1 > e2 ? e1 : e2); + + return def.Mid(start, end - start); +} + +void edbPackage::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to package %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, packageFunctionFactory); + browser->AppendCollection(this, packageProcedureFactory); + browser->AppendCollection(this, packageVariableFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Header"), firstLineOnly(GetHeader())); + properties->AppendItem(_("Body"), firstLineOnly(GetBody())); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("System package?"), GetSystemObject()); + if (GetConnection()->EdbMinimumVersion(8, 2)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *edbPackage::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *package = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetConnection()->EdbMinimumVersion(8, 2)) + package = packageFactory.CreateObjects(coll, 0, wxT(" AND nspname=") + qtDbString(GetName())); + else + package = packageFactory.CreateObjects(coll, 0, wxT(" AND pkgname=") + qtDbString(GetName())); + } + + return package; +} + + + +pgObject *edbPackageFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbPackage *package = 0; + + wxString sql, pkgsrc; + + wxString whereclause; + + if (collection->GetConnection()->EdbMinimumVersion(9, 0)) + pkgsrc = wxT("pg_catalog.edb_get_packagebodydef(nsp.oid) AS pkgbodysrc, ") + wxT("pg_catalog.edb_get_packageheaddef(nsp.oid) AS pkgheadsrc,\n"); + else if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + pkgsrc = wxT("nspbodysrc AS pkgbodysrc, nspheadsrc AS pkgheadsrc,\n"); + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + { + whereclause = wxT(" WHERE nspparent = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n"); + if (collection->GetConnection()->EdbMinimumVersion(9, 2)) + whereclause += wxT(" AND nspobjecttype = 0 "); + + sql = wxT("SELECT nsp.oid, nsp.xmin, nspname AS pkgname,\n") + pkgsrc + + wxT(" nspacl AS pkgacl, pg_get_userbyid(nspowner) AS owner, description\n") + wxT(" FROM pg_namespace nsp") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n") + + whereclause + + restriction + + wxT(" ORDER BY nspname;"); + } + else + { + + sql = wxT("SELECT oid, xmin, *, pg_get_userbyid(pkgowner) AS owner\n") + wxT(" FROM edb_package") + wxT(" WHERE pkgnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n") + + restriction + + wxT(" ORDER BY pkgname;"); + } + + pgSet *packages = collection->GetDatabase()->ExecuteSet(sql); + + if (packages) + { + while (!packages->Eof()) + { + wxString name = packages->GetVal(wxT("pkgname")); + package = new edbPackage(collection->GetSchema(), name); + + package->iSetOid(packages->GetOid(wxT("oid"))); + package->iSetXid(packages->GetOid(wxT("xmin"))); + package->iSetDatabase(collection->GetDatabase()); + package->iSetOwner(packages->GetVal(wxT("owner"))); + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + package->iSetComment(packages->GetVal(wxT("description"))); + + // EnterpriseDB's CVS code has some new parser code + // which is stricter about the formatting of body & + // header code and leaves off trailing ;'s + wxString tmp = packages->GetVal(wxT("pkgheadsrc")).Strip(wxString::both); + if (!tmp.EndsWith(wxT(";"))) + package->iSetHeader(tmp + wxT(";")); + else + package->iSetHeader(tmp); + + tmp = packages->GetVal(wxT("pkgbodysrc")).Strip(wxString::both); + if (!tmp.EndsWith(wxT(";")) && !tmp.IsEmpty()) + package->iSetBody(tmp + wxT(";")); + else + package->iSetBody(tmp); + + package->iSetAcl(packages->GetVal(wxT("pkgacl"))); + + if (browser) + { + browser->AppendObject(collection, package); + packages->MoveNext(); + } + else + break; + } + delete packages; + } + return package; +} + +///////////////////////////// + +edbPackageCollection::edbPackageCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString edbPackageCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on packages"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing packages"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for packages"); + break; + case OBJECTSLISTREPORT: + message = _("Packages list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/package.pngc" +#include "images/packages.pngc" + +edbPackageFactory::edbPackageFactory() + : pgSchemaObjFactory(__("Package"), __("New Package..."), __("Create a new package."), package_png_img) +{ + metaType = EDB_PACKAGE; +} + + +pgCollection *edbPackageFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +edbPackageFactory packageFactory; +static pgaCollectionFactory cf(&packageFactory, __("Packages"), packages_png_img); diff --git a/schema/edbPackageFunction.cpp b/schema/edbPackageFunction.cpp new file mode 100644 index 0000000..4aff518 --- /dev/null +++ b/schema/edbPackageFunction.cpp @@ -0,0 +1,562 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageFunction.cpp - EnterpriseDB Package member function +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgfeatures.h" +#include "schema/edbPackageFunction.h" + + +edbPackageFunction::edbPackageFunction(edbPackage *newPackage, const wxString &newName) + : edbPackageObject(newPackage, packageFunctionFactory, newName) +{ +} + +edbPackageFunction::edbPackageFunction(edbPackage *newPackage, pgaFactory &factory, const wxString &newName) + : edbPackageObject(newPackage, factory, newName) +{ +} + +edbPackageProcedure::edbPackageProcedure(edbPackage *newPackage, const wxString &newName) + : edbPackageFunction(newPackage, packageProcedureFactory, newName) +{ +} + +wxString edbPackageFunction::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package function"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package function"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package function \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package function \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop package function cascaded?"); + break; + case DROPTITLE: + message = _("Drop package function?"); + break; + case PROPERTIESREPORT: + message = _("Package function properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Package function properties"); + break; + case DDLREPORT: + message = _("Package function DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Package function DDL"); + break; + } + + return message; +} + + +wxString edbPackageFunction::GetFullName() +{ + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + +wxString edbPackageProcedure::GetFullName() +{ + if (GetArgSigList().IsEmpty()) + return GetName(); + else + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + +wxString edbPackageFunction::GetArgListWithNames() +{ + wxString args; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + if (i > 0) + args += wxT(", "); + + wxString arg; + + if (GetIsProcedure()) + { + if (!argNamesArray.Item(i).IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + + if (!argModesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += argModesArray.Item(i); + else + arg += wxT(" ") + argModesArray.Item(i); + } + } + else + { + if (!argModesArray.Item(i).IsEmpty()) + arg += argModesArray.Item(i); + + if (!argNamesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + else + arg += wxT(" ") + qtIdent(argNamesArray.Item(i)); + } + } + + if (!arg.IsEmpty()) + arg += wxT(" ") + argTypesArray.Item(i); + else + arg += argTypesArray.Item(i); + + // Parameter default value + if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && + !argDefsArray.IsEmpty()) + { + if ((argModesArray.Item(i).IsEmpty() || + argModesArray.Item(i) == wxT("IN") || + argModesArray.Item(i) == wxT("VARIADIC")) && + !argDefsArray.Item(i).IsEmpty() && + i < argDefsArray.Count()) + arg += wxT(" DEFAULT ") + argDefsArray.Item(i); + } + + args += arg; + } + return args; +} + +wxString edbPackageFunction::GetArgSigList() +{ + wxString args; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + // OUT parameters are not considered part of the signature + if (argModesArray.Item(i) != wxT("OUT")) + { + if (i > 0) + args += wxT(", "); + + args += argTypesArray.Item(i); + } + } + return args; +} + +wxString edbPackageFunction::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Package Function: ") + GetName() + wxT("\n\n"); + sql += GetSource() + wxT("\n\n"); + } + + return sql; +} + +wxString edbPackageProcedure::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Package Procedure: ") + GetName() + wxT("\n\n"); + sql += GetSource() + wxT("\n\n"); + } + + return sql; +} + +void edbPackageFunction::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Argument count"), GetArgCount()); + properties->AppendItem(_("Arguments"), GetArgListWithNames()); + properties->AppendItem(_("Signature arguments"), GetArgSigList()); + if (!GetIsProcedure()) + properties->AppendItem(_("Return type"), GetReturnType()); + properties->AppendItem(_("Visibility"), GetVisibility()); + properties->AppendItem(_("Source"), firstLineOnly(GetSource())); + } +} + + + +pgObject *edbPackageFunction::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *packageFunction = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetConnection()->EdbMinimumVersion(8, 2)) + packageFunction = packageFunctionFactory.CreateObjects(coll, 0, wxT("\n AND pronamespace=") + GetPackage()->GetOidStr() + wxT(" AND proname='") + GetName() + wxT("'")); + else + packageFunction = packageFunctionFactory.CreateObjects(coll, 0, wxT("\n AND packageoid=") + GetPackage()->GetOidStr() + wxT(" AND eltname='") + GetName() + wxT("'")); + } + + return packageFunction; +} + + +///////////////////////////// + +edbPackageFunctionCollection::edbPackageFunctionCollection(pgaFactory *factory, edbPackage *pkg) + : edbPackageObjCollection(factory, pkg) +{ +} + +wxString edbPackageFunctionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package functions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package functions"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for package functions"); + break; + case OBJECTSLISTREPORT: + message = _("Package functions list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +edbPackageFunction *edbPackageFunctionFactory::AppendFunctions(pgObject *obj, edbPackage *package, ctlTree *browser, const wxString &restriction) +{ + edbPackageFunction *packageFunction = 0; + pgSet *packageFunctions; + + // Caches + cacheMap typeCache, exprCache; + wxString sql, argDefsCol; + + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + if (obj->GetConnection()->EdbMinimumVersion(8, 4)) + { + argDefsCol = wxT("pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS argdefaults, pronargdefaults, "); + } + else + { + argDefsCol = wxT("proargdefvals AS argdefaults, COALESCE(substring(array_dims(proargdefvals), E'1:(.*)\\]')::integer, 0) AS pronargdefaults, "); + } + } + + if (obj->GetConnection()->EdbMinimumVersion(8, 2)) + { + sql = wxT("SELECT pg_proc.oid, proname AS eltname, prorettype AS eltdatatype, pronargs AS nargs, proaccess AS visibility,\n") + wxT(" proallargtypes AS allargtypes, proargtypes AS argtypes, proargnames AS argnames, proargmodes AS argmodes,") + argDefsCol + wxT("\n") + wxT(" CASE WHEN format_type(prorettype, NULL) = 'void' THEN 'P' ELSE 'F' END AS eltclass\n") + wxT(" FROM pg_proc, pg_namespace\n") + + restriction + wxT("\n") + wxT(" AND pg_proc.pronamespace = pg_namespace.oid\n") + wxT(" ORDER BY eltname"); + } + else + { + sql = wxT("SELECT oid, eltname, eltdatatype, eltclass, nargs, visibility,\n") + wxT(" allargtypes, argtypes, argnames, argmodes\n") + wxT(" FROM edb_pkgelements\n") + + restriction + wxT("\n") + wxT(" ORDER BY eltname"); + } + + packageFunctions = obj->GetDatabase()->ExecuteSet(sql); + + pgSet *types = obj->GetDatabase()->ExecuteSet(wxT( + "SELECT oid, format_type(oid, NULL) AS typname FROM pg_type")); + + while(!types->Eof()) + { + typeCache[types->GetVal(wxT("oid"))] = types->GetVal(wxT("typname")); + types->MoveNext(); + } + + if (packageFunctions) + { + while (!packageFunctions->Eof()) + { + size_t inModeCnt = 0; + size_t defaultArgsCnt = 0; + if (packageFunctions->GetVal(wxT("eltclass")) == wxT("F")) + packageFunction = new edbPackageFunction(package, packageFunctions->GetVal(wxT("eltname"))); + else + packageFunction = new edbPackageProcedure(package, packageFunctions->GetVal(wxT("eltname"))); + + // Tokenize the arguments + wxStringTokenizer argTypesTkz(wxEmptyString), argModesTkz(wxEmptyString); + queryTokenizer argNamesTkz(wxEmptyString, (wxChar)','); + wxArrayString argDefValArray; + wxString tmp; + + // Types + tmp = packageFunctions->GetVal(wxT("allargtypes")); + if (!tmp.IsEmpty()) + argTypesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + else + { + tmp = packageFunctions->GetVal(wxT("argtypes")); + if (!tmp.IsEmpty()) + argTypesTkz.SetString(tmp); + } + + // Names + tmp = packageFunctions->GetVal(wxT("argnames")); + if (!tmp.IsEmpty()) + argNamesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + + // Modes + tmp = packageFunctions->GetVal(wxT("argmodes")); + if (!tmp.IsEmpty()) + argModesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + + // Function defaults + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + defaultArgsCnt = packageFunctions->GetLong(wxT("pronargdefaults")); + + if (defaultArgsCnt > 0) + { + tmp = packageFunctions->GetVal(wxT("argdefaults")); + + if (!tmp.IsEmpty()) + { + getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argDefValArray); + } + } + } + + // Now iterate the arguments and build the arrays + wxString type, name, mode; + + while (argTypesTkz.HasMoreTokens()) + { + // Add the arg type. This is a type oid, so + // look it up in the hashmap + type = argTypesTkz.GetNextToken(); + packageFunction->iAddArgType(typeCache[type]); + + // Now add the name, stripping the quotes if + // necessary. + name = argNamesTkz.GetNextToken(); + if (!name.IsEmpty()) + { + if (name[0] == '"') + name = name.Mid(1, name.Length() - 2); + packageFunction->iAddArgName(name); + } + else + packageFunction->iAddArgName(wxEmptyString); + + // Now the mode + mode = argModesTkz.GetNextToken(); + if (!mode.IsEmpty()) + { + if (mode == wxT('o') || mode == wxT("2")) + mode = wxT("OUT"); + else if (mode == wxT("b")) + if (packageFunctions->GetVal(wxT("eltclass")) == wxT("F")) + mode = wxT("IN OUT"); + else + mode = wxT("INOUT"); + else if (mode == wxT("3")) + mode = wxT("IN OUT"); + else if (mode == wxT("v")) + { + inModeCnt++; + mode = wxT("VARIADIC"); + } + else + { + inModeCnt++; + mode = wxT("IN"); + } + + packageFunction->iAddArgMode(mode); + } + else + packageFunction->iAddArgMode(wxEmptyString); + } + + // Finally the defaults, as we got them. + if (packageFunction->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS)) + { + size_t currINindex = 0; + while (inModeCnt) + { + for (size_t index = 0; index < packageFunction->GetArgTypesArray().Count(); index++) + { + wxString def = wxEmptyString; + if(packageFunction->GetArgModesArray()[index].IsEmpty() || + packageFunction->GetArgModesArray()[index] == wxT("IN") || + packageFunction->GetArgModesArray()[index] == wxT("VARIADIC")) + { + if (!argDefValArray.IsEmpty() && inModeCnt <= argDefValArray.GetCount()) + { + def = argDefValArray[currINindex++]; + + if (!def.IsEmpty() && def != wxT("-")) + { + // Only EDB 8.3 does not support get the + // default value using pg_get_expr directly + if (!packageFunction->GetConnection()->BackendMinimumVersion(8, 4)) + { + // Check the cache first - if we don't + // have a value, get it and cache for + // next time + wxString val = exprCache[def]; + + if (val == wxEmptyString) + { + val = obj->GetDatabase()->ExecuteScalar( + wxT("SELECT pg_get_expr('") + def.Mid(1, def.Length() - 2) + wxT("', 'pg_catalog.pg_class'::regclass)")); + exprCache[def] = val; + } + def = val; + } + } + else + { + def = wxEmptyString; + } + } + inModeCnt--; + } + packageFunction->iAddArgDef(def); + } + } + } + + packageFunction->iSetOid(packageFunctions->GetOid(wxT("oid"))); + packageFunction->iSetArgCount(packageFunctions->GetOid(wxT("nargs"))); + packageFunction->iSetReturnType(typeCache[packageFunctions->GetVal(wxT("eltdatatype"))]); + + if (packageFunctions->GetVal(wxT("visibility")) == wxT("+")) + packageFunction->iSetVisibility(_("Public")); + else if (packageFunctions->GetVal(wxT("visibility")) == wxT("-")) + packageFunction->iSetVisibility(_("Private")); + else + packageFunction->iSetVisibility(_("Unknown")); + + packageFunction->iSetSource(package->GetBodyInner()); + + if (browser) + { + browser->AppendObject(obj, packageFunction); + packageFunctions->MoveNext(); + } + else + break; + } + + delete packageFunctions; + delete types; + } + return packageFunction; +} + +pgObject *edbPackageFunctionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString restr; + + if (collection->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2)) + restr = wxT(" WHERE format_type(prorettype, NULL) != 'void' AND pronamespace = "); + else + restr = wxT(" WHERE eltclass = 'F' AND packageoid = "); + + restr += ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr(); + restr += restriction; + + return AppendFunctions(collection, ((edbPackageObjCollection *)collection)->GetPackage(), browser, restr); +} + +pgObject *edbPackageProcedureFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString restr; + + if (collection->GetDatabase()->GetConnection()->EdbMinimumVersion(8, 2)) + restr = wxT(" WHERE format_type(prorettype, NULL) = 'void' AND pronamespace = "); + else + restr = wxT(" WHERE eltclass = 'P' AND packageoid = "); + + restr += ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr(); + restr += restriction; + + return AppendFunctions(collection, ((edbPackageObjCollection *)collection)->GetPackage(), browser, restr); +} + +#include "images/function.pngc" +#include "images/functions.pngc" + +edbPackageFunctionFactory::edbPackageFunctionFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img) + : edbPackageObjFactory(tn, ns, nls, img) +{ + metaType = EDB_PACKAGEFUNCTION; +} + +pgCollection *edbPackageFunctionFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageFunctionCollection(GetCollectionFactory(), (edbPackage *)obj); +} + +edbPackageFunctionFactory packageFunctionFactory(__("Function"), __("New Function..."), __("Create a new Function."), function_png_img); +static pgaCollectionFactory cff(&packageFunctionFactory, __("Functions"), functions_png_img); + +pgCollection *edbPackageObjFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageObjCollection(GetCollectionFactory(), (edbPackage *)obj); +} + +#include "images/procedure.pngc" +#include "images/procedures.pngc" + +edbPackageProcedureFactory::edbPackageProcedureFactory() + : edbPackageFunctionFactory(__("Procedure"), __("New Procedure..."), __("Create a new Procedure."), procedure_png_img) +{ +} + +edbPackageProcedureFactory packageProcedureFactory; +static pgaCollectionFactory cfp(&packageProcedureFactory, __("Procedures"), procedures_png_img); + + diff --git a/schema/edbPackageVariable.cpp b/schema/edbPackageVariable.cpp new file mode 100644 index 0000000..b64bd92 --- /dev/null +++ b/schema/edbPackageVariable.cpp @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPackageVariable.cpp - EnterpriseDB Package variable +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "schema/edbPackageVariable.h" + + +edbPackageVariable::edbPackageVariable(edbPackage *newPackage, const wxString &newName) + : edbPackageObject(newPackage, packageVariableFactory, newName) +{ +} + +wxString edbPackageVariable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package variable"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package variable"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package variable \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop package variable \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop package variable cascaded?"); + break; + case DROPTITLE: + message = _("Drop package variable?"); + break; + case PROPERTIESREPORT: + message = _("Package variable properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Package variable properties"); + break; + case DDLREPORT: + message = _("Package variable DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Package variable DDL"); + break; + } + + return message; +} + + +wxString edbPackageVariable::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Package Variable: ") + GetName() + wxT("\n\n"); + sql += GetName() + wxT(" ") + GetDataType() + wxT(";\n\n"); + } + + return sql; +} + +void edbPackageVariable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Data type"), GetDataType()); + properties->AppendItem(_("Visibility"), GetVisibility()); + } +} + + + +pgObject *edbPackageVariable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *packageVariable = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetConnection()->EdbMinimumVersion(8, 2)) + packageVariable = packageVariableFactory.CreateObjects(coll, 0, wxT("\n AND varname='") + GetName() + wxT("'")); + else + packageVariable = packageVariableFactory.CreateObjects(coll, 0, wxT("\n AND eltname='") + GetName() + wxT("'")); + } + + return packageVariable; +} + + +/////////////////////////////////////////////////// + +pgObject *edbPackageVariableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + + edbPackageVariable *packageVariable = 0; + + pgSet *packageVariables; + + wxString sql; + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + { + sql = wxT("SELECT oid, varname AS eltname, varaccess AS visibility, format_type(vartype, NULL) as datatype FROM edb_variable\n") + wxT(" WHERE varpackage = ") + ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr() + wxT("\n") + + restriction + wxT("\n") + wxT(" ORDER BY varname"); + } + else + { + sql = wxT("SELECT oid, eltname, visibility, format_type(eltdatatype, NULL) as datatype FROM edb_pkgelements\n") + wxT(" WHERE eltclass = 'V'\n") + wxT(" AND packageoid = ") + ((edbPackageObjCollection *)collection)->GetPackage()->GetOidStr() + wxT("\n") + + restriction + wxT("\n") + wxT(" ORDER BY eltname"); + } + + packageVariables = collection->GetDatabase()->ExecuteSet(sql); + + if (packageVariables) + { + edbPackage *package = ((edbPackageObjCollection *)collection)->GetPackage(); + + while (!packageVariables->Eof()) + { + // Do not create edbPackageVariable, if package is wrapped + if (package->GetBody().Trim(false).StartsWith(wxT("$__EDBwrapped__$"))) + { + packageVariables->MoveNext(); + continue; + } + packageVariable = new edbPackageVariable(package, packageVariables->GetVal(wxT("eltname"))); + packageVariable->iSetOid(packageVariables->GetOid(wxT("oid"))); + packageVariable->iSetDataType(packageVariables->GetVal(wxT("datatype"))); + if (packageVariables->GetVal(wxT("visibility")) == wxT("+")) + packageVariable->iSetVisibility(_("Public")); + else if (packageVariables->GetVal(wxT("visibility")) == wxT("-")) + packageVariable->iSetVisibility(_("Private")); + else + packageVariable->iSetVisibility(_("Unknown")); + + if (browser) + { + browser->AppendObject(collection, packageVariable); + packageVariables->MoveNext(); + } + else + break; + } + + delete packageVariables; + } + return packageVariable; +} + +///////////////////////////// + +edbPackageVariableCollection::edbPackageVariableCollection(pgaFactory *factory, edbPackage *pkg) + : edbPackageObjCollection(factory, pkg) +{ +} + +wxString edbPackageVariableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on package variables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing package variables"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for package variables"); + break; + case OBJECTSLISTREPORT: + message = _("Package variables list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/variable.pngc" +#include "images/variables.pngc" + +edbPackageVariableFactory::edbPackageVariableFactory() + : edbPackageObjFactory(__("Variable"), __("New Variable..."), __("Create a new Variable."), variable_png_img) +{ + metaType = EDB_PACKAGEVARIABLE; +} + +pgCollection *edbPackageVariableFactory::CreateCollection(pgObject *obj) +{ + return new edbPackageVariableCollection(GetCollectionFactory(), (edbPackage *)obj); +} + +edbPackageVariableFactory packageVariableFactory; +static pgaCollectionFactory cf(&packageVariableFactory, __("Variables"), variables_png_img); diff --git a/schema/edbPrivateSynonym.cpp b/schema/edbPrivateSynonym.cpp new file mode 100644 index 0000000..65d1404 --- /dev/null +++ b/schema/edbPrivateSynonym.cpp @@ -0,0 +1,227 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbPrivateSynonym.cpp - EnterpriseDB Private/Public Synonym class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbPrivateSynonym.h" + +edbPrivateSynonym::edbPrivateSynonym(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, edbPrivFactory, newName) +{ + isPublic = false; + if (newSchema && newSchema->GetName() == wxT("public")) + isPublic = true; +} + +bool edbPrivateSynonym::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql; + if (isPublic) + sql = wxT("DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + else + sql = wxT("DROP SYNONYM ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + +wxString edbPrivateSynonym::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop synonym \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop synonym?"); + break; + } + + return message; +} + +wxString edbPrivateSynonym::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + if (isPublic) + sql = wxT("-- Public synonym: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + else + sql = wxT("-- Private synonym: ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP SYNONYM ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier(); + + if (isPublic) + sql += wxT("\n\nCREATE OR REPLACE PUBLIC SYNONYM ") + GetQuotedIdentifier() + wxT(" FOR "); + else + sql += wxT("\n\nCREATE OR REPLACE SYNONYM ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetQuotedIdentifier() + wxT(" FOR "); + + if (GetTargetSchema() != wxEmptyString) + sql += qtIdent(GetTargetSchema()) + wxT("."); + + sql += qtIdent(GetTargetObject()) + wxT(";\n"); + } + + return sql; +} + +void edbPrivateSynonym::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Public Synonym"), isPublic ? _("Yes") : _("No")); + properties->AppendItem(_("Name"), GetName()); + if (!isPublic) + properties->AppendItem(_("Schema"), GetSchema()->GetName()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Target type"), GetTargetType()); + properties->AppendItem(_("Target schema"), GetTargetSchema()); + properties->AppendItem(_("Target object"), GetTargetObject()); + properties->AppendYesNoItem(_("System synonym?"), GetSystemObject()); + } +} + + + +pgObject *edbPrivateSynonym::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *synonym = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + synonym = edbPrivFactory.CreateObjects(coll, 0, wxT(" WHERE s.synname=") + qtDbString(GetName()) + + wxT(" AND s.synnamespace=") + coll->GetSchema()->GetOidStr() + wxT(" \n")); + + return synonym; +} + + + +pgObject *edbPrivateSynonymFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbPrivateSynonym *synonym = 0; + + wxString sql = wxT("SELECT *, pg_get_userbyid(synowner) AS owner,\n") + wxT(" COALESCE((SELECT relkind \n") + wxT(" FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid\n") + wxT(" AND n.nspname = synobjschema\n") + wxT(" AND c.relname = synobjname),\n") + wxT(" (SELECT CASE WHEN p.protype = '0' THEN 'f'::\"char\" ELSE 'p'::\"char\" END \n") + wxT(" FROM pg_proc p, pg_namespace n\n") + wxT(" WHERE p.pronamespace = n.oid\n") + wxT(" AND n.nspname = synobjschema\n") + wxT(" AND p.proname = synobjname LIMIT 1), '') AS targettype\n") + wxT(" FROM pg_synonym s") + wxT(" JOIN pg_namespace ns ON s.synnamespace = ns.oid AND ns.nspname = ") + + qtConnString(collection->GetSchema()->GetName()) + wxT(" \n") + + restriction + + wxT(" ORDER BY synname;"); + + pgSet *synonyms = collection->GetDatabase()->ExecuteSet(sql); + + if (synonyms) + { + while (!synonyms->Eof()) + { + wxString name = synonyms->GetVal(wxT("synname")); + synonym = new edbPrivateSynonym(collection->GetSchema(), name); + + synonym->iSetDatabase(collection->GetDatabase()); + synonym->iSetOwner(synonyms->GetVal(wxT("owner"))); + + if (synonyms->GetVal(wxT("targettype")) == wxT("r")) + synonym->iSetTargetType(_("Table")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("S")) + synonym->iSetTargetType(_("Sequence")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("v")) + synonym->iSetTargetType(_("View")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("f")) + synonym->iSetTargetType(_("Function")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("p")) + synonym->iSetTargetType(_("Procedure")); + else + synonym->iSetTargetType(_("Synonym")); + + synonym->iSetTargetSchema(synonyms->GetVal(wxT("synobjschema"))); + synonym->iSetTargetObject(synonyms->GetVal(wxT("synobjname"))); + + if (browser) + { + browser->AppendObject(collection, synonym); + synonyms->MoveNext(); + } + else + break; + } + delete synonyms; + } + return synonym; +} + +///////////////////////////// + +edbPrivateSynonymCollection::edbPrivateSynonymCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString edbPrivateSynonymCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on private synonyms"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing private synonyms"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for private synonyms"); + break; + case OBJECTSLISTREPORT: + message = _("Private synonyms list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/synonym.pngc" +#include "images/synonyms.pngc" + +edbPrivateSynonymFactory::edbPrivateSynonymFactory() + : pgSchemaObjFactory(__("Synonym"), __("New Synonym..."), __("Create a new Synonym."), synonym_png_img) +{ + metaType = EDB_SYNONYM; +} + +pgCollection *edbPrivateSynonymFactory::CreateCollection(pgObject *obj) +{ + return new edbPrivateSynonymCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +edbPrivateSynonymFactory edbPrivFactory; + +static pgaCollectionFactory cf(&edbPrivFactory, __("Synonyms"), synonyms_png_img); + diff --git a/schema/edbResourceGroup.cpp b/schema/edbResourceGroup.cpp new file mode 100644 index 0000000..c28a789 --- /dev/null +++ b/schema/edbResourceGroup.cpp @@ -0,0 +1,205 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbResourceGroup.cpp - Resource Group (only used for PPAS 9.4) +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbResourceGroup.h" + +#include "images/resourcegroup.pngc" +#include "images/resourcegroups.pngc" + +edbResourceGroup::edbResourceGroup(const wxString &newName) + : pgServerObject(resourceGroupFactory, newName), cpuRateLimit(0), dirtyRateLimit(0) +{ +} + +edbResourceGroup::~edbResourceGroup() +{ +} + +wxString edbResourceGroup::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource group"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resouce group"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource group \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource group \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop resource group cascaded?"); + break; + case DROPTITLE: + message = _("Drop resource group?"); + break; + case PROPERTIESREPORT: + message = _("Resource group properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Resource group properties"); + break; + case DDLREPORT: + message = _("Resource group DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Resource group DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Resource group dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Resource group dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Resource group dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Resource group dependents"); + break; + } + + return message; +} + +bool edbResourceGroup::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return server->ExecuteVoid(wxT("DROP RESOURCE GROUP ") + GetQuotedFullIdentifier()); +} + +wxString edbResourceGroup::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- RESOURCE GROUP: ") + GetName() + wxT("\n\n") + + wxT("-- DROP RESOURCE GROUP ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE RESOURCE GROUP ") + GetQuotedIdentifier() + wxT(";") + + wxT("\nALTER RESOURCE GROUP ") + GetQuotedIdentifier() + wxT(" SET cpu_rate_limit = ") + + wxString::Format(wxT("%f"), GetCPURateLimit()) + wxT(", dirty_rate_limit = ") + + wxString::Format(wxT("%f"), GetDirtyRateLimit()) + wxT(";"); + } + + return sql; +} + +void edbResourceGroup::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("CPU Rate Limit"), GetCPURateLimit()); + properties->AppendItem(_("Dirty Rate Limit"), GetDirtyRateLimit()); + } +} + +pgObject *edbResourceGroup::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *group = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + group = resourceGroupFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr()); + + return group; +} + + +edbResourceGroupFactory::edbResourceGroupFactory() + : pgServerObjFactory(__("Resource Group"), __("New Resource Group..."), __("Create a new Resource Group."), resourcegroup_png_img) +{ +} + +pgObject *edbResourceGroupFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbResourceGroup *resGroup = 0; + double cpuLimit, dirtyLimit; + + pgSet *groups = collection->GetServer()->ExecuteSet(wxT("SELECT oid, * from edb_resource_group") + restriction); + + if (groups) + { + while (!groups->Eof()) + { + resGroup = new edbResourceGroup(groups->GetVal(wxT("rgrpname"))); + resGroup->iSetServer(collection->GetServer()); + resGroup->iSetOid(groups->GetOid(wxT("oid"))); + groups->GetVal(wxT("rgrpcpuratelimit")).ToDouble(&cpuLimit); + resGroup->iSetCPURateLimit(cpuLimit); + groups->GetVal(wxT("rgrpdirtyratelimit")).ToDouble(&dirtyLimit); + resGroup->iSetDirtyRateLimit(dirtyLimit); + + if (browser) + { + browser->AppendObject(collection, resGroup); + groups->MoveNext(); + } + else + break; + } + + delete groups; + } + return resGroup; +} + +pgCollection *edbResourceGroupFactory::CreateCollection(pgObject *obj) +{ + return new edbResourceGroupCollection(GetCollectionFactory(), (pgServer *)obj); +} + +edbResourceGroupFactory resourceGroupFactory; +static pgaCollectionFactory rgcf(&resourceGroupFactory, __("Resource Groups"), resourcegroups_png_img); + +edbResourceGroupCollection::edbResourceGroupCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + +wxString edbResourceGroupCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource groups"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resource groups"); + break; + case OBJECTSLISTREPORT: + message = _("Resource groups list report"); + break; + } + + return message; +} + diff --git a/schema/edbSynonym.cpp b/schema/edbSynonym.cpp new file mode 100644 index 0000000..4c60ce5 --- /dev/null +++ b/schema/edbSynonym.cpp @@ -0,0 +1,239 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// edbSynonym.cpp - EnterpriseDB Synonym class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/edbSynonym.h" + +edbSynonym::edbSynonym(const wxString &newName) + : pgDatabaseObject(synonymFactory, newName) +{ +} + +wxString edbSynonym::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on synonym"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing synonym"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop synonym \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop synonym \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop synonym cascaded?"); + break; + case DROPTITLE: + message = _("Drop synonym?"); + break; + case PROPERTIESREPORT: + message = _("Synonym properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Synonym properties"); + break; + case DDLREPORT: + message = _("Synonym DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Synonym DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Synonym dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Synonym dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Synonym dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Synonym dependents"); + break; + } + + return message; +} + +bool edbSynonym::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + +wxString edbSynonym::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Public synonym: ") + GetQuotedIdentifier() + wxT("\n\n") + wxT("-- DROP PUBLIC SYNONYM ") + GetQuotedIdentifier(); + + sql += wxT("\n\nCREATE OR REPLACE PUBLIC SYNONYM ") + GetQuotedIdentifier() + wxT(" FOR "); + + if (GetTargetSchema() != wxEmptyString) + sql += qtIdent(GetTargetSchema()) + wxT("."); + + sql += qtIdent(GetTargetObject()) + wxT(";\n"); + } + + return sql; +} + +void edbSynonym::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Target type"), GetTargetType()); + properties->AppendItem(_("Target schema"), GetTargetSchema()); + properties->AppendItem(_("Target object"), GetTargetObject()); + properties->AppendYesNoItem(_("System synonym?"), GetSystemObject()); + } +} + + + +pgObject *edbSynonym::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *synonym = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + synonym = synonymFactory.CreateObjects(coll, 0, wxT(" WHERE synname=") + qtDbString(GetName())); + + return synonym; +} + + + +pgObject *edbSynonymFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + edbSynonym *synonym = 0; + + wxString sql = wxT("SELECT *, pg_get_userbyid(synowner) AS owner,\n") + wxT(" COALESCE((SELECT relkind \n") + wxT(" FROM pg_class c, pg_namespace n\n") + wxT(" WHERE c.relnamespace = n.oid\n") + wxT(" AND n.nspname = synobjschema\n") + wxT(" AND c.relname = synobjname), '') AS targettype\n") + wxT(" FROM pg_synonym") + + restriction + + wxT(" ORDER BY synname;"); + + pgSet *synonyms = collection->GetDatabase()->ExecuteSet(sql); + + if (synonyms) + { + while (!synonyms->Eof()) + { + wxString name = synonyms->GetVal(wxT("synname")); + synonym = new edbSynonym(name); + + synonym->iSetDatabase(collection->GetDatabase()); + synonym->iSetOwner(synonyms->GetVal(wxT("owner"))); + + if (synonyms->GetVal(wxT("targettype")) == wxT("r")) + synonym->iSetTargetType(_("Table")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("S")) + synonym->iSetTargetType(_("Sequence")); + else if (synonyms->GetVal(wxT("targettype")) == wxT("v")) + synonym->iSetTargetType(_("View")); + else + synonym->iSetTargetType(_("Public synonym")); + + synonym->iSetTargetSchema(synonyms->GetVal(wxT("synobjschema"))); + synonym->iSetTargetObject(synonyms->GetVal(wxT("synobjname"))); + + if (browser) + { + browser->AppendObject(collection, synonym); + synonyms->MoveNext(); + } + else + break; + } + delete synonyms; + } + return synonym; +} + +///////////////////////////// + +edbSynonymCollection::edbSynonymCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + +wxString edbSynonymCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on synonyms"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing synonyms"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for synonyms"); + break; + case OBJECTSLISTREPORT: + message = _("Synonyms list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/synonym.pngc" +#include "images/synonyms.pngc" + +edbSynonymFactory::edbSynonymFactory() + : pgDatabaseObjFactory(__("Public Synonym"), __("New Public Synonym..."), __("Create a new Public Synonym."), synonym_png_img) +{ +} + + +pgCollection *edbSynonymFactory::CreateCollection(pgObject *obj) +{ + return new edbSynonymCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +edbSynonymFactory synonymFactory; +static pgaCollectionFactory cf(&synonymFactory, __("Public Synonyms"), synonyms_png_img); diff --git a/schema/gpExtTable.cpp b/schema/gpExtTable.cpp new file mode 100644 index 0000000..048c45a --- /dev/null +++ b/schema/gpExtTable.cpp @@ -0,0 +1,575 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpExtTable.cpp - Greenplum External Table +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgColumn.h" +#include "schema/gpExtTable.h" +#include "frm/frmHint.h" + + +gpExtTable::gpExtTable(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, extTableFactory, newName) +{ +} + +gpExtTable::~gpExtTable() +{ +} + +wxString gpExtTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on external table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing external table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop external table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop external table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop external table cascaded?"); + break; + case DROPTITLE: + message = _("Drop external table?"); + break; + case PROPERTIESREPORT: + message = _("External table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("External table properties"); + break; + case DDLREPORT: + message = _("External table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("External table DDL"); + break; + case DEPENDENCIESREPORT: + message = _("External table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("External table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("External table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("External table dependents"); + break; + } + + return message; +} + +bool gpExtTable::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_class WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +wxMenu *gpExtTable::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + schemaFactory.AppendMenu(menu); + + return menu; +} + + +bool gpExtTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP EXTERNAL TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString gpExtTable::GetSql(ctlTree *browser) +{ + wxString colDetails; + wxString prevComment; + wxString q; + + if (sql.IsNull()) + { + sql = wxT("-- External Table: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP EXTERNAL TABLE ") + GetQuotedFullIdentifier() + wxT(";\n\n"); + /* Now get required information from pg_exttable */ + if (GetDatabase()->BackendMinimumVersion(8, 2, 5)) + { + q += wxT( + "SELECT x.location, x.fmttype, x.fmtopts, x.command, ") + wxT("x.rejectlimit, x.rejectlimittype,") + wxT("(SELECT relname ") + wxT("FROM pg_class ") + wxT("WHERE Oid=x.fmterrtbl) AS errtblname, ") + wxT("pg_catalog.pg_encoding_to_char(x.encoding) ") + wxT("FROM pg_catalog.pg_exttable x, pg_catalog.pg_class c ") + wxT("WHERE x.reloid = c.oid AND c.oid = ") + GetOidStr(); + } + else + { + /* not SREH and encoding colums yet */ + q += wxT( + "SELECT x.location, x.fmttype, x.fmtopts, x.command, ") + wxT("-1 as rejectlimit, null as rejectlimittype,") + wxT("null as errtblname, ") + wxT("null as encoding ") + wxT("FROM pg_catalog.pg_exttable x, pg_catalog.pg_class c ") + wxT("WHERE x.reloid = c.oid AND c.oid = ") + GetOidStr(); + + } + + pgSet *extTable = GetDatabase()->ExecuteSet(q); + + wxString locations = extTable->GetVal(0); + wxString fmttype = extTable->GetVal(1); + wxString fmtopts = extTable->GetVal(2); + wxString command = extTable->GetVal(3); + wxString rejlim = extTable->GetVal(4); + wxString rejlimtype = extTable->GetVal(5); + wxString errtblname = extTable->GetVal(6); + wxString extencoding = extTable->GetVal(7); + + delete extTable; + + if ((command.Length() > 0) || + (locations.Mid(1, 4) == wxT("http"))) + { + sql += wxT("CREATE EXTERNAL WEB TABLE ") + + GetQuotedFullIdentifier() + wxT("\n(\n"); + } + else + { + sql += wxT("CREATE EXTERNAL TABLE ") + + GetQuotedFullIdentifier() + wxT("\n(\n"); + } + + // Get the columns + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + columns->ShowTreeDetail(browser); + treeObjectIterator colIt1(browser, columns); + treeObjectIterator colIt2(browser, columns); + + + int lastRealCol = 0; + int currentCol = 0; + pgColumn *column; + + // Iterate the columns to find the last 'real' one + while ((column = (pgColumn *)colIt1.GetNextObject()) != 0) + { + currentCol++; + + if (column->GetInheritedCount() == 0) + lastRealCol = currentCol; + } + + // Now build the actual column list + int colCount = 0; + while ((column = (pgColumn *)colIt2.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (colCount) + { + // Only add a comma if this isn't the last 'real' column + if (colCount != lastRealCol) + sql += wxT(","); + if (!prevComment.IsEmpty()) + sql += wxT(" -- ") + firstLineOnly(prevComment); + + sql += wxT("\n"); + } + + /* if (column->GetInheritedCount() > 0) + { + if (!column->GetIsLocal()) + sql += wxString::Format(wxT("-- %s "), _("Inherited")) + + wxT("from table ") + column->GetInheritedTableName() + wxT(":"); + }*/ + + sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" ") + + column->GetDefinition(); + + prevComment = column->GetComment(); + + // Whilst we are looping round the columns, grab their comments as well. + // Perhaps we should also get storage types here? + colDetails += column->GetCommentSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') colDetails += wxT("\n"); + + colCount++; + } + } + } + if (!prevComment.IsEmpty()) + sql += wxT(" -- ") + firstLineOnly(prevComment); + + sql += wxT("\n)\n"); + + if(command.Length() > 0) + { + + wxString on_clause = locations; + + /* remove curly braces */ + on_clause = locations.Mid(1, locations.Length() - 2); + + + /* add EXECUTE clause */ + sql += wxT(" EXECUTE E'"); + for (size_t i = 0; i < command.Length(); i++) + { + if (command[i] == wxT('\\')) sql += wxT('\\'); + if (command[i] == wxT('\'')) sql += wxT('\''); + sql += command[i]; + } + sql += wxT("' "); + + + /* add ON clause */ + wxString temp; + + if(on_clause.StartsWith(wxT("HOST:"), &temp)) + { + sql += wxT("ON HOST '") + temp + wxT("'"); + } + else if(on_clause.StartsWith(wxT("PER_HOST"), &temp)) + sql += wxT("ON HOST "); + else if(on_clause.StartsWith(wxT("MASTER_ONLY"), &temp)) + sql += wxT("ON MASTER "); + else if(on_clause.StartsWith(wxT("SEGMENT_ID:"), &temp)) + sql += wxT("ON SEGMENT ") + temp + wxT(" "); + else if(on_clause.StartsWith(wxT("TOTAL_SEGS:"), &temp)) + sql += wxT("ON ") + temp + wxT(" "); + else if(on_clause.StartsWith(wxT("ALL_SEGMENTS"), &temp)) + sql += wxT("ON ALL "); + else + sql += on_clause; + + sql += wxT("\n "); + + } + else + { + + /* add LOCATION clause */ + + locations = locations.Mid(1, locations.Length() - 2); + wxStringTokenizer locs(locations, wxT(",")); + wxString token; + token = locs.GetNextToken(); + sql += wxT(" LOCATION (\n '"); + sql += token; + sql += wxT("'"); + while (locs.HasMoreTokens()) + { + sql += wxT(",\n '"); + sql += locs.GetNextToken(); + sql += wxT("'"); + } + sql += wxT("\n)\n "); + + } + + /* add FORMAT clause */ + sql += wxT("FORMAT '"); + sql += fmttype[0] == 't' ? wxT("text") : wxT("csv"); + sql += wxT("'"); + sql += wxT(" ("); + for (size_t i = 0; i < fmtopts.Length(); i++) + { + if (fmtopts[i] == wxT('\\')) sql += wxT('\\'); + sql += fmtopts[i]; + } + sql += wxT(")\n"); + + if (GetDatabase()->BackendMinimumVersion(8, 2)) + { + /* add ENCODING clause */ + sql += wxT("ENCODING '"); + sql += extencoding ; + sql += wxT("'"); + + /* add Single Row Error Handling clause (if any) */ + if(rejlim.Length() > 0) + { + sql += wxT("\n"); + + /* + * NOTE: error tables get automatically generated if don't exist. + * therefore we must be sure that this statement will be dumped after + * the error relation CREATE is dumped, so that we won't try to + * create it twice. For now we rely on the fact that we pick dumpable + * objects sorted by OID, and error table oid *should* always be less + * than its external table oid (could that not be true sometimes?) + */ + if(errtblname.Length() > 0) + { + sql += wxT("LOG ERRORS INTO "); + sql += errtblname; + sql += wxT(" "); + } + + /* reject limit */ + sql += wxT("SEGMENT REJECT LIMIT "); + sql += rejlim; + + /* reject limit type */ + if(rejlimtype[0] == 'r') + sql += wxT(" ROWS"); + else + sql += wxT(" PERCENT"); + } + } + + sql += wxT(";\n") + + GetOwnerSql(7, 3, wxEmptyString, wxT("TABLE")); + + + sql += GetGrant(wxT("r"), wxT("TABLE ") + GetQuotedFullIdentifier()); + + sql += GetCommentSql() + + wxT("\n"); + + // Column/constraint comments + if (!colDetails.IsEmpty()) + sql += colDetails + wxT("\n"); + + } + return sql; +} + + +wxString gpExtTable::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) +{ + wxString sql; + wxString line; + + int colcount = 0; + pgSetIterator set(GetConnection(), + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum>0\n") + wxT(" ORDER BY attnum")); + + + while (set.RowsLeft()) + { + if (colcount++) + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } + + line += qtIdent(set.GetVal(0)); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); + } + + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; +} + + +wxString gpExtTable::GetSelectSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +void gpExtTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + browser->RemoveDummyChild(this); + + browser->AppendCollection(this, columnFactory); + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("System Table?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *gpExtTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *extTable = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + extTable = extTableFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + } + + return extTable; +} + +void gpExtTable::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + hints.Add(HINT_OBJECT_EDITING); + frmHint::ShowHint((wxWindow *)form, hints, GetFullIdentifier(), force); +} + +/////////////////////////////////////////////////////// + + +pgObject *gpExtTableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + gpExtTable *extTable = 0; + + + pgSet *extTables = collection->GetDatabase()->ExecuteSet( + wxT("SELECT c.oid, c.xmin, c.relname, pg_get_userbyid(c.relowner) AS exttableowner, c.relacl AS relacl, description \n") + wxT(" FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" WHERE (c.relkind = 'x' OR (c.relkind = 'r' AND c.relstorage = 'x'))\n") + wxT(" AND relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY relname")); + + if (extTables) + { + while (!extTables->Eof()) + { + extTable = new gpExtTable(collection->GetSchema(), extTables->GetVal(wxT("relname"))); + + extTable->iSetOid(extTables->GetOid(wxT("oid"))); + extTable->iSetXid(extTables->GetOid(wxT("xmin"))); + extTable->iSetOwner(extTables->GetVal(wxT("exttableowner"))); + extTable->iSetComment(extTables->GetVal(wxT("description"))); + extTable->iSetAcl(extTables->GetVal(wxT("relacl"))); + //extTable->iSetDefinition(extTables->GetVal(wxT("definition"))); + + if (browser) + { + collection->AppendBrowserItem(browser, extTable); + extTables->MoveNext(); + } + else + break; + } + + delete extTables; + } + return extTable; +} + +///////////////////////////// + +gpExtTableCollection::gpExtTableCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString gpExtTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on external tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing external tables"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for external tables"); + break; + case OBJECTSLISTREPORT: + message = _("External tables list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/exttable.pngc" +#include "images/exttable-sm.pngc" +#include "images/exttables.pngc" + +gpExtTableFactory::gpExtTableFactory() + : pgSchemaObjFactory(__("External Table"), __("New External Table..."), __("Create a new External Table."), exttable_png_img, exttable_sm_png_img) +{ + metaType = GP_EXTTABLE; +} + + +pgCollection *gpExtTableFactory::CreateCollection(pgObject *obj) +{ + return new gpExtTableCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +gpExtTableFactory extTableFactory; +static pgaCollectionFactory cf(&extTableFactory, __("External Tables"), exttables_png_img); diff --git a/schema/gpPartition.cpp b/schema/gpPartition.cpp new file mode 100644 index 0000000..7cf1db2 --- /dev/null +++ b/schema/gpPartition.cpp @@ -0,0 +1,238 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpPartition.cpp - Greenplum Table Partition class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include "utils/misc.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMaintenance.h" +#include "schema/pgTable.h" +#include "schema/gpPartition.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" + + +// App headers + +gpPartition::gpPartition(pgSchema *newSchema, const wxString &newName) + : pgTable(newSchema, partitionFactory, newName) +{ +} + +gpPartition::~gpPartition() +{ +} + +bool gpPartition::CanCreate() +{ + return false; +} + +wxMenu *gpPartition::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + + } + return menu; +} +/* +wxString gpPartition::GetCreate() +{ + wxString sql; + + // sql = GetQuotedIdentifier() + wxT(" ") + // + GetTypeName().Upper() + GetDefinition(); + sql = wxT("Not implemented yet..sorry"); + return sql; +}; +*/ + +wxString gpPartition::GetSql(ctlTree *browser) +{ + wxString sql; + sql = wxT("-- "); + sql += _("Note: This DDL is a representation of how the partition might look as a table."); + sql += wxT("\n\n"); + + sql += pgTable::GetSql(browser); + return sql; +} + +pgObject *gpPartition::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + gpPartition *partition = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + partition = (gpPartition *)partitionFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr()); + + return partition; +} + +/////////////////////////////////////////////////////////// + +gpPartitionCollection::gpPartitionCollection(pgaFactory *factory, gpPartition *_table) + : pgTableCollection(factory, _table->GetSchema()) +{ + iSetOid(_table->GetOid()); +} + + +pgObject *gpPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + gpPartitionCollection *collection = (gpPartitionCollection *)coll; + wxString query; + gpPartition *table = 0; + + // Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB, + // so we need to multiply them by the number of segmentDBs to get reasonable values. + long gp_segments = 1; + + query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0"); + gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query)); + if (gp_segments <= 1) + gp_segments = 1; + + + pgSet *tables; + + query = wxT("SELECT rel.oid, relname, rel.reltablespace AS spcoid, spcname, pg_get_userbyid(relowner) AS relowner, relacl, ") + wxT("relhassubclass, reltuples, description, conname, conkey, parname, \n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl\n"); + + query += wxT(", substring(array_to_string(reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(", gpd.localoid, gpd.attrnums \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'appendonly=([a-z]*)') AS appendonly \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'compresslevel=([0-9]*)') AS compresslevel \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'orientation=([a-z]*)') AS orientation \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'compresstype=([a-z0-9]*)') AS compresstype \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'blocksize=([0-9]*)') AS blocksize \n"); + query += wxT(", substring(array_to_string(reloptions, ',') from 'checksum=([a-z]*)') AS checksum \n"); + //query += wxT(", rel.oid in (select parrelid from pg_partition) as ispartitioned\n"); // This only works for top-level tables, not intermediate ones + // This looks for intermediate partitions that have subpartitions + query += wxT(", rel.oid in (select pr.parchildrelid from pg_partition_rule pr, pg_partition pp where pr.paroid = pp.oid and pp.parlevel < (select max(parlevel) from pg_partition where parrelid = pp.parrelid)) as ispartitioned \n"); + + + query += wxT(" FROM pg_class rel JOIN pg_partition_rule pr ON(rel.oid = pr.parchildrelid) JOIN pg_partition p ON (pr.paroid = p.oid)\n") + wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n") + wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=rel.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint c ON c.conrelid=rel.oid AND c.contype='p'\n"); + query += wxT(" LEFT OUTER JOIN gp_distribution_policy gpd ON gpd.localoid=rel.oid\n"); + query += wxT(" WHERE relkind = 'r' "); + query += wxT(" AND i.inhparent = ") + collection->GetOidStr() + wxT("\n"); + + query += restriction + + wxT(" ORDER BY relname"); + + + tables = collection->GetDatabase()->ExecuteSet(query); + if (tables) + { + while (!tables->Eof()) + { + table = new gpPartition(collection->GetSchema(), tables->GetVal(wxT("relname"))); + + table->iSetOid(tables->GetOid(wxT("oid"))); + table->iSetOwner(tables->GetVal(wxT("relowner"))); + table->iSetAcl(tables->GetVal(wxT("relacl"))); + + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + + if (tables->GetVal(wxT("spcname")) == wxEmptyString) + table->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + table->iSetTablespace(tables->GetVal(wxT("spcname"))); + + table->iSetComment(tables->GetVal(wxT("description"))); + table->iSetHasOids(false); + table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments); + + table->iSetFillFactor(tables->GetVal(wxT("fillfactor"))); + + table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass"))); + table->iSetPartitionName(tables->GetVal(wxT("parname"))); + table->iSetPrimaryKeyName(tables->GetVal(wxT("conname"))); + table->iSetIsReplicated(tables->GetBool(wxT("isrepl"))); + wxString cn = tables->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + table->iSetPrimaryKeyColNumbers(cn); + + + Oid lo = tables->GetOid(wxT("localoid")); + wxString db = tables->GetVal(wxT("attrnums")); + db = db.Mid(1, db.Length() - 2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + table->iSetOrientation(tables->GetVal(wxT("orientation"))); + table->iSetCompressType(tables->GetVal(wxT("compresstype"))); + table->iSetBlocksize(tables->GetVal(wxT("blocksize"))); + table->iSetChecksum(tables->GetVal(wxT("checksum"))); + + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + +void gpPartitionFactory::AppendMenu(wxMenu *menu) +{ +} + +#include "images/table.pngc" +#include "images/table-sm.pngc" +#include "images/tables.pngc" + +gpPartitionFactory::gpPartitionFactory() + : pgTableObjFactory(__("Partition"), __("New Partition..."), __("Create a new Partition."), table_png_img, table_sm_png_img) +{ + metaType = GP_PARTITION; +} + +pgCollection *gpPartitionFactory::CreateCollection(pgObject *obj) +{ + return new gpPartitionCollection(GetCollectionFactory(), (gpPartition *)obj ); +} + +gpPartitionFactory partitionFactory; +static pgaCollectionFactory cf(&partitionFactory, __("Partitions"), tables_png_img); + + diff --git a/schema/gpResQueue.cpp b/schema/gpResQueue.cpp new file mode 100644 index 0000000..70205ba --- /dev/null +++ b/schema/gpResQueue.cpp @@ -0,0 +1,302 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpResQueue.cpp - Greenplum Resource Queue +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/gpResQueue.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" +#include "schema/pgDatabase.h" + + +gpResQueue::gpResQueue(pgaFactory &factory, const wxString &newName) + : pgServerObject(factory, newName) +{ +} + +gpResQueue::gpResQueue(const wxString &newName) + : pgServerObject(resQueueFactory, newName) +{ +} + +wxString gpResQueue::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource queue"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resource queue"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource queue \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop resource queue \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop resource queue cascaded?"); + break; + case DROPTITLE: + message = _("Drop resource queue?"); + break; + case PROPERTIESREPORT: + message = _("Resource queue properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Resource queue properties"); + break; + case DDLREPORT: + message = _("Resource queue DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Resource queue DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Resource queue dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Resource queue dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Resource queue dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Resource queue dependents"); + break; + } + + return message; +} + +int gpResQueue::GetIconId() +{ + return resQueueFactory.GetIconId(); +} + + + +bool gpResQueue::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return server->ExecuteVoid(wxT("DROP RESOURCE QUEUE ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString gpResQueue::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Resource Queue: \"") + GetName() + wxT("\"\n\n") + + wxT("-- DROP RESOURCE QUEUE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE RESOURCE QUEUE ") + GetQuotedIdentifier(); + + if (GetCountLimit() != -1.0) + { + sql += wxT(" ACTIVE THRESHOLD "); + sql += NumToStr(GetCountLimit()); + } + if (GetCostLimit() != -1.0) + { + sql += wxT(" COST THRESHOLD "); + sql += NumToStr(GetCostLimit()); + } + if (GetIgnoreCostLimit() != 0.0) + { + sql += wxT(" IGNORE THRESHOLD "); + sql += NumToStr(GetIgnoreCostLimit()); + } + if (GetOvercommit()) + sql += wxT(" OVERCOMMIT"); + else + sql += wxT(" NOOVERCOMMIT"); + } + return sql; +} + + + + + + +void gpResQueue::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + wxString queuesquery; + + queuesquery = wxT("SELECT rolname,\n") + wxT(" pg_catalog.shobj_description(r.oid, 'pg_authid') AS description\n"); + + queuesquery += wxT(" FROM pg_roles r\n") + wxT(" JOIN pg_resqueue q ON rolresqueue=q.oid\n") + wxT(" WHERE rolresqueue=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY rolname"); + + pgSetIterator queues(GetConnection(), queuesquery); + + while (queues.RowsLeft()) + { + wxString queue = queues.GetVal(wxT("rolname")); + + queuesIn.Add(queue); + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Active threshold"), GetCountLimit()); + properties->AppendItem(_("Cost threshold"), GetCostLimit()); + properties->AppendItem(_("Ignore threshold"), GetIgnoreCostLimit()); + properties->AppendItem(_("Over commit?"), BoolToYesNo(GetOvercommit())); + + wxString roleList; + + size_t index; + for (index = 0 ; index < queuesIn.GetCount() ; index++) + { + if (!roleList.IsEmpty()) + roleList += wxT(", "); + roleList += queuesIn.Item(index); + } + properties->AppendItem(_("Roles using this"), roleList); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + } +} + + + + +pgObject *gpResQueue::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *queue = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + queue = resQueueFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr()); + + return queue; +} + + + +pgObject *gpResQueueFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + gpResQueue *queue = 0; + pgSet *queues = 0; + + + + queues = collection->GetServer()->ExecuteSet(wxT("SELECT rsqname, rsqcountlimit, rsqcostlimit, rsqovercommit, rsqignorecostlimit, oid FROM pg_resqueue ORDER BY 1")); + + if (queues) + { + while (!queues->Eof()) + { + queue = new gpResQueue(queues->GetVal(wxT("rsqname"))); + + queue->iSetServer(collection->GetServer()); + queue->iSetCountLimit(queues->GetDouble(wxT("rsqcountlimit"))); + queue->iSetCostLimit(queues->GetDouble(wxT("rsqcostlimit"))); + queue->iSetOvercommit(queues->GetBool(wxT("rsqovercommit"))); + queue->iSetIgnoreCostLimit(queues->GetDouble(wxT("rsqignorecostlimit"))); + queue->iSetOid(queues->GetOid(wxT("oid"))); + + if (browser) + { + browser->AppendObject(collection, queue); + queues->MoveNext(); + } + else + break; + } + + delete queues; + } + return queue; +} + +///////////////////////////// + +gpResQueueCollection::gpResQueueCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + +wxString gpResQueueCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on resource queues"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing resource queues"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for resource queues"); + break; + case OBJECTSLISTREPORT: + message = _("Ressource queues list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/group.pngc" +#include "images/roles.pngc" + + +gpResQueueFactory::gpResQueueFactory() + : pgServerObjFactory(__("Resource Queue"), __("New Resource Queue..."), __("Create a new Resource Queue."), group_png_img) +{ + metaType = GP_RESOURCE_QUEUE; +} + + +pgCollection *gpResQueueFactory::CreateCollection(pgObject *obj) +{ + return new gpResQueueCollection(GetCollectionFactory(), (pgServer *)obj); +} + +gpResQueueFactory resQueueFactory; +static pgaCollectionFactory lcf(&resQueueFactory, __("Resource Queues"), roles_png_img); + + +dlgProperty *gpResQueueFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; +} + diff --git a/schema/module.mk b/schema/module.mk new file mode 100644 index 0000000..9ce59c5 --- /dev/null +++ b/schema/module.mk @@ -0,0 +1,68 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/schema Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + schema/edbPackage.cpp \ + schema/edbPackageFunction.cpp \ + schema/edbPackageVariable.cpp \ + schema/edbSynonym.cpp \ + schema/edbPrivateSynonym.cpp \ + schema/pgAggregate.cpp \ + schema/pgCast.cpp \ + schema/pgCatalogObject.cpp \ + schema/pgCheck.cpp \ + schema/pgCollation.cpp \ + schema/pgCollection.cpp \ + schema/pgColumn.cpp \ + schema/pgConstraints.cpp \ + schema/pgConversion.cpp \ + schema/pgDatabase.cpp \ + schema/pgDatatype.cpp \ + schema/pgDomain.cpp \ + schema/pgEventTrigger.cpp \ + schema/pgExtension.cpp \ + schema/pgForeignDataWrapper.cpp \ + schema/pgForeignKey.cpp \ + schema/pgForeignServer.cpp \ + schema/pgForeignTable.cpp \ + schema/pgFunction.cpp \ + schema/pgGroup.cpp \ + schema/pgIndex.cpp \ + schema/pgIndexConstraint.cpp \ + schema/pgLanguage.cpp \ + schema/pgObject.cpp \ + schema/pgOperator.cpp \ + schema/pgOperatorClass.cpp \ + schema/pgOperatorFamily.cpp \ + schema/pgRole.cpp \ + schema/pgRule.cpp \ + schema/pgSchema.cpp \ + schema/pgSequence.cpp \ + schema/pgServer.cpp \ + schema/pgTable.cpp \ + schema/pgTablespace.cpp \ + schema/pgTextSearchConfiguration.cpp \ + schema/pgTextSearchDictionary.cpp \ + schema/pgTextSearchParser.cpp \ + schema/pgTextSearchTemplate.cpp \ + schema/pgTrigger.cpp \ + schema/pgType.cpp \ + schema/pgUser.cpp \ + schema/pgUserMapping.cpp \ + schema/pgView.cpp \ + schema/gpExtTable.cpp \ + schema/gpResQueue.cpp \ + schema/gpPartition.cpp \ + schema/edbResourceGroup.cpp + +EXTRA_DIST += \ + schema/module.mk + diff --git a/schema/pgAggregate.cpp b/schema/pgAggregate.cpp new file mode 100644 index 0000000..7b790df --- /dev/null +++ b/schema/pgAggregate.cpp @@ -0,0 +1,410 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgAggregate.cpp - Aggregate class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgAggregate.h" + + +pgAggregate::pgAggregate(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, aggregateFactory, newName) +{ +} + +wxString pgAggregate::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on aggregate"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing aggregate"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop aggregate \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop aggregate \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop aggregate cascaded?"); + break; + case DROPTITLE: + message = _("Drop aggregate?"); + break; + case PROPERTIESREPORT: + message = _("Aggregate properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Aggregate properties"); + break; + case DDLREPORT: + message = _("Aggregate DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Aggregate DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Aggregate dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Aggregate dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Aggregate dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Aggregate dependents"); + break; + } + + return message; +} + +bool pgAggregate::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP AGGREGATE ") + GetSchema()->GetQuotedIdentifier() + wxT(".") + GetFullName(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgAggregate::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Aggregate: ") + GetQuotedFullName() + wxT("\n\n") + + wxT("-- DROP AGGREGATE ") + GetQuotedFullName() + wxT(";"); + + if (GetDatabase()->BackendMinimumVersion(8, 2)) + { + sql += wxT("\n\nCREATE AGGREGATE ") + GetQuotedFullName() + wxT(" ("); + } + else + { + sql += wxT("\n\nCREATE AGGREGATE ") + GetQuotedFullIdentifier() + + wxT("(\n BASETYPE=") + GetInputTypesList() + wxT(","); + } + + sql += wxT("\n SFUNC=") + GetStateFunction() + + wxT(",\n STYPE=") + GetStateType(); + + AppendIfFilled(sql, wxT(",\n FINALFUNC="), qtIdent(GetFinalFunction())); + + if (GetInitialCondition().length() > 0) + { + if (GetInitialCondition() == wxT("''")) + sql += wxT(",\n INITCOND=''"); + else if (GetInitialCondition() == wxT("\\'\\'")) + sql += wxT(",\n INITCOND=''''''"); + else + sql += wxT(",\n INITCOND=") + qtDbString(GetInitialCondition()); + } + + AppendIfFilled(sql, wxT(",\n SORTOP="), GetQuotedSortOp()); + + sql += wxT("\n);\n"); + sql += GetOwnerSql(8, 0, wxT("AGGREGATE ") + GetQuotedFullName()) + + GetGrant(wxT("X"), wxT("FUNCTION ") + GetQuotedFullIdentifier()); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON AGGREGATE ") + GetQuotedFullName() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + +void pgAggregate::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Input types"), GetInputTypesList()); + properties->AppendItem(_("State type"), GetStateType()); + properties->AppendItem(_("State function"), GetStateFunction()); + properties->AppendItem(_("Final type"), GetFinalType()); + properties->AppendItem(_("Final function"), GetFinalFunction()); + if (GetConnection()->BackendMinimumVersion(8, 1)) + properties->AppendItem(_("Sort operator"), GetSortOp()); + + if (GetInitialCondition() == wxT("")) + properties->AppendItem(_("Initial condition"), _("")); + else if (GetInitialCondition() == wxT("''")) + properties->AppendItem(_("Initial condition"), _("")); + else if (GetInitialCondition() == wxT("\\'\\'")) + properties->AppendItem(_("Initial condition"), _("''")); + else + properties->AppendItem(_("Initial condition"), GetInitialCondition()); + + properties->AppendYesNoItem(_("System aggregate?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +pgObject *pgAggregate::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *aggregate = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + aggregate = aggregateFactory.CreateObjects(coll, 0, wxT("\n AND aggfnoid::oid=") + GetOidStr()); + + return aggregate; +} + +wxString pgAggregate::GetQuotedFullName() +{ + return GetQuotedFullIdentifier() + wxT("(") + GetInputTypesList() + wxT(")"); +} + +wxString pgAggregate::GetFullName() +{ + return GetName() + wxT("(") + GetInputTypesList() + wxT(")"); +} + +// Return the list of input types +wxString pgAggregate::GetInputTypesList() +{ + wxString types; + + for (unsigned int i = 0; i < inputTypes.Count(); i++) + { + if (i > 0) + types += wxT(", "); + + types += inputTypes.Item(i); + } + return types; +} + +pgObject *pgAggregateFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgAggregate *aggregate = 0; + + // Build a cache of data types + pgSet *types = collection->GetDatabase()->ExecuteSet(wxT( + "SELECT oid, format_type(oid, typtypmod) AS typname FROM pg_type")); + cacheMap map; + while(!types->Eof()) + { + map[types->GetVal(wxT("oid"))] = types->GetVal(wxT("typname")); + types->MoveNext(); + } + + delete types; + // Build the query to get all objects + wxString sql = + wxT("SELECT aggfnoid::oid, proname AS aggname, pg_get_userbyid(proowner) AS aggowner, aggtransfn,\n") + wxT( "aggfinalfn, proargtypes, aggtranstype, proacl, ") + wxT( "CASE WHEN (tt.typlen = -1 AND tt.typelem != 0) THEN (SELECT at.typname FROM pg_type at WHERE at.oid = tt.typelem) || '[]' ELSE tt.typname END as transname, ") + wxT( "prorettype AS aggfinaltype, ") + wxT( "CASE WHEN (tf.typlen = -1 AND tf.typelem != 0) THEN (SELECT at.typname FROM pg_type at WHERE at.oid = tf.typelem) || '[]' ELSE tf.typname END as finalname, ") + wxT( "agginitval, description"); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=aggfnoid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=aggfnoid) AS providers"); + } + + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + sql += wxT(", oprname, opn.nspname as oprnsp\n") + wxT(" FROM pg_aggregate ag\n") + wxT(" LEFT OUTER JOIN pg_operator op ON op.oid=aggsortop\n") + wxT(" LEFT OUTER JOIN pg_namespace opn ON opn.oid=op.oprnamespace"); + } + else + sql += wxT("\n FROM pg_aggregate ag\n"); + + pgSet *aggregates = collection->GetDatabase()->ExecuteSet(sql + + wxT(" JOIN pg_proc pr ON pr.oid = ag.aggfnoid\n") + wxT(" JOIN pg_type tt on tt.oid=aggtranstype\n") + wxT(" JOIN pg_type tf on tf.oid=prorettype\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=aggfnoid::oid AND des.classoid='pg_aggregate'::regclass)\n") + wxT(" WHERE pronamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + + wxT("\n ORDER BY aggname")); + + if (aggregates) + { + while (!aggregates->Eof()) + { + aggregate = new pgAggregate(collection->GetSchema(), aggregates->GetVal(wxT("aggname"))); + + aggregate->iSetOid(aggregates->GetOid(wxT("aggfnoid"))); + aggregate->iSetOwner(aggregates->GetVal(wxT("aggowner"))); + aggregate->iSetAcl(aggregates->GetVal(wxT("proacl"))); + + // Get the input type names. From 8.2 onwards there might be + // multiple types in the array. In any case, we must properly + // quote "any" + + // Tokenize the arguments + wxStringTokenizer argTypes(wxEmptyString); + + if (aggregates->GetVal(wxT("proargtypes")) == wxEmptyString) + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 2)) + aggregate->iAddInputType(wxT("*")); + else + aggregate->iAddInputType(wxT("\"any\"")); + } + else + { + argTypes.SetString(aggregates->GetVal(wxT("proargtypes"))); + + while (argTypes.HasMoreTokens()) + { + // Add the arg type. This is a type oid, so + // look it up in the hashmap + wxString type = argTypes.GetNextToken(); + if (map[type] == wxT("any")) + aggregate->iAddInputType(wxT("\"any\"")); + else + aggregate->iAddInputType(qtTypeIdent(map[type])); + } + } + + aggregate->iSetStateType(aggregates->GetVal(wxT("transname"))); + aggregate->iSetStateFunction(aggregates->GetVal(wxT("aggtransfn"))); + aggregate->iSetFinalType(aggregates->GetVal(wxT("finalname"))); + + wxString final = aggregates->GetVal(wxT("aggfinalfn")); + if (final != wxT("-")) + aggregate->iSetFinalFunction(final); + + if (!aggregates->IsNull(aggregates->ColNumber(wxT("agginitval")))) + { + if (aggregates->GetVal(wxT("agginitval")).IsEmpty()) + aggregate->iSetInitialCondition(wxT("''")); + else if (aggregates->GetVal(wxT("agginitval")) == wxT("''")) + aggregate->iSetInitialCondition(wxT("\\'\\'")); + else + aggregate->iSetInitialCondition(aggregates->GetVal(wxT("agginitval"))); + } + + aggregate->iSetComment(aggregates->GetVal(wxT("description"))); + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + wxString oprname = aggregates->GetVal(wxT("oprname")); + if (!oprname.IsEmpty()) + { + wxString oprnsp = aggregates->GetVal(wxT("oprnsp")); + aggregate->iSetSortOp(collection->GetDatabase()->GetSchemaPrefix(oprnsp) + oprname); + aggregate->iSetQuotedSortOp(collection->GetDatabase()->GetQuotedSchemaPrefix(oprnsp) + + qtIdent(oprname)); + } + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + aggregate->iSetProviders(aggregates->GetVal(wxT("providers"))); + aggregate->iSetLabels(aggregates->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, aggregate); + aggregates->MoveNext(); + } + else + break; + } + + delete aggregates; + } + return aggregate; +} + +///////////////////////////// + +pgAggregateCollection::pgAggregateCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString pgAggregateCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on aggregates"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing aggregates"); + break; + case OBJECTSLISTREPORT: + message = _("Aggregates list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/aggregate.pngc" +#include "images/aggregate-sm.pngc" +#include "images/aggregates.pngc" + +pgAggregateFactory::pgAggregateFactory() + : pgSchemaObjFactory(__("Aggregate"), __("New Aggregate..."), __("Create a new Aggregate."), aggregate_png_img, aggregate_sm_png_img) +{ +} + +pgCollection *pgAggregateFactory::CreateCollection(pgObject *obj) +{ + return new pgAggregateCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgAggregateFactory aggregateFactory; +static pgaCollectionFactory cf(&aggregateFactory, __("Aggregates"), aggregates_png_img); diff --git a/schema/pgCast.cpp b/schema/pgCast.cpp new file mode 100644 index 0000000..f301027 --- /dev/null +++ b/schema/pgCast.cpp @@ -0,0 +1,268 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCast.cpp - Cast class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgCast.h" + +pgCast::pgCast(const wxString &newName) + : pgDatabaseObject(castFactory, newName) +{ +} + +pgCast::~pgCast() +{ +} + + +wxString pgCast::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on cast"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing cast"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop cast \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop cast \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop cast cascaded?"); + break; + case DROPTITLE: + message = _("Drop cast?"); + break; + case PROPERTIESREPORT: + message = _("Cast properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Cast properties"); + break; + case DDLREPORT: + message = _("Cast DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Cast DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Cast dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Cast dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Cast dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Cast dependents"); + break; + } + + return message; +} + + +bool pgCast::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP CAST (") + GetSourceType() + wxT(" AS ") + GetTargetType() + wxT(")"); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgCast::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Cast: ") + GetQuotedFullIdentifier() + wxT("\n\n") + wxT("-- DROP CAST (") + GetSourceType() + + wxT(" AS ") + GetTargetType() + wxT(");") + wxT("\n\nCREATE CAST (") + GetSourceType() + + wxT(" AS ") + GetTargetType(); + if (GetCastFunction().IsNull()) + sql += wxT(")\n WITHOUT FUNCTION"); + else + sql += wxT(")\n WITH FUNCTION ") + GetQuotedSchemaPrefix(GetCastNamespace()) + qtIdent(GetCastFunction()) + wxT("(") + GetSourceType() + wxT(")"); + if (GetCastContext() != wxT("EXPLICIT")) + sql += wxT("\n AS ") + GetCastContext(); + sql += wxT(";\n"); + } + + return sql; +} + +void pgCast::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Source type"), GetSourceType()); + properties->AppendItem(_("Target type"), GetTargetType()); + if (GetCastFunction().IsNull()) + properties->AppendItem(_("Function"), _("(binary compatible)")); + else + properties->AppendItem(_("Function"), GetCastFunction() + wxT("(") + GetSourceType() + wxT(")")); + properties->AppendItem(_("Context"), GetCastContext()); + properties->AppendYesNoItem(_("System cast?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgCast::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *cast = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + cast = castFactory.CreateObjects(coll, 0, wxT(" WHERE ca.oid=") + GetOidStr()); + + return cast; +} + + + +pgObject *pgCastFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgCast *cast = 0; + wxString systemRestriction; + if (!settings->GetShowSystemObjects() && restriction.IsEmpty()) + systemRestriction = wxT(" WHERE ca.oid > ") + NumToStr(collection->GetConnection()->GetLastSystemOID()) + wxT("\n"); + + pgSet *casts = collection->GetDatabase()->ExecuteSet( + wxT("SELECT ca.oid, ca.*, format_type(st.oid,NULL) AS srctyp, format_type(tt.oid,tt.typtypmod) AS trgtyp,") + wxT( " ns.nspname AS srcnspname, nt.nspname AS trgnspname,\n") + wxT( " proname, np.nspname AS pronspname, description\n") + wxT(" FROM pg_cast ca\n") + wxT(" JOIN pg_type st ON st.oid=castsource\n") + wxT(" JOIN pg_namespace ns ON ns.oid=st.typnamespace\n") + wxT(" JOIN pg_type tt ON tt.oid=casttarget\n") + wxT(" JOIN pg_namespace nt ON nt.oid=tt.typnamespace\n") + wxT(" LEFT JOIN pg_proc pr ON pr.oid=castfunc\n") + wxT(" LEFT JOIN pg_namespace np ON np.oid=pr.pronamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=ca.oid AND des.objsubid=0 AND des.classoid='pg_cast'::regclass)\n") + + restriction + systemRestriction + + wxT(" ORDER BY st.typname, tt.typname")); + + if (casts) + { + while (!casts->Eof()) + { + wxString name = casts->GetVal(wxT("srctyp")) + wxT("->") + casts->GetVal(wxT("trgtyp")); + cast = new pgCast(name); + + cast->iSetOid(casts->GetOid(wxT("oid"))); + cast->iSetDatabase(collection->GetDatabase()); + cast->iSetSourceType(casts->GetVal(wxT("srctyp"))); + cast->iSetSourceNamespace(casts->GetVal(wxT("srcnspname"))); + cast->iSetSourceTypeOid(casts->GetOid(wxT("castsource"))); + cast->iSetTargetType(casts->GetVal(wxT("trgtyp"))); + cast->iSetTargetNamespace(casts->GetVal(wxT("trgnspname"))); + cast->iSetTargetTypeOid(casts->GetOid(wxT("casttarget"))); + cast->iSetCastFunction(casts->GetVal(wxT("proname"))); + cast->iSetCastNamespace(casts->GetVal(wxT("pronspname"))); + cast->iSetComment(casts->GetVal(wxT("description"))); + wxString ct = casts->GetVal(wxT("castcontext")); + cast->iSetCastContext( + ct == wxT("i") ? wxT("IMPLICIT") : + ct == wxT("a") ? wxT("ASSIGNMENT") : wxT("EXPLICIT")); + + if (settings->GetShowSystemObjects() || + (cast->GetOid() > collection->GetServer()->GetLastSystemOID())) + { + if (browser) + { + browser->AppendObject(collection, cast); + casts->MoveNext(); + } + else + break; + } + else + break; + } + delete casts; + } + return cast; +} + + +///////////////////////////// + +pgCastCollection::pgCastCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgCastCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on casts"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing casts"); + break; + case OBJECTSLISTREPORT: + message = _("Casts list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/cast.pngc" +#include "images/cast-sm.pngc" +#include "images/casts.pngc" + +pgCastFactory::pgCastFactory() + : pgDatabaseObjFactory(__("Cast"), __("New Cast..."), __("Create a new Cast."), cast_png_img, cast_sm_png_img) +{ +} + + +pgCollection *pgCastFactory::CreateCollection(pgObject *obj) +{ + return new pgCastCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgCastFactory castFactory; +static pgaCollectionFactory cf(&castFactory, __("Casts"), casts_png_img); diff --git a/schema/pgCatalogObject.cpp b/schema/pgCatalogObject.cpp new file mode 100644 index 0000000..68359f2 --- /dev/null +++ b/schema/pgCatalogObject.cpp @@ -0,0 +1,208 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCatalogObject.cpp - EnterpriseDB catalog class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgColumn.h" + + +pgCatalogObject::pgCatalogObject(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, catalogObjectFactory, newName) +{ +} + +wxString pgCatalogObject::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalog object"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalog object"); + message += wxT(" ") + GetName(); + break; + case PROPERTIESREPORT: + message = _("Catalog object properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Catalog object properties"); + break; + case DEPENDENCIESREPORT: + message = _("Catalog object dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Catalog object dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Catalog object dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Catalog object dependents"); + break; + } + + return message; +} + + +wxString pgCatalogObject::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Catalog Object: ") + GetQuotedIdentifier() + wxT("\n"); + } + return sql; +} + + +void pgCatalogObject::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->AppendCollection(this, columnFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Comment"), GetComment()); + } +} + + + +pgObject *pgCatalogObject::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *catalog = 0; + pgCollection *parent = (pgCollection *)browser->GetItemData(browser->GetItemParent(item)); + if (parent) + catalog = catalogObjectFactory.CreateObjects(parent, 0, wxT("\n AND c.oid=") + GetOidStr()); + + return catalog; +} + + + +pgObject *pgCatalogObjectFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgCatalogObject *catalog = 0; + + wxString qry = wxT("SELECT c.oid, c.relname, pg_get_userbyid(relowner) AS owner, description\n") + wxT(" FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_description d ON (d.objoid=c.oid AND d.classoid='pg_class'::regclass)\n") + wxT(" WHERE relnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n"); + + qry += restriction + + wxT(" ORDER BY relname"); + + pgSet *catalogs = collection->GetServer()->ExecuteSet(qry); + + if (catalogs) + { + while (!catalogs->Eof()) + { + // On EnterpriseDB we need to ignore some objects in the sys + // catalog, namely, _*, dual and type_object_source. + if (!settings->GetShowSystemObjects() && + collection->GetSchema()->GetName() == wxT("sys") && + (catalogs->GetVal(wxT("relname")).StartsWith(wxT("_")) || + catalogs->GetVal(wxT("relname")) == wxT("dual") || + catalogs->GetVal(wxT("relname")) == wxT("type_object_source"))) + { + catalogs->MoveNext(); + continue; + } + + catalog = new pgCatalogObject(collection->GetSchema(), catalogs->GetVal(wxT("relname"))); + catalog->iSetOid(catalogs->GetOid(wxT("oid"))); + catalog->iSetOwner(catalogs->GetVal(wxT("owner"))); + catalog->iSetComment(catalogs->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(collection, catalog); + catalogs->MoveNext(); + } + else + break; + } + + delete catalogs; + } + return catalog; +} + +///////////////////////////// + +pgCatalogObjectCollection::pgCatalogObjectCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgCatalogObjectCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalog objects"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalog objects"); + break; + case OBJECTSLISTREPORT: + message = _("Catalog objects list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/catalogobject.pngc" +#include "images/catalogobject-sm.pngc" +#include "images/catalogobjects.pngc" + +pgCatalogObjectFactory::pgCatalogObjectFactory() + : pgSchemaObjFactory(__("Catalog Object"), __("New Catalog Object..."), __("Create a new Catalog Object."), catalogobject_png_img, catalogobject_sm_png_img) +{ + metaType = PGM_CATALOGOBJECT; +} + + +pgCollection *pgCatalogObjectFactory::CreateCollection(pgObject *obj) +{ + return new pgCatalogObjectCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgCatalogObjectFactory catalogObjectFactory; +static pgaCollectionFactory cf(&catalogObjectFactory, __("Catalog Objects"), catalogobjects_png_img); diff --git a/schema/pgCheck.cpp b/schema/pgCheck.cpp new file mode 100644 index 0000000..1002e5e --- /dev/null +++ b/schema/pgCheck.cpp @@ -0,0 +1,333 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCheck.cpp - Check class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgCheck.h" + + +pgCheck::pgCheck(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, checkFactory, newName) +{ +} + +pgCheck::~pgCheck() +{ +} + + +wxString pgCheck::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on check constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing check constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for check constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop check constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop check constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop check constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop check constraint?"); + break; + case PROPERTIESREPORT: + message = _("Check constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Check constraint properties"); + break; + case DDLREPORT: + message = _("Check constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Check constraint DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Check constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Check constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Check constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Check constraint dependents"); + break; + } + + return message; +} + + +int pgCheck::GetIconId() +{ + if (!GetDatabase()->BackendMinimumVersion(9, 2) || GetValid()) + return checkFactory.GetIconId(); + else + return checkFactory.GetClosedIconId(); +} + + +bool pgCheck::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER ") + objectKind + wxT(" ") + qtIdent(objectSchema) + wxT(".") + qtIdent(objectName) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgCheck::GetConstraint() +{ + sql = GetQuotedIdentifier() + wxT(" CHECK "); + + sql += wxT("(") + GetDefinition() + wxT(")"); + + if (GetDatabase()->BackendMinimumVersion(9, 2) && GetNoInherit()) + sql += wxT(" NO INHERIT"); + + if (GetDatabase()->BackendMinimumVersion(9, 2) && !GetValid()) + sql += wxT(" NOT VALID"); + + return sql; +} + + +wxString pgCheck::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Check: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- ALTER ") + objectKind + wxT(" ") + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier() + + wxT(";\n\nALTER ") + objectKind + wxT(" ") + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT("\n ADD CONSTRAINT ") + GetConstraint() + + wxT(";\n"); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON CONSTRAINT ") + GetQuotedIdentifier() + + wxT(" ON ") + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + + return sql; +} + + +void pgCheck::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Definition"), GetDefinition()); + if (GetDatabase()->BackendMinimumVersion(9, 2)) + { + properties->AppendItem(_("No Inherit?"), BoolToYesNo(GetNoInherit())); + properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid())); + } + // Check constraints on a domain don't have comments + if (objectKind.Upper() == wxT("TABLE")) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + +pgObject *pgCheck::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *check = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + check = checkFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + + return check; +} + + +void pgCheck::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER ") + objectKind + wxT(" ") + + GetQuotedSchemaPrefix(objectSchema) + qtIdent(objectName) + + wxT("\n VALIDATE CONSTRAINT ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + +pgObject *pgCheckFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgSchemaObjCollection *collection = (pgSchemaObjCollection *)coll; + pgCheck *check = 0; + + wxString connoinherit = collection->GetDatabase()->BackendMinimumVersion(9, 2) ? wxT(", connoinherit") : wxEmptyString; + wxString convalidated = collection->GetDatabase()->BackendMinimumVersion(9, 2) ? wxT(", convalidated") : wxEmptyString; + + wxString sql = + wxT("SELECT 'TABLE' AS objectkind, c.oid, conname, relname, nspname, description,\n") + wxT(" pg_get_expr(conbin, conrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as consrc\n") + + connoinherit + convalidated + + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE contype = 'c' AND conrelid = ") + NumToStr(collection->GetOid()) + + restriction + wxT("::oid\n") + wxT("UNION\n") + wxT("SELECT 'DOMAIN' AS objectkind, c.oid, conname, typname as relname, nspname, description,\n") + wxT(" regexp_replace(pg_get_constraintdef(c.oid, true), E'CHECK \\\\((.*)\\\\).*', E'\\\\1') as consrc\n") + + connoinherit + convalidated + + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_type t ON t.oid=contypid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=typnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE contype = 'c' AND contypid = ") + NumToStr(collection->GetOid()) + + restriction + wxT("::oid\n") + wxT(" ORDER BY conname"); + + pgSet *checks = collection->GetDatabase()->ExecuteSet(sql); + + if (checks) + { + while (!checks->Eof()) + { + check = new pgCheck(collection->GetSchema()->GetSchema(), checks->GetVal(wxT("conname"))); + + check->iSetOid(checks->GetOid(wxT("oid"))); + check->iSetDefinition(checks->GetVal(wxT("consrc"))); + check->iSetObjectKind(checks->GetVal(wxT("objectkind"))); + check->iSetObjectName(checks->GetVal(wxT("relname"))); + check->iSetObjectSchema(checks->GetVal(wxT("nspname"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + { + check->iSetNoInherit(checks->GetBool(wxT("connoinherit"))); + check->iSetValid(checks->GetBool(wxT("convalidated"))); + } + check->iSetComment(checks->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(collection, check); + checks->MoveNext(); + } + else + break; + } + + delete checks; + } + return check; +} + +///////////////////////////// + +wxString pgCheckCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on check constraints"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing check constraints"); + break; + case OBJECTSLISTREPORT: + message = _("Check constraints list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/check.pngc" +#include "images/checkbad.pngc" + +pgCheckFactory::pgCheckFactory() + : pgSchemaObjFactory(__("Check"), __("New Check..."), __("Create a new Check constraint."), check_png_img) +{ + metaType = PGM_CHECK; + collectionFactory = &constraintCollectionFactory; + closedId = addIcon(checkbad_png_img); +} + + +pgCheckFactory checkFactory; + +validateCheckFactory::validateCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate check constraint"), _("Validate the selected check constraint.")); +} + + +wxWindow *validateCheckFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgCheck *)obj)->Validate(form); + ((pgCheck *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgCheck *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateCheckFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(checkFactory) && obj->CanEdit() + && ((pgCheck *)obj)->GetConnection()->BackendMinimumVersion(9, 2) + && !((pgCheck *)obj)->GetValid(); +} diff --git a/schema/pgCollation.cpp b/schema/pgCollation.cpp new file mode 100644 index 0000000..35b4bb1 --- /dev/null +++ b/schema/pgCollation.cpp @@ -0,0 +1,249 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollation.cpp - Collation class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgCollation.h" +#include "schema/pgDatatype.h" + + +/* +dlgProperty *pgCollationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0L; +} +*/ + + +pgCollation::pgCollation(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, collationFactory, newName) +{ +} + +pgCollation::~pgCollation() +{ +} + +wxString pgCollation::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on collation"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing collation"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop collation \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop collation \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop collation cascaded?"); + break; + case DROPTITLE: + message = _("Drop collation?"); + break; + case PROPERTIESREPORT: + message = _("Collation properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Collation properties"); + break; + case DDLREPORT: + message = _("Collation DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Collation DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Collation dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Collation dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Collation dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Collation dependents"); + break; + } + + return message; +} + + +bool pgCollation::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP COLLATION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgCollation::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Collation: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP COLLATION ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE COLLATION ") + GetQuotedFullIdentifier() + + wxT("\n (LC_COLLATE=") + qtDbString(GetLcCollate()) + + wxT(", LC_CTYPE=") + qtDbString(GetLcCtype()) + + wxT(");\n"); + + sql += GetOwnerSql(9, 1) + + GetCommentSql(); + } + + return sql; +} + + +void pgCollation::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("LC_COLLATE"), GetLcCollate()); + properties->AppendItem(_("LC_CTYPE"), GetLcCtype()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgCollation::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *collation = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + collation = collationFactory.CreateObjects(coll, 0, wxT(" AND c.oid=") + GetOidStr() + wxT("\n")); + + return collation; +} + + +//////////////////////////////////////////////////// + + + +pgObject *pgCollationFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgCollation *collation = 0; + + pgDatabase *db = collection->GetDatabase(); + + pgSet *collations = db->ExecuteSet( + wxT("SELECT c.oid, c.collname, c.collcollate, c.collctype, \n") + wxT(" pg_get_userbyid(c.collowner) as cowner, description\n") + wxT(" FROM pg_collation c\n") + wxT(" JOIN pg_namespace n ON n.oid=c.collnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.classoid='pg_collation'::regclass)\n") + wxT(" WHERE c.collnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n") + + restriction + + wxT(" ORDER BY c.collname")); + + if (collations) + { + while (!collations->Eof()) + { + collation = new pgCollation(collection->GetSchema(), collations->GetVal(wxT("collname"))); + + collation->iSetOid(collations->GetOid(wxT("oid"))); + collation->iSetOwner(collations->GetVal(wxT("cowner"))); + collation->iSetLcCollate(collations->GetVal(wxT("collcollate"))); + collation->iSetLcCtype(collations->GetVal(wxT("collctype"))); + collation->iSetComment(collations->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(collection, collation); + collations->MoveNext(); + } + else + break; + } + + delete collations; + } + return collation; +} + +///////////////////////////// + +pgCollationCollection::pgCollationCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgCollationCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on collations"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing collations"); + break; + case OBJECTSLISTREPORT: + message = _("Collations list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/collation.pngc" +#include "images/collation-sm.pngc" +#include "images/collations.pngc" + +pgCollationFactory::pgCollationFactory() + : pgSchemaObjFactory(__("Collation"), __("New Collation..."), __("Create a new Collation."), collation_png_img, collation_sm_png_img) +{ +} + + +pgCollection *pgCollationFactory::CreateCollection(pgObject *obj) +{ + return new pgCollationCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgCollationFactory collationFactory; +static pgaCollectionFactory cf(&collationFactory, __("Collations"), collations_png_img); diff --git a/schema/pgCollection.cpp b/schema/pgCollection.cpp new file mode 100644 index 0000000..bf50a6d --- /dev/null +++ b/schema/pgCollection.cpp @@ -0,0 +1,148 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgCollection.cpp - Simple object for use with 'collection' nodes +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/menu.h" +#include "utils/misc.h" +#include "agent/pgaJob.h" +#include "schema/pgSchema.h" +#include "schema/pgTable.h" +#include "frm/frmMain.h" +#include "frm/frmReport.h" + +pgCollection::pgCollection(pgaFactory *factory) + : pgObject(*factory) +{ + um = 0; + fsrv = 0; + fdw = 0; + job = 0; + schema = 0; + database = 0; + server = 0; + projob = 0; +} + +bool pgCollection::IsCollectionFor(pgObject *obj) +{ + if (!obj) + return false; + pgaFactory *f = obj->GetFactory(); + if (!f) + return false; + return GetFactory() == f->GetCollectionFactory(); +} + + +bool pgCollection::IsCollectionForType(const int type) +{ + if (GetFactory()) + { + pgaFactory *f = pgaFactory::GetFactoryByMetaType(type); + return (f && f->GetCollectionFactory() == GetFactory()); + } + return false; +} + + +void pgCollection::ShowList(ctlTree *browser, ctlListView *properties) +{ + ShowList(((pgaCollectionFactory *)GetFactory())->GetItemTypeName(), browser, properties); +} + +void pgCollection::ShowList(const wxString &name, ctlTree *browser, ctlListView *properties) +{ + if (properties) + { + // Display the properties. + wxCookieType cookie; + pgObject *data; + + // Setup listview + CreateList3Columns(properties, wxGetTranslation(name), _("Owner"), _("Comment")); + + wxTreeItemId item = browser->GetFirstChild(GetId(), cookie); + long pos = 0; + while (item) + { + data = browser->GetObject(item); + if (IsCollectionFor(data)) + { + properties->InsertItem(pos, data->GetFullName(), data->GetIconId()); + properties->SetItem(pos, 1, data->GetOwner()); + properties->SetItem(pos, 2, firstLineOnly(data->GetComment())); + pos++; + } + // Get the next item + item = browser->GetNextChild(GetId(), cookie); + } + } +} + +void pgCollection::UpdateChildCount(ctlTree *browser, int substract) +{ + wxString label; + label.Printf(wxString(wxGetTranslation(GetName())) + wxT(" (%d)"), (int)browser->GetChildrenCount(GetId(), false) - substract); + browser->SetItemText(GetId(), label); +} + + +int pgCollection::GetIconId() +{ + pgaFactory *objFactory = pgaFactory::GetFactory(GetType()); + if (objFactory) + return objFactory->GetIconId(); + return 0; +} + + +pgObject *pgCollection::FindChild(ctlTree *browser, const int index) +{ + wxCookieType cookie; + pgObject *data; + + wxTreeItemId item = browser->GetFirstChild(GetId(), cookie); + long pos = 0; + while (item && index >= 0) + { + data = browser->GetObject(item); + if (data && IsCollectionFor(data)) + { + if (index == pos) + return data; + + pos++; + } + item = browser->GetNextChild(GetId(), cookie); + } + return 0; +} + + + +void pgCollection::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (browser->GetChildrenCount(GetId(), false) == 0) + { + if (GetFactory()) + GetFactory()->CreateObjects(this, browser); + } + + UpdateChildCount(browser); + if (properties) + { + ShowList(browser, properties); + } +} diff --git a/schema/pgColumn.cpp b/schema/pgColumn.cpp new file mode 100644 index 0000000..64f99b2 --- /dev/null +++ b/schema/pgColumn.cpp @@ -0,0 +1,809 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgColumn.cpp - Column class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "schema/pgDatatype.h" +#include "schema/pgColumn.h" + + +pgColumn::pgColumn(pgTable *newTable, const wxString &newName) + : pgTableObject(newTable, columnFactory, newName) +{ + isFK = false; + isPK = false; + isReferenced = -1; +} + +pgColumn::~pgColumn() +{ +} + + +wxString pgColumn::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on column"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing column"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for column"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop column \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop column \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop column cascaded?"); + break; + case DROPTITLE: + message = _("Drop column?"); + break; + case PROPERTIESREPORT: + message = _("Column properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Column properties"); + break; + case DDLREPORT: + message = _("Column DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Column DDL"); + break; + case STATISTICSREPORT: + message = _("Column statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Column statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Column dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Column dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Column dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Column dependents"); + break; + } + + return message; +} + + +bool pgColumn::IsReferenced() +{ + if (isReferenced < 0) + { + isReferenced = (int)StrToLong(GetConnection()->ExecuteScalar( + wxT("SELECT COUNT(1) FROM pg_depend dep\n") + wxT(" JOIN pg_class cl ON dep.classid=cl.oid AND relname='pg_rewrite'\n") + wxT(" WHERE refobjid=") + GetTableOidStr() + + wxT(" AND refobjsubid=") + NumToStr(GetColNumber()))); + } + + return (isReferenced != 0); +} + + +bool pgColumn::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullTable(); + sql += wxT(" DROP COLUMN ") + GetQuotedIdentifier(); + + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgColumn::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &where) +{ + pgObject::ShowDependencies(form, Dependencies, + wxT("\n WHERE dep.objid=") + table->GetOidStr() + + wxT(" AND dep.objsubid=") + NumToStr(colNumber)); +} + + +void pgColumn::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + pgObject::ShowDependents(form, referencedBy, + wxT("\n WHERE dep.refobjid=") + table->GetOidStr() + + wxT(" AND dep.refobjsubid=") + NumToStr(colNumber)); +} + +wxString pgColumn::GetSql(ctlTree *browser) +{ + if (sql.IsNull() && !GetSystemObject()) + { + if (GetTable()->GetMetaType() == PGM_VIEW) + { + sql = wxT("-- Column: ") + GetQuotedIdentifier() + wxT("\n\n"); + + if (!GetDefault().IsEmpty()) + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET DEFAULT ") + GetDefault() + wxT(";\n"); + + sql += GetCommentSql(); + } + else if (GetTable()->GetMetaType() == PGM_CATALOGOBJECT || GetTable()->GetMetaType() == GP_EXTTABLE) + { + sql = wxT("-- Column: ") + GetQuotedIdentifier() + wxT("\n\n"); + } + else + { + if (GetInheritedCount()) + sql = wxT("-- Column inherited; cannot be changed"); + else + { + sql = wxT("-- Column: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- ALTER TABLE ") + GetQuotedFullTable() + + wxT(" DROP COLUMN ") + GetQuotedIdentifier() + wxT(";") + + + wxT("\n\nALTER TABLE ") + GetQuotedFullTable() + + wxT(" ADD COLUMN ") + GetQuotedIdentifier() + wxT(" ") + + GetQuotedTypename(); + if (!GetCollation().IsEmpty() && GetCollation() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + GetCollation(); + sql += wxT(";\n"); + + sql += GetStorageSql(); + + if (GetNotNull()) + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET NOT NULL;\n"); + if (!GetDefault().IsEmpty()) + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET DEFAULT ") + GetDefault() + wxT(";\n"); + sql += GetAttstattargetSql(); + + sql += GetVariablesSql(); + + sql += GetCommentSql(); + + if (GetDatabase()->BackendMinimumVersion(8, 4)) + sql += GetPrivileges(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + } + } + + return sql; +} + +wxString pgColumn::GetCommentSql() +{ + wxString commentSql; + + if (!GetComment().IsEmpty()) + commentSql = wxT("COMMENT ON COLUMN ") + GetQuotedFullTable() + wxT(".") + GetQuotedIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + + return commentSql; +} + +wxString pgColumn::GetStorageSql() +{ + wxString storageSql; + + if (GetStorage() != GetDefaultStorage()) + storageSql = wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET STORAGE ") + GetStorage() + wxT(";\n"); + + return storageSql; +} + +wxString pgColumn::GetAttstattargetSql() +{ + wxString attstattargetSql; + + if (GetAttstattarget() >= 0) + attstattargetSql = wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET STATISTICS ") + NumToStr(GetAttstattarget()) + wxT(";\n"); + + return attstattargetSql; +} + +wxString pgColumn::GetVariablesSql() +{ + wxString variablesSql; + + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + variablesSql += wxT("ALTER TABLE ") + GetQuotedFullTable() + + wxT(" ALTER COLUMN ") + GetQuotedIdentifier() + + wxT(" SET (") + variables.Item(i) + wxT(");\n"); + + return variablesSql; +} + +wxString pgColumn::GetPrivileges() +{ + wxString privileges; + wxString strAcl = GetAcl(); + if (!strAcl.IsEmpty()) + { + wxArrayString aclArray; + strAcl = strAcl.Mid(1, strAcl.Length() - 2); + getArrayFromCommaSeparatedList(strAcl, aclArray); + wxString role; + for (unsigned int index = 0; index < aclArray.Count(); index++) + { + wxString strCurrAcl = aclArray[index]; + /* + * In rare case, we can have ',' (comma) in the user name. + * But, we need to handle them also + */ + if (strCurrAcl.Find(wxChar('=')) == wxNOT_FOUND) + { + // Check it is start of the ACL + if (strCurrAcl[0U] == (wxChar)'"') + role = strCurrAcl + wxT(","); + continue; + } + else + strCurrAcl = role + strCurrAcl; + + if (strCurrAcl[0U] == (wxChar)'"') + strCurrAcl = strCurrAcl.Mid(1, strCurrAcl.Length() - 1); + role = strCurrAcl.BeforeLast('='); + wxString value = strCurrAcl.Mid(role.Length() + 1).BeforeLast('/'); + + if (role.Left(6).IsSameAs(wxT("group "), false)) + { + role = wxT("group ") + qtIdent(qtStrip(role.Mid(6))); + } + else if (role.IsEmpty()) + { + role = wxT("public"); + } + else + role = qtIdent(qtStrip(role)); + + privileges += pgObject::GetPrivileges(wxT("awrx"), value, GetQuotedFullTable(), role, GetQuotedIdentifier()); + role.Clear(); + } + } + return privileges; +} +wxString pgColumn::GetDefinition() +{ + wxString sql = wxEmptyString; + wxString seqDefault1, seqDefault2; + + if (table->GetOfTypeOid() == 0) + sql += GetQuotedTypename(); + + if (!GetCollation().IsEmpty() && GetCollation() != wxT("pg_catalog.\"default\"")) + sql += wxT(" COLLATE ") + GetCollation(); + + wxString full_tabname = wxEmptyString; + if (GetDatabase()->BackendMinimumVersion(8, 1)) + { + wxString schpref; + + schpref = schema->GetQuotedPrefix(); + full_tabname = GetTableName() + wxT("_") + GetName() + wxT("_seq"); + + // If the generated sequence name is longer than 64 characters, then + // - If both table & column name exceed 29 chars, truncate both to 29 + // - If one of table or column name exceeds 29 chars, truncate it to + // 29 chars plus however much less than 29 chars the other name is. + if (full_tabname.Length() > 64) + { + int tlen = GetTableName().Length(); + int clen = GetName().Length(); + + if (tlen > 29 && clen > 29) + full_tabname = GetTableName().Left(29) + wxT("_") + GetName().Left(29) + wxT("_seq"); + else if (tlen > 29) + full_tabname = GetTableName().Left(29 + (29 - clen)) + wxT("_") + GetName() + wxT("_seq"); + else if (clen > 29) + full_tabname = GetTableName() + wxT("_") + GetName().Left(29 + (29 - tlen)) + wxT("_seq"); + } + + full_tabname = qtIdent(full_tabname); + + if (schpref != wxEmptyString) + full_tabname = schpref + full_tabname; + + seqDefault1 = wxT("nextval('") + full_tabname + wxT("'::regclass)"); + seqDefault2 = seqDefault1; + } + else + { + seqDefault1 = wxT("nextval('") + + schema->GetName() + wxT(".") + GetTableName() + + wxT("_") + GetName() + wxT("_seq'::text)"); + seqDefault2 = wxT("nextval('\"") + + schema->GetName() + wxT(".") + GetTableName() + + wxT("_") + GetName() + wxT("_seq\"'::text)"); + } + + if ((sql == wxT("integer") || sql == wxT("bigint") || sql == wxT("smallint") || + sql == wxT("pg_catalog.integer") || sql == wxT("pg_catalog.bigint") || sql == wxT("pg_catalog.smallint")) + && (GetDefault() == seqDefault1 || GetDefault() == seqDefault2)) + { + if (GetDatabase()->BackendMinimumVersion(8, 1)) + { + pgSet *set = ExecuteSet( + wxT("SELECT classid\n") + wxT(" FROM pg_depend\n") + wxT(" WHERE refobjid=") + table->GetOidStr() + + wxT(" AND refobjsubid = ") + NumToStr(GetColNumber()) + + wxT(" AND objid = '") + full_tabname + wxT("'::regclass") + + wxT(" AND deptype='a'")); + + if (set && set->NumRows()) + { + if (sql.Right(6) == wxT("bigint")) + sql = wxT("bigserial"); + else if (sql.Right(8) == wxT("smallint")) + sql = wxT("smallserial"); + else + sql = wxT("serial"); + } + + if (GetNotNull()) + sql += wxT(" NOT NULL"); + + if (!set || !(set->NumRows())) + AppendIfFilled(sql, wxT(" DEFAULT "), GetDefault()); + + if (set) + delete set; + } + else + { + if (sql.Right(6) == wxT("bigint")) + sql = wxT("bigserial"); + else if (sql.Right(8) == wxT("smallint")) + sql = wxT("smallserial"); + else + sql = wxT("serial"); + + if (GetNotNull()) + sql += wxT(" NOT NULL"); + } + } + else + { + if (GetNotNull()) + sql += wxT(" NOT NULL"); + if (!GetGenerated().IsEmpty()) { + if (GetGenerated()=="s") sql+= " GENERATED ALWAYS AS " + GetDefault() + " STORED"; + } else if (!GetIdentity().IsEmpty()) { + if (GetIdentity()=="a") sql+= " GENERATED ALWAYS AS IDENTITY"; + if (GetIdentity()=="d") sql+= " GENERATED BY DEFAULT AS IDENTITY" ; + } + else + AppendIfFilled(sql, wxT(" DEFAULT "), GetDefault()); + } + return sql; +} + + +void pgColumn::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + wxStringTokenizer indkey(pkCols); + while (indkey.HasMoreTokens()) + { + wxString str = indkey.GetNextToken(); + if (StrToLong(str) == GetColNumber()) + { + isPK = true; + break; + } + } + + if (!GetDatabase()->BackendMinimumVersion(7, 4)) + { + // 7.3 misses the ANY(array) comparison + pgSet *set = ExecuteSet( + wxT("SELECT conkey\n") + wxT(" FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl on cl.oid=confrelid\n") + wxT(" WHERE contype='f' AND conrelid = ") + GetTableOidStr() + wxT("\n") + wxT(" ORDER BY conname")); + if (set) + { + wxString str; + while (!isFK && !set->Eof()) + { + wxStringTokenizer conkey(set->GetVal(0)); + + while (conkey.HasMoreTokens()) + { + str = conkey.GetNextToken(); + if (StrToLong(str.Mid(1)) == GetColNumber()) + { + isFK = true; + break; + } + } + + set->MoveNext(); + } + delete set; + } + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Position"), GetColNumber()); + properties->AppendItem(_("Data type"), GetVarTypename()); + if (GetDatabase()->BackendMinimumVersion(9, 1)) + { + properties->AppendItem(_("Collation"), GetCollation()); + } + if (GetTable()->GetMetaType() != PGM_CATALOGOBJECT) + { + properties->AppendItem(_("Default"), GetDefault()); + if (GetTable()->GetMetaType() != PGM_VIEW && GetTable()->GetMetaType() != GP_EXTTABLE) + { + properties->AppendItem(_("Sequence"), database->GetSchemaPrefix(GetSerialSchema()) + GetSerialSequence()); + + properties->AppendYesNoItem(_("Not NULL?"), GetNotNull()); + properties->AppendYesNoItem(_("Primary key?"), GetIsPK()); + properties->AppendYesNoItem(_("Foreign key?"), GetIsFK()); + properties->AppendItem(_("Storage"), GetStorage()); + if (GetInheritedCount() != 0) + { + properties->AppendItem(_("Inherited"), + wxT("Yes (from table ") + GetInheritedTableName() + wxT(")")); + } + else + { + properties->AppendYesNoItem(_("Inherited"), false); + } + properties->AppendItem(_("Statistics"), GetAttstattarget()); + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + { + wxString item = variables.Item(i); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + properties->AppendYesNoItem(_("System column?"), GetSystemObject()); + } + } + if (GetDatabase()->BackendMinimumVersion(8, 4)) + { + properties->AppendItem(_("ACL"), GetAcl()); + } + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + +void pgColumn::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + DisplayStatistics(statistics, + wxT("SELECT null_frac AS ") + qtIdent(_("Null Fraction")) + + wxT(", avg_width AS ") + qtIdent(_("Average Width")) + + wxT(", n_distinct AS ") + qtIdent(_("Distinct Values")) + + wxT(", most_common_vals AS ") + qtIdent(_("Most Common Values")) + + wxT(", most_common_freqs AS ") + qtIdent(_("Most Common Frequencies")) + + wxT(", histogram_bounds AS ") + qtIdent(_("Histogram Bounds")) + + wxT(", correlation AS ") + qtIdent(_("Correlation")) + wxT("\n") + wxT(" FROM pg_stats\n") + wxT(" WHERE schemaname = ") + qtDbString(schema->GetName()) + wxT("\n") + wxT(" AND tablename = ") + qtDbString(GetTableName()) + wxT("\n") + wxT(" AND attname = ") + qtDbString(GetName())); +} + + +pgObject *pgColumn::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *column = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + column = columnFactory.CreateObjects(coll, 0, wxT("\n AND att.attnum=") + NumToStr(GetColNumber())); + + return column; +} + + + +pgObject *pgColumnFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgTableObjCollection *collection = (pgTableObjCollection *)coll; + pgColumn *column = 0; + pgDatabase *database = collection->GetDatabase(); + inheritHashMap inhMap; + + // grab inherited tables with attibute names + pgSet *inhtables = database->ExecuteSet( + wxT("SELECT\n") + wxT(" array_to_string(array_agg(inhrelname), ', ') inhrelname,\n") + wxT(" attrname\n") + wxT("FROM\n") + wxT(" (SELECT\n") + wxT(" inhparent::regclass AS inhrelname,\n") + wxT(" a.attname AS attrname\n") + wxT(" FROM\n") + wxT(" pg_inherits i\n") + wxT(" LEFT JOIN pg_attribute a ON\n") + wxT(" (attrelid = inhparent AND attnum > 0)\n") + wxT(" WHERE inhrelid = ") + collection->GetOidStr() + wxT("::oid\n") + wxT(" ORDER BY inhseqno) a\n") + wxT("GROUP BY attrname")); + + if (inhtables) + { + while (!inhtables->Eof()) + { + wxString attrName = inhtables->GetVal(wxT("attrname")); + wxString inhrelName = inhtables->GetVal(wxT("inhrelname")); + inhMap[attrName] = inhrelName; + inhtables->MoveNext(); + } + + delete inhtables; + } + + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT("\n AND att.attnum > 0"); + + wxString sql = + wxT("SELECT att.*, def.*, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS defval, CASE WHEN att.attndims > 0 THEN 1 ELSE 0 END AS isarray, format_type(ty.oid,NULL) AS typname, format_type(ty.oid,att.atttypmod) AS displaytypname, tn.nspname as typnspname, et.typname as elemtypname,\n") + wxT(" ty.typstorage AS defaultstorage, cl.relname, na.nspname, att.attstattarget, description, cs.relname AS sername, ns.nspname AS serschema,\n") + wxT(" (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup, indkey"); + + if (database->BackendMinimumVersion(9, 1)) + sql += wxT(",\n coll.collname, nspc.nspname as collnspname"); + if (database->BackendMinimumVersion(8, 5)) + sql += wxT(",\n attoptions"); + if (database->BackendMinimumVersion(7, 4)) + sql += + wxT(",\n") + wxT(" EXISTS(SELECT 1 FROM pg_constraint WHERE conrelid=att.attrelid AND contype='f'") + wxT(" AND att.attnum=ANY(conkey)) As isfk"); + if (database->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=att.attrelid AND sl1.objsubid=att.attnum) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=att.attrelid AND sl2.objsubid=att.attnum) AS providers"); + } + + sql += wxT("\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" JOIN pg_class cl ON cl.oid=att.attrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_type et ON et.oid=ty.typelem\n") + wxT(" LEFT OUTER JOIN pg_attrdef def ON adrelid=att.attrelid AND adnum=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN (pg_depend JOIN pg_class cs ON classid='pg_class'::regclass AND objid=cs.oid AND cs.relkind='S') ON refobjid=att.attrelid AND refobjsubid=att.attnum\n") + wxT(" LEFT OUTER JOIN pg_namespace ns ON ns.oid=cs.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_index pi ON pi.indrelid=att.attrelid AND indisprimary\n"); + if (database->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation coll ON att.attcollation=coll.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + sql += wxT(" WHERE att.attrelid = ") + collection->GetOidStr() + + restriction + systemRestriction + wxT("\n") + wxT(" AND att.attisdropped IS FALSE\n") + wxT(" ORDER BY att.attnum"); + + pgSet *columns = database->ExecuteSet(sql); + if (columns) + { + while (!columns->Eof()) + { + wxString attrName = columns->GetVal(wxT("attname")); + column = new pgColumn(collection->GetTable(), attrName); + + column->iSetAttTypId(columns->GetOid(wxT("atttypid"))); + column->iSetColNumber(columns->GetLong(wxT("attnum"))); + column->iSetIsArray(columns->GetBool(wxT("isarray"))); + column->iSetComment(columns->GetVal(wxT("description"))); + column->iSetSerialSequence(columns->GetVal(wxT("sername"))); + column->iSetSerialSchema(columns->GetVal(wxT("serschema"))); + if (database->BackendMinimumVersion(10, 0)) + { + column->iSetIdentity(columns->GetVal(wxT("attidentity"))); + }; + if (database->BackendMinimumVersion(12, 0)) + { + column->iSetGenerated(columns->GetVal(wxT("attgenerated"))); + }; + + + + column->iSetPkCols(columns->GetVal(wxT("indkey"))); + if (database->BackendMinimumVersion(7, 4)) + column->iSetIsFK(columns->GetBool(wxT("isfk"))); + + if (columns->GetBool(wxT("atthasdef"))) + column->iSetDefault(columns->GetVal(wxT("defval"))); + column->iSetStatistics(columns->GetLong(wxT("attstattarget"))); + + wxString storage = columns->GetVal(wxT("attstorage")); + column->iSetStorage( + storage == wxT("p") ? wxT("PLAIN") : + storage == wxT("e") ? wxT("EXTERNAL") : + storage == wxT("m") ? wxT("MAIN") : + storage == wxT("x") ? wxT("EXTENDED") : wxT("Unknown")); + wxString defaultStorage = columns->GetVal(wxT("defaultstorage")); + column->iSetDefaultStorage( + defaultStorage == wxT("p") ? wxT("PLAIN") : + defaultStorage == wxT("e") ? wxT("EXTERNAL") : + defaultStorage == wxT("m") ? wxT("MAIN") : + defaultStorage == wxT("x") ? wxT("EXTENDED") : wxT("Unknown")); + + column->iSetTyplen(columns->GetLong(wxT("attlen"))); + + long typmod = columns->GetLong(wxT("atttypmod")); + pgDatatype dt(columns->GetVal(wxT("typnspname")), columns->GetVal(wxT("typname")), + columns->GetBool(wxT("isdup")), + columns->GetLong(wxT("attndims")), typmod); + + + column->iSetTypmod(typmod); + column->iSetLength(dt.Length()); + column->iSetPrecision(dt.Precision()); + column->iSetRawTypename(dt.Name()); + + column->iSetVarTypename(dt.FullName()); + column->iSetQuotedTypename(columns->GetVal(wxT("displaytypname"))); + + column->iSetNotNull(columns->GetBool(wxT("attnotnull"))); + column->iSetQuotedFullTable(database->GetQuotedSchemaPrefix(columns->GetVal(wxT("nspname"))) + + qtIdent(columns->GetVal(wxT("relname")))); + column->iSetTableName(columns->GetVal(wxT("relname"))); + column->iSetInheritedCount(columns->GetLong(wxT("attinhcount"))); + + // Check whether the attribute is inherited + inheritHashMap::iterator it = inhMap.find(attrName); + if (it != inhMap.end()) + column->iSetInheritedTableName(it->second); + + column->iSetIsLocal(columns->GetBool(wxT("attislocal"))); + column->iSetAttstattarget(columns->GetLong(wxT("attstattarget"))); + if (database->BackendMinimumVersion(8, 5)) + { + wxString str = columns->GetVal(wxT("attoptions")); + if (!str.IsEmpty()) + FillArray(column->GetVariables(), str.Mid(1, str.Length() - 2)); + } + if (database->BackendMinimumVersion(8, 4)) + column->iSetAcl(columns->GetVal(wxT("attacl"))); + if (database->BackendMinimumVersion(9, 1)) + { + wxString coll = wxEmptyString; + if (!columns->GetVal(wxT("collname")).IsEmpty()) + coll = qtIdent(columns->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(columns->GetVal(wxT("collname"))); + column->iSetCollation(coll); + } + + if (database->BackendMinimumVersion(9, 1)) + { + column->iSetProviders(columns->GetVal(wxT("providers"))); + column->iSetLabels(columns->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, column); + columns->MoveNext(); + } + else + break; + } + + delete columns; + } + + inhMap.clear(); + return column; +} + +///////////////////////////// + +pgColumnCollection::pgColumnCollection(pgaFactory *factory, pgTable *tbl) + : pgTableObjCollection(factory, tbl) +{ +} + + +wxString pgColumnCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on columns"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing columns"); + break; + case OBJECTSLISTREPORT: + message = _("Columns list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/column.pngc" +#include "images/column-sm.pngc" +#include "images/columns.pngc" + +pgColumnFactory::pgColumnFactory() + : pgTableObjFactory(__("Column"), __("New Column..."), __("Create a new Column."), column_png_img, column_sm_png_img) +{ + metaType = PGM_COLUMN; +} + + +pgCollection *pgColumnFactory::CreateCollection(pgObject *obj) +{ + return new pgColumnCollection(GetCollectionFactory(), (pgTable *)obj); +} + +pgColumnFactory columnFactory; +static pgaCollectionFactory cf(&columnFactory, __("Columns"), columns_png_img); diff --git a/schema/pgConstraints.cpp b/schema/pgConstraints.cpp new file mode 100644 index 0000000..b768e53 --- /dev/null +++ b/schema/pgConstraints.cpp @@ -0,0 +1,129 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConstraint.cpp - Constraint collection +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + + +#include "pgAdmin3.h" +#include "schema/pgTable.h" +#include "schema/pgDomain.h" +#include "schema/pgConstraints.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgCheck.h" +#include "schema/pgForeignKey.h" +#include "schema/pgPartition.h" + + +pgConstraintCollection::pgConstraintCollection(pgaFactory *factory, pgSchema *schema) + : pgSchemaObjCollection(factory, schema) +{ +} + +wxMenu *pgConstraintCollection::GetNewMenu() +{ + if ((table && !table->CanCreate()) || (domain && !domain->CanCreate())) + return 0; + + wxMenu *menu = new wxMenu(); + if (table) + { + if (table->GetPrimaryKey().IsEmpty()) + primaryKeyFactory.AppendMenu(menu); + foreignKeyFactory.AppendMenu(menu); + excludeFactory.AppendMenu(menu); + uniqueFactory.AppendMenu(menu); + } + checkFactory.AppendMenu(menu); + return menu; +} + + +void pgConstraintCollection::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (browser->GetChildrenCount(GetId(), false) == 0) + { + browser->RemoveDummyChild(this); + + wxTreeItemId id = browser->GetItemParent(GetId()); + wxASSERT(id); + table = NULL; + domain = NULL; + if (browser->GetObject(id)->IsCreatedBy(tableFactory)) + { + table = (pgTable *)browser->GetObject(id); + } + if (browser->GetObject(id)->IsCreatedBy(pg_partitionFactory)) + { + table = (pgTable *)browser->GetObject(id); + } + + if (browser->GetObject(id)->IsCreatedBy(domainFactory)) + { + domain = (pgDomain *)browser->GetObject(id); + } + + if (table) + { + primaryKeyFactory.CreateObjects(this, browser); + foreignKeyFactory.CreateObjects(this, browser); + excludeFactory.CreateObjects(this, browser); + uniqueFactory.CreateObjects(this, browser); + } + checkFactory.CreateObjects(this, browser); + } + UpdateChildCount(browser); + if (properties) + ShowList(_("Constraints"), browser, properties); +} + + +wxString pgConstraintCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on constraints"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing constraints"); + break; + case OBJECTSLISTREPORT: + message = _("Constraints list report"); + break; + } + + return message; +} + + +///////////////////////////// + +#include "images/constraints.pngc" + +pgConstraintFactory::pgConstraintFactory() + : pgSchemaObjFactory(__("Constraint"), 0, 0, 0) +{ + metaType = PGM_CONSTRAINT; +} + +pgCollection *pgConstraintFactory::CreateCollection(pgObject *obj) +{ + return new pgConstraintCollection(GetCollectionFactory(), (pgSchema *)obj); +} + + +pgConstraintFactory constraintFactory; +pgaCollectionFactory constraintCollectionFactory(&constraintFactory, __("Constraints"), constraints_png_img); + + diff --git a/schema/pgConversion.cpp b/schema/pgConversion.cpp new file mode 100644 index 0000000..faf5fef --- /dev/null +++ b/schema/pgConversion.cpp @@ -0,0 +1,245 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgConversion.cpp - Conversion class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgConversion.h" + + +pgConversion::pgConversion(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, conversionFactory, newName) +{ +} + +pgConversion::~pgConversion() +{ +} + +wxString pgConversion::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on conversion"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing conversion"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop conversion \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop conversion \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop conversion cascaded?"); + break; + case DROPTITLE: + message = _("Drop conversion?"); + break; + case PROPERTIESREPORT: + message = _("Conversion properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Conversion properties"); + break; + case DDLREPORT: + message = _("Conversion DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Conversion DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Conversion dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Conversion dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Conversion dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Conversion dependents"); + break; + } + + return message; +} + + +bool pgConversion::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP CONVERSION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgConversion::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Conversion: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP CONVERSION ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + if (GetDefaultConversion()) + sql += wxT("DEFAULT "); + sql += wxT("CONVERSION ") + qtIdent(GetName()) + + wxT("\n FOR '") + GetForEncoding() + wxT("'") + + wxT("\n TO '") + GetToEncoding() + wxT("'") + + wxT("\n FROM ") + GetDatabase()->GetQuotedSchemaPrefix(GetProcNamespace()) + + qtIdent(GetProc()) + wxT(";\n") + + GetOwnerSql(8, 0); + } + + return sql; +} + +void pgConversion::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("From"), GetForEncoding()); + properties->AppendItem(_("To"), GetToEncoding()); + properties->AppendItem(_("Function"), GetSchemaPrefix(GetProcNamespace()) + GetProc()); + properties->AppendYesNoItem(_("Default?"), GetDefaultConversion()); + properties->AppendYesNoItem(_("System conversion?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + + +pgObject *pgConversion::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *conversion = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + conversion = conversionFactory.CreateObjects(coll, 0, wxT("\n AND co.oid=") + GetOidStr()); + + return conversion; +} + + + +pgObject *pgConversionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgConversion *conversion = 0; + + pgSet *conversions = collection->GetDatabase()->ExecuteSet( + wxT("SELECT co.oid, co.*, pg_encoding_to_char(conforencoding) as forencoding, pg_get_userbyid(conowner) as owner,") + wxT("pg_encoding_to_char(contoencoding) as toencoding, proname, nspname, description\n") + wxT(" FROM pg_conversion co\n") + wxT(" JOIN pg_proc pr ON pr.oid=conproc\n") + wxT(" JOIN pg_namespace na ON na.oid=pr.pronamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=co.oid AND des.objsubid=0 AND des.classoid='pg_conversion'::regclass)\n") + wxT(" WHERE connamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY conname")); + + if (conversions) + { + while (!conversions->Eof()) + { + conversion = new pgConversion(collection->GetSchema(), + conversions->GetVal(wxT("conname"))); + + conversion->iSetOid(conversions->GetOid(wxT("oid"))); + conversion->iSetOwner(conversions->GetVal(wxT("owner"))); + conversion->iSetComment(conversions->GetVal(wxT("description"))); + conversion->iSetForEncoding(conversions->GetVal(wxT("forencoding"))); + conversion->iSetToEncoding(conversions->GetVal(wxT("toencoding"))); + conversion->iSetProc(conversions->GetVal(wxT("proname"))); + conversion->iSetProcNamespace(conversions->GetVal(wxT("nspname"))); + conversion->iSetDefaultConversion(conversions->GetBool(wxT("condefault"))); + + if (browser) + { + browser->AppendObject(collection, conversion); + conversions->MoveNext(); + } + else + break; + } + + delete conversions; + } + return conversion; +} + +///////////////////////////// + +pgConversionCollection::pgConversionCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgConversionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on conversions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing conversions"); + break; + case OBJECTSLISTREPORT: + message = _("Conversions list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/conversion.pngc" +#include "images/conversions.pngc" + +pgConversionFactory::pgConversionFactory() + : pgSchemaObjFactory(__("Conversion"), __("New Conversion..."), __("Create a new Conversion."), conversion_png_img) +{ +} + + +pgCollection *pgConversionFactory::CreateCollection(pgObject *obj) +{ + return new pgConversionCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgConversionFactory conversionFactory; +static pgaCollectionFactory cf(&conversionFactory, __("Conversions"), conversions_png_img); diff --git a/schema/pgDatabase.cpp b/schema/pgDatabase.cpp new file mode 100644 index 0000000..89502ee --- /dev/null +++ b/schema/pgDatabase.cpp @@ -0,0 +1,1360 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatabase.cpp - PostgreSQL Database +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" +#include "frm/frmMain.h" +#include "schema/edbSynonym.h" +#include "schema/pgCast.h" +#include "schema/pgExtension.h" +#include "schema/pgPublication.h" +#include "schema/pgSubscription.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgLanguage.h" +#include "schema/pgSchema.h" +#include "schema/pgEventTrigger.h" +#include "slony/slCluster.h" +#include "frm/frmHint.h" +#include "frm/frmReport.h" + + +pgDatabase::pgDatabase(const wxString &newName) + : pgServerObject(databaseFactory, newName) +{ + useServerConnection = true; + allowConnections = true; + connected = false; + conn = NULL; + missingFKs = 0; + canDebugPlpgsql = 0; + canDebugEdbspl = 0; +} + + +pgDatabase::~pgDatabase() +{ + Disconnect(); +} + + +wxString pgDatabase::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on database"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing database"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop database \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop database \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop database cascaded?"); + break; + case DROPTITLE: + message = _("Drop database?"); + break; + case PROPERTIESREPORT: + message = _("Database properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Database properties"); + break; + case DDLREPORT: + message = _("Database DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Database DDL"); + break; + case STATISTICSREPORT: + message = _("Database statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Database statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Database dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Database dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Database dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Database dependents"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup database \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore database \"%s\""), + GetFullIdentifier().c_str()); + break; + } + + return message; +} + + +int pgDatabase::GetIconId() +{ + if (GetConnected()) + return databaseFactory.GetIconId(); + else + return databaseFactory.GetClosedIconId(); +} + + +wxMenu *pgDatabase::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + + if (GetConnection() && GetCreatePrivilege()) + { + if (settings->GetDisplayOption(_("Casts"))) + castFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Extensions")) && GetConnection()->BackendMinimumVersion(9, 1)) + extensionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Publications")) && GetConnection()->BackendMinimumVersion(10, 0)) + publicationFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Subscriptions")) && GetConnection()->BackendMinimumVersion(10, 0)) + subscriptionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Foreign Data Wrappers")) && GetConnection()->BackendMinimumVersion(8, 4)) + foreignDataWrapperFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Languages"))) + languageFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 0)) + if (!GetConnection()->BackendMinimumVersion(8, 4)) + synonymFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Schemas"))) + schemaFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Slony"))) + slClusterFactory.AppendMenu(menu); + } + return menu; +} + +int pgDatabase::Connect() +{ + if (!allowConnections) + return PGCONN_REFUSED; + + if (!connected) + { + if (GetName() == server->GetDatabaseName() && server->connection()->GetStatus() == PGCONN_OK) + { + useServerConnection = true; + conn = 0; + } + else + { + useServerConnection = false; + wxString applicationname = appearanceFactory->GetLongAppName() + wxT(" - Browser"); + conn = CreateConn(applicationname); + + if (!conn) + { + connected = false; + return PGCONN_BAD; + } + } + + // Now we're connected. + + // check for extended ruleutils with pretty-print option + wxString exprname = connection()->ExecuteScalar(wxT("SELECT proname FROM pg_proc WHERE proname='pg_get_viewdef' AND proargtypes[1]=16")); + if (!exprname.IsEmpty()) + prettyOption = wxT(", true"); + + UpdateDefaultSchema(); + + if (connection()->BackendMinimumVersion(9, 0)) + { + m_defPrivsOnTables = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='r'")); + m_defPrivsOnSeqs = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='S'")); + m_defPrivsOnFuncs = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='f'")); + } + if (connection()->BackendMinimumVersion(9, 2)) + { + m_defPrivsOnTypes = connection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = 0::OID AND defaclobjtype='T'")); + } + + connected = true; + } + + return connection()->GetStatus(); +} + + +pgConn *pgDatabase::connection() +{ + if (useServerConnection) + return server->connection(); + return conn; + +} + +void pgDatabase::CheckAlive() +{ + if (connected) + connected = connection()->IsAlive(); +} + +void pgDatabase::Disconnect() +{ + connected = false; + if (conn) + delete conn; + conn = 0; +} + + +bool pgDatabase::GetCanHint() +{ + if (encoding == wxT("SQL_ASCII")) + return true; + + if (encoding == wxT("UNICODE")) + { + wxString ver = GetServer()->GetVersionString(); + if (ver.Find(wxT("mingw32")) > 0 && ver.Find(wxT("SQL 8.0.")) > 0) + return true; + } + + if (GetServer()->GetConnection() == GetConnection() && + GetConnection()->BackendMinimumVersion(8, 0) && + !GetConnection()->HasFeature(FEATURE_FILEREAD)) + return true; + + return false; +} + + +void pgDatabase::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + int rc = -1; + + if (encoding == wxT("SQL_ASCII")) + hints.Add(HINT_ENCODING_ASCII); + else if (encoding == wxT("UNICODE")) + { + wxString ver = GetServer()->GetVersionString(); + if (ver.Find(wxT("mingw32")) > 0 && ver.Find(wxT("SQL 8.0.")) > 0) + hints.Add(HINT_ENCODING_UNICODE); + } + + if (GetServer()->GetConnection() == GetConnection() && + GetConnection()->BackendMinimumVersion(8, 0) && + !GetConnection()->HasFeature(FEATURE_FILEREAD)) + { + // if the server release is 9.1 or more and the server has no adminpack + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + // Search the adminpack extension + pgSet *set = GetConnection()->ExecuteSet(wxT("SELECT 1 FROM pg_available_extensions WHERE name='adminpack'")); + if (set->NumRows() == 1) + hints.Add(HINT_INSTRUMENTATION_91_WITH); + else + hints.Add(HINT_INSTRUMENTATION_91_WITHOUT); + delete set; + } + else + hints.Add(HINT_INSTRUMENTATION); + } + + if (force || !hintShown) + { + rc = frmHint::ShowHint(form, hints, GetFullIdentifier(), force); + if (rc == HINT_RC_FIX) + GetConnection()->ExecuteVoid(wxT("CREATE EXTENSION adminpack"), true); + } + hintShown = true; +} + + +void pgDatabase::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()) + { + bool hasSize = connection()->HasFeature(FEATURE_SIZE); + + wxString sql = wxT("SELECT numbackends AS ") + qtIdent(_("Backends")) + + wxT(", xact_commit AS ") + qtIdent(_("Xact Committed")) + + wxT(", xact_rollback AS ") + qtIdent(_("Xact Rolled Back")) + + wxT(", blks_read AS ") + qtIdent(_("Blocks Read")) + + wxT(", blks_hit AS ") + qtIdent(_("Blocks Hit")); + + if (connection()->BackendMinimumVersion(8, 3)) + sql += wxT(", tup_returned AS ") + qtIdent(_("Tuples Returned")) + + wxT(", tup_fetched AS ") + qtIdent(_("Tuples Fetched")) + + wxT(", tup_inserted AS ") + qtIdent(_("Tuples Inserted")) + + wxT(", tup_updated AS ") + qtIdent(_("Tuples Updated")) + + wxT(", tup_deleted AS ") + qtIdent(_("Tuples Deleted")); + + if (connection()->BackendMinimumVersion(9, 1)) + sql += wxT(", stats_reset AS ") + qtIdent(_("Last statistics reset")) + + wxT(", slave.confl_tablespace AS ") + qtIdent(_("Tablespace conflicts")) + + wxT(", slave.confl_lock AS ") + qtIdent(_("Lock conflicts")) + + wxT(", slave.confl_snapshot AS ") + qtIdent(_("Snapshot conflicts")) + + wxT(", slave.confl_bufferpin AS ") + qtIdent(_("Bufferpin conflicts")) + + wxT(", slave.confl_deadlock AS ") + qtIdent(_("Deadlock conflicts")); + + if (connection()->BackendMinimumVersion(9, 2)) + sql += wxT(", temp_files AS ") + qtIdent(_("Temporary files")) + + wxT(", pg_size_pretty(temp_bytes) AS ") + qtIdent(_("Size of temporary files")) + + wxT(", deadlocks AS ") + qtIdent(_("Deadlocks")) + + wxT(", blk_read_time AS ") + qtIdent(_("Block read time")) + + wxT(", blk_write_time AS ") + qtIdent(_("Block write time")); + + if (hasSize) + sql += wxT(", pg_size_pretty(pg_database_size(db.datid)) AS ") + qtIdent(_("Size")); + + sql += wxT("\n FROM pg_stat_database db"); + if (connection()->BackendMinimumVersion(9, 1)) + sql += wxT(" JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid"); + sql += wxT(" WHERE db.datname=") + qtDbString(GetName()); + + // DisplayStatistics is not available for this object + + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = connection()->ExecuteSet(sql); + + if (stats) + { + int col; + for (col = 0 ; col < stats->NumCols() ; col++) + { + if (!stats->ColName(col).IsEmpty()) + statistics->AppendItem(stats->ColName(col), stats->GetVal(col)); + } + delete stats; + } + } +} + + +pgSet *pgDatabase::ExecuteSet(const wxString &sql) +{ + pgSet *set = 0; + if (connection()) + { + set = connection()->ExecuteSet(sql); + if (!set) + CheckAlive(); + } + return set; +} + + +wxString pgDatabase::ExecuteScalar(const wxString &sql) +{ + wxString str; + if (connection()) + { + str = connection()->ExecuteScalar(sql); + if (str.IsEmpty() && connection()->GetLastResultStatus() != PGRES_TUPLES_OK) + CheckAlive(); + } + return str; +} + + +bool pgDatabase::ExecuteVoid(const wxString &sql, bool reportError) +{ + bool rc = 0; + if (connection()) + { + rc = connection()->ExecuteVoid(sql, reportError); + if (!rc) + CheckAlive(); + } + return rc; +} + + +void pgDatabase::UpdateDefaultSchema() +{ + searchPath = connection()->ExecuteScalar(wxT("SHOW search_path")); + + if (!searchPath.IsEmpty()) + { + wxStringTokenizer tk(searchPath, wxT(",")); + pgSet *set = ExecuteSet(wxT("SELECT nspname, session_user=nspname AS isuser FROM pg_namespace")); + if (set) + { + while (tk.HasMoreTokens()) + { + wxString str = tk.GetNextToken(); + str.Strip(wxString::both); + + if (str.IsEmpty()) + continue; + long row; + for (row = 1 ; row <= set->NumRows() ; row++) + { + set->Locate(row); + defaultSchema = set->GetVal(wxT("nspname")); + if (str == defaultSchema || + ((str == wxT("$user") || str == wxT("\"$user\"")) && set->GetBool(wxT("isuser")))) + { + delete set; + return; + } + } + } + delete set; + } + } + defaultSchema = wxEmptyString; +} + + +wxString pgDatabase::GetSchemaPrefix(const wxString &name) const +{ + if (name.IsEmpty()) + return name; + + if (name == wxT("pg_catalog") || name == defaultSchema) + return wxEmptyString; + + return name + wxT("."); +} + + +wxString pgDatabase::GetQuotedSchemaPrefix(const wxString &name) const +{ + wxString str = GetSchemaPrefix(name); + if (!str.IsEmpty()) + return qtIdent(str.Left(str.Length() - 1)) + wxT("."); + return str; +} + + +bool pgDatabase::GetSystemObject() const +{ + if (server) + { + if (this->GetName() == wxT("template0")) return true; + return (this->GetOid() <= server->GetLastSystemOID()); + } + else + { + return false; + } +} + + +wxArrayString pgDatabase::GetSlonyClusters(ctlTree *browser) +{ + wxArrayString clusters; + + pgCollection *collection = browser->FindCollection(slClusterFactory, GetId()); + if (collection) + { + treeObjectIterator clusterIterator(browser, collection); + + slCluster *cluster; + while ((cluster = (slCluster *)clusterIterator.GetNextObject()) != 0) + clusters.Add(cluster->GetName()); + } + return clusters; +} + + +void pgDatabase::AppendSchemaChange(const wxString &sql) +{ + wxDateTime dt; + dt.Now(); + schemaChanges.Append(wxT("-- ") + DateToStr(dt) + wxT("\n")); + schemaChanges.Append(sql); + schemaChanges.Append(wxT("\n\n")); +} + +bool pgDatabase::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (useServerConnection) + { + wxMessageDialog(frame, _("Maintenance database can't be dropped."), + _("Dropping database not allowed"), wxICON_EXCLAMATION | wxOK).ShowModal(); + + return false; + } + Disconnect(); + + bool done = server->ExecuteVoid(wxT("DROP DATABASE ") + GetQuotedIdentifier() + wxT(";")); + if (!done) + Connect(); + + return done; +} + + + +wxString pgDatabase::GetSql(ctlTree *browser) +{ + if (sql.IsEmpty()) + { + // If we can't connect to this database, use the maintenance DB + pgConn *myConn = GetConnection(); + if (!myConn) + myConn = GetServer()->GetConnection(); + + sql = wxT("-- Database: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP DATABASE ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\nCREATE DATABASE ") + GetQuotedIdentifier() + + wxT("\n WITH OWNER = ") + qtIdent(GetOwner()) + + wxT("\n ENCODING = ") + qtDbString(GetEncoding()); + if (!GetTablespace().IsEmpty()) + sql += wxT("\n TABLESPACE = ") + qtIdent(GetTablespace()); + if (myConn && myConn->BackendMinimumVersion(8, 4)) + { + sql += wxT("\n LC_COLLATE = ") + qtDbString(GetCollate()); + sql += wxT("\n LC_CTYPE = ") + qtDbString(GetCType()); + } + if (myConn && myConn->BackendMinimumVersion(8, 1)) + { + sql += wxT("\n CONNECTION LIMIT = "); + sql << GetConnectionLimit(); + } + sql += wxT(";\n"); + + if (variables.GetCount() > 0) + { + size_t i; + wxString username = wxEmptyString; + wxString parameter = wxEmptyString; + wxString value = wxEmptyString; + + sql += wxT("\n"); + for (i = 0 ; i < variables.GetCount() ; i += 3) + { + username = variables.Item(i); + parameter = variables.Item(i + 1); + value = variables.Item(i + 2); + + if (username.Length() == 0) + { + sql += wxT("ALTER DATABASE ") + GetQuotedFullIdentifier(); + } + else + { + sql += wxT("ALTER ROLE ") + username + wxT(" IN DATABASE ") + GetQuotedFullIdentifier(); + } + + if (parameter != wxT("search_path") && parameter != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + parameter + wxT(" = '") + value + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + parameter + wxT(" = ") + value + wxT(";\n"); + } + } + } + + if (myConn) + { + if (!myConn->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("CT")); + else + sql += GetGrant(wxT("CTc")); + } + + sql += wxT("\n") + pgDatabase::GetDefaultPrivileges('r', m_defPrivsOnTables, wxT("")); + sql += pgDatabase::GetDefaultPrivileges('S', m_defPrivsOnSeqs, wxT("")); + sql += pgDatabase::GetDefaultPrivileges('f', m_defPrivsOnFuncs, wxT("")); + sql += pgDatabase::GetDefaultPrivileges('T', m_defPrivsOnTypes, wxT("")); + + sql += GetCommentSql(); + + if (myConn->BackendMinimumVersion(9, 2)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + + +void pgDatabase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (Connect() == PGCONN_OK) + { + // Set the icon if required + UpdateIcon(browser); + + // Add child nodes if necessary + if (browser->GetChildrenCount(GetId(), false) == 0) + { + wxLogInfo(wxT("Adding child object to database %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("Catalogs"))) + browser->AppendCollection(this, catalogFactory); + if (settings->GetDisplayOption(_("Casts"))) + browser->AppendCollection(this, castFactory); + if (connection()->BackendMinimumVersion(9, 3) && settings->GetDisplayOption(_("Event Triggers"))) + browser->AppendCollection(this, eventTriggerFactory); + if (settings->GetDisplayOption(_("Extensions")) && GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, extensionFactory); + if (settings->GetDisplayOption(_("Publications")) && GetConnection()->BackendMinimumVersion(10, 0)) + browser->AppendCollection(this, publicationFactory); + if (settings->GetDisplayOption(_("Subscriptions")) && GetConnection()->BackendMinimumVersion(10, 0)) + browser->AppendCollection(this, subscriptionFactory); + if (settings->GetDisplayOption(_("Foreign Data Wrappers")) && GetConnection()->BackendMinimumVersion(8, 4)) + browser->AppendCollection(this, foreignDataWrapperFactory); + if (settings->GetDisplayOption(_("Languages"))) + browser->AppendCollection(this, languageFactory); + if (settings->GetDisplayOption(_("Synonyms")) && connection()->EdbMinimumVersion(8, 0)) + if (!GetConnection()->BackendMinimumVersion(8, 4)) + browser->AppendCollection(this, synonymFactory); + if (settings->GetDisplayOption(_("Schemas"))) + browser->AppendCollection(this, schemaFactory); + if (settings->GetDisplayOption(_("Slony-I Clusters"))) + browser->AppendCollection(this, slClusterFactory); + + wxString missingFKsql = wxT("SELECT COUNT(*) FROM\n") + wxT(" (SELECT tgargs from pg_trigger tr\n") + wxT(" LEFT JOIN pg_depend dep ON dep.objid=tr.oid AND deptype = 'i'\n") + wxT(" LEFT JOIN pg_constraint co ON refobjid = co.oid AND contype = 'f'\n") + wxT(" WHERE \n"); + if (connection()->BackendMinimumVersion(9, 0)) + missingFKsql += wxT("tgisinternal\n"); + else + missingFKsql += wxT("tgisconstraint\n"); + + missingFKsql += wxT(" AND co.oid IS NULL\n") + wxT(" GROUP BY tgargs\n") + wxT(" HAVING count(1) = 3) AS foo"); + missingFKs = StrToLong(connection()->ExecuteScalar(missingFKsql)); + + // Get configuration + wxString query; + if (connection()->BackendMinimumVersion(9, 0)) + { + query = wxT("WITH configs AS ") + wxT("(SELECT rolname, unnest(setconfig) AS config") + wxT(" FROM pg_db_role_setting s") + wxT(" LEFT JOIN pg_roles r ON r.oid=s.setrole") + wxT(" WHERE s.setdatabase=") + NumToStr(GetOid()) + wxT(")\n") + wxT("SELECT rolname, split_part(config, '=', 1) AS variable, ") + wxT(" replace(config, split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM configs"); + } + else + { + wxString query_mydb = wxT("SELECT datconfig FROM pg_database WHERE oid=") + NumToStr(GetOid()); + query = wxT("SELECT '' AS rolname, split_part(config, '=', 1) AS variable,\n") + wxT(" replace(config,split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM (\n") + wxT(" SELECT\n") + wxT(" (\n") + wxT(" SELECT datconfig[i]\n") + wxT(" FROM pg_database\n") + wxT(" WHERE oid=") + NumToStr(GetOid()) + wxT("\n") + wxT(" ) AS config\n") + wxT(" FROM generate_series(array_lower((") + query_mydb + wxT("),1), array_upper((") + query_mydb + wxT("),1)) AS i\n") + wxT(" ) configs"); + } + pgSet *configs = connection()->ExecuteSet(query); + if (configs) + { + while (!configs->Eof()) + { + variables.Add(configs->GetVal(wxT("rolname"))); + variables.Add(configs->GetVal(wxT("variable"))); + variables.Add(configs->GetVal(wxT("value"))); + configs->MoveNext(); + } + delete configs; + } + } + } + + GetServer()->iSetLastDatabase(GetName()); + + if (properties) + { + // Setup listview + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), NumToStr(GetOid())); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + if (!GetPath().IsEmpty()) + properties->AppendItem(_("Path"), GetPath()); + + // We may not actually be connected... + if (GetConnection() && GetConnection()->BackendMinimumVersion(8, 0)) + { + properties->AppendItem(_("Tablespace"), GetTablespace()); + properties->AppendItem(_("Default tablespace"), GetDefaultTablespace()); + } + properties->AppendItem(_("Encoding"), GetEncoding()); + + if (GetConnection() && GetConnection()->BackendMinimumVersion(8, 4)) + { + properties->AppendItem(_("Collation"), GetCollate()); + properties->AppendItem(_("Character type"), GetCType()); + } + + properties->AppendItem(_("Default schema"), defaultSchema); + + if (GetConnection() && GetConnection()->BackendMinimumVersion(9, 0)) + { + properties->AppendItem(_("Default table ACL"), m_defPrivsOnTables); + properties->AppendItem(_("Default sequence ACL"), m_defPrivsOnSeqs); + properties->AppendItem(_("Default function ACL"), m_defPrivsOnFuncs); + } + if (GetConnection() && GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("Default type ACL"), m_defPrivsOnTypes); + + size_t i; + wxString username; + wxString parameter; + wxString value; + for (i = 0 ; i < variables.GetCount() ; i += 3) + { + username = variables.Item(i); + parameter = variables.Item(i + 1); + value = variables.Item(i + 2); + + if (username.Length() == 0) + { + properties->AppendItem(parameter, value); + } + else + { + properties->AppendItem(parameter + wxT(" (role ") + username + wxT(")"), value); + } + } + properties->AppendYesNoItem(_("Allow connections?"), GetAllowConnections()); + properties->AppendYesNoItem(_("Connected?"), GetConnected()); + if (GetConnection() && GetConnection()->BackendMinimumVersion(8, 1)) + { + wxString strConnLimit; + strConnLimit.Printf(wxT("%ld"), GetConnectionLimit()); + properties->AppendItem(_("Connection limit"), strConnLimit); + } + properties->AppendYesNoItem(_("System database?"), GetSystemObject()); + if (GetMissingFKs()) + properties->AppendItem(_("Old style FKs"), GetMissingFKs()); + if (!GetSchemaRestriction().IsEmpty()) + properties->AppendItem(_("Schema restriction"), GetSchemaRestriction()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } + if (form && GetCanHint() && !hintShown) + { + ShowHint(form, false); + } +} + + + +pgObject *pgDatabase::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgDatabase *database = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + database = (pgDatabase *)databaseFactory.CreateObjects(coll, 0, wxT(" WHERE db.oid=") + GetOidStr() + wxT("\n")); + + return database; +} + + +pgObject *pgDatabaseFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgDatabase *database = 0; + + pgSet *databases; + + wxString datcollate, datctype, datconnlimit, seclabelsql; + + if (collection->GetConnection()->BackendMinimumVersion(8, 1)) + { + datconnlimit = wxT(", db.datconnlimit as connectionlimit"); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + datctype = wxT(", db.datctype as ctype"); + datcollate = wxT(", db.datcollate as collate"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + seclabelsql = wxT(",\n(SELECT array_agg(label) FROM pg_shseclabel sl1 WHERE sl1.objoid=db.oid) AS labels") + wxT(",\n(SELECT array_agg(provider) FROM pg_shseclabel sl2 WHERE sl2.objoid=db.oid) AS providers"); + } + + wxString restr = restriction; + if (!collection->GetServer()->GetDbRestriction().IsEmpty()) + { + if (restr.IsEmpty()) + restr = wxT(" WHERE datname IN ("); + else + restr += wxT(" AND datname IN ("); + + restr += collection->GetServer()->GetDbRestriction() + wxT(")\n"); + } + + // In 9.0+, database config options are in pg_db_role_setting + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + databases = collection->GetServer()->ExecuteSet( + wxT("SELECT db.oid, datname, db.dattablespace AS spcoid, spcname, datallowconn, datacl, ") + wxT("pg_encoding_to_char(encoding) AS serverencoding, pg_get_userbyid(datdba) AS datowner,") + wxT("has_database_privilege(db.oid, 'CREATE') as cancreate, \n") + wxT("current_setting('default_tablespace') AS default_tablespace, \n") + wxT("descr.description\n") + + datconnlimit + datcollate + datctype + seclabelsql + + wxT(" FROM pg_database db\n") + wxT(" LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID\n") + wxT(" LEFT OUTER JOIN pg_shdescription descr ON (db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)\n") + + restr + + wxT(" ORDER BY datname")); + } + else if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + databases = collection->GetServer()->ExecuteSet( + wxT("SELECT db.oid, datname, db.dattablespace AS spcoid, spcname, datallowconn, datacl, ") + wxT("pg_encoding_to_char(encoding) AS serverencoding, pg_get_userbyid(datdba) AS datowner,") + wxT("has_database_privilege(db.oid, 'CREATE') as cancreate, \n") + wxT("current_setting('default_tablespace') AS default_tablespace, \n") + wxT("descr.description\n") + + datconnlimit + datcollate + datctype + + wxT(" FROM pg_database db\n") + wxT(" LEFT OUTER JOIN pg_tablespace ta ON db.dattablespace=ta.OID\n") + wxT(" LEFT OUTER JOIN ") + + wxString(collection->GetConnection()->BackendMinimumVersion(8, 2) ? wxT("pg_shdescription") : wxT("pg_description")) + + wxT(" descr ON (db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)\n") + + restr + + wxT(" ORDER BY datname")); + else + databases = collection->GetServer()->ExecuteSet( + wxT("SELECT db.oid, datname, datpath, datallowconn, datacl, ") + wxT("pg_encoding_to_char(encoding) AS serverencoding, pg_get_userbyid(datdba) AS datowner,") + wxT("has_database_privilege(db.oid, 'CREATE') as cancreate,\n") + wxT("descr.description\n") + wxT(" FROM pg_database db\n") + wxT(" LEFT OUTER JOIN pg_description descr ON (db.oid=descr.objoid AND descr.classoid='pg_database'::regclass)\n") + + restr + + wxT(" ORDER BY datname")); + + if (databases) + { + while (!databases->Eof()) + { + wxString name = databases->GetVal(wxT("datname")); + database = new pgDatabase(name); + database->iSetServer(collection->GetServer()); + database->iSetOid(databases->GetOid(wxT("oid"))); + database->iSetOwner(databases->GetVal(wxT("datowner"))); + database->iSetAcl(databases->GetVal(wxT("datacl"))); + database->iSetEncoding(databases->GetVal(wxT("serverencoding"))); + database->iSetCreatePrivilege(databases->GetBool(wxT("cancreate"))); + database->iSetComment(databases->GetVal(wxT("description"))); + database->iSetAllowConnections(databases->GetBool(wxT("datallowconn"))); + + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + database->iSetTablespace(databases->GetVal(wxT("spcname"))); + database->iSetTablespaceOid(databases->GetOid(wxT("spcoid"))); + if (databases->GetVal(wxT("default_tablespace")) == wxEmptyString || databases->GetVal(wxT("default_tablespace")) == wxT("unset")) + database->iSetDefaultTablespace(databases->GetVal(wxT("spcname"))); + else + database->iSetDefaultTablespace(databases->GetVal(wxT("default_tablespace"))); + } + else + database->iSetPath(databases->GetVal(wxT("datpath"))); + + if (collection->GetConnection()->BackendMinimumVersion(8, 1)) + { + database->iSetConnectionLimit(databases->GetLong(wxT("connectionlimit"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + database->iSetCollate(databases->GetVal(wxT("collate"))); + database->iSetCType(databases->GetVal(wxT("ctype"))); + } + + if (collection->GetServer()->GetServerIndex()) + { + wxString value; + settings->Read(wxT("Servers/") + NumToStr(collection->GetServer()->GetServerIndex()) + + wxT("/Databases/") + name + wxT("/SchemaRestriction"), &value, wxEmptyString); + + database->iSetSchemaRestriction(value); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + database->iSetProviders(databases->GetVal(wxT("providers"))); + database->iSetLabels(databases->GetVal(wxT("labels"))); + } + + // Add the treeview node if required + if (settings->GetShowSystemObjects() || !database->GetSystemObject()) + { + if (browser) + { + int icon; + if (database->GetName() == database->GetServer()->GetDatabaseName()) + icon = databaseFactory.GetIconId(); + else + icon = databaseFactory.GetClosedIconId(); + + browser->AppendItem(collection->GetId(), database->GetIdentifier(), icon, -1, database); + } + else + break; + } + else + delete database; + + databases->MoveNext(); + } + delete databases; + } + return database; +} + +wxString pgDatabase::GetDefaultPrivileges(const wxChar &cType, wxString strDefPrivs, const wxString &strSchema) +{ + wxString strDefPrivsSql; + + if (!strDefPrivs.IsEmpty()) + { + wxString strRole, strPriv, strSupportedPrivs, strType; + strDefPrivs.Replace(wxT("\\\""), wxT("\""), true); + strDefPrivs.Replace(wxT("\\\\"), wxT("\\"), true); + + switch(cType) + { + case 'r': + strType = wxT("TABLES"); + strSupportedPrivs = wxT("arwdDxt"); + break; + case 'S': + strType = wxT("SEQUENCES"); + strSupportedPrivs = wxT("rwU"); + break; + case 'f': + strType = wxT("FUNCTIONS"); + strSupportedPrivs = wxT("X"); + break; + case 'T': + strType = wxT("TYPES"); + strSupportedPrivs = wxT("U"); + break; + default: + return wxT(""); + } + + // Removing starting brace '{' and ending brace '}' + strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length() - 1); + + while (pgObject::findUserPrivs(strDefPrivs, strRole, strPriv)) + { + strDefPrivsSql += pgObject::GetDefaultPrivileges(strType, strSupportedPrivs, strSchema, wxT(""), strPriv, qtIdent(strRole)); + + strRole = wxT(""); + strPriv = wxT(""); + } + } + return strDefPrivsSql; +} + +bool pgDatabase::CanCreate() +{ + return GetDatabase()->GetCreatePrivilege(); +} + +bool pgDatabase::CanDebugPlpgsql() +{ + wxString preload_option; + + // Result cache - 0 = not tested, 1 = false, 2 = true. + if (canDebugPlpgsql == 1) + return false; + else if (canDebugPlpgsql == 2) + return true; + + // "show shared_preload_libraries" does not work for other than + // the super users. + if (GetServer()->GetSuperUser()) + { + // Parameter's name depends of the backend's version + if (server->GetConnection()->BackendMinimumVersion(8, 2)) + { + preload_option = wxT("shared_preload_libraries"); + } + else + { + preload_option = wxT("preload_libraries"); + } + + // Check the appropriate plugin is loaded + if (!ExecuteScalar(wxT("SHOW ") + preload_option).Contains(wxT("plugin_debugger"))) + { + canDebugPlpgsql = 1; + return false; + } + } + + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_target_info';")) == wxT("0")) + { + canDebugPlpgsql = 1; + return false; + } + + // If this is EDBAS81, the debuggers will be built into the PLs + // so we don't need to check any further. + if (server->GetConnection()->EdbMinimumVersion(8, 1)) + { + canDebugPlpgsql = 2; + return true; + } + + // On EDBAS82 and PostgreSQL, we need to check to make sure that + // the debugger library is also available. + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'plpgsql_oid_debug';")) == wxT("0")) + { + canDebugPlpgsql = 1; + return false; + } + else + { + canDebugPlpgsql = 2; + return true; + } + + return true; +} + +bool pgDatabase::CanDebugEdbspl() +{ + // Result cache - 0 = not tested, 1 = false, 2 = true. + if (canDebugEdbspl == 1) + return false; + else if (canDebugEdbspl == 2) + return true; + + // "show shared_preload_libraries" does not work for other than + // the super users. + if (GetServer()->GetSuperUser()) + { + // Check the appropriate plugin is loaded + + // Before EDBAS92, there was a separate library for SPL and PL/pgSQL. + // Starting with 9.2, EDB uses the community version of pldebugger, + // and support for both languages is built into plugin_debugger.so + wxString library_name; + + if (server->GetConnection()->EdbMinimumVersion(9, 2)) + library_name = wxT("plugin_debugger"); + else + library_name = wxT("plugin_spl_debugger"); + + if (!ExecuteScalar(wxT("SHOW shared_preload_libraries;")).Contains(library_name)) + { + canDebugEdbspl = 1; + return false; + } + } + + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'pldbg_get_target_info';")) == wxT("0")) + { + canDebugEdbspl = 1; + return false; + } + + // If this is EDBAS81, the debuggers will be built into the PLs + // so we don't need to check any further. + if (server->GetConnection()->EdbMinimumVersion(8, 1)) + { + canDebugEdbspl = 2; + return true; + } + + // On EDBAS82 and PostgreSQL, we need to check to make sure that + // the debugger library is also available. + if (ExecuteScalar(wxT("SELECT count(*) FROM pg_proc WHERE proname = 'edb_oid_debug';")) == wxT("0")) + { + canDebugEdbspl = 1; + return false; + } + else + { + canDebugEdbspl = 2; + return true; + } + + return true; +} + +pgDatabaseCollection::pgDatabaseCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgDatabaseCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on databases"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing databases"); + break; + case STATISTICSREPORT: + message = _("Databases statistics report"); + break; + case OBJSTATISTICS: + message = _("Databases statistics"); + break; + case OBJECTSLISTREPORT: + message = _("Databases list report"); + break; + } + + return message; +} + + +void pgDatabaseCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for databases on ") + GetServer()->GetIdentifier()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + wxString restr; + if (!GetServer()->GetDbRestriction().IsEmpty()) + { + if (restr.IsEmpty()) + restr = wxT(" WHERE db.datname IN ("); + else + restr = wxT(" AND db.datname IN ("); + + restr += GetServer()->GetDbRestriction() + wxT(")\n"); + } + + wxString sql = wxT("SELECT db.datid, db.datname, numbackends, xact_commit, xact_rollback, blks_read, blks_hit"); + + if (GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", tup_returned, tup_fetched, tup_inserted, tup_updated, tup_deleted"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(", stats_reset, slave.confl_tablespace, slave.confl_lock, slave.confl_snapshot, slave.confl_bufferpin, slave.confl_deadlock"); + if (hasSize) + sql += wxT(", pg_size_pretty(pg_database_size(db.datid)) as size"); + + sql += wxT("\n FROM pg_stat_database db\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(" JOIN pg_stat_database_conflicts slave ON db.datid=slave.datid\n"); + sql += restr + wxT(" ORDER BY db.datname"); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Database"), 60); + statistics->AddColumn(_("Backends"), 50); + if (hasSize) + statistics->AddColumn(_("Size"), 60); + statistics->AddColumn(_("Xact Committed"), 60); + statistics->AddColumn(_("Xact Rolled Back"), 60); + statistics->AddColumn(_("Blocks Read"), 60); + statistics->AddColumn(_("Blocks Hit"), 60); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->AddColumn(_("Tuples Returned"), 60); + statistics->AddColumn(_("Tuples Fetched"), 60); + statistics->AddColumn(_("Tuples Inserted"), 60); + statistics->AddColumn(_("Tuples Updated"), 60); + statistics->AddColumn(_("Tuples Deleted"), 60); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->AddColumn(_("Last statistics reset"), 60); + statistics->AddColumn(_("Tablespace conflicts"), 60); + statistics->AddColumn(_("Lock conflicts"), 60); + statistics->AddColumn(_("Snapshot conflicts"), 60); + statistics->AddColumn(_("Bufferpin conflicts"), 60); + statistics->AddColumn(_("Deadlock conflicts"), 60); + } + + bool sysobj; + pgSet *stats = GetServer()->ExecuteSet(sql); + if (stats) + { + while (!stats->Eof()) + { + if (stats->GetVal(wxT("datname")) == wxT("template0")) + sysobj = true; + else + sysobj = stats->GetOid(wxT("datid")) <= GetServer()->GetLastSystemOID(); + + if (settings->GetShowSystemObjects() || !sysobj) + { + statistics->InsertItem(statistics->GetItemCount(), stats->GetVal(wxT("datname")), PGICON_STATISTICS); + statistics->SetItem(statistics->GetItemCount() - 1, 1, stats->GetVal(wxT("numbackends"))); + if (hasSize) + statistics->SetItem(statistics->GetItemCount() - 1, 2, stats->GetVal(wxT("size"))); + statistics->SetItem(statistics->GetItemCount() - 1, 2 + (hasSize ? 1 : 0), stats->GetVal(wxT("xact_commit"))); + statistics->SetItem(statistics->GetItemCount() - 1, 3 + (hasSize ? 1 : 0), stats->GetVal(wxT("xact_rollback"))); + statistics->SetItem(statistics->GetItemCount() - 1, 4 + (hasSize ? 1 : 0), stats->GetVal(wxT("blks_read"))); + statistics->SetItem(statistics->GetItemCount() - 1, 5 + (hasSize ? 1 : 0), stats->GetVal(wxT("blks_hit"))); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->SetItem(statistics->GetItemCount() - 1, 6 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_returned"))); + statistics->SetItem(statistics->GetItemCount() - 1, 7 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_fetched"))); + statistics->SetItem(statistics->GetItemCount() - 1, 8 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_inserted"))); + statistics->SetItem(statistics->GetItemCount() - 1, 9 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_updated"))); + statistics->SetItem(statistics->GetItemCount() - 1, 10 + (hasSize ? 1 : 0), stats->GetVal(wxT("tup_deleted"))); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->SetItem(statistics->GetItemCount() - 1, 11 + (hasSize ? 1 : 0), stats->GetVal(wxT("stats_reset"))); + statistics->SetItem(statistics->GetItemCount() - 1, 12 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_tablespace"))); + statistics->SetItem(statistics->GetItemCount() - 1, 13 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_lock"))); + statistics->SetItem(statistics->GetItemCount() - 1, 14 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_snapshot"))); + statistics->SetItem(statistics->GetItemCount() - 1, 15 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_bufferpin"))); + statistics->SetItem(statistics->GetItemCount() - 1, 16 + (hasSize ? 1 : 0), stats->GetVal(wxT("confl_deadlock"))); + } + } + stats->MoveNext(); + } + + delete stats; + } +} + + + +///////////////////////////////////////////////////// + +pgDatabaseObjCollection::pgDatabaseObjCollection(pgaFactory *factory, pgDatabase *db) + : pgCollection(factory) +{ + database = db; + server = database->GetServer(); +} + + +bool pgDatabaseObjCollection::CanCreate() +{ + if (IsCollectionForType(PGM_CATALOG)) + return false; + + return GetDatabase()->GetCreatePrivilege(); +} + + +#include "images/database.pngc" +#include "images/database-sm.pngc" +#include "images/databases.pngc" +#include "images/closeddatabase.pngc" +#include "images/closeddatabase-sm.pngc" + +pgDatabaseFactory::pgDatabaseFactory() + : pgServerObjFactory(__("Database"), __("New Database..."), __("Create a new Database."), database_png_img, database_sm_png_img) +{ + metaType = PGM_DATABASE; + closedId = addIcon(closeddatabase_png_img); + smallClosedId = addIcon(closeddatabase_sm_png_img); +} + +pgCollection *pgDatabaseFactory::CreateCollection(pgObject *obj) +{ + return new pgDatabaseCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgCollection *pgDatabaseObjFactory::CreateCollection(pgObject *obj) +{ + return new pgDatabaseObjCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + + +pgDatabaseFactory databaseFactory; +static pgaCollectionFactory cf(&databaseFactory, __("Databases"), databases_png_img); + + +disconnectDatabaseFactory::disconnectDatabaseFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Disconnec&t database"), _("Disconnect from the selected database.")); +} + + +wxWindow *disconnectDatabaseFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ctlTree *browser = form->GetBrowser(); + pgDatabase *database = (pgDatabase *)obj; + + if (obj->CheckOpenDialogs(browser, browser->GetSelection())) + { + wxString msg = _("There are properties dialogues open for one or more objects that would be refreshed. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot disconnect database"), wxICON_WARNING | wxOK); + } + else + { + database->Disconnect(); + database->UpdateIcon(browser); + browser->DeleteChildren(obj->GetId()); + browser->SelectItem(browser->GetItemParent(obj->GetId())); + form->execSelChange(browser->GetItemParent(obj->GetId()), true); + } + + return 0; +} + + +bool disconnectDatabaseFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(databaseFactory)) + return ((pgDatabase *)obj)->GetConnected() && (((pgDatabase *)obj)->GetName() != ((pgDatabase *)obj)->GetServer()->GetDatabaseName()); + + return false; +} diff --git a/schema/pgDatatype.cpp b/schema/pgDatatype.cpp new file mode 100644 index 0000000..1d28ae6 --- /dev/null +++ b/schema/pgDatatype.cpp @@ -0,0 +1,320 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDatatype.cpp - PostgreSQL Datatypes +// +////////////////////////////////////////////////////////////////////////// + + +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgDatatype.h" +#include "schema/pgDatabase.h" +#include "utils/pgDefs.h" + + +pgDatatype::pgDatatype(const wxString &nsp, const wxString &typname, bool isDup, long numdims, long typmod) +{ + needSchema = isDup; + schema = nsp; + + // Above 7.4, format_type also sends the schema name if it's not included + // in the search_path, so we need to skip it in the typname + if (typname.Contains(schema + wxT("\"."))) + name = typname.Mid(schema.Len() + 3); // "+2" because of the two double quotes + else if (typname.Contains(schema + wxT("."))) + name = typname.Mid(schema.Len() + 1); + else + name = typname; + + if (name.StartsWith(wxT("_"))) + { + if (!numdims) + numdims = 1; + name = name.Mid(1); + } + if (name.Right(2) == wxT("[]")) + { + if (!numdims) + numdims = 1; + name = name.Left(name.Len() - 2); + } + + if (name.StartsWith(wxT("\"")) && name.EndsWith(wxT("\""))) + name = name.Mid(1, name.Len() - 2); + + if (numdims > 0) + { + while (numdims--) + array += wxT("[]"); + } + + if (typmod != -1) + { + length = wxT("("); + if (name == wxT("numeric")) + { + len = (typmod - 4L) >> 16L; + prec = (typmod - 4) & 0xffff; + length += NumToStr(len); + if (prec) + length += wxT(",") + NumToStr(prec); + } + else if (name == wxT("time") || name == wxT("timetz") + || name == wxT("time without time zone") || name == wxT("time with time zone") + || name == wxT("timestamp") || name == wxT("timestamptz") + || name == wxT("timestamp without time zone") || name == wxT("timestamp with time zone") + || name == wxT("bit") || name == wxT("bit varying") || name == wxT("varbit")) + { + prec = 0; + len = typmod; + length += NumToStr(len); + } + else if (name == wxT("interval")) + { + prec = 0; + len = (typmod & 0xffff); + length += NumToStr(len); + } + else if (name == wxT("date")) + { + len = prec = 0; + length = wxT(""); /* Clear Length */ + } + else + { + prec = 0; + len = typmod - 4L; + length += NumToStr(len); + } + + if (length.Length() > 0) + length += wxT(")"); + } + else + len = prec = 0; +} + +// Return the full name of the type, with dimension and array qualifiers +wxString pgDatatype::FullName() const +{ + if (name == wxT("char") && schema == wxT("pg_catalog")) + return wxT("\"char\"") + array; + else if (name == wxT("time with time zone")) + return wxT("time") + length + wxT(" with time zone") + array; + else if (name == wxT("time without time zone")) + return wxT("time") + length + wxT(" without time zone") + array; + else if (name == wxT("timestamp with time zone")) + return wxT("timestamp") + length + wxT(" with time zone") + array; + else if (name == wxT("timestamp without time zone")) + return wxT("timestamp") + length + wxT(" without time zone") + array; + else + return name + length + array; +} + +// Return the quoted full name of the type, with dimension and array qualifiers +wxString pgDatatype::QuotedFullName() const +{ + if (name == wxT("char") && schema == wxT("pg_catalog")) + return wxT("\"char\"") + array; + else if (name == wxT("time with time zone")) + return wxT("time") + length + wxT(" with time zone") + array; + else if (name == wxT("time without time zone")) + return wxT("time") + length + wxT(" without time zone") + array; + else if (name == wxT("timestamp with time zone")) + return wxT("timestamp") + length + wxT(" with time zone") + array; + else if (name == wxT("timestamp without time zone")) + return wxT("timestamp") + length + wxT(" without time zone") + array; + else + return qtTypeIdent(name) + length + array; +} + +wxString pgDatatype::GetSchemaPrefix(pgDatabase *db) const +{ + if (schema.IsEmpty() || (!db && schema == wxT("pg_catalog"))) + return wxEmptyString; + + if (needSchema) + return schema + wxT("."); + + return db->GetSchemaPrefix(schema); +} + + +wxString pgDatatype::GetQuotedSchemaPrefix(pgDatabase *db) const +{ + wxString str = GetSchemaPrefix(db); + if (!str.IsEmpty()) + return qtIdent(str.Left(str.Length() - 1)) + wxT("."); + return str; +} + + +long pgDatatype::GetTypmod(const wxString &name, const wxString &len, const wxString &prec) +{ + if (len.IsEmpty()) + return -1; + if (name == wxT("numeric")) + { + return (((long)StrToLong(len) << 16) + StrToLong(prec)) + 4; + } + else if (name == wxT("time") || name == wxT("timetz") + || name == wxT("time without time zone") || name == wxT("time with time zone") + || name == wxT("timestamp") || name == wxT("timestamptz") + || name == wxT("timestamp without time zone") || name == wxT("timestamp with time zone") + || name == wxT("interval") || name == wxT("bit") || name == wxT("bit varying") || name == wxT("varbit")) + { + return StrToLong(len); + } + else + { + return StrToLong(len) + 4; + } +} + + +DatatypeReader::DatatypeReader(pgDatabase *db, const wxString &condition, bool addSerials) +{ + init(db, condition, addSerials); +} + + +DatatypeReader::DatatypeReader(pgDatabase *db, bool withDomains, bool addSerials) +{ + wxString condition = wxT("typisdefined AND typtype "); + // We don't get pseudotypes here + if (withDomains) + condition += wxT("IN ('b', 'c', 'd', 'e', 'r')"); + else + condition += wxT("IN ('b', 'c', 'e', 'r')"); + + condition += wxT("AND NOT EXISTS (select 1 from pg_class where relnamespace=typnamespace and relname = typname and relkind != 'c') AND (typname not like '_%' OR NOT EXISTS (select 1 from pg_class where relnamespace=typnamespace and relname = substring(typname from 2)::name and relkind != 'c')) "); + + if (!settings->GetShowSystemObjects()) + condition += wxT(" AND nsp.nspname != 'information_schema'"); + init(db, condition, addSerials); +} + +void DatatypeReader::init(pgDatabase *db, const wxString &condition, bool addSerials) +{ + database = db; + wxString sql = wxT("SELECT * FROM (SELECT format_type(t.oid,NULL) AS typname, CASE WHEN typelem > 0 THEN typelem ELSE t.oid END as elemoid, typlen, typtype, t.oid, nspname,\n") + wxT(" (SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup\n") + wxT(" FROM pg_type t\n") + wxT(" JOIN pg_namespace nsp ON typnamespace=nsp.oid\n") + wxT(" WHERE (NOT (typname = 'unknown' AND nspname = 'pg_catalog')) AND ") + condition + wxT("\n"); + + if (addSerials) + { + if (db->GetConnection()->BackendMinimumVersion(9, 2)) + { + sql += wxT(" UNION SELECT 'smallserial', 0, 2, 'b', 0, 'pg_catalog', false\n"); + } + sql += wxT(" UNION SELECT 'bigserial', 0, 8, 'b', 0, 'pg_catalog', false\n"); + sql += wxT(" UNION SELECT 'serial', 0, 4, 'b', 0, 'pg_catalog', false\n"); + } + + sql += wxT(" ) AS dummy ORDER BY nspname <> 'pg_catalog', nspname <> 'public', nspname, 1"); + + set = db->GetConnection()->ExecuteSet(sql); +} + + +bool DatatypeReader::IsDomain() const +{ + return set->GetVal(wxT("typtype")) == 'd'; +} + + +bool DatatypeReader::IsVarlen() const +{ + return set->GetLong(wxT("typlen")) == -1; +} + + +bool DatatypeReader::MaySpecifyLength() const +{ + if (IsDomain()) + return false; + + switch ((long)set->GetOid(wxT("elemoid"))) + { + case PGOID_TYPE_BIT: + case PGOID_TYPE_CHAR: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_NUMERIC: + return true; + default: + return false; + } +} + + +bool DatatypeReader::MaySpecifyPrecision() const +{ + if (IsDomain()) + return false; + + switch ((long)set->GetOid(wxT("elemoid"))) + { + case PGOID_TYPE_NUMERIC: + return true; + default: + return false; + } +} + + +pgDatatype DatatypeReader::GetDatatype() const +{ + return pgDatatype(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")), set->GetBool(wxT("isdup"))); +} + + +wxString DatatypeReader::GetTypename() const +{ + return set->GetVal(wxT("typname")); +} + + +wxString DatatypeReader::GetSchema() const +{ + return set->GetVal(wxT("nspname")); +} + + +wxString DatatypeReader::GetSchemaPrefix() const +{ + if (set->GetBool(wxT("isdup"))) + return set->GetVal(wxT("nspname")) + wxT("."); + else + return database->GetSchemaPrefix(set->GetVal(wxT("nspname"))); +} + + +wxString DatatypeReader::GetQuotedSchemaPrefix() const +{ + if (set->GetBool(wxT("isdup"))) + return qtIdent(set->GetVal(wxT("nspname"))) + wxT("."); + else + return database->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))); +} + + +wxString DatatypeReader::GetOidStr() const +{ + return set->GetVal(wxT("oid")); +} + + +OID DatatypeReader::GetOid() const +{ + return set->GetOid(wxT("oid")); +} diff --git a/schema/pgDomain.cpp b/schema/pgDomain.cpp new file mode 100644 index 0000000..2066b35 --- /dev/null +++ b/schema/pgDomain.cpp @@ -0,0 +1,425 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgDomain.cpp - Domain class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgDomain.h" +#include "schema/pgDatatype.h" + +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" +#include "schema/gpPartition.h" + + +pgDomain::pgDomain(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, domainFactory, newName) +{ +} + +pgDomain::~pgDomain() +{ +} + +wxString pgDomain::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on domain"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing domain"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop domain \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop domain \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop domain cascaded?"); + break; + case DROPTITLE: + message = _("Drop domain?"); + break; + case PROPERTIESREPORT: + message = _("Domain properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Domain properties"); + break; + case DDLREPORT: + message = _("Domain DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Domain DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Domain dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Domain dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Domain dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Domain dependents"); + break; + } + + return message; +} + + +bool pgDomain::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP DOMAIN ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgDomain::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Domain: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP DOMAIN ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE DOMAIN ") + GetQuotedFullIdentifier() + + wxT("\n AS ") + GetQuotedBasetype(); + if (GetCollationOid() > 0) + sql += wxT("\n COLLATE ") + GetQuotedCollation(); + AppendIfFilled(sql, wxT("\n DEFAULT "), GetDefault()); + // CONSTRAINT Name Dont know where it's stored, may be omitted anyway + if (notNull) + sql += wxT("\n NOT NULL"); + + // Get a count of the constraints. + int consCount = 0; + pgCollection *constraints = browser->FindCollection(checkFactory, GetId()); + if (constraints) + { + constraints->ShowTreeDetail(browser); + treeObjectIterator consIt(browser, constraints); + + pgObject *data; + + while ((data = consIt.GetNextObject()) != 0) + { + data->ShowTreeDetail(browser); + + sql += wxT("\n CONSTRAINT ") + data->GetQuotedIdentifier() + + wxT(" ") + data->GetTypeName().Upper() + + wxT(" ") ; + + switch (data->GetMetaType()) + { + case PGM_CHECK: + sql += wxT("(") + ((pgCheck *)data)->GetDefinition() + wxT(")"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && !((pgCheck *)data)->GetValid()) + sql += wxT(" NOT VALID"); + break; + } + } + } + + sql += wxT(";\n") + + GetOwnerSql(7, 4) + + GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + +wxMenu *pgDomain::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + checkFactory.AppendMenu(menu); + } + return menu; +} + + +void pgDomain::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to domain %s"), GetIdentifier().c_str()); + if (GetConnection()->BackendMinimumVersion(7, 4)) + browser->AppendCollection(this, constraintFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Base type"), GetBasetype()); + if (GetDimensions()) + properties->AppendItem(_("Dimensions"), GetDimensions()); + if (GetCollationOid() > 0) + properties->AppendItem(_("Collation"), GetQuotedCollation()); + properties->AppendItem(_("Default"), GetDefault()); + properties->AppendYesNoItem(_("Not NULL?"), GetNotNull()); + properties->AppendYesNoItem(_("System domain?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +pgObject *pgDomain::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *domain = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + domain = domainFactory.CreateObjects(coll, 0, wxT(" AND d.oid=") + GetOidStr() + wxT("\n")); + + return domain; +} + + +void pgDomain::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER DOMAIN ") + GetQuotedFullIdentifier() + + wxT("\n VALIDATE CONSTRAINT ") + GetCheckConstraintName(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + +//////////////////////////////////////////////////// + + + +pgObject *pgDomainFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgDomain *domain = 0; + + pgDatabase *db = collection->GetDatabase(); + + sql = wxT("SELECT d.oid, d.typname as domname, d.typbasetype, format_type(b.oid,NULL) as basetype, pg_get_userbyid(d.typowner) as domainowner, \n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + sql += wxT("c.oid AS colloid, c.collname, cn.nspname as collnspname, \n"); + sql += wxT(" d.typlen, d.typtypmod, d.typnotnull, d.typdefault, d.typndims, d.typdelim, bn.nspname as basensp,\n") + wxT(" description, (SELECT COUNT(1) FROM pg_type t2 WHERE t2.typname=d.typname) > 1 AS domisdup,\n") + wxT(" (SELECT COUNT(1) FROM pg_type t3 WHERE t3.typname=b.typname) > 1 AS baseisdup"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=d.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=d.oid) AS providers"); + } + sql += wxT("\n FROM pg_type d\n") + wxT(" JOIN pg_type b ON b.oid = d.typbasetype\n") + wxT(" JOIN pg_namespace bn ON bn.oid=b.typnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=d.oid AND des.classoid='pg_type'::regclass)\n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + sql += wxT(" LEFT OUTER JOIN pg_collation c ON d.typcollation=c.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cn ON c.collnamespace=cn.oid\n"); + sql += wxT(" WHERE d.typtype = 'd' AND d.typnamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + wxT("::oid\n") + + restriction + + wxT(" ORDER BY d.typname"); + pgSet *domains = db->ExecuteSet(sql); + + if (domains) + { + while (!domains->Eof()) + { + domain = new pgDomain(collection->GetSchema(), domains->GetVal(wxT("domname"))); + + domain->iSetOid(domains->GetOid(wxT("oid"))); + domain->iSetOwner(domains->GetVal(wxT("domainowner"))); + domain->iSetBasetype(domains->GetVal(wxT("basetype"))); + domain->iSetBasetypeOid(domains->GetOid(wxT("typbasetype"))); + domain->iSetComment(domains->GetVal(wxT("description"))); + long typmod = domains->GetLong(wxT("typtypmod")); + + pgDatatype dt(domains->GetVal(wxT("basensp")), domains->GetVal(wxT("basetype")), + domains->GetBool(wxT("baseisdup")), domains->GetLong(wxT("typndims")), typmod); + + domain->iSetTyplen(domains->GetLong(wxT("typlen"))); + domain->iSetTypmod(typmod); + domain->iSetLength(dt.Length()); + domain->iSetPrecision(dt.Precision()); + domain->iSetBasetype(dt.GetSchemaPrefix(db) + dt.FullName()); + domain->iSetQuotedBasetype(dt.GetQuotedSchemaPrefix(db) + dt.QuotedFullName()); + domain->iSetDefault(domains->GetVal(wxT("typdefault"))); + domain->iSetNotNull(domains->GetBool(wxT("typnotnull"))); + domain->iSetDimensions(domains->GetLong(wxT("typndims"))); + domain->iSetDelimiter(domains->GetVal(wxT("typdelim"))); + domain->iSetIsDup(domains->GetBool(wxT("domisdup"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + domain->iSetCollation(domains->GetVal(wxT("collname"))); + domain->iSetQuotedCollation(qtIdent(domains->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(domains->GetVal(wxT("collname")))); + domain->iSetCollationOid(domains->GetOid(wxT("colloid"))); + } + else + domain->iSetCollationOid(0); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + domain->iSetProviders(domains->GetVal(wxT("providers"))); + domain->iSetLabels(domains->GetVal(wxT("labels"))); + } + + // we suppose the constraint valid now + // this is checked in ShowTreeDetail for each domain + domain->iSetValid(true); + + if (browser) + { + browser->AppendObject(collection, domain); + domains->MoveNext(); + } + else + break; + } + + delete domains; + } + return domain; +} + +///////////////////////////// + +pgDomainCollection::pgDomainCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgDomainCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on domains"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing domains"); + break; + case OBJECTSLISTREPORT: + message = _("Domains list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/domain.pngc" +#include "images/domain-sm.pngc" +#include "images/domains.pngc" + +pgDomainFactory::pgDomainFactory() + : pgSchemaObjFactory(__("Domain"), __("New Domain..."), __("Create a new Domain."), domain_png_img, domain_sm_png_img) +{ + metaType = PGM_DOMAIN; +} + + +pgCollection *pgDomainFactory::CreateCollection(pgObject *obj) +{ + return new pgDomainCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgDomainFactory domainFactory; +static pgaCollectionFactory cf(&domainFactory, __("Domains"), domains_png_img); + +validateDomainCheckFactory::validateDomainCheckFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate domain check constraint"), _("Validate the selected domain check constraint.")); +} + + +wxWindow *validateDomainCheckFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgDomain *)obj)->Validate(form); + ((pgDomain *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgDomain *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateDomainCheckFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(domainFactory) && obj->CanEdit() + && ((pgDomain *)obj)->GetConnection()->BackendMinimumVersion(9, 2) + && !((pgDomain *)obj)->GetValid(); +} + diff --git a/schema/pgEventTrigger.cpp b/schema/pgEventTrigger.cpp new file mode 100644 index 0000000..c821a00 --- /dev/null +++ b/schema/pgEventTrigger.cpp @@ -0,0 +1,350 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgEventTrigger.cpp - EventTrigger class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgEventTrigger.h" +#include "schema/pgFunction.h" +#include "schema/pgSchema.h" + +pgEventTrigger::pgEventTrigger(const wxString &newName) + : pgDatabaseObject(eventTriggerFactory, newName) +{ + eventTriggerFunction = 0; + eventTriggerFunctionSchema = 0; +} + +pgEventTrigger::~pgEventTrigger() +{ + if (!expandedKids && eventTriggerFunction) + { + // eventTriggerFunction wasn't appended to tree, so we need to delete it manually. + delete eventTriggerFunction; + } + + delete eventTriggerFunctionSchema; +} + +pgCollection *pgEventTriggerFactory::CreateCollection(pgObject *obj) +{ + return new pgEventTriggerCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgObject *pgEventTriggerFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgEventTrigger *eventTrigger = 0; + + sql = wxT("SELECT e.oid, e.xmin, e.evtname AS name, REPLACE(e.evtevent, '_', ' ') AS eventname, pg_catalog.pg_get_userbyid(e.evtowner) AS eventowner, ") + wxT(" CASE e.evtenabled WHEN 'O' THEN 'enabled' WHEN 'R' THEN 'replica' WHEN 'A' THEN 'always' WHEN 'D' THEN 'disabled' END AS enabled, ") + wxT(" e.evtfoid AS eventfuncoid, e.evtfoid::regproc AS eventfunname, array_to_string(array(select quote_literal(x) from unnest(evttags) as t(x)), ', ') AS when, ") + wxT(" pg_catalog.obj_description(e.oid, 'pg_event_trigger') AS comment, ") + wxT(" p.prosrc AS source, p.pronamespace AS schemaoid, l.lanname AS language") + wxT(" FROM pg_event_trigger e\n") + wxT(" LEFT OUTER JOIN pg_proc p ON p.oid=e.evtfoid\n") + wxT(" LEFT OUTER JOIN pg_language l ON l.oid=p.prolang\n") + wxT(" WHERE 1=1 "); + + if (!restriction.IsEmpty()) + sql += restriction + wxT("\n"); + sql += wxT(" ORDER BY e.evtname "); + + pgSet *eventTriggers = collection->GetDatabase()->ExecuteSet(sql); + + if (eventTriggers) + { + while (!eventTriggers->Eof()) + { + eventTrigger = new pgEventTrigger(eventTriggers->GetVal(wxT("name"))); + eventTrigger->iSetDatabase(collection->GetDatabase()); + eventTrigger->iSetOid(eventTriggers->GetOid(wxT("oid"))); + eventTrigger->iSetXid(eventTriggers->GetOid(wxT("xmin"))); + eventTrigger->iSetOwner(eventTriggers->GetVal(wxT("eventowner"))); + eventTrigger->iSetFunctionOid(eventTriggers->GetOid(wxT("eventfuncoid"))); + eventTrigger->iSetLanguage(eventTriggers->GetVal(wxT("language"))); + eventTrigger->iSetSource(eventTriggers->GetVal(wxT("source"))); + eventTrigger->iSetEventName(eventTriggers->GetVal(wxT("eventname"))); + eventTrigger->iSetFunction(eventTriggers->GetVal(wxT("eventfunname"))); + (eventTriggers->GetVal(wxT("enabled")) == wxT("disabled")) ? eventTrigger->iSetEnabled(false), eventTrigger->iSetEnableStatus(wxT("disabled")) + : eventTrigger->iSetEnabled(true), eventTrigger->iSetEnableStatus(eventTriggers->GetVal(wxT("enabled"))); + eventTrigger->iSetComment(eventTriggers->GetVal(wxT("comment"))); + eventTrigger->iSetWhen(eventTriggers->GetVal(wxT("when"))); + eventTrigger->iSetSchemaOid(eventTriggers->GetOid(wxT("schemaoid"))); + + if (browser) + { + browser->AppendObject(collection, eventTrigger); + eventTriggers->MoveNext(); + } + else + break; + } + + delete eventTriggers; + } + return eventTrigger; +} + +pgObject *pgEventTrigger::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *eventTrigger = 0; + pgCollection *coll = browser->GetParentCollection(item); + + if (coll) + { + wxString restr = wxT(" \n AND e.oid = ") + GetOidStr(); + eventTrigger = eventTriggerFactory.CreateObjects(coll, 0, restr); + } + return eventTrigger; +} + +void pgEventTrigger::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids && GetLanguage() != wxT("edbspl") && GetLanguage() != wxT("sql")) + { + if (browser) + { + // if no browser present, function will not be appended to tree + expandedKids = true; + } + + if (eventTriggerFunction) + delete eventTriggerFunction; + + wxString restr = wxT(" WHERE nsp.oid= ") + NumToStr(GetSchemaOid()) + wxT("::oid\n"); + eventTriggerFunctionSchema = (pgSchema *)schemaFactory.CreateObjects((pgCollection *)browser->GetObject(GetId()), 0, restr); + + // append function here + eventTriggerFunction = functionFactory.AppendFunctions(this, eventTriggerFunctionSchema, browser, wxT(" WHERE pr.oid = ") + NumToStr(functionOid) + wxT("::oid\n")); + if (eventTriggerFunction) + { + iSetFunction(eventTriggerFunction->GetQuotedFullIdentifier()); + } + + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Event"), GetEventName()); + properties->AppendItem(_("Function"), GetFunction()); + properties->AppendItem(_("When?"), GetWhen()); + properties->AppendItem(_("Enabled?"), GetEnabled() ? wxT("Yes") : wxT("No")); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + +void pgEventTrigger::SetDirty() +{ + if (expandedKids) + eventTriggerFunction = 0; + pgObject::SetDirty(); +} + +wxString pgEventTrigger::GetSql(ctlTree *browser) +{ + if (sql.IsNull() && (this->eventTriggerFunction)) + { + sql = wxT("-- Event Trigger: ") + qtIdent(GetName()) + wxT(" on database ") + + qtIdent(((pgCollection *)browser->GetObject(GetId()))->GetDatabase()->GetName()) + wxT("\n\n") + + wxT("-- DROP EVENT TRIGGER ") + qtIdent(GetName()) + wxT(";\n\n"); + + sql += wxT("CREATE EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" ON ") + + GetEventName() + (GetWhen().IsEmpty() ? wxT("") : (wxT(" WHEN TAG IN (") + GetWhen() + wxT(")\n\n"))); + + // Event trigger backend function don't accept any arguments. + // Hence, it's not required to get/set empty arguments. + + sql += wxT(" EXECUTE PROCEDURE ") + eventTriggerFunction->GetQuotedFullIdentifier() + wxT("();\n\n"); + + if (!GetEnabled()) + { + sql += wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" DISABLE;\n"); + } + + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON EVENT TRIGGER ") + qtIdent(GetName()) + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + return sql; +} + +wxString pgEventTrigger::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on event trigger"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing event trigger"); + message += wxT(" ") + GetName(); + break; + case DROPCASCADETITLE: + message = _("Drop event trigger cascaded?"); + break; + case DROPTITLE: + message = _("Drop event trigger?"); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop event trigger \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop event trigger \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case PROPERTIESREPORT: + message = _("Event trigger properties report"); + message += wxT(" - ") + GetName(); + break; + case DDLREPORT: + message = _("Event trigger DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Event trigger DDL"); + break; + } + return message; +} + +int pgEventTrigger::GetIconId() +{ + if (GetEnabled()) + return eventTriggerFactory.GetIconId(); + else + return eventTriggerFactory.GetClosedIconId(); +} + + +wxString pgEventTriggerCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on event triggers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing event triggers"); + break; + case OBJECTSLISTREPORT: + message = _("Event triggers list report"); + break; + } + return message; +} + +bool pgEventTrigger::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP EVENT TRIGGER ") + qtIdent(GetName()); + if (cascaded) + sql += wxT(" CASCADE"); + sql += wxT(" ;"); + + return GetDatabase()->ExecuteVoid(sql); +} + +void pgEventTrigger::SetEnabled(ctlTree *browser, const bool b) +{ + if (qtIdent(GetName()).Len() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("ALTER EVENT TRIGGER ") + qtIdent(GetName()) ; + if (enabled && !b) + sql += wxT(" DISABLE"); + else if (!enabled && b) + sql += wxT(" ENABLE"); + GetDatabase()->ExecuteVoid(sql); + } + enabled = b; + UpdateIcon(browser); +} + +bool pgEventTrigger::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_event_trigger WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +///////////////////////////// + +pgEventTriggerCollection::pgEventTriggerCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ + +} + + +/////////////////////////////////////////////////// + +#include "images/trigger.pngc" +#include "images/triggerbad.pngc" +#include "images/triggers.pngc" + +pgEventTriggerFactory::pgEventTriggerFactory() + : pgDatabaseObjFactory(__("Event Trigger"), __("New Event Trigger..."), __("Create a new Event Trigger."), trigger_png_img) +{ + metaType = PGM_EVENTTRIGGER; + closedId = addIcon(triggerbad_png_img); +} + +pgEventTriggerFactory eventTriggerFactory; +static pgaCollectionFactory cf(&eventTriggerFactory, __("Event Triggers"), triggers_png_img); + +enabledisableEventTriggerFactory::enabledisableEventTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Event trigger enabled?"), _("Enable or disable selected event trigger."), wxITEM_CHECK); +} + +wxWindow *enabledisableEventTriggerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgEventTrigger *)obj)->SetEnabled(form->GetBrowser(), !((pgEventTrigger *)obj)->GetEnabled()); + ((pgEventTrigger *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + form->GetBrowser()->DeleteChildren(item); + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgEventTrigger *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + +bool enabledisableEventTriggerFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(eventTriggerFactory) && obj->CanEdit() + && ((pgEventTrigger *)obj)->GetConnection()->BackendMinimumVersion(9, 3); +} + +bool enabledisableEventTriggerFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(eventTriggerFactory) && ((pgEventTrigger *)obj)->GetEnabled(); +} \ No newline at end of file diff --git a/schema/pgExtension.cpp b/schema/pgExtension.cpp new file mode 100644 index 0000000..fd90b44 --- /dev/null +++ b/schema/pgExtension.cpp @@ -0,0 +1,234 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgExtension.cpp - Extension class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgExtension.h" + + +pgExtension::pgExtension(const wxString &newName) + : pgDatabaseObject(extensionFactory, newName) +{ +} + +wxString pgExtension::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on extension"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing extension"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop extension \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop extension \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop extension cascaded?"); + break; + case DROPTITLE: + message = _("Drop extension?"); + break; + case PROPERTIESREPORT: + message = _("Extension properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Extension properties"); + break; + case DDLREPORT: + message = _("Extension DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Extension DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Extension dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Extension dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Extension dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Extension dependents"); + break; + } + + return message; +} + +bool pgExtension::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP EXTENSION ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgExtension::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Extension: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP EXTENSION ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\n CREATE EXTENSION ") + GetName(); + + if (!GetSchemaStr().IsEmpty()) + sql += wxT("\n SCHEMA ") + qtIdent(GetSchemaStr()); + if (!GetVersion().IsEmpty()) + sql += wxT("\n VERSION ") + qtIdent(GetVersion()); + + sql += wxT(";\n"); + } + return sql; +} + + +void pgExtension::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Schema"), GetSchemaStr()); + properties->AppendYesNoItem(_("Relocatable?"), GetIsRelocatable()); + properties->AppendItem(_("Version"), GetVersion()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgExtension::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *language = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + language = extensionFactory.CreateObjects(coll, 0, wxT("\n AND x.oid=") + GetOidStr()); + + return language; +} + + + +pgObject *pgExtensionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgExtension *extension = 0; + + sql = wxT("select x.oid, pg_get_userbyid(extowner) AS owner, x.extname, n.nspname, x.extrelocatable, x.extversion, e.comment") + wxT(" FROM pg_extension x\n") + wxT(" JOIN pg_namespace n on x.extnamespace=n.oid\n") + wxT(" join pg_available_extensions() e(name, default_version, comment) ON x.extname=e.name\n") + + restriction + wxT("\n") + wxT(" ORDER BY x.extname"); + pgSet *extensions = collection->GetDatabase()->ExecuteSet(sql); + + if (extensions) + { + while (!extensions->Eof()) + { + + extension = new pgExtension(extensions->GetVal(wxT("extname"))); + extension->iSetDatabase(collection->GetDatabase()); + extension->iSetOid(extensions->GetOid(wxT("oid"))); + extension->iSetOwner(extensions->GetVal(wxT("owner"))); + extension->iSetSchemaStr(extensions->GetVal(wxT("nspname"))); + extension->iSetIsRelocatable(extensions->GetBool(wxT("extrelocatable"))); + extension->iSetVersion(extensions->GetVal(wxT("extversion"))); + extension->iSetComment(extensions->GetVal(wxT("comment"))); + + if (browser) + { + browser->AppendObject(collection, extension); + + extensions->MoveNext(); + } + else + break; + } + + delete extensions; + } + return extension; +} + + +///////////////////////////// + +pgExtensionCollection::pgExtensionCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgExtensionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on extensions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing extensions"); + break; + case OBJECTSLISTREPORT: + message = _("Extensions list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/extension.pngc" +#include "images/extension-sm.pngc" +#include "images/extensions.pngc" + +pgExtensionFactory::pgExtensionFactory() + : pgDatabaseObjFactory(__("Extension"), __("New Extension..."), __("Create a new Extension."), extension_png_img, extension_sm_png_img) +{ +} + + +pgCollection *pgExtensionFactory::CreateCollection(pgObject *obj) +{ + return new pgExtensionCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgExtensionFactory extensionFactory; +static pgaCollectionFactory cf(&extensionFactory, __("Extensions"), extensions_png_img); diff --git a/schema/pgForeignDataWrapper.cpp b/schema/pgForeignDataWrapper.cpp new file mode 100644 index 0000000..1d9e2e2 --- /dev/null +++ b/schema/pgForeignDataWrapper.cpp @@ -0,0 +1,408 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignDataWrapper.cpp - Foreign Data Wrapper class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgForeignServer.h" + + +pgForeignDataWrapper::pgForeignDataWrapper(const wxString &newName) + : pgDatabaseObject(foreignDataWrapperFactory, newName) +{ +} + + +wxString pgForeignDataWrapper::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign data wrapper"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign data wrapper"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign data wrapper \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign data wrapper \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign data wrapper cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign data wrapper?"); + break; + case PROPERTIESREPORT: + message = _("Foreign data wrapper properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign data wrapper properties"); + break; + case DDLREPORT: + message = _("Foreign data wrapper DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign data wrapper DDL"); + break; + case STATISTICSREPORT: + message = _("Foreign data wrapper statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Foreign data wrapper statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign data wrapper dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign data wrapper dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign data wrapper dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign data wrapper dependents"); + break; + } + + return message; +} + + +bool pgForeignDataWrapper::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignDataWrapper::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Data Wrapper: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + sql += wxT("FOREIGN DATA WRAPPER ") + GetName(); + + if (!GetHandlerProc().IsEmpty()) + sql += wxT("\n HANDLER ") + GetHandlerProc(); + + if (!GetValidatorProc().IsEmpty()) + sql += wxT("\n VALIDATOR ") + GetValidatorProc(); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(8, 4, wxT("FOREIGN DATA WRAPPER ") + GetName()) + + GetGrant(wxT("U"), wxT("FOREIGN DATA WRAPPER ") + GetQuotedFullIdentifier()); + } + return sql; +} + + +void pgForeignDataWrapper::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to foreign data wrapper %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("Foreign Servers"))) + browser->AppendCollection(this, foreignServerFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Handler"), GetHandlerProc()); + properties->AppendItem(_("Validator"), GetValidatorProc()); + properties->AppendItem(_("Options"), GetOptions()); + } +} + + + +pgObject *pgForeignDataWrapper::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *fdw = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + fdw = foreignDataWrapperFactory.CreateObjects(coll, 0, wxT("\n WHERE fdw.oid=") + GetOidStr()); + + return fdw; +} + + + +wxMenu *pgForeignDataWrapper::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (database->GetCreatePrivilege()) + { + foreignServerFactory.AppendMenu(menu); + } + return menu; +} + + +pgObject *pgForeignDataWrapperFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgForeignDataWrapper *fdw = 0; + + bool fdwHandlerSupport = (collection->GetDatabase()->BackendMinimumVersion(9, 1)); + + if(fdwHandlerSupport) + { + + sql = wxT("SELECT fdw.oid, fdwname, fdwhandler, fdwvalidator, fdwacl, ") + wxT("vh.proname as fdwhan, vp.proname as fdwval, description, ") + wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ") + wxT("pg_get_userbyid(fdwowner) as fdwowner\n"); + sql += wxT(" FROM pg_foreign_data_wrapper fdw\n") + wxT(" LEFT OUTER JOIN pg_proc vh on vh.oid=fdwhandler\n") + wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=fdw.oid AND des.objsubid=0 AND des.classoid='pg_foreign_data_wrapper'::regclass)\n") + + restriction + wxT("\n") + wxT(" ORDER BY fdwname"); + } + else + { + + sql = wxT("SELECT fdw.oid, fdwname, fdwvalidator, fdwacl, ") + wxT("vp.proname as fdwval, description, ") + wxT("array_to_string(fdwoptions, ',') AS fdwoptions, ") + wxT("pg_get_userbyid(fdwowner) as fdwowner\n"); + sql += wxT(" FROM pg_foreign_data_wrapper fdw\n") + wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=fdwvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=fdw.oid AND des.objsubid=0 AND des.classoid='pg_foreign_data_wrapper'::regclass)\n") + + restriction + wxT("\n") + wxT(" ORDER BY fdwname"); + } + pgSet *fdws = collection->GetDatabase()->ExecuteSet(sql); + + if (fdws) + { + while (!fdws->Eof()) + { + + fdw = new pgForeignDataWrapper(fdws->GetVal(wxT("fdwname"))); + fdw->iSetDatabase(collection->GetDatabase()); + fdw->iSetOid(fdws->GetOid(wxT("oid"))); + fdw->iSetOwner(fdws->GetVal(wxT("fdwowner"))); + fdw->iSetAcl(fdws->GetVal(wxT("fdwacl"))); + if(fdwHandlerSupport) + fdw->iSetHandlerProc(fdws->GetVal(wxT("fdwhan"))); + fdw->iSetValidatorProc(fdws->GetVal(wxT("fdwval"))); + fdw->iSetOptions(fdws->GetVal(wxT("fdwoptions"))); + + if (browser) + { + browser->AppendObject(collection, fdw); + + fdws->MoveNext(); + } + else + break; + } + + delete fdws; + } + return fdw; +} + + +wxString pgForeignDataWrapper::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +/////////////////////////////////////////////////////////////// + +void pgForeignDataWrapperObject::SetForeignDataWrapper(pgForeignDataWrapper *newForeignDataWrapper) +{ + fdw = newForeignDataWrapper; + database = fdw->GetDatabase(); +} + +bool pgForeignDataWrapperObject::CanDrop() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +bool pgForeignDataWrapperObject::CanCreate() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +void pgForeignDataWrapperObject::SetContextInfo(frmMain *form) +{ +} + + +pgSet *pgForeignDataWrapperObject::ExecuteSet(const wxString &sql) +{ + return fdw->GetDatabase()->ExecuteSet(sql); +} + +wxString pgForeignDataWrapperObject::ExecuteScalar(const wxString &sql) +{ + return fdw->GetDatabase()->ExecuteScalar(sql); +} + + +bool pgForeignDataWrapperObject::ExecuteVoid(const wxString &sql) +{ + return fdw->GetDatabase()->ExecuteVoid(sql); +} + + +///////////////////////////////////////////////////// + +pgForeignDataWrapperObjCollection::pgForeignDataWrapperObjCollection(pgaFactory *factory, pgForeignDataWrapper *newfdw) + : pgCollection(factory) +{ + fdw = newfdw; + database = fdw->GetDatabase(); + server = database->GetServer(); + iSetOid(fdw->GetOid()); +} + + +wxString pgForeignDataWrapperObjCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign data wrappers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign data wrappers"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign data wrappers list report"); + break; + } + + return message; +} + +bool pgForeignDataWrapperObjCollection::CanCreate() +{ + return GetDatabase()->GetCreatePrivilege(); +} + + +pgCollection *pgForeignDataWrapperObjFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignDataWrapperObjCollection(GetCollectionFactory(), (pgForeignDataWrapper *)obj); +} + + +///////////////////////////// + +pgForeignDataWrapperCollection::pgForeignDataWrapperCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgForeignDataWrapperCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign data wrappers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign data wrappers"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign data wrappers list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/foreigndatawrapper.pngc" +#include "images/foreigndatawrapper-sm.pngc" +#include "images/foreigndatawrappers.pngc" + +pgForeignDataWrapperFactory::pgForeignDataWrapperFactory() + : pgDatabaseObjFactory(__("Foreign Data Wrapper"), __("New Foreign Data Wrapper..."), __("Create a new Foreign Data Wrapper."), foreigndatawrapper_png_img, foreigndatawrapper_sm_png_img) +{ +} + + +pgCollection *pgForeignDataWrapperFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignDataWrapperCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgForeignDataWrapperFactory foreignDataWrapperFactory; +static pgaCollectionFactory cf(&foreignDataWrapperFactory, __("Foreign Data Wrappers"), foreigndatawrappers_png_img); diff --git a/schema/pgForeignKey.cpp b/schema/pgForeignKey.cpp new file mode 100644 index 0000000..135e7c9 --- /dev/null +++ b/schema/pgForeignKey.cpp @@ -0,0 +1,433 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignKey.cpp - ForeignKey class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "schema/pgForeignKey.h" +#include "schema/pgConstraints.h" + +pgForeignKey::pgForeignKey(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, foreignKeyFactory, newName) +{ +} + +pgForeignKey::~pgForeignKey() +{ +} + + +wxString pgForeignKey::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign key"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign key"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for foreign key"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign key \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign key \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign key cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign key?"); + break; + case PROPERTIESREPORT: + message = _("Foreign key properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign key properties"); + break; + case DDLREPORT: + message = _("Foreign key DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign key DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign key dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign key dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign key dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign key dependents"); + break; + } + + return message; +} + + +int pgForeignKey::GetIconId() +{ + if (!GetDatabase()->BackendMinimumVersion(9, 1) || GetValid()) + return foreignKeyFactory.GetIconId(); + else + return foreignKeyFactory.GetClosedIconId(); +} + + +bool pgForeignKey::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignKey::GetDefinition() +{ + wxString sql; + + sql = wxT("(") + GetQuotedFkColumns() + + wxT(")\n REFERENCES ") + GetQuotedSchemaPrefix(GetRefSchema()) + qtIdent(GetReferences()) + + wxT(" (") + GetQuotedRefColumns() + + wxT(")"); + + if (GetDatabase()->BackendMinimumVersion(7, 4) || GetMatch() == wxT("FULL")) + sql += wxT(" MATCH ") + GetMatch(); + + sql += wxT("\n ON UPDATE ") + GetOnUpdate() + + wxT(" ON DELETE ") + GetOnDelete(); + if (GetDeferrable()) + { + sql += wxT(" DEFERRABLE INITIALLY "); + if (GetDeferred()) + sql += wxT("DEFERRED"); + else + sql += wxT("IMMEDIATE"); + } + + if (GetDatabase()->BackendMinimumVersion(9, 1) && !GetValid()) + sql += wxT("\n NOT VALID"); + + return sql; +} + + +wxString pgForeignKey::GetConstraint() +{ + wxString sql; + sql = GetQuotedIdentifier() + + wxT(" FOREIGN KEY ") + GetDefinition(); + + return sql; +} + + +wxString pgForeignKey::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Key: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\nALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT("\n ADD CONSTRAINT ") + GetConstraint() + + wxT(";\n"); + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON CONSTRAINT ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +wxString pgForeignKey::GetFullName() +{ + return GetName() + wxT(" -> ") + GetReferences(); +} + +void pgForeignKey::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + wxTreeItemId id = browser->GetItemParent(GetId()); + pgTable *table = (pgTable *)browser->GetObject(id); + + wxStringTokenizer c1l(GetConkey(), wxT(",")); + wxStringTokenizer c2l(GetConfkey(), wxT(",")); + wxString c1, c2; + + // resolve column names + while (c1l.HasMoreTokens()) + { + c1 = c1l.GetNextToken(); + c2 = c2l.GetNextToken(); + pgSet *set = ExecuteSet( + wxT("SELECT a1.attname as conattname, a2.attname as confattname\n") + wxT(" FROM pg_attribute a1, pg_attribute a2\n") + wxT(" WHERE a1.attrelid=") + NumToStr(table->GetOid()) + wxT("::oid") + wxT(" AND a1.attnum=") + c1 + wxT("\n") + wxT(" AND a2.attrelid=") + GetRelTableOidStr() + wxT(" AND a2.attnum=") + c2); + if (set) + { + if (!fkColumns.IsNull()) + { + fkColumns += wxT(", "); + refColumns += wxT(", "); + quotedFkColumns += wxT(", "); + quotedRefColumns += wxT(", "); + } + fkColumns += set->GetVal(0); + refColumns += set->GetVal(1); + quotedFkColumns += qtIdent(set->GetVal(0)); + quotedRefColumns += qtIdent(set->GetVal(1)); + delete set; + } + } + wxTreeItemId item = browser->GetItemParent(GetId()); + while (item) + { + pgTable *table = (pgTable *)browser->GetObject(item); + if (table && table->IsCreatedBy(tableFactory)) + { + coveringIndex = table->GetCoveringIndex(browser, fkColumns); + break; + } + item = browser->GetItemParent(item); + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), NumToStr(GetOid())); + properties->AppendItem(_("Child columns"), GetFkColumns()); + properties->AppendItem(_("References"), GetReferences() + + wxT("(") + GetRefColumns() + wxT(")")); + + properties->AppendItem(_("Covering index"), GetCoveringIndex()); + properties->AppendItem(_("Match type"), GetMatch()); + properties->AppendItem(_("On update"), GetOnUpdate()); + properties->AppendItem(_("On delete"), GetOnDelete()); + properties->AppendItem(_("Deferrable?"), BoolToYesNo(GetDeferrable())); + if (GetDeferrable()) + properties->AppendItem(_("Initially?"), + GetDeferred() ? wxT("DEFERRED") : wxT("IMMEDIATE")); + if (GetDatabase()->BackendMinimumVersion(9, 1)) + properties->AppendItem(_("Valid?"), BoolToYesNo(GetValid())); + properties->AppendItem(_("System foreign key?"), BoolToYesNo(GetSystemObject())); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + +pgObject *pgForeignKey::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *foreignKey = 0; + + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + foreignKey = foreignKeyFactory.CreateObjects(coll, 0, wxT("\n AND ct.oid=") + GetOidStr()); + + return foreignKey; +} + + +void pgForeignKey::Validate(frmMain *form) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(fkSchema) + qtIdent(fkTable) + + wxT("\n VALIDATE CONSTRAINT ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + + iSetValid(true); + UpdateIcon(form->GetBrowser()); +} + + +pgObject *pgForeignKeyFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgTableObjCollection *collection = (pgTableObjCollection *)coll; + pgForeignKey *foreignKey = 0; + + sql = wxT("SELECT ct.oid, conname, condeferrable, condeferred, confupdtype, confdeltype, confmatchtype, ") + wxT("conkey, confkey, confrelid, nl.nspname as fknsp, cl.relname as fktab, ") + wxT("nr.nspname as refnsp, cr.relname as reftab, description"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + sql += wxT(", convalidated"); + sql += wxT("\n FROM pg_constraint ct\n") + wxT(" JOIN pg_class cl ON cl.oid=conrelid\n") + wxT(" JOIN pg_namespace nl ON nl.oid=cl.relnamespace\n") + wxT(" JOIN pg_class cr ON cr.oid=confrelid\n") + wxT(" JOIN pg_namespace nr ON nr.oid=cr.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=ct.oid AND des.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE contype='f' AND conrelid = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY conname"); + + pgSet *foreignKeys = collection->GetDatabase()->ExecuteSet(sql); + + if (foreignKeys) + { + while (!foreignKeys->Eof()) + { + foreignKey = new pgForeignKey(collection->GetSchema()->GetSchema(), foreignKeys->GetVal(wxT("conname"))); + + foreignKey->iSetOid(foreignKeys->GetOid(wxT("oid"))); + foreignKey->iSetRelTableOid(foreignKeys->GetOid(wxT("confrelid"))); + foreignKey->iSetFkSchema(foreignKeys->GetVal(wxT("fknsp"))); + foreignKey->iSetComment(foreignKeys->GetVal(wxT("description"))); + foreignKey->iSetFkTable(foreignKeys->GetVal(wxT("fktab"))); + foreignKey->iSetRefSchema(foreignKeys->GetVal(wxT("refnsp"))); + foreignKey->iSetReferences(foreignKeys->GetVal(wxT("reftab"))); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + foreignKey->iSetValid(foreignKeys->GetBool(wxT("convalidated"))); + wxString onUpd = foreignKeys->GetVal(wxT("confupdtype")); + wxString onDel = foreignKeys->GetVal(wxT("confdeltype")); + wxString match = foreignKeys->GetVal(wxT("confmatchtype")); + foreignKey->iSetOnUpdate( + onUpd.IsSameAs('a') ? wxT("NO ACTION") : + onUpd.IsSameAs('r') ? wxT("RESTRICT") : + onUpd.IsSameAs('c') ? wxT("CASCADE") : + onUpd.IsSameAs('d') ? wxT("SET DEFAULT") : + onUpd.IsSameAs('n') ? wxT("SET NULL") : wxT("Unknown")); + foreignKey->iSetOnDelete( + onDel.IsSameAs('a') ? wxT("NO ACTION") : + onDel.IsSameAs('r') ? wxT("RESTRICT") : + onDel.IsSameAs('c') ? wxT("CASCADE") : + onDel.IsSameAs('d') ? wxT("SET DEFAULT") : + onDel.IsSameAs('n') ? wxT("SET NULL") : wxT("Unknown")); + foreignKey->iSetMatch( + match.IsSameAs('f') ? wxT("FULL") : + match.IsSameAs('s') ? wxT("SIMPLE") : + match.IsSameAs('u') ? wxT("SIMPLE") : wxT("Unknown")); + + wxString cn = foreignKeys->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + foreignKey->iSetConkey(cn); + cn = foreignKeys->GetVal(wxT("confkey")); + cn = cn.Mid(1, cn.Length() - 2); + foreignKey->iSetConfkey(cn); + + foreignKey->iSetDeferrable(foreignKeys->GetBool(wxT("condeferrable"))); + foreignKey->iSetDeferred(foreignKeys->GetBool(wxT("condeferred"))); + + if (browser) + { + browser->AppendObject(collection, foreignKey); + foreignKeys->MoveNext(); + } + else + break; + } + + delete foreignKeys; + } + return foreignKey; +} + +///////////////////////////// + +wxString pgForeignKeyCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign keys"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign keys"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign keys list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/foreignkey.pngc" +#include "images/foreignkeybad.pngc" + + +pgForeignKeyFactory::pgForeignKeyFactory() + : pgSchemaObjFactory(__("Foreign Key"), __("New Foreign Key..."), __("Create a new Foreign Key constraint."), foreignkey_png_img) +{ + metaType = PGM_FOREIGNKEY; + collectionFactory = &constraintCollectionFactory; + closedId = addIcon(foreignkeybad_png_img); +} + + +pgForeignKeyFactory foreignKeyFactory; + +validateForeignKeyFactory::validateForeignKeyFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Validate foreign key"), _("Validate the selected foreign key.")); +} + + +wxWindow *validateForeignKeyFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgForeignKey *)obj)->Validate(form); + ((pgForeignKey *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgForeignKey *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool validateForeignKeyFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(foreignKeyFactory) && obj->CanEdit() + && ((pgForeignKey *)obj)->GetConnection()->BackendMinimumVersion(9, 1) + && !((pgForeignKey *)obj)->GetValid(); +} diff --git a/schema/pgForeignServer.cpp b/schema/pgForeignServer.cpp new file mode 100644 index 0000000..bbc8775 --- /dev/null +++ b/schema/pgForeignServer.cpp @@ -0,0 +1,351 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignServer.cpp - Foreign Server class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignServer.h" +#include "schema/pgUserMapping.h" +#include "schema/pgDatatype.h" + + +pgForeignServer::pgForeignServer(pgForeignDataWrapper *newForeignDataWrapper, const wxString &newName) + : pgForeignDataWrapperObject(newForeignDataWrapper, foreignServerFactory, newName) +{ +} + + +wxString pgForeignServer::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign server"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign server"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign server \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign server \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign server cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign server?"); + break; + case PROPERTIESREPORT: + message = _("Foreign server properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign server properties"); + break; + case DDLREPORT: + message = _("Foreign server DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign server DDL"); + break; + case STATISTICSREPORT: + message = _("Foreign server statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Foreign server statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign server dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign server dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign server dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign server dependents"); + break; + } + + return message; +} + + +bool pgForeignServer::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SERVER ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgForeignServer::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Server: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP SERVER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE SERVER ") + GetQuotedFullIdentifier() + + wxT("\n FOREIGN DATA WRAPPER ") + qtIdent(GetForeignDataWrapper()->GetName()); + + if (!GetType().IsEmpty()) + sql += wxT("\n TYPE ") + qtDbString(GetType()); + + if (!GetVersion().IsEmpty()) + sql += wxT("\n VERSION ") + qtDbString(GetVersion()); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(8, 4, wxT("SERVER ") + GetQuotedFullIdentifier()) + + GetGrant(wxT("U"), wxT("FOREIGN SERVER ") + GetQuotedFullIdentifier()); + } + return sql; +} + + +void pgForeignServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to foreign server %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("User Mappings"))) + browser->AppendCollection(this, userMappingFactory); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Type"), GetType()); + properties->AppendItem(_("Version"), GetVersion()); + properties->AppendItem(_("Options"), GetOptions()); + } +} + + + +pgObject *pgForeignServer::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *fs = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + fs = foreignServerFactory.CreateObjects(coll, 0, wxT(" AND srv.oid=") + GetOidStr()); + + return fs; +} + + +wxMenu *pgForeignServer::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (database->GetCreatePrivilege()) + { + userMappingFactory.AppendMenu(menu); + } + return menu; +} + + +//////////////////////////////////////////////////// + + +pgObject *pgForeignServerFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgForeignServer *fs = 0; + + sql = wxT("SELECT srv.oid, srvname, srvtype, srvversion, srvacl, fdw.fdwname as fdwname, description, ") + wxT("array_to_string(srvoptions, ',') AS srvoptions, ") + wxT("pg_get_userbyid(srvowner) as srvowner\n") + wxT(" FROM pg_foreign_server srv\n") + wxT(" LEFT OUTER JOIN pg_foreign_data_wrapper fdw on fdw.oid=srvfdw\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=srv.oid AND des.objsubid=0 AND des.classoid='pg_foreign_server'::regclass)\n") + wxT(" WHERE srvfdw = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY srvname"); + pgSet *foreignservers = collection->GetDatabase()->ExecuteSet(sql); + if (foreignservers) + { + while (!foreignservers->Eof()) + { + fs = new pgForeignServer(collection->GetForeignDataWrapper(), foreignservers->GetVal(wxT("srvname"))); + fs->iSetOid(foreignservers->GetOid(wxT("oid"))); + fs->iSetOwner(foreignservers->GetVal(wxT("srvowner"))); + fs->iSetAcl(foreignservers->GetVal(wxT("srvacl"))); + fs->iSetComment(foreignservers->GetVal(wxT("description"))); + fs->iSetType(foreignservers->GetVal(wxT("srvtype"))); + fs->iSetVersion(foreignservers->GetVal(wxT("srvversion"))); + fs->iSetOptions(foreignservers->GetVal(wxT("srvoptions"))); + + if (browser) + { + browser->AppendObject(collection, fs); + foreignservers->MoveNext(); + } + else + break; + } + + delete foreignservers; + } + + return fs; +} + + +wxString pgForeignServer::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +///////////////////////////// + +pgForeignServerObjCollection::pgForeignServerObjCollection(pgaFactory *factory, pgForeignServer *newsrv) + : pgCollection(factory) +{ + fsrv = newsrv; + fdw = fsrv->GetForeignDataWrapper(); + database = fdw->GetDatabase(); + server = database->GetServer(); + iSetOid(fsrv->GetOid()); +} + + +wxString pgForeignServerObjCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign servers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign servers"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign servers list report"); + break; + } + + return message; +} + +pgCollection *pgForeignServerObjFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignServerObjCollection(GetCollectionFactory(), (pgForeignServer *)obj); +} + + +/////////////////////////////////////////////////////////////// + +void pgForeignServerObject::SetForeignServer(pgForeignServer *newForeignServer) +{ + srv = newForeignServer; + database = fdw->GetDatabase(); +} + +bool pgForeignServerObject::CanDrop() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +bool pgForeignServerObject::CanCreate() +{ + return true; //fdw->GetCreatePrivilege(); +} + + +void pgForeignServerObject::SetContextInfo(frmMain *form) +{ +} + + +pgSet *pgForeignServerObject::ExecuteSet(const wxString &sql) +{ + return srv->GetDatabase()->ExecuteSet(sql); +} + +wxString pgForeignServerObject::ExecuteScalar(const wxString &sql) +{ + return srv->GetDatabase()->ExecuteScalar(sql); +} + + +bool pgForeignServerObject::ExecuteVoid(const wxString &sql) +{ + return srv->GetDatabase()->ExecuteVoid(sql); +} + + +/////////////////////////////////////////////////// + +#include "images/foreignserver.pngc" +#include "images/foreignserver-sm.pngc" +#include "images/foreignservers.pngc" + +pgForeignServerFactory::pgForeignServerFactory() + : pgForeignDataWrapperObjFactory(__("Foreign Server"), __("New Foreign Server..."), + __("Create a new Foreign Server."), foreignserver_png_img, foreignserver_sm_png_img) +{ +} + + +pgForeignServerFactory foreignServerFactory; +static pgaCollectionFactory cf(&foreignServerFactory, __("Foreign Servers"), foreignservers_png_img); diff --git a/schema/pgForeignTable.cpp b/schema/pgForeignTable.cpp new file mode 100644 index 0000000..259878b --- /dev/null +++ b/schema/pgForeignTable.cpp @@ -0,0 +1,415 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgForeignTable.cpp - Foreign Table class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignTable.h" +#include "schema/pgDatatype.h" + + +pgForeignTable::pgForeignTable(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, foreignTableFactory, newName) +{ +} + +pgForeignTable::~pgForeignTable() +{ +} + +wxString pgForeignTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop foreign table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop foreign table cascaded?"); + break; + case DROPTITLE: + message = _("Drop foreign table?"); + break; + case PROPERTIESREPORT: + message = _("Foreign table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Foreign table properties"); + break; + case DDLREPORT: + message = _("Foreign table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Foreign table DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Foreign table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Foreign table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Foreign table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Foreign table dependents"); + break; + } + + return message; +} + + +bool pgForeignTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FOREIGN TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgForeignTable::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Foreign Table: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP FOREIGN TABLE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE FOREIGN TABLE ") + GetQuotedFullIdentifier() + + wxT("\n (") + GetQuotedTypesList() + + wxT(")\n SERVER ") + GetForeignServer(); + + if (!GetOptionsList().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetOptionsList() + wxT(")"); + + sql += wxT(";\n") + + GetOwnerSql(9, 1) + + GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + + +void pgForeignTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + wxString constraint; + + if (!expandedKids) + { + expandedKids = true; + pgSet *set = ExecuteSet( + wxT("SELECT attname, format_type(t.oid,NULL) AS typname, attndims, atttypmod, nspname, attnotnull,\n") + wxT(" (SELECT COUNT(1) from pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup\n") + wxT(" FROM pg_attribute att\n") + wxT(" JOIN pg_type t ON t.oid=atttypid\n") + wxT(" JOIN pg_namespace nsp ON t.typnamespace=nsp.oid\n") + wxT(" LEFT OUTER JOIN pg_type b ON t.typelem=b.oid\n") + wxT(" WHERE att.attrelid=") + GetOidStr() + wxT("\n") + wxT(" AND attnum>0\n") + wxT(" ORDER by attnum")); + if (set) + { + int anzvar = 0; + while (!set->Eof()) + { + pgDatatype dt(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")), + set->GetBool(wxT("isdup")), set->GetLong(wxT("attndims")) > 0, set->GetLong(wxT("atttypmod"))); + constraint = set->GetBool(wxT("attnotnull")) ? wxT("NOT NULL") : wxT(""); + + if (anzvar++) + { + typesList += wxT(", "); + quotedTypesList += wxT(",\n "); + } + + typesList += set->GetVal(wxT("attname")) + wxT(" ") + + dt.GetSchemaPrefix(GetDatabase()) + dt.FullName() + wxT(" ") + + constraint; + + quotedTypesList += qtIdent(set->GetVal(wxT("attname"))) + wxT(" ") + + dt.GetQuotedSchemaPrefix(GetDatabase()) + dt.QuotedFullName() + wxT(" ") + + constraint; + + typesArray.Add(set->GetVal(wxT("attname"))); + typesArray.Add(dt.GetSchemaPrefix(GetDatabase()) + dt.FullName()); + typesArray.Add(constraint); + + set->MoveNext(); + } + delete set; + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Server"), GetForeignServer()); + properties->AppendItem(_("Columns"), GetQuotedTypesList()); + properties->AppendItem(_("Options"), GetOptionsList()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + +wxString pgForeignTable::GetSelectSql(ctlTree *browser) +{ + + wxString columns = wxEmptyString; + wxArrayString elements = GetTypesArray(); + size_t i; + for (i = 0 ; i < elements.GetCount() ; i += 3) + { + if (!columns.IsEmpty()) + columns += wxT(", "); + columns += qtIdent(elements.Item(i)); + } + + wxString sql = + wxT("SELECT ") + columns + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +pgObject *pgForeignTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *ft = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + ft = foreignTableFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + + return ft; +} + + +void pgForeignTable::iSetOptions(const wxString &tmpoptions) +{ + wxString tmp; + wxString option; + wxString value; + wxString currentChar; + bool wrappedInQuotes = false, antislash = false; + + options = wxEmptyString; + + if (tmpoptions == wxEmptyString) + return; + + // parse the options string + // we start at 1 and stop at length-1 to get rid of the { and } of the array + for (unsigned int index = 1 ; index < tmpoptions.Length() - 1 ; index++) + { + // get current char + currentChar = tmpoptions.Mid(index, 1); + + // if there is a double quote at the beginning of an option, + // the whole option=value will be wrapped in quotes + if (currentChar == wxT("\"") && tmp.IsEmpty()) + wrappedInQuotes = true; + else if (currentChar == wxT("\\") && wrappedInQuotes) + antislash = true; + else + { + if ((currentChar == wxT(",") && !wrappedInQuotes && !tmp.IsEmpty()) + || (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty())) + { + // new options + + if (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty()) + { + // In this specific case, the next character is the comma, + // but we don't want to start the next option with the comma + // so we skip it right now + index++; + } + + // we need to grab option and value from tmp string + option = tmp.BeforeFirst('='); + value = tmp.AfterFirst('='); + + // put them in the array + optionsArray.Add(option); + optionsArray.Add(value); + + // build the options string + if (options.Length() > 0) + options += wxT(", "); + options += option + wxT(" '") + value + wxT("'"); + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + } + else + tmp += currentChar; + antislash = false; + } + } + + // last options + + if (!tmp.IsEmpty()) + { + // we need to grab option and value from tmp string + option = tmp.BeforeFirst('='); + value = tmp.AfterFirst('='); + + // put them in the array + optionsArray.Add(option); + optionsArray.Add(value); + + // build the options string + if (options.Length() > 0) + options += wxT(", "); + options += option + wxT(" '") + value + wxT("'"); + } +} + + +///////////////////////////////////////////////////////// + + +pgForeignTableCollection::pgForeignTableCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgForeignTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on foreign tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing foreign tables"); + break; + case OBJECTSLISTREPORT: + message = _("Foreign tables list report"); + break; + } + + return message; +} + + +///////////////////////////////////////////////////////// + + +pgObject *pgForeignTableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgForeignTable *foreigntable = 0; + + wxString sql = wxT("SELECT c.oid AS ftoid, c.relname AS ftrelname, pg_get_userbyid(relowner) AS ftowner,\n") + wxT(" ftoptions, srvname AS ftsrvname, description,\n") + wxT(" (SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=c.oid) AS labels,\n") + wxT(" (SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=c.oid) AS providers\n") + wxT(" FROM pg_class c\n") + wxT(" JOIN pg_foreign_table ft ON c.oid=ft.ftrelid\n") + wxT(" LEFT OUTER JOIN pg_foreign_server fs ON ft.ftserver=fs.oid\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid AND des.classoid='pg_class'::regclass AND des.objsubid=0)\n") + wxT(" WHERE c.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY c.relname"); + + pgSet *foreigntables = collection->GetDatabase()->ExecuteSet(sql); + + if (foreigntables) + { + while (!foreigntables->Eof()) + { + foreigntable = new pgForeignTable(collection->GetSchema(), foreigntables->GetVal(wxT("ftrelname"))); + + foreigntable->iSetOid(foreigntables->GetOid(wxT("ftoid"))); + foreigntable->iSetOwner(foreigntables->GetVal(wxT("ftowner"))); + foreigntable->iSetForeignServer(foreigntables->GetVal(wxT("ftsrvname"))); + foreigntable->iSetOptions(foreigntables->GetVal(wxT("ftoptions"))); + foreigntable->iSetComment(foreigntables->GetVal(wxT("description"))); + foreigntable->iSetProviders(foreigntables->GetVal(wxT("providers"))); + foreigntable->iSetLabels(foreigntables->GetVal(wxT("labels"))); + + if (browser) + { + browser->AppendObject(collection, foreigntable); + foreigntables->MoveNext(); + } + else + break; + } + + delete foreigntables; + } + return foreigntable; +} + + +#include "images/foreigntable.pngc" +#include "images/foreigntables.pngc" + +pgForeignTableFactory::pgForeignTableFactory() + : pgSchemaObjFactory(__("Foreign Table"), __("New Foreign Table..."), __("Create a new Foreign Table."), foreigntable_png_img) +{ + metaType = PGM_FOREIGNTABLE; +} + + +pgCollection *pgForeignTableFactory::CreateCollection(pgObject *obj) +{ + return new pgForeignTableCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgForeignTableFactory foreignTableFactory; +static pgaCollectionFactory cf(&foreignTableFactory, __("Foreign Tables"), foreigntables_png_img); diff --git a/schema/pgFunction.cpp b/schema/pgFunction.cpp new file mode 100644 index 0000000..80b503e --- /dev/null +++ b/schema/pgFunction.cpp @@ -0,0 +1,1334 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgFunction.cpp - function class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/menu.h" +#include "utils/pgfeatures.h" +#include "utils/misc.h" +#include "schema/pgFunction.h" +#include "frm/frmMain.h" +#include "frm/frmReport.h" +#include "frm/frmHint.h" + +pgFunction::pgFunction(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, functionFactory, newName) +{ +} + + +pgFunction::pgFunction(pgSchema *newSchema, pgaFactory &factory, const wxString &newName) + : pgSchemaObject(newSchema, factory, newName) +{ +} + + +pgTriggerFunction::pgTriggerFunction(pgSchema *newSchema, const wxString &newName) + : pgFunction(newSchema, triggerFunctionFactory, newName) +{ +} + +pgProcedure::pgProcedure(pgSchema *newSchema, const wxString &newName) + : pgFunction(newSchema, procedureFactory, newName) +{ +} + +wxString pgFunction::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on function"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing function"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop function \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop function \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop function cascaded?"); + break; + case DROPTITLE: + message = _("Drop function?"); + break; + case PROPERTIESREPORT: + message = _("Function properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Function properties"); + break; + case DDLREPORT: + message = _("Function DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Function DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Function dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Function dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Function dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Function dependents"); + break; + } + + return message; +} + +wxString pgTriggerFunction::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on trigger function"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing trigger function"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger function \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger function \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop trigger function cascaded?"); + break; + case DROPTITLE: + message = _("Drop trigger function?"); + break; + case PROPERTIESREPORT: + message = _("Trigger function properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Trigger function properties"); + break; + case DDLREPORT: + message = _("Trigger function DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Trigger function DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Trigger function dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Trigger function dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Trigger function dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Trigger function dependents"); + break; + } + + return message; +} + +wxString pgProcedure::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on procedure"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing procedure"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop procedure \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop procedure \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop procedure cascaded?"); + break; + case DROPTITLE: + message = _("Drop procedure?"); + break; + case PROPERTIESREPORT: + message = _("Procedure properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Procedure properties"); + break; + case DDLREPORT: + message = _("Procedure DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Procedure DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Procedure dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Procedure dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Procedure dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Procedure dependents"); + break; + } + + return message; +} + +void pgFunction::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + wxString sql = wxT("SELECT calls AS ") + qtIdent(_("Number of calls")) + + wxT(", total_time AS ") + qtIdent(_("Total Time")) + + wxT(", self_time AS ") + qtIdent(_("Self Time")) + + wxT(" FROM pg_stat_user_functions") + + wxT(" WHERE funcid = ") + NumToStr(GetOid()); + DisplayStatistics(statistics, sql); + } +} + +bool pgFunction::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_proc WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool pgFunction::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP FUNCTION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT("(") + GetArgSigList() + wxT(")"); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +bool pgFunction::ResetStats() +{ + wxString sql = wxT("SELECT pg_stat_reset_single_function_counters(") + + NumToStr(this->GetOid()) + + wxT(")"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgFunction::GetFullName() +{ + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + +wxString pgProcedure::GetFullName() +{ + if (GetArgSigList().IsEmpty()) + return GetName(); + else + return GetName() + wxT("(") + GetArgSigList() + wxT(")"); +} + + +wxString pgFunction::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + wxString qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames(true) + wxT(")"); + wxString qtSig = GetQuotedFullIdentifier() + wxT("(") + GetArgSigList() + wxT(")"); + + sql = wxT("-- Function: ") + qtSig + wxT("\n\n") + + wxT("-- DROP FUNCTION ") + qtSig + wxT(";") + + wxT("\n\nCREATE OR REPLACE FUNCTION ") + qtName; + + // Use Oracle style syntax for edb-spl functions + if (GetLanguage() == wxT("edbspl") && GetProcType() == 2) + { + sql += wxT("\nRETURN "); + sql += GetReturnType(); + + sql += wxT(" AS"); + if (GetSource().StartsWith(wxT("\n"))) + sql += GetSource(); + else + sql += wxT("\n") + GetSource(); + } + else + { + sql += wxT("\n RETURNS "); + sql += GetReturnType(); + + sql += wxT(" AS\n"); + + if (GetLanguage().IsSameAs(wxT("C"), false)) + { + sql += qtDbString(GetBin()) + wxT(", ") + qtDbString(GetSource()); + } + else + { + if (GetConnection()->BackendMinimumVersion(7, 5)) + sql += qtDbStringDollar(GetSource()); + else + sql += qtDbString(GetSource()); + } + sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT(" "); + if (GetConnection()->BackendMinimumVersion(8, 4) && GetIsWindow()) + sql += wxT("WINDOW "); + sql += GetVolatility(); + if (GetConnection()->BackendMinimumVersion(9, 2) && GetIsLeakProof()) + sql += wxT(" LEAKPROOF"); + if (GetIsStrict()) + sql += wxT(" STRICT"); + if (GetSecureDefiner()) + sql += wxT(" SECURITY DEFINER"); + sql += wxT("\nPARALLEL ")+GetParallel(); + + // PostgreSQL 8.3+ cost/row estimations + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + sql += wxT("\n COST ") + NumToStr(GetCost()); + + if (GetReturnAsSet()) + sql += wxT("\n ROWS ") + NumToStr(GetRows()); + } + } + + if (!sql.Strip(wxString::both).EndsWith(wxT(";"))) + sql += wxT(";"); + + size_t i; + for (i = 0 ; i < configList.GetCount() ; i++) + { + if (configList.Item(i).BeforeFirst('=') != wxT("search_path") && + configList.Item(i).BeforeFirst('=') != wxT("temp_tablespaces")) + sql += wxT("\nALTER FUNCTION ") + qtSig + + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("='") + configList.Item(i).AfterFirst('=') + wxT("';\n"); + else + sql += wxT("\nALTER FUNCTION ") + qtSig + + wxT(" SET ") + configList.Item(i).BeforeFirst('=') + wxT("=") + configList.Item(i).AfterFirst('=') + wxT(";\n"); + } + + sql += wxT("\n") + + GetOwnerSql(8, 0, wxT("FUNCTION ") + qtSig) + + GetGrant(wxT("X"), wxT("FUNCTION ") + qtSig); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON FUNCTION ") + qtSig + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + +void pgFunction::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Argument count"), GetArgCount()); + properties->AppendItem(_("Arguments"), GetArgListWithNames()); + properties->AppendItem(_("Signature arguments"), GetArgSigList()); + if (!GetIsProcedure()) + properties->AppendItem(_("Return type"), GetReturnType()); + properties->AppendItem(_("Language"), GetLanguage()); + if (!GetIsProcedure()) properties->AppendYesNoItem(_("Returns a set?"), GetReturnAsSet()); + if (GetLanguage().IsSameAs(wxT("C"), false)) + { + properties->AppendItem(_("Object file"), GetBin()); + properties->AppendItem(_("Link symbol"), GetSource()); + } + else + properties->AppendItem(_("Source"), firstLineOnly(GetSource())); + + if (GetConnection()->BackendMinimumVersion(8, 3)&&!GetIsProcedure()) + { + properties->AppendItem(_("Estimated cost"), GetCost()); + if (GetReturnAsSet()) + properties->AppendItem(_("Estimated rows"), GetRows()); + } + + if (!GetIsProcedure()) properties->AppendItem(_("Volatility"), GetVolatility()); + if (!GetIsProcedure()) properties->AppendItem(_("Parallel"), GetParallel()); + if (GetConnection()->BackendMinimumVersion(9, 2)&&(!GetIsProcedure())) + properties->AppendYesNoItem(_("Leak proof?"), GetIsLeakProof()); + properties->AppendYesNoItem(_("Security of definer?"), GetSecureDefiner()); + if (!GetIsProcedure()) properties->AppendYesNoItem(_("Strict?"), GetIsStrict()); + if (GetConnection()->BackendMinimumVersion(8, 4)&&!GetIsProcedure()) + properties->AppendYesNoItem(_("Window?"), GetIsWindow()); + + size_t i; + for (i = 0 ; i < configList.GetCount() ; i++) + { + wxString item = configList.Item(i); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("System function?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +void pgFunction::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + hints.Add(HINT_OBJECT_EDITING); + frmHint::ShowHint((wxWindow *)form, hints, GetFullIdentifier(), force); +} + +wxString pgProcedure::GetSql(ctlTree *browser) +{ + if (!GetConnection()->BackendMinimumVersion(11, 0)) + return pgFunction::GetSql(browser); + + if (sql.IsNull()) + { + wxString qtName, qtSig; + + if (GetArgListWithNames().IsEmpty()) + { + qtName = GetQuotedFullIdentifier()+wxT("()"); + qtSig = GetQuotedFullIdentifier()+wxT("()"); + } + else + { + qtName = GetQuotedFullIdentifier() + wxT("(") + GetArgListWithNames() + wxT(")"); + qtSig = GetQuotedFullIdentifier() + wxT("(") + GetArgSigList() + wxT(")"); + } + + sql = wxT("-- Procedure: ") + qtSig + wxT("\n\n") + + wxT("-- DROP PROCEDURE ") + qtSig + wxT(";") + + wxT("\n\nCREATE OR REPLACE PROCEDURE ") + qtName; + + sql += wxT("\n LANGUAGE ") + GetLanguage() + wxT("\n "); + sql += wxT(" AS "); + sql += qtDbStringDollar(GetSource()); + sql += wxT(";\n\n"); + + size_t i; + for (i = 0 ; i < pgFunction::GetConfigList().GetCount() ; i++) + { + if (pgFunction::GetConfigList().Item(i).BeforeFirst('=') != wxT("search_path") && + pgFunction::GetConfigList().Item(i).BeforeFirst('=') != wxT("temp_tablespaces")) + sql += wxT("\nALTER PROCEDURE ") + qtSig + + wxT(" SET ") + pgFunction::GetConfigList().Item(i).BeforeFirst('=') + wxT("='") + pgFunction::GetConfigList().Item(i).AfterFirst('=') + wxT("';\n"); + else + sql += wxT("\nALTER PROCEDURE ") + qtSig + + wxT(" SET ") + pgFunction::GetConfigList().Item(i).BeforeFirst('=') + wxT("=") + pgFunction::GetConfigList().Item(i).AfterFirst('=') + wxT(";\n"); + } + + + sql += wxT("\n") + + GetOwnerSql(11, 0, wxT("PROCEDURE ") + qtSig); + sql += GetGrant(wxT("X"), wxT("PROCEDURE ") + qtSig); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON PROCEDURE ") + GetQuotedFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + + return sql; +} + + +bool pgProcedure::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (!GetConnection()->BackendMinimumVersion(11, 0)) + return pgFunction::DropObject(frame, browser, cascaded); + + wxString sql = wxT("DROP PROCEDURE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgFunction::GetArgListWithNames(bool multiline) +{ + wxString args; + unsigned int nArgs = 0; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + /* + * All Table arguments lies at the end of the list + * Do not include them as the part of the argument list + */ + if (argModesArray.Item(i) == wxT("TABLE")) + break; + + nArgs++; + if (args.Length() > 0) + { + args += (multiline) ? wxT(",\n ") : wxT(", "); + } + + wxString arg; + + if (GetIsProcedure()) + { + if (!argModesArray.Item(i).IsEmpty()) + { + arg += qtIdent(argNamesArray.Item(i)); + } + else + { + if (!argNamesArray.Item(i).IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + arg += wxT(" ") + argModesArray.Item(i); + } + + if (!argModesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += argModesArray.Item(i); + else + arg += wxT(" ") + argModesArray.Item(i); + } + } + else + { + if (!argModesArray.Item(i).IsEmpty()) + arg += argModesArray.Item(i); + + if (!argNamesArray.Item(i).IsEmpty()) + { + if (arg.IsEmpty()) + arg += qtIdent(argNamesArray.Item(i)); + else + arg += wxT(" ") + qtIdent(argNamesArray.Item(i)); + } + } + + if (!arg.IsEmpty()) + arg += wxT(" ") + argTypesArray.Item(i); + else + arg += argTypesArray.Item(i); + + // Parameter default value + if (GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) + && !argDefsArray.IsEmpty()) + { + if ((argModesArray.Item(i).IsEmpty() || + argModesArray.Item(i) == wxT("IN") || + // 'edbspl' does not support default value with + // INOUT parameter + (argModesArray.Item(i) == wxT("INOUT") && + GetLanguage() != wxT("edbspl")) || + argModesArray.Item(i) == wxT("VARIADIC")) && + !argDefsArray.Item(i).IsEmpty() && + i < argDefsArray.Count()) + { + arg += wxT(" DEFAULT ") + argDefsArray.Item(i); + } + } + + args += arg; + } + + if (multiline && nArgs > 1) + { + args = wxT("\n ") + args; + } + + return args; +} + +// Return the signature arguments list. If forScript = true, we format the list +// appropriately for use in a SELECT script. +wxString pgFunction::GetArgSigList(const bool forScript) +{ + wxString args; + + for (unsigned int i = 0; i < argTypesArray.Count(); i++) + { + // OUT parameters are not considered part of the signature, except for EDB-SPL, + // although this is not true for EDB AS90 onwards.. + if (argModesArray.Item(i) != wxT("OUT") && argModesArray.Item(i) != wxT("TABLE")) + { + if (args.Length() > 0) + { + if (forScript) + args += wxT(",\n"); + else + args += wxT(", "); + } + + if (forScript) + args += wxT(" <") + argTypesArray.Item(i) + wxT(">"); + else + args += argTypesArray.Item(i); + } + else + { + if (GetLanguage() == wxT("edbspl") && argModesArray.Item(i) != wxT("TABLE") && + !this->GetConnection()->EdbMinimumVersion(9, 0)) + { + if (args.Length() > 0) + { + if (forScript) + args += wxT(",\n"); + else + args += wxT(", "); + } + + if (forScript) + args += wxT(" <") + argTypesArray.Item(i) + wxT(">"); + else + args += argTypesArray.Item(i); + } + } + } + return args; +} + +pgFunction *pgFunctionFactory::AppendFunctions(pgObject *obj, pgSchema *schema, ctlTree *browser, const wxString &restriction) +{ + // Caches + cacheMap typeCache, exprCache; + + pgFunction *function = 0; + wxString argNamesCol, argDefsCol, proConfigCol, proType, seclab; + if (obj->GetConnection()->BackendMinimumVersion(8, 0)) + argNamesCol = wxT("proargnames, "); + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && !obj->GetConnection()->BackendMinimumVersion(8, 4)) + argDefsCol = wxT("proargdefvals, COALESCE(substring(array_dims(proargdefvals), E'1:(.*)\\]')::integer, 0) AS pronargdefaults, "); + if (obj->GetConnection()->BackendMinimumVersion(8, 4)) + argDefsCol = wxT("pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals, pronargdefaults, "); + if (obj->GetConnection()->BackendMinimumVersion(8, 3)) + proConfigCol = wxT("proconfig, "); + if (obj->GetConnection()->EdbMinimumVersion(8, 1)) + proType = wxT("protype, "); + if (obj->GetConnection()->BackendMinimumVersion(9, 1)) + { + seclab = wxT(",\n") + wxT("(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=pr.oid) AS labels,\n") + wxT("(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=pr.oid) AS providers"); + } + + pgSet *functions; + if (obj->GetConnection()->GetIsGreenplum()) + { + // the Open Source version of Greenplum already has the pg_get_function_result() function, + // however the 4.3 stable release does not have this function + functions = obj->GetDatabase()->ExecuteSet( + wxT("SELECT pr.oid, pr.xmin, pr.*, format_type(TYP.oid, NULL) AS typname, typns.nspname AS typnsp, lanname, ") + + argNamesCol + argDefsCol + proConfigCol + proType + + wxT(" pg_get_userbyid(proowner) as funcowner, description") + seclab + wxT("\n") + wxT(" FROM pg_proc pr\n") + wxT(" JOIN pg_type typ ON typ.oid=prorettype\n") + wxT(" JOIN pg_namespace typns ON typns.oid=typ.typnamespace\n") + wxT(" JOIN pg_language lng ON lng.oid=prolang\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)\n") + + restriction + + wxT(" ORDER BY proname")); + } + else + { + // new code for !Greenplum + wxString sqlprokind; + if (obj->GetConnection()->BackendMinimumVersion(11, 0)) {sqlprokind= wxT(" prokind, "); + } else + { + sqlprokind= wxT("case when proisagg then 'a' when proiswindow then 'w' else 'f' end prokind, "); + } + functions = obj->GetDatabase()->ExecuteSet( + wxT("SELECT pr.oid, pr.xmin, pr.*,lanname, pg_get_function_result(pr.oid) AS typname, typns.nspname AS typnsp, ") +sqlprokind+ + argNamesCol + argDefsCol + proConfigCol + proType + + wxT(" pg_get_userbyid(proowner) as funcowner, description") + seclab + wxT("\n") + wxT(", CASE WHEN pr.proparallel = 'r' THEN 'RESTRICTED'") + wxT(" WHEN pr.proparallel = 's' THEN 'SAFE'\n") + wxT(" WHEN pr.proparallel = 'u' THEN 'UNSAFE'\n") + wxT(" END as \"parallel\"") + wxT(" FROM pg_proc pr\n") + wxT(" JOIN pg_type typ ON typ.oid=prorettype\n") + wxT(" JOIN pg_namespace typns ON typns.oid=typ.typnamespace\n") + wxT(" JOIN pg_language lng ON lng.oid=prolang\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass)\n") + + restriction + + wxT(" ORDER BY proname")); + } + + pgSet *types = obj->GetDatabase()->ExecuteSet(wxT( + "SELECT oid, format_type(oid, NULL) AS typname FROM pg_type")); + + if (types) + { + while(!types->Eof()) + { + typeCache[types->GetVal(wxT("oid"))] = types->GetVal(wxT("typname")); + types->MoveNext(); + } + } + + if (functions) + { + while (!functions->Eof()) + { + bool isProcedure = false; + wxString prokind = functions->GetVal(wxT("prokind")); + wxString lanname = functions->GetVal(wxT("lanname")); + wxString typname = functions->GetVal(wxT("typname")); + + // Is this an EDB Stored Procedure? + if (obj->GetConnection()->EdbMinimumVersion(8, 1)) + { + wxString protype = functions->GetVal(wxT("protype")); + if (protype == wxT("1")) + isProcedure = true; + } + else if (obj->GetConnection()->BackendMinimumVersion(11, 0) && + prokind == wxT("p") ) + isProcedure = true; + + // Create the new object + if (isProcedure) + function = new pgProcedure(schema, functions->GetVal(wxT("proname"))); + else if (typname == wxT("\"trigger\"") || typname == wxT("trigger") || typname == wxT("event_trigger") || typname == wxT("\"event_trigger\"")) + function = new pgTriggerFunction(schema, functions->GetVal(wxT("proname"))); + else + function = new pgFunction(schema, functions->GetVal(wxT("proname"))); + + // Tokenize the arguments + wxStringTokenizer argTypesTkz(wxEmptyString), argModesTkz(wxEmptyString); + wxString tmp; + + wxArrayString argNamesArray; + wxArrayString argDefValArray; + + // We always have types + argTypesTkz.SetString(functions->GetVal(wxT("proargtypes"))); + + // We only have names in 8.0+ + if (obj->GetConnection()->BackendMinimumVersion(8, 0)) + { + tmp = functions->GetVal(wxT("proargnames")); + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argNamesArray); + } + + // EDB 8.0 had modes in pg_proc.proargdirs + //if (!obj->GetConnection()->EdbMinimumVersion(8, 1) && isProcedure) + // argModesTkz.SetString(functions->GetVal(wxT("proargdirs"))); + + if (obj->GetConnection()->EdbMinimumVersion(8, 1)) + function->iSetProcType(functions->GetLong(wxT("protype"))); + + // EDB 8.1 and PostgreSQL 8.1 have modes in pg_proc.proargmodes + if (obj->GetConnection()->BackendMinimumVersion(8, 1)) + { + tmp = functions->GetVal(wxT("proallargtypes")); + if (!tmp.IsEmpty()) + argTypesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + + tmp = functions->GetVal(wxT("proargmodes")); + if (!tmp.IsEmpty()) + argModesTkz.SetString(tmp.Mid(1, tmp.Length() - 2), wxT(",")); + } + function->iSetIsWindow(false); + // EDB 8.3: Function defaults + if (obj->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && + !obj->GetConnection()->BackendMinimumVersion(8, 4)) + { + tmp = functions->GetVal(wxT("proargdefvals")); + if (!tmp.IsEmpty()) + getArrayFromCommaSeparatedList(tmp.Mid(1, tmp.Length() - 2), argDefValArray); + + function->iSetArgDefValCount(functions->GetLong(wxT("pronargdefaults"))); + } + + if (obj->GetConnection()->BackendMinimumVersion(8, 4)) + { + tmp = functions->GetVal(wxT("proargdefaultvals")); + getArrayFromCommaSeparatedList(tmp, argDefValArray); + + function->iSetArgDefValCount(functions->GetLong(wxT("pronargdefaults"))); + + // Check if it is a window function + if (obj->GetConnection()->BackendMinimumVersion(11, 0)) + { + if (prokind == wxT("w")) function->iSetIsWindow(true); + } + else function->iSetIsWindow(functions->GetBool(wxT("proiswindow"))); + + } + else + function->iSetIsWindow(false); + + // Now iterate the arguments and build the arrays + wxString type, name, mode; + size_t nArgsIN = 0; + size_t nArgNames = 0; + + while (argTypesTkz.HasMoreTokens()) + { + if (nArgNames < argNamesArray.GetCount()) + { + name = argNamesArray[nArgNames++]; + } + else + name = wxEmptyString; + if (!name.IsEmpty()) + { + // Now add the name, stripping the quotes and \" if + // necessary. + if (name[0] == '"') + name = name.Mid(1, name.Length() - 2); + name.Replace(wxT("\\\""), wxT("\"")); + + // In EDBAS 90, if an SPL-function has both an OUT-parameter + // and a return value (which is not possible on PostgreSQL otherwise), + // the return value is transformed into an extra OUT-parameter + // named "_retval_" + if (obj->GetConnection()->EdbMinimumVersion(9, 0)) + { + if (name == wxT("_retval_")) + { + type = argTypesTkz.GetNextToken(); + // this will be the return type for this object + function->iSetReturnType(typeCache[type]); + + // consume uniformly, mode will definitely be "OUT" + mode = argModesTkz.GetNextToken(); + + continue; + } + } + function->iAddArgName(name); + } + else + function->iAddArgName(wxEmptyString); + + // Add the arg type. This is a type oid, so + // look it up in the hashmap + type = argTypesTkz.GetNextToken(); + function->iAddArgType(typeCache[type]); + + // Now the mode + mode = argModesTkz.GetNextToken(); + if (!mode.IsEmpty()) + { + if (mode == wxT('o') || mode == wxT("2")) + mode = wxT("OUT"); + else if (mode == wxT("b") || mode == wxT("3")) + { + nArgsIN++; + if (isProcedure) + mode = wxT("INOUT"); + else + { + mode = wxT("INOUT"); + // 'edbspl' does not support default values for the + // INOUT parameters. + //if (prokind != wxT("p")) + } + } + else if (mode == wxT("v")) + { + mode = wxT("VARIADIC"); + nArgsIN++; + } + else if (mode == wxT("t")) + mode = wxT("TABLE"); + else + { + mode = wxT("IN"); + nArgsIN++; + } + + function->iAddArgMode(mode); + } + else + { + function->iAddArgMode(wxEmptyString); + nArgsIN++; + } + } + + function->iSetArgCount(functions->GetLong(wxT("pronargs"))); + + wxString strReturnTableArgs; + // Process default values + size_t currINindex = 0; + for (size_t index = 0; index < function->GetArgModesArray().Count(); index++) + { + wxString def = wxEmptyString; + if(function->GetArgModesArray()[index].IsEmpty() || + function->GetArgModesArray()[index] == wxT("IN") || + (function->GetArgModesArray()[index] == wxT("INOUT") && + prokind != wxT("p")) || + function->GetArgModesArray()[index] == wxT("VARIADIC")) + { + if (!argDefValArray.IsEmpty() && nArgsIN <= argDefValArray.GetCount()) + { + def = argDefValArray[currINindex++]; + + if (!def.IsEmpty() && def != wxT("-")) + { + // Only EDB 8.3 does not support get the default value + // using pg_get_expr directly + if (function->GetConnection()->HasFeature(FEATURE_FUNCTION_DEFAULTS) && + !function->GetConnection()->BackendMinimumVersion(8, 4)) + { + // Check the cache first - if we don't have a value, get it and cache for next time + wxString val = exprCache[def]; + + if (val == wxEmptyString) + { + val = obj->GetDatabase()->ExecuteScalar( + wxT("SELECT pg_get_expr('") + def.Mid(1, def.Length() - 2) + wxT("', 'pg_catalog.pg_class'::regclass)")); + exprCache[def] = val; + } + def = val; + } + } + else + { + def = wxEmptyString; + } + } + nArgsIN--; + } + else if(function->GetConnection()->BackendMinimumVersion(8, 4) && + function->GetArgModesArray()[index] == wxT("TABLE")) + { + if (strReturnTableArgs.Length() > 0) + strReturnTableArgs += wxT(", "); + wxString strName = function->GetArgNamesArray()[index]; + if (!strName.IsEmpty()) + strReturnTableArgs += qtIdent(strName) + wxT(" "); + strReturnTableArgs += function->GetArgTypesArray()[index]; + } + function->iAddArgDef(def); + } + + function->iSetOid(functions->GetOid(wxT("oid"))); + function->iSetXid(functions->GetOid(wxT("xmin"))); + + if (browser) + function->UpdateSchema(browser, functions->GetOid(wxT("pronamespace"))); + + function->iSetOwner(functions->GetVal(wxT("funcowner"))); + function->iSetAcl(functions->GetVal(wxT("proacl"))); + + // set the return type only if not already set.. + if (function->GetReturnType().IsEmpty()) + { + wxString strType = functions->GetVal(wxT("typname")); + if (strType.Lower() == wxT("record") && !strReturnTableArgs.IsEmpty()) + { + strType = wxT("TABLE(") + strReturnTableArgs + wxT(")"); + } + function->iSetReturnType(strType); + } + function->iSetComment(functions->GetVal(wxT("description"))); + + function->iSetLanguage(lanname); + function->iSetSecureDefiner(functions->GetBool(wxT("prosecdef"))); + function->iSetReturnAsSet(functions->GetBool(wxT("proretset"))); + function->iSetIsStrict(functions->GetBool(wxT("proisstrict"))); + function->iSetSource(functions->GetVal(wxT("prosrc"))); + function->iSetBin(functions->GetVal(wxT("probin"))); + + wxString vol = functions->GetVal(wxT("provolatile")); + function->iSetVolatility( + vol.IsSameAs(wxT("i")) ? wxT("IMMUTABLE") : + vol.IsSameAs(wxT("s")) ? wxT("STABLE") : + vol.IsSameAs(wxT("v")) ? wxT("VOLATILE") : wxT("unknown")); + function->iSetParallel(functions->GetVal(wxT("parallel"))); + + // PostgreSQL 8.3 cost/row estimations + if (obj->GetConnection()->BackendMinimumVersion(8, 3)) + { + function->iSetCost(functions->GetLong(wxT("procost"))); + function->iSetRows(functions->GetLong(wxT("prorows"))); + wxString cfg = functions->GetVal(wxT("proconfig")); + if (!cfg.IsEmpty()) + FillArray(function->GetConfigList(), cfg.Mid(1, cfg.Length() - 2)); + } + + if (obj->GetConnection()->BackendMinimumVersion(9, 1)) + { + function->iSetProviders(functions->GetVal(wxT("providers"))); + function->iSetLabels(functions->GetVal(wxT("labels"))); + } + + if (obj->GetConnection()->BackendMinimumVersion(9, 2)) + { + function->iSetIsLeakProof(functions->GetBool(wxT("proleakproof"))); + } + + if (browser) + { + browser->AppendObject(obj, function); + functions->MoveNext(); + } + else + break; + } + + delete functions; + delete types; + } + return function; +} + + + +pgObject *pgFunction::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *function = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + function = functionFactory.AppendFunctions(coll, GetSchema(), 0, wxT(" WHERE pr.oid=") + GetOidStr() + wxT("\n")); + + // We might be linked to trigger.... + pgObject *trigger = browser->GetParentObject(item); + if (trigger->GetMetaType() == PGM_TRIGGER || trigger->GetMetaType() == PGM_EVENTTRIGGER) + function = functionFactory.AppendFunctions(trigger, GetSchema(), 0, wxT(" WHERE pr.oid=") + GetOidStr() + wxT("\n")); + + return function; +} + +// Generate the SELECT Script SQL +wxString pgFunction::GetSelectSql(ctlTree *browser) +{ + wxString args = GetArgSigList(true); + + wxString sql = wxT("SELECT ") + GetQuotedFullIdentifier(); + + if (args.Length()) + sql += wxT("(\n") + args + wxT("\n);\n"); + else + sql += wxT("();\n"); + + return sql; +} + +// Generate the EXEC Script SQL +wxString pgProcedure::GetExecSql(ctlTree *browser) +{ + wxString args = GetArgSigList(true); + + wxString sql = wxT("CALL ") + GetQuotedFullIdentifier(); + + if (args.Length()) + sql += wxT("(\n") + args + wxT("\n);\n"); + else + sql += wxT(";\n"); + + return sql; +} + +pgObject *pgFunctionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restr) +{ + wxString sqlprokind; + if (collection->GetConnection()->BackendMinimumVersion(11, 0)) {sqlprokind= wxT("prokind <> 'p' "); + } else + { + sqlprokind= wxT("case when proisagg then 'a' when proiswindow then 'w' else 'f' end <>'p' "); + } + + wxString funcRestriction = wxT( + " WHERE ")+sqlprokind+wxT(" AND pronamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + + wxT("::oid\n AND typname NOT IN ('trigger', 'event_trigger') \n"); + + if (collection->GetConnection()->EdbMinimumVersion(8, 1)) + funcRestriction += wxT(" AND NOT (lanname = 'edbspl' AND protype = '1')\n"); + else if (collection->GetConnection()->EdbMinimumVersion(8, 0)) + funcRestriction += wxT(" AND NOT (lanname = 'edbspl' AND typname = 'void')\n"); + + // Get the Functions + return AppendFunctions(collection, collection->GetSchema(), browser, funcRestriction); +} + + +pgCollection *pgFunctionFactory::CreateCollection(pgObject *obj) +{ + return new pgFunctionCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgObject *pgTriggerFunctionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restr) +{ + wxString sqlprokind; + if (collection->GetConnection()->BackendMinimumVersion(11, 0)) {sqlprokind= wxT("prokind = 'f' "); + } else + { + sqlprokind= wxT("case when proisagg then 'a' when proiswindow then 'w' else 'f' end ='f' "); + } + + wxString funcRestriction = wxT( + " WHERE ")+sqlprokind+wxT(" AND pronamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + + wxT("::oid\n"); + if(collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + //funcRestriction += wxT("AND (typname IN ('trigger', 'event_trigger') \nAND lanname NOT IN ('edbspl', 'sql', 'internal'))"); + funcRestriction += wxT("AND (typname IN ('trigger', 'event_trigger') \n)"); + } + else + { + funcRestriction += wxT("AND (typname = 'trigger'\n AND lanname != 'edbspl')"); + } + + // Get the Functions + return AppendFunctions(collection, collection->GetSchema(), browser, funcRestriction); +} + + +pgObject *pgProcedureFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restr) +{ + wxString funcRestriction = wxT( + " WHERE prokind = 'p' AND pronamespace = ") + NumToStr(collection->GetSchema()->GetOid()) + + wxT("::oid\n"); + + //if (collection->GetConnection()->EdbMinimumVersion(8, 1)) + // funcRestriction += wxT(" AND protype = '1'\n"); + //else + // funcRestriction += wxT(" AND typname = 'void'\n"); + + // Get the Functions + return AppendFunctions(collection, collection->GetSchema(), browser, funcRestriction); +} + + +#include "images/function.pngc" +#include "images/functions.pngc" + +pgFunctionFactory::pgFunctionFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img) + : pgSchemaObjFactory(tn, ns, nls, img) +{ + metaType = PGM_FUNCTION; +} + +pgFunctionFactory functionFactory(__("Function"), __("New Function..."), __("Create a new Function."), function_png_img); +static pgaCollectionFactory cf(&functionFactory, __("Functions"), functions_png_img); + + +#include "images/triggerfunction.pngc" +#include "images/triggerfunctions.pngc" + +pgTriggerFunctionFactory::pgTriggerFunctionFactory() + : pgFunctionFactory(__("Trigger Function"), __("New Trigger Function..."), __("Create a new Trigger Function."), triggerfunction_png_img) +{ +} + +pgTriggerFunctionFactory triggerFunctionFactory; +static pgaCollectionFactory cft(&triggerFunctionFactory, __("Trigger Functions"), triggerfunctions_png_img); + +#include "images/procedure.pngc" +#include "images/procedures.pngc" + +pgProcedureFactory::pgProcedureFactory() + : pgFunctionFactory(__("Procedure"), __("New Procedure"), __("Create a new Procedure."), procedure_png_img) +{ +} + +pgProcedureFactory procedureFactory; +static pgaCollectionFactory cfp(&procedureFactory, __("Procedures"), procedures_png_img); + +pgFunctionCollection::pgFunctionCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + +wxString pgFunctionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on functions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing functions"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for functions"); + break; + case OBJECTSLISTREPORT: + message = _("Functions list report"); + break; + } + + return message; +} + +void pgFunctionCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + wxLogInfo(wxT("Displaying statistics for functions on ") + GetSchema()->GetName()); + + wxString sql = wxT("SELECT funcname, calls, total_time, self_time") + wxT(" FROM pg_stat_user_functions") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName()) + + wxT(" ORDER BY funcname"); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Function"), 60); + statistics->AddColumn(_("Calls"), 50); + statistics->AddColumn(_("Total Time"), 60); + statistics->AddColumn(_("Self Time"), 60); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("funcname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("calls"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("total_time"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("self_time"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } + } +} + + +resetFunctionStatsFactory::resetFunctionStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Reset function statistics"), _("Reset statistics of the selected function.")); +} + + +wxWindow *resetFunctionStatsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to reset statistics of this function?"), _("Reset function statistics"), wxYES_NO) != wxYES) + return 0; + + ((pgFunction *)obj)->ResetStats(); + ((pgFunction *)obj)->ShowStatistics(form, form->GetStatistics()); + + return 0; +} + + +bool resetFunctionStatsFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(functionFactory) && ((pgFunction *)obj)->GetConnection()->BackendMinimumVersion(9, 0); +} + +wxString pgTriggerFunctionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on trigger functions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing trigger functions"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for trigger functions"); + break; + case OBJECTSLISTREPORT: + message = _("Trigger functions list report"); + break; + } + + return message; +} + +wxString pgProcedureCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on procedures"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing procedures"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for procedures"); + break; + case OBJECTSLISTREPORT: + message = _("Procedures list report"); + break; + } + + return message; +} + + diff --git a/schema/pgGroup.cpp b/schema/pgGroup.cpp new file mode 100644 index 0000000..6bff23c --- /dev/null +++ b/schema/pgGroup.cpp @@ -0,0 +1,233 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgGroup.cpp - PostgreSQL group (only used on pre-8.1 versions, pgRole +// is used on newer versions). +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgGroup.h" + + +pgGroup::pgGroup(const wxString &newName) + : pgServerObject(groupFactory, newName) +{ + memberCount = 0; +} + +wxString pgGroup::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on group"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing group"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for group"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop group cascaded?"); + break; + case DROPTITLE: + message = _("Drop group?"); + break; + case PROPERTIESREPORT: + message = _("Group properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Group properties"); + break; + case DDLREPORT: + message = _("Group DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Group DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Group dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Group dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Group dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Group dependents"); + break; + } + + return message; +} + +bool pgGroup::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return server->ExecuteVoid(wxT("DROP GROUP ") + GetQuotedFullIdentifier()); +} + +wxString pgGroup::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Group: ") + GetName() + wxT("\n\n") + + wxT("DROP GROUP ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE Group ") + GetQuotedIdentifier() + + wxT("\n WITH SYSID ") + NumToStr(groupId) + + wxT("\n USER ") + quotedMembers + + wxT(";\n"); + } + return sql; +} + + +void pgGroup::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + if (!memberIds.IsEmpty()) + { + wxString ml = memberIds; + ml.Replace(wxT(" "), wxT(",")); + pgSet *set = server->ExecuteSet(wxT( + "SELECT usename FROM pg_user WHERE usesysid IN (") + ml + wxT(")")); + if (set) + { + while (!set->Eof()) + { + wxString user = set->GetVal(0); + if (memberCount) + { + members += wxT(", "); + quotedMembers += wxT(", "); + } + members += user; + quotedMembers += qtIdent(user); + memberCount++; + usersIn.Add(user); + set->MoveNext(); + } + delete set; + } + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Group ID"), GetGroupId()); + properties->AppendItem(_("Member count"), GetMemberCount()); + properties->AppendItem(_("Members"), GetMembers()); + } +} + + + +pgObject *pgGroup::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *group = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + group = groupFactory.CreateObjects(coll, 0, wxT("\n WHERE grosysid=") + NumToStr(GetGroupId())); + + return group; +} + + + +pgObject *pgGroupFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgGroup *group = 0; + + pgSet *groups = collection->GetServer()->ExecuteSet(wxT( + "SELECT * from pg_group") + restriction + wxT(" ORDER BY groname")); + + if (groups) + { + while (!groups->Eof()) + { + group = new pgGroup(groups->GetVal(wxT("groname"))); + group->iSetGroupId(groups->GetLong(wxT("grosysid"))); + group->iSetServer(collection->GetServer()); + wxString mids = groups->GetVal(wxT("grolist")); + mids = mids.Mid(1, mids.Length() - 2); + group->iSetMemberIds(mids); + + if (browser) + { + browser->AppendObject(collection, group); + groups->MoveNext(); + } + else + break; + } + + delete groups; + } + return group; +} + +wxString pgGroupCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on groups"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing groups"); + break; + case OBJECTSLISTREPORT: + message = _("Groups list report"); + break; + } + + return message; +} + +#include "images/group.pngc" +#include "images/groups.pngc" + +pgGroupFactory::pgGroupFactory() + : pgServerObjFactory(__("Group"), __("New Group..."), __("Create a new Group."), group_png_img) +{ +} + + +pgGroupFactory groupFactory; +static pgaCollectionFactory cf(&groupFactory, __("Groups"), groups_png_img); diff --git a/schema/pgIndex.cpp b/schema/pgIndex.cpp new file mode 100644 index 0000000..47538b2 --- /dev/null +++ b/schema/pgIndex.cpp @@ -0,0 +1,760 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndex.cpp - Index class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" +#include "schema/pgIndex.h" +#include "schema/pgConstraints.h" +#include "schema/pgIndexConstraint.h" + + +pgIndexBase::pgIndexBase(pgSchema *newSchema, pgaFactory &factory, const wxString &newName) + : pgSchemaObject(newSchema, factory, newName) +{ + showExtendedStatistics = false; +} + +wxString pgIndexBase::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on index"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing index"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for index"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop index cascaded?"); + break; + case DROPTITLE: + message = _("Drop index?"); + break; + case PROPERTIESREPORT: + message = _("Index properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Index properties"); + break; + case DDLREPORT: + message = _("Index DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Index DDL"); + break; + case STATISTICSREPORT: + message = _("Index statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Index statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Index dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Index dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Index dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Index dependents"); + break; + } + + return message; +} + +bool pgIndexBase::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP INDEX ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgIndexBase::GetCreate() +{ + wxString str; +// no functional indexes so far + + str = wxT("CREATE "); + if (GetIsUnique()) + str += wxT("UNIQUE "); + str += wxT("INDEX "); + str += qtIdent(GetName()) + + wxT("\n ON ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT("\n USING ") + GetIndexType() + + wxT("\n ("); + if (GetProcName().IsNull()) + str += GetQuotedColumns(); + else + { + str += GetQuotedSchemaPrefix(GetProcNamespace()) + qtIdent(GetProcName()) + wxT("(") + GetQuotedColumns() + wxT(")"); + if (!this->GetOperatorClasses().IsNull()) + str += wxT(" ") + GetOperatorClasses(); + } + + str += wxT(")"); + +// if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0) +// str += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")"); + if (GetConnection()->BackendMinimumVersion(8, 2) && GetRelOptions().Length() > 0) + str += wxT("\n WITH (") + GetRelOptions() + wxT(")"); + + + if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace()) + str += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + AppendIfFilled(str, wxT("\n WHERE "), GetConstraint()); + + str += wxT(";\n"); + + if (GetConnection()->BackendMinimumVersion(7, 5)) + if (GetIsClustered()) + str += wxT("ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT(" CLUSTER ON ") + qtIdent(GetName()) + + wxT(";\n"); + + return str; +} + + +wxString pgIndexBase::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Index: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP INDEX ") + GetQuotedFullIdentifier() + wxT(";\n\n") + + GetCreate() + + GetCommentSql(); + } + return sql; +} + + + +void pgIndexBase::ReadColumnDetails() +{ + if (!expandedKids) + { + expandedKids = true; + bool indexconstraint = GetMetaType() == PGM_PRIMARYKEY || GetMetaType() == PGM_UNIQUE || GetMetaType() == PGM_EXCLUDE; + + // Allocate memory to store column def + if (columnCount > 0) columnList.Alloc(columnCount); + + if (GetConnection()->BackendMinimumVersion(7, 4)) + { + long i; + + for (i = 1 ; i <= columnCount ; i++) + { + if (i > 1) + { + columns += wxT(", "); + quotedColumns += wxT(", "); + } + + wxString options, coldef, opcname; + if (GetConnection()->BackendMinimumVersion(8, 3)) + options = wxT(" i.indoption[") + NumToStr((long)(i - 1)) + wxT("] AS options,\n"); + + pgSet *res; + wxString query; + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + query = wxT("SELECT\n") + options + + wxT(" pg_get_indexdef(i.indexrelid, ") + NumToStr(i) + GetDatabase()->GetPrettyOption() + wxT(") AS coldef,\n") + + wxT(" op.oprname,\n") + + wxT(" CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(",\n coll.collname, nspc.nspname as collnspname\n"); + query += wxT("FROM pg_index i\n") + wxT("JOIN pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = ") + NumToStr(i) + wxT(")\n") + + wxT("LEFT OUTER JOIN pg_opclass o ON (o.oid = i.indclass[") + NumToStr((long)(i - 1)) + wxT("])\n") + + wxT("LEFT OUTER JOIN pg_constraint c ON (c.conindid = i.indexrelid) ") + wxT("LEFT OUTER JOIN pg_operator op ON (op.oid = c.conexclop[") + NumToStr(i) + wxT("])\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT("LEFT OUTER JOIN pg_collation coll ON a.attcollation=coll.oid\n") + wxT("LEFT OUTER JOIN pg_namespace nspc ON coll.collnamespace=nspc.oid\n"); + query += wxT("WHERE i.indexrelid = ") + GetOidStr(); + } + else + { + query = wxT("SELECT\n") + options + + wxT(" pg_get_indexdef(i.indexrelid, ") + NumToStr(i) + GetDatabase()->GetPrettyOption() + wxT(") AS coldef,\n") + + wxT(" CASE WHEN (o.opcdefault = FALSE) THEN o.opcname ELSE null END AS opcname\n") + + wxT("FROM pg_index i\n") + + wxT("JOIN pg_attribute a ON (a.attrelid = i.indexrelid AND attnum = ") + NumToStr(i) + wxT(")\n") + + wxT("LEFT OUTER JOIN pg_opclass o ON (o.oid = i.indclass[") + NumToStr((long)(i - 1)) + wxT("])\n") + + wxT("WHERE i.indexrelid = ") + GetOidStr(); + } + + res = ExecuteSet(query); + + if (res->NumRows() > 0) + { + coldef = res->GetVal(wxT("coldef")); + + if (GetConnection()->BackendMinimumVersion(9, 1) && !indexconstraint) + { + wxString collation = wxEmptyString; + if (!res->GetVal(wxT("collname")).IsEmpty()) + { + collation = qtIdent(res->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(res->GetVal(wxT("collname"))); + coldef += wxT(" COLLATE ") + collation; + } + collationsArray.Add(collation); + } + else + { + collationsArray.Add(wxEmptyString); + } + + opcname = res->GetVal(wxT("opcname")); + opclassesArray.Add(opcname); + if (!opcname.IsEmpty()) + coldef += wxT(" ") + opcname; + + // Get the column options + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + long opt = res->GetLong(wxT("options")); + + if (opt && (opt & 0x0001)) // Descending... + { + ordersArray.Add(wxT("DESC")); + coldef += wxT(" DESC"); + // NULLS FIRST is the default for descending + if (!(opt && (opt & 0x0002))) + { + nullsArray.Add(wxT("NULLS LAST")); + coldef += wxT(" NULLS LAST"); + } + else + { + nullsArray.Add(wxEmptyString); + } + } + else // Ascending... + { + ordersArray.Add(wxT("ASC")); + if ((opt && (opt & 0x0002))) + { + nullsArray.Add(wxT("NULLS FIRST")); + coldef += wxT(" NULLS FIRST"); + } + else + { + nullsArray.Add(wxEmptyString); + } + } + } + else + { + ordersArray.Add(wxEmptyString); + nullsArray.Add(wxEmptyString); + } + } + + if (isExclude) + { + coldef += wxT(" WITH ") + res->GetVal(wxT("oprname")); + } + columns += coldef; + quotedColumns += coldef; + columnList.Add(coldef); + + //resolve memory leak occurred while expanding the index node in object browser + delete res; + res = NULL; + } + } + else + { + // its a 7.3 db + + // We cannot use SELECT IN (colNumbers) here because we couldn't be sure + // about the read order + wxStringTokenizer collist(GetColumnNumbers()); + wxStringTokenizer args(procArgTypeList); + wxString cn, ct; + columnCount = 0; + + while (collist.HasMoreTokens()) + { + cn = collist.GetNextToken(); + ct = args.GetNextToken(); + + pgSet *colSet = ExecuteSet( + wxT("SELECT attname as conattname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum=") + cn); + if (colSet) + { + if (columnCount) + { + columns += wxT(", "); + quotedColumns += wxT(", "); + } + wxString colName = colSet->GetVal(0); + columns += colName; + columnList.Add(colName); + ordersArray.Add(wxEmptyString); + nullsArray.Add(wxEmptyString); + opclassesArray.Add(wxEmptyString); + collationsArray.Add(wxEmptyString); + quotedColumns += qtIdent(colName); + + if (!ct.IsNull()) + { + pgSet *typeSet = ExecuteSet(wxT( + "SELECT typname FROM pg_type where oid=") + ct); + if (typeSet) + { + if (columnCount) + { + procArgs += wxT(", "); + typedColumns += wxT(", "); + quotedTypedColumns += wxT(", "); + } + wxString colType = typeSet->GetVal(0); + procArgs += colType; + typedColumns += colName + wxT("::") + colType; + quotedTypedColumns += qtIdent(colName) + wxT("::") + colType; + delete typeSet; + } + } + delete colSet; + } + columnCount++; + } + } + wxStringTokenizer ops(operatorClassList); + wxString op; + while (ops.HasMoreTokens()) + { + op = ops.GetNextToken(); + pgSet *set = ExecuteSet(wxT( + "SELECT opcname FROM pg_opclass WHERE oid=") + op); + if (set) + { + if (!operatorClasses.IsNull()) + operatorClasses += wxT(", "); + operatorClasses += set->GetVal(0); + delete set; + } + } + } +} + + +void pgIndexBase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + ReadColumnDetails(); + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 0)) + properties->AppendItem(_("Tablespace"), tablespace); + if (!GetProcName().IsNull()) + properties->AppendItem(_("Procedure "), GetSchemaPrefix(GetProcNamespace()) + GetProcName() + wxT("(") + GetTypedColumns() + wxT(")")); + else + properties->AppendItem(_("Columns"), GetColumns()); + + properties->AppendItem(_("Operator classes"), GetOperatorClasses()); + properties->AppendYesNoItem(_("Unique?"), GetIsUnique()); + properties->AppendYesNoItem(_("Primary?"), GetIsPrimary()); + properties->AppendYesNoItem(_("Clustered?"), GetIsClustered()); + properties->AppendYesNoItem(_("Valid?"), GetIsValid()); + properties->AppendItem(_("Access method"), GetIndexType()); + properties->AppendItem(_("Constraint"), GetConstraint()); + properties->AppendYesNoItem(_("System index?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + +void pgIndexBase::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT idx_scan AS ") + qtIdent(_("Index Scans")) + + wxT(", idx_tup_read AS ") + qtIdent(_("Index Tuples Read")) + + wxT(", idx_tup_fetch AS ") + qtIdent(_("Index Tuples Fetched")) + + wxT(", idx_blks_read AS ") + qtIdent(_("Index Blocks Read")) + + wxT(", idx_blks_hit AS ") + qtIdent(_("Index Blocks Hit")); + + if (GetConnection()->HasFeature(FEATURE_SIZE)) + sql += wxT(", pg_size_pretty(pg_relation_size(") + GetOidStr() + wxT(")) AS ") + qtIdent(_("Index Size")); + + if (showExtendedStatistics) + { + sql += wxT(", version AS ") + qtIdent(_("Version")) + wxT(",\n") + wxT(" tree_level AS ") + qtIdent(_("Tree Level")) + wxT(",\n") + wxT(" pg_size_pretty(index_size) AS ") + qtIdent(_("Index Size")) + wxT(",\n") + wxT(" root_block_no AS ") + qtIdent(_("Root Block No")) + wxT(",\n") + wxT(" internal_pages AS ") + qtIdent(_("Internal Pages")) + wxT(",\n") + wxT(" leaf_pages AS ") + qtIdent(_("Leaf Pages")) + wxT(",\n") + wxT(" empty_pages AS ") + qtIdent(_("Empty Pages")) + wxT(",\n") + wxT(" deleted_pages AS ") + qtIdent(_("Deleted Pages")) + wxT(",\n") + wxT(" avg_leaf_density AS ") + qtIdent(_("Average Leaf Density")) + wxT(",\n") + wxT(" leaf_fragmentation AS ") + qtIdent(_("Leaf Fragmentation")) + wxT("\n") + wxT(" FROM pgstatindex('") + GetQuotedFullIdentifier() + wxT("'), pg_stat_all_indexes stat"); + } + else + { + sql += wxT("\n") + wxT(" FROM pg_stat_all_indexes stat"); + } + sql += wxT("\n") + wxT(" JOIN pg_statio_all_indexes statio ON stat.indexrelid = statio.indexrelid\n") + wxT(" JOIN pg_class cl ON cl.oid=stat.indexrelid\n") + wxT(" WHERE stat.indexrelid = ") + GetOidStr(); + + DisplayStatistics(statistics, sql); +} + + +pgObject *pgIndexBase::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = indexFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + + +bool pgIndexBase::HasPgstatindex() +{ + return GetConnection()->HasFeature(FEATURE_PGSTATINDEX); +} + + +executePgstatindexFactory::executePgstatindexFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Extended index statistics"), _("Get extended statistics via pgstatindex for the selected object."), wxITEM_CHECK); +} + + +wxWindow *executePgstatindexFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgIndexBase *)obj)->GetShowExtendedStatistics()) + { + ((pgIndexBase *)obj)->iSetShowExtendedStatistics(true); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + form->SelectStatisticsTab(); + } + else + ((pgIndexBase *)obj)->iSetShowExtendedStatistics(false); + + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool executePgstatindexFactory::CheckEnable(pgObject *obj) +{ + return obj && + (obj->IsCreatedBy(indexFactory) || obj->IsCreatedBy(primaryKeyFactory) + || obj->IsCreatedBy(uniqueFactory) || obj->IsCreatedBy(excludeFactory)) && + ((pgIndexBase *)obj)->HasPgstatindex(); +} + +bool executePgstatindexFactory::CheckChecked(pgObject *obj) +{ + if (!obj) + return false; + + if (obj->GetMetaType() == PGM_INDEX || obj->GetMetaType() == PGM_PRIMARYKEY + || obj->GetMetaType() == PGM_UNIQUE || obj->GetMetaType() == PGM_EXCLUDE) + return ((pgIndexBase *)obj)->GetShowExtendedStatistics(); + + return false; +} + + +pgIndex::pgIndex(pgSchema *newSchema, const wxString &newName) + : pgIndexBase(newSchema, indexFactory, newName) +{ +} + + +pgObject *pgIndexBaseFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgSchemaObjCollection *collection = (pgSchemaObjCollection *)coll; + pgIndexBase *index = 0; + wxString query; + + wxString proname, projoin; + if (collection->GetConnection()->BackendMinimumVersion(7, 4)) + { + proname = wxT("indnatts, "); + if (collection->GetConnection()->BackendMinimumVersion(7, 5)) + { + proname += wxT("cls.reltablespace AS spcoid, spcname, "); + projoin = wxT(" LEFT OUTER JOIN pg_tablespace ta on ta.oid=cls.reltablespace\n"); + } + } + else + { + proname = wxT("proname, pn.nspname as pronspname, proargtypes, "); + projoin = wxT(" LEFT OUTER JOIN pg_proc pr ON pr.oid=indproc\n") + wxT(" LEFT OUTER JOIN pg_namespace pn ON pn.oid=pr.pronamespace\n"); + } + query = wxT("SELECT DISTINCT ON(cls.relname) cls.oid, cls.relname as idxname, indrelid, indkey, indisclustered, indisvalid, indisunique, indisprimary, n.nspname,\n") + wxT(" ") + proname + wxT("tab.relname as tabname, indclass, con.oid AS conoid, CASE contype WHEN 'p' THEN desp.description WHEN 'u' THEN desp.description WHEN 'x' THEN desp.description ELSE des.description END AS description,\n") + wxT(" pg_get_expr(indpred, indrelid") + collection->GetDatabase()->GetPrettyOption() + wxT(") as indconstraint, contype, condeferrable, condeferred, amname, array_to_string(cls.reloptions, ',') reloptions\n"); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(cls.reloptions, ',') from 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(" FROM pg_index idx\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" JOIN pg_class tab ON tab.oid=indrelid\n") + + projoin + + wxT(" JOIN pg_namespace n ON n.oid=tab.relnamespace\n") + wxT(" JOIN pg_am am ON am.oid=cls.relam\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint') AND dep.deptype='i')\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=cls.oid AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_description desp ON (desp.objoid=con.oid AND desp.objsubid = 0 AND desp.classoid='pg_constraint'::regclass)\n") + wxT(" WHERE indrelid = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY cls.relname"); + pgSet *indexes = collection->GetDatabase()->ExecuteSet(query); + + if (indexes) + { + while (!indexes->Eof()) + { + switch (*(indexes->GetCharPtr(wxT("contype")))) + { + case 0: + index = new pgIndex(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + break; + case 'p': + index = new pgPrimaryKey(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + ((pgPrimaryKey *)index)->iSetConstraintOid(indexes->GetOid(wxT("conoid"))); + break; + case 'u': + index = new pgUnique(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + ((pgUnique *)index)->iSetConstraintOid(indexes->GetOid(wxT("conoid"))); + break; + case 'x': + index = new pgExclude(collection->GetSchema()->GetSchema(), indexes->GetVal(wxT("idxname"))); + ((pgExclude *)index)->iSetConstraintOid(indexes->GetOid(wxT("conoid"))); + break; + default: + index = 0; + break; + } + + index->iSetOid(indexes->GetOid(wxT("oid"))); + index->iSetIsClustered(indexes->GetBool(wxT("indisclustered"))); + index->iSetIsValid(indexes->GetBool(wxT("indisvalid"))); + index->iSetIsUnique(indexes->GetBool(wxT("indisunique"))); + index->iSetIsPrimary(indexes->GetBool(wxT("indisprimary"))); + index->iSetIsExclude(*(indexes->GetCharPtr(wxT("contype"))) == 'x'); + index->iSetColumnNumbers(indexes->GetVal(wxT("indkey"))); + index->iSetIdxSchema(indexes->GetVal(wxT("nspname"))); + index->iSetComment(indexes->GetVal(wxT("description"))); + index->iSetRelOptions(indexes->GetVal(wxT("reloptions"))); + index->iSetIdxTable(indexes->GetVal(wxT("tabname"))); + index->iSetRelTableOid(indexes->GetOid(wxT("indrelid"))); + if (collection->GetConnection()->BackendMinimumVersion(7, 4)) + { + index->iSetColumnCount(indexes->GetLong(wxT("indnatts"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + if (indexes->GetOid(wxT("spcoid")) == 0) + index->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + index->iSetTablespaceOid(indexes->GetOid(wxT("spcoid"))); + + if (indexes->GetVal(wxT("spcname")) == wxEmptyString) + index->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + index->iSetTablespace(indexes->GetVal(wxT("spcname"))); + } + + } + else + { + index->iSetColumnCount(0L); + index->iSetProcNamespace(indexes->GetVal(wxT("pronspname"))); + index->iSetProcName(indexes->GetVal(wxT("proname"))); + index->iSetProcArgTypeList(indexes->GetVal(wxT("proargtypes"))); + } + index->iSetOperatorClassList(indexes->GetVal(wxT("indclass"))); + index->iSetDeferrable(indexes->GetBool(wxT("condeferrable"))); + index->iSetDeferred(indexes->GetBool(wxT("condeferred"))); + index->iSetConstraint(indexes->GetVal(wxT("indconstraint"))); + index->iSetIndexType(indexes->GetVal(wxT("amname"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + index->iSetFillFactor(indexes->GetVal(wxT("fillfactor"))); + + if (browser) + { + browser->AppendObject(collection, index); + indexes->MoveNext(); + } + else + break; + } + + delete indexes; + } + return index; +} + + +pgCollection *pgIndexBaseFactory::CreateCollection(pgObject *obj) +{ + return new pgIndexBaseCollection(GetCollectionFactory(), (pgSchema *)obj); +} + + + +pgObject *pgIndexFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, restriction + wxT("\n AND conname IS NULL")); +} + + +wxString pgIndexBaseCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on indexes"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing indexes"); + break; + case OBJECTSLISTREPORT: + message = _("Indexes list report"); + break; + } + + return message; +} + +///////////////////////////// + +#include "images/index.pngc" +#include "images/indexes.pngc" + +pgIndexFactory::pgIndexFactory() + : pgIndexBaseFactory(__("Index"), __("New Index..."), __("Create a new Index."), index_png_img) +{ + metaType = PGM_INDEX; +} + + +pgIndexFactory indexFactory; +static pgaCollectionFactory cf(&indexFactory, __("Indexes"), indexes_png_img); + + +pgIndexBaseCollection::pgIndexBaseCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +void pgIndexBaseCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for indexes on ") + GetSchema()->GetName()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Index Name")); + statistics->AddColumn(_("Index Scans")); + statistics->AddColumn(_("Index Tuples Read")); + statistics->AddColumn(_("Index Tuples Fetched")); + if (hasSize) + statistics->AddColumn(_("Size")); + + wxString sql = wxT("SELECT indexrelname, ") + wxT("idx_scan, idx_tup_read, idx_tup_fetch"); + + if (hasSize) + sql += wxT(", pg_size_pretty(pg_relation_size(indexrelid)) AS ") + qtIdent(wxT("size")); + + sql += wxT("\n") + wxT(" FROM pg_stat_all_indexes stat\n") + wxT(" JOIN pg_class cls ON cls.oid=indexrelid\n") + wxT(" LEFT JOIN pg_depend dep ON (dep.classid = cls.tableoid AND dep.objid = cls.oid AND dep.refobjsubid = '0' AND dep.refclassid=(SELECT oid FROM pg_class WHERE relname='pg_constraint'))\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON (con.tableoid = dep.refclassid AND con.oid = dep.refobjid)\n") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetSchema()->GetName()) + + wxT(" AND stat.relname = ") + qtDbString(GetSchema()->GetName()) + + wxT(" AND con.contype IS NULL") + + wxT("\n ORDER BY indexrelname"); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("indexrelname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("idx_scan"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("idx_tup_read"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("idx_tup_fetch"))); + if (hasSize) + statistics->SetItem(pos, 4, stats->GetVal(wxT("size"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } +} diff --git a/schema/pgIndexConstraint.cpp b/schema/pgIndexConstraint.cpp new file mode 100644 index 0000000..2c4b2d3 --- /dev/null +++ b/schema/pgIndexConstraint.cpp @@ -0,0 +1,504 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgIndexConstraint.cpp - IndexConstraint class: Primary Key, Unique +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgConstraints.h" +#include "schema/pgIndexConstraint.h" + + + +wxString pgIndexConstraint::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on index constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing index constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for index constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop index constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop index constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop index constraint?"); + break; + case PROPERTIESREPORT: + message = _("Index constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Index constraint properties"); + break; + case DDLREPORT: + message = _("Index constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Index constraint DDL"); + break; + case STATISTICSREPORT: + message = _("Index constraint statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Index constraint statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Index constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Index constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Index constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Index constraint dependents"); + break; + } + + return message; +} + + +bool pgIndexConstraint::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("ALTER TABLE ") + qtIdent(GetIdxSchema()) + wxT(".") + qtIdent(GetIdxTable()) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgIndexConstraint::GetDefinition() +{ + wxString sql = wxEmptyString; + + if (wxString(GetTypeName()).Upper() == wxT("EXCLUDE")) + sql += wxT("\n USING ") + GetIndexType() + wxT(" "); + + sql += wxT("(") + GetQuotedColumns() + wxT(")"); + + if (GetConnection()->BackendMinimumVersion(8, 2) && GetFillFactor().Length() > 0) + sql += wxT("\n WITH (FILLFACTOR=") + GetFillFactor() + wxT(")"); + + if (GetConnection()->BackendMinimumVersion(8, 0) && GetTablespace() != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\n USING INDEX TABLESPACE ") + qtIdent(GetTablespace()); + + if (GetConstraint().Length() > 0) + sql += wxT(" WHERE (") + GetConstraint() + wxT(")"); + + if (GetDeferrable()) + { + sql += wxT("\n DEFERRABLE INITIALLY "); + if (GetDeferred()) + sql += wxT("DEFERRED"); + else + sql += wxT("IMMEDIATE"); + } + return sql; +} + + +wxString pgIndexConstraint::GetCreate() +{ + wxString sql; + + sql = GetQuotedIdentifier() + wxT(" ") + + GetTypeName().Upper() + GetDefinition(); + + return sql; +}; + + +wxString pgIndexConstraint::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Constraint: ") + GetQuotedFullIdentifier() + + wxT("\n\n-- ALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT(" DROP CONSTRAINT ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\nALTER TABLE ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT("\n ADD CONSTRAINT ") + + GetCreate() + + wxT(";\n"); + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON CONSTRAINT ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedSchemaPrefix(GetIdxSchema()) + qtIdent(GetIdxTable()) + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + return sql; +} + + + +void pgIndexConstraint::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + ReadColumnDetails(); + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetConstraintOid()); + properties->AppendItem(_("Index OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 0)) + properties->AppendItem(_("Tablespace"), GetTablespace()); + if (GetProcName().IsNull()) + properties->AppendItem(_("Columns"), GetColumns()); + else + { + properties->AppendItem(_("Procedure "), GetSchemaPrefix(GetProcNamespace()) + GetProcName() + wxT("(") + GetTypedColumns() + wxT(")")); + properties->AppendItem(_("Operator classes"), GetOperatorClasses()); + } + properties->AppendYesNoItem(_("Unique?"), GetIsUnique()); + properties->AppendYesNoItem(_("Primary?"), GetIsPrimary()); + properties->AppendYesNoItem(_("Clustered?"), GetIsClustered()); + properties->AppendYesNoItem(_("Valid?"), GetIsValid()); + properties->AppendItem(_("Access method"), GetIndexType()); + properties->AppendItem(_("Constraint"), GetConstraint()); + properties->AppendYesNoItem(_("System index?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + +wxString pgPrimaryKey::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on primary key"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing primary key"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for primary key"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop primary key \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop primary key \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop primary key cascaded?"); + break; + case DROPTITLE: + message = _("Drop primary key?"); + break; + case PROPERTIESREPORT: + message = _("Primary key properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Primary key properties"); + break; + case DDLREPORT: + message = _("Primary key DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Primary key DDL"); + break; + case STATISTICSREPORT: + message = _("Primary key statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Primary key statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Primary key dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Primary key dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Primary key dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Primary key dependents"); + break; + } + + return message; +} + + +pgObject *pgPrimaryKey::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = primaryKeyFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + +wxString pgUnique::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on unique constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing unique constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for unique constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop unique constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop unique constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop unique constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop unique constraint?"); + break; + case PROPERTIESREPORT: + message = _("Unique constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Unique constraint properties"); + break; + case DDLREPORT: + message = _("Unique constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Unique constraint DDL"); + break; + case STATISTICSREPORT: + message = _("Unique constraint statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Unique constraint statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Unique constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Unique constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Unique constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Unique constraint dependents"); + break; + } + + return message; +} + + +pgObject *pgUnique::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = uniqueFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + +wxString pgExclude::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on exclusion constraint"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing exclusion constraint"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for exclusion constraint"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop exclusion constraint \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop exclusion constraint \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop exclusion constraint cascaded?"); + break; + case DROPTITLE: + message = _("Drop exclusion constraint?"); + break; + case PROPERTIESREPORT: + message = _("Exclusion constraint properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Exclusion constraint properties"); + break; + case DDLREPORT: + message = _("Exclusion constraint DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Exclusion constraint DDL"); + break; + case STATISTICSREPORT: + message = _("Exclusion constraint statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Exclusion constraint statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Exclusion constraint dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Exclusion constraint dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Exclusion constraint dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Exclusion constraint dependents"); + break; + } + + return message; +} + + +pgObject *pgExclude::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *index = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + index = excludeFactory.CreateObjects(coll, 0, wxT("\n AND cls.oid=") + GetOidStr()); + + return index; +} + +pgObject *pgPrimaryKeyFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &where) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, wxT(" AND contype='p'\n") + where); +} + + +pgObject *pgUniqueFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &where) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, wxT(" AND contype='u'\n") + where); +} + + +pgObject *pgExcludeFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &where) +{ + return pgIndexBaseFactory::CreateObjects(collection, browser, wxT(" AND contype='x'\n") + where); +} + + +#include "images/primarykey.pngc" + +pgPrimaryKeyFactory::pgPrimaryKeyFactory() + : pgIndexBaseFactory(__("Primary Key"), __("New Primary Key..."), __("Create a new Primary Key constraint."), primarykey_png_img) +{ + metaType = PGM_PRIMARYKEY; + collectionFactory = &constraintCollectionFactory; +} + + +pgPrimaryKeyFactory primaryKeyFactory; + +#include "images/unique.pngc" + +pgUniqueFactory::pgUniqueFactory() + : pgIndexBaseFactory(__("Unique"), __("New Unique Constraint..."), __("Create a new Unique constraint."), unique_png_img) +{ + metaType = PGM_UNIQUE; + collectionFactory = &constraintCollectionFactory; +} + + +pgUniqueFactory uniqueFactory; + + +#include "images/exclude.pngc" + +pgExcludeFactory::pgExcludeFactory() + : pgIndexBaseFactory(__("Exclude"), __("New Exclusion Constraint..."), __("Create a new Exclusion constraint."), exclude_png_img) +{ + metaType = PGM_EXCLUDE; + collectionFactory = &constraintCollectionFactory; +} + + +pgExcludeFactory excludeFactory; diff --git a/schema/pgLanguage.cpp b/schema/pgLanguage.cpp new file mode 100644 index 0000000..b1ba218 --- /dev/null +++ b/schema/pgLanguage.cpp @@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgLanguage.cpp - Language class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgLanguage.h" + + +pgLanguage::pgLanguage(const wxString &newName) + : pgDatabaseObject(languageFactory, newName) +{ +} + +wxString pgLanguage::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on language"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing language"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop language \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop language \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop language cascaded?"); + break; + case DROPTITLE: + message = _("Drop language?"); + break; + case PROPERTIESREPORT: + message = _("Language properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Language properties"); + break; + case DDLREPORT: + message = _("Language DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Language DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Language dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Language dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Language dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Language dependents"); + break; + } + + return message; +} + +bool pgLanguage::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP LANGUAGE ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgLanguage::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Language: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP LANGUAGE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + if (GetTrusted()) + sql += wxT("TRUSTED "); + sql += wxT("PROCEDURAL LANGUAGE '") + GetName() + + wxT("'\n HANDLER ") + qtIdent(GetHandlerProc()); + + if (!GetInlineProc().IsEmpty()) + sql += wxT("\n INLINE ") + qtIdent(GetInlineProc()); + + if (!GetValidatorProc().IsEmpty()) + sql += wxT("\n VALIDATOR ") + qtIdent(GetValidatorProc()); + + sql += wxT(";\n") + + GetOwnerSql(8, 3, wxT("LANGUAGE ") + GetName()) + + GetGrant(wxT("U"), wxT("LANGUAGE ") + GetQuotedFullIdentifier()); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + return sql; +} + +void pgLanguage::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 3)) + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendYesNoItem(_("Trusted?"), GetTrusted()); + properties->AppendItem(_("Handler function"), GetHandlerProc()); + if (GetConnection()->BackendMinimumVersion(9, 0)) + properties->AppendItem(_("Inline function"), GetInlineProc()); + properties->AppendItem(_("Validator function"), GetValidatorProc()); + properties->AppendYesNoItem(_("System language?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +pgObject *pgLanguage::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *language = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + language = languageFactory.CreateObjects(coll, 0, wxT("\n AND lan.oid=") + GetOidStr()); + + return language; +} + +pgObject *pgLanguageFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgLanguage *language = 0; + + sql = wxT("SELECT lan.oid, lanname, lanpltrusted, lanacl, hp.proname as lanproc, vp.proname as lanval, description"); + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", pg_get_userbyid(lan.lanowner) as languageowner"); + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + sql += wxT(", ip.proname as laninl"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=lan.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=lan.oid) AS providers"); + } + sql += wxT("\n FROM pg_language lan\n") + wxT(" JOIN pg_proc hp on hp.oid=lanplcallfoid\n"); + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + sql += wxT(" LEFT OUTER JOIN pg_proc ip on ip.oid=laninline\n"); + sql += wxT(" LEFT OUTER JOIN pg_proc vp on vp.oid=lanvalidator\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=lan.oid AND des.objsubid=0 AND des.classoid='pg_language'::regclass)\n") + wxT(" WHERE lanispl IS TRUE") + + restriction + wxT("\n") + wxT(" ORDER BY lanname"); + pgSet *languages = collection->GetDatabase()->ExecuteSet(sql); + + if (languages) + { + while (!languages->Eof()) + { + + language = new pgLanguage(languages->GetVal(wxT("lanname"))); + language->iSetDatabase(collection->GetDatabase()); + language->iSetOid(languages->GetOid(wxT("oid"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + { + language->iSetOwner(languages->GetVal(wxT("languageowner"))); + } + language->iSetAcl(languages->GetVal(wxT("lanacl"))); + language->iSetComment(languages->GetVal(wxT("description"))); + language->iSetHandlerProc(languages->GetVal(wxT("lanproc"))); + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + language->iSetInlineProc(languages->GetVal(wxT("laninl"))); + } + language->iSetValidatorProc(languages->GetVal(wxT("lanval"))); + language->iSetTrusted(languages->GetBool(wxT("lanpltrusted"))); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + language->iSetProviders(languages->GetVal(wxT("providers"))); + language->iSetLabels(languages->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, language); + languages->MoveNext(); + } + else + break; + } + + delete languages; + } + return language; +} + +///////////////////////////// + +pgLanguageCollection::pgLanguageCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + +wxString pgLanguageCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on languages"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing languages"); + break; + case OBJECTSLISTREPORT: + message = _("Languages list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/language.pngc" +#include "images/language-sm.pngc" +#include "images/languages.pngc" + +pgLanguageFactory::pgLanguageFactory() + : pgDatabaseObjFactory(__("Language"), __("New Language..."), __("Create a new Language."), language_png_img, language_sm_png_img) +{ + metaType = PGM_LANGUAGE; +} + +pgCollection *pgLanguageFactory::CreateCollection(pgObject *obj) +{ + return new pgLanguageCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgLanguageFactory languageFactory; +static pgaCollectionFactory cf(&languageFactory, __("Languages"), languages_png_img); diff --git a/schema/pgObject.cpp b/schema/pgObject.cpp new file mode 100644 index 0000000..7495119 --- /dev/null +++ b/schema/pgObject.cpp @@ -0,0 +1,2167 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgObject.cpp - PostgreSQL object base class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "schema/pgServer.h" +#include "frm/frmMain.h" +#include "frm/frmReport.h" +#include "schema/pgDomain.h" +#include "schema/pgAggregate.h" +#include "schema/pgSequence.h" +#include "schema/pgFunction.h" +#include "schema/pgType.h" +#include "schema/pgDatabase.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgView.h" +#include "schema/pgType.h" +#include "schema/pgOperator.h" +#include "schema/pgLanguage.h" +#include "schema/pgConversion.h" +#include "schema/pgTablespace.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "schema/pgUserMapping.h" +#include "schema/pgIndex.h" +#include "schema/pgTrigger.h" +#include "schema/pgCheck.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgForeignDataWrapper.h" +#include "schema/pgForeignServer.h" +#include "schema/pgForeignTable.h" +#include "schema/pgRule.h" +#include "schema/pgRole.h" +#include "schema/pgCast.h" +#include "schema/pgCatalogObject.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgOperatorFamily.h" +#include "schema/pgSchema.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgExtension.h" +#include "schema/edbPackage.h" +#include "schema/edbSynonym.h" +#include "schema/pgCollation.h" +#include "utils/pgDefs.h" +#include "schema/gpExtTable.h" +#include "schema/gpResQueue.h" +#include "agent/pgaJob.h" +#include "agent/pgaSchedule.h" +#include "agent/pgaStep.h" +#include "schema/pgPartition.h" + +int pgObject::GetType() const +{ + if (factory) + return factory->GetId(); + return type; +} + + +int pgObject::GetMetaType() const +{ + if (factory) + return factory->GetMetaType(); + return PGM_UNKNOWN; +} + + +wxString pgObject::GetTypeName() const +{ + return factory->GetTypeName(); +} + + +wxString pgObject::GetTranslatedTypeName() const +{ + return wxString(wxGetTranslation(GetTypeName())); +} + + +wxString pgObject::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on unknown object of type"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing unknown object of type"); + break; + case BACKUPGLOBALS: + message = _("Backup globals of unknown object of type"); + break; + case BACKUPSERVERTITLE: + message = _("Backup unknown object of type"); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop object \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPTITLE: + message = _("Drop object?"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore \"%s\""), + GetFullIdentifier().c_str()); + break; + } + //message += wxT(" ") + factory->GetTypeName(); + + return message; +} + + +int pgObject::GetIconId() +{ + int id = -1; + if (factory) + id = factory->GetIconId(); + + wxASSERT(id != -1); + return id; +} + + +int pgObject::GetTypeId(const wxString &typname) +{ + pgaFactory *factory = pgaFactory::GetFactory(typname); + if (factory) + return factory->GetId(); + + return -1; +} + + +pgObject::pgObject(pgaFactory &_factory, const wxString &newName) + : wxTreeItemData(), oid(0) +{ + factory = &_factory; + + if (factory->IsCollection() && newName.IsEmpty()) + name = factory->GetTypeName(); + else + name = newName; + + type = factory->GetId(); + expandedKids = false; + needReread = false; + hintShown = false; + dlg = NULL; +} + + +pgObject::pgObject(int newType, const wxString &newName) + : wxTreeItemData(), oid(0) +{ + factory = pgaFactory::GetFactory(newType); + + // Set the typename and type + type = newType; + + if (newName.IsEmpty()) + name = factory->GetTypeName(); + else + name = newName; + expandedKids = false; + needReread = false; + hintShown = false; + dlg = NULL; +} + + +void pgObject::AppendMenu(wxMenu *menu, int type) +{ + if (menu) + factory->AppendMenu(menu); +} + + +wxString pgObject::GetHelpPage(bool forCreate) const +{ + wxString page; + + if (!IsCollection()) + page = wxT("pg/sql-create") + GetTypeName().Lower(); + + return page; +} + + +wxMenu *pgObject::GetNewMenu() +{ + wxMenu *menu = new wxMenu(); + if (CanCreate()) + AppendMenu(menu); + return menu; +} + +void pgObject::ShowStatistics(frmMain *form, ctlListView *statistics) +{ +} + + +bool pgObject::UpdateIcon(ctlTree *browser) +{ + int icon = GetIconId(); + if (GetId() && browser->GetItemImage(GetId(), wxTreeItemIcon_Normal) != icon) + { + browser->SetItemImage(GetId(), GetIconId(), wxTreeItemIcon_Normal); + browser->SetItemImage(GetId(), GetIconId(), wxTreeItemIcon_Selected); + return true; + } + return false; +} + + +void pgObject::ShowDependency(pgDatabase *db, ctlListView *list, const wxString &query, const wxString &clsorder) +{ + list->ClearAll(); + list->AddColumn(_("Type"), 60); + list->AddColumn(_("Name"), 100); + list->AddColumn(_("Restriction"), 50); + + pgConn *conn = GetConnection(); + if (conn) + { + pgSet *set; + // currently missing: + // - pg_cast + // - pg_operator + // - pg_opclass + + // not being implemented: + // - pg_index (done by pg_class) + wxString q=query + wxT("\n") + wxT(" AND ") + clsorder + wxT(" IN (\n") + wxT(" SELECT oid FROM pg_class\n") + wxT(" WHERE relname IN ('pg_class', 'pg_constraint', 'pg_conversion', 'pg_language', 'pg_proc', 'pg_extension', \n") + wxT(" 'pg_rewrite', 'pg_namespace', 'pg_trigger', 'pg_type', 'pg_attrdef', 'pg_event_trigger','pg_publication_rel','pg_subscription_rel'))\n") + wxT(" ORDER BY ") + clsorder + wxT(", cl.relkind"); + set = conn->ExecuteSet(q); + + if (set) + { + while (!set->Eof()) + { + wxString refname; + wxString _refname = set->GetVal(wxT("refname")); + + if (db) + refname = db->GetQuotedSchemaPrefix(set->GetVal(wxT("nspname"))); + else + { + refname = qtIdent(set->GetVal(wxT("nspname"))); + if (!refname.IsEmpty()) + refname += wxT("."); + } + + wxString typestr = set->GetVal(wxT("type")); + pgaFactory *depFactory = 0; + switch ((wxChar)typestr.c_str()[0]) + { + case 'c': + case 's': // we don't know these; internally handled + case 't': + set->MoveNext(); + continue; + + case 'r': + { + if (StrToLong(typestr.Mid(1)) > 0) + depFactory = &columnFactory; + else + depFactory = &tableFactory; + break; + } + case 'i': + depFactory = &indexFactory; + break; + case 'E': + depFactory = &extensionFactory; + break; + + case 'S': + depFactory = &sequenceFactory; + break; + case 'v': + depFactory = &viewFactory; + break; + case 'x': + depFactory = &extTableFactory; + break; + case 'p': + depFactory = &functionFactory; + break; + case 'n': + depFactory = &schemaFactory; + break; + case 'y': + depFactory = &typeFactory; + break; + case 'T': + depFactory = &triggerFactory; + break; + case 'f': + depFactory = &foreignTableFactory; + break; + + case 'l': + depFactory = &languageFactory; + break; + case 'R': + { + refname = _refname + wxT(" ON ") + refname + set->GetVal(wxT("ownertable")); + _refname = wxEmptyString; + depFactory = &ruleFactory; + break; + } + case 'C': + { + switch ((wxChar)typestr.c_str()[1]) + { + case 'c': + depFactory = &checkFactory; + break; + case 'f': + refname += set->GetVal(wxT("ownertable")) + wxT("."); + depFactory = &foreignKeyFactory; + break; + case 'p': + depFactory = &primaryKeyFactory; + break; + case 'u': + depFactory = &uniqueFactory; + break; + case 'x': + depFactory = &excludeFactory; + break; + default: + break; + } + break; + } + case 'A': + { + // Include only functions + if (set->GetVal(wxT("adbin")).StartsWith(wxT("{FUNCEXPR"))) + { + depFactory = &functionFactory; + refname = set->GetVal(wxT("adsrc")); + break; + } + else + { + set->MoveNext(); + continue; + } + } + default: + break; + } + + refname += _refname; + + wxString typname; + int icon; + if (depFactory) + { + typname = depFactory->GetTypeName(); + icon = depFactory->GetIconId(); + } + else + { + typname = _("Unknown"); + icon = -1; + } + + wxString deptype; + + switch ( (wxChar) set->GetVal(wxT("deptype")).c_str()[0]) + { + case 'n': + deptype = wxT("normal"); + break; + case 'a': + deptype = wxT("auto"); + break; + case 'i': + { + if (settings->GetShowSystemObjects()) + deptype = wxT("internal"); + else + { + set->MoveNext(); + continue; + } + break; + } + case 'p': + deptype = wxT("pin"); + typname = wxEmptyString; + break; + default: + break; + } + + list->AppendItem(icon, typname, refname, deptype); + set->MoveNext(); + } + delete set; + } + } +} + +void pgObject::CreateList3Columns(ctlListView *list, const wxString &left, const wxString &middle, const wxString &right) +{ + list->ClearAll(); + list->AddColumn(left, 80); + list->AddColumn(middle, 80); + list->AddColumn(right, list->GetSize().GetWidth() - 170); +} + + +void pgObject::CreateListColumns(ctlListView *list, const wxString &left, const wxString &right) +{ + list->ClearAll(); + list->AddColumn(left, 130); + list->AddColumn(right, list->GetSize().GetWidth() - 140); +} + + +void pgObject::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh) +{ + if (this->IsCollection()) + return; + + // Bail out if this is a pgAgent object, as they use the OID for IDs + if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP || GetMetaType() == PGM_PROJOB) + return; + + wxString where; + if (wh.IsEmpty()) + { + if(!GetOidStr().IsSameAs(wxT("0"))) + where = wxT(" WHERE dep.objid=") + GetOidStr(); + else + return; + } + else + where = wh; + /* + * Behavior of concatinating operator (||) is different for EnterpriseDB. + * For the following query: + * SELECT a || null; + * When selected postgresql compatible mode, it will return null. + * And when selected oracle compatible mode, it will return 'a'. + * + * Hence, the following query may or may not work for EnterpriseDB depending on the + * compatiblity mode: + * COALESCE(cl.relname || '.' || att.attname, cl.relname, co.conname, pr.proname, + * tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) + * + * Instead of that, we will use the following query to run it correctly everytime: + * CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL + * THEN cl.relname || '.' || att.attname + * ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, + * la.lanname, rw.rulename, ns.nspname) + * END + */ + ShowDependency(GetDatabase(), Dependencies, + wxT("SELECT DISTINCT dep.deptype, dep.refclassid, cl.relkind, ad.adbin, pg_get_expr(ad.adbin,0) adsrc, \n") + wxT(" CASE WHEN cl.relkind IS NOT NULL THEN cl.relkind || COALESCE(dep.refobjsubid::text, '')\n") + wxT(" WHEN tg.oid IS NOT NULL THEN 'T'::text\n") + wxT(" WHEN ty.oid IS NOT NULL THEN 'y'::text\n") + wxT(" WHEN ns.oid IS NOT NULL THEN 'n'::text\n") + wxT(" WHEN pr.oid IS NOT NULL THEN 'p'::text\n") + wxT(" WHEN la.oid IS NOT NULL THEN 'l'::text\n") + wxT(" WHEN rw.oid IS NOT NULL THEN 'R'::text\n") + wxT(" WHEN co.oid IS NOT NULL THEN 'C'::text || contype\n") + wxT(" WHEN ad.oid IS NOT NULL THEN 'A'::text\n") + wxT(" WHEN ext.oid IS NOT NULL THEN 'E'::text\n") + wxT(" WHEN pub.oid IS NOT NULL THEN 'r'::text\n") + wxT(" ELSE '' END AS type,\n") + wxT(" COALESCE(coc.relname, clrw.relname) AS ownertable,\n") + wxT(" CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || '.' || att.attname\n") + wxT(" ELSE COALESCE(ext.extname,cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,pub.prrelid::regclass::text)\n") + wxT(" END AS refname,\n") + wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n") + wxT(" FROM pg_depend dep\n") + wxT(" LEFT JOIN pg_class cl ON dep.refobjid=cl.oid\n") + wxT(" LEFT JOIN pg_attribute att ON dep.refobjid=att.attrelid AND dep.refobjsubid=att.attnum\n") + wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n") + wxT(" LEFT JOIN pg_proc pr ON dep.refobjid=pr.oid\n") + wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n") + wxT(" LEFT JOIN pg_trigger tg ON dep.refobjid=tg.oid\n") + wxT(" LEFT JOIN pg_type ty ON dep.refobjid=ty.oid\n") + wxT(" LEFT JOIN pg_namespace nst ON ty.typnamespace=nst.oid\n") + wxT(" LEFT JOIN pg_constraint co ON dep.refobjid=co.oid\n") + wxT(" LEFT JOIN pg_class coc ON co.conrelid=coc.oid\n") + wxT(" LEFT JOIN pg_namespace nso ON co.connamespace=nso.oid\n") + wxT(" LEFT JOIN pg_rewrite rw ON dep.refobjid=rw.oid\n") + wxT(" LEFT JOIN pg_class clrw ON clrw.oid=rw.ev_class\n") + wxT(" LEFT JOIN pg_namespace nsrw ON clrw.relnamespace=nsrw.oid\n") + wxT(" LEFT JOIN pg_language la ON dep.refobjid=la.oid\n") + wxT(" LEFT JOIN pg_namespace ns ON dep.refobjid=ns.oid\n") + wxT(" LEFT JOIN pg_attrdef ad ON ad.adrelid=att.attrelid AND ad.adnum=att.attnum\n") + wxT(" LEFT JOIN pg_publication_rel pub ON dep.objid=pub.oid AND pub.prpubid=dep.refobjid\n") + wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.refobjid\n") + + where, wxT("refclassid")); + + pgConn *conn = GetConnection(); + if (conn) + { + if (where.Find(wxT("subid")) < 0 && conn->BackendMinimumVersion(8, 1)) + { + int iconId = groupRoleFactory.GetCollectionFactory()->GetIconId(); + pgSetIterator set(conn, + wxT("SELECT rolname AS refname, refclassid, deptype\n") + wxT(" FROM pg_shdepend dep\n") + wxT(" LEFT JOIN pg_roles r ON refclassid=1260 AND refobjid=r.oid\n") + + where + wxT("\n") + wxT(" ORDER BY 1")); + + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("refname")); + wxString deptype = set.GetVal(wxT("deptype")); + if (deptype == wxT("a")) + deptype = wxT("ACL"); + else if (deptype == wxT("o")) + deptype = _("Owner"); + + if (set.GetOid(wxT("refclassid")) == PGOID_CLASS_PG_AUTHID) + Dependencies->AppendItem(iconId, wxT("Role"), refname, deptype); + } + } + /* + * + * A Corner case, reported by Guillaume Lelarge, could be found at: + * http://archives.postgresql.org/pgadmin-hackers/2009-03/msg00026.php + * + * SQL: + * CREATE TABLE t1 (id serial); + * CREATE TABLE t2 (LIKE t1 INCLUDING DEFAULTS); + * + * When we try to drop the table t1, it gives the following notice: + * "NOTICE: default for table t2 column id depends on sequence t1_id_seq" + * + * This suggests that the column 't2.id' should be shown in the "Dependency" list + * of the sequence 't1_seq_id' + * + * As we could not find any direct relationship between 't1_seq_id' and 't2' + * table, we come up with this solution. + * + */ + if (GetMetaType() == PGM_SEQUENCE) + { + int iconId = columnFactory.GetIconId(); + /* + * Behavior of concatinating operator (||) is different for EnterpriseDB. + * For the following query: + * SELECT a || null; + * When selected postgresql compatible mode, it will return null. + * And when selected oracle compatible mode, it will return 'a'. + * + * Hence, the following query may or may not work for EnterpriseDB depending on the + * compatiblity mode: + * COALESCE(ref.relname || '.' || att.attname, ref.relname) + * + * Instead of that, we will use the following query to run it correctly everytime: + * CASE WHEN ref.relname IS NOT NULL AND att.attname IS NOT NULL + * THEN ref.relname || '.' || att.attname + * ELSE ref.relname + * END + */ + pgSetIterator set(conn, + wxT("SELECT \n") + wxT(" CASE WHEN att.attname IS NOT NULL AND ref.relname IS NOT NULL THEN ref.relname || '.' || att.attname\n") + wxT(" ELSE ref.relname \n") + wxT(" END AS refname, \n") + wxT(" d2.refclassid, d1.deptype AS deptype\n") + wxT("FROM pg_depend d1\n") + wxT(" LEFT JOIN pg_depend d2 ON d1.objid=d2.objid AND d1.refobjid != d2.refobjid\n") + wxT(" LEFT JOIN pg_class ref ON ref.oid = d2.refobjid\n") + wxT(" LEFT JOIN pg_attribute att ON d2.refobjid=att.attrelid AND d2.refobjsubid=att.attnum\n") + wxT("WHERE d1.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef')\n") + wxT(" AND d2.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d1.refobjid)\n") + wxT(" AND d1.refobjid=") + GetOidStr()); + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("refname")); + wxString deptype = set.GetVal(wxT("deptype")); + if (deptype == wxT("n")) + deptype = wxT("normal"); + else if (deptype == wxT("i")) + deptype = _("internal"); + else if (deptype == wxT("a")) + deptype = _("auto"); + + Dependencies->AppendItem(iconId, wxT("Column"), refname, deptype); + } + } + } + +} + + +void pgObject::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh) +{ + if (this->IsCollection()) + return; + + // Bail out if this is a pgAgent object, as they use the OID for IDs + if (GetMetaType() == PGM_JOB || GetMetaType() == PGM_SCHEDULE || GetMetaType() == PGM_STEP || GetMetaType() == PGM_PROJOB) + return; + + wxString where; + if (wh.IsEmpty()) + where = wxT(" WHERE dep.refobjid=") + GetOidStr(); + else + where = wh; + /* + * Behavior of concatinating operator (||) is different for EnterpriseDB. + * For the following query: + * SELECT a || null; + * When selected postgresql compatible mode, it will return null. + * And when selected oracle compatible mode, it will return 'a'. + * + * Hence, the following query may or may not work for EnterpriseDB depending on the + * compatiblity mode: + * COALESCE(cl.relname || '.' || att.attname, cl.relname, co.conname, pr.proname, + * tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname) + * + * Instead of that, we will use the following query to run it correctly everytime: + * CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL + * THEN cl.relname || '.' || att.attname + * ELSE COALESCE(cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, + * la.lanname, rw.rulename, ns.nspname) + * END + */ + ShowDependency(GetDatabase(), referencedBy, + wxT("SELECT DISTINCT dep.deptype, dep.classid, cl.relkind, ad.adbin, pg_get_expr(ad.adbin,0) adsrc, \n") + wxT(" CASE WHEN cl.relkind IS NOT NULL THEN cl.relkind || COALESCE(dep.objsubid::text, '')\n") + wxT(" WHEN tg.oid IS NOT NULL THEN 'T'::text\n") + wxT(" WHEN ty.oid IS NOT NULL THEN 'y'::text\n") + wxT(" WHEN ns.oid IS NOT NULL THEN 'n'::text\n") + wxT(" WHEN pr.oid IS NOT NULL THEN 'p'::text\n") + wxT(" WHEN la.oid IS NOT NULL THEN 'l'::text\n") + wxT(" WHEN rw.oid IS NOT NULL THEN 'R'::text\n") + wxT(" WHEN co.oid IS NOT NULL THEN 'C'::text || contype\n") + wxT(" WHEN ad.oid IS NOT NULL THEN 'A'::text\n") + wxT(" WHEN pub.oid IS NOT NULL THEN 'r'::text\n") + wxT(" WHEN ext.oid IS NOT NULL THEN 'E'::text\n") + wxT(" ELSE '' END AS type,\n") + wxT(" COALESCE(coc.relname, clrw.relname) AS ownertable,\n") + wxT(" CASE WHEN cl.relname IS NOT NULL AND att.attname IS NOT NULL THEN cl.relname || '.' || att.attname \n") + wxT(" ELSE COALESCE(ext.extname,cl.relname, co.conname, pr.proname, tg.tgname, ty.typname, la.lanname, rw.rulename, ns.nspname,pub.prrelid::regclass::text) \n") + wxT(" END AS refname,\n") + wxT(" COALESCE(nsc.nspname, nso.nspname, nsp.nspname, nst.nspname, nsrw.nspname) AS nspname\n") + wxT(" FROM pg_depend dep\n") + wxT(" LEFT JOIN pg_class cl ON dep.objid=cl.oid\n") + wxT(" LEFT JOIN pg_attribute att ON dep.objid=att.attrelid AND dep.objsubid=att.attnum\n") + wxT(" LEFT JOIN pg_namespace nsc ON cl.relnamespace=nsc.oid\n") + wxT(" LEFT JOIN pg_proc pr ON dep.objid=pr.oid\n") + wxT(" LEFT JOIN pg_namespace nsp ON pr.pronamespace=nsp.oid\n") + wxT(" LEFT JOIN pg_trigger tg ON dep.objid=tg.oid\n") + wxT(" LEFT JOIN pg_type ty ON dep.objid=ty.oid\n") + wxT(" LEFT JOIN pg_namespace nst ON ty.typnamespace=nst.oid\n") + wxT(" LEFT JOIN pg_constraint co ON dep.objid=co.oid\n") + wxT(" LEFT JOIN pg_class coc ON co.conrelid=coc.oid\n") + wxT(" LEFT JOIN pg_namespace nso ON co.connamespace=nso.oid\n") + wxT(" LEFT JOIN pg_rewrite rw ON dep.objid=rw.oid\n") + wxT(" LEFT JOIN pg_class clrw ON clrw.oid=rw.ev_class\n") + wxT(" LEFT JOIN pg_namespace nsrw ON clrw.relnamespace=nsrw.oid\n") + wxT(" LEFT JOIN pg_language la ON dep.objid=la.oid\n") + wxT(" LEFT JOIN pg_namespace ns ON dep.objid=ns.oid\n") + wxT(" LEFT JOIN pg_attrdef ad ON ad.oid=dep.objid\n") + wxT(" LEFT JOIN pg_extension ext ON ext.oid=dep.objid\n") + wxT(" LEFT JOIN pg_publication_rel pub ON dep.objid=pub.oid AND pub.prpubid=dep.refobjid\n") + + where, wxT("classid")); + + /* + * + * A Corner case, reported by Guillaume Lelarge, could be found at: + * http://archives.postgresql.org/pgadmin-hackers/2009-03/msg00026.php + * + * SQL: + * CREATE TABLE t1 (id serial); + * CREATE TABLE t2 (LIKE t1 INCLUDING DEFAULTS); + * + * When we try to drop the table t1, it gives the following notice: + * "NOTICE: default for table t2 column id depends on sequence t1_id_seq" + * + * This suggests that the sequence 't1_seq_id' should be shown in the + * "Dependents" list of the table 't2' and column 't2.id' + * + * As we could not find any direct relationship between 't1_seq_id' and 't2' + * table, we come up with this solution. + * + */ + pgConn *conn = GetConnection(); + if (conn && (GetMetaType() == PGM_TABLE || GetMetaType() == PGM_COLUMN)) + { + int iconId = sequenceFactory.GetIconId(); + wxString strQuery = + wxT("SELECT ref.relname AS refname, d2.refclassid, dep.deptype AS deptype\n") + wxT(" FROM pg_depend dep\n") + wxT(" LEFT JOIN pg_depend d2 ON dep.objid=d2.objid AND dep.refobjid != d2.refobjid\n") + wxT(" LEFT JOIN pg_class ref ON ref.oid=d2.refobjid\n") + wxT(" LEFT JOIN pg_attribute att ON d2.refclassid=att.attrelid AND d2.refobjsubid=att.attnum\n") + + where + + wxT(" AND dep.classid=(SELECT oid FROM pg_class WHERE relname='pg_attrdef')\n") + wxT(" AND dep.refobjid NOT IN (SELECT d3.refobjid FROM pg_depend d3 WHERE d3.objid=d2.refobjid)"); + + + pgSetIterator set(conn, strQuery); + + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("refname")); + if (refname.IsEmpty()) + continue; + + wxString deptype = set.GetVal(wxT("deptype")); + if (deptype == wxT("a")) + deptype = _("auto"); + else if (deptype == wxT("n")) + deptype = _("normal"); + else if (deptype == wxT("i")) + deptype = _("internal"); + + referencedBy->AppendItem(iconId, wxT("Sequence"), refname, deptype); + } + } +} + + +void pgObject::ShowTree(frmMain *form, ctlTree *browser, ctlListView *properties, ctlSQLBox *sqlPane) +{ + pgConn *conn = GetConnection(); + if (conn) + { + int status = conn->GetStatus(); + if (status == PGCONN_BROKEN || status == PGCONN_BAD) + { + form->SetStatusText(_(" Connection broken.")); + return; + } + } + + wxLogInfo(wxT("Displaying properties for %s %s"), GetTypeName().c_str(), GetIdentifier().c_str()); + + if (form) + { + form->StartMsg(GetTranslatedMessage(RETRIEVINGDETAILS)); + + SetContextInfo(form); + + form->ShowObjStatistics(this); + } + + ShowTreeDetail(browser, form, properties, sqlPane); + if (form) + form->EndMsg(!GetConnection() || GetConnection()->GetStatus() == PGCONN_OK); +} + + +wxTreeItemId pgObject::AppendBrowserItem(ctlTree *browser, pgObject *object) +{ + return browser->AppendObject(this, object); +} + + +wxString pgObject::GetCommentSql() +{ + wxString cmt; + if (!comment.IsNull()) + { + cmt = wxT("COMMENT ON ") + GetTypeName().Upper() + wxT(" ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(comment) + wxT(";\n"); + } + return cmt; +} + + +wxString pgObject::GetOwnerSql(int major, int minor, wxString objname, wxString objtype) +{ + wxString sql; + if (GetConnection()->BackendMinimumVersion(major, minor)) + { +// if (GetConnection()->GetUser() != owner) // optional? + { + if (objtype.IsEmpty()) + objtype = GetTypeName().Upper(); + + if (objname.IsEmpty()) + objname = objtype + wxT(" ") + GetQuotedFullIdentifier(); + + sql = wxT("ALTER ") + objname + wxT("\n OWNER TO ") + qtIdent(owner) + wxT(";\n"); + } + } + return sql; +} + + +void pgObject::AppendRight(wxString &rights, const wxString &acl, wxChar c, const wxChar *rightName, const wxString &column) +{ + if (acl.Find(c) >= 0) + { + if (!rights.IsNull()) + rights.Append(wxT(", ")); + rights.Append(rightName); + + if (!column.IsEmpty()) + rights.Append(wxT("(") + column + wxT(")")); + } +} + + +wxString pgObject::GetPrivilegeGrant(const wxString &allPattern, const wxString &acl, const wxString &grantOnObject, const wxString &user, const wxString &column) +{ + wxString rights; + + if (allPattern.Length() > 1 && acl == allPattern) + { + rights = wxT("ALL"); + if (!column.IsEmpty()) + rights += wxT("(") + column + wxT(")"); + } + else + { + AppendRight(rights, acl, 'r', wxT("SELECT"), column); + AppendRight(rights, acl, 'w', wxT("UPDATE"), column); + AppendRight(rights, acl, 'a', wxT("INSERT"), column); + AppendRight(rights, acl, 'D', wxT("TRUNCATE"), column); + AppendRight(rights, acl, 'c', wxT("CONNECT"), column); + AppendRight(rights, acl, 'd', wxT("DELETE"), column); + AppendRight(rights, acl, 'R', wxT("RULE"), column); + AppendRight(rights, acl, 'x', wxT("REFERENCES"), column); + AppendRight(rights, acl, 't', wxT("TRIGGER"), column); + AppendRight(rights, acl, 'X', wxT("EXECUTE"), column); + AppendRight(rights, acl, 'U', wxT("USAGE"), column); + AppendRight(rights, acl, 'C', wxT("CREATE"), column); + AppendRight(rights, acl, 'T', wxT("TEMPORARY"), column); + } + wxString grant; + if (rights.IsNull()) + { + grant += wxT("REVOKE ALL"); + if (!column.IsEmpty()) + grant += wxT("(") + column + wxT(")"); + } + else + grant += wxT("GRANT ") + rights; + + grant += wxT(" ON ") + grantOnObject; + + if (rights.IsNull()) grant += wxT(" FROM "); + else grant += wxT(" TO "); + + grant += user; + + return grant; +} + + +wxArrayString pgObject::GetProviderLabelArray() +{ + wxArrayString providersArray, labelsArray, seclabelsArray; + wxString currentChar; + wxString tmp; + bool wrappedInQuotes, antislash; + + if (labels.IsEmpty()) + return seclabelsArray; + + // parse the labels string + // we start at 1 and stop at length-1 to get rid of the { and } of the array + for (unsigned int index = 1 ; index < labels.Length() - 1 ; index++) + { + // get current char + currentChar = labels.Mid(index, 1); + + // if there is a double quote at the beginning of a label, + // the whole label will be wrapped in quotes + if (currentChar == wxT("\"") && tmp.IsEmpty()) + wrappedInQuotes = true; + else if (currentChar == wxT("\\") && wrappedInQuotes) + antislash = true; + else + { + if ((currentChar == wxT(",") && !wrappedInQuotes && !tmp.IsEmpty()) + || (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty())) + { + // put new label in the array + labelsArray.Add(tmp); + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + } + else + tmp += currentChar; + antislash = false; + } + } + + // last label + if (!tmp.IsEmpty()) + { + // put last label in the array + labelsArray.Add(tmp); + } + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + + // parse the providers string + // we start at 1 and stop at length-1 to get rid of the { and } of the array + for (unsigned int index = 1 ; index < providers.Length() - 1 ; index++) + { + // get current char + currentChar = providers.Mid(index, 1); + + // if there is a double quote at the beginning of a provider, + // the whole provider will be wrapped in quotes + if (currentChar == wxT("\"") && tmp.IsEmpty()) + wrappedInQuotes = true; + else if (currentChar == wxT("\\") && wrappedInQuotes) + antislash = true; + else + { + if ((currentChar == wxT(",") && !wrappedInQuotes && !tmp.IsEmpty()) + || (currentChar == wxT("\"") && wrappedInQuotes && !antislash && !tmp.IsEmpty())) + { + // put new provider in the array + providersArray.Add(tmp); + + // reinit tmp + tmp = wxEmptyString; + wrappedInQuotes = false; + } + else + tmp += currentChar; + antislash = false; + } + } + + // last provider + if (!tmp.IsEmpty()) + { + // put last provider in the array + providersArray.Add(tmp); + } + + // now, build one wxArrayString from these two + for (unsigned int index = 0 ; index < providersArray.GetCount() ; index++) + { + seclabelsArray.Add(providersArray.Item(index)); + seclabelsArray.Add(labelsArray.Item(index)); + } + + // return the final one + return seclabelsArray; +} + + +wxString pgObject::GetSeqLabelsSql() +{ + wxString sql = wxEmptyString; + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + sql += wxT("SECURITY LABEL FOR ") + seclabels.Item(index) + + wxT("\n ON ") + GetTypeName().Upper() + wxT(" ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(seclabels.Item(index + 1)) + wxT(";\n"); + } + } + + return sql; +} + + +wxString pgObject::GetPrivileges(const wxString &allPattern, const wxString &str, const wxString &grantOnObject, const wxString &user, const wxString &column) +{ + wxString aclWithGrant, aclWithoutGrant; + + const wxChar *p = str.c_str(); + while (*p) + { + if (allPattern.Find(*p) >= 0) + { + if (p[1] == (wxChar)'*') + aclWithGrant += *p; + else + aclWithoutGrant += *p; + } + p++; + if (*p == (wxChar)'*') + p++; + } + + wxString grant; + if (!aclWithoutGrant.IsEmpty() || aclWithGrant.IsEmpty()) + grant += GetPrivilegeGrant(allPattern, aclWithoutGrant, grantOnObject, user, column) + wxT(";\n"); + if (!aclWithGrant.IsEmpty()) + grant += GetPrivilegeGrant(allPattern, aclWithGrant, grantOnObject, user, column) + wxT(" WITH GRANT OPTION;\n"); + + return grant; +} + + +wxString pgObject::GetGrant(const wxString &allPattern, const wxString &_grantFor, const wxString &_column) +{ + wxString grant, str, user, grantFor, tmpUser; + + if (_grantFor.IsNull()) + { + grantFor = GetTypeName(); + grantFor.MakeUpper(); + grantFor += wxT(" ") + GetQuotedFullIdentifier(); + } + else + grantFor = _grantFor; + + if (!acl.IsNull()) + { + if (acl == wxT("{}")) + { + grant += GetPrivileges(allPattern, str, grantFor, wxT("public"), qtIdent(_column)); + grant += GetPrivileges(allPattern, str, grantFor, qtIdent(owner), qtIdent(_column)); + } + else + { + // checks if certain privilege is granted to public + bool grantedToPublic = false; + // checks if certain privilege is granted to owner + bool grantedToOwner = false; + + //queryTokenizer acls(acl.Mid(1, acl.Length() - 2), ','); + wxSortedArrayString acls(wxSplit(acl.Mid(1, acl.Length() - 2),',')); + + //while (acls.HasMoreTokens()) + for (int j=0;jconnection(); + + pgServer *server; + + if (IsCreatedBy(serverFactory)) + server = (pgServer *)this; + else + server = GetServer(); + + if (server) + return server->connection(); + return 0; +} + + +bool pgObject::CheckOpenDialogs(ctlTree *browser, wxTreeItemId node) +{ + pgObject *obj = browser->GetObject(node); + if (obj && obj->GetWindowPtr()) + return true; + + wxTreeItemIdValue cookie; + wxTreeItemId child = browser->GetFirstChild(node, cookie); + + while (child.IsOk()) + { + obj = browser->GetObject(child); + if (obj && obj->GetWindowPtr()) + return true; + + wxTreeItemIdValue subCookie; + wxTreeItemId subChildItem = browser->GetFirstChild(child, subCookie); + if (browser->IsExpanded(child)) + { + if (CheckOpenDialogs(browser, child)) + return true; + } + // It may be the case the user might have expanded the node opened the + // dialog and then collapsed the node again. This case is handled in the + // check below + else if (subChildItem && browser->GetItemData(subChildItem)) + { + if (CheckOpenDialogs(browser, child)) + return true; + } + + child = browser->GetNextChild(node, cookie); + } + + return false; +} + +////////////////////////////////////////////////////////////// + +bool pgServerObject::CanDrop() +{ + if (GetMetaType() == PGM_DATABASE) + return (server->GetCreatePrivilege() || server->GetSuperUser()); + else + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else + return server->GetSuperUser(); + } +} + + +bool pgServerObject::CanCreate() +{ + if (GetMetaType() == PGM_DATABASE) + return (server->GetCreatePrivilege() || server->GetSuperUser()); + else + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else + return server->GetSuperUser(); + } +} + + +void pgServerObject::FillOwned(ctlTree *browser, ctlListView *referencedBy, const wxArrayString &dblist, const wxString &query) +{ + pgCollection *databases = 0; + + wxCookieType cookie; + wxTreeItemId item = browser->GetFirstChild(GetServer()->GetId(), cookie); + while (item) + { + databases = (pgCollection *)browser->GetObject(item); + if (databases && databases->GetMetaType() == PGM_DATABASE) + break; + else + databases = 0; + + item = browser->GetNextChild(GetServer()->GetId(), cookie); + } + + size_t i; + for (i = 0 ; i < dblist.GetCount() ; i++) + { + wxString dbname = dblist.Item(i); + pgConn *conn = 0; + pgConn *tmpConn = 0; + + if (GetServer()->GetDatabaseName() == dbname) + conn = GetServer()->GetConnection(); + else + { + item = browser->GetFirstChild(databases->GetId(), cookie); + while (item) + { + pgDatabase *db = (pgDatabase *)browser->GetObject(item); + if (db && db->GetMetaType() == PGM_DATABASE && db->GetName() == dbname) + { + if (db->GetConnected()) + conn = db->GetConnection(); + break; + } + item = browser->GetNextChild(databases->GetId(), cookie); + } + } + if (conn && conn->GetStatus() != PGCONN_OK) + conn = 0; + + if (!conn) + { + tmpConn = GetServer()->CreateConn(dbname); + conn = tmpConn; + } + + if (conn) + { + pgSet *set = conn->ExecuteSet(query); + + if (set) + { + while (!set->Eof()) + { + wxString relname = qtIdent(set->GetVal(wxT("nspname"))); + if (!relname.IsEmpty()) + relname += wxT("."); + relname += qtIdent(set->GetVal(wxT("relname"))); + pgaFactory *ownerFactory = 0; + + switch ( (wxChar)set->GetVal(wxT("relkind")).c_str()[0]) + { + case 'r': + ownerFactory = &tableFactory; + break; + case 'i': + ownerFactory = &indexFactory; + relname = qtIdent(set->GetVal(wxT("indname"))) + wxT(" ON ") + relname; + break; + case 'S': + ownerFactory = &sequenceFactory; + break; + case 'v': + ownerFactory = &viewFactory; + break; + case 'x': + ownerFactory = &extTableFactory; + break; + case 'c': // composite type handled in PG_TYPE + case 's': // special + case 't': // toast + break; + case 'n': + ownerFactory = &schemaFactory; + break; + case 'y': + ownerFactory = &typeFactory; + break; + case 'd': + ownerFactory = &domainFactory; + break; + case 'C': + ownerFactory = &conversionFactory; + break; + case 'p': + ownerFactory = &functionFactory; + break; + case 'T': + ownerFactory = &triggerFunctionFactory; + break; + case 'o': + ownerFactory = &operatorFactory; + relname = set->GetVal(wxT("relname")); // unquoted + break; + } + + if (ownerFactory) + { + wxString typname; + int icon; + typname = ownerFactory->GetTypeName(); + icon = ownerFactory->GetIconId(); + referencedBy->AppendItem(icon, typname, dbname, relname); + } + + set->MoveNext(); + } + delete set; + } + } + + if (tmpConn) + delete tmpConn; + } +} + +////////////////////////////////////////////////////////////// + +pgServer *pgDatabaseObject::GetServer() const +{ + return database->GetServer(); +} + + +bool pgDatabaseObject::CanDrop() +{ + return (database->GetCreatePrivilege() && (GetMetaType() != PGM_CATALOG)); +} + + +bool pgDatabaseObject::CanCreate() +{ + return database->GetCreatePrivilege(); +} + + +wxString pgDatabaseObject::GetSchemaPrefix(const wxString &schemaname) const +{ + return database->GetSchemaPrefix(schemaname); +} + + +wxString pgDatabaseObject::GetQuotedSchemaPrefix(const wxString &schemaname) const +{ + return database->GetQuotedSchemaPrefix(schemaname); +} + + +void pgDatabaseObject::DisplayStatistics(ctlListView *statistics, const wxString &query) +{ + if (statistics) + { + wxLogInfo(wxT("Displaying statistics for %s %s"), GetTypeName().c_str(), GetFullIdentifier().c_str()); + + // Add the statistics view columns + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = database->ExecuteSet(query); + + if (stats) + { + int col; + for (col = 0 ; col < stats->NumCols() ; col++) + { + if (!stats->ColName(col).IsEmpty()) + statistics->AppendItem(stats->ColName(col), stats->GetVal(col)); + } + delete stats; + } + } +} + + +/////////////////////////////////////////////////////////////// + +void pgSchemaObject::SetSchema(pgSchema *newSchema) +{ + schema = newSchema; + database = schema->GetDatabase(); +} + + +void pgSchemaObject::UpdateSchema(ctlTree *browser, OID schemaOid) +{ + // used e.g. for triggers that use trigger functions from other namespaces + if (!browser) + return; + + if (schema->GetOid() != schemaOid) + { + pgObject *schemas = browser->GetObject(browser->GetItemParent(schema->GetId())); + + wxASSERT(schemas); + treeObjectIterator schIt(browser, schemas); + pgSchema *sch; + + while ((sch = (pgSchema *)schIt.GetNextObject()) != 0) + { + if (sch->GetOid() == schemaOid) + { + SetSchema(sch); + return; + } + } + + // If we get this far, it's possible the schema is actually a catalog + // in this case. We need to find the catalogs node and then search that. + pgObject *db = browser->GetObject(browser->GetItemParent(schemas->GetId())); + + wxASSERT(db); + treeObjectIterator catsIt(browser, db); + pgObject *catalogs; + + while ((catalogs = (pgObject *)catsIt.GetNextObject()) != 0) + { + if (catalogs->GetMetaType() == PGM_CATALOG) + break; + } + + // Assuming we got the catalogs node, now get the catalog + if (catalogs) + { + treeObjectIterator catIt(browser, catalogs); + pgCatalog *cat; + + while ((cat = (pgCatalog *)catIt.GetNextObject()) != 0) + { + if (cat->GetOid() == schemaOid) + { + SetSchema((pgSchema *)cat); + return; + } + } + } + + wxMessageBox(_("The schema oid can't be located, please refresh all schemas!"), + _("Missing information"), wxICON_EXCLAMATION | wxOK, browser); + } +} + + +bool pgSchemaObject::GetSystemObject() const +{ + if (!schema) + return false; + return GetOid() < GetConnection()->GetLastSystemOID(); +} + + +bool pgSchemaObject::CanDrop() +{ + return schema->GetCreatePrivilege() && schema->GetMetaType() != PGM_CATALOG; +} + + +bool pgSchemaObject::CanCreate() +{ + return schema->GetCreatePrivilege() && schema->GetMetaType() != PGM_CATALOG; +} + + +void pgSchemaObject::SetContextInfo(frmMain *form) +{ +// form->SetDatabase(schema->GetDatabase()); +} + +pgSet *pgSchemaObject::ExecuteSet(const wxString &sql) +{ + return schema->GetDatabase()->ExecuteSet(sql); +} + +wxString pgSchemaObject::ExecuteScalar(const wxString &sql) +{ + return schema->GetDatabase()->ExecuteScalar(sql); +} + +bool pgSchemaObject::ExecuteVoid(const wxString &sql) +{ + return schema->GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgSchemaObject::GetFullIdentifier() const +{ + return schema->GetPrefix() + GetName(); +} + + +wxString pgSchemaObject::GetQuotedFullIdentifier() const +{ + if (schema->GetTypeName() == wxT("Table")) + return schema->GetSchema()->GetQuotedPrefix() + GetQuotedIdentifier(); + else + return schema->GetQuotedPrefix() + GetQuotedIdentifier(); +} + + + + +enum tokentype +{ + SQLTK_NORMAL = 0, + SQLTK_JOINMOD, + SQLTK_JOIN, + SQLTK_ON, + SQLTK_UNION + +}; + +typedef struct __tokenaction +{ + const wxChar *keyword, *replaceKeyword; + int actionBefore, actionAfter; + tokentype special; + bool doBreak; +} tokenAction; + + +tokenAction sqlTokens[] = +{ + { wxT("WHERE")}, // initializing fails, so we're doing it in the code + { wxT("SELECT"), wxT(" SELECT"), 0, 8, SQLTK_NORMAL, true}, + { wxT("FROM"), wxT(" FROM"), -8, 8, SQLTK_NORMAL, true}, + { wxT("LEFT"), wxT(" LEFT"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("RIGHT"), wxT(" RIGHT"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("NATURAL"), wxT(" NATURAL"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("FULL"), wxT(" FULL"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("CROSS"), wxT(" CROSS"), -8, 13, SQLTK_JOINMOD, true}, + { wxT("UNION"), wxT(" UNION"), -8, 13, SQLTK_UNION, true}, + { wxT("JOIN"), wxT(" JOIN"), -8, 13, SQLTK_JOIN, true}, + { wxT("ON"), wxT("ON"), 0, -5, SQLTK_ON, false}, + { wxT("ORDER"), wxT(" ORDER"), -8, 8, SQLTK_NORMAL, true}, + { wxT("GROUP"), wxT(" GROUP"), -8, 8, SQLTK_NORMAL, true}, + { wxT("HAVING"), wxT(" HAVING"), -8, 8, SQLTK_NORMAL, true}, + { wxT("LIMIT"), wxT(" LIMIT"), -8, 8, SQLTK_NORMAL, true}, + { wxT("CASE"), wxT("CASE"), 0, 4, SQLTK_NORMAL, true}, + { wxT("WHEN"), wxT("WHEN"), 0, 0, SQLTK_NORMAL, true}, + { wxT("ELSE"), wxT("ELSE"), 0, 0, SQLTK_NORMAL, true}, + { wxT("END"), wxT("END "), -4, 0, SQLTK_NORMAL, true}, + {0, 0, 0, 0, SQLTK_NORMAL, false} +}; + +tokenAction secondOnToken = +{ wxT("ON"), wxT("ON"), -5, 0, SQLTK_ON, true}; + + + +wxString pgRuleObject::GetFormattedDefinition() +{ + // pgsql 7.4 does formatting itself + if (!GetDatabase()->GetPrettyOption().IsEmpty()) + return GetDefinition(); + + //////////////////////////////// + // ok, this code looks weird. It's necessary, because somebody (NOT the running code) + // will screw up that entry. It's broken in pgAdmin3::OnInit() already. + // maybe your compiler does better (VC6SP5, but an older c2xx to avoid other bugs) + + sqlTokens[0].replaceKeyword = wxT(" WHERE"); + sqlTokens[0].actionBefore = -8; + sqlTokens[0].actionAfter = 8; + sqlTokens[0].special = SQLTK_NORMAL; + sqlTokens[0].doBreak = true; + + wxString fc, token; + queryTokenizer tokenizer(GetDefinition()); + int indent = 0; + int position = 0; // col position. updated, but not used at the moment. + bool wasOn = false; + + while (tokenizer.HasMoreTokens()) + { + token = tokenizer.GetNextToken(); + +gotToken: + wxString trailingChars; + + // token may contain brackets + int bracketPos; + bracketPos = token.Find('(', true); + while (bracketPos >= 0) + { + fc += token.Left(bracketPos + 1); + token = token.Mid(bracketPos + 1); + bracketPos = token.Find('(', true); + } + + bracketPos = token.Find(')', true); + while (bracketPos >= 0) + { + trailingChars = token.Mid(bracketPos) + trailingChars; + token = token.Left(bracketPos); + bracketPos = token.Find(')', true); + } + // identify token + tokenAction *tp = sqlTokens; + while (tp->keyword) + { + if (!token.CmpNoCase(tp->keyword)) + { + if (tp->special == SQLTK_ON && wasOn) + tp = &secondOnToken; + else + wasOn = (tp->special == SQLTK_ON); + break; + } + tp++; + } + + if (tp && tp->keyword) + { + // we found a keyword. + if (tp->special == SQLTK_UNION || tp->special == SQLTK_JOINMOD) + { + token = tokenizer.GetNextToken(); + if (tp->special == SQLTK_UNION && token.CmpNoCase(wxT("JOIN"))) + { + fc += wxT("\nUNION\n"); + indent = 0; + goto gotToken; + } + else + { + trailingChars = token + wxT(" ") + trailingChars; + indent += tp->actionBefore; + if (indent < 0) indent = 0; + } + } + else + { + indent += tp->actionBefore; + if (indent < 0) indent = 0; + } + if (tp->doBreak) + { + fc += wxT("\n") + wxString(' ', (size_t)indent); + position = indent; + } + else + { + fc += wxT(" "); + position += 1; + } + fc += tp->replaceKeyword; + position += wxString(tp->replaceKeyword).Length(); + + indent += tp->actionAfter; + if (indent < 0) indent = 0; + } + else + { + fc += token; + position += token.Length(); + } + fc += wxT(" "); + position++; + if (!trailingChars.IsNull()) + { + fc += trailingChars + wxT(" ");; + position += trailingChars.Length() + 1; + } + } + return fc; +} + +wxString pgObject::qtDbString(const wxString &str) +{ + // Use the server aware version if possible + if (GetDatabase() && GetDatabase()->GetConnection()) + return GetDatabase()->GetConnection()->qtDbString(str); + else + { + wxString ret = str; + ret.Replace(wxT("\\"), wxT("\\\\")); + ret.Replace(wxT("'"), wxT("''")); + ret.Append(wxT("'")); + ret.Prepend(wxT("'")); + return ret; + } +} + +wxString pgObject::GetDefaultPrivileges(const wxString &strType, const wxString &strSupportedPrivs, + const wxString &strSchema, const wxString &strOrigDefPrivs, + const wxString &strNewDefPrivs, const wxString &strRole) +{ + wxString strDefPrivs, strGrant, strRevoke, strGrantOption, strRevokeGrantOption; + int privilegeCount = strSupportedPrivs.Length(); + + for (int index = 0; index < privilegeCount; index++) + { + bool inOrigPriv = false, inNewPriv = false, grantOptInOrigPriv = false, grantOptInNewPriv = false; + wxChar privChar = strSupportedPrivs.GetChar(index); + int privAt = strOrigDefPrivs.Find(privChar); + if (privAt != wxNOT_FOUND) + { + inOrigPriv = true; + if ((unsigned int)privAt < strOrigDefPrivs.Length() - 1 && + strOrigDefPrivs.GetChar(privAt + 1) == wxT('*')) + grantOptInOrigPriv = true; + } + + privAt = strNewDefPrivs.Find(privChar); + if (privAt != wxNOT_FOUND) + { + inNewPriv = true; + if ((unsigned int)privAt < strNewDefPrivs.Length() - 1 && + strNewDefPrivs.GetChar(privAt + 1) == wxT('*')) + grantOptInNewPriv = true; + } + if (inOrigPriv || inNewPriv || grantOptInOrigPriv || grantOptInNewPriv) + { + wxString strPrivilege = GetPrivilegeName(privChar); + if (!inOrigPriv && inNewPriv) + { + // GRANT PRIVILEGES + if (!grantOptInNewPriv) + strGrant += strPrivilege + wxT(", "); + // GRANT PRVILEGES WITH GRANT OPTION + else + strGrantOption += strPrivilege + wxT(", "); + } + // REVOKE PRIVILEGES + else if (inOrigPriv && !inNewPriv) + strRevoke += strPrivilege + wxT(", "); + else if (inOrigPriv && inNewPriv) + { + // REVOKE ONLY 'WITH GRANT OPTION' + if(grantOptInOrigPriv && !grantOptInNewPriv) + strRevokeGrantOption += strPrivilege + wxT(", "); + // GRANT PRVILEGES WITH GRANT OPTION + else if (!grantOptInOrigPriv && grantOptInNewPriv) + strGrantOption += strPrivilege + wxT(", "); + } + } + } + + bool isModified = false; + wxString strAltDefPriv; + + if (!strSchema.IsEmpty()) + strAltDefPriv = wxT("ALTER DEFAULT PRIVILEGES IN SCHEMA ") + strSchema; + else + strAltDefPriv = wxT("ALTER DEFAULT PRIVILEGES "); + + if (!strRevoke.IsEmpty()) + { + isModified = true; + strRevoke = strRevoke.SubString(0, strRevoke.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n REVOKE ") + strRevoke + wxT(" ON ") + strType + + wxT("\n FROM ") + strRole + wxT(";\n"); + } + if (!strRevokeGrantOption.IsEmpty()) + { + isModified = true; + strRevokeGrantOption = strRevokeGrantOption.SubString(0, strRevokeGrantOption.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n REVOKE GRANT OPTION FOR ") + strRevokeGrantOption + wxT(" ON ") + strType + + wxT("\n FROM ") + strRole + wxT(";\n"); + } + if (!strGrant.IsEmpty()) + { + isModified = true; + + strGrant = strGrant.SubString(0, strGrant.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n GRANT ") + strGrant + wxT(" ON ") + strType + + wxT("\n TO ") + strRole + wxT(";\n"); + } + if (!strGrantOption.IsEmpty()) + { + isModified = true; + strGrantOption = strGrantOption.SubString(0, strGrantOption.Length() - 3); + strDefPrivs += strAltDefPriv + + wxT("\n GRANT ") + strGrantOption + wxT(" ON ") + strType + + wxT("\n TO ") + strRole + wxT(" WITH GRANT OPTION;\n"); + } + if (isModified) + return strDefPrivs + wxT("\n"); + + return wxT(""); +} + +// Find the user-privileges pair from ACLs +// i.e. {=wDx/user1,postgres=adDxt/user1} +// Remove starting and ending curly braces, before supplying as the input +bool pgObject::findUserPrivs(wxString &strDefPrivs, wxString &strUser, wxString &strPriv) +{ + strUser = strPriv = wxT(""); + if (strDefPrivs.IsEmpty()) return false; + + bool startsWithQuote = false; + if (strDefPrivs.StartsWith(wxT("\""))) startsWithQuote = true; + + if (strDefPrivs.StartsWith(wxT("\"\""))) + { + wxChar currChar; + int quoteCount = 0; + int index = 0; + + currChar = strDefPrivs.GetChar(index); + + while (true) + { + if (currChar == wxT('=') && quoteCount % 2 == 0) + break; + strUser += currChar; + currChar = strDefPrivs.GetChar(++index); + if (currChar == wxT('"')) quoteCount++; + } + strUser = strUser.SubString(2, strUser.Length() - 2); + strUser.Replace(wxT("\"\""), wxT("\""), true); + strDefPrivs = strDefPrivs.SubString(index + 1, strDefPrivs.Length()); + } + else + { + /* Remove first quote */ + if (startsWithQuote) strDefPrivs = strDefPrivs.SubString(1, strDefPrivs.Length()); + + int equalCharAt = strDefPrivs.Find(wxT('=')); + + if (equalCharAt != 0) + strUser = strDefPrivs.SubString(0, equalCharAt - 1); + else + strUser = wxT("public"); + strDefPrivs = strDefPrivs.SubString(equalCharAt + 1, strDefPrivs.Length()); + } + + int slashCharAt = strDefPrivs.Find(wxT('/')); + strPriv = strDefPrivs.SubString(0, slashCharAt - 1); + + strDefPrivs = strDefPrivs.SubString(strPriv.Length() + 2, strDefPrivs.Length()); + + if (!strDefPrivs.StartsWith(wxT("\""))) + { + int commaCharAt = strDefPrivs.Find(wxT(',')); + if (commaCharAt == wxNOT_FOUND) strDefPrivs = wxT(""); + else strDefPrivs = strDefPrivs.SubString(commaCharAt + 1, strDefPrivs.Length()); + } + else + { + wxChar currChar; + int quoteCount = 0; + int index = 0; + + currChar = strDefPrivs.GetChar(index); + while (true) + { + if (currChar == wxT(',') && quoteCount % 2 == 0) + break; + currChar = strDefPrivs.GetChar(++index); + if (currChar == wxT('"')) quoteCount++; + } + strDefPrivs = strDefPrivs.SubString(index, strDefPrivs.Length()); + } + + return true; +} + +wxString pgObject::GetPrivilegeName(wxChar privilege) +{ + switch(privilege) + { + case 'a': + return wxT("INSERT"); + case 'r': + return wxT("SELECT"); + case 'w': + return wxT("UPDATE"); + case 'd': + return wxT("DELETE"); + case 'D': + return wxT("TRUNCATE"); + case 'x': + return wxT("REFERENCES"); + case 't': + return wxT("TRIGGER"); + case 'U': + return wxT("USAGE"); + case 'X': + return wxT("EXECUTE"); + default: + return wxT("UNKNOWN"); + } +} + +void pgObject::SetWindowPtr(dlgProperty *dlgprop) +{ + dlg = dlgprop; +} +wxString pgObject::GetSqlReCreate(frmMain *form, pgObject *obj) +{ + pgConn *conn = GetConnection(); + if (conn) + { + int status = conn->GetStatus(); + if (status == PGCONN_BROKEN || status == PGCONN_BAD) + { + form->SetStatusText(_(" Connection broken.")); + return wxT("");; + } + } + wxLogInfo(wxT("Recreate cascade object for %s %s"), GetTypeName().c_str(), GetIdentifier().c_str()); + + wxString sql; + wxString line; + ctlTree *browser=form->GetBrowser(); + wxString databasePath = form->GetNodePath(obj->GetDatabase()->GetId()); +// ïîëó÷åíèå ïðàâèëà è îò íåãî óæå çàâèñèìîñòè áóäåì ðàñêðó÷èâàòü + int colcount = 0; + pgSetIterator set(GetConnection(), + wxT("WITH RECURSIVE t(lvl,classid,objid,type_child) AS (\n") + wxT(" select 1,c_classid::regclass,c_objid,type_child from (\n") + wxT(" select dd.*\n") + wxT(" ,(pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type type_child\n") + wxT(" ,rule_to_view.classid c_classid\n") + wxT(" ,rule_to_view.objid c_objid\n") + wxT(" from pg_depend dd, lateral \n") + wxT(" pg_get_object_address(case when (pg_identify_object_as_address(classid, objid, objsubid)).type='rule' then 'view' \n") + wxT(" else (pg_identify_object_as_address(classid, objid, objsubid)).type end , \n") + wxT(" case when (pg_identify_object_as_address(classid, objid, objsubid)).type='rule' then \n") + wxT(" (pg_identify_object_as_address(classid, objid, objsubid)).object_names[1:2]\n") + wxT(" else (pg_identify_object_as_address(classid, objid, objsubid)).object_names\n") + wxT(" end\n") + wxT(" ,(pg_identify_object_as_address(classid, objid, objsubid)).object_args)\n") + wxT(" rule_to_view\n") + wxT(" where dd.deptype='n' and dd.refobjid=") + GetOidStr() + wxT("\n") + wxT(" ) d\n") + wxT(" where d.refobjid<>d.c_objid\n") + wxT(" group by c_classid,c_objid,type_child\n") + wxT("UNION ALL\n") + wxT("select lvl+1,c_classid::regclass classid,c_objid,type_child from (\n") + wxT(" select dd.*\n") + wxT(" ,(pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type type_child\n") + wxT(" ,rule_to_view.classid c_classid\n") + wxT(" ,rule_to_view.objid c_objid\n") + wxT(" ,t.lvl\n") + wxT(" from pg_depend dd,t, lateral \n") + wxT(" pg_get_object_address(case when (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type='rule' then 'view' \n") + wxT(" else (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type end , \n") + wxT(" case when (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).type='rule' then \n") + wxT(" (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).object_names[1:2]\n") + wxT(" else (pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).object_names\n") + wxT(" end\n") + wxT(" ,(pg_identify_object_as_address(dd.classid, dd.objid, dd.objsubid)).object_args)\n") + wxT(" rule_to_view\n") + wxT(" where dd.deptype='n' and dd.refobjid=t.objid\n") + wxT(" ) d\n") + wxT(" where d.refobjid<>d.c_objid\n") + wxT(" group by c_classid,c_objid,type_child,lvl\n") + wxT(") select t.*,coalesce(cc.conname,vv.relname,tt.tgname) objname,coalesce(cc.connamespace::regnamespace,vv.relnamespace::regnamespace)::text sch\n") + wxT(",coalesce(cc.conrelid::regclass) parent,coalesce(vv.relkind) kind from t\n") + wxT("left join pg_constraint cc on t.classid='pg_constraint'::regclass and t.objid=cc.oid\n") + wxT("left join pg_class vv on (t.classid='pg_class'::regclass and t.objid=vv.oid) or (cc.conrelid=vv.oid)\n") + wxT("left join pg_trigger tt on t.classid='pg_trigger'::regclass and t.objid=tt.oid\n") + wxT("") + wxT("") + wxT("order by 1 desc,2 asc;") + ); + + // lvl;classid;objid;child_type;objname;sch;parent + sql=wxT("-- "); + pgCollection *database = 0; + wxTreeItemId dbitem = obj->GetDatabase()->GetId(); + //pgCollection *collect = 0; + pgCollection *collectSchEl = 0; + wxCookieType cookie; + pgCollection *collect= browser->FindCollection(schemaFactory,dbitem); + + wxTreeItemId item = browser->GetFirstChild(dbitem, cookie); +if (1==0) { + while (item) + { + collect = (pgCollection *)browser->GetObject(item); + if (collect && collect->GetMetaType() == PGM_SCHEMA) + break; + else + collect = 0; + item = browser->GetNextChild(dbitem, cookie); + } +} + wxString findobj=wxT(","); + wxString dropblock=wxT("-- Óäàëåíèå çàâèñèìûõ îáúåêòîâ\n"); + wxString createblock=wxEmptyString; + while (set.RowsLeft()) + { + wxString refname = set.GetVal(wxT("objname")); + wxString parent = set.GetVal(wxT("parent")); + wxString type = set.GetVal(wxT("type_child")); + wxString kind = set.GetVal(wxT("kind")); + wxString sxema = parent.BeforeFirst('.'); + wxString table = parent.AfterFirst('.'); + if (sxema.IsEmpty()) { + sxema=set.GetVal(wxT("sch")); + table=refname; + } + pgaFactory *depFactory = 0; + if (refname.IsEmpty()) + continue; + if (findobj.Contains(wxT(",")+table+wxT(".")+refname+wxT(","))) continue; + //pgaCollectionFactory + + item = browser->GetFirstChild(collect->GetId(), cookie); + while (item) + { + collectSchEl = (pgCollection *)browser->GetObject(item); + if (collectSchEl && collectSchEl->GetMetaType() == PGM_SCHEMA && collectSchEl->GetName()==sxema) + { + pgCollection *coll= 0; + wxString whatfindt; + wxString tmpsql; + wxString fn=collectSchEl->GetFullName(); + if (type.Contains(wxT("rule"))||(type.Contains(wxT("view")))) whatfindt=wxT("...bb"); + if (type.Contains(wxT("table constraint"))) { + //coll=browser->FindCollection(tableFactory,item); + whatfindt=wxT("Tables"); + } + // look for the item starting with the given prefix after it + + + wxTreeItemId id=item; + while ( id.IsOk() && + ( browser->GetItemText(id) == wxT("Dummy") && !browser->GetItemData(id) + || true )) + { + pgObject *oo= ((pgObject *) browser->GetItemData(id)); + if (oo) { + pgaFactory *ff=oo->GetFactory(); + fn=ff->GetTypeName(); + fn=oo->GetName(); + if (fn==wxT("debug*history__0102")) { + fn=oo->GetFullName(); + pgaFactory *ff=oo->GetFactory(); + fn=ff->GetTypeName(); + if (ff==&pg_partitionFactory) { + fn=oo->GetFullName(); + }; + //oo->ShowTreeDetail(browser); + } + if ((oo->GetFactory()==&viewFactory || oo->GetFactory()==&tableFactory + || oo->GetFactory()==&pg_partitionFactory ) + && fn==table) { + break; + } + } + wxCookieType cookie; + if ( browser->HasChildren(id) &&((oo->GetFactory()==&viewFactory || oo->GetFactory()==&tableFactory + || oo->GetFactory()==&pg_partitionFactory + || oo->GetFactory()==&schemaFactory + ||oo->GetFactory()->GetTypeName()==whatfindt + ||oo->GetFactory()->GetTypeName()==wxT("Constraints") + ||oo->GetFactory()->GetTypeName()==wxT("Partitions") + ||oo->GetFactory()->GetTypeName()==wxT("Views") + ))) + { + if (oo) oo->ShowTreeDetail(browser); + id = browser->GetFirstChild(id, cookie); + } + else + { + // Try a sibling of this or ancestor instead + wxTreeItemId p = id; + wxTreeItemId toFind; + do + { + toFind = browser->GetNextSibling(p); + p = browser->GetItemParent(p); + } + while (p.IsOk() && !toFind.IsOk()); + id = toFind; + } + } + if ( id.IsOk() ) { + // íàéäåí íóæíûé ýëåìíò + pgObject *db=(pgTable *) browser->GetItemData(id); + if (kind=='r') { + // "table constraint" + pgTable *tbl=(pgTable *) db; + tbl->ShowTreeDetail(browser); + pgCollection *cll=tbl->GetConstraintCollection(browser); + if (cll) { + fn=cll->GetFullName(); + } + wxTreeItemId matchItem = browser->FindItem(cll->GetId(),refname); + if ( matchItem.IsOk() ) { + pgObject *o=browser->GetObject(matchItem); + //fn=o->GetName()+wxT(" - type : ")+o->GetTypeName(); + //sql+=fn+wxT("\n"); + tmpsql=browser->GetObject(matchItem)->GetSql(browser); + } + + } + else + { + tmpsql=db->GetSql(browser); + + } + } else { + // íå íàéäåò â äåðåâå ýëåìåíò ñ óêàçàííûì èìåíåì + + } + findobj=findobj+table+wxT(".")+refname+wxT(","); + wxStringTokenizer rowslist(tmpsql, wxT("\n"),wxTOKEN_RET_EMPTY ); + wxString cn; + wxString distributionColumns; + wxString createblocktmp=wxEmptyString; + int i=1; + while (rowslist.HasMoreTokens()) + { + cn = rowslist.GetNextToken(); + if (i==1) { + createblocktmp+=cn+wxT("\n"); + dropblock+=cn+wxT("\n"); + i++; + continue; + } + if (i==3) { + dropblock+=cn.Mid(3)+wxT("\n"); + i++; + continue; + } + createblocktmp+=cn+wxT("\n"); + i++; + } + createblock=createblocktmp+createblock; +// if (node->IsCollection()) +// owneritem = browser->GetParentObject(node->GetId())->GetId(); +// else +// owneritem = browser->GetParentObject(browser->GetParentObject(node->GetId())->GetId())->GetId(); + } + else + collectSchEl = 0; + item = browser->GetNextChild(collect, cookie); + } + + } + + sql+=dropblock+wxT("\n\n\n")+wxT("-- Ñîçäàíèå çàâèñèìûõ îáúåêòîâ(â îáðàòíîì ïîðÿäêå)\n")+createblock; + return sql; +} diff --git a/schema/pgOperator.cpp b/schema/pgOperator.cpp new file mode 100644 index 0000000..0cda743 --- /dev/null +++ b/schema/pgOperator.cpp @@ -0,0 +1,379 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperator.cpp - Operator class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgOperator.h" + + +pgOperator::pgOperator(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, operatorFactory, newName) +{ +} + +pgOperator::~pgOperator() +{ +} + +wxString pgOperator::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop operator cascaded?"); + break; + case DROPTITLE: + message = _("Drop operator?"); + break; + case PROPERTIESREPORT: + message = _("Operator properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Operator properties"); + break; + case DDLREPORT: + message = _("Operator DDL report"); + message += wxT(" - ") + GetName();; + break; + case DDL: + message = _("Operator DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Operator dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Operator dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Operator dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Operator dependents"); + break; + } + + return message; +} + +bool pgOperator::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP OPERATOR ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetIdentifier(); + + if (GetLeftType().Length() > 0) + sql += wxT(" (") + qtTypeIdent(GetLeftType()); + else + sql += wxT(") (NONE"); + + if (GetRightType().Length() > 0) + sql += wxT(", ") + qtTypeIdent(GetLeftType()) + wxT(")"); + else + sql += wxT(", NONE)"); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgOperator::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Operator: ") + GetQuotedFullIdentifier() + wxT("(") + GetOperands() + wxT(")\n\n") + + wxT("-- DROP OPERATOR ") + GetQuotedFullIdentifier() + + wxT("(") + GetOperands() + wxT(");\n\n") + wxT("CREATE OPERATOR ") + GetQuotedFullIdentifier() + + wxT("(\n PROCEDURE = ") + GetOperatorFunction(); + AppendIfFilled(sql, wxT(",\n LEFTARG = "), qtTypeIdent(GetLeftType())); + AppendIfFilled(sql, wxT(",\n RIGHTARG = "), qtTypeIdent(GetRightType())); + AppendIfFilled(sql, wxT(",\n COMMUTATOR = "), GetCommutator()); + AppendIfFilled(sql, wxT(",\n NEGATOR = "), GetNegator()); + AppendIfFilled(sql, wxT(",\n RESTRICT = "), GetRestrictFunction()); + AppendIfFilled(sql, wxT(",\n JOIN = "), GetJoinFunction()); + if (GetHashJoins()) sql += wxT(",\n HASHES"); + if (GetMergeJoins()) sql += wxT(",\n MERGES"); + + if (!GetDatabase()->BackendMinimumVersion(8, 3)) + { + AppendIfFilled(sql, wxT(",\n SORT1 = "), GetLeftSortOperator()); + AppendIfFilled(sql, wxT(",\n SORT2 = "), GetRightSortOperator()); + AppendIfFilled(sql, wxT(",\n LTCMP = "), GetLessOperator()); + AppendIfFilled(sql, wxT(",\n GTCMP = "), GetGreaterOperator()); + } + + sql += wxT(");\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON OPERATOR ") + GetQuotedFullIdentifier() + + wxT("(") + GetOperands() + wxT(") IS ") + + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +wxString pgOperator::GetOperands() const +{ + wxString sql; + if (GetLeftType().IsEmpty()) + sql = wxT("NONE"); + else + sql = qtIdent(GetLeftType()); + sql += wxT(", "); + + if (GetRightType().IsEmpty()) + sql += wxT("NONE"); + else + sql += qtIdent(GetRightType()); + + return sql; +} +wxString pgOperator::GetFullName() +{ + if (leftType.IsEmpty() || rightType.IsEmpty()) + return GetName() + wxT(" (") + leftType + rightType + wxT(")"); + else + return GetName() + wxT(" (") + leftType + wxT(", ") + rightType + wxT(")"); +} + + +void pgOperator::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Kind"), GetKind()); + if (!leftType.IsNull()) + properties->AppendItem(_("Left type"), GetLeftType()); + if (!rightType.IsNull()) + properties->AppendItem(_("Right type"), GetRightType()); + properties->AppendItem(_("Result type"), GetResultType()); + properties->AppendItem(_("Operator function"), GetOperatorFunction()); + properties->AppendItem(_("Commutator"), GetCommutator()); + properties->AppendItem(_("Negator"), GetNegator()); + properties->AppendItem(_("Join function"), GetJoinFunction()); + properties->AppendItem(_("Restrict function"), GetRestrictFunction()); + + if (!GetDatabase()->BackendMinimumVersion(8, 3)) + { + properties->AppendItem(_("Left Sort operator"), GetLeftSortOperator()); + properties->AppendItem(_("Right Sort operator"), GetRightSortOperator()); + properties->AppendItem(_("Less Than operator"), GetLessOperator()); + properties->AppendItem(_("Greater than operator"), GetGreaterOperator()); + } + + properties->AppendYesNoItem(_("Supports hash?"), GetHashJoins()); + properties->AppendYesNoItem(_("Supports merge?"), GetMergeJoins()); + properties->AppendYesNoItem(_("System operator?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgOperator::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *oper = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + oper = operatorFactory.CreateObjects(coll, 0, wxT("\n AND op.oid=") + GetOidStr()); + + return oper; +} + + +////////////////////////////////////////////////////// + + +pgOperatorCollection::pgOperatorCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgOperatorCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operators"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operators"); + break; + case OBJECTSLISTREPORT: + message = _("Operators list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgOperatorFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgOperator *oper = 0; + + pgSet *operators; + if (collection->GetDatabase()->BackendMinimumVersion(8, 3)) + { + operators = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.oprname, pg_get_userbyid(op.oprowner) as opowner, op.oprkind, op.oprcanhash, op.oprcanmerge,\n") + wxT(" op.oprleft, op.oprright, lt.typname as lefttype, rt.typname as righttype, et.typname as resulttype,\n") + wxT(" co.oprname as compop, ne.oprname as negop,\n") + wxT(" op.oprcode as operproc, op.oprjoin as joinproc, op.oprrest as restrproc, description\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=op.oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=op.oprright\n") + wxT(" JOIN pg_type et on et.oid=op.oprresult\n") + wxT(" LEFT OUTER JOIN pg_operator co ON co.oid=op.oprcom\n") + wxT(" LEFT OUTER JOIN pg_operator ne ON ne.oid=op.oprnegate\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=op.oid AND des.classoid='pg_operator'::regclass)\n") + wxT(" WHERE op.oprnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY op.oprname")); + } + else + { + operators = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.oprname, pg_get_userbyid(op.oprowner) as opowner, op.oprkind, op.oprcanhash,\n") + wxT(" op.oprleft, op.oprright, lt.typname as lefttype, rt.typname as righttype, et.typname as resulttype,\n") + wxT(" co.oprname as compop, ne.oprname as negop, lso.oprname as leftsortop, rso.oprname as rightsortop,\n") + wxT(" lco.oprname as lscmpop, gco.oprname as gtcmpop,\n") + wxT(" op.oprcode as operproc, op.oprjoin as joinproc, op.oprrest as restrproc, description\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=op.oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=op.oprright\n") + wxT(" JOIN pg_type et on et.oid=op.oprresult\n") + wxT(" LEFT OUTER JOIN pg_operator co ON co.oid=op.oprcom\n") + wxT(" LEFT OUTER JOIN pg_operator ne ON ne.oid=op.oprnegate\n") + wxT(" LEFT OUTER JOIN pg_operator lso ON lso.oid=op.oprlsortop\n") + wxT(" LEFT OUTER JOIN pg_operator rso ON rso.oid=op.oprrsortop\n") + wxT(" LEFT OUTER JOIN pg_operator lco ON lco.oid=op.oprltcmpop\n") + wxT(" LEFT OUTER JOIN pg_operator gco ON gco.oid=op.oprgtcmpop\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=op.oid AND des.classoid='pg_operator'::regclass)\n") + wxT(" WHERE op.oprnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY op.oprname")); + } + + if (operators) + { + while (!operators->Eof()) + { + oper = new pgOperator(collection->GetSchema(), operators->GetVal(wxT("oprname"))); + oper->iSetOid(operators->GetOid(wxT("oid"))); + oper->iSetOwner(operators->GetVal(wxT("opowner"))); + oper->iSetComment(operators->GetVal(wxT("description"))); + oper->iSetLeftType(operators->GetVal(wxT("lefttype"))); + oper->iSetRightType(operators->GetVal(wxT("righttype"))); + oper->iSetLeftTypeOid(operators->GetOid(wxT("oprleft"))); + oper->iSetRightTypeOid(operators->GetOid(wxT("oprright"))); + oper->iSetResultType(operators->GetVal(wxT("resulttype"))); + oper->iSetOperatorFunction(operators->GetVal(wxT("operproc"))); + + wxString tmp = operators->GetVal(wxT("joinproc")); + if (tmp != wxT("-")) + oper->iSetJoinFunction(tmp); + tmp = operators->GetVal(wxT("restrproc")); + if (tmp != wxT("-")) + oper->iSetRestrictFunction(tmp); + + if (!collection->GetDatabase()->BackendMinimumVersion(8, 3)) + { + oper->iSetLeftSortOperator(operators->GetVal(wxT("leftsortop"))); + oper->iSetRightSortOperator(operators->GetVal(wxT("rightsortop"))); + oper->iSetLessOperator(operators->GetVal(wxT("lscmpop"))); + oper->iSetGreaterOperator(operators->GetVal(wxT("gtcmpop"))); + } + + oper->iSetCommutator(operators->GetVal(wxT("compop"))); + oper->iSetNegator(operators->GetVal(wxT("negop"))); + wxString kind = operators->GetVal(wxT("oprkind")); + oper->iSetKind(kind.IsSameAs(wxT("b")) ? wxT("infix") : + kind.IsSameAs(wxT("l")) ? wxT("prefix") : + kind.IsSameAs(wxT("r")) ? wxT("postfix") : wxT("unknown")); + oper->iSetHashJoins(operators->GetBool(wxT("oprcanhash"))); + + if (!collection->GetDatabase()->BackendMinimumVersion(8, 3)) + oper->iSetMergeJoins(!oper->GetLeftSortOperator().IsNull() || !oper->GetRightSortOperator().IsNull() || + !oper->GetLessOperator().IsNull() || !oper->GetGreaterOperator().IsNull()); + else + oper->iSetMergeJoins(operators->GetBool(wxT("oprcanmerge"))); + + + if (browser) + { + browser->AppendObject(collection, oper); + operators->MoveNext(); + } + else + break; + } + + delete operators; + } + return oper; +} + + +#include "images/operator.pngc" +#include "images/operators.pngc" + +pgOperatorFactory::pgOperatorFactory() + : pgSchemaObjFactory(__("Operator"), __("New Operator..."), __("Create a new Operator."), operator_png_img) +{ +} + + +pgCollection *pgOperatorFactory::CreateCollection(pgObject *obj) +{ + return new pgOperatorCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgOperatorFactory operatorFactory; +static pgaCollectionFactory cf(&operatorFactory, __("Operators"), operators_png_img); diff --git a/schema/pgOperatorClass.cpp b/schema/pgOperatorClass.cpp new file mode 100644 index 0000000..7c586d3 --- /dev/null +++ b/schema/pgOperatorClass.cpp @@ -0,0 +1,426 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorClass.cpp - OperatorClass class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgFunction.h" + + +pgOperatorClass::pgOperatorClass(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, operatorClassFactory, newName) +{ +} + +pgOperatorClass::~pgOperatorClass() +{ +} + +wxString pgOperatorClass::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator class"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator class"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator class \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator class \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop operator class cascaded?"); + break; + case DROPTITLE: + message = _("Drop operator class?"); + break; + case PROPERTIESREPORT: + message = _("Operator class properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Operator class properties"); + break; + case DDLREPORT: + message = _("Operator class DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Operator class DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Operator class dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Operator class dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Operator class dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Operator class dependents"); + break; + } + + return message; +} + +bool pgOperatorClass::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP OPERATOR CLASS ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT(" USING ") + GetAccessMethod(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgOperatorClass::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Operator Class: ") + GetName() + wxT("\n\n") + + wxT("-- DROP OPERATOR CLASS ") + GetQuotedFullIdentifier() + wxT(" USING ") + GetAccessMethod() + wxT(";") + + wxT("\n\nCREATE OPERATOR CLASS ") + GetQuotedFullIdentifier(); + if (GetOpcDefault()) + sql += wxT(" DEFAULT"); + sql += wxT("\n FOR TYPE ") + GetInType() + + wxT(" USING ") + GetAccessMethod() + + wxT(" AS"); + unsigned int i; + bool needComma = false; + + for (i = 0 ; i < operators.Count() ; i++) + { + if (needComma) + sql += wxT(","); + + sql += wxT("\n OPERATOR ") + operators.Item(i); + needComma = true; + } + for (i = 0 ; i < functions.Count() ; i++) + { + if (needComma) + sql += wxT(","); + + sql += wxT("\n FUNCTION ") + quotedFunctions.Item(i); + needComma = true; + } + AppendIfFilled(sql, wxT("\n STORAGE "), GetKeyType()); + sql += wxT(";\n"); + } + + return sql; +} + + +void pgOperatorClass::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + pgSet *set; + + if (!GetConnection()->BackendMinimumVersion(8, 3)) + { + set = ExecuteSet( + wxT("SELECT amopstrategy, amopreqcheck, oprname, lt.typname as lefttype, rt.typname as righttype\n") + wxT(" FROM pg_amop am\n") + wxT(" JOIN pg_operator op ON amopopr=op.oid\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=oprright\n") + wxT(" WHERE amopclaid=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY amopstrategy")); + } + else if (!GetConnection()->BackendMinimumVersion(8, 4)) + { + set = ExecuteSet( + wxT("SELECT amopstrategy, amopreqcheck, oprname, lt.typname as lefttype, rt.typname as righttype\n") + wxT(" FROM pg_amop am\n") + wxT(" JOIN pg_operator op ON amopopr=op.oid\n") + wxT(" JOIN pg_opfamily opf ON amopfamily = opf.oid\n") + wxT(" JOIN pg_opclass opc ON opf.oid = opcfamily\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=oprright\n") + wxT(" WHERE opc.oid=") + GetOidStr() + wxT("\n") + wxT(" AND amopmethod = opf.opfmethod\n") + wxT(" AND amoplefttype = op.oprleft AND amoprighttype = op.oprright\n") + wxT(" ORDER BY amopstrategy")); + } + else + { + set = ExecuteSet( + wxT("SELECT amopstrategy, oprname, lt.typname as lefttype, rt.typname as righttype\n") + wxT(" FROM pg_amop am\n") + wxT(" JOIN pg_operator op ON amopopr=op.oid\n") + wxT(" JOIN pg_opfamily opf ON amopfamily = opf.oid\n") + wxT(" JOIN pg_opclass opc ON opf.oid = opcfamily\n") + wxT(" LEFT OUTER JOIN pg_type lt ON lt.oid=oprleft\n") + wxT(" LEFT OUTER JOIN pg_type rt ON rt.oid=oprright\n") + wxT(" WHERE opc.oid=") + GetOidStr() + wxT("\n") + wxT(" AND amopmethod = opf.opfmethod\n") + wxT(" AND amoplefttype = op.oprleft AND amoprighttype = op.oprright\n") + wxT(" ORDER BY amopstrategy")); + } + + if (set) + { + while (!set->Eof()) + { + wxString str = set->GetVal(wxT("amopstrategy")) + wxT(" ") + set->GetVal(wxT("oprname")); + wxString lt = set->GetVal(wxT("lefttype")); + wxString rt = set->GetVal(wxT("righttype")); + if (lt == GetInType() && (rt.IsEmpty() || rt == GetInType())) + lt = wxEmptyString; + if (rt == GetInType() && lt.IsEmpty()) + rt = wxEmptyString; + + if (!lt.IsEmpty() || !rt.IsEmpty()) + { + str += wxT("("); + if (!lt.IsEmpty()) + { + str += lt; + if (!rt.IsEmpty()) + str += wxT(", "); + } + if (!rt.IsEmpty()) + str += rt; + str += wxT(")"); + } + + if (!GetConnection()->BackendMinimumVersion(8, 4)) + { + if (set->GetBool(wxT("amopreqcheck"))) + str += wxT(" RECHECK"); + } + + operators.Add(str); + set->MoveNext(); + } + delete set; + } + + if (!GetConnection()->BackendMinimumVersion(8, 3)) + { + set = ExecuteSet( + wxT("SELECT amprocnum, amproc::oid\n") + wxT(" FROM pg_amproc am\n") + wxT(" WHERE amopclaid=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY amprocnum")); + } + else + { + set = ExecuteSet( + wxT("SELECT amprocnum, amproc::oid\n") + wxT(" FROM pg_amproc am\n") + wxT(" JOIN pg_opfamily opf ON amprocfamily = opf.oid\n") + wxT(" JOIN pg_opclass opc ON opf.oid = opcfamily\n") + wxT(" WHERE opc.oid=") + GetOidStr() + wxT("\n") + wxT(" AND amproclefttype = opc.opcintype AND amprocrighttype = opc.opcintype\n") + wxT(" ORDER BY amprocnum")); + } + + if (set) + { + while (!set->Eof()) + { + wxString amproc = set->GetVal(wxT("amproc")); + functionOids.Add(amproc); + + // We won't build a PG_FUNCTIONS collection under OperatorClass, so we create + // temporary function items + pgFunction *function = functionFactory.AppendFunctions(this, GetSchema(), 0, wxT(" WHERE pr.oid=") + amproc); + if (function) + { + functions.Add(set->GetVal(wxT("amprocnum")) + wxT(" ") + function->GetFullName()); + quotedFunctions.Add(set->GetVal(wxT("amprocnum")) + wxT(" ") + + function->GetQuotedFullIdentifier() + wxT("(") + function->GetArgSigList() + wxT(")")); + delete function; + } + + set->MoveNext(); + } + delete set; + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendYesNoItem(_("Default?"), GetOpcDefault()); + properties->AppendItem(_("For type"), GetInType()); + properties->AppendItem(_("Access method"), GetAccessMethod()); + if (GetConnection()->BackendMinimumVersion(8, 3)) + properties->AppendItem(_("Family"), GetFamily()); + + if (!GetKeyType().IsEmpty()) + properties->AppendItem(_("Storage"), GetKeyType()); + unsigned int i; + for (i = 0 ; i < operators.Count() ; i++) + properties->AppendItem(wxT("OPERATOR"), operators.Item(i)); + for (i = 0 ; i < functions.Count() ; i++) + properties->AppendItem(wxT("FUNCTION"), functions.Item(i)); + properties->AppendYesNoItem(_("System operator class?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(7, 5)) + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgOperatorClass::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *operatorClass = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + operatorClass = operatorClassFactory.CreateObjects(coll, 0, wxT("\n AND op.oid=") + GetOidStr()); + + return operatorClass; +} + + +/////////////////////////////////////////////////// + + +pgOperatorClassCollection::pgOperatorClassCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgOperatorClassCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator classes"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator classes"); + break; + case OBJECTSLISTREPORT: + message = _("Operator classes list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + + +pgObject *pgOperatorClassFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgOperatorClass *operatorClass = 0; + + pgSet *operatorClasses; + if (collection->GetDatabase()->BackendMinimumVersion(8, 3)) + { + operatorClasses = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.*, pg_get_userbyid(op.opcowner) as opowner, it.typname as intypename, dt.typname as keytypename, amname, opfname\n") + wxT(" FROM pg_opclass op\n") + wxT(" JOIN pg_opfamily opf ON op.opcfamily=opf.oid\n") + wxT(" JOIN pg_am am ON am.oid=opf.opfmethod\n") + wxT(" JOIN pg_type it ON it.oid=opcintype\n") + wxT(" LEFT OUTER JOIN pg_type dt ON dt.oid=opckeytype\n") + wxT(" WHERE opcnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY opcname")); + } + else + { + operatorClasses = collection->GetDatabase()->ExecuteSet( + wxT("SELECT op.oid, op.*, pg_get_userbyid(op.opcowner) as opowner, it.typname as intypename, dt.typname as keytypename, amname\n") + wxT(" FROM pg_opclass op\n") + wxT(" JOIN pg_am am ON am.oid=opcamid\n") + wxT(" JOIN pg_type it ON it.oid=opcintype\n") + wxT(" LEFT OUTER JOIN pg_type dt ON dt.oid=opckeytype\n") + wxT(" WHERE opcnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY opcname")); + } + + + if (operatorClasses) + { + while (!operatorClasses->Eof()) + { + operatorClass = new pgOperatorClass( + collection->GetSchema(), operatorClasses->GetVal(wxT("opcname"))); + + operatorClass->iSetOid(operatorClasses->GetOid(wxT("oid"))); + operatorClass->iSetOwner(operatorClasses->GetVal(wxT("opowner"))); + operatorClass->iSetAccessMethod(operatorClasses->GetVal(wxT("amname"))); + operatorClass->iSetInType(operatorClasses->GetVal(wxT("intypename"))); + operatorClass->iSetKeyType(operatorClasses->GetVal(wxT("keytypename"))); + operatorClass->iSetOpcDefault(operatorClasses->GetBool(wxT("opcdefault"))); + + if (collection->GetDatabase()->BackendMinimumVersion(8, 3)) + operatorClass->iSetFamily(operatorClasses->GetVal(wxT("opfname"))); + + if (browser) + { + browser->AppendObject(collection, operatorClass); + operatorClasses->MoveNext(); + } + else + break; + } + + delete operatorClasses; + } + return operatorClass; +} + + +#include "images/operatorclass.pngc" +#include "images/operatorclasses.pngc" + +pgOperatorClassFactory::pgOperatorClassFactory() + : pgSchemaObjFactory(__("Operator Class"), __("New Operator Class..."), __("Create a new Operator Class."), operatorclass_png_img) +{ + metaType = PGM_OPCLASS; +} + +dlgProperty *pgOperatorClassFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; // not implemented +} + +pgCollection *pgOperatorClassFactory::CreateCollection(pgObject *obj) +{ + return new pgOperatorClassCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgOperatorClassFactory operatorClassFactory; +static pgaCollectionFactory cf(&operatorClassFactory, __("Operator Classes"), operatorclasses_png_img); diff --git a/schema/pgOperatorFamily.cpp b/schema/pgOperatorFamily.cpp new file mode 100644 index 0000000..0bfc9ac --- /dev/null +++ b/schema/pgOperatorFamily.cpp @@ -0,0 +1,237 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgOperatorFamily.cpp - OperatorFamily class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgOperatorFamily.h" +#include "schema/pgFunction.h" + + +pgOperatorFamily::pgOperatorFamily(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, operatorFamilyFactory, newName) +{ +} + +pgOperatorFamily::~pgOperatorFamily() +{ +} + +wxString pgOperatorFamily::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator family"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator family"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator family \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop operator family \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop operator family cascaded?"); + break; + case DROPTITLE: + message = _("Drop operator family?"); + break; + case PROPERTIESREPORT: + message = _("Operator family properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Operator family properties"); + break; + case DDLREPORT: + message = _("Operator family DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Operator family DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Operator family dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Operator family dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Operator family dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Operator family dependents"); + break; + } + + return message; +} + +bool pgOperatorFamily::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP OPERATOR FAMILY ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier() + wxT(" USING ") + GetAccessMethod(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgOperatorFamily::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Operator Family: ") + GetName() + wxT("\n\n") + + wxT("-- DROP OPERATOR FAMILY ") + GetQuotedFullIdentifier() + wxT(" USING ") + GetAccessMethod() + wxT(";") + + wxT("\n\nCREATE OPERATOR FAMILY ") + GetQuotedFullIdentifier() + + wxT(" USING ") + GetAccessMethod() + + wxT(";"); + } + + return sql; +} + + +void pgOperatorFamily::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Access method"), GetAccessMethod()); + properties->AppendYesNoItem(_("System operator family?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgOperatorFamily::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *operatorFamily = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + operatorFamily = operatorFamilyFactory.CreateObjects(coll, 0, wxT("\n AND opf.oid=") + GetOidStr()); + + return operatorFamily; +} + + +/////////////////////////////////////////////////// + + +pgOperatorFamilyCollection::pgOperatorFamilyCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgOperatorFamilyCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on operator families"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing operator families"); + break; + case OBJECTSLISTREPORT: + message = _("Operator families list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + + +pgObject *pgOperatorFamilyFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgOperatorFamily *operatorFamily = 0; + + pgSet *operatorFamilies; + + operatorFamilies = collection->GetDatabase()->ExecuteSet( + wxT("SELECT opf.oid, opf.*, pg_get_userbyid(opf.opfowner) as opowner, amname\n") + wxT(" FROM pg_opfamily opf\n") + wxT(" JOIN pg_am am ON am.oid=opf.opfmethod\n") + wxT(" WHERE opfnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY opfname")); + + + if (operatorFamilies) + { + while (!operatorFamilies->Eof()) + { + operatorFamily = new pgOperatorFamily( + collection->GetSchema(), operatorFamilies->GetVal(wxT("opfname"))); + + operatorFamily->iSetOid(operatorFamilies->GetOid(wxT("oid"))); + operatorFamily->iSetOwner(operatorFamilies->GetVal(wxT("opowner"))); + operatorFamily->iSetAccessMethod(operatorFamilies->GetVal(wxT("amname"))); + + if (browser) + { + browser->AppendObject(collection, operatorFamily); + operatorFamilies->MoveNext(); + } + else + break; + } + + delete operatorFamilies; + } + return operatorFamily; +} + + +#include "images/operatorfamily.pngc" +#include "images/operatorfamilies.pngc" + +pgOperatorFamilyFactory::pgOperatorFamilyFactory() + : pgSchemaObjFactory(__("Operator Family"), __("New Operator Family..."), __("Create a new Operator Family."), operatorfamily_png_img) +{ + metaType = PGM_OPFAMILY; +} + +dlgProperty *pgOperatorFamilyFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return 0; // not implemented +} + +pgCollection *pgOperatorFamilyFactory::CreateCollection(pgObject *obj) +{ + return new pgOperatorFamilyCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgOperatorFamilyFactory operatorFamilyFactory; +static pgaCollectionFactory cf(&operatorFamilyFactory, __("Operator Families"), operatorfamilies_png_img); diff --git a/schema/pgPartition.cpp b/schema/pgPartition.cpp new file mode 100644 index 0000000..f94d0d5 --- /dev/null +++ b/schema/pgPartition.cpp @@ -0,0 +1,456 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// gpPartition.cpp - Greenplum Table Partition class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include "utils/misc.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMaintenance.h" +#include "schema/pgTable.h" +#include "schema/pgPartition.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" + + +// App headers + +pgPartition::pgPartition(pgSchema *newSchema, const wxString &newName) + : pgTable(newSchema, pg_partitionFactory, newName) +{ +} + +pgPartition::~pgPartition() +{ +} + +bool pgPartition::CanCreate() +{ + return true; +} + +wxMenu *pgPartition::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + + } + return menu; +} +/* +wxString gpPartition::GetCreate() +{ + wxString sql; + + // sql = GetQuotedIdentifier() + wxT(" ") + // + GetTypeName().Upper() + GetDefinition(); + sql = wxT("Not implemented yet..sorry"); + return sql; +}; +*/ + +wxString pgPartition::GetSql(ctlTree *browser) +{ + wxString sql; + sql = wxT("-- "); + sql += _("Note: This DDL is a representation of how the partition might look as a table."); + sql += wxT("\n\n"); + + sql += pgTable::GetSql(browser); + return sql; +} +ctlTree *tmp_br; +pgObject *pgPartition::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgPartition *partition = 0; + pgCollection *coll = browser->GetParentCollection(item); + tmp_br=browser; + if (coll) + partition = (pgPartition *)pg_partitionFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr()); + + return partition; +} + +/////////////////////////////////////////////////////////// + +pgPartitionCollection::pgPartitionCollection(pgaFactory *factory, pgPartition *_table) + : pgTableCollection(factory, _table->GetSchema()) +{ + iSetOid(_table->GetOid()); +} +void pgPartitionCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for tables on %s"), GetSchema()->GetIdentifier().c_str()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Table Name")); + statistics->AddColumn(_("Tuples inserted")); + statistics->AddColumn(_("Tuples updated")); + statistics->AddColumn(_("Tuples deleted")); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->AddColumn(_("Tuples HOT updated")); + statistics->AddColumn(_("Live tuples")); + statistics->AddColumn(_("Dead tuples")); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + statistics->AddColumn(_("Last vacuum")); + statistics->AddColumn(_("Last autovacuum")); + statistics->AddColumn(_("Last analyze")); + statistics->AddColumn(_("Last autoanalyze")); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->AddColumn(_("Vacuum counter")); + statistics->AddColumn(_("Autovacuum counter")); + statistics->AddColumn(_("Analyze counter")); + statistics->AddColumn(_("Autoanalyze counter")); + } + if (hasSize) + statistics->AddColumn(_("Size"), 50); + + wxString sql = wxT("SELECT st.relname, n_tup_ins, n_tup_upd, n_tup_del"); + if (GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", n_tup_hot_upd, n_live_tup, n_dead_tup"); + if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += wxT(", last_vacuum, last_autovacuum, last_analyze, last_autoanalyze"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(", vacuum_count, autovacuum_count, analyze_count, autoanalyze_count"); + if (hasSize) + sql += wxT(", pg_size_pretty(pg_relation_size(st.relid)") + wxT(" + CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid) + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END") + wxT(" + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS size"); + + sql += wxT("\n FROM pg_stat_all_tables st") + wxT(" JOIN pg_class cl on cl.oid=st.relid\n") + wxT(" JOIN pg_inherits i ON (cl.oid = i.inhrelid)") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName())+ wxT(" AND i.inhparent = ")+GetOidStr() + + wxT("\n ORDER BY relname"); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + + if (stats) + { + long pos = 0; + int i; + while (!stats->Eof()) + { + i = 4; + statistics->InsertItem(pos, stats->GetVal(wxT("relname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("n_tup_ins"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("n_tup_upd"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("n_tup_del"))); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_hot_upd"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_live_tup"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_dead_tup"))); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_vacuum"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autovacuum"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_analyze"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autoanalyze"))); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("vacuum_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("autovacuum_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("analyze_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("autoanalyze_count"))); + } + if (hasSize) + statistics->SetItem(pos, i, stats->GetVal(wxT("size"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } + +} + + +pgObject *pgPartitionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgPartitionCollection *collection = (pgPartitionCollection *)coll; + wxString query; + pgPartition *table = 0; + ctlTree *br=browser; + if (!br) br=tmp_br; + // Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB, + // so we need to multiply them by the number of segmentDBs to get reasonable values. + long gp_segments = 1; + + //query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0"); + //gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query)); + //if (gp_segments <= 1) + // gp_segments = 1; + + + pgSet *tables; + + query = wxT("SELECT rel.oid, rel.relname,rel.relnamespace::regnamespace AS nspace, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, ") + wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl,\n"); + query += wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount\n"); + query += wxT(", rel.relpersistence \n"); + if (collection->GetDatabase()->connection()->GetIsPgProEnt()) query += wxT(",left((cfs_fragmentation(rel.oid)*100)::text,5)::text AS cfs_ratio\n"); + else query += wxT(",null::text AS cfs_ratio\n"); + + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + query += wxT(", rel.reloftype, typ.typname\n"); + query += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS labels"); + query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); + query += wxT(",case when lk.relation=rel.oid then null else pg_get_partkeydef(rel.oid) end \n AS partkeydef"); + query += wxT(",case when lk.relation=rel.oid then 'AccessExclusiveLock' else pg_get_expr(rel.relpartbound, rel.oid) end \n AS partexp"); + query += wxT(",(select count(*)from pg_inherits ii where ii.inhparent=rel.oid)>0 AS ispartitioned"); + + + query += wxT(" FROM pg_class rel\n") + wxT(" JOIN pg_inherits i ON (rel.oid = i.inhrelid) \n") + wxT(" LEFT JOIN pg_locks lk ON locktype='relation' and granted=true and mode='AccessExclusiveLock' and relation=rel.oid\n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n"); + query += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid\n"); + query += wxT("LEFT JOIN pg_type typ ON rel.reloftype=typ.oid\n"); + + query += wxT(" WHERE rel.relkind IN ('r','s','t','p')\n"); + // show partitions in other schema + //query += wxT(" AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + query += wxT("--AND (not (rel.relkind='r' and rel.relpartbound IS NOT NULL))\n ") + wxT(" AND i.inhparent = ") + collection->GetOidStr() + wxT("\n"); + + query += restriction + + wxT(" ORDER BY rel.relname"); + + + tables = collection->GetDatabase()->ExecuteSet(query); + if (tables) + { + wxString currns=collection->GetSchema()->GetName(); +// wxArrayObject schemaArr; + std::vector schemaArr; + while (!tables->Eof()) + { + wxString ns=tables->GetVal(wxT("nspace")); + if (currns!=ns) { + // find pgSchema object in tree + if (!(schemaArr.size()>0)) { + wxTreeItemId currentItem = collection->GetSchema()->GetId(); + pgCollection *collsch; + wxTreeItemId scItem; + if (currentItem) scItem = br->GetItemParent(currentItem); + collsch = (pgCollection *) br->GetObject(scItem); + if (!collsch) continue; + treeObjectIterator schemaIterator(br, collsch); + pgSchema *s; + while ((s = (pgSchema *)schemaIterator.GetNextObject()) != 0) + schemaArr.push_back(s); + } + table = 0; + for (size_t j=0;jGetName()) { + table = new pgPartition(schemaArr[j], tables->GetVal(wxT("relname"))); + break; + } + } + if (!table) continue; + } else table = new pgPartition(collection->GetSchema(), tables->GetVal(wxT("relname"))); + + table->iSetOid(tables->GetOid(wxT("oid"))); + table->iSetOwner(tables->GetVal(wxT("relowner"))); + table->iSetAcl(tables->GetVal(wxT("relacl"))); + table->iSetRatio(tables->GetVal(wxT("cfs_ratio"))); + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + + if (tables->GetVal(wxT("spcname")) == wxEmptyString) + table->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + table->iSetTablespace(tables->GetVal(wxT("spcname"))); + table->iSetOfTypeOid(tables->GetOid(wxT("reloftype"))); + table->iSetOfType(tables->GetVal(wxT("typname"))); + table->iSetComment(tables->GetVal(wxT("description"))); + table->iSetUnlogged(tables->GetVal(wxT("relpersistence")) == wxT("u")); + table->iSetHasOids(false); + table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments); + table->iSetFillFactor(tables->GetVal(wxT("fillfactor"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + table->iSetRelOptions(tables->GetVal(wxT("reloptions"))); + if (table->GetCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + table->iSetAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("autovacuum_enabled"))) + table->iSetAutoVacuumEnabled(1); + else + table->iSetAutoVacuumEnabled(0); + table->iSetAutoVacuumVacuumThreshold(tables->GetVal(wxT("autovacuum_vacuum_threshold"))); + table->iSetAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + table->iSetAutoVacuumAnalyzeThreshold(tables->GetVal(wxT("autovacuum_analyze_threshold"))); + table->iSetAutoVacuumAnalyzeScaleFactor(tables->GetVal(wxT("autovacuum_analyze_scale_factor"))); + table->iSetAutoVacuumVacuumCostDelay(tables->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + table->iSetAutoVacuumVacuumCostLimit(tables->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + table->iSetAutoVacuumFreezeMinAge(tables->GetVal(wxT("autovacuum_freeze_min_age"))); + table->iSetAutoVacuumFreezeMaxAge(tables->GetVal(wxT("autovacuum_freeze_max_age"))); + table->iSetAutoVacuumFreezeTableAge(tables->GetVal(wxT("autovacuum_freeze_table_age"))); + } + table->iSetHasToastTable(tables->GetBool(wxT("hastoasttable"))); + if (table->GetHasToastTable()) + { + table->iSetToastRelOptions(tables->GetVal(wxT("toast_reloptions"))); + + if (table->GetToastCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + table->iSetToastAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("toast_autovacuum_enabled"))) + table->iSetToastAutoVacuumEnabled(1); + else + table->iSetToastAutoVacuumEnabled(0); + + table->iSetToastAutoVacuumVacuumThreshold(tables->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + table->iSetToastAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + table->iSetToastAutoVacuumVacuumCostDelay(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + table->iSetToastAutoVacuumVacuumCostLimit(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + table->iSetToastAutoVacuumFreezeMinAge(tables->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + table->iSetToastAutoVacuumFreezeMaxAge(tables->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + table->iSetToastAutoVacuumFreezeTableAge(tables->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + } + table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass"))); + table->iSetPrimaryKeyName(tables->GetVal(wxT("conname"))); + table->iSetIsReplicated(tables->GetBool(wxT("isrepl"))); + table->iSetTriggerCount(tables->GetLong(wxT("triggercount"))); + wxString cn = tables->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + table->iSetPrimaryKeyColNumbers(cn); + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(false); + if (collection->GetConnection()->BackendMinimumVersion(10, 0)) + { + table->iSetPartKeyDef(tables->GetVal(wxT("partkeydef"))); + table->iSetPartExp(tables->GetVal(wxT("partexp"))); + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + } + if (collection->GetConnection()->GetIsGreenplum()) + { + Oid lo = tables->GetOid(wxT("localoid")); + wxString db = tables->GetVal(wxT("attrnums")); + db = db.Mid(1, db.Length() - 2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + table->iSetOrientation(tables->GetVal(wxT("orientation"))); + table->iSetCompressType(tables->GetVal(wxT("compresstype"))); + table->iSetBlocksize(tables->GetVal(wxT("blocksize"))); + table->iSetChecksum(tables->GetVal(wxT("checksum"))); + + + if (collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + { + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + } + + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + { + table->iSetProviders(tables->GetVal(wxT("providers"))); + table->iSetLabels(tables->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + if (schemaArr.size()>0) schemaArr.clear(); + delete tables; + } + return table; +} + +void pgPartitionFactory::AppendMenu(wxMenu *menu) +{ +} + +#include "images/table.pngc" +#include "images/table-sm.pngc" +#include "images/tables.pngc" + +pgPartitionFactory::pgPartitionFactory() + : pgTableObjFactory(__("Partition"), __("New Partition..."), __("Create a new Partition."), table_png_img, table_sm_png_img) +{ + metaType = PGM_TABLE; + typeName = wxT("TABLE"); +} + +pgCollection *pgPartitionFactory::CreateCollection(pgObject *obj) +{ + return new pgPartitionCollection(GetCollectionFactory(), (pgPartition *)obj ); +} + +pgPartitionFactory pg_partitionFactory; +static pgaCollectionFactory cf(&pg_partitionFactory, __("Partitions"), tables_png_img); + + diff --git a/schema/pgPublication.cpp b/schema/pgPublication.cpp new file mode 100644 index 0000000..e9cbee7 --- /dev/null +++ b/schema/pgPublication.cpp @@ -0,0 +1,253 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgPublication.cpp - Publication class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgPublication.h" + + +pgPublication::pgPublication(const wxString &newName) + : pgDatabaseObject(publicationFactory, newName) +{ +} + +wxString pgPublication::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on publication"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing publication"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop publication \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop publication \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop publication cascaded?"); + break; + case DROPTITLE: + message = _("Drop publication?"); + break; + case PROPERTIESREPORT: + message = _("Publication properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Publication properties"); + break; + case DDLREPORT: + message = _("Publication DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Publication DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Publication dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Publication dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Publication dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Publication dependents"); + break; + } + + return message; +} + +bool pgPublication::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP PUBLICATION ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgPublication::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Publication: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP PUBLICATION ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\n CREATE PUBLICATION ") + GetName(); + + if (GetIsAll()) + { + sql += wxT("\n FOR ALL TABLES "); + } else + { + sql += wxT("\n FOR TABLE "); + if (!GetTablesStr().IsEmpty()) + sql += wxT("") + GetTablesStr(); + } + if (GetIsIns()&&GetIsUpd()&&GetIsDel()) + { + + } else + { + sql += wxT("\n WITH (publish = '") + GetStrOper() + wxT("')"); + } + + sql += wxT(";\n"); + } + return sql; +} + + +void pgPublication::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Tables"), GetTablesStr()); + //properties->AppendYesNoItem(_("Relocatable?"), GetIsRelocatable()); + //properties->AppendItem(_("Version"), GetVersion()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgPublication::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *language = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + language = publicationFactory.CreateObjects(coll, 0, wxT("\n WHERE x.oid=") + GetOidStr()); + + return language; +} + + + +pgObject *pgPublicationFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgPublication *publication = 0; + + sql = wxT("select x.oid,x.pubname, pg_get_userbyid(x.pubowner) AS owner, x.puballtables, x.pubinsert, x.pubupdate, x.pubdelete, obj_description(x.oid,'pg_publication') AS comment, t.t") + wxT(" FROM pg_publication x\n") + wxT(" LEFT JOIN LATERAL (select string_agg(schemaname||'.'||tablename,', ') t from pg_publication_tables where pubname=x.pubname) t on true \n") + wxT(" ") + + restriction + wxT("\n") + wxT(" ORDER BY x.pubname"); + pgSet *publications = collection->GetDatabase()->ExecuteSet(sql); + + if (publications) + { + while (!publications->Eof()) + { + + publication = new pgPublication(publications->GetVal(wxT("pubname"))); + publication->iSetDatabase(collection->GetDatabase()); + publication->iSetOid(publications->GetOid(wxT("oid"))); + publication->iSetOwner(publications->GetVal(wxT("owner"))); + publication->iSetTablesStr(publications->GetVal(wxT("t"))); + publication->iSetIsAll(publications->GetBool(wxT("puballtables"))); + publication->iSetIsIns(publications->GetBool(wxT("pubinsert"))); + publication->iSetIsUpd(publications->GetBool(wxT("pubupdate"))); + publication->iSetIsDel(publications->GetBool(wxT("pubdelete"))); + //publication->iSetVersion(publications->GetVal(wxT("extversion"))); + publication->iSetComment(publications->GetVal(wxT("comment"))); + + if (browser) + { + browser->AppendObject(collection, publication); + + publications->MoveNext(); + } + else + break; + } + + delete publications; + } + return publication; +} + + +///////////////////////////// + +pgPublicationCollection::pgPublicationCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgPublicationCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on publications"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing publications"); + break; + case OBJECTSLISTREPORT: + message = _("Publications list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/extension.pngc" +#include "images/extension-sm.pngc" +#include "images/extensions.pngc" + +pgPublicationFactory::pgPublicationFactory() + : pgDatabaseObjFactory(__("Publication"), __("New Publication..."), __("Create a new Publication."), extension_png_img, extension_sm_png_img) +{ +} + + +pgCollection *pgPublicationFactory::CreateCollection(pgObject *obj) +{ + return new pgPublicationCollection(GetCollectionFactory(), (pgDatabase *)obj); +} +dlgProperty *pgPublicationFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return NULL; +} + +pgPublicationFactory publicationFactory; +static pgaCollectionFactory cf(&publicationFactory, __("Publications"), extensions_png_img); diff --git a/schema/pgRole.cpp b/schema/pgRole.cpp new file mode 100644 index 0000000..4da8504 --- /dev/null +++ b/schema/pgRole.cpp @@ -0,0 +1,905 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRole.cpp - PostgreSQL Role +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgRole.h" +#include "frm/frmMain.h" +#include "dlg/dlgReassignDropOwned.h" +#include "utils/pgDefs.h" +#include "schema/pgDatabase.h" +#include "schema/pgTablespace.h" + + +pgLoginRole::pgLoginRole(const wxString &newName) + : pgRole(loginRoleFactory, newName) +{ +} + + +pgGroupRole::pgGroupRole(const wxString &newName) + : pgRole(groupRoleFactory, newName) +{ +} + + +pgRole::pgRole(pgaFactory &factory, const wxString &newName) + : pgServerObject(factory, newName) +{ +} + + +wxString pgLoginRole::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on login role"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing login role"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop login role \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop login role \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop login role cascaded?"); + break; + case DROPTITLE: + message = _("Drop login role?"); + break; + case PROPERTIESREPORT: + message = _("Login role properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Login role properties"); + break; + case DDLREPORT: + message = _("Login role DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Login role DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Login role dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Login role dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Login role dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Login role dependents"); + break; + } + + return message; +} + + +wxString pgGroupRole::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on group role"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing group role"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group role \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop group role \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop group role cascaded?"); + break; + case DROPTITLE: + message = _("Drop group role?"); + break; + case PROPERTIESREPORT: + message = _("Group role properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Group role properties"); + break; + case DDLREPORT: + message = _("Group role DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Group role DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Group role dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Group role dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Group role dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Group role dependents"); + break; + } + + return message; +} + + +int pgRole::GetIconId() +{ + if (GetCanLogin()) + return loginRoleFactory.GetIconId(); + else + return groupRoleFactory.GetIconId(); +} + + +bool pgRole::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if ((GetUpdateCatalog() && !server->GetConnection()->BackendMinimumVersion(9, 5)) || + (server->GetConnection()->BackendMinimumVersion(9, 5) && this->GetSuperuser())) + { + wxMessageDialog dlg(frame, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + return false; + } + return server->ExecuteVoid(wxT("DROP ROLE ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString pgRole::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Role: ") + GetName() + wxT("\n\n") + + wxT("-- DROP ROLE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE ROLE ") + GetQuotedIdentifier(); + + if (GetCanLogin()) + { + sql += wxT(" LOGIN"); + if (GetPassword() != wxT("********") && !GetPassword().IsEmpty()) + AppendIfFilled(sql, wxT("\n ENCRYPTED PASSWORD "), qtDbString(GetPassword())); + } + sql += wxT("\n "); + if (this->GetSuperuser()) sql += wxT(" SUPERUSER"); + else sql += wxT(" NOSUPERUSER"); + if (GetInherits()) sql += wxT(" INHERIT"); + else sql += wxT(" NOINHERIT"); + if (GetCreateDatabase()) sql += wxT(" CREATEDB"); + else sql += wxT(" NOCREATEDB"); + if (GetCreateRole()) sql += wxT(" CREATEROLE"); + else sql += wxT(" NOCREATEROLE"); + if (server->GetConnection()->BackendMinimumVersion(9, 1)) + { + if (GetReplication()) sql += wxT(" REPLICATION"); + else sql += wxT(" NOREPLICATION"); + } + if (GetConnectionLimit() > 0) + sql += wxT(" CONNECTION LIMIT ") + NumToStr(GetConnectionLimit()); + if (GetAccountExpires().IsValid()) + AppendIfFilled(sql, wxT(" VALID UNTIL "), qtDbString(DateToAnsiStr(GetAccountExpires()))); + if (GetRolQueueName().Length() > 0) + AppendIfFilled(sql, wxT(" RESOURCE QUEUE "), GetRolQueueName()); + sql += wxT(";\n"); + + if (this->GetSuperuser() && !GetUpdateCatalog() && + !server->GetConnection()->BackendMinimumVersion(9, 5)) + sql += wxT("UPDATE pg_authid SET rolcatupdate=false WHERE rolname=") + qtDbString(GetIdentifier()) + wxT(";\n"); + + size_t index; + if (variables.GetCount() > 0) + { + wxString dbname = wxEmptyString; + wxString parameter = wxEmptyString; + wxString value = wxEmptyString; + + sql += wxT("\n"); + for (index = 0 ; index < variables.GetCount() ; index += 3) + { + dbname = variables.Item(index); + parameter = variables.Item(index + 1); + value = variables.Item(index + 2); + + if (dbname.Length() == 0) + { + sql += wxT("ALTER ROLE ") + GetQuotedFullIdentifier(); + } + else + { + sql += wxT("ALTER ROLE ") + GetQuotedFullIdentifier() + wxT(" IN DATABASE ") + dbname; + } + + if (parameter != wxT("search_path") && parameter != wxT("temp_tablespaces")) + { + sql += wxT("\n SET ") + parameter + wxT(" = '") + value + wxT("';\n"); + } + else + { + sql += wxT("\n SET ") + parameter + wxT(" = ") + value + wxT(";\n"); + } + } + } + + for (index = 0 ; index < rolesIn.GetCount() ; index++) + { + wxString role = rolesIn.Item(index); + bool admin = false; + if (role.Right(PGROLE_ADMINOPTION_LEN) == PGROLE_ADMINOPTION) + { + admin = true; + role = role.Left(role.Length() - PGROLE_ADMINOPTION_LEN); + } + sql += wxT("GRANT ") + qtIdent(role) + + wxT(" TO ") + GetQuotedIdentifier(); + + if (admin) + sql += wxT(" WITH ADMIN OPTION"); + + sql += wxT(";\n"); + } + + if (!GetComment().IsNull()) + { + sql += wxT("COMMENT ON ROLE ") + GetQuotedFullIdentifier() + wxT(" IS ") + + qtDbString(GetComment()) + wxT(";\n"); + } + + wxString query; + query = wxT("select type,objname,grantee,string_agg(privilege_type,',' order by privilege_type) priv from (\n") +wxT(" select type, objname, r1.rolname grantor, r2.rolname grantee, privilege_type\n") +wxT(" from\n") +wxT(" (select \n") +wxT(" 'database'::text as type, datname as objname, datistemplate, datallowconn, \n") +wxT(" (aclexplode(datacl)).grantor as grantorI, \n") +wxT(" (aclexplode(datacl)).grantee as granteeI,\n") +wxT(" (aclexplode(datacl)).privilege_type,\n") +wxT(" (aclexplode(datacl)).is_grantable\n") +wxT(" from pg_database) as db\n") +wxT(" join pg_roles r1 on db.grantorI = r1.oid\n") +wxT(" join pg_roles r2 on db.granteeI = r2.oid\n") +wxT(" where r2.rolname not in ('postgres')\n") +wxT(" union all\n") +wxT(" /* Schemas / Namespaces */\n") +wxT(" select type, objname, r1.rolname grantor, r2.rolname grantee, privilege_type from \n") +wxT(" (select\n") +wxT(" 'schema'::text as type, nspname as objname, \n") +wxT(" (aclexplode(nspacl)).grantor as grantorI, \n") +wxT(" (aclexplode(nspacl)).grantee as granteeI,\n") +wxT(" (aclexplode(nspacl)).privilege_type,\n") +wxT(" (aclexplode(nspacl)).is_grantable\n") +wxT(" from pg_catalog.pg_namespace) as ns\n") +wxT(" join pg_roles r1 on ns.grantorI = r1.oid\n") +wxT(" join pg_roles r2 on ns.granteeI = r2.oid\n") +wxT(" where r2.rolname not in ('postgres')\n") +wxT(" union all\n") +wxT(" /* Tabelas */\n") +wxT(" select 'tables'::text as type, table_schema||'.'||table_name as objname, grantor, grantee, privilege_type \n") +wxT(" from information_schema.role_table_grants \n") +wxT(" where grantee not in ('postgres')\n") +wxT(" and table_schema not in ('information_schema', 'pg_catalog')\n") +wxT(" and grantor <> grantee\n") +wxT(" union all\n") +wxT(" /* Colunas (TODO: se o revoke on table from x retirar acesso das colunas, nao precisa desse bloco) */\n") +wxT("/* select \n") +wxT(" 'columns'::text as type, column_name||' ('||table_name||')' as objname,\n") +wxT(" grantor, grantee, privilege_type\n") +wxT(" from information_schema.role_column_grants\n") +wxT(" where \n") +wxT(" table_schema not in ('information_schema', 'pg_catalog')\n") +wxT(" and grantor <> grantee\n") +wxT(" union all\n") +wxT("*/\n") +wxT(" /* Funcoes / Procedures */\n") +wxT(" select 'routine'::text as type, routine_schema||'.'||routine_name as objname, grantor, grantee, privilege_type\n") +wxT(" from information_schema.role_routine_grants\n") +wxT(" where grantor <> grantee\n") +wxT(" and routine_schema not in ('information_schema', 'pg_catalog')\n") +wxT(" union all\n") +wxT(" /* Outros objetos */\n") +wxT(" select 'object'::text as type, object_name||'( '||object_type||')' as objname, grantor, grantee, privilege_type\n") +wxT(" from information_schema.role_usage_grants\n") +wxT(" where object_type <> 'COLLATION' and object_type <> 'DOMAIN'\n") +wxT(") aa where aa.grantee='")+GetName()+("' group by type,objname,grantee order by 1,2;\n"); + pgSet *roles = GetConnection()->ExecuteSet(query); + + if (roles) + { + //GRANT SELECT ON TABLE public.v_b TO okomgr; + wxString prev=wxEmptyString; + wxString addgrant=wxEmptyString; + while (!roles->Eof()) + { + if (wxT("tables")==roles->GetVal(wxT("type")) ) { + addgrant += wxT("\nGRANT ") + roles->GetVal(wxT("priv")) + wxT(" ON TABLE ") + qtIdent(roles->GetVal(wxT("objname")).BeforeFirst('.'))+wxT(".")+qtIdent(roles->GetVal(wxT("objname")).AfterFirst('.')) + + wxT(" TO ") + qtIdent(GetName()); + } + if (wxT("routine")==roles->GetVal(wxT("type")) ) { + addgrant += wxT("\nGRANT EXECUTE ON FUNCTION ") + qtIdent(roles->GetVal(wxT("objname")).BeforeFirst('.'))+wxT(".")+qtIdent(roles->GetVal(wxT("objname")).AfterFirst('.')) + + wxT(" TO ") + qtIdent(GetName()); + } + if (wxT("schema")==roles->GetVal(wxT("type")) ) { + addgrant += wxT("\nGRANT USAGE ON SCHEMA ") + qtIdent(roles->GetVal(wxT("objname"))) + + wxT(" TO ") + qtIdent(GetName()); + } + addgrant += wxT(";"); + roles->MoveNext(); + } + sql += wxT("\n")+ addgrant + wxT("\n"); + delete roles; + } + + + if (GetConnection()->BackendMinimumVersion(9, 2)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + + +void pgRole::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + form->StartMsg(_(" Retrieving Role owned objects")); + + referencedBy->ClearAll(); + referencedBy->AddColumn(_("Type"), 60); + referencedBy->AddColumn(_("Database"), 80); + referencedBy->AddColumn(_("Name"), 300); + + wxString sysoid = NumToStr(GetConnection()->GetLastSystemOID()); + + wxArrayString dblist; + + pgSet *set; + set = GetConnection()->ExecuteSet( + wxT("SELECT 'd' as type, datname, datallowconn, datdba\n") + wxT(" FROM pg_database db\n") + wxT("UNION\n") + wxT("SELECT 'M', spcname, null, null\n") + wxT(" FROM pg_tablespace where spcowner=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY 1, 2")); + + if (set) + { + while (!set->Eof()) + { + wxString name = set->GetVal(wxT("datname")); + if (set->GetVal(wxT("type")) == wxT("d")) + { + if (set->GetBool(wxT("datallowconn"))) + dblist.Add(name); + if (GetOidStr() == set->GetVal(wxT("datdba"))) + referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), name); + } + else + referencedBy->AppendItem(tablespaceFactory.GetIconId(), _("Tablespace"), wxEmptyString, name); + + set->MoveNext(); + } + delete set; + } + + // We ignore classid and refclassid here because we hope that oids are unique + // across system tables. + // Strictly speaking, we'd need to join pg_shdepend to each subquery + + wxString depOids = wxT("(SELECT objid FROM pg_shdepend WHERE refobjid=") + GetOidStr() + wxT(")"); + + FillOwned(form->GetBrowser(), referencedBy, dblist, + wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n") + wxT(" LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n") + wxT(" LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid\n") + wxT(" WHERE cl.oid IN ") + depOids + wxT(" AND cl.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'n', null, nspname, null\n") + wxT(" FROM pg_namespace nsp WHERE nsp.oid IN ") + depOids + wxT(" AND nsp.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN typtype='d' THEN 'd' ELSE 'y' END, null, typname, null\n") + wxT(" FROM pg_type ty WHERE ty.oid IN ") + depOids + wxT(" AND ty.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'C', null, conname, null\n") + wxT(" FROM pg_conversion co WHERE co.oid IN ") + depOids + wxT(" AND co.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + wxT(" THEN 'T' ELSE 'p' END, null, proname, null\n") + wxT(" FROM pg_proc pr WHERE pr.oid IN ") + depOids + wxT(" AND pr.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'o', null, oprname || '('::text || ") + wxT("COALESCE(tl.typname, ''::text) || ") + wxT("CASE WHEN tl.oid IS NOT NULL AND tr.oid IS NOT NULL THEN ','::text END || ") + wxT("COALESCE(tr.typname, ''::text) || ')'::text, null\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT JOIN pg_type tl ON tl.oid=op.oprleft\n") + wxT(" LEFT JOIN pg_type tr ON tr.oid=op.oprright\n") + wxT(" WHERE op.oid IN ") + depOids + wxT(" AND op.oid > ") + sysoid + wxT("\n") + wxT(" ORDER BY 1,2,3")); + + form->EndMsg(set != 0); +} + + +void pgRole::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + wxString rolesquery; + + if (GetConnection()->BackendMinimumVersion(8, 2)) + rolesquery = wxT("SELECT rolname, admin_option,\n") + wxT(" pg_catalog.shobj_description(r.oid, 'pg_authid') AS description\n"); + else + rolesquery = wxT("SELECT rolname, admin_option\n"); + + rolesquery += wxT(" FROM pg_roles r\n") + wxT(" JOIN pg_auth_members ON r.oid=roleid\n") + wxT(" WHERE member=") + GetOidStr() + wxT("\n") + wxT(" ORDER BY rolname"); + + pgSetIterator roles(GetConnection(), rolesquery); + + while (roles.RowsLeft()) + { + wxString role = roles.GetVal(wxT("rolname")); + if (roles.GetBool(wxT("admin_option"))) + role += PGROLE_ADMINOPTION; + + rolesIn.Add(role); + } + + // Get configuration + wxString query; + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + query = wxT("WITH configs AS ") + wxT("(SELECT datname, unnest(setconfig) AS config") + wxT(" FROM pg_db_role_setting s") + wxT(" LEFT JOIN pg_database d ON d.oid=s.setdatabase") + wxT(" WHERE s.setrole=") + NumToStr(GetOid()) + wxT(")\n") + wxT("SELECT datname, split_part(config, '=', 1) AS variable, replace(config, split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM configs"); + } + else + { + wxString query_myrole = wxT("SELECT rolconfig FROM pg_roles WHERE oid=") + NumToStr(GetOid()); + query = wxT("SELECT '' AS datname, split_part(config, '=', 1) AS variable,\n") + wxT(" replace(config,split_part(config, '=', 1) || '=', '') AS value\n") + wxT("FROM (\n") + wxT(" SELECT\n") + wxT(" (\n") + wxT(" SELECT rolconfig[i]\n") + wxT(" FROM pg_roles\n") + wxT(" WHERE oid=") + NumToStr(GetOid()) + wxT("\n") + wxT(" ) AS config\n") + wxT(" FROM generate_series(array_lower((") + query_myrole + wxT("),1), array_upper((") + query_myrole + wxT("),1)) AS i\n") + wxT(" ) configs"); + } + pgSet *configs = GetConnection()->ExecuteSet(query); + if (configs) + { + while (!configs->Eof()) + { + variables.Add(configs->GetVal(wxT("datname"))); + variables.Add(configs->GetVal(wxT("variable"))); + variables.Add(configs->GetVal(wxT("value"))); + configs->MoveNext(); + } + delete configs; + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Account expires"), DateToAnsiStr(GetAccountExpires())); + properties->AppendItem(_("Can login?"), BoolToYesNo(GetCanLogin())); + properties->AppendItem(_("Superuser?"), BoolToYesNo(GetSuperuser())); + properties->AppendItem(_("Create databases?"), BoolToYesNo(GetCreateDatabase())); + properties->AppendItem(_("Create roles?"), BoolToYesNo(GetCreateRole())); + + if (!server->GetConnection()->BackendMinimumVersion(9, 5)) + properties->AppendItem(_("Update catalogs?"), BoolToYesNo(GetUpdateCatalog())); + properties->AppendItem(_("Inherits?"), BoolToYesNo(GetInherits())); + if (server->GetConnection()->BackendMinimumVersion(9, 1)) + { + properties->AppendItem(_("Replication?"), BoolToYesNo(GetReplication())); + } + + wxString strConnLimit; + strConnLimit.Printf(wxT("%ld"), GetConnectionLimit()); + properties->AppendItem(_("Connection Limit"), strConnLimit); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + wxString roleList; + + size_t index; + for (index = 0 ; index < rolesIn.GetCount() ; index++) + { + if (!roleList.IsEmpty()) + roleList += wxT(", "); + roleList += rolesIn.Item(index); + } + properties->AppendItem(_("Member of"), roleList); + + wxString dbname; + wxString parameter; + wxString value; + for (index = 0; index < variables.GetCount() ; index += 3) + { + dbname = variables.Item(index); + parameter = variables.Item(index + 1); + value = variables.Item(index + 2); + + if (dbname.Length() == 0) + { + properties->AppendItem(parameter, value); + } + else + { + properties->AppendItem(parameter + wxT(" (database ") + dbname + wxT(")"), value); + } + } + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + +void pgRole::ReassignDropOwnedTo(frmMain *form) +{ + wxString query; + + dlgReassignDropOwned rdo(form, GetConnection(), this, GetServer()->GetDbRestriction()); + if (rdo.ShowModal() != wxID_CANCEL) + { + pgConn *conn; + conn = new pgConn(GetConnection()->GetHost(), + GetConnection()->GetService(), + GetConnection()->GetHostAddr(), + rdo.GetDatabase(), + GetConnection()->GetUser(), + GetConnection()->GetPassword(), + GetConnection()->GetPort(), + GetConnection()->GetRole(), + GetConnection()->GetSslMode(), + 0, + GetConnection()->GetApplicationName(), + GetConnection()->GetSSLCert(), + GetConnection()->GetSSLKey(), + GetConnection()->GetSSLRootCert(), + GetConnection()->GetSSLCrl(), + GetConnection()->GetSSLCompression()); + + if (conn->GetStatus() == PGCONN_OK) + { + if (rdo.IsReassign()) + { + if (wxMessageBox(_("Are you sure you wish to reassign all objects owned by the selected role?"), _("Reassign objects"), wxYES_NO) != wxYES) + return; + + query = wxT("REASSIGN OWNED BY ") + GetQuotedFullIdentifier() + wxT(" TO ") + qtIdent(rdo.GetRole()); + } + else + { + if (wxMessageBox(_("Are you sure you wish to drop all objects owned by the selected role?"), _("Drop objects"), wxYES_NO) != wxYES) + return; + + query = wxT("DROP OWNED BY ") + GetQuotedFullIdentifier(); + } + conn->ExecuteVoid(query); + } + else + { + wxMessageBox(wxT("Connection failed: ") + conn->GetLastError()); + } + } +} + + +pgObject *pgRole::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *role = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->GetServer()->GetConnection()->BackendMinimumVersion(8, 5)) + role = loginRoleFactory.CreateObjects(coll, 0, wxT("\n WHERE tab.oid=") + GetOidStr()); + else + role = loginRoleFactory.CreateObjects(coll, 0, wxT("\n WHERE oid=") + GetOidStr()); + } + + return role; +} + + + +pgObject *pgRoleBaseFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgRole *role = 0; + pgSet *roles = 0; + wxString query; + + wxString tabname; + + if (collection->GetServer()->HasPrivilege(wxT("table"), wxT("pg_authid"), wxT("SELECT"))) + tabname = wxT("pg_authid"); + else + tabname = wxT("pg_roles"); + + // In 9.0+, role config options are in pg_db_role_setting + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(8, 5)) + { + query = wxT("SELECT tab.oid, tab.*, pg_catalog.shobj_description(tab.oid, 'pg_authid') AS description"); + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + query += wxT(", (SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = rolresqueue) AS rsqname"); + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 2)) + { + query += wxT(",\n(SELECT array_agg(label) FROM pg_shseclabel sl1 WHERE sl1.objoid=tab.oid) AS labels") + wxT(",\n(SELECT array_agg(provider) FROM pg_shseclabel sl2 WHERE sl2.objoid=tab.oid) AS providers"); + } + query += wxT(" FROM ") + tabname + wxT(" tab") + + restriction + wxT(" ORDER BY rolname"); + } + else if (collection->GetServer()->GetConnection()->BackendMinimumVersion(8, 2)) + { + query = wxT("SELECT oid, *, pg_catalog.shobj_description(oid, 'pg_authid') AS description "); + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + query += wxT(", (SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = rolresqueue) AS rsqname"); + query += wxT(" FROM ") + tabname + restriction + wxT(" ORDER BY rolname"); + } + else + { + query = wxT("SELECT oid, *, '' AS description ") ; + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + query += wxT(", (SELECT rsqname FROM pg_resqueue WHERE pg_resqueue.oid = rolresqueue) AS rsqname"); + query += wxT(" FROM ") + tabname + restriction + wxT(" ORDER BY rolname"); + } + roles = collection->GetServer()->ExecuteSet(query); + + if (roles) + { + while (!roles->Eof()) + { + if (roles->GetBool(wxT("rolcanlogin"))) + role = new pgLoginRole(roles->GetVal(wxT("rolname"))); + else + role = new pgGroupRole(roles->GetVal(wxT("rolname"))); + role->iSetServer(collection->GetServer()); + role->iSetOid(roles->GetOid(wxT("oid"))); + role->iSetCanLogin(roles->GetBool(wxT("rolcanlogin"))); + role->iSetInherits(roles->GetBool(wxT("rolinherit"))); + role->iSetCreateRole(roles->GetBool(wxT("rolcreaterole"))); + role->iSetCreateDatabase(roles->GetBool(wxT("rolcreatedb"))); + role->iSetSuperuser(roles->GetBool(wxT("rolsuper"))); + + if (!collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 5)) + role->iSetUpdateCatalog(roles->GetBool(wxT("rolcatupdate"))); + role->iSetAccountExpires(roles->GetDateTime(wxT("rolvaliduntil"))); + role->iSetIsValidInfinity(roles->GetVal(wxT("rolvaliduntil")) == wxT("infinity") ? true : false); + role->iSetPassword(roles->GetVal(wxT("rolpassword"))); + role->iSetComment(roles->GetVal(wxT("description"))); + role->iSetConnectionLimit(roles->GetLong(wxT("rolconnlimit"))); + + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 1)) + { + role->iSetReplication(roles->GetBool(wxT("rolreplication"))); + } + + if (collection->GetServer()->GetConnection()->GetIsGreenplum()) + { + role->iSetRolQueueName(roles->GetVal(wxT("rsqname"))); + } + + if (collection->GetServer()->GetConnection()->BackendMinimumVersion(9, 2)) + { + role->iSetProviders(roles->GetVal(wxT("providers"))); + role->iSetLabels(roles->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, role); + roles->MoveNext(); + } + else + break; + } + + delete roles; + } + return role; +} + + +///////////////////////////// + +pgLoginRoleCollection::pgLoginRoleCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgLoginRoleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on login roles"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing login roles"); + break; + case OBJECTSLISTREPORT: + message = _("Login roles list report"); + break; + } + + return message; +} + + +///////////////////////////// + +pgGroupRoleCollection::pgGroupRoleCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +wxString pgGroupRoleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on group roles"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing group roles"); + break; + case OBJECTSLISTREPORT: + message = _("Group roles list report"); + break; + } + + return message; +} + + +pgObject *pgLoginRoleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + if (restriction.IsEmpty()) + return pgRoleBaseFactory::CreateObjects(collection, browser, wxT(" WHERE rolcanlogin")); + else + return pgRoleBaseFactory::CreateObjects(collection, browser, restriction); +} + + +pgObject *pgGroupRoleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + if (restriction.IsEmpty()) + return pgRoleBaseFactory::CreateObjects(collection, browser, wxT(" WHERE NOT rolcanlogin")); + else + return pgRoleBaseFactory::CreateObjects(collection, browser, restriction); +} + + +#include "images/user.pngc" +#include "images/group.pngc" +#include "images/roles.pngc" +#include "images/loginroles.pngc" + + +pgRoleBaseFactory::pgRoleBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img) + : pgServerObjFactory(tn, ns, nls, img) +{ + metaType = PGM_ROLE; +} + +pgLoginRoleFactory::pgLoginRoleFactory() + : pgRoleBaseFactory(__("Login Role"), __("New Login Role..."), __("Create a new Login Role."), user_png_img) +{ +} + +pgCollection *pgLoginRoleFactory::CreateCollection(pgObject *obj) +{ + return new pgLoginRoleCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgLoginRoleFactory loginRoleFactory; +static pgaCollectionFactory lcf(&loginRoleFactory, __("Login Roles"), loginroles_png_img); + + +pgGroupRoleFactory::pgGroupRoleFactory() + : pgRoleBaseFactory(__("Group Role"), __("New Group Role..."), __("Create a new Group Role."), group_png_img) +{ +} + +pgCollection *pgGroupRoleFactory::CreateCollection(pgObject *obj) +{ + return new pgGroupRoleCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgGroupRoleFactory groupRoleFactory; +static pgaCollectionFactory gcf(&groupRoleFactory, __("Group Roles"), roles_png_img); + + +reassignDropOwnedFactory::reassignDropOwnedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Reassign/Drop Owned..."), _("Reassigned or drop objects owned by the selected role.")); +} + + +wxWindow *reassignDropOwnedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgRole *)obj)->ReassignDropOwnedTo(form); + + return 0; +} + +bool reassignDropOwnedFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(loginRoleFactory) && ((pgRole *)obj)->GetConnection()->BackendMinimumVersion(8, 2); +} diff --git a/schema/pgRule.cpp b/schema/pgRule.cpp new file mode 100644 index 0000000..a16bfd2 --- /dev/null +++ b/schema/pgRule.cpp @@ -0,0 +1,356 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgRule.cpp - Rule class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "schema/pgRule.h" + + +pgRule::pgRule(pgSchema *newSchema, const wxString &newName) + : pgRuleObject(newSchema, ruleFactory, newName) +{ +} + +pgRule::~pgRule() +{ +} + +wxString pgRule::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on rule"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing rule"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for rule"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop rule \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop rule \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop rule cascaded?"); + break; + case DROPTITLE: + message = _("Drop rule?"); + break; + case PROPERTIESREPORT: + message = _("Rule properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Rule properties"); + break; + case DDLREPORT: + message = _("Rule DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Rule DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Rule dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Rule dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Rule dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Rule dependents"); + break; + } + + return message; +} + + +int pgRule::GetIconId() +{ + if (GetEnabled()) + return ruleFactory.GetIconId(); + else + return ruleFactory.GetClosedIconId(); +} + + +bool pgRule::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP RULE ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgRule::SetEnabled(ctlTree *browser, const bool b) +{ + if (GetQuotedFullTable().Len() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" "); + if (enabled && !b) + sql += wxT("DISABLE"); + else if (!enabled && b) + sql += wxT("ENABLE"); + sql += wxT(" RULE ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + } + + enabled = b; + UpdateIcon(browser); +} + + +wxString pgRule::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Rule: ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + wxT("\n\n") + + wxT("-- DROP RULE ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + wxT(";\n\n") + + wxT("CREATE OR REPLACE") + GetFormattedDefinition().Mid(6) // the backend pg_get_ruledef gives CREATE only + + wxT("\n"); + + if (!GetEnabled()) + { + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" ") + + wxT("DISABLE RULE ") + GetQuotedIdentifier() + wxT(";\n"); + } + + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON RULE ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + return sql; +} + + +void pgRule::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + wxString def = GetFormattedDefinition(); + if (!def.IsEmpty()) + { + int doPos = def.Find(wxT(" DO INSTEAD ")); + if (doPos > 0) + def = def.Mid(doPos + 12).Strip(wxString::both); + else + { + doPos = def.Find(wxT(" DO ")); + if (doPos > 0) + def = def.Mid(doPos + 4).Strip(wxString::both); + } + } + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Event"), GetEvent()); + properties->AppendItem(_("Condition"), GetCondition()); + properties->AppendYesNoItem(_("Do instead?"), GetDoInstead()); + properties->AppendItem(_("Definition"), firstLineOnly(def)); + if (this->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + properties->AppendYesNoItem(_("Enabled?"), GetEnabled()); + properties->AppendYesNoItem(_("System rule?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgRule::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *rule = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + rule = ruleFactory.CreateObjects(coll, 0, wxT("\n AND rw.oid=") + GetOidStr()); + + return rule; +} + + +pgObject *pgRuleFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgRule *rule = 0; + + pgSet *rules = collection->GetDatabase()->ExecuteSet( + wxT("SELECT rw.oid, rw.*, relname, CASE WHEN relkind = 'r' THEN TRUE ELSE FALSE END AS parentistable, nspname, description,\n") + wxT(" pg_get_ruledef(rw.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition\n") + wxT(" FROM pg_rewrite rw\n") + wxT(" JOIN pg_class cl ON cl.oid=rw.ev_class\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=cl.relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rw.oid AND des.classoid='pg_rewrite'::regclass)\n") + wxT(" WHERE ev_class = ") + NumToStr(collection->GetOid()) + + restriction + wxT("\n") + wxT(" ORDER BY rw.rulename")); + + if (rules) + { + while (!rules->Eof()) + { + // Be careful that the schema of a rule (and a trigger) is the schema of the schema + rule = new pgRule(collection->GetSchema()->GetSchema(), rules->GetVal(wxT("rulename"))); + + rule->iSetOid(rules->GetOid(wxT("oid"))); + rule->iSetComment(rules->GetVal(wxT("description"))); + + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + { + if (rules->GetVal(wxT("ev_enabled")) != wxT("D")) + rule->iSetEnabled(true); + else + rule->iSetEnabled(false); + } + + rule->iSetParentIsTable(rules->GetBool(wxT("parentistable"))); + rule->iSetDoInstead(rules->GetBool(wxT("is_instead"))); + rule->iSetAction(rules->GetVal(wxT("ev_action"))); + wxString definition = rules->GetVal(wxT("definition")); + int doPos = definition.Find(wxT(" DO ")); + int wherePos = definition.Find(wxT(" WHERE ")); + if (wherePos > 0 && wherePos < doPos) + rule->iSetCondition(definition.Mid(wherePos + 7, doPos - wherePos - 7)); + + rule->iSetDefinition(definition); + rule->iSetQuotedFullTable(collection->GetDatabase()->GetQuotedSchemaPrefix(rules->GetVal(wxT("nspname"))) + + qtIdent(rules->GetVal(wxT("relname")))); + const wxChar *evts[] = {0, wxT("SELECT"), wxT("UPDATE"), wxT("INSERT"), wxT("DELETE")}; + int evno = StrToLong(rules->GetVal(wxT("ev_type"))); + if (evno > 0 && evno < 5) + rule->iSetEvent(evts[evno]); + else + rule->iSetEvent(wxT("Unknown")); + + if (browser) + { + browser->AppendObject(collection, rule); + rules->MoveNext(); + } + else + break; + } + + delete rules; + } + return rule; +} + + +///////////////////////////// + + +pgRuleCollection::pgRuleCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgRuleCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on rules"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing rules"); + break; + case OBJECTSLISTREPORT: + message = _("Rules list report"); + break; + } + + return message; +} + + +///////////////////////////// + +#include "images/rule.pngc" +#include "images/rulebad.pngc" +#include "images/rules.pngc" + +pgRuleFactory::pgRuleFactory() + : pgSchemaObjFactory(__("Rule"), __("New Rule..."), __("Create a new Rule."), rule_png_img) +{ + metaType = PGM_RULE; + closedId = addIcon(rulebad_png_img); +} + + +pgCollection *pgRuleFactory::CreateCollection(pgObject *obj) +{ + return new pgRuleCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgRuleFactory ruleFactory; +static pgaCollectionFactory cf(&ruleFactory, __("Rules"), rules_png_img); + + +enabledisableRuleFactory::enabledisableRuleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Rule enabled?"), _("Enable or disable selected rule."), wxITEM_CHECK); +} + + +wxWindow *enabledisableRuleFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgRule *)obj)->SetEnabled(form->GetBrowser(), !((pgRule *)obj)->GetEnabled()); + ((pgRule *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgRule *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool enabledisableRuleFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(ruleFactory) + && ((pgRule *)obj)->GetConnection()->BackendMinimumVersion(8, 3) + && ((pgRule *)obj)->GetParentIsTable(); +} + +bool enabledisableRuleFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(ruleFactory) && ((pgRule *)obj)->GetEnabled(); +} diff --git a/schema/pgSchema.cpp b/schema/pgSchema.cpp new file mode 100644 index 0000000..e9033b3 --- /dev/null +++ b/schema/pgSchema.cpp @@ -0,0 +1,815 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSchema.cpp - schema class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/menu.h" +#include "utils/misc.h" +#include "schema/pgSchema.h" +#include "frm/frmMain.h" +#include "schema/pgCatalogObject.h" +#include "schema/edbPackage.h" +#include "schema/pgCollation.h" +#include "schema/pgDomain.h" +#include "schema/pgAggregate.h" +#include "schema/pgConversion.h" +#include "schema/pgForeignTable.h" +#include "schema/pgFunction.h" +#include "schema/pgOperator.h" +#include "schema/pgOperatorClass.h" +#include "schema/pgOperatorFamily.h" +#include "schema/pgSequence.h" +#include "schema/pgTable.h" +#include "schema/gpExtTable.h" +#include "schema/pgTextSearchConfiguration.h" +#include "schema/pgTextSearchDictionary.h" +#include "schema/pgTextSearchParser.h" +#include "schema/pgTextSearchTemplate.h" +#include "schema/pgType.h" +#include "schema/pgView.h" +#include "schema/gpPartition.h" +#include "schema/edbPrivateSynonym.h" +#include "frm/frmReport.h" + +#include "wx/regex.h" + +pgSchema::pgSchema(const wxString &newName) + : pgSchemaBase(schemaFactory, newName) +{ +} + +wxString pgSchema::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on schema"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing schema"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for schema"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop schema \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop schema \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop schema cascaded?"); + break; + case DROPTITLE: + message = _("Drop schema?"); + break; + case PROPERTIESREPORT: + message = _("Schema properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Schema properties"); + break; + case DDLREPORT: + message = _("Schema DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Schema DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Schema dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Schema dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Schema dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Schema dependents"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup schema \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore schema \"%s\""), + GetFullIdentifier().c_str()); + break; + } + + return message; +} + +pgCatalog::pgCatalog(const wxString &newName) + : pgSchemaBase(catalogFactory, newName) +{ +} + +wxString pgCatalog::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalog"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalog"); + message += wxT(" ") + GetName(); + break; + case PROPERTIESREPORT: + message = _("Catalog properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Catalog properties"); + break; + case DDLREPORT: + message = _("Catalog DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Catalog DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Catalog dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Catalog dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Catalog dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Catalog dependents"); + break; + } + + return message; +} + +pgSchemaBase::pgSchemaBase(pgaFactory &factory, const wxString &newName) + : pgDatabaseObject(factory, newName) +{ +} + +wxString pgCatalog::GetDisplayName() +{ + if (GetFullName() == wxT("pg_catalog")) + return wxT("PostgreSQL (pg_catalog)"); + else if (GetFullName() == wxT("pgagent")) + return wxT("pgAgent (pgagent)"); + else if (GetFullName() == wxT("information_schema")) + return wxT("ANSI (information_schema)"); + else if (GetFullName().StartsWith(wxT("_"))) + return wxT("Slony cluster (") + GetFullName().AfterFirst('_') + wxT(")"); + else if (GetFullName() == wxT("dbo")) + return wxT("Redmond (dbo)"); + else if (GetFullName() == wxT("sys")) + return wxT("Redwood (sys)"); + else + return GetFullName(); +} + + +wxMenu *pgSchemaBase::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + + if (GetCreatePrivilege()) + { + if (settings->GetDisplayOption(_("Aggregates"))) + aggregateFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Collations")) && GetConnection()->BackendMinimumVersion(9, 1)) + collationFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Conversions"))) + conversionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Domains"))) + domainFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Functions"))) + functionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Packages"))) + { + if (GetConnection()->EdbMinimumVersion(8, 0)) + packageFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Procedures"))) + { + if (GetConnection()->BackendMinimumVersion(11, 0)) + procedureFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Operators"))) + operatorFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Sequences"))) + sequenceFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Tables"))) + tableFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("FTS Configurations"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchConfigurationFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("FTS Dictionaries"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchDictionaryFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("FTS Parsers"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchParserFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("FTS Templates"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + textSearchTemplateFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Foreign Tables"))) + { + if (GetConnection()->BackendMinimumVersion(9, 1)) + foreignTableFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Trigger Functions"))) + triggerFunctionFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Types"))) + typeFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Views"))) + viewFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("External Tables"))) + { + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + extTableFactory.AppendMenu(menu); + } + if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 4)) + edbPrivFactory.AppendMenu(menu); + } + return menu; +} + +bool pgSchemaBase::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SCHEMA ") + GetQuotedFullIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgSchemaBase::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + wxString strName = qtIdent(GetName()); + if (GetMetaType() == PGM_CATALOG) + sql = wxT("-- Catalog: ") + GetName() + wxT("\n\n"); + else + sql = wxT("-- Schema: ") + GetName() + wxT("\n\n"); + + sql += wxT("-- DROP SCHEMA ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE SCHEMA ") + strName + + wxT("\n AUTHORIZATION ") + qtIdent(GetOwner()); + sql += wxT(";\n\n"); + + sql += GetGrant(wxT("UC"), wxT("SCHEMA ") + GetQuotedFullIdentifier()) + + GetCommentSql(); + + sql += wxT("\n") + pgDatabase::GetDefaultPrivileges('r', m_defPrivsOnTables, strName); + sql += pgDatabase::GetDefaultPrivileges('S', m_defPrivsOnSeqs, strName); + sql += pgDatabase::GetDefaultPrivileges('f', m_defPrivsOnFuncs, strName); + if (GetConnection()->BackendMinimumVersion(9, 2)) + sql += pgDatabase::GetDefaultPrivileges('T', m_defPrivsOnTypes, strName); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + +void pgSchemaBase::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + + GetDatabase()->GetServer()->iSetLastDatabase(GetDatabase()->GetName()); + GetDatabase()->GetServer()->iSetLastSchema(GetName()); + + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to schema %s"), GetIdentifier().c_str()); + + if (!(GetMetaType() == PGM_CATALOG && (GetFullName() == wxT("dbo") || GetFullName() == wxT("sys") || GetFullName() == wxT("information_schema")))) + { + if (settings->GetDisplayOption(_("Aggregates"))) + browser->AppendCollection(this, aggregateFactory); + if (settings->GetDisplayOption(_("Collations")) && GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, collationFactory); + if (settings->GetDisplayOption(_("Conversions"))) + browser->AppendCollection(this, conversionFactory); + if (settings->GetDisplayOption(_("Domains"))) + browser->AppendCollection(this, domainFactory); + if (settings->GetDisplayOption(_("Foreign Tables")) && GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, foreignTableFactory); + if (settings->GetDisplayOption(_("FTS Configurations"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchConfigurationFactory); + } + if (settings->GetDisplayOption(_("FTS Dictionaries"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchDictionaryFactory); + } + if (settings->GetDisplayOption(_("FTS Parsers"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchParserFactory); + } + if (settings->GetDisplayOption(_("FTS Templates"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, textSearchTemplateFactory); + } + if (settings->GetDisplayOption(_("Functions"))) + browser->AppendCollection(this, functionFactory); + + if (settings->GetDisplayOption(_("Operators"))) + browser->AppendCollection(this, operatorFactory); + if (settings->GetDisplayOption(_("Operator Classes"))) + browser->AppendCollection(this, operatorClassFactory); + + if (settings->GetDisplayOption(_("Operator Families"))) + { + if (GetConnection()->BackendMinimumVersion(8, 3)) + browser->AppendCollection(this, operatorFamilyFactory); + } + + if (settings->GetDisplayOption(_("Packages")) && GetConnection()->EdbMinimumVersion(8, 1)) + browser->AppendCollection(this, packageFactory); + + if (settings->GetDisplayOption(_("Procedures"))) + { + if (GetConnection()->BackendMinimumVersion(11, 0)) + browser->AppendCollection(this, procedureFactory); + } + + if (settings->GetDisplayOption(_("Sequences"))) + browser->AppendCollection(this, sequenceFactory); + if (settings->GetDisplayOption(_("Tables"))) + browser->AppendCollection(this, tableFactory); + if (settings->GetDisplayOption(_("External Tables"))) + { + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + browser->AppendCollection(this, extTableFactory); + } + if (settings->GetDisplayOption(_("Trigger Functions"))) + browser->AppendCollection(this, triggerFunctionFactory); + if (settings->GetDisplayOption(_("Types"))) + browser->AppendCollection(this, typeFactory); + if (settings->GetDisplayOption(_("Views"))) + browser->AppendCollection(this, viewFactory); + if (settings->GetDisplayOption(_("Synonyms")) && GetConnection()->EdbMinimumVersion(8, 4)) + browser->AppendCollection(this, edbPrivFactory); + } + else + browser->AppendCollection(this, catalogObjectFactory); + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + m_defPrivsOnTables = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='r'")); + m_defPrivsOnSeqs = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='S'")); + m_defPrivsOnFuncs = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='f'")); + } + if (GetConnection()->BackendMinimumVersion(9, 2)) + { + m_defPrivsOnTypes = GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = ") + GetOidStr() + wxT(" AND defaclobjtype='T'")); + } + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + properties->AppendItem(_("Default table ACL"), m_defPrivsOnTables); + properties->AppendItem(_("Default sequence ACL"), m_defPrivsOnSeqs); + properties->AppendItem(_("Default function ACL"), m_defPrivsOnFuncs); + } + if (GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("Default type ACL"), m_defPrivsOnTypes); + + if (GetMetaType() != PGM_CATALOG) + properties->AppendYesNoItem(_("System schema?"), GetSystemObject()); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +pgObject *pgSchemaBase::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *schema = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + if (coll->IsCollectionForType(PGM_CATALOG)) + schema = catalogFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n")); + else + schema = schemaFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n")); + } + + return schema; +} + + + +pgObject *pgSchemaBaseFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgSchema *schema = 0; + pgCatalog *catalog = 0; + + wxString restr = restriction; + + if (restr.IsEmpty()) + restr += wxT(" WHERE "); + else + restr += wxT(" AND "); + + if (GetMetaType() != PGM_CATALOG) + { + restr += wxT("NOT "); + } + + restr += wxT("((nspname = 'pg_catalog' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pg_class' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'pgagent' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'pga_job' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname = 'information_schema' AND EXISTS (SELECT 1 FROM pg_class WHERE relname = 'tables' AND relnamespace = nsp.oid LIMIT 1)) OR\n"); + restr += wxT("(nspname LIKE '_%' AND EXISTS (SELECT 1 FROM pg_proc WHERE proname='slonyversion' AND pronamespace = nsp.oid LIMIT 1))\n"); + + // We add the below schemas at initdb time itself. So users cannot create + // schemas of the same name later. However if DB is started in PostgreSQL + // mode, we do not install all other edb-sys.sql objects. So just checking + // for presence of schemas with such names should be enough.. + if (collection->GetConnection()->EdbMinimumVersion(8, 1)) + restr += wxT("OR (nspname = 'dbo' OR nspname = 'sys'))\n"); + else + restr += wxT(")"); + + if (collection->GetConnection()->EdbMinimumVersion(8, 2)) + { + restr += wxT(" AND nsp.nspparent = 0\n"); + // Do not show dbms_job_procedure in schemas + if (!settings->GetShowSystemObjects()) + restr += wxT("AND NOT (nspname = 'dbms_job_procedure' AND EXISTS(SELECT 1 FROM pg_proc WHERE pronamespace = nsp.oid and proname = 'run_job' LIMIT 1))\n"); + } + + if (!collection->GetDatabase()->GetSchemaRestriction().IsEmpty()) + restr += wxT(" AND nspname IN (") + collection->GetDatabase()->GetSchemaRestriction() + wxT(")"); + + // Don't fetch temp schemas if not actually required, as Greenplum seems to + // generate thousands in some circumstances. + if (!settings->GetShowSystemObjects()) + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + restr += wxT(" AND nspname NOT LIKE E'pg\\\\_temp\\\\_%'AND nspname NOT LIKE E'pg\\\\_toast_temp\\\\_%'"); + else + restr += wxT(" AND nspname NOT LIKE 'pg\\\\_temp\\\\_%'AND nspname NOT LIKE 'pg\\\\_toast_temp\\\\_%'"); + } + + wxString sql; + + if (GetMetaType() == PGM_CATALOG) + { + sql = wxT("SELECT 2 AS nsptyp,\n") + wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") + wxT(" FALSE as cancreate\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + else + { + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + { + sql = wxT("SELECT CASE WHEN nspname LIKE E'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE E'pg\\\\_%') THEN 0\n"); + } + else + { + sql = wxT("SELECT CASE WHEN nspname LIKE 'pg\\\\_temp\\\\_%' THEN 1\n") + wxT(" WHEN (nspname LIKE 'pg\\\\_%') THEN 0\n"); + } + sql += wxT(" ELSE 3 END AS nsptyp,\n") + wxT(" nsp.nspname, nsp.oid, pg_get_userbyid(nspowner) AS namespaceowner, nspacl, description,") + wxT(" has_schema_privilege(nsp.oid, 'CREATE') as cancreate"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=nsp.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=nsp.oid) AS providers"); + } + sql += wxT("\n FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=nsp.oid AND des.classoid='pg_namespace'::regclass)\n") + + restr + + wxT(" ORDER BY 1, nspname"); + } + + pgSet *schemas = collection->GetDatabase()->ExecuteSet(sql); + + if (schemas) + { + while (!schemas->Eof()) + { + wxString name = schemas->GetVal(wxT("nspname")); + long nsptyp = schemas->GetLong(wxT("nsptyp")); + + wxStringTokenizer tokens(settings->GetSystemSchemas(), wxT(",")); + while (tokens.HasMoreTokens()) + { + wxRegEx regex(tokens.GetNextToken()); + if (regex.Matches(name)) + { + nsptyp = SCHEMATYP_USERSYS; + break; + } + } + + if (nsptyp <= SCHEMATYP_USERSYS && this->GetMetaType() != PGM_CATALOG && !settings->GetShowSystemObjects()) + { + schemas->MoveNext(); + continue; + } + + if (GetMetaType() == PGM_CATALOG) + { + catalog = new pgCatalog(name); + + catalog->iSetSchemaTyp(nsptyp); + catalog->iSetDatabase(collection->GetDatabase()); + catalog->iSetComment(schemas->GetVal(wxT("description"))); + catalog->iSetOid(schemas->GetOid(wxT("oid"))); + catalog->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); + catalog->iSetAcl(schemas->GetVal(wxT("nspacl"))); + catalog->iSetCreatePrivilege(false); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 0)) + { + catalog->iSetDefPrivsOnTables(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='r'")))); + catalog->iSetDefPrivsOnSeqs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='S'")))); + catalog->iSetDefPrivsOnFuncs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='f'")))); + } + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + { + catalog->iSetDefPrivsOnTypes(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + catalog->GetOidStr() + wxT(" AND defaclobjtype='T'")))); + } + + if (browser) + { + browser->AppendObject(collection, catalog); + schemas->MoveNext(); + } + else + break; + } + else + { + schema = new pgSchema(name); + + schema->iSetSchemaTyp(nsptyp); + schema->iSetDatabase(collection->GetDatabase()); + schema->iSetComment(schemas->GetVal(wxT("description"))); + schema->iSetOid(schemas->GetOid(wxT("oid"))); + schema->iSetOwner(schemas->GetVal(wxT("namespaceowner"))); + schema->iSetAcl(schemas->GetVal(wxT("nspacl"))); + schema->iSetCreatePrivilege(schemas->GetBool(wxT("cancreate"))); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 0)) + { + schema->iSetDefPrivsOnTables(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='r'")))); + schema->iSetDefPrivsOnSeqs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='S'")))); + schema->iSetDefPrivsOnFuncs(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='f'")))); + } + if (collection->GetDatabase()->BackendMinimumVersion(9, 2)) + { + schema->iSetDefPrivsOnTypes(collection->GetConnection()->ExecuteScalar(wxT("SELECT defaclacl FROM pg_catalog.pg_default_acl dacl WHERE dacl.defaclnamespace = " + schema->GetOidStr() + wxT(" AND defaclobjtype='T'")))); + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + schema->iSetProviders(schemas->GetVal(wxT("providers"))); + schema->iSetLabels(schemas->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, schema); + schemas->MoveNext(); + } + else + break; + } + } + + delete schemas; + } + + if (GetMetaType() == PGM_CATALOG) + return catalog; + else + return schema; +} + + +pgObject *pgSchemaBase::ReadObjects(pgCollection *collection, ctlTree *browser) +{ + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT("WHERE ") + collection->GetConnection()->SystemNamespaceRestriction(wxT("nsp.nspname")); + + // Get the schemas + return schemaFactory.CreateObjects(collection, browser, systemRestriction); +} + + +///////////////////////////////////////////////////// + +pgSchemaObjCollection::pgSchemaObjCollection(pgaFactory *factory, pgSchema *sch) + : pgCollection(factory) +{ + schema = sch; + database = schema->GetDatabase(); + server = database->GetServer(); + iSetOid(sch->GetOid()); +} + +bool pgSchemaObjCollection::CanCreate() +{ + if(IsCollectionForType(PGM_OPCLASS) || IsCollectionForType(PGM_OPFAMILY)) + return false; + + // TODO + // OK, this is a hack. Rules and Views are both derived from pgRuleObject, which + // is derived from pgSchemaObject. In order that they attach to the treeview + // under the relevant node however, the Schema object is actually the table or + // View (yeah, I know - I didn't write it :-p ). This works fine *except* for + // Get CreatePrivilege() which doesn't exist in these classes so must be fixed + // up at this level. This needs a major rethink in the longer term + if (GetSchema()->GetMetaType() == PGM_TABLE || GetSchema()->GetMetaType() == PGM_VIEW || GetSchema()->GetMetaType() == GP_EXTTABLE || GetSchema()->GetMetaType() == GP_PARTITION) + return GetSchema()->GetSchema()->GetCreatePrivilege(); + else + return GetSchema()->GetCreatePrivilege(); +} + + +///////////////////////////// + +pgSchemaCollection::pgSchemaCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgSchemaCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on schemas"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing schemas"); + break; + case OBJECTSLISTREPORT: + message = _("Schemas list report"); + break; + } + + return message; +} + +///////////////////////////// + +pgCatalogCollection::pgCatalogCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgCatalogCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on catalogs"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing catalogs"); + break; + case OBJECTSLISTREPORT: + message = _("Catalogs list report"); + break; + } + + return message; +} + +///////////////////////////////////////////////////// + + +#include "images/namespace.pngc" +#include "images/namespace-sm.pngc" +#include "images/namespaces.pngc" +#include "images/catalog.pngc" +#include "images/catalog-sm.pngc" +#include "images/catalogs.pngc" + +pgSchemaBaseFactory::pgSchemaBaseFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm) + : pgDatabaseObjFactory(tn, ns, nls, img, imgSm) +{ + +} + +pgSchemaFactory::pgSchemaFactory() + : pgSchemaBaseFactory(__("Schema"), __("New Schema..."), __("Create a new Schema."), namespace_png_img, namespace_sm_png_img) +{ + metaType = PGM_SCHEMA; +} + +pgCollection *pgSchemaFactory::CreateCollection(pgObject *obj) +{ + return new pgSchemaCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgCatalogFactory::pgCatalogFactory() + : pgSchemaBaseFactory(__("Catalog"), __("New Catalog..."), __("Create a new Catalog."), catalog_png_img, catalog_sm_png_img) +{ + metaType = PGM_CATALOG; +} + +pgCollection *pgCatalogFactory::CreateCollection(pgObject *obj) +{ + return new pgCatalogCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + +pgCollection *pgSchemaObjFactory::CreateCollection(pgObject *obj) +{ + return new pgSchemaObjCollection(GetCollectionFactory(), (pgSchema *)obj); +} + + +pgSchemaFactory schemaFactory; +static pgaCollectionFactory scf(&schemaFactory, __("Schemas"), namespaces_png_img); + +pgCatalogFactory catalogFactory; +static pgaCollectionFactory ccf(&catalogFactory, __("Catalogs"), catalogs_png_img); diff --git a/schema/pgSequence.cpp b/schema/pgSequence.cpp new file mode 100644 index 0000000..d62e83b --- /dev/null +++ b/schema/pgSequence.cpp @@ -0,0 +1,369 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgSequence.cpp - Sequence class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgSequence.h" + + +pgSequence::pgSequence(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, sequenceFactory, newName) +{ + isReplicated = false; +} + +pgSequence::~pgSequence() +{ +} + +wxString pgSequence::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on sequence"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing sequence"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop sequence \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop sequence \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop sequence cascaded?"); + break; + case DROPTITLE: + message = _("Drop sequence?"); + break; + case PROPERTIESREPORT: + message = _("Sequence properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Sequence properties"); + break; + case DDLREPORT: + message = _("Sequence DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Sequence DDL"); + break; + case STATISTICSREPORT: + message = _("Sequence statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Sequence statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Sequence dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Sequence dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Sequence dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Sequence dependents"); + break; + } + + return message; +} + + +int pgSequence::GetIconId() +{ + if (isReplicated) + return sequenceFactory.GetReplicatedIconId(); + else + return sequenceFactory.GetIconId(); +} + +bool pgSequence::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SEQUENCE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgSequence::UpdateValues() +{ + wxString lsql; + wxString tabname = schema->GetQuotedPrefix() + qtIdent(GetName()); + if (GetConnection()->BackendMinimumVersion(10, 0)) + { + + lsql=wxT("SELECT pg_catalog.format_type(seqtypid, NULL) AS \"Type\",\n") + wxT(" seqstart AS \"start\",\n") + wxT(" seqmin AS \"min_value\",\n") + wxT(" seqmax AS \"max_value\",\n") + wxT(" seqincrement AS \"increment_by\",\n") + wxT(" CASE WHEN seqcycle THEN 'yes' ELSE 'no' END AS \"is_cycled\",\n") + wxT(" seqcache AS \"cache_value\",\n") + wxT(" last_value, is_called") + wxT(" FROM pg_catalog.pg_sequence,")+GetQuotedFullIdentifier()+wxT(" s") + wxT(" WHERE seqrelid = ")+GetOidStr()+wxT(""); + + } else + { + lsql=wxT("SELECT last_value, min_value, max_value, cache_value, is_cycled, increment_by, is_called\n") + wxT(" FROM ") + GetQuotedFullIdentifier(); + + } + pgSet *sequence = ExecuteSet(lsql); + + if (sequence) + { + lastValue = sequence->GetLongLong(wxT("last_value")); + minValue = sequence->GetLongLong(wxT("min_value")); + maxValue = sequence->GetLongLong(wxT("max_value")); + cacheValue = sequence->GetLongLong(wxT("cache_value")); + increment = sequence->GetLongLong(wxT("increment_by")); + cycled = sequence->GetBool(wxT("is_cycled")); + called = sequence->GetBool(wxT("is_called")); + if (called) + nextValue = lastValue + increment; + else + nextValue = lastValue; + + delete sequence; + } +} + + +wxString pgSequence::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + UpdateValues(); + sql = wxT("-- Sequence: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP SEQUENCE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE SEQUENCE ") + GetQuotedFullIdentifier() + + wxT("\n INCREMENT ") + GetIncrement().ToString() + + wxT("\n MINVALUE ") + GetMinValue().ToString() + + wxT("\n MAXVALUE ") + GetMaxValue().ToString() + + wxT("\n START ") + GetLastValue().ToString() + + wxT("\n CACHE ") + GetCacheValue().ToString(); + if (GetCycled()) + sql += wxT("\n CYCLE"); + sql += wxT(";\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + + if (!GetConnection()->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); + else + sql += GetGrant(wxT("rwU"), wxT("SEQUENCE ") + GetQuotedFullIdentifier()); + + sql += GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + +void pgSequence::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + UpdateValues(); + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Current value"), GetLastValue()); + properties->AppendItem(_("Next value"), GetNextValue()); + properties->AppendItem(_("Minimum"), GetMinValue()); + properties->AppendItem(_("Maximum"), GetMaxValue()); + properties->AppendItem(_("Increment"), GetIncrement()); + properties->AppendItem(_("Cache"), GetCacheValue()); + properties->AppendYesNoItem(_("Cycled?"), GetCycled()); + properties->AppendYesNoItem(_("Called?"), GetCalled()); + properties->AppendYesNoItem(_("System sequence?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +void pgSequence::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for sequence on ") + GetSchema()->GetIdentifier()); + + // Add the statistics view columns + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = GetSchema()->GetDatabase()->ExecuteSet(wxT( + "SELECT blks_read, blks_hit FROM pg_statio_all_sequences WHERE relid = ") + GetOidStr()); + + if (stats) + { + statistics->InsertItem(0, _("Blocks Read"), PGICON_STATISTICS); + statistics->SetItem(0l, 1, stats->GetVal(wxT("blks_read"))); + statistics->InsertItem(1, _("Blocks Hit"), PGICON_STATISTICS); + statistics->SetItem(1, 1, stats->GetVal(wxT("blks_hit"))); + + delete stats; + } +} + + +pgObject *pgSequence::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *sequence = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + sequence = sequenceFactory.CreateObjects(coll, 0, wxT("\n AND cl.oid=") + GetOidStr()); + + return sequence; +} + + +/////////////////////////////////////////////////// + + +pgSequenceCollection::pgSequenceCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgSequenceCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on sequences"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing sequences"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for sequences"); + break; + case OBJECTSLISTREPORT: + message = _("Sequences list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////////////////////////////////// + + +pgObject *pgSequenceFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgSet *sequences; + pgSequence *sequence = 0; + wxString sql; + + sql = wxT("SELECT cl.oid, relname, pg_get_userbyid(relowner) AS seqowner, relacl, description"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=cl.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=cl.oid) AS providers"); + } + sql += wxT("\n FROM pg_class cl\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=cl.oid AND des.classoid='pg_class'::regclass)\n") + wxT(" WHERE relkind = 'S' AND relnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY relname"); + + sequences = collection->GetDatabase()->ExecuteSet(sql); + + if (sequences) + { + while (!sequences->Eof()) + { + sequence = new pgSequence(collection->GetSchema(), + sequences->GetVal(wxT("relname"))); + + sequence->iSetOid(sequences->GetOid(wxT("oid"))); + sequence->iSetComment(sequences->GetVal(wxT("description"))); + sequence->iSetOwner(sequences->GetVal(wxT("seqowner"))); + sequence->iSetAcl(sequences->GetVal(wxT("relacl"))); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sequence->iSetProviders(sequences->GetVal(wxT("providers"))); + sequence->iSetLabels(sequences->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, sequence); + sequences->MoveNext(); + } + else + break; + } + delete sequences; + } + return sequence; +} + + +#include "images/sequence.pngc" +#include "images/sequences.pngc" + +pgSequenceFactory::pgSequenceFactory() + : pgSchemaObjFactory(__("Sequence"), __("New Sequence..."), __("Create a new Sequence."), sequence_png_img) +{ + metaType = PGM_SEQUENCE; +} + + +pgCollection *pgSequenceFactory::CreateCollection(pgObject *obj) +{ + return new pgSequenceCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgSequenceFactory sequenceFactory; +static pgaCollectionFactory cf(&sequenceFactory, __("Sequences"), sequences_png_img); diff --git a/schema/pgServer.cpp b/schema/pgServer.cpp new file mode 100644 index 0000000..7821b0b --- /dev/null +++ b/schema/pgServer.cpp @@ -0,0 +1,2282 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgServer.cpp - PostgreSQL Server +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include + +// App headers +#include "ctl/ctlMenuToolbar.h" +#include "frm/menu.h" +#include "utils/misc.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "dlg/dlgConnect.h" +#include "schema/pgDatabase.h" +#include "schema/pgTablespace.h" +#include "schema/pgGroup.h" +#include "schema/pgUser.h" +#include "schema/pgRole.h" +#include "schema/gpResQueue.h" +#include "agent/pgaJob.h" +#include "pro_scheduler/pgproJob.h" +#include "utils/utffile.h" +#include "utils/pgfeatures.h" +#include "utils/registry.h" +#include "frm/frmReport.h" +#include "dlg/dlgServer.h" +#include "schema/edbResourceGroup.h" + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) +#include "utils/sshTunnel.h" +#endif + +#define DEFAULT_PG_DATABASE wxT("postgres") + +pgServer::pgServer(const wxString &newName, const wxString &newHostAddr, const wxString &newDescription, const wxString &newService, + const wxString &newDatabase, const wxString &newUsername, int newPort, bool _storePwd, const wxString &newRolename, bool _restore, + int _ssl, const wxString &_colour, const wxString &_group, bool _sshTunnel, const wxString &newTunnelHost, const wxString &newTunnelUserName, + bool _authModePwd, const wxString &newTunnelPassword, const wxString &newPublicKey, const wxString &newIdentity, const int &sshPort) + : pgObject(serverFactory, newName) +{ + description = newDescription; + hostaddr = newHostAddr; + service = newService; + database = newDatabase; + username = newUsername; + port = newPort; + ssl = _ssl; + colour = _colour; + group = _group; + + serverIndex = 0; + + connected = false; + lastSystemOID = 0; + + conn = NULL; + passwordValid = true; + storePwd = _storePwd; + rolename = newRolename; + restore = _restore; + superUser = false; + createPrivilege = false; + sshTunnel = _sshTunnel; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + // SSH Tunnel + tunnelObj = NULL; + tunnelHost = newTunnelHost; + tunnelUserName = newTunnelUserName; + authModePwd = _authModePwd; + tunnelPassword = newTunnelPassword; + publicKeyFile = newPublicKey; + identityFile = newIdentity; + tunnelPort = sshPort; +#endif + +#ifdef WIN32 + scmHandle = 0; + serviceHandle = 0; +#endif +} + +pgServer::~pgServer() +{ + if (conn) + delete conn; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(tunnelObj) + { + if(tunnelObj->IsAlive()) + { + tunnelObj->Cleanup(); + } + tunnelObj = NULL; + } +#endif + +#ifdef WIN32 + if (serviceHandle) + CloseServiceHandle(serviceHandle); + if (scmHandle) + CloseServiceHandle(scmHandle); +#endif +} + + +wxString pgServer::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on server"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing server"); + message += wxT(" ") + GetName(); + break; + case BACKUPGLOBALS: + message = _("Backup globals of server"); + message += wxT(" ") + GetName(); + break; + case BACKUPSERVERTITLE: + message = _("Backup server"); + message += wxT(" ") + GetName(); + break; + case DROPTITLE: + message = _("Drop server?"); + break; + case PROPERTIESREPORT: + message = _("Server properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Server properties"); + break; + case STATISTICSREPORT: + message = _("Server statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Server statistics"); + break; + } + + return message; +} + + +int pgServer::GetIconId() +{ + if (GetConnected()) + return serverFactory.GetIconId(); + else + return serverFactory.GetClosedIconId(); +} + + +wxMenu *pgServer::GetNewMenu() +{ + wxMenu *menu = 0; + if (connected && (GetSuperUser() || GetCreateRole())) + { + menu = new wxMenu(); + if (settings->GetDisplayOption(_("Tablespaces"))) + tablespaceFactory.AppendMenu(menu); + if (GetConnection()->BackendMinimumVersion(8, 1)) + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + groupRoleFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Users/login Roles"))) + loginRoleFactory.AppendMenu(menu); + if (GetConnection()->GetIsGreenplum()) + { + if (settings->GetDisplayOption(_("Resource Queues"))) + resQueueFactory.AppendMenu(menu); + } + } + else + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + groupFactory.AppendMenu(menu); + if (settings->GetDisplayOption(_("Users/login Roles"))) + userFactory.AppendMenu(menu); + } + // Added Resource Group only for PPAS 9.4 and above + if (conn->GetIsEdb() && conn->EdbMinimumVersion(9, 4)) + { + if (settings->GetDisplayOption(_("Resource Groups"))) + resourceGroupFactory.AppendMenu(menu); + } + } + return menu; +} + +pgServer *pgServer::GetServer() const +{ + if (connected) + return (pgServer *)this; + return 0; +} + + +pgConn *pgServer::CreateConn(wxString dbName, OID oid, wxString applicationname) +{ + if (!connected) + return 0; + + if (dbName.IsEmpty()) + { + dbName = GetDatabaseName(); + oid = dbOid; + } + + pgConn *conn = NULL; +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(sshTunnel) + { + conn = new pgConn(local_listenhost, service, hostaddr, dbName, username, password, local_listenport, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + } + else +#endif + { + conn = new pgConn(GetName(), service, hostaddr, dbName, username, password, port, rolename, ssl, oid, applicationname, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + } + + if (conn && conn->GetStatus() != PGCONN_OK) + { + wxLogError(wxT("%s"), conn->GetLastError().c_str()); + delete conn; + return 0; + } + return conn; +} + + +wxString pgServer::GetFullName() +{ + if (GetDescription().Length() > 0) + return GetDescription() + wxT(" (") + GetIdentifier() + wxT(")"); + else + return wxT("(") + GetIdentifier() + wxT(")"); +} + +wxString pgServer::GetFullIdentifier() +{ + return GetFullName(); +} + +bool pgServer::Disconnect(frmMain *form) +{ +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(tunnelObj) + { + if(tunnelObj->IsAlive()) + { + tunnelObj->Cleanup(); + } + tunnelObj = NULL; + } +#endif + + if (conn) + { + delete conn; + conn = 0; + connected = false; + expandedKids = false; + ver = wxT(""); + versionNum = wxT(""); + lastSystemOID = 0; + } + + if (form) + UpdateIcon(form->GetBrowser()); + + return true; +} + + +bool pgServer::GetCanHint() +{ + return connected && conn->BackendMinimumVersion(8, 1) && !autovacuumRunning; +} + + +void pgServer::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + + if (!autovacuumRunning) + hints.Add(HINT_AUTOVACUUM); + + if (force || !hintShown) + frmHint::ShowHint(form, hints, GetFullIdentifier(), force); + hintShown = true; +} + + +#define SERVICEBUFSIZE 10000 +#define QUERYBUFSIZE 256 + +#ifdef WIN32 +wxArrayString pgServer::GetDependentServices(SC_HANDLE handle) +{ + wxArrayString services; + LPENUM_SERVICE_STATUS sbuf = (LPENUM_SERVICE_STATUS) new char[SERVICEBUFSIZE]; + + DWORD servicesReturned = 0, bytesNeeded; + ::EnumDependentServices(handle, SERVICE_STATE_ALL, sbuf, SERVICEBUFSIZE, &bytesNeeded, &servicesReturned); + + + DWORD i; + for (i = 0 ; i < servicesReturned ; i++) + { + SC_HANDLE h =::OpenService(scmHandle, sbuf[i].lpServiceName, SERVICE_QUERY_CONFIG); + if (h) + { + char buffer[QUERYBUFSIZE]; + LPQUERY_SERVICE_CONFIG qsc = (LPQUERY_SERVICE_CONFIG)buffer; + if(::QueryServiceConfig(h, qsc, QUERYBUFSIZE, &bytesNeeded)) + { + if (qsc->dwStartType != SERVICE_DISABLED) + services.Add(sbuf[i].lpServiceName); + } + + ::CloseServiceHandle(h); + } + } + delete[] sbuf; + + return services; +} +#endif + + +bool pgServer::StartService() +{ + bool done = false; +#ifdef WIN32 + if (serviceHandle) + { + done = (::StartService(serviceHandle, 0, 0) != 0); + if (!done) + { + DWORD rc = ::GetLastError(); + if (rc == ERROR_SERVICE_ALREADY_RUNNING) + { + GetServerRunning(); + return true; + } + // report error + wxLogError(__("Failed to start server %s: Errcode=%d\nCheck event log for details."), + serviceId.c_str(), rc); + } + else + { + GetServerRunning(); // ignore result, just to wait for startup + + wxArrayString services = GetDependentServices(serviceHandle); + + if (services.GetCount() > 0) + { + size_t i; + wxString serviceString; + for (i = 0 ; i < services.GetCount() ; i++) + serviceString += wxT(" ") + services.Item(i) + wxT("\n"); + + wxMessageDialog msg(0, _("There are dependent services configured:\n\n") + + serviceString + _("\nStart dependent services too?"), _("Dependent services"), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + + if (msg.ShowModal() == wxID_YES) + { + for (i = 0 ; i < services.GetCount() ; i++) + { + SC_HANDLE h =::OpenService(scmHandle, services.Item(i), GENERIC_EXECUTE | GENERIC_READ); + if (h) + { + if (!::StartService(h, 0, 0)) + done = false; + CloseServiceHandle(h); + } + else + done = false; + } + if (!done) + { + wxMessageDialog msg(0, _("One or more dependent services didn't start; see the eventlog for details."), _("Service start problem"), + wxICON_EXCLAMATION | wxOK); + msg.ShowModal(); + done = true; + } + } + } + } + } +#else + wxString res = ExecProcess(serviceId + wxT(" start")); + done = (res.Find(wxT("tarting")) > 0); +#endif + return done; +} + + +bool pgServer::StopService() +{ + bool done = false; +#ifdef WIN32 + if (serviceHandle) + { + SERVICE_STATUS st; + + done = (::ControlService(serviceHandle, SERVICE_CONTROL_STOP, &st) != 0); + if (!done) + { + if (::GetLastError() == ERROR_DEPENDENT_SERVICES_RUNNING) + { + LPENUM_SERVICE_STATUS sbuf = (LPENUM_SERVICE_STATUS) new char[SERVICEBUFSIZE]; + DWORD bytesNeeded, servicesReturned = 0; + ::EnumDependentServices(serviceHandle, SERVICE_ACTIVE, sbuf, SERVICEBUFSIZE, &bytesNeeded, &servicesReturned); + + done = true; + + if (servicesReturned) + { + DWORD i; + wxString services; + for (i = 0 ; i < servicesReturned ; i++) + services += wxT(" ") + wxString(sbuf[i].lpDisplayName) + wxT("\n"); + + wxMessageDialog msg(0, _("There are dependent services running:\n\n") + + services + _("\nStop dependent services?"), _("Dependent services"), + wxICON_EXCLAMATION | wxYES_NO | wxYES_DEFAULT); + if (msg.ShowModal() != wxID_YES) + return false; + + for (i = 0 ; done && i < servicesReturned ; i++) + { + SC_HANDLE h =::OpenService(scmHandle, sbuf[i].lpServiceName, GENERIC_EXECUTE | GENERIC_READ); + if (h) + { + done = (::ControlService(h, SERVICE_CONTROL_STOP, &st) != 0); + CloseServiceHandle(h); + } + else + done = false; + } + if (done) + { + done = (::ControlService(serviceHandle, SERVICE_CONTROL_STOP, &st) != 0); + + int retries = 10; + while (!done && retries > 0) + { + done = (::ControlService(serviceHandle, SERVICE_CONTROL_STOP, &st) != 0); + retries--; + + wxSleep(5); + } + + } + } + } + // report error + + if (!done) + wxLogError(__("Failed to stop server %s: Errcode=%d\nCheck event log for details."), + serviceId.c_str(), ::GetLastError()); + } + } +#else + wxString res = ExecProcess(serviceId + wxT(" stop")); + done = (res.Find(wxT("stopped")) > 0); +#endif + return done; +} + + +bool pgServer::GetServerRunning() +{ + bool done = false; +#ifdef WIN32 + if (serviceHandle) + { + SERVICE_STATUS st; + int loops; + + for (loops = 0 ; loops < 20 ; loops++) + { + if (::QueryServiceStatus(serviceHandle, &st) == 0) + { + DWORD rc = ::GetLastError(); + CloseServiceHandle(serviceHandle); + CloseServiceHandle(scmHandle); + serviceHandle = 0; + scmHandle = 0; + + return false; + } + done = (st.dwCurrentState == SERVICE_RUNNING); + if (st.dwCurrentState == SERVICE_START_PENDING) + Sleep(100); + else + break; + } + } +#else + + wxString res = ExecProcess(serviceId + wxT(" status")); + done = (res.Find(wxT("PID: ")) > 0); + +#endif + return done; +} + + +void pgServer::iSetServiceID(const wxString &s) +{ + serviceId = s; +#ifdef WIN32 + if (serviceId.Find('\\') < 0) + scmHandle = OpenSCManager(0, SERVICES_ACTIVE_DATABASE, GENERIC_EXECUTE); + else + scmHandle = OpenSCManager(wxT("\\\\") + serviceId.BeforeFirst('\\'), SERVICES_ACTIVE_DATABASE, GENERIC_EXECUTE | GENERIC_READ); + + if (scmHandle) + serviceHandle = OpenService(scmHandle, serviceId.AfterLast('\\'), GENERIC_EXECUTE | GENERIC_READ); +#endif +} + + +bool pgServer::GetServerControllable() +{ +#ifdef WIN32 + return serviceHandle != 0; +#else + return !serviceId.IsEmpty(); +#endif +} + + +wxString pgServer::passwordFilename() +{ + wxString fname = sysSettings::GetConfigFile(sysSettings::PGPASS); + + wxLogInfo(wxT("Using password file %s"), fname.c_str()); + return fname; +} + + + +bool pgServer::GetPasswordIsStored() +{ + wxString fname = passwordFilename(); + + + if (!wxFile::Exists(fname)) + return false; + + wxUtfFile file(fname, wxFile::read, wxFONTENCODING_SYSTEM); + + if (file.IsOpened()) + { + wxString before; + file.Read(before); + + wxStringTokenizer lines(before, wxT("\n\r")); + + wxString seekStr = GetName() + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + username + wxT(":") ; + + wxString seekStr2 = wxString(GetName().mb_str(wxConvUTF8), wxConvLibc) + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + wxString(username.mb_str(wxConvUTF8), wxConvLibc) + wxT(":") ; + + while (lines.HasMoreTokens()) + { + wxString str = lines.GetNextToken(); + if (str.Left(seekStr.Length()) == seekStr) + return true; + + if (str.Left(seekStr2.Length()) == seekStr2) + return true; + } + } + + return false; +} + + +void pgServer::StorePassword() +{ + wxString fname = passwordFilename(); + + if (!wxFile::Exists(fname)) + { + return; + } + wxUtfFile file; + // Don't try to read and write in one OP - it doesn't work well + wxString before; + file.Open(fname, wxFile::read, wxFONTENCODING_SYSTEM); + file.Read(before); + file.Close(); + + file.Open(fname, wxFile::write, wxFONTENCODING_SYSTEM); + + if (file.IsOpened()) + { + wxString after; + + wxString passwd; + wxString seekStr; + + if (GetConnection()->GetNeedUtfConnectString()) + { + passwd = wxString(password.mb_str(wxConvUTF8), wxConvLibc); + seekStr = wxString(GetName().mb_str(wxConvUTF8), wxConvLibc) + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + wxString(username.mb_str(wxConvUTF8), wxConvLibc) + wxT(":") ; + } + else + { + passwd = password; + seekStr = GetName() + wxT(":") + + NumToStr((long)GetPort()) + wxT(":*:") + + username + wxT(":") ; + } + + // Escape ":" and "\" from the password field + if (!passwd.IsEmpty()) + { + passwd.Replace(wxT("\\"), wxT("\\\\")); + passwd.Replace(wxT(":") , wxT("\\:")); + } + + file.Read(before); + wxStringTokenizer lines(before, wxT("\n\r")); + + file.Seek(0); + bool found = false; + while (lines.HasMoreTokens()) + { + wxString str = lines.GetNextToken(); + if (str.Left(seekStr.Length()) == seekStr && !passwd.IsEmpty()) + { + // entry found + found = true; + if (storePwd) + file.Write(seekStr + passwd + END_OF_LINE); + } + else + file.Write(str + END_OF_LINE); + } + if (!found && storePwd && !passwd.IsEmpty()) + file.Write(seekStr + passwd + END_OF_LINE); + + file.Close(); + } +} + + +int pgServer::Connect(frmMain *form, bool askPassword, const wxString &pwd, bool forceStorePassword, bool askTunnelPassword) +{ + wxLogInfo(wxT("Attempting to create a connection object...")); + + bool storePassword = false; + + if (!conn || conn->GetStatus() != PGCONN_OK) + { + if (conn) + { + delete conn; + conn = 0; + } + if (askPassword) + { + if ((sshTunnel || !passwordValid || !GetPasswordIsStored() || !GetStorePwd()) && GetSSLCert() == wxEmptyString) + { + wxString txt; + txt.Printf(_("Please enter password for user %s\non server %s (%s)"), username.c_str(), description.c_str(), GetName().c_str()); + dlgConnect *dlg = NULL; + // if sshTunnel is true then we have to hide 'Stored Password' option + if(sshTunnel) + dlg = new dlgConnect(NULL, txt, false); + else + dlg = new dlgConnect(form, txt, GetStorePwd()); + + dlg->SetWindowStyleFlag( dlg->GetWindowStyleFlag() | wxSTAY_ON_TOP); + + switch (dlg->Go()) + { + case wxID_OK: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + break; + case wxID_CANCEL: + case -1: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + return PGCONN_ABORTED; + default: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + wxLogError(__("Couldn't create a connection dialogue!")); + return PGCONN_BAD; + } + + iSetStorePwd(dlg->GetStorePwd()); + password = dlg->GetPassword(); + storePassword = true; + if(dlg) + { + delete dlg; + dlg = NULL; + } + } + } + else + iSetPassword(pwd); + + form->StartMsg(_("Connecting to database")); + + wxString host; + int iPort; +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(sshTunnel) + { + //Ask Tunnel Password + if(askTunnelPassword) + { + wxString txt; + if(GetAuthModePwd()) + { + txt.Printf(_("Please enter the SSH tunnel password for user %s\non server %s"), tunnelUserName.c_str(), tunnelHost.c_str()); + } + else + { + txt.Printf(_("Please enter the pass phrase for the identity file\n%s"), identityFile.c_str()); + } + dlgConnect dlg(NULL, txt, false); + + switch (dlg.Go()) + { + case wxID_OK: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + tunnelPassword = dlg.GetPassword(); + break; + case wxID_CANCEL: + case -1: + default: + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + form->EndMsg(false); + return PGCONN_ABORTED; + } + } + // Create SSH Tunnel if required + if(!tunnelObj) + { + if(!createSSHTunnel()) + { + form->EndMsg(false); + return PGCONN_SSHTUNNEL_ERROR; + } + } + + host = local_listenhost; + iPort = local_listenport; + } + else +#endif + { + host = GetName(); + iPort = port; + } + wxString usr=wxEmptyString; + wxGetEnv(wxT("USERNAME"),&usr); + if (database.IsEmpty()) + { + conn = new pgConn(host, service, hostaddr, DEFAULT_PG_DATABASE, username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() +wxT(" - ")+ usr, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + if (conn->GetStatus() == PGCONN_OK) + database = DEFAULT_PG_DATABASE; + else if (conn->GetStatus() == PGCONN_BAD && conn->GetLastError().Find( + wxT("database \"") DEFAULT_PG_DATABASE wxT("\" does not exist")) >= 0) + { + delete conn; + conn = new pgConn(host, service, hostaddr, wxT("template1"), username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + wxT(" - Browser"), sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + if (conn && conn->GetStatus() == PGCONN_OK) + database = wxT("template1"); + } + } + else + { + conn = new pgConn(host, service, hostaddr, database, username, password, iPort, rolename, ssl, 0, appearanceFactory->GetLongAppName() + _(" ")+usr, sslcert, sslkey, sslrootcert, sslcrl, sslcompression); + if (!conn) + { + form->EndMsg(false); + wxLogError(__("Couldn't create a connection object!")); + return PGCONN_BAD; + } + } + } + int status = conn->GetStatus(); + if (status == PGCONN_OK) + { + dbOid = conn->GetDbOid(); + + // Check the server version + if (conn->GetIsGreenplum()) + { + // Greenplum HAWQ (SQL on Hadoop) is not supported by this pgAdmin version + if (conn->GetIsHawq()) + { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str()); + } + else + { + // Check for Greenplum specific version + // Greenplum always shows PG version "8.2.15" for now + // this might change once the merge with recent PG versions makes progress + // therefore also check for the max version + if (!(conn->BackendMinimumVersion(GP_MIN_VERSION_N >> 8, GP_MIN_VERSION_N & 0x00FF)) || + (conn->BackendMinimumVersion(GP_MAX_VERSION_N >> 8, (GP_MAX_VERSION_N & 0x00FF) + 1))) + { + if (GP_MIN_VERSION_N == GP_MAX_VERSION_N) + { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected.\n\nSupported server version is %s."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str(), + wxString(GP_MIN_VERSION_T).c_str()); + } + else + { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected.\n\nSupported server versions are %s to %s."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str(), + wxString(GP_MIN_VERSION_T).c_str(), + wxString(GP_MAX_VERSION_T).c_str()); + } + } + } + } + else + { + if (!(conn->BackendMinimumVersion(SERVER_MIN_VERSION_N >> 8, SERVER_MIN_VERSION_N & 0x00FF)) || + (conn->BackendMinimumVersion(SERVER_MAX_VERSION_N >> 8, (SERVER_MAX_VERSION_N & 0x00FF) + 1))) { + wxLogWarning(_("The server you are connecting to is not a version that is supported by this release of %s.\n\n%s may not function as expected.\n\nSupported server versions are %s to %s."), + appearanceFactory->GetLongAppName().c_str(), + appearanceFactory->GetLongAppName().c_str(), + wxString(SERVER_MIN_VERSION_T).c_str(), + wxString(SERVER_MAX_VERSION_T).c_str()); + } + } + + connected = true; + bool hasUptime = false; + + wxString sql = wxT("SELECT usecreatedb, usesuper"); + if (conn->BackendMinimumVersion(8, 1)) + { + hasUptime = true; + sql += wxT(", CASE WHEN usesuper THEN pg_postmaster_start_time() ELSE NULL END as upsince"); + } + else if (conn->HasFeature(FEATURE_POSTMASTER_STARTTIME)) + { + hasUptime = true; + sql += wxT(", CASE WHEN usesuper THEN pg_postmaster_starttime() ELSE NULL END as upsince"); + } + if (conn->BackendMinimumVersion(8, 4)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_conf_load_time() ELSE NULL END as confloadedsince"); + } + if (conn->BackendMinimumVersion(8, 5)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_is_in_recovery() ELSE NULL END as inrecovery"); + if (conn->BackendMinimumVersion(10, 0)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_last_wal_receive_lsn() ELSE NULL END as receiveloc"); + sql += wxT(", CASE WHEN usesuper THEN pg_last_wal_replay_lsn() ELSE NULL END as replayloc"); + } + else + { + sql += wxT(", CASE WHEN usesuper THEN pg_last_xlog_receive_location() ELSE NULL END as receiveloc"); + sql += wxT(", CASE WHEN usesuper THEN pg_last_xlog_replay_location() ELSE NULL END as replayloc"); + } + } + if (conn->BackendMinimumVersion(9, 1)) + { + sql += wxT(", CASE WHEN usesuper THEN pg_last_xact_replay_timestamp() ELSE NULL END as replay_timestamp"); + if (conn->BackendMinimumVersion(10, 0)) + sql += wxT(", CASE WHEN usesuper AND pg_is_in_recovery() THEN pg_is_wal_replay_paused() ELSE NULL END as isreplaypaused"); + else + sql += wxT(", CASE WHEN usesuper AND pg_is_in_recovery() THEN pg_is_xlog_replay_paused() ELSE NULL END as isreplaypaused"); + } + + pgSet *set = ExecuteSet(sql + wxT("\n FROM pg_user WHERE usename=current_user")); + if (set) + { + iSetCreatePrivilege(set->GetBool(wxT("usecreatedb"))); + iSetSuperUser(set->GetBool(wxT("usesuper"))); + if (hasUptime) + iSetUpSince(set->GetDateTime(wxT("upsince"))); + if (conn->BackendMinimumVersion(8, 4)) + iSetConfLoadedSince(set->GetDateTime(wxT("confloadedsince"))); + if (conn->BackendMinimumVersion(8, 5)) + { + iSetInRecovery(set->GetBool(wxT("inrecovery"))); + iSetReplayLoc(set->GetVal(wxT("replayloc"))); + iSetReceiveLoc(set->GetVal(wxT("receiveloc"))); + } + if (conn->BackendMinimumVersion(9, 1)) + { + iSetReplayTimestamp(set->GetVal(wxT("replay_timestamp"))); + SetReplayPaused(set->GetBool(wxT("isreplaypaused"))); + } + delete set; + } + + if (conn->BackendMinimumVersion(8, 1)) + { + set = ExecuteSet(wxT("SELECT rolcreaterole, rolcreatedb FROM pg_roles WHERE rolname = current_user;")); + + if (set) + { + iSetCreatePrivilege(set->GetBool(wxT("rolcreatedb"))); + iSetCreateRole(set->GetBool(wxT("rolcreaterole"))); + delete set; + } + } + else + iSetCreateRole(false); + + wxString version, allVersions; + version.Printf(wxT("%d.%d"), conn->GetMajorVersion(), conn->GetMinorVersion()); + allVersions = settings->Read(wxT("Updates/pgsql-Versions"), wxEmptyString); + if (allVersions.Find(version) < 0) + { + if (!allVersions.IsEmpty()) + allVersions += wxT(", "); + allVersions += version; + settings->Write(wxT("Updates/pgsql-Versions"), allVersions); + } + if (conn->IsSSLconnected()) + settings->WriteBool(wxT("Updates/UseSSL"), true); + + UpdateIcon(form->GetBrowser()); + if (storePassword || forceStorePassword) + StorePassword(); + } + else + { + connected = false; + } + + form->EndMsg(connected && status == PGCONN_OK); + + passwordValid = connected; + return status; +} + + +wxString pgServer::GetIdentifier() const +{ + wxString idstr; + if (GetService().IsEmpty()) + { + if (GetName().IsEmpty()) + idstr.Printf(wxT("local:.s.PGSQL.%d"), port); + else if (GetName().StartsWith(wxT("/"))) + idstr.Printf(wxT("local:%s/.s.PGSQL.%d"), GetName().c_str(), port); + else + idstr.Printf(wxT("%s:%d"), GetName().c_str(), port); + } + else + idstr.Printf(_("service %s"), GetService().c_str()); + return idstr; +} + + +wxString pgServer::GetVersionString() +{ + if (connected) + { + if (ver.IsEmpty()) + ver = wxString(conn->GetVersionString()); + return ver; + } + else + return wxEmptyString; +} + + +wxString pgServer::GetVersionNumber() +{ + if (connected) + { + if (versionNum.IsEmpty()) + { + int major = 0, minor = 0; + sscanf(GetVersionString().ToAscii(), "%*s %d.%d", &major, &minor); + versionNum.Printf(wxT("%d.%d"), major, minor); + } + + } + return versionNum; +} + + +OID pgServer::GetLastSystemOID() +{ + if (connected) + { + if (lastSystemOID == 0) + lastSystemOID = conn->GetLastSystemOID(); + return lastSystemOID; + } + else + return 0; +} + + +bool pgServer::SetPassword(const wxString &newVal) +{ + wxString sql; + sql.Printf(wxT("ALTER USER %s WITH ENCRYPTED PASSWORD %s;"), qtIdent(username).c_str(), qtDbString(conn->EncryptPassword(username, newVal)).c_str()); + bool executed = conn->ExecuteVoid(sql); + if (executed) + { + password = newVal; + StorePassword(); + return true; + } + else + return false; +} + + +wxString pgServer::GetLastError() const +{ + wxString msg; + if (conn) + { + if (error != wxT("")) + { + if (conn->GetLastError() != wxT("")) + { + msg.Printf(wxT("%s\n%s"), error.c_str(), conn->GetLastError().c_str()); + } + else + { + msg = error; + } + } + else + { + msg = conn->GetLastError(); + } + } + return msg; +} + + + +void pgServer::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + // Add child nodes if necessary + if (GetConnected()) + { + // Reset password menu option +// form->fileMenu->Enable(MNU_PASSWORD, true); + + if (!expandedKids) + { + expandedKids = true; + // Log + + wxLogInfo(wxT("Adding child object to server %s"), GetIdentifier().c_str()); + + if (settings->GetDisplayOption(_("Databases"))) + browser->AppendCollection(this, databaseFactory); + + if (conn->BackendMinimumVersion(8, 0) && settings->GetDisplayOption(_("Tablespaces"))) + browser->AppendCollection(this, tablespaceFactory); + + // Jobs + // We only add the Jobs node if the appropriate objects are the initial DB. + if (settings->GetDisplayOption(_("pgAgent Jobs"))) + { + wxString exists = conn->ExecuteScalar( + wxT("SELECT cl.oid FROM pg_class cl JOIN pg_namespace ns ON ns.oid=relnamespace\n") + wxT(" WHERE relname='pga_job' AND nspname='pgagent'")); + + if (!exists.IsNull()) + { + exists = conn->ExecuteScalar(wxT("SELECT has_schema_privilege('pgagent', 'USAGE')")); + + if (exists == wxT("t")) + browser->AppendCollection(this, jobFactory); + } + } + if (settings->GetDisplayOption(_("pgpro_scheduler"))) + { + wxString exists = conn->ExecuteScalar( + wxT("select true ok from pg_extension where extname='pgpro_scheduler'\n")); + + if (!exists.IsNull()) + { + browser->AppendCollection(this, projobFactory); + } + } + + if (conn->BackendMinimumVersion(8, 1)) + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + browser->AppendCollection(this, groupRoleFactory); + if (settings->GetDisplayOption(_("Users/login Roles"))) + browser->AppendCollection(this, loginRoleFactory); + if (GetConnection()->GetIsGreenplum()) + { + if (settings->GetDisplayOption(_("Resource Queues"))) + browser->AppendCollection(this, resQueueFactory); + } + } + else + { + if (settings->GetDisplayOption(_("Groups/group Roles"))) + browser->AppendCollection(this, groupFactory); + if (settings->GetDisplayOption(_("Users/login Roles"))) + browser->AppendCollection(this, userFactory); + } + + // Added Resource Group only for PPAS 9.4 and above + if (conn->GetIsEdb() && conn->EdbMinimumVersion(9, 4)) + { + if (settings->GetDisplayOption(_("Resource Groups"))) + browser->AppendCollection(this, resourceGroupFactory); + } + + autovacuumRunning = true; + + wxString qry; + if (conn->BackendMinimumVersion(8, 3)) + qry = wxT("SELECT setting FROM pg_settings WHERE name IN ('autovacuum', 'track_counts')"); + else + qry = wxT("SELECT setting FROM pg_settings WHERE name IN ('autovacuum', 'stats_start_collector', 'stats_row_level')"); + + pgSetIterator set(conn, qry); + + while (autovacuumRunning && set.RowsLeft()) + autovacuumRunning = set.GetBool(wxT("setting")); + } + } + + + if (properties) + { + // Add the properties view columns + CreateListColumns(properties); + + // Display the Server properties + + properties->AppendItem(_("Description"), GetDescription()); + properties->AppendItem(_("Service"), GetService()); + if (GetName().IsEmpty() || GetName().StartsWith(wxT("/"))) + { + if (GetName().IsEmpty() && !GetService().IsEmpty()) + properties->AppendItem(_("Hostname"), wxEmptyString); + else + properties->AppendItem(_("Hostname"), wxT("local:") + GetName()); + + if (GetPort() == 0 && !GetService().IsEmpty()) + properties->AppendItem(_("Port"), wxEmptyString); + else + properties->AppendItem(_("Port"), (long)GetPort()); + } + else + { + properties->AppendItem(_("Hostname"), GetName()); + properties->AppendItem(_("Host Address"), GetHostAddr()); + if (GetPort() == 0 && !GetService().IsEmpty()) + properties->AppendItem(_("Port"), wxEmptyString); + else + properties->AppendItem(_("Port"), (long)GetPort()); +#ifdef PG_SSL + if (GetConnected()) + { + properties->AppendItem(_("Encryption"), + conn->IsSSLconnected() ? _("SSL encrypted") : _("not encrypted")); + } + else + { + if (ssl > 0) + { + wxString sslMode; + switch (ssl) + { + case 1: + sslMode = _("require"); + break; + case 2: + sslMode = _("prefer"); + break; + case 3: + sslMode = _("allow"); + break; + case 4: + sslMode = _("disable"); + break; + case 5: + sslMode = _("verify-ca"); + break; + case 6: + sslMode = _("verify-full"); + break; + } + properties->AppendItem(_("SSL Mode"), sslMode); + } + } + properties->AppendItem(_("SSL Certificate File"), GetSSLCert()); + properties->AppendItem(_("SSL Key File"), GetSSLKey()); + properties->AppendItem(_("SSL Root Certificate File"), GetSSLRootCert()); + properties->AppendItem(_("SSL Certificate Revocation List"), GetSSLCrl()); + properties->AppendItem(_("SSL Compression?"), (GetSSLCompression() ? _("yes") : _("no"))); +#endif + } + if (!serviceId.IsEmpty()) + properties->AppendItem(_("Service ID"), serviceId); + + properties->AppendItem(_("Maintenance database"), GetDatabaseName()); + properties->AppendItem(_("Username"), GetUsername()); + if (!GetRolename().IsEmpty()) + properties->AppendItem(_("Default role"), GetRolename()); + + properties->AppendYesNoItem(_("Store password?"), GetStorePwd()); + properties->AppendYesNoItem(_("Restore environment?"), GetRestore()); + if (GetConnected()) + { + properties->AppendItem(_("Version string"), GetVersionString()); + properties->AppendItem(_("Version number"), GetVersionNumber()); + properties->AppendItem(_("Last system OID"), GetLastSystemOID()); + } + properties->AppendYesNoItem(_("Connected?"), GetConnected()); + if (GetConnected()) + { + if (GetUpSince().IsValid()) + properties->AppendItem(_("Up since"), GetUpSince()); + if (GetConfLoadedSince().IsValid()) + properties->AppendItem(_("Configuration loaded since"), GetConfLoadedSince()); + if (conn->BackendMinimumVersion(8, 1)) + properties->AppendItem(wxT("Autovacuum"), (autovacuumRunning ? _("running") : _("not running"))); + if (conn->BackendMinimumVersion(8, 5)) + { + properties->AppendItem(_("In recovery"), (GetInRecovery() ? _("yes") : _("no"))); + properties->AppendItem(_("Last XLOG receive location"), GetReceiveLoc()); + properties->AppendItem(_("Last XLOG replay location"), GetReplayLoc()); + } + if (conn->BackendMinimumVersion(9, 1)) + { + properties->AppendItem(_("Last XACT replay timestamp"), GetReplayTimestamp()); + if (GetInRecovery()) + properties->AppendItem(_("Replay paused"), (GetReplayPaused() ? _("paused") : _("running"))); + else + properties->AppendItem(_("Replay paused"), wxEmptyString); + } + } + if (GetServerControllable()) + properties->AppendYesNoItem(_("Running?"), GetServerRunning()); + + if (!GetDbRestriction().IsEmpty()) + properties->AppendItem(_("DB restriction"), GetDbRestriction()); + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + if(sshTunnel) + { + properties->AppendItem(_("SSH tunneling?"), (sshTunnel ? _("Yes") : _("No"))); + properties->AppendItem(_("Tunnel host"), GetTunnelHost()); + properties->AppendItem(_("Tunnel username"), GetTunnelUserName()); + properties->AppendItem(_("Authentication mode"), (GetAuthModePwd() ? _("Password") : _("Identity file"))); + if(!GetAuthModePwd()) + { + properties->AppendItem(_("Identity file path"), GetIdentityFile()); + } + } +#endif + } + + if(!GetConnected()) + return; + + if (form && GetCanHint() && !hintShown) + { + ShowHint(form, false); + } +} + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + +bool pgServer::createSSHTunnel() +{ + bool retVal = false; + + tunnelObj = new CSSHTunnelThread(tunnelHost, GetName(), port, tunnelUserName, tunnelPassword, publicKeyFile, + identityFile, authModePwd ? AUTH_PASSWORD : AUTH_PUBLICKEY, tunnelPort); + + if(tunnelObj) + { + if(tunnelObj->Initialize()) + { + if ( tunnelObj->Create() != wxTHREAD_NO_ERROR ) + { + delete tunnelObj; + tunnelObj = NULL; + wxLogError(_("SSH Error: Unable to create SSH Tunnling Thread")); + } + else + { + if (tunnelObj->Run() != wxTHREAD_NO_ERROR ) + { + delete tunnelObj; + tunnelObj = NULL; + wxLogError(_("SSH Error: Unable to start SSH Tunnling Thread")); + } + + SetLocalListenHost(tunnelObj->GetLocalListenIP()); + SetLocalListenPort(tunnelObj->GetLocalListenPort()); + retVal = true; + } + } + else + { + delete tunnelObj; + tunnelObj = NULL; + } + } + + return retVal; +} +#endif + +void pgServer::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (conn) + { + wxString pidcol = GetConnection()->BackendMinimumVersion(9, 2) ? wxT("pid") : wxT("procpid"); + wxString querycol = GetConnection()->BackendMinimumVersion(9, 2) ? wxT("query") : wxT("current_query"); + wxString sql; + wxString replication_query = wxT("state || ' (' || sent_location || ' sent, ' || write_location || ' written, ' || flush_location || ' flushed, ' || replay_location || ' applied)'"); + if (GetConnection()->BackendMinimumVersion(10, 0)) { + replication_query = wxT("state || ' (' || sent_lsn || ' sent, ' || write_lsn || ' written, ' || flush_lsn || ' flushed, ' || replay_lsn || ' applied)'"); + } + wxLogInfo(wxT("Displaying statistics for server %s"), GetIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(wxT("PID"), 35); + statistics->AddColumn(_("User"), 70); + statistics->AddColumn(_("Database"), 70); + if (GetConnection()->BackendMinimumVersion(8, 1)) + { + statistics->AddColumn(_("Backend start"), 70); + statistics->AddColumn(_("Client"), 70); + } + statistics->AddColumn(_("Current Query"), 300); + + sql = wxT("SELECT ") + pidcol + wxT(" AS pid, usename, datname, backend_start, client_addr, "); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT("client_hostname, "); + sql += wxT("client_port, ") + querycol + wxT(" AS query FROM pg_stat_activity\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + sql += wxT("UNION\n") + wxT("SELECT ") + pidcol + wxT(", usename, '' AS datname, backend_start, client_addr, client_hostname, client_port, ") + + replication_query + wxT(" AS query FROM pg_stat_replication"); + } + + pgSet *stats = ExecuteSet(sql); + if (stats) + { + int pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("pid")), 0); + int colpos = 1; + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("usename"))); + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("datname"))); + if (GetConnection()->BackendMinimumVersion(8, 1)) + { + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("backend_start"))); + wxString client; + if (GetConnection()->BackendMinimumVersion(9, 1) && !stats->GetVal(wxT("client_hostname")).IsEmpty()) + client = stats->GetVal(wxT("client_hostname")) + wxT(":") + stats->GetVal(wxT("client_port")); + else + client = stats->GetVal(wxT("client_addr")) + wxT(":") + stats->GetVal(wxT("client_port")); + if (client == wxT(":-1")) + client = _("local pipe"); + statistics->SetItem(pos, colpos++, client); + } + statistics->SetItem(pos, colpos++, stats->GetVal(wxT("query"))); + + stats->MoveNext(); + pos++; + } + + delete stats; + } + } +} + +void pgServer::ShowDependencies(frmMain *form, ctlListView *Dependencies, const wxString &wh) +{ +} + + +void pgServer::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh) +{ +} + + +bool pgServer::ReloadConfiguration() +{ + wxString sql = wxT("select pg_reload_conf()"); + return conn->ExecuteVoid(sql); +} + + +bool pgServer::PauseReplay() +{ + SetReplayPaused(true); + wxString sql = wxT("SELECT pg_xlog_replay_pause()"); + return conn->ExecuteVoid(sql); +} + + +bool pgServer::ResumeReplay() +{ + SetReplayPaused(false); + wxString sql = wxT("SELECT pg_xlog_replay_resume()"); + return conn->ExecuteVoid(sql); +} + + +bool pgServer::AddNamedRestorePoint() +{ + wxString namedrestorepoint = wxGetTextFromUser(_("Enter the name of the restore point to add"), _("Restore point name")); + if (!namedrestorepoint.IsEmpty()) + { + wxString sql = wxT("select pg_create_restore_point(") + qtDbString(namedrestorepoint) + wxT(")"); + return conn->ExecuteVoid(sql); + } + return false; +} + +pgServerCollection::pgServerCollection(pgaFactory *factory) + : pgCollection(factory) +{ +} + + +wxString pgServerCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on servers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing servers"); + break; + case OBJECTSLISTREPORT: + message = _("Servers list report"); + break; + } + + return message; +} + + +pgServerObjCollection::pgServerObjCollection(pgaFactory *factory, pgServer *sv) + : pgCollection(factory) +{ + server = sv; +} + + +bool pgServerObjCollection::CanCreate() +{ + // We can't create resource queues on Greenplum yet. + if (IsCollectionForType(GP_RESOURCE_QUEUE)) + return false; + + // We can't create tablespaces on Greenplum + if (server->GetConnection()->GetIsGreenplum() && IsCollectionForType(PGM_TABLESPACE)) + return false; + + if (server->GetMetaType() == PGM_DATABASE) + return (GetServer()->GetCreatePrivilege() || GetServer()->GetSuperUser()); + else + { + if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_ROLE) + return (server->GetCreateRole() || server->GetSuperUser()); + else if (server->GetConnection()->BackendMinimumVersion(8, 1) && GetMetaType() == PGM_DATABASE) + return (server->GetCreatePrivilege() || server->GetSuperUser()); + else if (GetMetaType() == PGM_JOB) + return true; + else + return server->GetSuperUser(); + } +} + + +pgObject *pgServerFactory::CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr) +{ + wxTreeItemId groupitem, serveritem; + wxTreeItemIdValue groupcookie; + bool found; + + long numServers = settings->Read(wxT("Servers/Count"), 0L); + + long loop, port, ssl = 0; + wxString key, servername, hostaddr, description, service, database, username, lastDatabase, lastSchema; + wxString storePwd, rolename, restore, serviceID, discoveryID, dbRestriction, colour; + wxString group, sslcert, sslkey, sslrootcert, sslcrl, sslcompression; + +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + wxString sshTunnel, authModePwd, tunnelHost, tunnelUserName, tunnelPassword, publicKeyFile, identityFile; + long tunnelPort; +#endif + pgServer *server = 0; + + wxArrayString discoveredServers; + + // Get the hostname for later... + char buf[255]; + gethostname(buf, 255); + wxString hostname = wxString(buf, wxConvUTF8); + + //wxLogError(wxT("Loading previously registered servers")); + wxLogInfo(wxT("Loading previously registered servers")); + + for (loop = 1; loop <= numServers; ++loop) + { + key.Printf(wxT("Servers/%d/"), (int)loop); + + settings->Read(key + wxT("Server"), &servername, wxEmptyString); + settings->Read(key + wxT("HostAddr"), &hostaddr, wxEmptyString); + settings->Read(key + wxT("Service"), &service, wxEmptyString); + settings->Read(key + wxT("ServiceID"), &serviceID, wxEmptyString); + settings->Read(key + wxT("DiscoveryID"), &discoveryID, serviceID); + settings->Read(key + wxT("Description"), &description, wxEmptyString); + settings->Read(key + wxT("StorePwd"), &storePwd, wxEmptyString); + settings->Read(key + wxT("Rolename"), &rolename, wxEmptyString); + settings->Read(key + wxT("Restore"), &restore, wxT("true")); + settings->Read(key + wxT("Port"), &port, 0); + settings->Read(key + wxT("Database"), &database, wxEmptyString); + settings->Read(key + wxT("Username"), &username, wxEmptyString); + settings->Read(key + wxT("LastDatabase"), &lastDatabase, wxEmptyString); + settings->Read(key + wxT("LastSchema"), &lastSchema, wxEmptyString); + settings->Read(key + wxT("DbRestriction"), &dbRestriction, wxEmptyString); + settings->Read(key + wxT("Colour"), &colour, wxEmptyString); + settings->Read(key + wxT("Group"), &group, wxT("Servers")); + settings->Read(key + wxT("SSLCert"), &sslcert, wxEmptyString); + settings->Read(key + wxT("SSLKey"), &sslkey, wxEmptyString); + settings->Read(key + wxT("SSLRootCert"), &sslrootcert, wxEmptyString); + settings->Read(key + wxT("SSLCrl"), &sslcrl, wxEmptyString); + settings->Read(key + wxT("SSLCompression"), &sslcompression, wxT("true")); +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + settings->Read(key + wxT("SSHTunnel"), &sshTunnel, wxT("false")); + settings->Read(key + wxT("TunnelHost"), &tunnelHost, wxEmptyString); + settings->Read(key + wxT("TunnelUserName"), &tunnelUserName, wxEmptyString); + settings->Read(key + wxT("TunnelModePwd"), &authModePwd, wxT("true")); + settings->Read(key + wxT("PublicKeyFile"), &publicKeyFile, wxEmptyString); + settings->Read(key + wxT("IdentityFile"), &identityFile, wxEmptyString); + settings->Read(key + wxT("TunnelPort"), &tunnelPort, DEFAULT_SSH_PORT); +#endif + // Sanitize the colour + colour = colour.Trim(); + + if (!colour.IsEmpty()) + { + wxColour cColour; + + if (cColour.Set(colour)) + colour = cColour.GetAsString(wxC2S_HTML_SYNTAX); + else + colour = wxEmptyString; + } + + if (colour.IsEmpty()) + { + wxColour cColour; + cColour.Set(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString(wxC2S_HTML_SYNTAX)); + colour = cColour.GetAsString(wxC2S_HTML_SYNTAX); + } + + // SSL mode +#ifdef PG_SSL + settings->Read(key + wxT("SSL"), &ssl, 0); +#endif + + // Sanitize the group + if (group.IsEmpty()) + { + group = _("Servers"); + } + + // Add the Server node +#if defined(HAVE_OPENSSL_CRYPTO) || defined(HAVE_GCRYPT) + server = new pgServer(servername, hostaddr, description, service, database, username, port, StrToBool(storePwd), rolename, StrToBool(restore), ssl, + colour, group, StrToBool(sshTunnel), tunnelHost, tunnelUserName, StrToBool(authModePwd), tunnelPassword, publicKeyFile, identityFile, tunnelPort); +#else + server = new pgServer(servername, hostaddr, description, service, database, username, port, StrToBool(storePwd), rolename, StrToBool(restore), ssl, + colour, group); +#endif + server->iSetLastDatabase(lastDatabase); + server->iSetLastSchema(lastSchema); + server->iSetService(service); + server->iSetServiceID(serviceID); + server->iSetDiscoveryID(discoveryID); + server->iSetDiscovered(false); + server->iSetDbRestriction(dbRestriction); + server->iSetServerIndex(loop); + server->SetSSLCert(sslcert); + server->SetSSLKey(sslkey); + server->SetSSLRootCert(sslrootcert); + server->SetSSLCrl(sslcrl); + server->iSetSSLCompression(StrToBool(sslcompression)); + + found = false; + if (browser->ItemHasChildren(obj->GetId())) + { + groupitem = browser->GetFirstChild(obj->GetId(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + found = true; + else + groupitem = browser->GetNextChild(obj->GetId(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(obj->GetId(), group, obj->GetIconId()); + } + + serveritem = browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + browser->SortChildren(groupitem); + if (!server->GetColour().IsEmpty()) + browser->SetItemBackgroundColour(serveritem, wxColour(server->GetColour())); + + // Note if we're reloading a discovered server + if (!discoveryID.IsEmpty()) + discoveredServers.Add(discoveryID); + } + + group = _("Servers"); + +#ifdef __WXMSW__ + + // Add local servers. Will currently only work on Win32 with >= BETA3 + // of the Win32 PostgreSQL installer. + wxLogInfo(wxT("Loading servers registered on the local machine")); + + pgRegKey::PGREGWOWMODE wowMode = pgRegKey::PGREG_WOW_DEFAULT; + if (::wxIsPlatform64Bit()) + wowMode = pgRegKey::PGREG_WOW32; + + pgRegKey *pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("Software\\PostgreSQL\\Services"), pgRegKey::PGREG_READ, wowMode); + + if (pgKey == NULL) + { + wowMode = pgRegKey::PGREG_WOW64; + pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("Software\\PostgreSQL\\Services"), pgRegKey::PGREG_READ, wowMode); + } + + while (pgKey != NULL) + { + pgRegKey *svcKey = NULL; + wxString svcName; + long cookie = 0; + DWORD tmpport = 0; + bool flag = false; + + flag = pgKey->GetFirstKey(svcKey, cookie); + + while (flag != false) + { + svcName = svcKey->GetKeyName(); + // On Windows, the discovery ID is always the service name. + // Only load the server if we didn't load it with all the others. + if (discoveredServers.Index(svcName, false) < 0) + { + servername = wxT("localhost"); + database = wxEmptyString; + svcKey->QueryValue(wxT("Display Name"), description); + svcKey->QueryValue(wxT("Database Superuser"), username); + svcKey->QueryValue(wxT("Port"), &tmpport); + + // Add the Server node + server = new pgServer(servername, wxEmptyString, description, wxEmptyString, database, username, (long)tmpport, false, wxEmptyString, false); + server->iSetDiscoveryID(svcName); + server->iSetDiscovered(true); + server->iSetServiceID(svcName); + server->iSetGroup(group); + + found = false; + + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + found = true; + else + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(browser->GetRootItem(), group, obj->GetIconId()); + browser->SortChildren(browser->GetRootItem()); + } + + browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + browser->SortChildren(groupitem); + } + // Release the current registry key + delete svcKey; + + // Get the next one... + flag = pgKey->GetNextKey(svcKey, cookie); + } + + /* Release current registry key */ + delete pgKey; + pgKey = NULL; + /* + * If wowMode is equal to WOW32, that means this machine is a 64 bit machine and we need to read now 64 bit registry + */ + if (wowMode == pgRegKey::PGREG_WOW32) + { + wowMode = pgRegKey::PGREG_WOW64; + pgKey = pgRegKey::OpenRegKey(HKEY_LOCAL_MACHINE, wxT("Software\\PostgreSQL\\Services"), pgRegKey::PGREG_READ, wowMode); + } + } +#endif // __WXMSW__ + + // Add local servers on non-Win32 platforms (on Win32, they will be picked up above) +#ifndef WIN32 + + // On Unix/Mac, the discovery ID can be anything. We use the PostgreSQL + // package config filename if it's present, as that is the only thing vaguely + // discoverable and unique to a given installation. We can do the same for + // other distros in the future if they drop a suitable file someplace. + // Look for any files that match the basic postgres*.ini pattern. + + wxLogInfo(wxT("Loading servers registered on the local machine")); + + if (wxFile::Exists(REGISTRY_FILE)) + { + wxString version, locale; + long cookie; + + wxFileInputStream fst(REGISTRY_FILE); + wxFileConfig *cnf = new wxFileConfig(fst); + + // PostgreSQL servers + cnf->SetPath(wxT("/PostgreSQL")); + bool flag = cnf->GetFirstGroup(version, cookie); + while (flag) + { + // If there is no Version entry, this is probably an uninstalled server + if (cnf->Read(version + wxT("/Version"), wxEmptyString) != wxEmptyString) + { + // Only load this server if we haven't read it from the pgAdmin config + if (discoveredServers.Index(cnf->GetPath() + wxT("/") + version, false) < 0) + { + + // Basic details + servername = wxT("localhost"); + cnf->Read(version + wxT("/Description"), &description, wxT("PostgreSQL ") + version); + cnf->Read(version + wxT("/Superuser"), &username, wxEmptyString); + cnf->Read(version + wxT("/Port"), &port, 0); + + // Add the item, if it looks sane + if (port != 0 && username != wxEmptyString) + { + server = new pgServer(servername, wxEmptyString, description, wxEmptyString, wxT("postgres"), username, port, false, rolename, 0); + server->iSetDiscoveryID(cnf->GetPath() + wxT("/") + version); + server->iSetDiscovered(true); + server->iSetGroup(group); + found = false; + if (browser->ItemHasChildren(browser->GetRootItem())) + { + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!found && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + found = true; + else + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + } + + if (!found) + { + groupitem = browser->AppendItem(browser->GetRootItem(), group, obj->GetIconId()); + browser->SortChildren(browser->GetRootItem()); + } + + browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + browser->SortChildren(groupitem); + } + } + } + + flag = cnf->GetNextGroup(version, cookie); + } + + // EnterpriseDB servers + cnf->SetPath(wxT("/EnterpriseDB")); + flag = cnf->GetFirstGroup(version, cookie); + while (flag) + { + // If there is no Version entry, this is probably an uninstalled server + if (cnf->Read(version + wxT("/Version"), wxEmptyString) != wxEmptyString) + { + // Only load this server if we haven't read it from the pgAdmin config + if (discoveredServers.Index(cnf->GetPath() + wxT("/") + version, false) < 0) + { + + // Basic details + servername = wxT("localhost"); + cnf->Read(version + wxT("/Description"), &description, wxT("EnterpriseDB ") + version); + cnf->Read(version + wxT("/Superuser"), &username, wxEmptyString); + cnf->Read(version + wxT("/Port"), &port, 0); + + // Add the item, if it looks sane + if (port != 0 && username != wxEmptyString) + { + server = new pgServer(servername, wxEmptyString, description, wxEmptyString, wxT("edb"), username, port, false, rolename, 0); + server->iSetDiscoveryID(cnf->GetPath() + wxT("/") + version); + server->iSetDiscovered(true); + groupitem = browser->GetFirstChild(obj->GetId(), groupcookie); + if (!groupitem.IsOk()) + groupitem = browser->AppendItem(obj->GetId(), group, obj->GetIconId()); + browser->AppendItem(groupitem, server->GetFullName(), server->GetIconId(), -1, server); + } + } + } + + flag = cnf->GetNextGroup(version, cookie); + } + + delete cnf; + browser->SortChildren(obj->GetId()); + } + +#endif // !WIN32 + + return server; +} + +#include "images/servers.pngc" +#include "images/server.pngc" +#include "images/server-sm.pngc" +#include "images/serverbad.pngc" +#include "images/serverbad-sm.pngc" + +pgServerFactory::pgServerFactory() + : pgaFactory(__("Server"), __("New Server Registration"), __("Create a new Server registration."), server_png_img, server_sm_png_img) +{ + metaType = PGM_SERVER; + closedId = addIcon(serverbad_png_img); + smallClosedId = addIcon(serverbad_sm_png_img); +} + +pgCollection *pgServerFactory::CreateCollection(pgObject *obj) +{ + return new pgCollection(GetCollectionFactory()); +} + +pgCollection *pgServerObjFactory::CreateCollection(pgObject *obj) +{ + return new pgServerObjCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgServerFactory serverFactory; +static pgaCollectionFactory cf(&serverFactory, __("Servers"), servers_png_img); + +#include "images/connect.pngc" +addServerFactory::addServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : actionFactory(list) +{ + mnu->Append(id, _("&Add Server..."), _("Add a connection to a server.")); + toolbar->AddTool(id, _("Add Server"), *connect_png_bmp, _("Add a connection to a server."), wxITEM_NORMAL); +} + + +wxWindow *addServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + int rc = PGCONN_BAD; + + dlgServer dlg(&serverFactory, form, 0); + dlg.CenterOnParent(); + + while (rc != PGCONN_OK) + { + if (dlg.GoNew() != wxID_OK) + return 0; + + pgServer *server = (pgServer *)dlg.CreateObject(0); + + if (dlg.GetTryConnect()) + { + wxBusyInfo waiting(wxString::Format(_("Connecting to server %s (%s:%d)"), + server->GetDescription().c_str(), server->GetName().c_str(), server->GetPort()), form); + + // Give the UI a chance to redraw + wxSafeYield(); + wxMilliSleep(100); + wxSafeYield(); + + rc = server->Connect(form, false, dlg.GetPassword(), true); + } + else + { + rc = PGCONN_OK; + server->InvalidatePassword(); + } + switch (rc) + { + case PGCONN_OK: + { + int icon; + ctlTree *browser = form->GetBrowser(); + wxTreeItemId groupitem, parentitem; + wxTreeItemIdValue groupcookie; + int total; + wxString label; + + if (server->GetConnected()) + icon = serverFactory.GetIconId(); + else + icon = serverFactory.GetClosedIconId(); + wxLogInfo(wxT("pgServer object initialised as required.")); + + // Add the new server in its group + wxString group = server->GetGroup(); + if (group.Length() == 0) + group = _("Servers"); + + // Get the parent group + groupitem = browser->GetFirstChild(browser->GetRootItem(), groupcookie); + while (!parentitem && groupitem) + { + if (browser->GetItemText(groupitem).StartsWith(group)) + parentitem = groupitem; + groupitem = browser->GetNextChild(browser->GetRootItem(), groupcookie); + } + + if (!parentitem) + parentitem = browser->AppendItem(browser->GetRootItem(), group, icon, -1); + + browser->AppendItem(parentitem, server->GetFullName(), icon, -1, server); + browser->SortChildren(parentitem); + browser->Expand(parentitem); + + total = browser->GetChildrenCount(parentitem, false); + label = group + wxT(" (") + NumToStr((long)total) + wxT(")"); + browser->SetItemText(parentitem, label); + + form->StoreServers(); + return 0; + } + case PGCONN_DNSERR: + { + delete server; + break; + } + case PGCONN_BAD: + case PGCONN_BROKEN: + { + form->ReportConnError(server); + delete server; + + break; + } + case PGCONN_SSHTUNNEL_ERROR: + { + delete server; + break; + } + default: + { + wxLogInfo(__("pgServer object didn't initialise because the user aborted.")); + delete server; + return 0; + } + } + } + return 0; +} + + +startServiceFactory::startServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Start Service"), _("Start PostgreSQL Service")); +} + + +wxWindow *startServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Starting Service")); + bool rc = server->StartService(); + if (rc) + form->execSelChange(server->GetId(), true); + form->EndMsg(rc); + return 0; +} + + +bool startServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetServerControllable() && !server->GetServerRunning(); + } + return false; +} + + +stopServiceFactory::stopServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Stop Service"), _("Stop PostgreSQL Service")); +} + + +wxWindow *stopServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + wxMessageDialog msg(form, _("Are you sure you wish to shutdown this server?"), + _("Stop Service"), wxYES_NO | wxICON_QUESTION); + if (msg.ShowModal() == wxID_YES) + { + form->StartMsg(_("Stopping service")); + + bool done = server->StopService(); + + if (done) + { + if (server->Disconnect(form)) + { + form->GetBrowser()->DeleteChildren(server->GetId()); + form->execSelChange(server->GetId(), true); + } + } + form->EndMsg(done); + } + + return 0; +} + + +bool stopServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetServerControllable() && server->GetServerRunning(); + } + return false; +} + + +connectServerFactory::connectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Connect"), _("Connect to the selected server.")); +} + + +wxWindow *connectServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->ReconnectServer(server); + return 0; +} + + +bool connectServerFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + return !((pgServer *)obj)->GetConnected(); + + return false; +} + + +disconnectServerFactory::disconnectServerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Disconnec&t server"), _("Disconnect from the selected server.")); +} + + +wxWindow *disconnectServerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (obj->CheckOpenDialogs(form->GetBrowser(), form->GetBrowser()->GetSelection())) + { + wxString msg = _("There are properties dialogues open for one or more objects belonging to a database which will be disconnected. Please close the properties dialogues and try again."); + wxMessageBox(msg, _("Cannot disconnect database"), wxICON_WARNING | wxOK); + } + else + { + pgServer *server = (pgServer *)obj; + server->Disconnect(form); + server->UpdateIcon(form->GetBrowser()); + form->GetBrowser()->DeleteChildren(obj->GetId()); + form->execSelChange(obj->GetId(), true); + } + + return 0; +} + + +bool disconnectServerFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + return ((pgServer *)obj)->GetConnected(); + + return false; +} + +reloadconfServiceFactory::reloadconfServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Reload configuration"), _("Reload configuration")); +} + + +wxWindow *reloadconfServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Reloading configuration")); + bool rc = server->ReloadConfiguration(); + form->EndMsg(rc); + return 0; +} + + +bool reloadconfServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && server->connection()->BackendMinimumVersion(8, 1); + } + return false; +} + + +pausereplayServiceFactory::pausereplayServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Pause replay of WAL"), _("Pause replay of WAL")); +} + + +wxWindow *pausereplayServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Pausing replay of WAL")); + bool rc = server->PauseReplay(); + form->EndMsg(rc); + return 0; +} + + +bool pausereplayServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && + server->connection()->BackendMinimumVersion(9, 1) && + server->GetInRecovery() && + !server->GetReplayPaused(); + } + return false; +} + + +resumereplayServiceFactory::resumereplayServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Resume replay of WAL"), _("Resume replay of WAL")); +} + + +wxWindow *resumereplayServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Resuming replay of WAL")); + bool rc = server->ResumeReplay(); + form->EndMsg(rc); + return 0; +} + + +bool resumereplayServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && + server->connection()->BackendMinimumVersion(9, 1) && + server->GetInRecovery() && + server->GetReplayPaused(); + } + return false; +} + + +addnamedrestorepointServiceFactory::addnamedrestorepointServiceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Add named restore point"), _("Add named restore point")); +} + + +wxWindow *addnamedrestorepointServiceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + pgServer *server = (pgServer *)obj; + form->StartMsg(_("Add named restore point")); + bool rc = server->AddNamedRestorePoint(); + form->EndMsg(rc); + return 0; +} + + +bool addnamedrestorepointServiceFactory::CheckEnable(pgObject *obj) +{ + if (obj && obj->IsCreatedBy(serverFactory)) + { + pgServer *server = (pgServer *)obj; + return server->GetConnected() && server->connection()->BackendMinimumVersion(9, 1) && !server->GetInRecovery(); + } + return false; +} \ No newline at end of file diff --git a/schema/pgSubscription.cpp b/schema/pgSubscription.cpp new file mode 100644 index 0000000..ed107ff --- /dev/null +++ b/schema/pgSubscription.cpp @@ -0,0 +1,244 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgPublication.cpp - Subscription class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgSubscription.h" + + +pgSubscription::pgSubscription(const wxString &newName) + : pgDatabaseObject(subscriptionFactory, newName) +{ +} + +wxString pgSubscription::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on subscription"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing subscription"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop subscription \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop subscription \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop subscription cascaded?"); + break; + case DROPTITLE: + message = _("Drop subscription?"); + break; + case PROPERTIESREPORT: + message = _("Subscription properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Subscription properties"); + break; + case DDLREPORT: + message = _("Subscription DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Subscription DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Subscription dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Subscription dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Subscription dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Subscription dependents"); + break; + } + + return message; +} + +bool pgSubscription::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP SUBSCRIPTION ") + GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgSubscription::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Subscription: ") + GetQuotedIdentifier() + wxT("\n\n") + + wxT("-- DROP SUBSCRIPTION ") + GetQuotedIdentifier() + wxT(";") + + wxT("\n\n CREATE SUBSCRIPTION ") + GetName()+wxT("\n") + + wxT(" CONNECTION E") + qtConnString(GetConnInfo())+wxT("\n") + + wxT(" PUBLICATION ") + GetPubStr()+wxT(""); + sql += wxT("\n WITH (") + GetStrOper() + wxT(")"); + + sql += wxT(";\n"); + } + return sql; +} + + +void pgSubscription::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Publications"), GetPubStr()); + //properties->AppendYesNoItem(_("Relocatable?"), GetIsRelocatable()); + properties->AppendItem(_("Options"), GetStrOper()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgSubscription::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *language = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + language = subscriptionFactory.CreateObjects(coll, 0, wxT("\n and oid=") + GetOidStr()); + + return language; +} + + + +pgObject *pgSubscriptionFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgSubscription *subscription = 0; + bool superu=collection->GetDatabase()->GetConnection()->IsSuperuser(); + //wxString dbname=collection->GetDatabase()->GetConnection()->GetDbOid; + OID db=collection->GetDatabase()->GetConnection()->GetDbOid(); + sql = wxT("select oid,subname,pg_get_userbyid(subowner) AS \"owner\",subenabled,subconninfo,subslotname,subsynccommit,subpublications,obj_description(oid,'pg_subscription') as comment from pg_subscription where subdbid=") + +NumToStr(db)+ wxT("\n") + + restriction + wxT("\n"); + pgSet *subscriptions = collection->GetDatabase()->ExecuteSet(sql); + + if (subscriptions) + { + while (!subscriptions->Eof()) + { + wxString tmp; + tmp = subscriptions->GetVal(wxT("subpublications")); + tmp.Replace(wxT("{"), wxT("")); + tmp.Replace(wxT("}"), wxT("")); + + subscription = new pgSubscription(subscriptions->GetVal(wxT("subname"))); + subscription->iSetDatabase(collection->GetDatabase()); + subscription->iSetOid(subscriptions->GetOid(wxT("oid"))); + subscription->iSetOwner(subscriptions->GetVal(wxT("owner"))); + subscription->iSetPubStr(tmp); + subscription->iSetConnInfo(subscriptions->GetVal(wxT("subconninfo"))); + subscription->iSetSlotName(subscriptions->GetVal(wxT("subslotname"))); + //subscription->iSetName(subscriptions->GetVal(wxT("subname")); + subscription->iSetIsEnabled(subscriptions->GetBool(wxT("subenabled"))); + subscription->iSetIsSyncCommit(subscriptions->GetVal(wxT("subsynccommit"))); + subscription->iSetComment(subscriptions->GetVal(wxT("comment"))); + + if (browser) + { + browser->AppendObject(collection, subscription); + + subscriptions->MoveNext(); + } + else + break; + } + + delete subscriptions; + } + return subscription; +} + + +///////////////////////////// + +pgSubscriptionCollection::pgSubscriptionCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString pgSubscriptionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on subscriptions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing subscriptions"); + break; + case OBJECTSLISTREPORT: + message = _("Subscriptions list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/extension.pngc" +#include "images/extension-sm.pngc" +#include "images/extensions.pngc" +#include "images/slsubscription.pngc" +#include "images/slsubscriptions.pngc" + +pgSubscriptionFactory::pgSubscriptionFactory() + : pgDatabaseObjFactory(__("Subscription"), __("New Subscription..."), __("Create a new Subscription."), extension_png_img, extension_sm_png_img) +{ +} + + +pgCollection *pgSubscriptionFactory::CreateCollection(pgObject *obj) +{ + return new pgSubscriptionCollection(GetCollectionFactory(), (pgDatabase *)obj); +} +dlgProperty *pgSubscriptionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return NULL; +} + +pgSubscriptionFactory subscriptionFactory; +static pgaCollectionFactory cf(&subscriptionFactory, __("Subscriptions"), slsubscriptions_png_img); diff --git a/schema/pgTable.cpp b/schema/pgTable.cpp new file mode 100644 index 0000000..9931dae --- /dev/null +++ b/schema/pgTable.cpp @@ -0,0 +1,2019 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTable.cpp - Table class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +#include "utils/misc.h" +#include "frm/frmHint.h" +#include "frm/frmMain.h" +#include "frm/frmMaintenance.h" +#include "schema/pgTable.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgForeignKey.h" +#include "schema/pgCheck.h" +#include "utils/sysSettings.h" +#include "utils/pgfeatures.h" +#include "schema/pgRule.h" +#include "schema/pgTrigger.h" +#include "schema/pgConstraints.h" +#include "schema/gpPartition.h" +#include "schema/pgPartition.h" +#include + +// App headers + +pgTable::pgTable(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, tableFactory, newName) +{ + Init(); +} + +pgTable::pgTable(pgSchema *newSchema, pgaFactory &newFactory, const wxString &newName) + : pgSchemaObject(newSchema, newFactory, newName) +{ + Init(); +} + +pgTable::~pgTable() +{ +} + + +void pgTable::Init() +{ + rows = 0; + estimatedRows = 0.0; + + hasToastTable = false; + autovacuum_enabled = 0; + toast_autovacuum_enabled = 0; + + isPartitioned = false; + hasOids = false; + unlogged = false; + hasSubclass = false; + rowsCounted = false; + isReplicated = false; + showExtendedStatistics = false; + distributionIsRandom = false; + + inheritedTableCount = 0; + triggerCount = 0; + + tablespaceOid = 0; + ofTypeOid = 0; +} + + +wxString pgTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop table cascaded?"); + break; + case DROPTITLE: + message = _("Drop table?"); + break; + case PROPERTIESREPORT: + message = _("Table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Table properties"); + break; + case DDLREPORT: + message = _("Table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Table DDL"); + break; + case DATADICTIONNARYREPORT: + message = _("Table Data dictionary report"); + message += wxT(" - ") + GetName(); + break; + case STATISTICSREPORT: + message = _("Table statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Table statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Table dependents"); + break; + case BACKUPTITLE: + message = wxString::Format(_("Backup table \"%s\""), + GetFullIdentifier().c_str()); + break; + case RESTORETITLE: + message = wxString::Format(_("Restore table \"%s\""), + GetFullIdentifier().c_str()); + break; + } + + return message; +} + + +int pgTable::GetIconId() +{ + if (isReplicated) + return tableFactory.GetReplicatedIconId(); + else + if (!GetPartKeyDef().IsEmpty()||GetIsPartitioned()) return tableFactory.GetPartitionsIconId(); + else + return tableFactory.GetIconId(); +} + + +wxMenu *pgTable::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + columnFactory.AppendMenu(menu); + if (GetPrimaryKey().IsEmpty()) // Will not notice if pk has been added after last refresh + primaryKeyFactory.AppendMenu(menu); + foreignKeyFactory.AppendMenu(menu); + excludeFactory.AppendMenu(menu); + uniqueFactory.AppendMenu(menu); + checkFactory.AppendMenu(menu); + indexFactory.AppendMenu(menu); + ruleFactory.AppendMenu(menu); + triggerFactory.AppendMenu(menu); + + /* + * TEMPORARY: Disable adding new partitions until that code is working right. + * + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum() && GetIsPartitioned()) + partitionFactory.AppendMenu(menu); + */ + } + return menu; +} + + +int pgTable::GetReplicationStatus(ctlTree *browser, wxString *clusterName, long *setId) +{ + wxArrayString clusters = GetDatabase()->GetSlonyClusters(browser); + + bool isSubscribed = false; + + size_t i; + for (i = 0 ; i < clusters.GetCount() ; i++) + { + wxString nsp = qtIdent(wxT("_") + clusters.Item(i)); + + pgSetIterator sets(GetConnection(), + wxT("SELECT tab_set, sub_provider, ") + nsp + wxT(".getlocalnodeid(") + qtDbString(wxT("_") + clusters.Item(i)) + wxT(") AS localnode\n") + wxT(" FROM ") + nsp + wxT(".sl_table\n") + wxT(" LEFT JOIN ") + nsp + wxT(".sl_subscribe ON sub_set=tab_set\n") + wxT(" WHERE tab_reloid = ") + GetOidStr()); + + if (sets.RowsLeft()) + { + if (clusterName) + *clusterName = clusters.Item(i); + if (setId) + *setId = sets.GetLong(wxT("tab_set")); + if (isSubscribed) + return REPLICATIONSTATUS_MULTIPLY_PUBLISHED; + + long provider = sets.GetLong(wxT("sub_provider")); + if (provider) + { + if (provider != sets.GetLong(wxT("localnode"))) + return REPLICATIONSTATUS_REPLICATED; + + isSubscribed = true; + + } + } + } + if (isSubscribed) + return REPLICATIONSTATUS_SUBSCRIBED; + + return REPLICATIONSTATUS_NONE; +} + + +wxString pgTable::GetHelpPage(bool forCreate) const +{ + if (forCreate) + return wxT("pg/sql-createtable"); + else + return wxT("pg/sql-altertable"); +} + + +bool pgTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +bool pgTable::Truncate(bool cascaded) +{ + wxString sql = wxT("TRUNCATE TABLE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +bool pgTable::ResetStats() +{ + wxString sql = wxT("SELECT pg_stat_reset_single_table_counters(") + + NumToStr(this->GetOid()) + + wxT(")"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgTable::AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + wxString tmp; + + pgCollection *collection = browser->FindCollection(factory, GetId()); + if (collection) + { + tmp += wxT("\n"); + collection->ShowTreeDetail(browser); + + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + obj->ShowTreeDetail(browser); + + tmp += obj->GetSql(browser) + wxT("\n"); + } + } + + if (!tmp.IsEmpty() && tmp != wxT("\n")) + sql += tmp; +} + +void pgTable::AppendStuffNoSql(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + pgCollection *collection = browser->FindCollection(factory, GetId()); + if (collection) + { + collection->ShowTreeDetail(browser); + + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + obj->ShowTreeDetail(browser); + } + } +} + + + +wxString pgTable::GetSql(ctlTree *browser) +{ + wxString colDetails, conDetails; + wxString prevComment; + wxString cols_sql = wxEmptyString; + wxString cols_type = wxEmptyString; + wxString columnPrivileges; + + if (sql.IsNull()) + { + // make sure all kids are appended + ShowTreeDetail(browser); + sql = wxT("-- Table: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TABLE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE "); + if (GetUnlogged()) + sql += wxT("UNLOGGED "); + sql += wxT("TABLE ") + GetQuotedFullIdentifier(); + + // of type (9.0 material) + if (ofTypeOid > 0) + sql += wxT("\nOF ") + qtIdent(ofType); + + // Get a count of the constraints. + int consCount = 0; + pgCollection *constraints = browser->FindCollection(primaryKeyFactory, GetId()); + if (constraints) + consCount = browser->GetChildrenCount(constraints->GetId()); + + // Get the columns + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + columns->ShowTreeDetail(browser); + treeObjectIterator colIt1(browser, columns); + treeObjectIterator colIt2(browser, columns); + + + int lastRealCol = 0; + int currentCol = 0; + pgColumn *column; + // Iterate the columns to find the last 'real' one + while ((column = (pgColumn *)colIt1.GetNextObject()) != 0) + { + if (currentCol==0) {cols_type+=column->GetDisplayName()+wxT(" ")+column->GetQuotedTypename(); + } else cols_type+=wxT(", ")+column->GetDisplayName()+wxT(" ")+column->GetQuotedTypename(); + currentCol++; + //AppendIfFilled(cols_type,wxT(","),cols_type); + if (column->GetInheritedCount() == 0) + lastRealCol = currentCol; + } + cols_type=wxT("-- (")+cols_type+wxT(")"); + // Now build the actual column list + int colCount = 0; + while ((column = (pgColumn *)colIt2.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (colCount) + { + // Only add a comma if this isn't the last 'real' column, or if there are constraints + if (colCount != lastRealCol || consCount) + cols_sql += wxT(","); + if (!prevComment.IsEmpty()) + cols_sql += wxT(" -- ") + firstLineOnly(prevComment); + + cols_sql += wxT("\n"); + } + + if (column->GetInheritedCount() > 0) + { + if (!column->GetIsLocal()) + { + cols_sql += wxString::Format(wxT("-- %s "), _("Inherited")) + + wxT("from table ") + column->GetInheritedTableName() + wxT(":"); + } + } + + if (ofTypeOid > 0) + { + if (column->GetDefinition().Length() == 0) + { + cols_sql += wxString::Format(wxT("-- %s "), _("Inherited")) + + wxT("from type ") + ofType + wxT(": ") + + column->GetQuotedIdentifier(); + } + else + { + cols_sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" WITH OPTIONS ") + + column->GetDefinition(); + } + } + else + { + cols_sql += wxT(" ") + column->GetQuotedIdentifier() + wxT(" ") + + column->GetDefinition(); + } + + prevComment = column->GetComment(); + + // Whilst we are looping round the columns, grab their comments as well. + colDetails += column->GetCommentSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + colDetails += column->GetStorageSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + colDetails += column->GetAttstattargetSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + colDetails += column->GetVariablesSql(); + if (colDetails.Length() > 0) + if (colDetails.Last() != '\n') + colDetails += wxT("\n"); + + colCount++; + columnPrivileges += column->GetPrivileges(); + } + } + } + + // Now iterate the constraints + if (constraints) + { + constraints->ShowTreeDetail(browser); + treeObjectIterator consIt(browser, constraints); + + pgObject *data; + + while ((data = consIt.GetNextObject()) != 0) + { + data->ShowTreeDetail(browser); + + cols_sql += wxT(","); + + if (!prevComment.IsEmpty()) + cols_sql += wxT(" -- ") + firstLineOnly(prevComment); + + cols_sql += wxT("\n CONSTRAINT ") + data->GetQuotedIdentifier() + + wxT(" ") + data->GetTypeName().Upper() + + wxT(" ") ; + + prevComment = data->GetComment(); + if (!data->GetComment().IsEmpty()) + conDetails += wxT("COMMENT ON CONSTRAINT ") + data->GetQuotedIdentifier() + + wxT(" ON ") + GetQuotedFullIdentifier() + + wxT(" IS ") + qtDbString(data->GetComment()) + wxT(";\n"); + + switch (data->GetMetaType()) + { + case PGM_PRIMARYKEY: + case PGM_UNIQUE: + case PGM_EXCLUDE: + cols_sql += ((pgIndexConstraint *)data)->GetDefinition(); + break; + case PGM_FOREIGNKEY: + cols_sql += ((pgForeignKey *)data)->GetDefinition(); + break; + case PGM_CHECK: + cols_sql += wxT("(") + ((pgCheck *)data)->GetDefinition() + wxT(")"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && ((pgCheck *)data)->GetNoInherit()) + cols_sql += wxT(" NO INHERIT"); + if (GetDatabase()->BackendMinimumVersion(9, 2) && !((pgCheck *)data)->GetValid()) + cols_sql += wxT(" NOT VALID"); + break; + } + } + } + if (!prevComment.IsEmpty()) + cols_sql += wxT(" -- ") + firstLineOnly(prevComment); + if (GetConnection()->BackendMinimumVersion(10, 0)&&!GetPartExp().IsEmpty()) + { + sql += wxT("\n PARTITION OF ") + GetQuotedInheritedTables() + wxT("(\n") + cols_sql + wxT("\n)"); + sql += wxT(" ") + GetPartExp() + wxT(" "); + } else + { + sql += wxT("\n(\n") + cols_sql + wxT("\n)"); + } + if (GetInheritedTableCount()) + { + if (GetConnection()->BackendMinimumVersion(10, 0)&&!GetPartExp().IsEmpty()) { + + } else + { + sql += wxT("\nINHERITS (") + GetQuotedInheritedTables() + wxT(")"); + } + } + if (GetConnection()->BackendMinimumVersion(10, 0)&&!GetPartKeyDef().IsEmpty()) + { + sql += wxT("\nPARTITION BY ") + GetPartKeyDef() + wxT(" "); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + wxString sqlopt=wxEmptyString; + if (GetFillFactor().Length() > 0) + sqlopt += wxT("\n FILLFACTOR=") + GetFillFactor() + wxT(", "); + if (GetAppendOnly().Length() > 0) + sqlopt += wxT("APPENDONLY=") + GetAppendOnly() + wxT(", "); + if (GetCompressLevel().Length() > 0) + sqlopt += wxT("COMPRESSLEVEL=") + GetCompressLevel() + wxT(", "); + if (GetOrientation().Length() > 0) + sqlopt += wxT("ORIENTATION=") + GetOrientation() + wxT(", "); + if (GetCompressType().Length() > 0) + sqlopt += wxT("COMPRESSTYPE=") + GetCompressType() + wxT(", "); + if (GetBlocksize().Length() > 0) + sqlopt += wxT("BLOCKSIZE=") + GetBlocksize() + wxT(", "); + if (GetChecksum().Length() > 0) + sqlopt += wxT("CHECKSUM=") + GetChecksum() + wxT(", "); + if (GetConnection()->BackendMinimumVersion(12, 0)) { + if (!sqlopt.IsEmpty()) sqlopt=sqlopt.BeforeLast(','); + } else { + if (GetHasOids()) + sqlopt += wxT("\n OIDS=TRUE"); + else + sqlopt += wxT("\n OIDS=FALSE"); + } + + if(GetConnection()->BackendMinimumVersion(8, 4)) + { + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() == 1) + sqlopt += wxT(",\n autovacuum_enabled=true"); + else if (GetCustomAutoVacuumEnabled() == 0) + sqlopt += wxT(",\n autovacuum_enabled=false"); + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_vacuum_threshold=") + GetAutoVacuumVacuumThreshold(); + } + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_vacuum_scale_factor=") + GetAutoVacuumVacuumScaleFactor(); + } + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_analyze_threshold=") + GetAutoVacuumAnalyzeThreshold(); + } + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_analyze_scale_factor=") + GetAutoVacuumAnalyzeScaleFactor(); + } + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_vacuum_cost_delay=") + GetAutoVacuumVacuumCostDelay(); + } + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_vacuum_cost_limit=") + GetAutoVacuumVacuumCostLimit(); + } + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_freeze_min_age=") + GetAutoVacuumFreezeMinAge(); + } + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_freeze_max_age=") + GetAutoVacuumFreezeMaxAge(); + } + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + { + sqlopt += wxT(",\n autovacuum_freeze_table_age=") + GetAutoVacuumFreezeTableAge(); + } + } + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() == 1) + sqlopt += wxT(",\n toast.autovacuum_enabled=true"); + else if (GetToastAutoVacuumEnabled() == 0) + sqlopt += wxT(",\n toast.autovacuum_enabled=false"); + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_vacuum_threshold=") + GetToastAutoVacuumVacuumThreshold(); + } + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_vacuum_scale_factor=") + GetToastAutoVacuumVacuumScaleFactor(); + } + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_vacuum_cost_delay=") + GetToastAutoVacuumVacuumCostDelay(); + } + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_vacuum_cost_limit=") + GetToastAutoVacuumVacuumCostLimit(); + } + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_freeze_min_age=") + GetToastAutoVacuumFreezeMinAge(); + } + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_freeze_max_age=") + GetToastAutoVacuumFreezeMaxAge(); + } + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + { + sqlopt += wxT(",\n toast.autovacuum_freeze_table_age=") + GetToastAutoVacuumFreezeTableAge(); + } + } + } + wxRegEx reg("vacuum_index_cleanup=[a-z]+|vacuum_truncate=[a-z]+|parallel_workers=[0-9]+|toast_tuple_target=[0-9]+|log_autovacuum_min_duration=[0-9]+|user_catalog_table=[a-z]+"); + wxString relopt=GetRelOptions(); + wxString o; + size_t start, len; + while ( reg.Matches(relopt) ) + { + reg.GetMatch(&start, &len, 0); + o=reg.GetMatch(relopt, 0); + AppendIfFilled(sqlopt, ",\n ", o); + relopt = relopt.Mid (start + len); + } + relopt=GetToastRelOptions(); + while ( reg.Matches(relopt) ) + { + reg.GetMatch(&start, &len, 0); + o="toast." + reg.GetMatch(relopt, 0); + AppendIfFilled(sqlopt, ",\n ", o); + relopt = relopt.Mid (start + len); + } + if (!sqlopt.IsEmpty()) { + sql += wxT("\nWITH ("); + if (sqlopt.Index(',')==0) sqlopt=sqlopt.Mid(1); + sql += sqlopt; + sql += wxT("\n)"); + } + } + else + { + if (GetHasOids()) + sql += wxT("\nWITH OIDS"); + else + sql += wxT("\nWITHOUT OIDS"); + } + + if (GetConnection()->BackendMinimumVersion(8, 0) && tablespace != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + if (GetConnection()->GetIsGreenplum()) + { + // Add Greenplum DISTRIBUTED BY + if (distributionIsRandom) + { + sql += wxT("\nDISTRIBUTED RANDOMLY"); + } + else if (GetDistributionColNumbers().Length() == 0) + { + // catalog table or other non-distributed table + } + else + { + // convert list of columns numbers to column names + wxStringTokenizer collist(GetDistributionColNumbers(), wxT(",")); + wxString cn; + wxString distributionColumns; + while (collist.HasMoreTokens()) + { + cn = collist.GetNextToken(); + pgSet *set = ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum IN (") + cn + wxT(")")); + if (set) + { + if (!distributionColumns.IsNull()) + { + distributionColumns += wxT(", "); + } + distributionColumns += qtIdent(set->GetVal(0)); + delete set; + } + } + + sql += wxT("\nDISTRIBUTED BY ("); + sql += distributionColumns; + + sql += wxT(")"); + } + + if (GetIsPartitioned()) + if (GetConnection()->BackendMinimumVersion(8, 2, 9) && GetConnection()->GetIsGreenplum()) + if (GetPartitionDef().Length() == 0) + { + wxString query = wxT("SELECT pg_get_partition_def("); + query += GetOidStr(); + query += wxT(", true) "); + wxString partition_def = GetDatabase()->ExecuteScalar(query); + iSetPartitionDef(partition_def); + // pg_get_partition_def() doesn't work on partitions + if (GetPartitionDef().Length() == 0) + iSetPartitionDef(wxT("-- This partition has subpartitions")); + } + if (partitionDef.Length() > 0) + sql += wxT("\n") + partitionDef + wxT("\n"); + + + } + + + sql += wxT(";\n") + + GetOwnerSql(7, 3); + + if (GetConnection()->BackendMinimumVersion(8, 4)) + sql += GetGrant(wxT("arwdDxt")); + else if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdxt")); + else + sql += GetGrant(wxT("arwdRxt")); + wxString st=GetStatExt(); + if (!st.IsEmpty()) sql += st + wxT(";\n"); + sql += GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + + // Column/constraint comments + if (!colDetails.IsEmpty()) + sql += colDetails + wxT("\n"); + + if (!conDetails.IsEmpty()) + sql += conDetails + wxT("\n"); + + if (!columnPrivileges.IsEmpty()) + { + sql += columnPrivileges + wxT("\n"); + } + + AppendStuff(sql, browser, indexFactory); + AppendStuff(sql, browser, ruleFactory); + AppendStuff(sql, browser, triggerFactory); + + /* + * Disable adding partitions until that code works. + * + if (partitionDef.Length() > 0) + { + AppendStuffNoSql(sql, browser, partitionFactory); + } + */ + sql+=cols_type; + } + + return sql; +} + +wxString pgTable::GetCoveringIndex(ctlTree *browser, const wxString &collist) +{ + // delivers the name of the index which covers the named columns + wxCookieType cookie; + + wxTreeItemId collItem = browser->GetFirstChild(GetId(), cookie); + while (collItem) + { + pgObject *data = browser->GetObject(collItem); + if (data && data->IsCollection() && (data->GetMetaType() == PGM_CONSTRAINT || data->GetMetaType() == PGM_INDEX)) + { + wxCookieType cookie2; + wxTreeItemId item = browser->GetFirstChild(collItem, cookie2); + while (item) + { + pgIndex *index = (pgIndex *)browser->GetObject(item); + if (index && (index->GetMetaType() == PGM_INDEX || index->GetMetaType() == PGM_PRIMARYKEY + || index->GetMetaType() == PGM_UNIQUE || index->GetMetaType() == PGM_EXCLUDE)) + { + index->ShowTreeDetail(browser); + if (collist == index->GetColumns() || + collist + wxT(",") == index->GetColumns().Left(collist.Length() + 1)) + return index->GetName(); + } + item = browser->GetNextChild(collItem, cookie2); + } + } + collItem = browser->GetNextChild(GetId(), cookie); + } + + return wxEmptyString; +} + + +wxString pgTable::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) +{ + wxString sql; + wxString line; + + int colcount = 0; + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + columns->ShowTreeDetail(browser); + treeObjectIterator colIt(browser, columns); + + pgColumn *column; + while ((column = (pgColumn *)colIt.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (colcount++) + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } + + line += column->GetQuotedIdentifier(); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); + } + } + } + + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; +} + +pgCollection *pgTable::GetColumnCollection(ctlTree *browser) +{ + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + return columns; +} + +pgCollection *pgTable::GetConstraintCollection(ctlTree *browser) +{ + pgCollection *constraints = browser->FindCollection(constraintFactory, GetId()); + return constraints; +} + +wxString pgTable::GetSelectSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +wxString pgTable::GetInsertSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("INSERT INTO ") + GetQuotedFullIdentifier() + wxT("(\n") + wxT(" ") + GetCols(browser, 12, qms, false) + wxT(")\n") + wxT(" VALUES (") + qms + wxT(");\n"); + return sql; +} + + +wxString pgTable::GetUpdateSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("UPDATE ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" SET ") + GetCols(browser, 7, qms, true) + wxT("\n") + wxT(" WHERE ;\n"); + return sql; +} + +wxString pgTable::GetDeleteSql(ctlTree *browser) +{ + wxString sql = + wxT("DELETE FROM ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" WHERE ;\n"); + return sql; +} + +bool pgTable::EnableTriggers(const bool b) +{ + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullIdentifier() + wxT(" "); + + if (!b) + sql += wxT("DISABLE"); + else + sql += wxT("ENABLE"); + + sql += wxT(" TRIGGER ALL"); + + return GetDatabase()->ExecuteVoid(sql); +} + +void pgTable::UpdateRows() +{ + pgSet *props = ExecuteSet(wxT("SELECT count(*) AS rows FROM ONLY ") + GetQuotedFullIdentifier()); + if (props) + { + rows = props->GetLongLong(0); + delete props; + rowsCounted = true; + } +} + + +void pgTable::UpdateInheritance() +{ + // not checked so far + pgSet *props = ExecuteSet( + wxT("SELECT c.oid, c.relname , nspname\n") + wxT(" FROM pg_inherits i\n") + wxT(" JOIN pg_class c ON c.oid = i.inhparent\n") + wxT(" JOIN pg_namespace n ON n.oid=c.relnamespace\n") + wxT(" WHERE i.inhrelid = ") + GetOidStr() + wxT("\n") + wxT(" ORDER BY inhseqno")); + if (props) + { + inheritedTableCount = 0; + inheritedTables = wxT(""); + while (!props->Eof()) + { + if (inheritedTableCount) + { + inheritedTables += wxT(", "); + quotedInheritedTables += wxT(", "); + } + inheritedTables += props->GetVal(wxT("relname")); + quotedInheritedTables += GetQuotedSchemaPrefix(props->GetVal(wxT("nspname"))) + + qtIdent(props->GetVal(wxT("relname"))); + quotedInheritedTablesList.Add(GetQuotedSchemaPrefix(props->GetVal(wxT("nspname"))) + + qtIdent(props->GetVal(wxT("relname")))); + inheritedTablesOidList.Add(props->GetVal(wxT("oid"))); + props->MoveNext(); + inheritedTableCount++; + } + delete props; + } +} + + + + + +void pgTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + + // Log + wxLogInfo(wxT("Adding child object to table %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, columnFactory); + browser->AppendCollection(this, constraintFactory); + browser->AppendCollection(this, indexFactory); + browser->AppendCollection(this, ruleFactory); + browser->AppendCollection(this, triggerFactory); + + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum() && GetIsPartitioned()) + browser->AppendCollection(this, partitionFactory); + + if (GetConnection() != 0 && (!GetPartKeyDef().IsEmpty()||GetIsPartitioned())) + browser->AppendCollection(this, pg_partitionFactory); + + + // convert list of columns numbers to column names + wxStringTokenizer collist(GetPrimaryKeyColNumbers(), wxT(",")); + wxString cn; + + while (collist.HasMoreTokens()) + { + cn = collist.GetNextToken(); + pgSet *set = ExecuteSet( + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum IN (") + cn + wxT(")")); + if (set) + { + if (!primaryKey.IsNull()) + { + quotedPrimaryKey += wxT(", "); + primaryKey += wxT(", "); + } + primaryKey += set->GetVal(0); + quotedPrimaryKey += qtIdent(set->GetVal(0)); + delete set; + } + } + + if (settings->GetAutoRowCountThreshold() >= GetEstimatedRows()) + UpdateRows(); + + UpdateInheritance(); + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + if (GetConnection() != 0 && GetConnection()->GetIsGreenplum()) + { + gpPartition *p = dynamic_cast(this); + if (p != 0) + properties->AppendItem(_("Partition Name"), p->GetPartitionName()); + } + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + if (GetConnection()->BackendMinimumVersion(8, 0)) + properties->AppendItem(_("Tablespace"), tablespace); + properties->AppendItem(_("ACL"), GetAcl()); + if (GetConnection()->BackendMinimumVersion(9, 0)) + properties->AppendItem(_("Of type"), ofType); + if (GetPrimaryKey().IsNull()) + properties->AppendItem(_("Primary key"), _("")); + else + properties->AppendItem(_("Primary key"), GetPrimaryKey()); + + properties->AppendItem(_("Rows (estimated)"), GetEstimatedRows()); + + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + + if (rowsCounted) + properties->AppendItem(_("Rows (counted)"), rows); + else + properties->AppendItem(_("Rows (counted)"), _("not counted")); + + long setId; + wxString clusterName; + long repStat = GetReplicationStatus(browser, &clusterName, &setId); + + wxString clusterInfo; + clusterInfo.Printf(_("Cluster \"%s\", set %ld"), clusterName.c_str(), setId); + + wxString repString; + switch (repStat) + { + case REPLICATIONSTATUS_SUBSCRIBED: + repString = _("Published"); + break; + case REPLICATIONSTATUS_REPLICATED: + repString = _("Replicated"); + break; + case REPLICATIONSTATUS_MULTIPLY_PUBLISHED: + repString = _("Replicated"); + clusterName = _("Multiple clusters"); + break; + default: + break; + } + if (!repString.IsEmpty()) + properties->AppendItem(repString, clusterInfo); + + properties->AppendYesNoItem(_("Inherits tables"), GetHasSubclass()); + properties->AppendItem(_("Inherited tables count"), GetInheritedTableCount()); + if (GetInheritedTableCount()) + properties->AppendItem(_("Inherited tables"), GetInheritedTables()); + if (GetConnection()->BackendMinimumVersion(9, 1)) + properties->AppendYesNoItem(_("Unlogged?"), GetUnlogged()); + if (!GetConnection()->BackendMinimumVersion(12, 0)) + properties->AppendYesNoItem(_("Has OIDs?"), GetHasOids()); + if (!GetConnection()->BackendMinimumVersion(12, 0)) + properties->AppendYesNoItem(_("System table?"), GetSystemObject()); + if (GetConnection()->GetIsPgProEnt()) + properties->AppendItem(_("CFS fragmentation"), GetRatio()); + + /* Custom AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(8, 4) && GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Table auto-vacuum enabled?"), GetAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM base threshold"), GetAutoVacuumVacuumThreshold()); + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM scale factor"), GetAutoVacuumVacuumScaleFactor()); + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE base threshold"), GetAutoVacuumAnalyzeThreshold()); + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE scale factor"), GetAutoVacuumAnalyzeScaleFactor()); + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost delay"), GetAutoVacuumVacuumCostDelay()); + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost limit"), GetAutoVacuumVacuumCostLimit()); + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE minimum age"), GetAutoVacuumFreezeMinAge()); + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE maximum age"), GetAutoVacuumFreezeMaxAge()); + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE table age"), GetAutoVacuumFreezeTableAge()); + } + + /* Custom TOAST-TABLE AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(8, 4) && + GetHasToastTable() && + GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Toast auto-vacuum enabled?"), GetToastAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM base threshold"), GetToastAutoVacuumVacuumThreshold()); + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM scale factor"), GetToastAutoVacuumVacuumScaleFactor()); + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost delay"), GetToastAutoVacuumVacuumCostDelay()); + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost limit"), GetToastAutoVacuumVacuumCostLimit()); + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE minimum age"), GetToastAutoVacuumFreezeMinAge()); + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE maximum age"), GetToastAutoVacuumFreezeMaxAge()); + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE table age"), GetToastAutoVacuumFreezeTableAge()); + } + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } + if (form && GetVacuumHint() && !hintShown) + { + ShowHint(form, false); + } +} + + +bool pgTable::GetCanHint() +{ + return (GetVacuumHint() || primaryKey.IsEmpty()); +} + + +bool pgTable::GetVacuumHint() +{ + bool canHint = false; + + if (rowsCounted) + { + if (!estimatedRows || (estimatedRows == 1000 && rows.GetValue() != 1000)) + canHint = (rows >= 20); + else + { + double rowsDbl = (wxLongLong_t)rows.GetValue(); + double quot = rowsDbl * 10. / estimatedRows; + canHint = ((quot > 12 || quot < 8) && (rowsDbl < estimatedRows - 20. || rowsDbl > estimatedRows + 20.)); + } + } + else if (estimatedRows == 1000) + { + canHint = true; + } + return canHint; +} + + +void pgTable::ShowHint(frmMain *form, bool force) +{ + hintShown = true; + int rc; + + if (force) + { + wxArrayString hints; + if (GetVacuumHint()) + hints.Add(HINT_VACUUM); + if (primaryKey.IsEmpty()) + hints.Add(HINT_PRIMARYKEY); + + rc = frmHint::ShowHint(form, hints, GetFullIdentifier(), force); + } + else + rc = frmHint::ShowHint(form, HINT_VACUUM, GetFullIdentifier(), force); + + if (rc == HINT_RC_FIX) + { + frmMaintenance *frm = new frmMaintenance(form, this); + frm->Go(); + } +} + + + + +pgObject *pgTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgTable *table = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + table = (pgTable *)tableFactory.CreateObjects(coll, 0, wxT("\n AND rel.oid=") + GetOidStr()); + + return table; +} + + +bool pgTable::HasPgstattuple() +{ + return GetConnection()->HasFeature(FEATURE_PGSTATTUPLE); +} + +void pgTable::iSetTriggersEnabled(ctlTree *browser, bool enable) +{ + pgCollection *triggers = browser->FindCollection(triggerFactory, GetId()); + if (triggers) + { + triggers->ShowTreeDetail(browser); + treeObjectIterator trgIt(browser, triggers); + + pgTrigger *trigger; + while ((trigger = (pgTrigger *)trgIt.GetNextObject()) != 0) + { + trigger->SetEnabled(browser, enable); + } + } +} + +/////////////////////////////////////////////////////////// + + +pgTableCollection::pgTableCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing tables"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for tables"); + break; + case STATISTICSREPORT: + message = _("Tables statistics report"); + break; + case OBJSTATISTICS: + message = _("Tables statistics"); + break; + case OBJECTSLISTREPORT: + message = _("Tables list report"); + break; + } + + return message; +} + + +void pgTableCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for tables on %s"), GetSchema()->GetIdentifier().c_str()); + + bool hasSize = GetConnection()->HasFeature(FEATURE_SIZE); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Table Name")); + if (hasSize) + statistics->AddColumn(_("Size"), 50); + + statistics->AddColumn(_("Tuples inserted")); + statistics->AddColumn(_("Tuples updated")); + statistics->AddColumn(_("Tuples deleted")); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->AddColumn(_("Tuples HOT updated")); + statistics->AddColumn(_("Live tuples")); + statistics->AddColumn(_("Dead tuples")); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + statistics->AddColumn(_("Last vacuum")); + statistics->AddColumn(_("Last autovacuum")); + statistics->AddColumn(_("Last analyze")); + statistics->AddColumn(_("Last autoanalyze")); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->AddColumn(_("Vacuum counter")); + statistics->AddColumn(_("Autovacuum counter")); + statistics->AddColumn(_("Analyze counter")); + statistics->AddColumn(_("Autoanalyze counter")); + } + + wxString sql = wxT("SELECT st.relname, n_tup_ins, n_tup_upd, n_tup_del"); + if (GetConnection()->BackendMinimumVersion(8, 3)) + sql += wxT(", n_tup_hot_upd, n_live_tup, n_dead_tup"); + if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += wxT(", last_vacuum, last_autovacuum, last_analyze, last_autoanalyze"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += wxT(", vacuum_count, autovacuum_count, analyze_count, autoanalyze_count"); + if (hasSize) + sql += wxT(", pg_size_pretty(pg_relation_size(st.relid)") + wxT(" + CASE WHEN cl.reltoastrelid = 0 THEN 0 ELSE pg_relation_size(cl.reltoastrelid) + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0) END") + wxT(" + COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=st.relid)::int8, 0)) AS size"); + + sql += wxT("\n FROM pg_stat_all_tables st") + wxT(" JOIN pg_class cl on cl.oid=st.relid\n") + wxT(" WHERE schemaname = ") + qtDbString(GetSchema()->GetName()) + + wxT("\n ORDER BY relname"); + + pgSet *stats = GetDatabase()->ExecuteSet(sql); + + if (stats) + { + long pos = 0; + int i; + while (!stats->Eof()) + { + i = 5; + statistics->InsertItem(pos, stats->GetVal(wxT("relname")), PGICON_STATISTICS); + if (hasSize) + statistics->SetItem(pos, 1, stats->GetVal(wxT("size"))); + statistics->SetItem(pos, 2, stats->GetVal(wxT("n_tup_ins"))); + statistics->SetItem(pos, 3, stats->GetVal(wxT("n_tup_upd"))); + statistics->SetItem(pos, 4, stats->GetVal(wxT("n_tup_del"))); + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_tup_hot_upd"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_live_tup"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("n_dead_tup"))); + } + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_vacuum"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autovacuum"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_analyze"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("last_autoanalyze"))); + } + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + statistics->SetItem(pos, i++, stats->GetVal(wxT("vacuum_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("autovacuum_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("analyze_count"))); + statistics->SetItem(pos, i++, stats->GetVal(wxT("autoanalyze_count"))); + } + stats->MoveNext(); + pos++; + } + + delete stats; + } + statistics->SetColumnWidth(0,wxLIST_AUTOSIZE); +} + + +/////////////////////////////////////////////////////////// + + +void pgTable::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxString sql = + wxT("SELECT seq_scan AS ") + qtIdent(_("Sequential Scans")) + + wxT(", seq_tup_read AS ") + qtIdent(_("Sequential Tuples Read")) + + wxT(", idx_scan AS ") + qtIdent(_("Index Scans")) + + wxT(", idx_tup_fetch AS ") + qtIdent(_("Index Tuples Fetched")) + + wxT(", n_tup_ins AS ") + qtIdent(_("Tuples Inserted")) + + wxT(", n_tup_upd AS ") + qtIdent(_("Tuples Updated")) + + wxT(", n_tup_del AS ") + qtIdent(_("Tuples Deleted")); + + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + sql += + wxT(", n_tup_hot_upd AS ") + qtIdent(_("Tuples HOT Updated")) + + wxT(", n_live_tup AS ") + qtIdent(_("Live Tuples")) + + wxT(", n_dead_tup AS ") + qtIdent(_("Dead Tuples")); + } + + sql += wxT(", heap_blks_read AS ") + qtIdent(_("Heap Blocks Read")) + + wxT(", heap_blks_hit AS ") + qtIdent(_("Heap Blocks Hit")) + + wxT(", idx_blks_read AS ") + qtIdent(_("Index Blocks Read")) + + wxT(", idx_blks_hit AS ") + qtIdent(_("Index Blocks Hit")) + + wxT(", toast_blks_read AS ") + qtIdent(_("Toast Blocks Read")) + + wxT(", toast_blks_hit AS ") + qtIdent(_("Toast Blocks Hit")) + + wxT(", tidx_blks_read AS ") + qtIdent(_("Toast Index Blocks Read")) + + wxT(", tidx_blks_hit AS ") + qtIdent(_("Toast Index Blocks Hit")); + + if (GetConnection()->BackendMinimumVersion(8, 2)) + { + sql += + wxT(", last_vacuum AS ") + qtIdent(_("Last Vacuum")) + + wxT(", last_autovacuum AS ") + qtIdent(_("Last Autovacuum")) + + wxT(", last_analyze AS ") + qtIdent(_("Last Analyze")) + + wxT(", last_autoanalyze AS ") + qtIdent(_("Last Autoanalyze")); + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + sql += + wxT(", vacuum_count AS ") + qtIdent(_("Vacuum counter")) + + wxT(", autovacuum_count AS ") + qtIdent(_("Autovacuum counter")) + + wxT(", analyze_count AS ") + qtIdent(_("Analyze counter")) + + wxT(", autoanalyze_count AS ") + qtIdent(_("Autoanalyze counter")); + } + + if (GetConnection()->HasFeature(FEATURE_SIZE)) + { + sql += wxT(", pg_size_pretty(pg_relation_size(stat.relid)) AS ") + qtIdent(_("Table Size")) + + wxT(", CASE WHEN cl.reltoastrelid = 0 THEN ") + qtDbString(_("none")) + wxT(" ELSE pg_size_pretty(pg_relation_size(cl.reltoastrelid)+ COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=cl.reltoastrelid)::int8, 0)) END AS ") + qtIdent(_("Toast Table Size")) + + wxT(", pg_size_pretty(COALESCE((SELECT SUM(pg_relation_size(indexrelid)) FROM pg_index WHERE indrelid=stat.relid)::int8, 0)) AS ") + qtIdent(_("Indexes Size")); + } + + if (showExtendedStatistics) + { + sql += wxT("\n") + wxT(", tuple_count AS ") + qtIdent(_("Tuple Count")) + wxT(",\n") + wxT(" pg_size_pretty(tuple_len) AS ") + qtIdent(_("Tuple Length")) + wxT(",\n") + wxT(" tuple_percent AS ") + qtIdent(_("Tuple Percent")) + wxT(",\n") + wxT(" dead_tuple_count AS ") + qtIdent(_("Dead Tuple Count")) + wxT(",\n") + wxT(" pg_size_pretty(dead_tuple_len) AS ") + qtIdent(_("Dead Tuple Length")) + wxT(",\n") + wxT(" dead_tuple_percent AS ") + qtIdent(_("Dead Tuple Percent")) + wxT(",\n") + wxT(" pg_size_pretty(free_space) AS ") + qtIdent(_("Free Space")) + wxT(",\n") + wxT(" free_percent AS ") + qtIdent(_("Free Percent")) + wxT("\n") + wxT(" FROM pgstattuple('") + GetQuotedFullIdentifier() + wxT("'), pg_stat_all_tables stat"); + } + else + { + sql += wxT("\n") + wxT(" FROM pg_stat_all_tables stat"); + } + sql += wxT("\n") + wxT(" JOIN pg_statio_all_tables statio ON stat.relid = statio.relid\n") + wxT(" JOIN pg_class cl ON cl.oid=stat.relid\n") + wxT(" WHERE stat.relid = ") + GetOidStr(); + + + DisplayStatistics(statistics, sql); +} + + +pgObject *pgTableFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString query; + pgTable *table = 0; + + // Greenplum returns reltuples and relpages as tuples per segmentDB and pages per segmentDB, + // so we need to multiply them by the number of segmentDBs to get reasonable values. + long gp_segments = 1; + if (collection->GetConnection()->GetIsGreenplum()) + { + query = wxT("SELECT count(*) AS gp_segments from pg_catalog.gp_configuration where definedprimary = 't' and content >= 0"); + gp_segments = StrToLong(collection->GetDatabase()->ExecuteScalar(query)); + if (gp_segments <= 1) + gp_segments = 1; + } + + pgSet *tables; + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + query = wxT("SELECT rel.oid, rel.relname, rel.reltablespace AS spcoid, spc.spcname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, ") + wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl,\n"); + + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + query += wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisinternal = FALSE) AS triggercount\n"); + } + else + { + query += wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisconstraint = FALSE) AS triggercount\n"); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(", rel.relpersistence \n"); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + if (collection->GetConnection()->GetIsGreenplum()) + { + query += wxT(", gpd.localoid, gpd.attrnums \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'appendonly=([a-z]*)') AS appendonly \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'compresslevel=([0-9]*)') AS compresslevel \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'orientation=([a-z]*)') AS orientation \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'compresstype=([a-z0-9]*)') AS compresstype \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'blocksize=([0-9]*)') AS blocksize \n"); + query += wxT(", substring(array_to_string(rel.reloptions, ',') from 'checksum=([a-z]*)') AS checksum \n"); + if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + query += wxT(", rel.oid in (select parrelid from pg_partition) as ispartitioned\n"); + } + else if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + query += wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(rel.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", rel.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN rel.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + query += wxT(", rel.reloftype, typ.typname\n"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + query += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=rel.oid AND sl1.objsubid=0) AS labels"); + query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); + } + wxString pg10=wxEmptyString; + if (collection->GetDatabase()->BackendMinimumVersion(10, 0)) + { + query += wxT(",case when lk.relation=rel.oid then null else pg_get_partkeydef(rel.oid) end \n AS partkeydef"); + query += wxT(",case when lk.relation=rel.oid then null else pg_get_expr(rel.relpartbound, rel.oid) end \n AS partexp"); + query += wxT(",(select count(*)from pg_inherits ii where ii.inhparent=rel.oid) >0 AS ispartitioned"); + //pg10=wxT("pg_get_expr(rel.relpartbound, rel.oid) is null and"); + pg10=wxT("(rel.relpartbound is null and i.inhrelid is null) and"); + //query += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=rel.oid AND sl2.objsubid=0) AS providers"); + } +// 'ALTER STATISTICS '||substring('CREATE STATISTICS public.tab_a (dependencies) ON c1, c3 FROM a' from 'ICS (.+?)\s\(')||' OWNER TO '|| + //select relation from pg_locks where locktype='relation' and granted=true and mode='AccessExclusiveLock' + if (collection->GetDatabase()->connection()->GetIsPgProEnt()) query += wxT(",left((cfs_fragmentation(rel.oid)*100)::text,5)::text AS cfs_ratio"); + else query += wxT(",null::text AS cfs_ratio"); + + if (collection->GetDatabase()->BackendMinimumVersion(10, 0)) + { + query += wxT(",\n pg_get_statisticsobjdef(stat_ext.oid) AS stat_stmt"); + query += wxT(",\nCASE WHEN stat_ext.stxowner<>rel.relowner then 'ALTER STATISTICS '||substring(pg_get_statisticsobjdef(stat_ext.oid) from 'ICS (.+?)\\s\\(')||' OWNER TO '||stat_ext.stxowner::regrole else null end AS alter_stmt"); + } + query += wxT(" FROM pg_class rel\n") + wxT(" LEFT JOIN pg_locks lk ON locktype='relation' and granted=true and mode='AccessExclusiveLock' and relation=rel.oid\n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=rel.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_inherits i on i.inhrelid=rel.oid\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n"); + + // Add the toast table for vacuum parameters. + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + query += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = rel.reltoastrelid\n"); + + if (collection->GetConnection()->GetIsGreenplum()) + query += wxT(" LEFT OUTER JOIN gp_distribution_policy gpd ON gpd.localoid=rel.oid\n"); + + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + query += wxT("LEFT JOIN pg_type typ ON rel.reloftype=typ.oid\n"); + if (collection->GetConnection()->BackendMinimumVersion(10, 0)) + query += wxT("LEFT JOIN pg_statistic_ext stat_ext ON rel.oid=stat_ext.stxrelid\n"); + + query += wxT(" WHERE ")+pg10+wxT(" rel.relkind IN ('r','s','t','p') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + + // Greenplum: Eliminate (sub)partitions from the display, only show the parent partitioned table + // and eliminate external tables + if (collection->GetConnection()->GetIsGreenplum() && collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + query += wxT("AND rel.relstorage <> 'x' AND rel.oid NOT IN (SELECT parchildrelid from pg_partition_rule)"); + // only show the parent partitioned table + if (collection->GetConnection()->BackendMinimumVersion(10, 0)){ + //addIcon(tables_png_img); + query += wxT("AND (not (rel.relkind='r' and rel.relpartbound IS NOT NULL)) "); + } + + query += restriction + + wxT(" ORDER BY rel.relname"); + } + else + { + query = wxT("SELECT rel.oid, rel.relname, pg_get_userbyid(rel.relowner) AS relowner, rel.relacl, ") + wxT("rel.relhassubclass, rel.reltuples, des.description, con.conname, con.conkey,\n") + wxT(" (select count(*) FROM pg_trigger\n") + wxT(" WHERE tgrelid=rel.oid AND tgisconstraint = FALSE) AS triggercount,\n") + wxT(" EXISTS(select 1 FROM pg_trigger\n") + wxT(" JOIN pg_proc pt ON pt.oid=tgfoid AND pt.proname='logtrigger'\n") + wxT(" JOIN pg_proc pc ON pc.pronamespace=pt.pronamespace AND pc.proname='slonyversion'\n") + wxT(" WHERE tgrelid=rel.oid) AS isrepl\n") + wxT(" FROM pg_class rel\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=rel.oid AND des.objsubid=0 AND des.classoid='pg_class'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_constraint con ON con.conrelid=rel.oid AND con.contype='p'\n") + wxT(" WHERE rel.relkind IN ('r','s','t') AND rel.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY rel.relname"); + } + tables = collection->GetDatabase()->ExecuteSet(query); + if (tables) + { + while (!tables->Eof()) + { + table = new pgTable(collection->GetSchema(), tables->GetVal(wxT("relname"))); + + table->iSetOid(tables->GetOid(wxT("oid"))); + table->iSetOwner(tables->GetVal(wxT("relowner"))); + table->iSetAcl(tables->GetVal(wxT("relacl"))); + table->iSetRatio(tables->GetVal(wxT("cfs_ratio"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 0)) + { + if (tables->GetOid(wxT("spcoid")) == 0) + table->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + table->iSetTablespaceOid(tables->GetOid(wxT("spcoid"))); + + if (tables->GetVal(wxT("spcname")) == wxEmptyString) + table->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + table->iSetTablespace(tables->GetVal(wxT("spcname"))); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 0)) + { + table->iSetOfTypeOid(tables->GetOid(wxT("reloftype"))); + table->iSetOfType(tables->GetVal(wxT("typname"))); + } + else + { + table->iSetOfTypeOid(0); + table->iSetOfType(wxT("")); + } + table->iSetComment(tables->GetVal(wxT("description"))); + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + table->iSetUnlogged(tables->GetVal(wxT("relpersistence")) == wxT("u")); + else + table->iSetUnlogged(false); + table->iSetHasOids(false); + table->iSetEstimatedRows(tables->GetDouble(wxT("reltuples")) * gp_segments); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + { + table->iSetFillFactor(tables->GetVal(wxT("fillfactor"))); + } + + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + table->iSetRelOptions(tables->GetVal(wxT("reloptions"))); + if (table->GetCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + table->iSetAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("autovacuum_enabled"))) + table->iSetAutoVacuumEnabled(1); + else + table->iSetAutoVacuumEnabled(0); + table->iSetAutoVacuumVacuumThreshold(tables->GetVal(wxT("autovacuum_vacuum_threshold"))); + table->iSetAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + table->iSetAutoVacuumAnalyzeThreshold(tables->GetVal(wxT("autovacuum_analyze_threshold"))); + table->iSetAutoVacuumAnalyzeScaleFactor(tables->GetVal(wxT("autovacuum_analyze_scale_factor"))); + table->iSetAutoVacuumVacuumCostDelay(tables->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + table->iSetAutoVacuumVacuumCostLimit(tables->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + table->iSetAutoVacuumFreezeMinAge(tables->GetVal(wxT("autovacuum_freeze_min_age"))); + table->iSetAutoVacuumFreezeMaxAge(tables->GetVal(wxT("autovacuum_freeze_max_age"))); + table->iSetAutoVacuumFreezeTableAge(tables->GetVal(wxT("autovacuum_freeze_table_age"))); + } + table->iSetHasToastTable(tables->GetBool(wxT("hastoasttable"))); + if (table->GetHasToastTable()) + { + table->iSetToastRelOptions(tables->GetVal(wxT("toast_reloptions"))); + + if (table->GetToastCustomAutoVacuumEnabled()) + { + if (tables->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + table->iSetToastAutoVacuumEnabled(2); + else if (tables->GetBool(wxT("toast_autovacuum_enabled"))) + table->iSetToastAutoVacuumEnabled(1); + else + table->iSetToastAutoVacuumEnabled(0); + + table->iSetToastAutoVacuumVacuumThreshold(tables->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + table->iSetToastAutoVacuumVacuumScaleFactor(tables->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + table->iSetToastAutoVacuumVacuumCostDelay(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + table->iSetToastAutoVacuumVacuumCostLimit(tables->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + table->iSetToastAutoVacuumFreezeMinAge(tables->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + table->iSetToastAutoVacuumFreezeMaxAge(tables->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + table->iSetToastAutoVacuumFreezeTableAge(tables->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + } + table->iSetHasSubclass(tables->GetBool(wxT("relhassubclass"))); + table->iSetPrimaryKeyName(tables->GetVal(wxT("conname"))); + table->iSetIsReplicated(tables->GetBool(wxT("isrepl"))); + table->iSetTriggerCount(tables->GetLong(wxT("triggercount"))); + wxString cn = tables->GetVal(wxT("conkey")); + cn = cn.Mid(1, cn.Length() - 2); + table->iSetPrimaryKeyColNumbers(cn); + table->iSetPartitionDef(wxT("")); + table->iSetIsPartitioned(false); + + if (collection->GetConnection()->BackendMinimumVersion(10, 0)) + { + table->iSetPartKeyDef(tables->GetVal(wxT("partkeydef"))); + table->iSetPartExp(tables->GetVal(wxT("partexp"))); + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + wxString st = tables->GetVal(wxT("stat_stmt")); + wxString at = tables->GetVal(wxT("alter_stmt")); + if (!st.IsEmpty()&&!at.IsEmpty()) st=st+wxT(";\n")+at; + table->iSetStatExt(st); + + } + if (collection->GetConnection()->GetIsGreenplum()) + { + Oid lo = tables->GetOid(wxT("localoid")); + wxString db = tables->GetVal(wxT("attrnums")); + db = db.Mid(1, db.Length() - 2); + table->iSetDistributionColNumbers(db); + if (lo > 0 && db.Length() == 0) + table->iSetDistributionIsRandom(); + table->iSetAppendOnly(tables->GetVal(wxT("appendonly"))); + table->iSetCompressLevel(tables->GetVal(wxT("compresslevel"))); + table->iSetOrientation(tables->GetVal(wxT("orientation"))); + table->iSetCompressType(tables->GetVal(wxT("compresstype"))); + table->iSetBlocksize(tables->GetVal(wxT("blocksize"))); + table->iSetChecksum(tables->GetVal(wxT("checksum"))); + + + if (collection->GetConnection()->BackendMinimumVersion(8, 2, 9)) + { + table->iSetIsPartitioned(tables->GetBool(wxT("ispartitioned"))); + } + + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + { + table->iSetProviders(tables->GetVal(wxT("providers"))); + table->iSetLabels(tables->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + +bool pgTableObjCollection::CanCreate() +{ + // We don't create sub-objects of Views or External tables + if (GetTable()->GetMetaType() == PGM_VIEW || GetTable()->GetMetaType() == GP_EXTTABLE) + return false; + + return GetSchema()->GetCreatePrivilege(); +} + + +#include "images/table.pngc" +#include "images/table-repl.pngc" +#include "images/table-repl-sm.pngc" +#include "images/table-sm.pngc" +#include "images/tables.pngc" + +pgTableFactory::pgTableFactory() + : pgSchemaObjFactory(__("Table"), __("New Table..."), __("Create a new Table."), table_png_img, table_sm_png_img) +{ + metaType = PGM_TABLE; + if (WantSmallIcon()) + replicatedIconId = addIcon(table_repl_sm_png_img); + else + replicatedIconId = addIcon(table_repl_png_img); + partitionsIconId=addIcon(tables_png_img); +} + +pgCollection *pgTableFactory::CreateCollection(pgObject *obj) +{ + return new pgTableCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTableFactory tableFactory; +static pgaCollectionFactory cf(&tableFactory, __("Tables"), tables_png_img); + + +pgCollection *pgTableObjFactory::CreateCollection(pgObject *obj) +{ + return new pgTableObjCollection(GetCollectionFactory(), (pgTable *)obj); +} + + +countRowsFactory::countRowsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Count"), _("Count rows in the selected object.")); +} + + +wxWindow *countRowsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->StartMsg(_("Counting rows")); + + ((pgTable *)obj)->UpdateRows(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + form->EndMsg(); + + return 0; +} + + +bool countRowsFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)); +} + + +executePgstattupleFactory::executePgstattupleFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Extended table statistics"), _("Get extended statistics via pgstattuple for the selected object."), wxITEM_CHECK); +} + + +wxWindow *executePgstattupleFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (!((pgTable *)obj)->GetShowExtendedStatistics()) + { + ((pgTable *)obj)->iSetShowExtendedStatistics(true); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + form->SelectStatisticsTab(); + } + else + ((pgTable *)obj)->iSetShowExtendedStatistics(false); + + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool executePgstattupleFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && ((pgTable *)obj)->HasPgstattuple(); +} + +bool executePgstattupleFactory::CheckChecked(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && ((pgTable *)obj)->GetShowExtendedStatistics(); +} + +disableAllTriggersFactory::disableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Disable triggers"), _("Disable all triggers on the selected table.")); +} + + +wxWindow *disableAllTriggersFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to disable all triggers on this table?"), _("Disable triggers"), wxYES_NO) != wxYES) + return 0; + + if (!((pgTable *)obj)->EnableTriggers(false)) + return 0; + + ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), false); + + return 0; +} + + +bool disableAllTriggersFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && obj->CanEdit() + && (obj->GetOwner() == obj->GetConnection()->GetUser() || obj->GetServer()->GetSuperUser()) + && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTable *)obj)->GetTriggerCount() > 0; +} + +enableAllTriggersFactory::enableAllTriggersFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Enable triggers"), _("Enable all triggers on the selected table.")); +} + + +wxWindow *enableAllTriggersFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to enable all triggers on this table?"), _("Enable triggers"), wxYES_NO) != wxYES) + return 0; + + if (!((pgTable *)obj)->EnableTriggers(true)) + return 0; + + ((pgTable *)obj)->iSetTriggersEnabled(form->GetBrowser(), true); + + return 0; +} + + +bool enableAllTriggersFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && obj->CanEdit() + && (obj->GetOwner() == obj->GetConnection()->GetUser() || obj->GetServer()->GetSuperUser()) + && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTable *)obj)->GetTriggerCount() > 0; +} + +truncateFactory::truncateFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Truncate"), _("Truncate the selected table.")); +} + + +wxWindow *truncateFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to truncate this table?\n\nWARNING: This action will delete ALL data in the table!"), _("Truncate table"), wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT) != wxYES) + return 0; + + ((pgTable *)obj)->Truncate(false); + ((pgTable *)obj)->UpdateRows(); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + return 0; +} + + +bool truncateFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(tableFactory); +} + + +truncateCascadedFactory::truncateCascadedFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Truncate Cascaded"), _("Truncate the selected table and all referencing tables.")); +} + + +wxWindow *truncateCascadedFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to truncate this table and all tables that have foreign key references to this table?\n\nWARNING: This action will delete ALL data in the tables!"), _("Truncate table cascaded"), wxYES_NO | wxICON_QUESTION | wxNO_DEFAULT) != wxYES) + return 0; + + ((pgTable *)obj)->Truncate(true); + ((pgTable *)obj)->UpdateRows(); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + return 0; +} + + +bool truncateCascadedFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(tableFactory) && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(8, 2); +} + + +resetTableStatsFactory::resetTableStatsFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Reset table statistics"), _("Reset statistics of the selected table.")); +} + + +wxWindow *resetTableStatsFactory::StartDialog(frmMain *form, pgObject *obj) +{ + if (wxMessageBox(_("Are you sure you wish to reset statistics of this table?"), _("Reset statistics"), wxYES_NO) != wxYES) + return 0; + + ((pgTable *)obj)->ResetStats(); + ((pgTable *)obj)->ShowStatistics(form, form->GetStatistics()); + + return 0; +} + + +bool resetTableStatsFactory::CheckEnable(pgObject *obj) +{ + return obj && ( obj->IsCreatedBy(pg_partitionFactory) ||obj->IsCreatedBy(tableFactory)) && ((pgTable *)obj)->GetConnection()->BackendMinimumVersion(9, 0); +} diff --git a/schema/pgTablespace.cpp b/schema/pgTablespace.cpp new file mode 100644 index 0000000..6449c30 --- /dev/null +++ b/schema/pgTablespace.cpp @@ -0,0 +1,467 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTablespace.cpp - PostgreSQL Tablespace +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "utils/pgfeatures.h" +#include "schema/pgTablespace.h" +#include "schema/pgDatabase.h" +#include "frm/frmMain.h" +#include "dlg/dlgMoveTablespace.h" + + +pgTablespace::pgTablespace(const wxString &newName) + : pgServerObject(tablespaceFactory, newName) +{ +} + +wxString pgTablespace::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on tablespace"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing tablespace"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop tablespace \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop tablespace \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop tablespace cascaded?"); + break; + case DROPTITLE: + message = _("Drop tablespace?"); + break; + case PROPERTIESREPORT: + message = _("Tablespace properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Tablespace properties"); + break; + case DDLREPORT: + message = _("Tablespace DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Tablespace DDL"); + break; + case STATISTICSREPORT: + message = _("Tablespace statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("Tablespace statistics"); + break; + case DEPENDENCIESREPORT: + message = _("Tablespace dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Tablespace dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Tablespace dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Tablespace dependents"); + break; + } + + return message; +} + +void pgTablespace::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + form->StartMsg(_(" Retrieving tablespace usage")); + + referencedBy->ClearAll(); + referencedBy->AddColumn(_("Type"), 60); + referencedBy->AddColumn(_("Database"), 80); + referencedBy->AddColumn(_("Name"), 300); + + wxArrayString dblist; + + pgSet *set = GetConnection()->ExecuteSet( + wxT("SELECT datname, datallowconn, dattablespace\n") + wxT(" FROM pg_database db\n") + wxT(" ORDER BY datname")); + + if (set) + { + while (!set->Eof()) + { + wxString datname = set->GetVal(wxT("datname")); + if (set->GetBool(wxT("datallowconn"))) + dblist.Add(datname); + OID oid = set->GetOid(wxT("dattablespace")); + if (oid == GetOid()) + referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), datname); + + set->MoveNext(); + } + delete set; + } + + FillOwned(form->GetBrowser(), referencedBy, dblist, + wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n") + wxT(" LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n") + wxT(" LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid,\n") + wxT(" pg_database\n") + wxT(" WHERE datname = current_database()\n") + wxT(" AND (cl.reltablespace = ") + GetOidStr() + wxT("\n") + wxT(" OR (cl.reltablespace=0 AND dattablespace = ") + GetOidStr() + wxT("))\n") + wxT(" ORDER BY 1,2,3")); + + form->EndMsg(set != 0); +} + + +bool pgTablespace::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetConnection()->ExecuteVoid(wxT("DROP TABLESPACE ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString pgTablespace::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Tablespace: ") + GetName() + wxT("\n\n"); + if (location.IsEmpty()) + sql += wxT("-- System Tablespace\n"); + else + sql += wxT("-- DROP TABLESPACE ") + GetQuotedIdentifier() + + wxT("\n\nCREATE TABLESPACE ") + GetQuotedIdentifier() + + wxT("\n OWNER ") + qtIdent(GetOwner()) + + wxT("\n LOCATION ") + qtDbString(location) + + wxT(";\n"); + sql += GetCommentSql(); + + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + sql += wxT("ALTER TABLESPACE ") + GetQuotedFullIdentifier() + + wxT(" SET (") + variables.Item(i) + wxT(");\n"); + + if (GetConnection()->BackendMinimumVersion(9, 2)) + sql += GetSeqLabelsSql(); + } + return sql; +} + + +void pgTablespace::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Location"), GetLocation()); + size_t i; + for (i = 0 ; i < variables.GetCount() ; i++) + { + wxString item = variables.Item(i); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + +void pgTablespace::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (statistics) + { + if (GetConnection()->HasFeature(FEATURE_SIZE)) + { + wxLogInfo(wxT("Displaying statistics for %s"), GetTypeName().c_str()); + + // Add the statistics view columns + CreateListColumns(statistics, _("Statistic"), _("Value")); + + pgSet *stats = GetConnection()->ExecuteSet( + wxT("SELECT pg_size_pretty(pg_tablespace_size(") + GetOidStr() + wxT(")) AS ") + qtIdent(_("Tablespace Size"))); + + if (stats) + { + int col; + for (col = 0 ; col < stats->NumCols() ; col++) + { + if (!stats->ColName(col).IsEmpty()) + statistics->AppendItem(stats->ColName(col), stats->GetVal(col)); + } + delete stats; + } + } + } +} + + +void pgTablespace::MoveTablespace(frmMain *form) +{ + wxString query; + + dlgMoveTablespace rdo(form, GetConnection(), this); + if (rdo.ShowModal() != wxID_CANCEL) + { + if (wxMessageBox(wxString::Format( + _("Are you sure you wish to move objects from %s to %s?"), + GetQuotedFullIdentifier().c_str(), rdo.GetTablespace().c_str()), + _("Move tablespace?"), + wxYES_NO) != wxYES) + return; + + wxArrayString kind = rdo.GetKind(); + wxString ownerInfo, + moveTo = qtIdent(rdo.GetTablespace()), + currTblSpace = GetQuotedFullIdentifier(); + + if (rdo.GetOwner().Length() > 0) + { + ownerInfo = wxString::Format( + wxT(" OWNED BY %s"), + qtIdent(rdo.GetOwner()).c_str()); + } + + for(size_t index = 0; index < kind.GetCount(); ++index) + { + query += wxString::Format( + wxT("ALTER %s ALL IN TABLESPACE %s%s SET TABLESPACE %s;\n"), + kind.Item(index).c_str(), + currTblSpace.c_str(), + ownerInfo.c_str(), + moveTo.c_str()); + } + GetConnection()->ExecuteVoid(query); + } +} + + +pgObject *pgTablespace::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *tablespace = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + tablespace = tablespaceFactory.CreateObjects(coll, 0, wxT("\n WHERE ts.oid=") + GetOidStr()); + + return tablespace; +} + + + +pgObject *pgTablespaceFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTablespace *tablespace = 0; + + pgSet *tablespaces; + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, pg_catalog.pg_tablespace_location(ts.oid) AS spclocation, spcoptions, ") + wxT("pg_get_userbyid(spcowner) as spcuser, spcacl, ") + wxT("pg_catalog.shobj_description(oid, 'pg_tablespace') AS description, ") + wxT("(SELECT array_agg(label) FROM pg_shseclabel sl1 WHERE sl1.objoid=ts.oid) AS labels, ") + wxT("(SELECT array_agg(provider) FROM pg_shseclabel sl2 WHERE sl2.objoid=ts.oid) AS providers ") + wxT("FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + else if (collection->GetConnection()->BackendMinimumVersion(8, 5)) + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, spclocation, spcoptions, pg_get_userbyid(spcowner) as spcuser, spcacl, pg_catalog.shobj_description(oid, 'pg_tablespace') AS description FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + else if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, spclocation, pg_get_userbyid(spcowner) as spcuser, spcacl, pg_catalog.shobj_description(oid, 'pg_tablespace') AS description FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + else + tablespaces = collection->GetServer()->ExecuteSet( + wxT("SELECT ts.oid, spcname, spclocation, '' AS description, pg_get_userbyid(spcowner) as spcuser, spcacl FROM pg_tablespace ts\n") + + restriction + wxT(" ORDER BY spcname")); + + if (tablespaces) + { + while (!tablespaces->Eof()) + { + + tablespace = new pgTablespace(tablespaces->GetVal(wxT("spcname"))); + tablespace->iSetServer(collection->GetServer()); + tablespace->iSetOid(tablespaces->GetOid(wxT("oid"))); + tablespace->iSetOwner(tablespaces->GetVal(wxT("spcuser"))); + tablespace->iSetLocation(tablespaces->GetVal(wxT("spclocation"))); + tablespace->iSetAcl(tablespaces->GetVal(wxT("spcacl"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 2)) + tablespace->iSetComment(tablespaces->GetVal(wxT("description"))); + if (collection->GetConnection()->BackendMinimumVersion(8, 5)) + { + wxString str = tablespaces->GetVal(wxT("spcoptions")); + if (!str.IsEmpty()) + FillArray(tablespace->GetVariables(), str.Mid(1, str.Length() - 2)); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + tablespace->iSetProviders(tablespaces->GetVal(wxT("providers"))); + tablespace->iSetLabels(tablespaces->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, tablespace); + tablespaces->MoveNext(); + } + else + break; + } + + delete tablespaces; + } + return tablespace; +} + + +pgTablespaceCollection::pgTablespaceCollection(pgaFactory *factory, pgServer *sv) + : pgServerObjCollection(factory, sv) +{ +} + + +void pgTablespaceCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + if (GetConnection()->HasFeature(FEATURE_SIZE)) + { + wxLogInfo(wxT("Displaying statistics for tablespaces")); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Tablespace"), 100); + statistics->AddColumn(_("Size"), 60); + + pgSet *stats = GetConnection()->ExecuteSet( + wxT("SELECT spcname, pg_size_pretty(pg_tablespace_size(oid)) AS size FROM pg_tablespace ORDER BY spcname")); + + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + statistics->InsertItem(pos, stats->GetVal(wxT("spcname")), PGICON_STATISTICS); + statistics->SetItem(pos, 1, stats->GetVal(wxT("size"))); + stats->MoveNext(); + pos++; + } + + delete stats; + } + } +} + + +wxString pgTablespaceCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on tablespaces"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing tablespaces"); + break; + case STATISTICSREPORT: + message = _("Tablespaces statistics report"); + break; + case OBJSTATISTICS: + message = _("Tablespaces statistics"); + break; + case OBJECTSLISTREPORT: + message = _("Tablespaces list report"); + break; + } + + return message; +} + + +#include "images/tablespace.pngc" +#include "images/tablespaces.pngc" + + +pgTablespaceFactory::pgTablespaceFactory() + : pgServerObjFactory(__("Tablespace"), __("New Tablespace..."), __("Create a new Tablespace."), tablespace_png_img) +{ + metaType = PGM_TABLESPACE; +} + + +pgCollection *pgTablespaceFactory::CreateCollection(pgObject *obj) +{ + return new pgTablespaceCollection(GetCollectionFactory(), (pgServer *)obj); +} + +pgTablespaceFactory tablespaceFactory; +static pgaCollectionFactory cf(&tablespaceFactory, __("Tablespaces"), tablespaces_png_img); + +moveTablespaceFactory::moveTablespaceFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Move objects to..."), _("Move objects of the selected tablespace to another one.")); +} + + +wxWindow *moveTablespaceFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgTablespace *)obj)->MoveTablespace(form); + + return 0; +} + +bool moveTablespaceFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(tablespaceFactory) && ((pgTablespace *)obj)->GetConnection()->BackendMinimumVersion(9, 4); +} diff --git a/schema/pgTextSearchConfiguration.cpp b/schema/pgTextSearchConfiguration.cpp new file mode 100644 index 0000000..bbe3109 --- /dev/null +++ b/schema/pgTextSearchConfiguration.cpp @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchConfiguration.cpp - Text Search Configuration class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchConfiguration.h" + + +pgTextSearchConfiguration::pgTextSearchConfiguration(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchConfigurationFactory, newName) +{ +} + +pgTextSearchConfiguration::~pgTextSearchConfiguration() +{ +} + +wxString pgTextSearchConfiguration::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS configuration"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS configuration"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS configuration \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS configuration \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS configuration cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS configuration?"); + break; + case PROPERTIESREPORT: + message = _("FTS configuration properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS configuration properties"); + break; + case DDLREPORT: + message = _("FTS configuration DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS configuration DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS configuration dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS configuration dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS configuration dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS configuration dependents"); + break; + } + + return message; +} + +bool pgTextSearchConfiguration::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH CONFIGURATION ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchConfiguration::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Configuration: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH CONFIGURATION ") + GetFullIdentifier() + wxT("\n\n") + + wxT("CREATE TEXT SEARCH CONFIGURATION ") + GetFullIdentifier() + wxT(" (") + + wxT("\n PARSER = ") + qtTypeIdent(GetParser()) + + wxT("\n);\n"); + + for (size_t i = 0 ; i < tokens.GetCount() ; i++) + sql += wxT("ALTER TEXT SEARCH CONFIGURATION ") + GetQuotedFullIdentifier() + + wxT(" ADD MAPPING FOR ") + tokens.Item(i).BeforeFirst('/') + + wxT(" WITH ") + tokens.Item(i).AfterFirst('/') + + wxT(";\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH CONFIGURATION ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchConfiguration::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Parser"), GetParser()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchConfiguration::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *config = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + config = textSearchConfigurationFactory.CreateObjects(coll, 0, wxT("\n AND cfg.oid=") + GetOidStr()); + + return config; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchConfigurationCollection::pgTextSearchConfigurationCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchConfigurationCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS configurations"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS configurations"); + break; + case OBJECTSLISTREPORT: + message = _("FTS configurations list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchConfigurationFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchConfiguration *config = 0; + + pgSet *configurations; + configurations = collection->GetDatabase()->ExecuteSet( + wxT("SELECT cfg.oid, cfg.cfgname, pg_get_userbyid(cfg.cfgowner) as cfgowner, cfg.cfgparser, parser.prsname as parsername, description\n") + wxT(" FROM pg_ts_config cfg\n") + wxT(" LEFT OUTER JOIN pg_ts_parser parser ON parser.oid=cfg.cfgparser\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=cfg.oid AND des.classoid='pg_ts_config'::regclass)\n") + wxT(" WHERE cfg.cfgnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY cfg.cfgname")); + + if (configurations) + { + while (!configurations->Eof()) + { + config = new pgTextSearchConfiguration(collection->GetSchema(), configurations->GetVal(wxT("cfgname"))); + config->iSetOid(configurations->GetOid(wxT("oid"))); + config->iSetOwner(configurations->GetVal(wxT("cfgowner"))); + config->iSetComment(configurations->GetVal(wxT("description"))); + config->iSetParser(configurations->GetVal(wxT("parsername"))); + config->iSetParserOid(configurations->GetOid(wxT("cfgparser"))); + + pgSet *maps; + maps = collection->GetDatabase()->ExecuteSet( + wxT("SELECT\n") + wxT(" (SELECT t.alias FROM pg_catalog.ts_token_type(cfgparser) AS t") + wxT(" WHERE t.tokid = maptokentype) AS tokenalias,\n") + wxT(" dictname\n") + wxT("FROM pg_ts_config_map\n") + wxT(" LEFT OUTER JOIN pg_ts_config ON mapcfg=pg_ts_config.oid\n") + wxT(" LEFT OUTER JOIN pg_ts_dict ON mapdict=pg_ts_dict.oid\n") + wxT("WHERE mapcfg=") + config->GetOidStr() + wxT("\n") + wxT("ORDER BY 1, mapseqno")); + + if (maps) + { + wxString tokenToAdd; + while (!maps->Eof()) + { + if (tokenToAdd.Length() > 0 && + !tokenToAdd.BeforeFirst('/').IsSameAs(maps->GetVal(wxT("tokenalias")), false)) + { + config->GetTokens().Add(tokenToAdd); + tokenToAdd = wxT(""); + } + + if (tokenToAdd.Length() == 0) + tokenToAdd = maps->GetVal(wxT("tokenalias")) + wxT("/") + maps->GetVal(wxT("dictname")); + else + tokenToAdd += wxT(",") + maps->GetVal(wxT("dictname")); + + maps->MoveNext(); + } + + delete maps; + } + + if (browser) + { + browser->AppendObject(collection, config); + configurations->MoveNext(); + } + else + break; + } + + delete configurations; + } + return config; +} + + +#include "images/configuration.pngc" +#include "images/configurations.pngc" + +pgTextSearchConfigurationFactory::pgTextSearchConfigurationFactory() + : pgSchemaObjFactory(__("FTS Configuration"), __("New FTS Configuration..."), __("Create a new FTS Configuration."), configuration_png_img) +{ +} + + +pgCollection *pgTextSearchConfigurationFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchConfigurationCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchConfigurationFactory textSearchConfigurationFactory; +static pgaCollectionFactory cf(&textSearchConfigurationFactory, __("FTS Configurations"), configurations_png_img); diff --git a/schema/pgTextSearchDictionary.cpp b/schema/pgTextSearchDictionary.cpp new file mode 100644 index 0000000..10b1248 --- /dev/null +++ b/schema/pgTextSearchDictionary.cpp @@ -0,0 +1,241 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchDictionary.cpp - Text Search Dictionary class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchDictionary.h" + + +pgTextSearchDictionary::pgTextSearchDictionary(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchDictionaryFactory, newName) +{ +} + +pgTextSearchDictionary::~pgTextSearchDictionary() +{ +} + +wxString pgTextSearchDictionary::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS dictionary"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS dictionary"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS dictionary \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS dictionary \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS dictionary cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS dictionary?"); + break; + case PROPERTIESREPORT: + message = _("FTS dictionary properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS dictionary properties"); + break; + case DDLREPORT: + message = _("FTS dictionary DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS dictionary DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS dictionary dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS dictionary dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS dictionary dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS dictionary dependents"); + break; + } + + return message; +} + +bool pgTextSearchDictionary::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH DICTIONARY ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchDictionary::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Dictionary: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH DICTIONARY ") + GetFullIdentifier() + wxT("\n\n") + + wxT("CREATE TEXT SEARCH DICTIONARY ") + GetFullIdentifier() + wxT(" (") + + wxT("\n TEMPLATE = ") + qtTypeIdent(GetTemplate()); + + if (options.Length() > 0) + sql += wxT(",\n ") + options; + + sql += wxT("\n);\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH DICTIONARY ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchDictionary::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Template"), GetTemplate()); + properties->AppendItem(_("Options"), GetOptions()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchDictionary::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *dict = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + dict = textSearchDictionaryFactory.CreateObjects(coll, 0, wxT("\n AND dict.oid=") + GetOidStr()); + + return dict; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchDictionaryCollection::pgTextSearchDictionaryCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchDictionaryCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS dictionaries"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS dictionaries"); + break; + case OBJECTSLISTREPORT: + message = _("FTS dictionaries list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchDictionaryFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchDictionary *dict = 0; + + pgSet *dictionaries; + dictionaries = collection->GetDatabase()->ExecuteSet( + wxT("SELECT dict.oid, dict.dictname, pg_get_userbyid(dict.dictowner) as dictowner, t.tmplname, dict.dictinitoption, description\n") + wxT(" FROM pg_ts_dict dict\n") + wxT(" LEFT OUTER JOIN pg_ts_template t ON t.oid=dict.dicttemplate\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=dict.oid AND des.classoid='pg_ts_dict'::regclass)\n") + wxT(" WHERE dict.dictnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY dict.dictname")); + + if (dictionaries) + { + while (!dictionaries->Eof()) + { + dict = new pgTextSearchDictionary(collection->GetSchema(), dictionaries->GetVal(wxT("dictname"))); + dict->iSetOid(dictionaries->GetOid(wxT("oid"))); + dict->iSetOwner(dictionaries->GetVal(wxT("dictowner"))); + dict->iSetComment(dictionaries->GetVal(wxT("description"))); + dict->iSetTemplate(dictionaries->GetVal(wxT("tmplname"))); + dict->iSetOptions(dictionaries->GetVal(wxT("dictinitoption"))); + + if (browser) + { + browser->AppendObject(collection, dict); + dictionaries->MoveNext(); + } + else + break; + } + + delete dictionaries; + } + return dict; +} + + +#include "images/dictionary.pngc" +#include "images/dictionaries.pngc" + +pgTextSearchDictionaryFactory::pgTextSearchDictionaryFactory() + : pgSchemaObjFactory(__("FTS Dictionary"), __("New FTS Dictionary..."), __("Create a new FTS Dictionary."), dictionary_png_img) +{ +} + + +pgCollection *pgTextSearchDictionaryFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchDictionaryCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchDictionaryFactory textSearchDictionaryFactory; +static pgaCollectionFactory cf(&textSearchDictionaryFactory, __("FTS Dictionaries"), dictionaries_png_img); diff --git a/schema/pgTextSearchParser.cpp b/schema/pgTextSearchParser.cpp new file mode 100644 index 0000000..5216216 --- /dev/null +++ b/schema/pgTextSearchParser.cpp @@ -0,0 +1,253 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchParser.cpp - Text Search Parser class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchParser.h" + + +pgTextSearchParser::pgTextSearchParser(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchParserFactory, newName) +{ +} + +pgTextSearchParser::~pgTextSearchParser() +{ +} + +wxString pgTextSearchParser::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS parser"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS parser"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS parser \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS parser \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS parser cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS parser?"); + break; + case PROPERTIESREPORT: + message = _("FTS parser properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS parser properties"); + break; + case DDLREPORT: + message = _("FTS parser DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS parser DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS parser dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS parser dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS parser dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS parser dependents"); + break; + } + + return message; +} + +bool pgTextSearchParser::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH PARSER ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchParser::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Parser: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH PARSER ") + GetFullIdentifier() + wxT("\n\n") + + wxT("CREATE TEXT SEARCH PARSER ") + GetFullIdentifier() + wxT(" (") + + wxT("\n START = ") + qtTypeIdent(GetStart()) + + wxT(",\n GETTOKEN = ") + qtTypeIdent(GetGettoken()) + + wxT(",\n END = ") + qtTypeIdent(GetEnd()) + + wxT(",\n LEXTYPES = ") + qtTypeIdent(GetLextypes()); + + AppendIfFilled(sql, wxT(",\n HEADLINE = "), GetHeadline()); + + sql += wxT("\n);\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH PARSER ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchParser::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Start"), GetStart()); + properties->AppendItem(_("Gettoken"), GetGettoken()); + properties->AppendItem(_("End"), GetEnd()); + properties->AppendItem(_("Lextypes"), GetLextypes()); + properties->AppendItem(_("Headline"), GetHeadline()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchParser::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *parser = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + parser = textSearchParserFactory.CreateObjects(coll, 0, wxT("\n AND prs.oid=") + GetOidStr()); + + return parser; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchParserCollection::pgTextSearchParserCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchParserCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS parsers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS parsers"); + break; + case OBJECTSLISTREPORT: + message = _("FTS parsers list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchParserFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchParser *parser = 0; + + pgSet *parsers; + parsers = collection->GetDatabase()->ExecuteSet( + wxT("SELECT prs.oid, prs.prsname, prs.prsstart, prs.prstoken, prs.prsend, prs.prslextype, prs.prsheadline, description\n") + wxT(" FROM pg_ts_parser prs\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=prs.oid AND des.classoid='pg_ts_parser'::regclass)\n") + wxT(" WHERE prs.prsnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY prs.prsname")); + + if (parsers) + { + while (!parsers->Eof()) + { + parser = new pgTextSearchParser(collection->GetSchema(), parsers->GetVal(wxT("prsname"))); + parser->iSetOid(parsers->GetOid(wxT("oid"))); + parser->iSetComment(parsers->GetVal(wxT("description"))); + parser->iSetStart(parsers->GetVal(wxT("prsstart"))); + parser->iSetGettoken(parsers->GetVal(wxT("prstoken"))); + parser->iSetEnd(parsers->GetVal(wxT("prsend"))); + parser->iSetLextypes(parsers->GetVal(wxT("prslextype"))); + if (parsers->GetVal(wxT("prsheadline")).Cmp(wxT("-")) != 0) + { + parser->iSetHeadline(parsers->GetVal(wxT("prsheadline"))); + } + else + { + parser->iSetHeadline(wxT("")); + } + + if (browser) + { + browser->AppendObject(collection, parser); + parsers->MoveNext(); + } + else + break; + } + + delete parsers; + } + return parser; +} + + +#include "images/parser.pngc" +#include "images/parsers.pngc" + +pgTextSearchParserFactory::pgTextSearchParserFactory() + : pgSchemaObjFactory(__("FTS Parser"), __("New FTS Parser..."), __("Create a new FTS Parser."), parser_png_img) +{ +} + + +pgCollection *pgTextSearchParserFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchParserCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchParserFactory textSearchParserFactory; +static pgaCollectionFactory cf(&textSearchParserFactory, __("FTS Parsers"), parsers_png_img); diff --git a/schema/pgTextSearchTemplate.cpp b/schema/pgTextSearchTemplate.cpp new file mode 100644 index 0000000..6eb8cf4 --- /dev/null +++ b/schema/pgTextSearchTemplate.cpp @@ -0,0 +1,242 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTextSearchTemplate.cpp - Text Search Template class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgTextSearchTemplate.h" + + +pgTextSearchTemplate::pgTextSearchTemplate(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, textSearchTemplateFactory, newName) +{ +} + +pgTextSearchTemplate::~pgTextSearchTemplate() +{ +} + +wxString pgTextSearchTemplate::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS template"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS template"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS template \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop FTS template \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop FTS template cascaded?"); + break; + case DROPTITLE: + message = _("Drop FTS template?"); + break; + case PROPERTIESREPORT: + message = _("FTS template properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("FTS template properties"); + break; + case DDLREPORT: + message = _("FTS template DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("FTS template DDL"); + break; + case DEPENDENCIESREPORT: + message = _("FTS template dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("FTS template dependencies"); + break; + case DEPENDENTSREPORT: + message = _("FTS template dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("FTS template dependents"); + break; + } + + return message; +} + +bool pgTextSearchTemplate::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TEXT SEARCH TEMPLATE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + qtIdent(this->GetIdentifier()); + + if (cascaded) + sql += wxT(" CASCADE"); + + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgTextSearchTemplate::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Text Search Template: ") + GetFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TEXT SEARCH TEMPLATE ") + GetFullIdentifier() + wxT("\n\n") + wxT("CREATE TEXT SEARCH TEMPLATE ") + GetFullIdentifier() + wxT(" ("); + AppendIfFilled(sql, wxT("\n INIT = "), GetInit()); + AppendIfFilled(sql, wxT(",\n LEXIZE = "), GetLexize()); + sql += wxT("\n);\n"); + + if (!GetComment().IsNull()) + sql += wxT("COMMENT ON TEXT SEARCH TEMPLATE ") + GetFullIdentifier() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +void pgTextSearchTemplate::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Init"), GetInit()); + properties->AppendItem(_("Lexize"), GetLexize()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTextSearchTemplate::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *tstemplate = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + tstemplate = textSearchTemplateFactory.CreateObjects(coll, 0, wxT("\n AND tmpl.oid=") + GetOidStr()); + + return tstemplate; +} + + +/////////////////////////////////////////////////// + + +pgTextSearchTemplateCollection::pgTextSearchTemplateCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTextSearchTemplateCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on FTS templates"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing FTS templates"); + break; + case OBJECTSLISTREPORT: + message = _("FTS templates list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////////// + + +pgObject *pgTextSearchTemplateFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgTextSearchTemplate *tmpl = 0; + + pgSet *templates; + templates = collection->GetDatabase()->ExecuteSet( + wxT("SELECT tmpl.oid, tmpl.tmplname, tmpl.tmplinit, tmpl.tmpllexize, description\n") + wxT(" FROM pg_ts_template tmpl\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=tmpl.oid AND des.classoid='pg_ts_template'::regclass)\n") + wxT(" WHERE tmpl.tmplnamespace = ") + collection->GetSchema()->GetOidStr() + + restriction + wxT("\n") + wxT(" ORDER BY tmpl.tmplname")); + + if (templates) + { + while (!templates->Eof()) + { + tmpl = new pgTextSearchTemplate(collection->GetSchema(), templates->GetVal(wxT("tmplname"))); + tmpl->iSetOid(templates->GetOid(wxT("oid"))); + tmpl->iSetComment(templates->GetVal(wxT("description"))); + if (templates->GetVal(wxT("tmplinit")).Cmp(wxT("-")) != 0) + { + tmpl->iSetInit(templates->GetVal(wxT("tmplinit"))); + } + else + { + tmpl->iSetInit(wxT("")); + } + tmpl->iSetLexize(templates->GetVal(wxT("tmpllexize"))); + + if (browser) + { + browser->AppendObject(collection, tmpl); + templates->MoveNext(); + } + else + break; + } + + delete templates; + } + return tmpl; +} + + +#include "images/template.pngc" +#include "images/templates.pngc" + +pgTextSearchTemplateFactory::pgTextSearchTemplateFactory() + : pgSchemaObjFactory(__("FTS Template"), __("New FTS Template..."), __("Create a new FTS Template."), template_png_img) +{ +} + + +pgCollection *pgTextSearchTemplateFactory::CreateCollection(pgObject *obj) +{ + return new pgTextSearchTemplateCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTextSearchTemplateFactory textSearchTemplateFactory; +static pgaCollectionFactory cf(&textSearchTemplateFactory, __("FTS Templates"), templates_png_img); diff --git a/schema/pgTrigger.cpp b/schema/pgTrigger.cpp new file mode 100644 index 0000000..a381951 --- /dev/null +++ b/schema/pgTrigger.cpp @@ -0,0 +1,637 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgTrigger.cpp - Trigger class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "frm/frmMain.h" +#include "utils/misc.h" +#include "utils/pgDefs.h" +#include "schema/pgObject.h" +#include "schema/pgTrigger.h" +#include "schema/pgFunction.h" + + +pgTrigger::pgTrigger(pgSchema *newSchema, const wxString &newName) + : pgTriggerObject(newSchema, triggerFactory, newName) +{ + triggerFunction = 0; +} + + +pgTrigger::~pgTrigger() +{ + if (!expandedKids && triggerFunction) + { + // triggerFunction wasn't appended to tree, so we + // need to delete it manually + delete triggerFunction; + } +} + +wxString pgTrigger::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on trigger"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing trigger"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for trigger"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop trigger \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop trigger cascaded?"); + break; + case DROPTITLE: + message = _("Drop trigger?"); + break; + case PROPERTIESREPORT: + message = _("Trigger properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Trigger properties"); + break; + case DDLREPORT: + message = _("Trigger DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Trigger DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Trigger dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Trigger dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Trigger dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Trigger dependents"); + break; + } + + return message; +} + +int pgTrigger::GetIconId() +{ + if (GetEnabled()) + return triggerFactory.GetIconId(); + else + return triggerFactory.GetClosedIconId(); +} + + +bool pgTrigger::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_trigger WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +bool pgTrigger::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TRIGGER ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +void pgTrigger::SetEnabled(ctlTree *browser, const bool b) +{ + if (GetQuotedFullTable().Len() > 0 && ((enabled && !b) || (!enabled && b))) + { + wxString sql = wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" "); + if (enabled && !b) + sql += wxT("DISABLE"); + else if (!enabled && b) + sql += wxT("ENABLE"); + sql += wxT(" TRIGGER ") + GetQuotedIdentifier(); + GetDatabase()->ExecuteVoid(sql); + } + enabled = b; + UpdateIcon(browser); +} + + +void pgTrigger::SetDirty() +{ + if (expandedKids) + triggerFunction = 0; + pgObject::SetDirty(); +} + + +wxString pgTrigger::GetSql(ctlTree *browser) +{ + if (sql.IsNull() && (this->triggerFunction || GetLanguage() == wxT("edbspl"))) + { + sql = wxT("-- Trigger: ") + GetName() + wxT(" on ") + GetQuotedFullTable() + wxT("\n\n") + + wxT("-- DROP TRIGGER ") + qtIdent(GetName()) + + wxT(" ON ") + GetQuotedFullTable() + wxT(";\n\n"); + + if (GetLanguage() == wxT("edbspl")) + sql += wxT("CREATE OR REPLACE TRIGGER "); + else if (GetConnection()->BackendMinimumVersion(8, 2) && GetIsConstraint()) + sql += wxT("CREATE CONSTRAINT TRIGGER "); + else + sql += wxT("CREATE TRIGGER "); + + sql += qtIdent(GetName()) + wxT("\n ") + + GetFireWhen() + + wxT(" ") + GetEvent(); + + sql += wxT("\n ON ") + GetQuotedFullTable(); + if (GetDeferrable()) + { + sql += wxT("\n DEFERRABLE INITIALLY "); + if (GetDeferred()) + sql += wxT("DEFERRED"); + else + sql += wxT("IMMEDIATE"); + } + if (!GetReferences().IsEmpty()) + { + sql += wxT("\n ")+GetReferences(); + } + + sql += wxT("\n FOR EACH ") + GetForEach(); + + if (GetConnection()->BackendMinimumVersion(8, 5) + && !GetWhen().IsEmpty()) + sql += wxT("\n WHEN (") + GetWhen() + wxT(")"); + + if (GetLanguage() == wxT("edbspl")) + { + sql += wxT("\n") + GetSource(); + if (!sql.Trim().EndsWith(wxT(";"))) + sql = sql.Trim() + wxT(";"); + sql += wxT("\n"); + } + else + { + sql += wxT("\n EXECUTE PROCEDURE ") + triggerFunction->GetQuotedFullIdentifier() + + wxT("(") + GetArguments() + wxT(")") + + wxT(";\n"); + } + + if (!GetEnabled()) + { + sql += wxT("ALTER TABLE ") + GetQuotedFullTable() + wxT(" ") + + wxT("DISABLE TRIGGER ") + GetQuotedIdentifier() + wxT(";\n"); + } + + if (!GetComment().IsEmpty()) + sql += wxT("COMMENT ON TRIGGER ") + GetQuotedIdentifier() + wxT(" ON ") + GetQuotedFullTable() + + wxT(" IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + + return sql; +} + + +wxString pgTrigger::GetFireWhen() const +{ + wxString when = wxEmptyString; + + if (triggerType & TRIGGER_TYPE_BEFORE) + when = wxT("BEFORE"); + else if (triggerType & TRIGGER_TYPE_INSTEAD) + when = wxT("INSTEAD OF"); + else + when = wxT("AFTER"); + return when; +} + + +wxString pgTrigger::GetEvent() const +{ + wxString event; + if (triggerType & TRIGGER_TYPE_INSERT) + event = wxT("INSERT"); + if (triggerType & TRIGGER_TYPE_UPDATE) + { + if (!event.IsNull()) + event += wxT(" OR "); + event += wxT("UPDATE"); + if (!GetQuotedColumns().IsEmpty()) + event += wxT(" OF ") + GetQuotedColumns(); + } + if (triggerType & TRIGGER_TYPE_DELETE) + { + if (!event.IsNull()) + event += wxT(" OR "); + event += wxT("DELETE"); + } + if (triggerType & TRIGGER_TYPE_TRUNCATE) + { + if (!event.IsNull()) + event += wxT(" OR "); + event += wxT("TRUNCATE"); + } + return event; +} + +wxString pgTrigger::GetForEach() const +{ + return (triggerType & TRIGGER_TYPE_ROW) ? wxT("ROW") : wxT("STATEMENT"); +} + + + +void pgTrigger::ReadColumnDetails() +{ + if (!expandedKids) + { + expandedKids = true; + + if (GetConnection()->BackendMinimumVersion(8, 5)) + { + pgSet *res = ExecuteSet( + wxT("SELECT attname\n") + wxT("FROM pg_attribute,\n") + wxT("(SELECT tgrelid, unnest(tgattr) FROM pg_trigger\n") + wxT(" WHERE oid=") + GetOidStr() + wxT(") AS columns(tgrelid, colnum)\n") + wxT("WHERE colnum=attnum AND tgrelid=attrelid")); + + // Allocate memory to store column def + if (res->NumRows() > 0) columnList.Alloc(res->NumRows()); + + long i = 1; + columns = wxT(""); + quotedColumns = wxT(""); + + while (!res->Eof()) + { + if (i > 1) + { + columns += wxT(", "); + quotedColumns += wxT(", "); + } + + columns += res->GetVal(wxT("attname")); + quotedColumns += qtIdent(res->GetVal(wxT("attname"))); + columnList.Add(res->GetVal(wxT("attname"))); + + i++; + res->MoveNext(); + } + delete res; + } + else + { + columns = wxT(""); + quotedColumns = wxT(""); + } + } +} + + +void pgTrigger::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + ReadColumnDetails(); + + if (browser) + { + // if no browser present, function will not be appended to tree + expandedKids = true; + } + + if (GetLanguage() != wxT("edbspl")) + { + if (triggerFunction) + delete triggerFunction; + + // append function here + triggerFunction = functionFactory.AppendFunctions(this, GetSchema(), browser, wxT( + "WHERE pr.oid=") + NumToStr(functionOid) + wxT("::oid\n")); + if (triggerFunction) + { + iSetFunction(triggerFunction->GetQuotedFullIdentifier()); + } + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + if (GetConnection()->BackendMinimumVersion(8, 2)) + properties->AppendYesNoItem(_("Constraint?"), GetIsConstraint()); + properties->AppendItem(_("Fires"), GetFireWhen()); + properties->AppendItem(_("Event"), GetEvent()); + if (!GetQuotedColumns().IsEmpty()) + { + properties->AppendItem(_("Columns"), GetColumns()); + } + properties->AppendItem(_("For each"), GetForEach()); + if (GetLanguage() != wxT("edbspl")) + properties->AppendItem(_("Function"), GetFunction() + wxT("(") + GetArguments() + wxT(")")); + if (GetConnection()->BackendMinimumVersion(8, 5)) + properties->AppendItem(_("When?"), GetWhen()); + properties->AppendYesNoItem(_("Enabled?"), GetEnabled()); + properties->AppendYesNoItem(_("System trigger?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgTrigger::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *trigger = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + wxString restr = wxT("\n AND t.tgname=") + qtDbString(GetName()) + + wxT(" AND cl.oid=") + NumToStr(GetRelationOid()) + + wxT("::oid AND cl.relnamespace=") + GetSchema()->GetOidStr() + wxT("::oid"); + trigger = triggerFactory.CreateObjects(coll, 0, restr); + } + + return trigger; +} + + + +pgObject *pgTriggerFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + pgSchemaObjCollection *collection = (pgSchemaObjCollection *)coll; + pgTrigger *trigger = 0; + wxString ref=wxT(""); + if (collection->GetDatabase()->connection()->BackendMinimumVersion(10, 0)) + { + ref = wxT("tgoldtable,tgnewtable,"); + } + + wxString trig_sql; + trig_sql = wxT("SELECT t.oid, t.xmin, t.*, relname, CASE WHEN relkind = 'r' THEN TRUE ELSE FALSE END AS parentistable, ")+ref+ + wxT(" nspname, des.description, l.lanname, p.prosrc, \n") + wxT(" COALESCE(substring(pg_get_triggerdef(t.oid), 'WHEN (.*) EXECUTE PROCEDURE'), substring(pg_get_triggerdef(t.oid), 'WHEN (.*) \\$trigger')) AS whenclause\n") + wxT(" FROM pg_trigger t\n") + wxT(" JOIN pg_class cl ON cl.oid=tgrelid\n") + wxT(" JOIN pg_namespace na ON na.oid=relnamespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_trigger'::regclass)\n") + wxT(" LEFT OUTER JOIN pg_proc p ON p.oid=t.tgfoid\n") + wxT(" LEFT OUTER JOIN pg_language l ON l.oid=p.prolang\n") + wxT(" WHERE "); + if (collection->GetDatabase()->connection()->BackendMinimumVersion(9, 0)) + { + trig_sql += wxT("NOT tgisinternal"); + } + else if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + { + trig_sql += wxT("tgconstraint=0"); + } + else + { + trig_sql += wxT("NOT tgisconstraint"); + } + if (restriction.IsEmpty()) + trig_sql += wxT("\n AND tgrelid = ") + collection->GetOidStr() + wxT("\n"); + else + trig_sql += restriction + wxT("\n"); + trig_sql += wxT(" ORDER BY tgname"); + pgSet *triggers = collection->GetDatabase()->ExecuteSet(trig_sql); + + if (triggers) + { + while (!triggers->Eof()) + { + // Be careful that the schema of a trigger (and a rule) is the schema of the schema + trigger = new pgTrigger(collection->GetSchema()->GetSchema(), triggers->GetVal(wxT("tgname"))); + + trigger->iSetOid(triggers->GetOid(wxT("oid"))); + trigger->iSetXid(triggers->GetOid(wxT("xmin"))); + trigger->iSetComment(triggers->GetVal(wxT("description"))); + trigger->iSetFunctionOid(triggers->GetOid(wxT("tgfoid"))); + trigger->iSetRelationOid(triggers->GetOid(wxT("tgrelid"))); + if (!ref.IsEmpty()) { + wxString strsum=wxT(""); + if (!triggers->GetVal(wxT("tgoldtable")).IsEmpty()) { + strsum=wxT("REFERENCING OLD TABLE AS ")+triggers->GetVal(wxT("tgoldtable")); + } + if (!triggers->GetVal(wxT("tgnewtable")).IsEmpty()) { + if (strsum.IsEmpty()) strsum=wxT("REFERENCING"); + strsum+=wxT(" NEW TABLE AS ")+triggers->GetVal(wxT("tgnewtable")); + } + + trigger->iSetReferences(strsum); + } + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 3)) + { + if (triggers->GetVal(wxT("tgenabled")) != wxT("D")) + trigger->iSetEnabled(true); + else + trigger->iSetEnabled(false); + } + else + trigger->iSetEnabled(triggers->GetBool(wxT("tgenabled"))); + + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 2)) + { + if (collection->GetDatabase()->connection()->BackendMinimumVersion(9, 0)) + trigger->SetIsConstraint(triggers->GetLong(wxT("tgconstraint")) > 0); + else + trigger->SetIsConstraint(triggers->GetBool(wxT("tgisconstraint"))); + + trigger->iSetDeferrable(triggers->GetBool(wxT("tgdeferrable"))); + trigger->iSetDeferred(triggers->GetBool(wxT("tginitdeferred"))); + } + else + { + trigger->SetIsConstraint(false); + trigger->iSetDeferrable(false); + trigger->iSetDeferred(false); + } + + trigger->iSetTriggerType(triggers->GetLong(wxT("tgtype"))); + trigger->iSetParentIsTable(triggers->GetBool(wxT("parentistable"))); + + trigger->iSetLanguage(triggers->GetVal(wxT("lanname"))); + trigger->iSetSource(triggers->GetVal(wxT("prosrc"))); + trigger->iSetQuotedFullTable(collection->GetDatabase()->GetQuotedSchemaPrefix(triggers->GetVal(wxT("nspname"))) + qtIdent(triggers->GetVal(wxT("relname")))); + wxString arglist = wxEmptyString; + if (triggers->GetLong(wxT("tgnargs")) > 0) + arglist = triggers->GetVal(wxT("tgargs")); + wxString args = wxEmptyString; + + while (!arglist.IsEmpty()) + { + int pos = arglist.Find(wxT("\\000")); + if (pos != 0) + { + wxString arg; + if (pos > 0) + arg = arglist.Left(pos); + else + arg = arglist; + + if (!args.IsEmpty()) + args += wxT(", "); + if (NumToStr(StrToLong(arg)) == arg) + args += arg; + else + args += collection->GetDatabase()->GetConnection()->qtDbString(arg); + } + else + { + if (!args.IsEmpty()) + args += wxT(", "); + args += collection->GetDatabase()->GetConnection()->qtDbString(wxEmptyString); + } + if (pos >= 0) + arglist = arglist.Mid(pos + 4); + else + break; + } + trigger->iSetArguments(args); + + if (collection->GetDatabase()->connection()->BackendMinimumVersion(8, 5)) + { + wxString clause = triggers->GetVal(wxT("whenclause")); + trigger->iSetWhen(clause.SubString(1, clause.Length() - 2)); + } + + if (browser) + { + browser->AppendObject(collection, trigger); + triggers->MoveNext(); + } + else + break; + } + + delete triggers; + } + return trigger; +} + + +///////////////////////////// + + +pgTriggerCollection::pgTriggerCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTriggerCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on triggers"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing triggers"); + break; + case OBJECTSLISTREPORT: + message = _("Triggers list report"); + break; + } + + return message; +} + + +///////////////////////////// + +#include "images/trigger.pngc" +#include "images/triggerbad.pngc" +#include "images/triggers.pngc" + +pgTriggerFactory::pgTriggerFactory() + : pgSchemaObjFactory(__("Trigger"), __("New Trigger..."), __("Create a new Trigger."), trigger_png_img) +{ + metaType = PGM_TRIGGER; + closedId = addIcon(triggerbad_png_img); +} + + +pgCollection *pgTriggerFactory::CreateCollection(pgObject *obj) +{ + return new pgTriggerCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTriggerFactory triggerFactory; +static pgaCollectionFactory cf(&triggerFactory, __("Triggers"), triggers_png_img); + +enabledisableTriggerFactory::enabledisableTriggerFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Trigger enabled?"), _("Enable or disable selected trigger."), wxITEM_CHECK); +} + + +wxWindow *enabledisableTriggerFactory::StartDialog(frmMain *form, pgObject *obj) +{ + ((pgTrigger *)obj)->SetEnabled(form->GetBrowser(), !((pgTrigger *)obj)->GetEnabled()); + ((pgTrigger *)obj)->SetDirty(); + + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + { + form->GetBrowser()->DeleteChildren(item); + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + form->GetSqlPane()->SetReadOnly(false); + form->GetSqlPane()->SetText(((pgTrigger *)obj)->GetSql(form->GetBrowser())); + form->GetSqlPane()->SetReadOnly(true); + } + form->GetMenuFactories()->CheckMenu(obj, form->GetMenuBar(), (ctlMenuToolbar *)form->GetToolBar()); + + return 0; +} + + +bool enabledisableTriggerFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(triggerFactory) && obj->CanEdit() + && ((pgTrigger *)obj)->GetConnection()->BackendMinimumVersion(8, 1) + && ((pgTrigger *)obj)->GetParentIsTable(); +} + +bool enabledisableTriggerFactory::CheckChecked(pgObject *obj) +{ + return obj && obj->IsCreatedBy(triggerFactory) && ((pgTrigger *)obj)->GetEnabled(); +} diff --git a/schema/pgType.cpp b/schema/pgType.cpp new file mode 100644 index 0000000..510782f --- /dev/null +++ b/schema/pgType.cpp @@ -0,0 +1,572 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgType.cpp - Type class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgType.h" +#include "schema/pgDatatype.h" + + +pgType::pgType(pgSchema *newSchema, const wxString &newName) + : pgSchemaObject(newSchema, typeFactory, newName) +{ +} + +pgType::~pgType() +{ +} + +wxString pgType::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on type"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing type"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop type \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop type \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop type cascaded?"); + break; + case DROPTITLE: + message = _("Drop type?"); + break; + case PROPERTIESREPORT: + message = _("Type properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Type properties"); + break; + case DDLREPORT: + message = _("Type DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Type DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Type dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Type dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Type dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Type dependents"); + break; + } + + return message; +} + + +bool pgType::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP TYPE ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + +wxString pgType::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Type: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP TYPE ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE TYPE ") + GetQuotedFullIdentifier(); + if (GetTypeClass() == TYPE_COMPOSITE) + { + sql += wxT(" AS\n ("); + sql += GetQuotedTypesList(); + } + else if (GetTypeClass() == TYPE_ENUM) + { + sql += wxT(" AS ENUM\n ("); + sql += GetQuotedLabelList(); + } + else if (GetTypeClass() == TYPE_RANGE) + { + sql += wxT(" AS RANGE\n (") + wxT("SUBTYPE=") + rngsubtypestr; + if (!rngsubopcstr.IsEmpty()) + sql += wxT(",\n SUBTYPE_OPCLASS=") + rngsubopcstr; + if (!rngcollationstr.IsEmpty()) + sql += wxT(",\n COLLATION=") + rngcollationstr; + if (!rngcanonical.IsEmpty()) + sql += wxT(",\n CANONICAL=") + rngcanonical; + if (!rngsubdiff.IsEmpty()) + sql += wxT(",\n SUBTYPE_DIFF=") + rngsubdiff; + } + else + { + sql += wxT("\n (INPUT=") + qtIdent(GetInputFunction()) + + wxT(",\n OUTPUT=") + qtIdent(GetOutputFunction()); + if (GetConnection()->BackendMinimumVersion(7, 4)) + { + if (!GetReceiveFunction().IsEmpty()) + { + sql += wxT(",\n RECEIVE=") + GetReceiveFunction(); + } + if (!GetSendFunction().IsEmpty()) + { + sql += wxT(",\n SEND=") + GetSendFunction(); + } + } + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + if (!GetTypmodinFunction().IsEmpty()) + sql += wxT(",\n TYPMOD_IN=") + GetTypmodinFunction(); + if (!GetTypmodoutFunction().IsEmpty()) + sql += wxT(",\n TYPMOD_OUT=") + GetTypmodoutFunction(); + if (GetAnalyzeFunction() != wxEmptyString) + sql += wxT(",\n ANALYZE=") + GetAnalyzeFunction(); + } + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + sql += wxT(",\n CATEGORY=") + qtDbString(GetCategory()); + if (GetPrefered()) + sql += wxT(",\n PREFERRED=true"); + } + if (GetPassedByValue()) + sql += wxT(",\n PASSEDBYVALUE"); + AppendIfFilled(sql, wxT(", DEFAULT="), qtDbString(GetDefault())); + if (!GetElement().IsNull()) + { + sql += wxT(",\n ELEMENT=") + GetElement() + + wxT(", DELIMITER='") + GetDelimiter() + wxT("'"); + } + sql += wxT(",\n INTERNALLENGTH=") + NumToStr(GetInternalLength()) + + wxT(", ALIGNMENT=" + GetAlignment() + + wxT(", STORAGE=") + GetStorage()); + if (GetConnection()->BackendMinimumVersion(9, 1) && GetCollatable()) + { + sql += wxT(",\n COLLATABLE=true"); + } + if (GetConnection()->BackendMinimumVersion(9, 1) && GetCollatable()) + { + sql += wxT(",\n COLLATABLE=true"); + } + } + sql += wxT(");\n") + + GetOwnerSql(8, 0) + + GetCommentSql(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + return sql; +} + + + +void pgType::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + wxString query; + wxString collation; + + if (!expandedKids) + { + expandedKids = true; + if (GetTypeClass() == TYPE_COMPOSITE) + { + query = wxT("SELECT attname, format_type(t.oid,NULL) AS typname, attndims, atttypmod, nsp.nspname,\n") + wxT(" (SELECT COUNT(1) from pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(",\n collname, nspc.nspname as collnspname"); + query += wxT("\n FROM pg_attribute att\n") + wxT(" JOIN pg_type t ON t.oid=atttypid\n") + wxT(" JOIN pg_namespace nsp ON t.typnamespace=nsp.oid\n") + wxT(" LEFT OUTER JOIN pg_type b ON t.typelem=b.oid\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(" LEFT OUTER JOIN pg_collation c ON att.attcollation=c.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace nspc ON c.collnamespace=nspc.oid\n"); + query += wxT(" WHERE att.attrelid=") + NumToStr(relOid) + wxT("\n") + wxT(" ORDER by attnum"); + pgSet *set = ExecuteSet(query); + if (set) + { + int anzvar = 0; + while (!set->Eof()) + { + if (anzvar++) + { + typesList += wxT(", "); + quotedTypesList += wxT(",\n "); + } + typesList += set->GetVal(wxT("attname")) + wxT(" "); + typesArray.Add(set->GetVal(wxT("attname"))); + quotedTypesList += qtIdent(set->GetVal(wxT("attname"))) + wxT(" "); + + pgDatatype dt(set->GetVal(wxT("nspname")), set->GetVal(wxT("typname")), + set->GetBool(wxT("isdup")), set->GetLong(wxT("attndims")) > 0, set->GetLong(wxT("atttypmod"))); + + typesList += dt.GetSchemaPrefix(GetDatabase()) + dt.FullName(); + typesArray.Add(dt.GetSchemaPrefix(GetDatabase()) + dt.FullName()); + quotedTypesList += dt.GetQuotedSchemaPrefix(GetDatabase()) + dt.QuotedFullName(); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + { + if (set->GetVal(wxT("collname")).IsEmpty() || (set->GetVal(wxT("collname")) == wxT("default") && set->GetVal(wxT("collnspname")) == wxT("pg_catalog"))) + collation = wxEmptyString; + else + { + collation = qtIdent(set->GetVal(wxT("collnspname"))) + wxT(".") + qtIdent(set->GetVal(wxT("collname"))); + quotedTypesList += wxT(" COLLATE ") + collation; + } + collationsArray.Add(collation); + } + typesArray.Add(collation); + + set->MoveNext(); + } + delete set; + } + } + else if (GetTypeClass() == TYPE_ENUM) + { + query = wxT("SELECT enumlabel\n") + wxT(" FROM pg_enum\n") + wxT(" WHERE enumtypid=") + GetOidStr() + wxT("\n"); + if (GetConnection()->BackendMinimumVersion(9, 1)) + query += wxT(" ORDER by enumsortorder"); + else + query += wxT(" ORDER by oid"); + pgSet *set = ExecuteSet(query); + if (set) + { + int anzvar = 0; + while (!set->Eof()) + { + if (anzvar++) + { + labelList += wxT(", "); + quotedLabelList += wxT(",\n "); + } + labelList += set->GetVal(wxT("enumlabel")); + labelArray.Add(set->GetVal(wxT("enumlabel"))); + quotedLabelList += GetDatabase()->connection()->qtDbString(set->GetVal(wxT("enumlabel"))); + + set->MoveNext(); + } + delete set; + } + } + else if (GetTypeClass() == TYPE_RANGE) + { + query = wxT("SELECT rngsubtype, st.typname, ") + wxT("rngcollation, col.collname, ") + wxT("rngsubopc, opc.opcname, ") + wxT("rngcanonical, rngsubdiff\n") + wxT("FROM pg_range\n") + wxT("LEFT JOIN pg_type st ON st.oid=rngsubtype\n") + wxT("LEFT JOIN pg_collation col ON col.oid=rngcollation\n") + wxT("LEFT JOIN pg_opclass opc ON opc.oid=rngsubopc\n") + wxT("WHERE rngtypid=") + GetOidStr(); + pgSet *set = ExecuteSet(query); + if (set) + { + iSetSubtypeFunction(set->GetLong(wxT("rngsubtype"))); + iSetSubtypeFunctionStr(set->GetVal(wxT("typname"))); + iSetCollationFunction(set->GetLong(wxT("rngcollation"))); + iSetCollationFunctionStr(set->GetVal(wxT("collname"))); + iSetSubtypeOpClassFunction(set->GetLong(wxT("rngsubopc"))); + iSetSubtypeOpClassFunctionStr(set->GetVal(wxT("opcname"))); + if (set->GetVal(wxT("rngcanonical")) != wxT("-")) + iSetCanonical(set->GetVal(wxT("rngcanonical"))); + if (set->GetVal(wxT("rngsubdiff")) != wxT("-")) + iSetSubtypeDiff(set->GetVal(wxT("rngsubdiff"))); + } + delete set; + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + if (GetConnection()->BackendMinimumVersion(9, 2)) + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Alias"), GetAlias()); + if (GetTypeClass() == TYPE_COMPOSITE) + { + properties->AppendItem(_("Members"), GetTypesList()); + } + if (GetTypeClass() == TYPE_ENUM) + { + properties->AppendItem(_("Labels"), GetLabelList()); + } + else if (GetTypeClass() == TYPE_RANGE) + { + properties->AppendItem(_("Subtype"), GetSubtypeFunctionStr()); + properties->AppendItem(_("Collation"), GetCollationFunctionStr()); + properties->AppendItem(_("Subtype OpClass"), GetSubtypeOpClassFunctionStr()); + properties->AppendItem(_("Canonical"), GetCanonical()); + properties->AppendItem(_("Subtype diff"), GetSubtypeDiff()); + } + else + { + properties->AppendItem(_("Alignment"), GetAlignment()); + properties->AppendItem(_("Internal length"), GetInternalLength()); + properties->AppendItem(_("Default"), GetDefault()); + properties->AppendItem(_("Passed by Value?"), BoolToYesNo(GetPassedByValue())); + if (!GetElement().IsEmpty()) + { + properties->AppendItem(_("Element"), GetElement()); + properties->AppendItem(_("Delimiter"), GetDelimiter()); + } + properties->AppendItem(_("Input function"), GetInputFunction()); + properties->AppendItem(_("Output function"), GetOutputFunction()); + if (GetConnection()->BackendMinimumVersion(7, 4)) + { + properties->AppendItem(_("Receive function"), GetReceiveFunction()); + properties->AppendItem(_("Send function"), GetSendFunction()); + properties->AppendItem(_("Analyze function"), GetAnalyzeFunction()); + } + if (GetConnection()->BackendMinimumVersion(8, 4)) + { + properties->AppendItem(_("Category"), GetCategory()); + properties->AppendItem(_("Prefered?"), BoolToYesNo(GetPrefered())); + } + if (GetConnection()->BackendMinimumVersion(8, 3)) + { + if (GetTypmodinFunction().Length() > 0) + properties->AppendItem(_("Typmod in function"), GetTypmodinFunction()); + if (GetTypmodoutFunction().Length() > 0) + properties->AppendItem(_("Typmod out function"), GetTypmodoutFunction()); + } + properties->AppendItem(_("Storage"), GetStorage()); + if (GetConnection()->BackendMinimumVersion(9, 1)) + properties->AppendItem(_("Collatable?"), BoolToYesNo(GetCollatable())); + } + properties->AppendYesNoItem(_("System type?"), GetSystemObject()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + } +} + + + +pgObject *pgType::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *type = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + type = typeFactory.CreateObjects(coll, 0, wxT("\n AND t.oid=") + GetOidStr()); + + return type; +} + + +/////////////////////////////////////////////////// + + +pgTypeCollection::pgTypeCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgTypeCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on types"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing types"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for types"); + break; + case OBJECTSLISTREPORT: + message = _("Types list report"); + break; + } + + return message; +} + + +///////////////////////////////////////////////////////// + + +pgObject *pgTypeFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgType *type = 0; + wxString systemRestriction; + if (!settings->GetShowSystemObjects()) + systemRestriction = wxT(" AND ct.oid IS NULL\n"); + + wxString sql = wxT("SELECT t.oid, t.*, format_type(t.oid, null) AS alias,\n") + wxT("pg_get_userbyid(t.typowner) as typeowner, e.typname as element,\n") + wxT("description, ct.oid AS taboid"); + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=t.oid) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=t.oid) AS providers"); + } + sql += wxT("\n FROM pg_type t\n") + wxT(" LEFT OUTER JOIN pg_type e ON e.oid=t.typelem\n") + wxT(" LEFT OUTER JOIN pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)\n"); + + if (collection->GetDatabase()->BackendMinimumVersion(8, 1)) + sql += wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\\\_%' AND t.typnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + else + sql += wxT(" WHERE t.typtype != 'd' AND t.typname NOT LIKE '\\\\_%' AND t.typnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n"); + + sql += restriction + systemRestriction + + wxT(" ORDER BY t.typname"); + + pgSet *types = collection->GetDatabase()->ExecuteSet(sql); + + if (types) + { + while (!types->Eof()) + { + type = new pgType(collection->GetSchema(), types->GetVal(wxT("typname"))); + + type->iSetOid(types->GetOid(wxT("oid"))); + type->iSetOwner(types->GetVal(wxT("typeowner"))); + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + type->iSetAcl(types->GetVal(wxT("typacl"))); + type->iSetAlias(types->GetVal(wxT("alias"))); + type->iSetComment(types->GetVal(wxT("description"))); + type->iSetPassedByValue(types->GetBool(wxT("typbyval"))); + + if (types->GetVal(wxT("typtype")) == wxT("c")) + type->iSetTypeClass(TYPE_COMPOSITE); + else if (types->GetVal(wxT("typtype")) == wxT("e")) + type->iSetTypeClass(TYPE_ENUM); + else if (types->GetVal(wxT("typtype")) == wxT("r")) + type->iSetTypeClass(TYPE_RANGE); + else + type->iSetTypeClass(TYPE_EXTERNAL); + + type->iSetRelOid(types->GetOid(wxT("typrelid"))); + type->iSetIsRecordType(types->GetOid(wxT("taboid")) != 0); + type->iSetInternalLength(types->GetLong(wxT("typlen"))); + type->iSetDelimiter(types->GetVal(wxT("typdelim"))); + type->iSetElement(types->GetVal(wxT("element"))); + type->iSetInputFunction(types->GetVal(wxT("typinput"))); + type->iSetOutputFunction(types->GetVal(wxT("typoutput"))); + if (collection->GetConnection()->BackendMinimumVersion(7, 4)) + { + type->iSetReceiveFunction(types->GetVal(wxT("typreceive"))); + type->iSetSendFunction(types->GetVal(wxT("typsend"))); + type->iSetAnalyzeFunction(types->GetVal(wxT("typanalyze"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 4)) + { + type->iSetCategory(types->GetVal(wxT("typcategory"))); + type->iSetPrefered(types->GetBool(wxT("typispreferred"))); + } + if (collection->GetConnection()->BackendMinimumVersion(8, 3)) + { + if (types->GetVal(wxT("typmodin")) != wxT("-")) + type->iSetTypmodinFunction(types->GetVal(wxT("typmodin"))); + if (types->GetVal(wxT("typmodout")) != wxT("-")) + type->iSetTypmodoutFunction(types->GetVal(wxT("typmodout"))); + } + wxString align = types->GetVal(wxT("typalign")); + type->iSetAlignment( + align == wxT("c") ? wxT("char") : + align == wxT("s") ? wxT("int2") : + align == wxT("i") ? wxT("int4") : + align == wxT("d") ? wxT("double") : wxT("unknown")); + type->iSetDefault(types->GetVal(wxT("typdefault"))); + wxString storage = types->GetVal(wxT("typstorage")); + type->iSetStorage( + storage == wxT("p") ? wxT("PLAIN") : + storage == wxT("e") ? wxT("EXTERNAL") : + storage == wxT("m") ? wxT("MAIN") : + storage == wxT("x") ? wxT("EXTENDED") : wxT("unknown")); + if (collection->GetConnection()->BackendMinimumVersion(9, 1)) + type->iSetCollatable(types->GetLong(wxT("typcollation")) == 100); + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + type->iSetProviders(types->GetVal(wxT("providers"))); + type->iSetLabels(types->GetVal(wxT("labels"))); + } + + if (browser) + { + browser->AppendObject(collection, type); + types->MoveNext(); + } + else + break; + } + + delete types; + } + return type; +} + + +#include "images/type.pngc" +#include "images/types.pngc" + +pgTypeFactory::pgTypeFactory() + : pgSchemaObjFactory(__("Type"), __("New Type..."), __("Create a new Type."), type_png_img) +{ +} + + +pgCollection *pgTypeFactory::CreateCollection(pgObject *obj) +{ + return new pgTypeCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgTypeFactory typeFactory; +static pgaCollectionFactory cf(&typeFactory, __("Types"), types_png_img); diff --git a/schema/pgUser.cpp b/schema/pgUser.cpp new file mode 100644 index 0000000..4ca8f02 --- /dev/null +++ b/schema/pgUser.cpp @@ -0,0 +1,387 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUser.cpp - PostgreSQL User (only used on pre-8.1 versions, pgRole +// is used on newer versions). +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgUser.h" +#include "frm/frmMain.h" +#include "utils/pgDefs.h" +#include "schema/pgDatabase.h" +#include "schema/pgTablespace.h" + +pgUser::pgUser(const wxString &newName) + : pgServerObject(userFactory, newName) +{ +} + +wxString pgUser::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on user"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing user"); + message += wxT(" ") + GetName(); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for user"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop user cascaded?"); + break; + case DROPTITLE: + message = _("Drop user?"); + break; + case PROPERTIESREPORT: + message = _("User properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("User properties"); + break; + case DDLREPORT: + message = _("User DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("User DDL"); + break; + case DEPENDENCIESREPORT: + message = _("User dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("User dependencies"); + break; + case DEPENDENTSREPORT: + message = _("User dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("User dependents"); + break; + } + + return message; +} + + +bool pgUser::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (GetUpdateCatalog()) + { + wxMessageDialog dlg(frame, + _("Deleting a superuser might result in unwanted behaviour (e.g. when restoring the database).\nAre you sure?"), + _("Confirm superuser deletion"), + wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + if (dlg.ShowModal() != wxID_YES) + return false; + } + return server->ExecuteVoid(wxT("DROP USER ") + GetQuotedFullIdentifier() + wxT(";")); +} + + +wxString pgUser::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- User: ") + GetName() + wxT("\n\n") + + wxT("-- DROP USER ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE USER ") + GetQuotedIdentifier() + + wxT("\n WITH SYSID ") + NumToStr(userId); + if (GetPassword() != wxT("********")) + AppendIfFilled(sql, wxT("\n ENCRYPTED PASSWORD "), qtDbString(GetPassword())); + sql += wxT("\n "); + if (GetCreateDatabase()) sql += wxT(" CREATEDB"); + else sql += wxT(" NOCREATEDB"); + if (GetUpdateCatalog()) sql += wxT(" CREATEUSER"); + else sql += wxT(" NOCREATEUSER"); + if (GetAccountExpires().IsValid()) + AppendIfFilled(sql, wxT(" VALID UNTIL "), qtDbString(DateToAnsiStr(GetAccountExpires()))); + sql += wxT(";\n"); + + size_t index; + for (index = 0 ; index < configList.GetCount() ; index++) + { + if (configList.Item(index).BeforeFirst('=') != wxT("search_path") && + configList.Item(index).BeforeFirst('=') != wxT("temp_tablespaces")) + sql += wxT("ALTER USER ") + GetQuotedIdentifier() + + wxT(" SET ") + configList.Item(index).BeforeFirst('=') + wxT("='") + configList.Item(index).AfterFirst('=') + wxT("';\n"); + else + sql += wxT("ALTER USER ") + GetQuotedIdentifier() + + wxT(" SET ") + configList.Item(index).BeforeFirst('=') + wxT("=") + configList.Item(index).AfterFirst('=') + wxT(";\n"); + } + for (index = 0 ; index < groupsIn.GetCount() ; index++) + sql += wxT("ALTER GROUP ") + qtIdent(groupsIn.Item(index)) + + wxT(" ADD USER ") + GetQuotedIdentifier() + wxT(";\n"); + + } + return sql; +} + + + +void pgUser::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &where) +{ + form->StartMsg(_(" Retrieving user owned objects")); + + referencedBy->ClearAll(); + referencedBy->AddColumn(_("Type"), 60); + referencedBy->AddColumn(_("Database"), 80); + referencedBy->AddColumn(_("Name"), 300); + + wxString uid = NumToStr(GetUserId()); + wxString sysoid = NumToStr(GetConnection()->GetLastSystemOID()); + + wxArrayString dblist; + + pgSet *set; + if (GetConnection()->BackendMinimumVersion(7, 5)) + set = GetConnection()->ExecuteSet( + wxT("SELECT 'd' as type, datname, datallowconn, datdba\n") + wxT(" FROM pg_database db\n") + wxT("UNION\n") + wxT("SELECT 'M', spcname, null, null\n") + wxT(" FROM pg_tablespace where spcowner=") + uid + wxT("\n") + wxT(" ORDER BY 1, 2")); + else + set = GetConnection()->ExecuteSet( + wxT("SELECT 'd' as type, datname, datallowconn, datdba\n") + wxT(" FROM pg_database db")); + + if (set) + { + while (!set->Eof()) + { + wxString name = set->GetVal(wxT("datname")); + if (set->GetVal(wxT("type")) == wxT("d")) + { + if (set->GetBool(wxT("datallowconn"))) + dblist.Add(name); + if (GetUserId() == set->GetLong(wxT("datdba"))) + referencedBy->AppendItem(databaseFactory.GetIconId(), _("Database"), name); + } + else + referencedBy->AppendItem(tablespaceFactory.GetIconId(), _("Tablespace"), wxEmptyString, name); + + set->MoveNext(); + } + delete set; + } + + FillOwned(form->GetBrowser(), referencedBy, dblist, + wxT("SELECT cl.relkind, COALESCE(cin.nspname, cln.nspname) as nspname, COALESCE(ci.relname, cl.relname) as relname, cl.relname as indname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace cln ON cl.relnamespace=cln.oid\n") + wxT(" LEFT OUTER JOIN pg_index ind ON ind.indexrelid=cl.oid\n") + wxT(" LEFT OUTER JOIN pg_class ci ON ind.indrelid=ci.oid\n") + wxT(" LEFT OUTER JOIN pg_namespace cin ON ci.relnamespace=cin.oid\n") + wxT(" WHERE cl.relowner = ") + uid + wxT(" AND cl.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'n', null, nspname, null\n") + wxT(" FROM pg_namespace nsp WHERE nspowner = ") + uid + wxT(" AND nsp.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN typtype='d' THEN 'd' ELSE 'y' END, null, typname, null\n") + wxT(" FROM pg_type ty WHERE typowner = ") + uid + wxT(" AND ty.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'C', null, conname, null\n") + wxT(" FROM pg_conversion co WHERE conowner = ") + uid + wxT(" AND co.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT CASE WHEN prorettype=") + NumToStr(PGOID_TYPE_TRIGGER) + wxT(" THEN 'T' ELSE 'p' END, null, proname, null\n") + wxT(" FROM pg_proc pr WHERE proowner = ") + uid + wxT(" AND pr.oid > ") + sysoid + wxT("\n") + wxT("UNION ALL\n") + wxT("SELECT 'o', null, oprname || '('::text || ") + wxT("COALESCE(tl.typname, ''::text) || ") + wxT("CASE WHEN tl.oid IS NOT NULL AND tr.oid IS NOT NULL THEN ','::text END || ") + wxT("COALESCE(tr.typname, ''::text) || ')'::text, null\n") + wxT(" FROM pg_operator op\n") + wxT(" LEFT JOIN pg_type tl ON tl.oid=op.oprleft\n") + wxT(" LEFT JOIN pg_type tr ON tr.oid=op.oprright\n") + wxT(" WHERE oprowner = ") + uid + wxT(" AND op.oid > ") + sysoid + wxT("\n") + wxT(" ORDER BY 1,2,3")); + + form->EndMsg(set != 0); +} + + +void pgUser::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + pgSet *set = GetServer()->ExecuteSet(wxT("SELECT groname, grolist FROM pg_group ORDER BY groname")); + if (set) + { + while (!set->Eof()) + { + wxString groupName = set->GetVal(wxT("groname")); + wxString str = set->GetVal(wxT("grolist")); + if (!str.IsNull()) + { + wxStringTokenizer ids(str.Mid(1, str.Length() - 2), wxT(",")); + while (ids.HasMoreTokens()) + { + if (StrToLong(ids.GetNextToken()) == GetUserId()) + { + groupsIn.Add(groupName); + break; + } + } + } + set->MoveNext(); + } + delete set; + } + } + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("User ID"), GetUserId()); + properties->AppendItem(_("Account expires"), DateToAnsiStr(GetAccountExpires())); + properties->AppendItem(_("Superuser?"), BoolToYesNo(GetSuperuser())); + properties->AppendItem(_("Create databases?"), BoolToYesNo(GetCreateDatabase())); + properties->AppendItem(_("Update catalogs?"), BoolToYesNo(GetUpdateCatalog())); + + wxString groupList; + + size_t index; + for (index = 0 ; index < groupsIn.GetCount() ; index++) + { + if (!groupList.IsEmpty()) + groupList += wxT(", "); + groupList += groupsIn.Item(index); + } + properties->AppendItem(_("Member of"), groupList); + + for (index = 0; index < configList.GetCount() ; index++) + { + wxString item = configList.Item(index); + properties->AppendItem(item.BeforeFirst('='), item.AfterFirst('=')); + } + } +} + + + +pgObject *pgUser::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *user = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + user = userFactory.CreateObjects(coll, 0, wxT("\n WHERE usesysid=") + NumToStr(GetUserId())); + + return user; +} + +///////////////////////////// + +wxString pgUserCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on users"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing users"); + break; + case OBJECTSLISTREPORT: + message = _("Users list report"); + break; + } + + return message; +} + +///////////////////////////// + +pgObject *pgUserFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgUser *user = 0; + + wxString tabname; + + if (collection->GetServer()->HasPrivilege(wxT("table"), wxT("pg_shadow"), wxT("SELECT"))) + tabname = wxT("pg_shadow"); + else + tabname = wxT("pg_user"); + + pgSet *users = collection->GetServer()->ExecuteSet(wxT( + "SELECT * FROM ") + tabname + restriction + wxT(" ORDER BY usename")); + + if (users) + { + while (!users->Eof()) + { + + user = new pgUser(users->GetVal(wxT("usename"))); + user->iSetServer(collection->GetServer()); + user->iSetUserId(users->GetLong(wxT("usesysid"))); + user->iSetCreateDatabase(users->GetBool(wxT("usecreatedb"))); + user->iSetSuperuser(users->GetBool(wxT("usesuper"))); + user->iSetUpdateCatalog(users->GetBool(wxT("usecatupd"))); + user->iSetAccountExpires(users->GetDateTime(wxT("valuntil"))); + user->iSetPassword(users->GetVal(wxT("passwd"))); + + wxString cfg = users->GetVal(wxT("useconfig")); + if (!cfg.IsEmpty()) + FillArray(user->GetConfigList(), cfg.Mid(1, cfg.Length() - 2)); + + if (browser) + { + browser->AppendObject(collection, user); + users->MoveNext(); + } + else + break; + } + + delete users; + } + return user; +} + + +#include "images/user.pngc" +#include "images/users.pngc" + +pgUserFactory::pgUserFactory() + : pgServerObjFactory(__("User"), __("New User..."), __("Create a new User."), user_png_img) +{ +} + + +pgUserFactory userFactory; +static pgaCollectionFactory cf(&userFactory, __("Users"), users_png_img); diff --git a/schema/pgUserMapping.cpp b/schema/pgUserMapping.cpp new file mode 100644 index 0000000..6e21015 --- /dev/null +++ b/schema/pgUserMapping.cpp @@ -0,0 +1,269 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgUserMapping.cpp - User Mapping class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgForeignServer.h" +#include "schema/pgUserMapping.h" +#include "schema/pgDatatype.h" + + +pgUserMapping::pgUserMapping(pgForeignServer *newForeignServer, const wxString &newName) + : pgForeignServerObject(newForeignServer, userMappingFactory, newName) +{ +} + + +wxString pgUserMapping::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on user mapping"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing user mapping"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user mapping \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop user mapping \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop user mapping cascaded?"); + break; + case DROPTITLE: + message = _("Drop user mapping?"); + break; + case PROPERTIESREPORT: + message = _("User mapping properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("User mapping properties"); + break; + case DDLREPORT: + message = _("User mapping DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("User mapping DDL"); + break; + case STATISTICSREPORT: + message = _("User mapping statistics report"); + message += wxT(" - ") + GetName(); + break; + case OBJSTATISTICS: + message = _("User mapping statistics"); + break; + case DEPENDENCIESREPORT: + message = _("User mapping dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("User mapping dependencies"); + break; + case DEPENDENTSREPORT: + message = _("User mapping dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("User mapping dependents"); + break; + } + + return message; +} + + +bool pgUserMapping::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + wxString sql = wxT("DROP USER MAPPING FOR ") + GetUsr() + wxT(" SERVER ") + qtIdent(GetForeignServer()->GetName()); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgUserMapping::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Server: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP USER MAPPING FOR ") + GetUsr() + wxT(" SERVER ") + qtIdent(GetForeignServer()->GetName()) + wxT(";") + + wxT("\n\nCREATE USER MAPPING ") + + wxT("\n FOR ") + qtIdent(GetUsr()) + + wxT("\n SERVER ") + qtIdent(GetForeignServer()->GetName()); + + if (!GetOptions().IsEmpty()) + sql += wxT("\n OPTIONS (") + GetCreateOptions() + wxT(")"); + + sql += wxT(";\n"); + } + return sql; +} + + +void pgUserMapping::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("User"), GetUsr()); + properties->AppendItem(_("Options"), GetOptions()); + } +} + + + +pgObject *pgUserMapping::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *um = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + um = userMappingFactory.CreateObjects(coll, 0, wxT(" AND u.oid=") + GetOidStr()); + + return um; +} + + +//////////////////////////////////////////////////// + + +pgObject *pgUserMappingFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + wxString sql; + pgUserMapping *um = 0; + + sql = wxT("SELECT u.oid AS um_oid,\n") + wxT("CASE WHEN u.umuser = 0::oid THEN 'public'::name ELSE a.rolname END AS usr_name,\n") + wxT("array_to_string(u.umoptions, ',') AS um_options\n") + wxT("FROM pg_user_mapping u\n") + wxT(" LEFT JOIN pg_authid a ON a.oid = u.umuser\n") + wxT(" WHERE u.umserver = ") + collection->GetOidStr() + + restriction + wxT("\n") + wxT("ORDER BY 2"); + pgSet *usermappings = collection->GetDatabase()->ExecuteSet(sql); + if (usermappings) + { + while (!usermappings->Eof()) + { + um = new pgUserMapping(collection->GetForeignServer(), usermappings->GetVal(wxT("usr_name"))); + um->iSetOid(usermappings->GetOid(wxT("um_oid"))); + um->iSetUsr(usermappings->GetVal(wxT("usr_name"))); + um->iSetOptions(usermappings->GetVal(wxT("um_options"))); + + if (browser) + { + browser->AppendObject(collection, um); + usermappings->MoveNext(); + } + else + break; + } + + delete usermappings; + } + + return um; +} + + +wxString pgUserMapping::GetCreateOptions() +{ + wxString options_create = wxEmptyString; + wxString opt; + wxString val; + + wxStringTokenizer tkz_options(options, wxT(",")); + while (tkz_options.HasMoreTokens()) + { + wxStringTokenizer tkz_option(tkz_options.GetNextToken(), wxT("=")); + opt = tkz_option.GetNextToken(); + val = tkz_option.GetNextToken(); + + if (!options_create.IsEmpty()) + options_create += wxT(","); + + options_create += opt + wxT(" '") + val + wxT("'"); + } + + return options_create; +} + + +pgCollection *pgUserMappingObjFactory::CreateCollection(pgObject *obj) +{ + return new pgUserMappingCollection(GetCollectionFactory(), (pgUserMapping *)obj); +} + + +///////////////////////////// + +pgUserMappingCollection::pgUserMappingCollection(pgaFactory *factory, pgUserMapping *newum) + : pgCollection(factory) +{ + um = newum; + fsrv = um->GetForeignServer(); + fdw = fsrv->GetForeignDataWrapper(); + database = fdw->GetDatabase(); + server = database->GetServer(); + iSetOid(fsrv->GetOid()); +} + + +wxString pgUserMappingCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on user mappings"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing user mappings"); + break; + case OBJECTSLISTREPORT: + message = _("User mappings list report"); + break; + } + + return message; +} + +/////////////////////////////////////////////////// + +#include "images/usermapping.pngc" +#include "images/usermapping-sm.pngc" +#include "images/usermappings.pngc" + +pgUserMappingFactory::pgUserMappingFactory() + : pgForeignServerObjFactory(__("User Mapping"), __("New User Mapping..."), + __("Create a new User Mapping."), usermapping_png_img, usermapping_sm_png_img) +{ +} + + +pgUserMappingFactory userMappingFactory; +static pgaCollectionFactory cf(&userMappingFactory, __("User Mappings"), usermappings_png_img); diff --git a/schema/pgView.cpp b/schema/pgView.cpp new file mode 100644 index 0000000..b307519 --- /dev/null +++ b/schema/pgView.cpp @@ -0,0 +1,967 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgView.cpp - View class +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgColumn.h" +#include "schema/pgIndexConstraint.h" +#include "schema/pgView.h" +#include "frm/frmMain.h" +#include "frm/frmHint.h" +#include "schema/pgTrigger.h" + + +pgView::pgView(pgSchema *newSchema, const wxString &newName) + : pgRuleObject(newSchema, viewFactory, newName) +{ + hasInsertRule = false; + hasUpdateRule = false; + hasDeleteRule = false; +} + +pgView::~pgView() +{ +} + +wxString pgView::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on view"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing view"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop view \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop view \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop view cascaded?"); + break; + case DROPTITLE: + message = _("Drop view?"); + break; + case PROPERTIESREPORT: + message = _("View properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("View properties"); + break; + case DDLREPORT: + message = _("View DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("View DDL"); + break; + case DEPENDENCIESREPORT: + message = _("View dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("View dependencies"); + break; + case DEPENDENTSREPORT: + message = _("View dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("View dependents"); + break; + } + + return message; +} + + +bool pgView::IsUpToDate() +{ + wxString sql = wxT("SELECT xmin FROM pg_class WHERE oid = ") + this->GetOidStr(); + if (!this->GetDatabase()->GetConnection() || this->GetDatabase()->ExecuteScalar(sql) != NumToStr(GetXid())) + return false; + else + return true; +} + +wxMenu *pgView::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + if (schema->GetCreatePrivilege()) + { + ruleFactory.AppendMenu(menu); + triggerFactory.AppendMenu(menu); + if (GetMaterializedView()) + { + indexFactory.AppendMenu(menu); + } + } + return menu; +} + + +bool pgView::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + if (GetMaterializedView()) + sql = wxT("DROP MATERIALIZED VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + else + sql = wxT("DROP VIEW ") + this->GetSchema()->GetQuotedIdentifier() + wxT(".") + this->GetQuotedIdentifier(); + + if (cascaded) + sql += wxT(" CASCADE"); + return GetDatabase()->ExecuteVoid(sql); +} + + +wxString pgView::GetSql(ctlTree *browser) +{ + wxString withoptions; + + if (sql.IsNull()) + { + bool IsMatViewFlag = false; + if (!GetMaterializedView()) + { + sql = wxT("-- View: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP VIEW ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE OR REPLACE VIEW ") + GetQuotedFullIdentifier(); + + if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) + withoptions = wxT("security_barrier=") + GetSecurityBarrier(); + if (GetConnection()->BackendMinimumVersion(9, 4) && GetCheckOption().Length() > 0) + { + if (withoptions.Length() > 0) + withoptions += wxT(", "); + withoptions = wxT("check_option=") + GetCheckOption(); + } + if (withoptions.Length() > 0) + sql += wxT(" WITH (") + withoptions + wxT(")"); + } + else + { + sql = wxT("-- Materialized View: ") + GetQuotedFullIdentifier() + wxT("\n\n") + + wxT("-- DROP MATERIALIZED VIEW ") + GetQuotedFullIdentifier() + wxT(";") + + wxT("\n\nCREATE MATERIALIZED VIEW ") + GetQuotedFullIdentifier(); + + IsMatViewFlag = true; + + if (GetConnection()->BackendMinimumVersion(9, 3)) + { + if (GetFillFactor().Length() > 0 || GetAutoVacuumEnabled() == 1 || GetToastAutoVacuumEnabled() == 1) + { + bool tmpFlagTable = false; + bool tmpFlagToastTable = false; + + sql += wxT("\nWITH ("); + if (GetFillFactor().Length() > 0) + sql += wxT("\n FILLFACTOR=") + GetFillFactor(); + else + tmpFlagTable = true; + + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() == 1) + { + if (tmpFlagTable) + sql += wxT("\n autovacuum_enabled=true"); + else + sql += wxT(",\n autovacuum_enabled=true"); + tmpFlagToastTable = true; + } + else if (GetCustomAutoVacuumEnabled() == 0) + { + sql += wxT(",\n autovacuum_enabled=false"); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_threshold=") + GetAutoVacuumVacuumThreshold(); + } + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_scale_factor=") + GetAutoVacuumVacuumScaleFactor(); + } + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_threshold=") + GetAutoVacuumAnalyzeThreshold(); + } + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + { + sql += wxT(",\n autovacuum_analyze_scale_factor=") + GetAutoVacuumAnalyzeScaleFactor(); + } + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_delay=") + GetAutoVacuumVacuumCostDelay(); + } + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n autovacuum_vacuum_cost_limit=") + GetAutoVacuumVacuumCostLimit(); + } + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_min_age=") + GetAutoVacuumFreezeMinAge(); + } + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_max_age=") + GetAutoVacuumFreezeMaxAge(); + } + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n autovacuum_freeze_table_age=") + GetAutoVacuumFreezeTableAge(); + } + } + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() == 1) + { + if (tmpFlagTable && !tmpFlagToastTable) + sql += wxT("\n toast.autovacuum_enabled=true"); + else + sql += wxT(",\n toast.autovacuum_enabled=true"); + } + else if (GetToastAutoVacuumEnabled() == 0) + sql += wxT(",\n toast.autovacuum_enabled=false"); + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_threshold=") + GetToastAutoVacuumVacuumThreshold(); + } + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_scale_factor=") + GetToastAutoVacuumVacuumScaleFactor(); + } + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_delay=") + GetToastAutoVacuumVacuumCostDelay(); + } + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_vacuum_cost_limit=") + GetToastAutoVacuumVacuumCostLimit(); + } + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_min_age=") + GetToastAutoVacuumFreezeMinAge(); + } + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_max_age=") + GetToastAutoVacuumFreezeMaxAge(); + } + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + { + sql += wxT(",\n toast.autovacuum_freeze_table_age=") + GetToastAutoVacuumFreezeTableAge(); + } + } + sql += wxT("\n)"); + } + + if (tablespace != GetDatabase()->GetDefaultTablespace()) + sql += wxT("\nTABLESPACE ") + qtIdent(tablespace); + + wxString isPopulated; + if (GetIsPopulated().Cmp(wxT("t")) == 0) + isPopulated = wxT("WITH DATA;"); + else + isPopulated = wxT("WITH NO DATA;"); + + wxString sqlDefinition; + bool tmpLoopFlag = true; + sqlDefinition = GetFormattedDefinition(); + + // Remove semicolon from the end of the string + while(tmpLoopFlag) + { + int length = sqlDefinition.Len(); + int position = sqlDefinition.Find(';', true); + if ((position != wxNOT_FOUND) && (position = (length - 1))) + sqlDefinition.Remove(position, 1); + else + tmpLoopFlag = false; + } + + sql += wxT(" AS \n") + + sqlDefinition + + wxT("\n") + + isPopulated + + wxT("\n\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + } + } + + if (!IsMatViewFlag) + { + sql += wxT(" AS \n") + + GetFormattedDefinition() + + wxT("\n\n") + + GetOwnerSql(7, 3, wxT("TABLE ") + GetQuotedFullIdentifier()); + } + + if (GetConnection()->BackendMinimumVersion(8, 2)) + sql += GetGrant(wxT("arwdxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); + else + sql += GetGrant(wxT("arwdRxt"), wxT("TABLE ") + GetQuotedFullIdentifier()); + + // "MATERIALIZED" isn't part of the object type name, it's a property, so + // we need to generate the comment SQL manually here, instead of using + // wxString pgObject::GetCommentSql() + + if (!GetComment().IsNull()) + { + if (IsMatViewFlag) + { + sql += wxT("COMMENT ON MATERIALIZED VIEW ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + else + { + sql += wxT("COMMENT ON VIEW ") + GetQuotedFullIdentifier() + + wxT("\n IS ") + qtDbString(GetComment()) + wxT(";\n"); + } + } + + pgCollection *columns = browser->FindCollection(columnFactory, GetId()); + if (columns) + { + wxString defaults, comments; + columns->ShowTreeDetail(browser); + treeObjectIterator colIt(browser, columns); + + pgColumn *column; + while ((column = (pgColumn *)colIt.GetNextObject()) != 0) + { + column->ShowTreeDetail(browser); + if (column->GetColNumber() > 0) + { + if (!column->GetDefault().IsEmpty()) + { + defaults += wxT("ALTER TABLE ") + GetQuotedFullIdentifier() + + wxT(" ALTER COLUMN ") + column->GetQuotedIdentifier() + + wxT(" SET DEFAULT ") + column->GetDefault() + + wxT(";\n"); + } + comments += column->GetCommentSql(); + } + } + if (!defaults.IsEmpty()) + sql += defaults + wxT("\n"); + + if (!comments.IsEmpty()) + sql += comments + wxT("\n"); + + if (GetConnection()->BackendMinimumVersion(9, 1)) + sql += GetSeqLabelsSql(); + } + + if (IsMatViewFlag) + { + AppendStuff(sql, browser, indexFactory); + } + AppendStuff(sql, browser, ruleFactory); + AppendStuff(sql, browser, triggerFactory); + } + return sql; +} + + +wxString pgView::GetCols(ctlTree *browser, size_t indent, wxString &QMs, bool withQM) +{ + wxString sql; + wxString line; + + int colcount = 0; + pgSetIterator set(GetConnection(), + wxT("SELECT attname\n") + wxT(" FROM pg_attribute\n") + wxT(" WHERE attrelid=") + GetOidStr() + wxT(" AND attnum>0\n") + wxT(" ORDER BY attnum")); + + + while (set.RowsLeft()) + { + if (colcount++) + { + line += wxT(", "); + QMs += wxT(", "); + } + if (line.Length() > 60) + { + if (!sql.IsEmpty()) + { + sql += wxT("\n") + wxString(' ', indent); + } + sql += line; + line = wxEmptyString; + QMs += wxT("\n") + wxString(' ', indent); + } + + line += qtIdent(set.GetVal(0)); + if (withQM) + line += wxT("=?"); + QMs += wxT("?"); + } + + if (!line.IsEmpty()) + { + if (!sql.IsEmpty()) + sql += wxT("\n") + wxString(' ', indent); + sql += line; + } + return sql; +} + + +wxString pgView::GetSelectSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("SELECT ") + GetCols(browser, 7, qms, false) + wxT("\n") + wxT(" FROM ") + GetQuotedFullIdentifier() + wxT(";\n"); + return sql; +} + + +wxString pgView::GetInsertSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("INSERT INTO ") + GetQuotedFullIdentifier() + wxT("(\n") + wxT(" ") + GetCols(browser, 12, qms, false) + wxT(")\n") + wxT(" VALUES (") + qms + wxT(");\n"); + return sql; +} + + +wxString pgView::GetUpdateSql(ctlTree *browser) +{ + wxString qms; + wxString sql = + wxT("UPDATE ") + GetQuotedFullIdentifier() + wxT("\n") + wxT(" SET ") + GetCols(browser, 7, qms, true) + wxT("\n") + wxT(" WHERE ;\n"); + return sql; +} + + +void pgView::RefreshMatView(bool concurrently) +{ + wxString sql = wxT("REFRESH MATERIALIZED VIEW "); + if (concurrently) + sql += wxT("CONCURRENTLY "); + sql += GetQuotedFullIdentifier(); + GetDatabase()->ExecuteVoid(sql); +} + + +void pgView::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + browser->RemoveDummyChild(this); + + browser->AppendCollection(this, columnFactory); + + if (GetMaterializedView()) + browser->AppendCollection(this, indexFactory); + + pgCollection *collection = browser->AppendCollection(this, ruleFactory); + collection->iSetOid(GetOid()); + collection->ShowTreeDetail(browser); + treeObjectIterator colIt(browser, collection); + + pgRule *rule; + while (!hasInsertRule && !hasUpdateRule && !hasDeleteRule && (rule = (pgRule *)colIt.GetNextObject()) != 0) + { + if (rule->GetEvent().Find(wxT("INSERT")) >= 0) + hasInsertRule = true; + if (rule->GetEvent().Find(wxT("UPDATE")) >= 0) + hasUpdateRule = true; + if (rule->GetEvent().Find(wxT("DELETE")) >= 0) + hasDeleteRule = true; + } + + if (GetConnection()->BackendMinimumVersion(9, 1)) + browser->AppendCollection(this, triggerFactory); + } + if (properties) + { + CreateListColumns(properties); + wxString def = GetDefinition().Left(250); + def.Replace(wxT("\n"), wxT(" ")); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("OID"), GetOid()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("ACL"), GetAcl()); + properties->AppendItem(_("Definition"), def); + properties->AppendYesNoItem(_("System view?"), GetSystemObject()); + if (GetConnection()->BackendMinimumVersion(9, 2) && GetSecurityBarrier().Length() > 0) + properties->AppendItem(_("Security barrier?"), GetSecurityBarrier()); + + if (GetConnection()->BackendMinimumVersion(9, 3)) + properties->AppendYesNoItem(_("Materialized view?"), GetMaterializedView()); + + /* Custom AutoVacuum Settings */ + if (GetConnection()->BackendMinimumVersion(9, 3) && GetMaterializedView()) + { + if (!GetFillFactor().IsEmpty()) + properties->AppendItem(_("Fill factor"), GetFillFactor()); + + if (GetCustomAutoVacuumEnabled()) + { + if (GetAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Table auto-vacuum enabled?"), GetAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM base threshold"), GetAutoVacuumVacuumThreshold()); + if (!GetAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM scale factor"), GetAutoVacuumVacuumScaleFactor()); + if (!GetAutoVacuumAnalyzeThreshold().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE base threshold"), GetAutoVacuumAnalyzeThreshold()); + if (!GetAutoVacuumAnalyzeScaleFactor().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum ANALYZE scale factor"), GetAutoVacuumAnalyzeScaleFactor()); + if (!GetAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost delay"), GetAutoVacuumVacuumCostDelay()); + if (!GetAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum VACUUM cost limit"), GetAutoVacuumVacuumCostLimit()); + if (!GetAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE minimum age"), GetAutoVacuumFreezeMinAge()); + if (!GetAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE maximum age"), GetAutoVacuumFreezeMaxAge()); + if (!GetAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Table auto-vacuum FREEZE table age"), GetAutoVacuumFreezeTableAge()); + } + + if (GetHasToastTable() && GetToastCustomAutoVacuumEnabled()) + { + if (GetToastAutoVacuumEnabled() != 2) + { + properties->AppendItem(_("Toast auto-vacuum enabled?"), GetToastAutoVacuumEnabled() == 1 ? _("Yes") : _("No")); + } + if (!GetToastAutoVacuumVacuumThreshold().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM base threshold"), GetToastAutoVacuumVacuumThreshold()); + if (!GetToastAutoVacuumVacuumScaleFactor().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM scale factor"), GetToastAutoVacuumVacuumScaleFactor()); + if (!GetToastAutoVacuumVacuumCostDelay().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost delay"), GetToastAutoVacuumVacuumCostDelay()); + if (!GetToastAutoVacuumVacuumCostLimit().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum VACUUM cost limit"), GetToastAutoVacuumVacuumCostLimit()); + if (!GetToastAutoVacuumFreezeMinAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE minimum age"), GetToastAutoVacuumFreezeMinAge()); + if (!GetToastAutoVacuumFreezeMaxAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE maximum age"), GetToastAutoVacuumFreezeMaxAge()); + if (!GetToastAutoVacuumFreezeTableAge().IsEmpty()) + properties->AppendItem(_("Toast auto-vacuum FREEZE table age"), GetToastAutoVacuumFreezeTableAge()); + } + + properties->AppendItem(_("Tablespace"), tablespace); + + if (GetIsPopulated().Cmp(wxT("t")) == 0) + properties->AppendItem(_("With data?"), _("Yes")); + else + properties->AppendItem(_("With data?"), _("No")); + } + + if (GetConnection()->BackendMinimumVersion(9, 4)) + properties->AppendItem(_("Check Option"), GetCheckOption()); + + if (!GetLabels().IsEmpty()) + { + wxArrayString seclabels = GetProviderLabelArray(); + if (seclabels.GetCount() > 0) + { + for (unsigned int index = 0 ; index < seclabels.GetCount() - 1 ; index += 2) + { + properties->AppendItem(seclabels.Item(index), seclabels.Item(index + 1)); + } + } + } + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *pgView::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *view = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + { + // OIDs may change in EDB which allows the returned column set to be changed. + if (GetConnection()->EdbMinimumVersion(8, 0)) + view = viewFactory.CreateObjects(coll, 0, wxT("\n AND c.relname=") + GetConnection()->qtDbString(GetName())); + else + view = viewFactory.CreateObjects(coll, 0, wxT("\n AND c.oid=") + GetOidStr()); + } + + return view; +} + +void pgView::ShowHint(frmMain *form, bool force) +{ + wxArrayString hints; + hints.Add(HINT_OBJECT_EDITING); + frmHint::ShowHint((wxWindow *)form, hints, GetFullIdentifier(), force); +} + +void pgView::AppendStuff(wxString &sql, ctlTree *browser, pgaFactory &factory) +{ + wxString tmp; + + pgCollection *collection = browser->FindCollection(factory, GetId()); + if (collection) + { + tmp += wxT("\n"); + collection->ShowTreeDetail(browser); + + treeObjectIterator idxIt(browser, collection); + pgObject *obj; + while ((obj = idxIt.GetNextObject()) != 0) + { + if (obj->GetName() != wxT("_RETURN")) + { + obj->ShowTreeDetail(browser); + + tmp += obj->GetSql(browser) + wxT("\n"); + } + } + } + + if (!tmp.IsEmpty() && tmp != wxT("\n")) + sql += tmp; +} + +int pgView::GetIconId() +{ + if (GetMaterializedView()) + return viewFactory.GetMaterializedIconId(); + else + return viewFactory.GetIconId(); +} + +/////////////////////////////////////////////////// + + +pgViewCollection::pgViewCollection(pgaFactory *factory, pgSchema *sch) + : pgSchemaObjCollection(factory, sch) +{ +} + + +wxString pgViewCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on views"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing views"); + break; + case GRANTWIZARDTITLE: + message = _("Privileges for views"); + break; + case OBJECTSLISTREPORT: + message = _("Views list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////////// + + +pgObject *pgViewFactory::CreateObjects(pgCollection *collection, ctlTree *browser, const wxString &restriction) +{ + pgView *view = 0; + wxString sql; + + if (collection->GetDatabase()->BackendMinimumVersion(9, 3)) + { + sql = wxT("SELECT c.oid, c.xmin, c.relname,c.reltablespace AS spcoid, c.relkind, c.relispopulated AS ispopulated,spc.spcname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") + wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + } + else + { + sql = wxT("SELECT c.oid, c.xmin, c.relname,c.reltablespace AS spcoid,spc.spcname, pg_get_userbyid(c.relowner) AS viewowner, c.relacl, description, ") + wxT("pg_get_viewdef(c.oid") + collection->GetDatabase()->GetPrettyOption() + wxT(") AS definition"); + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + sql += wxT(",\n(SELECT array_agg(label) FROM pg_seclabels sl1 WHERE sl1.objoid=c.oid AND sl1.objsubid=0) AS labels"); + sql += wxT(",\n(SELECT array_agg(provider) FROM pg_seclabels sl2 WHERE sl2.objoid=c.oid AND sl2.objsubid=0) AS providers"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + sql += wxT(",\nsubstring(array_to_string(c.reloptions, ',') FROM 'security_barrier=([a-z|0-9]*)') AS security_barrier"); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + sql += wxT(", substring(array_to_string(c.reloptions, ',') FROM 'fillfactor=([0-9]*)') AS fillfactor \n"); + + sql += wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS autovacuum_enabled \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(c.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS autovacuum_freeze_table_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_enabled=([a-z|0-9]*)') AS toast_autovacuum_enabled \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_threshold=([0-9]*)') AS toast_autovacuum_vacuum_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_vacuum_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_threshold=([0-9]*)') AS toast_autovacuum_analyze_threshold \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_analyze_scale_factor=([0-9]*[.][0-9]*)') AS toast_autovacuum_analyze_scale_factor \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_delay=([0-9]*)') AS toast_autovacuum_vacuum_cost_delay \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_vacuum_cost_limit=([0-9]*)') AS toast_autovacuum_vacuum_cost_limit \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_min_age=([0-9]*)') AS toast_autovacuum_freeze_min_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_max_age=([0-9]*)') AS toast_autovacuum_freeze_max_age \n") + wxT(", substring(array_to_string(tst.reloptions, ',') FROM 'autovacuum_freeze_table_age=([0-9]*)') AS toast_autovacuum_freeze_table_age \n") + wxT(", c.reloptions AS reloptions, tst.reloptions AS toast_reloptions \n") + wxT(", (CASE WHEN c.reltoastrelid = 0 THEN false ELSE true END) AS hastoasttable\n"); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 4)) + { + sql += wxT(",\nsubstring(array_to_string(c.reloptions, ',') FROM 'check_option=([a-z]*)') AS check_option"); + } + + + + sql += wxT("\n FROM pg_class c\n") + wxT(" LEFT OUTER JOIN pg_tablespace spc on spc.oid=c.reltablespace\n") + wxT(" LEFT OUTER JOIN pg_description des ON (des.objoid=c.oid and des.objsubid=0 AND des.classoid='pg_class'::regclass)\n"); + + // Add the toast table for vacuum parameters. + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + sql += wxT(" LEFT OUTER JOIN pg_class tst ON tst.oid = c.reltoastrelid\n"); + + sql += wxT(" WHERE ((c.relhasrules AND (EXISTS (\n") + wxT(" SELECT r.rulename FROM pg_rewrite r\n") + wxT(" WHERE ((r.ev_class = c.oid)\n") + wxT(" AND (bpchar(r.ev_type) = '1'::bpchar)) ))) OR (c.relkind = 'v'::char))\n") + wxT(" AND c.relnamespace = ") + collection->GetSchema()->GetOidStr() + wxT("\n") + + restriction + + wxT(" ORDER BY relname"); + + pgSet *views = collection->GetDatabase()->ExecuteSet(sql); + + if (views) + { + while (!views->Eof()) + { + view = new pgView(collection->GetSchema(), views->GetVal(wxT("relname"))); + + view->iSetOid(views->GetOid(wxT("oid"))); + view->iSetXid(views->GetOid(wxT("xmin"))); + view->iSetOwner(views->GetVal(wxT("viewowner"))); + view->iSetComment(views->GetVal(wxT("description"))); + view->iSetAcl(views->GetVal(wxT("relacl"))); + view->iSetDefinition(views->GetVal(wxT("definition"))); + view->iSetMaterializedView(false); + if (collection->GetDatabase()->BackendMinimumVersion(9, 4)) + { + view->iSetCheckOption(views->GetVal(wxT("check_option"))); + } + + if (collection->GetDatabase()->BackendMinimumVersion(9, 1)) + { + view->iSetProviders(views->GetVal(wxT("providers"))); + view->iSetLabels(views->GetVal(wxT("labels"))); + } + if (collection->GetConnection()->BackendMinimumVersion(9, 2)) + { + view->iSetSecurityBarrier(views->GetVal(wxT("security_barrier"))); + } + + if (collection->GetConnection()->BackendMinimumVersion(9, 3)) + { + view->iSetFillFactor(views->GetVal(wxT("fillfactor"))); + + if (views->GetOid(wxT("spcoid")) == 0) + view->iSetTablespaceOid(collection->GetDatabase()->GetTablespaceOid()); + else + view->iSetTablespaceOid(views->GetOid(wxT("spcoid"))); + + view->iSetRelOptions(views->GetVal(wxT("reloptions"))); + + view->iSetIsPopulated(views->GetVal(wxT("ispopulated"))); + + if (view->GetCustomAutoVacuumEnabled()) + { + if (views->GetVal(wxT("autovacuum_enabled")).IsEmpty()) + view->iSetAutoVacuumEnabled(2); + else if (views->GetBool(wxT("autovacuum_enabled"))) + view->iSetAutoVacuumEnabled(1); + else + view->iSetAutoVacuumEnabled(0); + view->iSetAutoVacuumVacuumThreshold(views->GetVal(wxT("autovacuum_vacuum_threshold"))); + view->iSetAutoVacuumVacuumScaleFactor(views->GetVal(wxT("autovacuum_vacuum_scale_factor"))); + view->iSetAutoVacuumAnalyzeThreshold(views->GetVal(wxT("autovacuum_analyze_threshold"))); + view->iSetAutoVacuumAnalyzeScaleFactor(views->GetVal(wxT("autovacuum_analyze_scale_factor"))); + view->iSetAutoVacuumVacuumCostDelay(views->GetVal(wxT("autovacuum_vacuum_cost_delay"))); + view->iSetAutoVacuumVacuumCostLimit(views->GetVal(wxT("autovacuum_vacuum_cost_limit"))); + view->iSetAutoVacuumFreezeMinAge(views->GetVal(wxT("autovacuum_freeze_min_age"))); + view->iSetAutoVacuumFreezeMaxAge(views->GetVal(wxT("autovacuum_freeze_max_age"))); + view->iSetAutoVacuumFreezeTableAge(views->GetVal(wxT("autovacuum_freeze_table_age"))); + } + + view->iSetHasToastTable(views->GetBool(wxT("hastoasttable"))); + + if (view->GetHasToastTable()) + { + view->iSetToastRelOptions(views->GetVal(wxT("toast_reloptions"))); + + if (view->GetToastCustomAutoVacuumEnabled()) + { + if (views->GetVal(wxT("toast_autovacuum_enabled")).IsEmpty()) + view->iSetToastAutoVacuumEnabled(2); + else if (views->GetBool(wxT("toast_autovacuum_enabled"))) + view->iSetToastAutoVacuumEnabled(1); + else + view->iSetToastAutoVacuumEnabled(0); + + view->iSetToastAutoVacuumVacuumThreshold(views->GetVal(wxT("toast_autovacuum_vacuum_threshold"))); + view->iSetToastAutoVacuumVacuumScaleFactor(views->GetVal(wxT("toast_autovacuum_vacuum_scale_factor"))); + view->iSetToastAutoVacuumVacuumCostDelay(views->GetVal(wxT("toast_autovacuum_vacuum_cost_delay"))); + view->iSetToastAutoVacuumVacuumCostLimit(views->GetVal(wxT("toast_autovacuum_vacuum_cost_limit"))); + view->iSetToastAutoVacuumFreezeMinAge(views->GetVal(wxT("toast_autovacuum_freeze_min_age"))); + view->iSetToastAutoVacuumFreezeMaxAge(views->GetVal(wxT("toast_autovacuum_freeze_max_age"))); + view->iSetToastAutoVacuumFreezeTableAge(views->GetVal(wxT("toast_autovacuum_freeze_table_age"))); + } + } + + if (views->GetVal(wxT("spcname")) == wxEmptyString) + view->iSetTablespace(collection->GetDatabase()->GetTablespace()); + else + view->iSetTablespace(views->GetVal(wxT("spcname"))); + + if (views->GetVal(wxT("relkind")).Cmp(wxT("m")) == 0) + view->iSetMaterializedView(true); + } + + if (browser) + { + collection->AppendBrowserItem(browser, view); + // If it is materialized view then display the materialized view icon + if (collection->GetConnection()->BackendMinimumVersion(9, 3) && views->GetVal(wxT("relkind")).Cmp(wxT("m")) == 0) + browser->SetItemImage(view->GetId(), viewFactory.GetMaterializedIconId()); + + views->MoveNext(); + } + else + break; + } + + delete views; + } + return view; +} + + +#include "images/view.pngc" +#include "images/view-sm.pngc" +#include "images/views.pngc" +#include "images/mview.pngc" +#include "images/mview-sm.pngc" + +pgViewFactory::pgViewFactory() + : pgSchemaObjFactory(__("View"), __("New View..."), __("Create a new View."), view_png_img, view_sm_png_img) +{ + metaType = PGM_VIEW; + materializedId = addIcon(mview_png_img); + smallMaterializedId = addIcon(mview_sm_png_img); +} + + +pgCollection *pgViewFactory::CreateCollection(pgObject *obj) +{ + return new pgViewCollection(GetCollectionFactory(), (pgSchema *)obj); +} + +pgViewFactory viewFactory; +static pgaCollectionFactory cf(&viewFactory, __("Views"), views_png_img); + +refreshMatViewFactory::refreshMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Refresh data"), _("Refresh data for the selected object.")); +} + + +wxWindow *refreshMatViewFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->StartMsg(_("Refreshing data")); + + ((pgView *)obj)->RefreshMatView(false); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + form->EndMsg(); + + return 0; +} + + +bool refreshMatViewFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(viewFactory) && ((pgView *)obj)->GetMaterializedView(); +} + + +refreshConcurrentlyMatViewFactory::refreshConcurrentlyMatViewFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("&Refresh data concurrently"), _("Refresh data concurrently for the selected object.")); +} + + +wxWindow *refreshConcurrentlyMatViewFactory::StartDialog(frmMain *form, pgObject *obj) +{ + form->StartMsg(_("Refreshing data concurrently")); + + ((pgView *)obj)->RefreshMatView(true); + wxTreeItemId item = form->GetBrowser()->GetSelection(); + if (obj == form->GetBrowser()->GetObject(item)) + obj->ShowTreeDetail(form->GetBrowser(), 0, form->GetProperties()); + + form->EndMsg(); + + return 0; +} + + +bool refreshConcurrentlyMatViewFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(viewFactory) + && ((pgView *)obj)->GetMaterializedView() + && ((pgView *)obj)->GetConnection()->BackendMinimumVersion(9, 4);; +} diff --git a/slony/dlgRepCluster.cpp b/slony/dlgRepCluster.cpp new file mode 100644 index 0000000..547d572 --- /dev/null +++ b/slony/dlgRepCluster.cpp @@ -0,0 +1,1628 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepCluster.cpp - PostgreSQL Slony-I Cluster Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/pgDefs.h" +#include +#include + +#include "frm/frmMain.h" +#include "slony/dlgRepCluster.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "slony/slCluster.h" +#include "schema/pgDatatype.h" +#include "utils/sysProcess.h" + +#define cbServer CTRL_COMBOBOX("cbServer") +#define cbDatabase CTRL_COMBOBOX("cbDatabase") +#define cbClusterName CTRL_COMBOBOX("cbClusterName") + +BEGIN_EVENT_TABLE(dlgRepClusterBase, dlgProperty) + EVT_COMBOBOX(XRCID("cbServer"), dlgRepClusterBase::OnChangeServer) + EVT_COMBOBOX(XRCID("cbDatabase"), dlgRepClusterBase::OnChangeDatabase) +END_EVENT_TABLE(); + + + +dlgRepClusterBase::dlgRepClusterBase(pgaFactory *f, frmMain *frame, const wxString &dlgName, slCluster *node, pgDatabase *db) + : dlgProperty(f, frame, dlgName) +{ + cluster = node; + remoteServer = 0; + remoteConn = 0; + + pgObject *obj = db; + servers = obj->GetId(); + while (obj && obj != frame->GetServerCollection()) + { + servers = frame->GetBrowser()->GetItemParent(servers); + if (servers) + obj = frame->GetBrowser()->GetObject(servers); + } +} + + +dlgRepClusterBase::~dlgRepClusterBase() +{ + if (remoteConn) + { + delete remoteConn; + remoteConn = 0; + } +} + + +pgObject *dlgRepClusterBase::GetObject() +{ + return cluster; +} + + +bool dlgRepClusterBase::AddScript(wxString &sql, const wxString &fn) +{ + wxFileName filename; + filename.Assign(settings->GetSlonyPath(), fn); + + if (!wxFile::Exists(filename.GetFullPath())) + return false; + + wxFile file(filename.GetFullPath(), wxFile::read); + if (!file.IsOpened()) + return false; + + char *buffer; + size_t done; + + buffer = new char[file.Length() + 1]; + done = file.Read(buffer, file.Length()); + buffer[done] = 0; + sql += wxTextBuffer::Translate(wxString::FromAscii(buffer), wxTextFileType_Unix); + delete[] buffer; + + return done > 0; +} + + +int dlgRepClusterBase::Go(bool modal) +{ + return dlgProperty::Go(modal); +} + + +void dlgRepClusterBase::OnChangeServer(wxCommandEvent &ev) +{ + cbDatabase->Clear(); + if (remoteConn) + { + delete remoteConn; + remoteConn = 0; + } + int sel = cbServer->GetCurrentSelection(); + if (sel >= 0) + { + remoteServer = (pgServer *)cbServer->wxItemContainer::GetClientData(sel); + + if (!remoteServer->GetConnected()) + { + remoteServer->Connect(mainForm, remoteServer->GetStorePwd()); + if (!remoteServer->GetConnected()) + { + wxLogError(remoteServer->GetLastError()); + return; + } + } + if (remoteServer->GetConnected()) + { + pgSet *set = remoteServer->ExecuteSet( + wxT("SELECT DISTINCT datname\n") + wxT(" FROM pg_database db\n") + wxT(" WHERE datallowconn ORDER BY datname")); + if (set) + { + while (!set->Eof()) + { + cbDatabase->Append(set->GetVal(wxT("datname"))); + set->MoveNext(); + } + delete set; + + if (cbDatabase->GetCount()) + cbDatabase->SetSelection(0); + } + } + + } + OnChangeDatabase(ev); +} + + + +void dlgRepClusterBase::OnChangeDatabase(wxCommandEvent &ev) +{ + cbClusterName->Clear(); + + int sel = cbDatabase->GetCurrentSelection(); + if (remoteServer && sel >= 0) + { + if (remoteConn) + { + delete remoteConn; + remoteConn = 0; + } + remoteConn = remoteServer->CreateConn(cbDatabase->GetValue()); + if (remoteConn) + { + pgSet *set = remoteConn->ExecuteSet( + wxT("SELECT substr(nspname, 2) as clustername\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" JOIN pg_proc pro ON pronamespace=nsp.oid AND proname = 'slonyversion'\n") + wxT(" ORDER BY nspname")); + + if (set) + { + while (!set->Eof()) + { + cbClusterName->Append(set->GetVal(wxT("clustername"))); + set->MoveNext(); + } + delete set; + } + + if (cbClusterName->GetCount()) + cbClusterName->SetSelection(0); + } + } + OnChangeCluster(ev); +} + +////////////////////////////////////////////////////////////////////////////////7 + +// pointer to controls +#define chkJoinCluster CTRL_CHECKBOX("chkJoinCluster") +#define txtClusterName CTRL_TEXT("txtClusterName") +#define txtNodeID CTRL_TEXT("txtNodeID") +#define txtNodeName CTRL_TEXT("txtNodeName") +#define txtAdminNodeID CTRL_TEXT("txtAdminNodeID") +#define txtAdminNodeName CTRL_TEXT("txtAdminNodeName") +#define cbAdminNode CTRL_COMBOBOX("cbAdminNode") + + +BEGIN_EVENT_TABLE(dlgRepCluster, dlgRepClusterBase) + EVT_BUTTON(wxID_OK, dlgRepCluster::OnOK) + EVT_CHECKBOX(XRCID("chkJoinCluster"), dlgRepCluster::OnChangeJoin) + EVT_COMBOBOX(XRCID("cbClusterName"), dlgRepCluster::OnChangeCluster) + EVT_TEXT(XRCID("txtClusterName"), dlgRepCluster::OnChange) + EVT_TEXT(XRCID("txtNodeID"), dlgRepCluster::OnChange) + EVT_TEXT(XRCID("txtNodeName"), dlgRepCluster::OnChange) + EVT_COMBOBOX(XRCID("cbAdminNode"), dlgRepCluster::OnChange) + EVT_END_PROCESS(-1, dlgRepCluster::OnEndProcess) +END_EVENT_TABLE(); + + +dlgProperty *pgaSlClusterFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepCluster(this, frame, (slCluster *)node, (pgDatabase *)parent); +} + + +dlgRepCluster::dlgRepCluster(pgaFactory *f, frmMain *frame, slCluster *node, pgDatabase *db) + : dlgRepClusterBase(f, frame, wxT("dlgRepCluster"), node, db) +{ + process = 0; +} + + + +wxString dlgRepCluster::GetHelpPage() const +{ + wxString page = wxT("slony-install"); + if (chkJoinCluster->GetValue()) + page += wxT("#join"); + + return page; +} + +bool dlgRepCluster::SlonyMaximumVersion(const wxString &series, long minor) +{ + + wxString slonySeries; + long slonyMinorVersion; + + slonySeries = slonyVersion.BeforeLast('.'); + slonyVersion.AfterLast('.').ToLong(&slonyMinorVersion); + + return slonySeries == series && slonyMinorVersion <= minor; +} + + + +int dlgRepCluster::Go(bool modal) +{ + chkJoinCluster->SetValue(false); + + if (cluster) + { + // edit mode + txtClusterName->SetValue(cluster->GetName()); + txtNodeID->SetValue(NumToStr(cluster->GetLocalNodeID())); + txtClusterName->Disable(); + txtNodeID->Disable(); + txtNodeName->SetValue(cluster->GetLocalNodeName()); + txtNodeName->Disable(); + chkJoinCluster->Disable(); + + txtAdminNodeID->Hide(); + txtAdminNodeName->Hide(); + + wxString sql = + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_path ON no_id = pa_client\n") + wxT(" WHERE pa_server = ") + NumToStr(cluster->GetLocalNodeID()) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%host=") + cluster->GetServer()->GetName() + wxT("%")) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%dbname=") + cluster->GetDatabase()->GetName() + wxT("%")); + + if (cluster->GetServer()->GetPort() != 5432) + sql += wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%port=") + NumToStr((long)cluster->GetServer()->GetPort()) + wxT("%")); + + sql += wxT(" ORDER BY no_id"); + + pgSet *set = connection->ExecuteSet(sql); + if (set) + { + while (!set->Eof()) + { + long id = set->GetLong(wxT("no_id")); + cbAdminNode->Append(IdAndName(id, set->GetVal(wxT("no_comment"))), (void *)id); + if (id == cluster->GetAdminNodeID()) + cbAdminNode->SetSelection(cbAdminNode->GetCount() - 1); + + set->MoveNext(); + } + delete set; + } + if (!cbAdminNode->GetCount()) + { + cbAdminNode->Append(_(""), (void *) - 1); + cbAdminNode->SetSelection(0); + } + + cbServer->Append(cluster->GetServer()->GetName()); + cbServer->SetSelection(0); + cbDatabase->Append(cluster->GetDatabase()->GetName()); + cbDatabase->SetSelection(0); + cbClusterName->Append(cluster->GetName()); + cbClusterName->SetSelection(0); + } + else + { + // create mode + cbAdminNode->Hide(); + + wxString scriptVersion = wxEmptyString; + wxString xxidVersion = wxEmptyString; + + txtNodeID->SetValidator(numericValidator); + txtAdminNodeID->SetValidator(numericValidator); + txtClusterName->Hide(); + + //We need to find the exact Slony Version. + //NOTE: We are not supporting Slony versions less than 1.2.0 + wxString tempScript = wxEmptyString; + bool isSlonyVersionBefore2_2_0 = false; + + if(!AddScript(tempScript, wxT("slony1_funcs.sql"))) + { + if(!AddScript(tempScript, wxT("slony1_funcs.2.2.0.sql"))) + { + isSlonyVersionBefore2_2_0 = true; + } + else + { + isSlonyVersionBefore2_2_0 = false; + } + } + else + { + isSlonyVersionBefore2_2_0 = true; + } + + if (tempScript.Contains(wxT("@MODULEVERSION@")) && slonyVersion.IsEmpty()) + { + bool hasVerFunc = false; + this->database->ExecuteVoid(wxT("RESET SEARCH_PATH;")); + + if (isSlonyVersionBefore2_2_0) + hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs', '_Slony_I_getModuleVersion' LANGUAGE C"), false); + else + hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs.2.2.0', '_Slony_I_2_2_0_getModuleVersion' LANGUAGE C"), false); + + if (hasVerFunc) + { + slonyVersion = this->database->ExecuteScalar(wxT("SELECT pgadmin_slony_version();")); + this->database->ExecuteVoid(wxT("DROP FUNCTION pgadmin_slony_version()"), false); + } + else + { + tempScript.Empty(); + } + + if (slonyVersion.IsEmpty()) + { + wxLogError(_("Couldn't test for the Slony version. Assuming 1.2.0")); + slonyVersion = wxT("1.2.0"); + } + } + + //Here we are finding the exact slony scripts version, which is based on Slony Version and PG Version. + // For Slony 1.2.0 to 1.2.21 and 2.0.0 if PG 7.3 script version is v73 + // For Slony 1.2.0 to 1.2.21 and 2.0.0 if PG 7.4 script version is v74 + // For Slony 1.2.0 to 1.2.6 if PG 8.0+ script version is v80 + // For Slony 1.2.7 to 1.2.21 and 2.0.0 if PG 8.0 script version is v80 + // For Slony 1.2.7 to 1.2.21 and 2.0.0 if PG 8.1+ script version is v81 + // For Slony 2.0.1 and 2.0.2 if PG 8.3+ script version is v83. (These version onwards do not support PG Version less than 8.3) + // For Slony 2.0.3 if PG 8.3 script version is v83. + // For Slony 2.0.3 if PG 8.4+ script version is v84. + // For Slony 2.1.0 to 2.2.0 if PG 8.3 script version v83 + // For Slony 2.1.0 to 2.2.0 if PG 8.4+ script version v84 + // Since both 1.2 and 2.0 series is increasing, the following code needs to be updated with each Slony or PG update. + // For Slony 1.2.22 onwards if PG 7.4 script version v74 + // For Slony 1.2.22 onwards if PG 8.0 script version v80 + // For Slony 1.2.22 onwards if PG 8.3 script version v81 + // For Slony 1.2.22 onwards if PG 8.4+ script version v84 + if (!tempScript.IsEmpty()) + { + wxString slonySeries; + long slonyMinorVersion; + slonySeries = slonyVersion.BeforeLast('.'); + slonyVersion.AfterLast('.').ToLong(&slonyMinorVersion); + + //Set the slony_base and slony_funcs script version. + if (SlonyMaximumVersion(wxT("1.2"), 6)) + { + if (connection->BackendMinimumVersion(8, 0)) + scriptVersion = wxT("v80"); + else + { + if (connection->BackendMinimumVersion(7, 4)) + scriptVersion = wxT("v74"); + else + scriptVersion = wxT("v73"); + } + } + else + { + // For slony verion 1.2.22 and above set the script version + if (slonySeries == wxT("1.2") && slonyMinorVersion >= 22) + { + if (connection->BackendMinimumVersion(8, 4)) + scriptVersion = wxT("v84"); + else + { + if (connection->BackendMinimumVersion(8, 1)) + scriptVersion = wxT("v81"); + else + { + if (connection->BackendMinimumVersion(8, 0)) + scriptVersion = wxT("v80"); + else + scriptVersion = wxT("v74"); + } + } + } + + // For slony major version 1.2, minor version <= 21 and slony version 2.0, set the script version + if (SlonyMaximumVersion(wxT("1.2"), 21) || SlonyMaximumVersion(wxT("2.0"), 0)) + { + if (connection->BackendMinimumVersion(8, 1)) + scriptVersion = wxT("v81"); + else + { + if (connection->BackendMinimumVersion(8, 0)) + scriptVersion = wxT("v80"); + else + { + if (connection->BackendMinimumVersion(7, 4)) + scriptVersion = wxT("v74"); + else + scriptVersion = wxT("v73"); + } + } + } + else + { + if (SlonyMaximumVersion(wxT("2.0"), 2)) + scriptVersion = wxT("v83"); + else + { + if (SlonyMaximumVersion(wxT("2.0"), 8)) + { + if (connection->BackendMinimumVersion(8, 4)) + scriptVersion = wxT("v84"); + } + + if (SlonyMaximumVersion(wxT("2.1"), 4) || SlonyMaximumVersion(wxT("2.2"), 0)) + { + if (connection->BackendMinimumVersion(8, 4)) + scriptVersion = wxT("v84"); + } + else + { + if (scriptVersion.IsEmpty()) + scriptVersion = wxT("v83"); + } + } + } + } + + //Set the correct xxid version if applicable + // For Slony 1.2.0 to 1.2.17 and 2.0.0 if PG 7.3 xxid version is v73 + // For Slony 1.2.1 to 1.2.17 and 2.0.0 if PG 7.4+ xxid version is v74 + // For Slony 1.2.0 if PG 8.0 xxid version is v80 + // For Slony 2.0.1+ and PG8.4+ xxid is obsolete. + + if (SlonyMaximumVersion(wxT("1.2"), 0)) + { + if (connection->BackendMinimumVersion(8, 0)) + xxidVersion = wxT("v80"); + else + { + if (connection->BackendMinimumVersion(7, 4)) + xxidVersion = wxT("v74"); + else + xxidVersion = wxT("v73"); + } + } + else + { + // For Slony 1.2.22 and above if PG 7.4 xxid version is v74 + // For Slony 1.2.22 and above if PG 8.0 xxid version is v80 + // For Slony 1.2.22 and above if PG 8.1 xxid version is v81 + // For Slony 1.2.22 and above if PG 8.4+ xxid version is v84 + if (slonySeries == wxT("1.2") && slonyMinorVersion >= 22) + { + if (connection->BackendMinimumVersion(8, 4)) + xxidVersion = wxT("v84"); + else + { + if (connection->BackendMinimumVersion(8, 1)) + xxidVersion = wxT("v81"); + else + { + if (connection->BackendMinimumVersion(8, 0)) + xxidVersion = wxT("v80"); + else + xxidVersion = wxT("v74"); + } + } + } + + if (SlonyMaximumVersion(wxT("1.2"), 21) || SlonyMaximumVersion(wxT("2.0"), 0)) + { + if (!connection->BackendMinimumVersion(8, 4)) + { + if (connection->BackendMinimumVersion(7, 4)) + xxidVersion = wxT("v74"); + else + xxidVersion = wxT("v73"); + } + } + } + + wxString slonyBaseVersionFilename; + wxString slonyFuncsVersionFilename; + + if (SlonyMaximumVersion(wxT("2.2"), 0)) + { + slonyBaseVersionFilename = wxT("slony1_base.") + scriptVersion + wxT(".2.2.0.sql"); + slonyFuncsVersionFilename = wxT("slony1_funcs.") + scriptVersion + wxT(".2.2.0.sql"); + } + else + { + slonyBaseVersionFilename = wxT("slony1_base.") + scriptVersion + wxT(".sql"); + slonyFuncsVersionFilename = wxT("slony1_funcs.") + scriptVersion + wxT(".sql"); + } + + wxString xxidVersionFilename; + + if (!xxidVersion.IsEmpty()) + xxidVersionFilename = wxT("xxid.") + xxidVersion + wxT(".sql"); + + if (SlonyMaximumVersion(wxT("2.2"), 0)) + { + if (((!xxidVersion.IsEmpty() && !AddScript(createScript, xxidVersionFilename)) || + !AddScript(createScript, wxT("slony1_base.2.2.0.sql")) || + !AddScript(createScript, slonyBaseVersionFilename) || + !AddScript(createScript, wxT("slony1_funcs.2.2.0.sql")) || + !AddScript(createScript, slonyFuncsVersionFilename))) + createScript = wxEmptyString; + } + else + { + if (((!xxidVersion.IsEmpty() && !AddScript(createScript, xxidVersionFilename)) || + !AddScript(createScript, wxT("slony1_base.sql")) || + !AddScript(createScript, slonyBaseVersionFilename) || + !AddScript(createScript, wxT("slony1_funcs.sql")) || + !AddScript(createScript, slonyFuncsVersionFilename))) + createScript = wxEmptyString; + } + } + + // Populate the server combo box + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + int sel = -1; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + if (server == database->GetServer()) + sel = cbServer->GetCount(); + cbServer->Append(browser->GetItemText(server->GetId()), (void *)server); + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + if (sel >= 0) + cbServer->SetSelection(sel); + } + + wxCommandEvent ev; + OnChangeJoin(ev); + + return dlgRepClusterBase::Go(modal); +} + + +void dlgRepCluster::OnChangeJoin(wxCommandEvent &ev) +{ + bool joinCluster = chkJoinCluster->GetValue(); + txtClusterName->Show(!joinCluster); + cbClusterName->Show(joinCluster); + + cbServer->Enable(joinCluster); + cbDatabase->Enable(joinCluster); + + txtAdminNodeID->Show(!joinCluster && !cluster); + txtAdminNodeName->Show(!joinCluster && !cluster); + cbAdminNode->Show(joinCluster || cluster); + cbAdminNode->Move(txtAdminNodeID->GetPosition()); + + // Force the dialogue to resize to prevent a drawing issue on GTK +#ifdef __WXGTK__ + SetSize(GetSize().x + 1, GetSize().y + 1); + Layout(); + SetSize(GetSize().x - 1, GetSize().y - 1); +#endif + + if (joinCluster && !cbDatabase->GetCount()) + { + OnChangeServer(ev); + return; + } + + OnChange(ev); +} + + +void dlgRepCluster::OnChangeCluster(wxCommandEvent &ev) +{ + clusterBackup = wxEmptyString; + remoteVersion = wxEmptyString; + + cbAdminNode->Clear(); + cbAdminNode->Append(_(""), (void *) - 1); + + int sel = cbClusterName->GetCurrentSelection(); + if (remoteConn && sel >= 0) + { + wxString schemaPrefix = qtIdent(wxT("_") + cbClusterName->GetValue()) + wxT("."); + long adminNodeID = settings->Read(wxT("Replication/") + cbClusterName->GetValue() + wxT("/AdminNode"), -1L); + + remoteVersion = remoteConn->ExecuteScalar(wxT("SELECT ") + schemaPrefix + wxT("slonyVersion();")); + + wxString sql = + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + schemaPrefix + wxT("sl_node\n") + wxT(" JOIN ") + schemaPrefix + wxT("sl_path ON no_id = pa_client\n") + wxT(" WHERE pa_server = (SELECT last_value FROM ") + schemaPrefix + wxT("sl_local_node_id)\n") + wxT(" AND pa_conninfo ILIKE ") + qtDbString(wxT("%host=") + remoteServer->GetName() + wxT("%")) + wxT("\n") + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%dbname=") + cbDatabase->GetValue() + wxT("%")) + wxT("\n"); + + if (remoteServer->GetPort() != 5432) + sql += wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%port=") + NumToStr((long)remoteServer->GetPort()) + wxT("%")); + + pgSet *set = remoteConn->ExecuteSet(sql); + if (set) + { + if (!set->Eof()) + { + long id = set->GetLong(wxT("no_id")); + cbAdminNode->Append(IdAndName(id, set->GetVal(wxT("no_comment"))), (void *)id); + if (adminNodeID == id) + cbAdminNode->SetSelection(cbAdminNode->GetCount() - 1); + } + } + + + usedNodes.Clear(); + set = remoteConn->ExecuteSet( + wxT("SELECT no_id FROM ") + schemaPrefix + wxT("sl_node")); + + if (set) + { + while (!set->Eof()) + { + usedNodes.Add(set->GetLong(wxT("no_id"))); + set->MoveNext(); + } + delete set; + } + } + OnChange(ev); +} + + + +bool dlgRepCluster::CopyTable(pgConn *from, pgConn *to, const wxString &table) +{ + bool ok = true; + + pgSet *set = from->ExecuteSet(wxT("SELECT * FROM ") + table); + if (!set) + return false; + + while (ok && !set->Eof()) + { + wxString sql = wxT("INSERT INTO ") + table + wxT("("); + wxString vals; + int i; + + for (i = 0 ; i < set->NumCols() ; i++) + { + if (i) + { + sql += wxT(", ");; + vals += wxT(", "); + } + + sql += set->ColName(i); + + if (set->IsNull(i)) + vals += wxT("NULL"); + else + { + switch (set->ColTypeOid(i)) + { + case PGOID_TYPE_BOOL: + case PGOID_TYPE_BYTEA: + case PGOID_TYPE_CHAR: + case PGOID_TYPE_NAME: + case PGOID_TYPE_TEXT: + case PGOID_TYPE_VARCHAR: + case PGOID_TYPE_TIME: + case PGOID_TYPE_TIMESTAMP: + case PGOID_TYPE_TIME_ARRAY: + case PGOID_TYPE_TIMESTAMPTZ: + case PGOID_TYPE_INTERVAL: + case PGOID_TYPE_TIMETZ: + vals += qtDbString(set->GetVal(i)); + break; + default: + vals += set->GetVal(i); + } + } + } + + ok = to->ExecuteVoid( + sql + wxT(")\n VALUES (") + vals + wxT(");")); + + + set->MoveNext(); + } + delete set; + return ok; +} + + +void dlgRepCluster::OnOK(wxCommandEvent &ev) +{ +#ifdef __WXGTK__ + if (!btnOK->IsEnabled()) + return; +#endif + EnableOK(false); + + bool done = true; + done = connection->ExecuteVoid(wxT("BEGIN TRANSACTION;")); + + if (remoteConn) + done = remoteConn->ExecuteVoid(wxT("BEGIN TRANSACTION;")); + + // initialize cluster on local node + done = connection->ExecuteVoid(GetSql()); + + if (done && chkJoinCluster->GetValue()) + { + // we're joining an existing cluster + + wxString schemaPrefix = qtIdent(wxT("_") + cbClusterName->GetValue()) + wxT("."); + + wxString clusterVersion = remoteConn->ExecuteScalar( + wxT("SELECT ") + schemaPrefix + wxT("slonyversion()")); + + wxString newVersion = connection->ExecuteScalar( + wxT("SELECT ") + schemaPrefix + wxT("slonyversion()")); + + if (clusterVersion != newVersion) + { + wxMessageDialog msg(this, + wxString::Format(_("The newly created cluster version (%s)\n doesn't match the existing cluster's version (%s)"), + newVersion.c_str(), clusterVersion.c_str()), + _("Error while joining replication cluster"), wxICON_ERROR); + msg.ShowModal(); + done = false; + } + + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_node")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_path")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_listen")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_set")); + if (done) + done = CopyTable(remoteConn, connection, schemaPrefix + wxT("sl_subscribe")); + + + // make sure event seqno starts correctly after node reusage + if (done) + { + pgSet *set = connection->ExecuteSet( + wxT("SELECT ev_origin, MAX(ev_seqno) as seqno\n") + wxT(" FROM ") + schemaPrefix + wxT("sl_event\n") + wxT(" GROUP BY ev_origin")); + if (set) + { + while (done && !set->Eof()) + { + if (set->GetVal(wxT("ev_origin")) == txtNodeID->GetValue()) + { + done = connection->ExecuteVoid( + wxT("SELECT pg_catalog.setval(") + + qtDbString(wxT("_") + cbClusterName->GetValue() + wxT(".sl_event_seq")) + + wxT(", ") + set->GetVal(wxT("seqno")) + wxT("::int8 +1)")); + } + else + { + done = connection->ExecuteVoid( + wxT("INSERT INTO ") + schemaPrefix + wxT("sl_confirm(con_origin, con_received, con_seqno, con_timestamp\n") + wxT(" VALUES (") + set->GetVal(wxT("ev_origin")) + + wxT(", ") + txtNodeID->GetValue() + + wxT(", ") + set->GetVal(wxT("seqno")) + + wxT(", current_timestamp")); + + } + set->MoveNext(); + } + delete set; + } + } + + + // make sure rowid seq starts correctly + if (done) + { + wxString seqno = connection->ExecuteScalar( + wxT("SELECT MAX(seql_last_value)\n") + wxT(" FROM ") + schemaPrefix + wxT("sl_seqlog\n") + wxT(" WHERE seql_seqid = 0 AND seql_origin = ") + txtNodeID->GetValue()); + + if (!seqno.IsEmpty()) + { + done = connection->ExecuteVoid( + wxT("SELECT pg_catalog.setval(") + + qtDbString(wxT("_") + cbClusterName->GetValue() + wxT(".sl_rowid_seq")) + + wxT(", ") + seqno + wxT(")")); + } + } + + // create new node on the existing cluster + if (done) + { + wxString sql = + wxT("SELECT ") + schemaPrefix + wxT("storenode(") + + txtNodeID->GetValue() + wxT(", ") + + qtDbString(txtNodeName->GetValue()); + + // When user has not selected cluster drop down in that case "schemaPrefix" will be NULL, + // we have to use slonyVersion instead of remoteVersion + if (remoteVersion.IsEmpty()) + { + if (StrToDouble(slonyVersion) >= 1.1 && StrToDouble(slonyVersion) < 2.0) + sql += wxT(", false"); + } + else + { + if (StrToDouble(remoteVersion) >= 1.1 && StrToDouble(remoteVersion) < 2.0) + sql += wxT(", false"); + } + + sql += wxT(");\n") + wxT("SELECT ") + schemaPrefix + wxT("enablenode(") + + txtNodeID->GetValue() + wxT(");\n"); + + done = remoteConn->ExecuteVoid(sql); + } + + // add admin info to cluster + + if (done && cbAdminNode->GetCurrentSelection() > 0) + { + done = remoteConn->ExecuteVoid( + wxT("SELECT ") + schemaPrefix + wxT("storepath(") + + txtNodeID->GetValue() + wxT(", ") + + NumToStr((long)cbAdminNode->wxItemContainer::GetClientData(cbAdminNode->GetCurrentSelection())) + wxT(", ") + + qtDbString(wxT("host=") + database->GetServer()->GetName() + + wxT(" port=") + NumToStr((long)database->GetServer()->GetPort()) + + wxT(" dbname=") + database->GetName()) + wxT(", ") + wxT("0);\n")); + } + } + if (!done) + { + if (remoteConn) + done = remoteConn->ExecuteVoid(wxT("ROLLBACK TRANSACTION;")); + done = connection->ExecuteVoid(wxT("ROLLBACK TRANSACTION;")); + EnableOK(true); + return; + } + + if (remoteConn) + done = remoteConn->ExecuteVoid(wxT("COMMIT TRANSACTION;")); + done = connection->ExecuteVoid(wxT("COMMIT TRANSACTION;")); + + ShowObject(); + Destroy(); +} + + +pgObject *dlgRepCluster::CreateObject(pgCollection *collection) +{ + pgObject *obj = slClusterFactory.CreateObjects(collection, 0, + wxT(" WHERE nspname = ") + qtDbString(wxT("_") + GetName())); + + return obj; +} + + +void dlgRepCluster::CheckChange() +{ + if (cluster) + { + int sel = cbAdminNode->GetCurrentSelection(); + bool changed = (sel >= 0 && (long)cbAdminNode->wxEvtHandler::GetClientData() != cluster->GetAdminNodeID()); + + EnableOK(changed || txtComment->GetValue() != cluster->GetComment()); + } + else + { + size_t i; + bool enable = true; + + CheckValid(enable, chkJoinCluster->GetValue() || (!createScript.IsEmpty()), + _("Slony-I creation scripts not available; only joining possible.")); + + if (chkJoinCluster->GetValue()) + CheckValid(enable, !cbClusterName->GetValue().IsEmpty(), _("Please select a cluster name.")); + else + CheckValid(enable, !txtClusterName->GetValue().IsEmpty(), _("Please specify name.")); + + long nodeId = StrToLong(txtNodeID->GetValue()); + CheckValid(enable, nodeId > 0, _("Please specify local node ID.")); + for (i = 0 ; i < usedNodes.GetCount() && enable; i++) + CheckValid(enable, nodeId != usedNodes[i], _("Node ID is already in use.")); + + CheckValid(enable, !txtNodeName->GetValue().IsEmpty(), _("Please specify local node name.")); + + txtAdminNodeName->Enable(nodeId != StrToLong(txtAdminNodeID->GetValue())); + + EnableOK(enable); + } +} + + +void dlgRepCluster::OnEndProcess(wxProcessEvent &ev) +{ + if (process) + { + wxString error = process->ReadErrorStream(); + clusterBackup += process->ReadInputStream(); + delete process; + process = 0; + } +} + + +// this is necessary because wxString::Replace is ridiculously slow on large strings. + +void AppendBuf(wxChar *&buf, int &buflen, int &len, const wxChar *str, int slen = -1) +{ + if (slen < 0) + slen = wxStrlen(str); + if (!slen) + return; + if (buflen < len + slen) + { + buflen = (len + slen) * 6 / 5; + wxChar *tmp = new wxChar[buflen + 1]; + memcpy(tmp, buf, len * sizeof(wxChar)); + delete[] buf; + buf = tmp; + } + memcpy(buf + len, str, slen * sizeof(wxChar)); + len += slen; +} + + +wxString ReplaceString(const wxString &str, const wxString &oldStr, const wxString &newStr) +{ + int buflen = str.Length() + 100; + int len = 0; + + wxChar *buf = new wxChar[buflen + 1]; + + const wxChar *ptrIn = str.c_str(); + const wxChar *ptrFound = wxStrstr(ptrIn, oldStr); + + while (ptrFound) + { + AppendBuf(buf, buflen, len, ptrIn, ptrFound - ptrIn); + AppendBuf(buf, buflen, len, newStr.c_str()); + ptrIn = ptrFound + oldStr.Length(); + ptrFound = wxStrstr(ptrIn, oldStr); + } + + AppendBuf(buf, buflen, len, ptrIn); + buf[len] = 0; + wxString tmpstr(buf); + delete[] buf; + + return tmpstr; +} + + +wxString dlgRepCluster::GetSql() +{ + wxString sql; + wxString name; + if (chkJoinCluster->GetValue()) + name = wxT("_") + cbClusterName->GetValue(); + else + name = wxT("_") + txtClusterName->GetValue(); + + wxString quotedName = qtIdent(name); + + + if (cluster) + { + // edit mode + int sel = cbAdminNode->GetCurrentSelection(); + if (sel >= 0) + { + long id = (long)cbAdminNode->wxItemContainer::GetClientData(sel); + if (id != cluster->GetAdminNodeID()) + settings->WriteLong(wxT("Replication/") + cluster->GetName() + wxT("/AdminNode"), id); + } + } + else + { + // create mode + wxString backupExecutable; + if (remoteServer && remoteServer->GetConnection()->EdbMinimumVersion(8, 0)) + backupExecutable = edbBackupExecutable; + else if (remoteServer && remoteServer->GetConnection()->GetIsGreenplum()) + backupExecutable = gpBackupExecutable; + else + backupExecutable = pgBackupExecutable; + + if (remoteServer && clusterBackup.IsEmpty() && !backupExecutable.IsEmpty()) + { + wxArrayString environment; + if (!remoteServer->GetPasswordIsStored()) + environment.Add(wxT("PGPASSWORD=") + remoteServer->GetPassword()); + + process = sysProcess::Create(backupExecutable + + wxT(" -i -F p -h ") + remoteServer->GetName() + + wxT(" -p ") + NumToStr((long)remoteServer->GetPort()) + + wxT(" -U ") + remoteServer->GetUsername() + + wxT(" -s -O -n ") + name + + wxT(" ") + cbDatabase->GetValue(), + this, &environment); + + wxBusyCursor wait; + while (process) + { + wxSafeYield(); + if (process) + clusterBackup += process->ReadInputStream(); + wxSafeYield(); + wxMilliSleep(10); + } + } + + if (!clusterBackup.IsEmpty()) + { + int opclassPos = clusterBackup.Find(wxT("CREATE OPERATOR CLASS")); + sql = wxT("-- Extracted schema from existing cluster\n\n") + + clusterBackup.Left(opclassPos > 0 ? opclassPos : 99999999); + if (opclassPos > 0) + { + sql += wxT("----------- inserted by pgadmin: add public operators\n") + wxT("CREATE OPERATOR public.< (PROCEDURE = xxidlt,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\">\", NEGATOR = public.\">=\",") + wxT(" RESTRICT = scalarltsel, JOIN = scalarltjoinsel);\n") + wxT("CREATE OPERATOR public.= (PROCEDURE = xxideq,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"=\", NEGATOR = public.\"<>\",") + wxT(" RESTRICT = eqsel, JOIN = eqjoinsel,") + wxT(" SORT1 = public.\"<\", SORT2 = public.\"<\", HASHES);\n") + wxT("CREATE OPERATOR public.<> (PROCEDURE = xxidne,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"<>\", NEGATOR = public.\"=\",") + wxT(" RESTRICT = neqsel, JOIN = neqjoinsel);\n") + wxT("CREATE OPERATOR public.> (PROCEDURE = xxidgt,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"<\", NEGATOR = public.\"<=\",") + wxT(" RESTRICT = scalargtsel, JOIN = scalargtjoinsel);\n") + wxT("CREATE OPERATOR public.<= (PROCEDURE = xxidle,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\">=\", NEGATOR = public.\">\",") + wxT(" RESTRICT = scalarltsel, JOIN = scalarltjoinsel);\n") + wxT("CREATE OPERATOR public.>= (PROCEDURE = xxidge,") + wxT(" LEFTARG = xxid, RIGHTARG = xxid,") + wxT(" COMMUTATOR = public.\"<=\", NEGATOR = public.\"<\",") + wxT(" RESTRICT = scalargtsel, JOIN = scalargtjoinsel);\n") + wxT("------------- continue with backup script\n") + + clusterBackup.Mid(opclassPos); + } + } + else + { + sql = wxT("CREATE SCHEMA ") + quotedName + wxT(";\n\n") + + ReplaceString(createScript, wxT("@NAMESPACE@"), quotedName); + + if (chkJoinCluster->GetValue()) + sql = ReplaceString(sql, wxT("@CLUSTERNAME@"), cbClusterName->GetValue()); + else + sql = ReplaceString(sql, wxT("@CLUSTERNAME@"), txtClusterName->GetValue()); + + // From Slony 1.2 onwards, the scripts include the module version. + // To figure it out, temporarily load and use _Slony_I_getModuleVersion. + // We'll cache the result to save doing it again. + if (sql.Contains(wxT("@MODULEVERSION@")) && slonyVersion.IsEmpty()) + { + bool hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs', '_Slony_I_getModuleVersion' LANGUAGE C"), false); + if (!hasVerFunc) + { + hasVerFunc = this->database->ExecuteVoid(wxT("CREATE OR REPLACE FUNCTION pgadmin_slony_version() returns text as '$libdir/slony1_funcs.2.2.0', '_Slony_I_2_2_0_getModuleVersion' LANGUAGE C"), false); + } + if (hasVerFunc) + { + slonyVersion = this->database->ExecuteScalar(wxT("SELECT pgadmin_slony_version();")); + this->database->ExecuteVoid(wxT("DROP FUNCTION pgadmin_slony_version()"), false); + } + + if (slonyVersion.IsEmpty()) + { + wxLogError(_("Couldn't test for the Slony version. Assuming 1.2.0")); + slonyVersion = wxT("1.2.0"); + } + } + sql = ReplaceString(sql, wxT("@MODULEVERSION@"), slonyVersion); + + // If slony version is greater then equal to 2.2 then replace @FUNCVERSION to 2_2_0 + if (sql.Contains(wxT("@FUNCVERSION@")) && SlonyMaximumVersion(wxT("2.2"), 0)) + { + wxString slonyFuncVersion = slonyVersion; + slonyFuncVersion.Replace(wxT("."), wxT("_")); + sql = ReplaceString(sql, wxT("@FUNCVERSION@"), slonyFuncVersion); + } + } + + sql += wxT("\n") + wxT("SELECT ") + quotedName + wxT(".initializelocalnode(") + + txtNodeID->GetValue() + wxT(", ") + qtDbString(txtNodeName->GetValue()) + + wxT(");\n") + wxT("SELECT ") + quotedName; + + if (chkJoinCluster->GetValue()) + sql += wxT(".enablenode_int("); + else + sql += wxT(".enablenode("); + + sql += txtNodeID->GetValue() + + wxT(");\n"); + } + + if ((!cluster && !txtComment->IsEmpty()) || (cluster && + cluster->GetComment() != txtComment->GetValue())) + { + sql += wxT("\n") + wxT("COMMENT ON SCHEMA ") + quotedName + wxT(" IS ") + + qtDbString(txtComment->GetValue()) + wxT(";\n"); + } + + if (chkJoinCluster->GetValue()) + sql += wxT("\n\n-- In addition, the configuration is copied from the existing cluster.\n"); + else + { + wxString schemaPrefix = qtIdent(wxT("_") + txtClusterName->GetValue()) + wxT("."); + long adminNode = StrToLong(txtAdminNodeID->GetValue()); + if (adminNode > 0 && adminNode != StrToLong(txtNodeID->GetValue())) + { + sql += + wxT("\n-- Create admin node\n") + wxT("SELECT ") + schemaPrefix + wxT("storeNode(") + + NumToStr(adminNode) + wxT(", ") + + qtDbString(txtAdminNodeName->GetValue()); + + + // When user has not selected cluster drop down in that case "schemaPrefix" will be NULL, + // we have to use slonyVersion instead of remoteVersion + if (remoteVersion.IsEmpty()) + { + if (StrToDouble(slonyVersion) >= 1.1 && StrToDouble(slonyVersion) < 2.0) + sql += wxT(", false"); + } + else + { + // storeNode API contains three argument in slony version 1.1 and 1.2 (storeNode(int4,text,boolean)), + // slony version 2.0 onwards, storeNode API contains only two arguments e.g. storeNode(int4,text) + if (StrToDouble(remoteVersion) >= 1.1 && StrToDouble(remoteVersion) < 2.0) + sql += wxT(", false"); + } + + sql += wxT(");\n") + wxT("SELECT ") + schemaPrefix + wxT("storepath(") + + txtNodeID->GetValue() + wxT(", ") + + NumToStr(adminNode) + wxT(", ") + + qtDbString(wxT("host=") + database->GetServer()->GetName() + + wxT(" port=") + NumToStr((long)database->GetServer()->GetPort()) + + wxT(" dbname=") + database->GetName()) + wxT(", ") + wxT("0);\n"); + } + } + return sql; +} + + + +////////////////////////////////////////////////////////////////////////////////7 + + +#define txtCurrentVersion CTRL_TEXT("txtCurrentVersion") +#define txtVersion CTRL_TEXT("txtVersion") + +BEGIN_EVENT_TABLE(dlgRepClusterUpgrade, dlgRepClusterBase) + EVT_COMBOBOX(XRCID("cbClusterName"), dlgRepClusterUpgrade::OnChangeCluster) +END_EVENT_TABLE(); + +// no factory needed; called by slFunction + +dlgRepClusterUpgrade::dlgRepClusterUpgrade(pgaFactory *f, frmMain *frame, slCluster *cl) + : dlgRepClusterBase(f, frame, wxT("dlgRepClusterUpgrade"), cl, cl->GetDatabase()) +{ +} + + +int dlgRepClusterUpgrade::Go(bool modal) +{ + txtCurrentVersion->SetValue(cluster->GetClusterVersion()); + txtCurrentVersion->Disable(); + txtVersion->Disable(); + + // Populate the server combo box + ctlTree *browser = mainForm->GetBrowser(); + wxTreeItemIdValue foldercookie, servercookie; + wxTreeItemId folderitem, serveritem; + pgObject *object; + pgServer *server; + + folderitem = browser->GetFirstChild(browser->GetRootItem(), foldercookie); + while (folderitem) + { + if (browser->ItemHasChildren(folderitem)) + { + serveritem = browser->GetFirstChild(folderitem, servercookie); + while (serveritem) + { + object = browser->GetObject(serveritem); + if (object && object->IsCreatedBy(serverFactory)) + { + server = (pgServer *)object; + cbServer->Append(browser->GetItemText(server->GetId()), (void *)server); + } + serveritem = browser->GetNextChild(folderitem, servercookie); + } + } + folderitem = browser->GetNextChild(browser->GetRootItem(), foldercookie); + } + + if (cbServer->GetCount()) + cbServer->SetSelection(0); + + wxCommandEvent ev; + OnChangeServer(ev); + + return dlgRepClusterBase::Go(modal); +} + + +void dlgRepClusterUpgrade::CheckChange() +{ + bool enable = true; + CheckValid(enable, cluster->GetSlonPid() == 0, _("Slon process running on node; stop it before upgrading.")); + CheckValid(enable, cbDatabase->GetCount() > 0, _("Select server with Slony-I cluster installed.")); + CheckValid(enable, cbClusterName->GetCount() > 0, _("Select database with Slony-I cluster installed.")); + CheckValid(enable, cbClusterName->GetCurrentSelection() >= 0, _("Select Slony-I cluster.")); + CheckValid(enable, version > cluster->GetClusterVersion(), _("Selected cluster doesn't contain newer software.")); + EnableOK(enable); +} + + +wxString dlgRepClusterUpgrade::GetSql() +{ + if (sql.IsEmpty() && !version.IsEmpty() && remoteConn) + { + wxString remoteCluster = wxT("_") + cbClusterName->GetValue(); + sql = wxT("SET SEARCH_PATH = ") + qtIdent(wxT("_") + cluster->GetName()) + wxT(", pg_catalog;\n\n"); + + bool upgradeSchemaAvailable = false; + + { + // update functions + pgSetIterator func(remoteConn, + wxT("SELECT proname, proisagg, prosecdef, proisstrict, proretset, provolatile, pronargs, prosrc, probin,\n") + wxT(" lanname, tr.typname as rettype,\n") + wxT(" t0.typname AS arg0, t1.typname AS arg1, t2.typname AS arg2, t3.typname AS arg3, t4.typname AS arg4,\n") + wxT(" t5.typname AS arg5, t6.typname AS arg6, t7.typname AS arg7, t8.typname AS arg8, t9.typname AS arg9, \n") + wxT(" proargnames[0] AS an0, proargnames[1] AS an1, proargnames[2] AS an2, proargnames[3] AS an3, proargnames[4] AS an4,\n") + wxT(" proargnames[5] AS an5, proargnames[6] AS an6, proargnames[7] AS an7, proargnames[8] AS an8, proargnames[9] AS an9\n") + wxT(" FROM pg_proc\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=pronamespace\n") + wxT(" JOIN pg_language l ON l.oid=prolang\n") + wxT(" JOIN pg_type tr ON tr.oid=prorettype\n") + wxT(" LEFT JOIN pg_type t0 ON t0.oid=proargtypes[0]\n") + wxT(" LEFT JOIN pg_type t1 ON t1.oid=proargtypes[1]\n") + wxT(" LEFT JOIN pg_type t2 ON t2.oid=proargtypes[2]\n") + wxT(" LEFT JOIN pg_type t3 ON t3.oid=proargtypes[3]\n") + wxT(" LEFT JOIN pg_type t4 ON t4.oid=proargtypes[4]\n") + wxT(" LEFT JOIN pg_type t5 ON t5.oid=proargtypes[5]\n") + wxT(" LEFT JOIN pg_type t6 ON t6.oid=proargtypes[6]\n") + wxT(" LEFT JOIN pg_type t7 ON t7.oid=proargtypes[7]\n") + wxT(" LEFT JOIN pg_type t8 ON t8.oid=proargtypes[8]\n") + wxT(" LEFT JOIN pg_type t9 ON t9.oid=proargtypes[9]\n") + wxT(" WHERE nspname = ") + qtDbString(remoteCluster) + ); + + while (func.RowsLeft()) + { + wxString proname = func.GetVal(wxT("proname")); + if (proname == wxT("upgradeschema")) + upgradeSchemaAvailable = true; + + sql += wxT("CREATE OR REPLACE FUNCTION " + qtIdent(proname) + wxT("("); + + wxString language = func.GetVal(wxT("lanname")); + wxString volat = func.GetVal(wxT("provolatile")); + long numArgs = func.GetLong(wxT("pronargs")); + + long i; + + for (i = 0 ; i < numArgs ; i++) + { + if (i) + sql += wxT(", "); + wxString argname = func.GetVal(wxT("an") + NumToStr(i)); + if (!argname.IsEmpty()) + sql += qtIdent(argname) + wxT(" "); + + sql += qtIdent(func.GetVal(wxT("arg") + NumToStr(i))); + } + sql += wxT(")\n") + wxT(" RETURNS "); + if (func.GetBool(wxT("proretset"))) + sql += wxT("SETOF ")); + sql += qtIdent(func.GetVal(wxT("rettype"))); + + if (language == wxT("c")) + sql += wxT("\n") + wxT("AS '" + func.GetVal(wxT("probin")) + wxT("', '") + func.GetVal(wxT("prosrc")) + wxT("'")); + else + sql += wxT(" AS\n") + wxT("$BODY$") + func.GetVal(wxT("prosrc")) + wxT("$BODY$"); + + sql += wxT(" LANGUAGE ") + language; + + if (volat == wxT("v")) + sql += wxT(" VOLATILE"); + else if (volat == wxT("i")) + sql += wxT(" IMMUTABLE"); + else + sql += wxT(" STABLE"); + + if (func.GetBool(wxT("proisstrict"))) + sql += wxT(" STRICT"); + + if (func.GetBool(wxT("prosecdef"))) + sql += wxT(" SECURITY DEFINER"); + + sql += wxT(";\n\n"); + } + } + + if (upgradeSchemaAvailable) + sql += wxT("SELECT upgradeSchema(") + qtDbString(cluster->GetClusterVersion()) + wxT(");\n\n"); + + { + // Create missing tables and columns + // we don't expect column names and types to change + + pgSetIterator srcCols(remoteConn, + wxT("SELECT relname, attname, attndims, atttypmod, attnotnull, adsrc, ty.typname, tn.nspname as typnspname,\n") + wxT(" (SELECT count(1) FROM pg_type t2 WHERE t2.typname=ty.typname) > 1 AS isdup\n") + wxT(" FROM pg_attribute\n") + wxT(" JOIN pg_class c ON c.oid=attrelid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace") + wxT(" LEFT JOIN pg_attrdef d ON adrelid=attrelid and adnum=attnum\n") + wxT(" JOIN pg_type ty ON ty.oid=atttypid\n") + wxT(" JOIN pg_namespace tn ON tn.oid=ty.typnamespace\n") + wxT(" WHERE n.nspname = ") + qtDbString(remoteCluster) + + wxT(" AND attnum>0 and relkind='r'\n") + wxT(" ORDER BY (relname != 'sl_confirm'), relname, attname") + ); + + pgSetIterator destCols(connection, + wxT("SELECT relname, attname, adsrc\n") + wxT(" FROM pg_attribute\n") + wxT(" JOIN pg_class c ON c.oid=attrelid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace") + wxT(" LEFT JOIN pg_attrdef d ON adrelid=attrelid and adnum=attnum\n") + wxT(" WHERE n.nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + + wxT(" AND attnum>0 and relkind='r'\n") + wxT(" ORDER BY (relname != 'sl_confirm'), relname, attname") + ); + + if (!destCols.RowsLeft()) + return wxT("error"); + + wxString lastTable; + while (srcCols.RowsLeft()) + { + wxString table = srcCols.GetVal(wxT("relname")); + wxString column = srcCols.GetVal(wxT("attname")); + wxString defVal = srcCols.GetVal(wxT("adsrc")); + + if (table == wxT("sl_node")) + { + table = wxT("sl_node"); + } + pgDatatype dt(srcCols.GetVal(wxT("typnspname")), srcCols.GetVal(wxT("typname")), + srcCols.GetBool(wxT("isdup")), + srcCols.GetLong(wxT("attndims")), srcCols.GetLong(wxT("atttypmod"))); + + + if (destCols.Set()->Eof() || + destCols.GetVal(wxT("relname")) != table || + destCols.GetVal(wxT("attname")) != column) + { + if (table == lastTable || table == destCols.GetVal(wxT("relname"))) + { + // just an additional column + sql += wxT("ALTER TABLE ") + qtIdent(table) + + wxT(" ADD COLUMN ") + qtIdent(column) + + wxT(" ") + dt.GetQuotedSchemaPrefix(0) + dt.QuotedFullName(); + + if (!defVal.IsEmpty()) + sql += wxT(" DEFAULT ") + defVal; + if (srcCols.GetBool(wxT("attnotnull"))) + sql += wxT(" NOT NULL"); + + sql += wxT(";\n"); + } + else + { + // new table + // sl_confirm will always exist and be the first so no need for special + // precautions in case a new table is the very first in the set + + sql += wxT("CREATE TABLE ") + qtIdent(table) + + wxT(" (") + qtIdent(column) + + wxT(" ") + dt.GetQuotedSchemaPrefix(0) + dt.QuotedFullName(); + + if (!defVal.IsEmpty()) + sql += wxT(" DEFAULT ") + defVal; + + sql += wxT(");\n"); + } + } + else + { + // column is found + if (destCols.GetVal(wxT("adsrc")) != defVal) + { + sql += wxT("ALTER TABLE ") + qtIdent(table) + + wxT(" ALTER COLUMN ") + qtIdent(column); + if (defVal.IsEmpty()) + sql += wxT(" DROP DEFAULT;\n"); + else + sql += wxT(" SET DEFAULT ") + defVal + wxT(";\n"); + } + destCols.RowsLeft(); + } + lastTable = table; + } + } + + { + // check missing indexes + pgSetIterator srcIndexes(remoteConn, + wxT("SELECT t.relname, indkey, ti.relname as indname, pg_get_indexdef(indexrelid) AS inddef\n") + wxT(" FROM pg_index i\n") + wxT(" JOIN pg_class ti ON indexrelid=ti.oid\n") + wxT(" JOIN pg_class t ON indrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=t.relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(remoteCluster) + + wxT(" ORDER BY t.relname, ti.relname, indkey")); + + pgSetIterator destIndexes(remoteConn, + wxT("SELECT t.relname, indkey, ti.relname as indnamen") + wxT(" FROM pg_index i\n") + wxT(" JOIN pg_class ti ON indexrelid=ti.oid\n") + wxT(" JOIN pg_class t ON indrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=t.relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + + wxT(" ORDER BY t.relname, ti.relname, indkey")); + + if (!destIndexes.RowsLeft()) + return wxT("error"); + + while (srcIndexes.RowsLeft()) + { + wxString table = srcIndexes.GetVal(wxT("relname")); + + bool needUpdate = destIndexes.Set()->Eof() || + destIndexes.GetVal(wxT("relname")) != table; + + if (!needUpdate && destIndexes.GetVal(wxT("indkey")) != srcIndexes.GetVal(wxT("indkey"))) + { + // better ignore index name and check column names here + needUpdate = destIndexes.GetVal(wxT("indname")) != srcIndexes.GetVal(wxT("indname")); + } + if (needUpdate) + { + wxString inddef = srcIndexes.GetVal(wxT("inddef")); + inddef.Replace(qtIdent(remoteCluster) + wxT("."), qtIdent(wxT("_") + cluster->GetName()) + wxT(".")); + sql += inddef + wxT(";\n"); + } + else + destIndexes.RowsLeft(); + } + } + + { + // check missing constraints + // we don't expect constraint definitions to change + + pgSetIterator srcConstraints(remoteConn, + wxT("SELECT t.relname, contype, conkey, conname,\n") + wxT(" pg_get_constraintdef(c.oid) AS condef\n") + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class t ON c.conrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(remoteCluster) + wxT("\n") + wxT(" ORDER BY (contype != 'p'), relname, contype, conname, conkey") + ); + + pgSetIterator destConstraints(connection, + wxT("SELECT t.relname, contype, conkey, conname\n") + wxT(" FROM pg_constraint c\n") + wxT(" JOIN pg_class t ON c.conrelid=t.oid\n") + wxT(" JOIN pg_namespace n ON n.oid=relnamespace\n") + wxT(" WHERE nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + wxT("\n") + wxT(" ORDER BY (contype != 'p'), relname, contype, conname, conkey") + ); + + if (!destConstraints.RowsLeft()) + return wxT("error"); + + while (srcConstraints.RowsLeft()) + { + wxString table = srcConstraints.GetVal(wxT("relname")); + wxString contype = srcConstraints.GetVal(wxT("contype")); + + bool needUpdate = destConstraints.Set()->Eof() || + destConstraints.GetVal(wxT("relname")) != table || + destConstraints.GetVal(wxT("contype")) != contype; + if (!needUpdate && destConstraints.GetVal(wxT("conkey")) != srcConstraints.GetVal(wxT("conkey"))) + { + // better ignore constraint name and compare column names here + needUpdate = destConstraints.GetVal(wxT("conname")) != srcConstraints.GetVal(wxT("conname")); + } + if (needUpdate) + { + wxString condef = srcConstraints.GetVal(wxT("condef")); + condef.Replace(qtIdent(remoteCluster) + wxT("."), qtIdent(wxT("_") + cluster->GetName()) + wxT(".")); + + sql += wxT("ALTER TABLE ") + qtIdent(table) + + wxT(" ADD CONSTRAINT ") + qtIdent(srcConstraints.GetVal(wxT("conname"))) + + wxT(" ") + condef + + wxT(";\n"); + } + else + destConstraints.RowsLeft(); + } + + sql += wxT("\nNOTIFY ") + qtIdent(wxT("_") + cluster->GetName() + wxT("_Restart")) + + wxT(";\n\n"); + } + } + return sql; +} + + +pgObject *dlgRepClusterUpgrade::CreateObject(pgCollection *collection) +{ + return 0; +} + + +void dlgRepClusterUpgrade::OnChangeCluster(wxCommandEvent &ev) +{ + version = wxEmptyString; + sql = wxEmptyString; + + int sel = cbClusterName->GetCurrentSelection(); + if (remoteConn && sel >= 0) + { + wxString schemaPrefix = qtIdent(wxT("_") + cbClusterName->GetValue()) + wxT("."); + + version = remoteConn->ExecuteScalar(wxT("SELECT ") + schemaPrefix + wxT("slonyversion();")); + } + OnChange(ev); + + + txtVersion->SetValue(version); + OnChange(ev); +} diff --git a/slony/dlgRepListen.cpp b/slony/dlgRepListen.cpp new file mode 100644 index 0000000..3cb5993 --- /dev/null +++ b/slony/dlgRepListen.cpp @@ -0,0 +1,159 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepListen.cpp - PostgreSQL Slony-I Listen Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepListen.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slListen.h" +#include "schema/pgDatatype.h" + +// pointer to controls + +#define cbOrigin CTRL_COMBOBOX("cbOrigin") +#define txtReceiver CTRL_TEXT("txtReceiver") +#define cbProvider CTRL_COMBOBOX("cbProvider") + + + + +BEGIN_EVENT_TABLE(dlgRepListen, dlgProperty) + EVT_COMBOBOX(XRCID("cbOrigin"), dlgRepListen::OnChange) + EVT_COMBOBOX(XRCID("cbProvider"), dlgRepListen::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *slListenFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepListen(this, frame, (slListen *)node, (slNode *)parent); +} + +dlgRepListen::dlgRepListen(pgaFactory *f, frmMain *frame, slListen *l, slNode *n) + : dlgRepProperty(f, frame, n->GetCluster(), wxT("dlgRepListen")) +{ + listen = l; + node = n; +} + + +pgObject *dlgRepListen::GetObject() +{ + return listen; +} + + +int dlgRepListen::Go(bool modal) +{ + txtReceiver->SetValue(IdAndName(node->GetSlId(), node->GetName())); + txtReceiver->Disable(); + + if (listen) + { + // edit mode + cbOrigin->Append(IdAndName(listen->GetSlId(), listen->GetName())); + cbOrigin->SetSelection(0); + cbProvider->Append(IdAndName(listen->GetProviderId(), listen->GetProviderName())); + cbProvider->SetSelection(0); + cbOrigin->Disable(); + cbProvider->Disable(); + } + else + { + // create mode + + pgSet *nodes = connection->ExecuteSet( + wxT("SELECT no_id, no_comment, pa_server\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_path ON pa_server=no_id") + wxT(" AND pa_client=") + NumToStr(node->GetSlId()) + wxT("\n") + wxT(" WHERE no_id <> ") + NumToStr(node->GetSlId()) + wxT("\n") + wxT(" ORDER BY no_id") + ); + + if (nodes) + { + while (!nodes->Eof()) + { + long id = nodes->GetLong(wxT("no_id")); + wxString name = IdAndName(id, nodes->GetVal(wxT("no_comment"))); + + cbOrigin->Append(name, (void *)id); + + if (nodes->GetLong(wxT("pa_server")) > 0) + cbProvider->Append(name, (void *)id); + + nodes->MoveNext(); + } + delete nodes; + } + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepListen::CreateObject(pgCollection *collection) +{ + pgObject *obj = listenFactory.CreateObjects(collection, 0, + wxT(" WHERE li_origin = ") + NumToStr((OID)cbOrigin->wxItemContainer::GetClientData(cbOrigin->GetCurrentSelection())) + + wxT(" AND li_receiver = ") + NumToStr(node->GetSlId()) + + wxT(" AND li_provider = ") + NumToStr((OID)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())) + ); + + return obj; +} + + + + +void dlgRepListen::CheckChange() +{ + if (listen) + { + } + else + { + bool enable = true; + CheckValid(enable, cbProvider->GetCount() > 0, _("No path to any provider node; add proper path.")); + CheckValid(enable, cbOrigin->GetCurrentSelection() >= 0, _("Please select origin node of replication events.")); + CheckValid(enable, cbProvider->GetCurrentSelection() >= 0, _("Please select provider node for replication events.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepListen::GetSql() +{ + wxString sql; + + if (listen) + { + // edit mode + } + else + { + // create mode + + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storelisten(") + + NumToStr((OID)cbOrigin->wxItemContainer::GetClientData(cbOrigin->GetCurrentSelection())) + wxT(", ") + + NumToStr((OID)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())) + wxT(", ") + + NumToStr(node->GetSlId()) + wxT(");"); + } + + return sql; +} diff --git a/slony/dlgRepNode.cpp b/slony/dlgRepNode.cpp new file mode 100644 index 0000000..57aacee --- /dev/null +++ b/slony/dlgRepNode.cpp @@ -0,0 +1,122 @@ +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepNode.cpp - PostgreSQL Slony-I Node Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + + +#include "slony/dlgRepNode.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") + + + +BEGIN_EVENT_TABLE(dlgRepNode, dlgProperty) +END_EVENT_TABLE(); + + +dlgProperty *slNodeFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepNode(this, frame, (slNode *)node, (slCluster *)parent); +} + +dlgRepNode::dlgRepNode(pgaFactory *f, frmMain *frame, slNode *s, slCluster *c) + : dlgRepProperty(f, frame, c, wxT("dlgRepNode")) +{ + node = s; +} + + +pgObject *dlgRepNode::GetObject() +{ + return node; +} + + +int dlgRepNode::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (node) + { + // edit mode + txtID->SetValue(NumToStr(node->GetSlId())); + txtID->Disable(); + } + else + { + // create mode + EnableOK(true); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepNode::CreateObject(pgCollection *collection) +{ + wxString restriction; + if (StrToLong(txtID->GetValue()) > 0) + restriction = txtID->GetValue(); + else + restriction = wxT("(SELECT MAX(no_id) FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node)"); + + pgObject *obj = nodeFactory.CreateObjects(collection, 0, + wxT(" WHERE no_id = ") + restriction); + + return obj; +} + + +void dlgRepNode::CheckChange() +{ + if (node) + { + EnableOK(txtComment->GetValue() != node->GetComment()); + } + else + { + bool enable = true; + + EnableOK(enable); + } +} + + + +wxString dlgRepNode::GetSql() +{ + wxString sql; + + sql = wxT("-- Create replication node\n\n") + wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storenode("); + + if (StrToLong(txtID->GetValue()) > 0) + sql += txtID->GetValue(); + else + sql += wxT("(SELECT COALESCE(MAX(no_id), 0) + 1 FROM ") + + cluster->GetSchemaPrefix() + wxT("sl_node)"); + + sql += wxT(", ") + qtDbString(txtComment->GetValue()); + + // The spool parameter was removed for Slony 2.0 + if (!cluster->ClusterMinimumVersion(2, 0)) + sql += wxT(", false"); + + sql += wxT(");\n"); + + return sql; +} diff --git a/slony/dlgRepPath.cpp b/slony/dlgRepPath.cpp new file mode 100644 index 0000000..dc10acd --- /dev/null +++ b/slony/dlgRepPath.cpp @@ -0,0 +1,154 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepPath.cpp - PostgreSQL Slony-I Path Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepPath.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slPath.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define cbServer CTRL_COMBOBOX("cbServer") +#define txtConnInfo CTRL_TEXT("txtConnInfo") +#define txtConnRetry CTRL_TEXT("txtConnRetry") + + +BEGIN_EVENT_TABLE(dlgRepPath, dlgProperty) + EVT_TEXT(XRCID("txtConnInfo"), dlgRepPath::OnChange) + EVT_COMBOBOX(XRCID("cbServer"), dlgRepPath::OnChange) +END_EVENT_TABLE(); + +dlgProperty *slPathFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepPath(this, frame, (slPath *)node, (slNode *)parent); +} + + +dlgRepPath::dlgRepPath(pgaFactory *f, frmMain *frame, slPath *p, slNode *n) + : dlgRepProperty(f, frame, n->GetCluster(), wxT("dlgRepPath")) +{ + path = p; + node = n; +} + + +pgObject *dlgRepPath::GetObject() +{ + return path; +} + + +int dlgRepPath::Go(bool modal) +{ + + if (path) + { + // edit mode + cbServer->Append(IdAndName(path->GetSlId(), path->GetName()), (void *)path->GetSlId()); + cbServer->SetSelection(0); + cbServer->Disable(); + + txtConnInfo->SetValue(path->GetConnInfo()); + txtConnRetry->SetValue(NumToStr(path->GetConnRetry())); + } + else + { + // create mode + + txtConnRetry->SetValue(wxT("10")); + + pgSet *nodes = connection->ExecuteSet( + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_path ON pa_client=\n") + NumToStr(node->GetSlId()) + + wxT(" AND pa_server=no_id\n") + wxT(" WHERE no_active AND pa_client IS NULL\n") + wxT(" AND no_id <> ") + NumToStr(node->GetSlId()) + wxT("\n") + wxT(" ORDER BY no_id") + ); + + if (nodes) + { + while (!nodes->Eof()) + { + cbServer->Append(IdAndName(nodes->GetLong(wxT("no_id")), nodes->GetVal(wxT("no_comment"))), + (void *)nodes->GetLong(wxT("no_id"))); + nodes->MoveNext(); + } + delete nodes; + } + if (cbServer->GetCount() > 0) + cbServer->SetSelection(0); + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepPath::CreateObject(pgCollection *collection) +{ + pgObject *obj = pathFactory.CreateObjects(collection, 0, + wxT(" WHERE pa_server = ") + NumToStr((OID)cbServer->wxItemContainer::GetClientData(cbServer->GetCurrentSelection())) + + wxT(" AND pa_client = ") + NumToStr(node->GetSlId())); + + return obj; +} + + + + +void dlgRepPath::CheckChange() +{ + if (path) + { + EnableOK(txtConnInfo->GetValue() != path->GetConnInfo() + || StrToLong(txtConnRetry->GetValue()) != path->GetConnRetry()); + } + else + { + bool enable = true; + CheckValid(enable, cbServer->GetCount() > 0, _("No provider node without path definition left.")); + CheckValid(enable, cbServer->GetCurrentSelection() >= 0, _("Please select provider node.")); + + wxString connInfo = txtConnInfo->GetValue(); + CheckValid(enable, connInfo.Find(wxT("host=")) >= 0, _("Please provide host in connect info.")); + CheckValid(enable, connInfo.Find(wxT("dbname=")) >= 0, _("Please provide dbname in connect info.")); + CheckValid(enable, connInfo.Find(wxT("user=")) >= 0, _("Please provide user in connect info.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepPath::GetSql() +{ + wxString sql; + + int sel = cbServer->GetCurrentSelection(); + + if (sel >= 0) + { + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storepath(") + + NumToStr((OID)cbServer->wxItemContainer::GetClientData(sel)) + wxT(", ") + + NumToStr(node->GetSlId()) + wxT(", ") + + qtDbString(txtConnInfo->GetValue()) + wxT(", ") + + NumToStr(StrToLong(txtConnRetry->GetValue())) + wxT(");"); + } + return sql; +} diff --git a/slony/dlgRepProperty.cpp b/slony/dlgRepProperty.cpp new file mode 100644 index 0000000..d589fcf --- /dev/null +++ b/slony/dlgRepProperty.cpp @@ -0,0 +1,25 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepProperty.cpp - PostgreSQL Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "slony/dlgRepProperty.h" +#include "slony/slCluster.h" + + +dlgRepProperty::dlgRepProperty(pgaFactory *f, frmMain *frame, slCluster *c, const wxString &resName) + : dlgProperty(f, frame, resName) +{ + cluster = c; +} diff --git a/slony/dlgRepSequence.cpp b/slony/dlgRepSequence.cpp new file mode 100644 index 0000000..33e2e91 --- /dev/null +++ b/slony/dlgRepSequence.cpp @@ -0,0 +1,166 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSequence.cpp - PostgreSQL Slony-I Sequence Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepSequence.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "slony/slSequence.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define cbSequence CTRL_COMBOBOX2("cbSequence") + + + +BEGIN_EVENT_TABLE(dlgRepSequence, dlgProperty) + EVT_TEXT(XRCID("txtID"), dlgRepSequence::OnChange) + EVT_TEXT(XRCID("cbSequence"), dlgRepSequence::OnChange) + EVT_COMBOBOX(XRCID("cbSequence"), dlgRepSequence::OnChangeSel) + EVT_TEXT(XRCID("cbSequence"), dlgRepSequence::OnChange) +END_EVENT_TABLE(); + +dlgProperty *slSlSequenceFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepSequence(this, frame, (slSequence *)node, (slSet *)parent); +} + + +dlgRepSequence::dlgRepSequence(pgaFactory *f, frmMain *frame, slSequence *node, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSequence")) +{ + sequence = node; + set = s; +} + + +pgObject *dlgRepSequence::GetObject() +{ + return sequence; +} + + +int dlgRepSequence::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (sequence) + { + // edit mode + cbSequence->Append(sequence->GetName()); + cbSequence->SetSelection(0); + + txtID->SetValue(NumToStr(sequence->GetSlId())); + + cbSequence->Disable(); + txtComment->Disable(); + txtID->Disable(); + } + else + { + // create mode + + wxString restriction; + if (!settings->GetShowSystemObjects()) + restriction = wxT("\n AND ") + connection->SystemNamespaceRestriction(wxT("nspname")); + + pgSet *tabs = connection->ExecuteSet( + wxT("SELECT DISTINCT cl.oid, nspname, relname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace nsp ON relnamespace=nsp.oid\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_sequence s ON s.seq_reloid=cl.oid\n") + wxT(" WHERE s.seq_id IS NULL AND cl.relkind = 'S'") + restriction + wxT("\n") + wxT(" ORDER BY nspname, relname") + ); + + if (tabs) + { + while (!tabs->Eof()) + { + cbSequence->Append(tabs->GetVal(wxT("nspname")) + wxT(".") + tabs->GetVal(wxT("relname")), + (void *)tabs->GetOid(wxT("oid"))); + tabs->MoveNext(); + } + delete tabs; + } + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepSequence::CreateObject(pgCollection *collection) +{ + pgObject *obj = slSequenceFactory.CreateObjects(collection, 0, + wxT(" WHERE seq_reloid = ") + NumToStr((OID)cbSequence->wxItemContainer::GetClientData(cbSequence->GetGuessedSelection()))); + + return obj; +} + + +void dlgRepSequence::OnChangeSel(wxCommandEvent &ev) +{ + cbSequence->GuessSelection(ev); + OnChange(ev); +} + + +void dlgRepSequence::CheckChange() +{ + if (sequence) + { + EnableOK(txtComment->GetValue() != sequence->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, cbSequence->GetGuessedSelection() >= 0, _("Please select sequence to replicate.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepSequence::GetSql() +{ + wxString sql; + + if (sequence) + { + // edit mode + } + else + { + // create mode + + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("setaddsequence(") + + NumToStr(set->GetSlId()) + wxT(", "); + + if (StrToLong(txtID->GetValue()) > 0) + sql += txtID->GetValue(); + else + sql += wxT("(SELECT COALESCE(MAX(seq_id), 0) + 1 FROM ") + cluster->GetSchemaPrefix() + wxT("sl_sequence)"); + + sql += wxT(", ") + qtDbString(cbSequence->GetGuessedStringSelection()) + + wxT(", ") + qtDbString(txtComment->GetValue()) + + wxT(")\n"); + } + + return sql; +} diff --git a/slony/dlgRepSet.cpp b/slony/dlgRepSet.cpp new file mode 100644 index 0000000..db3491c --- /dev/null +++ b/slony/dlgRepSet.cpp @@ -0,0 +1,332 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSet.cpp - PostgreSQL Slony-I Set Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepSet.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slSet.h" +#include "frm/frmMain.h" + + +// pointer to controls +#define txtOrigin CTRL_TEXT("txtOrigin") +#define txtID CTRL_TEXT("txtID") + + + +BEGIN_EVENT_TABLE(dlgRepSet, dlgProperty) +END_EVENT_TABLE(); + + +dlgProperty *slSetFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepSet(this, frame, (slSet *)node, (slCluster *)parent); +} + +dlgRepSet::dlgRepSet(pgaFactory *f, frmMain *frame, slSet *s, slCluster *c) + : dlgRepProperty(f, frame, c, wxT("dlgRepSet")) +{ + set = s; +} + + +int dlgRepSet::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (set) + { + // edit mode + txtID->SetValue(NumToStr(set->GetSlId())); + txtID->Disable(); + txtOrigin->SetValue(IdAndName(set->GetOriginId(), set->GetOriginNode())); + txtComment->Disable(); + } + else + { + // create mode + txtOrigin->SetValue(IdAndName(cluster->GetLocalNodeID(), cluster->GetLocalNodeName())); + EnableOK(true); + } + + txtOrigin->Disable(); + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepSet::CreateObject(pgCollection *collection) +{ + wxString restriction; + if (StrToLong(txtID->GetValue()) > 0) + restriction = txtID->GetValue(); + else + restriction = wxT("(SELECT MAX(set_id) FROM ") + cluster->GetSchemaPrefix() + wxT("sl_set)"); + + pgObject *obj = setFactory.CreateObjects(collection, 0, + wxT(" WHERE set_id = ") + restriction); + + return obj; +} + + +void dlgRepSet::CheckChange() +{ + if (set) + { + EnableOK(txtComment->GetValue() != set->GetComment()); + } + else + { + bool enable = (!txtComment->IsEmpty()); + + EnableOK(enable); + } +} + + + +wxString dlgRepSet::GetSql() +{ + wxString sql; + + sql = wxT("-- Create replication set\n\n") + wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storeset("); + + if (StrToLong(txtID->GetValue()) > 0) + sql += txtID->GetValue(); + else + sql += wxT("(SELECT COALESCE(MAX(set_id), 0) + 1 FROM ") + + cluster->GetSchemaPrefix() + wxT("sl_set)"); + + sql += wxT(", ") + qtDbString(txtComment->GetValue()) + + wxT(");\n"); + + return sql; +} + + +//////////////////////////////////////////////////////////////////////////////////////// + + +#define cbTargetID CTRL_COMBOBOX("cbTargetID") + +BEGIN_EVENT_TABLE(dlgRepSetMerge, dlgProperty) + EVT_COMBOBOX(XRCID("cbTargetID"), dlgRepSetMerge::OnChange) +END_EVENT_TABLE(); + + +dlgRepSetMerge::dlgRepSetMerge(pgaFactory *f, frmMain *frame, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSetMerge")) +{ + set = s; +} + + +int dlgRepSetMerge::Go(bool modal) +{ + txtID->SetValue(IdAndName(set->GetSlId(), set->GetName())); + txtID->Disable(); + + wxString sql = + wxT("SELECT set_id, set_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_set\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_subscribe ON set_id=sub_set\n") + wxT(" WHERE set_origin = ") + NumToStr(cluster->GetLocalNodeID()) + + wxT(" AND set_id <> ") + NumToStr(set->GetSlId()); + + if (set->GetSubscriptionCount() > 0) + sql += wxT("\n") + wxT(" GROUP BY set_id, set_comment\n") + wxT("HAVING COUNT(sub_set) > 0"); + else + sql += wxT("\n") + wxT(" AND sub_set IS NULL"); + + pgSet *sets = connection->ExecuteSet(sql); + + if (sets) + { + while (!sets->Eof()) + { + long id = sets->GetLong(wxT("set_id")); + cbTargetID->Append(IdAndName(id, sets->GetVal(wxT("set_comment"))), (void *)id); + sets->MoveNext(); + } + delete sets; + } + + return dlgProperty::Go(modal); +} + + +void dlgRepSetMerge::CheckChange() +{ + bool enable = true; + + CheckValid(enable, cbTargetID->GetCount() > 0 , _("No set available to merge to.")); + CheckValid(enable, cbTargetID->GetCurrentSelection() >= 0, _("Please select replication set to merged to.")); + EnableOK(enable); +} + + +wxString dlgRepSetMerge::GetSql() +{ + wxString sql; + wxString addId = NumToStr(set->GetSlId()); + wxString toId = NumToStr((long)cbTargetID->wxItemContainer::GetClientData(cbTargetID->GetCurrentSelection())); + wxString prefix = cluster->GetSchemaPrefix(); + + if (set->GetSubscriptionCount() > 0) + { + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("mergeset(") + toId + wxT(", ") + addId + wxT(");\n"); + } + else + { + sql = wxT("-- remember objects to replicate\n") + wxT("CREATE TEMPORARY TABLE pga_tmp_repl_tables(tab_id int4, tabname text, idxname text, comment text, trgname text);\n") + wxT("INSERT INTO pga_tmp_repl_tables(tab_id, tabname, idxname, comment, trgname)\n"); + + if (cluster->ClusterMinimumVersion(2, 0)) + { + sql += wxT("SELECT tab_id, nsp.nspname || '.' || relname, tab_idxname, tab_comment, tgname\n") + wxT(" FROM ") + prefix + wxT("sl_table\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" LEFT JOIN pg_trigger t ON t.tgrelid = tab_reloid\n") + wxT(" JOIN pg_proc p ON t.tgfoid = p.oid\n") + wxT(" JOIN pg_namespace np ON p.pronamespace = np.oid\n") + wxT(" WHERE tab_set = ") + addId + + wxT(" AND np.nspname = ") + qtDbString(wxT("_") + cluster->GetName()) + wxT(";\n"); + } + else + { + sql += wxT("SELECT tab_id, nspname || '.' || relname, tab_idxname, tab_comment, trig_tgname\n") + wxT(" FROM ") + prefix + wxT("sl_table\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" LEFT JOIN ") + prefix + wxT("sl_trigger ON tab_id=trig_tabid") + wxT(" WHERE tab_set = ") + addId + wxT(";\n"); + } + + sql += wxT("\n") + wxT("CREATE TEMPORARY TABLE pga_tmp_repl_seqs(seq_id int4, seqname text, comment text);\n") + wxT("INSERT INTO pga_tmp_repl_seqs(seq_id, seqname, comment)\n") + wxT("SELECT seq_id, nspname ||'.' || relname, seq_comment\n") + wxT(" FROM ") + prefix + wxT("sl_sequence\n") + wxT(" JOIN pg_class cl ON cl.oid=seq_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" WHERE seq_set = ") + addId + wxT(";\n") + wxT("\n") + + wxT("-- drop objects in old set: tables, sequences\n") + wxT("SELECT ") + prefix + wxT("setdroptable(tab_id)\n") + wxT(" FROM (SELECT DISTINCT tab_id FROM pga_tmp_repl_tables) AS tmp;\n") + wxT("\n") + wxT("SELECT ") + prefix + wxT("setdropsequence(seq_id)\n") + wxT(" FROM pga_tmp_repl_seqs;\n") + wxT("\n") + + wxT("-- add objects to new set: tables, triggers, sequences\n") + wxT("SELECT ") + prefix + wxT("setaddtable(") + toId + wxT(", tab_id, tabname, idxname, comment)\n") + wxT(" FROM (SELECT DISTINCT tab_id, tabname, idxname, comment FROM pga_tmp_repl_tables) AS tmp;\n") + wxT("\n"); + + if (!cluster->ClusterMinimumVersion(2, 0)) + { + sql += wxT("SELECT ") + prefix + wxT("storetrigger(tab_id, trgname)\n") + wxT(" FROM pga_tmp_repl_tables WHERE trgname IS NOT NULL;\n") + wxT("\n"); + } + + sql += wxT("SELECT ") + prefix + wxT("setaddsequence(") + toId + wxT(", seq_id, seqname, comment)\n") + wxT(" FROM pga_tmp_repl_seqs;\n") + wxT("\n") + + wxT("-- finally, drop old set\n") + wxT("SELECT ") + prefix + wxT("dropset(") + addId + wxT(");\n") + wxT("\n") + wxT("-- cleanup\n") + wxT("DROP TABLE pga_tmp_repl_tables;\n") + wxT("DROP TABLE pga_tmp_repl_seqs;\n"); + } + + return sql; +} + + +//////////////////////////////////////////////////////////////////////////////////////// + + +#define cbTargetNode CTRL_COMBOBOX("cbTargetNode") + +BEGIN_EVENT_TABLE(dlgRepSetMove, dlgProperty) + EVT_COMBOBOX(XRCID("cbTargetNode"), dlgRepSetMove::OnChange) +END_EVENT_TABLE(); + + +dlgRepSetMove::dlgRepSetMove(pgaFactory *f, frmMain *frame, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSetMove")) +{ + set = s; +} + + +int dlgRepSetMove::Go(bool modal) +{ + txtID->SetValue(IdAndName(set->GetSlId(), set->GetName())); + txtID->Disable(); + + pgSet *nodes = connection->ExecuteSet( + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_subscribe ON sub_receiver=no_id\n") + wxT(" WHERE sub_set = ") + NumToStr(set->GetSlId())); + + if (nodes) + { + while (!nodes->Eof()) + { + long id = nodes->GetLong(wxT("no_id")); + cbTargetNode->Append(IdAndName(id, nodes->GetVal(wxT("no_comment"))), (void *)id); + nodes->MoveNext(); + } + delete nodes; + } + return dlgProperty::Go(modal); +} + + +void dlgRepSetMove::CheckChange() +{ + bool enable = true; + + CheckValid(enable, cbTargetNode->GetCount() > 0 , _("No node available to move this set to.")); + CheckValid(enable, cbTargetNode->GetCurrentSelection() >= 0, _("Please select node to move this replication set to.")); + EnableOK(enable); +} + + +wxString dlgRepSetMove::GetSql() +{ + wxString toId = NumToStr((long)cbTargetNode->wxItemContainer::GetClientData(cbTargetNode->GetCurrentSelection())); + + wxString sql = + wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("moveset(") + + NumToStr(set->GetSlId()) + wxT(", ") + toId + wxT(");\n"); + return sql; +} diff --git a/slony/dlgRepSubscription.cpp b/slony/dlgRepSubscription.cpp new file mode 100644 index 0000000..8e0d565 --- /dev/null +++ b/slony/dlgRepSubscription.cpp @@ -0,0 +1,182 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepSubscription.cpp - PostgreSQL Slony-I Subscription Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepSubscription.h" +#include "slony/slCluster.h" +#include "slony/slSubscription.h" +#include "slony/slSet.h" + + + +// pointer to controls +#define txtOrigin CTRL_TEXT("txtOrigin") +#define stReceiver CTRL_STATIC("stReceiver") +#define txtReceiver CTRL_TEXT("txtReceiver") +#define cbProvider CTRL_COMBOBOX("cbProvider") +#define stProvider CTRL_TEXT("stProvider") +#define chkForward CTRL_CHECKBOX("chkForward") + + + +BEGIN_EVENT_TABLE(dlgRepSubscription, dlgProperty) + EVT_COMBOBOX(XRCID("cbProvider"), dlgRepSubscription::OnChange) + EVT_CHECKBOX(XRCID("chkForward"), dlgRepSubscription::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *slSubscriptionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepSubscription(this, frame, (slSubscription *)node, (slSet *)parent); +} + +dlgRepSubscription::dlgRepSubscription(pgaFactory *f, frmMain *frame, slSubscription *sub, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepSubscription")) +{ + subscription = sub; + set = s; +} + + +pgObject *dlgRepSubscription::GetObject() +{ + return subscription; +} + + +int dlgRepSubscription::Go(bool modal) +{ + txtOrigin->SetValue(NumToStr(set->GetOriginId())); + if (subscription) + { + // edit mode + chkForward->SetValue(subscription->GetForward()); + txtReceiver->SetValue(IdAndName(subscription->GetReceiverId(), subscription->GetReceiverNode())); + } + else + { + // create mode + txtReceiver->SetValue(IdAndName(cluster->GetLocalNodeID(), cluster->GetLocalNodeName())); + + if (cluster->ClusterMinimumVersion(1, 1)) + { + // This is very ugly: starting with Slony-I 1.1, this must be called on the provider, + // not on the receiver. + stProvider->SetLabel(_("Receiver")); + stReceiver->SetLabel(_("Provider")); + } + } + + if (set->GetOriginId() == cluster->GetLocalNodeID() && subscription) + { + chkForward->SetValue(subscription->GetForward()); + cbProvider->Append(IdAndName(subscription->GetProviderId(), subscription->GetProviderNode())); + cbProvider->SetSelection(0); + cbProvider->Disable(); + chkForward->Disable(); + EnableOK(false); + } + else + { + pgSet *sets = connection->ExecuteSet( + wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + cluster->GetSchemaPrefix() + wxT("sl_node\n") + wxT(" WHERE no_active AND no_id <> ") + NumToStr(cluster->GetLocalNodeID())); + + if (sets) + { + while (!sets->Eof()) + { + cbProvider->Append(IdAndName(sets->GetLong(wxT("no_id")), sets->GetVal(wxT("no_comment"))), + (void *)sets->GetLong(wxT("no_id"))); + + if (subscription && sets->GetLong(wxT("no_id")) == subscription->GetProviderId()) + cbProvider->SetSelection(cbProvider->GetCount() - 1); + sets->MoveNext(); + } + delete sets; + } + } + if (!subscription && cbProvider->GetCount()) + { + cbProvider->SetSelection(0); + EnableOK(true); + } + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepSubscription::CreateObject(pgCollection *collection) +{ + pgObject *obj = slsubscriptionFactory.CreateObjects(collection, 0, + wxT(" WHERE set_id = ") + NumToStr(set->GetSlId()) + + wxT(" AND sub_receiver = ") + NumToStr(cluster->GetLocalNodeID())); + + return obj; +} + + +void dlgRepSubscription::CheckChange() +{ + if (subscription) + { + int sel = cbProvider->GetCurrentSelection(); + + EnableOK(sel >= 0 && (chkForward->GetValue() != subscription->GetForward() + || (long)cbProvider->wxItemContainer::GetClientData(sel) != subscription->GetProviderId())); + } + else + { + bool enable = true; + + EnableOK(enable); + } +} + + + +wxString dlgRepSubscription::GetSql() +{ + wxString sql; + + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("subscribeset(") + + NumToStr(set->GetSlId()) + wxT(", "); + + if (cluster && cluster->ClusterMinimumVersion(1, 1)) + { + // Actually, provider and receiver are exchanged here. + sql += NumToStr(cluster->GetLocalNodeID()) + wxT(", ") + + NumToStr((long)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())); + } + else + { + sql += NumToStr((long)cbProvider->wxItemContainer::GetClientData(cbProvider->GetCurrentSelection())) + wxT(", ") + + NumToStr(cluster->GetLocalNodeID()); + } + sql += wxT(", ") + + BoolToStr(chkForward->GetValue()); + + // Omit copy? + if (cluster && cluster->ClusterMinimumVersion(2, 0) && + cluster->GetClusterVersion() != wxT("2.0.0") && + cluster->GetClusterVersion() != wxT("2.0.1") && + cluster->GetClusterVersion() != wxT("2.0.2")) + sql += wxT(", false"); + + sql += wxT(");"); + + return sql; +} diff --git a/slony/dlgRepTable.cpp b/slony/dlgRepTable.cpp new file mode 100644 index 0000000..e0b1a1d --- /dev/null +++ b/slony/dlgRepTable.cpp @@ -0,0 +1,317 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// dlgRepTable.cpp - PostgreSQL Slony-I Table Property +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" + +#include "slony/dlgRepTable.h" +#include "slony/slCluster.h" +#include "slony/slSet.h" +#include "slony/slTable.h" +#include "schema/pgDatatype.h" + + +// pointer to controls +#define txtID CTRL_TEXT("txtID") +#define cbTable CTRL_COMBOBOX2("cbTable") +#define cbIndex CTRL_COMBOBOX("cbIndex") +#define chkTrigger CTRL_CHECKLISTBOX("chkTrigger") + + + +BEGIN_EVENT_TABLE(dlgRepTable, dlgRepProperty) + EVT_TEXT(XRCID("txtID"), dlgRepTable::OnChange) + EVT_COMBOBOX(XRCID("cbTable"), dlgRepTable::OnChangeTableSel) + EVT_TEXT(XRCID("cbTable"), dlgRepTable::OnChangeTable) + EVT_COMBOBOX(XRCID("cbIndex"), dlgRepTable::OnChange) + EVT_CHECKLISTBOX(XRCID("chkTrigger"), dlgRepTable::OnChange) +END_EVENT_TABLE(); + + +dlgProperty *slSlTableFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + return new dlgRepTable(this, frame, (slTable *)node, (slSet *)parent); +} + + +dlgRepTable::dlgRepTable(pgaFactory *f, frmMain *frame, slTable *node, slSet *s) + : dlgRepProperty(f, frame, s->GetCluster(), wxT("dlgRepTable")) +{ + table = node; + set = s; +} + + +pgObject *dlgRepTable::GetObject() +{ + return table; +} + + +int dlgRepTable::Go(bool modal) +{ + txtID->SetValidator(numericValidator); + + if (table) + { + // edit mode + cbTable->Append(table->GetName(), (void *)0); + cbTable->SetSelection(0); + cbIndex->Append(table->GetIndexName()); + cbIndex->SetSelection(0); + + txtID->SetValue(NumToStr(table->GetSlId())); + + cbTable->Disable(); + cbIndex->Disable(); + txtComment->Disable(); + txtID->Disable(); + + LoadTrigger(table->GetOid()); + + size_t i; + for (i = 0 ; i < table->GetTriggers().GetCount() ; i++) + { + int sel = chkTrigger->FindString(table->GetTriggers()[i]); + if (sel >= 0) + chkTrigger->Check(sel); + } + } + else + { + // create mode + + wxString restriction; + if (!settings->GetShowSystemObjects()) + restriction = wxT("\n AND ") + connection->SystemNamespaceRestriction(wxT("nspname")); + + pgSet *tabs = connection->ExecuteSet( + wxT("SELECT DISTINCT cl.oid, nspname, relname\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace nsp ON relnamespace=nsp.oid\n") + wxT(" JOIN pg_index on indrelid=cl.oid AND indisunique\n") + wxT(" LEFT JOIN ") + cluster->GetSchemaPrefix() + wxT("sl_table t ON t.tab_reloid=cl.oid\n") + wxT(" WHERE t.tab_id IS NULL AND cl.relkind = 'r'") + restriction + wxT("\n") + wxT(" ORDER BY nspname, relname") + ); + + if (tabs) + { + while (!tabs->Eof()) + { + cbTable->Append(tabs->GetVal(wxT("nspname")) + wxT(".") + tabs->GetVal(wxT("relname")), (void *)tabs->GetOid(wxT("oid"))); + tabs->MoveNext(); + } + delete tabs; + } + } + + return dlgProperty::Go(modal); +} + + +pgObject *dlgRepTable::CreateObject(pgCollection *collection) +{ + pgObject *obj = slTableFactory.CreateObjects(collection, 0, + wxT(" WHERE tab_reloid = ") + NumToStr((OID)cbTable->wxItemContainer::GetClientData(cbTable->GetGuessedSelection()))); + + return obj; +} + + + +void dlgRepTable::OnChangeTableSel(wxCommandEvent &ev) +{ + cbTable->GuessSelection(ev); + OnChangeTable(ev); +} + + +void dlgRepTable::OnChangeTable(wxCommandEvent &ev) +{ + int sel = cbTable->GetGuessedSelection(); + + cbIndex->Clear(); + chkTrigger->Clear(); + + if (sel >= 0) + { + OID relid = (OID)cbTable->wxItemContainer::GetClientData(sel); + + pgSet *idx = connection->ExecuteSet( + wxT("SELECT relname\n") + wxT(" FROM pg_index JOIN pg_class cl ON cl.oid=indexrelid\n") + wxT(" WHERE indrelid=") + NumToStr(relid) + wxT("\n") + wxT(" ORDER BY NOT indisprimary, relname") + ); + if (idx) + { + while (!idx->Eof()) + { + cbIndex->Append(idx->GetVal(wxT("relname"))); + idx->MoveNext(); + } + delete idx; + + cbIndex->SetSelection(0); + } + + LoadTrigger(relid); + } + + OnChange(ev); +} + + +void dlgRepTable::LoadTrigger(OID relid) +{ + wxString sql = wxT("SELECT tgname FROM pg_trigger\n") + wxT(" JOIN pg_proc pr ON pr.oid=tgfoid\n") + wxT(" JOIN pg_namespace ns ON ns.oid=pronamespace\n") + wxT(" WHERE tgrelid=") + NumToStr(relid); + if (connection->BackendMinimumVersion(8, 5)) + sql += wxT(" AND tgconstraint=0\n"); + else + sql += wxT(" AND NOT tgisconstraint\n"); + sql += wxT(" AND nspname <> ") + qtDbString(wxT("_") + set->GetCluster()->GetName()) + wxT("\n") + wxT(" ORDER BY tgname"); + + pgSet *trg = connection->ExecuteSet(sql); + + if (trg) + { + while (!trg->Eof()) + { + chkTrigger->Append(trg->GetVal(wxT("tgname"))); + trg->MoveNext(); + } + delete trg; + } +} + +void dlgRepTable::CheckChange() +{ + if (table) + { + bool tgChanged = false; + + unsigned int i; + int cnt = 0; + + for (i = 0 ; !tgChanged && i < chkTrigger->GetCount() ; i++) + { + if (chkTrigger->IsChecked(i)) + { + cnt++; + if (table->GetTriggers().Index(chkTrigger->GetString(i)) < 0) + tgChanged = true; + + } + } + + EnableOK(tgChanged + || (int)table->GetTriggers().GetCount() != cnt + || txtComment->GetValue() != table->GetComment()); + } + else + { + bool enable = true; + CheckValid(enable, cbTable->GetGuessedSelection() >= 0, _("Please select table to replicate.")); + CheckValid(enable, cbIndex->GetCurrentSelection() >= 0, _("Please select index.")); + + EnableOK(enable); + } +} + + + +wxString dlgRepTable::GetSql() +{ + wxString sql; + wxString id = txtID->GetValue();; + + wxArrayString newTriggers; + + unsigned int i; + for (i = 0 ; i < chkTrigger->GetCount() ; i++) + { + if (chkTrigger->IsChecked(i)) + newTriggers.Add(chkTrigger->GetString(i)); + } + + if (table) + { + // edit mode + + wxArrayString oldTriggers = table->GetTriggers(); + + i = oldTriggers.GetCount(); + while (i--) + { + int j = newTriggers.Index(oldTriggers[i]); + if (j >= 0) + { + newTriggers.RemoveAt(j); + oldTriggers.RemoveAt(i); + } + } + + // these triggers have been deleted + for (i = 0 ; i < (unsigned int)oldTriggers.GetCount() ; i++) + { + sql += wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("droptrigger(") + + id + wxT(", ") + + qtDbString(oldTriggers[i]) + wxT(");\n"); + } + } + else + { + // create mode + sql = wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("setaddtable(") + + NumToStr(set->GetSlId()) + wxT(", "); + + if (StrToLong(id) > 0) + { + sql += id; + } + else + { + sql += wxT("(SELECT COALESCE(MAX(tab_id), 0) + 1 FROM ") + cluster->GetSchemaPrefix() + wxT("sl_table)"); + + + id = wxT("(SELECT tab_id FROM ") + cluster->GetSchemaPrefix() + wxT("sl_table\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + wxT(" WHERE tab_set = ") + NumToStr(set->GetSlId()) + + wxT(" AND nspname ||'.' || relname = ") + qtDbString(cbTable->GetGuessedStringSelection()) + + wxT(")"); + + } + sql += wxT(", ") + qtDbString(cbTable->GetGuessedStringSelection()) + + wxT(", ") + qtDbString(cbIndex->GetStringSelection()) + + wxT(", ") + qtDbString(txtComment->GetValue()) + + wxT(");\n"); + } + + + // these triggers have been added + for (i = 0 ; i < (unsigned int)newTriggers.GetCount() ; i++) + { + sql += wxT("SELECT ") + cluster->GetSchemaPrefix() + wxT("storetrigger(") + + id + wxT(", ") + + qtDbString(newTriggers[i]) + wxT(");\n"); + } + + return sql; +} diff --git a/slony/module.mk b/slony/module.mk new file mode 100644 index 0000000..5aa65d4 --- /dev/null +++ b/slony/module.mk @@ -0,0 +1,34 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/slony/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + slony/dlgRepCluster.cpp \ + slony/dlgRepListen.cpp \ + slony/dlgRepNode.cpp \ + slony/dlgRepPath.cpp \ + slony/dlgRepProperty.cpp \ + slony/dlgRepSequence.cpp \ + slony/dlgRepSet.cpp \ + slony/dlgRepSubscription.cpp \ + slony/dlgRepTable.cpp \ + slony/slCluster.cpp \ + slony/slListen.cpp \ + slony/slNode.cpp \ + slony/slPath.cpp \ + slony/slSequence.cpp \ + slony/slSet.cpp \ + slony/slSubscription.cpp \ + slony/slTable.cpp + +EXTRA_DIST += \ + slony/module.mk + + diff --git a/slony/slCluster.cpp b/slony/slCluster.cpp new file mode 100644 index 0000000..10469bc --- /dev/null +++ b/slony/slCluster.cpp @@ -0,0 +1,613 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slCluster.cpp PostgreSQL Slony-I Cluster +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/dlgRepCluster.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slSet.h" +#include "frm/frmMain.h" + +#include + + +class RemoteConn +{ +public: + RemoteConn(long id, const wxString str, pgConn *c) + { + connInfo = str; + nodeID = id; + conn = c; + } + ~RemoteConn() + { + if (conn) delete conn; + } + + wxString connInfo; + pgConn *conn; + long nodeID; +}; + + +WX_DEFINE_OBJARRAY(RemoteConnArray); + +slCluster::slCluster(const wxString &newName) + : pgDatabaseObject(slClusterFactory, newName) +{ + localNode = 0; +} + +wxMenu *slCluster::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + +// if (GetCreatePrivilege()) + { + setFactory.AppendMenu(menu); + nodeFactory.AppendMenu(menu); + } + return menu; +} + + +bool slCluster::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetSchemaPrefix() + wxT("uninstallnode();\n") + wxT("DROP SCHEMA ") + qtIdent(wxT("_") + GetName()) + wxT(" CASCADE;")); +} + + +wxString slCluster::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony cluster"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony cluster"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony cluster \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony cluster \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony cluster cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony cluster?"); + break; + case PROPERTIESREPORT: + message = _("Slony cluster properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony cluster properties"); + break; + case DDLREPORT: + message = _("Slony cluster DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony cluster DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony cluster dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony cluster dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony cluster dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony cluster dependents"); + break; + } + + return message; +} + +wxString slCluster::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = _("-- Use the installation wizard\n-- to generate the Slony-I replication cluster.\n"); + } + return sql; +} + + +slNode *slCluster::GetLocalNode(ctlTree *browser) +{ + pgCollection *nodes = browser->FindCollection(nodeFactory, GetId()); + if (nodes) + { + slNode *node; + + treeObjectIterator ni(browser, nodes); + while ((node = (slNode *)ni.GetNextObject()) != 0) + { + if (node->GetSlId() == GetLocalNodeID()) + return node; + } + } + return 0; +} + + +pgConn *slCluster::GetNodeConn(frmMain *form, long nodeId, bool create) +{ + size_t i; + + if (nodeId == GetLocalNodeID()) + return GetDatabase()->GetConnection(); + + for (i = 0 ; i < remoteConns.GetCount() ; i++) + { + if (remoteConns[i].nodeID == nodeId) + return remoteConns[i].conn; + } + + if (create && adminNodeID >= 0) + { + wxString connstr = GetDatabase()->ExecuteScalar( + wxT("SELECT pa_conninfo FROM ") + GetSchemaPrefix() + wxT("sl_path\n") + wxT(" WHERE pa_server = ") + NumToStr(nodeId) + + wxT(" AND pa_client = ") + NumToStr(adminNodeID)); + + if (!connstr.IsEmpty()) + { + // check for server registration + wxTreeItemId servers = GetId(); + pgObject *obj = this; + while (obj && obj != form->GetServerCollection()) + { + servers = form->GetBrowser()->GetItemParent(servers); + if (servers) + obj = form->GetBrowser()->GetObject(servers); + } + + wxCookieType cookie; + + wxStringTokenizer strtok(connstr, wxT(" "), wxTOKEN_RET_EMPTY); + + wxString lastToken; + wxArrayString tokens; + wxString str; + + while (strtok.HasMoreTokens()) + { + str = strtok.GetNextToken(); + if (str.Find('=') < 0) + { + if (!lastToken.IsEmpty()) + lastToken += wxT(" "); + lastToken += str; + } + else + { + if (!lastToken.IsEmpty()) + tokens.Add(lastToken); + lastToken = str; + } + } + if (!lastToken.IsEmpty()) + tokens.Add(lastToken); + + size_t i; + + wxString host, dbname; + int port = 5432; + for (i = 0 ; i < tokens.GetCount() ; i++) + { + str = tokens[i].BeforeFirst('='); + if (str == wxT("host")) + host = tokens[i].AfterFirst('='); + else if (str == wxT("dbname")) + dbname = tokens[i].AfterFirst('='); + else if (str == wxT("port")) + port = StrToLong(tokens[i].AfterFirst('=')); + } + + if (host.IsEmpty() || dbname.IsEmpty()) + return NULL; + + wxTreeItemId serverItem = form->GetBrowser()->GetFirstChild(servers, cookie); + while (serverItem) + { + pgServer *server = (pgServer *)form->GetBrowser()->GetObject(serverItem); + if (server && server->IsCreatedBy(serverFactory)) + { + if (server->GetName() == host && server->GetPort() == port) + { + if (!server->GetConnected()) + { + server->Connect(form, server->GetStorePwd()); + if (!server->GetConnected()) + { + wxLogError(server->GetLastError()); + return NULL; + } + } + pgConn *conn = server->CreateConn(dbname); + + if (conn) + remoteConns.Add(new RemoteConn(nodeId, connstr, conn)); + + return conn; + } + } + serverItem = form->GetBrowser()->GetNextChild(servers, cookie); + } + + } + } + return NULL; +} + + +bool slCluster::ClusterMinimumVersion(int major, int minor) +{ + long ma = StrToLong(clusterVersion); + long mi = StrToLong(clusterVersion.AfterFirst('.')); + return ma > major || (ma == major && mi >= minor); +} + + +long slCluster::GetSlonPid() +{ + long slonPid; + wxString pidcol = GetConnection()->BackendMinimumVersion(9, 2) ? wxT("pid") : wxT("procpid"); + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + slonPid = StrToLong(GetConnection()->ExecuteScalar( + wxT("SELECT nl_backendpid FROM ") + qtIdent(wxT("_") + GetName()) + wxT(".sl_nodelock nl, ") + wxT("pg_stat_activity sa WHERE nl.nl_backendpid = sa.") + pidcol + wxT(" AND nl_nodeid = ") + + NumToStr(GetLocalNodeID()))); + } + else + { + slonPid = StrToLong(GetConnection()->ExecuteScalar( + wxT("SELECT listenerpid FROM pg_listener WHERE relname = ") + + qtDbString(wxT("_") + GetName() + wxT("_Event")))); + } + + return slonPid; +} + + +void slCluster::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + pgSet *set; + + set = GetDatabase()->ExecuteSet( + wxT("SELECT no_id, no_comment, ") + GetSchemaPrefix() + wxT("slonyversion() AS version\n") + wxT(" FROM ") + GetSchemaPrefix() + wxT("sl_local_node_id\n") + wxT(" JOIN ") + GetSchemaPrefix() + wxT("sl_node ON no_id = last_value")); + if (set) + { + iSetClusterVersion(set->GetVal(wxT("version"))); + iSetLocalNodeID(set->GetLong(wxT("no_id"))); + iSetLocalNodeName(set->GetVal(wxT("no_comment")).BeforeFirst('\n')); + delete set; + } + + adminNodeID = settings->Read(wxT("Replication/") + GetName() + wxT("/AdminNode"), -1L); + + wxString sql = wxT("SELECT no_id, no_comment\n") + wxT(" FROM ") + GetSchemaPrefix() + wxT("sl_node\n"); + + if (adminNodeID == -1L) + { + sql += wxT(" JOIN ") + GetSchemaPrefix() + wxT("sl_path ON no_id = pa_client\n") + wxT(" WHERE pa_server = ") + NumToStr(localNodeID) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%host=") + GetServer()->GetName() + wxT("%")) + + wxT(" AND pa_conninfo LIKE ") + qtDbString(wxT("%dbname=") + GetDatabase()->GetName() + wxT("%")); + } + else + sql += wxT(" WHERE no_id = ") + NumToStr(adminNodeID); + + + set = GetDatabase()->ExecuteSet(sql); + if (set) + { + if (!set->Eof()) + { + adminNodeID = set->GetLong(wxT("no_id")); + adminNodeName = set->GetVal(wxT("no_comment")); + settings->WriteLong(wxT("Replication/") + GetName() + wxT("/AdminNode"), adminNodeID); + } + delete set; + } + + wxLogInfo(wxT("Adding child object to cluster %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, nodeFactory); + browser->AppendCollection(this, setFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("Local node ID"), GetLocalNodeID()); + properties->AppendItem(_("Local node"), GetLocalNodeName()); + + if (GetAdminNodeID() == -1L) + properties->AppendItem(_("Admin node"), _("")); + else + { + properties->AppendItem(_("Admin node ID"), GetAdminNodeID()); + properties->AppendItem(_("Admin node"), GetAdminNodeName()); + } + + long slonPid = GetSlonPid(); + if (slonPid) + properties->AppendItem(wxT("Slon PID"), slonPid); + else + properties->AppendItem(wxT("Slon PID"), _("unknown")); + + properties->AppendItem(_("Version"), GetClusterVersion()); + properties->AppendItem(_("Owner"), GetOwner()); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *slCluster::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *cluster = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + cluster = slClusterFactory.CreateObjects(coll, 0, wxT(" WHERE nsp.oid=") + GetOidStr() + wxT("\n")); + + return cluster; +} + + + +pgObject *pgaSlClusterFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + slCluster *cluster = 0; + + pgSet *clusters = coll->GetDatabase()->ExecuteSet( + wxT("SELECT nsp.oid, substr(nspname, 2) as clustername, nspname, pg_get_userbyid(nspowner) AS namespaceowner, description\n") + wxT(" FROM pg_namespace nsp\n") + wxT(" LEFT OUTER JOIN pg_description des ON des.objoid=nsp.oid\n") + wxT(" JOIN pg_proc pro ON pronamespace=nsp.oid AND proname = 'slonyversion'\n") + + restriction + + wxT(" ORDER BY nspname")); + + if (clusters) + { + while (!clusters->Eof()) + { + cluster = new slCluster(clusters->GetVal(wxT("clustername"))); + cluster->iSetOid(clusters->GetOid(wxT("oid"))); + cluster->iSetDatabase(coll->GetDatabase()); + cluster->iSetSchemaPrefix(qtIdent(clusters->GetVal(wxT("nspname"))) + wxT(".")); + cluster->iSetOwner(clusters->GetVal(wxT("namespaceowner"))); + cluster->iSetComment(clusters->GetVal(wxT("description"))); + + if (browser) + { + browser->AppendObject(coll, cluster); + clusters->MoveNext(); + } + else + break; + } + + delete clusters; + } + return cluster; +} + + + +pgObject *slCluster::ReadObjects(pgCollection *coll, ctlTree *browser) +{ + // Get the clusters + return slClusterFactory.CreateObjects(coll, browser, wxEmptyString); +} + +///////////////////////////// + +slClusterCollection::slClusterCollection(pgaFactory *factory, pgDatabase *db) + : pgDatabaseObjCollection(factory, db) +{ +} + + +wxString slClusterCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony clusters"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony clusters"); + break; + case OBJECTSLISTREPORT: + message = _("Slony clusters list report"); + break; + } + + return message; +} + + +///////////////////////////// + + +#include "images/slcluster.pngc" +#include "images/slclusters.pngc" + +pgaSlClusterFactory::pgaSlClusterFactory() + : pgDatabaseObjFactory(__("Slony-I cluster"), __("New Slony-I cluster..."), __("Create new Slony-I Replication Cluster"), slcluster_png_img) +{ +// metaType = SLM_CLUSTER; +} + + +pgCollection *pgaSlClusterFactory::CreateCollection(pgObject *obj) +{ + return new slClusterCollection(GetCollectionFactory(), (pgDatabase *)obj); +} + + +slObject::slObject(slCluster *cl, pgaFactory &factory, const wxString &newName) + : pgDatabaseObject(factory, newName) +{ + cluster = cl; + iSetDatabase(cl->GetDatabase()); +} + +slObjCollection::slObjCollection(pgaFactory *factory, slCluster *_cluster) + : pgDatabaseObjCollection(factory, _cluster->GetDatabase()) +{ + cluster = _cluster; +} + +pgCollection *slObjFactory::CreateCollection(pgObject *obj) +{ + return new slObjCollection(GetCollectionFactory(), (slCluster *)obj); +} + + +pgaSlClusterFactory slClusterFactory; +static pgaCollectionFactory cf(&slClusterFactory, __("Slony Replication"), slclusters_png_img); + +//////////////////////////////////////////////7 + +bool clusterActionFactory::CheckEnable(pgObject *obj) +{ + return obj && obj->IsCreatedBy(slClusterFactory); +} + + +slonyRestartFactory::slonyRestartFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : clusterActionFactory(list) +{ + mnu->Append(id, _("Restart Node"), _("Restart node.")); +} + + +wxWindow *slonyRestartFactory::StartDialog(frmMain *form, pgObject *obj) +{ + slCluster *cluster = (slCluster *)obj; + + wxString notifyName; + wxString pidcol = cluster->GetDatabase()->BackendMinimumVersion(9, 2) ? wxT(" sa.pid ") : wxT(" sa.procpid "); + + if (cluster->GetDatabase()->BackendMinimumVersion(9, 0)) + { + notifyName = cluster->GetDatabase()->ExecuteScalar( + wxT("SELECT ") + cluster->GetDatabase()->GetConnection()->qtDbString(wxT("_") + cluster->GetName() + wxT("_Restart")) + + wxT(" FROM _") + cluster->GetName() + wxT(".sl_nodelock nl,") + wxT(" pg_stat_activity sa WHERE nl.nl_backendpid = ") + pidcol + wxT("AND nl_nodeid = ") + + NumToStr(cluster->GetLocalNodeID())); + } + else + { + notifyName = cluster->GetDatabase()->ExecuteScalar( + wxT("SELECT relname FROM pg_listener") + wxT(" WHERE relname=") + cluster->GetDatabase()->GetConnection()->qtDbString(wxT("_") + cluster->GetName() + wxT("_Restart"))); + } + + if (notifyName.IsEmpty()) + { + wxMessageDialog dlg(form, wxString::Format(_("Node \"%s\" not running"), cluster->GetLocalNodeName().c_str()), + _("Can't restart node"), wxICON_EXCLAMATION | wxOK); + dlg.ShowModal(); + form->CheckAlive(); + + return 0; + } + + wxMessageDialog dlg(form, wxString::Format(_("Restart node \"%s\"?"), + cluster->GetLocalNodeName().c_str()), _("Restart node"), wxICON_EXCLAMATION | wxYES_NO | wxNO_DEFAULT); + + if (dlg.ShowModal() != wxID_YES) + return 0; + + if (!cluster->GetDatabase()->ExecuteVoid( + wxT("NOTIFY ") + qtIdent(notifyName))) + form->CheckAlive(); + + return 0; +} + + +slonyUpgradeFactory::slonyUpgradeFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : clusterActionFactory(list) +{ + mnu->Append(id, _("Upgrade Node"), _("Upgrade node to newest replication software version.")); +} + + +wxWindow *slonyUpgradeFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgProperty *dlg = new dlgRepClusterUpgrade(&slClusterFactory, form, (slCluster *)obj); + dlg->InitDialog(form, obj); + dlg->CreateAdditionalPages(); + dlg->Go(false); + dlg->CheckChange(); + return 0; +} + + +slonyFailoverFactory::slonyFailoverFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : clusterActionFactory(list) +{ + mnu->Append(id, _("Failover"), _("Failover to backup node.")); +} + + +wxWindow *slonyFailoverFactory::StartDialog(frmMain *form, pgObject *obj) +{ + return 0; +} + + +bool slonyFailoverFactory::CheckEnable(pgObject *obj) +{ + return false; +} diff --git a/slony/slListen.cpp b/slony/slListen.cpp new file mode 100644 index 0000000..e30b572 --- /dev/null +++ b/slony/slListen.cpp @@ -0,0 +1,244 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slListen.cpp PostgreSQL Slony-I listen +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slListen.h" +#include "slony/slNode.h" +#include "slony/slCluster.h" +#include "frm/frmMain.h" + + +slListen::slListen(slNode *n, const wxString &newName) + : slNodeObject(n, listenFactory, newName) +{ +} + +bool slListen::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("droplisten(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetProviderId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(");\n")); +} + + +wxString slListen::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony listen"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony listen"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony listen \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony listen \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony listen cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony listen?"); + break; + case PROPERTIESREPORT: + message = _("Slony listen properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony listen properties"); + break; + case DDLREPORT: + message = _("Slony listen DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony listen DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony listen dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony listen dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony listen dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony listen dependents"); + break; + } + + return message; +} + +wxString slListen::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Node will listen to ") + GetProviderName() + + wxT(" for replication data from ") + GetOriginName() + wxT(".\n\n") + + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("storelisten(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetProviderId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(");\n"); + } + return sql; +} + + +void slListen::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Origin"), GetOriginName()); + properties->AppendItem(_("Origin ID"), GetSlId()); + properties->AppendItem(_("Provider"), GetProviderName()); + properties->AppendItem(_("Provider ID"), GetProviderId()); + } +} + + + +pgObject *slListen::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *listen = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + listen = listenFactory.CreateObjects(coll, 0, + wxT(" WHERE li_origin =") + NumToStr(GetSlId()) + + wxT(" AND li_provider = ") + NumToStr(GetProviderId()) + + wxT(" AND li_receiver = ") + NumToStr(GetNode()->GetSlId()) + + wxT("\n")); + + return listen; +} + + + +pgObject *slListenFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slNodeObjCollection *collection = (slNodeObjCollection *)coll; + slListen *listen = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE li_receiver = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *listens = collection->GetDatabase()->ExecuteSet( + wxT("SELECT li_origin, li_provider, li_receiver, no.no_comment as origin_name, np.no_comment as provider_name\n") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_listen\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node no ON no.no_id=li_origin\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node np ON np.no_id=li_provider\n") + + restriction + + wxT(" ORDER BY li_origin, li_provider")); + + if (listens) + { + while (!listens->Eof()) + { + wxString orgName = listens->GetVal(wxT("origin_name")).BeforeFirst('\n'); + wxString provName = listens->GetVal(wxT("provider_name")).BeforeFirst('\n'); + + listen = new slListen(collection->GetNode(), orgName + wxT(" (") + provName + wxT(")")); + listen->iSetSlId(listens->GetLong(wxT("li_origin"))); + listen->iSetProviderId(listens->GetLong(wxT("li_provider"))); + listen->iSetOriginName(orgName); + listen->iSetProviderName(provName); + + if (browser) + { + browser->AppendObject(collection, listen); + listens->MoveNext(); + } + else + break; + } + + delete listens; + } + return listen; +} + + +wxString slListenCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony listens"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony listens"); + break; + case OBJECTSLISTREPORT: + message = _("Slony listens list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/sllisten.pngc" +#include "images/sllistens.pngc" + +slListenFactory::slListenFactory() + : slNodeObjFactory(__("Listen"), __("New Listen"), __("Create a new Listen."), sllisten_png_img) +{ + metaType = SLM_LISTEN; +} + + +pgCollection *slListenFactory::CreateCollection(pgObject *obj) +{ + return new slListenCollection(GetCollectionFactory(), (slNode *)obj); +} + + +slListenFactory listenFactory; +static pgaCollectionFactory cf(&listenFactory, __("listens"), sllistens_png_img); diff --git a/slony/slNode.cpp b/slony/slNode.cpp new file mode 100644 index 0000000..b90f9a4 --- /dev/null +++ b/slony/slNode.cpp @@ -0,0 +1,499 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slNode.cpp PostgreSQL Slony-I node +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slNode.h" +#include "slony/slCluster.h" +#include "slony/slPath.h" +#include "slony/slListen.h" +#include "slony/slSet.h" +#include "frm/frmMain.h" + + +slNode::slNode(slCluster *cl, const wxString &newName) + : slObject(cl, nodeFactory, newName) +{ + pid = -1; +} + +int slNode::GetIconId() +{ + if (!GetActive()) + return nodeFactory.GetDisabledIconId(); + else if (GetSlId() == GetCluster()->GetLocalNodeID()) + return nodeFactory.GetLocalIconId(); + else + return nodeFactory.GetIconId(); +} + + +wxMenu *slNode::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + +// if (GetCreatePrivilege()) + pathFactory.AppendMenu(menu); + listenFactory.AppendMenu(menu); + + return menu; +} + + +bool slNode::CanDrop() +{ + return (GetSlId() != GetCluster()->GetLocalNodeID()); +} + + +bool slNode::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("dropnode(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slNode::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony node"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony node"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony node \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony node \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony node cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony node?"); + break; + case PROPERTIESREPORT: + message = _("Slony node properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony node properties"); + break; + case DDLREPORT: + message = _("Slony node DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony node DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony node dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony node dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony node dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony node dependents"); + break; + } + + return message; +} + +bool slNode::WaitForEvent(long evNode) +{ + return true; +} + + +wxString slNode::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Create replication node ") + GetName() + wxT(".\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("storenode(") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetComment()); + + if (GetCluster()->ClusterMinimumVersion(1, 1) && !GetCluster()->ClusterMinimumVersion(2, 0)) + sql += wxT(", ") + BoolToStr(GetSpool()); + sql += wxT(");\n"); + } + return sql; +} + + +long slNode::GetOutstandingAcks() +{ + long l = StrToLong(GetDatabase()->ExecuteScalar( + wxT("SELECT SUM(st_lag_num_events) AS sumlagevents\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID()) + wxT("\n") + wxT(" GROUP BY st_last_event"))); + + return l; +} + + +bool slNode::CheckAcksAndContinue(wxFrame *frame) +{ + long l = GetOutstandingAcks(); + if (!l) + return true; + + wxMessageDialog dlg(frame, wxString::Format(wxPLURAL("There are %ld event acknowledgement outstanding.\nContinue anyway?", + "There are %ld event acknowledgements outstanding.\nContinue anyway?", l), l), + _("Events pending"), wxYES_NO | wxNO_DEFAULT); + + return dlg.ShowModal() == wxID_YES; +} + + +void slNode::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + CreateListColumns(statistics, _("Statistic"), _("Value")); + + if (GetActive()) + { + if (GetCluster()->GetLocalNodeID() == GetSlId()) + { + pgSet *stats = GetDatabase()->ExecuteSet( + wxT("SELECT st_last_event,\n") + wxT(" MAX(st_last_received_ts - st_last_received_event_ts) AS roundtrip,\n") + wxT(" SUM(st_lag_num_events) AS sumlagevents, st_last_event - MAX(st_lag_num_events) as oldestlagevent,\n") + wxT(" MAX(st_last_event_ts - st_last_received_ts) AS maxeventlag\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID()) + wxT("\n") + wxT(" GROUP BY st_last_event")); + + if (stats) + { + wxString roundtrip = stats->GetVal(wxT("roundtrip")); + long lags = stats->GetLong(wxT("sumlagevents")); + if (roundtrip.Left(6) == wxT("00:00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(6))) + roundtrip.Mid(8) + wxT(" s"); + else if (roundtrip.Left(3) == wxT("00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(3))) + roundtrip.Mid(5); + + statistics->AppendItem(_("Last event"), stats->GetLong(wxT("st_last_event"))); + statistics->AppendItem(_("Max response time"), roundtrip); + statistics->AppendItem(_("Acks outstanding"), lags); + + + if (lags > 0) + { + long lagEvent = stats->GetLong(wxT("oldestlagevent")); + statistics->AppendItem(_("Oldest outstanding"), lagEvent); + statistics->AppendItem(_("Outstanding for"), stats->GetVal(wxT("maxeventlag"))); + } + + delete stats; + } + } + else + { + pgSet *stats = GetDatabase()->ExecuteSet( + wxT("SELECT st_last_event, st_last_event_ts, st_last_received, st_last_received_ts,\n") + wxT(" st_last_received_ts - st_last_received_event_ts AS roundtrip,\n") + wxT(" st_last_event_ts - st_last_received_ts AS eventlag,") + wxT(" ev_seqno, ev_type || ' ' || COALESCE(ev_data1, '') AS hanging\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" LEFT JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event ON ev_origin=st_origin AND ev_seqno=\n") + wxT(" (SELECT MIN(ev_seqno) FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event WHERE ev_seqno > st_last_received)\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID()) + wxT("\n") + wxT(" AND st_received = ") + NumToStr(GetSlId())); + + if (stats) + { + long evno = stats->GetLong(wxT("st_last_event")); + long ack = stats->GetLong(wxT("st_last_received")); + wxString roundtrip = stats->GetVal(wxT("roundtrip")); + if (roundtrip.Left(6) == wxT("00:00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(6))) + roundtrip.Mid(8) + wxT(" s"); + else if (roundtrip.Left(3) == wxT("00:")) + roundtrip = NumToStr(StrToLong(roundtrip.Mid(3))) + roundtrip.Mid(5); + + statistics->AppendItem(_("Last event"), evno); + statistics->AppendItem(_("Last event timestamp"), stats->GetDateTime(wxT("st_last_event_ts"))); + statistics->AppendItem(_("Last acknowledged"), ack); + statistics->AppendItem(_("Last ack timestamp"), stats->GetDateTime(wxT("st_last_received_ts"))); + statistics->AppendItem(_("Last response time"), roundtrip); + + if (evno > ack) + { + statistics->AppendItem(_("Outstanding acks"), evno - ack); + statistics->AppendItem(_("No ack for"), stats->GetVal(wxT("eventlag"))); + statistics->AppendItem(_("Hanging event"), stats->GetVal(wxT("ev_seqno"))); + statistics->AppendItem(_("Command"), stats->GetVal(wxT("hanging"))); + } + + delete stats; + } + } + } + else + statistics->AppendItem(_("not active"), wxEmptyString); +} + + +void slNode::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + wxString pidcol = wxEmptyString; + pgConn *conn = GetCluster()->GetNodeConn(form, GetSlId(), pid < 0); + + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + // Log + wxLogInfo(wxT("Adding child object to node %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, pathFactory); + browser->AppendCollection(this, listenFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + if (GetCluster()->GetLocalNodeID() == GetSlId()) + properties->AppendYesNoItem(_("Local node"), true); + properties->AppendYesNoItem(_("Active"), GetActive()); + if (GetCluster()->ClusterMinimumVersion(1, 1)) + properties->AppendYesNoItem(_("Log spooler"), GetSpool()); + properties->AppendYesNoItem(_("Connected"), conn != NULL); + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + + if (conn && pid < 0) + { + if (conn->BackendMinimumVersion(9, 0)) + { + if (conn->BackendMinimumVersion(9, 2)) + pidcol = wxT("pid"); + else + pidcol = wxT("procpid"); + + pid = StrToLong(conn->ExecuteScalar( + wxT("SELECT nl_backendpid FROM ") + qtIdent(wxT("_") + GetCluster()->GetName()) + wxT(".sl_nodelock nl, ") + wxT("pg_stat_activity sa WHERE nl.nl_backendpid = sa.") + pidcol + wxT(" AND nl_nodeid = ") + + NumToStr(GetCluster()->GetLocalNodeID()))); + } + else + { + pid = StrToLong(conn->ExecuteScalar( + wxT("SELECT listenerpid FROM pg_listener WHERE relname=") + qtDbString(wxT("_") + GetCluster()->GetName() + wxT("_Restart")))); + } + } + + if (conn) + { + if (GetPid()) + properties->AppendItem(_("Running PID"), GetPid()); + else + properties->AppendItem(_("Running PID"), _("not running")); + } + else + { + if (GetSlId() != GetCluster()->GetAdminNodeID()) + properties->AppendItem(_("Running PID"), _("administrative node")); + } + } +} + + + +pgObject *slNode::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *node = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + node = nodeFactory.CreateObjects(coll, 0, wxT(" WHERE no_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return node; +} + + + +pgObject *slNodeFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + slObjCollection *collection = (slObjCollection *)coll; + slNode *node = 0; + + pgSet *nodes = collection->GetDatabase()->ExecuteSet( + wxT("SELECT * FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node\n") + + restriction + + wxT(" ORDER BY no_id")); + + if (nodes) + { + while (!nodes->Eof()) + { + node = new slNode(collection->GetCluster(), nodes->GetVal(wxT("no_comment")).BeforeFirst('\n')); + node->iSetSlId(nodes->GetLong(wxT("no_id"))); + node->iSetActive(nodes->GetBool(wxT("no_active"))); + node->iSetComment(nodes->GetVal(wxT("no_comment"))); + + if (collection->GetCluster()->ClusterMinimumVersion(1, 1)) + { + if (nodes->HasColumn(wxT("no_spool"))) + node->iSetSpool(nodes->GetBool(wxT("no_spool"))); + } + + if (browser) + { + browser->AppendObject(collection, node); + nodes->MoveNext(); + } + else + break; + } + + delete nodes; + } + return node; +} + + +wxString slNodeCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony nodes"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony nodes"); + break; + case OBJECTSLISTREPORT: + message = _("Slony nodes list report"); + break; + } + + return message; +} + + +void slNodeCollection::ShowStatistics(frmMain *form, ctlListView *statistics) +{ + wxLogInfo(wxT("Displaying statistics for nodes on Cluster %s"), GetCluster()->GetIdentifier().c_str()); + + // Add the statistics view columns + statistics->ClearAll(); + statistics->AddColumn(_("Node"), 50); + statistics->AddColumn(_("Roundtrip"), 50); + statistics->AddColumn(_("Acks outstanding"), 50); + statistics->AddColumn(_("Outstanding time"), 50); + statistics->AddColumn(_("Event No"), 50); + statistics->AddColumn(_("Command"), 250); + + pgSet *stats = GetDatabase()->ExecuteSet( + wxT("SELECT st_received, st_last_event, st_lag_num_events, st_last_event_ts, st_last_received, st_last_received_ts,\n") + wxT(" st_last_received_ts - st_last_received_event_ts AS roundtrip,\n") + wxT(" CASE WHEN st_lag_num_events > 0 THEN st_last_event_ts - st_last_received_ts END AS eventlag,") + wxT(" ev_seqno, ev_type || ' ' || COALESCE(ev_data1, '') AS hanging\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_status\n") + wxT(" LEFT JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event ON ev_origin=st_origin AND ev_seqno=\n") + wxT(" (SELECT MIN(ev_seqno) FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_event WHERE ev_seqno > st_last_received)\n") + wxT(" WHERE st_origin = ") + NumToStr(GetCluster()->GetLocalNodeID())); + + if (stats) + { + long pos = 0; + while (!stats->Eof()) + { + long lagEvents = stats->GetLong(wxT("st_lag_num_events")); + statistics->InsertItem(pos, NumToStr(stats->GetLong(wxT("st_received"))), nodeFactory.GetIconId()); + statistics->SetItem(pos, 1, stats->GetVal(wxT("roundtrip"))); + statistics->SetItem(pos, 2, NumToStr(lagEvents)); + statistics->SetItem(pos, 3, stats->GetVal(wxT("eventlag"))); + if (lagEvents) + { + statistics->SetItem(pos, 4, stats->GetVal(wxT("ev_seqno"))); + statistics->SetItem(pos, 5, stats->GetVal(wxT("hanging"))); + } + stats->MoveNext(); + pos++; + } + + delete stats; + } +} + + +/////////////////////////////////////////////////// + +#include "images/slnode.pngc" +#include "images/slnode-local.pngc" +#include "images/slnode-disabled.pngc" +#include "images/slnodes.pngc" + +slNodeFactory::slNodeFactory() + : slObjFactory(__("Node"), __("New Node"), __("Create a new Node."), slnode_png_img) +{ + localIconId = addIcon(slnode_local_png_img); + disabledIconId = addIcon(slnode_disabled_png_img); + metaType = SLM_NODE; +} + +pgCollection *slNodeFactory::CreateCollection(pgObject *obj) +{ + return new slNodeCollection(GetCollectionFactory(), (slCluster *)obj); +} + + +slNodeObject::slNodeObject(slNode *n, pgaFactory &factory, const wxString &newName) + : slObject(n->GetCluster(), factory, newName) +{ + node = n; +} + +slNodeObjCollection::slNodeObjCollection(pgaFactory *factory, slNode *n) + : slObjCollection(factory, n->GetCluster()) +{ + node = n; + iSetSlId(n->GetSlId()); +} + + +pgCollection *slNodeObjFactory::CreateCollection(pgObject *obj) +{ + return new slNodeObjCollection(GetCollectionFactory(), (slNode *)obj); +} + + +slNodeFactory nodeFactory; +static pgaCollectionFactory cf(&nodeFactory, __("Nodes"), slnodes_png_img); diff --git a/slony/slPath.cpp b/slony/slPath.cpp new file mode 100644 index 0000000..d4b5b0a --- /dev/null +++ b/slony/slPath.cpp @@ -0,0 +1,236 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slPath.cpp PostgreSQL Slony-I path +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slPath.h" +#include "slony/slNode.h" +#include "slony/slCluster.h" +#include "frm/frmMain.h" + + +slPath::slPath(slNode *n, const wxString &newName) + : slNodeObject(n, pathFactory, newName) +{ +} + +bool slPath::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("droppath(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(");\n")); +} + + +wxString slPath::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony path"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony path"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony path \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony path \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony path cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony path?"); + break; + case PROPERTIESREPORT: + message = _("Slony path properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony path properties"); + break; + case DDLREPORT: + message = _("Slony path DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony path DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony path dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony path dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony path dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony path dependents"); + break; + } + + return message; +} + +wxString slPath::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Register path to node ") + GetName() + wxT(".\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("storepath(") + NumToStr(GetSlId()) + + wxT(", ") + NumToStr(GetNode()->GetSlId()) + + wxT(", ") + qtDbString(GetConnInfo()) + + wxT(", ") + NumToStr(GetConnRetry()) + + wxT(");\n"); + } + return sql; +} + + +void slPath::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Server name"), GetName().BeforeFirst('\n')); + properties->AppendItem(_("Server ID"), GetSlId()); + properties->AppendItem(_("Connect info"), GetConnInfo()); + properties->AppendItem(_("Retry"), GetConnRetry()); + } +} + + + +pgObject *slPath::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *path = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + path = pathFactory.CreateObjects(coll, 0, + wxT(" WHERE pa_server=") + NumToStr(GetSlId()) + + wxT(" AND pa_client=") + NumToStr(GetNode()->GetSlId()) + + wxT("\n")); + + return path; +} + + + +pgObject *slPathFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slNodeObjCollection *collection = (slNodeObjCollection *)coll; + slPath *path = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE pa_client = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *paths = collection->GetDatabase()->ExecuteSet( + wxT("SELECT pa_client, pa_server, pa_conninfo, pa_connretry, no_comment\n") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_path\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_node on no_id=pa_server\n") + + restriction + + wxT(" ORDER BY pa_server")); + + if (paths) + { + while (!paths->Eof()) + { + path = new slPath(collection->GetNode(), paths->GetVal(wxT("no_comment")).BeforeFirst('\n')); + path->iSetSlId(paths->GetLong(wxT("pa_server"))); + path->iSetConnInfo(paths->GetVal(wxT("pa_conninfo"))); + path->iSetConnRetry(paths->GetLong(wxT("pa_connretry"))); + + if (browser) + { + browser->AppendObject(collection, path); + paths->MoveNext(); + } + else + break; + } + + delete paths; + } + return path; +} + + +wxString slPathCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony paths"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony paths"); + break; + case OBJECTSLISTREPORT: + message = _("Slony paths list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/slpath.pngc" +#include "images/slpaths.pngc" + +slPathFactory::slPathFactory() + : slNodeObjFactory(__("Path"), __("New Path"), __("Create a new Path."), slpath_png_img) +{ + metaType = SLM_PATH; +} + + +pgCollection *slPathFactory::CreateCollection(pgObject *obj) +{ + return new slPathCollection(GetCollectionFactory(), (slNode *)obj); +} + + +slPathFactory pathFactory; +static pgaCollectionFactory cf(&pathFactory, __("Paths"), slpaths_png_img); diff --git a/slony/slSequence.cpp b/slony/slSequence.cpp new file mode 100644 index 0000000..3e034ac --- /dev/null +++ b/slony/slSequence.cpp @@ -0,0 +1,230 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSequence.cpp PostgreSQL Slony-I sequence +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/slSequence.h" +#include "slony/slSet.h" +#include "slony/slCluster.h" +#include "frm/frmMain.h" + + +slSequence::slSequence(slSet *s, const wxString &newName) + : slSetObject(s, slSequenceFactory, newName) +{ +} + +bool slSequence::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("setdropsequence(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slSequence::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony sequence"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony sequence"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony sequence \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony sequence \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony sequence cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony sequence?"); + break; + case PROPERTIESREPORT: + message = _("Slony sequence properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony sequence properties"); + break; + case DDLREPORT: + message = _("Slony sequence DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony sequence DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony sequence dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony sequence dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony sequence dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony sequence dependents"); + break; + } + + return message; +} + +wxString slSequence::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Register sequence ") + GetName() + wxT(" for replication.\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("setaddsequence(") + + NumToStr(GetSet()->GetSlId()) + wxT(", ") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetName()) + wxT(", ") + + qtDbString(GetComment()) + wxT(");\n"); + } + return sql; +} + + +void slSequence::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + properties->AppendYesNoItem(_("Active"), GetActive()); + } +} + + + +pgObject *slSequence::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *sequence = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + sequence = slSequenceFactory.CreateObjects(coll, 0, wxT(" WHERE seq_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return sequence; +} + + + +pgObject *slSlSequenceFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slSetObjCollection *collection = (slSetObjCollection *)coll; + slSequence *sequence = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE seq_set = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *sequences = collection->GetDatabase()->ExecuteSet( + wxT("SELECT seq_id, seq_set, nspname, relname, seq_comment\n") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_sequence\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_set ON set_id=seq_set\n") + wxT(" JOIN pg_class cl ON cl.oid=seq_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + + restriction + + wxT(" ORDER BY seq_id")); + + if (sequences) + { + while (!sequences->Eof()) + { + sequence = new slSequence(collection->GetSet(), sequences->GetVal(wxT("nspname")) + wxT(".") + sequences->GetVal(wxT("relname"))); + sequence->iSetSlId(sequences->GetLong(wxT("seq_id"))); + sequence->iSetComment(sequences->GetVal(wxT("seq_comment"))); + + if (browser) + { + browser->AppendObject(collection, sequence); + sequences->MoveNext(); + } + else + break; + } + + delete sequences; + } + return sequence; +} + + +wxString slSlSequenceCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony sequences"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony sequences"); + break; + case OBJECTSLISTREPORT: + message = _("Slony sequences list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/sequence-repl.pngc" +#include "images/sequences.pngc" + +slSlSequenceFactory::slSlSequenceFactory() + : slSetObjFactory(__("Sequence"), __("New Sequence"), __("Create a new Sequence."), sequence_repl_png_img) +{ + metaType = SLM_SEQUENCE; +} + + +pgCollection *slSlSequenceFactory::CreateCollection(pgObject *obj) +{ + return new slSlSequenceCollection(GetCollectionFactory(), (slSet *)obj); +} + + +slSlSequenceFactory slSequenceFactory; +static pgaCollectionFactory cf(&slSequenceFactory, __("Sequences"), sequences_png_img); diff --git a/slony/slSet.cpp b/slony/slSet.cpp new file mode 100644 index 0000000..7dfbc45 --- /dev/null +++ b/slony/slSet.cpp @@ -0,0 +1,565 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSet.cpp PostgreSQL Slony-I Set +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "schema/pgObject.h" +#include "slony/dlgRepSet.h" +#include "slony/slSet.h" +#include "slony/slCluster.h" +#include "slony/slNode.h" +#include "slony/slSequence.h" +#include "slony/slTable.h" +#include "slony/slSubscription.h" +#include "frm/frmMain.h" + + +slSet::slSet(slCluster *cl, const wxString &newName) + : slObject(cl, setFactory, newName) +{ +} + +int slSet::GetIconId() +{ + if (GetOriginId() == GetCluster()->GetLocalNodeID()) + return setFactory.GetExportedIconId(); + else + return setFactory.GetIconId(); +} + + +wxMenu *slSet::GetNewMenu() +{ + wxMenu *menu = pgObject::GetNewMenu(); + + if (GetOriginId() == GetCluster()->GetLocalNodeID()) + { + slSequenceFactory.AppendMenu(menu); + slTableFactory.AppendMenu(menu); + } + + slsubscriptionFactory.AppendMenu(menu); + + return menu; +} + + +bool slSet::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("dropset(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slSet::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony set"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony set"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony set \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony set \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony set cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony set?"); + break; + case PROPERTIESREPORT: + message = _("Slony set properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony set properties"); + break; + case DDLREPORT: + message = _("Slony set DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony set DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony set dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony set dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony set dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony set dependents"); + break; + } + + return message; +} + +wxString slSet::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Create replication set ") + GetName() + wxT(".\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("storeset(") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetComment()) + wxT(");\n"); + } + return sql; +} + +void slSet::ShowDependencies(frmMain *form, ctlListView *list, const wxString &wh) +{ + list->ClearAll(); + list->AddColumn(_("Type"), 60); + list->AddColumn(_("Name"), 100); + list->AddColumn(_("Comment"), 200); + + wxString where; + if (wh.IsEmpty()) + where = wxT(" WHERE set_id=") + NumToStr(GetSlId()); + else + where = wh; + + pgSet *set = GetDatabase()->ExecuteSet( + wxT("SELECT relkind, nspname, relname, id, comment\n") + wxT(" FROM pg_class cl\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=cl.relnamespace\n") + wxT(" JOIN (\n") + wxT(" SELECT tab_id AS id, tab_reloid AS oid, tab_altered AS altered, tab_comment AS comment\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_table t\n") + wxT(" JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_set s ON tab_set=set_id ") + where + wxT("\n") + wxT(" UNION\n") + wxT(" SELECT seq_id, seq_reloid, NULL, seq_comment\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_sequence t\n") + wxT(" JOIN ") + GetCluster()->GetSchemaPrefix() + wxT("sl_set s ON seq_set=set_id ") + where + wxT("\n") + wxT(" ) AS set ON set.oid=cl.oid")); + + if (set) + { + while (!set->Eof()) + { + wxString name = set->GetVal(wxT("nspname")) + wxT(".") + set->GetVal(wxT("relname")); + wxString typestr = set->GetVal(wxT("relkind")); + wxString comment = set->GetVal(wxT("comment")); + wxString typname; + int icon = -1; + switch ( (wxChar)typestr.c_str()[0]) + { + case 'S': + typname = _("Sequence"); + icon = -1; + break; + case 'r': + typname = _("Table"); + icon = -1; + break; + } + + list->AppendItem(icon, typname, name, comment); + + set->MoveNext(); + } + delete set; + } +} + + +wxString slSet::GetLockXXID() +{ + return GetConnection()->ExecuteScalar( + wxT("SELECT set_locked FROM ") + + GetCluster()->GetSchemaPrefix() + wxT("sl_set\n") + wxT(" WHERE set_id=") + NumToStr(GetSlId())); +} + + +bool slSet::Lock() +{ + return GetConnection()->ExecuteVoid(wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("lockSet(") + NumToStr(GetSlId()) + wxT(");")); +} + + +bool slSet::Unlock() +{ + return GetConnection()->ExecuteVoid(wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("unlockSet(") + NumToStr(GetSlId()) + wxT(");")); +} + + +bool slSet::CanDrop() +{ + if (GetMetaType() != SLM_SUBSCRIPTION) + return !GetSubscriptionCount() && GetOriginId() == GetCluster()->GetLocalNodeID(); + else + return GetOriginId() != GetCluster()->GetLocalNodeID(); +} + + +void slSet::ShowDependents(frmMain *form, ctlListView *referencedBy, const wxString &wh) +{ +} + + +void slSet::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + // Log + wxLogInfo(wxT("Adding child object to set %s"), GetIdentifier().c_str()); + + if (GetOriginId() == GetCluster()->GetLocalNodeID()) + { + browser->AppendCollection(this, slSequenceFactory); + browser->AppendCollection(this, slTableFactory); + } + browser->AppendCollection(this, slsubscriptionFactory); + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + properties->AppendItem(_("Origin ID"), GetOriginId()); + properties->AppendItem(_("Origin Node"), GetOriginNode()); + properties->AppendItem(_("Subscriptions"), GetSubscriptionCount()); + + wxString lockXXID = GetLockXXID(); + + if (!lockXXID.IsEmpty()) + properties->AppendItem(_("Lock XXID"), lockXXID); + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *slSet::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *set = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + set = setFactory.CreateObjects(coll, 0, wxT(" WHERE set_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return set; +} + + + +pgObject *slSetFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restriction) +{ + slSet *set = 0; + slObjCollection *collection = (slObjCollection *)coll; + wxString prefix = collection->GetCluster()->GetSchemaPrefix(); + + pgSet *sets = collection->GetDatabase()->ExecuteSet( + wxT("SELECT set_id, set_origin, no_comment, set_comment,\n") + wxT(" (SELECT COUNT(1) FROM ") + prefix + wxT("sl_subscribe where sub_set=set_id) AS subcount\n") + wxT(" FROM ") + prefix + wxT("sl_set\n") + wxT(" JOIN ") + prefix + wxT("sl_node ON set_origin=no_id\n") + + restriction + + wxT(" ORDER BY set_id")); + + if (sets) + { + while (!sets->Eof()) + { + set = new slSet(collection->GetCluster(), sets->GetVal(wxT("set_comment")).BeforeFirst('\n')); + set->iSetSlId(sets->GetLong(wxT("set_id"))); + set->iSetOriginId(sets->GetLong(wxT("set_origin"))); + set->iSetOriginNode(sets->GetVal(wxT("no_comment"))); + set->iSetSubscriptionCount(sets->GetLong(wxT("subcount"))); + set->iSetComment(sets->GetVal(wxT("set_comment"))); + + if (browser) + { + browser->AppendObject(coll, set); + sets->MoveNext(); + } + else + break; + } + + delete sets; + } + return set; +} + + +wxString slSetCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony sets"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony sets"); + break; + case OBJECTSLISTREPORT: + message = _("Slony sets list report"); + break; + } + + return message; +} + + +////////////////////////////////////////////////// + +#include "images/slset.pngc" +#include "images/slset2.pngc" +#include "images/slsets.pngc" + +slSetFactory::slSetFactory() + : slObjFactory(__("Set"), __("New Replication Set"), __("Create a new Replication Set."), slset2_png_img) +{ + exportedIconId = addIcon(slset_png_img); + metaType = SLM_SET; +} + + +pgCollection *slSetFactory::CreateCollection(pgObject *obj) +{ + return new slSetCollection(GetCollectionFactory(), (slCluster *)obj); +} + + +slSetObject::slSetObject(slSet *s, pgaFactory &factory, const wxString &newName) + : slObject(s->GetCluster(), factory, newName) +{ + set = s; +} + +bool slSetObject::CanDrop() +{ + if (GetMetaType() != SLM_SUBSCRIPTION) + return !set->GetSubscriptionCount() && set->GetOriginId() == GetCluster()->GetLocalNodeID(); + else + { + if (GetCluster()->ClusterMinimumVersion(1, 1)) + return (set->GetOriginId() == GetCluster()->GetLocalNodeID() || ((slSubscription *)this)->GetForward()); + else + return set->GetOriginId() != GetCluster()->GetLocalNodeID(); + } +} + + +bool slSetObject::CanCreate() +{ + if (GetMetaType() != SLM_SUBSCRIPTION) + return !set->GetSubscriptionCount() && set->GetOriginId() == GetCluster()->GetLocalNodeID(); + else + { + if (GetCluster()->ClusterMinimumVersion(1, 1)) + return (set->GetOriginId() == GetCluster()->GetLocalNodeID() || ((slSubscription *)this)->GetForward()); + else + return set->GetOriginId() != GetCluster()->GetLocalNodeID(); + } +} + + +slSetObjCollection::slSetObjCollection(pgaFactory *factory, slSet *_set) + : slObjCollection(factory, _set->GetCluster()) +{ + set = _set; + subscription = 0; + iSetSlId(set->GetSlId()); +} + + +bool slSetObjCollection::CanCreate() +{ + switch (GetMetaType()) + { + case SLM_SUBSCRIPTION: + if (GetCluster()->ClusterMinimumVersion(1, 1)) + return (set->GetOriginId() == GetCluster()->GetLocalNodeID() || ((slSubscription *)this)->GetForward()); + else + return set->GetOriginId() != GetCluster()->GetLocalNodeID(); + + case SLM_TABLE: + case SLM_SEQUENCE: + if (set->GetSubscriptionCount()) + return false; + else + return set->GetOriginId() == GetCluster()->GetLocalNodeID(); + default: + return false; + } +} + + +pgCollection *slSetObjFactory::CreateCollection(pgObject *obj) +{ + return new slSetObjCollection(GetCollectionFactory(), (slSet *)obj); +} + +slSetFactory setFactory; +static pgaCollectionFactory cf(&setFactory, __("Replication Sets"), slsets_png_img); + +//////////////////////////////////////////////////////////// + +slonyMergeSetFactory::slonyMergeSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Merge Set"), _("Merge two replication sets.")); +} + + +wxWindow *slonyMergeSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgProperty *dlg = new dlgRepSetMerge(&setFactory, form, (slSet *)obj); + dlg->InitDialog(form, obj); + dlg->CreateAdditionalPages(); + dlg->Go(false); + dlg->CheckChange(); + return 0; +} + + +bool slonyMergeSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || !obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID(); +} + + +///////////////////////////// + +slonyLockSetFactory::slonyLockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Lock Set"), _("Lock a replication set against updates.")); +} + + +wxWindow *slonyLockSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + slSet *set = (slSet *)obj; + + if (set->GetCluster()->GetLocalNode(form->GetBrowser())->CheckAcksAndContinue(form)) + { + if (set->Lock()) + form->Refresh(set); + } + return 0; +} + + +bool slonyLockSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || !obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID() && set->GetLockXXID().IsEmpty(); +} + + +///////////////////////////// + +slonyUnlockSetFactory::slonyUnlockSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Unlock Set"), _("Unlock a replication set and re-allow updates.")); +} + + +wxWindow *slonyUnlockSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + slSet *set = (slSet *)obj; + + if (set->GetCluster()->GetLocalNode(form->GetBrowser())->CheckAcksAndContinue(form)) + { + if (set->Unlock()) + form->Refresh(set); + } + return 0; +} + + +bool slonyUnlockSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || !obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID() && !set->GetLockXXID().IsEmpty(); +} + + +//////////////////////////////// + + +slonyMoveSetFactory::slonyMoveSetFactory(menuFactoryList *list, wxMenu *mnu, ctlMenuToolbar *toolbar) : contextActionFactory(list) +{ + mnu->Append(id, _("Move Set"), _("Move replication set to different node")); +} + + +wxWindow *slonyMoveSetFactory::StartDialog(frmMain *form, pgObject *obj) +{ + dlgProperty *dlg = new dlgRepSetMove(&setFactory, form, (slSet *)obj); + dlg->InitDialog(form, obj); + dlg->CreateAdditionalPages(); + dlg->Go(false); + dlg->CheckChange(); + return 0; +} + + +bool slonyMoveSetFactory::CheckEnable(pgObject *obj) +{ + if (!obj || ! obj->IsCreatedBy(setFactory)) + return false; + + slSet *set = (slSet *)obj; + + return set->GetOriginId() == set->GetCluster()->GetLocalNodeID() && !set->GetLockXXID().IsEmpty(); +} + + + diff --git a/slony/slSubscription.cpp b/slony/slSubscription.cpp new file mode 100644 index 0000000..1abd03d --- /dev/null +++ b/slony/slSubscription.cpp @@ -0,0 +1,294 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slSubscription.cpp PostgreSQL Slony-I subscription +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "slony/slSubscription.h" +#include "slony/slTable.h" +#include "slony/slSequence.h" +#include "frm/frmMain.h" + + + +slSubscription::slSubscription(slSet *s, const wxString &newName) + : slSetObject(s, slsubscriptionFactory, newName) +{ +} + +int slSubscription::GetIconId() +{ + if (GetReceiverId() == GetCluster()->GetLocalNodeID()) + return slsubscriptionFactory.GetIconId(); + else + return slsubscriptionFactory.GetExportedIconId(); +} + + +bool slSubscription::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("unsubscribeset(") + NumToStr(GetSet()->GetSlId()) + + wxT(", ") + NumToStr(GetReceiverId()) + + wxT(");")); + +} + + +wxString slSubscription::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony subscription"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony subscription"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony subscription \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony subscription \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony subscription cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony subscription?"); + break; + case PROPERTIESREPORT: + message = _("Slony subscription properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony subscription properties"); + break; + case DDLREPORT: + message = _("Slony subscription DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony subscription DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony subscription dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony subscription dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony subscription dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony subscription dependents"); + break; + } + + return message; +} + +bool slSubscription::CanCreate() +{ + return GetSet()->GetOriginId() != GetReceiverId() && slSetObject::CanCreate(); +} + + +bool slSubscription::CanDrop() +{ + return GetReceiverId() == GetCluster()->GetLocalNodeID(); +} + + +wxString slSubscription::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + if (GetReceiverId() != GetCluster()->GetLocalNodeID()) + sql = wxT("-- Subscription must be maintained on receiver node.\n"); + else + sql = wxT("-- subscribe replication set\n\n") + wxT(" SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("subscribeset(") + + NumToStr(GetSet()->GetSlId()) + wxT(", ") + + NumToStr(GetProviderId()) + wxT(", ") + + NumToStr(GetReceiverId()) + wxT(", ") + + BoolToStr(GetForward()) + wxT(");"); + } + return sql; +} + + +bool slSubscription::WantDummyChild() +{ + return GetSet()->GetOriginId() != GetCluster()->GetLocalNodeID(); +} + + +void slSubscription::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + + browser->RemoveDummyChild(this); + // Log + + if (WantDummyChild()) + { + wxTreeItemId id = browser->GetItemParent(browser->GetItemParent(GetId())); + if (id) + { + slSet *set = (slSet *)browser->GetObject(id); + if (set && set->IsCreatedBy(setFactory)) + { + wxLogInfo(wxT("Adding child object to subscription %s"), GetIdentifier().c_str()); + + browser->AppendCollection(this, slSequenceFactory); + browser->AppendCollection(this, slTableFactory); + } + } + } + } + + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Provider ID"), GetProviderId()); + properties->AppendItem(_("Provider Name"), GetProviderNode()); + properties->AppendItem(_("Receiver ID"), GetReceiverId()); + properties->AppendItem(_("Receiver Name"), GetReceiverNode()); + + properties->AppendYesNoItem(_("Active"), GetActive()); + properties->AppendYesNoItem(_("May forward"), GetForward()); + if (GetForward()) + properties->AppendYesNoItem(_("Is forwarded"), GetIsSubscribed()); + } +} + + + +pgObject *slSubscription::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *subscription = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + subscription = slsubscriptionFactory.CreateObjects(coll, 0, wxT(" WHERE sub_set=") + NumToStr(GetSet()->GetSlId()) + + wxT(" AND sub_receiver = ") + NumToStr(GetReceiverId()) + wxT("\n")); + return subscription; +} + + + +pgObject *slSubscriptionFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slSetObjCollection *collection = (slSetObjCollection *)coll; + slSubscription *subscription = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE sub_set = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + wxString prefix = collection->GetCluster()->GetSchemaPrefix(); + pgSet *subscriptions = collection->GetDatabase()->ExecuteSet( + wxT("SELECT sub_set, sub_provider, sub_receiver, sub_forward, sub_active,\n") + wxT(" re.no_comment as receiver_name, pr.no_comment as provider_name,\n") + wxT(" EXISTS (SELECT 1 FROM ") + prefix + wxT("sl_subscribe s2 WHERE s2.sub_provider = s1.sub_receiver AND s1.sub_set=s2.sub_set) AS is_subscribed\n") + wxT(" FROM ") + prefix + wxT("sl_subscribe s1\n") + wxT(" JOIN ") + prefix + wxT("sl_set ON set_id = sub_set\n") + wxT(" JOIN ") + prefix + wxT("sl_node pr ON pr.no_id = sub_provider\n") + wxT(" JOIN ") + prefix + wxT("sl_node re ON re.no_id = sub_receiver\n") + + restriction + + wxT(" ORDER BY sub_provider, sub_receiver")); + + if (subscriptions) + { + while (!subscriptions->Eof()) + { + subscription = new slSubscription(collection->GetSet(), subscriptions->GetVal(wxT("receiver_name"))); + subscription->iSetActive(subscriptions->GetBool(wxT("sub_active"))); + subscription->iSetForward(subscriptions->GetBool(wxT("sub_forward"))); + subscription->iSetReceiverId(subscriptions->GetLong(wxT("sub_receiver"))); + subscription->iSetProviderId(subscriptions->GetLong(wxT("sub_provider"))); + subscription->iSetReceiverNode(subscriptions->GetVal(wxT("receiver_name"))); + subscription->iSetProviderNode(subscriptions->GetVal(wxT("provider_name"))); + subscription->iSetIsSubscribed(subscriptions->GetBool(wxT("is_subscribed"))); + + if (browser) + { + browser->AppendObject(coll, subscription); + subscriptions->MoveNext(); + } + else + break; + } + + delete subscriptions; + } + return subscription; +} + + +wxString slSubscriptionCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony subscriptions"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony subscriptions"); + break; + case OBJECTSLISTREPORT: + message = _("Slony subscriptions list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/slsubscription.pngc" +#include "images/slsubscriptions.pngc" + +slSubscriptionFactory::slSubscriptionFactory() + : slSetObjFactory(__("Subscription"), __("New Subscription"), __("Create a new Subscription."), slsubscription_png_img) +{ + metaType = SLM_SUBSCRIPTION; +} + + +pgCollection *slSubscriptionFactory::CreateCollection(pgObject *obj) +{ + return new slSubscriptionCollection(GetCollectionFactory(), (slSet *)obj); +} + + +slSubscriptionFactory slsubscriptionFactory; +static pgaCollectionFactory cf(&slsubscriptionFactory, __("Subscriptions"), slsubscriptions_png_img); diff --git a/slony/slTable.cpp b/slony/slTable.cpp new file mode 100644 index 0000000..a9e8807 --- /dev/null +++ b/slony/slTable.cpp @@ -0,0 +1,277 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// slTable.cpp PostgreSQL Slony-I table +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +// App headers +#include "pgAdmin3.h" +#include "utils/misc.h" +#include "slony/slTable.h" +#include "frm/frmMain.h" + + +slTable::slTable(slSet *s, const wxString &newName) + : slSetObject(s, slTableFactory, newName) +{ +} + +bool slTable::DropObject(wxFrame *frame, ctlTree *browser, bool cascaded) +{ + return GetDatabase()->ExecuteVoid( + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + + wxT("setdroptable(") + NumToStr(GetSlId()) + wxT(");\n")); +} + + +wxString slTable::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony table"); + message += wxT(" ") + GetName(); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony table"); + message += wxT(" ") + GetName(); + break; + case DROPINCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony table \"%s\" including all objects that depend on it?"), + GetFullIdentifier().c_str()); + break; + case DROPEXCLUDINGDEPS: + message = wxString::Format(_("Are you sure you wish to drop Slony table \"%s\"?"), + GetFullIdentifier().c_str()); + break; + case DROPCASCADETITLE: + message = _("Drop Slony table cascaded?"); + break; + case DROPTITLE: + message = _("Drop Slony table?"); + break; + case PROPERTIESREPORT: + message = _("Slony table properties report"); + message += wxT(" - ") + GetName(); + break; + case PROPERTIES: + message = _("Slony table properties"); + break; + case DDLREPORT: + message = _("Slony table DDL report"); + message += wxT(" - ") + GetName(); + break; + case DDL: + message = _("Slony table DDL"); + break; + case DEPENDENCIESREPORT: + message = _("Slony table dependencies report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENCIES: + message = _("Slony table dependencies"); + break; + case DEPENDENTSREPORT: + message = _("Slony table dependents report"); + message += wxT(" - ") + GetName(); + break; + case DEPENDENTS: + message = _("Slony table dependents"); + break; + } + + return message; +} + +wxString slTable::GetSql(ctlTree *browser) +{ + if (sql.IsNull()) + { + sql = wxT("-- Register table ") + GetName() + wxT(" for replication.\n\n") + wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("setaddtable(") + + NumToStr(GetSet()->GetSlId()) + wxT(", ") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(GetName()) + wxT(", ") + + qtDbString(GetIndexName()) + wxT(", ") + + qtDbString(GetComment()) + wxT(");\n"); + + + size_t i; + for (i = 0 ; i < triggers.GetCount() ; i++) + { + sql += wxT("SELECT ") + GetCluster()->GetSchemaPrefix() + wxT("storetrigger(") + + NumToStr(GetSlId()) + wxT(", ") + + qtDbString(triggers[i]) + wxT(");\n"); + } + } + return sql; +} + + +void slTable::ShowTreeDetail(ctlTree *browser, frmMain *form, ctlListView *properties, ctlSQLBox *sqlPane) +{ + if (!expandedKids) + { + expandedKids = true; + pgSet *set; + + if (GetConnection()->BackendMinimumVersion(9, 0)) + { + set = GetConnection()->ExecuteSet( + wxT("SELECT tgname AS trig_tgname FROM pg_trigger t, pg_proc p, pg_namespace n ") + wxT("WHERE t.tgfoid = p.oid AND p.pronamespace = n.oid ") + wxT("AND n.nspname = ") + qtDbString(wxT("_") + GetCluster()->GetName())); + } + else + { + set = GetConnection()->ExecuteSet( + wxT("SELECT trig_tgname\n") + wxT(" FROM ") + GetCluster()->GetSchemaPrefix() + wxT("sl_trigger\n") + wxT(" WHERE trig_tabid = ") + NumToStr(GetSlId())); + } + + if (set) + { + while (!set->Eof()) + { + triggers.Add(set->GetVal(wxT("trig_tgname"))); + set->MoveNext(); + } + delete set; + } + } + + if (properties) + { + CreateListColumns(properties); + + properties->AppendItem(_("Name"), GetName()); + properties->AppendItem(_("ID"), GetSlId()); + properties->AppendItem(_("Index Name"), GetIndexName()); + properties->AppendYesNoItem(_("Altered"), GetAltered()); + + if (triggers.GetCount() > 0) + { + size_t i; + wxString triglist; + for (i = 0; i < triggers.GetCount() ; i++) + triglist += triggers[i] + wxT(", "); + + properties->AppendItem(_("Triggers"), triglist.BeforeLast(',')); + } + + properties->AppendItem(_("Comment"), firstLineOnly(GetComment())); + } +} + + + +pgObject *slTable::Refresh(ctlTree *browser, const wxTreeItemId item) +{ + pgObject *table = 0; + pgCollection *coll = browser->GetParentCollection(item); + if (coll) + table = slTableFactory.CreateObjects(coll, 0, wxT(" WHERE tab_id=") + NumToStr(GetSlId()) + wxT("\n")); + + return table; +} + + + +pgObject *slSlTableFactory::CreateObjects(pgCollection *coll, ctlTree *browser, const wxString &restr) +{ + slSetObjCollection *collection = (slSetObjCollection *)coll; + slTable *table = 0; + wxString restriction; + if (restr.IsEmpty()) + restriction = wxT(" WHERE tab_set = ") + NumToStr(collection->GetSlId()); + else + restriction = restr; + + pgSet *tables = collection->GetDatabase()->ExecuteSet( + wxT("SELECT tab_id, tab_reloid, tab_set, nspname, relname, tab_idxname, tab_altered, tab_comment") + wxT(" FROM ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_table\n") + wxT(" JOIN ") + collection->GetCluster()->GetSchemaPrefix() + wxT("sl_set ON set_id=tab_set\n") + wxT(" JOIN pg_class cl ON cl.oid=tab_reloid\n") + wxT(" JOIN pg_namespace nsp ON nsp.oid=relnamespace\n") + + restriction + + wxT(" ORDER BY tab_id")); + + if (tables) + { + while (!tables->Eof()) + { + table = new slTable(collection->GetSet(), tables->GetVal(wxT("nspname")) + wxT(".") + tables->GetVal(wxT("relname"))); + table->iSetSlId(tables->GetLong(wxT("tab_id"))); + table->iSetIndexName(tables->GetVal(wxT("tab_idxname"))); + table->iSetComment(tables->GetVal(wxT("tab_comment"))); + table->iSetAltered(tables->GetBool(wxT("tab_altered"))); + table->iSetOid(tables->GetOid(wxT("tab_reloid"))); + + if (browser) + { + browser->AppendObject(collection, table); + tables->MoveNext(); + } + else + break; + } + + delete tables; + } + return table; +} + + +wxString slSlTableCollection::GetTranslatedMessage(int kindOfMessage) const +{ + wxString message = wxEmptyString; + + switch (kindOfMessage) + { + case RETRIEVINGDETAILS: + message = _("Retrieving details on Slony tables"); + break; + case REFRESHINGDETAILS: + message = _("Refreshing Slony tables"); + break; + case OBJECTSLISTREPORT: + message = _("Slony tables list report"); + break; + } + + return message; +} + + +/////////////////////////////////////////////////// + +#include "images/table-repl.pngc" +#include "images/table-repl-sm.pngc" +#include "images/tables.pngc" + +slSlTableFactory::slSlTableFactory() + : slSetObjFactory(__("Table"), __("New Table"), __("Create a new Table."), table_repl_png_img, table_repl_sm_png_img) +{ + metaType = SLM_TABLE; +} + + +pgCollection *slSlTableFactory::CreateCollection(pgObject *obj) +{ + return new slSlTableCollection(GetCollectionFactory(), (slSet *)obj); +} + + +slSlTableFactory slTableFactory; +static pgaCollectionFactory cf(&slTableFactory, __("Tables"), tables_png_img); diff --git a/ui/_embed-xrc.bat b/ui/_embed-xrc.bat new file mode 100644 index 0000000..ef1ffeb --- /dev/null +++ b/ui/_embed-xrc.bat @@ -0,0 +1,13 @@ +@echo off +REM ####################################################################### +REM # +REM # pgAdmin III - PostgreSQL Tools +REM # Copyright (C) 2002 - 2016, The pgAdmin Development Team +REM # This software is released under the PostgreSQL Licence +REM # +REM # embed-xrc.bat - convert xrc files to c++ files +REM # +REM ####################################################################### + +"D:\wxWidgets-2.8.12\utils\wxrc\vc_msw\wxrc" -c -o xrcDialogs.cpp *.xrc + diff --git a/ui/_xrcDialogs.cpp b/ui/_xrcDialogs.cpp new file mode 100644 index 0000000..a9b26e3 --- /dev/null +++ b/ui/_xrcDialogs.cpp @@ -0,0 +1,39917 @@ +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 3537; +static unsigned char xml_res_file_0[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,80,114,101,99,105,115,105,111,110,83,99,97,108,101,68, +105,97,108,111,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,68,97, +116,97,116,121,112,101,32,112,114,111,112,101,114,116,105,101,115,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +49,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,49,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,97,108,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,99,97, +108,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_1 = 2978; +static unsigned char xml_res_file_1[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,84,97,98,108,101,78,97,109,101,68,105,97,108,111,103, +34,62,10,32,32,32,32,60,116,105,116,108,101,62,84,97,98,108,101,32,112, +114,111,112,101,114,116,105,101,115,60,47,116,105,116,108,101,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,49,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,49,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115, +117,97,108,84,97,98,108,101,78,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,117, +97,108,32,84,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85, +115,117,97,108,84,97,98,108,101,78,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_2 = 2897; +static unsigned char xml_res_file_2[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,100,100,70,97,118,111,117,114,105,116,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,65,100,100,32,102,97,118,111,117, +114,105,116,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,50,48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,49,54,44,50,50,53,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,84,105,116,108,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,105,116,108,101,34,47,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,111, +99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,84,114,101,101,34,32,110,97,109,101, +61,34,116,114,76,111,99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65,83,95,66,85,84, +84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95,66,79,82,68,69,82,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,78,101,119,70,111,108,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,70,111,108, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_3 = 12101; +static unsigned char xml_res_file_3[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,103,103,114,101,103,97,116,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,110,112,117,116,84,121,112,101,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,112,117,116,32,116,121,112,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,54,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116, +114,108,34,32,110,97,109,101,61,34,108,115,116,73,110,112,117,116,84,121, +112,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,38,97,109,112,59,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,54,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,112,117, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,116,97,116,101,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,116,97,116,101,32,116,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116, +97,116,101,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,116,97,116,101,70,117,110,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,97,116,101,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,116,97,116,101,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,105,110,97,108,70,117,110,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,110,97,108,32,102,117,110,99,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,70,105,110,97,108,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,114,116,79,112,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,114,116,32,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,111,114, +116,79,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +105,116,105,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,105,97,108,32,99, +111,110,100,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,73,110,105,116,105,97,108,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_4 = 7896; +static unsigned char xml_res_file_4[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,97,115,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,97,115,116,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,111,117,114,99,101,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,111,117,114,99,101,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,111,117,114,99,101,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114,103, +101,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,114,103,101,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,109, +112,108,105,99,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,109,112,108,105,99,105, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,109,112,108,105,99, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_5 = 6737; +static unsigned char xml_res_file_5[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,104,101,99,107,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,104,101,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,87, +104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,73,110,104,101,114,105,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,111,32,73,110,104,101,114,105,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +73,110,104,101,114,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,110,39,116,32,118,97,108,105,100,97,116,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_6 = 9024; +static unsigned char xml_res_file_6[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,108,97,116,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,50,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,53,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,111,99,97,108,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111, +99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,108,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,99,67,111,108,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,67,95,67,79,76,76,65,84,69,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,99,67, +111,108,108,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,99,67,116,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,67,95,67,84,89,80,69,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,99,67,116,121,112,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,99,111,108, +108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_7 = 13272; +static unsigned char xml_res_file_7[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,117,109,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,116,121,112,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76, +101,110,103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,44,49,48,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97, +117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,32,118,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +111,116,32,78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,116,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,116,116, +115,116,97,116,116,97,114,103,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,116, +105,115,116,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,116,116,115,116,97, +116,116,97,114,103,101,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,111,114,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_8 = 2535; +static unsigned char xml_res_file_8[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,110,101,99,116,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,67,111,110,110,101,99,116,32,116,111,32,83,101,114, +118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,50,48,53,44,56,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +48,53,44,32,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,69,110,116,101,114,32,116,104,101,32, +112,97,115,115,119,111,114,100,32,116,111,32,117,115,101,32,119,104,101, +110,32,99,111,110,110,101,99,116,105,110,103,32,116,111,32,116,104,101, +32,115,101,114,118,101,114,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116,111, +114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76, +80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,56,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_9 = 9325; +static unsigned char xml_res_file_9[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,118,101,114,115,105,111,110,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117, +108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,117,114,99,101,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,111,117,114,99,101,32,101,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,111,117,114,99,101,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,97,114,103,101,116,32,101,110,99,111,100,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_10 = 15692; +static unsigned char xml_res_file_10[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,55,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99, +111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112,108,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,97,116,104,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,97,116, +104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,98,108,101,115,112,97,99,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,108,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,114,97,99,116,101,114,32,116,121,112,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,83, +79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,110,101, +99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62, +45,49,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104, +101,109,97,82,101,115,116,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97, +32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,83,99,104,101,109,97,82,101,115,116,114,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110, +97,109,101,61,34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,54,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82, +69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97, +110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,114,85,115,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,114,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,85,115,101,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_11 = 3334; +static unsigned char xml_res_file_11[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,105,114,101,99,116,68,98,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,86,105,101,119,32,68,97,116,97,32,79,112,116, +105,111,110,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,52,53,48,44,50,49,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119, +115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,48,48,44, +49,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,101, +115,115,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,110,116,101,114,32,116,104,101, +32,114,101,113,117,105,114,101,100,32,118,97,108,117,101,115,32,102,111, +114,32,101,97,99,104,32,112,97,114,97,109,101,116,101,114,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,34,32, +110,97,109,101,61,34,103,114,100,80,97,114,97,109,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,83,101,116,32,116,104,101,32,102,117,110,99,116,105,111,110, +47,112,114,111,99,101,100,117,114,101,32,112,97,114,97,109,101,116,101, +114,32,118,97,108,117,101,115,46,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,80,107,103,73,110,105,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,98,117,103,32,112,97,99,107,97,103,101,32,105,110,105,116,105, +97,108,105,122,101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,101,98,117,103, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32, +99,117,114,114,101,110,116,32,111,112,116,105,111,110,115,32,97,110,100, +32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101, +46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99,101,108,32,97,110, +121,32,99,104,97,110,103,101,115,32,97,110,100,32,99,108,111,115,101,32, +116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_12 = 12541; +static unsigned char xml_res_file_12[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,111,109,97,105,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,97,115,101,32,116,121,112,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,101,110, +103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,49,49,50,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_13 = 6909; +static unsigned char xml_res_file_13[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,100,105,116,71,114,105,100,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,86,105,101,119,32, +68,97,116,97,32,79,112,116,105,111,110,115,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,83,111,114,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,83,111,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,108,98,108,83,111,114,116,67,111,108,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,101,108,101,99,116,101,100,32,67,111,108,117,109,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,111,114,116, +67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,76,105,115,116,115,32,116,104,101,32,99, +111,108,117,109,110,115,32,116,104,97,116,32,116,104,101,32,100,97,116, +97,32,119,105,108,108,32,98,101,32,115,111,114,116,101,100,32,98,121,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108, +65,118,97,105,108,67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,118,97,105,108, +97,98,108,101,32,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,111,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,83,101,108,101,99,116,32,97,32,99,111,108,117, +109,110,32,116,111,32,97,100,100,32,116,111,32,116,104,101,32,115,111,114, +116,32,108,105,115,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,44,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,65,115,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +115,99,101,110,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,65,100,100,32,116,104,101,32,115,101,108,101,99, +116,32,99,111,108,117,109,110,32,102,111,114,32,97,115,99,101,110,100,105, +110,103,32,115,111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,115,99,101,110,100, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,65,100,100,32,116,104,101,32,115,101,108,101,99,116,32,99,111,108,117, +109,110,32,102,111,114,32,100,101,115,99,101,110,100,105,110,103,32,115, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,101,114,115,112,101,99,116,105,118,101,62,49,60,47,112, +101,114,115,112,101,99,116,105,118,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,109,111,118, +101,32,116,104,101,32,115,101,108,101,99,116,101,100,32,115,111,114,116, +32,99,111,108,117,109,110,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,116,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,108,98,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,116, +101,114,32,83,116,114,105,110,103,32,40,101,103,46,32,111,105,100,32,38, +103,116,59,32,49,48,32,65,78,68,32,111,105,100,32,38,108,116,59,32,53,48, +41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,115,113, +108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,102,105,108,116,101,114,32,115,116,114,105,110,103, +32,116,111,32,97,112,112,108,121,32,116,111,32,116,104,101,32,100,97,116, +97,46,32,83,81,76,32,115,121,110,116,97,120,32,115,104,111,117,108,100, +32,98,101,32,117,115,101,100,32,97,115,32,116,104,101,32,115,116,114,105, +110,103,32,119,105,108,108,32,98,101,32,117,115,101,100,32,97,115,32,97, +32,39,87,72,69,82,69,39,32,99,108,97,117,115,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,86,97,108,105,100,97,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,86,97,108,105,100,97,116,101, +32,116,104,101,32,115,121,110,116,97,120,32,111,102,32,116,104,101,32,102, +105,108,116,101,114,32,115,116,114,105,110,103,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117,114,114, +101,110,116,32,111,112,116,105,111,110,115,32,97,110,100,32,99,108,111, +115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99, +101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110,100,32,99, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_14 = 9704; +static unsigned char xml_res_file_14[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,118,101,110,116,84,114,105,103,103,101,114,34, +62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +65,80,84,73,79,78,124,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,50,48,44,50,52,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,52,48,53,44,51,49,51,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,69,110,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,32,83,116,97,116,117,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,111,120,34,32,110,97,109,101,61,34,114,100,98,69,110,97,98,108, +101,83,116,97,116,117,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,78,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,82,69,80,76,73,67,65,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,65,76,87,65,89,83,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,51,56,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114, +105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,69,118,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68,76,32,67,79,77,77,65, +78,68,32,83,84,65,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68, +76,32,67,79,77,77,65,78,68,32,69,78,68,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,83,81,76,32,68,82,79,80,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,51,51,44,51,56,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,45,49,44,45,49,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,55,52,44,49,56,55,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105, +110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_15 = 6236; +static unsigned char xml_res_file_15[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120, +34,32,110,97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_16 = 6709; +static unsigned char xml_res_file_16[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,101,110,115,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,98,106,101,99,116,115,83,99,104,101,109,97,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,115,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,101,114,115,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_17 = 8453; +static unsigned char xml_res_file_17[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,105,110,100,82,101,112,108,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,70,105,110,100,32,97,110,100,32,82, +101,112,108,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,54,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,70,105,110,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,110,100,32,119,104,97,116,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,70,105,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,115,116,114,105,110,103,32,116,111,32,115,101,97, +114,99,104,32,102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,70,73,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,70,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,116,104,101,32, +115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,108,98,108,82,101,112,108,97,99,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,108,97, +99,101,32,119,105,116,104,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,82,101,112,108,97,99,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116, +101,114,32,116,104,101,32,114,101,112,108,97,99,101,109,101,110,116,32, +116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,80,76,65,67,69,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,82,101,112,108,97,99,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,70,105,110,100,32,97,110,100,32,114,101,112,108,97,99,101,32,116,104, +101,32,115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +82,69,80,76,65,67,69,65,76,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,112,108,97,99,101,32,38,97,109, +112,59,65,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,97, +110,100,32,114,101,112,108,97,99,101,32,97,108,108,32,111,99,99,117,114, +114,101,110,99,101,115,32,111,102,32,116,104,101,32,115,112,101,99,105, +102,105,101,100,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,98,79,114,105,103,105,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,114,105, +103,105,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,79,114,105,103,105,110,67,117,114,115,111,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +114,111,109,32,116,104,101,32,99,117,114,115,111,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,66,101, +103,105,110,32,115,101,97,114,99,104,105,110,103,32,97,116,32,116,104,101, +32,99,117,114,114,101,110,116,32,99,117,114,115,111,114,32,112,111,115, +105,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,100,79,114,105,103,105,110,84,111,112,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,114,111,109,32,116,104,101,32,116,111,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,66,101,103,105,110,32,115,101,97,114,99,104, +105,110,103,32,97,116,32,116,104,101,32,116,111,112,32,111,102,32,116,104, +101,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,98,68,105,114,101,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,105,114,101,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,100,68,105,114,101,99,116,105,111,110,70,111,114, +119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,111,114,119,97,114,100,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,83,101,97,114,99,104,32,102,111,114,119,97,114,100,115,32,116,104,114, +111,117,103,104,32,116,104,101,32,116,101,120,116,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,68,105,114,101, +99,116,105,111,110,66,97,99,107,119,97,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,97,99, +107,119,97,114,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,97,114,99,104,32,98,97,99,107,119,97,114,100,115,32,116,104,114,111, +117,103,104,32,116,104,101,32,116,101,120,116,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,98,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,87,104,111,108,101, +87,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,87,104,111,108,101,32,119,111,114,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,111,110, +32,119,104,111,108,101,32,119,111,114,100,115,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,77, +97,116,99,104,67,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,99,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,116, +104,101,32,99,97,115,101,32,111,102,32,116,104,101,32,116,101,120,116,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +79,112,116,105,111,110,115,85,115,101,82,101,103,101,120,112,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111, +110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,85,115,101,32,114, +101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111,110,115,32, +119,104,101,110,32,115,101,97,114,99,104,105,110,103,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,67,108,111,115,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_18 = 11336; +static unsigned char xml_res_file_18[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,68,97,116,97,87,114,97, +112,112,101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,110, +100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,108,105,100,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,86,97,108,105,100,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79, +77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79, +78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111, +118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104, +97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44, +55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_19 = 14711; +static unsigned char xml_res_file_19[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,75,101,121,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +101,114,114,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,101,102,101, +114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,101,102,101,114,114,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,99,104,70,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,102,117,108,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,77,97,116,99,104,70,117,108,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,111,110,116,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,110,39,116,32,118,97,108,105,100, +97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,111,110,116,86,97,108,105,100,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,117, +116,111,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111,32,70,75, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,73,110, +100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110,100, +101,120,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,118,101,114,105,110,103, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,110,100,101,120,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101, +102,101,114,101,110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,102, +101,114,101,110,99,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,102,101,114,101, +110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,117,109,110,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,76,111,99,97,108,32,99,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,101,102,67,111,108,117,109,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,102,101,114,101,110,99,105,110,103,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,82,101,102,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,82,101,102, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,82,101,102,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,65,99,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,85,112,100,97,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,68,101,108,101,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_20 = 11156; +static unsigned char xml_res_file_20[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57, +54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67, +116,114,108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,56,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66, +79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79, +82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,51,44,53,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +100,100,47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_21 = 17722; +static unsigned char xml_res_file_21[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,84,97,98,108,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,111,114,101,105,103,110,83,101,114,118,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,114,101,105,103,110,32,83,101,114,118,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117, +109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,67,111,108,117,109,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49, +44,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67, +111,109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76, +105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101, +109,98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101, +114,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,76,101,110,103,116,104,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,114,101, +99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,111,116,78,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,79,84,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,78,111,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79, +82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_22 = 26790; +static unsigned char xml_res_file_22[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,65,114,103,117,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114, +103,117,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,117, +109,101,110,116,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,82,101,116,117,114,110,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,116,117,114,110,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,82,101,116,117,114,110,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,110,103,117,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,76,97,110,103,117,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,111,108,97,116,105,108,105,116,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,111,108,97,116,105,108,105,116,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,86,111,108,97,116,105,108,105,116,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,86,79,76,65,84,73,76,69,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,84,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,77,77,85,84,65,66,76,69,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,101,116,111,102,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,101,116,117,114,110,115,32,115,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,101,116,111,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,114,105,99, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,83,116,114,105,99,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,101,99,117,114,101,68,101,102,105, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,101,99,117,114,105,116,121,32,111,102, +32,100,101,102,105,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,117,114, +101,68,101,102,105,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,87,105,110,100,111,119,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105,110, +100,111,119,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,87,105, +110,100,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,115,116,105,109,97,116,101,100,32, +99,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,115,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,111,119,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,69,115,116,105,109,97,116,101,100,32,114,111,119,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,101,97,107,80,114,111,111,102,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,101,97,107,32,112,114,111,111,102,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,76,101,97,107, +80,114,111,111,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,97,114,97,109,101,116,101,114,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,97,114,97,109,101,116,101,114,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,65,114,103, +117,109,101,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80, +79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,97,116,97,116,121,112,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,97,116,97,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,100,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,79,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,85,84, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,73,110,79,117,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,32,79,85,84,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,114,100,98,86,97,114,105,97,100,105, +99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,82,73,65,68,73,67, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,124,119,120,66,79,84,84,79,77,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,65,114,103,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114,103, +117,109,101,110,116,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,65,114,103,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,68, +101,102,86,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108, +116,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,68, +101,102,86,97,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72, +79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,72,65,78,71,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,100,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,98,106,101,99,116,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,32,102,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,79,98,106,101,99,116,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,105,110,107,83,121, +109,98,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,105,110,107,32,115,121, +109,98,111,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,105,110,107,83,121,109,98, +111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86, +97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86,97,114,105, +97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73, +78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,48,44, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,86,97,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,86,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_23 = 7226; +static unsigned char xml_res_file_23[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,71,114,111,117,112,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,71,114,111,117,112,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +101,109,98,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,101,109, +98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,115,78, +111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77,101,109,98,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,108,98,85,115,101,114,115,78,111,116,73,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120, +76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,103,116,59,38,103,116,59,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,68,101,108,85,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,108,116,59,38,108,116,59,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,84,79,80,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66, +111,120,34,32,110,97,109,101,61,34,108,98,85,115,101,114,115,73,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95, +83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_24 = 5724; +static unsigned char xml_res_file_24[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,72,98,97,67,111,110,102,105,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99,99,101,115, +115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,85,115,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,80,97,100,100,114,101,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +80,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,73,80,97,100,100,114,101,115,115,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,101, +116,104,111,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,116,104,111,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,77,101,116,104,111,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,112,116, +105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_25 = 16342; +static unsigned char xml_res_file_25[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101, +115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,110,105,113,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,85,110,105,113,117,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110, +105,113,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115, +116,101,114,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,67,108,117,115,116,101,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +110,99,117,114,114,101,110,116,108,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +99,117,114,114,101,110,116,32,98,117,105,108,100,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,111,110,99,117,114,114,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34, +99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112, +67,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,114,97,116, +111,114,32,99,108,97,115,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,67,108,97,115, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,69,83,67,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,117,108,108,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,85,76,76,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,48,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,98,78,117,108,108,115,70,105,114,115,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,73,82,83,84,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108, +115,76,97,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,65,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101, +109,111,118,101,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_26 = 16411; +static unsigned char xml_res_file_26[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,67,111,110,115,116,114,97,105, +110,116,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108, +101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,79,112,67,108,97,115,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,112,101,114,97,116,111,114,32,99,108,97,115,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,112,67,108,97,115,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,69,83,67,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,101,115,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,117,108,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,85,76,76,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +48,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108,115,70, +105,114,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,73,82,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,100,98,78,117,108,108,115,76,97,115,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,76,65,83,84,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,101,114,97, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_27 = 13557; +static unsigned char xml_res_file_27[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,74,111,98,34,62,10,32,32,32,32,60,116,105,116,108, +101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,50,56,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,50,53,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,74,111,98,99,108,97,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,74,111,98,32,99,108,97,115,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,74,111,98, +99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,111,115,116,65,103,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115,116,32, +97,103,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,65,103,101,110, +116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,114,101,97,116,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,114,101,97,116,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,114,101, +97,116,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,104,97,110,103,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,104,97,110,103,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,104,97, +110,103,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,101,120,116,114,117,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,101,120,116,32,114,117,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +101,120,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115,116,114,117, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,97,115,116,32,114,117,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,97,115,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115, +116,82,101,115,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,115,116,32,114,101, +115,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,97,115,116,82,101,115,117, +108,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,116,101,112,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,101,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,116,101,112, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120, +76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,67,104,97,110,103,101,83,116,101,112,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,83,116,101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,83,116, +101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,100,117,108,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95, +82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101,83,99,104,101, +100,117,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,65,100,100,83,99,104,101,100,117, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,82,101,109,111,118,101,83,99,104,101,100,117,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_28 = 8800; +static unsigned char xml_res_file_28[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,117,115,116,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,114,117,115,116,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114, +117,115,116,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,97,110,100,108, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,108,105,110,101,32,102,117,110, +99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,73,110,108,105,110,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,97,108,105,100,97,116,111,114,32,102,117,110,99, +116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_29 = 4926; +static unsigned char xml_res_file_29[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,105,110,67,111,110,102,105,103,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,50,52,56,44,49,57,56,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99, +114,105,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,48,44,54,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,50,51,56,44,57,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95, +78,79,95,65,85,84,79,82,69,83,73,90,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_30 = 2870; +static unsigned char xml_res_file_30[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,70,97,118,111,117,114,105,116, +101,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103, +101,32,102,97,118,111,117,114,105,116,101,115,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,49,56,44,49,57,56,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,116,114,76,111,99, +97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,50,48,56,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95, +66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,101,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,78,101,119,70,111,108,100, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,32,102,111,108,100,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_31 = 4804; +static unsigned char xml_res_file_31[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,77,97,99,114,111,115,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103,101,32,77,97,99, +114,111,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109, +101,61,34,108,115,116,75,101,121,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,115,105,122,101,62,49,53,48,100,60,47,109,105,110,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,44,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108, +83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113,108,66, +111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,48,48,44,49,48,48,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,108,101,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101, +97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,52,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,97,118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,97,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_32 = 3447; +static unsigned char xml_res_file_32[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,77,111,118,101,84,97,98,108,101,115,112,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,111,98,106,101, +99,116,115,32,116,111,32,97,110,111,116,104,101,114,32,116,97,98,108,101, +115,112,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,48,48,44,50,48,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,78,101,119,32,116,97,98, +108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,115,39,32, +107,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,98,106,101,99,116,115,39,32,111,119,110,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67, +69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_33 = 15920; +static unsigned char xml_res_file_33[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,76,101,102,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,101,102, +116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,102,116,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,82,105,103,104,116,84,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,105, +103,104,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,105,103,104,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,99,101,100,117,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,99,101,100,117,114,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +109,112,108,101,109,101,110,116,97,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,50,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,114, +105,99,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,115, +116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +74,111,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,102,117,110,99,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,74,111,105,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,117,116,97,116,111,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,117,116,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,109,109,117,116,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,101,103,97,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +101,103,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,78,101,103,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,102,116,83,111,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,102,116,32,115,111,114,116,32,111,112,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,76,101,102,116,83,111,114,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,105,103,104,116,83,111,114,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,105,103,104,116,32,115,111,114,116,32,111,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,105,103,104,116,83,111,114,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,115,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,32,111,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,115,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,71,114,101,97,116,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,38,103,116,59,32,111,112,101,114,97,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,71,114,101,97,116,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,97,110,72,97,115,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,112,111,114,116,115,32,104,97,115,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97, +110,72,97,115,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,77,101,114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,117,112,112,111,114, +116,115,32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97,110,77,101, +114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_34 = 7045; +static unsigned char xml_res_file_34[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,97,99,107,97,103,101,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,72,101,97,100,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,66,111,100, +121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124, +119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120,84,69,95,82, +73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_35 = 5366; +static unsigned char xml_res_file_35[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,103,112,97,115,115,67,111,110,102,105,103,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99, +99,101,115,115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60, +47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,111, +115,116,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,72,111,115,116,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,110,97, +109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,68,97,116,97,98,97,115,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,114,110,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114,110, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83, +87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,101,80,97,115,115,119,111,114, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80,97,115, +115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_36 = 3212; +static unsigned char xml_res_file_36[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,82,101,97,115,115,105,103,110,68,114,111,112,79,119,110,101, +100,34,62,10,32,32,32,32,60,116,105,116,108,101,62,82,101,97,115,115,105, +103,110,47,68,114,111,112,32,79,119,110,101,100,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,48,48,44,50,48,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,82,101,97,115,115,105,103,110,84, +111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,82,101,97,115,115,105,103,110,32,111,98,106,101, +99,116,115,32,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,111,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,114,98,68,114,111,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,114,111,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,70,114,111,109,32,100,97,116,97,98,97,115,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_37 = 9858; +static unsigned char xml_res_file_37[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,74,111,105,110, +67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,101,120, +105,115,116,105,110,103,32,99,108,117,115,116,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,74,111,105,110,67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,108,117,115,116,101,114,32,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,108,117, +115,116,101,114,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,111,100,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,73,68,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,109,105,110, +32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +65,100,109,105,110,78,111,100,101,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,65,100,109,105,110,78,111,100,101,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_38 = 5387; +static unsigned char xml_res_file_38[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,85,112,103, +114,97,100,101,34,62,10,32,32,32,32,60,116,105,116,108,101,62,85,112,103, +114,97,100,101,32,99,108,117,115,116,101,114,32,115,111,102,116,119,97, +114,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,117,114,114,101,110,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101,110,116, +32,118,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114, +101,110,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101, +114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115,116,101,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_39 = 4038; +static unsigned char xml_res_file_39[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,76,105,115,116,101,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,114,105,103,105, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101,99,101,105, +118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,82,101,99,101,105,118,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,118,105,100,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,111,118,105,100,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_40 = 3343; +static unsigned char xml_res_file_40[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,78,111,100,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_41 = 3939; +static unsigned char xml_res_file_41[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,80,97,116,104,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,73,110, +102,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,105,110,102, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,110,110,73,110,102,111,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,110,110,82,101,116,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,110,32,114,101,116,114,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,110,110,82,101,116,114,121,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_42 = 4031; +static unsigned char xml_res_file_42[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,113,117,101,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49, +50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,113, +117,101,110,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,101,113,117,101,110,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_43 = 4313; +static unsigned char xml_res_file_43[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,114,105,103,105,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,50,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51, +53,44,54,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_44 = 3396; +static unsigned char xml_res_file_44[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,101,114,103,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,101,114,103,101,32,115,101,116, +32,105,110,116,111,32,97,110,111,116,104,101,114,32,115,101,116,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49, +53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69, +124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69, +78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,116,111, +32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114, +103,101,116,32,111,102,32,109,101,114,103,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_45 = 3381; +static unsigned char xml_res_file_45[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,111,118,101,34,62,10,32, +32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,115,101,116,32,116, +111,32,111,116,104,101,114,32,110,111,100,101,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73, +68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,78,111,100,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,114,103,101,116,32,78,111,100,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,78,111,100,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_46 = 4740; +static unsigned char xml_res_file_46[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,117,98,115,99,114,105,112,116,105,111, +110,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60, +115,105,122,101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49, +54,44,49,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103, +105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,114,105,103,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,82,101,99,101,105,118,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +99,101,105,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,99,101,105,118, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,114, +111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,118,105,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,114,119,97,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,102,111,114,119,97,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,70,111,114,119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_47 = 5504; +static unsigned char xml_res_file_47[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,100, +101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +114,105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,114,105, +103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76,105, +115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,105,103, +103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,48,48,44,57,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_48 = 4089; +static unsigned char xml_res_file_48[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,115,111,117,114,99,101,71,114,111,117,112, +34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,71,114,112,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111, +117,112,32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,80,85,82,97,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80, +85,32,82,97,116,101,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +80,85,82,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,105,114,116,121,82,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,114,116,121,32,82,97,116,101,32,76,105,109, +105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,105,114,116,121,82,97,116,101,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,49,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +49,54,44,50,48,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,50,51,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_49 = 20602; +static unsigned char xml_res_file_49[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,111,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,55,48,44,50,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,54,54,44,50,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111, +108,101,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111, +114,100,32,40,97,103,97,105,110,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,99,99,111,117, +110,116,32,101,120,112,105,114,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,97,108,101,110,100,97, +114,66,111,120,34,32,110,97,109,101,61,34,100,97,116,86,97,108,105,100, +85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,80,95,65, +76,76,79,87,78,79,78,69,124,119,120,68,80,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109, +101,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109, +86,97,108,105,100,85,110,116,105,108,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110, +101,99,116,105,111,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +110,101,99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,110,110,101,99,116,105,111,110,76,105,109,105,116,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,32,112,114,105,118, +105,108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,82,111,108, +101,115,80,114,105,118,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,97,110,76,111,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,108,111,103,105,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,73,110,104,101,114,105,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,32,114,105,103,104,116,115,32,102,114,111, +109,32,112,97,114,101,110,116,32,114,111,108,101,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,83,117,112,101,114,117,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,101,114,117,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,32,99,114, +101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,82,111,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,99,114,101,97,116,101,32,114,111,108,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,85,112,100,97,116,101,67,97,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,109,111,100,105,102,121,32,99,97,116,97,108, +111,103,32,100,105,114,101,99,116,108,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,82,101,112,108,105,99,97,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,105,110,105,116,105,97,116,101,32,115,116,114,101,97, +109,105,110,103,32,114,101,112,108,105,99,97,116,105,111,110,32,97,110, +100,32,98,97,99,107,117,112,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,111,108,101,32,109,101,109,98,101,114,115,104,105,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,82,111,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,111,108,101,115,78,111,116,73,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,111,116,32,77,101,109,98,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,115,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,101,109,98,101,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,98,82,111,108, +101,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,65,100,100,82,111,108,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,103,116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,68,101,108,82,111,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,38,108,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84, +79,80,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,98,82,111,108,101,115,73,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,65,100,109,105,110,79,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,73,84,72,32,65,68,77,73,78,32,79,80,84,73,79,78,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,53,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,86, +97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114, +68,98,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97, +115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,114,68,98,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_50 = 8283; +static unsigned char xml_res_file_50[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,117,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,118,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,118,101,110,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +98,120,69,118,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,69,76,69,67,84,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,78,83,69,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +85,80,68,65,84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,69,76,69, +84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110, +115,105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,111,73,110,115,116, +101,97,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,32,105,110,115,116,101,97,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,111,73,110,115,116,101,97,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,110,100,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,100,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,67,111,110,100,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,101,109,101,110,116,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,97,116,101,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113, +108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_51 = 19358; +static unsigned char xml_res_file_51[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,100,117,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +53,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109, +101,61,34,99,97,108,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,110,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,69,110,100,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,121,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,68,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87, +101,101,107,32,68,97,121,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, +85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34, +99,104,107,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,45,49,44,55, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,83,117,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77, +111,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,117, +101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,87,101, +100,110,101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84, +104,117,114,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,70, +114,105,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,97,116, +117,114,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,110,116,104,32,68,97,121,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,77,111,110,116,104,100,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,99,104,107,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,45,49,44,55,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,49,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,50,110,100,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,114,100, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,52,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,53,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,54,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,55,116,104, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,56,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,57,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,49,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,49,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,50,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,51,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,49,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,50,110,100,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,51,114,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,51,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,76,97,115,116,32,100,97, +121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111, +110,116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, +84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,74,97,110,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +70,101,98,114,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +77,97,114,99,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,112,114, +105,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77,97,121,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,74,117,110,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,74,117,108,121,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,117,103,117,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,83,101,112,116,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,79,99,116,111,98,101,114,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,78,111,118,101,109,98,101,114,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,68,101,99,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,105,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,105,109, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,72,111,117,114,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,111,117,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76, +105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,45,49,44,49,48,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,110,117,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,77,105,110,117, +116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65, +87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,120,99,101,112,116,105,111,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,69,120,99,101,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,69,120,99,101,112,116,105,111,110,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,120,99,101,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69, +124,119,120,68,80,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,105,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,105,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109,101, +83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109,69, +120,99,101,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,69,120,99,101,112,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,69,120,99,101,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,82,101,109,111,118,101,69,120,99,101,112,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_52 = 5520; +static unsigned char xml_res_file_52[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,109,97,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_53 = 7618; +static unsigned char xml_res_file_53[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,97,114,99,104,79,98,106,101,99,116,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,83,101,97,114,99,104,32,79,98,106, +101,99,116,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,51,53,51,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76, +124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,71,114,105,100,66,97,103,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,51,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,48,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,97,116,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,116,116,101,114,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,97,116,116,101,114,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,69,110,116,101,114,32,112,97,114,116,32,111,102, +32,116,104,101,32,111,98,106,101,99,116,39,115,32,97,116,116,114,105,98, +117,116,101,32,121,111,117,39,114,101,32,108,111,111,107,105,110,103,32, +102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +83,101,97,114,99,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,105,110,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,112,111,115,62,49,44,48,60,47,99,101,108, +108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108, +108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +101,108,108,112,111,115,62,49,44,49,60,47,99,101,108,108,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110, +62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,55,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115, +62,50,44,48,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101, +108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,50,44, +49,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108, +115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,69,88,80,65,78,68,124,119, +120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,55,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,48,60,47, +99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,50,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,99,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,52,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108, +112,111,115,62,48,44,50,60,47,99,101,108,108,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,51,44,49, +60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,72,79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120, +84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,78,97,109,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,105,110,105,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,100,101, +102,105,110,105,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,109,109,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,99,111, +109,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,108,111,115,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32, +110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84, +95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_54 = 1165; +static unsigned char xml_res_file_54[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,108,101,99,116,67,111,110,110,101,99,116,105, +111,110,34,62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,110,101, +99,116,32,116,111,32,83,101,114,118,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,50,48,53,44,57,56,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44, +50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,110, +97,109,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,53,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,50,44,56,48,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,57,55,44,56,48,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,53,48,44,56,48,100,60,47,112,111,115,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_55 = 10154; +static unsigned char xml_res_file_55[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,52,55, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,110,99,114,101,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,99,114,101,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,73,110,99,114,101,109,101,110,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,77,105,110,105,109,117,109,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,105,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,77,97,120,105,109,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,97,99,104,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,99,104, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,97,99,104,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,99,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_56 = 24087; +static unsigned char xml_res_file_56[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,114,118,101,114,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,68,101,115,99, +114,105,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,101,114,118,105,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,105,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,105,110, +116,101,110,97,110,99,101,32,68,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,111,114,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,111,117,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,99,111,108,111,117,114, +80,105,99,107,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,83,76,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114, +32,82,111,111,116,32,67,101,114,116,105,102,105,99,97,116,101,32,70,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101, +114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +83,76,82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,83,83,76,32,82,111,111,116,32,67,101,114,116,105,102, +105,99,97,116,101,32,70,105,108,101,60,47,109,101,115,115,97,103,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105, +108,100,99,97,114,100,62,42,46,99,114,116,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,32,67, +101,114,116,105,102,105,99,97,116,101,32,82,101,118,111,99,97,116,105,111, +110,32,76,105,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105, +99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107, +101,114,83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,67,101,114,116,105,102,105,99,97,116,101,32,82,101, +118,111,99,97,116,105,111,110,32,76,105,115,116,32,70,105,108,101,60,47, +109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,99,114,108, +60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80, +95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,67,101,114,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,108,105,101,110,116,32,67,101,114,116,105,102,105,99,97,116,101, +32,70,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,83,83,76,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,99,101,114,116,105,102,105,99,97,116,101,32,102,105, +108,101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62, +42,46,99,114,116,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,83,76,75,101,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,108,105,101,110,116,32,75,101,121,32,70,105,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114, +108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,83,76,75,101,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,83,83,76,32,107, +101,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,46,107,101,121,60,47,119,105,108,100,99,97,114,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +32,67,111,109,112,114,101,115,115,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83, +76,67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,83,72,32,84,117,110,110,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,83,83,72,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,72,84,117,110, +110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,83,72,32,116,117,110, +110,101,108,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83,72,84,117,110,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,117,110,110,101, +108,72,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,117,110,110,101,108,32,104,111, +115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,84,117,110,110,101,108,72,111,115,116, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,117,110,110,101,108,80,111,114,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,117,110,110,101,108,32,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,117,110,110,101,108,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,117,110,110,101,108,85,115,101,114,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,85,115,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,117,116,104,101,110,116,105,99,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,104,101,110,116,105,99,97,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,49,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,49,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,97,100,105,111,66,116,110,80,97,115,115,119,111,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,97,100,105, +111,66,116,110,75,101,121,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,73,100,101,110,116,105,116,121,32,102,105,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,101,110, +116,105,116,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108, +101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,73,100,101,110,116,105,116,121,70,105,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,105,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,117,98,108,105,99,75,101, +121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,117,98,108,105,99,32,107,101, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67, +116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,80,117,98, +108,105,99,75,101,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,112,117,98,108,105,99,32,107,101,121,32,102,105,108,101, +60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,112, +117,98,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70, +76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,117,110,110,101,108,80,97,115,115, +119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,47,80, +97,115,115,112,104,114,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,65,100,118,97,110,99,101,100,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,97,108,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,111,115,116,65,100,100,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115, +116,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115, +116,65,100,100,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,121,67,111,110,110,101, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,110,111,119,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,114,121,67,111,110,110,101,99,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,82,101,115,116,111,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,115,116,111,114,101,32,101,110,118,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,82,101,115,116,111,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,82,111,108,101,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,98,82,101,115,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +66,32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,98,82,101,115,116,114,105,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,101,114,118,105,99,101,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,114,118,105,99,101,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_57 = 10963; +static unsigned char xml_res_file_57[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,116,101,112,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,55,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,110,101,99,116,105,111,110,32,84,121,112, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99, +97,108,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101, +62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,82,101,109,111,116, +101,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,116,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101, +110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101,110,97, +98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,110,101,99,116,105,111,110,32,83,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97, +98,108,101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,101,108,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108, +101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111, +120,34,32,110,97,109,101,61,34,114,98,120,75,105,110,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,83,81,76,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,66,97,116,99,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,105,110,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +105,109,101,110,115,105,111,110,62,49,60,47,100,105,109,101,110,115,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67, +79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34, +32,110,97,109,101,61,34,114,98,120,79,110,69,114,114,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,110,32,101,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,70,97,105,108,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,117,99,99,101,101,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,73,103,110,111,114,101,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47,100,105,109, +101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67, +73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_58 = 7474; +static unsigned char xml_res_file_58[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,121,110,111,110,121,109,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,97,114,103,101,116,84,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,97,114,103,101,116,32,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,114,103,101,116,32,115,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,83,99,104,101,109,97,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,79,98,106, +101,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,114,103,101,116,32,111,98,106,101, +99,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,79,98,106,101,99,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_59 = 40708; +static unsigned char xml_res_file_59[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,115, +112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,102,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,102,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,102,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,108,108,32,70,97,99,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,115, +79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,115,32,79,73,68,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,72,97,115,79,105,100,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,110,108,111,103,103,101,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,108,111,103,103,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,108, +111,103,103,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,73, +110,104,101,114,105,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,66,111,120,34,32,110,97,109,101,61,34,108,98,84,97,98,108,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100, +100,84,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,105,107,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82, +101,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,105,107,101,82,101, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,99,108,117,100,105,110,103,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110, +99,108,117,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,68,101,102,97,117,108,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,32,118,97,108,117,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108, +117,100,105,110,103,73,110,100,101,120,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,100,101,120,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117,100,105,110,103, +83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99, +107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,73,110,99,108,117,100,105,110,103,67,111,109,109,101,110,116,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,109,109,101,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,67,111,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108, +115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76, +67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,111,45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101, +108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45,118,97,99,117, +117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110,97,98, +108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,99,69,110,97,98,108,101,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101, +110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,98,97, +115,101,32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +66,97,115,101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,65,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,65,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,66,97,115,101,65,110,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,86,97,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97, +99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,86,97,99, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,78,65,76,89,90,69,32,115,99,97,108,101,32,102,97,99, +116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99, +68,101,108,97,121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,99,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85, +85,77,32,99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116, +67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101, +122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69, +69,90,69,32,109,105,110,105,109,117,109,32,97,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,114,101, +101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97, +98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69, +32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109,101,61,34,110, +98,112,84,111,97,115,116,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116, +32,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,117,115,116, +111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +117,115,116,111,109,32,97,117,116,111,45,118,97,99,117,117,109,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67, +85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,66,97,115,101,84,111,97,115,116,86,97,99,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,66,97,115,101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,84,111,97,115,116,86, +97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108, +101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116, +111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,68,101,108,97,121, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76, +105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99, +111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97, +115,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86, +97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77,97, +120,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109, +97,120,105,109,117,109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122, +101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90, +69,32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101, +101,122,101,84,97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_60 = 10511; +static unsigned char xml_res_file_60[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,53,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,111,99,97,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_61 = 12794; +static unsigned char xml_res_file_61[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,67,111,110,102, +105,103,117,114,97,116,105,111,110,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,97,114,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +97,114,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,80,97,114,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,112,121,32,67,111,110,102,105,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,111,112,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,111,107,101,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +111,107,101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,111,107,101,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,105,99,116,105,111,110,97,114,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,99,116,105,111,110,97,114,105,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,105,99,116,105,111,110,97,114,121,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,49,49,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,111,105,99,101,34,32,110,97,109,101,61,34,99,98,68,105,99,116,105, +111,110,97,114,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,54,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117, +115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117, +115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_62 = 11304; +static unsigned char xml_res_file_62[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,68,105,99,116, +105,111,110,97,114,121,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47, +115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114, +34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_63 = 10694; +static unsigned char xml_res_file_63[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,80,97,114,115, +101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,32, +70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116,97,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +71,101,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,101,116,116,111,107, +101,110,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,71,101, +116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,100,32,70, +117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,120,116,121,112, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,76,101,120,116,121,112,101,115,32,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,116,121,112,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,101,97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,108,105, +110,101,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,101, +97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_64 = 8482; +static unsigned char xml_res_file_64[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,120,105,122,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, +101,120,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101, +62,10}; + +static size_t xml_res_size_65 = 16584; +static unsigned char xml_res_file_65[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,114,105,103,103,101,114,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,56,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,119,32,116,114, +105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,111,119,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,110,115,116,114,97,105,110,116,32,116,114,105,103, +103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,67,111,110,115,116,114,97,105,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,97,98, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,114,105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,117,109,101, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,114,103,117,109,101,110,116,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,65,114,103,117,109,101,110,116,115,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,105,114,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,114,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,70,105,114,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,66,69,70,79,82,69,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,65,70,84,69,82,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,73,78,83,84,69,65,68,32,79,70,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,78,83,69,82,84,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,80,68,65,84,69,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,69,76,69,84,69,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,117,110,99, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,82,85,78,67,65,84,69,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116, +66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,124,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120, +84,69,95,82,73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_66 = 43189; +static unsigned char xml_res_file_66[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,121,112,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +100,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,67,111,109,112,111,115,105,116,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,110,117,109,101,114,97,116,105,111,110,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,69,120,116,101,114,110,97,108,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,82,97,110,103,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47, +100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95, +83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,44,50, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67,111, +109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116, +67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101,109,98,101, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,32, +110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,114,101,99,105,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,80,114,101,99,105,115,105,111,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,68,101,102,105,110,105,116,105,111,110,69,110,117,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,76,97,98,101,108,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,48,48,44, +49,53,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,98, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,98,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,97, +98,101,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,65,100,100,66,101,102,111,114,101,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,98,101,102,111, +114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,65,102,116,101,114,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,97,102,116,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,76,97,98,101,108,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78, +111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,68,101,102, +105,110,105,116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,113,117,105,114,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,110,112,117,116,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,117,116,112,117,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,117,116, +112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,97,108,32,49,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,101,99,101,105,118,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,99,101,105, +118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,101,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,101,110,100,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,101,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +121,112,109,111,100,32,105,110,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,111,117,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,109,111,100,32,111,117,116,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,111,117,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,116,101,114,110,97,108,32,108,101,110,103,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,110,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,86,97,114,105,97,98,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,114,105,97,98,108,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117,108,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,110,97,108,121,122,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,110, +97,108,121,122,101,32,102,117,110,99,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,110,97,108,121, +122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,116,101,103,111,114, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,114,114,97,121,32, +116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,105,116,101,109,62,66,111,111,108,101,97,110,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,67,111,109,112,111,115,105,116,101, +32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,68,97,116,101,47,116,105,109, +101,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,69,110,117,109,32,116,121, +112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,105,116,101,109,62,71,101,111,109,101,116,114,105,99,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,78,101,116,119,111,114,107,32,97,100, +100,114,101,115,115,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,117, +109,101,114,105,99,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,80,115,101, +117,100,111,45,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,116,114,105,110, +103,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,105,109,101,115,112,97, +110,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,85,115,101,114,45,100,101, +102,105,110,101,100,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,66,105, +116,45,115,116,114,105,110,103,32,116,121,112,101,115,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +117,110,107,110,111,119,110,32,116,121,112,101,115,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,80,114,101,102,101,114,101,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,102,101,114,101,100,63, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,80,114,101,102,101,114,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116, +105,111,110,97,108,32,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,108,101,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,105, +109,105,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,108,105,109,105,116,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,108,105,103,110,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,108,105,103,110,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,108,105,103,110, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,99,104,97,114,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,105,110,116,50,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,105,110,116,52,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,100,111,117,98,108,101,60, +47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,80,97,115,115,101,100,66,121,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,101,100,32,98,121,32,118,97,108,117,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,66,121,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,108,108,97,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108, +108,97,116,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,82,97,110,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,117,98,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112, +101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,98,116,121,112,101,32,111,112,101,114,97,116,111,114,32,99,108,97,115, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116, +121,112,101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,110,103,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,110,103,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,111,110,105,99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,97,110,111,110,105,99,97,108,32,102,117,110,99,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,97,110,111,110,105, +99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117, +98,116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,117,98,116,121,112,101,32,100,105,102,102,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98, +116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_67 = 15725; +static unsigned char xml_res_file_67[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,54,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115, +101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,115, +115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,105,100,85,110,116,105,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,65,99,99,111,117,110,116,32,101,120,112,105,114,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109,101,61,34,100, +97,116,86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97, +109,101,61,34,116,105,109,86,97,108,105,100,85,110,116,105,108,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116, +101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,111,108,101,32,112,114,105,118,105,108,101,103,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,82,111,108,101,115,80,114,105,118,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,99,97, +110,32,99,114,101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,85,115,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,117,112,101,114,117,115,101,114,32,40,99,97,110,32,99,114,101, +97,116,101,32,117,115,101,114,115,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,71,114,111,117,112,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,71,114,111,117,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77, +101,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101, +109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120, +34,32,110,97,109,101,61,34,108,98,71,114,111,117,112,115,78,111,116,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69, +68,95,83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,65,100,100,71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,103, +116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,68,101,108, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116,59,38,108, +116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84,79,80,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108, +98,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79, +82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,53,48,44,49,51,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110, +97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101, +32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_68 = 8224; +static unsigned char xml_res_file_68[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,77,97,112,112,105,110,103,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114, +108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84, +84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73, +90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53, +56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_69 = 36699; +static unsigned char xml_res_file_69[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,86,105,101,119,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,99, +117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,117,114,105,116,121,32,66,97,114,114,105,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,101,99,117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,87,105,116,104,32,67,104,101,99,107,32,79,112,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,76,111,99,97,108,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,97,115,99,97,100,101,100,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,68,101,102,105,110,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34, +116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,97,116,101,114,105,97,108,105,122,97,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,97,116,101,114,105,97,108,105, +122,101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,49,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,77,97,116,101,114,105,97,108,105,122, +101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,101, +114,105,97,108,105,122,101,100,32,86,105,101,119,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +77,97,116,101,114,105,97,108,105,122,101,100,86,105,101,119,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,50,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,49,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,86,97,99,117,117,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114, +111,119,115,62,51,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,97,98,108,101,83,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,111,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,108,32,70,97,99,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,108, +70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,86,105,101, +119,87,105,116,104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,105,116,104,32,68,97,116,97,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,77,97,116,86,105,101,119,87,105,116, +104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45, +118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,117,114,114,101,110,116,32,118,97,108,117, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66, +97,115,101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,66,97,115,101,65,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,66,97,115,101,65,110,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,66,97,115,101,65,110,67,117,114,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70, +97,99,116,111,114,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116,111,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99, +116,111,114,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,115, +99,97,108,101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97, +99,68,101,108,97,121,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,68,101,108,97, +121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111, +115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,86,97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109, +32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108, +101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,67,117,114, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,32,110,97,109,101,61,34,110,98,112,84,111,97,115,116, +86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116,32,116, +97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,117,115,116,111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111, +45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115, +116,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,117,114,114,101,110,116,32,118,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,84,111, +97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99, +116,111,114,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116, +111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +97,99,116,111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,97,99,116,111,114,84,111,97,115,116,86,97,99,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116, +32,100,101,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105,109,105,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32, +99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,76,105,109, +105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105, +109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +105,110,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108,101,32,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_70 = 18754; +static unsigned char xml_res_file_70[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,66,97,99,107,117,112,60,47,116,105,116,108,101,62,10, +32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,51,51,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69, +83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,56,53,44,50,50,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79,112, +116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,101, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114, +109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,112,114,101,115,115,32,82,97,116,105,111,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,99,111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,117,109,98,101,114,79,102,74,111,98,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,117,109,98,101,114,32,79,102,32,74,111,98,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,117,109,98,101,114,79,102,74,111,98,115,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,108,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111,110,115, +32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112,79,112,116, +105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,101,99,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,101,99,116,105,111,110,80,114,101,68,97,116, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100,97,116,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,115, +116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,32,79,102,32, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62, +119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32,100,97,116, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,66,108,111,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,108,111,98,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,111,110,39,116,32,115,97,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,78,111,79,119,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,78,111,80,114,105,118,105,108,101,103,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,114,105,118,105,108,101,103,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,78,111,84,97,98,108,101,115,112,97,99,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,85,110,108, +111,103,103,101,100,84,97,98,108,101,68,97,116,97,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,110,108,111,103,103,101,100,32,116,97,98,108,101,32,100,97, +116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111, +110,115,32,35,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,101,114,105,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,114,101,97,116,101,68,98,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,67,82,69,65,84, +69,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,114,111,112,68, +98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,68,82, +79,80,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108,117, +109,110,73,110,115,101,114,116,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,67,111,108,117,109,110,32,73,110,115,101,114,116,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,73,110,115,101,114,116,32,99, +111,109,109,97,110,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84, +73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,105,115, +97,98,108,101,68,111,108,108,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +111,108,108,97,114,32,113,117,111,116,105,110,103,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +77,105,115,99,101,108,108,97,110,111,117,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,85,115,101,83,101,116,83,101,115,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,32,83,69,84,32,83,69,83,83,73,79,78,32,65,85,84, +72,79,82,73,90,65,84,73,79,78,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105, +116,104,32,79,73,68,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111,116,101,70,111, +114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97,109, +101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65, +83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78,76,89,124,119, +120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_71 = 3997; +static unsigned char xml_res_file_71[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,71,108,111,98,97,108,115,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,71, +108,111,98,97,108,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116, +101,58,32,79,110,108,121,32,111,98,106,101,99,116,115,32,103,108,111,98, +97,108,32,116,111,32,116,104,101,32,101,110,116,105,114,101,32,100,97,116, +97,98,97,115,101,32,99,108,117,115,116,101,114,32,119,105,108,108,32,98, +101,32,98,97,99,107,101,100,92,110,117,112,46,32,84,104,101,32,98,97,99, +107,117,112,32,102,111,114,109,97,116,32,119,105,108,108,32,98,101,32,80, +76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111, +116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99,101,32,100, +111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32,105,100,101, +110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101,114,98,111, +115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,101,114,98,111,115,101,32,109,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,49,52,52,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,52,53,44,49,55,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,66,97,99,107,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78, +67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_72 = 3924; +static unsigned char xml_res_file_72[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,83,101,114,118,101,114,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,83,101, +114,118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101, +110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111, +108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,55, +48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,101,58,32,84,104, +101,32,98,97,99,107,117,112,32,102,111,114,109,97,116,32,119,105,108,108, +32,98,101,32,80,76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101, +81,117,111,116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49, +48,44,49,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109,101, +115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,49,52,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,52,53,44,49,55,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97,103,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95, +82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49, +51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_73 = 3589; +static unsigned char xml_res_file_73[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,69,120,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,69,120,112,111,114,116,32,100,97,116,97,32,116,111,32, +102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,53,51,44,49,52,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,114,98,82,111,119,83,101,112, +97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,119,32,115,101,112,97,114,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,51,56,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +98,76,70,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,70,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60, +47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44, +49,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,67,82,76,70,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,82,47,76,70,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,50,57,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,108,117,109,110,32,115,101,112,97,114,97,116,111, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60, +47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,60,112,111,115,62,49,48,48,44,53,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,67,104,97,114, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32, +99,104,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,55,48,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,81,117,111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60,47,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101,99,116, +105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32, +32,32,32,32,60,112,111,115,62,49,48,48,44,54,56,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,110,97,109,101,115,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,32, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,108,110,97,109,101,115,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,60,112,111,115,62,49,48,48,44,56,51,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,50,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111, +100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,51,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,51,56,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99,97,108,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,99,97,108,32,99,104, +97,114,115,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,52,48,44,49,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82, +97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98, +85,110,105,99,111,100,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,105,99,111,100,101,32,85,84,70,45,56,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,48,44,50,57,100,60,47,112, +111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,81,117,111,116,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,49,51,48,44,52,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,81,117,111,116,101,78, +111,110,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,110,111, +32,113,117,111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,52,48,44,54,48,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,98,81,117,111,116,101,83,116,114,105,110,103,115,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,111,110,108,121,32,115,116,114,105,110, +103,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117, +101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,52,48,44,55,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,98,81,117,111,116,101,65,108,108,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,97,108,108,32,99,111,108,117,109,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49, +52,48,44,56,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,49,48,55,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,48, +44,49,48,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,51,53,44,49,48,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,116,121,108,101,47,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,52,55,44,49,50,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,48,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112,111,115,62, +50,48,48,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_74 = 1443; +static unsigned char xml_res_file_74[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,71,114,97,110,116,87,105,122,97,114,100,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,71,114,97,110,116,32,87,105,122,97, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,48,48,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111, +111,107,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,108,101,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,83,101,108,101,99,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,76,105,115,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,51,44,50,51,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,107,65,108,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,52,48,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,85,110,99,104,107,65,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,110,99,104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,52,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,115,101,108, +101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,57,53,44,50,55,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,44,50,56,53, +100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,57,51,44,50,56,53,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,50,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101, +115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_75 = 3111; +static unsigned char xml_res_file_75[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,72,105,110,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,62,112,103,65,100,109,105,110,32,71,117,114,117,32,72,105,110,116, +60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,48, +48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,72,116,109, +108,87,105,110,100,111,119,34,32,110,97,109,101,61,34,104,116,109,108,72, +105,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,60,109,105,110,115,105,122,101,62,51,48,48,44,50,48,48,100,60, +47,109,105,110,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117, +112,112,114,101,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,111,32,110,111,116,32,115,104,111,119,32,116,104,105,115, +32,104,105,110,116,32,97,103,97,105,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,70,105,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,70,105,120,32,105,116,33,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,89,69,83,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,89,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,78,79,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,78, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51, +44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_76 = 12319; +static unsigned char xml_res_file_76[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,73,109,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,73,109,112,111,114,116,32,100,97,116,97,32,102,114,111, +109,32,102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,51,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,56,53,44,49,50,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,70,105,108,101,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,73,109,112,111,114,116,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62, +83,101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,105, +109,112,111,114,116,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95, +84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114, +100,62,42,46,99,115,118,59,42,46,42,59,42,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,69,110,116,101,114,32,97,32,102,105,108, +101,110,97,109,101,32,116,111,32,105,109,112,111,114,116,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114,109, +97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,116, +101,120,116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,99,115,118,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,98,105,110,97,114,121,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62, +48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,67, +111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109, +110,115,84,111,73,109,112,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108, +117,109,110,115,32,116,111,32,105,109,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,115,116,67,111,108,117,109,110,115,84,111,73,109,112,111, +114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,105,115,99,46,32,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,105,115,99,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,72,101,97,100,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,108,105,109,105,116,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,101,108, +105,109,105,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,44,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,91, +116,97,98,93,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,111,116,101, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,111,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,81,117,111,116,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,115,99,97,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,115,99,97,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,115,99, +97,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,85,76,76,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,78,117,108,108,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,117,108,108,83,116,114,105,110,103,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,85,76,76,32,115,116,114,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,103,110,111, +114,101,70,111,114,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,103, +110,111,114,101,32,102,111,114,32,99,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,108,115,116,73,103,110,111,114,101,70,111,114,67,111, +108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,97,117,103,101, +34,32,110,97,109,101,61,34,103,97,117,103,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,73,109,112,111,114,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_77 = 5178; +static unsigned char xml_res_file_77[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,77,97,105,110,116,101,110,97,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,105,110,116,101,110,97,110, +99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62, +50,48,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95, +66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,120,65,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,77,97,105,110,116,101,110,97,110,99,101, +32,111,112,101,114,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,86,65,67,85,85,77,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,65,78,65,76,89,90,69,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,82,69,73,78,68,69,88,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,76,85,83,84,69,82,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89, +95,82,79,87,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,111,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,70,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,114,101, +101,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,65,110,97,108,121,122,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101, +114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109, +101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97, +103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120, +84,69,95,82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117, +108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_78 = 68517; +static unsigned char xml_res_file_78[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,79,112,116,105,111,110,115,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,79,112,116,105,111,110,115,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,52,56,48,44,50,53,48,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,109,101,110,117, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,48,48,44,50,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72, +65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82, +68,69,82,124,119,120,84,82,95,72,73,68,69,95,82,79,79,84,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,44,49,44,50,44,51,44,52,44,53,44,54,44,55,44,56,44,57, +44,49,48,44,49,49,44,49,50,44,49,51,44,49,52,44,49,53,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,71,32,104,101,108,112,32,112, +97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,116,104,101,32,112,97,116,104,32,111,114,32,85,82,76,32,116,111,32,116, +104,101,32,80,111,115,116,103,114,101,83,81,76,32,100,111,99,117,109,101, +110,116,97,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,100,98,72,101,108,112,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,68,66,32,104,101,108,112,32,112,97,116,104,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,69,100,98,72,101,108,112,80,97,116,104,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,71,112,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,80,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +71,112,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,72, +101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +110,121,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83, +108,111,110,121,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,85,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,114,32,108,97,110,103,117,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,121,115,116,101,109,83,99,104,101, +109,97,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,121,115,116,101,109,32, +115,99,104,101,109,97,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,121,115,116,101, +109,83,99,104,101,109,97,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,66,114,111,119,115,101, +114,68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100, +100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,105,115,112,108,97,121,32,116,104,101,32,102,111,108,108,111,119, +105,110,103,32,100,97,116,97,98,97,115,101,32,111,98,106,101,99,116,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,115,116, +68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,68,101,102,97,117,108,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,80,114,111,112, +101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,65,117,116,111,82,111,119,67,111,117,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,117,110,116,32,114,111,119,115, +32,105,102,32,101,115,116,105,109,97,116,101,100,32,108,101,115,115,32, +116,104,97,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,65,117,116,111,82,111,119,67, +111,117,110,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,66,105,110,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,53,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,108,111,110,121,45,73,32,112,97, +116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99,107, +101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,108,111,110,121,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101, +62,83,101,108,101,99,116,32,100,105,114,101,99,116,111,114,121,32,119,105, +116,104,32,83,108,111,110,121,45,73,32,99,114,101,97,116,105,111,110,32, +115,99,114,105,112,116,115,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,111, +115,116,103,114,101,115,113,108,80,97,116,104,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,71,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,80,111,115,116,103,114,101,115,113,108,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,100,105,114,101,99,116,111,114,121,32,119,105,116,104,32,80,111,115, +116,103,114,101,83,81,76,32,117,116,105,108,105,116,105,101,115,60,47,109, +101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82, +80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,69,110,116,101,114,112,114,105,115,101, +100,98,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,68,66,32,98,105, +110,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,110,116,101,114,112,114,105,115,101,100,98,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101, +99,116,111,114,121,32,119,105,116,104,32,69,110,116,101,114,112,114,105, +115,101,68,66,32,117,116,105,108,105,116,105,101,115,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85, +83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,71,80,68,66,80,97,116,104,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,71,80,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,71,80,68,66,80,97,116,104,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101,99,116,111, +114,121,32,119,105,116,104,32,71,114,101,101,110,112,108,117,109,68,66, +32,117,116,105,108,105,116,105,101,115,60,47,109,101,115,115,97,103,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69, +88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,73,103,110,111,114,101,86,101,114,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,103,110,111,114,101,32,115,101,114,118,101,114,47,117, +116,105,108,105,116,121,32,118,101,114,115,105,111,110,32,109,105,115,109, +97,116,99,104,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,101,114,115,105,111,110,77,105,115,109,97,116,99,104,87,97, +114,110,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97,114,110,105, +110,103,58,32,66,97,99,107,117,112,32,111,114,32,114,101,115,116,111,114, +101,32,111,112,101,114,97,116,105,111,110,115,32,109,97,121,32,102,97,105, +108,32,105,102,32,116,104,101,32,80,111,115,116,103,114,101,83,81,76,32, +117,116,105,108,105,116,105,101,115,32,100,111,32,110,111,116,32,109,97, +116,99,104,32,116,104,101,32,115,101,114,118,101,114,32,118,101,114,115, +105,111,110,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,66,114,111,119,115,101,114,77,105,115,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60, +47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115,107,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,114, +109,32,111,98,106,101,99,116,32,100,101,108,101,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,121,115,116,101,109,79, +98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32, +83,121,115,116,101,109,32,79,98,106,101,99,116,115,32,105,110,32,116,104, +101,32,116,114,101,101,118,105,101,119,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,104,111,119,85,115,101,114,115,70,111,114,80, +114,105,118,105,108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,117,115,101,114,115,32,102,111,114,32,112,114,105,118,105, +108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,111,117,98,108,101,67,108,105,99,107,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,111,98,106, +101,99,116,32,112,114,111,112,101,114,116,105,101,115,32,111,110,32,100, +111,117,98,108,101,32,99,108,105,99,107,32,105,110,32,116,114,101,101,118, +105,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,104, +111,119,78,111,116,105,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104, +111,119,32,78,79,84,73,67,69,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,102,114,101,115,104,79,110,67,108,105,99,107,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,102,114,101,115,104,32,111,110,32, +99,108,105,99,107,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,82,101,102,114,101,115,104,79,110, +67,108,105,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,110,101,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102,114,101, +115,104,32,111,98,106,101,99,116,32,111,110,32,99,108,105,99,107,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102, +114,101,115,104,32,111,98,106,101,99,116,32,97,110,100,32,99,104,105,108, +100,114,101,110,32,111,110,32,99,108,105,99,107,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,69,100,105, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,113,108,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,111,110,116, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,83,113,108,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,67, +111,108,83,105,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,46,32, +99,104,97,114,97,99,116,101,114,115,32,112,101,114,32,99,111,108,117,109, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,77,97,120,67,111,108,83,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,62,50,53,54,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,73,110,100,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,73,110,100,101,110,116,32,99,104,97,114,97,99,116,101,114,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,73,110,100,101,110,116,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,112,97, +99,101,115,70,111,114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,115,112,97,99,101,115,32,105,110,115,116,101,97,100,32,111,102, +32,116,97,98,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,112,97,99,101,115,70,111, +114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,105,99,107,121, +83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,83,81,76, +32,102,114,111,109,32,109,97,105,110,32,119,105,110,100,111,119,32,116, +111,32,113,117,101,114,121,32,116,111,111,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116, +105,99,107,121,83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,82,111,108,108,98,97,99,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,32, +82,79,76,76,66,65,67,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,82, +111,108,108,98,97,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,67,111,109,109,105,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,67,111,109, +109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,67,111,109,109, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,75,101,121,119,111,114,100,73,110,85,112,112,101,114,99,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100,115,32,105, +110,32,117,112,112,101,114,99,97,115,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,75,101, +121,119,111,114,100,115,73,110,85,112,112,101,114,99,97,115,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,120,116,70, +111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,116, +101,114,110,97,108,32,102,111,114,109,97,116,116,105,110,103,32,117,116, +108,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,120,116,70,111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115, +115,97,103,101,62,83,101,108,101,99,116,32,117,116,105,108,105,116,121, +32,116,111,32,102,111,114,109,97,116,32,116,101,120,116,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,60,47,119,105, +108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95, +79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,65,32, +99,111,109,109,97,110,100,32,108,105,110,101,32,117,116,105,108,105,116, +121,32,119,104,105,99,104,32,114,101,97,100,115,32,83,84,68,73,78,32,97, +110,100,32,100,105,114,101,99,116,115,32,111,117,116,112,117,116,32,116, +111,32,83,84,68,79,85,84,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,67,111,108, +111,117,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,111,114,101,103,114,111,117,110, +100,47,66,97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47, +111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,81,76,85,115,101,83,121,115,116,101,109,66, +97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,115,121,115,116, +101,109,32,98,97,99,107,103,114,111,117,110,100,32,99,111,108,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,117,115,116,111,109, +66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32, +98,97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,66,97,99,107,103,114, +111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,83,81,76,85,115,101,83,121,115,116,101,109,70,111, +114,101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,115,121,115,116,101, +109,32,102,111,114,101,103,114,111,117,110,100,32,99,111,108,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,117,115,116,111,109, +70,111,114,101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109, +32,102,111,114,101,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,70,111,114, +101,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,77,97,114,103,105,110, +66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,114,103,105,110,32,98, +97,99,107,103,114,111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,77,97,114,103,105, +110,66,97,99,107,103,114,111,117,110,100,67,111,108,111,117,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,114, +101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,97,114,101,116,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,97,114,101,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99, +107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76, +67,97,114,101,116,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,81,76,32,83,121,110,116, +97,120,32,72,105,103,104,108,105,103,104,116,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,117,108, +116,105,108,105,110,101,32,99,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80, +105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +81,76,67,111,108,111,117,114,49,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,81,76,67,111,108,111,117,114,54,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,111,117,98,108,101,32,113,117, +111,116,101,100,32,115,116,114,105,110,103,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108, +111,117,114,54,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55, +48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,81,76,67,111,108,111,117,114,50,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,105,110,103,108,101,32,108,105,110,101,32,99,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,50,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108, +111,117,114,55,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,105,110,103,108,101,32,113,117,111,116,101,100,32,115,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,83,81,76,67,111,108,111,117,114,55,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,81,76,32, +100,111,99,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,51,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117, +114,49,48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112, +101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97, +109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,49, +48,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,111,108,111,117,114,52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,117,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117, +114,52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83, +81,76,67,111,108,111,117,114,49,49,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,100,101,110,116,105,102,105,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,81,76,67,111,108,111,117,114,49,49,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114,53,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108, +111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99, +107,101,114,83,81,76,67,111,108,111,117,114,53,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,82,101,115, +117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,112,121,81,117,111,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,115,117,108,116,32,99,111,112,121,32,113,117, +111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,81,117,111,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,78,111,110,101,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +83,116,114,105,110,103,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,108,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,81,117, +111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +117,108,116,32,99,111,112,121,32,113,117,111,116,101,32,99,104,97,114,97, +99,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,81,117,111,116,101, +67,104,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,83,101, +112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +117,108,116,32,99,111,112,121,32,102,105,101,108,100,32,115,101,112,97, +114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,111,112,121,83,101,112,97,114, +97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,124,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,97,98,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,110,100,105,99,97,116,101,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,78,85,76,76,32,118, +97,108,117,101,115,32,97,115,32,38,108,116,59,78,85,76,76,38,103,116,59, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,73,110,100,105,99,97,116,101,78,117,108,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,104, +111,117,115,97,110,100,115,83,101,112,97,114,97,116,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,104,111,117,115,97,110,100,115,32,115,101,112,97, +114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,104,111,117,115,97,110, +100,115,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,99,105,109,97,108,77, +97,114,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,99,105,109,97,108,32, +109,97,114,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,99,105,109,97,108,77, +97,114,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,111,108,117,109,110,78,97,109,101,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,112,121,32,99,111,108,117,109,110,32,110,97,109,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,67,111,108,117,109,110,78,97,109,101,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60, +47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +81,117,101,114,121,84,111,111,108,70,105,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110, +62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,105,99,111, +100,101,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,97,100, +32,97,110,100,32,119,114,105,116,101,32,85,110,105,99,111,100,101,32,85, +84,70,45,56,32,102,105,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,87,114,105,116,101,66,79,77,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,87,114,105,116,101,32,66,79,77,32,102,111,114,32,85,84,70,32,102, +105,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115, +107,83,97,118,101,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,32,110,111,116,32,112,114,111,109,112,116,32,102,111,114, +32,117,110,115,97,118,101,100,32,102,105,108,101,115,32,111,110,32,101, +120,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,81,117,101,114,121,84,111,111,108,70,97,118,111,117,114,105,116,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,97,118,111,117,114,105,116,101,115,70,105,108,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,97,118,111,117,114,105,116,101,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,70,97,118,111,117,114,105,116,101,115,70,105,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,102,105, +108,101,32,116,111,32,115,116,111,114,101,32,102,97,118,111,117,114,105, +116,101,115,32,113,117,101,114,105,101,115,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121,84, +111,111,108,77,97,99,114,111,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,99,114,111,115,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,114,111,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,77,97,99,114,111,115,70,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,102,105,108,101,32,116,111, +32,115,116,111,114,101,32,109,97,99,114,111,115,60,47,109,101,115,115,97, +103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78, +124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121, +84,111,111,108,72,105,115,116,111,114,121,70,105,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,105,115,116, +111,114,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,105,115, +116,111,114,121,32,102,105,108,101,32,112,97,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114,108,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,72,105,115,116,111,114,121,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,102,105,108,101,32,116,111,32,115,116,111,114,101,32,113,117,101,114, +105,101,115,32,104,105,115,116,111,114,121,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,108,98,108,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +97,120,105,109,117,109,32,113,117,101,114,105,101,115,32,116,111,32,115, +116,111,114,101,32,105,110,32,104,105,115,116,111,114,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49, +48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,72,105, +115,116,111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,97,120,105,109,117,109,32,115,105,122,101,32, +111,102,32,97,32,115,116,111,114,101,100,32,113,117,101,114,121,32,40,105, +110,32,98,121,116,101,115,41,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116, +111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,48,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,83,101,114,118,101,114,83,116,97,116,117,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,108,101, +80,114,111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,100,108,101,32,80,114,111,99,101,115,115,32,67,111,108,111,117, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,73,100,108,101,80,114,111,99,101,115,115,67,111,108,111, +117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,99,116,105,118,101,80,114, +111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,99,116,105,118,101,32,80,114,111,99,101,115,115,32,67,111,108,111, +117,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +65,99,116,105,118,101,80,114,111,99,101,115,115,67,111,108,111,117,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,108,111,119,80,114,111,99,101,115, +115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +119,32,80,114,111,99,101,115,115,32,67,111,108,111,117,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,83,108,111,119,80,114,111,99,101, +115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,108, +111,99,107,101,100,80,114,111,99,101,115,115,67,111,108,111,117,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,108,111,99,107,101,100,32,80,114,111,99, +101,115,115,32,67,111,108,111,117,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,66,108,111,99,107,101,100,80,114,111,99,101,115,115, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,97,116, +97,98,97,115,101,68,101,115,105,103,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109, +101,61,34,112,105,99,107,101,114,70,111,110,116,68,68,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,103,65,103,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,82,111,119, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,105,109,117,109,32, +114,111,119,115,32,116,111,32,114,101,116,114,105,101,118,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,82, +111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,48,48,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,120, +105,109,117,109,115,32,114,111,119,115,32,116,111,32,114,101,116,114,105, +101,118,101,32,105,110,116,111,32,111,117,116,112,117,116,32,119,105,110, +100,111,119,59,32,48,32,61,32,117,110,108,105,109,105,116,101,100,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +77,105,115,99,71,117,114,117,72,105,110,116,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117,112,112,114, +101,115,115,72,105,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,32, +110,111,116,32,115,104,111,119,32,103,117,114,117,32,104,105,110,116,115, +59,32,73,39,109,32,111,110,101,32,109,121,115,101,108,102,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,101,115,101,116,72,105, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,101,116,32,103, +117,114,117,32,104,105,110,116,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,77,105,115,99,76,111,103,103,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,76,111,103, +102,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,103,102,105,108, +101,32,40,37,73,68,32,119,105,108,108,32,98,101,32,114,101,112,108,97,99, +101,100,32,119,105,116,104,32,116,104,101,32,80,114,111,99,101,115,115, +32,73,68,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105, +108,101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34, +112,105,99,107,101,114,76,111,103,102,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,108,111,103,32,102,105,108, +101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88, +84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,110,116,101,114,32,97,32,102,105,108,101,110,97,109,101,32, +116,111,32,119,114,105,116,101,32,97,112,112,108,105,99,97,116,105,111, +110,32,108,111,103,115,32,116,111,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,97,100,76,111,103,108,101,118,101,108,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,103,32,76,101,118,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,78,111,32,108,111,103,103,105,110,103,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,38,97,109,112,59,69,114,114,111,114, +115,32,111,110,108,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,69,114,114,111,114,115,32,97,110,100,32,78,38,97,109,112,59,111, +116,105,99,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,69,114,114,111,114,115,44,32,78,111,116,105,99,101,115,44,32,38,97,109, +112,59,83,81,76,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,68,101,98,117,103,32,40,110,111,116,32,114,101,99,111, +109,109,101,110,100,101,100,32,102,111,114,32,110,111,114,109,97,108,32, +117,115,101,41,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,50,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116, +32,116,104,101,32,108,101,118,101,108,32,111,102,32,100,101,116,97,105, +108,32,116,111,32,114,101,99,111,114,100,32,105,110,32,116,104,101,32,108, +111,103,102,105,108,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117, +114,114,101,110,116,32,115,101,116,116,105,110,103,115,32,97,110,100,32, +99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +97,110,99,101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110, +100,32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117, +101,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_79 = 1417; +static unsigned char xml_res_file_79[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +60,116,105,116,108,101,62,67,104,97,110,103,101,32,80,97,115,115,119,111, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,49,55,53,44,55,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,67,117,114,114, +101,110,116,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114,101,110, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,55,48,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,48,48,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,78,101,119,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,80,97,115,115, +119,111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,101,119,34,62,10,32,32,32,32,32,32,60,112,111, +115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,108,98,108,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,110,102,105,114,109,32,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,51,55,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65, +83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,54,51,44,53,53,100,60,47, +112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,50,48,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_80 = 5273; +static unsigned char xml_res_file_80[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,71,101,110,101,114,97,116,101,32,97,32,114,101,112,111, +114,116,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,53,51,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,105,116,108,101,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,111,114,116, +32,84,105,116,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,97,32,116,105,116,108,101,32,102,111,114,32,116,104,101,32,114,101,112, +111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,111,116,101,115,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,101,112,111,114,116,32,78,111,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +78,111,116,101,115,34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,52, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62, +50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,65,85,84,79,95,83,67,82,79,76,76, +124,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,72,83,67,82, +79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,110,116,101,114,32,97,110,121,32,97,100,100,105,116, +105,111,110,97,108,32,110,111,116,101,115,32,116,111,32,105,110,99,108, +117,100,101,32,111,110,32,116,104,101,32,114,101,112,111,114,116,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +83,113,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99, +108,117,100,101,32,116,104,101,32,83,81,76,32,105,110,32,116,104,101,32, +114,101,112,111,114,116,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,60,112,111,115,62,53,44,57,57,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32,116, +104,101,32,83,81,76,32,102,114,111,109,32,116,104,101,32,111,98,106,101, +99,116,32,111,114,32,113,117,101,114,121,32,105,110,32,116,104,101,32,114, +101,112,111,114,116,63,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,34,32, +110,97,109,101,61,34,115,98,70,111,114,109,97,116,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,102,111,114,109, +97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +53,44,49,49,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,88,72,84,77,76,32,49, +46,48,32,84,114,97,110,115,105,116,105,111,110,97,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,67,114,101,97,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,105,110,32,88,72,84,77,76,32,49,46,48, +32,84,114,97,110,115,105,116,105,111,110,97,108,32,102,111,114,109,97,116, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,98,88,109,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,88,77,76,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,60,112,111,115,62,49,48,44,49,52,49,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,114,101,97, +116,101,32,116,104,101,32,114,101,112,111,114,116,32,105,110,32,88,77,76, +32,102,111,114,109,97,116,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120, +34,32,110,97,109,101,61,34,115,98,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,121,108,101,115, +104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,49,54,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,55,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,66,117, +105,108,116,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,69,109,98,101,100,32,116,104,101,32,100,101,102,97,117, +108,116,32,115,116,121,108,101,115,104,101,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,55,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,69,109,98,101,100,32,112,103,65, +100,109,105,110,39,115,32,100,101,102,97,117,108,116,32,115,116,121,108, +101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114,101,112, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,114,98,72,116,109,108,69,109,98,101,100,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,69,109,98,101, +100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108,101, +115,104,101,101,116,32,40,115,112,101,99,105,102,105,101,100,32,102,105, +108,101,32,109,117,115,116,32,101,120,105,115,116,41,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,57,49,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62, +69,109,98,101,100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114, +101,112,111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,76,105,110,107,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105, +110,107,32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100, +101,32,97,32,108,105,110,107,32,116,111,32,97,110,32,101,120,116,101,114, +110,97,108,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,114,101,112,111,114,116,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +108,97,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,48,44,49,55,56,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,88,109,108,76,105,110,107,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105,110,107, +32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,112,111,115,62,49,48,44,49,57,49,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32, +97,32,108,105,110,107,32,116,111,32,116,104,101,32,115,112,101,99,105,102, +105,101,100,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,88,77,76,32,102,105,108,101,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +114,111,99,101,115,115,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,88,83,76,84,32,80,114,111,99,101,115,115,32,116,104, +101,32,88,77,76,32,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,80,114,111,99,101,115, +115,32,116,104,101,32,88,77,76,32,100,97,116,97,32,117,115,105,110,103, +32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,50,50,51,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,72,116,109,108,83,116,121,108,101,115,104,101,101, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,54,50, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,88, +109,108,83,116,121,108,101,115,104,101,101,116,34,62,10,32,32,32,32,32, +32,60,112,111,115,62,54,48,44,50,50,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,50,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108, +101,99,116,32,116,104,101,32,115,116,121,108,101,115,104,101,101,116,32, +116,111,32,117,115,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,98,116,110,83,116,121,108,101,115,104,101,101,116,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,50,55,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117, +116,112,117,116,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,112,111,115,62,53,44,50,52,56,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,116,109,108,70,105,108,101, +34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,102,105,108,101, +32,116,111,32,119,114,105,116,101,32,116,104,101,32,114,101,112,111,114, +116,32,116,111,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,88,109,108,70,105,108,101,34,62,10,32,32,32, +32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,119, +114,105,116,101,32,116,104,101,32,114,101,112,111,114,116,32,116,111,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +50,51,53,44,50,52,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116,32,116, +104,101,32,102,105,108,101,32,116,111,32,119,114,105,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,116,111,46,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,66,114,111,119, +115,101,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,32,116,104,101,32,111,117,116,112,117,116,32,102,105,108,101,32,105, +110,32,116,104,101,32,100,101,102,97,117,108,116,32,98,114,111,119,115, +101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,53,44,50,54,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,44,50,56,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,55,44,50,56,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,50,48,48,44,50,56,53,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_81 = 16296; +static unsigned char xml_res_file_81[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,115,116,111,114,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,82,101,115,116,111,114,101,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,49,57,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,50,56,53,44,49,56,52,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,111,114,109,97,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,111,114,109,97,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,101,110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +78,117,109,98,101,114,79,102,74,111,98,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,117,109, +98,101,114,32,79,102,32,74,111,98,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,117,109, +98,101,114,79,102,74,111,98,115,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,111,114,101,32,79,112, +116,105,111,110,115,32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68, +117,109,112,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110,80, +114,101,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100, +97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116, +105,111,110,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105, +111,110,80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +111,115,116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +32,79,102,32,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108, +121,32,115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,110,39, +116,32,115,97,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,79,119,110, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,80,114,105,118,105, +108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,105,118,105, +108,101,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +84,97,98,108,101,115,112,97,99,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +116,111,114,101,32,79,112,116,105,111,110,115,32,35,50,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,117,109,112,79,112,116,105,111,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,101,114,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,114, +101,97,116,101,68,98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117, +100,101,32,67,82,69,65,84,69,32,68,65,84,65,66,65,83,69,32,115,116,97,116, +101,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,108,101,97,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101,97,110, +32,98,101,102,111,114,101,32,114,101,115,116,111,114,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,105,110,103,108,101,88,97, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,105,110,103,108,101,32,116,114, +97,110,115,97,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97, +98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,68,97, +116,97,70,111,114,70,97,105,108,101,100,84,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,111,32,68,97,116,97,32,102,111,114,32,70,97,105, +108,101,100,32,84,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99, +101,108,108,97,110,111,117,115,32,47,32,66,101,104,97,118,105,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,85,115,101,83,101,116,83,101,115, +115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,69,84, +32,83,69,83,83,73,79,78,32,65,85,84,72,79,82,73,90,65,84,73,79,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,120,105,116,79,110,69, +114,114,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,105,116,32,79,110, +32,69,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97, +109,101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79, +82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,105,101,119,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,68,105,115,112,108,97,121,32,111,98,106,101,99,116,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,68,105,115,112,108,97,121,32,111,98,106, +101,99,116,115,32,99,111,110,116,97,105,110,101,100,32,105,110,32,116,104, +101,32,100,117,109,112,32,111,110,32,97,32,115,112,101,99,105,102,105,99, +32,116,97,98,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101, +115,116,111,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddPrecisionScaleDialog.xrc"), xml_res_file_0, xml_res_size_0, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddTableNameDialog.xrc"), xml_res_file_1, xml_res_size_1, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAddFavourite.xrc"), xml_res_file_2, xml_res_size_2, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAggregate.xrc"), xml_res_file_3, xml_res_size_3, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCast.xrc"), xml_res_file_4, xml_res_size_4, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCheck.xrc"), xml_res_file_5, xml_res_size_5, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCollation.xrc"), xml_res_file_6, xml_res_size_6, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgColumn.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConnect.xrc"), xml_res_file_8, xml_res_size_8, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConversion.xrc"), xml_res_file_9, xml_res_size_9, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDatabase.xrc"), xml_res_file_10, xml_res_size_10, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDirectDbg.xrc"), xml_res_file_11, xml_res_size_11, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDomain.xrc"), xml_res_file_12, xml_res_size_12, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEditGridOptions.xrc"), xml_res_file_13, xml_res_size_13, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEventTrigger.xrc"), xml_res_file_14, xml_res_size_14, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtTable.xrc"), xml_res_file_15, xml_res_size_15, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtension.xrc"), xml_res_file_16, xml_res_size_16, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFindReplace.xrc"), xml_res_file_17, xml_res_size_17, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignDataWrapper.xrc"), xml_res_file_18, xml_res_size_18, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignKey.xrc"), xml_res_file_19, xml_res_size_19, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignServer.xrc"), xml_res_file_20, xml_res_size_20, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignTable.xrc"), xml_res_file_21, xml_res_size_21, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFunction.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgGroup.xrc"), xml_res_file_23, xml_res_size_23, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgHbaConfig.xrc"), xml_res_file_24, xml_res_size_24, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndex.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndexConstraint.xrc"), xml_res_file_26, xml_res_size_26, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgJob.xrc"), xml_res_file_27, xml_res_size_27, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgLanguage.xrc"), xml_res_file_28, xml_res_size_28, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMainConfig.xrc"), xml_res_file_29, xml_res_size_29, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageFavourites.xrc"), xml_res_file_30, xml_res_size_30, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageMacros.xrc"), xml_res_file_31, xml_res_size_31, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMoveTablespace.xrc"), xml_res_file_32, xml_res_size_32, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgOperator.xrc"), xml_res_file_33, xml_res_size_33, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPackage.xrc"), xml_res_file_34, xml_res_size_34, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPgpassConfig.xrc"), xml_res_file_35, xml_res_size_35, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgReassignDropOwned.xrc"), xml_res_file_36, xml_res_size_36, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepCluster.xrc"), xml_res_file_37, xml_res_size_37, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepClusterUpgrade.xrc"), xml_res_file_38, xml_res_size_38, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepListen.xrc"), xml_res_file_39, xml_res_size_39, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepNode.xrc"), xml_res_file_40, xml_res_size_40, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepPath.xrc"), xml_res_file_41, xml_res_size_41, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSequence.xrc"), xml_res_file_42, xml_res_size_42, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSet.xrc"), xml_res_file_43, xml_res_size_43, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMerge.xrc"), xml_res_file_44, xml_res_size_44, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMove.xrc"), xml_res_file_45, xml_res_size_45, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSubscription.xrc"), xml_res_file_46, xml_res_size_46, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepTable.xrc"), xml_res_file_47, xml_res_size_47, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgResourceGroup.xrc"), xml_res_file_48, xml_res_size_48, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRole.xrc"), xml_res_file_49, xml_res_size_49, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRule.xrc"), xml_res_file_50, xml_res_size_50, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchedule.xrc"), xml_res_file_51, xml_res_size_51, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchema.xrc"), xml_res_file_52, xml_res_size_52, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSearchObject.xrc"), xml_res_file_53, xml_res_size_53, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSelectConnection.xrc"), xml_res_file_54, xml_res_size_54, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSequence.xrc"), xml_res_file_55, xml_res_size_55, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgServer.xrc"), xml_res_file_56, xml_res_size_56, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgStep.xrc"), xml_res_file_57, xml_res_size_57, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSynonym.xrc"), xml_res_file_58, xml_res_size_58, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTable.xrc"), xml_res_file_59, xml_res_size_59, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTablespace.xrc"), xml_res_file_60, xml_res_size_60, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchConfiguration.xrc"), xml_res_file_61, xml_res_size_61, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchDictionary.xrc"), xml_res_file_62, xml_res_size_62, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchParser.xrc"), xml_res_file_63, xml_res_size_63, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchTemplate.xrc"), xml_res_file_64, xml_res_size_64, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTrigger.xrc"), xml_res_file_65, xml_res_size_65, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgType.xrc"), xml_res_file_66, xml_res_size_66, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUser.xrc"), xml_res_file_67, xml_res_size_67, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUserMapping.xrc"), xml_res_file_68, xml_res_size_68, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgView.xrc"), xml_res_file_69, xml_res_size_69, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackup.xrc"), xml_res_file_70, xml_res_size_70, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupGlobals.xrc"), xml_res_file_71, xml_res_size_71, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupServer.xrc"), xml_res_file_72, xml_res_size_72, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmExport.xrc"), xml_res_file_73, xml_res_size_73, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmGrantWizard.xrc"), xml_res_file_74, xml_res_size_74, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmHint.xrc"), xml_res_file_75, xml_res_size_75, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmImport.xrc"), xml_res_file_76, xml_res_size_76, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmMaintenance.xrc"), xml_res_file_77, xml_res_size_77, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmOptions.xrc"), xml_res_file_78, xml_res_size_78, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmPassword.xrc"), xml_res_file_79, xml_res_size_79, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmReport.xrc"), xml_res_file_80, xml_res_size_80, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmRestore.xrc"), xml_res_file_81, xml_res_size_81, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddPrecisionScaleDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_ddTableNameDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAddFavourite.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgAggregate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCast.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCheck.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgCollation.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgColumn.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConnect.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgConversion.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDatabase.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDirectDbg.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgDomain.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEditGridOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgEventTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgExtension.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFindReplace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignDataWrapper.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignKey.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgForeignTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgFunction.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgHbaConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndex.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgIndexConstraint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgJob.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgLanguage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMainConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageFavourites.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgManageMacros.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgMoveTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgOperator.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPackage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgPgpassConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgReassignDropOwned.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepCluster.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepClusterUpgrade.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepListen.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepNode.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepPath.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSet.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMerge.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSetMove.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepSubscription.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRepTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgResourceGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRole.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgRule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchedule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSchema.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSearchObject.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSelectConnection.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgStep.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgSynonym.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchConfiguration.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchDictionary.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchParser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTextSearchTemplate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgType.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgUserMapping.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_dlgView.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupGlobals.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmBackupServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmExport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmGrantWizard.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmHint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmImport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmMaintenance.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmPassword.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmReport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp.new$._pgadmin_ui_frmRestore.xrc")); +} diff --git a/ui/ddPrecisionScaleDialog.xrc b/ui/ddPrecisionScaleDialog.xrc new file mode 100644 index 0000000..e763fd7 --- /dev/null +++ b/ui/ddPrecisionScaleDialog.xrc @@ -0,0 +1,97 @@ + + + + Datatype properties + 300,165d + + + 1 + 0 + 0 + + + 296,140d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/ddTableNameDialog.xrc b/ui/ddTableNameDialog.xrc new file mode 100644 index 0000000..fe50845 --- /dev/null +++ b/ui/ddTableNameDialog.xrc @@ -0,0 +1,84 @@ + + + + Table properties + 300,165d + + + 1 + 0 + 0 + + + 296,140d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgAddFavourite.xrc b/ui/dlgAddFavourite.xrc new file mode 100644 index 0000000..22bd989 --- /dev/null +++ b/ui/dlgAddFavourite.xrc @@ -0,0 +1,84 @@ + + + + Add favourite + 220,250d + + + 216,225d + 1 + 5 + 5 + 3 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 1 + + + + + wxLEFT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + 0,0d + + + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgAggregate.xrc b/ui/dlgAggregate.xrc new file mode 100644 index 0000000..f21e53d --- /dev/null +++ b/ui/dlgAggregate.xrc @@ -0,0 +1,288 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + 0 + + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 60,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 60,-1d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgCast.xrc b/ui/dlgCast.xrc new file mode 100644 index 0000000..0e42d04 --- /dev/null +++ b/ui/dlgCast.xrc @@ -0,0 +1,197 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgCheck.xrc b/ui/dlgCheck.xrc new file mode 100644 index 0000000..57584cb --- /dev/null +++ b/ui/dlgCheck.xrc @@ -0,0 +1,170 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + + + 2 + 5 + 5 + 0 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgCollation.xrc b/ui/dlgCollation.xrc new file mode 100644 index 0000000..a6dbdde --- /dev/null +++ b/ui/dlgCollation.xrc @@ -0,0 +1,222 @@ + + + + + 220,280d + + + 1 + 0 + 0 + + + 216,255d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgColumn.xrc b/ui/dlgColumn.xrc new file mode 100644 index 0000000..43bfba9 --- /dev/null +++ b/ui/dlgColumn.xrc @@ -0,0 +1,319 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 10,10d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgConnect.xrc b/ui/dlgConnect.xrc new file mode 100644 index 0000000..dcce0ad --- /dev/null +++ b/ui/dlgConnect.xrc @@ -0,0 +1,74 @@ + + + + Connect to Server + 205,83d + + + 1 + 3 + 0 + + + 205, 25d + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Enter the password to use when connecting to the server. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 12 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 10 + + + 3,3d + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxALL + 8 + + + + diff --git a/ui/dlgConversion.xrc b/ui/dlgConversion.xrc new file mode 100644 index 0000000..bcbbddf --- /dev/null +++ b/ui/dlgConversion.xrc @@ -0,0 +1,227 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_TOP|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgDatabase.xrc b/ui/dlgDatabase.xrc new file mode 100644 index 0000000..204a7b6 --- /dev/null +++ b/ui/dlgDatabase.xrc @@ -0,0 +1,368 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 7 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + -1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxGROW + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgDirectDbg.xrc b/ui/dlgDirectDbg.xrc new file mode 100644 index 0000000..76347a6 --- /dev/null +++ b/ui/dlgDirectDbg.xrc @@ -0,0 +1,86 @@ + + + + View Data Options + 450,210d + + + 1 + 0 + 0 + + + 400,180d + 0 + + + + + 1 + 5 + 5 + 1 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Set the function/procedure parameter values. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + Accept the current options and close the dialogue. + 1 + + wxEXPAND|wxALL + 3 + + + + + Cancel any changes and close the dialogue. + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + + + + diff --git a/ui/dlgDomain.xrc b/ui/dlgDomain.xrc new file mode 100644 index 0000000..07d2545 --- /dev/null +++ b/ui/dlgDomain.xrc @@ -0,0 +1,302 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,112d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + 270,-1d + + + wxGROW + + + + 5 + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgEditGridOptions.xrc b/ui/dlgEditGridOptions.xrc new file mode 100644 index 0000000..fdab748 --- /dev/null +++ b/ui/dlgEditGridOptions.xrc @@ -0,0 +1,157 @@ + + + + View Data Options + 300,265d + + + 1 + 0 + 0 + + + 296,240d + + + + + 1 + 5 + 5 + 1 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Lists the columns that the data will be sorted by. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + Select a column to add to the sort list. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 5 + 5 + 0 + 0,1,2 + + + + Add the select column for ascending sort. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + 1 + + + + + Add the select column for descending sort. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + 1 + + + + + Remove the selected sort column. + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + 1 + + + + + + + + + + + 1 + 0 + 1 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + Enter the filter string to apply to the data. SQL syntax should be used as the string will be used as a 'WHERE' clause. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + Validate the syntax of the filter string. + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + Accept the current options and close the dialogue. + + wxEXPAND|wxALL + 3 + + + + + Cancel any changes and close the dialogue. + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgEventTrigger.xrc b/ui/dlgEventTrigger.xrc new file mode 100644 index 0000000..312c0f1 --- /dev/null +++ b/ui/dlgEventTrigger.xrc @@ -0,0 +1,229 @@ + + + + 300,265d + + + 1 + 0 + 0 + + + 320,240d + + + + 2 + 5 + 5 + 1 + 3 + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + 405,313 + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + 4 + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + 1 + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + ENABLE + REPLICA + ALWAYS + + 210,38 + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + DDL COMMAND START + DDL COMMAND END + SQL DROP + + 333,38 + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 5 + + + + + + + wxALL|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + -1,-1 + 374,187 + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL + 4 + + + + + + + wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL + 3 + + + + 4 + 1 + + + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + 3 + + + wxALIGN_LEFT|wxALIGN_TOP + 0,0d + + + + + 1 + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + 3 + + + + + + wxALL|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + 3 + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_LEFT|wxALIGN_TOP + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgExtTable.xrc b/ui/dlgExtTable.xrc new file mode 100644 index 0000000..5ae4c39 --- /dev/null +++ b/ui/dlgExtTable.xrc @@ -0,0 +1,160 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + wxVERTICAL + + 2,2d + + + + + + + wxEXPAND|wxALIGN_CENTER|wxALL + + + + + + wxEXPAND|wxALIGN_CENTER|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgExtension.xrc b/ui/dlgExtension.xrc new file mode 100644 index 0000000..7cb16e1 --- /dev/null +++ b/ui/dlgExtension.xrc @@ -0,0 +1,170 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgFindReplace.bak b/ui/dlgFindReplace.bak new file mode 100644 index 0000000..83bc398 --- /dev/null +++ b/ui/dlgFindReplace.bak @@ -0,0 +1,204 @@ + + + + Find and Replace + 300,166d + + + 1 + 0 + 0 + + + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the string to search for + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + Find the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the replacement text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Find and replace the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + 0,0d + + + + + Find and replace all occurrences of the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 2 + + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 1 + Begin searching at the current cursor position + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Begin searching at the top of the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 1 + Search forwards through the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Search backwards through the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Match on whole words + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Match the case of the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Use regular expressions when searching + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 0 + + 0,0d + + + + + Close the dialog + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + diff --git a/ui/dlgFindReplace.xrc b/ui/dlgFindReplace.xrc new file mode 100644 index 0000000..1e79574 --- /dev/null +++ b/ui/dlgFindReplace.xrc @@ -0,0 +1,209 @@ + + + + Find and Replace + 300,166d + + + 1 + 0 + 0 + + + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the string to search for + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + Find the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the replacement text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Find and replace the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + All find tabs + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Find and replace all occurrences of the specified text + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 2 + + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 1 + Begin searching at the current cursor position + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Begin searching at the top of the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 1 + Search forwards through the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Search backwards through the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Match on whole words + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Match the case of the text + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Use regular expressions when searching + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 0 + + 0,0d + + + + + Close the dialog + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + diff --git a/ui/dlgForeignDataWrapper.xrc b/ui/dlgForeignDataWrapper.xrc new file mode 100644 index 0000000..3276bf0 --- /dev/null +++ b/ui/dlgForeignDataWrapper.xrc @@ -0,0 +1,278 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgForeignKey.xrc b/ui/dlgForeignKey.xrc new file mode 100644 index 0000000..a2cb922 --- /dev/null +++ b/ui/dlgForeignKey.xrc @@ -0,0 +1,346 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxTOP||wxLEFT|wxRIGHT|wxGROW + 2 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxTOP|wxBOTTOM|wxGROW + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxTOP|wxGROW + + + + + + + + + 2 + 5 + 5 + 0 + 0,1 + + + + + NO ACTION + RESTRICT + CASCADE + SET NULL + SET DEFAULT + + 1 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + NO ACTION + RESTRICT + CASCADE + SET NULL + SET DEFAULT + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgForeignServer.xrc b/ui/dlgForeignServer.xrc new file mode 100644 index 0000000..a7b284d --- /dev/null +++ b/ui/dlgForeignServer.xrc @@ -0,0 +1,274 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgForeignTable.xrc b/ui/dlgForeignTable.xrc new file mode 100644 index 0000000..1280aa3 --- /dev/null +++ b/ui/dlgForeignTable.xrc @@ -0,0 +1,398 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + 3 + + wxALIGN_RIGHT + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgFunction.xrc b/ui/dlgFunction.xrc new file mode 100644 index 0000000..a041fe1 --- /dev/null +++ b/ui/dlgFunction.xrc @@ -0,0 +1,633 @@ + + + + + 350,265d + + + 1 + 0 + 0 + + + 346,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + VOLATILE + STABLE + IMMUTABLE + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + UNSAFE + RESTRICTED + SAFE + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + + + + + + wxALL|wxEXPAND + 5 + + + + + + + + wxALIGN_CENTRE_VERTICAL + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + wxTOP|wxBOTTOM + 5 + + + + + + wxALIGN_CENTRE_VERTICAL + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + 2 + 4 + 4 + 1 + + wxALL|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + 3 + + wxALIGN_RIGHT + + 0 + 0 + + + + + + + + 1 + 5 + 5 + 0 + 0,1 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxEXPAND + 5 + + + + + + wxALL|wxEXPAND + 5 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxGROW + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW + 4 + + + wxGROW + + + + + + wxALL|wxGROW + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 4 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 4 + + + + + + wxEXPAND|wxALL + 4 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND + 3 + + + + diff --git a/ui/dlgGroup.xrc b/ui/dlgGroup.xrc new file mode 100644 index 0000000..f45395b --- /dev/null +++ b/ui/dlgGroup.xrc @@ -0,0 +1,184 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 0,2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 2,2d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 1 + 5 + 5 + + + + 18,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + 18,-1d + + wxEXPAND|wxALIGN_TOP|wxALL + 4 + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgHbaConfig.xrc b/ui/dlgHbaConfig.xrc new file mode 100644 index 0000000..a864a19 --- /dev/null +++ b/ui/dlgHbaConfig.xrc @@ -0,0 +1,156 @@ + + + + Client Access Configuration + 220,150d + + + 1 + 5 + 5 + 0 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgIndex.xrc b/ui/dlgIndex.xrc new file mode 100644 index 0000000..2574b71 --- /dev/null +++ b/ui/dlgIndex.xrc @@ -0,0 +1,377 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxEXPAND|wxALL + 4 + + + + 2 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 5 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT + 4 + + + 15,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 10,3d + + + + 3 + + + + + + + + 15,3d + + + + + 1 + + + + wxTOP + 5 + + + wxEXPAND|wxALL + 4 + + + wxEXPAND|wxALL + 4 + + + + 4 + 0 + + 3,3d + + + + + + + + 3,3d + + + + + 50,-1d + + + + wxEXPAND|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgIndexConstraint.xrc b/ui/dlgIndexConstraint.xrc new file mode 100644 index 0000000..79ef279 --- /dev/null +++ b/ui/dlgIndexConstraint.xrc @@ -0,0 +1,379 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxEXPAND|wxALL + 4 + + + + 2 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 5 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT + 4 + + + 15,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 10,3d + + + + 3 + + + + + + + + 15,3d + + + + + 1 + + + + wxTOP + 5 + + + wxEXPAND|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + 4 + + + + 4 + 0 + + 3,3d + + + + + + + + 3,3d + + + + + 50,-1d + + + + wxEXPAND|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgJob.xrc b/ui/dlgJob.xrc new file mode 100644 index 0000000..8031eab --- /dev/null +++ b/ui/dlgJob.xrc @@ -0,0 +1,326 @@ + + + + + 220,280d + + + 1 + 0 + 0 + + + 216,255d + 0 + + + + + 2 + 5 + 5 + 10 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgLanguage.xrc b/ui/dlgLanguage.xrc new file mode 100644 index 0000000..94d3354 --- /dev/null +++ b/ui/dlgLanguage.xrc @@ -0,0 +1,215 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgMainConfig.xrc b/ui/dlgMainConfig.xrc new file mode 100644 index 0000000..47cf9bb --- /dev/null +++ b/ui/dlgMainConfig.xrc @@ -0,0 +1,139 @@ + + + + + 248,198d + + + 1 + 5 + 5 + 2 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + 5 + 5 + 0 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + + 5,55d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 10,65d + 238,90d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgManageFavourites.xrc b/ui/dlgManageFavourites.xrc new file mode 100644 index 0000000..c0df58b --- /dev/null +++ b/ui/dlgManageFavourites.xrc @@ -0,0 +1,83 @@ + + + + Manage favourites + 218,198d + + + 1 + 5 + 5 + 0 + 0 + + + 5,7d + 208,150d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgManageMacros.xrc b/ui/dlgManageMacros.xrc new file mode 100644 index 0000000..4dd1fc0 --- /dev/null +++ b/ui/dlgManageMacros.xrc @@ -0,0 +1,133 @@ + + + + Manage Macros + + + 1 + 5 + 5 + 0 + 0 + + + 3 + + + + + wxTOP|wxBOTTOM|wxLEFT|wxEXPAND + 5 + 150d + + + 5,5d + + + + 1 + + + + + + + wxALIGN_CENTRE_VERTICAL + + + 5d + + + + wxLEFT|wxRIGHT|wxEXPAND + + 3 + 2 + + wxTOP|wxLEFT|wxRIGHT|wxGROW + 5 + + + 5,5d + + + + + + wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND + 5 + 200,100d + + 0 + + + 5 + + 5,5d + + + + + + + 5 + 4 + + 5,5d + + + + + + + + 5,5d + + + wxALL + + 2 + + wxALL|wxGROW + + 0 + 2 + + wxTOP|wxLEFT|wxRIGHT|wxGROW|wxALIGN_CENTRE + 5 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgMoveTablespace.xrc b/ui/dlgMoveTablespace.xrc new file mode 100644 index 0000000..3fa2413 --- /dev/null +++ b/ui/dlgMoveTablespace.xrc @@ -0,0 +1,95 @@ + + + + Move objects to another tablespace + 200,200d + + + 1 + 5 + 5 + 0 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgOperator.xrc b/ui/dlgOperator.xrc new file mode 100644 index 0000000..adb215e --- /dev/null +++ b/ui/dlgOperator.xrc @@ -0,0 +1,370 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgPackage.xrc b/ui/dlgPackage.xrc new file mode 100644 index 0000000..3253cbc --- /dev/null +++ b/ui/dlgPackage.xrc @@ -0,0 +1,180 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgPgpassConfig.xrc b/ui/dlgPgpassConfig.xrc new file mode 100644 index 0000000..ac6f30b --- /dev/null +++ b/ui/dlgPgpassConfig.xrc @@ -0,0 +1,145 @@ + + + + Client Access Configuration + 300,265d + + + 1 + 5 + 5 + 0 + 0 + 296,240d + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgReassignDropOwned.xrc b/ui/dlgReassignDropOwned.xrc new file mode 100644 index 0000000..e873262 --- /dev/null +++ b/ui/dlgReassignDropOwned.xrc @@ -0,0 +1,90 @@ + + + + Reassign/Drop Owned + 200,200d + + + 1 + 5 + 5 + 0 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 3 + 0 + + 0,0d + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxEXPAND + + + + diff --git a/ui/dlgRepCluster.xrc b/ui/dlgRepCluster.xrc new file mode 100644 index 0000000..9c9de45 --- /dev/null +++ b/ui/dlgRepCluster.xrc @@ -0,0 +1,235 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + 5 + 5 + 0 + 0,1 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + 5 + 5 + 0 + + + 2 + 5 + 5 + 1 + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgRepClusterUpgrade.xrc b/ui/dlgRepClusterUpgrade.xrc new file mode 100644 index 0000000..5f530e8 --- /dev/null +++ b/ui/dlgRepClusterUpgrade.xrc @@ -0,0 +1,135 @@ + + + + Upgrade cluster software + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepListen.xrc b/ui/dlgRepListen.xrc new file mode 100644 index 0000000..bc96de4 --- /dev/null +++ b/ui/dlgRepListen.xrc @@ -0,0 +1,107 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepNode.xrc b/ui/dlgRepNode.xrc new file mode 100644 index 0000000..c7c0e23 --- /dev/null +++ b/ui/dlgRepNode.xrc @@ -0,0 +1,92 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepPath.xrc b/ui/dlgRepPath.xrc new file mode 100644 index 0000000..e03acf6 --- /dev/null +++ b/ui/dlgRepPath.xrc @@ -0,0 +1,105 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSequence.xrc b/ui/dlgRepSequence.xrc new file mode 100644 index 0000000..2d02668 --- /dev/null +++ b/ui/dlgRepSequence.xrc @@ -0,0 +1,107 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSet.xrc b/ui/dlgRepSet.xrc new file mode 100644 index 0000000..020c771 --- /dev/null +++ b/ui/dlgRepSet.xrc @@ -0,0 +1,114 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 2 + + + + 5,7d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,5d + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,22d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,20d + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,37d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 70,35d + 135,60d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSetMerge.xrc b/ui/dlgRepSetMerge.xrc new file mode 100644 index 0000000..760b723 --- /dev/null +++ b/ui/dlgRepSetMerge.xrc @@ -0,0 +1,92 @@ + + + + Merge set into another set + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSetMove.xrc b/ui/dlgRepSetMove.xrc new file mode 100644 index 0000000..c72d268 --- /dev/null +++ b/ui/dlgRepSetMove.xrc @@ -0,0 +1,92 @@ + + + + Move set to other node + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepSubscription.xrc b/ui/dlgRepSubscription.xrc new file mode 100644 index 0000000..76c78cd --- /dev/null +++ b/ui/dlgRepSubscription.xrc @@ -0,0 +1,121 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgRepTable.xrc b/ui/dlgRepTable.xrc new file mode 100644 index 0000000..00db0e2 --- /dev/null +++ b/ui/dlgRepTable.xrc @@ -0,0 +1,143 @@ + + + + + 220,150d + + + 1 + 0 + 0 + + + 216,125d + 0 + + + + + 2 + 5 + 5 + 1 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + 5,5d + 200,90d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/dlgResourceGroup.xrc b/ui/dlgResourceGroup.xrc new file mode 100644 index 0000000..7338c22 --- /dev/null +++ b/ui/dlgResourceGroup.xrc @@ -0,0 +1,106 @@ + + + + + 1 + 0 + 0 + + + + + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 2 + 15 + 5 + 1 + + + + + + 216,205d + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + 220,230d + + + \ No newline at end of file diff --git a/ui/dlgRole.xrc b/ui/dlgRole.xrc new file mode 100644 index 0000000..8291b3a --- /dev/null +++ b/ui/dlgRole.xrc @@ -0,0 +1,479 @@ + + + + + 270,250d + + + 1 + 0 + 0 + + + 266,225d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 0 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 166,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 0,2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 1 + 5 + 5 + + + + 18,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + 18,-1d + + wxEXPAND|wxALIGN_TOP|wxALL + 4 + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + 0,0d + + + 0,0d + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + 90,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 150,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgRule.xrc b/ui/dlgRule.xrc new file mode 100644 index 0000000..810bba2 --- /dev/null +++ b/ui/dlgRule.xrc @@ -0,0 +1,209 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + SELECT + INSERT + UPDATE + DELETE + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSchedule.xrc b/ui/dlgSchedule.xrc new file mode 100644 index 0000000..aeae60d --- /dev/null +++ b/ui/dlgSchedule.xrc @@ -0,0 +1,460 @@ + + + + + 220,250d + + + 1 + 0 + 0 + + + 216,225d + 0 + + + + + 2 + 5 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 2 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + -1,70d + + Sunday + Monday + Tuesday + Wednesday + Thursday + Friday + Saturday + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + -1,70d + + 1st + 2nd + 3rd + 4th + 5th + 6th + 7th + 8th + 9th + 10th + 11th + 12th + 13th + 14th + 15th + 16th + 17th + 18th + 19th + 20th + 21st + 22nd + 23rd + 24th + 25th + 26th + 27th + 28th + 29th + 30th + 31st + Last day + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + + January + February + March + April + May + June + July + August + September + October + November + December + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + -1,100d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_BOTTOM|wxALIGN_RIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 1,3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + 4 + 5 + 5 + 0 + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSchema.xrc b/ui/dlgSchema.xrc new file mode 100644 index 0000000..53962cb --- /dev/null +++ b/ui/dlgSchema.xrc @@ -0,0 +1,142 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSearchObject.xrc b/ui/dlgSearchObject.xrc new file mode 100644 index 0000000..f3846b9 --- /dev/null +++ b/ui/dlgSearchObject.xrc @@ -0,0 +1,214 @@ + + + + Search Objects + 353,240d + + + 0 + 1 + 0 + 0 + 0 + 0 + + + wxALIGN_CENTER|wxALL|wxEXPAND + 3 + + 5 + 3 + 1 + 3 + + 0,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 0,1 + 1,1 + wxEXPAND + 0 + + 0 + 2 + 5 + 5 + 0 + 0 + + + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxTOP + 3 + + Enter part of the object's attribute you're looking for + + + + + wxALIGN_CENTER_VERTICAL|wxTOP + 3 + + + 1 + + + + + + 1,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 1,1 + 1,1 + wxBOTTOM|wxEXPAND|wxLEFT|wxTOP + 3 + + + 270,-1d + + + + + 2,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 2,1 + 1,1 + wxBOTTOM|wxEXPAND|wxLEFT|wxTOP + 3 + + + 270,-1d + + + + + 3,0 + 1,1 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP + 4 + + + + + + 3,1 + 1,2 + wxEXPAND + 5 + + 0 + 1 + 0 + 0 + 0 + 0 + + + wxALL|wxEXPAND + 3 + + 340,150d + + + + + + + 0,2 + 3,1 + wxALIGN_CENTER_HORIZONTAL + 5 + + wxVERTICAL + + + wxLEFT|wxTOP + 5 + + + 1 + + + + + wxLEFT|wxTOP + 5 + + + 0 + + + + + wxLEFT|wxTOP + 5 + + + 0 + + + + + + + + + wxEXPAND + 5 + + 0 + 3 + 0 + 0 + 1 + + + + wxEXPAND|wxALL + 3 + + + + + + 0,0d + + + + wxEXPAND|wxALL + 3 + + + + + + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSelectConnection.xrc b/ui/dlgSelectConnection.xrc new file mode 100644 index 0000000..0424936 --- /dev/null +++ b/ui/dlgSelectConnection.xrc @@ -0,0 +1,40 @@ + + + + Connect to Server + 205,98d + + + + 5,7d + + + + 5,22d + + + + 5,37d + + + + 5,54d + + + + 2,80d + + + + + 1 + 97,80d + + + + + 0 + 150,80d + + + diff --git a/ui/dlgSequence.xrc b/ui/dlgSequence.xrc new file mode 100644 index 0000000..049a625 --- /dev/null +++ b/ui/dlgSequence.xrc @@ -0,0 +1,249 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,247d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 70,245d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgServer.xrc b/ui/dlgServer.xrc new file mode 100644 index 0000000..1637675 --- /dev/null +++ b/ui/dlgServer.xrc @@ -0,0 +1,538 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL Root Certificate File + *.crt + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL Certificate Revocation List File + *.crl + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL certificate file + *.crt + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select SSL key file + *.key + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 10 + 10 + 1 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select identity file + * + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 0 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select public key file + *.pub + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgStep.xrc b/ui/dlgStep.xrc new file mode 100644 index 0000000..a6802a7 --- /dev/null +++ b/ui/dlgStep.xrc @@ -0,0 +1,262 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 7 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + 2 + 0 + + + + + 0 + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + + + 0 + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxVERTICAL + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + wxALIGN_TOP|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxTOP + 4 + + + + 0 + 0 + 2 + + 0 + + + 0 + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + + + 0 + 15,-1d + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + SQL + Batch + + 0 + + 1 + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + Fail + Succeed + Ignore + + 1 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgSynonym.xrc b/ui/dlgSynonym.xrc new file mode 100644 index 0000000..17a4859 --- /dev/null +++ b/ui/dlgSynonym.xrc @@ -0,0 +1,185 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 5 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTable.xrc b/ui/dlgTable.xrc new file mode 100644 index 0000000..6ebaa32 --- /dev/null +++ b/ui/dlgTable.xrc @@ -0,0 +1,892 @@ + + + + + 350,265d + + + 1 + 0 + 0 + + + 346,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 3 + 5 + 5 + 0 + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 0 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 50,-1d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + 0 + + + 270,-1d + + + wxGROW + + + + 5 + 0 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxGROW + + + + + + + + 0 + + + + + 3 + 5 + 5 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 3 + 5 + 5 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTablespace.xrc b/ui/dlgTablespace.xrc new file mode 100644 index 0000000..6c1fe0a --- /dev/null +++ b/ui/dlgTablespace.xrc @@ -0,0 +1,256 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 3 + 1 + + + + 5,7d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,5d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,37d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 70,35d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5,52d + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 70,50d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + 5,22d + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,20d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + wxGROW + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTextSearchConfiguration.xrc b/ui/dlgTextSearchConfiguration.xrc new file mode 100644 index 0000000..d03f8f0 --- /dev/null +++ b/ui/dlgTextSearchConfiguration.xrc @@ -0,0 +1,310 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 2 + 5 + 5 + 0 + + + 111,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + 56,-1d + + + wxALIGN_CENTER_VERTICAL + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 3 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTextSearchDictionary.xrc b/ui/dlgTextSearchDictionary.xrc new file mode 100644 index 0000000..400ccdf --- /dev/null +++ b/ui/dlgTextSearchDictionary.xrc @@ -0,0 +1,277 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTextSearchParser.xrc b/ui/dlgTextSearchParser.xrc new file mode 100644 index 0000000..953d566 --- /dev/null +++ b/ui/dlgTextSearchParser.xrc @@ -0,0 +1,263 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + + diff --git a/ui/dlgTextSearchTemplate.xrc b/ui/dlgTextSearchTemplate.xrc new file mode 100644 index 0000000..988875e --- /dev/null +++ b/ui/dlgTextSearchTemplate.xrc @@ -0,0 +1,214 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgTrigger.xrc b/ui/dlgTrigger.xrc new file mode 100644 index 0000000..cb85a93 --- /dev/null +++ b/ui/dlgTrigger.xrc @@ -0,0 +1,394 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + -1,40 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 8 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + BEFORE + AFTER + INSTEAD OF + + 0 + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + -1,40 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + wxEXPAND|wxALL + 4 + + + + 2 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + 4 + + + + 4 + 0 + + 3,3d + + + + + + + + 3,3d + + + + + 50,-1d + + + + wxEXPAND|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + + + + wxTOP|wxRIGHT|wxGROW + 5 + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgType.xrc b/ui/dlgType.xrc new file mode 100644 index 0000000..2f183cf --- /dev/null +++ b/ui/dlgType.xrc @@ -0,0 +1,832 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + Composite + Enumeration + External + Range + + 1 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0,1,2 + 0 + + + + 1 + 5 + 5 + 0 + 0 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + + + + + wxALL|wxALIGN_RIGHT + 2 + + 3 + + wxALIGN_RIGHT + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + 0 + + + 5,5d + 200,155d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 4 + 5 + 5 + 0 + + 2,2d + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + 0 + + + 0 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + Array types + Boolean types + Composite types + Date/time types + Enum types + Geometric types + Network address types + Numeric types + Pseudo-types + String types + Timespan types + User-defined types + Bit-string types + unknown types + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + char + int2 + int4 + double + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgUser.xrc b/ui/dlgUser.xrc new file mode 100644 index 0000000..e65dbc6 --- /dev/null +++ b/ui/dlgUser.xrc @@ -0,0 +1,371 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 6 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 166,12d + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 3 + 5 + 5 + 1 + 0,2 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + 1 + 5 + 5 + + + + 18,-1d + + wxEXPAND|wxALIGN_BOTTOM|wxALL + 4 + + + + + 18,-1d + + wxEXPAND|wxALIGN_TOP|wxALL + 4 + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + 86,123d + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 4 + 5 + 0 + 0 + + + 5,6d + + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + + 3 + 0 + + 0,0d + + + + + 90,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 150,132d + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0,1 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxEXPAND|wxALIGN_CENTER_VERTICAL + + wxALL|wxGROW|wxALIGN_CENTRE + 4 + + + wxGROW + + + + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgUserMapping.xrc b/ui/dlgUserMapping.xrc new file mode 100644 index 0000000..87d18e7 --- /dev/null +++ b/ui/dlgUserMapping.xrc @@ -0,0 +1,207 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + + 296,240d + 0 + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxALL + 4 + + + + + 135,-1d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 1 + 0 + 0 + + + 70,15d + + + + wxALL|wxEXPAND + 5 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + + + + wxALIGN_CENTRE_VERTICAL + + + + 135,-1d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + wxEXPAND|wxALIGN_CENTRE_VERTICAL + + + wxALL|wxEXPAND|wxALIGN_BOTTOM|wxALIGN_CENTRE_HORIZONTAL + 5 + + + + 2 + + + + 13,58d + + wxALL|wxALIGN_RIGHT + 2 + + + + + 13,78d + + wxALL|wxALIGN_RIGHT + 2 + + + wxALIGN_RIGHT + + + + + + wxALL|wxGROW|wxALIGN_CENTRE + 3 + + + 2,2d + + + + 7 + 2 + + 3,3d + + + + + + + + 3,3d + + + + + 1 + + + + 3,3d + + + + + + + + 3,3d + + + wxTOP|wxLEFT|wxRIGHT|wxGROW + + + 3,3d + + + + + + wxGROW|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/dlgView.xrc b/ui/dlgView.xrc new file mode 100644 index 0000000..c41a9d5 --- /dev/null +++ b/ui/dlgView.xrc @@ -0,0 +1,728 @@ + + + + + 300,265d + + + 1 + 0 + 0 + + wxEXPAND|wxALL + + 296,240d + 0 + + + + + 2 + 5 + 5 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + No + Local + Cascaded + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxGROW + + + + + + + + + 1 + + + 2 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + 2 + 1 + 1 + + + + + 0 + + + + + 2 + 3 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + 4 + 4 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 3 + 4 + 4 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + + + + 3 + 4 + 4 + 1 + + 3,3d + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 3,3d + + + 3,3d + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 4 + + + + + + wxTOP|wxLEFT|wxRIGHT|wxEXPAND|wxALIGN_CENTRE_VERTICAL + 4 + + 5 + 5 + 0 + 1 + + + + + wxALL|wxGROW + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND + 3 + + + + diff --git a/ui/embed-xrc_v3.bat b/ui/embed-xrc_v3.bat new file mode 100644 index 0000000..14255fb --- /dev/null +++ b/ui/embed-xrc_v3.bat @@ -0,0 +1,13 @@ +@echo off +REM ####################################################################### +REM # +REM # pgAdmin III - PostgreSQL Tools +REM # Copyright (C) 2002 - 2016, The pgAdmin Development Team +REM # This software is released under the PostgreSQL Licence +REM # +REM # embed-xrc.bat - convert xrc files to c++ files +REM # +REM ####################################################################### + +"D:\PostgreSQL\pgadmin3\pgadmin\Debug_(3.0)\wxrc.exe" -c -o xrcDialogs.cpp *.xrc + diff --git a/ui/frmBackup.xrc b/ui/frmBackup.xrc new file mode 100644 index 0000000..62262be --- /dev/null +++ b/ui/frmBackup.xrc @@ -0,0 +1,412 @@ + + + + Backup + 300,233d + + + 1 + 0 + 0 + + + 2,2d + 285,224d + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/frmBackupGlobals.xrc b/ui/frmBackupGlobals.xrc new file mode 100644 index 0000000..8f41e19 --- /dev/null +++ b/ui/frmBackupGlobals.xrc @@ -0,0 +1,105 @@ + + + + Backup Globals + 210,153d + + + 1 + + + + + + + + 8,7d + + + 65,5d + 150,-1d + + + + 220,5d + 15,-1d + + + + 8,27d + + + 65,25d + 170,-1d + + + + + + 8,47d + + + + + 10,120d + + + + 1 + 10,144d + + + 1 + + 2,2d + 245,174d + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + 0 + 0 + + + diff --git a/ui/frmBackupServer.xrc b/ui/frmBackupServer.xrc new file mode 100644 index 0000000..3f22b25 --- /dev/null +++ b/ui/frmBackupServer.xrc @@ -0,0 +1,105 @@ + + + + Backup Server + 210,153d + + + 1 + + + + + + + + 8,7d + + + 65,5d + 150,-1d + + + + 220,5d + 15,-1d + + + + 8,27d + + + 65,25d + 170,-1d + + + + + + 8,47d + + + + + 10,120d + + + + 1 + 10,144d + + + 1 + + 2,2d + 245,174d + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + 0 + 0 + + + diff --git a/ui/frmExport.xrc b/ui/frmExport.xrc new file mode 100644 index 0000000..9482f4e --- /dev/null +++ b/ui/frmExport.xrc @@ -0,0 +1,131 @@ + + + + Export data to file + 253,143d + + + + 5,5d + 120,38d + + + + 1 + 10,17d + + + + + 10,29d + + + + 5,55d + + + + ; + , + | + + 0 + 100,53d + 25,12d + + + + + 5,70d + + + + " + ' + + 0 + 100,68d + 25,12d + + + + + 5,85d + + + + 1 + 100,83d + 12,12d + + + + 130,5d + 120,38d + + + + 1 + 140,17d + + + + + 140,29d + + + + 130,48d + 120,50d + + + + 140,60d + + + + + 1 + 140,72d + + + + 140,84d + + + + 5,107d + + + 100,105d + 130,-1d + + + + 235,105d + 15,-1d + + + + 2,125d + + + + + 1 + 55,125d + 70,12d + + + + 1 + 147,125d + + + + + 0 + 200,125d + + + \ No newline at end of file diff --git a/ui/frmGrantWizard.xrc b/ui/frmGrantWizard.xrc new file mode 100644 index 0000000..5317d6f --- /dev/null +++ b/ui/frmGrantWizard.xrc @@ -0,0 +1,46 @@ + + + + Grant Wizard + 200,303d + + + + + + + + 2,3d + 183,234d + + + + 2,240d + 50,-1d + + + + 60,240d + 50,-1d + + + 1 + + 2,2d + 195,276d + + + + 2,285d + + + + 1 + 93,285d + + + + 146,285d + + + \ No newline at end of file diff --git a/ui/frmHint.xrc b/ui/frmHint.xrc new file mode 100644 index 0000000..be39ffe --- /dev/null +++ b/ui/frmHint.xrc @@ -0,0 +1,90 @@ + + + + pgAdmin Guru Hint + 200,153d + + + 1 + + + + + wxALL|wxGROW + 5 + 300,200d + + + + + + wxALL + 5 + + + + 7 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + 0 + 0 + + + diff --git a/ui/frmImport.xrc b/ui/frmImport.xrc new file mode 100644 index 0000000..f47405d --- /dev/null +++ b/ui/frmImport.xrc @@ -0,0 +1,301 @@ + + + + Import data from file + 300,133d + + + 1 + 0 + 0 + + + 2,2d + 285,124d + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select the file to import + + *.csv;*.*;* + Enter a filename to import. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + text + csv + binary + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 1 + 0 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + ; + , + | + [tab] + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + " + ' + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + " + ' + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + + + + 2 + 5 + 5 + 1 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 4 + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 1 + 0 + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + diff --git a/ui/frmMaintenance.xrc b/ui/frmMaintenance.xrc new file mode 100644 index 0000000..2b71bd9 --- /dev/null +++ b/ui/frmMaintenance.xrc @@ -0,0 +1,142 @@ + + + + Maintenance + 200,153d + + + 1 + 0 + 0 + + + + + + + + 1 + 5 + 5 + 0 + + + + + VACUUM + ANALYZE + REINDEX + CLUSTER + + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 5 + 5 + 5 + 0 + wxHORIZONTAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 4 + + + + 2,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + 0,0 + + + + + 1 + 93,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT + 5 + + + + + 146,135d + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_RIGHT + 5 + + 1 + + wxEXPAND|wxGROW + + + + diff --git a/ui/frmOptions.xrc b/ui/frmOptions.xrc new file mode 100644 index 0000000..e488524 --- /dev/null +++ b/ui/frmOptions.xrc @@ -0,0 +1,1373 @@ + + + + Options + 480,250d + + + 1 + 0 + 0 + + + 2 + 0 + 1 + + + 100,225d + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 3 + + + + 1 + 5 + 5 + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 + 0 + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Enter the path or URL to the PostgreSQL documentation + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 1 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with Slony-I creation scripts + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with PostgreSQL utilities + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with EnterpriseDB utilities + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select directory with GreenplumDB utilities + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + None + Refresh object on click + Refresh object and children on click + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 256 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select utility to format text + * + + A command line utility which reads STDIN and directs output to STDOUT. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + wxVERTICAL + + + 3 + 4 + 4 + 0,1 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + 0,0d + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxVERTICAL + + + 2 + 4 + 4 + 0,1 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + wxVERTICAL + + + 4 + 4 + 4 + 0,2 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTRE|wxALL + 3 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + None + Strings + All + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + " + ' + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + ; + , + | + Tab + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 0 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select file to store favourites queries + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select file to store macros + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select file to store queries history + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 10 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 100 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 70,12d + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 100 + Maximums rows to retrieve into output window; 0 = unlimited + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 1 + + 1 + 5 + 5 + 0 + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + Select log file + + Enter a filename to write application logs to. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + &No logging + &Errors only + Errors and N&otices + Errors, Notices, &SQL + &Debug (not recommended for normal use) + + 2 + 1 + + Select the level of detail to record in the logfile. + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 3 + + + + 4 + 1 + + + + + wxEXPAND|wxALL + 3 + + + 0,0d + + + + + 1 + Accept the current settings and close the dialogue. + + wxEXPAND|wxALL + 3 + + + + + Cancel any changes and close the dialogue. + + wxEXPAND|wxALL + 3 + + + wxEXPAND|wxTOP|wxLEFT|wxRIGHT + + + + + + wxEXPAND|wxALIGN_CENTRE + 3 + + + + diff --git a/ui/frmPassword.xrc b/ui/frmPassword.xrc new file mode 100644 index 0000000..d672510 --- /dev/null +++ b/ui/frmPassword.xrc @@ -0,0 +1,47 @@ + + + + Change Password + 175,73d + + + + 5,7d + + + 70,5d + 100,-1d + + + + + 5,22d + + + 70,20d + 100,-1d + + + + + 5,37d + + + 70,35d + 100,-1d + + + + + 5,55d + + + + 63,55d + + + + 120,55d + + + \ No newline at end of file diff --git a/ui/frmReport.xrc b/ui/frmReport.xrc new file mode 100644 index 0000000..fa862ff --- /dev/null +++ b/ui/frmReport.xrc @@ -0,0 +1,149 @@ + + + + Generate a report + 253,303d + + + + 5,5d + + + 5,15d + 243,-1d + Enter a title for the report + + + + 5,35d + + + 5,45d + 243,45d + + Enter any additional notes to include on the report + + + + 5,99d + Include the SQL from the object or query in the report? + + + + 5,113d + 243,45d + + + + 1 + 10,128d + + Create the report in XHTML 1.0 Transitional format + + + + 1 + 10,141d + Create the report in XML format + + + + 5,163d + 243,75d + + + + 1 + 10,178d + + Embed pgAdmin's default stylesheet into the report. + + + + 10,191d + Embed an external stylesheet into the report + + + + 10,204d + Include a link to an external stylesheet in the report. + + + + 1 + 10,178d + + Do not use a stylesheet + + + + 10,191d + Include a link to the specified stylesheet in the XML file + + + + 10,204d + Process the XML data using the specified stylesheet + + + + 10,223d + + + 60,220d + 162,-1d + Select the stylesheet to use. + + + 60,220d + 162,-1d + Select the stylesheet to use. + + + + 227,220d + 15,-1d + Select the stylesheet to use. + + + + 5,248d + + + 55,245d + 175,-1d + Select the file to write the report to. + + + 55,245d + 175,-1d + Select the file to write the report to. + + + + 235,245d + 15,-1d + Select the file to write the report to. + + + + 5,265d + + + + 2,285d + + + + + 1 + 147,285d + + + + + 0 + 200,285d + + + \ No newline at end of file diff --git a/ui/frmRestore.xrc b/ui/frmRestore.xrc new file mode 100644 index 0000000..0a5a6fd --- /dev/null +++ b/ui/frmRestore.xrc @@ -0,0 +1,364 @@ + + + + Restore + 300,193d + + + 1 + 0 + 0 + + + 2,2d + 285,184d + + + + + + 2 + 5 + 5 + 1 + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + 2 + 5 + 5 + 0 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + 1 + 5 + 5 + 0 + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + 5 + 5 + 0 + wxVERTICAL + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + 1 + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxTOP|wxLEFT|wxRIGHT + 4 + + + + + + + + + + + + + + + + + + wxTOP|wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND|wxGROW|wxALIGN_CENTRE + + + + 5 + + + + + wxEXPAND|wxALL + 3 + + + 0,0 + + + + + Display objects contained in the dump on a specific tab + 1 + + wxEXPAND|wxALL + 3 + + + + + 1 + + wxEXPAND|wxALL + 3 + + + + + + wxEXPAND|wxALL + 3 + + 1 + + wxEXPAND|wxGROW + + + + diff --git a/ui/module.mk b/ui/module.mk new file mode 100644 index 0000000..b546e41 --- /dev/null +++ b/ui/module.mk @@ -0,0 +1,104 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/slony/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + ui/xrcDialogs.cpp + +TMP_ui += \ + ui/ddPrecisionScaleDialog.xrc \ + ui/ddTableNameDialog.xrc \ + ui/dlgAddFavourite.xrc \ + ui/dlgAggregate.xrc \ + ui/dlgCast.xrc \ + ui/dlgCheck.xrc \ + ui/dlgCollation.xrc \ + ui/dlgColumn.xrc \ + ui/dlgConnect.xrc \ + ui/dlgConversion.xrc \ + ui/dlgDatabase.xrc \ + ui/dlgDirectDbg.xrc \ + ui/dlgDomain.xrc \ + ui/dlgEventTrigger.xrc \ + ui/dlgExtension.xrc \ + ui/dlgEditGridOptions.xrc \ + ui/dlgExtTable.xrc \ + ui/dlgFindReplace.xrc \ + ui/dlgForeignDataWrapper.xrc \ + ui/dlgForeignKey.xrc \ + ui/dlgForeignServer.xrc \ + ui/dlgForeignTable.xrc \ + ui/dlgFunction.xrc \ + ui/dlgGroup.xrc \ + ui/dlgHbaConfig.xrc \ + ui/dlgIndex.xrc \ + ui/dlgIndexConstraint.xrc \ + ui/dlgJob.xrc \ + ui/dlgLanguage.xrc \ + ui/dlgMainConfig.xrc \ + ui/dlgManageFavourites.xrc \ + ui/dlgManageMacros.xrc \ + ui/dlgMoveTablespace.xrc \ + ui/dlgOperator.xrc \ + ui/dlgPackage.xrc \ + ui/dlgPgpassConfig.xrc \ + ui/dlgReassignDropOwned.xrc \ + ui/dlgRepCluster.xrc \ + ui/dlgRepClusterUpgrade.xrc \ + ui/dlgRepListen.xrc \ + ui/dlgRepNode.xrc \ + ui/dlgRepPath.xrc \ + ui/dlgRepSequence.xrc \ + ui/dlgRepSet.xrc \ + ui/dlgRepSetMerge.xrc \ + ui/dlgRepSetMove.xrc \ + ui/dlgRepSubscription.xrc \ + ui/dlgRepTable.xrc \ + ui/dlgRole.xrc \ + ui/dlgRule.xrc \ + ui/dlgSchedule.xrc \ + ui/dlgSchema.xrc \ + ui/dlgSearchObject.xrc \ + ui/dlgSelectConnection.xrc \ + ui/dlgSequence.xrc \ + ui/dlgServer.xrc \ + ui/dlgStep.xrc \ + ui/dlgSynonym.xrc \ + ui/dlgTable.xrc \ + ui/dlgTablespace.xrc \ + ui/dlgTextSearchConfiguration.xrc \ + ui/dlgTextSearchDictionary.xrc \ + ui/dlgTextSearchParser.xrc \ + ui/dlgTextSearchTemplate.xrc \ + ui/dlgTrigger.xrc \ + ui/dlgType.xrc \ + ui/dlgUser.xrc \ + ui/dlgUserMapping.xrc \ + ui/dlgView.xrc \ + ui/frmBackup.xrc \ + ui/frmBackupGlobals.xrc \ + ui/frmBackupServer.xrc \ + ui/frmExport.xrc \ + ui/frmGrantWizard.xrc \ + ui/frmHint.xrc \ + ui/frmImport.xrc \ + ui/frmMaintenance.xrc \ + ui/frmOptions.xrc \ + ui/frmPassword.xrc \ + ui/frmReport.xrc \ + ui/frmRestore.xrc \ + ui/dlgResourceGroup.xrc + +EXTRA_DIST += \ + ui/module.mk \ + ui/embed-xrc \ + ui/embed-xrc.bat + + diff --git a/ui/xrcDialogs.cpp b/ui/xrcDialogs.cpp new file mode 100644 index 0000000..54c992b --- /dev/null +++ b/ui/xrcDialogs.cpp @@ -0,0 +1,40072 @@ +// +// This file was automatically generated by wxrc, do not edit by hand. +// + +#include + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#include +#include +#include +#include + +#if wxCHECK_VERSION(2,8,5) && wxABI_VERSION >= 20805 + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFileWithMimeType(name, data, size, mime) +#else + #define XRC_ADD_FILE(name, data, size, mime) \ + wxMemoryFSHandler::AddFile(name, data, size) +#endif + +static size_t xml_res_size_0 = 3537; +static unsigned char xml_res_file_0[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,80,114,101,99,105,115,105,111,110,83,99,97,108,101,68, +105,97,108,111,103,34,62,10,32,32,32,32,60,116,105,116,108,101,62,68,97, +116,97,116,121,112,101,32,112,114,111,112,101,114,116,105,101,115,60,47, +116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +49,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,49,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,97,108,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,99,97,108,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,99,97, +108,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_1 = 2978; +static unsigned char xml_res_file_1[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,100,84,97,98,108,101,78,97,109,101,68,105,97,108,111,103, +34,62,10,32,32,32,32,60,116,105,116,108,101,62,84,97,98,108,101,32,112, +114,111,112,101,114,116,105,101,115,60,47,116,105,116,108,101,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,49,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,49,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115, +117,97,108,84,97,98,108,101,78,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,117, +97,108,32,84,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85, +115,117,97,108,84,97,98,108,101,78,97,109,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_2 = 2897; +static unsigned char xml_res_file_2[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,100,100,70,97,118,111,117,114,105,116,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,65,100,100,32,102,97,118,111,117, +114,105,116,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,50,48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,49,54,44,50,50,53,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,84,105,116,108,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,105,116,108,101,34,47,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,111, +99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,84,114,101,101,34,32,110,97,109,101, +61,34,116,114,76,111,99,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65,83,95,66,85,84, +84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95,66,79,82,68,69,82,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,78,101,119,70,111,108,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,70,111,108, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_3 = 12101; +static unsigned char xml_res_file_3[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,65,103,103,114,101,103,97,116,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,110,112,117,116,84,121,112,101,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,112,117,116,32,116,121,112,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,54,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116, +114,108,34,32,110,97,109,101,61,34,108,115,116,73,110,112,117,116,84,121, +112,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,84,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,38,97,109,112,59,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,54,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,112,117, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,116,97,116,101,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,116,97,116,101,32,116,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116, +97,116,101,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,116,97,116,101,70,117,110,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,97,116,101,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,116,97,116,101,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,105,110,97,108,70,117,110,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,110,97,108,32,102,117,110,99,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,70,105,110,97,108,70,117,110,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,114,116,79,112,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +111,114,116,32,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,111,114, +116,79,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +105,116,105,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,105,97,108,32,99, +111,110,100,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,73,110,105,116,105,97,108,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_4 = 7896; +static unsigned char xml_res_file_4[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,97,115,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,97,115,116,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,111,117,114,99,101,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,111,117,114,99,101,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,111,117,114,99,101,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114,103, +101,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,114,103,101,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,109, +112,108,105,99,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,109,112,108,105,99,105, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,109,112,108,105,99, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_5 = 6737; +static unsigned char xml_res_file_5[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,104,101,99,107,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,104,101,99,107,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,87, +104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,73,110,104,101,114,105,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,111,32,73,110,104,101,114,105,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +73,110,104,101,114,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,111,110,39,116,32,118,97,108,105,100,97,116,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,111,110,116,86,97,108,105,100,97,116,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_6 = 9024; +static unsigned char xml_res_file_6[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,108,97,116,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,50,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,53,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,111,99,97,108,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111, +99,97,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,108,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,99,67,111,108,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,67,95,67,79,76,76,65,84,69,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,99,67, +111,108,108,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,99,67,116,121,112, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,67,95,67,84,89,80,69,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,99,67,116,121,112,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,99,111,108, +108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_7 = 13272; +static unsigned char xml_res_file_7[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,108,117,109,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,116,121,112,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76, +101,110,103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,44,49,48,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97, +117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,32,118,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +111,116,32,78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,116,78,117,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,116,116, +115,116,97,116,116,97,114,103,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,116, +105,115,116,105,99,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,116,116,115,116,97, +116,116,97,114,103,101,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,111,114,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,32,124,32,119,120, +67,66,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_8 = 2535; +static unsigned char xml_res_file_8[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,110,101,99,116,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,67,111,110,110,101,99,116,32,116,111,32,83,101,114, +118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,50,48,53,44,56,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +48,53,44,32,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,69,110,116,101,114,32,116,104,101,32, +112,97,115,115,119,111,114,100,32,116,111,32,117,115,101,32,119,104,101, +110,32,99,111,110,110,101,99,116,105,110,103,32,116,111,32,116,104,101, +32,115,101,114,118,101,114,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116,111, +114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,49,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76, +80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,56,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_9 = 9325; +static unsigned char xml_res_file_9[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,67,111,110,118,101,114,115,105,111,110,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117, +108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,111,117,114,99,101,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,111,117,114,99,101,32,101,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,111,117,114,99,101,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,84,97,114,103,101,116,32,101,110,99,111,100,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,69,110,99,111,100,105,110, +103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_10 = 15692; +static unsigned char xml_res_file_10[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,55,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99, +111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119, +120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112,108,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,80,97,116,104,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80,97,116, +104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,98,108,101,115,112,97,99,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,108,108,97,116,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,108,108,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,114,97,99,116,101,114,32,116,121,112,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,83, +79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,110,101, +99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,110,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,62, +45,49,60,47,109,105,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104, +101,109,97,82,101,115,116,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97, +32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,83,99,104,101,109,97,82,101,115,116,114,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,86,97,114,105,97,98,108,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110, +97,109,101,61,34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,54,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82, +69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97, +110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114, +105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97, +108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,114,85,115,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,114,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,85,115,101,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_11 = 3334; +static unsigned char xml_res_file_11[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,105,114,101,99,116,68,98,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,86,105,101,119,32,68,97,116,97,32,79,112,116, +105,111,110,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,52,53,48,44,50,49,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119, +115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111, +111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,52,48,48,44, +49,56,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,101, +115,115,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,110,116,101,114,32,116,104,101, +32,114,101,113,117,105,114,101,100,32,118,97,108,117,101,115,32,102,111, +114,32,101,97,99,104,32,112,97,114,97,109,101,116,101,114,58,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,34,32, +110,97,109,101,61,34,103,114,100,80,97,114,97,109,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,83,101,116,32,116,104,101,32,102,117,110,99,116,105,111,110, +47,112,114,111,99,101,100,117,114,101,32,112,97,114,97,109,101,116,101, +114,32,118,97,108,117,101,115,46,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,80,107,103,73,110,105,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,98,117,103,32,112,97,99,107,97,103,101,32,105,110,105,116,105, +97,108,105,122,101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,101,98,117,103, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32, +99,117,114,114,101,110,116,32,111,112,116,105,111,110,115,32,97,110,100, +32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101, +46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117, +108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99,101,108,32,97,110, +121,32,99,104,97,110,103,101,115,32,97,110,100,32,99,108,111,115,101,32, +116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_12 = 12541; +static unsigned char xml_res_file_12[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,68,111,109,97,105,110,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,97,115,101,32,116,121,112,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,110,103,116,104,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,101,110, +103,116,104,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,114,101,99,105,115,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,80,114,101,99,105,115,105,111,110,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,97,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32, +78,85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,49,49,50,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,78,111,116,78,117,108,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,108,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_13 = 6909; +static unsigned char xml_res_file_13[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,100,105,116,71,114,105,100,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,86,105,101,119,32, +68,97,116,97,32,79,112,116,105,111,110,115,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,32,83,111,114,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,83,111,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,108,98,108,83,111,114,116,67,111,108,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,83,101,108,101,99,116,101,100,32,67,111,108,117,109,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,111,114,116, +67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,76,105,115,116,115,32,116,104,101,32,99, +111,108,117,109,110,115,32,116,104,97,116,32,116,104,101,32,100,97,116, +97,32,119,105,108,108,32,98,101,32,115,111,114,116,101,100,32,98,121,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108, +65,118,97,105,108,67,111,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,118,97,105,108, +97,98,108,101,32,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,111,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,83,101,108,101,99,116,32,97,32,99,111,108,117, +109,110,32,116,111,32,97,100,100,32,116,111,32,116,104,101,32,115,111,114, +116,32,108,105,115,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,44,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,65,115,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +115,99,101,110,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,65,100,100,32,116,104,101,32,115,101,108,101,99, +116,32,99,111,108,117,109,110,32,102,111,114,32,97,115,99,101,110,100,105, +110,103,32,115,111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,115,99,101,110,100, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,65,100,100,32,116,104,101,32,115,101,108,101,99,116,32,99,111,108,117, +109,110,32,102,111,114,32,100,101,115,99,101,110,100,105,110,103,32,115, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,101,114,115,112,101,99,116,105,118,101,62,49,60,47,112, +101,114,115,112,101,99,116,105,118,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,82,101,109,111,118, +101,32,116,104,101,32,115,101,108,101,99,116,101,100,32,115,111,114,116, +32,99,111,108,117,109,110,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,101,114,115,112,101,99,116,105,118, +101,62,49,60,47,112,101,114,115,112,101,99,116,105,118,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,116,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,108,98,108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,116, +101,114,32,83,116,114,105,110,103,32,40,101,103,46,32,111,105,100,32,38, +103,116,59,32,49,48,32,65,78,68,32,111,105,100,32,38,108,116,59,32,53,48, +41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,115,113, +108,70,105,108,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,102,105,108,116,101,114,32,115,116,114,105,110,103, +32,116,111,32,97,112,112,108,121,32,116,111,32,116,104,101,32,100,97,116, +97,46,32,83,81,76,32,115,121,110,116,97,120,32,115,104,111,117,108,100, +32,98,101,32,117,115,101,100,32,97,115,32,116,104,101,32,115,116,114,105, +110,103,32,119,105,108,108,32,98,101,32,117,115,101,100,32,97,115,32,97, +32,39,87,72,69,82,69,39,32,99,108,97,117,115,101,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,86,97,108,105,100,97,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,86,97,108,105,100,97,116,101, +32,116,104,101,32,115,121,110,116,97,120,32,111,102,32,116,104,101,32,102, +105,108,116,101,114,32,115,116,114,105,110,103,46,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117,114,114, +101,110,116,32,111,112,116,105,111,110,115,32,97,110,100,32,99,108,111, +115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,97,110,99, +101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110,100,32,99, +108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_14 = 9704; +static unsigned char xml_res_file_14[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,118,101,110,116,84,114,105,103,103,101,114,34, +62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +65,80,84,73,79,78,124,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,50,48,44,50,52,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70, +84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76, +69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62, +49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69, +70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,52,48,53,44,51,49,51,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76, +73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,69,110,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,32,83,116,97,116,117,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73, +71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,111,120,34,32,110,97,109,101,61,34,114,100,98,69,110,97,98,108, +101,83,116,97,116,117,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,78,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,82,69,80,76,73,67,65,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,65,76,87,65,89,83,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,51,56,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114, +105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,70,117,110,99,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,69,118,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68,76,32,67,79,77,77,65, +78,68,32,83,84,65,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,68, +76,32,67,79,77,77,65,78,68,32,69,78,68,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,83,81,76,32,68,82,79,80,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,51,51,44,51,56,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,45,49,44,45,49,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,55,52,44,49,56,55,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105, +110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,72,79,82,73,90,79,78,84,65,76,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71, +78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73, +71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,76,69,70,84,124,119, +120,65,76,73,71,78,95,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,76,69,70,84,124,119,120,65,76,73,71,78,95,84,79,80, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_15 = 6709; +static unsigned char xml_res_file_15[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,101,110,115,105,111,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,98,106,101,99,116,115,83,99,104,101,109,97,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114,115,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,86,101,114,115,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_16 = 6236; +static unsigned char xml_res_file_16[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,69,120,116,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109, +109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67, +65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120, +34,32,110,97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_17 = 8704; +static unsigned char xml_res_file_17[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,105,110,100,82,101,112,108,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,70,105,110,100,32,97,110,100,32,82, +101,112,108,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,54,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,70,105,110,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,105,110,100,32,119,104,97,116,58,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,70,105,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101, +114,32,116,104,101,32,115,116,114,105,110,103,32,116,111,32,115,101,97, +114,99,104,32,102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,70,73,78,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,70,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60, +47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,70,105,110,100,32,116,104,101,32, +115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,108,98,108,82,101,112,108,97,99,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,108,97, +99,101,32,119,105,116,104,58,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,82,101,112,108,97,99,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116, +101,114,32,116,104,101,32,114,101,112,108,97,99,101,109,101,110,116,32, +116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,80,76,65,67,69,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,82,101,112,108,97,99,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,70,105,110,100,32,97,110,100,32,114,101,112,108,97,99,101,32,116,104, +101,32,115,112,101,99,105,102,105,101,100,32,116,101,120,116,60,47,116, +111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,79,112,116,105,111,110,115,65,108,108,70,105,110,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +108,108,32,102,105,110,100,32,116,97,98,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105, +112,62,65,108,108,32,102,105,110,100,32,116,97,98,115,60,47,116,111,111, +108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,80,76,65, +67,69,65,76,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,82,101,112,108,97,99,101,32,38,97,109,112,59,65,108,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,70,105,110,100,32,97,110,100,32,114,101, +112,108,97,99,101,32,97,108,108,32,111,99,99,117,114,114,101,110,99,101, +115,32,111,102,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, +116,101,120,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,98,79, +114,105,103,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,114,105,103,105,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,79,114,105,103, +105,110,67,117,114,115,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,114,111,109,32,116,104, +101,32,99,117,114,115,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60, +47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,66,101,103,105,110,32,115,101, +97,114,99,104,105,110,103,32,97,116,32,116,104,101,32,99,117,114,114,101, +110,116,32,99,117,114,115,111,114,32,112,111,115,105,116,105,111,110,60, +47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,79,114,105,103,105,110,84,111,112,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,114,111,109, +32,116,104,101,32,116,111,112,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112, +62,66,101,103,105,110,32,115,101,97,114,99,104,105,110,103,32,97,116,32, +116,104,101,32,116,111,112,32,111,102,32,116,104,101,32,116,101,120,116, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +98,68,105,114,101,99,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,114,101,99,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,68,105,114,101,99,116,105,111,110,70,111,114,119,97,114,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,111,114,119,97,114,100,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117, +101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,97,114, +99,104,32,102,111,114,119,97,114,100,115,32,116,104,114,111,117,103,104, +32,116,104,101,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,114,100,68,105,114,101,99,116,105,111, +110,66,97,99,107,119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,97,99,107,119,97,114, +100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,97,114,99, +104,32,98,97,99,107,119,97,114,100,115,32,116,104,114,111,117,103,104,32, +116,104,101,32,116,101,120,116,60,47,116,111,111,108,116,105,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,98,79,112,116,105,111,110,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,112,116,105,111,110,115,87,104,111,108,101,87,111, +114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,87,104,111,108,101,32,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,111,110,32,119, +104,111,108,101,32,119,111,114,100,115,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,79,112,116,105,111,110,115,77,97, +116,99,104,67,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,99,97,115,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,116,99,104,32,116,104, +101,32,99,97,115,101,32,111,102,32,116,104,101,32,116,101,120,116,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,112, +116,105,111,110,115,85,115,101,82,101,103,101,120,112,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,103,117,108,97,114,32,101,120,112,114,101,115,115,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,116,111,111,108,116,105,112,62,85,115,101,32,114,101,103, +117,108,97,114,32,101,120,112,114,101,115,115,105,111,110,115,32,119,104, +101,110,32,115,101,97,114,99,104,105,110,103,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,108,111,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,108,111, +115,101,32,116,104,101,32,100,105,97,108,111,103,60,47,116,111,111,108, +116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_18 = 11336; +static unsigned char xml_res_file_18[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,68,97,116,97,87,114,97, +112,112,101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,110, +100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,108,105,100,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,86,97,108,105,100,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67, +95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47, +111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79, +77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79, +78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111, +118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104, +97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44, +55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_19 = 14711; +static unsigned char xml_res_file_19[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,75,101,121,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +101,114,114,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,101,102,101, +114,114,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,101,102,101,114,114,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,97,116,99,104,70,117, +108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,77,97,116,99,104,32,102,117,108,108,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,77,97,116,99,104,70,117,108,108,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,111,110,116,86,97,108,105,100, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,110,39,116,32,118,97,108,105,100, +97,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,68,111,110,116,86,97,108,105,100,97, +116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,117, +116,111,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,117,116,111,32,70,75, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,73,110, +100,101,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110,100, +101,120,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,118,101,114,105,110,103, +32,105,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,110,100,101,120,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,84,79,80,124,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101, +102,101,114,101,110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,102, +101,114,101,110,99,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,102,101,114,101, +110,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,108,117,109,110,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,76,111,99,97,108,32,99,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,82,101,102,67,111,108,117,109,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,102,101,114,101,110,99,105,110,103,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,82,101,102,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,82,101,102, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,82,101,102,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,65,99,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,85,112,100,97,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,79,110,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,110,32,68,101,108,101,116,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,79, +32,65,67,84,73,79,78,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,69,83, +84,82,73,67,84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,67,65,83,67,65, +68,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,78,85,76,76, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,83,69,84,32,68,69,70,65,85,76, +84,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115, +105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_20 = 11156; +static unsigned char xml_res_file_20[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57, +54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67, +116,114,108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111, +110,62,56,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124, +119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66, +79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79, +82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,51,44,53,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65, +100,100,47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_21 = 17718; +static unsigned char xml_res_file_21[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,111,114,101,105,103,110,84,97,98,108,101,34,62, +10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,52,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119, +110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,111,114,101,105,103,110,83,101,114,118,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,114,101,105,103,110,32,83,101,114,118,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,70,111,114,101,105,103,110,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117, +109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,67,111,108,117,109,110, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67,111,109,112, +111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67, +116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101,109,98,101,114, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79, +82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,32, +110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,114,101,99,105,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,80,114,101,99,105,115,105,111,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,111,116,78,117,108,108,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,78,79,84,32,78,85,76,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,116,78,117, +108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,77,101,109,98,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,65,100,100,77,101,109,98,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,67,104,97,110,103,101,77,101,109,98,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71, +78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79, +112,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,79,112,116, +105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,79,112,116, +105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,112,111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112, +116,105,111,110,62,56,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,79,112,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_22 = 27606; +static unsigned char xml_res_file_22[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115, +116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114, +83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,65,114,103,117,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114, +103,117,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,117, +109,101,110,116,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,82,101,116,117,114,110,116,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,116,117,114,110,32,116,121,112,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,82,101,116,117,114,110,116,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,110,103,117,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,76,97,110,103,117,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,111,108,97,116,105,108,105,116,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,111,108,97,116,105,108,105,116,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,86,111,108,97,116,105,108,105,116,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,86,79,76,65,84,73,76,69,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,84,65,66,76,69,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,77,77,85,84,65,66,76,69,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,97,114,97,108,108,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,97,114,97,108,108,101,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +80,97,114,97,108,108,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,85,78,83,65,70,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82, +69,83,84,82,73,67,84,69,68,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83, +65,70,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99, +116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,101,116,111,102,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,116,117, +114,110,115,32,115,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,116,111, +102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,114, +105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,116,114,105,99,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,83,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,101,99,117,114,101,68,101,102,105,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,99,117,114,105,116,121,32,111,102,32,100,101, +102,105,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,117,114,101,68, +101,102,105,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,87,105,110,100,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105,110,100,111, +119,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,87,105,110, +100,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,115,116,105,109,97,116,101,100,32, +99,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,115,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,111,119,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,69,115,116,105,109,97,116,101,100,32,114,111,119,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,76,101,97,107,80,114,111,111,102,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,101,97,107,32,112,114,111,111,102,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,76,101,97,107, +80,114,111,111,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,97,114,97,109,101,116,101,114,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,97,114,97,109,101,116,101,114,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105, +115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,65,114,103, +117,109,101,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80, +79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,97,116,97,116,121,112,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,97,116,97,116,121,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111,100,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82, +66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +100,98,79,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,85,84, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,73,110,79,117,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,78,32,79,85,84,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,114,100,98,86,97,114,105,97,100,105, +99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,82,73,65,68,73,67, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,124,119,120,66,79,84,84,79,77,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,65,114,103,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,114,103, +117,109,101,110,116,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,65,114,103,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,68, +101,102,86,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,97,117,108, +116,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,65,114,103,68, +101,102,86,97,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,76,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,72,65,78,71,69,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,100, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,67,111,100,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,98,106,101,99,116,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79, +98,106,101,99,116,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,98,106, +101,99,116,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,105, +110,107,83,121,109,98,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,105,110, +107,32,115,121,109,98,111,108,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,105,110,107, +83,121,109,98,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110, +97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75, +69,78,95,66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69, +88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86,97,114,105, +97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73, +78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,86,97,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,82,101,109,111,118,101,86,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,86,97, +114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_23 = 7226; +static unsigned char xml_res_file_23[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,71,114,111,117,112,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,71,114,111,117,112,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +101,109,98,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,101,109, +98,101,114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,115,78, +111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77,101,109,98,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101, +61,34,108,98,85,115,101,114,115,78,111,116,73,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120, +76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,103,116,59,38,103,116,59,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,68,101,108,85,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,108,116,59,38,108,116,59,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,84,79,80,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66, +111,120,34,32,110,97,109,101,61,34,108,98,85,115,101,114,115,73,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69,68,95, +83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_24 = 5724; +static unsigned char xml_res_file_24[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,72,98,97,67,111,110,102,105,103,34,62,10,32,32,32, +32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99,99,101,115, +115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60,47,116,105, +116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108, +101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,85,115,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,73,80,97,100,100,114,101,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +80,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,73,80,97,100,100,114,101,115,115,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,101, +116,104,111,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,116,104,111,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,77,101,116,104,111,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,112,116, +105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_25 = 16342; +static unsigned char xml_res_file_25[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101, +115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,110,105,113,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,85,110,105,113,117,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110, +105,113,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115, +116,101,114,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,67,108,117,115,116,101,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +110,99,117,114,114,101,110,116,108,121,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +99,117,114,114,101,110,116,32,98,117,105,108,100,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,111,110,99,117,114,114,101,110,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34, +99,98,67,111,108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112, +67,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101,114,97,116, +111,114,32,99,108,97,115,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,67,108,97,115, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,69,83,67,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +68,101,115,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,82,73,71,72,84,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,117,108,108,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,78,85,76,76,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,48,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,100,98,78,117,108,108,115,70,105,114,115,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,73,82,83,84,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108, +115,76,97,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,76,65,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101, +109,111,118,101,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,48,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_26 = 16411; +static unsigned char xml_res_file_26[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,73,110,100,101,120,67,111,110,115,116,114,97,105, +110,116,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108, +101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,110,100,101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,65,99,99,101,115,115,32,109,101,116,104,111,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +105,108,108,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114, +101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,87,104,101,114,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,115,116,114,97,105,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,87,104,101,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,79,112,67,108,97,115,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,112,101,114,97,116,111,114,32,99,108,97,115,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,79,112,67,108,97,115,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,69,83,67,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,101,115,99,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,117,108,108,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,85,76,76,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +48,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,114,100,98,78,117,108,108,115,70, +105,114,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +70,73,82,83,84,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,53,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,100,98,78,117,108,108,115,76,97,115,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,76,65,83,84,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118, +97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,112,101,114,97, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51, +44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_27 = 13557; +static unsigned char xml_res_file_27[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,74,111,98,34,62,10,32,32,32,32,60,116,105,116,108, +101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,50,56,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,50,53,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,74,111,98,99,108,97,115,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,74,111,98,32,99,108,97,115,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,74,111,98, +99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,111,115,116,65,103,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115,116,32, +97,103,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,65,103,101,110, +116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,114,101,97,116,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,114,101,97,116,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,114,101, +97,116,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,104,97,110,103,101,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,104,97,110,103,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,104,97, +110,103,101,100,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,101,120,116,114,117,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,101,120,116,32,114,117,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +101,120,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115,116,114,117, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,76,97,115,116,32,114,117,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,76,97,115,116,114,117,110,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,115, +116,82,101,115,117,108,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,115,116,32,114,101, +115,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,76,97,115,116,82,101,115,117, +108,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,116,101,112,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,101,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,83,116,101,112, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120, +76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98, +116,110,67,104,97,110,103,101,83,116,101,112,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,83,116,101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,83,116, +101,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,100,117,108,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +83,99,104,101,100,117,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95, +82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101,83,99,104,101, +100,117,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,98,116,110,65,100,100,83,99,104,101,100,117, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,82,101,109,111,118,101,83,99,104,101,100,117,108,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_28 = 8800; +static unsigned char xml_res_file_28[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,117,115,116,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,114,117,115,116,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114, +117,115,116,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,97,110,100,108,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,97,110,100,108,101,114, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,97,110,100,108, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,108,105,110,101,32,102,117,110, +99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,73,110,108,105,110,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,86,97,108,105,100,97,116,111,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,86,97,108,105,100,97,116,111,114,32,102,117,110,99, +116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,108,105,100,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_29 = 4926; +static unsigned char xml_res_file_29[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,105,110,67,111,110,102,105,103,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,50,52,56,44,49,57,56,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,101,115,99, +114,105,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,48,44,54,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,50,51,56,44,57,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95, +78,79,95,65,85,84,79,82,69,83,73,90,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_30 = 2870; +static unsigned char xml_res_file_30[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,70,97,118,111,117,114,105,116, +101,115,34,62,10,32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103, +101,32,102,97,118,111,117,114,105,116,101,115,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,49,56,44,49,57,56,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,116,114,76,111,99, +97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,50,48,56,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,32,124,32,119,120,83,73,77,80,76,69,95, +66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +51,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,82,101,110,97,109, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,101,116,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,78,101,119,70,111,108,100, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,101,119,32,102,111,108,100,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_31 = 4804; +static unsigned char xml_res_file_31[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,77,97,110,97,103,101,77,97,99,114,111,115,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,110,97,103,101,32,77,97,99, +114,111,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109, +101,61,34,108,115,116,75,101,121,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,105,110,115,105,122,101,62,49,53,48,100,60,47,109,105,110,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,44,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108, +83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113,108,66, +111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,105,110,115,105,122, +101,62,50,48,48,44,49,48,48,100,60,47,109,105,110,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,108,101,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101, +97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,52,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,97,118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,97,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,44,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_32 = 3447; +static unsigned char xml_res_file_32[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,77,111,118,101,84,97,98,108,101,115,112,97,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,111,98,106,101, +99,116,115,32,116,111,32,97,110,111,116,104,101,114,32,116,97,98,108,101, +115,112,97,99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,48,48,44,50,48,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,78,101,119,32,116,97,98, +108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,77,111,118,101,84,111,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,98,106,101,99,116,115,39,32, +107,105,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,75,105,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,98,106,101,99,116,115,39,32,111,119,110,101,114, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67, +69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98, +106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_33 = 15920; +static unsigned char xml_res_file_33[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,79,112,101,114,97,116,111,114,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117, +115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,76,101,102,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,101,102, +116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,102,116,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,82,105,103,104,116,84,121,112,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,105, +103,104,116,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,105,103,104,116, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,99,101,100,117,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,101,114,97,116,111,114,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,99,101,100,117,114,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +109,112,108,101,109,101,110,116,97,116,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,50,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,114, +105,99,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,115, +116,114,105,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +74,111,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,102,117,110,99,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,74,111,105,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,117,116,97,116,111,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,109,117,116,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,109,109,117,116,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,78,101,103,97,116,111,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +101,103,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,78,101,103,97,116,111,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,101,102,116,83,111,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,101,102,116,32,115,111,114,116,32,111,112,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,76,101,102,116,83,111,114,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,105,103,104,116,83,111,114,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,105,103,104,116,32,115,111,114,116,32,111,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,105,103,104,116,83,111,114,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,115,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,32,111,112,101,114,97,116,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,115,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,71,114,101,97,116,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,38,103,116,59,32,111,112,101,114,97,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,71,114,101,97,116,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,97,110,72,97,115,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,112,111,114,116,115,32,104,97,115,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97, +110,72,97,115,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,77,101,114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,117,112,112,111,114, +116,115,32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,97,110,77,101, +114,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_34 = 7045; +static unsigned char xml_res_file_34[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,97,99,107,97,103,101,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97, +100,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,72,101,97,100,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112, +62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109, +101,61,34,116,120,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,83,85,78,75,69,78,95, +66,79,82,68,69,82,124,119,120,84,69,95,82,73,67,72,50,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,66,111,100, +121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124, +119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120,84,69,95,82, +73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_35 = 5366; +static unsigned char xml_res_file_35[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,80,103,112,97,115,115,67,111,110,102,105,103,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,67,108,105,101,110,116,32,65,99, +99,101,115,115,32,67,111,110,102,105,103,117,114,97,116,105,111,110,60, +47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,111, +115,116,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,72,111,115,116,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115,116,110,97, +109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,68,97,116,97,98,97,115,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,114,110,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114,110, +97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83, +87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,82,101,80,97,115,115,119,111,114, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80,97,115, +115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_36 = 3212; +static unsigned char xml_res_file_36[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,85,84,70,45,56,34,63,62,10,60,114,101, +115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109,101,61,34, +100,108,103,82,101,97,115,115,105,103,110,68,114,111,112,79,119,110,101, +100,34,62,10,32,32,32,32,60,116,105,116,108,101,62,82,101,97,115,115,105, +103,110,47,68,114,111,112,32,79,119,110,101,100,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,48,48,44,50,48,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,82,101,97,115,115,105,103,110,84, +111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,82,101,97,115,115,105,103,110,32,111,98,106,101, +99,116,115,32,116,111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,82,111,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,114,98,68,114,111,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,68,114,111,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,70,114,111,109,32,100,97,116,97,98,97,115,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60, +47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62, +10}; + +static size_t xml_res_size_37 = 9858; +static unsigned char xml_res_file_37[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,34,62,10,32, +32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101, +62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,54,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,74,111,105,110, +67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,74,111,105,110,32,101,120, +105,115,116,105,110,103,32,99,108,117,115,116,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,74,111,105,110,67,108,117,115,116,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,97,116,97,98,97,115,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,108,117,115,116,101,114,32,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,108,117, +115,116,101,114,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,111,100,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,73,68,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,111,100,101,78,97,109, +101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,109,105,110, +32,78,111,100,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +65,100,109,105,110,78,111,100,101,73,68,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,65,100,109,105,110,78,111,100,101,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,65,100,109,105,110,78,111,100,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_38 = 5387; +static unsigned char xml_res_file_38[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,67,108,117,115,116,101,114,85,112,103, +114,97,100,101,34,62,10,32,32,32,32,60,116,105,116,108,101,62,85,112,103, +114,97,100,101,32,99,108,117,115,116,101,114,32,115,111,102,116,119,97, +114,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,117,114,114,101,110,116,86, +101,114,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101,110,116, +32,118,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114, +101,110,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101, +114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +97,116,97,98,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101, +114,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,108,117,115,116,101,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,108,117,115,116,101,114,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,86,101,114,115,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,101,114,115,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,86,101,114,115,105,111,110,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_39 = 4038; +static unsigned char xml_res_file_39[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,76,105,115,116,101,110,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,114,105,103,105, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,101,99,101,105, +118,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,82,101,99,101,105,118,101,114,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,114,111,118,105,100,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,114,111,118,105,100,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_40 = 3343; +static unsigned char xml_res_file_40[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,78,111,100,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_41 = 3939; +static unsigned char xml_res_file_41[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,80,97,116,104,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48, +44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,101,114,118,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,73,110, +102,111,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,105,110,102, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,110,110,73,110,102,111,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,110,110,82,101,116,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,110,110,32,114,101,116,114,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,67,111,110,110,82,101,116,114,121,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_42 = 4031; +static unsigned char xml_res_file_42[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,113,117,101,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49, +50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,113, +117,101,110,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,101,113,117,101,110,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_43 = 4313; +static unsigned char xml_res_file_43[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44, +49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,79,114,105,103,105,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,79,114,105,103,105,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,79,114,105,103,105,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,50,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51, +53,44,54,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_44 = 3396; +static unsigned char xml_res_file_44[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,101,114,103,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,101,114,103,101,32,115,101,116, +32,105,110,116,111,32,97,110,111,116,104,101,114,32,115,101,116,60,47,116, +105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49, +53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69, +124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69, +78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,116,32,116,111, +32,109,101,114,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,114, +103,101,116,32,111,102,32,109,101,114,103,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_45 = 3381; +static unsigned char xml_res_file_45[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,101,116,77,111,118,101,34,62,10,32, +32,32,32,60,116,105,116,108,101,62,77,111,118,101,32,115,101,116,32,116, +111,32,111,116,104,101,114,32,110,111,100,101,60,47,116,105,116,108,101, +62,10,32,32,32,32,60,115,105,122,101,62,50,50,48,44,49,53,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68, +69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67, +65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73, +68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,78,111,100,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,114,103,101,116,32,78,111,100,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,78,111,100,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_46 = 4740; +static unsigned char xml_res_file_46[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,83,117,98,115,99,114,105,112,116,105,111, +110,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60, +115,105,122,101,62,50,50,48,44,49,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68, +73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,49, +54,44,49,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99, +116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,114,105,103, +105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,114,105,103,105,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,79,114,105,103,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82, +69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,82,101,99,101,105,118,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +99,101,105,118,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,99,101,105,118, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78,76,89, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,114, +111,118,105,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,118,105,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,80,114,111,118,105,100,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,114,119,97,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,102,111,114,119,97,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,70,111,114,119,97,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_47 = 5504; +static unsigned char xml_res_file_47[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,112,84,97,98,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,49,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,49,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,110,100,101,120,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,100, +101,120,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,73,110,100,101,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +114,105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,114,105, +103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76,105, +115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,105,103, +103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,48,48,44,57,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_48 = 4089; +static unsigned char xml_res_file_48[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,101,115,111,117,114,99,101,71,114,111,117,112, +34,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,71,114,112,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,114,111, +117,112,32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,80,85,82,97,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,80, +85,32,82,97,116,101,32,76,105,109,105,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +80,85,82,97,116,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,105,114,116,121,82,97,116, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,114,116,121,32,82,97,116,101,32,76,105,109, +105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,68,105,114,116,121,82,97,116,101,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,49,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +49,54,44,50,48,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,115,105,122,101, +62,50,50,48,44,50,51,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69, +82,60,47,115,116,121,108,101,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_49 = 20602; +static unsigned char xml_res_file_49[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,111,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,55,48,44,50,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,54,54,44,50,50,53,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111, +108,101,32,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,82,69,65,68,79,78,76,89,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,100,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111, +114,100,32,40,97,103,97,105,110,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,82,101,80, +97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,99,99,111,117, +110,116,32,101,120,112,105,114,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,97,108,101,110,100,97, +114,66,111,120,34,32,110,97,109,101,61,34,100,97,116,86,97,108,105,100, +85,110,116,105,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,80,95,65, +76,76,79,87,78,79,78,69,124,119,120,68,80,95,68,82,79,80,68,79,87,78,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109, +101,83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109, +86,97,108,105,100,85,110,116,105,108,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110, +101,99,116,105,111,110,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110, +110,101,99,116,105,111,110,32,76,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,110,110,101,99,116,105,111,110,76,105,109,105,116,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,32,112,114,105,118, +105,108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,82,111,108, +101,115,80,114,105,118,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,97,110,76,111,103,105,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,108,111,103,105,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,73,110,104,101,114,105,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,32,114,105,103,104,116,115,32,102,114,111, +109,32,112,97,114,101,110,116,32,114,111,108,101,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,83,117,112,101,114,117,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,112,101,114,117,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,110,32,99,114, +101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,82,111,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,99,114,101,97,116,101,32,114,111,108,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,85,112,100,97,116,101,67,97,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,97,110,32,109,111,100,105,102,121,32,99,97,116,97,108, +111,103,32,100,105,114,101,99,116,108,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,82,101,112,108,105,99,97,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,97,110,32,105,110,105,116,105,97,116,101,32,115,116,114,101,97, +109,105,110,103,32,114,101,112,108,105,99,97,116,105,111,110,32,97,110, +100,32,98,97,99,107,117,112,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,82,111,108,101,32,109,101,109,98,101,114,115,104,105,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,82,111,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,111,108,101,115,78,111,116,73,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,78,111,116,32,77,101,109,98,101,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,115,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,101,109,98,101,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,98,82,111,108, +101,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79,82,84,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,65,100,100,82,111,108,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,103,116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,68,101,108,82,111,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116, +59,38,108,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84, +79,80,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,98,82,111,108,101,115,73,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,65,100,109,105,110,79,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,87,73,84,72,32,65,68,77,73,78,32,79,80,84,73,79,78,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,86, +97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,53,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,86, +97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108,117,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,32,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114, +68,98,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97, +115,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,86,97,114,68,98,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_50 = 8283; +static unsigned char xml_res_file_50[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,82,117,108,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,118,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,118,101,110,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +98,120,69,118,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,69,76,69,67,84,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,73,78,83,69,82,84,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +85,80,68,65,84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,68,69,76,69, +84,69,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110, +115,105,111,110,62,49,60,47,100,105,109,101,110,115,105,111,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,111,73,110,115,116, +101,97,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,68,111,32,105,110,115,116,101,97,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,111,73,110,115,116,101,97,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,110,100,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,100,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,67,111,110,100,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,83,116,97,116,101,109,101,110,116,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,83,116,97,116,101,109,101,110,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116,83,113, +108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49, +60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_51 = 19358; +static unsigned char xml_res_file_51[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,100,117,108,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,50,50, +48,44,50,53,48,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,49,54,44,50,50,53,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +53,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,82,69,65,68,79,78, +76,89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109, +101,61,34,99,97,108,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,110,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97,109, +101,61,34,116,105,109,69,110,100,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,121,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,68,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,50,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87, +101,101,107,32,68,97,121,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116, +109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65, +85,84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78, +95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34, +99,104,107,87,101,101,107,100,97,121,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,45,49,44,55, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,83,117,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77, +111,110,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,117, +101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,87,101, +100,110,101,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,84, +104,117,114,115,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,70, +114,105,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,97,116, +117,114,100,97,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,111,110,116,104,32,68,97,121,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,105,116,109,97,112,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,77,111,110,116,104,100,97,121,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,66,85,95,65,85,84,79,68,82,65,87,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,99,104,107,77,111,110,116,104,100,97,121,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,45,49,44,55,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,49,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,50,110,100,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,114,100, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,52,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,53,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,54,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,55,116,104, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,56,116,104,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,57,116,104,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,49,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,49,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,50,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,51,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,49,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,49,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,49,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,49,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,50,110,100,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,51,114,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,52,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,50,53,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,54,116, +104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,50,55,116,104,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,50,56,116,104,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,50,57,116,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,51,48,116,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,51,49,115, +116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,76,97,115,116,32,100,97, +121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,111, +110,116,104,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105, +116,109,97,112,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85, +84,79,68,82,65,87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,77,111,110,116,104,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,74,97,110,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +70,101,98,114,117,97,114,121,60,47,105,116,101,109,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +77,97,114,99,104,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,112,114, +105,108,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,77,97,121,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,74,117,110,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,74,117,108,121,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,65,117,103,117,115,116,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,83,101,112,116,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,79,99,116,111,98,101,114,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,78,111,118,101,109,98,101,114,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,68,101,99,101,109,98,101,114,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,105,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,84,105,109, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,72,111,117,114,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,111,117,114,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65,87, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,76, +105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,72,111,117, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,45,49,44,49,48,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,110,117,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,105,116,109,97,112,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,77,105,110,117, +116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,66,85,95,65,85,84,79,68,82,65, +87,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,66,79,84,84,79,77,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,99,104,107,77,105, +110,117,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,69,120,99,101,112,116,105,111,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,69,120,99,101,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32, +110,97,109,101,61,34,108,115,116,69,120,99,101,112,116,105,111,110,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76, +67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,44,51,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,68,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,97,108,101,110,100,97,114,66,111,120,34,32, +110,97,109,101,61,34,99,97,108,69,120,99,101,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69, +124,119,120,68,80,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,105,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,105,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,105,109,101, +83,112,105,110,67,116,114,108,34,32,110,97,109,101,61,34,116,105,109,69, +120,99,101,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,69,120,99,101,112,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,104,97,110,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,69,120,99,101,112,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,82,101,109,111,118,101,69,120,99,101,112,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_52 = 5520; +static unsigned char xml_res_file_52[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,99,104,101,109,97,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,51,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78, +97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_53 = 7618; +static unsigned char xml_res_file_53[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,97,114,99,104,79,98,106,101,99,116,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,83,101,97,114,99,104,32,79,98,106, +101,99,116,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122, +101,62,51,53,51,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,114,111,119,115,62,48,60,47,114,111, +119,115,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,49,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,124,119,120,65,76,76, +124,119,120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,71,114,105,100,66,97,103,83,105,122,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,51,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,48,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,97,116,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,116,116,101,114,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,48,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,97,116,116,101,114,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111, +111,108,116,105,112,62,69,110,116,101,114,32,112,97,114,116,32,111,102, +32,116,104,101,32,111,98,106,101,99,116,39,115,32,97,116,116,114,105,98, +117,116,101,32,121,111,117,39,114,101,32,108,111,111,107,105,110,103,32, +102,111,114,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +83,101,97,114,99,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,105,110,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,112,111,115,62,49,44,48,60,47,99,101,108, +108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108, +108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84, +121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +101,108,108,112,111,115,62,49,44,49,60,47,99,101,108,108,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110, +62,49,44,49,60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,66,79,84,84,79,77,124,119, +120,69,88,80,65,78,68,124,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,55,48,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115, +62,50,44,48,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101, +108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119, +120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,50,44, +49,60,47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108, +115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,66,79,84,84,79,77,124,119,120,69,88,80,65,78,68,124,119, +120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95,82,69,65,68,79,78,76, +89,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,55,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,48,60,47, +99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,101,108,108,115,112,97,110,62,49,44,49,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,84,79,80,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,117,108,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,112,111,115,62,51,44,49,60, +47,99,101,108,108,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,101,108,108,115,112,97,110,62,49,44,50,60,47,99,101,108,108,115,112, +97,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115, +62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114, +111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101, +61,34,108,99,82,101,115,117,108,116,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,52,48,44,49,53,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,99,101,108,108, +112,111,115,62,48,44,50,60,47,99,101,108,108,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,101,108,108,115,112,97,110,62,51,44,49, +60,47,99,101,108,108,115,112,97,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,72,79,82,73,90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110, +116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110, +62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120, +84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,78,97,109,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111,112,116,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,105,110,105,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,100,101, +102,105,110,105,116,105,111,110,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60,47,111, +112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,76,69,70,84,124,119,120,84,79,80,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,109,109,101,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,99,111, +109,109,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +114,111,119,115,62,48,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,47,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,48,60, +47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,108,111,115,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32, +110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84, +95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_54 = 1165; +static unsigned char xml_res_file_54[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,108,101,99,116,67,111,110,110,101,99,116,105, +111,110,34,62,10,32,32,32,32,60,116,105,116,108,101,62,67,111,110,110,101, +99,116,32,116,111,32,83,101,114,118,101,114,60,47,116,105,116,108,101,62, +10,32,32,32,32,60,115,105,122,101,62,50,48,53,44,57,56,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,101,114,118,101,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,83,101,114,118,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,97,116,97,98,97,115,101,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44, +50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101,110, +97,109,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,53,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,50,44,56,48,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,57,55,44,56,48,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,53,48,44,56,48,100,60,47,112,111,115,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_55 = 10154; +static unsigned char xml_res_file_55[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,113,117,101,110,99,101,34,62,10,32,32,32,32, +60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48, +48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +52,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,119,110,101,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,119,110,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,99,104,101, +109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76,73, +78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,50,52,55, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,73,110,99,114,101,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,73,110,99,114,101,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,73,110,99,114,101,109,101,110,116,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,83,116,97,114,116,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,77,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,77,105,110,105,109,117,109,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,77,105,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,77,97,120,105,109,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97,120,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,97,99,104,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,99,104, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,97,99,104,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,121,99,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,67,121,99,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49, +60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115, +66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115, +66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116, +62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_56 = 24087; +static unsigned char xml_res_file_56[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,101,114,118,101,114,34,62,10,32,32,32,32,60,116, +105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44, +50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76, +69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77, +69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116, +121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116, +101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,115,99,114,105,112,116,105,111,110,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,68,101,115,99, +114,105,112,116,105,111,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,72,111,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,114, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,101,114,118,105,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,105,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,105,110, +116,101,110,97,110,99,101,32,68,66,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,115,101,114,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,85,115,101,114, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,80,97,115,115,119,111,114,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,116,111,114,101,32,112,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,116,111,114,101,80,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,111,117,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,99,111,108,111,117,114, +80,105,99,107,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,71,114,111,117,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,83,76,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,83,83,76,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114, +32,82,111,111,116,32,67,101,114,116,105,102,105,99,97,116,101,32,70,105, +108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101, +114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +83,76,82,111,111,116,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,83,83,76,32,82,111,111,116,32,67,101,114,116,105,102, +105,99,97,116,101,32,70,105,108,101,60,47,109,101,115,115,97,103,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105, +108,100,99,97,114,100,62,42,46,99,114,116,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,114,118,101,114,32,67, +101,114,116,105,102,105,99,97,116,101,32,82,101,118,111,99,97,116,105,111, +110,32,76,105,115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105, +99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107, +101,114,83,83,76,67,114,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,67,101,114,116,105,102,105,99,97,116,101,32,82,101, +118,111,99,97,116,105,111,110,32,76,105,115,116,32,70,105,108,101,60,47, +109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,99,114,108, +60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80, +95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,83,83,76,67,101,114,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,108,105,101,110,116,32,67,101,114,116,105,102,105,99,97,116,101, +32,70,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,83,83,76,67,101,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101, +99,116,32,83,83,76,32,99,101,114,116,105,102,105,99,97,116,101,32,102,105, +108,101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62, +42,46,99,114,116,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,83,76,75,101,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,108,105,101,110,116,32,75,101,121,32,70,105,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114, +108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,83,76,75,101,121, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,83,83,76,32,107, +101,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,46,107,101,121,60,47,119,105,108,100,99,97,114,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,76, +67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,83,76, +32,67,111,109,112,114,101,115,115,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83, +76,67,111,109,112,114,101,115,115,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,83,83,72,32,84,117,110,110,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,83,83,72,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,83,72,84,117,110, +110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,83,72,32,116,117,110, +110,101,108,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107, +66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,83,72,84,117,110,110, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,117,110,110,101, +108,72,111,115,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,117,110,110,101,108,32,104,111, +115,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,84,117,110,110,101,108,72,111,115,116, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,117,110,110,101,108,80,111,114,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,117,110,110,101,108,32,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,117,110,110,101,108,80,111,114,116,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +84,117,110,110,101,108,85,115,101,114,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,115,101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,85,115,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +65,117,116,104,101,110,116,105,99,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,104,101,110,116,105,99,97,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,49,48,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,49,48,60,47,104,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,97,100,105,111,66,116,110,80,97,115,115,119,111,114,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100, +105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,97,100,105, +111,66,116,110,75,101,121,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,73,100,101,110,116,105,116,121,32,102,105,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,101,110, +116,105,116,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108, +101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,73,100,101,110,116,105,116,121,70,105,108,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,105,100,101,110,116,105, +116,121,32,102,105,108,101,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100, +99,97,114,100,62,42,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,48,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,117,98,108,105,99,75,101, +121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,117,98,108,105,99,32,107,101, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99,107,101,114,67, +116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114,80,117,98, +108,105,99,75,101,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101, +108,101,99,116,32,112,117,98,108,105,99,32,107,101,121,32,102,105,108,101, +60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,46,112, +117,98,60,47,119,105,108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70, +76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,117,110,110,101,108,80,97,115,115, +119,111,114,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,47,80, +97,115,115,112,104,114,97,115,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,117,110, +110,101,108,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,65,100,118,97,110,99,101,100,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,97,108,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,111,115,116,65,100,100,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,111,115, +116,32,65,100,100,114,101,115,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,111,115, +116,65,100,100,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,114,121,67,111,110,110,101, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,110,110,101,99,116,32,110,111,119,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,114,121,67,111,110,110,101,99,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,82,101,115,116,111,114,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,115,116,111,114,101,32,101,110,118,63,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,82,101,115,116,111,114,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,82,111,108,101,110,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,68,98,82,101,115,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +66,32,114,101,115,116,114,105,99,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,98,82,101,115,116,114,105,99,116,105,111,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,101,114,118,105,99,101,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,101,114,118,105,99,101,32,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,83,101,114,118,105,99,101,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_57 = 10963; +static unsigned char xml_res_file_57[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,116,101,112,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,55,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,68,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,73,68,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69, +110,97,98,108,101,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,110,110,84,121,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,110,110,101,99,116,105,111,110,32,84,121,112, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,49,60,47,111,112,116,105,111,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,48,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105, +111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99, +97,108,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95, +71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +76,111,99,97,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101, +62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,82,101,109,111,116, +101,67,111,110,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,116,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101, +110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,98,97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,98,97,115, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,97,116,97,98, +97,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,101,110,97,98,108,101,62,48,60,47,101,110,97, +98,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,110,110,101,99,116,105,111,110,32,83,116,114,105,110, +103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,84,79,80,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,84,79,80,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,48,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,48,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,67,111,110,110,83,116,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97, +98,108,101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,83,101,108,68,97,116,97,98,97,115,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,101,110,97,98,108, +101,62,48,60,47,101,110,97,98,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111, +120,34,32,110,97,109,101,61,34,114,98,120,75,105,110,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,83,81,76,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,66,97,116,99,104,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,105,110,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100, +105,109,101,110,115,105,111,110,62,49,60,47,100,105,109,101,110,115,105, +111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89,95,67, +79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34, +32,110,97,109,101,61,34,114,98,120,79,110,69,114,114,111,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,110,32,101,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,70,97,105,108,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,83,117,99,99,101,101,100,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,73,103,110,111,114,101,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47,100,105,109, +101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67, +73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_58 = 7474; +static unsigned char xml_res_file_58[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,83,121,110,111,110,121,109,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,67, +111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,97,114,103,101,116,84,121,112,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,84,97,114,103,101,116,32,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,84,97,114,103,101,116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,84,97,114,103,101,116,83,99,104,101,109,97,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,84,97,114,103,101,116,32,115,99,104,101,109,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,84,97,114,103,101,116,83,99,104,101,109,97,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,97,114,103,101,116,79,98,106, +101,99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,114,103,101,116,32,111,98,106,101, +99,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,114,103,101,116,79,98,106,101,99,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_59 = 40708; +static unsigned char xml_res_file_59[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,34,62,10,32,32,32,32,60,116,105, +116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,53,48,44,50,54, +53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62, +119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124, +119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78, +85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121, +108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60, +47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101, +61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,51,52,54,44,50,52,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100, +62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +68,101,102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,115, +112,97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,79,102,84,121,112,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,102,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,102,84,121, +112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,105,108,108,70,97,99,116,111,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,105,108,108,32,70,97,99,116,111,114,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,108,70,97,99,116,111,114,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,97,115, +79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,97,115,32,79,73,68,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,72,97,115,79,105,100,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101, +99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,85,110,108,111,103,103,101,100,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,108,111,103,103,101,100,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110,108, +111,103,103,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48, +60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +73,110,104,101,114,105,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,73, +110,104,101,114,105,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115, +116,66,111,120,34,32,110,97,109,101,61,34,108,98,84,97,98,108,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,97,98,108, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100, +100,84,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,84,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,76,105,107,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,76,105,107,101,82,101,108,97,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82, +101,108,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,76,105,107,101,82,101, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,99,108,117,100,105,110,103,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110, +99,108,117,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,68,101,102,97,117,108,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,32,118,97,108,117,101,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117, +100,105,110,103,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,99,108, +117,100,105,110,103,73,110,100,101,120,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,100,101,120,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,73,110,99,108,117,100,105,110,103, +83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99, +107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,73,110,99,108,117,100,105,110,103,67,111,109,109,101,110,116,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,111,109,109,101,110,116,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108,115,116, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,67,104,97,110,103,101,67,111,108,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +65,100,100,67,111,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +111,110,115,116,114,97,105,110,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61,34,108, +115,116,67,111,110,115,116,114,97,105,110,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50, +55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76, +67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69, +76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79, +87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98, +111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111,110,115,116,114, +84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,110,115,116,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,82,101,109,111,118,101,67,111,110,115,116,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,117,116,111,45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101, +108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,117,115,116,111,109,32,97,117,116,111,45,118,97,99,117, +117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,69,110,97,98, +108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,99,69,110,97,98,108,101,100,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114,114,101, +110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,98,97, +115,101,32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +66,97,115,101,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117, +114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,65,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,32,98,97,115,101, +32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,65,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,66,97,115,101,65,110,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,86,97,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97, +99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,86,97,99, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,65,110,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,78,65,76,89,90,69,32,115,99,97,108,101,32,102,97,99, +116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,65,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,97,99,116,111,114,65,110,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97,121,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99, +68,101,108,97,121,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,99,76,105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85, +85,77,32,99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,76,105,109,105,116, +67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101, +122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69, +69,90,69,32,109,105,110,105,109,117,109,32,97,103,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,114,101, +101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97, +98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69, +32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,32,110,97,109,101,61,34,110, +98,112,84,111,97,115,116,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116, +32,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,117,115,116, +111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +117,115,116,111,109,32,97,117,116,111,45,118,97,99,117,117,109,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,69,110,97,98,108,101, +100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67, +85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,66,97,115,101,84,111,97,115,116,86,97,99,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,66,97,115,101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,70,97,99,116,111,114,84,111,97,115,116,86, +97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108, +101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,97,99,116, +111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114, +84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32,100,101,108,97, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,68,101,108,97,121, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76, +105,109,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99, +111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97, +115,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86, +97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117, +109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,84,111,97,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77,97, +120,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,109, +97,120,105,109,117,109,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122, +101,77,97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90, +69,32,116,97,98,108,101,32,97,103,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34, +116,120,116,84,111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65, +103,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101, +101,122,101,84,97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65, +78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97, +116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106, +101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_60 = 10511; +static unsigned char xml_res_file_60[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32, +32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62, +51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101, +108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101, +114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111, +112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,51,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +53,44,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,51,55,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111, +109,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,53,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,53,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,76,111,99,97,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,99,97,116,105,111,110,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,76,111,99,97,116,105,111, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86,69,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,86,97,114,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,97,114,105,97,98,108,101,32,78,97,109,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,86,97,114,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80, +68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98, +108,101,32,86,97,108,117,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,97,108,117,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79, +75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117, +110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_61 = 12794; +static unsigned char xml_res_file_61[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,67,111,110,102, +105,103,117,114,97,116,105,111,110,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,80,97,114,115,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +97,114,115,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,80,97,114,115,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,112,121,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,67,111,112,121,32,67,111,110,102,105,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,111,112,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,84,111,107,101,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,84,111,107,101,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82,84, +124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111,110, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +111,107,101,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,84,111,107,101,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,105,99,116,105,111,110,97,114,121,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,105,99,116,105,111,110,97,114,105,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,68,105,99,116,105,111,110,97,114,121,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,49,49,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,111,105,99,101,34,32,110,97,109,101,61,34,99,98,68,105,99,116,105, +111,110,97,114,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,53,54,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69, +77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102, +97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117, +115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117, +115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10, +60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_62 = 11304; +static unsigned char xml_res_file_62[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,68,105,99,116, +105,111,110,97,114,121,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62, +10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115, +105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70, +65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80, +84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82, +69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101, +114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47, +115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82, +69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109, +101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101, +108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105, +111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,101,109,112,108,97,116,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,84,101,109,112,108,97,116,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,55,48,44,49,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,112,116,105,111,110,62,56,48,60,47,111,112,116,105,111, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65,78,68,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,112,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +79,112,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,66,79,84,84,79,77,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,72,79,82,73,90,79,78,84,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,82,69,77,79,86, +69,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,51,44,53,56,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,55,56,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114, +34,32,110,97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114, +101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_63 = 10694; +static unsigned char xml_res_file_63[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,80,97,114,115, +101,114,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32, +60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62, +10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95, +68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124, +119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69, +95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,83,116,97,114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,97,114,116,32, +70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,116,97,114,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +71,101,116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,71,101,116,116,111,107, +101,110,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,71,101, +116,84,111,107,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,100,32,70, +117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,100,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,101,120,116,121,112, +101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,76,101,120,116,121,112,101,115,32,70,117, +110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,116,121,112,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +72,101,97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,108,105, +110,101,32,70,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,72,101, +97,100,108,105,110,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_64 = 8482; +static unsigned char xml_res_file_64[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,101,120,116,83,101,97,114,99,104,84,101,109,112, +108,97,116,101,34,62,10,32,32,32,32,60,116,105,116,108,101,47,62,10,32, +32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85, +76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73, +79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83, +73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111, +119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111, +116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101, +98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108, +101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,99,104,101,109,97,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,99,104,101,109,97, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76, +84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,105,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,73,110,105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,76,101,120,105,122,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76, +101,120,105,122,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,76,101,120,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119, +120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,50,44,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,55,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,50,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101, +62,10}; + +static size_t xml_res_size_65 = 16584; +static unsigned char xml_res_file_65[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,114,105,103,103,101,114,34,62,10,32,32,32,32,60, +116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48, +44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97, +109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101, +99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105, +101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104, +103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +50,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,79,73,68,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,109,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69, +95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101, +32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,56,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,111,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,111,119,32,116,114, +105,103,103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,111,119,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,110,115,116,114,97,105,110,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,110,115,116,114,97,105,110,116,32,116,114,105,103, +103,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,67,111,110,115,116,114,97,105,110,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107, +101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,97,98, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,68,101,102,101,114,114,97,98,108,101,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,102,101,114,114,97,98,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,68,101,102,101,114,114,101,100,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,68,101,102,101,114,114,101,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,101,102,101,114,114,101,100,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,114,105,103,103,101,114,32,102,117,110,99,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,70,117,110,99,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,65,114,103,117,109,101, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,114,103,117,109,101,110,116,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,65,114,103,117,109,101,110,116,115,34,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,70,105,114,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,114,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,100,98,70,105,114,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,66,69,70,79,82,69,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,65,70,84,69,82,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,73,78,83,84,69,65,68,32,79,70,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +82,65,95,83,80,69,67,73,70,89,95,82,79,87,83,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,69,118,101,110,116,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,69,118,101,110,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,78,83,69,82,84,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,112, +100,97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,80,68,65,84,69,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,68,101,108,101,116,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,69,76,69,84,69,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,84,114,117,110,99, +97,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,82,85,78,67,65,84,69,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,87,104,101,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,104,101,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,87,104,101,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,45,49,44,52,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,67,111,108,117,109,110,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119, +115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114,108,34, +32,110,97,109,101,61,34,108,115,116,67,111,108,117,109,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95, +83,73,78,71,76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,67,111,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,100,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,67,111,108,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,53,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,66,111,100,121,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34,116,120,116, +66,111,100,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85,76,84,73,76, +73,78,69,124,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,124,119,120, +84,69,95,82,73,67,72,50,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105, +111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_66 = 43189; +static unsigned char xml_res_file_66[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,84,121,112,101,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,52,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34, +32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +79,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119, +110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,82,97,100,105,111,66,111,120,34,32,110,97,109,101,61,34,114, +100,98,84,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,67,111,109,112,111,115,105,116,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,69,110,117,109,101,114,97,116,105,111,110,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,69,120,116,101,114,110,97,108,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,82,97,110,103,101,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62,49,60,47, +100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,65,95, +83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,44,49,44,50, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,68,101,102,105,110,105,116,105,111,110,67,111, +109,112,111,115,105,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116, +67,116,114,108,34,32,110,97,109,101,61,34,108,115,116,77,101,109,98,101, +114,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69, +80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,77,101,109,98,101,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101,109,98,101,114,32, +110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,77,101,109,98,101,114,110,97,109,101,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,97,116,97,116,121,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,97,116,97,32,116,121,112,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110, +97,109,101,61,34,99,98,68,97,116,97,116,121,112,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,76,101,110,103,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,76,101,110,103,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,80,114,101,99,105,115,105,111,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,80,114,101,99,105,115,105,111,110,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,80,114,101,99,105,115,105,111,110, +34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,111, +108,108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,98,116,110,82,101,109,111,118,101,77,101,109,98,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109,111,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65, +76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,65,100,100,77,101,109, +98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,65,76, +73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,50,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,97,110,103,101, +77,101,109,98,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,68,101,102,105,110,105,116,105,111,110,69,110,117,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47, +103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,76,97,98,101,108,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,48,48,44, +49,53,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71, +76,69,95,83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,76,97,98, +101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,97,98,101, +108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,76,97, +98,101,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97, +99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +98,116,110,65,100,100,66,101,102,111,114,101,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,98,101,102,111, +114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,65,100,100,65,102,116,101,114,76,97,98,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100,32,97,102,116,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110, +82,101,109,111,118,101,76,97,98,101,108,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78, +111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,68,101,102, +105,110,105,116,105,111,110,69,120,116,101,114,110,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,82,101,113,117,105,114,101,100,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,73,110,112,117,116,32,102,117,110,99,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,73,110,112,117,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79, +78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,79,117,116,112,117,116,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117,116, +112,117,116,32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,79,117,116, +112,117,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,79,112,116,105,111,110,97,108,32,49,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,82,101,99,101,105,118,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,99,101,105,118,101, +32,102,117,110,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,101,99,101,105, +118,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,101,110,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,83,101,110,100,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,83,101,110,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,105,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84, +121,112,109,111,100,32,105,110,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,105,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,84,121,112,109,111,100,111,117,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121, +112,109,111,100,32,111,117,116,32,102,117,110,99,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +84,121,112,109,111,100,111,117,116,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,73,110,116,76,101,110,103,116,104, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73, +110,116,101,114,110,97,108,32,108,101,110,103,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,73,110,116,76,101,110,103,116,104,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,86,97,114,105,97,98,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,86,97,114,105,97,98,108,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,68,101,102,97,117,108,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101, +102,97,117,108,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,102,97,117,108,116,34, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,110,97,108,121,122,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,110, +97,108,121,122,101,32,102,117,110,99,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,110,97,108,121, +122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,116,101,103,111,114, +121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,97,116,101,103,111,114,121,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,114,114,97,121,32, +116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,105,116,101,109,62,66,111,111,108,101,97,110,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,67,111,109,112,111,115,105,116,101, +32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,68,97,116,101,47,116,105,109, +101,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,69,110,117,109,32,116,121, +112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,105,116,101,109,62,71,101,111,109,101,116,114,105,99,32,116, +121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,78,101,116,119,111,114,107,32,97,100, +100,114,101,115,115,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,117, +109,101,114,105,99,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,80,115,101, +117,100,111,45,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,116,114,105,110, +103,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,84,105,109,101,115,112,97, +110,32,116,121,112,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,85,115,101,114,45,100,101, +102,105,110,101,100,32,116,121,112,101,115,60,47,105,116,101,109,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,66,105, +116,45,115,116,114,105,110,103,32,116,121,112,101,115,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +117,110,107,110,111,119,110,32,116,121,112,101,115,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,80,114,101,102,101,114,101,100,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,102,101,114,101,100,63, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,80,114,101,102,101,114,101,100,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116, +105,111,110,97,108,32,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,108,101,109,101,110,116,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,108, +101,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,108,105, +109,105,116,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,68,101,108,105,109,105,116,101, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,108,105,103,110,109,101,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +65,108,105,103,110,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,65,108,105,103,110, +109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,99,104,97,114,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,105,110,116,50,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,105,110,116,52,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,100,111,117,98,108,101,60, +47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111, +110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,111,114,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,83,116,111,114,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62,48,60,47, +115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89, +124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,80,97,115,115,101,100,66,121,86,97,108, +117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,97,115,115,101,100,32,98,121,32,118,97,108,117,101,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101, +61,34,99,104,107,66,121,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,67,111,108,108,97,116,97,98,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,111,108,108,97,116,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108, +108,97,116,97,98,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101,102,105,110,105, +116,105,111,110,82,97,110,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,117,98,116,121,112,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66, +111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116,121,112,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117,98,116,121,112, +101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +117,98,116,121,112,101,32,111,112,101,114,97,116,111,114,32,99,108,97,115, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98,116, +121,112,101,79,112,99,108,97,115,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101, +110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,82,110,103,67,111,108,108,97,116,105,111,110,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,111,108,108,97,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,110,103,67,111,108, +108,97,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,97,110,111,110,105,99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,97,110,111,110,105,99,97,108,32,102,117,110,99,116,105,111,110,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,97,110,111,110,105, +99,97,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,117, +98,116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +83,117,98,116,121,112,101,32,100,105,102,102,32,102,117,110,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,83,117,98, +116,121,112,101,68,105,102,102,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68, +79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,48,44,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101, +61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69, +71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_67 = 15725; +static unsigned char xml_res_file_67[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34, +110,98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,50,57,54,44,50,52,48,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,80,114,111,112,101,114,116,105,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,80,114,111,112,101,114,116,105,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,54,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115, +101,114,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,97,109,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,73,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,73,68, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,73,68,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,97,115, +115,119,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,80,97,115,115,119,111,114,100,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,97,115,115,119,111,114,100,32,40,97,103,97,105,110,41,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,82,101,80,97,115,115,119,100,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,108,105,100,85,110,116,105,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,65,99,99,111,117,110,116,32,101,120,112,105,114,101,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,97,108,101,110,100,97,114,66,111,120,34,32,110,97,109,101,61,34,100, +97,116,86,97,108,105,100,85,110,116,105,108,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,68,80,95,65,76,76,79,87,78,79,78,69,124,119,120,68,80,95, +68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,84,105,109,101,83,112,105,110,67,116,114,108,34,32,110,97, +109,101,61,34,116,105,109,86,97,108,105,100,85,110,116,105,108,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111, +109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,67,108,117,115,116, +101,114,83,101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,82,111,108,101,32,112,114,105,118,105,108,101,103,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,82,111,108,101,115,80,114,105,118,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,114,101,97,116,101,68,66,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,114,32,99,97, +110,32,99,114,101,97,116,101,32,100,97,116,97,98,97,115,101,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,114,101,97,116,101,85,115,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,83,117,112,101,114,117,115,101,114,32,40,99,97,110,32,99,114,101, +97,116,101,32,117,115,101,114,115,41,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,54,54,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,71,114,111,117,112,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,71,114,111,117,112,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,71,114, +111,117,112,115,78,111,116,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,32,77, +101,109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,101, +109,98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,66,111,120, +34,32,110,97,109,101,61,34,108,98,71,114,111,117,112,115,78,111,116,73, +110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,56,54,44,49,50,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,66,95,78,69,69,68,69, +68,95,83,66,124,119,120,76,66,95,83,79,82,84,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,65,76, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,65,100,100,71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,103, +116,59,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +49,56,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,66,79,84,84,79,77,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,68,101,108, +71,114,111,117,112,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,108,116,59,38,108, +116,59,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,56,44,45,49, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,84,79,80,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108, +98,71,114,111,117,112,115,73,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,56,54,44,49,50,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,76,66,95,78,69,69,68,69,68,95,83,66,124,119,120,76,66,95,83,79, +82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,86,97,114,105,97,98,108,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97, +98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,76,105,115,116,67,116,114,108,34,32,110,97,109,101,61, +34,108,115,116,86,97,114,105,97,98,108,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,53,44,54, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,76,67,95,82,69,80,79,82, +84,124,119,120,76,67,95,83,73,78,71,76,69,95,83,69,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120,71,82,79, +87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,48,44,48,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,65,68, +68,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,65,100,100,47,67,104,97,110,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,48,44,49,51,50,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,101,109,111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,53,48,44,49,51,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,114,110, +97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,114,105,97,98,108,101, +32,78,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111, +66,111,120,34,32,110,97,109,101,61,34,99,98,86,97,114,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,86,97,114,105,97,98,108,101,32,86,97,108,117,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,44,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,86, +97,108,117,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61, +34,99,104,107,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_68 = 8224; +static unsigned char xml_res_file_68[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,85,115,101,114,77,97,112,112,105,110,103,34,62,10, +32,32,32,32,60,116,105,116,108,101,47,62,10,32,32,32,32,60,115,105,122, +101,62,51,48,48,44,50,54,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79, +71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89, +83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115, +62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111, +107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,57,54,44,50, +52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60, +115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101,99,116,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,111, +112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,114, +111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,85,115,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,85,115,101,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,85,115,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83,101,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97, +109,101,61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116, +101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,79,112,116,105,111,110,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,76,105,115,116,67,116,114, +108,34,32,110,97,109,101,61,34,108,115,116,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,55,48,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,76,67,95,82,69,80,79,82,84,124,119,120,76,67,95,83,73,78,71,76,69,95, +83,69,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116,105,111,110,62,56, +48,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +69,88,80,65,78,68,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,79,112,116,105,111,110,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,51,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,97,108,117,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,97,108, +117,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73, +67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,86,97,108,117,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,51,53,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +76,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,66,79,84, +84,79,77,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,72,79,82,73, +90,79,78,84,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,82,69,77,79,86,69,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,109, +111,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,51,44,53, +56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,65,68,68,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,65,100,100, +47,67,104,97,110,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62, +49,51,44,55,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,65,76,73,71,78,95,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,50,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,76,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62,50,44,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,50,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112, +97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,71,82,79,87,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,117,115,66,97,114,34,32,110,97,109,101,61,34,117,110, +107,83,116,97,116,117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,60,115,116,121,108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60, +47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111, +98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_69 = 36643; +static unsigned char xml_res_file_69[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,100,108,103,86,105,101,119,34,62,10,32,32,32,32,60,116,105,116, +108,101,47,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,54,53, +100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119, +120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119, +120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124, +119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116, +101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98, +111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +50,57,54,44,50,52,48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,48,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +80,114,111,112,101,114,116,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,80,114,111,112,101,114,116,105,101,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,52,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,78,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,78,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,79,73,68,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,73,68,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,79,73,68,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,79,119,110,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,99,116,108,67,111,109,98,111,66,111,120, +34,32,110,97,109,101,61,34,99,98,79,119,110,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47, +115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,99,104,101, +109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,83,99,104,101,109,97,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62, +119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79, +80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,109,109,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,67,111,109,109,101,110,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,67,108,117,115,116,101,114,83, +101,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,83,108,111,110,121,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,67,108,117,115,116,101,114,83,101,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110, +116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124, +119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,101,102, +105,110,105,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,101, +102,105,110,105,116,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,50,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,101,99, +117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101, +99,117,114,105,116,121,32,66,97,114,114,105,101,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,101,99,117,114,105,116,121,66,97,114,114,105,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,87,105,116,104,32,67,104,101,99,107,32,79,112,116, +105,111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,67,104,101,99,107,79,112,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,76,111,99,97,108,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,97,115,99,97,100,101,100,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,68,101,102,105,110,105,116,105,111,110, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,101,102,105,110,105,116,105,111,110,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,99,116,108,83,81,76,66,111,120,34,32,110,97,109,101,61,34, +116,120,116,83,113,108,66,111,120,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95, +77,85,76,84,73,76,73,78,69,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,112,116, +105,111,110,62,49,60,47,111,112,116,105,111,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,71,82, +79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,97,116,101,114,105,97,108,105,122,97,116,105,111,110, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,97,116,101,114,105,97,108,105, +122,101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111, +119,115,62,49,60,47,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,77,97,116,101,114,105,97,108,105,122, +101,100,86,105,101,119,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,116,101, +114,105,97,108,105,122,101,100,32,86,105,101,119,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +77,97,116,101,114,105,97,108,105,122,101,100,86,105,101,119,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,48,60,47,99, +104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,50,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,49,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109, +101,61,34,110,98,86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +48,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,114,111,119,115,62,51,60,47, +114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,97,98,108,101,83,112, +97,99,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,97,98,108, +101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +111,84,97,98,108,101,115,112,97,99,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82, +79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,105,108, +108,70,97,99,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,70,105,108,108,32,70,97,99,116,111,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,70,105,108,108,70,97,99,116,111, +114,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,77,97,116,86,105,101,119,87,105,116, +104,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87, +105,116,104,32,68,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,77,97,116,86,105,101,119,87,105,116,104,68,97,116, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,84,97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115, +62,51,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52,60,47,118, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44, +51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,67,117,115,116,111,109,86,97,99,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117, +116,111,45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47, +115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,86,97,99,69,110,97,98,108,101,100, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117, +114,114,101,110,116,32,118,97,108,117,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,86,97,99,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,98,97,115, +101,32,116,104,114,101,115,104,111,108,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,66,97,115,101,86,97,99,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,66,97,115,101,86,97,99,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,66,97,115,101,65,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,65,78,65,76,89,90,69,32,98,97,115,101,32,116,104,114,101,115,104, +111,108,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,66,97,115,101,65,110,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,65,110, +67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,97,99,116,111,114,86,97,99,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,115, +99,97,108,101,32,102,97,99,116,111,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,70,97,99,116,111,114,86,97,99,34,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,97,99,116,111,114,86,97,99,67,117,114,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,97,99,116,111,114,65,110,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,65,78,65,76,89,90,69,32,115,99,97,108,101,32,102,97,99, +116,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,97,99,116,111,114,65,110,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99, +116,111,114,65,110,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86,97,99,68,101,108, +97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85, +77,32,99,111,115,116,32,100,101,108,97,121,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108, +34,32,110,97,109,101,61,34,116,120,116,86,97,99,68,101,108,97,121,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,86,97,99,76,105,109,105,116,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116,32, +108,105,109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,86,97,99,76,105,109,105,116,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,86, +97,99,76,105,109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114,101, +101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109,32,97,103,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,114,101, +101,122,101,77,105,110,65,103,101,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,114, +101,101,122,101,77,105,110,65,103,101,67,117,114,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117,109, +32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,77,97,120,65,103,101,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,114,101,101,122,101,77,97,120,65,103,101,67,117,114,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34, +115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108, +101,32,97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,67,117,114, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107, +112,97,103,101,34,32,110,97,109,101,61,34,110,98,112,84,111,97,115,116, +86,97,99,117,117,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,111,97,115,116,32,116, +97,98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +67,117,115,116,111,109,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,67,117,115,116,111,109,32,97,117,116,111, +45,118,97,99,117,117,109,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,51,44,51,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115, +116,86,97,99,69,110,97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,69,110,97,98,108,101,100,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,84,111,97,115,116,86,97,99,69,110, +97,98,108,101,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,117,114,114,101,110,116,32,118,97,108,117,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115,101,84,111, +97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,98,97,115,101,32,116,104,114,101,115,104,111,108,100, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,66,97,115, +101,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,97,115, +101,84,111,97,115,116,86,97,99,67,117,114,114,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,97,99, +116,111,114,84,111,97,115,116,86,97,99,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,65,67,85,85,77,32,115,99,97,108,101,32,102,97,99,116, +111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +97,99,116,111,114,84,111,97,115,116,86,97,99,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,97,99,116,111,114,84,111,97,115,116,86,97,99,67,117,114,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32,99,111,115,116, +32,100,101,108,97,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,111,97,115,116,86,97,99,68,101,108,97,121,34,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,84,111,97,115,116,86,97,99,68,101,108,97,121,67,117,114,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105,109,105,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,65,67,85,85,77,32, +99,111,115,116,32,108,105,109,105,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32, +110,97,109,101,61,34,116,120,116,84,111,97,115,116,86,97,99,76,105,109, +105,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,86,97,99,76,105, +109,105,116,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,105,110,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,105,110,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,105,110,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +105,110,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,77,97,120,65,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,70,82,69,69,90,69,32,109,97,120,105,109,117,109,32, +97,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120, +116,84,111,97,115,116,70,114,101,101,122,101,77,97,120,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,77, +97,120,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,111,97,115,116,70, +114,101,101,122,101,84,97,98,108,101,65,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,82,69,69,90,69,32,116,97,98,108,101,32,97, +103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,84, +111,97,115,116,70,114,101,101,122,101,84,97,98,108,101,65,103,101,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,60,47, +102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,111,97,115,116,70,114,101,101,122,101,84, +97,98,108,101,65,103,101,67,117,114,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,124,119,120,65,76,73,71,78,95,67,69,78,84,82, +69,95,86,69,82,84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82, +84,73,67,65,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,76,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +117,115,66,97,114,34,32,110,97,109,101,61,34,117,110,107,83,116,97,116, +117,115,66,97,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,83,84,95,83,73,90,69,71,82,73,80,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101, +62,10}; + +static size_t xml_res_size_70 = 18754; +static unsigned char xml_res_file_70[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,66,97,99,107,117,112,60,47,116,105,116,108,101,62,10, +32,32,32,32,60,115,105,122,101,62,51,48,48,44,50,51,51,100,60,47,115,105, +122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65, +85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84, +73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69, +83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114, +111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,56,53,44,50,50,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79,112, +116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97,109,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108,101, +110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114, +109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61, +34,99,98,70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68, +82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,67,111,109,112,114,101,115,115,32,82,97,116,105,111,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,109,112,114,101,115,115,82,97,116,105,111,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,69,110,99,111,100,105,110,103,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +69,110,99,111,100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,117,109,98,101,114,79,102,74,111,98,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,117,109,98,101,114,32,79,102,32,74,111,98,115,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,117,109,98,101,114,79,102,74,111,98,115,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97, +109,101,61,34,115,116,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,108,101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78, +124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111,110,115, +32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110, +101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112,79,112,116, +105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47, +118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,83,101,99,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119, +97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76, +60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,101,99,116,105,111,110,80,114,101,68,97,116, +97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100,97,116,97,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110, +80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,111,115, +116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101,32,79,102,32, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62, +119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32,100,97,116, +97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110,108,121, +83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,66,108,111,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,66,108,111,98,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,68,111,110,39,116,32,115,97,118,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60, +47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60, +47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,78,111,79,119,110,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,79,119,110,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,78,111,80,114,105,118,105,108,101,103,101,115,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,80,114,105,118,105,108,101,103,101,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,78,111,84,97,98,108,101,115,112,97,99,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,84,97,98,108,101,115,112,97,99,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,85,110,108, +111,103,103,101,100,84,97,98,108,101,68,97,116,97,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,85,110,108,111,103,103,101,100,32,116,97,98,108,101,32,100,97, +116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,68,117,109,112,32,79,112,116,105,111, +110,115,32,35,50,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68,117,109,112, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111, +120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,101,114,105,101,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97, +112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,67,114,101,97,116,101,68,98,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,67,82,69,65,84, +69,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,114,111,112,68, +98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117,100,101,32,68,82, +79,80,32,68,65,84,65,66,65,83,69,32,115,116,97,116,101,109,101,110,116, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108,117, +109,110,73,110,115,101,114,116,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,67,111,108,117,109,110,32,73,110,115,101,114,116,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,115,101,114,116,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,85,115,101,32,73,110,115,101,114,116,32,99, +111,109,109,97,110,100,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97,98,108, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84, +73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,68,105,115, +97,98,108,101,68,111,108,108,97,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68, +111,108,108,97,114,32,113,117,111,116,105,110,103,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +77,105,115,99,101,108,108,97,110,111,117,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114, +105,101,110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,85,115,101,83,101,116,83,101,115,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,32,83,69,84,32,83,69,83,83,73,79,78,32,65,85,84, +72,79,82,73,90,65,84,73,79,78,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,105, +116,104,32,79,73,68,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111,116,101,70,111, +114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97,109, +101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72,65, +83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82,68, +69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78,76,89,124,119, +120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108, +112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44, +48,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111,117, +114,99,101,62,10}; + +static size_t xml_res_size_71 = 3997; +static unsigned char xml_res_file_71[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,71,108,111,98,97,108,115,34, +62,10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,71, +108,111,98,97,108,115,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98, +111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53, +100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,112,111,115,62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,49,55,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87, +78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116, +101,58,32,79,110,108,121,32,111,98,106,101,99,116,115,32,103,108,111,98, +97,108,32,116,111,32,116,104,101,32,101,110,116,105,114,101,32,100,97,116, +97,98,97,115,101,32,99,108,117,115,116,101,114,32,119,105,108,108,32,98, +101,32,98,97,99,107,101,100,92,110,117,112,46,32,84,104,101,32,98,97,99, +107,117,112,32,102,111,114,109,97,116,32,119,105,108,108,32,98,101,32,80, +76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101,81,117,111, +116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99,101,32,100, +111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32,105,100,101, +110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50, +48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,86,101,114,98,111, +115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,86,101,114,98,111,115,101,32,109,101,115,115,97,103,101, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,49,52,52,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47,115,101,108,101, +99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,52,53,44,49,55,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,66,97,99,107,117,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116, +62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84, +79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78, +67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80, +65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60, +103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119, +97,98,108,101,114,111,119,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115,111, +117,114,99,101,62,10}; + +static size_t xml_res_size_72 = 3924; +static unsigned char xml_res_file_72[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,66,97,99,107,117,112,83,101,114,118,101,114,34,62, +10,32,32,32,32,60,116,105,116,108,101,62,66,97,99,107,117,112,32,83,101, +114,118,101,114,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,49,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83, +89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82, +68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110,98,78, +111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,112,111,115,62,56,44,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,53,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,50,50,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108,101, +110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,56,44,50,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,82,111, +108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,54,53,44,50,53,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49,55, +48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65, +68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120, +67,66,95,83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,116,120,116,78,111,116,101,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,111,116,101,58,32,84,104, +101,32,98,97,99,107,117,112,32,102,111,114,109,97,116,32,119,105,108,108, +32,98,101,32,80,76,65,73,78,46,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,56,44,52,55,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,111,114,99,101, +81,117,111,116,101,70,111,114,73,100,101,110,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,111,114,99, +101,32,100,111,117,98,108,101,32,113,117,111,116,101,115,32,111,110,32, +105,100,101,110,116,105,102,105,101,114,115,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,49, +48,44,49,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,86,101,114,98,111,115,101,32,109,101, +115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47, +99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,49,52,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62, +49,60,47,115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,115,105,122,101,62,50,52,53,44,49,55,52,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,77,101,115,115,97,103,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,77,101,115,115,97,103,101, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95, +82,69,65,68,79,78,76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,67,69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115, +62,50,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79, +77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,66,97,99,107,117,112,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49, +51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79, +80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119, +120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108, +101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_73 = 3765; +static unsigned char xml_res_file_73[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,69,120,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,69,120,112,111,114,116,32,100,97,116,97,32,116,111,32, +102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105, +122,101,62,50,53,51,44,49,52,51,100,60,47,115,105,122,101,62,10,32,32,32, +32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76, +79,71,95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,114,98,82,111,119,83,101,112, +97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +82,111,119,32,115,101,112,97,114,97,116,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,53,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,50,48,44,51,56,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114, +98,76,70,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,70,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60, +47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44, +49,55,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,67,82,76,70,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,82,47,76,70,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,50,57,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111, +108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,60,108, +97,98,101,108,62,67,111,108,117,109,110,32,115,101,112,97,114,97,116,111, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53, +44,53,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +67,111,108,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,44,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60, +47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101, +99,116,105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10, +32,32,32,32,32,32,60,112,111,115,62,49,48,48,44,53,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60, +47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,67,104,97,114, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32, +99,104,97,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,55,48,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101, +61,34,99,98,81,117,111,116,101,67,104,97,114,34,62,10,32,32,32,32,32,32, +60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,34,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,60,105, +116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32,60,47,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,60,115,101,108,101,99,116, +105,111,110,62,48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32, +32,32,32,32,60,112,111,115,62,49,48,48,44,54,56,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,105,122,101,62,50,53,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,67,111,108,110,97,109,101,115,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108,117,109,110,32, +110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,67,111,108,110,97,109,101,115,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,60,112,111,115,62,49,48,48,44,56,51,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,50,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,69,110,99,111,100,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111, +100,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,49,51,48,44,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,51,56,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,76,111,99,97,108,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,99,97,108,32,99,104, +97,114,115,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,52,48,44,49,55,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82, +97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98, +85,110,105,99,111,100,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,85,110,105,99,111,100,101,32,85,84,70,45,56,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,48,44,50,57,100,60,47,112, +111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,34,32,110,97,109,101,61,34,115,98,81,117,111,116,105, +110,103,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116, +105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,49,51,48,44,52,56,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,49,50,48,44,53,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,81,117,111,116,101,78, +111,110,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,110,111, +32,113,117,111,116,105,110,103,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,52,48,44,54,48,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +114,98,81,117,111,116,101,83,116,114,105,110,103,115,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,111,110,108,121,32,115,116,114,105,110, +103,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,118,97,108,117, +101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,52,48,44,55,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,114,98,81,117,111,116,101,65,108,108,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,97,108,108,32,99,111,108,117,109,110, +115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49, +52,48,44,56,52,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,49,48,55,100,60, +47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70,105,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,48, +44,49,48,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122, +101,62,49,51,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,51,53,44,49,48,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44,45,49,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69, +76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,116,121,108,101,47,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +88,108,115,67,111,112,121,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,88,108,115,32,102,109,116,32,99,111,112,121,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104, +101,99,107,101,100,62,10,32,32,32,32,32,32,60,112,111,115,62,53,53,44,49, +50,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101, +62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,55,44,49,50,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102,97,117,108, +116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,48,48,44,49,50,53,100,60,47,112,111,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_74 = 1443; +static unsigned char xml_res_file_74[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,71,114,97,110,116,87,105,122,97,114,100,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,71,114,97,110,116,32,87,105,122,97, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,48,48,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83, +84,69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101, +98,111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111, +111,107,34,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,108,101,99,116,105, +111,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34, +32,110,97,109,101,61,34,112,110,108,83,101,108,101,99,116,105,111,110,34, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34, +32,110,97,109,101,61,34,99,104,107,76,105,115,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,51,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,49, +56,51,44,50,51,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,98,116,110,67,104,107,65,108,108, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67, +104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,52,48,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62, +53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116, +111,110,34,32,110,97,109,101,61,34,98,116,110,85,110,99,104,107,65,108, +108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +85,110,99,104,101,99,107,32,97,108,108,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,52,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,53,48,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,115,101,108, +101,99,116,101,100,62,49,60,47,115,101,108,101,99,116,101,100,62,10,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,112, +111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,57,53,44,50,55,54,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,72,101,108,112,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,44,50,56,53, +100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,57,51,44,50,56,53,100,60,47,112,111,115,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52, +54,44,50,56,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101, +115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_75 = 3111; +static unsigned char xml_res_file_75[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,72,105,110,116,34,62,10,32,32,32,32,60,116,105,116, +108,101,62,112,103,65,100,109,105,110,32,71,117,114,117,32,72,105,110,116, +60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62,50,48, +48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115,116,121, +108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89, +76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95, +77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115, +116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,72,116,109, +108,87,105,110,100,111,119,34,32,110,97,109,101,61,34,104,116,109,108,72, +105,110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,83,85,78,75,69,78,95,66,79,82,68,69,82,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,76,124,119,120, +71,82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,60,109,105,110,115,105,122,101,62,51,48,48,44,50,48,48,100,60, +47,109,105,110,115,105,122,101,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117, +112,112,114,101,115,115,34,62,10,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,68,111,32,110,111,116,32,115,104,111,119,32,116,104,105,115, +32,104,105,110,116,32,97,103,97,105,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,76,60,47,102,108,97,103,62,10, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,55,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,98,116,110,70,105,120,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,70,105,120,32,105,116,33,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100, +101,102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,89,69,83,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,89,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97, +117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111, +115,62,57,51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79, +84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,119,120,73,68,95,78,79,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,78, +111,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51, +44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57,51,44,49,51,53,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120, +73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +112,111,115,62,49,52,54,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,84,79,80,124,119,120, +66,79,84,84,79,77,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,124, +119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,124,119,120,65,76,73, +71,78,95,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71, +82,79,87,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62, +48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_76 = 12319; +static unsigned char xml_res_file_76[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,73,109,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,73,109,112,111,114,116,32,100,97,116,97,32,102,114,111, +109,32,102,105,108,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115, +105,122,101,62,51,48,48,44,49,51,51,100,60,47,115,105,122,101,62,10,32, +32,32,32,60,115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73, +65,76,79,71,95,83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119, +120,83,89,83,84,69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66, +79,82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98, +111,111,107,34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111, +107,34,62,10,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,50,44,50,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,50,56,53,44,49,50,52,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95,66,79,84,84,79, +77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,70,105,108,101,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,70,105,108,101,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,70,105,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108, +101,110,97,109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,73,109,112,111,114,116,102,105,108,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101,62, +83,101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,105, +109,112,111,114,116,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95, +84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,119,105,108,100,99,97,114, +100,62,42,46,99,115,118,59,42,46,42,59,42,60,47,119,105,108,100,99,97,114, +100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +116,111,111,108,116,105,112,62,69,110,116,101,114,32,97,32,102,105,108, +101,110,97,109,101,32,116,111,32,105,109,112,111,114,116,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,111,114,109, +97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,70,111,114,109,97,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98, +70,111,114,109,97,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,116, +101,120,116,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,99,115,118,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,98,105,110,97,114,121,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,105,111,110,62, +48,60,47,115,101,108,101,99,116,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120, +67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79, +87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +69,110,99,111,100,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,110,99,111,100,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34, +32,110,97,109,101,61,34,99,98,69,110,99,111,100,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78, +76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,124,119,120,67,66,95, +83,79,82,84,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,67,111,108,117,109,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,67, +111,108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111, +119,115,62,49,60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,67,111,108,117,109, +110,115,84,111,73,109,112,111,114,116,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,108, +117,109,110,115,32,116,111,32,105,109,112,111,114,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32,110,97,109, +101,61,34,108,115,116,67,111,108,117,109,110,115,84,111,73,109,112,111, +114,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101, +98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,77,105,115,99,46,32,79,112,116,105,111,110,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108, +34,32,110,97,109,101,61,34,112,110,108,77,105,115,99,79,112,116,105,111, +110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,73,68,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,79,105,100,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,72,101,97,100,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,97,100,101, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110, +97,109,101,61,34,99,104,107,72,101,97,100,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,68,101,108,105,109,105,116,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,68,101,108,105,109,105,116,101,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,68,101,108, +105,109,105,116,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +59,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,44,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,91, +116,97,98,93,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110, +111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,81,117,111,116,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,111,116,101, +79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108, +101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,81,117,111,116,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,111,116,101,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,81,117,111,116,101,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,115,99,97,112,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,69,115,99,97,112,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,69,115,99, +97,112,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68,79,87, +78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111, +111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,85,76,76,32,79,112,116,105,111,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97, +109,101,61,34,112,110,108,78,117,108,108,79,112,116,105,111,110,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105, +122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62, +53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,78,117,108,108,83,116,114,105,110,103,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,78,85,76,76,32,115,116,114,105,110,103,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,78,117,108,108,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,103,110,111, +114,101,70,111,114,67,111,108,117,109,110,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,103, +110,111,114,101,32,102,111,114,32,99,111,108,117,109,110,115,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,67,104,101,99,107,76,105,115,116,66,111,120,34,32, +110,97,109,101,61,34,108,115,116,73,103,110,111,114,101,70,111,114,67,111, +108,117,109,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,65,76,76,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124, +119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,71,97,117,103,101, +34,32,110,97,109,101,61,34,103,97,117,103,101,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,101,108,112,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119, +120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,73,109,112,111,114,116,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,100,101, +102,97,117,108,116,62,49,60,47,100,101,102,97,117,108,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95, +67,65,78,67,69,76,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,38,97,109,112,59,67,97,110,99,101,108,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47, +111,98,106,101,99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_77 = 5924; +static unsigned char xml_res_file_77[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,77,97,105,110,116,101,110,97,110,99,101,34,62,10, +32,32,32,32,60,116,105,116,108,101,62,77,97,105,110,116,101,110,97,110, +99,101,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101,62, +50,48,48,44,49,53,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,124,119,120,82,69,83,73,90,69,95,66,79,82,68,69,82, +60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48, +60,47,103,114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,78,111,116,101,98,111,111,107, +34,32,110,97,109,101,61,34,110,98,78,111,116,101,98,111,111,107,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,78,66,95, +66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116, +101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,112,116,105,111,110,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49, +60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97, +112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97, +100,105,111,66,111,120,34,32,110,97,109,101,61,34,114,98,120,65,99,116, +105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,77,97,105,110,116,101,110,97,110,99,101, +32,111,112,101,114,97,116,105,111,110,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,86,65,67,85,85,77,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,105,116,101,109,62,65,78,65,76,89,90,69,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +105,116,101,109,62,82,69,73,78,68,69,88,60,47,105,116,101,109,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,67,76,85,83,84,69,82,60,47,105,116,101,109,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,115,101,108,101,99,116,105,111,110,62,48,60,47,115,101,108,101,99, +116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,82,65,95,83,80,69,67,73,70,89, +95,82,79,87,83,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +86,65,67,85,85,77,32,111,112,116,105,111,110,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +114,105,101,110,116,62,119,120,72,79,82,73,90,79,78,84,65,76,60,47,111, +114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,70,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,70, +85,76,76,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,70,114,101, +101,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,70,82,69,69,90,69,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,65,110,97,108,121,122,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,65,78,65,76,89,90,69,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,73,83,65,66,76,69,95,80,65, +71,69,95,83,75,73,80,80,73,78,71,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,73, +83,65,66,76,69,95,80,65,71,69,95,83,75,73,80,80,73,78,71,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,67,79,78,67,85,82,82,69,78,84, +76,89,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,67,79,78,67,85,82,82,69,78,84,76, +89,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109, +101,61,34,99,104,107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86, +101,114,98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,101,108,101,99,116,101,100,62,49,60,47, +115,101,108,101,99,116,101,100,62,10,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112, +97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61, +34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,77,85, +76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78,76,89,124,119, +120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120, +71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,60,99, +111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109, +112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,112,111,115,62,50,44,49,51,53,100,60,47,112,111, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,53,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,112,111,115,62,57, +51,44,49,51,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97, +109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67, +97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,112,111,115,62,49,52,54,44,49,51,53,100,60,47,112, +111,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,84,79,80,124,119,120,66,79,84,84,79,77,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68,124,119,120,71,82, +79,87,124,119,120,65,76,73,71,78,95,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62, +53,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,71,82,79,87,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101, +115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_78 = 70018; +static unsigned char xml_res_file_78[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,79,112,116,105,111,110,115,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,79,112,116,105,111,110,115,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,52,56,48,44,50,53,48,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,48,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +114,111,119,115,62,48,60,47,103,114,111,119,97,98,108,101,114,111,119,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,99,116,108,84,114,101,101,34,32,110,97,109,101,61,34,109,101,110,117, +115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101, +62,49,48,48,44,50,50,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95,72, +65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79,82, +68,69,82,124,119,120,84,82,95,72,73,68,69,95,82,79,79,84,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60, +47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,114, +111,119,115,62,48,44,49,44,50,44,51,44,52,44,53,44,54,44,55,44,56,44,57, +44,49,48,44,49,49,44,49,50,44,49,51,44,49,52,44,49,53,60,47,103,114,111, +119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,80,71,32,104,101,108,112,32,112, +97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,80,103,72,101,108,112,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,116,104,101,32,112,97,116,104,32,111,114,32,85,82,76,32,116,111,32,116, +104,101,32,80,111,115,116,103,114,101,83,81,76,32,100,111,99,117,109,101, +110,116,97,116,105,111,110,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,69,100,98,72,101,108,112,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,68,66,32,104,101,108,112,32,112,97,116,104,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,69,100,98,72,101,108,112,80,97,116,104,34,47, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,71,112,72,101,108,112,80,97,116,104,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,71,80,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +71,112,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,72, +101,108,112,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +110,121,32,104,101,108,112,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83, +108,111,110,121,72,101,108,112,80,97,116,104,34,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,77,105,115, +99,85,73,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108, +101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,85,115,101,114,32,108,97,110,103,117,97,103,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,76,97,110,103,117,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116, +47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76, +89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,121,115,116,101,109,83,99,104,101, +109,97,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,121,115,116,101,109,32, +115,99,104,101,109,97,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116, +67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,83,121,115,116,101, +109,83,99,104,101,109,97,115,34,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80,97, +110,101,108,34,32,110,97,109,101,61,34,112,110,108,66,114,111,119,115,101, +114,68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100, +100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,114,111,119,115,62,49,60,47,103, +114,111,119,97,98,108,101,114,111,119,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,68,97,116, +97,98,97,115,101,79,98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,68,105,115,112,108,97,121,32,116,104,101,32,102,111,108,108,111,119, +105,110,103,32,100,97,116,97,98,97,115,101,32,111,98,106,101,99,116,115, +58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,76,105,115,116,66,111,120,34,32,110,97,109,101,61,34,108,115,116, +68,105,115,112,108,97,121,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,98,116,110,68,101,102,97,117,108,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,68,101,102,97,117,108,116,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,80,114,111,112, +101,114,116,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101, +110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71, +114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,65,117,116,111,82,111,119,67,111,117,110, +116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,67,111,117,110,116,32,114,111,119,115, +32,105,102,32,101,115,116,105,109,97,116,101,100,32,108,101,115,115,32, +116,104,97,110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,65,117,116,111,82,111,119,67, +111,117,110,116,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,66,114,111,119,115,101,114,66,105,110,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83, +105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111, +119,97,98,108,101,114,111,119,115,62,53,60,47,103,114,111,119,97,98,108, +101,114,111,119,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,108,111,110,121,80,97,116, +104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,83,108,111,110,121,45,73,32,112,97, +116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99,107, +101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +83,108,111,110,121,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115,115,97,103,101, +62,83,101,108,101,99,116,32,100,105,114,101,99,116,111,114,121,32,119,105, +116,104,32,83,108,111,110,121,45,73,32,99,114,101,97,116,105,111,110,32, +115,99,114,105,112,116,115,60,47,109,101,115,115,97,103,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69,88,84,67,84, +82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,80,111, +115,116,103,114,101,115,113,108,80,97,116,104,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,80,71,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,80,111,115,116,103,114,101,115,113,108,80,97, +116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,100,105,114,101,99,116,111,114,121,32,119,105,116,104,32,80,111,115, +116,103,114,101,83,81,76,32,117,116,105,108,105,116,105,101,115,60,47,109, +101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82, +80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,69,110,116,101,114,112,114,105,115,101, +100,98,80,97,116,104,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,68,66,32,98,105, +110,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,68,105,114,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,110,116,101,114,112,114,105,115,101,100,98,80,97,116,104,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101, +99,116,111,114,121,32,119,105,116,104,32,69,110,116,101,114,112,114,105, +115,101,68,66,32,117,116,105,108,105,116,105,101,115,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85, +83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,71,80,68,66,80,97,116,104,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,71,80,32,98,105,110,32,112,97,116,104,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,68,105,114,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,71,80,68,66,80,97,116,104,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,100,105,114,101,99,116,111, +114,121,32,119,105,116,104,32,71,114,101,101,110,112,108,117,109,68,66, +32,117,116,105,108,105,116,105,101,115,60,47,109,101,115,115,97,103,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,115,116,121,108,101,62,119,120,68,73,82,80,95,85,83,69,95,84,69, +88,84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,73,103,110,111,114,101,86,101,114,115,105,111,110,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,73,103,110,111,114,101,32,115,101,114,118,101,114,47,117, +116,105,108,105,116,121,32,118,101,114,115,105,111,110,32,109,105,115,109, +97,116,99,104,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61, +34,115,116,86,101,114,115,105,111,110,77,105,115,109,97,116,99,104,87,97, +114,110,105,110,103,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,87,97,114,110,105, +110,103,58,32,66,97,99,107,117,112,32,111,114,32,114,101,115,116,111,114, +101,32,111,112,101,114,97,116,105,111,110,115,32,109,97,121,32,102,97,105, +108,32,105,102,32,116,104,101,32,80,111,115,116,103,114,101,83,81,76,32, +117,116,105,108,105,116,105,101,115,32,100,111,32,110,111,116,32,109,97, +116,99,104,32,116,104,101,32,115,101,114,118,101,114,32,118,101,114,115, +105,111,110,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,66,114,111,119,115,101,114,77,105,115,99,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60, +47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120, +71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97, +98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70, +111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,115,107,68,101, +108,101,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,110,102,105,114, +109,32,111,98,106,101,99,116,32,100,101,108,101,116,105,111,110,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101, +99,107,101,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,121,115,116,101,109,79, +98,106,101,99,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32, +83,121,115,116,101,109,32,79,98,106,101,99,116,115,32,105,110,32,116,104, +101,32,116,114,101,101,118,105,101,119,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,83,104,111,119,85,115,101,114,115,70,111,114,80, +114,105,118,105,108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,117,115,101,114,115,32,102,111,114,32,112,114,105,118,105, +108,101,103,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107, +101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,68,111,117,98,108,101,67,108,105,99,107,80,114,111,112,101,114,116, +105,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104,111,119,32,111,98,106, +101,99,116,32,112,114,111,112,101,114,116,105,101,115,32,111,110,32,100, +111,117,98,108,101,32,99,108,105,99,107,32,105,110,32,116,114,101,101,118, +105,101,119,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,104, +111,119,78,111,116,105,99,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,104, +111,119,32,78,79,84,73,67,69,115,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49, +60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,82,101,102,114,101,115,104,79,110,67,108,105,99,107,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,82,101,102,114,101,115,104,32,111,110,32, +99,108,105,99,107,58,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109,98,111,66,111, +120,34,32,110,97,109,101,61,34,99,98,82,101,102,114,101,115,104,79,110, +67,108,105,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110,116,101,110,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,110,101,60,47,105,116, +101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102,114,101, +115,104,32,111,98,106,101,99,116,32,111,110,32,99,108,105,99,107,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,82,101,102, +114,101,115,104,32,111,98,106,101,99,116,32,97,110,100,32,99,104,105,108, +100,114,101,110,32,111,110,32,99,108,105,99,107,60,47,105,116,101,109,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +116,121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120, +67,66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110, +97,109,101,61,34,112,110,108,81,117,101,114,121,84,111,111,108,69,100,105, +116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100, +83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,83,113,108,70,111,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,111,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,111,110,116, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,83,113,108,70,111,110,116,34,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97,120,67, +111,108,83,105,122,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,46,32, +99,104,97,114,97,99,116,101,114,115,32,112,101,114,32,99,111,108,117,109, +110,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,77,97,120,67,111,108,83,105,122,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,97,108,117,101,62,50,53,54,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,73,110,100,101,110,116,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,73,110,100,101,110,116,32,99,104,97,114,97,99,116,101,114,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,73,110,100,101,110,116,34,47,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,112,97, +99,101,115,70,111,114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85, +115,101,32,115,112,97,99,101,115,32,105,110,115,116,101,97,100,32,111,102, +32,116,97,98,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,83,112,97,99,101,115,70,111, +114,84,97,98,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121, +108,101,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,116,105,99,107,121, +83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,83,81,76, +32,102,114,111,109,32,109,97,105,110,32,119,105,110,100,111,119,32,116, +111,32,113,117,101,114,121,32,116,111,111,108,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,116, +105,99,107,121,83,113,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99, +104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,82,111,108,108,98,97,99,107,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,32, +82,79,76,76,66,65,67,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,82, +111,108,108,98,97,99,107,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104, +101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,65,117,116,111,67,111,109,109,105,116,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,117,116,111,67,111,109, +109,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,65,117,116,111,67,111,109,109, +105,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101, +100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115, +116,75,101,121,119,111,114,100,73,110,85,112,112,101,114,99,97,115,101, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,75,101,121,119,111,114,100,115,32,105, +110,32,117,112,112,101,114,99,97,115,101,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,75,101, +121,119,111,114,100,115,73,110,85,112,112,101,114,99,97,115,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,69,120,116,70, +111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,116, +101,114,110,97,108,32,102,111,114,109,97,116,116,105,110,103,32,117,116, +108,105,116,121,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101,80,105,99, +107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105,99,107,101, +114,69,120,116,70,111,114,109,97,116,67,109,100,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101,115, +115,97,103,101,62,83,101,108,101,99,116,32,117,116,105,108,105,116,121, +32,116,111,32,102,111,114,109,97,116,32,116,101,120,116,60,47,109,101,115, +115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,119,105,108,100,99,97,114,100,62,42,60,47,119,105, +108,100,99,97,114,100,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95, +79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,65,32, +99,111,109,109,97,110,100,32,108,105,110,101,32,117,116,105,108,105,116, +121,32,119,104,105,99,104,32,114,101,97,100,115,32,83,84,68,73,78,32,97, +110,100,32,100,105,114,101,99,116,115,32,111,117,116,112,117,116,32,116, +111,32,83,84,68,79,85,84,46,60,47,116,111,111,108,116,105,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,65,83,85,84,80,115,116,121,108,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,69,110,97,98,108,101,32,65,83,85,84,80,32,115,116, +121,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,65,83,85,84,80,115,116,121,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,81,117,101,114,121,84,111,111,108,67,111,108,111,117,114,115,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100, +100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,70,111,114,101,103,114,111,117,110,100,47,66,97,99,107,103,114, +111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116, +62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,51,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +104,103,97,112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,44,49,60,47,103,114,111,119, +97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +83,81,76,85,115,101,83,121,115,116,101,109,66,97,99,107,103,114,111,117, +110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,85,115,101,32,115,121,115,116,101,109,32,98,97,99,107,103, +114,111,117,110,100,32,99,111,108,111,114,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,81,76,67,117,115,116,111,109,66,97,99,107,103,114,111, +117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,67,117,115,116,111,109,32,98,97,99,107,103,114,111, +117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,66,97,99,107,103,114,111,117,110,100, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,83,81,76,85,115,101,83,121,115,116,101,109,70,111,114,101,103,114,111, +117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,85,115,101,32,115,121,115,116,101,109,32,102,111,114, +101,103,114,111,117,110,100,32,99,111,108,111,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,81,76,67,117,115,116,111,109,70,111,114,101,103,114, +111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,117,115,116,111,109,32,102,111,114,101,103,114, +111,117,110,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,70,111,114,101,103,114,111,117,110,100, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122, +101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,112,97,99,101,114,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,81,76,77,97,114,103,105,110,66,97,99,107,103,114,111,117, +110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,77,97,114,103,105,110,32,98,97,99,107,103,114,111,117,110, +100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,83,81,76,77,97,114,103,105,110,66,97,99,107,103,114, +111,117,110,100,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,83,105,122, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,67,97,114,101,116,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,52, +60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,52,60,47,104, +103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,44,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,97,114,101,116,67,111, +108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +67,97,114,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,67,97,114,101,116,67,111,108,111,117, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50, +100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62, +119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69, +82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70, +84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +81,76,32,83,121,110,116,97,120,32,72,105,103,104,108,105,103,104,116,105, +110,103,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,111,108,115,62,52,60,47,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,52,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,52,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,44,50,60,47,103,114,111,119,97,98,108,101, +99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83,81,76, +67,111,108,111,117,114,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,77,117,108,116,105,108,105,110,101,32,99,111,109,109,101,110, +116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65, +78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,83,81,76,67,111,108,111,117,114,49,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +54,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,117, +98,108,101,32,113,117,111,116,101,100,32,115,116,114,105,110,103,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108, +111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99, +107,101,114,83,81,76,67,111,108,111,117,114,54,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114,50,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,105,110,103,108, +101,32,108,105,110,101,32,99,111,109,109,101,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80, +105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83, +81,76,67,111,108,111,117,114,50,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115, +105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109, +101,61,34,115,116,83,81,76,67,111,108,111,117,114,55,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,105,110,103,108,101,32,113,117, +111,116,101,100,32,115,116,114,105,110,103,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101, +114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108, +111,117,114,55,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55, +48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +83,81,76,67,111,108,111,117,114,51,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,83,81,76,32,100,111,99,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99, +107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76, +67,111,108,111,117,114,51,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,115,116,83,81,76,67,111,108,111,117,114,49,48,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,79,112,101,114,97,116,111,114,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108, +111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99, +107,101,114,83,81,76,67,111,108,111,117,114,49,48,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105, +122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117,114, +52,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,117,109, +98,101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116, +108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61, +34,112,105,99,107,101,114,83,81,76,67,111,108,111,117,114,52,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,83,81,76,67,111,108,111,117, +114,49,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,100, +101,110,116,105,102,105,101,114,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32, +110,97,109,101,61,34,112,105,99,107,101,114,83,81,76,67,111,108,111,117, +114,49,49,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44, +49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83, +116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,83, +81,76,67,111,108,111,117,114,53,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,75,101,121,119,111,114,100,60,47,108,97,98,101,108,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114,80,105,99, +107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114,83,81,76, +67,111,108,111,117,114,53,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105, +122,101,62,55,48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,82,69,124,119,120,65,76,76,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112, +110,108,81,117,101,114,121,84,111,111,108,82,101,115,117,108,116,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105, +100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +67,111,112,121,81,117,111,116,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +115,117,108,116,32,99,111,112,121,32,113,117,111,116,105,110,103,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,67,111,112,121,81,117,111,116,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,78,111,110,101,60,47,105, +116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,105,116,101,109,62,83,116,114,105,110,103,115, +60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,65,108,108,60,47, +105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,99,111,110,116,101,110,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116, +121,108,101,62,119,120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67, +66,95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,112,121,81,117,111,116,101,67,104,97,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,117,108,116,32,99,111,112,121, +32,113,117,111,116,101,32,99,104,97,114,97,99,116,101,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,67,111,112,121,81,117,111,116,101,67,104,97,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,34,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,39,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66, +95,68,82,79,80,68,79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,67,111,112,121,83,101,112,97,114,97,116,111,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,82,101,115,117,108,116,32,99,111,112,121, +32,102,105,101,108,100,32,115,101,112,97,114,97,116,111,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109,101,61,34,99, +98,67,111,112,121,83,101,112,97,114,97,116,111,114,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,110, +116,101,110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,105,116,101,109,62,59,60,47,105,116,101,109, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,105,116,101,109,62,44,60,47,105,116,101,109,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,105,116,101,109,62,124,60,47,105,116,101,109,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116, +101,109,62,84,97,98,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101, +110,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,68,82,79,80,68, +79,87,78,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,110, +100,105,99,97,116,101,78,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83, +104,111,119,32,78,85,76,76,32,118,97,108,117,101,115,32,97,115,32,38,108, +116,59,78,85,76,76,38,103,116,59,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,73,110,100,105, +99,97,116,101,78,117,108,108,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32, +110,97,109,101,61,34,115,116,84,104,111,117,115,97,110,100,115,83,101,112, +97,114,97,116,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,104,111,117,115, +97,110,100,115,32,115,101,112,97,114,97,116,111,114,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116, +120,116,84,104,111,117,115,97,110,100,115,83,101,112,97,114,97,116,111, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99,107,101,100, +62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +68,101,99,105,109,97,108,77,97,114,107,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +68,101,99,105,109,97,108,32,109,97,114,107,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,68, +101,99,105,109,97,108,77,97,114,107,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,99,104,101,99,107,101,100,62,48,60,47,99,104,101,99,107,101,100,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34, +32,110,97,109,101,61,34,115,116,67,111,108,117,109,110,78,97,109,101,115, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,108,97,98,101,108,62,67,111,112,121,32,99,111,108,117,109,110, +32,110,97,109,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,67,111,108,117,109,110,78, +97,109,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,47,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,81,117,101,114,121,84,111,111,108,70,105,108,101,115,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105, +100,100,101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,85,110, +105,99,111,100,101,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101, +97,100,32,97,110,100,32,119,114,105,116,101,32,85,110,105,99,111,100,101, +32,85,84,70,45,56,32,102,105,108,101,115,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97, +109,101,61,34,99,104,107,87,114,105,116,101,66,79,77,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97, +98,101,108,62,87,114,105,116,101,32,66,79,77,32,102,111,114,32,85,84,70, +32,102,105,108,101,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,49,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99, +104,107,65,115,107,83,97,118,101,67,111,110,102,105,114,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,68,111,32,110,111,116,32,112,114,111,109,112,116,32, +102,111,114,32,117,110,115,97,118,101,100,32,102,105,108,101,115,32,111, +110,32,101,120,105,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,104,101,99, +107,101,100,62,48,60,47,99,104,101,99,107,101,100,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,81,117,101,114,121,84,111,111,108,70,97,118,111,117,114, +105,116,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114,105, +100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103, +97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103, +114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97, +98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,70,97,118,111,117,114,105,116,101,115,70,105,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,97,118,111,117,114,105,116,101,115, +32,102,105,108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105, +108,101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34, +112,105,99,107,101,114,70,97,118,111,117,114,105,116,101,115,70,105,108, +101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116,32,102, +105,108,101,32,116,111,32,115,116,111,114,101,32,102,97,118,111,117,114, +105,116,101,115,32,113,117,101,114,105,101,115,60,47,109,101,115,115,97, +103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78, +124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121, +84,111,111,108,77,97,99,114,111,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49,60,47,104,105, +100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47, +104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60,47,103, +114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,77,97,99,114,111,115,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,99,114,111,115,32,102,105, +108,101,32,112,97,116,104,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82, +95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84, +124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105,108,101, +80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,77,97,99,114,111,115,70,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,102,105,108,101,32,116,111, +32,115,116,111,114,101,32,109,97,99,114,111,115,60,47,109,101,115,115,97, +103,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78, +124,119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116, +121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,81,117,101,114,121, +84,111,111,108,72,105,115,116,111,114,121,70,105,108,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,72,105,115,116, +111,114,121,70,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,72,105,115, +116,111,114,121,32,102,105,108,101,32,112,97,116,104,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,105,108,101,80,105,99,107,101,114,67,116,114,108,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,72,105,115,116,111,114,121,70,105, +108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,109,101,115,115,97,103,101,62,83,101,108,101,99,116, +32,102,105,108,101,32,116,111,32,115,116,111,114,101,32,113,117,101,114, +105,101,115,32,104,105,115,116,111,114,121,60,47,109,101,115,115,97,103, +101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,116,121,108,101,62,119,120,70,76,80,95,79,80,69,78,124, +119,120,70,76,80,95,85,83,69,95,84,69,88,84,67,84,82,76,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,108,98,108,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77, +97,120,105,109,117,109,32,113,117,101,114,105,101,115,32,116,111,32,115, +116,111,114,101,32,105,110,32,104,105,115,116,111,114,121,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116, +114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116,111,114,121, +77,97,120,81,117,101,114,105,101,115,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49, +48,60,47,118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,72,105, +115,116,111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,108,97,98,101,108,62,77,97,120,105,109,117,109,32,115,105,122,101,32, +111,102,32,97,32,115,116,111,114,101,100,32,113,117,101,114,121,32,40,105, +110,32,98,121,116,101,115,41,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120, +116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,72,105,115,116, +111,114,121,77,97,120,81,117,101,114,121,83,105,122,101,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +97,108,117,101,62,49,48,48,60,47,118,97,108,117,101,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124, +119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76, +124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61, +34,112,110,108,83,101,114,118,101,114,83,116,97,116,117,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,73,100,108,101, +80,114,111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,73,100,108,101,32,80,114,111,99,101,115,115,32,67,111,108,111,117, +114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84, +69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69, +70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111, +108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105, +99,107,101,114,73,100,108,101,80,114,111,99,101,115,115,67,111,108,111, +117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,65,99,116,105,118,101,80,114, +111,99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,65,99,116,105,118,101,32,80,114,111,99,101,115,115,32,67,111,108,111, +117,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73, +67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73, +71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98, +111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,99,116,108,67,111,108,111,117,114, +80,105,99,107,101,114,34,32,110,97,109,101,61,34,112,105,99,107,101,114, +65,99,116,105,118,101,80,114,111,99,101,115,115,67,111,108,111,117,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,55,48,44,49,50,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,108,111,119,80,114,111,99,101,115, +115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,108,111, +119,32,80,114,111,99,101,115,115,32,67,111,108,111,117,114,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65, +76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120, +84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122, +101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,99,116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,83,108,111,119,80,114,111,99,101, +115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49, +50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78, +84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,108, +111,99,107,101,100,80,114,111,99,101,115,115,67,111,108,111,117,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,108,111,99,107,101,100,32,80,114,111,99, +101,115,115,32,67,111,108,111,117,114,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99,116,108,67, +111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101,61,34,112, +105,99,107,101,114,66,108,111,99,107,101,100,80,114,111,99,101,115,115, +67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55,48,44,49,50,100, +60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,66,108,111,99, +107,101,100,98,121,80,114,111,99,101,115,115,67,111,108,111,117,114,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,66,108,111,99,107,101,100,32,98,121,32,80, +114,111,99,101,115,115,32,67,111,108,111,117,114,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,99, +116,108,67,111,108,111,117,114,80,105,99,107,101,114,34,32,110,97,109,101, +61,34,112,105,99,107,101,114,66,108,111,99,107,101,100,98,121,80,114,111, +99,101,115,115,67,111,108,111,117,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,105,122,101,62,55, +48,44,49,50,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110, +108,68,97,116,97,98,97,115,101,68,101,115,105,103,110,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100, +101,110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,49,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101, +120,116,34,32,110,97,109,101,61,34,115,116,70,111,110,116,68,68,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,70,111,110,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103, +62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,111,110,116,80,105,99,107,101,114,67,116,114,108,34,32,110, +97,109,101,61,34,112,105,99,107,101,114,70,111,110,116,68,68,34,47,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76, +73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84, +79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78, +95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124, +119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,80,103,65,103,101, +110,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,105,100,100,101,110,62,49,60,47,104,105,100,100,101,110,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101,120,71,114, +105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53, +60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62, +49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116, +97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,77,97, +120,82,111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,97,120,105, +109,117,109,32,114,111,119,115,32,116,111,32,114,101,116,114,105,101,118, +101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84, +101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,77,97, +120,82,111,119,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,118,97,108,117,101,62,49,48,48,60,47, +118,97,108,117,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,77,97,120, +105,109,117,109,115,32,114,111,119,115,32,116,111,32,114,101,116,114,105, +101,118,101,32,105,110,116,111,32,111,117,116,112,117,116,32,119,105,110, +100,111,119,59,32,48,32,61,32,117,110,108,105,109,105,116,101,100,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114, +100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73, +71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79, +80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97, +103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108, +77,105,115,99,71,117,114,117,72,105,110,116,115,34,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101,110,62,49, +60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62, +49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97, +112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115, +62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,117,112,112,114, +101,115,115,72,105,110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,32, +110,111,116,32,115,104,111,119,32,103,117,114,117,32,104,105,110,116,115, +59,32,73,39,109,32,111,110,101,32,109,121,115,101,108,102,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,82,101,115,101,116,72,105, +110,116,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115,101,116,32,103, +117,114,117,32,104,105,110,116,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109,101, +61,34,112,110,108,77,105,115,99,76,111,103,103,105,110,103,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,105,100,100,101, +110,62,49,60,47,104,105,100,100,101,110,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,76,111,103, +102,105,108,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,76,111,103,102,105,108, +101,32,40,37,73,68,32,119,105,108,108,32,98,101,32,114,101,112,108,97,99, +101,100,32,119,105,116,104,32,116,104,101,32,80,114,111,99,101,115,115, +32,73,68,41,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,105, +108,101,80,105,99,107,101,114,67,116,114,108,34,32,110,97,109,101,61,34, +112,105,99,107,101,114,76,111,103,102,105,108,101,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,109,101, +115,115,97,103,101,62,83,101,108,101,99,116,32,108,111,103,32,102,105,108, +101,60,47,109,101,115,115,97,103,101,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,70,76,80,95,79,80,69,78,124,119,120,70,76,80,95,85,83,69,95,84,69,88, +84,67,84,82,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,69,110,116,101,114,32,97,32,102,105,108,101,110,97,109,101,32, +116,111,32,119,114,105,116,101,32,97,112,112,108,105,99,97,116,105,111, +110,32,108,111,103,115,32,116,111,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,111,120,34,32,110, +97,109,101,61,34,114,97,100,76,111,103,108,101,118,101,108,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,76,111,103,32,76,101,118,101,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,99,111,110,116,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,78,111,32,108,111,103,103,105,110,103,60,47,105,116,101, +109,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,105,116,101,109,62,38,97,109,112,59,69,114,114,111,114, +115,32,111,110,108,121,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101, +109,62,69,114,114,111,114,115,32,97,110,100,32,78,38,97,109,112,59,111, +116,105,99,101,115,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109, +62,69,114,114,111,114,115,44,32,78,111,116,105,99,101,115,44,32,38,97,109, +112,59,83,81,76,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,105,116,101,109,62, +38,97,109,112,59,68,101,98,117,103,32,40,110,111,116,32,114,101,99,111, +109,109,101,110,100,101,100,32,102,111,114,32,110,111,114,109,97,108,32, +117,115,101,41,60,47,105,116,101,109,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,99,111,110,116,101,110, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,101,108,101,99,116,105,111,110,62,50,60,47,115,101,108, +101,99,116,105,111,110,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,100,105,109,101,110,115,105,111,110,62, +49,60,47,100,105,109,101,110,115,105,111,110,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101, +62,119,120,82,65,95,83,80,69,67,73,70,89,95,67,79,76,83,60,47,115,116,121, +108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116, +32,116,104,101,32,108,101,118,101,108,32,111,102,32,100,101,116,97,105, +108,32,116,111,32,114,101,99,111,114,100,32,105,110,32,116,104,101,32,108, +111,103,102,105,108,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,52,60,47,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99, +111,108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73, +68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66, +117,116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,116, +111,111,108,116,105,112,62,65,99,99,101,112,116,32,116,104,101,32,99,117, +114,114,101,110,116,32,115,101,116,116,105,110,103,115,32,97,110,100,32, +99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117,101,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38, +97,109,112,59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67, +97,110,99,101,108,32,97,110,121,32,99,104,97,110,103,101,115,32,97,110, +100,32,99,108,111,115,101,32,116,104,101,32,100,105,97,108,111,103,117, +101,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65, +76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,83,116,97,116,117,115,66,97,114,34,32,110, +97,109,101,61,34,117,110,107,83,116,97,116,117,115,66,97,114,34,62,10,32, +32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,83,84,95,83, +73,90,69,71,82,73,80,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,82,69,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,60,98, +111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,60,47,111,98,106,101,99,116,62,10,60,47,114,101,115, +111,117,114,99,101,62,10}; + +static size_t xml_res_size_79 = 1417; +static unsigned char xml_res_file_79[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,80,97,115,115,119,111,114,100,34,62,10,32,32,32,32, +60,116,105,116,108,101,62,67,104,97,110,103,101,32,80,97,115,115,119,111, +114,100,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,49,55,53,44,55,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60,115, +116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71,95, +83,84,89,76,69,124,119,120,67,65,80,84,73,79,78,124,119,120,83,89,83,84, +69,77,95,77,69,78,85,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,67,117,114,114, +101,110,116,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,67,117,114, +114,101,110,116,32,80,97,115,115,119,111,114,100,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,55,100,60,47,112,111,115, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67, +116,114,108,34,32,110,97,109,101,61,34,116,120,116,67,117,114,114,101,110, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,55,48,44,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,48,48,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,115,116,121,108, +101,62,119,120,84,69,95,80,65,83,83,87,79,82,68,60,47,115,116,121,108,101, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,84,101,120,116,34,32,110,97,109,101,61,34,108,98,108,78,101,119,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,78,101,119,32,80,97,115,115, +119,111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,50,50,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,78,101,119,34,62,10,32,32,32,32,32,32,60,112,111, +115,62,55,48,44,50,48,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60, +115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65,83,83,87, +79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101, +61,34,108,98,108,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,67,111,110,102,105,114,109,32,80,97,115,115,119, +111,114,100,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111, +115,62,53,44,51,55,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109,101, +61,34,116,120,116,67,111,110,102,105,114,109,34,62,10,32,32,32,32,32,32, +60,112,111,115,62,55,48,44,51,53,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,115,105,122,101,62,49,48,48,44,45,49,100,60,47,115,105,122,101, +62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,69,95,80,65, +83,83,87,79,82,68,60,47,115,116,121,108,101,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61, +34,119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98, +101,108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10, +32,32,32,32,32,32,60,112,111,115,62,53,44,53,53,100,60,47,112,111,115,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,38,97,109,112,59,79,75,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,54,51,44,53,53,100,60,47, +112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116, +116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69, +76,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59, +67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,49,50,48,44,53,53,100,60,47,112,111,115,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99,116,62, +10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_80 = 5273; +static unsigned char xml_res_file_80[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,112,111,114,116,34,62,10,32,32,32,32,60,116, +105,116,108,101,62,71,101,110,101,114,97,116,101,32,97,32,114,101,112,111, +114,116,60,47,116,105,116,108,101,62,10,32,32,32,32,60,115,105,122,101, +62,50,53,51,44,51,48,51,100,60,47,115,105,122,101,62,10,32,32,32,32,60, +115,116,121,108,101,62,119,120,68,69,70,65,85,76,84,95,68,73,65,76,79,71, +95,83,84,89,76,69,60,47,115,116,121,108,101,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,84,105,116,108,101,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,112,111,114,116, +32,84,105,116,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,84,105,116,108,101,34,62,10,32,32,32,32,32,32,60, +112,111,115,62,53,44,49,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,45,49,100,60,47,115,105,122,101,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,69,110,116,101,114, +32,97,32,116,105,116,108,101,32,102,111,114,32,116,104,101,32,114,101,112, +111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116,34,32,110, +97,109,101,61,34,115,116,78,111,116,101,115,34,62,10,32,32,32,32,32,32, +60,108,97,98,101,108,62,82,101,112,111,114,116,32,78,111,116,101,115,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,51, +53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116, +78,111,116,101,115,34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,44,52, +53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62, +50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60, +115,116,121,108,101,62,119,120,84,69,95,65,85,84,79,95,83,67,82,79,76,76, +124,119,120,84,69,95,77,85,76,84,73,76,73,78,69,124,119,120,72,83,67,82, +79,76,76,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,69,110,116,101,114,32,97,110,121,32,97,100,100,105,116, +105,111,110,97,108,32,110,111,116,101,115,32,116,111,32,105,110,99,108, +117,100,101,32,111,110,32,116,104,101,32,114,101,112,111,114,116,60,47, +116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107, +83,113,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99, +108,117,100,101,32,116,104,101,32,83,81,76,32,105,110,32,116,104,101,32, +114,101,112,111,114,116,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,60,112,111,115,62,53,44,57,57,100,60,47,112,111,115,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32,116, +104,101,32,83,81,76,32,102,114,111,109,32,116,104,101,32,111,98,106,101, +99,116,32,111,114,32,113,117,101,114,121,32,105,110,32,116,104,101,32,114, +101,112,111,114,116,63,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120,34,32, +110,97,109,101,61,34,115,98,70,111,114,109,97,116,34,62,10,32,32,32,32, +32,32,60,108,97,98,101,108,62,79,117,116,112,117,116,32,102,111,114,109, +97,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +53,44,49,49,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105, +122,101,62,50,52,51,44,52,53,100,60,47,115,105,122,101,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,34,62,10,32,32,32, +32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,88,72,84,77,76,32,49, +46,48,32,84,114,97,110,115,105,116,105,111,110,97,108,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,50,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,67,114,101,97,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,105,110,32,88,72,84,77,76,32,49,46,48, +32,84,114,97,110,115,105,116,105,111,110,97,108,32,102,111,114,109,97,116, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34,32,110,97,109, +101,61,34,114,98,88,109,108,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,88,77,76,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32, +32,32,32,32,32,60,112,111,115,62,49,48,44,49,52,49,100,60,47,112,111,115, +62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,67,114,101,97, +116,101,32,116,104,101,32,114,101,112,111,114,116,32,105,110,32,88,77,76, +32,102,111,114,109,97,116,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,66,111,120, +34,32,110,97,109,101,61,34,115,98,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,83,116,121,108,101,115, +104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112, +111,115,62,53,44,49,54,51,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +60,115,105,122,101,62,50,52,51,44,55,53,100,60,47,115,105,122,101,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,66,117, +105,108,116,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,69,109,98,101,100,32,116,104,101,32,100,101,102,97,117, +108,116,32,115,116,121,108,101,115,104,101,101,116,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,118,97,108,117,101,62,49,60,47,118,97,108, +117,101,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,55,56,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,82,66,95,71,82,79,85,80,60,47,115,116,121,108,101,62,10,32,32,32,32, +32,32,60,116,111,111,108,116,105,112,62,69,109,98,101,100,32,112,103,65, +100,109,105,110,39,115,32,100,101,102,97,117,108,116,32,115,116,121,108, +101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114,101,112, +111,114,116,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,114,98,72,116,109,108,69,109,98,101,100,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,69,109,98,101, +100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108,101, +115,104,101,101,116,32,40,115,112,101,99,105,102,105,101,100,32,102,105, +108,101,32,109,117,115,116,32,101,120,105,115,116,41,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,49,48,44,49,57,49,100,60, +47,112,111,115,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62, +69,109,98,101,100,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,32,105,110,116,111,32,116,104,101,32,114, +101,112,111,114,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,72,116,109,108,76,105,110,107,34, +62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105, +110,107,32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116, +121,108,101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100, +101,32,97,32,108,105,110,107,32,116,111,32,97,110,32,101,120,116,101,114, +110,97,108,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,114,101,112,111,114,116,46,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +108,97,105,110,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97, +109,112,59,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,118,97,108,117,101,62,49,60,47,118,97,108,117,101,62,10,32,32,32,32, +32,32,60,112,111,115,62,49,48,44,49,55,56,100,60,47,112,111,115,62,10,32, +32,32,32,32,32,60,115,116,121,108,101,62,119,120,82,66,95,71,82,79,85,80, +60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116, +105,112,62,68,111,32,110,111,116,32,117,115,101,32,97,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,82,97,100,105,111,66,117,116,116,111, +110,34,32,110,97,109,101,61,34,114,98,88,109,108,76,105,110,107,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,76,105,110,107, +32,116,111,32,97,110,32,101,120,116,101,114,110,97,108,32,115,116,121,108, +101,115,104,101,101,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +60,112,111,115,62,49,48,44,49,57,49,100,60,47,112,111,115,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,73,110,99,108,117,100,101,32, +97,32,108,105,110,107,32,116,111,32,116,104,101,32,115,112,101,99,105,102, +105,101,100,32,115,116,121,108,101,115,104,101,101,116,32,105,110,32,116, +104,101,32,88,77,76,32,102,105,108,101,60,47,116,111,111,108,116,105,112, +62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,82,97,100,105,111, +66,117,116,116,111,110,34,32,110,97,109,101,61,34,114,98,88,109,108,80, +114,111,99,101,115,115,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,88,83,76,84,32,80,114,111,99,101,115,115,32,116,104, +101,32,88,77,76,32,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,60,112,111,115,62,49,48,44,50,48,52,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,80,114,111,99,101,115, +115,32,116,104,101,32,88,77,76,32,100,97,116,97,32,117,115,105,110,103, +32,116,104,101,32,115,112,101,99,105,102,105,101,100,32,115,116,121,108, +101,115,104,101,101,116,60,47,116,111,111,108,116,105,112,62,10,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120,116, +34,32,110,97,109,101,61,34,115,116,83,116,121,108,101,115,104,101,101,116, +34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,110,97, +109,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,49,48,44,50,50,51,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97,109, +101,61,34,116,120,116,72,116,109,108,83,116,121,108,101,115,104,101,101, +116,34,62,10,32,32,32,32,32,32,60,112,111,115,62,54,48,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,54,50, +44,45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,88, +109,108,83,116,121,108,101,115,104,101,101,116,34,62,10,32,32,32,32,32, +32,60,112,111,115,62,54,48,44,50,50,48,100,60,47,112,111,115,62,10,32,32, +32,32,32,32,60,115,105,122,101,62,49,54,50,44,45,49,100,60,47,115,105,122, +101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83,101,108, +101,99,116,32,116,104,101,32,115,116,121,108,101,115,104,101,101,116,32, +116,111,32,117,115,101,46,60,47,116,111,111,108,116,105,112,62,10,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110, +97,109,101,61,34,98,116,110,83,116,121,108,101,115,104,101,101,116,34,62, +10,32,32,32,32,32,32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101, +108,62,10,32,32,32,32,32,32,60,112,111,115,62,50,50,55,44,50,50,48,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,53,44, +45,49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111, +108,116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,115,116,121, +108,101,115,104,101,101,116,32,116,111,32,117,115,101,46,60,47,116,111, +111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,117, +116,112,117,116,32,102,105,108,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,60,112,111,115,62,53,44,50,52,56,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114, +108,34,32,110,97,109,101,61,34,116,120,116,72,116,109,108,70,105,108,101, +34,62,10,32,32,32,32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47, +112,111,115,62,10,32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45, +49,100,60,47,115,105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108, +116,105,112,62,83,101,108,101,99,116,32,116,104,101,32,102,105,108,101, +32,116,111,32,119,114,105,116,101,32,116,104,101,32,114,101,112,111,114, +116,32,116,111,46,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110, +97,109,101,61,34,116,120,116,88,109,108,70,105,108,101,34,62,10,32,32,32, +32,32,32,60,112,111,115,62,53,53,44,50,52,53,100,60,47,112,111,115,62,10, +32,32,32,32,32,32,60,115,105,122,101,62,49,55,53,44,45,49,100,60,47,115, +105,122,101,62,10,32,32,32,32,32,32,60,116,111,111,108,116,105,112,62,83, +101,108,101,99,116,32,116,104,101,32,102,105,108,101,32,116,111,32,119, +114,105,116,101,32,116,104,101,32,114,101,112,111,114,116,32,116,111,46, +60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34,98,116, +110,70,105,108,101,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,46, +46,46,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115,62, +50,51,53,44,50,52,53,100,60,47,112,111,115,62,10,32,32,32,32,32,32,60,115, +105,122,101,62,49,53,44,45,49,100,60,47,115,105,122,101,62,10,32,32,32, +32,32,32,60,116,111,111,108,116,105,112,62,83,101,108,101,99,116,32,116, +104,101,32,102,105,108,101,32,116,111,32,119,114,105,116,101,32,116,104, +101,32,114,101,112,111,114,116,32,116,111,46,60,47,116,111,111,108,116, +105,112,62,10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101, +99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,66,114,111,119, +115,101,114,34,62,10,32,32,32,32,32,32,60,108,97,98,101,108,62,79,112,101, +110,32,116,104,101,32,111,117,116,112,117,116,32,102,105,108,101,32,105, +110,32,116,104,101,32,100,101,102,97,117,108,116,32,98,114,111,119,115, +101,114,63,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,112,111,115, +62,53,44,50,54,53,100,60,47,112,111,115,62,10,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101,61,34, +119,120,73,68,95,72,69,76,80,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,60,112,111,115,62,50,44,50,56,53,100,60,47,112,111,115,62, +10,32,32,32,32,32,32,60,115,116,121,108,101,47,62,10,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32,110,97,109,101, +61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32,60,108,97,98,101, +108,62,38,97,109,112,59,79,75,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101,102,97,117,108, +116,62,10,32,32,32,32,32,32,60,112,111,115,62,49,52,55,44,50,56,53,100, +60,47,112,111,115,62,10,32,32,32,32,32,32,60,115,116,121,108,101,47,62, +10,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110, +34,32,110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10, +32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,67,97,110,99, +101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,60,100,101,102, +97,117,108,116,62,48,60,47,100,101,102,97,117,108,116,62,10,32,32,32,32, +32,32,60,112,111,115,62,50,48,48,44,50,56,53,100,60,47,112,111,115,62,10, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101, +99,116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +static size_t xml_res_size_81 = 16296; +static unsigned char xml_res_file_81[] = { +60,63,120,109,108,32,118,101,114,115,105,111,110,61,34,49,46,48,34,32,101, +110,99,111,100,105,110,103,61,34,73,83,79,45,56,56,53,57,45,49,34,63,62, +10,60,114,101,115,111,117,114,99,101,62,10,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,119,120,68,105,97,108,111,103,34,32,110,97,109, +101,61,34,102,114,109,82,101,115,116,111,114,101,34,62,10,32,32,32,32,60, +116,105,116,108,101,62,82,101,115,116,111,114,101,60,47,116,105,116,108, +101,62,10,32,32,32,32,60,115,105,122,101,62,51,48,48,44,49,57,51,100,60, +47,115,105,122,101,62,10,32,32,32,32,60,115,116,121,108,101,62,119,120, +68,69,70,65,85,76,84,95,68,73,65,76,79,71,95,83,84,89,76,69,124,119,120, +67,65,80,84,73,79,78,124,119,120,83,89,83,84,69,77,95,77,69,78,85,124,119, +120,82,69,83,73,90,69,95,66,79,82,68,69,82,60,47,115,116,121,108,101,62, +10,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32, +32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114, +111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,114,111,119,115,62,48,60,47,103,114,111,119,97,98, +108,101,114,111,119,115,62,10,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,78,111,116,101,98,111,111,107,34,32,110,97,109,101,61,34,110, +98,78,111,116,101,98,111,111,107,34,62,10,32,32,32,32,32,32,32,32,32,32, +60,112,111,115,62,50,44,50,100,60,47,112,111,115,62,10,32,32,32,32,32,32, +32,32,32,32,60,115,105,122,101,62,50,56,53,44,49,56,52,100,60,47,115,105, +122,101,62,10,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,78,66,95,66,79,84,84,79,77,60,47,115,116,121,108,101,62,10,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +110,111,116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,70,105,108,101,32,79,112,116, +105,111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,80, +97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,70,105,108,101,79, +112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,99,111,108,115,62,50,60,47,99,111,108,115,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62, +53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111, +108,115,62,49,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116, +32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99,84,101,120, +116,34,32,110,97,109,101,61,34,115,116,70,111,114,109,97,116,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101, +108,62,70,111,114,109,97,116,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97, +103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,111,109, +98,111,66,111,120,34,32,110,97,109,101,61,34,99,98,70,111,114,109,97,116, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,110,116,101,110,116,47,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,67,66,95,82,69, +65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68,79,87,78,60,47,115, +116,121,108,101,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119, +120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124, +119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60, +47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105,99, +84,101,120,116,34,32,110,97,109,101,61,34,115,116,70,105,108,101,110,97, +109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,108,97,98,101,108,62,70,105,108,101,110,97,109,101,60,47,108,97, +98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115, +61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101,114, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +99,111,108,115,62,50,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,104,103,97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101, +99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +84,101,120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,70, +105,108,101,110,97,109,101,34,47,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80, +65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47, +98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34, +32,110,97,109,101,61,34,98,116,110,70,105,108,101,110,97,109,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,108,97,98,101,108,62,46,46,46,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95,67,69,78, +84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76, +69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100, +101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +83,116,97,116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116, +78,117,109,98,101,114,79,102,74,111,98,115,34,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,78,117,109, +98,101,114,32,79,102,32,74,111,98,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101, +99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,65,76,73,71,78,95,67,69,78,84,82,69,95,86,69,82,84, +73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82, +73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100, +101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114, +105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,84,101, +120,116,67,116,114,108,34,32,110,97,109,101,61,34,116,120,116,78,117,109, +98,101,114,79,102,74,111,98,115,34,47,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105, +116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97, +116,105,99,84,101,120,116,34,32,110,97,109,101,61,34,115,116,82,111,108, +101,110,97,109,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,82,111,108,101,110,97,109,101,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,65,76,73,71,78,95, +67,69,78,84,82,69,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115, +115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108, +97,115,115,61,34,119,120,67,111,109,98,111,66,111,120,34,32,110,97,109, +101,61,34,99,98,82,111,108,101,110,97,109,101,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119, +120,67,66,95,82,69,65,68,79,78,76,89,124,119,120,67,66,95,68,82,79,80,68, +79,87,78,124,119,120,67,66,95,83,79,82,84,60,47,115,116,121,108,101,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,110,111, +116,101,98,111,111,107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,60,108,97,98,101,108,62,82,101,115,116,111,114,101,32,79,112, +116,105,111,110,115,32,35,49,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,80,97,110,101,108,34,32,110,97,109,101,61,34,112,110,108,68, +117,109,112,79,112,116,105,111,110,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119, +120,70,108,101,120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118, +103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98, +108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98,108,101,99,111, +108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116,105, +99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,83,101,99,116,105, +111,110,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105,111,110,80, +114,101,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,101,45,100, +97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116, +105,111,110,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,97,116,97,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119, +120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95, +86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124, +119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114, +62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,83,101,99,116,105, +111,110,80,111,115,116,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80, +111,115,116,45,100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,121,112,101, +32,79,102,32,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,68,97,116,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108,121,32, +100,97,116,97,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,79,110, +108,121,83,99,104,101,109,97,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,79,110,108, +121,32,115,99,104,101,109,97,60,47,108,97,98,101,108,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,111,110,39, +116,32,115,97,118,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99, +111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47, +103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119, +120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99, +107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,79,119,110, +101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,108,97,98,101,108,62,79,119,110,101,114,60,47,108, +97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,80,114,105,118,105, +108,101,103,101,115,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,80,114,105,118,105, +108,101,103,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67, +69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111, +114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111, +84,97,98,108,101,115,112,97,99,101,115,34,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +84,97,98,108,101,115,112,97,99,101,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99, +116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97,103,101,34,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,82,101,115, +116,111,114,101,32,79,112,116,105,111,110,115,32,35,50,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99, +116,32,99,108,97,115,115,61,34,119,120,80,97,110,101,108,34,32,110,97,109, +101,61,34,112,110,108,68,117,109,112,79,112,116,105,111,110,115,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,70,108,101,120,71,114,105,100,83,105,122,101, +114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111, +108,115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60, +47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,83,116,97,116,105,99,66,111,120,83,105,122,101,114,34,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98, +101,108,62,81,117,101,114,105,101,115,60,47,108,97,98,101,108,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,99,111,108, +115,62,49,60,47,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,118,103,97,112,62,53,60,47,118,103,97,112,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,104,103, +97,112,62,53,60,47,104,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108, +115,62,48,60,47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,114,105,101, +110,116,62,119,120,86,69,82,84,73,67,65,76,60,47,111,114,105,101,110,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120, +67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,67,114, +101,97,116,101,68,98,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,73,110,99,108,117, +100,101,32,67,82,69,65,84,69,32,68,65,84,65,66,65,83,69,32,115,116,97,116, +101,109,101,110,116,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,67,108,101,97,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,67,108,101,97,110, +32,98,101,102,111,114,101,32,114,101,115,116,111,114,101,60,47,108,97,98, +101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88, +80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82, +84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120, +82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60, +47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,83,105,110,103,108,101,88,97, +99,116,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,108,97,98,101,108,62,83,105,110,103,108,101,32,116,114, +97,110,115,97,99,116,105,111,110,60,47,108,97,98,101,108,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,68,105,115,97, +98,108,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108, +115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +118,103,97,112,62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103, +97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,103,114,111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111, +119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69, +82,84,73,67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106, +101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111, +120,34,32,110,97,109,101,61,34,99,104,107,68,105,115,97,98,108,101,84,114, +105,103,103,101,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,84,114,105,103,103, +101,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69, +78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120, +76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114, +100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116,101, +109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104, +101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104,107,78,111,68,97, +116,97,70,111,114,70,97,105,108,101,100,84,97,98,108,101,115,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +108,97,98,101,108,62,78,111,32,68,97,116,97,32,102,111,114,32,70,97,105, +108,101,100,32,84,97,98,108,101,115,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98, +106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119, +120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47, +111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68, +124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65, +76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71,72, +84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,83,116,97,116, +105,99,66,111,120,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,77,105,115,99, +101,108,108,97,110,111,117,115,32,47,32,66,101,104,97,118,105,111,114,60, +47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,60,99,111,108,115,62,49,60,47,99,111,108,115,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,118,103,97,112, +62,53,60,47,118,103,97,112,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,104,103,97,112,62,53,60,47,104,103,97,112,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,103,114, +111,119,97,98,108,101,99,111,108,115,62,48,60,47,103,114,111,119,97,98, +108,101,99,111,108,115,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,111,114,105,101,110,116,62,119,120,86,69,82,84,73, +67,65,76,60,47,111,114,105,101,110,116,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66,111,120, +34,32,110,97,109,101,61,34,99,104,107,85,115,101,83,101,116,83,101,115, +115,105,111,110,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,85,115,101,32,83,69,84, +32,83,69,83,83,73,79,78,32,65,85,84,72,79,82,73,90,65,84,73,79,78,60,47, +108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120, +69,88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86, +69,82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52, +60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32, +99,108,97,115,115,61,34,115,105,122,101,114,105,116,101,109,34,62,10,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98, +106,101,99,116,32,99,108,97,115,115,61,34,119,120,67,104,101,99,107,66, +111,120,34,32,110,97,109,101,61,34,99,104,107,69,120,105,116,79,110,69, +114,114,111,114,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,69,120,105,116,32,79,110, +32,69,114,114,111,114,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,73,71, +78,95,67,69,78,84,69,82,95,86,69,82,84,73,67,65,76,124,119,120,84,79,80, +124,119,120,76,69,70,84,124,119,120,82,73,71,72,84,60,47,102,108,97,103, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,52,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106, +101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101, +114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,119,120,67,104,101,99,107,66,111,120,34,32,110,97,109,101,61,34,99,104, +107,86,101,114,98,111,115,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,86,101,114, +98,111,115,101,32,109,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,60,99,104,101,99,107,101,100,62,49,60,47,99,104,101,99,107,101,100, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69,82,84,73,67, +65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119,120,82,73,71, +72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69, +88,80,65,78,68,124,119,120,65,76,73,71,78,95,67,69,78,84,69,82,95,86,69, +82,84,73,67,65,76,124,119,120,84,79,80,124,119,120,76,69,70,84,124,119, +120,82,73,71,72,84,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,32,60,98,111,114,100,101,114,62,52,60,47,98,111, +114,100,101,114,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60, +47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111,107,112,97, +103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,79,98,106,101,99,116,115,60,47,108,97,98,101,108,62,10,32,32,32,32,32, +32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34, +99,116,108,67,104,101,99,107,84,114,101,101,86,105,101,119,34,32,110,97, +109,101,61,34,99,116,118,79,98,106,101,99,116,115,34,62,10,32,32,32,32, +32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84,82,95, +72,65,83,95,66,85,84,84,79,78,83,124,119,120,83,73,77,80,76,69,95,66,79, +82,68,69,82,60,47,115,116,121,108,101,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32, +60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,110,111,116,101,98,111,111, +107,112,97,103,101,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,108, +97,98,101,108,62,77,101,115,115,97,103,101,115,60,47,108,97,98,101,108, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99, +108,97,115,115,61,34,119,120,84,101,120,116,67,116,114,108,34,32,110,97, +109,101,61,34,116,120,116,77,101,115,115,97,103,101,115,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,115,116,121,108,101,62,119,120,84, +69,95,77,85,76,84,73,76,73,78,69,124,119,120,84,69,95,82,69,65,68,79,78, +76,89,124,119,120,72,83,67,82,79,76,76,60,47,115,116,121,108,101,62,10, +32,32,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60, +102,108,97,103,62,119,120,84,79,80,124,119,120,66,79,84,84,79,77,124,119, +120,76,69,70,84,124,119,120,82,73,71,72,84,124,119,120,69,88,80,65,78,68, +124,119,120,71,82,79,87,124,119,120,65,76,73,71,78,95,67,69,78,84,82,69, +60,47,102,108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116, +62,10,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61, +34,115,105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32, +60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,70,108,101, +120,71,114,105,100,83,105,122,101,114,34,62,10,32,32,32,32,32,32,32,32, +32,32,60,99,111,108,115,62,53,60,47,99,111,108,115,62,10,32,32,32,32,32, +32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,119,120,73,68,95,72,69,76,80, +34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108, +62,38,97,109,112,59,72,101,108,112,60,47,108,97,98,101,108,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32, +32,32,32,32,32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78, +68,124,119,120,65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101, +114,62,10,32,32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62, +10,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97, +115,115,61,34,115,112,97,99,101,114,34,62,10,32,32,32,32,32,32,32,32,32, +32,32,32,60,115,105,122,101,62,48,44,48,60,47,115,105,122,101,62,10,32, +32,32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32, +32,32,32,32,32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,115, +105,122,101,114,105,116,101,109,34,62,10,32,32,32,32,32,32,32,32,32,32, +32,32,60,111,98,106,101,99,116,32,99,108,97,115,115,61,34,119,120,66,117, +116,116,111,110,34,32,110,97,109,101,61,34,98,116,110,86,105,101,119,34, +62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62, +38,97,109,112,59,68,105,115,112,108,97,121,32,111,98,106,101,99,116,115, +60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32,32,32,32,32,32,32,32, +60,116,111,111,108,116,105,112,62,68,105,115,112,108,97,121,32,111,98,106, +101,99,116,115,32,99,111,110,116,97,105,110,101,100,32,105,110,32,116,104, +101,32,100,117,109,112,32,111,110,32,97,32,115,112,101,99,105,102,105,99, +32,116,97,98,60,47,116,111,111,108,116,105,112,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,79,75,34,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112,59,82,101, +115,116,111,114,101,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,32,32,60,100,101,102,97,117,108,116,62,49,60,47,100,101, +102,97,117,108,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,47,111, +98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,102,108, +97,103,62,119,120,69,88,80,65,78,68,124,119,120,65,76,76,60,47,102,108, +97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,98,111,114,100,101, +114,62,51,60,47,98,111,114,100,101,114,62,10,32,32,32,32,32,32,32,32,32, +32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,32,32,60,111, +98,106,101,99,116,32,99,108,97,115,115,61,34,115,105,122,101,114,105,116, +101,109,34,62,10,32,32,32,32,32,32,32,32,32,32,32,32,60,111,98,106,101, +99,116,32,99,108,97,115,115,61,34,119,120,66,117,116,116,111,110,34,32, +110,97,109,101,61,34,119,120,73,68,95,67,65,78,67,69,76,34,62,10,32,32, +32,32,32,32,32,32,32,32,32,32,32,32,60,108,97,98,101,108,62,38,97,109,112, +59,67,97,110,99,101,108,60,47,108,97,98,101,108,62,10,32,32,32,32,32,32, +32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32, +32,32,32,32,32,60,102,108,97,103,62,119,120,69,88,80,65,78,68,124,119,120, +65,76,76,60,47,102,108,97,103,62,10,32,32,32,32,32,32,32,32,32,32,32,32, +60,98,111,114,100,101,114,62,51,60,47,98,111,114,100,101,114,62,10,32,32, +32,32,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32, +32,32,32,32,32,60,103,114,111,119,97,98,108,101,99,111,108,115,62,49,60, +47,103,114,111,119,97,98,108,101,99,111,108,115,62,10,32,32,32,32,32,32, +32,32,60,47,111,98,106,101,99,116,62,10,32,32,32,32,32,32,32,32,60,102, +108,97,103,62,119,120,69,88,80,65,78,68,124,119,120,71,82,79,87,60,47,102, +108,97,103,62,10,32,32,32,32,32,32,60,47,111,98,106,101,99,116,62,10,32, +32,32,32,60,47,111,98,106,101,99,116,62,10,32,32,60,47,111,98,106,101,99, +116,62,10,60,47,114,101,115,111,117,114,99,101,62,10}; + +void InitXmlResource() +{ + + // Check for memory FS. If not present, load the handler: + { + wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"), wxT("dummy one")); + wxFileSystem fsys; + wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file")); + wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file")); + if (f) delete f; + else wxFileSystem::AddHandler(new wxMemoryFSHandler); + } + + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._ddPrecisionScaleDialog.xrc"), xml_res_file_0, xml_res_size_0, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._ddTableNameDialog.xrc"), xml_res_file_1, xml_res_size_1, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgAddFavourite.xrc"), xml_res_file_2, xml_res_size_2, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgAggregate.xrc"), xml_res_file_3, xml_res_size_3, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgCast.xrc"), xml_res_file_4, xml_res_size_4, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgCheck.xrc"), xml_res_file_5, xml_res_size_5, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgCollation.xrc"), xml_res_file_6, xml_res_size_6, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgColumn.xrc"), xml_res_file_7, xml_res_size_7, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgConnect.xrc"), xml_res_file_8, xml_res_size_8, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgConversion.xrc"), xml_res_file_9, xml_res_size_9, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgDatabase.xrc"), xml_res_file_10, xml_res_size_10, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgDirectDbg.xrc"), xml_res_file_11, xml_res_size_11, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgDomain.xrc"), xml_res_file_12, xml_res_size_12, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgEditGridOptions.xrc"), xml_res_file_13, xml_res_size_13, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgEventTrigger.xrc"), xml_res_file_14, xml_res_size_14, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgExtension.xrc"), xml_res_file_15, xml_res_size_15, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgExtTable.xrc"), xml_res_file_16, xml_res_size_16, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgFindReplace.xrc"), xml_res_file_17, xml_res_size_17, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignDataWrapper.xrc"), xml_res_file_18, xml_res_size_18, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignKey.xrc"), xml_res_file_19, xml_res_size_19, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignServer.xrc"), xml_res_file_20, xml_res_size_20, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgForeignTable.xrc"), xml_res_file_21, xml_res_size_21, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgFunction.xrc"), xml_res_file_22, xml_res_size_22, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgGroup.xrc"), xml_res_file_23, xml_res_size_23, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgHbaConfig.xrc"), xml_res_file_24, xml_res_size_24, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgIndex.xrc"), xml_res_file_25, xml_res_size_25, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgIndexConstraint.xrc"), xml_res_file_26, xml_res_size_26, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgJob.xrc"), xml_res_file_27, xml_res_size_27, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgLanguage.xrc"), xml_res_file_28, xml_res_size_28, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgMainConfig.xrc"), xml_res_file_29, xml_res_size_29, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgManageFavourites.xrc"), xml_res_file_30, xml_res_size_30, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgManageMacros.xrc"), xml_res_file_31, xml_res_size_31, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgMoveTablespace.xrc"), xml_res_file_32, xml_res_size_32, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgOperator.xrc"), xml_res_file_33, xml_res_size_33, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgPackage.xrc"), xml_res_file_34, xml_res_size_34, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgPgpassConfig.xrc"), xml_res_file_35, xml_res_size_35, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgReassignDropOwned.xrc"), xml_res_file_36, xml_res_size_36, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepCluster.xrc"), xml_res_file_37, xml_res_size_37, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepClusterUpgrade.xrc"), xml_res_file_38, xml_res_size_38, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepListen.xrc"), xml_res_file_39, xml_res_size_39, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepNode.xrc"), xml_res_file_40, xml_res_size_40, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepPath.xrc"), xml_res_file_41, xml_res_size_41, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSequence.xrc"), xml_res_file_42, xml_res_size_42, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSet.xrc"), xml_res_file_43, xml_res_size_43, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSetMerge.xrc"), xml_res_file_44, xml_res_size_44, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSetMove.xrc"), xml_res_file_45, xml_res_size_45, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepSubscription.xrc"), xml_res_file_46, xml_res_size_46, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRepTable.xrc"), xml_res_file_47, xml_res_size_47, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgResourceGroup.xrc"), xml_res_file_48, xml_res_size_48, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRole.xrc"), xml_res_file_49, xml_res_size_49, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgRule.xrc"), xml_res_file_50, xml_res_size_50, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSchedule.xrc"), xml_res_file_51, xml_res_size_51, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSchema.xrc"), xml_res_file_52, xml_res_size_52, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSearchObject.xrc"), xml_res_file_53, xml_res_size_53, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSelectConnection.xrc"), xml_res_file_54, xml_res_size_54, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSequence.xrc"), xml_res_file_55, xml_res_size_55, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgServer.xrc"), xml_res_file_56, xml_res_size_56, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgStep.xrc"), xml_res_file_57, xml_res_size_57, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgSynonym.xrc"), xml_res_file_58, xml_res_size_58, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTable.xrc"), xml_res_file_59, xml_res_size_59, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTablespace.xrc"), xml_res_file_60, xml_res_size_60, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchConfiguration.xrc"), xml_res_file_61, xml_res_size_61, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchDictionary.xrc"), xml_res_file_62, xml_res_size_62, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchParser.xrc"), xml_res_file_63, xml_res_size_63, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTextSearchTemplate.xrc"), xml_res_file_64, xml_res_size_64, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgTrigger.xrc"), xml_res_file_65, xml_res_size_65, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgType.xrc"), xml_res_file_66, xml_res_size_66, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgUser.xrc"), xml_res_file_67, xml_res_size_67, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgUserMapping.xrc"), xml_res_file_68, xml_res_size_68, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._dlgView.xrc"), xml_res_file_69, xml_res_size_69, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmBackup.xrc"), xml_res_file_70, xml_res_size_70, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmBackupGlobals.xrc"), xml_res_file_71, xml_res_size_71, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmBackupServer.xrc"), xml_res_file_72, xml_res_size_72, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmExport.xrc"), xml_res_file_73, xml_res_size_73, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmGrantWizard.xrc"), xml_res_file_74, xml_res_size_74, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmHint.xrc"), xml_res_file_75, xml_res_size_75, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmImport.xrc"), xml_res_file_76, xml_res_size_76, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmMaintenance.xrc"), xml_res_file_77, xml_res_size_77, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmOptions.xrc"), xml_res_file_78, xml_res_size_78, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmPassword.xrc"), xml_res_file_79, xml_res_size_79, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmReport.xrc"), xml_res_file_80, xml_res_size_80, wxT("text/xml")); + XRC_ADD_FILE(wxT("XRC_resource/xrcDialogs.cpp$._frmRestore.xrc"), xml_res_file_81, xml_res_size_81, wxT("text/xml")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._ddPrecisionScaleDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._ddTableNameDialog.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgAddFavourite.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgAggregate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgCast.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgCheck.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgCollation.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgColumn.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgConnect.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgConversion.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgDatabase.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgDirectDbg.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgDomain.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgEditGridOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgEventTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgExtension.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgExtTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgFindReplace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignDataWrapper.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignKey.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgForeignTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgFunction.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgHbaConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgIndex.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgIndexConstraint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgJob.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgLanguage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgMainConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgManageFavourites.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgManageMacros.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgMoveTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgOperator.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgPackage.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgPgpassConfig.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgReassignDropOwned.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepCluster.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepClusterUpgrade.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepListen.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepNode.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepPath.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSet.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSetMerge.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSetMove.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepSubscription.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRepTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgResourceGroup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRole.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgRule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSchedule.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSchema.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSearchObject.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSelectConnection.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSequence.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgStep.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgSynonym.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTable.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTablespace.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchConfiguration.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchDictionary.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchParser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTextSearchTemplate.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgTrigger.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgType.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgUser.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgUserMapping.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._dlgView.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmBackup.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmBackupGlobals.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmBackupServer.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmExport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmGrantWizard.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmHint.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmImport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmMaintenance.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmOptions.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmPassword.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmReport.xrc")); + wxXmlResource::Get()->Load(wxT("memory:XRC_resource/xrcDialogs.cpp$._frmRestore.xrc")); +} diff --git a/utils/csvfiles.cpp b/utils/csvfiles.cpp new file mode 100644 index 0000000..6b03ede --- /dev/null +++ b/utils/csvfiles.cpp @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// csvfiles.cpp - CSV file parsing +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" +#include "utils/sysLogger.h" +#include "utils/csvfiles.h" + +// PostgreSQL and GPDB now support CSV format logs. +// So, we need a way to parse the CSV files into lines, and lines into tokens (fields). + +bool CSVTokenizer::HasMoreTokens() const +{ + if ( m_string.length() > 0) + { + if ( m_pos >= m_string.length()) + return false; + + if ( m_string.find_first_not_of(wxT(','), m_pos) != wxString::npos ) + // there are non delimiter characters left, so we do have more tokens + return true; + + if (m_string[m_pos] == wxT('\n')) + return false; + } + return m_pos == 0 && !m_string.empty(); +} + +wxString CSVTokenizer::GetNextToken() +{ + wxString token; + + if ( !HasMoreTokens() ) + return token; + + // skip leading blanks if not quoted. + while (m_pos < m_string.length() && m_string[m_pos] == wxT(' ')) + m_pos ++; + + // Are we a quoted field? Must handle this special. + bool quoted_string = (m_string[m_pos] == wxT('\"')); + bool inquote = false; + + size_t pos = m_pos; + + // find the end of this token. + for (; pos < m_string.length(); pos++) + { + if (quoted_string && m_string[pos] == wxT('\"')) + inquote = !inquote; + + if (!inquote) + { + // Check to see if we have found the end of this token. + // Tokens normally end with a ',' delimiter. + if (m_string[pos] == wxT(',')) + break; + + // Last token is delimited by '\n' or by end of string. + if (m_string[pos] == wxT('\n') && pos == m_string.length() - 1) + break; + } + } + + if (quoted_string && !inquote) + { + token.assign(m_string, m_pos + 1, pos - m_pos - 2); // Remove leading and trailing quotes + + // Remove double doublequote chars, replace with single doublequote chars + token.Replace(wxT("\"\""), wxT("\""), true); + } + else + token.assign(m_string, m_pos, pos - m_pos); + + if (quoted_string && inquote) + { + wxLogNotice(wxT("unterminated double quoted string: %s\n"), token.c_str()); + } + + m_pos = pos + 1; // Skip token and delimiter + + if (m_pos > m_string.length()) // Perhaps no delimiter if at end of string if orig string didn't have '\n'. + m_pos = m_string.length(); + + return token; +} + +bool CSVLineTokenizer::HasMoreLines() const +{ + if ( m_string.find_first_not_of(wxT('\n'), m_pos) != wxString::npos ) + // there are non line-end characters left, so we do have more lines + return true; + return false; +} + +wxString CSVLineTokenizer::GetNextLine(bool &partial) +{ + wxString token; + partial = true; + + if ( !HasMoreLines() ) + return token; + + // find the end of this line. CSV lines end in "\n", but + // CSV lines may have "\n" chars inside double-quoted strings, so we need to find that out. + + bool inquote = false; + for (size_t pos = m_pos; pos < m_string.length(); pos++) + { + if (m_string[pos] == wxT('\"')) + inquote = !inquote; + + if (m_string[pos] == wxT('\n') && !inquote) + { + // Good, we found a complete log line terminated + // by "\n", and the "\n" wasn't in a quoted string. + + size_t len = pos - m_pos + 1; // return the line, including the trailing "\n" + token.assign(m_string, m_pos, len); + m_pos = pos + 1; // point to next line. + partial = false; + return token; + } + } + + // no more delimiters, so the line is everything till the end of + // string, but we don't have all of the CSV the line... Some must still be coming. + + token.assign(m_string, m_pos, wxString::npos); + partial = true; + + m_pos = m_string.length(); + + return token; +} diff --git a/utils/diff_match_patch.cc b/utils/diff_match_patch.cc new file mode 100644 index 0000000..54a092e --- /dev/null +++ b/utils/diff_match_patch.cc @@ -0,0 +1,2210 @@ +/* + * Copyright 2008 Google Inc. All Rights Reserved. + * Author: fraser@google.com (Neil Fraser) + * Author: mikeslemmer@gmail.com (Mike Slemmer) + * Author: quentinfiard@gmail.com (Quentin Fiard) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Diff Match and Patch + * http://code.google.com/p/google-diff-match-patch/ + */ + +#include "pgAdmin3.h" + +typedef std::wstring_convert, wchar_t> + UnicodeEncoder; + +////////////////////////// +// +// Diff Class +// +////////////////////////// + +/** + * Constructor. Initializes the diff with the provided values. + * @param operation One of INSERT, DELETE or EQUAL + * @param text The text being applied + */ +Diff::Diff(Operation _operation, const std::wstring &_text) + : operation(_operation), text(_text) { + // Construct a diff with the specified operation and text. +} + +Diff::Diff() {} + +std::wstring Diff::strOperation(Operation op) { + switch (op) { + case INSERT: + return L"INSERT"; + case DELETE: + return L"DELETE"; + case EQUAL: + return L"EQUAL"; + } + throw "Invalid operation."; +} + +/** + * Display a human-readable version of this Diff. + * @return text version + */ +std::wstring Diff::toString() const { + std::wstring prettyText = text; + // Replace linebreaks with Pilcrow signs. + std::replace(prettyText.begin(), prettyText.end(), L'\n', L'\u00b6'); + return L"Diff(" + strOperation(operation) + L",\"" + prettyText + L"\")"; +} + +/** + * Is this Diff equivalent to another Diff? + * @param d Another Diff to compare against + * @return true or false + */ +bool Diff::operator==(const Diff &d) const { + return (d.operation == this->operation) && (d.text == this->text); +} + +bool Diff::operator!=(const Diff &d) const { return !(operator==(d)); } + +///////////////////////////////////////////// +// +// Patch Class +// +///////////////////////////////////////////// + +namespace { + +int64_t AsInt64(const std::wstring &str) { + int64_t res; + if (swscanf(str.c_str(), L"%lld", &res) != 1) { + UnicodeEncoder unicode_encoder; + throw "Not an int64: " + unicode_encoder.to_bytes(str); + } + return res; +} + +std::size_t AsSizeT(const std::wstring &str) { + std::size_t res; + if (swscanf(str.c_str(), L"%lu", &res) != 1) { + UnicodeEncoder unicode_encoder; + throw "Not a size_t: " + unicode_encoder.to_bytes(str); + } + return res; +} + +std::string AsString(std::size_t value) { + std::stringstream ss; + ss << value; + return ss.str(); +} + +bool EndsWith(const std::wstring &str, const std::wstring &suffix) { + return str.size() >= suffix.size() && + str.substr(str.size() - suffix.size()) == suffix; +} + +// Replaces all occurences of character c in string str with the given +// replacement string. +void ReplaceAll(std::wstring &str, wchar_t c, const std::wstring &replacement) { + std::size_t pos = 0; + while ((pos = str.find(c, pos)) != std::wstring::npos) { + str.replace(pos, 1, replacement); + pos += replacement.size(); + } +} + +template +void Split(const std::wstring &str, wchar_t sep, Container &output) { + output.clear(); + std::size_t last_pos = 0; + std::size_t pos = 0; + while ((pos = str.find(sep, pos)) != std::wstring::npos) { + output.push_back(str.substr(last_pos, pos - last_pos)); + pos += 1; + last_pos = pos; + } + output.push_back(str.substr(last_pos)); +} + +bool StartsWith(const std::wstring &str, const std::wstring &suffix) { + return str.size() >= suffix.size() && str.substr(0, suffix.size()) == suffix; +} + +std::wstring URLDecode(const std::wstring &text) { + UnicodeEncoder unicode_encoder; + const auto &unicode = unicode_encoder.to_bytes(text); + std::stringstream res; + auto it = unicode.begin(); + auto current = it; + auto next = (it != unicode.end()) ? ++it : unicode.end(); + auto nextnext = (it != unicode.end()) ? ++it : unicode.end(); + for (; nextnext != unicode.end();) { + if ((*current == '%') && (isxdigit(*next) && isxdigit(*nextnext))) { + auto end = nextnext; + std::string hex(next, ++end); + uint32_t c; + sscanf(hex.c_str(), "%x", &c); + res << (char)c; + current = nextnext; + next = ++current; + if (next != unicode.end()) ++next; + nextnext = next; + if (nextnext != unicode.end()) ++nextnext; + } else { + res << *current; + ++current, ++next, ++nextnext; + } + } + if (current != unicode.end()) res << *current; + if (next != unicode.end()) res << *next; + return unicode_encoder.from_bytes(res.str()); +} + +void URLEncodeCharacter(char c, std::stringstream &out) { + if (!iswalnum(c) && c != '-' && c != '.' && c != '_' && c != '~') { + out << '%' << std::setw(2) << std::setfill('0') << std::hex + << std::uppercase << (int)(static_cast(c)); + } else { + out << c; + } +} + +std::wstring URLEncode(const std::wstring &text, const std::wstring &exclude) { + std::unordered_set exclude_set(exclude.begin(), exclude.end()); + std::stringstream res; + UnicodeEncoder unicode_encoder; + for (auto c : text) { + const auto &unicode = unicode_encoder.to_bytes(std::wstring(1, c)); + if (exclude_set.find(c) == exclude_set.end() && !iswalnum(c) && c != L'-' && + c != L'.' && c != L'_' && c != L'~') { + for (const auto narrow_c : unicode) { + URLEncodeCharacter(narrow_c, res); + } + } else { + res << unicode; + } + } + return unicode_encoder.from_bytes(res.str()); +} + +} // namespace + +/** + * Constructor. Initializes with an empty list of diffs. + */ +Patch::Patch() : start1(0), start2(0), size1(0), size2(0) {} + +bool Patch::isNull() const { + if (start1 == 0 && start2 == 0 && size1 == 0 && size2 == 0 && + diffs.size() == 0) { + return true; + } + return false; +} + +/** + * Emmulate GNU diff's format. + * Header: @@ -382,8 +481,9 @@ + * Indicies are printed as 1-based, not 0-based. + * @return The GNU diff string + */ +std::wstring Patch::toString() const { + std::wstringstream coords1, coords2; + if (size1 == 0) { + coords1 << start1 << L",0"; + } else if (size1 == 1) { + coords1 << start1 + 1; + } else { + coords1 << start1 + 1 << L',' << size1; + } + if (size2 == 0) { + coords2 << start2 << L",0"; + } else if (size2 == 1) { + coords2 << start2 + 1; + } else { + coords2 << start2 + 1 << L',' << size2; + } + std::wstringstream text; + text << L"@@ -" << coords1.str() << L" +" << coords2.str() << L" @@\n"; + // Escape the body of the patch with %xx notation. + for (const auto &aDiff : diffs) { + switch (aDiff.operation) { + case INSERT: + text << L'+'; + break; + case DELETE: + text << L'-'; + break; + case EQUAL: + text << L' '; + break; + } + text << URLEncode(aDiff.text, L" !~*'();/?:@&=+$,#") + L'\n'; + } + + return text.str(); +} + +///////////////////////////////////////////// +// +// diff_match_patch Class +// +///////////////////////////////////////////// + +diff_match_patch::diff_match_patch(short Diff_EditCost_, float Match_Threshold_,int Match_Distance_) + : Diff_Timeout(4.0f), + Diff_EditCost(Diff_EditCost_), //4 + Match_Threshold(Match_Threshold_), //0.5f + Match_Distance(Match_Distance_), //1000 + Patch_DeleteThreshold(0.5f), + Patch_Margin(4), + Match_MaxBits(32) {} + +std::list diff_match_patch::diff_main(const std::wstring &text1, + const std::wstring &text2) { + return diff_main(text1, text2, true); +} + +std::list diff_match_patch::diff_main(const std::wstring &text1, + const std::wstring &text2, + bool checklines) { + // Set a deadline by which time the diff must be complete. + clock_t deadline; + if (Diff_Timeout <= 0) { + deadline = std::numeric_limits::max(); + } else { + deadline = clock() + (clock_t)(Diff_Timeout * CLOCKS_PER_SEC); + } + return diff_main(text1, text2, checklines, deadline); +} + +std::list diff_match_patch::diff_main(const std::wstring &text1, + const std::wstring &text2, + bool checklines, clock_t deadline) { + // Check for equality (speedup). + std::list diffs; + if (text1 == text2) { + if (!text1.empty()) { + diffs.push_back(Diff(EQUAL, text1)); + } + return diffs; + } + + // Trim off common prefix (speedup). + std::size_t commonsize = diff_commonPrefix(text1, text2); + const std::wstring &commonprefix = text1.substr(0, commonsize); + std::wstring textChopped1 = text1.substr(commonsize); + std::wstring textChopped2 = text2.substr(commonsize); + + // Trim off common suffix (speedup). + commonsize = diff_commonSuffix(textChopped1, textChopped2); + const std::wstring &commonsuffix = + textChopped1.substr(textChopped1.size() - commonsize); + textChopped1 = textChopped1.substr(0, textChopped1.size() - commonsize); + textChopped2 = textChopped2.substr(0, textChopped2.size() - commonsize); + + // Compute the diff on the middle block. + diffs = diff_compute(textChopped1, textChopped2, checklines, deadline); + + // Restore the prefix and suffix. + if (!commonprefix.empty()) { + diffs.push_front(Diff(EQUAL, commonprefix)); + } + if (!commonsuffix.empty()) { + diffs.push_back(Diff(EQUAL, commonsuffix)); + } + + diff_cleanupMerge(diffs); + + return diffs; +} + +std::list diff_match_patch::diff_compute(std::wstring text1, + std::wstring text2, + bool checklines, + clock_t deadline) { + std::list diffs; + + if (text1.empty()) { + // Just add some text (speedup). + diffs.push_back(Diff(INSERT, text2)); + return diffs; + } + + if (text2.empty()) { + // Just delete some text (speedup). + diffs.push_back(Diff(DELETE, text1)); + return diffs; + } + + { + const std::wstring longtext = text1.size() > text2.size() ? text1 : text2; + const std::wstring shorttext = text1.size() > text2.size() ? text2 : text1; + const std::size_t i = longtext.find(shorttext); + if (i != std::wstring::npos) { + // Shorter text is inside the longer text (speedup). + const Operation op = (text1.size() > text2.size()) ? DELETE : INSERT; + diffs.push_back(Diff(op, longtext.substr(0, i))); + diffs.push_back(Diff(EQUAL, shorttext)); + diffs.push_back(Diff(op, safeSubStr(longtext, i + shorttext.size()))); + return diffs; + } + + if (shorttext.size() == 1) { + // Single character string. + // After the previous speedup, the character can't be an equality. + diffs.push_back(Diff(DELETE, text1)); + diffs.push_back(Diff(INSERT, text2)); + return diffs; + } + // Garbage collect longtext and shorttext by scoping out. + } + + // Check to see if the problem can be split in two. + const std::vector hm = diff_halfMatch(text1, text2); + if (hm.size() > 0) { + // A half-match was found, sort out the return data. + const std::wstring text1_a = hm[0]; + const std::wstring text1_b = hm[1]; + const std::wstring text2_a = hm[2]; + const std::wstring text2_b = hm[3]; + const std::wstring mid_common = hm[4]; + // Send both pairs off for separate processing. + std::list diffs_a = diff_main(text1_a, text2_a, checklines, deadline); + std::list diffs_b = diff_main(text1_b, text2_b, checklines, deadline); + // Merge the results. + diffs.splice(diffs.end(), diffs_a); + diffs.push_back(Diff(EQUAL, mid_common)); + diffs.splice(diffs.end(), diffs_b); + return diffs; + } + + // Perform a real diff. + if (checklines && text1.size() > 100 && text2.size() > 100) { + return diff_lineMode(text1, text2, deadline); + } + + return diff_bisect(text1, text2, deadline); +} + +std::list diff_match_patch::diff_lineMode(std::wstring text1, + std::wstring text2, + clock_t deadline) { + // Scan the text on a line-by-line basis first. + const auto &b = diff_linesToChars(text1, text2); + text1 = std::get<0>(b); + text2 = std::get<1>(b); + const auto &line_array = std::get<2>(b); + + std::list diffs = diff_main(text1, text2, false, deadline); + + // Convert the diff back to original text. + diff_charsToLines(diffs, line_array); + // Eliminate freak matches (e.g. blank lines) + diff_cleanupSemantic(diffs); + + // Rediff any replacement blocks, this time character-by-character. + // Add a dummy entry at the end. + diffs.push_back(Diff(EQUAL, L"")); + std::size_t count_delete = 0; + std::size_t count_insert = 0; + std::wstring text_delete = L""; + std::wstring text_insert = L""; + + for (auto thisDiff = diffs.begin(); thisDiff != diffs.end();) { + switch (thisDiff->operation) { + case INSERT: + count_insert++; + text_insert += thisDiff->text; + ++thisDiff; + break; + case DELETE: + count_delete++; + text_delete += thisDiff->text; + ++thisDiff; + break; + case EQUAL: + // Upon reaching an equality, check for prior redundancies. + if (count_delete >= 1 && count_insert >= 1) { + // Delete the offending records and add the merged ones. + auto it = thisDiff; + for (std::size_t j = 0; j < count_delete + count_insert; j++) { + --it; + it = diffs.erase(it); + } + auto new_diffs = diff_main(text_delete, text_insert, false, deadline); + for (const auto &new_diff : new_diffs) { + diffs.insert(it, new_diff); + } + } else { + ++thisDiff; + } + count_insert = 0; + count_delete = 0; + text_delete = L""; + text_insert = L""; + break; + } + } + diffs.pop_back(); // Remove the dummy entry at the end. + + return diffs; +} + +std::list diff_match_patch::diff_bisect(const std::wstring &text1, + const std::wstring &text2, + clock_t deadline) { + // Cache the text sizes to prevent multiple calls. + const int64_t text1_size = text1.size(); + const int64_t text2_size = text2.size(); + const int64_t max_d = (text1_size + text2_size + 1) / 2; + const int64_t v_offset = max_d; + const int64_t v_size = 2 * max_d; + std::unique_ptr v1(new int64_t[v_size]); + std::unique_ptr v2(new int64_t[v_size]); + for (std::size_t x = 0; x < v_size; x++) { + v1[x] = -1; + v2[x] = -1; + } + v1[v_offset + 1] = 0; + v2[v_offset + 1] = 0; + const int64_t delta = text1_size - text2_size; + // If the total number of characters is odd, then the front path will + // collide with the reverse path. + const bool front = (delta % 2 != 0); + // Offsets for start and end of k loop. + // Prevents mapping of space beyond the grid. + int64_t k1start = 0; + int64_t k1end = 0; + int64_t k2start = 0; + int64_t k2end = 0; + for (int64_t d = 0; d < max_d; d++) { + // Bail out if deadline is reached. + if (clock() > deadline) { + break; + } + + // Walk the front path one step. + for (int64_t k1 = -d + k1start; k1 <= d - k1end; k1 += 2) { + const int64_t k1_offset = v_offset + k1; + int64_t x1; + if (k1 == -d || (k1 != d && v1[k1_offset - 1] < v1[k1_offset + 1])) { + x1 = v1[k1_offset + 1]; + } else { + x1 = v1[k1_offset - 1] + 1; + } + int64_t y1 = x1 - k1; + while (x1 < text1_size && y1 < text2_size && text1[x1] == text2[y1]) { + x1++; + y1++; + } + v1[k1_offset] = x1; + if (x1 > text1_size) { + // Ran off the right of the graph. + k1end += 2; + } else if (y1 > text2_size) { + // Ran off the bottom of the graph. + k1start += 2; + } else if (front) { + int64_t k2_offset = v_offset + delta - k1; + if (k2_offset >= 0 && k2_offset < v_size && v2[k2_offset] != -1) { + // Mirror x2 onto top-left coordinate system. + int64_t x2 = text1_size - v2[k2_offset]; + if (x1 >= x2) { + // Overlap detected. + return diff_bisectSplit(text1, text2, x1, y1, deadline); + } + } + } + } + + // Walk the reverse path one step. + for (int64_t k2 = -d + k2start; k2 <= d - k2end; k2 += 2) { + const int64_t k2_offset = v_offset + k2; + int64_t x2; + if (k2 == -d || (k2 != d && v2[k2_offset - 1] < v2[k2_offset + 1])) { + x2 = v2[k2_offset + 1]; + } else { + x2 = v2[k2_offset - 1] + 1; + } + int64_t y2 = x2 - k2; + while (x2 < text1_size && y2 < text2_size && + text1[text1_size - x2 - 1] == text2[text2_size - y2 - 1]) { + x2++; + y2++; + } + v2[k2_offset] = x2; + if (x2 > text1_size) { + // Ran off the left of the graph. + k2end += 2; + } else if (y2 > text2_size) { + // Ran off the top of the graph. + k2start += 2; + } else if (!front) { + int64_t k1_offset = v_offset + delta - k2; + if (k1_offset >= 0 && k1_offset < v_size && v1[k1_offset] != -1) { + int64_t x1 = v1[k1_offset]; + int64_t y1 = v_offset + x1 - k1_offset; + // Mirror x2 onto top-left coordinate system. + x2 = text1_size - x2; + if (x1 >= x2) { + // Overlap detected. + return diff_bisectSplit(text1, text2, x1, y1, deadline); + } + } + } + } + } + // Diff took too long and hit the deadline or + // number of diffs equals number of characters, no commonality at all. + std::list diffs; + diffs.push_back(Diff(DELETE, text1)); + diffs.push_back(Diff(INSERT, text2)); + return diffs; +} + +std::list diff_match_patch::diff_bisectSplit(const std::wstring &text1, + const std::wstring &text2, + std::size_t x, std::size_t y, + clock_t deadline) { + std::wstring text1a = text1.substr(0, x); + std::wstring text2a = text2.substr(0, y); + std::wstring text1b = safeSubStr(text1, x); + std::wstring text2b = safeSubStr(text2, y); + + // Compute both diffs serially. + std::list diffs = diff_main(text1a, text2a, false, deadline); + std::list diffsb = diff_main(text1b, text2b, false, deadline); + diffs.splice(diffs.end(), diffsb); + return diffs; +} + +std::tuple > +diff_match_patch::diff_linesToChars(const std::wstring &text1, + const std::wstring &text2) const { + std::vector line_array; + std::unordered_map lineHash; + // e.g. line_array[4] == "Hello\n" + // e.g. linehash.get("Hello\n") == 4 + + // "\x00" is a valid character, but various debuggers don't like it. + // So we'll insert a junk entry to avoid generating a null character. + line_array.push_back(L""); + + const std::wstring chars1 = + diff_linesToCharsMunge(text1, line_array, lineHash); + const std::wstring chars2 = + diff_linesToCharsMunge(text2, line_array, lineHash); + + return std::make_tuple(chars1, chars2, line_array); +} + +std::wstring diff_match_patch::diff_linesToCharsMunge( + const std::wstring &text, std::vector &line_array, + std::unordered_map &lineHash) const { + std::size_t lineStart = 0; + bool has_line_end = false; + std::size_t lineEnd = std::wstring::npos; + std::wstring line; + std::wstring chars; + + if (text.size() == 0) return chars; + + // Walk the text, pulling out a substring for each line. + // text.split('\n') would would temporarily double our memory footprint. + // Modifying text would create many large strings to garbage collect. + while (!has_line_end || lineEnd < text.size() - 1) { + lineEnd = text.find('\n', lineStart); + has_line_end = true; + if (lineEnd == std::wstring::npos) { + lineEnd = text.size() - 1; + } + line = safeSubStr(text, lineStart, lineEnd + 1 - lineStart); + lineStart = lineEnd + 1; + + if (lineHash.find(line) != lineHash.end()) { + chars += wchar_t(static_cast(lineHash[line])); + } else { + line_array.push_back(line); + lineHash.emplace(line, line_array.size() - 1); + chars += wchar_t(static_cast(line_array.size() - 1)); + } + } + return chars; +} + +void diff_match_patch::diff_charsToLines( + std::list &diffs, const std::vector &line_array) { + for (auto &diff : diffs) { + std::wstring text; + for (std::size_t y = 0; y < diff.text.size(); y++) { + text += line_array[static_cast(diff.text[y])]; + } + diff.text = text; + } +} + +std::size_t diff_match_patch::diff_commonPrefix(const std::wstring &text1, + const std::wstring &text2) { + // Performance analysis: http://neil.fraser.name/news/2007/10/09/ + const std::size_t n = std::min(text1.size(), text2.size()); + for (std::size_t i = 0; i < n; i++) { + if (text1[i] != text2[i]) { + return i; + } + } + return n; +} + +std::size_t diff_match_patch::diff_commonSuffix(const std::wstring &text1, + const std::wstring &text2) { + // Performance analysis: http://neil.fraser.name/news/2007/10/09/ + const std::size_t text1_size = text1.size(); + const std::size_t text2_size = text2.size(); + const std::size_t n = std::min(text1_size, text2_size); + for (std::size_t i = 1; i <= n; i++) { + if (text1[text1_size - i] != text2[text2_size - i]) { + return i - 1; + } + } + return n; +} + +std::size_t diff_match_patch::diff_commonOverlap(const std::wstring &text1, + const std::wstring &text2) { + // Cache the text sizes to prevent multiple calls. + const std::size_t text1_size = text1.size(); + const std::size_t text2_size = text2.size(); + // Eliminate the null case. + if (text1_size == 0 || text2_size == 0) { + return 0; + } + // Truncate the longer string. + std::wstring text1_trunc = text1; + std::wstring text2_trunc = text2; + if (text1_size > text2_size) { + text1_trunc = text1.substr(text1.size() - text2_size); + } else if (text1_size < text2_size) { + text2_trunc = text2.substr(0, text1_size); + } + const std::size_t text_size = std::min(text1_size, text2_size); + // Quick check for the worst case. + if (text1_trunc == text2_trunc) { + return text_size; + } + + // Start by looking for a single character match + // and increase size until no match is found. + // Performance analysis: http://neil.fraser.name/news/2010/11/04/ + std::size_t best = 0; + std::size_t size = 1; + while (true) { + std::wstring pattern = text1_trunc.substr(text1_trunc.size() - size); + std::size_t found = text2_trunc.find(pattern); + if (found == std::wstring::npos) { + return best; + } + size += found; + if (found == 0 || text1_trunc.substr(text1_trunc.size() - size) == + text2_trunc.substr(0, size)) { + best = size; + size++; + } + } +} + +std::vector diff_match_patch::diff_halfMatch( + const std::wstring &text1, const std::wstring &text2) { + if (Diff_Timeout <= 0) { + // Don't risk returning a non-optimal diff if we have unlimited time. + return std::vector(); + } + const std::wstring longtext = text1.size() > text2.size() ? text1 : text2; + const std::wstring shorttext = text1.size() > text2.size() ? text2 : text1; + if (longtext.size() < 4 || shorttext.size() * 2 < longtext.size()) { + return std::vector(); // Pointless. + } + + // First check if the second quarter is the seed for a half-match. + const std::vector hm1 = + diff_halfMatchI(longtext, shorttext, (longtext.size() + 3) / 4); + // Check again based on the third quarter. + const std::vector hm2 = + diff_halfMatchI(longtext, shorttext, (longtext.size() + 1) / 2); + std::vector hm; + if (hm1.empty() && hm2.empty()) { + return std::vector(); + } else if (hm2.empty()) { + hm = hm1; + } else if (hm1.empty()) { + hm = hm2; + } else { + // Both matched. Select the longest. + hm = hm1[4].size() > hm2[4].size() ? hm1 : hm2; + } + + // A half-match was found, sort out the return data. + if (text1.size() > text2.size()) { + return hm; + } else { + std::vector listRet; + listRet.push_back(hm[2]); + listRet.push_back(hm[3]); + listRet.push_back(hm[0]); + listRet.push_back(hm[1]); + listRet.push_back(hm[4]); + return listRet; + } +} + +std::vector diff_match_patch::diff_halfMatchI( + const std::wstring &longtext, const std::wstring &shorttext, + std::size_t i) { + // Start with a 1/4 size substring at position i as a seed. + const std::wstring seed = safeSubStr(longtext, i, longtext.size() / 4); + std::size_t j=0; + std::wstring best_common; + std::wstring best_longtext_a, best_longtext_b; + std::wstring best_shorttext_a, best_shorttext_b; + while ((j = shorttext.find(seed, j + 1)) != std::wstring::npos) { + const std::size_t prefixLength = + diff_commonPrefix(safeSubStr(longtext, i), safeSubStr(shorttext, j)); + const std::size_t suffixLength = + diff_commonSuffix(longtext.substr(0, i), shorttext.substr(0, j)); + if (best_common.size() < suffixLength + prefixLength) { + best_common = safeSubStr(shorttext, j - suffixLength, suffixLength) + + safeSubStr(shorttext, j, prefixLength); + best_longtext_a = longtext.substr(0, i - suffixLength); + best_longtext_b = safeSubStr(longtext, i + prefixLength); + best_shorttext_a = shorttext.substr(0, j - suffixLength); + best_shorttext_b = safeSubStr(shorttext, j + prefixLength); + } + } + if (best_common.size() * 2 >= longtext.size()) { + std::vector aa; + aa.push_back(best_longtext_a); + aa.push_back(best_longtext_b); + aa.push_back(best_shorttext_a); + aa.push_back(best_shorttext_b); + aa.push_back(best_common); + return aa; + } else { + return std::vector(); + } +} + +void diff_match_patch::diff_cleanupSemantic(std::list &diffs) { + if (diffs.empty()) { + return; + } + bool changes = false; + std::vector::iterator> equalities; // Stack of equalities. + bool has_last_equality = false; + std::wstring last_equality; // Always equal to equalities.back().text + // Number of characters that changed prior to the equality. + std::size_t size_insertions1 = 0; + std::size_t size_deletions1 = 0; + // Number of characters that changed after the equality. + std::size_t size_insertions2 = 0; + std::size_t size_deletions2 = 0; + + for (auto thisDiff = diffs.begin(); thisDiff != diffs.end();) { + if (thisDiff->operation == EQUAL) { + // Equality found. + equalities.push_back(thisDiff); + size_insertions1 = size_insertions2; + size_deletions1 = size_deletions2; + size_insertions2 = 0; + size_deletions2 = 0; + last_equality = thisDiff->text; + has_last_equality = true; + ++thisDiff; + } else { + // An insertion or deletion. + if (thisDiff->operation == INSERT) { + size_insertions2 += thisDiff->text.size(); + } else { + size_deletions2 += thisDiff->text.size(); + } + // Eliminate an equality that is smaller or equal to the edits on both + // sides of it. + if (has_last_equality && (last_equality.size() <= + std::max(size_insertions1, size_deletions1)) && + (last_equality.size() <= + std::max(size_insertions2, size_deletions2))) { + // printf("Splitting: '%s'\n", qPrintable(last_equality)); + // Walk back to offending equality. + thisDiff = equalities.back(); + // Replace equality with a delete. + *thisDiff = Diff(DELETE, last_equality); + // Insert a corresponding an insert. + auto it = thisDiff; + ++it; + diffs.insert(it, Diff(INSERT, last_equality)); + + equalities.pop_back(); // Throw away the equality we just deleted. + if (!equalities.empty()) { + // Throw away the previous equality (it needs to be reevaluated). + equalities.pop_back(); + } + if (equalities.empty()) { + thisDiff = diffs.begin(); + } else { + // There is a safe equality we can fall back to. + thisDiff = equalities.back(); + } + + size_insertions1 = 0; // Reset the counters. + size_deletions1 = 0; + size_insertions2 = 0; + size_deletions2 = 0; + has_last_equality = false; + changes = true; + } else { + ++thisDiff; + } + } + } + + // Normalize the diff. + if (changes) { + diff_cleanupMerge(diffs); + } + diff_cleanupSemanticLossless(diffs); + + // Find any overlaps between deletions and insertions. + // e.g: abcxxxxxxdef + // -> abcxxxdef + // e.g: xxxabcdefxxx + // -> defxxxabc + // Only extract an overlap if it is as big as the edit ahead or behind it. + auto thisDiff = diffs.begin(); + auto prevDiff = (thisDiff != diffs.end()) ? thisDiff++ : diffs.end(); + while (thisDiff != diffs.end()) { + if (prevDiff->operation == DELETE && thisDiff->operation == INSERT) { + std::wstring deletion = prevDiff->text; + std::wstring insertion = thisDiff->text; + std::size_t overlap_size1 = diff_commonOverlap(deletion, insertion); + std::size_t overlap_size2 = diff_commonOverlap(insertion, deletion); + if (overlap_size1 >= overlap_size2) { + if (overlap_size1 >= deletion.size() / 2.0 || + overlap_size1 >= insertion.size() / 2.0) { + // Overlap found. Insert an equality and trim the surrounding edits. + diffs.insert(thisDiff, + Diff(EQUAL, insertion.substr(0, overlap_size1))); + prevDiff->text = deletion.substr(0, deletion.size() - overlap_size1); + thisDiff->text = safeSubStr(insertion, overlap_size1); + // diffs.insert inserts the element before the cursor, so there is + // no need to step past the new element. + } + } else { + if (overlap_size2 >= deletion.size() / 2.0 || + overlap_size2 >= insertion.size() / 2.0) { + // Reverse overlap found. + // Insert an equality and swap and trim the surrounding edits. + diffs.insert(thisDiff, + Diff(EQUAL, deletion.substr(0, overlap_size2))); + prevDiff->operation = INSERT; + prevDiff->text = + insertion.substr(0, insertion.size() - overlap_size2); + thisDiff->operation = DELETE; + thisDiff->text = safeSubStr(deletion, overlap_size2); + // pointer.insert inserts the element before the cursor, so there is + // no need to step past the new element. + } + } + ++thisDiff; + } + prevDiff = thisDiff; + if (thisDiff != diffs.end()) ++thisDiff; + } +} + +void diff_match_patch::diff_cleanupSemanticLossless(std::list &diffs) { + std::wstring equality1, edit, equality2; + std::wstring commonString; + std::size_t commonOffset; + int score, bestScore; + std::wstring bestEquality1, bestEdit, bestEquality2; + // Create a new iterator at the start. + auto ptr = diffs.begin(); + auto prevDiff = ptr; + auto thisDiff = (ptr != diffs.end()) ? ++ptr : ptr; + auto nextDiff = (ptr != diffs.end()) ? ++ptr : ptr; + + // Intentionally ignore the first and last element (don't need checking). + while (nextDiff != diffs.end()) { + if (prevDiff->operation == EQUAL && nextDiff->operation == EQUAL) { + // This is a single edit surrounded by equalities. + equality1 = prevDiff->text; + edit = thisDiff->text; + equality2 = nextDiff->text; + + // First, shift the edit as far left as possible. + commonOffset = diff_commonSuffix(equality1, edit); + if (commonOffset != 0) { + commonString = safeSubStr(edit, edit.size() - commonOffset); + equality1 = equality1.substr(0, equality1.size() - commonOffset); + edit = commonString + edit.substr(0, edit.size() - commonOffset); + equality2 = commonString + equality2; + } + + // Second, step character by character right, looking for the best fit. + bestEquality1 = equality1; + bestEdit = edit; + bestEquality2 = equality2; + bestScore = diff_cleanupSemanticScore(equality1, edit) + + diff_cleanupSemanticScore(edit, equality2); + while (!edit.empty() && !equality2.empty() && edit[0] == equality2[0]) { + equality1 += edit[0]; + edit = safeSubStr(edit, 1) + equality2[0]; + equality2 = safeSubStr(equality2, 1); + score = diff_cleanupSemanticScore(equality1, edit) + + diff_cleanupSemanticScore(edit, equality2); + // The >= encourages trailing rather than leading whitespace on edits. + if (score >= bestScore) { + bestScore = score; + bestEquality1 = equality1; + bestEdit = edit; + bestEquality2 = equality2; + } + } + + if (prevDiff->text != bestEquality1) { + // We have an improvement, save it back to the diff. + if (!bestEquality1.empty()) { + prevDiff->text = bestEquality1; + } else { + diffs.erase(prevDiff); + } + thisDiff->text = bestEdit; + if (!bestEquality2.empty()) { + nextDiff->text = bestEquality2; + } else { + nextDiff = diffs.erase(nextDiff); + nextDiff = thisDiff; + thisDiff = prevDiff; + } + } + } + prevDiff = thisDiff; + thisDiff = nextDiff; + if (nextDiff != diffs.end()) ++nextDiff; + } +} + +int diff_match_patch::diff_cleanupSemanticScore(const std::wstring &one, + const std::wstring &two) { + if (one.empty() || two.empty()) { + // Edges are the best. + return 6; + } + + // Each port of this function behaves slightly differently due to + // subtle differences in each language's definition of things like + // 'whitespace'. Since this function's purpose is largely cosmetic, + // the choice has been made to use each language's native features + // rather than force total conformity. + wchar_t char1 = one[one.size() - 1]; + wchar_t char2 = two[0]; + bool nonAlphaNumeric1 = !iswalnum(char1); + bool nonAlphaNumeric2 = !iswalnum(char2); + bool whitespace1 = nonAlphaNumeric1 && iswspace(char1); + bool whitespace2 = nonAlphaNumeric2 && iswspace(char2); + bool lineBreak1 = whitespace1 && iswcntrl(char1); + bool lineBreak2 = whitespace2 && iswcntrl(char2); + bool blankLine1 = lineBreak1 && std::regex_search(one, BLANKLINEEND); + bool blankLine2 = lineBreak2 && std::regex_search(two, BLANKLINESTART); + + if (blankLine1 || blankLine2) { + // Five points for blank lines. + return 5; + } else if (lineBreak1 || lineBreak2) { + // Four points for line breaks. + return 4; + } else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) { + // Three points for end of sentences. + return 3; + } else if (whitespace1 || whitespace2) { + // Two points for whitespace. + return 2; + } else if (nonAlphaNumeric1 || nonAlphaNumeric2) { + // One point for non-alphanumeric. + return 1; + } + return 0; +} + +// Define some regex patterns for matching boundaries. +std::wregex diff_match_patch::BLANKLINEEND(L"\\n\\r?\\n$"); +std::wregex diff_match_patch::BLANKLINESTART(L"^\\r?\\n\\r?\\n"); + +void diff_match_patch::diff_cleanupEfficiency(std::list &diffs) { + if (diffs.empty()) { + return; + } + bool changes = false; + std::vector::iterator> equalities; // Stack of equalities. + bool has_last_equality=false; + std::wstring last_equality; // Always equal to equalities.lastElement().text + // Is there an insertion operation before the last equality. + bool pre_ins = false; + // Is there a deletion operation before the last equality. + bool pre_del = false; + // Is there an insertion operation after the last equality. + bool post_ins = false; + // Is there a deletion operation after the last equality. + bool post_del = false; + + auto thisDiff = diffs.begin(); + auto safeDiff = thisDiff; + + while (thisDiff != diffs.end()) { + if (thisDiff->operation == EQUAL) { + // Equality found. + if (thisDiff->text.size() < Diff_EditCost && (post_ins || post_del)) { + // Candidate found. + equalities.push_back(thisDiff); + pre_ins = post_ins; + pre_del = post_del; + last_equality = thisDiff->text; + has_last_equality = true; + } else { + // Not a candidate, and can never become one. + equalities.clear(); + has_last_equality = false; + safeDiff = thisDiff; + } + post_ins = post_del = false; + ++thisDiff; + } else { + // An insertion or deletion. + if (thisDiff->operation == DELETE) { + post_del = true; + } else { + post_ins = true; + } + /* + * Five types to be split: + * ABXYCD + * AXCD + * ABXC + * AXCD + * ABXC + */ + if (has_last_equality && + ((pre_ins && pre_del && post_ins && post_del) || + ((last_equality.size() < Diff_EditCost / 2) && + ((pre_ins ? 1 : 0) + (pre_del ? 1 : 0) + (post_ins ? 1 : 0) + + (post_del ? 1 : 0)) == 3))) { + // printf("Splitting: '%s'\n", qPrintable(last_equality)); + // Walk back to offending equality. + thisDiff = equalities.back(); + + // Replace equality with a delete. + *thisDiff = Diff(DELETE, last_equality); + // Insert a corresponding an insert. + auto it = thisDiff; + ++it; + thisDiff = diffs.insert(it, Diff(INSERT, last_equality)); + + equalities.pop_back(); // Throw away the equality we just deleted. + has_last_equality = false; + if (pre_ins && pre_del) { + // No changes made which could affect previous entry, keep going. + post_ins = post_del = true; + equalities.clear(); + safeDiff = thisDiff; + ++thisDiff; + } else { + if (!equalities.empty()) { + // Throw away the previous equality (it needs to be reevaluated). + equalities.pop_back(); + } + if (equalities.empty()) { + // There are no previous questionable equalities, + // walk back to the last known safe diff. + thisDiff = safeDiff; + } else { + // There is an equality we can fall back to. + thisDiff = equalities.back(); + } + post_ins = post_del = false; + } + + changes = true; + } else { + ++thisDiff; + } + } + } + + if (changes) { + diff_cleanupMerge(diffs); + } +} + +void diff_match_patch::diff_cleanupMerge(std::list &diffs) { + diffs.push_back(Diff(EQUAL, L"")); // Add a dummy entry at the end. + std::size_t count_delete = 0; + std::size_t count_insert = 0; + std::wstring text_delete = L""; + std::wstring text_insert = L""; + Diff *prevEqual = NULL; + std::size_t commonsize; + for (auto thisDiff = diffs.begin(); thisDiff != diffs.end(); ++thisDiff) { + switch (thisDiff->operation) { + case INSERT: + count_insert++; + text_insert += thisDiff->text; + prevEqual = NULL; + break; + case DELETE: + count_delete++; + text_delete += thisDiff->text; + prevEqual = NULL; + break; + case EQUAL: + if (count_delete + count_insert > 1) { + bool both_types = count_delete != 0 && count_insert != 0; + // Delete the offending records. + auto it = thisDiff; + while (count_delete-- > 0) { + --it; + it = diffs.erase(it); + } + while (count_insert-- > 0) { + --it; + it = diffs.erase(it); + } + if (both_types) { + // Factor out any common prefixies. + commonsize = diff_commonPrefix(text_insert, text_delete); + if (commonsize != 0) { + if (it != diffs.begin()) { + --it; + if (it->operation != EQUAL) { + throw "Previous diff should have been an equality."; + } + it->text += text_insert.substr(0, commonsize); + ++it; + } else { + diffs.insert(it, + Diff(EQUAL, text_insert.substr(0, commonsize))); + } + text_insert = safeSubStr(text_insert, commonsize); + text_delete = safeSubStr(text_delete, commonsize); + } + // Factor out any common suffixies. + commonsize = diff_commonSuffix(text_insert, text_delete); + if (commonsize != 0) { + thisDiff->text = + safeSubStr(text_insert, text_insert.size() - commonsize) + + thisDiff->text; + text_insert = + text_insert.substr(0, text_insert.size() - commonsize); + text_delete = + text_delete.substr(0, text_delete.size() - commonsize); + } + } + // Insert the merged records. + if (!text_delete.empty()) { + diffs.insert(thisDiff, Diff(DELETE, text_delete)); + } + if (!text_insert.empty()) { + diffs.insert(thisDiff, Diff(INSERT, text_insert)); + } + } else if (prevEqual != NULL) { + // Merge this equality with the previous one. + prevEqual->text += thisDiff->text; + thisDiff = diffs.erase(thisDiff); + --thisDiff; + } + count_insert = 0; + count_delete = 0; + text_delete = L""; + text_insert = L""; + prevEqual = &(*thisDiff); + break; + } + } + if (diffs.back().text.empty()) { + diffs.pop_back(); // Remove the dummy entry at the end. + } + + /* + * Second pass: look for single edits surrounded on both sides by equalities + * which can be shifted sideways to eliminate an equality. + * e.g: ABAC -> ABAC + */ + bool changes = false; + // Create a new iterator at the start. + // (As opposed to walking the current one back.) + auto thisDiff = diffs.begin(); + auto prevDiff = (thisDiff != diffs.end()) ? thisDiff++ : diffs.end(); + auto nextDiff = thisDiff; + if (nextDiff != diffs.end()) ++nextDiff; + + // Intentionally ignore the first and last element (don't need checking). + while (nextDiff != diffs.end()) { + if (prevDiff->operation == EQUAL && nextDiff->operation == EQUAL) { + // This is a single edit surrounded by equalities. + if (EndsWith(thisDiff->text, prevDiff->text)) { + // Shift the edit over the previous equality. + thisDiff->text = prevDiff->text + + thisDiff->text.substr( + 0, thisDiff->text.size() - prevDiff->text.size()); + nextDiff->text = prevDiff->text + nextDiff->text; + // Delete prevDiff. + diffs.erase(prevDiff); + ++thisDiff; + ++nextDiff; + changes = true; + } else if (StartsWith(thisDiff->text, nextDiff->text)) { + // Shift the edit over the next equality. + prevDiff->text += nextDiff->text; + thisDiff->text = + safeSubStr(thisDiff->text, nextDiff->text.size()) + nextDiff->text; + nextDiff = diffs.erase(nextDiff); + changes = true; + } + } + prevDiff = thisDiff; + thisDiff = nextDiff; + if (nextDiff != diffs.end()) ++nextDiff; + } + // If shifts were made, the diff needs reordering and another shift sweep. + if (changes) { + diff_cleanupMerge(diffs); + } +} + +std::size_t diff_match_patch::diff_xIndex(const std::list &diffs, + std::size_t loc) { + std::size_t chars1 = 0; + std::size_t chars2 = 0; + std::size_t last_chars1 = 0; + std::size_t last_chars2 = 0; + Diff lastDiff; + for (const auto &aDiff : diffs) { + if (aDiff.operation != INSERT) { + // Equality or deletion. + chars1 += aDiff.text.size(); + } + if (aDiff.operation != DELETE) { + // Equality or insertion. + chars2 += aDiff.text.size(); + } + if (chars1 > loc) { + // Overshot the location. + lastDiff = aDiff; + break; + } + last_chars1 = chars1; + last_chars2 = chars2; + } + if (lastDiff.operation == DELETE) { + // The location was deleted. + return last_chars2; + } + // Add the remaining character size. + return last_chars2 + (loc - last_chars1); +} + +std::string diff_match_patch::diff_prettyHtml(const std::list &diffs) { + UnicodeEncoder unicode_encoder; + return unicode_encoder.to_bytes(diff_widePrettyHtml(diffs)); +} + +std::wstring diff_match_patch::diff_widePrettyHtml( + const std::list &diffs) { + std::wstring html; + std::wstring text; + for (const auto &aDiff : diffs) { + text = aDiff.text; + ReplaceAll(text, L'&', L"&"); + ReplaceAll(text, L'<', L"<"); + ReplaceAll(text, L'>', L">"); + ReplaceAll(text, L'\n', L"¶
"); + switch (aDiff.operation) { + case INSERT: + html += L"" + text + L""; + break; + case DELETE: + html += L"" + text + L""; + break; + case EQUAL: + html += L"" + text + L""; + break; + } + } + return html; +} + +std::string diff_match_patch::diff_text1(const std::list &diffs) { + UnicodeEncoder unicode_encoder; + return unicode_encoder.to_bytes(diff_wideText1(diffs)); +} + +std::wstring diff_match_patch::diff_wideText1(const std::list &diffs) { + std::wstring text; + for (const auto &aDiff : diffs) { + if (aDiff.operation != INSERT) { + text += aDiff.text; + } + } + return text; +} + +std::string diff_match_patch::diff_text2(const std::list &diffs) { + UnicodeEncoder unicode_encoder; + return unicode_encoder.to_bytes(diff_wideText2(diffs)); +} + +std::wstring diff_match_patch::diff_wideText2(const std::list &diffs) { + std::wstring text; + for (const auto &aDiff : diffs) { + if (aDiff.operation != DELETE) { + text += aDiff.text; + } + } + return text; +} + +std::size_t diff_match_patch::diff_levenshtein(const std::list &diffs) { + std::size_t levenshtein = 0; + std::size_t insertions = 0; + std::size_t deletions = 0; + for (const auto &aDiff : diffs) { + switch (aDiff.operation) { + case INSERT: + insertions += aDiff.text.size(); + break; + case DELETE: + deletions += aDiff.text.size(); + break; + case EQUAL: + // A deletion and an insertion is one substitution. + levenshtein += std::max(insertions, deletions); + insertions = 0; + deletions = 0; + break; + } + } + levenshtein += std::max(insertions, deletions); + return levenshtein; +} + +std::string diff_match_patch::diff_toDelta(const std::list &diffs) { + UnicodeEncoder unicode_encoder; + return unicode_encoder.to_bytes(diff_toWideDelta(diffs)); +} + +std::wstring diff_match_patch::diff_toWideDelta(const std::list &diffs) { + std::wstringstream text; + for (const auto &aDiff : diffs) { + switch (aDiff.operation) { + case INSERT: { + text << L'+' << URLEncode(aDiff.text, L" !~*'();/?:@&=+$,#") << L'\t'; + break; + } + case DELETE: + text << L'-' << aDiff.text.size() << '\t'; + break; + case EQUAL: + text << L'=' << aDiff.text.size() << L'\t'; + break; + } + } + const auto &res = text.str(); + if (!res.empty()) { + // Strip off trailing tab character. + return res.substr(0, res.size() - 1); + } + return res; +} + +std::list diff_match_patch::diff_fromDelta(const std::string &text1, + const std::string &delta) { + UnicodeEncoder unicode_encoder; + return diff_fromDelta(unicode_encoder.from_bytes(text1), + unicode_encoder.from_bytes(delta)); +} + +std::list diff_match_patch::diff_fromDelta(const std::wstring &text1, + const std::wstring &delta) { + std::list diffs; + std::size_t pointer = 0; // Cursor in text1 + std::vector tokens; + Split(delta, '\t', tokens); + for (const auto &token : tokens) { + if (token.empty()) { + // Blank tokens are ok (from a trailing \t). + continue; + } + // Each token begins with a one character parameter which specifies the + // operation of this token (delete, insert, equality). + std::wstring param = safeSubStr(token, 1); + switch (token[0]) { + case L'+': + param = URLDecode(param); + diffs.push_back(Diff(INSERT, param)); + break; + case L'-': + // Fall through. + case L'=': { + int64_t n = AsInt64(param); + if (n < 0) { + UnicodeEncoder unicode_encoder; + throw "Negative number in diff_fromDelta: " + + unicode_encoder.to_bytes(param); + } + std::wstring text; + text = safeSubStr(text1, pointer, n); + pointer += n; + if (token[0] == L'=') { + diffs.push_back(Diff(EQUAL, text)); + } else { + diffs.push_back(Diff(DELETE, text)); + } + break; + } + default: { + UnicodeEncoder unicode_encoder; + throw "Invalid diff operation in diff_fromDelta: " + + unicode_encoder.to_bytes(std::wstring(1, token[0])); + } + } + } + if (pointer != text1.size()) { + throw "Delta size (" + AsString(pointer) + + ") smaller than source text size (" + AsString(text1.size()) + ")"; + } + return diffs; +} + +// MATCH FUNCTIONS + +std::size_t diff_match_patch::match_main(const std::string &text, + const std::string &pattern, + std::size_t loc) { + UnicodeEncoder unicode_encoder; + return match_main(unicode_encoder.from_bytes(text), + unicode_encoder.from_bytes(pattern), loc); +} + +std::size_t diff_match_patch::match_main(const std::wstring &text, + const std::wstring &pattern, + std::size_t loc) { + loc = std::max(0UL, (unsigned long) std::min(loc, text.size())); + if (text == pattern) { + // Shortcut (potentially not guaranteed by the algorithm) + return 0; + } else if (text.empty()) { + // Nothing to match. + return std::wstring::npos; + } else if (loc + pattern.size() <= text.size() && + safeSubStr(text, loc, pattern.size()) == pattern) { + // Perfect match at the perfect spot! (Includes case of null pattern) + return loc; + } else { + // Do a fuzzy compare. + return match_bitap(text, pattern, loc); + } +} + +std::size_t diff_match_patch::match_bitap(const std::wstring &text, + const std::wstring &pattern, + std::size_t loc) { + if (!(Match_MaxBits == 0 || pattern.size() <= Match_MaxBits)) { + throw "Pattern too long for this application."; + } + + // Initialise the alphabet. + auto s = match_alphabet(pattern); + + // Highest score beyond which we give up. + double score_threshold = Match_Threshold; + // Is there a nearby exact match? (speedup) + std::size_t best_loc = text.find(pattern, loc); + if (best_loc != std::wstring::npos) { + score_threshold = + std::min(match_bitapScore(0, best_loc, loc, pattern), score_threshold); + // What about in the other direction? (speedup) + best_loc = text.rfind(pattern, loc + pattern.size()); + if (best_loc != std::wstring::npos) { + score_threshold = std::min(match_bitapScore(0, best_loc, loc, pattern), + score_threshold); + } + } + + // Initialise the bit arrays. + std::size_t matchmask = 1 << (pattern.size() - 1); + best_loc = std::wstring::npos; + + std::size_t bin_min, bin_mid; + std::size_t bin_max = pattern.size() + text.size(); + std::unique_ptr rd; + std::unique_ptr last_rd = NULL; + for (std::size_t d = 0; d < pattern.size(); d++) { + // Scan for the best match; each iteration allows for one more error. + // Run a binary search to determine how far from 'loc' we can stray at + // this error level. + bin_min = 0; + bin_mid = bin_max; + while (bin_min < bin_mid) { + if (match_bitapScore(d, loc + bin_mid, loc, pattern) <= score_threshold) { + bin_min = bin_mid; + } else { + bin_max = bin_mid; + } + bin_mid = (bin_max - bin_min) / 2 + bin_min; + } + // Use the result from this iteration as the maximum for the next. + bin_max = bin_mid; + std::size_t start = std::max(1, (int64_t)loc - bin_mid + 1); + std::size_t finish = std::min(loc + bin_mid, text.size()) + pattern.size(); + + rd.reset(new std::size_t[finish + 2]); + rd[finish + 1] = (1 << d) - 1; + for (std::size_t j = finish; j >= start; j--) { + std::size_t charMatch; + if (text.size() <= j - 1) { + // Out of range. + charMatch = 0; + } else { + charMatch = s[text[j - 1]]; + } + if (d == 0) { + // First pass: exact match. + rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; + } else { + // Subsequent passes: fuzzy match. + rd[j] = (((rd[j + 1] << 1) | 1) & charMatch) | + (((last_rd[j + 1] | last_rd[j]) << 1) | 1) | last_rd[j + 1]; + } + if ((rd[j] & matchmask) != 0) { + double score = match_bitapScore(d, j - 1, loc, pattern); + // This match will almost certainly be better than any existing + // match. But check anyway. + if (score <= score_threshold) { + // Told you so. + score_threshold = score; + best_loc = j - 1; + if (best_loc > loc) { + // When passing loc, don't exceed our current distance from loc. + start = std::max(1, 2 * (int64_t)loc - best_loc); + } else { + // Already passed loc, downhill from here on in. + break; + } + } + } + } + if (match_bitapScore(d + 1, loc, loc, pattern) > score_threshold) { + // No hope for a (better) match at greater error levels. + break; + } + last_rd = std::move(rd); + } + return best_loc; +} + +double diff_match_patch::match_bitapScore(std::size_t e, std::size_t x, + std::size_t loc, + const std::wstring &pattern) { + const float accuracy = static_cast(e) / pattern.size(); + const std::size_t proximity = (loc > x) ? (loc - x) : x - loc; + if (Match_Distance == 0) { + // Dodge divide by zero error. + return proximity == 0 ? accuracy : 1.0; + } + return accuracy + (proximity / static_cast(Match_Distance)); +} + +std::unordered_map diff_match_patch::match_alphabet( + const std::wstring &pattern) { + std::unordered_map s; + std::size_t i; + for (auto c : pattern) { + s.emplace(c, 0); + } + std::size_t mask = 1 << (pattern.size() - 1); + for (auto c : pattern) { + s[c] |= mask; + mask >>= 1; + } + return s; +} + +// PATCH FUNCTIONS + +void diff_match_patch::patch_addContext(Patch &patch, + const std::wstring &text) { + if (text.empty()) { + return; + } + std::wstring pattern = safeSubStr(text, patch.start2, patch.size1); + std::size_t padding = 0; + + // Look for the first and last matches of pattern in text. If two different + // matches are found, increase the pattern size. + while (text.find(pattern) != text.rfind(pattern) && + pattern.size() < Match_MaxBits - Patch_Margin - Patch_Margin) { + padding += Patch_Margin; + std::size_t offset = patch.start2 > padding ? patch.start2 - padding : 0; + pattern = safeSubStr( + text, offset, + std::min(text.size(), patch.start2 + patch.size1 + padding) - offset); + } + // Add one chunk for good luck. + padding += Patch_Margin; + + // Add the prefix. + auto offset = patch.start2 > padding ? patch.start2 - padding : 0; + std::wstring prefix = safeSubStr(text, offset, patch.start2 - offset); + if (!prefix.empty()) { + patch.diffs.push_front(Diff(EQUAL, prefix)); + } + // Add the suffix. + std::wstring suffix = + safeSubStr(text, patch.start2 + patch.size1, + std::min(text.size(), patch.start2 + patch.size1 + padding) - + (patch.start2 + patch.size1)); + if (!suffix.empty()) { + patch.diffs.push_back(Diff(EQUAL, suffix)); + } + + // Roll back the start points. + patch.start1 -= prefix.size(); + patch.start2 -= prefix.size(); + // Extend the sizes. + patch.size1 += prefix.size() + suffix.size(); + patch.size2 += prefix.size() + suffix.size(); +} + +std::list diff_match_patch::patch_make(const std::string &text1, + const std::string &text2) { + UnicodeEncoder unicode_encoder; + return patch_make(unicode_encoder.from_bytes(text1), + unicode_encoder.from_bytes(text2)); +} + +std::list diff_match_patch::patch_make(const std::wstring &text1, + const std::wstring &text2) { + // No diffs provided, compute our own. + std::list diffs = diff_main(text1, text2, true); + if (diffs.size() > 2) { + diff_cleanupSemantic(diffs); + diff_cleanupEfficiency(diffs); + } + + return patch_make(text1, diffs); +} + +std::list diff_match_patch::patch_make(const std::list &diffs) { + // No origin string provided, compute our own. + const std::wstring text1 = diff_wideText1(diffs); + return patch_make(text1, diffs); +} + +std::list diff_match_patch::patch_make(const std::string &text1, + const std::string & /*text2*/, + const std::list &diffs) { + // text2 is entirely unused. + UnicodeEncoder unicode_encoder; + return patch_make(unicode_encoder.from_bytes(text1), diffs); +} + +std::list diff_match_patch::patch_make(const std::wstring &text1, + const std::wstring & /*text2*/, + const std::list &diffs) { + // text2 is entirely unused. + return patch_make(text1, diffs); +} + +std::list diff_match_patch::patch_make(const std::string &text1, + const std::list &diffs) { + UnicodeEncoder unicode_encoder; + return patch_make(unicode_encoder.from_bytes(text1), diffs); +} + +std::list diff_match_patch::patch_make(const std::wstring &text1, + const std::list &diffs) { + std::list patches; + if (diffs.empty()) { + return patches; // Get rid of the null case. + } + Patch patch; + std::size_t char_count1 = 0; // Number of characters into the text1 string. + std::size_t char_count2 = 0; // Number of characters into the text2 string. + // Start with text1 (prepatch_text) and apply the diffs until we arrive at + // text2 (postpatch_text). We recreate the patches one by one to determine + // context info. + std::wstring prepatch_text = text1; + std::wstring postpatch_text = text1; + for (const auto &aDiff : diffs) { + if (patch.diffs.empty() && aDiff.operation != EQUAL) { + // A new patch starts here. + patch.start1 = char_count1; + patch.start2 = char_count2; + } + + switch (aDiff.operation) { + case INSERT: + patch.diffs.push_back(aDiff); + patch.size2 += aDiff.text.size(); + postpatch_text = postpatch_text.substr(0, char_count2) + aDiff.text + + safeSubStr(postpatch_text, char_count2); + break; + case DELETE: + patch.size1 += aDiff.text.size(); + patch.diffs.push_back(aDiff); + postpatch_text = + postpatch_text.substr(0, char_count2) + + safeSubStr(postpatch_text, char_count2 + aDiff.text.size()); + break; + case EQUAL: + if (aDiff.text.size() <= 2 * Patch_Margin && !patch.diffs.empty() && + !(aDiff == diffs.back())) { + // Small equality inside a patch. + patch.diffs.push_back(aDiff); + patch.size1 += aDiff.text.size(); + patch.size2 += aDiff.text.size(); + } + + if (aDiff.text.size() >= 2 * Patch_Margin) { + // Time for a new patch. + if (!patch.diffs.empty()) { + patch_addContext(patch, prepatch_text); + patches.push_back(patch); + patch = Patch(); + // Unlike Unidiff, our patch lists have a rolling context. + // http://code.google.com/p/google-diff-match-patch/wiki/Unidiff + // Update prepatch text & pos to reflect the application of the + // just completed patch. + prepatch_text = postpatch_text; + char_count1 = char_count2; + } + } + break; + } + + // Update the current character count. + if (aDiff.operation != INSERT) { + char_count1 += aDiff.text.size(); + } + if (aDiff.operation != DELETE) { + char_count2 += aDiff.text.size(); + } + } + // Pick up the leftover patch if not empty. + if (!patch.diffs.empty()) { + patch_addContext(patch, prepatch_text); + patches.push_back(patch); + } + + return patches; +} + +std::list diff_match_patch::patch_deepCopy( + const std::list &patches) { + std::list patchesCopy; + for (const auto &aPatch : patches) { + Patch patchCopy = Patch(); + for (const auto &aDiff : aPatch.diffs) { + Diff diffCopy = Diff(aDiff.operation, aDiff.text); + patchCopy.diffs.push_back(diffCopy); + } + patchCopy.start1 = aPatch.start1; + patchCopy.start2 = aPatch.start2; + patchCopy.size1 = aPatch.size1; + patchCopy.size2 = aPatch.size2; + patchesCopy.push_back(patchCopy); + } + return patchesCopy; +} + +std::pair > diff_match_patch::patch_apply( + const std::list &patches, const std::string &text) { + UnicodeEncoder unicode_encoder; + auto wide_result = patch_apply(patches, unicode_encoder.from_bytes(text)); + return std::make_pair(unicode_encoder.to_bytes(wide_result.first), + wide_result.second); +} + +std::pair > diff_match_patch::patch_apply( + const std::list &patches, const std::wstring &sourceText) { + std::wstring text = sourceText; // Copy to preserve original. + if (patches.empty()) { + return std::pair >(text, + std::vector(0)); + } + + // Deep copy the patches so that no changes are made to originals. + auto patchesCopy = patch_deepCopy(patches); + + std::wstring nullPadding = patch_addWidePadding(patchesCopy); + text = nullPadding + text + nullPadding; + patch_splitMax(patchesCopy); + + std::size_t x = 0; + // delta keeps track of the offset between the expected and actual location + // of the previous patch. If there are patches expected at positions 10 and + // 20, but the first patch was found at 12, delta is 2 and the second patch + // has an effective expected position of 22. + std::size_t delta = 0; + std::vector results(patchesCopy.size()); + for (const auto &aPatch : patchesCopy) { + std::size_t expected_loc = aPatch.start2 + delta; + std::wstring text1 = diff_wideText1(aPatch.diffs); + std::size_t start_loc; + std::size_t end_loc = std::wstring::npos; + if (text1.size() > Match_MaxBits) { + // patch_splitMax will only provide an oversized pattern in the case of + // a monster delete. + start_loc = + match_main(text, text1.substr(0, Match_MaxBits), expected_loc); + if (start_loc != std::wstring::npos) { + end_loc = match_main(text, text1.substr(text1.size() - Match_MaxBits), + expected_loc + text1.size() - Match_MaxBits); + if (end_loc == std::wstring::npos || start_loc >= end_loc) { + // Can't find valid trailing context. Drop this patch. + start_loc = std::wstring::npos; + } + } + } else { + start_loc = match_main(text, text1, expected_loc); + } + if (start_loc == std::wstring::npos) { + // No match found. :( + results[x] = false; + // Subtract the delta for this failed patch from subsequent patches. + delta -= aPatch.size2 - aPatch.size1; + } else { + // Found a match. :) + results[x] = true; + delta = start_loc - expected_loc; + std::wstring text2; + if (end_loc == std::wstring::npos) { + text2 = safeSubStr(text, start_loc, text1.size()); + } else { + text2 = + safeSubStr(text, start_loc, end_loc + Match_MaxBits - start_loc); + } + if (text1 == text2) { + // Perfect match, just shove the replacement text in. + text = text.substr(0, start_loc) + diff_wideText2(aPatch.diffs) + + safeSubStr(text, start_loc + text1.size()); + } else { + // Imperfect match. Run a diff to get a framework of equivalent + // indices. + std::list diffs = diff_main(text1, text2, false); + if (text1.size() > Match_MaxBits && + diff_levenshtein(diffs) / static_cast(text1.size()) > + Patch_DeleteThreshold) { + // The end points match, but the content is unacceptably bad. + results[x] = false; + } else { + diff_cleanupSemanticLossless(diffs); + std::size_t index1 = 0; + for (const auto &aDiff : aPatch.diffs) { + if (aDiff.operation != EQUAL) { + std::size_t index2 = diff_xIndex(diffs, index1); + if (aDiff.operation == INSERT) { + // Insertion + text = text.substr(0, start_loc + index2) + aDiff.text + + safeSubStr(text, start_loc + index2); + } else if (aDiff.operation == DELETE) { + // Deletion + text = text.substr(0, start_loc + index2) + + safeSubStr( + text, + start_loc + + diff_xIndex(diffs, index1 + aDiff.text.size())); + } + } + if (aDiff.operation != DELETE) { + index1 += aDiff.text.size(); + } + } + } + } + } + x++; + } + // Strip the padding off. + text = safeSubStr(text, nullPadding.size(), + text.size() - 2 * nullPadding.size()); + return std::pair >(text, results); +} + +std::string diff_match_patch::patch_addPadding(std::list &patches) { + UnicodeEncoder unicode_encoder; + return unicode_encoder.to_bytes(patch_addWidePadding(patches)); +} + +std::wstring diff_match_patch::patch_addWidePadding(std::list &patches) { + short paddingLength = Patch_Margin; + std::wstring nullPadding = L""; + for (short x = 1; x <= paddingLength; x++) { + nullPadding += wchar_t((ushort)x); + } + + // Bump all the patches forward. + for (auto &patch : patches) { + patch.start1 += paddingLength; + patch.start2 += paddingLength; + } + + // Add some padding on start of first diff. + Patch &firstPatch = patches.front(); + std::list &firstPatchDiffs = firstPatch.diffs; + if (firstPatchDiffs.empty() || firstPatchDiffs.front().operation != EQUAL) { + // Add nullPadding equality. + firstPatchDiffs.push_front(Diff(EQUAL, nullPadding)); + firstPatch.start1 -= paddingLength; // Should be 0. + firstPatch.start2 -= paddingLength; // Should be 0. + firstPatch.size1 += paddingLength; + firstPatch.size2 += paddingLength; + } else if (paddingLength > firstPatchDiffs.front().text.size()) { + // Grow first equality. + Diff &firstDiff = firstPatchDiffs.front(); + std::size_t extraLength = paddingLength - firstDiff.text.size(); + firstDiff.text = safeSubStr(nullPadding, firstDiff.text.size(), + paddingLength - firstDiff.text.size()) + + firstDiff.text; + firstPatch.start1 -= extraLength; + firstPatch.start2 -= extraLength; + firstPatch.size1 += extraLength; + firstPatch.size2 += extraLength; + } + + // Add some padding on end of last diff. + Patch &lastPatch = patches.front(); + std::list &lastPatchDiffs = lastPatch.diffs; + if (lastPatchDiffs.empty() || lastPatchDiffs.back().operation != EQUAL) { + // Add nullPadding equality. + lastPatchDiffs.push_back(Diff(EQUAL, nullPadding)); + lastPatch.size1 += paddingLength; + lastPatch.size2 += paddingLength; + } else if (paddingLength > lastPatchDiffs.back().text.size()) { + // Grow last equality. + Diff &lastDiff = lastPatchDiffs.back(); + std::size_t extraLength = paddingLength - lastDiff.text.size(); + lastDiff.text += nullPadding.substr(0, extraLength); + lastPatch.size1 += extraLength; + lastPatch.size2 += extraLength; + } + + return nullPadding; +} + +void diff_match_patch::patch_splitMax(std::list &patches) { + short patch_size = Match_MaxBits; + std::wstring precontext, postcontext; + Patch patch; + std::size_t start1, start2; + bool empty; + Operation diff_type; + std::wstring diff_text; + auto bigpatch = patches.begin(); + for (; bigpatch != patches.end();) { + if (bigpatch->size1 <= patch_size) { + ++bigpatch; + continue; + } + // Remove the big old patch. + start1 = bigpatch->start1; + start2 = bigpatch->start2; + precontext = L""; + while (!bigpatch->diffs.empty()) { + // Create one of several smaller patches. + patch = Patch(); + empty = true; + patch.start1 = start1 - precontext.size(); + patch.start2 = start2 - precontext.size(); + if (!precontext.empty()) { + patch.size1 = patch.size2 = precontext.size(); + patch.diffs.push_back(Diff(EQUAL, precontext)); + } + while (!bigpatch->diffs.empty() && + patch.size1 < patch_size - Patch_Margin) { + diff_type = bigpatch->diffs.front().operation; + diff_text = bigpatch->diffs.front().text; + if (diff_type == INSERT) { + // Insertions are harmless. + patch.size2 += diff_text.size(); + start2 += diff_text.size(); + patch.diffs.push_back(bigpatch->diffs.front()); + bigpatch->diffs.pop_front(); + empty = false; + } else if (diff_type == DELETE && patch.diffs.size() == 1 && + patch.diffs.front().operation == EQUAL && + diff_text.size() > 2 * patch_size) { + // This is a large deletion. Let it pass in one chunk. + patch.size1 += diff_text.size(); + start1 += diff_text.size(); + empty = false; + patch.diffs.push_back(Diff(diff_type, diff_text)); + bigpatch->diffs.pop_front(); + } else { + // Deletion or equality. Only take as much as we can stomach. + diff_text = diff_text.substr( + 0, std::min(diff_text.size(), + patch_size - patch.size1 - Patch_Margin)); + patch.size1 += diff_text.size(); + start1 += diff_text.size(); + if (diff_type == EQUAL) { + patch.size2 += diff_text.size(); + start2 += diff_text.size(); + } else { + empty = false; + } + patch.diffs.push_back(Diff(diff_type, diff_text)); + if (diff_text == bigpatch->diffs.front().text) { + bigpatch->diffs.pop_front(); + } else { + bigpatch->diffs.front().text = + safeSubStr(bigpatch->diffs.front().text, diff_text.size()); + } + } + } + // Compute the head context for the next patch. + precontext = diff_wideText2(patch.diffs); + precontext = safeSubStr(precontext, precontext.size() - Patch_Margin); + // Append the end context for this patch. + if (diff_wideText1(bigpatch->diffs).size() > Patch_Margin) { + postcontext = diff_wideText1(bigpatch->diffs).substr(0, Patch_Margin); + } else { + postcontext = diff_wideText1(bigpatch->diffs); + } + if (!postcontext.empty()) { + patch.size1 += postcontext.size(); + patch.size2 += postcontext.size(); + if (!patch.diffs.empty() && patch.diffs.back().operation == EQUAL) { + patch.diffs.back().text += postcontext; + } else { + patch.diffs.push_back(Diff(EQUAL, postcontext)); + } + } + if (!empty) { + patches.insert(bigpatch, patch); + } + } + bigpatch = patches.erase(bigpatch); + } +} + +std::string diff_match_patch::patch_toText(const std::list &patches) { + UnicodeEncoder unicode_encoder; + return unicode_encoder.to_bytes(patch_toWideText(patches)); +} + +std::wstring diff_match_patch::patch_toWideText( + const std::list &patches) { + std::wstring text; + for (const auto &aPatch : patches) { + text += aPatch.toString(); + } + return text; +} + +std::list diff_match_patch::patch_fromText(const std::string &textline) { + UnicodeEncoder unicode_encoder; + return patch_fromText(unicode_encoder.from_bytes(textline)); +} + +std::list diff_match_patch::patch_fromText( + const std::wstring &textline) { + std::list patches; + if (textline.empty()) { + return patches; + } + std::deque text; + Split(textline, '\n', text); + Patch patch; + std::wregex patchHeader(L"^@@ -(\\d+),?(\\d*) \\+(\\d+),?(\\d*) @@$"); + wchar_t sign; + std::wstring line; + while (!text.empty()) { + if (text.front().empty()) { + text.pop_front(); + continue; + } + std::wsmatch matches; + if (!std::regex_match(text.front(), matches, patchHeader)) { + UnicodeEncoder unicode_encoder; + throw "Invalid patch string: " + unicode_encoder.to_bytes(text.front()); + } + + patch = Patch(); + patch.start1 = AsSizeT(matches[1].str()); + if (matches[2].length() == 0) { + patch.start1--; + patch.size1 = 1; + } else if (matches[2].str() == L"0") { + patch.size1 = 0; + } else { + patch.start1--; + patch.size1 = AsSizeT(matches[2].str()); + } + + patch.start2 = AsSizeT(matches[3].str()); + if (matches[4].length() == 0) { + patch.start2--; + patch.size2 = 1; + } else if (matches[4].str() == L"0") { + patch.size2 = 0; + } else { + patch.start2--; + patch.size2 = AsSizeT(matches[4].str()); + } + text.pop_front(); + + while (!text.empty()) { + if (text.front().empty()) { + text.pop_front(); + continue; + } + sign = text.front()[0]; + line = safeSubStr(text.front(), 1); + ReplaceAll(line, L'+', L"%2B"); // decode would change all "+" to " " + line = URLDecode(line); + if (sign == L'-') { + // Deletion. + patch.diffs.push_back(Diff(DELETE, line)); + } else if (sign == L'+') { + // Insertion. + patch.diffs.push_back(Diff(INSERT, line)); + } else if (sign == L' ') { + // Minor equality. + patch.diffs.push_back(Diff(EQUAL, line)); + } else if (sign == L'@') { + // Start of next patch. + break; + } else { + // WTF? + UnicodeEncoder unicode_encoder; + throw "Invalid patch mode '" + + unicode_encoder.to_bytes(std::wstring(1, sign)) + "' in: " + + unicode_encoder.to_bytes(line); + } + text.pop_front(); + } + + patches.push_back(patch); + } + return patches; +} diff --git a/utils/diff_match_patch.h b/utils/diff_match_patch.h new file mode 100644 index 0000000..1d5465a --- /dev/null +++ b/utils/diff_match_patch.h @@ -0,0 +1,700 @@ +/* + * Copyright 2008 Google Inc. All Rights Reserved. + * Author: fraser@google.com (Neil Fraser) + * Author: mikeslemmer@gmail.com (Mike Slemmer) + * Author: quentinfiard@gmail.com (Quentin Fiard) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Diff Match and Patch + * http://code.google.com/p/google-diff-match-patch/ + */ +#include "pgadmin3.h" + +#ifndef DIFF_MATCH_PATCH_H_ +#define DIFF_MATCH_PATCH_H_ + +#include +#include +#include +#include +#include +#include +#pragma once + +//#include "targetver.h" + +//#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +//#include +#include +#include +typedef unsigned short ushort; + +/* + * Functions for diff, match and patch. + * Computes the difference between two texts to create a patch. + * Applies the patch onto another text, allowing for errors. + * + * @author fraser@google.com (Neil Fraser) + * + * C++11 port by quentinfiard@gmail.com (Quentin Fiard) based + * on the Qt/C++ port by mikeslemmer@gmail.com (Mike Slemmer). + * + * Here is a trivial sample program which works properly when linked with this + * library: + * + + #include + #include "diff_match_patch.h" + int main(int argc, char **argv) { + diff_match_patch dmp; + std::string str1 = "First string in diff"; + std::string str2 = "Second string in diff"; + + auto patch = dmp.patch_toText(dmp.patch_make(str1, str2)); + auto out = dmp.patch_apply(dmp.patch_fromText(patch), str1); + std::string strResult = out.first; + + // here, strResult will equal str2 above. + return strResult != str2; + } + + */ + +/**- +* The data structure representing a diff is a Linked list of Diff objects: +* {Diff(Operation.DELETE, "Hello"), Diff(Operation.INSERT, "Goodbye"), +* Diff(Operation.EQUAL, " world.")} +* which means: delete "Hello", add "Goodbye" and keep " world." +*/ + +#if defined(DELETE) +#undef DELETE +#endif // DUMMYSTRUCTNAME + +enum Operation { DELETE, INSERT, EQUAL }; + +/** +* Class representing one diff operation. +*/ +class Diff { + public: + Operation operation; + // One of: INSERT, DELETE or EQUAL. + std::wstring text; + // The text associated with this diff operation. + + /** + * Constructor. Initializes the diff with the provided values. + * @param operation One of INSERT, DELETE or EQUAL. + * @param text The text being applied. + */ + Diff(Operation _operation, const std::wstring &_text); + Diff(); + inline bool isNull() const; + std::wstring toString() const; + bool operator==(const Diff &d) const; + bool operator!=(const Diff &d) const; + + static std::wstring strOperation(Operation op); +}; + +/** +* Class representing one patch operation. +*/ +class Patch { + public: + std::list diffs; + std::size_t start1; + std::size_t start2; + std::size_t size1; + std::size_t size2; + + /** + * Constructor. Initializes with an empty list of diffs. + */ + Patch(); + bool isNull() const; + std::wstring toString() const; +}; + +/** + * Class containing the diff, match and patch methods. + * Also contains the behaviour settings. + */ +class diff_match_patch { + friend class TestableDiffMatchPatch; + + public: + // Defaults. + // Set these on your diff_match_patch instance to override the defaults. + + // Number of seconds to map a diff before giving up (0 for infinity). + float Diff_Timeout; + // Cost of an empty edit operation in terms of edit characters. + short Diff_EditCost; + // At what point is no match declared (0.0 = perfection, 1.0 = very loose). + float Match_Threshold; + // How far to search for a match (0 = exact location, 1000+ = broad match). + // A match this many characters away from the expected location will add + // 1.0 to the score (0.0 is a perfect match). + int Match_Distance; + // When deleting a large block of text (over ~64 characters), how close does + // the contents have to match the expected contents. (0.0 = perfection, + // 1.0 = very loose). Note that Match_Threshold controls how closely the + // end points of a delete need to match. + float Patch_DeleteThreshold; + // Chunk size for context size. + short Patch_Margin; + + // The number of bits in an int. + short Match_MaxBits; + + private: + // Define some regex patterns for matching boundaries. + static std::wregex BLANKLINEEND; + static std::wregex BLANKLINESTART; + + public: + diff_match_patch(short Diff_EditCost_,float Match_Threshold_,int Match_Distance_); + + // DIFF FUNCTIONS + + /** + * Find the differences between two texts. + * Run a faster slightly less optimal diff. + * This method allows the 'checklines' of diff_main() to be optional. + * Most of the time checklines is wanted, so default to true. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @return Linked List of Diff objects. + */ + std::list diff_main(const std::wstring &text1, + const std::wstring &text2); + + /** + * Find the differences between two texts. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @param checklines Speedup flag. If false, then don't run a + * line-level diff first to identify the changed areas. + * If true, then run a faster slightly less optimal diff. + * @return Linked List of Diff objects. + */ + std::list diff_main(const std::wstring &text1, + const std::wstring &text2, bool checklines); + + /** + * Find the differences between two texts. Simplifies the problem by + * stripping any common prefix or suffix off the texts before diffing. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @param checklines Speedup flag. If false, then don't run a + * line-level diff first to identify the changed areas. + * If true, then run a faster slightly less optimal diff. + * @param deadline Time when the diff should be complete by. Used + * internally for recursive calls. Users should set DiffTimeout instead. + * @return Linked List of Diff objects. + */ + private: + std::list diff_main(const std::wstring &text1, + const std::wstring &text2, bool checklines, + clock_t deadline); + + /** + * Find the differences between two texts. Assumes that the texts do not + * have any common prefix or suffix. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @param checklines Speedup flag. If false, then don't run a + * line-level diff first to identify the changed areas. + * If true, then run a faster slightly less optimal diff. + * @param deadline Time when the diff should be complete by. + * @return Linked List of Diff objects. + */ + private: + std::list diff_compute(std::wstring text1, std::wstring text2, + bool checklines, clock_t deadline); + + /** + * Do a quick line-level diff on both strings, then rediff the parts for + * greater accuracy. + * This speedup can produce non-minimal diffs. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @param deadline Time when the diff should be complete by. + * @return Linked List of Diff objects. + */ + private: + std::list diff_lineMode(std::wstring text1, std::wstring text2, + clock_t deadline); + + /** + * Find the 'middle snake' of a diff, split the problem in two + * and return the recursively constructed diff. + * See Myers 1986 paper: An O(ND) Difference Algorithm and Its Variations. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @return Linked List of Diff objects. + */ + protected: + std::list diff_bisect(const std::wstring &text1, + const std::wstring &text2, clock_t deadline); + + /** + * Given the location of the 'middle snake', split the diff in two parts + * and recurse. + * @param text1 Old string to be diffed. + * @param text2 New string to be diffed. + * @param x Index of split point in text1. + * @param y Index of split point in text2. + * @param deadline Time at which to bail if not yet complete. + * @return LinkedList of Diff objects. + */ + private: + std::list diff_bisectSplit(const std::wstring &text1, + const std::wstring &text2, std::size_t x, + std::size_t y, clock_t deadline); + + /** + * Split two texts into a list of strings. Reduce the texts to a string of + * hashes where each Unicode character represents one line. + * @param text1 First string. + * @param text2 Second string. + * @return Three element Object array, containing the encoded text1, the + * encoded text2 and the List of unique strings. The zeroth element + * of the List of unique strings is intentionally blank. + */ + protected: + std::tuple > + diff_linesToChars(const std::wstring &text1, + const std::wstring &text2) const; // return elems 0 + // and 1 are + // std::wstring, elem 2 + // is std::vector + + /** + * Split a text into a list of strings. Reduce the texts to a string of + * hashes where each Unicode character represents one line. + * @param text String to encode. + * @param lineArray List of unique strings. + * @param lineHash Map of strings to indices. + * @return Encoded string. + */ + private: + std::wstring diff_linesToCharsMunge( + const std::wstring &text, std::vector &lineArray, + std::unordered_map &lineHash) const; + + /** + * Rehydrate the text in a diff from a string of line hashes to real lines of + * text. + * @param diffs LinkedList of Diff objects. + * @param lineArray List of unique strings. + */ + private: + void diff_charsToLines(std::list &diffs, + const std::vector &lineArray); + + /** + * Determine the common prefix of two strings. + * @param text1 First string. + * @param text2 Second string. + * @return The number of characters common to the start of each string. + */ + public: + std::size_t diff_commonPrefix(const std::wstring &text1, + const std::wstring &text2); + + /** + * Determine the common suffix of two strings. + * @param text1 First string. + * @param text2 Second string. + * @return The number of characters common to the end of each string. + */ + public: + std::size_t diff_commonSuffix(const std::wstring &text1, + const std::wstring &text2); + + /** + * Determine if the suffix of one string is the prefix of another. + * @param text1 First string. + * @param text2 Second string. + * @return The number of characters common to the end of the first + * string and the start of the second string. + */ + protected: + std::size_t diff_commonOverlap(const std::wstring &text1, + const std::wstring &text2); + + /** + * Do the two texts share a substring which is at least half the size of + * the longer text? + * This speedup can produce non-minimal diffs. + * @param text1 First string. + * @param text2 Second string. + * @return Five element String array, containing the prefix of text1, the + * suffix of text1, the prefix of text2, the suffix of text2 and the + * common middle. Or null if there was no match. + */ + protected: + std::vector diff_halfMatch(const std::wstring &text1, + const std::wstring &text2); + + /** + * Does a substring of shorttext exist within longtext such that the + * substring is at least half the size of longtext? + * @param longtext Longer string. + * @param shorttext Shorter string. + * @param i Start index of quarter size substring within longtext. + * @return Five element String array, containing the prefix of longtext, the + * suffix of longtext, the prefix of shorttext, the suffix of shorttext + * and the common middle. Or null if there was no match. + */ + private: + std::vector diff_halfMatchI(const std::wstring &longtext, + const std::wstring &shorttext, + std::size_t i); + + /** + * Reduce the number of edits by eliminating semantically trivial equalities. + * @param diffs LinkedList of Diff objects. + */ + public: + void diff_cleanupSemantic(std::list &diffs); + + /** + * Look for single edits surrounded on both sides by equalities + * which can be shifted sideways to align the edit to a word boundary. + * e.g: The cat came. -> The cat came. + * @param diffs LinkedList of Diff objects. + */ + public: + void diff_cleanupSemanticLossless(std::list &diffs); + + /** + * Given two strings, compute a score representing whether the internal + * boundary falls on logical boundaries. + * Scores range from 6 (best) to 0 (worst). + * @param one First string. + * @param two Second string. + * @return The score. + */ + private: + int diff_cleanupSemanticScore(const std::wstring &one, + const std::wstring &two); + + /** + * Reduce the number of edits by eliminating operationally trivial equalities. + * @param diffs LinkedList of Diff objects. + */ + public: + void diff_cleanupEfficiency(std::list &diffs); + + /** + * Reorder and merge like edit sections. Merge equalities. + * Any edit section can move as long as it doesn't cross an equality. + * @param diffs LinkedList of Diff objects. + */ + public: + void diff_cleanupMerge(std::list &diffs); + + /** + * loc is a location in text1, compute and return the equivalent location in + * text2. + * e.g. "The cat" vs "The big cat", 1->1, 5->8 + * @param diffs LinkedList of Diff objects. + * @param loc Location within text1. + * @return Location within text2. + */ + public: + std::size_t diff_xIndex(const std::list &diffs, std::size_t loc); + + /** + * Convert a Diff list into a pretty HTML report. + * @param diffs LinkedList of Diff objects. + * @return HTML representation. + */ + public: + std::string diff_prettyHtml(const std::list &diffs); + std::wstring diff_widePrettyHtml(const std::list &diffs); + + /** + * Compute and return the source text (all equalities and deletions). + * @param diffs LinkedList of Diff objects. + * @return Source text. + */ + public: + std::string diff_text1(const std::list &diffs); + std::wstring diff_wideText1(const std::list &diffs); + + /** + * Compute and return the destination text (all equalities and insertions). + * @param diffs LinkedList of Diff objects. + * @return Destination text. + */ + public: + std::string diff_text2(const std::list &diffs); + std::wstring diff_wideText2(const std::list &diffs); + + /** + * Compute the Levenshtein distance; the number of inserted, deleted or + * substituted characters. + * @param diffs LinkedList of Diff objects. + * @return Number of changes. + */ + public: + std::size_t diff_levenshtein(const std::list &diffs); + + /** + * Crush the diff into an encoded string which describes the operations + * required to transform text1 into text2. + * E.g. =3\t-2\t+ing -> Keep 3 chars, delete 2 chars, insert 'ing'. + * Operations are tab-separated. Inserted text is escaped using %xx notation. + * @param diffs Array of diff tuples. + * @return Delta text. + */ + public: + std::string diff_toDelta(const std::list &diffs); + std::wstring diff_toWideDelta(const std::list &diffs); + + /** + * Given the original text1, and an encoded string which describes the + * operations required to transform text1 into text2, compute the full diff. + * @param text1 Source string for the diff. + * @param delta Delta text. + * @return Array of diff tuples or null if invalid. + * @throws std::wstring If invalid input. + */ + public: + std::list diff_fromDelta(const std::string &text1, + const std::string &delta); + std::list diff_fromDelta(const std::wstring &text1, + const std::wstring &delta); + + // MATCH FUNCTIONS + + /** + * Locate the best instance of 'pattern' in 'text' near 'loc'. + * Returns std::wstring::npos if no match found. + * @param text The text to search. + * @param pattern The pattern to search for. + * @param loc The location to search around. + * @return Best match index or std::wstring::npos. + */ + public: + std::size_t match_main(const std::string &text, const std::string &pattern, + std::size_t loc); + std::size_t match_main(const std::wstring &text, const std::wstring &pattern, + std::size_t loc); + + /** + * Locate the best instance of 'pattern' in 'text' near 'loc' using the + * Bitap algorithm. Returns std::wstring::npos if no match found. + * @param text The text to search. + * @param pattern The pattern to search for. + * @param loc The location to search around. + * @return Best match index or std::wstring::npos. + */ + protected: + std::size_t match_bitap(const std::wstring &text, const std::wstring &pattern, + std::size_t loc); + + /** + * Compute and return the score for a match with e errors and x location. + * @param e Number of errors in match. + * @param x Location of match. + * @param loc Expected location of match. + * @param pattern Pattern being sought. + * @return Overall score for match (0.0 = good, 1.0 = bad). + */ + private: + double match_bitapScore(std::size_t e, std::size_t x, std::size_t loc, + const std::wstring &pattern); + + /** + * Initialise the alphabet for the Bitap algorithm. + * @param pattern The text to encode. + * @return Hash of character locations. + */ + protected: + std::unordered_map match_alphabet( + const std::wstring &pattern); + + // PATCH FUNCTIONS + + /** + * Increase the context until it is unique, + * but don't let the pattern expand beyond Match_MaxBits. + * @param patch The patch to grow. + * @param text Source text. + */ + protected: + void patch_addContext(Patch &patch, const std::wstring &text); + + /** + * Compute a list of patches to turn text1 into text2. + * A set of diffs will be computed. + * @param text1 Old text. + * @param text2 New text. + * @return LinkedList of Patch objects. + */ + public: + std::list patch_make(const std::wstring &text1, + const std::wstring &text2); + std::list patch_make(const std::string &text1, + const std::string &text2); + + /** + * Compute a list of patches to turn text1 into text2. + * text1 will be derived from the provided diffs. + * @param diffs Array of diff tuples for text1 to text2. + * @return LinkedList of Patch objects. + */ + public: + std::list patch_make(const std::list &diffs); + + /** + * Compute a list of patches to turn text1 into text2. + * text2 is ignored, diffs are the delta between text1 and text2. + * @param text1 Old text. + * @param text2 Ignored. + * @param diffs Array of diff tuples for text1 to text2. + * @return LinkedList of Patch objects. + * @deprecated Prefer patch_make(const std::wstring &text1, const + * std::list + * &diffs). + */ + public: + std::list patch_make(const std::string &text1, + const std::string &text2, + const std::list &diffs); + std::list patch_make(const std::wstring &text1, + const std::wstring &text2, + const std::list &diffs); + + /** + * Compute a list of patches to turn text1 into text2. + * text2 is not provided, diffs are the delta between text1 and text2. + * @param text1 Old text. + * @param diffs Array of diff tuples for text1 to text2. + * @return LinkedList of Patch objects. + */ + public: + std::list patch_make(const std::string &text1, + const std::list &diffs); + std::list patch_make(const std::wstring &text1, + const std::list &diffs); + + /** + * Given an array of patches, return another array that is identical. + * @param patches Array of patch objects. + * @return Array of patch objects. + */ + public: + std::list patch_deepCopy(const std::list &patches); + + /** + * Merge a set of patches onto the text. Return a patched text, as well + * as an array of true/false values indicating which patches were applied. + * @param patches Array of patch objects. + * @param text Old text. + * @return Two element Object array, containing the new text and an array of + * boolean values. + */ + public: + std::pair > patch_apply( + const std::list &patches, const std::wstring &text); + std::pair > patch_apply( + const std::list &patches, const std::string &text); + + /** + * Add some padding on text start and end so that edges can match something. + * Intended to be called only from within patch_apply. + * @param patches Array of patch objects. + * @return The padding string added to each side. + */ + public: + std::string patch_addPadding(std::list &patches); + std::wstring patch_addWidePadding(std::list &patches); + + /** + * Look through the patches and break up any which are longer than the + * maximum limit of the match algorithm. + * Intended to be called only from within patch_apply. + * @param patches LinkedList of Patch objects. + */ + public: + void patch_splitMax(std::list &patches); + + /** + * Take a list of patches and return a textual representation. + * @param patches List of Patch objects. + * @return Text representation of patches. + */ + public: + std::string patch_toText(const std::list &patches); + std::wstring patch_toWideText(const std::list &patches); + + /** + * Parse a textual representation of patches and return a List of Patch + * objects. + * @param textline Text representation of patches. + * @return List of Patch objects. + * @throws std::wstring If invalid input. + */ + public: + std::list patch_fromText(const std::wstring &textline); + std::list patch_fromText(const std::string &textline); + + /** + * A safer version of std::wstring.mid(pos). This one returns "" instead of + * null when the postion equals the string size. + * @param str String to take a substring from. + * @param pos Position to start the substring from. + * @return Substring. + */ + private: + static inline std::wstring safeSubStr(const std::wstring &str, + std::size_t pos) { + return (pos >= str.size()) ? std::wstring() : str.substr(pos); + } + + /** + * A safer version of std::wstring.mid(pos, len). This one returns "" instead + * of + * null when the postion equals the string size. + * @param str String to take a substring from. + * @param pos Position to start the substring from. + * @param len Length of substring. + * @return Substring. + */ + private: + static inline std::wstring safeSubStr(const std::wstring &str, + std::size_t pos, std::size_t len) { + return (pos == str.size()) ? std::wstring() : str.substr(pos, len); + } +}; + +#endif // DIFF_MATCH_PATCH_H_ diff --git a/utils/factory.cpp b/utils/factory.cpp new file mode 100644 index 0000000..d5fe6fe --- /dev/null +++ b/utils/factory.cpp @@ -0,0 +1,428 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// factory.cpp - Object classes factory +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" + +#include "ctl/ctlMenuToolbar.h" +#include "schema/pgCollection.h" +#include "frm/menu.h" + +// wxWindows headers +#include + +wxArrayPtrVoid *factoryArray = 0; + +#define FACTORY_OFFSET 100 + +pgaFactory::pgaFactory(const wxChar *tn, const wxChar *ns, const wxChar *nls, wxImage *img, wxImage *imgSm) +{ + if (!factoryArray) + factoryArray = new wxArrayPtrVoid; + id = factoryArray->GetCount() + FACTORY_OFFSET; + factoryArray->Add(this); + collectionFactory = 0; + smallIconId = -1; + typeName = (wxChar *)tn; + if (ns) + newString = (wxChar *)ns; + else + newString = typeName; + if (nls) + newLongString = (wxChar *)nls; + else + newLongString = newString; + metaType = PGM_UNKNOWN; + + if (img && img->IsOk()) + { + image = *img; + iconId = addIcon(img); + if (imgSm && imgSm->IsOk()) + smallIconId = addIcon(imgSm); + } + else + iconId = -1; +} + + +bool pgaFactory::WantSmallIcon() +{ +#ifdef __WXMSW__ + return true; +#else + return false; +#endif +} + +int pgaFactory::GetIconId() +{ + if (WantSmallIcon() && smallIconId >= 0) + return smallIconId; + + return iconId; +} + +pgaFactory *pgaFactory::GetFactory(int id) +{ + id -= FACTORY_OFFSET; + if (id >= 0 && id < (int)factoryArray->GetCount()) + return (pgaFactory *)factoryArray->Item(id);; + + return 0; +} + + +pgaFactory *pgaFactory::GetFactory(const wxString &name) +{ + int i; + pgaFactory *factory; + + for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++) + { + if (name.Matches(factory->GetTypeName())) + return factory; + } + return 0; +} + +pgaFactory *pgaFactory::GetFactoryByMetaType(const int type) +{ + int i; + pgaFactory *factory; + + for (i = FACTORY_OFFSET ; (factory = GetFactory(i)) != 0 ; i++) + { + if (factory->GetMetaType() == type) + return factory; + } + return 0; +} + + +#include "images/property.pngc" +#include "images/statistics.pngc" + +wxArrayPtrVoid *deferredImagesArray = 0; + +int pgaFactory::addIcon(wxImage *img) +{ + if (!imageList) + { + if (!deferredImagesArray) + { + //Setup the global imagelist + deferredImagesArray = new wxArrayPtrVoid; + + deferredImagesArray->Add(property_png_img); + deferredImagesArray->Add(statistics_png_img); + } + + deferredImagesArray->Add(img); + + return deferredImagesArray->GetCount() - 1; + } + else + { + wxBitmap bmp(*img); + wxIcon *ico = new wxIcon(); + ico->CopyFromBitmap(bmp); + return imageList->Add(*ico); + } +} + +void pgaFactory::RealizeImages() +{ + if (!imageList && deferredImagesArray) + { + imageList = new wxImageList(16, 16, true, deferredImagesArray->GetCount()); + size_t i; + for (i = 0 ; i < deferredImagesArray->GetCount() ; i++) + { + wxImage *img = (wxImage *)deferredImagesArray->Item(i); + wxBitmap bmp(*img); + wxIcon *ico = new wxIcon(); + ico->CopyFromBitmap(bmp); + imageList->Add(*ico); + } + + delete deferredImagesArray; + deferredImagesArray = 0; + } +} + +void pgaFactory::RegisterMenu(wxWindow *w, wxObjectEventFunction func) +{ + w->Connect(GetFactory(FACTORY_OFFSET)->GetId() + MNU_NEW, + GetFactory(factoryArray->GetCount() + FACTORY_OFFSET - 1)->GetId() + MNU_NEW, + wxEVT_COMMAND_MENU_SELECTED, func); +} + + +void pgaFactory::AppendMenu(wxMenu *menu) +{ + if (menu && GetNewString()) + { + wxMenuItem *item = menu->Append(MNU_NEW + GetId(), wxGetTranslation(GetNewString()), wxGetTranslation(GetNewLongString())); + if (image.IsOk()) + { + (void)item; + // doesn't work? + // item->SetBitmap(wxBitmap(image)); + } + } +} + + +int pgaFactory::GetMetaType() +{ + if (IsCollection()) + return ((pgaCollectionFactory *)this)->GetItemFactory()->GetMetaType(); + return metaType; +} + + +pgaCollectionFactory::pgaCollectionFactory(pgaFactory *f, const wxChar *tn, wxImage *img, wxImage *imgSm) + : pgaFactory(tn, f->GetNewString(), f->GetNewLongString()) +{ + itemFactory = f; + f->collectionFactory = this; + if (img && img->IsOk()) + { + image = *img; + iconId = addIcon(img); + if (imgSm && imgSm->IsOk()) + smallIconId = addIcon(imgSm); + } + else + iconId = f->GetIconId(); +} + + +pgObject *pgaCollectionFactory::CreateObjects(pgCollection *obj, ctlTree *browser, const wxString &restr) +{ + if (itemFactory) + return itemFactory->CreateObjects(obj, browser, restr); + return 0; +} + + +dlgProperty *pgaCollectionFactory::CreateDialog(frmMain *frame, pgObject *node, pgObject *parent) +{ + if (itemFactory) + return itemFactory->CreateDialog(frame, node, parent); + return 0; +} + + +//////////////////////////////////////////////// + + +menuFactoryList::~menuFactoryList() +{ + while (GetCount()) + { + delete (menuFactory *)Item(0); + RemoveAt(0); + } +} + +actionFactory *menuFactoryList::GetFactory(int id, bool actionOnly) +{ + id -= MNU_ACTION; + if (id >= 0 && id < (int)GetCount()) + { + actionFactory *f = (actionFactory *)Item(id); + if (f->IsAction() || !actionOnly) + return f; + } + return 0; +} + + +void menuFactoryList::RegisterMenu(wxWindow *w, wxObjectEventFunction func) +{ + w->Connect(MNU_ACTION, MNU_ACTION + GetCount() - 1, + wxEVT_COMMAND_MENU_SELECTED, func); +} + + +void menuFactoryList::CheckMenu(pgObject *obj, wxMenuBar *menubar, ctlMenuToolbar *toolbar) +{ + size_t id; + for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++) + { + actionFactory *f = GetFactory(id); + if (f) + { + bool how = f->CheckEnable(obj); + if (menubar->FindItem(id)) + menubar->Enable(id, how); + if (toolbar) + toolbar->EnableTool(id, how); + + bool chk = f->CheckChecked(obj); + wxMenuItem *itm = menubar->FindItem(id); + if (itm && itm->IsCheckable()) + menubar->Check(id, chk); + } + } + for (id = 0 ; id < GetCount() ; id++) + { + actionFactory *f = (actionFactory *)Item(id); + if (f->IsSubmenu()) + EnableSubmenu(menubar, id + MNU_ACTION); + } +} + + +void menuFactoryList::EnableSubmenu(wxMenuBar *menuBar, int id) +{ + wxMenuItem *item = menuBar->FindItem(id); + if (item) + { + wxMenu *menu = item->GetSubMenu(); + wxASSERT(menu); + if (!menu) + return; + + size_t position; + for (position = 0 ; position < menu->GetMenuItemCount() ; position++) + { + item = menu->FindItemByPosition(position); + if (item && item->IsEnabled()) + { + menuBar->Enable(id, true); + return; + } + } + + menuBar->Enable(id, false); + } +} + + +void menuFactoryList::AppendEnabledMenus(wxMenuBar *menuBar, wxMenu *treeContextMenu) +{ + size_t id; + wxMenuItem *lastItem = 0; + for (id = MNU_ACTION ; id < GetCount() + MNU_ACTION ; id++) + { + actionFactory *f = GetFactory(id, false); + if (f->IsAction()) + { + if (f->GetContext()) + { + wxMenuItem *menuItem = menuBar->FindItem(id); + if (menuItem && menuItem->IsEnabled()) + { + if (!menuItem->IsSubMenu()) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + lastItem = treeContextMenu->Append(id, lab, menuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); + if (menuItem->IsCheckable() && menuItem->IsChecked()) + treeContextMenu->FindItem(id)->Check(); + } + else + { + /* Copy of submenu */ + wxMenu *oldSubMenu = menuItem->GetSubMenu(); + wxMenu *newSubMenu = new wxMenu(); + + size_t i; + int itemCount = 0; + wxMenuItem *singleMenuItem = 0; + for (i = 0; i < oldSubMenu->GetMenuItemCount(); i++) + { + wxMenuItem *oldMenuItem = oldSubMenu->FindItemByPosition(i); + if (oldMenuItem->IsEnabled()) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString oldLab = oldMenuItem->GetItemLabelText(); +#else + wxString oldLab = oldMenuItem->GetLabel(); // deprecated +#endif + newSubMenu->Append(oldMenuItem->GetId(), oldLab, oldMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); + if (oldMenuItem->IsCheckable() && oldMenuItem->IsChecked()) + newSubMenu->FindItem(oldMenuItem->GetId())->Check(); + + itemCount++; + singleMenuItem = oldMenuItem; + } + } + if (itemCount > 1) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = menuItem->GetItemLabelText(); +#else + wxString lab = menuItem->GetLabel(); // deprecated +#endif + lastItem = treeContextMenu->Append(id, lab, newSubMenu); + } + else + { + delete newSubMenu; + if (itemCount) + { +#if wxCHECK_VERSION(2, 9, 0) + wxString lab = singleMenuItem->GetItemLabelText(); +#else + wxString lab = singleMenuItem->GetLabel(); // deprecated +#endif + lastItem = treeContextMenu->Append(singleMenuItem->GetId(), lab, singleMenuItem->GetHelp(), menuItem->IsCheckable() ? wxITEM_CHECK : wxITEM_NORMAL); + if (singleMenuItem->IsCheckable() && singleMenuItem->IsChecked()) + treeContextMenu->FindItem(singleMenuItem->GetId())->Check(); + } + } + } + } + } + } + else + { + if (lastItem && lastItem->GetId() >= 0) + lastItem = treeContextMenu->AppendSeparator(); + } + } + + if (lastItem && lastItem->GetId() < 0) + { + treeContextMenu->Remove(lastItem); + delete lastItem; + } +} + + +menuFactory::menuFactory(menuFactoryList *list) +{ + if (list) + list->Add(this); +} + +menuFactory::~menuFactory() +{ +} + +actionFactory::actionFactory(menuFactoryList *list) : menuFactory(list) +{ + if (list) + id = list->GetCount() + MNU_ACTION - 1; + else + id = 0; + context = false; +} + + + diff --git a/utils/favourites.cpp b/utils/favourites.cpp new file mode 100644 index 0000000..52dde1b --- /dev/null +++ b/utils/favourites.cpp @@ -0,0 +1,359 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// favourites.cpp - Query favourites +// +////////////////////////////////////////////////////////////////////////// + +// wxWindows headers +#include + +#include "pgAdmin3.h" +#include "utils/favourites.h" +#include "utils/sysSettings.h" + +#include + +// +// libxml convenience macros +// +#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) +#define XML_STR(s) ((const xmlChar *)s) + +// +// libxml convenience function +// +static void SkipToEndElement(xmlTextReaderPtr reader) +{ + while (xmlTextReaderRead(reader) == 1) + { + if (xmlTextReaderNodeType(reader) == 15) + return; + } +} + + +// +// queryFavouriteItem - base class representing a single favourite item, or +// acting as the base for folders. +// +queryFavouriteItem::queryFavouriteItem(const wxString newtitle, const wxString newcontents) +{ + title = newtitle; + contents = newcontents; + id = -1; +} + +void queryFavouriteItem::AppendToMenu(wxMenu *menu, int newid) +{ + id = newid; + menu->Append(id, title); +} + + +// +// queryFavouriteFolder - represents a folder containing zero or more favourites +// +queryFavouriteFolder::queryFavouriteFolder(wxString title) : queryFavouriteItem(title, wxT("")) +{ + id = -2; +} + +queryFavouriteFolder::queryFavouriteFolder(xmlTextReaderPtr reader, wxString title) : queryFavouriteItem(title, wxT("")) +{ + id = -2; + + // Element of type , meaning empty folder + if (xmlTextReaderIsEmptyElement(reader)) + return; + + while (xmlTextReaderRead(reader)) + { + int type = xmlTextReaderNodeType(reader); + + if (type == 15) + return; // Close on parent element + if (xmlTextReaderNodeType(reader) != 1) + continue; // Any unknown element type + + wxString nodename = WXSTRING_FROM_XML(xmlTextReaderConstName(reader)); + + xmlChar *ctitle = xmlTextReaderGetAttribute(reader, XML_STR("title")); + if (!ctitle) + continue; // We ignore nodes without title + wxString title = WXSTRING_FROM_XML(ctitle); + xmlFree(ctitle); + + if (nodename == wxT("favourite")) + { + xmlChar *cont = xmlTextReaderReadString(reader); + if (!cont) + continue; // No contents, so ignore node + + favourites.Add(new queryFavouriteItem(title, WXSTRING_FROM_XML(cont))); + xmlFree(cont); + SkipToEndElement(reader); + } + else if (nodename == wxT("folder")) + { + favourites.Add(new queryFavouriteFolder(reader, title)); + } + } +} + +queryFavouriteFolder::~queryFavouriteFolder() +{ + WX_CLEAR_ARRAY(favourites); +} + +void queryFavouriteFolder::AddNewFavourite(const wxString &title, const wxString &contents) +{ + favourites.Add(new queryFavouriteItem(title, contents)); +} + +queryFavouriteFolder *queryFavouriteFolder::AddNewFolder(const wxString &title) +{ + queryFavouriteFolder *fld = new queryFavouriteFolder(title); + favourites.Add(fld); + return fld; +} + +int queryFavouriteFolder::AppendAllToMenu(wxMenu *menu, int startid) +{ + int id = startid; + size_t i; + + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) // id=-2 reserved for submenus + { + queryFavouriteFolder *fld = (queryFavouriteFolder *)favourites.Item(i); + + wxMenu *newmenu = new wxMenu(); + id = fld->AppendAllToMenu(newmenu, id); + menu->Append(-1, fld->title, newmenu); + } + else + { + favourites.Item(i)->AppendToMenu(menu, id); + id++; + } + } + return id; +} + +void queryFavouriteFolder::AppendAllToTree(wxTreeCtrl *tree, const wxTreeItemId &parent, bool onlyfolders) +{ + size_t i; + + treeid = parent; + + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) // id=-1 reserved for submenus + { + queryFavouriteFolder *fld = (queryFavouriteFolder *)favourites.Item(i); + + wxTreeItemId newtreeitem = tree->AppendItem(parent, fld->title, onlyfolders ? 0 : 1); + fld->AppendAllToTree(tree, newtreeitem, onlyfolders); + tree->Expand(newtreeitem); + } + else + { + if (!onlyfolders) + favourites.Item(i)->SetTreeId(tree->AppendItem(parent, favourites.Item(i)->GetTitle(), 0)); + } + } +} + +bool queryFavouriteFolder::DeleteTreeItem(const wxTreeItemId &treeitem) +{ + if (treeid == treeitem) + /* Can't delete ourselves, parent should handle that. */ + return false; + + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetTreeId() == treeitem) + { + queryFavouriteItem *itm = favourites.Item(i); + delete itm; + favourites.RemoveAt(i); + return true; + } + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + if (subfolder->DeleteTreeItem(treeitem)) + return true; + } + } + return false; +} + +queryFavouriteItem *queryFavouriteFolder::FindFavourite(int id) +{ + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == id) + return favourites.Item(i); + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + queryFavouriteItem *match = subfolder->FindFavourite(id); + if (match != NULL) + return match; + } + } + return NULL; +} + +queryFavouriteItem *queryFavouriteFolder::FindFavourite(const wxString &title) +{ + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + queryFavouriteItem *match = subfolder->FindFavourite(title); + if (match != NULL) + return match; + } + else if (favourites.Item(i)->GetTitle() == title) + return favourites.Item(i); + } + return NULL; +} + +queryFavouriteItem *queryFavouriteFolder::FindTreeItem(const wxTreeItemId &treeitem) +{ + if (treeid == treeitem) + return this; + + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + queryFavouriteItem *match = subfolder->FindTreeItem(treeitem); + if (match != NULL) + return match; + } + else if (favourites.Item(i)->GetTreeId() == treeitem) + return favourites.Item(i); + } + return NULL; +} + +bool queryFavouriteFolder::ContainsFolder(const wxString &title) +{ + size_t i; + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + if (favourites.Item(i)->GetTitle() == title) + return true; + } + } + return false; +} + +void queryFavouriteFolder::saveFolder(xmlTextWriterPtr writer) +{ + size_t i; + + for (i = 0; i < favourites.GetCount(); i++) + { + if (favourites.Item(i)->GetId() == -2) + { + queryFavouriteFolder *subfolder = (queryFavouriteFolder *)favourites.Item(i); + + xmlTextWriterStartElement(writer, XML_STR("folder")); + xmlTextWriterWriteAttribute(writer, XML_STR("title"), XML_FROM_WXSTRING(subfolder->title)); + subfolder->saveFolder(writer); + xmlTextWriterEndElement(writer); + } + else + { + xmlTextWriterStartElement(writer, XML_STR("favourite")); + xmlTextWriterWriteAttribute(writer, XML_STR("title"), XML_FROM_WXSTRING(favourites.Item(i)->GetTitle())); + xmlTextWriterWriteString(writer, XML_FROM_WXSTRING(favourites.Item(i)->GetContents())); + xmlTextWriterEndElement(writer); + } + } +} + +// +// queryFavouriteFileProvider - load and save favourites from a XML file in the users +// home directory +// +queryFavouriteFolder *queryFavouriteFileProvider::LoadFavourites(bool emptyonfailure) +{ + xmlTextReaderPtr reader; + int ret; + + if (!wxFile::Access(settings->GetFavouritesFile(), wxFile::read)) + return emptyonfailure ? (new queryFavouriteFolder()) : NULL; + + reader = xmlReaderForFile((const char *)settings->GetFavouritesFile().mb_str(wxConvUTF8), NULL, 0); + if (!reader) + { + wxMessageBox(_("Failed to load favourites file!")); + return emptyonfailure ? (new queryFavouriteFolder()) : NULL; + } + + ret = xmlTextReaderRead(reader); + if (ret != 1) + { + wxMessageBox(_("Failed to read favourites file!")); + return emptyonfailure ? (new queryFavouriteFolder()) : NULL; + } + + queryFavouriteFolder *f = (queryFavouriteFolder *)(new queryFavouriteFolder(reader, wxT(""))); + + xmlTextReaderClose(reader); + xmlFreeTextReader(reader); + xmlCleanupParser(); + + return f; +} + +void queryFavouriteFileProvider::SaveFavourites(queryFavouriteFolder *favourites) +{ + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetFavouritesFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to write to favourites file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("favourites")) < 0)) + { + wxMessageBox(_("Failed to write to favourites file!")); + xmlFreeTextWriter(writer); + return; + } + + ((queryFavouriteFolder *)favourites)->saveFolder(writer); + + if (xmlTextWriterEndDocument(writer) < 0) + { + wxMessageBox(_("Failed to write to favourites file!")); + } + + xmlFreeTextWriter(writer); +} diff --git a/utils/macros.cpp b/utils/macros.cpp new file mode 100644 index 0000000..6fc24f5 --- /dev/null +++ b/utils/macros.cpp @@ -0,0 +1,349 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// macros.cpp - Query macros +// +////////////////////////////////////////////////////////////////////////// + +#include + +#include "pgAdmin3.h" +#include "utils/favourites.h" +#include "utils/macros.h" +#include "utils/sysSettings.h" + +#include + +// +// libxml convenience macros +// +#define XML_FROM_WXSTRING(s) ((const xmlChar *)(const char *)s.mb_str(wxConvUTF8)) +#define WXSTRING_FROM_XML(s) wxString((char *)s, wxConvUTF8) +#define XML_STR(s) ((const xmlChar *)s) + +// +// libxml convenience function +// +static void SkipToEndElement(xmlTextReaderPtr reader) +{ + while (xmlTextReaderRead(reader) == 1) + { + if (xmlTextReaderNodeType(reader) == 15) + return; + } +} + +queryMacroItem::queryMacroItem(const wxString newKey, const wxString newName, const wxString newQuery, const int newId) +{ + key = newKey; + name = newName; + query = newQuery; + id = newId; +} + +void queryMacroItem::AppendToMenu(wxMenu *menu, int newId) +{ + id = newId; + menu->Append(id, name + wxT("\t") + key, query); +} + +void queryMacroItem::Update(const wxString &newName, const wxString &newQuery) +{ + name = newName; + query = newQuery; +} + +queryMacroList::queryMacroList(xmlTextReaderPtr reader) +{ + // Element of type , meaning empty folder + if (xmlTextReaderIsEmptyElement(reader)) + return; + + while (xmlTextReaderRead(reader)) + { + int type = xmlTextReaderNodeType(reader); + + if (type == 15) + return; // Close on parent element + if (xmlTextReaderNodeType(reader) != 1) + continue; // Any unknown element type + + wxString nodename = WXSTRING_FROM_XML(xmlTextReaderConstName(reader)); + + xmlChar *ckey = xmlTextReaderGetAttribute(reader, XML_STR("key")); + if (!ckey) + continue; + wxString key = WXSTRING_FROM_XML(ckey); + xmlFree(ckey); + + xmlChar *cname = xmlTextReaderGetAttribute(reader, XML_STR("name")); + if (!cname) + continue; + wxString name = WXSTRING_FROM_XML(cname); + xmlFree(cname); + + if (nodename == wxT("macro")) + { + xmlChar *cquery = xmlTextReaderReadString(reader); + if (!cquery) + continue; + wxString query = WXSTRING_FROM_XML(cquery); + xmlFree(cquery); + macros.Add(new queryMacroItem(key, name, query)); + SkipToEndElement(reader); + } + } +} + +queryMacroList::~queryMacroList() +{ + WX_CLEAR_ARRAY(macros); +} + +int queryMacroList::AppendAllToMenu(wxMenu *menu, int startId) +{ + int id = startId; + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + macros.Item(i)->AppendToMenu(menu, id); + id++; + } + return id; +} + +void queryMacroList::AddNewMacro(const wxString &key, const wxString &name, const wxString &query) +{ + macros.Add(new queryMacroItem(key, name, query)); +} + +void queryMacroList::AddOrUpdateMacro(const wxString &key, const wxString &name, const wxString &query) +{ + queryMacroItem *item = FindMacro(key); + if (item != NULL) + { + item->Update(name, query); + } + else + { + AddNewMacro(key, name, query); + } +} + +bool queryMacroList::DelMacro(int id) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetId() == id) + { + queryMacroItem *itm = macros.Item(i); + delete itm; + macros.RemoveAt(i); + return true; + } + } + return false; +} + +bool queryMacroList::DelMacro(const wxString &key) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetKey() == key) + { + queryMacroItem *itm = macros.Item(i); + delete itm; + macros.RemoveAt(i); + return true; + } + } + return false; +} + +queryMacroItem *queryMacroList::FindMacro(int id) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetId() == id) + return macros.Item(i); + } + + return NULL; +} +queryMacroItem *queryMacroList::GetItem(int i) +{ + if (i < macros.GetCount()) { + return macros.Item(i); + } + return NULL; +} +int queryMacroList::Count() +{ + return macros.GetCount(); + +} + +queryMacroItem *queryMacroList::FindMacro(const wxString &key) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + if (macros.Item(i)->GetKey() == key) + return macros.Item(i); + } + + return NULL; +} + +void queryMacroList::saveList(xmlTextWriterPtr writer) +{ + size_t i; + + for (i = 0; i < macros.GetCount(); i++) + { + xmlTextWriterStartElement(writer, XML_STR("macro")); + xmlTextWriterWriteAttribute(writer, XML_STR("key"), + XML_FROM_WXSTRING(macros.Item(i)->GetKey())); + xmlTextWriterWriteAttribute(writer, XML_STR("name"), + XML_FROM_WXSTRING(macros.Item(i)->GetName())); + xmlTextWriterWriteString(writer, + XML_FROM_WXSTRING(macros.Item(i)->GetQuery())); + xmlTextWriterEndElement(writer); + } +} + +// +// queryMacroFileProvider - load and save macros from a XML file in the users +// home directory +// +queryMacroList *queryMacroFileProvider::LoadMacros(bool emptyOnFailure) +{ + xmlTextReaderPtr reader; + int ret; + + if (!wxFile::Access(settings->GetMacrosFile(), wxFile::read)) + return emptyOnFailure ? (new queryMacroList()) : NULL; + + reader = xmlReaderForFile((const char *)settings->GetMacrosFile().mb_str(wxConvUTF8), NULL, 0); + if (!reader) + { + wxMessageBox(_("Failed to load macros file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + ret = xmlTextReaderRead(reader); + if (ret != 1) + { + wxMessageBox(_("Failed to read macros file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + queryMacroList *f = (queryMacroList *)(new queryMacroList(reader)); + + xmlTextReaderClose(reader); + xmlFreeTextReader(reader); + xmlCleanupParser(); + + return f; +} +queryMacroList *queryMacroFileProvider::LoadAutoReplace(bool emptyOnFailure) +{ + xmlTextReaderPtr reader; + int ret; + + if (!wxFile::Access(settings->GetAutoReplaceFile(), wxFile::read)) + return emptyOnFailure ? (new queryMacroList()) : NULL; + + reader = xmlReaderForFile((const char *)settings->GetAutoReplaceFile().mb_str(wxConvUTF8), NULL, 0); + if (!reader) + { + wxMessageBox(_("Failed to load AutoReplace file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + ret = xmlTextReaderRead(reader); + if (ret != 1) + { + wxMessageBox(_("Failed to read AutoReplace file!")); + return emptyOnFailure ? (new queryMacroList()) : NULL; + } + + queryMacroList *f = (queryMacroList *)(new queryMacroList(reader)); + + xmlTextReaderClose(reader); + xmlFreeTextReader(reader); + xmlCleanupParser(); + + return f; +} +void queryMacroFileProvider::SaveAutoReplace(queryMacroList *macros) +{ + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetAutoReplaceFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to open AutoReplace file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("macros")) < 0)) + { + wxMessageBox(_("Failed to write to AutoReplace file!")); + xmlFreeTextWriter(writer); + return; + } + + ((queryMacroList *)macros)->saveList(writer); + + if (xmlTextWriterEndDocument(writer) < -1) + { + wxMessageBox(_("Failed to write to AutoReplace file!")); + } + + xmlFreeTextWriter(writer); +} + +void queryMacroFileProvider::SaveMacros(queryMacroList *macros) +{ + xmlTextWriterPtr writer; + + writer = xmlNewTextWriterFilename((const char *)settings->GetMacrosFile().mb_str(wxConvUTF8), 0); + if (!writer) + { + wxMessageBox(_("Failed to open macros file!")); + return; + } + xmlTextWriterSetIndent(writer, 1); + + if ((xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) || + (xmlTextWriterStartElement(writer, XML_STR("macros")) < 0)) + { + wxMessageBox(_("Failed to write to macros file!")); + xmlFreeTextWriter(writer); + return; + } + + ((queryMacroList *)macros)->saveList(writer); + + if (xmlTextWriterEndDocument(writer) < -1) + { + wxMessageBox(_("Failed to write to macros file!")); + } + + xmlFreeTextWriter(writer); +} diff --git a/utils/misc.cpp b/utils/misc.cpp new file mode 100644 index 0000000..66b5276 --- /dev/null +++ b/utils/misc.cpp @@ -0,0 +1,1408 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// misc.cpp - Miscellaneous Utilities +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/utffile.h" +#include + +#ifdef __WXMSW__ +#include +#endif + +// Standard headers +#include + +// App headers +#include "utils/misc.h" + +#if !defined(PGSCLI) + +// App headers +#include "frm/frmMain.h" + +wxImageList *imageList = 0; + +#endif // PGSCLI + +extern "C" +{ +#define YYSTYPE_IS_DECLARED +#define DECIMAL DECIMAL_P + typedef int YYSTYPE; +#include "parser/keywords.h" +} + +// we dont have an appropriate wxLongLong method +#ifdef __WIN32__ +#define atolonglong _atoi64 +#else +#ifdef __WXMAC__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#ifdef __FreeBSD__ +#define atolonglong(str) strtoll(str, (char **)NULL, 10) +#else +#define atolonglong atoll +#endif +#endif +#endif + + + +// Conversions + + +wxString BoolToYesNo(bool value) +{ + return value ? _("Yes") : _("No"); +} + + +wxString BoolToStr(bool value) +{ + return value ? wxT("true") : wxT("false"); +} + + + +bool StrToBool(const wxString &value) +{ + if (value.StartsWith(wxT("t"))) + { + return true; + } + else if (value.StartsWith(wxT("T"))) + { + return true; + } + else if (value.StartsWith(wxT("1"))) + { + return true; + } + else if (value.StartsWith(wxT("Y"))) + { + return true; + } + else if (value.StartsWith(wxT("y"))) + { + return true; + } + else if (value == wxT("on")) + return true; + + return false; +} + +wxString NumToStr(long value) +{ + wxString result; + result.Printf(wxT("%ld"), value); + return result; +} + + +wxString NumToStr(OID value) +{ + wxString result; + result.Printf(wxT("%lu"), (long)value); + return result; +} + + +long StrToLong(const wxString &value) +{ + return atol(value.ToAscii()); +} + + +OID StrToOid(const wxString &value) +{ + return (OID)strtoul(value.ToAscii(), 0, 10); +} + +wxString generate_spaces(int length) +{ + return wxString().Pad(length); +} + +wxString NumToStr(double value) +{ + wxString result; + static wxString decsep; + + if (decsep.Length() == 0) + { + decsep.Printf(wxT("%lf"), 1.2); + decsep = decsep[(unsigned int)1]; + } + + result.Printf(wxT("%lf"), value); + result.Replace(decsep, wxT(".")); + + // Get rid of excessive decimal places + if (result.Contains(wxT("."))) + while (result.Right(1) == wxT("0")) + result.RemoveLast(); + if (result.Right(1) == wxT(".")) + result.RemoveLast(); + + return result; +} + + +wxString NumToStr(wxLongLong value) +{ + wxString str; +#if wxCHECK_VERSION(2, 9, 0) + str.Printf("%" wxLongLongFmtSpec "d", value.GetValue()); +#else + str.Printf(wxT("%") wxLongLongFmtSpec wxT("d"), value.GetValue()); +#endif + return str; +} + + +double StrToDouble(const wxString &value) +{ + wxCharBuffer buf = value.ToAscii(); + char *p = (char *)strchr(buf, '.'); + if (p) + *p = localeconv()->decimal_point[0]; + + return strtod(buf, 0); +} + + +wxLongLong StrToLongLong(const wxString &value) +{ + return atolonglong(value.ToAscii()); +} + + +wxString DateToAnsiStr(const wxDateTime &datetime) +{ + if (!datetime.IsValid()) + return wxEmptyString; + + return datetime.FormatISODate() + wxT(" ") + datetime.FormatISOTime(); +} + + +wxString DateToStr(const wxDateTime &datetime) +{ + if (!datetime.IsValid()) + return wxEmptyString; + + return datetime.FormatDate() + wxT(" ") + datetime.FormatTime(); +} + + +wxString ElapsedTimeToStr(wxLongLong msec) +{ + wxTimeSpan tsMsec(0, 0, 0, msec); + + int days = tsMsec.GetDays(); + int hours = (wxTimeSpan(tsMsec.GetHours(), 0, 0, 0) - wxTimeSpan(days * 24)).GetHours(); + int minutes = (wxTimeSpan(0, tsMsec.GetMinutes(), 0, 0) - wxTimeSpan(hours)).GetMinutes(); + long seconds = (wxTimeSpan(0, 0, tsMsec.GetSeconds(), 0) - wxTimeSpan(hours, minutes)).GetSeconds().ToLong(); + long milliseconds = (wxTimeSpan(0, 0, 0, tsMsec.GetMilliseconds()) - wxTimeSpan(0, 0, seconds)).GetMilliseconds().ToLong(); + + if (days > 0) + return wxString::Format( + wxT("%d %s, %02d:%02d:%02ld hours"), + days, wxT("days"), hours, minutes, seconds + ); + else if (hours > 0) + return wxString::Format( + wxT("%02d:%02d:%02ld hours"), hours, minutes, seconds + ); + else if (msec >= 1000 * 60) + return wxString::Format(wxT("%02d:%02ld minutes"), minutes, seconds); + else if (msec >= 1000) + return wxString::Format( + wxT("%ld.%ld secs"), seconds, milliseconds / 100 + ); + else + return msec.ToString() + wxT(" msec"); +} + +wxDateTime StrToDateTime(const wxString &value) +{ + wxDateTime dt; + /* This hasn't just been used. ( Is not infinity ) */ + if ( !value.IsEmpty() ) + dt.ParseDateTime(value); + return dt; +} + +#if !defined(PGSCLI) + +void CheckOnScreen(wxWindow *win, wxPoint &pos, wxSize &size, const int w0, const int h0) +{ + wxRect rect; + int scrH, scrW; + + wxSize screenSize = wxGetDisplaySize(); + scrW = screenSize.x; + scrH = screenSize.y; + + if (pos.x > scrW - w0) + pos.x = scrW - w0; + if (pos.y > scrH - h0) + pos.y = scrH - h0; + + if (pos.x < 0) + pos.x = 0; + if (pos.y < 0) + pos.y = 0; + + if (size.GetWidth() < w0) + size.SetWidth(w0); + if (size.GetHeight() < h0) + size.SetHeight(h0); + + if (size.GetWidth() > scrW) + size.SetWidth(scrW); + if (size.GetHeight() > scrH) + size.SetHeight(scrH); +} + +#endif // PGSCLI + +wxString qtConnString(const wxString &value) +{ + wxString result = value; + + result.Replace(wxT("\\"), wxT("\\\\")); + result.Replace(wxT("'"), wxT("\\'")); + result.Append(wxT("'")); + result.Prepend(wxT("'")); + + return result; +} + +#if !defined(PGSCLI) + +wxString IdAndName(long id, const wxString &name) +{ + wxString str; + str.Printf(wxT("%ld - %s"), id, name.BeforeFirst('\n').c_str()); + return str; +} + + +wxString qtDbStringDollar(const wxString &value) +{ + wxString qtDefault = wxT("BODY"); + wxString qt = qtDefault; + int counter = 1; + if (value.Find('\'') < 0 && value.Find('\n') < 0 && value.Find('\r') < 0) + { + wxString ret = value; + ret.Replace(wxT("\\"), wxT("\\\\")); + ret.Replace(wxT("'"), wxT("''")); + ret.Append(wxT("'")); + ret.Prepend(wxT("'")); + return ret; + } + + while (value.Find(wxT("$") + qt + wxT("$")) >= 0) + qt.Printf(wxT("%s%d"), qtDefault.c_str(), counter++); + + + return wxT("$") + qt + wxT("$") + + value + + wxT("$") + qt + wxT("$"); +} + + +void FillKeywords(wxString &str) +{ + // unfortunately, the keyword list is static. + int i; + + str = wxString(); + + for (i = 0; i < NumScanKeywords; i++) + { + str += wxT(" ") + wxString::FromAscii(ScanKeywords[i].name); + } + for (i = 0; i < NumScanKeywordsExtra; i++) + { + str += wxT(" ") + wxString::FromAscii(ScanKeywordsExtra[i].name); + } +} + +#endif // PGSCLI + +static bool needsQuoting(wxString &value, bool forTypes) +{ + // Is it a number? + if (value.IsNumber()) + return true; + else + { + // certain types should not be quoted even though it contains a space. Evilness. + wxString valNoArray; + if (forTypes && value.Right(2) == wxT("[]")) + valNoArray = value.Mid(0, value.Len() - 2); + else + valNoArray = value; + + if (forTypes && + (!valNoArray.CmpNoCase(wxT("character varying")) || + !valNoArray.CmpNoCase(wxT("\"char\"")) || + !valNoArray.CmpNoCase(wxT("bit varying")) || + !valNoArray.CmpNoCase(wxT("double precision")) || + !valNoArray.CmpNoCase(wxT("timestamp without time zone")) || + !valNoArray.CmpNoCase(wxT("timestamp with time zone")) || + !valNoArray.CmpNoCase(wxT("time without time zone")) || + !valNoArray.CmpNoCase(wxT("time with time zone")) || + !valNoArray.CmpNoCase(wxT("\"trigger\"")) || + !valNoArray.CmpNoCase(wxT("\"unknown\"")))) + return false; + + int pos = 0; + while (pos < (int)valNoArray.length()) + { + wxChar c = valNoArray.GetChar(pos); + if (!((pos > 0) && (c >= '0' && c <= '9')) && + !(c >= 'a' && c <= 'z') && + !(c == '_')) + { + return true; + } + pos++; + } + } + + // is it a keyword? + const ScanKeyword *sk = ScanKeywordLookup(value.ToAscii()); + if (!sk) + return false; + if (sk->category == UNRESERVED_KEYWORD) + return false; + if (forTypes && sk->category == COL_NAME_KEYWORD) + return false; + return true; +} + +wxString qtTypeIdent(const wxString &value) +{ + if (value.Length() == 0) + return value; + + wxString result = value; + + if (needsQuoting(result, true)) + { + result.Replace(wxT("\""), wxT("\"\"")); + return wxT("\"") + result + wxT("\""); + } + else + return result; +} + + +wxString qtIdent(const wxString &value) +{ + if (value.Length() == 0) + return value; + + wxString result = value; + + if (needsQuoting(result, false)) + { + result.Replace(wxT("\""), wxT("\"\"")); + return wxT("\"") + result + wxT("\""); + } + else + return result; +} + +#if !defined(PGSCLI) + +wxString qtStrip(const wxString &str) +{ + if (str.Left(2) == wxT("\\\"")) + return str.Mid(2, str.Length() - 4); + else + return str; +} + + +wxString TransformToNewDatconfig(const wxString &list) +{ + const wxChar *cp = list.c_str(); + + wxString config = wxEmptyString; + wxString str = wxEmptyString; + bool quote = false; + + while (*cp) + { + switch (*cp) + { + case '\\': + { + if (cp[1] == '"') + { + str.Append(*cp); + cp++; + str.Append(*cp); + } + break; + } + case '"': + case '\'': + { + quote = !quote; + str.Append(*cp); + break; + } + case ',': + { + if (!quote) + { + if (!config.IsEmpty()) + config += wxT(","); + config += wxT("=") + str; + str = wxEmptyString; + break; + } + } + default: + { + str.Append(*cp); + break; + } + } + cp++; + } + + if (!str.IsEmpty()) + { + if (!config.IsEmpty()) + config += wxT(","); + config += wxT("=") + str; + } + + return config; +} + + +void FillArray(wxArrayString &array, const wxString &list) +{ + const wxChar *cp = list.c_str(); + + wxString str; + bool quote = false; + + while (*cp) + { + switch (*cp) + { + case '\\': + { + if (cp[1] == '"') + { + cp++; + str.Append(*cp); + } + break; + } + case '"': + case '\'': + { + quote = !quote; + break; + } + case ',': + { + if (!quote) + { + array.Add(str); + str = wxEmptyString; + break; + } + } + default: + { + str.Append(*cp); + break; + } + } + cp++; + } + if (!str.IsEmpty()) + array.Add(str); +} + + +queryTokenizer::queryTokenizer(const wxString &str, const wxChar delim) + : wxStringTokenizer() +{ + if (delim == (wxChar)' ') + SetString(str, wxT(" \n\r\t"), wxTOKEN_RET_EMPTY_ALL); + else + SetString(str, delim, wxTOKEN_RET_EMPTY_ALL); + delimiter = delim; +} + + +void AppendIfFilled(wxString &str, const wxString &delimiter, const wxString &what) +{ + if (!what.IsNull()) + str += delimiter + what; +} + + +wxString queryTokenizer::GetNextToken() +{ + // we need to override wxStringTokenizer, because we have to handle quotes + wxString str; + + bool foundQuote = false; + do + { + wxString s = wxStringTokenizer::GetNextToken(); + str.Append(s); + int quotePos; + do + { + quotePos = s.Find('"'); + if (quotePos >= 0) + { + foundQuote = !foundQuote; + s = s.Mid(quotePos + 1); + } + } + while (quotePos >= 0); + + if (foundQuote) + str.Append(delimiter); + } + while (foundQuote & HasMoreTokens()); + + return str; +} + + +wxString FileRead(const wxString &filename, int format) +{ + wxString str; + + wxFontEncoding encoding; + if (format > 0) + encoding = wxFONTENCODING_UTF8; + else + encoding = wxFONTENCODING_DEFAULT; + + wxUtfFile file(filename, wxFile::read, encoding); + + if (file.IsOpened()) + file.Read(str); + + return wxTextBuffer::Translate(str, wxTextFileType_Unix); // we want only \n +} + + +bool FileWrite(const wxString &filename, const wxString &data, int format) +{ + wxFontEncoding encoding = wxFONTENCODING_DEFAULT; + wxUtfFile file; + + if (format < 0) + { + if (wxFile::Access(filename, wxFile::read)) + { + file.Open(filename); + encoding = file.GetEncoding(); + file.Close(); + } + if (encoding == wxFONTENCODING_DEFAULT) + encoding = settings->GetUnicodeFile() ? wxFONTENCODING_UTF8 : wxFONTENCODING_SYSTEM; + } + else + encoding = format ? wxFONTENCODING_UTF8 : wxFONTENCODING_SYSTEM; + + + file.Open(filename, wxFile::write, wxS_DEFAULT, encoding); + + if (file.IsOpened()) + return file.Write(wxTextBuffer::Translate(data)); + + return false; +} + + +wxString CleanHelpPath(const wxString &path) +{ + wxString thePath = path; + + if (thePath.IsEmpty()) + return wxEmptyString; + + // If the filename ends in .chm, .hhp, .pdf or .zip, it's + // a file based help system and we can assumes it's + // correct. + if (thePath.Lower().EndsWith(wxT(".hhp")) || +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + thePath.Lower().EndsWith(wxT(".chm")) || +#endif + thePath.Lower().EndsWith(wxT(".pdf")) || + thePath.Lower().EndsWith(wxT(".zip"))) + return thePath; + + // In all other cases we must have a directory + wxString sep; + + // Figure out the appropriate seperator + if (thePath.Lower().Contains(wxT("://"))) + sep = wxT("/"); + else + sep = wxFileName::GetPathSeparator(); + + // First, correct the path separators + thePath.Replace(wxT("/"), sep); + thePath.Replace(wxT("\\"), sep); + + // Now, append the seperator if it's not there + if (!thePath.EndsWith(sep)) + thePath += sep; + + return thePath; +} + +bool HelpPathValid(const wxString &path) +{ + if (path.IsEmpty()) + return true; + + // If the filename contains any of the sensible URL schemes + // we just assume it's correct if the end also looks right. + if ((path.Lower().StartsWith(wxT("http://")) || + path.Lower().StartsWith(wxT("https://")) || + path.Lower().StartsWith(wxT("file://")) || + path.Lower().StartsWith(wxT("ftp://"))) && + (path.Lower().EndsWith(wxT(".hhp")) || +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + path.Lower().EndsWith(wxT(".chm")) || +#endif + path.Lower().EndsWith(wxT(".pdf")) || + path.Lower().EndsWith(wxT(".zip")) || + path.Lower().EndsWith(wxT("/")))) + return true; + + // Otherwise, we're looking for a file (or directory) that + // actually exists. + wxString sep = wxFileName::GetPathSeparator(); + if (path.Lower().EndsWith(wxT(".hhp")) || +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + path.Lower().EndsWith(wxT(".chm")) || +#endif + path.Lower().EndsWith(wxT(".pdf")) || + path.Lower().EndsWith(wxT(".zip"))) + return wxFile::Exists(path); + else if (path.Lower().EndsWith(sep)) + return wxDir::Exists(path); + else + return false; +} + +void DisplayHelp(const wxString &helpTopic, const HelpType helpType) +{ + static wxHelpControllerBase *pgHelpCtl = 0; + static wxHelpControllerBase *edbHelpCtl = 0; + static wxHelpControllerBase *greenplumHelpCtl = 0; + static wxHelpControllerBase *slonyHelpCtl = 0; + static wxString pgInitPath = wxEmptyString; + static wxString edbInitPath = wxEmptyString; + static wxString gpInitPath = wxEmptyString; + static wxString slonyInitPath = wxEmptyString; + + switch (helpType) + { + case HELP_PGADMIN: + DisplayPgAdminHelp(helpTopic); + break; + + case HELP_POSTGRESQL: + DisplayExternalHelp(helpTopic, settings->GetPgHelpPath(), pgHelpCtl, (pgInitPath != settings->GetPgHelpPath() ? true : false)); + pgInitPath = settings->GetPgHelpPath(); + break; + + case HELP_ENTERPRISEDB: + DisplayExternalHelp(helpTopic, settings->GetEdbHelpPath(), edbHelpCtl, (edbInitPath != settings->GetEdbHelpPath() ? true : false)); + edbInitPath = settings->GetEdbHelpPath(); + break; + + case HELP_GREENPLUM: + { + // the old help path (stored in the settings) is no longer working + static wxString gpHelpPath = settings->GetGpHelpPath(); + + // Note: never end the URL on "index.html" + // InitHelp() does obscure magic with this ending + if (gpHelpPath.CmpNoCase(wxT("http://docs.gopivotal.com/gpdb/")) == 0) + { + gpHelpPath = wxT("http://gpdb.docs.pivotal.io/"); + // Replace the path to the old domain with the link to + // the new documentation path + // The old link is working for now, but there is no guarantee + // that it will stay this way + // Also the new link automatically redirects to the latest version + settings->SetGpHelpPath(gpHelpPath); + } + + if (gpHelpPath.CmpNoCase(wxT("http://www.greenplum.com/docs/3300/")) == 0) + { + gpHelpPath = wxT("http://gpdb.docs.pivotal.io/"); + // this is the old link, update the link to the new documentation link + // problem: this saves the link into the configuration file + settings->SetGpHelpPath(gpHelpPath); + } + DisplayExternalHelp(helpTopic, settings->GetGpHelpPath(), greenplumHelpCtl, (gpInitPath != settings->GetGpHelpPath() ? true : false)); + gpInitPath = settings->GetGpHelpPath(); + } + break; + + case HELP_SLONY: + DisplayExternalHelp(helpTopic, settings->GetSlonyHelpPath(), slonyHelpCtl, (slonyInitPath != settings->GetSlonyHelpPath() ? true : false)); + slonyInitPath = settings->GetSlonyHelpPath(); + break; + + default: + DisplayPgAdminHelp(helpTopic); + break; + } +} + +void DisplayPgAdminHelp(const wxString &helpTopic) +{ + static wxHelpControllerBase *helpCtl = 0; + static bool firstCall = true; + + // Startup the main help system + if (firstCall) + { + firstCall = false; + wxString helpdir = docPath + wxT("/") + settings->GetCanonicalLanguageName(); + + if (!wxFile::Exists(helpdir + wxT("/pgadmin3.hhp")) && +#if defined(__WXMSW__) || wxUSE_LIBMSPACK + !wxFile::Exists(helpdir + wxT("/pgadmin3.chm")) && +#endif + !wxFile::Exists(helpdir + wxT("/pgadmin3.zip"))) + helpdir = docPath + wxT("/en_US"); + +#ifdef __WXMSW__ +#ifndef __WXDEBUG__ + if (wxFile::Exists(helpdir + wxT("/pgadmin3.chm"))) + { + helpCtl = new wxCHMHelpController(); + helpCtl->Initialize(helpdir + wxT("/pgadmin3")); + } + else +#endif +#endif +#if wxUSE_LIBMSPACK + if (wxFile::Exists(helpdir + wxT("/pgadmin3.chm")) || + wxFile::Exists(helpdir + wxT("/pgadmin3.hhp")) || wxFile::Exists(helpdir + wxT("/pgadmin3.zip"))) +#else + if (wxFile::Exists(helpdir + wxT("/pgadmin3.hhp")) || wxFile::Exists(helpdir + wxT("/pgadmin3.zip"))) +#endif + { + helpCtl = new wxHtmlHelpController(); + helpCtl->Initialize(helpdir + wxT("/pgadmin3")); + } + } + + wxString page; + int hashPos = helpTopic.Find('#'); + if (hashPos < 0) + page = helpTopic + wxT(".html"); + else + page = helpTopic.Left(hashPos) + wxT(".html") + helpTopic.Mid(hashPos); + + if (helpCtl) + { + if (helpTopic == wxT("index.html")) + helpCtl->DisplayContents(); + else + helpCtl->DisplaySection(page); + } + else + { + wxLaunchDefaultBrowser(page); + } +} + +void DisplayExternalHelp(const wxString &helpTopic, const wxString &docPath, wxHelpControllerBase *helpCtl, const bool init) +{ + // Build the page name + wxString page; + int hashPos = helpTopic.Find('#'); + if (hashPos < 0) + page = helpTopic + wxT(".html"); + else + page = helpTopic.Left(hashPos) + wxT(".html") + helpTopic.Mid(hashPos); + + // If the docPath ends in .pdf, then open the file in the browser. No + // bookmarks though :-( + if (docPath.Lower().EndsWith(wxT(".pdf"))) + { + wxLaunchDefaultBrowser(docPath); + return; + } + + // If the docPath doesn't end in .chm, .zip or .hhp, then we must be using + // plain HTML files, so just fire off the browser and be done with it. + if (!docPath.Lower().EndsWith(wxT(".hhp")) && +#if defined (__WXMSW__) || wxUSE_LIBMSPACK + !docPath.Lower().EndsWith(wxT(".chm")) && +#endif + !docPath.Lower().EndsWith(wxT(".zip"))) + { + wxLaunchDefaultBrowser(docPath + page); + return; + } + + // We must be using HTML Help, so init the appropriate help controller + // Note the path that we init for - if it changes, we need to init a + // new controller in case it's no longer the same type + if (init || !helpCtl) + { + // Get shot of the old help controller if there is one. + if (helpCtl) + delete helpCtl; + +#ifdef __WXMSW__ + // For Windows builds we us the MS HTML Help viewer for .chm files + if (docPath.Lower().EndsWith(wxT(".chm")) && wxFile::Exists(docPath)) + { + helpCtl = new wxCHMHelpController(); + helpCtl->Initialize(docPath); + } + else +#endif +#if wxUSE_LIBMSPACK + // If we can use a .chm file... + if ((docPath.Lower().EndsWith(wxT(".chm")) && wxFile::Exists(docPath)) || + (docPath.Lower().EndsWith(wxT(".hhp")) && wxFile::Exists(docPath)) || + (docPath.Lower().EndsWith(wxT(".zip")) && wxFile::Exists(docPath))) +#else + // Otherwise... + if ((docPath.Lower().EndsWith(wxT(".hhp")) && wxFile::Exists(docPath)) || + (docPath.Lower().EndsWith(wxT(".zip")) && wxFile::Exists(docPath))) +#endif + { + helpCtl = new wxHtmlHelpController(); + helpCtl->Initialize(docPath); + } + } + + // Display the page using the help controller + // If it's foobar'ed, use the browser. + if (helpCtl) + { + if (helpTopic == wxT("index.html")) + helpCtl->DisplayContents(); + else + helpCtl->DisplaySection(page); + } + else + { + wxLogError(_("The help source (\"%s\") could not be opened. Please check the help configuration options."), docPath.c_str()); + } +} + +wxString GetHtmlEntity(const wxChar ch) +{ + // REWRITE THIS - IT'S (STILL) BLOODY INEFFICIENT!! + + // Quick bailout + if ((ch >= 'a' && ch <= 'z') || + (ch >= 'A' && ch <= 'Z') || + (ch >= '0' && ch <= '9')) + return wxString(ch); + + unsigned short ents[] = + { + 34, + 39, + 38, + 60, + 62, + 160, + 161, + 164, + 162, + 163, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 8482, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 215, + 247, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 338, + 339, + 352, + 353, + 376, + 710, + 732, + 8194, + 8195, + 8201, + 8204, + 8205, + 8206, + 8207, + 8211, + 8212, + 8216, + 8217, + 8218, + 8220, + 8221, + 8222, + 8224, + 8225, + 8230, + 8240, + 8249, + 8250, + 8364, + 0 + }; + + int elem = 0; + + while (ents[elem] != 0) + { + if (ch == ents[elem]) + { + wxString ret = wxT("&#"); + ret += NumToStr((long)ents[elem]); + ret += wxT(";"); + return ret; + } + elem++; + } + + return wxString(ch); +} + +wxString HtmlEntities(const wxString &str) +{ + wxString ret; + + for (unsigned int x = 0; x < str.Length(); x++) + { + if (str[x] != 13) + ret += GetHtmlEntity(str[x]); + } + + return ret; +} + + +#ifndef WIN32 +wxString ExecProcess(const wxString &cmd) +{ + wxString res; + FILE *f = popen(cmd.ToAscii(), "r"); + + if (f) + { + char buffer[1024]; + int cnt; + while ((cnt = fread(buffer, 1, 1024, f)) > 0) + { + res += wxString::FromAscii(buffer); + } + pclose(f); + } + return res; +} + +int ExecProcess(const wxString &command, wxArrayString &result) +{ + FILE *fp_command; + char buf[4098]; + + fp_command = popen(command.mb_str(wxConvUTF8), "r"); + + if (!fp_command) + return -1; + + while(!feof(fp_command)) + { + if (fgets(buf, 4096, fp_command) != NULL) + result.Add(wxString::FromAscii(buf)); + } + + return pclose(fp_command); +} +#endif + +#ifdef WIN32 +#if (_MSC_VER < 1300) +/* _ftol2 is more than VC7. */ +extern "C" long _ftol( double ); +extern "C" long _ftol2( double dblSource ) +{ + return _ftol( dblSource ); +} +#endif +#endif + +wxString firstLineOnly(const wxString &str) +{ + wxString ip, tmp; + ip = str; + ip = ip.Trim(true).Trim(false); + + if (ip.Contains(wxT("\r\n")) && (ip.First(wxT("\r")) < ip.First(wxT("\n")))) + { + tmp = ip.BeforeFirst('\r'); + if (ip.BeforeFirst('\r').Length() != ip.Length()) + tmp += wxT("..."); + } + else + { + tmp = ip.BeforeFirst('\n'); + if (ip.BeforeFirst('\n').Length() != ip.Length()) + tmp += wxT("..."); + } + + return tmp; +} + +bool pgAppMinimumVersion(const wxString &cmd, const int majorVer, const int minorVer) +{ + wxArrayString output; + bool isEnterpriseDB = false; + +#ifdef __WXMSW__ + if (wxExecute(cmd + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(cmd + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), cmd.c_str()); + return false; + } + + // Is this an EDB utility? + if (output[0].Contains(wxT("EnterpriseDB"))) + isEnterpriseDB = true; + + wxString version = output[0].AfterLast(' '); + int len=version.Length(); + long actualMajor = 0, actualMinor = 0; + + wxString tmp = wxT(""); + int x = 0; + while(x majorVer) + return true; + + if (actualMajor == majorVer && actualMinor >= minorVer) + return true; + + return false; +} + +bool isPgApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("PostgreSQL"))) + return true; + + return false; +} + +bool isEdbApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("EnterpriseDB"))) + return true; + + return false; +} + +bool isGpApp(const wxString &app) +{ + if (!wxFile::Exists(app)) + return false; + + wxArrayString output; + +#ifdef __WXMSW__ + if (wxExecute(app + wxT(" --version"), output, 0) != 0) +#else + if (ExecProcess(app + wxT(" --version"), output) != 0) +#endif + { + wxLogError(_("Failed to execute: %s --version"), app.c_str()); + return false; + } + + if (output[0].Contains(wxT("8.2"))) // Ugly... No way to tell Greenplum app from PostgreSQL 8.2 app + return true; + + return false; +} + +wxString sanitizePath(const wxString &path) +{ + if (path.Length()) + { + wxFileName fn = path; + fn.Normalize(); + return fn.GetLongPath(); + } + + return wxEmptyString; +} + +/** + * FUNCTION: commandLineCleanOption + * INPUTS: + * option - input string needs to be reformatted + * schemaObject - Is this an object related to schema? + * PURPOSE: + * - Fixup a (double-quoted) string for use on the command line + */ +wxString commandLineCleanOption(const wxString &option, bool schemaObject) +{ + wxString tmp = option; + + if (schemaObject) + { + // Replace double-quote with slash & double-quote + tmp.Replace(wxT("\""), wxT("\\\"")); + } + else + { + // If required, clean the string to know the real object name + if (option.StartsWith(wxT("\"")) && option.EndsWith(wxT("\""))) + tmp = option.AfterFirst((wxChar)'"').BeforeLast((wxChar)'"'); + + // Replace single splash to double-splash + tmp.Replace(wxT("\\"), wxT("\\\\")); + + // Replace double-quote with slash & double-quote + tmp.Replace(wxT("\""), wxT("\\\"")); + + // Replace double (slash & double-quote) combination to single (slash & double-quote) combination + tmp.Replace(wxT("\\\"\\\""), wxT("\\\"")); + + // Add the double quotes + tmp = wxT("\"") + tmp + wxT("\""); + } + + return tmp; +} + +#endif // PGSCLI + +// Get an array from a comma separated list +bool getArrayFromCommaSeparatedList(const wxString &str, wxArrayString &res) +{ + size_t len = str.Len(), index = 0, nBracketLevel = 0, startArray = 0; + bool inSingleQuote = false, inDoubleQuote = false; + + if (len == 0) + return true; + + for(; index < len; index++) + { + wxChar curr = str.GetChar(index); + if (!inDoubleQuote && curr == (wxChar)'\'') + inSingleQuote = !inSingleQuote; + else if (!inSingleQuote && curr == (wxChar)'"') + inDoubleQuote = !inDoubleQuote; + else if (!inDoubleQuote && !inSingleQuote && curr == (wxChar)'(') + nBracketLevel++; + else if (!inDoubleQuote && !inSingleQuote && curr == (wxChar)')') + nBracketLevel--; + else if (!inDoubleQuote && !inSingleQuote && nBracketLevel == 0 && curr == (wxChar)',') + { + if (index != startArray) + res.Add(str.SubString(startArray, index - 1).Trim(true).Trim(false)); + else + res.Add(wxEmptyString); + startArray = index + 1; + } + } + if (inDoubleQuote || inSingleQuote || nBracketLevel != 0) + return false; + + // Add last value to array + res.Add(str.SubString(startArray, index).Trim(true).Trim(false)); + + return true; +} + diff --git a/utils/module.mk b/utils/module.mk new file mode 100644 index 0000000..822b534 --- /dev/null +++ b/utils/module.mk @@ -0,0 +1,34 @@ +####################################################################### +# +# pgAdmin III - PostgreSQL Tools +# +# Copyright (C) 2002 - 2016, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +# module.mk - pgadmin/utils/ Makefile fragment +# +####################################################################### + +pgadmin3_SOURCES += \ + utils/csvfiles.cpp \ + utils/factory.cpp \ + utils/favourites.cpp \ + utils/misc.cpp \ + utils/pgconfig.cpp \ + utils/registry.cpp \ + utils/sysLogger.cpp \ + utils/sysProcess.cpp \ + utils/sysSettings.cpp \ + utils/tabcomplete.c \ + utils/utffile.cpp \ + utils/macros.cpp + +if BUILD_SSH_TUNNEL +pgadmin3_SOURCES += \ + utils/sshTunnel.cpp +endif + +EXTRA_DIST += \ + utils/module.mk \ + utils/tab-complete.inc \ + utils/tabcomplete.pl diff --git a/utils/pgconfig.cpp b/utils/pgconfig.cpp new file mode 100644 index 0000000..7488084 --- /dev/null +++ b/utils/pgconfig.cpp @@ -0,0 +1,624 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// pgconfig.cpp - backend configuration classes +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +#include + +#include "utils/pgconfig.h" +#include "db/pgConn.h" +#include "db/pgSet.h" +#include "utils/utffile.h" + + +#define DEFAULT_COMMENT_INDEX wxT("\t\t# ") + + +int FindToken(const wxString &str, const wxChar **list) +{ + int index; + for (index = 0 ; list[index] ; index++) + { + if (list[index] == str) + return index; + + } + return -1; +} + + +const wxChar *pgConfigTypeStrings[] = +{ + wxT("bool"), + wxT("integer"), + wxT("real"), + wxT("string"), + 0 +}; + + +void pgSettingItem::SetType(const wxString &str) +{ + int index = FindToken(str, pgConfigTypeStrings); + if (index < 0) + type = PGC_STRING; + else + type = (pgConfigType)index; +} + + +const wxChar *pgConfigContextStrings[] = +{ + wxT("internal"), + wxT("postmaster"), + wxT("sighup"), + wxT("backend"), + wxT("superuser"), + wxT("userlimit"), + wxT("user"), + 0 +}; + + +void pgSettingItem::SetContext(const wxString &str) +{ + int index = FindToken(str, pgConfigContextStrings); + if (index < 0) + context = PGC_INTERNAL; + else + context = (pgConfigContext)index; +} + + +const wxChar *pgConfigSourceStrings[] = +{ + wxT("default"), + wxT("environment variable"), + wxT("configuration file"), + wxT("command line"), + wxT("unprivileged"), + wxT("database"), + wxT("user"), + wxT("client"), + wxT("override"), + wxT("interactive"), + wxT("test"), + wxT("session"), + 0 +}; + + +void pgSettingItem::SetSource(const wxString &str) +{ + int index = FindToken(str, pgConfigSourceStrings); + if (index < 0) + source = PGC_UNKNOWNSOURCE; + else + source = (pgConfigSource)index; +} + + +wxString pgSettingItem::GetActiveValue() +{ + if (newLine) + { + if (!newLine->isComment) + return newLine->value; + } + else if (orgLine) + { + if (!orgLine->isComment) + return orgLine->value; + } + return value; +} + + +pgConfigLine::pgConfigLine(pgConfigLine *line) +{ + item = line->item; + value = line->value; + comment = line->comment; + isComment = line->isComment; +} + + +bool pgConfigLine::Differs(pgConfigLine *line) +{ + return value != line->value || comment != line->comment || isComment != line->isComment; +} + + +wxString pgConfigLine::GetNewText() +{ + wxString quote; + wxString newLine; + if (item->type == pgSettingItem::PGC_STRING) + { + if (value.Find('\'') >= 0) + quote = wxT("\""); + else + quote = wxT("'"); + } + if (isComment) + newLine = wxT("# "); + + newLine += item->name + wxT(" = ") + + quote + value + quote; + + if (!comment.IsEmpty()) + { + if (item->orgLine && item->orgLine->commentIndent.Find('#') >= 0) + newLine += item->orgLine->commentIndent; + else + newLine += DEFAULT_COMMENT_INDEX; + newLine += comment; + } + return newLine; +} + + +pgConfigOrgLine::pgConfigOrgLine(pgConfigLine *line) : pgConfigLine(line) +{ + text = line->GetNewText(); + if (isComment) + commentIndent = DEFAULT_COMMENT_INDEX; +} + + +wxString pgConfigOrgLine::GetNewText() +{ + if (!item || !item->newLine) + return text; + return item->newLine->GetNewText(); +} + + +//////////////////////////////////////////////// + + +pgSettingFileReader::pgSettingFileReader(bool localized) +{ + + wxUtfFile file; + + wxString path = i18nPath + wxT("/") + settings->GetCanonicalLanguageName() + wxT("/pg_settings.csv"); + if (localized && wxFile::Exists(path)) + file.Open(path); + else + file.Open(i18nPath + wxT("/pg_settings.csv")); + + if (file.IsOpened()) + { + file.Read(buffer); + file.Close(); + } + + if (!buffer.IsEmpty()) + { + buffer = wxTextBuffer::Translate(buffer, wxTextFileType_Unix); + + columnNames = buffer.BeforeFirst('\n'); + bp = const_cast((const wxChar *)buffer + columnNames.Length() + 1); + } +} + + +pgSettingFileReader::~pgSettingFileReader() +{ +} + + +pgSettingItem *pgSettingFileReader::GetNextItem() +{ + if (!bp || !*bp || *bp == '\n') + return 0; + + pgSettingItem *item = new pgSettingItem; + wxStringTokenizer tk(columnNames, wxT(";")); + wxString column = tk.GetNextToken(); + + wxChar *c = bp; + while (*c) + { + wxString value; + + if (*c++ != '"') + { + // invalid syntax + return 0; + } + while (*c && *c != '\n') + { + if (*c == '"') + { + if (c[1] == '"') + c++; + else + break; + } + value.Append(*c++); + } + if (*c++ != '"') + { + // format error + return 0; + } + if (column == wxT("name") || column == wxT("\"name\"")) + item->name = value.Lower(); + else if (column == wxT("category") || column == wxT("\"category\"")) + item->category = value; + else if (column == wxT("short_desc") || column == wxT("\"short_desc\"")) + item->short_desc = value; + else if (column == wxT("extra_desc") || column == wxT("\"extra_desc\"")) + item->extra_desc = value; + else if (column == wxT("min_val") || column == wxT("\"min_val\"")) + item->min_val = value; + else if (column == wxT("max_val") || column == wxT("\"max_val\"")) + item->max_val = value; + else if (column == wxT("context") || column == wxT("\"context\"")) + item->SetContext(value); + else if (column == wxT("vartype") || column == wxT("\"vartype\"")) + item->SetType(value); + + column = tk.GetNextToken(); + if (*c == '\n') + { + bp = c + 1; + break; + } + else if (!*c) + { + bp = 0; + break; + } + else if (*c == ';') + c++; + else + { + // invalid syntax + return 0; + } + } + + return item; +} + + +pgSettingDbReader::pgSettingDbReader(pgConn *conn) +{ + set = conn->ExecuteSet(wxT("SELECT name, setting, source, category, short_desc, extra_desc, context, vartype, min_val, max_val FROM pg_settings ORDER BY name")); +} + + +pgSettingDbReader::~pgSettingDbReader() +{ + if (set) + delete set; +} + +pgSettingItem *pgSettingDbReader::GetNextItem() +{ + if (set->Eof()) + return 0; + + pgSettingItem *item = new pgSettingItem; + + item->name = set->GetVal(wxT("name")).Lower(); + item->category = set->GetVal(wxT("category")); + item->short_desc = set->GetVal(wxT("short_desc")); + item->extra_desc = set->GetVal(wxT("extra_desc")); + item->min_val = set->GetVal(wxT("min_val")); + item->max_val = set->GetVal(wxT("max_val")); + item->SetContext(set->GetVal(wxT("context"))); + item->SetType(set->GetVal(wxT("vartype"))); + item->SetSource(set->GetVal(wxT("source"))); + item->value = set->GetVal(wxT("setting")); + + set->MoveNext(); + + return item; +} + + +/////////////////////////////////////////////////////// + +// must match enum pgHbaConnectType!!! +const wxChar *pgHbaConnectTypeStrings[] = +{ + wxT("local"), + wxT("host"), + wxT("hostssl"), + wxT("hostnossl"), + 0 +}; + + +// must match enum pgHbaMethod!!! +const wxChar *pgHbaMethodStrings[] = +{ + wxT("trust"), + wxT("reject"), + wxT("md5"), + wxT("crypt"), + wxT("password"), + wxT("krb4"), + wxT("krb5"), + wxT("ident"), + wxT("pam"), + wxT("ldap"), + wxT("gss"), + wxT("sspi"), + wxT("cert"), + wxT("peer"), + wxT("radius"), + 0 +}; + + +bool IsSpaceChar(wxChar c, const wxChar *spaceChars = wxT("\t ")) +{ + return wxStrchr(spaceChars, c) != NULL; +} + + +void SkipSpace(const wxChar *&ptr, const wxChar *spaceChars = wxT("\t ")) +{ + while (*ptr && IsSpaceChar(*ptr)) + ptr++; +} + + +void SkipNonspace(const wxChar *&ptr, const wxChar *spaceChars = wxT("\t ")) +{ + while (*ptr && !IsSpaceChar(*ptr)) + ptr++; +} + + +pgHbaConfigLine::pgHbaConfigLine(const wxString &line) +{ + item = -1; + isValid = false; + isComment = true; + connectType = PGC_INVALIDCONF; + method = PGC_INVALIDMETHOD; + Init(line); +} + + +void pgHbaConfigLine::Init(const wxString &line) +{ + isValid = false; + connectType = PGC_INVALIDCONF; + changed = false; + + if (line.IsEmpty()) + return; + + text = line; + + const wxChar *p0 = line.c_str(); + + if (*p0 == '#') + { + isComment = true; + p0++; + SkipSpace(p0); + } + else + isComment = false; + + + const wxChar *p1 = p0; + SkipNonspace(p1); + + wxString str = line.Mid(p0 - line.c_str(), p1 - p0); + + int i = FindToken(str, pgHbaConnectTypeStrings); + + if (i >= 0) + connectType = (pgHbaConnectType)i; + else + { + connectType = PGC_INVALIDCONF; + return; + } + + SkipSpace(p1); + + const wxChar *p2 = p1; + bool quoted = false; + + while (*p2) + { + if (!quoted && IsSpaceChar(*p2)) + break; + if (*p2 == '"') + quoted = !quoted; + p2++; + } + + database = line.Mid(p1 - line.c_str(), p2 - p1); + + SkipSpace(p2); + + const wxChar *p3 = p2; + + quoted = false; + while (*p3) + { + if (!quoted && IsSpaceChar(*p3)) + break; + if (*p3 == '"') + quoted = !quoted; + p3++; + } + + user = line.Mid(p2 - line.c_str(), p3 - p2); + + SkipSpace(p3); + + const wxChar *p4 = p3; + + if (connectType == PGC_LOCAL) + { + // no ip address + } + else + { + bool hasCidr = false; + while (*p4 && !IsSpaceChar(*p4)) + { + if (*p4 == '/') + hasCidr = true; + p4++; + } + if (!hasCidr) + { + SkipSpace(p4); + SkipNonspace(p4); + } + + ipaddress = line.Mid(p3 - line.c_str(), p4 - p3); + SkipSpace(p4); + } + + const wxChar *p5 = p4; + SkipNonspace(p5); + + str = line.Mid(p4 - line.c_str(), p5 - p4); + + i = FindToken(str, pgHbaMethodStrings); + + if (i >= 0) + method = (pgHbaMethod)i; + else + { + return; + } + SkipSpace(p5); + option = p5; + + isValid = true; +} + + +const wxChar *pgHbaConfigLine::GetConnectType() +{ + if (connectType >= 0 && connectType < PGC_INVALIDCONF) + return pgHbaConnectTypeStrings[connectType]; + return 0; +} + + +const wxChar *pgHbaConfigLine::GetMethod() +{ + if (method >= 0 && method < PGC_INVALIDMETHOD) + return pgHbaMethodStrings[method]; + return 0; +} + + +wxString pgHbaConfigLine::GetText() +{ + if (!changed) + return text; + + wxString str; + wxString tabspace = wxT("\t "); + if (isComment) + str = wxT("# "); + + str += GetConnectType() + + tabspace + database + + tabspace + user; + + if (connectType != PGC_LOCAL) + str += tabspace + ipaddress; + + str += tabspace + GetMethod(); + + if (method >= PGC_IDENT && !option.IsEmpty()) + str += tabspace + option; + + return str; +} + + +//////////////////////////////////////////////// +pgPassConfigLine::pgPassConfigLine(const wxString &line) +{ + item = -1; + Init(line); +} + +void pgPassConfigLine::Init(const wxString &line) +{ + text = line; + + if (line.IsEmpty()) + return; + + isComment = line.StartsWith(wxT("#")); + + wxString tmpLine = line; + // De-escape backslash "\" + tmpLine.Replace(wxT("\\\\"), wxT("\\")); + + int iVarCount = 0; + wxStringTokenizer tok(isComment ? tmpLine.Mid(1) : tmpLine, wxT(":")); + while(tok.HasMoreTokens()) + { + wxString val = tok.GetNextToken(); + if (!val.IsEmpty()) + { + /* if last charecter of the token is backslash "\" then it means + that it is used to escape ":" so we need to add the next token. + */ + while(val.Last() == wxT('\\')) + { + val.RemoveLast(); + val = val + wxT(":") + tok.GetNextToken(); + } + + iVarCount++; + switch(iVarCount) + { + case 1: // hostname + hostname = val; + break; + case 2: // port + port = val; + break; + case 3: // database + database = val; + break; + case 4: //username + username = val; + break; + case 5: // password + password = val; + break; + } + } + } +} + +wxString pgPassConfigLine::GetText() +{ + return (isComment ? wxT("#") : wxT("")) + + hostname + wxT(":") + + port + wxT(":") + + database + wxT(":") + + username + wxT(":") + + password; +} diff --git a/utils/registry.cpp b/utils/registry.cpp new file mode 100644 index 0000000..9cd4154 --- /dev/null +++ b/utils/registry.cpp @@ -0,0 +1,377 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// RCS-ID: +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// registry.cpp - Windows Registry Reader for both 32 and 64 mode +// +////////////////////////////////////////////////////////////////////////// +#include "pgAdmin3.h" + +#include "utils/registry.h" + +#ifdef __WXMSW__ + +#define RESERVED 0 +#define PGREG_SEPERATOR wxT("\\") + +static struct stdkey +{ + HKEY key; + wxString name; +} +aStdHKeys[] = +{ + {HKEY_CLASSES_ROOT, wxT("HKEY_CLASSES_ROOT")}, + {HKEY_CURRENT_USER, wxT("HKEY_CURRENT_USER")}, + {HKEY_LOCAL_MACHINE, wxT("HKEY_LOCAL_MACHINE") }, + {HKEY_USERS, wxT("HKEY_USERS")}, + {HKEY_CURRENT_CONFIG, wxT("HKEY_CURRENT_CONFIG")} +}; + +#define NOS_STD_KEYS (size_t)(sizeof(aStdHKeys)/sizeof(stdkey)) + +pgRegKey::pgRegKey(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode) +{ + Init(root, subkey, wowMode, accessMode); +} + +pgRegKey::pgRegKey(const pgRegKey &parent, const wxString &key) +{ + wxString strKey; + strKey << parent.m_strName << PGREG_SEPERATOR << key; + + Init(parent.m_hRoot, strKey, PGREG_WOW_DEFAULT, parent.m_accessMode); + m_wowMode = parent.m_wowMode; +} + +void pgRegKey::Init(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode, PGREGACCESSMODE accessMode) +{ + m_hRoot = root; + m_strName = subkey; + m_accessMode = accessMode; + m_hKey = NULL; +#ifdef __WIN64__ + m_wowMode = KEY_WOW64_64KEY; +#else + m_wowMode = KEY_WOW64_32KEY; +#endif + + switch (wowMode) + { + case PGREG_WOW32: +#ifdef __WIN64__ + m_wowMode = KEY_WOW64_32KEY; +#endif // __WIN64__ + break; + + case PGREG_WOW64: +#ifndef __WIN64__ + // we can only access 64 bit registry under 64 bit platforms + if (::wxIsPlatform64Bit()) + m_wowMode = KEY_WOW64_64KEY; +#endif // !__WIN64__ + break; + } +} + +pgRegKey *pgRegKey::OpenRegKey(HKEY root, const wxString &subkey, PGREGACCESSMODE accessmode, PGREGWOWMODE wowMode) +{ + wxString strKey = subkey; + + !subkey.IsEmpty() && subkey.EndsWith(wxT("\\"), &strKey); + pgRegKey *tmpKey = new pgRegKey(root, strKey, wowMode, accessmode); + + HKEY tmpRegKey = 0; + long nError = ::RegOpenKeyEx(root, (LPCTSTR)strKey, RESERVED, + (accessmode == PGREG_READ ? KEY_READ : KEY_ALL_ACCESS) | tmpKey->m_wowMode, + &tmpRegKey); + + if (nError != ERROR_SUCCESS) + { + delete(tmpKey); + tmpKey = NULL; + } + else + tmpKey->m_hKey = tmpRegKey; + + return tmpKey; +} + +void pgRegKey::Close() +{ + if (m_hKey) + { + ::RegCloseKey(m_hKey); + m_hKey = NULL; + } +} + +pgRegKey::~pgRegKey() +{ + Close(); +} + +bool pgRegKey::KeyExists(HKEY root, const wxString &subkey, PGREGWOWMODE wowMode) +{ + if (subkey.IsEmpty()) + return true; + +#ifdef __WIN64__ + long keyWowMode = KEY_WOW64_64KEY; +#else + long keyWowMode = KEY_WOW64_32KEY; +#endif + + switch (wowMode) + { + case PGREG_WOW32: +#ifdef __WIN64__ + keyWowMode = KEY_WOW64_32KEY; +#endif // __WIN64__ + break; + + case PGREG_WOW64: +#ifndef __WIN64__ + // we can only access 64 bit registry under 64 bit platforms + if (::wxIsPlatform64Bit()) + keyWowMode = KEY_WOW64_64KEY; +#endif // ! __WIN64__ + break; + } + + HKEY hkeyDummy; + if (::RegOpenKeyEx(root, (LPCTSTR)subkey, RESERVED, KEY_READ | keyWowMode, &hkeyDummy) == ERROR_SUCCESS) + { + ::RegCloseKey(hkeyDummy); + return true; + } + return false; +} + +bool pgRegKey::GetKeyInfo(size_t *pnSubKeys, size_t *pnMaxKeyLen, size_t *pnValues, size_t *pnMaxValueLen) const +{ + + long nError = ::RegQueryInfoKey(m_hKey, NULL, NULL, RESERVED, (LPDWORD)pnSubKeys, (LPDWORD)pnMaxKeyLen, NULL, + (LPDWORD)pnValues, (LPDWORD)pnMaxValueLen, NULL, NULL, NULL); + + if (nError != ERROR_SUCCESS) + return false; + return true; +} + +wxString pgRegKey::ToString() const +{ + wxString str; + size_t index = 0; + for (; index < NOS_STD_KEYS; index++) + { + if (m_hRoot == aStdHKeys[index].key) + { + str = aStdHKeys[index].name; + break; + } + } + + if (!m_strName.IsEmpty()) + str << wxT("\\") << m_strName; + + return str; +} + +wxString pgRegKey::GetKeyName() const +{ + if (!m_strName.IsEmpty()) + { + int index = m_strName.Find(wxT('\\'), true); + return m_strName.SubString(index + 1, m_strName.Len()); + } + return wxEmptyString; +} + +bool pgRegKey::QueryValue(const wxString &strkey, LPDWORD pVal) const +{ + if (strkey.IsEmpty()) + return false; + + DWORD dwType, dwSize = sizeof(DWORD); + unsigned char *pBuf = (unsigned char *)pVal; + + long nError = ::RegQueryValueEx(m_hKey, (LPCTSTR)strkey, RESERVED, &dwType, pBuf, &dwSize); + + if (nError != ERROR_SUCCESS) + return false; + + if (dwType != REG_DWORD && dwType != REG_DWORD_BIG_ENDIAN) + return false; + return true; +} + +bool pgRegKey::QueryValue(const wxString &strVal, wxString &sVal) const +{ + DWORD dwType, dwSize; + + long nError = RegQueryValueEx(m_hKey, (LPCTSTR)strVal, RESERVED, &dwType, NULL, &dwSize); + + if (nError == ERROR_SUCCESS) + { + sVal = wxT(""); + if (dwSize == 0) + return true; + + wxChar *pBuf = (wxChar *)calloc(dwSize, sizeof(wxChar)); + nError = ::RegQueryValueEx(m_hKey, (LPCTSTR)strVal, RESERVED, &dwType, (LPBYTE)pBuf, &dwSize); + + DWORD index = 0; + if (dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ) + { + wxChar *actualValueStr = (wxChar *)calloc(dwSize, sizeof(wxChar)); + memcpy(actualValueStr, pBuf, dwSize * sizeof(wxChar)); + + wxChar *curr_line; + sVal = wxT(""); + do + { + DWORD dwExpSize = ::ExpandEnvironmentStrings((actualValueStr + index), NULL, 0); + curr_line = (wxChar *)calloc(dwExpSize, sizeof(wxChar)); + + ::ExpandEnvironmentStrings(actualValueStr + index, curr_line, dwExpSize); + + if (index != 0) + sVal << wxT("\n\r") << curr_line; + else + sVal << curr_line; + index += (DWORD)wxStrlen(actualValueStr + index) + 1; + free(curr_line); + } + while (actualValueStr[index] && dwType == REG_MULTI_SZ); + + free(actualValueStr); + } + else + sVal = pBuf; + + free(pBuf); + return true; + } + return false; +} + +bool pgRegKey::QueryValue(const wxString &strVal, LPBYTE &pVal, DWORD &len) const +{ + DWORD dwType; + if(RegQueryValueEx(m_hKey, (LPCTSTR)strVal, + RESERVED, &dwType, pVal, &len) == ERROR_SUCCESS) + return true; + len = 0; + return false; +} + +bool pgRegKey::GetFirstValue(wxString &strkey, long &lIndex) const +{ + lIndex = 0; + return GetNextValue(strkey, lIndex); +} + +bool pgRegKey::GetNextValue(wxString &strval, long &lIndex) const +{ + if (lIndex < 0) + return false; + + TCHAR szVal[1024]; + DWORD dwValLen = 1024; + + long nError = RegEnumValue(m_hKey, lIndex, szVal, &dwValLen, RESERVED, NULL, NULL, NULL); + + if (nError != ERROR_SUCCESS) + { + if (nError == ERROR_NO_MORE_ITEMS) + { + nError = ERROR_SUCCESS; + lIndex = -1; + } + return false; + } + strval = szVal; + lIndex++; + return true; +} + +bool pgRegKey::HasValue(const wxString &strval) +{ + long nRetVal = ::RegQueryValueEx(m_hKey, (LPCTSTR)strval, RESERVED, NULL, NULL, NULL); + + return nRetVal == ERROR_SUCCESS; +} + +bool pgRegKey::GetFirstKey(pgRegKey *&pkey, long &lIndex) const +{ + lIndex = 0; + return GetNextKey(pkey, lIndex); +} + +bool pgRegKey::GetNextKey(pgRegKey *&pKey, long &lIndex) const +{ + pKey = NULL; + + if (lIndex < 0) + return false; + + TCHAR szKey[1024]; + DWORD dwKeyLen = 1023; + long nError = ::RegEnumKeyEx(m_hKey, lIndex, szKey, &dwKeyLen, NULL, NULL, NULL, NULL); + + if (nError != ERROR_SUCCESS) + { + lIndex = -1; + return false; + } + lIndex++; + wxString strSubKey = m_strName; + strSubKey << wxT("\\") << szKey; + + pgRegKey *tmpKey = new pgRegKey(m_hRoot, (LPCTSTR)strSubKey, PGREG_WOW_DEFAULT, m_accessMode); + tmpKey->m_wowMode = m_wowMode; + + HKEY tmpRegKey = 0; + nError + = ::RegOpenKeyEx(m_hRoot, (LPCTSTR)strSubKey, RESERVED, (m_accessMode == PGREG_READ ? KEY_READ : KEY_ALL_ACCESS) | m_wowMode, &tmpRegKey); + + if (nError != ERROR_SUCCESS) + { + delete(tmpKey); + tmpKey = NULL; + pKey = NULL; + + return false; + } + else + tmpKey->m_hKey = tmpRegKey; + + pKey = tmpKey; + + return true; +} + +bool pgRegKey::HasKey(const wxString &strKey) const +{ + wxString strSubKey = m_strName; + strSubKey << wxT("\\") << strKey; + + return pgRegKey::KeyExists(m_hRoot, strSubKey, m_wowMode == KEY_WOW64_64KEY ? PGREG_WOW64 : PGREG_WOW32) ; +} + +DWORD pgRegKey::GetValueType(const wxString &key) const +{ + DWORD dwType; + long nError = RegQueryValueEx((HKEY) m_hKey, (LPCTSTR)key, RESERVED, + &dwType, NULL, NULL); + + if (nError != ERROR_SUCCESS) + return REG_NONE; + return dwType; +} + +#endif // __WXMSW__ diff --git a/utils/sshTunnel.cpp b/utils/sshTunnel.cpp new file mode 100644 index 0000000..ed75f34 --- /dev/null +++ b/utils/sshTunnel.cpp @@ -0,0 +1,630 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sshTunnel.cpp - Used to create SSH Tunnels +// +////////////////////////////////////////////////////////////////////////// + +// App headers +#include "pgAdmin3.h" +#include + +#undef ssize_t +#define ssize_t long +#include "libssh2.h" +#include "utils/sshTunnel.h" +#include "frm/frmMain.h" + +#pragma comment (lib, "Ws2_32.lib") + +typedef const char *(*inet_ntop_t) (int af, const void *src, char *dst, socklen_t size); + +#ifdef WIN32 +const char *custom_inet_ntop(int af, const void *src, char *dst, int cnt) +{ + struct sockaddr_in srcaddr; + + memset(&srcaddr, 0, sizeof(struct sockaddr_in)); + memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr)); + + srcaddr.sin_family = af; + if (WSAAddressToStringA((struct sockaddr *) &srcaddr, sizeof(struct sockaddr_in), 0, dst, (LPDWORD) &cnt) != 0) + { + + wxLogInfo(wxT("SSH error: WSAAddressToStringA failed with error code %d"), WSAGetLastError()); + return NULL; + } + return dst; +} + +static inet_ntop_t gs_fnPtr_inet_ntop = &custom_inet_ntop; +#else +static inet_ntop_t gs_fnPtr_inet_ntop = &inet_ntop; +#endif + +char CSSHTunnelThread::m_keyboard_interactive_pwd[SSH_MAX_PASSWORD_LEN]; + +CSSHTunnelThread::CSSHTunnelThread(const wxString tunnelhost, const wxString remote_desthost, const unsigned int remote_destport, + const wxString username, const wxString password, const wxString publickey, const wxString privatekey, + const enAuthenticationMethod &enAuthMethod, const unsigned int tunnelPort) + : m_tunnelhost(tunnelhost), m_remote_desthost(remote_desthost), m_remote_destport(remote_destport), m_username(username), + m_password(password), m_publickey(publickey), m_privatekey(privatekey), m_enAuthMethod(enAuthMethod), m_tunnelPort(tunnelPort) +{ + m_local_listenip = wxEmptyString; + m_local_listenport = 0; + m_listensock = -1, m_sock = -1; + m_session = NULL; + + memset(m_keyboard_interactive_pwd, 0 , strlen(m_keyboard_interactive_pwd)); + strncpy(m_keyboard_interactive_pwd, (const char *)password.mb_str(wxConvUTF8), password.Length()); +} + +CSSHTunnelThread::~CSSHTunnelThread(void) +{ +} + +bool CSSHTunnelThread::Initialize() +{ + int rc, auth = AUTH_NONE; + const char *fingerprint; + char *userauthlist; + +#ifdef WIN32 + char sockopt; + WSADATA wsadata; + int err; + + err = WSAStartup(MAKEWORD(2, 0), &wsadata); + if(err != 0) + { + wxLogInfo(wxT("WSAStartup failed with error: %d"), err); + return false; + } +#else + int sockopt; +#endif + + wxArrayString arrTunnelHostIP; + + if (resolveDNS(m_tunnelhost.mb_str(), arrTunnelHostIP)) + { + rc = libssh2_init (0); + + if (rc != 0) + { + LogSSHTunnelErrors(wxString::Format(_("libssh2 initialization failed with error code %d"), rc), GetId()); + return false; + } + + /* Connect to SSH server */ + m_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + m_sin.sin_family = AF_INET; + if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrTunnelHostIP.Item(0).mb_str()))) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Error in inet address with error code %d"), wxSysErrorCode()), GetId()); + return false; + } + m_sin.sin_port = htons(m_tunnelPort); + if (connect(m_sock, (struct sockaddr *)(&m_sin), + sizeof(struct sockaddr_in)) != 0) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Could not connect to socket with error code %d"), wxSysErrorCode()), GetId()); + return false; + } + + /* Create a session instance */ + m_session = libssh2_session_init(); + + if (!m_session) + { + LogSSHTunnelErrors(_("SSH error: Could not initialize SSH session!"), GetId()); + return false; + } + + /* ... start it up. This will trade welcome banners, exchange keys, + * and setup crypto, compression, and MAC layers + */ + rc = libssh2_session_handshake(m_session, m_sock); + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Error when starting up SSH session with error code %d"), rc), GetId(), m_session); + return false; + } + + /* At this point we havn't yet authenticated. The first thing to do + * is check the hostkey's fingerprint against our known hosts Your app + * may have it hard coded, may go to a file, may present it to the + * user, that's your call + */ + fingerprint = libssh2_hostkey_hash(m_session, LIBSSH2_HOSTKEY_HASH_SHA1); + wxString newHostKey = wxEmptyString; + for(int i = 0; i < 20; i++) + { + newHostKey += wxString::Format(wxT("%02X "), (unsigned char)fingerprint[i]); + } + + // Check if the SSH Host Key is verified + if(!IsHostKeyVerified(newHostKey)) + { + Cleanup(); + return false; + } + + + /* check what authentication methods are available */ + userauthlist = libssh2_userauth_list(m_session, m_username.mb_str(), strlen(m_username.mb_str())); + + if (strstr(userauthlist, "password")) + auth |= AUTH_PASSWORD; + if(strstr(userauthlist, "keyboard-interactive")) + auth |= AUTH_KEYBOARD_INTERACTIVE; + if (strstr(userauthlist, "publickey")) + auth |= AUTH_PUBLICKEY; + + if ((auth & AUTH_PASSWORD) && (m_enAuthMethod == AUTH_PASSWORD)) + auth = AUTH_PASSWORD; + else if ((auth & AUTH_KEYBOARD_INTERACTIVE) && (m_enAuthMethod == AUTH_PASSWORD)) + auth = AUTH_KEYBOARD_INTERACTIVE; + if ((auth & AUTH_PUBLICKEY) && (m_enAuthMethod == AUTH_PUBLICKEY)) + auth = AUTH_PUBLICKEY; + + if (auth & AUTH_PASSWORD) + { + rc = libssh2_userauth_password(m_session, m_username.mb_str(), m_password.mb_str()); + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by password failed with error code %d"), rc), GetId(), m_session); + Cleanup(); + return false; + } + } + else if (auth & AUTH_KEYBOARD_INTERACTIVE) + { + rc = libssh2_userauth_keyboard_interactive(m_session, m_username.mb_str(), &CSSHTunnelThread::keyboard_interactive); + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by password failed with error code %d"), rc), GetId(), m_session); + Cleanup(); + return false; + } + } + else if (auth & AUTH_PUBLICKEY) + { +#ifdef HAVE_GCRYPT + rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), m_publickey.mb_str(), m_privatekey.mb_str(), m_password.mb_str()); +#else + rc = libssh2_userauth_publickey_fromfile(m_session, m_username.mb_str(), NULL, m_privatekey.mb_str(), m_password.mb_str()); +#endif + if (rc) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Authentication by identity file failed with error code %d"), rc), GetId(), m_session); + Cleanup(); + return false; + } + } + else + { + LogSSHTunnelErrors(_("SSH error: No supported authentication methods found!"), GetId()); + Cleanup(); + return false; + } + + // Get the IP Address of local machine + wxArrayString arrLocalIP; + if(resolveDNS("localhost", arrLocalIP)) + { + m_listensock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + memset(&m_sin, 0 , sizeof(m_sin)); + m_sin.sin_family = AF_INET; + + // Give port no to 0 so that bind will automatically select the available port. + m_sin.sin_port = htons(0); + if (INADDR_NONE == (m_sin.sin_addr.s_addr = inet_addr(arrLocalIP.Item(0).mb_str()))) + { + Cleanup(); + return false; + } + + sockopt = 1; + setsockopt(m_listensock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)); + m_sinlen = sizeof(m_sin); + if (-1 == bind(m_listensock, (struct sockaddr *)&m_sin, m_sinlen)) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: bind failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + return false; + } + + if (getsockname(m_listensock, (struct sockaddr *)&m_sin, &m_sinlen) == -1) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: getsockname() failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + return false; + } + + if (-1 == listen(m_listensock, 2)) + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: listen failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + return false; + } + + m_local_listenip = wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc); + m_local_listenport = ntohs(m_sin.sin_port); + + wxLogInfo(wxT("Waiting for TCP connection on %s:%d..."), m_local_listenip.c_str(), m_local_listenport); + return true; + } + else + { + LogSSHTunnelErrors(_("SSH error: Unable to resolve localhost"), GetId()); + } + } + else + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: Unable to resolve host: %s"), m_tunnelhost.c_str()), GetId()); + } + + return false; +} + +void *CSSHTunnelThread::Entry() +{ + while (1) + { + int forwardsock = accept(m_listensock, (struct sockaddr *) & m_sin, &m_sinlen); + if (-1 == forwardsock) + { +#ifdef WIN32 + if(wxSysErrorCode() != WSAEINTR && wxSysErrorCode() != WSAEBADF) +#else + if(wxSysErrorCode() != EINTR && wxSysErrorCode() != EBADF && wxSysErrorCode() != ECONNABORTED) +#endif + { + LogSSHTunnelErrors(wxString::Format(_("SSH error: accept failed with error code %d"), wxSysErrorCode()), GetId()); + Cleanup(); + } + break; + } + + // Create thread for read/write. + CSubThread *subThread = new CSubThread(m_sin, m_remote_desthost, m_remote_destport, m_session, forwardsock); + if ( subThread->Create() != wxTHREAD_NO_ERROR ) + { + delete subThread; + subThread = NULL; + } + else + { + if (subThread->Run() != wxTHREAD_NO_ERROR ) + { + delete subThread; + subThread = NULL; + } + else + { + g_SSHThreadMutex.Lock(); + g_setSocketDescriptor.insert(forwardsock); + g_SSHThreadMutex.Unlock(); + } + } + } + + return NULL; +} + +void CSSHTunnelThread::Cleanup() +{ + // Close all the sockets + g_SSHThreadMutex.Lock(); + subThreadSDSet::iterator it; + for( it = g_setSocketDescriptor.begin(); it != g_setSocketDescriptor.end(); ++it ) + { + int socketDescriptor = *it; +#ifdef WIN32 + closesocket(socketDescriptor); +#else + close(socketDescriptor); +#endif + } + g_SSHThreadMutex.Unlock(); + + Sleep(1000); + + if(m_session) + { + libssh2_session_disconnect(m_session, "Client disconnecting normally"); + libssh2_session_free(m_session); + m_session = NULL; + } + + if (m_listensock) + { +#ifdef WIN32 + closesocket(m_listensock); +#else + close(m_listensock); +#endif + m_listensock = 0; + } + + if (m_sock) + { +#ifdef WIN32 + closesocket(m_sock); +#else + close(m_sock); +#endif + m_sock = 0; + } + + libssh2_exit(); +} + +bool CSSHTunnelThread::resolveDNS(const char *host, wxArrayString &arrIPAddress) +{ + struct addrinfo hints, *res, *p; + int status; + char ipstr[INET6_ADDRSTRLEN]; +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 +#endif + memset(&hints, 0, sizeof hints); + memset(&ipstr, 0, sizeof ipstr); + hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG | AI_PASSIVE; + + if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0) + { + wxLogInfo(wxT("getaddrinfo failed with error code: %d"), status); + return false; + } + + for(p = res; p != NULL; p = p->ai_next) + { + void *addr; + if (p->ai_family == AF_INET) + { + struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr; + addr = &(ipv4->sin_addr); + + /* convert the IP to a string*/ + if(NULL != gs_fnPtr_inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr)) + arrIPAddress.Add(wxString(ipstr, wxConvLocal)); + } + } + + if(res) + { + freeaddrinfo(res); // free the linked list + } + + if(arrIPAddress.Count() > 0) + { + return true; + } + + return false; +} + +void CSSHTunnelThread::keyboard_interactive(const char *name, int name_len, const char *instr, int instr_len, + int num_prompts, const struct _LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE *res, + void **abstract) +{ + if (num_prompts == 1) + { + res[0].text = strdup(m_keyboard_interactive_pwd); + res[0].length = strlen(m_keyboard_interactive_pwd); + } +} + +bool CSSHTunnelThread::IsHostKeyVerified(const wxString &newHostKey) +{ + bool bIsVerified = false; + wxString cachedHostKey = settings->Read(wxT("HostKeys/") + m_tunnelhost, wxEmptyString); + + // If cached host key is empty then ask user to accept or reject + if (cachedHostKey == wxEmptyString) + { + // Prompt User to accept or reject + wxString msg = wxString::Format(wxT("Host key received for the SSH server \"%s\" is \n\n%s\n\nWould you like to accept it and continue with the connection?"), m_tunnelhost.c_str(), newHostKey.c_str()); + int answer = wxMessageBox(msg, wxT("Host key verification"), wxYES_NO | wxNO_DEFAULT); + if (answer == wxYES) + { + // Write the host key with respect to tunnel host + settings->Write(wxT("HostKeys/") + m_tunnelhost, newHostKey); + bIsVerified = true; + } + } + else + { + // Compare the cached host key with the new key + if (cachedHostKey.compare(newHostKey) == 0) + bIsVerified = true; + else + { + // Prompt user to accept or reject the new host key received for the tunnel host + wxString msg = wxString::Format(wxT("The host key received from the server \"%s\" is\n\n%s\n\nbut the stored key is\n\n%s\n\nThis may indicate that this is not the same server that was previously used.\n\nDo you wish to accept and store the new key, and continue with the connection?"), m_tunnelhost.c_str(), newHostKey.c_str(), cachedHostKey.c_str()); + int answer = wxMessageBox(msg, wxT("Host key verification - WARNING"), wxYES_NO | wxNO_DEFAULT); + if (answer == wxYES) + { + // Write the host key with respect to tunnel host + settings->Write(wxT("HostKeys/") + m_tunnelhost, newHostKey); + bIsVerified = true; + } + } + } + + return bIsVerified; +} + +CSubThread::CSubThread(const struct sockaddr_in sin, const wxString remote_desthost, const unsigned int remote_destport, + LIBSSH2_SESSION *session, int forwardsock) + : m_sin(sin), m_remote_desthost(remote_desthost), m_remote_destport(remote_destport), + m_subThreadSession(session), m_forwardsock(forwardsock) +{ +} + +CSubThread::~CSubThread(void) +{ + g_SSHThreadMutex.Lock(); + g_setSocketDescriptor.erase(m_forwardsock); + g_SSHThreadMutex.Unlock(); +} + +void * +CSubThread::Entry() +{ + fd_set fds; + struct timeval tv; + ssize_t len, wr; + char buf[20480]; + int rc, i = 0; + + const char *shost = inet_ntoa(m_sin.sin_addr); + unsigned int sport = ntohs(m_sin.sin_port); + + wxLogInfo(wxT("Forwarding connection from %s:%d to %s:%d"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), + sport, m_remote_desthost.c_str(), m_remote_destport); + + /* Must use blocking here to avoid connect errors */ + //libssh2_session_set_blocking(m_subThreadSession, 1); + + while((m_channel = libssh2_channel_direct_tcpip_ex(m_subThreadSession, m_remote_desthost.mb_str(), + m_remote_destport, shost, sport)) == NULL) + { + rc = libssh2_session_last_error(m_subThreadSession, NULL, NULL, 0); + if (rc == LIBSSH2_ERROR_EAGAIN) + Sleep(10); + else + break; + } + + /* Must use non-blocking IO hereafter due to the current libssh2 API */ + libssh2_session_set_blocking(m_subThreadSession, 0); + + if (!m_channel) + { + wxLogInfo(_("SSH error: Could not open a direct-tcpip channel!")); + goto shutdown; + } + + while (1) + { + FD_ZERO(&fds); + FD_SET(m_forwardsock, &fds); + tv.tv_sec = 0; + tv.tv_usec = 100000; + rc = select(m_forwardsock + 1, &fds, NULL, NULL, &tv); + memset(buf, 0, sizeof(buf)); + if (-1 == rc) + { + wxLogInfo(_("SSH error: select failed with error code %d"), wxSysErrorCode()); + goto shutdown; + } + if (rc && FD_ISSET(m_forwardsock, &fds)) + { + len = recv(m_forwardsock, buf, sizeof(buf), 0); + if (len < 0) + { + wxLogInfo(_("SSH error: read failed with error code %d"), wxSysErrorCode()); + goto shutdown; + } + else if (0 == len) + { + wxLogInfo(_("The client at %s:%d disconnected!"), wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); + goto shutdown; + } + wr = 0; + do + { + i = libssh2_channel_write(m_channel, buf, len); + + if (i < 0) + { + wxLogInfo(_("SSH error: libssh2_channel_write with error code %d"), i); + goto shutdown; + } + wr += i; + } + while (i > 0 && wr < len); + } + while (1) + { + len = libssh2_channel_read(m_channel, buf, sizeof(buf)); + + if (LIBSSH2_ERROR_EAGAIN == len) + break; + else if (len < 0) + { + wxLogInfo(_("SSH error: libssh2_channel_read with error code %d"), (int)len); + goto shutdown; + } + wr = 0; + while (wr < len) + { + i = send(m_forwardsock, buf + wr, len - wr, 0); + if (i <= 0) + { + wxLogInfo(_("SSH error: write failed with error code %d"), wxSysErrorCode()); + goto shutdown; + } + wr += i; + } + if (libssh2_channel_eof(m_channel)) + { + wxLogInfo(_("Connection at %s:%d disconnected by server"), + wxString(inet_ntoa(m_sin.sin_addr), wxConvLibc).c_str(), sport); + goto shutdown; + } + } + } +shutdown: +#ifdef WIN32 + closesocket(m_forwardsock); +#else + close(m_forwardsock); +#endif + + if (m_channel) + { + libssh2_channel_close(m_channel); + libssh2_channel_free(m_channel); + m_channel = NULL; + } + + return NULL; +} + +void LogSSHTunnelErrors(const wxString &msg, const int &id, struct _LIBSSH2_SESSION *session) +{ + g_SSHThreadMutex.TryLock(); + + wxString errorMsg = msg; + // If session is not NULL then fetch the last error on that session + if (session) + { + char *errmsg; + int errmsg_len; + libssh2_session_last_error(session, &errmsg, &errmsg_len, 0); + if (errmsg_len > 0) + { + wxString errmsg_s(errmsg, wxConvLibc); + errorMsg += wxString::Format(_(" [%s]"), errmsg_s.c_str()); + } + } + + wxCommandEvent event(SSH_TUNNEL_ERROR_EVENT, id); + // Give it some contents + event.SetString(errorMsg); + + // Do send it + wxPostEvent(winMain, event); + + g_SSHThreadMutex.Unlock(); +} diff --git a/utils/sysLogger.cpp b/utils/sysLogger.cpp new file mode 100644 index 0000000..e2319d7 --- /dev/null +++ b/utils/sysLogger.cpp @@ -0,0 +1,312 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysLogger.cpp - Log handling class +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + +// wxWindows headers +#include +#include +#include +#include + +// App headers +#if !defined(PGSCLI) +#include "copyright.h" // needed for APPNAME_L caption +#endif // PGSCLI + +#include "utils/sysLogger.h" + +wxLogLevel sysLogger::logLevel = LOG_ERRORS; +wxString sysLogger::logFile = wxT("debug.log"); + +#if !wxCHECK_VERSION(2, 9, 0) + +// IMPLEMENT_LOG_FUNCTION(Sql) from wx../common/log.c +void wxVLogQuietError(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_ERRORS) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_QuietError, s_szBuf, time(NULL)); + + } +} + +void wxLogQuietError(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogQuietError(szFormat, argptr); + va_end(argptr); +} + + +void wxVLogSql(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_SQL) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_Sql, s_szBuf, time(NULL)); + + } +} + +void wxLogSql(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogSql(szFormat, argptr); + va_end(argptr); +} + + + +void wxVLogNotice(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_NOTICE) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_Notice, s_szBuf, time(NULL)); + } +} + +void wxLogNotice(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogNotice(szFormat, argptr); + va_end(argptr); +} + +void wxVLogScript(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_SQL) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_Script, s_szBuf, time(NULL)); + } +} + +void wxLogScript(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogScript(szFormat, argptr); + va_end(argptr); +} + +void wxVLogScriptVerbose(const wxChar *szFormat, va_list argptr) +{ + static wxChar s_szBuf[8192]; + + if (sysLogger::logLevel >= LOG_DEBUG) + { + wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); + wxLog::OnLog(wxLOG_ScriptVerbose, s_szBuf, time(NULL)); + } +} + +void wxLogScriptVerbose(const wxChar *szFormat, ...) +{ + va_list argptr; + va_start(argptr, szFormat); + wxVLogScriptVerbose(szFormat, argptr); + va_end(argptr); +} + +#endif + +#if wxCHECK_VERSION(2, 9, 0) +void sysLogger::DoLogTextAtLevel(wxLogLevel level, const wxString &msg) +#else +void sysLogger::DoLog(wxLogLevel level, const wxChar *msg, time_t timestamp) +#endif +{ + wxString msgtype, preamble; + int icon = 0; + + switch (level) + { + case wxLOG_FatalError: + msgtype = wxT("FATAL "); + preamble = _("A fatal error has occurred:\n\n"); + icon = wxICON_ERROR; + break; + + case wxLOG_Error: + msgtype = wxT("ERROR "); + preamble = _("An error has occurred:\n\n"); + icon = wxICON_ERROR; + break; + + case wxLOG_QuietError: + msgtype = wxT("ERROR "); + break; + + case wxLOG_Warning: + msgtype = wxT("WARNING"); + preamble = _("Warning:\n\n"); + icon = wxICON_EXCLAMATION; + break; + + case wxLOG_Message: + msgtype = wxT("MESSAGE"); + preamble = wxT(""); + icon = wxICON_INFORMATION; + break; + + case wxLOG_Info: + msgtype = wxT("INFO "); + break; + + case wxLOG_Status: + msgtype = wxT("STATUS "); + break; + + case wxLOG_Notice: + msgtype = wxT("NOTICE "); + break; + + case wxLOG_Sql: + msgtype = wxT("QUERY "); + break; + + case wxLOG_Script: + msgtype = wxT("SCRIPT "); + break; + + case wxLOG_ScriptVerbose: + msgtype = wxT("SCRIPT "); + break; + + case wxLOG_Trace: + msgtype = wxT("TRACE "); + break; + + case wxLOG_Debug: + msgtype = wxT("DEBUG "); + break; + + default: + msgtype = wxT("UNKNOWN"); + icon = wxICON_INFORMATION; + break; + } + + wxString fullmsg; + +#if wxCHECK_VERSION(2, 9, 0) + // Build the message. + fullmsg << msgtype << wxT(": ") << msg; +#else + // Convert the timestamp + wxDateTime *time = new wxDateTime(timestamp); + + // Build the message. + fullmsg << time->FormatISODate() << wxT(" ") << + time->FormatISOTime() << wxT(" ") << msgtype << wxT(": ") << msg; + + // Make sure to delete the time that we allocated + delete time; +#endif + + // Display the message if required + switch (logLevel) + { + case LOG_NONE: + break; + + case LOG_ERRORS: + if (level == wxLOG_FatalError || + level == wxLOG_Error || + level == wxLOG_QuietError) + WriteLog(fullmsg); + break; + + case LOG_NOTICE: + if (level == wxLOG_FatalError || + level == wxLOG_Error || + level == wxLOG_QuietError || + level == wxLOG_Notice) + WriteLog(fullmsg); + break; + + case LOG_SQL: + if (level == wxLOG_FatalError || + level == wxLOG_Error || + level == wxLOG_QuietError || + level == wxLOG_Message || + level == wxLOG_Status || + level == wxLOG_Notice || + level == wxLOG_Sql || + level == wxLOG_Script) + WriteLog(fullmsg); + break; + + case LOG_DEBUG: + WriteLog(fullmsg); + break; + } + + // Display a messagebox if required. +#if !defined(PGSCLI) + if (icon != 0 && !SilenceMessage(msg)) + wxMessageBox(preamble + wxGetTranslation(msg), appearanceFactory->GetLongAppName(), wxOK | wxCENTRE | icon); +#endif // PGSCLI +} + + +void sysLogger::WriteLog(const wxString &msg) +{ + wxString pid, logfile; + + // Disable logging to prevent recursion in the event of a problem + wxLogNull foo; + + pid.Printf(wxT("%ld"), wxGetProcessId()); + logfile.Printf(wxT("%s"), logFile.c_str()); + logfile.Replace(wxT("%ID"), pid); + + wxFFile file(logfile, wxT("a")); + +#if !defined(PGSCLI) + if (!file.IsOpened()) + { + wxMessageBox(_("Cannot open the logfile!"), _("FATAL"), wxOK | wxCENTRE | wxICON_ERROR); + return; + } +#endif // PGSCLI + + file.Write(msg + wxT("\n")); + file.Close(); +} + +// Check to see if a message should be silenced (because it's meaningless +// and cannot be silenced at source +bool sysLogger::SilenceMessage(const wxString &msg) +{ +#ifdef __WXMAC__ + // This one crops up on the Mac and originates from the logging code + // for no obviously apparent reason. + if (msg.Contains(_("can't flush file descriptor"))) + return true; +#endif + return false; +} + diff --git a/utils/sysProcess.cpp b/utils/sysProcess.cpp new file mode 100644 index 0000000..cc3540a --- /dev/null +++ b/utils/sysProcess.cpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysProcess.cpp - External process +// +////////////////////////////////////////////////////////////////////////// + + +// wxWindows headers +#include + + +// App headers +#include "pgAdmin3.h" +#include "utils/sysProcess.h" + + +sysProcess::sysProcess(wxEvtHandler *evh, wxMBConv &conv) + : wxProcess(evh), m_conv(conv) +{ + pid = 0; + Redirect(); +} + + +sysProcess *sysProcess::Create(const wxString &exec, wxEvtHandler *evh, wxArrayString *env, wxMBConv &conv) +{ + sysProcess *proc = new sysProcess(evh, conv); + if (env) + proc->SetEnvironment(*env); + + if (!proc->Run(exec)) + { + delete proc; + proc = 0; + } + return proc; +} + + +bool sysProcess::Run(const wxString &exec) +{ + pid = wxExecute(exec, wxEXEC_ASYNC, this); + return (pid != 0); +} + + +void sysProcess::SetEnvironment(const wxArrayString &environment) +{ + size_t i; + for (i = 0 ; i < environment.GetCount() ; i++) + { + wxString str = environment.Item(i); + wxSetEnv(str.BeforeFirst('='), str.AfterFirst('=')); + } +} + + +void sysProcess::Abort() +{ + if (pid) + wxKill(pid, wxSIGTERM); +} + + +wxString sysProcess::ReadInputStream() +{ + if (IsInputAvailable()) + return ReadStream(GetInputStream()); + return wxEmptyString; +} + + +wxString sysProcess::ReadErrorStream() +{ + if (IsErrorAvailable()) + return ReadStream(GetErrorStream()); + return wxEmptyString; +} + +void sysProcess::WriteOutputStream(const wxString &out) +{ + // With wxEOL_DOS (=wxEOL_NATIVE in Windows) WriteString() will turn each '\n' + // into "\r\n", thus making "\r\n" a wrong "\r\r\n". + // With wxEOL_UNIX it passes EOL characters as-is, which is preferable. + wxTextOutputStream tos(*GetOutputStream(), wxEOL_UNIX); + tos.WriteString(out); +} + +wxString sysProcess::ReadStream(wxInputStream *input) +{ + wxString str; + + char buffer[1000 + 1]; + size_t size = 1; + while (size && !input->Eof()) + { + input->Read(buffer, sizeof(buffer) - 1); + size = input->LastRead(); + if (size) + { + buffer[size] = 0; + str.Append(wxString::Format(wxT("%s"), wxString(buffer, m_conv).c_str())); + } + } + return str; +} + diff --git a/utils/sysSettings.cpp b/utils/sysSettings.cpp new file mode 100644 index 0000000..82bb1c7 --- /dev/null +++ b/utils/sysSettings.cpp @@ -0,0 +1,944 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// sysSettings.cpp - Settings handling class +// +// Note: This class stores and manages all the applications settings. +// Settings are all read in the ctor, but may be written either in +// the relevant SetXXX() member function for rarely written settings +// or in the dtor for regularly changed settings such as form sizes. +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" + + +// wxWindows headers +#include +#include +#include +#include +#include +#include +#include +#include +// App headers +#include "utils/sysSettings.h" +#include "utils/sysLogger.h" +#include "utils/misc.h" +sysSettings::sysSettings(const wxString &name) : wxConfig(name) +{ + // Open the default settings file + defaultSettings = NULL; + if (!settingsIni.IsEmpty()) + { + wxFileInputStream fst(settingsIni); + defaultSettings = new wxFileConfig(fst); + } + + // Convert settings from pre-1.5 + long i, serverCount; + Read(wxT("Servers/Count"), &serverCount, 0L); + for (i = 1 ; i <= serverCount ; i++) + { + if (moveStringValue(wxT("Servers/Database%d"), wxT("Servers/%d/Database"), i)) + { + moveStringValue(wxT("Servers/Description%d"), wxT("Servers/%d/Description"), i); + moveStringValue(wxT("Servers/LastDatabase%d"), wxT("Servers/%d/LastDatabase"), i); + moveStringValue(wxT("Servers/LastSchema%d"), wxT("Servers/%d/LastSchema"), i); + moveStringValue(wxT("Servers/Server%d"), wxT("Servers/%d/Server"), i); + moveStringValue(wxT("Servers/ServiceId%d"), wxT("Servers/%d/ServiceId"), i); + moveStringValue(wxT("Servers/StorePWD%d"), wxT("Servers/%d/StorePWD"), i); + moveStringValue(wxT("Servers/Rolename%d"), wxT("Servers/%d/Rolename"), i); + moveStringValue(wxT("Servers/Username%d"), wxT("Servers/%d/Username"), i); + moveLongValue(wxT("Servers/Port%d"), wxT("Servers/%d/Port"), i); + moveLongValue(wxT("Servers/SSL%d"), wxT("Servers/%d/SSL"), i); + } + } +} + +sysSettings::~sysSettings() +{ + + if(defaultSettings) + { + delete defaultSettings; + defaultSettings = NULL; + } +} + +bool sysSettings::GetDisplayOption(const wxString &objtype, bool GetDefault) +{ + bool retval, def = true; + wxString engtype; + + if (objtype == _("Databases")) + engtype = wxT("Databases"); + else if (objtype == _("Tablespaces")) + engtype = wxT("Tablespaces"); + else if (objtype == _("pgAgent Jobs")) + engtype = wxT("pgAgent Jobs"); + else if (objtype == _("pgpro_scheduler")) + engtype = wxT("pgpro_scheduler"); + else if (objtype == _("Groups/group Roles")) + engtype = wxT("Groups-login Roles"); + else if (objtype == _("Users/login Roles")) + engtype = wxT("Users-login Roles"); + else if (objtype == _("Resource Queues")) + engtype = wxT("Resource Queues"); + else if (objtype == _("Resource Groups")) + engtype = wxT("Resource Groups"); + else if (objtype == _("Catalogs")) + engtype = wxT("Catalogs"); + else if (objtype == _("Casts")) + { + engtype = wxT("Casts"); + def = false; + } + else if (objtype == _("Foreign Data Wrappers")) + { + engtype = wxT("Foreign Data Wrappers"); + def = false; + } + else if (objtype == _("Foreign Servers")) + { + engtype = wxT("Foreign Servers"); + def = false; + } + else if (objtype == _("User Mappings")) + { + engtype = wxT("User Mappings"); + def = false; + } + else if (objtype == _("Foreign Tables")) + { + engtype = wxT("Foreign Tables"); + def = false; + } + else if (objtype == _("Languages")) + { + engtype = wxT("Languages"); + def = false; + } + else if (objtype == _("Extensions")) + engtype = wxT("Extensions"); + else if (objtype == _("Publications")) + engtype = wxT("Publications"); + else if (objtype == _("Subscriptions")) + engtype = wxT("Subscriptions"); + else if (objtype == _("Synonyms")) + engtype = wxT("Synonyms"); + else if (objtype == _("Schemas")) + engtype = wxT("Schemas"); + else if (objtype == _("Slony-I Clusters")) + engtype = wxT("Slony-I Clusters"); + else if (objtype == _("Aggregates")) + { + engtype = wxT("Aggregates"); + def = false; + } + else if (objtype == _("Conversions")) + { + engtype = wxT("Conversions"); + def = false; + } + else if (objtype == _("Domains")) + engtype = wxT("Domains"); + else if (objtype == _("Functions")) + engtype = wxT("Functions"); + else if (objtype == _("Trigger Functions")) + engtype = wxT("Trigger Functions"); + else if (objtype == _("Packages")) + engtype = wxT("Packages"); + else if (objtype == _("Procedures")) + engtype = wxT("Procedures"); + else if (objtype == _("Operators")) + { + engtype = wxT("Operators"); + def = false; + } + else if (objtype == _("Operator Classes")) + { + engtype = wxT("Operator Classes"); + def = false; + } + else if (objtype == _("Operator Families")) + { + engtype = wxT("Operator Families"); + def = false; + } + else if (objtype == _("Sequences")) + engtype = wxT("Sequences"); + else if (objtype == _("Tables")) + engtype = wxT("Tables"); + else if (objtype == _("FTS Configurations")) + engtype = wxT("FTS Configurations"); + else if (objtype == _("FTS Dictionaries")) + engtype = wxT("FTS Dictionaries"); + else if (objtype == _("FTS Parsers")) + engtype = wxT("FTS Parsers"); + else if (objtype == _("FTS Templates")) + engtype = wxT("FTS Templates"); + else if (objtype == _("Types")) + { + engtype = wxT("Types"); + def = false; + } + else if (objtype == _("Views")) + engtype = wxT("Views"); + else if (objtype == _("External Tables")) + engtype = wxT("External Tables"); + else if (objtype == _("Event Triggers")) + engtype = wxT("Event Triggers"); + + // If we just want the default, return it. + if (GetDefault) + return def; + + // Otherwise get the reg value. + Read(wxT("Display/") + engtype, &retval, def); + return retval; +} + +void sysSettings::SetDisplayOption(const wxString &objtype, bool display) +{ + wxString engtype; + + if (objtype == _("Databases")) engtype = wxT("Databases"); + else if (objtype == _("Tablespaces")) engtype = wxT("Tablespaces"); + else if (objtype == _("pgAgent Jobs")) engtype = wxT("pgAgent Jobs"); + else if (objtype == _("pgpro_scheduler")) engtype = wxT("pgpro_scheduler"); + else if (objtype == _("Groups/group Roles")) engtype = wxT("Groups-login Roles"); + else if (objtype == _("Users/login Roles")) engtype = wxT("Users-login Roles"); + else if (objtype == _("Resource Queues")) engtype = wxT("Resource Queues"); + else if (objtype == _("Resource Groups")) engtype = wxT("Resource Groups"); + else if (objtype == _("Catalogs")) engtype = wxT("Catalogs"); + else if (objtype == _("Casts")) engtype = wxT("Casts"); + else if (objtype == _("Foreign Data Wrappers")) engtype = wxT("Foreign Data Wrappers"); + else if (objtype == _("Foreign Servers")) engtype = wxT("Foreign Servers"); + else if (objtype == _("User Mappings")) engtype = wxT("User mappings"); + else if (objtype == _("Foreign Tables")) engtype = wxT("Foreign Tables"); + else if (objtype == _("Languages")) engtype = wxT("Languages"); + else if (objtype == _("Event Triggers")) engtype = wxT("Event Triggers"); + else if (objtype == _("Extensions")) engtype = wxT("Extensions"); + else if (objtype == _("Publications")) engtype = wxT("Publications"); + else if (objtype == _("Subscriptions")) engtype = wxT("Subscriptions"); + else if (objtype == _("Synonyms")) engtype = wxT("Synonyms"); + else if (objtype == _("Schemas")) engtype = wxT("Schemas"); + else if (objtype == _("Slony-I Clusters")) engtype = wxT("Slony-I Clusters"); + else if (objtype == _("Aggregates")) engtype = wxT("Aggregates"); + else if (objtype == _("Conversions")) engtype = wxT("Conversions"); + else if (objtype == _("Domains")) engtype = wxT("Domains"); + else if (objtype == _("Functions")) engtype = wxT("Functions"); + else if (objtype == _("Trigger Functions")) engtype = wxT("Trigger Functions"); + else if (objtype == _("Packages")) engtype = wxT("Packages"); + else if (objtype == _("Procedures")) engtype = wxT("Procedures"); + else if (objtype == _("Operators")) engtype = wxT("Operators"); + else if (objtype == _("Operator Classes")) engtype = wxT("Operator Classes"); + else if (objtype == _("Operator Families")) engtype = wxT("Operator Families"); + else if (objtype == _("Sequences")) engtype = wxT("Sequences"); + else if (objtype == _("Tables")) engtype = wxT("Tables"); + else if (objtype == _("FTS Configurations")) engtype = wxT("FTS Configurations"); + else if (objtype == _("FTS Dictionaries")) engtype = wxT("FTS Dictionaries"); + else if (objtype == _("FTS Parsers")) engtype = wxT("FTS Parsers"); + else if (objtype == _("FTS Templates")) engtype = wxT("FTS Templates"); + else if (objtype == _("Types")) engtype = wxT("Types"); + else if (objtype == _("Views")) engtype = wxT("Views"); + else if (objtype == _("External Tables")) engtype = wxT("External Tables"); + + WriteBool(wxT("Display/") + engtype, display); +} + +bool sysSettings::moveStringValue(const wxChar *oldKey, const wxChar *newKey, int index) +{ + wxString k1, k2; + if (index >= 0) + { + k1.Printf(oldKey, index); + k2.Printf(newKey, index); + } + else + { + k1 = oldKey; + k2 = newKey; + } + + if (!Exists(k2) && Exists(k1)) + { + wxString value; + Read(k1, &value, wxEmptyString); + Write(k2, value); + + return true; + } + + return false; +} + + + +bool sysSettings::moveLongValue(const wxChar *oldKey, const wxChar *newKey, int index) +{ + wxString k1, k2; + if (index >= 0) + { + k1.Printf(oldKey, index); + k2.Printf(newKey, index); + } + else + { + k1 = oldKey; + k2 = newKey; + } + + if (!Exists(k2) && Exists(k1)) + { + long value; + Read(k1, &value, 0L); + WriteLong(k2, value); + + return true; + } + + return false; +} + +// Read a string value +bool sysSettings::Read(const wxString &key, wxString *str, const wxString &defaultVal) const +{ + wxString actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, str, actualDefault); +} + +// Return a string value +wxString sysSettings::Read(const wxString &key, const wxString &defaultVal) const +{ + wxString actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, actualDefault); +} + +// Read an int value +bool sysSettings::Read(const wxString &key, int *i, int defaultVal) const +{ + int actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, i, actualDefault); +} + +// Read a long value +bool sysSettings::Read(const wxString &key, long *l, long defaultVal) const +{ + long actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, l, actualDefault); +} + + +// Return a long value +long sysSettings::Read(const wxString &key, long defaultVal) const +{ + long actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, defaultVal); + + return wxConfig::Read(key, actualDefault); +} + +// Read a boolean value +bool sysSettings::Read(const wxString &key, bool *val, bool defaultVal) const +{ + wxString actualDefault = BoolToStr(defaultVal); + wxString str; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + defaultSettings->Read(key, &actualDefault, BoolToStr(defaultVal)); + + Read(key, &str, actualDefault); + *val = StrToBool(str); + return true; +} + +// Read a point value +wxPoint sysSettings::Read(const wxString &key, const wxPoint &defaultVal) const +{ + wxPoint actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + { + actualDefault.x = defaultSettings->Read(key + wxT("/Left"), defaultVal.x); + actualDefault.y = defaultSettings->Read(key + wxT("/Top"), defaultVal.y); + } + + return wxPoint(wxConfig::Read(key + wxT("/Left"), actualDefault.x), + wxConfig::Read(key + wxT("/Top"), actualDefault.y)); +} + +// Read a size value +wxSize sysSettings::Read(const wxString &key, const wxSize &defaultVal) const +{ + wxSize actualDefault = defaultVal; + + // Get the default from the defaults file, in preference + // to the hardcoded value + if (defaultSettings) + { + actualDefault.x = defaultSettings->Read(key + wxT("/Width"), defaultVal.x); + actualDefault.y = defaultSettings->Read(key + wxT("/Height"), defaultVal.y); + } + + return wxSize(wxConfig::Read(key + wxT("/Width"), actualDefault.x), + wxConfig::Read(key + wxT("/Height"), actualDefault.y)); +} + +// Write a boolean value +bool sysSettings::WriteBool(const wxString &key, bool value) +{ + return Write(key, BoolToStr(value)); +} + +// Write a point value +bool sysSettings::WritePoint(const wxString &key, const wxPoint &value) +{ + bool rc = wxConfig::Write(key + wxT("/Left"), value.x); + if (rc) + rc = wxConfig::Write(key + wxT("/Top"), value.y); + return rc; +} + +// Write a size value +bool sysSettings::WriteSize(const wxString &key, const wxSize &value) +{ + bool rc = wxConfig::Write(key + wxT("/Width"), value.x); + if (rc) + rc = wxConfig::Write(key + wxT("/Height"), value.y); + return rc; +} + + +////////////////////////////////////////////////////////////////////////// +// Log +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetLogFile() +{ + wxString logFile; + + // Try to get a vaguely usable default path. + char *homedir; +#ifdef __WXMSW__ + char *homedrive; +#endif + + wxString deflog; + +#ifdef __WXMSW__ + homedrive = getenv("HOMEDRIVE"); + homedir = getenv("HOMEPATH"); +#else + homedir = getenv("HOME"); +#endif + + if (!homedir) + deflog = wxT("pgadmin.log"); + else + { + +#ifdef __WXMSW__ +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &paths = wxStandardPaths::Get(); +#else + wxStandardPaths paths; +#endif + deflog = paths.GetDocumentsDir(); + deflog += wxT("\\pgadmin.log"); +#else + deflog = wxString::FromAscii(homedir); + deflog += wxT("/pgadmin.log"); +#endif + } + + Read(wxT("LogFile"), &logFile, deflog); + + return logFile; +} + +////////////////////////////////////////////////////////////////////////// +// Help files +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetSlonyHelpPath() +{ + wxString path; + + Read(wxT("SlonyHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} + +wxString sysSettings::GetPgHelpPath() +{ + wxString path; + + Read(wxT("PostgreSQLHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} + +wxString sysSettings::GetEdbHelpPath() +{ + wxString path; + + Read(wxT("EnterpriseDBHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} + +wxString sysSettings::GetGpHelpPath() +{ + wxString path; + + Read(wxT("GreenplumDBHelpPath"), &path, wxT("")); + path = CleanHelpPath(path); + + if (!HelpPathValid(path)) + path = wxEmptyString; + + return path; +} +////////////////////////////////////////////////////////////////////////// +// Copy quoting +////////////////////////////////////////////////////////////////////////// + +int sysSettings::GetCopyQuoting() +{ + wxString val; + + Read(wxT("Copy/Quote"), &val, wxT("Strings")); + if (val == wxT("All")) + return 2; + else if (val == wxT("Strings")) + return 1; + else + return 0; +} + +void sysSettings::SetCopyQuoting(const int i) +{ + switch (i) + { + case 2: + Write(wxT("Copy/Quote"), wxT("All")); + break; + case 1: + Write(wxT("Copy/Quote"), wxT("Strings")); + break; + case 0: + Write(wxT("Copy/Quote"), wxT("None")); + break; + default: + break; + } +} + +////////////////////////////////////////////////////////////////////////// +// Export quoting +////////////////////////////////////////////////////////////////////////// + +int sysSettings::GetExportQuoting() +{ + wxString val; + + Read(wxT("Export/Quote"), &val, wxT("Strings")); + if (val == wxT("All")) + return 2; + else if (val == wxT("Strings")) + return 1; + else + return 0; +} + +void sysSettings::SetExportQuoting(const int i) +{ + switch (i) + { + case 2: + Write(wxT("Export/Quote"), wxT("All")); + break; + case 1: + Write(wxT("Export/Quote"), wxT("Strings")); + break; + case 0: + Write(wxT("Export/Quote"), wxT("None")); + break; + default: + break; + } +} + +////////////////////////////////////////////////////////////////////////// +// Export quoting +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetExportRowSeparator() +{ + wxString val; +#ifdef __WXMSW__ + Read(wxT("Export/RowSeparator"), &val, wxT("CR/LF")); +#else + Read(wxT("Export/RowSeparator"), &val, wxT("LF")); +#endif + if (val == wxT("CR/LF")) + return wxT("\r\n"); + else + return wxT("\n"); +} + +void sysSettings::SetExportRowSeparator(const wxString &s) +{ + if (s == wxT("\r\n")) + Write(wxT("Export/RowSeparator"), wxT("CR/LF")); + else + Write(wxT("Export/RowSeparator"), wxT("LF")); +} + +////////////////////////////////////////////////////////////////////////// +// System Font +////////////////////////////////////////////////////////////////////////// + +wxFont sysSettings::GetSystemFont() +{ + wxString fontName; + + Read(wxT("Font"), &fontName, wxEmptyString); + + if (fontName.IsEmpty()) + return wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT); + else + return wxFont(fontName); +} + +void sysSettings::SetSystemFont(const wxFont &font) +{ + wxString fontName = font.GetNativeFontInfoDesc(); + + if (fontName == wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT).GetNativeFontInfoDesc()) + Write(wxT("Font"), wxString(wxEmptyString)); + else + Write(wxT("Font"), fontName); +} + +////////////////////////////////////////////////////////////////////////// +// SQL Font +////////////////////////////////////////////////////////////////////////// + +wxFont sysSettings::GetSQLFont() +{ + wxString fontName; + + Read(wxT("frmQuery/Font"), &fontName, wxEmptyString); + + if (fontName.IsEmpty()) + { +#ifdef __WXMSW__ + return wxFont(9, wxTELETYPE, wxNORMAL, wxNORMAL); +#else +#ifdef __WXGTK__ + return wxFont(10, wxTELETYPE, wxNORMAL, wxNORMAL); +#else + return wxFont(12, wxTELETYPE, wxNORMAL, wxNORMAL); +#endif +#endif + } + else + return wxFont(fontName); +} + +void sysSettings::SetSQLFont(const wxFont &font) +{ + wxString fontName = font.GetNativeFontInfoDesc(); + + Write(wxT("frmQuery/Font"), fontName); +} + +////////////////////////////////////////////////////////////////////////// +// Database Designer Font +////////////////////////////////////////////////////////////////////////// + +wxFont sysSettings::GetDDFont() +{ + wxString fontName; + + Read(wxT("DDFont"), &fontName, wxEmptyString); + + if (fontName.IsEmpty()) + return wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT); + else + return wxFont(fontName); +} + +void sysSettings::SetDDFont(const wxFont &font) +{ + wxString fontName = font.GetNativeFontInfoDesc(); + + if (fontName == wxSystemSettings::GetFont(wxSYS_ICONTITLE_FONT).GetNativeFontInfoDesc()) + Write(wxT("DDFont"), wxString(wxEmptyString)); + else + Write(wxT("DDFont"), fontName); +} + +////////////////////////////////////////////////////////////////////////// +// Language +////////////////////////////////////////////////////////////////////////// + +wxString sysSettings::GetCanonicalLanguageName() +{ + const wxLanguageInfo *langInfo; + + langInfo = wxLocale::GetLanguageInfo(Read(wxT("LanguageId"), wxLANGUAGE_DEFAULT)); + + if (langInfo) + return langInfo->CanonicalName; + + return wxEmptyString; +} + +void sysSettings::SetCanonicalLanguage(const wxLanguage &lang) +{ + if (wxLocale::GetLanguageName(lang) != GetCanonicalLanguageName()) + { + delete locale; + locale = new wxLocale(); + if (locale->Init(lang)) + { +#ifdef __LINUX__ + { + wxLogNull noLog; + locale->AddCatalog(wxT("fileutils")); + } +#endif + locale->AddCatalog(wxT("pgadmin3")); + settings->WriteLong(wxT("LanguageId"), (long)lang); + } + } +} + +////////////////////////////////////////////////////////////////////////// +// Get system wide configuration file names +////////////////////////////////////////////////////////////////////////// +wxString sysSettings::GetConfigFile(configFileName cfgname) +{ + wxASSERT_MSG(cfgname == sysSettings::PGPASS, + wxT("Handles only pgpass configuration")); + if (cfgname == PGPASS) + { +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + wxString fname; + bool bpsfile = wxGetEnv(wxT("PGPASSFILE"), &fname); + if (!bpsfile) + { + fname = stdp.GetUserConfigDir(); +#ifdef WIN32 + fname += wxT("\\postgresql"); + if (!wxDirExists(fname)) + wxMkdir(fname); + fname += wxT("\\pgpass.conf"); + } +#else + fname += wxT("/.pgpass"); + } +#endif + else + { + if(!wxFileName::FileExists(fname)) + { + wxFileName dirTemp = wxFileName::DirName(fname); + /* + * wxFileName::DirName() does not return the directory path of + * the file. It assumes that the given path is of a directory, + * when the specified file/directory does not exist. + * + * Hence - removeing it to get the actual parent directory. + */ + dirTemp.RemoveLastDir(); + + if (!dirTemp.DirExists()) + { + wxFileName dir = dirTemp; + + // Decide which are folders we need to create + wxString sRemoveOnError = dirTemp.GetPath(); + + while(!dirTemp.DirExists()) + { + sRemoveOnError = dirTemp.GetPath(); + dirTemp.RemoveLastDir(); + } + + if (!dir.Mkdir(0755, wxPATH_MKDIR_FULL)) + { + // In case of failure decide - we may need to delete + // the created directory structure from exists parent + // directory. + if (wxDir::Exists(sRemoveOnError)) + wxFileName::Rmdir(sRemoveOnError); + } + } + } + } + + wxFile f; + if (!f.Exists(fname)) + f.Create(fname, false, wxS_IRUSR | wxS_IWUSR); + + return fname; + } + + return wxT(""); +} + + +wxString sysSettings::GetFavouritesFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_favourites.xml"); +#else + tmp += wxT("/.pgadminfavourites"); +#endif + + Read(wxT("FavouritesFile"), &s, tmp); + + return s; +} + + +wxString sysSettings::GetMacrosFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_macros.xml"); +#else + tmp += wxT("/.pgadminmacros"); +#endif + + Read(wxT("MacrosFile"), &s, tmp); + + return s; +} +wxString sysSettings::GetAutoReplaceFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_autoreplace.xml"); +#else + tmp += wxT("/.pgadminautoreplace"); +#endif + + Read(wxT("AutoReplaceFile"), &s, tmp); + + return s; +} + + +wxString sysSettings::GetHistoryFile() +{ + wxString s, tmp; + +#if wxCHECK_VERSION(2, 9, 5) + wxStandardPaths &stdp = wxStandardPaths::Get(); +#else + wxStandardPaths stdp; +#endif + tmp = stdp.GetUserConfigDir(); +#ifdef WIN32 + tmp += wxT("\\postgresql"); + if (!wxDirExists(tmp)) + wxMkdir(tmp); + tmp += wxT("\\pgadmin_histoqueries.xml"); +#else + tmp += wxT("/.pgadmin_histoqueries"); +#endif + + Read(wxT("History/File"), &s, tmp); + + return s; +} + diff --git a/utils/tab-complete.inc b/utils/tab-complete.inc new file mode 100644 index 0000000..98b7a35 --- /dev/null +++ b/utils/tab-complete.inc @@ -0,0 +1,1741 @@ +typedef struct SchemaQuery +{ + /* + * Name of catalog or catalogs to be queried, with alias, eg. + * "pg_catalog.pg_class c". Note that "pg_namespace n" will be added. + */ + const char *catname; + + /* + * Selection condition --- only rows meeting this condition are candidates + * to display. If catname mentions multiple tables, include the necessary + * join condition here. For example, "c.relkind = 'r'". Write NULL (not + * an empty string) if not needed. + */ + const char *selcondition; + + /* + * Visibility condition --- which rows are visible without schema + * qualification? For example, "pg_catalog.pg_table_is_visible(c.oid)". + */ + const char *viscondition; + + /* + * Namespace --- name of field to join to pg_namespace.oid. For example, + * "c.relnamespace". + */ + const char *namespace; + + /* + * Result --- the appropriately-quoted name to return, in the case of an + * unqualified name. For example, "pg_catalog.quote_ident(c.relname)". + */ + const char *result; + + /* + * In some cases a different result must be used for qualified names. + * Enter that here, or write NULL if result can be used. + */ + const char *qualresult; +} SchemaQuery; + + +/* + * Communication variables set by COMPLETE_WITH_FOO macros and then used by + * the completion callback functions. Ugly but there is no better way. + */ +static const char *completion_charp; /* to pass a string */ +static const char *const * completion_charpp; /* to pass a list of strings */ +static const char *completion_info_charp; /* to pass a second string */ + +/* + * Assembly instructions for schema queries + */ + +static const SchemaQuery Query_for_list_of_aggregates = { + /* catname */ + "pg_catalog.pg_proc p", + /* selcondition */ + "p.proisagg", + /* viscondition */ + "pg_catalog.pg_function_is_visible(p.oid)", + /* namespace */ + "p.pronamespace", + /* result */ + "pg_catalog.quote_ident(p.proname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_datatypes = { + /* catname */ + "pg_catalog.pg_type t", + /* selcondition --- ignore table rowtypes and array types */ + "(t.typrelid = 0 " + " OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) " + "AND t.typname !~ '^_'", + /* viscondition */ + "pg_catalog.pg_type_is_visible(t.oid)", + /* namespace */ + "t.typnamespace", + /* result */ + "pg_catalog.format_type(t.oid, NULL)", + /* qualresult */ + "pg_catalog.quote_ident(t.typname)" +}; + +static const SchemaQuery Query_for_list_of_domains = { + /* catname */ + "pg_catalog.pg_type t", + /* selcondition */ + "t.typtype = 'd'", + /* viscondition */ + "pg_catalog.pg_type_is_visible(t.oid)", + /* namespace */ + "t.typnamespace", + /* result */ + "pg_catalog.quote_ident(t.typname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_functions = { + /* catname */ + "pg_catalog.pg_proc p", + /* selcondition */ + NULL, + /* viscondition */ + "pg_catalog.pg_function_is_visible(p.oid)", + /* namespace */ + "p.pronamespace", + /* result */ + "pg_catalog.quote_ident(p.proname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_indexes = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('i')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_sequences = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('S')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_tables = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('r')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_tisv = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('r', 'i', 'S', 'v')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_tsv = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('r', 'S', 'v')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + +static const SchemaQuery Query_for_list_of_views = { + /* catname */ + "pg_catalog.pg_class c", + /* selcondition */ + "c.relkind IN ('v')", + /* viscondition */ + "pg_catalog.pg_table_is_visible(c.oid)", + /* namespace */ + "c.relnamespace", + /* result */ + "pg_catalog.quote_ident(c.relname)", + /* qualresult */ + NULL +}; + + +/* + * Queries to get lists of names of various kinds of things, possibly + * restricted to names matching a partially entered name. In these queries, + * %s will be replaced by the text entered so far (suitably escaped to + * become a SQL literal string). %d will be replaced by the length of the + * string (in unescaped form). A second %s, if present, will be replaced + * by a suitably-escaped version of the string provided in + * completion_info_charp. + * + * Beware that the allowed sequences of %s and %d are determined by + * _complete_from_query(). + */ + +#define Query_for_list_of_attributes \ +"SELECT pg_catalog.quote_ident(attname) "\ +" FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c "\ +" WHERE c.oid = a.attrelid "\ +" AND a.attnum > 0 "\ +" AND NOT a.attisdropped "\ +" AND substring(pg_catalog.quote_ident(attname),1,%d)='%s' "\ +" AND pg_catalog.quote_ident(relname)='%s' "\ +" AND pg_catalog.pg_table_is_visible(c.oid)" + +#define Query_for_list_of_databases \ +"SELECT pg_catalog.quote_ident(datname) FROM pg_catalog.pg_database "\ +" WHERE substring(pg_catalog.quote_ident(datname),1,%d)='%s'" + +#define Query_for_list_of_tablespaces \ +"SELECT pg_catalog.quote_ident(spcname) FROM pg_catalog.pg_tablespace "\ +" WHERE substring(pg_catalog.quote_ident(spcname),1,%d)='%s'" + +#define Query_for_list_of_encodings \ +" SELECT DISTINCT pg_catalog.pg_encoding_to_char(conforencoding) "\ +" FROM pg_catalog.pg_conversion "\ +" WHERE substring(pg_catalog.pg_encoding_to_char(conforencoding),1,%d)=UPPER('%s')" + +#define Query_for_list_of_languages \ +"SELECT pg_catalog.quote_ident(lanname) "\ +" FROM pg_language "\ +" WHERE lanname != 'internal' "\ +" AND substring(pg_catalog.quote_ident(lanname),1,%d)='%s' " + +#define Query_for_list_of_schemas \ +"SELECT pg_catalog.quote_ident(nspname) FROM pg_catalog.pg_namespace "\ +" WHERE substring(pg_catalog.quote_ident(nspname),1,%d)='%s'" + +#define Query_for_list_of_set_vars \ +"SELECT name FROM "\ +" (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ +" WHERE context IN ('user', 'superuser') "\ +" UNION ALL SELECT 'constraints' "\ +" UNION ALL SELECT 'transaction' "\ +" UNION ALL SELECT 'session' "\ +" UNION ALL SELECT 'role' "\ +" UNION ALL SELECT 'all') ss "\ +" WHERE substring(name,1,%d)='%s'" + +#define Query_for_list_of_show_vars \ +"SELECT name FROM "\ +" (SELECT pg_catalog.lower(name) AS name FROM pg_catalog.pg_settings "\ +" UNION ALL SELECT 'session authorization' "\ +" UNION ALL SELECT 'all') ss "\ +" WHERE substring(name,1,%d)='%s'" + +#define Query_for_list_of_system_relations \ +"SELECT pg_catalog.quote_ident(relname) "\ +" FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n "\ +" WHERE c.relkind IN ('r', 'v', 's', 'S') "\ +" AND substring(pg_catalog.quote_ident(relname),1,%d)='%s' "\ +" AND c.relnamespace = n.oid "\ +" AND n.nspname = 'pg_catalog'" + +#define Query_for_list_of_roles \ +" SELECT pg_catalog.quote_ident(rolname) "\ +" FROM pg_catalog.pg_roles "\ +" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'" + +#define Query_for_list_of_grant_roles \ +" SELECT pg_catalog.quote_ident(rolname) "\ +" FROM pg_catalog.pg_roles "\ +" WHERE substring(pg_catalog.quote_ident(rolname),1,%d)='%s'"\ +" UNION ALL SELECT 'PUBLIC'" + +/* the silly-looking length condition is just to eat up the current word */ +#define Query_for_table_owning_index \ +"SELECT pg_catalog.quote_ident(c1.relname) "\ +" FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\ +" WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\ +" and (%d = length('%s'))"\ +" and pg_catalog.quote_ident(c2.relname)='%s'"\ +" and pg_catalog.pg_table_is_visible(c2.oid)" + +/* the silly-looking length condition is just to eat up the current word */ +#define Query_for_index_of_table \ +"SELECT pg_catalog.quote_ident(c2.relname) "\ +" FROM pg_catalog.pg_class c1, pg_catalog.pg_class c2, pg_catalog.pg_index i"\ +" WHERE c1.oid=i.indrelid and i.indexrelid=c2.oid"\ +" and (%d = length('%s'))"\ +" and pg_catalog.quote_ident(c1.relname)='%s'"\ +" and pg_catalog.pg_table_is_visible(c2.oid)" + +/* the silly-looking length condition is just to eat up the current word */ +#define Query_for_list_of_tables_for_trigger \ +"SELECT pg_catalog.quote_ident(relname) "\ +" FROM pg_catalog.pg_class"\ +" WHERE (%d = length('%s'))"\ +" AND oid IN "\ +" (SELECT tgrelid FROM pg_catalog.pg_trigger "\ +" WHERE pg_catalog.quote_ident(tgname)='%s')" + +/* + * This is a list of all "things" in Pgsql, which can show up after CREATE or + * DROP; and there is also a query to get a list of them. + */ + +typedef struct +{ + const char *name; + const char *query; /* simple query, or NULL */ + const SchemaQuery *squery; /* schema query, or NULL */ +} pgsql_thing_t; + +static const pgsql_thing_t words_after_create[] = { + {"AGGREGATE", NULL, &Query_for_list_of_aggregates}, + {"CAST", NULL, NULL}, /* Casts have complex structures for names, so + * skip it */ + + /* + * CREATE CONSTRAINT TRIGGER is not supported here because it is designed + * to be used only by pg_dump. + */ + {"CONVERSION", "SELECT pg_catalog.quote_ident(conname) FROM pg_catalog.pg_conversion WHERE substring(pg_catalog.quote_ident(conname),1,%d)='%s'"}, + {"DATABASE", Query_for_list_of_databases}, + {"DOMAIN", NULL, &Query_for_list_of_domains}, + {"FUNCTION", NULL, &Query_for_list_of_functions}, + {"GROUP", Query_for_list_of_roles}, + {"LANGUAGE", Query_for_list_of_languages}, + {"INDEX", NULL, &Query_for_list_of_indexes}, + {"OPERATOR", NULL, NULL}, /* Querying for this is probably not such a + * good idea. */ + {"ROLE", Query_for_list_of_roles}, + {"RULE", "SELECT pg_catalog.quote_ident(rulename) FROM pg_catalog.pg_rules WHERE substring(pg_catalog.quote_ident(rulename),1,%d)='%s'"}, + {"SCHEMA", Query_for_list_of_schemas}, + {"SEQUENCE", NULL, &Query_for_list_of_sequences}, + {"TABLE", NULL, &Query_for_list_of_tables}, + {"TABLESPACE", Query_for_list_of_tablespaces}, + {"TEMP", NULL, NULL}, /* for CREATE TEMP TABLE ... */ + {"TRIGGER", "SELECT pg_catalog.quote_ident(tgname) FROM pg_catalog.pg_trigger WHERE substring(pg_catalog.quote_ident(tgname),1,%d)='%s'"}, + {"TYPE", NULL, &Query_for_list_of_datatypes}, + {"UNIQUE", NULL, NULL}, /* for CREATE UNIQUE INDEX ... */ + {"USER", Query_for_list_of_roles}, + {"VIEW", NULL, &Query_for_list_of_views}, + {NULL, NULL, NULL} /* end of list */ +}; + + +/* The completion function. Acc. to readline spec this gets passed the text + entered to far and its start and end in the readline buffer. The return value + is some partially obscure list format that can be generated by the readline + libraries completion_matches() function, so we don't have to worry about it. +*/ +static char * psql_completion(char *text, int start, int end, void *dbptr) +{ + /* This is the variable we'll return. */ + char *matches = NULL; + + /* These are going to contain some scannage of the input line. */ + char *prev_wd, + *prev2_wd, + *prev3_wd, + *prev4_wd, + *prev5_wd; + + static const char *const sql_commands[] = { + "ABORT", "ALTER", "ANALYZE", "BEGIN", "CHECKPOINT", "CLOSE", "CLUSTER", "COMMENT", + "COMMIT", "COPY", "CREATE", "DEALLOCATE", "DECLARE", "DELETE FROM", "DROP", "END", "EXECUTE", + "EXPLAIN", "FETCH", "GRANT", "INSERT", "LISTEN", "LOAD", "LOCK", "MOVE", "NOTIFY", + "PREPARE", "REINDEX", "RELEASE", "RESET", "REVOKE", "ROLLBACK", "SAVEPOINT", + "SELECT", "SET", "SHOW", "START", "TRUNCATE", "UNLISTEN", "UPDATE", "VACUUM", NULL + }; + + static const char *const backslash_commands[] = { + "\\a", "\\connect", "\\C", "\\cd", "\\copy", "\\copyright", + "\\d", "\\da", "\\db", "\\dc", "\\dC", "\\dd", "\\dD", "\\df", + "\\dg", "\\di", "\\dl", "\\dn", "\\do", "\\dp", "\\ds", "\\dS", + "\\dt", "\\dT", "\\dv", "\\du", + "\\e", "\\echo", "\\encoding", + "\\f", "\\g", "\\h", "\\help", "\\H", "\\i", "\\l", + "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink", + "\\o", "\\p", "\\password", "\\pset", "\\q", "\\qecho", "\\r", "\\set", "\\t", "\\T", + "\\timing", "\\unset", "\\x", "\\w", "\\z", "\\!", NULL + }; + + (void) end; /* not used */ + +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + rl_completion_append_character = ' '; +#endif + + /* Clear a few things. */ + completion_charp = NULL; + completion_charpp = NULL; + completion_info_charp = NULL; + + /* + * Scan the input line before our current position for the last four + * words. According to those we'll make some smart decisions on what the + * user is probably intending to type. TODO: Use strtokx() to do this. + */ + prev_wd = previous_word(start, 0); + prev2_wd = previous_word(start, 1); + prev3_wd = previous_word(start, 2); + prev4_wd = previous_word(start, 3); + prev5_wd = previous_word(start, 4); + + /* If a backslash command was started, continue */ + if (text[0] == '\\') + COMPLETE_WITH_LIST(backslash_commands); + + /* If no previous word, suggest one of the basic sql commands */ + else if (!prev_wd) + COMPLETE_WITH_LIST(sql_commands); + +/* CREATE or DROP but not ALTER (TABLE|DOMAIN|GROUP) sth DROP */ + /* complete with something you can create or drop */ + else if (pg_strcasecmp(prev_wd, "CREATE") == 0 || + (pg_strcasecmp(prev_wd, "DROP") == 0 && + pg_strcasecmp(prev3_wd, "TABLE") != 0 && + pg_strcasecmp(prev3_wd, "DOMAIN") != 0 && + pg_strcasecmp(prev3_wd, "GROUP") != 0)) + matches = complete_create_command(text); + +/* ALTER */ + + /* + * complete with what you can alter (TABLE, GROUP, USER, ...) unless we're + * in ALTER TABLE sth ALTER + */ + else if (pg_strcasecmp(prev_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "TABLE") != 0) + { + static const char *const list_ALTER[] = + {"AGGREGATE", "CONVERSION", "DATABASE", "DOMAIN", "FUNCTION", + "GROUP", "INDEX", "LANGUAGE", "OPERATOR", "ROLE", "SCHEMA", "SEQUENCE", "TABLE", + "TABLESPACE", "TRIGGER", "TYPE", "USER", NULL}; + + COMPLETE_WITH_LIST(list_ALTER); + } + /* ALTER AGGREGATE,FUNCTION */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "AGGREGATE") == 0 || + pg_strcasecmp(prev2_wd, "FUNCTION") == 0)) + { + static const char *const list_ALTERAGG[] = + {"OWNER TO", "RENAME TO", "SET SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERAGG); + } + + /* ALTER CONVERSION,SCHEMA */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 || + pg_strcasecmp(prev2_wd, "SCHEMA") == 0)) + { + static const char *const list_ALTERGEN[] = + {"OWNER TO", "RENAME TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERGEN); + } + + /* ALTER DATABASE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "DATABASE") == 0) + { + static const char *const list_ALTERDATABASE[] = + {"RESET", "SET", "OWNER TO", "RENAME TO", "CONNECTION LIMIT", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDATABASE); + } + + /* ALTER INDEX */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "INDEX") == 0) + { + static const char *const list_ALTERINDEX[] = + {"SET TABLESPACE", "OWNER TO", "RENAME TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERINDEX); + } + + /* ALTER LANGUAGE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "LANGUAGE") == 0) + COMPLETE_WITH_CONST("RENAME TO"); + + /* ALTER USER,ROLE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + (pg_strcasecmp(prev2_wd, "USER") == 0 || + pg_strcasecmp(prev2_wd, "ROLE") == 0)) + { + static const char *const list_ALTERUSER[] = + {"ENCRYPTED", "UNENCRYPTED", "CREATEDB", "NOCREATEDB", "CREATEUSER", + "NOCREATEUSER", "CREATEROLE", "NOCREATEROLE", "INHERIT", "NOINHERIT", + "LOGIN", "NOLOGIN", "CONNECTION LIMIT", "VALID UNTIL", "RENAME TO", + "SUPERUSER", "NOSUPERUSER", "SET", "RESET", NULL}; + + COMPLETE_WITH_LIST(list_ALTERUSER); + } + + /* complete ALTER USER,ROLE ENCRYPTED,UNENCRYPTED with PASSWORD */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0)) + { + COMPLETE_WITH_CONST("PASSWORD"); + } + /* ALTER DOMAIN */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "DOMAIN") == 0) + { + static const char *const list_ALTERDOMAIN[] = + {"ADD", "DROP", "OWNER TO", "SET", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDOMAIN); + } + /* ALTER DOMAIN DROP */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "DOMAIN") == 0 && + pg_strcasecmp(prev_wd, "DROP") == 0) + { + static const char *const list_ALTERDOMAIN2[] = + {"CONSTRAINT", "DEFAULT", "NOT NULL", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDOMAIN2); + } + /* ALTER DOMAIN SET */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "DOMAIN") == 0 && + pg_strcasecmp(prev_wd, "SET") == 0) + { + static const char *const list_ALTERDOMAIN3[] = + {"DEFAULT", "NOT NULL", "SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERDOMAIN3); + } + /* ALTER SEQUENCE */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "SEQUENCE") == 0) + { + static const char *const list_ALTERSEQUENCE[] = + {"INCREMENT", "MINVALUE", "MAXVALUE", "RESTART", "NO", "CACHE", "CYCLE", + "SET SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERSEQUENCE); + } + /* ALTER SEQUENCE NO */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "SEQUENCE") == 0 && + pg_strcasecmp(prev_wd, "NO") == 0) + { + static const char *const list_ALTERSEQUENCE2[] = + {"MINVALUE", "MAXVALUE", "CYCLE", NULL}; + + COMPLETE_WITH_LIST(list_ALTERSEQUENCE2); + } + /* ALTER TRIGGER , add ON */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TRIGGER") == 0) + COMPLETE_WITH_CONST("ON"); + + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "TRIGGER") == 0) + { + completion_info_charp = prev2_wd; + COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_trigger); + } + + /* + * If we have ALTER TRIGGER ON, then add the correct tablename + */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "TRIGGER") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + + /* ALTER TRIGGER ON */ + else if (pg_strcasecmp(prev4_wd, "TRIGGER") == 0 && + pg_strcasecmp(prev2_wd, "ON") == 0) + COMPLETE_WITH_CONST("RENAME TO"); + + /* + * If we detect ALTER TABLE , suggest either ADD, DROP, ALTER, + * RENAME, CLUSTER ON or OWNER + */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TABLE") == 0) + { + static const char *const list_ALTER2[] = + {"ADD", "ALTER", "CLUSTER ON", "DROP", "RENAME", "OWNER TO", + "SET", NULL}; + + COMPLETE_WITH_LIST(list_ALTER2); + } + /* If we have TABLE ALTER|RENAME, provide list of columns */ + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + (pg_strcasecmp(prev_wd, "ALTER") == 0 || + pg_strcasecmp(prev_wd, "RENAME") == 0)) + COMPLETE_WITH_ATTR(prev2_wd); + + /* ALTER TABLE xxx RENAME yyy */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "RENAME") == 0 && + pg_strcasecmp(prev_wd, "TO") != 0) + COMPLETE_WITH_CONST("TO"); + + /* If we have TABLE DROP, provide COLUMN or CONSTRAINT */ + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev_wd, "DROP") == 0) + { + static const char *const list_TABLEDROP[] = + {"COLUMN", "CONSTRAINT", NULL}; + + COMPLETE_WITH_LIST(list_TABLEDROP); + } + /* If we have TABLE DROP COLUMN, provide list of columns */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "DROP") == 0 && + pg_strcasecmp(prev_wd, "COLUMN") == 0) + COMPLETE_WITH_ATTR(prev3_wd); + /* ALTER TABLE ALTER [COLUMN] */ + else if ((pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "COLUMN") == 0) || + (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "ALTER") == 0)) + { + /* DROP ... does not work well yet */ + static const char *const list_COLUMNALTER[] = + {"TYPE", "SET DEFAULT", "DROP DEFAULT", "SET NOT NULL", + "DROP NOT NULL", "SET STATISTICS", "SET STORAGE", NULL}; + + COMPLETE_WITH_LIST(list_COLUMNALTER); + } + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev_wd, "CLUSTER") == 0) + COMPLETE_WITH_CONST("ON"); + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + completion_info_charp = prev3_wd; + COMPLETE_WITH_QUERY(Query_for_index_of_table); + } + /* If we have TABLE SET, provide WITHOUT,TABLESPACE and SCHEMA */ + else if (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev_wd, "SET") == 0) + { + static const char *const list_TABLESET[] = + {"WITHOUT", "TABLESPACE", "SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_TABLESET); + } + /* If we have TABLE SET TABLESPACE provide a list of tablespaces */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "TABLESPACE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + /* If we have TABLE SET WITHOUT provide CLUSTER or OIDS */ + else if (pg_strcasecmp(prev4_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "WITHOUT") == 0) + { + static const char *const list_TABLESET2[] = + {"CLUSTER", "OIDS", NULL}; + + COMPLETE_WITH_LIST(list_TABLESET2); + } + /* we have ALTER TABLESPACE, so suggest RENAME TO, OWNER TO */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TABLESPACE") == 0) + { + static const char *const list_ALTERTSPC[] = + {"RENAME TO", "OWNER TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERTSPC); + } + /* complete ALTER TYPE with OWNER TO, SET SCHEMA */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "TYPE") == 0) + { + static const char *const list_ALTERTYPE[] = + {"OWNER TO", "SET SCHEMA", NULL}; + + COMPLETE_WITH_LIST(list_ALTERTYPE); + } + /* complete ALTER GROUP */ + else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 && + pg_strcasecmp(prev2_wd, "GROUP") == 0) + { + static const char *const list_ALTERGROUP[] = + {"ADD USER", "DROP USER", "RENAME TO", NULL}; + + COMPLETE_WITH_LIST(list_ALTERGROUP); + } + /* complete ALTER GROUP ADD|DROP with USER */ + else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 && + pg_strcasecmp(prev3_wd, "GROUP") == 0 && + (pg_strcasecmp(prev_wd, "ADD") == 0 || + pg_strcasecmp(prev_wd, "DROP") == 0)) + COMPLETE_WITH_CONST("USER"); + /* complete {ALTER} GROUP ADD|DROP USER with a user name */ + else if (pg_strcasecmp(prev4_wd, "GROUP") == 0 && + (pg_strcasecmp(prev2_wd, "ADD") == 0 || + pg_strcasecmp(prev2_wd, "DROP") == 0) && + pg_strcasecmp(prev_wd, "USER") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + +/* BEGIN, END, ABORT */ + else if (pg_strcasecmp(prev_wd, "BEGIN") == 0 || + pg_strcasecmp(prev_wd, "END") == 0 || + pg_strcasecmp(prev_wd, "ABORT") == 0) + { + static const char *const list_TRANS[] = + {"WORK", "TRANSACTION", NULL}; + + COMPLETE_WITH_LIST(list_TRANS); + } +/* COMMIT */ + else if (pg_strcasecmp(prev_wd, "COMMIT") == 0) + { + static const char *const list_COMMIT[] = + {"WORK", "TRANSACTION", "PREPARED", NULL}; + + COMPLETE_WITH_LIST(list_COMMIT); + } +/* RELEASE SAVEPOINT */ + else if (pg_strcasecmp(prev_wd, "RELEASE") == 0) + COMPLETE_WITH_CONST("SAVEPOINT"); +/* ROLLBACK*/ + else if (pg_strcasecmp(prev_wd, "ROLLBACK") == 0) + { + static const char *const list_TRANS[] = + {"WORK", "TRANSACTION", "TO SAVEPOINT", "PREPARED", NULL}; + + COMPLETE_WITH_LIST(list_TRANS); + } +/* CLUSTER */ + + /* + * If the previous word is CLUSTER and not without produce list of + * indexes. + */ + else if (pg_strcasecmp(prev_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev2_wd, "WITHOUT") != 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + /* If we have CLUSTER , then add "ON" */ + else if (pg_strcasecmp(prev2_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev_wd, "ON") != 0) + COMPLETE_WITH_CONST("ON"); + + /* + * If we have CLUSTER ON, then add the correct tablename as well. + */ + else if (pg_strcasecmp(prev3_wd, "CLUSTER") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + completion_info_charp = prev2_wd; + COMPLETE_WITH_QUERY(Query_for_table_owning_index); + } + +/* COMMENT */ + else if (pg_strcasecmp(prev_wd, "COMMENT") == 0) + COMPLETE_WITH_CONST("ON"); + else if (pg_strcasecmp(prev2_wd, "COMMENT") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + static const char *const list_COMMENT[] = + {"CAST", "CONVERSION", "DATABASE", "INDEX", "LANGUAGE", "RULE", "SCHEMA", + "SEQUENCE", "TABLE", "TYPE", "VIEW", "COLUMN", "AGGREGATE", "FUNCTION", + "OPERATOR", "TRIGGER", "CONSTRAINT", "DOMAIN", "LARGE OBJECT", NULL}; + + COMPLETE_WITH_LIST(list_COMMENT); + } + else if (pg_strcasecmp(prev4_wd, "COMMENT") == 0 && + pg_strcasecmp(prev3_wd, "ON") == 0) + COMPLETE_WITH_CONST("IS"); + +/* COPY */ + + /* + * If we have COPY [BINARY] (which you'd have to type yourself), offer + * list of tables (Also cover the analogous backslash command) + */ + else if (pg_strcasecmp(prev_wd, "COPY") == 0 || + pg_strcasecmp(prev_wd, "\\copy") == 0 || + (pg_strcasecmp(prev2_wd, "COPY") == 0 && + pg_strcasecmp(prev_wd, "BINARY") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* If we have COPY|BINARY , complete it with "TO" or "FROM" */ + else if (pg_strcasecmp(prev2_wd, "COPY") == 0 || + pg_strcasecmp(prev2_wd, "\\copy") == 0 || + pg_strcasecmp(prev2_wd, "BINARY") == 0) + { + static const char *const list_FROMTO[] = + {"FROM", "TO", NULL}; + + COMPLETE_WITH_LIST(list_FROMTO); + } + /* If we have COPY|BINARY FROM|TO, complete with filename */ + else if ((pg_strcasecmp(prev3_wd, "COPY") == 0 || + pg_strcasecmp(prev3_wd, "\\copy") == 0 || + pg_strcasecmp(prev3_wd, "BINARY") == 0) && + (pg_strcasecmp(prev_wd, "FROM") == 0 || + pg_strcasecmp(prev_wd, "TO") == 0)) + matches = complete_filename(); + + /* Handle COPY|BINARY FROM|TO filename */ + else if ((pg_strcasecmp(prev4_wd, "COPY") == 0 || + pg_strcasecmp(prev4_wd, "\\copy") == 0 || + pg_strcasecmp(prev4_wd, "BINARY") == 0) && + (pg_strcasecmp(prev2_wd, "FROM") == 0 || + pg_strcasecmp(prev2_wd, "TO") == 0)) + { + static const char *const list_COPY[] = + {"BINARY", "OIDS", "DELIMITER", "NULL", "CSV", NULL}; + + COMPLETE_WITH_LIST(list_COPY); + } + + /* Handle COPY|BINARY FROM|TO filename CSV */ + else if (pg_strcasecmp(prev_wd, "CSV") == 0 && + (pg_strcasecmp(prev3_wd, "FROM") == 0 || + pg_strcasecmp(prev3_wd, "TO") == 0)) + { + static const char *const list_CSV[] = + {"HEADER", "QUOTE", "ESCAPE", "FORCE QUOTE", NULL}; + + COMPLETE_WITH_LIST(list_CSV); + } + + /* CREATE DATABASE */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "DATABASE") == 0) + { + static const char *const list_DATABASE[] = + {"OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "CONNECTION LIMIT", + NULL}; + + COMPLETE_WITH_LIST(list_DATABASE); + } + + /* CREATE INDEX */ + /* First off we complete CREATE UNIQUE with "INDEX" */ + else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 && + pg_strcasecmp(prev_wd, "UNIQUE") == 0) + COMPLETE_WITH_CONST("INDEX"); + /* If we have CREATE|UNIQUE INDEX , then add "ON" */ + else if (pg_strcasecmp(prev2_wd, "INDEX") == 0 && + (pg_strcasecmp(prev3_wd, "CREATE") == 0 || + pg_strcasecmp(prev3_wd, "UNIQUE") == 0)) + COMPLETE_WITH_CONST("ON"); + /* Complete ... INDEX ON with a list of tables */ + else if (pg_strcasecmp(prev3_wd, "INDEX") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + + /* + * Complete INDEX ON with a list of table columns (which + * should really be in parens) + */ + else if (pg_strcasecmp(prev4_wd, "INDEX") == 0 && + pg_strcasecmp(prev2_wd, "ON") == 0) + { + if (find_open_parenthesis(end)) + COMPLETE_WITH_ATTR(prev_wd); + else + COMPLETE_WITH_CONST("("); + } + else if (pg_strcasecmp(prev5_wd, "INDEX") == 0 && + pg_strcasecmp(prev3_wd, "ON") == 0 && + pg_strcasecmp(prev_wd, "(") == 0) + COMPLETE_WITH_ATTR(prev2_wd); + /* same if you put in USING */ + else if (pg_strcasecmp(prev4_wd, "ON") == 0 && + pg_strcasecmp(prev2_wd, "USING") == 0) + COMPLETE_WITH_ATTR(prev3_wd); + /* Complete USING with an index method */ + else if (pg_strcasecmp(prev_wd, "USING") == 0) + { + static const char *const index_mth[] = + {"BTREE", "HASH", "GIST", NULL}; + + COMPLETE_WITH_LIST(index_mth); + } + +/* CREATE RULE */ + /* Complete "CREATE RULE " with "AS" */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "RULE") == 0) + COMPLETE_WITH_CONST("AS"); + /* Complete "CREATE RULE AS with "ON" */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + pg_strcasecmp(prev3_wd, "RULE") == 0 && + pg_strcasecmp(prev_wd, "AS") == 0) + COMPLETE_WITH_CONST("ON"); + /* Complete "RULE * AS ON" with SELECT|UPDATE|DELETE|INSERT */ + else if (pg_strcasecmp(prev4_wd, "RULE") == 0 && + pg_strcasecmp(prev2_wd, "AS") == 0 && + pg_strcasecmp(prev_wd, "ON") == 0) + { + static const char *const rule_events[] = + {"SELECT", "UPDATE", "INSERT", "DELETE", NULL}; + + COMPLETE_WITH_LIST(rule_events); + } + /* Complete "AS ON " with a "TO" */ + else if (pg_strcasecmp(prev3_wd, "AS") == 0 && + pg_strcasecmp(prev2_wd, "ON") == 0 && + (toupper((unsigned char) prev_wd[4]) == 'T' || + toupper((unsigned char) prev_wd[5]) == 'T')) + COMPLETE_WITH_CONST("TO"); + /* Complete "AS ON TO" with a table name */ + else if (pg_strcasecmp(prev4_wd, "AS") == 0 && + pg_strcasecmp(prev3_wd, "ON") == 0 && + pg_strcasecmp(prev_wd, "TO") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* CREATE TABLE */ + /* Complete CREATE TEMP with "TABLE" */ + else if (pg_strcasecmp(prev2_wd, "CREATE") == 0 && + pg_strcasecmp(prev_wd, "TEMP") == 0) + COMPLETE_WITH_CONST("TABLE"); + +/* CREATE TABLESPACE */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "TABLESPACE") == 0) + { + static const char *const list_CREATETABLESPACE[] = + {"OWNER", "LOCATION", NULL}; + + COMPLETE_WITH_LIST(list_CREATETABLESPACE); + } + /* Complete CREATE TABLESPACE name OWNER name with "LOCATION" */ + else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 && + pg_strcasecmp(prev4_wd, "TABLESPACE") == 0 && + pg_strcasecmp(prev2_wd, "OWNER") == 0) + { + COMPLETE_WITH_CONST("LOCATION"); + } + +/* CREATE TRIGGER */ + /* complete CREATE TRIGGER with BEFORE,AFTER */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "TRIGGER") == 0) + { + static const char *const list_CREATETRIGGER[] = + {"BEFORE", "AFTER", NULL}; + + COMPLETE_WITH_LIST(list_CREATETRIGGER); + } + /* complete CREATE TRIGGER BEFORE,AFTER sth with OR,ON */ + else if (pg_strcasecmp(prev5_wd, "CREATE") == 0 && + pg_strcasecmp(prev4_wd, "TRIGGER") == 0 && + (pg_strcasecmp(prev2_wd, "BEFORE") == 0 || + pg_strcasecmp(prev2_wd, "AFTER") == 0)) + { + static const char *const list_CREATETRIGGER2[] = + {"ON", "OR", NULL}; + + COMPLETE_WITH_LIST(list_CREATETRIGGER2); + } + +/* CREATE ROLE,USER,GROUP */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + (pg_strcasecmp(prev2_wd, "ROLE") == 0 || + pg_strcasecmp(prev2_wd, "GROUP") == 0 || pg_strcasecmp(prev2_wd, "USER") == 0)) + { + static const char *const list_CREATEROLE[] = + {"ADMIN", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE", "CREATEUSER", + "ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOINHERIT", "NOLOGIN", "NOCREATEDB", + "NOCREATEROLE", "NOCREATEUSER", "NOSUPERUSER", "ROLE", "SUPERUSER", "SYSID", + "UNENCRYPTED", NULL}; + + COMPLETE_WITH_LIST(list_CREATEROLE); + } + + /* + * complete CREATE ROLE,USER,GROUP ENCRYPTED,UNENCRYPTED with + * PASSWORD + */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || + pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + (pg_strcasecmp(prev_wd, "ENCRYPTED") == 0 || pg_strcasecmp(prev_wd, "UNENCRYPTED") == 0)) + { + COMPLETE_WITH_CONST("PASSWORD"); + } + /* complete CREATE ROLE,USER,GROUP IN with ROLE,GROUP */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + (pg_strcasecmp(prev3_wd, "ROLE") == 0 || + pg_strcasecmp(prev3_wd, "GROUP") == 0 || pg_strcasecmp(prev3_wd, "USER") == 0) && + pg_strcasecmp(prev_wd, "IN") == 0) + { + static const char *const list_CREATEROLE3[] = + {"GROUP", "ROLE", NULL}; + + COMPLETE_WITH_LIST(list_CREATEROLE3); + } + +/* CREATE VIEW */ + /* Complete CREATE VIEW with AS */ + else if (pg_strcasecmp(prev3_wd, "CREATE") == 0 && + pg_strcasecmp(prev2_wd, "VIEW") == 0) + COMPLETE_WITH_CONST("AS"); + /* Complete "CREATE VIEW AS with "SELECT" */ + else if (pg_strcasecmp(prev4_wd, "CREATE") == 0 && + pg_strcasecmp(prev3_wd, "VIEW") == 0 && + pg_strcasecmp(prev_wd, "AS") == 0) + COMPLETE_WITH_CONST("SELECT"); + +/* DECLARE */ + else if (pg_strcasecmp(prev2_wd, "DECLARE") == 0) + { + static const char *const list_DECLARE[] = + {"BINARY", "INSENSITIVE", "SCROLL", "NO SCROLL", "CURSOR", NULL}; + + COMPLETE_WITH_LIST(list_DECLARE); + } + + else if (pg_strcasecmp(prev_wd, "CURSOR") == 0) + { + static const char *const list_DECLARECURSOR[] = + {"WITH HOLD", "WITHOUT HOLD", "FOR", NULL}; + + COMPLETE_WITH_LIST(list_DECLARECURSOR); + } + + +/* DELETE */ + + /* + * Complete DELETE with FROM (only if the word before that is not "ON" + * (cf. rules) or "BEFORE" or "AFTER" (cf. triggers) or GRANT) + */ + else if (pg_strcasecmp(prev_wd, "DELETE") == 0 && + !(pg_strcasecmp(prev2_wd, "ON") == 0 || + pg_strcasecmp(prev2_wd, "GRANT") == 0 || + pg_strcasecmp(prev2_wd, "BEFORE") == 0 || + pg_strcasecmp(prev2_wd, "AFTER") == 0)) + COMPLETE_WITH_CONST("FROM"); + /* Complete DELETE FROM with a list of tables */ + else if (pg_strcasecmp(prev2_wd, "DELETE") == 0 && + pg_strcasecmp(prev_wd, "FROM") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* Complete DELETE FROM
*/ + else if (pg_strcasecmp(prev3_wd, "DELETE") == 0 && + pg_strcasecmp(prev2_wd, "FROM") == 0) + { + static const char *const list_DELETE[] = + {"USING", "WHERE", "SET", NULL}; + + COMPLETE_WITH_LIST(list_DELETE); + } + /* XXX: implement tab completion for DELETE ... USING */ + +/* DROP (when not the previous word) */ + /* DROP AGGREGATE */ + else if (pg_strcasecmp(prev3_wd, "DROP") == 0 && + pg_strcasecmp(prev2_wd, "AGGREGATE") == 0) + COMPLETE_WITH_CONST("("); + + /* DROP object with CASCADE / RESTRICT */ + else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 && + (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 || + pg_strcasecmp(prev2_wd, "DOMAIN") == 0 || + pg_strcasecmp(prev2_wd, "FUNCTION") == 0 || + pg_strcasecmp(prev2_wd, "INDEX") == 0 || + pg_strcasecmp(prev2_wd, "LANGUAGE") == 0 || + pg_strcasecmp(prev2_wd, "SCHEMA") == 0 || + pg_strcasecmp(prev2_wd, "SEQUENCE") == 0 || + pg_strcasecmp(prev2_wd, "TABLE") == 0 || + pg_strcasecmp(prev2_wd, "TYPE") == 0 || + pg_strcasecmp(prev2_wd, "VIEW") == 0)) || + (pg_strcasecmp(prev4_wd, "DROP") == 0 && + pg_strcasecmp(prev3_wd, "AGGREGATE") == 0 && + prev_wd[strlen(prev_wd) - 1] == ')')) + { + + if ((pg_strcasecmp(prev3_wd, "DROP") == 0) && (pg_strcasecmp(prev2_wd, "FUNCTION") == 0)) + { + if (find_open_parenthesis(end)) + { + static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'"; + char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev_wd)); + sprintf(tmp_buf, func_args_query, prev_wd); + COMPLETE_WITH_QUERY(tmp_buf); + free(tmp_buf); + } + else + { + COMPLETE_WITH_CONST("("); + } + } + else + { + static const char *const list_DROPCR[] = + {"CASCADE", "RESTRICT", NULL}; + + COMPLETE_WITH_LIST(list_DROPCR); + } + } + else if (pg_strcasecmp(prev4_wd, "DROP") == 0 && + pg_strcasecmp(prev3_wd, "FUNCTION") == 0 && + pg_strcasecmp(prev_wd, "(") == 0 ) + { + static const char func_args_query[] = "select pg_catalog.oidvectortypes(proargtypes)||')' from pg_proc where proname='%s'"; + char *tmp_buf = malloc(strlen(func_args_query) + strlen(prev2_wd)); + sprintf(tmp_buf, func_args_query, prev2_wd); + COMPLETE_WITH_QUERY(tmp_buf); + free(tmp_buf); + } + + + +/* EXPLAIN */ + + /* + * Complete EXPLAIN [ANALYZE] [VERBOSE] with list of EXPLAIN-able commands + */ + else if (pg_strcasecmp(prev_wd, "EXPLAIN") == 0) + { + static const char *const list_EXPLAIN[] = + {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", "ANALYZE", "VERBOSE", NULL}; + + COMPLETE_WITH_LIST(list_EXPLAIN); + } + else if (pg_strcasecmp(prev2_wd, "EXPLAIN") == 0 && + pg_strcasecmp(prev_wd, "ANALYZE") == 0) + { + static const char *const list_EXPLAIN[] = + {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", "VERBOSE", NULL}; + + COMPLETE_WITH_LIST(list_EXPLAIN); + } + else if (pg_strcasecmp(prev_wd, "VERBOSE") == 0 && + pg_strcasecmp(prev3_wd, "VACUUM") != 0 && + pg_strcasecmp(prev4_wd, "VACUUM") != 0 && + (pg_strcasecmp(prev2_wd, "ANALYZE") == 0 || + pg_strcasecmp(prev2_wd, "EXPLAIN") == 0)) + { + static const char *const list_EXPLAIN[] = + {"SELECT", "INSERT", "DELETE", "UPDATE", "DECLARE", NULL}; + + COMPLETE_WITH_LIST(list_EXPLAIN); + } + +/* FETCH && MOVE */ + /* Complete FETCH with one of FORWARD, BACKWARD, RELATIVE */ + else if (pg_strcasecmp(prev_wd, "FETCH") == 0 || + pg_strcasecmp(prev_wd, "MOVE") == 0) + { + static const char *const list_FETCH1[] = + {"ABSOLUTE", "BACKWARD", "FORWARD", "RELATIVE", NULL}; + + COMPLETE_WITH_LIST(list_FETCH1); + } + /* Complete FETCH with one of ALL, NEXT, PRIOR */ + else if (pg_strcasecmp(prev2_wd, "FETCH") == 0 || + pg_strcasecmp(prev2_wd, "MOVE") == 0) + { + static const char *const list_FETCH2[] = + {"ALL", "NEXT", "PRIOR", NULL}; + + COMPLETE_WITH_LIST(list_FETCH2); + } + + /* + * Complete FETCH with "FROM" or "IN". These are equivalent, + * but we may as well tab-complete both: perhaps some users prefer one + * variant or the other. + */ + else if (pg_strcasecmp(prev3_wd, "FETCH") == 0 || + pg_strcasecmp(prev3_wd, "MOVE") == 0) + { + static const char *const list_FROMIN[] = + {"FROM", "IN", NULL}; + + COMPLETE_WITH_LIST(list_FROMIN); + } + +/* GRANT && REVOKE*/ + /* Complete GRANT/REVOKE with a list of privileges */ + else if (pg_strcasecmp(prev_wd, "GRANT") == 0 || + pg_strcasecmp(prev_wd, "REVOKE") == 0) + { + static const char *const list_privileg[] = + {"SELECT", "INSERT", "UPDATE", "DELETE", "RULE", "REFERENCES", + "TRIGGER", "CREATE", "TEMPORARY", "EXECUTE", "USAGE", "ALL", NULL}; + + COMPLETE_WITH_LIST(list_privileg); + } + /* Complete GRANT/REVOKE with "ON" */ + else if (pg_strcasecmp(prev2_wd, "GRANT") == 0 || + pg_strcasecmp(prev2_wd, "REVOKE") == 0) + COMPLETE_WITH_CONST("ON"); + + /* + * Complete GRANT/REVOKE ON with a list of tables, views, sequences, + * and indexes + * + * keywords DATABASE, FUNCTION, LANGUAGE, SCHEMA added to query result via + * UNION; seems to work intuitively + * + * Note: GRANT/REVOKE can get quite complex; tab-completion as implemented + * here will only work if the privilege list contains exactly one + * privilege + */ + else if ((pg_strcasecmp(prev3_wd, "GRANT") == 0 || + pg_strcasecmp(prev3_wd, "REVOKE") == 0) && + pg_strcasecmp(prev_wd, "ON") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, + " UNION SELECT 'DATABASE'" + " UNION SELECT 'FUNCTION'" + " UNION SELECT 'LANGUAGE'" + " UNION SELECT 'SCHEMA'" + " UNION SELECT 'TABLESPACE'"); + + /* Complete "GRANT/REVOKE * ON * " with "TO" */ + else if ((pg_strcasecmp(prev4_wd, "GRANT") == 0 || + pg_strcasecmp(prev4_wd, "REVOKE") == 0) && + pg_strcasecmp(prev2_wd, "ON") == 0) + { + if (pg_strcasecmp(prev_wd, "DATABASE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + else if (pg_strcasecmp(prev_wd, "FUNCTION") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (pg_strcasecmp(prev_wd, "LANGUAGE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_languages); + else if (pg_strcasecmp(prev_wd, "SCHEMA") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (pg_strcasecmp(prev_wd, "TABLESPACE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (pg_strcasecmp(prev4_wd, "GRANT") == 0) + COMPLETE_WITH_CONST("TO"); + else + COMPLETE_WITH_CONST("FROM"); + } + + /* Complete "GRANT/REVOKE * ON * TO/FROM" with username, GROUP, or PUBLIC */ + else if (pg_strcasecmp(prev3_wd, "ON") == 0 && + ((pg_strcasecmp(prev5_wd, "GRANT") == 0 && + pg_strcasecmp(prev_wd, "TO") == 0) || + (pg_strcasecmp(prev5_wd, "REVOKE") == 0 && + pg_strcasecmp(prev_wd, "FROM") == 0))) + COMPLETE_WITH_QUERY(Query_for_list_of_grant_roles); + +/* GROUP BY */ + else if (pg_strcasecmp(prev3_wd, "FROM") == 0 && + pg_strcasecmp(prev_wd, "GROUP") == 0) + COMPLETE_WITH_CONST("BY"); + +/* INSERT */ + /* Complete INSERT with "INTO" */ + else if (pg_strcasecmp(prev_wd, "INSERT") == 0) + COMPLETE_WITH_CONST("INTO"); + /* Complete INSERT INTO with table names */ + else if (pg_strcasecmp(prev2_wd, "INSERT") == 0 && + pg_strcasecmp(prev_wd, "INTO") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* Complete "INSERT INTO
(" with attribute names */ + else if (rl_line_buffer[start - 1] == '(' && + pg_strcasecmp(prev3_wd, "INSERT") == 0 && + pg_strcasecmp(prev2_wd, "INTO") == 0) + COMPLETE_WITH_ATTR(prev_wd); + + /* + * Complete INSERT INTO
with "VALUES" or "SELECT" or "DEFAULT + * VALUES" + */ + else if (pg_strcasecmp(prev3_wd, "INSERT") == 0 && + pg_strcasecmp(prev2_wd, "INTO") == 0) + { + static const char *const list_INSERT[] = + {"DEFAULT VALUES", "SELECT", "VALUES", NULL}; + + COMPLETE_WITH_LIST(list_INSERT); + } + /* Complete INSERT INTO
(attribs) with "VALUES" or "SELECT" */ + else if (pg_strcasecmp(prev4_wd, "INSERT") == 0 && + pg_strcasecmp(prev3_wd, "INTO") == 0 && + prev_wd[strlen(prev_wd) - 1] == ')') + { + static const char *const list_INSERT[] = + {"SELECT", "VALUES", NULL}; + + COMPLETE_WITH_LIST(list_INSERT); + } + + /* Insert an open parenthesis after "VALUES" */ + else if (pg_strcasecmp(prev_wd, "VALUES") == 0 && + pg_strcasecmp(prev2_wd, "DEFAULT") != 0) + COMPLETE_WITH_CONST("("); + +/* LOCK */ + /* Complete LOCK [TABLE] with a list of tables */ + else if (pg_strcasecmp(prev_wd, "LOCK") == 0 || + (pg_strcasecmp(prev_wd, "TABLE") == 0 && + pg_strcasecmp(prev2_wd, "LOCK") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + + /* For the following, handle the case of a single table only for now */ + + /* Complete LOCK [TABLE]
with "IN" */ + else if ((pg_strcasecmp(prev2_wd, "LOCK") == 0 && + pg_strcasecmp(prev_wd, "TABLE")) || + (pg_strcasecmp(prev2_wd, "TABLE") == 0 && + pg_strcasecmp(prev3_wd, "LOCK") == 0)) + COMPLETE_WITH_CONST("IN"); + + /* Complete LOCK [TABLE]
IN with a lock mode */ + else if (pg_strcasecmp(prev_wd, "IN") == 0 && + (pg_strcasecmp(prev3_wd, "LOCK") == 0 || + (pg_strcasecmp(prev3_wd, "TABLE") == 0 && + pg_strcasecmp(prev4_wd, "LOCK") == 0))) + { + static const char *const lock_modes[] = + {"ACCESS SHARE MODE", + "ROW SHARE MODE", "ROW EXCLUSIVE MODE", + "SHARE UPDATE EXCLUSIVE MODE", "SHARE MODE", + "SHARE ROW EXCLUSIVE MODE", + "EXCLUSIVE MODE", "ACCESS EXCLUSIVE MODE", NULL}; + + COMPLETE_WITH_LIST(lock_modes); + } + +/* NOTIFY */ + else if (pg_strcasecmp(prev_wd, "NOTIFY") == 0) + COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s'"); + +/* OWNER TO - complete with available roles*/ + else if (pg_strcasecmp(prev2_wd, "OWNER") == 0 && + pg_strcasecmp(prev_wd, "TO") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + +/* ORDER BY */ + else if (pg_strcasecmp(prev3_wd, "FROM") == 0 && + pg_strcasecmp(prev_wd, "ORDER") == 0) + COMPLETE_WITH_CONST("BY"); + else if (pg_strcasecmp(prev4_wd, "FROM") == 0 && + pg_strcasecmp(prev2_wd, "ORDER") == 0 && + pg_strcasecmp(prev_wd, "BY") == 0) + COMPLETE_WITH_ATTR(prev3_wd); + +/* PREPARE xx AS */ + else if (pg_strcasecmp(prev_wd, "AS") == 0 && + pg_strcasecmp(prev3_wd, "PREPARE") == 0) + { + static const char *const list_PREPARE[] = + {"SELECT", "UPDATE", "INSERT", "DELETE", NULL}; + + COMPLETE_WITH_LIST(list_PREPARE); + } + + +/* REINDEX */ + else if (pg_strcasecmp(prev_wd, "REINDEX") == 0) + { + static const char *const list_REINDEX[] = + {"TABLE", "INDEX", "SYSTEM", "DATABASE", NULL}; + + COMPLETE_WITH_LIST(list_REINDEX); + } + else if (pg_strcasecmp(prev2_wd, "REINDEX") == 0) + { + if (pg_strcasecmp(prev_wd, "TABLE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + else if (pg_strcasecmp(prev_wd, "INDEX") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (pg_strcasecmp(prev_wd, "SYSTEM") == 0 || + pg_strcasecmp(prev_wd, "DATABASE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + } + +/* SELECT */ + /* naah . . . */ + +/* SET, RESET, SHOW */ + /* Complete with a variable name */ + else if ((pg_strcasecmp(prev_wd, "SET") == 0 && + pg_strcasecmp(prev3_wd, "UPDATE") != 0) || + pg_strcasecmp(prev_wd, "RESET") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_set_vars); + else if (pg_strcasecmp(prev_wd, "SHOW") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_show_vars); + /* Complete "SET TRANSACTION" */ + else if ((pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "TRANSACTION") == 0) + || (pg_strcasecmp(prev2_wd, "START") == 0 + && pg_strcasecmp(prev_wd, "TRANSACTION") == 0) + || (pg_strcasecmp(prev2_wd, "BEGIN") == 0 + && pg_strcasecmp(prev_wd, "WORK") == 0) + || (pg_strcasecmp(prev2_wd, "BEGIN") == 0 + && pg_strcasecmp(prev_wd, "TRANSACTION") == 0) + || (pg_strcasecmp(prev4_wd, "SESSION") == 0 + && pg_strcasecmp(prev3_wd, "CHARACTERISTICS") == 0 + && pg_strcasecmp(prev2_wd, "AS") == 0 + && pg_strcasecmp(prev_wd, "TRANSACTION") == 0)) + { + static const char *const my_list[] = + {"ISOLATION LEVEL", "READ", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if ((pg_strcasecmp(prev3_wd, "SET") == 0 + || pg_strcasecmp(prev3_wd, "BEGIN") == 0 + || pg_strcasecmp(prev3_wd, "START") == 0 + || (pg_strcasecmp(prev4_wd, "CHARACTERISTICS") == 0 + && pg_strcasecmp(prev3_wd, "AS") == 0)) + && (pg_strcasecmp(prev2_wd, "TRANSACTION") == 0 + || pg_strcasecmp(prev2_wd, "WORK") == 0) + && pg_strcasecmp(prev_wd, "ISOLATION") == 0) + COMPLETE_WITH_CONST("LEVEL"); + else if ((pg_strcasecmp(prev4_wd, "SET") == 0 + || pg_strcasecmp(prev4_wd, "BEGIN") == 0 + || pg_strcasecmp(prev4_wd, "START") == 0 + || pg_strcasecmp(prev4_wd, "AS") == 0) + && (pg_strcasecmp(prev3_wd, "TRANSACTION") == 0 + || pg_strcasecmp(prev3_wd, "WORK") == 0) + && pg_strcasecmp(prev2_wd, "ISOLATION") == 0 + && pg_strcasecmp(prev_wd, "LEVEL") == 0) + { + static const char *const my_list[] = + {"READ", "REPEATABLE", "SERIALIZABLE", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if ((pg_strcasecmp(prev4_wd, "TRANSACTION") == 0 || + pg_strcasecmp(prev4_wd, "WORK") == 0) && + pg_strcasecmp(prev3_wd, "ISOLATION") == 0 && + pg_strcasecmp(prev2_wd, "LEVEL") == 0 && + pg_strcasecmp(prev_wd, "READ") == 0) + { + static const char *const my_list[] = + {"UNCOMMITTED", "COMMITTED", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if ((pg_strcasecmp(prev4_wd, "TRANSACTION") == 0 || + pg_strcasecmp(prev4_wd, "WORK") == 0) && + pg_strcasecmp(prev3_wd, "ISOLATION") == 0 && + pg_strcasecmp(prev2_wd, "LEVEL") == 0 && + pg_strcasecmp(prev_wd, "REPEATABLE") == 0) + COMPLETE_WITH_CONST("READ"); + else if ((pg_strcasecmp(prev3_wd, "SET") == 0 || + pg_strcasecmp(prev3_wd, "BEGIN") == 0 || + pg_strcasecmp(prev3_wd, "START") == 0 || + pg_strcasecmp(prev3_wd, "AS") == 0) && + (pg_strcasecmp(prev2_wd, "TRANSACTION") == 0 || + pg_strcasecmp(prev2_wd, "WORK") == 0) && + pg_strcasecmp(prev_wd, "READ") == 0) + { + static const char *const my_list[] = + {"ONLY", "WRITE", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + /* Complete SET CONSTRAINTS with DEFERRED|IMMEDIATE */ + else if (pg_strcasecmp(prev3_wd, "SET") == 0 && + pg_strcasecmp(prev2_wd, "CONSTRAINTS") == 0) + { + static const char *const constraint_list[] = + {"DEFERRED", "IMMEDIATE", NULL}; + + COMPLETE_WITH_LIST(constraint_list); + } + /* Complete SET ROLE */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "ROLE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + /* Complete SET SESSION with AUTHORIZATION or CHARACTERISTICS... */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev_wd, "SESSION") == 0) + { + static const char *const my_list[] = + {"AUTHORIZATION", "CHARACTERISTICS AS TRANSACTION", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + /* Complete SET SESSION AUTHORIZATION with username */ + else if (pg_strcasecmp(prev3_wd, "SET") == 0 + && pg_strcasecmp(prev2_wd, "SESSION") == 0 + && pg_strcasecmp(prev_wd, "AUTHORIZATION") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + /* Complete RESET SESSION with AUTHORIZATION */ + else if (pg_strcasecmp(prev2_wd, "RESET") == 0 && + pg_strcasecmp(prev_wd, "SESSION") == 0) + COMPLETE_WITH_CONST("AUTHORIZATION"); + /* Complete SET with "TO" */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev4_wd, "UPDATE") != 0 && + pg_strcasecmp(prev_wd, "TABLESPACE") != 0 && + pg_strcasecmp(prev4_wd, "DOMAIN") != 0) + COMPLETE_WITH_CONST("TO"); + /* Suggest possible variable values */ + else if (pg_strcasecmp(prev3_wd, "SET") == 0 && + (pg_strcasecmp(prev_wd, "TO") == 0 || strcmp(prev_wd, "=") == 0)) + { + if (pg_strcasecmp(prev2_wd, "DateStyle") == 0) + { + static const char *const my_list[] = + {"ISO", "SQL", "Postgres", "German", + "YMD", "DMY", "MDY", + "US", "European", "NonEuropean", + "DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (pg_strcasecmp(prev2_wd, "GEQO") == 0) + { + static const char *const my_list[] = + {"ON", "OFF", "DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else + { + static const char *const my_list[] = + {"DEFAULT", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + } + +/* START TRANSACTION */ + else if (pg_strcasecmp(prev_wd, "START") == 0) + COMPLETE_WITH_CONST("TRANSACTION"); + +/* TRUNCATE */ + else if (pg_strcasecmp(prev_wd, "TRUNCATE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* UNLISTEN */ + else if (pg_strcasecmp(prev_wd, "UNLISTEN") == 0) + COMPLETE_WITH_QUERY("SELECT pg_catalog.quote_ident(relname) FROM pg_catalog.pg_listener WHERE substring(pg_catalog.quote_ident(relname),1,%d)='%s' UNION SELECT '*'"); + +/* UPDATE */ + /* If prev. word is UPDATE suggest a list of tables */ + else if (pg_strcasecmp(prev_wd, "UPDATE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + /* Complete UPDATE
with "SET" */ + else if (pg_strcasecmp(prev2_wd, "UPDATE") == 0) + COMPLETE_WITH_CONST("SET"); + + /* + * If the previous word is SET (and it wasn't caught above as the _first_ + * word) the word before it was (hopefully) a table name and we'll now + * make a list of attributes. + */ + else if (pg_strcasecmp(prev_wd, "SET") == 0) + COMPLETE_WITH_ATTR(prev2_wd); + +/* UPDATE xx SET yy = */ + else if (pg_strcasecmp(prev2_wd, "SET") == 0 && + pg_strcasecmp(prev4_wd, "UPDATE") == 0) + COMPLETE_WITH_CONST("="); + +/* + * VACUUM [ FULL | FREEZE ] [ VERBOSE ] [ table ] + * VACUUM [ FULL | FREEZE ] [ VERBOSE ] ANALYZE [ table [ (column [, ...] ) ] ] + */ + else if (pg_strcasecmp(prev_wd, "VACUUM") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'FULL'" + " UNION SELECT 'FREEZE'" + " UNION SELECT 'ANALYZE'" + " UNION SELECT 'VERBOSE'"); + else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 && + (pg_strcasecmp(prev_wd, "FULL") == 0 || + pg_strcasecmp(prev_wd, "FREEZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'ANALYZE'" + " UNION SELECT 'VERBOSE'"); + else if (pg_strcasecmp(prev3_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "ANALYZE") == 0 && + (pg_strcasecmp(prev2_wd, "FULL") == 0 || + pg_strcasecmp(prev2_wd, "FREEZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'VERBOSE'"); + else if (pg_strcasecmp(prev3_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "VERBOSE") == 0 && + (pg_strcasecmp(prev2_wd, "FULL") == 0 || + pg_strcasecmp(prev2_wd, "FREEZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'ANALYZE'"); + else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "VERBOSE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'ANALYZE'"); + else if (pg_strcasecmp(prev2_wd, "VACUUM") == 0 && + pg_strcasecmp(prev_wd, "ANALYZE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, + " UNION SELECT 'VERBOSE'"); + else if ((pg_strcasecmp(prev_wd, "ANALYZE") == 0 && + pg_strcasecmp(prev2_wd, "VERBOSE") == 0) || + (pg_strcasecmp(prev_wd, "VERBOSE") == 0 && + pg_strcasecmp(prev2_wd, "ANALYZE") == 0)) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* ANALYZE */ + /* If the previous word is ANALYZE, produce list of tables */ + else if (pg_strcasecmp(prev_wd, "ANALYZE") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + +/* WHERE */ + /* Simple case of the word before the where being the table name */ + else if (pg_strcasecmp(prev_wd, "WHERE") == 0) + COMPLETE_WITH_ATTR(prev2_wd); + +/* ... FROM ... */ +/* TODO: also include SRF ? */ + else if (pg_strcasecmp(prev_wd, "FROM") == 0 && + pg_strcasecmp(prev3_wd, "COPY") != 0 && + pg_strcasecmp(prev3_wd, "\\copy") != 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL); + + +/* Backslash commands */ +/* TODO: \dc \dd \dl */ + else if (strcmp(prev_wd, "\\connect") == 0 || strcmp(prev_wd, "\\c") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); + else if (strcmp(prev_wd, "\\d") == 0 || strcmp(prev_wd, "\\d+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tisv, NULL); + else if (strcmp(prev_wd, "\\da") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_aggregates, NULL); + else if (strcmp(prev_wd, "\\db") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces); + else if (strcmp(prev_wd, "\\dD") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_domains, NULL); + else if (strcmp(prev_wd, "\\df") == 0 || strcmp(prev_wd, "\\df+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL); + else if (strcmp(prev_wd, "\\di") == 0 || strcmp(prev_wd, "\\di+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (strcmp(prev_wd, "\\dn") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_schemas); + else if (strcmp(prev_wd, "\\dp") == 0 || strcmp(prev_wd, "\\z") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv, NULL); + else if (strcmp(prev_wd, "\\ds") == 0 || strcmp(prev_wd, "\\ds+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_sequences, NULL); + else if (strcmp(prev_wd, "\\dS") == 0 || strcmp(prev_wd, "\\dS+") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_system_relations); + else if (strcmp(prev_wd, "\\dt") == 0 || strcmp(prev_wd, "\\dt+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); + else if (strcmp(prev_wd, "\\dT") == 0 || strcmp(prev_wd, "\\dT+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_datatypes, NULL); + else if (strcmp(prev_wd, "\\du") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + else if (strcmp(prev_wd, "\\dv") == 0 || strcmp(prev_wd, "\\dv+") == 0) + COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL); + else if (strcmp(prev_wd, "\\encoding") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_encodings); + else if (strcmp(prev_wd, "\\h") == 0 || strcmp(prev_wd, "\\help") == 0) + COMPLETE_WITH_LIST(sql_commands); + else if (strcmp(prev_wd, "\\password") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_roles); + else if (strcmp(prev_wd, "\\pset") == 0) + { + static const char *const my_list[] = + {"format", "border", "expanded", + "null", "fieldsep", "tuples_only", "title", "tableattr", "pager", + "recordsep", NULL}; + + COMPLETE_WITH_LIST(my_list); + } + else if (strcmp(prev_wd, "\\cd") == 0 || + strcmp(prev_wd, "\\e") == 0 || strcmp(prev_wd, "\\edit") == 0 || + strcmp(prev_wd, "\\g") == 0 || + strcmp(prev_wd, "\\i") == 0 || strcmp(prev_wd, "\\include") == 0 || + strcmp(prev_wd, "\\o") == 0 || strcmp(prev_wd, "\\out") == 0 || + strcmp(prev_wd, "\\s") == 0 || + strcmp(prev_wd, "\\w") == 0 || strcmp(prev_wd, "\\write") == 0 + ) + matches = complete_filename(); + + + /* + * Finally, we look through the list of "things", such as TABLE, INDEX and + * check if that was the previous word. If so, execute the query to get a + * list of them. + */ + else + { + int i; + + for (i = 0; words_after_create[i].name; i++) + { + if (pg_strcasecmp(prev_wd, words_after_create[i].name) == 0) + { + if (words_after_create[i].query) + COMPLETE_WITH_QUERY(words_after_create[i].query); + else if (words_after_create[i].squery) + COMPLETE_WITH_SCHEMA_QUERY(*words_after_create[i].squery, + NULL); + break; + } + } + } + + /* + * If we still don't have anything to match we have to fabricate some sort + * of default list. If we were to just return NULL, readline automatically + * attempts filename completion, and that's usually no good. + */ + if (matches == NULL) + { + COMPLETE_WITH_CONST(""); +#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER + rl_completion_append_character = '\0'; +#endif + } + + /* free storage */ + free(prev_wd); + free(prev2_wd); + free(prev3_wd); + free(prev4_wd); + free(prev5_wd); + + /* Return our Grand List O' Matches */ + return matches; +} + + + + + diff --git a/utils/tabcomplete.c b/utils/tabcomplete.c new file mode 100644 index 0000000..f8cba05 --- /dev/null +++ b/utils/tabcomplete.c @@ -0,0 +1,415 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - Tab completion +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// tab-complete.cpp - Functions interfacing with tab-complete from psql +// +////////////////////////////////////////////////////////////////////////// + +/* + * BUG: Must compile as C and not C++, because of + * http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B315481 + * Adds a bit of C<->C++ cruft... + */ + +#define _CRT_NONSTDC_NO_DEPRECATE +#include +#include +#include +#include +#include + +/* + * Callbacks to the C++ world + */ +char *pg_query_to_single_ordered_string(char *query, void *dbptr); + + +/* + * Global vars for readline emulation + */ +static char *rl_line_buffer; + +/* + * Macros to ease typing present in psql, rewritten for our API + */ +#define COMPLETE_WITH_QUERY(query) \ + do { matches = complete_from_query(text,query,NULL,dbptr); } while (0) +#define COMPLETE_WITH_SCHEMA_QUERY(query, addon) \ + do { matches = complete_from_schema_query(text,&query, addon, dbptr); } while (0) +#define COMPLETE_WITH_LIST(list) \ + do { matches = complete_from_list(text,list); } while (0) +#define COMPLETE_WITH_CONST(str) \ + do { matches = complete_from_const(text,str); } while (0) +#define COMPLETE_WITH_ATTR(table) \ + do { matches = complete_from_query(text,Query_for_list_of_attributes, table, dbptr); } while (0) + +/* + * Functions used by the tab completion in psql normally found in pgport + */ +static void *pg_malloc(size_t size) +{ + return malloc(size); +} + +static int pg_strcasecmp(const char *s1, const char *s2) +{ +#ifdef WIN32 + return _stricmp(s1, s2); +#else + return strcasecmp(s1, s2); +#endif +} + +static int pg_strncasecmp(const char *s1, const char *s2, int len) +{ +#ifdef WIN32 + return _strnicmp(s1, s2, len); +#else + return strncasecmp(s1, s2, len); +#endif +} + +/* + * Return the word (space delimited) before point. Set skip > 0 to + * skip that many words; e.g. skip=1 finds the word before the + * previous one. Return value is NULL or a malloc'ed string. + * + * Copied directly from psql. + */ +static char * +previous_word(int point, int skip) +{ + int i, + start = 0, + end = -1, + inquotes = 0; + char *s; + + while (skip-- >= 0) + { + /* first we look for a space before the current word */ + for (i = point; i >= 0; i--) + if (rl_line_buffer[i] == ' ') + break; + + /* now find the first non-space which then constitutes the end */ + for (; i >= 0; i--) + if (rl_line_buffer[i] != ' ') + { + end = i; + break; + } + + /* + * If no end found we return null, because there is no word before the + * point + */ + if (end == -1) + return NULL; + + /* + * Otherwise we now look for the start. The start is either the last + * character before any space going backwards from the end, or it's + * simply character 0 + */ + for (start = end; start > 0; start--) + { + if (rl_line_buffer[start] == '"') + inquotes = !inquotes; + if ((rl_line_buffer[start - 1] == ' ') && inquotes == 0) + break; + } + + point = start; + } + + /* make a copy */ + s = (char *)pg_malloc(end - start + 2); + + strncpy(s, &rl_line_buffer[start], end - start + 1); + s[end - start + 1] = '\0'; + + return s; +} + +/* Find the parenthesis after the last word */ +/* Copied directly from psql */ +static int find_open_parenthesis(int end) +{ + int i = end-1; + + while((rl_line_buffer[i]!=' ')&&(i>=0)) + { + if (rl_line_buffer[i]=='(') return 1; + i--; + } + while((rl_line_buffer[i]==' ')&&(i>=0)) + { + i--; + } + if (rl_line_buffer[i]=='(') + { + return 1; + } + return 0; + +} + + +/* + * Forward declarations + */ +static char *complete_from_list(const char *text, const char * const *list); +static char *complete_from_const(const char *text, const char *string); +static char *complete_from_query(const char *text, const char *query, const char *addon, void *dbptr); +static char *complete_from_schema_query(const char *text, const void* query, const char *addon, void *dbptr); +static char *complete_create_command(char *text); +static char *complete_filename(); + +/* + * Include the main tab completion functionality from psql + */ +#include "tab-complete.inc" + + +/* + * Completion functions mimicking those from psql, only returning a single space separated + * string instead of being called multiple times by the readline library. + */ +static char *_complete_from_list(const char *text, const char * const *list, int casesensitive) +{ + int string_length = strlen(text); + int size = 0; + int i; + char *r; + + for (i = 0; list[i] != NULL; i++) + { + if (casesensitive && strncmp(text, list[i], string_length) == 0) + size += strlen(list[i]); + if (!casesensitive && pg_strncasecmp(text, list[i], string_length) == 0) + size += strlen(list[i]); + } + + if (size == 0) + return NULL; + + r = calloc(size + i*2 + 1, 1); + for (i = 0; list[i] != NULL; i++) + { + if ((casesensitive && strncmp(text, list[i], string_length) == 0) + || + (!casesensitive && pg_strncasecmp(text, list[i], string_length) == 0)) + { + strcat(r,list[i]); + strcat(r," \t"); + } + } + r[strlen(r)-1] = '\0'; /* Chop of trailing space */ + return r; +} + +static char *complete_from_list(const char *text, const char * const *list) +{ + char *r = _complete_from_list(text, list, 1); + if (r) + return r; + return _complete_from_list(text, list, 0); +} + + +static char *complete_from_const(const char *text, const char *string) +{ + return strdup(string); +} + +static char *_complete_from_query(const char *text, const char *query, const SchemaQuery *squery, const char *addon, void *dbptr) +{ + int string_length = strlen(text); + char *e_text; + char *complete_query = NULL; + char *t; + + e_text = malloc(string_length*2+1); + PQescapeString(e_text, text, string_length); + + if (query != NULL) + { + /* Normal query */ + int bufsize = 1024; + char *e_addon; + + /* Normal query needs escaped string */ + if (addon) + { + e_addon = malloc(strlen(addon)*2+1); + PQescapeString(e_addon, addon, strlen(addon)); + } + else + e_addon = strdup(""); + + while (1) + { + int r; + complete_query = realloc(complete_query, bufsize); +#ifdef WIN32 + r = _snprintf(complete_query, bufsize, query, string_length, e_text, e_addon); +#else + r = snprintf(complete_query, bufsize, query, string_length, e_text, e_addon); +#endif + if (r < 0 || r >= bufsize) + bufsize *= 2; + else + break; + } + free(e_addon); + } + else + { + /* Schema query */ + char *selcondition = NULL; + char *viscondition = NULL; + char *suppress_str = NULL; + const char *qualresult; + int bufsize = 2048; + + if (squery->selcondition) + { + selcondition = malloc(strlen(squery->selcondition)+10); + sprintf(selcondition,"%s AND ",squery->selcondition); + } + else + selcondition = strdup(""); + + if (squery->viscondition) + { + viscondition = malloc(strlen(squery->viscondition)+10); + sprintf(viscondition, " AND %s",squery->viscondition); + } + else + viscondition = strdup(""); + + if (strcmp(squery->catname,"pg_catalog.pg_class c") == 0 && + strncmp(text, "pg_", 3) != 0) + suppress_str = " AND c.relnamespace <> (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')"; + else + suppress_str = ""; + + qualresult = squery->qualresult; + if (qualresult == NULL) + qualresult = squery->result; + + while (1) + { + int r; + complete_query = realloc(complete_query, bufsize); +#ifdef WIN32 + r = _snprintf(complete_query, bufsize, +#else + r = snprintf(complete_query, bufsize, +#endif + "SELECT %s FROM %s WHERE %s substring(%s,1,%d)='%s' %s %s " + "\nUNION\n" + "SELECT pg_catalog.quote_ident(n.nspname) || '.' FROM pg_catalog.pg_namespace n WHERE substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d)='%s' AND (SELECT pg_catalog.count(*) FROM pg_catalog.pg_namespace WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d)= substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1))>1" + "\nUNION\n" + "SELECT pg_catalog.quote_ident(n.nspname) || '.' || %s FROM %s, pg_catalog.pg_namespace n WHERE %s = n.oid AND %s substring(pg_catalog.quote_ident(n.nspname) || '.' || %s,1,%d)='%s' AND substring(pg_catalog.quote_ident(n.nspname) || '.',1,%d) = substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(n.nspname))+1) AND (SELECT pg_catalog.count(*) FROM pg_catalog.pg_namespace WHERE substring(pg_catalog.quote_ident(nspname) || '.',1,%d) = substring('%s',1,pg_catalog.length(pg_catalog.quote_ident(nspname))+1)) = 1" + "\n%s", + squery->result, + squery->catname, + selcondition, + squery->result, + string_length, + e_text, + viscondition, + suppress_str, + string_length, + e_text, + string_length, + e_text, + qualresult, + squery->catname, + squery->namespace, + selcondition, + qualresult, + string_length, + e_text, + string_length, + e_text, + string_length, + e_text, + addon?addon:""); + + if (r < 0 || r >= bufsize) + bufsize *= 2; + else + break; + + } + + free(viscondition); + free(selcondition); + + } + t = pg_query_to_single_ordered_string(complete_query, dbptr); + if (complete_query) + free(complete_query); + free(e_text); + return t; +} + +static char *complete_from_query(const char *text, const char *query, const char *addon, void *dbptr) +{ + return _complete_from_query(text, query, NULL, addon, dbptr); +} + +static char *complete_from_schema_query(const char *text, const void* query, const char *addon, void *dbptr) +{ + /* query really is a SchemaQuery, but we don't know about SchemaQuery early enough. */ + return _complete_from_query(text, NULL, (SchemaQuery *)query, addon, dbptr); +} + +static char *complete_create_command(char *text) +{ + int string_length = strlen(text); + int size = 0; + int i; + char *r; + + for (i = 0; words_after_create[i].name != NULL; i++) + { + if (pg_strncasecmp(text, words_after_create[i].name, string_length) == 0) + size += strlen(words_after_create[i].name); + } + + r = calloc(size + i*2 + 1, 1); + for (i = 0; words_after_create[i].name != NULL; i++) + { + if (pg_strncasecmp(text, words_after_create[i].name, string_length) == 0) + { + strcat(r,words_after_create[i].name); + strcat(r," \t"); + } + } + r[strlen(r)-1] = '\0'; /* Chop of trailing space */ + return r; +} + +/* Not implemented */ +static char *complete_filename() +{ + return NULL; +} + + +/* + * Entrypoint from the C++ world + */ +char *tab_complete(const char *allstr, const int startptr, const int endptr, void *dbptr) +{ + rl_line_buffer = (char *)allstr; + return psql_completion((char *)(allstr + startptr), startptr,endptr,dbptr); +} diff --git a/utils/tabcomplete.pl b/utils/tabcomplete.pl new file mode 100644 index 0000000..81ef3da --- /dev/null +++ b/utils/tabcomplete.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl +########################################################################## +## +## pgAdmin III - Tab completion +## +## Copyright (C) 2002 - 2016, The pgAdmin Development Team +## This software is released under the PostgreSQL Licence +## +## tab-complete.pl - Script to build tab-complete.inc +## +########################################################################## + + +# This script builds tab-complete.inc from tab-complete.c. The +# source file (tab-complete.c) should be copied from the latest +# PostgreSQL sources (src/bin/psql/tab-complete.c), so we don't +# have to do all the work ourselves... + +use strict; +use warnings; + +open(F, "tab-complete.c") || die("Could not open tab-complete.c!"); +undef $/; +my $alltxt = ; +close(F); + +# Get rid of everything before and after the parts we're interested in +$alltxt =~ /.*(typedef struct SchemaQuery.*)\/\* GENERATOR FUNCTIONS\s+.*/s || die("Failed match 1"); +$alltxt = $1; + +# Get rid of forward declarations and initialize_readline +$alltxt =~ /(.*)\/\*\s+Forward declaration of functions \*\/.*(\/\* The completion function\..*)/s || die("Failed match 2"); +$alltxt = $1 . $2; + +# Get rid of completion macros, we define them ourselves +$alltxt =~ /(.*)\/\* A couple of macros to ease typing.*\*\/\s+#define COMPLETE_WITH_QUERY.*\s+(\/\*\s+\* Assembly instructions.*)/s || die("Failed match 4"); +$alltxt = $1 . $2; + +# Rewrite matches that don't use the macros +$alltxt =~ s/completion_matches\(text, create_command_generator\)/complete_create_command\(text\)/gs || die("Failed match 5"); +$alltxt =~ s/completion_matches\(text, filename_completion_function\)/complete_filename\(\)/gs || die("Failed match 6"); + +# We're going to return char*, not char** +$alltxt =~ s/static char \*\*\s+psql_completion/static char \* psql_completion/s || die("Failed match 7"); +$alltxt =~ s/char\s+\*\*matches = NULL/char \*matches = NULL/s || die("Failed match 8"); + +# Add an extra parameter to psql_completion +$alltxt =~ s/psql_completion\(char \*text, int start, int end\)/psql_completion\(char \*text, int start, int end, void \*dbptr\)/s || die("Failed match 9"); + +open(F,">tab-complete.inc") || die("Could not open tab-complete.inc!"); +print F $alltxt; +print F "\n\n"; +close(F); + +print "Done.\n"; diff --git a/utils/utffile.cpp b/utils/utffile.cpp new file mode 100644 index 0000000..55a0822 --- /dev/null +++ b/utils/utffile.cpp @@ -0,0 +1,337 @@ +////////////////////////////////////////////////////////////////////////// +// +// pgAdmin III - PostgreSQL Tools +// +// Copyright (C) 2002 - 2016, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +// utffile.cpp - file io with BOM interpretation +// +////////////////////////////////////////////////////////////////////////// + +#include "pgAdmin3.h" +#include "utils/utffile.h" +#include "utils/sysLogger.h" + +wxMBConvUTF16BE wxConvUTF16BE; +wxMBConvUTF16LE wxConvUTF16LE; +wxMBConvUTF32BE wxConvUTF32BE; +wxMBConvUTF32LE wxConvUTF32LE; + +// these are the magic characters identifying an Unicode file +#define BOM_UTF8 "\357\273\277" +#define BOM_UTF16LE "\377\376" +#define BOM_UTF16BE "\376\377" +#define BOM_UTF32LE "\377\376\000\000" +#define BOM_UTF32BE "\000\000\376\377" + +wxUtfFile::wxUtfFile() : wxFile() +{ +} + + +wxUtfFile::wxUtfFile(const wxChar *szFileName, OpenMode mode, wxFontEncoding encoding) : wxFile() +{ + m_strFileName = szFileName; + Open(szFileName, mode, wxS_DEFAULT, encoding); +} + + +wxUtfFile::wxUtfFile(int fd, wxFontEncoding encoding) : wxFile(fd) +{ + EvalBOM(encoding); +} + + +off_t wxUtfFile::Read(wxString &str, off_t nCount) +{ + if (nCount == (off_t) - 1) + nCount = Length() - Tell(); + if (!nCount) + return 0; + + char *buffer = new char[nCount + 4]; + // on some systems, len returned from wxFile::read might not reflect the number of bytes written + // to the buffer, but the bytes read from file. In case of CR/LF translation, this is not the same. + memset(buffer, 0, nCount + 4); + off_t len = wxFile::Read(buffer, nCount); + + if (len >= 0) + { + memset(buffer + len, 0, 4); + + if (m_conversion) + { + int decr; + size_t nLen = 0; + + + // We are trying 4 times to convert, in case the last utf char + // was truncated. + for (decr = 0 ; len > 0 && decr < 4 ; decr++) + { + nLen = m_conversion->MB2WC(NULL, buffer, 0); + if ( nLen != (size_t) - 1 ) + break; + len--; + buffer[len] = 0; + } + + if (nLen == (size_t) - 1) + { + if (!m_strFileName.IsEmpty()) + { + wxLogWarning(_("The file \"%s\" could not be opened because it contains characters that could not be interpreted."), m_strFileName.c_str()); + } + Seek(decr - nLen, wxFromCurrent); + return (size_t) - 1; + } + if (decr) + Seek(-decr, wxFromCurrent); + + m_conversion->MB2WC((wchar_t *)(wxChar *)wxStringBuffer(str, nLen + 1), (const char *)buffer, (size_t)(nLen + 1)); + } + else + str = (wxChar *)buffer; + } + + delete[] buffer; + return len; +} + + +bool wxUtfFile::Write(const wxString &str) +{ + size_t len = str.Length(); + if (!len) + return true; + + if (m_conversion) + { + wxWX2MBbuf buf = str.mb_str(*m_conversion); + if (!buf) + return false; + + return wxFile::Write(str, *m_conversion); + } + else + return wxFile::Write(str.c_str(), len * sizeof(wxChar)) == len * sizeof(wxChar); +} + + + +bool wxUtfFile::Create(const wxChar *szFileName, bool bOverwrite, int access, wxFontEncoding encoding) +{ + if (!wxFile::Create(szFileName, bOverwrite, access)) + return false; + + DetermineConversion(encoding); + WriteBOM(); + + return true; +} + + +bool wxUtfFile::Open(const wxChar *szFileName, OpenMode mode, int access, wxFontEncoding encoding) +{ + if (!wxFile::Open(szFileName, mode, access)) + return false; + + + m_bomOffset = 0; + DetermineConversion(wxFONTENCODING_SYSTEM); + + if (mode != write && EvalBOM(encoding)) + { + // File freshly created, need BOM + if (mode != read) + WriteBOM(); + } + else if (mode != read && encoding != wxFONTENCODING_DEFAULT) + { + // force BOM to a specific value + switch (encoding) + { + case wxFONTENCODING_UTF8: + case wxFONTENCODING_UTF16BE: + case wxFONTENCODING_UTF16LE: + case wxFONTENCODING_UTF32BE: + case wxFONTENCODING_UTF32LE: + break; + default: + encoding = wxFONTENCODING_SYSTEM; + break; + } + if (encoding != m_encoding) + { + DetermineConversion(encoding); + WriteBOM(); + } + } + return true; +} + + +void wxUtfFile::Attach(int fd, wxFontEncoding encoding) +{ + wxFile::Attach(fd); + EvalBOM(encoding); +} + + +off_t wxUtfFile::Seek(off_t ofs, wxSeekMode mode) +{ + off_t pos; + if (mode == wxFromStart) + pos = wxFile::Seek(ofs + m_bomOffset, wxFromStart) - m_bomOffset; + else + pos = wxFile::Seek(ofs, mode) - m_bomOffset; + + if (pos != wxInvalidOffset) + pos -= m_bomOffset; + + return pos; +} + + + +wxFontEncoding wxUtfFile::GetEncoding() +{ + if (IsOpened()) + return m_encoding; + else + return wxFONTENCODING_DEFAULT; +} + + +void wxUtfFile::WriteBOM() +{ + if (!settings->GetWriteBOM()) + return; + + wxFile::Seek(0); + switch (m_encoding) + { + case wxFONTENCODING_UTF8: + wxFile::Write(BOM_UTF8, 3); + m_bomOffset = 3; + break; + case wxFONTENCODING_UTF16BE: + wxFile::Write(BOM_UTF16BE, 2); + m_bomOffset = 2; + break; + case wxFONTENCODING_UTF16LE: + wxFile::Write(BOM_UTF16LE, 2); + m_bomOffset = 2; + break; + case wxFONTENCODING_UTF32BE: + wxFile::Write(BOM_UTF32LE, 4); + m_bomOffset = 4; + break; + case wxFONTENCODING_UTF32LE: + wxFile::Write(BOM_UTF32LE, 4); + m_bomOffset = 4; + break; + default: + m_bomOffset = 0; + break; + } +} + + +void wxUtfFile::DetermineConversion(wxFontEncoding encoding) +{ + switch (encoding) + { + case wxFONTENCODING_UTF8: + case wxFONTENCODING_UTF16BE: + case wxFONTENCODING_UTF16LE: + case wxFONTENCODING_UTF32BE: + case wxFONTENCODING_UTF32LE: + // we know these + m_encoding = encoding; + break; + default: + m_encoding = wxFONTENCODING_SYSTEM; + break; + } + + if (m_encoding == wxFONTENCODING_UNICODE) + m_conversion = 0; + else + { + switch (m_encoding) + { + case wxFONTENCODING_SYSTEM: + m_conversion = &wxConvLibc; + break; + case wxFONTENCODING_UTF8: + m_conversion = &wxConvUTF8; + break; + case wxFONTENCODING_UTF16BE: + m_conversion = &wxConvUTF16BE; + break; + case wxFONTENCODING_UTF16LE: + m_conversion = &wxConvUTF16LE; + break; + case wxFONTENCODING_UTF32BE: + m_conversion = &wxConvUTF32BE; + break; + case wxFONTENCODING_UTF32LE: + m_conversion = &wxConvUTF32LE; + break; + default: + break; + } + } +} + + +bool wxUtfFile::EvalBOM(wxFontEncoding encoding) +{ + // returns true, if BOM needs to be written. + + char bombuf[4] = "###"; + long len = wxFile::Read(bombuf, 4); + + if (!memcmp(bombuf, BOM_UTF32BE, 4)) + { + encoding = wxFONTENCODING_UTF32BE; + m_bomOffset = 4; + } + else if (!memcmp(bombuf, BOM_UTF32LE, 4)) + { + encoding = wxFONTENCODING_UTF32LE; + m_bomOffset = 4; + } + else if (!memcmp(bombuf, BOM_UTF8, 3)) + { + encoding = wxFONTENCODING_UTF8; + m_bomOffset = 3; + } + else if (!memcmp(bombuf, BOM_UTF16BE, 2)) + { + encoding = wxFONTENCODING_UTF16BE; + m_bomOffset = 2; + } + else if (!memcmp(bombuf, BOM_UTF16LE, 2)) + { + encoding = wxFONTENCODING_UTF16LE; + m_bomOffset = 2; + } + else + { + // no encoding was found. + m_bomOffset = 0; + } + + DetermineConversion(encoding); + + // if this file has length 0, BOM needs to be written because it's freshly created + if (len == 0) + return true; + else if (len != m_bomOffset) + Seek(0); + + return false; +}